bouncycastle-1.49.orig/0000755000175000017500000000000012152231261014424 5ustar ebourgebourgbouncycastle-1.49.orig/coverage.xml0000644000175000017500000001271310262753174016761 0ustar ebourgebourg %Common; ]> &Common; bouncycastle-1.49.orig/jdk1.4/0000755000175000017500000000000012152033550015420 5ustar ebourgebourgbouncycastle-1.49.orig/jdk1.4/org/0000755000175000017500000000000012152033550016207 5ustar ebourgebourgbouncycastle-1.49.orig/jdk1.4/org/bouncycastle/0000755000175000017500000000000012152033550020702 5ustar ebourgebourgbouncycastle-1.49.orig/jdk1.4/org/bouncycastle/util/0000755000175000017500000000000012152033550021657 5ustar ebourgebourgbouncycastle-1.49.orig/jdk1.4/org/bouncycastle/util/Integers.java0000644000175000017500000000022612103622714024304 0ustar ebourgebourgpackage org.bouncycastle.util; public class Integers { public static Integer valueOf(int value) { return new Integer(value); } } bouncycastle-1.49.orig/jdk1.4/org/bouncycastle/cms/0000755000175000017500000000000012152033550021464 5ustar ebourgebourgbouncycastle-1.49.orig/jdk1.4/org/bouncycastle/cms/jcajce/0000755000175000017500000000000012152033550022703 5ustar ebourgebourgbouncycastle-1.49.orig/jdk1.4/org/bouncycastle/cms/jcajce/JceKeyAgreeRecipientInfoGenerator.java0000644000175000017500000002006211723553745032232 0ustar ebourgebourgpackage org.bouncycastle.cms.jcajce; import java.security.GeneralSecurityException; import java.security.InvalidAlgorithmParameterException; import java.security.KeyPair; import java.security.KeyPairGenerator; import java.security.PrivateKey; import java.security.Provider; import java.security.PublicKey; import java.security.SecureRandom; import java.security.cert.CertificateEncodingException; import java.security.cert.X509Certificate; import java.util.ArrayList; import java.util.List; import javax.crypto.Cipher; import javax.crypto.KeyAgreement; import javax.crypto.SecretKey; import org.bouncycastle.asn1.ASN1Encodable; import org.bouncycastle.asn1.ASN1EncodableVector; import org.bouncycastle.asn1.ASN1ObjectIdentifier; import org.bouncycastle.asn1.ASN1OctetString; import org.bouncycastle.asn1.ASN1Sequence; import org.bouncycastle.asn1.DEROctetString; import org.bouncycastle.asn1.DERSequence; import org.bouncycastle.asn1.cms.KeyAgreeRecipientIdentifier; import org.bouncycastle.asn1.cms.RecipientEncryptedKey; import org.bouncycastle.asn1.cms.RecipientKeyIdentifier; import org.bouncycastle.asn1.cms.ecc.MQVuserKeyingMaterial; import org.bouncycastle.asn1.x509.AlgorithmIdentifier; import org.bouncycastle.asn1.x509.SubjectPublicKeyInfo; import org.bouncycastle.cms.CMSAlgorithm; import org.bouncycastle.cms.CMSEnvelopedGenerator; import org.bouncycastle.cms.CMSException; import org.bouncycastle.cms.KeyAgreeRecipientInfoGenerator; import org.bouncycastle.jce.interfaces.ECPublicKey; import org.bouncycastle.jce.spec.ECParameterSpec; import org.bouncycastle.jce.spec.MQVPrivateKeySpec; import org.bouncycastle.jce.spec.MQVPublicKeySpec; import org.bouncycastle.operator.GenericKey; public class JceKeyAgreeRecipientInfoGenerator extends KeyAgreeRecipientInfoGenerator { private List recipientIDs = new ArrayList(); private List recipientKeys = new ArrayList(); private PublicKey senderPublicKey; private PrivateKey senderPrivateKey; private EnvelopedDataHelper helper = new EnvelopedDataHelper(new DefaultJcaJceExtHelper()); private SecureRandom random; private KeyPair ephemeralKP; public JceKeyAgreeRecipientInfoGenerator(ASN1ObjectIdentifier keyAgreementOID, PrivateKey senderPrivateKey, PublicKey senderPublicKey, ASN1ObjectIdentifier keyEncryptionOID) { super(keyAgreementOID, SubjectPublicKeyInfo.getInstance(senderPublicKey.getEncoded()), keyEncryptionOID); this.senderPublicKey = senderPublicKey; this.senderPrivateKey = senderPrivateKey; } public JceKeyAgreeRecipientInfoGenerator setProvider(Provider provider) { this.helper = new EnvelopedDataHelper(new ProviderJcaJceExtHelper(provider)); return this; } public JceKeyAgreeRecipientInfoGenerator setProvider(String providerName) { this.helper = new EnvelopedDataHelper(new NamedJcaJceExtHelper(providerName)); return this; } public JceKeyAgreeRecipientInfoGenerator setSecureRandom(SecureRandom random) { this.random = random; return this; } /** * Add a recipient based on the passed in certificate's public key and its issuer and serial number. * * @param recipientCert recipient's certificate * @return the current instance. * @throws CertificateEncodingException if the necessary data cannot be extracted from the certificate. */ public JceKeyAgreeRecipientInfoGenerator addRecipient(X509Certificate recipientCert) throws CertificateEncodingException { recipientIDs.add(new KeyAgreeRecipientIdentifier(CMSUtils.getIssuerAndSerialNumber(recipientCert))); recipientKeys.add(recipientCert.getPublicKey()); return this; } /** * Add a recipient identified by the passed in subjectKeyID and the for the passed in public key. * * @param subjectKeyID identifier actual recipient will use to match the private key. * @param publicKey the public key for encrypting the secret key. * @return the current instance. * @throws CertificateEncodingException */ public JceKeyAgreeRecipientInfoGenerator addRecipient(byte[] subjectKeyID, PublicKey publicKey) throws CertificateEncodingException { recipientIDs.add(new KeyAgreeRecipientIdentifier(new RecipientKeyIdentifier(subjectKeyID))); recipientKeys.add(publicKey); return this; } public ASN1Sequence generateRecipientEncryptedKeys(AlgorithmIdentifier keyAgreeAlgorithm, AlgorithmIdentifier keyEncryptionAlgorithm, GenericKey contentEncryptionKey) throws CMSException { init(keyAgreeAlgorithm.getAlgorithm()); PrivateKey senderPrivateKey = this.senderPrivateKey; ASN1ObjectIdentifier keyAgreementOID = keyAgreeAlgorithm.getAlgorithm(); if (keyAgreementOID.getId().equals(CMSEnvelopedGenerator.ECMQV_SHA1KDF)) { senderPrivateKey = new MQVPrivateKeySpec( senderPrivateKey, ephemeralKP.getPrivate(), ephemeralKP.getPublic()); } ASN1EncodableVector recipientEncryptedKeys = new ASN1EncodableVector(); for (int i = 0; i != recipientIDs.size(); i++) { PublicKey recipientPublicKey = (PublicKey)recipientKeys.get(i); KeyAgreeRecipientIdentifier karId = (KeyAgreeRecipientIdentifier)recipientIDs.get(i); if (keyAgreementOID.getId().equals(CMSEnvelopedGenerator.ECMQV_SHA1KDF)) { recipientPublicKey = new MQVPublicKeySpec(recipientPublicKey, recipientPublicKey); } try { // Use key agreement to choose a wrap key for this recipient KeyAgreement keyAgreement = helper.createKeyAgreement(keyAgreementOID); keyAgreement.init(senderPrivateKey, random); keyAgreement.doPhase(recipientPublicKey, true); SecretKey keyEncryptionKey = keyAgreement.generateSecret(keyEncryptionAlgorithm.getAlgorithm().getId()); // Wrap the content encryption key with the agreement key Cipher keyEncryptionCipher = helper.createCipher(keyEncryptionAlgorithm.getAlgorithm()); keyEncryptionCipher.init(Cipher.WRAP_MODE, keyEncryptionKey, random); byte[] encryptedKeyBytes = keyEncryptionCipher.wrap(helper.getJceKey(contentEncryptionKey)); ASN1OctetString encryptedKey = new DEROctetString(encryptedKeyBytes); recipientEncryptedKeys.add(new RecipientEncryptedKey(karId, encryptedKey)); } catch (GeneralSecurityException e) { throw new CMSException("cannot perform agreement step: " + e.getMessage(), e); } } return new DERSequence(recipientEncryptedKeys); } protected ASN1Encodable getUserKeyingMaterial(AlgorithmIdentifier keyAgreeAlg) throws CMSException { init(keyAgreeAlg.getAlgorithm()); if (ephemeralKP != null) { return new MQVuserKeyingMaterial( createOriginatorPublicKey(SubjectPublicKeyInfo.getInstance(ephemeralKP.getPublic().getEncoded())), null); } return null; } private void init(ASN1ObjectIdentifier keyAgreementOID) throws CMSException { if (random == null) { random = new SecureRandom(); } if (keyAgreementOID.equals(CMSAlgorithm.ECMQV_SHA1KDF)) { if (ephemeralKP == null) { try { ECParameterSpec ecParamSpec = ((ECPublicKey)senderPublicKey).getParams(); KeyPairGenerator ephemKPG = helper.createKeyPairGenerator(keyAgreementOID); ephemKPG.initialize(ecParamSpec, random); ephemeralKP = ephemKPG.generateKeyPair(); } catch (InvalidAlgorithmParameterException e) { throw new CMSException( "cannot determine MQV ephemeral key pair parameters from public key: " + e); } } } } } bouncycastle-1.49.orig/jdk1.4/org/bouncycastle/eac/0000755000175000017500000000000012152033550021432 5ustar ebourgebourgbouncycastle-1.49.orig/jdk1.4/org/bouncycastle/eac/jcajce/0000755000175000017500000000000012152033550022651 5ustar ebourgebourgbouncycastle-1.49.orig/jdk1.4/org/bouncycastle/eac/jcajce/JcaPublicKeyConverter.java0000644000175000017500000001127112151301740027711 0ustar ebourgebourgpackage org.bouncycastle.eac.jcajce; import java.math.BigInteger; import java.security.KeyFactory; import java.security.NoSuchAlgorithmException; import java.security.NoSuchProviderException; import java.security.Provider; import java.security.PublicKey; import java.security.spec.InvalidKeySpecException; import java.security.spec.RSAPublicKeySpec; import org.bouncycastle.asn1.ASN1ObjectIdentifier; import org.bouncycastle.asn1.eac.EACObjectIdentifiers; import org.bouncycastle.asn1.eac.ECDSAPublicKey; import org.bouncycastle.asn1.eac.PublicKeyDataObject; import org.bouncycastle.asn1.eac.RSAPublicKey; import org.bouncycastle.eac.EACException; import org.bouncycastle.jce.interfaces.ECPublicKey; import org.bouncycastle.jce.spec.ECParameterSpec; import org.bouncycastle.jce.spec.ECPublicKeySpec; import org.bouncycastle.math.ec.ECCurve; import org.bouncycastle.math.ec.ECFieldElement; import org.bouncycastle.math.ec.ECPoint; public class JcaPublicKeyConverter { private EACHelper helper = new DefaultEACHelper(); public JcaPublicKeyConverter setProvider(String providerName) { this.helper = new NamedEACHelper(providerName); return this; } public JcaPublicKeyConverter setProvider(Provider provider) { this.helper = new ProviderEACHelper(provider); return this; } public PublicKey getKey(PublicKeyDataObject publicKeyDataObject) throws EACException, InvalidKeySpecException { if (publicKeyDataObject.getUsage().on(EACObjectIdentifiers.id_TA_ECDSA)) { return getECPublicKeyPublicKey((ECDSAPublicKey)publicKeyDataObject); } else { RSAPublicKey pubKey = (RSAPublicKey)publicKeyDataObject; RSAPublicKeySpec pubKeySpec = new RSAPublicKeySpec(pubKey.getModulus(), pubKey.getPublicExponent()); try { KeyFactory factk = helper.createKeyFactory("RSA"); return factk.generatePublic(pubKeySpec); } catch (NoSuchProviderException e) { throw new EACException("cannot find provider: " + e.getMessage(), e); } catch (NoSuchAlgorithmException e) { throw new EACException("cannot find algorithm ECDSA: " + e.getMessage(), e); } } } private PublicKey getECPublicKeyPublicKey(ECDSAPublicKey key) throws EACException, InvalidKeySpecException { ECParameterSpec spec = getParams(key); ECCurve curve = spec.getCurve(); ECPoint point = curve.decodePoint(key.getPublicPointY()); ECPublicKeySpec pubKeySpec = new ECPublicKeySpec(point, spec); KeyFactory factk; try { factk = helper.createKeyFactory("ECDSA"); } catch (NoSuchProviderException e) { throw new EACException("cannot find provider: " + e.getMessage(), e); } catch (NoSuchAlgorithmException e) { throw new EACException("cannot find algorithm ECDSA: " + e.getMessage(), e); } return factk.generatePublic(pubKeySpec); } private ECParameterSpec getParams(ECDSAPublicKey key) { if (!key.hasParameters()) { throw new IllegalArgumentException("Public key does not contains EC Params"); } BigInteger p = key.getPrimeModulusP(); ECCurve.Fp curve = new ECCurve.Fp(p, key.getFirstCoefA(), key.getSecondCoefB()); ECPoint G = curve.decodePoint(key.getBasePointG()); BigInteger order = key.getOrderOfBasePointR(); BigInteger coFactor = key.getCofactorF(); ECParameterSpec ecspec = new ECParameterSpec(curve, G, order, coFactor); return ecspec; } public PublicKeyDataObject getPublicKeyDataObject(ASN1ObjectIdentifier usage, PublicKey publicKey) { if (publicKey instanceof java.security.interfaces.RSAPublicKey) { java.security.interfaces.RSAPublicKey pubKey = (java.security.interfaces.RSAPublicKey)publicKey; return new RSAPublicKey(usage, pubKey.getModulus(), pubKey.getPublicExponent()); } else { ECPublicKey pubKey = (ECPublicKey)publicKey; ECParameterSpec params = pubKey.getParameters(); return new ECDSAPublicKey( usage, ((ECCurve.Fp)params.getCurve()).getQ(), ((ECFieldElement.Fp)params.getCurve().getA()).toBigInteger(), ((ECFieldElement.Fp)params.getCurve().getB()).toBigInteger(), params.getG().getEncoded(), params.getN(), pubKey.getQ().getEncoded(), params.getH().intValue()); } } } bouncycastle-1.49.orig/jdk1.4/org/bouncycastle/x509/0000755000175000017500000000000012152033550021407 5ustar ebourgebourgbouncycastle-1.49.orig/jdk1.4/org/bouncycastle/x509/util/0000755000175000017500000000000012152033550022364 5ustar ebourgebourgbouncycastle-1.49.orig/jdk1.4/org/bouncycastle/x509/util/LDAPStoreHelper.java0000644000175000017500000011615311737303212026136 0ustar ebourgebourgpackage org.bouncycastle.x509.util; import java.io.ByteArrayInputStream; import java.io.IOException; import java.security.Principal; import java.security.cert.CertificateParsingException; import java.security.cert.X509CRL; import java.security.cert.X509Certificate; import java.sql.Date; import java.util.ArrayList; import java.util.Collection; import java.util.HashMap; import java.util.HashSet; import java.util.Iterator; import java.util.List; import java.util.Map; import java.util.Properties; import java.util.Set; import javax.naming.Context; import javax.naming.NamingEnumeration; import javax.naming.NamingException; import javax.naming.directory.Attribute; import javax.naming.directory.DirContext; import javax.naming.directory.InitialDirContext; import javax.naming.directory.SearchControls; import javax.naming.directory.SearchResult; import javax.security.auth.x500.X500Principal; import org.bouncycastle.asn1.ASN1InputStream; import org.bouncycastle.asn1.x509.Certificate; import org.bouncycastle.asn1.x509.CertificatePair; import org.bouncycastle.jce.X509LDAPCertStoreParameters; import org.bouncycastle.jce.provider.X509AttrCertParser; import org.bouncycastle.jce.provider.X509CRLParser; import org.bouncycastle.jce.provider.X509CertPairParser; import org.bouncycastle.jce.provider.X509CertParser; import org.bouncycastle.util.StoreException; import org.bouncycastle.x509.X509AttributeCertStoreSelector; import org.bouncycastle.x509.X509AttributeCertificate; import org.bouncycastle.x509.X509CRLStoreSelector; import org.bouncycastle.x509.X509CertPairStoreSelector; import org.bouncycastle.x509.X509CertStoreSelector; import org.bouncycastle.x509.X509CertificatePair; /** * This is a general purpose implementation to get X.509 certificates, CRLs, * attribute certificates and cross certificates from a LDAP location. *

* At first a search is performed in the ldap*AttributeNames of the * {@link org.bouncycastle.jce.X509LDAPCertStoreParameters} with the given * information of the subject (for all kind of certificates) or issuer (for * CRLs), respectively, if a {@link org.bouncycastle.x509.X509CertStoreSelector} or * {@link org.bouncycastle.x509.X509AttributeCertificate} is given with that * details. *

* For the used schemes see: *

*/ public class LDAPStoreHelper { // TODO: cache results private X509LDAPCertStoreParameters params; public LDAPStoreHelper(X509LDAPCertStoreParameters params) { this.params = params; } /** * Initial Context Factory. */ private static String LDAP_PROVIDER = "com.sun.jndi.ldap.LdapCtxFactory"; /** * Processing referrals.. */ private static String REFERRALS_IGNORE = "ignore"; /** * Security level to be used for LDAP connections. */ private static final String SEARCH_SECURITY_LEVEL = "none"; /** * Package Prefix for loading URL context factories. */ private static final String URL_CONTEXT_PREFIX = "com.sun.jndi.url"; private DirContext connectLDAP() throws NamingException { Properties props = new Properties(); props.setProperty(Context.INITIAL_CONTEXT_FACTORY, LDAP_PROVIDER); props.setProperty(Context.BATCHSIZE, "0"); props.setProperty(Context.PROVIDER_URL, params.getLdapURL()); props.setProperty(Context.URL_PKG_PREFIXES, URL_CONTEXT_PREFIX); props.setProperty(Context.REFERRAL, REFERRALS_IGNORE); props.setProperty(Context.SECURITY_AUTHENTICATION, SEARCH_SECURITY_LEVEL); DirContext ctx = new InitialDirContext(props); return ctx; } private String parseDN(String subject, String dNAttributeName) { String temp = subject; int begin = temp.toLowerCase().indexOf( dNAttributeName.toLowerCase() + "="); if (begin == -1) { return ""; } temp = temp.substring(begin + dNAttributeName.length()); int end = temp.indexOf(','); if (end == -1) { end = temp.length(); } while (temp.charAt(end - 1) == '\\') { end = temp.indexOf(',', end + 1); if (end == -1) { end = temp.length(); } } temp = temp.substring(0, end); begin = temp.indexOf('='); temp = temp.substring(begin + 1); if (temp.charAt(0) == ' ') { temp = temp.substring(1); } if (temp.startsWith("\"")) { temp = temp.substring(1); } if (temp.endsWith("\"")) { temp = temp.substring(0, temp.length() - 1); } return temp; } private Set createCerts(List list, X509CertStoreSelector xselector) throws StoreException { Set certSet = new HashSet(); Iterator it = list.iterator(); X509CertParser parser = new X509CertParser(); while (it.hasNext()) { try { parser.engineInit(new ByteArrayInputStream((byte[])it .next())); X509Certificate cert = (X509Certificate)parser .engineRead(); if (xselector.match((Object)cert)) { certSet.add(cert); } } catch (Exception e) { } } return certSet; } /** * Can use the subject and serial and the subject and serialNumber of the * certificate of the given of the X509CertStoreSelector. If a certificate * for checking is given this has higher precedence. * * @param xselector The selector with the search criteria. * @param attrs Attributes which contain the certificates in the LDAP * directory. * @param attrNames Attribute names in teh LDAP directory which correspond to the * subjectAttributeNames. * @param subjectAttributeNames Subject attribute names (like "CN", "O", "OU") to use to * search in the LDAP directory * @return A list of found DER encoded certificates. * @throws StoreException if an error occurs while searching. */ private List certSubjectSerialSearch(X509CertStoreSelector xselector, String[] attrs, String attrNames[], String subjectAttributeNames[]) throws StoreException { // TODO: support also subjectAltNames? List list = new ArrayList(); String subject = null; String serial = null; subject = getSubjectAsString(xselector); if (xselector.getSerialNumber() != null) { serial = xselector.getSerialNumber().toString(); } if (xselector.getCertificate() != null) { subject = xselector.getCertificate().getSubjectX500Principal().getName("RFC1779"); serial = xselector.getCertificate().getSerialNumber().toString(); } String attrValue = null; if (subject != null) { for (int i = 0; i < subjectAttributeNames.length; i++) { attrValue = parseDN(subject, subjectAttributeNames[i]); list .addAll(search(attrNames, "*" + attrValue + "*", attrs)); } } if (serial != null && params.getSearchForSerialNumberIn() != null) { attrValue = serial; list.addAll(search( splitString(params.getSearchForSerialNumberIn()), attrValue, attrs)); } if (serial == null && subject == null) { list.addAll(search(attrNames, "*", attrs)); } return list; } /** * Can use the subject of the forward certificate of the set certificate * pair or the subject of the forward * {@link org.bouncycastle.x509.X509CertStoreSelector} of the given * selector. * * @param xselector The selector with the search criteria. * @param attrs Attributes which contain the attribute certificates in the * LDAP directory. * @param attrNames Attribute names in the LDAP directory which correspond to the * subjectAttributeNames. * @param subjectAttributeNames Subject attribute names (like "CN", "O", "OU") to use to * search in the LDAP directory * @return A list of found DER encoded certificate pairs. * @throws StoreException if an error occurs while searching. */ private List crossCertificatePairSubjectSearch( X509CertPairStoreSelector xselector, String[] attrs, String attrNames[], String subjectAttributeNames[]) throws StoreException { List list = new ArrayList(); // search for subject String subject = null; if (xselector.getForwardSelector() != null) { subject = getSubjectAsString(xselector.getForwardSelector()); } if (xselector.getCertPair() != null) { if (xselector.getCertPair().getForward() != null) { subject = xselector.getCertPair().getForward() .getSubjectX500Principal().getName("RFC1779"); } } String attrValue = null; if (subject != null) { for (int i = 0; i < subjectAttributeNames.length; i++) { attrValue = parseDN(subject, subjectAttributeNames[i]); list .addAll(search(attrNames, "*" + attrValue + "*", attrs)); } } if (subject == null) { list.addAll(search(attrNames, "*", attrs)); } return list; } /** * Can use the entityName of the holder of the attribute certificate, the * serialNumber of attribute certificate and the serialNumber of the * associated certificate of the given of the X509AttributeCertSelector. * * @param xselector The selector with the search criteria. * @param attrs Attributes which contain the attribute certificates in the * LDAP directory. * @param attrNames Attribute names in the LDAP directory which correspond to the * subjectAttributeNames. * @param subjectAttributeNames Subject attribute names (like "CN", "O", "OU") to use to * search in the LDAP directory * @return A list of found DER encoded attribute certificates. * @throws StoreException if an error occurs while searching. */ private List attrCertSubjectSerialSearch( X509AttributeCertStoreSelector xselector, String[] attrs, String attrNames[], String subjectAttributeNames[]) throws StoreException { List list = new ArrayList(); // search for serialNumber of associated cert, // serialNumber of the attribute certificate or DN in the entityName // of the holder String subject = null; String serial = null; Collection serials = new HashSet(); Principal principals[] = null; if (xselector.getHolder() != null) { // serialNumber of associated cert if (xselector.getHolder().getSerialNumber() != null) { serials.add(xselector.getHolder().getSerialNumber() .toString()); } // DN in the entityName of the holder if (xselector.getHolder().getEntityNames() != null) { principals = xselector.getHolder().getEntityNames(); } } if (xselector.getAttributeCert() != null) { if (xselector.getAttributeCert().getHolder().getEntityNames() != null) { principals = xselector.getAttributeCert().getHolder() .getEntityNames(); } // serialNumber of the attribute certificate serials.add(xselector.getAttributeCert().getSerialNumber() .toString()); } if (principals != null) { // only first should be relevant if (principals[0] instanceof X500Principal) { subject = ((X500Principal)principals[0]) .getName("RFC1779"); } else { // strange ... subject = principals[0].getName(); } } if (xselector.getSerialNumber() != null) { serials.add(xselector.getSerialNumber().toString()); } String attrValue = null; if (subject != null) { for (int i = 0; i < subjectAttributeNames.length; i++) { attrValue = parseDN(subject, subjectAttributeNames[i]); list .addAll(search(attrNames, "*" + attrValue + "*", attrs)); } } if (serials.size() > 0 && params.getSearchForSerialNumberIn() != null) { Iterator it = serials.iterator(); while (it.hasNext()) { serial = (String)it.next(); list.addAll(search(splitString(params.getSearchForSerialNumberIn()), serial, attrs)); } } if (serials.size() == 0 && subject == null) { list.addAll(search(attrNames, "*", attrs)); } return list; } /** * Can use the issuer of the given of the X509CRLStoreSelector. * * @param xselector The selector with the search criteria. * @param attrs Attributes which contain the attribute certificates in the * LDAP directory. * @param attrNames Attribute names in the LDAP directory which correspond to the * subjectAttributeNames. * @param issuerAttributeNames Issuer attribute names (like "CN", "O", "OU") to use to search * in the LDAP directory * @return A list of found DER encoded CRLs. * @throws StoreException if an error occurs while searching. */ private List cRLIssuerSearch(X509CRLStoreSelector xselector, String[] attrs, String attrNames[], String issuerAttributeNames[]) throws StoreException { List list = new ArrayList(); String issuer = null; Collection issuers = new HashSet(); /* if (xselector.getIssuers() != null) { issuers.addAll(xselector.getIssuers()); } */ if (xselector.getCertificateChecking() != null) { issuers.add(getCertificateIssuer(xselector.getCertificateChecking())); } if (xselector.getAttrCertificateChecking() != null) { Principal principals[] = xselector.getAttrCertificateChecking().getIssuer().getPrincipals(); for (int i=0; iList of encodings of the certificates, attribute * certificates, CRL or certificate pairs. * * @param attributeNames The attribute names to look for in the LDAP. * @param attributeValue The value the attribute name must have. * @param attrs The attributes in the LDAP which hold the certificate, * attribute certificate, certificate pair or CRL in a found * entry. * @return A List of byte arrays with the encodings. * @throws StoreException if an error occurs getting the results from the LDAP * directory. */ private List search(String attributeNames[], String attributeValue, String[] attrs) throws StoreException { String filter = null; if (attributeNames == null) { filter = null; } else { filter = ""; if (attributeValue.equals("**")) { attributeValue = "*"; } for (int i = 0; i < attributeNames.length; i++) { filter += "(" + attributeNames[i] + "=" + attributeValue + ")"; } filter = "(|" + filter + ")"; } String filter2 = ""; for (int i = 0; i < attrs.length; i++) { filter2 += "(" + attrs[i] + "=*)"; } filter2 = "(|" + filter2 + ")"; String filter3 = "(&" + filter + "" + filter2 + ")"; if (filter == null) { filter3 = filter2; } List list; list = getFromCache(filter3); if (list != null) { return list; } DirContext ctx = null; list = new ArrayList(); try { ctx = connectLDAP(); SearchControls constraints = new SearchControls(); constraints.setSearchScope(SearchControls.SUBTREE_SCOPE); constraints.setCountLimit(0); constraints.setReturningAttributes(attrs); NamingEnumeration results = ctx.search(params.getBaseDN(), filter3, constraints); while (results.hasMoreElements()) { SearchResult sr = (SearchResult)results.next(); NamingEnumeration enumeration = ((Attribute)(sr .getAttributes().getAll().next())).getAll(); while (enumeration.hasMore()) { list.add(enumeration.next()); } } addToCache(filter3, list); } catch (NamingException e) { // skip exception, unfortunately if an attribute type is not // supported an exception is thrown } finally { try { if (null != ctx) { ctx.close(); } } catch (Exception e) { } } return list; } private Set createCRLs(List list, X509CRLStoreSelector xselector) throws StoreException { Set crlSet = new HashSet(); X509CRLParser parser = new X509CRLParser(); Iterator it = list.iterator(); while (it.hasNext()) { try { parser.engineInit(new ByteArrayInputStream((byte[])it .next())); X509CRL crl = (X509CRL)parser.engineRead(); if (xselector.match((Object)crl)) { crlSet.add(crl); } } catch (StreamParsingException e) { } } return crlSet; } private Set createCrossCertificatePairs(List list, X509CertPairStoreSelector xselector) throws StoreException { Set certPairSet = new HashSet(); int i = 0; while (i < list.size()) { X509CertificatePair pair; try { // first try to decode it as certificate pair try { X509CertPairParser parser = new X509CertPairParser(); parser.engineInit(new ByteArrayInputStream( (byte[])list.get(i))); pair = (X509CertificatePair)parser.engineRead(); } catch (StreamParsingException e) { // now try it to construct it the forward and reverse // certificate byte[] forward = (byte[])list.get(i); byte[] reverse = (byte[])list.get(i + 1); pair = new X509CertificatePair(new CertificatePair( Certificate .getInstance(new ASN1InputStream( forward).readObject()), Certificate .getInstance(new ASN1InputStream( reverse).readObject()))); i++; } if (xselector.match((Object)pair)) { certPairSet.add(pair); } } catch (CertificateParsingException e) { // try next } catch (IOException e) { // try next } i++; } return certPairSet; } private Set createAttributeCertificates(List list, X509AttributeCertStoreSelector xselector) throws StoreException { Set certSet = new HashSet(); Iterator it = list.iterator(); X509AttrCertParser parser = new X509AttrCertParser(); while (it.hasNext()) { try { parser.engineInit(new ByteArrayInputStream((byte[])it .next())); X509AttributeCertificate cert = (X509AttributeCertificate)parser .engineRead(); if (xselector.match((Object)cert)) { certSet.add(cert); } } catch (StreamParsingException e) { } } return certSet; } /** * Returns the CRLs for issued certificates for other CAs matching the given * selector.
* The authorityRevocationList attribute includes revocation information * regarding certificates issued to other CAs. * * @param selector The CRL selector to use to find the CRLs. * @return A possible empty collection with CRLs * @throws StoreException */ public Collection getAuthorityRevocationLists(X509CRLStoreSelector selector) throws StoreException { String[] attrs = splitString(params.getAuthorityRevocationListAttribute()); String attrNames[] = splitString(params .getLdapAuthorityRevocationListAttributeName()); String issuerAttributeNames[] = splitString(params .getAuthorityRevocationListIssuerAttributeName()); List list = cRLIssuerSearch(selector, attrs, attrNames, issuerAttributeNames); Set resultSet = createCRLs(list, selector); if (resultSet.size() == 0) { X509CRLStoreSelector emptySelector = new X509CRLStoreSelector(); list = cRLIssuerSearch(emptySelector, attrs, attrNames, issuerAttributeNames); resultSet.addAll(createCRLs(list, selector)); } return resultSet; } /** * Returns the revocation list for revoked attribute certificates. *

* The attributeCertificateRevocationList holds a list of attribute * certificates that have been revoked. * * @param selector The CRL selector to use to find the CRLs. * @return A possible empty collection with CRLs. * @throws StoreException */ public Collection getAttributeCertificateRevocationLists( X509CRLStoreSelector selector) throws StoreException { String[] attrs = splitString(params .getAttributeCertificateRevocationListAttribute()); String attrNames[] = splitString(params .getLdapAttributeCertificateRevocationListAttributeName()); String issuerAttributeNames[] = splitString(params .getAttributeCertificateRevocationListIssuerAttributeName()); List list = cRLIssuerSearch(selector, attrs, attrNames, issuerAttributeNames); Set resultSet = createCRLs(list, selector); if (resultSet.size() == 0) { X509CRLStoreSelector emptySelector = new X509CRLStoreSelector(); list = cRLIssuerSearch(emptySelector, attrs, attrNames, issuerAttributeNames); resultSet.addAll(createCRLs(list, selector)); } return resultSet; } /** * Returns the revocation list for revoked attribute certificates for an * attribute authority *

* The attributeAuthorityList holds a list of AA certificates that have been * revoked. * * @param selector The CRL selector to use to find the CRLs. * @return A possible empty collection with CRLs * @throws StoreException */ public Collection getAttributeAuthorityRevocationLists( X509CRLStoreSelector selector) throws StoreException { String[] attrs = splitString(params.getAttributeAuthorityRevocationListAttribute()); String attrNames[] = splitString(params .getLdapAttributeAuthorityRevocationListAttributeName()); String issuerAttributeNames[] = splitString(params .getAttributeAuthorityRevocationListIssuerAttributeName()); List list = cRLIssuerSearch(selector, attrs, attrNames, issuerAttributeNames); Set resultSet = createCRLs(list, selector); if (resultSet.size() == 0) { X509CRLStoreSelector emptySelector = new X509CRLStoreSelector(); list = cRLIssuerSearch(emptySelector, attrs, attrNames, issuerAttributeNames); resultSet.addAll(createCRLs(list, selector)); } return resultSet; } /** * Returns cross certificate pairs. * * @param selector The selector to use to find the cross certificates. * @return A possible empty collection with {@link X509CertificatePair}s * @throws StoreException */ public Collection getCrossCertificatePairs( X509CertPairStoreSelector selector) throws StoreException { String[] attrs = splitString(params.getCrossCertificateAttribute()); String attrNames[] = splitString(params.getLdapCrossCertificateAttributeName()); String subjectAttributeNames[] = splitString(params .getCrossCertificateSubjectAttributeName()); List list = crossCertificatePairSubjectSearch(selector, attrs, attrNames, subjectAttributeNames); Set resultSet = createCrossCertificatePairs(list, selector); if (resultSet.size() == 0) { X509CertStoreSelector emptyCertselector = new X509CertStoreSelector(); X509CertPairStoreSelector emptySelector = new X509CertPairStoreSelector(); emptySelector.setForwardSelector(emptyCertselector); emptySelector.setReverseSelector(emptyCertselector); list = crossCertificatePairSubjectSearch(emptySelector, attrs, attrNames, subjectAttributeNames); resultSet.addAll(createCrossCertificatePairs(list, selector)); } return resultSet; } /** * Returns end certificates. *

* The attributeDescriptorCertificate is self signed by a source of * authority and holds a description of the privilege and its delegation * rules. * * @param selector The selector to find the certificates. * @return A possible empty collection with certificates. * @throws StoreException */ public Collection getUserCertificates(X509CertStoreSelector selector) throws StoreException { String[] attrs = splitString(params.getUserCertificateAttribute()); String attrNames[] = splitString(params.getLdapUserCertificateAttributeName()); String subjectAttributeNames[] = splitString(params .getUserCertificateSubjectAttributeName()); List list = certSubjectSerialSearch(selector, attrs, attrNames, subjectAttributeNames); Set resultSet = createCerts(list, selector); if (resultSet.size() == 0) { X509CertStoreSelector emptySelector = new X509CertStoreSelector(); list = certSubjectSerialSearch(emptySelector, attrs, attrNames, subjectAttributeNames); resultSet.addAll(createCerts(list, selector)); } return resultSet; } /** * Returns attribute certificates for an attribute authority *

* The aAcertificate holds the privileges of an attribute authority. * * @param selector The selector to find the attribute certificates. * @return A possible empty collection with attribute certificates. * @throws StoreException */ public Collection getAACertificates(X509AttributeCertStoreSelector selector) throws StoreException { String[] attrs = splitString(params.getAACertificateAttribute()); String attrNames[] = splitString(params.getLdapAACertificateAttributeName()); String subjectAttributeNames[] = splitString(params.getAACertificateSubjectAttributeName()); List list = attrCertSubjectSerialSearch(selector, attrs, attrNames, subjectAttributeNames); Set resultSet = createAttributeCertificates(list, selector); if (resultSet.size() == 0) { X509AttributeCertStoreSelector emptySelector = new X509AttributeCertStoreSelector(); list = attrCertSubjectSerialSearch(emptySelector, attrs, attrNames, subjectAttributeNames); resultSet.addAll(createAttributeCertificates(list, selector)); } return resultSet; } /** * Returns an attribute certificate for an authority *

* The attributeDescriptorCertificate is self signed by a source of * authority and holds a description of the privilege and its delegation * rules. * * @param selector The selector to find the attribute certificates. * @return A possible empty collection with attribute certificates. * @throws StoreException */ public Collection getAttributeDescriptorCertificates( X509AttributeCertStoreSelector selector) throws StoreException { String[] attrs = splitString(params.getAttributeDescriptorCertificateAttribute()); String attrNames[] = splitString(params .getLdapAttributeDescriptorCertificateAttributeName()); String subjectAttributeNames[] = splitString(params .getAttributeDescriptorCertificateSubjectAttributeName()); List list = attrCertSubjectSerialSearch(selector, attrs, attrNames, subjectAttributeNames); Set resultSet = createAttributeCertificates(list, selector); if (resultSet.size() == 0) { X509AttributeCertStoreSelector emptySelector = new X509AttributeCertStoreSelector(); list = attrCertSubjectSerialSearch(emptySelector, attrs, attrNames, subjectAttributeNames); resultSet.addAll(createAttributeCertificates(list, selector)); } return resultSet; } /** * Returns CA certificates. *

* The cACertificate attribute of a CA's directory entry shall be used to * store self-issued certificates (if any) and certificates issued to this * CA by CAs in the same realm as this CA. * * @param selector The selector to find the certificates. * @return A possible empty collection with certificates. * @throws StoreException */ public Collection getCACertificates(X509CertStoreSelector selector) throws StoreException { String[] attrs = splitString(params.getCACertificateAttribute()); String attrNames[] = splitString(params.getLdapCACertificateAttributeName()); String subjectAttributeNames[] = splitString(params .getCACertificateSubjectAttributeName()); List list = certSubjectSerialSearch(selector, attrs, attrNames, subjectAttributeNames); Set resultSet = createCerts(list, selector); if (resultSet.size() == 0) { X509CertStoreSelector emptySelector = new X509CertStoreSelector(); list = certSubjectSerialSearch(emptySelector, attrs, attrNames, subjectAttributeNames); resultSet.addAll(createCerts(list, selector)); } return resultSet; } /** * Returns the delta revocation list for revoked certificates. * * @param selector The CRL selector to use to find the CRLs. * @return A possible empty collection with CRLs. * @throws StoreException */ public Collection getDeltaCertificateRevocationLists( X509CRLStoreSelector selector) throws StoreException { String[] attrs = splitString(params.getDeltaRevocationListAttribute()); String attrNames[] = splitString(params.getLdapDeltaRevocationListAttributeName()); String issuerAttributeNames[] = splitString(params .getDeltaRevocationListIssuerAttributeName()); List list = cRLIssuerSearch(selector, attrs, attrNames, issuerAttributeNames); Set resultSet = createCRLs(list, selector); if (resultSet.size() == 0) { X509CRLStoreSelector emptySelector = new X509CRLStoreSelector(); list = cRLIssuerSearch(emptySelector, attrs, attrNames, issuerAttributeNames); resultSet.addAll(createCRLs(list, selector)); } return resultSet; } /** * Returns an attribute certificate for an user. *

* The attributeCertificateAttribute holds the privileges of a user * * @param selector The selector to find the attribute certificates. * @return A possible empty collection with attribute certificates. * @throws StoreException */ public Collection getAttributeCertificateAttributes( X509AttributeCertStoreSelector selector) throws StoreException { String[] attrs = splitString(params.getAttributeCertificateAttributeAttribute()); String attrNames[] = splitString(params .getLdapAttributeCertificateAttributeAttributeName()); String subjectAttributeNames[] = splitString(params .getAttributeCertificateAttributeSubjectAttributeName()); List list = attrCertSubjectSerialSearch(selector, attrs, attrNames, subjectAttributeNames); Set resultSet = createAttributeCertificates(list, selector); if (resultSet.size() == 0) { X509AttributeCertStoreSelector emptySelector = new X509AttributeCertStoreSelector(); list = attrCertSubjectSerialSearch(emptySelector, attrs, attrNames, subjectAttributeNames); resultSet.addAll(createAttributeCertificates(list, selector)); } return resultSet; } /** * Returns the certificate revocation lists for revoked certificates. * * @param selector The CRL selector to use to find the CRLs. * @return A possible empty collection with CRLs. * @throws StoreException */ public Collection getCertificateRevocationLists( X509CRLStoreSelector selector) throws StoreException { String[] attrs = splitString(params.getCertificateRevocationListAttribute()); String attrNames[] = splitString(params .getLdapCertificateRevocationListAttributeName()); String issuerAttributeNames[] = splitString(params .getCertificateRevocationListIssuerAttributeName()); List list = cRLIssuerSearch(selector, attrs, attrNames, issuerAttributeNames); Set resultSet = createCRLs(list, selector); if (resultSet.size() == 0) { X509CRLStoreSelector emptySelector = new X509CRLStoreSelector(); list = cRLIssuerSearch(emptySelector, attrs, attrNames, issuerAttributeNames); resultSet.addAll(createCRLs(list, selector)); } return resultSet; } private Map cacheMap = new HashMap(cacheSize); private static int cacheSize = 32; private static long lifeTime = 60 * 1000; private synchronized void addToCache(String searchCriteria, List list) { Date now = new Date(System.currentTimeMillis()); List cacheEntry = new ArrayList(); cacheEntry.add(now); cacheEntry.add(list); if (cacheMap.containsKey(searchCriteria)) { cacheMap.put(searchCriteria, cacheEntry); } else { if (cacheMap.size() >= cacheSize) { // replace oldest Iterator it = cacheMap.entrySet().iterator(); long oldest = now.getTime(); Object replace = null; while (it.hasNext()) { Map.Entry entry = (Map.Entry)it.next(); long current = ((Date)((List)entry.getValue()).get(0)) .getTime(); if (current < oldest) { oldest = current; replace = entry.getKey(); } } cacheMap.remove(replace); } cacheMap.put(searchCriteria, cacheEntry); } } private List getFromCache(String searchCriteria) { List entry = (List)cacheMap.get(searchCriteria); long now = System.currentTimeMillis(); if (entry != null) { // too old if (((Date)entry.get(0)).getTime() < (now - lifeTime)) { return null; } return (List)entry.get(1); } return null; } /* * spilt string based on spaces */ private String[] splitString(String str) { return str.split("\\s+"); } private String getSubjectAsString(X509CertStoreSelector xselector) { try { byte[] encSubject = xselector.getSubjectAsBytes(); if (encSubject != null) { return new X500Principal(encSubject).getName("RFC1779"); } } catch (IOException e) { throw new StoreException("exception processing name: " + e.getMessage(), e); } return null; } private X500Principal getCertificateIssuer(X509Certificate cert) { return cert.getIssuerX500Principal(); } } bouncycastle-1.49.orig/jdk1.4/org/bouncycastle/x509/X509CRLStoreSelector.java0000644000175000017500000002431410772047440026013 0ustar ebourgebourgpackage org.bouncycastle.x509; import org.bouncycastle.asn1.DERInteger; import org.bouncycastle.asn1.x509.X509Extensions; import org.bouncycastle.util.Arrays; import org.bouncycastle.util.Selector; import org.bouncycastle.x509.extension.X509ExtensionUtil; import java.io.IOException; import java.math.BigInteger; import java.security.cert.CRL; import java.security.cert.X509CRL; import java.security.cert.X509CRLSelector; /** * This class is a Selector implementation for X.509 certificate revocation * lists. * * @see org.bouncycastle.util.Selector * @see org.bouncycastle.x509.X509Store * @see org.bouncycastle.jce.provider.X509StoreCRLCollection */ public class X509CRLStoreSelector extends X509CRLSelector implements Selector { private boolean deltaCRLIndicator = false; private boolean completeCRLEnabled = false; private BigInteger maxBaseCRLNumber = null; private byte[] issuingDistributionPoint = null; private boolean issuingDistributionPointEnabled = false; private X509AttributeCertificate attrCertChecking; /** * Returns if the issuing distribution point criteria should be applied. * Defaults to false. *

* You may also set the issuing distribution point criteria if not a missing * issuing distribution point should be assumed. * * @return Returns if the issuing distribution point check is enabled. */ public boolean isIssuingDistributionPointEnabled() { return issuingDistributionPointEnabled; } /** * Enables or disables the issuing distribution point check. * * @param issuingDistributionPointEnabled true to enable the * issuing distribution point check. */ public void setIssuingDistributionPointEnabled( boolean issuingDistributionPointEnabled) { this.issuingDistributionPointEnabled = issuingDistributionPointEnabled; } /** * Sets the attribute certificate being checked. This is not a criterion. * Rather, it is optional information that may help a {@link X509Store} find * CRLs that would be relevant when checking revocation for the specified * attribute certificate. If null is specified, then no such * optional information is provided. * * @param attrCert the X509AttributeCertificate being checked (or * null) * @see #getAttrCertificateChecking() */ public void setAttrCertificateChecking(X509AttributeCertificate attrCert) { attrCertChecking = attrCert; } /** * Returns the attribute certificate being checked. * * @return Returns the attribute certificate being checked. * @see #setAttrCertificateChecking(X509AttributeCertificate) */ public X509AttributeCertificate getAttrCertificateChecking() { return attrCertChecking; } public boolean match(Object obj) { if (!(obj instanceof X509CRL)) { return false; } X509CRL crl = (X509CRL)obj; DERInteger dci = null; try { byte[] bytes = crl .getExtensionValue(X509Extensions.DeltaCRLIndicator.getId()); if (bytes != null) { dci = DERInteger.getInstance(X509ExtensionUtil .fromExtensionValue(bytes)); } } catch (Exception e) { return false; } if (isDeltaCRLIndicatorEnabled()) { if (dci == null) { return false; } } if (isCompleteCRLEnabled()) { if (dci != null) { return false; } } if (dci != null) { if (maxBaseCRLNumber != null) { if (dci.getPositiveValue().compareTo(maxBaseCRLNumber) == 1) { return false; } } } if (issuingDistributionPointEnabled) { byte[] idp = crl .getExtensionValue(X509Extensions.IssuingDistributionPoint .getId()); if (issuingDistributionPoint == null) { if (idp != null) { return false; } } else { if (!Arrays.areEqual(idp, issuingDistributionPoint)) { return false; } } } return super.match((X509CRL)obj); } public boolean match(CRL crl) { return match((Object)crl); } /** * Returns if this selector must match CRLs with the delta CRL indicator * extension set. Defaults to false. * * @return Returns true if only CRLs with the delta CRL * indicator extension are selected. */ public boolean isDeltaCRLIndicatorEnabled() { return deltaCRLIndicator; } /** * If this is set to true the CRL reported contains the delta * CRL indicator CRL extension. *

* {@link #setCompleteCRLEnabled(boolean)} and * {@link #setDeltaCRLIndicatorEnabled(boolean)} excluded each other. * * @param deltaCRLIndicator true if the delta CRL indicator * extension must be in the CRL. */ public void setDeltaCRLIndicatorEnabled(boolean deltaCRLIndicator) { this.deltaCRLIndicator = deltaCRLIndicator; } /** * Returns an instance of this from a X509CRLSelector. * * @param selector A X509CRLSelector instance. * @return An instance of an X509CRLStoreSelector. * @exception IllegalArgumentException if selector is null or creation * fails. */ public static X509CRLStoreSelector getInstance(X509CRLSelector selector) { if (selector == null) { throw new IllegalArgumentException( "cannot create from null selector"); } X509CRLStoreSelector cs = new X509CRLStoreSelector(); cs.setCertificateChecking(selector.getCertificateChecking()); cs.setDateAndTime(selector.getDateAndTime()); try { cs.setIssuerNames(selector.getIssuerNames()); } catch (IOException e) { // cannot happen throw new IllegalArgumentException(e.getMessage()); } //cs.setIssuers(selector.getIssuers()); cs.setMaxCRLNumber(selector.getMaxCRL()); cs.setMinCRLNumber(selector.getMinCRL()); return cs; } public Object clone() { X509CRLStoreSelector sel = X509CRLStoreSelector.getInstance(this); sel.deltaCRLIndicator = deltaCRLIndicator; sel.completeCRLEnabled = completeCRLEnabled; sel.maxBaseCRLNumber = maxBaseCRLNumber; sel.attrCertChecking = attrCertChecking; sel.issuingDistributionPointEnabled = issuingDistributionPointEnabled; sel.issuingDistributionPoint = Arrays.clone(issuingDistributionPoint); return sel; } /** * If true only complete CRLs are returned. Defaults to * false. * * @return true if only complete CRLs are returned. */ public boolean isCompleteCRLEnabled() { return completeCRLEnabled; } /** * If set to true only complete CRLs are returned. *

* {@link #setCompleteCRLEnabled(boolean)} and * {@link #setDeltaCRLIndicatorEnabled(boolean)} excluded each other. * * @param completeCRLEnabled true if only complete CRLs * should be returned. */ public void setCompleteCRLEnabled(boolean completeCRLEnabled) { this.completeCRLEnabled = completeCRLEnabled; } /** * Get the maximum base CRL number. Defaults to null. * * @return Returns the maximum base CRL number. * @see #setMaxBaseCRLNumber(BigInteger) */ public BigInteger getMaxBaseCRLNumber() { return maxBaseCRLNumber; } /** * Sets the maximum base CRL number. Setting to null disables * this cheack. *

* This is only meaningful for delta CRLs. Complete CRLs must have a CRL * number which is greater or equal than the base number of the * corresponding CRL. * * @param maxBaseCRLNumber The maximum base CRL number to set. */ public void setMaxBaseCRLNumber(BigInteger maxBaseCRLNumber) { this.maxBaseCRLNumber = maxBaseCRLNumber; } /** * Returns the issuing distribution point. Defaults to null, * which is a missing issuing distribution point extension. *

* The internal byte array is cloned before it is returned. *

* The criteria must be enable with * {@link #setIssuingDistributionPointEnabled(boolean)}. * * @return Returns the issuing distribution point. * @see #setIssuingDistributionPoint(byte[]) */ public byte[] getIssuingDistributionPoint() { return Arrays.clone(issuingDistributionPoint); } /** * Sets the issuing distribution point. *

* The issuing distribution point extension is a CRL extension which * identifies the scope and the distribution point of a CRL. The scope * contains among others information about revocation reasons contained in * the CRL. Delta CRLs and complete CRLs must have matching issuing * distribution points. *

* The byte array is cloned to protect against subsequent modifications. *

* You must also enable or disable this criteria with * {@link #setIssuingDistributionPointEnabled(boolean)}. * * @param issuingDistributionPoint The issuing distribution point to set. * This is the DER encoded OCTET STRING extension value. * @see #getIssuingDistributionPoint() */ public void setIssuingDistributionPoint(byte[] issuingDistributionPoint) { this.issuingDistributionPoint = Arrays.clone(issuingDistributionPoint); } } bouncycastle-1.49.orig/jdk1.4/org/bouncycastle/x509/X509CertStoreSelector.java0000644000175000017500000000546110772047467026303 0ustar ebourgebourgpackage org.bouncycastle.x509; import org.bouncycastle.util.Selector; import java.io.IOException; import java.security.cert.Certificate; import java.security.cert.X509CertSelector; import java.security.cert.X509Certificate; /** * This class is a Selector implementation for X.509 certificates. * * @see org.bouncycastle.util.Selector * @see org.bouncycastle.x509.X509Store * @see org.bouncycastle.jce.provider.X509StoreCertCollection */ public class X509CertStoreSelector extends X509CertSelector implements Selector { public boolean match(Object obj) { if (!(obj instanceof X509Certificate)) { return false; } X509Certificate other = (X509Certificate)obj; return super.match(other); } public boolean match(Certificate cert) { return match((Object)cert); } public Object clone() { X509CertStoreSelector selector = (X509CertStoreSelector)super.clone(); return selector; } /** * Returns an instance of this from a X509CertSelector. * * @param selector A X509CertSelector instance. * @return An instance of an X509CertStoreSelector. * @exception IllegalArgumentException if selector is null or creation fails. */ public static X509CertStoreSelector getInstance(X509CertSelector selector) { if (selector == null) { throw new IllegalArgumentException("cannot create from null selector"); } X509CertStoreSelector cs = new X509CertStoreSelector(); cs.setAuthorityKeyIdentifier(selector.getAuthorityKeyIdentifier()); cs.setBasicConstraints(selector.getBasicConstraints()); cs.setCertificate(selector.getCertificate()); cs.setCertificateValid(selector.getCertificateValid()); cs.setMatchAllSubjectAltNames(selector.getMatchAllSubjectAltNames()); try { cs.setPathToNames(selector.getPathToNames()); cs.setExtendedKeyUsage(selector.getExtendedKeyUsage()); cs.setNameConstraints(selector.getNameConstraints()); cs.setPolicy(selector.getPolicy()); cs.setSubjectPublicKeyAlgID(selector.getSubjectPublicKeyAlgID()); cs.setIssuer(selector.getIssuerAsBytes()); cs.setSubject(selector.getSubjectAsBytes()); } catch (IOException e) { throw new IllegalArgumentException("error in passed in selector: " + e); } cs.setKeyUsage(selector.getKeyUsage()); cs.setPrivateKeyValid(selector.getPrivateKeyValid()); cs.setSerialNumber(selector.getSerialNumber()); cs.setSubjectKeyIdentifier(selector.getSubjectKeyIdentifier()); cs.setSubjectPublicKey(selector.getSubjectPublicKey()); return cs; } } bouncycastle-1.49.orig/jdk1.4/org/bouncycastle/jcajce/0000755000175000017500000000000012152033550022121 5ustar ebourgebourgbouncycastle-1.49.orig/jdk1.4/org/bouncycastle/jcajce/provider/0000755000175000017500000000000012152033550023753 5ustar ebourgebourgbouncycastle-1.49.orig/jdk1.4/org/bouncycastle/jcajce/provider/asymmetric/0000755000175000017500000000000012152033550026130 5ustar ebourgebourgbouncycastle-1.49.orig/jdk1.4/org/bouncycastle/jcajce/provider/asymmetric/util/0000755000175000017500000000000012152033550027105 5ustar ebourgebourgbouncycastle-1.49.orig/jdk1.4/org/bouncycastle/jcajce/provider/asymmetric/util/ECUtil.java0000644000175000017500000001447012132471344031110 0ustar ebourgebourgpackage org.bouncycastle.jcajce.provider.asymmetric.util; import java.security.InvalidKeyException; import java.security.PrivateKey; import java.security.PublicKey; import org.bouncycastle.asn1.ASN1ObjectIdentifier; import org.bouncycastle.asn1.cryptopro.ECGOST3410NamedCurves; import org.bouncycastle.asn1.nist.NISTNamedCurves; import org.bouncycastle.asn1.sec.SECNamedCurves; import org.bouncycastle.asn1.teletrust.TeleTrusTNamedCurves; import org.bouncycastle.asn1.x9.X962NamedCurves; import org.bouncycastle.asn1.x9.X9ECParameters; import org.bouncycastle.crypto.params.AsymmetricKeyParameter; import org.bouncycastle.crypto.params.ECDomainParameters; import org.bouncycastle.crypto.params.ECPrivateKeyParameters; import org.bouncycastle.crypto.params.ECPublicKeyParameters; import org.bouncycastle.jce.interfaces.ECPrivateKey; import org.bouncycastle.jce.interfaces.ECPublicKey; import org.bouncycastle.jce.provider.BouncyCastleProvider; import org.bouncycastle.jcajce.provider.asymmetric.ec.BCECPublicKey; import org.bouncycastle.jce.spec.ECParameterSpec; /** * utility class for converting jce/jca ECDSA, ECDH, and ECDHC * objects into their org.bouncycastle.crypto counterparts. */ public class ECUtil { /** * Returns a sorted array of middle terms of the reduction polynomial. * @param k The unsorted array of middle terms of the reduction polynomial * of length 1 or 3. * @return the sorted array of middle terms of the reduction polynomial. * This array always has length 3. */ static int[] convertMidTerms( int[] k) { int[] res = new int[3]; if (k.length == 1) { res[0] = k[0]; } else { if (k.length != 3) { throw new IllegalArgumentException("Only Trinomials and pentanomials supported"); } if (k[0] < k[1] && k[0] < k[2]) { res[0] = k[0]; if (k[1] < k[2]) { res[1] = k[1]; res[2] = k[2]; } else { res[1] = k[2]; res[2] = k[1]; } } else if (k[1] < k[2]) { res[0] = k[1]; if (k[0] < k[2]) { res[1] = k[0]; res[2] = k[2]; } else { res[1] = k[2]; res[2] = k[0]; } } else { res[0] = k[2]; if (k[0] < k[1]) { res[1] = k[0]; res[2] = k[1]; } else { res[1] = k[1]; res[2] = k[0]; } } } return res; } public static AsymmetricKeyParameter generatePublicKeyParameter( PublicKey key) throws InvalidKeyException { if (key instanceof ECPublicKey) { ECPublicKey k = (ECPublicKey)key; ECParameterSpec s = k.getParameters(); if (s == null) { s = BouncyCastleProvider.CONFIGURATION.getEcImplicitlyCa(); return new ECPublicKeyParameters( ((BCECPublicKey)k).engineGetQ(), new ECDomainParameters(s.getCurve(), s.getG(), s.getN(), s.getH(), s.getSeed())); } else { return new ECPublicKeyParameters( k.getQ(), new ECDomainParameters(s.getCurve(), s.getG(), s.getN(), s.getH(), s.getSeed())); } } throw new InvalidKeyException("cannot identify EC public key."); } public static AsymmetricKeyParameter generatePrivateKeyParameter( PrivateKey key) throws InvalidKeyException { if (key instanceof ECPrivateKey) { ECPrivateKey k = (ECPrivateKey)key; ECParameterSpec s = k.getParameters(); if (s == null) { s = BouncyCastleProvider.CONFIGURATION.getEcImplicitlyCa(); } return new ECPrivateKeyParameters( k.getD(), new ECDomainParameters(s.getCurve(), s.getG(), s.getN(), s.getH(), s.getSeed())); } throw new InvalidKeyException("can't identify EC private key."); } public static ASN1ObjectIdentifier getNamedCurveOid( String name) { ASN1ObjectIdentifier oid = X962NamedCurves.getOID(name); if (oid == null) { oid = SECNamedCurves.getOID(name); if (oid == null) { oid = NISTNamedCurves.getOID(name); } if (oid == null) { oid = TeleTrusTNamedCurves.getOID(name); } if (oid == null) { oid = ECGOST3410NamedCurves.getOID(name); } } return oid; } public static X9ECParameters getNamedCurveByOid( ASN1ObjectIdentifier oid) { X9ECParameters params = X962NamedCurves.getByOID(oid); if (params == null) { params = SECNamedCurves.getByOID(oid); if (params == null) { params = NISTNamedCurves.getByOID(oid); } if (params == null) { params = TeleTrusTNamedCurves.getByOID(oid); } } return params; } public static String getCurveName( ASN1ObjectIdentifier oid) { String name = X962NamedCurves.getName(oid); if (name == null) { name = SECNamedCurves.getName(oid); if (name == null) { name = NISTNamedCurves.getName(oid); } if (name == null) { name = TeleTrusTNamedCurves.getName(oid); } if (name == null) { name = ECGOST3410NamedCurves.getName(oid); } } return name; } } bouncycastle-1.49.orig/jdk1.4/org/bouncycastle/jcajce/provider/asymmetric/util/DSABase.java0000644000175000017500000000631111703465111031156 0ustar ebourgebourgpackage org.bouncycastle.jcajce.provider.asymmetric.util; import java.math.BigInteger; import java.security.InvalidKeyException; import java.security.PrivateKey; import java.security.SecureRandom; import java.security.Signature; import java.security.SignatureException; import java.security.spec.AlgorithmParameterSpec; import org.bouncycastle.asn1.pkcs.PKCSObjectIdentifiers; import org.bouncycastle.asn1.x509.X509ObjectIdentifiers; import org.bouncycastle.crypto.DSA; import org.bouncycastle.crypto.Digest; public abstract class DSABase extends Signature implements PKCSObjectIdentifiers, X509ObjectIdentifiers { protected Digest digest; protected DSA signer; protected DSAEncoder encoder; protected DSABase( String name, Digest digest, DSA signer, DSAEncoder encoder) { super(name); this.digest = digest; this.signer = signer; this.encoder = encoder; } protected void engineInitSign( PrivateKey privateKey) throws InvalidKeyException { doEngineInitSign(privateKey, appRandom); } protected void engineUpdate( byte b) throws SignatureException { digest.update(b); } protected void engineUpdate( byte[] b, int off, int len) throws SignatureException { digest.update(b, off, len); } protected byte[] engineSign() throws SignatureException { byte[] hash = new byte[digest.getDigestSize()]; digest.doFinal(hash, 0); try { BigInteger[] sig = signer.generateSignature(hash); return encoder.encode(sig[0], sig[1]); } catch (Exception e) { throw new SignatureException(e.toString()); } } protected boolean engineVerify( byte[] sigBytes) throws SignatureException { byte[] hash = new byte[digest.getDigestSize()]; digest.doFinal(hash, 0); BigInteger[] sig; try { sig = encoder.decode(sigBytes); } catch (Exception e) { throw new SignatureException("error decoding signature bytes."); } return signer.verifySignature(hash, sig[0], sig[1]); } protected void engineSetParameter( AlgorithmParameterSpec params) { throw new UnsupportedOperationException("engineSetParameter unsupported"); } /** * @deprecated replaced with */ protected void engineSetParameter( String param, Object value) { throw new UnsupportedOperationException("engineSetParameter unsupported"); } /** * @deprecated */ protected Object engineGetParameter( String param) { throw new UnsupportedOperationException("engineSetParameter unsupported"); } protected abstract void doEngineInitSign(PrivateKey privateKey, SecureRandom random) throws InvalidKeyException; } bouncycastle-1.49.orig/jdk1.4/org/bouncycastle/jcajce/provider/asymmetric/ecgost/0000755000175000017500000000000012152033550027414 5ustar ebourgebourg././@LongLink0000000000000000000000000000015400000000000011565 Lustar rootrootbouncycastle-1.49.orig/jdk1.4/org/bouncycastle/jcajce/provider/asymmetric/ecgost/BCECGOST3410PublicKey.javabouncycastle-1.49.orig/jdk1.4/org/bouncycastle/jcajce/provider/asymmetric/ecgost/BCECGOST3410PublicK0000644000175000017500000003520212110037231032306 0ustar ebourgebourgpackage org.bouncycastle.jcajce.provider.asymmetric.ecgost; import java.io.IOException; import java.io.ObjectInputStream; import java.io.ObjectOutputStream; import java.math.BigInteger; import org.bouncycastle.asn1.ASN1Encodable; import org.bouncycastle.asn1.ASN1ObjectIdentifier; import org.bouncycastle.asn1.ASN1OctetString; import org.bouncycastle.asn1.ASN1Primitive; import org.bouncycastle.asn1.ASN1Sequence; import org.bouncycastle.asn1.DERBitString; import org.bouncycastle.asn1.DERNull; import org.bouncycastle.asn1.DERObjectIdentifier; import org.bouncycastle.asn1.DEROctetString; import org.bouncycastle.asn1.cryptopro.CryptoProObjectIdentifiers; import org.bouncycastle.asn1.cryptopro.ECGOST3410NamedCurves; import org.bouncycastle.asn1.cryptopro.GOST3410PublicKeyAlgParameters; import org.bouncycastle.asn1.x509.AlgorithmIdentifier; import org.bouncycastle.asn1.x509.SubjectPublicKeyInfo; import org.bouncycastle.asn1.x9.X962Parameters; import org.bouncycastle.asn1.x9.X9ECParameters; import org.bouncycastle.asn1.x9.X9ECPoint; import org.bouncycastle.asn1.x9.X9IntegerConverter; import org.bouncycastle.asn1.x9.X9ObjectIdentifiers; import org.bouncycastle.crypto.params.ECDomainParameters; import org.bouncycastle.crypto.params.ECPublicKeyParameters; import org.bouncycastle.jcajce.provider.asymmetric.util.ECUtil; import org.bouncycastle.jcajce.provider.asymmetric.util.KeyUtil; import org.bouncycastle.jce.ECGOST3410NamedCurveTable; import org.bouncycastle.jce.interfaces.ECPointEncoder; import org.bouncycastle.jce.interfaces.ECPublicKey; import org.bouncycastle.jce.provider.BouncyCastleProvider; import org.bouncycastle.jce.spec.ECNamedCurveParameterSpec; import org.bouncycastle.jce.spec.ECParameterSpec; import org.bouncycastle.jce.spec.ECPublicKeySpec; import org.bouncycastle.math.ec.ECCurve; import org.bouncycastle.math.ec.ECPoint; public class BCECGOST3410PublicKey implements ECPublicKey, ECPointEncoder { private String algorithm = "ECGOST3410"; private boolean withCompression; private transient org.bouncycastle.math.ec.ECPoint q; private transient ECParameterSpec ecSpec; private transient GOST3410PublicKeyAlgParameters gostParams; public BCECGOST3410PublicKey( String algorithm, BCECGOST3410PublicKey key) { this.algorithm = algorithm; this.q = key.q; this.ecSpec = key.ecSpec; this.withCompression = key.withCompression; this.gostParams = key.gostParams; } public BCECGOST3410PublicKey( ECPublicKeySpec spec) { this.q = spec.getQ(); if (spec.getParams() != null) { this.ecSpec = spec.getParams(); } else { if (q.getCurve() == null) { org.bouncycastle.jce.spec.ECParameterSpec s = BouncyCastleProvider.CONFIGURATION.getEcImplicitlyCa(); q = s.getCurve().createPoint(q.getX().toBigInteger(), q.getY().toBigInteger(), false); } this.ecSpec = null; } } public BCECGOST3410PublicKey( String algorithm, ECPublicKeyParameters params, ECParameterSpec spec) { ECDomainParameters dp = params.getParameters(); this.algorithm = algorithm; this.q = params.getQ(); if (spec == null) { this.ecSpec = new ECParameterSpec( dp.getCurve(), dp.getG(), dp.getN(), dp.getH(), dp.getSeed()); } else { this.ecSpec = spec; } } public BCECGOST3410PublicKey( String algorithm, ECPublicKeyParameters params) { this.algorithm = algorithm; this.q = params.getQ(); this.ecSpec = null; } BCECGOST3410PublicKey( ECPublicKey key) { this.q = key.getQ(); this.algorithm = key.getAlgorithm(); this.ecSpec = key.getParameters(); } BCECGOST3410PublicKey( String algorithm, ECPoint q, ECParameterSpec ecSpec) { this.algorithm = algorithm; this.q = q; this.ecSpec = ecSpec; } BCECGOST3410PublicKey( SubjectPublicKeyInfo info) { populateFromPubKeyInfo(info); } private void populateFromPubKeyInfo(SubjectPublicKeyInfo info) { if (info.getAlgorithmId().getObjectId().equals(CryptoProObjectIdentifiers.gostR3410_2001)) { DERBitString bits = info.getPublicKeyData(); ASN1OctetString key; this.algorithm = "ECGOST3410"; try { key = (ASN1OctetString)ASN1Primitive.fromByteArray(bits.getBytes()); } catch (IOException ex) { throw new IllegalArgumentException("error recovering public key"); } byte[] keyEnc = key.getOctets(); byte[] x = new byte[32]; byte[] y = new byte[32]; for (int i = 0; i != x.length; i++) { x[i] = keyEnc[32 - 1 - i]; } for (int i = 0; i != y.length; i++) { y[i] = keyEnc[64 - 1 - i]; } gostParams = new GOST3410PublicKeyAlgParameters((ASN1Sequence)info.getAlgorithmId().getParameters()); ECNamedCurveParameterSpec spec = ECGOST3410NamedCurveTable.getParameterSpec(ECGOST3410NamedCurves.getName(gostParams.getPublicKeyParamSet())); ecSpec = spec; this.q = spec.getCurve().createPoint(new BigInteger(1, x), new BigInteger(1, y), false); } else { X962Parameters params = X962Parameters.getInstance(info.getAlgorithmId().getParameters()); ECCurve curve; if (params.isNamedCurve()) { ASN1ObjectIdentifier oid = ASN1ObjectIdentifier.getInstance(params.getParameters()); X9ECParameters ecP = ECUtil.getNamedCurveByOid(oid); ecSpec = new ECNamedCurveParameterSpec( ECUtil.getCurveName(oid), ecP.getCurve(), ecP.getG(), ecP.getN(), ecP.getH(), ecP.getSeed()); curve = ((ECParameterSpec)ecSpec).getCurve(); } else if (params.isImplicitlyCA()) { ecSpec = null; curve = BouncyCastleProvider.CONFIGURATION.getEcImplicitlyCa().getCurve(); } else { X9ECParameters ecP = X9ECParameters.getInstance(params.getParameters()); ecSpec = new ECParameterSpec( ecP.getCurve(), ecP.getG(), ecP.getN(), ecP.getH(), ecP.getSeed()); curve = ((ECParameterSpec)ecSpec).getCurve(); } DERBitString bits = info.getPublicKeyData(); byte[] data = bits.getBytes(); ASN1OctetString key = new DEROctetString(data); // // extra octet string - one of our old certs... // if (data[0] == 0x04 && data[1] == data.length - 2 && (data[2] == 0x02 || data[2] == 0x03)) { int qLength = new X9IntegerConverter().getByteLength(curve); if (qLength >= data.length - 3) { try { key = (ASN1OctetString)ASN1Primitive.fromByteArray(data); } catch (IOException ex) { throw new IllegalArgumentException("error recovering public key"); } } } X9ECPoint derQ = new X9ECPoint(curve, key); this.q = derQ.getPoint(); } } public String getAlgorithm() { return algorithm; } public String getFormat() { return "X.509"; } public byte[] getEncoded() { SubjectPublicKeyInfo info; if (algorithm.equals("ECGOST3410")) { ASN1Encodable params = null; if (gostParams != null) { params = gostParams; } else if (ecSpec instanceof ECNamedCurveParameterSpec) { params = new GOST3410PublicKeyAlgParameters( ECGOST3410NamedCurves.getOID(((ECNamedCurveParameterSpec)ecSpec).getName()), CryptoProObjectIdentifiers.gostR3411_94_CryptoProParamSet); } else { ECParameterSpec p = (ECParameterSpec)ecSpec; ECCurve curve = p.getG().getCurve(); ECPoint generator = curve.createPoint(p.getG().getX().toBigInteger(), p.getG().getY().toBigInteger(), withCompression); X9ECParameters ecP = new X9ECParameters( p.getCurve(), generator, p.getN(), p.getH(), p.getSeed()); params = new X962Parameters(ecP); } ECPoint qq = this.getQ(); ECPoint point = qq.getCurve().createPoint(qq.getX().toBigInteger(), qq.getY().toBigInteger(), false); ASN1OctetString p = ASN1OctetString.getInstance(new X9ECPoint(point)); BigInteger bX = this.q.getX().toBigInteger(); BigInteger bY = this.q.getY().toBigInteger(); byte[] encKey = new byte[64]; byte[] val = bX.toByteArray(); for (int i = 0; i != 32; i++) { encKey[i] = val[val.length - 1 - i]; } val = bY.toByteArray(); for (int i = 0; i != 32; i++) { encKey[32 + i] = val[val.length - 1 - i]; } try { info = new SubjectPublicKeyInfo(new AlgorithmIdentifier(CryptoProObjectIdentifiers.gostR3410_2001, params), new DEROctetString(encKey)); } catch (IOException e) { return null; } } else { X962Parameters params = null; if (ecSpec instanceof ECNamedCurveParameterSpec) { DERObjectIdentifier curveOid = ECUtil.getNamedCurveOid(((ECNamedCurveParameterSpec)ecSpec).getName()); if (curveOid == null) { curveOid = new DERObjectIdentifier(((ECNamedCurveParameterSpec)ecSpec).getName()); } params = new X962Parameters(curveOid); } else if (ecSpec == null) { params = new X962Parameters(DERNull.INSTANCE); } else { ECParameterSpec p = (ECParameterSpec)ecSpec; ECCurve curve = p.getG().getCurve(); ECPoint generator = curve.createPoint(p.getG().getX().toBigInteger(), p.getG().getY().toBigInteger(), withCompression); X9ECParameters ecP = new X9ECParameters( p.getCurve(), generator, p.getN(), p.getH(), p.getSeed()); params = new X962Parameters(ecP); } ECCurve curve = this.engineGetQ().getCurve(); ECPoint point = curve.createPoint(this.getQ().getX().toBigInteger(), this.getQ().getY().toBigInteger(), withCompression); ASN1OctetString p = ASN1OctetString.getInstance(new X9ECPoint(point)); info = new SubjectPublicKeyInfo(new AlgorithmIdentifier(X9ObjectIdentifiers.id_ecPublicKey, params), p.getOctets()); } return KeyUtil.getEncodedSubjectPublicKeyInfo(info); } public ECParameterSpec getParams() { return (ECParameterSpec)ecSpec; } public ECParameterSpec getParameters() { return (ECParameterSpec)ecSpec; } public org.bouncycastle.math.ec.ECPoint getQ() { if (ecSpec == null) { if (q instanceof org.bouncycastle.math.ec.ECPoint.Fp) { return new org.bouncycastle.math.ec.ECPoint.Fp(null, q.getX(), q.getY()); } else { return new org.bouncycastle.math.ec.ECPoint.F2m(null, q.getX(), q.getY()); } } return q; } public org.bouncycastle.math.ec.ECPoint engineGetQ() { return q; } public String toString() { StringBuffer buf = new StringBuffer(); String nl = System.getProperty("line.separator"); buf.append("EC Public Key").append(nl); buf.append(" X: ").append(this.getQ().getX().toBigInteger().toString(16)).append(nl); buf.append(" Y: ").append(this.getQ().getY().toBigInteger().toString(16)).append(nl); return buf.toString(); } public void setPointFormat(String style) { withCompression = !("UNCOMPRESSED".equalsIgnoreCase(style)); } ECParameterSpec engineGetSpec() { if (ecSpec != null) { return (ECParameterSpec)ecSpec; } return BouncyCastleProvider.CONFIGURATION.getEcImplicitlyCa(); } public boolean equals(Object o) { if (!(o instanceof BCECGOST3410PublicKey)) { return false; } BCECGOST3410PublicKey other = (BCECGOST3410PublicKey)o; return getQ().equals(other.getQ()) && (engineGetSpec().equals(other.engineGetSpec())); } public int hashCode() { return getQ().hashCode() ^ engineGetSpec().hashCode(); } private void readObject( ObjectInputStream in) throws IOException, ClassNotFoundException { in.defaultReadObject(); byte[] enc = (byte[])in.readObject(); populateFromPubKeyInfo(SubjectPublicKeyInfo.getInstance(ASN1Primitive.fromByteArray(enc))); } private void writeObject( ObjectOutputStream out) throws IOException { out.defaultWriteObject(); out.writeObject(this.getEncoded()); } } bouncycastle-1.49.orig/jdk1.4/org/bouncycastle/jcajce/provider/asymmetric/ecgost/SignatureSpi.java0000644000175000017500000001377312110037231032701 0ustar ebourgebourgpackage org.bouncycastle.jcajce.provider.asymmetric.ecgost; import java.math.BigInteger; import java.security.InvalidKeyException; import java.security.PrivateKey; import java.security.PublicKey; import java.security.SignatureException; import java.security.spec.AlgorithmParameterSpec; import org.bouncycastle.asn1.pkcs.PKCSObjectIdentifiers; import org.bouncycastle.asn1.x509.SubjectPublicKeyInfo; import org.bouncycastle.asn1.x509.X509ObjectIdentifiers; import org.bouncycastle.crypto.CipherParameters; import org.bouncycastle.crypto.DSA; import org.bouncycastle.crypto.Digest; import org.bouncycastle.crypto.digests.GOST3411Digest; import org.bouncycastle.crypto.params.ParametersWithRandom; import org.bouncycastle.crypto.signers.ECGOST3410Signer; import org.bouncycastle.jcajce.provider.asymmetric.util.ECUtil; import org.bouncycastle.jce.interfaces.ECKey; import org.bouncycastle.jce.interfaces.ECPublicKey; import org.bouncycastle.jce.interfaces.GOST3410Key; import org.bouncycastle.jce.provider.BouncyCastleProvider; import org.bouncycastle.jcajce.provider.asymmetric.util.GOST3410Util; public class SignatureSpi extends java.security.Signature implements PKCSObjectIdentifiers, X509ObjectIdentifiers { private Digest digest; private DSA signer; public SignatureSpi() { super("ECGOST3410"); this.digest = new GOST3411Digest(); this.signer = new ECGOST3410Signer(); } protected void engineInitVerify( PublicKey publicKey) throws InvalidKeyException { CipherParameters param; if (publicKey instanceof ECPublicKey) { param = ECUtil.generatePublicKeyParameter(publicKey); } else if (publicKey instanceof GOST3410Key) { param = GOST3410Util.generatePublicKeyParameter(publicKey); } else { try { byte[] bytes = publicKey.getEncoded(); publicKey = BouncyCastleProvider.getPublicKey(SubjectPublicKeyInfo.getInstance(bytes)); if (publicKey instanceof ECPublicKey) { param = ECUtil.generatePublicKeyParameter(publicKey); } else { throw new InvalidKeyException("can't recognise key type in DSA based signer"); } } catch (Exception e) { throw new InvalidKeyException("can't recognise key type in DSA based signer"); } } digest.reset(); signer.init(false, param); } protected void engineInitSign( PrivateKey privateKey) throws InvalidKeyException { CipherParameters param; if (privateKey instanceof ECKey) { param = ECUtil.generatePrivateKeyParameter(privateKey); } else { param = GOST3410Util.generatePrivateKeyParameter(privateKey); } digest.reset(); if (appRandom != null) { signer.init(true, new ParametersWithRandom(param, appRandom)); } else { signer.init(true, param); } } protected void engineUpdate( byte b) throws SignatureException { digest.update(b); } protected void engineUpdate( byte[] b, int off, int len) throws SignatureException { digest.update(b, off, len); } protected byte[] engineSign() throws SignatureException { byte[] hash = new byte[digest.getDigestSize()]; digest.doFinal(hash, 0); try { byte[] sigBytes = new byte[64]; BigInteger[] sig = signer.generateSignature(hash); byte[] r = sig[0].toByteArray(); byte[] s = sig[1].toByteArray(); if (s[0] != 0) { System.arraycopy(s, 0, sigBytes, 32 - s.length, s.length); } else { System.arraycopy(s, 1, sigBytes, 32 - (s.length - 1), s.length - 1); } if (r[0] != 0) { System.arraycopy(r, 0, sigBytes, 64 - r.length, r.length); } else { System.arraycopy(r, 1, sigBytes, 64 - (r.length - 1), r.length - 1); } return sigBytes; } catch (Exception e) { throw new SignatureException(e.toString()); } } protected boolean engineVerify( byte[] sigBytes) throws SignatureException { byte[] hash = new byte[digest.getDigestSize()]; digest.doFinal(hash, 0); BigInteger[] sig; try { byte[] r = new byte[32]; byte[] s = new byte[32]; System.arraycopy(sigBytes, 0, s, 0, 32); System.arraycopy(sigBytes, 32, r, 0, 32); sig = new BigInteger[2]; sig[0] = new BigInteger(1, r); sig[1] = new BigInteger(1, s); } catch (Exception e) { throw new SignatureException("error decoding signature bytes."); } return signer.verifySignature(hash, sig[0], sig[1]); } protected void engineSetParameter( AlgorithmParameterSpec params) { throw new UnsupportedOperationException("engineSetParameter unsupported"); } /** * @deprecated replaced with */ protected void engineSetParameter( String param, Object value) { throw new UnsupportedOperationException("engineSetParameter unsupported"); } /** * @deprecated */ protected Object engineGetParameter( String param) { throw new UnsupportedOperationException("engineSetParameter unsupported"); } } bouncycastle-1.49.orig/jdk1.4/org/bouncycastle/jcajce/provider/asymmetric/ecgost/KeyFactorySpi.java0000644000175000017500000000777211701450540033031 0ustar ebourgebourgpackage org.bouncycastle.jcajce.provider.asymmetric.ecgost; import java.io.IOException; import java.security.InvalidKeyException; import java.security.Key; import java.security.PrivateKey; import java.security.PublicKey; import java.security.spec.InvalidKeySpecException; import java.security.spec.KeySpec; import org.bouncycastle.asn1.ASN1ObjectIdentifier; import org.bouncycastle.asn1.cryptopro.CryptoProObjectIdentifiers; import org.bouncycastle.asn1.pkcs.PrivateKeyInfo; import org.bouncycastle.asn1.x509.SubjectPublicKeyInfo; import org.bouncycastle.jcajce.provider.asymmetric.util.BaseKeyFactorySpi; import org.bouncycastle.jce.interfaces.ECPrivateKey; import org.bouncycastle.jce.interfaces.ECPublicKey; import org.bouncycastle.jce.provider.BouncyCastleProvider; import org.bouncycastle.jce.spec.ECParameterSpec; import org.bouncycastle.jce.spec.ECPrivateKeySpec; import org.bouncycastle.jce.spec.ECPublicKeySpec; public class KeyFactorySpi extends BaseKeyFactorySpi { public KeyFactorySpi() { } protected KeySpec engineGetKeySpec( Key key, Class spec) throws InvalidKeySpecException { if (spec.isAssignableFrom(org.bouncycastle.jce.spec.ECPublicKeySpec.class) && key instanceof ECPublicKey) { ECPublicKey k = (ECPublicKey)key; if (k.getParams() != null) { return new org.bouncycastle.jce.spec.ECPublicKeySpec(k.getQ(), k.getParameters()); } else { ECParameterSpec implicitSpec = BouncyCastleProvider.CONFIGURATION.getEcImplicitlyCa(); return new org.bouncycastle.jce.spec.ECPublicKeySpec(k.getQ(), implicitSpec); } } else if (spec.isAssignableFrom(org.bouncycastle.jce.spec.ECPrivateKeySpec.class) && key instanceof ECPrivateKey) { ECPrivateKey k = (ECPrivateKey)key; if (k.getParams() != null) { return new org.bouncycastle.jce.spec.ECPrivateKeySpec(k.getD(), k.getParameters()); } else { ECParameterSpec implicitSpec = BouncyCastleProvider.CONFIGURATION.getEcImplicitlyCa(); return new org.bouncycastle.jce.spec.ECPrivateKeySpec(k.getD(), implicitSpec); } } return super.engineGetKeySpec(key, spec); } protected Key engineTranslateKey( Key key) throws InvalidKeyException { throw new InvalidKeyException("key type unknown"); } protected PrivateKey engineGeneratePrivate( KeySpec keySpec) throws InvalidKeySpecException { if (keySpec instanceof ECPrivateKeySpec) { return new BCECGOST3410PrivateKey((ECPrivateKeySpec)keySpec); } return super.engineGeneratePrivate(keySpec); } protected PublicKey engineGeneratePublic( KeySpec keySpec) throws InvalidKeySpecException { if (keySpec instanceof ECPublicKeySpec) { return new BCECGOST3410PublicKey((ECPublicKeySpec)keySpec); } return super.engineGeneratePublic(keySpec); } public PrivateKey generatePrivate(PrivateKeyInfo keyInfo) throws IOException { ASN1ObjectIdentifier algOid = keyInfo.getPrivateKeyAlgorithm().getAlgorithm(); if (algOid.equals(CryptoProObjectIdentifiers.gostR3410_2001)) { return new BCECGOST3410PrivateKey(keyInfo); } else { throw new IOException("algorithm identifier " + algOid + " in key not recognised"); } } public PublicKey generatePublic(SubjectPublicKeyInfo keyInfo) throws IOException { ASN1ObjectIdentifier algOid = keyInfo.getAlgorithm().getAlgorithm(); if (algOid.equals(CryptoProObjectIdentifiers.gostR3410_2001)) { return new BCECGOST3410PublicKey(keyInfo); } else { throw new IOException("algorithm identifier " + algOid + " in key not recognised"); } } } ././@LongLink0000000000000000000000000000015200000000000011563 Lustar rootrootbouncycastle-1.49.orig/jdk1.4/org/bouncycastle/jcajce/provider/asymmetric/ecgost/KeyPairGeneratorSpi.javabouncycastle-1.49.orig/jdk1.4/org/bouncycastle/jcajce/provider/asymmetric/ecgost/KeyPairGeneratorSpi0000644000175000017500000001150511726530737033247 0ustar ebourgebourgpackage org.bouncycastle.jcajce.provider.asymmetric.ecgost; import java.security.InvalidAlgorithmParameterException; import java.security.InvalidParameterException; import java.security.KeyPair; import java.security.SecureRandom; import java.security.spec.AlgorithmParameterSpec; import org.bouncycastle.asn1.cryptopro.ECGOST3410NamedCurves; import org.bouncycastle.crypto.AsymmetricCipherKeyPair; import org.bouncycastle.crypto.generators.ECKeyPairGenerator; import org.bouncycastle.crypto.params.ECDomainParameters; import org.bouncycastle.crypto.params.ECKeyGenerationParameters; import org.bouncycastle.crypto.params.ECPrivateKeyParameters; import org.bouncycastle.crypto.params.ECPublicKeyParameters; import org.bouncycastle.jce.provider.BouncyCastleProvider; import org.bouncycastle.jce.spec.ECNamedCurveGenParameterSpec; import org.bouncycastle.jce.spec.ECNamedCurveParameterSpec; import org.bouncycastle.jce.spec.ECParameterSpec; public class KeyPairGeneratorSpi extends java.security.KeyPairGenerator { ECParameterSpec ecParams = null; ECKeyPairGenerator engine = new ECKeyPairGenerator(); String algorithm = "ECGOST3410"; ECKeyGenerationParameters param; int strength = 239; SecureRandom random = null; boolean initialised = false; public KeyPairGeneratorSpi() { super("ECGOST3410"); } public void initialize( int strength, SecureRandom random) { this.strength = strength; this.random = random; if (ecParams != null) { param = new ECKeyGenerationParameters(new ECDomainParameters(ecParams.getCurve(), ecParams.getG(), ecParams.getN()), random); engine.init(param); initialised = true; } else { throw new InvalidParameterException("unknown key size."); } } public void initialize( AlgorithmParameterSpec params, SecureRandom random) throws InvalidAlgorithmParameterException { if (params instanceof ECParameterSpec) { ECParameterSpec p = (ECParameterSpec)params; this.ecParams = p; param = new ECKeyGenerationParameters(new ECDomainParameters(p.getCurve(), p.getG(), p.getN()), random); engine.init(param); initialised = true; } else if (params instanceof ECNamedCurveGenParameterSpec) { String curveName; curveName = ((ECNamedCurveGenParameterSpec)params).getName(); ECDomainParameters ecP = ECGOST3410NamedCurves.getByName(curveName); if (ecP == null) { throw new InvalidAlgorithmParameterException("unknown curve name: " + curveName); } this.ecParams = new ECNamedCurveParameterSpec( curveName, ecP.getCurve(), ecP.getG(), ecP.getN(), ecP.getH(), ecP.getSeed()); param = new ECKeyGenerationParameters(new ECDomainParameters(ecParams.getCurve(), ecParams.getG(), ecParams.getN()), random); engine.init(param); initialised = true; } else if (params == null && BouncyCastleProvider.CONFIGURATION.getEcImplicitlyCa() != null) { ECParameterSpec p = BouncyCastleProvider.CONFIGURATION.getEcImplicitlyCa(); this.ecParams = null; param = new ECKeyGenerationParameters(new ECDomainParameters(p.getCurve(), p.getG(), p.getN()), random); engine.init(param); initialised = true; } else if (params == null && BouncyCastleProvider.CONFIGURATION.getEcImplicitlyCa() == null) { throw new InvalidAlgorithmParameterException("null parameter passed but no implicitCA set"); } else { throw new InvalidAlgorithmParameterException("parameter object not a ECParameterSpec: " + params.getClass().getName()); } } public KeyPair generateKeyPair() { if (!initialised) { throw new IllegalStateException("EC Key Pair Generator not initialised"); } AsymmetricCipherKeyPair pair = engine.generateKeyPair(); ECPublicKeyParameters pub = (ECPublicKeyParameters)pair.getPublic(); ECPrivateKeyParameters priv = (ECPrivateKeyParameters)pair.getPrivate(); if (ecParams == null) { return new KeyPair(new BCECGOST3410PublicKey(algorithm, pub), new BCECGOST3410PrivateKey(algorithm, priv)); } else { ECParameterSpec p = (ECParameterSpec)ecParams; BCECGOST3410PublicKey pubKey = new BCECGOST3410PublicKey(algorithm, pub, p); return new KeyPair(pubKey, new BCECGOST3410PrivateKey(algorithm, priv, pubKey, p)); } } } ././@LongLink0000000000000000000000000000015500000000000011566 Lustar rootrootbouncycastle-1.49.orig/jdk1.4/org/bouncycastle/jcajce/provider/asymmetric/ecgost/BCECGOST3410PrivateKey.javabouncycastle-1.49.orig/jdk1.4/org/bouncycastle/jcajce/provider/asymmetric/ecgost/BCECGOST3410Private0000644000175000017500000002562512110037231032377 0ustar ebourgebourgpackage org.bouncycastle.jcajce.provider.asymmetric.ecgost; import java.io.ByteArrayOutputStream; import java.io.IOException; import java.io.ObjectInputStream; import java.io.ObjectOutputStream; import java.math.BigInteger; import java.util.Enumeration; import org.bouncycastle.asn1.ASN1Encodable; import org.bouncycastle.asn1.ASN1Integer; import org.bouncycastle.asn1.ASN1ObjectIdentifier; import org.bouncycastle.asn1.ASN1Primitive; import org.bouncycastle.asn1.ASN1Sequence; import org.bouncycastle.asn1.DERBitString; import org.bouncycastle.asn1.DERNull; import org.bouncycastle.asn1.DEROutputStream; import org.bouncycastle.asn1.cryptopro.CryptoProObjectIdentifiers; import org.bouncycastle.asn1.cryptopro.ECGOST3410NamedCurves; import org.bouncycastle.asn1.pkcs.PrivateKeyInfo; import org.bouncycastle.asn1.sec.ECPrivateKeyStructure; import org.bouncycastle.asn1.x509.AlgorithmIdentifier; import org.bouncycastle.asn1.x509.SubjectPublicKeyInfo; import org.bouncycastle.asn1.x9.X962Parameters; import org.bouncycastle.asn1.x9.X9ECParameters; import org.bouncycastle.asn1.x9.X9ObjectIdentifiers; import org.bouncycastle.crypto.params.ECDomainParameters; import org.bouncycastle.crypto.params.ECPrivateKeyParameters; import org.bouncycastle.jcajce.provider.asymmetric.util.ECUtil; import org.bouncycastle.jcajce.provider.asymmetric.util.KeyUtil; import org.bouncycastle.jcajce.provider.asymmetric.util.PKCS12BagAttributeCarrierImpl; import org.bouncycastle.jce.interfaces.ECPointEncoder; import org.bouncycastle.jce.interfaces.ECPrivateKey; import org.bouncycastle.jce.interfaces.PKCS12BagAttributeCarrier; import org.bouncycastle.jce.provider.BouncyCastleProvider; import org.bouncycastle.jce.spec.ECNamedCurveParameterSpec; import org.bouncycastle.jce.spec.ECParameterSpec; import org.bouncycastle.jce.spec.ECPrivateKeySpec; import org.bouncycastle.math.ec.ECCurve; import org.bouncycastle.math.ec.ECPoint; public class BCECGOST3410PrivateKey implements ECPrivateKey, PKCS12BagAttributeCarrier, ECPointEncoder { private String algorithm = "ECGOST3410"; private boolean withCompression; private transient BigInteger d; private transient ECParameterSpec ecSpec; private transient DERBitString publicKey; private transient PKCS12BagAttributeCarrierImpl attrCarrier = new PKCS12BagAttributeCarrierImpl(); protected BCECGOST3410PrivateKey() { } BCECGOST3410PrivateKey( ECPrivateKey key) { this.d = key.getD(); this.algorithm = key.getAlgorithm(); this.ecSpec = key.getParameters(); } public BCECGOST3410PrivateKey( ECPrivateKeySpec spec) { this.d = spec.getD(); this.ecSpec = spec.getParams(); } public BCECGOST3410PrivateKey( String algorithm, ECPrivateKeyParameters params, BCECGOST3410PublicKey pubKey, ECParameterSpec spec) { ECDomainParameters dp = params.getParameters(); this.algorithm = algorithm; this.d = params.getD(); if (spec == null) { this.ecSpec = new ECParameterSpec( dp.getCurve(), dp.getG(), dp.getN(), dp.getH(), dp.getSeed()); } else { this.ecSpec = spec; } publicKey = getPublicKeyDetails(pubKey); } public BCECGOST3410PrivateKey( String algorithm, ECPrivateKeyParameters params) { this.algorithm = algorithm; this.d = params.getD(); this.ecSpec = null; } public BCECGOST3410PrivateKey( String algorithm, BCECGOST3410PrivateKey key) { this.algorithm = algorithm; this.d = key.d; this.ecSpec = key.ecSpec; this.withCompression = key.withCompression; this.publicKey = key.publicKey; this.attrCarrier = key.attrCarrier; } BCECGOST3410PrivateKey( PrivateKeyInfo info) { populateFromPrivKeyInfo(info); } private void populateFromPrivKeyInfo(PrivateKeyInfo info) { X962Parameters params = X962Parameters.getInstance(info.getAlgorithmId().getParameters()); if (params.isNamedCurve()) { ASN1ObjectIdentifier oid = (ASN1ObjectIdentifier)params.getParameters(); ECDomainParameters ecP = ECGOST3410NamedCurves.getByOID(oid); ecSpec = new ECNamedCurveParameterSpec( ECUtil.getCurveName(oid), ecP.getCurve(), ecP.getG(), ecP.getN(), ecP.getH(), ecP.getSeed()); } else if (params.isImplicitlyCA()) { ecSpec = null; } else { X9ECParameters ecP = X9ECParameters.getInstance(params.getParameters()); ecSpec = new ECParameterSpec(ecP.getCurve(), ecP.getG(), ecP.getN(), ecP.getH(), ecP.getSeed()); } if (info.getPrivateKey() instanceof ASN1Integer) { ASN1Integer derD = ASN1Integer.getInstance(info.getPrivateKey()); this.d = derD.getValue(); } else { ECPrivateKeyStructure ec = new ECPrivateKeyStructure((ASN1Sequence)info.getPrivateKey()); this.d = ec.getKey(); this.publicKey = ec.getPublicKey(); } } public String getAlgorithm() { return algorithm; } /** * return the encoding format we produce in getEncoded(). * * @return the string "PKCS#8" */ public String getFormat() { return "PKCS#8"; } /** * Return a PKCS8 representation of the key. The sequence returned * represents a full PrivateKeyInfo object. * * @return a PKCS8 representation of the key. */ public byte[] getEncoded() { ByteArrayOutputStream bOut = new ByteArrayOutputStream(); DEROutputStream dOut = new DEROutputStream(bOut); X962Parameters params = null; if (ecSpec instanceof ECNamedCurveParameterSpec) { ASN1ObjectIdentifier curveOid = ECUtil.getNamedCurveOid(((ECNamedCurveParameterSpec)ecSpec).getName()); params = new X962Parameters(curveOid); } else if (ecSpec == null) { params = new X962Parameters(DERNull.INSTANCE); } else { ECParameterSpec p = (ECParameterSpec)ecSpec; ECCurve curve = p.getG().getCurve(); ECPoint generator; if (curve instanceof ECCurve.Fp) { generator = new ECPoint.Fp(curve, p.getG().getX(), p.getG().getY(), withCompression); } else if (curve instanceof ECCurve.F2m) { generator = new ECPoint.F2m(curve, p.getG().getX(), p.getG().getY(), withCompression); } else { throw new UnsupportedOperationException("Subclass of ECPoint " + curve.getClass().toString() + "not supported"); } X9ECParameters ecP = new X9ECParameters( p.getCurve(), generator, p.getN(), p.getH(), p.getSeed()); params = new X962Parameters(ecP); } PrivateKeyInfo info; ECPrivateKeyStructure keyStructure; if (publicKey != null) { keyStructure = new ECPrivateKeyStructure(this.getD(), publicKey, params); } else { keyStructure = new ECPrivateKeyStructure(this.getD(), params); } try { if (algorithm.equals("ECGOST3410")) { info = new PrivateKeyInfo(new AlgorithmIdentifier(CryptoProObjectIdentifiers.gostR3410_2001, params), keyStructure); } else { info = new PrivateKeyInfo(new AlgorithmIdentifier(X9ObjectIdentifiers.id_ecPublicKey, params), keyStructure); } return KeyUtil.getEncodedPrivateKeyInfo(info); } catch (IOException e) { return null; } } public ECParameterSpec getParams() { return (ECParameterSpec)ecSpec; } public ECParameterSpec getParameters() { return (ECParameterSpec)ecSpec; } public BigInteger getD() { return d; } public void setBagAttribute( ASN1ObjectIdentifier oid, ASN1Encodable attribute) { attrCarrier.setBagAttribute(oid, attribute); } public ASN1Encodable getBagAttribute( ASN1ObjectIdentifier oid) { return attrCarrier.getBagAttribute(oid); } public Enumeration getBagAttributeKeys() { return attrCarrier.getBagAttributeKeys(); } public void setPointFormat(String style) { withCompression = !("UNCOMPRESSED".equalsIgnoreCase(style)); } ECParameterSpec engineGetSpec() { if (ecSpec != null) { return ecSpec; } return BouncyCastleProvider.CONFIGURATION.getEcImplicitlyCa(); } public boolean equals(Object o) { if (!(o instanceof BCECGOST3410PrivateKey)) { return false; } BCECGOST3410PrivateKey other = (BCECGOST3410PrivateKey)o; return getD().equals(other.getD()) && (engineGetSpec().equals(other.engineGetSpec())); } public int hashCode() { return getD().hashCode() ^ engineGetSpec().hashCode(); } private DERBitString getPublicKeyDetails(BCECGOST3410PublicKey pub) { try { SubjectPublicKeyInfo info = SubjectPublicKeyInfo.getInstance(ASN1Primitive.fromByteArray(pub.getEncoded())); return info.getPublicKeyData(); } catch (IOException e) { // should never happen return null; } } private void readObject( ObjectInputStream in) throws IOException, ClassNotFoundException { in.defaultReadObject(); byte[] enc = (byte[])in.readObject(); populateFromPrivKeyInfo(PrivateKeyInfo.getInstance(ASN1Primitive.fromByteArray(enc))); this.attrCarrier = new PKCS12BagAttributeCarrierImpl(); } private void writeObject( ObjectOutputStream out) throws IOException { out.defaultWriteObject(); out.writeObject(this.getEncoded()); } } bouncycastle-1.49.orig/jdk1.4/org/bouncycastle/jcajce/provider/asymmetric/rsa/0000755000175000017500000000000012152033550026715 5ustar ebourgebourg././@LongLink0000000000000000000000000000015200000000000011563 Lustar rootrootbouncycastle-1.49.orig/jdk1.4/org/bouncycastle/jcajce/provider/asymmetric/rsa/AlgorithmParametersSpi.javabouncycastle-1.49.orig/jdk1.4/org/bouncycastle/jcajce/provider/asymmetric/rsa/AlgorithmParametersSpi0000644000175000017500000001474011676515402033307 0ustar ebourgebourgpackage org.bouncycastle.jcajce.provider.asymmetric.rsa; import java.io.ByteArrayOutputStream; import java.io.IOException; import java.security.spec.AlgorithmParameterSpec; import java.security.spec.InvalidParameterSpecException; import java.security.spec.PSSParameterSpec; import org.bouncycastle.asn1.ASN1Integer; import org.bouncycastle.asn1.DEROutputStream; import org.bouncycastle.asn1.pkcs.RSAESOAEPparams; import org.bouncycastle.asn1.pkcs.RSASSAPSSparams; public abstract class AlgorithmParametersSpi extends java.security.AlgorithmParametersSpi { protected boolean isASN1FormatString(String format) { return format == null || format.equals("ASN.1"); } protected AlgorithmParameterSpec engineGetParameterSpec( Class paramSpec) throws InvalidParameterSpecException { if (paramSpec == null) { throw new NullPointerException("argument to getParameterSpec must not be null"); } return localEngineGetParameterSpec(paramSpec); } protected abstract AlgorithmParameterSpec localEngineGetParameterSpec(Class paramSpec) throws InvalidParameterSpecException; public static class OAEP extends AlgorithmParametersSpi { AlgorithmParameterSpec currentSpec; /** * Return the PKCS#1 ASN.1 structure RSAES-OAEP-params. */ protected byte[] engineGetEncoded() { return null; } protected byte[] engineGetEncoded( String format) { if (isASN1FormatString(format) || format.equalsIgnoreCase("X.509")) { return engineGetEncoded(); } return null; } protected AlgorithmParameterSpec localEngineGetParameterSpec( Class paramSpec) throws InvalidParameterSpecException { throw new InvalidParameterSpecException("unknown parameter spec passed to OAEP parameters object."); } protected void engineInit( AlgorithmParameterSpec paramSpec) throws InvalidParameterSpecException { this.currentSpec = paramSpec; } protected void engineInit( byte[] params) throws IOException { try { RSAESOAEPparams oaepP = RSAESOAEPparams.getInstance(params); throw new IOException("Operation not supported"); } catch (ClassCastException e) { throw new IOException("Not a valid OAEP Parameter encoding."); } catch (ArrayIndexOutOfBoundsException e) { throw new IOException("Not a valid OAEP Parameter encoding."); } } protected void engineInit( byte[] params, String format) throws IOException { if (format.equalsIgnoreCase("X.509") || format.equalsIgnoreCase("ASN.1")) { engineInit(params); } else { throw new IOException("Unknown parameter format " + format); } } protected String engineToString() { return "OAEP Parameters"; } } public static class PSS extends AlgorithmParametersSpi { PSSParameterSpec currentSpec; /** * Return the PKCS#1 ASN.1 structure RSASSA-PSS-params. */ protected byte[] engineGetEncoded() throws IOException { ByteArrayOutputStream bOut = new ByteArrayOutputStream(); DEROutputStream dOut = new DEROutputStream(bOut); PSSParameterSpec pssSpec = (PSSParameterSpec)currentSpec; RSASSAPSSparams pssP = new RSASSAPSSparams(RSASSAPSSparams.DEFAULT_HASH_ALGORITHM, RSASSAPSSparams.DEFAULT_MASK_GEN_FUNCTION, new ASN1Integer(pssSpec.getSaltLength()), RSASSAPSSparams.DEFAULT_TRAILER_FIELD); dOut.writeObject(pssP); dOut.close(); return bOut.toByteArray(); } protected byte[] engineGetEncoded( String format) throws IOException { if (format.equalsIgnoreCase("X.509") || format.equalsIgnoreCase("ASN.1")) { return engineGetEncoded(); } return null; } protected AlgorithmParameterSpec localEngineGetParameterSpec( Class paramSpec) throws InvalidParameterSpecException { if (paramSpec == PSSParameterSpec.class && currentSpec != null) { return currentSpec; } throw new InvalidParameterSpecException("unknown parameter spec passed to PSS parameters object."); } protected void engineInit( AlgorithmParameterSpec paramSpec) throws InvalidParameterSpecException { if (!(paramSpec instanceof PSSParameterSpec)) { throw new InvalidParameterSpecException("PSSParameterSpec required to initialise an PSS algorithm parameters object"); } this.currentSpec = (PSSParameterSpec)paramSpec; } protected void engineInit( byte[] params) throws IOException { try { RSASSAPSSparams pssP = RSASSAPSSparams.getInstance(params); currentSpec = new PSSParameterSpec( pssP.getSaltLength().intValue()); } catch (ClassCastException e) { throw new IOException("Not a valid PSS Parameter encoding."); } catch (ArrayIndexOutOfBoundsException e) { throw new IOException("Not a valid PSS Parameter encoding."); } } protected void engineInit( byte[] params, String format) throws IOException { if (isASN1FormatString(format) || format.equalsIgnoreCase("X.509")) { engineInit(params); } else { throw new IOException("Unknown parameter format " + format); } } protected String engineToString() { return "PSS Parameters"; } } } bouncycastle-1.49.orig/jdk1.4/org/bouncycastle/jcajce/provider/asymmetric/rsa/PSSSignatureSpi.java0000644000175000017500000002450711677222630032605 0ustar ebourgebourgpackage org.bouncycastle.jcajce.provider.asymmetric.rsa; import java.io.ByteArrayOutputStream; import java.security.AlgorithmParameters; import java.security.InvalidKeyException; import java.security.InvalidParameterException; import java.security.PrivateKey; import java.security.PublicKey; import java.security.SecureRandom; import java.security.Signature; import java.security.SignatureException; import java.security.interfaces.RSAPrivateKey; import java.security.interfaces.RSAPublicKey; import java.security.spec.AlgorithmParameterSpec; import java.security.spec.PSSParameterSpec; import org.bouncycastle.crypto.AsymmetricBlockCipher; import org.bouncycastle.crypto.CryptoException; import org.bouncycastle.crypto.Digest; import org.bouncycastle.crypto.digests.SHA1Digest; import org.bouncycastle.crypto.digests.SHA224Digest; import org.bouncycastle.crypto.digests.SHA256Digest; import org.bouncycastle.crypto.digests.SHA384Digest; import org.bouncycastle.crypto.digests.SHA512Digest; import org.bouncycastle.crypto.engines.RSABlindedEngine; import org.bouncycastle.crypto.params.ParametersWithRandom; import org.bouncycastle.jce.provider.BouncyCastleProvider; public class PSSSignatureSpi extends Signature { private AlgorithmParameters engineParams; private PSSParameterSpec paramSpec; private AsymmetricBlockCipher signer; private Digest contentDigest; private Digest mgfDigest; private int saltLength; private byte trailer; private boolean isRaw; private org.bouncycastle.crypto.signers.PSSSigner pss; private byte getTrailer( int trailerField) { if (trailerField == 1) { return org.bouncycastle.crypto.signers.PSSSigner.TRAILER_IMPLICIT; } throw new IllegalArgumentException("unknown trailer field"); } private void setupContentDigest() { if (isRaw) { this.contentDigest = new NullPssDigest(mgfDigest); } else { this.contentDigest = mgfDigest; } } protected PSSSignatureSpi( String name, AsymmetricBlockCipher signer, Digest digest) { super(name); this.signer = signer; this.mgfDigest = digest; if (digest != null) { this.saltLength = digest.getDigestSize(); } else { this.saltLength = 20; } if (paramSpec != null) { this.saltLength = paramSpec.getSaltLength(); } this.isRaw = false; setupContentDigest(); } // care - this constructor is actually used by outside organisations protected PSSSignatureSpi( String name, AsymmetricBlockCipher signer, Digest digest, boolean isRaw) { super(name); this.signer = signer; this.mgfDigest = digest; if (digest != null) { this.saltLength = digest.getDigestSize(); } else { this.saltLength = 20; } if (paramSpec != null) { this.saltLength = paramSpec.getSaltLength(); } this.isRaw = isRaw; setupContentDigest(); } protected void engineInitVerify( PublicKey publicKey) throws InvalidKeyException { if (!(publicKey instanceof RSAPublicKey)) { throw new InvalidKeyException("Supplied key is not a RSAPublicKey instance"); } pss = new org.bouncycastle.crypto.signers.PSSSigner(signer, contentDigest, mgfDigest, saltLength); pss.init(false, RSAUtil.generatePublicKeyParameter((RSAPublicKey)publicKey)); } protected void engineInitSign( PrivateKey privateKey, SecureRandom random) throws InvalidKeyException { if (!(privateKey instanceof RSAPrivateKey)) { throw new InvalidKeyException("Supplied key is not a RSAPrivateKey instance"); } pss = new org.bouncycastle.crypto.signers.PSSSigner(signer, contentDigest, mgfDigest, saltLength); pss.init(true, new ParametersWithRandom(RSAUtil.generatePrivateKeyParameter((RSAPrivateKey)privateKey), random)); } protected void engineInitSign( PrivateKey privateKey) throws InvalidKeyException { if (!(privateKey instanceof RSAPrivateKey)) { throw new InvalidKeyException("Supplied key is not a RSAPrivateKey instance"); } pss = new org.bouncycastle.crypto.signers.PSSSigner(signer, contentDigest, mgfDigest, saltLength); pss.init(true, RSAUtil.generatePrivateKeyParameter((RSAPrivateKey)privateKey)); } protected void engineUpdate( byte b) throws SignatureException { pss.update(b); } protected void engineUpdate( byte[] b, int off, int len) throws SignatureException { pss.update(b, off, len); } protected byte[] engineSign() throws SignatureException { try { return pss.generateSignature(); } catch (CryptoException e) { throw new SignatureException(e.getMessage()); } } protected boolean engineVerify( byte[] sigBytes) throws SignatureException { return pss.verifySignature(sigBytes); } protected void engineSetParameter( AlgorithmParameterSpec params) throws InvalidParameterException { if (params instanceof PSSParameterSpec) { PSSParameterSpec newParamSpec = (PSSParameterSpec)params; this.engineParams = null; this.paramSpec = newParamSpec; this.saltLength = paramSpec.getSaltLength(); if (mgfDigest == null) { switch (saltLength) { case 20: this.mgfDigest = new SHA1Digest(); break; case 28: this.mgfDigest = new SHA224Digest(); break; case 32: this.mgfDigest = new SHA256Digest(); break; case 48: this.mgfDigest = new SHA384Digest(); break; case 64: this.mgfDigest = new SHA512Digest(); break; } setupContentDigest(); } } else { throw new InvalidParameterException("Only PSSParameterSpec supported"); } } protected AlgorithmParameters engineGetParameters() { if (engineParams == null) { try { engineParams = AlgorithmParameters.getInstance("PSS", BouncyCastleProvider.PROVIDER_NAME); engineParams.init(new PSSParameterSpec(saltLength)); } catch (Exception e) { throw new RuntimeException(e.toString()); } } return engineParams; } /** * @deprecated replaced with */ protected void engineSetParameter( String param, Object value) { throw new UnsupportedOperationException("engineSetParameter unsupported"); } protected Object engineGetParameter( String param) { throw new UnsupportedOperationException("engineGetParameter unsupported"); } static public class nonePSS extends PSSSignatureSpi { public nonePSS() { super("NONEwithRSAandMGF1", new RSABlindedEngine(), null, true); } } static public class PSSwithRSA extends PSSSignatureSpi { public PSSwithRSA() { super("SHA1withRSAandMGF1", new RSABlindedEngine(), null); } } static public class SHA1withRSA extends PSSSignatureSpi { public SHA1withRSA() { super("SHA1withRSAandMGF1", new RSABlindedEngine(), new SHA1Digest()); } } static public class SHA224withRSA extends PSSSignatureSpi { public SHA224withRSA() { super("SHA224withRSAandMGF1", new RSABlindedEngine(), new SHA224Digest()); } } static public class SHA256withRSA extends PSSSignatureSpi { public SHA256withRSA() { super("SHA256withRSAandMGF1", new RSABlindedEngine(), new SHA256Digest()); } } static public class SHA384withRSA extends PSSSignatureSpi { public SHA384withRSA() { super("SHA384withRSAandMGF1", new RSABlindedEngine(), new SHA384Digest()); } } static public class SHA512withRSA extends PSSSignatureSpi { public SHA512withRSA() { super("SHA512withRSAandMGF1", new RSABlindedEngine(), new SHA512Digest()); } } private class NullPssDigest implements Digest { private ByteArrayOutputStream bOut = new ByteArrayOutputStream(); private Digest baseDigest; private boolean oddTime = true; public NullPssDigest(Digest mgfDigest) { this.baseDigest = mgfDigest; } public String getAlgorithmName() { return "NULL"; } public int getDigestSize() { return baseDigest.getDigestSize(); } public void update(byte in) { bOut.write(in); } public void update(byte[] in, int inOff, int len) { bOut.write(in, inOff, len); } public int doFinal(byte[] out, int outOff) { byte[] res = bOut.toByteArray(); if (oddTime) { System.arraycopy(res, 0, out, outOff, res.length); } else { baseDigest.update(res, 0, res.length); baseDigest.doFinal(out, outOff); } reset(); oddTime = !oddTime; return res.length; } public void reset() { bOut.reset(); baseDigest.reset(); } public int getByteLength() { return 0; } } } bouncycastle-1.49.orig/jdk1.4/org/bouncycastle/jcajce/provider/asymmetric/rsa/CipherSpi.java0000644000175000017500000003356611723603754031477 0ustar ebourgebourgpackage org.bouncycastle.jcajce.provider.asymmetric.rsa; import java.io.ByteArrayOutputStream; import java.security.AlgorithmParameters; import java.security.InvalidAlgorithmParameterException; import java.security.InvalidKeyException; import java.security.InvalidParameterException; import java.security.Key; import java.security.NoSuchAlgorithmException; import java.security.SecureRandom; import java.security.interfaces.RSAPrivateKey; import java.security.interfaces.RSAPublicKey; import java.security.spec.AlgorithmParameterSpec; import javax.crypto.BadPaddingException; import javax.crypto.Cipher; import javax.crypto.IllegalBlockSizeException; import javax.crypto.NoSuchPaddingException; import org.bouncycastle.crypto.AsymmetricBlockCipher; import org.bouncycastle.crypto.CipherParameters; import org.bouncycastle.crypto.InvalidCipherTextException; import org.bouncycastle.crypto.digests.MD5Digest; import org.bouncycastle.crypto.digests.SHA224Digest; import org.bouncycastle.crypto.digests.SHA256Digest; import org.bouncycastle.crypto.digests.SHA384Digest; import org.bouncycastle.crypto.digests.SHA512Digest; import org.bouncycastle.crypto.encodings.ISO9796d1Encoding; import org.bouncycastle.crypto.encodings.OAEPEncoding; import org.bouncycastle.crypto.encodings.PKCS1Encoding; import org.bouncycastle.crypto.engines.RSABlindedEngine; import org.bouncycastle.crypto.params.ParametersWithRandom; import org.bouncycastle.jcajce.provider.asymmetric.util.BaseCipherSpi; import org.bouncycastle.jce.provider.BouncyCastleProvider; import org.bouncycastle.util.Strings; public class CipherSpi extends BaseCipherSpi { private AsymmetricBlockCipher cipher; private AlgorithmParameterSpec paramSpec; private AlgorithmParameters engineParams; private boolean publicKeyOnly = false; private boolean privateKeyOnly = false; private ByteArrayOutputStream bOut = new ByteArrayOutputStream(); public CipherSpi( AsymmetricBlockCipher engine) { cipher = engine; } public CipherSpi( boolean publicKeyOnly, boolean privateKeyOnly, AsymmetricBlockCipher engine) { this.publicKeyOnly = publicKeyOnly; this.privateKeyOnly = privateKeyOnly; cipher = engine; } protected int engineGetBlockSize() { try { return cipher.getInputBlockSize(); } catch (NullPointerException e) { throw new IllegalStateException("RSA Cipher not initialised"); } } protected int engineGetKeySize( Key key) { if (key instanceof RSAPrivateKey) { RSAPrivateKey k = (RSAPrivateKey)key; return k.getModulus().bitLength(); } else if (key instanceof RSAPublicKey) { RSAPublicKey k = (RSAPublicKey)key; return k.getModulus().bitLength(); } throw new IllegalArgumentException("not an RSA key!"); } protected int engineGetOutputSize( int inputLen) { try { return cipher.getOutputBlockSize(); } catch (NullPointerException e) { throw new IllegalStateException("RSA Cipher not initialised"); } } protected AlgorithmParameters engineGetParameters() { if (engineParams == null) { if (paramSpec != null) { try { engineParams = AlgorithmParameters.getInstance("OAEP", BouncyCastleProvider.PROVIDER_NAME); engineParams.init(paramSpec); } catch (Exception e) { throw new RuntimeException(e.toString()); } } } return engineParams; } protected void engineSetMode( String mode) throws NoSuchAlgorithmException { String md = Strings.toUpperCase(mode); if (md.equals("NONE") || md.equals("ECB")) { return; } if (md.equals("1")) { privateKeyOnly = true; publicKeyOnly = false; return; } else if (md.equals("2")) { privateKeyOnly = false; publicKeyOnly = true; return; } throw new NoSuchAlgorithmException("can't support mode " + mode); } protected void engineSetPadding( String padding) throws NoSuchPaddingException { String pad = Strings.toUpperCase(padding); if (pad.equals("NOPADDING")) { cipher = new RSABlindedEngine(); } else if (pad.equals("PKCS1PADDING")) { cipher = new PKCS1Encoding(new RSABlindedEngine()); } else if (pad.equals("ISO9796-1PADDING")) { cipher = new ISO9796d1Encoding(new RSABlindedEngine()); } else if (pad.equals("OAEPPADDING")) { cipher = new OAEPEncoding(new RSABlindedEngine()); } else if (pad.equals("OAEPWITHSHA1ANDMGF1PADDING")) { cipher = new OAEPEncoding(new RSABlindedEngine()); } else if (pad.equals("OAEPWITHSHA224ANDMGF1PADDING")) { cipher = new OAEPEncoding(new RSABlindedEngine(), new SHA224Digest()); } else if (pad.equals("OAEPWITHSHA256ANDMGF1PADDING")) { cipher = new OAEPEncoding(new RSABlindedEngine(), new SHA256Digest()); } else if (pad.equals("OAEPWITHSHA384ANDMGF1PADDING")) { cipher = new OAEPEncoding(new RSABlindedEngine(), new SHA384Digest()); } else if (pad.equals("OAEPWITHSHA512ANDMGF1PADDING")) { cipher = new OAEPEncoding(new RSABlindedEngine(), new SHA512Digest()); } else if (pad.equals("OAEPWITHMD5ANDMGF1PADDING")) { cipher = new OAEPEncoding(new RSABlindedEngine(), new MD5Digest()); } else { throw new NoSuchPaddingException(padding + " unavailable with RSA."); } } protected void engineInit( int opmode, Key key, AlgorithmParameterSpec params, SecureRandom random) throws InvalidKeyException, InvalidAlgorithmParameterException { CipherParameters param; if (params == null) { if (key instanceof RSAPublicKey) { if (privateKeyOnly && opmode == Cipher.ENCRYPT_MODE) { throw new InvalidKeyException( "mode 1 requires RSAPrivateKey"); } param = RSAUtil.generatePublicKeyParameter((RSAPublicKey)key); } else if (key instanceof RSAPrivateKey) { if (publicKeyOnly && opmode == Cipher.ENCRYPT_MODE) { throw new InvalidKeyException( "mode 2 requires RSAPublicKey"); } param = RSAUtil.generatePrivateKeyParameter((RSAPrivateKey)key); } else { throw new InvalidKeyException("unknown key type passed to RSA"); } } else { throw new IllegalArgumentException("unknown parameter type."); } if (!(cipher instanceof RSABlindedEngine)) { if (random != null) { param = new ParametersWithRandom(param, random); } else { param = new ParametersWithRandom(param, new SecureRandom()); } } switch (opmode) { case javax.crypto.Cipher.ENCRYPT_MODE: case javax.crypto.Cipher.WRAP_MODE: cipher.init(true, param); break; case javax.crypto.Cipher.DECRYPT_MODE: case javax.crypto.Cipher.UNWRAP_MODE: cipher.init(false, param); break; default: throw new InvalidParameterException("unknown opmode " + opmode + " passed to RSA"); } } protected void engineInit( int opmode, Key key, AlgorithmParameters params, SecureRandom random) throws InvalidKeyException, InvalidAlgorithmParameterException { AlgorithmParameterSpec paramSpec = null; if (params != null) { throw new InvalidAlgorithmParameterException("cannot recognise parameters."); } engineParams = params; engineInit(opmode, key, paramSpec, random); } protected void engineInit( int opmode, Key key, SecureRandom random) throws InvalidKeyException { try { engineInit(opmode, key, (AlgorithmParameterSpec)null, random); } catch (InvalidAlgorithmParameterException e) { // this shouldn't happen throw new InvalidKeyException("Eeeek! " + e.toString()); } } protected byte[] engineUpdate( byte[] input, int inputOffset, int inputLen) { bOut.write(input, inputOffset, inputLen); if (cipher instanceof RSABlindedEngine) { if (bOut.size() > cipher.getInputBlockSize() + 1) { throw new ArrayIndexOutOfBoundsException("too much data for RSA block"); } } else { if (bOut.size() > cipher.getInputBlockSize()) { throw new ArrayIndexOutOfBoundsException("too much data for RSA block"); } } return null; } protected int engineUpdate( byte[] input, int inputOffset, int inputLen, byte[] output, int outputOffset) { bOut.write(input, inputOffset, inputLen); if (cipher instanceof RSABlindedEngine) { if (bOut.size() > cipher.getInputBlockSize() + 1) { throw new ArrayIndexOutOfBoundsException("too much data for RSA block"); } } else { if (bOut.size() > cipher.getInputBlockSize()) { throw new ArrayIndexOutOfBoundsException("too much data for RSA block"); } } return 0; } protected byte[] engineDoFinal( byte[] input, int inputOffset, int inputLen) throws IllegalBlockSizeException, BadPaddingException { if (input != null) { bOut.write(input, inputOffset, inputLen); } if (cipher instanceof RSABlindedEngine) { if (bOut.size() > cipher.getInputBlockSize() + 1) { throw new ArrayIndexOutOfBoundsException("too much data for RSA block"); } } else { if (bOut.size() > cipher.getInputBlockSize()) { throw new ArrayIndexOutOfBoundsException("too much data for RSA block"); } } try { byte[] bytes = bOut.toByteArray(); bOut.reset(); return cipher.processBlock(bytes, 0, bytes.length); } catch (InvalidCipherTextException e) { throw new BadPaddingException(e.getMessage()); } } protected int engineDoFinal( byte[] input, int inputOffset, int inputLen, byte[] output, int outputOffset) throws IllegalBlockSizeException, BadPaddingException { if (input != null) { bOut.write(input, inputOffset, inputLen); } if (cipher instanceof RSABlindedEngine) { if (bOut.size() > cipher.getInputBlockSize() + 1) { throw new ArrayIndexOutOfBoundsException("too much data for RSA block"); } } else { if (bOut.size() > cipher.getInputBlockSize()) { throw new ArrayIndexOutOfBoundsException("too much data for RSA block"); } } byte[] out; try { byte[] bytes = bOut.toByteArray(); bOut.reset(); out = cipher.processBlock(bytes, 0, bytes.length); } catch (InvalidCipherTextException e) { throw new BadPaddingException(e.getMessage()); } for (int i = 0; i != out.length; i++) { output[outputOffset + i] = out[i]; } return out.length; } /** * classes that inherit from us. */ static public class NoPadding extends CipherSpi { public NoPadding() { super(new RSABlindedEngine()); } } static public class PKCS1v1_5Padding extends CipherSpi { public PKCS1v1_5Padding() { super(new PKCS1Encoding(new RSABlindedEngine())); } } static public class PKCS1v1_5Padding_PrivateOnly extends CipherSpi { public PKCS1v1_5Padding_PrivateOnly() { super(false, true, new PKCS1Encoding(new RSABlindedEngine())); } } static public class PKCS1v1_5Padding_PublicOnly extends CipherSpi { public PKCS1v1_5Padding_PublicOnly() { super(true, false, new PKCS1Encoding(new RSABlindedEngine())); } } static public class OAEPPadding extends CipherSpi { public OAEPPadding() { super(new OAEPEncoding(new RSABlindedEngine())); } } static public class ISO9796d1Padding extends CipherSpi { public ISO9796d1Padding() { super(new ISO9796d1Encoding(new RSABlindedEngine())); } } } bouncycastle-1.49.orig/jdk1.4/org/bouncycastle/jcajce/provider/asymmetric/ec/0000755000175000017500000000000012152033550026517 5ustar ebourgebourgbouncycastle-1.49.orig/jdk1.4/org/bouncycastle/jcajce/provider/asymmetric/ec/SignatureSpi.java0000644000175000017500000002220612147045327032012 0ustar ebourgebourgpackage org.bouncycastle.jcajce.provider.asymmetric.ec; import java.io.IOException; import java.math.BigInteger; import java.security.InvalidKeyException; import java.security.PrivateKey; import java.security.PublicKey; import java.security.SecureRandom; import org.bouncycastle.asn1.ASN1EncodableVector; import org.bouncycastle.asn1.ASN1Encoding; import org.bouncycastle.asn1.ASN1Primitive; import org.bouncycastle.asn1.ASN1Sequence; import org.bouncycastle.asn1.DERInteger; import org.bouncycastle.asn1.DERSequence; import org.bouncycastle.asn1.x509.SubjectPublicKeyInfo; import org.bouncycastle.crypto.CipherParameters; import org.bouncycastle.crypto.DSA; import org.bouncycastle.crypto.Digest; import org.bouncycastle.crypto.digests.NullDigest; import org.bouncycastle.crypto.digests.RIPEMD160Digest; import org.bouncycastle.crypto.digests.SHA1Digest; import org.bouncycastle.crypto.digests.SHA224Digest; import org.bouncycastle.crypto.digests.SHA256Digest; import org.bouncycastle.crypto.digests.SHA384Digest; import org.bouncycastle.crypto.digests.SHA512Digest; import org.bouncycastle.crypto.params.ParametersWithRandom; import org.bouncycastle.crypto.signers.ECDSASigner; import org.bouncycastle.crypto.signers.ECNRSigner; import org.bouncycastle.jcajce.provider.asymmetric.util.DSABase; import org.bouncycastle.jcajce.provider.asymmetric.util.DSAEncoder; import org.bouncycastle.jcajce.provider.asymmetric.util.ECUtil; import org.bouncycastle.jce.interfaces.ECKey; import org.bouncycastle.jce.interfaces.ECPublicKey; import org.bouncycastle.jce.provider.BouncyCastleProvider; public class SignatureSpi extends DSABase { SignatureSpi(Digest digest, DSA signer, DSAEncoder encoder) { super("ECDSA", digest, signer, encoder); } protected void engineInitVerify(PublicKey publicKey) throws InvalidKeyException { CipherParameters param; if (publicKey instanceof ECPublicKey) { param = ECUtil.generatePublicKeyParameter(publicKey); } else { try { byte[] bytes = publicKey.getEncoded(); publicKey = BouncyCastleProvider.getPublicKey(SubjectPublicKeyInfo.getInstance(bytes)); if (publicKey instanceof ECPublicKey) { param = ECUtil.generatePublicKeyParameter(publicKey); } else { throw new InvalidKeyException("can't recognise key type in ECDSA based signer"); } } catch (Exception e) { throw new InvalidKeyException("can't recognise key type in ECDSA based signer"); } } digest.reset(); signer.init(false, param); } protected void doEngineInitSign( PrivateKey privateKey, SecureRandom random) throws InvalidKeyException { CipherParameters param; if (privateKey instanceof ECKey) { param = ECUtil.generatePrivateKeyParameter(privateKey); } else { throw new InvalidKeyException("can't recognise key type in ECDSA based signer"); } digest.reset(); if (random != null) { signer.init(true, new ParametersWithRandom(param, random)); } else { signer.init(true, param); } } static public class ecDSA extends SignatureSpi { public ecDSA() { super(new SHA1Digest(), new ECDSASigner(), new StdDSAEncoder()); } } static public class ecDSAnone extends SignatureSpi { public ecDSAnone() { super(new NullDigest(), new ECDSASigner(), new StdDSAEncoder()); } } static public class ecDSA224 extends SignatureSpi { public ecDSA224() { super(new SHA224Digest(), new ECDSASigner(), new StdDSAEncoder()); } } static public class ecDSA256 extends SignatureSpi { public ecDSA256() { super(new SHA256Digest(), new ECDSASigner(), new StdDSAEncoder()); } } static public class ecDSA384 extends SignatureSpi { public ecDSA384() { super(new SHA384Digest(), new ECDSASigner(), new StdDSAEncoder()); } } static public class ecDSA512 extends SignatureSpi { public ecDSA512() { super(new SHA512Digest(), new ECDSASigner(), new StdDSAEncoder()); } } static public class ecDSARipeMD160 extends SignatureSpi { public ecDSARipeMD160() { super(new RIPEMD160Digest(), new ECDSASigner(), new StdDSAEncoder()); } } static public class ecNR extends SignatureSpi { public ecNR() { super(new SHA1Digest(), new ECNRSigner(), new StdDSAEncoder()); } } static public class ecNR224 extends SignatureSpi { public ecNR224() { super(new SHA224Digest(), new ECNRSigner(), new StdDSAEncoder()); } } static public class ecNR256 extends SignatureSpi { public ecNR256() { super(new SHA256Digest(), new ECNRSigner(), new StdDSAEncoder()); } } static public class ecNR384 extends SignatureSpi { public ecNR384() { super(new SHA384Digest(), new ECNRSigner(), new StdDSAEncoder()); } } static public class ecNR512 extends SignatureSpi { public ecNR512() { super(new SHA512Digest(), new ECNRSigner(), new StdDSAEncoder()); } } static public class ecCVCDSA extends SignatureSpi { public ecCVCDSA() { super(new SHA1Digest(), new ECDSASigner(), new CVCDSAEncoder()); } } static public class ecCVCDSA224 extends SignatureSpi { public ecCVCDSA224() { super(new SHA224Digest(), new ECDSASigner(), new CVCDSAEncoder()); } } static public class ecCVCDSA256 extends SignatureSpi { public ecCVCDSA256() { super(new SHA256Digest(), new ECDSASigner(), new CVCDSAEncoder()); } } static public class ecCVCDSA384 extends SignatureSpi { public ecCVCDSA384() { super(new SHA384Digest(), new ECDSASigner(), new CVCDSAEncoder()); } } static public class ecCVCDSA512 extends SignatureSpi { public ecCVCDSA512() { super(new SHA512Digest(), new ECDSASigner(), new CVCDSAEncoder()); } } private static class StdDSAEncoder implements DSAEncoder { public byte[] encode( BigInteger r, BigInteger s) throws IOException { ASN1EncodableVector v = new ASN1EncodableVector(); v.add(new DERInteger(r)); v.add(new DERInteger(s)); return new DERSequence(v).getEncoded(ASN1Encoding.DER); } public BigInteger[] decode( byte[] encoding) throws IOException { ASN1Sequence s = (ASN1Sequence)ASN1Primitive.fromByteArray(encoding); BigInteger[] sig = new BigInteger[2]; sig[0] = ((DERInteger)s.getObjectAt(0)).getValue(); sig[1] = ((DERInteger)s.getObjectAt(1)).getValue(); return sig; } } private static class CVCDSAEncoder implements DSAEncoder { public byte[] encode( BigInteger r, BigInteger s) throws IOException { byte[] first = makeUnsigned(r); byte[] second = makeUnsigned(s); byte[] res; if (first.length > second.length) { res = new byte[first.length * 2]; } else { res = new byte[second.length * 2]; } System.arraycopy(first, 0, res, res.length / 2 - first.length, first.length); System.arraycopy(second, 0, res, res.length - second.length, second.length); return res; } private byte[] makeUnsigned(BigInteger val) { byte[] res = val.toByteArray(); if (res[0] == 0) { byte[] tmp = new byte[res.length - 1]; System.arraycopy(res, 1, tmp, 0, tmp.length); return tmp; } return res; } public BigInteger[] decode( byte[] encoding) throws IOException { BigInteger[] sig = new BigInteger[2]; byte[] first = new byte[encoding.length / 2]; byte[] second = new byte[encoding.length / 2]; System.arraycopy(encoding, 0, first, 0, first.length); System.arraycopy(encoding, first.length, second, 0, second.length); sig[0] = new BigInteger(1, first); sig[1] = new BigInteger(1, second); return sig; } } } bouncycastle-1.49.orig/jdk1.4/org/bouncycastle/jcajce/provider/asymmetric/ec/KeyFactorySpi.java0000644000175000017500000001334311701454635032134 0ustar ebourgebourgpackage org.bouncycastle.jcajce.provider.asymmetric.ec; import java.io.IOException; import java.security.InvalidKeyException; import java.security.Key; import java.security.PrivateKey; import java.security.PublicKey; import java.security.spec.InvalidKeySpecException; import java.security.spec.KeySpec; import org.bouncycastle.asn1.ASN1ObjectIdentifier; import org.bouncycastle.asn1.pkcs.PrivateKeyInfo; import org.bouncycastle.asn1.x509.SubjectPublicKeyInfo; import org.bouncycastle.asn1.x9.X9ObjectIdentifiers; import org.bouncycastle.jcajce.provider.asymmetric.util.BaseKeyFactorySpi; import org.bouncycastle.jcajce.provider.config.ProviderConfiguration; import org.bouncycastle.jcajce.provider.util.AsymmetricKeyInfoConverter; import org.bouncycastle.jce.interfaces.ECPrivateKey; import org.bouncycastle.jce.interfaces.ECPublicKey; import org.bouncycastle.jce.provider.BouncyCastleProvider; import org.bouncycastle.jce.spec.ECParameterSpec; import org.bouncycastle.jce.spec.ECPrivateKeySpec; import org.bouncycastle.jce.spec.ECPublicKeySpec; public class KeyFactorySpi extends BaseKeyFactorySpi implements AsymmetricKeyInfoConverter { String algorithm; ProviderConfiguration configuration; KeyFactorySpi( String algorithm, ProviderConfiguration configuration) { this.algorithm = algorithm; this.configuration = configuration; } protected Key engineTranslateKey( Key key) throws InvalidKeyException { if (key instanceof ECPublicKey) { return new BCECPublicKey((ECPublicKey)key, configuration); } else if (key instanceof ECPrivateKey) { return new BCECPrivateKey((ECPrivateKey)key, configuration); } throw new InvalidKeyException("key type unknown"); } protected KeySpec engineGetKeySpec( Key key, Class spec) throws InvalidKeySpecException { if (spec.isAssignableFrom(org.bouncycastle.jce.spec.ECPublicKeySpec.class) && key instanceof ECPublicKey) { ECPublicKey k = (ECPublicKey)key; if (k.getParams() != null) { return new org.bouncycastle.jce.spec.ECPublicKeySpec(k.getQ(), k.getParameters()); } else { ECParameterSpec implicitSpec = BouncyCastleProvider.CONFIGURATION.getEcImplicitlyCa(); return new org.bouncycastle.jce.spec.ECPublicKeySpec(k.getQ(), implicitSpec); } } else if (spec.isAssignableFrom(org.bouncycastle.jce.spec.ECPrivateKeySpec.class) && key instanceof ECPrivateKey) { ECPrivateKey k = (ECPrivateKey)key; if (k.getParams() != null) { return new org.bouncycastle.jce.spec.ECPrivateKeySpec(k.getD(), k.getParameters()); } else { ECParameterSpec implicitSpec = configuration.getEcImplicitlyCa(); return new org.bouncycastle.jce.spec.ECPrivateKeySpec(k.getD(), implicitSpec); } } return super.engineGetKeySpec(key, spec); } protected PrivateKey engineGeneratePrivate( KeySpec keySpec) throws InvalidKeySpecException { if (keySpec instanceof ECPrivateKeySpec) { return new BCECPrivateKey(algorithm, (ECPrivateKeySpec)keySpec, configuration); } return super.engineGeneratePrivate(keySpec); } protected PublicKey engineGeneratePublic( KeySpec keySpec) throws InvalidKeySpecException { if (keySpec instanceof ECPublicKeySpec) { return new BCECPublicKey(algorithm, (ECPublicKeySpec)keySpec, configuration); } return super.engineGeneratePublic(keySpec); } public PrivateKey generatePrivate(PrivateKeyInfo keyInfo) throws IOException { ASN1ObjectIdentifier algOid = keyInfo.getPrivateKeyAlgorithm().getAlgorithm(); if (algOid.equals(X9ObjectIdentifiers.id_ecPublicKey)) { return new BCECPrivateKey(algorithm, keyInfo, configuration); } else { throw new IOException("algorithm identifier " + algOid + " in key not recognised"); } } public PublicKey generatePublic(SubjectPublicKeyInfo keyInfo) throws IOException { ASN1ObjectIdentifier algOid = keyInfo.getAlgorithm().getAlgorithm(); if (algOid.equals(X9ObjectIdentifiers.id_ecPublicKey)) { return new BCECPublicKey(algorithm, keyInfo, configuration); } else { throw new IOException("algorithm identifier " + algOid + " in key not recognised"); } } public static class EC extends KeyFactorySpi { public EC() { super("EC", BouncyCastleProvider.CONFIGURATION); } } public static class ECDSA extends KeyFactorySpi { public ECDSA() { super("ECDSA", BouncyCastleProvider.CONFIGURATION); } } public static class ECGOST3410 extends KeyFactorySpi { public ECGOST3410() { super("ECGOST3410", BouncyCastleProvider.CONFIGURATION); } } public static class ECDH extends KeyFactorySpi { public ECDH() { super("ECDH", BouncyCastleProvider.CONFIGURATION); } } public static class ECDHC extends KeyFactorySpi { public ECDHC() { super("ECDHC", BouncyCastleProvider.CONFIGURATION); } } public static class ECMQV extends KeyFactorySpi { public ECMQV() { super("ECMQV", BouncyCastleProvider.CONFIGURATION); } } } bouncycastle-1.49.orig/jdk1.4/org/bouncycastle/jcajce/provider/asymmetric/ec/BCECPrivateKey.java0000644000175000017500000002740412110037231032063 0ustar ebourgebourgpackage org.bouncycastle.jcajce.provider.asymmetric.ec; import java.io.ByteArrayOutputStream; import java.io.IOException; import java.io.ObjectInputStream; import java.io.ObjectOutputStream; import java.math.BigInteger; import java.util.Enumeration; import org.bouncycastle.asn1.ASN1Encodable; import org.bouncycastle.asn1.ASN1Integer; import org.bouncycastle.asn1.ASN1ObjectIdentifier; import org.bouncycastle.asn1.ASN1Primitive; import org.bouncycastle.asn1.ASN1Sequence; import org.bouncycastle.asn1.DERBitString; import org.bouncycastle.asn1.DERNull; import org.bouncycastle.asn1.DEROutputStream; import org.bouncycastle.asn1.cryptopro.CryptoProObjectIdentifiers; import org.bouncycastle.asn1.pkcs.PrivateKeyInfo; import org.bouncycastle.asn1.sec.ECPrivateKeyStructure; import org.bouncycastle.asn1.x509.AlgorithmIdentifier; import org.bouncycastle.asn1.x509.SubjectPublicKeyInfo; import org.bouncycastle.asn1.x9.X962Parameters; import org.bouncycastle.asn1.x9.X9ECParameters; import org.bouncycastle.asn1.x9.X9ObjectIdentifiers; import org.bouncycastle.crypto.params.ECDomainParameters; import org.bouncycastle.crypto.params.ECPrivateKeyParameters; import org.bouncycastle.jcajce.provider.asymmetric.util.ECUtil; import org.bouncycastle.jcajce.provider.asymmetric.util.KeyUtil; import org.bouncycastle.jcajce.provider.asymmetric.util.PKCS12BagAttributeCarrierImpl; import org.bouncycastle.jcajce.provider.config.ProviderConfiguration; import org.bouncycastle.jce.interfaces.ECPointEncoder; import org.bouncycastle.jce.interfaces.ECPrivateKey; import org.bouncycastle.jce.interfaces.PKCS12BagAttributeCarrier; import org.bouncycastle.jce.provider.BouncyCastleProvider; import org.bouncycastle.jce.spec.ECNamedCurveParameterSpec; import org.bouncycastle.jce.spec.ECParameterSpec; import org.bouncycastle.jce.spec.ECPrivateKeySpec; import org.bouncycastle.math.ec.ECCurve; import org.bouncycastle.math.ec.ECPoint; public class BCECPrivateKey implements ECPrivateKey, PKCS12BagAttributeCarrier, ECPointEncoder { private String algorithm = "EC"; private boolean withCompression; private transient BigInteger d; private transient ECParameterSpec ecSpec; private transient ProviderConfiguration configuration; private transient DERBitString publicKey; private transient PKCS12BagAttributeCarrierImpl attrCarrier = new PKCS12BagAttributeCarrierImpl(); protected BCECPrivateKey() { } BCECPrivateKey( ECPrivateKey key, ProviderConfiguration configuration) { this.d = key.getD(); this.algorithm = key.getAlgorithm(); this.ecSpec = key.getParameters(); this.configuration = configuration; } public BCECPrivateKey( String algorithm, ECPrivateKeySpec spec, ProviderConfiguration configuration) { this.algorithm = algorithm; this.d = spec.getD(); this.ecSpec = spec.getParams(); this.configuration = configuration; } public BCECPrivateKey( String algorithm, ECPrivateKeyParameters params, BCECPublicKey pubKey, ECParameterSpec spec, ProviderConfiguration configuration) { ECDomainParameters dp = params.getParameters(); this.algorithm = algorithm; this.d = params.getD(); this.configuration = configuration; if (spec == null) { this.ecSpec = new ECParameterSpec( dp.getCurve(), dp.getG(), dp.getN(), dp.getH(), dp.getSeed()); } else { this.ecSpec = spec; } publicKey = getPublicKeyDetails(pubKey); } public BCECPrivateKey( String algorithm, ECPrivateKeyParameters params, ProviderConfiguration configuration) { this.algorithm = algorithm; this.d = params.getD(); this.ecSpec = null; this.configuration = configuration; } public BCECPrivateKey( String algorithm, BCECPrivateKey key) { this.algorithm = algorithm; this.d = key.d; this.ecSpec = key.ecSpec; this.withCompression = key.withCompression; this.publicKey = key.publicKey; this.attrCarrier = key.attrCarrier; this.configuration = key.configuration; } BCECPrivateKey( PrivateKeyInfo info, ProviderConfiguration configuration) { this.configuration = configuration; populateFromPrivKeyInfo(info); } BCECPrivateKey( String algorithm, PrivateKeyInfo info, ProviderConfiguration configuration) { this.configuration = configuration; populateFromPrivKeyInfo(info); this.algorithm = algorithm; } private void populateFromPrivKeyInfo(PrivateKeyInfo info) { X962Parameters params = X962Parameters.getInstance(info.getAlgorithmId().getParameters()); if (params.isNamedCurve()) { ASN1ObjectIdentifier oid = (ASN1ObjectIdentifier)params.getParameters(); X9ECParameters ecP = ECUtil.getNamedCurveByOid(oid); ecSpec = new ECNamedCurveParameterSpec( ECUtil.getCurveName(oid), ecP.getCurve(), ecP.getG(), ecP.getN(), ecP.getH(), ecP.getSeed()); } else if (params.isImplicitlyCA()) { ecSpec = null; } else { X9ECParameters ecP = X9ECParameters.getInstance(params.getParameters()); ecSpec = new ECParameterSpec(ecP.getCurve(), ecP.getG(), ecP.getN(), ecP.getH(), ecP.getSeed()); } if (info.getPrivateKey() instanceof ASN1Integer) { ASN1Integer derD = ASN1Integer.getInstance(info.getPrivateKey()); this.d = derD.getValue(); } else { ECPrivateKeyStructure ec = new ECPrivateKeyStructure((ASN1Sequence)info.getPrivateKey()); this.d = ec.getKey(); this.publicKey = ec.getPublicKey(); } } public String getAlgorithm() { return algorithm; } /** * return the encoding format we produce in getEncoded(). * * @return the string "PKCS#8" */ public String getFormat() { return "PKCS#8"; } /** * Return a PKCS8 representation of the key. The sequence returned * represents a full PrivateKeyInfo object. * * @return a PKCS8 representation of the key. */ public byte[] getEncoded() { ByteArrayOutputStream bOut = new ByteArrayOutputStream(); DEROutputStream dOut = new DEROutputStream(bOut); X962Parameters params = null; if (ecSpec instanceof ECNamedCurveParameterSpec) { ASN1ObjectIdentifier curveOid = ECUtil.getNamedCurveOid(((ECNamedCurveParameterSpec)ecSpec).getName()); params = new X962Parameters(curveOid); } else if (ecSpec == null) { params = new X962Parameters(DERNull.INSTANCE); } else { ECParameterSpec p = (ECParameterSpec)ecSpec; ECCurve curve = p.getG().getCurve(); ECPoint generator; if (curve instanceof ECCurve.Fp) { generator = new ECPoint.Fp(curve, p.getG().getX(), p.getG().getY(), withCompression); } else if (curve instanceof ECCurve.F2m) { generator = new ECPoint.F2m(curve, p.getG().getX(), p.getG().getY(), withCompression); } else { throw new UnsupportedOperationException("Subclass of ECPoint " + curve.getClass().toString() + "not supported"); } X9ECParameters ecP = new X9ECParameters( p.getCurve(), generator, p.getN(), p.getH(), p.getSeed()); params = new X962Parameters(ecP); } PrivateKeyInfo info; ECPrivateKeyStructure keyStructure; if (publicKey != null) { keyStructure = new ECPrivateKeyStructure(this.getD(), publicKey, params); } else { keyStructure = new ECPrivateKeyStructure(this.getD(), params); } try { if (algorithm.equals("ECGOST3410")) { info = new PrivateKeyInfo(new AlgorithmIdentifier(CryptoProObjectIdentifiers.gostR3410_2001, params), keyStructure); } else { info = new PrivateKeyInfo(new AlgorithmIdentifier(X9ObjectIdentifiers.id_ecPublicKey, params), keyStructure); } return KeyUtil.getEncodedPrivateKeyInfo(info); } catch (IOException e) { return null; } } public ECParameterSpec getParams() { return (ECParameterSpec)ecSpec; } public ECParameterSpec getParameters() { return (ECParameterSpec)ecSpec; } public BigInteger getD() { return d; } public void setBagAttribute( ASN1ObjectIdentifier oid, ASN1Encodable attribute) { attrCarrier.setBagAttribute(oid, attribute); } public ASN1Encodable getBagAttribute( ASN1ObjectIdentifier oid) { return attrCarrier.getBagAttribute(oid); } public Enumeration getBagAttributeKeys() { return attrCarrier.getBagAttributeKeys(); } public void setPointFormat(String style) { withCompression = !("UNCOMPRESSED".equalsIgnoreCase(style)); } ECParameterSpec engineGetSpec() { if (ecSpec != null) { return ecSpec; } return BouncyCastleProvider.CONFIGURATION.getEcImplicitlyCa(); } public boolean equals(Object o) { if (!(o instanceof BCECPrivateKey)) { return false; } BCECPrivateKey other = (BCECPrivateKey)o; return getD().equals(other.getD()) && (engineGetSpec().equals(other.engineGetSpec())); } public int hashCode() { return getD().hashCode() ^ engineGetSpec().hashCode(); } private DERBitString getPublicKeyDetails(BCECPublicKey pub) { try { SubjectPublicKeyInfo info = SubjectPublicKeyInfo.getInstance(ASN1Primitive.fromByteArray(pub.getEncoded())); return info.getPublicKeyData(); } catch (IOException e) { // should never happen return null; } } private void readObject( ObjectInputStream in) throws IOException, ClassNotFoundException { in.defaultReadObject(); byte[] enc = (byte[])in.readObject(); populateFromPrivKeyInfo(PrivateKeyInfo.getInstance(ASN1Primitive.fromByteArray(enc))); this.configuration = BouncyCastleProvider.CONFIGURATION; this.attrCarrier = new PKCS12BagAttributeCarrierImpl(); } private void writeObject( ObjectOutputStream out) throws IOException { out.defaultWriteObject(); out.writeObject(this.getEncoded()); } } bouncycastle-1.49.orig/jdk1.4/org/bouncycastle/jcajce/provider/asymmetric/ec/KeyAgreementSpi.java0000644000175000017500000002461412110037231032417 0ustar ebourgebourgpackage org.bouncycastle.jcajce.provider.asymmetric.ec; import java.math.BigInteger; import java.security.InvalidAlgorithmParameterException; import java.security.InvalidKeyException; import java.security.Key; import java.security.NoSuchAlgorithmException; import java.security.PrivateKey; import java.security.PublicKey; import java.security.SecureRandom; import java.security.spec.AlgorithmParameterSpec; import java.util.Hashtable; import javax.crypto.SecretKey; import javax.crypto.ShortBufferException; import javax.crypto.spec.SecretKeySpec; import org.bouncycastle.asn1.DERObjectIdentifier; import org.bouncycastle.asn1.nist.NISTObjectIdentifiers; import org.bouncycastle.asn1.pkcs.PKCSObjectIdentifiers; import org.bouncycastle.asn1.x9.X9IntegerConverter; import org.bouncycastle.crypto.BasicAgreement; import org.bouncycastle.crypto.CipherParameters; import org.bouncycastle.crypto.DerivationFunction; import org.bouncycastle.crypto.agreement.ECDHBasicAgreement; import org.bouncycastle.crypto.agreement.ECDHCBasicAgreement; import org.bouncycastle.crypto.agreement.ECMQVBasicAgreement; import org.bouncycastle.crypto.agreement.kdf.DHKDFParameters; import org.bouncycastle.crypto.agreement.kdf.ECDHKEKGenerator; import org.bouncycastle.crypto.digests.SHA1Digest; import org.bouncycastle.crypto.params.ECDomainParameters; import org.bouncycastle.crypto.params.ECPrivateKeyParameters; import org.bouncycastle.crypto.params.ECPublicKeyParameters; import org.bouncycastle.crypto.params.MQVPrivateParameters; import org.bouncycastle.crypto.params.MQVPublicParameters; import org.bouncycastle.jcajce.provider.asymmetric.util.ECUtil; import org.bouncycastle.jce.interfaces.ECPrivateKey; import org.bouncycastle.jce.interfaces.ECPublicKey; import org.bouncycastle.jce.interfaces.MQVPrivateKey; import org.bouncycastle.jce.interfaces.MQVPublicKey; import org.bouncycastle.util.Integers; /** * Diffie-Hellman key agreement using elliptic curve keys, ala IEEE P1363 * both the simple one, and the simple one with cofactors are supported. * * Also, MQV key agreement per SEC-1 */ public class KeyAgreementSpi extends javax.crypto.KeyAgreementSpi { private static final X9IntegerConverter converter = new X9IntegerConverter(); private static final Hashtable algorithms = new Hashtable(); static { Integer i128 = Integers.valueOf(128); Integer i192 = Integers.valueOf(192); Integer i256 = Integers.valueOf(256); algorithms.put(NISTObjectIdentifiers.id_aes128_CBC.getId(), i128); algorithms.put(NISTObjectIdentifiers.id_aes192_CBC.getId(), i192); algorithms.put(NISTObjectIdentifiers.id_aes256_CBC.getId(), i256); algorithms.put(NISTObjectIdentifiers.id_aes128_wrap.getId(), i128); algorithms.put(NISTObjectIdentifiers.id_aes192_wrap.getId(), i192); algorithms.put(NISTObjectIdentifiers.id_aes256_wrap.getId(), i256); algorithms.put(PKCSObjectIdentifiers.id_alg_CMS3DESwrap.getId(), i192); } private String kaAlgorithm; private BigInteger result; private ECDomainParameters parameters; private BasicAgreement agreement; private DerivationFunction kdf; private byte[] bigIntToBytes( BigInteger r) { return converter.integerToBytes(r, converter.getByteLength(parameters.getG().getX())); } protected KeyAgreementSpi( String kaAlgorithm, BasicAgreement agreement, DerivationFunction kdf) { this.kaAlgorithm = kaAlgorithm; this.agreement = agreement; this.kdf = kdf; } protected Key engineDoPhase( Key key, boolean lastPhase) throws InvalidKeyException, IllegalStateException { if (parameters == null) { throw new IllegalStateException(kaAlgorithm + " not initialised."); } if (!lastPhase) { throw new IllegalStateException(kaAlgorithm + " can only be between two parties."); } CipherParameters pubKey; if (agreement instanceof ECMQVBasicAgreement) { if (!(key instanceof MQVPublicKey)) { throw new InvalidKeyException(kaAlgorithm + " key agreement requires " + getSimpleName(MQVPublicKey.class) + " for doPhase"); } MQVPublicKey mqvPubKey = (MQVPublicKey)key; ECPublicKeyParameters staticKey = (ECPublicKeyParameters) ECUtil.generatePublicKeyParameter(mqvPubKey.getStaticKey()); ECPublicKeyParameters ephemKey = (ECPublicKeyParameters) ECUtil.generatePublicKeyParameter(mqvPubKey.getEphemeralKey()); pubKey = new MQVPublicParameters(staticKey, ephemKey); // TODO Validate that all the keys are using the same parameters? } else { if (!(key instanceof ECPublicKey)) { throw new InvalidKeyException(kaAlgorithm + " key agreement requires " + getSimpleName(ECPublicKey.class) + " for doPhase"); } pubKey = ECUtil.generatePublicKeyParameter((PublicKey)key); // TODO Validate that all the keys are using the same parameters? } result = agreement.calculateAgreement(pubKey); return null; } protected byte[] engineGenerateSecret() throws IllegalStateException { if (kdf != null) { throw new UnsupportedOperationException( "KDF can only be used when algorithm is known"); } return bigIntToBytes(result); } protected int engineGenerateSecret( byte[] sharedSecret, int offset) throws IllegalStateException, ShortBufferException { byte[] secret = engineGenerateSecret(); if (sharedSecret.length - offset < secret.length) { throw new ShortBufferException(kaAlgorithm + " key agreement: need " + secret.length + " bytes"); } System.arraycopy(secret, 0, sharedSecret, offset, secret.length); return secret.length; } protected SecretKey engineGenerateSecret( String algorithm) throws NoSuchAlgorithmException { byte[] secret = bigIntToBytes(result); if (kdf != null) { if (!algorithms.containsKey(algorithm)) { throw new NoSuchAlgorithmException("unknown algorithm encountered: " + algorithm); } int keySize = ((Integer)algorithms.get(algorithm)).intValue(); DHKDFParameters params = new DHKDFParameters(new DERObjectIdentifier(algorithm), keySize, secret); byte[] keyBytes = new byte[keySize / 8]; kdf.init(params); kdf.generateBytes(keyBytes, 0, keyBytes.length); secret = keyBytes; } else { // TODO Should we be ensuring the key is the right length? } return new SecretKeySpec(secret, algorithm); } protected void engineInit( Key key, AlgorithmParameterSpec params, SecureRandom random) throws InvalidKeyException, InvalidAlgorithmParameterException { initFromKey(key); } protected void engineInit( Key key, SecureRandom random) throws InvalidKeyException { initFromKey(key); } private void initFromKey(Key key) throws InvalidKeyException { if (agreement instanceof ECMQVBasicAgreement) { if (!(key instanceof MQVPrivateKey)) { throw new InvalidKeyException(kaAlgorithm + " key agreement requires " + getSimpleName(MQVPrivateKey.class) + " for initialisation"); } MQVPrivateKey mqvPrivKey = (MQVPrivateKey)key; ECPrivateKeyParameters staticPrivKey = (ECPrivateKeyParameters) ECUtil.generatePrivateKeyParameter(mqvPrivKey.getStaticPrivateKey()); ECPrivateKeyParameters ephemPrivKey = (ECPrivateKeyParameters) ECUtil.generatePrivateKeyParameter(mqvPrivKey.getEphemeralPrivateKey()); ECPublicKeyParameters ephemPubKey = null; if (mqvPrivKey.getEphemeralPublicKey() != null) { ephemPubKey = (ECPublicKeyParameters) ECUtil.generatePublicKeyParameter(mqvPrivKey.getEphemeralPublicKey()); } MQVPrivateParameters localParams = new MQVPrivateParameters(staticPrivKey, ephemPrivKey, ephemPubKey); this.parameters = staticPrivKey.getParameters(); // TODO Validate that all the keys are using the same parameters? agreement.init(localParams); } else { if (!(key instanceof ECPrivateKey)) { throw new InvalidKeyException(kaAlgorithm + " key agreement requires " + getSimpleName(ECPrivateKey.class) + " for initialisation"); } ECPrivateKeyParameters privKey = (ECPrivateKeyParameters)ECUtil.generatePrivateKeyParameter((PrivateKey)key); this.parameters = privKey.getParameters(); agreement.init(privKey); } } private static String getSimpleName(Class clazz) { String fullName = clazz.getName(); return fullName.substring(fullName.lastIndexOf('.') + 1); } public static class DH extends KeyAgreementSpi { public DH() { super("ECDH", new ECDHBasicAgreement(), null); } } public static class DHC extends KeyAgreementSpi { public DHC() { super("ECDHC", new ECDHCBasicAgreement(), null); } } public static class MQV extends KeyAgreementSpi { public MQV() { super("ECMQV", new ECMQVBasicAgreement(), null); } } public static class DHwithSHA1KDF extends KeyAgreementSpi { public DHwithSHA1KDF() { super("ECDHwithSHA1KDF", new ECDHBasicAgreement(), new ECDHKEKGenerator(new SHA1Digest())); } } public static class MQVwithSHA1KDF extends KeyAgreementSpi { public MQVwithSHA1KDF() { super("ECMQVwithSHA1KDF", new ECMQVBasicAgreement(), new ECDHKEKGenerator(new SHA1Digest())); } } } bouncycastle-1.49.orig/jdk1.4/org/bouncycastle/jcajce/provider/asymmetric/ec/BCECPublicKey.java0000644000175000017500000002656212110037231031673 0ustar ebourgebourgpackage org.bouncycastle.jcajce.provider.asymmetric.ec; import java.io.IOException; import java.io.ObjectInputStream; import java.io.ObjectOutputStream; import org.bouncycastle.asn1.ASN1ObjectIdentifier; import org.bouncycastle.asn1.ASN1OctetString; import org.bouncycastle.asn1.ASN1Primitive; import org.bouncycastle.asn1.DERBitString; import org.bouncycastle.asn1.DERNull; import org.bouncycastle.asn1.DERObjectIdentifier; import org.bouncycastle.asn1.DEROctetString; import org.bouncycastle.asn1.x509.AlgorithmIdentifier; import org.bouncycastle.asn1.x509.SubjectPublicKeyInfo; import org.bouncycastle.asn1.x9.X962Parameters; import org.bouncycastle.asn1.x9.X9ECParameters; import org.bouncycastle.asn1.x9.X9ECPoint; import org.bouncycastle.asn1.x9.X9IntegerConverter; import org.bouncycastle.asn1.x9.X9ObjectIdentifiers; import org.bouncycastle.crypto.params.ECDomainParameters; import org.bouncycastle.crypto.params.ECPublicKeyParameters; import org.bouncycastle.jcajce.provider.asymmetric.util.ECUtil; import org.bouncycastle.jcajce.provider.asymmetric.util.KeyUtil; import org.bouncycastle.jcajce.provider.config.ProviderConfiguration; import org.bouncycastle.jce.interfaces.ECPointEncoder; import org.bouncycastle.jce.interfaces.ECPublicKey; import org.bouncycastle.jce.provider.BouncyCastleProvider; import org.bouncycastle.jce.spec.ECNamedCurveParameterSpec; import org.bouncycastle.jce.spec.ECParameterSpec; import org.bouncycastle.jce.spec.ECPublicKeySpec; import org.bouncycastle.math.ec.ECCurve; import org.bouncycastle.math.ec.ECPoint; public class BCECPublicKey implements ECPublicKey, ECPointEncoder { private String algorithm = "EC"; private boolean withCompression; private transient org.bouncycastle.math.ec.ECPoint q; private transient ECParameterSpec ecSpec; private transient ProviderConfiguration configuration; public BCECPublicKey( String algorithm, BCECPublicKey key ) { this.algorithm = algorithm; this.q = key.q; this.ecSpec = key.ecSpec; this.withCompression = key.withCompression; this.configuration = key.configuration; } public BCECPublicKey( String algorithm, ECPublicKeySpec spec, ProviderConfiguration configuration) { this.algorithm = algorithm; this.q = spec.getQ(); this.configuration = configuration; if (spec.getParams() != null) { this.ecSpec = spec.getParams(); } else { if (q.getCurve() == null) { org.bouncycastle.jce.spec.ECParameterSpec s = BouncyCastleProvider.CONFIGURATION.getEcImplicitlyCa(); q = s.getCurve().createPoint(q.getX().toBigInteger(), q.getY().toBigInteger(), false); } this.ecSpec = null; } } public BCECPublicKey( String algorithm, ECPublicKeyParameters params, ECParameterSpec spec, ProviderConfiguration configuration) { ECDomainParameters dp = params.getParameters(); this.algorithm = algorithm; this.q = params.getQ(); this.configuration = configuration; if (spec == null) { this.ecSpec = new ECParameterSpec( dp.getCurve(), dp.getG(), dp.getN(), dp.getH(), dp.getSeed()); } else { this.ecSpec = spec; } } public BCECPublicKey( String algorithm, ECPublicKeyParameters params, ProviderConfiguration configuration) { this.algorithm = algorithm; this.q = params.getQ(); this.ecSpec = null; this.configuration = configuration; } BCECPublicKey( ECPublicKey key, ProviderConfiguration configuration) { this.q = key.getQ(); this.algorithm = key.getAlgorithm(); this.ecSpec = key.getParameters(); this.configuration = configuration; } BCECPublicKey( String algorithm, ECPoint q, ECParameterSpec ecSpec, ProviderConfiguration configuration) { this.algorithm = algorithm; this.q = q; this.ecSpec = ecSpec; this.configuration = configuration; } BCECPublicKey( SubjectPublicKeyInfo info, ProviderConfiguration configuration) { this.configuration = configuration; populateFromPubKeyInfo(info); } BCECPublicKey( String algorithm, SubjectPublicKeyInfo info, ProviderConfiguration configuration) { this.configuration = configuration; populateFromPubKeyInfo(info); this.algorithm = algorithm; } private void populateFromPubKeyInfo(SubjectPublicKeyInfo info) { X962Parameters params = X962Parameters.getInstance(info.getAlgorithmId().getParameters()); ECCurve curve; if (params.isNamedCurve()) { ASN1ObjectIdentifier oid = ASN1ObjectIdentifier.getInstance(params.getParameters()); X9ECParameters ecP = ECUtil.getNamedCurveByOid(oid); ecSpec = new ECNamedCurveParameterSpec( ECUtil.getCurveName(oid), ecP.getCurve(), ecP.getG(), ecP.getN(), ecP.getH(), ecP.getSeed()); curve = ((ECParameterSpec)ecSpec).getCurve(); } else if (params.isImplicitlyCA()) { ecSpec = null; curve = BouncyCastleProvider.CONFIGURATION.getEcImplicitlyCa().getCurve(); } else { X9ECParameters ecP = X9ECParameters.getInstance(params.getParameters()); ecSpec = new ECParameterSpec( ecP.getCurve(), ecP.getG(), ecP.getN(), ecP.getH(), ecP.getSeed()); curve = ((ECParameterSpec)ecSpec).getCurve(); } DERBitString bits = info.getPublicKeyData(); byte[] data = bits.getBytes(); ASN1OctetString key = new DEROctetString(data); // // extra octet string - one of our old certs... // if (data[0] == 0x04 && data[1] == data.length - 2 && (data[2] == 0x02 || data[2] == 0x03)) { int qLength = new X9IntegerConverter().getByteLength(curve); if (qLength >= data.length - 3) { try { key = (ASN1OctetString)ASN1Primitive.fromByteArray(data); } catch (IOException ex) { throw new IllegalArgumentException("error recovering public key"); } } } X9ECPoint derQ = new X9ECPoint(curve, key); this.q = derQ.getPoint(); } public String getAlgorithm() { return algorithm; } public String getFormat() { return "X.509"; } public byte[] getEncoded() { SubjectPublicKeyInfo info; X962Parameters params = null; if (ecSpec instanceof ECNamedCurveParameterSpec) { DERObjectIdentifier curveOid = ECUtil.getNamedCurveOid(((ECNamedCurveParameterSpec)ecSpec).getName()); if (curveOid == null) { curveOid = new DERObjectIdentifier(((ECNamedCurveParameterSpec)ecSpec).getName()); } params = new X962Parameters(curveOid); } else if (ecSpec == null) { params = new X962Parameters(DERNull.INSTANCE); } else { ECParameterSpec p = (ECParameterSpec)ecSpec; ECCurve curve = p.getG().getCurve(); ECPoint generator = curve.createPoint(p.getG().getX().toBigInteger(), p.getG().getY().toBigInteger(), withCompression); X9ECParameters ecP = new X9ECParameters( p.getCurve(), generator, p.getN(), p.getH(), p.getSeed()); params = new X962Parameters(ecP); } ECCurve curve = this.engineGetQ().getCurve(); ECPoint point = curve.createPoint(this.getQ().getX().toBigInteger(), this.getQ().getY().toBigInteger(), withCompression); ASN1OctetString p = ASN1OctetString.getInstance(new X9ECPoint(point)); info = new SubjectPublicKeyInfo(new AlgorithmIdentifier(X9ObjectIdentifiers.id_ecPublicKey, params), p.getOctets()); return KeyUtil.getEncodedSubjectPublicKeyInfo(info); } public ECParameterSpec getParams() { return (ECParameterSpec)ecSpec; } public ECParameterSpec getParameters() { return (ECParameterSpec)ecSpec; } public org.bouncycastle.math.ec.ECPoint getQ() { if (ecSpec == null) { if (q instanceof org.bouncycastle.math.ec.ECPoint.Fp) { return new org.bouncycastle.math.ec.ECPoint.Fp(null, q.getX(), q.getY()); } else { return new org.bouncycastle.math.ec.ECPoint.F2m(null, q.getX(), q.getY()); } } return q; } public org.bouncycastle.math.ec.ECPoint engineGetQ() { return q; } public String toString() { StringBuffer buf = new StringBuffer(); String nl = System.getProperty("line.separator"); buf.append("EC Public Key").append(nl); buf.append(" X: ").append(this.getQ().getX().toBigInteger().toString(16)).append(nl); buf.append(" Y: ").append(this.getQ().getY().toBigInteger().toString(16)).append(nl); return buf.toString(); } public void setPointFormat(String style) { withCompression = !("UNCOMPRESSED".equalsIgnoreCase(style)); } ECParameterSpec engineGetSpec() { if (ecSpec != null) { return (ECParameterSpec)ecSpec; } return BouncyCastleProvider.CONFIGURATION.getEcImplicitlyCa(); } public boolean equals(Object o) { if (!(o instanceof BCECPublicKey)) { return false; } BCECPublicKey other = (BCECPublicKey)o; return getQ().equals(other.getQ()) && (engineGetSpec().equals(other.engineGetSpec())); } public int hashCode() { return getQ().hashCode() ^ engineGetSpec().hashCode(); } private void readObject( ObjectInputStream in) throws IOException, ClassNotFoundException { in.defaultReadObject(); byte[] enc = (byte[])in.readObject(); populateFromPubKeyInfo(SubjectPublicKeyInfo.getInstance(ASN1Primitive.fromByteArray(enc))); this.configuration = BouncyCastleProvider.CONFIGURATION; } private void writeObject( ObjectOutputStream out) throws IOException { out.defaultWriteObject(); out.writeObject(this.getEncoded()); } } ././@LongLink0000000000000000000000000000014600000000000011566 Lustar rootrootbouncycastle-1.49.orig/jdk1.4/org/bouncycastle/jcajce/provider/asymmetric/ec/KeyPairGeneratorSpi.javabouncycastle-1.49.orig/jdk1.4/org/bouncycastle/jcajce/provider/asymmetric/ec/KeyPairGeneratorSpi.jav0000644000175000017500000002242612103623062033115 0ustar ebourgebourgpackage org.bouncycastle.jcajce.provider.asymmetric.ec; import java.security.InvalidAlgorithmParameterException; import java.security.InvalidParameterException; import java.security.KeyPair; import java.security.SecureRandom; import java.security.spec.AlgorithmParameterSpec; import java.util.Hashtable; import org.bouncycastle.asn1.ASN1ObjectIdentifier; import org.bouncycastle.asn1.nist.NISTNamedCurves; import org.bouncycastle.asn1.sec.SECNamedCurves; import org.bouncycastle.asn1.teletrust.TeleTrusTNamedCurves; import org.bouncycastle.asn1.x9.X962NamedCurves; import org.bouncycastle.asn1.x9.X9ECParameters; import org.bouncycastle.crypto.AsymmetricCipherKeyPair; import org.bouncycastle.crypto.generators.ECKeyPairGenerator; import org.bouncycastle.crypto.params.ECDomainParameters; import org.bouncycastle.crypto.params.ECKeyGenerationParameters; import org.bouncycastle.crypto.params.ECPrivateKeyParameters; import org.bouncycastle.crypto.params.ECPublicKeyParameters; import org.bouncycastle.jcajce.provider.config.ProviderConfiguration; import org.bouncycastle.jce.ECNamedCurveTable; import org.bouncycastle.jce.provider.BouncyCastleProvider; import org.bouncycastle.jce.spec.ECNamedCurveGenParameterSpec; import org.bouncycastle.jce.spec.ECNamedCurveParameterSpec; import org.bouncycastle.jce.spec.ECParameterSpec; import org.bouncycastle.util.Integers; public abstract class KeyPairGeneratorSpi extends java.security.KeyPairGenerator { public KeyPairGeneratorSpi(String algorithmName) { super(algorithmName); } public static class EC extends KeyPairGeneratorSpi { ECKeyGenerationParameters param; ECKeyPairGenerator engine = new ECKeyPairGenerator(); ECParameterSpec ecParams = null; int strength = 239; int certainty = 50; SecureRandom random = new SecureRandom(); boolean initialised = false; String algorithm; ProviderConfiguration configuration; static private Hashtable ecParameters; static { ecParameters = new Hashtable(); ecParameters.put(Integers.valueOf(192), ECNamedCurveTable.getParameterSpec("prime192v1")); ecParameters.put(Integers.valueOf(239), ECNamedCurveTable.getParameterSpec("prime239v1")); ecParameters.put(Integers.valueOf(256), ECNamedCurveTable.getParameterSpec("prime256v1")); } public EC() { super("EC"); this.algorithm = "EC"; this.configuration = BouncyCastleProvider.CONFIGURATION; } public EC( String algorithm, ProviderConfiguration configuration) { super(algorithm); this.algorithm = algorithm; this.configuration = configuration; } public void initialize( int strength, SecureRandom random) { this.strength = strength; this.random = random; this.ecParams = (ECParameterSpec)ecParameters.get(Integers.valueOf(strength)); if (ecParams != null) { param = new ECKeyGenerationParameters(new ECDomainParameters(ecParams.getCurve(), ecParams.getG(), ecParams.getN()), random); engine.init(param); initialised = true; } else { throw new InvalidParameterException("unknown key size."); } } public void initialize( AlgorithmParameterSpec params, SecureRandom random) throws InvalidAlgorithmParameterException { if (params instanceof ECParameterSpec) { ECParameterSpec p = (ECParameterSpec)params; this.ecParams = (ECParameterSpec)params; param = new ECKeyGenerationParameters(new ECDomainParameters(p.getCurve(), p.getG(), p.getN()), random); engine.init(param); initialised = true; } else if (params instanceof ECNamedCurveGenParameterSpec) { String curveName; curveName = ((ECNamedCurveGenParameterSpec)params).getName(); X9ECParameters ecP = X962NamedCurves.getByName(curveName); if (ecP == null) { ecP = SECNamedCurves.getByName(curveName); if (ecP == null) { ecP = NISTNamedCurves.getByName(curveName); } if (ecP == null) { ecP = TeleTrusTNamedCurves.getByName(curveName); } if (ecP == null) { // See if it's actually an OID string (SunJSSE ServerHandshaker setupEphemeralECDHKeys bug) try { ASN1ObjectIdentifier oid = new ASN1ObjectIdentifier(curveName); ecP = X962NamedCurves.getByOID(oid); if (ecP == null) { ecP = SECNamedCurves.getByOID(oid); } if (ecP == null) { ecP = NISTNamedCurves.getByOID(oid); } if (ecP == null) { ecP = TeleTrusTNamedCurves.getByOID(oid); } if (ecP == null) { throw new InvalidAlgorithmParameterException("unknown curve OID: " + curveName); } } catch (IllegalArgumentException ex) { throw new InvalidAlgorithmParameterException("unknown curve name: " + curveName); } } } this.ecParams = new ECNamedCurveParameterSpec( curveName, ecP.getCurve(), ecP.getG(), ecP.getN(), ecP.getH(), null); // ecP.getSeed()); Work-around JDK bug -- it won't look up named curves properly if seed is present param = new ECKeyGenerationParameters(new ECDomainParameters(ecParams.getCurve(), ecParams.getG(), ecParams.getN()), random); engine.init(param); initialised = true; } else if (params == null && configuration.getEcImplicitlyCa() != null) { ECParameterSpec p = configuration.getEcImplicitlyCa(); this.ecParams = (ECParameterSpec)params; param = new ECKeyGenerationParameters(new ECDomainParameters(p.getCurve(), p.getG(), p.getN()), random); engine.init(param); initialised = true; } else if (params == null && configuration.getEcImplicitlyCa() == null) { throw new InvalidAlgorithmParameterException("null parameter passed but no implicitCA set"); } else { throw new InvalidAlgorithmParameterException("parameter object not a ECParameterSpec"); } } public KeyPair generateKeyPair() { if (!initialised) { throw new IllegalStateException("EC Key Pair Generator not initialised"); } AsymmetricCipherKeyPair pair = engine.generateKeyPair(); ECPublicKeyParameters pub = (ECPublicKeyParameters)pair.getPublic(); ECPrivateKeyParameters priv = (ECPrivateKeyParameters)pair.getPrivate(); if (ecParams == null) { return new KeyPair(new BCECPublicKey(algorithm, pub, configuration), new BCECPrivateKey(algorithm, priv, configuration)); } else { ECParameterSpec p = (ECParameterSpec)ecParams; BCECPublicKey pubKey = new BCECPublicKey(algorithm, pub, p, configuration); return new KeyPair(pubKey, new BCECPrivateKey(algorithm, priv, pubKey, p, configuration)); } } } public static class ECDSA extends EC { public ECDSA() { super("ECDSA", BouncyCastleProvider.CONFIGURATION); } } public static class ECDH extends EC { public ECDH() { super("ECDH", BouncyCastleProvider.CONFIGURATION); } } public static class ECDHC extends EC { public ECDHC() { super("ECDHC", BouncyCastleProvider.CONFIGURATION); } } public static class ECMQV extends EC { public ECMQV() { super("ECMQV", BouncyCastleProvider.CONFIGURATION); } } } bouncycastle-1.49.orig/jdk1.4/org/bouncycastle/jcajce/provider/asymmetric/elgamal/0000755000175000017500000000000012152033550027532 5ustar ebourgebourgbouncycastle-1.49.orig/jdk1.4/org/bouncycastle/jcajce/provider/asymmetric/elgamal/CipherSpi.java0000644000175000017500000002051412110036731032263 0ustar ebourgebourgpackage org.bouncycastle.jcajce.provider.asymmetric.elgamal; import java.security.AlgorithmParameters; import java.security.InvalidAlgorithmParameterException; import java.security.InvalidKeyException; import java.security.InvalidParameterException; import java.security.Key; import java.security.NoSuchAlgorithmException; import java.security.PrivateKey; import java.security.PublicKey; import java.security.SecureRandom; import java.security.spec.AlgorithmParameterSpec; import javax.crypto.BadPaddingException; import javax.crypto.IllegalBlockSizeException; import javax.crypto.NoSuchPaddingException; import javax.crypto.interfaces.DHKey; import org.bouncycastle.crypto.AsymmetricBlockCipher; import org.bouncycastle.crypto.BufferedAsymmetricBlockCipher; import org.bouncycastle.crypto.CipherParameters; import org.bouncycastle.crypto.InvalidCipherTextException; import org.bouncycastle.crypto.encodings.ISO9796d1Encoding; import org.bouncycastle.crypto.encodings.OAEPEncoding; import org.bouncycastle.crypto.encodings.PKCS1Encoding; import org.bouncycastle.crypto.engines.ElGamalEngine; import org.bouncycastle.crypto.params.ParametersWithRandom; import org.bouncycastle.jcajce.provider.asymmetric.util.BaseCipherSpi; import org.bouncycastle.jce.interfaces.ElGamalKey; import org.bouncycastle.jce.interfaces.ElGamalPrivateKey; import org.bouncycastle.jce.interfaces.ElGamalPublicKey; import org.bouncycastle.jce.provider.BouncyCastleProvider; import org.bouncycastle.util.Strings; public class CipherSpi extends BaseCipherSpi { private BufferedAsymmetricBlockCipher cipher; private AlgorithmParameterSpec paramSpec; private AlgorithmParameters engineParams; public CipherSpi( AsymmetricBlockCipher engine) { cipher = new BufferedAsymmetricBlockCipher(engine); } protected int engineGetBlockSize() { return cipher.getInputBlockSize(); } protected int engineGetKeySize( Key key) { if (key instanceof ElGamalKey) { ElGamalKey k = (ElGamalKey)key; return k.getParameters().getP().bitLength(); } else if (key instanceof DHKey) { DHKey k = (DHKey)key; return k.getParams().getP().bitLength(); } throw new IllegalArgumentException("not an ElGamal key!"); } protected int engineGetOutputSize( int inputLen) { return cipher.getOutputBlockSize(); } protected AlgorithmParameters engineGetParameters() { if (engineParams == null) { if (paramSpec != null) { try { engineParams = AlgorithmParameters.getInstance("OAEP", BouncyCastleProvider.PROVIDER_NAME); engineParams.init(paramSpec); } catch (Exception e) { throw new RuntimeException(e.toString()); } } } return engineParams; } protected void engineSetMode( String mode) throws NoSuchAlgorithmException { String md = Strings.toUpperCase(mode); if (md.equals("NONE") || md.equals("ECB")) { return; } throw new NoSuchAlgorithmException("can't support mode " + mode); } protected void engineSetPadding( String padding) throws NoSuchPaddingException { String pad = Strings.toUpperCase(padding); if (pad.equals("NOPADDING")) { cipher = new BufferedAsymmetricBlockCipher(new ElGamalEngine()); } else if (pad.equals("PKCS1PADDING")) { cipher = new BufferedAsymmetricBlockCipher(new PKCS1Encoding(new ElGamalEngine())); } else if (pad.equals("ISO9796-1PADDING")) { cipher = new BufferedAsymmetricBlockCipher(new ISO9796d1Encoding(new ElGamalEngine())); } else if (pad.equals("OAEPPADDING")) { cipher = new BufferedAsymmetricBlockCipher(new OAEPEncoding(new ElGamalEngine())); } else if (pad.equals("OAEPWITHSHA1ANDMGF1PADDING")) { cipher = new BufferedAsymmetricBlockCipher(new OAEPEncoding(new ElGamalEngine())); } else { throw new NoSuchPaddingException(padding + " unavailable with ElGamal."); } } protected void engineInit( int opmode, Key key, AlgorithmParameterSpec params, SecureRandom random) throws InvalidKeyException { CipherParameters param; if (params == null) { if (key instanceof ElGamalPublicKey) { param = ElGamalUtil.generatePublicKeyParameter((PublicKey)key); } else if (key instanceof ElGamalPrivateKey) { param = ElGamalUtil.generatePrivateKeyParameter((PrivateKey)key); } else { throw new InvalidKeyException("unknown key type passed to ElGamal"); } } else { throw new IllegalArgumentException("unknown parameter type."); } if (random != null) { param = new ParametersWithRandom(param, random); } switch (opmode) { case javax.crypto.Cipher.ENCRYPT_MODE: case javax.crypto.Cipher.WRAP_MODE: cipher.init(true, param); break; case javax.crypto.Cipher.DECRYPT_MODE: case javax.crypto.Cipher.UNWRAP_MODE: cipher.init(false, param); break; default: throw new InvalidParameterException("unknown opmode " + opmode + " passed to ElGamal"); } } protected void engineInit( int opmode, Key key, AlgorithmParameters params, SecureRandom random) throws InvalidKeyException, InvalidAlgorithmParameterException { throw new InvalidAlgorithmParameterException("can't handle parameters in ElGamal"); } protected void engineInit( int opmode, Key key, SecureRandom random) throws InvalidKeyException { engineInit(opmode, key, (AlgorithmParameterSpec)null, random); } protected byte[] engineUpdate( byte[] input, int inputOffset, int inputLen) { cipher.processBytes(input, inputOffset, inputLen); return null; } protected int engineUpdate( byte[] input, int inputOffset, int inputLen, byte[] output, int outputOffset) { cipher.processBytes(input, inputOffset, inputLen); return 0; } protected byte[] engineDoFinal( byte[] input, int inputOffset, int inputLen) throws IllegalBlockSizeException, BadPaddingException { cipher.processBytes(input, inputOffset, inputLen); try { return cipher.doFinal(); } catch (InvalidCipherTextException e) { throw new BadPaddingException(e.getMessage()); } } protected int engineDoFinal( byte[] input, int inputOffset, int inputLen, byte[] output, int outputOffset) throws IllegalBlockSizeException, BadPaddingException { byte[] out; cipher.processBytes(input, inputOffset, inputLen); try { out = cipher.doFinal(); } catch (InvalidCipherTextException e) { throw new BadPaddingException(e.getMessage()); } for (int i = 0; i != out.length; i++) { output[outputOffset + i] = out[i]; } return out.length; } /** * classes that inherit from us. */ static public class NoPadding extends CipherSpi { public NoPadding() { super(new ElGamalEngine()); } } static public class PKCS1v1_5Padding extends CipherSpi { public PKCS1v1_5Padding() { super(new PKCS1Encoding(new ElGamalEngine())); } } } bouncycastle-1.49.orig/jdk1.4/org/bouncycastle/jcajce/provider/keystore/0000755000175000017500000000000012152033550025620 5ustar ebourgebourgbouncycastle-1.49.orig/jdk1.4/org/bouncycastle/jcajce/provider/keystore/pkcs12/0000755000175000017500000000000012152033550026723 5ustar ebourgebourg././@LongLink0000000000000000000000000000014600000000000011566 Lustar rootrootbouncycastle-1.49.orig/jdk1.4/org/bouncycastle/jcajce/provider/keystore/pkcs12/PKCS12KeyStoreSpi.javabouncycastle-1.49.orig/jdk1.4/org/bouncycastle/jcajce/provider/keystore/pkcs12/PKCS12KeyStoreSpi.jav0000644000175000017500000015562212132471233032507 0ustar ebourgebourgpackage org.bouncycastle.jcajce.provider.keystore.pkcs12; import java.io.BufferedInputStream; import java.io.ByteArrayInputStream; import java.io.ByteArrayOutputStream; import java.io.IOException; import java.io.InputStream; import java.io.OutputStream; import java.security.Key; import java.security.KeyStore; import java.security.KeyStoreException; import java.security.KeyStoreSpi; import java.security.NoSuchAlgorithmException; import java.security.Principal; import java.security.PrivateKey; import java.security.Provider; import java.security.PublicKey; import java.security.SecureRandom; import java.security.UnrecoverableKeyException; import java.security.cert.Certificate; import java.security.cert.CertificateEncodingException; import java.security.cert.CertificateException; import java.security.cert.CertificateFactory; import java.security.cert.X509Certificate; import java.util.Date; import java.util.Enumeration; import java.util.Hashtable; import java.util.Vector; import javax.crypto.Cipher; import javax.crypto.Mac; import javax.crypto.SecretKey; import javax.crypto.SecretKeyFactory; import javax.crypto.spec.IvParameterSpec; import javax.crypto.spec.PBEKeySpec; import javax.crypto.spec.PBEParameterSpec; import org.bouncycastle.asn1.ASN1Encodable; import org.bouncycastle.asn1.ASN1EncodableVector; import org.bouncycastle.asn1.ASN1Encoding; import org.bouncycastle.asn1.ASN1InputStream; import org.bouncycastle.asn1.ASN1ObjectIdentifier; import org.bouncycastle.asn1.ASN1OctetString; import org.bouncycastle.asn1.ASN1Primitive; import org.bouncycastle.asn1.ASN1Sequence; import org.bouncycastle.asn1.ASN1Set; import org.bouncycastle.asn1.BEROctetString; import org.bouncycastle.asn1.BEROutputStream; import org.bouncycastle.asn1.DERBMPString; import org.bouncycastle.asn1.DERNull; import org.bouncycastle.asn1.DEROctetString; import org.bouncycastle.asn1.DEROutputStream; import org.bouncycastle.asn1.DERSequence; import org.bouncycastle.asn1.DERSet; import org.bouncycastle.asn1.pkcs.AuthenticatedSafe; import org.bouncycastle.asn1.pkcs.CertBag; import org.bouncycastle.asn1.pkcs.ContentInfo; import org.bouncycastle.asn1.pkcs.EncryptedData; import org.bouncycastle.asn1.pkcs.MacData; import org.bouncycastle.asn1.pkcs.PBES2Parameters; import org.bouncycastle.asn1.pkcs.PBKDF2Params; import org.bouncycastle.asn1.pkcs.PKCS12PBEParams; import org.bouncycastle.asn1.pkcs.PKCSObjectIdentifiers; import org.bouncycastle.asn1.pkcs.Pfx; import org.bouncycastle.asn1.pkcs.SafeBag; import org.bouncycastle.asn1.util.ASN1Dump; import org.bouncycastle.asn1.x509.AlgorithmIdentifier; import org.bouncycastle.asn1.x509.AuthorityKeyIdentifier; import org.bouncycastle.asn1.x509.DigestInfo; import org.bouncycastle.asn1.x509.Extension; import org.bouncycastle.asn1.x509.SubjectKeyIdentifier; import org.bouncycastle.asn1.x509.SubjectPublicKeyInfo; import org.bouncycastle.asn1.x509.X509ObjectIdentifiers; import org.bouncycastle.jcajce.provider.symmetric.util.BCPBEKey; import org.bouncycastle.jcajce.provider.util.SecretKeyUtil; import org.bouncycastle.jce.interfaces.BCKeyStore; import org.bouncycastle.jce.interfaces.PKCS12BagAttributeCarrier; import org.bouncycastle.jce.provider.BouncyCastleProvider; import org.bouncycastle.util.Arrays; import org.bouncycastle.util.Strings; import org.bouncycastle.util.encoders.Hex; public class PKCS12KeyStoreSpi extends KeyStoreSpi implements PKCSObjectIdentifiers, X509ObjectIdentifiers, BCKeyStore { private static final int SALT_SIZE = 20; private static final int MIN_ITERATIONS = 1024; private static final Provider bcProvider = new BouncyCastleProvider(); private IgnoresCaseHashtable keys = new IgnoresCaseHashtable(); private Hashtable localIds = new Hashtable(); private IgnoresCaseHashtable certs = new IgnoresCaseHashtable(); private Hashtable chainCerts = new Hashtable(); private Hashtable keyCerts = new Hashtable(); // // generic object types // static final int NULL = 0; static final int CERTIFICATE = 1; static final int KEY = 2; static final int SECRET = 3; static final int SEALED = 4; // // key types // static final int KEY_PRIVATE = 0; static final int KEY_PUBLIC = 1; static final int KEY_SECRET = 2; protected SecureRandom random = new SecureRandom(); // use of final causes problems with JDK 1.2 compiler private CertificateFactory certFact; private ASN1ObjectIdentifier keyAlgorithm; private ASN1ObjectIdentifier certAlgorithm; private class CertId { byte[] id; CertId( PublicKey key) { this.id = createSubjectKeyId(key).getKeyIdentifier(); } CertId( byte[] id) { this.id = id; } public int hashCode() { return Arrays.hashCode(id); } public boolean equals( Object o) { if (o == this) { return true; } if (!(o instanceof CertId)) { return false; } CertId cId = (CertId)o; return Arrays.areEqual(id, cId.id); } } public PKCS12KeyStoreSpi( Provider provider, ASN1ObjectIdentifier keyAlgorithm, ASN1ObjectIdentifier certAlgorithm) { this.keyAlgorithm = keyAlgorithm; this.certAlgorithm = certAlgorithm; try { if (provider != null) { certFact = CertificateFactory.getInstance("X.509", provider); } else { certFact = CertificateFactory.getInstance("X.509"); } } catch (Exception e) { throw new IllegalArgumentException("can't create cert factory - " + e.toString()); } } private SubjectKeyIdentifier createSubjectKeyId( PublicKey pubKey) { try { SubjectPublicKeyInfo info = new SubjectPublicKeyInfo( (ASN1Sequence)ASN1Primitive.fromByteArray(pubKey.getEncoded())); return new SubjectKeyIdentifier(info); } catch (Exception e) { throw new RuntimeException("error creating key"); } } public void setRandom( SecureRandom rand) { this.random = rand; } public Enumeration engineAliases() { Hashtable tab = new Hashtable(); Enumeration e = certs.keys(); while (e.hasMoreElements()) { tab.put(e.nextElement(), "cert"); } e = keys.keys(); while (e.hasMoreElements()) { String a = (String)e.nextElement(); if (tab.get(a) == null) { tab.put(a, "key"); } } return tab.keys(); } public boolean engineContainsAlias( String alias) { return (certs.get(alias) != null || keys.get(alias) != null); } /** * this is not quite complete - we should follow up on the chain, a bit * tricky if a certificate appears in more than one chain... */ public void engineDeleteEntry( String alias) throws KeyStoreException { Key k = (Key)keys.remove(alias); Certificate c = (Certificate)certs.remove(alias); if (c != null) { chainCerts.remove(new CertId(c.getPublicKey())); } if (k != null) { String id = (String)localIds.remove(alias); if (id != null) { c = (Certificate)keyCerts.remove(id); } if (c != null) { chainCerts.remove(new CertId(c.getPublicKey())); } } } /** * simply return the cert for the private key */ public Certificate engineGetCertificate( String alias) { if (alias == null) { throw new IllegalArgumentException("null alias passed to getCertificate."); } Certificate c = (Certificate)certs.get(alias); // // look up the key table - and try the local key id // if (c == null) { String id = (String)localIds.get(alias); if (id != null) { c = (Certificate)keyCerts.get(id); } else { c = (Certificate)keyCerts.get(alias); } } return c; } public String engineGetCertificateAlias( Certificate cert) { Enumeration c = certs.elements(); Enumeration k = certs.keys(); while (c.hasMoreElements()) { Certificate tc = (Certificate)c.nextElement(); String ta = (String)k.nextElement(); if (tc.equals(cert)) { return ta; } } c = keyCerts.elements(); k = keyCerts.keys(); while (c.hasMoreElements()) { Certificate tc = (Certificate)c.nextElement(); String ta = (String)k.nextElement(); if (tc.equals(cert)) { return ta; } } return null; } public Certificate[] engineGetCertificateChain( String alias) { if (alias == null) { throw new IllegalArgumentException("null alias passed to getCertificateChain."); } if (!engineIsKeyEntry(alias)) { return null; } Certificate c = engineGetCertificate(alias); if (c != null) { Vector cs = new Vector(); while (c != null) { X509Certificate x509c = (X509Certificate)c; Certificate nextC = null; byte[] bytes = x509c.getExtensionValue(Extension.authorityKeyIdentifier.getId()); if (bytes != null) { try { ASN1InputStream aIn = new ASN1InputStream(bytes); byte[] authBytes = ((ASN1OctetString)aIn.readObject()).getOctets(); aIn = new ASN1InputStream(authBytes); AuthorityKeyIdentifier id = AuthorityKeyIdentifier.getInstance(aIn.readObject()); if (id.getKeyIdentifier() != null) { nextC = (Certificate)chainCerts.get(new CertId(id.getKeyIdentifier())); } } catch (IOException e) { throw new RuntimeException(e.toString()); } } if (nextC == null) { // // no authority key id, try the Issuer DN // Principal i = x509c.getIssuerDN(); Principal s = x509c.getSubjectDN(); if (!i.equals(s)) { Enumeration e = chainCerts.keys(); while (e.hasMoreElements()) { X509Certificate crt = (X509Certificate)chainCerts.get(e.nextElement()); Principal sub = crt.getSubjectDN(); if (sub.equals(i)) { try { x509c.verify(crt.getPublicKey()); nextC = crt; break; } catch (Exception ex) { // continue } } } } } cs.addElement(c); if (nextC != c) // self signed - end of the chain { c = nextC; } else { c = null; } } Certificate[] certChain = new Certificate[cs.size()]; for (int i = 0; i != certChain.length; i++) { certChain[i] = (Certificate)cs.elementAt(i); } return certChain; } return null; } public Date engineGetCreationDate(String alias) { if (alias == null) { throw new NullPointerException("alias == null"); } if (keys.get(alias) == null && certs.get(alias) == null) { return null; } return new Date(); } public Key engineGetKey( String alias, char[] password) throws NoSuchAlgorithmException, UnrecoverableKeyException { if (alias == null) { throw new IllegalArgumentException("null alias passed to getKey."); } return (Key)keys.get(alias); } public boolean engineIsCertificateEntry( String alias) { return (certs.get(alias) != null && keys.get(alias) == null); } public boolean engineIsKeyEntry( String alias) { return (keys.get(alias) != null); } public void engineSetCertificateEntry( String alias, Certificate cert) throws KeyStoreException { if (keys.get(alias) != null) { throw new KeyStoreException("There is a key entry with the name " + alias + "."); } certs.put(alias, cert); chainCerts.put(new CertId(cert.getPublicKey()), cert); } public void engineSetKeyEntry( String alias, byte[] key, Certificate[] chain) throws KeyStoreException { throw new RuntimeException("operation not supported"); } public void engineSetKeyEntry( String alias, Key key, char[] password, Certificate[] chain) throws KeyStoreException { if (!(key instanceof PrivateKey)) { throw new KeyStoreException("PKCS12 does not support non-PrivateKeys"); } if ((key instanceof PrivateKey) && (chain == null)) { throw new KeyStoreException("no certificate chain for private key"); } if (keys.get(alias) != null) { engineDeleteEntry(alias); } keys.put(alias, key); if (chain != null) { certs.put(alias, chain[0]); for (int i = 0; i != chain.length; i++) { chainCerts.put(new CertId(chain[i].getPublicKey()), chain[i]); } } } public int engineSize() { Hashtable tab = new Hashtable(); Enumeration e = certs.keys(); while (e.hasMoreElements()) { tab.put(e.nextElement(), "cert"); } e = keys.keys(); while (e.hasMoreElements()) { String a = (String)e.nextElement(); if (tab.get(a) == null) { tab.put(a, "key"); } } return tab.size(); } protected PrivateKey unwrapKey( AlgorithmIdentifier algId, byte[] data, char[] password, boolean wrongPKCS12Zero) throws IOException { ASN1ObjectIdentifier algorithm = algId.getAlgorithm(); try { if (algorithm.on(PKCSObjectIdentifiers.pkcs_12PbeIds)) { PKCS12PBEParams pbeParams = PKCS12PBEParams.getInstance(algId.getParameters()); PBEKeySpec pbeSpec = new PBEKeySpec(password); PrivateKey out; SecretKeyFactory keyFact = SecretKeyFactory.getInstance( algorithm.getId(), bcProvider); PBEParameterSpec defParams = new PBEParameterSpec( pbeParams.getIV(), pbeParams.getIterations().intValue()); SecretKey k = keyFact.generateSecret(pbeSpec); ((BCPBEKey)k).setTryWrongPKCS12Zero(wrongPKCS12Zero); Cipher cipher = Cipher.getInstance(algorithm.getId(), bcProvider); cipher.init(Cipher.UNWRAP_MODE, k, defParams); // we pass "" as the key algorithm type as it is unknown at this point return (PrivateKey)cipher.unwrap(data, "", Cipher.PRIVATE_KEY); } else if (algorithm.equals(PKCSObjectIdentifiers.id_PBES2)) { PBES2Parameters alg = PBES2Parameters.getInstance(algId.getParameters()); PBKDF2Params func = PBKDF2Params.getInstance(alg.getKeyDerivationFunc().getParameters()); SecretKeyFactory keyFact = SecretKeyFactory.getInstance(alg.getKeyDerivationFunc().getAlgorithm().getId(), bcProvider); SecretKey k = keyFact.generateSecret(new PBEKeySpec(password, func.getSalt(), func.getIterationCount().intValue(), SecretKeyUtil.getKeySize(alg.getEncryptionScheme().getAlgorithm()))); Cipher cipher = Cipher.getInstance(alg.getEncryptionScheme().getAlgorithm().getId(), bcProvider); cipher.init(Cipher.UNWRAP_MODE, k, new IvParameterSpec(ASN1OctetString.getInstance(alg.getEncryptionScheme().getParameters()).getOctets())); // we pass "" as the key algorithm type as it is unknown at this point return (PrivateKey)cipher.unwrap(data, "", Cipher.PRIVATE_KEY); } } catch (Exception e) { throw new IOException("exception unwrapping private key - " + e.toString()); } throw new IOException("exception unwrapping private key - cannot recognise: " + algorithm); } protected byte[] wrapKey( String algorithm, Key key, PKCS12PBEParams pbeParams, char[] password) throws IOException { PBEKeySpec pbeSpec = new PBEKeySpec(password); byte[] out; try { SecretKeyFactory keyFact = SecretKeyFactory.getInstance( algorithm, bcProvider); PBEParameterSpec defParams = new PBEParameterSpec( pbeParams.getIV(), pbeParams.getIterations().intValue()); Cipher cipher = Cipher.getInstance(algorithm, bcProvider); cipher.init(Cipher.WRAP_MODE, keyFact.generateSecret(pbeSpec), defParams); out = cipher.wrap(key); } catch (Exception e) { throw new IOException("exception encrypting data - " + e.toString()); } return out; } protected byte[] cryptData( boolean forEncryption, AlgorithmIdentifier algId, char[] password, boolean wrongPKCS12Zero, byte[] data) throws IOException { String algorithm = algId.getAlgorithm().getId(); PKCS12PBEParams pbeParams = PKCS12PBEParams.getInstance(algId.getParameters()); PBEKeySpec pbeSpec = new PBEKeySpec(password); try { SecretKeyFactory keyFact = SecretKeyFactory.getInstance(algorithm, bcProvider); PBEParameterSpec defParams = new PBEParameterSpec( pbeParams.getIV(), pbeParams.getIterations().intValue()); BCPBEKey key = (BCPBEKey)keyFact.generateSecret(pbeSpec); key.setTryWrongPKCS12Zero(wrongPKCS12Zero); Cipher cipher = Cipher.getInstance(algorithm, bcProvider); int mode = forEncryption ? Cipher.ENCRYPT_MODE : Cipher.DECRYPT_MODE; cipher.init(mode, key, defParams); return cipher.doFinal(data); } catch (Exception e) { throw new IOException("exception decrypting data - " + e.toString()); } } public void engineLoad( InputStream stream, char[] password) throws IOException { if (stream == null) // just initialising { return; } if (password == null) { throw new NullPointerException("No password supplied for PKCS#12 KeyStore."); } BufferedInputStream bufIn = new BufferedInputStream(stream); bufIn.mark(10); int head = bufIn.read(); if (head != 0x30) { throw new IOException("stream does not represent a PKCS12 key store"); } bufIn.reset(); ASN1InputStream bIn = new ASN1InputStream(bufIn); ASN1Sequence obj = (ASN1Sequence)bIn.readObject(); Pfx bag = Pfx.getInstance(obj); ContentInfo info = bag.getAuthSafe(); Vector chain = new Vector(); boolean unmarkedKey = false; boolean wrongPKCS12Zero = false; if (bag.getMacData() != null) // check the mac code { MacData mData = bag.getMacData(); DigestInfo dInfo = mData.getMac(); AlgorithmIdentifier algId = dInfo.getAlgorithmId(); byte[] salt = mData.getSalt(); int itCount = mData.getIterationCount().intValue(); byte[] data = ((ASN1OctetString)info.getContent()).getOctets(); try { byte[] res = calculatePbeMac(algId.getAlgorithm(), salt, itCount, password, false, data); byte[] dig = dInfo.getDigest(); if (!Arrays.constantTimeAreEqual(res, dig)) { if (password.length > 0) { throw new IOException("PKCS12 key store mac invalid - wrong password or corrupted file."); } // Try with incorrect zero length password res = calculatePbeMac(algId.getAlgorithm(), salt, itCount, password, true, data); if (!Arrays.constantTimeAreEqual(res, dig)) { throw new IOException("PKCS12 key store mac invalid - wrong password or corrupted file."); } wrongPKCS12Zero = true; } } catch (IOException e) { throw e; } catch (Exception e) { throw new IOException("error constructing MAC: " + e.toString()); } } keys = new IgnoresCaseHashtable(); localIds = new Hashtable(); if (info.getContentType().equals(data)) { bIn = new ASN1InputStream(((ASN1OctetString)info.getContent()).getOctets()); AuthenticatedSafe authSafe = AuthenticatedSafe.getInstance(bIn.readObject()); ContentInfo[] c = authSafe.getContentInfo(); for (int i = 0; i != c.length; i++) { if (c[i].getContentType().equals(data)) { ASN1InputStream dIn = new ASN1InputStream(((ASN1OctetString)c[i].getContent()).getOctets()); ASN1Sequence seq = (ASN1Sequence)dIn.readObject(); for (int j = 0; j != seq.size(); j++) { SafeBag b = SafeBag.getInstance(seq.getObjectAt(j)); if (b.getBagId().equals(pkcs8ShroudedKeyBag)) { org.bouncycastle.asn1.pkcs.EncryptedPrivateKeyInfo eIn = org.bouncycastle.asn1.pkcs.EncryptedPrivateKeyInfo.getInstance(b.getBagValue()); PrivateKey privKey = unwrapKey(eIn.getEncryptionAlgorithm(), eIn.getEncryptedData(), password, wrongPKCS12Zero); // // set the attributes on the key // PKCS12BagAttributeCarrier bagAttr = (PKCS12BagAttributeCarrier)privKey; String alias = null; ASN1OctetString localId = null; if (b.getBagAttributes() != null) { Enumeration e = b.getBagAttributes().getObjects(); while (e.hasMoreElements()) { ASN1Sequence sq = (ASN1Sequence)e.nextElement(); ASN1ObjectIdentifier aOid = (ASN1ObjectIdentifier)sq.getObjectAt(0); ASN1Set attrSet = (ASN1Set)sq.getObjectAt(1); ASN1Primitive attr = null; if (attrSet.size() > 0) { attr = (ASN1Primitive)attrSet.getObjectAt(0); ASN1Encodable existing = bagAttr.getBagAttribute(aOid); if (existing != null) { // OK, but the value has to be the same if (!existing.toASN1Primitive().equals(attr)) { throw new IOException( "attempt to add existing attribute with different value"); } } else { bagAttr.setBagAttribute(aOid, attr); } } if (aOid.equals(pkcs_9_at_friendlyName)) { alias = ((DERBMPString)attr).getString(); keys.put(alias, privKey); } else if (aOid.equals(pkcs_9_at_localKeyId)) { localId = (ASN1OctetString)attr; } } } if (localId != null) { String name = new String(Hex.encode(localId.getOctets())); if (alias == null) { keys.put(name, privKey); } else { localIds.put(alias, name); } } else { unmarkedKey = true; keys.put("unmarked", privKey); } } else if (b.getBagId().equals(certBag)) { chain.addElement(b); } else { System.out.println("extra in data " + b.getBagId()); System.out.println(ASN1Dump.dumpAsString(b)); } } } else if (c[i].getContentType().equals(encryptedData)) { EncryptedData d = EncryptedData.getInstance(c[i].getContent()); byte[] octets = cryptData(false, d.getEncryptionAlgorithm(), password, wrongPKCS12Zero, d.getContent().getOctets()); ASN1Sequence seq = (ASN1Sequence)ASN1Primitive.fromByteArray(octets); for (int j = 0; j != seq.size(); j++) { SafeBag b = SafeBag.getInstance(seq.getObjectAt(j)); if (b.getBagId().equals(certBag)) { chain.addElement(b); } else if (b.getBagId().equals(pkcs8ShroudedKeyBag)) { org.bouncycastle.asn1.pkcs.EncryptedPrivateKeyInfo eIn = org.bouncycastle.asn1.pkcs.EncryptedPrivateKeyInfo.getInstance(b.getBagValue()); PrivateKey privKey = unwrapKey(eIn.getEncryptionAlgorithm(), eIn.getEncryptedData(), password, wrongPKCS12Zero); // // set the attributes on the key // PKCS12BagAttributeCarrier bagAttr = (PKCS12BagAttributeCarrier)privKey; String alias = null; ASN1OctetString localId = null; Enumeration e = b.getBagAttributes().getObjects(); while (e.hasMoreElements()) { ASN1Sequence sq = (ASN1Sequence)e.nextElement(); ASN1ObjectIdentifier aOid = (ASN1ObjectIdentifier)sq.getObjectAt(0); ASN1Set attrSet = (ASN1Set)sq.getObjectAt(1); ASN1Primitive attr = null; if (attrSet.size() > 0) { attr = (ASN1Primitive)attrSet.getObjectAt(0); ASN1Encodable existing = bagAttr.getBagAttribute(aOid); if (existing != null) { // OK, but the value has to be the same if (!existing.toASN1Primitive().equals(attr)) { throw new IOException( "attempt to add existing attribute with different value"); } } else { bagAttr.setBagAttribute(aOid, attr); } } if (aOid.equals(pkcs_9_at_friendlyName)) { alias = ((DERBMPString)attr).getString(); keys.put(alias, privKey); } else if (aOid.equals(pkcs_9_at_localKeyId)) { localId = (ASN1OctetString)attr; } } String name = new String(Hex.encode(localId.getOctets())); if (alias == null) { keys.put(name, privKey); } else { localIds.put(alias, name); } } else if (b.getBagId().equals(keyBag)) { org.bouncycastle.asn1.pkcs.PrivateKeyInfo kInfo = org.bouncycastle.asn1.pkcs.PrivateKeyInfo.getInstance(b.getBagValue()); PrivateKey privKey = BouncyCastleProvider.getPrivateKey(kInfo); // // set the attributes on the key // PKCS12BagAttributeCarrier bagAttr = (PKCS12BagAttributeCarrier)privKey; String alias = null; ASN1OctetString localId = null; Enumeration e = b.getBagAttributes().getObjects(); while (e.hasMoreElements()) { ASN1Sequence sq = (ASN1Sequence)e.nextElement(); ASN1ObjectIdentifier aOid = (ASN1ObjectIdentifier)sq.getObjectAt(0); ASN1Set attrSet = (ASN1Set)sq.getObjectAt(1); ASN1Primitive attr = null; if (attrSet.size() > 0) { attr = (ASN1Primitive)attrSet.getObjectAt(0); ASN1Encodable existing = bagAttr.getBagAttribute(aOid); if (existing != null) { // OK, but the value has to be the same if (!existing.toASN1Primitive().equals(attr)) { throw new IOException( "attempt to add existing attribute with different value"); } } else { bagAttr.setBagAttribute(aOid, attr); } } if (aOid.equals(pkcs_9_at_friendlyName)) { alias = ((DERBMPString)attr).getString(); keys.put(alias, privKey); } else if (aOid.equals(pkcs_9_at_localKeyId)) { localId = (ASN1OctetString)attr; } } String name = new String(Hex.encode(localId.getOctets())); if (alias == null) { keys.put(name, privKey); } else { localIds.put(alias, name); } } else { System.out.println("extra in encryptedData " + b.getBagId()); System.out.println(ASN1Dump.dumpAsString(b)); } } } else { System.out.println("extra " + c[i].getContentType().getId()); System.out.println("extra " + ASN1Dump.dumpAsString(c[i].getContent())); } } } certs = new IgnoresCaseHashtable(); chainCerts = new Hashtable(); keyCerts = new Hashtable(); for (int i = 0; i != chain.size(); i++) { SafeBag b = (SafeBag)chain.elementAt(i); CertBag cb = CertBag.getInstance(b.getBagValue()); if (!cb.getCertId().equals(x509Certificate)) { throw new RuntimeException("Unsupported certificate type: " + cb.getCertId()); } Certificate cert; try { ByteArrayInputStream cIn = new ByteArrayInputStream( ((ASN1OctetString)cb.getCertValue()).getOctets()); cert = certFact.generateCertificate(cIn); } catch (Exception e) { throw new RuntimeException(e.toString()); } // // set the attributes // ASN1OctetString localId = null; String alias = null; if (b.getBagAttributes() != null) { Enumeration e = b.getBagAttributes().getObjects(); while (e.hasMoreElements()) { ASN1Sequence sq = (ASN1Sequence)e.nextElement(); ASN1ObjectIdentifier oid = (ASN1ObjectIdentifier)sq.getObjectAt(0); ASN1Primitive attr = (ASN1Primitive)((ASN1Set)sq.getObjectAt(1)).getObjectAt(0); PKCS12BagAttributeCarrier bagAttr = null; if (cert instanceof PKCS12BagAttributeCarrier) { bagAttr = (PKCS12BagAttributeCarrier)cert; ASN1Encodable existing = bagAttr.getBagAttribute(oid); if (existing != null) { // OK, but the value has to be the same if (!existing.toASN1Primitive().equals(attr)) { throw new IOException( "attempt to add existing attribute with different value"); } } else { bagAttr.setBagAttribute(oid, attr); } } if (oid.equals(pkcs_9_at_friendlyName)) { alias = ((DERBMPString)attr).getString(); } else if (oid.equals(pkcs_9_at_localKeyId)) { localId = (ASN1OctetString)attr; } } } chainCerts.put(new CertId(cert.getPublicKey()), cert); if (unmarkedKey) { if (keyCerts.isEmpty()) { String name = new String(Hex.encode(createSubjectKeyId(cert.getPublicKey()).getKeyIdentifier())); keyCerts.put(name, cert); keys.put(name, keys.remove("unmarked")); } } else { // // the local key id needs to override the friendly name // if (localId != null) { String name = new String(Hex.encode(localId.getOctets())); keyCerts.put(name, cert); } if (alias != null) { certs.put(alias, cert); } } } } public void engineStore(OutputStream stream, char[] password) throws IOException { doStore(stream, password, false); } private void doStore(OutputStream stream, char[] password, boolean useDEREncoding) throws IOException { if (password == null) { throw new NullPointerException("No password supplied for PKCS#12 KeyStore."); } // // handle the key // ASN1EncodableVector keyS = new ASN1EncodableVector(); Enumeration ks = keys.keys(); while (ks.hasMoreElements()) { byte[] kSalt = new byte[SALT_SIZE]; random.nextBytes(kSalt); String name = (String)ks.nextElement(); PrivateKey privKey = (PrivateKey)keys.get(name); PKCS12PBEParams kParams = new PKCS12PBEParams(kSalt, MIN_ITERATIONS); byte[] kBytes = wrapKey(keyAlgorithm.getId(), privKey, kParams, password); AlgorithmIdentifier kAlgId = new AlgorithmIdentifier(keyAlgorithm, kParams.toASN1Primitive()); org.bouncycastle.asn1.pkcs.EncryptedPrivateKeyInfo kInfo = new org.bouncycastle.asn1.pkcs.EncryptedPrivateKeyInfo(kAlgId, kBytes); boolean attrSet = false; ASN1EncodableVector kName = new ASN1EncodableVector(); if (privKey instanceof PKCS12BagAttributeCarrier) { PKCS12BagAttributeCarrier bagAttrs = (PKCS12BagAttributeCarrier)privKey; // // make sure we are using the local alias on store // DERBMPString nm = (DERBMPString)bagAttrs.getBagAttribute(pkcs_9_at_friendlyName); if (nm == null || !nm.getString().equals(name)) { bagAttrs.setBagAttribute(pkcs_9_at_friendlyName, new DERBMPString(name)); } // // make sure we have a local key-id // if (bagAttrs.getBagAttribute(pkcs_9_at_localKeyId) == null) { Certificate ct = engineGetCertificate(name); bagAttrs.setBagAttribute(pkcs_9_at_localKeyId, createSubjectKeyId(ct.getPublicKey())); } Enumeration e = bagAttrs.getBagAttributeKeys(); while (e.hasMoreElements()) { ASN1ObjectIdentifier oid = (ASN1ObjectIdentifier)e.nextElement(); ASN1EncodableVector kSeq = new ASN1EncodableVector(); kSeq.add(oid); kSeq.add(new DERSet(bagAttrs.getBagAttribute(oid))); attrSet = true; kName.add(new DERSequence(kSeq)); } } if (!attrSet) { // // set a default friendly name (from the key id) and local id // ASN1EncodableVector kSeq = new ASN1EncodableVector(); Certificate ct = engineGetCertificate(name); kSeq.add(pkcs_9_at_localKeyId); kSeq.add(new DERSet(createSubjectKeyId(ct.getPublicKey()))); kName.add(new DERSequence(kSeq)); kSeq = new ASN1EncodableVector(); kSeq.add(pkcs_9_at_friendlyName); kSeq.add(new DERSet(new DERBMPString(name))); kName.add(new DERSequence(kSeq)); } SafeBag kBag = new SafeBag(pkcs8ShroudedKeyBag, kInfo.toASN1Primitive(), new DERSet(kName)); keyS.add(kBag); } byte[] keySEncoded = new DERSequence(keyS).getEncoded(ASN1Encoding.DER); BEROctetString keyString = new BEROctetString(keySEncoded); // // certificate processing // byte[] cSalt = new byte[SALT_SIZE]; random.nextBytes(cSalt); ASN1EncodableVector certSeq = new ASN1EncodableVector(); PKCS12PBEParams cParams = new PKCS12PBEParams(cSalt, MIN_ITERATIONS); AlgorithmIdentifier cAlgId = new AlgorithmIdentifier(certAlgorithm, cParams.toASN1Primitive()); Hashtable doneCerts = new Hashtable(); Enumeration cs = keys.keys(); while (cs.hasMoreElements()) { try { String name = (String)cs.nextElement(); Certificate cert = engineGetCertificate(name); boolean cAttrSet = false; CertBag cBag = new CertBag( x509Certificate, new DEROctetString(cert.getEncoded())); ASN1EncodableVector fName = new ASN1EncodableVector(); if (cert instanceof PKCS12BagAttributeCarrier) { PKCS12BagAttributeCarrier bagAttrs = (PKCS12BagAttributeCarrier)cert; // // make sure we are using the local alias on store // DERBMPString nm = (DERBMPString)bagAttrs.getBagAttribute(pkcs_9_at_friendlyName); if (nm == null || !nm.getString().equals(name)) { bagAttrs.setBagAttribute(pkcs_9_at_friendlyName, new DERBMPString(name)); } // // make sure we have a local key-id // if (bagAttrs.getBagAttribute(pkcs_9_at_localKeyId) == null) { bagAttrs.setBagAttribute(pkcs_9_at_localKeyId, createSubjectKeyId(cert.getPublicKey())); } Enumeration e = bagAttrs.getBagAttributeKeys(); while (e.hasMoreElements()) { ASN1ObjectIdentifier oid = (ASN1ObjectIdentifier)e.nextElement(); ASN1EncodableVector fSeq = new ASN1EncodableVector(); fSeq.add(oid); fSeq.add(new DERSet(bagAttrs.getBagAttribute(oid))); fName.add(new DERSequence(fSeq)); cAttrSet = true; } } if (!cAttrSet) { ASN1EncodableVector fSeq = new ASN1EncodableVector(); fSeq.add(pkcs_9_at_localKeyId); fSeq.add(new DERSet(createSubjectKeyId(cert.getPublicKey()))); fName.add(new DERSequence(fSeq)); fSeq = new ASN1EncodableVector(); fSeq.add(pkcs_9_at_friendlyName); fSeq.add(new DERSet(new DERBMPString(name))); fName.add(new DERSequence(fSeq)); } SafeBag sBag = new SafeBag(certBag, cBag.toASN1Primitive(), new DERSet(fName)); certSeq.add(sBag); doneCerts.put(cert, cert); } catch (CertificateEncodingException e) { throw new IOException("Error encoding certificate: " + e.toString()); } } cs = certs.keys(); while (cs.hasMoreElements()) { try { String certId = (String)cs.nextElement(); Certificate cert = (Certificate)certs.get(certId); boolean cAttrSet = false; if (keys.get(certId) != null) { continue; } CertBag cBag = new CertBag( x509Certificate, new DEROctetString(cert.getEncoded())); ASN1EncodableVector fName = new ASN1EncodableVector(); if (cert instanceof PKCS12BagAttributeCarrier) { PKCS12BagAttributeCarrier bagAttrs = (PKCS12BagAttributeCarrier)cert; // // make sure we are using the local alias on store // DERBMPString nm = (DERBMPString)bagAttrs.getBagAttribute(pkcs_9_at_friendlyName); if (nm == null || !nm.getString().equals(certId)) { bagAttrs.setBagAttribute(pkcs_9_at_friendlyName, new DERBMPString(certId)); } Enumeration e = bagAttrs.getBagAttributeKeys(); while (e.hasMoreElements()) { ASN1ObjectIdentifier oid = (ASN1ObjectIdentifier)e.nextElement(); // a certificate not immediately linked to a key doesn't require // a localKeyID and will confuse some PKCS12 implementations. // // If we find one, we'll prune it out. if (oid.equals(PKCSObjectIdentifiers.pkcs_9_at_localKeyId)) { continue; } ASN1EncodableVector fSeq = new ASN1EncodableVector(); fSeq.add(oid); fSeq.add(new DERSet(bagAttrs.getBagAttribute(oid))); fName.add(new DERSequence(fSeq)); cAttrSet = true; } } if (!cAttrSet) { ASN1EncodableVector fSeq = new ASN1EncodableVector(); fSeq.add(pkcs_9_at_friendlyName); fSeq.add(new DERSet(new DERBMPString(certId))); fName.add(new DERSequence(fSeq)); } SafeBag sBag = new SafeBag(certBag, cBag.toASN1Primitive(), new DERSet(fName)); certSeq.add(sBag); doneCerts.put(cert, cert); } catch (CertificateEncodingException e) { throw new IOException("Error encoding certificate: " + e.toString()); } } cs = chainCerts.keys(); while (cs.hasMoreElements()) { try { CertId certId = (CertId)cs.nextElement(); Certificate cert = (Certificate)chainCerts.get(certId); if (doneCerts.get(cert) != null) { continue; } CertBag cBag = new CertBag( x509Certificate, new DEROctetString(cert.getEncoded())); ASN1EncodableVector fName = new ASN1EncodableVector(); if (cert instanceof PKCS12BagAttributeCarrier) { PKCS12BagAttributeCarrier bagAttrs = (PKCS12BagAttributeCarrier)cert; Enumeration e = bagAttrs.getBagAttributeKeys(); while (e.hasMoreElements()) { ASN1ObjectIdentifier oid = (ASN1ObjectIdentifier)e.nextElement(); // a certificate not immediately linked to a key doesn't require // a localKeyID and will confuse some PKCS12 implementations. // // If we find one, we'll prune it out. if (oid.equals(PKCSObjectIdentifiers.pkcs_9_at_localKeyId)) { continue; } ASN1EncodableVector fSeq = new ASN1EncodableVector(); fSeq.add(oid); fSeq.add(new DERSet(bagAttrs.getBagAttribute(oid))); fName.add(new DERSequence(fSeq)); } } SafeBag sBag = new SafeBag(certBag, cBag.toASN1Primitive(), new DERSet(fName)); certSeq.add(sBag); } catch (CertificateEncodingException e) { throw new IOException("Error encoding certificate: " + e.toString()); } } byte[] certSeqEncoded = new DERSequence(certSeq).getEncoded(ASN1Encoding.DER); byte[] certBytes = cryptData(true, cAlgId, password, false, certSeqEncoded); EncryptedData cInfo = new EncryptedData(data, cAlgId, new BEROctetString(certBytes)); ContentInfo[] info = new ContentInfo[] { new ContentInfo(data, keyString), new ContentInfo(encryptedData, cInfo.toASN1Primitive()) }; AuthenticatedSafe auth = new AuthenticatedSafe(info); ByteArrayOutputStream bOut = new ByteArrayOutputStream(); DEROutputStream asn1Out; if (useDEREncoding) { asn1Out = new DEROutputStream(bOut); } else { asn1Out = new BEROutputStream(bOut); } asn1Out.writeObject(auth); byte[] pkg = bOut.toByteArray(); ContentInfo mainInfo = new ContentInfo(data, new BEROctetString(pkg)); // // create the mac // byte[] mSalt = new byte[20]; int itCount = MIN_ITERATIONS; random.nextBytes(mSalt); byte[] data = ((ASN1OctetString)mainInfo.getContent()).getOctets(); MacData mData; try { byte[] res = calculatePbeMac(id_SHA1, mSalt, itCount, password, false, data); AlgorithmIdentifier algId = new AlgorithmIdentifier(id_SHA1, DERNull.INSTANCE); DigestInfo dInfo = new DigestInfo(algId, res); mData = new MacData(dInfo, mSalt, itCount); } catch (Exception e) { throw new IOException("error constructing MAC: " + e.toString()); } // // output the Pfx // Pfx pfx = new Pfx(mainInfo, mData); if (useDEREncoding) { asn1Out = new DEROutputStream(stream); } else { asn1Out = new BEROutputStream(stream); } asn1Out.writeObject(pfx); } private static byte[] calculatePbeMac( ASN1ObjectIdentifier oid, byte[] salt, int itCount, char[] password, boolean wrongPkcs12Zero, byte[] data) throws Exception { SecretKeyFactory keyFact = SecretKeyFactory.getInstance(oid.getId(), bcProvider); PBEParameterSpec defParams = new PBEParameterSpec(salt, itCount); PBEKeySpec pbeSpec = new PBEKeySpec(password); BCPBEKey key = (BCPBEKey)keyFact.generateSecret(pbeSpec); key.setTryWrongPKCS12Zero(wrongPkcs12Zero); Mac mac = Mac.getInstance(oid.getId(), bcProvider); mac.init(key, defParams); mac.update(data); return mac.doFinal(); } public static class BCPKCS12KeyStore extends PKCS12KeyStoreSpi { public BCPKCS12KeyStore() { super(bcProvider, pbeWithSHAAnd3_KeyTripleDES_CBC, pbeWithSHAAnd40BitRC2_CBC); } } public static class BCPKCS12KeyStore3DES extends PKCS12KeyStoreSpi { public BCPKCS12KeyStore3DES() { super(bcProvider, pbeWithSHAAnd3_KeyTripleDES_CBC, pbeWithSHAAnd3_KeyTripleDES_CBC); } } public static class DefPKCS12KeyStore extends PKCS12KeyStoreSpi { public DefPKCS12KeyStore() { super(null, pbeWithSHAAnd3_KeyTripleDES_CBC, pbeWithSHAAnd40BitRC2_CBC); } } public static class DefPKCS12KeyStore3DES extends PKCS12KeyStoreSpi { public DefPKCS12KeyStore3DES() { super(null, pbeWithSHAAnd3_KeyTripleDES_CBC, pbeWithSHAAnd3_KeyTripleDES_CBC); } } private static class IgnoresCaseHashtable { private Hashtable orig = new Hashtable(); private Hashtable keys = new Hashtable(); public void put(String key, Object value) { String lower = (key == null) ? null : Strings.toLowerCase(key); String k = (String)keys.get(lower); if (k != null) { orig.remove(k); } keys.put(lower, key); orig.put(key, value); } public Enumeration keys() { return orig.keys(); } public Object remove(String alias) { String k = (String)keys.remove(alias == null ? null : Strings.toLowerCase(alias)); if (k == null) { return null; } return orig.remove(k); } public Object get(String alias) { String k = (String)keys.get(alias == null ? null : Strings.toLowerCase(alias)); if (k == null) { return null; } return orig.get(k); } public Enumeration elements() { return orig.elements(); } } } bouncycastle-1.49.orig/jdk1.4/org/bouncycastle/jce/0000755000175000017500000000000012152033550021443 5ustar ebourgebourgbouncycastle-1.49.orig/jdk1.4/org/bouncycastle/jce/provider/0000755000175000017500000000000012152033550023275 5ustar ebourgebourgbouncycastle-1.49.orig/jdk1.4/org/bouncycastle/jce/provider/BouncyCastleProviderConfiguration.java0000644000175000017500000001226012070736713033011 0ustar ebourgebourgpackage org.bouncycastle.jce.provider; import java.security.Permission; import javax.crypto.spec.DHParameterSpec; import org.bouncycastle.jcajce.provider.config.ConfigurableProvider; import org.bouncycastle.jcajce.provider.config.ProviderConfiguration; import org.bouncycastle.jcajce.provider.config.ProviderConfigurationPermission; import org.bouncycastle.jce.spec.ECParameterSpec; class BouncyCastleProviderConfiguration implements ProviderConfiguration { private static Permission BC_EC_LOCAL_PERMISSION = new ProviderConfigurationPermission( BouncyCastleProvider.PROVIDER_NAME, ConfigurableProvider.THREAD_LOCAL_EC_IMPLICITLY_CA); private static Permission BC_EC_PERMISSION = new ProviderConfigurationPermission( BouncyCastleProvider.PROVIDER_NAME, ConfigurableProvider.EC_IMPLICITLY_CA); private static Permission BC_DH_LOCAL_PERMISSION = new ProviderConfigurationPermission( BouncyCastleProvider.PROVIDER_NAME, ConfigurableProvider.THREAD_LOCAL_DH_DEFAULT_PARAMS); private static Permission BC_DH_PERMISSION = new ProviderConfigurationPermission( BouncyCastleProvider.PROVIDER_NAME, ConfigurableProvider.DH_DEFAULT_PARAMS); private ThreadLocal ecThreadSpec = new ThreadLocal(); private ThreadLocal dhThreadSpec = new ThreadLocal(); private volatile ECParameterSpec ecImplicitCaParams; private volatile Object dhDefaultParams; void setParameter(String parameterName, Object parameter) { SecurityManager securityManager = System.getSecurityManager(); if (parameterName.equals(ConfigurableProvider.THREAD_LOCAL_EC_IMPLICITLY_CA)) { ECParameterSpec curveSpec; if (securityManager != null) { securityManager.checkPermission(BC_EC_LOCAL_PERMISSION); } if (parameter instanceof ECParameterSpec || parameter == null) { curveSpec = (ECParameterSpec)parameter; } else { throw new IllegalArgumentException("not a valid ECParameterSpec"); } if (curveSpec == null) { ecThreadSpec.set(null); } else { ecThreadSpec.set(curveSpec); } } else if (parameterName.equals(ConfigurableProvider.EC_IMPLICITLY_CA)) { if (securityManager != null) { securityManager.checkPermission(BC_EC_PERMISSION); } if (parameter instanceof ECParameterSpec || parameter == null) { ecImplicitCaParams = (ECParameterSpec)parameter; } else // assume java.security.spec { throw new IllegalArgumentException("not a valid ECParameterSpec"); } } else if (parameterName.equals(ConfigurableProvider.THREAD_LOCAL_DH_DEFAULT_PARAMS)) { Object dhSpec; if (securityManager != null) { securityManager.checkPermission(BC_DH_LOCAL_PERMISSION); } if (parameter instanceof DHParameterSpec || parameter instanceof DHParameterSpec[] || parameter == null) { dhSpec = parameter; } else { throw new IllegalArgumentException("not a valid DHParameterSpec"); } if (dhSpec == null) { dhThreadSpec.set(null); } else { dhThreadSpec.set(dhSpec); } } else if (parameterName.equals(ConfigurableProvider.DH_DEFAULT_PARAMS)) { if (securityManager != null) { securityManager.checkPermission(BC_DH_PERMISSION); } if (parameter instanceof DHParameterSpec || parameter instanceof DHParameterSpec[] || parameter == null) { dhDefaultParams = parameter; } else { throw new IllegalArgumentException("not a valid DHParameterSpec or DHParameterSpec[]"); } } } public ECParameterSpec getEcImplicitlyCa() { ECParameterSpec spec = (ECParameterSpec)ecThreadSpec.get(); if (spec != null) { return spec; } return ecImplicitCaParams; } public DHParameterSpec getDHDefaultParameters(int keySize) { Object params = dhThreadSpec.get(); if (params == null) { params = dhDefaultParams; } if (params instanceof DHParameterSpec) { DHParameterSpec spec = (DHParameterSpec)params; if (spec.getP().bitLength() == keySize) { return spec; } } else if (params instanceof DHParameterSpec[]) { DHParameterSpec[] specs = (DHParameterSpec[])params; for (int i = 0; i != specs.length; i++) { if (specs[i].getP().bitLength() == keySize) { return specs[i]; } } } return null; } } bouncycastle-1.49.orig/jdk1.4/org/bouncycastle/jce/provider/CertPathValidatorUtilities.java0000644000175000017500000014240512103623011031413 0ustar ebourgebourgpackage org.bouncycastle.jce.provider; import java.io.ByteArrayOutputStream; import java.io.IOException; import java.math.BigInteger; import java.security.GeneralSecurityException; import java.security.KeyFactory; import java.security.PublicKey; import java.security.cert.CRLException; import java.security.cert.CertPath; import java.security.cert.CertPathValidatorException; import java.security.cert.CertStore; import java.security.cert.CertStoreException; import java.security.cert.Certificate; import java.security.cert.CertificateParsingException; import java.security.cert.PKIXParameters; import java.security.cert.PolicyQualifierInfo; import java.security.cert.TrustAnchor; import java.security.cert.X509CRL; import java.security.cert.X509CRLEntry; import java.security.cert.X509CRLSelector; import java.security.cert.X509CertSelector; import java.security.cert.X509Certificate; import java.security.interfaces.DSAParams; import java.security.interfaces.DSAPublicKey; import java.security.spec.DSAPublicKeySpec; import java.text.ParseException; import java.util.ArrayList; import java.util.Collection; import java.util.Date; import java.util.Enumeration; import java.util.HashSet; import java.util.Iterator; import java.util.List; import java.util.Map; import java.util.Set; import javax.security.auth.x500.X500Principal; import org.bouncycastle.asn1.ASN1Encodable; import org.bouncycastle.asn1.ASN1InputStream; import org.bouncycastle.asn1.ASN1Integer; import org.bouncycastle.asn1.ASN1OctetString; import org.bouncycastle.asn1.ASN1OutputStream; import org.bouncycastle.asn1.ASN1Primitive; import org.bouncycastle.asn1.ASN1Sequence; import org.bouncycastle.asn1.DEREnumerated; import org.bouncycastle.asn1.DERGeneralizedTime; import org.bouncycastle.asn1.DERIA5String; import org.bouncycastle.asn1.DERObjectIdentifier; import org.bouncycastle.asn1.DERSequence; import org.bouncycastle.asn1.isismtt.ISISMTTObjectIdentifiers; import org.bouncycastle.asn1.x509.AlgorithmIdentifier; import org.bouncycastle.asn1.x509.CRLDistPoint; import org.bouncycastle.asn1.x509.CRLReason; import org.bouncycastle.asn1.x509.CertificateList; import org.bouncycastle.asn1.x509.DistributionPoint; import org.bouncycastle.asn1.x509.DistributionPointName; import org.bouncycastle.asn1.x509.GeneralName; import org.bouncycastle.asn1.x509.GeneralNames; import org.bouncycastle.asn1.x509.PolicyInformation; import org.bouncycastle.asn1.x509.SubjectPublicKeyInfo; import org.bouncycastle.asn1.x509.X509Extension; import org.bouncycastle.asn1.x509.X509Extensions; import org.bouncycastle.jce.X509LDAPCertStoreParameters; import org.bouncycastle.jce.exception.ExtCertPathValidatorException; import org.bouncycastle.util.Selector; import org.bouncycastle.util.StoreException; import org.bouncycastle.util.Integers; import org.bouncycastle.x509.ExtendedPKIXBuilderParameters; import org.bouncycastle.x509.ExtendedPKIXParameters; import org.bouncycastle.x509.X509AttributeCertStoreSelector; import org.bouncycastle.x509.X509AttributeCertificate; import org.bouncycastle.x509.X509CRLStoreSelector; import org.bouncycastle.x509.X509CertStoreSelector; import org.bouncycastle.x509.X509Store; public class CertPathValidatorUtilities { protected static final PKIXCRLUtil CRL_UTIL = new PKIXCRLUtil(); protected static final String CERTIFICATE_POLICIES = X509Extensions.CertificatePolicies.getId(); protected static final String BASIC_CONSTRAINTS = X509Extensions.BasicConstraints.getId(); protected static final String POLICY_MAPPINGS = X509Extensions.PolicyMappings.getId(); protected static final String SUBJECT_ALTERNATIVE_NAME = X509Extensions.SubjectAlternativeName.getId(); protected static final String NAME_CONSTRAINTS = X509Extensions.NameConstraints.getId(); protected static final String KEY_USAGE = X509Extensions.KeyUsage.getId(); protected static final String INHIBIT_ANY_POLICY = X509Extensions.InhibitAnyPolicy.getId(); protected static final String ISSUING_DISTRIBUTION_POINT = X509Extensions.IssuingDistributionPoint.getId(); protected static final String DELTA_CRL_INDICATOR = X509Extensions.DeltaCRLIndicator.getId(); protected static final String POLICY_CONSTRAINTS = X509Extensions.PolicyConstraints.getId(); protected static final String FRESHEST_CRL = X509Extensions.FreshestCRL.getId(); protected static final String CRL_DISTRIBUTION_POINTS = X509Extensions.CRLDistributionPoints.getId(); protected static final String AUTHORITY_KEY_IDENTIFIER = X509Extensions.AuthorityKeyIdentifier.getId(); protected static final String ANY_POLICY = "2.5.29.32.0"; protected static final String CRL_NUMBER = X509Extensions.CRLNumber.getId(); /* * key usage bits */ protected static final int KEY_CERT_SIGN = 5; protected static final int CRL_SIGN = 6; protected static final String[] crlReasons = new String[]{ "unspecified", "keyCompromise", "cACompromise", "affiliationChanged", "superseded", "cessationOfOperation", "certificateHold", "unknown", "removeFromCRL", "privilegeWithdrawn", "aACompromise"}; /** * Search the given Set of TrustAnchor's for one that is the * issuer of the given X509 certificate. Uses the default provider * for signature verification. * * @param cert the X509 certificate * @param trustAnchors a Set of TrustAnchor's * @return the TrustAnchor object if found or * null if not. * @throws AnnotatedException if a TrustAnchor was found but the signature verification * on the given certificate has thrown an exception. */ protected static TrustAnchor findTrustAnchor( X509Certificate cert, Set trustAnchors) throws AnnotatedException { return findTrustAnchor(cert, trustAnchors, null); } /** * Search the given Set of TrustAnchor's for one that is the * issuer of the given X509 certificate. Uses the specified * provider for signature verification, or the default provider * if null. * * @param cert the X509 certificate * @param trustAnchors a Set of TrustAnchor's * @param sigProvider the provider to use for signature verification * @return the TrustAnchor object if found or * null if not. * @throws AnnotatedException if a TrustAnchor was found but the signature verification * on the given certificate has thrown an exception. */ protected static TrustAnchor findTrustAnchor( X509Certificate cert, Set trustAnchors, String sigProvider) throws AnnotatedException { TrustAnchor trust = null; PublicKey trustPublicKey = null; Exception invalidKeyEx = null; X509CertSelector certSelectX509 = new X509CertSelector(); X500Principal certIssuer = getEncodedIssuerPrincipal(cert); try { certSelectX509.setSubject(certIssuer.getEncoded()); } catch (IOException ex) { throw new AnnotatedException("Cannot set subject search criteria for trust anchor.", ex); } Iterator iter = trustAnchors.iterator(); while (iter.hasNext() && trust == null) { trust = (TrustAnchor)iter.next(); if (trust.getTrustedCert() != null) { if (certSelectX509.match(trust.getTrustedCert())) { trustPublicKey = trust.getTrustedCert().getPublicKey(); } else { trust = null; } } else if (trust.getCAName() != null && trust.getCAPublicKey() != null) { try { X500Principal caName = new X500Principal(trust.getCAName()); if (certIssuer.equals(caName)) { trustPublicKey = trust.getCAPublicKey(); } else { trust = null; } } catch (IllegalArgumentException ex) { trust = null; } } else { trust = null; } if (trustPublicKey != null) { try { verifyX509Certificate(cert, trustPublicKey, sigProvider); } catch (Exception ex) { invalidKeyEx = ex; trust = null; trustPublicKey = null; } } } if (trust == null && invalidKeyEx != null) { throw new AnnotatedException("TrustAnchor found but certificate validation failed.", invalidKeyEx); } return trust; } protected static void addAdditionalStoresFromAltNames( X509Certificate cert, ExtendedPKIXParameters pkixParams) throws CertificateParsingException { // if in the IssuerAltName extension an URI // is given, add an additinal X.509 store if (cert.getIssuerAlternativeNames() != null) { Iterator it = cert.getIssuerAlternativeNames().iterator(); while (it.hasNext()) { // look for URI List list = (List)it.next(); if (list.get(0).equals(Integers.valueOf(GeneralName.uniformResourceIdentifier))) { // found String temp = (String)list.get(1); CertPathValidatorUtilities.addAdditionalStoreFromLocation(temp, pkixParams); } } } } /** * Returns the issuer of an attribute certificate or certificate. * * @param cert The attribute certificate or certificate. * @return The issuer as X500Principal. */ protected static X500Principal getEncodedIssuerPrincipal( Object cert) { if (cert instanceof X509Certificate) { return ((X509Certificate)cert).getIssuerX500Principal(); } else { return (X500Principal)((X509AttributeCertificate)cert).getIssuer().getPrincipals()[0]; } } protected static Date getValidDate(PKIXParameters paramsPKIX) { Date validDate = paramsPKIX.getDate(); if (validDate == null) { validDate = new Date(); } return validDate; } protected static X500Principal getSubjectPrincipal(X509Certificate cert) { return cert.getSubjectX500Principal(); } protected static boolean isSelfIssued(X509Certificate cert) { return cert.getSubjectDN().equals(cert.getIssuerDN()); } /** * Extract the value of the given extension, if it exists. * * @param ext The extension object. * @param oid The object identifier to obtain. * @throws AnnotatedException if the extension cannot be read. */ protected static ASN1Primitive getExtensionValue( java.security.cert.X509Extension ext, String oid) throws AnnotatedException { byte[] bytes = ext.getExtensionValue(oid); if (bytes == null) { return null; } return getObject(oid, bytes); } private static ASN1Primitive getObject( String oid, byte[] ext) throws AnnotatedException { try { ASN1InputStream aIn = new ASN1InputStream(ext); ASN1OctetString octs = (ASN1OctetString)aIn.readObject(); aIn = new ASN1InputStream(octs.getOctets()); return aIn.readObject(); } catch (Exception e) { throw new AnnotatedException("exception processing extension " + oid, e); } } protected static X500Principal getIssuerPrincipal(X509CRL crl) { return crl.getIssuerX500Principal(); } protected static AlgorithmIdentifier getAlgorithmIdentifier( PublicKey key) throws CertPathValidatorException { try { ASN1InputStream aIn = new ASN1InputStream(key.getEncoded()); SubjectPublicKeyInfo info = SubjectPublicKeyInfo.getInstance(aIn.readObject()); return info.getAlgorithmId(); } catch (Exception e) { throw new ExtCertPathValidatorException("Subject public key cannot be decoded.", e); } } // crl checking // // policy checking // protected static final Set getQualifierSet(ASN1Sequence qualifiers) throws CertPathValidatorException { Set pq = new HashSet(); if (qualifiers == null) { return pq; } ByteArrayOutputStream bOut = new ByteArrayOutputStream(); ASN1OutputStream aOut = new ASN1OutputStream(bOut); Enumeration e = qualifiers.getObjects(); while (e.hasMoreElements()) { try { aOut.writeObject((ASN1Encodable)e.nextElement()); pq.add(new PolicyQualifierInfo(bOut.toByteArray())); } catch (IOException ex) { throw new ExtCertPathValidatorException("Policy qualifier info cannot be decoded.", ex); } bOut.reset(); } return pq; } protected static PKIXPolicyNode removePolicyNode( PKIXPolicyNode validPolicyTree, List[] policyNodes, PKIXPolicyNode _node) { PKIXPolicyNode _parent = (PKIXPolicyNode)_node.getParent(); if (validPolicyTree == null) { return null; } if (_parent == null) { for (int j = 0; j < policyNodes.length; j++) { policyNodes[j] = new ArrayList(); } return null; } else { _parent.removeChild(_node); removePolicyNodeRecurse(policyNodes, _node); return validPolicyTree; } } private static void removePolicyNodeRecurse( List[] policyNodes, PKIXPolicyNode _node) { policyNodes[_node.getDepth()].remove(_node); if (_node.hasChildren()) { Iterator _iter = _node.getChildren(); while (_iter.hasNext()) { PKIXPolicyNode _child = (PKIXPolicyNode)_iter.next(); removePolicyNodeRecurse(policyNodes, _child); } } } protected static boolean processCertD1i( int index, List[] policyNodes, DERObjectIdentifier pOid, Set pq) { List policyNodeVec = policyNodes[index - 1]; for (int j = 0; j < policyNodeVec.size(); j++) { PKIXPolicyNode node = (PKIXPolicyNode)policyNodeVec.get(j); Set expectedPolicies = node.getExpectedPolicies(); if (expectedPolicies.contains(pOid.getId())) { Set childExpectedPolicies = new HashSet(); childExpectedPolicies.add(pOid.getId()); PKIXPolicyNode child = new PKIXPolicyNode(new ArrayList(), index, childExpectedPolicies, node, pq, pOid.getId(), false); node.addChild(child); policyNodes[index].add(child); return true; } } return false; } protected static void processCertD1ii( int index, List[] policyNodes, DERObjectIdentifier _poid, Set _pq) { List policyNodeVec = policyNodes[index - 1]; for (int j = 0; j < policyNodeVec.size(); j++) { PKIXPolicyNode _node = (PKIXPolicyNode)policyNodeVec.get(j); if (ANY_POLICY.equals(_node.getValidPolicy())) { Set _childExpectedPolicies = new HashSet(); _childExpectedPolicies.add(_poid.getId()); PKIXPolicyNode _child = new PKIXPolicyNode(new ArrayList(), index, _childExpectedPolicies, _node, _pq, _poid.getId(), false); _node.addChild(_child); policyNodes[index].add(_child); return; } } } protected static void prepareNextCertB1( int i, List[] policyNodes, String id_p, Map m_idp, X509Certificate cert ) throws AnnotatedException, CertPathValidatorException { boolean idp_found = false; Iterator nodes_i = policyNodes[i].iterator(); while (nodes_i.hasNext()) { PKIXPolicyNode node = (PKIXPolicyNode)nodes_i.next(); if (node.getValidPolicy().equals(id_p)) { idp_found = true; node.expectedPolicies = (Set)m_idp.get(id_p); break; } } if (!idp_found) { nodes_i = policyNodes[i].iterator(); while (nodes_i.hasNext()) { PKIXPolicyNode node = (PKIXPolicyNode)nodes_i.next(); if (ANY_POLICY.equals(node.getValidPolicy())) { Set pq = null; ASN1Sequence policies = null; try { policies = DERSequence.getInstance(getExtensionValue(cert, CERTIFICATE_POLICIES)); } catch (Exception e) { throw new AnnotatedException("Certificate policies cannot be decoded.", e); } Enumeration e = policies.getObjects(); while (e.hasMoreElements()) { PolicyInformation pinfo = null; try { pinfo = PolicyInformation.getInstance(e.nextElement()); } catch (Exception ex) { throw new AnnotatedException("Policy information cannot be decoded.", ex); } if (ANY_POLICY.equals(pinfo.getPolicyIdentifier().getId())) { try { pq = getQualifierSet(pinfo.getPolicyQualifiers()); } catch (CertPathValidatorException ex) { throw new ExtCertPathValidatorException( "Policy qualifier info set could not be built.", ex); } break; } } boolean ci = false; if (cert.getCriticalExtensionOIDs() != null) { ci = cert.getCriticalExtensionOIDs().contains(CERTIFICATE_POLICIES); } PKIXPolicyNode p_node = (PKIXPolicyNode)node.getParent(); if (ANY_POLICY.equals(p_node.getValidPolicy())) { PKIXPolicyNode c_node = new PKIXPolicyNode( new ArrayList(), i, (Set)m_idp.get(id_p), p_node, pq, id_p, ci); p_node.addChild(c_node); policyNodes[i].add(c_node); } break; } } } } protected static PKIXPolicyNode prepareNextCertB2( int i, List[] policyNodes, String id_p, PKIXPolicyNode validPolicyTree) { Iterator nodes_i = policyNodes[i].iterator(); while (nodes_i.hasNext()) { PKIXPolicyNode node = (PKIXPolicyNode)nodes_i.next(); if (node.getValidPolicy().equals(id_p)) { PKIXPolicyNode p_node = (PKIXPolicyNode)node.getParent(); p_node.removeChild(node); nodes_i.remove(); for (int k = (i - 1); k >= 0; k--) { List nodes = policyNodes[k]; for (int l = 0; l < nodes.size(); l++) { PKIXPolicyNode node2 = (PKIXPolicyNode)nodes.get(l); if (!node2.hasChildren()) { validPolicyTree = removePolicyNode(validPolicyTree, policyNodes, node2); if (validPolicyTree == null) { break; } } } } } } return validPolicyTree; } protected static boolean isAnyPolicy( Set policySet) { return policySet == null || policySet.contains(ANY_POLICY) || policySet.isEmpty(); } protected static void addAdditionalStoreFromLocation(String location, ExtendedPKIXParameters pkixParams) { if (pkixParams.isAdditionalLocationsEnabled()) { try { if (location.startsWith("ldap://")) { // ldap://directory.d-trust.net/CN=D-TRUST // Qualified CA 2003 1:PN,O=D-Trust GmbH,C=DE // skip "ldap://" location = location.substring(7); // after first / baseDN starts String base = null; String url = null; if (location.indexOf("/") != -1) { base = location.substring(location.indexOf("/")); // URL url = "ldap://" + location.substring(0, location.indexOf("/")); } else { url = "ldap://" + location; } // use all purpose parameters X509LDAPCertStoreParameters params = new X509LDAPCertStoreParameters.Builder( url, base).build(); pkixParams.addAdditionalStore(X509Store.getInstance( "CERTIFICATE/LDAP", params, BouncyCastleProvider.PROVIDER_NAME)); pkixParams.addAdditionalStore(X509Store.getInstance( "CRL/LDAP", params, BouncyCastleProvider.PROVIDER_NAME)); pkixParams.addAdditionalStore(X509Store.getInstance( "ATTRIBUTECERTIFICATE/LDAP", params, BouncyCastleProvider.PROVIDER_NAME)); pkixParams.addAdditionalStore(X509Store.getInstance( "CERTIFICATEPAIR/LDAP", params, BouncyCastleProvider.PROVIDER_NAME)); } } catch (Exception e) { // cannot happen throw new RuntimeException("Exception adding X.509 stores."); } } } /** * Return a Collection of all certificates or attribute certificates found * in the X509Store's that are matching the certSelect criteriums. * * @param certSelect a {@link Selector} object that will be used to select * the certificates * @param certStores a List containing only {@link X509Store} objects. These * are used to search for certificates. * @return a Collection of all found {@link X509Certificate} or * {@link org.bouncycastle.x509.X509AttributeCertificate} objects. * May be empty but never null. */ protected static Collection findCertificates(X509CertStoreSelector certSelect, List certStores) throws AnnotatedException { Set certs = new HashSet(); Iterator iter = certStores.iterator(); while (iter.hasNext()) { Object obj = iter.next(); if (obj instanceof X509Store) { X509Store certStore = (X509Store)obj; try { certs.addAll(certStore.getMatches(certSelect)); } catch (StoreException e) { throw new AnnotatedException( "Problem while picking certificates from X.509 store.", e); } } else { CertStore certStore = (CertStore)obj; try { certs.addAll(certStore.getCertificates(certSelect)); } catch (CertStoreException e) { throw new AnnotatedException( "Problem while picking certificates from certificate store.", e); } } } return certs; } protected static Collection findCertificates(X509AttributeCertStoreSelector certSelect, List certStores) throws AnnotatedException { Set certs = new HashSet(); Iterator iter = certStores.iterator(); while (iter.hasNext()) { Object obj = iter.next(); if (obj instanceof X509Store) { X509Store certStore = (X509Store)obj; try { certs.addAll(certStore.getMatches(certSelect)); } catch (StoreException e) { throw new AnnotatedException( "Problem while picking certificates from X.509 store.", e); } } } return certs; } protected static void addAdditionalStoresFromCRLDistributionPoint( CRLDistPoint crldp, ExtendedPKIXParameters pkixParams) throws AnnotatedException { if (crldp != null) { DistributionPoint dps[] = null; try { dps = crldp.getDistributionPoints(); } catch (Exception e) { throw new AnnotatedException( "Distribution points could not be read.", e); } for (int i = 0; i < dps.length; i++) { DistributionPointName dpn = dps[i].getDistributionPoint(); // look for URIs in fullName if (dpn != null) { if (dpn.getType() == DistributionPointName.FULL_NAME) { GeneralName[] genNames = GeneralNames.getInstance( dpn.getName()).getNames(); // look for an URI for (int j = 0; j < genNames.length; j++) { if (genNames[j].getTagNo() == GeneralName.uniformResourceIdentifier) { String location = DERIA5String.getInstance( genNames[j].getName()).getString(); CertPathValidatorUtilities .addAdditionalStoreFromLocation(location, pkixParams); } } } } } } } /** * Add the CRL issuers from the cRLIssuer field of the distribution point or * from the certificate if not given to the issuer criterion of the * selector. *

* The issuerPrincipals are a collection with a single * X500Principal for X509Certificates. For * {@link X509AttributeCertificate}s the issuer may contain more than one * X500Principal. * * @param dp The distribution point. * @param issuerPrincipals The issuers of the certificate or attribute * certificate which contains the distribution point. * @param selector The CRL selector. * @param pkixParams The PKIX parameters containing the cert stores. * @throws AnnotatedException if an exception occurs while processing. * @throws ClassCastException if issuerPrincipals does not * contain only X500Principals. */ protected static void getCRLIssuersFromDistributionPoint( DistributionPoint dp, Collection issuerPrincipals, X509CRLSelector selector, ExtendedPKIXParameters pkixParams) throws AnnotatedException { List issuers = new ArrayList(); // indirect CRL if (dp.getCRLIssuer() != null) { GeneralName genNames[] = dp.getCRLIssuer().getNames(); // look for a DN for (int j = 0; j < genNames.length; j++) { if (genNames[j].getTagNo() == GeneralName.directoryName) { try { issuers.add(new X500Principal(genNames[j].getName() .toASN1Primitive().getEncoded())); } catch (IOException e) { throw new AnnotatedException( "CRL issuer information from distribution point cannot be decoded.", e); } } } } else { /* * certificate issuer is CRL issuer, distributionPoint field MUST be * present. */ if (dp.getDistributionPoint() == null) { throw new AnnotatedException( "CRL issuer is omitted from distribution point but no distributionPoint field present."); } // add and check issuer principals for (Iterator it = issuerPrincipals.iterator(); it.hasNext(); ) { issuers.add((X500Principal)it.next()); } } // TODO: is not found although this should correctly add the rel name. selector of Sun is buggy here or PKI test case is invalid // distributionPoint // if (dp.getDistributionPoint() != null) // { // // look for nameRelativeToCRLIssuer // if (dp.getDistributionPoint().getType() == DistributionPointName.NAME_RELATIVE_TO_CRL_ISSUER) // { // // append fragment to issuer, only one // // issuer can be there, if this is given // if (issuers.size() != 1) // { // throw new AnnotatedException( // "nameRelativeToCRLIssuer field is given but more than one CRL issuer is given."); // } // ASN1Encodable relName = dp.getDistributionPoint().getName(); // Iterator it = issuers.iterator(); // List issuersTemp = new ArrayList(issuers.size()); // while (it.hasNext()) // { // Enumeration e = null; // try // { // e = ASN1Sequence.getInstance( // new ASN1InputStream(((X500Principal) it.next()) // .getEncoded()).readObject()).getObjects(); // } // catch (IOException ex) // { // throw new AnnotatedException( // "Cannot decode CRL issuer information.", ex); // } // ASN1EncodableVector v = new ASN1EncodableVector(); // while (e.hasMoreElements()) // { // v.add((ASN1Encodable) e.nextElement()); // } // v.add(relName); // issuersTemp.add(new X500Principal(new DERSequence(v) // .getDEREncoded())); // } // issuers.clear(); // issuers.addAll(issuersTemp); // } // } Iterator it = issuers.iterator(); while (it.hasNext()) { try { selector.addIssuerName(((X500Principal)it.next()).getEncoded()); } catch (IOException ex) { throw new AnnotatedException( "Cannot decode CRL issuer information.", ex); } } } private static BigInteger getSerialNumber( Object cert) { if (cert instanceof X509Certificate) { return ((X509Certificate)cert).getSerialNumber(); } else { return ((X509AttributeCertificate)cert).getSerialNumber(); } } protected static void getCertStatus( Date validDate, X509CRL crl, Object cert, CertStatus certStatus) throws AnnotatedException { X509CRLEntry crl_entry = null; boolean isIndirect; try { isIndirect = X509CRLObject.isIndirectCRL(crl); } catch (CRLException exception) { throw new AnnotatedException("Failed check for indirect CRL.", exception); } if (isIndirect) { if (!(crl instanceof X509CRLObject)) { try { crl = new X509CRLObject(CertificateList.getInstance(crl.getEncoded())); } catch (CRLException exception) { throw new AnnotatedException("Failed to recode indirect CRL.", exception); } } crl_entry = crl.getRevokedCertificate(getSerialNumber(cert)); if (crl_entry == null) { return; } X500Principal certIssuer = ((X509CRLEntryObject)crl_entry).getCertificateIssuer(); if (certIssuer == null) { certIssuer = getIssuerPrincipal(crl); } if (!getEncodedIssuerPrincipal(cert).equals(certIssuer)) { return; } } else if (!getEncodedIssuerPrincipal(cert).equals(getIssuerPrincipal(crl))) { return; // not for our issuer, ignore } else { crl_entry = crl.getRevokedCertificate(getSerialNumber(cert)); if (crl_entry == null) { return; } } DEREnumerated reasonCode = null; if (crl_entry.hasExtensions()) { try { reasonCode = DEREnumerated .getInstance(CertPathValidatorUtilities .getExtensionValue(crl_entry, X509Extension.reasonCode.getId())); } catch (Exception e) { throw new AnnotatedException( "Reason code CRL entry extension could not be decoded.", e); } } // for reason keyCompromise, caCompromise, aACompromise or // unspecified if (!(validDate.getTime() < crl_entry.getRevocationDate().getTime()) || reasonCode == null || reasonCode.getValue().intValue() == 0 || reasonCode.getValue().intValue() == 1 || reasonCode.getValue().intValue() == 2 || reasonCode.getValue().intValue() == 8) { // (i) or (j) (1) if (reasonCode != null) { certStatus.setCertStatus(reasonCode.getValue().intValue()); } // (i) or (j) (2) else { certStatus.setCertStatus(CRLReason.unspecified); } certStatus.setRevocationDate(crl_entry.getRevocationDate()); } } /** * Fetches delta CRLs according to RFC 3280 section 5.2.4. * * @param currentDate The date for which the delta CRLs must be valid. * @param paramsPKIX The extended PKIX parameters. * @param completeCRL The complete CRL the delta CRL is for. * @return A Set of X509CRLs with delta CRLs. * @throws AnnotatedException if an exception occurs while picking the delta * CRLs. */ protected static Set getDeltaCRLs(Date currentDate, ExtendedPKIXParameters paramsPKIX, X509CRL completeCRL) throws AnnotatedException { X509CRLStoreSelector deltaSelect = new X509CRLStoreSelector(); // 5.2.4 (a) try { deltaSelect.addIssuerName(CertPathValidatorUtilities .getIssuerPrincipal(completeCRL).getEncoded()); } catch (IOException e) { throw new AnnotatedException("Cannot extract issuer from CRL.", e); } BigInteger completeCRLNumber = null; try { ASN1Primitive derObject = CertPathValidatorUtilities.getExtensionValue(completeCRL, CRL_NUMBER); if (derObject != null) { completeCRLNumber = ASN1Integer.getInstance(derObject).getPositiveValue(); } } catch (Exception e) { throw new AnnotatedException( "CRL number extension could not be extracted from CRL.", e); } // 5.2.4 (b) byte[] idp = null; try { idp = completeCRL.getExtensionValue(ISSUING_DISTRIBUTION_POINT); } catch (Exception e) { throw new AnnotatedException( "Issuing distribution point extension value could not be read.", e); } // 5.2.4 (d) deltaSelect.setMinCRLNumber(completeCRLNumber == null ? null : completeCRLNumber .add(BigInteger.valueOf(1))); deltaSelect.setIssuingDistributionPoint(idp); deltaSelect.setIssuingDistributionPointEnabled(true); // 5.2.4 (c) deltaSelect.setMaxBaseCRLNumber(completeCRLNumber); // find delta CRLs Set temp = CRL_UTIL.findCRLs(deltaSelect, paramsPKIX, currentDate); Set result = new HashSet(); for (Iterator it = temp.iterator(); it.hasNext(); ) { X509CRL crl = (X509CRL)it.next(); if (isDeltaCRL(crl)) { result.add(crl); } } return result; } private static boolean isDeltaCRL(X509CRL crl) { Set critical = crl.getCriticalExtensionOIDs(); if (critical == null) { return false; } return critical.contains(RFC3280CertPathUtilities.DELTA_CRL_INDICATOR); } /** * Fetches complete CRLs according to RFC 3280. * * @param dp The distribution point for which the complete CRL * @param cert The X509Certificate or * {@link org.bouncycastle.x509.X509AttributeCertificate} for * which the CRL should be searched. * @param currentDate The date for which the delta CRLs must be valid. * @param paramsPKIX The extended PKIX parameters. * @return A Set of X509CRLs with complete * CRLs. * @throws AnnotatedException if an exception occurs while picking the CRLs * or no CRLs are found. */ protected static Set getCompleteCRLs(DistributionPoint dp, Object cert, Date currentDate, ExtendedPKIXParameters paramsPKIX) throws AnnotatedException { X509CRLStoreSelector crlselect = new X509CRLStoreSelector(); try { Set issuers = new HashSet(); if (cert instanceof X509AttributeCertificate) { issuers.add(((X509AttributeCertificate)cert) .getIssuer().getPrincipals()[0]); } else { issuers.add(getEncodedIssuerPrincipal(cert)); } CertPathValidatorUtilities.getCRLIssuersFromDistributionPoint(dp, issuers, crlselect, paramsPKIX); } catch (AnnotatedException e) { throw new AnnotatedException( "Could not get issuer information from distribution point.", e); } if (cert instanceof X509Certificate) { crlselect.setCertificateChecking((X509Certificate)cert); } else if (cert instanceof X509AttributeCertificate) { crlselect.setAttrCertificateChecking((X509AttributeCertificate)cert); } crlselect.setCompleteCRLEnabled(true); Set crls = CRL_UTIL.findCRLs(crlselect, paramsPKIX, currentDate); if (crls.isEmpty()) { if (cert instanceof X509AttributeCertificate) { X509AttributeCertificate aCert = (X509AttributeCertificate)cert; throw new AnnotatedException("No CRLs found for issuer \"" + aCert.getIssuer().getPrincipals()[0] + "\""); } else { X509Certificate xCert = (X509Certificate)cert; throw new AnnotatedException("No CRLs found for issuer \"" + xCert.getIssuerX500Principal() + "\""); } } return crls; } protected static Date getValidCertDateFromValidityModel( ExtendedPKIXParameters paramsPKIX, CertPath certPath, int index) throws AnnotatedException { if (paramsPKIX.getValidityModel() == ExtendedPKIXParameters.CHAIN_VALIDITY_MODEL) { // if end cert use given signing/encryption/... time if (index <= 0) { return CertPathValidatorUtilities.getValidDate(paramsPKIX); // else use time when previous cert was created } else { if (index - 1 == 0) { DERGeneralizedTime dateOfCertgen = null; try { byte[] extBytes = ((X509Certificate)certPath.getCertificates().get(index - 1)).getExtensionValue(ISISMTTObjectIdentifiers.id_isismtt_at_dateOfCertGen.getId()); if (extBytes != null) { dateOfCertgen = DERGeneralizedTime.getInstance(ASN1Primitive.fromByteArray(extBytes)); } } catch (IOException e) { throw new AnnotatedException( "Date of cert gen extension could not be read."); } catch (IllegalArgumentException e) { throw new AnnotatedException( "Date of cert gen extension could not be read."); } if (dateOfCertgen != null) { try { return dateOfCertgen.getDate(); } catch (ParseException e) { throw new AnnotatedException( "Date from date of cert gen extension could not be parsed.", e); } } return ((X509Certificate)certPath.getCertificates().get( index - 1)).getNotBefore(); } else { return ((X509Certificate)certPath.getCertificates().get( index - 1)).getNotBefore(); } } } else { return getValidDate(paramsPKIX); } } /** * Return the next working key inheriting DSA parameters if necessary. *

* This methods inherits DSA parameters from the indexed certificate or * previous certificates in the certificate chain to the returned * PublicKey. The list is searched upwards, meaning the end * certificate is at position 0 and previous certificates are following. *

*

* If the indexed certificate does not contain a DSA key this method simply * returns the public key. If the DSA key already contains DSA parameters * the key is also only returned. *

* * @param certs The certification path. * @param index The index of the certificate which contains the public key * which should be extended with DSA parameters. * @return The public key of the certificate in list position * index extended with DSA parameters if applicable. * @throws AnnotatedException if DSA parameters cannot be inherited. */ protected static PublicKey getNextWorkingKey(List certs, int index) throws CertPathValidatorException { Certificate cert = (Certificate)certs.get(index); PublicKey pubKey = cert.getPublicKey(); if (!(pubKey instanceof DSAPublicKey)) { return pubKey; } DSAPublicKey dsaPubKey = (DSAPublicKey)pubKey; if (dsaPubKey.getParams() != null) { return dsaPubKey; } for (int i = index + 1; i < certs.size(); i++) { X509Certificate parentCert = (X509Certificate)certs.get(i); pubKey = parentCert.getPublicKey(); if (!(pubKey instanceof DSAPublicKey)) { throw new CertPathValidatorException( "DSA parameters cannot be inherited from previous certificate."); } DSAPublicKey prevDSAPubKey = (DSAPublicKey)pubKey; if (prevDSAPubKey.getParams() == null) { continue; } DSAParams dsaParams = prevDSAPubKey.getParams(); DSAPublicKeySpec dsaPubKeySpec = new DSAPublicKeySpec( dsaPubKey.getY(), dsaParams.getP(), dsaParams.getQ(), dsaParams.getG()); try { KeyFactory keyFactory = KeyFactory.getInstance("DSA", BouncyCastleProvider.PROVIDER_NAME); return keyFactory.generatePublic(dsaPubKeySpec); } catch (Exception exception) { throw new RuntimeException(exception.getMessage()); } } throw new CertPathValidatorException("DSA parameters cannot be inherited from previous certificate."); } /** * Find the issuer certificates of a given certificate. * * @param cert The certificate for which an issuer should be found. * @param pkixParams * @return A Collection object containing the issuer * X509Certificates. Never null. * @throws AnnotatedException if an error occurs. */ protected static Collection findIssuerCerts( X509Certificate cert, ExtendedPKIXBuilderParameters pkixParams) throws AnnotatedException { X509CertStoreSelector certSelect = new X509CertStoreSelector(); Set certs = new HashSet(); try { certSelect.setSubject(cert.getIssuerX500Principal().getEncoded()); } catch (IOException ex) { throw new AnnotatedException( "Subject criteria for certificate selector to find issuer certificate could not be set.", ex); } Iterator iter; try { List matches = new ArrayList(); matches.addAll(CertPathValidatorUtilities.findCertificates(certSelect, pkixParams.getCertStores())); matches.addAll(CertPathValidatorUtilities.findCertificates(certSelect, pkixParams.getStores())); matches.addAll(CertPathValidatorUtilities.findCertificates(certSelect, pkixParams.getAdditionalStores())); iter = matches.iterator(); } catch (AnnotatedException e) { throw new AnnotatedException("Issuer certificate cannot be searched.", e); } X509Certificate issuer = null; while (iter.hasNext()) { issuer = (X509Certificate)iter.next(); // issuer cannot be verified because possible DSA inheritance // parameters are missing certs.add(issuer); } return certs; } protected static void verifyX509Certificate(X509Certificate cert, PublicKey publicKey, String sigProvider) throws GeneralSecurityException { if (sigProvider == null) { cert.verify(publicKey); } else { cert.verify(publicKey, sigProvider); } } } bouncycastle-1.49.orig/jdk1.4/org/bouncycastle/jce/provider/X509SignatureUtil.java0000644000175000017500000000774411676515270027357 0ustar ebourgebourgpackage org.bouncycastle.jce.provider; import java.security.InvalidKeyException; import java.security.NoSuchAlgorithmException; import java.security.Signature; import java.security.SignatureException; import org.bouncycastle.asn1.ASN1Encodable; import org.bouncycastle.asn1.ASN1Null; import org.bouncycastle.asn1.DERNull; import org.bouncycastle.asn1.DERObjectIdentifier; import org.bouncycastle.asn1.cryptopro.CryptoProObjectIdentifiers; import org.bouncycastle.asn1.nist.NISTObjectIdentifiers; import org.bouncycastle.asn1.oiw.OIWObjectIdentifiers; import org.bouncycastle.asn1.pkcs.PKCSObjectIdentifiers; import org.bouncycastle.asn1.pkcs.RSASSAPSSparams; import org.bouncycastle.asn1.teletrust.TeleTrusTObjectIdentifiers; import org.bouncycastle.asn1.x509.AlgorithmIdentifier; class X509SignatureUtil { private static final ASN1Null derNull = new DERNull(); static void setSignatureParameters( Signature signature, ASN1Encodable params) throws NoSuchAlgorithmException, SignatureException, InvalidKeyException { if (params != null && !derNull.equals(params)) { /* AlgorithmParameters sigParams = AlgorithmParameters.getInstance(signature.getAlgorithm(), signature.getProvider()); try { sigParams.init(params.getDERObject().getDEREncoded()); } catch (IOException e) { throw new SignatureException("IOException decoding parameters: " + e.getMessage()); } try { signature.setParameters(sigParams.getParameterSpec(PSSParameterSpec.class)); } catch (GeneralSecurityException e) { throw new SignatureException("Exception extracting parameters: " + e.getMessage()); } */ } } static String getSignatureName( AlgorithmIdentifier sigAlgId) { ASN1Encodable params = sigAlgId.getParameters(); if (params != null && !derNull.equals(params)) { if (sigAlgId.getObjectId().equals(PKCSObjectIdentifiers.id_RSASSA_PSS)) { RSASSAPSSparams rsaParams = RSASSAPSSparams.getInstance(params); return getDigestAlgName(rsaParams.getHashAlgorithm().getObjectId()) + "withRSAandMGF1"; } } return sigAlgId.getObjectId().getId(); } /** * Return the digest algorithm using one of the standard JCA string * representations rather the the algorithm identifier (if possible). */ private static String getDigestAlgName( DERObjectIdentifier digestAlgOID) { if (PKCSObjectIdentifiers.md5.equals(digestAlgOID)) { return "MD5"; } else if (OIWObjectIdentifiers.idSHA1.equals(digestAlgOID)) { return "SHA1"; } else if (NISTObjectIdentifiers.id_sha224.equals(digestAlgOID)) { return "SHA224"; } else if (NISTObjectIdentifiers.id_sha256.equals(digestAlgOID)) { return "SHA256"; } else if (NISTObjectIdentifiers.id_sha384.equals(digestAlgOID)) { return "SHA384"; } else if (NISTObjectIdentifiers.id_sha512.equals(digestAlgOID)) { return "SHA512"; } else if (TeleTrusTObjectIdentifiers.ripemd128.equals(digestAlgOID)) { return "RIPEMD128"; } else if (TeleTrusTObjectIdentifiers.ripemd160.equals(digestAlgOID)) { return "RIPEMD160"; } else if (TeleTrusTObjectIdentifiers.ripemd256.equals(digestAlgOID)) { return "RIPEMD256"; } else if (CryptoProObjectIdentifiers.gostR3411.equals(digestAlgOID)) { return "GOST3411"; } else { return digestAlgOID.getId(); } } } bouncycastle-1.49.orig/jdk1.4/org/bouncycastle/jce/provider/JDKPKCS12KeyStore.java0000644000175000017500000015464611730507765027121 0ustar ebourgebourgpackage org.bouncycastle.jce.provider; import java.io.BufferedInputStream; import java.io.ByteArrayInputStream; import java.io.ByteArrayOutputStream; import java.io.IOException; import java.io.InputStream; import java.io.OutputStream; import java.security.Key; import java.security.KeyStoreException; import java.security.KeyStoreSpi; import java.security.NoSuchAlgorithmException; import java.security.Principal; import java.security.PrivateKey; import java.security.Provider; import java.security.PublicKey; import java.security.SecureRandom; import java.security.UnrecoverableKeyException; import java.security.cert.Certificate; import java.security.cert.CertificateEncodingException; import java.security.cert.CertificateFactory; import java.security.cert.X509Certificate; import java.util.Date; import java.util.Enumeration; import java.util.Hashtable; import java.util.Vector; import javax.crypto.Cipher; import javax.crypto.Mac; import javax.crypto.SecretKey; import javax.crypto.SecretKeyFactory; import javax.crypto.spec.PBEKeySpec; import javax.crypto.spec.PBEParameterSpec; import org.bouncycastle.asn1.ASN1Encodable; import org.bouncycastle.asn1.ASN1EncodableVector; import org.bouncycastle.asn1.ASN1InputStream; import org.bouncycastle.asn1.ASN1Object; import org.bouncycastle.asn1.ASN1ObjectIdentifier; import org.bouncycastle.asn1.ASN1OctetString; import org.bouncycastle.asn1.ASN1Primitive; import org.bouncycastle.asn1.ASN1Sequence; import org.bouncycastle.asn1.ASN1Set; import org.bouncycastle.asn1.BERConstructedOctetString; import org.bouncycastle.asn1.BEROutputStream; import org.bouncycastle.asn1.DERBMPString; import org.bouncycastle.asn1.DERNull; import org.bouncycastle.asn1.DEROctetString; import org.bouncycastle.asn1.DERSequence; import org.bouncycastle.asn1.DERSet; import org.bouncycastle.asn1.pkcs.AuthenticatedSafe; import org.bouncycastle.asn1.pkcs.CertBag; import org.bouncycastle.asn1.pkcs.ContentInfo; import org.bouncycastle.asn1.pkcs.EncryptedData; import org.bouncycastle.asn1.pkcs.MacData; import org.bouncycastle.asn1.pkcs.PKCS12PBEParams; import org.bouncycastle.asn1.pkcs.PKCSObjectIdentifiers; import org.bouncycastle.asn1.pkcs.Pfx; import org.bouncycastle.asn1.pkcs.SafeBag; import org.bouncycastle.asn1.util.ASN1Dump; import org.bouncycastle.asn1.x509.AlgorithmIdentifier; import org.bouncycastle.asn1.x509.AuthorityKeyIdentifier; import org.bouncycastle.asn1.x509.DigestInfo; import org.bouncycastle.asn1.x509.SubjectKeyIdentifier; import org.bouncycastle.asn1.x509.SubjectPublicKeyInfo; import org.bouncycastle.asn1.x509.X509Extensions; import org.bouncycastle.asn1.x509.X509ObjectIdentifiers; import org.bouncycastle.jcajce.provider.symmetric.util.BCPBEKey; import org.bouncycastle.jce.interfaces.BCKeyStore; import org.bouncycastle.jce.interfaces.PKCS12BagAttributeCarrier; import org.bouncycastle.util.Arrays; import org.bouncycastle.util.Strings; import org.bouncycastle.util.encoders.Hex; public class JDKPKCS12KeyStore extends KeyStoreSpi implements PKCSObjectIdentifiers, X509ObjectIdentifiers, BCKeyStore { private static final int SALT_SIZE = 20; private static final int MIN_ITERATIONS = 1024; private static final Provider bcProvider = new BouncyCastleProvider(); private IgnoresCaseHashtable keys = new IgnoresCaseHashtable(); private Hashtable localIds = new Hashtable(); private IgnoresCaseHashtable certs = new IgnoresCaseHashtable(); private Hashtable chainCerts = new Hashtable(); private Hashtable keyCerts = new Hashtable(); // // generic object types // static final int NULL = 0; static final int CERTIFICATE = 1; static final int KEY = 2; static final int SECRET = 3; static final int SEALED = 4; // // key types // static final int KEY_PRIVATE = 0; static final int KEY_PUBLIC = 1; static final int KEY_SECRET = 2; protected SecureRandom random = new SecureRandom(); // use of final causes problems with JDK 1.2 compiler private CertificateFactory certFact; private ASN1ObjectIdentifier keyAlgorithm; private ASN1ObjectIdentifier certAlgorithm; private class CertId { byte[] id; CertId( PublicKey key) { this.id = createSubjectKeyId(key).getKeyIdentifier(); } CertId( byte[] id) { this.id = id; } public int hashCode() { return Arrays.hashCode(id); } public boolean equals( Object o) { if (o == this) { return true; } if (!(o instanceof CertId)) { return false; } CertId cId = (CertId)o; return Arrays.areEqual(id, cId.id); } } public JDKPKCS12KeyStore( Provider provider, ASN1ObjectIdentifier keyAlgorithm, ASN1ObjectIdentifier certAlgorithm) { this.keyAlgorithm = keyAlgorithm; this.certAlgorithm = certAlgorithm; try { if (provider != null) { certFact = CertificateFactory.getInstance("X.509", provider); } else { certFact = CertificateFactory.getInstance("X.509"); } } catch (Exception e) { throw new IllegalArgumentException("can't create cert factory - " + e.toString()); } } private SubjectKeyIdentifier createSubjectKeyId( PublicKey pubKey) { try { SubjectPublicKeyInfo info = SubjectPublicKeyInfo.getInstance( (ASN1Sequence) ASN1Primitive.fromByteArray(pubKey.getEncoded())); return new SubjectKeyIdentifier(info); } catch (Exception e) { throw new RuntimeException("error creating key"); } } public void setRandom( SecureRandom rand) { this.random = rand; } public Enumeration engineAliases() { Hashtable tab = new Hashtable(); Enumeration e = certs.keys(); while (e.hasMoreElements()) { tab.put(e.nextElement(), "cert"); } e = keys.keys(); while (e.hasMoreElements()) { String a = (String)e.nextElement(); if (tab.get(a) == null) { tab.put(a, "key"); } } return tab.keys(); } public boolean engineContainsAlias( String alias) { return (certs.get(alias) != null || keys.get(alias) != null); } /** * this is not quite complete - we should follow up on the chain, a bit * tricky if a certificate appears in more than one chain... */ public void engineDeleteEntry( String alias) throws KeyStoreException { Key k = (Key)keys.remove(alias); Certificate c = (Certificate)certs.remove(alias); if (c != null) { chainCerts.remove(new CertId(c.getPublicKey())); } if (k != null) { String id = (String)localIds.remove(alias); if (id != null) { c = (Certificate)keyCerts.remove(id); } if (c != null) { chainCerts.remove(new CertId(c.getPublicKey())); } } if (c == null && k == null) { throw new KeyStoreException("no such entry as " + alias); } } /** * simply return the cert for the private key */ public Certificate engineGetCertificate( String alias) { if (alias == null) { throw new IllegalArgumentException("null alias passed to getCertificate."); } Certificate c = (Certificate)certs.get(alias); // // look up the key table - and try the local key id // if (c == null) { String id = (String)localIds.get(alias); if (id != null) { c = (Certificate)keyCerts.get(id); } else { c = (Certificate)keyCerts.get(alias); } } return c; } public String engineGetCertificateAlias( Certificate cert) { Enumeration c = certs.elements(); Enumeration k = certs.keys(); while (c.hasMoreElements()) { Certificate tc = (Certificate)c.nextElement(); String ta = (String)k.nextElement(); if (tc.equals(cert)) { return ta; } } c = keyCerts.elements(); k = keyCerts.keys(); while (c.hasMoreElements()) { Certificate tc = (Certificate)c.nextElement(); String ta = (String)k.nextElement(); if (tc.equals(cert)) { return ta; } } return null; } public Certificate[] engineGetCertificateChain( String alias) { if (alias == null) { throw new IllegalArgumentException("null alias passed to getCertificateChain."); } if (!engineIsKeyEntry(alias)) { return null; } Certificate c = engineGetCertificate(alias); if (c != null) { Vector cs = new Vector(); while (c != null) { X509Certificate x509c = (X509Certificate)c; Certificate nextC = null; byte[] bytes = x509c.getExtensionValue(X509Extensions.AuthorityKeyIdentifier.getId()); if (bytes != null) { try { ASN1InputStream aIn = new ASN1InputStream(bytes); byte[] authBytes = ((ASN1OctetString)aIn.readObject()).getOctets(); aIn = new ASN1InputStream(authBytes); AuthorityKeyIdentifier id = AuthorityKeyIdentifier.getInstance(aIn.readObject()); if (id.getKeyIdentifier() != null) { nextC = (Certificate)chainCerts.get(new CertId(id.getKeyIdentifier())); } } catch (IOException e) { throw new RuntimeException(e.toString()); } } if (nextC == null) { // // no authority key id, try the Issuer DN // Principal i = x509c.getIssuerDN(); Principal s = x509c.getSubjectDN(); if (!i.equals(s)) { Enumeration e = chainCerts.keys(); while (e.hasMoreElements()) { X509Certificate crt = (X509Certificate)chainCerts.get(e.nextElement()); Principal sub = crt.getSubjectDN(); if (sub.equals(i)) { try { x509c.verify(crt.getPublicKey()); nextC = crt; break; } catch (Exception ex) { // continue } } } } } cs.addElement(c); if (nextC != c) // self signed - end of the chain { c = nextC; } else { c = null; } } Certificate[] certChain = new Certificate[cs.size()]; for (int i = 0; i != certChain.length; i++) { certChain[i] = (Certificate)cs.elementAt(i); } return certChain; } return null; } public Date engineGetCreationDate(String alias) { return new Date(); } public Key engineGetKey( String alias, char[] password) throws NoSuchAlgorithmException, UnrecoverableKeyException { if (alias == null) { throw new IllegalArgumentException("null alias passed to getKey."); } return (Key)keys.get(alias); } public boolean engineIsCertificateEntry( String alias) { return (certs.get(alias) != null && keys.get(alias) == null); } public boolean engineIsKeyEntry( String alias) { return (keys.get(alias) != null); } public void engineSetCertificateEntry( String alias, Certificate cert) throws KeyStoreException { if (keys.get(alias) != null) { throw new KeyStoreException("There is a key entry with the name " + alias + "."); } certs.put(alias, cert); chainCerts.put(new CertId(cert.getPublicKey()), cert); } public void engineSetKeyEntry( String alias, byte[] key, Certificate[] chain) throws KeyStoreException { throw new RuntimeException("operation not supported"); } public void engineSetKeyEntry( String alias, Key key, char[] password, Certificate[] chain) throws KeyStoreException { if ((key instanceof PrivateKey) && (chain == null)) { throw new KeyStoreException("no certificate chain for private key"); } if (keys.get(alias) != null) { engineDeleteEntry(alias); } keys.put(alias, key); certs.put(alias, chain[0]); for (int i = 0; i != chain.length; i++) { chainCerts.put(new CertId(chain[i].getPublicKey()), chain[i]); } } public int engineSize() { Hashtable tab = new Hashtable(); Enumeration e = certs.keys(); while (e.hasMoreElements()) { tab.put(e.nextElement(), "cert"); } e = keys.keys(); while (e.hasMoreElements()) { String a = (String)e.nextElement(); if (tab.get(a) == null) { tab.put(a, "key"); } } return tab.size(); } protected PrivateKey unwrapKey( AlgorithmIdentifier algId, byte[] data, char[] password, boolean wrongPKCS12Zero) throws IOException { String algorithm = algId.getObjectId().getId(); PKCS12PBEParams pbeParams = PKCS12PBEParams.getInstance(algId.getParameters()); PBEKeySpec pbeSpec = new PBEKeySpec(password); PrivateKey out; try { SecretKeyFactory keyFact = SecretKeyFactory.getInstance( algorithm, bcProvider); PBEParameterSpec defParams = new PBEParameterSpec( pbeParams.getIV(), pbeParams.getIterations().intValue()); SecretKey k = keyFact.generateSecret(pbeSpec); ((BCPBEKey)k).setTryWrongPKCS12Zero(wrongPKCS12Zero); Cipher cipher = Cipher.getInstance(algorithm, bcProvider); cipher.init(Cipher.UNWRAP_MODE, k, defParams); // we pass "" as the key algorithm type as it is unknown at this point out = (PrivateKey)cipher.unwrap(data, "", Cipher.PRIVATE_KEY); } catch (Exception e) { throw new IOException("exception unwrapping private key - " + e.toString()); } return out; } protected byte[] wrapKey( String algorithm, Key key, PKCS12PBEParams pbeParams, char[] password) throws IOException { PBEKeySpec pbeSpec = new PBEKeySpec(password); byte[] out; try { SecretKeyFactory keyFact = SecretKeyFactory.getInstance( algorithm, bcProvider); PBEParameterSpec defParams = new PBEParameterSpec( pbeParams.getIV(), pbeParams.getIterations().intValue()); Cipher cipher = Cipher.getInstance(algorithm, bcProvider); cipher.init(Cipher.WRAP_MODE, keyFact.generateSecret(pbeSpec), defParams); out = cipher.wrap(key); } catch (Exception e) { throw new IOException("exception encrypting data - " + e.toString()); } return out; } protected byte[] cryptData( boolean forEncryption, AlgorithmIdentifier algId, char[] password, boolean wrongPKCS12Zero, byte[] data) throws IOException { String algorithm = algId.getObjectId().getId(); PKCS12PBEParams pbeParams = PKCS12PBEParams.getInstance(algId.getParameters()); PBEKeySpec pbeSpec = new PBEKeySpec(password); try { SecretKeyFactory keyFact = SecretKeyFactory.getInstance(algorithm, bcProvider); PBEParameterSpec defParams = new PBEParameterSpec( pbeParams.getIV(), pbeParams.getIterations().intValue()); BCPBEKey key = (BCPBEKey) keyFact.generateSecret(pbeSpec); key.setTryWrongPKCS12Zero(wrongPKCS12Zero); Cipher cipher = Cipher.getInstance(algorithm, bcProvider); int mode = forEncryption ? Cipher.ENCRYPT_MODE : Cipher.DECRYPT_MODE; cipher.init(mode, key, defParams); return cipher.doFinal(data); } catch (Exception e) { throw new IOException("exception decrypting data - " + e.toString()); } } public void engineLoad( InputStream stream, char[] password) throws IOException { if (stream == null) // just initialising { return; } if (password == null) { throw new NullPointerException("No password supplied for PKCS#12 KeyStore."); } BufferedInputStream bufIn = new BufferedInputStream(stream); bufIn.mark(10); int head = bufIn.read(); if (head != 0x30) { throw new IOException("stream does not represent a PKCS12 key store"); } bufIn.reset(); ASN1InputStream bIn = new ASN1InputStream(bufIn); ASN1Sequence obj = (ASN1Sequence)bIn.readObject(); Pfx bag = Pfx.getInstance(obj); ContentInfo info = bag.getAuthSafe(); Vector chain = new Vector(); boolean unmarkedKey = false; boolean wrongPKCS12Zero = false; if (bag.getMacData() != null) // check the mac code { MacData mData = bag.getMacData(); DigestInfo dInfo = mData.getMac(); AlgorithmIdentifier algId = dInfo.getAlgorithmId(); byte[] salt = mData.getSalt(); int itCount = mData.getIterationCount().intValue(); byte[] data = ((ASN1OctetString)info.getContent()).getOctets(); try { byte[] res = calculatePbeMac(algId.getObjectId(), salt, itCount, password, false, data); byte[] dig = dInfo.getDigest(); if (!Arrays.constantTimeAreEqual(res, dig)) { if (password.length > 0) { throw new IOException("PKCS12 key store mac invalid - wrong password or corrupted file."); } // Try with incorrect zero length password res = calculatePbeMac(algId.getObjectId(), salt, itCount, password, true, data); if (!Arrays.constantTimeAreEqual(res, dig)) { throw new IOException("PKCS12 key store mac invalid - wrong password or corrupted file."); } wrongPKCS12Zero = true; } } catch (IOException e) { throw e; } catch (Exception e) { throw new IOException("error constructing MAC: " + e.toString()); } } keys = new IgnoresCaseHashtable(); localIds = new Hashtable(); if (info.getContentType().equals(data)) { bIn = new ASN1InputStream(((ASN1OctetString)info.getContent()).getOctets()); AuthenticatedSafe authSafe = AuthenticatedSafe.getInstance(bIn.readObject()); ContentInfo[] c = authSafe.getContentInfo(); for (int i = 0; i != c.length; i++) { if (c[i].getContentType().equals(data)) { ASN1InputStream dIn = new ASN1InputStream(((ASN1OctetString)c[i].getContent()).getOctets()); ASN1Sequence seq = (ASN1Sequence)dIn.readObject(); for (int j = 0; j != seq.size(); j++) { SafeBag b = SafeBag.getInstance(seq.getObjectAt(j)); if (b.getBagId().equals(pkcs8ShroudedKeyBag)) { org.bouncycastle.asn1.pkcs.EncryptedPrivateKeyInfo eIn = org.bouncycastle.asn1.pkcs.EncryptedPrivateKeyInfo.getInstance(b.getBagValue()); PrivateKey privKey = unwrapKey(eIn.getEncryptionAlgorithm(), eIn.getEncryptedData(), password, wrongPKCS12Zero); // // set the attributes on the key // PKCS12BagAttributeCarrier bagAttr = (PKCS12BagAttributeCarrier)privKey; String alias = null; ASN1OctetString localId = null; if (b.getBagAttributes() != null) { Enumeration e = b.getBagAttributes().getObjects(); while (e.hasMoreElements()) { ASN1Sequence sq = (ASN1Sequence)e.nextElement(); ASN1ObjectIdentifier aOid = (ASN1ObjectIdentifier)sq.getObjectAt(0); ASN1Set attrSet = (ASN1Set)sq.getObjectAt(1); ASN1Object attr = null; if (attrSet.size() > 0) { attr = (ASN1Object)attrSet.getObjectAt(0); ASN1Encodable existing = bagAttr.getBagAttribute(aOid); if (existing != null) { // OK, but the value has to be the same if (!existing.toASN1Primitive().equals(attr)) { throw new IOException( "attempt to add existing attribute with different value"); } } else { bagAttr.setBagAttribute(aOid, attr); } } if (aOid.equals(pkcs_9_at_friendlyName)) { alias = ((DERBMPString)attr).getString(); keys.put(alias, privKey); } else if (aOid.equals(pkcs_9_at_localKeyId)) { localId = (ASN1OctetString)attr; } } } if (localId != null) { String name = new String(Hex.encode(localId.getOctets())); if (alias == null) { keys.put(name, privKey); } else { localIds.put(alias, name); } } else { unmarkedKey = true; keys.put("unmarked", privKey); } } else if (b.getBagId().equals(certBag)) { chain.addElement(b); } else { System.out.println("extra in data " + b.getBagId()); System.out.println(ASN1Dump.dumpAsString(b)); } } } else if (c[i].getContentType().equals(encryptedData)) { EncryptedData d = EncryptedData.getInstance(c[i].getContent()); byte[] octets = cryptData(false, d.getEncryptionAlgorithm(), password, wrongPKCS12Zero, d.getContent().getOctets()); ASN1Sequence seq = (ASN1Sequence) ASN1Primitive.fromByteArray(octets); for (int j = 0; j != seq.size(); j++) { SafeBag b = SafeBag.getInstance(seq.getObjectAt(j)); if (b.getBagId().equals(certBag)) { chain.addElement(b); } else if (b.getBagId().equals(pkcs8ShroudedKeyBag)) { org.bouncycastle.asn1.pkcs.EncryptedPrivateKeyInfo eIn = org.bouncycastle.asn1.pkcs.EncryptedPrivateKeyInfo.getInstance(b.getBagValue()); PrivateKey privKey = unwrapKey(eIn.getEncryptionAlgorithm(), eIn.getEncryptedData(), password, wrongPKCS12Zero); // // set the attributes on the key // PKCS12BagAttributeCarrier bagAttr = (PKCS12BagAttributeCarrier)privKey; String alias = null; ASN1OctetString localId = null; Enumeration e = b.getBagAttributes().getObjects(); while (e.hasMoreElements()) { ASN1Sequence sq = (ASN1Sequence)e.nextElement(); ASN1ObjectIdentifier aOid = (ASN1ObjectIdentifier)sq.getObjectAt(0); ASN1Set attrSet= (ASN1Set)sq.getObjectAt(1); ASN1Object attr = null; if (attrSet.size() > 0) { attr = (ASN1Object)attrSet.getObjectAt(0); ASN1Encodable existing = bagAttr.getBagAttribute(aOid); if (existing != null) { // OK, but the value has to be the same if (!existing.toASN1Primitive().equals(attr)) { throw new IOException( "attempt to add existing attribute with different value"); } } else { bagAttr.setBagAttribute(aOid, attr); } } if (aOid.equals(pkcs_9_at_friendlyName)) { alias = ((DERBMPString)attr).getString(); keys.put(alias, privKey); } else if (aOid.equals(pkcs_9_at_localKeyId)) { localId = (ASN1OctetString)attr; } } String name = new String(Hex.encode(localId.getOctets())); if (alias == null) { keys.put(name, privKey); } else { localIds.put(alias, name); } } else if (b.getBagId().equals(keyBag)) { org.bouncycastle.asn1.pkcs.PrivateKeyInfo kInfo = new org.bouncycastle.asn1.pkcs.PrivateKeyInfo((ASN1Sequence)b.getBagValue()); PrivateKey privKey = BouncyCastleProvider.getPrivateKey(kInfo); // // set the attributes on the key // PKCS12BagAttributeCarrier bagAttr = (PKCS12BagAttributeCarrier)privKey; String alias = null; ASN1OctetString localId = null; Enumeration e = b.getBagAttributes().getObjects(); while (e.hasMoreElements()) { ASN1Sequence sq = (ASN1Sequence)e.nextElement(); ASN1ObjectIdentifier aOid = (ASN1ObjectIdentifier)sq.getObjectAt(0); ASN1Set attrSet = (ASN1Set)sq.getObjectAt(1); ASN1Object attr = null; if (attrSet.size() > 0) { attr = (ASN1Object)attrSet.getObjectAt(0); ASN1Encodable existing = bagAttr.getBagAttribute(aOid); if (existing != null) { // OK, but the value has to be the same if (!existing.toASN1Primitive().equals(attr)) { throw new IOException( "attempt to add existing attribute with different value"); } } else { bagAttr.setBagAttribute(aOid, attr); } } if (aOid.equals(pkcs_9_at_friendlyName)) { alias = ((DERBMPString)attr).getString(); keys.put(alias, privKey); } else if (aOid.equals(pkcs_9_at_localKeyId)) { localId = (ASN1OctetString)attr; } } String name = new String(Hex.encode(localId.getOctets())); if (alias == null) { keys.put(name, privKey); } else { localIds.put(alias, name); } } else { System.out.println("extra in encryptedData " + b.getBagId()); System.out.println(ASN1Dump.dumpAsString(b)); } } } else { System.out.println("extra " + c[i].getContentType().getId()); System.out.println("extra " + ASN1Dump.dumpAsString(c[i].getContent())); } } } certs = new IgnoresCaseHashtable(); chainCerts = new Hashtable(); keyCerts = new Hashtable(); for (int i = 0; i != chain.size(); i++) { SafeBag b = (SafeBag)chain.elementAt(i); CertBag cb = CertBag.getInstance(b.getBagValue()); if (!cb.getCertId().equals(x509Certificate)) { throw new RuntimeException("Unsupported certificate type: " + cb.getCertId()); } Certificate cert; try { ByteArrayInputStream cIn = new ByteArrayInputStream( ((ASN1OctetString)cb.getCertValue()).getOctets()); cert = certFact.generateCertificate(cIn); } catch (Exception e) { throw new RuntimeException(e.toString()); } // // set the attributes // ASN1OctetString localId = null; String alias = null; if (b.getBagAttributes() != null) { Enumeration e = b.getBagAttributes().getObjects(); while (e.hasMoreElements()) { ASN1Sequence sq = (ASN1Sequence)e.nextElement(); ASN1ObjectIdentifier oid = (ASN1ObjectIdentifier)sq.getObjectAt(0); ASN1Object attr = (ASN1Object)((ASN1Set)sq.getObjectAt(1)).getObjectAt(0); PKCS12BagAttributeCarrier bagAttr = null; if (cert instanceof PKCS12BagAttributeCarrier) { bagAttr = (PKCS12BagAttributeCarrier)cert; ASN1Encodable existing = bagAttr.getBagAttribute(oid); if (existing != null) { // OK, but the value has to be the same if (!existing.toASN1Primitive().equals(attr)) { throw new IOException( "attempt to add existing attribute with different value"); } } else { bagAttr.setBagAttribute(oid, attr); } } if (oid.equals(pkcs_9_at_friendlyName)) { alias = ((DERBMPString)attr).getString(); } else if (oid.equals(pkcs_9_at_localKeyId)) { localId = (ASN1OctetString)attr; } } } chainCerts.put(new CertId(cert.getPublicKey()), cert); if (unmarkedKey) { if (keyCerts.isEmpty()) { String name = new String(Hex.encode(createSubjectKeyId(cert.getPublicKey()).getKeyIdentifier())); keyCerts.put(name, cert); keys.put(name, keys.remove("unmarked")); } } else { // // the local key id needs to override the friendly name // if (localId != null) { String name = new String(Hex.encode(localId.getOctets())); keyCerts.put(name, cert); } if (alias != null) { certs.put(alias, cert); } } } } public void engineStore(OutputStream stream, char[] password) throws IOException { if (password == null) { throw new NullPointerException("No password supplied for PKCS#12 KeyStore."); } // // handle the key // ASN1EncodableVector keyS = new ASN1EncodableVector(); Enumeration ks = keys.keys(); while (ks.hasMoreElements()) { byte[] kSalt = new byte[SALT_SIZE]; random.nextBytes(kSalt); String name = (String)ks.nextElement(); PrivateKey privKey = (PrivateKey)keys.get(name); PKCS12PBEParams kParams = new PKCS12PBEParams(kSalt, MIN_ITERATIONS); byte[] kBytes = wrapKey(keyAlgorithm.getId(), privKey, kParams, password); AlgorithmIdentifier kAlgId = new AlgorithmIdentifier(keyAlgorithm, kParams.toASN1Object()); org.bouncycastle.asn1.pkcs.EncryptedPrivateKeyInfo kInfo = new org.bouncycastle.asn1.pkcs.EncryptedPrivateKeyInfo(kAlgId, kBytes); boolean attrSet = false; ASN1EncodableVector kName = new ASN1EncodableVector(); if (privKey instanceof PKCS12BagAttributeCarrier) { PKCS12BagAttributeCarrier bagAttrs = (PKCS12BagAttributeCarrier)privKey; // // make sure we are using the local alias on store // DERBMPString nm = (DERBMPString)bagAttrs.getBagAttribute(pkcs_9_at_friendlyName); if (nm == null || !nm.getString().equals(name)) { bagAttrs.setBagAttribute(pkcs_9_at_friendlyName, new DERBMPString(name)); } // // make sure we have a local key-id // if (bagAttrs.getBagAttribute(pkcs_9_at_localKeyId) == null) { Certificate ct = engineGetCertificate(name); bagAttrs.setBagAttribute(pkcs_9_at_localKeyId, createSubjectKeyId(ct.getPublicKey())); } Enumeration e = bagAttrs.getBagAttributeKeys(); while (e.hasMoreElements()) { ASN1ObjectIdentifier oid = (ASN1ObjectIdentifier)e.nextElement(); ASN1EncodableVector kSeq = new ASN1EncodableVector(); kSeq.add(oid); kSeq.add(new DERSet(bagAttrs.getBagAttribute(oid))); attrSet = true; kName.add(new DERSequence(kSeq)); } } if (!attrSet) { // // set a default friendly name (from the key id) and local id // ASN1EncodableVector kSeq = new ASN1EncodableVector(); Certificate ct = engineGetCertificate(name); kSeq.add(pkcs_9_at_localKeyId); kSeq.add(new DERSet(createSubjectKeyId(ct.getPublicKey()))); kName.add(new DERSequence(kSeq)); kSeq = new ASN1EncodableVector(); kSeq.add(pkcs_9_at_friendlyName); kSeq.add(new DERSet(new DERBMPString(name))); kName.add(new DERSequence(kSeq)); } SafeBag kBag = new SafeBag(pkcs8ShroudedKeyBag, kInfo.toASN1Object(), new DERSet(kName)); keyS.add(kBag); } byte[] keySEncoded = new DERSequence(keyS).getEncoded(); BERConstructedOctetString keyString = new BERConstructedOctetString(keySEncoded); // // certificate processing // byte[] cSalt = new byte[SALT_SIZE]; random.nextBytes(cSalt); ASN1EncodableVector certSeq = new ASN1EncodableVector(); PKCS12PBEParams cParams = new PKCS12PBEParams(cSalt, MIN_ITERATIONS); AlgorithmIdentifier cAlgId = new AlgorithmIdentifier(certAlgorithm, cParams.toASN1Object()); Hashtable doneCerts = new Hashtable(); Enumeration cs = keys.keys(); while (cs.hasMoreElements()) { try { String name = (String)cs.nextElement(); Certificate cert = engineGetCertificate(name); boolean cAttrSet = false; CertBag cBag = new CertBag( x509Certificate, new DEROctetString(cert.getEncoded())); ASN1EncodableVector fName = new ASN1EncodableVector(); if (cert instanceof PKCS12BagAttributeCarrier) { PKCS12BagAttributeCarrier bagAttrs = (PKCS12BagAttributeCarrier)cert; // // make sure we are using the local alias on store // DERBMPString nm = (DERBMPString)bagAttrs.getBagAttribute(pkcs_9_at_friendlyName); if (nm == null || !nm.getString().equals(name)) { bagAttrs.setBagAttribute(pkcs_9_at_friendlyName, new DERBMPString(name)); } // // make sure we have a local key-id // if (bagAttrs.getBagAttribute(pkcs_9_at_localKeyId) == null) { bagAttrs.setBagAttribute(pkcs_9_at_localKeyId, createSubjectKeyId(cert.getPublicKey())); } Enumeration e = bagAttrs.getBagAttributeKeys(); while (e.hasMoreElements()) { ASN1ObjectIdentifier oid = (ASN1ObjectIdentifier)e.nextElement(); ASN1EncodableVector fSeq = new ASN1EncodableVector(); fSeq.add(oid); fSeq.add(new DERSet(bagAttrs.getBagAttribute(oid))); fName.add(new DERSequence(fSeq)); cAttrSet = true; } } if (!cAttrSet) { ASN1EncodableVector fSeq = new ASN1EncodableVector(); fSeq.add(pkcs_9_at_localKeyId); fSeq.add(new DERSet(createSubjectKeyId(cert.getPublicKey()))); fName.add(new DERSequence(fSeq)); fSeq = new ASN1EncodableVector(); fSeq.add(pkcs_9_at_friendlyName); fSeq.add(new DERSet(new DERBMPString(name))); fName.add(new DERSequence(fSeq)); } SafeBag sBag = new SafeBag(certBag, cBag.toASN1Object(), new DERSet(fName)); certSeq.add(sBag); doneCerts.put(cert, cert); } catch (CertificateEncodingException e) { throw new IOException("Error encoding certificate: " + e.toString()); } } cs = certs.keys(); while (cs.hasMoreElements()) { try { String certId = (String)cs.nextElement(); Certificate cert = (Certificate)certs.get(certId); boolean cAttrSet = false; if (keys.get(certId) != null) { continue; } CertBag cBag = new CertBag( x509Certificate, new DEROctetString(cert.getEncoded())); ASN1EncodableVector fName = new ASN1EncodableVector(); if (cert instanceof PKCS12BagAttributeCarrier) { PKCS12BagAttributeCarrier bagAttrs = (PKCS12BagAttributeCarrier)cert; // // make sure we are using the local alias on store // DERBMPString nm = (DERBMPString)bagAttrs.getBagAttribute(pkcs_9_at_friendlyName); if (nm == null || !nm.getString().equals(certId)) { bagAttrs.setBagAttribute(pkcs_9_at_friendlyName, new DERBMPString(certId)); } Enumeration e = bagAttrs.getBagAttributeKeys(); while (e.hasMoreElements()) { ASN1ObjectIdentifier oid = (ASN1ObjectIdentifier)e.nextElement(); // a certificate not immediately linked to a key doesn't require // a localKeyID and will confuse some PKCS12 implementations. // // If we find one, we'll prune it out. if (oid.equals(PKCSObjectIdentifiers.pkcs_9_at_localKeyId)) { continue; } ASN1EncodableVector fSeq = new ASN1EncodableVector(); fSeq.add(oid); fSeq.add(new DERSet(bagAttrs.getBagAttribute(oid))); fName.add(new DERSequence(fSeq)); cAttrSet = true; } } if (!cAttrSet) { ASN1EncodableVector fSeq = new ASN1EncodableVector(); fSeq.add(pkcs_9_at_friendlyName); fSeq.add(new DERSet(new DERBMPString(certId))); fName.add(new DERSequence(fSeq)); } SafeBag sBag = new SafeBag(certBag, cBag.toASN1Object(), new DERSet(fName)); certSeq.add(sBag); doneCerts.put(cert, cert); } catch (CertificateEncodingException e) { throw new IOException("Error encoding certificate: " + e.toString()); } } cs = chainCerts.keys(); while (cs.hasMoreElements()) { try { CertId certId = (CertId)cs.nextElement(); Certificate cert = (Certificate)chainCerts.get(certId); if (doneCerts.get(cert) != null) { continue; } CertBag cBag = new CertBag( x509Certificate, new DEROctetString(cert.getEncoded())); ASN1EncodableVector fName = new ASN1EncodableVector(); if (cert instanceof PKCS12BagAttributeCarrier) { PKCS12BagAttributeCarrier bagAttrs = (PKCS12BagAttributeCarrier)cert; Enumeration e = bagAttrs.getBagAttributeKeys(); while (e.hasMoreElements()) { ASN1ObjectIdentifier oid = (ASN1ObjectIdentifier)e.nextElement(); // a certificate not immediately linked to a key doesn't require // a localKeyID and will confuse some PKCS12 implementations. // // If we find one, we'll prune it out. if (oid.equals(PKCSObjectIdentifiers.pkcs_9_at_localKeyId)) { continue; } ASN1EncodableVector fSeq = new ASN1EncodableVector(); fSeq.add(oid); fSeq.add(new DERSet(bagAttrs.getBagAttribute(oid))); fName.add(new DERSequence(fSeq)); } } SafeBag sBag = new SafeBag(certBag, cBag.toASN1Object(), new DERSet(fName)); certSeq.add(sBag); } catch (CertificateEncodingException e) { throw new IOException("Error encoding certificate: " + e.toString()); } } byte[] certSeqEncoded = new DERSequence(certSeq).getEncoded(); byte[] certBytes = cryptData(true, cAlgId, password, false, certSeqEncoded); EncryptedData cInfo = new EncryptedData(data, cAlgId, new BERConstructedOctetString(certBytes)); ContentInfo[] info = new ContentInfo[] { new ContentInfo(data, keyString), new ContentInfo(encryptedData, cInfo.toASN1Object()) }; AuthenticatedSafe auth = new AuthenticatedSafe(info); ByteArrayOutputStream bOut = new ByteArrayOutputStream(); BEROutputStream berOut = new BEROutputStream(bOut); berOut.writeObject(auth); byte[] pkg = bOut.toByteArray(); ContentInfo mainInfo = new ContentInfo(data, new BERConstructedOctetString(pkg)); // // create the mac // byte[] mSalt = new byte[20]; int itCount = MIN_ITERATIONS; random.nextBytes(mSalt); byte[] data = ((ASN1OctetString)mainInfo.getContent()).getOctets(); MacData mData; try { byte[] res = calculatePbeMac(id_SHA1, mSalt, itCount, password, false, data); AlgorithmIdentifier algId = new AlgorithmIdentifier(id_SHA1, new DERNull()); DigestInfo dInfo = new DigestInfo(algId, res); mData = new MacData(dInfo, mSalt, itCount); } catch (Exception e) { throw new IOException("error constructing MAC: " + e.toString()); } // // output the Pfx // Pfx pfx = new Pfx(mainInfo, mData); berOut = new BEROutputStream(stream); berOut.writeObject(pfx); } private static byte[] calculatePbeMac( ASN1ObjectIdentifier oid, byte[] salt, int itCount, char[] password, boolean wrongPkcs12Zero, byte[] data) throws Exception { SecretKeyFactory keyFact = SecretKeyFactory.getInstance(oid.getId(), bcProvider); PBEParameterSpec defParams = new PBEParameterSpec(salt, itCount); PBEKeySpec pbeSpec = new PBEKeySpec(password); BCPBEKey key = (BCPBEKey) keyFact.generateSecret(pbeSpec); key.setTryWrongPKCS12Zero(wrongPkcs12Zero); Mac mac = Mac.getInstance(oid.getId(), bcProvider); mac.init(key, defParams); mac.update(data); return mac.doFinal(); } public static class BCPKCS12KeyStore extends JDKPKCS12KeyStore { public BCPKCS12KeyStore() { super(bcProvider, pbeWithSHAAnd3_KeyTripleDES_CBC, pbeWithSHAAnd40BitRC2_CBC); } } public static class BCPKCS12KeyStore3DES extends JDKPKCS12KeyStore { public BCPKCS12KeyStore3DES() { super(bcProvider, pbeWithSHAAnd3_KeyTripleDES_CBC, pbeWithSHAAnd3_KeyTripleDES_CBC); } } public static class DefPKCS12KeyStore extends JDKPKCS12KeyStore { public DefPKCS12KeyStore() { super(null, pbeWithSHAAnd3_KeyTripleDES_CBC, pbeWithSHAAnd40BitRC2_CBC); } } public static class DefPKCS12KeyStore3DES extends JDKPKCS12KeyStore { public DefPKCS12KeyStore3DES() { super(null, pbeWithSHAAnd3_KeyTripleDES_CBC, pbeWithSHAAnd3_KeyTripleDES_CBC); } } private static class IgnoresCaseHashtable { private Hashtable orig = new Hashtable(); private Hashtable keys = new Hashtable(); public void put(String key, Object value) { String lower = Strings.toLowerCase(key); String k = (String)keys.get(lower); if (k != null) { orig.remove(k); } keys.put(lower, key); orig.put(key, value); } public Enumeration keys() { return orig.keys(); } public Object remove(String alias) { String k = (String)keys.remove(Strings.toLowerCase(alias)); if (k == null) { return null; } return orig.remove(k); } public Object get(String alias) { String k = (String)keys.get(Strings.toLowerCase(alias)); if (k == null) { return null; } return orig.get(k); } public Enumeration elements() { return orig.elements(); } } } bouncycastle-1.49.orig/jdk1.4/org/bouncycastle/jce/interfaces/0000755000175000017500000000000012152033550023566 5ustar ebourgebourgbouncycastle-1.49.orig/jdk1.4/org/bouncycastle/jce/interfaces/ECKey.java0000644000175000017500000000106510262753174025406 0ustar ebourgebourgpackage org.bouncycastle.jce.interfaces; import org.bouncycastle.jce.spec.ECParameterSpec; /** * generic interface for an Elliptic Curve Key. */ public interface ECKey { /** * return a parameter specification representing the EC domain parameters * for the key. * @deprecated this method vanises in JDK 1.5. Use getParameters(). */ public ECParameterSpec getParams(); /** * return a parameter specification representing the EC domain parameters * for the key. */ public ECParameterSpec getParameters(); } bouncycastle-1.49.orig/jdk13.xml0000644000175000017500000001615512150050436016073 0ustar ebourgebourg bouncycastle-1.49.orig/LICENSE.html0000644000175000017500000000222112105571345016401 0ustar ebourgebourg Copyright (c) 2000-2013 The Legion Of The Bouncy Castle (http://www.bouncycastle.org)

Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions:

The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software.

THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. bouncycastle-1.49.orig/jdk1.3/0000755000175000017500000000000012152033550015417 5ustar ebourgebourgbouncycastle-1.49.orig/jdk1.3/org/0000755000175000017500000000000012152033550016206 5ustar ebourgebourgbouncycastle-1.49.orig/jdk1.3/org/bouncycastle/0000755000175000017500000000000012152033550020701 5ustar ebourgebourgbouncycastle-1.49.orig/jdk1.3/org/bouncycastle/crypto/0000755000175000017500000000000012152033550022221 5ustar ebourgebourgbouncycastle-1.49.orig/jdk1.3/org/bouncycastle/crypto/tls/0000755000175000017500000000000012152033550023023 5ustar ebourgebourgbouncycastle-1.49.orig/jdk1.3/org/bouncycastle/crypto/tls/UDPTransport.java0000644000175000017500000000415112147323461026243 0ustar ebourgebourgpackage org.bouncycastle.crypto.tls; import java.io.IOException; import java.net.DatagramPacket; import java.net.DatagramSocket; public class UDPTransport implements DatagramTransport { private final static int MIN_IP_OVERHEAD = 20; private final static int MAX_IP_OVERHEAD = MIN_IP_OVERHEAD + 64; private final static int UDP_OVERHEAD = 8; private final DatagramSocket socket; private final int receiveLimit, sendLimit; public UDPTransport(DatagramSocket socket, int mtu) throws IOException { // // In 1.3 and earlier sockets were bound and connected during creation // //if (!socket.isBound() || !socket.isConnected()) //{ // throw new IllegalArgumentException("'socket' must be bound and connected"); //} this.socket = socket; // NOTE: As of JDK 1.6, can use NetworkInterface.getMTU this.receiveLimit = mtu - MIN_IP_OVERHEAD - UDP_OVERHEAD; this.sendLimit = mtu - MAX_IP_OVERHEAD - UDP_OVERHEAD; } public int getReceiveLimit() { return receiveLimit; } public int getSendLimit() { // TODO[DTLS] Implement Path-MTU discovery? return sendLimit; } public int receive(byte[] buf, int off, int len, int waitMillis) throws IOException { socket.setSoTimeout(waitMillis); DatagramPacket packet = new DatagramPacket(buf, off, len); socket.receive(packet); return packet.getLength(); } public void send(byte[] buf, int off, int len) throws IOException { if (len > getSendLimit()) { /* * RFC 4347 4.1.1. "If the application attempts to send a record larger than the MTU, * the DTLS implementation SHOULD generate an error, thus avoiding sending a packet * which will be fragmented." */ // TODO Exception } DatagramPacket packet = new DatagramPacket(buf, off, len); socket.send(packet); } public void close() throws IOException { socket.close(); } } bouncycastle-1.49.orig/jdk1.3/org/bouncycastle/asn1/0000755000175000017500000000000012152033550021543 5ustar ebourgebourgbouncycastle-1.49.orig/jdk1.3/org/bouncycastle/asn1/StreamUtil.java0000644000175000017500000000356011703444641024513 0ustar ebourgebourgpackage org.bouncycastle.asn1; import java.io.ByteArrayInputStream; import java.io.FileInputStream; import java.io.IOException; import java.io.InputStream; class StreamUtil { /** * Find out possible longest length... * * @param in input stream of interest * @return length calculation or MAX_VALUE. */ static int findLimit(InputStream in) { if (in instanceof LimitedInputStream) { return ((LimitedInputStream)in).getRemaining(); } else if (in instanceof ASN1InputStream) { return ((ASN1InputStream)in).getLimit(); } else if (in instanceof ByteArrayInputStream) { return ((ByteArrayInputStream)in).available(); } return Integer.MAX_VALUE; } static int calculateBodyLength( int length) { int count = 1; if (length > 127) { int size = 1; int val = length; while ((val >>>= 8) != 0) { size++; } for (int i = (size - 1) * 8; i >= 0; i -= 8) { count++; } } return count; } static int calculateTagLength(int tagNo) throws IOException { int length = 1; if (tagNo >= 31) { if (tagNo < 128) { length++; } else { byte[] stack = new byte[5]; int pos = stack.length; stack[--pos] = (byte)(tagNo & 0x7F); do { tagNo >>= 7; stack[--pos] = (byte)(tagNo & 0x7F | 0x80); } while (tagNo > 127); length += stack.length - pos; } } return length; } } bouncycastle-1.49.orig/jdk1.3/org/bouncycastle/cert/0000755000175000017500000000000012152033550021636 5ustar ebourgebourgbouncycastle-1.49.orig/jdk1.3/org/bouncycastle/cert/crmf/0000755000175000017500000000000012152033550022565 5ustar ebourgebourgbouncycastle-1.49.orig/jdk1.3/org/bouncycastle/cert/crmf/jcajce/0000755000175000017500000000000012152033550024004 5ustar ebourgebourgbouncycastle-1.49.orig/jdk1.3/org/bouncycastle/cert/crmf/jcajce/JcaPKIArchiveControlBuilder.java0000644000175000017500000000125111504501516032063 0ustar ebourgebourgpackage org.bouncycastle.cert.crmf.jcajce; import java.security.PrivateKey; import org.bouncycastle.asn1.pkcs.PrivateKeyInfo; import org.bouncycastle.asn1.x500.X500Name; import org.bouncycastle.asn1.x509.GeneralName; import org.bouncycastle.cert.crmf.PKIArchiveControlBuilder; public class JcaPKIArchiveControlBuilder extends PKIArchiveControlBuilder { public JcaPKIArchiveControlBuilder(PrivateKey privateKey, X500Name name) { this(privateKey, new GeneralName(name)); } public JcaPKIArchiveControlBuilder(PrivateKey privateKey, GeneralName generalName) { super(PrivateKeyInfo.getInstance(privateKey.getEncoded()), generalName); } } bouncycastle-1.49.orig/jdk1.3/org/bouncycastle/cert/crmf/jcajce/JcaCertificateRequestMessage.java0000644000175000017500000000301211726307315032372 0ustar ebourgebourgpackage org.bouncycastle.cert.crmf.jcajce; import java.security.Provider; import java.security.PublicKey; import org.bouncycastle.asn1.crmf.CertReqMsg; import org.bouncycastle.asn1.x509.SubjectPublicKeyInfo; import org.bouncycastle.cert.crmf.CRMFException; import org.bouncycastle.cert.crmf.CertificateRequestMessage; import org.bouncycastle.jcajce.DefaultJcaJceHelper; import org.bouncycastle.jcajce.NamedJcaJceHelper; import org.bouncycastle.jcajce.ProviderJcaJceHelper; public class JcaCertificateRequestMessage extends CertificateRequestMessage { private CRMFHelper helper = new CRMFHelper(new DefaultJcaJceHelper()); public JcaCertificateRequestMessage(CertificateRequestMessage certReqMsg) { this(certReqMsg.toASN1Structure()); } public JcaCertificateRequestMessage(CertReqMsg certReqMsg) { super(certReqMsg); } public JcaCertificateRequestMessage setProvider(String providerName) { this.helper = new CRMFHelper(new NamedJcaJceHelper(providerName)); return this; } public JcaCertificateRequestMessage setProvider(Provider provider) { this.helper = new CRMFHelper(new ProviderJcaJceHelper(provider)); return this; } public PublicKey getPublicKey() throws CRMFException { SubjectPublicKeyInfo subjectPublicKeyInfo = getCertTemplate().getPublicKey(); if (subjectPublicKeyInfo != null) { return helper.toPublicKey(subjectPublicKeyInfo); } return null; } } ././@LongLink0000000000000000000000000000015100000000000011562 Lustar rootrootbouncycastle-1.49.orig/jdk1.3/org/bouncycastle/cert/crmf/jcajce/JcaCertificateRequestMessageBuilder.javabouncycastle-1.49.orig/jdk1.3/org/bouncycastle/cert/crmf/jcajce/JcaCertificateRequestMessageBuilder.0000644000175000017500000000132311504501516033033 0ustar ebourgebourgpackage org.bouncycastle.cert.crmf.jcajce; import java.math.BigInteger; import java.security.PublicKey; import org.bouncycastle.asn1.x500.X500Name; import org.bouncycastle.asn1.x509.GeneralName; import org.bouncycastle.asn1.x509.SubjectPublicKeyInfo; import org.bouncycastle.cert.crmf.CertificateRequestMessageBuilder; public class JcaCertificateRequestMessageBuilder extends CertificateRequestMessageBuilder { public JcaCertificateRequestMessageBuilder(BigInteger certReqId) { super(certReqId); } public JcaCertificateRequestMessageBuilder setPublicKey(PublicKey publicKey) { setPublicKey(SubjectPublicKeyInfo.getInstance(publicKey.getEncoded())); return this; } } bouncycastle-1.49.orig/jdk1.3/org/bouncycastle/cert/selector/0000755000175000017500000000000012152033550023456 5ustar ebourgebourgbouncycastle-1.49.orig/jdk1.3/org/bouncycastle/cert/selector/jcajce/0000755000175000017500000000000012152033550024675 5ustar ebourgebourg././@LongLink0000000000000000000000000000014600000000000011566 Lustar rootrootbouncycastle-1.49.orig/jdk1.3/org/bouncycastle/cert/selector/jcajce/JcaX509CertSelectorConverter.javabouncycastle-1.49.orig/jdk1.3/org/bouncycastle/cert/selector/jcajce/JcaX509CertSelectorConverter.jav0000644000175000017500000000317111726263416032707 0ustar ebourgebourgpackage org.bouncycastle.cert.selector.jcajce; import java.io.IOException; import java.math.BigInteger; import org.bouncycastle.jce.cert.X509CertSelector; import org.bouncycastle.asn1.DEROctetString; import org.bouncycastle.asn1.x500.X500Name; import org.bouncycastle.cert.selector.X509CertificateHolderSelector; public class JcaX509CertSelectorConverter { public JcaX509CertSelectorConverter() { } protected X509CertSelector doConversion(X500Name issuer, BigInteger serialNumber, byte[] subjectKeyIdentifier) { X509CertSelector selector = new X509CertSelector(); if (issuer != null) { try { selector.setIssuer(issuer.getEncoded()); } catch (IOException e) { throw new IllegalArgumentException("unable to convert issuer: " + e.getMessage()); } } if (serialNumber != null) { selector.setSerialNumber(serialNumber); } if (subjectKeyIdentifier != null) { try { selector.setSubjectKeyIdentifier(new DEROctetString(subjectKeyIdentifier).getEncoded()); } catch (IOException e) { throw new IllegalArgumentException("unable to convert issuer: " + e.getMessage()); } } return selector; } public X509CertSelector getCertSelector(X509CertificateHolderSelector holderSelector) { return doConversion(holderSelector.getIssuer(), holderSelector.getSerialNumber(), holderSelector.getSubjectKeyIdentifier()); } } ././@LongLink0000000000000000000000000000015200000000000011563 Lustar rootrootbouncycastle-1.49.orig/jdk1.3/org/bouncycastle/cert/selector/jcajce/JcaX509CertificateHolderSelector.javabouncycastle-1.49.orig/jdk1.3/org/bouncycastle/cert/selector/jcajce/JcaX509CertificateHolderSelector0000644000175000017500000000326611726263416032730 0ustar ebourgebourgpackage org.bouncycastle.cert.selector.jcajce; import java.math.BigInteger; import java.security.cert.X509Certificate; import org.bouncycastle.jce.X509Principal; import org.bouncycastle.jce.PrincipalUtil; import org.bouncycastle.asn1.ASN1OctetString; import org.bouncycastle.asn1.x500.X500Name; import org.bouncycastle.asn1.x509.X509Extension; import org.bouncycastle.cert.selector.X509CertificateHolderSelector; public class JcaX509CertificateHolderSelector extends X509CertificateHolderSelector { /** * Construct a signer identifier based on the issuer, serial number and subject key identifier (if present) of the passed in * certificate. * * @param certificate certificate providing the issue and serial number and subject key identifier. */ public JcaX509CertificateHolderSelector(X509Certificate certificate) { super(convertPrincipal(certificate), certificate.getSerialNumber(), getSubjectKeyId(certificate)); } private static X500Name convertPrincipal(X509Certificate issuer) { if (issuer == null) { return null; } try { return X500Name.getInstance(PrincipalUtil.getIssuerX509Principal(issuer).toASN1Primitive()); } catch (Exception e) { throw new IllegalArgumentException("conversion failed: " + e.toString()); } } private static byte[] getSubjectKeyId(X509Certificate cert) { byte[] ext = cert.getExtensionValue(X509Extension.subjectKeyIdentifier.getId()); if (ext != null) { return ASN1OctetString.getInstance(ASN1OctetString.getInstance(ext).getOctets()).getOctets(); } else { return null; } } } bouncycastle-1.49.orig/jdk1.3/org/bouncycastle/cert/selector/jcajce/JcaSelectorConverter.java0000644000175000017500000000202111726263416031635 0ustar ebourgebourgpackage org.bouncycastle.cert.selector.jcajce; import org.bouncycastle.jce.cert.X509CertSelector; import org.bouncycastle.asn1.ASN1OctetString; import org.bouncycastle.asn1.x500.X500Name; import org.bouncycastle.cert.selector.X509CertificateHolderSelector; public class JcaSelectorConverter { public JcaSelectorConverter() { } public X509CertificateHolderSelector getCertificateHolderSelector(X509CertSelector certSelector) { try { if (certSelector.getSubjectKeyIdentifier() != null) { return new X509CertificateHolderSelector(X500Name.getInstance(certSelector.getIssuerAsBytes()), certSelector.getSerialNumber(), ASN1OctetString.getInstance(certSelector.getSubjectKeyIdentifier()).getOctets()); } else { return new X509CertificateHolderSelector(X500Name.getInstance(certSelector.getIssuerAsBytes()), certSelector.getSerialNumber()); } } catch (Exception e) { throw new IllegalArgumentException("conversion failed: " + e.toString()); } } } bouncycastle-1.49.orig/jdk1.3/org/bouncycastle/cert/ocsp/0000755000175000017500000000000012152033550022602 5ustar ebourgebourgbouncycastle-1.49.orig/jdk1.3/org/bouncycastle/cert/ocsp/jcajce/0000755000175000017500000000000012152033550024021 5ustar ebourgebourgbouncycastle-1.49.orig/jdk1.3/org/bouncycastle/cert/ocsp/jcajce/JcaRespID.java0000644000175000017500000000104711504501517026435 0ustar ebourgebourgpackage org.bouncycastle.cert.ocsp.jcajce; import java.security.PublicKey; import org.bouncycastle.asn1.x500.X500Name; import org.bouncycastle.asn1.x509.SubjectPublicKeyInfo; import org.bouncycastle.cert.ocsp.OCSPException; import org.bouncycastle.cert.ocsp.RespID; import org.bouncycastle.operator.DigestCalculator; public class JcaRespID extends RespID { public JcaRespID(PublicKey pubKey, DigestCalculator digCalc) throws OCSPException { super(SubjectPublicKeyInfo.getInstance(pubKey.getEncoded()), digCalc); } } bouncycastle-1.49.orig/jdk1.3/org/bouncycastle/cert/jcajce/0000755000175000017500000000000012152033550023055 5ustar ebourgebourgbouncycastle-1.49.orig/jdk1.3/org/bouncycastle/cert/jcajce/JcaCertStoreBuilder.java0000644000175000017500000001024312132666220027563 0ustar ebourgebourgpackage org.bouncycastle.cert.jcajce; import java.security.GeneralSecurityException; import java.security.InvalidAlgorithmParameterException; import java.security.NoSuchAlgorithmException; import java.security.NoSuchProviderException; import java.security.Provider; import java.security.cert.CRLException; import org.bouncycastle.jce.cert.CertStore; import java.security.cert.CertificateException; import org.bouncycastle.jce.cert.CollectionCertStoreParameters; import java.util.ArrayList; import java.util.Iterator; import java.util.List; import org.bouncycastle.cert.X509CRLHolder; import org.bouncycastle.cert.X509CertificateHolder; import org.bouncycastle.util.Store; /** * Builder to create a CertStore from certificate and CRL stores. */ public class JcaCertStoreBuilder { private List certs = new ArrayList(); private List crls = new ArrayList(); private Object provider; private JcaX509CertificateConverter certificateConverter = new JcaX509CertificateConverter(); private JcaX509CRLConverter crlConverter = new JcaX509CRLConverter(); private String type = "Collection"; /** * Add a store full of X509CertificateHolder objects. * * @param certStore a store of X509CertificateHolder objects. */ public JcaCertStoreBuilder addCertificates(Store certStore) { certs.addAll(certStore.getMatches(null)); return this; } /** * Add a single certificate. * * @param cert the X509 certificate holder containing the certificate. */ public JcaCertStoreBuilder addCertificate(X509CertificateHolder cert) { certs.add(cert); return this; } /** * Add a store full of X509CRLHolder objects. * @param crlStore a store of X509CRLHolder objects. */ public JcaCertStoreBuilder addCRLs(Store crlStore) { crls.addAll(crlStore.getMatches(null)); return this; } /** * Add a single CRL. * * @param crl the X509 CRL holder containing the CRL. */ public JcaCertStoreBuilder addCRL(X509CRLHolder crl) { crls.add(crl); return this; } public JcaCertStoreBuilder setProvider(String providerName) { certificateConverter.setProvider(providerName); crlConverter.setProvider(providerName); this.provider = providerName; return this; } public JcaCertStoreBuilder setProvider(Provider provider) { certificateConverter.setProvider(provider); crlConverter.setProvider(provider); this.provider = provider; return this; } /** * Set the type of the CertStore generated. By default it is "Collection". * * @param type type of CertStore passed to CertStore.getInstance(). * @return the current builder. */ public JcaCertStoreBuilder setType(String type) { this.type = type; return this; } /** * Build the CertStore from the current inputs. * * @return a CertStore. * @throws GeneralSecurityException */ public CertStore build() throws GeneralSecurityException { CollectionCertStoreParameters params = convertHolders(certificateConverter, crlConverter); if (provider instanceof String) { return CertStore.getInstance(type, params, (String)provider); } if (provider instanceof Provider) { return CertStore.getInstance(type, params, (Provider)provider); } return CertStore.getInstance(type, params); } private CollectionCertStoreParameters convertHolders(JcaX509CertificateConverter certificateConverter, JcaX509CRLConverter crlConverter) throws CertificateException, CRLException { List jcaObjs = new ArrayList(certs.size() + crls.size()); for (Iterator it = certs.iterator(); it.hasNext();) { jcaObjs.add(certificateConverter.getCertificate((X509CertificateHolder)it.next())); } for (Iterator it = crls.iterator(); it.hasNext();) { jcaObjs.add(crlConverter.getCRL((X509CRLHolder)it.next())); } return new CollectionCertStoreParameters(jcaObjs); } } bouncycastle-1.49.orig/jdk1.3/org/bouncycastle/cert/jcajce/JcaX500NameUtil.java0000644000175000017500000000252011730542775026447 0ustar ebourgebourgpackage org.bouncycastle.cert.jcajce; import java.security.cert.X509Certificate; import org.bouncycastle.asn1.x500.X500Name; import org.bouncycastle.asn1.x500.X500NameStyle; import org.bouncycastle.jce.PrincipalUtil; public class JcaX500NameUtil { public static X500Name getIssuer(X509Certificate certificate) { try { return X500Name.getInstance(PrincipalUtil.getIssuerX509Principal(certificate).getEncoded()); } catch (Exception e) { throw new IllegalStateException(e.toString()); } } public static X500Name getSubject(X509Certificate certificate) { try { return X500Name.getInstance(PrincipalUtil.getSubjectX509Principal(certificate).getEncoded()); } catch (Exception e) { throw new IllegalStateException(e.toString()); } } public static X500Name getIssuer(X500NameStyle style, X509Certificate certificate) { try { return X500Name.getInstance(style, PrincipalUtil.getIssuerX509Principal(certificate).getEncoded()); } catch (Exception e) { throw new IllegalStateException(e.toString()); } } public static X500Name getSubject(X500NameStyle style, X509Certificate certificate) { try { return X500Name.getInstance(style, PrincipalUtil.getSubjectX509Principal(certificate).getEncoded()); } catch (Exception e) { throw new IllegalStateException(e.toString()); } } } bouncycastle-1.49.orig/jdk1.3/org/bouncycastle/cert/jcajce/JcaX509v3CertificateBuilder.java0000644000175000017500000000413211504501516030730 0ustar ebourgebourgpackage org.bouncycastle.cert.jcajce; import java.math.BigInteger; import java.security.PublicKey; import java.security.cert.CertificateEncodingException; import java.security.cert.X509Certificate; import java.util.Date; import org.bouncycastle.asn1.ASN1ObjectIdentifier; import org.bouncycastle.asn1.x500.X500Name; import org.bouncycastle.asn1.x509.SubjectPublicKeyInfo; import org.bouncycastle.cert.X509v3CertificateBuilder; /** * JCA helper class to allow JCA objects to be used in the construction of a Version 3 certificate. */ public class JcaX509v3CertificateBuilder extends X509v3CertificateBuilder { /** * Initialise the builder using a PublicKey. * * @param issuer X500Name representing the issuer of this certificate. * @param serial the serial number for the certificate. * @param notBefore date before which the certificate is not valid. * @param notAfter date after which the certificate is not valid. * @param subject X500Name representing the subject of this certificate. * @param publicKey the public key to be associated with the certificate. */ public JcaX509v3CertificateBuilder(X500Name issuer, BigInteger serial, Date notBefore, Date notAfter, X500Name subject, PublicKey publicKey) { super(issuer, serial, notBefore, notAfter, subject, SubjectPublicKeyInfo.getInstance(publicKey.getEncoded())); } /** * Add a given extension field for the standard extensions tag (tag 3) * copying the extension value from another certificate. * * @param oid the type of the extension to be copied. * @param critical true if the extension is to be marked critical, false otherwise. * @param certificate the source of the extension to be copied. * @return the builder instance. */ public JcaX509v3CertificateBuilder copyAndAddExtension( ASN1ObjectIdentifier oid, boolean critical, X509Certificate certificate) throws CertificateEncodingException { this.copyAndAddExtension(oid, critical, new JcaX509CertificateHolder(certificate)); return this; } } bouncycastle-1.49.orig/jdk1.3/org/bouncycastle/cert/jcajce/JcaX509v2CRLBuilder.java0000644000175000017500000000047711504501516027135 0ustar ebourgebourgpackage org.bouncycastle.cert.jcajce; import java.util.Date; import org.bouncycastle.asn1.x500.X500Name; import org.bouncycastle.cert.X509v2CRLBuilder; public class JcaX509v2CRLBuilder extends X509v2CRLBuilder { public JcaX509v2CRLBuilder(X500Name issuer, Date now) { super(issuer, now); } } bouncycastle-1.49.orig/jdk1.3/org/bouncycastle/cert/jcajce/ProviderCertHelper.java0000644000175000017500000000133611504501516027475 0ustar ebourgebourgpackage org.bouncycastle.cert.jcajce; import java.security.Provider; import java.security.NoSuchProviderException; import java.security.cert.CertificateException; import java.security.cert.CertificateFactory; class ProviderCertHelper extends CertHelper { private final Provider provider; ProviderCertHelper(Provider provider) { this.provider = provider; } protected CertificateFactory createCertificateFactory(String type) throws CertificateException { try { return CertificateFactory.getInstance(type, provider.getName()); } catch (NoSuchProviderException e) { throw new CertificateException(e.toString()); } } } bouncycastle-1.49.orig/jdk1.3/org/bouncycastle/cert/jcajce/JcaX509v1CertificateBuilder.java0000644000175000017500000000234211504501516030727 0ustar ebourgebourgpackage org.bouncycastle.cert.jcajce; import java.math.BigInteger; import java.security.PublicKey; import java.util.Date; import org.bouncycastle.asn1.x500.X500Name; import org.bouncycastle.asn1.x509.SubjectPublicKeyInfo; import org.bouncycastle.cert.X509v1CertificateBuilder; /** * JCA helper class to allow JCA objects to be used in the construction of a Version 1 certificate. */ public class JcaX509v1CertificateBuilder extends X509v1CertificateBuilder { /** * Initialise the builder using a PublicKey. * * @param issuer X500Name representing the issuer of this certificate. * @param serial the serial number for the certificate. * @param notBefore date before which the certificate is not valid. * @param notAfter date after which the certificate is not valid. * @param subject X500Name representing the subject of this certificate. * @param publicKey the public key to be associated with the certificate. */ public JcaX509v1CertificateBuilder(X500Name issuer, BigInteger serial, Date notBefore, Date notAfter, X500Name subject, PublicKey publicKey) { super(issuer, serial, notBefore, notAfter, subject, SubjectPublicKeyInfo.getInstance(publicKey.getEncoded())); } } bouncycastle-1.49.orig/jdk1.3/org/bouncycastle/mail/0000755000175000017500000000000012152033550021623 5ustar ebourgebourgbouncycastle-1.49.orig/jdk1.3/org/bouncycastle/mail/smime/0000755000175000017500000000000012152033550022735 5ustar ebourgebourgbouncycastle-1.49.orig/jdk1.3/org/bouncycastle/mail/smime/SMIMESignedGenerator.java0000644000175000017500000011333711726307316027475 0ustar ebourgebourgpackage org.bouncycastle.mail.smime; import java.io.IOException; import java.io.OutputStream; import java.security.InvalidKeyException; import java.security.NoSuchAlgorithmException; import java.security.NoSuchProviderException; import java.security.PrivateKey; import java.security.Provider; import org.bouncycastle.jce.cert.CertStore; import org.bouncycastle.jce.cert.CertStoreException; import java.security.cert.X509Certificate; import java.util.ArrayList; import java.util.Collections; import java.util.Enumeration; import java.util.HashMap; import java.util.Iterator; import java.util.List; import java.util.Map; import java.util.Set; import java.util.TreeSet; import javax.activation.CommandMap; import javax.activation.MailcapCommandMap; import javax.mail.MessagingException; import javax.mail.Multipart; import javax.mail.internet.ContentType; import javax.mail.internet.MimeBodyPart; import javax.mail.internet.MimeMessage; import javax.mail.internet.MimeMultipart; import org.bouncycastle.asn1.ASN1ObjectIdentifier; import org.bouncycastle.asn1.cms.AttributeTable; import org.bouncycastle.asn1.cryptopro.CryptoProObjectIdentifiers; import org.bouncycastle.asn1.nist.NISTObjectIdentifiers; import org.bouncycastle.asn1.oiw.OIWObjectIdentifiers; import org.bouncycastle.asn1.pkcs.PKCSObjectIdentifiers; import org.bouncycastle.asn1.teletrust.TeleTrusTObjectIdentifiers; import org.bouncycastle.asn1.x9.X9ObjectIdentifiers; import org.bouncycastle.cms.CMSAlgorithm; import org.bouncycastle.cms.CMSException; import org.bouncycastle.cms.CMSSignedDataStreamGenerator; import org.bouncycastle.cms.SignerInfoGenerator; import org.bouncycastle.cms.SignerInformation; import org.bouncycastle.cms.SignerInformationStore; import org.bouncycastle.mail.smime.util.CRLFOutputStream; import org.bouncycastle.util.Store; import org.bouncycastle.x509.X509Store; /** * general class for generating a pkcs7-signature message. *

* A simple example of usage. * *

 *      X509Certificate signCert = ...
 *      KeyPair         signKP = ...
 *
 *      List certList = new ArrayList();
 *
 *      certList.add(signCert);
 *
 *      Store certs = new JcaCertStore(certList);
 *
 *      SMIMESignedGenerator gen = new SMIMESignedGenerator();
 *
 *      gen.addSignerInfoGenerator(new JcaSimpleSignerInfoGeneratorBuilder().setProvider("BC").build("SHA1withRSA", signKP.getPrivate(), signCert));
 *
 *      gen.addCertificates(certs);
 *
 *      MimeMultipart       smime = fact.generate(content);
 * 
*

* Note 1: if you are using this class with AS2 or some other protocol * that does not use "7bit" as the default content transfer encoding you * will need to use the constructor that allows you to specify the default * content transfer encoding, such as "binary". *

*

* Note 2: between RFC 3851 and RFC 5751 the values used in the micalg parameter * for signed messages changed. We will accept both, but the default is now to use * RFC 5751. In the event you are dealing with an older style system you will also need * to use a constructor that sets the micalgs table and call it with RFC3851_MICALGS. *

*/ public class SMIMESignedGenerator extends SMIMEGenerator { public static final String DIGEST_SHA1 = OIWObjectIdentifiers.idSHA1.getId(); public static final String DIGEST_MD5 = PKCSObjectIdentifiers.md5.getId(); public static final String DIGEST_SHA224 = NISTObjectIdentifiers.id_sha224.getId(); public static final String DIGEST_SHA256 = NISTObjectIdentifiers.id_sha256.getId(); public static final String DIGEST_SHA384 = NISTObjectIdentifiers.id_sha384.getId(); public static final String DIGEST_SHA512 = NISTObjectIdentifiers.id_sha512.getId(); public static final String DIGEST_GOST3411 = CryptoProObjectIdentifiers.gostR3411.getId(); public static final String DIGEST_RIPEMD128 = TeleTrusTObjectIdentifiers.ripemd128.getId(); public static final String DIGEST_RIPEMD160 = TeleTrusTObjectIdentifiers.ripemd160.getId(); public static final String DIGEST_RIPEMD256 = TeleTrusTObjectIdentifiers.ripemd256.getId(); public static final String ENCRYPTION_RSA = PKCSObjectIdentifiers.rsaEncryption.getId(); public static final String ENCRYPTION_DSA = X9ObjectIdentifiers.id_dsa_with_sha1.getId(); public static final String ENCRYPTION_ECDSA = X9ObjectIdentifiers.ecdsa_with_SHA1.getId(); public static final String ENCRYPTION_RSA_PSS = PKCSObjectIdentifiers.id_RSASSA_PSS.getId(); public static final String ENCRYPTION_GOST3410 = CryptoProObjectIdentifiers.gostR3410_94.getId(); public static final String ENCRYPTION_ECGOST3410 = CryptoProObjectIdentifiers.gostR3410_2001.getId(); private static final String CERTIFICATE_MANAGEMENT_CONTENT = "application/pkcs7-mime; name=smime.p7c; smime-type=certs-only"; private static final String DETACHED_SIGNATURE_TYPE = "application/pkcs7-signature; name=smime.p7s; smime-type=signed-data"; private static final String ENCAPSULATED_SIGNED_CONTENT_TYPE = "application/pkcs7-mime; name=smime.p7m; smime-type=signed-data"; public static final Map RFC3851_MICALGS; public static final Map RFC5751_MICALGS; public static final Map STANDARD_MICALGS; private static MailcapCommandMap addCommands(CommandMap cm) { MailcapCommandMap mc = (MailcapCommandMap)cm; mc.addMailcap("application/pkcs7-signature;; x-java-content-handler=org.bouncycastle.mail.smime.handlers.pkcs7_signature"); mc.addMailcap("application/pkcs7-mime;; x-java-content-handler=org.bouncycastle.mail.smime.handlers.pkcs7_mime"); mc.addMailcap("application/x-pkcs7-signature;; x-java-content-handler=org.bouncycastle.mail.smime.handlers.x_pkcs7_signature"); mc.addMailcap("application/x-pkcs7-mime;; x-java-content-handler=org.bouncycastle.mail.smime.handlers.x_pkcs7_mime"); mc.addMailcap("multipart/signed;; x-java-content-handler=org.bouncycastle.mail.smime.handlers.multipart_signed"); return mc; } static { CommandMap.setDefaultCommandMap(addCommands(CommandMap.getDefaultCommandMap())); Map stdMicAlgs = new HashMap(); stdMicAlgs.put(CMSAlgorithm.MD5, "md5"); stdMicAlgs.put(CMSAlgorithm.SHA1, "sha-1"); stdMicAlgs.put(CMSAlgorithm.SHA224, "sha-224"); stdMicAlgs.put(CMSAlgorithm.SHA256, "sha-256"); stdMicAlgs.put(CMSAlgorithm.SHA384, "sha-384"); stdMicAlgs.put(CMSAlgorithm.SHA512, "sha-512"); stdMicAlgs.put(CMSAlgorithm.GOST3411, "gostr3411-94"); RFC5751_MICALGS = Collections.unmodifiableMap(stdMicAlgs); Map oldMicAlgs = new HashMap(); oldMicAlgs.put(CMSAlgorithm.MD5, "md5"); oldMicAlgs.put(CMSAlgorithm.SHA1, "sha1"); oldMicAlgs.put(CMSAlgorithm.SHA224, "sha224"); oldMicAlgs.put(CMSAlgorithm.SHA256, "sha256"); oldMicAlgs.put(CMSAlgorithm.SHA384, "sha384"); oldMicAlgs.put(CMSAlgorithm.SHA512, "sha512"); oldMicAlgs.put(CMSAlgorithm.GOST3411, "gostr3411-94"); RFC3851_MICALGS = Collections.unmodifiableMap(oldMicAlgs); STANDARD_MICALGS = RFC5751_MICALGS; } private final String defaultContentTransferEncoding; private final Map micAlgs; private List _certStores = new ArrayList(); private List certStores = new ArrayList(); private List crlStores = new ArrayList(); private List attrCertStores = new ArrayList(); private List signerInfoGens = new ArrayList(); private List _signers = new ArrayList(); private List _oldSigners = new ArrayList(); private List _attributeCerts = new ArrayList(); private Map _digests = new HashMap(); /** * base constructor - default content transfer encoding 7bit */ public SMIMESignedGenerator() { this("7bit", STANDARD_MICALGS); } /** * base constructor - default content transfer encoding explicitly set * * @param defaultContentTransferEncoding new default to use. */ public SMIMESignedGenerator( String defaultContentTransferEncoding) { this(defaultContentTransferEncoding, STANDARD_MICALGS); } /** * base constructor - default content transfer encoding explicitly set * * @param micAlgs a map of ANS1ObjectIdentifiers to strings hash algorithm names. */ public SMIMESignedGenerator( Map micAlgs) { this("7bit", micAlgs); } /** * base constructor - default content transfer encoding explicitly set * * @param defaultContentTransferEncoding new default to use. * @param micAlgs a map of ANS1ObjectIdentifiers to strings hash algorithm names. */ public SMIMESignedGenerator( String defaultContentTransferEncoding, Map micAlgs) { this.defaultContentTransferEncoding = defaultContentTransferEncoding; this.micAlgs = micAlgs; } /** * add a signer - no attributes other than the default ones will be * provided here. * * @param key key to use to generate the signature * @param cert the public key certificate associated with the signer's key. * @param digestOID object ID of the digest algorithm to use. * @exception IllegalArgumentException any of the arguments are inappropriate * @deprecated use addSignerInfoGenerator() */ public void addSigner( PrivateKey key, X509Certificate cert, String digestOID) throws IllegalArgumentException { _signers.add(new Signer(key, cert, new ASN1ObjectIdentifier(digestOID), null, null)); } /** * add a signer - no attributes other than the default ones will be * provided here. * * @param key key to use to generate the signature * @param cert the public key certificate associated with the signer's key. * @param encryptionOID object ID of the digest ecnryption algorithm to use. * @param digestOID object ID of the digest algorithm to use. * @exception IllegalArgumentException any of the arguments are inappropriate * @deprecated use addSignerInfoGenerator() */ public void addSigner( PrivateKey key, X509Certificate cert, String encryptionOID, String digestOID) throws IllegalArgumentException { _signers.add(new Signer(key, cert, new ASN1ObjectIdentifier(encryptionOID), new ASN1ObjectIdentifier(digestOID), null, null)); } /** * Add a signer with extra signed/unsigned attributes or overrides * for the standard attributes. For example this method can be used to * explictly set default attributes such as the signing time. * * @param key key to use to generate the signature * @param cert the public key certificate associated with the signer's key. * @param digestOID object ID of the digest algorithm to use. * @param signedAttr signed attributes to be included in the signature. * @param unsignedAttr unsigned attribitues to be included. * @exception IllegalArgumentException any of the arguments are inappropriate * @deprecated use addSignerInfoGenerator() */ public void addSigner( PrivateKey key, X509Certificate cert, String digestOID, AttributeTable signedAttr, AttributeTable unsignedAttr) throws IllegalArgumentException { _signers.add(new Signer(key, cert, new ASN1ObjectIdentifier(digestOID), signedAttr, unsignedAttr)); } /** * Add a signer with extra signed/unsigned attributes or overrides * for the standard attributes and a digest encryption algorithm. For * example this method can be used to explictly set default attributes * such as the signing time. * * @param key key to use to generate the signature * @param cert the public key certificate associated with the signer's key. * @param encryptionOID the digest encryption algorithm OID. * @param digestOID object ID of the digest algorithm to use. * @param signedAttr signed attributes to be included in the signature. * @param unsignedAttr unsigned attribitues to be included. * @exception IllegalArgumentException any of the arguments are inappropriate * @deprecated use addSignerInfoGenerator() */ public void addSigner( PrivateKey key, X509Certificate cert, String encryptionOID, String digestOID, AttributeTable signedAttr, AttributeTable unsignedAttr) throws IllegalArgumentException { _signers.add(new Signer(key, cert, new ASN1ObjectIdentifier(encryptionOID), new ASN1ObjectIdentifier(digestOID), signedAttr, unsignedAttr)); } /** * Add a store of precalculated signers to the generator. * * @param signerStore store of signers */ public void addSigners( SignerInformationStore signerStore) { Iterator it = signerStore.getSigners().iterator(); while (it.hasNext()) { _oldSigners.add(it.next()); } } public void addSignerInfoGenerator(SignerInfoGenerator sigInfoGen) { signerInfoGens.add(sigInfoGen); } /** * add the certificates and CRLs contained in the given CertStore * to the pool that will be included in the encoded signature block. *

* Note: this assumes the CertStore will support null in the get * methods. *

* @param certStore CertStore containing the certificates and CRLs to be added. * @deprecated use addCertificates(Store) and addCRLs(Store) */ public void addCertificatesAndCRLs( CertStore certStore) throws CertStoreException, SMIMEException { _certStores.add(certStore); } public void addCertificates( Store certStore) { certStores.add(certStore); } public void addCRLs( Store crlStore) { crlStores.add(crlStore); } public void addAttributeCertificates( Store certStore) { attrCertStores.add(certStore); } /** * Add the attribute certificates contained in the passed in store to the * generator. * * @param store a store of Version 2 attribute certificates * @throws CMSException if an error occurse processing the store. * @deprecated use addAttributeCertificates(Store) */ public void addAttributeCertificates( X509Store store) throws CMSException { _attributeCerts.add(store); } private void addHashHeader( StringBuffer header, List signers) { int count = 0; // // build the hash header // Iterator it = signers.iterator(); Set micAlgSet = new TreeSet(); while (it.hasNext()) { Object signer = it.next(); ASN1ObjectIdentifier digestOID; if (signer instanceof Signer) { digestOID = ((Signer)signer).getDigestOID(); } else if (signer instanceof SignerInformation) { digestOID = ((SignerInformation)signer).getDigestAlgorithmID().getAlgorithm(); } else { digestOID = ((SignerInfoGenerator)signer).getDigestAlgorithm().getAlgorithm(); } String micAlg = (String)micAlgs.get(digestOID); if (micAlg == null) { micAlgSet.add("unknown"); } else { micAlgSet.add(micAlg); } } it = micAlgSet.iterator(); while (it.hasNext()) { String alg = (String)it.next(); if (count == 0) { if (micAlgSet.size() != 1) { header.append("; micalg=\""); } else { header.append("; micalg="); } } else { header.append(','); } header.append(alg); count++; } if (count != 0) { if (micAlgSet.size() != 1) { header.append('\"'); } } } /* * at this point we expect our body part to be well defined. */ private MimeMultipart make( MimeBodyPart content, Provider sigProvider) throws NoSuchAlgorithmException, SMIMEException { try { MimeBodyPart sig = new MimeBodyPart(); sig.setContent(new ContentSigner(content, false, sigProvider), DETACHED_SIGNATURE_TYPE); sig.addHeader("Content-Type", DETACHED_SIGNATURE_TYPE); sig.addHeader("Content-Disposition", "attachment; filename=\"smime.p7s\""); sig.addHeader("Content-Description", "S/MIME Cryptographic Signature"); sig.addHeader("Content-Transfer-Encoding", encoding); // // build the multipart header // StringBuffer header = new StringBuffer( "signed; protocol=\"application/pkcs7-signature\""); List allSigners = new ArrayList(_signers); allSigners.addAll(_oldSigners); allSigners.addAll(signerInfoGens); addHashHeader(header, allSigners); MimeMultipart mm = new MimeMultipart(header.toString()); mm.addBodyPart(content); mm.addBodyPart(sig); return mm; } catch (MessagingException e) { throw new SMIMEException("exception putting multi-part together.", e); } } private MimeMultipart make( MimeBodyPart content) throws SMIMEException { try { MimeBodyPart sig = new MimeBodyPart(); sig.setContent(new ContentSigner(content, false), DETACHED_SIGNATURE_TYPE); sig.addHeader("Content-Type", DETACHED_SIGNATURE_TYPE); sig.addHeader("Content-Disposition", "attachment; filename=\"smime.p7s\""); sig.addHeader("Content-Description", "S/MIME Cryptographic Signature"); sig.addHeader("Content-Transfer-Encoding", encoding); // // build the multipart header // StringBuffer header = new StringBuffer( "signed; protocol=\"application/pkcs7-signature\""); List allSigners = new ArrayList(_signers); allSigners.addAll(_oldSigners); allSigners.addAll(signerInfoGens); addHashHeader(header, allSigners); MimeMultipart mm = new MimeMultipart(header.toString()); mm.addBodyPart(content); mm.addBodyPart(sig); return mm; } catch (MessagingException e) { throw new SMIMEException("exception putting multi-part together.", e); } } /* * at this point we expect our body part to be well defined - generate with data in the signature */ private MimeBodyPart makeEncapsulated( MimeBodyPart content, Provider sigProvider) throws NoSuchAlgorithmException, SMIMEException { try { MimeBodyPart sig = new MimeBodyPart(); sig.setContent(new ContentSigner(content, true, sigProvider), ENCAPSULATED_SIGNED_CONTENT_TYPE); sig.addHeader("Content-Type", ENCAPSULATED_SIGNED_CONTENT_TYPE); sig.addHeader("Content-Disposition", "attachment; filename=\"smime.p7m\""); sig.addHeader("Content-Description", "S/MIME Cryptographic Signed Data"); sig.addHeader("Content-Transfer-Encoding", encoding); return sig; } catch (MessagingException e) { throw new SMIMEException("exception putting body part together.", e); } } /* * at this point we expect our body part to be well defined - generate with data in the signature */ private MimeBodyPart makeEncapsulated( MimeBodyPart content) throws SMIMEException { try { MimeBodyPart sig = new MimeBodyPart(); sig.setContent(new ContentSigner(content, true), ENCAPSULATED_SIGNED_CONTENT_TYPE); sig.addHeader("Content-Type", ENCAPSULATED_SIGNED_CONTENT_TYPE); sig.addHeader("Content-Disposition", "attachment; filename=\"smime.p7m\""); sig.addHeader("Content-Description", "S/MIME Cryptographic Signed Data"); sig.addHeader("Content-Transfer-Encoding", encoding); return sig; } catch (MessagingException e) { throw new SMIMEException("exception putting body part together.", e); } } /** * Return a map of oids and byte arrays representing the digests calculated on the content during * the last generate. * * @return a map of oids (as String objects) and byte[] representing digests. */ public Map getGeneratedDigests() { return new HashMap(_digests); } /** * generate a signed object that contains an SMIME Signed Multipart * object using the given provider. * @param content the MimeBodyPart to be signed. * @param sigProvider the provider to be used for the signature. * @return a Multipart containing the content and signature. * @throws NoSuchAlgorithmException if the required algorithms for the signature cannot be found. * @throws NoSuchProviderException if no provider can be found. * @throws SMIMEException if an exception occurs in processing the signature. * @deprecated use generate(MimeBodyPart) */ public MimeMultipart generate( MimeBodyPart content, String sigProvider) throws NoSuchAlgorithmException, NoSuchProviderException, SMIMEException { return make(makeContentBodyPart(content), SMIMEUtil.getProvider(sigProvider)); } /** * generate a signed object that contains an SMIME Signed Multipart * object using the given provider. * @param content the MimeBodyPart to be signed. * @param sigProvider the provider to be used for the signature. * @return a Multipart containing the content and signature. * @throws NoSuchAlgorithmException if the required algorithms for the signature cannot be found. * @throws SMIMEException if an exception occurs in processing the signature. */ public MimeMultipart generate( MimeBodyPart content, Provider sigProvider) throws NoSuchAlgorithmException, SMIMEException { return make(makeContentBodyPart(content), sigProvider); } /** * generate a signed object that contains an SMIME Signed Multipart * object using the given provider from the given MimeMessage * * @throws NoSuchAlgorithmException if the required algorithms for the signature cannot be found. * @throws NoSuchProviderException if no provider can be found. * @throws SMIMEException if an exception occurs in processing the signature. */ public MimeMultipart generate( MimeMessage message, String sigProvider) throws NoSuchAlgorithmException, NoSuchProviderException, SMIMEException { return generate(message, SMIMEUtil.getProvider(sigProvider)); } /** * generate a signed object that contains an SMIME Signed Multipart * object using the given provider from the given MimeMessage * * @throws NoSuchAlgorithmException if the required algorithms for the signature cannot be found. * @throws NoSuchProviderException if no provider can be found. * @throws SMIMEException if an exception occurs in processing the signature. */ public MimeMultipart generate( MimeMessage message, Provider sigProvider) throws NoSuchAlgorithmException, SMIMEException { try { message.saveChanges(); // make sure we're up to date. } catch (MessagingException e) { throw new SMIMEException("unable to save message", e); } return make(makeContentBodyPart(message), sigProvider); } public MimeMultipart generate( MimeBodyPart content) throws SMIMEException { return make(makeContentBodyPart(content)); } /** * generate a signed message with encapsulated content *

* Note: doing this is strongly not recommended as it means a * recipient of the message will have to be able to read the signature to read the * message. */ public MimeBodyPart generateEncapsulated( MimeBodyPart content) throws SMIMEException { return makeEncapsulated(makeContentBodyPart(content)); } /** * generate a signed message with encapsulated content *

* Note: doing this is strongly not recommended as it means a * recipient of the message will have to be able to read the signature to read the * message. * @deprecated use generateEncapsulated(content) */ public MimeBodyPart generateEncapsulated( MimeBodyPart content, String sigProvider) throws NoSuchAlgorithmException, NoSuchProviderException, SMIMEException { return makeEncapsulated(makeContentBodyPart(content), SMIMEUtil.getProvider(sigProvider)); } /** * generate a signed message with encapsulated content *

* Note: doing this is strongly not recommended as it means a * recipient of the message will have to be able to read the signature to read the * message. * @deprecated use generateEncapsulated(content) */ public MimeBodyPart generateEncapsulated( MimeBodyPart content, Provider sigProvider) throws NoSuchAlgorithmException, NoSuchProviderException, SMIMEException { return makeEncapsulated(makeContentBodyPart(content), sigProvider); } /** * generate a signed object that contains an SMIME Signed Multipart * object using the given provider from the given MimeMessage. *

* Note: doing this is strongly not recommended as it means a * recipient of the message will have to be able to read the signature to read the * message. * @deprecated use generateEncapsulated(content) */ public MimeBodyPart generateEncapsulated( MimeMessage message, String sigProvider) throws NoSuchAlgorithmException, NoSuchProviderException, SMIMEException { return generateEncapsulated(message, SMIMEUtil.getProvider(sigProvider)); } /** * generate a signed object that contains an SMIME Signed Multipart * object using the given provider from the given MimeMessage. *

* Note: doing this is strongly not recommended as it means a * recipient of the message will have to be able to read the signature to read the * message. * @deprecated use generateEncapsulated(content) */ public MimeBodyPart generateEncapsulated( MimeMessage message, Provider sigProvider) throws NoSuchAlgorithmException, SMIMEException { try { message.saveChanges(); // make sure we're up to date. } catch (MessagingException e) { throw new SMIMEException("unable to save message", e); } return makeEncapsulated(makeContentBodyPart(message), sigProvider); } /** * Creates a certificate management message which is like a signed message with no content * or signers but that still carries certificates and CRLs. * * @return a MimeBodyPart containing the certs and CRLs. * @deprecated use generateCertificateManagement() */ public MimeBodyPart generateCertificateManagement( String provider) throws SMIMEException, NoSuchProviderException { return generateCertificateManagement(SMIMEUtil.getProvider(provider)); } /** * Creates a certificate management message which is like a signed message with no content * or signers but that still carries certificates and CRLs. * * @return a MimeBodyPart containing the certs and CRLs. * @deprecated use generateCertificateManagement() */ public MimeBodyPart generateCertificateManagement( Provider provider) throws SMIMEException { try { MimeBodyPart sig = new MimeBodyPart(); sig.setContent(new ContentSigner(null, true, provider), CERTIFICATE_MANAGEMENT_CONTENT); sig.addHeader("Content-Type", CERTIFICATE_MANAGEMENT_CONTENT); sig.addHeader("Content-Disposition", "attachment; filename=\"smime.p7c\""); sig.addHeader("Content-Description", "S/MIME Certificate Management Message"); sig.addHeader("Content-Transfer-Encoding", encoding); return sig; } catch (MessagingException e) { throw new SMIMEException("exception putting body part together.", e); } } /** * Creates a certificate management message which is like a signed message with no content * or signers but that still carries certificates and CRLs. * * @return a MimeBodyPart containing the certs and CRLs. */ public MimeBodyPart generateCertificateManagement() throws SMIMEException { try { MimeBodyPart sig = new MimeBodyPart(); sig.setContent(new ContentSigner(null, true), CERTIFICATE_MANAGEMENT_CONTENT); sig.addHeader("Content-Type", CERTIFICATE_MANAGEMENT_CONTENT); sig.addHeader("Content-Disposition", "attachment; filename=\"smime.p7c\""); sig.addHeader("Content-Description", "S/MIME Certificate Management Message"); sig.addHeader("Content-Transfer-Encoding", encoding); return sig; } catch (MessagingException e) { throw new SMIMEException("exception putting body part together.", e); } } private class Signer { final PrivateKey key; final X509Certificate cert; final ASN1ObjectIdentifier encryptionOID; final ASN1ObjectIdentifier digestOID; final AttributeTable signedAttr; final AttributeTable unsignedAttr; Signer( PrivateKey key, X509Certificate cert, ASN1ObjectIdentifier digestOID, AttributeTable signedAttr, AttributeTable unsignedAttr) { this(key, cert, null, digestOID, signedAttr, unsignedAttr); } Signer( PrivateKey key, X509Certificate cert, ASN1ObjectIdentifier encryptionOID, ASN1ObjectIdentifier digestOID, AttributeTable signedAttr, AttributeTable unsignedAttr) { this.key = key; this.cert = cert; this.encryptionOID = encryptionOID; this.digestOID = digestOID; this.signedAttr = signedAttr; this.unsignedAttr = unsignedAttr; } public X509Certificate getCert() { return cert; } public ASN1ObjectIdentifier getEncryptionOID() { return encryptionOID; } public ASN1ObjectIdentifier getDigestOID() { return digestOID; } public PrivateKey getKey() { return key; } public AttributeTable getSignedAttr() { return signedAttr; } public AttributeTable getUnsignedAttr() { return unsignedAttr; } } private class ContentSigner implements SMIMEStreamingProcessor { private final MimeBodyPart content; private final boolean encapsulate; private final Provider provider; private final boolean noProvider; ContentSigner( MimeBodyPart content, boolean encapsulate, Provider provider) { this.content = content; this.encapsulate = encapsulate; this.provider = provider; this.noProvider = false; } ContentSigner( MimeBodyPart content, boolean encapsulate) { this.content = content; this.encapsulate = encapsulate; this.provider = null; this.noProvider = true; } protected CMSSignedDataStreamGenerator getGenerator() throws CMSException, CertStoreException, InvalidKeyException, NoSuchAlgorithmException, NoSuchProviderException { CMSSignedDataStreamGenerator gen = new CMSSignedDataStreamGenerator(); for (Iterator it = _certStores.iterator(); it.hasNext();) { gen.addCertificatesAndCRLs((CertStore)it.next()); } for (Iterator it = certStores.iterator(); it.hasNext();) { gen.addCertificates((Store)it.next()); } for (Iterator it = crlStores.iterator(); it.hasNext();) { gen.addCRLs((Store)it.next()); } for (Iterator it = attrCertStores.iterator(); it.hasNext();) { gen.addAttributeCertificates((Store)it.next()); } for (Iterator it = _attributeCerts.iterator(); it.hasNext();) { gen.addAttributeCertificates((X509Store)it.next()); } for (Iterator it = _signers.iterator(); it.hasNext();) { Signer signer = (Signer)it.next(); if (signer.getEncryptionOID() != null) { gen.addSigner(signer.getKey(), signer.getCert(), signer.getEncryptionOID().getId(), signer.getDigestOID().getId(), signer.getSignedAttr(), signer.getUnsignedAttr(), provider); } else { gen.addSigner(signer.getKey(), signer.getCert(), signer.getDigestOID().getId(), signer.getSignedAttr(), signer.getUnsignedAttr(), provider); } } for (Iterator it = signerInfoGens.iterator(); it.hasNext();) { gen.addSignerInfoGenerator((SignerInfoGenerator)it.next()); } gen.addSigners(new SignerInformationStore(_oldSigners)); return gen; } private void writeBodyPart( OutputStream out, MimeBodyPart bodyPart) throws IOException, MessagingException { if (bodyPart.getContent() instanceof Multipart) { Multipart mp = (Multipart)bodyPart.getContent(); ContentType contentType = new ContentType(mp.getContentType()); String boundary = "--" + contentType.getParameter("boundary"); SMIMEUtil.LineOutputStream lOut = new SMIMEUtil.LineOutputStream(out); Enumeration headers = bodyPart.getAllHeaderLines(); while (headers.hasMoreElements()) { lOut.writeln((String)headers.nextElement()); } lOut.writeln(); // CRLF separator SMIMEUtil.outputPreamble(lOut, bodyPart, boundary); for (int i = 0; i < mp.getCount(); i++) { lOut.writeln(boundary); writeBodyPart(out, (MimeBodyPart)mp.getBodyPart(i)); lOut.writeln(); // CRLF terminator } lOut.writeln(boundary + "--"); } else { if (SMIMEUtil.isCanonicalisationRequired(bodyPart, defaultContentTransferEncoding)) { out = new CRLFOutputStream(out); } bodyPart.writeTo(out); } } public void write(OutputStream out) throws IOException { try { CMSSignedDataStreamGenerator gen = getGenerator(); OutputStream signingStream = gen.open(out, encapsulate); if (content != null) { if (!encapsulate) { writeBodyPart(signingStream, content); } else { content.getDataHandler().setCommandMap(addCommands(CommandMap.getDefaultCommandMap())); content.writeTo(signingStream); } } signingStream.close(); _digests = gen.getGeneratedDigests(); } catch (MessagingException e) { throw new IOException(e.toString()); } catch (NoSuchAlgorithmException e) { throw new IOException(e.toString()); } catch (NoSuchProviderException e) { throw new IOException(e.toString()); } catch (CMSException e) { throw new IOException(e.toString()); } catch (InvalidKeyException e) { throw new IOException(e.toString()); } catch (CertStoreException e) { throw new IOException(e.toString()); } } } } bouncycastle-1.49.orig/jdk1.3/org/bouncycastle/i18n/0000755000175000017500000000000012152033550021460 5ustar ebourgebourgbouncycastle-1.49.orig/jdk1.3/org/bouncycastle/i18n/LocalizedMessage.java0000644000175000017500000003513210722253200025537 0ustar ebourgebourgpackage org.bouncycastle.i18n; import org.bouncycastle.i18n.filter.Filter; import org.bouncycastle.i18n.filter.TrustedInput; import org.bouncycastle.i18n.filter.UntrustedInput; import org.bouncycastle.i18n.filter.UntrustedUrlInput; import java.io.UnsupportedEncodingException; import java.text.DateFormat; import java.text.Format; import java.text.MessageFormat; import java.util.Locale; import java.util.MissingResourceException; import java.util.ResourceBundle; import java.util.TimeZone; public class LocalizedMessage { protected final String id; protected final String resource; // ISO-8859-1 is the default encoding public static final String DEFAULT_ENCODING = "ISO-8859-1"; protected String encoding = DEFAULT_ENCODING; protected FilteredArguments arguments; protected FilteredArguments extraArgs = null; protected Filter filter = null; protected ClassLoader loader = null; /** * Constructs a new LocalizedMessage using resource as the base name for the * RessourceBundle and id as the message bundle id the resource file. * @param resource base name of the resource file * @param id the id of the corresponding bundle in the resource file * @throws NullPointerException if resource or id is null */ public LocalizedMessage(String resource,String id) throws NullPointerException { if (resource == null || id == null) { throw new NullPointerException(); } this.id = id; this.resource = resource; arguments = new FilteredArguments(); } /** * Constructs a new LocalizedMessage using resource as the base name for the * RessourceBundle and id as the message bundle id the resource file. * @param resource base name of the resource file * @param id the id of the corresponding bundle in the resource file * @param encoding the encoding of the resource file * @throws NullPointerException if resource or id is null * @throws UnsupportedEncodingException if the encoding is not supported */ public LocalizedMessage(String resource,String id, String encoding) throws NullPointerException, UnsupportedEncodingException { if (resource == null || id == null) { throw new NullPointerException(); } this.id = id; this.resource = resource; arguments = new FilteredArguments(); this.encoding = encoding; } /** * Constructs a new LocalizedMessage using resource as the base name for the * RessourceBundle and id as the message bundle id the resource file. * @param resource base name of the resource file * @param id the id of the corresponding bundle in the resource file * @param arguments an array containing the arguments for the message * @throws NullPointerException if resource or id is null */ public LocalizedMessage(String resource, String id, Object[] arguments) throws NullPointerException { if (resource == null || id == null || arguments == null) { throw new NullPointerException(); } this.id = id; this.resource = resource; this.arguments = new FilteredArguments(arguments); } /** * Constructs a new LocalizedMessage using resource as the base name for the * RessourceBundle and id as the message bundle id the resource file. * @param resource base name of the resource file * @param id the id of the corresponding bundle in the resource file * @param encoding the encoding of the resource file * @param arguments an array containing the arguments for the message * @throws NullPointerException if resource or id is null * @throws UnsupportedEncodingException if the encoding is not supported */ public LocalizedMessage(String resource, String id, String encoding, Object[] arguments) throws NullPointerException, UnsupportedEncodingException { if (resource == null || id == null || arguments == null) { throw new NullPointerException(); } this.id = id; this.resource = resource; this.arguments = new FilteredArguments(arguments); this.encoding = encoding; } /** * Reads the entry id + "." + key from the resource file and returns a * formated message for the given Locale and TimeZone. * @param key second part of the entry id * @param loc the used {@link Locale} * @param timezone the used {@link TimeZone} * @return a Strng containing the localized message * @throws MissingEntryException if the resource file is not available or the entry does not exist. */ public String getEntry(String key,Locale loc, TimeZone timezone) throws MissingEntryException { String entry = id; if (key != null) { entry += "." + key; } try { ResourceBundle bundle; if (loader == null) { bundle = ResourceBundle.getBundle(resource,loc); } else { bundle = ResourceBundle.getBundle(resource, loc, loader); } String result = bundle.getString(entry); if (!encoding.equals(DEFAULT_ENCODING)) { result = new String(result.getBytes(DEFAULT_ENCODING), encoding); } if (!arguments.isEmpty()) { result = formatWithTimeZone(result,arguments.getFilteredArgs(loc),loc,timezone); } result = addExtraArgs(result, loc); return result; } catch (MissingResourceException mre) { throw new MissingEntryException("Can't find entry " + entry + " in resource file " + resource + ".", resource, entry, loc, loader != null ? loader : this.getClassLoader()); } catch (UnsupportedEncodingException use) { // should never occur - cause we already test this in the constructor throw new RuntimeException(use.toString()); } } protected String formatWithTimeZone( String template, Object[] arguments, Locale locale, TimeZone timezone) { MessageFormat mf = new MessageFormat(" "); mf.setLocale(locale); mf.applyPattern(template); if (!timezone.equals(TimeZone.getDefault())) { Format[] formats = mf.getFormats(); for (int i = 0; i < formats.length; i++) { if (formats[i] instanceof DateFormat) { DateFormat temp = (DateFormat) formats[i]; temp.setTimeZone(timezone); mf.setFormat(i,temp); } } } return mf.format(arguments); } protected String addExtraArgs(String msg, Locale locale) { if (extraArgs != null) { StringBuffer sb = new StringBuffer(msg); Object[] filteredArgs = extraArgs.getFilteredArgs(locale); for (int i = 0; i < filteredArgs.length; i++) { sb.append(filteredArgs[i]); } msg = sb.toString(); } return msg; } /** * Sets the {@link Filter} that is used to filter the arguments of this message * @param filter the {@link Filter} to use. null to disable filtering. */ public void setFilter(Filter filter) { arguments.setFilter(filter); if (extraArgs != null) { extraArgs.setFilter(filter); } this.filter = filter; } /** * Returns the current filter. * @return the current filter */ public Filter getFilter() { return filter; } /** * Set the {@link ClassLoader} which loads the resource files. If it is set to null * then the default {@link ClassLoader} is used. * @param loader the {@link ClassLoader} which loads the resource files */ public void setClassLoader(ClassLoader loader) { this.loader = loader; } /** * Returns the {@link ClassLoader} which loads the resource files or null * if the default ClassLoader is used. * @return the {@link ClassLoader} which loads the resource files */ public ClassLoader getClassLoader() { return loader; } /** * Returns the id of the message in the resource bundle. * @return the id of the message */ public String getId() { return id; } /** * Returns the name of the resource bundle for this message * @return name of the resource file */ public String getResource() { return resource; } /** * Returns an Object[] containing the message arguments. * @return the message arguments */ public Object[] getArguments() { return arguments.getArguments(); } /** * * @param extraArg */ public void setExtraArgument(Object extraArg) { setExtraArguments(new Object[] {extraArg}); } /** * * @param extraArgs */ public void setExtraArguments(Object[] extraArgs) { if (extraArgs != null) { this.extraArgs = new FilteredArguments(extraArgs); this.extraArgs.setFilter(filter); } else { this.extraArgs = null; } } /** * * @return */ public Object[] getExtraArgs() { return (extraArgs == null) ? null : extraArgs.getArguments(); } protected class FilteredArguments { protected static final int NO_FILTER = 0; protected static final int FILTER = 1; protected static final int FILTER_URL = 2; protected Filter filter = null; protected boolean[] isLocaleSpecific; protected int[] argFilterType; protected Object[] arguments; protected Object[] unpackedArgs; protected Object[] filteredArgs; FilteredArguments() { this(new Object[0]); } FilteredArguments(Object[] args) { this.arguments = args; this.unpackedArgs = new Object[args.length]; this.filteredArgs = new Object[args.length]; this.isLocaleSpecific = new boolean[args.length]; this.argFilterType = new int[args.length]; for (int i = 0; i < args.length; i++) { if (args[i] instanceof TrustedInput) { this.unpackedArgs[i] = ((TrustedInput) args[i]).getInput(); argFilterType[i] = NO_FILTER; } else if (args[i] instanceof UntrustedInput) { this.unpackedArgs[i] = ((UntrustedInput) args[i]).getInput(); if (args[i] instanceof UntrustedUrlInput) { argFilterType[i] = FILTER_URL; } else { argFilterType[i] = FILTER; } } else { this.unpackedArgs[i] = args[i]; argFilterType[i] = FILTER; } // locale specific this.isLocaleSpecific[i] = (this.unpackedArgs[i] instanceof LocaleString); } } public boolean isEmpty() { return unpackedArgs.length == 0; } public Object[] getArguments() { return arguments; } public Object[] getFilteredArgs(Locale locale) { Object[] result = new Object[unpackedArgs.length]; for (int i = 0; i < unpackedArgs.length; i++) { Object arg; if (filteredArgs[i] != null) { arg = filteredArgs[i]; } else { arg = unpackedArgs[i]; if (isLocaleSpecific[i]) { // get locale arg = ((LocaleString) arg).getLocaleString(locale); arg = filter(argFilterType[i], arg); } else { arg = filter(argFilterType[i], arg); filteredArgs[i] = arg; } } result[i] = arg; } return result; } private Object filter(int type, Object obj) { if (filter != null) { Object o = (null == obj) ? "null" : obj; switch (type) { case NO_FILTER: return o; case FILTER: return filter.doFilter(o.toString()); case FILTER_URL: return filter.doFilterUrl(o.toString()); default: return null; } } else { return obj; } } public Filter getFilter() { return filter; } public void setFilter(Filter filter) { if (filter != this.filter) { for (int i = 0; i < unpackedArgs.length; i++) { filteredArgs[i] = null; } } this.filter = filter; } } public String toString() { StringBuffer sb = new StringBuffer(); sb.append("Resource: \"").append(resource); sb.append("\" Id: \"").append(id).append("\""); sb.append(" Arguments: ").append(arguments.getArguments().length).append(" normal, ") .append(extraArgs.getArguments().length).append(" extra"); sb.append(" Encoding: ").append(encoding); sb.append(" ClassLoader: ").append(loader); return sb.toString(); } } bouncycastle-1.49.orig/jdk1.3/org/bouncycastle/i18n/MissingEntryException.java0000644000175000017500000000361610722253405026647 0ustar ebourgebourgpackage org.bouncycastle.i18n; import java.net.URL; import java.net.URLClassLoader; import java.util.Locale; public class MissingEntryException extends RuntimeException { protected final String resource; protected final String key; protected final ClassLoader loader; protected final Locale locale; private Throwable cause; private String debugMsg; public MissingEntryException(String message, String resource, String key, Locale locale, ClassLoader loader) { super(message); this.resource = resource; this.key = key; this.locale = locale; this.loader = loader; } public MissingEntryException(String message, Throwable cause, String resource, String key, Locale locale, ClassLoader loader) { super(message); this.cause = cause; this.resource = resource; this.key = key; this.locale = locale; this.loader = loader; } public Throwable getCause() { return cause; } public String getKey() { return key; } public String getResource() { return resource; } public ClassLoader getClassLoader() { return loader; } public Locale getLocale() { return locale; } public String getDebugMsg() { if (debugMsg == null) { debugMsg = "Can not find entry " + key + " in resource file " + resource + " for the locale " + locale + "."; if (loader instanceof URLClassLoader) { URL[] urls = ((URLClassLoader) loader).getURLs(); debugMsg += " The following entries in the classpath were searched: "; for (int i = 0; i != urls.length; i++) { debugMsg += urls[i] + " "; } } } return debugMsg; } } bouncycastle-1.49.orig/jdk1.3/org/bouncycastle/ocsp/0000755000175000017500000000000012152033550021645 5ustar ebourgebourgbouncycastle-1.49.orig/jdk1.3/org/bouncycastle/ocsp/OCSPUtil.java0000644000175000017500000002147411505036313024123 0ustar ebourgebourgpackage org.bouncycastle.ocsp; import org.bouncycastle.asn1.DERNull; import org.bouncycastle.asn1.DERObjectIdentifier; import org.bouncycastle.asn1.cryptopro.CryptoProObjectIdentifiers; import org.bouncycastle.asn1.nist.NISTObjectIdentifiers; import org.bouncycastle.asn1.pkcs.PKCSObjectIdentifiers; import org.bouncycastle.asn1.teletrust.TeleTrusTObjectIdentifiers; import org.bouncycastle.asn1.x509.AlgorithmIdentifier; import org.bouncycastle.asn1.x9.X9ObjectIdentifiers; import org.bouncycastle.util.Strings; import java.security.InvalidAlgorithmParameterException; import java.security.MessageDigest; import java.security.NoSuchAlgorithmException; import java.security.NoSuchProviderException; import java.security.Signature; import org.bouncycastle.jce.cert.CertStore; import org.bouncycastle.jce.cert.CertStoreParameters; import java.security.cert.CertificateException; import org.bouncycastle.jce.cert.CertificateFactory; import java.util.ArrayList; import java.util.Enumeration; import java.util.HashSet; import java.util.Hashtable; import java.util.Iterator; import java.util.List; import java.util.Set; class OCSPUtil { private static Hashtable algorithms = new Hashtable(); private static Hashtable oids = new Hashtable(); private static Set noParams = new HashSet(); static { algorithms.put("MD2WITHRSAENCRYPTION", PKCSObjectIdentifiers.md2WithRSAEncryption); algorithms.put("MD2WITHRSA", PKCSObjectIdentifiers.md2WithRSAEncryption); algorithms.put("MD5WITHRSAENCRYPTION", PKCSObjectIdentifiers.md5WithRSAEncryption); algorithms.put("MD5WITHRSA", PKCSObjectIdentifiers.md5WithRSAEncryption); algorithms.put("SHA1WITHRSAENCRYPTION", PKCSObjectIdentifiers.sha1WithRSAEncryption); algorithms.put("SHA1WITHRSA", PKCSObjectIdentifiers.sha1WithRSAEncryption); algorithms.put("SHA224WITHRSAENCRYPTION", PKCSObjectIdentifiers.sha224WithRSAEncryption); algorithms.put("SHA224WITHRSA", PKCSObjectIdentifiers.sha224WithRSAEncryption); algorithms.put("SHA256WITHRSAENCRYPTION", PKCSObjectIdentifiers.sha256WithRSAEncryption); algorithms.put("SHA256WITHRSA", PKCSObjectIdentifiers.sha256WithRSAEncryption); algorithms.put("SHA384WITHRSAENCRYPTION", PKCSObjectIdentifiers.sha384WithRSAEncryption); algorithms.put("SHA384WITHRSA", PKCSObjectIdentifiers.sha384WithRSAEncryption); algorithms.put("SHA512WITHRSAENCRYPTION", PKCSObjectIdentifiers.sha512WithRSAEncryption); algorithms.put("SHA512WITHRSA", PKCSObjectIdentifiers.sha512WithRSAEncryption); algorithms.put("RIPEMD160WITHRSAENCRYPTION", TeleTrusTObjectIdentifiers.rsaSignatureWithripemd160); algorithms.put("RIPEMD160WITHRSA", TeleTrusTObjectIdentifiers.rsaSignatureWithripemd160); algorithms.put("RIPEMD128WITHRSAENCRYPTION", TeleTrusTObjectIdentifiers.rsaSignatureWithripemd128); algorithms.put("RIPEMD128WITHRSA", TeleTrusTObjectIdentifiers.rsaSignatureWithripemd128); algorithms.put("RIPEMD256WITHRSAENCRYPTION", TeleTrusTObjectIdentifiers.rsaSignatureWithripemd256); algorithms.put("RIPEMD256WITHRSA", TeleTrusTObjectIdentifiers.rsaSignatureWithripemd256); algorithms.put("SHA1WITHDSA", X9ObjectIdentifiers.id_dsa_with_sha1); algorithms.put("DSAWITHSHA1", X9ObjectIdentifiers.id_dsa_with_sha1); algorithms.put("SHA224WITHDSA", NISTObjectIdentifiers.dsa_with_sha224); algorithms.put("SHA256WITHDSA", NISTObjectIdentifiers.dsa_with_sha256); algorithms.put("SHA1WITHECDSA", X9ObjectIdentifiers.ecdsa_with_SHA1); algorithms.put("ECDSAWITHSHA1", X9ObjectIdentifiers.ecdsa_with_SHA1); algorithms.put("SHA224WITHECDSA", X9ObjectIdentifiers.ecdsa_with_SHA224); algorithms.put("SHA256WITHECDSA", X9ObjectIdentifiers.ecdsa_with_SHA256); algorithms.put("SHA384WITHECDSA", X9ObjectIdentifiers.ecdsa_with_SHA384); algorithms.put("SHA512WITHECDSA", X9ObjectIdentifiers.ecdsa_with_SHA512); algorithms.put("GOST3411WITHGOST3410", CryptoProObjectIdentifiers.gostR3411_94_with_gostR3410_94); algorithms.put("GOST3411WITHGOST3410-94", CryptoProObjectIdentifiers.gostR3411_94_with_gostR3410_94); oids.put(PKCSObjectIdentifiers.md2WithRSAEncryption, "MD2WITHRSA"); oids.put(PKCSObjectIdentifiers.md5WithRSAEncryption, "MD5WITHRSA"); oids.put(PKCSObjectIdentifiers.sha1WithRSAEncryption, "SHA1WITHRSA"); oids.put(PKCSObjectIdentifiers.sha224WithRSAEncryption, "SHA224WITHRSA"); oids.put(PKCSObjectIdentifiers.sha256WithRSAEncryption, "SHA256WITHRSA"); oids.put(PKCSObjectIdentifiers.sha384WithRSAEncryption, "SHA384WITHRSA"); oids.put(PKCSObjectIdentifiers.sha512WithRSAEncryption, "SHA512WITHRSA"); oids.put(TeleTrusTObjectIdentifiers.rsaSignatureWithripemd160, "RIPEMD160WITHRSA"); oids.put(TeleTrusTObjectIdentifiers.rsaSignatureWithripemd128, "RIPEMD128WITHRSA"); oids.put(TeleTrusTObjectIdentifiers.rsaSignatureWithripemd256, "RIPEMD256WITHRSA"); oids.put(X9ObjectIdentifiers.id_dsa_with_sha1, "SHA1WITHDSA"); oids.put(NISTObjectIdentifiers.dsa_with_sha224, "SHA224WITHDSA"); oids.put(NISTObjectIdentifiers.dsa_with_sha256, "SHA256WITHDSA"); oids.put(X9ObjectIdentifiers.ecdsa_with_SHA1, "SHA1WITHECDSA"); oids.put(X9ObjectIdentifiers.ecdsa_with_SHA224, "SHA224WITHECDSA"); oids.put(X9ObjectIdentifiers.ecdsa_with_SHA256, "SHA256WITHECDSA"); oids.put(X9ObjectIdentifiers.ecdsa_with_SHA384, "SHA384WITHECDSA"); oids.put(X9ObjectIdentifiers.ecdsa_with_SHA512, "SHA512WITHECDSA"); oids.put(CryptoProObjectIdentifiers.gostR3411_94_with_gostR3410_94, "GOST3411WITHGOST3410"); // // According to RFC 3279, the ASN.1 encoding SHALL (id-dsa-with-sha1) or MUST (ecdsa-with-SHA*) omit the parameters field. // The parameters field SHALL be NULL for RSA based signature algorithms. // noParams.add(X9ObjectIdentifiers.ecdsa_with_SHA1); noParams.add(X9ObjectIdentifiers.ecdsa_with_SHA224); noParams.add(X9ObjectIdentifiers.ecdsa_with_SHA256); noParams.add(X9ObjectIdentifiers.ecdsa_with_SHA384); noParams.add(X9ObjectIdentifiers.ecdsa_with_SHA512); noParams.add(X9ObjectIdentifiers.id_dsa_with_sha1); noParams.add(NISTObjectIdentifiers.dsa_with_sha224); noParams.add(NISTObjectIdentifiers.dsa_with_sha256); } static DERObjectIdentifier getAlgorithmOID( String algorithmName) { algorithmName = Strings.toUpperCase(algorithmName); if (algorithms.containsKey(algorithmName)) { return (DERObjectIdentifier)algorithms.get(algorithmName); } return new DERObjectIdentifier(algorithmName); } static String getAlgorithmName( DERObjectIdentifier oid) { if (oids.containsKey(oid)) { return (String)oids.get(oid); } return oid.getId(); } static AlgorithmIdentifier getSigAlgID( DERObjectIdentifier sigOid) { if (noParams.contains(sigOid)) { return new AlgorithmIdentifier(sigOid); } else { return new AlgorithmIdentifier(sigOid, new DERNull()); } } static Iterator getAlgNames() { Enumeration e = algorithms.keys(); List l = new ArrayList(); while (e.hasMoreElements()) { l.add(e.nextElement()); } return l.iterator(); } static CertStore createCertStoreInstance(String type, CertStoreParameters params, String provider) throws InvalidAlgorithmParameterException, NoSuchAlgorithmException, NoSuchProviderException { if (provider == null) { return CertStore.getInstance(type, params); } return CertStore.getInstance(type, params, provider); } static MessageDigest createDigestInstance(String digestName, String provider) throws NoSuchAlgorithmException, NoSuchProviderException { if (provider == null) { return MessageDigest.getInstance(digestName); } return MessageDigest.getInstance(digestName, provider); } static Signature createSignatureInstance(String sigName, String provider) throws NoSuchAlgorithmException, NoSuchProviderException { if (provider == null) { return Signature.getInstance(sigName); } return Signature.getInstance(sigName, provider); } static CertificateFactory createX509CertificateFactory(String provider) throws CertificateException, NoSuchProviderException { if (provider == null) { return CertificateFactory.getInstance("X.509"); } return CertificateFactory.getInstance("X.509", provider); } } bouncycastle-1.49.orig/jdk1.3/org/bouncycastle/ocsp/RespID.java0000644000175000017500000000342511505036313023643 0ustar ebourgebourgpackage org.bouncycastle.ocsp; import java.security.MessageDigest; import java.security.PublicKey; import org.bouncycastle.jce.X509Principal; import org.bouncycastle.asn1.ASN1InputStream; import org.bouncycastle.asn1.ASN1OctetString; import org.bouncycastle.asn1.DEROctetString; import org.bouncycastle.asn1.ocsp.ResponderID; import org.bouncycastle.asn1.x500.X500Name; import org.bouncycastle.asn1.x509.SubjectPublicKeyInfo; /** * Carrier for a ResponderID. */ public class RespID { ResponderID id; public RespID( ResponderID id) { this.id = id; } public RespID( X509Principal name) { this.id = new ResponderID(X500Name.getInstance(name.getEncoded())); } public RespID( PublicKey key) throws OCSPException { try { // TODO Allow specification of a particular provider MessageDigest digest = OCSPUtil.createDigestInstance("SHA1", null); ASN1InputStream aIn = new ASN1InputStream(key.getEncoded()); SubjectPublicKeyInfo info = SubjectPublicKeyInfo.getInstance(aIn.readObject()); digest.update(info.getPublicKeyData().getBytes()); ASN1OctetString keyHash = new DEROctetString(digest.digest()); this.id = new ResponderID(keyHash); } catch (Exception e) { throw new OCSPException("problem creating ID: " + e, e); } } public ResponderID toASN1Object() { return id; } public boolean equals( Object o) { if (!(o instanceof RespID)) { return false; } RespID obj = (RespID)o; return id.equals(obj.id); } public int hashCode() { return id.hashCode(); } } bouncycastle-1.49.orig/jdk1.3/org/bouncycastle/ocsp/OCSPReqGenerator.java0000644000175000017500000002121211726307316025603 0ustar ebourgebourgpackage org.bouncycastle.ocsp; import java.io.ByteArrayOutputStream; import java.io.IOException; import java.security.GeneralSecurityException; import java.security.NoSuchProviderException; import java.security.PrivateKey; import java.security.SecureRandom; import java.security.cert.CertificateEncodingException; import java.security.cert.X509Certificate; import java.util.ArrayList; import java.util.Iterator; import java.util.List; import org.bouncycastle.asn1.ASN1EncodableVector; import org.bouncycastle.asn1.ASN1OutputStream; import org.bouncycastle.asn1.ASN1Primitive; import org.bouncycastle.asn1.ASN1Sequence; import org.bouncycastle.asn1.DERBitString; import org.bouncycastle.asn1.DERNull; import org.bouncycastle.asn1.DERObjectIdentifier; import org.bouncycastle.asn1.DERSequence; import org.bouncycastle.asn1.ocsp.OCSPRequest; import org.bouncycastle.asn1.ocsp.Request; import org.bouncycastle.asn1.ocsp.Signature; import org.bouncycastle.asn1.ocsp.TBSRequest; import org.bouncycastle.asn1.x509.AlgorithmIdentifier; import org.bouncycastle.asn1.x509.Extensions; import org.bouncycastle.asn1.x509.GeneralName; import org.bouncycastle.asn1.x509.X509CertificateStructure; import org.bouncycastle.asn1.x509.X509Extensions; import org.bouncycastle.jce.X509Principal; /** * @deprecated use classes in org.bouncycastle.cert.ocsp. */ public class OCSPReqGenerator { private List list = new ArrayList(); private GeneralName requestorName = null; private X509Extensions requestExtensions = null; private class RequestObject { CertificateID certId; X509Extensions extensions; public RequestObject( CertificateID certId, X509Extensions extensions) { this.certId = certId; this.extensions = extensions; } public Request toRequest() throws Exception { return new Request(certId.toASN1Object(), Extensions.getInstance(extensions)); } } /** * Add a request for the given CertificateID. * * @param certId certificate ID of interest */ public void addRequest( CertificateID certId) { list.add(new RequestObject(certId, null)); } /** * Add a request with extensions * * @param certId certificate ID of interest * @param singleRequestExtensions the extensions to attach to the request */ public void addRequest( CertificateID certId, X509Extensions singleRequestExtensions) { list.add(new RequestObject(certId, singleRequestExtensions)); } /** * Set the requestor name to the passed in X500Principal * * @param requestorName a X500Principal representing the requestor name. */ public void setRequestorName( X509Principal requestorName) { try { this.requestorName = new GeneralName(GeneralName.directoryName, new X509Principal(requestorName.getEncoded())); } catch (IOException e) { throw new IllegalArgumentException("cannot encode principal: " + e); } } public void setRequestorName( GeneralName requestorName) { this.requestorName = requestorName; } public void setRequestExtensions( X509Extensions requestExtensions) { this.requestExtensions = requestExtensions; } private OCSPReq generateRequest( DERObjectIdentifier signingAlgorithm, PrivateKey key, X509Certificate[] chain, String provider, SecureRandom random) throws OCSPException, NoSuchProviderException { Iterator it = list.iterator(); ASN1EncodableVector requests = new ASN1EncodableVector(); while (it.hasNext()) { try { requests.add(((RequestObject)it.next()).toRequest()); } catch (Exception e) { throw new OCSPException("exception creating Request", e); } } TBSRequest tbsReq = new TBSRequest(requestorName, new DERSequence(requests), requestExtensions); java.security.Signature sig = null; Signature signature = null; if (signingAlgorithm != null) { if (requestorName == null) { throw new OCSPException("requestorName must be specified if request is signed."); } try { sig = OCSPUtil.createSignatureInstance(signingAlgorithm.getId(), provider); if (random != null) { sig.initSign(key, random); } else { sig.initSign(key); } } catch (NoSuchProviderException e) { // TODO Why this special case? throw e; } catch (GeneralSecurityException e) { throw new OCSPException("exception creating signature: " + e, e); } DERBitString bitSig = null; try { ByteArrayOutputStream bOut = new ByteArrayOutputStream(); ASN1OutputStream aOut = new ASN1OutputStream(bOut); aOut.writeObject(tbsReq); sig.update(bOut.toByteArray()); bitSig = new DERBitString(sig.sign()); } catch (Exception e) { throw new OCSPException("exception processing TBSRequest: " + e, e); } AlgorithmIdentifier sigAlgId = new AlgorithmIdentifier(signingAlgorithm, new DERNull()); if (chain != null && chain.length > 0) { ASN1EncodableVector v = new ASN1EncodableVector(); try { for (int i = 0; i != chain.length; i++) { v.add(new X509CertificateStructure( (ASN1Sequence)ASN1Primitive.fromByteArray(chain[i].getEncoded()))); } } catch (IOException e) { throw new OCSPException("error processing certs", e); } catch (CertificateEncodingException e) { throw new OCSPException("error encoding certs", e); } signature = new Signature(sigAlgId, bitSig, new DERSequence(v)); } else { signature = new Signature(sigAlgId, bitSig); } } return new OCSPReq(new OCSPRequest(tbsReq, signature)); } /** * Generate an unsigned request * * @return the OCSPReq * @throws OCSPException */ public OCSPReq generate() throws OCSPException { try { return generateRequest(null, null, null, null, null); } catch (NoSuchProviderException e) { // // this shouldn't happen but... // throw new OCSPException("no provider! - " + e, e); } } public OCSPReq generate( String signingAlgorithm, PrivateKey key, X509Certificate[] chain, String provider) throws OCSPException, NoSuchProviderException, IllegalArgumentException { return generate(signingAlgorithm, key, chain, provider, null); } public OCSPReq generate( String signingAlgorithm, PrivateKey key, X509Certificate[] chain, String provider, SecureRandom random) throws OCSPException, NoSuchProviderException, IllegalArgumentException { if (signingAlgorithm == null) { throw new IllegalArgumentException("no signing algorithm specified"); } try { DERObjectIdentifier oid = OCSPUtil.getAlgorithmOID(signingAlgorithm); return generateRequest(oid, key, chain, provider, random); } catch (IllegalArgumentException e) { throw new IllegalArgumentException("unknown signing algorithm specified: " + signingAlgorithm); } } /** * Return an iterator of the signature names supported by the generator. * * @return an iterator containing recognised names. */ public Iterator getSignatureAlgNames() { return OCSPUtil.getAlgNames(); } } bouncycastle-1.49.orig/jdk1.3/org/bouncycastle/ocsp/OCSPReq.java0000644000175000017500000002672011702716272023744 0ustar ebourgebourgpackage org.bouncycastle.ocsp; import java.io.ByteArrayInputStream; import java.io.ByteArrayOutputStream; import java.io.IOException; import java.io.InputStream; import java.security.InvalidAlgorithmParameterException; import java.security.NoSuchAlgorithmException; import java.security.NoSuchProviderException; import java.security.PublicKey; import java.security.Signature; import java.security.cert.CertificateException; import java.security.cert.X509Certificate; import java.util.ArrayList; import java.util.Enumeration; import java.util.HashSet; import java.util.List; import java.util.Set; import org.bouncycastle.asn1.ASN1Encodable; import org.bouncycastle.asn1.ASN1Encoding; import org.bouncycastle.asn1.ASN1InputStream; import org.bouncycastle.asn1.ASN1ObjectIdentifier; import org.bouncycastle.asn1.ASN1OutputStream; import org.bouncycastle.asn1.ASN1Sequence; import org.bouncycastle.asn1.ocsp.OCSPRequest; import org.bouncycastle.asn1.ocsp.Request; import org.bouncycastle.asn1.x509.GeneralName; import org.bouncycastle.asn1.x509.X509Extension; import org.bouncycastle.asn1.x509.X509Extensions; import org.bouncycastle.jce.cert.CertStore; import org.bouncycastle.jce.cert.CertStoreParameters; import org.bouncycastle.jce.cert.CertificateFactory; import org.bouncycastle.jce.cert.CollectionCertStoreParameters; /** *

 * OCSPRequest     ::=     SEQUENCE {
 *       tbsRequest                  TBSRequest,
 *       optionalSignature   [0]     EXPLICIT Signature OPTIONAL }
 *
 *   TBSRequest      ::=     SEQUENCE {
 *       version             [0]     EXPLICIT Version DEFAULT v1,
 *       requestorName       [1]     EXPLICIT GeneralName OPTIONAL,
 *       requestList                 SEQUENCE OF Request,
 *       requestExtensions   [2]     EXPLICIT Extensions OPTIONAL }
 *
 *   Signature       ::=     SEQUENCE {
 *       signatureAlgorithm      AlgorithmIdentifier,
 *       signature               BIT STRING,
 *       certs               [0] EXPLICIT SEQUENCE OF Certificate OPTIONAL}
 *
 *   Version         ::=             INTEGER  {  v1(0) }
 *
 *   Request         ::=     SEQUENCE {
 *       reqCert                     CertID,
 *       singleRequestExtensions     [0] EXPLICIT Extensions OPTIONAL }
 *
 *   CertID          ::=     SEQUENCE {
 *       hashAlgorithm       AlgorithmIdentifier,
 *       issuerNameHash      OCTET STRING, -- Hash of Issuer's DN
 *       issuerKeyHash       OCTET STRING, -- Hash of Issuers public key
 *       serialNumber        CertificateSerialNumber }
 * 
*/ public class OCSPReq implements java.security.cert.X509Extension { private OCSPRequest req; public OCSPReq( OCSPRequest req) { this.req = req; } public OCSPReq( byte[] req) throws IOException { this(new ASN1InputStream(req)); } public OCSPReq( InputStream in) throws IOException { this(new ASN1InputStream(in)); } private OCSPReq( ASN1InputStream aIn) throws IOException { try { this.req = OCSPRequest.getInstance(aIn.readObject()); } catch (IllegalArgumentException e) { throw new IOException("malformed request: " + e.getMessage()); } catch (ClassCastException e) { throw new IOException("malformed request: " + e.getMessage()); } } /** * Return the DER encoding of the tbsRequest field. * @return DER encoding of tbsRequest * @throws OCSPException in the event of an encoding error. */ public byte[] getTBSRequest() throws OCSPException { try { return req.getTbsRequest().getEncoded(); } catch (IOException e) { throw new OCSPException("problem encoding tbsRequest", e); } } public int getVersion() { return req.getTbsRequest().getVersion().getValue().intValue() + 1; } public GeneralName getRequestorName() { return GeneralName.getInstance(req.getTbsRequest().getRequestorName()); } public Req[] getRequestList() { ASN1Sequence seq = req.getTbsRequest().getRequestList(); Req[] requests = new Req[seq.size()]; for (int i = 0; i != requests.length; i++) { requests[i] = new Req(Request.getInstance(seq.getObjectAt(i))); } return requests; } public X509Extensions getRequestExtensions() { return X509Extensions.getInstance(req.getTbsRequest().getRequestExtensions()); } /** * return the object identifier representing the signature algorithm */ public String getSignatureAlgOID() { if (!this.isSigned()) { return null; } return req.getOptionalSignature().getSignatureAlgorithm().getObjectId().getId(); } public byte[] getSignature() { if (!this.isSigned()) { return null; } return req.getOptionalSignature().getSignature().getBytes(); } private List getCertList( String provider) throws OCSPException, NoSuchProviderException { List certs = new ArrayList(); ByteArrayOutputStream bOut = new ByteArrayOutputStream(); ASN1OutputStream aOut = new ASN1OutputStream(bOut); CertificateFactory cf; try { cf = OCSPUtil.createX509CertificateFactory(provider); } catch (CertificateException ex) { throw new OCSPException("can't get certificate factory.", ex); } // // load the certificates if we have any // ASN1Sequence s = req.getOptionalSignature().getCerts(); if (s != null) { Enumeration e = s.getObjects(); while (e.hasMoreElements()) { try { aOut.writeObject((ASN1Encodable)e.nextElement()); certs.add(cf.generateCertificate( new ByteArrayInputStream(bOut.toByteArray()))); } catch (IOException ex) { throw new OCSPException( "can't re-encode certificate!", ex); } catch (CertificateException ex) { throw new OCSPException( "can't re-encode certificate!", ex); } bOut.reset(); } } return certs; } public X509Certificate[] getCerts( String provider) throws OCSPException, NoSuchProviderException { if (!this.isSigned()) { return null; } List certs = this.getCertList(provider); return (X509Certificate[])certs.toArray(new X509Certificate[certs.size()]); } /** * If the request is signed return a possibly empty CertStore containing the certificates in the * request. If the request is not signed the method returns null. * * @param type type of CertStore to return * @param provider provider to use * @return null if not signed, a CertStore otherwise * @throws NoSuchAlgorithmException * @throws NoSuchProviderException * @throws OCSPException */ public CertStore getCertificates( String type, String provider) throws NoSuchAlgorithmException, NoSuchProviderException, OCSPException { if (!this.isSigned()) { return null; } try { CertStoreParameters params = new CollectionCertStoreParameters(this.getCertList(provider)); return OCSPUtil.createCertStoreInstance(type, params, provider); } catch (InvalidAlgorithmParameterException e) { throw new OCSPException("can't setup the CertStore", e); } } /** * Return whether or not this request is signed. * * @return true if signed false otherwise. */ public boolean isSigned() { return req.getOptionalSignature() != null; } /** * verify the signature against the TBSRequest object we contain. */ public boolean verify( PublicKey key, String sigProvider) throws OCSPException, NoSuchProviderException { if (!this.isSigned()) { throw new OCSPException("attempt to verify signature on unsigned object"); } try { Signature signature = OCSPUtil.createSignatureInstance(this.getSignatureAlgOID(), sigProvider); signature.initVerify(key); ByteArrayOutputStream bOut = new ByteArrayOutputStream(); ASN1OutputStream aOut = new ASN1OutputStream(bOut); aOut.writeObject(req.getTbsRequest()); signature.update(bOut.toByteArray()); return signature.verify(this.getSignature()); } catch (NoSuchProviderException e) { // TODO Why this special case? throw e; } catch (Exception e) { throw new OCSPException("exception processing sig: " + e, e); } } /** * return the ASN.1 encoded representation of this object. */ public byte[] getEncoded() throws IOException { ByteArrayOutputStream bOut = new ByteArrayOutputStream(); ASN1OutputStream aOut = new ASN1OutputStream(bOut); aOut.writeObject(req); return bOut.toByteArray(); } /** * RFC 2650 doesn't specify any critical extensions so we return true * if any are encountered. * * @return true if any critical extensions are present. */ public boolean hasUnsupportedCriticalExtension() { Set extns = getCriticalExtensionOIDs(); if (extns != null && !extns.isEmpty()) { return true; } return false; } private Set getExtensionOIDs(boolean critical) { Set set = new HashSet(); X509Extensions extensions = this.getRequestExtensions(); if (extensions != null) { Enumeration e = extensions.oids(); while (e.hasMoreElements()) { ASN1ObjectIdentifier oid = (ASN1ObjectIdentifier)e.nextElement(); X509Extension ext = extensions.getExtension(oid); if (critical == ext.isCritical()) { set.add(oid.getId()); } } } return set; } public Set getCriticalExtensionOIDs() { return getExtensionOIDs(true); } public Set getNonCriticalExtensionOIDs() { return getExtensionOIDs(false); } public byte[] getExtensionValue(String oid) { X509Extensions exts = this.getRequestExtensions(); if (exts != null) { X509Extension ext = exts.getExtension(new ASN1ObjectIdentifier(oid)); if (ext != null) { try { return ext.getValue().getEncoded(ASN1Encoding.DER); } catch (Exception e) { throw new RuntimeException("error encoding " + e.toString()); } } } return null; } } bouncycastle-1.49.orig/jdk1.3/org/bouncycastle/ocsp/BasicOCSPResp.java0000644000175000017500000002344111726307316025066 0ustar ebourgebourgpackage org.bouncycastle.ocsp; import java.io.ByteArrayInputStream; import java.io.ByteArrayOutputStream; import java.io.IOException; import java.security.InvalidAlgorithmParameterException; import java.security.NoSuchAlgorithmException; import java.security.NoSuchProviderException; import java.security.PublicKey; import java.security.Signature; import org.bouncycastle.jce.cert.CertStore; import org.bouncycastle.jce.cert.CertStoreParameters; import java.security.cert.CertificateException; import org.bouncycastle.jce.cert.CertificateFactory; import org.bouncycastle.jce.cert.CollectionCertStoreParameters; import java.security.cert.X509Certificate; import java.text.ParseException; import java.util.ArrayList; import java.util.Date; import java.util.Enumeration; import java.util.HashSet; import java.util.List; import java.util.Set; import org.bouncycastle.asn1.ASN1Encodable; import org.bouncycastle.asn1.ASN1Encoding; import org.bouncycastle.asn1.ASN1OutputStream; import org.bouncycastle.asn1.ASN1Sequence; import org.bouncycastle.asn1.DERObjectIdentifier; import org.bouncycastle.asn1.ocsp.BasicOCSPResponse; import org.bouncycastle.asn1.ocsp.ResponseData; import org.bouncycastle.asn1.ocsp.SingleResponse; import org.bouncycastle.asn1.x509.X509Extension; import org.bouncycastle.asn1.x509.X509Extensions; /** *
 * BasicOCSPResponse       ::= SEQUENCE {
 *    tbsResponseData      ResponseData,
 *    signatureAlgorithm   AlgorithmIdentifier,
 *    signature            BIT STRING,
 *    certs                [0] EXPLICIT SEQUENCE OF Certificate OPTIONAL }
 * 
* * @deprecated use classes in org.bouncycastle.cert.ocsp. */ public class BasicOCSPResp implements java.security.cert.X509Extension { BasicOCSPResponse resp; ResponseData data; X509Certificate[] chain = null; public BasicOCSPResp( BasicOCSPResponse resp) { this.resp = resp; this.data = resp.getTbsResponseData(); } /** * Return the DER encoding of the tbsResponseData field. * @return DER encoding of tbsResponseData * @throws OCSPException in the event of an encoding error. */ public byte[] getTBSResponseData() throws OCSPException { try { return resp.getTbsResponseData().getEncoded(); } catch (IOException e) { throw new OCSPException("problem encoding tbsResponseData", e); } } public int getVersion() { return data.getVersion().getValue().intValue() + 1; } public RespID getResponderId() { return new RespID(data.getResponderID()); } public Date getProducedAt() { try { return data.getProducedAt().getDate(); } catch (ParseException e) { throw new IllegalStateException("ParseException:" + e.getMessage()); } } public SingleResp[] getResponses() { ASN1Sequence s = data.getResponses(); SingleResp[] rs = new SingleResp[s.size()]; for (int i = 0; i != rs.length; i++) { rs[i] = new SingleResp(SingleResponse.getInstance(s.getObjectAt(i))); } return rs; } public X509Extensions getResponseExtensions() { return X509Extensions.getInstance(data.getResponseExtensions()); } /** * RFC 2650 doesn't specify any critical extensions so we return true * if any are encountered. * * @return true if any critical extensions are present. */ public boolean hasUnsupportedCriticalExtension() { Set extns = getCriticalExtensionOIDs(); if (extns != null && !extns.isEmpty()) { return true; } return false; } private Set getExtensionOIDs(boolean critical) { Set set = new HashSet(); X509Extensions extensions = this.getResponseExtensions(); if (extensions != null) { Enumeration e = extensions.oids(); while (e.hasMoreElements()) { DERObjectIdentifier oid = (DERObjectIdentifier)e.nextElement(); X509Extension ext = extensions.getExtension(oid); if (critical == ext.isCritical()) { set.add(oid.getId()); } } } return set; } public Set getCriticalExtensionOIDs() { return getExtensionOIDs(true); } public Set getNonCriticalExtensionOIDs() { return getExtensionOIDs(false); } public byte[] getExtensionValue(String oid) { X509Extensions exts = this.getResponseExtensions(); if (exts != null) { X509Extension ext = exts.getExtension(new DERObjectIdentifier(oid)); if (ext != null) { try { return ext.getValue().getEncoded(ASN1Encoding.DER); } catch (Exception e) { throw new RuntimeException("error encoding " + e.toString()); } } } return null; } public String getSignatureAlgName() { return OCSPUtil.getAlgorithmName(resp.getSignatureAlgorithm().getObjectId()); } public String getSignatureAlgOID() { return resp.getSignatureAlgorithm().getObjectId().getId(); } /** * @deprecated RespData class is no longer required as all functionality is * available on this class. * @return the RespData object */ public RespData getResponseData() { return new RespData(resp.getTbsResponseData()); } public byte[] getSignature() { return resp.getSignature().getBytes(); } private List getCertList( String provider) throws OCSPException, NoSuchProviderException { List certs = new ArrayList(); ByteArrayOutputStream bOut = new ByteArrayOutputStream(); ASN1OutputStream aOut = new ASN1OutputStream(bOut); CertificateFactory cf; try { cf = OCSPUtil.createX509CertificateFactory(provider); } catch (CertificateException ex) { throw new OCSPException("can't get certificate factory.", ex); } // // load the certificates and revocation lists if we have any // ASN1Sequence s = resp.getCerts(); if (s != null) { Enumeration e = s.getObjects(); while (e.hasMoreElements()) { try { aOut.writeObject((ASN1Encodable)e.nextElement()); certs.add(cf.generateCertificate( new ByteArrayInputStream(bOut.toByteArray()))); } catch (IOException ex) { throw new OCSPException( "can't re-encode certificate!", ex); } catch (CertificateException ex) { throw new OCSPException( "can't re-encode certificate!", ex); } bOut.reset(); } } return certs; } public X509Certificate[] getCerts( String provider) throws OCSPException, NoSuchProviderException { List certs = getCertList(provider); return (X509Certificate[])certs.toArray(new X509Certificate[certs.size()]); } /** * Return the certificates, if any associated with the response. * @param type type of CertStore to create * @param provider provider to use * @return a CertStore, possibly empty * @throws NoSuchAlgorithmException * @throws NoSuchProviderException * @throws OCSPException */ public CertStore getCertificates( String type, String provider) throws NoSuchAlgorithmException, NoSuchProviderException, OCSPException { try { CertStoreParameters params = new CollectionCertStoreParameters(this.getCertList(provider)); return OCSPUtil.createCertStoreInstance(type, params, provider); } catch (InvalidAlgorithmParameterException e) { throw new OCSPException("can't setup the CertStore", e); } } /** * verify the signature against the tbsResponseData object we contain. */ public boolean verify( PublicKey key, String sigProvider) throws OCSPException, NoSuchProviderException { try { Signature signature = OCSPUtil.createSignatureInstance(this.getSignatureAlgName(), sigProvider); signature.initVerify(key); signature.update(resp.getTbsResponseData().getEncoded(ASN1Encoding.DER)); return signature.verify(this.getSignature()); } catch (NoSuchProviderException e) { // TODO Why this special case? throw e; } catch (Exception e) { throw new OCSPException("exception processing sig: " + e, e); } } /** * return the ASN.1 encoded representation of this object. */ public byte[] getEncoded() throws IOException { return resp.getEncoded(); } public boolean equals(Object o) { if (o == this) { return true; } if (!(o instanceof BasicOCSPResp)) { return false; } BasicOCSPResp r = (BasicOCSPResp)o; return resp.equals(r.resp); } public int hashCode() { return resp.hashCode(); } } bouncycastle-1.49.orig/jdk1.3/org/bouncycastle/cms/0000755000175000017500000000000012152033550021463 5ustar ebourgebourgbouncycastle-1.49.orig/jdk1.3/org/bouncycastle/cms/CMSSignedData.java0000644000175000017500000006434612132666220024715 0ustar ebourgebourgpackage org.bouncycastle.cms; import java.io.IOException; import java.io.InputStream; import java.io.OutputStream; import java.security.NoSuchAlgorithmException; import java.security.NoSuchProviderException; import java.security.Provider; import org.bouncycastle.jce.cert.CertStore; import org.bouncycastle.jce.cert.CertStoreException; import java.util.ArrayList; import java.util.Collection; import java.util.Iterator; import java.util.List; import java.util.Map; import org.bouncycastle.asn1.ASN1EncodableVector; import org.bouncycastle.asn1.ASN1InputStream; import org.bouncycastle.asn1.ASN1ObjectIdentifier; import org.bouncycastle.asn1.ASN1OctetString; import org.bouncycastle.asn1.ASN1Sequence; import org.bouncycastle.asn1.ASN1Set; import org.bouncycastle.asn1.BERSequence; import org.bouncycastle.asn1.DERSet; import org.bouncycastle.asn1.cms.ContentInfo; import org.bouncycastle.asn1.cms.SignedData; import org.bouncycastle.asn1.cms.SignerInfo; import org.bouncycastle.cert.jcajce.JcaCertStoreBuilder; import org.bouncycastle.operator.DefaultSignatureAlgorithmIdentifierFinder; import org.bouncycastle.operator.OperatorCreationException; import org.bouncycastle.operator.SignatureAlgorithmIdentifierFinder; import org.bouncycastle.util.Store; import org.bouncycastle.x509.NoSuchStoreException; import org.bouncycastle.x509.X509Store; /** * general class for handling a pkcs7-signature message. * * A simple example of usage - note, in the example below the validity of * the certificate isn't verified, just the fact that one of the certs * matches the given signer... * *
 *  Store                   certStore = s.getCertificates();
 *  SignerInformationStore  signers = s.getSignerInfos();
 *  Collection              c = signers.getSigners();
 *  Iterator                it = c.iterator();
 *  
 *  while (it.hasNext())
 *  {
 *      SignerInformation   signer = (SignerInformation)it.next();
 *      Collection          certCollection = certStore.getMatches(signer.getSID());
 *
 *      Iterator              certIt = certCollection.iterator();
 *      X509CertificateHolder cert = (X509CertificateHolder)certIt.next();
 *  
 *      if (signer.verify(new JcaSimpleSignerInfoVerifierBuilder().setProvider("BC").build(cert)))
 *      {
 *          verified++;
 *      }   
 *  }
 * 
*/ public class CMSSignedData { private static final CMSSignedHelper HELPER = CMSSignedHelper.INSTANCE; SignedData signedData; ContentInfo contentInfo; CMSTypedData signedContent; SignerInformationStore signerInfoStore; X509Store attributeStore; X509Store certificateStore; X509Store crlStore; private Map hashes; private CMSSignedData( CMSSignedData c) { this.signedData = c.signedData; this.contentInfo = c.contentInfo; this.signedContent = c.signedContent; this.signerInfoStore = c.signerInfoStore; } public CMSSignedData( byte[] sigBlock) throws CMSException { this(CMSUtils.readContentInfo(sigBlock)); } public CMSSignedData( CMSProcessable signedContent, byte[] sigBlock) throws CMSException { this(signedContent, CMSUtils.readContentInfo(sigBlock)); } /** * Content with detached signature, digests precomputed * * @param hashes a map of precomputed digests for content indexed by name of hash. * @param sigBlock the signature object. */ public CMSSignedData( Map hashes, byte[] sigBlock) throws CMSException { this(hashes, CMSUtils.readContentInfo(sigBlock)); } /** * base constructor - content with detached signature. * * @param signedContent the content that was signed. * @param sigData the signature object. */ public CMSSignedData( CMSProcessable signedContent, InputStream sigData) throws CMSException { this(signedContent, CMSUtils.readContentInfo(new ASN1InputStream(sigData))); } /** * base constructor - with encapsulated content */ public CMSSignedData( InputStream sigData) throws CMSException { this(CMSUtils.readContentInfo(sigData)); } public CMSSignedData( final CMSProcessable signedContent, ContentInfo sigData) throws CMSException { if (signedContent instanceof CMSTypedData) { this.signedContent = (CMSTypedData)signedContent; } else { this.signedContent = new CMSTypedData() { public ASN1ObjectIdentifier getContentType() { return signedData.getEncapContentInfo().getContentType(); } public void write(OutputStream out) throws IOException, CMSException { signedContent.write(out); } public Object getContent() { return signedContent.getContent(); } }; } this.contentInfo = sigData; this.signedData = getSignedData(); } public CMSSignedData( Map hashes, ContentInfo sigData) throws CMSException { this.hashes = hashes; this.contentInfo = sigData; this.signedData = getSignedData(); } public CMSSignedData( ContentInfo sigData) throws CMSException { this.contentInfo = sigData; this.signedData = getSignedData(); // // this can happen if the signed message is sent simply to send a // certificate chain. // if (signedData.getEncapContentInfo().getContent() != null) { this.signedContent = new CMSProcessableByteArray(signedData.getEncapContentInfo().getContentType(), ((ASN1OctetString)(signedData.getEncapContentInfo() .getContent())).getOctets()); } else { this.signedContent = null; } } private SignedData getSignedData() throws CMSException { try { return SignedData.getInstance(contentInfo.getContent()); } catch (ClassCastException e) { throw new CMSException("Malformed content.", e); } catch (IllegalArgumentException e) { throw new CMSException("Malformed content.", e); } } /** * Return the version number for this object */ public int getVersion() { return signedData.getVersion().getValue().intValue(); } /** * return the collection of signers that are associated with the * signatures for the message. */ public SignerInformationStore getSignerInfos() { if (signerInfoStore == null) { ASN1Set s = signedData.getSignerInfos(); List signerInfos = new ArrayList(); SignatureAlgorithmIdentifierFinder sigAlgFinder = new DefaultSignatureAlgorithmIdentifierFinder(); for (int i = 0; i != s.size(); i++) { SignerInfo info = SignerInfo.getInstance(s.getObjectAt(i)); ASN1ObjectIdentifier contentType = signedData.getEncapContentInfo().getContentType(); if (hashes == null) { signerInfos.add(new SignerInformation(info, contentType, signedContent, null)); } else { Object obj = hashes.keySet().iterator().next(); byte[] hash = (obj instanceof String) ? (byte[])hashes.get(info.getDigestAlgorithm().getAlgorithm().getId()) : (byte[])hashes.get(info.getDigestAlgorithm().getAlgorithm()); signerInfos.add(new SignerInformation(info, contentType, null, hash)); } } signerInfoStore = new SignerInformationStore(signerInfos); } return signerInfoStore; } /** * return a X509Store containing the attribute certificates, if any, contained * in this message. * * @param type type of store to create * @param provider name of provider to use * @return a store of attribute certificates * @exception NoSuchProviderException if the provider requested isn't available. * @exception NoSuchStoreException if the store type isn't available. * @exception CMSException if a general exception prevents creation of the X509Store * @deprecated use base Store returning method */ public X509Store getAttributeCertificates( String type, String provider) throws NoSuchStoreException, NoSuchProviderException, CMSException { return getAttributeCertificates(type, CMSUtils.getProvider(provider)); } /** * return a X509Store containing the attribute certificates, if any, contained * in this message. * * @param type type of store to create * @param provider provider to use * @return a store of attribute certificates * @exception NoSuchStoreException if the store type isn't available. * @exception CMSException if a general exception prevents creation of the X509Store * @deprecated use base Store returning method */ public X509Store getAttributeCertificates( String type, Provider provider) throws NoSuchStoreException, CMSException { if (attributeStore == null) { attributeStore = HELPER.createAttributeStore(type, provider, this.getAttributeCertificates()); } return attributeStore; } /** * return a X509Store containing the public key certificates, if any, contained * in this message. * * @param type type of store to create * @param provider name of provider to use * @return a store of public key certificates * @exception NoSuchProviderException if the provider requested isn't available. * @exception NoSuchStoreException if the store type isn't available. * @exception CMSException if a general exception prevents creation of the X509Store * @deprecated use base Store returning method */ public X509Store getCertificates( String type, String provider) throws NoSuchStoreException, NoSuchProviderException, CMSException { return getCertificates(type, CMSUtils.getProvider(provider)); } /** * return a X509Store containing the public key certificates, if any, contained * in this message. * * @param type type of store to create * @param provider provider to use * @return a store of public key certificates * @exception NoSuchStoreException if the store type isn't available. * @exception CMSException if a general exception prevents creation of the X509Store * @deprecated use base Store returning method */ public X509Store getCertificates( String type, Provider provider) throws NoSuchStoreException, CMSException { if (certificateStore == null) { certificateStore = HELPER.createCertificateStore(type, provider, this.getCertificates()); } return certificateStore; } /** * return a X509Store containing CRLs, if any, contained * in this message. * * @param type type of store to create * @param provider name of provider to use * @return a store of CRLs * @exception NoSuchProviderException if the provider requested isn't available. * @exception NoSuchStoreException if the store type isn't available. * @exception CMSException if a general exception prevents creation of the X509Store * @deprecated use base Store returning method */ public X509Store getCRLs( String type, String provider) throws NoSuchStoreException, NoSuchProviderException, CMSException { return getCRLs(type, CMSUtils.getProvider(provider)); } /** * return a X509Store containing CRLs, if any, contained * in this message. * * @param type type of store to create * @param provider provider to use * @return a store of CRLs * @exception NoSuchStoreException if the store type isn't available. * @exception CMSException if a general exception prevents creation of the X509Store * @deprecated use base Store returning method */ public X509Store getCRLs( String type, Provider provider) throws NoSuchStoreException, CMSException { if (crlStore == null) { crlStore = HELPER.createCRLsStore(type, provider, getCRLs()); } return crlStore; } /** * return a CertStore containing the certificates and CRLs associated with * this message. * * @exception NoSuchProviderException if the provider requested isn't available. * @exception NoSuchAlgorithmException if the cert store isn't available. * @exception CMSException if a general exception prevents creation of the CertStore * @deprecated use base Store returning method and org.bouncycastle.cert.jcajce.JcaCertStoreBuilder */ public CertStore getCertificatesAndCRLs( String type, String provider) throws NoSuchAlgorithmException, NoSuchProviderException, CMSException { return getCertificatesAndCRLs(type, CMSUtils.getProvider(provider)); } /** * return a CertStore containing the certificates and CRLs associated with * this message. * * @exception NoSuchAlgorithmException if the cert store isn't available. * @exception CMSException if a general exception prevents creation of the CertStore * @deprecated use base Store returning method and org.bouncycastle.cert.jcajce.JcaCertStoreBuilder */ public CertStore getCertificatesAndCRLs( String type, Provider provider) throws NoSuchAlgorithmException, CMSException { try { JcaCertStoreBuilder certStoreBuilder = new JcaCertStoreBuilder().setType(type); if (provider != null) { certStoreBuilder.setProvider(provider); } certStoreBuilder.addCertificates(this.getCertificates()); certStoreBuilder.addCRLs(this.getCRLs()); return certStoreBuilder.build(); } catch (NoSuchAlgorithmException e) { throw e; } catch (Exception e) { throw new CMSException("exception creating CertStore: " + e.getMessage(), e); } } /** * Return any X.509 certificate objects in this SignedData structure as a Store of X509CertificateHolder objects. * * @return a Store of X509CertificateHolder objects. */ public Store getCertificates() { return HELPER.getCertificates(signedData.getCertificates()); } /** * Return any X.509 CRL objects in this SignedData structure as a Store of X509CRLHolder objects. * * @return a Store of X509CRLHolder objects. */ public Store getCRLs() { return HELPER.getCRLs(signedData.getCRLs()); } /** * Return any X.509 attribute certificate objects in this SignedData structure as a Store of X509AttributeCertificateHolder objects. * * @return a Store of X509AttributeCertificateHolder objects. */ public Store getAttributeCertificates() { return HELPER.getAttributeCertificates(signedData.getCertificates()); } /** * Return any OtherRevocationInfo OtherRevInfo objects of the type indicated by otherRevocationInfoFormat in * this SignedData structure. * * @param otherRevocationInfoFormat OID of the format type been looked for. * * @return a Store of ASN1Encodable objects representing any objects of otherRevocationInfoFormat found. */ public Store getOtherRevocationInfo(ASN1ObjectIdentifier otherRevocationInfoFormat) { return HELPER.getOtherRevocationInfo(otherRevocationInfoFormat, signedData.getCRLs()); } /** * Return the a string representation of the OID associated with the * encapsulated content info structure carried in the signed data. * * @return the OID for the content type. */ public String getSignedContentTypeOID() { return signedData.getEncapContentInfo().getContentType().getId(); } public CMSTypedData getSignedContent() { return signedContent; } /** * return the ContentInfo * @deprecated use toASN1Structure() */ public ContentInfo getContentInfo() { return contentInfo; } /** * return the ContentInfo */ public ContentInfo toASN1Structure() { return contentInfo; } /** * return the ASN.1 encoded representation of this object. */ public byte[] getEncoded() throws IOException { return contentInfo.getEncoded(); } /** * Verify all the SignerInformation objects and their associated counter signatures attached * to this CMS SignedData object. * * @param verifierProvider a provider of SignerInformationVerifier objects. * @return true if all verify, false otherwise. * @throws CMSException if an exception occurs during the verification process. */ public boolean verifySignatures(SignerInformationVerifierProvider verifierProvider) throws CMSException { return verifySignatures(verifierProvider, false); } /** * Verify all the SignerInformation objects and optionally their associated counter signatures attached * to this CMS SignedData object. * * @param verifierProvider a provider of SignerInformationVerifier objects. * @param ignoreCounterSignatures if true don't check counter signatures. If false check counter signatures as well. * @return true if all verify, false otherwise. * @throws CMSException if an exception occurs during the verification process. */ public boolean verifySignatures(SignerInformationVerifierProvider verifierProvider, boolean ignoreCounterSignatures) throws CMSException { Collection signers = this.getSignerInfos().getSigners(); for (Iterator it = signers.iterator(); it.hasNext();) { SignerInformation signer = (SignerInformation)it.next(); try { SignerInformationVerifier verifier = verifierProvider.get(signer.getSID()); if (!signer.verify(verifier)) { return false; } if (!ignoreCounterSignatures) { Collection counterSigners = signer.getCounterSignatures().getSigners(); for (Iterator cIt = counterSigners.iterator(); cIt.hasNext();) { SignerInformation counterSigner = (SignerInformation)cIt.next(); SignerInformationVerifier counterVerifier = verifierProvider.get(signer.getSID()); if (!counterSigner.verify(counterVerifier)) { return false; } } } } catch (OperatorCreationException e) { throw new CMSException("failure in verifier provider: " + e.getMessage(), e); } } return true; } /** * Replace the SignerInformation store associated with this * CMSSignedData object with the new one passed in. You would * probably only want to do this if you wanted to change the unsigned * attributes associated with a signer, or perhaps delete one. * * @param signedData the signed data object to be used as a base. * @param signerInformationStore the new signer information store to use. * @return a new signed data object. */ public static CMSSignedData replaceSigners( CMSSignedData signedData, SignerInformationStore signerInformationStore) { // // copy // CMSSignedData cms = new CMSSignedData(signedData); // // replace the store // cms.signerInfoStore = signerInformationStore; // // replace the signers in the SignedData object // ASN1EncodableVector digestAlgs = new ASN1EncodableVector(); ASN1EncodableVector vec = new ASN1EncodableVector(); Iterator it = signerInformationStore.getSigners().iterator(); while (it.hasNext()) { SignerInformation signer = (SignerInformation)it.next(); digestAlgs.add(CMSSignedHelper.INSTANCE.fixAlgID(signer.getDigestAlgorithmID())); vec.add(signer.toASN1Structure()); } ASN1Set digests = new DERSet(digestAlgs); ASN1Set signers = new DERSet(vec); ASN1Sequence sD = (ASN1Sequence)signedData.signedData.toASN1Primitive(); vec = new ASN1EncodableVector(); // // signers are the last item in the sequence. // vec.add(sD.getObjectAt(0)); // version vec.add(digests); for (int i = 2; i != sD.size() - 1; i++) { vec.add(sD.getObjectAt(i)); } vec.add(signers); cms.signedData = SignedData.getInstance(new BERSequence(vec)); // // replace the contentInfo with the new one // cms.contentInfo = new ContentInfo(cms.contentInfo.getContentType(), cms.signedData); return cms; } /** * Replace the certificate and CRL information associated with this * CMSSignedData object with the new one passed in. * * @param signedData the signed data object to be used as a base. * @param certsAndCrls the new certificates and CRLs to be used. * @return a new signed data object. * @exception CMSException if there is an error processing the CertStore * @deprecated use method taking Store arguments. */ public static CMSSignedData replaceCertificatesAndCRLs( CMSSignedData signedData, CertStore certsAndCrls) throws CMSException { // // copy // CMSSignedData cms = new CMSSignedData(signedData); // // replace the certs and crls in the SignedData object // ASN1Set certs = null; ASN1Set crls = null; try { ASN1Set set = CMSUtils.createBerSetFromList(CMSUtils.getCertificatesFromStore(certsAndCrls)); if (set.size() != 0) { certs = set; } } catch (CertStoreException e) { throw new CMSException("error getting certs from certStore", e); } try { ASN1Set set = CMSUtils.createBerSetFromList(CMSUtils.getCRLsFromStore(certsAndCrls)); if (set.size() != 0) { crls = set; } } catch (CertStoreException e) { throw new CMSException("error getting crls from certStore", e); } // // replace the CMS structure. // cms.signedData = new SignedData(signedData.signedData.getDigestAlgorithms(), signedData.signedData.getEncapContentInfo(), certs, crls, signedData.signedData.getSignerInfos()); // // replace the contentInfo with the new one // cms.contentInfo = new ContentInfo(cms.contentInfo.getContentType(), cms.signedData); return cms; } /** * Replace the certificate and CRL information associated with this * CMSSignedData object with the new one passed in. * * @param signedData the signed data object to be used as a base. * @param certificates the new certificates to be used. * @param attrCerts the new attribute certificates to be used. * @param crls the new CRLs to be used. * @return a new signed data object. * @exception CMSException if there is an error processing the CertStore */ public static CMSSignedData replaceCertificatesAndCRLs( CMSSignedData signedData, Store certificates, Store attrCerts, Store crls) throws CMSException { // // copy // CMSSignedData cms = new CMSSignedData(signedData); // // replace the certs and crls in the SignedData object // ASN1Set certSet = null; ASN1Set crlSet = null; if (certificates != null || attrCerts != null) { List certs = new ArrayList(); if (certificates != null) { certs.addAll(CMSUtils.getCertificatesFromStore(certificates)); } if (attrCerts != null) { certs.addAll(CMSUtils.getAttributeCertificatesFromStore(attrCerts)); } ASN1Set set = CMSUtils.createBerSetFromList(certs); if (set.size() != 0) { certSet = set; } } if (crls != null) { ASN1Set set = CMSUtils.createBerSetFromList(CMSUtils.getCRLsFromStore(crls)); if (set.size() != 0) { crlSet = set; } } // // replace the CMS structure. // cms.signedData = new SignedData(signedData.signedData.getDigestAlgorithms(), signedData.signedData.getEncapContentInfo(), certSet, crlSet, signedData.signedData.getSignerInfos()); // // replace the contentInfo with the new one // cms.contentInfo = new ContentInfo(cms.contentInfo.getContentType(), cms.signedData); return cms; } } bouncycastle-1.49.orig/jdk1.3/org/bouncycastle/cms/CMSUtils.java0000644000175000017500000002530212132666220023777 0ustar ebourgebourgpackage org.bouncycastle.cms; import java.io.IOException; import java.io.InputStream; import java.io.OutputStream; import java.security.NoSuchProviderException; import java.security.Provider; import java.security.Security; import java.security.cert.CRLException; import org.bouncycastle.jce.cert.CertStore; import org.bouncycastle.jce.cert.CertStoreException; import java.security.cert.CertificateEncodingException; import java.security.cert.X509CRL; import java.security.cert.X509Certificate; import java.util.ArrayList; import java.util.Collection; import java.util.Iterator; import java.util.List; import org.bouncycastle.asn1.ASN1Encodable; import org.bouncycastle.asn1.ASN1EncodableVector; import org.bouncycastle.asn1.ASN1InputStream; import org.bouncycastle.asn1.ASN1ObjectIdentifier; import org.bouncycastle.asn1.ASN1Primitive; import org.bouncycastle.asn1.ASN1Set; import org.bouncycastle.asn1.BEROctetStringGenerator; import org.bouncycastle.asn1.BERSet; import org.bouncycastle.asn1.DERSet; import org.bouncycastle.asn1.DERTaggedObject; import org.bouncycastle.asn1.cms.CMSObjectIdentifiers; import org.bouncycastle.asn1.cms.ContentInfo; import org.bouncycastle.asn1.cms.IssuerAndSerialNumber; import org.bouncycastle.asn1.cms.OtherRecipientInfo; import org.bouncycastle.asn1.cms.OtherRevocationInfoFormat; import org.bouncycastle.asn1.ocsp.OCSPResponse; import org.bouncycastle.asn1.ocsp.OCSPResponseStatus; import org.bouncycastle.asn1.x509.Certificate; import org.bouncycastle.asn1.x509.CertificateList; import org.bouncycastle.asn1.x509.TBSCertificate; import org.bouncycastle.cert.X509AttributeCertificateHolder; import org.bouncycastle.cert.X509CRLHolder; import org.bouncycastle.cert.X509CertificateHolder; import org.bouncycastle.operator.DigestCalculator; import org.bouncycastle.util.Store; import org.bouncycastle.util.io.Streams; import org.bouncycastle.util.io.TeeInputStream; import org.bouncycastle.util.io.TeeOutputStream; class CMSUtils { static ContentInfo readContentInfo( byte[] input) throws CMSException { // enforce limit checking as from a byte array return readContentInfo(new ASN1InputStream(input)); } static ContentInfo readContentInfo( InputStream input) throws CMSException { // enforce some limit checking return readContentInfo(new ASN1InputStream(input)); } static List getCertificatesFromStore(CertStore certStore) throws CertStoreException, CMSException { List certs = new ArrayList(); try { for (Iterator it = certStore.getCertificates(null).iterator(); it.hasNext();) { X509Certificate c = (X509Certificate)it.next(); certs.add(Certificate.getInstance(ASN1Primitive.fromByteArray(c.getEncoded()))); } return certs; } catch (IllegalArgumentException e) { throw new CMSException("error processing certs", e); } catch (IOException e) { throw new CMSException("error processing certs", e); } catch (CertificateEncodingException e) { throw new CMSException("error encoding certs", e); } } static List getCertificatesFromStore(Store certStore) throws CMSException { List certs = new ArrayList(); try { for (Iterator it = certStore.getMatches(null).iterator(); it.hasNext();) { X509CertificateHolder c = (X509CertificateHolder)it.next(); certs.add(c.toASN1Structure()); } return certs; } catch (ClassCastException e) { throw new CMSException("error processing certs", e); } } static List getAttributeCertificatesFromStore(Store attrStore) throws CMSException { List certs = new ArrayList(); try { for (Iterator it = attrStore.getMatches(null).iterator(); it.hasNext();) { X509AttributeCertificateHolder attrCert = (X509AttributeCertificateHolder)it.next(); certs.add(new DERTaggedObject(false, 2, attrCert.toASN1Structure())); } return certs; } catch (ClassCastException e) { throw new CMSException("error processing certs", e); } } static List getCRLsFromStore(CertStore certStore) throws CertStoreException, CMSException { List crls = new ArrayList(); try { for (Iterator it = certStore.getCRLs(null).iterator(); it.hasNext();) { X509CRL c = (X509CRL)it.next(); crls.add(CertificateList.getInstance(ASN1Primitive.fromByteArray(c.getEncoded()))); } return crls; } catch (IllegalArgumentException e) { throw new CMSException("error processing crls", e); } catch (IOException e) { throw new CMSException("error processing crls", e); } catch (CRLException e) { throw new CMSException("error encoding crls", e); } } static List getCRLsFromStore(Store crlStore) throws CMSException { List certs = new ArrayList(); try { for (Iterator it = crlStore.getMatches(null).iterator(); it.hasNext();) { X509CRLHolder c = (X509CRLHolder)it.next(); certs.add(c.toASN1Structure()); } return certs; } catch (ClassCastException e) { throw new CMSException("error processing certs", e); } } static Collection getOthersFromStore(ASN1ObjectIdentifier otherRevocationInfoFormat, Store otherRevocationInfos) { List others = new ArrayList(); for (Iterator it = otherRevocationInfos.getMatches(null).iterator(); it.hasNext();) { ASN1Encodable info = (ASN1Encodable)it.next(); if (CMSObjectIdentifiers.id_ri_ocsp_response.equals(otherRevocationInfoFormat)) { OCSPResponse resp = OCSPResponse.getInstance(info); if (resp.getResponseStatus().getValue().intValue() != OCSPResponseStatus.SUCCESSFUL) { throw new IllegalArgumentException("cannot add unsuccessful OCSP response to CMS SignedData"); } } others.add(new DERTaggedObject(false, 1, new OtherRevocationInfoFormat(otherRevocationInfoFormat, info))); } return others; } static ASN1Set createBerSetFromList(List derObjects) { ASN1EncodableVector v = new ASN1EncodableVector(); for (Iterator it = derObjects.iterator(); it.hasNext();) { v.add((ASN1Encodable)it.next()); } return new BERSet(v); } static ASN1Set createDerSetFromList(List derObjects) { ASN1EncodableVector v = new ASN1EncodableVector(); for (Iterator it = derObjects.iterator(); it.hasNext();) { v.add((ASN1Encodable)it.next()); } return new DERSet(v); } static OutputStream createBEROctetOutputStream(OutputStream s, int tagNo, boolean isExplicit, int bufferSize) throws IOException { BEROctetStringGenerator octGen = new BEROctetStringGenerator(s, tagNo, isExplicit); if (bufferSize != 0) { return octGen.getOctetOutputStream(new byte[bufferSize]); } return octGen.getOctetOutputStream(); } static TBSCertificate getTBSCertificateStructure( X509Certificate cert) { try { return TBSCertificate.getInstance( ASN1Primitive.fromByteArray(cert.getTBSCertificate())); } catch (Exception e) { throw new IllegalArgumentException( "can't extract TBS structure from this cert"); } } static IssuerAndSerialNumber getIssuerAndSerialNumber(X509Certificate cert) { TBSCertificate tbsCert = getTBSCertificateStructure(cert); return new IssuerAndSerialNumber(tbsCert.getIssuer(), tbsCert.getSerialNumber().getValue()); } private static ContentInfo readContentInfo( ASN1InputStream in) throws CMSException { try { return ContentInfo.getInstance(in.readObject()); } catch (IOException e) { throw new CMSException("IOException reading content.", e); } catch (ClassCastException e) { throw new CMSException("Malformed content.", e); } catch (IllegalArgumentException e) { throw new CMSException("Malformed content.", e); } } public static byte[] streamToByteArray( InputStream in) throws IOException { return Streams.readAll(in); } public static byte[] streamToByteArray( InputStream in, int limit) throws IOException { return Streams.readAllLimited(in, limit); } public static Provider getProvider(String providerName) throws NoSuchProviderException { if (providerName != null) { Provider prov = Security.getProvider(providerName); if (prov != null) { return prov; } throw new NoSuchProviderException("provider " + providerName + " not found."); } return null; } static InputStream attachDigestsToInputStream(Collection digests, InputStream s) { InputStream result = s; Iterator it = digests.iterator(); while (it.hasNext()) { DigestCalculator digest = (DigestCalculator)it.next(); result = new TeeInputStream(result, digest.getOutputStream()); } return result; } static OutputStream attachSignersToOutputStream(Collection signers, OutputStream s) { OutputStream result = s; Iterator it = signers.iterator(); while (it.hasNext()) { SignerInfoGenerator signerGen = (SignerInfoGenerator)it.next(); result = getSafeTeeOutputStream(result, signerGen.getCalculatingOutputStream()); } return result; } static OutputStream getSafeOutputStream(OutputStream s) { return s == null ? new NullOutputStream() : s; } static OutputStream getSafeTeeOutputStream(OutputStream s1, OutputStream s2) { return s1 == null ? getSafeOutputStream(s2) : s2 == null ? getSafeOutputStream(s1) : new TeeOutputStream( s1, s2); } } bouncycastle-1.49.orig/jdk1.3/org/bouncycastle/cms/CMSEnvelopedHelper.java0000644000175000017500000002103012103632343025747 0ustar ebourgebourgpackage org.bouncycastle.cms; import java.io.FilterInputStream; import java.io.IOException; import java.io.InputStream; import java.security.NoSuchAlgorithmException; import java.security.NoSuchProviderException; import java.security.Provider; import java.util.ArrayList; import java.util.HashMap; import java.util.List; import java.util.Map; import javax.crypto.KeyGenerator; import org.bouncycastle.asn1.ASN1Encodable; import org.bouncycastle.asn1.ASN1Set; import org.bouncycastle.asn1.cms.KEKRecipientInfo; import org.bouncycastle.asn1.cms.KeyAgreeRecipientInfo; import org.bouncycastle.asn1.cms.KeyTransRecipientInfo; import org.bouncycastle.asn1.cms.PasswordRecipientInfo; import org.bouncycastle.asn1.cms.RecipientInfo; import org.bouncycastle.asn1.x509.AlgorithmIdentifier; import org.bouncycastle.operator.DigestCalculator; import org.bouncycastle.util.Integers; class CMSEnvelopedHelper { static final CMSEnvelopedHelper INSTANCE = new CMSEnvelopedHelper(); private static final Map KEYSIZES = new HashMap(); private static final Map BASE_CIPHER_NAMES = new HashMap(); private static final Map CIPHER_ALG_NAMES = new HashMap(); private static final Map MAC_ALG_NAMES = new HashMap(); static { KEYSIZES.put(CMSEnvelopedGenerator.DES_EDE3_CBC, Integers.valueOf(192)); KEYSIZES.put(CMSEnvelopedGenerator.AES128_CBC, Integers.valueOf(128)); KEYSIZES.put(CMSEnvelopedGenerator.AES192_CBC, Integers.valueOf(192)); KEYSIZES.put(CMSEnvelopedGenerator.AES256_CBC, Integers.valueOf(256)); BASE_CIPHER_NAMES.put(CMSEnvelopedGenerator.DES_EDE3_CBC, "DESEDE"); BASE_CIPHER_NAMES.put(CMSEnvelopedGenerator.AES128_CBC, "AES"); BASE_CIPHER_NAMES.put(CMSEnvelopedGenerator.AES192_CBC, "AES"); BASE_CIPHER_NAMES.put(CMSEnvelopedGenerator.AES256_CBC, "AES"); CIPHER_ALG_NAMES.put(CMSEnvelopedGenerator.DES_EDE3_CBC, "DESEDE/CBC/PKCS5Padding"); CIPHER_ALG_NAMES.put(CMSEnvelopedGenerator.AES128_CBC, "AES/CBC/PKCS5Padding"); CIPHER_ALG_NAMES.put(CMSEnvelopedGenerator.AES192_CBC, "AES/CBC/PKCS5Padding"); CIPHER_ALG_NAMES.put(CMSEnvelopedGenerator.AES256_CBC, "AES/CBC/PKCS5Padding"); MAC_ALG_NAMES.put(CMSEnvelopedGenerator.DES_EDE3_CBC, "DESEDEMac"); MAC_ALG_NAMES.put(CMSEnvelopedGenerator.AES128_CBC, "AESMac"); MAC_ALG_NAMES.put(CMSEnvelopedGenerator.AES192_CBC, "AESMac"); MAC_ALG_NAMES.put(CMSEnvelopedGenerator.AES256_CBC, "AESMac"); } KeyGenerator createSymmetricKeyGenerator( String encryptionOID, Provider provider) throws NoSuchAlgorithmException { try { return createKeyGenerator(encryptionOID, provider); } catch (NoSuchAlgorithmException e) { try { String algName = (String)BASE_CIPHER_NAMES.get(encryptionOID); if (algName != null) { return createKeyGenerator(algName, provider); } } catch (NoSuchAlgorithmException ex) { // ignore } if (provider != null) { return createSymmetricKeyGenerator(encryptionOID, null); } throw e; } } int getKeySize(String oid) { Integer keySize = (Integer)KEYSIZES.get(oid); if (keySize == null) { throw new IllegalArgumentException("no keysize for " + oid); } return keySize.intValue(); } private KeyGenerator createKeyGenerator( String algName, Provider provider) throws NoSuchAlgorithmException { if (provider != null) { try { return KeyGenerator.getInstance(algName, provider.getName()); } catch (NoSuchProviderException e) { throw new NoSuchAlgorithmException(e.toString()); } } else { return KeyGenerator.getInstance(algName); } } static RecipientInformationStore buildRecipientInformationStore( ASN1Set recipientInfos, AlgorithmIdentifier messageAlgorithm, CMSSecureReadable secureReadable) { return buildRecipientInformationStore(recipientInfos, messageAlgorithm, secureReadable, null); } static RecipientInformationStore buildRecipientInformationStore( ASN1Set recipientInfos, AlgorithmIdentifier messageAlgorithm, CMSSecureReadable secureReadable, AuthAttributesProvider additionalData) { List infos = new ArrayList(); for (int i = 0; i != recipientInfos.size(); i++) { RecipientInfo info = RecipientInfo.getInstance(recipientInfos.getObjectAt(i)); readRecipientInfo(infos, info, messageAlgorithm, secureReadable, additionalData); } return new RecipientInformationStore(infos); } private static void readRecipientInfo( List infos, RecipientInfo info, AlgorithmIdentifier messageAlgorithm, CMSSecureReadable secureReadable, AuthAttributesProvider additionalData) { ASN1Encodable recipInfo = info.getInfo(); if (recipInfo instanceof KeyTransRecipientInfo) { infos.add(new KeyTransRecipientInformation( (KeyTransRecipientInfo)recipInfo, messageAlgorithm, secureReadable, additionalData)); } else if (recipInfo instanceof KEKRecipientInfo) { infos.add(new KEKRecipientInformation( (KEKRecipientInfo)recipInfo, messageAlgorithm, secureReadable, additionalData)); } else if (recipInfo instanceof KeyAgreeRecipientInfo) { KeyAgreeRecipientInformation.readRecipientInfo(infos, (KeyAgreeRecipientInfo)recipInfo, messageAlgorithm, secureReadable, additionalData); } else if (recipInfo instanceof PasswordRecipientInfo) { infos.add(new PasswordRecipientInformation( (PasswordRecipientInfo)recipInfo, messageAlgorithm, secureReadable, additionalData)); } } static class CMSDigestAuthenticatedSecureReadable implements CMSSecureReadable { private DigestCalculator digestCalculator; private CMSReadable readable; public CMSDigestAuthenticatedSecureReadable(DigestCalculator digestCalculator, CMSReadable readable) { this.digestCalculator = digestCalculator; this.readable = readable; } public InputStream getInputStream() throws IOException, CMSException { return new FilterInputStream(readable.getInputStream()) { public int read() throws IOException { int b = in.read(); if (b >= 0) { digestCalculator.getOutputStream().write(b); } return b; } public int read(byte[] inBuf, int inOff, int inLen) throws IOException { int n = in.read(inBuf, inOff, inLen); if (n >= 0) { digestCalculator.getOutputStream().write(inBuf, inOff, n); } return n; } }; } public byte[] getDigest() { return digestCalculator.getDigest(); } } static class CMSAuthenticatedSecureReadable implements CMSSecureReadable { private AlgorithmIdentifier algorithm; private CMSReadable readable; CMSAuthenticatedSecureReadable(AlgorithmIdentifier algorithm, CMSReadable readable) { this.algorithm = algorithm; this.readable = readable; } public InputStream getInputStream() throws IOException, CMSException { return readable.getInputStream(); } } static class CMSEnvelopedSecureReadable implements CMSSecureReadable { private AlgorithmIdentifier algorithm; private CMSReadable readable; CMSEnvelopedSecureReadable(AlgorithmIdentifier algorithm, CMSReadable readable) { this.algorithm = algorithm; this.readable = readable; } public InputStream getInputStream() throws IOException, CMSException { return readable.getInputStream(); } } } bouncycastle-1.49.orig/jdk1.3/org/bouncycastle/cms/CMSSignedGenerator.java0000644000175000017500000003276212132666220025767 0ustar ebourgebourgpackage org.bouncycastle.cms; import java.io.IOException; import java.security.PrivateKey; import java.security.SecureRandom; import org.bouncycastle.jce.cert.CertStore; import org.bouncycastle.jce.cert.CertStoreException; import java.security.interfaces.DSAPrivateKey; import java.security.interfaces.RSAPrivateKey; import java.util.ArrayList; import java.util.HashMap; import java.util.HashSet; import java.util.Iterator; import java.util.List; import java.util.Map; import java.util.Set; import org.bouncycastle.asn1.ASN1Encodable; import org.bouncycastle.asn1.ASN1ObjectIdentifier; import org.bouncycastle.asn1.ASN1Primitive; import org.bouncycastle.asn1.ASN1Set; import org.bouncycastle.asn1.DERSet; import org.bouncycastle.asn1.DERTaggedObject; import org.bouncycastle.asn1.cms.AttributeTable; import org.bouncycastle.asn1.cms.CMSObjectIdentifiers; import org.bouncycastle.asn1.cms.OtherRevocationInfoFormat; import org.bouncycastle.asn1.cryptopro.CryptoProObjectIdentifiers; import org.bouncycastle.asn1.nist.NISTObjectIdentifiers; import org.bouncycastle.asn1.oiw.OIWObjectIdentifiers; import org.bouncycastle.asn1.pkcs.PKCSObjectIdentifiers; import org.bouncycastle.asn1.teletrust.TeleTrusTObjectIdentifiers; import org.bouncycastle.asn1.x509.AlgorithmIdentifier; import org.bouncycastle.asn1.x509.AttributeCertificate; import org.bouncycastle.asn1.x9.X9ObjectIdentifiers; import org.bouncycastle.cert.X509AttributeCertificateHolder; import org.bouncycastle.cert.X509CRLHolder; import org.bouncycastle.cert.X509CertificateHolder; import org.bouncycastle.jce.interfaces.GOST3410PrivateKey; import org.bouncycastle.util.Store; import org.bouncycastle.x509.X509AttributeCertificate; import org.bouncycastle.x509.X509Store; public class CMSSignedGenerator { /** * Default type for the signed data. */ public static final String DATA = CMSObjectIdentifiers.data.getId(); public static final String DIGEST_SHA1 = OIWObjectIdentifiers.idSHA1.getId(); public static final String DIGEST_SHA224 = NISTObjectIdentifiers.id_sha224.getId(); public static final String DIGEST_SHA256 = NISTObjectIdentifiers.id_sha256.getId(); public static final String DIGEST_SHA384 = NISTObjectIdentifiers.id_sha384.getId(); public static final String DIGEST_SHA512 = NISTObjectIdentifiers.id_sha512.getId(); public static final String DIGEST_MD5 = PKCSObjectIdentifiers.md5.getId(); public static final String DIGEST_GOST3411 = CryptoProObjectIdentifiers.gostR3411.getId(); public static final String DIGEST_RIPEMD128 = TeleTrusTObjectIdentifiers.ripemd128.getId(); public static final String DIGEST_RIPEMD160 = TeleTrusTObjectIdentifiers.ripemd160.getId(); public static final String DIGEST_RIPEMD256 = TeleTrusTObjectIdentifiers.ripemd256.getId(); public static final String ENCRYPTION_RSA = PKCSObjectIdentifiers.rsaEncryption.getId(); public static final String ENCRYPTION_DSA = X9ObjectIdentifiers.id_dsa_with_sha1.getId(); public static final String ENCRYPTION_ECDSA = X9ObjectIdentifiers.ecdsa_with_SHA1.getId(); public static final String ENCRYPTION_RSA_PSS = PKCSObjectIdentifiers.id_RSASSA_PSS.getId(); public static final String ENCRYPTION_GOST3410 = CryptoProObjectIdentifiers.gostR3410_94.getId(); public static final String ENCRYPTION_ECGOST3410 = CryptoProObjectIdentifiers.gostR3410_2001.getId(); private static final String ENCRYPTION_ECDSA_WITH_SHA1 = X9ObjectIdentifiers.ecdsa_with_SHA1.getId(); private static final String ENCRYPTION_ECDSA_WITH_SHA224 = X9ObjectIdentifiers.ecdsa_with_SHA224.getId(); private static final String ENCRYPTION_ECDSA_WITH_SHA256 = X9ObjectIdentifiers.ecdsa_with_SHA256.getId(); private static final String ENCRYPTION_ECDSA_WITH_SHA384 = X9ObjectIdentifiers.ecdsa_with_SHA384.getId(); private static final String ENCRYPTION_ECDSA_WITH_SHA512 = X9ObjectIdentifiers.ecdsa_with_SHA512.getId(); private static final Set NO_PARAMS = new HashSet(); private static final Map EC_ALGORITHMS = new HashMap(); static { NO_PARAMS.add(ENCRYPTION_DSA); NO_PARAMS.add(ENCRYPTION_ECDSA); NO_PARAMS.add(ENCRYPTION_ECDSA_WITH_SHA1); NO_PARAMS.add(ENCRYPTION_ECDSA_WITH_SHA224); NO_PARAMS.add(ENCRYPTION_ECDSA_WITH_SHA256); NO_PARAMS.add(ENCRYPTION_ECDSA_WITH_SHA384); NO_PARAMS.add(ENCRYPTION_ECDSA_WITH_SHA512); EC_ALGORITHMS.put(DIGEST_SHA1, ENCRYPTION_ECDSA_WITH_SHA1); EC_ALGORITHMS.put(DIGEST_SHA224, ENCRYPTION_ECDSA_WITH_SHA224); EC_ALGORITHMS.put(DIGEST_SHA256, ENCRYPTION_ECDSA_WITH_SHA256); EC_ALGORITHMS.put(DIGEST_SHA384, ENCRYPTION_ECDSA_WITH_SHA384); EC_ALGORITHMS.put(DIGEST_SHA512, ENCRYPTION_ECDSA_WITH_SHA512); } protected List certs = new ArrayList(); protected List crls = new ArrayList(); protected List _signers = new ArrayList(); protected List signerGens = new ArrayList(); protected Map digests = new HashMap(); protected final SecureRandom rand; /** * base constructor */ protected CMSSignedGenerator() { this(new SecureRandom()); } /** * constructor allowing specific source of randomness * @param rand instance of SecureRandom to use */ protected CMSSignedGenerator( SecureRandom rand) { this.rand = rand; } protected String getEncOID( PrivateKey key, String digestOID) { String encOID = null; if (key instanceof RSAPrivateKey || "RSA".equalsIgnoreCase(key.getAlgorithm())) { encOID = ENCRYPTION_RSA; } else if (key instanceof DSAPrivateKey || "DSA".equalsIgnoreCase(key.getAlgorithm())) { encOID = ENCRYPTION_DSA; if (!digestOID.equals(DIGEST_SHA1)) { throw new IllegalArgumentException("can't mix DSA with anything but SHA1"); } } else if ("ECDSA".equalsIgnoreCase(key.getAlgorithm()) || "EC".equalsIgnoreCase(key.getAlgorithm())) { encOID = (String)EC_ALGORITHMS.get(digestOID); if (encOID == null) { throw new IllegalArgumentException("can't mix ECDSA with anything but SHA family digests"); } } else if (key instanceof GOST3410PrivateKey || "GOST3410".equalsIgnoreCase(key.getAlgorithm())) { encOID = ENCRYPTION_GOST3410; } else if ("ECGOST3410".equalsIgnoreCase(key.getAlgorithm())) { encOID = ENCRYPTION_ECGOST3410; } return encOID; } protected Map getBaseParameters(ASN1ObjectIdentifier contentType, AlgorithmIdentifier digAlgId, byte[] hash) { Map param = new HashMap(); param.put(CMSAttributeTableGenerator.CONTENT_TYPE, contentType); param.put(CMSAttributeTableGenerator.DIGEST_ALGORITHM_IDENTIFIER, digAlgId); param.put(CMSAttributeTableGenerator.DIGEST, hash.clone()); return param; } protected ASN1Set getAttributeSet( AttributeTable attr) { if (attr != null) { return new DERSet(attr.toASN1EncodableVector()); } return null; } /** * add the certificates and CRLs contained in the given CertStore * to the pool that will be included in the encoded signature block. *

* Note: this assumes the CertStore will support null in the get * methods. * @param certStore CertStore containing the public key certificates and CRLs * @throws java.security.cert.CertStoreException if an issue occurs processing the CertStore * @throws CMSException if an issue occurse transforming data from the CertStore into the message * @deprecated use addCertificates and addCRLs */ public void addCertificatesAndCRLs( CertStore certStore) throws CertStoreException, CMSException { certs.addAll(CMSUtils.getCertificatesFromStore(certStore)); crls.addAll(CMSUtils.getCRLsFromStore(certStore)); } /** * Add a certificate to the certificate set to be included with the generated SignedData message. * * @param certificate the certificate to be included. * @throws CMSException if the certificate cannot be encoded for adding. */ public void addCertificate( X509CertificateHolder certificate) throws CMSException { certs.add(certificate.toASN1Structure()); } /** * Add the certificates in certStore to the certificate set to be included with the generated SignedData message. * * @param certStore the store containing the certificates to be included. * @throws CMSException if the certificates cannot be encoded for adding. */ public void addCertificates( Store certStore) throws CMSException { certs.addAll(CMSUtils.getCertificatesFromStore(certStore)); } /** * Add a CRL to the CRL set to be included with the generated SignedData message. * * @param crl the CRL to be included. */ public void addCRL(X509CRLHolder crl) { crls.add(crl.toASN1Structure()); } /** * Add the CRLs in crlStore to the CRL set to be included with the generated SignedData message. * * @param crlStore the store containing the CRLs to be included. * @throws CMSException if the CRLs cannot be encoded for adding. */ public void addCRLs( Store crlStore) throws CMSException { crls.addAll(CMSUtils.getCRLsFromStore(crlStore)); } /** * Add the attribute certificates in attrStore to the certificate set to be included with the generated SignedData message. * * @param attrCert the store containing the certificates to be included. * @throws CMSException if the attribute certificate cannot be encoded for adding. */ public void addAttributeCertificate( X509AttributeCertificateHolder attrCert) throws CMSException { certs.add(new DERTaggedObject(false, 2, attrCert.toASN1Structure())); } /** * Add the attribute certificates in attrStore to the certificate set to be included with the generated SignedData message. * * @param attrStore the store containing the certificates to be included. * @throws CMSException if the attribute certificate cannot be encoded for adding. */ public void addAttributeCertificates( Store attrStore) throws CMSException { certs.addAll(CMSUtils.getAttributeCertificatesFromStore(attrStore)); } /** * Add a single instance of otherRevocationData to the CRL set to be included with the generated SignedData message. * * @param otherRevocationInfoFormat the OID specifying the format of the otherRevocationInfo data. * @param otherRevocationInfo the otherRevocationInfo ASN.1 structure. */ public void addOtherRevocationInfo( ASN1ObjectIdentifier otherRevocationInfoFormat, ASN1Encodable otherRevocationInfo) { crls.add(new DERTaggedObject(false, 1, new OtherRevocationInfoFormat(otherRevocationInfoFormat, otherRevocationInfo))); } /** * Add a Store of otherRevocationData to the CRL set to be included with the generated SignedData message. * * @param otherRevocationInfoFormat the OID specifying the format of the otherRevocationInfo data. * @param otherRevocationInfos a Store of otherRevocationInfo data to add. */ public void addOtherRevocationInfo( ASN1ObjectIdentifier otherRevocationInfoFormat, Store otherRevocationInfos) { crls.addAll(CMSUtils.getOthersFromStore(otherRevocationInfoFormat, otherRevocationInfos)); } /** * Add the attribute certificates contained in the passed in store to the * generator. * * @param store a store of Version 2 attribute certificates * @throws CMSException if an error occurse processing the store. * @deprecated use basic Store method */ public void addAttributeCertificates( X509Store store) throws CMSException { try { for (Iterator it = store.getMatches(null).iterator(); it.hasNext();) { X509AttributeCertificate attrCert = (X509AttributeCertificate)it.next(); certs.add(new DERTaggedObject(false, 2, AttributeCertificate.getInstance(ASN1Primitive.fromByteArray(attrCert.getEncoded())))); } } catch (IllegalArgumentException e) { throw new CMSException("error processing attribute certs", e); } catch (IOException e) { throw new CMSException("error processing attribute certs", e); } } /** * Add a store of precalculated signers to the generator. * * @param signerStore store of signers */ public void addSigners( SignerInformationStore signerStore) { Iterator it = signerStore.getSigners().iterator(); while (it.hasNext()) { _signers.add(it.next()); } } public void addSignerInfoGenerator(SignerInfoGenerator infoGen) { signerGens.add(infoGen); } /** * Return a map of oids and byte arrays representing the digests calculated on the content during * the last generate. * * @return a map of oids (as String objects) and byte[] representing digests. */ public Map getGeneratedDigests() { return new HashMap(digests); } } bouncycastle-1.49.orig/jdk1.3/org/bouncycastle/cms/CMSSignedDataParser.java0000644000175000017500000010115212132666220026055 0ustar ebourgebourgpackage org.bouncycastle.cms; import java.io.ByteArrayInputStream; import java.io.IOException; import java.io.InputStream; import java.io.OutputStream; import java.security.NoSuchAlgorithmException; import java.security.NoSuchProviderException; import java.security.Provider; import org.bouncycastle.jce.cert.CertStore; import org.bouncycastle.jce.cert.CertStoreException; import java.util.ArrayList; import java.util.HashMap; import java.util.Iterator; import java.util.List; import java.util.Map; import org.bouncycastle.asn1.ASN1Encodable; import org.bouncycastle.asn1.ASN1EncodableVector; import org.bouncycastle.asn1.ASN1Generator; import org.bouncycastle.asn1.ASN1ObjectIdentifier; import org.bouncycastle.asn1.ASN1OctetStringParser; import org.bouncycastle.asn1.ASN1SequenceParser; import org.bouncycastle.asn1.ASN1Set; import org.bouncycastle.asn1.ASN1SetParser; import org.bouncycastle.asn1.ASN1StreamParser; import org.bouncycastle.asn1.BERSequenceGenerator; import org.bouncycastle.asn1.BERSetParser; import org.bouncycastle.asn1.BERTaggedObject; import org.bouncycastle.asn1.BERTags; import org.bouncycastle.asn1.DERSet; import org.bouncycastle.asn1.DERTaggedObject; import org.bouncycastle.asn1.cms.CMSObjectIdentifiers; import org.bouncycastle.asn1.cms.ContentInfoParser; import org.bouncycastle.asn1.cms.SignedDataParser; import org.bouncycastle.asn1.cms.SignerInfo; import org.bouncycastle.asn1.x509.AlgorithmIdentifier; import org.bouncycastle.cert.jcajce.JcaCertStoreBuilder; import org.bouncycastle.operator.DigestCalculator; import org.bouncycastle.operator.DigestCalculatorProvider; import org.bouncycastle.operator.OperatorCreationException; import org.bouncycastle.operator.bc.BcDigestCalculatorProvider; import org.bouncycastle.util.Store; import org.bouncycastle.util.io.Streams; import org.bouncycastle.x509.NoSuchStoreException; import org.bouncycastle.x509.X509Store; /** * Parsing class for an CMS Signed Data object from an input stream. *

* Note: that because we are in a streaming mode only one signer can be tried and it is important * that the methods on the parser are called in the appropriate order. *

*

* A simple example of usage for an encapsulated signature. *

*

* Two notes: first, in the example below the validity of * the certificate isn't verified, just the fact that one of the certs * matches the given signer, and, second, because we are in a streaming * mode the order of the operations is important. *

*
 *      CMSSignedDataParser     sp = new CMSSignedDataParser(new JcaDigestCalculatorProviderBuilder().setProvider("BC").build(), encapSigData);
 *
 *      sp.getSignedContent().drain();
 *
 *      Store                   certStore = sp.getCertificates();
 *      SignerInformationStore  signers = sp.getSignerInfos();
 *      
 *      Collection              c = signers.getSigners();
 *      Iterator                it = c.iterator();
 *
 *      while (it.hasNext())
 *      {
 *          SignerInformation   signer = (SignerInformation)it.next();
 *          Collection          certCollection = certStore.getMatches(signer.getSID());
 *
 *          Iterator        certIt = certCollection.iterator();
 *          X509CertificateHolder cert = (X509CertificateHolder)certIt.next();
 *
 *          System.out.println("verify returns: " + signer.verify(new JcaSimpleSignerInfoVerifierBuilder().setProvider("BC").build(cert)));
 *      }
 * 
* Note also: this class does not introduce buffering - if you are processing large files you should create * the parser with: *
 *          CMSSignedDataParser     ep = new CMSSignedDataParser(new BufferedInputStream(encapSigData, bufSize));
 *  
* where bufSize is a suitably large buffer size. */ public class CMSSignedDataParser extends CMSContentInfoParser { private static final CMSSignedHelper HELPER = CMSSignedHelper.INSTANCE; private SignedDataParser _signedData; private ASN1ObjectIdentifier _signedContentType; private CMSTypedStream _signedContent; private Map digests; private SignerInformationStore _signerInfoStore; private X509Store _attributeStore; private ASN1Set _certSet, _crlSet; private boolean _isCertCrlParsed; private X509Store _certificateStore; private X509Store _crlStore; /** * @deprecated use method taking a DigestCalculatorProvider */ public CMSSignedDataParser( byte[] sigBlock) throws CMSException { this(createDefaultDigestProvider(), new ByteArrayInputStream(sigBlock)); } public CMSSignedDataParser( DigestCalculatorProvider digestCalculatorProvider, byte[] sigBlock) throws CMSException { this(digestCalculatorProvider, new ByteArrayInputStream(sigBlock)); } /** * @deprecated use method taking digest calculator provider. * @param signedContent * @param sigBlock * @throws CMSException */ public CMSSignedDataParser( CMSTypedStream signedContent, byte[] sigBlock) throws CMSException { this(createDefaultDigestProvider(), signedContent, new ByteArrayInputStream(sigBlock)); } public CMSSignedDataParser( DigestCalculatorProvider digestCalculatorProvider, CMSTypedStream signedContent, byte[] sigBlock) throws CMSException { this(digestCalculatorProvider, signedContent, new ByteArrayInputStream(sigBlock)); } private static DigestCalculatorProvider createDefaultDigestProvider() throws CMSException { return new BcDigestCalculatorProvider(); } /** * base constructor - with encapsulated content * * @deprecated use method taking a DigestCalculatorProvider */ public CMSSignedDataParser( InputStream sigData) throws CMSException { this(createDefaultDigestProvider(), null, sigData); } /** * base constructor - with encapsulated content */ public CMSSignedDataParser( DigestCalculatorProvider digestCalculatorProvider, InputStream sigData) throws CMSException { this(digestCalculatorProvider, null, sigData); } /** * base constructor * * @param signedContent the content that was signed. * @param sigData the signature object stream. * * * @deprecated use method taking a DigestCalculatorProvider */ public CMSSignedDataParser( CMSTypedStream signedContent, InputStream sigData) throws CMSException { this(createDefaultDigestProvider(), signedContent, sigData); } /** * base constructor * * @param digestCalculatorProvider for generating accumulating digests * @param signedContent the content that was signed. * @param sigData the signature object stream. */ public CMSSignedDataParser( DigestCalculatorProvider digestCalculatorProvider, CMSTypedStream signedContent, InputStream sigData) throws CMSException { super(sigData); try { _signedContent = signedContent; _signedData = SignedDataParser.getInstance(_contentInfo.getContent(BERTags.SEQUENCE)); digests = new HashMap(); ASN1SetParser digAlgs = _signedData.getDigestAlgorithms(); ASN1Encodable o; while ((o = digAlgs.readObject()) != null) { AlgorithmIdentifier algId = AlgorithmIdentifier.getInstance(o); try { DigestCalculator calculator = digestCalculatorProvider.get(algId); if (calculator != null) { this.digests.put(algId.getAlgorithm(), calculator); } } catch (OperatorCreationException e) { // ignore } } // // If the message is simply a certificate chain message getContent() may return null. // ContentInfoParser cont = _signedData.getEncapContentInfo(); ASN1OctetStringParser octs = (ASN1OctetStringParser) cont.getContent(BERTags.OCTET_STRING); if (octs != null) { CMSTypedStream ctStr = new CMSTypedStream( cont.getContentType().getId(), octs.getOctetStream()); if (_signedContent == null) { _signedContent = ctStr; } else { // // content passed in, need to read past empty encapsulated content info object if present // ctStr.drain(); } } if (signedContent == null) { _signedContentType = cont.getContentType(); } else { _signedContentType = _signedContent.getContentType(); } } catch (IOException e) { throw new CMSException("io exception: " + e.getMessage(), e); } if (digests.isEmpty()) { throw new CMSException("no digests could be created for message."); } } /** * Return the version number for the SignedData object * * @return the version number */ public int getVersion() { return _signedData.getVersion().getValue().intValue(); } /** * return the collection of signers that are associated with the * signatures for the message. * @throws CMSException */ public SignerInformationStore getSignerInfos() throws CMSException { if (_signerInfoStore == null) { populateCertCrlSets(); List signerInfos = new ArrayList(); Map hashes = new HashMap(); Iterator it = digests.keySet().iterator(); while (it.hasNext()) { Object digestKey = it.next(); hashes.put(digestKey, ((DigestCalculator)digests.get(digestKey)).getDigest()); } try { ASN1SetParser s = _signedData.getSignerInfos(); ASN1Encodable o; while ((o = s.readObject()) != null) { SignerInfo info = SignerInfo.getInstance(o.toASN1Primitive()); byte[] hash = (byte[])hashes.get(info.getDigestAlgorithm().getAlgorithm()); signerInfos.add(new SignerInformation(info, _signedContentType, null, hash)); } } catch (IOException e) { throw new CMSException("io exception: " + e.getMessage(), e); } _signerInfoStore = new SignerInformationStore(signerInfos); } return _signerInfoStore; } /** * return a X509Store containing the attribute certificates, if any, contained * in this message. * * @param type type of store to create * @param provider name of provider to use * @return a store of attribute certificates * @exception NoSuchProviderException if the provider requested isn't available. * @exception org.bouncycastle.x509.NoSuchStoreException if the store type isn't available. * @exception CMSException if a general exception prevents creation of the X509Store * @deprecated use getAttributeCertificates() */ public X509Store getAttributeCertificates( String type, String provider) throws NoSuchStoreException, NoSuchProviderException, CMSException { return getAttributeCertificates(type, CMSUtils.getProvider(provider)); } /** * return a X509Store containing the attribute certificates, if any, contained * in this message. * * @param type type of store to create * @param provider provider to use * @return a store of attribute certificates * @exception org.bouncycastle.x509.NoSuchStoreException if the store type isn't available. * @exception CMSException if a general exception prevents creation of the X509Store * @deprecated use getAttributeCertificates() */ public X509Store getAttributeCertificates( String type, Provider provider) throws NoSuchStoreException, CMSException { if (_attributeStore == null) { populateCertCrlSets(); _attributeStore = HELPER.createAttributeStore(type, provider, this.getAttributeCertificates()); } return _attributeStore; } /** * return a X509Store containing the public key certificates, if any, contained * in this message. * * @param type type of store to create * @param provider provider to use * @return a store of public key certificates * @exception NoSuchProviderException if the provider requested isn't available. * @exception NoSuchStoreException if the store type isn't available. * @exception CMSException if a general exception prevents creation of the X509Store * @deprecated use getCertificates() */ public X509Store getCertificates( String type, String provider) throws NoSuchStoreException, NoSuchProviderException, CMSException { return getCertificates(type, CMSUtils.getProvider(provider)); } /** * return a X509Store containing the public key certificates, if any, contained * in this message. * * @param type type of store to create * @param provider provider to use * @return a store of public key certificates * @exception NoSuchStoreException if the store type isn't available. * @exception CMSException if a general exception prevents creation of the X509Store * @deprecated use getCertificates() */ public X509Store getCertificates( String type, Provider provider) throws NoSuchStoreException, CMSException { if (_certificateStore == null) { populateCertCrlSets(); _certificateStore = HELPER.createCertificateStore(type, provider, this.getCertificates()); } return _certificateStore; } /** * return a X509Store containing CRLs, if any, contained * in this message. * * @param type type of store to create * @param provider name of provider to use * @return a store of CRLs * @exception NoSuchProviderException if the provider requested isn't available. * @exception NoSuchStoreException if the store type isn't available. * @exception CMSException if a general exception prevents creation of the X509Store * @deprecated use getCRLs() */ public X509Store getCRLs( String type, String provider) throws NoSuchStoreException, NoSuchProviderException, CMSException { return getCRLs(type, CMSUtils.getProvider(provider)); } /** * return a X509Store containing CRLs, if any, contained * in this message. * * @param type type of store to create * @param provider provider to use * @return a store of CRLs * @exception NoSuchStoreException if the store type isn't available. * @exception CMSException if a general exception prevents creation of the X509Store * @deprecated use getCRLs() */ public X509Store getCRLs( String type, Provider provider) throws NoSuchStoreException, CMSException { if (_crlStore == null) { populateCertCrlSets(); _crlStore = HELPER.createCRLsStore(type, provider, getCRLs()); } return _crlStore; } /** * return a CertStore containing the certificates and CRLs associated with * this message. * * @exception NoSuchProviderException if the provider requested isn't available. * @exception NoSuchAlgorithmException if the cert store isn't available. * @exception CMSException if a general exception prevents creation of the CertStore * @deprecated use getCertificates() and org.bouncycastle.cert.jcajce.JcaCertStoreBuilder */ public CertStore getCertificatesAndCRLs( String type, String provider) throws NoSuchAlgorithmException, NoSuchProviderException, CMSException { return getCertificatesAndCRLs(type, CMSUtils.getProvider(provider)); } /** * return a CertStore containing the certificates and CRLs associated with * this message. * * @exception NoSuchProviderException if the provider requested isn't available. * @exception NoSuchAlgorithmException if the cert store isn't available. * @exception CMSException if a general exception prevents creation of the CertStore * @deprecated use getCertificates() and org.bouncycastle.cert.jcajce.JcaCertStoreBuilder */ public CertStore getCertificatesAndCRLs( String type, Provider provider) throws NoSuchAlgorithmException, NoSuchProviderException, CMSException { populateCertCrlSets(); try { JcaCertStoreBuilder certStoreBuilder = new JcaCertStoreBuilder().setType(type); if (provider != null) { certStoreBuilder.setProvider(provider); } certStoreBuilder.addCertificates(this.getCertificates()); certStoreBuilder.addCRLs(this.getCRLs()); return certStoreBuilder.build(); } catch (NoSuchAlgorithmException e) { throw e; } catch (Exception e) { throw new CMSException("exception creating CertStore: " + e.getMessage(), e); } } /** * Return any X.509 certificate objects in this SignedData structure as a Store of X509CertificateHolder objects. * * @return a Store of X509CertificateHolder objects. */ public Store getCertificates() throws CMSException { populateCertCrlSets(); return HELPER.getCertificates(_certSet); } /** * Return any X.509 CRL objects in this SignedData structure as a Store of X509CRLHolder objects. * * @return a Store of X509CRLHolder objects. */ public Store getCRLs() throws CMSException { populateCertCrlSets(); return HELPER.getCRLs(_crlSet); } /** * Return any X.509 attribute certificate objects in this SignedData structure as a Store of X509AttributeCertificateHolder objects. * * @return a Store of X509AttributeCertificateHolder objects. */ public Store getAttributeCertificates() throws CMSException { populateCertCrlSets(); return HELPER.getAttributeCertificates(_certSet); } /** * Return any OtherRevocationInfo OtherRevInfo objects of the type indicated by otherRevocationInfoFormat in * this SignedData structure. * * @param otherRevocationInfoFormat OID of the format type been looked for. * * @return a Store of ASN1Encodable objects representing any objects of otherRevocationInfoFormat found. */ public Store getOtherRevocationInfo(ASN1ObjectIdentifier otherRevocationInfoFormat) throws CMSException { populateCertCrlSets(); return HELPER.getOtherRevocationInfo(otherRevocationInfoFormat, _crlSet); } private void populateCertCrlSets() throws CMSException { if (_isCertCrlParsed) { return; } _isCertCrlParsed = true; try { // care! Streaming - these must be done in exactly this order. _certSet = getASN1Set(_signedData.getCertificates()); _crlSet = getASN1Set(_signedData.getCrls()); } catch (IOException e) { throw new CMSException("problem parsing cert/crl sets", e); } } /** * Return the a string representation of the OID associated with the * encapsulated content info structure carried in the signed data. * * @return the OID for the content type. */ public String getSignedContentTypeOID() { return _signedContentType.getId(); } public CMSTypedStream getSignedContent() { if (_signedContent == null) { return null; } InputStream digStream = CMSUtils.attachDigestsToInputStream( digests.values(), _signedContent.getContentStream()); return new CMSTypedStream(_signedContent.getContentType(), digStream); } /** * Replace the signerinformation store associated with the passed * in message contained in the stream original with the new one passed in. * You would probably only want to do this if you wanted to change the unsigned * attributes associated with a signer, or perhaps delete one. *

* The output stream is returned unclosed. *

* @param original the signed data stream to be used as a base. * @param signerInformationStore the new signer information store to use. * @param out the stream to write the new signed data object to. * @return out. */ public static OutputStream replaceSigners( InputStream original, SignerInformationStore signerInformationStore, OutputStream out) throws CMSException, IOException { ASN1StreamParser in = new ASN1StreamParser(original); ContentInfoParser contentInfo = new ContentInfoParser((ASN1SequenceParser)in.readObject()); SignedDataParser signedData = SignedDataParser.getInstance(contentInfo.getContent(BERTags.SEQUENCE)); BERSequenceGenerator sGen = new BERSequenceGenerator(out); sGen.addObject(CMSObjectIdentifiers.signedData); BERSequenceGenerator sigGen = new BERSequenceGenerator(sGen.getRawOutputStream(), 0, true); // version number sigGen.addObject(signedData.getVersion()); // digests signedData.getDigestAlgorithms().toASN1Primitive(); // skip old ones ASN1EncodableVector digestAlgs = new ASN1EncodableVector(); for (Iterator it = signerInformationStore.getSigners().iterator(); it.hasNext();) { SignerInformation signer = (SignerInformation)it.next(); digestAlgs.add(CMSSignedHelper.INSTANCE.fixAlgID(signer.getDigestAlgorithmID())); } sigGen.getRawOutputStream().write(new DERSet(digestAlgs).getEncoded()); // encap content info ContentInfoParser encapContentInfo = signedData.getEncapContentInfo(); BERSequenceGenerator eiGen = new BERSequenceGenerator(sigGen.getRawOutputStream()); eiGen.addObject(encapContentInfo.getContentType()); pipeEncapsulatedOctetString(encapContentInfo, eiGen.getRawOutputStream()); eiGen.close(); writeSetToGeneratorTagged(sigGen, signedData.getCertificates(), 0); writeSetToGeneratorTagged(sigGen, signedData.getCrls(), 1); ASN1EncodableVector signerInfos = new ASN1EncodableVector(); for (Iterator it = signerInformationStore.getSigners().iterator(); it.hasNext();) { SignerInformation signer = (SignerInformation)it.next(); signerInfos.add(signer.toASN1Structure()); } sigGen.getRawOutputStream().write(new DERSet(signerInfos).getEncoded()); sigGen.close(); sGen.close(); return out; } /** * Replace the certificate and CRL information associated with this * CMSSignedData object with the new one passed in. *

* The output stream is returned unclosed. *

* @param original the signed data stream to be used as a base. * @param certsAndCrls the new certificates and CRLs to be used. * @param out the stream to write the new signed data object to. * @return out. * @exception CMSException if there is an error processing the CertStore * @deprecated use method that takes Store objects. */ public static OutputStream replaceCertificatesAndCRLs( InputStream original, CertStore certsAndCrls, OutputStream out) throws CMSException, IOException { ASN1StreamParser in = new ASN1StreamParser(original); ContentInfoParser contentInfo = new ContentInfoParser((ASN1SequenceParser)in.readObject()); SignedDataParser signedData = SignedDataParser.getInstance(contentInfo.getContent(BERTags.SEQUENCE)); BERSequenceGenerator sGen = new BERSequenceGenerator(out); sGen.addObject(CMSObjectIdentifiers.signedData); BERSequenceGenerator sigGen = new BERSequenceGenerator(sGen.getRawOutputStream(), 0, true); // version number sigGen.addObject(signedData.getVersion()); // digests sigGen.getRawOutputStream().write(signedData.getDigestAlgorithms().toASN1Primitive().getEncoded()); // encap content info ContentInfoParser encapContentInfo = signedData.getEncapContentInfo(); BERSequenceGenerator eiGen = new BERSequenceGenerator(sigGen.getRawOutputStream()); eiGen.addObject(encapContentInfo.getContentType()); pipeEncapsulatedOctetString(encapContentInfo, eiGen.getRawOutputStream()); eiGen.close(); // // skip existing certs and CRLs // getASN1Set(signedData.getCertificates()); getASN1Set(signedData.getCrls()); // // replace the certs and crls in the SignedData object // ASN1Set certs; try { certs = CMSUtils.createBerSetFromList(CMSUtils.getCertificatesFromStore(certsAndCrls)); } catch (CertStoreException e) { throw new CMSException("error getting certs from certStore", e); } if (certs.size() > 0) { sigGen.getRawOutputStream().write(new DERTaggedObject(false, 0, certs).getEncoded()); } ASN1Set crls; try { crls = CMSUtils.createBerSetFromList(CMSUtils.getCRLsFromStore(certsAndCrls)); } catch (CertStoreException e) { throw new CMSException("error getting crls from certStore", e); } if (crls.size() > 0) { sigGen.getRawOutputStream().write(new DERTaggedObject(false, 1, crls).getEncoded()); } sigGen.getRawOutputStream().write(signedData.getSignerInfos().toASN1Primitive().getEncoded()); sigGen.close(); sGen.close(); return out; } /** * Replace the certificate and CRL information associated with this * CMSSignedData object with the new one passed in. *

* The output stream is returned unclosed. *

* @param original the signed data stream to be used as a base. * @param certs new certificates to be used, if any. * @param crls new CRLs to be used, if any. * @param attrCerts new attribute certificates to be used, if any. * @param out the stream to write the new signed data object to. * @return out. * @exception CMSException if there is an error processing the CertStore */ public static OutputStream replaceCertificatesAndCRLs( InputStream original, Store certs, Store crls, Store attrCerts, OutputStream out) throws CMSException, IOException { ASN1StreamParser in = new ASN1StreamParser(original); ContentInfoParser contentInfo = new ContentInfoParser((ASN1SequenceParser)in.readObject()); SignedDataParser signedData = SignedDataParser.getInstance(contentInfo.getContent(BERTags.SEQUENCE)); BERSequenceGenerator sGen = new BERSequenceGenerator(out); sGen.addObject(CMSObjectIdentifiers.signedData); BERSequenceGenerator sigGen = new BERSequenceGenerator(sGen.getRawOutputStream(), 0, true); // version number sigGen.addObject(signedData.getVersion()); // digests sigGen.getRawOutputStream().write(signedData.getDigestAlgorithms().toASN1Primitive().getEncoded()); // encap content info ContentInfoParser encapContentInfo = signedData.getEncapContentInfo(); BERSequenceGenerator eiGen = new BERSequenceGenerator(sigGen.getRawOutputStream()); eiGen.addObject(encapContentInfo.getContentType()); pipeEncapsulatedOctetString(encapContentInfo, eiGen.getRawOutputStream()); eiGen.close(); // // skip existing certs and CRLs // getASN1Set(signedData.getCertificates()); getASN1Set(signedData.getCrls()); // // replace the certs and crls in the SignedData object // if (certs != null || attrCerts != null) { List certificates = new ArrayList(); if (certs != null) { certificates.addAll(CMSUtils.getCertificatesFromStore(certs)); } if (attrCerts != null) { certificates.addAll(CMSUtils.getAttributeCertificatesFromStore(attrCerts)); } ASN1Set asn1Certs = CMSUtils.createBerSetFromList(certificates); if (asn1Certs.size() > 0) { sigGen.getRawOutputStream().write(new DERTaggedObject(false, 0, asn1Certs).getEncoded()); } } if (crls != null) { ASN1Set asn1Crls = CMSUtils.createBerSetFromList(CMSUtils.getCRLsFromStore(crls)); if (asn1Crls.size() > 0) { sigGen.getRawOutputStream().write(new DERTaggedObject(false, 1, asn1Crls).getEncoded()); } } sigGen.getRawOutputStream().write(signedData.getSignerInfos().toASN1Primitive().getEncoded()); sigGen.close(); sGen.close(); return out; } private static void writeSetToGeneratorTagged( ASN1Generator asn1Gen, ASN1SetParser asn1SetParser, int tagNo) throws IOException { ASN1Set asn1Set = getASN1Set(asn1SetParser); if (asn1Set != null) { if (asn1SetParser instanceof BERSetParser) { asn1Gen.getRawOutputStream().write(new BERTaggedObject(false, tagNo, asn1Set).getEncoded()); } else { asn1Gen.getRawOutputStream().write(new DERTaggedObject(false, tagNo, asn1Set).getEncoded()); } } } private static ASN1Set getASN1Set( ASN1SetParser asn1SetParser) { return asn1SetParser == null ? null : ASN1Set.getInstance(asn1SetParser.toASN1Primitive()); } private static void pipeEncapsulatedOctetString(ContentInfoParser encapContentInfo, OutputStream rawOutputStream) throws IOException { ASN1OctetStringParser octs = (ASN1OctetStringParser) encapContentInfo.getContent(BERTags.OCTET_STRING); if (octs != null) { pipeOctetString(octs, rawOutputStream); } // BERTaggedObjectParser contentObject = (BERTaggedObjectParser)encapContentInfo.getContentObject(); // if (contentObject != null) // { // // Handle IndefiniteLengthInputStream safely // InputStream input = ASN1StreamParser.getSafeRawInputStream(contentObject.getContentStream(true)); // // // TODO BerTaggedObjectGenerator? // BEROutputStream berOut = new BEROutputStream(rawOutputStream); // berOut.write(DERTags.CONSTRUCTED | DERTags.TAGGED | 0); // berOut.write(0x80); // // pipeRawOctetString(input, rawOutputStream); // // berOut.write(0x00); // berOut.write(0x00); // // input.close(); // } } private static void pipeOctetString( ASN1OctetStringParser octs, OutputStream output) throws IOException { // TODO Allow specification of a specific fragment size? OutputStream outOctets = CMSUtils.createBEROctetOutputStream( output, 0, true, 0); Streams.pipeAll(octs.getOctetStream(), outOctets); outOctets.close(); } // private static void pipeRawOctetString( // InputStream rawInput, // OutputStream rawOutput) // throws IOException // { // InputStream tee = new TeeInputStream(rawInput, rawOutput); // ASN1StreamParser sp = new ASN1StreamParser(tee); // ASN1OctetStringParser octs = (ASN1OctetStringParser)sp.readObject(); // Streams.drain(octs.getOctetStream()); // } } bouncycastle-1.49.orig/jdk1.3/org/bouncycastle/cms/jcajce/0000755000175000017500000000000012152033550022702 5ustar ebourgebourgbouncycastle-1.49.orig/jdk1.3/org/bouncycastle/cms/jcajce/JcaSignerId.java0000644000175000017500000000215011702763111025670 0ustar ebourgebourgpackage org.bouncycastle.cms.jcajce; import java.math.BigInteger; import java.security.cert.X509Certificate; import org.bouncycastle.asn1.x500.X500Name; import org.bouncycastle.cms.SignerId; import org.bouncycastle.jce.PrincipalUtil; import org.bouncycastle.jce.X509Principal; public class JcaSignerId extends SignerId { private static X509Principal getPrincipal(X509Certificate cert) { try { return PrincipalUtil.getIssuerX509Principal(cert); } catch (Exception e) { throw new IllegalArgumentException("unable to extract principle"); } } /** * Construct a signer identifier based on the issuer, serial number and subject key identifier (if present) of the passed in * certificate. * * @param certificate certificate providing the issue and serial number and subject key identifier. */ public JcaSignerId(X509Certificate certificate) { super(X500Name.getInstance(getPrincipal(certificate).getEncoded()), certificate.getSerialNumber(), CMSUtils.getSubjectKeyId(certificate)); } } bouncycastle-1.49.orig/jdk1.3/org/bouncycastle/cms/jcajce/JcaX509CertSelectorConverter.java0000644000175000017500000000137211726263416031056 0ustar ebourgebourgpackage org.bouncycastle.cms.jcajce; import org.bouncycastle.jce.cert.X509CertSelector; import org.bouncycastle.cms.KeyTransRecipientId; import org.bouncycastle.cms.SignerId; public class JcaX509CertSelectorConverter extends org.bouncycastle.cert.selector.jcajce.JcaX509CertSelectorConverter { public JcaX509CertSelectorConverter() { } public X509CertSelector getCertSelector(KeyTransRecipientId recipientId) { return doConversion(recipientId.getIssuer(), recipientId.getSerialNumber(), recipientId.getSubjectKeyIdentifier()); } public X509CertSelector getCertSelector(SignerId signerId) { return doConversion(signerId.getIssuer(), signerId.getSerialNumber(), signerId.getSubjectKeyIdentifier()); } } bouncycastle-1.49.orig/jdk1.3/org/bouncycastle/cms/jcajce/JceKeyTransRecipientId.java0000644000175000017500000000157011521672550030062 0ustar ebourgebourgpackage org.bouncycastle.cms.jcajce; import java.security.cert.CertificateEncodingException; import java.security.cert.X509Certificate; import org.bouncycastle.asn1.x500.X500Name; import org.bouncycastle.cms.KeyTransRecipientId; import org.bouncycastle.jce.PrincipalUtil; import org.bouncycastle.jce.X509Principal; public class JceKeyTransRecipientId extends KeyTransRecipientId { public JceKeyTransRecipientId(X509Certificate certificate) { super(X500Name.getInstance(extractIssuer(certificate)), certificate.getSerialNumber()); } private static X509Principal extractIssuer(X509Certificate certificate) { try { return PrincipalUtil.getIssuerX509Principal(certificate); } catch (CertificateEncodingException e) { throw new IllegalStateException("can't extract issuer"); } } } bouncycastle-1.49.orig/jdk1.3/org/bouncycastle/cms/jcajce/JceKeyAgreeRecipientId.java0000644000175000017500000000162611523656117030023 0ustar ebourgebourgpackage org.bouncycastle.cms.jcajce; import java.math.BigInteger; import java.security.cert.CertificateEncodingException; import java.security.cert.X509Certificate; import org.bouncycastle.jce.PrincipalUtil; import org.bouncycastle.jce.X509Principal; import org.bouncycastle.asn1.x500.X500Name; import org.bouncycastle.cms.KeyAgreeRecipientId; public class JceKeyAgreeRecipientId extends KeyAgreeRecipientId { public JceKeyAgreeRecipientId(X509Certificate certificate) { super(X500Name.getInstance(extractIssuer(certificate)), certificate.getSerialNumber()); } private static X509Principal extractIssuer(X509Certificate certificate) { try { return PrincipalUtil.getIssuerX509Principal(certificate); } catch (CertificateEncodingException e) { throw new IllegalStateException("can't extract issuer"); } } } bouncycastle-1.49.orig/jdk1.3/org/bouncycastle/cms/jcajce/JcaSelectorConverter.java0000644000175000017500000000314511726263416027652 0ustar ebourgebourgpackage org.bouncycastle.cms.jcajce; import org.bouncycastle.jce.cert.X509CertSelector; import org.bouncycastle.asn1.ASN1OctetString; import org.bouncycastle.asn1.x500.X500Name; import org.bouncycastle.cms.KeyTransRecipientId; import org.bouncycastle.cms.SignerId; public class JcaSelectorConverter { public JcaSelectorConverter() { } public SignerId getSignerId(X509CertSelector certSelector) { try { if (certSelector.getSubjectKeyIdentifier() != null) { return new SignerId(X500Name.getInstance(certSelector.getIssuerAsBytes()), certSelector.getSerialNumber(), ASN1OctetString.getInstance(certSelector.getSubjectKeyIdentifier()).getOctets()); } else { return new SignerId(X500Name.getInstance(certSelector.getIssuerAsBytes()), certSelector.getSerialNumber()); } } catch (Exception e) { throw new IllegalArgumentException("conversion failed: " + e.toString()); } } public KeyTransRecipientId getKeyTransRecipientId(X509CertSelector certSelector) { try { if (certSelector.getSubjectKeyIdentifier() != null) { return new KeyTransRecipientId(X500Name.getInstance(certSelector.getIssuerAsBytes()), certSelector.getSerialNumber(), ASN1OctetString.getInstance(certSelector.getSubjectKeyIdentifier()).getOctets()); } else { return new KeyTransRecipientId(X500Name.getInstance(certSelector.getIssuerAsBytes()), certSelector.getSerialNumber()); } } catch (Exception e) { throw new IllegalArgumentException("conversion failed: " + e.toString()); } } } bouncycastle-1.49.orig/jdk1.3/org/bouncycastle/tsp/0000755000175000017500000000000012152033550021507 5ustar ebourgebourgbouncycastle-1.49.orig/jdk1.3/org/bouncycastle/tsp/TimeStampTokenGenerator.java0000644000175000017500000005174612132666220027146 0ustar ebourgebourgpackage org.bouncycastle.tsp; import java.io.ByteArrayOutputStream; import java.io.IOException; import java.io.OutputStream; import java.math.BigInteger; import java.security.MessageDigest; import java.security.NoSuchAlgorithmException; import java.security.NoSuchProviderException; import java.security.PrivateKey; import java.security.cert.CRLException; import org.bouncycastle.jce.cert.CertStore; import org.bouncycastle.jce.cert.CertStoreException; import java.security.cert.CertificateEncodingException; import java.security.cert.X509CRL; import java.security.cert.X509Certificate; import java.security.interfaces.DSAPrivateKey; import java.security.interfaces.RSAPrivateKey; import java.util.ArrayList; import java.util.Collection; import java.util.Date; import java.util.Hashtable; import java.util.Iterator; import java.util.List; import java.util.Map; import org.bouncycastle.asn1.ASN1Boolean; import org.bouncycastle.asn1.ASN1Encoding; import org.bouncycastle.asn1.ASN1GeneralizedTime; import org.bouncycastle.asn1.ASN1Integer; import org.bouncycastle.asn1.ASN1ObjectIdentifier; import org.bouncycastle.asn1.DERNull; import org.bouncycastle.asn1.DERSet; import org.bouncycastle.asn1.cms.Attribute; import org.bouncycastle.asn1.cms.AttributeTable; import org.bouncycastle.asn1.ess.ESSCertID; import org.bouncycastle.asn1.ess.ESSCertIDv2; import org.bouncycastle.asn1.ess.SigningCertificate; import org.bouncycastle.asn1.ess.SigningCertificateV2; import org.bouncycastle.asn1.oiw.OIWObjectIdentifiers; import org.bouncycastle.asn1.pkcs.PKCSObjectIdentifiers; import org.bouncycastle.asn1.tsp.Accuracy; import org.bouncycastle.asn1.tsp.MessageImprint; import org.bouncycastle.asn1.tsp.TSTInfo; import org.bouncycastle.asn1.x509.AlgorithmIdentifier; import org.bouncycastle.asn1.x509.GeneralName; import org.bouncycastle.cert.jcajce.JcaX509CRLHolder; import org.bouncycastle.cert.jcajce.JcaX509CertificateHolder; import org.bouncycastle.cms.CMSAttributeTableGenerationException; import org.bouncycastle.cms.CMSAttributeTableGenerator; import org.bouncycastle.cms.CMSException; import org.bouncycastle.cms.CMSProcessableByteArray; import org.bouncycastle.cms.CMSSignedData; import org.bouncycastle.cms.CMSSignedDataGenerator; import org.bouncycastle.cms.CMSSignedGenerator; import org.bouncycastle.cms.DefaultSignedAttributeTableGenerator; import org.bouncycastle.cms.SignerInfoGenerator; import org.bouncycastle.cms.SimpleAttributeTableGenerator; import org.bouncycastle.cms.jcajce.JcaSignerInfoGeneratorBuilder; import org.bouncycastle.jce.interfaces.GOST3410PrivateKey; import org.bouncycastle.operator.DigestCalculator; import org.bouncycastle.operator.OperatorCreationException; import org.bouncycastle.operator.jcajce.JcaContentSignerBuilder; import org.bouncycastle.operator.jcajce.JcaDigestCalculatorProviderBuilder; import org.bouncycastle.util.CollectionStore; import org.bouncycastle.util.Store; /** * Currently the class supports ESSCertID by if a digest calculator based on SHA1 is passed in, otherwise it uses * ESSCertIDv2. In the event you need to pass both types, you will need to override the SignedAttributeGenerator * for the SignerInfoGeneratorBuilder you are using. For the default for ESSCertIDv2 the code will look something * like the following: *
 * final ESSCertID essCertid = new ESSCertID(certHashSha1, issuerSerial);
 * final ESSCertIDv2 essCertidV2 = new ESSCertIDv2(certHashSha256, issuerSerial);
 *
 * signerInfoGenBuilder.setSignedAttributeGenerator(new CMSAttributeTableGenerator()
 * {
 *     public AttributeTable getAttributes(Map parameters)
 *         throws CMSAttributeTableGenerationException
 *     {
 *         CMSAttributeTableGenerator attrGen = new DefaultSignedAttributeTableGenerator();
 *
 *         AttributeTable table = attrGen.getAttributes(parameters);
 *
 *         table = table.add(PKCSObjectIdentifiers.id_aa_signingCertificate, new SigningCertificate(essCertid));
 *         table = table.add(PKCSObjectIdentifiers.id_aa_signingCertificateV2, new SigningCertificateV2(essCertidV2));
 *
 *         return table;
 *     }
 * });
 * 
*/ public class TimeStampTokenGenerator { int accuracySeconds = -1; int accuracyMillis = -1; int accuracyMicros = -1; boolean ordering = false; GeneralName tsa = null; private ASN1ObjectIdentifier tsaPolicyOID; PrivateKey key; X509Certificate cert; String digestOID; AttributeTable signedAttr; AttributeTable unsignedAttr; private List certs = new ArrayList(); private List crls = new ArrayList(); private List attrCerts = new ArrayList(); private SignerInfoGenerator signerInfoGen; /** * Basic Constructor - set up a calculator based on signerInfoGen with a ESSCertID calculated from * the signer's associated certificate using the sha1DigestCalculator. If alternate values are required * for id-aa-signingCertificate they should be added to the signerInfoGen object before it is passed in, * otherwise a standard digest based value will be added. * * @param signerInfoGen the generator for the signer we are using. * @param digestCalculator calculator for to use for digest of certificate. * @param tsaPolicy tasPolicy to send. * @throws IllegalArgumentException if calculator is not SHA-1 or there is no associated certificate for the signer, * @throws TSPException if the signer certificate cannot be processed. */ public TimeStampTokenGenerator( final SignerInfoGenerator signerInfoGen, DigestCalculator digestCalculator, ASN1ObjectIdentifier tsaPolicy) throws IllegalArgumentException, TSPException { this.signerInfoGen = signerInfoGen; this.tsaPolicyOID = tsaPolicy; if (!signerInfoGen.hasAssociatedCertificate()) { throw new IllegalArgumentException("SignerInfoGenerator must have an associated certificate"); } TSPUtil.validateCertificate(signerInfoGen.getAssociatedCertificate()); try { OutputStream dOut = digestCalculator.getOutputStream(); dOut.write(signerInfoGen.getAssociatedCertificate().getEncoded()); dOut.close(); if (digestCalculator.getAlgorithmIdentifier().getAlgorithm().equals(OIWObjectIdentifiers.idSHA1)) { final ESSCertID essCertid = new ESSCertID(digestCalculator.getDigest()); this.signerInfoGen = new SignerInfoGenerator(signerInfoGen, new CMSAttributeTableGenerator() { public AttributeTable getAttributes(Map parameters) throws CMSAttributeTableGenerationException { AttributeTable table = signerInfoGen.getSignedAttributeTableGenerator().getAttributes(parameters); if (table.get(PKCSObjectIdentifiers.id_aa_signingCertificate) == null) { return table.add(PKCSObjectIdentifiers.id_aa_signingCertificate, new SigningCertificate(essCertid)); } return table; } }, signerInfoGen.getUnsignedAttributeTableGenerator()); } else { AlgorithmIdentifier digAlgID = new AlgorithmIdentifier(digestCalculator.getAlgorithmIdentifier().getAlgorithm()); final ESSCertIDv2 essCertid = new ESSCertIDv2(digAlgID, digestCalculator.getDigest()); this.signerInfoGen = new SignerInfoGenerator(signerInfoGen, new CMSAttributeTableGenerator() { public AttributeTable getAttributes(Map parameters) throws CMSAttributeTableGenerationException { AttributeTable table = signerInfoGen.getSignedAttributeTableGenerator().getAttributes(parameters); if (table.get(PKCSObjectIdentifiers.id_aa_signingCertificateV2) == null) { return table.add(PKCSObjectIdentifiers.id_aa_signingCertificateV2, new SigningCertificateV2(essCertid)); } return table; } }, signerInfoGen.getUnsignedAttributeTableGenerator()); } } catch (IOException e) { throw new TSPException("Exception processing certificate.", e); } } /** * Basic Constructor - set up a calculator based on signerInfoGen with a ESSCertID calculated from * the signer's associated certificate using the sha1DigestCalculator. * * @param sha1DigestCalculator calculator for SHA-1 of certificate. * @param signerInfoGen the generator for the signer we are using. * @param tsaPolicy tasPolicy to send. * @throws IllegalArgumentException if calculator is not SHA-1 or there is no associated certificate for the signer, * @throws TSPException if the signer certificate cannot be processed. * @deprecated use constructor taking signerInfoGen first. */ public TimeStampTokenGenerator( DigestCalculator sha1DigestCalculator, final SignerInfoGenerator signerInfoGen, ASN1ObjectIdentifier tsaPolicy) throws IllegalArgumentException, TSPException { this(signerInfoGen, sha1DigestCalculator, tsaPolicy); } /** * basic creation - only the default attributes will be included here. * @deprecated use SignerInfoGenerator constructor that takes a digest calculator */ public TimeStampTokenGenerator( final SignerInfoGenerator signerInfoGen, ASN1ObjectIdentifier tsaPolicy) throws IllegalArgumentException, TSPException { this(new DigestCalculator() { private ByteArrayOutputStream bOut = new ByteArrayOutputStream(); public AlgorithmIdentifier getAlgorithmIdentifier() { return new AlgorithmIdentifier(OIWObjectIdentifiers.idSHA1, DERNull.INSTANCE); } public OutputStream getOutputStream() { return bOut; } public byte[] getDigest() { try { return MessageDigest.getInstance("SHA-1").digest(bOut.toByteArray()); } catch (NoSuchAlgorithmException e) { throw new IllegalStateException("cannot find sha-1: "+ e.getMessage()); } } }, signerInfoGen, tsaPolicy); } /** * basic creation - only the default attributes will be included here. * @deprecated use SignerInfoGenerator constructor that takes a digest calculator. */ public TimeStampTokenGenerator( PrivateKey key, X509Certificate cert, String digestOID, String tsaPolicyOID) throws IllegalArgumentException, TSPException { this(key, cert, digestOID, tsaPolicyOID, null, null); } /** * basic creation - only the default attributes will be included here. * @deprecated use SignerInfoGenerator constructor that takes a digest calculator. */ public TimeStampTokenGenerator( PrivateKey key, X509Certificate cert, ASN1ObjectIdentifier digestOID, String tsaPolicyOID) throws IllegalArgumentException, TSPException { this(key, cert, digestOID.getId(), tsaPolicyOID, null, null); } /** * create with a signer with extra signed/unsigned attributes. * @deprecated use SignerInfoGenerator constructor that takes a digest calculator. */ public TimeStampTokenGenerator( PrivateKey key, X509Certificate cert, String digestOID, String tsaPolicyOID, AttributeTable signedAttr, AttributeTable unsignedAttr) throws IllegalArgumentException, TSPException { this.key = key; this.cert = cert; this.digestOID = digestOID; this.tsaPolicyOID = new ASN1ObjectIdentifier(tsaPolicyOID); this.unsignedAttr = unsignedAttr; // // add the essCertid // Hashtable signedAttrs = null; if (signedAttr != null) { signedAttrs = signedAttr.toHashtable(); } else { signedAttrs = new Hashtable(); } TSPUtil.validateCertificate(cert); try { ESSCertID essCertid = new ESSCertID(MessageDigest.getInstance("SHA-1").digest(cert.getEncoded())); signedAttrs.put(PKCSObjectIdentifiers.id_aa_signingCertificate, new Attribute( PKCSObjectIdentifiers.id_aa_signingCertificate, new DERSet(new SigningCertificate(essCertid)))); } catch (NoSuchAlgorithmException e) { throw new TSPException("Can't find a SHA-1 implementation.", e); } catch (CertificateEncodingException e) { throw new TSPException("Exception processing certificate.", e); } this.signedAttr = new AttributeTable(signedAttrs); } /** * @deprecated use addCertificates and addCRLs * @param certificates * @throws CertStoreException * @throws TSPException */ public void setCertificatesAndCRLs(CertStore certificates) throws CertStoreException, TSPException { Collection c1 = certificates.getCertificates(null); for (Iterator it = c1.iterator(); it.hasNext();) { try { certs.add(new JcaX509CertificateHolder((X509Certificate)it.next())); } catch (CertificateEncodingException e) { throw new TSPException("cannot encode certificate: " + e.getMessage(), e); } } c1 = certificates.getCRLs(null); for (Iterator it = c1.iterator(); it.hasNext();) { try { crls.add(new JcaX509CRLHolder((X509CRL)it.next())); } catch (CRLException e) { throw new TSPException("cannot encode CRL: " + e.getMessage(), e); } } } /** * Add the store of X509 Certificates to the generator. * * @param certStore a Store containing X509CertificateHolder objects */ public void addCertificates( Store certStore) { certs.addAll(certStore.getMatches(null)); } /** * * @param crlStore a Store containing X509CRLHolder objects. */ public void addCRLs( Store crlStore) { crls.addAll(crlStore.getMatches(null)); } /** * * @param attrStore a Store containing X509AttributeCertificate objects. */ public void addAttributeCertificates( Store attrStore) { attrCerts.addAll(attrStore.getMatches(null)); } public void setAccuracySeconds(int accuracySeconds) { this.accuracySeconds = accuracySeconds; } public void setAccuracyMillis(int accuracyMillis) { this.accuracyMillis = accuracyMillis; } public void setAccuracyMicros(int accuracyMicros) { this.accuracyMicros = accuracyMicros; } public void setOrdering(boolean ordering) { this.ordering = ordering; } public void setTSA(GeneralName tsa) { this.tsa = tsa; } //------------------------------------------------------------------------------ public TimeStampToken generate( TimeStampRequest request, BigInteger serialNumber, Date genTime, String provider) throws NoSuchAlgorithmException, NoSuchProviderException, TSPException { if (signerInfoGen == null) { try { JcaSignerInfoGeneratorBuilder sigBuilder = new JcaSignerInfoGeneratorBuilder(new JcaDigestCalculatorProviderBuilder().setProvider(provider).build()); sigBuilder.setSignedAttributeGenerator(new DefaultSignedAttributeTableGenerator(signedAttr)); if (unsignedAttr != null) { sigBuilder.setUnsignedAttributeGenerator(new SimpleAttributeTableGenerator(unsignedAttr)); } signerInfoGen = sigBuilder.build(new JcaContentSignerBuilder(getSigAlgorithm(key, digestOID)).setProvider(provider).build(key), cert); } catch (OperatorCreationException e) { throw new TSPException("Error generating signing operator", e); } catch (CertificateEncodingException e) { throw new TSPException("Error encoding certificate", e); } } return generate(request, serialNumber, genTime); } public TimeStampToken generate( TimeStampRequest request, BigInteger serialNumber, Date genTime) throws TSPException { if (signerInfoGen == null) { throw new IllegalStateException("can only use this method with SignerInfoGenerator constructor"); } ASN1ObjectIdentifier digestAlgOID = request.getMessageImprintAlgOID(); AlgorithmIdentifier algID = new AlgorithmIdentifier(digestAlgOID, DERNull.INSTANCE); MessageImprint messageImprint = new MessageImprint(algID, request.getMessageImprintDigest()); Accuracy accuracy = null; if (accuracySeconds > 0 || accuracyMillis > 0 || accuracyMicros > 0) { ASN1Integer seconds = null; if (accuracySeconds > 0) { seconds = new ASN1Integer(accuracySeconds); } ASN1Integer millis = null; if (accuracyMillis > 0) { millis = new ASN1Integer(accuracyMillis); } ASN1Integer micros = null; if (accuracyMicros > 0) { micros = new ASN1Integer(accuracyMicros); } accuracy = new Accuracy(seconds, millis, micros); } ASN1Boolean derOrdering = null; if (ordering) { derOrdering = new ASN1Boolean(ordering); } ASN1Integer nonce = null; if (request.getNonce() != null) { nonce = new ASN1Integer(request.getNonce()); } ASN1ObjectIdentifier tsaPolicy = tsaPolicyOID; if (request.getReqPolicy() != null) { tsaPolicy = request.getReqPolicy(); } TSTInfo tstInfo = new TSTInfo(tsaPolicy, messageImprint, new ASN1Integer(serialNumber), new ASN1GeneralizedTime(genTime), accuracy, derOrdering, nonce, tsa, request.getExtensions()); try { CMSSignedDataGenerator signedDataGenerator = new CMSSignedDataGenerator(); if (request.getCertReq()) { // TODO: do we need to check certs non-empty? signedDataGenerator.addCertificates(new CollectionStore(certs)); signedDataGenerator.addCRLs(new CollectionStore(crls)); signedDataGenerator.addAttributeCertificates(new CollectionStore(attrCerts)); } else { signedDataGenerator.addCRLs(new CollectionStore(crls)); } signedDataGenerator.addSignerInfoGenerator(signerInfoGen); byte[] derEncodedTSTInfo = tstInfo.getEncoded(ASN1Encoding.DER); CMSSignedData signedData = signedDataGenerator.generate(new CMSProcessableByteArray(PKCSObjectIdentifiers.id_ct_TSTInfo, derEncodedTSTInfo), true); return new TimeStampToken(signedData); } catch (CMSException cmsEx) { throw new TSPException("Error generating time-stamp token", cmsEx); } catch (IOException e) { throw new TSPException("Exception encoding info", e); } } private String getSigAlgorithm( PrivateKey key, String digestOID) { String enc = null; if (key instanceof RSAPrivateKey || "RSA".equalsIgnoreCase(key.getAlgorithm())) { enc = "RSA"; } else if (key instanceof DSAPrivateKey || "DSA".equalsIgnoreCase(key.getAlgorithm())) { enc = "DSA"; } else if ("ECDSA".equalsIgnoreCase(key.getAlgorithm()) || "EC".equalsIgnoreCase(key.getAlgorithm())) { enc = "ECDSA"; } else if (key instanceof GOST3410PrivateKey || "GOST3410".equalsIgnoreCase(key.getAlgorithm())) { enc = "GOST3410"; } else if ("ECGOST3410".equalsIgnoreCase(key.getAlgorithm())) { enc = CMSSignedGenerator.ENCRYPTION_ECGOST3410; } return TSPUtil.getDigestAlgName(digestOID) + "with" + enc; } } bouncycastle-1.49.orig/jdk1.3/org/bouncycastle/tsp/cms/0000755000175000017500000000000012152033550022271 5ustar ebourgebourgbouncycastle-1.49.orig/jdk1.3/org/bouncycastle/tsp/cms/CMSTimeStampedDataParser.java0000644000175000017500000001460511624652555027707 0ustar ebourgebourgpackage org.bouncycastle.tsp.cms; import java.io.ByteArrayInputStream; import java.io.IOException; import java.io.InputStream; import java.net.MalformedURLException; import java.net.URL; import org.bouncycastle.asn1.BERTags; import org.bouncycastle.asn1.DERIA5String; import org.bouncycastle.asn1.cms.AttributeTable; import org.bouncycastle.asn1.cms.CMSObjectIdentifiers; import org.bouncycastle.asn1.cms.ContentInfoParser; import org.bouncycastle.asn1.cms.TimeStampedDataParser; import org.bouncycastle.cms.CMSContentInfoParser; import org.bouncycastle.cms.CMSException; import org.bouncycastle.operator.DigestCalculator; import org.bouncycastle.operator.DigestCalculatorProvider; import org.bouncycastle.operator.OperatorCreationException; import org.bouncycastle.tsp.TimeStampToken; import org.bouncycastle.util.io.Streams; public class CMSTimeStampedDataParser extends CMSContentInfoParser { private TimeStampedDataParser timeStampedData; private TimeStampDataUtil util; public CMSTimeStampedDataParser(InputStream in) throws CMSException { super(in); initialize(_contentInfo); } public CMSTimeStampedDataParser(byte[] baseData) throws CMSException { this(new ByteArrayInputStream(baseData)); } private void initialize(ContentInfoParser contentInfo) throws CMSException { try { if (CMSObjectIdentifiers.timestampedData.equals(contentInfo.getContentType())) { this.timeStampedData = TimeStampedDataParser.getInstance(contentInfo.getContent(BERTags.SEQUENCE)); } else { throw new IllegalArgumentException("Malformed content - type must be " + CMSObjectIdentifiers.timestampedData.getId()); } } catch (IOException e) { throw new CMSException("parsing exception: " + e.getMessage(), e); } } public byte[] calculateNextHash(DigestCalculator calculator) throws CMSException { return util.calculateNextHash(calculator); } public InputStream getContent() { if (timeStampedData.getContent() != null) { return timeStampedData.getContent().getOctetStream(); } return null; } public URL getDataUri() throws MalformedURLException { DERIA5String dataURI = this.timeStampedData.getDataUri(); if (dataURI != null) { return new URL(dataURI.getString()); } return null; } /** * Initialise the passed in calculator with the MetaData for this message, if it is * required as part of the initial message imprint calculation. * * @param calculator the digest calculator to be initialised. * @throws CMSException if the MetaData is required and cannot be processed */ public void initialiseMessageImprintDigestCalculator(DigestCalculator calculator) throws CMSException { util.initialiseMessageImprintDigestCalculator(calculator); } /** * Returns an appropriately initialised digest calculator based on the message imprint algorithm * described in the first time stamp in the TemporalData for this message. If the metadata is required * to be included in the digest calculation, the returned calculator will be pre-initialised. * * @param calculatorProvider a provider of DigestCalculator objects. * @return an initialised digest calculator. * @throws OperatorCreationException if the provider is unable to create the calculator. */ public DigestCalculator getMessageImprintDigestCalculator(DigestCalculatorProvider calculatorProvider) throws OperatorCreationException { try { parseTimeStamps(); } catch (CMSException e) { throw new OperatorCreationException("unable to extract algorithm ID: " + e.getMessage(), e); } return util.getMessageImprintDigestCalculator(calculatorProvider); } public String getFileName() { return util.getFileName(); } public String getMediaType() { return util.getMediaType(); } public AttributeTable getOtherMetaData() { return util.getOtherMetaData(); } public TimeStampToken[] getTimeStampTokens() throws CMSException { parseTimeStamps(); return util.getTimeStampTokens(); } /** * Validate the digests present in the TimeStampTokens contained in the CMSTimeStampedData. * * @param calculatorProvider provider for digest calculators * @param dataDigest the calculated data digest for the message * @throws ImprintDigestInvalidException if an imprint digest fails to compare * @throws CMSException if an exception occurs processing the message. */ public void validate(DigestCalculatorProvider calculatorProvider, byte[] dataDigest) throws ImprintDigestInvalidException, CMSException { parseTimeStamps(); util.validate(calculatorProvider, dataDigest); } /** * Validate the passed in timestamp token against the tokens and data present in the message. * * @param calculatorProvider provider for digest calculators * @param dataDigest the calculated data digest for the message. * @param timeStampToken the timestamp token of interest. * @throws ImprintDigestInvalidException if the token is not present in the message, or an imprint digest fails to compare. * @throws CMSException if an exception occurs processing the message. */ public void validate(DigestCalculatorProvider calculatorProvider, byte[] dataDigest, TimeStampToken timeStampToken) throws ImprintDigestInvalidException, CMSException { parseTimeStamps(); util.validate(calculatorProvider, dataDigest, timeStampToken); } private void parseTimeStamps() throws CMSException { try { if (util == null) { InputStream cont = this.getContent(); if (cont != null) { Streams.drain(cont); } util = new TimeStampDataUtil(timeStampedData); } } catch (IOException e) { throw new CMSException("unable to parse evidence block: " + e.getMessage(), e); } } } bouncycastle-1.49.orig/jdk1.3/org/bouncycastle/tsp/cms/CMSTimeStampedGenerator.java0000644000175000017500000000601712103632343027567 0ustar ebourgebourgpackage org.bouncycastle.tsp.cms; import java.net.URL; import org.bouncycastle.asn1.ASN1Boolean; import org.bouncycastle.asn1.DERBoolean; import org.bouncycastle.asn1.DERIA5String; import org.bouncycastle.asn1.DERUTF8String; import org.bouncycastle.asn1.cms.Attributes; import org.bouncycastle.asn1.cms.MetaData; import org.bouncycastle.cms.CMSException; import org.bouncycastle.operator.DigestCalculator; import org.bouncycastle.util.Integers; public class CMSTimeStampedGenerator { protected MetaData metaData; protected URL dataUri; /** * Set the dataURL to be included in message. * * @param dataUri URL for the data the initial message imprint digest is based on. */ public void setDataUri(URL dataUri) { this.dataUri = dataUri; } /** * Set the MetaData for the generated message. * * @param hashProtected true if the MetaData should be included in first imprint calculation, false otherwise. * @param fileName optional file name, may be null. * @param mediaType optional media type, may be null. */ public void setMetaData(boolean hashProtected, String fileName, String mediaType) { setMetaData(hashProtected, fileName, mediaType, null); } /** * Set the MetaData for the generated message. * * @param hashProtected true if the MetaData should be included in first imprint calculation, false otherwise. * @param fileName optional file name, may be null. * @param mediaType optional media type, may be null. * @param attributes optional attributes, may be null. */ public void setMetaData(boolean hashProtected, String fileName, String mediaType, Attributes attributes) { DERUTF8String asn1FileName = null; if (fileName != null) { asn1FileName = new DERUTF8String(fileName); } DERIA5String asn1MediaType = null; if (mediaType != null) { asn1MediaType = new DERIA5String(mediaType); } setMetaData(hashProtected, asn1FileName, asn1MediaType, attributes); } private void setMetaData(boolean hashProtected, DERUTF8String fileName, DERIA5String mediaType, Attributes attributes) { this.metaData = new MetaData(ASN1Boolean.getInstance(hashProtected), fileName, mediaType, attributes); } /** * Initialise the passed in calculator with the MetaData for this message, if it is * required as part of the initial message imprint calculation. After initialisation the * calculator can then be used to calculate the initial message imprint digest for the first * timestamp. * * @param calculator the digest calculator to be initialised. * @throws CMSException if the MetaData is required and cannot be processed */ public void initialiseMessageImprintDigestCalculator(DigestCalculator calculator) throws CMSException { MetaDataUtil util = new MetaDataUtil(metaData); util.initialiseMessageImprintDigestCalculator(calculator); } } bouncycastle-1.49.orig/jdk1.3/org/bouncycastle/tsp/cms/CMSTimeStampedData.java0000644000175000017500000001542011531052564026515 0ustar ebourgebourgpackage org.bouncycastle.tsp.cms; import java.io.ByteArrayInputStream; import java.io.IOException; import java.io.InputStream; import java.net.URL; import java.net.MalformedURLException; import org.bouncycastle.asn1.ASN1InputStream; import org.bouncycastle.asn1.DERIA5String; import org.bouncycastle.asn1.cms.AttributeTable; import org.bouncycastle.asn1.cms.CMSObjectIdentifiers; import org.bouncycastle.asn1.cms.ContentInfo; import org.bouncycastle.asn1.cms.Evidence; import org.bouncycastle.asn1.cms.TimeStampAndCRL; import org.bouncycastle.asn1.cms.TimeStampTokenEvidence; import org.bouncycastle.asn1.cms.TimeStampedData; import org.bouncycastle.cms.CMSException; import org.bouncycastle.operator.DigestCalculator; import org.bouncycastle.operator.DigestCalculatorProvider; import org.bouncycastle.operator.OperatorCreationException; import org.bouncycastle.tsp.TimeStampToken; public class CMSTimeStampedData { private TimeStampedData timeStampedData; private ContentInfo contentInfo; private TimeStampDataUtil util; public CMSTimeStampedData(ContentInfo contentInfo) { this.initialize(contentInfo); } public CMSTimeStampedData(InputStream in) throws IOException { try { initialize(ContentInfo.getInstance(new ASN1InputStream(in).readObject())); } catch (ClassCastException e) { throw new IOException("Malformed content: " + e); } catch (IllegalArgumentException e) { throw new IOException("Malformed content: " + e); } } public CMSTimeStampedData(byte[] baseData) throws IOException { this(new ByteArrayInputStream(baseData)); } private void initialize(ContentInfo contentInfo) { this.contentInfo = contentInfo; if (CMSObjectIdentifiers.timestampedData.equals(contentInfo.getContentType())) { this.timeStampedData = TimeStampedData.getInstance(contentInfo.getContent()); } else { throw new IllegalArgumentException("Malformed content - type must be " + CMSObjectIdentifiers.timestampedData.getId()); } util = new TimeStampDataUtil(this.timeStampedData); } public byte[] calculateNextHash(DigestCalculator calculator) throws CMSException { return util.calculateNextHash(calculator); } /** * Return a new timeStampedData object with the additional token attached. * * @throws CMSException */ public CMSTimeStampedData addTimeStamp(TimeStampToken token) throws CMSException { TimeStampAndCRL[] timeStamps = util.getTimeStamps(); TimeStampAndCRL[] newTimeStamps = new TimeStampAndCRL[timeStamps.length + 1]; System.arraycopy(timeStamps, 0, newTimeStamps, 0, timeStamps.length); newTimeStamps[timeStamps.length] = new TimeStampAndCRL(token.toCMSSignedData().getContentInfo()); return new CMSTimeStampedData(new ContentInfo(CMSObjectIdentifiers.timestampedData, new TimeStampedData(timeStampedData.getDataUri(), timeStampedData.getMetaData(), timeStampedData.getContent(), new Evidence(new TimeStampTokenEvidence(newTimeStamps))))); } public byte[] getContent() { if (timeStampedData.getContent() != null) { return timeStampedData.getContent().getOctets(); } return null; } public URL getDataUri() throws MalformedURLException { DERIA5String dataURI = this.timeStampedData.getDataUri(); if (dataURI != null) { return new URL(dataURI.getString()); } return null; } public String getFileName() { return util.getFileName(); } public String getMediaType() { return util.getMediaType(); } public AttributeTable getOtherMetaData() { return util.getOtherMetaData(); } public TimeStampToken[] getTimeStampTokens() throws CMSException { return util.getTimeStampTokens(); } /** * Initialise the passed in calculator with the MetaData for this message, if it is * required as part of the initial message imprint calculation. * * @param calculator the digest calculator to be initialised. * @throws CMSException if the MetaData is required and cannot be processed */ public void initialiseMessageImprintDigestCalculator(DigestCalculator calculator) throws CMSException { util.initialiseMessageImprintDigestCalculator(calculator); } /** * Returns an appropriately initialised digest calculator based on the message imprint algorithm * described in the first time stamp in the TemporalData for this message. If the metadata is required * to be included in the digest calculation, the returned calculator will be pre-initialised. * * @param calculatorProvider a provider of DigestCalculator objects. * @return an initialised digest calculator. * @throws OperatorCreationException if the provider is unable to create the calculator. */ public DigestCalculator getMessageImprintDigestCalculator(DigestCalculatorProvider calculatorProvider) throws OperatorCreationException { return util.getMessageImprintDigestCalculator(calculatorProvider); } /** * Validate the digests present in the TimeStampTokens contained in the CMSTimeStampedData. * * @param calculatorProvider provider for digest calculators * @param dataDigest the calculated data digest for the message * @throws ImprintDigestInvalidException if an imprint digest fails to compare * @throws CMSException if an exception occurs processing the message. */ public void validate(DigestCalculatorProvider calculatorProvider, byte[] dataDigest) throws ImprintDigestInvalidException, CMSException { util.validate(calculatorProvider, dataDigest); } /** * Validate the passed in timestamp token against the tokens and data present in the message. * * @param calculatorProvider provider for digest calculators * @param dataDigest the calculated data digest for the message. * @param timeStampToken the timestamp token of interest. * @throws ImprintDigestInvalidException if the token is not present in the message, or an imprint digest fails to compare. * @throws CMSException if an exception occurs processing the message. */ public void validate(DigestCalculatorProvider calculatorProvider, byte[] dataDigest, TimeStampToken timeStampToken) throws ImprintDigestInvalidException, CMSException { util.validate(calculatorProvider, dataDigest, timeStampToken); } public byte[] getEncoded() throws IOException { return contentInfo.getEncoded(); } } bouncycastle-1.49.orig/jdk1.3/org/bouncycastle/tsp/TimeStampToken.java0000644000175000017500000003767612104173672025310 0ustar ebourgebourgpackage org.bouncycastle.tsp; import java.io.ByteArrayInputStream; import java.io.ByteArrayOutputStream; import java.io.IOException; import java.io.OutputStream; import java.security.MessageDigest; import java.security.NoSuchAlgorithmException; import java.security.NoSuchProviderException; import org.bouncycastle.jce.cert.CertStore; import java.security.cert.CertificateEncodingException; import java.security.cert.CertificateExpiredException; import java.security.cert.CertificateNotYetValidException; import java.security.cert.X509Certificate; import java.util.Collection; import java.util.Date; import org.bouncycastle.asn1.ASN1InputStream; import org.bouncycastle.asn1.cms.Attribute; import org.bouncycastle.asn1.cms.AttributeTable; import org.bouncycastle.asn1.cms.ContentInfo; import org.bouncycastle.asn1.cms.IssuerAndSerialNumber; import org.bouncycastle.asn1.ess.ESSCertID; import org.bouncycastle.asn1.ess.ESSCertIDv2; import org.bouncycastle.asn1.ess.SigningCertificate; import org.bouncycastle.asn1.ess.SigningCertificateV2; import org.bouncycastle.asn1.nist.NISTObjectIdentifiers; import org.bouncycastle.asn1.oiw.OIWObjectIdentifiers; import org.bouncycastle.asn1.pkcs.PKCSObjectIdentifiers; import org.bouncycastle.asn1.tsp.TSTInfo; import org.bouncycastle.asn1.x500.X500Name; import org.bouncycastle.asn1.x509.AlgorithmIdentifier; import org.bouncycastle.asn1.x509.GeneralName; import org.bouncycastle.asn1.x509.IssuerSerial; import org.bouncycastle.asn1.x509.X509Name; import org.bouncycastle.cert.X509CertificateHolder; import org.bouncycastle.cms.CMSException; import org.bouncycastle.cms.CMSProcessable; import org.bouncycastle.cms.CMSSignedData; import org.bouncycastle.cms.SignerId; import org.bouncycastle.cms.SignerInformation; import org.bouncycastle.cms.SignerInformationVerifier; import org.bouncycastle.jce.PrincipalUtil; import org.bouncycastle.jce.X509Principal; import org.bouncycastle.operator.DigestCalculator; import org.bouncycastle.operator.OperatorCreationException; import org.bouncycastle.util.Arrays; import org.bouncycastle.util.Store; public class TimeStampToken { CMSSignedData tsToken; SignerInformation tsaSignerInfo; Date genTime; TimeStampTokenInfo tstInfo; CertID certID; public TimeStampToken(ContentInfo contentInfo) throws TSPException, IOException { this(getSignedData(contentInfo)); } private static CMSSignedData getSignedData(ContentInfo contentInfo) throws TSPException { try { return new CMSSignedData(contentInfo); } catch (CMSException e) { throw new TSPException("TSP parsing error: " + e.getMessage(), e.getCause()); } } public TimeStampToken(CMSSignedData signedData) throws TSPException, IOException { this.tsToken = signedData; if (!this.tsToken.getSignedContentTypeOID().equals(PKCSObjectIdentifiers.id_ct_TSTInfo.getId())) { throw new TSPValidationException("ContentInfo object not for a time stamp."); } Collection signers = tsToken.getSignerInfos().getSigners(); if (signers.size() != 1) { throw new IllegalArgumentException("Time-stamp token signed by " + signers.size() + " signers, but it must contain just the TSA signature."); } tsaSignerInfo = (SignerInformation)signers.iterator().next(); try { CMSProcessable content = tsToken.getSignedContent(); ByteArrayOutputStream bOut = new ByteArrayOutputStream(); content.write(bOut); ASN1InputStream aIn = new ASN1InputStream(new ByteArrayInputStream(bOut.toByteArray())); this.tstInfo = new TimeStampTokenInfo(TSTInfo.getInstance(aIn.readObject())); Attribute attr = tsaSignerInfo.getSignedAttributes().get(PKCSObjectIdentifiers.id_aa_signingCertificate); if (attr != null) { SigningCertificate signCert = SigningCertificate.getInstance(attr.getAttrValues().getObjectAt(0)); this.certID = new CertID(ESSCertID.getInstance(signCert.getCerts()[0])); } else { attr = tsaSignerInfo.getSignedAttributes().get(PKCSObjectIdentifiers.id_aa_signingCertificateV2); if (attr == null) { throw new TSPValidationException("no signing certificate attribute found, time stamp invalid."); } SigningCertificateV2 signCertV2 = SigningCertificateV2.getInstance(attr.getAttrValues().getObjectAt(0)); this.certID = new CertID(ESSCertIDv2.getInstance(signCertV2.getCerts()[0])); } } catch (CMSException e) { throw new TSPException(e.getMessage(), e.getUnderlyingException()); } } public TimeStampTokenInfo getTimeStampInfo() { return tstInfo; } public SignerId getSID() { return tsaSignerInfo.getSID(); } public AttributeTable getSignedAttributes() { return tsaSignerInfo.getSignedAttributes(); } public AttributeTable getUnsignedAttributes() { return tsaSignerInfo.getUnsignedAttributes(); } /** * @deprecated use getCertificates() or getCRLs() */ public CertStore getCertificatesAndCRLs( String type, String provider) throws NoSuchAlgorithmException, NoSuchProviderException, CMSException { return tsToken.getCertificatesAndCRLs(type, provider); } public Store getCertificates() { return tsToken.getCertificates(); } public Store getCRLs() { return tsToken.getCRLs(); } public Store getAttributeCertificates() { return tsToken.getAttributeCertificates(); } /** * Validate the time stamp token. *

* To be valid the token must be signed by the passed in certificate and * the certificate must be the one referred to by the SigningCertificate * attribute included in the hashed attributes of the token. The * certificate must also have the ExtendedKeyUsageExtension with only * KeyPurposeId.id_kp_timeStamping and have been valid at the time the * timestamp was created. *

*

* A successful call to validate means all the above are true. *

* @deprecated */ public void validate( X509Certificate cert, String provider) throws TSPException, TSPValidationException, CertificateExpiredException, CertificateNotYetValidException, NoSuchProviderException { try { if (!Arrays.constantTimeAreEqual(certID.getCertHash(), MessageDigest.getInstance(certID.getHashAlgorithmName()).digest(cert.getEncoded()))) { throw new TSPValidationException("certificate hash does not match certID hash."); } if (certID.getIssuerSerial() != null) { if (!certID.getIssuerSerial().getSerial().getValue().equals(cert.getSerialNumber())) { throw new TSPValidationException("certificate serial number does not match certID for signature."); } GeneralName[] names = certID.getIssuerSerial().getIssuer().getNames(); X509Principal principal = PrincipalUtil.getIssuerX509Principal(cert); boolean found = false; for (int i = 0; i != names.length; i++) { if (names[i].getTagNo() == 4 && new X509Principal(X509Name.getInstance(names[i].getName())).equals(principal)) { found = true; break; } } if (!found) { throw new TSPValidationException("certificate name does not match certID for signature. "); } } TSPUtil.validateCertificate(cert); cert.checkValidity(tstInfo.getGenTime()); if (!tsaSignerInfo.verify(cert, provider)) { throw new TSPValidationException("signature not created by certificate."); } } catch (CMSException e) { if (e.getUnderlyingException() != null) { throw new TSPException(e.getMessage(), e.getUnderlyingException()); } else { throw new TSPException("CMS exception: " + e, e); } } catch (NoSuchAlgorithmException e) { throw new TSPException("cannot find algorithm: " + e, e); } catch (CertificateEncodingException e) { throw new TSPException("problem processing certificate: " + e, e); } } /** * Validate the time stamp token. *

* To be valid the token must be signed by the passed in certificate and * the certificate must be the one referred to by the SigningCertificate * attribute included in the hashed attributes of the token. The * certificate must also have the ExtendedKeyUsageExtension with only * KeyPurposeId.id_kp_timeStamping and have been valid at the time the * timestamp was created. *

*

* A successful call to validate means all the above are true. *

* * @param sigVerifier the content verifier create the objects required to verify the CMS object in the timestamp. * @throws TSPException if an exception occurs in processing the token. * @throws TSPValidationException if the certificate or signature fail to be valid. * @throws IllegalArgumentException if the sigVerifierProvider has no associated certificate. */ public void validate( SignerInformationVerifier sigVerifier) throws TSPException, TSPValidationException { if (!sigVerifier.hasAssociatedCertificate()) { throw new IllegalArgumentException("verifier provider needs an associated certificate"); } try { X509CertificateHolder certHolder = sigVerifier.getAssociatedCertificate(); DigestCalculator calc = sigVerifier.getDigestCalculator(certID.getHashAlgorithm()); OutputStream cOut = calc.getOutputStream(); cOut.write(certHolder.getEncoded()); cOut.close(); if (!Arrays.constantTimeAreEqual(certID.getCertHash(), calc.getDigest())) { throw new TSPValidationException("certificate hash does not match certID hash."); } if (certID.getIssuerSerial() != null) { IssuerAndSerialNumber issuerSerial = new IssuerAndSerialNumber(certHolder.toASN1Structure()); if (!certID.getIssuerSerial().getSerial().equals(issuerSerial.getSerialNumber())) { throw new TSPValidationException("certificate serial number does not match certID for signature."); } GeneralName[] names = certID.getIssuerSerial().getIssuer().getNames(); boolean found = false; for (int i = 0; i != names.length; i++) { if (names[i].getTagNo() == 4 && X500Name.getInstance(names[i].getName()).equals(X500Name.getInstance(issuerSerial.getName()))) { found = true; break; } } if (!found) { throw new TSPValidationException("certificate name does not match certID for signature. "); } } TSPUtil.validateCertificate(certHolder); if (!certHolder.isValidOn(tstInfo.getGenTime())) { throw new TSPValidationException("certificate not valid when time stamp created."); } if (!tsaSignerInfo.verify(sigVerifier)) { throw new TSPValidationException("signature not created by certificate."); } } catch (CMSException e) { if (e.getUnderlyingException() != null) { throw new TSPException(e.getMessage(), e.getUnderlyingException()); } else { throw new TSPException("CMS exception: " + e, e); } } catch (IOException e) { throw new TSPException("problem processing certificate: " + e, e); } catch (OperatorCreationException e) { throw new TSPException("unable to create digest: " + e.getMessage(), e); } } /** * Return true if the signature on time stamp token is valid. *

* Note: this is a much weaker proof of correctness than calling validate(). *

* * @param sigVerifier the content verifier create the objects required to verify the CMS object in the timestamp. * @return true if the signature matches, false otherwise. * @throws TSPException if the signature cannot be processed or the provider cannot match the algorithm. */ public boolean isSignatureValid( SignerInformationVerifier sigVerifier) throws TSPException { try { return tsaSignerInfo.verify(sigVerifier); } catch (CMSException e) { if (e.getUnderlyingException() != null) { throw new TSPException(e.getMessage(), e.getUnderlyingException()); } else { throw new TSPException("CMS exception: " + e, e); } } } /** * Return the underlying CMSSignedData object. * * @return the underlying CMS structure. */ public CMSSignedData toCMSSignedData() { return tsToken; } /** * Return a ASN.1 encoded byte stream representing the encoded object. * * @throws IOException if encoding fails. */ public byte[] getEncoded() throws IOException { return tsToken.getEncoded(); } // perhaps this should be done using an interface on the ASN.1 classes... private class CertID { private ESSCertID certID; private ESSCertIDv2 certIDv2; CertID(ESSCertID certID) { this.certID = certID; this.certIDv2 = null; } CertID(ESSCertIDv2 certID) { this.certIDv2 = certID; this.certID = null; } public String getHashAlgorithmName() { if (certID != null) { return "SHA-1"; } else { if (NISTObjectIdentifiers.id_sha256.equals(certIDv2.getHashAlgorithm().getAlgorithm())) { return "SHA-256"; } return certIDv2.getHashAlgorithm().getAlgorithm().getId(); } } public AlgorithmIdentifier getHashAlgorithm() { if (certID != null) { return new AlgorithmIdentifier(OIWObjectIdentifiers.idSHA1); } else { return certIDv2.getHashAlgorithm(); } } public byte[] getCertHash() { if (certID != null) { return certID.getCertHash(); } else { return certIDv2.getCertHash(); } } public IssuerSerial getIssuerSerial() { if (certID != null) { return certID.getIssuerSerial(); } else { return certIDv2.getIssuerSerial(); } } } } bouncycastle-1.49.orig/jdk1.3/org/bouncycastle/tsp/TSPUtil.java0000644000175000017500000003642412103632343023670 0ustar ebourgebourgpackage org.bouncycastle.tsp; import java.io.ByteArrayInputStream; import java.io.IOException; import java.io.OutputStream; import java.security.MessageDigest; import java.security.NoSuchAlgorithmException; import java.security.NoSuchProviderException; import java.security.Provider; import java.security.cert.X509Certificate; import java.util.ArrayList; import java.util.Collection; import java.util.Collections; import java.util.HashMap; import java.util.HashSet; import java.util.List; import java.util.Map; import java.util.Set; import org.bouncycastle.asn1.ASN1Encodable; import org.bouncycastle.asn1.ASN1EncodableVector; import org.bouncycastle.asn1.ASN1InputStream; import org.bouncycastle.asn1.ASN1ObjectIdentifier; import org.bouncycastle.asn1.ASN1OctetString; import org.bouncycastle.asn1.ASN1Set; import org.bouncycastle.asn1.cms.Attribute; import org.bouncycastle.asn1.cms.AttributeTable; import org.bouncycastle.asn1.cms.ContentInfo; import org.bouncycastle.asn1.cryptopro.CryptoProObjectIdentifiers; import org.bouncycastle.asn1.nist.NISTObjectIdentifiers; import org.bouncycastle.asn1.oiw.OIWObjectIdentifiers; import org.bouncycastle.asn1.pkcs.PKCSObjectIdentifiers; import org.bouncycastle.asn1.teletrust.TeleTrusTObjectIdentifiers; import org.bouncycastle.asn1.x509.ExtendedKeyUsage; import org.bouncycastle.asn1.x509.Extension; import org.bouncycastle.asn1.x509.Extensions; import org.bouncycastle.asn1.x509.ExtensionsGenerator; import org.bouncycastle.asn1.x509.KeyPurposeId; import org.bouncycastle.asn1.x509.X509Extensions; import org.bouncycastle.cert.X509CertificateHolder; import org.bouncycastle.cms.SignerInformation; import org.bouncycastle.operator.DigestCalculator; import org.bouncycastle.operator.DigestCalculatorProvider; import org.bouncycastle.operator.OperatorCreationException; import org.bouncycastle.util.Arrays; import org.bouncycastle.util.Integers; public class TSPUtil { private static Set EMPTY_SET = Collections.unmodifiableSet(new HashSet()); private static List EMPTY_LIST = Collections.unmodifiableList(new ArrayList()); private static final Map digestLengths = new HashMap(); private static final Map digestNames = new HashMap(); static { digestLengths.put(PKCSObjectIdentifiers.md5.getId(), Integers.valueOf(16)); digestLengths.put(OIWObjectIdentifiers.idSHA1.getId(), Integers.valueOf(20)); digestLengths.put(NISTObjectIdentifiers.id_sha224.getId(), Integers.valueOf(28)); digestLengths.put(NISTObjectIdentifiers.id_sha256.getId(), Integers.valueOf(32)); digestLengths.put(NISTObjectIdentifiers.id_sha384.getId(), Integers.valueOf(48)); digestLengths.put(NISTObjectIdentifiers.id_sha512.getId(), Integers.valueOf(64)); digestLengths.put(TeleTrusTObjectIdentifiers.ripemd128.getId(), Integers.valueOf(16)); digestLengths.put(TeleTrusTObjectIdentifiers.ripemd160.getId(), Integers.valueOf(20)); digestLengths.put(TeleTrusTObjectIdentifiers.ripemd256.getId(), Integers.valueOf(32)); digestLengths.put(CryptoProObjectIdentifiers.gostR3411.getId(), Integers.valueOf(32)); digestNames.put(PKCSObjectIdentifiers.md5.getId(), "MD5"); digestNames.put(OIWObjectIdentifiers.idSHA1.getId(), "SHA1"); digestNames.put(NISTObjectIdentifiers.id_sha224.getId(), "SHA224"); digestNames.put(NISTObjectIdentifiers.id_sha256.getId(), "SHA256"); digestNames.put(NISTObjectIdentifiers.id_sha384.getId(), "SHA384"); digestNames.put(NISTObjectIdentifiers.id_sha512.getId(), "SHA512"); digestNames.put(PKCSObjectIdentifiers.sha1WithRSAEncryption.getId(), "SHA1"); digestNames.put(PKCSObjectIdentifiers.sha224WithRSAEncryption.getId(), "SHA224"); digestNames.put(PKCSObjectIdentifiers.sha256WithRSAEncryption.getId(), "SHA256"); digestNames.put(PKCSObjectIdentifiers.sha384WithRSAEncryption.getId(), "SHA384"); digestNames.put(PKCSObjectIdentifiers.sha512WithRSAEncryption.getId(), "SHA512"); digestNames.put(TeleTrusTObjectIdentifiers.ripemd128.getId(), "RIPEMD128"); digestNames.put(TeleTrusTObjectIdentifiers.ripemd160.getId(), "RIPEMD160"); digestNames.put(TeleTrusTObjectIdentifiers.ripemd256.getId(), "RIPEMD256"); digestNames.put(CryptoProObjectIdentifiers.gostR3411.getId(), "GOST3411"); } /** * Fetches the signature time-stamp attributes from a SignerInformation object. * Checks that the MessageImprint for each time-stamp matches the signature field. * (see RFC 3161 Appendix A). * * @param signerInfo a SignerInformation to search for time-stamps * @param provider an optional provider to use to create MessageDigest instances * @return a collection of TimeStampToken objects * @throws TSPValidationException * @deprecated use getSignatureTimestamps(SignerInformation, DigestCalculatorProvider) */ public static Collection getSignatureTimestamps(SignerInformation signerInfo, Provider provider) throws TSPValidationException { List timestamps = new ArrayList(); AttributeTable unsignedAttrs = signerInfo.getUnsignedAttributes(); if (unsignedAttrs != null) { ASN1EncodableVector allTSAttrs = unsignedAttrs.getAll( PKCSObjectIdentifiers.id_aa_signatureTimeStampToken); for (int i = 0; i < allTSAttrs.size(); ++i) { Attribute tsAttr = (Attribute)allTSAttrs.get(i); ASN1Set tsAttrValues = tsAttr.getAttrValues(); for (int j = 0; j < tsAttrValues.size(); ++j) { try { ContentInfo contentInfo = ContentInfo.getInstance(tsAttrValues.getObjectAt(j)); TimeStampToken timeStampToken = new TimeStampToken(contentInfo); TimeStampTokenInfo tstInfo = timeStampToken.getTimeStampInfo(); MessageDigest digest = createDigestInstance(tstInfo.getMessageImprintAlgOID().getId(), provider); byte[] expectedDigest = digest.digest(signerInfo.getSignature()); if (!Arrays.constantTimeAreEqual(expectedDigest, tstInfo.getMessageImprintDigest())) { throw new TSPValidationException("Incorrect digest in message imprint"); } timestamps.add(timeStampToken); } catch (NoSuchAlgorithmException e) { throw new TSPValidationException("Unknown hash algorithm specified in timestamp"); } catch (Exception e) { throw new TSPValidationException("Timestamp could not be parsed"); } } } } return timestamps; } /** * Fetches the signature time-stamp attributes from a SignerInformation object. * Checks that the MessageImprint for each time-stamp matches the signature field. * (see RFC 3161 Appendix A). * * @param signerInfo a SignerInformation to search for time-stamps * @param digCalcProvider provider for digest calculators * @return a collection of TimeStampToken objects * @throws TSPValidationException */ public static Collection getSignatureTimestamps(SignerInformation signerInfo, DigestCalculatorProvider digCalcProvider) throws TSPValidationException { List timestamps = new ArrayList(); AttributeTable unsignedAttrs = signerInfo.getUnsignedAttributes(); if (unsignedAttrs != null) { ASN1EncodableVector allTSAttrs = unsignedAttrs.getAll( PKCSObjectIdentifiers.id_aa_signatureTimeStampToken); for (int i = 0; i < allTSAttrs.size(); ++i) { Attribute tsAttr = (Attribute)allTSAttrs.get(i); ASN1Set tsAttrValues = tsAttr.getAttrValues(); for (int j = 0; j < tsAttrValues.size(); ++j) { try { ContentInfo contentInfo = ContentInfo.getInstance(tsAttrValues.getObjectAt(j)); TimeStampToken timeStampToken = new TimeStampToken(contentInfo); TimeStampTokenInfo tstInfo = timeStampToken.getTimeStampInfo(); DigestCalculator digCalc = digCalcProvider.get(tstInfo.getHashAlgorithm()); OutputStream dOut = digCalc.getOutputStream(); dOut.write(signerInfo.getSignature()); dOut.close(); byte[] expectedDigest = digCalc.getDigest(); if (!Arrays.constantTimeAreEqual(expectedDigest, tstInfo.getMessageImprintDigest())) { throw new TSPValidationException("Incorrect digest in message imprint"); } timestamps.add(timeStampToken); } catch (OperatorCreationException e) { throw new TSPValidationException("Unknown hash algorithm specified in timestamp"); } catch (Exception e) { throw new TSPValidationException("Timestamp could not be parsed"); } } } } return timestamps; } /** * Validate the passed in certificate as being of the correct type to be used * for time stamping. To be valid it must have an ExtendedKeyUsage extension * which has a key purpose identifier of id-kp-timeStamping. * * @param cert the certificate of interest. * @throws TSPValidationException if the certicate fails on one of the check points. */ public static void validateCertificate( X509Certificate cert) throws TSPValidationException { if (cert.getVersion() != 3) { throw new IllegalArgumentException("Certificate must have an ExtendedKeyUsage extension."); } byte[] ext = cert.getExtensionValue(X509Extensions.ExtendedKeyUsage.getId()); if (ext == null) { throw new TSPValidationException("Certificate must have an ExtendedKeyUsage extension."); } if (!cert.getCriticalExtensionOIDs().contains(X509Extensions.ExtendedKeyUsage.getId())) { throw new TSPValidationException("Certificate must have an ExtendedKeyUsage extension marked as critical."); } ASN1InputStream aIn = new ASN1InputStream(new ByteArrayInputStream(ext)); try { aIn = new ASN1InputStream(new ByteArrayInputStream(((ASN1OctetString)aIn.readObject()).getOctets())); ExtendedKeyUsage extKey = ExtendedKeyUsage.getInstance(aIn.readObject()); if (!extKey.hasKeyPurposeId(KeyPurposeId.id_kp_timeStamping) || extKey.size() != 1) { throw new TSPValidationException("ExtendedKeyUsage not solely time stamping."); } } catch (IOException e) { throw new TSPValidationException("cannot process ExtendedKeyUsage extension"); } } /** * Validate the passed in certificate as being of the correct type to be used * for time stamping. To be valid it must have an ExtendedKeyUsage extension * which has a key purpose identifier of id-kp-timeStamping. * * @param cert the certificate of interest. * @throws TSPValidationException if the certicate fails on one of the check points. */ public static void validateCertificate( X509CertificateHolder cert) throws TSPValidationException { if (cert.toASN1Structure().getVersionNumber() != 3) { throw new IllegalArgumentException("Certificate must have an ExtendedKeyUsage extension."); } Extension ext = cert.getExtension(Extension.extendedKeyUsage); if (ext == null) { throw new TSPValidationException("Certificate must have an ExtendedKeyUsage extension."); } if (!ext.isCritical()) { throw new TSPValidationException("Certificate must have an ExtendedKeyUsage extension marked as critical."); } ExtendedKeyUsage extKey = ExtendedKeyUsage.getInstance(ext.getParsedValue()); if (!extKey.hasKeyPurposeId(KeyPurposeId.id_kp_timeStamping) || extKey.size() != 1) { throw new TSPValidationException("ExtendedKeyUsage not solely time stamping."); } } /* * Return the digest algorithm using one of the standard JCA string * representations rather than the algorithm identifier (if possible). */ static String getDigestAlgName( String digestAlgOID) { String digestName = (String)digestNames.get(digestAlgOID); if (digestName != null) { return digestName; } return digestAlgOID; } static int getDigestLength( String digestAlgOID) throws TSPException { Integer length = (Integer)digestLengths.get(digestAlgOID); if (length != null) { return length.intValue(); } throw new TSPException("digest algorithm cannot be found."); } static MessageDigest createDigestInstance(String digestAlgOID, Provider provider) throws NoSuchAlgorithmException { String digestName = TSPUtil.getDigestAlgName(digestAlgOID); if (provider != null) { try { return MessageDigest.getInstance(digestName, provider.getName()); } catch (NoSuchAlgorithmException e) { // Ignore } catch (NoSuchProviderException e) { // Ignore } } return MessageDigest.getInstance(digestName); } static Set getCriticalExtensionOIDs(X509Extensions extensions) { if (extensions == null) { return EMPTY_SET; } return Collections.unmodifiableSet(new HashSet(java.util.Arrays.asList(extensions.getCriticalExtensionOIDs()))); } static Set getNonCriticalExtensionOIDs(X509Extensions extensions) { if (extensions == null) { return EMPTY_SET; } // TODO: should probably produce a set that imposes correct ordering return Collections.unmodifiableSet(new HashSet(java.util.Arrays.asList(extensions.getNonCriticalExtensionOIDs()))); } static List getExtensionOIDs(Extensions extensions) { if (extensions == null) { return EMPTY_LIST; } return Collections.unmodifiableList(java.util.Arrays.asList(extensions.getExtensionOIDs())); } static void addExtension(ExtensionsGenerator extGenerator, ASN1ObjectIdentifier oid, boolean isCritical, ASN1Encodable value) throws TSPIOException { try { extGenerator.addExtension(oid, isCritical, value); } catch (IOException e) { throw new TSPIOException("cannot encode extension: " + e.getMessage(), e); } } } bouncycastle-1.49.orig/jdk1.3/org/bouncycastle/eac/0000755000175000017500000000000012152033550021431 5ustar ebourgebourgbouncycastle-1.49.orig/jdk1.3/org/bouncycastle/eac/operator/0000755000175000017500000000000012152033550023264 5ustar ebourgebourgbouncycastle-1.49.orig/jdk1.3/org/bouncycastle/eac/operator/jcajce/0000755000175000017500000000000012152033550024503 5ustar ebourgebourgbouncycastle-1.49.orig/jdk1.3/org/bouncycastle/eac/operator/jcajce/ProviderEACHelper.java0000644000175000017500000000107611702763111030620 0ustar ebourgebourgpackage org.bouncycastle.eac.operator.jcajce; import java.security.NoSuchAlgorithmException; import java.security.NoSuchProviderException; import java.security.Provider; import java.security.Signature; class ProviderEACHelper extends EACHelper { private final Provider provider; ProviderEACHelper(Provider provider) { this.provider = provider; } protected Signature createSignature(String type) throws NoSuchAlgorithmException, NoSuchProviderException { return Signature.getInstance(type, provider.getName()); } } bouncycastle-1.49.orig/jdk1.3/org/bouncycastle/eac/jcajce/0000755000175000017500000000000012152033550022650 5ustar ebourgebourgbouncycastle-1.49.orig/jdk1.3/org/bouncycastle/eac/jcajce/ProviderEACHelper.java0000644000175000017500000000107111723774500026767 0ustar ebourgebourgpackage org.bouncycastle.eac.jcajce; import java.security.KeyFactory; import java.security.NoSuchAlgorithmException; import java.security.NoSuchProviderException; import java.security.Provider; class ProviderEACHelper implements EACHelper { private final Provider provider; ProviderEACHelper(Provider provider) { this.provider = provider; } public KeyFactory createKeyFactory(String type) throws NoSuchAlgorithmException, NoSuchProviderException { return KeyFactory.getInstance(type, provider.getName()); } } bouncycastle-1.49.orig/jdk1.3/org/bouncycastle/x509/0000755000175000017500000000000012152033550021406 5ustar ebourgebourgbouncycastle-1.49.orig/jdk1.3/org/bouncycastle/x509/AttributeCertificateIssuer.java0000644000175000017500000001274611725245373027601 0ustar ebourgebourgpackage org.bouncycastle.x509; import java.io.IOException; import java.security.Principal; import java.security.cert.Certificate; import java.security.cert.CertificateEncodingException; import java.security.cert.X509Certificate; import java.util.ArrayList; import java.util.List; import org.bouncycastle.asn1.ASN1Encodable; import org.bouncycastle.asn1.x509.AttCertIssuer; import org.bouncycastle.asn1.x509.GeneralName; import org.bouncycastle.asn1.x509.GeneralNames; import org.bouncycastle.asn1.x509.V2Form; import org.bouncycastle.jce.PrincipalUtil; import org.bouncycastle.jce.X509Principal; import org.bouncycastle.jce.cert.CertSelector; import org.bouncycastle.util.Selector; /** * Carrying class for an attribute certificate issuer. */ public class AttributeCertificateIssuer implements CertSelector, Selector { final ASN1Encodable form; /** * @param issuer */ AttributeCertificateIssuer( AttCertIssuer issuer) { form = issuer.getIssuer(); } public AttributeCertificateIssuer( X509Principal principal) { form = new V2Form(new GeneralNames(new GeneralName(principal))); } private Object[] getNames() { GeneralNames name; if (form instanceof V2Form) { name = ((V2Form)form).getIssuerName(); } else { name = (GeneralNames)form; } GeneralName[] names = name.getNames(); List l = new ArrayList(names.length); for (int i = 0; i != names.length; i++) { if (names[i].getTagNo() == GeneralName.directoryName) { try { l.add(new X509Principal(((ASN1Encodable)names[i].getName()).toASN1Primitive().getEncoded())); } catch (IOException e) { throw new RuntimeException("badly formed Name object"); } } } return l.toArray(new Object[l.size()]); } /** * Return any principal objects inside the attribute certificate issuer object. * * @return an array of Principal objects (usually X509Principal) */ public Principal[] getPrincipals() { Object[] p = this.getNames(); List l = new ArrayList(); for (int i = 0; i != p.length; i++) { if (p[i] instanceof Principal) { l.add(p[i]); } } return (Principal[])l.toArray(new Principal[l.size()]); } private boolean matchesDN(X509Principal subject, GeneralNames targets) { GeneralName[] names = targets.getNames(); for (int i = 0; i != names.length; i++) { GeneralName gn = names[i]; if (gn.getTagNo() == GeneralName.directoryName) { try { if (new X509Principal(((ASN1Encodable)gn.getName()).toASN1Primitive().getEncoded()).equals(subject)) { return true; } } catch (IOException e) { } } } return false; } /* (non-Javadoc) * @see java.security.cert.CertSelector#clone() */ public Object clone() { return new AttributeCertificateIssuer(AttCertIssuer.getInstance(form)); } /* (non-Javadoc) * @see java.security.cert.CertSelector#match(java.security.cert.Certificate) */ public boolean match(Certificate cert) { if (!(cert instanceof X509Certificate)) { return false; } X509Certificate x509Cert = (X509Certificate)cert; try { if (form instanceof V2Form) { V2Form issuer = (V2Form)form; if (issuer.getBaseCertificateID() != null) { return issuer.getBaseCertificateID().getSerial().getValue().equals(x509Cert.getSerialNumber()) && matchesDN(PrincipalUtil.getIssuerX509Principal(x509Cert), issuer.getBaseCertificateID().getIssuer()); } GeneralNames name = issuer.getIssuerName(); if (matchesDN(PrincipalUtil.getSubjectX509Principal(x509Cert), name)) { return true; } } else { GeneralNames name = (GeneralNames)form; if (matchesDN(PrincipalUtil.getSubjectX509Principal(x509Cert), name)) { return true; } } } catch (CertificateEncodingException e) { return false; } return false; } public boolean equals(Object obj) { if (obj == this) { return true; } if (!(obj instanceof AttributeCertificateIssuer)) { return false; } AttributeCertificateIssuer other = (AttributeCertificateIssuer)obj; return this.form.equals(other.form); } public int hashCode() { return this.form.hashCode(); } public boolean match(Object obj) { if (!(obj instanceof X509Certificate)) { return false; } return match((Certificate)obj); } } bouncycastle-1.49.orig/jdk1.3/org/bouncycastle/x509/AttributeCertificateHolder.java0000644000175000017500000002746611726307316027546 0ustar ebourgebourgpackage org.bouncycastle.x509; import java.io.IOException; import java.math.BigInteger; import java.security.MessageDigest; import java.security.Principal; import java.security.cert.Certificate; import java.security.cert.CertificateEncodingException; import java.security.cert.CertificateParsingException; import java.security.cert.X509Certificate; import java.util.ArrayList; import java.util.List; import org.bouncycastle.asn1.ASN1Encodable; import org.bouncycastle.asn1.ASN1Integer; import org.bouncycastle.asn1.ASN1Sequence; import org.bouncycastle.asn1.ASN1ObjectIdentifier; import org.bouncycastle.asn1.x509.AlgorithmIdentifier; import org.bouncycastle.asn1.x509.GeneralName; import org.bouncycastle.asn1.x509.GeneralNames; import org.bouncycastle.asn1.x509.Holder; import org.bouncycastle.asn1.x509.IssuerSerial; import org.bouncycastle.asn1.x509.ObjectDigestInfo; import org.bouncycastle.jce.PrincipalUtil; import org.bouncycastle.jce.X509Principal; import org.bouncycastle.jce.cert.CertSelector; import org.bouncycastle.util.Arrays; import org.bouncycastle.util.Selector; /** * The Holder object. * *
 *          Holder ::= SEQUENCE {
 *                baseCertificateID   [0] IssuerSerial OPTIONAL,
 *                         -- the issuer and serial number of
 *                         -- the holder's Public Key Certificate
 *                entityName          [1] GeneralNames OPTIONAL,
 *                         -- the name of the claimant or role
 *                objectDigestInfo    [2] ObjectDigestInfo OPTIONAL
 *                         -- used to directly authenticate the holder,
 *                         -- for example, an executable
 *          }
 * 
* @deprecated use org.bouncycastle.cert.AttributeCertificateHolder */ public class AttributeCertificateHolder implements CertSelector, Selector { final Holder holder; AttributeCertificateHolder(ASN1Sequence seq) { holder = Holder.getInstance(seq); } public AttributeCertificateHolder(X509Principal issuerName, BigInteger serialNumber) { holder = new org.bouncycastle.asn1.x509.Holder(new IssuerSerial( new GeneralNames(new GeneralName(issuerName)), new ASN1Integer(serialNumber))); } public AttributeCertificateHolder(X509Certificate cert) throws CertificateParsingException { X509Principal name; try { name = PrincipalUtil.getIssuerX509Principal(cert); } catch (Exception e) { throw new CertificateParsingException(e.getMessage()); } holder = new Holder(new IssuerSerial(generateGeneralNames(name), new ASN1Integer(cert.getSerialNumber()))); } public AttributeCertificateHolder(X509Principal principal) { holder = new Holder(generateGeneralNames(principal)); } /** * Constructs a holder for v2 attribute certificates with a hash value for * some type of object. *

* digestedObjectType can be one of the following: *

*

* This cannot be used if a v1 attribute certificate is used. * * @param digestedObjectType The digest object type. * @param digestAlgorithm The algorithm identifier for the hash. * @param otherObjectTypeID The object type ID if * digestedObjectType is * otherObjectDigest. * @param objectDigest The hash value. */ public AttributeCertificateHolder(int digestedObjectType, String digestAlgorithm, String otherObjectTypeID, byte[] objectDigest) { holder = new Holder(new ObjectDigestInfo(digestedObjectType, new ASN1ObjectIdentifier(otherObjectTypeID), new AlgorithmIdentifier(digestAlgorithm), Arrays .clone(objectDigest))); } /** * Returns the digest object type if an object digest info is used. *

*

* * @return The digest object type or -1 if no object digest info is set. */ public int getDigestedObjectType() { if (holder.getObjectDigestInfo() != null) { return holder.getObjectDigestInfo().getDigestedObjectType() .getValue().intValue(); } return -1; } /** * Returns the other object type ID if an object digest info is used. * * @return The other object type ID or null if no object * digest info is set. */ public String getDigestAlgorithm() { if (holder.getObjectDigestInfo() != null) { return holder.getObjectDigestInfo().getDigestAlgorithm().getObjectId() .getId(); } return null; } /** * Returns the hash if an object digest info is used. * * @return The hash or null if no object digest info is set. */ public byte[] getObjectDigest() { if (holder.getObjectDigestInfo() != null) { return holder.getObjectDigestInfo().getObjectDigest().getBytes(); } return null; } /** * Returns the digest algorithm ID if an object digest info is used. * * @return The digest algorithm ID or null if no object * digest info is set. */ public String getOtherObjectTypeID() { if (holder.getObjectDigestInfo() != null) { holder.getObjectDigestInfo().getOtherObjectTypeID().getId(); } return null; } private GeneralNames generateGeneralNames(X509Principal principal) { return new GeneralNames(new GeneralName(principal)); } private boolean matchesDN(X509Principal subject, GeneralNames targets) { GeneralName[] names = targets.getNames(); for (int i = 0; i != names.length; i++) { GeneralName gn = names[i]; if (gn.getTagNo() == GeneralName.directoryName) { try { if (new X509Principal(((ASN1Encodable)gn.getName()).toASN1Primitive() .getEncoded()).equals(subject)) { return true; } } catch (IOException e) { } } } return false; } private Object[] getNames(GeneralName[] names) { List l = new ArrayList(names.length); for (int i = 0; i != names.length; i++) { if (names[i].getTagNo() == GeneralName.directoryName) { try { l.add(new X509Principal( ((ASN1Encodable)names[i].getName()).toASN1Primitive().getEncoded())); } catch (IOException e) { throw new RuntimeException("badly formed Name object"); } } } return l.toArray(new Object[l.size()]); } private Principal[] getPrincipals(GeneralNames names) { Object[] p = this.getNames(names.getNames()); List l = new ArrayList(); for (int i = 0; i != p.length; i++) { if (p[i] instanceof Principal) { l.add(p[i]); } } return (Principal[])l.toArray(new Principal[l.size()]); } /** * Return any principal objects inside the attribute certificate holder * entity names field. * * @return an array of Principal objects (usually X509Principal), null if no * entity names field is set. */ public Principal[] getEntityNames() { if (holder.getEntityName() != null) { return getPrincipals(holder.getEntityName()); } return null; } /** * Return the principals associated with the issuer attached to this holder * * @return an array of principals, null if no BaseCertificateID is set. */ public Principal[] getIssuer() { if (holder.getBaseCertificateID() != null) { return getPrincipals(holder.getBaseCertificateID().getIssuer()); } return null; } /** * Return the serial number associated with the issuer attached to this * holder. * * @return the certificate serial number, null if no BaseCertificateID is * set. */ public BigInteger getSerialNumber() { if (holder.getBaseCertificateID() != null) { return holder.getBaseCertificateID().getSerial().getValue(); } return null; } public Object clone() { return new AttributeCertificateHolder((ASN1Sequence)holder .toASN1Object()); } public boolean match(Certificate cert) { if (!(cert instanceof X509Certificate)) { return false; } X509Certificate x509Cert = (X509Certificate)cert; try { if (holder.getBaseCertificateID() != null) { return holder.getBaseCertificateID().getSerial().getValue().equals(x509Cert.getSerialNumber()) && matchesDN(PrincipalUtil.getIssuerX509Principal(x509Cert), holder.getBaseCertificateID().getIssuer()); } if (holder.getEntityName() != null) { if (matchesDN(PrincipalUtil.getSubjectX509Principal(x509Cert), holder.getEntityName())) { return true; } } if (holder.getObjectDigestInfo() != null) { MessageDigest md = null; try { md = MessageDigest.getInstance(getDigestAlgorithm(), "BC"); } catch (Exception e) { return false; } switch (getDigestedObjectType()) { case ObjectDigestInfo.publicKey: // TODO: DSA Dss-parms md.update(cert.getPublicKey().getEncoded()); break; case ObjectDigestInfo.publicKeyCert: md.update(cert.getEncoded()); break; } if (!Arrays.areEqual(md.digest(), getObjectDigest())) { return false; } } } catch (CertificateEncodingException e) { return false; } return false; } public boolean equals(Object obj) { if (obj == this) { return true; } if (!(obj instanceof AttributeCertificateHolder)) { return false; } AttributeCertificateHolder other = (AttributeCertificateHolder)obj; return this.holder.equals(other.holder); } public int hashCode() { return this.holder.hashCode(); } public boolean match(Object obj) { if (!(obj instanceof X509Certificate)) { return false; } return match((Certificate)obj); } } bouncycastle-1.49.orig/jdk1.3/org/bouncycastle/x509/X509CRLStoreSelector.java0000644000175000017500000002432310772043536026014 0ustar ebourgebourgpackage org.bouncycastle.x509; import org.bouncycastle.asn1.DERInteger; import org.bouncycastle.asn1.x509.X509Extensions; import org.bouncycastle.util.Arrays; import org.bouncycastle.util.Selector; import org.bouncycastle.x509.extension.X509ExtensionUtil; import java.io.IOException; import java.math.BigInteger; import java.security.cert.CRL; import java.security.cert.X509CRL; import org.bouncycastle.jce.cert.X509CRLSelector; /** * This class is a Selector implementation for X.509 certificate revocation * lists. * * @see org.bouncycastle.util.Selector * @see org.bouncycastle.x509.X509Store * @see org.bouncycastle.jce.provider.X509StoreCRLCollection */ public class X509CRLStoreSelector extends X509CRLSelector implements Selector { private boolean deltaCRLIndicator = false; private boolean completeCRLEnabled = false; private BigInteger maxBaseCRLNumber = null; private byte[] issuingDistributionPoint = null; private boolean issuingDistributionPointEnabled = false; private X509AttributeCertificate attrCertChecking; /** * Returns if the issuing distribution point criteria should be applied. * Defaults to false. *

* You may also set the issuing distribution point criteria if not a missing * issuing distribution point should be assumed. * * @return Returns if the issuing distribution point check is enabled. */ public boolean isIssuingDistributionPointEnabled() { return issuingDistributionPointEnabled; } /** * Enables or disables the issuing distribution point check. * * @param issuingDistributionPointEnabled true to enable the * issuing distribution point check. */ public void setIssuingDistributionPointEnabled( boolean issuingDistributionPointEnabled) { this.issuingDistributionPointEnabled = issuingDistributionPointEnabled; } /** * Sets the attribute certificate being checked. This is not a criterion. * Rather, it is optional information that may help a {@link X509Store} find * CRLs that would be relevant when checking revocation for the specified * attribute certificate. If null is specified, then no such * optional information is provided. * * @param attrCert the X509AttributeCertificate being checked (or * null) * @see #getAttrCertificateChecking() */ public void setAttrCertificateChecking(X509AttributeCertificate attrCert) { attrCertChecking = attrCert; } /** * Returns the attribute certificate being checked. * * @return Returns the attribute certificate being checked. * @see #setAttrCertificateChecking(X509AttributeCertificate) */ public X509AttributeCertificate getAttrCertificateChecking() { return attrCertChecking; } public boolean match(Object obj) { if (!(obj instanceof X509CRL)) { return false; } X509CRL crl = (X509CRL)obj; DERInteger dci = null; try { byte[] bytes = crl .getExtensionValue(X509Extensions.DeltaCRLIndicator.getId()); if (bytes != null) { dci = DERInteger.getInstance(X509ExtensionUtil .fromExtensionValue(bytes)); } } catch (Exception e) { return false; } if (isDeltaCRLIndicatorEnabled()) { if (dci == null) { return false; } } if (isCompleteCRLEnabled()) { if (dci != null) { return false; } } if (dci != null) { if (maxBaseCRLNumber != null) { if (dci.getPositiveValue().compareTo(maxBaseCRLNumber) == 1) { return false; } } } if (issuingDistributionPointEnabled) { byte[] idp = crl .getExtensionValue(X509Extensions.IssuingDistributionPoint .getId()); if (issuingDistributionPoint == null) { if (idp != null) { return false; } } else { if (!Arrays.areEqual(idp, issuingDistributionPoint)) { return false; } } } return super.match((X509CRL)obj); } public boolean match(CRL crl) { return match((Object)crl); } /** * Returns if this selector must match CRLs with the delta CRL indicator * extension set. Defaults to false. * * @return Returns true if only CRLs with the delta CRL * indicator extension are selected. */ public boolean isDeltaCRLIndicatorEnabled() { return deltaCRLIndicator; } /** * If this is set to true the CRL reported contains the delta * CRL indicator CRL extension. *

* {@link #setCompleteCRLEnabled(boolean)} and * {@link #setDeltaCRLIndicatorEnabled(boolean)} excluded each other. * * @param deltaCRLIndicator true if the delta CRL indicator * extension must be in the CRL. */ public void setDeltaCRLIndicatorEnabled(boolean deltaCRLIndicator) { this.deltaCRLIndicator = deltaCRLIndicator; } /** * Returns an instance of this from a X509CRLSelector. * * @param selector A X509CRLSelector instance. * @return An instance of an X509CRLStoreSelector. * @exception IllegalArgumentException if selector is null or creation * fails. */ public static X509CRLStoreSelector getInstance(X509CRLSelector selector) { if (selector == null) { throw new IllegalArgumentException( "cannot create from null selector"); } X509CRLStoreSelector cs = new X509CRLStoreSelector(); cs.setCertificateChecking(selector.getCertificateChecking()); cs.setDateAndTime(selector.getDateAndTime()); try { cs.setIssuerNames(selector.getIssuerNames()); } catch (IOException e) { // cannot happen throw new IllegalArgumentException(e.getMessage()); } //cs.setIssuers(selector.getIssuers()); cs.setMaxCRLNumber(selector.getMaxCRL()); cs.setMinCRLNumber(selector.getMinCRL()); return cs; } public Object clone() { X509CRLStoreSelector sel = X509CRLStoreSelector.getInstance(this); sel.deltaCRLIndicator = deltaCRLIndicator; sel.completeCRLEnabled = completeCRLEnabled; sel.maxBaseCRLNumber = maxBaseCRLNumber; sel.attrCertChecking = attrCertChecking; sel.issuingDistributionPointEnabled = issuingDistributionPointEnabled; sel.issuingDistributionPoint = Arrays.clone(issuingDistributionPoint); return sel; } /** * If true only complete CRLs are returned. Defaults to * false. * * @return true if only complete CRLs are returned. */ public boolean isCompleteCRLEnabled() { return completeCRLEnabled; } /** * If set to true only complete CRLs are returned. *

* {@link #setCompleteCRLEnabled(boolean)} and * {@link #setDeltaCRLIndicatorEnabled(boolean)} excluded each other. * * @param completeCRLEnabled true if only complete CRLs * should be returned. */ public void setCompleteCRLEnabled(boolean completeCRLEnabled) { this.completeCRLEnabled = completeCRLEnabled; } /** * Get the maximum base CRL number. Defaults to null. * * @return Returns the maximum base CRL number. * @see #setMaxBaseCRLNumber(BigInteger) */ public BigInteger getMaxBaseCRLNumber() { return maxBaseCRLNumber; } /** * Sets the maximum base CRL number. Setting to null disables * this cheack. *

* This is only meaningful for delta CRLs. Complete CRLs must have a CRL * number which is greater or equal than the base number of the * corresponding CRL. * * @param maxBaseCRLNumber The maximum base CRL number to set. */ public void setMaxBaseCRLNumber(BigInteger maxBaseCRLNumber) { this.maxBaseCRLNumber = maxBaseCRLNumber; } /** * Returns the issuing distribution point. Defaults to null, * which is a missing issuing distribution point extension. *

* The internal byte array is cloned before it is returned. *

* The criteria must be enable with * {@link #setIssuingDistributionPointEnabled(boolean)}. * * @return Returns the issuing distribution point. * @see #setIssuingDistributionPoint(byte[]) */ public byte[] getIssuingDistributionPoint() { return Arrays.clone(issuingDistributionPoint); } /** * Sets the issuing distribution point. *

* The issuing distribution point extension is a CRL extension which * identifies the scope and the distribution point of a CRL. The scope * contains among others information about revocation reasons contained in * the CRL. Delta CRLs and complete CRLs must have matching issuing * distribution points. *

* The byte array is cloned to protect against subsequent modifications. *

* You must also enable or disable this criteria with * {@link #setIssuingDistributionPointEnabled(boolean)}. * * @param issuingDistributionPoint The issuing distribution point to set. * This is the DER encoded OCTET STRING extension value. * @see #getIssuingDistributionPoint() */ public void setIssuingDistributionPoint(byte[] issuingDistributionPoint) { this.issuingDistributionPoint = Arrays.clone(issuingDistributionPoint); } } bouncycastle-1.49.orig/jdk1.3/org/bouncycastle/x509/X509CertStoreSelector.java0000644000175000017500000000547212104173672026271 0ustar ebourgebourgpackage org.bouncycastle.x509; import org.bouncycastle.util.Selector; import java.io.IOException; import java.security.cert.Certificate; import org.bouncycastle.jce.cert.X509CertSelector; import java.security.cert.X509Certificate; /** * This class is a Selector implementation for X.509 certificates. * * @see org.bouncycastle.util.Selector * @see org.bouncycastle.x509.X509Store * @see org.bouncycastle.jce.provider.X509StoreCertCollection */ public class X509CertStoreSelector extends X509CertSelector implements Selector { public boolean match(Object obj) { if (!(obj instanceof X509Certificate)) { return false; } X509Certificate other = (X509Certificate)obj; return super.match(other); } public boolean match(Certificate cert) { return match((Object)cert); } public Object clone() { X509CertStoreSelector selector = (X509CertStoreSelector)super.clone(); return selector; } /** * Returns an instance of this from a X509CertSelector. * * @param selector A X509CertSelector instance. * @return An instance of an X509CertStoreSelector. * @exception IllegalArgumentException if selector is null or creation fails. */ public static X509CertStoreSelector getInstance(X509CertSelector selector) { if (selector == null) { throw new IllegalArgumentException("cannot create from null selector"); } X509CertStoreSelector cs = new X509CertStoreSelector(); cs.setAuthorityKeyIdentifier(selector.getAuthorityKeyIdentifier()); cs.setBasicConstraints(selector.getBasicConstraints()); cs.setCertificate(selector.getCertificate()); cs.setCertificateValid(selector.getCertificateValid()); cs.setMatchAllSubjectAltNames(selector.getMatchAllSubjectAltNames()); try { cs.setPathToNames(selector.getPathToNames()); cs.setExtendedKeyUsage(selector.getExtendedKeyUsage()); //cs.setNameConstraints(selector.getNameConstraints()); cs.setPolicy(selector.getPolicy()); cs.setSubjectPublicKeyAlgID(selector.getSubjectPublicKeyAlgID()); cs.setSubject(selector.getSubjectAsBytes()); cs.setIssuer(selector.getIssuerAsBytes()); } catch (IOException e) { throw new IllegalArgumentException("error in passed in selector: " + e); } cs.setKeyUsage(selector.getKeyUsage()); cs.setPrivateKeyValid(selector.getPrivateKeyValid()); cs.setSerialNumber(selector.getSerialNumber()); cs.setSubjectKeyIdentifier(selector.getSubjectKeyIdentifier()); cs.setSubjectPublicKey(selector.getSubjectPublicKey()); return cs; } } bouncycastle-1.49.orig/jdk1.3/org/bouncycastle/x509/ExtendedPKIXParameters.java0000644000175000017500000005200011116106606026530 0ustar ebourgebourgpackage org.bouncycastle.x509; import org.bouncycastle.util.Selector; import org.bouncycastle.util.Store; import java.security.InvalidAlgorithmParameterException; import org.bouncycastle.jce.cert.CertSelector; import org.bouncycastle.jce.cert.CertStore; import org.bouncycastle.jce.cert.CollectionCertStoreParameters; import org.bouncycastle.jce.cert.LDAPCertStoreParameters; import org.bouncycastle.jce.cert.PKIXParameters; import org.bouncycastle.jce.cert.TrustAnchor; import org.bouncycastle.jce.cert.X509CertSelector; import java.util.ArrayList; import java.util.Collection; import java.util.Collections; import java.util.HashSet; import java.util.Iterator; import java.util.List; import java.util.Set; /** * This class extends the PKIXParameters with a validity model parameter. */ public class ExtendedPKIXParameters extends PKIXParameters { private List stores; private Selector selector; private boolean additionalLocationsEnabled; private List additionalStores; private Set trustedACIssuers; private Set necessaryACAttributes; private Set prohibitedACAttributes; private Set attrCertCheckers; /** * Creates an instance of PKIXParameters with the specified * Set of most-trusted CAs. Each element of the set is a * {@link TrustAnchor TrustAnchor}.

Note that the Set * is copied to protect against subsequent modifications. * * @param trustAnchors a Set of TrustAnchors * @throws InvalidAlgorithmParameterException if the specified * Set is empty. * @throws NullPointerException if the specified Set is * null * @throws ClassCastException if any of the elements in the Set * is not of type java.security.cert.TrustAnchor */ public ExtendedPKIXParameters(Set trustAnchors) throws InvalidAlgorithmParameterException { super(trustAnchors); stores = new ArrayList(); additionalStores = new ArrayList(); trustedACIssuers = new HashSet(); necessaryACAttributes = new HashSet(); prohibitedACAttributes = new HashSet(); attrCertCheckers = new HashSet(); } /** * Returns an instance with the parameters of a given * PKIXParameters object. * * @param pkixParams The given PKIXParameters * @return an extended PKIX params object */ public static ExtendedPKIXParameters getInstance(PKIXParameters pkixParams) { ExtendedPKIXParameters params; try { params = new ExtendedPKIXParameters(pkixParams.getTrustAnchors()); } catch (Exception e) { // cannot happen throw new RuntimeException(e.getMessage()); } params.setParams(pkixParams); return params; } /** * Method to support clone() under J2ME. * super.clone() does not exist and fields are not copied. * * @param params Parameters to set. If this are * ExtendedPKIXParameters they are copied to. */ protected void setParams(PKIXParameters params) { setDate(params.getDate()); setCertPathCheckers(params.getCertPathCheckers()); setCertStores(params.getCertStores()); setAnyPolicyInhibited(params.isAnyPolicyInhibited()); setExplicitPolicyRequired(params.isExplicitPolicyRequired()); setPolicyMappingInhibited(params.isPolicyMappingInhibited()); setRevocationEnabled(params.isRevocationEnabled()); setInitialPolicies(params.getInitialPolicies()); setPolicyQualifiersRejected(params.getPolicyQualifiersRejected()); setSigProvider(params.getSigProvider()); setTargetCertConstraints(params.getTargetCertConstraints()); try { setTrustAnchors(params.getTrustAnchors()); } catch (Exception e) { // cannot happen throw new RuntimeException(e.getMessage()); } if (params instanceof ExtendedPKIXParameters) { ExtendedPKIXParameters _params = (ExtendedPKIXParameters) params; validityModel = _params.validityModel; useDeltas = _params.useDeltas; additionalLocationsEnabled = _params.additionalLocationsEnabled; selector = _params.selector == null ? null : (Selector) _params.selector.clone(); stores = new ArrayList(_params.stores); additionalStores = new ArrayList(_params.additionalStores); trustedACIssuers = new HashSet(_params.trustedACIssuers); prohibitedACAttributes = new HashSet(_params.prohibitedACAttributes); necessaryACAttributes = new HashSet(_params.necessaryACAttributes); attrCertCheckers = new HashSet(_params.attrCertCheckers); } } /** * This is the default PKIX validity model. Actually there are two variants * of this: The PKIX model and the modified PKIX model. The PKIX model * verifies that all involved certificates must have been valid at the * current time. The modified PKIX model verifies that all involved * certificates were valid at the signing time. Both are indirectly choosen * with the {@link PKIXParameters#setDate(java.util.Date)} method, so this * methods sets the Date when all certificates must have been * valid. */ public static final int PKIX_VALIDITY_MODEL = 0; /** * This model uses the following validity model. Each certificate must have * been valid at the moment where is was used. That means the end * certificate must have been valid at the time the signature was done. The * CA certificate which signed the end certificate must have been valid, * when the end certificate was signed. The CA (or Root CA) certificate must * have been valid, when the CA certificate was signed and so on. So the * {@link PKIXParameters#setDate(java.util.Date)} method sets the time, when * the end certificate must have been valid.

It is used e.g. * in the German signature law. */ public static final int CHAIN_VALIDITY_MODEL = 1; private int validityModel = PKIX_VALIDITY_MODEL; private boolean useDeltas = false; /** * Defaults to false. * * @return Returns if delta CRLs should be used. */ public boolean isUseDeltasEnabled() { return useDeltas; } /** * Sets if delta CRLs should be used for checking the revocation status. * * @param useDeltas true if delta CRLs should be used. */ public void setUseDeltasEnabled(boolean useDeltas) { this.useDeltas = useDeltas; } /** * @return Returns the validity model. * @see #CHAIN_VALIDITY_MODEL * @see #PKIX_VALIDITY_MODEL */ public int getValidityModel() { return validityModel; } /** * Sets the Java CertStore to this extended PKIX parameters. * * @throws ClassCastException if an element of stores is not * a CertStore. */ public void setCertStores(List stores) { if (stores != null) { Iterator it = stores.iterator(); while (it.hasNext()) { addCertStore((CertStore)it.next()); } } } /** * Sets the Bouncy Castle Stores for finding CRLs, certificates, attribute * certificates or cross certificates. *

* The List is cloned. * * @param stores A list of stores to use. * @see #getStores * @throws ClassCastException if an element of stores is not * a {@link Store}. */ public void setStores(List stores) { if (stores == null) { this.stores = new ArrayList(); } else { for (Iterator i = stores.iterator(); i.hasNext();) { if (!(i.next() instanceof Store)) { throw new ClassCastException( "All elements of list must be " + "of type org.bouncycastle.util.Store."); } } this.stores = new ArrayList(stores); } } /** * Adds a Bouncy Castle {@link Store} to find CRLs, certificates, attribute * certificates or cross certificates. *

* This method should be used to add local stores, like collection based * X.509 stores, if available. Local stores should be considered first, * before trying to use additional (remote) locations, because they do not * need possible additional network traffic. *

* If store is null it is ignored. * * @param store The store to add. * @see #getStores */ public void addStore(Store store) { if (stores != null) { stores.add(store); } } /** * Adds a additional Bouncy Castle {@link Store} to find CRLs, certificates, * attribute certificates or cross certificates. *

* You should not use this method. This method is used for adding additional * X.509 stores, which are used to add (remote) locations, e.g. LDAP, found * during X.509 object processing, e.g. in certificates or CRLs. This method * is used in PKIX certification path processing. *

* If store is null it is ignored. * * @param store The store to add. * @see #getStores() */ public void addAddionalStore(Store store) { if (store != null) { additionalStores.add(store); } } /** * Returns an immutable List of additional Bouncy Castle * Stores used for finding CRLs, certificates, attribute * certificates or cross certificates. * * @return an immutable List of additional Bouncy Castle * Stores. Never null. * * @see #addAddionalStore(Store) */ public List getAdditionalStores() { return Collections.unmodifiableList(additionalStores); } /** * Returns an immutable List of Bouncy Castle * Stores used for finding CRLs, certificates, attribute * certificates or cross certificates. * * @return an immutable List of Bouncy Castle * Stores. Never null. * * @see #setStores(List) */ public List getStores() { return Collections.unmodifiableList(new ArrayList(stores)); } /** * @param validityModel The validity model to set. * @see #CHAIN_VALIDITY_MODEL * @see #PKIX_VALIDITY_MODEL */ public void setValidityModel(int validityModel) { this.validityModel = validityModel; } public Object clone() { ExtendedPKIXParameters params; try { params = new ExtendedPKIXParameters(getTrustAnchors()); } catch (Exception e) { // cannot happen throw new RuntimeException(e.getMessage()); } params.setParams(this); return params; } /** * Returns if additional {@link X509Store}s for locations like LDAP found * in certificates or CRLs should be used. * * @return Returns true if additional stores are used. */ public boolean isAdditionalLocationsEnabled() { return additionalLocationsEnabled; } /** * Sets if additional {@link X509Store}s for locations like LDAP found in * certificates or CRLs should be used. * * @param enabled true if additional stores are used. */ public void setAdditionalLocationsEnabled(boolean enabled) { additionalLocationsEnabled = enabled; } /** * Returns the required constraints on the target certificate or attribute * certificate. The constraints are returned as an instance of * Selector. If null, no constraints are * defined. * *

* The target certificate in a PKIX path may be a certificate or an * attribute certificate. *

* Note that the Selector returned is cloned to protect * against subsequent modifications. * * @return a Selector specifying the constraints on the * target certificate or attribute certificate (or null) * @see #setTargetConstraints * @see X509CertStoreSelector * @see X509AttributeCertStoreSelector */ public Selector getTargetConstraints() { if (selector != null) { return (Selector) selector.clone(); } else { return null; } } /** * Sets the required constraints on the target certificate or attribute * certificate. The constraints are specified as an instance of * Selector. If null, no constraints are * defined. *

* The target certificate in a PKIX path may be a certificate or an * attribute certificate. *

* Note that the Selector specified is cloned to protect * against subsequent modifications. * * @param selector a Selector specifying the constraints on * the target certificate or attribute certificate (or * null) * @see #getTargetConstraints * @see X509CertStoreSelector * @see X509AttributeCertStoreSelector */ public void setTargetConstraints(Selector selector) { if (selector != null) { this.selector = (Selector) selector.clone(); } else { this.selector = null; } } /** * Sets the required constraints on the target certificate. The constraints * are specified as an instance of X509CertSelector. If * null, no constraints are defined. * *

* This method wraps the given X509CertSelector into a * X509CertStoreSelector. *

* Note that the X509CertSelector specified is cloned to * protect against subsequent modifications. * * @param selector a X509CertSelector specifying the * constraints on the target certificate (or null) * @see #getTargetCertConstraints * @see X509CertStoreSelector */ public void setTargetCertConstraints(CertSelector selector) { super.setTargetCertConstraints(selector); if (selector != null) { this.selector = X509CertStoreSelector .getInstance((X509CertSelector) selector); } else { this.selector = null; } } /** * Returns the trusted attribute certificate issuers. If attribute * certificates is verified the trusted AC issuers must be set. *

* The returned Set consists of TrustAnchors. *

* The returned Set is immutable. Never null * * @return Returns an immutable set of the trusted AC issuers. */ public Set getTrustedACIssuers() { return Collections.unmodifiableSet(trustedACIssuers); } /** * Sets the trusted attribute certificate issuers. If attribute certificates * is verified the trusted AC issuers must be set. *

* The trustedACIssuers must be a Set of * TrustAnchor *

* The given set is cloned. * * @param trustedACIssuers The trusted AC issuers to set. Is never * null. * @throws ClassCastException if an element of stores is not * a TrustAnchor. */ public void setTrustedACIssuers(Set trustedACIssuers) { if (trustedACIssuers == null) { trustedACIssuers.clear(); return; } for (Iterator it = trustedACIssuers.iterator(); it.hasNext();) { if (!(it.next() instanceof TrustAnchor)) { throw new ClassCastException("All elements of set must be " + "of type " + TrustAnchor.class.getName() + "."); } } this.trustedACIssuers.clear(); this.trustedACIssuers.addAll(trustedACIssuers); } /** * Returns the neccessary attributes which must be contained in an attribute * certificate. *

* The returned Set is immutable and contains * Strings with the OIDs. * * @return Returns the necessary AC attributes. */ public Set getNecessaryACAttributes() { return Collections.unmodifiableSet(necessaryACAttributes); } /** * Sets the neccessary which must be contained in an attribute certificate. *

* The Set must contain Strings with the * OIDs. *

* The set is cloned. * * @param necessaryACAttributes The necessary AC attributes to set. * @throws ClassCastException if an element of * necessaryACAttributes is not a * String. */ public void setNecessaryACAttributes(Set necessaryACAttributes) { if (necessaryACAttributes == null) { this.necessaryACAttributes.clear(); return; } for (Iterator it = necessaryACAttributes.iterator(); it.hasNext();) { if (!(it.next() instanceof String)) { throw new ClassCastException("All elements of set must be " + "of type String."); } } this.necessaryACAttributes.clear(); this.necessaryACAttributes.addAll(necessaryACAttributes); } /** * Returns the attribute certificates which are not allowed. *

* The returned Set is immutable and contains * Strings with the OIDs. * * @return Returns the prohibited AC attributes. Is never null. */ public Set getProhibitedACAttributes() { return prohibitedACAttributes; } /** * Sets the attribute certificates which are not allowed. *

* The Set must contain Strings with the * OIDs. *

* The set is cloned. * * @param prohibitedACAttributes The prohibited AC attributes to set. * @throws ClassCastException if an element of * prohibitedACAttributes is not a * String. */ public void setProhibitedACAttributes(Set prohibitedACAttributes) { if (prohibitedACAttributes == null) { this.prohibitedACAttributes.clear(); return; } for (Iterator it = prohibitedACAttributes.iterator(); it.hasNext();) { if (!(it.next() instanceof String)) { throw new ClassCastException("All elements of set must be " + "of type String."); } } this.prohibitedACAttributes.clear(); this.prohibitedACAttributes.addAll(prohibitedACAttributes); } /** * Returns the attribute certificate checker. The returned set contains * {@link PKIXAttrCertChecker}s and is immutable. * * @return Returns the attribute certificate checker. Is never * null. */ public Set getAttrCertCheckers() { return Collections.unmodifiableSet(attrCertCheckers); } /** * Sets the attribute certificate checkers. *

* All elements in the Set must a {@link PKIXAttrCertChecker}. *

* The given set is cloned. * * @param attrCertCheckers The attribute certificate checkers to set. Is * never null. * @throws ClassCastException if an element of attrCertCheckers * is not a PKIXAttrCertChecker. */ /* public void setAttrCertCheckers(Set attrCertCheckers) { if (attrCertCheckers == null) { this.attrCertCheckers.clear(); return; } for (Iterator it = attrCertCheckers.iterator(); it.hasNext();) { if (!(it.next() instanceof PKIXAttrCertChecker)) { throw new ClassCastException("All elements of set must be " + "of type " + PKIXAttrCertChecker.class.getName() + "."); } } this.attrCertCheckers.clear(); this.attrCertCheckers.addAll(attrCertCheckers); } */ } bouncycastle-1.49.orig/jdk1.3/org/bouncycastle/x509/X509Util.java0000644000175000017500000003471211726307316023575 0ustar ebourgebourgpackage org.bouncycastle.x509; import java.io.IOException; import java.security.InvalidKeyException; import java.security.NoSuchAlgorithmException; import java.security.NoSuchProviderException; import java.security.PrivateKey; import java.security.Provider; import java.security.SecureRandom; import java.security.Security; import java.security.Signature; import java.security.SignatureException; import java.util.ArrayList; import java.util.Enumeration; import java.util.HashSet; import java.util.Hashtable; import java.util.Iterator; import java.util.List; import java.util.Set; import org.bouncycastle.asn1.ASN1Encodable; import org.bouncycastle.asn1.ASN1Encoding; import org.bouncycastle.asn1.ASN1Integer; import org.bouncycastle.asn1.DERNull; import org.bouncycastle.asn1.DERObjectIdentifier; import org.bouncycastle.asn1.cryptopro.CryptoProObjectIdentifiers; import org.bouncycastle.asn1.nist.NISTObjectIdentifiers; import org.bouncycastle.asn1.oiw.OIWObjectIdentifiers; import org.bouncycastle.asn1.pkcs.PKCSObjectIdentifiers; import org.bouncycastle.asn1.pkcs.RSASSAPSSparams; import org.bouncycastle.asn1.teletrust.TeleTrusTObjectIdentifiers; import org.bouncycastle.asn1.x509.AlgorithmIdentifier; import org.bouncycastle.asn1.x9.X9ObjectIdentifiers; import org.bouncycastle.jce.X509Principal; import org.bouncycastle.util.Strings; class X509Util { private static Hashtable algorithms = new Hashtable(); private static Hashtable params = new Hashtable(); private static Set noParams = new HashSet(); static { algorithms.put("MD2WITHRSAENCRYPTION", PKCSObjectIdentifiers.md2WithRSAEncryption); algorithms.put("MD2WITHRSA", PKCSObjectIdentifiers.md2WithRSAEncryption); algorithms.put("MD5WITHRSAENCRYPTION", PKCSObjectIdentifiers.md5WithRSAEncryption); algorithms.put("MD5WITHRSA", PKCSObjectIdentifiers.md5WithRSAEncryption); algorithms.put("SHA1WITHRSAENCRYPTION", PKCSObjectIdentifiers.sha1WithRSAEncryption); algorithms.put("SHA1WITHRSA", PKCSObjectIdentifiers.sha1WithRSAEncryption); algorithms.put("SHA224WITHRSAENCRYPTION", PKCSObjectIdentifiers.sha224WithRSAEncryption); algorithms.put("SHA224WITHRSA", PKCSObjectIdentifiers.sha224WithRSAEncryption); algorithms.put("SHA256WITHRSAENCRYPTION", PKCSObjectIdentifiers.sha256WithRSAEncryption); algorithms.put("SHA256WITHRSA", PKCSObjectIdentifiers.sha256WithRSAEncryption); algorithms.put("SHA384WITHRSAENCRYPTION", PKCSObjectIdentifiers.sha384WithRSAEncryption); algorithms.put("SHA384WITHRSA", PKCSObjectIdentifiers.sha384WithRSAEncryption); algorithms.put("SHA512WITHRSAENCRYPTION", PKCSObjectIdentifiers.sha512WithRSAEncryption); algorithms.put("SHA512WITHRSA", PKCSObjectIdentifiers.sha512WithRSAEncryption); algorithms.put("SHA1WITHRSAANDMGF1", PKCSObjectIdentifiers.id_RSASSA_PSS); algorithms.put("SHA224WITHRSAANDMGF1", PKCSObjectIdentifiers.id_RSASSA_PSS); algorithms.put("SHA256WITHRSAANDMGF1", PKCSObjectIdentifiers.id_RSASSA_PSS); algorithms.put("SHA384WITHRSAANDMGF1", PKCSObjectIdentifiers.id_RSASSA_PSS); algorithms.put("SHA512WITHRSAANDMGF1", PKCSObjectIdentifiers.id_RSASSA_PSS); algorithms.put("RIPEMD160WITHRSAENCRYPTION", TeleTrusTObjectIdentifiers.rsaSignatureWithripemd160); algorithms.put("RIPEMD160WITHRSA", TeleTrusTObjectIdentifiers.rsaSignatureWithripemd160); algorithms.put("RIPEMD128WITHRSAENCRYPTION", TeleTrusTObjectIdentifiers.rsaSignatureWithripemd128); algorithms.put("RIPEMD128WITHRSA", TeleTrusTObjectIdentifiers.rsaSignatureWithripemd128); algorithms.put("RIPEMD256WITHRSAENCRYPTION", TeleTrusTObjectIdentifiers.rsaSignatureWithripemd256); algorithms.put("RIPEMD256WITHRSA", TeleTrusTObjectIdentifiers.rsaSignatureWithripemd256); algorithms.put("SHA1WITHDSA", X9ObjectIdentifiers.id_dsa_with_sha1); algorithms.put("DSAWITHSHA1", X9ObjectIdentifiers.id_dsa_with_sha1); algorithms.put("SHA224WITHDSA", NISTObjectIdentifiers.dsa_with_sha224); algorithms.put("SHA256WITHDSA", NISTObjectIdentifiers.dsa_with_sha256); algorithms.put("SHA384WITHDSA", NISTObjectIdentifiers.dsa_with_sha384); algorithms.put("SHA512WITHDSA", NISTObjectIdentifiers.dsa_with_sha512); algorithms.put("SHA1WITHECDSA", X9ObjectIdentifiers.ecdsa_with_SHA1); algorithms.put("ECDSAWITHSHA1", X9ObjectIdentifiers.ecdsa_with_SHA1); algorithms.put("SHA224WITHECDSA", X9ObjectIdentifiers.ecdsa_with_SHA224); algorithms.put("SHA256WITHECDSA", X9ObjectIdentifiers.ecdsa_with_SHA256); algorithms.put("SHA384WITHECDSA", X9ObjectIdentifiers.ecdsa_with_SHA384); algorithms.put("SHA512WITHECDSA", X9ObjectIdentifiers.ecdsa_with_SHA512); algorithms.put("GOST3411WITHGOST3410", CryptoProObjectIdentifiers.gostR3411_94_with_gostR3410_94); algorithms.put("GOST3411WITHGOST3410-94", CryptoProObjectIdentifiers.gostR3411_94_with_gostR3410_94); algorithms.put("GOST3411WITHECGOST3410", CryptoProObjectIdentifiers.gostR3411_94_with_gostR3410_2001); algorithms.put("GOST3411WITHECGOST3410-2001", CryptoProObjectIdentifiers.gostR3411_94_with_gostR3410_2001); algorithms.put("GOST3411WITHGOST3410-2001", CryptoProObjectIdentifiers.gostR3411_94_with_gostR3410_2001); // // According to RFC 3279, the ASN.1 encoding SHALL (id-dsa-with-sha1) or MUST (ecdsa-with-SHA*) omit the parameters field. // The parameters field SHALL be NULL for RSA based signature algorithms. // noParams.add(X9ObjectIdentifiers.ecdsa_with_SHA1); noParams.add(X9ObjectIdentifiers.ecdsa_with_SHA224); noParams.add(X9ObjectIdentifiers.ecdsa_with_SHA256); noParams.add(X9ObjectIdentifiers.ecdsa_with_SHA384); noParams.add(X9ObjectIdentifiers.ecdsa_with_SHA512); noParams.add(X9ObjectIdentifiers.id_dsa_with_sha1); noParams.add(NISTObjectIdentifiers.dsa_with_sha224); noParams.add(NISTObjectIdentifiers.dsa_with_sha256); noParams.add(NISTObjectIdentifiers.dsa_with_sha384); noParams.add(NISTObjectIdentifiers.dsa_with_sha512); // // RFC 4491 // noParams.add(CryptoProObjectIdentifiers.gostR3411_94_with_gostR3410_94); noParams.add(CryptoProObjectIdentifiers.gostR3411_94_with_gostR3410_2001); // // explicit params // AlgorithmIdentifier sha1AlgId = new AlgorithmIdentifier(OIWObjectIdentifiers.idSHA1, new DERNull()); params.put("SHA1WITHRSAANDMGF1", creatPSSParams(sha1AlgId, 20)); AlgorithmIdentifier sha224AlgId = new AlgorithmIdentifier(NISTObjectIdentifiers.id_sha224, new DERNull()); params.put("SHA224WITHRSAANDMGF1", creatPSSParams(sha224AlgId, 28)); AlgorithmIdentifier sha256AlgId = new AlgorithmIdentifier(NISTObjectIdentifiers.id_sha256, new DERNull()); params.put("SHA256WITHRSAANDMGF1", creatPSSParams(sha256AlgId, 32)); AlgorithmIdentifier sha384AlgId = new AlgorithmIdentifier(NISTObjectIdentifiers.id_sha384, new DERNull()); params.put("SHA384WITHRSAANDMGF1", creatPSSParams(sha384AlgId, 48)); AlgorithmIdentifier sha512AlgId = new AlgorithmIdentifier(NISTObjectIdentifiers.id_sha512, new DERNull()); params.put("SHA512WITHRSAANDMGF1", creatPSSParams(sha512AlgId, 64)); } private static RSASSAPSSparams creatPSSParams(AlgorithmIdentifier hashAlgId, int saltSize) { return new RSASSAPSSparams( hashAlgId, new AlgorithmIdentifier(PKCSObjectIdentifiers.id_mgf1, hashAlgId), new ASN1Integer(saltSize), new ASN1Integer(1)); } static DERObjectIdentifier getAlgorithmOID( String algorithmName) { algorithmName = Strings.toUpperCase(algorithmName); if (algorithms.containsKey(algorithmName)) { return (DERObjectIdentifier)algorithms.get(algorithmName); } return new DERObjectIdentifier(algorithmName); } static AlgorithmIdentifier getSigAlgID( DERObjectIdentifier sigOid, String algorithmName) { if (noParams.contains(sigOid)) { return new AlgorithmIdentifier(sigOid); } algorithmName = Strings.toUpperCase(algorithmName); if (params.containsKey(algorithmName)) { return new AlgorithmIdentifier(sigOid, (ASN1Encodable)params.get(algorithmName)); } else { return new AlgorithmIdentifier(sigOid, new DERNull()); } } static Iterator getAlgNames() { Enumeration e = algorithms.keys(); List l = new ArrayList(); while (e.hasMoreElements()) { l.add(e.nextElement()); } return l.iterator(); } static Signature getSignatureInstance( String algorithm) throws NoSuchAlgorithmException { return Signature.getInstance(algorithm); } static Signature getSignatureInstance( String algorithm, String provider) throws NoSuchProviderException, NoSuchAlgorithmException { if (provider != null) { return Signature.getInstance(algorithm, provider); } else { return Signature.getInstance(algorithm); } } static byte[] calculateSignature( DERObjectIdentifier sigOid, String sigName, PrivateKey key, SecureRandom random, ASN1Encodable object) throws IOException, NoSuchAlgorithmException, InvalidKeyException, SignatureException { Signature sig; if (sigOid == null) { throw new IllegalStateException("no signature algorithm specified"); } sig = X509Util.getSignatureInstance(sigName); if (random != null) { sig.initSign(key, random); } else { sig.initSign(key); } sig.update(object.toASN1Primitive().getEncoded(ASN1Encoding.DER)); return sig.sign(); } static byte[] calculateSignature( DERObjectIdentifier sigOid, String sigName, String provider, PrivateKey key, SecureRandom random, ASN1Encodable object) throws IOException, NoSuchProviderException, NoSuchAlgorithmException, InvalidKeyException, SignatureException { Signature sig; if (sigOid == null) { throw new IllegalStateException("no signature algorithm specified"); } sig = X509Util.getSignatureInstance(sigName, provider); if (random != null) { sig.initSign(key, random); } else { sig.initSign(key); } sig.update(object.toASN1Primitive().getEncoded(ASN1Encoding.DER)); return sig.sign(); } static class Implementation { Object engine; Provider provider; Implementation( Object engine, Provider provider) { this.engine = engine; this.provider = provider; } Object getEngine() { return engine; } Provider getProvider() { return provider; } } /** * see if we can find an algorithm (or its alias and what it represents) in * the property table for the given provider. */ static Implementation getImplementation( String baseName, String algorithm, Provider prov) throws NoSuchAlgorithmException { algorithm = Strings.toUpperCase(algorithm); String alias; while ((alias = prov.getProperty("Alg.Alias." + baseName + "." + algorithm)) != null) { algorithm = alias; } String className = prov.getProperty(baseName + "." + algorithm); if (className != null) { try { Class cls; ClassLoader clsLoader = prov.getClass().getClassLoader(); if (clsLoader != null) { cls = clsLoader.loadClass(className); } else { cls = Class.forName(className); } return new Implementation(cls.newInstance(), prov); } catch (ClassNotFoundException e) { throw new IllegalStateException( "algorithm " + algorithm + " in provider " + prov.getName() + " but no class \"" + className + "\" found!"); } catch (Exception e) { throw new IllegalStateException( "algorithm " + algorithm + " in provider " + prov.getName() + " but class \"" + className + "\" inaccessible!"); } } throw new NoSuchAlgorithmException("cannot find implementation " + algorithm + " for provider " + prov.getName()); } /** * return an implementation for a given algorithm/provider. * If the provider is null, we grab the first avalaible who has the required algorithm. */ static Implementation getImplementation( String baseName, String algorithm) throws NoSuchAlgorithmException { Provider[] prov = Security.getProviders(); // // search every provider looking for the algorithm we want. // for (int i = 0; i != prov.length; i++) { // // try case insensitive // Implementation imp = getImplementation(baseName, Strings.toUpperCase(algorithm), prov[i]); if (imp != null) { return imp; } try { imp = getImplementation(baseName, algorithm, prov[i]); } catch (NoSuchAlgorithmException e) { // continue } } throw new NoSuchAlgorithmException("cannot find implementation " + algorithm); } static Provider getProvider(String provider) throws NoSuchProviderException { Provider prov = Security.getProvider(provider); if (prov == null) { throw new NoSuchProviderException("Provider " + provider + " not found"); } return prov; } } bouncycastle-1.49.orig/jdk1.3/org/bouncycastle/x509/ExtendedPKIXBuilderParameters.java0000644000175000017500000001605710767403724030067 0ustar ebourgebourgpackage org.bouncycastle.x509; import org.bouncycastle.util.Selector; import java.security.InvalidAlgorithmParameterException; import java.security.InvalidParameterException; import org.bouncycastle.jce.cert.PKIXBuilderParameters; import org.bouncycastle.jce.cert.PKIXParameters; import org.bouncycastle.jce.cert.TrustAnchor; import org.bouncycastle.jce.cert.X509CertSelector; import java.util.Collections; import java.util.HashSet; import java.util.Set; /** * This class contains extended parameters for PKIX certification path builders. * * @see java.security.cert.PKIXBuilderParameters * @see org.bouncycastle.jce.provider.PKIXCertPathBuilderSpi */ public class ExtendedPKIXBuilderParameters extends ExtendedPKIXParameters { private int maxPathLength = 5; private Set excludedCerts = Collections.EMPTY_SET; /** * Excluded certificates are not used for building a certification path. *

* The returned set is immutable. * * @return Returns the excluded certificates. */ public Set getExcludedCerts() { return Collections.unmodifiableSet(excludedCerts); } /** * Sets the excluded certificates which are not used for building a * certification path. If the Set is null an * empty set is assumed. *

* The given set is cloned to protect it against subsequent modifications. * * @param excludedCerts The excluded certificates to set. */ public void setExcludedCerts(Set excludedCerts) { if (excludedCerts == null) { excludedCerts = Collections.EMPTY_SET; } else { this.excludedCerts = new HashSet(excludedCerts); } } /** * Creates an instance of PKIXBuilderParameters with the * specified Set of most-trusted CAs. Each element of the set * is a {@link TrustAnchor TrustAnchor}. * *

* Note that the Set is copied to protect against subsequent * modifications. * * @param trustAnchors a Set of TrustAnchors * @param targetConstraints a Selector specifying the * constraints on the target certificate or attribute * certificate. * @throws InvalidAlgorithmParameterException if trustAnchors * is empty. * @throws NullPointerException if trustAnchors is * null * @throws ClassCastException if any of the elements of * trustAnchors is not of type * java.security.cert.TrustAnchor */ public ExtendedPKIXBuilderParameters(Set trustAnchors, Selector targetConstraints) throws InvalidAlgorithmParameterException { super(trustAnchors); setTargetConstraints(targetConstraints); } /** * Sets the maximum number of intermediate non-self-issued certificates in a * certification path. The PKIX CertPathBuilder must not * build paths longer then this length. *

* A value of 0 implies that the path can only contain a single certificate. * A value of -1 does not limit the length. The default length is 5. * *

* * The basic constraints extension of a CA certificate overrides this value * if smaller. * * @param maxPathLength the maximum number of non-self-issued intermediate * certificates in the certification path * @throws InvalidParameterException if maxPathLength is set * to a value less than -1 * * @see org.bouncycastle.jce.provider.PKIXCertPathBuilderSpi * @see #getMaxPathLength */ public void setMaxPathLength(int maxPathLength) { if (maxPathLength < -1) { throw new InvalidParameterException("The maximum path " + "length parameter can not be less than -1."); } this.maxPathLength = maxPathLength; } /** * Returns the value of the maximum number of intermediate non-self-issued * certificates in the certification path. * * @return the maximum number of non-self-issued intermediate certificates * in the certification path, or -1 if no limit exists. * * @see #setMaxPathLength(int) */ public int getMaxPathLength() { return maxPathLength; } /** * Can alse handle ExtendedPKIXBuilderParameters and * PKIXBuilderParameters. * * @param params Parameters to set. * @see org.bouncycastle.x509.ExtendedPKIXParameters#setParams(java.security.cert.PKIXParameters) */ protected void setParams(PKIXParameters params) { super.setParams(params); if (params instanceof ExtendedPKIXBuilderParameters) { ExtendedPKIXBuilderParameters _params = (ExtendedPKIXBuilderParameters) params; maxPathLength = _params.maxPathLength; excludedCerts = new HashSet(_params.excludedCerts); } if (params instanceof PKIXBuilderParameters) { PKIXBuilderParameters _params = (PKIXBuilderParameters) params; maxPathLength = _params.getMaxPathLength(); } } /** * Makes a copy of this PKIXParameters object. Changes to the * copy will not affect the original and vice versa. * * @return a copy of this PKIXParameters object */ public Object clone() { ExtendedPKIXBuilderParameters params = null; try { params = new ExtendedPKIXBuilderParameters(getTrustAnchors(), getTargetConstraints()); } catch (Exception e) { // cannot happen throw new RuntimeException(e.getMessage()); } params.setParams(this); return params; } /** * Returns an instance of ExtendedPKIXParameters which can be * safely casted to ExtendedPKIXBuilderParameters. *

* This method can be used to get a copy from other * PKIXBuilderParameters, PKIXParameters, * and ExtendedPKIXParameters instances. * * @param pkixParams The PKIX parameters to create a copy of. * @return An ExtendedPKIXBuilderParameters instance. */ public static ExtendedPKIXParameters getInstance(PKIXParameters pkixParams) { ExtendedPKIXBuilderParameters params; try { params = new ExtendedPKIXBuilderParameters(pkixParams .getTrustAnchors(), X509CertStoreSelector .getInstance((X509CertSelector) pkixParams .getTargetCertConstraints())); } catch (Exception e) { // cannot happen throw new RuntimeException(e.getMessage()); } params.setParams(pkixParams); return params; } } bouncycastle-1.49.orig/jdk1.3/org/bouncycastle/x509/examples/0000755000175000017500000000000012152033550023224 5ustar ebourgebourgbouncycastle-1.49.orig/jdk1.3/org/bouncycastle/x509/examples/AttrCertExample.java0000644000175000017500000002656510331052735027154 0ustar ebourgebourgpackage org.bouncycastle.x509.examples; import java.security.cert.*; import java.security.spec.RSAPrivateCrtKeySpec; import java.security.spec.RSAPublicKeySpec; import java.security.*; import java.math.*; import java.util.Date; import java.util.Hashtable; import java.util.Vector; import org.bouncycastle.jce.PrincipalUtil; import org.bouncycastle.jce.X509Principal; import org.bouncycastle.jce.provider.*; import org.bouncycastle.asn1.*; import org.bouncycastle.asn1.misc.MiscObjectIdentifiers; import org.bouncycastle.asn1.misc.NetscapeCertType; import org.bouncycastle.asn1.x509.GeneralName; import org.bouncycastle.x509.*; /** * A simple exmple that generates an attribute certificate. */ public class AttrCertExample { static X509V1CertificateGenerator v1CertGen = new X509V1CertificateGenerator(); static X509V3CertificateGenerator v3CertGen = new X509V3CertificateGenerator(); /** * we generate the CA's certificate */ public static X509Certificate createCaCert( PublicKey pubKey, PrivateKey privKey) throws Exception { // // signers name // String issuer = "C=AU, O=The Legion of the Bouncy Castle, OU=Bouncy Primary Certificate"; // // subjects name - the same as we are self signed. // String subject = "C=AU, O=The Legion of the Bouncy Castle, OU=Bouncy Primary Certificate"; // // create the certificate - version 1 // v1CertGen.setSerialNumber(BigInteger.valueOf(10)); v1CertGen.setIssuerDN(new X509Principal(issuer)); v1CertGen.setNotBefore(new Date(System.currentTimeMillis() - 1000L * 60 * 60 * 24 * 30)); v1CertGen.setNotAfter(new Date(System.currentTimeMillis() + (1000L * 60 * 60 * 24 * 30))); v1CertGen.setSubjectDN(new X509Principal(subject)); v1CertGen.setPublicKey(pubKey); v1CertGen.setSignatureAlgorithm("SHA1WithRSAEncryption"); X509Certificate cert = v1CertGen.generateX509Certificate(privKey); cert.checkValidity(new Date()); cert.verify(pubKey); return cert; } /** * we generate a certificate signed by our CA's intermediate certficate */ public static X509Certificate createClientCert( PublicKey pubKey, PrivateKey caPrivKey, PublicKey caPubKey) throws Exception { // // issuer // String issuer = "C=AU, O=The Legion of the Bouncy Castle, OU=Bouncy Primary Certificate"; // // subjects name table. // Hashtable attrs = new Hashtable(); Vector order = new Vector(); attrs.put(X509Principal.C, "AU"); attrs.put(X509Principal.O, "The Legion of the Bouncy Castle"); attrs.put(X509Principal.L, "Melbourne"); attrs.put(X509Principal.CN, "Eric H. Echidna"); attrs.put(X509Principal.EmailAddress, "feedback-crypto@bouncycastle.org"); order.addElement(X509Principal.C); order.addElement(X509Principal.O); order.addElement(X509Principal.L); order.addElement(X509Principal.CN); order.addElement(X509Principal.EmailAddress); // // create the certificate - version 3 // v3CertGen.reset(); v3CertGen.setSerialNumber(BigInteger.valueOf(20)); v3CertGen.setIssuerDN(new X509Principal(issuer)); v3CertGen.setNotBefore(new Date(System.currentTimeMillis() - 1000L * 60 * 60 * 24 * 30)); v3CertGen.setNotAfter(new Date(System.currentTimeMillis() + (1000L * 60 * 60 * 24 * 30))); v3CertGen.setSubjectDN(new X509Principal(order, attrs)); v3CertGen.setPublicKey(pubKey); v3CertGen.setSignatureAlgorithm("SHA1WithRSAEncryption"); // // add the extensions // v3CertGen.addExtension( MiscObjectIdentifiers.netscapeCertType, false, new NetscapeCertType(NetscapeCertType.objectSigning | NetscapeCertType.smime)); X509Certificate cert = v3CertGen.generateX509Certificate(caPrivKey); cert.checkValidity(new Date()); cert.verify(caPubKey); return cert; } public static void main(String args[]) throws Exception { Security.addProvider(new BouncyCastleProvider()); // // personal keys // RSAPublicKeySpec pubKeySpec = new RSAPublicKeySpec( new BigInteger("b4a7e46170574f16a97082b22be58b6a2a629798419be12872a4bdba626cfae9900f76abfb12139dce5de56564fab2b6543165a040c606887420e33d91ed7ed7", 16), new BigInteger("11", 16)); RSAPrivateCrtKeySpec privKeySpec = new RSAPrivateCrtKeySpec( new BigInteger("b4a7e46170574f16a97082b22be58b6a2a629798419be12872a4bdba626cfae9900f76abfb12139dce5de56564fab2b6543165a040c606887420e33d91ed7ed7", 16), new BigInteger("11", 16), new BigInteger("9f66f6b05410cd503b2709e88115d55daced94d1a34d4e32bf824d0dde6028ae79c5f07b580f5dce240d7111f7ddb130a7945cd7d957d1920994da389f490c89", 16), new BigInteger("c0a0758cdf14256f78d4708c86becdead1b50ad4ad6c5c703e2168fbf37884cb", 16), new BigInteger("f01734d7960ea60070f1b06f2bb81bfac48ff192ae18451d5e56c734a5aab8a5", 16), new BigInteger("b54bb9edff22051d9ee60f9351a48591b6500a319429c069a3e335a1d6171391", 16), new BigInteger("d3d83daf2a0cecd3367ae6f8ae1aeb82e9ac2f816c6fc483533d8297dd7884cd", 16), new BigInteger("b8f52fc6f38593dabb661d3f50f8897f8106eee68b1bce78a95b132b4e5b5d19", 16)); // // ca keys // RSAPublicKeySpec caPubKeySpec = new RSAPublicKeySpec( new BigInteger("b259d2d6e627a768c94be36164c2d9fc79d97aab9253140e5bf17751197731d6f7540d2509e7b9ffee0a70a6e26d56e92d2edd7f85aba85600b69089f35f6bdbf3c298e05842535d9f064e6b0391cb7d306e0a2d20c4dfb4e7b49a9640bdea26c10ad69c3f05007ce2513cee44cfe01998e62b6c3637d3fc0391079b26ee36d5", 16), new BigInteger("11", 16)); RSAPrivateCrtKeySpec caPrivKeySpec = new RSAPrivateCrtKeySpec( new BigInteger("b259d2d6e627a768c94be36164c2d9fc79d97aab9253140e5bf17751197731d6f7540d2509e7b9ffee0a70a6e26d56e92d2edd7f85aba85600b69089f35f6bdbf3c298e05842535d9f064e6b0391cb7d306e0a2d20c4dfb4e7b49a9640bdea26c10ad69c3f05007ce2513cee44cfe01998e62b6c3637d3fc0391079b26ee36d5", 16), new BigInteger("11", 16), new BigInteger("92e08f83cc9920746989ca5034dcb384a094fb9c5a6288fcc4304424ab8f56388f72652d8fafc65a4b9020896f2cde297080f2a540e7b7ce5af0b3446e1258d1dd7f245cf54124b4c6e17da21b90a0ebd22605e6f45c9f136d7a13eaac1c0f7487de8bd6d924972408ebb58af71e76fd7b012a8d0e165f3ae2e5077a8648e619", 16), new BigInteger("f75e80839b9b9379f1cf1128f321639757dba514642c206bbbd99f9a4846208b3e93fbbe5e0527cc59b1d4b929d9555853004c7c8b30ee6a213c3d1bb7415d03", 16), new BigInteger("b892d9ebdbfc37e397256dd8a5d3123534d1f03726284743ddc6be3a709edb696fc40c7d902ed804c6eee730eee3d5b20bf6bd8d87a296813c87d3b3cc9d7947", 16), new BigInteger("1d1a2d3ca8e52068b3094d501c9a842fec37f54db16e9a67070a8b3f53cc03d4257ad252a1a640eadd603724d7bf3737914b544ae332eedf4f34436cac25ceb5", 16), new BigInteger("6c929e4e81672fef49d9c825163fec97c4b7ba7acb26c0824638ac22605d7201c94625770984f78a56e6e25904fe7db407099cad9b14588841b94f5ab498dded", 16), new BigInteger("dae7651ee69ad1d081ec5e7188ae126f6004ff39556bde90e0b870962fa7b926d070686d8244fe5a9aa709a95686a104614834b0ada4b10f53197a5cb4c97339", 16)); // // set up the keys // KeyFactory fact = KeyFactory.getInstance("RSA", "BC"); PrivateKey caPrivKey = fact.generatePrivate(caPrivKeySpec); PublicKey caPubKey = fact.generatePublic(caPubKeySpec); PrivateKey privKey = fact.generatePrivate(privKeySpec); PublicKey pubKey = fact.generatePublic(pubKeySpec); // // note in this case we are using the CA certificate for both the client cetificate // and the attribute certificate. This is to make the vcode simpler to read, in practice // the CA for the attribute certificate should be different to that of the client certificate // X509Certificate caCert = createCaCert(caPubKey, caPrivKey); X509Certificate clientCert = createClientCert(pubKey, caPrivKey, caPubKey); // Einen neuen Attributzertifikatsgenerator instantiieren X509V2AttributeCertificateGenerator acGen = new X509V2AttributeCertificateGenerator(); acGen.reset(); /* * Holder setzen hier als IssuerSerial Issuer und Serial sind ein * eindeutiger Schl�ssel f�r ein Client Zertifikat! */ acGen.setHolder(new AttributeCertificateHolder(clientCert)); // Issuer setzen acGen.setIssuer(new AttributeCertificateIssuer(PrincipalUtil.getSubjectX509Principal(caCert))); // Serial Number (frei gew�hlt) acGen.setSerialNumber(new BigInteger("1")); // not Before acGen.setNotBefore(new Date(System.currentTimeMillis() - 50000)); // not After acGen.setNotAfter(new Date(System.currentTimeMillis() + 50000)); // signature Algorithmus acGen.setSignatureAlgorithm("SHA1WithRSAEncryption"); // Die eigentlichen Attribute GeneralName roleName = new GeneralName(GeneralName.rfc822Name, "DAU123456789"); ASN1EncodableVector roleSyntax = new ASN1EncodableVector(); roleSyntax.add(roleName); // roleSyntax OID: 2.5.24.72 X509Attribute attributes = new X509Attribute("2.5.24.72", new DERSequence(roleSyntax)); acGen.addAttribute(attributes); // Privaten Schluessel der CA lesen // Und noch signieren X509V2AttributeCertificate att = (X509V2AttributeCertificate)acGen .generateCertificate(caPrivKey, "BC"); // Hier ist das Attributzertifikat fertig im Speicher, jetzt testen: // Holder AttributeCertificateHolder h = att.getHolder(); if (h.match(clientCert)) { System.out.println("Matches original client x509 cert"); } // Issuer AttributeCertificateIssuer issuer = att.getIssuer(); if (issuer.match(caCert)) { System.out.println("Matches original ca x509 cert"); } // Dates System.out.println("valid not before: " + att.getNotBefore()); System.out.println("valid not before: " + att.getNotAfter()); // Dates checken (bc wirft NotValid Exception wenn nicht g�ltig) try { att.checkValidity(); att.checkValidity(new Date()); } catch (Exception e) { System.out.println(e); } // verify try { att.verify(caPubKey, "BC"); } catch (Exception e) { System.out.println(e); } // Attribute X509Attribute[] attribs = att.getAttributes(); System.out.println("cert has " + attribs.length + " attributes:"); for (int i = 0; i < attribs.length; i++) { X509Attribute a = attribs[i]; System.out.println("OID: " + a.getOID()); if (a.getOID().equals("2.5.24.72")) { System.out.println("rolesyntax read from cert!"); } } } } bouncycastle-1.49.orig/jdk1.3/org/bouncycastle/x509/X509V2CRLGenerator.java0000644000175000017500000003145512132656275025363 0ustar ebourgebourgpackage org.bouncycastle.x509; import java.io.IOException; import java.math.BigInteger; import java.security.GeneralSecurityException; import java.security.InvalidKeyException; import java.security.NoSuchAlgorithmException; import java.security.NoSuchProviderException; import java.security.PrivateKey; import java.security.SecureRandom; import java.security.SignatureException; import java.security.cert.CRLException; import java.security.cert.X509CRL; import java.security.cert.X509CRLEntry; import java.util.Date; import java.util.Iterator; import java.util.Set; import org.bouncycastle.asn1.ASN1Encodable; import org.bouncycastle.asn1.ASN1EncodableVector; import org.bouncycastle.asn1.ASN1GeneralizedTime; import org.bouncycastle.asn1.ASN1InputStream; import org.bouncycastle.asn1.ASN1Integer; import org.bouncycastle.asn1.ASN1ObjectIdentifier; import org.bouncycastle.asn1.ASN1Sequence; import org.bouncycastle.asn1.DERBitString; import org.bouncycastle.asn1.DERObjectIdentifier; import org.bouncycastle.asn1.DERSequence; import org.bouncycastle.asn1.x509.AlgorithmIdentifier; import org.bouncycastle.asn1.x509.CertificateList; import org.bouncycastle.asn1.x509.Extensions; import org.bouncycastle.asn1.x509.TBSCertList; import org.bouncycastle.asn1.x509.Time; import org.bouncycastle.asn1.x509.V2TBSCertListGenerator; import org.bouncycastle.asn1.x509.X509Extensions; import org.bouncycastle.asn1.x509.X509ExtensionsGenerator; import org.bouncycastle.asn1.x509.X509Name; import org.bouncycastle.jce.X509Principal; import org.bouncycastle.jce.provider.X509CRLObject; /** * class to produce an X.509 Version 2 CRL. * @deprecated use org.bouncycastle.cert.X509v2CRLBuilder. */ public class X509V2CRLGenerator { private V2TBSCertListGenerator tbsGen; private DERObjectIdentifier sigOID; private AlgorithmIdentifier sigAlgId; private String signatureAlgorithm; private X509ExtensionsGenerator extGenerator; public X509V2CRLGenerator() { tbsGen = new V2TBSCertListGenerator(); extGenerator = new X509ExtensionsGenerator(); } /** * reset the generator */ public void reset() { tbsGen = new V2TBSCertListGenerator(); extGenerator.reset(); } /** * Set the issuer distinguished name - the issuer is the entity whose private key is used to sign the * certificate. */ public void setIssuerDN( X509Name issuer) { tbsGen.setIssuer(issuer); } public void setThisUpdate( Date date) { tbsGen.setThisUpdate(new Time(date)); } public void setNextUpdate( Date date) { tbsGen.setNextUpdate(new Time(date)); } /** * Reason being as indicated by CRLReason, i.e. CRLReason.keyCompromise * or 0 if CRLReason is not to be used **/ public void addCRLEntry(BigInteger userCertificate, Date revocationDate, int reason) { tbsGen.addCRLEntry(new ASN1Integer(userCertificate), new Time(revocationDate), reason); } /** * Add a CRL entry with an Invalidity Date extension as well as a CRLReason extension. * Reason being as indicated by CRLReason, i.e. CRLReason.keyCompromise * or 0 if CRLReason is not to be used **/ public void addCRLEntry(BigInteger userCertificate, Date revocationDate, int reason, Date invalidityDate) { tbsGen.addCRLEntry(new ASN1Integer(userCertificate), new Time(revocationDate), reason, new ASN1GeneralizedTime(invalidityDate)); } /** * Add a CRL entry with extensions. **/ public void addCRLEntry(BigInteger userCertificate, Date revocationDate, X509Extensions extensions) { tbsGen.addCRLEntry(new ASN1Integer(userCertificate), new Time(revocationDate), Extensions.getInstance(extensions)); } /** * Add the CRLEntry objects contained in a previous CRL. * * @param other the X509CRL to source the other entries from. */ public void addCRL(X509CRL other) throws CRLException { Set revocations = other.getRevokedCertificates(); if (revocations != null) { Iterator it = revocations.iterator(); while (it.hasNext()) { X509CRLEntry entry = (X509CRLEntry)it.next(); ASN1InputStream aIn = new ASN1InputStream(entry.getEncoded()); try { tbsGen.addCRLEntry(ASN1Sequence.getInstance(aIn.readObject())); } catch (IOException e) { throw new CRLException("exception processing encoding of CRL: " + e.toString()); } } } } /** * Set the signature algorithm. This can be either a name or an OID, names * are treated as case insensitive. * * @param signatureAlgorithm string representation of the algorithm name. */ public void setSignatureAlgorithm( String signatureAlgorithm) { this.signatureAlgorithm = signatureAlgorithm; try { sigOID = X509Util.getAlgorithmOID(signatureAlgorithm); } catch (Exception e) { throw new IllegalArgumentException("Unknown signature type requested"); } sigAlgId = X509Util.getSigAlgID(sigOID, signatureAlgorithm); tbsGen.setSignature(sigAlgId); } /** * add a given extension field for the standard extensions tag (tag 0) */ public void addExtension( String oid, boolean critical, ASN1Encodable value) { this.addExtension(new DERObjectIdentifier(oid), critical, value); } /** * add a given extension field for the standard extensions tag (tag 0) */ public void addExtension( DERObjectIdentifier oid, boolean critical, ASN1Encodable value) { extGenerator.addExtension(new ASN1ObjectIdentifier(oid.getId()), critical, value); } /** * add a given extension field for the standard extensions tag (tag 0) */ public void addExtension( String oid, boolean critical, byte[] value) { this.addExtension(new DERObjectIdentifier(oid), critical, value); } /** * add a given extension field for the standard extensions tag (tag 0) */ public void addExtension( DERObjectIdentifier oid, boolean critical, byte[] value) { extGenerator.addExtension(new ASN1ObjectIdentifier(oid.getId()), critical, value); } /** * generate an X509 CRL, based on the current issuer and subject * using the default provider "BC". * @deprecated use generate(key, "BC") */ public X509CRL generateX509CRL( PrivateKey key) throws SecurityException, SignatureException, InvalidKeyException { try { return generateX509CRL(key, "BC", null); } catch (NoSuchProviderException e) { throw new SecurityException("BC provider not installed!"); } } /** * generate an X509 CRL, based on the current issuer and subject * using the default provider "BC" and an user defined SecureRandom object as * source of randomness. * @deprecated use generate(key, random, "BC") */ public X509CRL generateX509CRL( PrivateKey key, SecureRandom random) throws SecurityException, SignatureException, InvalidKeyException { try { return generateX509CRL(key, "BC", random); } catch (NoSuchProviderException e) { throw new SecurityException("BC provider not installed!"); } } /** * generate an X509 certificate, based on the current issuer and subject * using the passed in provider for the signing. * @deprecated use generate() */ public X509CRL generateX509CRL( PrivateKey key, String provider) throws NoSuchProviderException, SecurityException, SignatureException, InvalidKeyException { return generateX509CRL(key, provider, null); } /** * generate an X509 CRL, based on the current issuer and subject, * using the passed in provider for the signing. * @deprecated use generate() */ public X509CRL generateX509CRL( PrivateKey key, String provider, SecureRandom random) throws NoSuchProviderException, SecurityException, SignatureException, InvalidKeyException { try { return generate(key, provider, random); } catch (NoSuchProviderException e) { throw e; } catch (SignatureException e) { throw e; } catch (InvalidKeyException e) { throw e; } catch (GeneralSecurityException e) { throw new SecurityException("exception: " + e); } } /** * generate an X509 CRL, based on the current issuer and subject * using the default provider. *

* Note: this differs from the deprecated method in that the default provider is * used - not "BC". *

*/ public X509CRL generate( PrivateKey key) throws CRLException, IllegalStateException, NoSuchAlgorithmException, SignatureException, InvalidKeyException { return generate(key, (SecureRandom)null); } /** * generate an X509 CRL, based on the current issuer and subject * using the default provider and an user defined SecureRandom object as * source of randomness. *

* Note: this differs from the deprecated method in that the default provider is * used - not "BC". *

*/ public X509CRL generate( PrivateKey key, SecureRandom random) throws CRLException, IllegalStateException, NoSuchAlgorithmException, SignatureException, InvalidKeyException { TBSCertList tbsCrl = generateCertList(); byte[] signature; try { signature = X509Util.calculateSignature(sigOID, signatureAlgorithm, key, random, tbsCrl); } catch (IOException e) { throw new ExtCRLException("cannot generate CRL encoding", e); } return generateJcaObject(tbsCrl, signature); } /** * generate an X509 certificate, based on the current issuer and subject * using the passed in provider for the signing. */ public X509CRL generate( PrivateKey key, String provider) throws CRLException, IllegalStateException, NoSuchProviderException, NoSuchAlgorithmException, SignatureException, InvalidKeyException { return generate(key, provider, null); } /** * generate an X509 CRL, based on the current issuer and subject, * using the passed in provider for the signing. */ public X509CRL generate( PrivateKey key, String provider, SecureRandom random) throws CRLException, IllegalStateException, NoSuchProviderException, NoSuchAlgorithmException, SignatureException, InvalidKeyException { TBSCertList tbsCrl = generateCertList(); byte[] signature; try { signature = X509Util.calculateSignature(sigOID, signatureAlgorithm, provider, key, random, tbsCrl); } catch (IOException e) { throw new ExtCRLException("cannot generate CRL encoding", e); } return generateJcaObject(tbsCrl, signature); } private TBSCertList generateCertList() { if (!extGenerator.isEmpty()) { tbsGen.setExtensions(extGenerator.generate()); } return tbsGen.generateTBSCertList(); } private X509CRL generateJcaObject(TBSCertList tbsCrl, byte[] signature) throws CRLException { ASN1EncodableVector v = new ASN1EncodableVector(); v.add(tbsCrl); v.add(sigAlgId); v.add(new DERBitString(signature)); return new X509CRLObject(new CertificateList(new DERSequence(v))); } /** * Return an iterator of the signature names supported by the generator. * * @return an iterator containing recognised names. */ public Iterator getSignatureAlgNames() { return X509Util.getAlgNames(); } private static class ExtCRLException extends CRLException { Throwable cause; ExtCRLException(String message, Throwable cause) { super(message); this.cause = cause; } public Throwable getCause() { return cause; } } } bouncycastle-1.49.orig/jdk1.3/org/bouncycastle/x509/X509V1CertificateGenerator.java0000644000175000017500000002476012132656275027165 0ustar ebourgebourgpackage org.bouncycastle.x509; import java.io.ByteArrayInputStream; import java.io.IOException; import java.math.BigInteger; import java.security.GeneralSecurityException; import java.security.InvalidKeyException; import java.security.NoSuchAlgorithmException; import java.security.NoSuchProviderException; import java.security.PrivateKey; import java.security.PublicKey; import java.security.SecureRandom; import java.security.SignatureException; import java.security.cert.CertificateEncodingException; import java.security.cert.CertificateParsingException; import java.security.cert.X509Certificate; import java.util.Date; import java.util.Iterator; import org.bouncycastle.asn1.ASN1EncodableVector; import org.bouncycastle.asn1.ASN1InputStream; import org.bouncycastle.asn1.ASN1Integer; import org.bouncycastle.asn1.ASN1Sequence; import org.bouncycastle.asn1.DERBitString; import org.bouncycastle.asn1.DERObjectIdentifier; import org.bouncycastle.asn1.DERSequence; import org.bouncycastle.asn1.x509.AlgorithmIdentifier; import org.bouncycastle.asn1.x509.SubjectPublicKeyInfo; import org.bouncycastle.asn1.x509.TBSCertificate; import org.bouncycastle.asn1.x509.Time; import org.bouncycastle.asn1.x509.V1TBSCertificateGenerator; import org.bouncycastle.asn1.x509.Certificate; import org.bouncycastle.asn1.x509.X509Name; import org.bouncycastle.jce.provider.X509CertificateObject; /** * class to produce an X.509 Version 1 certificate. * @deprecated use org.bouncycastle.cert.X509v1CertificateBuilder. */ public class X509V1CertificateGenerator { private V1TBSCertificateGenerator tbsGen; private DERObjectIdentifier sigOID; private AlgorithmIdentifier sigAlgId; private String signatureAlgorithm; public X509V1CertificateGenerator() { tbsGen = new V1TBSCertificateGenerator(); } /** * reset the generator */ public void reset() { tbsGen = new V1TBSCertificateGenerator(); } /** * set the serial number for the certificate. */ public void setSerialNumber( BigInteger serialNumber) { if (serialNumber.compareTo(BigInteger.ZERO) <= 0) { throw new IllegalArgumentException("serial number must be a positive integer"); } tbsGen.setSerialNumber(new ASN1Integer(serialNumber)); } /** * Set the issuer distinguished name - the issuer is the entity whose private key is used to sign the * certificate. */ public void setIssuerDN( X509Name issuer) { tbsGen.setIssuer(issuer); } public void setNotBefore( Date date) { tbsGen.setStartDate(new Time(date)); } public void setNotAfter( Date date) { tbsGen.setEndDate(new Time(date)); } /** * Set the subject distinguished name. The subject describes the entity associated with the public key. */ public void setSubjectDN( X509Name subject) { tbsGen.setSubject(subject); } public void setPublicKey( PublicKey key) { try { tbsGen.setSubjectPublicKeyInfo(new SubjectPublicKeyInfo((ASN1Sequence)new ASN1InputStream( new ByteArrayInputStream(key.getEncoded())).readObject())); } catch (Exception e) { throw new IllegalArgumentException("unable to process key - " + e.toString()); } } /** * Set the signature algorithm. This can be either a name or an OID, names * are treated as case insensitive. * * @param signatureAlgorithm string representation of the algorithm name. */ public void setSignatureAlgorithm( String signatureAlgorithm) { this.signatureAlgorithm = signatureAlgorithm; try { sigOID = X509Util.getAlgorithmOID(signatureAlgorithm); } catch (Exception e) { throw new IllegalArgumentException("Unknown signature type requested"); } sigAlgId = X509Util.getSigAlgID(sigOID, signatureAlgorithm); tbsGen.setSignature(sigAlgId); } /** * generate an X509 certificate, based on the current issuer and subject * using the default provider "BC". * @deprecated use generate(key, "BC") */ public X509Certificate generateX509Certificate( PrivateKey key) throws SecurityException, SignatureException, InvalidKeyException { try { return generateX509Certificate(key, "BC", null); } catch (NoSuchProviderException e) { throw new SecurityException("BC provider not installed!"); } } /** * generate an X509 certificate, based on the current issuer and subject * using the default provider "BC" and the passed in source of randomness * @deprecated use generate(key, random, "BC") */ public X509Certificate generateX509Certificate( PrivateKey key, SecureRandom random) throws SecurityException, SignatureException, InvalidKeyException { try { return generateX509Certificate(key, "BC", random); } catch (NoSuchProviderException e) { throw new SecurityException("BC provider not installed!"); } } /** * generate an X509 certificate, based on the current issuer and subject, * using the passed in provider for the signing, and the passed in source * of randomness (if required). * @deprecated use generate() */ public X509Certificate generateX509Certificate( PrivateKey key, String provider) throws NoSuchProviderException, SecurityException, SignatureException, InvalidKeyException { return generateX509Certificate(key, provider, null); } /** * generate an X509 certificate, based on the current issuer and subject, * using the passed in provider for the signing, and the passed in source * of randomness (if required). * @deprecated use generate() */ public X509Certificate generateX509Certificate( PrivateKey key, String provider, SecureRandom random) throws NoSuchProviderException, SecurityException, SignatureException, InvalidKeyException { try { return generate(key, provider, random); } catch (NoSuchProviderException e) { throw e; } catch (SignatureException e) { throw e; } catch (InvalidKeyException e) { throw e; } catch (GeneralSecurityException e) { throw new SecurityException("exception: " + e); } } /** * generate an X509 certificate, based on the current issuer and subject * using the default provider. *

* Note: this differs from the deprecated method in that the default provider is * used - not "BC". *

*/ public X509Certificate generate( PrivateKey key) throws CertificateEncodingException, IllegalStateException, NoSuchAlgorithmException, SignatureException, InvalidKeyException { return generate(key, (SecureRandom)null); } /** * generate an X509 certificate, based on the current issuer and subject * using the default provider and the passed in source of randomness *

* Note: this differs from the deprecated method in that the default provider is * used - not "BC". *

*/ public X509Certificate generate( PrivateKey key, SecureRandom random) throws CertificateEncodingException, IllegalStateException, NoSuchAlgorithmException, SignatureException, InvalidKeyException { TBSCertificate tbsCert = tbsGen.generateTBSCertificate(); byte[] signature; try { signature = X509Util.calculateSignature(sigOID, signatureAlgorithm, key, random, tbsCert); } catch (IOException e) { throw new ExtCertificateEncodingException("exception encoding TBS cert", e); } return generateJcaObject(tbsCert, signature); } /** * generate an X509 certificate, based on the current issuer and subject, * using the passed in provider for the signing, and the passed in source * of randomness (if required). */ public X509Certificate generate( PrivateKey key, String provider) throws CertificateEncodingException, IllegalStateException, NoSuchProviderException, NoSuchAlgorithmException, SignatureException, InvalidKeyException { return generate(key, provider, null); } /** * generate an X509 certificate, based on the current issuer and subject, * using the passed in provider for the signing, and the passed in source * of randomness (if required). */ public X509Certificate generate( PrivateKey key, String provider, SecureRandom random) throws CertificateEncodingException, IllegalStateException, NoSuchProviderException, NoSuchAlgorithmException, SignatureException, InvalidKeyException { TBSCertificate tbsCert = tbsGen.generateTBSCertificate(); byte[] signature; try { signature = X509Util.calculateSignature(sigOID, signatureAlgorithm, provider, key, random, tbsCert); } catch (IOException e) { throw new ExtCertificateEncodingException("exception encoding TBS cert", e); } return generateJcaObject(tbsCert, signature); } private X509Certificate generateJcaObject(TBSCertificate tbsCert, byte[] signature) throws CertificateEncodingException { ASN1EncodableVector v = new ASN1EncodableVector(); v.add(tbsCert); v.add(sigAlgId); v.add(new DERBitString(signature)); try { return new X509CertificateObject(Certificate.getInstance(new DERSequence(v))); } catch (CertificateParsingException e) { throw new ExtCertificateEncodingException("exception producing certificate object", e); } } /** * Return an iterator of the signature names supported by the generator. * * @return an iterator containing recognised names. */ public Iterator getSignatureAlgNames() { return X509Util.getAlgNames(); } } bouncycastle-1.49.orig/jdk1.3/org/bouncycastle/x509/X509AttributeCertStoreSelector.java0000644000175000017500000003531511624652555030164 0ustar ebourgebourgpackage org.bouncycastle.x509; import java.io.IOException; import java.math.BigInteger; import java.security.cert.CertificateExpiredException; import java.security.cert.CertificateNotYetValidException; import java.util.Collection; import java.util.Collections; import java.util.Date; import java.util.HashSet; import java.util.Iterator; import java.util.Set; import org.bouncycastle.asn1.ASN1InputStream; import org.bouncycastle.asn1.ASN1Primitive; import org.bouncycastle.asn1.DEROctetString; import org.bouncycastle.asn1.x509.GeneralName; import org.bouncycastle.asn1.x509.Target; import org.bouncycastle.asn1.x509.TargetInformation; import org.bouncycastle.asn1.x509.Targets; import org.bouncycastle.asn1.x509.X509Extensions; import org.bouncycastle.util.Selector; /** * This class is an Selector like implementation to select * attribute certificates from a given set of criteria. * * @see org.bouncycastle.x509.X509AttributeCertificate * @see org.bouncycastle.x509.X509Store */ public class X509AttributeCertStoreSelector implements Selector { // TODO: name constraints??? private AttributeCertificateHolder holder; private AttributeCertificateIssuer issuer; private BigInteger serialNumber; private Date attributeCertificateValid; private X509AttributeCertificate attributeCert; private Collection targetNames = new HashSet(); private Collection targetGroups = new HashSet(); public X509AttributeCertStoreSelector() { super(); } /** * Decides if the given attribute certificate should be selected. * * @param obj The attribute certificate which should be checked. * @return true if the attribute certificate can be selected, * false otherwise. */ public boolean match(Object obj) { if (!(obj instanceof X509AttributeCertificate)) { return false; } X509AttributeCertificate attrCert = (X509AttributeCertificate) obj; if (this.attributeCert != null) { if (!this.attributeCert.equals(attrCert)) { return false; } } if (serialNumber != null) { if (!attrCert.getSerialNumber().equals(serialNumber)) { return false; } } if (holder != null) { if (!attrCert.getHolder().equals(holder)) { return false; } } if (issuer != null) { if (!attrCert.getIssuer().equals(issuer)) { return false; } } if (attributeCertificateValid != null) { try { attrCert.checkValidity(attributeCertificateValid); } catch (CertificateExpiredException e) { return false; } catch (CertificateNotYetValidException e) { return false; } } if (!targetNames.isEmpty() || !targetGroups.isEmpty()) { byte[] targetInfoExt = attrCert .getExtensionValue(X509Extensions.TargetInformation.getId()); if (targetInfoExt != null) { TargetInformation targetinfo; try { targetinfo = TargetInformation .getInstance(new ASN1InputStream( ((DEROctetString) DEROctetString .fromByteArray(targetInfoExt)).getOctets()) .readObject()); } catch (IOException e) { return false; } catch (IllegalArgumentException e) { return false; } Targets[] targetss = targetinfo.getTargetsObjects(); if (!targetNames.isEmpty()) { boolean found = false; for (int i=0; inull is * given any will do. * * @param attributeCert The attribute certificate to set. */ public void setAttributeCert(X509AttributeCertificate attributeCert) { this.attributeCert = attributeCert; } /** * Get the criteria for the validity. * * @return Returns the attributeCertificateValid. */ public Date getAttributeCertificateValid() { if (attributeCertificateValid != null) { return new Date(attributeCertificateValid.getTime()); } return null; } /** * Set the time, when the certificate must be valid. If null * is given any will do. * * @param attributeCertificateValid The attribute certificate validation * time to set. */ public void setAttributeCertificateValid(Date attributeCertificateValid) { if (attributeCertificateValid != null) { this.attributeCertificateValid = new Date(attributeCertificateValid .getTime()); } else { this.attributeCertificateValid = null; } } /** * Gets the holder. * * @return Returns the holder. */ public AttributeCertificateHolder getHolder() { return holder; } /** * Sets the holder. If null is given any will do. * * @param holder The holder to set. */ public void setHolder(AttributeCertificateHolder holder) { this.holder = holder; } /** * Returns the issuer criterion. * * @return Returns the issuer. */ public AttributeCertificateIssuer getIssuer() { return issuer; } /** * Sets the issuer the attribute certificate must have. If null * is given any will do. * * @param issuer The issuer to set. */ public void setIssuer(AttributeCertificateIssuer issuer) { this.issuer = issuer; } /** * Gets the serial number the attribute certificate must have. * * @return Returns the serialNumber. */ public BigInteger getSerialNumber() { return serialNumber; } /** * Sets the serial number the attribute certificate must have. If * null is given any will do. * * @param serialNumber The serialNumber to set. */ public void setSerialNumber(BigInteger serialNumber) { this.serialNumber = serialNumber; } /** * Adds a target name criterion for the attribute certificate to the target * information extension criteria. The X509AttributeCertificate * must contain at least one of the specified target names. *

* Each attribute certificate may contain a target information extension * limiting the servers where this attribute certificate can be used. If * this extension is not present, the attribute certificate is not targeted * and may be accepted by any server. * * @param name The name as a GeneralName (not null) */ public void addTargetName(GeneralName name) { targetNames.add(name); } /** * Adds a target name criterion for the attribute certificate to the target * information extension criteria. The X509AttributeCertificate * must contain at least one of the specified target names. *

* Each attribute certificate may contain a target information extension * limiting the servers where this attribute certificate can be used. If * this extension is not present, the attribute certificate is not targeted * and may be accepted by any server. * * @param name a byte array containing the name in ASN.1 DER encoded form of a GeneralName * @throws IOException if a parsing error occurs. */ public void addTargetName(byte[] name) throws IOException { addTargetName(GeneralName.getInstance(ASN1Primitive.fromByteArray(name))); } /** * Adds a collection with target names criteria. If null is * given any will do. *

* The collection consists of either GeneralName objects or byte[] arrays representing * DER encoded GeneralName structures. * * @param names A collection of target names. * @throws IOException if a parsing error occurs. * @see #addTargetName(byte[]) * @see #addTargetName(GeneralName) */ public void setTargetNames(Collection names) throws IOException { targetNames = extractGeneralNames(names); } /** * Gets the target names. The collection consists of Lists * made up of an Integer in the first entry and a DER encoded * byte array or a String in the second entry. *

* The returned collection is immutable. * * @return The collection of target names * @see #setTargetNames(Collection) */ public Collection getTargetNames() { return Collections.unmodifiableCollection(targetNames); } /** * Adds a target group criterion for the attribute certificate to the target * information extension criteria. The X509AttributeCertificate * must contain at least one of the specified target groups. *

* Each attribute certificate may contain a target information extension * limiting the servers where this attribute certificate can be used. If * this extension is not present, the attribute certificate is not targeted * and may be accepted by any server. * * @param group The group as GeneralName form (not null) */ public void addTargetGroup(GeneralName group) { targetGroups.add(group); } /** * Adds a target group criterion for the attribute certificate to the target * information extension criteria. The X509AttributeCertificate * must contain at least one of the specified target groups. *

* Each attribute certificate may contain a target information extension * limiting the servers where this attribute certificate can be used. If * this extension is not present, the attribute certificate is not targeted * and may be accepted by any server. * * @param name a byte array containing the group in ASN.1 DER encoded form of a GeneralName * @throws IOException if a parsing error occurs. */ public void addTargetGroup(byte[] name) throws IOException { addTargetGroup(GeneralName.getInstance(ASN1Primitive.fromByteArray(name))); } /** * Adds a collection with target groups criteria. If null is * given any will do. *

* The collection consists of GeneralName objects or byte[]Lists * made up of an Integer in the first entry and a DER encoded * byte array or a String in the second entry. *

* The returned collection is immutable. * * @return The collection of target groups. * @see #setTargetGroups(Collection) */ public Collection getTargetGroups() { return Collections.unmodifiableCollection(targetGroups); } private Set extractGeneralNames(Collection names) throws IOException { if (names == null || names.isEmpty()) { return new HashSet(); } Set temp = new HashSet(); for (Iterator it = names.iterator(); it.hasNext();) { Object o = it.next(); if (o instanceof GeneralName) { temp.add(o); } else { temp.add(GeneralName.getInstance(ASN1Primitive.fromByteArray((byte[])o))); } } return temp; } } bouncycastle-1.49.orig/jdk1.3/org/bouncycastle/x509/X509V3CertificateGenerator.java0000644000175000017500000003533512132656275027167 0ustar ebourgebourgpackage org.bouncycastle.x509; import java.io.IOException; import java.math.BigInteger; import java.security.GeneralSecurityException; import java.security.InvalidKeyException; import java.security.NoSuchAlgorithmException; import java.security.NoSuchProviderException; import java.security.PrivateKey; import java.security.PublicKey; import java.security.SecureRandom; import java.security.SignatureException; import java.security.cert.CertificateEncodingException; import java.security.cert.CertificateParsingException; import java.security.cert.X509Certificate; import java.util.Date; import java.util.Iterator; import org.bouncycastle.asn1.ASN1Encodable; import org.bouncycastle.asn1.ASN1EncodableVector; import org.bouncycastle.asn1.ASN1InputStream; import org.bouncycastle.asn1.ASN1Integer; import org.bouncycastle.asn1.ASN1ObjectIdentifier; import org.bouncycastle.asn1.DERBitString; import org.bouncycastle.asn1.DERObjectIdentifier; import org.bouncycastle.asn1.DERSequence; import org.bouncycastle.asn1.x509.AlgorithmIdentifier; import org.bouncycastle.asn1.x509.SubjectPublicKeyInfo; import org.bouncycastle.asn1.x509.TBSCertificate; import org.bouncycastle.asn1.x509.Time; import org.bouncycastle.asn1.x509.V3TBSCertificateGenerator; import org.bouncycastle.asn1.x509.Certificate; import org.bouncycastle.asn1.x509.X509ExtensionsGenerator; import org.bouncycastle.asn1.x509.X509Name; import org.bouncycastle.jce.provider.X509CertificateObject; import org.bouncycastle.x509.extension.X509ExtensionUtil; /** * class to produce an X.509 Version 3 certificate. * @deprecated use org.bouncycastle.cert.X509v3CertificateBuilder. */ public class X509V3CertificateGenerator { private V3TBSCertificateGenerator tbsGen; private DERObjectIdentifier sigOID; private AlgorithmIdentifier sigAlgId; private String signatureAlgorithm; private X509ExtensionsGenerator extGenerator; public X509V3CertificateGenerator() { tbsGen = new V3TBSCertificateGenerator(); extGenerator = new X509ExtensionsGenerator(); } /** * reset the generator */ public void reset() { tbsGen = new V3TBSCertificateGenerator(); extGenerator.reset(); } /** * set the serial number for the certificate. */ public void setSerialNumber( BigInteger serialNumber) { if (serialNumber.compareTo(BigInteger.ZERO) <= 0) { throw new IllegalArgumentException("serial number must be a positive integer"); } tbsGen.setSerialNumber(new ASN1Integer(serialNumber)); } /** * Set the issuer distinguished name - the issuer is the entity whose private key is used to sign the * certificate. */ public void setIssuerDN( X509Name issuer) { tbsGen.setIssuer(issuer); } public void setNotBefore( Date date) { tbsGen.setStartDate(new Time(date)); } public void setNotAfter( Date date) { tbsGen.setEndDate(new Time(date)); } /** * Set the subject distinguished name. The subject describes the entity associated with the public key. */ public void setSubjectDN( X509Name subject) { tbsGen.setSubject(subject); } public void setPublicKey( PublicKey key) throws IllegalArgumentException { try { tbsGen.setSubjectPublicKeyInfo( SubjectPublicKeyInfo.getInstance(new ASN1InputStream(key.getEncoded()).readObject())); } catch (Exception e) { throw new IllegalArgumentException("unable to process key - " + e.toString()); } } /** * Set the signature algorithm. This can be either a name or an OID, names * are treated as case insensitive. * * @param signatureAlgorithm string representation of the algorithm name. */ public void setSignatureAlgorithm( String signatureAlgorithm) { this.signatureAlgorithm = signatureAlgorithm; try { sigOID = X509Util.getAlgorithmOID(signatureAlgorithm); } catch (Exception e) { throw new IllegalArgumentException("Unknown signature type requested: " + signatureAlgorithm); } sigAlgId = X509Util.getSigAlgID(sigOID, signatureAlgorithm); tbsGen.setSignature(sigAlgId); } /** * Set the subject unique ID - note: it is very rare that it is correct to do this. */ public void setSubjectUniqueID(boolean[] uniqueID) { tbsGen.setSubjectUniqueID(booleanToBitString(uniqueID)); } /** * Set the issuer unique ID - note: it is very rare that it is correct to do this. */ public void setIssuerUniqueID(boolean[] uniqueID) { tbsGen.setIssuerUniqueID(booleanToBitString(uniqueID)); } private DERBitString booleanToBitString(boolean[] id) { byte[] bytes = new byte[(id.length + 7) / 8]; for (int i = 0; i != id.length; i++) { bytes[i / 8] |= (id[i]) ? (1 << ((7 - (i % 8)))) : 0; } int pad = id.length % 8; if (pad == 0) { return new DERBitString(bytes); } else { return new DERBitString(bytes, 8 - pad); } } /** * add a given extension field for the standard extensions tag (tag 3) */ public void addExtension( String oid, boolean critical, ASN1Encodable value) { this.addExtension(new DERObjectIdentifier(oid), critical, value); } /** * add a given extension field for the standard extensions tag (tag 3) */ public void addExtension( DERObjectIdentifier oid, boolean critical, ASN1Encodable value) { extGenerator.addExtension(new ASN1ObjectIdentifier(oid.getId()), critical, value); } /** * add a given extension field for the standard extensions tag (tag 3) * The value parameter becomes the contents of the octet string associated * with the extension. */ public void addExtension( String oid, boolean critical, byte[] value) { this.addExtension(new DERObjectIdentifier(oid), critical, value); } /** * add a given extension field for the standard extensions tag (tag 3) */ public void addExtension( DERObjectIdentifier oid, boolean critical, byte[] value) { extGenerator.addExtension(new ASN1ObjectIdentifier(oid.getId()), critical, value); } /** * add a given extension field for the standard extensions tag (tag 3) * copying the extension value from another certificate. * @throws CertificateParsingException if the extension cannot be extracted. */ public void copyAndAddExtension( String oid, boolean critical, X509Certificate cert) throws CertificateParsingException { byte[] extValue = cert.getExtensionValue(oid); if (extValue == null) { throw new CertificateParsingException("extension " + oid + " not present"); } try { ASN1Encodable value = X509ExtensionUtil.fromExtensionValue(extValue); this.addExtension(oid, critical, value); } catch (IOException e) { throw new CertificateParsingException(e.toString()); } } /** * add a given extension field for the standard extensions tag (tag 3) * copying the extension value from another certificate. * @throws CertificateParsingException if the extension cannot be extracted. */ public void copyAndAddExtension( DERObjectIdentifier oid, boolean critical, X509Certificate cert) throws CertificateParsingException { this.copyAndAddExtension(oid.getId(), critical, cert); } /** * generate an X509 certificate, based on the current issuer and subject * using the default provider "BC". * @deprecated use generate(key, "BC") */ public X509Certificate generateX509Certificate( PrivateKey key) throws SecurityException, SignatureException, InvalidKeyException { try { return generateX509Certificate(key, "BC", null); } catch (NoSuchProviderException e) { throw new SecurityException("BC provider not installed!"); } } /** * generate an X509 certificate, based on the current issuer and subject * using the default provider "BC", and the passed in source of randomness * (if required). * @deprecated use generate(key, random, "BC") */ public X509Certificate generateX509Certificate( PrivateKey key, SecureRandom random) throws SecurityException, SignatureException, InvalidKeyException { try { return generateX509Certificate(key, "BC", random); } catch (NoSuchProviderException e) { throw new SecurityException("BC provider not installed!"); } } /** * generate an X509 certificate, based on the current issuer and subject, * using the passed in provider for the signing. * @deprecated use generate() */ public X509Certificate generateX509Certificate( PrivateKey key, String provider) throws NoSuchProviderException, SecurityException, SignatureException, InvalidKeyException { return generateX509Certificate(key, provider, null); } /** * generate an X509 certificate, based on the current issuer and subject, * using the passed in provider for the signing and the supplied source * of randomness, if required. * @deprecated use generate() */ public X509Certificate generateX509Certificate( PrivateKey key, String provider, SecureRandom random) throws NoSuchProviderException, SecurityException, SignatureException, InvalidKeyException { try { return generate(key, provider, random); } catch (NoSuchProviderException e) { throw e; } catch (SignatureException e) { throw e; } catch (InvalidKeyException e) { throw e; } catch (GeneralSecurityException e) { throw new SecurityException("exception: " + e); } } /** * generate an X509 certificate, based on the current issuer and subject * using the default provider. *

* Note: this differs from the deprecated method in that the default provider is * used - not "BC". *

*/ public X509Certificate generate( PrivateKey key) throws CertificateEncodingException, IllegalStateException, NoSuchAlgorithmException, SignatureException, InvalidKeyException { return generate(key, (SecureRandom)null); } /** * generate an X509 certificate, based on the current issuer and subject * using the default provider, and the passed in source of randomness * (if required). *

* Note: this differs from the deprecated method in that the default provider is * used - not "BC". *

*/ public X509Certificate generate( PrivateKey key, SecureRandom random) throws CertificateEncodingException, IllegalStateException, NoSuchAlgorithmException, SignatureException, InvalidKeyException { TBSCertificate tbsCert = generateTbsCert(); byte[] signature; try { signature = X509Util.calculateSignature(sigOID, signatureAlgorithm, key, random, tbsCert); } catch (IOException e) { throw new ExtCertificateEncodingException("exception encoding TBS cert", e); } try { return generateJcaObject(tbsCert, signature); } catch (CertificateParsingException e) { throw new ExtCertificateEncodingException("exception producing certificate object", e); } } /** * generate an X509 certificate, based on the current issuer and subject, * using the passed in provider for the signing. */ public X509Certificate generate( PrivateKey key, String provider) throws CertificateEncodingException, IllegalStateException, NoSuchProviderException, NoSuchAlgorithmException, SignatureException, InvalidKeyException { return generate(key, provider, null); } /** * generate an X509 certificate, based on the current issuer and subject, * using the passed in provider for the signing and the supplied source * of randomness, if required. */ public X509Certificate generate( PrivateKey key, String provider, SecureRandom random) throws CertificateEncodingException, IllegalStateException, NoSuchProviderException, NoSuchAlgorithmException, SignatureException, InvalidKeyException { TBSCertificate tbsCert = generateTbsCert(); byte[] signature; try { signature = X509Util.calculateSignature(sigOID, signatureAlgorithm, provider, key, random, tbsCert); } catch (IOException e) { throw new ExtCertificateEncodingException("exception encoding TBS cert", e); } try { return generateJcaObject(tbsCert, signature); } catch (CertificateParsingException e) { throw new ExtCertificateEncodingException("exception producing certificate object", e); } } private TBSCertificate generateTbsCert() { if (!extGenerator.isEmpty()) { tbsGen.setExtensions(extGenerator.generate()); } return tbsGen.generateTBSCertificate(); } private X509Certificate generateJcaObject(TBSCertificate tbsCert, byte[] signature) throws CertificateParsingException { ASN1EncodableVector v = new ASN1EncodableVector(); v.add(tbsCert); v.add(sigAlgId); v.add(new DERBitString(signature)); return new X509CertificateObject(Certificate.getInstance(new DERSequence(v))); } /** * Return an iterator of the signature names supported by the generator. * * @return an iterator containing recognised names. */ public Iterator getSignatureAlgNames() { return X509Util.getAlgNames(); } } bouncycastle-1.49.orig/jdk1.3/org/bouncycastle/operator/0000755000175000017500000000000012152033550022534 5ustar ebourgebourgbouncycastle-1.49.orig/jdk1.3/org/bouncycastle/operator/jcajce/0000755000175000017500000000000012152033550023753 5ustar ebourgebourgbouncycastle-1.49.orig/jdk1.3/org/bouncycastle/operator/jcajce/OperatorHelper.java0000644000175000017500000003224111723612405027560 0ustar ebourgebourgpackage org.bouncycastle.operator.jcajce; import java.io.ByteArrayInputStream; import java.io.IOException; import java.security.GeneralSecurityException; import java.security.MessageDigest; import java.security.NoSuchAlgorithmException; import java.security.NoSuchProviderException; import java.security.Signature; import java.security.cert.CertificateException; import java.security.cert.CertificateFactory; import java.security.cert.X509Certificate; import java.util.HashMap; import java.util.Map; import javax.crypto.Cipher; import org.bouncycastle.asn1.ASN1Encodable; import org.bouncycastle.asn1.ASN1ObjectIdentifier; import org.bouncycastle.asn1.DERNull; import org.bouncycastle.asn1.cryptopro.CryptoProObjectIdentifiers; import org.bouncycastle.asn1.kisa.KISAObjectIdentifiers; import org.bouncycastle.asn1.nist.NISTObjectIdentifiers; import org.bouncycastle.asn1.ntt.NTTObjectIdentifiers; import org.bouncycastle.asn1.oiw.OIWObjectIdentifiers; import org.bouncycastle.asn1.pkcs.PKCSObjectIdentifiers; import org.bouncycastle.asn1.pkcs.RSASSAPSSparams; import org.bouncycastle.asn1.teletrust.TeleTrusTObjectIdentifiers; import org.bouncycastle.asn1.x509.AlgorithmIdentifier; import org.bouncycastle.asn1.x9.X9ObjectIdentifiers; import org.bouncycastle.cert.X509CertificateHolder; import org.bouncycastle.jcajce.JcaJceHelper; import org.bouncycastle.operator.OperatorCreationException; //import java.security.spec.PSSParameterSpec; class OperatorHelper { private static final Map oids = new HashMap(); private static final Map asymmetricWrapperAlgNames = new HashMap(); private static final Map symmetricWrapperAlgNames = new HashMap(); private static final Map symmetricKeyAlgNames = new HashMap(); static { // // reverse mappings // oids.put(new ASN1ObjectIdentifier("1.2.840.113549.1.1.5"), "SHA1WITHRSA"); oids.put(PKCSObjectIdentifiers.sha224WithRSAEncryption, "SHA224WITHRSA"); oids.put(PKCSObjectIdentifiers.sha256WithRSAEncryption, "SHA256WITHRSA"); oids.put(PKCSObjectIdentifiers.sha384WithRSAEncryption, "SHA384WITHRSA"); oids.put(PKCSObjectIdentifiers.sha512WithRSAEncryption, "SHA512WITHRSA"); oids.put(CryptoProObjectIdentifiers.gostR3411_94_with_gostR3410_94, "GOST3411WITHGOST3410"); oids.put(CryptoProObjectIdentifiers.gostR3411_94_with_gostR3410_2001, "GOST3411WITHECGOST3410"); oids.put(new ASN1ObjectIdentifier("1.2.840.113549.1.1.4"), "MD5WITHRSA"); oids.put(new ASN1ObjectIdentifier("1.2.840.113549.1.1.2"), "MD2WITHRSA"); oids.put(new ASN1ObjectIdentifier("1.2.840.10040.4.3"), "SHA1WITHDSA"); oids.put(X9ObjectIdentifiers.ecdsa_with_SHA1, "SHA1WITHECDSA"); oids.put(X9ObjectIdentifiers.ecdsa_with_SHA224, "SHA224WITHECDSA"); oids.put(X9ObjectIdentifiers.ecdsa_with_SHA256, "SHA256WITHECDSA"); oids.put(X9ObjectIdentifiers.ecdsa_with_SHA384, "SHA384WITHECDSA"); oids.put(X9ObjectIdentifiers.ecdsa_with_SHA512, "SHA512WITHECDSA"); oids.put(OIWObjectIdentifiers.sha1WithRSA, "SHA1WITHRSA"); oids.put(OIWObjectIdentifiers.dsaWithSHA1, "SHA1WITHDSA"); oids.put(NISTObjectIdentifiers.dsa_with_sha224, "SHA224WITHDSA"); oids.put(NISTObjectIdentifiers.dsa_with_sha256, "SHA256WITHDSA"); asymmetricWrapperAlgNames.put(new ASN1ObjectIdentifier(PKCSObjectIdentifiers.rsaEncryption.getId()), "RSA/ECB/PKCS1Padding"); symmetricWrapperAlgNames.put(PKCSObjectIdentifiers.id_alg_CMS3DESwrap, "DESEDEWrap"); symmetricWrapperAlgNames.put(PKCSObjectIdentifiers.id_alg_CMSRC2wrap, "RC2Wrap"); symmetricWrapperAlgNames.put(NISTObjectIdentifiers.id_aes128_wrap, "AESWrap"); symmetricWrapperAlgNames.put(NISTObjectIdentifiers.id_aes192_wrap, "AESWrap"); symmetricWrapperAlgNames.put(NISTObjectIdentifiers.id_aes256_wrap, "AESWrap"); symmetricWrapperAlgNames.put(NTTObjectIdentifiers.id_camellia128_wrap, "CamelliaWrap"); symmetricWrapperAlgNames.put(NTTObjectIdentifiers.id_camellia192_wrap, "CamelliaWrap"); symmetricWrapperAlgNames.put(NTTObjectIdentifiers.id_camellia256_wrap, "CamelliaWrap"); symmetricWrapperAlgNames.put(KISAObjectIdentifiers.id_npki_app_cmsSeed_wrap, "SEEDWrap"); symmetricWrapperAlgNames.put(PKCSObjectIdentifiers.des_EDE3_CBC, "DESede"); symmetricKeyAlgNames.put(NISTObjectIdentifiers.aes, "AES"); symmetricKeyAlgNames.put(NISTObjectIdentifiers.id_aes128_CBC, "AES"); symmetricKeyAlgNames.put(NISTObjectIdentifiers.id_aes192_CBC, "AES"); symmetricKeyAlgNames.put(NISTObjectIdentifiers.id_aes256_CBC, "AES"); symmetricKeyAlgNames.put(PKCSObjectIdentifiers.des_EDE3_CBC, "DESede"); symmetricKeyAlgNames.put(PKCSObjectIdentifiers.RC2_CBC, "RC2"); } private JcaJceHelper helper; OperatorHelper(JcaJceHelper helper) { this.helper = helper; } Cipher createAsymmetricWrapper(ASN1ObjectIdentifier algorithm, Map extraAlgNames) throws OperatorCreationException { try { String cipherName = null; if (!extraAlgNames.isEmpty()) { cipherName = (String)extraAlgNames.get(algorithm); } if (cipherName == null) { cipherName = (String)asymmetricWrapperAlgNames.get(algorithm); } if (cipherName != null) { try { // this is reversed as the Sun policy files now allow unlimited strength RSA return helper.createCipher(cipherName); } catch (NoSuchAlgorithmException e) { // try alternate for RSA if (cipherName.equals("RSA/ECB/PKCS1Padding")) { try { return helper.createCipher("RSA/NONE/PKCS1Padding"); } catch (NoSuchAlgorithmException ex) { // Ignore } } // Ignore } } return helper.createCipher(algorithm.getId()); } catch (GeneralSecurityException e) { throw new OperatorCreationException("cannot create cipher: " + e.getMessage(), e); } } Cipher createSymmetricWrapper(ASN1ObjectIdentifier algorithm) throws OperatorCreationException { try { String cipherName = (String)symmetricWrapperAlgNames.get(algorithm); if (cipherName != null) { try { // this is reversed as the Sun policy files now allow unlimited strength RSA return helper.createCipher(cipherName); } catch (NoSuchAlgorithmException e) { // Ignore } } return helper.createCipher(algorithm.getId()); } catch (GeneralSecurityException e) { throw new OperatorCreationException("cannot create cipher: " + e.getMessage(), e); } } MessageDigest createDigest(AlgorithmIdentifier digAlgId) throws GeneralSecurityException { MessageDigest dig; try { dig = helper.createDigest(getDigestAlgName(digAlgId.getAlgorithm())); } catch (NoSuchAlgorithmException e) { // // try an alternate // if (oids.get(digAlgId.getAlgorithm()) != null) { String digestAlgorithm = (String)oids.get(digAlgId.getAlgorithm()); dig = helper.createDigest(digestAlgorithm); } else { throw e; } } return dig; } Signature createSignature(AlgorithmIdentifier sigAlgId) throws GeneralSecurityException { Signature sig; try { sig = helper.createSignature(getSignatureName(sigAlgId)); } catch (NoSuchAlgorithmException e) { // // try an alternate // if (oids.get(sigAlgId.getAlgorithm()) != null) { String signatureAlgorithm = (String)oids.get(sigAlgId.getAlgorithm()); sig = helper.createSignature(signatureAlgorithm); } else { throw e; } } return sig; } public Signature createRawSignature(AlgorithmIdentifier algorithm) { Signature sig; try { String algName = getSignatureName(algorithm); algName = "NONE" + algName.substring(algName.indexOf("WITH")); sig = helper.createSignature(algName); // RFC 4056 // When the id-RSASSA-PSS algorithm identifier is used for a signature, // the AlgorithmIdentifier parameters field MUST contain RSASSA-PSS-params. /* Can;t do this pre-jdk1.4 if (algorithm.getAlgorithm().equals(PKCSObjectIdentifiers.id_RSASSA_PSS)) { AlgorithmParameters params = helper.createAlgorithmParameters(algName); params.init(algorithm.getParameters().toASN1Primitive().getEncoded(), "ASN.1"); PSSParameterSpec spec = (PSSParameterSpec)params.getParameterSpec(PSSParameterSpec.class); sig.setParameter(spec); } */ } catch (Exception e) { return null; } return sig; } private static String getSignatureName( AlgorithmIdentifier sigAlgId) { ASN1Encodable params = sigAlgId.getParameters(); if (params != null && !DERNull.INSTANCE.equals(params)) { if (sigAlgId.getAlgorithm().equals(PKCSObjectIdentifiers.id_RSASSA_PSS)) { RSASSAPSSparams rsaParams = RSASSAPSSparams.getInstance(params); return getDigestAlgName(rsaParams.getHashAlgorithm().getAlgorithm()) + "WITHRSAANDMGF1"; } } if (oids.containsKey(sigAlgId.getAlgorithm())) { return (String)oids.get(sigAlgId.getAlgorithm()); } return sigAlgId.getAlgorithm().getId(); } private static String getDigestAlgName( ASN1ObjectIdentifier digestAlgOID) { if (PKCSObjectIdentifiers.md5.equals(digestAlgOID)) { return "MD5"; } else if (OIWObjectIdentifiers.idSHA1.equals(digestAlgOID)) { return "SHA1"; } else if (NISTObjectIdentifiers.id_sha224.equals(digestAlgOID)) { return "SHA224"; } else if (NISTObjectIdentifiers.id_sha256.equals(digestAlgOID)) { return "SHA256"; } else if (NISTObjectIdentifiers.id_sha384.equals(digestAlgOID)) { return "SHA384"; } else if (NISTObjectIdentifiers.id_sha512.equals(digestAlgOID)) { return "SHA512"; } else if (TeleTrusTObjectIdentifiers.ripemd128.equals(digestAlgOID)) { return "RIPEMD128"; } else if (TeleTrusTObjectIdentifiers.ripemd160.equals(digestAlgOID)) { return "RIPEMD160"; } else if (TeleTrusTObjectIdentifiers.ripemd256.equals(digestAlgOID)) { return "RIPEMD256"; } else if (CryptoProObjectIdentifiers.gostR3411.equals(digestAlgOID)) { return "GOST3411"; } else { return digestAlgOID.getId(); } } public X509Certificate convertCertificate(X509CertificateHolder certHolder) throws CertificateException { try { CertificateFactory certFact = helper.createCertificateFactory("X.509"); return (X509Certificate)certFact.generateCertificate(new ByteArrayInputStream(certHolder.getEncoded())); } catch (IOException e) { throw new OpCertificateException("cannot get encoded form of certificate: " + e.getMessage(), e); } catch (NoSuchAlgorithmException e) { throw new OpCertificateException("cannot create certificate factory: " + e.getMessage(), e); } catch (NoSuchProviderException e) { throw new OpCertificateException("cannot find factory provider: " + e.getMessage(), e); } } // TODO: put somewhere public so cause easily accessed private static class OpCertificateException extends CertificateException { private Throwable cause; public OpCertificateException(String msg, Throwable cause) { super(msg); this.cause = cause; } public Throwable getCause() { return cause; } } String getKeyAlgorithmName(ASN1ObjectIdentifier oid) { String name = (String)symmetricKeyAlgNames.get(oid); if (name != null) { return name; } return oid.getId(); } } bouncycastle-1.49.orig/jdk1.3/org/bouncycastle/jcajce/0000755000175000017500000000000012152033550022120 5ustar ebourgebourgbouncycastle-1.49.orig/jdk1.3/org/bouncycastle/jcajce/provider/0000755000175000017500000000000012152033550023752 5ustar ebourgebourgbouncycastle-1.49.orig/jdk1.3/org/bouncycastle/jcajce/provider/asymmetric/0000755000175000017500000000000012152033550026127 5ustar ebourgebourgbouncycastle-1.49.orig/jdk1.3/org/bouncycastle/jcajce/provider/asymmetric/rsa/0000755000175000017500000000000012152033550026714 5ustar ebourgebourg././@LongLink0000000000000000000000000000015200000000000011563 Lustar rootrootbouncycastle-1.49.orig/jdk1.3/org/bouncycastle/jcajce/provider/asymmetric/rsa/AlgorithmParametersSpi.javabouncycastle-1.49.orig/jdk1.3/org/bouncycastle/jcajce/provider/asymmetric/rsa/AlgorithmParametersSpi0000644000175000017500000001352511705207420033275 0ustar ebourgebourgpackage org.bouncycastle.jcajce.provider.asymmetric.rsa; import java.io.ByteArrayOutputStream; import java.io.IOException; import java.security.spec.AlgorithmParameterSpec; import java.security.spec.InvalidParameterSpecException; import org.bouncycastle.asn1.ASN1Integer; import org.bouncycastle.asn1.DEROutputStream; import org.bouncycastle.asn1.pkcs.RSAESOAEPparams; import org.bouncycastle.asn1.pkcs.RSASSAPSSparams; public abstract class AlgorithmParametersSpi extends java.security.AlgorithmParametersSpi { protected boolean isASN1FormatString(String format) { return format == null || format.equals("ASN.1"); } protected AlgorithmParameterSpec engineGetParameterSpec( Class paramSpec) throws InvalidParameterSpecException { if (paramSpec == null) { throw new NullPointerException("argument to getParameterSpec must not be null"); } return localEngineGetParameterSpec(paramSpec); } protected abstract AlgorithmParameterSpec localEngineGetParameterSpec(Class paramSpec) throws InvalidParameterSpecException; public static class OAEP extends AlgorithmParametersSpi { AlgorithmParameterSpec currentSpec; /** * Return the PKCS#1 ASN.1 structure RSAES-OAEP-params. */ protected byte[] engineGetEncoded() { return null; } protected byte[] engineGetEncoded( String format) { if (this.isASN1FormatString(format) || format.equalsIgnoreCase("X.509")) { return engineGetEncoded(); } return null; } protected AlgorithmParameterSpec localEngineGetParameterSpec( Class paramSpec) throws InvalidParameterSpecException { throw new InvalidParameterSpecException("unknown parameter spec passed to OAEP parameters object."); } protected void engineInit( AlgorithmParameterSpec paramSpec) throws InvalidParameterSpecException { this.currentSpec = paramSpec; } protected void engineInit( byte[] params) throws IOException { try { RSAESOAEPparams oaepP = RSAESOAEPparams.getInstance(params); throw new IOException("Operation not supported"); } catch (ClassCastException e) { throw new IOException("Not a valid OAEP Parameter encoding."); } catch (ArrayIndexOutOfBoundsException e) { throw new IOException("Not a valid OAEP Parameter encoding."); } } protected void engineInit( byte[] params, String format) throws IOException { if (format.equalsIgnoreCase("X.509") || format.equalsIgnoreCase("ASN.1")) { engineInit(params); } else { throw new IOException("Unknown parameter format " + format); } } protected String engineToString() { return "OAEP Parameters"; } } public static class PSS extends AlgorithmParametersSpi { /** * Return the PKCS#1 ASN.1 structure RSASSA-PSS-params. */ protected byte[] engineGetEncoded() throws IOException { ByteArrayOutputStream bOut = new ByteArrayOutputStream(); DEROutputStream dOut = new DEROutputStream(bOut); RSASSAPSSparams pssP = new RSASSAPSSparams(RSASSAPSSparams.DEFAULT_HASH_ALGORITHM, RSASSAPSSparams.DEFAULT_MASK_GEN_FUNCTION, new ASN1Integer(20), RSASSAPSSparams.DEFAULT_TRAILER_FIELD); dOut.writeObject(pssP); dOut.close(); return bOut.toByteArray(); } protected byte[] engineGetEncoded( String format) throws IOException { if (format.equalsIgnoreCase("X.509") || format.equalsIgnoreCase("ASN.1")) { return engineGetEncoded(); } return null; } protected AlgorithmParameterSpec localEngineGetParameterSpec( Class paramSpec) throws InvalidParameterSpecException { throw new InvalidParameterSpecException("unknown parameter spec passed to PSS parameters object."); } protected void engineInit( AlgorithmParameterSpec paramSpec) throws InvalidParameterSpecException { throw new InvalidParameterSpecException("Not implemented"); } protected void engineInit( byte[] params) throws IOException { try { RSASSAPSSparams pssP = RSASSAPSSparams.getInstance(params); } catch (ClassCastException e) { throw new IOException("Not a valid PSS Parameter encoding."); } catch (ArrayIndexOutOfBoundsException e) { throw new IOException("Not a valid PSS Parameter encoding."); } } protected void engineInit( byte[] params, String format) throws IOException { if (this.isASN1FormatString(format) || format.equalsIgnoreCase("X.509")) { engineInit(params); } else { throw new IOException("Unknown parameter format " + format); } } protected String engineToString() { return "PSS Parameters"; } } } bouncycastle-1.49.orig/jdk1.3/org/bouncycastle/jcajce/provider/asymmetric/rsa/PSSSignatureSpi.java0000644000175000017500000002513511703444641032600 0ustar ebourgebourgpackage org.bouncycastle.jcajce.provider.asymmetric.rsa; import java.io.ByteArrayOutputStream; import java.security.AlgorithmParameters; import java.security.InvalidKeyException; import java.security.InvalidParameterException; import java.security.PrivateKey; import java.security.PublicKey; import java.security.SecureRandom; import java.security.Signature; import java.security.SignatureException; import java.security.interfaces.RSAPrivateKey; import java.security.interfaces.RSAPublicKey; import java.security.spec.AlgorithmParameterSpec; import org.bouncycastle.crypto.AsymmetricBlockCipher; import org.bouncycastle.crypto.CipherParameters; import org.bouncycastle.crypto.CryptoException; import org.bouncycastle.crypto.Digest; import org.bouncycastle.crypto.digests.SHA1Digest; import org.bouncycastle.crypto.digests.SHA224Digest; import org.bouncycastle.crypto.digests.SHA256Digest; import org.bouncycastle.crypto.digests.SHA384Digest; import org.bouncycastle.crypto.digests.SHA512Digest; import org.bouncycastle.crypto.engines.RSABlindedEngine; import org.bouncycastle.crypto.params.ParametersWithRandom; public class PSSSignatureSpi extends Signature { private AlgorithmParameters engineParams; private AsymmetricBlockCipher signer; private Digest contentDigest; private Digest mgfDigest; private int saltLength; private byte trailer; private boolean isRaw; private ByteArrayOutputStream bOut; private org.bouncycastle.crypto.signers.PSSSigner pss; private CipherParameters sigParams; private byte getTrailer( int trailerField) { if (trailerField == 1) { return org.bouncycastle.crypto.signers.PSSSigner.TRAILER_IMPLICIT; } throw new IllegalArgumentException("unknown trailer field"); } private void setupContentDigest() { if (isRaw) { this.contentDigest = new NullPssDigest(mgfDigest); } else { this.contentDigest = mgfDigest; } } protected PSSSignatureSpi( String name, AsymmetricBlockCipher signer, Digest digest) { super(name); this.signer = signer; this.mgfDigest = digest; if (digest != null) { this.saltLength = digest.getDigestSize(); } else { this.saltLength = 20; } this.isRaw = false; setupContentDigest(); } // care - this constructor is actually used by outside organisations protected PSSSignatureSpi( String name, AsymmetricBlockCipher signer, Digest digest, boolean isRaw) { super(name); this.signer = signer; this.mgfDigest = digest; if (digest != null) { this.saltLength = digest.getDigestSize(); } else { this.saltLength = 20; } this.isRaw = isRaw; setupContentDigest(); } protected void engineInitVerify( PublicKey publicKey) throws InvalidKeyException { if (!(publicKey instanceof RSAPublicKey)) { throw new InvalidKeyException("Supplied key is not a RSAPublicKey instance"); } sigParams = RSAUtil.generatePublicKeyParameter((RSAPublicKey)publicKey); if (isRaw) { bOut = new ByteArrayOutputStream(); } else { pss = new org.bouncycastle.crypto.signers.PSSSigner(signer, contentDigest, mgfDigest, saltLength); pss.init(false, sigParams); } } protected void engineInitSign( PrivateKey privateKey, SecureRandom random) throws InvalidKeyException { if (!(privateKey instanceof RSAPrivateKey)) { throw new InvalidKeyException("Supplied key is not a RSAPrivateKey instance"); } sigParams = new ParametersWithRandom(RSAUtil.generatePrivateKeyParameter((RSAPrivateKey)privateKey), random); if (isRaw) { bOut = new ByteArrayOutputStream(); } else { pss = new org.bouncycastle.crypto.signers.PSSSigner(signer, contentDigest, mgfDigest, saltLength); pss.init(true, sigParams); } } protected void engineInitSign( PrivateKey privateKey) throws InvalidKeyException { if (!(privateKey instanceof RSAPrivateKey)) { throw new InvalidKeyException("Supplied key is not a RSAPrivateKey instance"); } sigParams = RSAUtil.generatePrivateKeyParameter((RSAPrivateKey)privateKey); if (isRaw) { bOut = new ByteArrayOutputStream(); } else { pss = new org.bouncycastle.crypto.signers.PSSSigner(signer, contentDigest, mgfDigest, saltLength); pss.init(true, sigParams); } } protected void engineUpdate( byte b) throws SignatureException { if (isRaw) { bOut.write(b); } else { pss.update(b); } } protected void engineUpdate( byte[] b, int off, int len) throws SignatureException { if (isRaw) { bOut.write(b, off, len); } else { pss.update(b, off, len); } } protected byte[] engineSign() throws SignatureException { try { if (isRaw) { byte[] hash = bOut.toByteArray(); contentDigest = mgfDigest = guessDigest(hash.length); saltLength = contentDigest.getDigestSize(); pss = new org.bouncycastle.crypto.signers.PSSSigner(signer, new NullPssDigest(contentDigest), mgfDigest, saltLength); pss.init(true, sigParams); } return pss.generateSignature(); } catch (CryptoException e) { throw new SignatureException(e.getMessage()); } } protected boolean engineVerify( byte[] sigBytes) throws SignatureException { if (isRaw) { byte[] hash = bOut.toByteArray(); contentDigest = mgfDigest = guessDigest(hash.length); saltLength = contentDigest.getDigestSize(); pss = new org.bouncycastle.crypto.signers.PSSSigner(signer, new NullPssDigest(contentDigest), mgfDigest, saltLength); pss.init(false, sigParams); pss.update(hash, 0, hash.length); } return pss.verifySignature(sigBytes); } protected void engineSetParameter( AlgorithmParameterSpec params) throws InvalidParameterException { throw new InvalidParameterException("Only PSSParameterSpec supported"); } protected AlgorithmParameters engineGetParameters() { return engineParams; } /** * @deprecated replaced with
*/ protected void engineSetParameter( String param, Object value) { throw new UnsupportedOperationException("engineSetParameter unsupported"); } protected Object engineGetParameter( String param) { throw new UnsupportedOperationException("engineGetParameter unsupported"); } private Digest guessDigest(int size) { switch (size) { case 20: return new SHA1Digest(); case 28: return new SHA224Digest(); case 32: return new SHA256Digest(); case 48: return new SHA384Digest(); case 64: return new SHA512Digest(); } return null; } static public class nonePSS extends PSSSignatureSpi { public nonePSS() { super("NONEwithRSAandMGF1", new RSABlindedEngine(), null, true); } } static public class PSSwithRSA extends PSSSignatureSpi { public PSSwithRSA() { super("SHA1withRSAandMGF1", new RSABlindedEngine(), null); } } static public class SHA1withRSA extends PSSSignatureSpi { public SHA1withRSA() { super("SHA1withRSAandMGF1", new RSABlindedEngine(), new SHA1Digest()); } } static public class SHA224withRSA extends PSSSignatureSpi { public SHA224withRSA() { super("SHA224withRSAandMGF1", new RSABlindedEngine(), new SHA224Digest()); } } static public class SHA256withRSA extends PSSSignatureSpi { public SHA256withRSA() { super("SHA256withRSAandMGF1", new RSABlindedEngine(), new SHA256Digest()); } } static public class SHA384withRSA extends PSSSignatureSpi { public SHA384withRSA() { super("SHA384withRSAandMGF1", new RSABlindedEngine(), new SHA384Digest()); } } static public class SHA512withRSA extends PSSSignatureSpi { public SHA512withRSA() { super("SHA512withRSAandMGF1", new RSABlindedEngine(), new SHA512Digest()); } } private class NullPssDigest implements Digest { private ByteArrayOutputStream bOut = new ByteArrayOutputStream(); private Digest baseDigest; private boolean oddTime = true; public NullPssDigest(Digest mgfDigest) { this.baseDigest = mgfDigest; } public String getAlgorithmName() { return "NULL"; } public int getDigestSize() { return baseDigest.getDigestSize(); } public void update(byte in) { bOut.write(in); } public void update(byte[] in, int inOff, int len) { bOut.write(in, inOff, len); } public int doFinal(byte[] out, int outOff) { byte[] res = bOut.toByteArray(); if (oddTime) { System.arraycopy(res, 0, out, outOff, res.length); } else { baseDigest.update(res, 0, res.length); baseDigest.doFinal(out, outOff); } reset(); oddTime = !oddTime; return res.length; } public void reset() { bOut.reset(); baseDigest.reset(); } public int getByteLength() { return 0; } } } bouncycastle-1.49.orig/jdk1.3/org/bouncycastle/jcajce/provider/asymmetric/x509/0000755000175000017500000000000012152033550026634 5ustar ebourgebourgbouncycastle-1.49.orig/jdk1.3/org/bouncycastle/jcajce/provider/asymmetric/x509/X509CRLObject.java0000644000175000017500000004133612132664306031652 0ustar ebourgebourgpackage org.bouncycastle.jcajce.provider.asymmetric.x509; import java.io.IOException; import java.math.BigInteger; import java.security.InvalidKeyException; import java.security.NoSuchAlgorithmException; import java.security.NoSuchProviderException; import java.security.Principal; import java.security.PublicKey; import java.security.Signature; import java.security.SignatureException; import java.security.cert.CRLException; import java.security.cert.Certificate; import java.security.cert.CertificateEncodingException; import java.security.cert.X509CRL; import java.security.cert.X509CRLEntry; import java.security.cert.X509Certificate; import java.util.Collections; import java.util.Date; import java.util.Enumeration; import java.util.HashSet; import java.util.Iterator; import java.util.Set; import org.bouncycastle.asn1.ASN1Encodable; import org.bouncycastle.asn1.ASN1Encoding; import org.bouncycastle.asn1.ASN1InputStream; import org.bouncycastle.asn1.ASN1ObjectIdentifier; import org.bouncycastle.asn1.DERInteger; import org.bouncycastle.asn1.util.ASN1Dump; import org.bouncycastle.asn1.x500.X500Name; import org.bouncycastle.asn1.x509.CRLDistPoint; import org.bouncycastle.asn1.x509.CRLNumber; import org.bouncycastle.asn1.x509.CertificateList; import org.bouncycastle.asn1.x509.Extension; import org.bouncycastle.asn1.x509.Extensions; import org.bouncycastle.asn1.x509.GeneralNames; import org.bouncycastle.asn1.x509.IssuingDistributionPoint; import org.bouncycastle.asn1.x509.TBSCertList; import org.bouncycastle.jce.X509Principal; import org.bouncycastle.jce.provider.RFC3280CertPathUtilities; import org.bouncycastle.jce.provider.BouncyCastleProvider; import org.bouncycastle.util.encoders.Hex; import org.bouncycastle.x509.extension.X509ExtensionUtil; /** * The following extensions are listed in RFC 2459 as relevant to CRLs * * Authority Key Identifier * Issuer Alternative Name * CRL Number * Delta CRL Indicator (critical) * Issuing Distribution Point (critical) */ class X509CRLObject extends X509CRL { private CertificateList c; private String sigAlgName; private byte[] sigAlgParams; private boolean isIndirect; static boolean isIndirectCRL(X509CRL crl) throws CRLException { try { byte[] idp = crl.getExtensionValue(Extension.issuingDistributionPoint.getId()); return idp != null && IssuingDistributionPoint.getInstance(X509ExtensionUtil.fromExtensionValue(idp)).isIndirectCRL(); } catch (Exception e) { throw new ExtCRLException( "Exception reading IssuingDistributionPoint", e); } } public X509CRLObject( CertificateList c) throws CRLException { this.c = c; try { this.sigAlgName = X509SignatureUtil.getSignatureName(c.getSignatureAlgorithm()); if (c.getSignatureAlgorithm().getParameters() != null) { this.sigAlgParams = ((ASN1Encodable)c.getSignatureAlgorithm().getParameters()).toASN1Primitive().getEncoded(ASN1Encoding.DER); } else { this.sigAlgParams = null; } this.isIndirect = isIndirectCRL(this); } catch (Exception e) { throw new CRLException("CRL contents invalid: " + e); } } /** * Will return true if any extensions are present and marked * as critical as we currently dont handle any extensions! */ public boolean hasUnsupportedCriticalExtension() { Set extns = getCriticalExtensionOIDs(); if (extns == null) { return false; } extns.remove(RFC3280CertPathUtilities.ISSUING_DISTRIBUTION_POINT); extns.remove(RFC3280CertPathUtilities.DELTA_CRL_INDICATOR); return !extns.isEmpty(); } private Set getExtensionOIDs(boolean critical) { if (this.getVersion() == 2) { Extensions extensions = c.getTBSCertList().getExtensions(); if (extensions != null) { Set set = new HashSet(); Enumeration e = extensions.oids(); while (e.hasMoreElements()) { ASN1ObjectIdentifier oid = (ASN1ObjectIdentifier)e.nextElement(); Extension ext = extensions.getExtension(oid); if (critical == ext.isCritical()) { set.add(oid.getId()); } } return set; } } return null; } public Set getCriticalExtensionOIDs() { return getExtensionOIDs(true); } public Set getNonCriticalExtensionOIDs() { return getExtensionOIDs(false); } public byte[] getExtensionValue(String oid) { Extensions exts = c.getTBSCertList().getExtensions(); if (exts != null) { Extension ext = exts.getExtension(new ASN1ObjectIdentifier(oid)); if (ext != null) { try { return ext.getExtnValue().getEncoded(); } catch (Exception e) { throw new IllegalStateException("error parsing " + e.toString()); } } } return null; } public byte[] getEncoded() throws CRLException { try { return c.getEncoded(ASN1Encoding.DER); } catch (IOException e) { throw new CRLException(e.toString()); } } public void verify(PublicKey key) throws CRLException, NoSuchAlgorithmException, InvalidKeyException, NoSuchProviderException, SignatureException { verify(key, BouncyCastleProvider.PROVIDER_NAME); } public void verify(PublicKey key, String sigProvider) throws CRLException, NoSuchAlgorithmException, InvalidKeyException, NoSuchProviderException, SignatureException { if (!c.getSignatureAlgorithm().equals(c.getTBSCertList().getSignature())) { throw new CRLException("Signature algorithm on CertificateList does not match TBSCertList."); } Signature sig; if (sigProvider != null) { sig = Signature.getInstance(getSigAlgName(), sigProvider); } else { sig = Signature.getInstance(getSigAlgName()); } sig.initVerify(key); sig.update(this.getTBSCertList()); if (!sig.verify(this.getSignature())) { throw new SignatureException("CRL does not verify with supplied public key."); } } public int getVersion() { return c.getVersionNumber(); } public Principal getIssuerDN() { return new X509Principal(X500Name.getInstance(c.getIssuer().toASN1Primitive())); } public Date getThisUpdate() { return c.getThisUpdate().getDate(); } public Date getNextUpdate() { if (c.getNextUpdate() != null) { return c.getNextUpdate().getDate(); } return null; } private Set loadCRLEntries() { Set entrySet = new HashSet(); Enumeration certs = c.getRevokedCertificateEnumeration(); X500Name previousCertificateIssuer = c.getIssuer(); while (certs.hasMoreElements()) { TBSCertList.CRLEntry entry = (TBSCertList.CRLEntry)certs.nextElement(); X509CRLEntryObject crlEntry = new X509CRLEntryObject(entry, isIndirect, previousCertificateIssuer); entrySet.add(crlEntry); if (isIndirect && entry.hasExtensions()) { Extension currentCaName = entry.getExtensions().getExtension(Extension.certificateIssuer); if (currentCaName != null) { previousCertificateIssuer = X500Name.getInstance(GeneralNames.getInstance(currentCaName.getParsedValue()).getNames()[0].getName()); } } } return entrySet; } public X509CRLEntry getRevokedCertificate(BigInteger serialNumber) { Enumeration certs = c.getRevokedCertificateEnumeration(); X500Name previousCertificateIssuer = c.getIssuer(); while (certs.hasMoreElements()) { TBSCertList.CRLEntry entry = (TBSCertList.CRLEntry)certs.nextElement(); if (serialNumber.equals(entry.getUserCertificate().getValue())) { return new X509CRLEntryObject(entry, isIndirect, previousCertificateIssuer); } if (isIndirect && entry.hasExtensions()) { Extension currentCaName = entry.getExtensions().getExtension(Extension.certificateIssuer); if (currentCaName != null) { previousCertificateIssuer = X500Name.getInstance(GeneralNames.getInstance(currentCaName.getParsedValue()).getNames()[0].getName()); } } } return null; } public Set getRevokedCertificates() { Set entrySet = loadCRLEntries(); if (!entrySet.isEmpty()) { return Collections.unmodifiableSet(entrySet); } return null; } public byte[] getTBSCertList() throws CRLException { try { return c.getTBSCertList().getEncoded("DER"); } catch (IOException e) { throw new CRLException(e.toString()); } } public byte[] getSignature() { return c.getSignature().getBytes(); } public String getSigAlgName() { return sigAlgName; } public String getSigAlgOID() { return c.getSignatureAlgorithm().getAlgorithm().getId(); } public byte[] getSigAlgParams() { if (sigAlgParams != null) { byte[] tmp = new byte[sigAlgParams.length]; System.arraycopy(sigAlgParams, 0, tmp, 0, tmp.length); return tmp; } return null; } /** * Returns a string representation of this CRL. * * @return a string representation of this CRL. */ public String toString() { StringBuffer buf = new StringBuffer(); String nl = System.getProperty("line.separator"); buf.append(" Version: ").append(this.getVersion()).append( nl); buf.append(" IssuerDN: ").append(this.getIssuerDN()) .append(nl); buf.append(" This update: ").append(this.getThisUpdate()) .append(nl); buf.append(" Next update: ").append(this.getNextUpdate()) .append(nl); buf.append(" Signature Algorithm: ").append(this.getSigAlgName()) .append(nl); byte[] sig = this.getSignature(); buf.append(" Signature: ").append( new String(Hex.encode(sig, 0, 20))).append(nl); for (int i = 20; i < sig.length; i += 20) { if (i < sig.length - 20) { buf.append(" ").append( new String(Hex.encode(sig, i, 20))).append(nl); } else { buf.append(" ").append( new String(Hex.encode(sig, i, sig.length - i))).append(nl); } } Extensions extensions = c.getTBSCertList().getExtensions(); if (extensions != null) { Enumeration e = extensions.oids(); if (e.hasMoreElements()) { buf.append(" Extensions: ").append(nl); } while (e.hasMoreElements()) { ASN1ObjectIdentifier oid = (ASN1ObjectIdentifier) e.nextElement(); Extension ext = extensions.getExtension(oid); if (ext.getExtnValue() != null) { byte[] octs = ext.getExtnValue().getOctets(); ASN1InputStream dIn = new ASN1InputStream(octs); buf.append(" critical(").append( ext.isCritical()).append(") "); try { if (oid.equals(Extension.cRLNumber)) { buf.append( new CRLNumber(DERInteger.getInstance( dIn.readObject()).getPositiveValue())) .append(nl); } else if (oid.equals(Extension.deltaCRLIndicator)) { buf.append( "Base CRL: " + new CRLNumber(DERInteger.getInstance( dIn.readObject()).getPositiveValue())) .append(nl); } else if (oid .equals(Extension.issuingDistributionPoint)) { buf.append( IssuingDistributionPoint.getInstance(dIn.readObject())).append(nl); } else if (oid .equals(Extension.cRLDistributionPoints)) { buf.append( CRLDistPoint.getInstance(dIn.readObject())).append(nl); } else if (oid.equals(Extension.freshestCRL)) { buf.append( CRLDistPoint.getInstance(dIn.readObject())).append(nl); } else { buf.append(oid.getId()); buf.append(" value = ").append( ASN1Dump.dumpAsString(dIn.readObject())) .append(nl); } } catch (Exception ex) { buf.append(oid.getId()); buf.append(" value = ").append("*****").append(nl); } } else { buf.append(nl); } } } Set set = getRevokedCertificates(); if (set != null) { Iterator it = set.iterator(); while (it.hasNext()) { buf.append(it.next()); buf.append(nl); } } return buf.toString(); } /** * Checks whether the given certificate is on this CRL. * * @param cert the certificate to check for. * @return true if the given certificate is on this CRL, * false otherwise. */ public boolean isRevoked(Certificate cert) { if (!cert.getType().equals("X.509")) { throw new RuntimeException("X.509 CRL used with non X.509 Cert"); } TBSCertList.CRLEntry[] certs = c.getRevokedCertificates(); X500Name caName = c.getIssuer(); if (certs != null) { BigInteger serial = ((X509Certificate)cert).getSerialNumber(); for (int i = 0; i < certs.length; i++) { if (isIndirect && certs[i].hasExtensions()) { Extension currentCaName = certs[i].getExtensions().getExtension(Extension.certificateIssuer); if (currentCaName != null) { caName = X500Name.getInstance(GeneralNames.getInstance(currentCaName.getParsedValue()).getNames()[0].getName()); } } if (certs[i].getUserCertificate().getValue().equals(serial)) { X500Name issuer; try { issuer = org.bouncycastle.asn1.x509.Certificate.getInstance(cert.getEncoded()).getIssuer(); } catch (CertificateEncodingException e) { throw new RuntimeException("Cannot process certificate"); } if (!caName.equals(issuer)) { return false; } return true; } } } return false; } } ././@LongLink0000000000000000000000000000014700000000000011567 Lustar rootrootbouncycastle-1.49.orig/jdk1.3/org/bouncycastle/jcajce/provider/asymmetric/x509/CertificateFactory.javabouncycastle-1.49.orig/jdk1.3/org/bouncycastle/jcajce/provider/asymmetric/x509/CertificateFactory.ja0000644000175000017500000002547012132656275032747 0ustar ebourgebourgpackage org.bouncycastle.jcajce.provider.asymmetric.x509; import java.io.IOException; import java.io.InputStream; import java.io.PushbackInputStream; import java.security.cert.CRL; import java.security.cert.CRLException; import org.bouncycastle.jce.cert.CertPath; import java.security.cert.CertificateException; import org.bouncycastle.jce.cert.CertificateFactorySpi; import java.security.cert.CertificateParsingException; import java.security.cert.X509Certificate; import java.util.ArrayList; import java.util.Collection; import java.util.Iterator; import java.util.List; import org.bouncycastle.asn1.ASN1InputStream; import org.bouncycastle.asn1.ASN1ObjectIdentifier; import org.bouncycastle.asn1.ASN1Sequence; import org.bouncycastle.asn1.ASN1Set; import org.bouncycastle.asn1.ASN1TaggedObject; import org.bouncycastle.asn1.pkcs.PKCSObjectIdentifiers; import org.bouncycastle.asn1.pkcs.SignedData; import org.bouncycastle.asn1.x509.Certificate; import org.bouncycastle.asn1.x509.CertificateList; import org.bouncycastle.jce.provider.X509CRLObject; import org.bouncycastle.jce.provider.X509CertificateObject; /** * class for dealing with X509 certificates. *

* At the moment this will deal with "-----BEGIN CERTIFICATE-----" to "-----END CERTIFICATE-----" * base 64 encoded certs, as well as the BER binaries of certificates and some classes of PKCS#7 * objects. */ public class CertificateFactory extends CertificateFactorySpi { private static final PEMUtil PEM_CERT_PARSER = new PEMUtil("CERTIFICATE"); private static final PEMUtil PEM_CRL_PARSER = new PEMUtil("CRL"); private ASN1Set sData = null; private int sDataObjectCount = 0; private InputStream currentStream = null; private ASN1Set sCrlData = null; private int sCrlDataObjectCount = 0; private InputStream currentCrlStream = null; private java.security.cert.Certificate readDERCertificate( ASN1InputStream dIn) throws IOException, CertificateParsingException { ASN1Sequence seq = (ASN1Sequence)dIn.readObject(); if (seq.size() > 1 && seq.getObjectAt(0) instanceof ASN1ObjectIdentifier) { if (seq.getObjectAt(0).equals(PKCSObjectIdentifiers.signedData)) { sData = SignedData.getInstance(ASN1Sequence.getInstance( (ASN1TaggedObject)seq.getObjectAt(1), true)).getCertificates(); return getCertificate(); } } return new X509CertificateObject( Certificate.getInstance(seq)); } private java.security.cert.Certificate getCertificate() throws CertificateParsingException { if (sData != null) { while (sDataObjectCount < sData.size()) { Object obj = sData.getObjectAt(sDataObjectCount++); if (obj instanceof ASN1Sequence) { return new X509CertificateObject( Certificate.getInstance(obj)); } } } return null; } private java.security.cert.Certificate readPEMCertificate( InputStream in) throws IOException, CertificateParsingException { ASN1Sequence seq = PEM_CERT_PARSER.readPEMObject(in); if (seq != null) { return new X509CertificateObject( Certificate.getInstance(seq)); } return null; } protected CRL createCRL(CertificateList c) throws CRLException { return new X509CRLObject(c); } private CRL readPEMCRL( InputStream in) throws IOException, CRLException { ASN1Sequence seq = PEM_CRL_PARSER.readPEMObject(in); if (seq != null) { return createCRL( CertificateList.getInstance(seq)); } return null; } private CRL readDERCRL( ASN1InputStream aIn) throws IOException, CRLException { ASN1Sequence seq = (ASN1Sequence)aIn.readObject(); if (seq.size() > 1 && seq.getObjectAt(0) instanceof ASN1ObjectIdentifier) { if (seq.getObjectAt(0).equals(PKCSObjectIdentifiers.signedData)) { sCrlData = SignedData.getInstance(ASN1Sequence.getInstance( (ASN1TaggedObject)seq.getObjectAt(1), true)).getCRLs(); return getCRL(); } } return createCRL( CertificateList.getInstance(seq)); } private CRL getCRL() throws CRLException { if (sCrlData == null || sCrlDataObjectCount >= sCrlData.size()) { return null; } return createCRL( CertificateList.getInstance( sCrlData.getObjectAt(sCrlDataObjectCount++))); } /** * Generates a certificate object and initializes it with the data * read from the input stream inStream. */ public java.security.cert.Certificate engineGenerateCertificate( InputStream in) throws CertificateException { if (currentStream == null) { currentStream = in; sData = null; sDataObjectCount = 0; } else if (currentStream != in) // reset if input stream has changed { currentStream = in; sData = null; sDataObjectCount = 0; } try { if (sData != null) { if (sDataObjectCount != sData.size()) { return getCertificate(); } else { sData = null; sDataObjectCount = 0; return null; } } PushbackInputStream pis = new PushbackInputStream(in); int tag = pis.read(); if (tag == -1) { return null; } pis.unread(tag); if (tag != 0x30) // assume ascii PEM encoded. { return readPEMCertificate(pis); } else { return readDERCertificate(new ASN1InputStream(pis)); } } catch (Exception e) { throw new ExCertificateException(e); } } /** * Returns a (possibly empty) collection view of the certificates * read from the given input stream inStream. */ public Collection engineGenerateCertificates( InputStream inStream) throws CertificateException { java.security.cert.Certificate cert; List certs = new ArrayList(); while ((cert = engineGenerateCertificate(inStream)) != null) { certs.add(cert); } return certs; } /** * Generates a certificate revocation list (CRL) object and initializes * it with the data read from the input stream inStream. */ public CRL engineGenerateCRL( InputStream inStream) throws CRLException { if (currentCrlStream == null) { currentCrlStream = inStream; sCrlData = null; sCrlDataObjectCount = 0; } else if (currentCrlStream != inStream) // reset if input stream has changed { currentCrlStream = inStream; sCrlData = null; sCrlDataObjectCount = 0; } try { if (sCrlData != null) { if (sCrlDataObjectCount != sCrlData.size()) { return getCRL(); } else { sCrlData = null; sCrlDataObjectCount = 0; return null; } } PushbackInputStream pis = new PushbackInputStream(inStream); int tag = pis.read(); if (tag == -1) { return null; } pis.unread(tag); if (tag != 0x30) // assume ascii PEM encoded. { return readPEMCRL(pis); } else { // lazy evaluate to help processing of large CRLs return readDERCRL(new ASN1InputStream(pis, true)); } } catch (CRLException e) { throw e; } catch (Exception e) { throw new CRLException(e.toString()); } } /** * Returns a (possibly empty) collection view of the CRLs read from * the given input stream inStream. * * The inStream may contain a sequence of DER-encoded CRLs, or * a PKCS#7 CRL set. This is a PKCS#7 SignedData object, with the * only signficant field being crls. In particular the signature * and the contents are ignored. */ public Collection engineGenerateCRLs( InputStream inStream) throws CRLException { CRL crl; List crls = new ArrayList(); while ((crl = engineGenerateCRL(inStream)) != null) { crls.add(crl); } return crls; } public Iterator engineGetCertPathEncodings() { return null; // TODO: PKIXCertPath.certPathEncodings.iterator(); } public CertPath engineGenerateCertPath( InputStream inStream) throws CertificateException { return engineGenerateCertPath(inStream, "PkiPath"); } public CertPath engineGenerateCertPath( InputStream inStream, String encoding) throws CertificateException { return new PKIXCertPath(inStream, encoding); } public CertPath engineGenerateCertPath( List certificates) throws CertificateException { Iterator iter = certificates.iterator(); Object obj; while (iter.hasNext()) { obj = iter.next(); if (obj != null) { if (!(obj instanceof X509Certificate)) { throw new CertificateException("list contains non X509Certificate object while creating CertPath\n" + obj.toString()); } } } return new PKIXCertPath(certificates); } private class ExCertificateException extends CertificateException { private Throwable cause; public ExCertificateException(Throwable cause) { this.cause = cause; } public ExCertificateException(String msg, Throwable cause) { super(msg); this.cause = cause; } public Throwable getCause() { return cause; } } } bouncycastle-1.49.orig/jdk1.3/org/bouncycastle/jcajce/provider/asymmetric/x509/SignatureUtil.java0000644000175000017500000001077211702724207032313 0ustar ebourgebourgpackage org.bouncycastle.jcajce.provider.asymmetric.x509; import java.io.IOException; import java.security.AlgorithmParameters; import java.security.GeneralSecurityException; import java.security.InvalidKeyException; import java.security.NoSuchAlgorithmException; import java.security.NoSuchProviderException; import java.security.Signature; import java.security.SignatureException; import org.bouncycastle.asn1.ASN1Encodable; import org.bouncycastle.asn1.ASN1Encoding; import org.bouncycastle.asn1.ASN1Null; import org.bouncycastle.asn1.ASN1ObjectIdentifier; import org.bouncycastle.asn1.ASN1Sequence; import org.bouncycastle.asn1.DERNull; import org.bouncycastle.asn1.cryptopro.CryptoProObjectIdentifiers; import org.bouncycastle.asn1.nist.NISTObjectIdentifiers; import org.bouncycastle.asn1.oiw.OIWObjectIdentifiers; import org.bouncycastle.asn1.pkcs.PKCSObjectIdentifiers; import org.bouncycastle.asn1.pkcs.RSASSAPSSparams; import org.bouncycastle.asn1.teletrust.TeleTrusTObjectIdentifiers; import org.bouncycastle.asn1.x509.AlgorithmIdentifier; import org.bouncycastle.asn1.x9.X9ObjectIdentifiers; class SignatureUtil { private static final ASN1Null derNull = new DERNull(); static void setSignatureParameters( Signature signature, ASN1Encodable params) throws NoSuchAlgorithmException, SignatureException, InvalidKeyException { if (params != null && !derNull.equals(params.toASN1Primitive())) { try { AlgorithmParameters sigParams = AlgorithmParameters.getInstance(signature.getAlgorithm(), signature.getProvider().getName()); try { sigParams.init(params.toASN1Primitive().getEncoded(ASN1Encoding.DER)); } catch (IOException e) { throw new SignatureException("IOException decoding parameters: " + e.getMessage()); } } catch (NoSuchProviderException e) { throw new SignatureException("cannot find provider: " + e.getMessage()); } } } static String getSignatureName( AlgorithmIdentifier sigAlgId) { ASN1Encodable params = sigAlgId.getParameters(); if (params != null && !derNull.equals(params)) { if (sigAlgId.getAlgorithm().equals(PKCSObjectIdentifiers.id_RSASSA_PSS)) { RSASSAPSSparams rsaParams = RSASSAPSSparams.getInstance(params); return getDigestAlgName(rsaParams.getHashAlgorithm().getAlgorithm()) + "withRSAandMGF1"; } if (sigAlgId.getAlgorithm().equals(X9ObjectIdentifiers.ecdsa_with_SHA2)) { ASN1Sequence ecDsaParams = ASN1Sequence.getInstance(params); return getDigestAlgName((ASN1ObjectIdentifier)ecDsaParams.getObjectAt(0)) + "withECDSA"; } } return sigAlgId.getAlgorithm().getId(); } /** * Return the digest algorithm using one of the standard JCA string * representations rather the the algorithm identifier (if possible). */ private static String getDigestAlgName( ASN1ObjectIdentifier digestAlgOID) { if (PKCSObjectIdentifiers.md5.equals(digestAlgOID)) { return "MD5"; } else if (OIWObjectIdentifiers.idSHA1.equals(digestAlgOID)) { return "SHA1"; } else if (NISTObjectIdentifiers.id_sha224.equals(digestAlgOID)) { return "SHA224"; } else if (NISTObjectIdentifiers.id_sha256.equals(digestAlgOID)) { return "SHA256"; } else if (NISTObjectIdentifiers.id_sha384.equals(digestAlgOID)) { return "SHA384"; } else if (NISTObjectIdentifiers.id_sha512.equals(digestAlgOID)) { return "SHA512"; } else if (TeleTrusTObjectIdentifiers.ripemd128.equals(digestAlgOID)) { return "RIPEMD128"; } else if (TeleTrusTObjectIdentifiers.ripemd160.equals(digestAlgOID)) { return "RIPEMD160"; } else if (TeleTrusTObjectIdentifiers.ripemd256.equals(digestAlgOID)) { return "RIPEMD256"; } else if (CryptoProObjectIdentifiers.gostR3411.equals(digestAlgOID)) { return "GOST3411"; } else { return digestAlgOID.getId(); } } } bouncycastle-1.49.orig/jdk1.3/org/bouncycastle/jcajce/provider/asymmetric/x509/PKIXCertPath.java0000644000175000017500000002772011730543346031727 0ustar ebourgebourgpackage org.bouncycastle.jcajce.provider.asymmetric.x509; import java.io.BufferedInputStream; import java.io.ByteArrayInputStream; import java.io.ByteArrayOutputStream; import java.io.IOException; import java.io.InputStream; import java.io.OutputStreamWriter; import java.security.NoSuchProviderException; import org.bouncycastle.jce.cert.CertPath; import java.security.cert.Certificate; import java.security.cert.CertificateEncodingException; import java.security.cert.CertificateException; import java.security.cert.CertificateFactory; import java.security.cert.X509Certificate; import java.util.ArrayList; import java.util.Collections; import java.util.Enumeration; import java.util.Iterator; import java.util.List; import java.util.ListIterator; import org.bouncycastle.jce.X509Principal; import org.bouncycastle.jce.PrincipalUtil; import org.bouncycastle.asn1.ASN1Encodable; import org.bouncycastle.asn1.ASN1EncodableVector; import org.bouncycastle.asn1.ASN1Encoding; import org.bouncycastle.asn1.ASN1InputStream; import org.bouncycastle.asn1.ASN1Integer; import org.bouncycastle.asn1.ASN1Primitive; import org.bouncycastle.asn1.ASN1Sequence; import org.bouncycastle.asn1.DERSequence; import org.bouncycastle.asn1.DERSet; import org.bouncycastle.asn1.pkcs.ContentInfo; import org.bouncycastle.asn1.pkcs.PKCSObjectIdentifiers; import org.bouncycastle.asn1.pkcs.SignedData; import org.bouncycastle.jce.provider.BouncyCastleProvider; import org.bouncycastle.util.io.pem.PemObject; import org.bouncycastle.util.io.pem.PemWriter; /** * CertPath implementation for X.509 certificates. *
**/ public class PKIXCertPath extends CertPath { static final List certPathEncodings; static { List encodings = new ArrayList(); encodings.add("PkiPath"); encodings.add("PEM"); encodings.add("PKCS7"); certPathEncodings = Collections.unmodifiableList(encodings); } private List certificates; /** * @param certs */ private List sortCerts( List certs) { try { if (certs.size() < 2) { return certs; } X509Principal issuer = PrincipalUtil.getIssuerX509Principal(((X509Certificate)certs.get(0))); boolean okay = true; for (int i = 1; i != certs.size(); i++) { X509Certificate cert = (X509Certificate)certs.get(i); if (issuer.equals(PrincipalUtil.getSubjectX509Principal(cert))) { issuer = PrincipalUtil.getIssuerX509Principal(((X509Certificate)certs.get(i))); } else { okay = false; break; } } if (okay) { return certs; } // find end-entity cert List retList = new ArrayList(certs.size()); List orig = new ArrayList(certs); for (int i = 0; i < certs.size(); i++) { X509Certificate cert = (X509Certificate)certs.get(i); boolean found = false; X509Principal subject = PrincipalUtil.getSubjectX509Principal(cert); for (int j = 0; j != certs.size(); j++) { X509Certificate c = (X509Certificate)certs.get(j); if (PrincipalUtil.getIssuerX509Principal(c).equals(subject)) { found = true; break; } } if (!found) { retList.add(cert); certs.remove(i); } } // can only have one end entity cert - something's wrong, give up. if (retList.size() > 1) { return orig; } for (int i = 0; i != retList.size(); i++) { issuer = PrincipalUtil.getIssuerX509Principal(((X509Certificate)retList.get(i))); for (int j = 0; j < certs.size(); j++) { X509Certificate c = (X509Certificate)certs.get(j); if (issuer.equals(PrincipalUtil.getSubjectX509Principal(c))) { retList.add(c); certs.remove(j); break; } } } // make sure all certificates are accounted for. if (certs.size() > 0) { return orig; } return retList; } catch (Exception e) { return certs; } } PKIXCertPath(List certificates) { super("X.509"); this.certificates = sortCerts(new ArrayList(certificates)); } /** * Creates a CertPath of the specified type. * This constructor is protected because most users should use * a CertificateFactory to create CertPaths. **/ PKIXCertPath( InputStream inStream, String encoding) throws CertificateException { super("X.509"); try { if (encoding.equalsIgnoreCase("PkiPath")) { ASN1InputStream derInStream = new ASN1InputStream(inStream); ASN1Primitive derObject = derInStream.readObject(); if (!(derObject instanceof ASN1Sequence)) { throw new CertificateException("input stream does not contain a ASN1 SEQUENCE while reading PkiPath encoded data to load CertPath"); } Enumeration e = ((ASN1Sequence)derObject).getObjects(); certificates = new ArrayList(); CertificateFactory certFactory = CertificateFactory.getInstance("X.509", BouncyCastleProvider.PROVIDER_NAME); while (e.hasMoreElements()) { ASN1Encodable element = (ASN1Encodable)e.nextElement(); byte[] encoded = element.toASN1Primitive().getEncoded(ASN1Encoding.DER); certificates.add(0, certFactory.generateCertificate( new ByteArrayInputStream(encoded))); } } else if (encoding.equalsIgnoreCase("PKCS7") || encoding.equalsIgnoreCase("PEM")) { inStream = new BufferedInputStream(inStream); certificates = new ArrayList(); CertificateFactory certFactory= CertificateFactory.getInstance("X.509", BouncyCastleProvider.PROVIDER_NAME); Certificate cert; while ((cert = certFactory.generateCertificate(inStream)) != null) { certificates.add(cert); } } else { throw new CertificateException("unsupported encoding: " + encoding); } } catch (IOException ex) { throw new CertificateException("IOException throw while decoding CertPath:\n" + ex.toString()); } catch (NoSuchProviderException ex) { throw new CertificateException("BouncyCastle provider not found while trying to get a CertificateFactory:\n" + ex.toString()); } this.certificates = sortCerts(certificates); } /** * Returns an iteration of the encodings supported by this * certification path, with the default encoding * first. Attempts to modify the returned Iterator via its * remove method result in an UnsupportedOperationException. * * @return an Iterator over the names of the supported encodings (as Strings) **/ public Iterator getEncodings() { return certPathEncodings.iterator(); } /** * Returns the encoded form of this certification path, using * the default encoding. * * @return the encoded bytes * @exception java.security.cert.CertificateEncodingException if an encoding error occurs **/ public byte[] getEncoded() throws CertificateEncodingException { Iterator iter = getEncodings(); if (iter.hasNext()) { Object enc = iter.next(); if (enc instanceof String) { return getEncoded((String)enc); } } return null; } /** * Returns the encoded form of this certification path, using * the specified encoding. * * @param encoding the name of the encoding to use * @return the encoded bytes * @exception java.security.cert.CertificateEncodingException if an encoding error * occurs or the encoding requested is not supported * **/ public byte[] getEncoded(String encoding) throws CertificateEncodingException { if (encoding.equalsIgnoreCase("PkiPath")) { ASN1EncodableVector v = new ASN1EncodableVector(); ListIterator iter = certificates.listIterator(certificates.size()); while (iter.hasPrevious()) { v.add(toASN1Object((X509Certificate)iter.previous())); } return toDEREncoded(new DERSequence(v)); } else if (encoding.equalsIgnoreCase("PKCS7")) { ContentInfo encInfo = new ContentInfo(PKCSObjectIdentifiers.data, null); ASN1EncodableVector v = new ASN1EncodableVector(); for (int i = 0; i != certificates.size(); i++) { v.add(toASN1Object((X509Certificate)certificates.get(i))); } SignedData sd = new SignedData( new ASN1Integer(1), new DERSet(), encInfo, new DERSet(v), null, new DERSet()); return toDEREncoded(new ContentInfo( PKCSObjectIdentifiers.signedData, sd)); } else if (encoding.equalsIgnoreCase("PEM")) { ByteArrayOutputStream bOut = new ByteArrayOutputStream(); PemWriter pWrt = new PemWriter(new OutputStreamWriter(bOut)); try { for (int i = 0; i != certificates.size(); i++) { pWrt.writeObject(new PemObject("CERTIFICATE", ((X509Certificate)certificates.get(i)).getEncoded())); } pWrt.close(); } catch (Exception e) { throw new CertificateEncodingException("can't encode certificate for PEM encoded path"); } return bOut.toByteArray(); } else { throw new CertificateEncodingException("unsupported encoding: " + encoding); } } /** * Returns the list of certificates in this certification * path. The List returned must be immutable and thread-safe. * * @return an immutable List of Certificates (may be empty, but not null) **/ public List getCertificates() { return Collections.unmodifiableList(new ArrayList(certificates)); } /** * Return a DERObject containing the encoded certificate. * * @param cert the X509Certificate object to be encoded * * @return the DERObject **/ private ASN1Primitive toASN1Object( X509Certificate cert) throws CertificateEncodingException { try { return new ASN1InputStream(cert.getEncoded()).readObject(); } catch (Exception e) { throw new CertificateEncodingException("Exception while encoding certificate: " + e.toString()); } } private byte[] toDEREncoded(ASN1Encodable obj) throws CertificateEncodingException { try { return obj.toASN1Primitive().getEncoded(ASN1Encoding.DER); } catch (IOException e) { throw new CertificateEncodingException("Exception thrown: " + e); } } } ././@LongLink0000000000000000000000000000015200000000000011563 Lustar rootrootbouncycastle-1.49.orig/jdk1.3/org/bouncycastle/jcajce/provider/asymmetric/x509/X509CertificateObject.javabouncycastle-1.49.orig/jdk1.3/org/bouncycastle/jcajce/provider/asymmetric/x509/X509CertificateObject0000644000175000017500000006370512132664306032540 0ustar ebourgebourgpackage org.bouncycastle.jcajce.provider.asymmetric.x509; import java.io.ByteArrayOutputStream; import java.io.IOException; import java.math.BigInteger; import java.net.InetAddress; import java.net.UnknownHostException; import java.security.InvalidKeyException; import java.security.NoSuchAlgorithmException; import java.security.NoSuchProviderException; import java.security.Principal; import java.security.Provider; import java.security.PublicKey; import java.security.Security; import java.security.Signature; import java.security.SignatureException; import java.security.cert.Certificate; import java.security.cert.CertificateEncodingException; import java.security.cert.CertificateException; import java.security.cert.CertificateExpiredException; import java.security.cert.CertificateNotYetValidException; import java.security.cert.CertificateParsingException; import java.security.cert.X509Certificate; import java.util.ArrayList; import java.util.Collection; import java.util.Collections; import java.util.Date; import java.util.Enumeration; import java.util.HashSet; import java.util.List; import java.util.Set; import org.bouncycastle.asn1.ASN1Encodable; import org.bouncycastle.asn1.ASN1Encoding; import org.bouncycastle.asn1.ASN1InputStream; import org.bouncycastle.asn1.ASN1ObjectIdentifier; import org.bouncycastle.asn1.ASN1OutputStream; import org.bouncycastle.asn1.ASN1Primitive; import org.bouncycastle.asn1.ASN1Sequence; import org.bouncycastle.asn1.ASN1String; import org.bouncycastle.asn1.DERBitString; import org.bouncycastle.asn1.DERIA5String; import org.bouncycastle.asn1.DERNull; import org.bouncycastle.asn1.DEROctetString; import org.bouncycastle.asn1.misc.MiscObjectIdentifiers; import org.bouncycastle.asn1.misc.NetscapeCertType; import org.bouncycastle.asn1.misc.NetscapeRevocationURL; import org.bouncycastle.asn1.misc.VerisignCzagExtension; import org.bouncycastle.asn1.util.ASN1Dump; import org.bouncycastle.asn1.x500.X500Name; import org.bouncycastle.asn1.x500.style.RFC4519Style; import org.bouncycastle.asn1.x509.AlgorithmIdentifier; import org.bouncycastle.asn1.x509.BasicConstraints; import org.bouncycastle.asn1.x509.Extension; import org.bouncycastle.asn1.x509.Extensions; import org.bouncycastle.asn1.x509.GeneralName; import org.bouncycastle.asn1.x509.KeyUsage; import org.bouncycastle.jcajce.provider.asymmetric.util.PKCS12BagAttributeCarrierImpl; import org.bouncycastle.jce.X509Principal; import org.bouncycastle.jce.provider.RFC3280CertPathUtilities; import org.bouncycastle.jce.provider.BouncyCastleProvider; import org.bouncycastle.jce.interfaces.PKCS12BagAttributeCarrier; import org.bouncycastle.util.Arrays; import org.bouncycastle.util.Integers; import org.bouncycastle.util.encoders.Hex; class X509CertificateObject extends X509Certificate implements PKCS12BagAttributeCarrier { private org.bouncycastle.asn1.x509.Certificate c; private BasicConstraints basicConstraints; private boolean[] keyUsage; private boolean hashValueSet; private int hashValue; private PKCS12BagAttributeCarrier attrCarrier = new PKCS12BagAttributeCarrierImpl(); public X509CertificateObject( org.bouncycastle.asn1.x509.Certificate c) throws CertificateParsingException { this.c = c; try { byte[] bytes = this.getExtensionBytes("2.5.29.19"); if (bytes != null) { basicConstraints = BasicConstraints.getInstance(ASN1Primitive.fromByteArray(bytes)); } } catch (Exception e) { throw new CertificateParsingException("cannot construct BasicConstraints: " + e); } try { byte[] bytes = this.getExtensionBytes("2.5.29.15"); if (bytes != null) { DERBitString bits = DERBitString.getInstance(ASN1Primitive.fromByteArray(bytes)); bytes = bits.getBytes(); int length = (bytes.length * 8) - bits.getPadBits(); keyUsage = new boolean[(length < 9) ? 9 : length]; for (int i = 0; i != length; i++) { keyUsage[i] = (bytes[i / 8] & (0x80 >>> (i % 8))) != 0; } } else { keyUsage = null; } } catch (Exception e) { throw new CertificateParsingException("cannot construct KeyUsage: " + e); } } public void checkValidity() throws CertificateExpiredException, CertificateNotYetValidException { this.checkValidity(new Date()); } public void checkValidity( Date date) throws CertificateExpiredException, CertificateNotYetValidException { if (date.getTime() > this.getNotAfter().getTime()) // for other VM compatibility { throw new CertificateExpiredException("certificate expired on " + c.getEndDate().getTime()); } if (date.getTime() < this.getNotBefore().getTime()) { throw new CertificateNotYetValidException("certificate not valid till " + c.getStartDate().getTime()); } } public int getVersion() { return c.getVersionNumber(); } public BigInteger getSerialNumber() { return c.getSerialNumber().getValue(); } public Principal getIssuerDN() { try { return new X509Principal(X500Name.getInstance(c.getIssuer().getEncoded())); } catch (IOException e) { return null; } } public Principal getSubjectDN() { return new X509Principal(X500Name.getInstance(c.getSubject().toASN1Primitive())); } public Date getNotBefore() { return c.getStartDate().getDate(); } public Date getNotAfter() { return c.getEndDate().getDate(); } public byte[] getTBSCertificate() throws CertificateEncodingException { try { return c.getTBSCertificate().getEncoded(ASN1Encoding.DER); } catch (IOException e) { throw new CertificateEncodingException(e.toString()); } } public byte[] getSignature() { return c.getSignature().getBytes(); } /** * return a more "meaningful" representation for the signature algorithm used in * the certficate. */ public String getSigAlgName() { Provider prov = Security.getProvider(BouncyCastleProvider.PROVIDER_NAME); if (prov != null) { String algName = prov.getProperty("Alg.Alias.Signature." + this.getSigAlgOID()); if (algName != null) { return algName; } } Provider[] provs = Security.getProviders(); // // search every provider looking for a real algorithm // for (int i = 0; i != provs.length; i++) { String algName = provs[i].getProperty("Alg.Alias.Signature." + this.getSigAlgOID()); if (algName != null) { return algName; } } return this.getSigAlgOID(); } /** * return the object identifier for the signature. */ public String getSigAlgOID() { return c.getSignatureAlgorithm().getAlgorithm().getId(); } /** * return the signature parameters, or null if there aren't any. */ public byte[] getSigAlgParams() { if (c.getSignatureAlgorithm().getParameters() != null) { try { return c.getSignatureAlgorithm().getParameters().toASN1Primitive().getEncoded(ASN1Encoding.DER); } catch (IOException e) { return null; } } else { return null; } } public boolean[] getIssuerUniqueID() { DERBitString id = c.getTBSCertificate().getIssuerUniqueId(); if (id != null) { byte[] bytes = id.getBytes(); boolean[] boolId = new boolean[bytes.length * 8 - id.getPadBits()]; for (int i = 0; i != boolId.length; i++) { boolId[i] = (bytes[i / 8] & (0x80 >>> (i % 8))) != 0; } return boolId; } return null; } public boolean[] getSubjectUniqueID() { DERBitString id = c.getTBSCertificate().getSubjectUniqueId(); if (id != null) { byte[] bytes = id.getBytes(); boolean[] boolId = new boolean[bytes.length * 8 - id.getPadBits()]; for (int i = 0; i != boolId.length; i++) { boolId[i] = (bytes[i / 8] & (0x80 >>> (i % 8))) != 0; } return boolId; } return null; } public boolean[] getKeyUsage() { return keyUsage; } public List getExtendedKeyUsage() throws CertificateParsingException { byte[] bytes = this.getExtensionBytes("2.5.29.37"); if (bytes != null) { try { ASN1InputStream dIn = new ASN1InputStream(bytes); ASN1Sequence seq = (ASN1Sequence)dIn.readObject(); List list = new ArrayList(); for (int i = 0; i != seq.size(); i++) { list.add(((ASN1ObjectIdentifier)seq.getObjectAt(i)).getId()); } return Collections.unmodifiableList(list); } catch (Exception e) { throw new CertificateParsingException("error processing extended key usage extension"); } } return null; } public int getBasicConstraints() { if (basicConstraints != null) { if (basicConstraints.isCA()) { if (basicConstraints.getPathLenConstraint() == null) { return Integer.MAX_VALUE; } else { return basicConstraints.getPathLenConstraint().intValue(); } } else { return -1; } } return -1; } public Collection getSubjectAlternativeNames() throws CertificateParsingException { return getAlternativeNames(getExtensionBytes(Extension.subjectAlternativeName.getId())); } public Collection getIssuerAlternativeNames() throws CertificateParsingException { return getAlternativeNames(getExtensionBytes(Extension.issuerAlternativeName.getId())); } public Set getCriticalExtensionOIDs() { if (this.getVersion() == 3) { Set set = new HashSet(); Extensions extensions = c.getTBSCertificate().getExtensions(); if (extensions != null) { Enumeration e = extensions.oids(); while (e.hasMoreElements()) { ASN1ObjectIdentifier oid = (ASN1ObjectIdentifier)e.nextElement(); Extension ext = extensions.getExtension(oid); if (ext.isCritical()) { set.add(oid.getId()); } } return set; } } return null; } private byte[] getExtensionBytes(String oid) { Extensions exts = c.getTBSCertificate().getExtensions(); if (exts != null) { Extension ext = exts.getExtension(new ASN1ObjectIdentifier(oid)); if (ext != null) { return ext.getExtnValue().getOctets(); } } return null; } public byte[] getExtensionValue(String oid) { Extensions exts = c.getTBSCertificate().getExtensions(); if (exts != null) { Extension ext = exts.getExtension(new ASN1ObjectIdentifier(oid)); if (ext != null) { try { return ext.getExtnValue().getEncoded(); } catch (Exception e) { throw new IllegalStateException("error parsing " + e.toString()); } } } return null; } public Set getNonCriticalExtensionOIDs() { if (this.getVersion() == 3) { Set set = new HashSet(); Extensions extensions = c.getTBSCertificate().getExtensions(); if (extensions != null) { Enumeration e = extensions.oids(); while (e.hasMoreElements()) { ASN1ObjectIdentifier oid = (ASN1ObjectIdentifier)e.nextElement(); Extension ext = extensions.getExtension(oid); if (!ext.isCritical()) { set.add(oid.getId()); } } return set; } } return null; } public boolean hasUnsupportedCriticalExtension() { if (this.getVersion() == 3) { Extensions extensions = c.getTBSCertificate().getExtensions(); if (extensions != null) { Enumeration e = extensions.oids(); while (e.hasMoreElements()) { ASN1ObjectIdentifier oid = (ASN1ObjectIdentifier)e.nextElement(); String oidId = oid.getId(); if (oidId.equals(RFC3280CertPathUtilities.KEY_USAGE) || oidId.equals(RFC3280CertPathUtilities.CERTIFICATE_POLICIES) || oidId.equals(RFC3280CertPathUtilities.POLICY_MAPPINGS) || oidId.equals(RFC3280CertPathUtilities.INHIBIT_ANY_POLICY) || oidId.equals(RFC3280CertPathUtilities.CRL_DISTRIBUTION_POINTS) || oidId.equals(RFC3280CertPathUtilities.ISSUING_DISTRIBUTION_POINT) || oidId.equals(RFC3280CertPathUtilities.DELTA_CRL_INDICATOR) || oidId.equals(RFC3280CertPathUtilities.POLICY_CONSTRAINTS) || oidId.equals(RFC3280CertPathUtilities.BASIC_CONSTRAINTS) || oidId.equals(RFC3280CertPathUtilities.SUBJECT_ALTERNATIVE_NAME) || oidId.equals(RFC3280CertPathUtilities.NAME_CONSTRAINTS)) { continue; } Extension ext = extensions.getExtension(oid); if (ext.isCritical()) { return true; } } } } return false; } public PublicKey getPublicKey() { try { return BouncyCastleProvider.getPublicKey(c.getSubjectPublicKeyInfo()); } catch (IOException e) { return null; // should never happen... } } public byte[] getEncoded() throws CertificateEncodingException { try { return c.getEncoded(ASN1Encoding.DER); } catch (IOException e) { throw new CertificateEncodingException(e.toString()); } } public boolean equals( Object o) { if (o == this) { return true; } if (!(o instanceof Certificate)) { return false; } Certificate other = (Certificate)o; try { byte[] b1 = this.getEncoded(); byte[] b2 = other.getEncoded(); return Arrays.areEqual(b1, b2); } catch (CertificateEncodingException e) { return false; } } public synchronized int hashCode() { if (!hashValueSet) { hashValue = calculateHashCode(); hashValueSet = true; } return hashValue; } private int calculateHashCode() { try { int hashCode = 0; byte[] certData = this.getEncoded(); for (int i = 1; i < certData.length; i++) { hashCode += certData[i] * i; } return hashCode; } catch (CertificateEncodingException e) { return 0; } } public void setBagAttribute( ASN1ObjectIdentifier oid, ASN1Encodable attribute) { attrCarrier.setBagAttribute(oid, attribute); } public ASN1Encodable getBagAttribute( ASN1ObjectIdentifier oid) { return attrCarrier.getBagAttribute(oid); } public Enumeration getBagAttributeKeys() { return attrCarrier.getBagAttributeKeys(); } public String toString() { StringBuffer buf = new StringBuffer(); String nl = System.getProperty("line.separator"); buf.append(" [0] Version: ").append(this.getVersion()).append(nl); buf.append(" SerialNumber: ").append(this.getSerialNumber()).append(nl); buf.append(" IssuerDN: ").append(this.getIssuerDN()).append(nl); buf.append(" Start Date: ").append(this.getNotBefore()).append(nl); buf.append(" Final Date: ").append(this.getNotAfter()).append(nl); buf.append(" SubjectDN: ").append(this.getSubjectDN()).append(nl); buf.append(" Public Key: ").append(this.getPublicKey()).append(nl); buf.append(" Signature Algorithm: ").append(this.getSigAlgName()).append(nl); byte[] sig = this.getSignature(); buf.append(" Signature: ").append(new String(Hex.encode(sig, 0, 20))).append(nl); for (int i = 20; i < sig.length; i += 20) { if (i < sig.length - 20) { buf.append(" ").append(new String(Hex.encode(sig, i, 20))).append(nl); } else { buf.append(" ").append(new String(Hex.encode(sig, i, sig.length - i))).append(nl); } } Extensions extensions = c.getTBSCertificate().getExtensions(); if (extensions != null) { Enumeration e = extensions.oids(); if (e.hasMoreElements()) { buf.append(" Extensions: \n"); } while (e.hasMoreElements()) { ASN1ObjectIdentifier oid = (ASN1ObjectIdentifier)e.nextElement(); Extension ext = extensions.getExtension(oid); if (ext.getExtnValue() != null) { byte[] octs = ext.getExtnValue().getOctets(); ASN1InputStream dIn = new ASN1InputStream(octs); buf.append(" critical(").append(ext.isCritical()).append(") "); try { if (oid.equals(Extension.basicConstraints)) { buf.append(BasicConstraints.getInstance(dIn.readObject())).append(nl); } else if (oid.equals(Extension.keyUsage)) { buf.append(KeyUsage.getInstance(dIn.readObject())).append(nl); } else if (oid.equals(MiscObjectIdentifiers.netscapeCertType)) { buf.append(new NetscapeCertType((DERBitString)dIn.readObject())).append(nl); } else if (oid.equals(MiscObjectIdentifiers.netscapeRevocationURL)) { buf.append(new NetscapeRevocationURL((DERIA5String)dIn.readObject())).append(nl); } else if (oid.equals(MiscObjectIdentifiers.verisignCzagExtension)) { buf.append(new VerisignCzagExtension((DERIA5String)dIn.readObject())).append(nl); } else { buf.append(oid.getId()); buf.append(" value = ").append(ASN1Dump.dumpAsString(dIn.readObject())).append(nl); //buf.append(" value = ").append("*****").append(nl); } } catch (Exception ex) { buf.append(oid.getId()); // buf.append(" value = ").append(new String(Hex.encode(ext.getExtnValue().getOctets()))).append(nl); buf.append(" value = ").append("*****").append(nl); } } else { buf.append(nl); } } } return buf.toString(); } public final void verify( PublicKey key) throws CertificateException, NoSuchAlgorithmException, InvalidKeyException, NoSuchProviderException, SignatureException { Signature signature; String sigName = X509SignatureUtil.getSignatureName(c.getSignatureAlgorithm()); try { signature = Signature.getInstance(sigName, BouncyCastleProvider.PROVIDER_NAME); } catch (Exception e) { signature = Signature.getInstance(sigName); } checkSignature(key, signature); } public final void verify( PublicKey key, String sigProvider) throws CertificateException, NoSuchAlgorithmException, InvalidKeyException, NoSuchProviderException, SignatureException { String sigName = X509SignatureUtil.getSignatureName(c.getSignatureAlgorithm()); Signature signature = Signature.getInstance(sigName, sigProvider); checkSignature(key, signature); } private void checkSignature( PublicKey key, Signature signature) throws CertificateException, NoSuchAlgorithmException, SignatureException, InvalidKeyException { if (!isAlgIdEqual(c.getSignatureAlgorithm(), c.getTBSCertificate().getSignature())) { throw new CertificateException("signature algorithm in TBS cert not same as outer cert"); } ASN1Encodable params = c.getSignatureAlgorithm().getParameters(); // TODO This should go after the initVerify? X509SignatureUtil.setSignatureParameters(signature, params); signature.initVerify(key); signature.update(this.getTBSCertificate()); if (!signature.verify(this.getSignature())) { throw new SignatureException("certificate does not verify with supplied key"); } } private boolean isAlgIdEqual(AlgorithmIdentifier id1, AlgorithmIdentifier id2) { if (!id1.getAlgorithm().equals(id2.getAlgorithm())) { return false; } if (id1.getParameters() == null) { if (id2.getParameters() != null && !id2.getParameters().equals(DERNull.INSTANCE)) { return false; } return true; } if (id2.getParameters() == null) { if (id1.getParameters() != null && !id1.getParameters().equals(DERNull.INSTANCE)) { return false; } return true; } return id1.getParameters().equals(id2.getParameters()); } private static Collection getAlternativeNames(byte[] extVal) throws CertificateParsingException { if (extVal == null) { return null; } try { Collection temp = new ArrayList(); Enumeration it = ASN1Sequence.getInstance(extVal).getObjects(); while (it.hasMoreElements()) { GeneralName genName = GeneralName.getInstance(it.nextElement()); List list = new ArrayList(); list.add(Integers.valueOf(genName.getTagNo())); switch (genName.getTagNo()) { case GeneralName.ediPartyName: case GeneralName.x400Address: case GeneralName.otherName: list.add(genName.getEncoded()); break; case GeneralName.directoryName: list.add(X500Name.getInstance(RFC4519Style.INSTANCE, genName.getName()).toString()); break; case GeneralName.dNSName: case GeneralName.rfc822Name: case GeneralName.uniformResourceIdentifier: list.add(((ASN1String)genName.getName()).getString()); break; case GeneralName.registeredID: list.add(ASN1ObjectIdentifier.getInstance(genName.getName()).getId()); break; case GeneralName.iPAddress: byte[] addrBytes = DEROctetString.getInstance(genName.getName()).getOctets(); list.add(addrBytes); break; default: throw new IOException("Bad tag number: " + genName.getTagNo()); } temp.add(list); } if (temp.size() == 0) { return null; } return Collections.unmodifiableCollection(temp); } catch (Exception e) { throw new CertificateParsingException(e.getMessage()); } } } ././@LongLink0000000000000000000000000000014600000000000011566 Lustar rootrootbouncycastle-1.49.orig/jdk1.3/org/bouncycastle/jcajce/provider/asymmetric/x509/X509SignatureUtil.javabouncycastle-1.49.orig/jdk1.3/org/bouncycastle/jcajce/provider/asymmetric/x509/X509SignatureUtil.jav0000644000175000017500000000776712147323462032554 0ustar ebourgebourgpackage org.bouncycastle.jcajce.provider.asymmetric.x509; import java.security.InvalidKeyException; import java.security.NoSuchAlgorithmException; import java.security.Signature; import java.security.SignatureException; import org.bouncycastle.asn1.ASN1Encodable; import org.bouncycastle.asn1.ASN1Null; import org.bouncycastle.asn1.DERNull; import org.bouncycastle.asn1.DERObjectIdentifier; import org.bouncycastle.asn1.cryptopro.CryptoProObjectIdentifiers; import org.bouncycastle.asn1.nist.NISTObjectIdentifiers; import org.bouncycastle.asn1.oiw.OIWObjectIdentifiers; import org.bouncycastle.asn1.pkcs.PKCSObjectIdentifiers; import org.bouncycastle.asn1.pkcs.RSASSAPSSparams; import org.bouncycastle.asn1.teletrust.TeleTrusTObjectIdentifiers; import org.bouncycastle.asn1.x509.AlgorithmIdentifier; class X509SignatureUtil { private static final ASN1Null derNull = new DERNull(); static void setSignatureParameters( Signature signature, ASN1Encodable params) throws NoSuchAlgorithmException, SignatureException, InvalidKeyException { if (params != null && !derNull.equals(params)) { /* AlgorithmParameters sigParams = AlgorithmParameters.getInstance(signature.getAlgorithm(), signature.getProvider()); try { sigParams.init(params.getDERObject().getDEREncoded()); } catch (IOException e) { throw new SignatureException("IOException decoding parameters: " + e.getMessage()); } try { signature.setParameters(sigParams.getParameterSpec(PSSParameterSpec.class)); } catch (GeneralSecurityException e) { throw new SignatureException("Exception extracting parameters: " + e.getMessage()); } */ } } static String getSignatureName( AlgorithmIdentifier sigAlgId) { ASN1Encodable params = sigAlgId.getParameters(); if (params != null && !derNull.equals(params)) { if (sigAlgId.getObjectId().equals(PKCSObjectIdentifiers.id_RSASSA_PSS)) { RSASSAPSSparams rsaParams = RSASSAPSSparams.getInstance(params); return getDigestAlgName(rsaParams.getHashAlgorithm().getObjectId()) + "withRSAandMGF1"; } } return sigAlgId.getObjectId().getId(); } /** * Return the digest algorithm using one of the standard JCA string * representations rather the the algorithm identifier (if possible). */ private static String getDigestAlgName( DERObjectIdentifier digestAlgOID) { if (PKCSObjectIdentifiers.md5.equals(digestAlgOID)) { return "MD5"; } else if (OIWObjectIdentifiers.idSHA1.equals(digestAlgOID)) { return "SHA1"; } else if (NISTObjectIdentifiers.id_sha224.equals(digestAlgOID)) { return "SHA224"; } else if (NISTObjectIdentifiers.id_sha256.equals(digestAlgOID)) { return "SHA256"; } else if (NISTObjectIdentifiers.id_sha384.equals(digestAlgOID)) { return "SHA384"; } else if (NISTObjectIdentifiers.id_sha512.equals(digestAlgOID)) { return "SHA512"; } else if (TeleTrusTObjectIdentifiers.ripemd128.equals(digestAlgOID)) { return "RIPEMD128"; } else if (TeleTrusTObjectIdentifiers.ripemd160.equals(digestAlgOID)) { return "RIPEMD160"; } else if (TeleTrusTObjectIdentifiers.ripemd256.equals(digestAlgOID)) { return "RIPEMD256"; } else if (CryptoProObjectIdentifiers.gostR3411.equals(digestAlgOID)) { return "GOST3411"; } else { return digestAlgOID.getId(); } } } ././@LongLink0000000000000000000000000000014700000000000011567 Lustar rootrootbouncycastle-1.49.orig/jdk1.3/org/bouncycastle/jcajce/provider/asymmetric/x509/X509CRLEntryObject.javabouncycastle-1.49.orig/jdk1.3/org/bouncycastle/jcajce/provider/asymmetric/x509/X509CRLEntryObject.ja0000644000175000017500000002113112132664306032334 0ustar ebourgebourgpackage org.bouncycastle.jcajce.provider.asymmetric.x509; import java.io.IOException; import java.math.BigInteger; import java.security.cert.CRLException; import java.security.cert.X509CRLEntry; import java.util.Date; import java.util.Enumeration; import java.util.HashSet; import java.util.Set; import org.bouncycastle.asn1.ASN1Encoding; import org.bouncycastle.asn1.ASN1InputStream; import org.bouncycastle.asn1.ASN1ObjectIdentifier; import org.bouncycastle.asn1.DEREnumerated; import org.bouncycastle.asn1.util.ASN1Dump; import org.bouncycastle.asn1.x500.X500Name; import org.bouncycastle.asn1.x509.CRLReason; import org.bouncycastle.asn1.x509.Extension; import org.bouncycastle.asn1.x509.Extensions; import org.bouncycastle.asn1.x509.GeneralName; import org.bouncycastle.asn1.x509.GeneralNames; import org.bouncycastle.asn1.x509.TBSCertList; import org.bouncycastle.asn1.x509.X509Extension; import org.bouncycastle.x509.extension.X509ExtensionUtil; import org.bouncycastle.jce.X509Principal; /** * The following extensions are listed in RFC 2459 as relevant to CRL Entries * * ReasonCode Hode Instruction Code Invalidity Date Certificate Issuer * (critical) */ class X509CRLEntryObject extends X509CRLEntry { private TBSCertList.CRLEntry c; private X500Name certificateIssuer; private int hashValue; private boolean isHashValueSet; public X509CRLEntryObject(TBSCertList.CRLEntry c) { this.c = c; this.certificateIssuer = null; } /** * Constructor for CRLEntries of indirect CRLs. If isIndirect * is false {@link #getCertificateIssuer()} will always * return null, previousCertificateIssuer is * ignored. If this isIndirect is specified and this CRLEntry * has no certificate issuer CRL entry extension * previousCertificateIssuer is returned by * {@link #getCertificateIssuer()}. * * @param c * TBSCertList.CRLEntry object. * @param isIndirect * true if the corresponding CRL is a indirect * CRL. * @param previousCertificateIssuer * Certificate issuer of the previous CRLEntry. */ public X509CRLEntryObject( TBSCertList.CRLEntry c, boolean isIndirect, X500Name previousCertificateIssuer) { this.c = c; this.certificateIssuer = loadCertificateIssuer(isIndirect, previousCertificateIssuer); } /** * Will return true if any extensions are present and marked as critical as * we currently don't handle any extensions! */ public boolean hasUnsupportedCriticalExtension() { Set extns = getCriticalExtensionOIDs(); return extns != null && !extns.isEmpty(); } private X500Name loadCertificateIssuer(boolean isIndirect, X500Name previousCertificateIssuer) { if (!isIndirect) { return null; } byte[] ext = getExtensionValue(X509Extension.certificateIssuer.getId()); if (ext == null) { return previousCertificateIssuer; } try { GeneralName[] names = GeneralNames.getInstance( X509ExtensionUtil.fromExtensionValue(ext)).getNames(); for (int i = 0; i < names.length; i++) { if (names[i].getTagNo() == GeneralName.directoryName) { return X500Name.getInstance(names[i].getName()); } } return null; } catch (IOException e) { return null; } } X509Principal getCertificateIssuer() { if (certificateIssuer == null) { return null; } try { return new X509Principal(certificateIssuer.getEncoded()); } catch (Exception e) { throw new IllegalStateException(e.toString()); } } private Set getExtensionOIDs(boolean critical) { Extensions extensions = c.getExtensions(); if (extensions != null) { Set set = new HashSet(); Enumeration e = extensions.oids(); while (e.hasMoreElements()) { ASN1ObjectIdentifier oid = (ASN1ObjectIdentifier) e.nextElement(); Extension ext = extensions.getExtension(oid); if (critical == ext.isCritical()) { set.add(oid.getId()); } } return set; } return null; } public Set getCriticalExtensionOIDs() { return getExtensionOIDs(true); } public Set getNonCriticalExtensionOIDs() { return getExtensionOIDs(false); } public byte[] getExtensionValue(String oid) { Extensions exts = c.getExtensions(); if (exts != null) { Extension ext = exts.getExtension(new ASN1ObjectIdentifier(oid)); if (ext != null) { try { return ext.getExtnValue().getEncoded(); } catch (Exception e) { throw new RuntimeException("error encoding " + e.toString()); } } } return null; } /** * Cache the hashCode value - calculating it with the standard method. * @return calculated hashCode. */ public int hashCode() { if (!isHashValueSet) { hashValue = super.hashCode(); isHashValueSet = true; } return hashValue; } public byte[] getEncoded() throws CRLException { try { return c.getEncoded(ASN1Encoding.DER); } catch (IOException e) { throw new CRLException(e.toString()); } } public BigInteger getSerialNumber() { return c.getUserCertificate().getValue(); } public Date getRevocationDate() { return c.getRevocationDate().getDate(); } public boolean hasExtensions() { return c.getExtensions() != null; } public String toString() { StringBuffer buf = new StringBuffer(); String nl = System.getProperty("line.separator"); buf.append(" userCertificate: ").append(this.getSerialNumber()).append(nl); buf.append(" revocationDate: ").append(this.getRevocationDate()).append(nl); Extensions extensions = c.getExtensions(); if (extensions != null) { Enumeration e = extensions.oids(); if (e.hasMoreElements()) { buf.append(" crlEntryExtensions:").append(nl); while (e.hasMoreElements()) { ASN1ObjectIdentifier oid = (ASN1ObjectIdentifier)e.nextElement(); Extension ext = extensions.getExtension(oid); if (ext.getExtnValue() != null) { byte[] octs = ext.getExtnValue().getOctets(); ASN1InputStream dIn = new ASN1InputStream(octs); buf.append(" critical(").append(ext.isCritical()).append(") "); try { if (oid.equals(X509Extension.reasonCode)) { buf.append(CRLReason.getInstance(DEREnumerated.getInstance(dIn.readObject()))).append(nl); } else if (oid.equals(X509Extension.certificateIssuer)) { buf.append("Certificate issuer: ").append(GeneralNames.getInstance(dIn.readObject())).append(nl); } else { buf.append(oid.getId()); buf.append(" value = ").append(ASN1Dump.dumpAsString(dIn.readObject())).append(nl); } } catch (Exception ex) { buf.append(oid.getId()); buf.append(" value = ").append("*****").append(nl); } } else { buf.append(nl); } } } } return buf.toString(); } } bouncycastle-1.49.orig/jdk1.3/org/bouncycastle/jcajce/provider/keystore/0000755000175000017500000000000012152033550025617 5ustar ebourgebourgbouncycastle-1.49.orig/jdk1.3/org/bouncycastle/jcajce/provider/keystore/pkcs12/0000755000175000017500000000000012152033550026722 5ustar ebourgebourg././@LongLink0000000000000000000000000000014600000000000011566 Lustar rootrootbouncycastle-1.49.orig/jdk1.3/org/bouncycastle/jcajce/provider/keystore/pkcs12/PKCS12KeyStoreSpi.javabouncycastle-1.49.orig/jdk1.3/org/bouncycastle/jcajce/provider/keystore/pkcs12/PKCS12KeyStoreSpi.jav0000644000175000017500000015563412147323462032517 0ustar ebourgebourgpackage org.bouncycastle.jcajce.provider.keystore.pkcs12; import java.io.BufferedInputStream; import java.io.ByteArrayInputStream; import java.io.ByteArrayOutputStream; import java.io.IOException; import java.io.InputStream; import java.io.OutputStream; import java.security.Key; import java.security.KeyStore; import java.security.KeyStoreException; import java.security.KeyStoreSpi; import java.security.NoSuchAlgorithmException; import java.security.Principal; import java.security.PrivateKey; import java.security.Provider; import java.security.PublicKey; import java.security.SecureRandom; import java.security.UnrecoverableKeyException; import java.security.cert.Certificate; import java.security.cert.CertificateEncodingException; import java.security.cert.CertificateException; import java.security.cert.CertificateFactory; import java.security.cert.X509Certificate; import java.util.Date; import java.util.Enumeration; import java.util.Hashtable; import java.util.Vector; import javax.crypto.Cipher; import javax.crypto.Mac; import javax.crypto.SecretKey; import javax.crypto.SecretKeyFactory; import javax.crypto.spec.IvParameterSpec; import javax.crypto.spec.PBEKeySpec; import javax.crypto.spec.PBEParameterSpec; import org.bouncycastle.asn1.ASN1Encodable; import org.bouncycastle.asn1.ASN1EncodableVector; import org.bouncycastle.asn1.ASN1Encoding; import org.bouncycastle.asn1.ASN1InputStream; import org.bouncycastle.asn1.ASN1ObjectIdentifier; import org.bouncycastle.asn1.ASN1OctetString; import org.bouncycastle.asn1.ASN1Primitive; import org.bouncycastle.asn1.ASN1Sequence; import org.bouncycastle.asn1.ASN1Set; import org.bouncycastle.asn1.BEROctetString; import org.bouncycastle.asn1.BEROutputStream; import org.bouncycastle.asn1.DERBMPString; import org.bouncycastle.asn1.DERNull; import org.bouncycastle.asn1.DEROctetString; import org.bouncycastle.asn1.DEROutputStream; import org.bouncycastle.asn1.DERSequence; import org.bouncycastle.asn1.DERSet; import org.bouncycastle.asn1.pkcs.AuthenticatedSafe; import org.bouncycastle.asn1.pkcs.CertBag; import org.bouncycastle.asn1.pkcs.ContentInfo; import org.bouncycastle.asn1.pkcs.EncryptedData; import org.bouncycastle.asn1.pkcs.MacData; import org.bouncycastle.asn1.pkcs.PBES2Parameters; import org.bouncycastle.asn1.pkcs.PBKDF2Params; import org.bouncycastle.asn1.pkcs.PKCS12PBEParams; import org.bouncycastle.asn1.pkcs.PKCSObjectIdentifiers; import org.bouncycastle.asn1.pkcs.Pfx; import org.bouncycastle.asn1.pkcs.SafeBag; import org.bouncycastle.asn1.util.ASN1Dump; import org.bouncycastle.asn1.x509.AlgorithmIdentifier; import org.bouncycastle.asn1.x509.AuthorityKeyIdentifier; import org.bouncycastle.asn1.x509.DigestInfo; import org.bouncycastle.asn1.x509.Extension; import org.bouncycastle.asn1.x509.SubjectKeyIdentifier; import org.bouncycastle.asn1.x509.SubjectPublicKeyInfo; import org.bouncycastle.asn1.x509.X509ObjectIdentifiers; import org.bouncycastle.jcajce.provider.symmetric.util.BCPBEKey; import org.bouncycastle.jcajce.provider.util.SecretKeyUtil; import org.bouncycastle.jce.interfaces.BCKeyStore; import org.bouncycastle.jce.interfaces.PKCS12BagAttributeCarrier; import org.bouncycastle.jce.provider.BouncyCastleProvider; import org.bouncycastle.util.Arrays; import org.bouncycastle.util.Strings; import org.bouncycastle.util.encoders.Hex; public class PKCS12KeyStoreSpi extends KeyStoreSpi implements PKCSObjectIdentifiers, X509ObjectIdentifiers, BCKeyStore { private static final int SALT_SIZE = 20; private static final int MIN_ITERATIONS = 1024; private static final Provider bcProvider = new BouncyCastleProvider(); private IgnoresCaseHashtable keys = new IgnoresCaseHashtable(); private Hashtable localIds = new Hashtable(); private IgnoresCaseHashtable certs = new IgnoresCaseHashtable(); private Hashtable chainCerts = new Hashtable(); private Hashtable keyCerts = new Hashtable(); // // generic object types // static final int NULL = 0; static final int CERTIFICATE = 1; static final int KEY = 2; static final int SECRET = 3; static final int SEALED = 4; // // key types // static final int KEY_PRIVATE = 0; static final int KEY_PUBLIC = 1; static final int KEY_SECRET = 2; protected SecureRandom random = new SecureRandom(); // use of final causes problems with JDK 1.2 compiler private CertificateFactory certFact; private ASN1ObjectIdentifier keyAlgorithm; private ASN1ObjectIdentifier certAlgorithm; private class CertId { byte[] id; CertId( PublicKey key) { this.id = createSubjectKeyId(key).getKeyIdentifier(); } CertId( byte[] id) { this.id = id; } public int hashCode() { return Arrays.hashCode(id); } public boolean equals( Object o) { if (o == this) { return true; } if (!(o instanceof CertId)) { return false; } CertId cId = (CertId)o; return Arrays.areEqual(id, cId.id); } } public PKCS12KeyStoreSpi( Provider provider, ASN1ObjectIdentifier keyAlgorithm, ASN1ObjectIdentifier certAlgorithm) { this.keyAlgorithm = keyAlgorithm; this.certAlgorithm = certAlgorithm; try { if (provider != null) { certFact = CertificateFactory.getInstance("X.509", provider.getName()); } else { certFact = CertificateFactory.getInstance("X.509"); } } catch (Exception e) { throw new IllegalArgumentException("can't create cert factory - " + e.toString()); } } private SubjectKeyIdentifier createSubjectKeyId( PublicKey pubKey) { try { SubjectPublicKeyInfo info = new SubjectPublicKeyInfo( (ASN1Sequence)ASN1Primitive.fromByteArray(pubKey.getEncoded())); return new SubjectKeyIdentifier(info); } catch (Exception e) { throw new RuntimeException("error creating key"); } } public void setRandom( SecureRandom rand) { this.random = rand; } public Enumeration engineAliases() { Hashtable tab = new Hashtable(); Enumeration e = certs.keys(); while (e.hasMoreElements()) { tab.put(e.nextElement(), "cert"); } e = keys.keys(); while (e.hasMoreElements()) { String a = (String)e.nextElement(); if (tab.get(a) == null) { tab.put(a, "key"); } } return tab.keys(); } public boolean engineContainsAlias( String alias) { return (certs.get(alias) != null || keys.get(alias) != null); } /** * this is not quite complete - we should follow up on the chain, a bit * tricky if a certificate appears in more than one chain... */ public void engineDeleteEntry( String alias) throws KeyStoreException { Key k = (Key)keys.remove(alias); Certificate c = (Certificate)certs.remove(alias); if (c != null) { chainCerts.remove(new CertId(c.getPublicKey())); } if (k != null) { String id = (String)localIds.remove(alias); if (id != null) { c = (Certificate)keyCerts.remove(id); } if (c != null) { chainCerts.remove(new CertId(c.getPublicKey())); } } } /** * simply return the cert for the private key */ public Certificate engineGetCertificate( String alias) { if (alias == null) { throw new IllegalArgumentException("null alias passed to getCertificate."); } Certificate c = (Certificate)certs.get(alias); // // look up the key table - and try the local key id // if (c == null) { String id = (String)localIds.get(alias); if (id != null) { c = (Certificate)keyCerts.get(id); } else { c = (Certificate)keyCerts.get(alias); } } return c; } public String engineGetCertificateAlias( Certificate cert) { Enumeration c = certs.elements(); Enumeration k = certs.keys(); while (c.hasMoreElements()) { Certificate tc = (Certificate)c.nextElement(); String ta = (String)k.nextElement(); if (tc.equals(cert)) { return ta; } } c = keyCerts.elements(); k = keyCerts.keys(); while (c.hasMoreElements()) { Certificate tc = (Certificate)c.nextElement(); String ta = (String)k.nextElement(); if (tc.equals(cert)) { return ta; } } return null; } public Certificate[] engineGetCertificateChain( String alias) { if (alias == null) { throw new IllegalArgumentException("null alias passed to getCertificateChain."); } if (!engineIsKeyEntry(alias)) { return null; } Certificate c = engineGetCertificate(alias); if (c != null) { Vector cs = new Vector(); while (c != null) { X509Certificate x509c = (X509Certificate)c; Certificate nextC = null; byte[] bytes = x509c.getExtensionValue(Extension.authorityKeyIdentifier.getId()); if (bytes != null) { try { ASN1InputStream aIn = new ASN1InputStream(bytes); byte[] authBytes = ((ASN1OctetString)aIn.readObject()).getOctets(); aIn = new ASN1InputStream(authBytes); AuthorityKeyIdentifier id = AuthorityKeyIdentifier.getInstance(aIn.readObject()); if (id.getKeyIdentifier() != null) { nextC = (Certificate)chainCerts.get(new CertId(id.getKeyIdentifier())); } } catch (IOException e) { throw new RuntimeException(e.toString()); } } if (nextC == null) { // // no authority key id, try the Issuer DN // Principal i = x509c.getIssuerDN(); Principal s = x509c.getSubjectDN(); if (!i.equals(s)) { Enumeration e = chainCerts.keys(); while (e.hasMoreElements()) { X509Certificate crt = (X509Certificate)chainCerts.get(e.nextElement()); Principal sub = crt.getSubjectDN(); if (sub.equals(i)) { try { x509c.verify(crt.getPublicKey()); nextC = crt; break; } catch (Exception ex) { // continue } } } } } cs.addElement(c); if (nextC != c) // self signed - end of the chain { c = nextC; } else { c = null; } } Certificate[] certChain = new Certificate[cs.size()]; for (int i = 0; i != certChain.length; i++) { certChain[i] = (Certificate)cs.elementAt(i); } return certChain; } return null; } public Date engineGetCreationDate(String alias) { if (alias == null) { throw new NullPointerException("alias == null"); } if (keys.get(alias) == null && certs.get(alias) == null) { return null; } return new Date(); } public Key engineGetKey( String alias, char[] password) throws NoSuchAlgorithmException, UnrecoverableKeyException { if (alias == null) { throw new IllegalArgumentException("null alias passed to getKey."); } return (Key)keys.get(alias); } public boolean engineIsCertificateEntry( String alias) { return (certs.get(alias) != null && keys.get(alias) == null); } public boolean engineIsKeyEntry( String alias) { return (keys.get(alias) != null); } public void engineSetCertificateEntry( String alias, Certificate cert) throws KeyStoreException { if (keys.get(alias) != null) { throw new KeyStoreException("There is a key entry with the name " + alias + "."); } certs.put(alias, cert); chainCerts.put(new CertId(cert.getPublicKey()), cert); } public void engineSetKeyEntry( String alias, byte[] key, Certificate[] chain) throws KeyStoreException { throw new RuntimeException("operation not supported"); } public void engineSetKeyEntry( String alias, Key key, char[] password, Certificate[] chain) throws KeyStoreException { if (!(key instanceof PrivateKey)) { throw new KeyStoreException("PKCS12 does not support non-PrivateKeys"); } if ((key instanceof PrivateKey) && (chain == null)) { throw new KeyStoreException("no certificate chain for private key"); } if (keys.get(alias) != null) { engineDeleteEntry(alias); } keys.put(alias, key); if (chain != null) { certs.put(alias, chain[0]); for (int i = 0; i != chain.length; i++) { chainCerts.put(new CertId(chain[i].getPublicKey()), chain[i]); } } } public int engineSize() { Hashtable tab = new Hashtable(); Enumeration e = certs.keys(); while (e.hasMoreElements()) { tab.put(e.nextElement(), "cert"); } e = keys.keys(); while (e.hasMoreElements()) { String a = (String)e.nextElement(); if (tab.get(a) == null) { tab.put(a, "key"); } } return tab.size(); } protected PrivateKey unwrapKey( AlgorithmIdentifier algId, byte[] data, char[] password, boolean wrongPKCS12Zero) throws IOException { ASN1ObjectIdentifier algorithm = algId.getAlgorithm(); try { if (algorithm.on(PKCSObjectIdentifiers.pkcs_12PbeIds)) { PKCS12PBEParams pbeParams = PKCS12PBEParams.getInstance(algId.getParameters()); PBEKeySpec pbeSpec = new PBEKeySpec(password); PrivateKey out; SecretKeyFactory keyFact = SecretKeyFactory.getInstance( algorithm.getId(), bcProvider); PBEParameterSpec defParams = new PBEParameterSpec( pbeParams.getIV(), pbeParams.getIterations().intValue()); SecretKey k = keyFact.generateSecret(pbeSpec); ((BCPBEKey)k).setTryWrongPKCS12Zero(wrongPKCS12Zero); Cipher cipher = Cipher.getInstance(algorithm.getId(), bcProvider); cipher.init(Cipher.UNWRAP_MODE, k, defParams); // we pass "" as the key algorithm type as it is unknown at this point return (PrivateKey)cipher.unwrap(data, "", Cipher.PRIVATE_KEY); } else if (algorithm.equals(PKCSObjectIdentifiers.id_PBES2)) { PBES2Parameters alg = PBES2Parameters.getInstance(algId.getParameters()); PBKDF2Params func = PBKDF2Params.getInstance(alg.getKeyDerivationFunc().getParameters()); SecretKeyFactory keyFact = SecretKeyFactory.getInstance(alg.getKeyDerivationFunc().getAlgorithm().getId(), bcProvider); SecretKey k = keyFact.generateSecret(new PBEKeySpec(password, func.getSalt(), func.getIterationCount().intValue(), SecretKeyUtil.getKeySize(alg.getEncryptionScheme().getAlgorithm()))); Cipher cipher = Cipher.getInstance(alg.getEncryptionScheme().getAlgorithm().getId(), bcProvider); cipher.init(Cipher.UNWRAP_MODE, k, new IvParameterSpec(ASN1OctetString.getInstance(alg.getEncryptionScheme().getParameters()).getOctets())); // we pass "" as the key algorithm type as it is unknown at this point return (PrivateKey)cipher.unwrap(data, "", Cipher.PRIVATE_KEY); } } catch (Exception e) { throw new IOException("exception unwrapping private key - " + e.toString()); } throw new IOException("exception unwrapping private key - cannot recognise: " + algorithm); } protected byte[] wrapKey( String algorithm, Key key, PKCS12PBEParams pbeParams, char[] password) throws IOException { PBEKeySpec pbeSpec = new PBEKeySpec(password); byte[] out; try { SecretKeyFactory keyFact = SecretKeyFactory.getInstance( algorithm, bcProvider); PBEParameterSpec defParams = new PBEParameterSpec( pbeParams.getIV(), pbeParams.getIterations().intValue()); Cipher cipher = Cipher.getInstance(algorithm, bcProvider); cipher.init(Cipher.WRAP_MODE, keyFact.generateSecret(pbeSpec), defParams); out = cipher.wrap(key); } catch (Exception e) { throw new IOException("exception encrypting data - " + e.toString()); } return out; } protected byte[] cryptData( boolean forEncryption, AlgorithmIdentifier algId, char[] password, boolean wrongPKCS12Zero, byte[] data) throws IOException { String algorithm = algId.getAlgorithm().getId(); PKCS12PBEParams pbeParams = PKCS12PBEParams.getInstance(algId.getParameters()); PBEKeySpec pbeSpec = new PBEKeySpec(password); try { SecretKeyFactory keyFact = SecretKeyFactory.getInstance(algorithm, bcProvider); PBEParameterSpec defParams = new PBEParameterSpec( pbeParams.getIV(), pbeParams.getIterations().intValue()); BCPBEKey key = (BCPBEKey)keyFact.generateSecret(pbeSpec); key.setTryWrongPKCS12Zero(wrongPKCS12Zero); Cipher cipher = Cipher.getInstance(algorithm, bcProvider); int mode = forEncryption ? Cipher.ENCRYPT_MODE : Cipher.DECRYPT_MODE; cipher.init(mode, key, defParams); return cipher.doFinal(data); } catch (Exception e) { throw new IOException("exception decrypting data - " + e.toString()); } } public void engineLoad( InputStream stream, char[] password) throws IOException { if (stream == null) // just initialising { return; } if (password == null) { throw new NullPointerException("No password supplied for PKCS#12 KeyStore."); } BufferedInputStream bufIn = new BufferedInputStream(stream); bufIn.mark(10); int head = bufIn.read(); if (head != 0x30) { throw new IOException("stream does not represent a PKCS12 key store"); } bufIn.reset(); ASN1InputStream bIn = new ASN1InputStream(bufIn); ASN1Sequence obj = (ASN1Sequence)bIn.readObject(); Pfx bag = Pfx.getInstance(obj); ContentInfo info = bag.getAuthSafe(); Vector chain = new Vector(); boolean unmarkedKey = false; boolean wrongPKCS12Zero = false; if (bag.getMacData() != null) // check the mac code { MacData mData = bag.getMacData(); DigestInfo dInfo = mData.getMac(); AlgorithmIdentifier algId = dInfo.getAlgorithmId(); byte[] salt = mData.getSalt(); int itCount = mData.getIterationCount().intValue(); byte[] data = ((ASN1OctetString)info.getContent()).getOctets(); try { byte[] res = calculatePbeMac(algId.getAlgorithm(), salt, itCount, password, false, data); byte[] dig = dInfo.getDigest(); if (!Arrays.constantTimeAreEqual(res, dig)) { if (password.length > 0) { throw new IOException("PKCS12 key store mac invalid - wrong password or corrupted file."); } // Try with incorrect zero length password res = calculatePbeMac(algId.getAlgorithm(), salt, itCount, password, true, data); if (!Arrays.constantTimeAreEqual(res, dig)) { throw new IOException("PKCS12 key store mac invalid - wrong password or corrupted file."); } wrongPKCS12Zero = true; } } catch (IOException e) { throw e; } catch (Exception e) { throw new IOException("error constructing MAC: " + e.toString()); } } keys = new IgnoresCaseHashtable(); localIds = new Hashtable(); if (info.getContentType().equals(data)) { bIn = new ASN1InputStream(((ASN1OctetString)info.getContent()).getOctets()); AuthenticatedSafe authSafe = AuthenticatedSafe.getInstance(bIn.readObject()); ContentInfo[] c = authSafe.getContentInfo(); for (int i = 0; i != c.length; i++) { if (c[i].getContentType().equals(data)) { ASN1InputStream dIn = new ASN1InputStream(((ASN1OctetString)c[i].getContent()).getOctets()); ASN1Sequence seq = (ASN1Sequence)dIn.readObject(); for (int j = 0; j != seq.size(); j++) { SafeBag b = SafeBag.getInstance(seq.getObjectAt(j)); if (b.getBagId().equals(pkcs8ShroudedKeyBag)) { org.bouncycastle.asn1.pkcs.EncryptedPrivateKeyInfo eIn = org.bouncycastle.asn1.pkcs.EncryptedPrivateKeyInfo.getInstance(b.getBagValue()); PrivateKey privKey = unwrapKey(eIn.getEncryptionAlgorithm(), eIn.getEncryptedData(), password, wrongPKCS12Zero); // // set the attributes on the key // PKCS12BagAttributeCarrier bagAttr = (PKCS12BagAttributeCarrier)privKey; String alias = null; ASN1OctetString localId = null; if (b.getBagAttributes() != null) { Enumeration e = b.getBagAttributes().getObjects(); while (e.hasMoreElements()) { ASN1Sequence sq = (ASN1Sequence)e.nextElement(); ASN1ObjectIdentifier aOid = (ASN1ObjectIdentifier)sq.getObjectAt(0); ASN1Set attrSet = (ASN1Set)sq.getObjectAt(1); ASN1Primitive attr = null; if (attrSet.size() > 0) { attr = (ASN1Primitive)attrSet.getObjectAt(0); ASN1Encodable existing = bagAttr.getBagAttribute(aOid); if (existing != null) { // OK, but the value has to be the same if (!existing.toASN1Primitive().equals(attr)) { throw new IOException( "attempt to add existing attribute with different value"); } } else { bagAttr.setBagAttribute(aOid, attr); } } if (aOid.equals(pkcs_9_at_friendlyName)) { alias = ((DERBMPString)attr).getString(); keys.put(alias, privKey); } else if (aOid.equals(pkcs_9_at_localKeyId)) { localId = (ASN1OctetString)attr; } } } if (localId != null) { String name = new String(Hex.encode(localId.getOctets())); if (alias == null) { keys.put(name, privKey); } else { localIds.put(alias, name); } } else { unmarkedKey = true; keys.put("unmarked", privKey); } } else if (b.getBagId().equals(certBag)) { chain.addElement(b); } else { System.out.println("extra in data " + b.getBagId()); System.out.println(ASN1Dump.dumpAsString(b)); } } } else if (c[i].getContentType().equals(encryptedData)) { EncryptedData d = EncryptedData.getInstance(c[i].getContent()); byte[] octets = cryptData(false, d.getEncryptionAlgorithm(), password, wrongPKCS12Zero, d.getContent().getOctets()); ASN1Sequence seq = (ASN1Sequence)ASN1Primitive.fromByteArray(octets); for (int j = 0; j != seq.size(); j++) { SafeBag b = SafeBag.getInstance(seq.getObjectAt(j)); if (b.getBagId().equals(certBag)) { chain.addElement(b); } else if (b.getBagId().equals(pkcs8ShroudedKeyBag)) { org.bouncycastle.asn1.pkcs.EncryptedPrivateKeyInfo eIn = org.bouncycastle.asn1.pkcs.EncryptedPrivateKeyInfo.getInstance(b.getBagValue()); PrivateKey privKey = unwrapKey(eIn.getEncryptionAlgorithm(), eIn.getEncryptedData(), password, wrongPKCS12Zero); // // set the attributes on the key // PKCS12BagAttributeCarrier bagAttr = (PKCS12BagAttributeCarrier)privKey; String alias = null; ASN1OctetString localId = null; Enumeration e = b.getBagAttributes().getObjects(); while (e.hasMoreElements()) { ASN1Sequence sq = (ASN1Sequence)e.nextElement(); ASN1ObjectIdentifier aOid = (ASN1ObjectIdentifier)sq.getObjectAt(0); ASN1Set attrSet = (ASN1Set)sq.getObjectAt(1); ASN1Primitive attr = null; if (attrSet.size() > 0) { attr = (ASN1Primitive)attrSet.getObjectAt(0); ASN1Encodable existing = bagAttr.getBagAttribute(aOid); if (existing != null) { // OK, but the value has to be the same if (!existing.toASN1Primitive().equals(attr)) { throw new IOException( "attempt to add existing attribute with different value"); } } else { bagAttr.setBagAttribute(aOid, attr); } } if (aOid.equals(pkcs_9_at_friendlyName)) { alias = ((DERBMPString)attr).getString(); keys.put(alias, privKey); } else if (aOid.equals(pkcs_9_at_localKeyId)) { localId = (ASN1OctetString)attr; } } String name = new String(Hex.encode(localId.getOctets())); if (alias == null) { keys.put(name, privKey); } else { localIds.put(alias, name); } } else if (b.getBagId().equals(keyBag)) { org.bouncycastle.asn1.pkcs.PrivateKeyInfo kInfo = org.bouncycastle.asn1.pkcs.PrivateKeyInfo.getInstance(b.getBagValue()); PrivateKey privKey = BouncyCastleProvider.getPrivateKey(kInfo); // // set the attributes on the key // PKCS12BagAttributeCarrier bagAttr = (PKCS12BagAttributeCarrier)privKey; String alias = null; ASN1OctetString localId = null; Enumeration e = b.getBagAttributes().getObjects(); while (e.hasMoreElements()) { ASN1Sequence sq = (ASN1Sequence)e.nextElement(); ASN1ObjectIdentifier aOid = (ASN1ObjectIdentifier)sq.getObjectAt(0); ASN1Set attrSet = (ASN1Set)sq.getObjectAt(1); ASN1Primitive attr = null; if (attrSet.size() > 0) { attr = (ASN1Primitive)attrSet.getObjectAt(0); ASN1Encodable existing = bagAttr.getBagAttribute(aOid); if (existing != null) { // OK, but the value has to be the same if (!existing.toASN1Primitive().equals(attr)) { throw new IOException( "attempt to add existing attribute with different value"); } } else { bagAttr.setBagAttribute(aOid, attr); } } if (aOid.equals(pkcs_9_at_friendlyName)) { alias = ((DERBMPString)attr).getString(); keys.put(alias, privKey); } else if (aOid.equals(pkcs_9_at_localKeyId)) { localId = (ASN1OctetString)attr; } } String name = new String(Hex.encode(localId.getOctets())); if (alias == null) { keys.put(name, privKey); } else { localIds.put(alias, name); } } else { System.out.println("extra in encryptedData " + b.getBagId()); System.out.println(ASN1Dump.dumpAsString(b)); } } } else { System.out.println("extra " + c[i].getContentType().getId()); System.out.println("extra " + ASN1Dump.dumpAsString(c[i].getContent())); } } } certs = new IgnoresCaseHashtable(); chainCerts = new Hashtable(); keyCerts = new Hashtable(); for (int i = 0; i != chain.size(); i++) { SafeBag b = (SafeBag)chain.elementAt(i); CertBag cb = CertBag.getInstance(b.getBagValue()); if (!cb.getCertId().equals(x509Certificate)) { throw new RuntimeException("Unsupported certificate type: " + cb.getCertId()); } Certificate cert; try { ByteArrayInputStream cIn = new ByteArrayInputStream( ((ASN1OctetString)cb.getCertValue()).getOctets()); cert = certFact.generateCertificate(cIn); } catch (Exception e) { throw new RuntimeException(e.toString()); } // // set the attributes // ASN1OctetString localId = null; String alias = null; if (b.getBagAttributes() != null) { Enumeration e = b.getBagAttributes().getObjects(); while (e.hasMoreElements()) { ASN1Sequence sq = (ASN1Sequence)e.nextElement(); ASN1ObjectIdentifier oid = (ASN1ObjectIdentifier)sq.getObjectAt(0); ASN1Primitive attr = (ASN1Primitive)((ASN1Set)sq.getObjectAt(1)).getObjectAt(0); PKCS12BagAttributeCarrier bagAttr = null; if (cert instanceof PKCS12BagAttributeCarrier) { bagAttr = (PKCS12BagAttributeCarrier)cert; ASN1Encodable existing = bagAttr.getBagAttribute(oid); if (existing != null) { // OK, but the value has to be the same if (!existing.toASN1Primitive().equals(attr)) { throw new IOException( "attempt to add existing attribute with different value"); } } else { bagAttr.setBagAttribute(oid, attr); } } if (oid.equals(pkcs_9_at_friendlyName)) { alias = ((DERBMPString)attr).getString(); } else if (oid.equals(pkcs_9_at_localKeyId)) { localId = (ASN1OctetString)attr; } } } chainCerts.put(new CertId(cert.getPublicKey()), cert); if (unmarkedKey) { if (keyCerts.isEmpty()) { String name = new String(Hex.encode(createSubjectKeyId(cert.getPublicKey()).getKeyIdentifier())); keyCerts.put(name, cert); keys.put(name, keys.remove("unmarked")); } } else { // // the local key id needs to override the friendly name // if (localId != null) { String name = new String(Hex.encode(localId.getOctets())); keyCerts.put(name, cert); } if (alias != null) { certs.put(alias, cert); } } } } public void engineStore(OutputStream stream, char[] password) throws IOException { doStore(stream, password, false); } private void doStore(OutputStream stream, char[] password, boolean useDEREncoding) throws IOException { if (password == null) { throw new NullPointerException("No password supplied for PKCS#12 KeyStore."); } // // handle the key // ASN1EncodableVector keyS = new ASN1EncodableVector(); Enumeration ks = keys.keys(); while (ks.hasMoreElements()) { byte[] kSalt = new byte[SALT_SIZE]; random.nextBytes(kSalt); String name = (String)ks.nextElement(); PrivateKey privKey = (PrivateKey)keys.get(name); PKCS12PBEParams kParams = new PKCS12PBEParams(kSalt, MIN_ITERATIONS); byte[] kBytes = wrapKey(keyAlgorithm.getId(), privKey, kParams, password); AlgorithmIdentifier kAlgId = new AlgorithmIdentifier(keyAlgorithm, kParams.toASN1Primitive()); org.bouncycastle.asn1.pkcs.EncryptedPrivateKeyInfo kInfo = new org.bouncycastle.asn1.pkcs.EncryptedPrivateKeyInfo(kAlgId, kBytes); boolean attrSet = false; ASN1EncodableVector kName = new ASN1EncodableVector(); if (privKey instanceof PKCS12BagAttributeCarrier) { PKCS12BagAttributeCarrier bagAttrs = (PKCS12BagAttributeCarrier)privKey; // // make sure we are using the local alias on store // DERBMPString nm = (DERBMPString)bagAttrs.getBagAttribute(pkcs_9_at_friendlyName); if (nm == null || !nm.getString().equals(name)) { bagAttrs.setBagAttribute(pkcs_9_at_friendlyName, new DERBMPString(name)); } // // make sure we have a local key-id // if (bagAttrs.getBagAttribute(pkcs_9_at_localKeyId) == null) { Certificate ct = engineGetCertificate(name); bagAttrs.setBagAttribute(pkcs_9_at_localKeyId, createSubjectKeyId(ct.getPublicKey())); } Enumeration e = bagAttrs.getBagAttributeKeys(); while (e.hasMoreElements()) { ASN1ObjectIdentifier oid = (ASN1ObjectIdentifier)e.nextElement(); ASN1EncodableVector kSeq = new ASN1EncodableVector(); kSeq.add(oid); kSeq.add(new DERSet(bagAttrs.getBagAttribute(oid))); attrSet = true; kName.add(new DERSequence(kSeq)); } } if (!attrSet) { // // set a default friendly name (from the key id) and local id // ASN1EncodableVector kSeq = new ASN1EncodableVector(); Certificate ct = engineGetCertificate(name); kSeq.add(pkcs_9_at_localKeyId); kSeq.add(new DERSet(createSubjectKeyId(ct.getPublicKey()))); kName.add(new DERSequence(kSeq)); kSeq = new ASN1EncodableVector(); kSeq.add(pkcs_9_at_friendlyName); kSeq.add(new DERSet(new DERBMPString(name))); kName.add(new DERSequence(kSeq)); } SafeBag kBag = new SafeBag(pkcs8ShroudedKeyBag, kInfo.toASN1Primitive(), new DERSet(kName)); keyS.add(kBag); } byte[] keySEncoded = new DERSequence(keyS).getEncoded(ASN1Encoding.DER); BEROctetString keyString = new BEROctetString(keySEncoded); // // certificate processing // byte[] cSalt = new byte[SALT_SIZE]; random.nextBytes(cSalt); ASN1EncodableVector certSeq = new ASN1EncodableVector(); PKCS12PBEParams cParams = new PKCS12PBEParams(cSalt, MIN_ITERATIONS); AlgorithmIdentifier cAlgId = new AlgorithmIdentifier(certAlgorithm, cParams.toASN1Primitive()); Hashtable doneCerts = new Hashtable(); Enumeration cs = keys.keys(); while (cs.hasMoreElements()) { try { String name = (String)cs.nextElement(); Certificate cert = engineGetCertificate(name); boolean cAttrSet = false; CertBag cBag = new CertBag( x509Certificate, new DEROctetString(cert.getEncoded())); ASN1EncodableVector fName = new ASN1EncodableVector(); if (cert instanceof PKCS12BagAttributeCarrier) { PKCS12BagAttributeCarrier bagAttrs = (PKCS12BagAttributeCarrier)cert; // // make sure we are using the local alias on store // DERBMPString nm = (DERBMPString)bagAttrs.getBagAttribute(pkcs_9_at_friendlyName); if (nm == null || !nm.getString().equals(name)) { bagAttrs.setBagAttribute(pkcs_9_at_friendlyName, new DERBMPString(name)); } // // make sure we have a local key-id // if (bagAttrs.getBagAttribute(pkcs_9_at_localKeyId) == null) { bagAttrs.setBagAttribute(pkcs_9_at_localKeyId, createSubjectKeyId(cert.getPublicKey())); } Enumeration e = bagAttrs.getBagAttributeKeys(); while (e.hasMoreElements()) { ASN1ObjectIdentifier oid = (ASN1ObjectIdentifier)e.nextElement(); ASN1EncodableVector fSeq = new ASN1EncodableVector(); fSeq.add(oid); fSeq.add(new DERSet(bagAttrs.getBagAttribute(oid))); fName.add(new DERSequence(fSeq)); cAttrSet = true; } } if (!cAttrSet) { ASN1EncodableVector fSeq = new ASN1EncodableVector(); fSeq.add(pkcs_9_at_localKeyId); fSeq.add(new DERSet(createSubjectKeyId(cert.getPublicKey()))); fName.add(new DERSequence(fSeq)); fSeq = new ASN1EncodableVector(); fSeq.add(pkcs_9_at_friendlyName); fSeq.add(new DERSet(new DERBMPString(name))); fName.add(new DERSequence(fSeq)); } SafeBag sBag = new SafeBag(certBag, cBag.toASN1Primitive(), new DERSet(fName)); certSeq.add(sBag); doneCerts.put(cert, cert); } catch (CertificateEncodingException e) { throw new IOException("Error encoding certificate: " + e.toString()); } } cs = certs.keys(); while (cs.hasMoreElements()) { try { String certId = (String)cs.nextElement(); Certificate cert = (Certificate)certs.get(certId); boolean cAttrSet = false; if (keys.get(certId) != null) { continue; } CertBag cBag = new CertBag( x509Certificate, new DEROctetString(cert.getEncoded())); ASN1EncodableVector fName = new ASN1EncodableVector(); if (cert instanceof PKCS12BagAttributeCarrier) { PKCS12BagAttributeCarrier bagAttrs = (PKCS12BagAttributeCarrier)cert; // // make sure we are using the local alias on store // DERBMPString nm = (DERBMPString)bagAttrs.getBagAttribute(pkcs_9_at_friendlyName); if (nm == null || !nm.getString().equals(certId)) { bagAttrs.setBagAttribute(pkcs_9_at_friendlyName, new DERBMPString(certId)); } Enumeration e = bagAttrs.getBagAttributeKeys(); while (e.hasMoreElements()) { ASN1ObjectIdentifier oid = (ASN1ObjectIdentifier)e.nextElement(); // a certificate not immediately linked to a key doesn't require // a localKeyID and will confuse some PKCS12 implementations. // // If we find one, we'll prune it out. if (oid.equals(PKCSObjectIdentifiers.pkcs_9_at_localKeyId)) { continue; } ASN1EncodableVector fSeq = new ASN1EncodableVector(); fSeq.add(oid); fSeq.add(new DERSet(bagAttrs.getBagAttribute(oid))); fName.add(new DERSequence(fSeq)); cAttrSet = true; } } if (!cAttrSet) { ASN1EncodableVector fSeq = new ASN1EncodableVector(); fSeq.add(pkcs_9_at_friendlyName); fSeq.add(new DERSet(new DERBMPString(certId))); fName.add(new DERSequence(fSeq)); } SafeBag sBag = new SafeBag(certBag, cBag.toASN1Primitive(), new DERSet(fName)); certSeq.add(sBag); doneCerts.put(cert, cert); } catch (CertificateEncodingException e) { throw new IOException("Error encoding certificate: " + e.toString()); } } cs = chainCerts.keys(); while (cs.hasMoreElements()) { try { CertId certId = (CertId)cs.nextElement(); Certificate cert = (Certificate)chainCerts.get(certId); if (doneCerts.get(cert) != null) { continue; } CertBag cBag = new CertBag( x509Certificate, new DEROctetString(cert.getEncoded())); ASN1EncodableVector fName = new ASN1EncodableVector(); if (cert instanceof PKCS12BagAttributeCarrier) { PKCS12BagAttributeCarrier bagAttrs = (PKCS12BagAttributeCarrier)cert; Enumeration e = bagAttrs.getBagAttributeKeys(); while (e.hasMoreElements()) { ASN1ObjectIdentifier oid = (ASN1ObjectIdentifier)e.nextElement(); // a certificate not immediately linked to a key doesn't require // a localKeyID and will confuse some PKCS12 implementations. // // If we find one, we'll prune it out. if (oid.equals(PKCSObjectIdentifiers.pkcs_9_at_localKeyId)) { continue; } ASN1EncodableVector fSeq = new ASN1EncodableVector(); fSeq.add(oid); fSeq.add(new DERSet(bagAttrs.getBagAttribute(oid))); fName.add(new DERSequence(fSeq)); } } SafeBag sBag = new SafeBag(certBag, cBag.toASN1Primitive(), new DERSet(fName)); certSeq.add(sBag); } catch (CertificateEncodingException e) { throw new IOException("Error encoding certificate: " + e.toString()); } } byte[] certSeqEncoded = new DERSequence(certSeq).getEncoded(ASN1Encoding.DER); byte[] certBytes = cryptData(true, cAlgId, password, false, certSeqEncoded); EncryptedData cInfo = new EncryptedData(data, cAlgId, new BEROctetString(certBytes)); ContentInfo[] info = new ContentInfo[] { new ContentInfo(data, keyString), new ContentInfo(encryptedData, cInfo.toASN1Primitive()) }; AuthenticatedSafe auth = new AuthenticatedSafe(info); ByteArrayOutputStream bOut = new ByteArrayOutputStream(); DEROutputStream asn1Out; if (useDEREncoding) { asn1Out = new DEROutputStream(bOut); } else { asn1Out = new BEROutputStream(bOut); } asn1Out.writeObject(auth); byte[] pkg = bOut.toByteArray(); ContentInfo mainInfo = new ContentInfo(data, new BEROctetString(pkg)); // // create the mac // byte[] mSalt = new byte[20]; int itCount = MIN_ITERATIONS; random.nextBytes(mSalt); byte[] data = ((ASN1OctetString)mainInfo.getContent()).getOctets(); MacData mData; try { byte[] res = calculatePbeMac(id_SHA1, mSalt, itCount, password, false, data); AlgorithmIdentifier algId = new AlgorithmIdentifier(id_SHA1, DERNull.INSTANCE); DigestInfo dInfo = new DigestInfo(algId, res); mData = new MacData(dInfo, mSalt, itCount); } catch (Exception e) { throw new IOException("error constructing MAC: " + e.toString()); } // // output the Pfx // Pfx pfx = new Pfx(mainInfo, mData); if (useDEREncoding) { asn1Out = new DEROutputStream(stream); } else { asn1Out = new BEROutputStream(stream); } asn1Out.writeObject(pfx); } private static byte[] calculatePbeMac( ASN1ObjectIdentifier oid, byte[] salt, int itCount, char[] password, boolean wrongPkcs12Zero, byte[] data) throws Exception { SecretKeyFactory keyFact = SecretKeyFactory.getInstance(oid.getId(), bcProvider); PBEParameterSpec defParams = new PBEParameterSpec(salt, itCount); PBEKeySpec pbeSpec = new PBEKeySpec(password); BCPBEKey key = (BCPBEKey)keyFact.generateSecret(pbeSpec); key.setTryWrongPKCS12Zero(wrongPkcs12Zero); Mac mac = Mac.getInstance(oid.getId(), bcProvider); mac.init(key, defParams); mac.update(data); return mac.doFinal(); } public static class BCPKCS12KeyStore extends PKCS12KeyStoreSpi { public BCPKCS12KeyStore() { super(bcProvider, pbeWithSHAAnd3_KeyTripleDES_CBC, pbeWithSHAAnd40BitRC2_CBC); } } public static class BCPKCS12KeyStore3DES extends PKCS12KeyStoreSpi { public BCPKCS12KeyStore3DES() { super(bcProvider, pbeWithSHAAnd3_KeyTripleDES_CBC, pbeWithSHAAnd3_KeyTripleDES_CBC); } } public static class DefPKCS12KeyStore extends PKCS12KeyStoreSpi { public DefPKCS12KeyStore() { super(null, pbeWithSHAAnd3_KeyTripleDES_CBC, pbeWithSHAAnd40BitRC2_CBC); } } public static class DefPKCS12KeyStore3DES extends PKCS12KeyStoreSpi { public DefPKCS12KeyStore3DES() { super(null, pbeWithSHAAnd3_KeyTripleDES_CBC, pbeWithSHAAnd3_KeyTripleDES_CBC); } } private static class IgnoresCaseHashtable { private Hashtable orig = new Hashtable(); private Hashtable keys = new Hashtable(); public void put(String key, Object value) { String lower = (key == null) ? null : Strings.toLowerCase(key); String k = (String)keys.get(lower); if (k != null) { orig.remove(k); } keys.put(lower, key); orig.put(key, value); } public Enumeration keys() { return orig.keys(); } public Object remove(String alias) { String k = (String)keys.remove(alias == null ? null : Strings.toLowerCase(alias)); if (k == null) { return null; } return orig.remove(k); } public Object get(String alias) { String k = (String)keys.get(alias == null ? null : Strings.toLowerCase(alias)); if (k == null) { return null; } return orig.get(k); } public Enumeration elements() { return orig.elements(); } } } bouncycastle-1.49.orig/jdk1.3/org/bouncycastle/jcajce/ProviderJcaJceHelper.java0000644000175000017500000000670312104173671026771 0ustar ebourgebourgpackage org.bouncycastle.jcajce; import java.security.AlgorithmParameterGenerator; import java.security.AlgorithmParameters; import java.security.KeyFactory; import java.security.KeyPairGenerator; import java.security.MessageDigest; import java.security.NoSuchAlgorithmException; import java.security.NoSuchProviderException; import java.security.Provider; import java.security.Signature; import java.security.cert.CertificateException; import java.security.cert.CertificateFactory; import javax.crypto.Cipher; import javax.crypto.KeyAgreement; import javax.crypto.KeyGenerator; import javax.crypto.Mac; import javax.crypto.NoSuchPaddingException; import javax.crypto.SecretKeyFactory; public class ProviderJcaJceHelper implements JcaJceHelper { protected final Provider provider; public ProviderJcaJceHelper(Provider provider) { this.provider = provider; } public Cipher createCipher( String algorithm) throws NoSuchAlgorithmException, NoSuchPaddingException, NoSuchProviderException { return Cipher.getInstance(algorithm, provider.getName()); } public Mac createMac(String algorithm) throws NoSuchAlgorithmException, NoSuchProviderException { return Mac.getInstance(algorithm, provider.getName()); } public KeyAgreement createKeyAgreement(String algorithm) throws NoSuchAlgorithmException, NoSuchProviderException { return KeyAgreement.getInstance(algorithm, provider.getName()); } public AlgorithmParameterGenerator createAlgorithmParameterGenerator(String algorithm) throws NoSuchAlgorithmException, NoSuchProviderException { return AlgorithmParameterGenerator.getInstance(algorithm, provider.getName()); } public AlgorithmParameters createAlgorithmParameters(String algorithm) throws NoSuchAlgorithmException, NoSuchProviderException { return AlgorithmParameters.getInstance(algorithm, provider.getName()); } public KeyGenerator createKeyGenerator(String algorithm) throws NoSuchAlgorithmException, NoSuchProviderException { return KeyGenerator.getInstance(algorithm, provider.getName()); } public KeyFactory createKeyFactory(String algorithm) throws NoSuchAlgorithmException, NoSuchProviderException { return KeyFactory.getInstance(algorithm, provider.getName()); } public SecretKeyFactory createSecretKeyFactory(String algorithm) throws NoSuchAlgorithmException, NoSuchProviderException { return SecretKeyFactory.getInstance(algorithm, provider.getName()); } public KeyPairGenerator createKeyPairGenerator(String algorithm) throws NoSuchAlgorithmException, NoSuchProviderException { return KeyPairGenerator.getInstance(algorithm, provider.getName()); } public MessageDigest createDigest(String algorithm) throws NoSuchAlgorithmException, NoSuchProviderException { return MessageDigest.getInstance(algorithm, provider.getName()); } public Signature createSignature(String algorithm) throws NoSuchAlgorithmException, NoSuchProviderException { return Signature.getInstance(algorithm, provider.getName()); } public CertificateFactory createCertificateFactory(String algorithm) throws NoSuchAlgorithmException, CertificateException, NoSuchProviderException { return CertificateFactory.getInstance(algorithm, provider.getName()); } } bouncycastle-1.49.orig/jdk1.3/org/bouncycastle/pkcs/0000755000175000017500000000000012152033550021641 5ustar ebourgebourgbouncycastle-1.49.orig/jdk1.3/org/bouncycastle/pkcs/jcajce/0000755000175000017500000000000012152033550023060 5ustar ebourgebourgbouncycastle-1.49.orig/jdk1.3/org/bouncycastle/pkcs/jcajce/JcaPKCS10CertificationRequestBuilder.java0000644000175000017500000000162111523656117032641 0ustar ebourgebourgpackage org.bouncycastle.pkcs.jcajce; import java.security.PublicKey; import org.bouncycastle.asn1.x500.X500Name; import org.bouncycastle.asn1.x509.SubjectPublicKeyInfo; import org.bouncycastle.pkcs.PKCS10CertificationRequestBuilder; /** * Extension of the PKCS#10 builder to support PublicKey and X500Principal objects. */ public class JcaPKCS10CertificationRequestBuilder extends PKCS10CertificationRequestBuilder { /** * Create a PKCS#10 builder for the passed in subject and JCA public key. * * @param subject an X500Name containing the subject associated with the request we are building. * @param publicKey a JCA public key that is to be associated with the request we are building. */ public JcaPKCS10CertificationRequestBuilder(X500Name subject, PublicKey publicKey) { super(subject, SubjectPublicKeyInfo.getInstance(publicKey.getEncoded())); } } bouncycastle-1.49.orig/jdk1.3/org/bouncycastle/jce/0000755000175000017500000000000012152033550021442 5ustar ebourgebourgbouncycastle-1.49.orig/jdk1.3/org/bouncycastle/jce/provider/0000755000175000017500000000000012152033550023274 5ustar ebourgebourgbouncycastle-1.49.orig/jdk1.3/org/bouncycastle/jce/provider/X509CRLObject.java0000644000175000017500000004132212132666220026302 0ustar ebourgebourgpackage org.bouncycastle.jce.provider; import java.io.IOException; import java.math.BigInteger; import java.security.InvalidKeyException; import java.security.NoSuchAlgorithmException; import java.security.NoSuchProviderException; import java.security.Principal; import java.security.PublicKey; import java.security.Signature; import java.security.SignatureException; import java.security.cert.CRLException; import java.security.cert.Certificate; import java.security.cert.CertificateEncodingException; import java.security.cert.X509CRL; import java.security.cert.X509CRLEntry; import java.security.cert.X509Certificate; import java.util.Collections; import java.util.Date; import java.util.Enumeration; import java.util.HashSet; import java.util.Iterator; import java.util.Set; import org.bouncycastle.asn1.ASN1Encodable; import org.bouncycastle.asn1.ASN1Encoding; import org.bouncycastle.asn1.ASN1InputStream; import org.bouncycastle.asn1.ASN1ObjectIdentifier; import org.bouncycastle.asn1.DERInteger; import org.bouncycastle.asn1.util.ASN1Dump; import org.bouncycastle.asn1.x500.X500Name; import org.bouncycastle.asn1.x509.CRLDistPoint; import org.bouncycastle.asn1.x509.CRLNumber; import org.bouncycastle.asn1.x509.CertificateList; import org.bouncycastle.asn1.x509.Extension; import org.bouncycastle.asn1.x509.Extensions; import org.bouncycastle.asn1.x509.GeneralNames; import org.bouncycastle.asn1.x509.IssuingDistributionPoint; import org.bouncycastle.asn1.x509.TBSCertList; import org.bouncycastle.jce.X509Principal; import org.bouncycastle.jce.provider.RFC3280CertPathUtilities; import org.bouncycastle.jce.provider.BouncyCastleProvider; import org.bouncycastle.util.encoders.Hex; import org.bouncycastle.x509.extension.X509ExtensionUtil; /** * The following extensions are listed in RFC 2459 as relevant to CRLs * * Authority Key Identifier * Issuer Alternative Name * CRL Number * Delta CRL Indicator (critical) * Issuing Distribution Point (critical) */ public class X509CRLObject extends X509CRL { private CertificateList c; private String sigAlgName; private byte[] sigAlgParams; private boolean isIndirect; static boolean isIndirectCRL(X509CRL crl) throws CRLException { try { byte[] idp = crl.getExtensionValue(Extension.issuingDistributionPoint.getId()); return idp != null && IssuingDistributionPoint.getInstance(X509ExtensionUtil.fromExtensionValue(idp)).isIndirectCRL(); } catch (Exception e) { throw new ExtCRLException( "Exception reading IssuingDistributionPoint", e); } } public X509CRLObject( CertificateList c) throws CRLException { this.c = c; try { this.sigAlgName = X509SignatureUtil.getSignatureName(c.getSignatureAlgorithm()); if (c.getSignatureAlgorithm().getParameters() != null) { this.sigAlgParams = ((ASN1Encodable)c.getSignatureAlgorithm().getParameters()).toASN1Primitive().getEncoded(ASN1Encoding.DER); } else { this.sigAlgParams = null; } this.isIndirect = isIndirectCRL(this); } catch (Exception e) { throw new CRLException("CRL contents invalid: " + e); } } /** * Will return true if any extensions are present and marked * as critical as we currently dont handle any extensions! */ public boolean hasUnsupportedCriticalExtension() { Set extns = getCriticalExtensionOIDs(); if (extns == null) { return false; } extns.remove(RFC3280CertPathUtilities.ISSUING_DISTRIBUTION_POINT); extns.remove(RFC3280CertPathUtilities.DELTA_CRL_INDICATOR); return !extns.isEmpty(); } private Set getExtensionOIDs(boolean critical) { if (this.getVersion() == 2) { Extensions extensions = c.getTBSCertList().getExtensions(); if (extensions != null) { Set set = new HashSet(); Enumeration e = extensions.oids(); while (e.hasMoreElements()) { ASN1ObjectIdentifier oid = (ASN1ObjectIdentifier)e.nextElement(); Extension ext = extensions.getExtension(oid); if (critical == ext.isCritical()) { set.add(oid.getId()); } } return set; } } return null; } public Set getCriticalExtensionOIDs() { return getExtensionOIDs(true); } public Set getNonCriticalExtensionOIDs() { return getExtensionOIDs(false); } public byte[] getExtensionValue(String oid) { Extensions exts = c.getTBSCertList().getExtensions(); if (exts != null) { Extension ext = exts.getExtension(new ASN1ObjectIdentifier(oid)); if (ext != null) { try { return ext.getExtnValue().getEncoded(); } catch (Exception e) { throw new IllegalStateException("error parsing " + e.toString()); } } } return null; } public byte[] getEncoded() throws CRLException { try { return c.getEncoded(ASN1Encoding.DER); } catch (IOException e) { throw new CRLException(e.toString()); } } public void verify(PublicKey key) throws CRLException, NoSuchAlgorithmException, InvalidKeyException, NoSuchProviderException, SignatureException { verify(key, BouncyCastleProvider.PROVIDER_NAME); } public void verify(PublicKey key, String sigProvider) throws CRLException, NoSuchAlgorithmException, InvalidKeyException, NoSuchProviderException, SignatureException { if (!c.getSignatureAlgorithm().equals(c.getTBSCertList().getSignature())) { throw new CRLException("Signature algorithm on CertificateList does not match TBSCertList."); } Signature sig; if (sigProvider != null) { sig = Signature.getInstance(getSigAlgName(), sigProvider); } else { sig = Signature.getInstance(getSigAlgName()); } sig.initVerify(key); sig.update(this.getTBSCertList()); if (!sig.verify(this.getSignature())) { throw new SignatureException("CRL does not verify with supplied public key."); } } public int getVersion() { return c.getVersionNumber(); } public Principal getIssuerDN() { return new X509Principal(X500Name.getInstance(c.getIssuer().toASN1Primitive())); } public Date getThisUpdate() { return c.getThisUpdate().getDate(); } public Date getNextUpdate() { if (c.getNextUpdate() != null) { return c.getNextUpdate().getDate(); } return null; } private Set loadCRLEntries() { Set entrySet = new HashSet(); Enumeration certs = c.getRevokedCertificateEnumeration(); X500Name previousCertificateIssuer = c.getIssuer(); while (certs.hasMoreElements()) { TBSCertList.CRLEntry entry = (TBSCertList.CRLEntry)certs.nextElement(); X509CRLEntryObject crlEntry = new X509CRLEntryObject(entry, isIndirect, previousCertificateIssuer); entrySet.add(crlEntry); if (isIndirect && entry.hasExtensions()) { Extension currentCaName = entry.getExtensions().getExtension(Extension.certificateIssuer); if (currentCaName != null) { previousCertificateIssuer = X500Name.getInstance(GeneralNames.getInstance(currentCaName.getParsedValue()).getNames()[0].getName()); } } } return entrySet; } public X509CRLEntry getRevokedCertificate(BigInteger serialNumber) { Enumeration certs = c.getRevokedCertificateEnumeration(); X500Name previousCertificateIssuer = c.getIssuer(); while (certs.hasMoreElements()) { TBSCertList.CRLEntry entry = (TBSCertList.CRLEntry)certs.nextElement(); if (serialNumber.equals(entry.getUserCertificate().getValue())) { return new X509CRLEntryObject(entry, isIndirect, previousCertificateIssuer); } if (isIndirect && entry.hasExtensions()) { Extension currentCaName = entry.getExtensions().getExtension(Extension.certificateIssuer); if (currentCaName != null) { previousCertificateIssuer = X500Name.getInstance(GeneralNames.getInstance(currentCaName.getParsedValue()).getNames()[0].getName()); } } } return null; } public Set getRevokedCertificates() { Set entrySet = loadCRLEntries(); if (!entrySet.isEmpty()) { return Collections.unmodifiableSet(entrySet); } return null; } public byte[] getTBSCertList() throws CRLException { try { return c.getTBSCertList().getEncoded("DER"); } catch (IOException e) { throw new CRLException(e.toString()); } } public byte[] getSignature() { return c.getSignature().getBytes(); } public String getSigAlgName() { return sigAlgName; } public String getSigAlgOID() { return c.getSignatureAlgorithm().getAlgorithm().getId(); } public byte[] getSigAlgParams() { if (sigAlgParams != null) { byte[] tmp = new byte[sigAlgParams.length]; System.arraycopy(sigAlgParams, 0, tmp, 0, tmp.length); return tmp; } return null; } /** * Returns a string representation of this CRL. * * @return a string representation of this CRL. */ public String toString() { StringBuffer buf = new StringBuffer(); String nl = System.getProperty("line.separator"); buf.append(" Version: ").append(this.getVersion()).append( nl); buf.append(" IssuerDN: ").append(this.getIssuerDN()) .append(nl); buf.append(" This update: ").append(this.getThisUpdate()) .append(nl); buf.append(" Next update: ").append(this.getNextUpdate()) .append(nl); buf.append(" Signature Algorithm: ").append(this.getSigAlgName()) .append(nl); byte[] sig = this.getSignature(); buf.append(" Signature: ").append( new String(Hex.encode(sig, 0, 20))).append(nl); for (int i = 20; i < sig.length; i += 20) { if (i < sig.length - 20) { buf.append(" ").append( new String(Hex.encode(sig, i, 20))).append(nl); } else { buf.append(" ").append( new String(Hex.encode(sig, i, sig.length - i))).append(nl); } } Extensions extensions = c.getTBSCertList().getExtensions(); if (extensions != null) { Enumeration e = extensions.oids(); if (e.hasMoreElements()) { buf.append(" Extensions: ").append(nl); } while (e.hasMoreElements()) { ASN1ObjectIdentifier oid = (ASN1ObjectIdentifier) e.nextElement(); Extension ext = extensions.getExtension(oid); if (ext.getExtnValue() != null) { byte[] octs = ext.getExtnValue().getOctets(); ASN1InputStream dIn = new ASN1InputStream(octs); buf.append(" critical(").append( ext.isCritical()).append(") "); try { if (oid.equals(Extension.cRLNumber)) { buf.append( new CRLNumber(DERInteger.getInstance( dIn.readObject()).getPositiveValue())) .append(nl); } else if (oid.equals(Extension.deltaCRLIndicator)) { buf.append( "Base CRL: " + new CRLNumber(DERInteger.getInstance( dIn.readObject()).getPositiveValue())) .append(nl); } else if (oid .equals(Extension.issuingDistributionPoint)) { buf.append( IssuingDistributionPoint.getInstance(dIn.readObject())).append(nl); } else if (oid .equals(Extension.cRLDistributionPoints)) { buf.append( CRLDistPoint.getInstance(dIn.readObject())).append(nl); } else if (oid.equals(Extension.freshestCRL)) { buf.append( CRLDistPoint.getInstance(dIn.readObject())).append(nl); } else { buf.append(oid.getId()); buf.append(" value = ").append( ASN1Dump.dumpAsString(dIn.readObject())) .append(nl); } } catch (Exception ex) { buf.append(oid.getId()); buf.append(" value = ").append("*****").append(nl); } } else { buf.append(nl); } } } Set set = getRevokedCertificates(); if (set != null) { Iterator it = set.iterator(); while (it.hasNext()) { buf.append(it.next()); buf.append(nl); } } return buf.toString(); } /** * Checks whether the given certificate is on this CRL. * * @param cert the certificate to check for. * @return true if the given certificate is on this CRL, * false otherwise. */ public boolean isRevoked(Certificate cert) { if (!cert.getType().equals("X.509")) { throw new RuntimeException("X.509 CRL used with non X.509 Cert"); } TBSCertList.CRLEntry[] certs = c.getRevokedCertificates(); X500Name caName = c.getIssuer(); if (certs != null) { BigInteger serial = ((X509Certificate)cert).getSerialNumber(); for (int i = 0; i < certs.length; i++) { if (isIndirect && certs[i].hasExtensions()) { Extension currentCaName = certs[i].getExtensions().getExtension(Extension.certificateIssuer); if (currentCaName != null) { caName = X500Name.getInstance(GeneralNames.getInstance(currentCaName.getParsedValue()).getNames()[0].getName()); } } if (certs[i].getUserCertificate().getValue().equals(serial)) { X500Name issuer; try { issuer = org.bouncycastle.asn1.x509.Certificate.getInstance(cert.getEncoded()).getIssuer(); } catch (CertificateEncodingException e) { throw new RuntimeException("Cannot process certificate"); } if (!caName.equals(issuer)) { return false; } return true; } } } return false; } } bouncycastle-1.49.orig/jdk1.3/org/bouncycastle/jce/provider/PKIXPolicyNode.java0000644000175000017500000000771510331052734026714 0ustar ebourgebourgpackage org.bouncycastle.jce.provider; import java.util.ArrayList; import java.util.HashSet; import java.util.Iterator; import java.util.List; import java.util.Set; import org.bouncycastle.jce.cert.PolicyNode; public class PKIXPolicyNode implements PolicyNode { protected List children; protected int depth; protected Set expectedPolicies; protected PolicyNode parent; protected Set policyQualifiers; protected String validPolicy; protected boolean critical; /* * * CONSTRUCTORS * */ public PKIXPolicyNode( List _children, int _depth, Set _expectedPolicies, PolicyNode _parent, Set _policyQualifiers, String _validPolicy, boolean _critical) { children = _children; depth = _depth; expectedPolicies = _expectedPolicies; parent = _parent; policyQualifiers = _policyQualifiers; validPolicy = _validPolicy; critical = _critical; } public void addChild( PKIXPolicyNode _child) { children.add(_child); _child.setParent(this); } public Iterator getChildren() { return children.iterator(); } public int getDepth() { return depth; } public Set getExpectedPolicies() { return expectedPolicies; } public PolicyNode getParent() { return parent; } public Set getPolicyQualifiers() { return policyQualifiers; } public String getValidPolicy() { return validPolicy; } public boolean hasChildren() { return !children.isEmpty(); } public boolean isCritical() { return critical; } public void removeChild(PKIXPolicyNode _child) { children.remove(_child); } public void setCritical(boolean _critical) { critical = _critical; } public void setParent(PKIXPolicyNode _parent) { parent = _parent; } public String toString() { return toString(""); } public String toString(String _indent) { StringBuffer _buf = new StringBuffer(); _buf.append(_indent); _buf.append(validPolicy); _buf.append(" {\n"); for(int i = 0; i < children.size(); i++) { _buf.append(((PKIXPolicyNode)children.get(i)).toString(_indent + " ")); } _buf.append(_indent); _buf.append("}\n"); return _buf.toString(); } public Object clone() { return copy(); } public PKIXPolicyNode copy() { Set _expectedPolicies = new HashSet(); Iterator _iter = expectedPolicies.iterator(); while (_iter.hasNext()) { _expectedPolicies.add(new String((String)_iter.next())); } Set _policyQualifiers = new HashSet(); _iter = policyQualifiers.iterator(); while (_iter.hasNext()) { _policyQualifiers.add(new String((String)_iter.next())); } PKIXPolicyNode _node = new PKIXPolicyNode(new ArrayList(), depth, _expectedPolicies, null, _policyQualifiers, new String(validPolicy), critical); _iter = children.iterator(); while (_iter.hasNext()) { PKIXPolicyNode _child = ((PKIXPolicyNode)_iter.next()).copy(); _child.setParent(_node); _node.addChild(_child); } return _node; } } bouncycastle-1.49.orig/jdk1.3/org/bouncycastle/jce/provider/MultiCertStoreSpi.java0000644000175000017500000000502310623745117027552 0ustar ebourgebourgpackage org.bouncycastle.jce.provider; import org.bouncycastle.jce.MultiCertStoreParameters; import java.security.InvalidAlgorithmParameterException; import org.bouncycastle.jce.cert.CRLSelector; import org.bouncycastle.jce.cert.CertSelector; import org.bouncycastle.jce.cert.CertStore; import org.bouncycastle.jce.cert.CertStoreException; import org.bouncycastle.jce.cert.CertStoreParameters; import org.bouncycastle.jce.cert.CertStoreSpi; import java.util.ArrayList; import java.util.Collection; import java.util.Collections; import java.util.Iterator; import java.util.List; public class MultiCertStoreSpi extends CertStoreSpi { private MultiCertStoreParameters params; public MultiCertStoreSpi(CertStoreParameters params) throws InvalidAlgorithmParameterException { super(params); if (!(params instanceof MultiCertStoreParameters)) { throw new InvalidAlgorithmParameterException("org.bouncycastle.jce.provider.MultiCertStoreSpi: parameter must be a MultiCertStoreParameters object\n" + params.toString()); } this.params = (MultiCertStoreParameters)params; } public Collection engineGetCertificates(CertSelector certSelector) throws CertStoreException { boolean searchAllStores = params.getSearchAllStores(); Iterator iter = params.getCertStores().iterator(); List allCerts = searchAllStores ? new ArrayList() : Collections.EMPTY_LIST; while (iter.hasNext()) { CertStore store = (CertStore)iter.next(); Collection certs = store.getCertificates(certSelector); if (searchAllStores) { allCerts.addAll(certs); } else if (!certs.isEmpty()) { return certs; } } return allCerts; } public Collection engineGetCRLs(CRLSelector crlSelector) throws CertStoreException { boolean searchAllStores = params.getSearchAllStores(); Iterator iter = params.getCertStores().iterator(); List allCRLs = searchAllStores ? new ArrayList() : Collections.EMPTY_LIST; while (iter.hasNext()) { CertStore store = (CertStore)iter.next(); Collection crls = store.getCRLs(crlSelector); if (searchAllStores) { allCRLs.addAll(crls); } else if (!crls.isEmpty()) { return crls; } } return allCRLs; } } bouncycastle-1.49.orig/jdk1.3/org/bouncycastle/jce/provider/PKIXCRLUtil.java0000644000175000017500000001113411424221705026113 0ustar ebourgebourgpackage org.bouncycastle.jce.provider; import org.bouncycastle.jce.cert.CertStore; import org.bouncycastle.jce.cert.CertStoreException; import org.bouncycastle.jce.cert.PKIXParameters; import java.security.cert.X509CRL; import java.security.cert.X509Certificate; import java.util.Collection; import java.util.Date; import java.util.HashSet; import java.util.Iterator; import java.util.List; import java.util.Set; import org.bouncycastle.util.StoreException; import org.bouncycastle.x509.ExtendedPKIXParameters; import org.bouncycastle.x509.X509CRLStoreSelector; import org.bouncycastle.x509.X509Store; public class PKIXCRLUtil { public Set findCRLs(X509CRLStoreSelector crlselect, ExtendedPKIXParameters paramsPKIX, Date currentDate) throws AnnotatedException { Set initialSet = new HashSet(); // get complete CRL(s) try { initialSet.addAll(findCRLs(crlselect, paramsPKIX.getAdditionalStores())); initialSet.addAll(findCRLs(crlselect, paramsPKIX.getStores())); initialSet.addAll(findCRLs(crlselect, paramsPKIX.getCertStores())); } catch (AnnotatedException e) { throw new AnnotatedException("Exception obtaining complete CRLs.", e); } Set finalSet = new HashSet(); Date validityDate = currentDate; if (paramsPKIX.getDate() != null) { validityDate = paramsPKIX.getDate(); } // based on RFC 5280 6.3.3 for (Iterator it = initialSet.iterator(); it.hasNext();) { X509CRL crl = (X509CRL)it.next(); if (crl.getNextUpdate().after(validityDate)) { X509Certificate cert = crlselect.getCertificateChecking(); if (cert != null) { if (crl.getThisUpdate().before(cert.getNotAfter())) { finalSet.add(crl); } } else { finalSet.add(crl); } } } return finalSet; } public Set findCRLs(X509CRLStoreSelector crlselect, PKIXParameters paramsPKIX) throws AnnotatedException { Set completeSet = new HashSet(); // get complete CRL(s) try { completeSet.addAll(findCRLs(crlselect, paramsPKIX.getCertStores())); } catch (AnnotatedException e) { throw new AnnotatedException("Exception obtaining complete CRLs.", e); } return completeSet; } /** * Return a Collection of all CRLs found in the X509Store's that are * matching the crlSelect criteriums. * * @param crlSelect a {@link X509CRLStoreSelector} object that will be used * to select the CRLs * @param crlStores a List containing only * {@link org.bouncycastle.x509.X509Store X509Store} objects. * These are used to search for CRLs * * @return a Collection of all found {@link java.security.cert.X509CRL X509CRL} objects. May be * empty but never null. */ private final Collection findCRLs(X509CRLStoreSelector crlSelect, List crlStores) throws AnnotatedException { Set crls = new HashSet(); Iterator iter = crlStores.iterator(); AnnotatedException lastException = null; boolean foundValidStore = false; while (iter.hasNext()) { Object obj = iter.next(); if (obj instanceof X509Store) { X509Store store = (X509Store)obj; try { crls.addAll(store.getMatches(crlSelect)); foundValidStore = true; } catch (StoreException e) { lastException = new AnnotatedException( "Exception searching in X.509 CRL store.", e); } } else { CertStore store = (CertStore)obj; try { crls.addAll(store.getCRLs(crlSelect)); foundValidStore = true; } catch (CertStoreException e) { lastException = new AnnotatedException( "Exception searching in X.509 CRL store.", e); } } } if (!foundValidStore && lastException != null) { throw lastException; } return crls; } } bouncycastle-1.49.orig/jdk1.3/org/bouncycastle/jce/provider/CertPathValidatorUtilities.java0000644000175000017500000013710111726307315031427 0ustar ebourgebourgpackage org.bouncycastle.jce.provider; import java.io.ByteArrayOutputStream; import java.io.IOException; import java.math.BigInteger; import java.security.GeneralSecurityException; import java.security.KeyFactory; import java.security.PublicKey; import java.security.cert.CRLException; import org.bouncycastle.jce.cert.CertPath; import org.bouncycastle.jce.cert.CertPathValidatorException; import org.bouncycastle.jce.cert.CertStore; import org.bouncycastle.jce.cert.CertStoreException; import java.security.cert.Certificate; import java.security.cert.CertificateParsingException; import org.bouncycastle.jce.cert.PKIXParameters; import org.bouncycastle.jce.cert.PolicyQualifierInfo; import org.bouncycastle.jce.cert.TrustAnchor; import java.security.cert.X509CRL; import java.security.cert.X509CRLEntry; import org.bouncycastle.jce.cert.X509CRLSelector; import org.bouncycastle.jce.cert.X509CertSelector; import java.security.cert.X509Certificate; import java.security.interfaces.DSAParams; import java.security.interfaces.DSAPublicKey; import java.security.spec.DSAPublicKeySpec; import java.text.ParseException; import java.util.ArrayList; import java.util.Collection; import java.util.Date; import java.util.Enumeration; import java.util.HashSet; import java.util.Iterator; import java.util.List; import java.util.Map; import java.util.Set; import org.bouncycastle.asn1.ASN1Encodable; import org.bouncycastle.asn1.ASN1InputStream; import org.bouncycastle.asn1.ASN1Integer; import org.bouncycastle.asn1.ASN1OctetString; import org.bouncycastle.asn1.ASN1OutputStream; import org.bouncycastle.asn1.ASN1Primitive; import org.bouncycastle.asn1.ASN1Sequence; import org.bouncycastle.asn1.DEREnumerated; import org.bouncycastle.asn1.DERGeneralizedTime; import org.bouncycastle.asn1.DERIA5String; import org.bouncycastle.asn1.DERObjectIdentifier; import org.bouncycastle.asn1.DERSequence; import org.bouncycastle.asn1.isismtt.ISISMTTObjectIdentifiers; import org.bouncycastle.asn1.x509.AlgorithmIdentifier; import org.bouncycastle.asn1.x509.CRLDistPoint; import org.bouncycastle.asn1.x509.CRLReason; import org.bouncycastle.asn1.x509.CertificateList; import org.bouncycastle.asn1.x509.DistributionPoint; import org.bouncycastle.asn1.x509.DistributionPointName; import org.bouncycastle.asn1.x509.GeneralName; import org.bouncycastle.asn1.x509.GeneralNames; import org.bouncycastle.asn1.x509.PolicyInformation; import org.bouncycastle.asn1.x509.SubjectPublicKeyInfo; import org.bouncycastle.asn1.x509.X509Extension; import org.bouncycastle.asn1.x509.X509Extensions; import org.bouncycastle.jce.exception.ExtCertPathValidatorException; import org.bouncycastle.jce.X509Principal; import org.bouncycastle.jce.PrincipalUtil; import org.bouncycastle.util.Selector; import org.bouncycastle.util.StoreException; import org.bouncycastle.x509.ExtendedPKIXBuilderParameters; import org.bouncycastle.x509.ExtendedPKIXParameters; import org.bouncycastle.x509.X509AttributeCertStoreSelector; import org.bouncycastle.x509.X509AttributeCertificate; import org.bouncycastle.x509.X509CRLStoreSelector; import org.bouncycastle.x509.X509CertStoreSelector; import org.bouncycastle.x509.X509Store; public class CertPathValidatorUtilities { protected static final PKIXCRLUtil CRL_UTIL = new PKIXCRLUtil(); protected static final String CERTIFICATE_POLICIES = X509Extensions.CertificatePolicies.getId(); protected static final String BASIC_CONSTRAINTS = X509Extensions.BasicConstraints.getId(); protected static final String POLICY_MAPPINGS = X509Extensions.PolicyMappings.getId(); protected static final String SUBJECT_ALTERNATIVE_NAME = X509Extensions.SubjectAlternativeName.getId(); protected static final String NAME_CONSTRAINTS = X509Extensions.NameConstraints.getId(); protected static final String KEY_USAGE = X509Extensions.KeyUsage.getId(); protected static final String INHIBIT_ANY_POLICY = X509Extensions.InhibitAnyPolicy.getId(); protected static final String ISSUING_DISTRIBUTION_POINT = X509Extensions.IssuingDistributionPoint.getId(); protected static final String DELTA_CRL_INDICATOR = X509Extensions.DeltaCRLIndicator.getId(); protected static final String POLICY_CONSTRAINTS = X509Extensions.PolicyConstraints.getId(); protected static final String FRESHEST_CRL = X509Extensions.FreshestCRL.getId(); protected static final String CRL_DISTRIBUTION_POINTS = X509Extensions.CRLDistributionPoints.getId(); protected static final String AUTHORITY_KEY_IDENTIFIER = X509Extensions.AuthorityKeyIdentifier.getId(); protected static final String ANY_POLICY = "2.5.29.32.0"; protected static final String CRL_NUMBER = X509Extensions.CRLNumber.getId(); /* * key usage bits */ protected static final int KEY_CERT_SIGN = 5; protected static final int CRL_SIGN = 6; protected static final String[] crlReasons = new String[]{ "unspecified", "keyCompromise", "cACompromise", "affiliationChanged", "superseded", "cessationOfOperation", "certificateHold", "unknown", "removeFromCRL", "privilegeWithdrawn", "aACompromise"}; /** * Search the given Set of TrustAnchor's for one that is the * issuer of the given X509 certificate. Uses the default provider * for signature verification. * * @param cert the X509 certificate * @param trustAnchors a Set of TrustAnchor's * @return the TrustAnchor object if found or * null if not. * @throws AnnotatedException if a TrustAnchor was found but the signature verification * on the given certificate has thrown an exception. */ protected static TrustAnchor findTrustAnchor( X509Certificate cert, Set trustAnchors) throws AnnotatedException { return findTrustAnchor(cert, trustAnchors, null); } /** * Search the given Set of TrustAnchor's for one that is the * issuer of the given X509 certificate. Uses the specified * provider for signature verification, or the default provider * if null. * * @param cert the X509 certificate * @param trustAnchors a Set of TrustAnchor's * @param sigProvider the provider to use for signature verification * @return the TrustAnchor object if found or * null if not. * @throws AnnotatedException if a TrustAnchor was found but the signature verification * on the given certificate has thrown an exception. */ protected static TrustAnchor findTrustAnchor( X509Certificate cert, Set trustAnchors, String sigProvider) throws AnnotatedException { TrustAnchor trust = null; PublicKey trustPublicKey = null; Exception invalidKeyEx = null; X509CertSelector certSelectX509 = new X509CertSelector(); X509Principal certIssuer = getEncodedIssuerPrincipal(cert); try { certSelectX509.setSubject(certIssuer.getEncoded()); } catch (IOException ex) { throw new AnnotatedException("Cannot set subject search criteria for trust anchor.", ex); } Iterator iter = trustAnchors.iterator(); while (iter.hasNext() && trust == null) { trust = (TrustAnchor)iter.next(); if (trust.getTrustedCert() != null) { if (certSelectX509.match(trust.getTrustedCert())) { trustPublicKey = trust.getTrustedCert().getPublicKey(); } else { trust = null; } } else if (trust.getCAName() != null && trust.getCAPublicKey() != null) { try { X509Principal caName = new X509Principal(trust.getCAName()); if (certIssuer.equals(caName)) { trustPublicKey = trust.getCAPublicKey(); } else { trust = null; } } catch (IllegalArgumentException ex) { trust = null; } } else { trust = null; } if (trustPublicKey != null) { try { verifyX509Certificate(cert, trustPublicKey, sigProvider); } catch (Exception ex) { invalidKeyEx = ex; trust = null; trustPublicKey = null; } } } if (trust == null && invalidKeyEx != null) { throw new AnnotatedException("TrustAnchor found but certificate validation failed.", invalidKeyEx); } return trust; } protected static void addAdditionalStoresFromAltNames( X509Certificate cert, ExtendedPKIXParameters pkixParams) throws CertificateParsingException { // if in the IssuerAltName extension an URI // is given, add an additinal X.509 store /* if (cert.getIssuerAlternativeNames() != null) { Iterator it = cert.getIssuerAlternativeNames().iterator(); while (it.hasNext()) { // look for URI List list = (List)it.next(); if (list.get(0).equals(new Integer(GeneralName.uniformResourceIdentifier))) { // found String temp = (String)list.get(1); CertPathValidatorUtilities.addAdditionalStoreFromLocation(temp, pkixParams); } } } */ } /** * Returns the issuer of an attribute certificate or certificate. * * @param cert The attribute certificate or certificate. * @return The issuer as X509Principal. */ protected static X509Principal getEncodedIssuerPrincipal( Object cert) { if (cert instanceof X509Certificate) { try { return PrincipalUtil.getIssuerX509Principal((X509Certificate)cert); } catch (Exception e) { throw new IllegalStateException(e.toString()); } } else { return (X509Principal)((X509AttributeCertificate)cert).getIssuer().getPrincipals()[0]; } } protected static Date getValidDate(PKIXParameters paramsPKIX) { Date validDate = paramsPKIX.getDate(); if (validDate == null) { validDate = new Date(); } return validDate; } protected static X509Principal getSubjectPrincipal(X509Certificate cert) { try { return PrincipalUtil.getSubjectX509Principal(cert); } catch (Exception e) { throw new IllegalStateException(e.toString()); } } protected static boolean isSelfIssued(X509Certificate cert) { return cert.getSubjectDN().equals(cert.getIssuerDN()); } /** * Extract the value of the given extension, if it exists. * * @param ext The extension object. * @param oid The object identifier to obtain. * @throws AnnotatedException if the extension cannot be read. */ protected static ASN1Primitive getExtensionValue( java.security.cert.X509Extension ext, String oid) throws AnnotatedException { byte[] bytes = ext.getExtensionValue(oid); if (bytes == null) { return null; } return getObject(oid, bytes); } private static ASN1Primitive getObject( String oid, byte[] ext) throws AnnotatedException { try { ASN1InputStream aIn = new ASN1InputStream(ext); ASN1OctetString octs = (ASN1OctetString)aIn.readObject(); aIn = new ASN1InputStream(octs.getOctets()); return aIn.readObject(); } catch (Exception e) { throw new AnnotatedException("exception processing extension " + oid, e); } } protected static X509Principal getIssuerPrincipal(X509CRL crl) { try { return PrincipalUtil.getIssuerX509Principal(crl); } catch (Exception e) { throw new IllegalStateException(e.toString()); } } protected static AlgorithmIdentifier getAlgorithmIdentifier( PublicKey key) throws CertPathValidatorException { try { ASN1InputStream aIn = new ASN1InputStream(key.getEncoded()); SubjectPublicKeyInfo info = SubjectPublicKeyInfo.getInstance(aIn.readObject()); return info.getAlgorithmId(); } catch (Exception e) { throw new ExtCertPathValidatorException("Subject public key cannot be decoded.", e); } } // crl checking // // policy checking // protected static final Set getQualifierSet(ASN1Sequence qualifiers) throws CertPathValidatorException { Set pq = new HashSet(); if (qualifiers == null) { return pq; } ByteArrayOutputStream bOut = new ByteArrayOutputStream(); ASN1OutputStream aOut = new ASN1OutputStream(bOut); Enumeration e = qualifiers.getObjects(); while (e.hasMoreElements()) { try { aOut.writeObject((ASN1Encodable)e.nextElement()); pq.add(new PolicyQualifierInfo(bOut.toByteArray())); } catch (IOException ex) { throw new ExtCertPathValidatorException("Policy qualifier info cannot be decoded.", ex); } bOut.reset(); } return pq; } protected static PKIXPolicyNode removePolicyNode( PKIXPolicyNode validPolicyTree, List[] policyNodes, PKIXPolicyNode _node) { PKIXPolicyNode _parent = (PKIXPolicyNode)_node.getParent(); if (validPolicyTree == null) { return null; } if (_parent == null) { for (int j = 0; j < policyNodes.length; j++) { policyNodes[j] = new ArrayList(); } return null; } else { _parent.removeChild(_node); removePolicyNodeRecurse(policyNodes, _node); return validPolicyTree; } } private static void removePolicyNodeRecurse( List[] policyNodes, PKIXPolicyNode _node) { policyNodes[_node.getDepth()].remove(_node); if (_node.hasChildren()) { Iterator _iter = _node.getChildren(); while (_iter.hasNext()) { PKIXPolicyNode _child = (PKIXPolicyNode)_iter.next(); removePolicyNodeRecurse(policyNodes, _child); } } } protected static boolean processCertD1i( int index, List[] policyNodes, DERObjectIdentifier pOid, Set pq) { List policyNodeVec = policyNodes[index - 1]; for (int j = 0; j < policyNodeVec.size(); j++) { PKIXPolicyNode node = (PKIXPolicyNode)policyNodeVec.get(j); Set expectedPolicies = node.getExpectedPolicies(); if (expectedPolicies.contains(pOid.getId())) { Set childExpectedPolicies = new HashSet(); childExpectedPolicies.add(pOid.getId()); PKIXPolicyNode child = new PKIXPolicyNode(new ArrayList(), index, childExpectedPolicies, node, pq, pOid.getId(), false); node.addChild(child); policyNodes[index].add(child); return true; } } return false; } protected static void processCertD1ii( int index, List[] policyNodes, DERObjectIdentifier _poid, Set _pq) { List policyNodeVec = policyNodes[index - 1]; for (int j = 0; j < policyNodeVec.size(); j++) { PKIXPolicyNode _node = (PKIXPolicyNode)policyNodeVec.get(j); if (ANY_POLICY.equals(_node.getValidPolicy())) { Set _childExpectedPolicies = new HashSet(); _childExpectedPolicies.add(_poid.getId()); PKIXPolicyNode _child = new PKIXPolicyNode(new ArrayList(), index, _childExpectedPolicies, _node, _pq, _poid.getId(), false); _node.addChild(_child); policyNodes[index].add(_child); return; } } } protected static void prepareNextCertB1( int i, List[] policyNodes, String id_p, Map m_idp, X509Certificate cert ) throws AnnotatedException, CertPathValidatorException { boolean idp_found = false; Iterator nodes_i = policyNodes[i].iterator(); while (nodes_i.hasNext()) { PKIXPolicyNode node = (PKIXPolicyNode)nodes_i.next(); if (node.getValidPolicy().equals(id_p)) { idp_found = true; node.expectedPolicies = (Set)m_idp.get(id_p); break; } } if (!idp_found) { nodes_i = policyNodes[i].iterator(); while (nodes_i.hasNext()) { PKIXPolicyNode node = (PKIXPolicyNode)nodes_i.next(); if (ANY_POLICY.equals(node.getValidPolicy())) { Set pq = null; ASN1Sequence policies = null; try { policies = DERSequence.getInstance(getExtensionValue(cert, CERTIFICATE_POLICIES)); } catch (Exception e) { throw new AnnotatedException("Certificate policies cannot be decoded.", e); } Enumeration e = policies.getObjects(); while (e.hasMoreElements()) { PolicyInformation pinfo = null; try { pinfo = PolicyInformation.getInstance(e.nextElement()); } catch (Exception ex) { throw new AnnotatedException("Policy information cannot be decoded.", ex); } if (ANY_POLICY.equals(pinfo.getPolicyIdentifier().getId())) { try { pq = getQualifierSet(pinfo.getPolicyQualifiers()); } catch (CertPathValidatorException ex) { throw new ExtCertPathValidatorException( "Policy qualifier info set could not be built.", ex); } break; } } boolean ci = false; if (cert.getCriticalExtensionOIDs() != null) { ci = cert.getCriticalExtensionOIDs().contains(CERTIFICATE_POLICIES); } PKIXPolicyNode p_node = (PKIXPolicyNode)node.getParent(); if (ANY_POLICY.equals(p_node.getValidPolicy())) { PKIXPolicyNode c_node = new PKIXPolicyNode( new ArrayList(), i, (Set)m_idp.get(id_p), p_node, pq, id_p, ci); p_node.addChild(c_node); policyNodes[i].add(c_node); } break; } } } } protected static PKIXPolicyNode prepareNextCertB2( int i, List[] policyNodes, String id_p, PKIXPolicyNode validPolicyTree) { Iterator nodes_i = policyNodes[i].iterator(); while (nodes_i.hasNext()) { PKIXPolicyNode node = (PKIXPolicyNode)nodes_i.next(); if (node.getValidPolicy().equals(id_p)) { PKIXPolicyNode p_node = (PKIXPolicyNode)node.getParent(); p_node.removeChild(node); nodes_i.remove(); for (int k = (i - 1); k >= 0; k--) { List nodes = policyNodes[k]; for (int l = 0; l < nodes.size(); l++) { PKIXPolicyNode node2 = (PKIXPolicyNode)nodes.get(l); if (!node2.hasChildren()) { validPolicyTree = removePolicyNode(validPolicyTree, policyNodes, node2); if (validPolicyTree == null) { break; } } } } } } return validPolicyTree; } protected static boolean isAnyPolicy( Set policySet) { return policySet == null || policySet.contains(ANY_POLICY) || policySet.isEmpty(); } protected static void addAdditionalStoreFromLocation(String location, ExtendedPKIXParameters pkixParams) { } /** * Return a Collection of all certificates or attribute certificates found * in the X509Store's that are matching the certSelect criteriums. * * @param certSelect a {@link Selector} object that will be used to select * the certificates * @param certStores a List containing only {@link X509Store} objects. These * are used to search for certificates. * @return a Collection of all found {@link X509Certificate} or * {@link org.bouncycastle.x509.X509AttributeCertificate} objects. * May be empty but never null. */ protected static Collection findCertificates(X509CertStoreSelector certSelect, List certStores) throws AnnotatedException { Set certs = new HashSet(); Iterator iter = certStores.iterator(); while (iter.hasNext()) { Object obj = iter.next(); if (obj instanceof X509Store) { X509Store certStore = (X509Store)obj; try { certs.addAll(certStore.getMatches(certSelect)); } catch (StoreException e) { throw new AnnotatedException( "Problem while picking certificates from X.509 store.", e); } } else { CertStore certStore = (CertStore)obj; try { certs.addAll(certStore.getCertificates(certSelect)); } catch (CertStoreException e) { throw new AnnotatedException( "Problem while picking certificates from certificate store.", e); } } } return certs; } protected static Collection findCertificates(X509AttributeCertStoreSelector certSelect, List certStores) throws AnnotatedException { Set certs = new HashSet(); Iterator iter = certStores.iterator(); while (iter.hasNext()) { Object obj = iter.next(); if (obj instanceof X509Store) { X509Store certStore = (X509Store)obj; try { certs.addAll(certStore.getMatches(certSelect)); } catch (StoreException e) { throw new AnnotatedException( "Problem while picking certificates from X.509 store.", e); } } } return certs; } protected static void addAdditionalStoresFromCRLDistributionPoint( CRLDistPoint crldp, ExtendedPKIXParameters pkixParams) throws AnnotatedException { if (crldp != null) { DistributionPoint dps[] = null; try { dps = crldp.getDistributionPoints(); } catch (Exception e) { throw new AnnotatedException( "Distribution points could not be read.", e); } for (int i = 0; i < dps.length; i++) { DistributionPointName dpn = dps[i].getDistributionPoint(); // look for URIs in fullName if (dpn != null) { if (dpn.getType() == DistributionPointName.FULL_NAME) { GeneralName[] genNames = GeneralNames.getInstance( dpn.getName()).getNames(); // look for an URI for (int j = 0; j < genNames.length; j++) { if (genNames[j].getTagNo() == GeneralName.uniformResourceIdentifier) { String location = DERIA5String.getInstance( genNames[j].getName()).getString(); CertPathValidatorUtilities .addAdditionalStoreFromLocation(location, pkixParams); } } } } } } } /** * Add the CRL issuers from the cRLIssuer field of the distribution point or * from the certificate if not given to the issuer criterion of the * selector. *

* The issuerPrincipals are a collection with a single * X509Principal for X509Certificates. For * {@link X509AttributeCertificate}s the issuer may contain more than one * X509Principal. * * @param dp The distribution point. * @param issuerPrincipals The issuers of the certificate or attribute * certificate which contains the distribution point. * @param selector The CRL selector. * @param pkixParams The PKIX parameters containing the cert stores. * @throws AnnotatedException if an exception occurs while processing. * @throws ClassCastException if issuerPrincipals does not * contain only X509Principals. */ protected static void getCRLIssuersFromDistributionPoint( DistributionPoint dp, Collection issuerPrincipals, X509CRLSelector selector, ExtendedPKIXParameters pkixParams) throws AnnotatedException { List issuers = new ArrayList(); // indirect CRL if (dp.getCRLIssuer() != null) { GeneralName genNames[] = dp.getCRLIssuer().getNames(); // look for a DN for (int j = 0; j < genNames.length; j++) { if (genNames[j].getTagNo() == GeneralName.directoryName) { try { issuers.add(new X509Principal(genNames[j].getName() .toASN1Primitive().getEncoded())); } catch (IOException e) { throw new AnnotatedException( "CRL issuer information from distribution point cannot be decoded.", e); } } } } else { /* * certificate issuer is CRL issuer, distributionPoint field MUST be * present. */ if (dp.getDistributionPoint() == null) { throw new AnnotatedException( "CRL issuer is omitted from distribution point but no distributionPoint field present."); } // add and check issuer principals for (Iterator it = issuerPrincipals.iterator(); it.hasNext(); ) { issuers.add((X509Principal)it.next()); } } // TODO: is not found although this should correctly add the rel name. selector of Sun is buggy here or PKI test case is invalid // distributionPoint // if (dp.getDistributionPoint() != null) // { // // look for nameRelativeToCRLIssuer // if (dp.getDistributionPoint().getType() == DistributionPointName.NAME_RELATIVE_TO_CRL_ISSUER) // { // // append fragment to issuer, only one // // issuer can be there, if this is given // if (issuers.size() != 1) // { // throw new AnnotatedException( // "nameRelativeToCRLIssuer field is given but more than one CRL issuer is given."); // } // ASN1Encodable relName = dp.getDistributionPoint().getName(); // Iterator it = issuers.iterator(); // List issuersTemp = new ArrayList(issuers.size()); // while (it.hasNext()) // { // Enumeration e = null; // try // { // e = ASN1Sequence.getInstance( // new ASN1InputStream(((X500Principal) it.next()) // .getEncoded()).readObject()).getObjects(); // } // catch (IOException ex) // { // throw new AnnotatedException( // "Cannot decode CRL issuer information.", ex); // } // ASN1EncodableVector v = new ASN1EncodableVector(); // while (e.hasMoreElements()) // { // v.add((ASN1Encodable) e.nextElement()); // } // v.add(relName); // issuersTemp.add(new X500Principal(new DERSequence(v) // .getDEREncoded())); // } // issuers.clear(); // issuers.addAll(issuersTemp); // } // } Iterator it = issuers.iterator(); while (it.hasNext()) { try { selector.addIssuerName(((X509Principal)it.next()).getEncoded()); } catch (IOException ex) { throw new AnnotatedException( "Cannot decode CRL issuer information.", ex); } } } private static BigInteger getSerialNumber( Object cert) { if (cert instanceof X509Certificate) { return ((X509Certificate)cert).getSerialNumber(); } else { return ((X509AttributeCertificate)cert).getSerialNumber(); } } protected static void getCertStatus( Date validDate, X509CRL crl, Object cert, CertStatus certStatus) throws AnnotatedException { X509CRLEntry crl_entry = null; boolean isIndirect; try { isIndirect = X509CRLObject.isIndirectCRL(crl); } catch (CRLException exception) { throw new AnnotatedException("Failed check for indirect CRL.", exception); } if (isIndirect) { if (!(crl instanceof X509CRLObject)) { try { crl = new X509CRLObject(CertificateList.getInstance(crl.getEncoded())); } catch (CRLException exception) { throw new AnnotatedException("Failed to recode indirect CRL.", exception); } } crl_entry = crl.getRevokedCertificate(getSerialNumber(cert)); if (crl_entry == null) { return; } X509Principal certIssuer = ((X509CRLEntryObject)crl_entry).getCertificateIssuer(); if (certIssuer == null) { certIssuer = getIssuerPrincipal(crl); } if (!getEncodedIssuerPrincipal(cert).equals(certIssuer)) { return; } } else if (!getEncodedIssuerPrincipal(cert).equals(getIssuerPrincipal(crl))) { return; // not for our issuer, ignore } else { crl_entry = crl.getRevokedCertificate(getSerialNumber(cert)); if (crl_entry == null) { return; } } DEREnumerated reasonCode = null; if (crl_entry.hasExtensions()) { try { reasonCode = DEREnumerated .getInstance(CertPathValidatorUtilities .getExtensionValue(crl_entry, X509Extension.reasonCode.getId())); } catch (Exception e) { throw new AnnotatedException( "Reason code CRL entry extension could not be decoded.", e); } } // for reason keyCompromise, caCompromise, aACompromise or // unspecified if (!(validDate.getTime() < crl_entry.getRevocationDate().getTime()) || reasonCode == null || reasonCode.getValue().intValue() == 0 || reasonCode.getValue().intValue() == 1 || reasonCode.getValue().intValue() == 2 || reasonCode.getValue().intValue() == 8) { // (i) or (j) (1) if (reasonCode != null) { certStatus.setCertStatus(reasonCode.getValue().intValue()); } // (i) or (j) (2) else { certStatus.setCertStatus(CRLReason.unspecified); } certStatus.setRevocationDate(crl_entry.getRevocationDate()); } } /** * Fetches delta CRLs according to RFC 3280 section 5.2.4. * * @param currentDate The date for which the delta CRLs must be valid. * @param paramsPKIX The extended PKIX parameters. * @param completeCRL The complete CRL the delta CRL is for. * @return A Set of X509CRLs with delta CRLs. * @throws AnnotatedException if an exception occurs while picking the delta * CRLs. */ protected static Set getDeltaCRLs(Date currentDate, ExtendedPKIXParameters paramsPKIX, X509CRL completeCRL) throws AnnotatedException { X509CRLStoreSelector deltaSelect = new X509CRLStoreSelector(); // 5.2.4 (a) try { deltaSelect.addIssuerName(CertPathValidatorUtilities .getIssuerPrincipal(completeCRL).getEncoded()); } catch (IOException e) { throw new AnnotatedException("Cannot extract issuer from CRL.", e); } BigInteger completeCRLNumber = null; try { ASN1Primitive derObject = CertPathValidatorUtilities.getExtensionValue(completeCRL, CRL_NUMBER); if (derObject != null) { completeCRLNumber = ASN1Integer.getInstance(derObject).getPositiveValue(); } } catch (Exception e) { throw new AnnotatedException( "CRL number extension could not be extracted from CRL.", e); } // 5.2.4 (b) byte[] idp = null; try { idp = completeCRL.getExtensionValue(ISSUING_DISTRIBUTION_POINT); } catch (Exception e) { throw new AnnotatedException( "Issuing distribution point extension value could not be read.", e); } // 5.2.4 (d) deltaSelect.setMinCRLNumber(completeCRLNumber == null ? null : completeCRLNumber .add(BigInteger.valueOf(1))); deltaSelect.setIssuingDistributionPoint(idp); deltaSelect.setIssuingDistributionPointEnabled(true); // 5.2.4 (c) deltaSelect.setMaxBaseCRLNumber(completeCRLNumber); // find delta CRLs Set temp = CRL_UTIL.findCRLs(deltaSelect, paramsPKIX, currentDate); Set result = new HashSet(); for (Iterator it = temp.iterator(); it.hasNext(); ) { X509CRL crl = (X509CRL)it.next(); if (isDeltaCRL(crl)) { result.add(crl); } } return result; } private static boolean isDeltaCRL(X509CRL crl) { Set critical = crl.getCriticalExtensionOIDs(); if (critical == null) { return false; } return critical.contains(RFC3280CertPathUtilities.DELTA_CRL_INDICATOR); } /** * Fetches complete CRLs according to RFC 3280. * * @param dp The distribution point for which the complete CRL * @param cert The X509Certificate or * {@link org.bouncycastle.x509.X509AttributeCertificate} for * which the CRL should be searched. * @param currentDate The date for which the delta CRLs must be valid. * @param paramsPKIX The extended PKIX parameters. * @return A Set of X509CRLs with complete * CRLs. * @throws AnnotatedException if an exception occurs while picking the CRLs * or no CRLs are found. */ protected static Set getCompleteCRLs(DistributionPoint dp, Object cert, Date currentDate, ExtendedPKIXParameters paramsPKIX) throws AnnotatedException { X509CRLStoreSelector crlselect = new X509CRLStoreSelector(); try { Set issuers = new HashSet(); if (cert instanceof X509AttributeCertificate) { issuers.add(((X509AttributeCertificate)cert) .getIssuer().getPrincipals()[0]); } else { issuers.add(getEncodedIssuerPrincipal(cert)); } CertPathValidatorUtilities.getCRLIssuersFromDistributionPoint(dp, issuers, crlselect, paramsPKIX); } catch (AnnotatedException e) { throw new AnnotatedException( "Could not get issuer information from distribution point.", e); } if (cert instanceof X509Certificate) { crlselect.setCertificateChecking((X509Certificate)cert); } else if (cert instanceof X509AttributeCertificate) { crlselect.setAttrCertificateChecking((X509AttributeCertificate)cert); } crlselect.setCompleteCRLEnabled(true); Set crls = CRL_UTIL.findCRLs(crlselect, paramsPKIX, currentDate); if (crls.isEmpty()) { if (cert instanceof X509AttributeCertificate) { X509AttributeCertificate aCert = (X509AttributeCertificate)cert; throw new AnnotatedException("No CRLs found for issuer \"" + aCert.getIssuer().getPrincipals()[0] + "\""); } else { X509Certificate xCert = (X509Certificate)cert; throw new AnnotatedException("No CRLs found for issuer \"" + xCert.getIssuerDN() + "\""); } } return crls; } protected static Date getValidCertDateFromValidityModel( ExtendedPKIXParameters paramsPKIX, CertPath certPath, int index) throws AnnotatedException { if (paramsPKIX.getValidityModel() == ExtendedPKIXParameters.CHAIN_VALIDITY_MODEL) { // if end cert use given signing/encryption/... time if (index <= 0) { return CertPathValidatorUtilities.getValidDate(paramsPKIX); // else use time when previous cert was created } else { if (index - 1 == 0) { DERGeneralizedTime dateOfCertgen = null; try { byte[] extBytes = ((X509Certificate)certPath.getCertificates().get(index - 1)).getExtensionValue(ISISMTTObjectIdentifiers.id_isismtt_at_dateOfCertGen.getId()); if (extBytes != null) { dateOfCertgen = DERGeneralizedTime.getInstance(ASN1Primitive.fromByteArray(extBytes)); } } catch (IOException e) { throw new AnnotatedException( "Date of cert gen extension could not be read."); } catch (IllegalArgumentException e) { throw new AnnotatedException( "Date of cert gen extension could not be read."); } if (dateOfCertgen != null) { try { return dateOfCertgen.getDate(); } catch (ParseException e) { throw new AnnotatedException( "Date from date of cert gen extension could not be parsed.", e); } } return ((X509Certificate)certPath.getCertificates().get( index - 1)).getNotBefore(); } else { return ((X509Certificate)certPath.getCertificates().get( index - 1)).getNotBefore(); } } } else { return getValidDate(paramsPKIX); } } /** * Return the next working key inheriting DSA parameters if necessary. *

* This methods inherits DSA parameters from the indexed certificate or * previous certificates in the certificate chain to the returned * PublicKey. The list is searched upwards, meaning the end * certificate is at position 0 and previous certificates are following. *

*

* If the indexed certificate does not contain a DSA key this method simply * returns the public key. If the DSA key already contains DSA parameters * the key is also only returned. *

* * @param certs The certification path. * @param index The index of the certificate which contains the public key * which should be extended with DSA parameters. * @return The public key of the certificate in list position * index extended with DSA parameters if applicable. * @throws AnnotatedException if DSA parameters cannot be inherited. */ protected static PublicKey getNextWorkingKey(List certs, int index) throws CertPathValidatorException { Certificate cert = (Certificate)certs.get(index); PublicKey pubKey = cert.getPublicKey(); if (!(pubKey instanceof DSAPublicKey)) { return pubKey; } DSAPublicKey dsaPubKey = (DSAPublicKey)pubKey; if (dsaPubKey.getParams() != null) { return dsaPubKey; } for (int i = index + 1; i < certs.size(); i++) { X509Certificate parentCert = (X509Certificate)certs.get(i); pubKey = parentCert.getPublicKey(); if (!(pubKey instanceof DSAPublicKey)) { throw new CertPathValidatorException( "DSA parameters cannot be inherited from previous certificate."); } DSAPublicKey prevDSAPubKey = (DSAPublicKey)pubKey; if (prevDSAPubKey.getParams() == null) { continue; } DSAParams dsaParams = prevDSAPubKey.getParams(); DSAPublicKeySpec dsaPubKeySpec = new DSAPublicKeySpec( dsaPubKey.getY(), dsaParams.getP(), dsaParams.getQ(), dsaParams.getG()); try { KeyFactory keyFactory = KeyFactory.getInstance("DSA", BouncyCastleProvider.PROVIDER_NAME); return keyFactory.generatePublic(dsaPubKeySpec); } catch (Exception exception) { throw new RuntimeException(exception.getMessage()); } } throw new CertPathValidatorException("DSA parameters cannot be inherited from previous certificate."); } /** * Find the issuer certificates of a given certificate. * * @param cert The certificate for which an issuer should be found. * @param pkixParams * @return A Collection object containing the issuer * X509Certificates. Never null. * @throws AnnotatedException if an error occurs. */ protected static Collection findIssuerCerts( X509Certificate cert, ExtendedPKIXBuilderParameters pkixParams) throws AnnotatedException { X509CertStoreSelector certSelect = new X509CertStoreSelector(); Set certs = new HashSet(); try { certSelect.setSubject(PrincipalUtil.getSubjectX509Principal(cert).getEncoded()); } catch (Exception ex) { throw new AnnotatedException( "Subject criteria for certificate selector to find issuer certificate could not be set.", ex); } Iterator iter; try { List matches = new ArrayList(); matches.addAll(CertPathValidatorUtilities.findCertificates(certSelect, pkixParams.getCertStores())); matches.addAll(CertPathValidatorUtilities.findCertificates(certSelect, pkixParams.getStores())); matches.addAll(CertPathValidatorUtilities.findCertificates(certSelect, pkixParams.getAdditionalStores())); iter = matches.iterator(); } catch (AnnotatedException e) { throw new AnnotatedException("Issuer certificate cannot be searched.", e); } X509Certificate issuer = null; while (iter.hasNext()) { issuer = (X509Certificate)iter.next(); // issuer cannot be verified because possible DSA inheritance // parameters are missing certs.add(issuer); } return certs; } protected static void verifyX509Certificate(X509Certificate cert, PublicKey publicKey, String sigProvider) throws GeneralSecurityException { if (sigProvider == null) { cert.verify(publicKey); } else { cert.verify(publicKey, sigProvider); } } } bouncycastle-1.49.orig/jdk1.3/org/bouncycastle/jce/provider/PKIXCertPathValidatorSpi.java0000644000175000017500000003551212104173671030703 0ustar ebourgebourgpackage org.bouncycastle.jce.provider; import java.security.InvalidAlgorithmParameterException; import java.security.PublicKey; import org.bouncycastle.jce.cert.CertPath; import org.bouncycastle.jce.cert.CertPathParameters; import org.bouncycastle.jce.cert.CertPathValidatorException; import org.bouncycastle.jce.cert.CertPathValidatorResult; import org.bouncycastle.jce.cert.CertPathValidatorSpi; import org.bouncycastle.jce.cert.PKIXCertPathChecker; import org.bouncycastle.jce.cert.PKIXCertPathValidatorResult; import org.bouncycastle.jce.cert.PKIXParameters; import org.bouncycastle.jce.cert.TrustAnchor; import java.security.cert.X509Certificate; import java.util.ArrayList; import java.util.HashSet; import java.util.Iterator; import java.util.List; import java.util.Set; import org.bouncycastle.jce.X509Principal; import org.bouncycastle.asn1.ASN1Encodable; import org.bouncycastle.asn1.DERObjectIdentifier; import org.bouncycastle.asn1.x509.AlgorithmIdentifier; import org.bouncycastle.jce.exception.ExtCertPathValidatorException; import org.bouncycastle.x509.ExtendedPKIXParameters; /** * CertPathValidatorSpi implementation for X.509 Certificate validation � la RFC * 3280. */ public class PKIXCertPathValidatorSpi extends CertPathValidatorSpi { public CertPathValidatorResult engineValidate( CertPath certPath, CertPathParameters params) throws CertPathValidatorException, InvalidAlgorithmParameterException { if (!(params instanceof PKIXParameters)) { throw new InvalidAlgorithmParameterException("Parameters must be a " + PKIXParameters.class.getName() + " instance."); } ExtendedPKIXParameters paramsPKIX; if (params instanceof ExtendedPKIXParameters) { paramsPKIX = (ExtendedPKIXParameters)params; } else { paramsPKIX = ExtendedPKIXParameters.getInstance((PKIXParameters)params); } if (paramsPKIX.getTrustAnchors() == null) { throw new InvalidAlgorithmParameterException( "trustAnchors is null, this is not allowed for certification path validation."); } // // 6.1.1 - inputs // // // (a) // List certs = certPath.getCertificates(); int n = certs.size(); if (certs.isEmpty()) { throw new CertPathValidatorException("Certification path is empty.", null, certPath, 0); } // // (b) // // Date validDate = CertPathValidatorUtilities.getValidDate(paramsPKIX); // // (c) // Set userInitialPolicySet = paramsPKIX.getInitialPolicies(); // // (d) // TrustAnchor trust; try { trust = CertPathValidatorUtilities.findTrustAnchor((X509Certificate) certs.get(certs.size() - 1), paramsPKIX.getTrustAnchors(), paramsPKIX.getSigProvider()); } catch (AnnotatedException e) { throw new CertPathValidatorException(e.getMessage(), e, certPath, certs.size() - 1); } if (trust == null) { throw new CertPathValidatorException("Trust anchor for certification path not found.", null, certPath, -1); } // // (e), (f), (g) are part of the paramsPKIX object. // Iterator certIter; int index = 0; int i; // Certificate for each interation of the validation loop // Signature information for each iteration of the validation loop // // 6.1.2 - setup // // // (a) // List[] policyNodes = new ArrayList[n + 1]; for (int j = 0; j < policyNodes.length; j++) { policyNodes[j] = new ArrayList(); } Set policySet = new HashSet(); policySet.add(RFC3280CertPathUtilities.ANY_POLICY); PKIXPolicyNode validPolicyTree = new PKIXPolicyNode(new ArrayList(), 0, policySet, null, new HashSet(), RFC3280CertPathUtilities.ANY_POLICY, false); policyNodes[0].add(validPolicyTree); // // (b) and (c) // PKIXNameConstraintValidator nameConstraintValidator = new PKIXNameConstraintValidator(); // (d) // int explicitPolicy; Set acceptablePolicies = new HashSet(); if (paramsPKIX.isExplicitPolicyRequired()) { explicitPolicy = 0; } else { explicitPolicy = n + 1; } // // (e) // int inhibitAnyPolicy; if (paramsPKIX.isAnyPolicyInhibited()) { inhibitAnyPolicy = 0; } else { inhibitAnyPolicy = n + 1; } // // (f) // int policyMapping; if (paramsPKIX.isPolicyMappingInhibited()) { policyMapping = 0; } else { policyMapping = n + 1; } // // (g), (h), (i), (j) // PublicKey workingPublicKey; X509Principal workingIssuerName; X509Certificate sign = trust.getTrustedCert(); try { if (sign != null) { workingIssuerName = CertPathValidatorUtilities.getSubjectPrincipal(sign); workingPublicKey = sign.getPublicKey(); } else { workingIssuerName = new X509Principal(trust.getCAName()); workingPublicKey = trust.getCAPublicKey(); } } catch (IllegalArgumentException ex) { throw new ExtCertPathValidatorException("Subject of trust anchor could not be (re)encoded.", ex, certPath, -1); } AlgorithmIdentifier workingAlgId = null; try { workingAlgId = CertPathValidatorUtilities.getAlgorithmIdentifier(workingPublicKey); } catch (CertPathValidatorException e) { throw new ExtCertPathValidatorException( "Algorithm identifier of public key of trust anchor could not be read.", e, certPath, -1); } DERObjectIdentifier workingPublicKeyAlgorithm = workingAlgId.getObjectId(); ASN1Encodable workingPublicKeyParameters = workingAlgId.getParameters(); // // (k) // int maxPathLength = n; // // 6.1.3 // if (paramsPKIX.getTargetConstraints() != null && !paramsPKIX.getTargetConstraints().match((X509Certificate) certs.get(0))) { throw new ExtCertPathValidatorException( "Target certificate in certification path does not match targetConstraints.", null, certPath, 0); } // // initialize CertPathChecker's // List pathCheckers = paramsPKIX.getCertPathCheckers(); certIter = pathCheckers.iterator(); while (certIter.hasNext()) { ((PKIXCertPathChecker) certIter.next()).init(false); } X509Certificate cert = null; for (index = certs.size() - 1; index >= 0; index--) { // try // { // // i as defined in the algorithm description // i = n - index; // // set certificate to be checked in this round // sign and workingPublicKey and workingIssuerName are set // at the end of the for loop and initialized the // first time from the TrustAnchor // cert = (X509Certificate) certs.get(index); boolean verificationAlreadyPerformed = (index == certs.size() - 1); // // 6.1.3 // RFC3280CertPathUtilities.processCertA(certPath, paramsPKIX, index, workingPublicKey, verificationAlreadyPerformed, workingIssuerName, sign); RFC3280CertPathUtilities.processCertBC(certPath, index, nameConstraintValidator); validPolicyTree = RFC3280CertPathUtilities.processCertD(certPath, index, acceptablePolicies, validPolicyTree, policyNodes, inhibitAnyPolicy); validPolicyTree = RFC3280CertPathUtilities.processCertE(certPath, index, validPolicyTree); RFC3280CertPathUtilities.processCertF(certPath, index, validPolicyTree, explicitPolicy); // // 6.1.4 // if (i != n) { if (cert != null && cert.getVersion() == 1) { throw new CertPathValidatorException("Version 1 certificates can't be used as CA ones.", null, certPath, index); } RFC3280CertPathUtilities.prepareNextCertA(certPath, index); validPolicyTree = RFC3280CertPathUtilities.prepareCertB(certPath, index, policyNodes, validPolicyTree, policyMapping); RFC3280CertPathUtilities.prepareNextCertG(certPath, index, nameConstraintValidator); // (h) explicitPolicy = RFC3280CertPathUtilities.prepareNextCertH1(certPath, index, explicitPolicy); policyMapping = RFC3280CertPathUtilities.prepareNextCertH2(certPath, index, policyMapping); inhibitAnyPolicy = RFC3280CertPathUtilities.prepareNextCertH3(certPath, index, inhibitAnyPolicy); // // (i) // explicitPolicy = RFC3280CertPathUtilities.prepareNextCertI1(certPath, index, explicitPolicy); policyMapping = RFC3280CertPathUtilities.prepareNextCertI2(certPath, index, policyMapping); // (j) inhibitAnyPolicy = RFC3280CertPathUtilities.prepareNextCertJ(certPath, index, inhibitAnyPolicy); // (k) RFC3280CertPathUtilities.prepareNextCertK(certPath, index); // (l) maxPathLength = RFC3280CertPathUtilities.prepareNextCertL(certPath, index, maxPathLength); // (m) maxPathLength = RFC3280CertPathUtilities.prepareNextCertM(certPath, index, maxPathLength); // (n) RFC3280CertPathUtilities.prepareNextCertN(certPath, index); Set criticalExtensions = cert.getCriticalExtensionOIDs(); if (criticalExtensions != null) { criticalExtensions = new HashSet(criticalExtensions); // these extensions are handled by the algorithm criticalExtensions.remove(RFC3280CertPathUtilities.KEY_USAGE); criticalExtensions.remove(RFC3280CertPathUtilities.CERTIFICATE_POLICIES); criticalExtensions.remove(RFC3280CertPathUtilities.POLICY_MAPPINGS); criticalExtensions.remove(RFC3280CertPathUtilities.INHIBIT_ANY_POLICY); criticalExtensions.remove(RFC3280CertPathUtilities.ISSUING_DISTRIBUTION_POINT); criticalExtensions.remove(RFC3280CertPathUtilities.DELTA_CRL_INDICATOR); criticalExtensions.remove(RFC3280CertPathUtilities.POLICY_CONSTRAINTS); criticalExtensions.remove(RFC3280CertPathUtilities.BASIC_CONSTRAINTS); criticalExtensions.remove(RFC3280CertPathUtilities.SUBJECT_ALTERNATIVE_NAME); criticalExtensions.remove(RFC3280CertPathUtilities.NAME_CONSTRAINTS); } else { criticalExtensions = new HashSet(); } // (o) RFC3280CertPathUtilities.prepareNextCertO(certPath, index, criticalExtensions, pathCheckers); // set signing certificate for next round sign = cert; // (c) workingIssuerName = CertPathValidatorUtilities.getSubjectPrincipal(sign); // (d) try { workingPublicKey = CertPathValidatorUtilities.getNextWorkingKey(certPath.getCertificates(), index); } catch (CertPathValidatorException e) { throw new CertPathValidatorException("Next working key could not be retrieved.", e, certPath, index); } workingAlgId = CertPathValidatorUtilities.getAlgorithmIdentifier(workingPublicKey); // (f) workingPublicKeyAlgorithm = workingAlgId.getObjectId(); // (e) workingPublicKeyParameters = workingAlgId.getParameters(); } } // // 6.1.5 Wrap-up procedure // explicitPolicy = RFC3280CertPathUtilities.wrapupCertA(explicitPolicy, cert); explicitPolicy = RFC3280CertPathUtilities.wrapupCertB(certPath, index + 1, explicitPolicy); // // (c) (d) and (e) are already done // // // (f) // Set criticalExtensions = cert.getCriticalExtensionOIDs(); if (criticalExtensions != null) { criticalExtensions = new HashSet(criticalExtensions); // these extensions are handled by the algorithm criticalExtensions.remove(RFC3280CertPathUtilities.KEY_USAGE); criticalExtensions.remove(RFC3280CertPathUtilities.CERTIFICATE_POLICIES); criticalExtensions.remove(RFC3280CertPathUtilities.POLICY_MAPPINGS); criticalExtensions.remove(RFC3280CertPathUtilities.INHIBIT_ANY_POLICY); criticalExtensions.remove(RFC3280CertPathUtilities.ISSUING_DISTRIBUTION_POINT); criticalExtensions.remove(RFC3280CertPathUtilities.DELTA_CRL_INDICATOR); criticalExtensions.remove(RFC3280CertPathUtilities.POLICY_CONSTRAINTS); criticalExtensions.remove(RFC3280CertPathUtilities.BASIC_CONSTRAINTS); criticalExtensions.remove(RFC3280CertPathUtilities.SUBJECT_ALTERNATIVE_NAME); criticalExtensions.remove(RFC3280CertPathUtilities.NAME_CONSTRAINTS); criticalExtensions.remove(RFC3280CertPathUtilities.CRL_DISTRIBUTION_POINTS); } else { criticalExtensions = new HashSet(); } RFC3280CertPathUtilities.wrapupCertF(certPath, index + 1, pathCheckers, criticalExtensions); PKIXPolicyNode intersection = RFC3280CertPathUtilities.wrapupCertG(certPath, paramsPKIX, userInitialPolicySet, index + 1, policyNodes, validPolicyTree, acceptablePolicies); if ((explicitPolicy > 0) || (intersection != null)) { return new PKIXCertPathValidatorResult(trust, intersection, cert.getPublicKey()); } throw new CertPathValidatorException("Path processing failed on policy.", null, certPath, index); } } bouncycastle-1.49.orig/jdk1.3/org/bouncycastle/jce/provider/X509CertificateObject.java0000644000175000017500000006367112132666220030117 0ustar ebourgebourgpackage org.bouncycastle.jce.provider; import java.io.ByteArrayOutputStream; import java.io.IOException; import java.math.BigInteger; import java.net.InetAddress; import java.net.UnknownHostException; import java.security.InvalidKeyException; import java.security.NoSuchAlgorithmException; import java.security.NoSuchProviderException; import java.security.Principal; import java.security.Provider; import java.security.PublicKey; import java.security.Security; import java.security.Signature; import java.security.SignatureException; import java.security.cert.Certificate; import java.security.cert.CertificateEncodingException; import java.security.cert.CertificateException; import java.security.cert.CertificateExpiredException; import java.security.cert.CertificateNotYetValidException; import java.security.cert.CertificateParsingException; import java.security.cert.X509Certificate; import java.util.ArrayList; import java.util.Collection; import java.util.Collections; import java.util.Date; import java.util.Enumeration; import java.util.HashSet; import java.util.List; import java.util.Set; import org.bouncycastle.asn1.ASN1Encodable; import org.bouncycastle.asn1.ASN1Encoding; import org.bouncycastle.asn1.ASN1InputStream; import org.bouncycastle.asn1.ASN1ObjectIdentifier; import org.bouncycastle.asn1.ASN1OutputStream; import org.bouncycastle.asn1.ASN1Primitive; import org.bouncycastle.asn1.ASN1Sequence; import org.bouncycastle.asn1.ASN1String; import org.bouncycastle.asn1.DERBitString; import org.bouncycastle.asn1.DERIA5String; import org.bouncycastle.asn1.DERNull; import org.bouncycastle.asn1.DEROctetString; import org.bouncycastle.asn1.misc.MiscObjectIdentifiers; import org.bouncycastle.asn1.misc.NetscapeCertType; import org.bouncycastle.asn1.misc.NetscapeRevocationURL; import org.bouncycastle.asn1.misc.VerisignCzagExtension; import org.bouncycastle.asn1.util.ASN1Dump; import org.bouncycastle.asn1.x500.X500Name; import org.bouncycastle.asn1.x500.style.RFC4519Style; import org.bouncycastle.asn1.x509.AlgorithmIdentifier; import org.bouncycastle.asn1.x509.BasicConstraints; import org.bouncycastle.asn1.x509.Extension; import org.bouncycastle.asn1.x509.Extensions; import org.bouncycastle.asn1.x509.GeneralName; import org.bouncycastle.asn1.x509.KeyUsage; import org.bouncycastle.jcajce.provider.asymmetric.util.PKCS12BagAttributeCarrierImpl; import org.bouncycastle.jce.X509Principal; import org.bouncycastle.jce.provider.RFC3280CertPathUtilities; import org.bouncycastle.jce.provider.BouncyCastleProvider; import org.bouncycastle.jce.interfaces.PKCS12BagAttributeCarrier; import org.bouncycastle.util.Arrays; import org.bouncycastle.util.Integers; import org.bouncycastle.util.encoders.Hex; public class X509CertificateObject extends X509Certificate implements PKCS12BagAttributeCarrier { private org.bouncycastle.asn1.x509.Certificate c; private BasicConstraints basicConstraints; private boolean[] keyUsage; private boolean hashValueSet; private int hashValue; private PKCS12BagAttributeCarrier attrCarrier = new PKCS12BagAttributeCarrierImpl(); public X509CertificateObject( org.bouncycastle.asn1.x509.Certificate c) throws CertificateParsingException { this.c = c; try { byte[] bytes = this.getExtensionBytes("2.5.29.19"); if (bytes != null) { basicConstraints = BasicConstraints.getInstance(ASN1Primitive.fromByteArray(bytes)); } } catch (Exception e) { throw new CertificateParsingException("cannot construct BasicConstraints: " + e); } try { byte[] bytes = this.getExtensionBytes("2.5.29.15"); if (bytes != null) { DERBitString bits = DERBitString.getInstance(ASN1Primitive.fromByteArray(bytes)); bytes = bits.getBytes(); int length = (bytes.length * 8) - bits.getPadBits(); keyUsage = new boolean[(length < 9) ? 9 : length]; for (int i = 0; i != length; i++) { keyUsage[i] = (bytes[i / 8] & (0x80 >>> (i % 8))) != 0; } } else { keyUsage = null; } } catch (Exception e) { throw new CertificateParsingException("cannot construct KeyUsage: " + e); } } public void checkValidity() throws CertificateExpiredException, CertificateNotYetValidException { this.checkValidity(new Date()); } public void checkValidity( Date date) throws CertificateExpiredException, CertificateNotYetValidException { if (date.getTime() > this.getNotAfter().getTime()) // for other VM compatibility { throw new CertificateExpiredException("certificate expired on " + c.getEndDate().getTime()); } if (date.getTime() < this.getNotBefore().getTime()) { throw new CertificateNotYetValidException("certificate not valid till " + c.getStartDate().getTime()); } } public int getVersion() { return c.getVersionNumber(); } public BigInteger getSerialNumber() { return c.getSerialNumber().getValue(); } public Principal getIssuerDN() { try { return new X509Principal(X500Name.getInstance(c.getIssuer().getEncoded())); } catch (IOException e) { return null; } } public Principal getSubjectDN() { return new X509Principal(X500Name.getInstance(c.getSubject().toASN1Primitive())); } public Date getNotBefore() { return c.getStartDate().getDate(); } public Date getNotAfter() { return c.getEndDate().getDate(); } public byte[] getTBSCertificate() throws CertificateEncodingException { try { return c.getTBSCertificate().getEncoded(ASN1Encoding.DER); } catch (IOException e) { throw new CertificateEncodingException(e.toString()); } } public byte[] getSignature() { return c.getSignature().getBytes(); } /** * return a more "meaningful" representation for the signature algorithm used in * the certficate. */ public String getSigAlgName() { Provider prov = Security.getProvider(BouncyCastleProvider.PROVIDER_NAME); if (prov != null) { String algName = prov.getProperty("Alg.Alias.Signature." + this.getSigAlgOID()); if (algName != null) { return algName; } } Provider[] provs = Security.getProviders(); // // search every provider looking for a real algorithm // for (int i = 0; i != provs.length; i++) { String algName = provs[i].getProperty("Alg.Alias.Signature." + this.getSigAlgOID()); if (algName != null) { return algName; } } return this.getSigAlgOID(); } /** * return the object identifier for the signature. */ public String getSigAlgOID() { return c.getSignatureAlgorithm().getAlgorithm().getId(); } /** * return the signature parameters, or null if there aren't any. */ public byte[] getSigAlgParams() { if (c.getSignatureAlgorithm().getParameters() != null) { try { return c.getSignatureAlgorithm().getParameters().toASN1Primitive().getEncoded(ASN1Encoding.DER); } catch (IOException e) { return null; } } else { return null; } } public boolean[] getIssuerUniqueID() { DERBitString id = c.getTBSCertificate().getIssuerUniqueId(); if (id != null) { byte[] bytes = id.getBytes(); boolean[] boolId = new boolean[bytes.length * 8 - id.getPadBits()]; for (int i = 0; i != boolId.length; i++) { boolId[i] = (bytes[i / 8] & (0x80 >>> (i % 8))) != 0; } return boolId; } return null; } public boolean[] getSubjectUniqueID() { DERBitString id = c.getTBSCertificate().getSubjectUniqueId(); if (id != null) { byte[] bytes = id.getBytes(); boolean[] boolId = new boolean[bytes.length * 8 - id.getPadBits()]; for (int i = 0; i != boolId.length; i++) { boolId[i] = (bytes[i / 8] & (0x80 >>> (i % 8))) != 0; } return boolId; } return null; } public boolean[] getKeyUsage() { return keyUsage; } public List getExtendedKeyUsage() throws CertificateParsingException { byte[] bytes = this.getExtensionBytes("2.5.29.37"); if (bytes != null) { try { ASN1InputStream dIn = new ASN1InputStream(bytes); ASN1Sequence seq = (ASN1Sequence)dIn.readObject(); List list = new ArrayList(); for (int i = 0; i != seq.size(); i++) { list.add(((ASN1ObjectIdentifier)seq.getObjectAt(i)).getId()); } return Collections.unmodifiableList(list); } catch (Exception e) { throw new CertificateParsingException("error processing extended key usage extension"); } } return null; } public int getBasicConstraints() { if (basicConstraints != null) { if (basicConstraints.isCA()) { if (basicConstraints.getPathLenConstraint() == null) { return Integer.MAX_VALUE; } else { return basicConstraints.getPathLenConstraint().intValue(); } } else { return -1; } } return -1; } public Collection getSubjectAlternativeNames() throws CertificateParsingException { return getAlternativeNames(getExtensionBytes(Extension.subjectAlternativeName.getId())); } public Collection getIssuerAlternativeNames() throws CertificateParsingException { return getAlternativeNames(getExtensionBytes(Extension.issuerAlternativeName.getId())); } public Set getCriticalExtensionOIDs() { if (this.getVersion() == 3) { Set set = new HashSet(); Extensions extensions = c.getTBSCertificate().getExtensions(); if (extensions != null) { Enumeration e = extensions.oids(); while (e.hasMoreElements()) { ASN1ObjectIdentifier oid = (ASN1ObjectIdentifier)e.nextElement(); Extension ext = extensions.getExtension(oid); if (ext.isCritical()) { set.add(oid.getId()); } } return set; } } return null; } private byte[] getExtensionBytes(String oid) { Extensions exts = c.getTBSCertificate().getExtensions(); if (exts != null) { Extension ext = exts.getExtension(new ASN1ObjectIdentifier(oid)); if (ext != null) { return ext.getExtnValue().getOctets(); } } return null; } public byte[] getExtensionValue(String oid) { Extensions exts = c.getTBSCertificate().getExtensions(); if (exts != null) { Extension ext = exts.getExtension(new ASN1ObjectIdentifier(oid)); if (ext != null) { try { return ext.getExtnValue().getEncoded(); } catch (Exception e) { throw new IllegalStateException("error parsing " + e.toString()); } } } return null; } public Set getNonCriticalExtensionOIDs() { if (this.getVersion() == 3) { Set set = new HashSet(); Extensions extensions = c.getTBSCertificate().getExtensions(); if (extensions != null) { Enumeration e = extensions.oids(); while (e.hasMoreElements()) { ASN1ObjectIdentifier oid = (ASN1ObjectIdentifier)e.nextElement(); Extension ext = extensions.getExtension(oid); if (!ext.isCritical()) { set.add(oid.getId()); } } return set; } } return null; } public boolean hasUnsupportedCriticalExtension() { if (this.getVersion() == 3) { Extensions extensions = c.getTBSCertificate().getExtensions(); if (extensions != null) { Enumeration e = extensions.oids(); while (e.hasMoreElements()) { ASN1ObjectIdentifier oid = (ASN1ObjectIdentifier)e.nextElement(); String oidId = oid.getId(); if (oidId.equals(RFC3280CertPathUtilities.KEY_USAGE) || oidId.equals(RFC3280CertPathUtilities.CERTIFICATE_POLICIES) || oidId.equals(RFC3280CertPathUtilities.POLICY_MAPPINGS) || oidId.equals(RFC3280CertPathUtilities.INHIBIT_ANY_POLICY) || oidId.equals(RFC3280CertPathUtilities.CRL_DISTRIBUTION_POINTS) || oidId.equals(RFC3280CertPathUtilities.ISSUING_DISTRIBUTION_POINT) || oidId.equals(RFC3280CertPathUtilities.DELTA_CRL_INDICATOR) || oidId.equals(RFC3280CertPathUtilities.POLICY_CONSTRAINTS) || oidId.equals(RFC3280CertPathUtilities.BASIC_CONSTRAINTS) || oidId.equals(RFC3280CertPathUtilities.SUBJECT_ALTERNATIVE_NAME) || oidId.equals(RFC3280CertPathUtilities.NAME_CONSTRAINTS)) { continue; } Extension ext = extensions.getExtension(oid); if (ext.isCritical()) { return true; } } } } return false; } public PublicKey getPublicKey() { try { return BouncyCastleProvider.getPublicKey(c.getSubjectPublicKeyInfo()); } catch (IOException e) { return null; // should never happen... } } public byte[] getEncoded() throws CertificateEncodingException { try { return c.getEncoded(ASN1Encoding.DER); } catch (IOException e) { throw new CertificateEncodingException(e.toString()); } } public boolean equals( Object o) { if (o == this) { return true; } if (!(o instanceof Certificate)) { return false; } Certificate other = (Certificate)o; try { byte[] b1 = this.getEncoded(); byte[] b2 = other.getEncoded(); return Arrays.areEqual(b1, b2); } catch (CertificateEncodingException e) { return false; } } public synchronized int hashCode() { if (!hashValueSet) { hashValue = calculateHashCode(); hashValueSet = true; } return hashValue; } private int calculateHashCode() { try { int hashCode = 0; byte[] certData = this.getEncoded(); for (int i = 1; i < certData.length; i++) { hashCode += certData[i] * i; } return hashCode; } catch (CertificateEncodingException e) { return 0; } } public void setBagAttribute( ASN1ObjectIdentifier oid, ASN1Encodable attribute) { attrCarrier.setBagAttribute(oid, attribute); } public ASN1Encodable getBagAttribute( ASN1ObjectIdentifier oid) { return attrCarrier.getBagAttribute(oid); } public Enumeration getBagAttributeKeys() { return attrCarrier.getBagAttributeKeys(); } public String toString() { StringBuffer buf = new StringBuffer(); String nl = System.getProperty("line.separator"); buf.append(" [0] Version: ").append(this.getVersion()).append(nl); buf.append(" SerialNumber: ").append(this.getSerialNumber()).append(nl); buf.append(" IssuerDN: ").append(this.getIssuerDN()).append(nl); buf.append(" Start Date: ").append(this.getNotBefore()).append(nl); buf.append(" Final Date: ").append(this.getNotAfter()).append(nl); buf.append(" SubjectDN: ").append(this.getSubjectDN()).append(nl); buf.append(" Public Key: ").append(this.getPublicKey()).append(nl); buf.append(" Signature Algorithm: ").append(this.getSigAlgName()).append(nl); byte[] sig = this.getSignature(); buf.append(" Signature: ").append(new String(Hex.encode(sig, 0, 20))).append(nl); for (int i = 20; i < sig.length; i += 20) { if (i < sig.length - 20) { buf.append(" ").append(new String(Hex.encode(sig, i, 20))).append(nl); } else { buf.append(" ").append(new String(Hex.encode(sig, i, sig.length - i))).append(nl); } } Extensions extensions = c.getTBSCertificate().getExtensions(); if (extensions != null) { Enumeration e = extensions.oids(); if (e.hasMoreElements()) { buf.append(" Extensions: \n"); } while (e.hasMoreElements()) { ASN1ObjectIdentifier oid = (ASN1ObjectIdentifier)e.nextElement(); Extension ext = extensions.getExtension(oid); if (ext.getExtnValue() != null) { byte[] octs = ext.getExtnValue().getOctets(); ASN1InputStream dIn = new ASN1InputStream(octs); buf.append(" critical(").append(ext.isCritical()).append(") "); try { if (oid.equals(Extension.basicConstraints)) { buf.append(BasicConstraints.getInstance(dIn.readObject())).append(nl); } else if (oid.equals(Extension.keyUsage)) { buf.append(KeyUsage.getInstance(dIn.readObject())).append(nl); } else if (oid.equals(MiscObjectIdentifiers.netscapeCertType)) { buf.append(new NetscapeCertType((DERBitString)dIn.readObject())).append(nl); } else if (oid.equals(MiscObjectIdentifiers.netscapeRevocationURL)) { buf.append(new NetscapeRevocationURL((DERIA5String)dIn.readObject())).append(nl); } else if (oid.equals(MiscObjectIdentifiers.verisignCzagExtension)) { buf.append(new VerisignCzagExtension((DERIA5String)dIn.readObject())).append(nl); } else { buf.append(oid.getId()); buf.append(" value = ").append(ASN1Dump.dumpAsString(dIn.readObject())).append(nl); //buf.append(" value = ").append("*****").append(nl); } } catch (Exception ex) { buf.append(oid.getId()); // buf.append(" value = ").append(new String(Hex.encode(ext.getExtnValue().getOctets()))).append(nl); buf.append(" value = ").append("*****").append(nl); } } else { buf.append(nl); } } } return buf.toString(); } public final void verify( PublicKey key) throws CertificateException, NoSuchAlgorithmException, InvalidKeyException, NoSuchProviderException, SignatureException { Signature signature; String sigName = X509SignatureUtil.getSignatureName(c.getSignatureAlgorithm()); try { signature = Signature.getInstance(sigName, BouncyCastleProvider.PROVIDER_NAME); } catch (Exception e) { signature = Signature.getInstance(sigName); } checkSignature(key, signature); } public final void verify( PublicKey key, String sigProvider) throws CertificateException, NoSuchAlgorithmException, InvalidKeyException, NoSuchProviderException, SignatureException { String sigName = X509SignatureUtil.getSignatureName(c.getSignatureAlgorithm()); Signature signature = Signature.getInstance(sigName, sigProvider); checkSignature(key, signature); } private void checkSignature( PublicKey key, Signature signature) throws CertificateException, NoSuchAlgorithmException, SignatureException, InvalidKeyException { if (!isAlgIdEqual(c.getSignatureAlgorithm(), c.getTBSCertificate().getSignature())) { throw new CertificateException("signature algorithm in TBS cert not same as outer cert"); } ASN1Encodable params = c.getSignatureAlgorithm().getParameters(); // TODO This should go after the initVerify? X509SignatureUtil.setSignatureParameters(signature, params); signature.initVerify(key); signature.update(this.getTBSCertificate()); if (!signature.verify(this.getSignature())) { throw new SignatureException("certificate does not verify with supplied key"); } } private boolean isAlgIdEqual(AlgorithmIdentifier id1, AlgorithmIdentifier id2) { if (!id1.getAlgorithm().equals(id2.getAlgorithm())) { return false; } if (id1.getParameters() == null) { if (id2.getParameters() != null && !id2.getParameters().equals(DERNull.INSTANCE)) { return false; } return true; } if (id2.getParameters() == null) { if (id1.getParameters() != null && !id1.getParameters().equals(DERNull.INSTANCE)) { return false; } return true; } return id1.getParameters().equals(id2.getParameters()); } private static Collection getAlternativeNames(byte[] extVal) throws CertificateParsingException { if (extVal == null) { return null; } try { Collection temp = new ArrayList(); Enumeration it = ASN1Sequence.getInstance(extVal).getObjects(); while (it.hasMoreElements()) { GeneralName genName = GeneralName.getInstance(it.nextElement()); List list = new ArrayList(); list.add(Integers.valueOf(genName.getTagNo())); switch (genName.getTagNo()) { case GeneralName.ediPartyName: case GeneralName.x400Address: case GeneralName.otherName: list.add(genName.getEncoded()); break; case GeneralName.directoryName: list.add(X500Name.getInstance(RFC4519Style.INSTANCE, genName.getName()).toString()); break; case GeneralName.dNSName: case GeneralName.rfc822Name: case GeneralName.uniformResourceIdentifier: list.add(((ASN1String)genName.getName()).getString()); break; case GeneralName.registeredID: list.add(ASN1ObjectIdentifier.getInstance(genName.getName()).getId()); break; case GeneralName.iPAddress: byte[] addrBytes = DEROctetString.getInstance(genName.getName()).getOctets(); list.add(addrBytes); break; default: throw new IOException("Bad tag number: " + genName.getTagNo()); } temp.add(list); } if (temp.size() == 0) { return null; } return Collections.unmodifiableCollection(temp); } catch (Exception e) { throw new CertificateParsingException(e.getMessage()); } } } bouncycastle-1.49.orig/jdk1.3/org/bouncycastle/jce/provider/CertStoreCollectionSpi.java0000644000175000017500000000540310604446274030556 0ustar ebourgebourgpackage org.bouncycastle.jce.provider; import java.security.InvalidAlgorithmParameterException; import java.security.cert.CRL; import org.bouncycastle.jce.cert.CRLSelector; import org.bouncycastle.jce.cert.CertSelector; import org.bouncycastle.jce.cert.CertStoreException; import org.bouncycastle.jce.cert.CertStoreParameters; import org.bouncycastle.jce.cert.CertStoreSpi; import java.security.cert.Certificate; import org.bouncycastle.jce.cert.CollectionCertStoreParameters; import java.util.ArrayList; import java.util.Collection; import java.util.Iterator; import java.util.List; public class CertStoreCollectionSpi extends CertStoreSpi { private CollectionCertStoreParameters params; public CertStoreCollectionSpi(CertStoreParameters params) throws InvalidAlgorithmParameterException { super(params); if (!(params instanceof CollectionCertStoreParameters)) { throw new InvalidAlgorithmParameterException("org.bouncycastle.jce.provider.CertStoreCollectionSpi: parameter must be a CollectionCertStoreParameters object\n" + params.toString()); } this.params = (CollectionCertStoreParameters)params; } public Collection engineGetCertificates( CertSelector selector) throws CertStoreException { List col = new ArrayList(); Iterator iter = params.getCollection().iterator(); if (selector == null) { while (iter.hasNext()) { Object obj = iter.next(); if (obj instanceof Certificate) { col.add(obj); } } } else { while (iter.hasNext()) { Object obj = iter.next(); if ((obj instanceof Certificate) && selector.match((Certificate)obj)) { col.add(obj); } } } return col; } public Collection engineGetCRLs( CRLSelector selector) throws CertStoreException { List col = new ArrayList(); Iterator iter = params.getCollection().iterator(); if (selector == null) { while (iter.hasNext()) { Object obj = iter.next(); if (obj instanceof CRL) { col.add(obj); } } } else { while (iter.hasNext()) { Object obj = iter.next(); if ((obj instanceof CRL) && selector.match((CRL)obj)) { col.add(obj); } } } return col; } } bouncycastle-1.49.orig/jdk1.3/org/bouncycastle/jce/provider/RFC3280CertPathUtilities.java0000644000175000017500000027111412132666220030427 0ustar ebourgebourgpackage org.bouncycastle.jce.provider; import java.io.IOException; import java.math.BigInteger; import java.security.GeneralSecurityException; import java.security.PublicKey; import org.bouncycastle.jce.cert.CertPath; import org.bouncycastle.jce.cert.CertPathBuilder; import org.bouncycastle.jce.cert.CertPathBuilderException; import org.bouncycastle.jce.cert.CertPathValidatorException; import java.security.cert.CertificateExpiredException; import java.security.cert.CertificateNotYetValidException; import org.bouncycastle.jce.cert.PKIXCertPathChecker; import java.security.cert.CRLException; import java.security.cert.X509CRL; import java.security.cert.X509Certificate; import java.security.cert.X509Extension; import java.util.ArrayList; import java.util.Collection; import java.util.Date; import java.util.Enumeration; import java.util.HashMap; import java.util.HashSet; import java.util.Iterator; import java.util.List; import java.util.Map; import java.util.Set; import java.util.Vector; import org.bouncycastle.asn1.ASN1Encodable; import org.bouncycastle.asn1.ASN1EncodableVector; import org.bouncycastle.asn1.ASN1InputStream; import org.bouncycastle.asn1.ASN1Primitive; import org.bouncycastle.asn1.ASN1Sequence; import org.bouncycastle.asn1.ASN1TaggedObject; import org.bouncycastle.asn1.DERInteger; import org.bouncycastle.asn1.DERObjectIdentifier; import org.bouncycastle.asn1.DERSequence; import org.bouncycastle.asn1.x509.BasicConstraints; import org.bouncycastle.asn1.x509.CRLDistPoint; import org.bouncycastle.asn1.x509.CRLReason; import org.bouncycastle.asn1.x509.DistributionPoint; import org.bouncycastle.asn1.x509.DistributionPointName; import org.bouncycastle.asn1.x509.GeneralName; import org.bouncycastle.asn1.x509.GeneralNames; import org.bouncycastle.asn1.x509.GeneralSubtree; import org.bouncycastle.asn1.x509.IssuingDistributionPoint; import org.bouncycastle.asn1.x509.NameConstraints; import org.bouncycastle.asn1.x509.PolicyInformation; import org.bouncycastle.asn1.x509.X509Extensions; import org.bouncycastle.asn1.x509.X509Name; import org.bouncycastle.jce.exception.ExtCertPathValidatorException; import org.bouncycastle.jce.X509Principal; import org.bouncycastle.jce.PrincipalUtil; import org.bouncycastle.util.Arrays; import org.bouncycastle.x509.ExtendedPKIXBuilderParameters; import org.bouncycastle.x509.ExtendedPKIXParameters; import org.bouncycastle.x509.X509CRLStoreSelector; import org.bouncycastle.x509.X509CertStoreSelector; public class RFC3280CertPathUtilities { private static final PKIXCRLUtil CRL_UTIL = new PKIXCRLUtil(); /** * If the complete CRL includes an issuing distribution point (IDP) CRL * extension check the following: *

* (i) If the distribution point name is present in the IDP CRL extension * and the distribution field is present in the DP, then verify that one of * the names in the IDP matches one of the names in the DP. If the * distribution point name is present in the IDP CRL extension and the * distribution field is omitted from the DP, then verify that one of the * names in the IDP matches one of the names in the cRLIssuer field of the * DP. *

*

* (ii) If the onlyContainsUserCerts boolean is asserted in the IDP CRL * extension, verify that the certificate does not include the basic * constraints extension with the cA boolean asserted. *

*

* (iii) If the onlyContainsCACerts boolean is asserted in the IDP CRL * extension, verify that the certificate includes the basic constraints * extension with the cA boolean asserted. *

*

* (iv) Verify that the onlyContainsAttributeCerts boolean is not asserted. *

* * @param dp The distribution point. * @param cert The certificate. * @param crl The CRL. * @throws AnnotatedException if one of the conditions is not met or an error occurs. */ protected static void processCRLB2( DistributionPoint dp, Object cert, X509CRL crl) throws AnnotatedException { IssuingDistributionPoint idp = null; try { idp = IssuingDistributionPoint.getInstance(CertPathValidatorUtilities.getExtensionValue(crl, RFC3280CertPathUtilities.ISSUING_DISTRIBUTION_POINT)); } catch (Exception e) { throw new AnnotatedException("Issuing distribution point extension could not be decoded.", e); } // (b) (2) (i) // distribution point name is present if (idp != null) { if (idp.getDistributionPoint() != null) { // make list of names DistributionPointName dpName = IssuingDistributionPoint.getInstance(idp).getDistributionPoint(); List names = new ArrayList(); if (dpName.getType() == DistributionPointName.FULL_NAME) { GeneralName[] genNames = GeneralNames.getInstance(dpName.getName()).getNames(); for (int j = 0; j < genNames.length; j++) { names.add(genNames[j]); } } if (dpName.getType() == DistributionPointName.NAME_RELATIVE_TO_CRL_ISSUER) { ASN1EncodableVector vec = new ASN1EncodableVector(); try { Enumeration e = ASN1Sequence.getInstance( ASN1Sequence.fromByteArray(CertPathValidatorUtilities.getIssuerPrincipal(crl) .getEncoded())).getObjects(); while (e.hasMoreElements()) { vec.add((ASN1Encodable)e.nextElement()); } } catch (IOException e) { throw new AnnotatedException("Could not read CRL issuer.", e); } vec.add(dpName.getName()); names.add(new GeneralName(X509Name.getInstance(new DERSequence(vec)))); } boolean matches = false; // verify that one of the names in the IDP matches one // of the names in the DP. if (dp.getDistributionPoint() != null) { dpName = dp.getDistributionPoint(); GeneralName[] genNames = null; if (dpName.getType() == DistributionPointName.FULL_NAME) { genNames = GeneralNames.getInstance(dpName.getName()).getNames(); } if (dpName.getType() == DistributionPointName.NAME_RELATIVE_TO_CRL_ISSUER) { if (dp.getCRLIssuer() != null) { genNames = dp.getCRLIssuer().getNames(); } else { genNames = new GeneralName[1]; try { genNames[0] = new GeneralName(new X509Name( (ASN1Sequence)ASN1Sequence.fromByteArray(CertPathValidatorUtilities .getEncodedIssuerPrincipal(cert).getEncoded()))); } catch (IOException e) { throw new AnnotatedException("Could not read certificate issuer.", e); } } for (int j = 0; j < genNames.length; j++) { Enumeration e = ASN1Sequence.getInstance(genNames[j].getName().toASN1Primitive()).getObjects(); ASN1EncodableVector vec = new ASN1EncodableVector(); while (e.hasMoreElements()) { vec.add((ASN1Encodable)e.nextElement()); } vec.add(dpName.getName()); genNames[j] = new GeneralName(new X509Name(new DERSequence(vec))); } } if (genNames != null) { for (int j = 0; j < genNames.length; j++) { if (names.contains(genNames[j])) { matches = true; break; } } } if (!matches) { throw new AnnotatedException( "No match for certificate CRL issuing distribution point name to cRLIssuer CRL distribution point."); } } // verify that one of the names in // the IDP matches one of the names in the cRLIssuer field of // the DP else { if (dp.getCRLIssuer() == null) { throw new AnnotatedException("Either the cRLIssuer or the distributionPoint field must " + "be contained in DistributionPoint."); } GeneralName[] genNames = dp.getCRLIssuer().getNames(); for (int j = 0; j < genNames.length; j++) { if (names.contains(genNames[j])) { matches = true; break; } } if (!matches) { throw new AnnotatedException( "No match for certificate CRL issuing distribution point name to cRLIssuer CRL distribution point."); } } } BasicConstraints bc = null; try { bc = BasicConstraints.getInstance(CertPathValidatorUtilities.getExtensionValue((X509Extension)cert, BASIC_CONSTRAINTS)); } catch (Exception e) { throw new AnnotatedException("Basic constraints extension could not be decoded.", e); } if (cert instanceof X509Certificate) { // (b) (2) (ii) if (idp.onlyContainsUserCerts() && (bc != null && bc.isCA())) { throw new AnnotatedException("CA Cert CRL only contains user certificates."); } // (b) (2) (iii) if (idp.onlyContainsCACerts() && (bc == null || !bc.isCA())) { throw new AnnotatedException("End CRL only contains CA certificates."); } } // (b) (2) (iv) if (idp.onlyContainsAttributeCerts()) { throw new AnnotatedException("onlyContainsAttributeCerts boolean is asserted."); } } } /** * If the DP includes cRLIssuer, then verify that the issuer field in the * complete CRL matches cRLIssuer in the DP and that the complete CRL * contains an issuing distribution point extension with the indirectCRL * boolean asserted. Otherwise, verify that the CRL issuer matches the * certificate issuer. * * @param dp The distribution point. * @param cert The certificate ot attribute certificate. * @param crl The CRL for cert. * @throws AnnotatedException if one of the above conditions does not apply or an error * occurs. */ protected static void processCRLB1( DistributionPoint dp, Object cert, X509CRL crl) throws AnnotatedException { ASN1Primitive idp = CertPathValidatorUtilities.getExtensionValue(crl, ISSUING_DISTRIBUTION_POINT); boolean isIndirect = false; if (idp != null) { if (IssuingDistributionPoint.getInstance(idp).isIndirectCRL()) { isIndirect = true; } } byte[] issuerBytes = CertPathValidatorUtilities.getIssuerPrincipal(crl).getEncoded(); boolean matchIssuer = false; if (dp.getCRLIssuer() != null) { GeneralName genNames[] = dp.getCRLIssuer().getNames(); for (int j = 0; j < genNames.length; j++) { if (genNames[j].getTagNo() == GeneralName.directoryName) { try { if (Arrays.areEqual(genNames[j].getName().toASN1Primitive().getEncoded(), issuerBytes)) { matchIssuer = true; } } catch (IOException e) { throw new AnnotatedException( "CRL issuer information from distribution point cannot be decoded.", e); } } } if (matchIssuer && !isIndirect) { throw new AnnotatedException("Distribution point contains cRLIssuer field but CRL is not indirect."); } if (!matchIssuer) { throw new AnnotatedException("CRL issuer of CRL does not match CRL issuer of distribution point."); } } else { if (CertPathValidatorUtilities.getIssuerPrincipal(crl).equals( CertPathValidatorUtilities.getEncodedIssuerPrincipal(cert))) { matchIssuer = true; } } if (!matchIssuer) { throw new AnnotatedException("Cannot find matching CRL issuer for certificate."); } } protected static ReasonsMask processCRLD( X509CRL crl, DistributionPoint dp) throws AnnotatedException { IssuingDistributionPoint idp = null; try { idp = IssuingDistributionPoint.getInstance(CertPathValidatorUtilities.getExtensionValue(crl, RFC3280CertPathUtilities.ISSUING_DISTRIBUTION_POINT)); } catch (Exception e) { throw new AnnotatedException("Issuing distribution point extension could not be decoded.", e); } // (d) (1) if (idp != null && idp.getOnlySomeReasons() != null && dp.getReasons() != null) { return new ReasonsMask(dp.getReasons()).intersect(new ReasonsMask(idp.getOnlySomeReasons())); } // (d) (4) if ((idp == null || idp.getOnlySomeReasons() == null) && dp.getReasons() == null) { return ReasonsMask.allReasons; } // (d) (2) and (d)(3) return (dp.getReasons() == null ? ReasonsMask.allReasons : new ReasonsMask(dp.getReasons())).intersect(idp == null ? ReasonsMask.allReasons : new ReasonsMask(idp.getOnlySomeReasons())); } public static final String CERTIFICATE_POLICIES = X509Extensions.CertificatePolicies.getId(); public static final String POLICY_MAPPINGS = X509Extensions.PolicyMappings.getId(); public static final String INHIBIT_ANY_POLICY = X509Extensions.InhibitAnyPolicy.getId(); public static final String ISSUING_DISTRIBUTION_POINT = X509Extensions.IssuingDistributionPoint.getId(); public static final String FRESHEST_CRL = X509Extensions.FreshestCRL.getId(); public static final String DELTA_CRL_INDICATOR = X509Extensions.DeltaCRLIndicator.getId(); public static final String POLICY_CONSTRAINTS = X509Extensions.PolicyConstraints.getId(); public static final String BASIC_CONSTRAINTS = X509Extensions.BasicConstraints.getId(); public static final String CRL_DISTRIBUTION_POINTS = X509Extensions.CRLDistributionPoints.getId(); public static final String SUBJECT_ALTERNATIVE_NAME = X509Extensions.SubjectAlternativeName.getId(); public static final String NAME_CONSTRAINTS = X509Extensions.NameConstraints.getId(); public static final String AUTHORITY_KEY_IDENTIFIER = X509Extensions.AuthorityKeyIdentifier.getId(); public static final String KEY_USAGE = X509Extensions.KeyUsage.getId(); public static final String CRL_NUMBER = X509Extensions.CRLNumber.getId(); public static final String ANY_POLICY = "2.5.29.32.0"; /* * key usage bits */ protected static final int KEY_CERT_SIGN = 5; protected static final int CRL_SIGN = 6; /** * Obtain and validate the certification path for the complete CRL issuer. * If a key usage extension is present in the CRL issuer's certificate, * verify that the cRLSign bit is set. * * @param crl CRL which contains revocation information for the certificate * cert. * @param cert The attribute certificate or certificate to check if it is * revoked. * @param defaultCRLSignCert The issuer certificate of the certificate cert. * @param defaultCRLSignKey The public key of the issuer certificate * defaultCRLSignCert. * @param paramsPKIX paramsPKIX PKIX parameters. * @param certPathCerts The certificates on the certification path. * @return A Set with all keys of possible CRL issuer * certificates. * @throws AnnotatedException if the CRL is not valid or the status cannot be checked or * some error occurs. */ protected static Set processCRLF( X509CRL crl, Object cert, X509Certificate defaultCRLSignCert, PublicKey defaultCRLSignKey, ExtendedPKIXParameters paramsPKIX, List certPathCerts) throws AnnotatedException { // (f) // get issuer from CRL X509CertStoreSelector selector = new X509CertStoreSelector(); try { byte[] issuerPrincipal = CertPathValidatorUtilities.getIssuerPrincipal(crl).getEncoded(); selector.setSubject(issuerPrincipal); } catch (IOException e) { throw new AnnotatedException( "Subject criteria for certificate selector to find issuer certificate for CRL could not be set.", e); } // get CRL signing certs Collection coll; try { coll = CertPathValidatorUtilities.findCertificates(selector, paramsPKIX.getStores()); coll.addAll(CertPathValidatorUtilities.findCertificates(selector, paramsPKIX.getAdditionalStores())); coll.addAll(CertPathValidatorUtilities.findCertificates(selector, paramsPKIX.getCertStores())); } catch (AnnotatedException e) { throw new AnnotatedException("Issuer certificate for CRL cannot be searched.", e); } coll.add(defaultCRLSignCert); Iterator cert_it = coll.iterator(); List validCerts = new ArrayList(); List validKeys = new ArrayList(); while (cert_it.hasNext()) { X509Certificate signingCert = (X509Certificate)cert_it.next(); /* * CA of the certificate, for which this CRL is checked, has also * signed CRL, so skip the path validation, because is already done */ if (signingCert.equals(defaultCRLSignCert)) { validCerts.add(signingCert); validKeys.add(defaultCRLSignKey); continue; } try { CertPathBuilder builder = CertPathBuilder.getInstance("PKIX", BouncyCastleProvider.PROVIDER_NAME); selector = new X509CertStoreSelector(); selector.setCertificate(signingCert); ExtendedPKIXParameters temp = (ExtendedPKIXParameters)paramsPKIX.clone(); temp.setTargetCertConstraints(selector); ExtendedPKIXBuilderParameters params = (ExtendedPKIXBuilderParameters)ExtendedPKIXBuilderParameters .getInstance(temp); /* * if signingCert is placed not higher on the cert path a * dependency loop results. CRL for cert is checked, but * signingCert is needed for checking the CRL which is dependent * on checking cert because it is higher in the cert path and so * signing signingCert transitively. so, revocation is disabled, * forgery attacks of the CRL are detected in this outer loop * for all other it must be enabled to prevent forgery attacks */ if (certPathCerts.contains(signingCert)) { params.setRevocationEnabled(false); } else { params.setRevocationEnabled(true); } List certs = builder.build(params).getCertPath().getCertificates(); validCerts.add(signingCert); validKeys.add(CertPathValidatorUtilities.getNextWorkingKey(certs, 0)); } catch (CertPathBuilderException e) { throw new AnnotatedException("Internal error.", e); } catch (CertPathValidatorException e) { throw new AnnotatedException("Public key of issuer certificate of CRL could not be retrieved.", e); } catch (Exception e) { throw new RuntimeException(e.getMessage()); } } Set checkKeys = new HashSet(); AnnotatedException lastException = null; for (int i = 0; i < validCerts.size(); i++) { X509Certificate signCert = (X509Certificate)validCerts.get(i); boolean[] keyusage = signCert.getKeyUsage(); if (keyusage != null && (keyusage.length < 7 || !keyusage[CRL_SIGN])) { lastException = new AnnotatedException( "Issuer certificate key usage extension does not permit CRL signing."); } else { checkKeys.add(validKeys.get(i)); } } if (checkKeys.isEmpty() && lastException == null) { throw new AnnotatedException("Cannot find a valid issuer certificate."); } if (checkKeys.isEmpty() && lastException != null) { throw lastException; } return checkKeys; } protected static PublicKey processCRLG( X509CRL crl, Set keys) throws AnnotatedException { Exception lastException = null; for (Iterator it = keys.iterator(); it.hasNext();) { PublicKey key = (PublicKey)it.next(); try { crl.verify(key); return key; } catch (Exception e) { lastException = e; } } throw new AnnotatedException("Cannot verify CRL.", lastException); } protected static X509CRL processCRLH( Set deltacrls, PublicKey key) throws AnnotatedException { Exception lastException = null; for (Iterator it = deltacrls.iterator(); it.hasNext();) { X509CRL crl = (X509CRL)it.next(); try { crl.verify(key); return crl; } catch (Exception e) { lastException = e; } } if (lastException != null) { throw new AnnotatedException("Cannot verify delta CRL.", lastException); } return null; } protected static Set processCRLA1i( Date currentDate, ExtendedPKIXParameters paramsPKIX, X509Certificate cert, X509CRL crl) throws AnnotatedException { Set set = new HashSet(); if (paramsPKIX.isUseDeltasEnabled()) { CRLDistPoint freshestCRL = null; try { freshestCRL = CRLDistPoint .getInstance(CertPathValidatorUtilities.getExtensionValue(cert, FRESHEST_CRL)); } catch (AnnotatedException e) { throw new AnnotatedException("Freshest CRL extension could not be decoded from certificate.", e); } if (freshestCRL == null) { try { freshestCRL = CRLDistPoint.getInstance(CertPathValidatorUtilities.getExtensionValue(crl, FRESHEST_CRL)); } catch (AnnotatedException e) { throw new AnnotatedException("Freshest CRL extension could not be decoded from CRL.", e); } } if (freshestCRL != null) { try { CertPathValidatorUtilities.addAdditionalStoresFromCRLDistributionPoint(freshestCRL, paramsPKIX); } catch (AnnotatedException e) { throw new AnnotatedException( "No new delta CRL locations could be added from Freshest CRL extension.", e); } // get delta CRL(s) try { set.addAll(CertPathValidatorUtilities.getDeltaCRLs(currentDate, paramsPKIX, crl)); } catch (AnnotatedException e) { throw new AnnotatedException("Exception obtaining delta CRLs.", e); } } } return set; } protected static Set[] processCRLA1ii( Date currentDate, ExtendedPKIXParameters paramsPKIX, X509Certificate cert, X509CRL crl) throws AnnotatedException { Set deltaSet = new HashSet(); X509CRLStoreSelector crlselect = new X509CRLStoreSelector(); crlselect.setCertificateChecking(cert); try { crlselect.addIssuerName(PrincipalUtil.getIssuerX509Principal(crl).getEncoded()); } catch (CRLException e) { throw new AnnotatedException("Cannot extract issuer from CRL." + e, e); } catch (IOException e) { throw new AnnotatedException("Cannot extract issuer from CRL." + e, e); } crlselect.setCompleteCRLEnabled(true); Set completeSet = CRL_UTIL.findCRLs(crlselect, paramsPKIX, currentDate); if (paramsPKIX.isUseDeltasEnabled()) { // get delta CRL(s) try { deltaSet.addAll(CertPathValidatorUtilities.getDeltaCRLs(currentDate, paramsPKIX, crl)); } catch (AnnotatedException e) { throw new AnnotatedException("Exception obtaining delta CRLs.", e); } } return new Set[] { completeSet, deltaSet}; } /** * If use-deltas is set, verify the issuer and scope of the delta CRL. * * @param deltaCRL The delta CRL. * @param completeCRL The complete CRL. * @param pkixParams The PKIX paramaters. * @throws AnnotatedException if an exception occurs. */ protected static void processCRLC( X509CRL deltaCRL, X509CRL completeCRL, ExtendedPKIXParameters pkixParams) throws AnnotatedException { if (deltaCRL == null) { return; } IssuingDistributionPoint completeidp = null; try { completeidp = IssuingDistributionPoint.getInstance(CertPathValidatorUtilities.getExtensionValue( completeCRL, RFC3280CertPathUtilities.ISSUING_DISTRIBUTION_POINT)); } catch (Exception e) { throw new AnnotatedException("Issuing distribution point extension could not be decoded.", e); } if (pkixParams.isUseDeltasEnabled()) { // (c) (1) try { if (!PrincipalUtil.getIssuerX509Principal(deltaCRL).equals(PrincipalUtil.getIssuerX509Principal(completeCRL))) { throw new AnnotatedException("Complete CRL issuer does not match delta CRL issuer."); } } catch (CRLException e) { throw new AnnotatedException( "Cannot extract issuer from CRL.", e); } // (c) (2) IssuingDistributionPoint deltaidp = null; try { deltaidp = IssuingDistributionPoint.getInstance(CertPathValidatorUtilities.getExtensionValue( deltaCRL, ISSUING_DISTRIBUTION_POINT)); } catch (Exception e) { throw new AnnotatedException( "Issuing distribution point extension from delta CRL could not be decoded.", e); } boolean match = false; if (completeidp == null) { if (deltaidp == null) { match = true; } } else { if (completeidp.equals(deltaidp)) { match = true; } } if (!match) { throw new AnnotatedException( "Issuing distribution point extension from delta CRL and complete CRL does not match."); } // (c) (3) ASN1Primitive completeKeyIdentifier = null; try { completeKeyIdentifier = CertPathValidatorUtilities.getExtensionValue( completeCRL, AUTHORITY_KEY_IDENTIFIER); } catch (AnnotatedException e) { throw new AnnotatedException( "Authority key identifier extension could not be extracted from complete CRL.", e); } ASN1Primitive deltaKeyIdentifier = null; try { deltaKeyIdentifier = CertPathValidatorUtilities.getExtensionValue( deltaCRL, AUTHORITY_KEY_IDENTIFIER); } catch (AnnotatedException e) { throw new AnnotatedException( "Authority key identifier extension could not be extracted from delta CRL.", e); } if (completeKeyIdentifier == null) { throw new AnnotatedException("CRL authority key identifier is null."); } if (deltaKeyIdentifier == null) { throw new AnnotatedException("Delta CRL authority key identifier is null."); } if (!completeKeyIdentifier.equals(deltaKeyIdentifier)) { throw new AnnotatedException( "Delta CRL authority key identifier does not match complete CRL authority key identifier."); } } } protected static void processCRLI( Date validDate, X509CRL deltacrl, Object cert, CertStatus certStatus, ExtendedPKIXParameters pkixParams) throws AnnotatedException { if (pkixParams.isUseDeltasEnabled() && deltacrl != null) { CertPathValidatorUtilities.getCertStatus(validDate, deltacrl, cert, certStatus); } } protected static void processCRLJ( Date validDate, X509CRL completecrl, Object cert, CertStatus certStatus) throws AnnotatedException { if (certStatus.getCertStatus() == CertStatus.UNREVOKED) { CertPathValidatorUtilities.getCertStatus(validDate, completecrl, cert, certStatus); } } protected static PKIXPolicyNode prepareCertB( CertPath certPath, int index, List[] policyNodes, PKIXPolicyNode validPolicyTree, int policyMapping) throws CertPathValidatorException { List certs = certPath.getCertificates(); X509Certificate cert = (X509Certificate)certs.get(index); int n = certs.size(); // i as defined in the algorithm description int i = n - index; // (b) // ASN1Sequence pm = null; try { pm = DERSequence.getInstance(CertPathValidatorUtilities.getExtensionValue(cert, RFC3280CertPathUtilities.POLICY_MAPPINGS)); } catch (AnnotatedException ex) { throw new ExtCertPathValidatorException("Policy mappings extension could not be decoded.", ex, certPath, index); } PKIXPolicyNode _validPolicyTree = validPolicyTree; if (pm != null) { ASN1Sequence mappings = (ASN1Sequence)pm; Map m_idp = new HashMap(); Set s_idp = new HashSet(); for (int j = 0; j < mappings.size(); j++) { ASN1Sequence mapping = (ASN1Sequence)mappings.getObjectAt(j); String id_p = ((DERObjectIdentifier)mapping.getObjectAt(0)).getId(); String sd_p = ((DERObjectIdentifier)mapping.getObjectAt(1)).getId(); Set tmp; if (!m_idp.containsKey(id_p)) { tmp = new HashSet(); tmp.add(sd_p); m_idp.put(id_p, tmp); s_idp.add(id_p); } else { tmp = (Set)m_idp.get(id_p); tmp.add(sd_p); } } Iterator it_idp = s_idp.iterator(); while (it_idp.hasNext()) { String id_p = (String)it_idp.next(); // // (1) // if (policyMapping > 0) { boolean idp_found = false; Iterator nodes_i = policyNodes[i].iterator(); while (nodes_i.hasNext()) { PKIXPolicyNode node = (PKIXPolicyNode)nodes_i.next(); if (node.getValidPolicy().equals(id_p)) { idp_found = true; node.expectedPolicies = (Set)m_idp.get(id_p); break; } } if (!idp_found) { nodes_i = policyNodes[i].iterator(); while (nodes_i.hasNext()) { PKIXPolicyNode node = (PKIXPolicyNode)nodes_i.next(); if (RFC3280CertPathUtilities.ANY_POLICY.equals(node.getValidPolicy())) { Set pq = null; ASN1Sequence policies = null; try { policies = (ASN1Sequence)CertPathValidatorUtilities.getExtensionValue(cert, RFC3280CertPathUtilities.CERTIFICATE_POLICIES); } catch (AnnotatedException e) { throw new ExtCertPathValidatorException( "Certificate policies extension could not be decoded.", e, certPath, index); } Enumeration e = policies.getObjects(); while (e.hasMoreElements()) { PolicyInformation pinfo = null; try { pinfo = PolicyInformation.getInstance(e.nextElement()); } catch (Exception ex) { throw new CertPathValidatorException( "Policy information could not be decoded.", ex, certPath, index); } if (RFC3280CertPathUtilities.ANY_POLICY.equals(pinfo.getPolicyIdentifier().getId())) { try { pq = CertPathValidatorUtilities .getQualifierSet(pinfo.getPolicyQualifiers()); } catch (CertPathValidatorException ex) { throw new ExtCertPathValidatorException( "Policy qualifier info set could not be decoded.", ex, certPath, index); } break; } } boolean ci = false; if (cert.getCriticalExtensionOIDs() != null) { ci = cert.getCriticalExtensionOIDs().contains( RFC3280CertPathUtilities.CERTIFICATE_POLICIES); } PKIXPolicyNode p_node = (PKIXPolicyNode)node.getParent(); if (RFC3280CertPathUtilities.ANY_POLICY.equals(p_node.getValidPolicy())) { PKIXPolicyNode c_node = new PKIXPolicyNode(new ArrayList(), i, (Set)m_idp .get(id_p), p_node, pq, id_p, ci); p_node.addChild(c_node); policyNodes[i].add(c_node); } break; } } } // // (2) // } else if (policyMapping <= 0) { Iterator nodes_i = policyNodes[i].iterator(); while (nodes_i.hasNext()) { PKIXPolicyNode node = (PKIXPolicyNode)nodes_i.next(); if (node.getValidPolicy().equals(id_p)) { PKIXPolicyNode p_node = (PKIXPolicyNode)node.getParent(); p_node.removeChild(node); nodes_i.remove(); for (int k = (i - 1); k >= 0; k--) { List nodes = policyNodes[k]; for (int l = 0; l < nodes.size(); l++) { PKIXPolicyNode node2 = (PKIXPolicyNode)nodes.get(l); if (!node2.hasChildren()) { _validPolicyTree = CertPathValidatorUtilities.removePolicyNode( _validPolicyTree, policyNodes, node2); if (_validPolicyTree == null) { break; } } } } } } } } } return _validPolicyTree; } protected static void prepareNextCertA( CertPath certPath, int index) throws CertPathValidatorException { List certs = certPath.getCertificates(); X509Certificate cert = (X509Certificate)certs.get(index); // // // (a) check the policy mappings // ASN1Sequence pm = null; try { pm = DERSequence.getInstance(CertPathValidatorUtilities.getExtensionValue(cert, RFC3280CertPathUtilities.POLICY_MAPPINGS)); } catch (AnnotatedException ex) { throw new ExtCertPathValidatorException("Policy mappings extension could not be decoded.", ex, certPath, index); } if (pm != null) { ASN1Sequence mappings = pm; for (int j = 0; j < mappings.size(); j++) { DERObjectIdentifier issuerDomainPolicy = null; DERObjectIdentifier subjectDomainPolicy = null; try { ASN1Sequence mapping = DERSequence.getInstance(mappings.getObjectAt(j)); issuerDomainPolicy = DERObjectIdentifier.getInstance(mapping.getObjectAt(0)); subjectDomainPolicy = DERObjectIdentifier.getInstance(mapping.getObjectAt(1)); } catch (Exception e) { throw new ExtCertPathValidatorException("Policy mappings extension contents could not be decoded.", e, certPath, index); } if (RFC3280CertPathUtilities.ANY_POLICY.equals(issuerDomainPolicy.getId())) { throw new CertPathValidatorException("IssuerDomainPolicy is anyPolicy", null, certPath, index); } if (RFC3280CertPathUtilities.ANY_POLICY.equals(subjectDomainPolicy.getId())) { throw new CertPathValidatorException("SubjectDomainPolicy is anyPolicy,", null, certPath, index); } } } } protected static void processCertF( CertPath certPath, int index, PKIXPolicyNode validPolicyTree, int explicitPolicy) throws CertPathValidatorException { // // (f) // if (explicitPolicy <= 0 && validPolicyTree == null) { throw new ExtCertPathValidatorException("No valid policy tree found when one expected.", null, certPath, index); } } protected static PKIXPolicyNode processCertE( CertPath certPath, int index, PKIXPolicyNode validPolicyTree) throws CertPathValidatorException { List certs = certPath.getCertificates(); X509Certificate cert = (X509Certificate)certs.get(index); // // (e) // ASN1Sequence certPolicies = null; try { certPolicies = DERSequence.getInstance(CertPathValidatorUtilities.getExtensionValue(cert, RFC3280CertPathUtilities.CERTIFICATE_POLICIES)); } catch (AnnotatedException e) { throw new ExtCertPathValidatorException("Could not read certificate policies extension from certificate.", e, certPath, index); } if (certPolicies == null) { validPolicyTree = null; } return validPolicyTree; } protected static void processCertBC( CertPath certPath, int index, PKIXNameConstraintValidator nameConstraintValidator) throws CertPathValidatorException { List certs = certPath.getCertificates(); X509Certificate cert = (X509Certificate)certs.get(index); int n = certs.size(); // i as defined in the algorithm description int i = n - index; // // (b), (c) permitted and excluded subtree checking. // if (!(CertPathValidatorUtilities.isSelfIssued(cert) && (i < n))) { X509Principal principal = CertPathValidatorUtilities.getSubjectPrincipal(cert); ASN1InputStream aIn = new ASN1InputStream(principal.getEncoded()); ASN1Sequence dns; try { dns = DERSequence.getInstance(aIn.readObject()); } catch (Exception e) { throw new CertPathValidatorException("Exception extracting subject name when checking subtrees.", e, certPath, index); } try { nameConstraintValidator.checkPermittedDN(dns); nameConstraintValidator.checkExcludedDN(dns); } catch (PKIXNameConstraintValidatorException e) { throw new CertPathValidatorException("Subtree check for certificate subject failed.", e, certPath, index); } GeneralNames altName = null; try { altName = GeneralNames.getInstance(CertPathValidatorUtilities.getExtensionValue(cert, RFC3280CertPathUtilities.SUBJECT_ALTERNATIVE_NAME)); } catch (Exception e) { throw new CertPathValidatorException("Subject alternative name extension could not be decoded.", e, certPath, index); } Vector emails = new X509Name(dns).getValues(X509Name.EmailAddress); for (Enumeration e = emails.elements(); e.hasMoreElements();) { String email = (String)e.nextElement(); GeneralName emailAsGeneralName = new GeneralName(GeneralName.rfc822Name, email); try { nameConstraintValidator.checkPermitted(emailAsGeneralName); nameConstraintValidator.checkExcluded(emailAsGeneralName); } catch (PKIXNameConstraintValidatorException ex) { throw new CertPathValidatorException( "Subtree check for certificate subject alternative email failed.", ex, certPath, index); } } if (altName != null) { GeneralName[] genNames = null; try { genNames = altName.getNames(); } catch (Exception e) { throw new CertPathValidatorException("Subject alternative name contents could not be decoded.", e, certPath, index); } for (int j = 0; j < genNames.length; j++) { try { nameConstraintValidator.checkPermitted(genNames[j]); nameConstraintValidator.checkExcluded(genNames[j]); } catch (PKIXNameConstraintValidatorException e) { throw new CertPathValidatorException( "Subtree check for certificate subject alternative name failed.", e, certPath, index); } } } } } protected static PKIXPolicyNode processCertD( CertPath certPath, int index, Set acceptablePolicies, PKIXPolicyNode validPolicyTree, List[] policyNodes, int inhibitAnyPolicy) throws CertPathValidatorException { List certs = certPath.getCertificates(); X509Certificate cert = (X509Certificate)certs.get(index); int n = certs.size(); // i as defined in the algorithm description int i = n - index; // // (d) policy Information checking against initial policy and // policy mapping // ASN1Sequence certPolicies = null; try { certPolicies = DERSequence.getInstance(CertPathValidatorUtilities.getExtensionValue(cert, RFC3280CertPathUtilities.CERTIFICATE_POLICIES)); } catch (AnnotatedException e) { throw new ExtCertPathValidatorException("Could not read certificate policies extension from certificate.", e, certPath, index); } if (certPolicies != null && validPolicyTree != null) { // // (d) (1) // Enumeration e = certPolicies.getObjects(); Set pols = new HashSet(); while (e.hasMoreElements()) { PolicyInformation pInfo = PolicyInformation.getInstance(e.nextElement()); DERObjectIdentifier pOid = pInfo.getPolicyIdentifier(); pols.add(pOid.getId()); if (!RFC3280CertPathUtilities.ANY_POLICY.equals(pOid.getId())) { Set pq = null; try { pq = CertPathValidatorUtilities.getQualifierSet(pInfo.getPolicyQualifiers()); } catch (CertPathValidatorException ex) { throw new ExtCertPathValidatorException("Policy qualifier info set could not be build.", ex, certPath, index); } boolean match = CertPathValidatorUtilities.processCertD1i(i, policyNodes, pOid, pq); if (!match) { CertPathValidatorUtilities.processCertD1ii(i, policyNodes, pOid, pq); } } } if (acceptablePolicies.isEmpty() || acceptablePolicies.contains(RFC3280CertPathUtilities.ANY_POLICY)) { acceptablePolicies.clear(); acceptablePolicies.addAll(pols); } else { Iterator it = acceptablePolicies.iterator(); Set t1 = new HashSet(); while (it.hasNext()) { Object o = it.next(); if (pols.contains(o)) { t1.add(o); } } acceptablePolicies.clear(); acceptablePolicies.addAll(t1); } // // (d) (2) // if ((inhibitAnyPolicy > 0) || ((i < n) && CertPathValidatorUtilities.isSelfIssued(cert))) { e = certPolicies.getObjects(); while (e.hasMoreElements()) { PolicyInformation pInfo = PolicyInformation.getInstance(e.nextElement()); if (RFC3280CertPathUtilities.ANY_POLICY.equals(pInfo.getPolicyIdentifier().getId())) { Set _apq = CertPathValidatorUtilities.getQualifierSet(pInfo.getPolicyQualifiers()); List _nodes = policyNodes[i - 1]; for (int k = 0; k < _nodes.size(); k++) { PKIXPolicyNode _node = (PKIXPolicyNode)_nodes.get(k); Iterator _policySetIter = _node.getExpectedPolicies().iterator(); while (_policySetIter.hasNext()) { Object _tmp = _policySetIter.next(); String _policy; if (_tmp instanceof String) { _policy = (String)_tmp; } else if (_tmp instanceof DERObjectIdentifier) { _policy = ((DERObjectIdentifier)_tmp).getId(); } else { continue; } boolean _found = false; Iterator _childrenIter = _node.getChildren(); while (_childrenIter.hasNext()) { PKIXPolicyNode _child = (PKIXPolicyNode)_childrenIter.next(); if (_policy.equals(_child.getValidPolicy())) { _found = true; } } if (!_found) { Set _newChildExpectedPolicies = new HashSet(); _newChildExpectedPolicies.add(_policy); PKIXPolicyNode _newChild = new PKIXPolicyNode(new ArrayList(), i, _newChildExpectedPolicies, _node, _apq, _policy, false); _node.addChild(_newChild); policyNodes[i].add(_newChild); } } } break; } } } PKIXPolicyNode _validPolicyTree = validPolicyTree; // // (d) (3) // for (int j = (i - 1); j >= 0; j--) { List nodes = policyNodes[j]; for (int k = 0; k < nodes.size(); k++) { PKIXPolicyNode node = (PKIXPolicyNode)nodes.get(k); if (!node.hasChildren()) { _validPolicyTree = CertPathValidatorUtilities.removePolicyNode(_validPolicyTree, policyNodes, node); if (_validPolicyTree == null) { break; } } } } // // d (4) // Set criticalExtensionOids = cert.getCriticalExtensionOIDs(); if (criticalExtensionOids != null) { boolean critical = criticalExtensionOids.contains(RFC3280CertPathUtilities.CERTIFICATE_POLICIES); List nodes = policyNodes[i]; for (int j = 0; j < nodes.size(); j++) { PKIXPolicyNode node = (PKIXPolicyNode)nodes.get(j); node.setCritical(critical); } } return _validPolicyTree; } return null; } protected static void processCertA( CertPath certPath, ExtendedPKIXParameters paramsPKIX, int index, PublicKey workingPublicKey, boolean verificationAlreadyPerformed, X509Principal workingIssuerName, X509Certificate sign) throws ExtCertPathValidatorException { List certs = certPath.getCertificates(); X509Certificate cert = (X509Certificate)certs.get(index); // // (a) verify // if (!verificationAlreadyPerformed) { try { // (a) (1) // CertPathValidatorUtilities.verifyX509Certificate(cert, workingPublicKey, paramsPKIX.getSigProvider()); } catch (GeneralSecurityException e) { throw new ExtCertPathValidatorException("Could not validate certificate signature.", e, certPath, index); } } try { // (a) (2) // cert.checkValidity(CertPathValidatorUtilities .getValidCertDateFromValidityModel(paramsPKIX, certPath, index)); } catch (CertificateExpiredException e) { throw new ExtCertPathValidatorException("Could not validate certificate: " + e.getMessage(), e, certPath, index); } catch (CertificateNotYetValidException e) { throw new ExtCertPathValidatorException("Could not validate certificate: " + e.getMessage(), e, certPath, index); } catch (AnnotatedException e) { throw new ExtCertPathValidatorException("Could not validate time of certificate.", e, certPath, index); } // // (a) (3) // if (paramsPKIX.isRevocationEnabled()) { try { checkCRLs(paramsPKIX, cert, CertPathValidatorUtilities.getValidCertDateFromValidityModel(paramsPKIX, certPath, index), sign, workingPublicKey, certs); } catch (AnnotatedException e) { Throwable cause = e; if (null != e.getCause()) { cause = e.getCause(); } throw new ExtCertPathValidatorException(e.getMessage(), cause, certPath, index); } } // // (a) (4) name chaining // if (!CertPathValidatorUtilities.getEncodedIssuerPrincipal(cert).equals(workingIssuerName)) { throw new ExtCertPathValidatorException("IssuerName(" + CertPathValidatorUtilities.getEncodedIssuerPrincipal(cert) + ") does not match SubjectName(" + workingIssuerName + ") of signing certificate.", null, certPath, index); } } protected static int prepareNextCertI1( CertPath certPath, int index, int explicitPolicy) throws CertPathValidatorException { List certs = certPath.getCertificates(); X509Certificate cert = (X509Certificate)certs.get(index); // // (i) // ASN1Sequence pc = null; try { pc = DERSequence.getInstance(CertPathValidatorUtilities.getExtensionValue(cert, RFC3280CertPathUtilities.POLICY_CONSTRAINTS)); } catch (Exception e) { throw new ExtCertPathValidatorException("Policy constraints extension cannot be decoded.", e, certPath, index); } int tmpInt; if (pc != null) { Enumeration policyConstraints = pc.getObjects(); while (policyConstraints.hasMoreElements()) { try { ASN1TaggedObject constraint = ASN1TaggedObject.getInstance(policyConstraints.nextElement()); if (constraint.getTagNo() == 0) { tmpInt = DERInteger.getInstance(constraint, false).getValue().intValue(); if (tmpInt < explicitPolicy) { return tmpInt; } break; } } catch (IllegalArgumentException e) { throw new ExtCertPathValidatorException("Policy constraints extension contents cannot be decoded.", e, certPath, index); } } } return explicitPolicy; } protected static int prepareNextCertI2( CertPath certPath, int index, int policyMapping) throws CertPathValidatorException { List certs = certPath.getCertificates(); X509Certificate cert = (X509Certificate)certs.get(index); // // (i) // ASN1Sequence pc = null; try { pc = DERSequence.getInstance(CertPathValidatorUtilities.getExtensionValue(cert, RFC3280CertPathUtilities.POLICY_CONSTRAINTS)); } catch (Exception e) { throw new ExtCertPathValidatorException("Policy constraints extension cannot be decoded.", e, certPath, index); } int tmpInt; if (pc != null) { Enumeration policyConstraints = pc.getObjects(); while (policyConstraints.hasMoreElements()) { try { ASN1TaggedObject constraint = ASN1TaggedObject.getInstance(policyConstraints.nextElement()); if (constraint.getTagNo() == 1) { tmpInt = DERInteger.getInstance(constraint, false).getValue().intValue(); if (tmpInt < policyMapping) { return tmpInt; } break; } } catch (IllegalArgumentException e) { throw new ExtCertPathValidatorException("Policy constraints extension contents cannot be decoded.", e, certPath, index); } } } return policyMapping; } protected static void prepareNextCertG( CertPath certPath, int index, PKIXNameConstraintValidator nameConstraintValidator) throws CertPathValidatorException { List certs = certPath.getCertificates(); X509Certificate cert = (X509Certificate)certs.get(index); // // (g) handle the name constraints extension // NameConstraints nc = null; try { ASN1Sequence ncSeq = DERSequence.getInstance(CertPathValidatorUtilities.getExtensionValue(cert, RFC3280CertPathUtilities.NAME_CONSTRAINTS)); if (ncSeq != null) { nc = NameConstraints.getInstance(ncSeq); } } catch (Exception e) { throw new ExtCertPathValidatorException("Name constraints extension could not be decoded.", e, certPath, index); } if (nc != null) { // // (g) (1) permitted subtrees // GeneralSubtree[] permitted = nc.getPermittedSubtrees(); if (permitted != null) { try { nameConstraintValidator.intersectPermittedSubtree(permitted); } catch (Exception ex) { throw new ExtCertPathValidatorException( "Permitted subtrees cannot be build from name constraints extension.", ex, certPath, index); } } // // (g) (2) excluded subtrees // GeneralSubtree[] excluded = nc.getExcludedSubtrees(); if (excluded != null) { for (int i = 0; i != excluded.length; i++) try { nameConstraintValidator.addExcludedSubtree(excluded[i]); } catch (Exception ex) { throw new ExtCertPathValidatorException( "Excluded subtrees cannot be build from name constraints extension.", ex, certPath, index); } } } } /** * Checks a distribution point for revocation information for the * certificate cert. * * @param dp The distribution point to consider. * @param paramsPKIX PKIX parameters. * @param cert Certificate to check if it is revoked. * @param validDate The date when the certificate revocation status should be * checked. * @param defaultCRLSignCert The issuer certificate of the certificate cert. * @param defaultCRLSignKey The public key of the issuer certificate * defaultCRLSignCert. * @param certStatus The current certificate revocation status. * @param reasonMask The reasons mask which is already checked. * @param certPathCerts The certificates of the certification path. * @throws AnnotatedException if the certificate is revoked or the status cannot be checked * or some error occurs. */ private static void checkCRL( DistributionPoint dp, ExtendedPKIXParameters paramsPKIX, X509Certificate cert, Date validDate, X509Certificate defaultCRLSignCert, PublicKey defaultCRLSignKey, CertStatus certStatus, ReasonsMask reasonMask, List certPathCerts) throws AnnotatedException { Date currentDate = new Date(System.currentTimeMillis()); if (validDate.getTime() > currentDate.getTime()) { throw new AnnotatedException("Validation time is in future."); } // (a) /* * We always get timely valid CRLs, so there is no step (a) (1). * "locally cached" CRLs are assumed to be in getStore(), additional * CRLs must be enabled in the ExtendedPKIXParameters and are in * getAdditionalStore() */ Set crls = CertPathValidatorUtilities.getCompleteCRLs(dp, cert, currentDate, paramsPKIX); boolean validCrlFound = false; AnnotatedException lastException = null; Iterator crl_iter = crls.iterator(); while (crl_iter.hasNext() && certStatus.getCertStatus() == CertStatus.UNREVOKED && !reasonMask.isAllReasons()) { try { X509CRL crl = (X509CRL)crl_iter.next(); // (d) ReasonsMask interimReasonsMask = RFC3280CertPathUtilities.processCRLD(crl, dp); // (e) /* * The reasons mask is updated at the end, so only valid CRLs * can update it. If this CRL does not contain new reasons it * must be ignored. */ if (!interimReasonsMask.hasNewReasons(reasonMask)) { continue; } // (f) Set keys = RFC3280CertPathUtilities.processCRLF(crl, cert, defaultCRLSignCert, defaultCRLSignKey, paramsPKIX, certPathCerts); // (g) PublicKey key = RFC3280CertPathUtilities.processCRLG(crl, keys); X509CRL deltaCRL = null; if (paramsPKIX.isUseDeltasEnabled()) { // get delta CRLs Set deltaCRLs = CertPathValidatorUtilities.getDeltaCRLs(currentDate, paramsPKIX, crl); // we only want one valid delta CRL // (h) deltaCRL = RFC3280CertPathUtilities.processCRLH(deltaCRLs, key); } /* * CRL must be be valid at the current time, not the validation * time. If a certificate is revoked with reason keyCompromise, * cACompromise, it can be used for forgery, also for the past. * This reason may not be contained in older CRLs. */ /* * in the chain model signatures stay valid also after the * certificate has been expired, so they do not have to be in * the CRL validity time */ if (paramsPKIX.getValidityModel() != ExtendedPKIXParameters.CHAIN_VALIDITY_MODEL) { /* * if a certificate has expired, but was revoked, it is not * more in the CRL, so it would be regarded as valid if the * first check is not done */ if (cert.getNotAfter().getTime() < crl.getThisUpdate().getTime()) { throw new AnnotatedException("No valid CRL for current time found."); } } RFC3280CertPathUtilities.processCRLB1(dp, cert, crl); // (b) (2) RFC3280CertPathUtilities.processCRLB2(dp, cert, crl); // (c) RFC3280CertPathUtilities.processCRLC(deltaCRL, crl, paramsPKIX); // (i) RFC3280CertPathUtilities.processCRLI(validDate, deltaCRL, cert, certStatus, paramsPKIX); // (j) RFC3280CertPathUtilities.processCRLJ(validDate, crl, cert, certStatus); // (k) if (certStatus.getCertStatus() == CRLReason.removeFromCRL) { certStatus.setCertStatus(CertStatus.UNREVOKED); } // update reasons mask reasonMask.addReasons(interimReasonsMask); Set criticalExtensions = crl.getCriticalExtensionOIDs(); if (criticalExtensions != null) { criticalExtensions = new HashSet(criticalExtensions); criticalExtensions.remove(X509Extensions.IssuingDistributionPoint.getId()); criticalExtensions.remove(X509Extensions.DeltaCRLIndicator.getId()); if (!criticalExtensions.isEmpty()) { throw new AnnotatedException("CRL contains unsupported critical extensions."); } } if (deltaCRL != null) { criticalExtensions = deltaCRL.getCriticalExtensionOIDs(); if (criticalExtensions != null) { criticalExtensions = new HashSet(criticalExtensions); criticalExtensions.remove(X509Extensions.IssuingDistributionPoint.getId()); criticalExtensions.remove(X509Extensions.DeltaCRLIndicator.getId()); if (!criticalExtensions.isEmpty()) { throw new AnnotatedException("Delta CRL contains unsupported critical extension."); } } } validCrlFound = true; } catch (AnnotatedException e) { lastException = e; } } if (!validCrlFound) { throw lastException; } } /** * Checks a certificate if it is revoked. * * @param paramsPKIX PKIX parameters. * @param cert Certificate to check if it is revoked. * @param validDate The date when the certificate revocation status should be * checked. * @param sign The issuer certificate of the certificate cert. * @param workingPublicKey The public key of the issuer certificate sign. * @param certPathCerts The certificates of the certification path. * @throws AnnotatedException if the certificate is revoked or the status cannot be checked * or some error occurs. */ protected static void checkCRLs( ExtendedPKIXParameters paramsPKIX, X509Certificate cert, Date validDate, X509Certificate sign, PublicKey workingPublicKey, List certPathCerts) throws AnnotatedException { AnnotatedException lastException = null; CRLDistPoint crldp = null; try { crldp = CRLDistPoint.getInstance(CertPathValidatorUtilities.getExtensionValue(cert, RFC3280CertPathUtilities.CRL_DISTRIBUTION_POINTS)); } catch (Exception e) { throw new AnnotatedException("CRL distribution point extension could not be read.", e); } try { CertPathValidatorUtilities.addAdditionalStoresFromCRLDistributionPoint(crldp, paramsPKIX); } catch (AnnotatedException e) { throw new AnnotatedException( "No additional CRL locations could be decoded from CRL distribution point extension.", e); } CertStatus certStatus = new CertStatus(); ReasonsMask reasonsMask = new ReasonsMask(); boolean validCrlFound = false; // for each distribution point if (crldp != null) { DistributionPoint dps[] = null; try { dps = crldp.getDistributionPoints(); } catch (Exception e) { throw new AnnotatedException("Distribution points could not be read.", e); } if (dps != null) { for (int i = 0; i < dps.length && certStatus.getCertStatus() == CertStatus.UNREVOKED && !reasonsMask.isAllReasons(); i++) { ExtendedPKIXParameters paramsPKIXClone = (ExtendedPKIXParameters)paramsPKIX.clone(); try { checkCRL(dps[i], paramsPKIXClone, cert, validDate, sign, workingPublicKey, certStatus, reasonsMask, certPathCerts); validCrlFound = true; } catch (AnnotatedException e) { lastException = e; } } } } /* * If the revocation status has not been determined, repeat the process * above with any available CRLs not specified in a distribution point * but issued by the certificate issuer. */ if (certStatus.getCertStatus() == CertStatus.UNREVOKED && !reasonsMask.isAllReasons()) { try { /* * assume a DP with both the reasons and the cRLIssuer fields * omitted and a distribution point name of the certificate * issuer. */ ASN1Primitive issuer = null; try { issuer = new ASN1InputStream(CertPathValidatorUtilities.getEncodedIssuerPrincipal(cert).getEncoded()) .readObject(); } catch (Exception e) { throw new AnnotatedException("Issuer from certificate for CRL could not be reencoded.", e); } DistributionPoint dp = new DistributionPoint(new DistributionPointName(0, new GeneralNames( new GeneralName(GeneralName.directoryName, issuer))), null, null); ExtendedPKIXParameters paramsPKIXClone = (ExtendedPKIXParameters)paramsPKIX.clone(); checkCRL(dp, paramsPKIXClone, cert, validDate, sign, workingPublicKey, certStatus, reasonsMask, certPathCerts); validCrlFound = true; } catch (AnnotatedException e) { lastException = e; } } if (!validCrlFound) { if (lastException instanceof AnnotatedException) { throw lastException; } throw new AnnotatedException("No valid CRL found.", lastException); } if (certStatus.getCertStatus() != CertStatus.UNREVOKED) { String message = "Certificate revocation after " + certStatus.getRevocationDate(); message += ", reason: " + crlReasons[certStatus.getCertStatus()]; throw new AnnotatedException(message); } if (!reasonsMask.isAllReasons() && certStatus.getCertStatus() == CertStatus.UNREVOKED) { certStatus.setCertStatus(CertStatus.UNDETERMINED); } if (certStatus.getCertStatus() == CertStatus.UNDETERMINED) { throw new AnnotatedException("Certificate status could not be determined."); } } protected static int prepareNextCertJ( CertPath certPath, int index, int inhibitAnyPolicy) throws CertPathValidatorException { List certs = certPath.getCertificates(); X509Certificate cert = (X509Certificate)certs.get(index); // // (j) // DERInteger iap = null; try { iap = DERInteger.getInstance(CertPathValidatorUtilities.getExtensionValue(cert, RFC3280CertPathUtilities.INHIBIT_ANY_POLICY)); } catch (Exception e) { throw new ExtCertPathValidatorException("Inhibit any-policy extension cannot be decoded.", e, certPath, index); } if (iap != null) { int _inhibitAnyPolicy = iap.getValue().intValue(); if (_inhibitAnyPolicy < inhibitAnyPolicy) { return _inhibitAnyPolicy; } } return inhibitAnyPolicy; } protected static void prepareNextCertK( CertPath certPath, int index) throws CertPathValidatorException { List certs = certPath.getCertificates(); X509Certificate cert = (X509Certificate)certs.get(index); // // (k) // BasicConstraints bc = null; try { bc = BasicConstraints.getInstance(CertPathValidatorUtilities.getExtensionValue(cert, RFC3280CertPathUtilities.BASIC_CONSTRAINTS)); } catch (Exception e) { throw new ExtCertPathValidatorException("Basic constraints extension cannot be decoded.", e, certPath, index); } if (bc != null) { if (!(bc.isCA())) { throw new CertPathValidatorException("Not a CA certificate"); } } else { throw new CertPathValidatorException("Intermediate certificate lacks BasicConstraints"); } } protected static int prepareNextCertL( CertPath certPath, int index, int maxPathLength) throws CertPathValidatorException { List certs = certPath.getCertificates(); X509Certificate cert = (X509Certificate)certs.get(index); // // (l) // if (!CertPathValidatorUtilities.isSelfIssued(cert)) { if (maxPathLength <= 0) { throw new ExtCertPathValidatorException("Max path length not greater than zero", null, certPath, index); } return maxPathLength - 1; } return maxPathLength; } protected static int prepareNextCertM( CertPath certPath, int index, int maxPathLength) throws CertPathValidatorException { List certs = certPath.getCertificates(); X509Certificate cert = (X509Certificate)certs.get(index); // // (m) // BasicConstraints bc = null; try { bc = BasicConstraints.getInstance(CertPathValidatorUtilities.getExtensionValue(cert, RFC3280CertPathUtilities.BASIC_CONSTRAINTS)); } catch (Exception e) { throw new ExtCertPathValidatorException("Basic constraints extension cannot be decoded.", e, certPath, index); } if (bc != null) { BigInteger _pathLengthConstraint = bc.getPathLenConstraint(); if (_pathLengthConstraint != null) { int _plc = _pathLengthConstraint.intValue(); if (_plc < maxPathLength) { return _plc; } } } return maxPathLength; } protected static void prepareNextCertN( CertPath certPath, int index) throws CertPathValidatorException { List certs = certPath.getCertificates(); X509Certificate cert = (X509Certificate)certs.get(index); // // (n) // boolean[] _usage = cert.getKeyUsage(); if ((_usage != null) && !_usage[RFC3280CertPathUtilities.KEY_CERT_SIGN]) { throw new ExtCertPathValidatorException( "Issuer certificate keyusage extension is critical and does not permit key signing.", null, certPath, index); } } protected static void prepareNextCertO( CertPath certPath, int index, Set criticalExtensions, List pathCheckers) throws CertPathValidatorException { List certs = certPath.getCertificates(); X509Certificate cert = (X509Certificate)certs.get(index); // // (o) // Iterator tmpIter; tmpIter = pathCheckers.iterator(); while (tmpIter.hasNext()) { try { ((PKIXCertPathChecker)tmpIter.next()).check(cert, criticalExtensions); } catch (CertPathValidatorException e) { throw new CertPathValidatorException(e.getMessage(), e.getCause(), certPath, index); } } if (!criticalExtensions.isEmpty()) { throw new ExtCertPathValidatorException("Certificate has unsupported critical extension: " + criticalExtensions, null, certPath, index); } } protected static int prepareNextCertH1( CertPath certPath, int index, int explicitPolicy) { List certs = certPath.getCertificates(); X509Certificate cert = (X509Certificate)certs.get(index); // // (h) // if (!CertPathValidatorUtilities.isSelfIssued(cert)) { // // (1) // if (explicitPolicy != 0) { return explicitPolicy - 1; } } return explicitPolicy; } protected static int prepareNextCertH2( CertPath certPath, int index, int policyMapping) { List certs = certPath.getCertificates(); X509Certificate cert = (X509Certificate)certs.get(index); // // (h) // if (!CertPathValidatorUtilities.isSelfIssued(cert)) { // // (2) // if (policyMapping != 0) { return policyMapping - 1; } } return policyMapping; } protected static int prepareNextCertH3( CertPath certPath, int index, int inhibitAnyPolicy) { List certs = certPath.getCertificates(); X509Certificate cert = (X509Certificate)certs.get(index); // // (h) // if (!CertPathValidatorUtilities.isSelfIssued(cert)) { // // (3) // if (inhibitAnyPolicy != 0) { return inhibitAnyPolicy - 1; } } return inhibitAnyPolicy; } protected static final String[] crlReasons = new String[] { "unspecified", "keyCompromise", "cACompromise", "affiliationChanged", "superseded", "cessationOfOperation", "certificateHold", "unknown", "removeFromCRL", "privilegeWithdrawn", "aACompromise"}; protected static int wrapupCertA( int explicitPolicy, X509Certificate cert) { // // (a) // if (!CertPathValidatorUtilities.isSelfIssued(cert) && (explicitPolicy != 0)) { explicitPolicy--; } return explicitPolicy; } protected static int wrapupCertB( CertPath certPath, int index, int explicitPolicy) throws CertPathValidatorException { List certs = certPath.getCertificates(); X509Certificate cert = (X509Certificate)certs.get(index); // // (b) // int tmpInt; ASN1Sequence pc = null; try { pc = DERSequence.getInstance(CertPathValidatorUtilities.getExtensionValue(cert, RFC3280CertPathUtilities.POLICY_CONSTRAINTS)); } catch (AnnotatedException e) { throw new ExtCertPathValidatorException("Policy constraints could not be decoded.", e, certPath, index); } if (pc != null) { Enumeration policyConstraints = pc.getObjects(); while (policyConstraints.hasMoreElements()) { ASN1TaggedObject constraint = (ASN1TaggedObject)policyConstraints.nextElement(); switch (constraint.getTagNo()) { case 0: try { tmpInt = DERInteger.getInstance(constraint, false).getValue().intValue(); } catch (Exception e) { throw new ExtCertPathValidatorException( "Policy constraints requireExplicitPolicy field could not be decoded.", e, certPath, index); } if (tmpInt == 0) { return 0; } break; } } } return explicitPolicy; } protected static void wrapupCertF( CertPath certPath, int index, List pathCheckers, Set criticalExtensions) throws CertPathValidatorException { List certs = certPath.getCertificates(); X509Certificate cert = (X509Certificate)certs.get(index); Iterator tmpIter; tmpIter = pathCheckers.iterator(); while (tmpIter.hasNext()) { try { ((PKIXCertPathChecker)tmpIter.next()).check(cert, criticalExtensions); } catch (CertPathValidatorException e) { throw new ExtCertPathValidatorException("Additional certificate path checker failed.", e, certPath, index); } } if (!criticalExtensions.isEmpty()) { throw new ExtCertPathValidatorException("Certificate has unsupported critical extension: " + criticalExtensions, null, certPath, index); } } protected static PKIXPolicyNode wrapupCertG( CertPath certPath, ExtendedPKIXParameters paramsPKIX, Set userInitialPolicySet, int index, List[] policyNodes, PKIXPolicyNode validPolicyTree, Set acceptablePolicies) throws CertPathValidatorException { int n = certPath.getCertificates().size(); // // (g) // PKIXPolicyNode intersection; // // (g) (i) // if (validPolicyTree == null) { if (paramsPKIX.isExplicitPolicyRequired()) { throw new ExtCertPathValidatorException("Explicit policy requested but none available.", null, certPath, index); } intersection = null; } else if (CertPathValidatorUtilities.isAnyPolicy(userInitialPolicySet)) // (g) // (ii) { if (paramsPKIX.isExplicitPolicyRequired()) { if (acceptablePolicies.isEmpty()) { throw new ExtCertPathValidatorException("Explicit policy requested but none available.", null, certPath, index); } else { Set _validPolicyNodeSet = new HashSet(); for (int j = 0; j < policyNodes.length; j++) { List _nodeDepth = policyNodes[j]; for (int k = 0; k < _nodeDepth.size(); k++) { PKIXPolicyNode _node = (PKIXPolicyNode)_nodeDepth.get(k); if (RFC3280CertPathUtilities.ANY_POLICY.equals(_node.getValidPolicy())) { Iterator _iter = _node.getChildren(); while (_iter.hasNext()) { _validPolicyNodeSet.add(_iter.next()); } } } } Iterator _vpnsIter = _validPolicyNodeSet.iterator(); while (_vpnsIter.hasNext()) { PKIXPolicyNode _node = (PKIXPolicyNode)_vpnsIter.next(); String _validPolicy = _node.getValidPolicy(); if (!acceptablePolicies.contains(_validPolicy)) { // validPolicyTree = // removePolicyNode(validPolicyTree, policyNodes, // _node); } } if (validPolicyTree != null) { for (int j = (n - 1); j >= 0; j--) { List nodes = policyNodes[j]; for (int k = 0; k < nodes.size(); k++) { PKIXPolicyNode node = (PKIXPolicyNode)nodes.get(k); if (!node.hasChildren()) { validPolicyTree = CertPathValidatorUtilities.removePolicyNode(validPolicyTree, policyNodes, node); } } } } } } intersection = validPolicyTree; } else { // // (g) (iii) // // This implementation is not exactly same as the one described in // RFC3280. // However, as far as the validation result is concerned, both // produce // adequate result. The only difference is whether AnyPolicy is // remain // in the policy tree or not. // // (g) (iii) 1 // Set _validPolicyNodeSet = new HashSet(); for (int j = 0; j < policyNodes.length; j++) { List _nodeDepth = policyNodes[j]; for (int k = 0; k < _nodeDepth.size(); k++) { PKIXPolicyNode _node = (PKIXPolicyNode)_nodeDepth.get(k); if (RFC3280CertPathUtilities.ANY_POLICY.equals(_node.getValidPolicy())) { Iterator _iter = _node.getChildren(); while (_iter.hasNext()) { PKIXPolicyNode _c_node = (PKIXPolicyNode)_iter.next(); if (!RFC3280CertPathUtilities.ANY_POLICY.equals(_c_node.getValidPolicy())) { _validPolicyNodeSet.add(_c_node); } } } } } // // (g) (iii) 2 // Iterator _vpnsIter = _validPolicyNodeSet.iterator(); while (_vpnsIter.hasNext()) { PKIXPolicyNode _node = (PKIXPolicyNode)_vpnsIter.next(); String _validPolicy = _node.getValidPolicy(); if (!userInitialPolicySet.contains(_validPolicy)) { validPolicyTree = CertPathValidatorUtilities.removePolicyNode(validPolicyTree, policyNodes, _node); } } // // (g) (iii) 4 // if (validPolicyTree != null) { for (int j = (n - 1); j >= 0; j--) { List nodes = policyNodes[j]; for (int k = 0; k < nodes.size(); k++) { PKIXPolicyNode node = (PKIXPolicyNode)nodes.get(k); if (!node.hasChildren()) { validPolicyTree = CertPathValidatorUtilities.removePolicyNode(validPolicyTree, policyNodes, node); } } } } intersection = validPolicyTree; } return intersection; } } bouncycastle-1.49.orig/jdk1.3/org/bouncycastle/jce/provider/ProviderUtil.java0000644000175000017500000000423411701477362026606 0ustar ebourgebourgpackage org.bouncycastle.jce.provider; import java.io.ByteArrayInputStream; import java.io.IOException; import java.io.InputStream; import java.security.Permission; import org.bouncycastle.jcajce.provider.config.ConfigurableProvider; import org.bouncycastle.jcajce.provider.config.ProviderConfigurationPermission; import org.bouncycastle.jce.spec.ECParameterSpec; public class ProviderUtil { private static Permission BC_EC_LOCAL_PERMISSION = new ProviderConfigurationPermission( "BC", ConfigurableProvider.THREAD_LOCAL_EC_IMPLICITLY_CA); private static Permission BC_EC_PERMISSION = new ProviderConfigurationPermission( "BC", ConfigurableProvider.EC_IMPLICITLY_CA); private static ThreadLocal threadSpec = new ThreadLocal(); private static volatile ECParameterSpec ecImplicitCaParams; static void setParameter(String parameterName, Object parameter) { SecurityManager securityManager = System.getSecurityManager(); if (parameterName.equals(ConfigurableProvider.THREAD_LOCAL_EC_IMPLICITLY_CA)) { ECParameterSpec curveSpec; if (securityManager != null) { securityManager.checkPermission(BC_EC_LOCAL_PERMISSION); } curveSpec = (ECParameterSpec)parameter; threadSpec.set(curveSpec); } else if (parameterName.equals(ConfigurableProvider.EC_IMPLICITLY_CA)) { if (securityManager != null) { securityManager.checkPermission(BC_EC_PERMISSION); } ecImplicitCaParams = (ECParameterSpec)parameter; } } public static ECParameterSpec getEcImplicitlyCa() { ECParameterSpec spec = (ECParameterSpec)threadSpec.get(); if (spec != null) { return spec; } return ecImplicitCaParams; } static int getReadLimit(InputStream in) throws IOException { if (in instanceof ByteArrayInputStream) { return in.available(); } return Integer.MAX_VALUE; } } bouncycastle-1.49.orig/jdk1.3/org/bouncycastle/jce/provider/X509CRLEntryObject.java0000644000175000017500000002111512132666220027322 0ustar ebourgebourgpackage org.bouncycastle.jce.provider; import java.io.IOException; import java.math.BigInteger; import java.security.cert.CRLException; import java.security.cert.X509CRLEntry; import java.util.Date; import java.util.Enumeration; import java.util.HashSet; import java.util.Set; import org.bouncycastle.asn1.ASN1Encoding; import org.bouncycastle.asn1.ASN1InputStream; import org.bouncycastle.asn1.ASN1ObjectIdentifier; import org.bouncycastle.asn1.DEREnumerated; import org.bouncycastle.asn1.util.ASN1Dump; import org.bouncycastle.asn1.x500.X500Name; import org.bouncycastle.asn1.x509.CRLReason; import org.bouncycastle.asn1.x509.Extension; import org.bouncycastle.asn1.x509.Extensions; import org.bouncycastle.asn1.x509.GeneralName; import org.bouncycastle.asn1.x509.GeneralNames; import org.bouncycastle.asn1.x509.TBSCertList; import org.bouncycastle.asn1.x509.X509Extension; import org.bouncycastle.x509.extension.X509ExtensionUtil; import org.bouncycastle.jce.X509Principal; /** * The following extensions are listed in RFC 2459 as relevant to CRL Entries * * ReasonCode Hode Instruction Code Invalidity Date Certificate Issuer * (critical) */ public class X509CRLEntryObject extends X509CRLEntry { private TBSCertList.CRLEntry c; private X500Name certificateIssuer; private int hashValue; private boolean isHashValueSet; public X509CRLEntryObject(TBSCertList.CRLEntry c) { this.c = c; this.certificateIssuer = null; } /** * Constructor for CRLEntries of indirect CRLs. If isIndirect * is false {@link #getCertificateIssuer()} will always * return null, previousCertificateIssuer is * ignored. If this isIndirect is specified and this CRLEntry * has no certificate issuer CRL entry extension * previousCertificateIssuer is returned by * {@link #getCertificateIssuer()}. * * @param c * TBSCertList.CRLEntry object. * @param isIndirect * true if the corresponding CRL is a indirect * CRL. * @param previousCertificateIssuer * Certificate issuer of the previous CRLEntry. */ public X509CRLEntryObject( TBSCertList.CRLEntry c, boolean isIndirect, X500Name previousCertificateIssuer) { this.c = c; this.certificateIssuer = loadCertificateIssuer(isIndirect, previousCertificateIssuer); } /** * Will return true if any extensions are present and marked as critical as * we currently don't handle any extensions! */ public boolean hasUnsupportedCriticalExtension() { Set extns = getCriticalExtensionOIDs(); return extns != null && !extns.isEmpty(); } private X500Name loadCertificateIssuer(boolean isIndirect, X500Name previousCertificateIssuer) { if (!isIndirect) { return null; } byte[] ext = getExtensionValue(X509Extension.certificateIssuer.getId()); if (ext == null) { return previousCertificateIssuer; } try { GeneralName[] names = GeneralNames.getInstance( X509ExtensionUtil.fromExtensionValue(ext)).getNames(); for (int i = 0; i < names.length; i++) { if (names[i].getTagNo() == GeneralName.directoryName) { return X500Name.getInstance(names[i].getName()); } } return null; } catch (IOException e) { return null; } } X509Principal getCertificateIssuer() { if (certificateIssuer == null) { return null; } try { return new X509Principal(certificateIssuer.getEncoded()); } catch (Exception e) { throw new IllegalStateException(e.toString()); } } private Set getExtensionOIDs(boolean critical) { Extensions extensions = c.getExtensions(); if (extensions != null) { Set set = new HashSet(); Enumeration e = extensions.oids(); while (e.hasMoreElements()) { ASN1ObjectIdentifier oid = (ASN1ObjectIdentifier) e.nextElement(); Extension ext = extensions.getExtension(oid); if (critical == ext.isCritical()) { set.add(oid.getId()); } } return set; } return null; } public Set getCriticalExtensionOIDs() { return getExtensionOIDs(true); } public Set getNonCriticalExtensionOIDs() { return getExtensionOIDs(false); } public byte[] getExtensionValue(String oid) { Extensions exts = c.getExtensions(); if (exts != null) { Extension ext = exts.getExtension(new ASN1ObjectIdentifier(oid)); if (ext != null) { try { return ext.getExtnValue().getEncoded(); } catch (Exception e) { throw new RuntimeException("error encoding " + e.toString()); } } } return null; } /** * Cache the hashCode value - calculating it with the standard method. * @return calculated hashCode. */ public int hashCode() { if (!isHashValueSet) { hashValue = super.hashCode(); isHashValueSet = true; } return hashValue; } public byte[] getEncoded() throws CRLException { try { return c.getEncoded(ASN1Encoding.DER); } catch (IOException e) { throw new CRLException(e.toString()); } } public BigInteger getSerialNumber() { return c.getUserCertificate().getValue(); } public Date getRevocationDate() { return c.getRevocationDate().getDate(); } public boolean hasExtensions() { return c.getExtensions() != null; } public String toString() { StringBuffer buf = new StringBuffer(); String nl = System.getProperty("line.separator"); buf.append(" userCertificate: ").append(this.getSerialNumber()).append(nl); buf.append(" revocationDate: ").append(this.getRevocationDate()).append(nl); Extensions extensions = c.getExtensions(); if (extensions != null) { Enumeration e = extensions.oids(); if (e.hasMoreElements()) { buf.append(" crlEntryExtensions:").append(nl); while (e.hasMoreElements()) { ASN1ObjectIdentifier oid = (ASN1ObjectIdentifier)e.nextElement(); Extension ext = extensions.getExtension(oid); if (ext.getExtnValue() != null) { byte[] octs = ext.getExtnValue().getOctets(); ASN1InputStream dIn = new ASN1InputStream(octs); buf.append(" critical(").append(ext.isCritical()).append(") "); try { if (oid.equals(X509Extension.reasonCode)) { buf.append(CRLReason.getInstance(DEREnumerated.getInstance(dIn.readObject()))).append(nl); } else if (oid.equals(X509Extension.certificateIssuer)) { buf.append("Certificate issuer: ").append(GeneralNames.getInstance(dIn.readObject())).append(nl); } else { buf.append(oid.getId()); buf.append(" value = ").append(ASN1Dump.dumpAsString(dIn.readObject())).append(nl); } } catch (Exception ex) { buf.append(oid.getId()); buf.append(" value = ").append("*****").append(nl); } } else { buf.append(nl); } } } } return buf.toString(); } } bouncycastle-1.49.orig/jdk1.3/org/bouncycastle/jce/provider/PKIXCertPathBuilderSpi.java0000644000175000017500000003204312104173671030340 0ustar ebourgebourgpackage org.bouncycastle.jce.provider; import java.io.IOException; import java.security.InvalidAlgorithmParameterException; import java.security.PublicKey; import org.bouncycastle.jce.cert.CertPath; import org.bouncycastle.jce.cert.CertPathBuilderException; import org.bouncycastle.jce.cert.CertPathBuilderResult; import org.bouncycastle.jce.cert.CertPathBuilderSpi; import org.bouncycastle.jce.cert.CertPathParameters; import org.bouncycastle.jce.cert.CertPathValidator; import org.bouncycastle.jce.cert.CertPathValidatorException; import org.bouncycastle.jce.cert.CertSelector; import org.bouncycastle.jce.cert.CertStore; import org.bouncycastle.jce.cert.CertStoreException; import java.security.cert.Certificate; import java.security.cert.CertificateException; import org.bouncycastle.jce.cert.CertificateFactory; import org.bouncycastle.jce.cert.PKIXBuilderParameters; import org.bouncycastle.jce.cert.PKIXBuilderParameters; import org.bouncycastle.jce.cert.PKIXCertPathBuilderResult; import org.bouncycastle.jce.cert.PKIXCertPathValidatorResult; import org.bouncycastle.jce.cert.TrustAnchor; import org.bouncycastle.jce.cert.X509CertSelector; import java.security.cert.X509Certificate; import java.util.ArrayList; import java.util.Collection; import java.util.HashSet; import java.util.Iterator; import java.util.List; import java.util.Set; import org.bouncycastle.jce.X509Principal; import org.bouncycastle.x509.ExtendedPKIXBuilderParameters; import org.bouncycastle.jce.PrincipalUtil; /** * Implements the PKIX CertPathBuilding algorithem for BouncyCastle. *
* MAYBE: implement more CertPath validation whil build path to omit invalid pathes * * @see CertPathBuilderSpi **/ public class PKIXCertPathBuilderSpi extends CertPathBuilderSpi { /** * Build and validate a CertPath using the given parameter. * * @param params PKIXBuilderParameters object containing all * information to build the CertPath **/ public CertPathBuilderResult engineBuild( CertPathParameters params) throws CertPathBuilderException, InvalidAlgorithmParameterException { if (!(params instanceof PKIXBuilderParameters) && !(params instanceof ExtendedPKIXBuilderParameters)) { throw new InvalidAlgorithmParameterException( "Parameters must be an instance of " + PKIXBuilderParameters.class.getName() + " or " + ExtendedPKIXBuilderParameters.class.getName() + "."); } ExtendedPKIXBuilderParameters pkixParams = null; if (params instanceof ExtendedPKIXBuilderParameters) { pkixParams = (ExtendedPKIXBuilderParameters) params; } else { pkixParams = (ExtendedPKIXBuilderParameters) ExtendedPKIXBuilderParameters .getInstance((PKIXBuilderParameters) params); } Collection targets; Iterator targetIter; List certPathList = new ArrayList(); Set certPathSet = new HashSet(); X509Certificate cert; Collection certs; CertPath certPath = null; Exception certPathException = null; // search target certificates CertSelector certSelect = pkixParams.getTargetCertConstraints(); if (certSelect == null) { throw new CertPathBuilderException("targetCertConstraints must be non-null for CertPath building"); } try { targets = findCertificates(certSelect, pkixParams.getCertStores()); } catch (CertStoreException e) { throw new CertPathBuilderException(e); } if (targets.isEmpty()) { throw new CertPathBuilderException("no certificate found matching targetCertContraints"); } CertificateFactory cFact; CertPathValidator validator; try { cFact = CertificateFactory.getInstance("X.509", "BC"); validator = CertPathValidator.getInstance("PKIX", "BC"); } catch (Exception e) { throw new CertPathBuilderException("exception creating support classes: " + e); } // // check all potential target certificates targetIter = targets.iterator(); while (targetIter.hasNext()) { cert = (X509Certificate)targetIter.next(); certPathList.clear(); certPathSet.clear(); while (cert != null) { // add cert to the certpath certPathList.add(cert); certPathSet.add(cert); // check whether the issuer of is a TrustAnchor if (findTrustAnchor(cert, pkixParams.getTrustAnchors()) != null) { try { certPath = cFact.generateCertPath(certPathList); PKIXCertPathValidatorResult result = (PKIXCertPathValidatorResult)validator.validate(certPath, pkixParams); return new PKIXCertPathBuilderResult(certPath, result.getTrustAnchor(), result.getPolicyTree(), result.getPublicKey()); } catch (CertificateException ex) { certPathException = ex; } catch (CertPathValidatorException ex) { certPathException = ex; } // if validation failed go to next certificate cert = null; } else { // try to get the issuer certificate from one // of the CertStores try { X509Certificate issuer = findIssuer(cert, pkixParams.getCertStores()); if (issuer.equals(cert)) { cert = null; } else { cert = issuer; // validation failed - circular path detected, go to next certificate if (certPathSet.contains(cert)) { cert = null; } } } catch (CertPathValidatorException ex) { certPathException = ex; cert = null; } } } } if (certPath != null) { throw new CertPathBuilderException("found certificate chain, but could not be validated", certPathException); } throw new CertPathBuilderException("unable to find certificate chain"); } /** * Search the given Set of TrustAnchor's for one that is the * issuer of the fiven X509 certificate. * * @param cert the X509 certificate * @param trustAnchors a Set of TrustAnchor's * * @return the TrustAnchor object if found or * null if not. * * @exception CertPathValidatorException if a TrustAnchor was * found but the signature verificytion on the given certificate * has thrown an exception. This Exception can be obtainted with * getCause() method. **/ final TrustAnchor findTrustAnchor( X509Certificate cert, Set trustAnchors) throws CertPathBuilderException { Iterator iter = trustAnchors.iterator(); TrustAnchor trust = null; PublicKey trustPublicKey = null; Exception invalidKeyEx = null; X509CertSelector certSelectX509 = new X509CertSelector(); try { certSelectX509.setSubject(PrincipalUtil.getIssuerX509Principal(cert).getEncoded()); } catch (Exception ex) { throw new CertPathBuilderException("can't get trust anchor principal",null); } while (iter.hasNext() && trust == null) { trust = (TrustAnchor)iter.next(); if (trust.getTrustedCert() != null) { if (certSelectX509.match(trust.getTrustedCert())) { trustPublicKey = trust.getTrustedCert().getPublicKey(); } else { trust = null; } } else if (trust.getCAName() != null && trust.getCAPublicKey() != null) { try { X509Principal certIssuer = PrincipalUtil.getIssuerX509Principal(cert); X509Principal caName = new X509Principal(trust.getCAName()); if (certIssuer.equals(caName)) { trustPublicKey = trust.getCAPublicKey(); } else { trust = null; } } catch (Exception ex) { trust = null; } } else { trust = null; } if (trustPublicKey != null) { try { cert.verify(trustPublicKey); } catch (Exception ex) { invalidKeyEx = ex; trust = null; } } } if (trust == null && invalidKeyEx != null) { throw new CertPathBuilderException("TrustAnchor found put certificate validation failed",invalidKeyEx); } return trust; } /** * Return a Collection of all certificates found in the * CertStore's that are matching the certSelect criteriums. * * @param certSelect a {@link CertSelector CertSelector} * object that will be used to select the certificates * @param certStores a List containing only {@link CertStore * CertStore} objects. These are used to search for * certificates * * @return a Collection of all found {@link Certificate Certificate} * objects. May be empty but never null. **/ private Collection findCertificates( CertSelector certSelect, List certStores) throws CertStoreException { Set certs = new HashSet(); Iterator iter = certStores.iterator(); while (iter.hasNext()) { CertStore certStore = (CertStore)iter.next(); certs.addAll(certStore.getCertificates(certSelect)); } return certs; } /** * Find the issuer certificate of the given certificate. * * @param cert the certificate hows issuer certificate should * be found. * @param certStores a list of CertStore object * that will be searched * * @return then X509Certificate object containing * the issuer certificate or null if not found * * @exception CertPathValidatorException if a TrustAnchor was * found but the signature verificytion on the given certificate * has thrown an exception. This Exception can be obtainted with * getCause() method. **/ private X509Certificate findIssuer( X509Certificate cert, List certStores) throws CertPathValidatorException { Exception invalidKeyEx = null; X509CertSelector certSelect = new X509CertSelector(); try { certSelect.setSubject(PrincipalUtil.getIssuerX509Principal(cert).getEncoded()); } catch (Exception ex) { throw new CertPathValidatorException("Issuer not found", null, null, -1); } Iterator iter; try { iter = findCertificates(certSelect, certStores).iterator(); } catch (CertStoreException e) { throw new CertPathValidatorException(e); } X509Certificate issuer = null; while (iter.hasNext() && issuer == null) { issuer = (X509Certificate)iter.next(); try { cert.verify(issuer.getPublicKey()); } catch (Exception ex) { invalidKeyEx = ex; issuer = null; } } if (issuer == null && invalidKeyEx == null) { throw new CertPathValidatorException("Issuer not found", null, null, -1); } if (issuer == null && invalidKeyEx != null) { throw new CertPathValidatorException("issuer found but certificate validation failed",invalidKeyEx,null,-1); } return issuer; } } bouncycastle-1.49.orig/jdk1.3/org/bouncycastle/jce/provider/JCESecretKeyFactory.java0000644000175000017500000003444111701477364027733 0ustar ebourgebourgpackage org.bouncycastle.jce.provider; import java.lang.reflect.Constructor; import java.security.InvalidKeyException; import java.security.spec.InvalidKeySpecException; import java.security.spec.KeySpec; import javax.crypto.SecretKey; import javax.crypto.SecretKeyFactorySpi; import javax.crypto.spec.DESKeySpec; import javax.crypto.spec.DESedeKeySpec; import javax.crypto.spec.PBEKeySpec; import javax.crypto.spec.SecretKeySpec; import org.bouncycastle.asn1.ASN1ObjectIdentifier; import org.bouncycastle.asn1.pkcs.PKCSObjectIdentifiers; import org.bouncycastle.crypto.CipherParameters; import org.bouncycastle.jcajce.provider.symmetric.util.BCPBEKey; import org.bouncycastle.jcajce.provider.symmetric.util.PBE; public class JCESecretKeyFactory extends SecretKeyFactorySpi implements PBE { protected String algName; protected ASN1ObjectIdentifier algOid; protected JCESecretKeyFactory( String algName, ASN1ObjectIdentifier algOid) { this.algName = algName; this.algOid = algOid; } protected SecretKey engineGenerateSecret( KeySpec keySpec) throws InvalidKeySpecException { if (keySpec instanceof SecretKeySpec) { return (SecretKey)keySpec; } throw new InvalidKeySpecException("Invalid KeySpec"); } protected KeySpec engineGetKeySpec( SecretKey key, Class keySpec) throws InvalidKeySpecException { if (keySpec == null) { throw new InvalidKeySpecException("keySpec parameter is null"); } if (key == null) { throw new InvalidKeySpecException("key parameter is null"); } if (SecretKeySpec.class.isAssignableFrom(keySpec)) { return new SecretKeySpec(key.getEncoded(), algName); } try { Class[] parameters = { byte[].class }; Constructor c = keySpec.getConstructor(parameters); Object[] p = new Object[1]; p[0] = key.getEncoded(); return (KeySpec)c.newInstance(p); } catch (Exception e) { throw new InvalidKeySpecException(e.toString()); } } protected SecretKey engineTranslateKey( SecretKey key) throws InvalidKeyException { if (key == null) { throw new InvalidKeyException("key parameter is null"); } if (!key.getAlgorithm().equalsIgnoreCase(algName)) { throw new InvalidKeyException("Key not of type " + algName + "."); } return new SecretKeySpec(key.getEncoded(), algName); } /* * classes that inherit from us */ static public class PBEKeyFactory extends JCESecretKeyFactory { private boolean forCipher; private int scheme; private int digest; private int keySize; private int ivSize; public PBEKeyFactory( String algorithm, ASN1ObjectIdentifier oid, boolean forCipher, int scheme, int digest, int keySize, int ivSize) { super(algorithm, oid); this.forCipher = forCipher; this.scheme = scheme; this.digest = digest; this.keySize = keySize; this.ivSize = ivSize; } protected SecretKey engineGenerateSecret( KeySpec keySpec) throws InvalidKeySpecException { if (keySpec instanceof PBEKeySpec) { PBEKeySpec pbeSpec = (PBEKeySpec)keySpec; CipherParameters param; return new BCPBEKey(this.algName, this.algOid, scheme, digest, keySize, ivSize, pbeSpec, null); } throw new InvalidKeySpecException("Invalid KeySpec"); } } static public class DESPBEKeyFactory extends JCESecretKeyFactory { private boolean forCipher; private int scheme; private int digest; private int keySize; private int ivSize; public DESPBEKeyFactory( String algorithm, ASN1ObjectIdentifier oid, boolean forCipher, int scheme, int digest, int keySize, int ivSize) { super(algorithm, oid); this.forCipher = forCipher; this.scheme = scheme; this.digest = digest; this.keySize = keySize; this.ivSize = ivSize; } protected SecretKey engineGenerateSecret( KeySpec keySpec) throws InvalidKeySpecException { if (keySpec instanceof PBEKeySpec) { PBEKeySpec pbeSpec = (PBEKeySpec)keySpec; CipherParameters param; return new BCPBEKey(this.algName, this.algOid, scheme, digest, keySize, ivSize, pbeSpec, null); } throw new InvalidKeySpecException("Invalid KeySpec"); } } static public class DES extends JCESecretKeyFactory { public DES() { super("DES", null); } protected SecretKey engineGenerateSecret( KeySpec keySpec) throws InvalidKeySpecException { if (keySpec instanceof DESKeySpec) { DESKeySpec desKeySpec = (DESKeySpec)keySpec; return new SecretKeySpec(desKeySpec.getKey(), "DES"); } return super.engineGenerateSecret(keySpec); } } static public class DESede extends JCESecretKeyFactory { public DESede() { super("DESede", null); } protected KeySpec engineGetKeySpec( SecretKey key, Class keySpec) throws InvalidKeySpecException { if (keySpec == null) { throw new InvalidKeySpecException("keySpec parameter is null"); } if (key == null) { throw new InvalidKeySpecException("key parameter is null"); } if (SecretKeySpec.class.isAssignableFrom(keySpec)) { return new SecretKeySpec(key.getEncoded(), algName); } else if (DESedeKeySpec.class.isAssignableFrom(keySpec)) { byte[] bytes = key.getEncoded(); try { if (bytes.length == 16) { byte[] longKey = new byte[24]; System.arraycopy(bytes, 0, longKey, 0, 16); System.arraycopy(bytes, 0, longKey, 16, 8); return new DESedeKeySpec(longKey); } else { return new DESedeKeySpec(bytes); } } catch (Exception e) { throw new InvalidKeySpecException(e.toString()); } } throw new InvalidKeySpecException("Invalid KeySpec"); } protected SecretKey engineGenerateSecret( KeySpec keySpec) throws InvalidKeySpecException { if (keySpec instanceof DESedeKeySpec) { DESedeKeySpec desKeySpec = (DESedeKeySpec)keySpec; return new SecretKeySpec(desKeySpec.getKey(), "DESede"); } return super.engineGenerateSecret(keySpec); } } /** * PBEWithMD5AndDES */ static public class PBEWithMD5AndDES extends DESPBEKeyFactory { public PBEWithMD5AndDES() { super("PBEwithMD5andDES", null, true, PKCS5S1, MD5, 64, 64); } } /** * PBEWithMD5AndRC2 */ static public class PBEWithMD5AndRC2 extends PBEKeyFactory { public PBEWithMD5AndRC2() { super("PBEwithMD5andRC2", null, true, PKCS5S1, MD5, 64, 64); } } /** * PBEWithSHA1AndDES */ static public class PBEWithSHA1AndDES extends PBEKeyFactory { public PBEWithSHA1AndDES() { super("PBEwithSHA1andDES", null, true, PKCS5S1, SHA1, 64, 64); } } /** * PBEWithSHA1AndRC2 */ static public class PBEWithSHA1AndRC2 extends PBEKeyFactory { public PBEWithSHA1AndRC2() { super("PBEwithSHA1andRC2", null, true, PKCS5S1, SHA1, 64, 64); } } /** * PBEWithSHAAnd3-KeyTripleDES-CBC */ static public class PBEWithSHAAndDES3Key extends PBEKeyFactory { public PBEWithSHAAndDES3Key() { super("PBEwithSHAandDES3Key-CBC", PKCSObjectIdentifiers.pbeWithSHAAnd3_KeyTripleDES_CBC, true, PKCS12, SHA1, 192, 64); } } /** * PBEWithSHAAnd2-KeyTripleDES-CBC */ static public class PBEWithSHAAndDES2Key extends PBEKeyFactory { public PBEWithSHAAndDES2Key() { super("PBEwithSHAandDES2Key-CBC", PKCSObjectIdentifiers.pbeWithSHAAnd2_KeyTripleDES_CBC, true, PKCS12, SHA1, 128, 64); } } /** * PBEWithSHAAnd128BitRC2-CBC */ static public class PBEWithSHAAnd128BitRC2 extends PBEKeyFactory { public PBEWithSHAAnd128BitRC2() { super("PBEwithSHAand128BitRC2-CBC", PKCSObjectIdentifiers.pbeWithSHAAnd128BitRC2_CBC, true, PKCS12, SHA1, 128, 64); } } /** * PBEWithSHAAnd40BitRC2-CBC */ static public class PBEWithSHAAnd40BitRC2 extends PBEKeyFactory { public PBEWithSHAAnd40BitRC2() { super("PBEwithSHAand40BitRC2-CBC", PKCSObjectIdentifiers.pbewithSHAAnd40BitRC2_CBC, true, PKCS12, SHA1, 40, 64); } } /** * PBEWithSHAAndTwofish-CBC */ static public class PBEWithSHAAndTwofish extends PBEKeyFactory { public PBEWithSHAAndTwofish() { super("PBEwithSHAandTwofish-CBC", null, true, PKCS12, SHA1, 256, 128); } } /** * PBEWithSHAAnd128BitRC4 */ static public class PBEWithSHAAnd128BitRC4 extends PBEKeyFactory { public PBEWithSHAAnd128BitRC4() { super("PBEWithSHAAnd128BitRC4", PKCSObjectIdentifiers.pbeWithSHAAnd128BitRC4, true, PKCS12, SHA1, 128, 0); } } /** * PBEWithSHAAnd40BitRC4 */ static public class PBEWithSHAAnd40BitRC4 extends PBEKeyFactory { public PBEWithSHAAnd40BitRC4() { super("PBEWithSHAAnd128BitRC4", PKCSObjectIdentifiers.pbeWithSHAAnd128BitRC4, true, PKCS12, SHA1, 40, 0); } } /** * PBEWithHmacRIPEMD160 */ public static class PBEWithRIPEMD160 extends PBEKeyFactory { public PBEWithRIPEMD160() { super("PBEwithHmacRIPEMD160", null, false, PKCS12, RIPEMD160, 160, 0); } } /** * PBEWithHmacSHA */ public static class PBEWithSHA extends PBEKeyFactory { public PBEWithSHA() { super("PBEwithHmacSHA", null, false, PKCS12, SHA1, 160, 0); } } /** * PBEWithHmacTiger */ public static class PBEWithTiger extends PBEKeyFactory { public PBEWithTiger() { super("PBEwithHmacTiger", null, false, PKCS12, TIGER, 192, 0); } } /** * PBEWithSHA1And128BitAES-BC */ static public class PBEWithSHAAnd128BitAESBC extends PBEKeyFactory { public PBEWithSHAAnd128BitAESBC() { super("PBEWithSHA1And128BitAES-CBC-BC", null, true, PKCS12, SHA1, 128, 128); } } /** * PBEWithSHA1And192BitAES-BC */ static public class PBEWithSHAAnd192BitAESBC extends PBEKeyFactory { public PBEWithSHAAnd192BitAESBC() { super("PBEWithSHA1And192BitAES-CBC-BC", null, true, PKCS12, SHA1, 192, 128); } } /** * PBEWithSHA1And256BitAES-BC */ static public class PBEWithSHAAnd256BitAESBC extends PBEKeyFactory { public PBEWithSHAAnd256BitAESBC() { super("PBEWithSHA1And256BitAES-CBC-BC", null, true, PKCS12, SHA1, 256, 128); } } /** * PBEWithSHA256And128BitAES-BC */ static public class PBEWithSHA256And128BitAESBC extends PBEKeyFactory { public PBEWithSHA256And128BitAESBC() { super("PBEWithSHA256And128BitAES-CBC-BC", null, true, PKCS12, SHA256, 128, 128); } } /** * PBEWithSHA256And192BitAES-BC */ static public class PBEWithSHA256And192BitAESBC extends PBEKeyFactory { public PBEWithSHA256And192BitAESBC() { super("PBEWithSHA256And192BitAES-CBC-BC", null, true, PKCS12, SHA256, 192, 128); } } /** * PBEWithSHA256And256BitAES-BC */ static public class PBEWithSHA256And256BitAESBC extends PBEKeyFactory { public PBEWithSHA256And256BitAESBC() { super("PBEWithSHA256And256BitAES-CBC-BC", null, true, PKCS12, SHA256, 256, 128); } } /** * PBEWithMD5And128BitAES-OpenSSL */ static public class PBEWithMD5And128BitAESCBCOpenSSL extends PBEKeyFactory { public PBEWithMD5And128BitAESCBCOpenSSL() { super("PBEWithMD5And128BitAES-CBC-OpenSSL", null, true, OPENSSL, MD5, 128, 128); } } /** * PBEWithMD5And128BitAES-OpenSSL */ static public class PBEWithMD5And192BitAESCBCOpenSSL extends PBEKeyFactory { public PBEWithMD5And192BitAESCBCOpenSSL() { super("PBEWithMD5And128BitAES-CBC-OpenSSL", null, true, OPENSSL, MD5, 192, 128); } } /** * PBEWithMD5And128BitAES-OpenSSL */ static public class PBEWithMD5And256BitAESCBCOpenSSL extends PBEKeyFactory { public PBEWithMD5And256BitAESCBCOpenSSL() { super("PBEWithMD5And128BitAES-CBC-OpenSSL", null, true, OPENSSL, MD5, 256, 128); } } } bouncycastle-1.49.orig/jdk1.3/org/bouncycastle/jce/provider/JDKAlgorithmParameters.java0000644000175000017500000005215511702725362030463 0ustar ebourgebourgpackage org.bouncycastle.jce.provider; import java.io.ByteArrayOutputStream; import java.io.IOException; import java.security.AlgorithmParametersSpi; import java.security.spec.AlgorithmParameterSpec; import java.security.spec.InvalidParameterSpecException; import javax.crypto.spec.IvParameterSpec; import javax.crypto.spec.PBEParameterSpec; import javax.crypto.spec.RC2ParameterSpec; import org.bouncycastle.asn1.ASN1EncodableVector; import org.bouncycastle.asn1.ASN1InputStream; import org.bouncycastle.asn1.ASN1OctetString; import org.bouncycastle.asn1.ASN1Sequence; import org.bouncycastle.asn1.DERInteger; import org.bouncycastle.asn1.DEROctetString; import org.bouncycastle.asn1.DEROutputStream; import org.bouncycastle.asn1.DERSequence; import org.bouncycastle.asn1.misc.CAST5CBCParameters; import org.bouncycastle.asn1.pkcs.PKCS12PBEParams; import org.bouncycastle.asn1.pkcs.RC2CBCParameter; import org.bouncycastle.jce.spec.IESParameterSpec; public abstract class JDKAlgorithmParameters extends AlgorithmParametersSpi { protected boolean isASN1FormatString(String format) { return format == null || format.equals("ASN.1"); } protected AlgorithmParameterSpec engineGetParameterSpec( Class paramSpec) throws InvalidParameterSpecException { if (paramSpec == null) { throw new NullPointerException("argument to getParameterSpec must not be null"); } return localEngineGetParameterSpec(paramSpec); } protected abstract AlgorithmParameterSpec localEngineGetParameterSpec(Class paramSpec) throws InvalidParameterSpecException; public static class IVAlgorithmParameters extends JDKAlgorithmParameters { private byte[] iv; protected byte[] engineGetEncoded() throws IOException { return engineGetEncoded("ASN.1"); } protected byte[] engineGetEncoded( String format) throws IOException { if (this.isASN1FormatString(format)) { return new DEROctetString(engineGetEncoded("RAW")).getEncoded(); } if (format.equals("RAW")) { byte[] tmp = new byte[iv.length]; System.arraycopy(iv, 0, tmp, 0, iv.length); return tmp; } return null; } protected AlgorithmParameterSpec localEngineGetParameterSpec( Class paramSpec) throws InvalidParameterSpecException { if (paramSpec == IvParameterSpec.class) { return new IvParameterSpec(iv); } throw new InvalidParameterSpecException("unknown parameter spec passed to IV parameters object."); } protected void engineInit( AlgorithmParameterSpec paramSpec) throws InvalidParameterSpecException { if (!(paramSpec instanceof IvParameterSpec)) { throw new InvalidParameterSpecException("IvParameterSpec required to initialise a IV parameters algorithm parameters object"); } this.iv = ((IvParameterSpec)paramSpec).getIV(); } protected void engineInit( byte[] params) throws IOException { // // check that we don't have a DER encoded octet string // if ((params.length % 8) != 0 && params[0] == 0x04 && params[1] == params.length - 2) { ASN1InputStream aIn = new ASN1InputStream(params); ASN1OctetString oct = (ASN1OctetString)aIn.readObject(); params = oct.getOctets(); } this.iv = new byte[params.length]; System.arraycopy(params, 0, iv, 0, iv.length); } protected void engineInit( byte[] params, String format) throws IOException { if (this.isASN1FormatString(format)) { ASN1InputStream aIn = new ASN1InputStream(params); try { ASN1OctetString oct = (ASN1OctetString)aIn.readObject(); engineInit(oct.getOctets()); } catch (Exception e) { throw new IOException("Exception decoding: " + e); } return; } if (format.equals("RAW")) { engineInit(params); return; } throw new IOException("Unknown parameters format in IV parameters object"); } protected String engineToString() { return "IV Parameters"; } } public static class RC2AlgorithmParameters extends JDKAlgorithmParameters { private short[] table = { 0xbd, 0x56, 0xea, 0xf2, 0xa2, 0xf1, 0xac, 0x2a, 0xb0, 0x93, 0xd1, 0x9c, 0x1b, 0x33, 0xfd, 0xd0, 0x30, 0x04, 0xb6, 0xdc, 0x7d, 0xdf, 0x32, 0x4b, 0xf7, 0xcb, 0x45, 0x9b, 0x31, 0xbb, 0x21, 0x5a, 0x41, 0x9f, 0xe1, 0xd9, 0x4a, 0x4d, 0x9e, 0xda, 0xa0, 0x68, 0x2c, 0xc3, 0x27, 0x5f, 0x80, 0x36, 0x3e, 0xee, 0xfb, 0x95, 0x1a, 0xfe, 0xce, 0xa8, 0x34, 0xa9, 0x13, 0xf0, 0xa6, 0x3f, 0xd8, 0x0c, 0x78, 0x24, 0xaf, 0x23, 0x52, 0xc1, 0x67, 0x17, 0xf5, 0x66, 0x90, 0xe7, 0xe8, 0x07, 0xb8, 0x60, 0x48, 0xe6, 0x1e, 0x53, 0xf3, 0x92, 0xa4, 0x72, 0x8c, 0x08, 0x15, 0x6e, 0x86, 0x00, 0x84, 0xfa, 0xf4, 0x7f, 0x8a, 0x42, 0x19, 0xf6, 0xdb, 0xcd, 0x14, 0x8d, 0x50, 0x12, 0xba, 0x3c, 0x06, 0x4e, 0xec, 0xb3, 0x35, 0x11, 0xa1, 0x88, 0x8e, 0x2b, 0x94, 0x99, 0xb7, 0x71, 0x74, 0xd3, 0xe4, 0xbf, 0x3a, 0xde, 0x96, 0x0e, 0xbc, 0x0a, 0xed, 0x77, 0xfc, 0x37, 0x6b, 0x03, 0x79, 0x89, 0x62, 0xc6, 0xd7, 0xc0, 0xd2, 0x7c, 0x6a, 0x8b, 0x22, 0xa3, 0x5b, 0x05, 0x5d, 0x02, 0x75, 0xd5, 0x61, 0xe3, 0x18, 0x8f, 0x55, 0x51, 0xad, 0x1f, 0x0b, 0x5e, 0x85, 0xe5, 0xc2, 0x57, 0x63, 0xca, 0x3d, 0x6c, 0xb4, 0xc5, 0xcc, 0x70, 0xb2, 0x91, 0x59, 0x0d, 0x47, 0x20, 0xc8, 0x4f, 0x58, 0xe0, 0x01, 0xe2, 0x16, 0x38, 0xc4, 0x6f, 0x3b, 0x0f, 0x65, 0x46, 0xbe, 0x7e, 0x2d, 0x7b, 0x82, 0xf9, 0x40, 0xb5, 0x1d, 0x73, 0xf8, 0xeb, 0x26, 0xc7, 0x87, 0x97, 0x25, 0x54, 0xb1, 0x28, 0xaa, 0x98, 0x9d, 0xa5, 0x64, 0x6d, 0x7a, 0xd4, 0x10, 0x81, 0x44, 0xef, 0x49, 0xd6, 0xae, 0x2e, 0xdd, 0x76, 0x5c, 0x2f, 0xa7, 0x1c, 0xc9, 0x09, 0x69, 0x9a, 0x83, 0xcf, 0x29, 0x39, 0xb9, 0xe9, 0x4c, 0xff, 0x43, 0xab }; private short[] ekb = { 0x5d, 0xbe, 0x9b, 0x8b, 0x11, 0x99, 0x6e, 0x4d, 0x59, 0xf3, 0x85, 0xa6, 0x3f, 0xb7, 0x83, 0xc5, 0xe4, 0x73, 0x6b, 0x3a, 0x68, 0x5a, 0xc0, 0x47, 0xa0, 0x64, 0x34, 0x0c, 0xf1, 0xd0, 0x52, 0xa5, 0xb9, 0x1e, 0x96, 0x43, 0x41, 0xd8, 0xd4, 0x2c, 0xdb, 0xf8, 0x07, 0x77, 0x2a, 0xca, 0xeb, 0xef, 0x10, 0x1c, 0x16, 0x0d, 0x38, 0x72, 0x2f, 0x89, 0xc1, 0xf9, 0x80, 0xc4, 0x6d, 0xae, 0x30, 0x3d, 0xce, 0x20, 0x63, 0xfe, 0xe6, 0x1a, 0xc7, 0xb8, 0x50, 0xe8, 0x24, 0x17, 0xfc, 0x25, 0x6f, 0xbb, 0x6a, 0xa3, 0x44, 0x53, 0xd9, 0xa2, 0x01, 0xab, 0xbc, 0xb6, 0x1f, 0x98, 0xee, 0x9a, 0xa7, 0x2d, 0x4f, 0x9e, 0x8e, 0xac, 0xe0, 0xc6, 0x49, 0x46, 0x29, 0xf4, 0x94, 0x8a, 0xaf, 0xe1, 0x5b, 0xc3, 0xb3, 0x7b, 0x57, 0xd1, 0x7c, 0x9c, 0xed, 0x87, 0x40, 0x8c, 0xe2, 0xcb, 0x93, 0x14, 0xc9, 0x61, 0x2e, 0xe5, 0xcc, 0xf6, 0x5e, 0xa8, 0x5c, 0xd6, 0x75, 0x8d, 0x62, 0x95, 0x58, 0x69, 0x76, 0xa1, 0x4a, 0xb5, 0x55, 0x09, 0x78, 0x33, 0x82, 0xd7, 0xdd, 0x79, 0xf5, 0x1b, 0x0b, 0xde, 0x26, 0x21, 0x28, 0x74, 0x04, 0x97, 0x56, 0xdf, 0x3c, 0xf0, 0x37, 0x39, 0xdc, 0xff, 0x06, 0xa4, 0xea, 0x42, 0x08, 0xda, 0xb4, 0x71, 0xb0, 0xcf, 0x12, 0x7a, 0x4e, 0xfa, 0x6c, 0x1d, 0x84, 0x00, 0xc8, 0x7f, 0x91, 0x45, 0xaa, 0x2b, 0xc2, 0xb1, 0x8f, 0xd5, 0xba, 0xf2, 0xad, 0x19, 0xb2, 0x67, 0x36, 0xf7, 0x0f, 0x0a, 0x92, 0x7d, 0xe3, 0x9d, 0xe9, 0x90, 0x3e, 0x23, 0x27, 0x66, 0x13, 0xec, 0x81, 0x15, 0xbd, 0x22, 0xbf, 0x9f, 0x7e, 0xa9, 0x51, 0x4b, 0x4c, 0xfb, 0x02, 0xd3, 0x70, 0x86, 0x31, 0xe7, 0x3b, 0x05, 0x03, 0x54, 0x60, 0x48, 0x65, 0x18, 0xd2, 0xcd, 0x5f, 0x32, 0x88, 0x0e, 0x35, 0xfd }; private byte[] iv; private int parameterVersion = 58; protected byte[] engineGetEncoded() { byte[] tmp = new byte[iv.length]; System.arraycopy(iv, 0, tmp, 0, iv.length); return tmp; } protected byte[] engineGetEncoded( String format) throws IOException { if (this.isASN1FormatString(format)) { if (parameterVersion == -1) { return new RC2CBCParameter(engineGetEncoded()).getEncoded(); } else { return new RC2CBCParameter(parameterVersion, engineGetEncoded()).getEncoded(); } } if (format.equals("RAW")) { return engineGetEncoded(); } return null; } protected AlgorithmParameterSpec localEngineGetParameterSpec( Class paramSpec) throws InvalidParameterSpecException { if (paramSpec == RC2ParameterSpec.class) { if (parameterVersion != -1) { if (parameterVersion < 256) { return new RC2ParameterSpec(ekb[parameterVersion], iv); } else { return new RC2ParameterSpec(parameterVersion, iv); } } } if (paramSpec == IvParameterSpec.class) { return new IvParameterSpec(iv); } throw new InvalidParameterSpecException("unknown parameter spec passed to RC2 parameters object."); } protected void engineInit( AlgorithmParameterSpec paramSpec) throws InvalidParameterSpecException { if (paramSpec instanceof IvParameterSpec) { this.iv = ((IvParameterSpec)paramSpec).getIV(); } else if (paramSpec instanceof RC2ParameterSpec) { int effKeyBits = ((RC2ParameterSpec)paramSpec).getEffectiveKeyBits(); if (effKeyBits != -1) { if (effKeyBits < 256) { parameterVersion = table[effKeyBits]; } else { parameterVersion = effKeyBits; } } this.iv = ((RC2ParameterSpec)paramSpec).getIV(); } else { throw new InvalidParameterSpecException("IvParameterSpec or RC2ParameterSpec required to initialise a RC2 parameters algorithm parameters object"); } } protected void engineInit( byte[] params) throws IOException { this.iv = new byte[params.length]; System.arraycopy(params, 0, iv, 0, iv.length); } protected void engineInit( byte[] params, String format) throws IOException { if (this.isASN1FormatString(format)) { ASN1InputStream aIn = new ASN1InputStream(params); RC2CBCParameter p = RC2CBCParameter.getInstance(aIn.readObject()); if (p.getRC2ParameterVersion() != null) { parameterVersion = p.getRC2ParameterVersion().intValue(); } iv = p.getIV(); return; } if (format.equals("RAW")) { engineInit(params); return; } throw new IOException("Unknown parameters format in IV parameters object"); } protected String engineToString() { return "RC2 Parameters"; } } public static class CAST5AlgorithmParameters extends JDKAlgorithmParameters { private byte[] iv; private int keyLength = 128; protected byte[] engineGetEncoded() { byte[] tmp = new byte[iv.length]; System.arraycopy(iv, 0, tmp, 0, iv.length); return tmp; } protected byte[] engineGetEncoded( String format) throws IOException { if (this.isASN1FormatString(format)) { return new CAST5CBCParameters(engineGetEncoded(), keyLength).getEncoded(); } if (format.equals("RAW")) { return engineGetEncoded(); } return null; } protected AlgorithmParameterSpec localEngineGetParameterSpec( Class paramSpec) throws InvalidParameterSpecException { if (paramSpec == IvParameterSpec.class) { return new IvParameterSpec(iv); } throw new InvalidParameterSpecException("unknown parameter spec passed to CAST5 parameters object."); } protected void engineInit( AlgorithmParameterSpec paramSpec) throws InvalidParameterSpecException { if (paramSpec instanceof IvParameterSpec) { this.iv = ((IvParameterSpec)paramSpec).getIV(); } else { throw new InvalidParameterSpecException("IvParameterSpec required to initialise a CAST5 parameters algorithm parameters object"); } } protected void engineInit( byte[] params) throws IOException { this.iv = new byte[params.length]; System.arraycopy(params, 0, iv, 0, iv.length); } protected void engineInit( byte[] params, String format) throws IOException { if (this.isASN1FormatString(format)) { ASN1InputStream aIn = new ASN1InputStream(params); CAST5CBCParameters p = CAST5CBCParameters.getInstance(aIn.readObject()); keyLength = p.getKeyLength(); iv = p.getIV(); return; } if (format.equals("RAW")) { engineInit(params); return; } throw new IOException("Unknown parameters format in IV parameters object"); } protected String engineToString() { return "CAST5 Parameters"; } } public static class PKCS12PBE extends JDKAlgorithmParameters { PKCS12PBEParams params; protected byte[] engineGetEncoded() { ByteArrayOutputStream bOut = new ByteArrayOutputStream(); DEROutputStream dOut = new DEROutputStream(bOut); try { dOut.writeObject(params); } catch (IOException e) { throw new RuntimeException("Oooops! " + e.toString()); } return bOut.toByteArray(); } protected byte[] engineGetEncoded( String format) { if (this.isASN1FormatString(format)) { return engineGetEncoded(); } return null; } protected AlgorithmParameterSpec localEngineGetParameterSpec( Class paramSpec) throws InvalidParameterSpecException { if (paramSpec == PBEParameterSpec.class) { return new PBEParameterSpec(params.getIV(), params.getIterations().intValue()); } throw new InvalidParameterSpecException("unknown parameter spec passed to PKCS12 PBE parameters object."); } protected void engineInit( AlgorithmParameterSpec paramSpec) throws InvalidParameterSpecException { if (!(paramSpec instanceof PBEParameterSpec)) { throw new InvalidParameterSpecException("PBEParameterSpec required to initialise a PKCS12 PBE parameters algorithm parameters object"); } PBEParameterSpec pbeSpec = (PBEParameterSpec)paramSpec; this.params = new PKCS12PBEParams(pbeSpec.getSalt(), pbeSpec.getIterationCount()); } protected void engineInit( byte[] params) throws IOException { ASN1InputStream aIn = new ASN1InputStream(params); this.params = PKCS12PBEParams.getInstance(aIn.readObject()); } protected void engineInit( byte[] params, String format) throws IOException { if (this.isASN1FormatString(format)) { engineInit(params); return; } throw new IOException("Unknown parameters format in PKCS12 PBE parameters object"); } protected String engineToString() { return "PKCS12 PBE Parameters"; } } public static class IES extends JDKAlgorithmParameters { IESParameterSpec currentSpec; /** * in the abscence of a standard way of doing it this will do for * now... */ protected byte[] engineGetEncoded() { ByteArrayOutputStream bOut = new ByteArrayOutputStream(); DEROutputStream dOut = new DEROutputStream(bOut); try { ASN1EncodableVector v = new ASN1EncodableVector(); v.add(new DEROctetString(currentSpec.getDerivationV())); v.add(new DEROctetString(currentSpec.getEncodingV())); v.add(new DERInteger(currentSpec.getMacKeySize())); dOut.writeObject(new DERSequence(v)); dOut.close(); } catch (IOException e) { throw new RuntimeException("Error encoding IESParameters"); } return bOut.toByteArray(); } protected byte[] engineGetEncoded( String format) { if (this.isASN1FormatString(format) || format.equalsIgnoreCase("X.509")) { return engineGetEncoded(); } return null; } protected AlgorithmParameterSpec localEngineGetParameterSpec( Class paramSpec) throws InvalidParameterSpecException { if (paramSpec == IESParameterSpec.class) { return currentSpec; } throw new InvalidParameterSpecException("unknown parameter spec passed to ElGamal parameters object."); } protected void engineInit( AlgorithmParameterSpec paramSpec) throws InvalidParameterSpecException { if (!(paramSpec instanceof IESParameterSpec)) { throw new InvalidParameterSpecException("IESParameterSpec required to initialise a IES algorithm parameters object"); } this.currentSpec = (IESParameterSpec)paramSpec; } protected void engineInit( byte[] params) throws IOException { ASN1InputStream aIn = new ASN1InputStream(params); try { ASN1Sequence s = (ASN1Sequence)aIn.readObject(); this.currentSpec = new IESParameterSpec( ((ASN1OctetString)s.getObjectAt(0)).getOctets(), ((ASN1OctetString)s.getObjectAt(0)).getOctets(), ((DERInteger)s.getObjectAt(0)).getValue().intValue()); } catch (ClassCastException e) { throw new IOException("Not a valid IES Parameter encoding."); } catch (ArrayIndexOutOfBoundsException e) { throw new IOException("Not a valid IES Parameter encoding."); } } protected void engineInit( byte[] params, String format) throws IOException { if (this.isASN1FormatString(format) || format.equalsIgnoreCase("X.509")) { engineInit(params); } else { throw new IOException("Unknown parameter format " + format); } } protected String engineToString() { return "IES Parameters"; } } } bouncycastle-1.49.orig/jdk1.3/org/bouncycastle/jce/provider/JCEPBEKey.java0000644000175000017500000000614711701476630025561 0ustar ebourgebourgpackage org.bouncycastle.jce.provider; import javax.crypto.SecretKey; import javax.crypto.spec.PBEKeySpec; import org.bouncycastle.asn1.ASN1ObjectIdentifier; import org.bouncycastle.crypto.CipherParameters; import org.bouncycastle.crypto.PBEParametersGenerator; import org.bouncycastle.crypto.params.KeyParameter; import org.bouncycastle.crypto.params.ParametersWithIV; import org.bouncycastle.jcajce.provider.symmetric.util.PBE; public class JCEPBEKey implements SecretKey { String algorithm; ASN1ObjectIdentifier oid; int type; int digest; int keySize; int ivSize; CipherParameters param; PBEKeySpec pbeKeySpec; boolean tryWrong = false; /** * @param param */ public JCEPBEKey( String algorithm, ASN1ObjectIdentifier oid, int type, int digest, int keySize, int ivSize, PBEKeySpec pbeKeySpec, CipherParameters param) { this.algorithm = algorithm; this.oid = oid; this.type = type; this.digest = digest; this.keySize = keySize; this.ivSize = ivSize; this.pbeKeySpec = pbeKeySpec; this.param = param; } public String getAlgorithm() { return algorithm; } public String getFormat() { return "RAW"; } public byte[] getEncoded() { if (param != null) { KeyParameter kParam; if (param instanceof ParametersWithIV) { kParam = (KeyParameter)((ParametersWithIV)param).getParameters(); } else { kParam = (KeyParameter)param; } return kParam.getKey(); } else { if (type == PBE.PKCS12) { return PBEParametersGenerator.PKCS12PasswordToBytes(pbeKeySpec.getPassword()); } else { return PBEParametersGenerator.PKCS5PasswordToBytes(pbeKeySpec.getPassword()); } } } int getType() { return type; } int getDigest() { return digest; } int getKeySize() { return keySize; } int getIvSize() { return ivSize; } CipherParameters getParam() { return param; } /** * these should never be called. */ int getIterationCount() { return 0; } byte[] getSalt() { return null; } /** * Return the object identifier associated with this algorithm * * @return the oid for this PBE key */ public ASN1ObjectIdentifier getOID() { return oid; } void setTryWrongPKCS12Zero(boolean tryWrong) { this.tryWrong = tryWrong; } boolean shouldTryWrongPKCS12() { return tryWrong; } } bouncycastle-1.49.orig/jdk1.3/org/bouncycastle/jce/provider/JDKPKCS12KeyStore.java0000644000175000017500000015563411730534433027106 0ustar ebourgebourgpackage org.bouncycastle.jce.provider; import java.io.BufferedInputStream; import java.io.ByteArrayInputStream; import java.io.ByteArrayOutputStream; import java.io.IOException; import java.io.InputStream; import java.io.OutputStream; import java.security.Key; import java.security.KeyStoreException; import java.security.KeyStoreSpi; import java.security.NoSuchAlgorithmException; import java.security.Principal; import java.security.PrivateKey; import java.security.PublicKey; import java.security.SecureRandom; import java.security.UnrecoverableKeyException; import java.security.cert.Certificate; import java.security.cert.CertificateEncodingException; import java.security.cert.CertificateFactory; import java.security.cert.X509Certificate; import java.util.Date; import java.util.Enumeration; import java.util.Hashtable; import java.util.Vector; import javax.crypto.Cipher; import javax.crypto.Mac; import javax.crypto.SecretKey; import javax.crypto.SecretKeyFactory; import javax.crypto.spec.PBEKeySpec; import javax.crypto.spec.PBEParameterSpec; import org.bouncycastle.asn1.ASN1Encodable; import org.bouncycastle.asn1.ASN1EncodableVector; import org.bouncycastle.asn1.ASN1Encoding; import org.bouncycastle.asn1.ASN1InputStream; import org.bouncycastle.asn1.ASN1ObjectIdentifier; import org.bouncycastle.asn1.ASN1OctetString; import org.bouncycastle.asn1.ASN1Primitive; import org.bouncycastle.asn1.ASN1Sequence; import org.bouncycastle.asn1.ASN1Set; import org.bouncycastle.asn1.BERConstructedOctetString; import org.bouncycastle.asn1.BEROutputStream; import org.bouncycastle.asn1.DERBMPString; import org.bouncycastle.asn1.DERNull; import org.bouncycastle.asn1.DEROctetString; import org.bouncycastle.asn1.DEROutputStream; import org.bouncycastle.asn1.DERSequence; import org.bouncycastle.asn1.DERSet; import org.bouncycastle.asn1.pkcs.AuthenticatedSafe; import org.bouncycastle.asn1.pkcs.CertBag; import org.bouncycastle.asn1.pkcs.ContentInfo; import org.bouncycastle.asn1.pkcs.EncryptedData; import org.bouncycastle.asn1.pkcs.MacData; import org.bouncycastle.asn1.pkcs.PKCS12PBEParams; import org.bouncycastle.asn1.pkcs.PKCSObjectIdentifiers; import org.bouncycastle.asn1.pkcs.Pfx; import org.bouncycastle.asn1.pkcs.SafeBag; import org.bouncycastle.asn1.util.ASN1Dump; import org.bouncycastle.asn1.x509.AlgorithmIdentifier; import org.bouncycastle.asn1.x509.AuthorityKeyIdentifier; import org.bouncycastle.asn1.x509.DigestInfo; import org.bouncycastle.asn1.x509.SubjectKeyIdentifier; import org.bouncycastle.asn1.x509.SubjectPublicKeyInfo; import org.bouncycastle.asn1.x509.X509Extensions; import org.bouncycastle.asn1.x509.X509ObjectIdentifiers; import org.bouncycastle.jcajce.provider.symmetric.util.BCPBEKey; import org.bouncycastle.jce.interfaces.BCKeyStore; import org.bouncycastle.jce.interfaces.PKCS12BagAttributeCarrier; import org.bouncycastle.util.Arrays; import org.bouncycastle.util.Strings; import org.bouncycastle.util.encoders.Hex; public class JDKPKCS12KeyStore extends KeyStoreSpi implements PKCSObjectIdentifiers, X509ObjectIdentifiers, BCKeyStore { private static final int SALT_SIZE = 20; private static final int MIN_ITERATIONS = 1024; private IgnoresCaseHashtable keys = new IgnoresCaseHashtable(); private Hashtable localIds = new Hashtable(); private IgnoresCaseHashtable certs = new IgnoresCaseHashtable(); private Hashtable chainCerts = new Hashtable(); private Hashtable keyCerts = new Hashtable(); private static final String bcProvider = "BC"; // // generic object types // static final int NULL = 0; static final int CERTIFICATE = 1; static final int KEY = 2; static final int SECRET = 3; static final int SEALED = 4; // // key types // static final int KEY_PRIVATE = 0; static final int KEY_PUBLIC = 1; static final int KEY_SECRET = 2; protected SecureRandom random = new SecureRandom(); // use of final causes problems with JDK 1.2 compiler private CertificateFactory certFact; private ASN1ObjectIdentifier keyAlgorithm; private ASN1ObjectIdentifier certAlgorithm; private class CertId { byte[] id; CertId( PublicKey key) { this.id = createSubjectKeyId(key).getKeyIdentifier(); } CertId( byte[] id) { this.id = id; } public int hashCode() { return Arrays.hashCode(id); } public boolean equals( Object o) { if (o == this) { return true; } if (!(o instanceof CertId)) { return false; } CertId cId = (CertId)o; return Arrays.areEqual(id, cId.id); } } public JDKPKCS12KeyStore( String provider, ASN1ObjectIdentifier keyAlgorithm, ASN1ObjectIdentifier certAlgorithm) { this.keyAlgorithm = keyAlgorithm; this.certAlgorithm = certAlgorithm; try { if (provider != null) { certFact = CertificateFactory.getInstance("X.509", provider); } else { certFact = CertificateFactory.getInstance("X.509"); } } catch (Exception e) { throw new IllegalArgumentException("can't create cert factory - " + e.toString()); } } private SubjectKeyIdentifier createSubjectKeyId( PublicKey pubKey) { try { SubjectPublicKeyInfo info = new SubjectPublicKeyInfo( (ASN1Sequence) ASN1Primitive.fromByteArray(pubKey.getEncoded())); return new SubjectKeyIdentifier(info); } catch (Exception e) { throw new RuntimeException("error creating key"); } } public void setRandom( SecureRandom rand) { this.random = rand; } public Enumeration engineAliases() { Hashtable tab = new Hashtable(); Enumeration e = certs.keys(); while (e.hasMoreElements()) { tab.put(e.nextElement(), "cert"); } e = keys.keys(); while (e.hasMoreElements()) { String a = (String)e.nextElement(); if (tab.get(a) == null) { tab.put(a, "key"); } } return tab.keys(); } public boolean engineContainsAlias( String alias) { return (certs.get(alias) != null || keys.get(alias) != null); } /** * this is not quite complete - we should follow up on the chain, a bit * tricky if a certificate appears in more than one chain... */ public void engineDeleteEntry( String alias) throws KeyStoreException { Key k = (Key)keys.remove(alias); Certificate c = (Certificate)certs.remove(alias); if (c != null) { chainCerts.remove(new CertId(c.getPublicKey())); } if (k != null) { String id = (String)localIds.remove(alias); if (id != null) { c = (Certificate)keyCerts.remove(id); } if (c != null) { chainCerts.remove(new CertId(c.getPublicKey())); } } if (c == null && k == null) { throw new KeyStoreException("no such entry as " + alias); } } /** * simply return the cert for the private key */ public Certificate engineGetCertificate( String alias) { if (alias == null) { throw new IllegalArgumentException("null alias passed to getCertificate."); } Certificate c = (Certificate)certs.get(alias); // // look up the key table - and try the local key id // if (c == null) { String id = (String)localIds.get(alias); if (id != null) { c = (Certificate)keyCerts.get(id); } else { c = (Certificate)keyCerts.get(alias); } } return c; } public String engineGetCertificateAlias( Certificate cert) { Enumeration c = certs.elements(); Enumeration k = certs.keys(); while (c.hasMoreElements()) { Certificate tc = (Certificate)c.nextElement(); String ta = (String)k.nextElement(); if (tc.equals(cert)) { return ta; } } c = keyCerts.elements(); k = keyCerts.keys(); while (c.hasMoreElements()) { Certificate tc = (Certificate)c.nextElement(); String ta = (String)k.nextElement(); if (tc.equals(cert)) { return ta; } } return null; } public Certificate[] engineGetCertificateChain( String alias) { if (alias == null) { throw new IllegalArgumentException("null alias passed to getCertificateChain."); } if (!engineIsKeyEntry(alias)) { return null; } Certificate c = engineGetCertificate(alias); if (c != null) { Vector cs = new Vector(); while (c != null) { X509Certificate x509c = (X509Certificate)c; Certificate nextC = null; byte[] bytes = x509c.getExtensionValue(X509Extensions.AuthorityKeyIdentifier.getId()); if (bytes != null) { try { ASN1InputStream aIn = new ASN1InputStream(bytes); byte[] authBytes = ((ASN1OctetString)aIn.readObject()).getOctets(); aIn = new ASN1InputStream(authBytes); AuthorityKeyIdentifier id = AuthorityKeyIdentifier.getInstance(aIn.readObject()); if (id.getKeyIdentifier() != null) { nextC = (Certificate)chainCerts.get(new CertId(id.getKeyIdentifier())); } } catch (IOException e) { throw new RuntimeException(e.toString()); } } if (nextC == null) { // // no authority key id, try the Issuer DN // Principal i = x509c.getIssuerDN(); Principal s = x509c.getSubjectDN(); if (!i.equals(s)) { Enumeration e = chainCerts.keys(); while (e.hasMoreElements()) { X509Certificate crt = (X509Certificate)chainCerts.get(e.nextElement()); Principal sub = crt.getSubjectDN(); if (sub.equals(i)) { try { x509c.verify(crt.getPublicKey()); nextC = crt; break; } catch (Exception ex) { // continue } } } } } cs.addElement(c); if (nextC != c) // self signed - end of the chain { c = nextC; } else { c = null; } } Certificate[] certChain = new Certificate[cs.size()]; for (int i = 0; i != certChain.length; i++) { certChain[i] = (Certificate)cs.elementAt(i); } return certChain; } return null; } public Date engineGetCreationDate(String alias) { return new Date(); } public Key engineGetKey( String alias, char[] password) throws NoSuchAlgorithmException, UnrecoverableKeyException { if (alias == null) { throw new IllegalArgumentException("null alias passed to getKey."); } return (Key)keys.get(alias); } public boolean engineIsCertificateEntry( String alias) { return (certs.get(alias) != null && keys.get(alias) == null); } public boolean engineIsKeyEntry( String alias) { return (keys.get(alias) != null); } public void engineSetCertificateEntry( String alias, Certificate cert) throws KeyStoreException { if (keys.get(alias) != null) { throw new KeyStoreException("There is a key entry with the name " + alias + "."); } certs.put(alias, cert); chainCerts.put(new CertId(cert.getPublicKey()), cert); } public void engineSetKeyEntry( String alias, byte[] key, Certificate[] chain) throws KeyStoreException { throw new RuntimeException("operation not supported"); } public void engineSetKeyEntry( String alias, Key key, char[] password, Certificate[] chain) throws KeyStoreException { if ((key instanceof PrivateKey) && (chain == null)) { throw new KeyStoreException("no certificate chain for private key"); } if (keys.get(alias) != null) { engineDeleteEntry(alias); } keys.put(alias, key); certs.put(alias, chain[0]); for (int i = 0; i != chain.length; i++) { chainCerts.put(new CertId(chain[i].getPublicKey()), chain[i]); } } public int engineSize() { Hashtable tab = new Hashtable(); Enumeration e = certs.keys(); while (e.hasMoreElements()) { tab.put(e.nextElement(), "cert"); } e = keys.keys(); while (e.hasMoreElements()) { String a = (String)e.nextElement(); if (tab.get(a) == null) { tab.put(a, "key"); } } return tab.size(); } protected PrivateKey unwrapKey( AlgorithmIdentifier algId, byte[] data, char[] password, boolean wrongPKCS12Zero) throws IOException { String algorithm = algId.getAlgorithm().getId(); PKCS12PBEParams pbeParams = PKCS12PBEParams.getInstance(algId.getParameters()); PBEKeySpec pbeSpec = new PBEKeySpec(password); PrivateKey out; try { SecretKeyFactory keyFact = SecretKeyFactory.getInstance( algorithm, bcProvider); PBEParameterSpec defParams = new PBEParameterSpec( pbeParams.getIV(), pbeParams.getIterations().intValue()); SecretKey k = keyFact.generateSecret(pbeSpec); ((BCPBEKey)k).setTryWrongPKCS12Zero(wrongPKCS12Zero); Cipher cipher = Cipher.getInstance(algorithm, bcProvider); cipher.init(Cipher.UNWRAP_MODE, k, defParams); // we pass "" as the key algorithm type as it is unknown at this point out = (PrivateKey)cipher.unwrap(data, "", Cipher.PRIVATE_KEY); } catch (Exception e) { throw new IOException("exception unwrapping private key - " + e.toString()); } return out; } protected byte[] wrapKey( String algorithm, Key key, PKCS12PBEParams pbeParams, char[] password) throws IOException { PBEKeySpec pbeSpec = new PBEKeySpec(password); byte[] out; try { SecretKeyFactory keyFact = SecretKeyFactory.getInstance( algorithm, bcProvider); PBEParameterSpec defParams = new PBEParameterSpec( pbeParams.getIV(), pbeParams.getIterations().intValue()); Cipher cipher = Cipher.getInstance(algorithm, bcProvider); cipher.init(Cipher.WRAP_MODE, keyFact.generateSecret(pbeSpec), defParams); out = cipher.wrap(key); } catch (Exception e) { throw new IOException("exception encrypting data - " + e.toString()); } return out; } protected byte[] cryptData( boolean forEncryption, AlgorithmIdentifier algId, char[] password, boolean wrongPKCS12Zero, byte[] data) throws IOException { String algorithm = algId.getObjectId().getId(); PKCS12PBEParams pbeParams = PKCS12PBEParams.getInstance(algId.getParameters()); PBEKeySpec pbeSpec = new PBEKeySpec(password); try { SecretKeyFactory keyFact = SecretKeyFactory.getInstance(algorithm, bcProvider); PBEParameterSpec defParams = new PBEParameterSpec( pbeParams.getIV(), pbeParams.getIterations().intValue()); BCPBEKey key = (BCPBEKey) keyFact.generateSecret(pbeSpec); key.setTryWrongPKCS12Zero(wrongPKCS12Zero); Cipher cipher = Cipher.getInstance(algorithm, bcProvider); int mode = forEncryption ? Cipher.ENCRYPT_MODE : Cipher.DECRYPT_MODE; cipher.init(mode, key, defParams); return cipher.doFinal(data); } catch (Exception e) { throw new IOException("exception decrypting data - " + e.toString()); } } public void engineLoad( InputStream stream, char[] password) throws IOException { if (stream == null) // just initialising { return; } if (password == null) { throw new NullPointerException("No password supplied for PKCS#12 KeyStore."); } BufferedInputStream bufIn = new BufferedInputStream(stream); bufIn.mark(10); int head = bufIn.read(); if (head != 0x30) { throw new IOException("stream does not represent a PKCS12 key store"); } bufIn.reset(); ASN1InputStream bIn = new ASN1InputStream(bufIn); ASN1Sequence obj = (ASN1Sequence)bIn.readObject(); Pfx bag = Pfx.getInstance(obj); ContentInfo info = bag.getAuthSafe(); Vector chain = new Vector(); boolean unmarkedKey = false; boolean wrongPKCS12Zero = false; if (bag.getMacData() != null) // check the mac code { MacData mData = bag.getMacData(); DigestInfo dInfo = mData.getMac(); AlgorithmIdentifier algId = dInfo.getAlgorithmId(); byte[] salt = mData.getSalt(); int itCount = mData.getIterationCount().intValue(); byte[] data = ((ASN1OctetString)info.getContent()).getOctets(); try { byte[] res = calculatePbeMac(algId.getObjectId(), salt, itCount, password, false, data); byte[] dig = dInfo.getDigest(); if (!Arrays.constantTimeAreEqual(res, dig)) { if (password.length > 0) { throw new IOException("PKCS12 key store mac invalid - wrong password or corrupted file."); } // Try with incorrect zero length password res = calculatePbeMac(algId.getObjectId(), salt, itCount, password, true, data); if (!Arrays.constantTimeAreEqual(res, dig)) { throw new IOException("PKCS12 key store mac invalid - wrong password or corrupted file."); } wrongPKCS12Zero = true; } } catch (IOException e) { throw e; } catch (Exception e) { throw new IOException("error constructing MAC: " + e.toString()); } } keys = new IgnoresCaseHashtable(); localIds = new Hashtable(); if (info.getContentType().equals(data)) { bIn = new ASN1InputStream(((ASN1OctetString)info.getContent()).getOctets()); AuthenticatedSafe authSafe = AuthenticatedSafe.getInstance(bIn.readObject()); ContentInfo[] c = authSafe.getContentInfo(); for (int i = 0; i != c.length; i++) { if (c[i].getContentType().equals(data)) { ASN1InputStream dIn = new ASN1InputStream(((ASN1OctetString)c[i].getContent()).getOctets()); ASN1Sequence seq = (ASN1Sequence)dIn.readObject(); for (int j = 0; j != seq.size(); j++) { SafeBag b = SafeBag.getInstance(seq.getObjectAt(j)); if (b.getBagId().equals(pkcs8ShroudedKeyBag)) { org.bouncycastle.asn1.pkcs.EncryptedPrivateKeyInfo eIn = org.bouncycastle.asn1.pkcs.EncryptedPrivateKeyInfo.getInstance(b.getBagValue()); PrivateKey privKey = unwrapKey(eIn.getEncryptionAlgorithm(), eIn.getEncryptedData(), password, wrongPKCS12Zero); // // set the attributes on the key // PKCS12BagAttributeCarrier bagAttr = (PKCS12BagAttributeCarrier)privKey; String alias = null; ASN1OctetString localId = null; if (b.getBagAttributes() != null) { Enumeration e = b.getBagAttributes().getObjects(); while (e.hasMoreElements()) { ASN1Sequence sq = (ASN1Sequence)e.nextElement(); ASN1ObjectIdentifier aOid = (ASN1ObjectIdentifier)sq.getObjectAt(0); ASN1Set attrSet = (ASN1Set)sq.getObjectAt(1); ASN1Primitive attr = null; if (attrSet.size() > 0) { attr = (ASN1Primitive)attrSet.getObjectAt(0); ASN1Encodable existing = bagAttr.getBagAttribute(aOid); if (existing != null) { // OK, but the value has to be the same if (!existing.toASN1Primitive().equals(attr)) { throw new IOException( "attempt to add existing attribute with different value"); } } else { bagAttr.setBagAttribute(aOid, attr); } } if (aOid.equals(pkcs_9_at_friendlyName)) { alias = ((DERBMPString)attr).getString(); keys.put(alias, privKey); } else if (aOid.equals(pkcs_9_at_localKeyId)) { localId = (ASN1OctetString)attr; } } } if (localId != null) { String name = new String(Hex.encode(localId.getOctets())); if (alias == null) { keys.put(name, privKey); } else { localIds.put(alias, name); } } else { unmarkedKey = true; keys.put("unmarked", privKey); } } else if (b.getBagId().equals(certBag)) { chain.addElement(b); } else { System.out.println("extra in data " + b.getBagId()); System.out.println(ASN1Dump.dumpAsString(b)); } } } else if (c[i].getContentType().equals(encryptedData)) { EncryptedData d = EncryptedData.getInstance(c[i].getContent()); byte[] octets = cryptData(false, d.getEncryptionAlgorithm(), password, wrongPKCS12Zero, d.getContent().getOctets()); ASN1Sequence seq = (ASN1Sequence) ASN1Primitive.fromByteArray(octets); for (int j = 0; j != seq.size(); j++) { SafeBag b = SafeBag.getInstance(seq.getObjectAt(j)); if (b.getBagId().equals(certBag)) { chain.addElement(b); } else if (b.getBagId().equals(pkcs8ShroudedKeyBag)) { org.bouncycastle.asn1.pkcs.EncryptedPrivateKeyInfo eIn = org.bouncycastle.asn1.pkcs.EncryptedPrivateKeyInfo.getInstance(b.getBagValue()); PrivateKey privKey = unwrapKey(eIn.getEncryptionAlgorithm(), eIn.getEncryptedData(), password, wrongPKCS12Zero); // // set the attributes on the key // PKCS12BagAttributeCarrier bagAttr = (PKCS12BagAttributeCarrier)privKey; String alias = null; ASN1OctetString localId = null; Enumeration e = b.getBagAttributes().getObjects(); while (e.hasMoreElements()) { ASN1Sequence sq = (ASN1Sequence)e.nextElement(); ASN1ObjectIdentifier aOid = (ASN1ObjectIdentifier)sq.getObjectAt(0); ASN1Set attrSet= (ASN1Set)sq.getObjectAt(1); ASN1Primitive attr = null; if (attrSet.size() > 0) { attr = (ASN1Primitive)attrSet.getObjectAt(0); ASN1Encodable existing = bagAttr.getBagAttribute(aOid); if (existing != null) { // OK, but the value has to be the same if (!existing.toASN1Primitive().equals(attr)) { throw new IOException( "attempt to add existing attribute with different value"); } } else { bagAttr.setBagAttribute(aOid, attr); } } if (aOid.equals(pkcs_9_at_friendlyName)) { alias = ((DERBMPString)attr).getString(); keys.put(alias, privKey); } else if (aOid.equals(pkcs_9_at_localKeyId)) { localId = (ASN1OctetString)attr; } } String name = new String(Hex.encode(localId.getOctets())); if (alias == null) { keys.put(name, privKey); } else { localIds.put(alias, name); } } else if (b.getBagId().equals(keyBag)) { org.bouncycastle.asn1.pkcs.PrivateKeyInfo kInfo = new org.bouncycastle.asn1.pkcs.PrivateKeyInfo((ASN1Sequence)b.getBagValue()); PrivateKey privKey = BouncyCastleProvider.getPrivateKey(kInfo); // // set the attributes on the key // PKCS12BagAttributeCarrier bagAttr = (PKCS12BagAttributeCarrier)privKey; String alias = null; ASN1OctetString localId = null; Enumeration e = b.getBagAttributes().getObjects(); while (e.hasMoreElements()) { ASN1Sequence sq = (ASN1Sequence)e.nextElement(); ASN1ObjectIdentifier aOid = (ASN1ObjectIdentifier)sq.getObjectAt(0); ASN1Set attrSet = (ASN1Set)sq.getObjectAt(1); ASN1Primitive attr = null; if (attrSet.size() > 0) { attr = (ASN1Primitive)attrSet.getObjectAt(0); ASN1Encodable existing = bagAttr.getBagAttribute(aOid); if (existing != null) { // OK, but the value has to be the same if (!existing.toASN1Primitive().equals(attr)) { throw new IOException( "attempt to add existing attribute with different value"); } } else { bagAttr.setBagAttribute(aOid, attr); } } if (aOid.equals(pkcs_9_at_friendlyName)) { alias = ((DERBMPString)attr).getString(); keys.put(alias, privKey); } else if (aOid.equals(pkcs_9_at_localKeyId)) { localId = (ASN1OctetString)attr; } } String name = new String(Hex.encode(localId.getOctets())); if (alias == null) { keys.put(name, privKey); } else { localIds.put(alias, name); } } else { System.out.println("extra in encryptedData " + b.getBagId()); System.out.println(ASN1Dump.dumpAsString(b)); } } } else { System.out.println("extra " + c[i].getContentType().getId()); System.out.println("extra " + ASN1Dump.dumpAsString(c[i].getContent())); } } } certs = new IgnoresCaseHashtable(); chainCerts = new Hashtable(); keyCerts = new Hashtable(); for (int i = 0; i != chain.size(); i++) { SafeBag b = (SafeBag)chain.elementAt(i); CertBag cb = CertBag.getInstance(b.getBagValue()); if (!cb.getCertId().equals(x509Certificate)) { throw new RuntimeException("Unsupported certificate type: " + cb.getCertId()); } Certificate cert; try { ByteArrayInputStream cIn = new ByteArrayInputStream( ((ASN1OctetString)cb.getCertValue()).getOctets()); cert = certFact.generateCertificate(cIn); } catch (Exception e) { throw new RuntimeException(e.toString()); } // // set the attributes // ASN1OctetString localId = null; String alias = null; if (b.getBagAttributes() != null) { Enumeration e = b.getBagAttributes().getObjects(); while (e.hasMoreElements()) { ASN1Sequence sq = (ASN1Sequence)e.nextElement(); ASN1ObjectIdentifier oid = (ASN1ObjectIdentifier)sq.getObjectAt(0); ASN1Primitive attr = (ASN1Primitive)((ASN1Set)sq.getObjectAt(1)).getObjectAt(0); PKCS12BagAttributeCarrier bagAttr = null; if (cert instanceof PKCS12BagAttributeCarrier) { bagAttr = (PKCS12BagAttributeCarrier)cert; ASN1Encodable existing = bagAttr.getBagAttribute(oid); if (existing != null) { // OK, but the value has to be the same if (!existing.toASN1Primitive().equals(attr)) { throw new IOException( "attempt to add existing attribute with different value"); } } else { bagAttr.setBagAttribute(oid, attr); } } if (oid.equals(pkcs_9_at_friendlyName)) { alias = ((DERBMPString)attr).getString(); } else if (oid.equals(pkcs_9_at_localKeyId)) { localId = (ASN1OctetString)attr; } } } chainCerts.put(new CertId(cert.getPublicKey()), cert); if (unmarkedKey) { if (keyCerts.isEmpty()) { String name = new String(Hex.encode(createSubjectKeyId(cert.getPublicKey()).getKeyIdentifier())); keyCerts.put(name, cert); keys.put(name, keys.remove("unmarked")); } } else { // // the local key id needs to override the friendly name // if (localId != null) { String name = new String(Hex.encode(localId.getOctets())); keyCerts.put(name, cert); } if (alias != null) { certs.put(alias, cert); } } } } public void engineStore(OutputStream stream, char[] password) throws IOException { doStore(stream, password, false); } private void doStore(OutputStream stream, char[] password, boolean useDEREncoding) throws IOException { if (password == null) { throw new NullPointerException("No password supplied for PKCS#12 KeyStore."); } // // handle the key // ASN1EncodableVector keyS = new ASN1EncodableVector(); Enumeration ks = keys.keys(); while (ks.hasMoreElements()) { byte[] kSalt = new byte[SALT_SIZE]; random.nextBytes(kSalt); String name = (String)ks.nextElement(); PrivateKey privKey = (PrivateKey)keys.get(name); PKCS12PBEParams kParams = new PKCS12PBEParams(kSalt, MIN_ITERATIONS); byte[] kBytes = wrapKey(keyAlgorithm.getId(), privKey, kParams, password); AlgorithmIdentifier kAlgId = new AlgorithmIdentifier(keyAlgorithm, kParams.toASN1Primitive()); org.bouncycastle.asn1.pkcs.EncryptedPrivateKeyInfo kInfo = new org.bouncycastle.asn1.pkcs.EncryptedPrivateKeyInfo(kAlgId, kBytes); boolean attrSet = false; ASN1EncodableVector kName = new ASN1EncodableVector(); if (privKey instanceof PKCS12BagAttributeCarrier) { PKCS12BagAttributeCarrier bagAttrs = (PKCS12BagAttributeCarrier)privKey; // // make sure we are using the local alias on store // DERBMPString nm = (DERBMPString)bagAttrs.getBagAttribute(pkcs_9_at_friendlyName); if (nm == null || !nm.getString().equals(name)) { bagAttrs.setBagAttribute(pkcs_9_at_friendlyName, new DERBMPString(name)); } // // make sure we have a local key-id // if (bagAttrs.getBagAttribute(pkcs_9_at_localKeyId) == null) { Certificate ct = engineGetCertificate(name); bagAttrs.setBagAttribute(pkcs_9_at_localKeyId, createSubjectKeyId(ct.getPublicKey())); } Enumeration e = bagAttrs.getBagAttributeKeys(); while (e.hasMoreElements()) { ASN1ObjectIdentifier oid = (ASN1ObjectIdentifier)e.nextElement(); ASN1EncodableVector kSeq = new ASN1EncodableVector(); kSeq.add(oid); kSeq.add(new DERSet(bagAttrs.getBagAttribute(oid))); attrSet = true; kName.add(new DERSequence(kSeq)); } } if (!attrSet) { // // set a default friendly name (from the key id) and local id // ASN1EncodableVector kSeq = new ASN1EncodableVector(); Certificate ct = engineGetCertificate(name); kSeq.add(pkcs_9_at_localKeyId); kSeq.add(new DERSet(createSubjectKeyId(ct.getPublicKey()))); kName.add(new DERSequence(kSeq)); kSeq = new ASN1EncodableVector(); kSeq.add(pkcs_9_at_friendlyName); kSeq.add(new DERSet(new DERBMPString(name))); kName.add(new DERSequence(kSeq)); } SafeBag kBag = new SafeBag(pkcs8ShroudedKeyBag, kInfo.toASN1Primitive(), new DERSet(kName)); keyS.add(kBag); } byte[] keySEncoded = new DERSequence(keyS).getEncoded(ASN1Encoding.DER); BERConstructedOctetString keyString = new BERConstructedOctetString(keySEncoded); // // certificate processing // byte[] cSalt = new byte[SALT_SIZE]; random.nextBytes(cSalt); ASN1EncodableVector certSeq = new ASN1EncodableVector(); PKCS12PBEParams cParams = new PKCS12PBEParams(cSalt, MIN_ITERATIONS); AlgorithmIdentifier cAlgId = new AlgorithmIdentifier(certAlgorithm, cParams.toASN1Primitive()); Hashtable doneCerts = new Hashtable(); Enumeration cs = keys.keys(); while (cs.hasMoreElements()) { try { String name = (String)cs.nextElement(); Certificate cert = engineGetCertificate(name); boolean cAttrSet = false; CertBag cBag = new CertBag( x509Certificate, new DEROctetString(cert.getEncoded())); ASN1EncodableVector fName = new ASN1EncodableVector(); if (cert instanceof PKCS12BagAttributeCarrier) { PKCS12BagAttributeCarrier bagAttrs = (PKCS12BagAttributeCarrier)cert; // // make sure we are using the local alias on store // DERBMPString nm = (DERBMPString)bagAttrs.getBagAttribute(pkcs_9_at_friendlyName); if (nm == null || !nm.getString().equals(name)) { bagAttrs.setBagAttribute(pkcs_9_at_friendlyName, new DERBMPString(name)); } // // make sure we have a local key-id // if (bagAttrs.getBagAttribute(pkcs_9_at_localKeyId) == null) { bagAttrs.setBagAttribute(pkcs_9_at_localKeyId, createSubjectKeyId(cert.getPublicKey())); } Enumeration e = bagAttrs.getBagAttributeKeys(); while (e.hasMoreElements()) { ASN1ObjectIdentifier oid = (ASN1ObjectIdentifier)e.nextElement(); ASN1EncodableVector fSeq = new ASN1EncodableVector(); fSeq.add(oid); fSeq.add(new DERSet(bagAttrs.getBagAttribute(oid))); fName.add(new DERSequence(fSeq)); cAttrSet = true; } } if (!cAttrSet) { ASN1EncodableVector fSeq = new ASN1EncodableVector(); fSeq.add(pkcs_9_at_localKeyId); fSeq.add(new DERSet(createSubjectKeyId(cert.getPublicKey()))); fName.add(new DERSequence(fSeq)); fSeq = new ASN1EncodableVector(); fSeq.add(pkcs_9_at_friendlyName); fSeq.add(new DERSet(new DERBMPString(name))); fName.add(new DERSequence(fSeq)); } SafeBag sBag = new SafeBag(certBag, cBag.toASN1Primitive(), new DERSet(fName)); certSeq.add(sBag); doneCerts.put(cert, cert); } catch (CertificateEncodingException e) { throw new IOException("Error encoding certificate: " + e.toString()); } } cs = certs.keys(); while (cs.hasMoreElements()) { try { String certId = (String)cs.nextElement(); Certificate cert = (Certificate)certs.get(certId); boolean cAttrSet = false; if (keys.get(certId) != null) { continue; } CertBag cBag = new CertBag( x509Certificate, new DEROctetString(cert.getEncoded())); ASN1EncodableVector fName = new ASN1EncodableVector(); if (cert instanceof PKCS12BagAttributeCarrier) { PKCS12BagAttributeCarrier bagAttrs = (PKCS12BagAttributeCarrier)cert; // // make sure we are using the local alias on store // DERBMPString nm = (DERBMPString)bagAttrs.getBagAttribute(pkcs_9_at_friendlyName); if (nm == null || !nm.getString().equals(certId)) { bagAttrs.setBagAttribute(pkcs_9_at_friendlyName, new DERBMPString(certId)); } Enumeration e = bagAttrs.getBagAttributeKeys(); while (e.hasMoreElements()) { ASN1ObjectIdentifier oid = (ASN1ObjectIdentifier)e.nextElement(); // a certificate not immediately linked to a key doesn't require // a localKeyID and will confuse some PKCS12 implementations. // // If we find one, we'll prune it out. if (oid.equals(PKCSObjectIdentifiers.pkcs_9_at_localKeyId)) { continue; } ASN1EncodableVector fSeq = new ASN1EncodableVector(); fSeq.add(oid); fSeq.add(new DERSet(bagAttrs.getBagAttribute(oid))); fName.add(new DERSequence(fSeq)); cAttrSet = true; } } if (!cAttrSet) { ASN1EncodableVector fSeq = new ASN1EncodableVector(); fSeq.add(pkcs_9_at_friendlyName); fSeq.add(new DERSet(new DERBMPString(certId))); fName.add(new DERSequence(fSeq)); } SafeBag sBag = new SafeBag(certBag, cBag.toASN1Primitive(), new DERSet(fName)); certSeq.add(sBag); doneCerts.put(cert, cert); } catch (CertificateEncodingException e) { throw new IOException("Error encoding certificate: " + e.toString()); } } cs = chainCerts.keys(); while (cs.hasMoreElements()) { try { CertId certId = (CertId)cs.nextElement(); Certificate cert = (Certificate)chainCerts.get(certId); if (doneCerts.get(cert) != null) { continue; } CertBag cBag = new CertBag( x509Certificate, new DEROctetString(cert.getEncoded())); ASN1EncodableVector fName = new ASN1EncodableVector(); if (cert instanceof PKCS12BagAttributeCarrier) { PKCS12BagAttributeCarrier bagAttrs = (PKCS12BagAttributeCarrier)cert; Enumeration e = bagAttrs.getBagAttributeKeys(); while (e.hasMoreElements()) { ASN1ObjectIdentifier oid = (ASN1ObjectIdentifier)e.nextElement(); // a certificate not immediately linked to a key doesn't require // a localKeyID and will confuse some PKCS12 implementations. // // If we find one, we'll prune it out. if (oid.equals(PKCSObjectIdentifiers.pkcs_9_at_localKeyId)) { continue; } ASN1EncodableVector fSeq = new ASN1EncodableVector(); fSeq.add(oid); fSeq.add(new DERSet(bagAttrs.getBagAttribute(oid))); fName.add(new DERSequence(fSeq)); } } SafeBag sBag = new SafeBag(certBag, cBag.toASN1Primitive(), new DERSet(fName)); certSeq.add(sBag); } catch (CertificateEncodingException e) { throw new IOException("Error encoding certificate: " + e.toString()); } } byte[] certSeqEncoded = new DERSequence(certSeq).getEncoded(ASN1Encoding.DER); byte[] certBytes = cryptData(true, cAlgId, password, false, certSeqEncoded); EncryptedData cInfo = new EncryptedData(data, cAlgId, new BERConstructedOctetString(certBytes)); ContentInfo[] info = new ContentInfo[] { new ContentInfo(data, keyString), new ContentInfo(encryptedData, cInfo.toASN1Primitive()) }; AuthenticatedSafe auth = new AuthenticatedSafe(info); ByteArrayOutputStream bOut = new ByteArrayOutputStream(); DEROutputStream asn1Out; if (useDEREncoding) { asn1Out = new DEROutputStream(bOut); } else { asn1Out = new BEROutputStream(bOut); } asn1Out.writeObject(auth); byte[] pkg = bOut.toByteArray(); ContentInfo mainInfo = new ContentInfo(data, new BERConstructedOctetString(pkg)); // // create the mac // byte[] mSalt = new byte[20]; int itCount = MIN_ITERATIONS; random.nextBytes(mSalt); byte[] data = ((ASN1OctetString)mainInfo.getContent()).getOctets(); MacData mData; try { byte[] res = calculatePbeMac(id_SHA1, mSalt, itCount, password, false, data); AlgorithmIdentifier algId = new AlgorithmIdentifier(id_SHA1, new DERNull()); DigestInfo dInfo = new DigestInfo(algId, res); mData = new MacData(dInfo, mSalt, itCount); } catch (Exception e) { throw new IOException("error constructing MAC: " + e.toString()); } // // output the Pfx // Pfx pfx = new Pfx(mainInfo, mData); if (useDEREncoding) { asn1Out = new DEROutputStream(stream); } else { asn1Out = new BEROutputStream(stream); } asn1Out.writeObject(pfx); } private static byte[] calculatePbeMac( ASN1ObjectIdentifier oid, byte[] salt, int itCount, char[] password, boolean wrongPkcs12Zero, byte[] data) throws Exception { SecretKeyFactory keyFact = SecretKeyFactory.getInstance(oid.getId(), bcProvider); PBEParameterSpec defParams = new PBEParameterSpec(salt, itCount); PBEKeySpec pbeSpec = new PBEKeySpec(password); BCPBEKey key = (BCPBEKey) keyFact.generateSecret(pbeSpec); key.setTryWrongPKCS12Zero(wrongPkcs12Zero); Mac mac = Mac.getInstance(oid.getId(), bcProvider); mac.init(key, defParams); mac.update(data); return mac.doFinal(); } public static class BCPKCS12KeyStore extends JDKPKCS12KeyStore { public BCPKCS12KeyStore() { super(bcProvider, pbeWithSHAAnd3_KeyTripleDES_CBC, pbeWithSHAAnd40BitRC2_CBC); } } public static class BCPKCS12KeyStore3DES extends JDKPKCS12KeyStore { public BCPKCS12KeyStore3DES() { super(bcProvider, pbeWithSHAAnd3_KeyTripleDES_CBC, pbeWithSHAAnd3_KeyTripleDES_CBC); } } public static class DefPKCS12KeyStore extends JDKPKCS12KeyStore { public DefPKCS12KeyStore() { super(null, pbeWithSHAAnd3_KeyTripleDES_CBC, pbeWithSHAAnd40BitRC2_CBC); } } public static class DefPKCS12KeyStore3DES extends JDKPKCS12KeyStore { public DefPKCS12KeyStore3DES() { super(null, pbeWithSHAAnd3_KeyTripleDES_CBC, pbeWithSHAAnd3_KeyTripleDES_CBC); } } private static class IgnoresCaseHashtable { private Hashtable orig = new Hashtable(); private Hashtable keys = new Hashtable(); public void put(String key, Object value) { String lower = Strings.toLowerCase(key); String k = (String)keys.get(lower); if (k != null) { orig.remove(k); } keys.put(lower, key); orig.put(key, value); } public Enumeration keys() { return orig.keys(); } public Object remove(String alias) { String k = (String)keys.remove(Strings.toLowerCase(alias)); if (k == null) { return null; } return orig.remove(k); } public Object get(String alias) { String k = (String)keys.get(Strings.toLowerCase(alias)); if (k == null) { return null; } return orig.get(k); } public Enumeration elements() { return orig.elements(); } } } bouncycastle-1.49.orig/jdk1.3/org/bouncycastle/jce/PKCS10CertificationRequest.java0000644000175000017500000005400012104624114027261 0ustar ebourgebourgpackage org.bouncycastle.jce; import java.io.IOException; import java.security.AlgorithmParameters; import java.security.GeneralSecurityException; import java.security.InvalidKeyException; import java.security.KeyFactory; import java.security.NoSuchAlgorithmException; import java.security.NoSuchProviderException; import java.security.PrivateKey; import java.security.PublicKey; import java.security.Signature; import java.security.SignatureException; import java.security.spec.InvalidKeySpecException; import java.security.spec.X509EncodedKeySpec; import java.util.HashSet; import java.util.Hashtable; import java.util.Set; import org.bouncycastle.asn1.ASN1Encodable; import org.bouncycastle.asn1.ASN1Encoding; import org.bouncycastle.asn1.ASN1InputStream; import org.bouncycastle.asn1.ASN1Integer; import org.bouncycastle.asn1.ASN1Primitive; import org.bouncycastle.asn1.ASN1Sequence; import org.bouncycastle.asn1.ASN1Set; import org.bouncycastle.asn1.DERBitString; import org.bouncycastle.asn1.DERNull; import org.bouncycastle.asn1.DERObjectIdentifier; import org.bouncycastle.asn1.cryptopro.CryptoProObjectIdentifiers; import org.bouncycastle.asn1.nist.NISTObjectIdentifiers; import org.bouncycastle.asn1.oiw.OIWObjectIdentifiers; import org.bouncycastle.asn1.pkcs.CertificationRequest; import org.bouncycastle.asn1.pkcs.CertificationRequestInfo; import org.bouncycastle.asn1.pkcs.PKCSObjectIdentifiers; import org.bouncycastle.asn1.pkcs.RSASSAPSSparams; import org.bouncycastle.asn1.teletrust.TeleTrusTObjectIdentifiers; import org.bouncycastle.asn1.x509.AlgorithmIdentifier; import org.bouncycastle.asn1.x509.SubjectPublicKeyInfo; import org.bouncycastle.asn1.x509.X509Name; import org.bouncycastle.asn1.x9.X9ObjectIdentifiers; import org.bouncycastle.jce.provider.BouncyCastleProvider; import org.bouncycastle.util.Strings; /** * A class for verifying and creating PKCS10 Certification requests. *
 * CertificationRequest ::= SEQUENCE {
 *   certificationRequestInfo  CertificationRequestInfo,
 *   signatureAlgorithm        AlgorithmIdentifier{{ SignatureAlgorithms }},
 *   signature                 BIT STRING
 * }
 *
 * CertificationRequestInfo ::= SEQUENCE {
 *   version             INTEGER { v1(0) } (v1,...),
 *   subject             Name,
 *   subjectPKInfo   SubjectPublicKeyInfo{{ PKInfoAlgorithms }},
 *   attributes          [0] Attributes{{ CRIAttributes }}
 *  }
 *
 *  Attributes { ATTRIBUTE:IOSet } ::= SET OF Attribute{{ IOSet }}
 *
 *  Attribute { ATTRIBUTE:IOSet } ::= SEQUENCE {
 *    type    ATTRIBUTE.&id({IOSet}),
 *    values  SET SIZE(1..MAX) OF ATTRIBUTE.&Type({IOSet}{\@type})
 *  }
 * 
* @deprecated use classes in org.bouncycastle.pkcs. */ public class PKCS10CertificationRequest extends CertificationRequest { private static Hashtable algorithms = new Hashtable(); private static Hashtable params = new Hashtable(); private static Hashtable keyAlgorithms = new Hashtable(); private static Hashtable oids = new Hashtable(); private static Set noParams = new HashSet(); static { algorithms.put("MD2WITHRSAENCRYPTION", new DERObjectIdentifier("1.2.840.113549.1.1.2")); algorithms.put("MD2WITHRSA", new DERObjectIdentifier("1.2.840.113549.1.1.2")); algorithms.put("MD5WITHRSAENCRYPTION", new DERObjectIdentifier("1.2.840.113549.1.1.4")); algorithms.put("MD5WITHRSA", new DERObjectIdentifier("1.2.840.113549.1.1.4")); algorithms.put("RSAWITHMD5", new DERObjectIdentifier("1.2.840.113549.1.1.4")); algorithms.put("SHA1WITHRSAENCRYPTION", new DERObjectIdentifier("1.2.840.113549.1.1.5")); algorithms.put("SHA1WITHRSA", new DERObjectIdentifier("1.2.840.113549.1.1.5")); algorithms.put("SHA224WITHRSAENCRYPTION", PKCSObjectIdentifiers.sha224WithRSAEncryption); algorithms.put("SHA224WITHRSA", PKCSObjectIdentifiers.sha224WithRSAEncryption); algorithms.put("SHA256WITHRSAENCRYPTION", PKCSObjectIdentifiers.sha256WithRSAEncryption); algorithms.put("SHA256WITHRSA", PKCSObjectIdentifiers.sha256WithRSAEncryption); algorithms.put("SHA384WITHRSAENCRYPTION", PKCSObjectIdentifiers.sha384WithRSAEncryption); algorithms.put("SHA384WITHRSA", PKCSObjectIdentifiers.sha384WithRSAEncryption); algorithms.put("SHA512WITHRSAENCRYPTION", PKCSObjectIdentifiers.sha512WithRSAEncryption); algorithms.put("SHA512WITHRSA", PKCSObjectIdentifiers.sha512WithRSAEncryption); algorithms.put("SHA1WITHRSAANDMGF1", PKCSObjectIdentifiers.id_RSASSA_PSS); algorithms.put("SHA224WITHRSAANDMGF1", PKCSObjectIdentifiers.id_RSASSA_PSS); algorithms.put("SHA256WITHRSAANDMGF1", PKCSObjectIdentifiers.id_RSASSA_PSS); algorithms.put("SHA384WITHRSAANDMGF1", PKCSObjectIdentifiers.id_RSASSA_PSS); algorithms.put("SHA512WITHRSAANDMGF1", PKCSObjectIdentifiers.id_RSASSA_PSS); algorithms.put("RSAWITHSHA1", new DERObjectIdentifier("1.2.840.113549.1.1.5")); algorithms.put("RIPEMD128WITHRSAENCRYPTION", TeleTrusTObjectIdentifiers.rsaSignatureWithripemd128); algorithms.put("RIPEMD128WITHRSA", TeleTrusTObjectIdentifiers.rsaSignatureWithripemd128); algorithms.put("RIPEMD160WITHRSAENCRYPTION", TeleTrusTObjectIdentifiers.rsaSignatureWithripemd160); algorithms.put("RIPEMD160WITHRSA", TeleTrusTObjectIdentifiers.rsaSignatureWithripemd160); algorithms.put("RIPEMD256WITHRSAENCRYPTION", TeleTrusTObjectIdentifiers.rsaSignatureWithripemd256); algorithms.put("RIPEMD256WITHRSA", TeleTrusTObjectIdentifiers.rsaSignatureWithripemd256); algorithms.put("SHA1WITHDSA", new DERObjectIdentifier("1.2.840.10040.4.3")); algorithms.put("DSAWITHSHA1", new DERObjectIdentifier("1.2.840.10040.4.3")); algorithms.put("SHA224WITHDSA", NISTObjectIdentifiers.dsa_with_sha224); algorithms.put("SHA256WITHDSA", NISTObjectIdentifiers.dsa_with_sha256); algorithms.put("SHA384WITHDSA", NISTObjectIdentifiers.dsa_with_sha384); algorithms.put("SHA512WITHDSA", NISTObjectIdentifiers.dsa_with_sha512); algorithms.put("SHA1WITHECDSA", X9ObjectIdentifiers.ecdsa_with_SHA1); algorithms.put("SHA224WITHECDSA", X9ObjectIdentifiers.ecdsa_with_SHA224); algorithms.put("SHA256WITHECDSA", X9ObjectIdentifiers.ecdsa_with_SHA256); algorithms.put("SHA384WITHECDSA", X9ObjectIdentifiers.ecdsa_with_SHA384); algorithms.put("SHA512WITHECDSA", X9ObjectIdentifiers.ecdsa_with_SHA512); algorithms.put("ECDSAWITHSHA1", X9ObjectIdentifiers.ecdsa_with_SHA1); algorithms.put("GOST3411WITHGOST3410", CryptoProObjectIdentifiers.gostR3411_94_with_gostR3410_94); algorithms.put("GOST3410WITHGOST3411", CryptoProObjectIdentifiers.gostR3411_94_with_gostR3410_94); algorithms.put("GOST3411WITHECGOST3410", CryptoProObjectIdentifiers.gostR3411_94_with_gostR3410_2001); algorithms.put("GOST3411WITHECGOST3410-2001", CryptoProObjectIdentifiers.gostR3411_94_with_gostR3410_2001); algorithms.put("GOST3411WITHGOST3410-2001", CryptoProObjectIdentifiers.gostR3411_94_with_gostR3410_2001); // // reverse mappings // oids.put(new DERObjectIdentifier("1.2.840.113549.1.1.5"), "SHA1WITHRSA"); oids.put(PKCSObjectIdentifiers.sha224WithRSAEncryption, "SHA224WITHRSA"); oids.put(PKCSObjectIdentifiers.sha256WithRSAEncryption, "SHA256WITHRSA"); oids.put(PKCSObjectIdentifiers.sha384WithRSAEncryption, "SHA384WITHRSA"); oids.put(PKCSObjectIdentifiers.sha512WithRSAEncryption, "SHA512WITHRSA"); oids.put(CryptoProObjectIdentifiers.gostR3411_94_with_gostR3410_94, "GOST3411WITHGOST3410"); oids.put(CryptoProObjectIdentifiers.gostR3411_94_with_gostR3410_2001, "GOST3411WITHECGOST3410"); oids.put(new DERObjectIdentifier("1.2.840.113549.1.1.4"), "MD5WITHRSA"); oids.put(new DERObjectIdentifier("1.2.840.113549.1.1.2"), "MD2WITHRSA"); oids.put(new DERObjectIdentifier("1.2.840.10040.4.3"), "SHA1WITHDSA"); oids.put(X9ObjectIdentifiers.ecdsa_with_SHA1, "SHA1WITHECDSA"); oids.put(X9ObjectIdentifiers.ecdsa_with_SHA224, "SHA224WITHECDSA"); oids.put(X9ObjectIdentifiers.ecdsa_with_SHA256, "SHA256WITHECDSA"); oids.put(X9ObjectIdentifiers.ecdsa_with_SHA384, "SHA384WITHECDSA"); oids.put(X9ObjectIdentifiers.ecdsa_with_SHA512, "SHA512WITHECDSA"); oids.put(OIWObjectIdentifiers.sha1WithRSA, "SHA1WITHRSA"); oids.put(OIWObjectIdentifiers.dsaWithSHA1, "SHA1WITHDSA"); oids.put(NISTObjectIdentifiers.dsa_with_sha224, "SHA224WITHDSA"); oids.put(NISTObjectIdentifiers.dsa_with_sha256, "SHA256WITHDSA"); // // key types // keyAlgorithms.put(PKCSObjectIdentifiers.rsaEncryption, "RSA"); keyAlgorithms.put(X9ObjectIdentifiers.id_dsa, "DSA"); // // According to RFC 3279, the ASN.1 encoding SHALL (id-dsa-with-sha1) or MUST (ecdsa-with-SHA*) omit the parameters field. // The parameters field SHALL be NULL for RSA based signature algorithms. // noParams.add(X9ObjectIdentifiers.ecdsa_with_SHA1); noParams.add(X9ObjectIdentifiers.ecdsa_with_SHA224); noParams.add(X9ObjectIdentifiers.ecdsa_with_SHA256); noParams.add(X9ObjectIdentifiers.ecdsa_with_SHA384); noParams.add(X9ObjectIdentifiers.ecdsa_with_SHA512); noParams.add(X9ObjectIdentifiers.id_dsa_with_sha1); noParams.add(NISTObjectIdentifiers.dsa_with_sha224); noParams.add(NISTObjectIdentifiers.dsa_with_sha256); // // RFC 4491 // noParams.add(CryptoProObjectIdentifiers.gostR3411_94_with_gostR3410_94); noParams.add(CryptoProObjectIdentifiers.gostR3411_94_with_gostR3410_2001); // // explicit params // AlgorithmIdentifier sha1AlgId = new AlgorithmIdentifier(OIWObjectIdentifiers.idSHA1, new DERNull()); params.put("SHA1WITHRSAANDMGF1", creatPSSParams(sha1AlgId, 20)); AlgorithmIdentifier sha224AlgId = new AlgorithmIdentifier(NISTObjectIdentifiers.id_sha224, new DERNull()); params.put("SHA224WITHRSAANDMGF1", creatPSSParams(sha224AlgId, 28)); AlgorithmIdentifier sha256AlgId = new AlgorithmIdentifier(NISTObjectIdentifiers.id_sha256, new DERNull()); params.put("SHA256WITHRSAANDMGF1", creatPSSParams(sha256AlgId, 32)); AlgorithmIdentifier sha384AlgId = new AlgorithmIdentifier(NISTObjectIdentifiers.id_sha384, new DERNull()); params.put("SHA384WITHRSAANDMGF1", creatPSSParams(sha384AlgId, 48)); AlgorithmIdentifier sha512AlgId = new AlgorithmIdentifier(NISTObjectIdentifiers.id_sha512, new DERNull()); params.put("SHA512WITHRSAANDMGF1", creatPSSParams(sha512AlgId, 64)); } private static RSASSAPSSparams creatPSSParams(AlgorithmIdentifier hashAlgId, int saltSize) { return new RSASSAPSSparams( hashAlgId, new AlgorithmIdentifier(PKCSObjectIdentifiers.id_mgf1, hashAlgId), new ASN1Integer(saltSize), new ASN1Integer(1)); } private static ASN1Sequence toDERSequence( byte[] bytes) { try { ASN1InputStream dIn = new ASN1InputStream(bytes); return (ASN1Sequence)dIn.readObject(); } catch (Exception e) { throw new IllegalArgumentException("badly encoded request"); } } /** * construct a PKCS10 certification request from a DER encoded * byte stream. */ public PKCS10CertificationRequest( byte[] bytes) { super(toDERSequence(bytes)); } public PKCS10CertificationRequest( ASN1Sequence sequence) { super(sequence); } /** * create a PKCS10 certfication request using the BC provider. */ public PKCS10CertificationRequest( String signatureAlgorithm, X509Name subject, PublicKey key, ASN1Set attributes, PrivateKey signingKey) throws NoSuchAlgorithmException, NoSuchProviderException, InvalidKeyException, SignatureException { this(signatureAlgorithm, subject, key, attributes, signingKey, BouncyCastleProvider.PROVIDER_NAME); } /** * create a PKCS10 certfication request using the named provider. */ public PKCS10CertificationRequest( String signatureAlgorithm, X509Name subject, PublicKey key, ASN1Set attributes, PrivateKey signingKey, String provider) throws NoSuchAlgorithmException, NoSuchProviderException, InvalidKeyException, SignatureException { String algorithmName = Strings.toUpperCase(signatureAlgorithm); DERObjectIdentifier sigOID = (DERObjectIdentifier)algorithms.get(algorithmName); if (sigOID == null) { try { sigOID = new DERObjectIdentifier(algorithmName); } catch (Exception e) { throw new IllegalArgumentException("Unknown signature type requested"); } } if (subject == null) { throw new IllegalArgumentException("subject must not be null"); } if (key == null) { throw new IllegalArgumentException("public key must not be null"); } if (noParams.contains(sigOID)) { this.sigAlgId = new AlgorithmIdentifier(sigOID); } else if (params.containsKey(algorithmName)) { this.sigAlgId = new AlgorithmIdentifier(sigOID, (ASN1Encodable)params.get(algorithmName)); } else { this.sigAlgId = new AlgorithmIdentifier(sigOID, DERNull.INSTANCE); } try { ASN1Sequence seq = (ASN1Sequence)ASN1Primitive.fromByteArray(key.getEncoded()); this.reqInfo = new CertificationRequestInfo(subject, new SubjectPublicKeyInfo(seq), attributes); } catch (IOException e) { throw new IllegalArgumentException("can't encode public key"); } Signature sig; if (provider == null) { sig = Signature.getInstance(signatureAlgorithm); } else { sig = Signature.getInstance(signatureAlgorithm, provider); } sig.initSign(signingKey); try { sig.update(reqInfo.getEncoded(ASN1Encoding.DER)); } catch (Exception e) { throw new IllegalArgumentException("exception encoding TBS cert request - " + e); } this.sigBits = new DERBitString(sig.sign()); } /** * return the public key associated with the certification request - * the public key is created using the BC provider. */ public PublicKey getPublicKey() throws NoSuchAlgorithmException, NoSuchProviderException, InvalidKeyException { return getPublicKey(BouncyCastleProvider.PROVIDER_NAME); } public PublicKey getPublicKey( String provider) throws NoSuchAlgorithmException, NoSuchProviderException, InvalidKeyException { SubjectPublicKeyInfo subjectPKInfo = reqInfo.getSubjectPublicKeyInfo(); try { X509EncodedKeySpec xspec = new X509EncodedKeySpec(new DERBitString(subjectPKInfo).getBytes()); AlgorithmIdentifier keyAlg = subjectPKInfo.getAlgorithm(); try { if (provider == null) { return KeyFactory.getInstance(keyAlg.getAlgorithm().getId()).generatePublic(xspec); } else { return KeyFactory.getInstance(keyAlg.getAlgorithm().getId(), provider).generatePublic(xspec); } } catch (NoSuchAlgorithmException e) { // // try an alternate // if (keyAlgorithms.get(keyAlg.getObjectId()) != null) { String keyAlgorithm = (String)keyAlgorithms.get(keyAlg.getObjectId()); if (provider == null) { return KeyFactory.getInstance(keyAlgorithm).generatePublic(xspec); } else { return KeyFactory.getInstance(keyAlgorithm, provider).generatePublic(xspec); } } throw e; } } catch (InvalidKeySpecException e) { throw new InvalidKeyException("error decoding public key"); } catch (IOException e) { throw new InvalidKeyException("error decoding public key"); } } /** * verify the request using the BC provider. */ public boolean verify() throws NoSuchAlgorithmException, NoSuchProviderException, InvalidKeyException, SignatureException { return verify(BouncyCastleProvider.PROVIDER_NAME); } /** * verify the request using the passed in provider. */ public boolean verify( String provider) throws NoSuchAlgorithmException, NoSuchProviderException, InvalidKeyException, SignatureException { return verify(this.getPublicKey(provider), provider); } /** * verify the request using the passed in public key and the provider.. */ public boolean verify( PublicKey pubKey, String provider) throws NoSuchAlgorithmException, NoSuchProviderException, InvalidKeyException, SignatureException { Signature sig; try { if (provider == null) { sig = Signature.getInstance(getSignatureName(sigAlgId)); } else { sig = Signature.getInstance(getSignatureName(sigAlgId), provider); } } catch (NoSuchAlgorithmException e) { // // try an alternate // if (oids.get(sigAlgId.getObjectId()) != null) { String signatureAlgorithm = (String)oids.get(sigAlgId.getObjectId()); if (provider == null) { sig = Signature.getInstance(signatureAlgorithm); } else { sig = Signature.getInstance(signatureAlgorithm, provider); } } else { throw e; } } setSignatureParameters(sig, sigAlgId.getParameters(), provider); sig.initVerify(pubKey); try { sig.update(reqInfo.getEncoded(ASN1Encoding.DER)); } catch (Exception e) { throw new SignatureException("exception encoding TBS cert request - " + e); } return sig.verify(sigBits.getBytes()); } /** * return a DER encoded byte array representing this object */ public byte[] getEncoded() { try { return this.getEncoded(ASN1Encoding.DER); } catch (IOException e) { throw new RuntimeException(e.toString()); } } private void setSignatureParameters( Signature signature, ASN1Encodable params, String provider) throws NoSuchAlgorithmException, NoSuchProviderException, SignatureException, InvalidKeyException { if (params != null && !DERNull.INSTANCE.equals(params)) { AlgorithmParameters sigParams = AlgorithmParameters.getInstance(signature.getAlgorithm(), provider); try { sigParams.init(params.toASN1Primitive().getEncoded(ASN1Encoding.DER)); } catch (IOException e) { throw new SignatureException("IOException decoding parameters: " + e.getMessage()); } } } static String getSignatureName( AlgorithmIdentifier sigAlgId) { ASN1Encodable params = sigAlgId.getParameters(); if (params != null && !DERNull.INSTANCE.equals(params)) { if (sigAlgId.getObjectId().equals(PKCSObjectIdentifiers.id_RSASSA_PSS)) { RSASSAPSSparams rsaParams = RSASSAPSSparams.getInstance(params); return getDigestAlgName(rsaParams.getHashAlgorithm().getObjectId()) + "withRSAandMGF1"; } } return sigAlgId.getObjectId().getId(); } private static String getDigestAlgName( DERObjectIdentifier digestAlgOID) { if (PKCSObjectIdentifiers.md5.equals(digestAlgOID)) { return "MD5"; } else if (OIWObjectIdentifiers.idSHA1.equals(digestAlgOID)) { return "SHA1"; } else if (NISTObjectIdentifiers.id_sha224.equals(digestAlgOID)) { return "SHA224"; } else if (NISTObjectIdentifiers.id_sha256.equals(digestAlgOID)) { return "SHA256"; } else if (NISTObjectIdentifiers.id_sha384.equals(digestAlgOID)) { return "SHA384"; } else if (NISTObjectIdentifiers.id_sha512.equals(digestAlgOID)) { return "SHA512"; } else if (TeleTrusTObjectIdentifiers.ripemd128.equals(digestAlgOID)) { return "RIPEMD128"; } else if (TeleTrusTObjectIdentifiers.ripemd160.equals(digestAlgOID)) { return "RIPEMD160"; } else if (TeleTrusTObjectIdentifiers.ripemd256.equals(digestAlgOID)) { return "RIPEMD256"; } else if (CryptoProObjectIdentifiers.gostR3411.equals(digestAlgOID)) { return "GOST3411"; } else { return digestAlgOID.getId(); } } } bouncycastle-1.49.orig/jdk1.3/org/bouncycastle/jce/cert/0000755000175000017500000000000012152033550022377 5ustar ebourgebourgbouncycastle-1.49.orig/jdk1.3/org/bouncycastle/jce/cert/PolicyQualifierInfo.java0000644000175000017500000001647211701477362027205 0ustar ebourgebourgpackage org.bouncycastle.jce.cert; import java.io.ByteArrayInputStream; import java.io.ByteArrayOutputStream; import java.io.IOException; import org.bouncycastle.asn1.ASN1InputStream; import org.bouncycastle.asn1.ASN1Object; import org.bouncycastle.asn1.ASN1ObjectIdentifier; import org.bouncycastle.asn1.ASN1Sequence; import org.bouncycastle.asn1.DEROutputStream; import org.bouncycastle.asn1.util.ASN1Dump; /** * An immutable policy qualifier represented by the ASN.1 PolicyQualifierInfo * structure.
*
* The ASN.1 definition is as follows:
*
* *
 *    PolicyQualifierInfo ::= SEQUENCE {
 *         policyQualifierId       PolicyQualifierId,
 *         qualifier               ANY DEFINED BY policyQualifierId }
 * 
* *
*
* A certificate policies extension, if present in an X.509 version 3 * certificate, contains a sequence of one or more policy information terms, * each of which consists of an object identifier (OID) and optional qualifiers. * In an end-entity certificate, these policy information terms indicate the * policy under which the certificate has been issued and the purposes for which * the certificate may be used. In a CA certificate, these policy information * terms limit the set of policies for certification paths which include this * certificate.
*
* A Set of PolicyQualifierInfo objects are * returned by the * {@link PolicyNode#getPolicyQualifiers PolicyNode.getPolicyQualifiers} method. * This allows applications with specific policy requirements to process and * validate each policy qualifier. Applications that need to process policy * qualifiers should explicitly set the policyQualifiersRejected * flag to false (by calling the * {@link PKIXParameters#setPolicyQualifiersRejected * PKIXParameters.setPolicyQualifiersRejected} method) before validating a * certification path.
*
* Note that the PKIX certification path validation algorithm specifies that any * policy qualifier in a certificate policies extension that is marked critical * must be processed and validated. Otherwise the certification path must be * rejected. If the policyQualifiersRejected flag is set to * false, it is up to the application to validate all policy qualifiers in this * manner in order to be PKIX compliant.
*
* Concurrent Access
*
* All PolicyQualifierInfo objects must be immutable and * thread-safe. That is, multiple threads may concurrently invoke the methods * defined in this class on a single PolicyQualifierInfo object * (or more than one) with no ill effects. Requiring * PolicyQualifierInfo objects to be immutable and thread-safe * allows them to be passed around to various pieces of code without worrying * about coordinating access.
*
* Uses {@link org.bouncycastle.asn1.ASN1InputStream ASN1InputStream}, * {@link org.bouncycastle.asn1.ASN1Sequence ASN1Sequence}, * {@link org.bouncycastle.asn1.ASN1ObjectIdentifier ASN1ObjectIdentifier}, * {@link org.bouncycastle.asn1.DEROutputStream DEROutputStream}, * {@link org.bouncycastle.asn1.ASN1Object ASN1Object} */ public final class PolicyQualifierInfo { private String id; private byte[] encoded; private byte[] qualifier; /** * Creates an instance of PolicyQualifierInfo from the * encoded bytes. The encoded byte array is copied on construction.
*
* Uses {@link org.bouncycastle.asn1.ASN1InputStream ASN1InputStream}, * {@link org.bouncycastle.asn1.ASN1Sequence ASN1Sequence}, * {@link org.bouncycastle.asn1.ASN1ObjectIdentifier ASN1ObjectIdentifier} and * {@link org.bouncycastle.asn1.DEROutputStream DEROutputStream} * * @param encoded * a byte array containing the qualifier in DER encoding * * @exception IOException * thrown if the byte array does not represent a valid and * parsable policy qualifier */ public PolicyQualifierInfo(byte[] encoded) throws IOException { this.encoded = (byte[])encoded.clone(); try { ByteArrayInputStream inStream = new ByteArrayInputStream( this.encoded); ASN1InputStream derInStream = new ASN1InputStream(inStream); ASN1Sequence obj = (ASN1Sequence)derInStream.readObject(); id = ((ASN1ObjectIdentifier)obj.getObjectAt(0)).getId(); ByteArrayOutputStream outStream = new ByteArrayOutputStream(); DEROutputStream derOutStream = new DEROutputStream(outStream); derOutStream.writeObject(obj.getObjectAt(1)); derOutStream.close(); qualifier = outStream.toByteArray(); } catch (Exception ex) { throw new IOException("parsing exception : " + ex.toString()); } } /** * Returns the policyQualifierId field of this * PolicyQualifierInfo. The policyQualifierId * is an Object Identifier (OID) represented by a set of nonnegative * integers separated by periods. * * @return the OID (never null) */ public String getPolicyQualifierId() { return id; } /** * Returns the ASN.1 DER encoded form of this * PolicyQualifierInfo. * * @return the ASN.1 DER encoded bytes (never null). Note * that a copy is returned, so the data is cloned each time this * method is called. */ public byte[] getEncoded() { return (byte[])encoded.clone(); } /** * Returns the ASN.1 DER encoded form of the qualifier field * of this PolicyQualifierInfo. * * @return the ASN.1 DER encoded bytes of the qualifier * field. Note that a copy is returned, so the data is cloned each * time this method is called. */ public byte[] getPolicyQualifier() { if (qualifier == null) { return null; } return (byte[])qualifier.clone(); } /** * Return a printable representation of this * PolicyQualifierInfo.
*
* Uses {@link org.bouncycastle.asn1.ASN1InputStream ASN1InputStream}, * {@link org.bouncycastle.asn1.ASN1Object ASN1Object} * * @return a String describing the contents of this * PolicyQualifierInfo */ public String toString() { StringBuffer s = new StringBuffer(); s.append("PolicyQualifierInfo: [\n"); s.append("qualifierID: ").append(id).append('\n'); try { ByteArrayInputStream inStream = new ByteArrayInputStream(qualifier); ASN1InputStream derInStream = new ASN1InputStream(inStream); ASN1Object derObject = derInStream.readObject(); s .append(" qualifier:\n").append(ASN1Dump.dumpAsString(derObject)) .append('\n'); } catch (IOException ex) { s.append(ex.getMessage()); } s.append("qualifier: ").append(id).append('\n'); s.append(']'); return s.toString(); } }bouncycastle-1.49.orig/jdk1.3/org/bouncycastle/jce/cert/X509Extension.java0000644000175000017500000000050410262753174025616 0ustar ebourgebourg package org.bouncycastle.jce.cert; import java.util.Set; public interface X509Extension { public abstract Set getCriticalExtensionOIDs(); public abstract byte[] getExtensionValue(String oid); public abstract Set getNonCriticalExtensionOIDs(); public abstract boolean hasUnsupportedCriticalExtension(); } bouncycastle-1.49.orig/jdk1.3/org/bouncycastle/jce/cert/CertPathValidator.java0000644000175000017500000002464110331052734026633 0ustar ebourgebourgpackage org.bouncycastle.jce.cert; import java.security.InvalidAlgorithmParameterException; import java.security.NoSuchAlgorithmException; import java.security.NoSuchProviderException; import java.security.Provider; import java.security.Security; /** * A class for validating certification paths (also known as certificate * chains).
*
* This class uses a provider-based architecture, as described in the Java * Cryptography Architecture. To create a CertPathValidator, * call one of the static getInstance methods, passing in the * algorithm name of the CertPathValidator desired and * optionally the name of the provider desired.
*
* Once a CertPathValidator object has been created, it can * be used to validate certification paths by calling the {@link #validate * validate} method and passing it the CertPath to be validated * and an algorithm-specific set of parameters. If successful, the result is * returned in an object that implements the * CertPathValidatorResult interface.
*
* Concurrent Access
*
* The static methods of this class are guaranteed to be thread-safe. * Multiple threads may concurrently invoke the static methods defined in * this class with no ill effects.
*
* However, this is not true for the non-static methods defined by this class. * Unless otherwise documented by a specific provider, threads that need to * access a single CertPathValidator instance concurrently should * synchronize amongst themselves and provide the necessary locking. Multiple * threads each manipulating a different CertPathValidator * instance need not synchronize.
*
* @see CertPath **/ public class CertPathValidator extends Object { private CertPathValidatorSpi validatorSpi; private Provider provider; private String algorithm; /** * Creates a CertPathValidator object of the given algorithm, * and encapsulates the given provider implementation (SPI object) in it. * * @param validatorSpi * the provider implementation * @param provider * the provider * @param algorithm * the algorithm name */ protected CertPathValidator( CertPathValidatorSpi validatorSpi, Provider provider, String algorithm) { this.validatorSpi = validatorSpi; this.provider = provider; this.algorithm = algorithm; } /** * Returns a CertPathValidator object that implements the * specified algorithm.
*
* If the default provider package provides an implementation of the * specified CertPathValidator algorithm, an instance of * CertPathValidator containing that implementation is * returned. If the requested algorithm is not available in the default * package, other packages are searched. * * @param algorithm * the name of the requested CertPathValidator * algorithm * * @return a CertPathValidator object that implements the * specified algorithm * * @exception NoSuchAlgorithmException * if the requested algorithm is not available in the default * provider package or any of the other provider packages * that were searched */ public static CertPathValidator getInstance(String algorithm) throws NoSuchAlgorithmException { try { CertUtil.Implementation imp = CertUtil.getImplementation( "CertPathValidator", algorithm, (String)null); if (imp != null) { return new CertPathValidator((CertPathValidatorSpi)imp .getEngine(), imp.getProvider(), algorithm); } } catch (NoSuchProviderException ex) { } throw new NoSuchAlgorithmException("can't find algorithm " + algorithm); } /** * Returns a CertPathValidator object that implements the * specified algorithm, as supplied by the specified provider. * * @param algorithm * the name of the requested CertPathValidator * algorithm * @param provider * the name of the provider * * @return a CertPathValidator object that implements the * specified algorithm, as supplied by the specified provider * * @exception NoSuchAlgorithmException * if the requested algorithm is not available from the * specified provider * @exception NoSuchProviderException * if the provider has not been configured * @exception IllegalArgumentException * if the provider is null */ public static CertPathValidator getInstance(String algorithm, String provider) throws NoSuchAlgorithmException, NoSuchProviderException { if (provider == null) { throw new IllegalArgumentException("provider must be non-null"); } CertUtil.Implementation imp = CertUtil.getImplementation( "CertPathValidator", algorithm, provider); if (imp != null) { return new CertPathValidator((CertPathValidatorSpi)imp.getEngine(), imp.getProvider(), algorithm); } throw new NoSuchAlgorithmException("can't find algorithm " + algorithm); } /** * Returns a CertPathValidator object that implements the * specified algorithm, as supplied by the specified provider. Note: the * provider doesn't have to be registered. * * @param algorithm * the name of the requested CertPathValidator * algorithm * @param provider * the provider * * @return a CertPathValidator object that implements the * specified algorithm, as supplied by the specified provider * * @exception NoSuchAlgorithmException * if the requested algorithm is not available from the * specified provider * @exception IllegalArgumentException * if the provider is null */ public static CertPathValidator getInstance(String algorithm, Provider provider) throws NoSuchAlgorithmException { if (provider == null) { throw new IllegalArgumentException("provider must be non-null"); } CertUtil.Implementation imp = CertUtil.getImplementation( "CertPathValidator", algorithm, provider); if (imp != null) { return new CertPathValidator((CertPathValidatorSpi)imp.getEngine(), provider, algorithm); } throw new NoSuchAlgorithmException("can't find algorithm " + algorithm); } /** * Returns the Provider of this * CertPathValidator. * * @return the Provider of this * CertPathValidator */ public final Provider getProvider() { return provider; } /** * Returns the algorithm name of this CertPathValidator. * * @return the algorithm name of this CertPathValidator */ public final String getAlgorithm() { return algorithm; } /** * Validates the specified certification path using the specified algorithm * parameter set.
*
* The CertPath specified must be of a type that is supported * by the validation algorithm, otherwise an * InvalidAlgorithmParameterException will be thrown. For * example, a CertPathValidator that implements the PKIX * algorithm validates CertPath objects of type X.509. * * @param certPath * the CertPath to be validated * @param params * the algorithm parameters * * @return the result of the validation algorithm * * @exception CertPathValidatorException * if the CertPath does not validate * @exception InvalidAlgorithmParameterException * if the specified parameters or the type of the specified * CertPath are inappropriate for this * CertPathValidator */ public final CertPathValidatorResult validate(CertPath certPath, CertPathParameters params) throws CertPathValidatorException, InvalidAlgorithmParameterException { return validatorSpi.engineValidate(certPath, params); } /** * Returns the default CertPathValidator type as specified in * the Java security properties file, or the string "PKIX" if no * such property exists. The Java security properties file is located in the * file named <JAVA_HOME>/lib/security/java.security, where * <JAVA_HOME> refers to the directory where the SDK was installed.
*
* The default CertPathValidator type can be used by * applications that do not want to use a hard-coded type when calling one * of the getInstance methods, and want to provide a default * type in case a user does not specify its own.
*
* The default CertPathValidator type can be changed by * setting the value of the "certpathvalidator.type" security property (in * the Java security properties file) to the desired type. * * @return the default CertPathValidator type as specified in * the Java security properties file, or the string "PKIX" * if no such property exists. */ public static final String getDefaultType() { String defaulttype = null; defaulttype = Security.getProperty("certpathvalidator.type"); if (defaulttype == null || defaulttype.length() <= 0) { return "PKIX"; } else { return defaulttype; } } } bouncycastle-1.49.orig/jdk1.3/org/bouncycastle/jce/cert/CertificateFactory.java0000644000175000017500000001375410331052734027030 0ustar ebourgebourgpackage org.bouncycastle.jce.cert; import java.io.InputStream; import java.security.NoSuchProviderException; import java.security.Provider; import java.security.cert.CRL; import java.security.cert.CRLException; import java.security.cert.Certificate; import java.security.cert.CertificateException; import java.util.Collection; import java.util.Iterator; import java.util.List; /** **/ public class CertificateFactory { private CertificateFactorySpi certFacSpi; private Provider provider; private String type; protected CertificateFactory( CertificateFactorySpi certFacSpi, Provider provider, String type) { this.certFacSpi = certFacSpi; this.provider = provider; this.type = type; } public final CRL generateCRL(InputStream inStream) throws CRLException { return certFacSpi.engineGenerateCRL(inStream); } public final Collection generateCRLs(InputStream inStream) throws CRLException { return certFacSpi.engineGenerateCRLs(inStream); } public final Certificate generateCertificate(InputStream inStream) throws CertificateException { return certFacSpi.engineGenerateCertificate(inStream); } public final /*Sk13 Vector*/ Collection generateCertificates(InputStream inStream) throws CertificateException { return certFacSpi.engineGenerateCertificates(inStream); } /** * Returns an iteration of the CertPath encodings supported * by this certificate factory, with the default encoding first. See * Appendix A in the * Java Certification Path API Programmer's Guide for information about * standard encoding names and their formats.
*
* Attempts to modify the returned Iterator via its * remove method result in an * UnsupportedOperationException. * * @return an Iterator over the names of the supported * CertPath encodings (as Strings) */ public final Iterator getCertPathEncodings() { return certFacSpi.engineGetCertPathEncodings(); } /** * Generates a CertPath object and initializes it with * the data read from the InputStream inStream. The data * is assumed to be in the default encoding. The name of the default * encoding is the first element of the Iterator returned by * the {@link #getCertPathEncodings getCertPathEncodings} method. * * @param inStream an InputStream containing the data * * @return a CertPath initialized with the data from the * InputStream * * @exception CertificateException if an exception occurs while decoding */ public final CertPath generateCertPath(InputStream inStream) throws CertificateException { return certFacSpi.engineGenerateCertPath(inStream); } /** * Generates a CertPath object and initializes it with * the data read from the InputStream inStream. The data * is assumed to be in the specified encoding. See Appendix A in the *
* Java Certification Path API Programmer's Guide * for information about standard encoding names and their formats. * * @param inStream an InputStream containing the data * @param encoding the encoding used for the data * * @return a CertPath initialized with the data from the * InputStream * * @exception CertificateException if an exception occurs while decoding or * the encoding requested is not supported */ public final CertPath generateCertPath(InputStream inStream, String encoding) throws CertificateException { return certFacSpi.engineGenerateCertPath(inStream, encoding); } /** * Generates a CertPath object and initializes it with * a List of Certificates.
*
* The certificates supplied must be of a type supported by the * CertificateFactory. They will be copied out of the supplied * List object. * * @param certificates a List of Certificates * * @return a CertPath initialized with the supplied list of * certificates * * @exception CertificateException if an exception occurs */ public final CertPath generateCertPath(List certificates) throws CertificateException { return certFacSpi.engineGenerateCertPath(certificates); } public static final CertificateFactory getInstance(String type) throws CertificateException { try { CertUtil.Implementation imp = CertUtil.getImplementation("CertificateFactory", type, (String)null); if (imp != null) { return new CertificateFactory((CertificateFactorySpi)imp.getEngine(), imp.getProvider(), type); } throw new CertificateException("can't find type " + type); } catch (NoSuchProviderException e) { throw new CertificateException(type + " not found"); } } public static final CertificateFactory getInstance( String type, String provider) throws CertificateException, NoSuchProviderException { CertUtil.Implementation imp = CertUtil.getImplementation("CertificateFactory", type, provider); if (imp != null) { return new CertificateFactory((CertificateFactorySpi)imp.getEngine(), imp.getProvider(), type); } throw new CertificateException("can't find type " + type); } public final Provider getProvider() { return provider; } public final String getType() { return type; } } bouncycastle-1.49.orig/jdk1.3/org/bouncycastle/jce/cert/CertStore.java0000644000175000017500000003702310331052734025163 0ustar ebourgebourgpackage org.bouncycastle.jce.cert; import java.security.InvalidAlgorithmParameterException; import java.security.NoSuchAlgorithmException; import java.security.NoSuchProviderException; import java.security.Provider; import java.security.Security; import java.util.Collection; /** * A class for retrieving Certificates and CRLs * from a repository.
*
* This class uses a provider-based architecture, as described in the * Java Cryptography Architecture. * To create a CertStore, call one of the static * getInstance methods, passing in the type of * CertStore desired, any applicable initialization parameters * and optionally the name of the provider desired.
*
* Once the CertStore has been created, it can be used to * retrieve Certificates and CRLs by calling its * {@link #getCertificates(CertSelector selector) getCertificates} and * {@link #getCRLs(CRLSelector selector) getCRLs} methods.
*
* Unlike a {@link java.security.KeyStore KeyStore}, which provides access * to a cache of private keys and trusted certificates, a * CertStore is designed to provide access to a potentially * vast repository of untrusted certificates and CRLs. For example, an LDAP * implementation of CertStore provides access to certificates * and CRLs stored in one or more directories using the LDAP protocol and the * schema as defined in the RFC service attribute. See Appendix A in the * Java Certification Path API Programmer's Guide for more information about * standard CertStore types.
*
* Concurrent Access
*
* All public methods of CertStore objects must be thread-safe. * That is, multiple threads may concurrently invoke these methods on a * single CertStore object (or more than one) with no * ill effects. This allows a CertPathBuilder to search for a * CRL while simultaneously searching for further certificates, for instance.
*
* The static methods of this class are also guaranteed to be thread-safe. * Multiple threads may concurrently invoke the static methods defined in * this class with no ill effects.
*
**/ public class CertStore extends Object { private CertStoreSpi storeSpi; private Provider provider; private String type; private CertStoreParameters params; /** * Creates a CertStore object of the given type, and * encapsulates the given provider implementation (SPI object) in it. * * @param storeSpi * the provider implementation * @param provider * the provider * @param type * the type * @param params * the initialization parameters (may be null) */ protected CertStore( CertStoreSpi storeSpi, Provider provider, String type, CertStoreParameters params) { this.storeSpi = storeSpi; this.provider = provider; this.type = type; this.params = params; } /** * Returns a Collection of Certificates that * match the specified selector. If no Certificates match * the selector, an empty Collection will be returned.
*
* For some CertStore types, the resulting * Collection may not contain all of the * Certificates that match the selector. For instance, an * LDAP CertStore may not search all entries in the * directory. Instead, it may just search entries that are likely to contain * the Certificates it is looking for.
*
* Some CertStore implementations (especially LDAP * CertStores) may throw a CertStoreException * unless a non-null CertSelector is provided that includes * specific criteria that can be used to find the certificates. Issuer * and/or subject names are especially useful criteria. * * @param selector * A CertSelector used to select which * Certificates should be returned. Specify * null to return all Certificates * (if supported). * * @return A Collection of Certificates that * match the specified selector (never null) * @exception CertStoreException * if an exception occurs */ public final Collection getCertificates(CertSelector selector) throws CertStoreException { return storeSpi.engineGetCertificates(selector); } /** * Returns a Collection of CRLs that match * the specified selector. If no CRLs match the selector, an * empty Collection will be returned.
*
* For some CertStore types, the resulting * Collection may not contain all of the * CRLs that match the selector. For instance, an LDAP * CertStore may not search all entries in the directory. * Instead, it may just search entries that are likely to contain the * CRLs it is looking for.
*
* Some CertStore implementations (especially LDAP * CertStores) may throw a CertStoreException * unless a non-null CRLSelector is provided that includes * specific criteria that can be used to find the CRLs. Issuer names and/or * the certificate to be checked are especially useful. * * @param selector * A CRLSelector used to select which * CRLs should be returned. Specify * null to return all CRLs (if * supported). * * @return A Collection of CRLs that match * the specified selector (never null) * * @exception CertStoreException * if an exception occurs */ public final Collection getCRLs(CRLSelector selector) throws CertStoreException { return storeSpi.engineGetCRLs(selector); } /** * Returns a CertStore object that implements the specified * CertStore type and is initialized with the specified * parameters.
*
* If the default provider package provides an implementation of the * specified CertStore type, an instance of * CertStore containing that implementation is returned. If * the requested type is not available in the default package, other * packages are searched.
*
* The CertStore that is returned is initialized with the * specified CertStoreParameters. The type of parameters * needed may vary between different types of CertStores. * Note that the specified CertStoreParameters object is * cloned. * * @param type * the name of the requested CertStore type * @param params * the initialization parameters (may be null) * * @return a CertStore object that implements the specified * CertStore type * * @exception NoSuchAlgorithmException * if the requested type is not available in the default * provider package or any of the other provider packages * that were searched * @exception InvalidAlgorithmParameterException * if the specified initialization parameters are * inappropriate for this CertStore */ public static CertStore getInstance(String type, CertStoreParameters params) throws InvalidAlgorithmParameterException, NoSuchAlgorithmException { try { CertUtil.Implementation imp = CertUtil.getImplementation( "CertStore", type, (String)null, new Class[] { CertStoreParameters.class }, new Object[] { params }); if (imp != null) { return new CertStore((CertStoreSpi)imp.getEngine(), imp .getProvider(), type, params); } } catch (NoSuchProviderException ex) { } throw new NoSuchAlgorithmException("can't find type " + type); } /** * Returns a CertStore object that implements the specified * CertStore type, as supplied by the specified provider and * initialized with the specified parameters.
*
* The CertStore that is returned is initialized with the * specified CertStoreParameters. The type of parameters * needed may vary between different types of CertStores. * Note that the specified CertStoreParameters object is * cloned. * * @param type * the requested CertStore type * @param params * the initialization parameters (may be null) * @param provider * the name of the provider * * @return a CertStore object that implements the specified * type, as supplied by the specified provider * * @exception NoSuchAlgorithmException * if the requested type is not available from the specified * provider * @exception InvalidAlgorithmParameterException * if the specified initialization parameters are * inappropriate for this CertStore * @exception NoSuchProviderException * if the provider has not been configured * @exception IllegalArgumentException * if the provider is null */ public static CertStore getInstance(String type, CertStoreParameters params, String provider) throws InvalidAlgorithmParameterException, NoSuchAlgorithmException, NoSuchProviderException, IllegalArgumentException { if (provider == null) { throw new IllegalArgumentException("provider must be non-null"); } CertUtil.Implementation imp = CertUtil.getImplementation("CertStore", type, provider, new Class[] { CertStoreParameters.class }, new Object[] { params }); if (imp != null) { return new CertStore((CertStoreSpi)imp.getEngine(), imp .getProvider(), type, params); } throw new NoSuchAlgorithmException("can't find type " + type); } /** * Returns a CertStore object that implements the specified * CertStore type, as supplied by the specified provider and * initialized with the specified parameters. Note: the * provider doesn't have to be registered.
*
* The CertStore that is returned is initialized with the * specified CertStoreParameters. The type of parameters * needed may vary between different types of CertStores. * Note that the specified CertStoreParameters object is * cloned. * * @param type * the requested CertStore type * @param params * the initialization parameters (may be null) * @param provider * the provider * * @return a CertStore object that implements the specified * type, as supplied by the specified provider * * @exception NoSuchAlgorithmException * if the requested type is not available from the specified * provider * @exception InvalidAlgorithmParameterException * if the specified initialization parameters are * inappropriate for this CertStore * @exception IllegalArgumentException * if the provider is null */ public static CertStore getInstance(String type, CertStoreParameters params, Provider provider) throws NoSuchAlgorithmException, InvalidAlgorithmParameterException, IllegalArgumentException { if (provider == null) { throw new IllegalArgumentException("provider must be non-null"); } CertUtil.Implementation imp = CertUtil.getImplementation("CertStore", type, provider, new Class[] { CertStoreParameters.class }, new Object[] { params }); if (imp != null) { return new CertStore((CertStoreSpi)imp.getEngine(), provider, type, params); } throw new NoSuchAlgorithmException("can't find type " + type); } /** * Returns the parameters used to initialize this CertStore. * Note that the CertStoreParameters object is cloned before * it is returned. * * @return the parameters used to initialize this CertStore * (may be null) */ public final CertStoreParameters getCertStoreParameters() { return params; } /** * Returns the type of this CertStore. * * @return the type of this CertStore */ public final String getType() { return type; } /** * Returns the provider of this CertStore. * * @return the provider of this CertStore */ public final Provider getProvider() { return provider; } /** * Returns the default CertStore type as specified in the * Java security properties file, or the string "LDAP" if no such * property exists. The Java security properties file is located in the file * named <JAVA_HOME>/lib/security/java.security, where * <JAVA_HOME> refers to the directory where the SDK was installed.
*
* The default CertStore type can be used by applications * that do not want to use a hard-coded type when calling one of the * getInstance methods, and want to provide a default * CertStore type in case a user does not specify its own.
*
* The default CertStore type can be changed by setting the * value of the "certstore.type" security property (in the Java security * properties file) to the desired type. * * @return the default CertStore type as specified in the * Java security properties file, or the string "LDAP" if * no such property exists. */ public static final String getDefaultType() { String defaulttype = null; defaulttype = Security.getProperty("certstore.type"); if (defaulttype == null || defaulttype.length() <= 0) { return "LDAP"; } else { return defaulttype; } } } bouncycastle-1.49.orig/jdk1.3/org/bouncycastle/jce/cert/CertPathBuilderSpi.java0000644000175000017500000000355310331052734026747 0ustar ebourgebourgpackage org.bouncycastle.jce.cert; import java.security.InvalidAlgorithmParameterException; /** * The Service Provider Interface (SPI) for the CertPathBuilder * class. All CertPathBuilder implementations must include a class * (the SPI class) that extends this class (CertPathBuilderSpi) and * implements all of its methods. In general, instances of this class * should only be accessed through the CertPathBuilder class. For * details, see the Java Cryptography Architecture.
*
* Concurrent Access
*
* Instances of this class need not be protected against concurrent * access from multiple threads. Threads that need to access a single * CertPathBuilderSpi instance concurrently should synchronize amongst * themselves and provide the necessary locking before calling the * wrapping CertPathBuilder object.
*
* However, implementations of CertPathBuilderSpi may still encounter * concurrency issues, since multiple threads each manipulating a * different CertPathBuilderSpi instance need not synchronize. **/ public abstract class CertPathBuilderSpi extends Object { /** * The default constructor. */ public CertPathBuilderSpi() {} /** * Attempts to build a certification path using the specified * algorithm parameter set. * * @param params the algorithm parameters * * @return the result of the build algorithm * * @exception CertPathBuilderException if the builder is unable * to construct a certification path that satisfies the * specified * @exception parametersInvalidAlgorithmParameterException if the * specified parameters are inappropriate for this CertPathBuilder */ public abstract CertPathBuilderResult engineBuild(CertPathParameters params) throws CertPathBuilderException, InvalidAlgorithmParameterException; } bouncycastle-1.49.orig/jdk1.3/org/bouncycastle/jce/cert/PKIXBuilderParameters.java0000644000175000017500000001765610331052734027371 0ustar ebourgebourgpackage org.bouncycastle.jce.cert; import java.security.InvalidAlgorithmParameterException; import java.security.InvalidParameterException; import java.security.KeyStore; import java.security.KeyStoreException; import java.util.Set; /** * Parameters used as input for the PKIX CertPathBuilder * algorithm.
*
* A PKIX CertPathBuilder uses these parameters to {@link * CertPathBuilder#build build} a CertPath which has been * validated according to the PKIX certification path validation algorithm.
*
* To instantiate a PKIXBuilderParameters object, an * application must specify one or more most-trusted CAs as defined by * the PKIX certification path validation algorithm. The most-trusted CA * can be specified using one of two constructors. An application * can call {@link #PKIXBuilderParameters(Set, CertSelector) * PKIXBuilderParameters(Set, CertSelector)}, specifying a * Set of TrustAnchor objects, each of which * identifies a most-trusted CA. Alternatively, an application can call * {@link #PKIXBuilderParameters(KeyStore, CertSelector) * PKIXBuilderParameters(KeyStore, CertSelector)}, specifying a * KeyStore instance containing trusted certificate entries, each * of which will be considered as a most-trusted CA.
*
* In addition, an application must specify constraints on the target * certificate that the CertPathBuilder will attempt * to build a path to. The constraints are specified as a * CertSelector object. These constraints should provide the * CertPathBuilder with enough search criteria to find the target * certificate. Minimal criteria for an X509Certificate usually * include the subject name and/or one or more subject alternative names. * If enough criteria is not specified, the CertPathBuilder * may throw a CertPathBuilderException.
*
* Concurrent Access
*
* Unless otherwise specified, the methods defined in this class are not * thread-safe. Multiple threads that need to access a single * object concurrently should synchronize amongst themselves and * provide the necessary locking. Multiple threads each manipulating * separate objects need not synchronize. * * @see CertPathBuilder **/ public class PKIXBuilderParameters extends PKIXParameters { private int maxPathLength = 5; /** * Creates an instance of PKIXBuilderParameters with the * specified Set of most-trusted CAs. Each element of the set * is a {@link TrustAnchor TrustAnchor}.
*
* Note that the Set is copied to protect against subsequent * modifications. * * @param trustAnchors * a Set of TrustAnchors * @param targetConstraints * a CertSelector specifying the constraints on * the target certificate * * @exception InvalidAlgorithmParameterException * if trustAnchors is empty * (trustAnchors.isEmpty() == true) * @exception NullPointerException * if trustAnchors is null * @exception ClassCastException * if any of the elements of trustAnchors are * not of type java.security.cert.TrustAnchor */ public PKIXBuilderParameters( Set trustAnchors, CertSelector targetConstraints) throws InvalidAlgorithmParameterException { super(trustAnchors); setTargetCertConstraints(targetConstraints); } /** * Creates an instance of PKIXBuilderParameters that * populates the set of most-trusted CAs from the trusted certificate * entries contained in the specified KeyStore. Only * keystore entries that contain trusted X509Certificates * are considered; all other certificate types are ignored. * * @param keystore * a KeyStore from which the set of most-trusted * CAs will be populated * @param targetConstraints * a CertSelector specifying the constraints on * the target certificate * * @exception KeyStoreException * if keystore has not been initialized * @exception InvalidAlgorithmParameterException * if keystore does not contain at least one * trusted certificate entry * @exception NullPointerException * if keystore is null */ public PKIXBuilderParameters( KeyStore keystore, CertSelector targetConstraints) throws KeyStoreException, InvalidAlgorithmParameterException { super(keystore); setTargetCertConstraints(targetConstraints); } /** * Sets the value of the maximum number of non-self-issued intermediate * certificates that may exist in a certification path. A certificate is * self-issued if the DNs that appear in the subject and issuer fields are * identical and are not empty. Note that the last certificate in a * certification path is not an intermediate certificate, and is not * included in this limit. Usually the last certificate is an end entity * certificate, but it can be a CA certificate. A PKIX * CertPathBuilder instance must not build paths longer than * the length specified.
*
* A value of 0 implies that the path can only contain a single certificate. * A value of -1 implies that the path length is unconstrained (i.e. there * is no maximum). The default maximum path length, if not specified, is 5. * Setting a value less than -1 will cause an exception to be thrown.
*
* If any of the CA certificates contain the * BasicConstraintsExtension, the value of the * pathLenConstraint field of the extension overrides the * maximum path length parameter whenever the result is a certification path * of smaller length. * * @param maxPathLength * the maximum number of non-self-issued intermediate * certificates that may exist in a certification path * * @exception InvalidParameterException * if maxPathLength is set to a value less * than -1 * * @see #getMaxPathLength */ public void setMaxPathLength(int maxPathLength) { if (maxPathLength < -1) { throw new InvalidParameterException( "the maximum path length parameter can not be less than -1"); } this.maxPathLength = maxPathLength; } /** * Returns the value of the maximum number of intermediate non-self-issued * certificates that may exist in a certification path. See the * {@link #setMaxPathLength} method for more details. * * @return the maximum number of non-self-issued intermediate certificates * that may exist in a certification path, or -1 if there is no * limit * * @see #setMaxPathLength */ public int getMaxPathLength() { return maxPathLength; } /** * Returns a formatted string describing the parameters. * * @return a formatted string describing the parameters */ public String toString() { StringBuffer s = new StringBuffer(); s.append("PKIXBuilderParameters [\n"); s.append(super.toString()); s.append(" Maximum Path Length: "); s.append(getMaxPathLength()); s.append("\n]\n"); return s.toString(); } } bouncycastle-1.49.orig/jdk1.3/org/bouncycastle/jce/cert/CertPath.java0000644000175000017500000002544310505106272024766 0ustar ebourgebourgpackage org.bouncycastle.jce.cert; import java.io.ByteArrayInputStream; import java.io.NotSerializableException; import java.io.ObjectStreamException; import java.io.Serializable; import java.security.cert.CertificateEncodingException; import java.security.cert.CertificateException; import java.util.Iterator; import java.util.List; import java.util.ListIterator; /** * An immutable sequence of certificates (a certification path).
*
* This is an abstract class that defines the methods common to all CertPaths. * Subclasses can handle different kinds of certificates (X.509, PGP, etc.).
*
* All CertPath objects have a type, a list of Certificates, and one or more * supported encodings. Because the CertPath class is immutable, a CertPath * cannot change in any externally visible way after being constructed. This * stipulation applies to all public fields and methods of this class and any * added or overridden by subclasses.
*
* The type is a String that identifies the type of Certificates in the * certification path. For each certificate cert in a certification path * certPath, cert.getType().equals(certPath.getType()) must be true.
*
* The list of Certificates is an ordered List of zero or more Certificates. * This List and all of the Certificates contained in it must be immutable.
*
* Each CertPath object must support one or more encodings so that the object * can be translated into a byte array for storage or transmission to other * parties. Preferably, these encodings should be well-documented standards * (such as PKCS#7). One of the encodings supported by a CertPath is considered * the default encoding. This encoding is used if no encoding is explicitly * requested (for the {@link #getEncoded()} method, for instance).
*
* All CertPath objects are also Serializable. CertPath objects are resolved * into an alternate {@link CertPathRep} object during serialization. This * allows a CertPath object to be serialized into an equivalent representation * regardless of its underlying implementation.
*
* CertPath objects can be created with a CertificateFactory or they can be * returned by other classes, such as a CertPathBuilder.
*
* By convention, X.509 CertPaths (consisting of X509Certificates), are ordered * starting with the target certificate and ending with a certificate issued by * the trust anchor. That is, the issuer of one certificate is the subject of * the following one. The certificate representing the * {@link TrustAnchor TrustAnchor} should not be included in the certification * path. Unvalidated X.509 CertPaths may not follow these conventions. PKIX * CertPathValidators will detect any departure from these conventions that * cause the certification path to be invalid and throw a * CertPathValidatorException.
*
* Concurrent Access
*
* All CertPath objects must be thread-safe. That is, multiple threads may * concurrently invoke the methods defined in this class on a single CertPath * object (or more than one) with no ill effects. This is also true for the List * returned by CertPath.getCertificates.
*
* Requiring CertPath objects to be immutable and thread-safe allows them to be * passed around to various pieces of code without worrying about coordinating * access. Providing this thread-safety is generally not difficult, since the * CertPath and List objects in question are immutable. * * @see CertificateFactory * @see CertPathBuilder */ public abstract class CertPath extends Object implements Serializable { private String type; /** * Alternate CertPath class for serialization. */ protected static class CertPathRep implements Serializable { private String type; private byte[] data; /** * Creates a CertPathRep with the specified type and * encoded form of a certification path. * * @param type * the standard name of a CertPath * @param typedata * the encoded form of the certification path */ protected CertPathRep(String type, byte[] data) { this.type = type; this.data = data; } /** * Returns a CertPath constructed from the type and data. * * @return the resolved CertPath object * @exception ObjectStreamException * if a CertPath could not be constructed */ protected Object readResolve() throws ObjectStreamException { try { ByteArrayInputStream inStream = new ByteArrayInputStream(data); CertificateFactory cf = CertificateFactory.getInstance(type); return cf.generateCertPath(inStream); } catch (CertificateException ce) { throw new NotSerializableException( " java.security.cert.CertPath: " + type); } } } /** * Creates a CertPath of the specified type. This constructor is protected * because most users should use a CertificateFactory to create CertPaths. * * @param type * the standard name of the type of Certificatesin this path */ protected CertPath(String type) { this.type = type; } /** * Returns the type of Certificates in this certification path. This is the * same string that would be returned by * {@link java.security.cert.Certificate#getType()} for all Certificates in * the certification path. * * @return the type of Certificates in this certification path (never null) */ public String getType() { return type; } /** * Returns an iteration of the encodings supported by this certification * path, with the default encoding first. Attempts to modify the returned * Iterator via its remove method result in an * UnsupportedOperationException. * * @return an Iterator over the names of the supported encodings (as * Strings) */ public abstract Iterator getEncodings(); /** * Compares this certification path for equality with the specified object. * Two CertPaths are equal if and only if their types are equal and their * certificate Lists (and by implication the Certificates in those Lists) * are equal. A CertPath is never equal to an object that is not a CertPath.
*
* This algorithm is implemented by this method. If it is overridden, the * behavior specified here must be maintained. * * @param other * the object to test for equality with this certification path * * @return true if the specified object is equal to this certification path, * false otherwise * * @see Object#hashCode() Object.hashCode() */ public boolean equals(Object other) { if (!(other instanceof CertPath)) { return false; } CertPath otherCertPath = (CertPath)other; if (!getType().equals(otherCertPath.getType())) { return false; } return getCertificates().equals(otherCertPath.getCertificates()); } /** * Returns the hashcode for this certification path. The hash code of a * certification path is defined to be the result of the following * calculation: * *
     * hashCode = path.getType().hashCode();
     * hashCode = 31 * hashCode + path.getCertificates().hashCode();
     * 
* * This ensures that path1.equals(path2) implies that * path1.hashCode()==path2.hashCode() for any two certification paths, path1 * and path2, as required by the general contract of Object.hashCode. * * @return The hashcode value for this certification path * * @see #equals(Object) */ public int hashCode() { return getType().hashCode() * 31 + getCertificates().hashCode(); } /** * Returns a string representation of this certification path. This calls * the toString method on each of the Certificates in the path. * * @return a string representation of this certification path */ public String toString() { StringBuffer s = new StringBuffer(); List certs = getCertificates(); ListIterator iter = certs.listIterator(); s.append('\n').append(getType()).append(" Cert Path: length = ").append(certs.size()) .append("\n[\n"); while (iter.hasNext()) { s .append("=========================================================Certificate ") .append(iter.nextIndex()).append('\n'); s.append(iter.next()).append('\n'); s .append("========================================================Certificate end\n\n\n"); } s.append("\n]"); return s.toString(); } /** * Returns the encoded form of this certification path, using the default * encoding. * * @return the encoded bytes * * @exception CertificateEncodingException * if an encoding error occurs */ public abstract byte[] getEncoded() throws CertificateEncodingException; /** * Returns the encoded form of this certification path, using the specified * encoding. * * @param encoding * the name of the encoding to use * * @return the encoded bytes * * @exception CertificateEncodingException * if an encoding error occurs or the encoding requested is * not supported */ public abstract byte[] getEncoded(String encoding) throws CertificateEncodingException; /** * Returns the list of certificates in this certification path. The List * returned must be immutable and thread-safe. * * @return an immutable List of Certificates (may be empty, but not null) */ public abstract List getCertificates(); /** * Replaces the CertPath to be serialized with a CertPathRep object. * * @return the CertPathRep to be serialized * * @exception ObjectStreamException * if a CertPathRep object representing this certification * path could not be created */ protected Object writeReplace() throws ObjectStreamException { try { return new CertPathRep(getType(), getEncoded()); } catch (CertificateException ce) { throw new NotSerializableException(" java.security.cert.CertPath: " + getType()); } } } bouncycastle-1.49.orig/jdk1.3/org/bouncycastle/jce/cert/LDAPCertStoreParameters.java0000644000175000017500000000746610505106272027660 0ustar ebourgebourgpackage org.bouncycastle.jce.cert; /** * Parameters used as input for the LDAP CertStore algorithm.
*
* This class is used to provide necessary configuration parameters (server * name and port number) to implementations of the LDAP CertStore * algorithm.
*
* Concurrent Access
*
* Unless otherwise specified, the methods defined in this class are not * thread-safe. Multiple threads that need to access a single * object concurrently should synchronize amongst themselves and * provide the necessary locking. Multiple threads each manipulating * separate objects need not synchronize. * * @see CertStore **/ public class LDAPCertStoreParameters implements CertStoreParameters { private static final int LDAP_DEFAULT_PORT = 389; /** * the port number of the LDAP server */ private String serverName; /** * the DNS name of the LDAP server */ private int port; /** * Creates an instance of LDAPCertStoreParameters with the * default parameter values (server name "localhost", port 389). */ public LDAPCertStoreParameters() { this("localhost", LDAP_DEFAULT_PORT); } /** * Creates an instance of LDAPCertStoreParameters with the * specified server name and a default port of 389. * * @param serverName * the DNS name of the LDAP server * * @exception NullPointerException * if serverName is null */ public LDAPCertStoreParameters(String serverName) { this(serverName, LDAP_DEFAULT_PORT); } /** * Creates an instance of LDAPCertStoreParameters with the * specified parameter values. * * @param serverName * the DNS name of the LDAP server * @param port * the port number of the LDAP server * * @exception NullPointerException * if serverName is null */ public LDAPCertStoreParameters(String serverName, int port) { if (serverName == null) { throw new NullPointerException("serverName must be non-null"); } this.serverName = serverName; this.port = port; } /** * Returns the DNS name of the LDAP server. * * @return the name (not null) */ public String getServerName() { return serverName; } /** * Returns the port number of the LDAP server. * * @return the port number */ public int getPort() { return port; } /** * Returns a copy of this object. Changes to the copy will not affect the * original and vice versa.
*
* Note: this method currently performs a shallow copy of the object (simply * calls Object.clone()). This may be changed in a future * revision to perform a deep copy if new parameters are added that should * not be shared. * * @return the copy */ public Object clone() { try { return super.clone(); } catch (CloneNotSupportedException e) { /* Cannot happen */ throw new InternalError(e.toString()); } } /** * Returns a formatted string describing the parameters. * * @return a formatted string describing the parameters */ public String toString() { StringBuffer sb = new StringBuffer(); sb.append("LDAPCertStoreParameters: [\n"); sb.append(" serverName: ").append(serverName).append('\n'); sb.append(" port: ").append(port).append('\n'); sb.append(']'); return sb.toString(); } } bouncycastle-1.49.orig/jdk1.3/org/bouncycastle/jce/cert/CertPathValidatorException.java0000644000175000017500000002057110505106272030510 0ustar ebourgebourgpackage org.bouncycastle.jce.cert; import java.io.PrintStream; import java.io.PrintWriter; import java.security.GeneralSecurityException; /** * An exception indicating one of a variety of problems encountered when * validating a certification path.
*
* A CertPathValidatorException provides support for wrapping * exceptions. The {@link #getCause getCause} method returns the throwable, * if any, that caused this exception to be thrown.
*
* A CertPathValidatorException may also include the * certification path that was being validated when the exception was thrown * and the index of the certificate in the certification path that caused the * exception to be thrown. Use the {@link #getCertPath getCertPath} and * {@link #getIndex getIndex} methods to retrieve this information.
*
* Concurrent Access
*
* Unless otherwise specified, the methods defined in this class are not * thread-safe. Multiple threads that need to access a single * object concurrently should synchronize amongst themselves and * provide the necessary locking. Multiple threads each manipulating * separate objects need not synchronize. * * @see CertPathValidator **/ public class CertPathValidatorException extends GeneralSecurityException { private Throwable cause; private CertPath certPath; private int index = -1; /** * Creates a CertPathValidatorException with no detail * message. */ public CertPathValidatorException() { super(); } /** * Creates a CertPathValidatorException with the given detail * message. A detail message is a String that describes this * particular exception. * * @param messag * the detail message */ public CertPathValidatorException(String message) { super(message); } /** * Creates a CertPathValidatorException with the specified * detail message and cause. * * @param msg * the detail message * @param cause * the cause (which is saved for later retrieval by the * {@link #getCause getCause()} method). (A null * value is permitted, and indicates that the cause is * nonexistent or unknown.) */ public CertPathValidatorException(String message, Throwable cause) { super(message); this.cause = cause; } /** * Creates a CertPathValidatorException with the specified * detail message, cause, certification path, and index. * * @param msg * the detail message (or null if none) * @param cause * the cause (or null if none) * @param certPath * the certification path that was in the process of being * validated when the error was encountered * @param index * the index of the certificate in the certification path that * caused the error (or -1 if not applicable). Note that the list * of certificates in a CertPath is zero based. * * @exception IndexOutOfBoundsException * if the index is out of range * (index < -1 || (certPath != null && index >= * certPath.getCertificates().size()) * @exception IllegalArgumentException * if certPath is null and * index is not -1 */ public CertPathValidatorException( String message, Throwable cause, CertPath certPath, int index) { super(message); if (certPath == null && index != -1) { throw new IllegalArgumentException( "certPath = null and index != -1"); } if (index < -1 || (certPath != null && index >= certPath.getCertificates() .size())) { throw new IndexOutOfBoundsException( " index < -1 or out of bound of certPath.getCertificates()"); } this.cause = cause; this.certPath = certPath; this.index = index; } /** * Creates a CertPathValidatorException that wraps the * specified throwable. This allows any exception to be converted into a * CertPathValidatorException, while retaining information * about the wrapped exception, which may be useful for debugging. The * detail message is set to (cause==null ? null : cause.toString() * ) * (which typically contains the class and detail message of cause). * * @param cause * the cause (which is saved for later retrieval by the * {@link #getCause getCause()} method). (A null * value is permitted, and indicates that the cause is * nonexistent or unknown.) */ public CertPathValidatorException(Throwable cause) { this.cause = cause; } /** * Returns the detail message for this * CertPathValidatorException. * * @return the detail message, or null if neither the message * nor cause were specified */ public String getMessage() { String message = super.getMessage(); if (message != null) { return message; } if (cause != null) { return cause.getMessage(); } return null; } /** * Returns the certification path that was being validated when the * exception was thrown. * * @return the CertPath that was being validated when the * exception was thrown (or null if not specified) */ public CertPath getCertPath() { return certPath; } /** * Returns the index of the certificate in the certification path that * caused the exception to be thrown. Note that the list of certificates in * a CertPath is zero based. If no index has been set, -1 is * returned. * * @return the index that has been set, or -1 if none has been set */ public int getIndex() { return index; } /** * Returns the cause of this CertPathValidatorException or * null if the cause is nonexistent or unknown. * * @return the cause of this throwable or null if the cause * is nonexistent or unknown. */ public Throwable getCause() { return cause; } /** * Returns a string describing this exception, including a description of * the internal (wrapped) cause if there is one. * * @return a string representation of this * CertPathValidatorException */ public String toString() { StringBuffer sb = new StringBuffer(); String s = getMessage(); if (s != null) { sb.append(s); } if (getIndex() >= 0) { sb.append("index in certpath: ").append(getIndex()).append('\n'); sb.append(getCertPath()); } return sb.toString(); } /** * Prints a stack trace to System.err, including the * backtrace of the cause, if any. */ public void printStackTrace() { printStackTrace(System.err); } /** * Prints a stack trace to a PrintStream, including the * backtrace of the cause, if any. * * @param ps * the PrintStream to use for output */ public void printStackTrace(PrintStream ps) { super.printStackTrace(ps); if (getCause() != null) { getCause().printStackTrace(ps); } } /** * Prints a stack trace to a PrintWriter, including the * backtrace of the cause, if any. * * @param pw * the PrintWriter to use for output */ public void printStackTrace(PrintWriter pw) { super.printStackTrace(pw); if (getCause() != null) { getCause().printStackTrace(pw); } } } bouncycastle-1.49.orig/jdk1.3/org/bouncycastle/jce/cert/CertPathBuilder.java0000644000175000017500000002267610331052734026302 0ustar ebourgebourgpackage org.bouncycastle.jce.cert; import java.security.InvalidAlgorithmParameterException; import java.security.NoSuchAlgorithmException; import java.security.NoSuchProviderException; import java.security.Provider; import java.security.Security; /** * A class for building certification paths (also known as certificate chains).
*
* This class uses a provider-based architecture, as described in the Java * Cryptography Architecture. To create a CertPathBuilder, call * one of the static getInstance methods, passing in the * algorithm name of the CertPathBuilder desired and optionally the name of the * provider desired.
*
* Once a CertPathBuilder object has been created, certification * paths can be constructed by calling the {@link #build build} method and * passing it an algorithm-specific set of parameters. If successful, the result * (including the CertPath that was built) is returned in an object that * implements the CertPathBuilderResult interface.
*
* Concurrent Access
*
* The static methods of this class are guaranteed to be thread-safe. Multiple * threads may concurrently invoke the static methods defined in this class with * no ill effects.
*
* However, this is not true for the non-static methods defined by this class. * Unless otherwise documented by a specific provider, threads that need to * access a single CertPathBuilder instance concurrently should * synchronize amongst themselves and provide the necessary locking. Multiple * threads each manipulating a different CertPathBuilder instance * need not synchronize.
*
*/ public class CertPathBuilder extends Object { private CertPathBuilderSpi builderSpi; private Provider provider; private String algorithm; /** * Creates a CertPathBuilder object of the given algorithm, and encapsulates * the given provider implementation (SPI object) in it. * * @param builderSpi * the provider implementation * @param provider * the provider * @param algorithm * the algorithm name */ protected CertPathBuilder( CertPathBuilderSpi builderSpi, Provider provider, String algorithm) { this.builderSpi = builderSpi; this.provider = provider; this.algorithm = algorithm; } /** * Returns a CertPathBuilder object that implements the specified algorithm.
*
* If the default provider package provides an implementation of the * specified CertPathBuilder algorithm, an instance of CertPathBuilder * containing that implementation is returned. If the requested algorithm is * not available in the default package, other packages are searched.
*
* * @param algorithm * the name of the requested CertPathBuilder algorithm * * @return a CertPathBuilder object that implements the specified algorithm * * @exception NoSuchAlgorithmException * if the requested algorithm is not available in the default * provider package or any of the other provider packages * that were searched */ public static CertPathBuilder getInstance(String algorithm) throws NoSuchAlgorithmException { try { CertUtil.Implementation imp = CertUtil.getImplementation( "CertPathBuilder", algorithm, (String)null); if (imp != null) { return new CertPathBuilder((CertPathBuilderSpi)imp.getEngine(), imp.getProvider(), algorithm); } } catch (NoSuchProviderException ex) { } throw new NoSuchAlgorithmException("can't find type " + algorithm); } /** * Returns a CertPathBuilder object that implements the specified algorithm, * as supplied by the specified provider. * * @param algorithm * the name of the requested CertPathBuilder algorithm * @param provider * the name of the provider * * @return a CertPathBuilder object that implements the specified algorithm, * as supplied by the specified provider * * @exception NoSuchAlgorithmException * if the requested algorithm is not available from the * specified provider * @exception NoSuchProviderException * if the provider has not been configured * @exception IllegalArgumentException * if the provider is null */ public static CertPathBuilder getInstance(String algorithm, String provider) throws NoSuchAlgorithmException, NoSuchProviderException { if (provider == null) { throw new IllegalArgumentException("provider must be non-null"); } CertUtil.Implementation imp = CertUtil.getImplementation( "CertPathBuilder", algorithm, provider); if (imp != null) { return new CertPathBuilder((CertPathBuilderSpi)imp.getEngine(), imp .getProvider(), algorithm); } throw new NoSuchAlgorithmException("can't find type " + algorithm); } /** * Returns a CertPathBuilder object that implements the specified algorithm, * as supplied by the specified provider. Note: the provider doesn't have to * be registered. * * @param algorithm * the name of the requested CertPathBuilder algorithm * @param provider * the provider * @return a CertPathBuilder object that implements the specified algorithm, * as supplied by the specified provider * * @exception NoSuchAlgorithmException * if the requested algorithm is not available from the * specified provider * @exception IllegalArgumentException * if the provider is null. */ public static CertPathBuilder getInstance(String algorithm, Provider provider) throws NoSuchAlgorithmException { if (provider == null) { throw new IllegalArgumentException("provider must be non-null"); } CertUtil.Implementation imp = CertUtil.getImplementation( "CertPathBuilder", algorithm, provider); if (imp != null) { return new CertPathBuilder((CertPathBuilderSpi)imp.getEngine(), provider, algorithm); } throw new NoSuchAlgorithmException("can't find type " + algorithm); } /** * Returns the provider of this CertPathBuilder. * * @return the provider of this CertPathBuilder */ public final Provider getProvider() { return provider; } /** * Returns the name of the algorithm of this CertPathBuilder. * * @return the name of the algorithm of this CertPathBuilder */ public final String getAlgorithm() { return algorithm; } /** * Attempts to build a certification path using the specified algorithm * parameter set. * * @param params * the algorithm parameters * * @return the result of the build algorithm * * @exception CertPathBuilderException * if the builder is unable to construct a certification path * that satisfies the specified parameters * @exception InvalidAlgorithmParameterException * if the specified parameters * are inappropriate for this * CertPathBuilder */ public final CertPathBuilderResult build(CertPathParameters params) throws CertPathBuilderException, InvalidAlgorithmParameterException { return builderSpi.engineBuild(params); } /** * Returns the default CertPathBuilder type as specified in * the Java security properties file, or the string "PKIX" if no * such property exists. The Java security properties file is located in the * file named <JAVA_HOME>/lib/security/java.security, where * <JAVA_HOME> refers to the directory where the SDK was installed.
*
* The default CertPathBuilder type can be used by * applications that do not want to use a hard-coded type when calling one * of the getInstance methods, and want to provide a default * type in case a user does not specify its own.
*
* The default CertPathBuilder type can be changed by setting * the value of the "certpathbuilder.type" security property (in the Java * security properties file) to the desired type. * * @return the default CertPathBuilder type as specified in * the Java security properties file, or the string "PKIX" * if no such property exists. */ public static final String getDefaultType() { String defaulttype = null; defaulttype = Security.getProperty("certpathbuilder.type"); if (defaulttype == null || defaulttype.length() <= 0) { return "PKIX"; } else { return defaulttype; } } } bouncycastle-1.49.orig/jdk1.3/org/bouncycastle/jce/cert/PKIXParameters.java0000644000175000017500000007013010505106272026044 0ustar ebourgebourgpackage org.bouncycastle.jce.cert; import java.security.InvalidAlgorithmParameterException; import java.security.KeyStore; import java.security.KeyStoreException; import java.security.cert.Certificate; import java.security.cert.X509Certificate; import java.util.ArrayList; import java.util.Collections; import java.util.Date; import java.util.Enumeration; import java.util.HashSet; import java.util.Iterator; import java.util.List; import java.util.Set; /** * Parameters used as input for the PKIX CertPathValidator algorithm.
*
* A PKIX CertPathValidator uses these parameters to validate a * CertPath according to the PKIX certification path validation * algorithm.
*
* To instantiate a PKIXParameters object, an application must * specify one or more most-trusted CAs as defined by the PKIX * certification path validation algorithm. The most-trusted CAs can be * specified using one of two constructors. An application can call * {@link #PKIXParameters(Set)}, specifying a Set of TrustAnchor * objects, each of which identify a most-trusted CA. Alternatively, an * application can call {@link #PKIXParameters(KeyStore)}, specifying a * KeyStore instance containing trusted certificate entries, each * of which will be considered as a most-trusted CA.
*
* Once a PKIXParameters object has been created, other * parameters can be specified (by calling {@link #setInitialPolicies} or * {@link #setDate}, for instance) and then the PKIXParameters * is passed along with the CertPath to be validated to * {@link CertPathValidator#validate}.
*
* Any parameter that is not set (or is set to null) will be set to the default * value for that parameter. The default value for the date parameter is null, * which indicates the current time when the path is validated. The default for * the remaining parameters is the least constrained.
*
* Concurrent Access
*
* Unless otherwise specified, the methods defined in this class are not * thread-safe. Multiple threads that need to access a single object * concurrently should synchronize amongst themselves and provide the necessary * locking. Multiple threads each manipulating separate objects need not * synchronize. * * @see CertPathValidator */ public class PKIXParameters implements CertPathParameters { private Set trustAnchors; private Set initialPolicies = new HashSet(); private List certStores = new ArrayList(); private CertSelector certSelector; private List certPathCheckers = new ArrayList(); private boolean revocationEnabled = true; private boolean explicitPolicyRequired = false; private boolean policyMappingInhibited = false; private boolean anyPolicyInhibited = false; private boolean policyQualifiersRejected = true; private Date date; private String sigProvider; /** * Creates an instance of PKIXParameters with the specified Set of * most-trusted CAs. Each element of the set is a TrustAnchor.
*
* Note that the Set is copied to protect against subsequent modifications. * * @param trustAnchors * a Set of TrustAnchors * * @exception InvalidAlgorithmParameterException * if the specified Set is empty * (trustAnchors.isEmpty() == true) * @exception NullPointerException * if the specified Set is null * @exception ClassCastException * if any of the elements in the Set are not of type * java.security.cert.TrustAnchor */ public PKIXParameters(Set trustAnchors) throws InvalidAlgorithmParameterException { setTrustAnchors(trustAnchors); } /** * Creates an instance of PKIXParameters that populates the set of * most-trusted CAs from the trusted certificate entries contained in the * specified KeyStore. Only keystore entries that contain trusted * X509Certificates are considered; all other certificate types are ignored. * * @param keystore * a KeyStore from which the set of most-trusted CAs will be * populated * * @exception KeyStoreException * if the keystore has not been initialized * @exception InvalidAlgorithmParameterException * if the keystore does not contain at least one trusted * certificate entry * @exception NullPointerException * if the keystore is null */ public PKIXParameters(KeyStore keystore) throws KeyStoreException, InvalidAlgorithmParameterException { if (keystore == null) { throw new NullPointerException( "the keystore parameter must be non-null"); } Set trustAnchors = new HashSet(); String alias; Certificate cert; Enumeration enum = keystore.aliases(); while (enum.hasMoreElements()) { alias = (String)enum.nextElement(); if (keystore.isCertificateEntry(alias)) { cert = keystore.getCertificate(alias); if (cert instanceof X509Certificate) { trustAnchors.add(new TrustAnchor((X509Certificate)cert, null)); } } } setTrustAnchors(trustAnchors); } /** * Returns an immutable Set of the most-trusted CAs. * * @return an immutable Set of TrustAnchors * (never null) * * @see #setTrustAnchors */ public Set getTrustAnchors() { return Collections.unmodifiableSet(trustAnchors); } /** * Sets the Set of most-trusted CAs.
*
* Note that the Set is copied to protect against subsequent modifications.
*
* * @param trustAnchors * a Set of TrustAnchors * * @exception InvalidAlgorithmParameterException * if the specified Set is empty * (trustAnchors.isEmpty() == true) * @exception NullPointerException * if the specified Set is null * @exception ClassCastException * if any of the elements in the set are not of type * java.security.cert.TrustAnchor * * @see #getTrustAnchors */ public void setTrustAnchors(Set trustAnchors) throws InvalidAlgorithmParameterException { if (trustAnchors == null) { throw new NullPointerException( "the trustAnchors parameter must be non-null"); } if (trustAnchors.isEmpty()) { throw new InvalidAlgorithmParameterException( "the trustAnchors parameter must be non-empty"); } Iterator iter = trustAnchors.iterator(); TrustAnchor obj; this.trustAnchors = new HashSet(); while (iter.hasNext()) { obj = (TrustAnchor)iter.next(); if (obj != null) { this.trustAnchors.add(obj); } } } /** * Returns an immutable Set of initial policy identifiers (OID strings), * indicating that any one of these policies would be acceptable to the * certificate user for the purposes of certification path processing. The * default return value is an empty Set, which is * interpreted as meaning that any policy would be acceptable. * * @return an immutable Set of initial policy OIDs in String * format, or an empty Set (implying any policy is * acceptable). Never returns null. * * @see #setInitialPolicies(java.util.Set) */ public Set getInitialPolicies() { Set returnSet = initialPolicies; if (initialPolicies == null) { returnSet = new HashSet(); } return Collections.unmodifiableSet(returnSet); } /** * Sets the Set of initial policy identifiers (OID strings), * indicating that any one of these policies would be acceptable to the * certificate user for the purposes of certification path processing. By * default, any policy is acceptable (i.e. all policies), so a user that * wants to allow any policy as acceptable does not need to call this * method, or can call it with an empty Set (or * null).
*
* Note that the Set is copied to protect against subsequent modifications.
*
* * @param initialPolicies * a Set of initial policy OIDs in String format (or * null) * * @exception ClassCastException * if any of the elements in the set are not of type String * * @see #getInitialPolicies() */ public void setInitialPolicies(Set initialPolicies) { if (initialPolicies == null || initialPolicies.isEmpty()) { this.initialPolicies = null; } else { Iterator iter = initialPolicies.iterator(); this.initialPolicies = new HashSet(); String obj; while (iter.hasNext()) { obj = (String)iter.next(); if (obj != null) { this.initialPolicies.add(obj); } } } } /** * Sets the list of CertStores to be used in finding certificates and CRLs. * May be null, in which case no CertStores will be used. The first * CertStores in the list may be preferred to those that appear later.
*
* Note that the List is copied to protect against subsequent modifications.
*
* * @param stores * a List of CertStores (or null) * * @exception ClassCastException * if any of the elements in the list are not of type * java.security.cert.CertStore * * @see #getCertStores() */ public void setCertStores(List stores) { certStores = new ArrayList(); if (stores != null && !stores.isEmpty()) { Iterator iter = stores.iterator(); CertStore obj; while (iter.hasNext()) { obj = (CertStore)iter.next(); if (obj != null) { certStores.add(obj); } } } } /** * Adds a CertStore to the end of the list of CertStores used in finding * certificates and CRLs. * * @param store * the CertStore to add. If * nullnull) * * @see #setCertStores(java.util.List) */ public List getCertStores() { return Collections.unmodifiableList(certStores); } /** * Sets the RevocationEnabled flag. If this flag is true, the default * revocation checking mechanism of the underlying PKIX service provider * will be used. If this flag is false, the default revocation checking * mechanism will be disabled (not used).
*
* When a PKIXParameters object is created, this flag is set * to true. This setting reflects the most common strategy for checking * revocation, since each service provider must support revocation checking * to be PKIX compliant. Sophisticated applications should set this flag to * false when it is not practical to use a PKIX service provider's default * revocation checking mechanism or when an alternative revocation checking * mechanism is to be substituted (by also calling the * {@link #addCertPathChecker addCertPathChecker} or {@link * #setCertPathCheckers setCertPathCheckers} methods). * * @param val * the new value of the RevocationEnabled flag */ public void setRevocationEnabled(boolean val) { revocationEnabled = val; } /** * Checks the RevocationEnabled flag. If this flag is true, the default * revocation checking mechanism of the underlying PKIX service provider * will be used. If this flag is false, the default revocation checking * mechanism will be disabled (not used). See the setRevocationEnabled * method for more details on setting the value of this flag. * * @return the current value of the RevocationEnabled flag */ public boolean isRevocationEnabled() { return revocationEnabled; } /** * Sets the ExplicitPolicyRequired flag. If this flag is true, an acceptable * policy needs to be explicitly identified in every certificate. By * default, the ExplicitPolicyRequired flag is false. * * @param val * true if explicit policy is to be required, false otherwise */ public void setExplicitPolicyRequired(boolean val) { explicitPolicyRequired = val; } /** * Checks if explicit policy is required. If this flag is true, an * acceptable policy needs to be explicitly identified in every certificate. * By default, the ExplicitPolicyRequired flag is false. * * @return true if explicit policy is required, false otherwise */ public boolean isExplicitPolicyRequired() { return explicitPolicyRequired; } /** * Sets the PolicyMappingInhibited flag. If this flag is true, policy * mapping is inhibited. By default, policy mapping is not inhibited (the * flag is false). * * @param val * true if policy mapping is to be inhibited, false otherwise */ public void setPolicyMappingInhibited(boolean val) { policyMappingInhibited = val; } /** * Checks if policy mapping is inhibited. If this flag is true, policy * mapping is inhibited. By default, policy mapping is not inhibited (the * flag is false). * * @return true if policy mapping is inhibited, false otherwise */ public boolean isPolicyMappingInhibited() { return policyMappingInhibited; } /** * Sets state to determine if the any policy OID should be processed if it * is included in a certificate. By default, the any policy OID is not * inhibited ({@link #isAnyPolicyInhibited()} returns false). * * @return val - true if the any policy OID is to be * inhibited, false otherwise */ public void setAnyPolicyInhibited(boolean val) { anyPolicyInhibited = val; } /** * Checks whether the any policy OID should be processed if it is included * in a certificate. * * @return true if the any policy OID is inhibited, * false otherwise */ public boolean isAnyPolicyInhibited() { return anyPolicyInhibited; } /** * Sets the PolicyQualifiersRejected flag. If this flag is true, * certificates that include policy qualifiers in a certificate policies * extension that is marked critical are rejected. If the flag is false, * certificates are not rejected on this basis.
*
* When a PKIXParameters object is created, this flag is set * to true. This setting reflects the most common (and simplest) strategy * for processing policy qualifiers. Applications that want to use a more * sophisticated policy must set this flag to false.
*
* Note that the PKIX certification path validation algorithm specifies that * any policy qualifier in a certificate policies extension that is marked * critical must be processed and validated. Otherwise the certification * path must be rejected. If the policyQualifiersRejected flag is set to * false, it is up to the application to validate all policy qualifiers in * this manner in order to be PKIX compliant. * * @param qualifiersRejected * the new value of the PolicyQualifiersRejected flag * * @see #getPolicyQualifiersRejected() * @see PolicyQualifierInfo */ public void setPolicyQualifiersRejected(boolean qualifiersRejected) { policyQualifiersRejected = qualifiersRejected; } /** * Gets the PolicyQualifiersRejected flag. If this flag is true, * certificates that include policy qualifiers in a certificate policies * extension that is marked critical are rejected. If the flag is false, * certificates are not rejected on this basis.
*
* When a PKIXParameters object is created, this flag is set to true. This * setting reflects the most common (and simplest) strategy for processing * policy qualifiers. Applications that want to use a more sophisticated * policy must set this flag to false. * * @return the current value of the PolicyQualifiersRejected flag * * @see #setPolicyQualifiersRejected(boolean) */ public boolean getPolicyQualifiersRejected() { return policyQualifiersRejected; } /** * Returns the time for which the validity of the certification path should * be determined. If null, the current time is used.
*
* Note that the Date returned is copied to protect against subsequent * modifications. * * @return the Date, or null if not set * * @see #setDate(java.util.Date) */ public Date getDate() { if (date == null) { return null; } return new Date(date.getTime()); } /** * Sets the time for which the validity of the certification path should be * determined. If null, the current time is used.
*
* Note that the Date supplied here is copied to protect against subsequent * modifications. * * @param date * the Date, or null for the current time * * @see #getDate() */ public void setDate(Date date) { if (date == null) { this.date = null; } else { this.date = new Date(date.getTime()); } } /** * Sets a List of additional certification path checkers. If * the specified List contains an object that is not a PKIXCertPathChecker, * it is ignored.
*
* Each PKIXCertPathChecker specified implements additional * checks on a certificate. Typically, these are checks to process and * verify private extensions contained in certificates. Each * PKIXCertPathChecker should be instantiated with any * initialization parameters needed to execute the check.
*
* This method allows sophisticated applications to extend a PKIX * CertPathValidator or CertPathBuilder. Each * of the specified PKIXCertPathCheckers will be called, in turn, by a PKIX * CertPathValidator or CertPathBuilder for * each certificate processed or validated.
*
* Regardless of whether these additional PKIXCertPathCheckers are set, a * PKIX CertPathValidator or CertPathBuilder * must perform all of the required PKIX checks on each certificate. The one * exception to this rule is if the RevocationEnabled flag is set to false * (see the {@link #setRevocationEnabled(boolean) setRevocationEnabled} * method).
*
* Note that the List supplied here is copied and each PKIXCertPathChecker * in the list is cloned to protect against subsequent modifications. * * @param checkers * a List of PKIXCertPathCheckers. May be null, in which case no * additional checkers will be used. * @exception ClassCastException * if any of the elements in the list are not of type * java.security.cert.PKIXCertPathChecker * @see #getCertPathCheckers() */ public void setCertPathCheckers(List checkers) { certPathCheckers = new ArrayList(); if (checkers == null) { return; } Iterator iter = checkers.iterator(); while (iter.hasNext()) { certPathCheckers .add((PKIXCertPathChecker)((PKIXCertPathChecker)iter.next()) .clone()); } } /** * Returns the List of certification path checkers. The returned List is * immutable, and each PKIXCertPathChecker in the List is cloned to protect * against subsequent modifications. * * @return an immutable List of PKIXCertPathCheckers (may be empty, but not * null) * * @see #setCertPathCheckers(java.util.List) */ public List getCertPathCheckers() { List checkers = new ArrayList(); Iterator iter = certPathCheckers.iterator(); while (iter.hasNext()) { checkers .add((PKIXCertPathChecker)((PKIXCertPathChecker)iter.next()) .clone()); } return Collections.unmodifiableList(checkers); } /** * Adds a PKIXCertPathChecker to the list of certification path checkers. * See the {@link #setCertPathCheckers} method for more details.
*
* Note that the PKIXCertPathChecker is cloned to protect * against subsequent modifications. * * @param checker * a PKIXCertPathChecker to add to the list of * checks. If null, the checker is ignored (not * added to list). */ public void addCertPathChecker(PKIXCertPathChecker checker) { if (checker != null) { certPathCheckers.add(checker.clone()); } } /** * Returns the signature provider's name, or null if not set. * * @return the signature provider's name (or null) * * @see #setSigProvider(java.lang.String) */ public String getSigProvider() { return sigProvider; } /** * Sets the signature provider's name. The specified provider will be * preferred when creating Signature objects. If null or not set, the first * provider found supporting the algorithm will be used. * * @param sigProvider * the signature provider's name (or null) * * @see #getSigProvider() */ public void setSigProvider(String sigProvider) { this.sigProvider = sigProvider; } /** * Returns the required constraints on the target certificate. The * constraints are returned as an instance of CertSelector. If * null, no constraints are defined.
*
* Note that the CertSelector returned is cloned to protect against * subsequent modifications. * * @return a CertSelector specifying the constraints on the target * certificate (or null) * * @see #setTargetCertConstraints(CertSelector) */ public CertSelector getTargetCertConstraints() { if (certSelector == null) { return null; } return (CertSelector)certSelector.clone(); } /** * Sets the required constraints on the target certificate. The constraints * are specified as an instance of CertSelector. If null, no constraints are * defined.
*
* Note that the CertSelector specified is cloned to protect against * subsequent modifications. * * @param selector * a CertSelector specifying the constraints on the target * certificate (or null) * * @see #getTargetCertConstraints() */ public void setTargetCertConstraints(CertSelector selector) { if (selector == null) { certSelector = null; } else { certSelector = (CertSelector)selector.clone(); } } /** * Makes a copy of this PKIXParameters object. Changes to the copy will not * affect the original and vice versa. * * @return a copy of this PKIXParameters object */ public Object clone() { try { PKIXParameters obj = (PKIXParameters)super.clone(); obj.certStores = new ArrayList(certStores); Iterator iter = certPathCheckers.iterator(); obj.certPathCheckers = new ArrayList(); while (iter.hasNext()) { obj.certPathCheckers.add(((PKIXCertPathChecker)iter.next()) .clone()); } if (initialPolicies != null) { obj.initialPolicies = new HashSet(initialPolicies); } if (trustAnchors != null) { obj.trustAnchors = new HashSet(trustAnchors); } if (certSelector != null) { obj.certSelector = (CertSelector)certSelector.clone(); } return obj; } catch (CloneNotSupportedException ex) { throw new InternalError(); } } /** * Returns a formatted string describing the parameters. * * @return a formatted string describing the parameters. */ public String toString() { StringBuffer s = new StringBuffer(); s.append("[\n"); if (trustAnchors != null) { s.append(" Trust Anchors: ").append(trustAnchors).append('\n'); } if (initialPolicies != null) { if (initialPolicies.isEmpty()) { s.append(" Initial Policy OIDs: any\n"); } else { s.append(" Initial Policy OIDs: [") .append(initialPolicies).append("]\n"); } } s.append(" Validity Date: "); if (date != null) { s.append(date); } else { s.append("null"); } s.append('\n'); s.append(" Signature Provider: "); if (sigProvider != null) { s.append(sigProvider); } else { s.append("null"); } s.append('\n'); s.append(" Default Revocation Enabled: "); s.append(revocationEnabled); s.append('\n'); s.append(" Explicit Policy Required: "); s.append(explicitPolicyRequired); s.append('\n'); s.append(" Policy Mapping Inhibited: "); s.append(policyMappingInhibited); s.append('\n'); s.append(" Any Policy Inhibited: "); s.append(anyPolicyInhibited); s.append('\n'); s.append(" Policy Qualifiers Rejected: "); s.append(policyQualifiersRejected); s.append('\n'); s.append(" Target Cert Constraints: "); s.append(certSelector); s.append('\n'); s.append(" Certification Path Checkers: ["); s.append(certPathCheckers); s.append("}\n"); s.append(" CertStores: ["); s.append(certStores); s.append("}\n"); s.append("]\n"); return s.toString(); } } bouncycastle-1.49.orig/jdk1.3/org/bouncycastle/jce/cert/CertPathBuilderResult.java0000644000175000017500000000260610262753174027501 0ustar ebourgebourgpackage org.bouncycastle.jce.cert; /** * A specification of the result of a certification path builder algorithm. * All results returned by the {@link CertPathBuilder#build CertPathBuilder.build} method * must implement this interface.
*
* At a minimum, a CertPathBuilderResult contains the CertPath built by the * CertPathBuilder instance. Implementations of this interface may add methods * to return implementation or algorithm specific information, such as * debugging information or certification path validation results.
*
* Concurrent Access
*
* Unless otherwise specified, the methods defined in this interface are not * thread-safe. Multiple threads that need to access a single object * concurrently should synchronize amongst themselves and provide the * necessary locking. Multiple threads each manipulating separate objects * need not synchronize. **/ public interface CertPathBuilderResult extends Cloneable { /** * Returns the built certification path. * * @return the certification path (never null) */ public CertPath getCertPath(); /** * Makes a copy of this CertPathBuilderResult. * Changes to the copy will not affect the original and vice * versa. * * @return a copy of this CertPathBuilderResult */ public Object clone(); } bouncycastle-1.49.orig/jdk1.3/org/bouncycastle/jce/cert/CertUtil.java0000644000175000017500000004073411701477362025021 0ustar ebourgebourgpackage org.bouncycastle.jce.cert; import java.io.ByteArrayOutputStream; import java.io.IOException; import java.security.InvalidAlgorithmParameterException; import java.security.NoSuchProviderException; import java.security.Provider; import java.security.Security; import org.bouncycastle.asn1.ASN1Object; import org.bouncycastle.asn1.ASN1ObjectIdentifier; import org.bouncycastle.asn1.DERIA5String; import org.bouncycastle.asn1.DEROutputStream; import org.bouncycastle.asn1.OIDTokenizer; import org.bouncycastle.asn1.x509.X509Name; import org.bouncycastle.util.Strings; class CertUtil { static class Implementation { Object engine; Provider provider; Implementation( Object engine, Provider provider) { this.engine = engine; this.provider = provider; } Object getEngine() { return engine; } Provider getProvider() { return provider; } } /** * see if we can find an algorithm (or its alias and what it represents) in * the property table for the given provider. * * @return null if no algorithm found, an Implementation if it is. */ static Implementation getImplementation( String baseName, String algorithm, Provider prov) { if (prov == null) { Provider[] provider = Security.getProviders(); // // search every provider looking for the algorithm we want. // for (int i = 0; i != provider.length; i++) { Implementation imp = getImplementation(baseName, algorithm, provider[i]); if (imp != null) { return imp; } } return null; } String alias; while ((alias = prov.getProperty("Alg.Alias." + baseName + "." + algorithm)) != null) { algorithm = alias; } String className = prov.getProperty(baseName + "." + algorithm); if (className != null) { try { return new Implementation(Class.forName(className).newInstance(), prov); } catch (ClassNotFoundException e) { throw new IllegalStateException( "algorithm " + algorithm + " in provider " + prov.getName() + " but no class found!"); } catch (Exception e) { throw new IllegalStateException( "algorithm " + algorithm + " in provider " + prov.getName() + " but class inaccessible: " + e.toString()); } } return null; } /** * return an implementation for a given algorithm/provider. * If the provider is null, we grab the first avalaible who has the required algorithm. * * @return null if no algorithm found, an Implementation if it is. * @exception NoSuchProviderException if a provider is specified and not found. */ static Implementation getImplementation( String baseName, String algorithm, String provider) throws NoSuchProviderException { if (provider == null) { Provider[] prov = Security.getProviders(); // // search every provider looking for the algorithm we want. // for (int i = 0; i != prov.length; i++) { Implementation imp = getImplementation(baseName, algorithm, prov[i]); if (imp != null) { return imp; } } } else { Provider prov = Security.getProvider(provider); if (prov == null) { throw new NoSuchProviderException("Provider " + provider + " not found"); } return getImplementation(baseName, algorithm, prov); } return null; } /** * see if we can find an algorithm (or its alias and what it represents) in * the property table for the given provider. * * @return null if no algorithm found, an Implementation if it is. */ static Implementation getImplementation(String baseName, String algorithm, Provider prov, Class[] ctorparamtype, Object[] ctorparam) throws InvalidAlgorithmParameterException { String alias; while ((alias = prov.getProperty("Alg.Alias." + baseName + "." + algorithm)) != null) { algorithm = alias; } String className = prov.getProperty(baseName + "." + algorithm); if (className != null) { try { return new Implementation(Class.forName(className) .getConstructor(ctorparamtype).newInstance(ctorparam), prov); } catch (ClassNotFoundException e) { throw new IllegalStateException("algorithm " + algorithm + " in provider " + prov.getName() + " but no class found!"); } catch (Exception e) { if (e instanceof InvalidAlgorithmParameterException) { throw (InvalidAlgorithmParameterException)e; } throw new IllegalStateException("algorithm " + algorithm + " in provider " + prov.getName() + " but class inaccessible!"); } } return null; } /** * return an implementation for a given algorithm/provider. If the provider * is null, we grab the first avalaible who has the required algorithm. * * @return null if no algorithm found, an Implementation if it is. * * @exception NoSuchProviderException * if a provider is specified and not found. */ static Implementation getImplementation(String baseName, String algorithm, String provider, Class[] ctorparamtype, Object[] ctorparam) throws NoSuchProviderException, InvalidAlgorithmParameterException { if (provider == null) { Provider[] prov = Security.getProviders(); // // search every provider looking for the algorithm we want. // for (int i = 0; i != prov.length; i++) { Implementation imp = getImplementation(baseName, algorithm, prov[i], ctorparamtype, ctorparam); if (imp != null) { return imp; } } } else { Provider prov = Security.getProvider(provider); if (prov == null) { throw new NoSuchProviderException("Provider " + provider + " not found"); } return getImplementation(baseName, algorithm, prov, ctorparamtype, ctorparam); } return null; } static byte[] parseGeneralName(int type, String data) throws IOException { byte[] encoded = null; switch (type) { case 0: throw new IOException( "unable to parse OtherName String representation"); case 1: encoded = parseRfc822(data.trim()); break; case 2: encoded = parseDNSName(data.trim()); break; case 3: throw new IOException( "unable to parse ORAddress String representation"); case 4: encoded = parseX509Name(data.trim()); break; case 5: throw new IOException( "unable to parse EDIPartyName String representation"); case 6: encoded = parseURI(data.trim()); break; case 7: encoded = parseIP(data.trim()); break; case 8: encoded = parseOID(data.trim()); break; default: throw new IOException( "unable to parse unkown type String representation"); } return encoded; } /** * Check the format of an OID.
* Throw an IOException if the first component is not 0, 1 or 2 or the * second component is greater than 39.
*
* User {@link org.bouncycastle.asn1.OIDTokenizer OIDTokenizer} * * @param the * OID to be checked. * * @exception IOException * if the first component is not 0, 1 or 2 or the second * component is greater than 39. */ static byte[] parseOID(String oid) throws IOException { OIDTokenizer tokenizer = new OIDTokenizer(oid); String token; if (!tokenizer.hasMoreTokens()) { throw new IOException("OID contains no tokens"); } token = tokenizer.nextToken(); if (token == null) { throw new IOException("OID contains no tokens"); } try { int test = (Integer.valueOf(token)).intValue(); if (test < 0 || test > 2) { throw new IOException("first token is not >= 0 and <=2"); } if (!tokenizer.hasMoreTokens()) { throw new IOException("OID contains only one token"); } token = tokenizer.nextToken(); if (token == null) { throw new IOException("OID contains only one token"); } test = (Integer.valueOf(token)).intValue(); if (test < 0 || test > 39) { throw new IOException("secon token is not >= 0 and <=39"); } } catch (NumberFormatException ex) { throw new IOException("token: " + token + ": " + ex.toString()); } ASN1Object derData = new ASN1ObjectIdentifier(oid); ByteArrayOutputStream outStream = new ByteArrayOutputStream(); DEROutputStream derOutStream = new DEROutputStream(outStream); derOutStream.writeObject(derData); derOutStream.close(); return outStream.toByteArray(); } /** * Parse the given IPv4 or IPv6 into DER encoded byte array representation. * * @param the * IP in well known String format * * @return the IP as byte array * * @exception IOException * if the String could not be parsed */ private static byte[] parseIP(String data) throws IOException { byte[] encoded = parseIPv4(data); if (encoded == null) { encoded = parseIPv6(data); } if (encoded == null) { throw new IOException( "unable to parse IP to DER encoded byte array"); } return encoded; } /** * Parse the given IPv4 into DER encoded byte array representation. * * @param the * IP in well known String format * * @return the IP as byte array or null if not parseable */ private static byte[] parseIPv4(String data) { if (data.length() == 0) { return null; } int octet; int octets = 0; byte[] dst = new byte[4]; int pos = 0; int start = 0; while (start < data.length() && (pos = data.indexOf('.', start)) > start && pos - start > 3) { try { octet = (Integer.valueOf(data.substring(start, pos - start))) .intValue(); } catch (NumberFormatException ex) { return null; } if (octet < 0 || octet > 255) { return null; } dst[octets++] = (byte)(octet & 0xff); start = pos + 1; } if (octets < 4) { return null; } return dst; } /** * Parse the given IPv6 into DER encoded byte array representation.
*
* TODO: implement this * * @param the * IP in well known String format * * @return the IP as byte array or null if not parseable */ private static byte[] parseIPv6(String data) { return null; } /** * Parse the given URI into DER encoded byte array representation. * * @param the * URI in well known String format * * @return the URI as byte array * * @exception IOException * if the String could not be parsed */ private static byte[] parseURI(String data) throws IOException { // TODO do parsing test ASN1Object derData = new DERIA5String(data); ByteArrayOutputStream outStream = new ByteArrayOutputStream(); DEROutputStream derOutStream = new DEROutputStream(outStream); derOutStream.writeObject(derData); derOutStream.close(); return outStream.toByteArray(); } /** * Parse the given rfc822 addr-spec into DER encoded byte array * representation. * * @param the * rfc822 addr-spec in well known String format * * @return the rfc822 addr-spec as byte array * * @exception IOException * if the String could not be parsed */ private static byte[] parseRfc822(String data) throws IOException { int tmpInt = data.indexOf('@'); if (tmpInt < 0 || tmpInt >= data.length() - 1) { throw new IOException("wrong format of rfc822Name:" + data); } // TODO more test for illegal charateers ASN1Object derData = new DERIA5String(data); ByteArrayOutputStream outStream = new ByteArrayOutputStream(); DEROutputStream derOutStream = new DEROutputStream(outStream); derOutStream.writeObject(derData); derOutStream.close(); return outStream.toByteArray(); } /** * Parse the given DNS name into DER encoded byte array representation. The * String must be in den preffered name syntax as defined in RFC 1034. * * @param the * DNS name in well known String format * * @return the DNS name as byte array * * @exception IOException * if the String could not be parsed */ private static byte[] parseDNSName(String data) throws IOException { // TODO more test for illegal charateers ASN1Object derData = new DERIA5String(data); ByteArrayOutputStream outStream = new ByteArrayOutputStream(); DEROutputStream derOutStream = new DEROutputStream(outStream); derOutStream.writeObject(derData); derOutStream.close(); return outStream.toByteArray(); } /** * Parse the given X.509 name into DER encoded byte array representation. * * @param the * X.509 name in well known String format * * @return the X.509 name as byte array * * @exception IOException * if the String could not be parsed */ private static byte[] parseX509Name(String data) throws IOException { // TODO more test for illegal charateers ByteArrayOutputStream outStream = new ByteArrayOutputStream(); DEROutputStream derOutStream = new DEROutputStream(outStream); derOutStream.writeObject(new X509Name(trimX509Name(data))); derOutStream.close(); return outStream.toByteArray(); } /** * Returns the given name converted to upper case and all multi spaces squezed * to one space. **/ static String trimX509Name(String name) { String data = Strings.toUpperCase(name.trim()); int pos; while ((pos = data.indexOf(" ")) >= 0) { data = data.substring(0, pos) + data.substring(pos + 1); } while ((pos = data.indexOf(" =")) >= 0) { data = data.substring(0, pos) + data.substring(pos + 1); } while ((pos = data.indexOf("= ")) >= 0) { data = data.substring(0, pos + 1) + data.substring(pos + 2); } return data; } }bouncycastle-1.49.orig/jdk1.3/org/bouncycastle/jce/cert/CertPathValidatorSpi.java0000644000175000017500000000477210262753174027323 0ustar ebourgebourgpackage org.bouncycastle.jce.cert; import java.security.InvalidAlgorithmParameterException; /** * * The Service Provider Interface (SPI) * for the {@link CertPathValidator CertPathValidator} class. All * CertPathValidator implementations must include a class (the * SPI class) that extends this class (CertPathValidatorSpi) * and implements all of its methods. In general, instances of this class * should only be accessed through the CertPathValidator class. * For details, see the Java Cryptography Architecture.
*
* Concurrent Access
*
* Instances of this class need not be protected against concurrent * access from multiple threads. Threads that need to access a single * CertPathValidatorSpi instance concurrently should synchronize * amongst themselves and provide the necessary locking before calling the * wrapping CertPathValidator object.
*
* However, implementations of CertPathValidatorSpi may still * encounter concurrency issues, since multiple threads each * manipulating a different CertPathValidatorSpi instance need not * synchronize. **/ public abstract class CertPathValidatorSpi extends Object { /** * The default constructor. */ public CertPathValidatorSpi() {} /** * Validates the specified certification path using the specified * algorithm parameter set.
*
* The CertPath specified must be of a type that is * supported by the validation algorithm, otherwise an * InvalidAlgorithmParameterException will be thrown. For * example, a CertPathValidator that implements the PKIX * algorithm validates CertPath objects of type X.509. * * @param certPath the CertPath to be validated * @param params the algorithm parameters * * @return the result of the validation algorithm * * @exception CertPathValidatorException if the CertPath * does not validate * @exception InvalidAlgorithmParameterException if the specified * parameters or the type of the specified CertPath are * inappropriate for this CertPathValidator */ public abstract CertPathValidatorResult engineValidate(CertPath certPath, CertPathParameters params) throws CertPathValidatorException, InvalidAlgorithmParameterException; } bouncycastle-1.49.orig/jdk1.3/org/bouncycastle/jce/cert/CertPathParameters.java0000644000175000017500000000114710262753174027016 0ustar ebourgebourgpackage org.bouncycastle.jce.cert; /** * A specification of certification path algorithm parameters. The purpose * of this interface is to group (and provide type safety for) all CertPath * parameter specifications. All CertPath parameter specifications must * implement this interface. **/ public interface CertPathParameters extends Cloneable { /** * Makes a copy of this CertPathParameters. Changes to the * copy will not affect the original and vice versa. * * @return a copy of this CertPathParameters **/ public Object clone(); } bouncycastle-1.49.orig/jdk1.3/org/bouncycastle/jce/cert/X509CRLSelector.java0000644000175000017500000005611611701477362025776 0ustar ebourgebourgpackage org.bouncycastle.jce.cert; import java.io.ByteArrayInputStream; import java.io.IOException; import java.math.BigInteger; import java.security.cert.CRL; import java.security.cert.X509CRL; import java.security.cert.X509Certificate; import java.util.Collection; import java.util.Date; import java.util.HashSet; import java.util.Iterator; import java.util.Set; import org.bouncycastle.asn1.ASN1InputStream; import org.bouncycastle.asn1.ASN1Object; import org.bouncycastle.asn1.ASN1OctetString; import org.bouncycastle.asn1.ASN1Sequence; import org.bouncycastle.asn1.DERInteger; import org.bouncycastle.asn1.x509.X509Extensions; import org.bouncycastle.asn1.x509.X509Name; import org.bouncycastle.jce.PrincipalUtil; /** * A CRLSelector that selects X509CRLs that match * all specified criteria. This class is particularly useful when selecting CRLs * from a CertStore to check revocation status of a particular * certificate.
*
* When first constructed, an X509CRLSelector has no criteria * enabled and each of the get methods return a default value (null). * Therefore, the {@link #match match} method would return true * for any X509CRL. Typically, several criteria are enabled (by * calling {@link #setIssuerNames setIssuerNames} or * {@link #setDateAndTime setDateAndTime}, for instance) and then the * X509CRLSelector is passed to * {@link CertStore#getCRLs CertStore.getCRLs} or some similar method.
*
* Please refer to RFC 2459 for definitions of the X.509 CRL fields and * extensions mentioned below.
*
* Concurrent Access
*
* Unless otherwise specified, the methods defined in this class are not * thread-safe. Multiple threads that need to access a single object * concurrently should synchronize amongst themselves and provide the necessary * locking. Multiple threads each manipulating separate objects need not * synchronize.
*
* Uses {@link org.bouncycastle.asn1.ASN1InputStream ASN1InputStream}, * {@link org.bouncycastle.asn1.ASN1Sequence ASN1Sequence}, * {@link org.bouncycastle.asn1.ASN1ObjectIdentifier ASN1ObjectIdentifier}, * {@link org.bouncycastle.asn1.DEROutputStream DEROutputStream}, * {@link org.bouncycastle.asn1.ASN1Object ASN1Object}, * {@link org.bouncycastle.asn1.x509.X509Name X509Name} * * @see CRLSelector * @see X509CRL */ public class X509CRLSelector implements CRLSelector { private Set issuerNames = null; private Set issuerNamesX509 = null; private BigInteger minCRL = null; private BigInteger maxCRL = null; private Date dateAndTime = null; private X509Certificate certChecking = null; /** * Creates an X509CRLSelector. Initially, no criteria are * set so any X509CRL will match. */ public X509CRLSelector() { } /** * Sets the issuerNames criterion. The issuer distinguished name in the * X509CRL must match at least one of the specified * distinguished names. If null, any issuer distinguished * name will do.
*
* This method allows the caller to specify, with a single method call, the * complete set of issuer names which X509CRLs may contain. * The specified value replaces the previous value for the issuerNames * criterion.
*
* The names parameter (if not null) is a * Collection of names. Each name is a String * or a byte array representing a distinguished name (in RFC 2253 or ASN.1 * DER encoded form, respectively). If null is supplied as * the value for this argument, no issuerNames check will be performed.
*
* Note that the names parameter can contain duplicate * distinguished names, but they may be removed from the * Collection of names returned by the * {@link #getIssuerNames getIssuerNames} method.
*
* If a name is specified as a byte array, it should contain a single DER * encoded distinguished name, as defined in X.501. The ASN.1 notation for * this structure is as follows. * *

     *  Name ::= CHOICE {
     *    RDNSequence }
     * 
     *  RDNSequence ::= SEQUENCE OF RDN
     * 
     *  RDN ::=
     *    SET SIZE (1 .. MAX) OF AttributeTypeAndValue
     * 
     *  AttributeTypeAndValue ::= SEQUENCE {
     *    type     AttributeType,
     *    value    AttributeValue }
     * 
     *  AttributeType ::= OBJECT IDENTIFIER
     * 
     *  AttributeValue ::= ANY DEFINED BY AttributeType
     *  ....
     *  DirectoryString ::= CHOICE {
     *        teletexString           TeletexString (SIZE (1..MAX)),
     *        printableString         PrintableString (SIZE (1..MAX)),
     *        universalString         UniversalString (SIZE (1..MAX)),
     *        utf8String              UTF8String (SIZE (1.. MAX)),
     *        bmpString               BMPString (SIZE (1..MAX)) }
     * 
* *
*
* Note that a deep copy is performed on the Collection to * protect against subsequent modifications. * * @param names * a Collection of names (or null) * * @exception IOException * if a parsing error occurs * * @see #getIssuerNames */ public void setIssuerNames(Collection names) throws IOException { if (names == null || names.isEmpty()) { issuerNames = null; issuerNamesX509 = null; } else { Object item; Iterator iter = names.iterator(); while (iter.hasNext()) { item = iter.next(); if (item instanceof String) { addIssuerName((String)item); } else if (item instanceof byte[]) { addIssuerName((byte[])item); } else { throw new IOException("name not byte[]or String: " + item.toString()); } } } } /** * Adds a name to the issuerNames criterion. The issuer distinguished name * in the X509CRL must match at least one of the specified * distinguished names.
*
* This method allows the caller to add a name to the set of issuer names * which X509CRLs may contain. The specified name is added to * any previous value for the issuerNames criterion. If the specified name * is a duplicate, it may be ignored.
*
* Uses {@link org.bouncycastle.asn1.x509.X509Name X509Name} for parsing the * name * * @param name * the name in RFC 2253 form * * @exception IOException * if a parsing error occurs */ public void addIssuerName(String name) throws IOException { if (issuerNames == null) { issuerNames = new HashSet(); issuerNamesX509 = new HashSet(); } X509Name nameX509; try { nameX509 = new X509Name(name); } catch (IllegalArgumentException ex) { throw new IOException(ex.getMessage()); } issuerNamesX509.add(nameX509); issuerNames.add(name); } /** * Adds a name to the issuerNames criterion. The issuer distinguished name * in the X509CRL must match at least one of the specified * distinguished names.
*
* This method allows the caller to add a name to the set of issuer names * which X509CRLs may contain. The specified name is added to * any previous value for the issuerNames criterion. If the specified name * is a duplicate, it may be ignored. If a name is specified as a byte * array, it should contain a single DER encoded distinguished name, as * defined in X.501. The ASN.1 notation for this structure is as follows.
*
* The name is provided as a byte array. This byte array should contain a * single DER encoded distinguished name, as defined in X.501. The ASN.1 * notation for this structure appears in the documentation for * {@link #setIssuerNames setIssuerNames(Collection names)}.
*
* Note that the byte array supplied here is cloned to protect against * subsequent modifications.
*
* Uses {@link org.bouncycastle.asn1.x509.X509Name X509Name} for parsing the * name, {@link org.bouncycastle.asn1.ASN1InputStream ASN1InputStream}, * {@link org.bouncycastle.asn1.ASN1Object ASN1Object} and * {@link org.bouncycastle.asn1.ASN1Sequence ASN1Sequence} * * @param name * a byte array containing the name in ASN.1 DER encoded form * * @exception IOException * if a parsing error occurs */ public void addIssuerName(byte[] name) throws IOException { if (issuerNames == null) { issuerNames = new HashSet(); issuerNamesX509 = new HashSet(); } ByteArrayInputStream inStream = new ByteArrayInputStream(name); ASN1InputStream derInStream = new ASN1InputStream(inStream); ASN1Object obj = derInStream.readObject(); if (obj instanceof ASN1Sequence) { issuerNamesX509.add(new X509Name((ASN1Sequence)obj)); } else { throw new IOException("parsing error"); } issuerNames.add(name.clone()); } /** * Sets the minCRLNumber criterion. The X509CRL must have a * CRL number extension whose value is greater than or equal to the * specified value. If null, no minCRLNumber check will be * done. * * @param minCRL * the minimum CRL number accepted (or null) */ public void setMinCRLNumber(BigInteger minCRL) { this.minCRL = minCRL; } /** * Sets the maxCRLNumber criterion. The X509CRL must have a * CRL number extension whose value is less than or equal to the specified * value. If null, no maxCRLNumber check will be done. * * @param maxCRL * the maximum CRL number accepted (or null) */ public void setMaxCRLNumber(BigInteger maxCRL) { this.maxCRL = maxCRL; } /** * Sets the dateAndTime criterion. The specified date must be equal to or * later than the value of the thisUpdate component of the * X509CRL and earlier than the value of the nextUpdate * component. There is no match if the X509CRL does not * contain a nextUpdate component. If null, no dateAndTime * check will be done.
*
* Note that the Date supplied here is cloned to protect * against subsequent modifications. * * @param dateAndTime * the Date to match against (or null) * * @see #getDateAndTime */ public void setDateAndTime(Date dateAndTime) { if (dateAndTime == null) { this.dateAndTime = null; } else { this.dateAndTime = new Date(dateAndTime.getTime()); } } /** * Sets the certificate being checked. This is not a criterion. Rather, it * is optional information that may help a CertStore find * CRLs that would be relevant when checking revocation for the specified * certificate. If null is specified, then no such optional * information is provided. * * @param cert * the X509Certificate being checked (or * null) * * @see #getCertificateChecking */ public void setCertificateChecking(X509Certificate cert) { certChecking = cert; } /** * Returns a copy of the issuerNames criterion. The issuer distinguished * name in the X509CRL must match at least one of the * specified distinguished names. If the value returned is null, * any issuer distinguished name will do.
*
* If the value returned is not null, it is a * Collection of names. Each name is a String * or a byte array representing a distinguished name (in RFC 2253 or ASN.1 * DER encoded form, respectively). Note that the Collection * returned may contain duplicate names.
*
* If a name is specified as a byte array, it should contain a single DER * encoded distinguished name, as defined in X.501. The ASN.1 notation for * this structure is given in the documentation for * {@link #setIssuerNames setIssuerNames(Collection names)}.
*
* Note that a deep copy is performed on the Collection to * protect against subsequent modifications. * * @return a Collection of names (or null) * @see #setIssuerNames */ public Collection getIssuerNames() { if (issuerNames == null) { return null; } Collection set = new HashSet(); Iterator iter = issuerNames.iterator(); Object item; while (iter.hasNext()) { item = iter.next(); if (item instanceof String) { set.add(new String((String)item)); } else if (item instanceof byte[]) { set.add(((byte[])item).clone()); } } return set; } /** * Returns the minCRLNumber criterion. The X509CRL must have * a CRL number extension whose value is greater than or equal to the * specified value. If null, no minCRLNumber check will be * done. * * @return the minimum CRL number accepted (or null) */ public BigInteger getMinCRL() { return minCRL; } /** * Returns the maxCRLNumber criterion. The X509CRL must have * a CRL number extension whose value is less than or equal to the specified * value. If null, no maxCRLNumber check will be done. * * @return the maximum CRL number accepted (or null) */ public BigInteger getMaxCRL() { return maxCRL; } /** * Returns the dateAndTime criterion. The specified date must be equal to or * later than the value of the thisUpdate component of the * X509CRL and earlier than the value of the nextUpdate * component. There is no match if the X509CRL does not * contain a nextUpdate component. If null, no dateAndTime * check will be done.
*
* Note that the Date returned is cloned to protect against * subsequent modifications. * * @return the Date to match against (or null) * * @see #setDateAndTime */ public Date getDateAndTime() { if (dateAndTime == null) { return null; } return new Date(dateAndTime.getTime()); } /** * Returns the certificate being checked. This is not a criterion. Rather, * it is optional information that may help a CertStore find * CRLs that would be relevant when checking revocation for the specified * certificate. If the value returned is null, then no such * optional information is provided. * * @return the certificate being checked (or null) * * @see #setCertificateChecking */ public X509Certificate getCertificateChecking() { return certChecking; } /** * Returns a printable representation of the X509CRLSelector.
*
* Uses * {@link org.bouncycastle.asn1.x509.X509Name#toString X509Name.toString} to * format the output * * @return a String describing the contents of the * X509CRLSelector. */ public String toString() { StringBuffer s = new StringBuffer(); s.append("X509CRLSelector: [\n"); if (issuerNamesX509 != null) { s.append(" IssuerNames:\n"); Iterator iter = issuerNamesX509.iterator(); while (iter.hasNext()) { s.append(" ").append(iter.next()).append('\n'); } } if (minCRL != null) { s.append(" minCRLNumber: ").append(minCRL).append('\n'); } if (maxCRL != null) { s.append(" maxCRLNumber: ").append(maxCRL).append('\n'); } if (dateAndTime != null) { s.append(" dateAndTime: ").append(dateAndTime).append('\n'); } if (certChecking != null) { s.append(" Certificate being checked: ").append(certChecking).append('\n'); } s.append(']'); return s.toString(); } /** * Decides whether a CRL should be selected.
*
* Uses * {@link org.bouncycastle.asn1.x509.X509Name#toString X509Name.toString} to * parse and to compare the crl parameter issuer and * {@link org.bouncycastle.asn1.x509.X509Extensions#CRLNumber CRLNumber} to * access the CRL number extension. * * @param crl * the CRL to be checked * * @return true if the CRL should be selected, * false otherwise */ public boolean match(CRL crl) { if (!(crl instanceof X509CRL)) { return false; } X509CRL crlX509 = (X509CRL)crl; boolean test; if (issuerNamesX509 != null) { Iterator iter = issuerNamesX509.iterator(); test = false; X509Name crlIssuer = null; try { crlIssuer = PrincipalUtil.getIssuerX509Principal(crlX509); } catch (Exception ex) { return false; } while (iter.hasNext()) { if (crlIssuer.equals(iter.next(), true)) { test = true; break; } } if (!test) { return false; } } byte[] data = crlX509.getExtensionValue(X509Extensions.CRLNumber .getId()); if (data != null) { try { ByteArrayInputStream inStream = new ByteArrayInputStream(data); ASN1InputStream derInputStream = new ASN1InputStream(inStream); inStream = new ByteArrayInputStream( ((ASN1OctetString)derInputStream.readObject()) .getOctets()); derInputStream = new ASN1InputStream(inStream); BigInteger crlNumber = ((DERInteger)derInputStream.readObject()) .getPositiveValue(); if (minCRL != null && minCRL.compareTo(crlNumber) > 0) { return false; } if (maxCRL != null && maxCRL.compareTo(crlNumber) < 0) { return false; } } catch (IOException ex) { return false; } } else if (minCRL != null || maxCRL != null) { return false; } if (dateAndTime != null) { Date check = crlX509.getThisUpdate(); if (check == null) { return false; } else if (dateAndTime.before(check)) { return false; } check = crlX509.getNextUpdate(); if (check == null) { return false; } else if (!dateAndTime.before(check)) { return false; } } return true; } /** * Returns a copy of this object. * * @return the copy */ public Object clone() { try { X509CRLSelector copy = (X509CRLSelector)super.clone(); if (issuerNames != null) { copy.issuerNames = new HashSet(); Iterator iter = issuerNames.iterator(); Object obj; while (iter.hasNext()) { obj = iter.next(); if (obj instanceof byte[]) { copy.issuerNames.add(((byte[])obj).clone()); } else { copy.issuerNames.add(obj); } } copy.issuerNamesX509 = new HashSet(issuerNamesX509); } return copy; } catch (CloneNotSupportedException e) { /* Cannot happen */ throw new InternalError(e.toString()); } } /** * Decides whether a CRL should be selected. * * @param crl * the CRL to be checked * * @return true if the CRL should be selected, * false otherwise */ public boolean equals(Object obj) { if (!(obj instanceof X509CRLSelector)) { return false; } X509CRLSelector equalsCRL = (X509CRLSelector)obj; if (!equals(dateAndTime, equalsCRL.dateAndTime)) { return false; } if (!equals(minCRL, equalsCRL.minCRL)) { return false; } if (!equals(maxCRL, equalsCRL.maxCRL)) { return false; } if (!equals(issuerNamesX509, equalsCRL.issuerNamesX509)) { return false; } if (!equals(certChecking, equalsCRL.certChecking)) { return false; } return true; } /** * Return true if two Objects are unequal. * This means that one is null and the other is * not or obj1.equals(obj2) returns * false. **/ private boolean equals(Object obj1, Object obj2) { if (obj1 == null) { if (obj2 != null) { return true; } } else if (!obj1.equals(obj2)) { return true; } return false; } }bouncycastle-1.49.orig/jdk1.3/org/bouncycastle/jce/cert/X509CertSelector.java0000644000175000017500000026507312104173671026251 0ustar ebourgebourgpackage org.bouncycastle.jce.cert; import java.io.ByteArrayInputStream; import java.io.ByteArrayOutputStream; import java.io.IOException; import java.math.BigInteger; import java.security.PublicKey; import java.security.cert.Certificate; import java.security.cert.X509Certificate; import java.text.SimpleDateFormat; import java.util.ArrayList; import java.util.Arrays; import java.util.Collection; import java.util.Collections; import java.util.Date; import java.util.Enumeration; import java.util.HashSet; import java.util.Hashtable; import java.util.Iterator; import java.util.List; import java.util.Set; import org.bouncycastle.asn1.ASN1InputStream; import org.bouncycastle.asn1.ASN1Object; import org.bouncycastle.asn1.ASN1ObjectIdentifier; import org.bouncycastle.asn1.ASN1OctetString; import org.bouncycastle.asn1.ASN1Sequence; import org.bouncycastle.asn1.ASN1TaggedObject; import org.bouncycastle.asn1.DERGeneralizedTime; import org.bouncycastle.asn1.DEROutputStream; import org.bouncycastle.asn1.util.ASN1Dump; import org.bouncycastle.asn1.x509.AlgorithmIdentifier; import org.bouncycastle.asn1.x509.ExtendedKeyUsage; import org.bouncycastle.asn1.x509.KeyPurposeId; import org.bouncycastle.asn1.x509.SubjectPublicKeyInfo; import org.bouncycastle.asn1.x509.X509Extensions; import org.bouncycastle.asn1.x509.X509Name; import org.bouncycastle.jce.PrincipalUtil; import org.bouncycastle.util.Integers; /** * A CertSelector that selects * X509Certificates that match all * specified criteria. This class is particularly useful when * selecting certificates from a CertStore to build a PKIX-compliant * certification path.
*
* When first constructed, an X509CertSelector has no criteria enabled * and each of the get methods return a default value (null, or -1 for * the {@link #getBasicConstraints} method). Therefore, the {@link #match} method would * return true for any X509Certificate. Typically, several criteria * are enabled (by calling {@link #setIssuer} or {@link #setKeyUsage}, for instance) and * then the X509CertSelector is passed to {@link CertStore#getCertificates} or * some similar method.
*
* Several criteria can be enabled (by calling {@link #setIssuer} and * {@link #setSerialNumber}, for example) such that the match method usually * uniquely matches a single X509Certificate. We say usually, since it * is possible for two issuing CAs to have the same distinguished name * and each issue a certificate with the same serial number. Other * unique combinations include the issuer, subject, * subjectKeyIdentifier and/or the subjectPublicKey criteria.
*
* Please refer to RFC 2459 for definitions of the X.509 certificate * extensions mentioned below.
*
* Concurrent Access
*
* Unless otherwise specified, the methods defined in this class are * not thread-safe. Multiple threads that need to access a single * object concurrently should synchronize amongst themselves and * provide the necessary locking. Multiple threads each manipulating * separate objects need not synchronize.
*
* TODO: implement name constraints * TODO: implement match check for path to names
*
* Uses {@link org.bouncycastle.asn1.ASN1InputStream ASN1InputStream}, * {@link org.bouncycastle.asn1.ASN1Sequence ASN1Sequence}, * {@link org.bouncycastle.asn1.ASN1ObjectIdentifier ASN1ObjectIdentifier}, * {@link org.bouncycastle.asn1.DEROutputStream DEROutputStream}, * {@link org.bouncycastle.asn1.ASN1Object ASN1Object}, * {@link org.bouncycastle.asn1.OIDTokenizer OIDTokenizer}, * {@link org.bouncycastle.asn1.x509.X509Name X509Name}, * {@link org.bouncycastle.asn1.x509.X509Extensions X509Extensions}, * {@link org.bouncycastle.asn1.x509.ExtendedKeyUsage ExtendedKeyUsage}, * {@link org.bouncycastle.asn1.x509.KeyPurposeId KeyPurposeId}, * {@link org.bouncycastle.asn1.x509.SubjectPublicKeyInfo SubjectPublicKeyInfo}, * {@link org.bouncycastle.asn1.x509.AlgorithmIdentifier AlgorithmIdentifier} */ public class X509CertSelector implements CertSelector { private static final Hashtable keyPurposeIdMap = new Hashtable(); static { keyPurposeIdMap.put(KeyPurposeId.id_kp_serverAuth.getId(), KeyPurposeId.id_kp_serverAuth); keyPurposeIdMap.put(KeyPurposeId.id_kp_clientAuth.getId(), KeyPurposeId.id_kp_clientAuth); keyPurposeIdMap.put(KeyPurposeId.id_kp_codeSigning.getId(), KeyPurposeId.id_kp_codeSigning); keyPurposeIdMap.put(KeyPurposeId.id_kp_emailProtection.getId(), KeyPurposeId.id_kp_emailProtection); keyPurposeIdMap.put(KeyPurposeId.id_kp_ipsecEndSystem.getId(), KeyPurposeId.id_kp_ipsecEndSystem); keyPurposeIdMap.put(KeyPurposeId.id_kp_ipsecTunnel.getId(), KeyPurposeId.id_kp_ipsecTunnel); keyPurposeIdMap.put(KeyPurposeId.id_kp_ipsecUser.getId(), KeyPurposeId.id_kp_ipsecUser); keyPurposeIdMap.put(KeyPurposeId.id_kp_timeStamping.getId(), KeyPurposeId.id_kp_timeStamping); } private X509Certificate x509Cert = null; private BigInteger serialNumber = null; private Object issuerDN = null; private X509Name issuerDNX509 = null; private Object subjectDN = null; private X509Name subjectDNX509 = null; private byte[] subjectKeyID = null; private byte[] authorityKeyID = null; private Date certValid = null; private Date privateKeyValid = null; private ASN1ObjectIdentifier subjectKeyAlgID = null; private PublicKey subjectPublicKey = null; private byte[] subjectPublicKeyByte = null; private boolean[] keyUsage = null; private Set keyPurposeSet = null; private boolean matchAllSubjectAltNames = true; private Set subjectAltNames = null; private Set subjectAltNamesByte = null; private int minMaxPathLen = -1; private Set policy = null; private Set policyOID = null; private Set pathToNames = null; private Set pathToNamesByte = null; /** * Creates an X509CertSelector. Initially, no criteria are * set so any X509Certificate will match. */ public X509CertSelector() { } /** * Sets the certificateEquals criterion. The specified * X509Certificate must be equal to the * X509Certificate passed to the match method. If * null, then this check is not applied.
*
* This method is particularly useful when it is necessary to match a single * certificate. Although other criteria can be specified in conjunction with * the certificateEquals criterion, it is usually not practical or * necessary. * * @param cert * the X509Certificate to match (or null) * * @see #getCertificate() */ public void setCertificate(X509Certificate cert) { x509Cert = cert; } /** * Sets the serialNumber criterion. The specified serial number must match * the certificate serial number in the X509Certificate. If * null, any certificate serial number will do. * * @param serial * the certificate serial number to match (or null) * * @see #getSerialNumber() */ public void setSerialNumber(BigInteger serial) { serialNumber = serial; } /** * Sets the issuer criterion. The specified distinguished name must match * the issuer distinguished name in the X509Certificate. If * null, any issuer distinguished name will do.
*
* If issuerDN is not null, it should contain * a distinguished name, in RFC 2253 format.
*
* Uses {@link org.bouncycastle.asn1.x509.X509Name X509Name} for parsing the * issuerDN. * * @param issuerDN * a distinguished name in RFC 2253 format (or null) * * @exception IOException * if a parsing error occurs (incorrect form for DN) */ public void setIssuer(String issuerDN) throws IOException { if (issuerDN == null) { this.issuerDN = null; this.issuerDNX509 = null; } else { X509Name nameX509; try { nameX509 = new X509Name(issuerDN); } catch (IllegalArgumentException ex) { throw new IOException(ex.getMessage()); } this.issuerDNX509 = nameX509; this.issuerDN = issuerDN; } } /** * Sets the issuer criterion. The specified distinguished name must match * the issuer distinguished name in the X509Certificate. If * null is specified, the issuer criterion is disabled and any issuer * distinguished name will do.
*
* If issuerDN is not null, it should contain * a single DER encoded distinguished name, as defined in X.501. The ASN.1 * notation for this structure is as follows.
*
* *
     *    Name ::= CHOICE {
     *      RDNSequence }
     * 
     *    RDNSequence ::= SEQUENCE OF RDN
     * 
     *    RDN ::=
     *      SET SIZE (1 .. MAX) OF AttributeTypeAndValue
     * 
     *    AttributeTypeAndValue ::= SEQUENCE {
     *      type     AttributeType,
     *      value    AttributeValue }
     * 
     *    AttributeType ::= OBJECT IDENTIFIER
     * 
     *    AttributeValue ::= ANY DEFINED BY AttributeType
     *    ....
     *    DirectoryString ::= CHOICE {
     *      teletexString           TeletexString (SIZE (1..MAX)),
     *      printableString         PrintableString (SIZE (1..MAX)),
     *      universalString         UniversalString (SIZE (1..MAX)),
     *      utf8String              UTF8String (SIZE (1.. MAX)),
     *      bmpString               BMPString (SIZE (1..MAX)) }
     * 
* *
*
* Note that the byte array specified here is cloned to protect against * subsequent modifications.
*
* Uses {@link org.bouncycastle.asn1.ASN1InputStream ASN1InputStream}, * {@link org.bouncycastle.asn1.ASN1Object ASN1Object}, * {@link org.bouncycastle.asn1.ASN1Sequence ASN1Sequence}, * {@link org.bouncycastle.asn1.x509.X509Name X509Name} * * @param issuerDN - * a byte array containing the distinguished name in ASN.1 DER * encoded form (or null) * * @exception IOException * if an encoding error occurs (incorrect form for DN) */ public void setIssuer(byte[] issuerDN) throws IOException { if (issuerDN == null) { this.issuerDN = null; this.issuerDNX509 = null; } else { ByteArrayInputStream inStream = new ByteArrayInputStream(issuerDN); ASN1InputStream derInStream = new ASN1InputStream(inStream); ASN1Object obj = derInStream.readObject(); if (obj instanceof ASN1Sequence) { this.issuerDNX509 = new X509Name((ASN1Sequence)obj); } else { throw new IOException("parsing error"); } this.issuerDN = (byte[])issuerDN.clone(); } } /** * Sets the subject criterion. The specified distinguished name must match * the subject distinguished name in the X509Certificate. If * null, any subject distinguished name will do.
*
* If subjectDN is not null, it should * contain a distinguished name, in RFC 2253 format.
*
* Uses {@link org.bouncycastle.asn1.x509.X509Name X509Name} for parsing the * subjectDN. * * @param subjectDN * a distinguished name in RFC 2253 format (or null) * * @exception IOException * if a parsing error occurs (incorrect form for DN) */ public void setSubject(String subjectDN) throws IOException { if (subjectDN == null) { this.subjectDN = null; this.subjectDNX509 = null; } else { X509Name nameX509; try { nameX509 = new X509Name(subjectDN); } catch (IllegalArgumentException ex) { throw new IOException(ex.getMessage()); } this.subjectDNX509 = nameX509; this.subjectDN = subjectDN; } } /** * Sets the subject criterion. The specified distinguished name must match * the subject distinguished name in the X509Certificate. If * null, any subject distinguished name will do.
*
* If subjectDN is not null, it should * contain a single DER encoded distinguished name, as defined in X.501. For * the ASN.1 notation for this structure, see * {@link #setIssuer(byte []) setIssuer(byte [] issuerDN)}.
*
* Uses {@link org.bouncycastle.asn1.ASN1InputStream ASN1InputStream}, * {@link org.bouncycastle.asn1.ASN1Object ASN1Object}, * {@link org.bouncycastle.asn1.ASN1Sequence ASN1Sequence}, * {@link org.bouncycastle.asn1.x509.X509Name X509Name} * * @param subjectDN * a byte array containing the distinguished name in ASN.1 DER * format (or null) * * @exception IOException * if an encoding error occurs (incorrect form for DN) */ public void setSubject(byte[] subjectDN) throws IOException { if (subjectDN == null) { this.subjectDN = null; this.subjectDNX509 = null; } else { ByteArrayInputStream inStream = new ByteArrayInputStream(subjectDN); ASN1InputStream derInStream = new ASN1InputStream(inStream); ASN1Object obj = derInStream.readObject(); if (obj instanceof ASN1Sequence) { this.subjectDNX509 = new X509Name((ASN1Sequence)obj); } else { throw new IOException("parsing error"); } this.subjectDN = (byte[])subjectDN.clone(); } } /** * Sets the subjectKeyIdentifier criterion. The X509Certificate * must contain a SubjectKeyIdentifier extension for which the contents of * the extension matches the specified criterion value. If the criterion * value is null, no subjectKeyIdentifier check will be done.
*
* If subjectKeyID is not null, it should * contain a single DER encoded value corresponding to the contents of the * extension value (not including the object identifier, criticality * setting, and encapsulating OCTET STRING) for a SubjectKeyIdentifier * extension. The ASN.1 notation for this structure follows.
*
* *
     *    SubjectKeyIdentifier ::= KeyIdentifier
     * 
     *    KeyIdentifier ::= OCTET STRING
     * 
* *
*
* Since the format of subject key identifiers is not mandated by any * standard, subject key identifiers are not parsed by the * X509CertSelector. Instead, the values are compared using * a byte-by-byte comparison.
*
* Note that the byte array supplied here is cloned to protect against * subsequent modifications. * * @param subjectKeyID - * the subject key identifier (or null) * * @see #getSubjectKeyIdentifier() */ public void setSubjectKeyIdentifier(byte[] subjectKeyID) { if (subjectKeyID == null) { this.subjectKeyID = null; } else { this.subjectKeyID = (byte[])subjectKeyID.clone(); } } /** * Sets the authorityKeyIdentifier criterion. The * X509Certificate must contain an AuthorityKeyIdentifier * extension for which the contents of the extension value matches the * specified criterion value. If the criterion value is null, * no authorityKeyIdentifier check will be done.
*
* If authorityKeyID is not null, it should * contain a single DER encoded value corresponding to the contents of the * extension value (not including the object identifier, criticality * setting, and encapsulating OCTET STRING) for an AuthorityKeyIdentifier * extension. The ASN.1 notation for this structure follows.
*
* *
     *    AuthorityKeyIdentifier ::= SEQUENCE {
     *      keyIdentifier             [0] KeyIdentifier           OPTIONAL,
     *      authorityCertIssuer       [1] GeneralNames            OPTIONAL,
     *      authorityCertSerialNumber [2] CertificateSerialNumber OPTIONAL  }
     * 
     *    KeyIdentifier ::= OCTET STRING
     * 
* *
*
* Authority key identifiers are not parsed by the * X509CertSelector. Instead, the values are compared using * a byte-by-byte comparison.
*
* When the keyIdentifier field of * AuthorityKeyIdentifier is populated, the value is usually * taken from the SubjectKeyIdentifier extension in the issuer's * certificate. Note, however, that the result of * X509Certificate.getExtensionValue() on the issuer's certificate may NOT be used directly as the * input to setAuthorityKeyIdentifier. This is because the * SubjectKeyIdentifier contains only a KeyIdentifier OCTET STRING, and not * a SEQUENCE of KeyIdentifier, GeneralNames, and CertificateSerialNumber. * In order to use the extension value of the issuer certificate's * SubjectKeyIdentifier extension, it will be necessary to extract the value * of the embedded KeyIdentifier OCTET STRING, then DER encode this OCTET * STRING inside a SEQUENCE. For more details on SubjectKeyIdentifier, see * {@link #setSubjectKeyIdentifier(byte[]) setSubjectKeyIdentifier(byte[] subjectKeyID }).
*
* Note also that the byte array supplied here is cloned to protect against * subsequent modifications. * * @param authorityKeyID * the authority key identifier (or null) * * @see #getAuthorityKeyIdentifier() */ public void setAuthorityKeyIdentifier(byte[] authorityKeyID) { if (authorityKeyID == null) { this.authorityKeyID = null; } else { this.authorityKeyID = (byte[])authorityKeyID.clone(); } } /** * Sets the certificateValid criterion. The specified date must fall within * the certificate validity period for the X509Certificate. If * null, no certificateValid check will be done.
*
* Note that the Date supplied here is cloned to protect against subsequent * modifications. * * @param certValid * the Date to check (or null) * * @see #getCertificateValid() */ public void setCertificateValid(Date certValid) { if (certValid == null) { this.certValid = null; } else { this.certValid = new Date(certValid.getTime()); } } /** * Sets the privateKeyValid criterion. The specified date must fall within * the private key validity period for the X509Certificate. If * null, no privateKeyValid check will be done.
*
* Note that the Date supplied here is cloned to protect against subsequent * modifications. * * @param privateKeyValid * the Date to check (or null) * * @see #getPrivateKeyValid() */ public void setPrivateKeyValid(Date privateKeyValid) { if (privateKeyValid == null) { this.privateKeyValid = null; } else { this.privateKeyValid = new Date(privateKeyValid.getTime()); } } /** * Sets the subjectPublicKeyAlgID criterion. The X509Certificate must * contain a subject public key with the specified algorithm. If * null, no subjectPublicKeyAlgID check will be done. * * @param oid * The object identifier (OID) of the algorithm to check for (or * null). An OID is represented by a set of * nonnegative integers separated by periods. * * @exception IOException * if the OID is invalid, such as the first component being * not 0, 1 or 2 or the second component being greater than * 39. * * @see #getSubjectPublicKeyAlgID() */ public void setSubjectPublicKeyAlgID(String oid) throws IOException { if (oid != null) { CertUtil.parseOID(oid); subjectKeyAlgID = new ASN1ObjectIdentifier(oid); } else { subjectKeyAlgID = null; } } /** * Sets the subjectPublicKey criterion. The X509Certificate must contain the * specified subject public key. If null, no subjectPublicKey check will be * done. * * @param key * the subject public key to check for (or null) * * @see #getSubjectPublicKey() */ public void setSubjectPublicKey(PublicKey key) { if (key == null) { subjectPublicKey = null; subjectPublicKeyByte = null; } else { subjectPublicKey = key; subjectPublicKeyByte = key.getEncoded(); } } /** * Sets the subjectPublicKey criterion. The X509Certificate * must contain the specified subject public key. If null, * no subjectPublicKey check will be done.
*
* Because this method allows the public key to be specified as a byte * array, it may be used for unknown key types.
*
* If key is not null, it should contain a single DER * encoded SubjectPublicKeyInfo structure, as defined in X.509. The ASN.1 * notation for this structure is as follows.
*
* *
     *    SubjectPublicKeyInfo  ::=  SEQUENCE  {
     *      algorithm            AlgorithmIdentifier,
     *      subjectPublicKey     BIT STRING  }
     * 
     *    AlgorithmIdentifier  ::=  SEQUENCE  {
     *      algorithm               OBJECT IDENTIFIER,
     *      parameters              ANY DEFINED BY algorithm OPTIONAL  }
     *                                -- contains a value of the type
     *                                -- registered for use with the
     *                                -- algorithm object identifier value
     * 
* *
*
* Note that the byte array supplied here is cloned to protect against * subsequent modifications. * * @param key * a byte array containing the subject public key in ASN.1 DER * form (or null) * * @exception IOException * if an encoding error occurs (incorrect form for subject * public key) * * @see #getSubjectPublicKey() */ public void setSubjectPublicKey(byte[] key) throws IOException { if (key == null) { subjectPublicKey = null; subjectPublicKeyByte = null; } else { subjectPublicKey = null; subjectPublicKeyByte = (byte[])key.clone(); // TODO // try to generyte PublicKey Object from subjectPublicKeyByte } } /** * Sets the keyUsage criterion. The X509Certificate must allow the specified * keyUsage values. If null, no keyUsage check will be done. Note that an * X509Certificate that has no keyUsage extension implicitly allows all * keyUsage values.
*
* Note that the boolean array supplied here is cloned to protect against * subsequent modifications. * * @param keyUsage * a boolean array in the same format as the boolean array * returned by X509Certificate.getKeyUsage(). Or * null. * * @see #getKeyUsage() */ public void setKeyUsage(boolean[] keyUsage) { if (keyUsage == null) { this.keyUsage = null; } else { this.keyUsage = (boolean[])keyUsage.clone(); } } /** * Sets the extendedKeyUsage criterion. The X509Certificate * must allow the specified key purposes in its extended key usage * extension. If keyPurposeSet is empty or null, * no extendedKeyUsage check will be done. Note that an * X509Certificate that has no extendedKeyUsage extension * implicitly allows all key purposes.
*
* Note that the Set is cloned to protect against subsequent modifications.
*
* Uses {@link org.bouncycastle.asn1.x509.KeyPurposeId KeyPurposeId} * * @param keyPurposeSet * a Set of key purpose OIDs in string format (or * null). Each OID is represented by a set of * nonnegative integers separated by periods. * * @exception IOException * if the OID is invalid, such as the first component being * not 0, 1 or 2 or the second component being greater than * 39. * * @see #getExtendedKeyUsage() */ public void setExtendedKeyUsage(Set keyPurposeSet) throws IOException { if (keyPurposeSet == null || keyPurposeSet.isEmpty()) { this.keyPurposeSet = keyPurposeSet; } else { this.keyPurposeSet = new HashSet(); Iterator iter = keyPurposeSet.iterator(); Object obj; KeyPurposeId purposeID; while (iter.hasNext()) { obj = iter.next(); if (obj instanceof String) { purposeID = (KeyPurposeId)keyPurposeIdMap.get((String)obj); if (purposeID == null) { throw new IOException("unknown purposeID " + (String)obj); } this.keyPurposeSet.add(purposeID); } } } } /** * Enables/disables matching all of the subjectAlternativeNames specified in * the {@link #setSubjectAlternativeNames setSubjectAlternativeNames} or * {@link #addSubjectAlternativeName addSubjectAlternativeName} methods. If * enabled, the X509Certificate must contain all of the * specified subject alternative names. If disabled, the X509Certificate * must contain at least one of the specified subject alternative names.
*
* The matchAllNames flag is true by default. * * @param matchAllNames * if true, the flag is enabled; if * false, the flag is disabled. * * @see #getMatchAllSubjectAltNames() */ public void setMatchAllSubjectAltNames(boolean matchAllNames) { matchAllSubjectAltNames = matchAllNames; } /** * Sets the subjectAlternativeNames criterion. The * X509Certificate must contain all or at least one of the * specified subjectAlternativeNames, depending on the value of the * matchAllNames flag (see {@link #setMatchAllSubjectAltNames}).
*
* This method allows the caller to specify, with a single method call, the * complete set of subject alternative names for the subjectAlternativeNames * criterion. The specified value replaces the previous value for the * subjectAlternativeNames criterion.
*
* The names parameter (if not null) is a * Collection with one entry for each name to be included in * the subject alternative name criterion. Each entry is a List * whose first entry is an Integer (the name type, 0-8) and * whose second entry is a String or a byte array (the name, * in string or ASN.1 DER encoded form, respectively). There can be multiple * names of the same type. If null is supplied as the value * for this argument, no subjectAlternativeNames check will be performed.
*
* Each subject alternative name in the Collection may be * specified either as a String or as an ASN.1 encoded byte * array. For more details about the formats used, see * {@link #addSubjectAlternativeName(int, String) addSubjectAlternativeName(int type, String name)} * and * {@link #addSubjectAlternativeName(int, byte[]) addSubjectAlternativeName(int type, byte [] name}).
*
* Note that the names parameter can contain duplicate names * (same name and name type), but they may be removed from the * Collection of names returned by the * {@link #getSubjectAlternativeNames} method.
*
* Note that a deep copy is performed on the Collection to protect against * subsequent modifications. * * @param names - * a Collection of names (or null) * * @exception IOException * if a parsing error occurs * * @see #getSubjectAlternativeNames() */ public void setSubjectAlternativeNames(Collection names) throws IOException { try { if (names == null || names.isEmpty()) { subjectAltNames = null; subjectAltNamesByte = null; } else { subjectAltNames = new HashSet(); subjectAltNamesByte = new HashSet(); Iterator iter = names.iterator(); List item; int type; Object data; while (iter.hasNext()) { item = (List)iter.next(); type = ((Integer)item.get(0)).intValue(); data = item.get(1); if (data instanceof String) { addSubjectAlternativeName(type, (String)data); } else if (data instanceof byte[]) { addSubjectAlternativeName(type, (byte[])data); } else { throw new IOException( "parsing error: unknown data type"); } } } } catch (Exception ex) { throw new IOException("parsing exception:\n" + ex.toString()); } } /** * Adds a name to the subjectAlternativeNames criterion. The * X509Certificate must contain all or at least one of the * specified subjectAlternativeNames, depending on the value of the * matchAllNames flag (see {@link #setMatchAllSubjectAltNames}).
*
* This method allows the caller to add a name to the set of subject * alternative names. The specified name is added to any previous value for * the subjectAlternativeNames criterion. If the specified name is a * duplicate, it may be ignored.
*
* The name is provided in string format. RFC 822, DNS, and URI names use * the well-established string formats for those types (subject to the * restrictions included in RFC 2459). IPv4 address names are supplied using * dotted quad notation. OID address names are represented as a series of * nonnegative integers separated by periods. And directory names * (distinguished names) are supplied in RFC 2253 format. No standard string * format is defined for otherNames, X.400 names, EDI party names, IPv6 * address names, or any other type of names. They should be specified using * the * {@link #addSubjectAlternativeName(int, byte[]) addSubjectAlternativeName(int type, byte [] name)} * method. * * @param type * the name type (0-8, as specified in RFC 2459, section 4.2.1.7) * @param name - * the name in string form (not null) * * @exception IOException * if a parsing error occurs */ public void addSubjectAlternativeName(int type, String name) throws IOException { // TODO full implementation of CertUtil.parseGeneralName byte[] encoded = CertUtil.parseGeneralName(type, name); List tmpList = new ArrayList(); tmpList.add(Integers.valueOf(type)); tmpList.add(name); subjectAltNames.add(tmpList); tmpList.set(1, encoded); subjectAltNamesByte.add(tmpList); } /** * Adds a name to the subjectAlternativeNames criterion. The * X509Certificate must contain all or at least one of the * specified subjectAlternativeNames, depending on the value of the * matchAllNames flag (see {@link #setMatchAllSubjectAltNames}).
*
* This method allows the caller to add a name to the set of subject * alternative names. The specified name is added to any previous value for * the subjectAlternativeNames criterion. If the specified name is a * duplicate, it may be ignored.
*
* The name is provided as a byte array. This byte array should contain the * DER encoded name, as it would appear in the GeneralName structure defined * in RFC 2459 and X.509. The encoded byte array should only contain the * encoded value of the name, and should not include the tag associated with * the name in the GeneralName structure. The ASN.1 definition of this * structure appears below.
*
* *
     *    GeneralName ::= CHOICE {
     *        otherName                       [0]     OtherName,
     *        rfc822Name                      [1]     IA5String,
     *        dNSName                         [2]     IA5String,
     *        x400Address                     [3]     ORAddress,
     *        directoryName                   [4]     Name,
     *        ediPartyName                    [5]     EDIPartyName,
     *        uniformResourceIdentifier       [6]     IA5String,
     *        iPAddress                       [7]     OCTET STRING,
     *        registeredID                    [8]     OBJECT IDENTIFIER}
     * 
* *
*
* Note that the byte array supplied here is cloned to protect against * subsequent modifications.
*
* TODO: check encoded format * * @param type * the name type (0-8, as listed above) * @param name * a byte array containing the name in ASN.1 DER encoded form * * @exception IOException * if a parsing error occurs */ public void addSubjectAlternativeName(int type, byte[] name) throws IOException { // TODO check encoded format List tmpList = new ArrayList(); tmpList.add(Integers.valueOf(type)); tmpList.add(name.clone()); subjectAltNames.add(tmpList); subjectAltNamesByte.add(tmpList); } /** * Sets the name constraints criterion. The X509Certificate * must have subject and subject alternative names that meet the specified * name constraints.
*
* The name constraints are specified as a byte array. This byte array * should contain the DER encoded form of the name constraints, as they * would appear in the NameConstraints structure defined in RFC 2459 and * X.509. The ASN.1 definition of this structure appears below.
*
* *
     *   NameConstraints ::= SEQUENCE {
     *        permittedSubtrees       [0]     GeneralSubtrees OPTIONAL,
     *        excludedSubtrees        [1]     GeneralSubtrees OPTIONAL }
     * 
     *   GeneralSubtrees ::= SEQUENCE SIZE (1..MAX) OF GeneralSubtree
     * 
     *   GeneralSubtree ::= SEQUENCE {
     *        base                    GeneralName,
     *        minimum         [0]     BaseDistance DEFAULT 0,
     *        maximum         [1]     BaseDistance OPTIONAL }
     * 
     *   BaseDistance ::= INTEGER (0..MAX)
     * 
     *   GeneralName ::= CHOICE {
     *        otherName                       [0]     OtherName,
     *        rfc822Name                      [1]     IA5String,
     *        dNSName                         [2]     IA5String,
     *        x400Address                     [3]     ORAddress,
     *        directoryName                   [4]     Name,
     *        ediPartyName                    [5]     EDIPartyName,
     *        uniformResourceIdentifier       [6]     IA5String,
     *        iPAddress                       [7]     OCTET STRING,
     *        registeredID                    [8]     OBJECT IDENTIFIER}
     * 
* *
*
* Note that the byte array supplied here is cloned to protect against * subsequent modifications.
*
* TODO: implement this * * @param bytes * a byte array containing the ASN.1 DER encoding of a * NameConstraints extension to be used for checking name * constraints. Only the value of the extension is included, not * the OID or criticality flag. Can be null, in * which case no name constraints check will be performed * * @exception IOException * if a parsing error occurs * @exception UnsupportedOperationException * because this method is not supported * @see #getNameConstraints() */ public void setNameConstraints(byte[] bytes) throws IOException { throw new UnsupportedOperationException(); } /** * Sets the basic constraints constraint. If the value is greater than or * equal to zero, X509Certificates must include a * basicConstraints extension with a pathLen of at least this value. If the * value is -2, only end-entity certificates are accepted. If the value is * -1, no check is done.
*
* This constraint is useful when building a certification path forward * (from the target toward the trust anchor. If a partial path has been * built, any candidate certificate must have a maxPathLen value greater * than or equal to the number of certificates in the partial path. * * @param minMaxPathLen * the value for the basic constraints constraint * * @exception IllegalArgumentException * if the value is less than -2 * * @see #getBasicConstraints() */ public void setBasicConstraints(int minMaxPathLen) { if (minMaxPathLen < -2) { throw new IllegalArgumentException("minMaxPathLen must be >= -2"); } this.minMaxPathLen = minMaxPathLen; } /** * Sets the policy constraint. The X509Certificate must include at least one * of the specified policies in its certificate policies extension. If * certPolicySet is empty, then the X509Certificate must include at least * some specified policy in its certificate policies extension. If * certPolicySet is null, no policy check will be performed.
*
* Note that the Set is cloned to protect against subsequent modifications.
*
* TODO: implement match check for this * * @param certPolicySet * a Set of certificate policy OIDs in string format (or null). * Each OID is represented by a set of nonnegative integers * separated by periods. * * @exception IOException * if a parsing error occurs on the OID such as the first * component is not 0, 1 or 2 or the second component is * greater than 39. * * @see #getPolicy() */ public void setPolicy(Set certPolicySet) throws IOException { if (certPolicySet == null) { policy = null; policyOID = null; } else { policyOID = new HashSet(); Iterator iter = certPolicySet.iterator(); Object item; while (iter.hasNext()) { item = iter.next(); if (item instanceof String) { CertUtil.parseOID((String)item); policyOID.add(new ASN1ObjectIdentifier((String)item)); } else { throw new IOException( "certPolicySet contains null values or non String objects"); } } policy = new HashSet(certPolicySet); } } /** * Sets the pathToNames criterion. The X509Certificate must * not include name constraints that would prohibit building a path to the * specified names.
*
* This method allows the caller to specify, with a single method call, the * complete set of names which the X509Certificates's name * constraints must permit. The specified value replaces the previous value * for the pathToNames criterion.
*
* This constraint is useful when building a certification path forward * (from the target toward the trust anchor. If a partial path has been * built, any candidate certificate must not include name constraints that * would prohibit building a path to any of the names in the partial path.
*
* The names parameter (if not null) is a * Collection with one entry for each name to be included in * the pathToNames criterion. Each entry is a List whose * first entry is an Integer (the name type, 0-8) and whose second entry is * a String or a byte array (the name, in string or ASN.1 DER * encoded form, respectively). There can be multiple names of the same * type. If null is supplied as the value for this argument, * no pathToNames check will be performed.
*
* Each name in the Collection may be specified either as a String or as an * ASN.1 encoded byte array. For more details about the formats used, see * {@link #addPathToName(int, String) addPathToName(int type, String name)} * and * {@link #addPathToName(int, byte[]) addPathToName(int type, byte [] name)}.
*
* Note that the names parameter can contain duplicate names (same name and * name type), but they may be removed from the Collection of names returned * by the {@link #getPathToNames} method.
*
* Note that a deep copy is performed on the Collection to protect against * subsequent modifications.
*
* TODO: implement this match check for this * * @param names * a Collection with one entry per name (or null) * * @exception IOException * if a parsing error occurs * @exception UnsupportedOperationException * because this method is not supported * * @see #getPathToNames() */ public void setPathToNames(Collection names) throws IOException { try { if (names == null || names.isEmpty()) { pathToNames = null; pathToNamesByte = null; } else { pathToNames = new HashSet(); pathToNamesByte = new HashSet(); Iterator iter = names.iterator(); List item; int type; Object data; while (iter.hasNext()) { item = (List)iter.next(); type = ((Integer)item.get(0)).intValue(); data = item.get(1); if (data instanceof String) { addPathToName(type, (String)data); } else if (data instanceof byte[]) { addPathToName(type, (byte[])data); } else { throw new IOException( "parsing error: unknown data type"); } } } } catch (Exception ex) { throw new IOException("parsing exception:\n" + ex.toString()); } } /** * Adds a name to the pathToNames criterion. The * X509Certificate must not include name constraints that * would prohibit building a path to the specified name.
*
* This method allows the caller to add a name to the set of names which the * X509Certificates's name constraints must permit. The * specified name is added to any previous value for the pathToNames * criterion. If the name is a duplicate, it may be ignored.
*
* The name is provided in string format. RFC 822, DNS, and URI names use * the well-established string formats for those types (subject to the * restrictions included in RFC 2459). IPv4 address names are supplied using * dotted quad notation. OID address names are represented as a series of * nonnegative integers separated by periods. And directory names * (distinguished names) are supplied in RFC 2253 format. No standard string * format is defined for otherNames, X.400 names, EDI party names, IPv6 * address names, or any other type of names. They should be specified using * the * {@link #addPathToName(int, byte[]) addPathToName(int type, byte [] name)} * method.
*
* TODO: implement this match check for this * * @param type * the name type (0-8, as specified in RFC 2459, section 4.2.1.7) * @param name * the name in string form * * @exceptrion IOException if a parsing error occurs */ public void addPathToName(int type, String name) throws IOException { // TODO full implementation of CertUtil.parseGeneralName byte[] encoded = CertUtil.parseGeneralName(type, name); List tmpList = new ArrayList(); tmpList.add(Integers.valueOf(type)); tmpList.add(name); pathToNames.add(tmpList); tmpList.set(1, encoded); pathToNamesByte.add(tmpList); throw new UnsupportedOperationException(); } /** * Adds a name to the pathToNames criterion. The * X509Certificate must not include name constraints that * would prohibit building a path to the specified name.
*
* This method allows the caller to add a name to the set of names which the * X509Certificates's name constraints must permit. The * specified name is added to any previous value for the pathToNames * criterion. If the name is a duplicate, it may be ignored.
*
* The name is provided as a byte array. This byte array should contain the * DER encoded name, as it would appear in the GeneralName structure defined * in RFC 2459 and X.509. The ASN.1 definition of this structure appears in * the documentation for * {@link #addSubjectAlternativeName(int,byte[]) addSubjectAlternativeName(int type, byte[] name)}.
*
* Note that the byte array supplied here is cloned to protect against * subsequent modifications.
*
* TODO: implement this match check for this * * @param type * the name type (0-8, as specified in RFC 2459, section 4.2.1.7) * @param name * a byte array containing the name in ASN.1 DER encoded form * * @exception IOException * if a parsing error occurs */ public void addPathToName(int type, byte[] name) throws IOException { // TODO check encoded format List tmpList = new ArrayList(); tmpList.add(Integers.valueOf(type)); tmpList.add(name.clone()); pathToNames.add(tmpList); pathToNamesByte.add(tmpList); } /** * Returns the certificateEquals criterion. The specified * X509Certificate must be equal to the * X509Certificate passed to the match method. If * null, this check is not applied. * * @retrun the X509Certificate to match (or null) * * @see #setCertificate(java.security.cert.X509Certificate) */ public X509Certificate getCertificate() { return x509Cert; } /** * Returns the serialNumber criterion. The specified serial number must * match the certificate serial number in the X509Certificate. * If null, any certificate serial number will do. * * @return the certificate serial number to match (or null) * * @see #setSerialNumber(java.math.BigInteger) */ public BigInteger getSerialNumber() { return serialNumber; } /** * Returns the issuer criterion as a String. This distinguished name must * match the issuer distinguished name in the X509Certificate. * If null, the issuer criterion is disabled and any issuer * distinguished name will do.
*
* If the value returned is not null, it is a distinguished * name, in RFC 2253 format.
*
* Uses {@link org.bouncycastle.asn1.x509.X509Name X509Name} for formatiing * byte[] issuerDN to String. * * @return the required issuer distinguished name in RFC 2253 format (or * null) */ public String getIssuerAsString() { if (issuerDN instanceof String) { return new String((String)issuerDN); } else if (issuerDNX509 != null) { return issuerDNX509.toString(); } return null; } /** * Returns the issuer criterion as a byte array. This distinguished name * must match the issuer distinguished name in the * X509Certificate. If null, the issuer * criterion is disabled and any issuer distinguished name will do.
*
* If the value returned is not null, it is a byte array * containing a single DER encoded distinguished name, as defined in X.501. * The ASN.1 notation for this structure is supplied in the documentation * for {@link #setIssuer(byte[]) setIssuer(byte [] issuerDN)}.
*
* Note that the byte array returned is cloned to protect against subsequent * modifications.
*
* Uses {@link org.bouncycastle.asn1.DEROutputStream DEROutputStream}, * {@link org.bouncycastle.asn1.x509.X509Name X509Name} to gnerate byte[] * output for String issuerDN. * * @return a byte array containing the required issuer distinguished name in * ASN.1 DER format (or null) * * @exception IOException * if an encoding error occurs */ public byte[] getIssuerAsBytes() throws IOException { if (issuerDN instanceof byte[]) { return (byte[])((byte[])issuerDN).clone(); } else if (issuerDNX509 != null) { ByteArrayOutputStream outStream = new ByteArrayOutputStream(); DEROutputStream derOutStream = new DEROutputStream(outStream); derOutStream.writeObject(issuerDNX509.toASN1Primitive()); derOutStream.close(); return outStream.toByteArray(); } return null; } /** * Returns the subject criterion as a String. This distinguished name must * match the subject distinguished name in the X509Certificate. * If null, the subject criterion is disabled and any * subject distinguished name will do.
*
* If the value returned is not null, it is a distinguished * name, in RFC 2253 format.
*
* Uses {@link org.bouncycastle.asn1.x509.X509Name X509Name} for formatiing * byte[] subjectDN to String. * * @return the required subject distinguished name in RFC 2253 format (or * null) */ public String getSubjectAsString() { if (subjectDN instanceof String) { return new String((String)subjectDN); } else if (subjectDNX509 != null) { return subjectDNX509.toString(); } return null; } /** * Returns the subject criterion as a byte array. This distinguished name * must match the subject distinguished name in the * X509Certificate. If null, the subject * criterion is disabled and any subject distinguished name will do.
*
* If the value returned is not null, it is a byte array * containing a single DER encoded distinguished name, as defined in X.501. * The ASN.1 notation for this structure is supplied in the documentation * for {@link #setSubject(byte [] subjectDN) setSubject(byte [] subjectDN)}.
*
* Note that the byte array returned is cloned to protect against subsequent * modifications.
*
* Uses {@link org.bouncycastle.asn1.DEROutputStream DEROutputStream}, * {@link org.bouncycastle.asn1.x509.X509Name X509Name} to gnerate byte[] * output for String subjectDN. * * @return a byte array containing the required subject distinguished name * in ASN.1 DER format (or null) * * @exception IOException * if an encoding error occurs */ public byte[] getSubjectAsBytes() throws IOException { if (subjectDN instanceof byte[]) { return (byte[])((byte[])subjectDN).clone(); } else if (subjectDNX509 != null) { ByteArrayOutputStream outStream = new ByteArrayOutputStream(); DEROutputStream derOutStream = new DEROutputStream(outStream); derOutStream.writeObject(subjectDNX509.toASN1Primitive()); derOutStream.close(); return outStream.toByteArray(); } return null; } /** * Returns the subjectKeyIdentifier criterion. The * X509Certificate must contain a SubjectKeyIdentifier * extension with the specified value. If null, no * subjectKeyIdentifier check will be done.
*
* Note that the byte array returned is cloned to protect against subsequent * modifications. * * @return the key identifier (or null) * * @see #setSubjectKeyIdentifier */ public byte[] getSubjectKeyIdentifier() { if (subjectKeyID != null) { return (byte[])subjectKeyID.clone(); } return null; } /** * Returns the authorityKeyIdentifier criterion. The * X509Certificate must contain a AuthorityKeyIdentifier * extension with the specified value. If null, no * authorityKeyIdentifier check will be done.
*
* Note that the byte array returned is cloned to protect against subsequent * modifications. * * @return the key identifier (or null) * * @see #setAuthorityKeyIdentifier */ public byte[] getAuthorityKeyIdentifier() { if (authorityKeyID != null) { return (byte[])authorityKeyID.clone(); } return null; } /** * Returns the certificateValid criterion. The specified date must fall * within the certificate validity period for the * X509Certificate. If null, no * certificateValid check will be done.
*
* Note that the Date returned is cloned to protect against * subsequent modifications. * * @return the Date to check (or null) * * @see #setCertificateValid */ public Date getCertificateValid() { if (certValid != null) { return new Date(certValid.getTime()); } return null; } /** * Returns the privateKeyValid criterion. The specified date must fall * within the private key validity period for the * X509Certificate. If null, no * privateKeyValid check will be done.
*
* Note that the Date returned is cloned to protect against * subsequent modifications. * * @return the Date to check (or null) * * @see #setPrivateKeyValid */ public Date getPrivateKeyValid() { if (privateKeyValid != null) { return new Date(privateKeyValid.getTime()); } return null; } /** * Returns the subjectPublicKeyAlgID criterion. The * X509Certificate must contain a subject public key with the * specified algorithm. If null, no subjectPublicKeyAlgID * check will be done. * * @return the object identifier (OID) of the signature algorithm to check * for (or null). An OID is represented by a set of * nonnegative integers separated by periods. * * @see #setSubjectPublicKeyAlgID */ public String getSubjectPublicKeyAlgID() { if (subjectKeyAlgID != null) { return subjectKeyAlgID.toString(); } return null; } /** * Returns the subjectPublicKey criterion. The X509Certificate * must contain the specified subject public key. If null, * no subjectPublicKey check will be done. * * @return the subject public key to check for (or null) * * @see #setSubjectPublicKey */ public PublicKey getSubjectPublicKey() { return subjectPublicKey; } /** * Returns the keyUsage criterion. The X509Certificate must * allow the specified keyUsage values. If null, no keyUsage check will be * done.
*
* Note that the boolean array returned is cloned to protect against * subsequent modifications. * * @return a boolean array in the same format as the boolean array returned * by * {@link X509Certificate#getKeyUsage() X509Certificate.getKeyUsage()}. * Or null. * * @see #setKeyUsage */ public boolean[] getKeyUsage() { if (keyUsage != null) { return (boolean[])keyUsage.clone(); } return null; } /** * Returns the extendedKeyUsage criterion. The X509Certificate * must allow the specified key purposes in its extended key usage * extension. If the keyPurposeSet returned is empty or * null, no extendedKeyUsage check will be done. Note that * an X509Certificate that has no extendedKeyUsage extension * implicitly allows all key purposes. * * @return an immutable Set of key purpose OIDs in string * format (or null) * @see #setExtendedKeyUsage */ public Set getExtendedKeyUsage() { if (keyPurposeSet == null || keyPurposeSet.isEmpty()) { return keyPurposeSet; } Set returnSet = new HashSet(); Iterator iter = keyPurposeSet.iterator(); while (iter.hasNext()) { returnSet.add(iter.next().toString()); } return Collections.unmodifiableSet(returnSet); } /** * Indicates if the X509Certificate must contain all or at * least one of the subjectAlternativeNames specified in the * {@link #setSubjectAlternativeNames setSubjectAlternativeNames} or * {@link #addSubjectAlternativeName addSubjectAlternativeName} methods. If * true, the X509Certificate must contain all * of the specified subject alternative names. If false, the * X509Certificate must contain at least one of the specified * subject alternative names. * * @return true if the flag is enabled; false * if the flag is disabled. The flag is true by * default. * * @see #setMatchAllSubjectAltNames */ public boolean getMatchAllSubjectAltNames() { return matchAllSubjectAltNames; } /** * Returns a copy of the subjectAlternativeNames criterion. The * X509Certificate must contain all or at least one of the * specified subjectAlternativeNames, depending on the value of the * matchAllNames flag (see {@link #getMatchAllSubjectAltNames * getMatchAllSubjectAltNames}). If the value returned is null, * no subjectAlternativeNames check will be performed.
*
* If the value returned is not null, it is a * Collection with one entry for each name to be included in * the subject alternative name criterion. Each entry is a List * whose first entry is an Integer (the name type, 0-8) and * whose second entry is a String or a byte array (the name, * in string or ASN.1 DER encoded form, respectively). There can be multiple * names of the same type. Note that the Collection returned * may contain duplicate names (same name and name type).
*
* Each subject alternative name in the Collection may be * specified either as a String or as an ASN.1 encoded byte * array. For more details about the formats used, see * {@link #addSubjectAlternativeName(int type, String name) * addSubjectAlternativeName(int type, String name)} and * {@link #addSubjectAlternativeName(int type, byte [] name) * addSubjectAlternativeName(int type, byte [] name)}.
*
* Note that a deep copy is performed on the Collection to * protect against subsequent modifications. * * @return a Collection of names (or null) * * @see #setSubjectAlternativeNames */ public Collection getSubjectAlternativeNames() { if (subjectAltNames != null) { return null; } Set returnAltNames = new HashSet(); List returnList; Iterator iter = subjectAltNames.iterator(); List obj; while (iter.hasNext()) { obj = (List)iter.next(); returnList = new ArrayList(); returnList.add(obj.get(0)); if (obj.get(1) instanceof byte[]) { returnList.add(((byte[])obj.get(1)).clone()); } else { returnList.add(obj.get(1)); } returnAltNames.add(returnList); } return returnAltNames; } /** * Returns the name constraints criterion. The X509Certificate * must have subject and subject alternative names that meet the specified * name constraints.
*
* The name constraints are returned as a byte array. This byte array * contains the DER encoded form of the name constraints, as they would * appear in the NameConstraints structure defined in RFC 2459 and X.509. * The ASN.1 notation for this structure is supplied in the documentation * for * {@link #setNameConstraints(byte [] bytes) setNameConstraints(byte [] bytes)}.
*
* Note that the byte array returned is cloned to protect against subsequent * modifications.
*
* TODO: implement this * * @return a byte array containing the ASN.1 DER encoding of a * NameConstraints extension used for checking name constraints. * null if no name constraints check will be * performed. * * @exception UnsupportedOperationException * because this method is not supported * * @see #setNameConstraints */ public byte[] getNameConstraints() { throw new UnsupportedOperationException(); } /** * Returns the basic constraints constraint. If the value is greater than or * equal to zero, the X509Certificates must include a * basicConstraints extension with a pathLen of at least this value. If the * value is -2, only end-entity certificates are accepted. If the value is * -1, no basicConstraints check is done. * * @return the value for the basic constraints constraint * * @see #setBasicConstraints */ public int getBasicConstraints() { return minMaxPathLen; } /** * Returns the policy criterion. The X509Certificate must * include at least one of the specified policies in its certificate * policies extension. If the Set returned is empty, then the * X509Certificate must include at least some specified * policy in its certificate policies extension. If the Set * returned is null, no policy check will be performed. * * @return an immutable Set of certificate policy OIDs in * string format (or null) * * @see #setPolicy */ public Set getPolicy() { if (policy == null) { return null; } return Collections.unmodifiableSet(policy); } /** * Returns a copy of the pathToNames criterion. The * X509Certificate must not include name constraints that * would prohibit building a path to the specified names. If the value * returned is null, no pathToNames check will be performed.
*
* If the value returned is not null, it is a * Collection with one entry for each name to be included in * the pathToNames criterion. Each entry is a List whose * first entry is an Integer (the name type, 0-8) and whose * second entry is a String or a byte array (the name, in * string or ASN.1 DER encoded form, respectively). There can be multiple * names of the same type. Note that the Collection returned * may contain duplicate names (same name and name type).
*
* Each name in the Collection may be specified either as a * String or as an ASN.1 encoded byte array. For more details * about the formats used, see {@link #addPathToName(int type, String name) * addPathToName(int type, String name)} and * {@link #addPathToName(int type, byte [] name) addPathToName(int type, * byte [] name)}.
*
* Note that a deep copy is performed on the Collection to * protect against subsequent modifications. * * @return a Collection of names (or null) * * @see #setPathToNames */ public Collection getPathToNames() { if (pathToNames == null) { return null; } Set returnPathToNames = new HashSet(); List returnList; Iterator iter = pathToNames.iterator(); List obj; while (iter.hasNext()) { obj = (List)iter.next(); returnList = new ArrayList(); returnList.add(obj.get(0)); if (obj.get(1) instanceof byte[]) { returnList.add(((byte[])obj.get(1)).clone()); } else { returnList.add(obj.get(1)); } returnPathToNames.add(returnList); } return returnPathToNames; } /** * Return a printable representation of the CertSelector.
*
* TODO: implement output for currently unsupported options(name * constraints)
*
* Uses {@link org.bouncycastle.asn1.ASN1InputStream ASN1InputStream}, * {@link org.bouncycastle.asn1.ASN1Object ASN1Object}, * {@link org.bouncycastle.asn1.x509.KeyPurposeId KeyPurposeId} * * @return a String describing the contents of the * CertSelector */ public String toString() { StringBuffer sb = new StringBuffer(); sb.append("X509CertSelector: [\n"); if (x509Cert != null) { sb.append(" Certificate: ").append(x509Cert).append('\n'); } if (serialNumber != null) { sb.append(" Serial Number: ").append(serialNumber).append('\n'); } if (issuerDN != null) { sb.append(" Issuer: ").append(getIssuerAsString()).append('\n'); } if (subjectDN != null) { sb.append(" Subject: ").append(getSubjectAsString()).append('\n'); } try { if (subjectKeyID != null) { ByteArrayInputStream inStream = new ByteArrayInputStream( subjectKeyID); ASN1InputStream derInStream = new ASN1InputStream(inStream); ASN1Object derObject = derInStream.readObject(); sb.append(" Subject Key Identifier: ") .append(ASN1Dump.dumpAsString(derObject)).append('\n'); } if (authorityKeyID != null) { ByteArrayInputStream inStream = new ByteArrayInputStream( authorityKeyID); ASN1InputStream derInStream = new ASN1InputStream(inStream); ASN1Object derObject = derInStream.readObject(); sb.append(" Authority Key Identifier: ") .append(ASN1Dump.dumpAsString(derObject)).append('\n'); } } catch (IOException ex) { sb.append(ex.getMessage()).append('\n'); } if (certValid != null) { sb.append(" Certificate Valid: ").append(certValid).append('\n'); } if (privateKeyValid != null) { sb.append(" Private Key Valid: ").append(privateKeyValid) .append('\n'); } if (subjectKeyAlgID != null) { sb.append(" Subject Public Key AlgID: ") .append(subjectKeyAlgID).append('\n'); } if (subjectPublicKey != null) { sb.append(" Subject Public Key: ").append(subjectPublicKey) .append('\n'); } if (keyUsage != null) { sb.append(" Key Usage: ").append(keyUsage).append('\n'); } if (keyPurposeSet != null) { sb.append(" Extended Key Usage: ").append(keyPurposeSet) .append('\n'); } if (policy != null) { sb.append(" Policy: ").append(policy).append('\n'); } sb.append(" matchAllSubjectAltNames flag: ") .append(matchAllSubjectAltNames).append('\n'); if (subjectAltNamesByte != null) { sb.append(" SubjectAlternativNames: \n["); Iterator iter = subjectAltNamesByte.iterator(); List obj; try { while (iter.hasNext()) { obj = (List)iter.next(); ByteArrayInputStream inStream = new ByteArrayInputStream( (byte[])obj.get(1)); ASN1InputStream derInStream = new ASN1InputStream(inStream); ASN1Object derObject = derInStream.readObject(); sb.append(" Type: ").append(obj.get(0)).append(" Data: ") .append(ASN1Dump.dumpAsString(derObject)).append('\n'); } } catch (IOException ex) { sb.append(ex.getMessage()).append('\n'); } sb.append("]\n"); } if (pathToNamesByte != null) { sb.append(" PathToNamesNames: \n["); Iterator iter = pathToNamesByte.iterator(); List obj; try { while (iter.hasNext()) { obj = (List)iter.next(); ByteArrayInputStream inStream = new ByteArrayInputStream( (byte[])obj.get(1)); ASN1InputStream derInStream = new ASN1InputStream(inStream); ASN1Object derObject = derInStream.readObject(); sb.append(" Type: ").append(obj.get(0)).append(" Data: ") .append(ASN1Dump.dumpAsString(derObject)).append('\n'); } } catch (IOException ex) { sb.append(ex.getMessage()).append('\n'); } sb.append("]\n"); } sb.append(']'); return sb.toString(); } /** * Decides whether a Certificate should be selected.
*
* TODO: implement missing tests (name constraints and path to names)
*
* Uses {@link org.bouncycastle.asn1.ASN1InputStream ASN1InputStream}, * {@link org.bouncycastle.asn1.ASN1Sequence ASN1Sequence}, * {@link org.bouncycastle.asn1.ASN1ObjectIdentifier ASN1ObjectIdentifier}, * {@link org.bouncycastle.asn1.ASN1Object ASN1Object}, * {@link org.bouncycastle.asn1.DERGeneralizedTime DERGeneralizedTime}, * {@link org.bouncycastle.asn1.x509.X509Name X509Name}, * {@link org.bouncycastle.asn1.x509.X509Extensions X509Extensions}, * {@link org.bouncycastle.asn1.x509.ExtendedKeyUsage ExtendedKeyUsage}, * {@link org.bouncycastle.asn1.x509.KeyPurposeId KeyPurposeId}, * {@link org.bouncycastle.asn1.x509.SubjectPublicKeyInfo SubjectPublicKeyInfo}, * {@link org.bouncycastle.asn1.x509.AlgorithmIdentifier AlgorithmIdentifier} * to access X509 extensions * * @param cert * the Certificate to be checked * * @return true if the Certificate should be * selected, false otherwise */ public boolean match(Certificate cert) { boolean[] booleanArray; List tempList; Iterator tempIter; if (!(cert instanceof X509Certificate)) { return false; } X509Certificate certX509 = (X509Certificate)cert; if (x509Cert != null && !x509Cert.equals(certX509)) { return false; } if (serialNumber != null && !serialNumber.equals(certX509.getSerialNumber())) { return false; } try { if (issuerDNX509 != null) { if (!issuerDNX509.equals(PrincipalUtil .getIssuerX509Principal(certX509), true)) { return false; } } if (subjectDNX509 != null) { if (!subjectDNX509.equals(PrincipalUtil .getSubjectX509Principal(certX509), true)) { return false; } } } catch (Exception ex) { return false; } if (subjectKeyID != null) { byte[] data = certX509 .getExtensionValue(X509Extensions.SubjectKeyIdentifier .getId()); if (data == null) { return false; } try { ByteArrayInputStream inStream = new ByteArrayInputStream(data); ASN1InputStream derInputStream = new ASN1InputStream(inStream); byte[] testData = ((ASN1OctetString)derInputStream.readObject()) .getOctets(); if (!Arrays.equals(subjectKeyID, testData)) { return false; } } catch (IOException ex) { return false; } } if (authorityKeyID != null) { byte[] data = certX509 .getExtensionValue(X509Extensions.AuthorityKeyIdentifier .getId()); if (data == null) { return false; } try { ByteArrayInputStream inStream = new ByteArrayInputStream(data); ASN1InputStream derInputStream = new ASN1InputStream(inStream); byte[] testData = ((ASN1OctetString)derInputStream.readObject()) .getOctets(); if (!Arrays.equals(authorityKeyID, testData)) { return false; } } catch (IOException ex) { return false; } } if (certValid != null) { if (certX509.getNotAfter() != null && certValid.after(certX509.getNotAfter())) { return false; } if (certX509.getNotBefore() != null && certValid.before(certX509.getNotBefore())) { return false; } } if (privateKeyValid != null) { try { byte[] data = certX509 .getExtensionValue(X509Extensions.PrivateKeyUsagePeriod .getId()); if (data != null) { ByteArrayInputStream inStream = new ByteArrayInputStream( data); ASN1InputStream derInputStream = new ASN1InputStream(inStream); inStream = new ByteArrayInputStream( ((ASN1OctetString)derInputStream.readObject()) .getOctets()); derInputStream = new ASN1InputStream(inStream); // TODO fix this, Sequence contains tagged objects ASN1Sequence derObject = (ASN1Sequence)derInputStream .readObject(); DERGeneralizedTime derDate = DERGeneralizedTime .getInstance(derObject.getObjectAt(0)); SimpleDateFormat dateF = new SimpleDateFormat( "yyyyMMddHHmmssZ"); if (privateKeyValid.before(dateF.parse(derDate.getTime()))) { return false; } derDate = DERGeneralizedTime.getInstance(derObject .getObjectAt(1)); if (privateKeyValid.after(dateF.parse(derDate.getTime()))) { return false; } } } catch (Exception ex) { return false; } } if (subjectKeyAlgID != null) { try { ByteArrayInputStream inStream = new ByteArrayInputStream( certX509.getPublicKey().getEncoded()); ASN1InputStream derInputStream = new ASN1InputStream(inStream); SubjectPublicKeyInfo publicKeyInfo = new SubjectPublicKeyInfo( (ASN1Sequence)derInputStream.readObject()); AlgorithmIdentifier algInfo = publicKeyInfo.getAlgorithmId(); if (!algInfo.getObjectId().equals(subjectKeyAlgID)) { return false; } } catch (Exception ex) { return false; } } if (subjectPublicKeyByte != null) { if (!Arrays.equals(subjectPublicKeyByte, certX509.getPublicKey() .getEncoded())) { return false; } } if (subjectPublicKey != null) { if (!subjectPublicKey.equals(certX509.getPublicKey())) { return false; } } if (keyUsage != null) { booleanArray = certX509.getKeyUsage(); if (booleanArray != null) { for (int i = 0; i < keyUsage.length; i++) { if (keyUsage[i] && (booleanArray.length <= i || !booleanArray[i])) { return false; } } } } if (keyPurposeSet != null && !keyPurposeSet.isEmpty()) { try { byte[] data = certX509 .getExtensionValue(X509Extensions.ExtendedKeyUsage .getId()); if (data != null) { ByteArrayInputStream inStream = new ByteArrayInputStream( data); ASN1InputStream derInputStream = new ASN1InputStream(inStream); ExtendedKeyUsage extendedKeyUsage = ExtendedKeyUsage.getInstance( derInputStream.readObject()); tempIter = keyPurposeSet.iterator(); while (tempIter.hasNext()) { if (!extendedKeyUsage .hasKeyPurposeId((KeyPurposeId)tempIter.next())) { return false; } } } } catch (Exception ex) { return false; } } if (minMaxPathLen != -1) { if (minMaxPathLen == -2 && certX509.getBasicConstraints() != -1) { return false; } if (minMaxPathLen >= 0 && certX509.getBasicConstraints() < minMaxPathLen) { return false; } } if (policyOID != null) { try { byte[] data = certX509 .getExtensionValue(X509Extensions.CertificatePolicies .getId()); if (data == null) { return false; } if (!policyOID.isEmpty()) { ByteArrayInputStream inStream = new ByteArrayInputStream( data); ASN1InputStream derInputStream = new ASN1InputStream(inStream); inStream = new ByteArrayInputStream( ((ASN1OctetString)derInputStream.readObject()) .getOctets()); derInputStream = new ASN1InputStream(inStream); Enumeration policySequence = ((ASN1Sequence)derInputStream .readObject()).getObjects(); ASN1Sequence policyObject; boolean test = false; while (policySequence.hasMoreElements() && !test) { policyObject = (ASN1Sequence)policySequence .nextElement(); if (policyOID.contains(policyObject.getObjectAt(0))) { test = true; } } if (!test) { return false; } } } catch (Exception ex) { ex.printStackTrace(); return false; } } if (subjectAltNamesByte != null) { try { byte[] data = certX509 .getExtensionValue(X509Extensions.SubjectAlternativeName .getId()); if (data == null) { return false; } ByteArrayInputStream inStream = new ByteArrayInputStream(data); ASN1InputStream derInputStream = new ASN1InputStream(inStream); inStream = new ByteArrayInputStream( ((ASN1OctetString)derInputStream.readObject()) .getOctets()); derInputStream = new ASN1InputStream(inStream); Enumeration altNamesSequence = ((ASN1Sequence)derInputStream .readObject()).getObjects(); ASN1TaggedObject altNameObject; boolean test = false; Set testSet = new HashSet(subjectAltNamesByte); List testList; ASN1Object derData; ByteArrayOutputStream outStream; DEROutputStream derOutStream; while (altNamesSequence.hasMoreElements() && !test) { altNameObject = (ASN1TaggedObject)altNamesSequence .nextElement(); testList = new ArrayList(2); testList.add(Integers.valueOf(altNameObject.getTagNo())); derData = altNameObject.getObject(); outStream = new ByteArrayOutputStream(); derOutStream = new DEROutputStream(outStream); derOutStream.writeObject(derData); derOutStream.close(); testList.add(outStream.toByteArray()); if (testSet.remove(testList)) { test = true; } if (matchAllSubjectAltNames && !testSet.isEmpty()) { test = false; } } if (!test) { return false; } } catch (Exception ex) { ex.printStackTrace(); return false; } } return true; } /** * Returns a copy of this object. * * @return the copy */ public Object clone() { try { X509CertSelector copy = (X509CertSelector)super.clone(); if (issuerDN instanceof byte[]) { copy.issuerDN = ((byte[])issuerDN).clone(); } if (subjectDN instanceof byte[]) { copy.subjectDN = ((byte[])subjectDN).clone(); } if (subjectKeyID != null) { copy.subjectKeyID = (byte[])subjectKeyID.clone(); } if (authorityKeyID != null) { copy.authorityKeyID = (byte[])authorityKeyID.clone(); } if (subjectPublicKeyByte != null) { copy.subjectPublicKeyByte = (byte[])subjectPublicKeyByte .clone(); } if (keyUsage != null) { copy.keyUsage = (boolean[])keyUsage.clone(); } if (keyPurposeSet != null) { copy.keyPurposeSet = new HashSet(keyPurposeSet); } if (policy != null) { copy.policy = new HashSet(policy); copy.policyOID = new HashSet(); Iterator iter = policyOID.iterator(); while (iter.hasNext()) { copy.policyOID.add(new ASN1ObjectIdentifier( ((ASN1ObjectIdentifier)iter.next()).getId())); } } if (subjectAltNames != null) { copy.subjectAltNames = new HashSet(getSubjectAlternativeNames()); Iterator iter = subjectAltNamesByte.iterator(); List obj; List cloneObj; while (iter.hasNext()) { obj = (List)iter.next(); cloneObj = new ArrayList(); cloneObj.add(obj.get(0)); cloneObj.add(((byte[])obj.get(1)).clone()); copy.subjectAltNamesByte.add(cloneObj); } } if (pathToNames != null) { copy.pathToNames = new HashSet(getPathToNames()); Iterator iter = pathToNamesByte.iterator(); List obj; List cloneObj; while (iter.hasNext()) { obj = (List)iter.next(); cloneObj = new ArrayList(); cloneObj.add(obj.get(0)); cloneObj.add(((byte[])obj.get(1)).clone()); copy.pathToNamesByte.add(cloneObj); } } return copy; } catch (CloneNotSupportedException e) { /* Cannot happen */ throw new InternalError(e.toString()); } } } bouncycastle-1.49.orig/jdk1.3/org/bouncycastle/jce/cert/PolicyNode.java0000644000175000017500000000777410262753174025341 0ustar ebourgebourgpackage org.bouncycastle.jce.cert; import java.util.Iterator; import java.util.Set; /** * An immutable valid policy tree node as defined by the PKIX certification * path validation algorithm.
*
* One of the outputs of the PKIX certification path validation * algorithm is a valid policy tree, which includes the policies that * were determined to be valid, how this determination was reached, * and any policy qualifiers encountered. This tree is of depth * n, where n is the length of the certification * path that has been validated.
*
* Most applications will not need to examine the valid policy tree. * They can achieve their policy processing goals by setting the * policy-related parameters in PKIXParameters. However, * the valid policy tree is available for more sophisticated applications, * especially those that process policy qualifiers.
*
* {@link PKIXCertPathValidatorResult#getPolicyTree() * PKIXCertPathValidatorResult.getPolicyTree} returns the root node of the * valid policy tree. The tree can be traversed using the * {@link #getChildren getChildren} and {@link #getParent getParent} methods. * Data about a particular node can be retrieved using other methods of * PolicyNode.
*
* Concurrent Access
*
* All PolicyNode objects must be immutable and * thread-safe. Multiple threads may concurrently invoke the methods defined * in this class on a single PolicyNode object (or more than one) * with no ill effects. This stipulation applies to all public fields and * methods of this class and any added or overridden by subclasses. **/ public interface PolicyNode { /** * Returns the parent of this node, or null if this is the * root node. * * @return the parent of this node, or null if this is the * root node */ public PolicyNode getParent(); /** * Returns an iterator over the children of this node. Any attempts to * modify the children of this node through the * Iterator's remove method must throw an * UnsupportedOperationException. * * @return an iterator over the children of this node */ public Iterator getChildren(); /** * Returns the depth of this node in the valid policy tree. * * @return the depth of this node (0 for the root node, 1 for its * children, and so on) */ public int getDepth(); /** * Returns the valid policy represented by this node. * * @return the String OID of the valid policy * represented by this node, or the special value "any-policy". For * the root node, this method always returns the special value "any-policy". */ public String getValidPolicy(); /** * Returns the set of policy qualifiers associated with the * valid policy represented by this node. * * @return an immutable Set of * PolicyQualifierInfos. For the root node, this * is always an empty Set. */ public Set getPolicyQualifiers(); /** * Returns the set of expected policies that would satisfy this * node's valid policy in the next certificate to be processed. * * @return an immutable Set of expected policy * String OIDs, or an immutable Set with * the single special value "any-policy". For the root node, this method * always returns a Set with the single value "any-policy". */ public Set getExpectedPolicies(); /** * Returns the criticality indicator of the certificate policy extension * in the most recently processed certificate. * * @return true if extension marked critical, * false otherwise. For the root node, false * is always returned. */ public boolean isCritical(); } bouncycastle-1.49.orig/jdk1.3/org/bouncycastle/jce/cert/CertPathBuilderException.java0000644000175000017500000001217110407162352030150 0ustar ebourgebourgpackage org.bouncycastle.jce.cert; import java.io.PrintStream; import java.io.PrintWriter; import java.security.GeneralSecurityException; /** * An exception indicating one of a variety of problems encountered * when building a certification path with a * CertPathBuilder.
*
* A CertPathBuilderException provides support for * wrapping exceptions. The {@link #getCause() getCause} method * returns the throwable, if any, that caused this exception to be * thrown.
*
* Concurrent Access
*
* Unless otherwise specified, the methods defined in this class are * not thread-safe. Multiple threads that need to access a single * object concurrently should synchronize amongst themselves and * provide the necessary locking. Multiple threads each manipulating * separate objects need not synchronize. * * @see CertPathBuilder **/ public class CertPathBuilderException extends GeneralSecurityException { private Throwable cause; /** * Creates a CertPathBuilderException with null * as its detail message. */ public CertPathBuilderException() { } /** * Creates a CertPathBuilderException with the given detail * message. The detail message is a String that describes * this particular exception in more detail. * * @param msg * the detail message */ public CertPathBuilderException(String message) { super(message); } /** * Creates a CertPathBuilderException that wraps the * specified throwable. This allows any exception to be converted into a * CertPathBuilderException, while retaining information * about the wrapped exception, which may be useful for debugging. The * detail message is set to * (cause==null ? null : cause.toString()) (which typically * contains the class and detail message of cause). * * @param cause * the cause (which is saved for later retrieval by the * {@link #getCause()} method). (A null value is permitted, and * indicates that the cause is nonexistent or unknown.) */ public CertPathBuilderException(String message, Throwable cause) { super(message); this.cause = cause; } /** * Creates a CertPathBuilderException with the specified * detail message and cause. * * @param msg * the detail message * @param cause * the cause (which is saved for later retrieval by the * {@link #getCause()} method). (A null value is permitted, and * indicates that the cause is nonexistent or unknown.) */ public CertPathBuilderException(Throwable cause) { this.cause = cause; } /** * Returns the internal (wrapped) cause, or null if the cause is nonexistent * or unknown. * * @return the cause of this throwable or null if the cause * is nonexistent or unknown. */ public Throwable getCause() { return cause; } /** * Returns the detail message for this CertPathBuilderException. * * @return the detail message, or null if neither the message * nor internal cause were specified */ public String getMessage() { String message = super.getMessage(); if (message == null && cause == null) { return null; } if (cause != null) { return cause.getMessage(); } return message; } /** * Returns a string describing this exception, including a description of * the internal (wrapped) cause if there is one. * * @return a string representation of this * CertPathBuilderException */ public String toString() { String message = getMessage(); if (message == null) { return ""; } return message; } /** * Prints a stack trace to System.err, including the * backtrace of the cause, if any. */ public void printStackTrace() { printStackTrace(System.err); } /** * Prints a stack trace to a PrintStream, including the * backtrace of the cause, if any. * * @param ps * the PrintStream to use for output */ public void printStackTrace(PrintStream ps) { super.printStackTrace(ps); if (getCause() != null) { getCause().printStackTrace(ps); } } /** * Prints a stack trace to a PrintWriter, including the * backtrace of the cause, if any. * * @param ps * the PrintWriter to use for output */ public void printStackTrace(PrintWriter pw) { super.printStackTrace(pw); if (getCause() != null) { getCause().printStackTrace(pw); } } } bouncycastle-1.49.orig/jdk1.3/org/bouncycastle/jce/cert/PKIXCertPathChecker.java0000644000175000017500000001636410331052734026751 0ustar ebourgebourgpackage org.bouncycastle.jce.cert; import java.security.cert.Certificate; import java.util.Collection; import java.util.Set; /** * An abstract class that performs one or more checks on an * X509Certificate.
*
* A concrete implementation of the PKIXCertPathChecker class * can be created to extend the PKIX certification path validation algorithm. * For example, an implementation may check for and process a critical private * extension of each certificate in a certification path.
*
* Instances of PKIXCertPathChecker are passed as parameters * using the {@link PKIXParameters#setCertPathCheckers setCertPathCheckers} * or {@link PKIXParameters#addCertPathChecker addCertPathChecker} methods * of the PKIXParameters and PKIXBuilderParameters * class. Each of the PKIXCertPathCheckers {@link #check check} * methods will be called, in turn, for each certificate processed by a PKIX * CertPathValidator or CertPathBuilder * implementation.
*
* A PKIXCertPathChecker may be called multiple times on * successive certificates in a certification path. Concrete subclasses * are expected to maintain any internal state that may be necessary to * check successive certificates. The {@link #init init} method is used * to initialize the internal state of the checker so that the certificates * of a new certification path may be checked. A stateful implementation * must override the {@link #clone clone} method if necessary in * order to allow a PKIX CertPathBuilder to efficiently * backtrack and try other paths. In these situations, the * CertPathBuilder is able to restore prior path validation * states by restoring the cloned PKIXCertPathCheckers.
*
* The order in which the certificates are presented to the * PKIXCertPathChecker may be either in the forward direction * (from target to most-trusted CA) or in the reverse direction (from * most-trusted CA to target). A PKIXCertPathChecker implementation * must support reverse checking (the ability to perform its checks when * it is presented with certificates in the reverse direction) and may * support forward checking (the ability to perform its checks when it is * presented with certificates in the forward direction). The * {@link #isForwardCheckingSupported isForwardCheckingSupported} method * indicates whether forward checking is supported.
*
* Additional input parameters required for executing the check may be * specified through constructors of concrete implementations of this class.
*
* Concurrent Access
*
* Unless otherwise specified, the methods defined in this class are not * thread-safe. Multiple threads that need to access a single * object concurrently should synchronize amongst themselves and * provide the necessary locking. Multiple threads each manipulating * separate objects need not synchronize. * * @see PKIXParameters * @see PKIXBuilderParameters **/ public abstract class PKIXCertPathChecker implements Cloneable { /** * Default constructor. */ protected PKIXCertPathChecker() { } /** * Initializes the internal state of this PKIXCertPathChecker. *

* The forward flag specifies the order that certificates * will be passed to the {@link #check check} method (forward or reverse). A * PKIXCertPathChecker must support reverse checking * and may support forward checking. * * @param forward * the order that certificates are presented to the * check method. If true, * certificates are presented from target to most-trusted CA * (forward); if false, from most-trusted CA to * target (reverse). * @exception CertPathValidatorException * if this PKIXCertPathChecker is unable to * check certificates in the specified order; it should never * be thrown if the forward flag is false since reverse * checking must be supported */ public abstract void init(boolean forward) throws CertPathValidatorException; /** * Indicates if forward checking is supported. Forward checking refers to * the ability of the PKIXCertPathChecker to perform its * checks when certificates are presented to the check method * in the forward direction (from target to most-trusted CA). * * @return true if forward checking is supported, * false otherwise */ public abstract boolean isForwardCheckingSupported(); /** * Returns an immutable Set of X.509 certificate extensions * that this PKIXCertPathChecker supports (i.e. recognizes, * is able to process), or null if no extensions are * supported. *

* Each element of the set is a String representing the * Object Identifier (OID) of the X.509 extension that is supported. The OID * is represented by a set of nonnegative integers separated by periods. *

* All X.509 certificate extensions that a PKIXCertPathChecker * might possibly be able to process should be included in the set. * * @return an immutable Set of X.509 extension OIDs (in * String format) supported by this * PKIXCertPathChecker, or null if no * extensions are supported */ public abstract Set getSupportedExtensions(); /** * Performs the check(s) on the specified certificate using its internal * state and removes any critical extensions that it processes from the * specified collection of OID strings that represent the unresolved * critical extensions. The certificates are presented in the order * specified by the init method. * * @param cert * the Certificate to be checked * @param unresolvedCritExts * a Collection of OID strings representing the * current set of unresolved critical extensions * @exception CertPathValidatorException * if the specified certificate does not pass the check */ public abstract void check(Certificate cert, Collection unresolvedCritExts) throws CertPathValidatorException; /** * Returns a clone of this object. Calls the Object.clone() * method. All subclasses which maintain state must support and override * this method, if necessary. * * @return a copy of this PKIXCertPathChecker */ public Object clone() { try { return super.clone(); } catch (CloneNotSupportedException ex) { /* Cannot happen */ throw new InternalError(ex.toString()); } } } bouncycastle-1.49.orig/jdk1.3/org/bouncycastle/jce/cert/CertStoreParameters.java0000644000175000017500000000507510262753174027222 0ustar ebourgebourgpackage org.bouncycastle.jce.cert; /** * A specification of CertStore parameters.
*
* The purpose of this interface is to group (and provide type safety for) * all CertStore parameter specifications. All * CertStore parameter specifications must implement this * interface.
*
* Typically, a CertStoreParameters object is passed as a parameter * to one of the {@link CertStore#getInstance CertStore.getInstance} methods. * The getInstance method returns a CertStore that * is used for retrieving Certificates and CRLs. The * CertStore that is returned is initialized with the specified * parameters. The type of parameters needed may vary between different types * of CertStores. * * @see CertStore#getInstance **/ public interface CertStoreParameters extends Cloneable { /** * Makes a copy of this CertStoreParameters.
*
* The precise meaning of "copy" may depend on the class of * the CertStoreParameters object. A typical implementation * performs a "deep copy" of this object, but this is not an absolute * requirement. Some implementations may perform a "shallow copy" of some * or all of the fields of this object.
*
* Note that the CertStore.getInstance methods make a copy * of the specified CertStoreParameters. A deep copy * implementation of clone is safer and more robust, as it * prevents the caller from corrupting a shared CertStore by * subsequently modifying the contents of its initialization parameters. * However, a shallow copy implementation of clone is more * appropriate for applications that need to hold a reference to a * parameter contained in the CertStoreParameters. For example, * a shallow copy clone allows an application to release the resources of * a particular CertStore initialization parameter immediately, * rather than waiting for the garbage collection mechanism. This should * be done with the utmost care, since the CertStore may still * be in use by other threads.
*
* Each subclass should state the precise behavior of this method so * that users and developers know what to expect. * * @return a copy of this CertStoreParameters */ public Object clone(); } bouncycastle-1.49.orig/jdk1.3/org/bouncycastle/jce/cert/CollectionCertStoreParameters.java0000644000175000017500000001040510331052734031216 0ustar ebourgebourgpackage org.bouncycastle.jce.cert; import java.util.ArrayList; import java.util.Collection; /** * Parameters used as input for the Collection CertStore * algorithm.
*
* This class is used to provide necessary configuration parameters * to implementations of the Collection CertStore * algorithm. The only parameter included in this class is the * Collection from which the CertStore will * retrieve certificates and CRLs.
*
* Concurrent Access
*
* Unless otherwise specified, the methods defined in this class are not * thread-safe. Multiple threads that need to access a single * object concurrently should synchronize amongst themselves and * provide the necessary locking. Multiple threads each manipulating * separate objects need not synchronize. * * @see java.util.Collection * @see CertStore **/ public class CollectionCertStoreParameters implements CertStoreParameters { private Collection collection; /** * Creates an instance of CollectionCertStoreParameters which * will allow certificates and CRLs to be retrieved from the specified * Collection. If the specified Collection * contains an object that is not a Certificate or * CRL, that object will be ignored by the Collection * CertStore.
*
* The Collection is not copied. Instead, a reference * is used. This allows the caller to subsequently add or remove * Certificates or CRLs from the * Collection, thus changing the set of * Certificates or CRLs available to the * Collection CertStore. The Collection * CertStore will not modify the contents of the * Collection.
*
* If the Collection will be modified by one thread while * another thread is calling a method of a Collection CertStore * that has been initialized with this Collection, the * Collection must have fail-fast iterators. * * @param collection * a Collection of Certificates * and CRLs * * @exception NullPointerException * if collection is null */ public CollectionCertStoreParameters(Collection collection) { if (collection == null) { throw new NullPointerException("collection must be non-null"); } this.collection = collection; } /** * Creates an instance of CollectionCertStoreParameters with * the an empty Collection. */ public CollectionCertStoreParameters() { collection = new ArrayList(); } /** * Returns the Collection from which Certificates * and CRLs are retrieved. This is not a copy of the * Collection, it is a reference. This allows the caller to * subsequently add or remove Certificates or * CRLs from the Collection. * * @return the Collection (never null) */ public Collection getCollection() { return collection; } /** * Returns a copy of this object. Note that only a reference to the * Collection is copied, and not the contents. * * @return the copy */ public Object clone() { try { return super.clone(); } catch (CloneNotSupportedException e) { /* Cannot happen */ throw new InternalError(e.toString()); } } /** * Returns a formatted string describing the parameters. * * @return a formatted string describing the parameters */ public String toString() { StringBuffer s = new StringBuffer(); s.append("CollectionCertStoreParameters: [\n collections:\n"); s.append(getCollection()); s.append("\n]"); return s.toString(); } } bouncycastle-1.49.orig/jdk1.3/org/bouncycastle/jce/cert/TrustAnchor.java0000644000175000017500000002621211701477362025535 0ustar ebourgebourgpackage org.bouncycastle.jce.cert; import java.io.ByteArrayInputStream; import java.io.IOException; import java.security.PublicKey; import java.security.cert.X509Certificate; import org.bouncycastle.asn1.ASN1InputStream; import org.bouncycastle.asn1.ASN1Object; import org.bouncycastle.asn1.ASN1Sequence; /** * A trust anchor or most-trusted Certification Authority (CA).
*
* This class represents a "most-trusted CA", which is used as a trust anchor * for validating X.509 certification paths. A most-trusted CA includes the * public key of the CA, the CA's name, and any constraints upon the set of * paths which may be validated using this key. These parameters can be * specified in the form of a trusted X509Certificate or as individual * parameters.
*
* Concurrent Access
*
* All TrustAnchor objects must be immutable and thread-safe. That is, multiple * threads may concurrently invoke the methods defined in this class on a * single TrustAnchor object (or more than one) with no ill effects. Requiring * TrustAnchor objects to be immutable and thread-safe allows them to be passed * around to various pieces of code without worrying about coordinating access. * This stipulation applies to all public fields and methods of this class and * any added or overridden by subclasses.
*
* TODO: implement better nameConstraints testing. **/ public class TrustAnchor { private X509Certificate trustCert = null; private PublicKey trustPublicKey = null; private String trustName = null; private byte[] nameConstraints = null; /** * Creates an instance of TrustAnchor with the specified X509Certificate and * optional name constraints, which are intended to be used as additional * constraints when validating an X.509 certification path.
*
* The name constraints are specified as a byte array. This byte array * should contain the DER encoded form of the name constraints, as they * would appear in the NameConstraints structure defined in RFC 2459 and * X.509. The ASN.1 definition of this structure appears below.
*
* *

     *   NameConstraints ::= SEQUENCE {
     *        permittedSubtrees       [0]     GeneralSubtrees OPTIONAL,
     *        excludedSubtrees        [1]     GeneralSubtrees OPTIONAL }
     * 
     *   GeneralSubtrees ::= SEQUENCE SIZE (1..MAX) OF GeneralSubtree
     * 
     *   GeneralSubtree ::= SEQUENCE {
     *        base                    GeneralName,
     *        minimum         [0]     BaseDistance DEFAULT 0,
     *        maximum         [1]     BaseDistance OPTIONAL }
     * 
     *   BaseDistance ::= INTEGER (0..MAX)
     * 
     *   GeneralName ::= CHOICE {
     *        otherName                       [0]     OtherName,
     *        rfc822Name                      [1]     IA5String,
     *        dNSName                         [2]     IA5String,
     *        x400Address                     [3]     ORAddress,
     *        directoryName                   [4]     Name,
     *        ediPartyName                    [5]     EDIPartyName,
     *        uniformResourceIdentifier       [6]     IA5String,
     *        iPAddress                       [7]     OCTET STRING,
     *        registeredID                    [8]     OBJECT IDENTIFIER}
     * 
* *
*
* Note that the name constraints byte array supplied is cloned to protect * against subsequent modifications. * * @param trustedCert * a trusted X509Certificate * @param nameConstraints * a byte array containing the ASN.1 DER encoding of a * NameConstraints extension to be used for checking name * constraints. Only the value of the extension is included, not * the OID or criticality flag. Specify null to omit the * parameter. * * @exception IllegalArgumentException * if the name constraints cannot be decoded * @exception NullPointerException * if the specified X509Certificate is null */ public TrustAnchor(X509Certificate trustedCert, byte[] nameConstraints) { if (trustedCert == null) { throw new NullPointerException("trustedCert must be non-null"); } this.trustCert = trustedCert; if (nameConstraints != null) { this.nameConstraints = (byte[])nameConstraints.clone(); checkNameConstraints(this.nameConstraints); } } /** * Creates an instance of TrustAnchor where the most-trusted * CA is specified as a distinguished name and public key. Name constraints * are an optional parameter, and are intended to be used as additional * constraints when validating an X.509 certification path. * * The name constraints are specified as a byte array. This byte array * contains the DER encoded form of the name constraints, as they would * appear in the NameConstraints structure defined in RFC 2459 and X.509. * The ASN.1 notation for this structure is supplied in the documentation * for {@link #TrustAnchor(X509Certificate trustedCert, byte[] * nameConstraints) TrustAnchor(X509Certificate trustedCert, byte[] * nameConstraints) }. * * Note that the name constraints byte array supplied here is cloned to * protect against subsequent modifications. * * @param caName * the X.500 distinguished name of the most-trusted CA in RFC * 2253 String format * @param pubKey * the public key of the most-trusted CA * @param nameConstraints * a byte array containing the ASN.1 DER encoding of a * NameConstraints extension to be used for checking name * constraints. Only the value of the extension is included, not * the OID or criticality flag. Specify null to omit the * parameter. * * @exception IllegalArgumentException * if the specified caName parameter is empty (caName.length() == 0) * or incorrectly formatted or the name constraints cannot be * decoded * @exception NullPointerException * if the specified caName or pubKey parameter is null */ public TrustAnchor(String caName, PublicKey pubKey, byte[] nameConstraints) { if (caName == null) { throw new NullPointerException("caName must be non-null"); } if (pubKey == null) { throw new NullPointerException("pubKey must be non-null"); } if (caName.length() == 0) { throw new IllegalArgumentException( "caName can not be an empty string"); } this.trustName = caName; this.trustPublicKey = pubKey; if (nameConstraints != null) { this.nameConstraints = (byte[])nameConstraints.clone(); checkNameConstraints(this.nameConstraints); } } /** * Returns the most-trusted CA certificate. * * @return a trusted X509Certificate or null * if the trust anchor was not specified as a trusted certificate */ public final X509Certificate getTrustedCert() { return trustCert; } /** * Returns the name of the most-trusted CA in RFC 2253 String format. * * @return the X.500 distinguished name of the most-trusted CA, or * null if the trust anchor was not specified as a * trusted public key and name pair */ public final String getCAName() { return trustName; } /** * Returns the public key of the most-trusted CA. * * @return the public key of the most-trusted CA, or null if the trust * anchor was not specified as a trusted public key and name pair */ public final PublicKey getCAPublicKey() { return trustPublicKey; } /** * Returns the name constraints parameter. The specified name constraints * are associated with this trust anchor and are intended to be used as * additional constraints when validating an X.509 certification path.
*
* The name constraints are returned as a byte array. This byte array * contains the DER encoded form of the name constraints, as they would * appear in the NameConstraints structure defined in RFC 2459 and X.509. * The ASN.1 notation for this structure is supplied in the documentation * for TrustAnchor(X509Certificate trustedCert, byte[] * nameConstraints).
*
* Note that the byte array returned is cloned to protect against subsequent * modifications. * * @return a byte array containing the ASN.1 DER encoding of a * NameConstraints extension used for checking name constraints, or * null if not set. */ public final byte[] getNameConstraints() { return (byte[])nameConstraints.clone(); } /** * Returns a formatted string describing the TrustAnchor. * * @return a formatted string describing the TrustAnchor */ public String toString() { StringBuffer sb = new StringBuffer(); sb.append("[\n"); if (getCAPublicKey() != null) { sb.append(" Trusted CA Public Key: ").append(getCAPublicKey()).append('\n'); sb.append(" Trusted CA Issuer Name: ").append(getCAName()).append('\n'); } else { sb.append(" Trusted CA cert: ").append(getTrustedCert()).append('\n'); } if (nameConstraints != null) { sb.append(" Name Constraints: ").append(nameConstraints).append('\n'); } return sb.toString(); } /** * Check given DER encoded nameConstraints for correct decoding. Currently * only basic DER decoding test.
*
* TODO: implement more testing. * * @param data * the DER encoded nameConstrains to be checked or * null * @exception IllegalArgumentException * if the check failed. */ private void checkNameConstraints(byte[] data) { if (data != null) { try { ByteArrayInputStream inStream = new ByteArrayInputStream(data); ASN1InputStream derInStream = new ASN1InputStream(inStream); ASN1Object derObject = derInStream.readObject(); if (!(derObject instanceof ASN1Sequence)) { throw new IllegalArgumentException( "nameConstraints parameter decoding error"); } } catch (IOException ex) { throw new IllegalArgumentException( "nameConstraints parameter decoding error: " + ex); } } } }bouncycastle-1.49.orig/jdk1.3/org/bouncycastle/jce/cert/CertSelector.java0000644000175000017500000000255410262753174025661 0ustar ebourgebourgpackage org.bouncycastle.jce.cert; import java.security.cert.Certificate; /** * A selector that defines a set of criteria for selecting * Certificates. Classes that implement this interface * are often used to specify which Certificates should * be retrieved from a CertStore.
*
* Concurrent Access
*
* Unless otherwise specified, the methods defined in this interface are not * thread-safe. Multiple threads that need to access a single * object concurrently should synchronize amongst themselves and * provide the necessary locking. Multiple threads each manipulating * separate objects need not synchronize. * * @see Certificate * @see CertStore * @see CertStore#getCertificates */ public interface CertSelector extends Cloneable { /** * Decides whether a Certificate should be selected. * * @param cert the Certificate to be checked * @return true if the Certificate * should be selected, false otherwise */ public boolean match(Certificate cert); /** * Makes a copy of this CertSelector. Changes to the * copy will not affect the original and vice versa. * * @return a copy of this CertSelector */ public Object clone(); } bouncycastle-1.49.orig/jdk1.3/org/bouncycastle/jce/cert/PKIXCertPathValidatorResult.java0000644000175000017500000001211710505106272030521 0ustar ebourgebourgpackage org.bouncycastle.jce.cert; import java.security.PublicKey; /** * This class represents the successful result of the PKIX certification path * validation algorithm.
*
* Instances of PKIXCertPathValidatorResult are returned by the * {@link CertPathValidator#validate validate} method of * CertPathValidator objects implementing the PKIX algorithm.
*
* All PKIXCertPathValidatorResult objects contain the valid * policy tree and subject public key resulting from the validation algorithm, * as well as a TrustAnchor describing the certification * authority (CA) that served as a trust anchor for the certification path.
*
* Concurrent Access
*
* Unless otherwise specified, the methods defined in this class are not * thread-safe. Multiple threads that need to access a single object * concurrently should synchronize amongst themselves and provide the necessary * locking. Multiple threads each manipulating separate objects need not * synchronize. * * @see CertPathValidatorResult */ public class PKIXCertPathValidatorResult implements CertPathValidatorResult { private TrustAnchor trustAnchor; private PolicyNode policyTree; private PublicKey subjectPublicKey; /** * Creates an instance of PKIXCertPathValidatorResult * containing the specified parameters. * * @param trustAnchor * a TrustAnchor describing the CA that served as * a trust anchor for the certification path * @param policyTree * the immutable valid policy tree, or null if * there are no valid policies * @param subjectPublicKey * the public key of the subject * * @exception NullPointerException * if the subjectPublicKey or * trustAnchor parameters are * null */ public PKIXCertPathValidatorResult( TrustAnchor trustAnchor, PolicyNode policyTree, PublicKey subjectPublicKey) { if (subjectPublicKey == null) { throw new NullPointerException("subjectPublicKey must be non-null"); } if (trustAnchor == null) { throw new NullPointerException("trustAnchor must be non-null"); } this.trustAnchor = trustAnchor; this.policyTree = policyTree; this.subjectPublicKey = subjectPublicKey; } /** * Returns the TrustAnchor describing the CA that served as a * trust anchor for the certification path. * * @return the TrustAnchor (never null) */ public TrustAnchor getTrustAnchor() { return trustAnchor; } /** * Returns the root node of the valid policy tree resulting from the PKIX * certification path validation algorithm. The PolicyNode * object that is returned and any objects that it returns through public * methods are immutable.
*
* Most applications will not need to examine the valid policy tree. They * can achieve their policy processing goals by setting the policy-related * parameters in PKIXParameters. However, more sophisticated * applications, especially those that process policy qualifiers, may need * to traverse the valid policy tree using the * {@link PolicyNode#getParent PolicyNode.getParent} and * {@link PolicyNode#getChildren PolicyNode.getChildren} methods. * * @return the root node of the valid policy tree, or null if * there are no valid policies */ public PolicyNode getPolicyTree() { return policyTree; } /** * Returns the public key of the subject (target) of the certification path, * including any inherited public key parameters if applicable. * * @return the public key of the subject (never null) */ public PublicKey getPublicKey() { return subjectPublicKey; } /** * Returns a copy of this object. * * @return the copy */ public Object clone() { try { return super.clone(); } catch (CloneNotSupportedException ex) { throw new InternalError(ex.toString()); } } /** * Return a printable representation of this * PKIXCertPathValidatorResult. * * @return a String describing the contents of this * PKIXCertPathValidatorResult */ public String toString() { StringBuffer s = new StringBuffer(); s.append("PKIXCertPathValidatorResult: [ \n"); s.append(" Trust Anchor: ").append(getTrustAnchor()).append('\n'); s.append(" Policy Tree: ").append(getPolicyTree()).append('\n'); s.append(" Subject Public Key: ").append(getPublicKey()).append("\n]"); return s.toString(); } } bouncycastle-1.49.orig/jdk1.3/org/bouncycastle/jce/cert/CRLSelector.java0000644000175000017500000000244010262753174025376 0ustar ebourgebourgpackage org.bouncycastle.jce.cert; import java.security.cert.CRL; /** * A selector that defines a set of criteria for selecting CRLs. * Classes that implement this interface are often used to specify * which CRLs should be retrieved from a CertStore.
*
* Concurrent Access
*
* Unless otherwise specified, the methods defined in this interface are not * thread-safe. Multiple threads that need to access a single * object concurrently should synchronize amongst themselves and * provide the necessary locking. Multiple threads each manipulating * separate objects need not synchronize. * * @see CRL * @see CertStore * @see CertStore#getCRLs **/ public interface CRLSelector extends Cloneable { /** * Decides whether a CRL should be selected. * * @param crl the CRL to be checked * * @return true if the CRL should be selected, * false otherwise */ public boolean match(CRL crl); /** * Makes a copy of this CRLSelector. Changes to the * copy will not affect the original and vice versa. * * @return a copy of this CRLSelector */ public Object clone(); } bouncycastle-1.49.orig/jdk1.3/org/bouncycastle/jce/cert/CertStoreException.java0000644000175000017500000001246710505106272027047 0ustar ebourgebourgpackage org.bouncycastle.jce.cert; import java.io.PrintStream; import java.io.PrintWriter; import java.security.GeneralSecurityException; /** * An exception indicating one of a variety of problems retrieving * certificates and CRLs from a CertStore.
*
* A CertStoreException provides support for wrapping * exceptions. The {@link #getCause getCause} method returns the throwable, * if any, that caused this exception to be thrown.
*
* Concurrent Access
*
* Unless otherwise specified, the methods defined in this class are not * thread-safe. Multiple threads that need to access a single * object concurrently should synchronize amongst themselves and * provide the necessary locking. Multiple threads each manipulating * separate objects need not synchronize. * * @see CertStore **/ public class CertStoreException extends GeneralSecurityException { private Throwable cause; /** * Creates a CertStoreException with null as * its detail message. */ public CertStoreException() { super(); } /** * Creates a CertStoreException with the given detail * message. A detail message is a String that describes this * particular exception. * * @param messag * the detail message */ public CertStoreException(String message) { super(message); } /** * Creates a CertStoreException with the specified detail * message and cause. * * @param messag * the detail message * @param cause * the cause (which is saved for later retrieval by the * {@link #getCause getCause()} method). (A null * value is permitted, and indicates that the cause is * nonexistent or unknown.) */ public CertStoreException(String message, Throwable cause) { super(message); this.cause = cause; } /** * Creates a CertStoreException that wraps the specified * throwable. This allows any exception to be converted into a * CertStoreException, while retaining information about the * cause, which may be useful for debugging. The detail message is set to (cause==null ? null : cause.toString()) * (which typically contains the class and detail message of cause). * * @param cause * the cause (which is saved for later retrieval by the * {@link #getCause getCause()} method). (A null * value is permitted, and indicates that the cause is * nonexistent or unknown.) */ public CertStoreException(Throwable cause) { this.cause = cause; } /** * Returns the detail message for this CertStoreException. * * @return the detail message, or null if neither the message * nor cause were specified */ public String getMessage() { String message = super.getMessage(); if (message == null && cause == null) { return null; } StringBuffer s = new StringBuffer(); if (message != null) { s.append(message).append('\n'); } if (cause != null) { s.append("Cause:\n").append(cause.getMessage()); } return s.toString(); } /** * Returns the cause of this CertStoreException or * null if the cause is nonexistent or unknown. * * @return the cause of this throwable or null if the cause * is nonexistent or unknown. */ public Throwable getCause() { return cause; } /** * Returns a string describing this exception, including a description of * the internal (wrapped) cause if there is one. * * @return a string representation of this CertStoreException */ public String toString() { String message = getMessage(); if (message == null) { return ""; } return message; } /** * Prints a stack trace to System.err, including the * backtrace of the cause, if any. */ public void printStackTrace() { printStackTrace(System.err); } /** * Prints a stack trace to a PrintStream, including the * backtrace of the cause, if any. * * @param ps * the PrintStream to use for output */ public void printStackTrace(PrintStream ps) { super.printStackTrace(ps); if (cause != null) { cause.printStackTrace(ps); } } /** * Prints a stack trace to a PrintWriter, including the * backtrace of the cause, if any. * * @param pw * the PrintWriter to use for output */ public void printStackTrace(PrintWriter pw) { if (cause != null) { cause.printStackTrace(pw); } super.printStackTrace(pw); if (cause != null) { cause.printStackTrace(pw); } } } bouncycastle-1.49.orig/jdk1.3/org/bouncycastle/jce/cert/CertStoreSpi.java0000644000175000017500000001155510331052734025641 0ustar ebourgebourgpackage org.bouncycastle.jce.cert; import java.security.InvalidAlgorithmParameterException; import java.util.Collection; /** * The Service Provider Interface (SPI) * for the {@link CertStore CertStore} class. All CertStore * implementations must include a class (the SPI class) that extends * this class (CertStoreSpi), provides a constructor with * a single argument of type CertStoreParameters, and implements * all of its methods. In general, instances of this class should only be * accessed through the CertStore class. * For details, see the Java Cryptography Architecture.
*
* Concurrent Access
*
* The public methods of all CertStoreSpi objects must be * thread-safe. That is, multiple threads may concurrently invoke these * methods on a single CertStoreSpi object (or more than one) * with no ill effects. This allows a CertPathBuilder to search * for a CRL while simultaneously searching for further certificates, for * instance.
*
* Simple CertStoreSpi implementations will probably ensure * thread safety by adding a synchronized keyword to their * engineGetCertificates and engineGetCRLs methods. * More sophisticated ones may allow truly concurrent access. **/ public abstract class CertStoreSpi extends Object { /** * The sole constructor. * * @param params the initialization parameters (may be null) * @exception InvalidAlgorithmParameterException if the initialization * parameters are inappropriate for this CertStoreSpi */ public CertStoreSpi(CertStoreParameters params) throws InvalidAlgorithmParameterException {} /** * Returns a Collection of Certificates that * match the specified selector. If no Certificates * match the selector, an empty Collection will be returned.
*
* For some CertStore types, the resulting * Collection may not contain all of the * Certificates that match the selector. For instance, * an LDAP CertStore may not search all entries in the * directory. Instead, it may just search entries that are likely to * contain the Certificates it is looking for.
*
* Some CertStore implementations (especially LDAP * CertStores) may throw a CertStoreException * unless a non-null CertSelector is provided that includes * specific criteria that can be used to find the certificates. Issuer * and/or subject names are especially useful criteria. * * @param selector A CertSelector used to select which * Certificates should be returned. Specify null * to return all Certificates (if supported). * * @return A Collection of Certificates that * match the specified selector (never null) * * @exception CertStoreException if an exception occurs */ public abstract Collection engineGetCertificates(CertSelector selector) throws CertStoreException; /** * Returns a Collection of CRLs that * match the specified selector. If no CRLs * match the selector, an empty Collection will be returned.
*
* For some CertStore types, the resulting * Collection may not contain all of the * CRLs that match the selector. For instance, * an LDAP CertStore may not search all entries in the * directory. Instead, it may just search entries that are likely to * contain the CRLs it is looking for.
*
* Some CertStore implementations (especially LDAP * CertStores) may throw a CertStoreException * unless a non-null CRLSelector is provided that includes * specific criteria that can be used to find the CRLs. Issuer names * and/or the certificate to be checked are especially useful. * * @param selector A CRLSelector used to select which * CRLs should be returned. Specify null * to return all CRLs (if supported). * * @return A Collection of CRLs that * match the specified selector (never null) * * @exception CertStoreException if an exception occurs */ public abstract Collection engineGetCRLs(CRLSelector selector) throws CertStoreException; } bouncycastle-1.49.orig/jdk1.3/org/bouncycastle/jce/cert/PKIXCertPathBuilderResult.java0000644000175000017500000000752710505106272030173 0ustar ebourgebourgpackage org.bouncycastle.jce.cert; import java.security.PublicKey; /** * This class represents the successful result of the PKIX certification * path builder algorithm. All certification paths that are built and * returned using this algorithm are also validated according to the PKIX * certification path validation algorithm.
*
* Instances of PKIXCertPathBuilderResult are returned by * the build method of CertPathBuilder * objects implementing the PKIX algorithm.
*
* All PKIXCertPathBuilderResult objects contain the * certification path constructed by the build algorithm, the * valid policy tree and subject public key resulting from the build * algorithm, and a TrustAnchor describing the certification * authority (CA) that served as a trust anchor for the certification path.
*
* Concurrent Access
*
* Unless otherwise specified, the methods defined in this class are not * thread-safe. Multiple threads that need to access a single * object concurrently should synchronize amongst themselves and * provide the necessary locking. Multiple threads each manipulating * separate objects need not synchronize. * * @see CertPathBuilderResult * **/ public class PKIXCertPathBuilderResult extends PKIXCertPathValidatorResult implements CertPathBuilderResult { private CertPath certPath; /** * Creates an instance of PKIXCertPathBuilderResult * containing the specified parameters. * * @param certPath * the validated CertPath * @param trustAnchor * a TrustAnchor describing the CA that served as * a trust anchor for the certification path * @param policyTree * the immutable valid policy tree, or null if * there are no valid policies * @param subjectPublicKey * the public key of the subject * * @exception NullPointerException * if the certPath, trustAnchor * or subjectPublicKey parameters are * null */ public PKIXCertPathBuilderResult( CertPath certPath, TrustAnchor trustAnchor, PolicyNode policyTree, PublicKey subjectPublicKey) { super(trustAnchor, policyTree, subjectPublicKey); if (certPath == null) { throw new NullPointerException("certPath must be non-null"); } this.certPath = certPath; } /** * Returns the built and validated certification path. The * CertPath object does not include the trust anchor. * Instead, use the {@link #getTrustAnchor() getTrustAnchor()} method to * obtain the TrustAnchor that served as the trust anchor for * the certification path. * * @return the built and validated CertPath (never * null) */ public CertPath getCertPath() { return certPath; } /** * Return a printable representation of this * PKIXCertPathBuilderResult. * * @return a String describing the contents of this * PKIXCertPathBuilderResult */ public String toString() { StringBuffer s = new StringBuffer(); s.append("PKIXCertPathBuilderResult: [\n"); s.append(" Certification Path: ").append(getCertPath()).append('\n'); s.append(" Trust Anchor: ").append(getTrustAnchor()).append('\n'); s.append(" Policy Tree: ").append(getPolicyTree()).append('\n'); s.append(" Subject Public Key: ").append(getPublicKey()).append("\n]"); return s.toString(); } } bouncycastle-1.49.orig/jdk1.3/org/bouncycastle/jce/cert/package.html0000644000175000017500000000014010262753174024666 0ustar ebourgebourg Compatibility API for the JDK 1.4 CertPath API. bouncycastle-1.49.orig/jdk1.3/org/bouncycastle/jce/cert/CertPathValidatorResult.java0000644000175000017500000000135010262753174030033 0ustar ebourgebourgpackage org.bouncycastle.jce.cert; /** * A specification of the result of a certification path validator algorithm.
*
* The purpose of this interface is to group (and provide type safety * for) all certification path validator results. All results returned * by the {@link CertPathValidator#validate CertPathValidator.validate} * method must implement this interface. * * @see CertPathValidator **/ public interface CertPathValidatorResult extends Cloneable { /** * Makes a copy of this CertPathValidatorResult. Changes to the * copy will not affect the original and vice versa. * * @return a copy of this CertPathValidatorResult */ public Object clone(); } bouncycastle-1.49.orig/jdk1.3/org/bouncycastle/jce/cert/CertificateFactorySpi.java0000644000175000017500000001022510262753174027503 0ustar ebourgebourgpackage org.bouncycastle.jce.cert; import java.io.InputStream; import java.security.cert.CertificateException; import java.util.Iterator; import java.util.List; public abstract class CertificateFactorySpi extends java.security.cert.CertificateFactorySpi { public CertificateFactorySpi() { } /** * Returns an iteration of the CertPath encodings supported * by this certificate factory, with the default encoding first. See * Appendix A in the * Java Certification Path API Programmer's Guide * for information about standard encoding names.
*
* Attempts to modify the returned Iterator via its * remove method result in an * UnsupportedOperationException.
*
* This method was added to version 1.4 of the Java 2 Platform * Standard Edition. In order to maintain backwards compatibility with * existing service providers, this method cannot be abstract * and by default throws an UnsupportedOperationException. * * @return an Iterator over the names of the supported * CertPath encodings (as Strings) * * @exception UnsupportedOperationException if the method is not supported */ public abstract Iterator engineGetCertPathEncodings(); /** * Generates a CertPath object and initializes it with * the data read from the InputStream inStream. The data * is assumed to be in the default encoding. * * @param inStream an InputStream containing the data * * @return a CertPath initialized with the data from the * InputStream * * @exception CertificateException if an exception occurs while decoding */ public abstract CertPath engineGenerateCertPath(InputStream inStream) throws CertificateException; /** * Generates a CertPath object and initializes it with * the data read from the InputStream inStream. The data * is assumed to be in the specified encoding.
*
* This method was added to version 1.4 of the Java 2 Platform * Standard Edition. In order to maintain backwards compatibility with * existing service providers, this method cannot be abstract * and by default throws an UnsupportedOperationException. * * @param inStream an InputStream containing the data * @param encoding the encoding used for the data * * @return a CertPath initialized with the data from the * InputStream * * @exception CertificateException if an exception occurs while decoding or * the encoding requested is not supported * @exception UnsupportedOperationException if the method is not supported */ public abstract CertPath engineGenerateCertPath(InputStream inStream, String encoding) throws CertificateException; /** * Generates a CertPath object and initializes it with * a List of Certificates.
*
* The certificates supplied must be of a type supported by the * CertificateFactory. They will be copied out of the supplied * List object.
*
* This method was added to version 1.4 of the Java 2 Platform * Standard Edition. In order to maintain backwards compatibility with * existing service providers, this method cannot be abstract * and by default throws an UnsupportedOperationException. * * @param certificates a List of Certificates * * @return a CertPath initialized with the supplied list of * certificates * * @exception CertificateException if an exception occurs * @exception UnsupportedOperationException if the method is not supported */ public abstract CertPath engineGenerateCertPath(List certificates) throws CertificateException; } bouncycastle-1.49.orig/jdk1.3/org/bouncycastle/jce/MultiCertStoreParameters.java0000644000175000017500000000270010623745117027267 0ustar ebourgebourgpackage org.bouncycastle.jce; import org.bouncycastle.jce.cert.CertStoreParameters; import java.util.Collection; public class MultiCertStoreParameters implements CertStoreParameters { private Collection certStores; private boolean searchAllStores; /** * Create a parameters object which specifies searching of all the passed in stores. * * @param certStores CertStores making up the multi CertStore */ public MultiCertStoreParameters(Collection certStores) { this(certStores, true); } /** * Create a parameters object which can be to used to make a multi store made up * of the passed in CertStores. If the searchAllStores parameter is false, any search on * the multi-store will terminate as soon as a search query produces a result. * * @param certStores CertStores making up the multi CertStore * @param searchAllStores true if all CertStores should be searched on request, false if a result * should be returned on the first successful CertStore query. */ public MultiCertStoreParameters(Collection certStores, boolean searchAllStores) { this.certStores = certStores; this.searchAllStores = searchAllStores; } public Collection getCertStores() { return certStores; } public boolean getSearchAllStores() { return searchAllStores; } public Object clone() { return this; } } bouncycastle-1.49.orig/jdk1.3/org/bouncycastle/jce/exception/0000755000175000017500000000000012152033550023440 5ustar ebourgebourgbouncycastle-1.49.orig/jdk1.3/org/bouncycastle/jce/exception/ExtCertPathValidatorException.java0000644000175000017500000000126610722206756032243 0ustar ebourgebourgpackage org.bouncycastle.jce.exception; import org.bouncycastle.jce.cert.CertPath; import org.bouncycastle.jce.cert.CertPathValidatorException; public class ExtCertPathValidatorException extends CertPathValidatorException implements ExtException { private Throwable cause; public ExtCertPathValidatorException(String message, Throwable cause) { super(message); this.cause = cause; } public ExtCertPathValidatorException(String msg, Throwable cause, CertPath certPath, int index) { super(msg, cause, certPath, index); this.cause = cause; } public Throwable getCause() { return cause; } } bouncycastle-1.49.orig/jdk1.3/org/bouncycastle/jce/exception/ExtCertPathBuilderException.java0000644000175000017500000000123210722253561031671 0ustar ebourgebourgpackage org.bouncycastle.jce.exception; import org.bouncycastle.jce.cert.CertPath; import org.bouncycastle.jce.cert.CertPathBuilderException; public class ExtCertPathBuilderException extends CertPathBuilderException implements ExtException { private Throwable cause; public ExtCertPathBuilderException(String message, Throwable cause) { super(message); this.cause = cause; } public ExtCertPathBuilderException(String msg, Throwable cause, CertPath certPath, int index) { super(msg, cause); this.cause = cause; } public Throwable getCause() { return cause; } } bouncycastle-1.49.orig/jdk1.3/org/bouncycastle/jce/spec/0000755000175000017500000000000012152033550022374 5ustar ebourgebourgbouncycastle-1.49.orig/jdk1.3/org/bouncycastle/jce/spec/PSSParameterSpec.java0000644000175000017500000000177610331052735026376 0ustar ebourgebourgpackage org.bouncycastle.jce.spec; /** * This class specifies a parameter spec for RSA PSS encoding scheme, * as defined in the PKCS#1 v2.1. * * @see java.security.spec.AlgorithmParameterSpec * @see java.security.Signature */ public class PSSParameterSpec extends Object implements java.security.spec.AlgorithmParameterSpec { private int saltLen; /** * Creates a new PSSParameterSpec given the salt length as defined * in PKCS#1. * * @param saltLen - the length of salt in bits to be used in PKCS#1 * PSS encoding. * @throws IllegalArgumentException - if saltLen is less than 0. */ public PSSParameterSpec(int saltLen) { if (saltLen < 0) { throw new IllegalArgumentException("Salt length must be >= 0"); } this.saltLen = saltLen; } /** * Returns the salt length in bits. * * @returns the salt length. */ public int getSaltLength() { return saltLen; } } bouncycastle-1.49.orig/jdk1.3/org/bouncycastle/jce/ECKeyUtil.java0000644000175000017500000002130512110037231024076 0ustar ebourgebourgpackage org.bouncycastle.jce; import java.io.UnsupportedEncodingException; import java.security.KeyFactory; import java.security.NoSuchAlgorithmException; import java.security.NoSuchProviderException; import java.security.PrivateKey; import java.security.Provider; import java.security.PublicKey; import java.security.Security; import java.security.spec.PKCS8EncodedKeySpec; import java.security.spec.X509EncodedKeySpec; import org.bouncycastle.asn1.ASN1ObjectIdentifier; import org.bouncycastle.asn1.ASN1Primitive; import org.bouncycastle.asn1.cryptopro.CryptoProObjectIdentifiers; import org.bouncycastle.asn1.pkcs.PrivateKeyInfo; import org.bouncycastle.asn1.x509.AlgorithmIdentifier; import org.bouncycastle.asn1.x509.SubjectPublicKeyInfo; import org.bouncycastle.asn1.x9.X962Parameters; import org.bouncycastle.asn1.x9.X9ECParameters; import org.bouncycastle.asn1.x9.X9ObjectIdentifiers; import org.bouncycastle.jcajce.provider.asymmetric.util.ECUtil; import org.bouncycastle.jce.provider.BouncyCastleProvider; /** * Utility class to allow conversion of EC key parameters to explicit from named * curves and back (where possible). */ public class ECKeyUtil { /** * Convert a passed in public EC key to have explicit parameters. If the key * is already using explicit parameters it is returned. * * @param key key to be converted * @param providerName provider name to be used. * @return the equivalent key with explicit curve parameters * @throws IllegalArgumentException * @throws NoSuchAlgorithmException * @throws NoSuchProviderException */ public static PublicKey publicToExplicitParameters(PublicKey key, String providerName) throws IllegalArgumentException, NoSuchAlgorithmException, NoSuchProviderException { Provider provider = Security.getProvider(providerName); if (provider == null) { throw new NoSuchProviderException("cannot find provider: " + providerName); } return publicToExplicitParameters(key, provider); } /** * Convert a passed in public EC key to have explicit parameters. If the key * is already using explicit parameters it is returned. * * @param key key to be converted * @param provider provider to be used. * @return the equivalent key with explicit curve parameters * @throws IllegalArgumentException * @throws NoSuchAlgorithmException */ public static PublicKey publicToExplicitParameters(PublicKey key, Provider provider) throws IllegalArgumentException, NoSuchAlgorithmException { try { SubjectPublicKeyInfo info = SubjectPublicKeyInfo.getInstance(ASN1Primitive.fromByteArray(key.getEncoded())); if (info.getAlgorithmId().getObjectId().equals(CryptoProObjectIdentifiers.gostR3410_2001)) { throw new IllegalArgumentException("cannot convert GOST key to explicit parameters."); } else { X962Parameters params = X962Parameters.getInstance(info.getAlgorithmId().getParameters()); X9ECParameters curveParams; if (params.isNamedCurve()) { ASN1ObjectIdentifier oid = ASN1ObjectIdentifier.getInstance(params.getParameters()); curveParams = ECUtil.getNamedCurveByOid(oid); // ignore seed value due to JDK bug curveParams = new X9ECParameters(curveParams.getCurve(), curveParams.getG(), curveParams.getN(), curveParams.getH()); } else if (params.isImplicitlyCA()) { curveParams = new X9ECParameters(BouncyCastleProvider.CONFIGURATION.getEcImplicitlyCa().getCurve(), BouncyCastleProvider.CONFIGURATION.getEcImplicitlyCa().getG(), BouncyCastleProvider.CONFIGURATION.getEcImplicitlyCa().getN(), BouncyCastleProvider.CONFIGURATION.getEcImplicitlyCa().getH()); } else { return key; // already explicit } params = new X962Parameters(curveParams); info = new SubjectPublicKeyInfo(new AlgorithmIdentifier(X9ObjectIdentifiers.id_ecPublicKey, params), info.getPublicKeyData().getBytes()); KeyFactory keyFact = KeyFactory.getInstance(key.getAlgorithm(), provider.getName()); return keyFact.generatePublic(new X509EncodedKeySpec(info.getEncoded())); } } catch (IllegalArgumentException e) { throw e; } catch (NoSuchAlgorithmException e) { throw e; } catch (Exception e) { // shouldn't really happen... throw new UnexpectedException(e); } } /** * Convert a passed in private EC key to have explicit parameters. If the key * is already using explicit parameters it is returned. * * @param key key to be converted * @param providerName provider name to be used. * @return the equivalent key with explicit curve parameters * @throws IllegalArgumentException * @throws NoSuchAlgorithmException * @throws NoSuchProviderException */ public static PrivateKey privateToExplicitParameters(PrivateKey key, String providerName) throws IllegalArgumentException, NoSuchAlgorithmException, NoSuchProviderException { Provider provider = Security.getProvider(providerName); if (provider == null) { throw new NoSuchProviderException("cannot find provider: " + providerName); } return privateToExplicitParameters(key, provider); } /** * Convert a passed in private EC key to have explicit parameters. If the key * is already using explicit parameters it is returned. * * @param key key to be converted * @param provider provider to be used. * @return the equivalent key with explicit curve parameters * @throws IllegalArgumentException * @throws NoSuchAlgorithmException */ public static PrivateKey privateToExplicitParameters(PrivateKey key, Provider provider) throws IllegalArgumentException, NoSuchAlgorithmException { try { PrivateKeyInfo info = PrivateKeyInfo.getInstance(ASN1Primitive.fromByteArray(key.getEncoded())); if (info.getAlgorithmId().getObjectId().equals(CryptoProObjectIdentifiers.gostR3410_2001)) { throw new UnsupportedEncodingException("cannot convert GOST key to explicit parameters."); } else { X962Parameters params = X962Parameters.getInstance(info.getAlgorithmId().getParameters()); X9ECParameters curveParams; if (params.isNamedCurve()) { ASN1ObjectIdentifier oid = ASN1ObjectIdentifier.getInstance(params.getParameters()); curveParams = ECUtil.getNamedCurveByOid(oid); // ignore seed value due to JDK bug curveParams = new X9ECParameters(curveParams.getCurve(), curveParams.getG(), curveParams.getN(), curveParams.getH()); } else if (params.isImplicitlyCA()) { curveParams = new X9ECParameters(BouncyCastleProvider.CONFIGURATION.getEcImplicitlyCa().getCurve(), BouncyCastleProvider.CONFIGURATION.getEcImplicitlyCa().getG(), BouncyCastleProvider.CONFIGURATION.getEcImplicitlyCa().getN(), BouncyCastleProvider.CONFIGURATION.getEcImplicitlyCa().getH()); } else { return key; // already explicit } params = new X962Parameters(curveParams); info = new PrivateKeyInfo(new AlgorithmIdentifier(X9ObjectIdentifiers.id_ecPublicKey, params), info.parsePrivateKey()); KeyFactory keyFact = KeyFactory.getInstance(key.getAlgorithm(), provider.getName()); return keyFact.generatePrivate(new PKCS8EncodedKeySpec(info.getEncoded())); } } catch (IllegalArgumentException e) { throw e; } catch (NoSuchAlgorithmException e) { throw e; } catch (Exception e) { // shouldn't really happen throw new UnexpectedException(e); } } private static class UnexpectedException extends RuntimeException { private Throwable cause; UnexpectedException(Throwable cause) { super(cause.toString()); this.cause = cause; } public Throwable getCause() { return cause; } } } bouncycastle-1.49.orig/jdk14.xml0000644000175000017500000001401612147055766016107 0ustar ebourgebourg bouncycastle-1.49.orig/releasenotes.html0000644000175000017500000027146212150005743020021 0ustar ebourgebourg Bouncy Castle Crypto Package - Release Notes

Bouncy Castle Crypto Package - Release Notes


1.0 Introduction

The Bouncy Castle Crypto package is a Java implementation of cryptographic algorithms. The package is organised so that it contains a light-weight API suitable for use in any environment (including the newly released J2ME) with the additional infrastructure to conform the algorithms to the JCE framework.

2.0 Release History

2.1.1 Version

Release 1.49

2.1.2 Defects Fixed

  • Occasional ArrayOutOfBounds exception in DSTU-4145 signature generation has been fixed.
  • The handling of escaped characters in X500 names is much improved.
  • The BC CertificateFactory no longer returns null for CertificateFactory.getCertPathEncodings().
  • PKCS10CertificationRequestBuilder now encodes no attributes as empty by default. Encoding as absent is still available via a boolean flag.
  • DERT61String has been reverted back to its previous implementaion. A new class DERT61UTF8String has been introduced which defaults to UTF-8 encoding.
  • OAEPEncoding could throw an array output bounds exception for small keys with large mask function digests. This has been fixed.
  • PEMParser would throw a NullPointerException if it ran into explicit EC curve parameters, it would also throw an Exception if the named curve was not already defined. The parser now returns X9ECParmameters for explicit parameters and returns an ASN1ObjectIdentifier for a named curve.
  • The V2TBSCertListGenerator was adding the wrong date type for CRL invalidity date extensions. This has been fixed.

2.1.3 Additional Features and Functionality

  • A SecretKeyFactory has been added that enables use of PBKDF2WithHmacSHA.
  • Support has been added to PKCS12 KeyStores and PfxPdu to handle PKCS#5 encrypted private keys.
  • Support has been added for SHA-512/224, SHA-512-256, as well as a general SHA-512/t in the lightweight API.
  • The JcaPGPPrivateKey class has been added to provide better support in the PGP API for HSM private keys.
  • A new KeyStore type, BKS-V1, has been added for people needing to create key stores compatible with earlier versions of Bouncy Castle.
  • Some extra generation methods have been added to TimeStampResponseGenerator to allow more control in the generation of TimeStampResponses.
  • It is now possible to override the SignerInfo attributes during TimeStampTokenGeneration.
  • The TSP API now supports generation of certIDs based on digests other than SHA-1.
  • OCSP responses can now be included in CMS SignedData objects.
  • The SipHash MAC algorithm has been added to the lightweight API and the provider.
  • ISO9796-2 PSS signatures can now be initialised with a signature to allow the signer to deal with odd recovered message lengths on verification.
  • The 4 DRBGs described in NIST SP 800-90A have been added to the prng package together with SecureRandom builders.
  • DSA version 2 parameter and key generation is now supported in the provider and lightweight API.
  • A new interface Memoable has been added for objects that can copy in and out their state. The digest classes now support this. A special class NonMemoableDigest has been added which hides the Memoable interface where it should not be available.
  • TDEA is now recognised as an alias for DESede.
  • A new package org.bouncycastle.crypto.ec has been introduced to the light wieght API with a range of EC based cryptographic operators.
  • The OpenPGP API now supports password changing on V3 keys if the appropriate PBEKeyEncryptor is used.
  • The OpenPGP API now supports password changing on secret key rings where only the private keys for the subkeys have been exported.
  • Support has been added to the lightweight API for RSA-KEM and ECIES-KEM.
  • Support has been added for NIST SP 800-38D - GMAC to AES and other 128 bit block size algorithms.
  • The org.bouncycastle.crypto.tls package has been extended to support client and server side TLS 1.1.
  • The org.bouncycastle.crypto.tls package has been extended to support client and server side DTLS 1.0.
  • A basic commitment package has been introduced into the lightweight API containing a digest based commitment scheme.

2.1.4 Notes

  • The NTRU implementation has been moved into the org.bouncycastle.pqc package hierarchy.
  • The change to PEMParser to support explicit EC curves is not backward compatible. If you run into a named curve you need to use org.bouncycastle.asn1.x9.ECNamedCurveTable.getByOID() to look the curve up if required.

2.2.1 Version

Release 1.48

2.2.2 Defects Fixed

  • Occasional key compatibility issues in IES due to variable length keys have been fixed.
  • PEMWriter now recognises the new PKCS10CertificationRequest object.
  • The provider implementation for RSA now resets when the init method is called.
  • SignerInformation has been rewritten to better support signers without any associated signed attributes.
  • An issue with an incorrect version number of SignedData associated with the use of SubjectKeyIdentifiers has now been fixed.
  • An issue with the equals() check in BCStrictStyle has been fixed.
  • The BC SSL implementation has been modified to deal with the "Lucky Thirteen" attack.
  • A regression in 1.47 which prevented key wrapping with regular symmetric PBE algorihtms has been fixed.

2.2.3 Additional Features and Functionality

  • IES now supports auto generation of ephemeral keys in both the JCE and the lightweight APIs.
  • A new class PEMParser has been added to return the new CertificateHolder and Request objects introduced recently.
  • An implementation of Password Authenticated Key Exchange by Juggling (J-PAKE) has now been added to the lightweight API.
  • Support has now been added for the DSTU-4145-2002 to the lightweight API and the provider.
  • The BC X509Certificate implementation now provides support for the JCA methods X509Certificate.getSubjectAlternativeNames() and X509Certificate.getIssuerAlternativeNames().
  • PEMReader can now be configured to support different providers for encyrption and public key decoding.
  • Some extra DSA OIDs have been added to the supported list for the provider.
  • The BC provider will now automatically try to interpret other provider software EC private keys. It is no longer necessary to use a KeyFactory for conversion.
  • A new provider, the BCPQ (for BC Post Quantum) provider has been added with support for the Rainbow signature algorithm and the McEliece family of encryption algorithms.
  • Support has been added for the SHA3 family of digests to both the provider and the lightweight API.
  • T61String now uses UTF-8 encoding by default rather than a simple 8 bit transform.

2.3.1 Version

Release 1.47

2.3.2 Defects Fixed

  • OpenPGP ID based certifications now support UTF-8. Note: this may mean that some old certifications no longer validate - if this happens a retry can be added using by converting the ID using Strings.fromByteArray(Strings.toByteArray(id)) - this will strip out the top byte in each character.
  • IPv4/IPv6 parsing in CIDR no longer assumes octet boundaries on a mask.
  • The CRL PKIX routines will now only rebuild the CRL as a last resort when looking for the certificate issuer.
  • The DEK-Info header in PEM generation was lower case. It is now upper case in accordance with RFC 1421.
  • An occasional issue causing an OutOfMemoryException for PGP compressed data generation has now been fixed.
  • An illegal argument exception that could occur with multi-valued RDNs in the X509v3CertificateBuilder has been fixed.
  • Shared secret calculation in IES could occasionally add a leading zero byte. This has been fixed.
  • PEMReader would choke on a private key with an empty password. This has been fixed.
  • The default MAC for a BKS key store was 2 bytes, this has been upgraded to 20 bytes.
  • BKS key store loading no longer freezes on negative iteration counts.
  • A regression in 1.46 which prevented parsing of PEM files with extra text at the start has been fixed.
  • CMS secret key generation now attempts to stop use of invalid lengths with OIDs that predefine a key length.
  • Check of DH parameter L could reject some valid keys. This is now fixed.

2.3.3 Additional Features and Functionality

  • Support is now provided via the RepeatedKey class to enable IV only re-initialisation in the JCE layer. The same effect can be acheived in the light weight API by using null as the key parameter when creating a ParametersWithIV object.
  • CRMF now supports empty poposkInput.
  • The OpenPGP API now supports operator based interfaces for most operations and lightweight implementations have been added for JCE related functionality.
  • JcaSignerId and JceRecipientId will now match on serial number, issuer, and the subject key identifier if it's available.
  • CMS Enveloped and AuthenticatedData now support OriginatorInfo.
  • NTRU encryption and signing is now provided in the lightweight source and the ext version of the provider.
  • There is now API support for Extended Access Control (EAC).
  • The performance of CertPath building and validation has been improved.
  • The TLS Java Client API has been updated to make support for GSI GSSAPI possible.
  • Support for ECDSA_fixed_ECDH authentication has been added to the TLS client.
  • Support for the Features signature sub-packet has been added to the PGP API.
  • The number of lightweight operators for PGP and CMS/SMIME has been increased.
  • Classes involved in CRL manipulation have been rewritten to reduce memory requirements for handling and parsing extremely large CRLs.
  • RFC 5751 changed the definition of the micalg parameters defined in RFC 3851. The SMIMESignedGenerator is now up to date with the latest micalg parameter set and a constructor has been added to allow the old micalg parameter set to be used.
  • An operator based framework has been added for processing PKCS#8 and PKCS#12 files.
  • The J2ME lcrypto release now includes higher level classes for handling PKCS, CMS, CRMF, CMP, EAC, OpenPGP, and certificate generation.

2.3.4 Other notes

Okay, so we have had to do another release. The issue we have run into is that we probably didn't go far enough in 1.46, but we are now confident that moving from this release to 2.0 should be largely just getting rid of deprecated methods. While this release does change a lot it is relatively straight forward to do a port and we have a porting guide which explains the important ones. The area there has been the most change in is the ASN.1 library which was in bad need of a rewrite after 10 years of patching. On the bright side the rewrite did allow us to eliminate a few problems and bugs in the ASN.1 library, so we have some hope anyone porting to it will also have similar benefits. As with 1.46 the other point of emphasis has been making sure interface support is available for operations across the major APIs, so the lightweight API or some local role your own methods can be used instead for doing encryption and signing.

2.4.1 Version

Release 1.46

2.4.2 Defects Fixed

  • An edge condition in ECDSA which could result in an invalid signature has been fixed.
  • Exhaustive testing has been performed on the ASN.1 parser, eliminating another potential OutOfMemoryException and several escaping run time exceptions.
  • BC generated certificates generated different hashCodes from other equivalent implementations. This has been fixed.
  • Parsing an ESSCertIDv2 would fail if the object did not include an IssuerSerialNumber. This has been fixed.
  • DERGeneralizedTime.getDate() would produce incorrect results for fractional seconds. This has been fixed.
  • PSSSigner would produce incorrect results if the MGF digest and content digest were not the same. This has been fixed.

2.4.3 Additional Features and Functionality

  • A null genTime can be passed to TimeStampResponseGenerator.generate() to generate timeNotAvailable error responses.
  • Support has been added for reading and writing of openssl PKCS#8 encrypted keys.
  • New streams have been added for supporting general creation of PEM data, and allowing for estimation of output size on generation. Generators have been added for some of the standard OpenSSL objects.
  • CRL searching for CertPath validation now supports the optional algorithm given in Section 6.3.3 of RFC 5280, allowing the latest CRL to be used for a set time providing the certificate is unexpired.
  • AES-CMAC and DESede-CMAC have been added to the JCE provider.
  • Support for CRMF (RFC 4211) and CMP (RFC 4210) has been added.
  • BufferedBlockCipher will now always reset after a doFinal().
  • Support for CMS TimeStampedData (RFC 5544) has been added.
  • JCE EC keypairs are now serialisable.
  • TLS now supports client-side authentication.
  • TLS now supports compression.
  • TLS now supports ECC cipher suites (RFC 4492).
  • PGP public subkeys can now be separately decoded and encoded.
  • An IV can now be passed to an ISO9797Alg3Mac.

2.4.4 Other notes

Baring security patches we expect 1.46 will be the last of the 1.* releases. The next release of BC will be version 2.0. For this reason a lot of things in 1.46 that relate to CMS have been deprecated and new methods have been added to the CMS and certificate handling APIs which provide greater flexibility in how digest and signature algorithms get used. It is now possible to use the lightweight API or a simple custom API with CMS and for certificate generation. In addition a lot of methods and some classes that were deprecated for reasons of been confusing, or in some cases just plan wrong, have been removed.

So there are four things useful to know about this release:

  • It's not a simple drop in like previous releases, if you wish migrate to it you will need to recompile your application.
  • If you avoid deprecated methods it should be relatively painless to move to version 2.0
  • The X509Name class will utlimately be replacde with the X500Name class, the getInstance() methods on both these classes allow conversion from one type to another.
  • The org.bouncycastle.cms.RecipientId class now has a collection of subclasses to allow for more specific recipient matching. If you are creating your own recipient ids you should use the constructors for the subclasses rather than relying on the set methods inherited from X509CertSelector. The dependencies on X509CertSelector and CertStore will be removed from the version 2 CMS API.

2.5.1 Version

Release 1.45

2.5.2 Defects Fixed

  • OpenPGP now supports UTF-8 in file names for literal data.
  • The ASN.1 library was losing track of the stream limit in a couple of places, leading to the potential of an OutOfMemoryError on a badly corrupted stream. This has been fixed.
  • The provider now uses a privileged block for initialisation.
  • JCE/JCA EC keys are now serialisable.

2.5.3 Additional Features and Functionality

  • Support for EC MQV has been added to the light weight API, provider, and the CMS/SMIME library.

2.5.4 Security Advisory

  • This version of the provider has been specifically reviewed to eliminate possible timing attacks on algorithms such as GCM and CCM mode.

2.6.1 Version

Release 1.44

2.6.2 Defects Fixed

  • The reset() method in BufferedAsymmetricBlockCipher is now fully clearing the buffer.
  • Use of ImplicitlyCA with KeyFactory and Sun keyspec no longer causes NullPointerException.
  • X509DefaultEntryConverter was not recognising telephone number as a PrintableString field. This has been fixed.
  • The SecureRandom in the J2ME was not using a common seed source, which made cross seeeding of SecureRandom's impossible. This has been fixed.
  • Occasional uses of "private final" on methods were causing issues with some J2ME platforms. The use of "private final" on methods has been removed.
  • NONEwithDSA was not resetting correctly on verify() or sign(). This has been fixed.
  • Fractional seconds in a GeneralisedTime were resulting in incorrect date conversions if more than 3 decimal places were included due to the Java date parser. Fractional seconds are now truncated to 3 decimal places on conversion.
  • The micAlg in S/MIME signed messages was not always including the hash algorithm for previous signers. This has been fixed.
  • SignedMailValidator was only including the From header and ignoring the Sender header in validating the email address. This has been fixed.
  • The PKCS#12 keystore would throw a NullPointerException if a null password was passed in. This has been fixed.
  • CertRepMessage.getResponse() was attempting to return the wrong underlying field in the structure. This has been fixed.
  • PKIXCertPathReviewer.getTrustAnchor() could occasionally cause a null pointer exception or an exception due to conflicting trust anchors. This has been fixed.
  • Handling of explicit CommandMap objects with the generation of S/MIME messages has been improved.

2.6.3 Additional Features and Functionality

  • PEMReader/PEMWriter now support encrypted EC keys.
  • BC generated EC private keys now include optional fields required by OpenSSL.
  • Support for PSS signatures has been added to CMS and S/MIME.
  • CMS processing will attempt to recover if there is no AlgorithmParameters object for a provider and use an IvParameterSpec where possible.
  • CertificateID always required a provider to be explicitly set. A null provider is now interpreted as a request to use the default provider.
  • SubjectKeyIdentifier now supports both methods specified in RFC 3280, section 4.2.1.2 for generating the identifier.
  • Performance of GCM mode has been greatly improved (on average 10x).
  • The BC provider has been updated to support the JSSE in providing ECDH.
  • Support for mac lengths of 96, 104, 112, and 120 bits has been added to existing support for 128 bits in GCMBlockCipher.
  • General work has been done on trying to propagate exception causes more effectively.
  • Support for loading GOST 34.10-2001 keys has been improved in the provider.
  • Support for raw signatures has been extended to RSA and RSA-PSS in the provider. RSA support can be used in CMSSignedDataStreamGenerator to support signatures without signed attributes.

2.7.1 Version

Release 1.43

2.7.2 Defects Fixed

  • Multiple countersignature attributes are now correctly collected.
  • Two bugs in HC-128 and HC-256 related to sign extension and byte swapping have been fixed. The implementations now pass the latest ecrypt vector tests.
  • X509Name.hashCode() is now consistent with equals.

2.7.3 Security Advisory

  • The effect of the sign extension bug was to decrease the key space the HC-128 and HC-256 ciphers were operating in and the byte swapping inverted every 32 bits of the generated stream. If you are using either HC-128 or HC-256 you must upgrade to this release.

2.8.1 Version

Release 1.42

2.8.2 Defects Fixed

  • A NullPointer exception which could be result from generating a diffie-hellman key has been fixed.
  • CertPath validation could occasionally mistakenly identify a delta CRL. This has been fixed.
  • '=' inside a X509Name/X509Principal was not being properly escaped. This has been fixed.
  • ApplicationSpecific ASN.1 tags are now recognised in BER data. The getObject() method now handles processing of arbitrary tags.
  • X509CertStoreSelector.getInstance() was not propagating the subjectAlternativeNames attribute. This has been fixed.
  • Use of the BC PKCS#12 implementation required the BC provider to be registered explicitly with the JCE. This has been fixed.
  • OpenPGP now fully supports use of the Provider object.
  • CMS now fully supports use of the Provider object.
  • Multiplication by negative powers of two is fixed in BigInteger.
  • OptionalValidity now encodes correctly.

2.8.3 Additional Features and Functionality

  • Support for NONEwithECDSA has been added.
  • Support for Grainv1 and Grain128 has been added.
  • Support for EAC algorithms has been added to CMS/SMIME.
  • Support for basic CMS AuthenticatedData to the CMS package.
  • Jars are now packaged using pack200 for JDK1.5 and JDK 1.6.
  • ASN1Dump now supports a verbose mode for displaying the contents of octet and bit strings.
  • Support for the SRP-6a protocol has been added to the lightweight API.

2.9.1 Version

Release 1.41

2.9.2 Defects Fixed

  • The GeneralName String constructor now supports IPv4 and IPv6 address parsing.
  • An issue with nested-multiparts with postamble for S/MIME that was causing signatures to fail verification has been fixed.
  • ESSCertIDv2 encoding now complies with RFC 5035.
  • ECDSA now computes correct signatures for oversized hashes when the order of the base point is not a multiple of 8 in compliance with X9.62-2005.
  • J2ME SecureRandom now provides additional protection against predictive and backtracking attacks when high volumes of random data are generated.
  • Fix to regression from 1.38: PKIXCertPathCheckers were not being called on intermediate certificates.
  • Standard name "DiffieHellman" is now supported in the provider.
  • Better support for equality tests for '#' encoded entries has been added to X509Name.

2.9.3 Additional Features and Functionality

  • Camellia is now 12.5% faster than previously.
  • A smaller version (around 8k compiled) of Camellia, CamelliaLightEngine has also been added.
  • CMSSignedData generation now supports SubjectKeyIdentifier as well as use of issuer/serial.
  • A CMSPBE key holder for UTF8 keys has been added to the CMS API.
  • Salt and iteration count can now be recovered from PasswordRecipientInformation.
  • Methods in the OpenPGP, CMS, and S/MIME APIs which previously could only take provider names can now take providers objects as well (JDK1.4 and greater).
  • Support for reading and extracting personalised certificates in PGP Secret Key rings has been added.

2.10.1 Version

Release 1.40

2.10.2 Defects Fixed

  • EAX mode ciphers were not resetting correctly after a doFinal/reset. This has been fixed.
  • The SMIME API was failing to verify doubly nested multipart objects in signatures correctly. This has been fixed.
  • Some boolean parameters to IssuingDistributionPoint were being reversed. This has been fixed.
  • A zero length RDN would cause an exception in an X509Name. This has been fixed.
  • Passing a null to ExtendedPKIXParameters.setTrustedACIssuers() would cause a NullPointerException. This has been fixed.
  • CertTemplate was incorrectly encoding issuer and subject fields when set.
  • hashCode() for X509CertificateObject was very poor. This has been fixed.
  • Specifying a greater than 32bit length for a stream and relying on the default BCPGOutputStream resulted in corrupted data. This has been fixed.
  • PKCS7Padding validation would not fail if pad length was 0. This has been fixed.
  • javax.crypto classes no longer appear in the JDK 1.3 provider jar.
  • Signature creation time was not being properly initialised in new V4 PGP signature objects although the encoding was correct. This has been fixed.
  • The '+' character can now be escaped or quoted in the constructor for X509Name, X509Prinicipal.
  • Fix to regression from 1.38: PKIXCertPathValidatorResult.getPublicKey was returning the wrong public key when the BC certificate path validator was used.

2.10.3 Additional Features and Functionality

  • Galois/Counter Mode (GCM) has been added to the lightweight API and the JCE provider.
  • SignedPublicKeyAndChallenge and PKCS10CertificationRequest can now take null providers if you need to fall back to the default provider mechanism.
  • The TSP package now supports validation of responses with V2 signing certificate entries.
  • Unnecessary local ID attributes on certificates in PKCS12 files are now automatically removed.
  • The PKCS12 store types PKCS12-3DES-3DES and PKCS12-DEF-3DES-3DES have been added to support generation of PKCS12 files with both certificates and keys protected by 3DES.

2.10.4 Additional Notes

  • Due to problems for some users caused by the presence of the IDEA algorithm, an implementation is no longer included in the default signed jars. Only the providers of the form bcprov-ext-*-*.jar now include IDEA.

2.10.1 Version

Release 1.39

2.10.2 Defects Fixed

  • A bug causing the odd NullPointerException has been removed from the LocalizedMessage class.
  • IV handling in CMS for the SEED and Camellia was incorrect. This has been fixed.
  • ASN.1 stream parser now throws exceptions for unterminated sequences.
  • EAX mode was not handling non-zero offsetted data correctly and failing. This has been fixed.
  • The BC X509CertificateFactory now handles multiple certificates and CRLs in streams that don't support marking.
  • The BC CRL implementation could lead to a NullPointer exception being thrown if critical extensions were missing. This has been fixed.
  • Some ASN.1 structures would cause a class cast exception in AuthorityKeyIdentifier. This has been fixed.
  • The CertID class used by the TSP library was incomplete. This has been fixed.
  • A system property check in PKCS1Encoding to cause a AccessControlException under some circumstances. This has been fixed.
  • A decoding issue with a mis-identified tagged object in CertRepMessage has been fixed.
  • \# is now properly recognised in the X509Name class.

2.10.3 Additional Features and Functionality

  • Certifications associated with user attributes can now be created, verified and removed in OpenPGP.
  • API support now exists for CMS countersignature reading and production.
  • The TSP package now supports parsing of responses with V2 signing certificate entries.
  • Lazy evaluation of DER sequences has been introduced to ASN1InputStream to allow support for larger sequences.
  • KeyPurposeId class has been updated for RFC 4945.
  • CertPath processing has been further extended to encompass the NIST CertPath evaluation suite.
  • Initial support has been added for HP_CERTIFICATE_REQUEST in the TLS API.
  • Providers for JDK 1.4 and up now use SignatureSpi directly rather than extending Signature. This is more in track with the way dynamic provider selection now works.
  • PGP example programs now handle blank names in literal data objects.
  • The ProofOfPossession class now better supports the underlying ASN.1 structure.
  • Support has been added to the provider for the VMPC MAC.

2.11.1 Version

Release 1.38

2.11.2 Defects Fixed

  • SMIME signatures containing non-standard quote-printable data could be altered by SMIME encryption. This has been fixed.
  • CMS signatures that do not use signed attributes were vulnerable to one of Bleichenbacher's RSA signature forgery attacks. This has been fixed.
  • The SMIMESignedParser(Part) constructor was not producing a content body part that cleared itself after writeTo() as indicated in the JavaDoc. This has been fixed.
  • BCPGInputStream now handles data blocks in the 2**31->2**32-1 range.
  • A bug causing second and later encrypted objects to be ignored in KeyBasedFileProcessor example has been fixed.
  • Value of the TstInfo.Tsa field is now directly accessible from TimeStampTokenInfo.
  • Generating an ECGOST-3410 key using an ECGenParameterSpec could cause a ClassCastException in the key generator. This has been fixed.
  • Use of the parameters J and L in connection with Diffie-Hellman parameters in the light weight API was ambiguous and confusing. This has been dealt with.
  • Some entities were not fully removed from a PKCS#12 file when deleted due to case issues. This has been fixed.
  • Overwriting entities in a PKCS#12 file was not fully compliant with the JavaDoc for KeyStore. This has been fixed.
  • TlsInputStream.read() could appear to return end of file when end of file had not been reached. This has been fixed.

2.11.3 Additional Features and Functionality

  • Buffering in the streaming CMS has been reworked. Throughput is now usually higher and the behaviour is more predictable.
  • It's now possible to pass a table of hashes to a CMS detached signature rather than having to always pass the data.
  • Classes supporting signature policy and signer attributes have been added to the ASN.1 ESS/ESF packages.
  • Further work has been done on optimising memory usage in ASN1InputStream. In some cases memory usage has been reduced to 25% of previous.
  • Pre-existing signers can now be added to the SMIMESignedGenerator.
  • Support has been added to the provider for the VMPC stream cipher.
  • CertPathReviewer has better handling for problem trust anchors.
  • Base64 encoder now does initial size calculations to try to improve resource usage.

2.12.1 Version

Release 1.37

2.12.2 Defects Fixed

  • The ClearSignedFileProcessor example for OpenPGP did not take into account trailing white space in the file to be signed. This has been fixed.
  • A possible infinite loop in the CertPathBuilder and SignedMailValidator have been removed.
  • Requesting DES, DESede, or Blowfish keys using regular Diffie-Hellman now returns the same length keys as the regular JCE provider.
  • Some uncompressed EC certificates were being interpreted as compressed and causing an exception. This has been fixed.
  • Adding a CRL with no revocations on it to the CRL generator could cause an exception to be thrown. This has been fixed.
  • Using the default JDK provider with the CMS library would cause exceptions in some circumstances. This has been fixed.
  • BC provider DSAKeys are now serializable.
  • Using only a non-sha digest in S/MIME signed data would produce a corrupt MIME header. This has been fixed.
  • The default private key length in the lightweght API for generated DiffieHellman parameters was absurdly small, this has been fixed.
  • Cipher.getParameters() for PBEwithSHAAndTwofish-CBC was returning null after intialisation. This has been fixed.

2.12.3 Additional Features and Functionality

  • The block cipher mode CCM has been added to the provider and light weight API.
  • The block cipher mode EAX has been added to the provider and light weight API.
  • The stream cipher HC-128 and HC-256 has been added to the provider and lightwieght API.
  • The stream cipher ISAAC has been added to the lightweight API.
  • Support for producing and parsing notation data signature subpackets has been added to OpenPGP.
  • Support for implicit tagging has been added to DERApplicationSpecific.
  • CMS better supports basic Sun provider.
  • A full set of SEC-2 EC curves is now provided in the SEC lookup table.
  • Specifying a null provider in CMS now always uses the default provider, rather than causing an exception.
  • Support has been added to the OpenPGP API for parsing experimental signatures
  • CertPath validator now handles inherited DSA parameters and a wider range of name constraints.
  • Further work has been done on improving the performance of ECDSA - it is now about two to six times faster depending on the curve.
  • The Noekeon block cipher has been added to the provider and the lightweight API.
  • Certificate generation now supports generation of certificates with an empty Subject if the subjectAlternativeName extension is present.
  • The JCE provider now supports RIPEMD160withECDSA.

2.13.1 Version

Release 1.36

2.13.2 Defects Fixed

  • DSA key generator now checks range and keysize.
  • Class loader issues with i18n classes should now be fixed.
  • X.500 name serial number value now output as unambiguous long form SERIALNUMBER
  • The fix for multipart messages with mixed content-transfer-encoding in 1.35 caused a regression for processing some messages with embedded multiparts that contained blank lines of preamble text - this should now be fixed.
  • Another regression which sometimes affected the SMIMESignedParser has also been fixed.
  • SharedFileInputStream compatibility issues with JavaMail 1.4 have been addressed.
  • JDK 1.5 and later KeyFactory now accepts ECPublicKey/ECPrivateKey to translateKey.
  • JDK 1.5 and later KeyFactory now produces ECPublicKeySpec/ECPrivateKeySpec on getKeySpec.
  • Some surrogate pairs were not assembled correctly by the UTF8 decoder. This has been fixed.
  • Alias resolution in PKCS#12 is now case insensitive.

2.13.3 Additional Features and Functionality

  • CMS/SMIME now supports basic EC KeyAgreement with X9.63.
  • CMS/SMIME now supports RFC 3211 password based encryption.
  • Support has been added for certificate, CRL, and certification request generation for the regular SHA algorithms with RSA-PSS.
  • Further work has been done in speeding up prime number generation in the lightweight BigInteger class.
  • Support for the SEED algorithm has been added to the provider and the lightweight API.
  • Support for the Salsa20 algorithm has been added to the provider and the lightweight API.
  • CMS/SMIME now support SEED and Camellia
  • A table of TeleTrusT curves has been added.
  • CMSSignedData creation and Collection CertStore now preserves the order of certificates/CRls if the backing collection is ordered.
  • CMS Signed objects now use BER encoding for sets containing certificates and CRLs, allowing specific ordering to be specified for the objects contained.
  • CMS enveloped now works around providers which throw UnsupportedOperationException if key wrap is attempted.
  • DSASigner now handles long messages. SHA2 family digest support for DSA has been added to the provider.

2.14.1 Version

Release 1.35

2.14.2 Defects Fixed

  • Test data files are no longer in the provider jars.
  • SMIMESignedParser now handles indefinite length data in SignerInfos.
  • Under some circumstances the SMIME library was failing to canonicalize mixed-multipart data correctly. This has been fixed.
  • The l parameter was being ignored for the DH and ElGamal key generation. This has been fixed.
  • The ASN1Sequence constructor for OtherRecipientInfo was broken. It has been fixed
  • Regression - DN fields SerialNumber and Country were changed to encode as UTF8String in 1.34 in the X509DefaultEntryConverter, these now encode as PrintableString.
  • CMSSignedData.replaceSigners() was not replacing the digest set as well as the signers. This has been fixed.
  • DERGeneralizedTime produced a time string without a GMT offset if they represented local time. This has been fixed.
  • Some temp files were still being left on Windows by the SMIME library. All of the known problems have been fixed.
  • Comparing ASN.1 object for equality would fail in some circumstances. This has been fixed.
  • The IESEngine could incorrectly encrypt data when used in block cipher mode. This has been fixed.
  • An error in the encoding of the KEKRecipientInfo has been fixed. Compatability warning: this may mean that versions of BC mail prior to 1.35 will have trouble processing KEK messages produced by 1.35 or later.

2.14.3 Additional Features and Functionality

  • Further optimisations to elliptic curve math libraries.
  • API now incorporates a CertStore which should be suitable for use with LDAP.
  • The streaming ASN.1 API is now integrated into the base one, the sasn1 package has been deprecated.
  • The OpenPGP implementation now supports SHA-224 and BZIP2.
  • The OpenPGP implementation now supports SHA-1 checksumming on secret keys.
  • The JCE provider now does RSA blinding by default.
  • CMSSignedDataParser now provides methods for replacing signers and replacing certificates and CRLs.
  • A generic store API has been added to support CRLs, Certificates and Attribute certificates.
  • The CMS/SMIME API now supports inclusion and retrieval of version 2 attribute certificates.
  • Support for generating CertificationRequests and Certificates has been added for GOST-3410-2001 (ECGOST)
  • CMS/SMIME now support ECGOST
  • Basic BER Octet Strings now encode in a canonical fashion by default.
  • DERUTCTime can now return Date objects
  • Validating constructors have been added to DERPrintableString, DERIA5String, and DERNumericString.
  • A lightweight API for supporting TLS has been added.
  • Implementations of the TEA and XTEA ciphers have been added to the light weight API and the provider.
  • PEMReader now supports OpenSSL ECDSA key pairs.
  • PGP packet streams can now be closed off using close() on the returned stream as well as closing the generator.

2.15.1 Version

Release 1.34

2.15.2 Defects Fixed

  • Endianess of integer conversion in KDF2BytesGenerator was incorrect. This has been fixed.
  • Generating critical signature subpackets in OpenPGP would result in a zero packet tag. This has been fixed.
  • Some flags in PKIFailure info were incorrect, and the range of values was incomplete. The range of values has been increased and the flags corrected.
  • The helper class for AuthorityKeyExtension generation was including the subject rather than the issuer DN of the CA certificate. This has been fixed.
  • SMIMESignedParser now avoids JavaMail quoted-printable recoding issue.
  • Verification of RSA signatures done with keys with public exponents of 3 was vunerable to Bleichenbacher's RSA signature forgery attack. This has been fixed.
  • PGP Identity strings were only being interpreted as ASCII rather than UTF8. This has been fixed.
  • CertificateFactory.generateCRLs now returns a Collection rather than null.

2.15.3 Additional Features and Functionality

  • An ISO18033KDFParameters class had been added to support ISO18033 KDF generators.
  • An implemention of the KDF1 bytes generator algorithm has been added.
  • An implementation of NaccacheStern encryption has been added to the lightweight API.
  • X509V2CRLGenerator can now be loaded from an existing CRL.
  • The CMS enveloped data generators will now attempt to use the default provider for encryption if the passed in provider can only handle key exchange.
  • OpenPGP file processing has been substantially speeded up.
  • The PKCS1Encoder would accept PKCS1 packets which were one byte oversize. By default this will now cause an error. However, as there are still implementations which still produce such packets the older behaviour can be turned on by setting the VM system property org.bouncycastle.pkcs1.strict to false before creating an RSA cipher using PKCS1 encoding.
  • A target has been added to the bc-build.xml to zip up the source code rather than leaving it in a directory tree. The build scripts now run this target by default.
  • Use of toUpperCase and toLowerCase has been replaced with a locale independent converter where appropriate.
  • Support for retrieving the issuers of indirect CRLs has been added.
  • Classes for doing incremental path validation of PKIX cert paths have been added to the X.509 package and S/MIME.
  • Locale issues with String.toUpperCase() have now been worked around.
  • Optional limiting has been added to ASN1InputStream to avoid possible OutOfMemoryErrors on corrupted streams.
  • Support has been added for SHA224withECDSA, SHA256withECDSA, SHA384withECDSA, and SHA512withECDSA for the generation of signatures, certificates, CRLs, and certification requests.
  • Performance of the prime number generation in the BigInteger library has been further improved.
  • In line with RFC 3280 section 4.1.2.4 DN's are now encoded using UTF8String by default rather than PrintableString.

2.15.5 Security Advisory

  • If you are using public exponents with the value three you *must* upgrade to this release, otherwise it will be possible for attackers to exploit some of Bleichenbacher's RSA signature forgery attacks on your applications.

2.16.1 Version

Release 1.33

2.16.2 Defects Fixed

  • OCSPResponseData was including the default version in its encoding. This has been fixed.
  • BasicOCSPResp.getVersion() would throw a NullPointer exception if called on a default version response. This has been fixed.
  • Addition of an EC point under Fp could result in an ArithmeticException. This has been fixed.
  • The n value for prime192v2 was incorrect. This has been fixed.
  • ArmoredInputStream was not closing the underlying stream on close. This has been fixed.
  • Small base64 encoded strings with embedded white space could decode incorrectly using the Base64 class. This has been fixed.

2.16.3 Additional Features and Functionality

  • The X509V2CRLGenerator now supports adding general extensions to CRL entries.
  • A RoleSyntax implementation has been added to the x509 ASN.1 package, and the AttributeCertificateHolder class now support the IssuerSerial option.
  • The CMS API now correctly recognises the OIW OID for DSA with SHA-1.
  • DERUTF8String now supports surrogate pairs.

2.17.1 Version

Release 1.32

2.17.2 Defects Fixed

  • Further work has been done on RFC 3280 compliance.
  • The ASN1Sequence constructor for SemanticsInformation would sometimes throw a ClassCastException on reconstruction an object from a byte stream. This has been fixed.
  • The SharedInputStream.read(buf, 0, len) method would return 0 at EOF, rather than -1. This has been fixed.
  • X9FieldElement could fail to encode a Fp field element correctly. This has been fixed.
  • The streaming S/MIME API was occasionally leaving temporary files around. The SIMEUtil class responsible for creating the files now returns a FileBackedMimeBodyPart object which has a dispose method on it which should allow removal of the file backing the body part.
  • An encoding defect in EnvelopedData generation in the CMS streaming, S/MIME API has been fixed.
  • DER constructed octet strings could cause exceptions in the streaming ASN.1 library. This has been fixed.
  • Several compatibility issues connected with EnvelopedData decoding between the streaming CMS library and other libraries have been fixed.
  • JDK 1.4 and earlier would sometimes encode named curve parameters explicitly. This has been fixed.
  • An incorrect header for SHA-256 OpenPGP clear text signatures has been fixed.
  • An occasional bug that could result in invalid clear text signatures has been fixed.
  • OpenPGP clear text signatures containing '\r' as line separators were not being correctly canonicalized. This has been fixed.

2.17.3 Additional Features and Functionality

  • The ASN.1 library now includes classes for the ICAO Electronic Passport.
  • Support has been added to CMS and S/MIME for ECDSA.
  • Support has been added for the SEC/NIST elliptic curves.
  • Support has been added for elliptic curves over F2m.
  • Support has been added for repeated attributes in CMS and S/MIME messages.
  • A wider range of RSA-PSS signature types is now supported for CRL and Certificate verification.

2.17.4 Possible compatibility issue

  • Previously elliptic curve keys and points were generated with point compression enabled by default. Owing to patent issues in some jurisdictions, they are now generated with point compression disabled by default.

2.18.1 Version

Release 1.31

2.18.2 Defects Fixed

  • getCriticalExtensionOIDs on an X.509 attribute certificate was returning the non-critical set. This has been fixed.
  • Encoding uncompressed ECDSA keys could occasionally introduce an extra leading zero byte. This has been fixed.
  • Expiry times for OpenPGP master keys are now recognised across the range of possible certifications.
  • PGP 2 keys can now be decrypted by the the OpenPGP library.
  • PGP 2 signature packets threw an exception on trailer processing. This has been been fixed.
  • Attempting to retrieve signature subpackets from an OpenPGP version 3 signature would throw a null pointer exception. This has been fixed.
  • Another occasional defect in EC point encoding has been fixed.
  • In some cases AttributeCertificateHolder.getIssuer() would return an empty array for attribute certificates using the BaseCertificateID. This has been fixed.
  • OIDs with extremely large components would sometimes reencode with unnecessary bytes in their encoding. The optimal DER encoding will now be produced instead.

2.18.3 Additional Features and Functionality

  • The SMIME package now supports the large file streaming model as well.
  • Additional ASN.1 message support has been added for RFC 3739 in the org.bouncycastle.x509.qualified package.
  • Support has been added for Mac algorithm 3 from ISO 9797 to both the lightweight APIs and the provider.
  • The provider now supports the DESEDE64 MAC algorithm.
  • CertPathValidator has been updated to better support path validation as defined in RFC 3280.

2.19.1 Version

Release 1.30

2.19.2 Defects Fixed

  • Whirlpool was calculating the wrong digest for 31 byte data and could throw an exception for some other data lengths. This has been fixed.
  • AlgorithmParameters for IVs were returning a default of RAW encoding of the parameters when they should have been returning an ASN.1 encoding. This has been fixed.
  • Base64 encoded streams without armoring could cause an exception in PGPUtil.getDecoderStream(). This has been fixed.
  • PGPSecretKey.copyWithNewPassword() would incorrectly tag sub keys. This has been fixed.
  • PGPSecretKey.copyWithNewPassword() would not handle the NULL algorithm. This has been fixed.
  • Directly accessing the dates on an X.509 Attribute Certificate constructed from an InputStream would return null, not the date objects. This has been fixed.
  • KEKIdentifier would not handle OtherKeyAttribute objects correctly. This has been fixed.
  • GetCertificateChain on a PKCS12 keystore would return a single certificate chain rather than null if the alias passed in represented a certificate not a key. This has been fixed.

2.19.3 Additional Features and Functionality

  • RSAEngine no longer assumes keys are byte aligned when checking for out of range input.
  • PGPSecretKeyRing.removeSecretKey and PGPSecretKeyRing.insertSecretKey have been added.
  • There is now a getter for the serial number on TimeStampTokenInfo.
  • Classes for dealing with CMS objects in a streaming fashion have been added to the CMS package.
  • PGPCompressedDataGenerator now supports partial packets on output.
  • OpenPGP Signature generation and verification now supports SHA-256, SHA-384, and SHA-512.
  • Both the lightweight API and the provider now support the Camellia encryption algorithm.

2.20.1 Version

Release 1.29

2.20.2 Defects Fixed

  • HMac-SHA384 and HMac-SHA512 were not IETF compliant. This has been fixed.
  • The equals() method on ElGamalKeyParameters and DHKeyParameters in the lightweight API would sometimes return false when it should return true. This has been fixed.
  • Parse error for OpenSSL style PEM encoded certificate requests in the PEMReader has been fixed.
  • PGPPublicKey.getValidDays() now checks for the relevant signature for version 4 and later keys as well as using the version 3 key valid days field.
  • ISO9796 signatures for full recovered messsages could incorrectly verify for similar messages in some circumstances. This has been fixed.
  • The occasional problem with decrypting PGP messages containing compressed streams now appears to be fixed.

2.20.3 Additional Features and Functionality

  • Support has been added for the OIDs and key generation required for HMac-SHA224, HMac-SHA256, HMac-SHA384, and HMac-SHA512.
  • SignerInformation will used default implementation of message digest if signature provider doesn't support it.
  • The provider and the lightweight API now support the GOST-28147-94 MAC algorithm.
  • Headers are now settable for PGP armored output streams.

2.20.4 Notes

  • The old versions of HMac-SHA384 and HMac-SHA512 can be invoked as OldHMacSHA384 and OldHMacSHA512, or by using the OldHMac class in the lightweight API.

2.21.1 Version

Release 1.28

2.21.2 Defects Fixed

  • Signatures on binary encoded S/MIME messages could fail to validate when correct. This has been fixed.
  • getExtensionValue() on CRL Entries were returning the encoding of the inner object, rather than the octet string. This has been fixed.
  • CertPath implementation now returns an immutable list for a certificate path.
  • Generic sorting now takes place in the CertificateFactory.generateCertPath() rather than CertPathValidator.
  • DERGeneralizedTime can now handle time strings with milli-seconds.
  • Stateful CertPathCheckers were not being initialised in all cases, by the CertPathValidator. This has been fixed.
  • PGPUtil file processing methods were failing to close files after processing. This has been fixed.
  • A disordered set in a CMS signature could cause a CMS signature to fail to validate when it should. This has been fixed.
  • PKCS12 files where both the local key id and friendly name were set on a certificate would not parse correctly. This has been fixed.
  • Filetype for S/MIME compressed messages was incorrect. This has been fixed.
  • BigInteger class can now create negative numbers from byte arrays.

2.21.3 Additional Features and Functionality

  • S/MIME now does canonicalization on non-binary input for signatures.
  • Micalgs for the new SHA schemes are now supported.
  • Provided and lightweight API now support ISO 7816-4 padding.
  • The S/MIME API now directly supports the creation of certificate management messages.
  • The provider and the light weight API now support the cipher GOST-28147, the signature algorithms GOST-3410 (GOST-3410 94) and EC GOST-3410 (GOST-3410 2001), the message digest GOST-3411 and the GOST OFB mode (use GOFB).
  • CMSSignedDataGenerator will used default implementation of message digest if signature provider doesn't support it.
  • Support has been added for the creation of ECDSA certificate requests.
  • The provider and the light weight API now support the WHIRLPOOL message digest.

2.21.4 Notes

  • Patches for S/MIME binary signatures and canonicalization were actually applied in 1.27, but a couple of days after the release - if the class CMSProcessableBodyPartOutbound is present in the package org.bouncycastle.mail.smime you have the patched 1.27. We would recommend upgrading to 1.28 in any case as some S/MIME 3.1 recommendations have also been introduced for header creation.
  • GOST private keys are probably not encoding correctly and can be expected to change.

2.22.1 Version

Release 1.27

2.22.2 Defects Fixed

  • Typos in the provider which pointed Signature algorithms SHA256WithRSA, SHA256WithRSAEncryption, SHA384WithRSA, SHA384WithRSAEncryption, SHA512WithRSA, and SHA512WithRSAEncryption at the PSS versions of the algorithms have been fixed. The correct names for the PSS algorithms are SHA256withRSAandMGF1, SHA384withRSAandMGF1, and SHA512withRSAandMGF1.
  • X509CertificateFactory failed under some circumstances to reset properly if the input stream being passed to generateCertificate(s)() changed, This has been fixed.
  • OpenPGP BitStrength for DSA keys was being calculated from the key's generator rather than prime. This has been fixed.
  • Possible infinite loop in ASN.1 SET sorting has been removed.
  • SHA512withRSAandMGF1 with a zero length salt would cause an exception if used with a 1024 bit RSA key. This has been fixed.
  • Adding an Exporter to a PGPSubpacketVector added a Revocable instead. This has been fixed.
  • AttributeCertificateIssuer.getPrincipal() could throw an ArrayStoreException. This has been fixed.
  • CertPathValidator now guarantees to call any CertPathCheckers passed in for each certificate.
  • TSP TimeStampToken was failing to validate time stamp tokens with the issuerSerial field set in the ESSCertID structure. This has been fixed.
  • Path validation in environments with frequently updated CRLs could occasionally reject a valid path. This has been fixed.

2.22.3 Additional Features and Functionality

  • Full support has been added for the OAEPParameterSpec class to the JDK 1.5 povider.
  • Full support has been added for the PSSParameterSpec class to the JDK 1.4 and JDK 1.5 providers.
  • Support for PKCS1 signatures for SHA-256, SHA-384, and SHA-512 has been added to CMS.
  • PGPKeyRingCollection classes now support partial matching of user ID strings.
  • This release disables the quick check on the IV for a PGP public key encrypted message in order to help prevent applications being vunerable to oracle attacks.
  • The CertPath support classes now support PKCS #7 encoding.
  • Point compression can now be turned off when encoding elliptic curve keys.

2.22.4 Changes that may affect compatibility

  • org.bouncycastle.jce.interfaces.ElGamalKey.getParams() has been changed to getParameters() to avoid clashes with a JCE interface with the same method signature.
  • org.bouncycastle.jce.interfaces.ECKey.getParams() has been changed in JDK 1.5 to getParameters() to avoid clashes with a JCE interface with the same method signature. The getParams() method in pre-1.5 has been deprecated.
  • SHA256WithRSAEncryption, SHA384WithRSAEncryption, SHA512WithRSAEncryption now refer to their PKCS #1 V1.5 implementations. If you were using these previously you should use SHA256WithRSAAndMGF1, SHA384WithRSAAndMGF1, or SHA512WithRSAAndMGF1.

2.23.1 Version

Release 1.26

2.23.2 Defects Fixed

  • The X.509 class UserNotice assumed some of the optional fields were not optional. This has been fixed.
  • BCPGInputStream would break on input packets of 8274 bytes in length. This has been fixed.
  • Public key fingerprints for PGP version 3 keys are now correctly calculated.
  • ISO9796-2 PSS would sometimes throw an exception on a correct signature. This has been fixed.
  • ASN1Sets now properly sort their contents when created from scratch.
  • A bug introduced in the CertPath validation in the last release which meant some certificate paths would validate if they were invalid has been fixed.

2.23.3 Additional Features and Functionality

  • Support for JDK 1.5 naming conventions for OAEP encryption and PSS signing has been added.
  • Support for Time Stamp Protocol (RFC 3161) has been added.
  • Support for Mozilla's PublicKeyAndChallenge key certification message has been added.
  • OpenPGP now supports key rings containing GNU_DUMMY_S2K.
  • Support for the new versions (JDK 1.4 and later) of PBEKeySpec has been added to the providers.
  • PBEWithMD5AndRC2, PBEWithSHA1AndRC2 now generate keys rather than exceptions.
  • The BigInteger implementation has been further optimised to take more advantage of the Montgomery number capabilities.

2.23.4 JDK 1.5 Changes

  • The JDK 1.5 version of the provider now supports the new Elliptic Curve classes found in the java.security packages. Note: while we have tried to preserve some backwards compatibility people using Elliptic curve are likely to find some minor code changes are required when moving code from JDK 1.4 to JDK 1.5 as the java.security APIs have changed.

2.24.1 Version

Release 1.25

2.24.2 Defects Fixed

  • In some situations OpenPGP would overread when a stream had been broken up into partial blocks. This has been fixed.
  • Explicitly setting a key size for RC4 in the CMS library would cause an exception. This has been fixed.
  • getSignatures() on PGPPublicKey would throw a ClassCastException in some cases. This has been fixed.
  • Encapsulated signed data was been generated with the wrong mime headers, this has been fixed.
  • The isSignature method on PGPSecretKey now correctly identifies signing keys.
  • An interoperability issue with DH key exchange between the Sun JCE provider and the BC provider, concerning sign bit expansion, has been fixed.
  • The X509CertificateFactory would fail to reset correctly after reading an ASN.1 certificate chain. This has been fixed.
  • CertPathValidator now handles unsorted lists of certs.
  • The PGPSignatureGenerator would sometimes throw an exception when adding hashed subpackets. This has been fixed.
  • Ordered equality in X509Name was not terminating as early as possible. This has been fixed.
  • getBitStrength for PGPPublicKeys was returning the wrong value for ElGamal keys. This has been fixed.
  • getKeyExpirationTime/getSignatureExpirationTime was returning a Date rather than a delta. This isn't meaningful as a Date and has been changed to a long.
  • the crlIssuer field in DistributionPoint name was encoding/decoding incorrectly. This has been fixed.
  • X509Name now recognises international characters in the input string and stores them as BMP strings.
  • Parsing a message with a zero length body with SMIMESigned would cause an exception. This has been fixed.
  • Some versions of PGP use zeros in the data stream rather than a replication of the last two bytes of the iv as specified in the RFC to determine if the correct decryption key has been found. The decryption classes will now cope with both.

2.24.3 Additional Features and Functionality

  • Support for extracting signatures based on PGP user attributes has been added to PGPPublicKey.
  • BCPGArmoredInputStream should cope with plain text files better.
  • The OpenPGP library can now create indefinite length streams and handle packets greater than (2^32 - 1) in length.
  • Direct support for adding SignerUserID and PrimaryUserID has been added to the PGPSignatureSubpacketGenerator.
  • Support for ISO-9796-2/PSS has been added to the lightweight API.
  • API support for extracting recovered messages from signatures that support message recovery has been added to the lightweight API.
  • String value conversion in a DN being processed by X509Name is now fully configurable.
  • It is now possible to create new versions of CMSSignedData objects without having to convert the original object down to its base ASN.1 equivalents.
  • Support for adding PGP revocations and other key signatures has been added.
  • Support for SHA-224 and SHA224withRSA has been added.
  • Trailing bit complement (TBC) padding has been added.
  • OID components of up to 2^63 bits are now supported.

2.25.1 Version

Release 1.24

2.25.2 Defects Fixed

  • OpenPGP Secret key rings now parse key rings with user attribute packets in them correctly.
  • OpenPGP Secret key rings now parse key rings with GPG comment packets in them.
  • X509Name and X509Principal now correctly handle BitStrings.
  • OpenPGP now correctly recognises RSA signature only keys.
  • When re-encoding PGP public keys taken off secret keys getEncoded would sometimes throw a NullPointerException. This has been fixed.
  • A basic PKCS12 file with a single key and certificate, but no attributes, would cause a null pointer exception. This has been fixed.
  • Signature verification now handles signatures where the parameters block is missing rather than NULL.
  • Lightweight CBCBlockCipherMac was failing to add padding if padding was being explicitly provided and data length was a multiple of the block size. This has been fixed.
  • ZIP compression in PGP was failing to compress data in many cases. This has been fixed.
  • Signatures were occasionally produced with incorrect padding in their associated bit strings, this has been fixed.
  • An encoding error introduced in 1.23 which affected generation of the KeyUsage extension has been fixed.

2.25.3 Additional Features and Functionality

  • PKCS12 keystore now handles single key/certificate files without any attributes present.
  • Support for creation of PGPKeyRings incorporating sub keys has been added.
  • ZeroPadding for encrypting ASCII data has been added.

2.26.1 Version

Release 1.23

2.26.2 Defects Fixed

  • Reading a PGP Secret key file would sometimes cause a class cast exception. This has been fixed.
  • PGP will now read SecretKeys which are encrypted with the null algorithm.
  • PGP ObjectFactory will recognise Marker packets.
  • BasicConstraints class now handles default empty sequences correctly.
  • S2K Secret Key generation now supported in OpenPGP for keys greater than 160 bits, a bug causing it to occasionally generate the wrong key has been fixed.
  • OpenPGP implementation can now read PGP 8 keys.
  • Decoding issues with Secret Sub Keys should now be fixed.
  • PGP would occasionally unpack ElGamal encrypted data incorrectly, this has been fixed.
  • OCSP TBSRequest now uses abbreviated encoding if the default version is used.
  • X509Name class will now print names with nested pairs in component sets correctly.
  • RC4 now resets correctly on doFinal.

2.26.3 Additional Features and Functionality

  • PGP V3 keys and V3 signature generation is now supported.
  • Collection classes have been added for representing files of PGP public and secret keys.
  • PEMReader now supports "RSA PUBLIC KEY".
  • RipeMD256 and RipeMD320 have been added.
  • Heuristic decoder stream has been added to OpenPGP which "guesses" how the input is constructed.
  • ArmoredInputStream now recognises clear text signed files.
  • ArmoredOutputStream now provides support for generating clear text signed files.
  • Support has been added to CMS for RipeMD128, RipeMD160, and RipeMD256.
  • Support for generating certification directly and editing PGP public key certifications has been added.
  • Support has been added for modification detection codes to the PGP library.
  • Examples have been rewritten to take advantage of the above.
  • SMIMESigned can now covert data straight into a mime message.
  • DERGeneralizedTime getTime() method now handles a broader range of input strings.

2.27.1 Version

Release 1.22

2.27.2 Defects Fixed

  • Generating DSA signatures with PGP would cause a class cast exception, this has been fixed.
  • PGP Data in the 192 to 8383 byte length would sometimes be written with the wrong length header. This has been fixed.
  • The certificate factory would only parse the first certificate in a PKCS7 object. This has been fixed.
  • getRevocationReason() in RevokedStatus in OCSP would throw an exception for a non-null reason, rather than a null one. This has been fixed.
  • PSS signature verification would fail approximately 0.5 % of the time on correct signatures. This has been fixed.
  • Encoding of CRL Distribution Points now always works.

2.27.3 Additional Features and Functionality

  • Additional methods for getting public key information have been added to the PGP package.
  • Some support for user attributes and the image attribute tag has been added.
  • Support for the AuthorityInformationAccess extension has been added.
  • Support for ElGamal encryption/decryption has been added to the PGP package.

2.28.1 Version

Release 1.21

2.28.2 Defects Fixed

  • The CertPath validator would fail for some valid CRLs. This has been fixed.
  • AES OIDS for S/MIME were still incorrect, this has been fixed.
  • The CertPathBuilder would sometimes throw a NullPointerException looking for an issuer. This has been fixed.
  • The J2ME BigInteger class would sometimes go into an infinite loop generating prime numbers. This has been fixed.
  • DERBMPString.equals() would throw a class cast exception. This has been fixed.

2.28.3 Additional Features and Functionality

  • PEMReader now handles public keys.
  • OpenPGP/BCPG should now handle partial input streams. Additional methods for reading subpackets off signatures.
  • The ASN.1 library now supports policy qualifiers and policy info objects.

2.29.1 Version

Release 1.20

2.29.2 Defects Fixed

  • BigInteger toString() in J2ME/JDK1.0 now produces same output as the Sun one.
  • RSA would throw a NullPointer exception with doFinal without arguments. This has been fixed.
  • OCSP CertificateID would calculate wrong issuer hash if issuer cert was not self signed. This has been fixed.
  • Most of response generation in OCSP was broken. This has been fixed.
  • The CertPath builder would sometimes go into an infinite loop on some chains if the trust anchor was missing. This has been fixed.
  • AES OIDS were incorrect, this has been fixed.
  • In some cases BC generated private keys would not work with the JSSE. This has been fixed.

2.29.3 Additional Features and Functionality

  • Support for reading/writing OpenPGP public/private keys and OpenPGP signatures has been added.
  • Support for generating OpenPGP PBE messages and public key encrypted messages has been added.
  • Support for decrypting OpenPGP messages has been added.
  • Addition of a Null block cipher to the light weight API.

2.30.1 Version

Release 1.19

2.30.2 Defects Fixed

  • The PKCS12 store would throw an exception reading PFX files that had attributes with no values. This has been fixed.
  • RSA Private Keys would not serialise if they had PKCS12 bag attributes attached to them, this has been fixed.
  • GeneralName was encoding OtherName as explicitly tagged, rather than implicitly tagged. This has been fixed.
  • ASN1 parser would sometimes mistake an implicit null for an implicit empty sequence. This has been fixed.

2.30.3 Additional Features and Functionality

  • S/MIME and CMS now support the draft standard for AES encryption.
  • S/MIME and CMS now support setable key sizes for the standard algorithms.
  • S/MIME and CMS now handle ARC4/RC4 encrypted messages.
  • The CertPath validator now passes the NIST test suite.
  • A basic OCSP implementation has been added which includes request generation and the processing of responses. Response generation is also provided, but should be treated as alpha quality code.
  • CMS now attempts to use JCA naming conventions in addition to the OID name in order to find algorithms.

2.31.1 Version

Release 1.18

2.31.2 Defects Fixed

  • DESKeySpec.isParityAdjusted in the clean room JCE could go into an infinite loop. This has been fixed.
  • The SMIME API would end up throwing a class cast exception if a MimeBodyPart was passed in containing a MimeMultipart. This is now fixed.
  • ASN1InputStream could go into an infinite loop reading a truncated input stream. This has been fixed.
  • Seeding with longs in the SecureRandom for the J2ME and JDK 1.0, only used 4 bytes of the seed value. This has been fixed.

2.31.3 Additional Features and Functionality

  • The X.509 OID for RSA is now recognised by the provider as is the OID for RSA/OAEP.
  • Default iv's for DES are now handled correctly in CMS.
  • The ASN.1 classes have been updated to use the generic ASN1* classes where possible.
  • A constructor has been added to SMIMESigned to simplify the processing of "application/pkcs7-mime; smime-type=signed-data;" signatures.
  • Diffie-Hellman key generation is now faster in environments using the Sun BigInteger library.

2.32.1 Version

Release 1.17

2.32.2 Defects Fixed

  • Reuse of an CMSSignedObject could occasionally result in a class cast exception. This has been fixed.
  • The X.509 DistributionPointName occasionally encoded incorrectly. This has been fixed.
  • BasicConstraints construction would break if an ASN.1 sequence was used with only the required parameter. This has been fixed.
  • The DERObject constructor in OriginatorIdentifierOrKey was leaving the id field as null. This has been fixed.

2.32.2 Additional Functionality and Features

  • RC2 now supports the full range of parameter versions and effective key sizes.
  • CompressedData handling has been added to CMS/SMIME.
  • The 1.4 version now allows X500Principles to be generated directly from CRLs.
  • SMIME objects now support binary encoding. The number of signature types recognised has been increased.
  • CMS can create signed objects with encapsulated data. Note: while this was been done we realised we could simplify things, we did and for the most part people won't notice, other than the occasional reference to CMSSignable will need to be replaced with CMSProcessable.
  • X509Name and X509Principal now support forward and reverse X509Name to string conversion, with changeable lookup tables for converting OIDs into strings. Both classes also now allow the direction of encoding to be set when a string is converted as well as changeable lookup tables for string to OID conversion.

2.33.1 Version

Release 1.16

2.33.2 Defects Fixed

  • CRLS were only working for UTC time constructed Time objects, this has been fixed.
  • KeyUsage and ReasonFlags sometimes encoded longer than necessary. This has been fixed.
  • BER encoded sets are now recognised and dealt with.
  • Encoding issues in CMS which were causing problems with backwards compatibility with older CMS/SMIME clients have been fixed.
  • KeyFactory now allows for creation of RSAKey*Spec classes.
  • The X509CertSelector in the clean room CertPath API is now less likely to throw a NullPointerException at the wrong time.
  • Macs now clone correctly in the clean room JCE.

2.33.3 Additional Functionality and Features

  • PGPCFB support has been added to the provider and the lightweight API.
  • There are now three versions of the AESEngine, all faster than before, with the largest footprint one being the fastest. The JCE AES now refers to the fastest.
  • The 1.4 version of the library now allows for X500Principals to be generated directly from certificates.
  • X509Name has been extended to parse numeric oids, "oid." oids, and to recognise the LDAP UID.
  • Immutable sequences and sets have been introduced to the ASN.1 package.
  • The SMIME/CMS ASN.1 base classes have been rewritten to reduce the size of the package for use with the lightweight API.
  • The SMIME/CMS api's have been rewritten to allow them to take advantage of the Cert Path API, remove code suited to inclusion in the provider, and to support multiple recipients/signers.

2.34.1 Version

Release 1.15

2.34.2 Defects Fixed

  • The base string for the oids in asn1.x509.KeyPurposeId was incorrect. This has been fixed.
  • MimeBodyParts in the SMIME Generator did not have their Content-Type properly set up after decryption. This has been fixed.
  • If a X.509 certificate did not have all the keyUsage extension bits set, the provider wasn't padding the return value of the key usage extension to 8 booleans in length. This has been fixed.
  • In some cases the simple BC keystore allowed overwriting of an alias with one of the same name. This has been fixed.
  • The key schedule for RC5-64 was not always being calculated correctly. This has been fixed.
  • On reset buffered blockcipher was only partially erasing the previous buffer. This has been fixed.
  • All lightweight mac classes now do a reset on doFinal.
  • ASN.1 object identifiers wouldn't encode the first byte correctly if the OID started with 2 and the second number was greater than 47. This has been fixed.
  • If a key had PKCS9 attributes associated with it on storage they took precedence over the local alias used to add the key to the PKCS12 key store. The local name now takes precedence.
  • ReasonFlags now correctly encodes.

2.34.3 Additional Functionality and Features

  • The PKCS12 key store now handles key bags in encryptedData bags.
  • The X509NameTokenizer now handles for '\' and '"' characters.
  • SMIME v2 compliance has been added. Use setVersion(2) in the generator classes.
  • The ASN.1 library now supports ENUMERATED, UniversalString and the X.509 library support for CRLs now includes CRLReason, and some elements of CertificatePolicies.
  • Both the provider and the lightweight library now support a basic SIC mode for block ciphers.

2.35.1 Version

Release 1.14

2.35.2 Defects Fixed

  • there was a bug in the BigInteger right shifting for > 31 bit shifts. This has been fixed.
  • x509 name had it's equality test based on the order of the directory elements, this has been fixed.
  • the mode used with the RSA cipher in KeyTransRecipientInfoParser in the smime implementation was not compatible with the Sun JCE. This has been fixed.
  • PKCS7 SignedData now supports single length signing chains.
  • When a root certificate had a different issuer id from the subject id, or had it's own AuthorityKeyExtension the PKCS12 key store would drop the root certificate from the certificate chain. This has been fixed.
  • The PKCS10 CertificationRequestInfo class always expected at least one attribute. This has been fixed.
  • UTF8 strings are now correctly recognised.
  • The Tiger implementation was producing results in reverse byte order for each of the 3 words making up the digest. This has been fixed.
  • asn1.x509.ExtendedKeyUsage used to through a null pointer exception on construction. This has been fixed.

2.35.3 Additional Functionality and Features

  • The BigInteger library now uses Montgomery numbers for modPow and is substantially faster.
  • SMIMECapabilities, and SMIMEEncryptionKeyPreference attributes added to S/MIME.
  • Increased range of key sizes available in S/MIME.
  • getInstance(ASN1TaggedObject, boolean) methods have been added to most ASN1 types. These deal with implicit/explicit tagging ambiguities with constructed types.
  • Added EncryptedPrivateKeyInfo object to the clean room JCE.
  • A PEMReader has been added for handling some of the openSSL PEM files.
  • The X.509 certificate factory supports a wider range of encodings and object identifiers.

2.36.1 Version

Release 1.13

2.36.2 Defects Fixed

  • The TBSCertificate object in the ASN.1 library now properly implements the Time object, rather returning UTC time.
  • The DESedeKeyGenerator now supports 112 and 168 bit key generation.
  • Certificates with the keyId set to null in the AuthorityKeyIdentifier extensions would sometimes cause the PKCS12 store to throw a NullPointer exception. This has been fixed.
  • toByteArray in the big integer class was not always producing correct results for negative numbers. This has been Fixed.

2.36.3 Additional Functionality and Features

  • The key to keySpec handling of the secret key factories has been improved.
  • There is now a SMIME implementation and a more complete CMS implementation (see CONTRIBUTORS file for additonal details).
  • A CertPath implementation that runs under jdk1.1 and jdk1.4 has also being contributed. A work around to allow it to be used with jdk1.2 and jdk1.3 has also been added. Note: the implementation is not quite complete because policymapping, name and subtree constraints are not yet implemented.
  • The API now supports the generation of PKCS7 signed objects. Note: this is still beta code - one known issue is that it doesn't support single length certificate chains for signing keys.

2.37.1 Version

Release 1.12

2.37.2 Defects Fixed

  • The ASN.1 library was unable to read an empty set object. This has been fixed.
  • Returning sets of critical and non-critical extensions on X.509 certificates could result in a null pointer exception if the certificate had no extensions. This has been fixed.
  • The BC JKS implementation does not follow the conventional one - it has been renamed BKS, an attempt to create a JKS keystore using the BC provider will now result in an exception.
  • The PKCS 10 generator verify(provider) method was ignoring the provider when generating the public key. This has been fixed.
  • The PKCS12 store would throw an OutOfMemoryException if passed a non-PKCS12 file. This has been fixed.
  • In the case where there was no AuthorityKeyIdentifier the PKCS12 store would fail to find certificates further up the signing chain. The store now uses the IssuerDN if no AuthorityKeyIdentifier is specified and the IssuerDN is different from the SubjectDN,
  • PKCS10/CertificationRequestInfo objects with only a single attribute wer not being handled properly. This has been fixed.
  • getExtensionValue for X.509 CRLs was returning the value of the DER-Encoded octet string not the DER-Encoded octet string as required. This has been fixed.
  • the IV algorithm parameters class would improperly throw an exception on initialisation. This has been fixed.

2.37.3 Additional Functionality and Features

  • The AESWrap ciphers will now take IV's.
  • The DES-EDEWrap algorithm described in http://www.ietf.org/internet-drafts/draft-ietf-smime-key-wrap-01.txt is now supported.
  • Support for the ExtendedKeyUsageExtension and the KeyPurposeId has been added.
  • The OID based alias for DSA has been added to the JCE provider.
  • BC key stores now implement the BCKeyStore interface so you can provide your own source of randomness to a key store.
  • The ASN.1 library now supports GeneralizedTime.
  • HMACSHA256, HMACSHA384, and HMACSHA512 are now added.
  • PSS has been added to the JCE, PSS and ISO9796 signers in the lightweight api have been rewritten so they can be used incrementally. SHA256withRSA, SHA384withRSA, and SHA512withRSA have been added.
  • Base support for CMS (RFC 2630) is now provided (see CONTRIBUTORS file for details).

2.38.1 Version

Release 1.11

2.38.2 Defects Fixed

  • X9.23 padding of MACs now works correctly with block size aligned data.
  • Loading a corrupted "UBER" key store would occasionally cause the appearance of hanging. This has been fixed.
  • Loading a PKCS12 store where not all certificates had PKCS9 attributes assigned to them would cause a NullPointerException. This has been fixed.
  • The PKCS12 store wasn't correctly recovering certificate chains of length less than 2 on calling the getCertificateChain method. This has been fixed.
  • Lone certificates were not been stored in the PKCS12 store. This has been fixed.
  • CFB and OFB modes weren't padding iv's more than 1 byte less than the block size of the cipher if the mode was reused with a shorter IV. This has been fixed.
  • IV handling and block size return values for CFB and OFB modes wasn't being handled in the same way as the Sun reference implementation. This has been fixed.
  • CertificateInfoRequests were not handling null attributes correctly. This has been fixed.
  • Tags for the X.509 GeneralName structure were wrongly encoded. This has been fixed.
  • getExtensionValue for X.509 certificates was returning the value of the DER-Encoded octet string not the DER-Encoded octet string as required. This has been fixed.
  • reset on the version 3 X.509 certificate generator was not flushing the extensions. This has been fixed.
  • The NetscapeCert type bits were reversed! This has been fixed.

2.38.3 Additional Functionality and Features

  • The lightweight API and the JCE provider now support ElGamal.
  • X509Principal, and X509Name now supports the "DC" attribute and the creation of directory names from vectors.
  • RSA-PSS signature padding has been added to the lightweight API.
  • EC Public/Private keys are now encoded in accordance with SEC 1. The library will still read older keys as well.
  • Added PKCS12-DEF a pkcs12 based key store which works around a bug in the Sun keytool - it always uses the default provider for creating certificates.
  • A cut down version of the Rijndael has been added that provides the functionality required to conform the the AES. It is designed to fully support FIPS-197. A fips AES wrapper (AESWrap in the JCE, AESWrapEngine in the lightweight library has also been added).
  • Elliptic curve routines now handle uncompressed points as well as the compressed ones.

2.38.4 Other changes

  • As the range of public key types supported has expanded the getPublicKey method on the SubjectPublicKeyInfo class is not always going to work. The more generic method getPublicKeyData has been added and getPublicKey now throws an IOException if there is a problem.

2.39.1 Version

Release 1.10

2.39.2 Defects Fixed

  • The PKCS12 Key Store now interoperates with the JDK key tool. Note: this does mean the the key name passed to the setKeyEntry calls has become significant.
  • The "int" constructor for DERInteger only supported ints up to 128. This has been fixed.
  • The ASN.1 input streams now handle zero-tagged zero length objects correctly.

2.39.3 Additional Functionality and Features

  • The JCE Provider and the lightweight API now support Serpent, CAST5, and CAST6.
  • The JCE provider and the lightweight API now has an implementation of ECIES. Note: this is based on a draft, don't use it for anything that needs to be kept long term as it may be adjusted.
  • Further work has been done on performance - mainly in the symmetric ciphers.
  • Support for the generation of PKCS10 certification requests has been added.

2.40.1 Version

Release 1.09

2.40.2 Defects Fixed

  • failure to pass in an RC5 parameters object now results in an exception at the upper level of the JCE, rather than falling over in the lightweight library.
  • ISO10126Padding now incorporates the correct amount of random data.
  • The PKCS12 key store wasn't picking up certificate chains properly when being used to write PKCS12 files. This has been fixed.
  • The Twofish engine would call System.exit if the key was too large. This has been fixed.
  • In some cases the ASN.1 library wouldn't handle implicit tagging properly. This has been fixed.

2.40.3 Additional Functionality and Features

  • Support for RC5-64 has been added to the JCE.
  • ISO9796-2 signatures have been added to the JCE and lightweight API.
  • A more general paddings packge for use with MACs and block ciphers had been aded to the lightweight API. MACs now allow you to specify padding.
  • X9.23 Padding has been added to the JCE and lightwieght API. The old PaddedBlockCipher class is now deprecated see org.bouncycastle.crypto.paddings for details.
  • SHA-256, SHA-384, and SHA-512 are now added. Note: while the public review period has finished, these algorithms have not yet been standardised, in the event that final standardisation changes the algorithms these implementations will be changed.
  • It's now possible to set bag attributes on items to go into a PKCS12 store, using the org.bouncycastle.jce.interfaces.PKCS12BagAttributeCarrier interface.
  • More classses have been added to the ASN.1 package for dealing with certificate extensions and CRLs including a CRL generator. Note: the CRL generators should be regarded as under development and subject to change.
  • There's now an examples package for the JCE (in addition to the examples in org.bouncycastle.jce.provider.test) - org.bouncycastle.jce.examples. It currently consists of a class showing how to generate a PKCS12 file.
  • The X.509 CertificateFactory now includes CRL support. DER or PEM CRLs may be processed.
  • The BigInteger library has been written with a view to making it less resource hungry and faster - whether it's fast enough remains to be seen!

2.41.1 Version

Release 1.08

2.41.2 Defects Fixed

  • It wasn't possible to specify an ordering for distinguished names in X509 certificates. This is now supported.
  • In some circumstances stream Ciphers in the JCE would cause null pointer exceptions on doFinal. This has been fixed.
  • Unpadded ciphers would sometimes buffer the last block of input, even if it could be processed. This has been fixed.
  • The netscape certificate request class wouldn't compile under JDK 1.1. This has been fixed.

2.41.3 Additional Functionality and Features

  • ISO 9796-1 padding is now supported with RSA in the lightweight API and the JCE.
  • support classes have been added for reading and writing PKCS 12 files, including a keystore for the JCA.
  • The message digests MD4, Tiger, and RIPEMD128 have been added to the JCE and the lightweight API. Note: MD4 and RIPEMD128 have been added for compatibility purposes only - we recommend you don't use them for anything new!
  • The JDK 1.1 certificate classes didn't conform to the JDK 1.2 API as the collections class was not present. Thanks to a donated collections API this is fixed.

2.42.1 Version

Release 1.07

2.42.2 Defects Fixed

  • It turned out that the setOddParity method in the DESParameter class was indeed doing something odd but not what was intended. This is now fixed. Note:This will affect some PBE encryptions that were carried out with DES, equivalent PBE ciphers to the old PBE DES cipher can be accessed by prepending the work "Broken" in front of the original PBE cipher call. If you want an example of how to deal with this as a migration issue have a look in org.bouncycastle.jce.provider.JDKKeyStore lines 201-291.

2.43.1 Version

Release 1.06

2.43.2 Defects Fixed

  • Diffie-Hellman keys are now properly serialisable as well as encodable.
  • Three of the semi-weak keys in the DESParameters, and the DESKeySpec look up table, were incorrect. This has been fixed.
  • DESEDE key generators now accept 112 and 168 as the key sizes, as well as 128 and 192 (for those people who don't like to count the parity bits).
  • Providing no strength parameter is passed to the DESede key generator in the JCE provider, the provider now generates DESede keys in the k1-k2-k1 format (which is compatible with the Sun reference implementation), otherwise you get what you ask for (3-DES or 2-DES in the minimum number of bytes).
  • Base Diffie-Hellman key agreement now works correctly for more than two parties.
  • Cipher.getAlgorithmParameters was returing null in cases where a cipher object had generated it's own IV. This has been fixed.
  • An error in the key store occasionally caused checks of entry types to result in a null pointer exception. This has been fixed.
  • RSA key generator in JCE now recognises RSAKeyGenerationParameterSpec.
  • Resetting and resusing HMacs in the lightweight and heavyweight libraries caused a NullPointer exception. This has been fixed.

2.43.3 Additional Functionality

  • ISO10126Padding is now recognised explicitly for block ciphers as well.
  • The Blowfish implementation is now somewhat faster.

2.44.1 Version

Release 1.05

2.44.2 Defects Fixed

  • The DESEDE key generator can now be used to generate 2-Key-DESEDE keys as well as 3-Key-DESEDE keys.
  • One of the weak keys in the DESParameters, and the DESKeySpec look up table, was incorrect. This has been fixed.
  • The PKCS12 generator was only generating the first 128-160 bits of the key correctly (depending on the digest used). This has been fixed.
  • The ASN.1 library was skipping explicitly tagged objects of zero length. This has been fixed.

2.44.3 Additional Functionality

  • There is now an org.bouncycastle.jce.netscape package which has a class in for dealing with Netscape Certificate Request objects.

2.44.4 Additional Notes

Concerning the PKCS12 fix: in a few cases this may cause some backward compatibility issues - if this happens to you, drop us a line at feedback-crypto@bouncycastle.org and we will help you get it sorted out.

2.45.1 Version

Release 1.04

2.45.2 Defects Fixed

  • Signatures generated by other providers that include optional null parameters in the AlgorithmIdentifier are now handled correctly by the provider.
  • The JCE 1.2.1 states that the names of algorithms associated with the JCE are case insensitive. The class that matches algorithms to names now tries to match the name given with it's equivalent in upper case, before trying to match it as given. If you write a provider and include versions of your algorithm names in uppercase only, this JCE implementation will always match a getInstance regardless of the case of the algorithm passed into the getInstance method.
  • If the JCE API and the Provider were in a different class path, the class loader being used sometimes failed to find classes for JCE Ciphers, etc. This has been fixed.
  • An error in the ASN.1 library was causing problems serialising Diffie-Hellman keys. This has been fixed.
  • The agreement package was left out of the j2me bat file. This has been fixed.
  • The BigInteger class for 1.0 and the j2me wasn't able to generate random integers (prime or otherwise). This has been fixed.
  • The BigInteger class would sometimes go into a death spiral if the any 32nd bit of an exponent was set when modPow was called. This has been fixed.
  • Cipher.getInstance would treat "//" in a transformation as a single "/". This has been fixed.
  • PBEWithSHAAndIDEA-CBC was throwing an exception on initialisation. This has been fixed.
  • The X509Name class in the asn1.x509 package wasn't initialising its local hash table when the hash table constructor was called. This has been fixed.

2.45.3 Additional Functionality

  • Added Elliptic Curve DSA (X9.62) - ECDSA - to provider and lightweight library.
  • Added Elliptic Curve basic Diffie-Hellman to provider and lightweight library.
  • Added DSA support to the provider and the lightweight library.
  • Added super class interfaces for basic Diffie-Hellman agreement classes to lightweight library.
  • The certificate generators now support ECDSA and DSA certs as well.

2.46.1 Version

Release 1.03

2.46.2 Defects Fixed

  • CFB and OFB modes when specified without padding would insist on input being block aligned. When specified without padding CFB and OFB now behave in a compatible fashion (a doFinal on a partial block will yield just the data that could be processed). In short, it provides another way of generating cipher text the same length as the plain text.

2.47.1 Version

Release 1.02

2.47.2 Defects Fixed

  • The RSA key pair generator occasionally produced keys 1 bit under the requested size. This is now fixed.

2.48.1 Version

Release 1.01

2.48.2 Defects Fixed

  • Buffered ciphers in lightweight library were not resetting correctly on a doFinal. This has been fixed.

2.49.1 Version

Release 1.0

2.49.2 Defects Fixed

  • JDK1.2 version now works with keytool for certificate generation.
  • Certificate toString method no longer throws a null pointer exception if a group [3] extension has not been added.
  • Under some circumstances the NullCipher would throw a NullPointerException, this has been fixed.
  • Under some circumstances CipherInputStream would throw a NullPointerException, this has been fixed.
  • OpenSSL/SSLeay private key encodings would cause an exception to be thrown by the RSA key factory. This is now fixed.
  • The Cipher class always used the default provider even when one was specified, this has been fixed.
  • Some DES PBE algorithms did not set the parity correctly in generated keys, this has been fixed.

2.49.3 Additional functionality

  • Argument validation is much improved.
  • An X509KeyUsage class has been added to the JCE class to make it easier to specify the KeyUsage extension on X.509 certificates.
  • The library now allows creation of version 1 certificates as well.

3.0 Notes

The J2ME is only supported under Windows.

If you are trying to use the lightweight provider in a JDK 1.0 applet, you need to change the package names for java.math.BigInteger, java.lang.IllegalStateException, and java.security.SecureRandom

The RSA test under JDK 1.0 and J2ME takes a while to run... bouncycastle-1.49.orig/crypto_env.properties0000644000175000017500000000105212062253470020736 0ustar ebourgebourg# The location of the J2MEWTK installation for use with # compilation user.j2me.home = /usr/local/var/javamewtk # The top level directory of this project containing all # the src, lib, ... directories user.devel.root = /Users/jon_eaves/coding/bc/java/crypto user.mail.jar = /usr/local/var/javamail/mail.jar user.mailapi.jar = /usr/local/var/javamail/lib/mailapi.jar user.activation.jar = /usr/local/var/jaf/activation.jar user.jcoverage.root = d:/var/jcoverage-1.0.5 # version specific information master.version = 1.48 master.shortver = 148 bouncycastle-1.49.orig/build1-40000644000175000017500000000116011116104575015674 0ustar ebourgebourg#!/bin/sh - # # build script for 1.4 # # If it's given a buildname it creates a subdirectory and places a build in it, # otherwise it just creates the docs and class files. # JDKPATH=/opt/jdk1.4.2 JAVA_MAIL_HOME=/opt/javamail-1.3.1 JAVA_ACTIVATION_HOME=/opt/jaf-1.0.2 JAVA_HOME=$JDKPATH export JAVA_HOME PATH=$JDKPATH/bin:$PATH export PATH CLASSPATH=$JAVA_MAIL_HOME/mail.jar:$JAVA_ACTIVATION_HOME/activation.jar:$CLASSPATH export CLASSPATH if [ "$1" = "test" ] then ant -f jdk14.xml test else if ant -f jdk14.xml build-provider then ant -f jdk14.xml build ant -f jdk14.xml zip-src fi fi bouncycastle-1.49.orig/jdk1.0/0000755000175000017500000000000012152033551015415 5ustar ebourgebourgbouncycastle-1.49.orig/jdk1.0/org/0000755000175000017500000000000012152033551016204 5ustar ebourgebourgbouncycastle-1.49.orig/jdk1.0/org/bouncycastle/0000755000175000017500000000000012152033551020677 5ustar ebourgebourgbouncycastle-1.49.orig/jdk1.0/org/bouncycastle/crypto/0000755000175000017500000000000012152033551022217 5ustar ebourgebourgbouncycastle-1.49.orig/jdk1.0/org/bouncycastle/crypto/encodings/0000755000175000017500000000000012152033551024170 5ustar ebourgebourgbouncycastle-1.49.orig/jdk1.0/org/bouncycastle/crypto/encodings/PKCS1Encoding.java0000644000175000017500000001464011527114060027330 0ustar ebourgebourgpackage org.bouncycastle.crypto.encodings; import org.bouncycastle.crypto.AsymmetricBlockCipher; import org.bouncycastle.crypto.CipherParameters; import org.bouncycastle.crypto.InvalidCipherTextException; import org.bouncycastle.crypto.params.AsymmetricKeyParameter; import org.bouncycastle.crypto.params.ParametersWithRandom; import java.security.SecureRandom; import java.security.AccessController; import java.security.PrivilegedAction; /** * this does your basic PKCS 1 v1.5 padding - whether or not you should be using this * depends on your application - see PKCS1 Version 2 for details. */ public class PKCS1Encoding implements AsymmetricBlockCipher { /** * some providers fail to include the leading zero in PKCS1 encoded blocks. If you need to * work with one of these set the system property org.bouncycastle.pkcs1.strict to false. *

* The system property is checked during construction of the encoding object, it is set to * true by default. *

*/ public static final String STRICT_LENGTH_ENABLED_PROPERTY = "org.bouncycastle.pkcs1.strict"; private static final int HEADER_LENGTH = 10; private SecureRandom random; private AsymmetricBlockCipher engine; private boolean forEncryption; private boolean forPrivateKey; private boolean useStrictLength; /** * Basic constructor. * @param cipher */ public PKCS1Encoding( AsymmetricBlockCipher cipher) { this.engine = cipher; this.useStrictLength = useStrict(); } // // for J2ME compatibility // private boolean useStrict() { // required if security manager has been installed. String strict = System.getProperty(STRICT_LENGTH_ENABLED_PROPERTY); return strict == null || strict.equals("true"); } public AsymmetricBlockCipher getUnderlyingCipher() { return engine; } public void init( boolean forEncryption, CipherParameters param) { AsymmetricKeyParameter kParam; if (param instanceof ParametersWithRandom) { ParametersWithRandom rParam = (ParametersWithRandom)param; this.random = rParam.getRandom(); kParam = (AsymmetricKeyParameter)rParam.getParameters(); } else { this.random = new SecureRandom(); kParam = (AsymmetricKeyParameter)param; } engine.init(forEncryption, param); this.forPrivateKey = kParam.isPrivate(); this.forEncryption = forEncryption; } public int getInputBlockSize() { int baseBlockSize = engine.getInputBlockSize(); if (forEncryption) { return baseBlockSize - HEADER_LENGTH; } else { return baseBlockSize; } } public int getOutputBlockSize() { int baseBlockSize = engine.getOutputBlockSize(); if (forEncryption) { return baseBlockSize; } else { return baseBlockSize - HEADER_LENGTH; } } public byte[] processBlock( byte[] in, int inOff, int inLen) throws InvalidCipherTextException { if (forEncryption) { return encodeBlock(in, inOff, inLen); } else { return decodeBlock(in, inOff, inLen); } } private byte[] encodeBlock( byte[] in, int inOff, int inLen) throws InvalidCipherTextException { if (inLen > getInputBlockSize()) { throw new IllegalArgumentException("input data too large"); } byte[] block = new byte[engine.getInputBlockSize()]; if (forPrivateKey) { block[0] = 0x01; // type code 1 for (int i = 1; i != block.length - inLen - 1; i++) { block[i] = (byte)0xFF; } } else { random.nextBytes(block); // random fill block[0] = 0x02; // type code 2 // // a zero byte marks the end of the padding, so all // the pad bytes must be non-zero. // for (int i = 1; i != block.length - inLen - 1; i++) { while (block[i] == 0) { block[i] = (byte)random.nextInt(); } } } block[block.length - inLen - 1] = 0x00; // mark the end of the padding System.arraycopy(in, inOff, block, block.length - inLen, inLen); return engine.processBlock(block, 0, block.length); } /** * @exception InvalidCipherTextException if the decrypted block is not in PKCS1 format. */ private byte[] decodeBlock( byte[] in, int inOff, int inLen) throws InvalidCipherTextException { byte[] block = engine.processBlock(in, inOff, inLen); if (block.length < getOutputBlockSize()) { throw new InvalidCipherTextException("block truncated"); } byte type = block[0]; if (type != 1 && type != 2) { throw new InvalidCipherTextException("unknown block type"); } if (useStrictLength && block.length != engine.getOutputBlockSize()) { throw new InvalidCipherTextException("block incorrect size"); } // // find and extract the message block. // int start; for (start = 1; start != block.length; start++) { byte pad = block[start]; if (pad == 0) { break; } if (type == 1 && pad != (byte)0xff) { throw new InvalidCipherTextException("block padding incorrect"); } } start++; // data should start at the next byte if (start >= block.length || start < HEADER_LENGTH) { throw new InvalidCipherTextException("no data in block"); } byte[] result = new byte[block.length - start]; System.arraycopy(block, start, result, 0, result.length); return result; } } bouncycastle-1.49.orig/jdk1.0/org/bouncycastle/crypto/test/0000755000175000017500000000000012152033551023176 5ustar ebourgebourgbouncycastle-1.49.orig/jdk1.0/org/bouncycastle/crypto/test/CipherTest.java0000644000175000017500000000131610262753175026127 0ustar ebourgebourgpackage org.bouncycastle.crypto.test; import org.bouncycastle.util.test.SimpleTestResult; import org.bouncycastle.util.test.Test; import org.bouncycastle.util.test.TestResult; /** */ public abstract class CipherTest implements Test { Test[] tests; protected CipherTest( Test[] tests) { this.tests = tests; } public abstract String getName(); public TestResult perform() { for (int i = 0; i != tests.length; i++) { TestResult res = tests[i].perform(); if (!res.isSuccessful()) { return res; } } return new SimpleTestResult(true, getName() + ": Okay"); } } bouncycastle-1.49.orig/jdk1.0/org/bouncycastle/crypto/test/RC4Test.java0000644000175000017500000000301110262753175025277 0ustar ebourgebourgpackage org.bouncycastle.crypto.test; import org.bouncycastle.crypto.engines.RC4Engine; import org.bouncycastle.crypto.params.KeyParameter; import org.bouncycastle.util.encoders.Hex; import org.bouncycastle.util.test.SimpleTestResult; import org.bouncycastle.util.test.Test; import org.bouncycastle.util.test.TestResult; /** * RC4 Test */ public class RC4Test implements Test { StreamCipherVectorTest[] tests = { new StreamCipherVectorTest(0, new RC4Engine(), new KeyParameter(Hex.decode("0123456789ABCDEF")), "4e6f772069732074", "3afbb5c77938280d"), new StreamCipherVectorTest(0, new RC4Engine(), new KeyParameter(Hex.decode("0123456789ABCDEF")), "68652074696d6520", "1cf1e29379266d59"), new StreamCipherVectorTest(0, new RC4Engine(), new KeyParameter(Hex.decode("0123456789ABCDEF")), "666f7220616c6c20", "12fbb0c771276459") }; public String getName() { return "RC4"; } public TestResult perform() { for (int i = 0; i != tests.length; i++) { TestResult res = tests[i].perform(); if (!res.isSuccessful()) { return res; } } return new SimpleTestResult(true, getName() + ": Okay"); } public static void main( String[] args) { RC4Test test = new RC4Test(); TestResult result = test.perform(); System.out.println(result); } } bouncycastle-1.49.orig/jdk1.0/org/bouncycastle/crypto/test/DESedeTest.java0000644000175000017500000000346310262753175026013 0ustar ebourgebourgpackage org.bouncycastle.crypto.test; import org.bouncycastle.crypto.engines.DESedeEngine; import org.bouncycastle.crypto.params.KeyParameter; import org.bouncycastle.util.encoders.Hex; import org.bouncycastle.util.test.Test; import org.bouncycastle.util.test.TestResult; /** * DESede tester */ public class DESedeTest extends CipherTest { static String input1 = "4e6f77206973207468652074696d6520666f7220616c6c20"; static String input2 = "4e6f7720697320746865"; static Test[] tests = { new BlockCipherVectorTest(0, new DESedeEngine(), new KeyParameter(Hex.decode("0123456789abcdef0123456789abcdef")), input1, "3fa40e8a984d48156a271787ab8883f9893d51ec4b563b53"), new BlockCipherVectorTest(1, new DESedeEngine(), new KeyParameter(Hex.decode("0123456789abcdeffedcba9876543210")), input1, "d80a0d8b2bae5e4e6a0094171abcfc2775d2235a706e232c"), new BlockCipherVectorTest(2, new DESedeEngine(), new KeyParameter(Hex.decode("0123456789abcdef0123456789abcdef0123456789abcdef")), input1, "3fa40e8a984d48156a271787ab8883f9893d51ec4b563b53"), new BlockCipherVectorTest(3, new DESedeEngine(), new KeyParameter(Hex.decode("0123456789abcdeffedcba98765432100123456789abcdef")), input1, "d80a0d8b2bae5e4e6a0094171abcfc2775d2235a706e232c") }; DESedeTest() { super(tests); } public String getName() { return "DESede"; } public static void main( String[] args) { DESedeTest test = new DESedeTest(); TestResult result = test.perform(); System.out.println(result); } } bouncycastle-1.49.orig/jdk1.0/org/bouncycastle/crypto/test/BlockCipherVectorTest.java0000644000175000017500000000563110262753175030271 0ustar ebourgebourgpackage org.bouncycastle.crypto.test; import org.bouncycastle.crypto.BlockCipher; import org.bouncycastle.crypto.BufferedBlockCipher; import org.bouncycastle.crypto.CipherParameters; import org.bouncycastle.crypto.CryptoException; import org.bouncycastle.util.encoders.Hex; import org.bouncycastle.util.test.SimpleTestResult; import org.bouncycastle.util.test.Test; import org.bouncycastle.util.test.TestResult; /** * a basic test that takes a cipher, key parameter, and an input * and output string. This test wraps the engine in a buffered block * cipher with padding disabled. */ public class BlockCipherVectorTest implements Test { int id; BlockCipher engine; CipherParameters param; byte[] input; byte[] output; public BlockCipherVectorTest( int id, BlockCipher engine, CipherParameters param, String input, String output) { this.id = id; this.engine = engine; this.param = param; this.input = Hex.decode(input); this.output = Hex.decode(output); } public String getName() { return engine.getAlgorithmName() + " Vector Test " + id; } public TestResult perform() { BufferedBlockCipher cipher = new BufferedBlockCipher(engine); cipher.init(true, param); byte[] out = new byte[input.length]; int len1 = cipher.processBytes(input, 0, input.length, out, 0); try { cipher.doFinal(out, len1); } catch (CryptoException e) { return new SimpleTestResult(false, getName() + ": failed - exception " + e.toString()); } if (!isEqualArray(out, output)) { return new SimpleTestResult(false, getName() + ": failed - " + "expected " + new String(Hex.encode(output), 0) + " got " + new String(Hex.encode(out), 0)); } cipher.init(false, param); int len2 = cipher.processBytes(output, 0, output.length, out, 0); try { cipher.doFinal(out, len2); } catch (CryptoException e) { return new SimpleTestResult(false, getName() + ": failed reversal - exception " + e.toString()); } if (!isEqualArray(input, out)) { return new SimpleTestResult(false, getName() + ": failed reversal"); } return new SimpleTestResult(true, getName() + ": OKAY"); } private boolean isEqualArray( byte[] a, byte[] b) { if (a.length != b.length) { return false; } for (int i = 0; i != a.length; i++) { if (a[i] != b[i]) { return false; } } return true; } } bouncycastle-1.49.orig/jdk1.0/org/bouncycastle/crypto/test/IDEATest.java0000644000175000017500000000225210262753175025417 0ustar ebourgebourgpackage org.bouncycastle.crypto.test; import org.bouncycastle.crypto.engines.IDEAEngine; import org.bouncycastle.crypto.params.KeyParameter; import org.bouncycastle.util.encoders.Hex; import org.bouncycastle.util.test.Test; import org.bouncycastle.util.test.TestResult; /** */ public class IDEATest extends CipherTest { static Test[] tests = { new BlockCipherVectorTest(0, new IDEAEngine(), new KeyParameter(Hex.decode("00112233445566778899AABBCCDDEEFF")), "000102030405060708090a0b0c0d0e0f", "ed732271a7b39f475b4b2b6719f194bf"), new BlockCipherVectorTest(0, new IDEAEngine(), new KeyParameter(Hex.decode("00112233445566778899AABBCCDDEEFF")), "f0f1f2f3f4f5f6f7f8f9fafbfcfdfeff", "b8bc6ed5c899265d2bcfad1fc6d4287d") }; IDEATest() { super(tests); } public String getName() { return "IDEA"; } public static void main( String[] args) { IDEATest test = new IDEATest(); TestResult result = test.perform(); System.out.println(result); } } bouncycastle-1.49.orig/jdk1.0/org/bouncycastle/crypto/test/RC2Test.java0000644000175000017500000000440510262753175025305 0ustar ebourgebourgpackage org.bouncycastle.crypto.test; import org.bouncycastle.crypto.engines.RC2Engine; import org.bouncycastle.crypto.params.RC2Parameters; import org.bouncycastle.util.encoders.Hex; import org.bouncycastle.util.test.TestResult; /** * RC2 tester - vectors from ftp://ftp.isi.edu/in-notes/rfc2268.txt * * RFC 2268 "A Description of the RC2(r) Encryption Algorithm" */ public class RC2Test extends CipherTest { static BlockCipherVectorTest[] tests = { new BlockCipherVectorTest(0, new RC2Engine(), new RC2Parameters(Hex.decode("0000000000000000"), 63), "0000000000000000", "ebb773f993278eff"), new BlockCipherVectorTest(1, new RC2Engine(), new RC2Parameters(Hex.decode("ffffffffffffffff"), 64), "ffffffffffffffff", "278b27e42e2f0d49"), new BlockCipherVectorTest(2, new RC2Engine(), new RC2Parameters(Hex.decode("3000000000000000"), 64), "1000000000000001", "30649edf9be7d2c2"), new BlockCipherVectorTest(3, new RC2Engine(), new RC2Parameters(Hex.decode("88"), 64), "0000000000000000", "61a8a244adacccf0"), new BlockCipherVectorTest(4, new RC2Engine(), new RC2Parameters(Hex.decode("88bca90e90875a"), 64), "0000000000000000", "6ccf4308974c267f"), new BlockCipherVectorTest(5, new RC2Engine(), new RC2Parameters(Hex.decode("88bca90e90875a7f0f79c384627bafb2"), 64), "0000000000000000", "1a807d272bbe5db1"), new BlockCipherVectorTest(6, new RC2Engine(), new RC2Parameters(Hex.decode("88bca90e90875a7f0f79c384627bafb2"), 128), "0000000000000000", "2269552ab0f85ca6"), new BlockCipherVectorTest(7, new RC2Engine(), new RC2Parameters(Hex.decode("88bca90e90875a7f0f79c384627bafb216f80a6f85920584c42fceb0be255daf1e"), 129), "0000000000000000", "5b78d3a43dfff1f1") }; RC2Test() { super(tests); } public String getName() { return "RC2"; } public static void main( String[] args) { RC2Test test = new RC2Test(); TestResult result = test.perform(); System.out.println(result); } } bouncycastle-1.49.orig/jdk1.0/org/bouncycastle/crypto/test/RSATest.java0000644000175000017500000002322110262753175025341 0ustar ebourgebourgpackage org.bouncycastle.crypto.test; import java.math.BigInteger; import java.security.SecureRandom; import org.bouncycastle.crypto.AsymmetricBlockCipher; import org.bouncycastle.crypto.AsymmetricCipherKeyPair; import org.bouncycastle.crypto.encodings.OAEPEncoding; import org.bouncycastle.crypto.encodings.PKCS1Encoding; import org.bouncycastle.crypto.engines.RSAEngine; import org.bouncycastle.crypto.params.RSAKeyParameters; import org.bouncycastle.crypto.params.RSAPrivateCrtKeyParameters; import org.bouncycastle.crypto.generators.RSAKeyPairGenerator; import org.bouncycastle.crypto.params.RSAKeyGenerationParameters; import org.bouncycastle.util.encoders.Hex; import org.bouncycastle.util.test.SimpleTestResult; import org.bouncycastle.util.test.Test; import org.bouncycastle.util.test.TestResult; public class RSATest implements Test { static BigInteger mod = new BigInteger("b259d2d6e627a768c94be36164c2d9fc79d97aab9253140e5bf17751197731d6f7540d2509e7b9ffee0a70a6e26d56e92d2edd7f85aba85600b69089f35f6bdbf3c298e05842535d9f064e6b0391cb7d306e0a2d20c4dfb4e7b49a9640bdea26c10ad69c3f05007ce2513cee44cfe01998e62b6c3637d3fc0391079b26ee36d5", 16); static BigInteger pubExp = new BigInteger("11", 16); static BigInteger privExp = new BigInteger("92e08f83cc9920746989ca5034dcb384a094fb9c5a6288fcc4304424ab8f56388f72652d8fafc65a4b9020896f2cde297080f2a540e7b7ce5af0b3446e1258d1dd7f245cf54124b4c6e17da21b90a0ebd22605e6f45c9f136d7a13eaac1c0f7487de8bd6d924972408ebb58af71e76fd7b012a8d0e165f3ae2e5077a8648e619", 16); static BigInteger p = new BigInteger("f75e80839b9b9379f1cf1128f321639757dba514642c206bbbd99f9a4846208b3e93fbbe5e0527cc59b1d4b929d9555853004c7c8b30ee6a213c3d1bb7415d03", 16); static BigInteger q = new BigInteger("b892d9ebdbfc37e397256dd8a5d3123534d1f03726284743ddc6be3a709edb696fc40c7d902ed804c6eee730eee3d5b20bf6bd8d87a296813c87d3b3cc9d7947", 16); static BigInteger pExp = new BigInteger("1d1a2d3ca8e52068b3094d501c9a842fec37f54db16e9a67070a8b3f53cc03d4257ad252a1a640eadd603724d7bf3737914b544ae332eedf4f34436cac25ceb5", 16); static BigInteger qExp = new BigInteger("6c929e4e81672fef49d9c825163fec97c4b7ba7acb26c0824638ac22605d7201c94625770984f78a56e6e25904fe7db407099cad9b14588841b94f5ab498dded", 16); static BigInteger crtCoef = new BigInteger("dae7651ee69ad1d081ec5e7188ae126f6004ff39556bde90e0b870962fa7b926d070686d8244fe5a9aa709a95686a104614834b0ada4b10f53197a5cb4c97339", 16); static String input = "4e6f77206973207468652074696d6520666f7220616c6c20676f6f64206d656e"; // // to check that we handling byte extension by big number correctly. // static String edgeInput = "ff6f77206973207468652074696d6520666f7220616c6c20676f6f64206d656e"; public String getName() { return "RSA"; } public TestResult perform() { RSAKeyParameters pubParameters = new RSAKeyParameters(false, mod, pubExp); RSAKeyParameters privParameters = new RSAPrivateCrtKeyParameters(mod, pubExp, privExp, p, q, pExp, qExp, crtCoef); byte[] data = Hex.decode(edgeInput); // // RAW // AsymmetricBlockCipher eng = new RSAEngine(); eng.init(true, pubParameters); try { data = eng.processBlock(data, 0, data.length); } catch (Exception e) { return new SimpleTestResult(false, "RSA: failed - exception " + e.toString()); } eng.init(false, privParameters); try { data = eng.processBlock(data, 0, data.length); } catch (Exception e) { return new SimpleTestResult(false, "RSA: failed - exception " + e.toString()); } if (!edgeInput.equals(new String(Hex.encode(data), 0))) { return new SimpleTestResult(false, "RSA: failed RAW edge Test"); } data = Hex.decode(input); eng.init(true, pubParameters); try { data = eng.processBlock(data, 0, data.length); } catch (Exception e) { return new SimpleTestResult(false, "RSA: failed - exception " + e.toString()); } eng.init(false, privParameters); try { data = eng.processBlock(data, 0, data.length); } catch (Exception e) { return new SimpleTestResult(false, "RSA: failed - exception " + e.toString()); } if (!input.equals(new String(Hex.encode(data), 0))) { return new SimpleTestResult(false, "RSA: failed RAW Test"); } // // PKCS1 - public encrypt, private decrypt // eng = new PKCS1Encoding(eng); eng.init(true, pubParameters); try { data = eng.processBlock(data, 0, data.length); } catch (Exception e) { return new SimpleTestResult(false, "RSA: failed - exception " + e.toString()); } eng.init(false, privParameters); try { data = eng.processBlock(data, 0, data.length); } catch (Exception e) { return new SimpleTestResult(false, "RSA: failed - exception " + e.toString()); } if (!input.equals(new String(Hex.encode(data), 0))) { return new SimpleTestResult(false, "RSA: failed PKCS1 public/private Test"); } // // PKCS1 - private encrypt, public decrypt // eng = new PKCS1Encoding(((PKCS1Encoding)eng).getUnderlyingCipher()); eng.init(true, privParameters); try { data = eng.processBlock(data, 0, data.length); } catch (Exception e) { return new SimpleTestResult(false, "RSA: failed - exception " + e.toString()); } eng.init(false, pubParameters); try { data = eng.processBlock(data, 0, data.length); } catch (Exception e) { return new SimpleTestResult(false, "RSA: failed - exception " + e.toString()); } if (!input.equals(new String(Hex.encode(data), 0))) { return new SimpleTestResult(false, "RSA: failed PKCS1 private/public Test"); } // // OAEP - public encrypt, private decrypt // eng = new OAEPEncoding(((PKCS1Encoding)eng).getUnderlyingCipher()); eng.init(true, pubParameters); try { data = eng.processBlock(data, 0, data.length); } catch (Exception e) { return new SimpleTestResult(false, "RSA: failed - exception " + e.toString()); } eng.init(false, privParameters); try { data = eng.processBlock(data, 0, data.length); } catch (Exception e) { return new SimpleTestResult(false, "RSA: failed - exception " + e.toString()); } if (!input.equals(new String(Hex.encode(data), 0))) { return new SimpleTestResult(false, "RSA: failed OAEP Test"); } // // key generation test // RSAKeyPairGenerator pGen = new RSAKeyPairGenerator(); RSAKeyGenerationParameters genParam = new RSAKeyGenerationParameters( BigInteger.valueOf(0x11), new SecureRandom(), 768, 25); pGen.init(genParam); AsymmetricCipherKeyPair pair = pGen.generateKeyPair(); eng = new RSAEngine(); if (((RSAKeyParameters)pair.getPublic()).getModulus().bitLength() < 762) { return new SimpleTestResult(false, "RSA: failed key generation (768) length test"); } eng.init(true, pair.getPublic()); try { data = eng.processBlock(data, 0, data.length); } catch (Exception e) { return new SimpleTestResult(false, "RSA: failed - exception " + e.toString()); } eng.init(false, pair.getPrivate()); try { data = eng.processBlock(data, 0, data.length); } catch (Exception e) { return new SimpleTestResult(false, "RSA: failed - exception " + e.toString()); } if (!input.equals(new String(Hex.encode(data), 0))) { return new SimpleTestResult(false, "RSA: failed key generation (768) Test"); } genParam = new RSAKeyGenerationParameters(BigInteger.valueOf(0x11), new SecureRandom(), 1024, 25); pGen.init(genParam); pair = pGen.generateKeyPair(); eng.init(true, pair.getPublic()); if (((RSAKeyParameters)pair.getPublic()).getModulus().bitLength() < 1018) { return new SimpleTestResult(false, "RSA: failed key generation (1024) length test"); } try { data = eng.processBlock(data, 0, data.length); } catch (Exception e) { return new SimpleTestResult(false, "RSA: failed - exception " + e.toString()); } eng.init(false, pair.getPrivate()); try { data = eng.processBlock(data, 0, data.length); } catch (Exception e) { return new SimpleTestResult(false, "RSA: failed - exception " + e.toString()); } if (!input.equals(new String(Hex.encode(data), 0))) { return new SimpleTestResult(false, "RSA: failed key generation (1024) test"); } return new SimpleTestResult(false, "RSA: Okay"); } public static void main( String[] args) { RSATest test = new RSATest(); TestResult result = test.perform(); System.out.println(result); } } bouncycastle-1.49.orig/jdk1.0/org/bouncycastle/crypto/test/SkipjackTest.java0000644000175000017500000000164210262753175026456 0ustar ebourgebourgpackage org.bouncycastle.crypto.test; import org.bouncycastle.crypto.engines.SkipjackEngine; import org.bouncycastle.crypto.params.KeyParameter; import org.bouncycastle.util.encoders.Hex; import org.bouncycastle.util.test.Test; import org.bouncycastle.util.test.TestResult; /** */ public class SkipjackTest extends CipherTest { static Test[] tests = { new BlockCipherVectorTest(0, new SkipjackEngine(), new KeyParameter(Hex.decode("00998877665544332211")), "33221100ddccbbaa", "2587cae27a12d300") }; SkipjackTest() { super(tests); } public String getName() { return "SKIPJACK"; } public static void main( String[] args) { SkipjackTest test = new SkipjackTest(); TestResult result = test.perform(); System.out.println(result); } } bouncycastle-1.49.orig/jdk1.0/org/bouncycastle/crypto/test/ECTest.java0000644000175000017500000002061110350737002025170 0ustar ebourgebourgpackage org.bouncycastle.crypto.test; import java.math.BigInteger; import java.security.SecureRandom; import org.bouncycastle.crypto.AsymmetricCipherKeyPair; import org.bouncycastle.crypto.BasicAgreement; import org.bouncycastle.crypto.agreement.ECDHBasicAgreement; import org.bouncycastle.crypto.generators.ECKeyPairGenerator; import org.bouncycastle.crypto.params.ECDomainParameters; import org.bouncycastle.crypto.params.ECKeyGenerationParameters; import org.bouncycastle.crypto.params.ECPrivateKeyParameters; import org.bouncycastle.crypto.params.ECPublicKeyParameters; import org.bouncycastle.crypto.params.ParametersWithRandom; import org.bouncycastle.crypto.signers.ECDSASigner; import org.bouncycastle.math.ec.ECCurveFp; import org.bouncycastle.util.encoders.Hex; import org.bouncycastle.util.test.SimpleTestResult; import org.bouncycastle.util.test.Test; import org.bouncycastle.util.test.TestResult; class k1 extends SecureRandom { public void nextBytes(byte[] bytes) { byte[] k = new BigInteger("6140507067065001063065065565667405560006161556565665656654").toByteArray(); System.arraycopy(k, k.length-bytes.length, bytes, 0, bytes.length); } } /** * X9.62 - 1998,
* J.3.1, Page 152, ECDSA over the field Fp
* an example with 192 bit prime */ class ECDSA192bitPrime implements Test { BigInteger r = new BigInteger("3342403536405981729393488334694600415596881826869351677613"); BigInteger s = new BigInteger("5735822328888155254683894997897571951568553642892029982342"); SecureRandom k = new k1(); public String getName() { return "ECDSA 192 bit prime"; } public TestResult perform() { ECCurveFp curve = new ECCurveFp( new BigInteger("6277101735386680763835789423207666416083908700390324961279"), // q new BigInteger("fffffffffffffffffffffffffffffffefffffffffffffffc", 16), // a new BigInteger("64210519e59c80e70fa7e9ab72243049feb8deecc146b9b1", 16)); // b ECDomainParameters params = new ECDomainParameters( curve, curve.decodePoint(Hex.decode("03188da80eb03090f67cbf20eb43a18800f4ff0afd82ff1012")), // G new BigInteger("6277101735386680763835789423176059013767194773182842284081")); // n ECPrivateKeyParameters priKey = new ECPrivateKeyParameters( new BigInteger("651056770906015076056810763456358567190100156695615665659"), // d params); ParametersWithRandom param = new ParametersWithRandom(priKey, k); ECDSASigner ecdsa = new ECDSASigner(); ecdsa.init(true, param); byte[] message = new BigInteger("968236873715988614170569073515315707566766479517").toByteArray(); BigInteger[] sig = ecdsa.generateSignature(message); if (!r.equals(sig[0])) { return new SimpleTestResult(false, getName() + ": r component wrong." + System.getProperty("line.separator") + " expecting: " + r + System.getProperty("line.separator") + " got : " + sig[0]); } if (!s.equals(sig[1])) { return new SimpleTestResult(false, getName() + ": s component wrong." + System.getProperty("line.separator") + " expecting: " + s + System.getProperty("line.separator") + " got : " + sig[1]); } // Verify the signature ECPublicKeyParameters pubKey = new ECPublicKeyParameters( curve.decodePoint(Hex.decode("0262b12d60690cdcf330babab6e69763b471f994dd702d16a5")), // Q params); ecdsa.init(false, pubKey); if (ecdsa.verifySignature(message, sig[0], sig[1])) { return new SimpleTestResult(true, getName() + ": Okay"); } else { return new SimpleTestResult(false, getName() + ": verification fails"); } } } /** * key generation test */ class ECDSAKeyGenTest implements Test { public String getName() { return "ECDSA key generation test"; } public TestResult perform() { SecureRandom random = new SecureRandom(); ECCurveFp curve = new ECCurveFp( new BigInteger("883423532389192164791648750360308885314476597252960362792450860609699839"), // q new BigInteger("7fffffffffffffffffffffff7fffffffffff8000000000007ffffffffffc", 16), // a new BigInteger("6b016c3bdcf18941d0d654921475ca71a9db2fb27d1d37796185c2942c0a", 16)); // b ECDomainParameters params = new ECDomainParameters( curve, curve.decodePoint(Hex.decode("020ffa963cdca8816ccc33b8642bedf905c3d358573d3f27fbbd3b3cb9aaaf")), // G new BigInteger("883423532389192164791648750360308884807550341691627752275345424702807307")); // n ECKeyPairGenerator pGen = new ECKeyPairGenerator(); ECKeyGenerationParameters genParam = new ECKeyGenerationParameters( params, random); pGen.init(genParam); AsymmetricCipherKeyPair pair = pGen.generateKeyPair(); ParametersWithRandom param = new ParametersWithRandom(pair.getPrivate(), random); ECDSASigner ecdsa = new ECDSASigner(); ecdsa.init(true, param); byte[] message = new BigInteger("968236873715988614170569073515315707566766479517").toByteArray(); BigInteger[] sig = ecdsa.generateSignature(message); ecdsa.init(false, pair.getPublic()); if (ecdsa.verifySignature(message, sig[0], sig[1])) { return new SimpleTestResult(true, getName() + ": Okay"); } else { return new SimpleTestResult(false, getName() + ": signature fails"); } } } /** * Basic Key Agreement Test */ class ECBasicAgreementTest implements Test { public String getName() { return "ECDSA basic agreement test"; } public TestResult perform() { SecureRandom random = new SecureRandom(); ECCurveFp curve = new ECCurveFp( new BigInteger("883423532389192164791648750360308885314476597252960362792450860609699839"), // q new BigInteger("7fffffffffffffffffffffff7fffffffffff8000000000007ffffffffffc", 16), // a new BigInteger("6b016c3bdcf18941d0d654921475ca71a9db2fb27d1d37796185c2942c0a", 16)); // b ECDomainParameters params = new ECDomainParameters( curve, curve.decodePoint(Hex.decode("020ffa963cdca8816ccc33b8642bedf905c3d358573d3f27fbbd3b3cb9aaaf")), // G new BigInteger("883423532389192164791648750360308884807550341691627752275345424702807307")); // n ECKeyPairGenerator pGen = new ECKeyPairGenerator(); ECKeyGenerationParameters genParam = new ECKeyGenerationParameters( params, random); pGen.init(genParam); AsymmetricCipherKeyPair p1 = pGen.generateKeyPair(); AsymmetricCipherKeyPair p2 = pGen.generateKeyPair(); // // two way // BasicAgreement e1 = new ECDHBasicAgreement(); BasicAgreement e2 = new ECDHBasicAgreement(); e1.init(p1.getPrivate()); e2.init(p2.getPrivate()); BigInteger k1 = e1.calculateAgreement(p2.getPublic()); BigInteger k2 = e2.calculateAgreement(p1.getPublic()); if (!k1.equals(k2)) { return new SimpleTestResult(false, this.getName() + ": calculated agreement test failed"); } return new SimpleTestResult(true, this.getName() + ": Okay"); } } /** * ECDSA tests are taken from X9.62. */ public class ECTest implements Test { Test tests[] = { new ECDSA192bitPrime(), new ECDSAKeyGenTest(), new ECBasicAgreementTest() }; public String getName() { return "EC"; } public TestResult perform() { for (int i = 0; i != tests.length; i++) { TestResult result = tests[i].perform(); if (!result.isSuccessful()) { return result; } } return new SimpleTestResult(true, "EC: Okay"); } public static void main( String[] args) { ECTest test = new ECTest(); TestResult result = test.perform(); System.out.println(result); } } bouncycastle-1.49.orig/jdk1.0/org/bouncycastle/crypto/test/StreamCipherVectorTest.java0000644000175000017500000000423510262753175030471 0ustar ebourgebourgpackage org.bouncycastle.crypto.test; import org.bouncycastle.crypto.CipherParameters; import org.bouncycastle.crypto.StreamCipher; import org.bouncycastle.util.encoders.Hex; import org.bouncycastle.util.test.SimpleTestResult; import org.bouncycastle.util.test.Test; import org.bouncycastle.util.test.TestResult; /** * a basic test that takes a stream cipher, key parameter, and an input * and output string. */ public class StreamCipherVectorTest implements Test { int id; StreamCipher cipher; CipherParameters param; byte[] input; byte[] output; public StreamCipherVectorTest( int id, StreamCipher cipher, CipherParameters param, String input, String output) { this.id = id; this.cipher = cipher; this.param = param; this.input = Hex.decode(input); this.output = Hex.decode(output); } public String getName() { return cipher.getAlgorithmName() + " Vector Test " + id; } public TestResult perform() { cipher.init(true, param); byte[] out = new byte[input.length]; cipher.processBytes(input, 0, input.length, out, 0); if (!isEqualArray(out, output)) { return new SimpleTestResult(false, getName() + ": failed - " + "expected " + new String(Hex.encode(output), 0) + " got " + new String(Hex.encode(out), 0)); } cipher.init(false, param); cipher.processBytes(output, 0, output.length, out, 0); if (!isEqualArray(input, out)) { return new SimpleTestResult(false, getName() + ": failed reversal"); } return new SimpleTestResult(true, getName() + ": OKAY"); } private boolean isEqualArray( byte[] a, byte[] b) { if (a.length != b.length) { return false; } for (int i = 0; i != a.length; i++) { if (a[i] != b[i]) { return false; } } return true; } } bouncycastle-1.49.orig/jdk1.0/org/bouncycastle/crypto/test/RijndaelTest.java0000644000175000017500000000772310262753175026455 0ustar ebourgebourgpackage org.bouncycastle.crypto.test; import org.bouncycastle.crypto.engines.RijndaelEngine; import org.bouncycastle.crypto.params.KeyParameter; import org.bouncycastle.util.encoders.Hex; import org.bouncycastle.util.test.Test; import org.bouncycastle.util.test.TestResult; /** */ public class RijndaelTest extends CipherTest { static Test[] tests = { new BlockCipherVectorTest(0, new RijndaelEngine(128), new KeyParameter(Hex.decode("80000000000000000000000000000000")), "00000000000000000000000000000000", "0EDD33D3C621E546455BD8BA1418BEC8"), new BlockCipherVectorTest(1, new RijndaelEngine(128), new KeyParameter(Hex.decode("00000000000000000000000000000080")), "00000000000000000000000000000000", "172AEAB3D507678ECAF455C12587ADB7"), /* new BlockCipherMonteCarloTest(2, 10000, new RijndaelEngine(128), new KeyParameter(Hex.decode("00000000000000000000000000000000")), "00000000000000000000000000000000", "C34C052CC0DA8D73451AFE5F03BE297F"), */ new BlockCipherMonteCarloTest(2, 100, new RijndaelEngine(128), new KeyParameter(Hex.decode("00000000000000000000000000000000")), "00000000000000000000000000000000", "73ec274b42decc2a923d973d31289803"), /* new BlockCipherMonteCarloTest(3, 10000, new RijndaelEngine(128), new KeyParameter(Hex.decode("5F060D3716B345C253F6749ABAC10917")), "355F697E8B868B65B25A04E18D782AFA", "ACC863637868E3E068D2FD6E3508454A"), */ new BlockCipherMonteCarloTest(3, 100, new RijndaelEngine(128), new KeyParameter(Hex.decode("5F060D3716B345C253F6749ABAC10917")), "355F697E8B868B65B25A04E18D782AFA", "83b24df55c094168e7036527642b1dbe"), new BlockCipherVectorTest(4, new RijndaelEngine(128), new KeyParameter(Hex.decode("000000000000000000000000000000000000000000000000")), "80000000000000000000000000000000", "6CD02513E8D4DC986B4AFE087A60BD0C"), /* new BlockCipherMonteCarloTest(5, 10000, new RijndaelEngine(128), new KeyParameter(Hex.decode("AAFE47EE82411A2BF3F6752AE8D7831138F041560631B114")), "F3F6752AE8D7831138F041560631B114", "77BA00ED5412DFF27C8ED91F3C376172"), */ new BlockCipherMonteCarloTest(5, 100, new RijndaelEngine(128), new KeyParameter(Hex.decode("AAFE47EE82411A2BF3F6752AE8D7831138F041560631B114")), "F3F6752AE8D7831138F041560631B114", "c8a8f465b898b2ebc1b86cbf1f366c09"), new BlockCipherVectorTest(6, new RijndaelEngine(128), new KeyParameter(Hex.decode("0000000000000000000000000000000000000000000000000000000000000000")), "80000000000000000000000000000000", "DDC6BF790C15760D8D9AEB6F9A75FD4E"), /* new BlockCipherMonteCarloTest(7, 10000, new RijndaelEngine(128), new KeyParameter(Hex.decode("28E79E2AFC5F7745FCCABE2F6257C2EF4C4EDFB37324814ED4137C288711A386")), "C737317FE0846F132B23C8C2A672CE22", "E58B82BFBA53C0040DC610C642121168") */ new BlockCipherMonteCarloTest(7, 100, new RijndaelEngine(128), new KeyParameter(Hex.decode("28E79E2AFC5F7745FCCABE2F6257C2EF4C4EDFB37324814ED4137C288711A386")), "C737317FE0846F132B23C8C2A672CE22", "8fa011e53ee83f5a63f568a01ace9f1e") }; RijndaelTest() { super(tests); } public String getName() { return "Rijndael"; } public static void main( String[] args) { RijndaelTest test = new RijndaelTest(); TestResult result = test.perform(); System.out.println(result); } } bouncycastle-1.49.orig/jdk1.0/org/bouncycastle/crypto/test/DHTest.java0000644000175000017500000001133510262753175025212 0ustar ebourgebourgpackage org.bouncycastle.crypto.test; import java.math.BigInteger; import java.security.SecureRandom; import org.bouncycastle.crypto.AsymmetricCipherKeyPair; import org.bouncycastle.crypto.agreement.DHAgreement; import org.bouncycastle.crypto.agreement.DHBasicAgreement; import org.bouncycastle.crypto.generators.DHBasicKeyPairGenerator; import org.bouncycastle.crypto.generators.DHKeyPairGenerator; import org.bouncycastle.crypto.params.DHKeyGenerationParameters; import org.bouncycastle.crypto.params.DHParameters; import org.bouncycastle.crypto.params.DHPrivateKeyParameters; import org.bouncycastle.crypto.params.DHPublicKeyParameters; import org.bouncycastle.util.test.SimpleTestResult; import org.bouncycastle.util.test.Test; import org.bouncycastle.util.test.TestResult; public class DHTest implements Test { private BigInteger g512 = new BigInteger("153d5d6172adb43045b68ae8e1de1070b6137005686d29d3d73a7749199681ee5b212c9b96bfdcfa5b20cd5e3fd2044895d609cf9b410b7a0f12ca1cb9a428cc", 16); private BigInteger p512 = new BigInteger("9494fec095f3b85ee286542b3836fc81a5dd0a0349b4c239dd38744d488cf8e31db8bcb7d33b41abb9e5a33cca9144b1cef332c94bf0573bf047a3aca98cdf3b", 16); public String getName() { return "DH"; } private TestResult testGP( int size, BigInteger g, BigInteger p) { DHParameters dhParams = new DHParameters(p, g); DHKeyGenerationParameters params = new DHKeyGenerationParameters(new SecureRandom(), dhParams); DHKeyPairGenerator kpGen = new DHKeyPairGenerator(); kpGen.init(params); // // generate first pair // AsymmetricCipherKeyPair pair = kpGen.generateKeyPair(); DHPublicKeyParameters pu1 = (DHPublicKeyParameters)pair.getPublic(); DHPrivateKeyParameters pv1 = (DHPrivateKeyParameters)pair.getPrivate(); // // generate second pair // pair = kpGen.generateKeyPair(); DHPublicKeyParameters pu2 = (DHPublicKeyParameters)pair.getPublic(); DHPrivateKeyParameters pv2 = (DHPrivateKeyParameters)pair.getPrivate(); // // two way // DHAgreement e1 = new DHAgreement(); DHAgreement e2 = new DHAgreement(); e1.init(pv1); e2.init(pv2); BigInteger m1 = e1.calculateMessage(); BigInteger m2 = e2.calculateMessage(); BigInteger k1 = e1.calculateAgreement(pu2, m2); BigInteger k2 = e2.calculateAgreement(pu1, m1); if (!k1.equals(k2)) { return new SimpleTestResult(false, size + " bit 2-way test failed"); } return new SimpleTestResult(true, this.getName() + ": Okay"); } private TestResult testSimple( int size, BigInteger g, BigInteger p) { DHParameters dhParams = new DHParameters(p, g); DHKeyGenerationParameters params = new DHKeyGenerationParameters(new SecureRandom(), dhParams); DHBasicKeyPairGenerator kpGen = new DHBasicKeyPairGenerator(); kpGen.init(params); // // generate first pair // AsymmetricCipherKeyPair pair = kpGen.generateKeyPair(); DHPublicKeyParameters pu1 = (DHPublicKeyParameters)pair.getPublic(); DHPrivateKeyParameters pv1 = (DHPrivateKeyParameters)pair.getPrivate(); // // generate second pair // pair = kpGen.generateKeyPair(); DHPublicKeyParameters pu2 = (DHPublicKeyParameters)pair.getPublic(); DHPrivateKeyParameters pv2 = (DHPrivateKeyParameters)pair.getPrivate(); // // two way // DHBasicAgreement e1 = new DHBasicAgreement(); DHBasicAgreement e2 = new DHBasicAgreement(); e1.init(pv1); e2.init(pv2); BigInteger k1 = e1.calculateAgreement(pu2); BigInteger k2 = e2.calculateAgreement(pu1); if (!k1.equals(k2)) { return new SimpleTestResult(false, "basic " + size + " bit 2-way test failed"); } return new SimpleTestResult(true, this.getName() + ": Okay"); } public TestResult perform() { TestResult result = testSimple(512, g512, p512); if (!result.isSuccessful()) { return result; } result = testGP(512, g512, p512); if (!result.isSuccessful()) { return result; } return result; } public static void main( String[] args) { DHTest test = new DHTest(); TestResult result = test.perform(); System.out.println(result); } } bouncycastle-1.49.orig/jdk1.0/org/bouncycastle/crypto/test/AESTest.java0000644000175000017500000000575110350737002025321 0ustar ebourgebourgpackage org.bouncycastle.crypto.test; import org.bouncycastle.crypto.engines.AESEngine; import org.bouncycastle.crypto.params.KeyParameter; import org.bouncycastle.util.encoders.Hex; import org.bouncycastle.util.test.Test; import org.bouncycastle.util.test.TestResult; /** * Test vectors from the NIST standard tests and Brian Gladman's vector set * * http://fp.gladman.plus.com/cryptography_technology/rijndael/ */ public class AESTest extends CipherTest { static Test[] tests = { new BlockCipherVectorTest(0, new AESEngine(), new KeyParameter(Hex.decode("80000000000000000000000000000000")), "00000000000000000000000000000000", "0EDD33D3C621E546455BD8BA1418BEC8"), new BlockCipherVectorTest(1, new AESEngine(), new KeyParameter(Hex.decode("00000000000000000000000000000080")), "00000000000000000000000000000000", "172AEAB3D507678ECAF455C12587ADB7"), new BlockCipherMonteCarloTest(2, 10000, new AESEngine(), new KeyParameter(Hex.decode("00000000000000000000000000000000")), "00000000000000000000000000000000", "C34C052CC0DA8D73451AFE5F03BE297F"), new BlockCipherMonteCarloTest(3, 10000, new AESEngine(), new KeyParameter(Hex.decode("5F060D3716B345C253F6749ABAC10917")), "355F697E8B868B65B25A04E18D782AFA", "ACC863637868E3E068D2FD6E3508454A"), new BlockCipherVectorTest(4, new AESEngine(), new KeyParameter(Hex.decode("000000000000000000000000000000000000000000000000")), "80000000000000000000000000000000", "6CD02513E8D4DC986B4AFE087A60BD0C"), new BlockCipherMonteCarloTest(5, 10000, new AESEngine(), new KeyParameter(Hex.decode("AAFE47EE82411A2BF3F6752AE8D7831138F041560631B114")), "F3F6752AE8D7831138F041560631B114", "77BA00ED5412DFF27C8ED91F3C376172"), new BlockCipherVectorTest(6, new AESEngine(), new KeyParameter(Hex.decode("0000000000000000000000000000000000000000000000000000000000000000")), "80000000000000000000000000000000", "DDC6BF790C15760D8D9AEB6F9A75FD4E"), new BlockCipherMonteCarloTest(7, 10000, new AESEngine(), new KeyParameter(Hex.decode("28E79E2AFC5F7745FCCABE2F6257C2EF4C4EDFB37324814ED4137C288711A386")), "C737317FE0846F132B23C8C2A672CE22", "E58B82BFBA53C0040DC610C642121168") }; AESTest() { super(tests); } public String getName() { return "AES"; } public static void main( String[] args) { AESTest test = new AESTest(); TestResult result = test.perform(); System.out.println(result); } } bouncycastle-1.49.orig/jdk1.0/org/bouncycastle/crypto/test/BlowfishTest.java0000644000175000017500000000461210262753175026474 0ustar ebourgebourgpackage org.bouncycastle.crypto.test; import org.bouncycastle.crypto.engines.BlowfishEngine; import org.bouncycastle.crypto.params.KeyParameter; import org.bouncycastle.util.encoders.Hex; import org.bouncycastle.util.test.Test; import org.bouncycastle.util.test.TestResult; /** * blowfish tester - vectors from http://www.counterpane.com/vectors.txt */ public class BlowfishTest extends CipherTest { static Test[] tests = { new BlockCipherVectorTest(0, new BlowfishEngine(), new KeyParameter(Hex.decode("0000000000000000")), "0000000000000000", "4EF997456198DD78"), new BlockCipherVectorTest(1, new BlowfishEngine(), new KeyParameter(Hex.decode("FFFFFFFFFFFFFFFF")), "FFFFFFFFFFFFFFFF", "51866FD5B85ECB8A"), new BlockCipherVectorTest(2, new BlowfishEngine(), new KeyParameter(Hex.decode("3000000000000000")), "1000000000000001", "7D856F9A613063F2"), new BlockCipherVectorTest(3, new BlowfishEngine(), new KeyParameter(Hex.decode("1111111111111111")), "1111111111111111", "2466DD878B963C9D"), new BlockCipherVectorTest(4, new BlowfishEngine(), new KeyParameter(Hex.decode("0123456789ABCDEF")), "1111111111111111", "61F9C3802281B096"), new BlockCipherVectorTest(5, new BlowfishEngine(), new KeyParameter(Hex.decode("FEDCBA9876543210")), "0123456789ABCDEF", "0ACEAB0FC6A0A28D"), new BlockCipherVectorTest(6, new BlowfishEngine(), new KeyParameter(Hex.decode("7CA110454A1A6E57")), "01A1D6D039776742", "59C68245EB05282B"), new BlockCipherVectorTest(7, new BlowfishEngine(), new KeyParameter(Hex.decode("0131D9619DC1376E")), "5CD54CA83DEF57DA", "B1B8CC0B250F09A0"), }; BlowfishTest() { super(tests); } public String getName() { return "Blowfish"; } public static void main( String[] args) { BlowfishTest test = new BlowfishTest(); TestResult result = test.perform(); System.out.println(result); } } bouncycastle-1.49.orig/jdk1.0/org/bouncycastle/crypto/test/DESTest.java0000644000175000017500000001134210262753175025330 0ustar ebourgebourgpackage org.bouncycastle.crypto.test; import org.bouncycastle.crypto.engines.DESEngine; import org.bouncycastle.crypto.modes.CBCBlockCipher; import org.bouncycastle.crypto.modes.CFBBlockCipher; import org.bouncycastle.crypto.modes.OFBBlockCipher; import org.bouncycastle.crypto.params.DESParameters; import org.bouncycastle.crypto.params.KeyParameter; import org.bouncycastle.crypto.params.ParametersWithIV; import org.bouncycastle.util.encoders.Hex; import org.bouncycastle.util.test.SimpleTestResult; import org.bouncycastle.util.test.Test; import org.bouncycastle.util.test.TestResult; class DESParityTest implements Test { public String getName() { return "DESParityTest"; } public TestResult perform() { byte[] k1In = { (byte)0xff, (byte)0xff, (byte)0xff, (byte)0xff, (byte)0xff, (byte)0xff, (byte)0xff, (byte)0xff }; byte[] k1Out = { (byte)0xfe, (byte)0xfe, (byte)0xfe, (byte)0xfe, (byte)0xfe, (byte)0xfe, (byte)0xfe, (byte)0xfe }; byte[] k2In = { (byte)0xef, (byte)0xcb, (byte)0xda, (byte)0x4f, (byte)0xaa, (byte)0x99, (byte)0x7f, (byte)0x63 }; byte[] k2Out = { (byte)0xef, (byte)0xcb, (byte)0xda, (byte)0x4f, (byte)0xab, (byte)0x98, (byte)0x7f, (byte)0x62 }; DESParameters.setOddParity(k1In); for (int i = 0; i != k1In.length; i++) { if (k1In[i] != k1Out[i]) { return new SimpleTestResult(false, getName() + ": Failed " + "got " + new String(Hex.encode(k1In), 0) + " expected " + new String(Hex.encode(k1Out), 0)); } } DESParameters.setOddParity(k2In); for (int i = 0; i != k2In.length; i++) { if (k2In[i] != k2Out[i]) { return new SimpleTestResult(false, getName() + ": Failed " + "got " + new String(Hex.encode(k2In), 0) + " expected " + new String(Hex.encode(k2Out), 0)); } } return new SimpleTestResult(true, getName() + ": Okay"); } } /** * DES tester - vectors from FIPS 81 */ public class DESTest extends CipherTest { static String input1 = "4e6f77206973207468652074696d6520666f7220616c6c20"; static String input2 = "4e6f7720697320746865"; static String input3 = "4e6f7720697320746865aabbcc"; static Test[] tests = { new BlockCipherVectorTest(0, new DESEngine(), new KeyParameter(Hex.decode("0123456789abcdef")), input1, "3fa40e8a984d48156a271787ab8883f9893d51ec4b563b53"), new BlockCipherVectorTest(1, new CBCBlockCipher(new DESEngine()), new ParametersWithIV(new KeyParameter(Hex.decode("0123456789abcdef")), Hex.decode("1234567890abcdef")), input1, "e5c7cdde872bf27c43e934008c389c0f683788499a7c05f6"), new BlockCipherVectorTest(2, new CFBBlockCipher(new DESEngine(), 8), new ParametersWithIV(new KeyParameter(Hex.decode("0123456789abcdef")), Hex.decode("1234567890abcdef")), input2, "f31fda07011462ee187f"), new BlockCipherVectorTest(3, new CFBBlockCipher(new DESEngine(), 64), new ParametersWithIV(new KeyParameter(Hex.decode("0123456789abcdef")), Hex.decode("1234567890abcdef")), input1, "f3096249c7f46e51a69e839b1a92f78403467133898ea622"), new BlockCipherVectorTest(4, new OFBBlockCipher(new DESEngine(), 8), new ParametersWithIV(new KeyParameter(Hex.decode("0123456789abcdef")), Hex.decode("1234567890abcdef")), input2, "f34a2850c9c64985d684"), new BlockCipherVectorTest(5, new CFBBlockCipher(new DESEngine(), 64), new ParametersWithIV(new KeyParameter(Hex.decode("0123456789abcdef")), Hex.decode("1234567890abcdef")), input3, "f3096249c7f46e51a69e0954bf"), new BlockCipherVectorTest(6, new OFBBlockCipher(new DESEngine(), 64), new ParametersWithIV(new KeyParameter(Hex.decode("0123456789abcdef")), Hex.decode("1234567890abcdef")), input3, "f3096249c7f46e5135f2c0eb8b"), new DESParityTest() }; public DESTest() { super(tests); } public String getName() { return "DES"; } public static void main( String[] args) { DESTest test = new DESTest(); TestResult result = test.perform(); System.out.println(result); } } bouncycastle-1.49.orig/jdk1.0/org/bouncycastle/crypto/test/RC6Test.java0000644000175000017500000000530410262753175025310 0ustar ebourgebourgpackage org.bouncycastle.crypto.test; import org.bouncycastle.crypto.engines.RC6Engine; import org.bouncycastle.crypto.params.KeyParameter; import org.bouncycastle.util.encoders.Hex; import org.bouncycastle.util.test.Test; import org.bouncycastle.util.test.TestResult; /** * RC6 Test - test vectors from AES Submitted RSA Reference implementation. * ftp://ftp.funet.fi/pub/crypt/cryptography/symmetric/aes/rc6-unix-refc.tar */ public class RC6Test extends CipherTest { static Test[] tests = { new BlockCipherVectorTest(0, new RC6Engine(), new KeyParameter( Hex.decode("00000000000000000000000000000000")), "80000000000000000000000000000000", "f71f65e7b80c0c6966fee607984b5cdf"), new BlockCipherVectorTest(1, new RC6Engine(), new KeyParameter( Hex.decode("000000000000000000000000000000008000000000000000")), "00000000000000000000000000000000", "dd04c176440bbc6686c90aee775bd368"), new BlockCipherVectorTest(2, new RC6Engine(), new KeyParameter( Hex.decode("000000000000000000000000000000000000001000000000")), "00000000000000000000000000000000", "937fe02d20fcb72f0f57201012b88ba4"), new BlockCipherVectorTest(3, new RC6Engine(), new KeyParameter( Hex.decode("00000001000000000000000000000000")), "00000000000000000000000000000000", "8a380594d7396453771a1dfbe2914c8e"), new BlockCipherVectorTest(4, new RC6Engine(), new KeyParameter( Hex.decode("1000000000000000000000000000000000000000000000000000000000000000")), "00000000000000000000000000000000", "11395d4bfe4c8258979ee2bf2d24dff4"), new BlockCipherVectorTest(5, new RC6Engine(), new KeyParameter( Hex.decode("0000000000000000000000000000000000080000000000000000000000000000")), "00000000000000000000000000000000", "3d6f7e99f6512553bb983e8f75672b97") }; RC6Test() { super(tests); } public String getName() { return "RC6"; } public static void main( String[] args) { RC6Test test = new RC6Test(); TestResult result = test.perform(); System.out.println(result); } } bouncycastle-1.49.orig/jdk1.0/org/bouncycastle/crypto/test/RC5Test.java0000644000175000017500000002212310262753175025305 0ustar ebourgebourgpackage org.bouncycastle.crypto.test; import org.bouncycastle.crypto.engines.RC532Engine; import org.bouncycastle.crypto.engines.RC564Engine; import org.bouncycastle.crypto.modes.CBCBlockCipher; import org.bouncycastle.crypto.params.ParametersWithIV; import org.bouncycastle.crypto.params.RC5Parameters; import org.bouncycastle.util.encoders.Hex; import org.bouncycastle.util.test.SimpleTestResult; import org.bouncycastle.util.test.Test; import org.bouncycastle.util.test.TestResult; /** * RC5 tester - vectors from ftp://ftp.nordu.net/rfc/rfc2040.txt * * RFC 2040 "The RC5, RC5-CBC, RC5-CBC-Pad, and RC5-CTS Algorithms" */ public class RC5Test implements Test { BlockCipherVectorTest[] tests = { new BlockCipherVectorTest(0, new CBCBlockCipher(new RC532Engine()), new ParametersWithIV( new RC5Parameters(Hex.decode("00"), 0), Hex.decode("0000000000000000")), "0000000000000000", "7a7bba4d79111d1e"), new BlockCipherVectorTest(1, new CBCBlockCipher(new RC532Engine()), new ParametersWithIV( new RC5Parameters(Hex.decode("00"), 0), Hex.decode("0000000000000000")), "ffffffffffffffff", "797bba4d78111d1e"), new BlockCipherVectorTest(2, new CBCBlockCipher(new RC532Engine()), new ParametersWithIV( new RC5Parameters(Hex.decode("00"), 0), Hex.decode("0000000000000001")), "0000000000000000", "7a7bba4d79111d1f"), new BlockCipherVectorTest(3, new CBCBlockCipher(new RC532Engine()), new ParametersWithIV( new RC5Parameters(Hex.decode("00"), 0), Hex.decode("0000000000000000")), "0000000000000001", "7a7bba4d79111d1f"), new BlockCipherVectorTest(4, new CBCBlockCipher(new RC532Engine()), new ParametersWithIV( new RC5Parameters(Hex.decode("00"), 0), Hex.decode("0102030405060708")), "1020304050607080", "8b9ded91ce7794a6"), new BlockCipherVectorTest(5, new CBCBlockCipher(new RC532Engine()), new ParametersWithIV( new RC5Parameters(Hex.decode("11"), 1), Hex.decode("0000000000000000")), "0000000000000000", "2f759fe7ad86a378"), new BlockCipherVectorTest(6, new CBCBlockCipher(new RC532Engine()), new ParametersWithIV( new RC5Parameters(Hex.decode("00"), 2), Hex.decode("0000000000000000")), "0000000000000000", "dca2694bf40e0788"), new BlockCipherVectorTest(7, new CBCBlockCipher(new RC532Engine()), new ParametersWithIV( new RC5Parameters(Hex.decode("00000000"), 2), Hex.decode("0000000000000000")), "0000000000000000", "dca2694bf40e0788"), new BlockCipherVectorTest(8, new CBCBlockCipher(new RC532Engine()), new ParametersWithIV( new RC5Parameters(Hex.decode("00000000"), 8), Hex.decode("0000000000000000")), "0000000000000000", "dcfe098577eca5ff"), new BlockCipherVectorTest(9, new CBCBlockCipher(new RC532Engine()), new ParametersWithIV( new RC5Parameters(Hex.decode("00"), 8), Hex.decode("0102030405060708")), "1020304050607080", "9646fb77638f9ca8"), new BlockCipherVectorTest(10, new CBCBlockCipher(new RC532Engine()), new ParametersWithIV( new RC5Parameters(Hex.decode("00"), 12), Hex.decode("0102030405060708")), "1020304050607080", "b2b3209db6594da4"), new BlockCipherVectorTest(11, new CBCBlockCipher(new RC532Engine()), new ParametersWithIV( new RC5Parameters(Hex.decode("00"), 16), Hex.decode("0102030405060708")), "1020304050607080", "545f7f32a5fc3836"), new BlockCipherVectorTest(12, new CBCBlockCipher(new RC532Engine()), new ParametersWithIV( new RC5Parameters(Hex.decode("01020304"), 8), Hex.decode("0000000000000000")), "ffffffffffffffff", "8285e7c1b5bc7402"), new BlockCipherVectorTest(13, new CBCBlockCipher(new RC532Engine()), new ParametersWithIV( new RC5Parameters(Hex.decode("01020304"), 12), Hex.decode("0000000000000000")), "ffffffffffffffff", "fc586f92f7080934"), new BlockCipherVectorTest(14, new CBCBlockCipher(new RC532Engine()), new ParametersWithIV( new RC5Parameters(Hex.decode("01020304"), 16), Hex.decode("0000000000000000")), "ffffffffffffffff", "cf270ef9717ff7c4"), new BlockCipherVectorTest(15, new CBCBlockCipher(new RC532Engine()), new ParametersWithIV( new RC5Parameters(Hex.decode("0102030405060708"), 12), Hex.decode("0000000000000000")), "ffffffffffffffff", "e493f1c1bb4d6e8c"), new BlockCipherVectorTest(16, new CBCBlockCipher(new RC532Engine()), new ParametersWithIV( new RC5Parameters(Hex.decode("0102030405060708"), 8), Hex.decode("0102030405060708")), "1020304050607080", "5c4c041e0f217ac3"), new BlockCipherVectorTest(17, new CBCBlockCipher(new RC532Engine()), new ParametersWithIV( new RC5Parameters(Hex.decode("0102030405060708"), 12), Hex.decode("0102030405060708")), "1020304050607080", "921f12485373b4f7"), new BlockCipherVectorTest(18, new CBCBlockCipher(new RC532Engine()), new ParametersWithIV( new RC5Parameters(Hex.decode("0102030405060708"), 16), Hex.decode("0102030405060708")), "1020304050607080", "5ba0ca6bbe7f5fad"), new BlockCipherVectorTest(19, new CBCBlockCipher(new RC532Engine()), new ParametersWithIV( new RC5Parameters(Hex.decode("01020304050607081020304050607080"), 8), Hex.decode("0102030405060708")), "1020304050607080", "c533771cd0110e63"), new BlockCipherVectorTest(20, new CBCBlockCipher(new RC532Engine()), new ParametersWithIV( new RC5Parameters(Hex.decode("01020304050607081020304050607080"), 12), Hex.decode("0102030405060708")), "1020304050607080", "294ddb46b3278d60"), new BlockCipherVectorTest(21, new CBCBlockCipher(new RC532Engine()), new ParametersWithIV( new RC5Parameters(Hex.decode("01020304050607081020304050607080"), 16), Hex.decode("0102030405060708")), "1020304050607080", "dad6bda9dfe8f7e8"), new BlockCipherVectorTest(22, new CBCBlockCipher(new RC532Engine()), new ParametersWithIV( new RC5Parameters(Hex.decode("0102030405"), 12), Hex.decode("0000000000000000")), "ffffffffffffffff", "97e0787837ed317f"), new BlockCipherVectorTest(23, new CBCBlockCipher(new RC532Engine()), new ParametersWithIV( new RC5Parameters(Hex.decode("0102030405"), 8), Hex.decode("0000000000000000")), "ffffffffffffffff", "7875dbf6738c6478"), new BlockCipherVectorTest(23, new CBCBlockCipher(new RC532Engine()), new ParametersWithIV( new RC5Parameters(Hex.decode("0102030405"), 8), Hex.decode("7875dbf6738c6478")), "0808080808080808", "8f34c3c681c99695"), new BlockCipherVectorTest(640, new CBCBlockCipher(new RC564Engine()), new ParametersWithIV( new RC5Parameters(Hex.decode("00"), 0), Hex.decode("00000000000000000000000000000000")), "00000000000000000000000000000000", "9f09b98d3f6062d9d4d59973d00e0e63"), new BlockCipherVectorTest(641, new CBCBlockCipher(new RC564Engine()), new ParametersWithIV( new RC5Parameters(Hex.decode("00"), 0), Hex.decode("00000000000000000000000000000000")), "ffffffffffffffffffffffffffffffff", "9e09b98d3f6062d9d3d59973d00e0e63") }; public String getName() { return "RC5"; } public TestResult perform() { for (int i = 0; i != tests.length; i++) { TestResult res = tests[i].perform(); if (!res.isSuccessful()) { return res; } } return new SimpleTestResult(true, getName() + ": Okay"); } public static void main( String[] args) { RC5Test test = new RC5Test(); TestResult result = test.perform(); System.out.println(result); } } bouncycastle-1.49.orig/jdk1.0/org/bouncycastle/crypto/test/BlockCipherMonteCarloTest.java0000644000175000017500000000643310262753175031073 0ustar ebourgebourgpackage org.bouncycastle.crypto.test; import org.bouncycastle.crypto.BlockCipher; import org.bouncycastle.crypto.BufferedBlockCipher; import org.bouncycastle.crypto.CipherParameters; import org.bouncycastle.crypto.CryptoException; import org.bouncycastle.util.encoders.Hex; import org.bouncycastle.util.test.SimpleTestResult; import org.bouncycastle.util.test.Test; import org.bouncycastle.util.test.TestResult; /** * a basic test that takes a cipher, key parameter, and an input * and output string. This test wraps the engine in a buffered block * cipher with padding disabled. */ public class BlockCipherMonteCarloTest implements Test { int id; int iterations; BlockCipher engine; CipherParameters param; byte[] input; byte[] output; public BlockCipherMonteCarloTest( int id, int iterations, BlockCipher engine, CipherParameters param, String input, String output) { this.id = id; this.iterations = iterations; this.engine = engine; this.param = param; this.input = Hex.decode(input); this.output = Hex.decode(output); } public String getName() { return engine.getAlgorithmName() + " Monte Carlo Test " + id; } public TestResult perform() { BufferedBlockCipher cipher = new BufferedBlockCipher(engine); cipher.init(true, param); byte[] out = new byte[input.length]; System.arraycopy(input, 0, out, 0, out.length); for (int i = 0; i != iterations; i++) { int len1 = cipher.processBytes(out, 0, out.length, out, 0); try { cipher.doFinal(out, len1); } catch (CryptoException e) { return new SimpleTestResult(false, getName() + ": failed - exception " + e.toString()); } } if (!isEqualArray(out, output)) { return new SimpleTestResult(false, getName() + ": failed - " + "expected " + new String(Hex.encode(output), 0) + " got " + new String(Hex.encode(out), 0)); } cipher.init(false, param); for (int i = 0; i != iterations; i++) { int len1 = cipher.processBytes(out, 0, out.length, out, 0); try { cipher.doFinal(out, len1); } catch (CryptoException e) { return new SimpleTestResult(false, getName() + ": failed reversal - exception " + e.toString()); } } if (!isEqualArray(input, out)) { return new SimpleTestResult(false, getName() + ": failed reversal"); } return new SimpleTestResult(true, getName() + ": OKAY"); } private boolean isEqualArray( byte[] a, byte[] b) { if (a.length != b.length) { return false; } for (int i = 0; i != a.length; i++) { if (a[i] != b[i]) { return false; } } return true; } } bouncycastle-1.49.orig/jdk1.0/org/bouncycastle/crypto/test/RegressionTest.java0000644000175000017500000000135510262753175027040 0ustar ebourgebourgpackage org.bouncycastle.crypto.test; import org.bouncycastle.util.test.Test; import org.bouncycastle.util.test.TestResult; public class RegressionTest { public static Test[] tests = { new AESTest(), new DESTest(), new DESedeTest(), new SkipjackTest(), new BlowfishTest(), new IDEATest(), new RC2Test(), new RC4Test(), new RC5Test(), new RC6Test(), new RijndaelTest(), new ECTest(), new RSATest() }; public static void main( String[] args) { for (int i = 0; i != tests.length; i++) { TestResult result = tests[i].perform(); System.out.println(result); } } } bouncycastle-1.49.orig/jdk1.0/org/bouncycastle/crypto/engines/0000755000175000017500000000000012152033551023647 5ustar ebourgebourgbouncycastle-1.49.orig/jdk1.0/org/bouncycastle/crypto/engines/BlowfishEngine.java0000644000175000017500000006261011251332502027417 0ustar ebourgebourgpackage org.bouncycastle.crypto.engines; import org.bouncycastle.crypto.BlockCipher; import org.bouncycastle.crypto.CipherParameters; import org.bouncycastle.crypto.DataLengthException; import org.bouncycastle.crypto.params.KeyParameter; /** * A class that provides Blowfish key encryption operations, * such as encoding data and generating keys. * All the algorithms herein are from Applied Cryptography * and implement a simplified cryptography interface. */ public final class BlowfishEngine implements BlockCipher { private final static int[] KP = { 0x243F6A88, 0x85A308D3, 0x13198A2E, 0x03707344, 0xA4093822, 0x299F31D0, 0x082EFA98, 0xEC4E6C89, 0x452821E6, 0x38D01377, 0xBE5466CF, 0x34E90C6C, 0xC0AC29B7, 0xC97C50DD, 0x3F84D5B5, 0xB5470917, 0x9216D5D9, 0x8979FB1B }, KS0 = { 0xD1310BA6, 0x98DFB5AC, 0x2FFD72DB, 0xD01ADFB7, 0xB8E1AFED, 0x6A267E96, 0xBA7C9045, 0xF12C7F99, 0x24A19947, 0xB3916CF7, 0x0801F2E2, 0x858EFC16, 0x636920D8, 0x71574E69, 0xA458FEA3, 0xF4933D7E, 0x0D95748F, 0x728EB658, 0x718BCD58, 0x82154AEE, 0x7B54A41D, 0xC25A59B5, 0x9C30D539, 0x2AF26013, 0xC5D1B023, 0x286085F0, 0xCA417918, 0xB8DB38EF, 0x8E79DCB0, 0x603A180E, 0x6C9E0E8B, 0xB01E8A3E, 0xD71577C1, 0xBD314B27, 0x78AF2FDA, 0x55605C60, 0xE65525F3, 0xAA55AB94, 0x57489862, 0x63E81440, 0x55CA396A, 0x2AAB10B6, 0xB4CC5C34, 0x1141E8CE, 0xA15486AF, 0x7C72E993, 0xB3EE1411, 0x636FBC2A, 0x2BA9C55D, 0x741831F6, 0xCE5C3E16, 0x9B87931E, 0xAFD6BA33, 0x6C24CF5C, 0x7A325381, 0x28958677, 0x3B8F4898, 0x6B4BB9AF, 0xC4BFE81B, 0x66282193, 0x61D809CC, 0xFB21A991, 0x487CAC60, 0x5DEC8032, 0xEF845D5D, 0xE98575B1, 0xDC262302, 0xEB651B88, 0x23893E81, 0xD396ACC5, 0x0F6D6FF3, 0x83F44239, 0x2E0B4482, 0xA4842004, 0x69C8F04A, 0x9E1F9B5E, 0x21C66842, 0xF6E96C9A, 0x670C9C61, 0xABD388F0, 0x6A51A0D2, 0xD8542F68, 0x960FA728, 0xAB5133A3, 0x6EEF0B6C, 0x137A3BE4, 0xBA3BF050, 0x7EFB2A98, 0xA1F1651D, 0x39AF0176, 0x66CA593E, 0x82430E88, 0x8CEE8619, 0x456F9FB4, 0x7D84A5C3, 0x3B8B5EBE, 0xE06F75D8, 0x85C12073, 0x401A449F, 0x56C16AA6, 0x4ED3AA62, 0x363F7706, 0x1BFEDF72, 0x429B023D, 0x37D0D724, 0xD00A1248, 0xDB0FEAD3, 0x49F1C09B, 0x075372C9, 0x80991B7B, 0x25D479D8, 0xF6E8DEF7, 0xE3FE501A, 0xB6794C3B, 0x976CE0BD, 0x04C006BA, 0xC1A94FB6, 0x409F60C4, 0x5E5C9EC2, 0x196A2463, 0x68FB6FAF, 0x3E6C53B5, 0x1339B2EB, 0x3B52EC6F, 0x6DFC511F, 0x9B30952C, 0xCC814544, 0xAF5EBD09, 0xBEE3D004, 0xDE334AFD, 0x660F2807, 0x192E4BB3, 0xC0CBA857, 0x45C8740F, 0xD20B5F39, 0xB9D3FBDB, 0x5579C0BD, 0x1A60320A, 0xD6A100C6, 0x402C7279, 0x679F25FE, 0xFB1FA3CC, 0x8EA5E9F8, 0xDB3222F8, 0x3C7516DF, 0xFD616B15, 0x2F501EC8, 0xAD0552AB, 0x323DB5FA, 0xFD238760, 0x53317B48, 0x3E00DF82, 0x9E5C57BB, 0xCA6F8CA0, 0x1A87562E, 0xDF1769DB, 0xD542A8F6, 0x287EFFC3, 0xAC6732C6, 0x8C4F5573, 0x695B27B0, 0xBBCA58C8, 0xE1FFA35D, 0xB8F011A0, 0x10FA3D98, 0xFD2183B8, 0x4AFCB56C, 0x2DD1D35B, 0x9A53E479, 0xB6F84565, 0xD28E49BC, 0x4BFB9790, 0xE1DDF2DA, 0xA4CB7E33, 0x62FB1341, 0xCEE4C6E8, 0xEF20CADA, 0x36774C01, 0xD07E9EFE, 0x2BF11FB4, 0x95DBDA4D, 0xAE909198, 0xEAAD8E71, 0x6B93D5A0, 0xD08ED1D0, 0xAFC725E0, 0x8E3C5B2F, 0x8E7594B7, 0x8FF6E2FB, 0xF2122B64, 0x8888B812, 0x900DF01C, 0x4FAD5EA0, 0x688FC31C, 0xD1CFF191, 0xB3A8C1AD, 0x2F2F2218, 0xBE0E1777, 0xEA752DFE, 0x8B021FA1, 0xE5A0CC0F, 0xB56F74E8, 0x18ACF3D6, 0xCE89E299, 0xB4A84FE0, 0xFD13E0B7, 0x7CC43B81, 0xD2ADA8D9, 0x165FA266, 0x80957705, 0x93CC7314, 0x211A1477, 0xE6AD2065, 0x77B5FA86, 0xC75442F5, 0xFB9D35CF, 0xEBCDAF0C, 0x7B3E89A0, 0xD6411BD3, 0xAE1E7E49, 0x00250E2D, 0x2071B35E, 0x226800BB, 0x57B8E0AF, 0x2464369B, 0xF009B91E, 0x5563911D, 0x59DFA6AA, 0x78C14389, 0xD95A537F, 0x207D5BA2, 0x02E5B9C5, 0x83260376, 0x6295CFA9, 0x11C81968, 0x4E734A41, 0xB3472DCA, 0x7B14A94A, 0x1B510052, 0x9A532915, 0xD60F573F, 0xBC9BC6E4, 0x2B60A476, 0x81E67400, 0x08BA6FB5, 0x571BE91F, 0xF296EC6B, 0x2A0DD915, 0xB6636521, 0xE7B9F9B6, 0xFF34052E, 0xC5855664, 0x53B02D5D, 0xA99F8FA1, 0x08BA4799, 0x6E85076A }, KS1 = { 0x4B7A70E9, 0xB5B32944, 0xDB75092E, 0xC4192623, 0xAD6EA6B0, 0x49A7DF7D, 0x9CEE60B8, 0x8FEDB266, 0xECAA8C71, 0x699A17FF, 0x5664526C, 0xC2B19EE1, 0x193602A5, 0x75094C29, 0xA0591340, 0xE4183A3E, 0x3F54989A, 0x5B429D65, 0x6B8FE4D6, 0x99F73FD6, 0xA1D29C07, 0xEFE830F5, 0x4D2D38E6, 0xF0255DC1, 0x4CDD2086, 0x8470EB26, 0x6382E9C6, 0x021ECC5E, 0x09686B3F, 0x3EBAEFC9, 0x3C971814, 0x6B6A70A1, 0x687F3584, 0x52A0E286, 0xB79C5305, 0xAA500737, 0x3E07841C, 0x7FDEAE5C, 0x8E7D44EC, 0x5716F2B8, 0xB03ADA37, 0xF0500C0D, 0xF01C1F04, 0x0200B3FF, 0xAE0CF51A, 0x3CB574B2, 0x25837A58, 0xDC0921BD, 0xD19113F9, 0x7CA92FF6, 0x94324773, 0x22F54701, 0x3AE5E581, 0x37C2DADC, 0xC8B57634, 0x9AF3DDA7, 0xA9446146, 0x0FD0030E, 0xECC8C73E, 0xA4751E41, 0xE238CD99, 0x3BEA0E2F, 0x3280BBA1, 0x183EB331, 0x4E548B38, 0x4F6DB908, 0x6F420D03, 0xF60A04BF, 0x2CB81290, 0x24977C79, 0x5679B072, 0xBCAF89AF, 0xDE9A771F, 0xD9930810, 0xB38BAE12, 0xDCCF3F2E, 0x5512721F, 0x2E6B7124, 0x501ADDE6, 0x9F84CD87, 0x7A584718, 0x7408DA17, 0xBC9F9ABC, 0xE94B7D8C, 0xEC7AEC3A, 0xDB851DFA, 0x63094366, 0xC464C3D2, 0xEF1C1847, 0x3215D908, 0xDD433B37, 0x24C2BA16, 0x12A14D43, 0x2A65C451, 0x50940002, 0x133AE4DD, 0x71DFF89E, 0x10314E55, 0x81AC77D6, 0x5F11199B, 0x043556F1, 0xD7A3C76B, 0x3C11183B, 0x5924A509, 0xF28FE6ED, 0x97F1FBFA, 0x9EBABF2C, 0x1E153C6E, 0x86E34570, 0xEAE96FB1, 0x860E5E0A, 0x5A3E2AB3, 0x771FE71C, 0x4E3D06FA, 0x2965DCB9, 0x99E71D0F, 0x803E89D6, 0x5266C825, 0x2E4CC978, 0x9C10B36A, 0xC6150EBA, 0x94E2EA78, 0xA5FC3C53, 0x1E0A2DF4, 0xF2F74EA7, 0x361D2B3D, 0x1939260F, 0x19C27960, 0x5223A708, 0xF71312B6, 0xEBADFE6E, 0xEAC31F66, 0xE3BC4595, 0xA67BC883, 0xB17F37D1, 0x018CFF28, 0xC332DDEF, 0xBE6C5AA5, 0x65582185, 0x68AB9802, 0xEECEA50F, 0xDB2F953B, 0x2AEF7DAD, 0x5B6E2F84, 0x1521B628, 0x29076170, 0xECDD4775, 0x619F1510, 0x13CCA830, 0xEB61BD96, 0x0334FE1E, 0xAA0363CF, 0xB5735C90, 0x4C70A239, 0xD59E9E0B, 0xCBAADE14, 0xEECC86BC, 0x60622CA7, 0x9CAB5CAB, 0xB2F3846E, 0x648B1EAF, 0x19BDF0CA, 0xA02369B9, 0x655ABB50, 0x40685A32, 0x3C2AB4B3, 0x319EE9D5, 0xC021B8F7, 0x9B540B19, 0x875FA099, 0x95F7997E, 0x623D7DA8, 0xF837889A, 0x97E32D77, 0x11ED935F, 0x16681281, 0x0E358829, 0xC7E61FD6, 0x96DEDFA1, 0x7858BA99, 0x57F584A5, 0x1B227263, 0x9B83C3FF, 0x1AC24696, 0xCDB30AEB, 0x532E3054, 0x8FD948E4, 0x6DBC3128, 0x58EBF2EF, 0x34C6FFEA, 0xFE28ED61, 0xEE7C3C73, 0x5D4A14D9, 0xE864B7E3, 0x42105D14, 0x203E13E0, 0x45EEE2B6, 0xA3AAABEA, 0xDB6C4F15, 0xFACB4FD0, 0xC742F442, 0xEF6ABBB5, 0x654F3B1D, 0x41CD2105, 0xD81E799E, 0x86854DC7, 0xE44B476A, 0x3D816250, 0xCF62A1F2, 0x5B8D2646, 0xFC8883A0, 0xC1C7B6A3, 0x7F1524C3, 0x69CB7492, 0x47848A0B, 0x5692B285, 0x095BBF00, 0xAD19489D, 0x1462B174, 0x23820E00, 0x58428D2A, 0x0C55F5EA, 0x1DADF43E, 0x233F7061, 0x3372F092, 0x8D937E41, 0xD65FECF1, 0x6C223BDB, 0x7CDE3759, 0xCBEE7460, 0x4085F2A7, 0xCE77326E, 0xA6078084, 0x19F8509E, 0xE8EFD855, 0x61D99735, 0xA969A7AA, 0xC50C06C2, 0x5A04ABFC, 0x800BCADC, 0x9E447A2E, 0xC3453484, 0xFDD56705, 0x0E1E9EC9, 0xDB73DBD3, 0x105588CD, 0x675FDA79, 0xE3674340, 0xC5C43465, 0x713E38D8, 0x3D28F89E, 0xF16DFF20, 0x153E21E7, 0x8FB03D4A, 0xE6E39F2B, 0xDB83ADF7 }, KS2 = { 0xE93D5A68, 0x948140F7, 0xF64C261C, 0x94692934, 0x411520F7, 0x7602D4F7, 0xBCF46B2E, 0xD4A20068, 0xD4082471, 0x3320F46A, 0x43B7D4B7, 0x500061AF, 0x1E39F62E, 0x97244546, 0x14214F74, 0xBF8B8840, 0x4D95FC1D, 0x96B591AF, 0x70F4DDD3, 0x66A02F45, 0xBFBC09EC, 0x03BD9785, 0x7FAC6DD0, 0x31CB8504, 0x96EB27B3, 0x55FD3941, 0xDA2547E6, 0xABCA0A9A, 0x28507825, 0x530429F4, 0x0A2C86DA, 0xE9B66DFB, 0x68DC1462, 0xD7486900, 0x680EC0A4, 0x27A18DEE, 0x4F3FFEA2, 0xE887AD8C, 0xB58CE006, 0x7AF4D6B6, 0xAACE1E7C, 0xD3375FEC, 0xCE78A399, 0x406B2A42, 0x20FE9E35, 0xD9F385B9, 0xEE39D7AB, 0x3B124E8B, 0x1DC9FAF7, 0x4B6D1856, 0x26A36631, 0xEAE397B2, 0x3A6EFA74, 0xDD5B4332, 0x6841E7F7, 0xCA7820FB, 0xFB0AF54E, 0xD8FEB397, 0x454056AC, 0xBA489527, 0x55533A3A, 0x20838D87, 0xFE6BA9B7, 0xD096954B, 0x55A867BC, 0xA1159A58, 0xCCA92963, 0x99E1DB33, 0xA62A4A56, 0x3F3125F9, 0x5EF47E1C, 0x9029317C, 0xFDF8E802, 0x04272F70, 0x80BB155C, 0x05282CE3, 0x95C11548, 0xE4C66D22, 0x48C1133F, 0xC70F86DC, 0x07F9C9EE, 0x41041F0F, 0x404779A4, 0x5D886E17, 0x325F51EB, 0xD59BC0D1, 0xF2BCC18F, 0x41113564, 0x257B7834, 0x602A9C60, 0xDFF8E8A3, 0x1F636C1B, 0x0E12B4C2, 0x02E1329E, 0xAF664FD1, 0xCAD18115, 0x6B2395E0, 0x333E92E1, 0x3B240B62, 0xEEBEB922, 0x85B2A20E, 0xE6BA0D99, 0xDE720C8C, 0x2DA2F728, 0xD0127845, 0x95B794FD, 0x647D0862, 0xE7CCF5F0, 0x5449A36F, 0x877D48FA, 0xC39DFD27, 0xF33E8D1E, 0x0A476341, 0x992EFF74, 0x3A6F6EAB, 0xF4F8FD37, 0xA812DC60, 0xA1EBDDF8, 0x991BE14C, 0xDB6E6B0D, 0xC67B5510, 0x6D672C37, 0x2765D43B, 0xDCD0E804, 0xF1290DC7, 0xCC00FFA3, 0xB5390F92, 0x690FED0B, 0x667B9FFB, 0xCEDB7D9C, 0xA091CF0B, 0xD9155EA3, 0xBB132F88, 0x515BAD24, 0x7B9479BF, 0x763BD6EB, 0x37392EB3, 0xCC115979, 0x8026E297, 0xF42E312D, 0x6842ADA7, 0xC66A2B3B, 0x12754CCC, 0x782EF11C, 0x6A124237, 0xB79251E7, 0x06A1BBE6, 0x4BFB6350, 0x1A6B1018, 0x11CAEDFA, 0x3D25BDD8, 0xE2E1C3C9, 0x44421659, 0x0A121386, 0xD90CEC6E, 0xD5ABEA2A, 0x64AF674E, 0xDA86A85F, 0xBEBFE988, 0x64E4C3FE, 0x9DBC8057, 0xF0F7C086, 0x60787BF8, 0x6003604D, 0xD1FD8346, 0xF6381FB0, 0x7745AE04, 0xD736FCCC, 0x83426B33, 0xF01EAB71, 0xB0804187, 0x3C005E5F, 0x77A057BE, 0xBDE8AE24, 0x55464299, 0xBF582E61, 0x4E58F48F, 0xF2DDFDA2, 0xF474EF38, 0x8789BDC2, 0x5366F9C3, 0xC8B38E74, 0xB475F255, 0x46FCD9B9, 0x7AEB2661, 0x8B1DDF84, 0x846A0E79, 0x915F95E2, 0x466E598E, 0x20B45770, 0x8CD55591, 0xC902DE4C, 0xB90BACE1, 0xBB8205D0, 0x11A86248, 0x7574A99E, 0xB77F19B6, 0xE0A9DC09, 0x662D09A1, 0xC4324633, 0xE85A1F02, 0x09F0BE8C, 0x4A99A025, 0x1D6EFE10, 0x1AB93D1D, 0x0BA5A4DF, 0xA186F20F, 0x2868F169, 0xDCB7DA83, 0x573906FE, 0xA1E2CE9B, 0x4FCD7F52, 0x50115E01, 0xA70683FA, 0xA002B5C4, 0x0DE6D027, 0x9AF88C27, 0x773F8641, 0xC3604C06, 0x61A806B5, 0xF0177A28, 0xC0F586E0, 0x006058AA, 0x30DC7D62, 0x11E69ED7, 0x2338EA63, 0x53C2DD94, 0xC2C21634, 0xBBCBEE56, 0x90BCB6DE, 0xEBFC7DA1, 0xCE591D76, 0x6F05E409, 0x4B7C0188, 0x39720A3D, 0x7C927C24, 0x86E3725F, 0x724D9DB9, 0x1AC15BB4, 0xD39EB8FC, 0xED545578, 0x08FCA5B5, 0xD83D7CD3, 0x4DAD0FC4, 0x1E50EF5E, 0xB161E6F8, 0xA28514D9, 0x6C51133C, 0x6FD5C7E7, 0x56E14EC4, 0x362ABFCE, 0xDDC6C837, 0xD79A3234, 0x92638212, 0x670EFA8E, 0x406000E0 }, KS3 = { 0x3A39CE37, 0xD3FAF5CF, 0xABC27737, 0x5AC52D1B, 0x5CB0679E, 0x4FA33742, 0xD3822740, 0x99BC9BBE, 0xD5118E9D, 0xBF0F7315, 0xD62D1C7E, 0xC700C47B, 0xB78C1B6B, 0x21A19045, 0xB26EB1BE, 0x6A366EB4, 0x5748AB2F, 0xBC946E79, 0xC6A376D2, 0x6549C2C8, 0x530FF8EE, 0x468DDE7D, 0xD5730A1D, 0x4CD04DC6, 0x2939BBDB, 0xA9BA4650, 0xAC9526E8, 0xBE5EE304, 0xA1FAD5F0, 0x6A2D519A, 0x63EF8CE2, 0x9A86EE22, 0xC089C2B8, 0x43242EF6, 0xA51E03AA, 0x9CF2D0A4, 0x83C061BA, 0x9BE96A4D, 0x8FE51550, 0xBA645BD6, 0x2826A2F9, 0xA73A3AE1, 0x4BA99586, 0xEF5562E9, 0xC72FEFD3, 0xF752F7DA, 0x3F046F69, 0x77FA0A59, 0x80E4A915, 0x87B08601, 0x9B09E6AD, 0x3B3EE593, 0xE990FD5A, 0x9E34D797, 0x2CF0B7D9, 0x022B8B51, 0x96D5AC3A, 0x017DA67D, 0xD1CF3ED6, 0x7C7D2D28, 0x1F9F25CF, 0xADF2B89B, 0x5AD6B472, 0x5A88F54C, 0xE029AC71, 0xE019A5E6, 0x47B0ACFD, 0xED93FA9B, 0xE8D3C48D, 0x283B57CC, 0xF8D56629, 0x79132E28, 0x785F0191, 0xED756055, 0xF7960E44, 0xE3D35E8C, 0x15056DD4, 0x88F46DBA, 0x03A16125, 0x0564F0BD, 0xC3EB9E15, 0x3C9057A2, 0x97271AEC, 0xA93A072A, 0x1B3F6D9B, 0x1E6321F5, 0xF59C66FB, 0x26DCF319, 0x7533D928, 0xB155FDF5, 0x03563482, 0x8ABA3CBB, 0x28517711, 0xC20AD9F8, 0xABCC5167, 0xCCAD925F, 0x4DE81751, 0x3830DC8E, 0x379D5862, 0x9320F991, 0xEA7A90C2, 0xFB3E7BCE, 0x5121CE64, 0x774FBE32, 0xA8B6E37E, 0xC3293D46, 0x48DE5369, 0x6413E680, 0xA2AE0810, 0xDD6DB224, 0x69852DFD, 0x09072166, 0xB39A460A, 0x6445C0DD, 0x586CDECF, 0x1C20C8AE, 0x5BBEF7DD, 0x1B588D40, 0xCCD2017F, 0x6BB4E3BB, 0xDDA26A7E, 0x3A59FF45, 0x3E350A44, 0xBCB4CDD5, 0x72EACEA8, 0xFA6484BB, 0x8D6612AE, 0xBF3C6F47, 0xD29BE463, 0x542F5D9E, 0xAEC2771B, 0xF64E6370, 0x740E0D8D, 0xE75B1357, 0xF8721671, 0xAF537D5D, 0x4040CB08, 0x4EB4E2CC, 0x34D2466A, 0x0115AF84, 0xE1B00428, 0x95983A1D, 0x06B89FB4, 0xCE6EA048, 0x6F3F3B82, 0x3520AB82, 0x011A1D4B, 0x277227F8, 0x611560B1, 0xE7933FDC, 0xBB3A792B, 0x344525BD, 0xA08839E1, 0x51CE794B, 0x2F32C9B7, 0xA01FBAC9, 0xE01CC87E, 0xBCC7D1F6, 0xCF0111C3, 0xA1E8AAC7, 0x1A908749, 0xD44FBD9A, 0xD0DADECB, 0xD50ADA38, 0x0339C32A, 0xC6913667, 0x8DF9317C, 0xE0B12B4F, 0xF79E59B7, 0x43F5BB3A, 0xF2D519FF, 0x27D9459C, 0xBF97222C, 0x15E6FC2A, 0x0F91FC71, 0x9B941525, 0xFAE59361, 0xCEB69CEB, 0xC2A86459, 0x12BAA8D1, 0xB6C1075E, 0xE3056A0C, 0x10D25065, 0xCB03A442, 0xE0EC6E0E, 0x1698DB3B, 0x4C98A0BE, 0x3278E964, 0x9F1F9532, 0xE0D392DF, 0xD3A0342B, 0x8971F21E, 0x1B0A7441, 0x4BA3348C, 0xC5BE7120, 0xC37632D8, 0xDF359F8D, 0x9B992F2E, 0xE60B6F47, 0x0FE3F11D, 0xE54CDA54, 0x1EDAD891, 0xCE6279CF, 0xCD3E7E6F, 0x1618B166, 0xFD2C1D05, 0x848FD2C5, 0xF6FB2299, 0xF523F357, 0xA6327623, 0x93A83531, 0x56CCCD02, 0xACF08162, 0x5A75EBB5, 0x6E163697, 0x88D273CC, 0xDE966292, 0x81B949D0, 0x4C50901B, 0x71C65614, 0xE6C6C7BD, 0x327A140A, 0x45E1D006, 0xC3F27B9A, 0xC9AA53FD, 0x62A80F00, 0xBB25BFE2, 0x35BDD2F6, 0x71126905, 0xB2040222, 0xB6CBCF7C, 0xCD769C2B, 0x53113EC0, 0x1640E3D3, 0x38ABBD60, 0x2547ADF0, 0xBA38209C, 0xF746CE76, 0x77AFA1C5, 0x20756060, 0x85CBFE4E, 0x8AE88DD8, 0x7AAAF9B0, 0x4CF9AA7E, 0x1948C25C, 0x02FB8A8C, 0x01C36AE4, 0xD6EBE1F9, 0x90D4F869, 0xA65CDEA0, 0x3F09252D, 0xC208E69F, 0xB74E6132, 0xCE77E25B, 0x578FDFE3, 0x3AC372E6 }; //==================================== // Useful constants //==================================== private static final int ROUNDS = 16; private static final int BLOCK_SIZE = 8; // bytes = 64 bits private static final int SBOX_SK = 256; private static final int SBOX_KA = 4; private static final int P_SZ = ROUNDS+2; private int S[][]; // the s-boxes private int P[]; // the p-array private boolean isInit = false; private boolean encrypting = false; private byte[] workingKey = null; public BlowfishEngine() { S = new int[SBOX_KA][SBOX_SK]; P = new int[P_SZ]; } /** * initialise a Blowfish cipher. * * @param forEncryption whether or not we are for encryption. * @param params the parameters required to set up the cipher. * @exception IllegalArgumentException if the params argument is * inappropriate. */ public void init( boolean encrypting, CipherParameters params) { if (params instanceof KeyParameter) { this.encrypting = encrypting; this.workingKey = ((KeyParameter)params).getKey(); setKey(this.workingKey); return; } throw new IllegalArgumentException("invalid parameter passed to Blowfish init - " + params.getClass().getName()); } public String getAlgorithmName() { return "Blowfish"; } public int processBlock( byte[] in, int inOff, byte[] out, int outOff) { if (workingKey == null) { throw new IllegalStateException("Blowfish not initialised"); } if ((inOff + BLOCK_SIZE) > in.length) { throw new DataLengthException("input buffer too short"); } if ((outOff + BLOCK_SIZE) > out.length) { throw new DataLengthException("output buffer too short"); } if (encrypting) { encryptBlock(in, inOff, out, outOff); } else { decryptBlock(in, inOff, out, outOff); } return BLOCK_SIZE; } public void reset() { } public int getBlockSize() { return BLOCK_SIZE; } //================================== // Private Implementation //================================== private void setKey(byte[] key) { /* * - comments are from _Applied Crypto_, Schneier, p338 * please be careful comparing the two, AC numbers the * arrays from 1, the enclosed code from 0. * * (1) * Initialise the S-boxes and the P-array, with a fixed string * This string contains the hexadecimal digits of pi (3.141...) */ System.arraycopy(KS0, 0, S[0], 0, SBOX_SK); System.arraycopy(KS1, 0, S[1], 0, SBOX_SK); System.arraycopy(KS2, 0, S[2], 0, SBOX_SK); System.arraycopy(KS3, 0, S[3], 0, SBOX_SK); System.arraycopy(KP, 0, P, 0, P_SZ); /* * (2) * Now, XOR P[0] with the first 32 bits of the key, XOR P[1] with the * second 32-bits of the key, and so on for all bits of the key * (up to P[17]). Repeatedly cycle through the key bits until the * entire P-array has been XOR-ed with the key bits */ int keyLength = key.length; int keyIndex = 0; for (int i=0;i< P_SZ; i++) { // get the 32 bits of the key, in 4 * 8 bit chunks int data = 0x0000000; for (int j=0; j < 4; j++) { // create a 32 bit block data = data << 8; data |= (int) (key[keyIndex] & 0xff); keyIndex++; // wrap when we get to the end of the key if (keyIndex >= keyLength) { keyIndex = 0; } } // XOR the newly created 32 bit chunk onto the P-array P[i] = P[i] ^ data; } /* * (3) * Encrypt the all-zero string with the Blowfish algorithm, using * the subkeys described in (1) and (2) */ int result[] = new int[2]; /* * (4) * Replace P1 and P2 with the output of step (3) * * (5) * Encrypt the output of step(3) using the Blowfish algorithm, * with the modified subkeys. * * (6) * Replace P3 and P4 with the output of step (5) * * (7) * Continue the process, replacing all elements of the P-array * and then all four S-boxes in order, with the output of the * continuously changing Blowfish algorithm */ int data_l = 0; int data_r = 0; for (int i=0; i< P_SZ; i+=2) { BF_Encipher(data_l, data_r, result); data_l = P[i] = result[0]; data_r = P[i+1] = result[1]; } for (int i=0; i< 4; ++i) { for (int s=0; s>> 8) & 0x00ff; b = (x >>> 16) & 0x00ff; a = (x >>> 24); return ((S[0][a] + S[1][b]) ^ S[2][c]) + S[3][d]; } private void BF_Encipher(int xl, int xr, int result[]) { xl ^= P[0]; for (int i = 1; i < ROUNDS; i += 2) { xr ^= F(xl) ^ P[i]; xl ^= F(xr) ^ P[i + 1]; } xr ^= P[ROUNDS + 1]; result[0] = xr; result[1] = xl; return; } private void BF_Decipher(int xl, int xr, int result[]) { xl ^= P[ROUNDS + 1]; for (int i = ROUNDS; i > 0 ; i -= 2) { xr ^= F(xl) ^ P[i]; xl ^= F(xr) ^ P[i - 1]; } xr ^= P[0]; result[0] = xr; result[1] = xl; } private int BytesTo32bits(byte[] b, int i) { int rv = 0; rv = ((b[i] & 0xff) << 24) | ((b[i+1] & 0xff) << 16) | ((b[i+2] & 0xff) << 8) | ((b[i+3] & 0xff)); return rv; } private void Bits32ToBytes(int in, byte[] b, int offset) { b[offset + 3] = (byte)in; b[offset + 2] = (byte)(in >> 8); b[offset + 1] = (byte)(in >> 16); b[offset] = (byte)(in >> 24); } } bouncycastle-1.49.orig/jdk1.0/org/bouncycastle/asn1/0000755000175000017500000000000012152033551021541 5ustar ebourgebourgbouncycastle-1.49.orig/jdk1.0/org/bouncycastle/asn1/DERIA5String.java0000644000175000017500000000446510262753175024530 0ustar ebourgebourgpackage org.bouncycastle.asn1; import java.io.IOException; /** * DER IA5String object - this is an ascii string, strictly speaking * we don't handle this correctly as we're taking advantage of the fact the * default platform encoding is ascii... later! */ public class DERIA5String extends DERObject { String string; /** * return a IA5 string from the passed in object * * @exception IllegalArgumentException if the object cannot be converted. */ public static DERIA5String getInstance( Object obj) { if (obj == null || obj instanceof DERIA5String) { return (DERIA5String)obj; } if (obj instanceof ASN1OctetString) { return new DERIA5String(((ASN1OctetString)obj).getOctets()); } throw new IllegalArgumentException("illegal object in getInstance: " + obj.getClass().getName()); } /** * return an IA5 String from a tagged object. * * @param obj the tagged object holding the object we want * @param explicit true if the object is meant to be explicitly * tagged false otherwise. * @exception IllegalArgumentException if the tagged object cannot * be converted. */ public static DERIA5String getInstance( ASN1TaggedObject obj, boolean explicit) { return getInstance(obj.getObject()); } public DERIA5String( String string) { this.string = string; } /** * @param string - bytes representing the string. */ public DERIA5String( byte[] string) { this.string = new String(string, 0); } public String getString() { return string; } void encode( DEROutputStream out) throws IOException { byte[] bytes = new byte[string.length()]; string.getBytes(0, string.length(), bytes, 0); out.writeEncoded(IA5_STRING, bytes); } public int hashCode() { return this.getString().hashCode(); } public boolean equals( Object o) { if (!(o instanceof DERIA5String)) { return false; } DERIA5String s = (DERIA5String)o; return this.getString().equals(s.getString()); } } bouncycastle-1.49.orig/jdk1.0/org/bouncycastle/asn1/DERUTCTime.java0000644000175000017500000000365610262753175024236 0ustar ebourgebourgpackage org.bouncycastle.asn1; import java.io.IOException; /** * UTC time object. */ public class DERUTCTime extends DERObject { String time; /** * @param data the octets making up the time. */ public DERUTCTime( String time) { this.time = time; } DERUTCTime( byte[] bytes) { // // explicitly convert to characters // char[] dateC = new char[bytes.length]; for (int i = 0; i != dateC.length; i++) { dateC[i] = (char)(bytes[i] & 0xff); } this.time = new String(dateC); } /** * return the time - always in the form of * YYMMDDhhmmss[Z|+hh'mm'|-hh'mm'] */ public String getTime() { // // standardise the format. // if (time.length() == 11) { return time.substring(0, 10) + "00Z"; } else if (time.length() == 17) { return time.substring(0, 10) + "00" + time.substring(10); } return time; } /** * return the time as an adjusted date with a 4 digit year. This goes * in the range of 1950 - 2049. */ public String getAdjustedTime() { String d = this.getTime(); if (d.charAt(0) < '5') { return "20" + d; } else { return "19" + d; } } void encode( DEROutputStream out) throws IOException { byte[] bytes = new byte[time.length()]; time.getBytes(0, time.length(), bytes, 0); out.writeEncoded(UTC_TIME, bytes); } public boolean equals( Object o) { if ((o == null) || !(o instanceof DERUTCTime)) { return false; } return time.equals(((DERUTCTime)o).time); } public int hashCode() { return time.hashCode(); } } bouncycastle-1.49.orig/jdk1.0/org/bouncycastle/asn1/DERGeneralizedTime.java0000644000175000017500000001032610350737002026011 0ustar ebourgebourgpackage org.bouncycastle.asn1; import java.io.IOException; /** * Generalized time object. */ public class DERGeneralizedTime extends DERObject { String time; /** * return a generalized time from the passed in object * * @exception IllegalArgumentException if the object cannot be converted. */ public static DERGeneralizedTime getInstance( Object obj) { if (obj == null || obj instanceof DERGeneralizedTime) { return (DERGeneralizedTime)obj; } if (obj instanceof ASN1OctetString) { return new DERGeneralizedTime(((ASN1OctetString)obj).getOctets()); } throw new IllegalArgumentException("illegal object in getInstance: " + obj.getClass().getName()); } /** * return a Generalized Time object from a tagged object. * * @param obj the tagged object holding the object we want * @param explicit true if the object is meant to be explicitly * tagged false otherwise. * @exception IllegalArgumentException if the tagged object cannot * be converted. */ public static DERGeneralizedTime getInstance( ASN1TaggedObject obj, boolean explicit) { return getInstance(obj.getObject()); } /** * The correct format for this is YYYYMMDDHHMMSSZ, or without the Z * for local time, or Z+-HHMM on the end, for difference between local * time and UTC time. *

* * @param time the time string. */ public DERGeneralizedTime( String time) { this.time = time; } DERGeneralizedTime( byte[] bytes) { // // explicitly convert to characters // char[] dateC = new char[bytes.length]; for (int i = 0; i != dateC.length; i++) { dateC[i] = (char)(bytes[i] & 0xff); } this.time = new String(dateC); } /** * return the time - always in the form of * YYYYMMDDhhmmssGMT(+hh:mm|-hh:mm). *

* Normally in a certificate we would expect "Z" rather than "GMT", * however adding the "GMT" means we can just use: *

     *     dateF = new SimpleDateFormat("yyyyMMddHHmmssz");
     * 
* To read in the time and get a date which is compatible with our local * time zone. */ public String getTime() { // // standardise the format. // if (time.charAt(time.length() - 1) == 'Z') { return time.substring(0, time.length() - 1) + "GMT+00:00"; } else { int signPos = time.length() - 5; char sign = time.charAt(signPos); if (sign == '-' || sign == '+') { return time.substring(0, signPos) + "GMT" + time.substring(signPos, signPos + 3) + ":" + time.substring(signPos + 3); } else { signPos = time.length() - 3; sign = time.charAt(signPos); if (sign == '-' || sign == '+') { return time.substring(0, signPos) + "GMT" + time.substring(signPos) + ":00"; } } } return time; } private byte[] getOctets() { char[] cs = time.toCharArray(); byte[] bs = new byte[cs.length]; for (int i = 0; i != cs.length; i++) { bs[i] = (byte)cs[i]; } return bs; } public boolean equals( Object o) { if ((o == null) || !(o instanceof DERGeneralizedTime)) { return false; } return time.equals(((DERGeneralizedTime)o).time); } public int hashCode() { return time.hashCode(); } void encode( DEROutputStream out) throws IOException { byte[] bytes = new byte[time.length()]; time.getBytes(0, time.length(), bytes, 0); out.writeEncoded(GENERALIZED_TIME, bytes); } } bouncycastle-1.49.orig/jdk1.0/org/bouncycastle/asn1/x9/0000755000175000017500000000000012152033551022101 5ustar ebourgebourgbouncycastle-1.49.orig/jdk1.0/org/bouncycastle/asn1/x9/X9FieldID.java0000644000175000017500000000300010262753175024431 0ustar ebourgebourgpackage org.bouncycastle.asn1.x9; import java.math.BigInteger; import org.bouncycastle.asn1.ASN1EncodableVector; import org.bouncycastle.asn1.ASN1Sequence; import org.bouncycastle.asn1.DEREncodable; import org.bouncycastle.asn1.DERInteger; import org.bouncycastle.asn1.DERObject; import org.bouncycastle.asn1.DERObjectIdentifier; import org.bouncycastle.asn1.DERSequence; /** * ASN.1 def for Elliptic-Curve Field ID structure. See * X9.62, for further details. */ public class X9FieldID implements DEREncodable, X9ObjectIdentifiers { private DERObjectIdentifier id; private DERObject parameters; public X9FieldID( DERObjectIdentifier id, BigInteger primeP) { this.id = id; this.parameters = new DERInteger(primeP); } public X9FieldID( ASN1Sequence seq) { this.id = (DERObjectIdentifier)seq.getObjectAt(0); this.parameters = (DERObject)seq.getObjectAt(1); } public DERObjectIdentifier getIdentifier() { return id; } public DERObject getParameters() { return parameters; } /** *
     *  FieldID ::= SEQUENCE {
     *      fieldType       FIELD-ID.&id({IOSet}),
     *      parameters      FIELD-ID.&Type({IOSet}{@fieldType})
     *  }
     * 
*/ public DERObject getDERObject() { ASN1EncodableVector seq = new ASN1EncodableVector(); seq.add(this.id); seq.add(this.parameters); return new DERSequence(seq); } } bouncycastle-1.49.orig/jdk1.0/org/bouncycastle/asn1/x9/OtherInfo.java0000644000175000017500000000437410262753175024664 0ustar ebourgebourgpackage org.bouncycastle.asn1.x9; import java.util.Enumeration; import org.bouncycastle.asn1.ASN1EncodableVector; import org.bouncycastle.asn1.ASN1OctetString; import org.bouncycastle.asn1.ASN1Sequence; import org.bouncycastle.asn1.DEREncodable; import org.bouncycastle.asn1.DERObject; import org.bouncycastle.asn1.DERSequence; import org.bouncycastle.asn1.DERTaggedObject; /** * ANS.1 def for Diffie-Hellman key exchange OtherInfo structure. See * RFC 2631, or X9.42, for further details. */ public class OtherInfo implements DEREncodable { private KeySpecificInfo keyInfo; private ASN1OctetString partyAInfo; private ASN1OctetString suppPubInfo; public OtherInfo( KeySpecificInfo keyInfo, ASN1OctetString partyAInfo, ASN1OctetString suppPubInfo) { this.keyInfo = keyInfo; this.partyAInfo = partyAInfo; this.suppPubInfo = suppPubInfo; } public OtherInfo( ASN1Sequence seq) { Enumeration e = seq.getObjects(); keyInfo = new KeySpecificInfo((ASN1Sequence)e.nextElement()); while (e.hasMoreElements()) { DERTaggedObject o = (DERTaggedObject)e.nextElement(); if (o.getTagNo() == 0) { partyAInfo = (ASN1OctetString)o.getObject(); } else if (o.getTagNo() == 2) { suppPubInfo = (ASN1OctetString)o.getObject(); } } } public KeySpecificInfo getKeyInfo() { return keyInfo; } public ASN1OctetString getPartyAInfo() { return partyAInfo; } public ASN1OctetString getSuppPubInfo() { return suppPubInfo; } /** *
     *  OtherInfo ::= SEQUENCE {
     *      keyInfo KeySpecificInfo,
     *      partyAInfo [0] OCTET STRING OPTIONAL,
     *      suppPubInfo [2] OCTET STRING
     *  }
     * 
*/ public DERObject getDERObject() { ASN1EncodableVector seq = new ASN1EncodableVector(); seq.add(keyInfo); if (partyAInfo != null) { seq.add(new DERTaggedObject(0, partyAInfo)); } seq.add(new DERTaggedObject(2, suppPubInfo)); return new DERSequence(seq); } } bouncycastle-1.49.orig/jdk1.0/org/bouncycastle/asn1/x9/X9ECParameters.java0000644000175000017500000000720710533203640025505 0ustar ebourgebourgpackage org.bouncycastle.asn1.x9; import java.math.BigInteger; import org.bouncycastle.asn1.ASN1EncodableVector; import org.bouncycastle.asn1.ASN1OctetString; import org.bouncycastle.asn1.ASN1Sequence; import org.bouncycastle.asn1.DEREncodable; import org.bouncycastle.asn1.DERInteger; import org.bouncycastle.asn1.DERObject; import org.bouncycastle.asn1.DERSequence; import org.bouncycastle.math.ec.ECCurve; import org.bouncycastle.math.ec.ECCurveFp; import org.bouncycastle.math.ec.ECPoint; /** * ASN.1 def for Elliptic-Curve ECParameters structure. See * X9.62, for further details. */ public class X9ECParameters implements DEREncodable, X9ObjectIdentifiers { private static final BigInteger ONE = BigInteger.valueOf(1); private X9FieldID fieldID; private ECCurve curve; private ECPoint g; private BigInteger n; private BigInteger h; private byte[] seed; public X9ECParameters( ASN1Sequence seq) { if (!(seq.getObjectAt(0) instanceof DERInteger) || !((DERInteger)seq.getObjectAt(0)).getValue().equals(ONE)) { throw new IllegalArgumentException("bad version in X9ECParameters"); } X9Curve x9c = new X9Curve( new X9FieldID((ASN1Sequence)seq.getObjectAt(1)), (ASN1Sequence)seq.getObjectAt(2)); this.curve = x9c.getCurve(); this.g = new X9ECPoint(curve, (ASN1OctetString)seq.getObjectAt(3)).getPoint(); this.n = ((DERInteger)seq.getObjectAt(4)).getValue(); this.seed = x9c.getSeed(); if (seq.size() == 6) { this.h = ((DERInteger)seq.getObjectAt(5)).getValue(); } } public X9ECParameters( ECCurve curve, ECPoint g, BigInteger n) { this(curve, g, n, ONE, null); } public X9ECParameters( ECCurve curve, ECPoint g, BigInteger n, BigInteger h) { this(curve, g, n, h, null); } public X9ECParameters( ECCurve curve, ECPoint g, BigInteger n, BigInteger h, byte[] seed) { this.curve = curve; this.g = g; this.n = n; this.h = h; this.seed = seed; if (curve instanceof ECCurveFp) { this.fieldID = new X9FieldID(prime_field, ((ECCurveFp)curve).getQ()); } else { this.fieldID = new X9FieldID(characteristic_two_field, null); } } public ECCurve getCurve() { return curve; } public ECPoint getG() { return g; } public BigInteger getN() { return n; } public BigInteger getH() { return h; } public byte[] getSeed() { return seed; } /** *
     *  ECParameters ::= SEQUENCE {
     *      version         INTEGER { ecpVer1(1) } (ecpVer1),
     *      fieldID         FieldID {{FieldTypes}},
     *      curve           X9Curve,
     *      base            X9ECPoint,
     *      order           INTEGER,
     *      cofactor        INTEGER OPTIONAL
     *  }
     * 
*/ public DERObject getDERObject() { ASN1EncodableVector seq = new ASN1EncodableVector(); seq.add(new DERInteger(1)); seq.add(fieldID); seq.add(new X9Curve(curve, seed)); seq.add(new X9ECPoint(g)); seq.add(new DERInteger(n)); if (!h.equals(BigInteger.valueOf(1))) { seq.add(new DERInteger(h)); } return new DERSequence(seq); } } bouncycastle-1.49.orig/jdk1.0/org/bouncycastle/asn1/x9/X9ObjectIdentifiers.java0000644000175000017500000000556110262753175026603 0ustar ebourgebourgpackage org.bouncycastle.asn1.x9; import org.bouncycastle.asn1.DERObjectIdentifier; public interface X9ObjectIdentifiers { // // X9.62 // // ansi-X9-62 OBJECT IDENTIFIER ::= { iso(1) member-body(2) // us(840) ansi-x962(10045) } // static final String ansi_X9_62 = "1.2.840.10045"; static final String id_fieldType = ansi_X9_62 + ".1"; static final DERObjectIdentifier prime_field = new DERObjectIdentifier(id_fieldType + ".1"); static final DERObjectIdentifier characteristic_two_field = new DERObjectIdentifier(id_fieldType + ".2"); static final DERObjectIdentifier gnBasis = new DERObjectIdentifier(id_fieldType + ".2.3.1"); static final DERObjectIdentifier tpBasis = new DERObjectIdentifier(id_fieldType + ".2.3.2"); static final DERObjectIdentifier ppBasis = new DERObjectIdentifier(id_fieldType + ".2.3.3"); static final String id_ecSigType = ansi_X9_62 + ".4"; static final DERObjectIdentifier ecdsa_with_SHA1 = new DERObjectIdentifier(id_ecSigType + ".1"); static final String id_publicKeyType = ansi_X9_62 + ".2"; static final DERObjectIdentifier id_ecPublicKey = new DERObjectIdentifier(id_publicKeyType + ".1"); // // named curves // static final String ellipticCurve = ansi_X9_62 + ".3"; // // Prime // static final String primeCurve = ellipticCurve + ".1"; static final DERObjectIdentifier prime192v1 = new DERObjectIdentifier(primeCurve + ".1"); static final DERObjectIdentifier prime192v2 = new DERObjectIdentifier(primeCurve + ".2"); static final DERObjectIdentifier prime192v3 = new DERObjectIdentifier(primeCurve + ".3"); static final DERObjectIdentifier prime239v1 = new DERObjectIdentifier(primeCurve + ".4"); static final DERObjectIdentifier prime239v2 = new DERObjectIdentifier(primeCurve + ".5"); static final DERObjectIdentifier prime239v3 = new DERObjectIdentifier(primeCurve + ".6"); static final DERObjectIdentifier prime256v1 = new DERObjectIdentifier(primeCurve + ".7"); // // Diffie-Hellman // // dhpublicnumber OBJECT IDENTIFIER ::= { iso(1) member-body(2) // us(840) ansi-x942(10046) number-type(2) 1 } // static final DERObjectIdentifier dhpublicnumber = new DERObjectIdentifier("1.2.840.10046.2.1"); // // DSA // // dsapublicnumber OBJECT IDENTIFIER ::= { iso(1) member-body(2) // us(840) ansi-x957(10040) number-type(4) 1 } static final DERObjectIdentifier id_dsa = new DERObjectIdentifier("1.2.840.10040.4.1"); } bouncycastle-1.49.orig/jdk1.0/org/bouncycastle/asn1/x9/X9Curve.java0000644000175000017500000000460710262753175024273 0ustar ebourgebourgpackage org.bouncycastle.asn1.x9; import java.math.BigInteger; import org.bouncycastle.asn1.ASN1EncodableVector; import org.bouncycastle.asn1.ASN1OctetString; import org.bouncycastle.asn1.ASN1Sequence; import org.bouncycastle.asn1.DERBitString; import org.bouncycastle.asn1.DEREncodable; import org.bouncycastle.asn1.DERInteger; import org.bouncycastle.asn1.DERObject; import org.bouncycastle.asn1.DERSequence; import org.bouncycastle.math.ec.ECCurve; import org.bouncycastle.math.ec.ECCurveFp; /** * ASN.1 def for Elliptic-Curve Curve structure. See * X9.62, for further details. */ public class X9Curve implements DEREncodable, X9ObjectIdentifiers { private ECCurve curve; private byte[] seed; public X9Curve( ECCurve curve) { this.curve = curve; this.seed = null; } public X9Curve( ECCurve curve, byte[] seed) { this.curve = curve; this.seed = seed; } public X9Curve( X9FieldID fieldID, ASN1Sequence seq) { if (fieldID.getIdentifier().equals(prime_field)) { BigInteger q = ((DERInteger)fieldID.getParameters()).getValue(); X9FieldElement x9A = new X9FieldElement(true, q, (ASN1OctetString)seq.getObjectAt(0)); X9FieldElement x9B = new X9FieldElement(true, q, (ASN1OctetString)seq.getObjectAt(1)); curve = new ECCurveFp(q, x9A.getValue().toBigInteger(), x9B.getValue().toBigInteger()); } else { throw new RuntimeException("not implemented"); } if (seq.size() == 3) { seed = ((DERBitString)seq.getObjectAt(2)).getBytes(); } } public ECCurve getCurve() { return curve; } public byte[] getSeed() { return seed; } /** *
     *  Curve ::= SEQUENCE {
     *      a               FieldElement,
     *      b               FieldElement,
     *      seed            BIT STRING      OPTIONAL
     *  }
     * 
*/ public DERObject getDERObject() { ASN1EncodableVector seq = new ASN1EncodableVector(); seq.add(new X9FieldElement(curve.getA()).getDERObject()); seq.add(new X9FieldElement(curve.getB()).getDERObject()); if (seed != null) { seq.add(new DERBitString(seed)); } return new DERSequence(seq); } } bouncycastle-1.49.orig/jdk1.0/org/bouncycastle/asn1/x9/X962Parameters.java0000644000175000017500000000214210262753175025452 0ustar ebourgebourgpackage org.bouncycastle.asn1.x9; import org.bouncycastle.asn1.ASN1Choice; import org.bouncycastle.asn1.DEREncodable; import org.bouncycastle.asn1.DERObject; import org.bouncycastle.asn1.DERObjectIdentifier; public class X962Parameters implements DEREncodable, ASN1Choice { private DERObject params = null; public X962Parameters( X9ECParameters ecParameters) { this.params = ecParameters.getDERObject(); } public X962Parameters( DERObjectIdentifier namedCurve) { this.params = namedCurve; } public X962Parameters( DERObject obj) { this.params = obj; } public boolean isNamedCurve() { return (params instanceof DERObjectIdentifier); } public DERObject getParameters() { return params; } /** *
     * Parameters ::= CHOICE {
     *    ecParameters ECParameters,
     *    namedCurve   CURVES.&id({CurveNames}),
     *    implicitlyCA NULL
     * }
     * 
*/ public DERObject getDERObject() { return params; } } bouncycastle-1.49.orig/jdk1.0/org/bouncycastle/asn1/x9/X9ECPoint.java0000644000175000017500000000165310262753175024506 0ustar ebourgebourgpackage org.bouncycastle.asn1.x9; import org.bouncycastle.asn1.ASN1OctetString; import org.bouncycastle.asn1.DEREncodable; import org.bouncycastle.asn1.DERObject; import org.bouncycastle.asn1.DEROctetString; import org.bouncycastle.math.ec.ECCurve; import org.bouncycastle.math.ec.ECPoint; /** * class for describing an ECPoint as a DER object. */ public class X9ECPoint implements DEREncodable { ECPoint p; public X9ECPoint( ECPoint p) { this.p = p; } public X9ECPoint( ECCurve c, ASN1OctetString s) { this.p = c.decodePoint(s.getOctets()); } public ECPoint getPoint() { return p; } /** *
     *  ECPoint ::= OCTET STRING
     * 
*

* Octet string produced using ECPoint.getEncoded(). */ public DERObject getDERObject() { return new DEROctetString(p.getEncoded()); } } bouncycastle-1.49.orig/jdk1.0/org/bouncycastle/asn1/x9/KeySpecificInfo.java0000644000175000017500000000310510262753175025770 0ustar ebourgebourgpackage org.bouncycastle.asn1.x9; import java.util.Enumeration; import org.bouncycastle.asn1.ASN1EncodableVector; import org.bouncycastle.asn1.ASN1OctetString; import org.bouncycastle.asn1.ASN1Sequence; import org.bouncycastle.asn1.DEREncodable; import org.bouncycastle.asn1.DERObject; import org.bouncycastle.asn1.DERObjectIdentifier; import org.bouncycastle.asn1.DERSequence; /** * ASN.1 def for Diffie-Hellman key exchange KeySpecificInfo structure. See * RFC 2631, or X9.42, for further details. */ public class KeySpecificInfo implements DEREncodable { private DERObjectIdentifier algorithm; private ASN1OctetString counter; public KeySpecificInfo( DERObjectIdentifier algorithm, ASN1OctetString counter) { this.algorithm = algorithm; this.counter = counter; } public KeySpecificInfo( ASN1Sequence seq) { Enumeration e = seq.getObjects(); algorithm = (DERObjectIdentifier)e.nextElement(); counter = (ASN1OctetString)e.nextElement(); } public DERObjectIdentifier getAlgorithm() { return algorithm; } public ASN1OctetString getCounter() { return counter; } /** *

     *  KeySpecificInfo ::= SEQUENCE {
     *      algorithm OBJECT IDENTIFIER,
     *      counter OCTET STRING SIZE (4..4)
     *  }
     * 
*/ public DERObject getDERObject() { ASN1EncodableVector seq = new ASN1EncodableVector(); seq.add(algorithm); seq.add(counter); return new DERSequence(seq); } } bouncycastle-1.49.orig/jdk1.0/org/bouncycastle/asn1/x9/X9FieldElement.java0000644000175000017500000000306710262753175025543 0ustar ebourgebourgpackage org.bouncycastle.asn1.x9; import java.math.BigInteger; import org.bouncycastle.asn1.ASN1OctetString; import org.bouncycastle.asn1.DEREncodable; import org.bouncycastle.asn1.DERObject; import org.bouncycastle.asn1.DEROctetString; import org.bouncycastle.math.ec.ECFieldElement; import org.bouncycastle.math.ec.ECFieldElementFp; /** * class for processing an FieldElement as a DER object. */ public class X9FieldElement implements DEREncodable { private ECFieldElement f; public X9FieldElement( ECFieldElement f) { this.f = f; } public X9FieldElement( boolean fP, BigInteger q, ASN1OctetString s) { if (fP) { this.f = new ECFieldElementFp(q, new BigInteger(1, s.getOctets())); } else { throw new RuntimeException("not implemented"); } } public ECFieldElement getValue() { return f; } /** *
     *  FieldElement ::= OCTET STRING
     * 
*

*

    *
  1. if q is an odd prime then the field element is * processed as an Integer and converted to an octet string * according to x 9.62 4.3.1.
  2. *
  3. if q is 2m then the bit string * contained in the field element is converted into an octet * string with the same ordering padded at the front if necessary. *
  4. *
*/ public DERObject getDERObject() { return new DEROctetString(f.toBigInteger().toByteArray()); } } bouncycastle-1.49.orig/jdk1.0/org/bouncycastle/asn1/x9/X962NamedCurves.java0000644000175000017500000002045410262753175025571 0ustar ebourgebourgpackage org.bouncycastle.asn1.x9; import java.math.BigInteger; import java.util.Enumeration; import java.util.Hashtable; import org.bouncycastle.asn1.DERObjectIdentifier; import org.bouncycastle.math.ec.ECCurve; import org.bouncycastle.math.ec.ECCurveFp; import org.bouncycastle.util.encoders.Hex; /** * table of the current named curves defined in X.962 EC-DSA. */ public class X962NamedCurves { static final ECCurve cFp192v1 = new ECCurveFp( new BigInteger("6277101735386680763835789423207666416083908700390324961279"), new BigInteger("fffffffffffffffffffffffffffffffefffffffffffffffc", 16), new BigInteger("64210519e59c80e70fa7e9ab72243049feb8deecc146b9b1", 16)); static final X9ECParameters prime192v1 = new X9ECParameters( cFp192v1, cFp192v1.decodePoint( Hex.decode("03188da80eb03090f67cbf20eb43a18800f4ff0afd82ff1012")), new BigInteger("ffffffffffffffffffffffff99def836146bc9b1b4d22831", 16), BigInteger.valueOf(1), Hex.decode("3045AE6FC8422f64ED579528D38120EAE12196D5")); static final ECCurve cFp192v2 = new ECCurveFp( new BigInteger("6277101735386680763835789423207666416083908700390324961279"), new BigInteger("fffffffffffffffffffffffffffffffefffffffffffffffc", 16), new BigInteger("cc22d6dfb95c6b25e49c0d6364a4e5980c393aa21668d953", 16)); static final X9ECParameters prime192v2 = new X9ECParameters( cFp192v2, cFp192v2.decodePoint( Hex.decode("03eea2bae7e1497842f2de7769cfe9c989c072ad696f48034a")), new BigInteger("ffffffffffffffffffffffff5fb1a724dc80418648d8dd31", 16), BigInteger.valueOf(1), Hex.decode("31a92ee2029fd10d901b113e990710f0d21ac6b6")); static final ECCurve cFp192v3 = new ECCurveFp( new BigInteger("6277101735386680763835789423207666416083908700390324961279"), new BigInteger("fffffffffffffffffffffffffffffffefffffffffffffffc", 16), new BigInteger("22123dc2395a05caa7423daeccc94760a7d462256bd56916", 16)); static final X9ECParameters prime192v3 = new X9ECParameters( cFp192v3, cFp192v3.decodePoint( Hex.decode("027d29778100c65a1da1783716588dce2b8b4aee8e228f1896")), new BigInteger("ffffffffffffffffffffffff7a62d031c83f4294f640ec13", 16), BigInteger.valueOf(1), Hex.decode("c469684435deb378c4b65ca9591e2a5763059a2e")); static final ECCurve cFp239v1 = new ECCurveFp( new BigInteger("883423532389192164791648750360308885314476597252960362792450860609699839"), new BigInteger("7fffffffffffffffffffffff7fffffffffff8000000000007ffffffffffc", 16), new BigInteger("6b016c3bdcf18941d0d654921475ca71a9db2fb27d1d37796185c2942c0a", 16)); static final X9ECParameters prime239v1 = new X9ECParameters( cFp239v1, cFp239v1.decodePoint( Hex.decode("020ffa963cdca8816ccc33b8642bedf905c3d358573d3f27fbbd3b3cb9aaaf")), new BigInteger("7fffffffffffffffffffffff7fffff9e5e9a9f5d9071fbd1522688909d0b", 16), BigInteger.valueOf(1), Hex.decode("e43bb460f0b80cc0c0b075798e948060f8321b7d")); static final ECCurve cFp239v2 = new ECCurveFp( new BigInteger("883423532389192164791648750360308885314476597252960362792450860609699839"), new BigInteger("7fffffffffffffffffffffff7fffffffffff8000000000007ffffffffffc", 16), new BigInteger("617fab6832576cbbfed50d99f0249c3fee58b94ba0038c7ae84c8c832f2c", 16)); static final X9ECParameters prime239v2 = new X9ECParameters( cFp239v2, cFp239v2.decodePoint( Hex.decode("0238af09d98727705120c921bb5e9e26296a3cdcf2f35757a0eafd87b830e7")), new BigInteger("7fffffffffffffffffffffff800000cfa7e8594377d414c03821bc582063", 16), BigInteger.valueOf(1), Hex.decode("e8b4011604095303ca3b8099982be09fcb9ae616")); static final ECCurve cFp239v3 = new ECCurveFp( new BigInteger("883423532389192164791648750360308885314476597252960362792450860609699839"), new BigInteger("7fffffffffffffffffffffff7fffffffffff8000000000007ffffffffffc", 16), new BigInteger("255705fa2a306654b1f4cb03d6a750a30c250102d4988717d9ba15ab6d3e", 16)); static final X9ECParameters prime239v3 = new X9ECParameters( cFp239v3, cFp239v3.decodePoint( Hex.decode("036768ae8e18bb92cfcf005c949aa2c6d94853d0e660bbf854b1c9505fe95a")), new BigInteger("7fffffffffffffffffffffff7fffff975deb41b3a6057c3c432146526551", 16), BigInteger.valueOf(1), Hex.decode("7d7374168ffe3471b60a857686a19475d3bfa2ff")); static final ECCurve cFp256v1 = new ECCurveFp( new BigInteger("115792089210356248762697446949407573530086143415290314195533631308867097853951"), new BigInteger("ffffffff00000001000000000000000000000000fffffffffffffffffffffffc", 16), new BigInteger("5ac635d8aa3a93e7b3ebbd55769886bc651d06b0cc53b0f63bce3c3e27d2604b", 16)); static final X9ECParameters prime256v1 = new X9ECParameters( cFp256v1, cFp256v1.decodePoint( Hex.decode("036b17d1f2e12c4247f8bce6e563a440f277037d812deb33a0f4a13945d898c296")), new BigInteger("ffffffff00000000ffffffffffffffffbce6faada7179e84f3b9cac2fc632551", 16), BigInteger.valueOf(1), Hex.decode("c49d360886e704936a6678e1139d26b7819f7e90")); static final Hashtable objIds = new Hashtable(); static final Hashtable curves = new Hashtable(); static final Hashtable names = new Hashtable(); static { objIds.put("prime192v1", X9ObjectIdentifiers.prime192v1); objIds.put("prime192v2", X9ObjectIdentifiers.prime192v2); objIds.put("prime192v3", X9ObjectIdentifiers.prime192v3); objIds.put("prime239v1", X9ObjectIdentifiers.prime239v1); objIds.put("prime239v2", X9ObjectIdentifiers.prime239v2); objIds.put("prime239v3", X9ObjectIdentifiers.prime239v3); objIds.put("prime256v1", X9ObjectIdentifiers.prime256v1); names.put(X9ObjectIdentifiers.prime192v1, "prime192v1"); names.put(X9ObjectIdentifiers.prime192v2, "prime192v2"); names.put(X9ObjectIdentifiers.prime192v3, "prime192v3"); names.put(X9ObjectIdentifiers.prime239v1, "prime239v1"); names.put(X9ObjectIdentifiers.prime239v2, "prime239v2"); names.put(X9ObjectIdentifiers.prime239v3, "prime239v3"); names.put(X9ObjectIdentifiers.prime256v1, "prime256v1"); curves.put(X9ObjectIdentifiers.prime192v1, prime192v1); curves.put(X9ObjectIdentifiers.prime192v2, prime192v2); curves.put(X9ObjectIdentifiers.prime192v3, prime192v3); curves.put(X9ObjectIdentifiers.prime239v1, prime239v1); curves.put(X9ObjectIdentifiers.prime239v2, prime239v2); curves.put(X9ObjectIdentifiers.prime239v3, prime239v3); curves.put(X9ObjectIdentifiers.prime256v1, prime256v1); } public static X9ECParameters getByName( String name) { DERObjectIdentifier oid = (DERObjectIdentifier)objIds.get(name); if (oid != null) { return (X9ECParameters)curves.get(oid); } return null; } /** * return the X9ECParameters object for the named curve represented by * the passed in object identifier. Null if the curve isn't present. * * @param oid an object identifier representing a named curve, if present. */ public static X9ECParameters getByOID( DERObjectIdentifier oid) { return (X9ECParameters)curves.get(oid); } /** * return the object identifier signified by the passed in name. Null * if there is no object identifier associated with name. * * @return the object identifier associated with name, if present. */ public static DERObjectIdentifier getOID( String name) { return (DERObjectIdentifier)objIds.get(name); } /** * return the named curve name represented by the given object identifier. */ public static String getName( DERObjectIdentifier oid) { return (String)names.get(oid); } /** * returns an enumeration containing the name strings for curves * contained in this structure. */ public static Enumeration getNames() { return objIds.keys(); } } bouncycastle-1.49.orig/jdk1.0/org/bouncycastle/asn1/DERVisibleString.java0000644000175000017500000000211410262753175025534 0ustar ebourgebourgpackage org.bouncycastle.asn1; import java.io.IOException; /** * DER Visible String object. */ public class DERVisibleString extends DERObject { String string; public DERVisibleString( String string) { this.string = string; } /** * @param string - bytes representing the string */ public DERVisibleString( byte[] string) { this.string = new String(string, 0); } public String getString() { return string; } public boolean equals( Object o) { if ((o == null) || !(o instanceof DERVisibleString)) { return false; } return this.getString().equals(((DERVisibleString)o).getString()); } public int hashCode() { return this.getString().hashCode(); } void encode( DEROutputStream out) throws IOException { byte[] bytes = new byte[string.length()]; string.getBytes(0, string.length(), bytes, 0); out.writeEncoded(VISIBLE_STRING, bytes); } } bouncycastle-1.49.orig/jdk1.0/org/bouncycastle/asn1/util/0000755000175000017500000000000012152033551022516 5ustar ebourgebourgbouncycastle-1.49.orig/jdk1.0/org/bouncycastle/asn1/util/ASN1Dump.java0000644000175000017500000001647210533203640024722 0ustar ebourgebourgpackage org.bouncycastle.asn1.util; import java.util.Enumeration; import org.bouncycastle.asn1.*; import org.bouncycastle.util.encoders.Hex; public class ASN1Dump { private static final String TAB = " "; /** * dump a DER object as a formatted string with indentation * * @param obj the DERObject to be dumped out. */ public static String _dumpAsString( String indent, DERObject obj) { if (obj instanceof ASN1Sequence) { StringBuffer buf = new StringBuffer(); Enumeration e = ((ASN1Sequence)obj).getObjects(); String tab = indent + TAB; buf.append(indent); if (obj instanceof BERConstructedSequence) { buf.append("BER ConstructedSequence"); } else { buf.append("ConstructedSequence"); } buf.append(System.getProperty("line.separator")); while (e.hasMoreElements()) { Object o = e.nextElement(); if (o == null) { buf.append(tab); buf.append("NULL"); buf.append(System.getProperty("line.separator")); } else if (o instanceof DERObject) { buf.append(_dumpAsString(tab, (DERObject)o)); } else { buf.append(_dumpAsString(tab, ((DEREncodable)o).getDERObject())); } } return buf.toString(); } else if (obj instanceof DERTaggedObject) { StringBuffer buf = new StringBuffer(); String tab = indent + TAB; buf.append(indent); if (obj instanceof BERTaggedObject) { buf.append("BER Tagged ["); } else { buf.append("Tagged ["); } DERTaggedObject o = (DERTaggedObject)obj; buf.append(o.getTagNo()); buf.append(']'); if (!o.isExplicit()) { buf.append(" IMPLICIT "); } buf.append(System.getProperty("line.separator")); if (o.isEmpty()) { buf.append(tab); buf.append("EMPTY"); } else { buf.append(_dumpAsString(tab, o.getObject())); } return buf.toString(); } else if (obj instanceof ASN1Set) { StringBuffer buf = new StringBuffer(); Enumeration e = ((ASN1Set)obj).getObjects(); String tab = indent + TAB; buf.append(indent); buf.append("ConstructedSet"); buf.append(System.getProperty("line.separator")); while (e.hasMoreElements()) { Object o = e.nextElement(); if (o == null) { buf.append(tab); buf.append("NULL"); buf.append(System.getProperty("line.separator")); } else if (o instanceof DERObject) { buf.append(_dumpAsString(tab, (DERObject)o)); } else { buf.append(_dumpAsString(tab, ((DEREncodable)o).getDERObject())); } } return buf.toString(); } else if (obj instanceof DERSet) { StringBuffer buf = new StringBuffer(); Enumeration e = ((DERSet)obj).getObjects(); String tab = indent + TAB; buf.append(indent); buf.append("Set"); buf.append(System.getProperty("line.separator")); while (e.hasMoreElements()) { Object o = e.nextElement(); if (o == null) { buf.append(tab); buf.append("NULL"); buf.append(System.getProperty("line.separator")); } else if (o instanceof DERObject) { buf.append(_dumpAsString(tab, (DERObject)o)); } else { buf.append(_dumpAsString(tab, ((DEREncodable)o).getDERObject())); } } return buf.toString(); } else if (obj instanceof DERObjectIdentifier) { return indent + "ObjectIdentifier(" + ((DERObjectIdentifier)obj).getId() + ")" + System.getProperty("line.separator"); } else if (obj instanceof DERBoolean) { return indent + "Boolean(" + ((DERBoolean)obj).isTrue() + ")" + System.getProperty("line.separator"); } else if (obj instanceof DERInteger) { return indent + "Integer(" + ((DERInteger)obj).getValue() + ")" + System.getProperty("line.separator"); } else if (obj instanceof ASN1OctetString) { return indent + obj.toString() + "[" + ((ASN1OctetString)obj).getOctets().length + "] " + System.getProperty("line.separator"); } else if (obj instanceof DERIA5String) { return indent + "IA5String(" + ((DERIA5String)obj).getString() + ") " + System.getProperty("line.separator"); } else if (obj instanceof DERPrintableString) { return indent + "PrintableString(" + ((DERPrintableString)obj).getString() + ") " + System.getProperty("line.separator"); } else if (obj instanceof DERVisibleString) { return indent + "VisibleString(" + ((DERVisibleString)obj).getString() + ") " + System.getProperty("line.separator"); } else if (obj instanceof DERBMPString) { return indent + "BMPString(" + ((DERBMPString)obj).getString() + ") " + System.getProperty("line.separator"); } else if (obj instanceof DERT61String) { return indent + "T61String(" + ((DERT61String)obj).getString() + ") " + System.getProperty("line.separator"); } else if (obj instanceof DERUTCTime) { return indent + "UTCTime(" + ((DERUTCTime)obj).getTime() + ") " + System.getProperty("line.separator"); } else if (obj instanceof DERUnknownTag) { return indent + "Unknown " + Integer.toString(((DERUnknownTag)obj).getTag(), 16) + " " + new String(Hex.encode(((DERUnknownTag)obj).getData()), 0) + System.getProperty("line.separator"); } else { return indent + obj.toString() + System.getProperty("line.separator"); } } /** * dump out a DER object as a formatted string * * @param obj the DERObject to be dumped out. */ public static String dumpAsString( Object obj) { if (obj instanceof DERObject) { return _dumpAsString("", (DERObject)obj); } else if (obj instanceof DEREncodable) { return _dumpAsString("", ((DEREncodable)obj).getDERObject()); } return "unknown object type " + obj.toString(); } } bouncycastle-1.49.orig/jdk1.0/org/bouncycastle/asn1/util/Dump.java0000644000175000017500000000122210350737002024263 0ustar ebourgebourgpackage org.bouncycastle.asn1.util; import java.io.EOFException; import java.io.FileInputStream; import org.bouncycastle.asn1.BERInputStream; public class Dump { public static void main( String args[]) throws Exception { FileInputStream fIn = new FileInputStream(args[0]); BERInputStream bIn = new BERInputStream(fIn); Object obj = null; try { while ((obj = bIn.readObject()) != null) { System.out.println(ASN1Dump.dumpAsString(obj)); } } catch (EOFException e) { // ignore } } } bouncycastle-1.49.orig/jdk1.0/org/bouncycastle/asn1/util/DERDump.java0000644000175000017500000000127510262753175024641 0ustar ebourgebourgpackage org.bouncycastle.asn1.util; import org.bouncycastle.asn1.DEREncodable; import org.bouncycastle.asn1.DERObject; /** * @deprecated use ASN1Dump. */ public class DERDump extends ASN1Dump { /** * dump out a DER object as a formatted string * * @param obj the DERObject to be dumped out. */ public static String dumpAsString( DERObject obj) { return _dumpAsString("", obj); } /** * dump out a DER object as a formatted string * * @param obj the DERObject to be dumped out. */ public static String dumpAsString( DEREncodable obj) { return _dumpAsString("", obj.getDERObject()); } } bouncycastle-1.49.orig/jdk1.0/org/bouncycastle/asn1/DERT61String.java0000644000175000017500000000205310262753175024513 0ustar ebourgebourgpackage org.bouncycastle.asn1; import java.io.IOException; /** * DER T61String object. */ public class DERT61String extends DERObject { String string; public DERT61String( String string) { this.string = string; } /** * @param string - bytes representing the string */ public DERT61String( byte[] string) { this.string = new String(string, 0); } public String getString() { return string; } void encode( DEROutputStream out) throws IOException { byte[] bytes = new byte[string.length()]; string.getBytes(0, string.length(), bytes, 0); out.writeEncoded(T61_STRING, bytes); } public boolean equals( Object o) { if ((o == null) || !(o instanceof DERT61String)) { return false; } return this.getString().equals(((DERT61String)o).getString()); } public int hashCode() { return this.getString().hashCode(); } } bouncycastle-1.49.orig/jdk1.0/org/bouncycastle/asn1/DERPrintableString.java0000644000175000017500000000214410262753175026062 0ustar ebourgebourgpackage org.bouncycastle.asn1; import java.io.IOException; /** * DER PrintableString object. */ public class DERPrintableString extends DERObject { String string; public DERPrintableString( String string) { this.string = string; } /** * @param string - bytes representing the string */ public DERPrintableString( byte[] string) { this.string = new String(string, 0); } public String getString() { return string; } public int hashCode() { return this.getString().hashCode(); } public boolean equals( Object o) { if (!(o instanceof DERPrintableString)) { return false; } DERPrintableString s = (DERPrintableString)o; return this.getString().equals(s.getString()); } void encode( DEROutputStream out) throws IOException { byte[] bytes = new byte[string.length()]; string.getBytes(0, string.length(), bytes, 0); out.writeEncoded(PRINTABLE_STRING, bytes); } } bouncycastle-1.49.orig/jdk1.0/org/bouncycastle/asn1/DERInputStream.java0000644000175000017500000001464310505106272025223 0ustar ebourgebourgpackage org.bouncycastle.asn1; import java.io.ByteArrayInputStream; import java.io.EOFException; import java.io.FilterInputStream; import java.io.IOException; import java.io.InputStream; public class DERInputStream extends FilterInputStream implements DERTags { public DERInputStream( InputStream is) { super(is); } protected int readLength() throws IOException { int length = read(); if (length < 0) { throw new IOException("EOF found when length expected"); } if (length == 0x80) { return -1; // indefinite-length encoding } if (length > 127) { int size = length & 0x7f; length = 0; for (int i = 0; i < size; i++) { int next = read(); if (next < 0) { throw new IOException("EOF found reading length"); } length = (length << 8) + next; } } return length; } protected void readFully( byte[] bytes) throws IOException { int left = bytes.length; if (left == 0) { return; } while ((left -= read(bytes, bytes.length - left, left)) != 0) { // do nothing } } /** * build an object given its tag and a byte stream to construct it * from. */ protected DERObject buildObject( int tag, byte[] bytes) throws IOException { switch (tag) { case NULL: return null; case SEQUENCE | CONSTRUCTED: ByteArrayInputStream bIn = new ByteArrayInputStream(bytes); BERInputStream dIn = new BERInputStream(bIn); DERConstructedSequence seq = new DERConstructedSequence(); try { for (;;) { DERObject obj = dIn.readObject(); seq.addObject(obj); } } catch (EOFException ex) { return seq; } case SET | CONSTRUCTED: bIn = new ByteArrayInputStream(bytes); dIn = new BERInputStream(bIn); DERSet set = new DERSet(dIn.readObject()); try { for (;;) { DERObject obj = dIn.readObject(); set.addObject(obj); } } catch (EOFException ex) { return set; } case BOOLEAN: return new DERBoolean(bytes); case INTEGER: return new DERInteger(bytes); case OBJECT_IDENTIFIER: int head = bytes[0] & 0xff; StringBuffer objId = new StringBuffer(); objId.append(head / 40); objId.append('.'); objId.append(head % 40); int value = 0; for (int i = 1; i != bytes.length; i++) { int b = bytes[i] & 0xff; value = value * 128 + (b & 0x7f); if ((b & 128) == 0) // end of number reached { objId.append('.'); objId.append(value); value = 0; } } return new DERObjectIdentifier(objId.toString()); case BIT_STRING: int padBits = bytes[0]; byte[] data = new byte[bytes.length - 1]; System.arraycopy(bytes, 1, data, 0, bytes.length - 1); return new DERBitString(data, padBits); case PRINTABLE_STRING: return new DERPrintableString(bytes); case IA5_STRING: return new DERIA5String(bytes); case T61_STRING: return new DERT61String(bytes); case VISIBLE_STRING: return new DERVisibleString(bytes); case BMP_STRING: return new DERBMPString(bytes); case OCTET_STRING: return new DEROctetString(bytes); case GENERALIZED_TIME: return new DERGeneralizedTime(new String(bytes, 0)); case UTC_TIME: return new DERUTCTime(new String(bytes, 0)); default: // // with tagged object tag number is bottom 4 bits // if ((tag & (TAGGED | CONSTRUCTED)) != 0) { if (bytes.length == 0) // empty tag! { return new DERTaggedObject(tag & 0x0f); } // // simple type - implicit... return an octet string // if ((tag & CONSTRUCTED) == 0) { return new DERTaggedObject(false, tag & 0x0f, new DEROctetString(bytes)); } bIn = new ByteArrayInputStream(bytes); dIn = new BERInputStream(bIn); DEREncodable dObj = dIn.readObject(); // // explicitly tagged (probably!) - if it isn't we'd have to // tell from the context // if (dIn.available() == 0) { return new DERTaggedObject(tag & 0x0f, dObj); } // // another implicit object, we'll create a sequence... // seq = new DERConstructedSequence(); seq.addObject(dObj); try { for (;;) { dObj = dIn.readObject(); seq.addObject(dObj); } } catch (EOFException ex) { // ignore -- } return new DERTaggedObject(false, tag & 0x0f, seq); } return new DERUnknownTag(tag, bytes); } } public DERObject readObject() throws IOException { int tag = read(); if (tag == -1) { throw new EOFException(); } int length = readLength(); byte[] bytes = new byte[length]; readFully(bytes); return buildObject(tag, bytes); } } bouncycastle-1.49.orig/jdk1.0/org/bouncycastle/asn1/cryptopro/0000755000175000017500000000000012152033551023602 5ustar ebourgebourgbouncycastle-1.49.orig/jdk1.0/org/bouncycastle/asn1/cryptopro/ECGOST3410NamedCurves.java0000644000175000017500000001656610262753175030127 0ustar ebourgebourgpackage org.bouncycastle.asn1.cryptopro; import java.math.BigInteger; import java.util.Enumeration; import java.util.Hashtable; import org.bouncycastle.asn1.DERObjectIdentifier; import org.bouncycastle.crypto.params.ECDomainParameters; import org.bouncycastle.math.ec.*; /** * table of the available named parameters for GOST 3410-2001. */ public class ECGOST3410NamedCurves { static final Hashtable objIds = new Hashtable(); static final Hashtable params = new Hashtable(); static final Hashtable names = new Hashtable(); static { BigInteger mod_p = new BigInteger("115792089237316195423570985008687907853269984665640564039457584007913129639319"); BigInteger mod_q = new BigInteger("115792089237316195423570985008687907853073762908499243225378155805079068850323"); ECCurveFp curve = new ECCurveFp( mod_p, // p new BigInteger("115792089237316195423570985008687907853269984665640564039457584007913129639316"), // a new BigInteger("166")); // b ECDomainParameters ecParams = new ECDomainParameters( curve, new ECPointFp(curve, new ECFieldElementFp(curve.getQ(),new BigInteger("1")), // x new ECFieldElementFp(curve.getQ(),new BigInteger("64033881142927202683649881450433473985931760268884941288852745803908878638612"))), // y mod_q); params.put(CryptoProObjectIdentifiers.gostR3410_2001_CryptoPro_A, ecParams); mod_p = new BigInteger("115792089237316195423570985008687907853269984665640564039457584007913129639319"); mod_q = new BigInteger("115792089237316195423570985008687907853073762908499243225378155805079068850323"); curve = new ECCurveFp( mod_p, // p new BigInteger("115792089237316195423570985008687907853269984665640564039457584007913129639316"), new BigInteger("166")); ecParams = new ECDomainParameters( curve, new ECPointFp(curve, new ECFieldElementFp(curve.getQ(),new BigInteger("1")), // x new ECFieldElementFp(curve.getQ(),new BigInteger("64033881142927202683649881450433473985931760268884941288852745803908878638612"))), // y mod_q); params.put(CryptoProObjectIdentifiers.gostR3410_2001_CryptoPro_XchA, ecParams); mod_p = new BigInteger("57896044618658097711785492504343953926634992332820282019728792003956564823193"); //p mod_q = new BigInteger("57896044618658097711785492504343953927102133160255826820068844496087732066703"); //q curve = new ECCurveFp( mod_p, // p new BigInteger("57896044618658097711785492504343953926634992332820282019728792003956564823190"), // a new BigInteger("28091019353058090096996979000309560759124368558014865957655842872397301267595")); // b ecParams = new ECDomainParameters( curve, new ECPointFp(curve, new ECFieldElementFp(mod_p,new BigInteger("1")), // x new ECFieldElementFp(mod_p,new BigInteger("28792665814854611296992347458380284135028636778229113005756334730996303888124"))), // y mod_q); // q params.put(CryptoProObjectIdentifiers.gostR3410_2001_CryptoPro_B, ecParams); mod_p = new BigInteger("70390085352083305199547718019018437841079516630045180471284346843705633502619"); mod_q = new BigInteger("70390085352083305199547718019018437840920882647164081035322601458352298396601"); curve = new ECCurveFp( mod_p, // p new BigInteger("70390085352083305199547718019018437841079516630045180471284346843705633502616"), new BigInteger("32858")); ecParams = new ECDomainParameters( curve, new ECPointFp(curve, new ECFieldElementFp(mod_p,new BigInteger("0")), new ECFieldElementFp(mod_p,new BigInteger("29818893917731240733471273240314769927240550812383695689146495261604565990247"))), mod_q); params.put(CryptoProObjectIdentifiers.gostR3410_2001_CryptoPro_XchB, ecParams); mod_p = new BigInteger("70390085352083305199547718019018437841079516630045180471284346843705633502619"); //p mod_q = new BigInteger("70390085352083305199547718019018437840920882647164081035322601458352298396601"); //q curve = new ECCurveFp( mod_p, // p new BigInteger("70390085352083305199547718019018437841079516630045180471284346843705633502616"), // a new BigInteger("32858")); // b ecParams = new ECDomainParameters( curve, new ECPointFp(curve, new ECFieldElementFp(mod_p,new BigInteger("0")), // x new ECFieldElementFp(mod_p,new BigInteger("29818893917731240733471273240314769927240550812383695689146495261604565990247"))), // y mod_q); // q params.put(CryptoProObjectIdentifiers.gostR3410_2001_CryptoPro_C, ecParams); objIds.put("GostR3410-2001-CryptoPro-A", CryptoProObjectIdentifiers.gostR3410_2001_CryptoPro_A); objIds.put("GostR3410-2001-CryptoPro-B", CryptoProObjectIdentifiers.gostR3410_2001_CryptoPro_B); objIds.put("GostR3410-2001-CryptoPro-C", CryptoProObjectIdentifiers.gostR3410_2001_CryptoPro_C); objIds.put("GostR3410-2001-CryptoPro-XchA", CryptoProObjectIdentifiers.gostR3410_2001_CryptoPro_XchA); objIds.put("GostR3410-2001-CryptoPro-XchB", CryptoProObjectIdentifiers.gostR3410_2001_CryptoPro_XchB); names.put(CryptoProObjectIdentifiers.gostR3410_2001_CryptoPro_A, "GostR3410-2001-CryptoPro-A"); names.put(CryptoProObjectIdentifiers.gostR3410_2001_CryptoPro_B, "GostR3410-2001-CryptoPro-B"); names.put(CryptoProObjectIdentifiers.gostR3410_2001_CryptoPro_C, "GostR3410-2001-CryptoPro-C"); names.put(CryptoProObjectIdentifiers.gostR3410_2001_CryptoPro_XchA, "GostR3410-2001-CryptoPro-XchA"); names.put(CryptoProObjectIdentifiers.gostR3410_2001_CryptoPro_XchB, "GostR3410-2001-CryptoPro-XchB"); } /** * return the ECDomainParameters object for the given OID, null if it * isn't present. * * @param oid an object identifier representing a named parameters, if present. */ public static ECDomainParameters getByOID( DERObjectIdentifier oid) { return (ECDomainParameters)params.get(oid); } /** * returns an enumeration containing the name strings for parameters * contained in this structure. */ public static Enumeration getNames() { return objIds.keys(); } public static ECDomainParameters getByName( String name) { DERObjectIdentifier oid = (DERObjectIdentifier)objIds.get(name); if (oid != null) { return (ECDomainParameters)params.get(oid); } return null; } /** * return the named curve name represented by the given object identifier. */ public static String getName( DERObjectIdentifier oid) { return (String)names.get(oid); } public static DERObjectIdentifier getOID(String name) { return (DERObjectIdentifier)objIds.get(name); } } bouncycastle-1.49.orig/jdk1.0/org/bouncycastle/asn1/cms/0000755000175000017500000000000012152033551022323 5ustar ebourgebourgbouncycastle-1.49.orig/jdk1.0/org/bouncycastle/asn1/cms/Time.java0000644000175000017500000000336511531050645024076 0ustar ebourgebourgpackage org.bouncycastle.asn1.cms; import org.bouncycastle.asn1.ASN1Choice; import org.bouncycastle.asn1.ASN1TaggedObject; import org.bouncycastle.asn1.DEREncodable; import org.bouncycastle.asn1.DERGeneralizedTime; import org.bouncycastle.asn1.DERObject; import org.bouncycastle.asn1.DERUTCTime; public class Time implements DEREncodable, ASN1Choice { DERObject time; public static Time getInstance( ASN1TaggedObject obj, boolean explicit) { return getInstance(obj.getObject()); } public Time( DERObject time) { if (!(time instanceof DERUTCTime) && !(time instanceof DERGeneralizedTime)) { throw new IllegalArgumentException("unknown object passed to Time"); } this.time = time; } public static Time getInstance( Object obj) { if (obj == null || obj instanceof Time) { return (Time)obj; } else if (obj instanceof DERUTCTime) { return new Time((DERUTCTime)obj); } else if (obj instanceof DERGeneralizedTime) { return new Time((DERGeneralizedTime)obj); } throw new IllegalArgumentException("unknown object in factory"); } public String getTime() { if (time instanceof DERUTCTime) { return ((DERUTCTime)time).getAdjustedTime(); } else { return ((DERGeneralizedTime)time).getTime(); } } /** *
     * Time ::= CHOICE {
     *             utcTime        UTCTime,
     *             generalTime    GeneralizedTime }
     * 
*/ public DERObject getDERObject() { return time; } } bouncycastle-1.49.orig/jdk1.0/org/bouncycastle/asn1/x509/0000755000175000017500000000000012152033551022246 5ustar ebourgebourgbouncycastle-1.49.orig/jdk1.0/org/bouncycastle/asn1/x509/TBSCertList.java0000644000175000017500000000772410350737002025225 0ustar ebourgebourg package org.bouncycastle.asn1.x509; import org.bouncycastle.asn1.ASN1Sequence; import org.bouncycastle.asn1.DEREncodable; import org.bouncycastle.asn1.DERInteger; import org.bouncycastle.asn1.DERObject; import org.bouncycastle.asn1.DERTaggedObject; import org.bouncycastle.asn1.DERUTCTime; /** * PKIX RFC-2459 * *
 * TBSCertList  ::=  SEQUENCE  {
 *      version                 Version OPTIONAL,
 *                                   -- if present, shall be v2
 *      signature               AlgorithmIdentifier,
 *      issuer                  Name,
 *      thisUpdate              Time,
 *      nextUpdate              Time OPTIONAL,
 *      revokedCertificates     SEQUENCE OF SEQUENCE  {
 *           userCertificate         CertificateSerialNumber,
 *           revocationDate          Time,
 *           crlEntryExtensions      Extensions OPTIONAL
 *                                         -- if present, shall be v2
 *                                }  OPTIONAL,
 *      crlExtensions           [0]  EXPLICIT Extensions OPTIONAL
 *                                         -- if present, shall be v2
 *                                }
 * 
*/ public class TBSCertList implements DEREncodable { ASN1Sequence seq; DERInteger version; AlgorithmIdentifier signature; X509Name issuer; DERUTCTime thisUpdate; DERUTCTime nextUpdate; CRLEntry[] revokedCertificates; X509Extensions crlExtensions; public TBSCertList( ASN1Sequence seq) { int seqPos = 0; this.seq = seq; if (seq.getObjectAt(seqPos) instanceof DERInteger) { version = (DERInteger)seq.getObjectAt(seqPos++); } else { version = new DERInteger(0); } if (seq.getObjectAt(seqPos) instanceof AlgorithmIdentifier) { signature = (AlgorithmIdentifier)seq.getObjectAt(seqPos++); } else { signature = new AlgorithmIdentifier((ASN1Sequence)seq.getObjectAt(seqPos++)); } if (seq.getObjectAt(seqPos) instanceof X509Name) { issuer = (X509Name)seq.getObjectAt(seqPos++); } else { issuer = new X509Name((ASN1Sequence)seq.getObjectAt(seqPos++)); } thisUpdate = (DERUTCTime)seq.getObjectAt(seqPos++); if (seqPos < seq.size() && seq.getObjectAt(seqPos) instanceof DERUTCTime) { nextUpdate = (DERUTCTime)seq.getObjectAt(seqPos++); } if (seqPos < seq.size() && !(seq.getObjectAt(seqPos) instanceof DERTaggedObject)) { ASN1Sequence certs = (ASN1Sequence)seq.getObjectAt(seqPos++); revokedCertificates = new CRLEntry[certs.size()]; for (int i = 0; i < revokedCertificates.length; i++) { revokedCertificates[i] = new CRLEntry((ASN1Sequence)certs.getObjectAt(i)); } } if (seqPos < seq.size() && seq.getObjectAt(seqPos) instanceof DERTaggedObject) { crlExtensions = new X509Extensions((ASN1Sequence)((DERTaggedObject)seq.getObjectAt(seqPos++)).getObject()); } } public int getVersion() { return version.getValue().intValue() + 1; } public DERInteger getVersionNumber() { return version; } public AlgorithmIdentifier getSignature() { return signature; } public X509Name getIssuer() { return issuer; } public DERUTCTime getThisUpdate() { return thisUpdate; } public DERUTCTime getNextUpdate() { return nextUpdate; } public CRLEntry[] getRevokedCertificates() { return revokedCertificates; } public X509Extensions getExtensions() { return crlExtensions; } public DERObject getDERObject() { return seq; } } bouncycastle-1.49.orig/jdk1.0/org/bouncycastle/asn1/x509/CRLEntry.java0000644000175000017500000000211410262753175024564 0ustar ebourgebourgpackage org.bouncycastle.asn1.x509; import org.bouncycastle.asn1.ASN1Sequence; import org.bouncycastle.asn1.DEREncodable; import org.bouncycastle.asn1.DERInteger; import org.bouncycastle.asn1.DERObject; import org.bouncycastle.asn1.DERUTCTime; public class CRLEntry implements DEREncodable { ASN1Sequence seq; DERInteger userCertificate; DERUTCTime revocationDate; X509Extensions crlEntryExtensions; public CRLEntry( ASN1Sequence seq) { this.seq = seq; userCertificate = (DERInteger)seq.getObjectAt(0); revocationDate = (DERUTCTime)seq.getObjectAt(1); if ( seq.size() == 3 ) { crlEntryExtensions = new X509Extensions((ASN1Sequence)seq.getObjectAt(2)); } } public DERInteger getUserCertificate() { return userCertificate; } public DERUTCTime getRevocationDate() { return revocationDate; } public X509Extensions getExtensions() { return crlEntryExtensions; } public DERObject getDERObject() { return seq; } } bouncycastle-1.49.orig/jdk1.0/org/bouncycastle/asn1/x509/CertificateList.java0000644000175000017500000000544310262753175026210 0ustar ebourgebourgpackage org.bouncycastle.asn1.x509; import org.bouncycastle.asn1.ASN1EncodableVector; import org.bouncycastle.asn1.ASN1Sequence; import org.bouncycastle.asn1.ASN1TaggedObject; import org.bouncycastle.asn1.DERBitString; import org.bouncycastle.asn1.DEREncodable; import org.bouncycastle.asn1.DERObject; import org.bouncycastle.asn1.DERSequence; import org.bouncycastle.asn1.DERUTCTime; /** * PKIX RFC-2459 * * The X.509 v2 CRL syntax is as follows. For signature calculation, * the data that is to be signed is ASN.1 DER encoded. * *
 * CertificateList  ::=  SEQUENCE  {
 *      tbsCertList          TBSCertList,
 *      signatureAlgorithm   AlgorithmIdentifier,
 *      signatureValue       BIT STRING  }
 * 
*/ public class CertificateList implements DEREncodable { TBSCertList tbsCertList; AlgorithmIdentifier sigAlgId; DERBitString sig; public static CertificateList getInstance( ASN1TaggedObject obj, boolean explicit) { return getInstance(ASN1Sequence.getInstance(obj, explicit)); } public static CertificateList getInstance( Object obj) { if (obj instanceof CertificateList) { return (CertificateList)obj; } else if (obj instanceof ASN1Sequence) { return new CertificateList((ASN1Sequence)obj); } throw new IllegalArgumentException("unknown object in factory"); } public CertificateList( ASN1Sequence seq) { if ( seq.getObjectAt(0) instanceof TBSCertList ) { tbsCertList = (TBSCertList)seq.getObjectAt(0); } else { tbsCertList = new TBSCertList((ASN1Sequence)seq.getObjectAt(0)); } sigAlgId = AlgorithmIdentifier.getInstance(seq.getObjectAt(1)); sig = (DERBitString)seq.getObjectAt(2); } public TBSCertList getTBSCertList() { return tbsCertList; } public CRLEntry[] getRevokedCertificates() { return tbsCertList.getRevokedCertificates(); } public AlgorithmIdentifier getSignatureAlgorithm() { return sigAlgId; } public DERBitString getSignature() { return sig; } public int getVersion() { return tbsCertList.getVersion(); } public X509Name getIssuer() { return tbsCertList.getIssuer(); } public DERUTCTime getThisUpdate() { return tbsCertList.getThisUpdate(); } public DERUTCTime getNextUpdate() { return tbsCertList.getNextUpdate(); } public DERObject getDERObject() { ASN1EncodableVector v = new ASN1EncodableVector(); v.add(tbsCertList); v.add(sigAlgId); v.add(sig); return new DERSequence(v); } } bouncycastle-1.49.orig/jdk1.0/org/bouncycastle/asn1/x509/Time.java0000644000175000017500000000345611531050646024023 0ustar ebourgebourgpackage org.bouncycastle.asn1.x509; import org.bouncycastle.asn1.ASN1Choice; import org.bouncycastle.asn1.ASN1Encodable; import org.bouncycastle.asn1.ASN1TaggedObject; import org.bouncycastle.asn1.DEREncodable; import org.bouncycastle.asn1.DERGeneralizedTime; import org.bouncycastle.asn1.DERObject; import org.bouncycastle.asn1.DERUTCTime; public class Time extends ASN1Encodable implements ASN1Choice { DERObject time; public static Time getInstance( ASN1TaggedObject obj, boolean explicit) { return getInstance(obj.getObject()); } public Time( DERObject time) { if (!(time instanceof DERUTCTime) && !(time instanceof DERGeneralizedTime)) { throw new IllegalArgumentException("unknown object passed to Time"); } this.time = time; } public static Time getInstance( Object obj) { if (obj == null || obj instanceof Time) { return (Time)obj; } else if (obj instanceof DERUTCTime) { return new Time((DERUTCTime)obj); } else if (obj instanceof DERGeneralizedTime) { return new Time((DERGeneralizedTime)obj); } throw new IllegalArgumentException("unknown object in factory"); } public String getTime() { if (time instanceof DERUTCTime) { return ((DERUTCTime)time).getAdjustedTime(); } else { return ((DERGeneralizedTime)time).getTime(); } } /** *
     * Time ::= CHOICE {
     *             utcTime        UTCTime,
     *             generalTime    GeneralizedTime }
     * 
*/ public DERObject toASN1Object() { return time; } } bouncycastle-1.49.orig/jdk1.0/org/bouncycastle/asn1/test/0000755000175000017500000000000012152033551022520 5ustar ebourgebourgbouncycastle-1.49.orig/jdk1.0/org/bouncycastle/asn1/test/DERTest.java0000644000175000017500000000637712110311353024643 0ustar ebourgebourgpackage org.bouncycastle.asn1.test; import java.io.ByteArrayInputStream; import java.io.ByteArrayOutputStream; import java.io.IOException; import java.math.BigInteger; import org.bouncycastle.asn1.ASN1Sequence; import org.bouncycastle.asn1.DERInputStream; import org.bouncycastle.asn1.DEROutputStream; import org.bouncycastle.asn1.pkcs.PKCSObjectIdentifiers; import org.bouncycastle.asn1.pkcs.PrivateKeyInfo; import org.bouncycastle.asn1.pkcs.RSAPrivateKeyStructure; import org.bouncycastle.asn1.x509.AlgorithmIdentifier; import org.bouncycastle.asn1.x509.RSAPublicKeyStructure; import org.bouncycastle.asn1.x509.SubjectPublicKeyInfo; import org.bouncycastle.util.encoders.Hex; public class DERTest implements PKCSObjectIdentifiers { public static void main( String[] args) throws IOException { BigInteger one = BigInteger.valueOf(1); BigInteger two = BigInteger.valueOf(2); BigInteger three = BigInteger.valueOf(3); BigInteger four = BigInteger.valueOf(4); BigInteger five = BigInteger.valueOf(5); BigInteger six = BigInteger.valueOf(6); BigInteger seven = BigInteger.valueOf(7); BigInteger eight = BigInteger.valueOf(8); ByteArrayOutputStream bOut = new ByteArrayOutputStream(); DEROutputStream dOut = new DEROutputStream(bOut); RSAPrivateKeyStructure priv = new RSAPrivateKeyStructure(one, two, three, four, five, six, seven, eight); PrivateKeyInfo info = new PrivateKeyInfo(new AlgorithmIdentifier(rsaEncryption, null), priv.getDERObject()); dOut.writeObject(info); dOut.close(); byte[] data = bOut.toByteArray(); System.out.println(new String(Hex.encode(data), 0)); ByteArrayInputStream bIn = new ByteArrayInputStream(data); DERInputStream dIn = new DERInputStream(bIn); info = PrivateKeyInfo.getInstance(dIn.readObject()); priv = new RSAPrivateKeyStructure((ASN1Sequence)info.getPrivateKey()); System.out.println( priv.getModulus() + " " + priv.getPublicExponent() + " " + priv.getPrivateExponent() + " " + priv.getPrime1() + " " + priv.getPrime2() + " " + priv.getExponent1() + " " + priv.getExponent2() + " " + priv.getCoefficient()); // // X509 public key // bOut = new ByteArrayOutputStream(); dOut = new DEROutputStream(bOut); SubjectPublicKeyInfo pubInfo = new SubjectPublicKeyInfo(new AlgorithmIdentifier(rsaEncryption, null), new RSAPublicKeyStructure(one, two).getDERObject()); dOut.writeObject(pubInfo); dOut.close(); data = bOut.toByteArray(); System.out.println(new String(Hex.encode(data), 0)); bIn = new ByteArrayInputStream(data); dIn = new DERInputStream(bIn); pubInfo = new SubjectPublicKeyInfo((ASN1Sequence)dIn.readObject()); RSAPublicKeyStructure pubKey = new RSAPublicKeyStructure((ASN1Sequence)pubInfo.getPublicKey()); System.out.println( pubKey.getModulus() + " " + pubKey.getPublicExponent()); } } bouncycastle-1.49.orig/jdk1.0/org/bouncycastle/asn1/test/EncryptedPrivateKeyInfoTest.java0000644000175000017500000001362310262753175031020 0ustar ebourgebourgpackage org.bouncycastle.asn1.test; import java.io.ByteArrayInputStream; import java.io.ByteArrayOutputStream; import org.bouncycastle.asn1.ASN1Sequence; import org.bouncycastle.asn1.DERInputStream; import org.bouncycastle.asn1.DERObject; import org.bouncycastle.asn1.DEROutputStream; import org.bouncycastle.asn1.pkcs.EncryptedPrivateKeyInfo; import org.bouncycastle.asn1.util.DERDump; import org.bouncycastle.util.encoders.Base64; import org.bouncycastle.util.test.SimpleTestResult; import org.bouncycastle.util.test.Test; import org.bouncycastle.util.test.TestResult; /** * Test the reading and writing of EncryptedPrivateKeyInfo objects using * the test vectors provided at * * RSA's PKCS5 Page *

* The vectors are Base 64 encoded and encrypted using the password "password" * (without quotes). They should all yield the same PrivateKeyInfo object. */ public class EncryptedPrivateKeyInfoTest implements Test { static byte[] sample1 = Base64.decode( "MIIBozA9BgkqhkiG9w0BBQ0wMDAbBgkqhkiG9w0BBQwwDgQIfWBDXwLp4K4CAggA" + "MBEGBSsOAwIHBAiaCF/AvOgQ6QSCAWDWX4BdAzCRNSQSANSuNsT5X8mWYO27mr3Y" + "9c9LoBVXGNmYWKA77MI4967f7SmjNcgXj3xNE/jmnVz6hhsjS8E5VPT3kfyVkpdZ" + "0lr5e9Yk2m3JWpPU7++v5zBkZmC4V/MwV/XuIs6U+vykgzMgpxQg0oZKS9zgmiZo" + "f/4dOCL0UtCDnyOSvqT7mCVIcMDIEKu8QbVlgZYBop08l60EuEU3gARUo8WsYQmO" + "Dz/ldx0Z+znIT0SXVuOwc+RVItC5T/Qx+aijmmpt+9l14nmaGBrEkmuhmtdvU/4v" + "aptewGRgmjOfD6cqK+zs0O5NrrJ3P/6ZSxXj91CQgrThGfOv72bUncXEMNtc8pks" + "2jpHFjGMdKufnadAD7XuMgzkkaklEXZ4f5tU6heIIwr51g0GBEGF96gYPFnjnSQM" + "75JE02Clo+DfcfXpcybPTwwFg2jd6JTTOfkdf6OdSlA/1XNK43FA"); static byte[] sample2 = Base64.decode( "MIIBpjBABgkqhkiG9w0BBQ0wMzAbBgkqhkiG9w0BBQwwDgQIeFeOWl1jywYCAggA" + "MBQGCCqGSIb3DQMHBAjUJ5eGBhQGtQSCAWBrHrRgqO8UUMLcWzZEtpk1l3mjxiF/" + "koCMkHsFwowgyWhEbgIkTgbSViK54LVK8PskekcGNLph+rB6bGZ7pPbL5pbXASJ8" + "+MkQcG3FZdlS4Ek9tTJDApj3O1UubZGFG4uvTlJJFbF1BOJ3MkY3XQ9Gl1qwv7j5" + "6e103Da7Cq9+oIDKmznza78XXQYrUsPo8mJGjUxPskEYlzwvHjKubRnYm/K6RKhi" + "5f4zX4BQ/Dt3H812ZjRXrsjAJP0KrD/jyD/jCT7zNBVPH1izBds+RwizyQAHwfNJ" + "BFR78TH4cgzB619X47FDVOnT0LqQNVd0O3cSwnPrXE9XR3tPayE+iOB15llFSmi8" + "z0ByOXldEpkezCn92Umk++suzIVj1qfsK+bv2phZWJPbLEIWPDRHUbYf76q5ArAr" + "u4xtxT/hoK3krEs/IN3d70qjlUJ36SEw1UaZ82PWhakQbdtu39ZraMJB"); static byte[] sample3 = Base64.decode( "MIIBrjBIBgkqhkiG9w0BBQ0wOzAeBgkqhkiG9w0BBQwwEQQIrHyQPBZqWLUCAggA" + "AgEQMBkGCCqGSIb3DQMCMA0CAToECEhbh7YZKiPSBIIBYCT1zp6o5jpFlIkgwPop" + "7bW1+8ACr4exqzkeb3WflQ8cWJ4cURxzVdvxUnXeW1VJdaQZtjS/QHs5GhPTG/0f" + "wtvnaPfwrIJ3FeGaZfcg2CrYhalOFmEb4xrE4KyoEQmUN8tb/Cg94uzd16BOPw21" + "RDnE8bnPdIGY7TyL95kbkqH23mK53pi7h+xWIgduW+atIqDyyt55f7WMZcvDvlj6" + "VpN/V0h+qxBHL274WA4dj6GYgeyUFpi60HdGCK7By2TBy8h1ZvKGjmB9h8jZvkx1" + "MkbRumXxyFsowTZawyYvO8Um6lbfEDP9zIEUq0IV8RqH2MRyblsPNSikyYhxX/cz" + "tdDxRKhilySbSBg5Kr8OfcwKp9bpinN96nmG4xr3Tch1bnVvqJzOQ5+Vva2WwVvH" + "2JkWvYm5WaANg4Q6bRxu9vz7DuhbJjQdZbxFezIAgrJdSe92B00jO/0Kny1WjiVO" + "6DA="); public String getName() { return "EncryptedPrivateKeyInfoTest"; } private TestResult test( int id, byte[] sample) { ByteArrayInputStream bIn = new ByteArrayInputStream(sample); DERInputStream dIn = new DERInputStream(bIn); EncryptedPrivateKeyInfo info; try { info = new EncryptedPrivateKeyInfo((ASN1Sequence)dIn.readObject()); } catch (Exception e) { return new SimpleTestResult(false, getName() + ": test " + id + " failed construction - exception " + e.toString()); } ByteArrayOutputStream bOut = new ByteArrayOutputStream(); DEROutputStream dOut = new DEROutputStream(bOut); try { dOut.writeObject(info); } catch (Exception e) { return new SimpleTestResult(false, getName() + ": test " + id + " failed writing - exception " + e.toString()); } byte[] bytes = bOut.toByteArray(); if (bytes.length != sample.length) { try { bIn = new ByteArrayInputStream(bytes); dIn = new DERInputStream(bIn); DERObject obj = (DERObject)dIn.readObject(); return new SimpleTestResult(false, getName() + ": test " + id + " length mismatch - expected " + sample.length + System.getProperty("line.separator") + DERDump.dumpAsString(info) + " got " + bytes.length + System.getProperty("line.separator") + DERDump.dumpAsString(obj)); } catch (Exception e) { e.printStackTrace(); return new SimpleTestResult(false, getName() + ": test " + id + " length mismatch - exception " + e.toString()); } } for (int i = 0; i != bytes.length; i++) { if (bytes[i] != sample[i]) { return new SimpleTestResult(false, getName() + ": test " + id + " data mismatch"); } } return new SimpleTestResult(true, getName() + ": test " + id + " Okay"); } public TestResult perform() { TestResult result = test(0, sample1); if (!result.isSuccessful()) { return result; } result = test(1, sample2); if (!result.isSuccessful()) { return result; } result = test(2, sample3); if (!result.isSuccessful()) { return result; } return new SimpleTestResult(true, getName() + ": Okay"); } public static void main( String[] args) { Test test = new EncryptedPrivateKeyInfoTest(); TestResult result = test.perform(); System.out.println(result.toString()); } } bouncycastle-1.49.orig/jdk1.0/org/bouncycastle/asn1/DERBMPString.java0000644000175000017500000000211110262753175024552 0ustar ebourgebourgpackage org.bouncycastle.asn1; import java.io.IOException; /** * DER BMPString object. */ public class DERBMPString extends DERObject implements DERString { String string; public DERBMPString( String string) { this.string = string; } /** * @param string - bytes representing the string */ public DERBMPString( byte[] string) { this.string = new String(string, 0); } public String getString() { return string; } public int hashCode() { return this.getString().hashCode(); } public boolean equals( Object o) { if (!(o instanceof DERBMPString)) { return false; } DERBMPString s = (DERBMPString)o; return this.getString().equals(s.getString()); } void encode( DEROutputStream out) throws IOException { byte[] bytes = new byte[string.length()]; string.getBytes(0, string.length(), bytes, 0); out.writeEncoded(BMP_STRING, bytes); } } bouncycastle-1.49.orig/jdk1.0/org/bouncycastle/asn1/ASN1InputStream.java0000644000175000017500000002541010706632454025316 0ustar ebourgebourgpackage org.bouncycastle.asn1; import java.io.ByteArrayInputStream; import java.io.ByteArrayOutputStream; import java.io.IOException; import java.io.InputStream; import java.util.Vector; class EOCObject extends DERObject { void encode( DEROutputStream out) throws IOException { throw new IOException("Eeek!"); } public boolean equals(Object o) { return (o instanceof EOCObject); } public int hashCode() { return 0; } } /** * a general purpose ASN.1 decoder - note: this class differs from the * others in that it returns null after it has read the last object in * the stream. If an ASN.1 NULL is encountered a DER/BER Null object is * returned. */ public class ASN1InputStream extends DERInputStream { private static final DERObject END_OF_STREAM = new EOCObject(); public ASN1InputStream( InputStream is) { super(is); } protected int readLength() throws IOException { int length = read(); if (length < 0) { throw new IOException("EOF found when length expected"); } if (length == 0x80) { return -1; // indefinite-length encoding } if (length > 127) { int size = length & 0x7f; if (size > 4) { throw new IOException("DER length more than 4 bytes"); } length = 0; for (int i = 0; i < size; i++) { int next = read(); if (next < 0) { throw new IOException("EOF found reading length"); } length = (length << 8) + next; } if (length < 0) { throw new IOException("corrupted stream - negative length found"); } } return length; } protected void readFully( byte[] bytes) throws IOException { int left = bytes.length; if (left == 0) { return; } while ((left -= read(bytes, bytes.length - left, left)) != 0) { ; } } /** * build an object given its tag and a byte stream to construct it * from. */ protected DERObject buildObject( int tag, byte[] bytes) throws IOException { switch (tag) { case NULL: return new DERNull(); case SEQUENCE | CONSTRUCTED: ByteArrayInputStream bIn = new ByteArrayInputStream(bytes); ASN1InputStream aIn = new ASN1InputStream(bIn); ASN1EncodableVector v = new ASN1EncodableVector(); DERObject obj = aIn.readObject(); while (obj != null) { v.add(obj); obj = aIn.readObject(); } return new DERSequence(v); case SET | CONSTRUCTED: bIn = new ByteArrayInputStream(bytes); aIn = new ASN1InputStream(bIn); v = new ASN1EncodableVector(); obj = aIn.readObject(); while (obj != null) { v.add(obj); obj = aIn.readObject(); } return new DERSet(v); case BOOLEAN: return new DERBoolean(bytes); case INTEGER: return new DERInteger(bytes); case ENUMERATED: return new DEREnumerated(bytes); case OBJECT_IDENTIFIER: return new DERObjectIdentifier(bytes); case BIT_STRING: int padBits = bytes[0]; byte[] data = new byte[bytes.length - 1]; System.arraycopy(bytes, 1, data, 0, bytes.length - 1); return new DERBitString(data, padBits); case UTF8_STRING: return new DERUTF8String(bytes); case PRINTABLE_STRING: return new DERPrintableString(bytes); case IA5_STRING: return new DERIA5String(bytes); case T61_STRING: return new DERT61String(bytes); case VISIBLE_STRING: return new DERVisibleString(bytes); case UNIVERSAL_STRING: return new DERUniversalString(bytes); case BMP_STRING: return new DERBMPString(bytes); case OCTET_STRING: return new DEROctetString(bytes); case UTC_TIME: return new DERUTCTime(bytes); case GENERALIZED_TIME: return new DERGeneralizedTime(bytes); default: // // with tagged object tag number is bottom 5 bits // if ((tag & TAGGED) != 0) { if ((tag & 0x1f) == 0x1f) { throw new IOException("unsupported high tag encountered"); } if (bytes.length == 0) // empty tag! { return new DERTaggedObject(tag & 0x1f); } // // simple type - implicit... return an octet string // if ((tag & CONSTRUCTED) == 0) { return new DERTaggedObject(false, tag & 0x1f, new DEROctetString(bytes)); } bIn = new ByteArrayInputStream(bytes); aIn = new ASN1InputStream(bIn); DEREncodable dObj = aIn.readObject(); // // explicitly tagged (probably!) - if it isn't we'd have to // tell from the context // if (aIn.available() == 0) { return new DERTaggedObject(tag & 0x1f, dObj); } // // another implicit object, we'll create a sequence... // v = new ASN1EncodableVector(); while (dObj != null) { v.add(dObj); dObj = aIn.readObject(); } return new DERTaggedObject(false, tag & 0x1f, new DERSequence(v)); } return new DERUnknownTag(tag, bytes); } } /** * read a string of bytes representing an indefinite length object. */ private byte[] readIndefiniteLengthFully() throws IOException { ByteArrayOutputStream bOut = new ByteArrayOutputStream(); int b, b1; b1 = read(); while ((b = read()) >= 0) { if (b1 == 0 && b == 0) { break; } bOut.write(b1); b1 = b; } return bOut.toByteArray(); } private BERConstructedOctetString buildConstructedOctetString() throws IOException { Vector octs = new Vector(); for (;;) { DERObject o = readObject(); if (o == END_OF_STREAM) { break; } octs.addElement(o); } return new BERConstructedOctetString(octs); } public DERObject readObject() throws IOException { int tag = read(); if (tag == -1) { return null; } int length = readLength(); if (length < 0) // indefinite length method { switch (tag) { case NULL: return new BERNull(); case SEQUENCE | CONSTRUCTED: ASN1EncodableVector v = new ASN1EncodableVector(); for (;;) { DERObject obj = readObject(); if (obj == END_OF_STREAM) { break; } v.add(obj); } return new BERSequence(v); case SET | CONSTRUCTED: v = new ASN1EncodableVector(); for (;;) { DERObject obj = readObject(); if (obj == END_OF_STREAM) { break; } v.add(obj); } return new BERSet(v); case OCTET_STRING | CONSTRUCTED: return buildConstructedOctetString(); default: // // with tagged object tag number is bottom 5 bits // if ((tag & TAGGED) != 0) { if ((tag & 0x1f) == 0x1f) { throw new IOException("unsupported high tag encountered"); } // // simple type - implicit... return an octet string // if ((tag & CONSTRUCTED) == 0) { byte[] bytes = readIndefiniteLengthFully(); return new BERTaggedObject(false, tag & 0x1f, new DEROctetString(bytes)); } // // either constructed or explicitly tagged // DERObject dObj = readObject(); if (dObj == END_OF_STREAM) // empty tag! { return new DERTaggedObject(tag & 0x1f); } DERObject next = readObject(); // // explicitly tagged (probably!) - if it isn't we'd have to // tell from the context // if (next == END_OF_STREAM) { return new BERTaggedObject(tag & 0x1f, dObj); } // // another implicit object, we'll create a sequence... // v = new ASN1EncodableVector(); v.add(dObj); do { v.add(next); next = readObject(); } while (next != END_OF_STREAM); return new BERTaggedObject(false, tag & 0x1f, new BERSequence(v)); } throw new IOException("unknown BER object encountered"); } } else { if (tag == 0 && length == 0) // end of contents marker. { return END_OF_STREAM; } byte[] bytes = new byte[length]; readFully(bytes); return buildObject(tag, bytes); } } } bouncycastle-1.49.orig/jdk1.0/org/bouncycastle/asn1/BERInputStream.java0000644000175000017500000001024510533203640025211 0ustar ebourgebourgpackage org.bouncycastle.asn1; import java.io.ByteArrayOutputStream; import java.io.EOFException; import java.io.IOException; import java.io.InputStream; import java.util.Vector; class eos extends DERObject { void encode( DEROutputStream out) throws IOException { throw new IOException("Eeek!"); } public boolean equals(Object o) { return (o instanceof eos); } public int hashCode() { return 0; } } public class BERInputStream extends DERInputStream { private static final DERObject END_OF_STREAM = new eos(); public BERInputStream( InputStream is) { super(is); } /** * read a string of bytes representing an indefinite length object. */ private byte[] readIndefiniteLengthFully() throws IOException { ByteArrayOutputStream bOut = new ByteArrayOutputStream(); int b, b1; b1 = read(); while ((b = read()) >= 0) { if (b1 == 0 && b == 0) { break; } bOut.write(b1); b1 = b; } return bOut.toByteArray(); } private BERConstructedOctetString buildConstructedOctetString( DEROctetString o1, DEROctetString o2) throws IOException { Vector octs = new Vector(); if (o1 != null) { octs.addElement(o1); octs.addElement(o2); } for (;;) { DERObject o = readObject(); if (o == END_OF_STREAM) { break; } octs.addElement(o); } return new BERConstructedOctetString(octs); } public DERObject readObject() throws IOException { int tag = read(); if (tag == -1) { throw new EOFException(); } int length = readLength(); if (length < 0) // indefinite length method { byte[] bytes; switch (tag) { case NULL: return null; case SEQUENCE | CONSTRUCTED: BERConstructedSequence seq = new BERConstructedSequence(); for (;;) { DERObject obj = readObject(); if (obj == END_OF_STREAM) { break; } seq.addObject(obj); } return seq; case OCTET_STRING | CONSTRUCTED: return buildConstructedOctetString(null, null); default: if ((tag & (TAGGED | CONSTRUCTED)) != 0) { // with tagged object tag number is bottom 4 bits BERTaggedObject tagObj = new BERTaggedObject(tag & 0x0f, readObject()); DERObject o = readObject(); if (o == END_OF_STREAM) { return tagObj; } else if (o instanceof DEROctetString && tagObj.getObject() instanceof DEROctetString) { // // it's an implicit object - mark it as so... // tagObj = new BERTaggedObject(false, tag & 0x0f, buildConstructedOctetString((DEROctetString)tagObj.getObject(), (DEROctetString)o)); return tagObj; } throw new IOException("truncated tagged object"); } bytes = readIndefiniteLengthFully(); return buildObject(tag, bytes); } } else { if (tag == 0 && length == 0) // end of contents marker. { return END_OF_STREAM; } byte[] bytes = new byte[length]; readFully(bytes); return buildObject(tag, bytes); } } } bouncycastle-1.49.orig/jdk1.0/org/bouncycastle/util/0000755000175000017500000000000012152033551021654 5ustar ebourgebourgbouncycastle-1.49.orig/jdk1.0/org/bouncycastle/util/encoders/0000755000175000017500000000000012152033551023456 5ustar ebourgebourgbouncycastle-1.49.orig/jdk1.0/org/bouncycastle/util/encoders/Base64.java0000644000175000017500000001754010350737002025354 0ustar ebourgebourgpackage org.bouncycastle.util.encoders; public class Base64 { private static byte[] encodingTable = { (byte)'A', (byte)'B', (byte)'C', (byte)'D', (byte)'E', (byte)'F', (byte)'G', (byte)'H', (byte)'I', (byte)'J', (byte)'K', (byte)'L', (byte)'M', (byte)'N', (byte)'O', (byte)'P', (byte)'Q', (byte)'R', (byte)'S', (byte)'T', (byte)'U', (byte)'V', (byte)'W', (byte)'X', (byte)'Y', (byte)'Z', (byte)'a', (byte)'b', (byte)'c', (byte)'d', (byte)'e', (byte)'f', (byte)'g', (byte)'h', (byte)'i', (byte)'j', (byte)'k', (byte)'l', (byte)'m', (byte)'n', (byte)'o', (byte)'p', (byte)'q', (byte)'r', (byte)'s', (byte)'t', (byte)'u', (byte)'v', (byte)'w', (byte)'x', (byte)'y', (byte)'z', (byte)'0', (byte)'1', (byte)'2', (byte)'3', (byte)'4', (byte)'5', (byte)'6', (byte)'7', (byte)'8', (byte)'9', (byte)'+', (byte)'/' }; /** * encode the input data producong a base 64 encoded byte array. * * @return a byte array containing the base 64 encoded data. */ public static byte[] encode( byte[] data) { byte[] bytes; int modulus = data.length % 3; if (modulus == 0) { bytes = new byte[4 * data.length / 3]; } else { bytes = new byte[4 * ((data.length / 3) + 1)]; } int dataLength = (data.length - modulus); int a1, a2, a3; for (int i = 0, j = 0; i < dataLength; i += 3, j += 4) { a1 = data[i] & 0xff; a2 = data[i + 1] & 0xff; a3 = data[i + 2] & 0xff; bytes[j] = encodingTable[(a1 >>> 2) & 0x3f]; bytes[j + 1] = encodingTable[((a1 << 4) | (a2 >>> 4)) & 0x3f]; bytes[j + 2] = encodingTable[((a2 << 2) | (a3 >>> 6)) & 0x3f]; bytes[j + 3] = encodingTable[a3 & 0x3f]; } /* * process the tail end. */ int b1, b2, b3; int d1, d2; switch (modulus) { case 0: /* nothing left to do */ break; case 1: d1 = data[data.length - 1] & 0xff; b1 = (d1 >>> 2) & 0x3f; b2 = (d1 << 4) & 0x3f; bytes[bytes.length - 4] = encodingTable[b1]; bytes[bytes.length - 3] = encodingTable[b2]; bytes[bytes.length - 2] = (byte)'='; bytes[bytes.length - 1] = (byte)'='; break; case 2: d1 = data[data.length - 2] & 0xff; d2 = data[data.length - 1] & 0xff; b1 = (d1 >>> 2) & 0x3f; b2 = ((d1 << 4) | (d2 >>> 4)) & 0x3f; b3 = (d2 << 2) & 0x3f; bytes[bytes.length - 4] = encodingTable[b1]; bytes[bytes.length - 3] = encodingTable[b2]; bytes[bytes.length - 2] = encodingTable[b3]; bytes[bytes.length - 1] = (byte)'='; break; } return bytes; } /* * set up the decoding table. */ private static byte[] decodingTable; static { decodingTable = new byte[128]; for (int i = 'A'; i <= 'Z'; i++) { decodingTable[i] = (byte)(i - 'A'); } for (int i = 'a'; i <= 'z'; i++) { decodingTable[i] = (byte)(i - 'a' + 26); } for (int i = '0'; i <= '9'; i++) { decodingTable[i] = (byte)(i - '0' + 52); } decodingTable['+'] = 62; decodingTable['/'] = 63; } /** * decode the base 64 encoded input data. * * @return a byte array representing the decoded data. */ public static byte[] decode( byte[] data) { byte[] bytes; byte b1, b2, b3, b4; if (data[data.length - 2] == '=') { bytes = new byte[(((data.length / 4) - 1) * 3) + 1]; } else if (data[data.length - 1] == '=') { bytes = new byte[(((data.length / 4) - 1) * 3) + 2]; } else { bytes = new byte[((data.length / 4) * 3)]; } for (int i = 0, j = 0; i < data.length - 4; i += 4, j += 3) { b1 = decodingTable[data[i]]; b2 = decodingTable[data[i + 1]]; b3 = decodingTable[data[i + 2]]; b4 = decodingTable[data[i + 3]]; bytes[j] = (byte)((b1 << 2) | (b2 >> 4)); bytes[j + 1] = (byte)((b2 << 4) | (b3 >> 2)); bytes[j + 2] = (byte)((b3 << 6) | b4); } if (data[data.length - 2] == '=') { b1 = decodingTable[data[data.length - 4]]; b2 = decodingTable[data[data.length - 3]]; bytes[bytes.length - 1] = (byte)((b1 << 2) | (b2 >> 4)); } else if (data[data.length - 1] == '=') { b1 = decodingTable[data[data.length - 4]]; b2 = decodingTable[data[data.length - 3]]; b3 = decodingTable[data[data.length - 2]]; bytes[bytes.length - 2] = (byte)((b1 << 2) | (b2 >> 4)); bytes[bytes.length - 1] = (byte)((b2 << 4) | (b3 >> 2)); } else { b1 = decodingTable[data[data.length - 4]]; b2 = decodingTable[data[data.length - 3]]; b3 = decodingTable[data[data.length - 2]]; b4 = decodingTable[data[data.length - 1]]; bytes[bytes.length - 3] = (byte)((b1 << 2) | (b2 >> 4)); bytes[bytes.length - 2] = (byte)((b2 << 4) | (b3 >> 2)); bytes[bytes.length - 1] = (byte)((b3 << 6) | b4); } return bytes; } /** * decode the base 64 encoded String data. * * @return a byte array representing the decoded data. */ public static byte[] decode( String data) { byte[] bytes; byte b1, b2, b3, b4; if (data.charAt(data.length() - 2) == '=') { bytes = new byte[(((data.length() / 4) - 1) * 3) + 1]; } else if (data.charAt(data.length() - 1) == '=') { bytes = new byte[(((data.length() / 4) - 1) * 3) + 2]; } else { bytes = new byte[((data.length() / 4) * 3)]; } for (int i = 0, j = 0; i < data.length() - 4; i += 4, j += 3) { b1 = decodingTable[data.charAt(i)]; b2 = decodingTable[data.charAt(i + 1)]; b3 = decodingTable[data.charAt(i + 2)]; b4 = decodingTable[data.charAt(i + 3)]; bytes[j] = (byte)((b1 << 2) | (b2 >> 4)); bytes[j + 1] = (byte)((b2 << 4) | (b3 >> 2)); bytes[j + 2] = (byte)((b3 << 6) | b4); } if (data.charAt(data.length() - 2) == '=') { b1 = decodingTable[data.charAt(data.length() - 4)]; b2 = decodingTable[data.charAt(data.length() - 3)]; bytes[bytes.length - 1] = (byte)((b1 << 2) | (b2 >> 4)); } else if (data.charAt(data.length() - 1) == '=') { b1 = decodingTable[data.charAt(data.length() - 4)]; b2 = decodingTable[data.charAt(data.length() - 3)]; b3 = decodingTable[data.charAt(data.length() - 2)]; bytes[bytes.length - 2] = (byte)((b1 << 2) | (b2 >> 4)); bytes[bytes.length - 1] = (byte)((b2 << 4) | (b3 >> 2)); } else { b1 = decodingTable[data.charAt(data.length() - 4)]; b2 = decodingTable[data.charAt(data.length() - 3)]; b3 = decodingTable[data.charAt(data.length() - 2)]; b4 = decodingTable[data.charAt(data.length() - 1)]; bytes[bytes.length - 3] = (byte)((b1 << 2) | (b2 >> 4)); bytes[bytes.length - 2] = (byte)((b2 << 4) | (b3 >> 2)); bytes[bytes.length - 1] = (byte)((b3 << 6) | b4); } return bytes; } } bouncycastle-1.49.orig/jdk1.0/org/bouncycastle/math/0000755000175000017500000000000012152033551021630 5ustar ebourgebourgbouncycastle-1.49.orig/jdk1.0/org/bouncycastle/math/ec/0000755000175000017500000000000012152033551022217 5ustar ebourgebourgbouncycastle-1.49.orig/jdk1.0/org/bouncycastle/math/ec/ECPointFp.java0000644000175000017500000000473210262753175024672 0ustar ebourgebourgpackage org.bouncycastle.math.ec; import java.math.BigInteger; public class ECPointFp extends ECPoint { public ECPointFp(ECCurve curve, ECFieldElement x, ECFieldElement y) { super(curve, x, y); } /** * return the field element encoded with point compression. (S 4.3.6) */ public byte[] getEncoded() { byte PC; if (this.getY().toBigInteger().testBit(0)) { PC = 0x02; } else { PC = 0x03; } byte[] X = this.getX().toBigInteger().toByteArray(); byte[] PO = new byte[X.length + 1]; PO[0] = PC; System.arraycopy(X, 0, PO, 1, X.length); return PO; } // B.3 pg 62 public ECPoint add(ECPoint b) { ECFieldElement gamma = b.y.subtract(y).divide(b.x.subtract(x)); ECFieldElement x3 = gamma.multiply(gamma).subtract(x).subtract(b.x); ECFieldElement y3 = gamma.multiply(x.subtract(x3)).subtract(y); return new ECPointFp(curve, x3, y3); } // B.3 pg 62 public ECPoint twice() { ECFieldElement TWO = curve.fromBigInteger(BigInteger.valueOf(2)); ECFieldElement THREE = curve.fromBigInteger(BigInteger.valueOf(3)); ECFieldElement gamma = x.multiply(x).multiply(THREE).add(curve.a).divide(y.multiply(TWO)); ECFieldElement x3 = gamma.multiply(gamma).subtract(x.multiply(TWO)); ECFieldElement y3 = gamma.multiply(x.subtract(x3)).subtract(y); return new ECPointFp(curve, x3, y3); } // D.3.2 pg 102 (see Note:) public ECPoint subtract(ECPoint p2) { return add(new ECPointFp(curve, p2.x, p2.y.negate())); } // D.3.2 pg 101 public ECPoint multiply(BigInteger k) { // BigInteger e = k.mod(n); // n == order this BigInteger e = k; BigInteger h = e.multiply(BigInteger.valueOf(3)); ECPoint R = this; for (int i = h.bitLength() - 2; i > 0; i--) { R = R.twice(); if ( h.testBit(i) && !e.testBit(i) ) { //System.out.print("+"); R = R.add(this); } else if ( !h.testBit(i) && e.testBit(i) ) { //System.out.print("-"); R = R.subtract(this); } // else // System.out.print("."); } // System.out.println(); return R; } } bouncycastle-1.49.orig/jdk1.0/org/bouncycastle/math/ec/ECConstants.java0000644000175000017500000000034310262753175025261 0ustar ebourgebourgpackage org.bouncycastle.math.ec; import java.math.BigInteger; public interface ECConstants { public static final BigInteger ZERO = BigInteger.valueOf(0); public static final BigInteger ONE = BigInteger.valueOf(1); } bouncycastle-1.49.orig/jdk1.0/org/bouncycastle/math/ec/ECCurveFp.java0000644000175000017500000000410310350737002024642 0ustar ebourgebourgpackage org.bouncycastle.math.ec; import java.math.BigInteger; public class ECCurveFp extends ECCurve { public ECCurveFp(BigInteger q, BigInteger a, BigInteger b) { super(q, a, b); } public ECFieldElement fromBigInteger(BigInteger x) { return new ECFieldElementFp(this.getQ(), x); } public BigInteger getQ() { return q; } // 4.2.1 pg 17 public ECPoint decodePoint(byte[] encoded) { ECPoint p = null; switch (encoded[0]) { // compressed case 0x02: case 0x03: int ytilde = encoded[0] & 1; byte[] i = new byte[encoded.length - 1]; System.arraycopy(encoded, 1, i, 0, i.length); ECFieldElement x = new ECFieldElementFp(this.q, new BigInteger(1, i)); ECFieldElement alpha = x.multiply(x.square()).add(x.multiply(a).add(b)); ECFieldElement beta = alpha.sqrt(); if ( beta == null ) { throw new RuntimeException("Invalid point compression"); } int bit0 = (beta.toBigInteger().testBit(0) ? 0 : 1); if ( bit0 == ytilde ) { p = new ECPointFp(this, x, beta); } else { p = new ECPointFp(this, x, new ECFieldElementFp(this.q, q.subtract(beta.toBigInteger()))); } break; case 0x04: byte[] xEnc = new byte[(encoded.length - 1) / 2]; byte[] yEnc = new byte[(encoded.length - 1) / 2]; System.arraycopy(encoded, 1, xEnc, 0, xEnc.length); System.arraycopy(encoded, xEnc.length + 1, yEnc, 0, yEnc.length); p = new ECPointFp(this, new ECFieldElementFp(this.q, new BigInteger(1, xEnc)), new ECFieldElementFp(this.q, new BigInteger(1, yEnc))); break; default: throw new RuntimeException("Invalid point encoding 0x" + Integer.toString(encoded[0], 16)); } return p; } } bouncycastle-1.49.orig/jdk1.0/org/bouncycastle/math/ec/ECCurve.java0000644000175000017500000000101110262753175024362 0ustar ebourgebourgpackage org.bouncycastle.math.ec; import java.math.BigInteger; public abstract class ECCurve { BigInteger q; ECFieldElement a, b; public ECCurve(BigInteger q, BigInteger a, BigInteger b) { this.q = q; this.a = fromBigInteger(a); this.b = fromBigInteger(b); } public abstract ECFieldElement fromBigInteger(BigInteger x); public abstract ECPoint decodePoint(byte[] encoded); public ECFieldElement getA() { return a; } public ECFieldElement getB() { return b; } } bouncycastle-1.49.orig/jdk1.0/org/bouncycastle/math/ec/ECFieldElementFp.java0000644000175000017500000000310310262753175026125 0ustar ebourgebourgpackage org.bouncycastle.math.ec; import java.math.BigInteger; public class ECFieldElementFp extends ECFieldElement { /** * return the field name for this field. * * @return the string "Fp". */ public String getFieldName() { return "Fp"; } public ECFieldElementFp(BigInteger q, BigInteger x) { super(q, x); } public ECFieldElement add(ECFieldElement b) { return new ECFieldElementFp(p, x.add(b.x).mod(p)); } public ECFieldElement subtract(ECFieldElement b) { return new ECFieldElementFp(p, x.subtract(b.x).mod(p)); } public ECFieldElement multiply(ECFieldElement b) { return new ECFieldElementFp(p, x.multiply(b.x).mod(p)); } public ECFieldElement divide(ECFieldElement b) { return new ECFieldElementFp(p, x.multiply(b.x.modInverse(p)).mod(p)); } public ECFieldElement negate() { return new ECFieldElementFp(p, x.negate().mod(p)); } public ECFieldElement square() { return new ECFieldElementFp(p, x.multiply(x).mod(p)); } public ECFieldElement invert() { return new ECFieldElementFp(p, x.modInverse(p)); } // D.1.4 91 public ECFieldElement sqrt() { // p mod 4 == 3 if ( p.testBit(1) ) { // z = g^(u+1) + p, p = 4u + 3 ECFieldElement z = new ECFieldElementFp(p, x.modPow(p.shiftRight(2).add(ONE), p)); return z.square().equals(this) ? z : null; } throw new RuntimeException("not done yet"); } } bouncycastle-1.49.orig/jdk1.0/org/bouncycastle/math/ec/ECPoint.java0000644000175000017500000000174010350737002024365 0ustar ebourgebourgpackage org.bouncycastle.math.ec; import java.math.BigInteger; public abstract class ECPoint { ECCurve curve; ECFieldElement x; ECFieldElement y; public ECPoint(ECCurve curve, ECFieldElement x, ECFieldElement y) { this.curve = curve; this.x = x; this.y = y; } public ECFieldElement getX() { return x; } public ECFieldElement getY() { return y; } public boolean equals( Object other) { if (other == this) { return true; } if (!(other instanceof ECPoint)) { return false; } ECPoint o = (ECPoint)other; return x.equals(o.x) && y.equals(o.y); } public abstract byte[] getEncoded(); public abstract ECPoint add(ECPoint b); public abstract ECPoint subtract(ECPoint b); public abstract ECPoint twice(); public abstract ECPoint multiply(BigInteger b); } bouncycastle-1.49.orig/jdk1.0/org/bouncycastle/math/ec/ECFieldElement.java0000644000175000017500000000216310262753175025644 0ustar ebourgebourgpackage org.bouncycastle.math.ec; import java.math.BigInteger; public abstract class ECFieldElement implements ECConstants { BigInteger x; BigInteger p; public ECFieldElement(BigInteger q, BigInteger x) { if (x.compareTo(q) >= 0) { throw new IllegalArgumentException("x value of field element too large"); } this.x = x; this.p = q; // curve.getQ(); } public BigInteger toBigInteger() { return x; } public boolean equals(Object other) { if ( other == this ) return true; if ( !(other instanceof ECFieldElement) ) return false; ECFieldElement o = (ECFieldElement)other; return p.equals(o.p) && x.equals(o.x); } public abstract String getFieldName(); public abstract ECFieldElement add(ECFieldElement b); public abstract ECFieldElement subtract(ECFieldElement b); public abstract ECFieldElement multiply(ECFieldElement b); public abstract ECFieldElement divide(ECFieldElement b); public abstract ECFieldElement negate(); public abstract ECFieldElement square(); public abstract ECFieldElement invert(); public abstract ECFieldElement sqrt(); } bouncycastle-1.49.orig/jdk1.0/java/0000755000175000017500000000000012152033551016336 5ustar ebourgebourgbouncycastle-1.49.orig/jdk1.0/java/lang/0000755000175000017500000000000012152033551017257 5ustar ebourgebourgbouncycastle-1.49.orig/jdk1.0/java/lang/IllegalStateException.java0000644000175000017500000000033110350737002024350 0ustar ebourgebourgpackage java.lang; public class IllegalStateException extends RuntimeException { public IllegalStateException() { } public IllegalStateException(String message) { super(message); } } bouncycastle-1.49.orig/jdk1.0/java/math/0000755000175000017500000000000012152033551017267 5ustar ebourgebourgbouncycastle-1.49.orig/jdk1.0/java/math/test/0000755000175000017500000000000012152033551020246 5ustar ebourgebourgbouncycastle-1.49.orig/jdk1.0/java/math/test/BigIntegerTest.java0000644000175000017500000003155112062253471024002 0ustar ebourgebourgpackage java.math.test; import java.math.BigInteger; import java.security.SecureRandom; import org.bouncycastle.util.test.*; public class BigIntegerTest extends SimpleTest { private static BigInteger VALUE1 = new BigInteger("1234"); private static BigInteger VALUE2 = new BigInteger("1234567890"); private static BigInteger VALUE3 = new BigInteger("12345678901234567890123"); private static BigInteger zero = BigInteger.ZERO; private static BigInteger one = BigInteger.ONE; private static BigInteger two = BigInteger.valueOf(2); public String getName() { return "BigInteger"; } private void clearBitTest() { BigInteger value = VALUE1.clearBit(3); BigInteger result = new BigInteger("1234"); if (!value.equals(result)) { fail("clearBit - expected: " + result + " got: " + value); } value = VALUE2.clearBit(3); result = new BigInteger("1234567890"); if (!value.equals(result)) { fail("clearBit - expected: " + result + " got: " + value); } value = VALUE3.clearBit(3); result = new BigInteger("12345678901234567890115"); if (!value.equals(result)) { fail("clearBit - expected: " + result + " got: " + value); } value = VALUE2.clearBit(55); result = new BigInteger("1234567890"); if (!value.equals(result)) { fail("clearBit - expected: " + result + " got: " + value); } value = VALUE3.clearBit(55); result = new BigInteger("12345642872437548926155"); if (!value.equals(result)) { fail("clearBit - expected: " + result + " got: " + value); } } private void flipBitTest() { BigInteger value = VALUE1.flipBit(3); BigInteger result = new BigInteger("1242"); if (!value.equals(result)) { fail("flipBit - expected: " + result + " got: " + value); } value = VALUE2.flipBit(3); result = new BigInteger("1234567898"); if (!value.equals(result)) { fail("flipBit - expected: " + result + " got: " + value); } value = VALUE3.flipBit(3); result = new BigInteger("12345678901234567890115"); if (!value.equals(result)) { fail("flipBit - expected: " + result + " got: " + value); } value = VALUE2.flipBit(55); result = new BigInteger("36028798253531858"); if (!value.equals(result)) { fail("flipBit - expected: " + result + " got: " + value); } value = VALUE3.flipBit(55); result = new BigInteger("12345642872437548926155"); if (!value.equals(result)) { fail("flipBit - expected: " + result + " got: " + value); } } private void setBitTest() { BigInteger value = VALUE1.setBit(3); BigInteger result = new BigInteger("1242"); if (!value.equals(result)) { fail("setBit - expected: " + result + " got: " + value); } value = VALUE2.setBit(3); result = new BigInteger("1234567898"); if (!value.equals(result)) { fail("setBit - expected: " + result + " got: " + value); } value = VALUE3.setBit(3); result = new BigInteger("12345678901234567890123"); if (!value.equals(result)) { fail("setBit - expected: " + result + " got: " + value); } value = VALUE2.setBit(55); result = new BigInteger("36028798253531858"); if (!value.equals(result)) { fail("setBit - expected: " + result + " got: " + value); } value = VALUE3.setBit(55); result = new BigInteger("12345678901234567890123"); if (!value.equals(result)) { fail("setBit - expected: " + result + " got: " + value); } } private void testDivideAndRemainder() { SecureRandom random = new SecureRandom(); BigInteger n = new BigInteger(48, random); BigInteger[] qr = n.divideAndRemainder(n); if (!qr[0].equals(one) || !qr[1].equals(zero)) { fail("testDivideAndRemainder - expected: 1/0 got: " + qr[0] + "/" + qr[1]); } qr = n.divideAndRemainder(one); if (!qr[0].equals(n) || !qr[1].equals(zero)) { fail("testDivideAndRemainder - expected: " + n + "/0 got: " + qr[0] + "/" + qr[1]); } for (int rep = 0; rep < 10; ++rep) { BigInteger a = new BigInteger(100 - rep, 0, random); BigInteger b = new BigInteger(100 + rep, 0, random); BigInteger c = new BigInteger(10 + rep, 0, random); BigInteger d = a.multiply(b).add(c); BigInteger[] es = d.divideAndRemainder(a); if (!es[0].equals(b) || !es[1].equals(c)) { fail("testDivideAndRemainder - expected: " + b + "/" + c + " got: " + qr[0] + "/" + qr[1]); } } } private void testModInverse() { SecureRandom random = new SecureRandom(); for (int i = 0; i < 10; ++i) { BigInteger p = BigInteger.probablePrime(64, random); BigInteger q = new BigInteger(63, random).add(one); BigInteger inv = q.modInverse(p); BigInteger inv2 = inv.modInverse(p); if (!q.equals(inv2)) { fail("testModInverse failed symmetry test"); } BigInteger check = q.multiply(inv).mod(p); if (!one.equals(check)) { fail("testModInverse - expected: 1 got: " + check); } } // ModInverse for powers of 2 for (int i = 1; i <= 128; ++i) { BigInteger m = one.shiftLeft(i); BigInteger d = new BigInteger(i, random).setBit(0); BigInteger x = d.modInverse(m); BigInteger check = x.multiply(d).mod(m); if (!one.equals(check)) { fail("testModInverse - expected: 1 got: " + check); } } } private void testNegate() { if (!zero.equals(zero.negate())) { fail("zero - negate falied"); } if (!one.equals(one.negate().negate())) { fail("one - negate falied"); } if (!two.equals(two.negate().negate())) { fail("two - negate falied"); } } private void testNot() { for (int i = -10; i <= 10; ++i) { if(!BigInteger.valueOf(~i).equals( BigInteger.valueOf(i).not())) { fail("Problem: ~" + i + " should be " + ~i); } } } private void testOr() { for (int i = -10; i <= 10; ++i) { for (int j = -10; j <= 10; ++j) { if (!BigInteger.valueOf(i | j).equals( BigInteger.valueOf(i).or(BigInteger.valueOf(j)))) { fail("Problem: " + i + " OR " + j + " should be " + (i | j)); } } } } public void testPow() { if (!one.equals(zero.pow(0))) { fail("one pow equals failed"); } if (!zero.equals(zero.pow(123))) { fail("zero pow equals failed"); } if (!one.equals(one.pow(0))) { fail("one one equals failed"); } if (!one.equals(one.pow(123))) { fail("1 123 equals failed"); } if (!two.pow(147).equals(one.shiftLeft(147))) { fail("2 pow failed"); } if (!one.shiftLeft(7).pow(11).equals(one.shiftLeft(77))) { fail("pow 2 pow failed"); } BigInteger n = new BigInteger("1234567890987654321"); BigInteger result = one; for (int i = 0; i < 10; ++i) { try { BigInteger.valueOf(i).pow(-1); fail("expected ArithmeticException"); } catch (ArithmeticException e) {} if (!result.equals(n.pow(i))) { fail("mod pow equals failed"); } result = result.multiply(n); } } public void testToString() { SecureRandom random = new SecureRandom(); int trials = 256; BigInteger[] tests = new BigInteger[trials]; for (int i = 0; i < trials; ++i) { int len = random.nextInt(i + 1); tests[i] = new BigInteger(len, random); } for (int radix = Character.MIN_RADIX; radix <= Character.MAX_RADIX; ++radix) { for (int i = 0; i < trials; ++i) { BigInteger n1 = tests[i]; String s = n1.toString(radix); BigInteger n2 = new BigInteger(s, radix); if (!n1.equals(n2)) { fail("testToStringRadix - radix:" + radix + ", n1:" + n1.toString(16) + ", n2:" + n2.toString(16)); } } } } private void xorTest() { BigInteger value = VALUE1.xor(VALUE2); BigInteger result = new BigInteger("1234568704"); if (!value.equals(result)) { fail("xor - expected: " + result + " got: " + value); } value = VALUE1.xor(VALUE3); result = new BigInteger("12345678901234567888921"); if (!value.equals(result)) { fail("xor - expected: " + result + " got: " + value); } value = VALUE3.xor(VALUE1); result = new BigInteger("12345678901234567888921"); if (!value.equals(result)) { fail("xor - expected: " + result + " got: " + value); } value = VALUE2.xor(new BigInteger("-1")); result = new BigInteger("-1234567891"); if (!value.equals(result)) { fail("xor - expected: " + result + " got: " + value); } value = VALUE3.xor(VALUE3); result = new BigInteger("0"); if (!value.equals(result)) { fail("xor - expected: " + result + " got: " + value); } } public void performTest() { clearBitTest(); flipBitTest(); setBitTest(); testDivideAndRemainder(); testModInverse(); testNegate(); testNot(); testOr(); testPow(); testToString(); xorTest(); BigInteger n1, n2, r1; // test division where the difference in bit length of the dividend and divisor is 32 bits n1 = new BigInteger("54975581388"); n2 = new BigInteger("10"); r1 = n1.divide(n2); if (!r1.toString(10).equals("5497558138")) { fail("BigInteger: failed Divide Test"); } // two's complement test byte[] zeroBytes = BigInteger.ZERO.toByteArray(); byte[] oneBytes = BigInteger.ONE.toByteArray(); byte[] minusOneBytes = BigInteger.ONE.negate().toByteArray(); BigInteger zero = new BigInteger(zeroBytes); if (!zero.equals(BigInteger.ZERO)) { fail("Failed constructing zero"); } BigInteger one = new BigInteger(oneBytes); if (!one.equals(BigInteger.ONE)) { fail("Failed constructing one"); } BigInteger minusOne = new BigInteger(minusOneBytes); if (!minusOne.equals(BigInteger.ONE.negate())) { fail("Failed constructing minus one"); } SecureRandom random = new SecureRandom(); byte[] randomBytes = new byte[100]; for (int i=0; i < 100; i++) { random.nextBytes(randomBytes); BigInteger bcInt = new BigInteger(randomBytes); BigInteger bcInt2 = new BigInteger(bcInt.toByteArray()); if (!bcInt.equals(bcInt2)) { fail("Failed constructing random value " + i); } // java.math.BigInteger jdkInt = new java.math.BigInteger(randomBytes); // byte[] bcBytes = bcInt.toByteArray(); // byte[] jdkBytes = jdkInt.toByteArray(); // if (!arrayEquals(bcBytes, jdkBytes)) // { // fail(""Failed constructing random value " + i); // } } } public static void main( String[] args) { runTest(new BigIntegerTest()); } } bouncycastle-1.49.orig/jdk1.0/java/math/test/RegressionTest.java0000644000175000017500000000067710262753175024116 0ustar ebourgebourgpackage java.math.test; import org.bouncycastle.util.test.Test; import org.bouncycastle.util.test.TestResult; public class RegressionTest { public static Test[] tests = { new BigIntegerTest() }; public static void main( String[] args) { for (int i = 0; i != tests.length; i++) { TestResult result = tests[i].perform(); System.out.println(result); } } } bouncycastle-1.49.orig/jdk1.0/java/math/BigInteger.java0000644000175000017500000024576012076150721022173 0ustar ebourgebourgpackage java.math; import java.util.Random; import java.util.Stack; import org.bouncycastle.util.Arrays; public class BigInteger { // The first few odd primes /* 3 5 7 11 13 17 19 23 29 31 37 41 43 47 53 59 61 67 71 73 79 83 89 97 101 103 107 109 113 127 131 137 139 149 151 157 163 167 173 179 181 191 193 197 199 211 223 227 229 233 239 241 251 257 263 269 271 277 281 283 293 307 311 313 317 331 337 347 349 353 359 367 373 379 383 389 397 401 409 419 421 431 433 439 443 449 457 461 463 467 479 487 491 499 503 509 521 523 541 547 557 563 569 571 577 587 593 599 601 607 613 617 619 631 641 643 647 653 659 661 673 677 683 691 701 709 719 727 733 739 743 751 757 761 769 773 787 797 809 811 821 823 827 829 839 853 857 859 863 877 881 883 887 907 911 919 929 937 941 947 953 967 971 977 983 991 997 1009 1013 1019 1021 1031 1033 1039 1049 1051 1061 1063 1069 1087 1091 1093 1097 1103 1109 1117 1123 1129 1151 1153 1163 1171 1181 1187 1193 1201 1213 1217 1223 1229 1231 1237 1249 1259 1277 1279 1283 1289 */ // Each list has a product < 2^31 private static final int[][] primeLists = new int[][] { new int[]{ 3, 5, 7, 11, 13, 17, 19, 23 }, new int[]{ 29, 31, 37, 41, 43 }, new int[]{ 47, 53, 59, 61, 67 }, new int[]{ 71, 73, 79, 83 }, new int[]{ 89, 97, 101, 103 }, new int[]{ 107, 109, 113, 127 }, new int[]{ 131, 137, 139, 149 }, new int[]{ 151, 157, 163, 167 }, new int[]{ 173, 179, 181, 191 }, new int[]{ 193, 197, 199, 211 }, new int[]{ 223, 227, 229 }, new int[]{ 233, 239, 241 }, new int[]{ 251, 257, 263 }, new int[]{ 269, 271, 277 }, new int[]{ 281, 283, 293 }, new int[]{ 307, 311, 313 }, new int[]{ 317, 331, 337 }, new int[]{ 347, 349, 353 }, new int[]{ 359, 367, 373 }, new int[]{ 379, 383, 389 }, new int[]{ 397, 401, 409 }, new int[]{ 419, 421, 431 }, new int[]{ 433, 439, 443 }, new int[]{ 449, 457, 461 }, new int[]{ 463, 467, 479 }, new int[]{ 487, 491, 499 }, new int[]{ 503, 509, 521 }, new int[]{ 523, 541, 547 }, new int[]{ 557, 563, 569 }, new int[]{ 571, 577, 587 }, new int[]{ 593, 599, 601 }, new int[]{ 607, 613, 617 }, new int[]{ 619, 631, 641 }, new int[]{ 643, 647, 653 }, new int[]{ 659, 661, 673 }, new int[]{ 677, 683, 691 }, new int[]{ 701, 709, 719 }, new int[]{ 727, 733, 739 }, new int[]{ 743, 751, 757 }, new int[]{ 761, 769, 773 }, new int[]{ 787, 797, 809 }, new int[]{ 811, 821, 823 }, new int[]{ 827, 829, 839 }, new int[]{ 853, 857, 859 }, new int[]{ 863, 877, 881 }, new int[]{ 883, 887, 907 }, new int[]{ 911, 919, 929 }, new int[]{ 937, 941, 947 }, new int[]{ 953, 967, 971 }, new int[]{ 977, 983, 991 }, new int[]{ 997, 1009, 1013 }, new int[]{ 1019, 1021, 1031 }, new int[]{ 1033, 1039, 1049 }, new int[]{ 1051, 1061, 1063 }, new int[]{ 1069, 1087, 1091 }, new int[]{ 1093, 1097, 1103 }, new int[]{ 1109, 1117, 1123 }, new int[]{ 1129, 1151, 1153 }, new int[]{ 1163, 1171, 1181 }, new int[]{ 1187, 1193, 1201 }, new int[]{ 1213, 1217, 1223 }, new int[]{ 1229, 1231, 1237 }, new int[]{ 1249, 1259, 1277 }, new int[]{ 1279, 1283, 1289 }, }; private static int[] primeProducts; private static final long IMASK = 0xffffffffL; private static final int[] ZERO_MAGNITUDE = new int[0]; private static final BigInteger[] SMALL_CONSTANTS = new BigInteger[17]; public static final BigInteger ZERO; public static final BigInteger ONE; public static final BigInteger TWO; public static final BigInteger THREE; public static final BigInteger TEN; private final static byte[] bitCounts = { 0, 1, 1, 2, 1, 2, 2, 3, 1, 2, 2, 3, 2, 3, 3, 4, 1, 2, 2, 3, 2, 3, 3, 4, 2, 3, 3, 4, 3, 4, 4, 5, 1, 2, 2, 3, 2, 3, 3, 4, 2, 3, 3, 4, 3, 4, 4, 5, 2, 3, 3, 4, 3, 4, 4, 5, 3, 4, 4, 5, 4, 5, 5, 6, 1, 2, 2, 3, 2, 3, 3, 4, 2, 3, 3, 4, 3, 4, 4, 5, 2, 3, 3, 4, 3, 4, 4, 5, 3, 4, 4, 5, 4, 5, 5, 6, 2, 3, 3, 4, 3, 4, 4, 5, 3, 4, 4, 5, 4, 5, 5, 6, 3, 4, 4, 5, 4, 5, 5, 6, 4, 5, 5, 6, 5, 6, 6, 7, 1, 2, 2, 3, 2, 3, 3, 4, 2, 3, 3, 4, 3, 4, 4, 5, 2, 3, 3, 4, 3, 4, 4, 5, 3, 4, 4, 5, 4, 5, 5, 6, 2, 3, 3, 4, 3, 4, 4, 5, 3, 4, 4, 5, 4, 5, 5, 6, 3, 4, 4, 5, 4, 5, 5, 6, 4, 5, 5, 6, 5, 6, 6, 7, 2, 3, 3, 4, 3, 4, 4, 5, 3, 4, 4, 5, 4, 5, 5, 6, 3, 4, 4, 5, 4, 5, 5, 6, 4, 5, 5, 6, 5, 6, 6, 7, 3, 4, 4, 5, 4, 5, 5, 6, 4, 5, 5, 6, 5, 6, 6, 7, 4, 5, 5, 6, 5, 6, 6, 7, 5, 6, 6, 7, 6, 7, 7, 8 }; private final static byte[] bitLengths = { 0, 1, 2, 2, 3, 3, 3, 3, 4, 4, 4, 4, 4, 4, 4, 4, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8 }; /* * These are the threshold bit-lengths (of an exponent) where we increase the window size. * These were calculated according to the expected savings in multiplications. * Some squares will also be saved on average, but we offset these against the extra storage costs. */ private static final int[] EXP_WINDOW_THRESHOLDS = { 7, 25, 81, 241, 673, 1793, 4609, Integer.MAX_VALUE }; static { /* * Avoid using large windows in VMs with little memory. * Window size limited to 2 below 256kB, then increased by one for every doubling, * i.e. at 512kB, 1MB, 2MB, etc... */ long totalMemory = Runtime.getRuntime().totalMemory(); if (totalMemory <= Integer.MAX_VALUE) { int mem = (int)totalMemory; int maxExpThreshold = 1 + bitLen(mem >> 18); if (maxExpThreshold < EXP_WINDOW_THRESHOLDS.length) { EXP_WINDOW_THRESHOLDS[maxExpThreshold] = Integer.MAX_VALUE; } } ZERO = new BigInteger(0, ZERO_MAGNITUDE); ZERO.nBits = 0; ZERO.nBitLength = 0; SMALL_CONSTANTS[0] = ZERO; int numBits = 0; for (int i = 1; i < SMALL_CONSTANTS.length; ++i) { SMALL_CONSTANTS[i] = createValueOf(i); // Check for a power of two if ((i & -i) == i) { SMALL_CONSTANTS[i].nBits = 1; ++numBits; } SMALL_CONSTANTS[i].nBitLength = numBits; } ONE = SMALL_CONSTANTS[1]; TWO = SMALL_CONSTANTS[2]; THREE = SMALL_CONSTANTS[3]; TEN = SMALL_CONSTANTS[10]; primeProducts = new int[primeLists.length]; for (int i = 0; i < primeLists.length; ++i) { int[] primeList = primeLists[i]; int product = 1; for (int j = 0; j < primeList.length; ++j) { product *= primeList[j]; } primeProducts[i] = product; } } private int sign; // -1 means -ve; +1 means +ve; 0 means 0; private int[] magnitude; // array of ints with [0] being the most significant private int nBits = -1; // cache bitCount() value private int nBitLength = -1; // cache bitLength() value private int mQuote = 0; // -m^(-1) mod b, b = 2^32 (see Montgomery mult.), 0 when uninitialised private BigInteger() { } private BigInteger(int signum, int[] mag) { if (mag.length > 0) { sign = signum; int i = 0; while (i < mag.length && mag[i] == 0) { i++; } if (i == 0) { magnitude = mag; } else { // strip leading 0 bytes int[] newMag = new int[mag.length - i]; System.arraycopy(mag, i, newMag, 0, newMag.length); magnitude = newMag; if (newMag.length == 0) sign = 0; } } else { magnitude = mag; sign = 0; } } public BigInteger(String sval) throws NumberFormatException { this(sval, 10); } public BigInteger(String sval, int rdx) throws NumberFormatException { if (sval.length() == 0) { throw new NumberFormatException("Zero length BigInteger"); } if (rdx < Character.MIN_RADIX || rdx > Character.MAX_RADIX) { throw new NumberFormatException("Radix out of range"); } int index = 0; sign = 1; if (sval.charAt(0) == '-') { if (sval.length() == 1) { throw new NumberFormatException("Zero length BigInteger"); } sign = -1; index = 1; } // strip leading zeros from the string value while (index < sval.length() && Character.digit(sval.charAt(index), rdx) == 0) { index++; } if (index >= sval.length()) { // zero value - we're done sign = 0; magnitude = new int[0]; return; } ////// // could we work out the max number of ints required to store // sval.length digits in the given base, then allocate that // storage in one hit?, then generate the magnitude in one hit too? ////// BigInteger b = ZERO; BigInteger r = valueOf(rdx); while (index < sval.length()) { // (optimise this by taking chunks of digits instead?) b = b.multiply(r).add(valueOf(Character.digit(sval.charAt(index), rdx))); index++; } magnitude = b.magnitude; return; } public BigInteger(byte[] bval) throws NumberFormatException { if (bval.length == 0) { throw new NumberFormatException("Zero length BigInteger"); } sign = 1; if (bval[0] < 0) { sign = -1; } magnitude = makeMagnitude(bval, sign); if (magnitude.length == 0) { sign = 0; } } /** * If sign >= 0, packs bytes into an array of ints, most significant first * If sign < 0, packs 2's complement of bytes into * an array of ints, most significant first, * adding an extra most significant byte in case bval = {0x80, 0x00, ..., 0x00} * * @param bval * @param sign * @return */ private int[] makeMagnitude(byte[] bval, int sign) { if (sign >= 0) { int i; int[] mag; int firstSignificant; // strip leading zeros for (firstSignificant = 0; firstSignificant < bval.length && bval[firstSignificant] == 0; firstSignificant++); if (firstSignificant >= bval.length) { return new int[0]; } int nInts = (bval.length - firstSignificant + 3) / 4; int bCount = (bval.length - firstSignificant) % 4; if (bCount == 0) bCount = 4; // n = k * (n / k) + n % k // bval.length - firstSignificant + 3 = 4 * nInts + bCount - 1 // bval.length - firstSignificant + 4 - bCount = 4 * nInts mag = new int[nInts]; int v = 0; int magnitudeIndex = 0; for (i = firstSignificant; i < bval.length; i++) { // bval.length + 4 - bCount - i + 4 * magnitudeIndex = 4 * nInts // 1 <= bCount <= 4 v <<= 8; v |= bval[i] & 0xff; bCount--; if (bCount <= 0) { mag[magnitudeIndex] = v; magnitudeIndex++; bCount = 4; v = 0; } } // 4 - bCount + 4 * magnitudeIndex = 4 * nInts // bCount = 4 * (1 + magnitudeIndex - nInts) // 1 <= bCount <= 4 // So bCount = 4 and magnitudeIndex = nInts = mag.length // if (magnitudeIndex < mag.length) // { // mag[magnitudeIndex] = v; // } return mag; } else { int i; int[] mag; int firstSignificant; // strip leading -1's for (firstSignificant = 0; firstSignificant < bval.length - 1 && bval[firstSignificant] == 0xff; firstSignificant++); int nBytes = bval.length; boolean leadingByte = false; // check for -2^(n-1) if (bval[firstSignificant] == 0x80) { for (i = firstSignificant + 1; i < bval.length; i++) { if (bval[i] != 0) { break; } } if (i == bval.length) { nBytes++; leadingByte = true; } } int nInts = (nBytes - firstSignificant + 3) / 4; int bCount = (nBytes - firstSignificant) % 4; if (bCount == 0) bCount = 4; // n = k * (n / k) + n % k // nBytes - firstSignificant + 3 = 4 * nInts + bCount - 1 // nBytes - firstSignificant + 4 - bCount = 4 * nInts // 1 <= bCount <= 4 mag = new int[nInts]; int v = 0; int magnitudeIndex = 0; // nBytes + 4 - bCount - i + 4 * magnitudeIndex = 4 * nInts // 1 <= bCount <= 4 if (leadingByte) { // bval.length + 1 + 4 - bCount - i + 4 * magnitudeIndex = 4 * nInts bCount--; // bval.length + 1 + 4 - (bCount + 1) - i + 4 * magnitudeIndex = 4 * nInts // bval.length + 4 - bCount - i + 4 * magnitudeIndex = 4 * nInts if (bCount <= 0) { magnitudeIndex++; bCount = 4; } // bval.length + 4 - bCount - i + 4 * magnitudeIndex = 4 * nInts // 1 <= bCount <= 4 } for (i = firstSignificant; i < bval.length; i++) { // bval.length + 4 - bCount - i + 4 * magnitudeIndex = 4 * nInts // 1 <= bCount <= 4 v <<= 8; v |= ~bval[i] & 0xff; bCount--; if (bCount <= 0) { mag[magnitudeIndex] = v; magnitudeIndex++; bCount = 4; v = 0; } } // 4 - bCount + 4 * magnitudeIndex = 4 * nInts // 1 <= bCount <= 4 // bCount = 4 * (1 + magnitudeIndex - nInts) // 1 <= bCount <= 4 // So bCount = 4 and magnitudeIndex = nInts = mag.length // if (magnitudeIndex < mag.length) // { // mag[magnitudeIndex] = v; // } mag = inc(mag); // TODO Fix above so that this is not necessary? if (mag[0] == 0) { int[] tmp = new int[mag.length - 1]; System.arraycopy(mag, 1, tmp, 0, tmp.length); mag = tmp; } return mag; } } public BigInteger(int sign, byte[] mag) throws NumberFormatException { if (sign < -1 || sign > 1) { throw new NumberFormatException("Invalid sign value"); } if (sign == 0) { this.sign = 0; this.magnitude = new int[0]; return; } // copy bytes this.magnitude = makeMagnitude(mag, 1); this.sign = sign; } public BigInteger(int numBits, Random rnd) throws IllegalArgumentException { if (numBits < 0) { throw new IllegalArgumentException("numBits must be non-negative"); } this.nBits = -1; this.nBitLength = -1; if (numBits == 0) { // this.sign = 0; this.magnitude = ZERO_MAGNITUDE; return; } int nBytes = (numBits + 7) / 8; byte[] b = new byte[nBytes]; nextRndBytes(rnd, b); // strip off any excess bits in the MSB int xBits = BITS_PER_BYTE * nBytes - numBits; b[0] &= (byte)(255 >>> xBits); this.magnitude = makeMagnitude(b, 1); this.sign = this.magnitude.length < 1 ? 0 : 1; } private static final int BITS_PER_BYTE = 8; private static final int BYTES_PER_INT = 4; /** * strictly speaking this is a little dodgey from a compliance * point of view as it forces people to be using SecureRandom as * well, that being said - this implementation is for a crypto * library and you do have the source! */ private void nextRndBytes(Random rnd, byte[] bytes) { int numRequested = bytes.length; int numGot = 0, r = 0; if (rnd instanceof java.security.SecureRandom) { ((java.security.SecureRandom)rnd).nextBytes(bytes); } else { for (; ; ) { for (int i = 0; i < BYTES_PER_INT; i++) { if (numGot == numRequested) { return; } r = (i == 0 ? rnd.nextInt() : r >> BITS_PER_BYTE); bytes[numGot++] = (byte)r; } } } } public BigInteger(int bitLength, int certainty, Random rnd) throws ArithmeticException { if (bitLength < 2) { throw new ArithmeticException("bitLength < 2"); } this.sign = 1; this.nBitLength = bitLength; if (bitLength == 2) { this.magnitude = rnd.nextInt() < 0 ? TWO.magnitude : THREE.magnitude; return; } int nBytes = (bitLength + 7) / BITS_PER_BYTE; int xBits = BITS_PER_BYTE * nBytes - bitLength; byte mask = (byte)(255 >>> xBits); byte[] b = new byte[nBytes]; for (;;) { nextRndBytes(rnd, b); // strip off any excess bits in the MSB b[0] &= mask; // ensure the leading bit is 1 (to meet the strength requirement) b[0] |= (byte)(1 << (7 - xBits)); // ensure the trailing bit is 1 (i.e. must be odd) b[nBytes - 1] |= (byte)1; this.magnitude = makeMagnitude(b, 1); this.nBits = -1; this.mQuote = 0; if (certainty < 1) break; if (this.isProbablePrime(certainty)) break; if (bitLength > 32) { for (int rep = 0; rep < 10000; ++rep) { int n = 33 + (rnd.nextInt() >>> 1) % (bitLength - 2); this.magnitude[this.magnitude.length - (n >>> 5)] ^= (1 << (n & 31)); this.magnitude[this.magnitude.length - 1] ^= (rnd.nextInt() << 1); this.mQuote = 0; if (this.isProbablePrime(certainty)) return; } } } } public BigInteger abs() { return (sign >= 0) ? this : this.negate(); } /** * return a = a + b - b preserved. */ private int[] add(int[] a, int[] b) { int tI = a.length - 1; int vI = b.length - 1; long m = 0; while (vI >= 0) { m += (((long)a[tI]) & IMASK) + (((long)b[vI--]) & IMASK); a[tI--] = (int)m; m >>>= 32; } while (tI >= 0 && m != 0) { m += (((long)a[tI]) & IMASK); a[tI--] = (int)m; m >>>= 32; } return a; } /** * return a = a + 1. */ private int[] inc(int[] a) { int tI = a.length - 1; long m = 0; m = (((long)a[tI]) & IMASK) + 1L; a[tI--] = (int)m; m >>>= 32; while (tI >= 0 && m != 0) { m += (((long)a[tI]) & IMASK); a[tI--] = (int)m; m >>>= 32; } return a; } public BigInteger add(BigInteger val) throws ArithmeticException { if (val.sign == 0 || val.magnitude.length == 0) return this; if (this.sign == 0 || this.magnitude.length == 0) return val; if (val.sign < 0) { if (this.sign > 0) return this.subtract(val.negate()); } else { if (this.sign < 0) return val.subtract(this.negate()); } return addToMagnitude(val.magnitude); } private BigInteger addToMagnitude( int[] magToAdd) { int[] big, small; if (this.magnitude.length < magToAdd.length) { big = magToAdd; small = this.magnitude; } else { big = this.magnitude; small = magToAdd; } // Conservatively avoid over-allocation when no overflow possible int limit = Integer.MAX_VALUE; if (big.length == small.length) limit -= small[0]; boolean possibleOverflow = (big[0] ^ (1 << 31)) >= limit; int extra = possibleOverflow ? 1 : 0; int[] bigCopy = new int[big.length + extra]; System.arraycopy(big, 0, bigCopy, extra, big.length); bigCopy = add(bigCopy, small); return new BigInteger(this.sign, bigCopy); } public BigInteger and( BigInteger value) { if (this.sign == 0 || value.sign == 0) { return ZERO; } int[] aMag = this.sign > 0 ? this.magnitude : add(ONE).magnitude; int[] bMag = value.sign > 0 ? value.magnitude : value.add(ONE).magnitude; boolean resultNeg = sign < 0 && value.sign < 0; int resultLength = Math.max(aMag.length, bMag.length); int[] resultMag = new int[resultLength]; int aStart = resultMag.length - aMag.length; int bStart = resultMag.length - bMag.length; for (int i = 0; i < resultMag.length; ++i) { int aWord = i >= aStart ? aMag[i - aStart] : 0; int bWord = i >= bStart ? bMag[i - bStart] : 0; if (this.sign < 0) { aWord = ~aWord; } if (value.sign < 0) { bWord = ~bWord; } resultMag[i] = aWord & bWord; if (resultNeg) { resultMag[i] = ~resultMag[i]; } } BigInteger result = new BigInteger(1, resultMag); // TODO Optimise this case if (resultNeg) { result = result.not(); } return result; } public BigInteger andNot( BigInteger value) { return and(value.not()); } public int bitCount() { if (nBits == -1) { if (sign < 0) { // TODO Optimise this case nBits = not().bitCount(); } else { int sum = 0; for (int i = 0; i < magnitude.length; i++) { sum += bitCounts[magnitude[i] & 0xff]; sum += bitCounts[(magnitude[i] >> 8) & 0xff]; sum += bitCounts[(magnitude[i] >> 16) & 0xff]; sum += bitCounts[(magnitude[i] >> 24) & 0xff]; } nBits = sum; } } return nBits; } private static int calcBitLength(int sign, int indx, int[] mag) { if (mag.length == 0) { return 0; } while (indx != mag.length && mag[indx] == 0) { indx++; } if (indx == mag.length) { return 0; } // bit length for everything after the first int int bitLength = 32 * ((mag.length - indx) - 1); // and determine bitlength of first int bitLength += bitLen(mag[indx]); if (sign < 0) { // Check if magnitude is a power of two boolean pow2 = ((bitCounts[mag[indx] & 0xff]) + (bitCounts[(mag[indx] >> 8) & 0xff]) + (bitCounts[(mag[indx] >> 16) & 0xff]) + (bitCounts[(mag[indx] >> 24) & 0xff])) == 1; for (int i = indx + 1; i < mag.length && pow2; i++) { pow2 = (mag[i] == 0); } bitLength -= (pow2 ? 1 : 0); } return bitLength; } public int bitLength() { if (nBitLength == -1) { if (sign == 0) { nBitLength = 0; } else { nBitLength = calcBitLength(sign, 0, magnitude); } } return nBitLength; } // // bitLen(value) is the number of bits in value. // private static int bitLen(int w) { int t = w >>> 24; if (t != 0) { return 24 + bitLengths[t]; } t = w >>> 16; if (t != 0) { return 16 + bitLengths[t]; } t = w >>> 8; if (t != 0) { return 8 + bitLengths[t]; } return bitLengths[w]; } private boolean quickPow2Check() { return sign > 0 && nBits == 1; } public int compareTo(Object o) { return compareTo((BigInteger)o); } /** * unsigned comparison on two arrays - note the arrays may * start with leading zeros. */ private static int compareTo(int xIndx, int[] x, int yIndx, int[] y) { while (xIndx != x.length && x[xIndx] == 0) { xIndx++; } while (yIndx != y.length && y[yIndx] == 0) { yIndx++; } return compareNoLeadingZeroes(xIndx, x, yIndx, y); } private static int compareNoLeadingZeroes(int xIndx, int[] x, int yIndx, int[] y) { int diff = (x.length - y.length) - (xIndx - yIndx); if (diff != 0) { return diff < 0 ? -1 : 1; } // lengths of magnitudes the same, test the magnitude values while (xIndx < x.length) { int v1 = x[xIndx++]; int v2 = y[yIndx++]; if (v1 != v2) { return (v1 ^ Integer.MIN_VALUE) < (v2 ^ Integer.MIN_VALUE) ? -1 : 1; } } return 0; } public int compareTo(BigInteger val) { if (sign < val.sign) return -1; if (sign > val.sign) return 1; if (sign == 0) return 0; return sign * compareTo(0, magnitude, 0, val.magnitude); } /** * return z = x / y - done in place (z value preserved, x contains the * remainder) */ private int[] divide(int[] x, int[] y) { int xyCmp = compareTo(0, x, 0, y); int[] count; if (xyCmp > 0) { int[] c; int shift = calcBitLength(1, 0, x) - calcBitLength(1, 0, y); if (shift > 1) { c = shiftLeft(y, shift - 1); count = shiftLeft(ONE.magnitude, shift - 1); if (shift % 32 == 0) { // Special case where the shift is the size of an int. int countSpecial[] = new int[shift / 32 + 1]; System.arraycopy(count, 0, countSpecial, 1, countSpecial.length - 1); countSpecial[0] = 0; count = countSpecial; } } else { c = new int[x.length]; count = new int[1]; System.arraycopy(y, 0, c, c.length - y.length, y.length); count[0] = 1; } int[] iCount = new int[count.length]; subtract(0, x, 0, c); System.arraycopy(count, 0, iCount, 0, count.length); int xStart = 0; int cStart = 0; int iCountStart = 0; for (; ; ) { int cmp = compareTo(xStart, x, cStart, c); while (cmp >= 0) { subtract(xStart, x, cStart, c); add(count, iCount); cmp = compareTo(xStart, x, cStart, c); } xyCmp = compareTo(xStart, x, 0, y); if (xyCmp > 0) { if (x[xStart] == 0) { xStart++; } shift = calcBitLength(1, cStart, c) - calcBitLength(1, xStart, x); if (shift == 0) { shiftRightOneInPlace(cStart, c); shiftRightOneInPlace(iCountStart, iCount); } else { shiftRightInPlace(cStart, c, shift); shiftRightInPlace(iCountStart, iCount, shift); } if (c[cStart] == 0) { cStart++; } if (iCount[iCountStart] == 0) { iCountStart++; } } else if (xyCmp == 0) { add(count, ONE.magnitude); for (int i = xStart; i != x.length; i++) { x[i] = 0; } break; } else { break; } } } else if (xyCmp == 0) { count = new int[1]; count[0] = 1; Arrays.fill(x, 0); } else { count = new int[1]; count[0] = 0; } return count; } public BigInteger divide(BigInteger val) throws ArithmeticException { if (val.sign == 0) { throw new ArithmeticException("Divide by zero"); } if (sign == 0) { return BigInteger.ZERO; } if (val.compareTo(BigInteger.ONE) == 0) { return this; } int[] mag = new int[this.magnitude.length]; System.arraycopy(this.magnitude, 0, mag, 0, mag.length); return new BigInteger(this.sign * val.sign, divide(mag, val.magnitude)); } public BigInteger[] divideAndRemainder(BigInteger val) throws ArithmeticException { if (val.sign == 0) { throw new ArithmeticException("Divide by zero"); } BigInteger biggies[] = new BigInteger[2]; if (sign == 0) { biggies[0] = biggies[1] = BigInteger.ZERO; return biggies; } if (val.compareTo(BigInteger.ONE) == 0) { biggies[0] = this; biggies[1] = BigInteger.ZERO; return biggies; } int[] remainder = new int[this.magnitude.length]; System.arraycopy(this.magnitude, 0, remainder, 0, remainder.length); int[] quotient = divide(remainder, val.magnitude); biggies[0] = new BigInteger(this.sign * val.sign, quotient); biggies[1] = new BigInteger(this.sign, remainder); return biggies; } public boolean equals(Object val) { if (val == this) return true; if (!(val instanceof BigInteger)) return false; BigInteger biggie = (BigInteger)val; return sign == biggie.sign && isEqualMagnitude(biggie); } private boolean isEqualMagnitude(BigInteger x) { if (magnitude.length != x.magnitude.length) { return false; } for (int i = 0; i < magnitude.length; i++) { if (magnitude[i] != x.magnitude[i]) { return false; } } return true; } public BigInteger gcd(BigInteger val) { if (val.sign == 0) return this.abs(); else if (sign == 0) return val.abs(); BigInteger r; BigInteger u = this; BigInteger v = val; while (v.sign != 0) { r = u.mod(v); u = v; v = r; } return u; } public int hashCode() { int hc = magnitude.length; if (magnitude.length > 0) { hc ^= magnitude[0]; if (magnitude.length > 1) { hc ^= magnitude[magnitude.length - 1]; } } return sign < 0 ? ~hc : hc; } public int intValue() { if (sign == 0) { return 0; } int n = magnitude.length; int val = magnitude[n - 1]; return sign < 0 ? -val : val; } public byte byteValue() { return (byte)intValue(); } /** * return whether or not a BigInteger is probably prime with a * probability of 1 - (1/2)**certainty. *

* From Knuth Vol 2, pg 395. */ public boolean isProbablePrime(int certainty) { if (certainty <= 0) return true; if (sign == 0) return false; BigInteger n = this.abs(); if (!n.testBit(0)) return n.equals(TWO); if (n.equals(ONE)) return false; // Try to reduce the penalty for really small numbers int numLists = Math.min(n.bitLength() - 1, primeLists.length); for (int i = 0; i < numLists; ++i) { int test = n.remainder(primeProducts[i]); int[] primeList = primeLists[i]; for (int j = 0; j < primeList.length; ++j) { int prime = primeList[j]; int qRem = test % prime; if (qRem == 0) { // We may find small numbers in the list return n.bitLength() < 16 && n.intValue() == prime; } } } // // let n = 1 + 2^kq // int s = n.getLowestSetBitMaskFirst(-1 << 1); BigInteger r = n.shiftRight(s); Random random = new Random(); // NOTE: Avoid conversion to/from Montgomery form and check for R/-R as result instead BigInteger montRadix = ONE.shiftLeft(32 * n.magnitude.length).remainder(n); BigInteger minusMontRadix = n.subtract(montRadix); do { BigInteger a; do { a = new BigInteger(n.bitLength(), random); } while (a.sign == 0 || a.compareTo(n) >= 0 || a.isEqualMagnitude(montRadix) || a.isEqualMagnitude(minusMontRadix)); BigInteger y = modPowMonty(a, r, n, false); if (!y.equals(montRadix)) { int j = 0; while (!y.equals(minusMontRadix)) { if (++j == s) { return false; } y = modPowMonty(y, TWO, n, false); if (y.equals(montRadix)) { return false; } } } certainty -= 2; // composites pass for only 1/4 possible 'a' } while (certainty > 0); return true; } public long longValue() { if (sign == 0) { return 0; } int n = magnitude.length; long val = magnitude[n - 1] & IMASK; if (n > 1) { val |= (magnitude[n - 2] & IMASK) << 32; } return sign < 0 ? -val : val; } public BigInteger max(BigInteger val) { return (compareTo(val) > 0) ? this : val; } public BigInteger min(BigInteger val) { return (compareTo(val) < 0) ? this : val; } public BigInteger mod(BigInteger m) throws ArithmeticException { if (m.sign <= 0) { throw new ArithmeticException("BigInteger: modulus is not positive"); } BigInteger biggie = this.remainder(m); return (biggie.sign >= 0 ? biggie : biggie.add(m)); } public BigInteger modInverse(BigInteger m) throws ArithmeticException { if (m.sign < 1) { throw new ArithmeticException("Modulus must be positive"); } if (m.quickPow2Check()) { return modInversePow2(m); } BigInteger d = this.remainder(m); BigInteger x = new BigInteger(); BigInteger gcd = BigInteger.extEuclid(d, m, x, null); if (!gcd.equals(BigInteger.ONE)) { throw new ArithmeticException("Numbers not relatively prime."); } if (x.compareTo(BigInteger.ZERO) < 0) { x = x.add(m); } return x; } private BigInteger modInversePow2(BigInteger m) { // assert m.signum() > 0; // assert m.bitCount() == 1; if (!testBit(0)) { throw new ArithmeticException("Numbers not relatively prime."); } int pow = m.bitLength() - 1; if (pow <= 64) { long inv = modInverse64(longValue()); if (pow < 64) { inv &= (m.longValue() - 1); } return BigInteger.valueOf(inv); } BigInteger d = this.remainder(m); BigInteger x = d; int bitsCorrect = 3; while (bitsCorrect < pow) { BigInteger t = x.multiply(d).remainder(m); x = x.multiply(TWO.subtract(t)).remainder(m); bitsCorrect <<= 1; } if (x.sign < 0) { x = x.add(m); } return x; } private static int modInverse32(int d) { // Newton-Raphson division (roughly) int x = d; // d.x == 1 mod 2**3 x *= 2 - d * x; // d.x == 1 mod 2**6 x *= 2 - d * x; // d.x == 1 mod 2**12 x *= 2 - d * x; // d.x == 1 mod 2**24 x *= 2 - d * x; // d.x == 1 mod 2**48 // assert d * x == 1; return x; } private static long modInverse64(long d) { // Newton-Raphson division (roughly) long x = d; // d.x == 1 mod 2**3 x *= 2 - d * x; // d.x == 1 mod 2**6 x *= 2 - d * x; // d.x == 1 mod 2**12 x *= 2 - d * x; // d.x == 1 mod 2**24 x *= 2 - d * x; // d.x == 1 mod 2**48 x *= 2 - d * x; // d.x == 1 mod 2**96 // assert d * x == 1L; return x; } /** * Calculate the numbers u1, u2, and u3 such that: * * u1 * a + u2 * b = u3 * * where u3 is the greatest common divider of a and b. * a and b using the extended Euclid algorithm (refer p. 323 * of The Art of Computer Programming vol 2, 2nd ed). * This also seems to have the side effect of calculating * some form of multiplicative inverse. * * @param a First number to calculate gcd for * @param b Second number to calculate gcd for * @param u1Out the return object for the u1 value * @param u2Out the return object for the u2 value * @return The greatest common divisor of a and b */ private static BigInteger extEuclid(BigInteger a, BigInteger b, BigInteger u1Out, BigInteger u2Out) { BigInteger u1 = BigInteger.ONE; BigInteger u3 = a; BigInteger v1 = BigInteger.ZERO; BigInteger v3 = b; while (v3.sign > 0) { BigInteger[] q = u3.divideAndRemainder(v3); BigInteger tn = u1.subtract(v1.multiply(q[0])); u1 = v1; v1 = tn; u3 = v3; v3 = q[1]; } if (u1Out != null) { u1Out.sign = u1.sign; u1Out.magnitude = u1.magnitude; } if (u2Out != null) { BigInteger res = u3.subtract(u1.multiply(a)).divide(b); u2Out.sign = res.sign; u2Out.magnitude = res.magnitude; } return u3; } /** * zero out the array x */ private static void zero(int[] x) { for (int i = 0; i != x.length; i++) { x[i] = 0; } } public BigInteger modPow(BigInteger e, BigInteger m) { if (m.sign < 1) { throw new ArithmeticException("Modulus must be positive"); } if (m.equals(ONE)) { return ZERO; } if (e.sign == 0) { return ONE; } if (sign == 0) { return ZERO; } boolean negExp = e.sign < 0; if (negExp) { e = e.negate(); } BigInteger result = this.mod(m); if (!e.equals(ONE)) { if ((m.magnitude[m.magnitude.length - 1] & 1) == 0) { result = modPowBarrett(result, e, m); } else { result = modPowMonty(result, e, m, true); } } if (negExp) { result = result.modInverse(m); } return result; } private static BigInteger modPowBarrett(BigInteger b, BigInteger e, BigInteger m) { int k = m.magnitude.length; BigInteger mr = ONE.shiftLeft((k + 1) << 5); BigInteger yu = ONE.shiftLeft(k << 6).divide(m); // Sliding window from MSW to LSW int extraBits = 0, expLength = e.bitLength(); while (expLength > EXP_WINDOW_THRESHOLDS[extraBits]) { ++extraBits; } int numPowers = 1 << extraBits; BigInteger[] oddPowers = new BigInteger[numPowers]; oddPowers[0] = b; BigInteger b2 = reduceBarrett(b.square(), m, mr, yu); for (int i = 1; i < numPowers; ++i) { oddPowers[i] = reduceBarrett(oddPowers[i - 1].multiply(b2), m, mr, yu); } int[] windowList = getWindowList(e.magnitude, extraBits); // assert windowList.size() > 0; int window = windowList[0]; int mult = window & 0xFF, lastZeroes = window >>> 8; BigInteger y; if (mult == 1) { y = b2; --lastZeroes; } else { y = oddPowers[mult >>> 1]; } int windowPos = 1; while ((window = windowList[windowPos++]) != -1) { mult = window & 0xFF; int bits = lastZeroes + bitLengths[mult]; for (int j = 0; j < bits; ++j) { y = reduceBarrett(y.square(), m, mr, yu); } y = reduceBarrett(y.multiply(oddPowers[mult >>> 1]), m, mr, yu); lastZeroes = window >>> 8; } for (int i = 0; i < lastZeroes; ++i) { y = reduceBarrett(y.square(), m, mr, yu); } return y; } private static BigInteger reduceBarrett(BigInteger x, BigInteger m, BigInteger mr, BigInteger yu) { int xLen = x.bitLength(), mLen = m.bitLength(); if (xLen < mLen) { return x; } if (xLen - mLen > 1) { int k = m.magnitude.length; BigInteger q1 = x.divideWords(k - 1); BigInteger q2 = q1.multiply(yu); // TODO Only need partial multiplication here BigInteger q3 = q2.divideWords(k + 1); BigInteger r1 = x.remainderWords(k + 1); BigInteger r2 = q3.multiply(m); // TODO Only need partial multiplication here BigInteger r3 = r2.remainderWords(k + 1); x = r1.subtract(r3); if (x.sign < 0) { x = x.add(mr); } } while (x.compareTo(m) >= 0) { x = x.subtract(m); } return x; } private static BigInteger modPowMonty(BigInteger b, BigInteger e, BigInteger m, boolean convert) { int n = m.magnitude.length; int powR = 32 * n; boolean smallMontyModulus = m.bitLength() + 2 <= powR; int mDash = m.getMQuote(); // tmp = this * R mod m if (convert) { b = b.shiftLeft(powR).remainder(m); } int[] yAccum = new int[n + 1]; int[] zVal = b.magnitude; // assert zVal.length <= n; if (zVal.length < n) { int[] tmp = new int[n]; System.arraycopy(zVal, 0, tmp, n - zVal.length, zVal.length); zVal = tmp; } // Sliding window from MSW to LSW int extraBits = 0; // Filter the common case of small RSA exponents with few bits set if (e.magnitude.length > 1 || e.bitCount() > 2) { int expLength = e.bitLength(); while (expLength > EXP_WINDOW_THRESHOLDS[extraBits]) { ++extraBits; } } int numPowers = 1 << extraBits; int[][] oddPowers = new int[numPowers][]; oddPowers[0] = zVal; int[] zSquared = Arrays.clone(zVal); squareMonty(yAccum, zSquared, m.magnitude, mDash, smallMontyModulus); for (int i = 1; i < numPowers; ++i) { oddPowers[i] = Arrays.clone(oddPowers[i - 1]); multiplyMonty(yAccum, oddPowers[i], zSquared, m.magnitude, mDash, smallMontyModulus); } int[] windowList = getWindowList(e.magnitude, extraBits); // assert windowList.size() > 0; int window = windowList[0]; int mult = window & 0xFF, lastZeroes = window >>> 8; int[] yVal; if (mult == 1) { yVal = zSquared; --lastZeroes; } else { yVal = Arrays.clone(oddPowers[mult >>> 1]); } int windowPos = 1; while ((window = windowList[windowPos++]) != -1) { mult = window & 0xFF; int bits = lastZeroes + bitLengths[mult]; for (int j = 0; j < bits; ++j) { squareMonty(yAccum, yVal, m.magnitude, mDash, smallMontyModulus); } multiplyMonty(yAccum, yVal, oddPowers[mult >>> 1], m.magnitude, mDash, smallMontyModulus); lastZeroes = window >>> 8; } for (int i = 0; i < lastZeroes; ++i) { squareMonty(yAccum, yVal, m.magnitude, mDash, smallMontyModulus); } if (convert) { // Return y * R^(-1) mod m reduceMonty(yVal, m.magnitude, mDash); } else if (smallMontyModulus && compareTo(0, yVal, 0, m.magnitude) >= 0) { subtract(0, yVal, 0, m.magnitude); } return new BigInteger(1, yVal); } private static int[] getWindowList(int[] mag, int extraBits) { int v = mag[0]; // assert v != 0; int leadingBits = bitLen(v); int resultSize = (((mag.length - 1) << 5) + leadingBits) / (1 + extraBits) + 2; int[] result = new int[resultSize]; int resultPos = 0; int bitPos = 33 - leadingBits; v <<= bitPos; int mult = 1, multLimit = 1 << extraBits; int zeroes = 0; int i = 0; for (; ; ) { for (; bitPos < 32; ++bitPos) { if (mult < multLimit) { mult = (mult << 1) | (v >>> 31); } else if (v < 0) { result[resultPos++] = createWindowEntry(mult, zeroes); mult = 1; zeroes = 0; } else { ++zeroes; } v <<= 1; } if (++i == mag.length) { result[resultPos++] = createWindowEntry(mult, zeroes); break; } v = mag[i]; bitPos = 0; } result[resultPos] = -1; return result; } private static int createWindowEntry(int mult, int zeroes) { while ((mult & 1) == 0) { mult >>>= 1; ++zeroes; } return mult | (zeroes << 8); } /** * return w with w = x * x - w is assumed to have enough space. */ private static int[] square(int[] w, int[] x) { // Note: this method allows w to be only (2 * x.Length - 1) words if result will fit // if (w.length != 2 * x.length) // { // throw new IllegalArgumentException("no I don't think so..."); // } long c; int wBase = w.length - 1; for (int i = x.length - 1; i != 0; --i) { long v = x[i] & IMASK; c = v * v + (w[wBase] & IMASK); w[wBase] = (int)c; c >>>= 32; for (int j = i - 1; j >= 0; --j) { long prod = v * (x[j] & IMASK); c += (w[--wBase] & IMASK) + ((prod << 1) & IMASK); w[wBase] = (int)c; c = (c >>> 32) + (prod >>> 31); } c += w[--wBase] & IMASK; w[wBase] = (int)c; if (--wBase >= 0) { w[wBase] = (int)(c >> 32); } wBase += i; } c = x[0] & IMASK; c = c * c + (w[wBase] & IMASK); w[wBase] = (int)c; if (--wBase >= 0) { w[wBase] += (int)(c >> 32); } return w; } /** * return x with x = y * z - x is assumed to have enough space. */ private static int[] multiply(int[] x, int[] y, int[] z) { int i = z.length; if (i < 1) { return x; } int xBase = x.length - y.length; for (;;) { long a = z[--i] & IMASK; long val = 0; for (int j = y.length - 1; j >= 0; j--) { val += a * (y[j] & IMASK) + (x[xBase + j] & IMASK); x[xBase + j] = (int)val; val >>>= 32; } --xBase; if (i < 1) { if (xBase >= 0) { x[xBase] = (int)val; } break; } x[xBase] = (int)val; } return x; } /** * Calculate mQuote = -m^(-1) mod b with b = 2^32 (32 = word size) */ private int getMQuote() { if (mQuote != 0) { return mQuote; // already calculated } // assert this.sign > 0; int d = -magnitude[magnitude.length - 1]; // assert (d & 1) != 0; return mQuote = modInverse32(d); } private static void reduceMonty(int[] x, int[] m, int mDash) // mDash = -m^(-1) mod b { // NOTE: Not a general purpose reduction (which would allow x up to twice the bitlength of m) // assert x.length == m.length; int n = m.length; for (int i = n - 1; i >= 0; --i) { int x0 = x[n - 1]; long t = (x0 * mDash) & IMASK; long carry = t * (m[n - 1] & IMASK) + (x0 & IMASK); // assert (int)carry == 0; carry >>>= 32; for (int j = n - 2; j >= 0; --j) { carry += t * (m[j] & IMASK) + (x[j] & IMASK); x[j + 1] = (int)carry; carry >>>= 32; } x[0] = (int)carry; // assert carry >>> 32 == 0; } if (compareTo(0, x, 0, m) >= 0) { subtract(0, x, 0, m); } } /** * Montgomery multiplication: a = x * y * R^(-1) mod m *
* Based algorithm 14.36 of Handbook of Applied Cryptography. *
*

  • m, x, y should have length n
  • *
  • a should have length (n + 1)
  • *
  • b = 2^32, R = b^n
  • *
    * The result is put in x *
    * NOTE: the indices of x, y, m, a different in HAC and in Java */ private static void multiplyMonty(int[] a, int[] x, int[] y, int[] m, int mDash, boolean smallMontyModulus) // mDash = -m^(-1) mod b { int n = m.length; long y_0 = y[n - 1] & IMASK; // 1. a = 0 (Notation: a = (a_{n} a_{n-1} ... a_{0})_{b} ) for (int i = 0; i <= n; i++) { a[i] = 0; } // 2. for i from 0 to (n - 1) do the following: for (int i = n; i > 0; i--) { long a0 = a[n] & IMASK; long x_i = x[i - 1] & IMASK; long prod1 = x_i * y_0; long carry = (prod1 & IMASK) + a0; // 2.1 u = ((a[0] + (x[i] * y[0]) * mDash) mod b long u = ((int)carry * mDash) & IMASK; // 2.2 a = (a + x_i * y + u * m) / b long prod2 = u * (m[n - 1] & IMASK); carry += (prod2 & IMASK); // assert (int)carry == 0; carry = (carry >>> 32) + (prod1 >>> 32) + (prod2 >>> 32); for (int j = n - 2; j >= 0; j--) { prod1 = x_i * (y[j] & IMASK); prod2 = u * (m[j] & IMASK); carry += (prod1 & IMASK) + (prod2 & IMASK) + (a[j + 1] & IMASK); a[j + 2] = (int)carry; carry = (carry >>> 32) + (prod1 >>> 32) + (prod2 >>> 32); } carry += (a[0] & IMASK); a[1] = (int)carry; a[0] = (int)(carry >>> 32); } // 3. if x >= m the x = x - m if (!smallMontyModulus && compareTo(0, a, 0, m) >= 0) { subtract(0, a, 0, m); } // put the result in x System.arraycopy(a, 1, x, 0, n); } private static void squareMonty(int[] a, int[] x, int[] m, int mDash, boolean smallMontyModulus) // mDash = -m^(-1) mod b { int n = m.length; long x0 = x[n - 1] & IMASK; { long carry = x0 * x0; long u = ((int)carry * mDash) & IMASK; long prod1, prod2 = u * (m[n - 1] & IMASK); carry += (prod2 & IMASK); // assert (int)carry == 0; carry = (carry >>> 32) + (prod2 >>> 32); // assert carry <= (IMASK << 1); for (int j = n - 2; j >= 0; --j) { prod1 = x0 * (x[j] & IMASK); prod2 = u * (m[j] & IMASK); carry += ((prod1 << 1) & IMASK) + (prod2 & IMASK); a[j + 2] = (int)carry; carry = (carry >>> 32) + (prod1 >>> 31) + (prod2 >>> 32); } a[1] = (int)carry; a[0] = (int)(carry >>> 32); } for (int i = n - 2; i >= 0; --i) { int a0 = a[n]; long u = (a0 * mDash) & IMASK; long carry = u * (m[n - 1] & IMASK) + (a0 & IMASK); // assert (int)carry == 0; carry >>>= 32; for (int j = n - 2; j > i; --j) { carry += u * (m[j] & IMASK) + (a[j + 1] & IMASK); a[j + 2] = (int)carry; carry >>>= 32; } long xi = x[i] & IMASK; { long prod1 = xi * xi; long prod2 = u * (m[i] & IMASK); carry += (prod1 & IMASK) + (prod2 & IMASK) + (a[i + 1] & IMASK); a[i + 2] = (int)carry; carry = (carry >>> 32) + (prod1 >>> 32) + (prod2 >>> 32); } for (int j = i - 1; j >= 0; --j) { long prod1 = xi * (x[j] & IMASK); long prod2 = u * (m[j] & IMASK); carry += ((prod1 << 1) & IMASK) + (prod2 & IMASK) + (a[j + 1] & IMASK); a[j + 2] = (int)carry; carry = (carry >>> 32) + (prod1 >>> 31) + (prod2 >>> 32); } carry += (a[0] & IMASK); a[1] = (int)carry; a[0] = (int)(carry >>> 32); } if (!smallMontyModulus && compareTo(0, a, 0, m) >= 0) { subtract(0, a, 0, m); } System.arraycopy(a, 1, x, 0, n); } public BigInteger multiply(BigInteger val) { if (val == this) return square(); if ((sign & val.sign) == 0) return ZERO; if (val.quickPow2Check()) // val is power of two { BigInteger result = this.shiftLeft(val.abs().bitLength() - 1); return val.sign > 0 ? result : result.negate(); } if (this.quickPow2Check()) // this is power of two { BigInteger result = val.shiftLeft(this.abs().bitLength() - 1); return this.sign > 0 ? result : result.negate(); } int resLength = magnitude.length + val.magnitude.length; int[] res = new int[resLength]; multiply(res, this.magnitude, val.magnitude); int resSign = sign ^ val.sign ^ 1; return new BigInteger(resSign, res); } public BigInteger square() { if (sign == 0) { return ZERO; } if (this.quickPow2Check()) { return shiftLeft(abs().bitLength() - 1); } int resLength = magnitude.length << 1; if ((magnitude[0] >>> 16) == 0) { --resLength; } int[] res = new int[resLength]; square(res, magnitude); return new BigInteger(1, res); } public BigInteger negate() { if (sign == 0) { return this; } return new BigInteger(-sign, magnitude); } public BigInteger not() { return add(ONE).negate(); } public BigInteger pow(int exp) throws ArithmeticException { if (exp <= 0) { if (exp < 0) throw new ArithmeticException("Negative exponent"); return ONE; } if (sign == 0) { return this; } if (quickPow2Check()) { long powOf2 = (long)exp * (bitLength() - 1); if (powOf2 > Integer.MAX_VALUE) { throw new ArithmeticException("Result too large"); } return ONE.shiftLeft((int)powOf2); } BigInteger y = BigInteger.ONE, z = this; while (exp != 0) { if ((exp & 0x1) == 1) { y = y.multiply(z); } exp >>= 1; if (exp != 0) { z = z.multiply(z); } } return y; } public static BigInteger probablePrime( int bitLength, Random random) { return new BigInteger(bitLength, 100, random); } private int remainder(int m) { long acc = 0; for (int pos = 0; pos < magnitude.length; ++pos) { acc = (acc << 32 | ((long)magnitude[pos] & 0xffffffffL)) % m; } return (int) acc; } /** * return x = x % y - done in place (y value preserved) */ private static int[] remainder(int[] x, int[] y) { int xStart = 0; while (xStart < x.length && x[xStart] == 0) { ++xStart; } int yStart = 0; while (yStart < y.length && y[yStart] == 0) { ++yStart; } int xyCmp = compareNoLeadingZeroes(xStart, x, yStart, y); if (xyCmp > 0) { int yBitLength = calcBitLength(1, yStart, y); int xBitLength = calcBitLength(1, xStart, x); int shift = xBitLength - yBitLength; int[] c; int cStart = 0; int cBitLength = yBitLength; if (shift > 0) { c = shiftLeft(y, shift); cBitLength += shift; } else { int len = y.length - yStart; c = new int[len]; System.arraycopy(y, yStart, c, 0, len); } for (;;) { if (cBitLength < xBitLength || compareNoLeadingZeroes(xStart, x, cStart, c) >= 0) { subtract(xStart, x, cStart, c); while (x[xStart] == 0) { if (++xStart == x.length) { return x; } } xyCmp = compareNoLeadingZeroes(xStart, x, yStart, y); if (xyCmp <= 0) { break; } //xBitLength = bitLength(xStart, x); xBitLength = 32 * (x.length - xStart - 1) + bitLen(x[xStart]); } shift = cBitLength - xBitLength; if (shift < 2) { shiftRightOneInPlace(cStart, c); --cBitLength; } else { shiftRightInPlace(cStart, c, shift); cBitLength -= shift; } // cStart = c.length - ((cBitLength + 31) / 32); while (c[cStart] == 0) { ++cStart; } } } if (xyCmp == 0) { for (int i = xStart; i < x.length; ++i) { x[i] = 0; } } return x; } public BigInteger remainder(BigInteger n) throws ArithmeticException { if (n.sign == 0) { throw new ArithmeticException("BigInteger: Divide by zero"); } if (sign == 0) { return BigInteger.ZERO; } // For small values, use fast remainder method if (n.magnitude.length == 1) { int val = n.magnitude[0]; if (val > 0) { if (val == 1) return ZERO; int rem = remainder(val); return rem == 0 ? ZERO : new BigInteger(sign, new int[]{ rem }); } } if (compareTo(0, magnitude, 0, n.magnitude) < 0) return this; int[] res; if (n.quickPow2Check()) // n is power of two { // TODO Move before small values branch above? res = lastNBits(n.abs().bitLength() - 1); } else { res = new int[this.magnitude.length]; System.arraycopy(this.magnitude, 0, res, 0, res.length); res = remainder(res, n.magnitude); } return new BigInteger(sign, res); } private int[] lastNBits( int n) { if (n < 1) { return ZERO_MAGNITUDE; } int numWords = (n + 31) / 32; numWords = Math.min(numWords, this.magnitude.length); int[] result = new int[numWords]; System.arraycopy(this.magnitude, this.magnitude.length - numWords, result, 0, numWords); int excessBits = (numWords << 5) - n; if (excessBits > 0) { result[0] &= (-1 >>> excessBits); } return result; } private BigInteger divideWords(int w) { // assert w >= 0; int n = magnitude.length; if (w >= n) { return ZERO; } int[] mag = new int[n - w]; System.arraycopy(magnitude, 0, mag, 0, n - w); return new BigInteger(sign, mag); } private BigInteger remainderWords(int w) { // assert w >= 0; int n = magnitude.length; if (w >= n) { return this; } int[] mag = new int[w]; System.arraycopy(magnitude, n - w, mag, 0, w); return new BigInteger(sign, mag); } /** * do a left shift - this returns a new array. */ private static int[] shiftLeft(int[] mag, int n) { int nInts = n >>> 5; int nBits = n & 0x1f; int magLen = mag.length; int newMag[] = null; if (nBits == 0) { newMag = new int[magLen + nInts]; System.arraycopy(mag, 0, newMag, 0, magLen); } else { int i = 0; int nBits2 = 32 - nBits; int highBits = mag[0] >>> nBits2; if (highBits != 0) { newMag = new int[magLen + nInts + 1]; newMag[i++] = highBits; } else { newMag = new int[magLen + nInts]; } int m = mag[0]; for (int j = 0; j < magLen - 1; j++) { int next = mag[j + 1]; newMag[i++] = (m << nBits) | (next >>> nBits2); m = next; } newMag[i] = mag[magLen - 1] << nBits; } return newMag; } private static int shiftLeftOneInPlace(int[] x, int carry) { // assert carry == 0 || carry == 1; int pos = x.length; while (--pos >= 0) { int val = x[pos]; x[pos] = (val << 1) | carry; carry = val >>> 31; } return carry; } public BigInteger shiftLeft(int n) { if (sign == 0 || magnitude.length == 0) { return ZERO; } if (n == 0) { return this; } if (n < 0) { return shiftRight( -n); } BigInteger result = new BigInteger(sign, shiftLeft(magnitude, n)); if (this.nBits != -1) { result.nBits = sign > 0 ? this.nBits : this.nBits + n; } if (this.nBitLength != -1) { result.nBitLength = this.nBitLength + n; } return result; } /** * do a right shift - this does it in place. */ private static void shiftRightInPlace(int start, int[] mag, int n) { int nInts = (n >>> 5) + start; int nBits = n & 0x1f; int magEnd = mag.length - 1; if (nInts != start) { int delta = (nInts - start); for (int i = magEnd; i >= nInts; i--) { mag[i] = mag[i - delta]; } for (int i = nInts - 1; i >= start; i--) { mag[i] = 0; } } if (nBits != 0) { int nBits2 = 32 - nBits; int m = mag[magEnd]; for (int i = magEnd; i >= nInts + 1; i--) { int next = mag[i - 1]; mag[i] = (m >>> nBits) | (next << nBits2); m = next; } mag[nInts] >>>= nBits; } } /** * do a right shift by one - this does it in place. */ private static void shiftRightOneInPlace(int start, int[] mag) { int magEnd = mag.length - 1; int m = mag[magEnd]; for (int i = magEnd; i > start; i--) { int next = mag[i - 1]; mag[i] = (m >>> 1) | (next << 31); m = next; } mag[start] >>>= 1; } public BigInteger shiftRight(int n) { if (n == 0) { return this; } if (n < 0) { return shiftLeft( -n); } if (n >= bitLength()) { return (this.sign < 0 ? valueOf( -1) : BigInteger.ZERO); } int[] res = new int[this.magnitude.length]; System.arraycopy(this.magnitude, 0, res, 0, res.length); shiftRightInPlace(0, res, n); return new BigInteger(this.sign, res); // TODO Port C# version's optimisations... } public int signum() { return sign; } /** * returns x = x - y - we assume x is >= y */ private static int[] subtract(int xStart, int[] x, int yStart, int[] y) { int iT = x.length; int iV = y.length; long m; int borrow = 0; do { m = ((long)x[--iT] & IMASK) - ((long)y[--iV] & IMASK) + borrow; x[iT] = (int)m; // borrow = (m < 0) ? -1 : 0; borrow = (int)(m >> 63); } while (iV > yStart); if (borrow != 0) { while (--x[--iT] == -1) { } } return x; } public BigInteger subtract(BigInteger val) { if (val.sign == 0 || val.magnitude.length == 0) { return this; } if (sign == 0 || magnitude.length == 0) { return val.negate(); } if (this.sign != val.sign) { return this.add(val.negate()); } int compare = compareTo(0, magnitude, 0, val.magnitude); if (compare == 0) { return ZERO; } BigInteger bigun, littlun; if (compare < 0) { bigun = val; littlun = this; } else { bigun = this; littlun = val; } int res[] = new int[bigun.magnitude.length]; System.arraycopy(bigun.magnitude, 0, res, 0, res.length); return new BigInteger(this.sign * compare, subtract(0, res, 0, littlun.magnitude)); } public byte[] toByteArray() { if (sign == 0) { return new byte[1]; } int bitLength = bitLength(); byte[] bytes = new byte[bitLength / 8 + 1]; int magIndex = magnitude.length; int bytesIndex = bytes.length; if (sign > 0) { while (magIndex > 1) { int mag = magnitude[--magIndex]; bytes[--bytesIndex] = (byte) mag; bytes[--bytesIndex] = (byte)(mag >>> 8); bytes[--bytesIndex] = (byte)(mag >>> 16); bytes[--bytesIndex] = (byte)(mag >>> 24); } int lastMag = magnitude[0]; while ((lastMag & 0xFFFFFF00) != 0) { bytes[--bytesIndex] = (byte) lastMag; lastMag >>>= 8; } bytes[--bytesIndex] = (byte) lastMag; } else { boolean carry = true; while (magIndex > 1) { int mag = ~magnitude[--magIndex]; if (carry) { carry = (++mag == 0); } bytes[--bytesIndex] = (byte) mag; bytes[--bytesIndex] = (byte)(mag >>> 8); bytes[--bytesIndex] = (byte)(mag >>> 16); bytes[--bytesIndex] = (byte)(mag >>> 24); } int lastMag = magnitude[0]; if (carry) { // Never wraps because magnitude[0] != 0 --lastMag; } while ((lastMag & 0xFFFFFF00) != 0) { bytes[--bytesIndex] = (byte) ~lastMag; lastMag >>>= 8; } bytes[--bytesIndex] = (byte) ~lastMag; if (bytesIndex > 0) { bytes[--bytesIndex] = (byte)0xFF; } } return bytes; } public BigInteger xor(BigInteger val) { if (this.sign == 0) { return val; } if (val.sign == 0) { return this; } int[] aMag = this.sign > 0 ? this.magnitude : this.add(ONE).magnitude; int[] bMag = val.sign > 0 ? val.magnitude : val.add(ONE).magnitude; boolean resultNeg = (sign < 0 && val.sign >= 0) || (sign >= 0 && val.sign < 0); int resultLength = Math.max(aMag.length, bMag.length); int[] resultMag = new int[resultLength]; int aStart = resultMag.length - aMag.length; int bStart = resultMag.length - bMag.length; for (int i = 0; i < resultMag.length; ++i) { int aWord = i >= aStart ? aMag[i - aStart] : 0; int bWord = i >= bStart ? bMag[i - bStart] : 0; if (this.sign < 0) { aWord = ~aWord; } if (val.sign < 0) { bWord = ~bWord; } resultMag[i] = aWord ^ bWord; if (resultNeg) { resultMag[i] = ~resultMag[i]; } } BigInteger result = new BigInteger(1, resultMag); if (resultNeg) { result = result.not(); } return result; } public BigInteger or( BigInteger value) { if (this.sign == 0) { return value; } if (value.sign == 0) { return this; } int[] aMag = this.sign > 0 ? this.magnitude : this.add(ONE).magnitude; int[] bMag = value.sign > 0 ? value.magnitude : value.add(ONE).magnitude; boolean resultNeg = sign < 0 || value.sign < 0; int resultLength = Math.max(aMag.length, bMag.length); int[] resultMag = new int[resultLength]; int aStart = resultMag.length - aMag.length; int bStart = resultMag.length - bMag.length; for (int i = 0; i < resultMag.length; ++i) { int aWord = i >= aStart ? aMag[i - aStart] : 0; int bWord = i >= bStart ? bMag[i - bStart] : 0; if (this.sign < 0) { aWord = ~aWord; } if (value.sign < 0) { bWord = ~bWord; } resultMag[i] = aWord | bWord; if (resultNeg) { resultMag[i] = ~resultMag[i]; } } BigInteger result = new BigInteger(1, resultMag); if (resultNeg) { result = result.not(); } return result; } public BigInteger setBit(int n) throws ArithmeticException { if (n < 0) { throw new ArithmeticException("Bit address less than zero"); } if (testBit(n)) { return this; } // TODO Handle negative values and zero if (sign > 0 && n < (bitLength() - 1)) { return flipExistingBit(n); } return or(ONE.shiftLeft(n)); } public BigInteger clearBit(int n) throws ArithmeticException { if (n < 0) { throw new ArithmeticException("Bit address less than zero"); } if (!testBit(n)) { return this; } // TODO Handle negative values if (sign > 0 && n < (bitLength() - 1)) { return flipExistingBit(n); } return andNot(ONE.shiftLeft(n)); } public BigInteger flipBit(int n) throws ArithmeticException { if (n < 0) { throw new ArithmeticException("Bit address less than zero"); } // TODO Handle negative values and zero if (sign > 0 && n < (bitLength() - 1)) { return flipExistingBit(n); } return xor(ONE.shiftLeft(n)); } private BigInteger flipExistingBit(int n) { int[] mag = new int[this.magnitude.length]; System.arraycopy(this.magnitude, 0, mag, 0, mag.length); mag[mag.length - 1 - (n >>> 5)] ^= (1 << (n & 31)); // Flip 0 bit to 1 //mag[mag.Length - 1 - (n / 32)] |= (1 << (n % 32)); return new BigInteger(this.sign, mag); } public String toString() { return toString(10); } public String toString(int rdx) { if (magnitude == null) { return "null"; } if (sign == 0) { return "0"; } if (rdx < Character.MIN_RADIX || rdx > Character.MAX_RADIX) { rdx = 10; } // NOTE: This *should* be unnecessary, since the magnitude *should* never have leading zero digits int firstNonZero = 0; while (firstNonZero < magnitude.length) { if (magnitude[firstNonZero] != 0) { break; } ++firstNonZero; } if (firstNonZero == magnitude.length) { return "0"; } StringBuffer sb = new StringBuffer(); if (sign == -1) { sb.append('-'); } switch (rdx) { case 2: { int pos = firstNonZero; sb.append(Integer.toBinaryString(magnitude[pos])); while (++pos < magnitude.length) { appendZeroExtendedString(sb, Integer.toBinaryString(magnitude[pos]), 32); } break; } case 4: { int pos = firstNonZero; int mag = magnitude[pos]; if (mag < 0) { sb.append(Integer.toString(mag >>> 30, 4)); mag &= (1 << 30) - 1; appendZeroExtendedString(sb, Integer.toString(mag, 4), 15); } else { sb.append(Integer.toString(mag, 4)); } int mask = (1 << 16) - 1; while (++pos < magnitude.length) { mag = magnitude[pos]; appendZeroExtendedString(sb, Integer.toString(mag >>> 16, 4), 8); appendZeroExtendedString(sb, Integer.toString(mag & mask, 4), 8); } break; } case 8: { long mask = (1L << 63) - 1; BigInteger u = this.abs(); int bits = u.bitLength(); Stack S = new Stack(); while (bits > 63) { S.push(Long.toString((u.longValue() & mask),8)); u = u.shiftRight(63); bits -= 63; } sb.append(Long.toString(u.longValue(), 8)); while (!S.empty()) { appendZeroExtendedString(sb, (String)S.pop(), 21); } break; } case 16: { int pos = firstNonZero; sb.append(Integer.toHexString(magnitude[pos])); while (++pos < magnitude.length) { appendZeroExtendedString(sb, Integer.toHexString(magnitude[pos]), 8); } break; } default: { BigInteger q = this.abs(); if (q.bitLength() < 64) { sb.append(Long.toString(q.longValue(), rdx)); break; } // Based on algorithm 1a from chapter 4.4 in Seminumerical Algorithms (Knuth) // Work out the largest power of 'rdx' that is a positive 64-bit integer // TODO possibly cache power/exponent against radix? long limit = Long.MAX_VALUE / rdx; long power = rdx; int exponent = 1; while (power <= limit) { power *= rdx; ++exponent; } BigInteger bigPower = BigInteger.valueOf(power); Stack S = new Stack(); while (q.compareTo(bigPower) >= 0) { BigInteger[] qr = q.divideAndRemainder(bigPower); S.push(Long.toString(qr[1].longValue(), rdx)); q = qr[0]; } sb.append(Long.toString(q.longValue(), rdx)); while (!S.empty()) { appendZeroExtendedString(sb, (String)S.pop(), exponent); } break; } } return sb.toString(); } private static void appendZeroExtendedString(StringBuffer sb, String s, int minLength) { for (int len = s.length(); len < minLength; ++len) { sb.append('0'); } sb.append(s); } public static BigInteger valueOf(long val) { if (val >= 0 && val < SMALL_CONSTANTS.length) { return SMALL_CONSTANTS[(int)val]; } return createValueOf(val); } private static BigInteger createValueOf(long val) { if (val < 0) { if (val == Long.MIN_VALUE) { return valueOf(~val).not(); } return valueOf(-val).negate(); } // store val into a byte array byte[] b = new byte[8]; for (int i = 0; i < 8; i++) { b[7 - i] = (byte)val; val >>= 8; } return new BigInteger(b); } public int getLowestSetBit() { if (this.sign == 0) { return -1; } return getLowestSetBitMaskFirst(-1); } private int getLowestSetBitMaskFirst(int firstWordMask) { int w = magnitude.length, offset = 0; int word = magnitude[--w] & firstWordMask; // assert magnitude[0] != 0; while (word == 0) { word = magnitude[--w]; offset += 32; } while ((word & 0xFF) == 0) { word >>>= 8; offset += 8; } while ((word & 1) == 0) { word >>>= 1; ++offset; } return offset; } public boolean testBit(int n) throws ArithmeticException { if (n < 0) { throw new ArithmeticException("Bit position must not be negative"); } if (sign < 0) { return !not().testBit(n); } int wordNum = n / 32; if (wordNum >= magnitude.length) return false; int word = magnitude[magnitude.length - 1 - wordNum]; return ((word >> (n % 32)) & 1) > 0; } } bouncycastle-1.49.orig/jdk1.0/java/security/0000755000175000017500000000000012152033551020205 5ustar ebourgebourgbouncycastle-1.49.orig/jdk1.0/java/security/SecureRandom.java0000644000175000017500000000670510350737002023447 0ustar ebourgebourgpackage java.security; import org.bouncycastle.crypto.digests.SHA1Digest; /** * An implementation of SecureRandom specifically for the * light-weight API, JDK 1.0, and the J2ME. Random generation is * based on the traditional SHA1 with counter. Calling setSeed * will always increase the entropy of the hash. */ public class SecureRandom extends java.util.Random { private static SecureRandom rand = new SecureRandom(); private byte[] seed; private long counter = 1; private SHA1Digest digest = new SHA1Digest(); private byte[] state = new byte[digest.getDigestSize()]; // public constructors public SecureRandom() { super(0); setSeed(System.currentTimeMillis()); } public SecureRandom( byte[] inSeed) { super(0); setSeed(inSeed); } // protected constructors // protected SecureRandom(SecureRandomSpi srs, Provider provider); // public class methods public static SecureRandom getInstance(String algorithm) { return new SecureRandom(); } public static SecureRandom getInstance(String algorithm, String provider) { return new SecureRandom(); } public static byte[] getSeed( int numBytes) { byte[] rv = new byte[numBytes]; rand.setSeed(System.currentTimeMillis()); rand.nextBytes(rv); return rv; } // public instance methods public byte[] generateSeed( int numBytes) { byte[] rv = new byte[numBytes]; nextBytes(rv); return rv; } // public final Provider getProvider(); public void setSeed( byte[] inSeed) { digest.update(inSeed, 0, inSeed.length); } // public methods overriding random public void nextBytes( byte[] bytes) { int stateOff = 0; digest.doFinal(state, 0); for (int i = 0; i != bytes.length; i++) { if (stateOff == state.length) { byte[] b = longToBytes(counter++); digest.update(b, 0, b.length); digest.update(state, 0, state.length); digest.doFinal(state, 0); stateOff = 0; } bytes[i] = state[stateOff++]; } byte[] b = longToBytes(counter++); digest.update(b, 0, b.length); digest.update(state, 0, state.length); } public void setSeed( long rSeed) { if (rSeed != 0) { setSeed(longToBytes(rSeed)); } } private byte[] intBytes = new byte[4]; public int nextInt() { nextBytes(intBytes); int result = 0; for (int i = 0; i < 4; i++) { result = (result << 8) + (intBytes[i] & 0xff); } return result; } protected final int next( int numBits) { int size = (numBits + 7) / 8; byte[] bytes = new byte[size]; nextBytes(bytes); int result = 0; for (int i = 0; i < size; i++) { result = (result << 8) + (bytes[i] & 0xff); } return result & ((1 << numBits) - 1); } private byte[] longBytes = new byte[8]; private byte[] longToBytes( long val) { for (int i = 0; i != 8; i++) { longBytes[i] = (byte)val; val >>>= 8; } return longBytes; } } bouncycastle-1.49.orig/jdk12.xml0000644000175000017500000000264610262753174016105 0ustar ebourgebourg %Common; ]> &Common; bouncycastle-1.49.orig/bc-build.xml0000644000175000017500000012332712151565324016650 0ustar ebourgebourg bouncycastle-1.49.orig/common.xml0000644000175000017500000002070110262753174016452 0ustar ebourgebourg bouncycastle-1.49.orig/jdk11.xml0000644000175000017500000001021710262753174016075 0ustar ebourgebourg %Common; ]> &Common; bouncycastle-1.49.orig/midp.xml0000644000175000017500000002277512062253470016122 0ustar ebourgebourg %Common; ]> &Common; bouncycastle-1.49.orig/lib/0000755000175000017500000000000012152033551015174 5ustar ebourgebourgbouncycastle-1.49.orig/test/0000755000175000017500000000000012152033550015404 5ustar ebourgebourgbouncycastle-1.49.orig/test/jdk1.4/0000755000175000017500000000000012152033550016377 5ustar ebourgebourgbouncycastle-1.49.orig/test/jdk1.4/org/0000755000175000017500000000000012152033550017166 5ustar ebourgebourgbouncycastle-1.49.orig/test/jdk1.4/org/bouncycastle/0000755000175000017500000000000012152033550021661 5ustar ebourgebourgbouncycastle-1.49.orig/test/jdk1.4/org/bouncycastle/asn1/0000755000175000017500000000000012152033550022523 5ustar ebourgebourgbouncycastle-1.49.orig/test/jdk1.4/org/bouncycastle/asn1/test/0000755000175000017500000000000012152033550023502 5ustar ebourgebourgbouncycastle-1.49.orig/test/jdk1.4/org/bouncycastle/asn1/test/AllTests.java0000644000175000017500000000206011725522364026111 0ustar ebourgebourgpackage org.bouncycastle.asn1.test; import junit.framework.Test; import junit.framework.TestCase; import junit.framework.TestSuite; import org.bouncycastle.util.test.SimpleTestResult; public class AllTests extends TestCase { public void testASN1() { org.bouncycastle.util.test.Test[] tests = RegressionTest.tests; for (int i = 0; i != tests.length; i++) { SimpleTestResult result = (SimpleTestResult)tests[i].perform(); if (!result.isSuccessful()) { fail(result.toString()); } } } public static void main (String[] args) { junit.textui.TestRunner.run(suite()); } public static Test suite() { TestSuite suite = new TestSuite("ASN.1 Tests"); suite.addTestSuite(AllTests.class); suite.addTestSuite(ASN1SequenceParserTest.class); suite.addTestSuite(OctetStringTest.class); suite.addTestSuite(ParseTest.class); return suite; } } bouncycastle-1.49.orig/test/jdk1.4/org/bouncycastle/cert/0000755000175000017500000000000012152033550022616 5ustar ebourgebourgbouncycastle-1.49.orig/test/jdk1.4/org/bouncycastle/cert/test/0000755000175000017500000000000012152033550023575 5ustar ebourgebourgbouncycastle-1.49.orig/test/jdk1.4/org/bouncycastle/cert/test/CertTest.java0000644000175000017500000044335412132650547026223 0ustar ebourgebourgpackage org.bouncycastle.cert.test; import java.io.ByteArrayInputStream; import java.io.IOException; import java.io.UnsupportedEncodingException; import java.math.BigInteger; import java.security.KeyFactory; import java.security.KeyPair; import java.security.KeyPairGenerator; import java.security.KeyStore; import java.security.NoSuchAlgorithmException; import java.security.NoSuchProviderException; import java.security.PrivateKey; import java.security.PublicKey; import java.security.SecureRandom; import java.security.Security; import java.security.Signature; import java.security.cert.CRL; import java.security.cert.Certificate; import java.security.cert.CertificateException; import java.security.cert.CertificateFactory; import java.security.cert.X509CRL; import java.security.cert.X509CRLEntry; import java.security.cert.X509Certificate; import java.security.spec.InvalidKeySpecException; import java.security.spec.RSAPrivateCrtKeySpec; import java.security.spec.RSAPublicKeySpec; import java.util.Collection; import java.util.Date; import java.util.Iterator; import java.util.List; import java.util.Set; import java.util.Vector; import javax.security.auth.x500.X500Principal; import org.bouncycastle.asn1.ASN1Encodable; import org.bouncycastle.asn1.ASN1EncodableVector; import org.bouncycastle.asn1.ASN1Enumerated; import org.bouncycastle.asn1.ASN1ObjectIdentifier; import org.bouncycastle.asn1.ASN1Primitive; import org.bouncycastle.asn1.DEREnumerated; import org.bouncycastle.asn1.DERNull; import org.bouncycastle.asn1.DERObjectIdentifier; import org.bouncycastle.asn1.DEROctetString; import org.bouncycastle.asn1.DERSequence; import org.bouncycastle.asn1.pkcs.PKCSObjectIdentifiers; import org.bouncycastle.asn1.pkcs.RSAPublicKey; import org.bouncycastle.asn1.x500.X500Name; import org.bouncycastle.asn1.x500.X500NameBuilder; import org.bouncycastle.asn1.x500.style.BCStyle; import org.bouncycastle.asn1.x509.AlgorithmIdentifier; import org.bouncycastle.asn1.x509.AuthorityKeyIdentifier; import org.bouncycastle.asn1.x509.CRLReason; import org.bouncycastle.asn1.x509.Extension; import org.bouncycastle.asn1.x509.ExtensionsGenerator; import org.bouncycastle.asn1.x509.GeneralName; import org.bouncycastle.asn1.x509.GeneralNames; import org.bouncycastle.asn1.x509.IssuingDistributionPoint; import org.bouncycastle.asn1.x509.KeyPurposeId; import org.bouncycastle.asn1.x509.SubjectPublicKeyInfo; import org.bouncycastle.asn1.x509.X509CertificateStructure; import org.bouncycastle.asn1.x509.X509Extension; import org.bouncycastle.asn1.x509.X509Extensions; import org.bouncycastle.asn1.x9.X9ObjectIdentifiers; import org.bouncycastle.cert.X509CRLEntryHolder; import org.bouncycastle.cert.X509CRLHolder; import org.bouncycastle.cert.X509CertificateHolder; import org.bouncycastle.cert.X509v1CertificateBuilder; import org.bouncycastle.cert.X509v2CRLBuilder; import org.bouncycastle.cert.X509v3CertificateBuilder; import org.bouncycastle.cert.jcajce.JcaX509CRLConverter; import org.bouncycastle.cert.jcajce.JcaX509CRLHolder; import org.bouncycastle.cert.jcajce.JcaX509CertificateConverter; import org.bouncycastle.cert.jcajce.JcaX509CertificateHolder; import org.bouncycastle.cert.jcajce.JcaX509v1CertificateBuilder; import org.bouncycastle.cert.jcajce.JcaX509v2CRLBuilder; import org.bouncycastle.cert.jcajce.JcaX509v3CertificateBuilder; import org.bouncycastle.crypto.params.RSAKeyParameters; import org.bouncycastle.crypto.params.RSAPrivateCrtKeyParameters; import org.bouncycastle.jce.X509KeyUsage; import org.bouncycastle.jce.X509Principal; import org.bouncycastle.jce.interfaces.ECPointEncoder; import org.bouncycastle.jce.provider.BouncyCastleProvider; import org.bouncycastle.jce.spec.ECParameterSpec; import org.bouncycastle.jce.spec.ECPrivateKeySpec; import org.bouncycastle.jce.spec.ECPublicKeySpec; import org.bouncycastle.jce.spec.GOST3410ParameterSpec; import org.bouncycastle.math.ec.ECCurve; import org.bouncycastle.operator.ContentSigner; import org.bouncycastle.operator.ContentVerifierProvider; import org.bouncycastle.operator.DefaultDigestAlgorithmIdentifierFinder; import org.bouncycastle.operator.DefaultSignatureAlgorithmIdentifierFinder; import org.bouncycastle.operator.bc.BcRSAContentSignerBuilder; import org.bouncycastle.operator.bc.BcRSAContentVerifierProviderBuilder; import org.bouncycastle.operator.jcajce.JcaContentSignerBuilder; import org.bouncycastle.operator.jcajce.JcaContentVerifierProviderBuilder; import org.bouncycastle.util.encoders.Base64; import org.bouncycastle.util.encoders.Hex; import org.bouncycastle.util.test.SimpleTest; import org.bouncycastle.x509.extension.AuthorityKeyIdentifierStructure; import org.bouncycastle.x509.extension.X509ExtensionUtil; public class CertTest extends SimpleTest { private static final String BC = org.bouncycastle.jce.provider.BouncyCastleProvider.PROVIDER_NAME; // test CA byte[] testCAp12 = Base64.decode( "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" + "HLhcYQcQ1R+RucctAgIEAAAA"); // // server.crt // byte[] cert1 = Base64.decode( "MIIDXjCCAsegAwIBAgIBBzANBgkqhkiG9w0BAQQFADCBtzELMAkGA1UEBhMCQVUx" + "ETAPBgNVBAgTCFZpY3RvcmlhMRgwFgYDVQQHEw9Tb3V0aCBNZWxib3VybmUxGjAY" + "BgNVBAoTEUNvbm5lY3QgNCBQdHkgTHRkMR4wHAYDVQQLExVDZXJ0aWZpY2F0ZSBB" + "dXRob3JpdHkxFTATBgNVBAMTDENvbm5lY3QgNCBDQTEoMCYGCSqGSIb3DQEJARYZ" + "d2VibWFzdGVyQGNvbm5lY3Q0LmNvbS5hdTAeFw0wMDA2MDIwNzU2MjFaFw0wMTA2" + "MDIwNzU2MjFaMIG4MQswCQYDVQQGEwJBVTERMA8GA1UECBMIVmljdG9yaWExGDAW" + "BgNVBAcTD1NvdXRoIE1lbGJvdXJuZTEaMBgGA1UEChMRQ29ubmVjdCA0IFB0eSBM" + "dGQxFzAVBgNVBAsTDldlYnNlcnZlciBUZWFtMR0wGwYDVQQDExR3d3cyLmNvbm5l" + "Y3Q0LmNvbS5hdTEoMCYGCSqGSIb3DQEJARYZd2VibWFzdGVyQGNvbm5lY3Q0LmNv" + "bS5hdTCBnzANBgkqhkiG9w0BAQEFAAOBjQAwgYkCgYEArvDxclKAhyv7Q/Wmr2re" + "Gw4XL9Cnh9e+6VgWy2AWNy/MVeXdlxzd7QAuc1eOWQkGQEiLPy5XQtTY+sBUJ3AO" + "Rvd2fEVJIcjf29ey7bYua9J/vz5MG2KYo9/WCHIwqD9mmG9g0xLcfwq/s8ZJBswE" + "7sb85VU+h94PTvsWOsWuKaECAwEAAaN3MHUwJAYDVR0RBB0wG4EZd2VibWFzdGVy" + "QGNvbm5lY3Q0LmNvbS5hdTA6BglghkgBhvhCAQ0ELRYrbW9kX3NzbCBnZW5lcmF0" + "ZWQgY3VzdG9tIHNlcnZlciBjZXJ0aWZpY2F0ZTARBglghkgBhvhCAQEEBAMCBkAw" + "DQYJKoZIhvcNAQEEBQADgYEAotccfKpwSsIxM1Hae8DR7M/Rw8dg/RqOWx45HNVL" + "iBS4/3N/TO195yeQKbfmzbAA2jbPVvIvGgTxPgO1MP4ZgvgRhasaa0qCJCkWvpM4" + "yQf33vOiYQbpv4rTwzU8AmRlBG45WdjyNIigGV+oRc61aKCTnLq7zB8N3z1TF/bF" + "5/8="); // // ca.crt // byte[] cert2 = Base64.decode( "MIIDbDCCAtWgAwIBAgIBADANBgkqhkiG9w0BAQQFADCBtzELMAkGA1UEBhMCQVUx" + "ETAPBgNVBAgTCFZpY3RvcmlhMRgwFgYDVQQHEw9Tb3V0aCBNZWxib3VybmUxGjAY" + "BgNVBAoTEUNvbm5lY3QgNCBQdHkgTHRkMR4wHAYDVQQLExVDZXJ0aWZpY2F0ZSBB" + "dXRob3JpdHkxFTATBgNVBAMTDENvbm5lY3QgNCBDQTEoMCYGCSqGSIb3DQEJARYZ" + "d2VibWFzdGVyQGNvbm5lY3Q0LmNvbS5hdTAeFw0wMDA2MDIwNzU1MzNaFw0wMTA2" + "MDIwNzU1MzNaMIG3MQswCQYDVQQGEwJBVTERMA8GA1UECBMIVmljdG9yaWExGDAW" + "BgNVBAcTD1NvdXRoIE1lbGJvdXJuZTEaMBgGA1UEChMRQ29ubmVjdCA0IFB0eSBM" + "dGQxHjAcBgNVBAsTFUNlcnRpZmljYXRlIEF1dGhvcml0eTEVMBMGA1UEAxMMQ29u" + "bmVjdCA0IENBMSgwJgYJKoZIhvcNAQkBFhl3ZWJtYXN0ZXJAY29ubmVjdDQuY29t" + "LmF1MIGfMA0GCSqGSIb3DQEBAQUAA4GNADCBiQKBgQDgs5ptNG6Qv1ZpCDuUNGmv" + "rhjqMDPd3ri8JzZNRiiFlBA4e6/ReaO1U8ASewDeQMH6i9R6degFdQRLngbuJP0s" + "xcEE+SksEWNvygfzLwV9J/q+TQDyJYK52utb++lS0b48A1KPLwEsyL6kOAgelbur" + "ukwxowprKUIV7Knf1ajetQIDAQABo4GFMIGCMCQGA1UdEQQdMBuBGXdlYm1hc3Rl" + "ckBjb25uZWN0NC5jb20uYXUwDwYDVR0TBAgwBgEB/wIBADA2BglghkgBhvhCAQ0E" + "KRYnbW9kX3NzbCBnZW5lcmF0ZWQgY3VzdG9tIENBIGNlcnRpZmljYXRlMBEGCWCG" + "SAGG+EIBAQQEAwICBDANBgkqhkiG9w0BAQQFAAOBgQCsGvfdghH8pPhlwm1r3pQk" + "msnLAVIBb01EhbXm2861iXZfWqGQjrGAaA0ZpXNk9oo110yxoqEoSJSzniZa7Xtz" + "soTwNUpE0SLHvWf/SlKdFWlzXA+vOZbzEv4UmjeelekTm7lc01EEa5QRVzOxHFtQ" + "DhkaJ8VqOMajkQFma2r9iA=="); // // testx509.pem // byte[] cert3 = Base64.decode( "MIIBWzCCAQYCARgwDQYJKoZIhvcNAQEEBQAwODELMAkGA1UEBhMCQVUxDDAKBgNV" + "BAgTA1FMRDEbMBkGA1UEAxMSU1NMZWF5L3JzYSB0ZXN0IENBMB4XDTk1MDYxOTIz" + "MzMxMloXDTk1MDcxNzIzMzMxMlowOjELMAkGA1UEBhMCQVUxDDAKBgNVBAgTA1FM" + "RDEdMBsGA1UEAxMUU1NMZWF5L3JzYSB0ZXN0IGNlcnQwXDANBgkqhkiG9w0BAQEF" + "AANLADBIAkEAqtt6qS5GTxVxGZYWa0/4u+IwHf7p2LNZbcPBp9/OfIcYAXBQn8hO" + "/Re1uwLKXdCjIoaGs4DLdG88rkzfyK5dPQIDAQABMAwGCCqGSIb3DQIFBQADQQAE" + "Wc7EcF8po2/ZO6kNCwK/ICH6DobgLekA5lSLr5EvuioZniZp5lFzAw4+YzPQ7XKJ" + "zl9HYIMxATFyqSiD9jsx"); // // v3-cert1.pem // byte[] cert4 = Base64.decode( "MIICjTCCAfigAwIBAgIEMaYgRzALBgkqhkiG9w0BAQQwRTELMAkGA1UEBhMCVVMx" + "NjA0BgNVBAoTLU5hdGlvbmFsIEFlcm9uYXV0aWNzIGFuZCBTcGFjZSBBZG1pbmlz" + "dHJhdGlvbjAmFxE5NjA1MjgxMzQ5MDUrMDgwMBcROTgwNTI4MTM0OTA1KzA4MDAw" + "ZzELMAkGA1UEBhMCVVMxNjA0BgNVBAoTLU5hdGlvbmFsIEFlcm9uYXV0aWNzIGFu" + "ZCBTcGFjZSBBZG1pbmlzdHJhdGlvbjEgMAkGA1UEBRMCMTYwEwYDVQQDEwxTdGV2" + "ZSBTY2hvY2gwWDALBgkqhkiG9w0BAQEDSQAwRgJBALrAwyYdgxmzNP/ts0Uyf6Bp" + "miJYktU/w4NG67ULaN4B5CnEz7k57s9o3YY3LecETgQ5iQHmkwlYDTL2fTgVfw0C" + "AQOjgaswgagwZAYDVR0ZAQH/BFowWDBWMFQxCzAJBgNVBAYTAlVTMTYwNAYDVQQK" + "Ey1OYXRpb25hbCBBZXJvbmF1dGljcyBhbmQgU3BhY2UgQWRtaW5pc3RyYXRpb24x" + "DTALBgNVBAMTBENSTDEwFwYDVR0BAQH/BA0wC4AJODMyOTcwODEwMBgGA1UdAgQR" + "MA8ECTgzMjk3MDgyM4ACBSAwDQYDVR0KBAYwBAMCBkAwCwYJKoZIhvcNAQEEA4GB" + "AH2y1VCEw/A4zaXzSYZJTTUi3uawbbFiS2yxHvgf28+8Js0OHXk1H1w2d6qOHH21" + "X82tZXd/0JtG0g1T9usFFBDvYK8O0ebgz/P5ELJnBL2+atObEuJy1ZZ0pBDWINR3" + "WkDNLCGiTkCKp0F5EWIrVDwh54NNevkCQRZita+z4IBO"); // // v3-cert2.pem // byte[] cert5 = Base64.decode( "MIICiTCCAfKgAwIBAgIEMeZfHzANBgkqhkiG9w0BAQQFADB9MQswCQYDVQQGEwJD" + "YTEPMA0GA1UEBxMGTmVwZWFuMR4wHAYDVQQLExVObyBMaWFiaWxpdHkgQWNjZXB0" + "ZWQxHzAdBgNVBAoTFkZvciBEZW1vIFB1cnBvc2VzIE9ubHkxHDAaBgNVBAMTE0Vu" + "dHJ1c3QgRGVtbyBXZWIgQ0EwHhcNOTYwNzEyMTQyMDE1WhcNOTYxMDEyMTQyMDE1" + "WjB0MSQwIgYJKoZIhvcNAQkBExVjb29rZUBpc3NsLmF0bC5ocC5jb20xCzAJBgNV" + "BAYTAlVTMScwJQYDVQQLEx5IZXdsZXR0IFBhY2thcmQgQ29tcGFueSAoSVNTTCkx" + "FjAUBgNVBAMTDVBhdWwgQS4gQ29va2UwXDANBgkqhkiG9w0BAQEFAANLADBIAkEA" + "6ceSq9a9AU6g+zBwaL/yVmW1/9EE8s5you1mgjHnj0wAILuoB3L6rm6jmFRy7QZT" + "G43IhVZdDua4e+5/n1ZslwIDAQABo2MwYTARBglghkgBhvhCAQEEBAMCB4AwTAYJ" + "YIZIAYb4QgENBD8WPVRoaXMgY2VydGlmaWNhdGUgaXMgb25seSBpbnRlbmRlZCBm" + "b3IgZGVtb25zdHJhdGlvbiBwdXJwb3Nlcy4wDQYJKoZIhvcNAQEEBQADgYEAi8qc" + "F3zfFqy1sV8NhjwLVwOKuSfhR/Z8mbIEUeSTlnH3QbYt3HWZQ+vXI8mvtZoBc2Fz" + "lexKeIkAZXCesqGbs6z6nCt16P6tmdfbZF3I3AWzLquPcOXjPf4HgstkyvVBn0Ap" + "jAFN418KF/Cx4qyHB4cjdvLrRjjQLnb2+ibo7QU="); // // pem encoded pkcs7 // byte[] cert6 = Base64.decode( "MIAGCSqGSIb3DQEHAqCAMIACAQExCzAJBgUrDgMCGgUAMIAGCSqGSIb3DQEHAQAAoIIJbzCCAj0w" + "ggGmAhEAzbp/VvDf5LxU/iKss3KqVTANBgkqhkiG9w0BAQIFADBfMQswCQYDVQQGEwJVUzEXMBUG" + "A1UEChMOVmVyaVNpZ24sIEluYy4xNzA1BgNVBAsTLkNsYXNzIDEgUHVibGljIFByaW1hcnkgQ2Vy" + "dGlmaWNhdGlvbiBBdXRob3JpdHkwHhcNOTYwMTI5MDAwMDAwWhcNMjgwODAxMjM1OTU5WjBfMQsw" + "CQYDVQQGEwJVUzEXMBUGA1UEChMOVmVyaVNpZ24sIEluYy4xNzA1BgNVBAsTLkNsYXNzIDEgUHVi" + "bGljIFByaW1hcnkgQ2VydGlmaWNhdGlvbiBBdXRob3JpdHkwgZ8wDQYJKoZIhvcNAQEBBQADgY0A" + "MIGJAoGBAOUZv22jVmEtmUhx9mfeuY3rt56GgAqRDvo4Ja9GiILlc6igmyRdDR/MZW4MsNBWhBiH" + "mgabEKFz37RYOWtuwfYV1aioP6oSBo0xrH+wNNePNGeICc0UEeJORVZpH3gCgNrcR5EpuzbJY1zF" + "4Ncth3uhtzKwezC6Ki8xqu6jZ9rbAgMBAAEwDQYJKoZIhvcNAQECBQADgYEATD+4i8Zo3+5DMw5d" + "6abLB4RNejP/khv0Nq3YlSI2aBFsfELM85wuxAc/FLAPT/+Qknb54rxK6Y/NoIAK98Up8YIiXbix" + "3YEjo3slFUYweRb46gVLlH8dwhzI47f0EEA8E8NfH1PoSOSGtHuhNbB7Jbq4046rPzidADQAmPPR" + "cZQwggMuMIICl6ADAgECAhEA0nYujRQMPX2yqCVdr+4NdTANBgkqhkiG9w0BAQIFADBfMQswCQYD" + "VQQGEwJVUzEXMBUGA1UEChMOVmVyaVNpZ24sIEluYy4xNzA1BgNVBAsTLkNsYXNzIDEgUHVibGlj" + "IFByaW1hcnkgQ2VydGlmaWNhdGlvbiBBdXRob3JpdHkwHhcNOTgwNTEyMDAwMDAwWhcNMDgwNTEy" + "MjM1OTU5WjCBzDEXMBUGA1UEChMOVmVyaVNpZ24sIEluYy4xHzAdBgNVBAsTFlZlcmlTaWduIFRy" + "dXN0IE5ldHdvcmsxRjBEBgNVBAsTPXd3dy52ZXJpc2lnbi5jb20vcmVwb3NpdG9yeS9SUEEgSW5j" + "b3JwLiBCeSBSZWYuLExJQUIuTFREKGMpOTgxSDBGBgNVBAMTP1ZlcmlTaWduIENsYXNzIDEgQ0Eg" + "SW5kaXZpZHVhbCBTdWJzY3JpYmVyLVBlcnNvbmEgTm90IFZhbGlkYXRlZDCBnzANBgkqhkiG9w0B" + "AQEFAAOBjQAwgYkCgYEAu1pEigQWu1X9A3qKLZRPFXg2uA1Ksm+cVL+86HcqnbnwaLuV2TFBcHqB" + "S7lIE1YtxwjhhEKrwKKSq0RcqkLwgg4C6S/7wju7vsknCl22sDZCM7VuVIhPh0q/Gdr5FegPh7Yc" + "48zGmo5/aiSS4/zgZbqnsX7vyds3ashKyAkG5JkCAwEAAaN8MHowEQYJYIZIAYb4QgEBBAQDAgEG" + "MEcGA1UdIARAMD4wPAYLYIZIAYb4RQEHAQEwLTArBggrBgEFBQcCARYfd3d3LnZlcmlzaWduLmNv" + "bS9yZXBvc2l0b3J5L1JQQTAPBgNVHRMECDAGAQH/AgEAMAsGA1UdDwQEAwIBBjANBgkqhkiG9w0B" + "AQIFAAOBgQCIuDc73dqUNwCtqp/hgQFxHpJqbS/28Z3TymQ43BuYDAeGW4UVag+5SYWklfEXfWe0" + "fy0s3ZpCnsM+tI6q5QsG3vJWKvozx74Z11NMw73I4xe1pElCY+zCphcPXVgaSTyQXFWjZSAA/Rgg" + "5V+CprGoksVYasGNAzzrw80FopCubjCCA/gwggNhoAMCAQICEBbbn/1G1zppD6KsP01bwywwDQYJ" + "KoZIhvcNAQEEBQAwgcwxFzAVBgNVBAoTDlZlcmlTaWduLCBJbmMuMR8wHQYDVQQLExZWZXJpU2ln" + "biBUcnVzdCBOZXR3b3JrMUYwRAYDVQQLEz13d3cudmVyaXNpZ24uY29tL3JlcG9zaXRvcnkvUlBB" + "IEluY29ycC4gQnkgUmVmLixMSUFCLkxURChjKTk4MUgwRgYDVQQDEz9WZXJpU2lnbiBDbGFzcyAx" + "IENBIEluZGl2aWR1YWwgU3Vic2NyaWJlci1QZXJzb25hIE5vdCBWYWxpZGF0ZWQwHhcNMDAxMDAy" + "MDAwMDAwWhcNMDAxMjAxMjM1OTU5WjCCAQcxFzAVBgNVBAoTDlZlcmlTaWduLCBJbmMuMR8wHQYD" + "VQQLExZWZXJpU2lnbiBUcnVzdCBOZXR3b3JrMUYwRAYDVQQLEz13d3cudmVyaXNpZ24uY29tL3Jl" + "cG9zaXRvcnkvUlBBIEluY29ycC4gYnkgUmVmLixMSUFCLkxURChjKTk4MR4wHAYDVQQLExVQZXJz" + "b25hIE5vdCBWYWxpZGF0ZWQxJzAlBgNVBAsTHkRpZ2l0YWwgSUQgQ2xhc3MgMSAtIE1pY3Jvc29m" + "dDETMBEGA1UEAxQKRGF2aWQgUnlhbjElMCMGCSqGSIb3DQEJARYWZGF2aWRAbGl2ZW1lZGlhLmNv" + "bS5hdTCBnzANBgkqhkiG9w0BAQEFAAOBjQAwgYkCgYEAqxBsdeNmSvFqhMNwhQgNzM8mdjX9eSXb" + "DawpHtQHjmh0AKJSa3IwUY0VIsyZHuXWktO/CgaMBVPt6OVf/n0R2sQigMP6Y+PhEiS0vCJBL9aK" + "0+pOo2qXrjVBmq+XuCyPTnc+BOSrU26tJsX0P9BYorwySiEGxGanBNATdVL4NdUCAwEAAaOBnDCB" + "mTAJBgNVHRMEAjAAMEQGA1UdIAQ9MDswOQYLYIZIAYb4RQEHAQgwKjAoBggrBgEFBQcCARYcaHR0" + "cHM6Ly93d3cudmVyaXNpZ24uY29tL3JwYTARBglghkgBhvhCAQEEBAMCB4AwMwYDVR0fBCwwKjAo" + "oCagJIYiaHR0cDovL2NybC52ZXJpc2lnbi5jb20vY2xhc3MxLmNybDANBgkqhkiG9w0BAQQFAAOB" + "gQBC8yIIdVGpFTf8/YiL14cMzcmL0nIRm4kGR3U59z7UtcXlfNXXJ8MyaeI/BnXwG/gD5OKYqW6R" + "yca9vZOxf1uoTBl82gInk865ED3Tej6msCqFzZffnSUQvOIeqLxxDlqYRQ6PmW2nAnZeyjcnbI5Y" + "syQSM2fmo7n6qJFP+GbFezGCAkUwggJBAgEBMIHhMIHMMRcwFQYDVQQKEw5WZXJpU2lnbiwgSW5j" + "LjEfMB0GA1UECxMWVmVyaVNpZ24gVHJ1c3QgTmV0d29yazFGMEQGA1UECxM9d3d3LnZlcmlzaWdu" + "LmNvbS9yZXBvc2l0b3J5L1JQQSBJbmNvcnAuIEJ5IFJlZi4sTElBQi5MVEQoYyk5ODFIMEYGA1UE" + "AxM/VmVyaVNpZ24gQ2xhc3MgMSBDQSBJbmRpdmlkdWFsIFN1YnNjcmliZXItUGVyc29uYSBOb3Qg" + "VmFsaWRhdGVkAhAW25/9Rtc6aQ+irD9NW8MsMAkGBSsOAwIaBQCggbowGAYJKoZIhvcNAQkDMQsG" + "CSqGSIb3DQEHATAcBgkqhkiG9w0BCQUxDxcNMDAxMDAyMTczNTE4WjAjBgkqhkiG9w0BCQQxFgQU" + "gZjSaBEY2oxGvlQUIMnxSXhivK8wWwYJKoZIhvcNAQkPMU4wTDAKBggqhkiG9w0DBzAOBggqhkiG" + "9w0DAgICAIAwDQYIKoZIhvcNAwICAUAwBwYFKw4DAgcwDQYIKoZIhvcNAwICASgwBwYFKw4DAh0w" + "DQYJKoZIhvcNAQEBBQAEgYAzk+PU91/ZFfoiuKOECjxEh9fDYE2jfDCheBIgh5gdcCo+sS1WQs8O" + "HreQ9Nop/JdJv1DQMBK6weNBBDoP0EEkRm1XCC144XhXZC82jBZohYmi2WvDbbC//YN58kRMYMyy" + "srrfn4Z9I+6kTriGXkrpGk9Q0LSGjmG2BIsqiF0dvwAAAAAAAA=="); // // dsaWithSHA1 cert // byte[] cert7 = Base64.decode( "MIIEXAYJKoZIhvcNAQcCoIIETTCCBEkCAQExCzAJBgUrDgMCGgUAMAsGCSqG" + "SIb3DQEHAaCCAsMwggK/MIIB4AIBADCBpwYFKw4DAhswgZ0CQQEkJRHP+mN7" + "d8miwTMN55CUSmo3TO8WGCxgY61TX5k+7NU4XPf1TULjw3GobwaJX13kquPh" + "fVXk+gVy46n4Iw3hAhUBSe/QF4BUj+pJOF9ROBM4u+FEWA8CQQD4mSJbrABj" + "TUWrlnAte8pS22Tq4/FPO7jHSqjijUHfXKTrHL1OEqV3SVWcFy5j/cqBgX/z" + "m8Q12PFp/PjOhh+nMA4xDDAKBgNVBAMTA0lEMzAeFw05NzEwMDEwMDAwMDBa" + "Fw0zODAxMDEwMDAwMDBaMA4xDDAKBgNVBAMTA0lEMzCB8DCBpwYFKw4DAhsw" + "gZ0CQQEkJRHP+mN7d8miwTMN55CUSmo3TO8WGCxgY61TX5k+7NU4XPf1TULj" + "w3GobwaJX13kquPhfVXk+gVy46n4Iw3hAhUBSe/QF4BUj+pJOF9ROBM4u+FE" + "WA8CQQD4mSJbrABjTUWrlnAte8pS22Tq4/FPO7jHSqjijUHfXKTrHL1OEqV3" + "SVWcFy5j/cqBgX/zm8Q12PFp/PjOhh+nA0QAAkEAkYkXLYMtGVGWj9OnzjPn" + "sB9sefSRPrVegZJCZbpW+Iv0/1RP1u04pHG9vtRpIQLjzUiWvLMU9EKQTThc" + "eNMmWDCBpwYFKw4DAhswgZ0CQQEkJRHP+mN7d8miwTMN55CUSmo3TO8WGCxg" + "Y61TX5k+7NU4XPf1TULjw3GobwaJX13kquPhfVXk+gVy46n4Iw3hAhUBSe/Q" + "F4BUj+pJOF9ROBM4u+FEWA8CQQD4mSJbrABjTUWrlnAte8pS22Tq4/FPO7jH" + "SqjijUHfXKTrHL1OEqV3SVWcFy5j/cqBgX/zm8Q12PFp/PjOhh+nAy8AMCwC" + "FBY3dBSdeprGcqpr6wr3xbG+6WW+AhRMm/facKJNxkT3iKgJbp7R8Xd3QTGC" + "AWEwggFdAgEBMBMwDjEMMAoGA1UEAxMDSUQzAgEAMAkGBSsOAwIaBQCgXTAY" + "BgkqhkiG9w0BCQMxCwYJKoZIhvcNAQcBMBwGCSqGSIb3DQEJBTEPFw0wMjA1" + "MjQyMzEzMDdaMCMGCSqGSIb3DQEJBDEWBBS4WMsoJhf7CVbZYCFcjoTRzPkJ" + "xjCBpwYFKw4DAhswgZ0CQQEkJRHP+mN7d8miwTMN55CUSmo3TO8WGCxgY61T" + "X5k+7NU4XPf1TULjw3GobwaJX13kquPhfVXk+gVy46n4Iw3hAhUBSe/QF4BU" + "j+pJOF9ROBM4u+FEWA8CQQD4mSJbrABjTUWrlnAte8pS22Tq4/FPO7jHSqji" + "jUHfXKTrHL1OEqV3SVWcFy5j/cqBgX/zm8Q12PFp/PjOhh+nBC8wLQIVALID" + "dt+MHwawrDrwsO1Z6sXBaaJsAhRaKssrpevmLkbygKPV07XiAKBG02Zvb2Jh" + "cg=="); // // testcrl.pem // byte[] crl1 = Base64.decode( "MIICjTCCAfowDQYJKoZIhvcNAQECBQAwXzELMAkGA1UEBhMCVVMxIDAeBgNVBAoT" + "F1JTQSBEYXRhIFNlY3VyaXR5LCBJbmMuMS4wLAYDVQQLEyVTZWN1cmUgU2VydmVy" + "IENlcnRpZmljYXRpb24gQXV0aG9yaXR5Fw05NTA1MDIwMjEyMjZaFw05NTA2MDEw" + "MDAxNDlaMIIBaDAWAgUCQQAABBcNOTUwMjAxMTcyNDI2WjAWAgUCQQAACRcNOTUw" + "MjEwMDIxNjM5WjAWAgUCQQAADxcNOTUwMjI0MDAxMjQ5WjAWAgUCQQAADBcNOTUw" + "MjI1MDA0NjQ0WjAWAgUCQQAAGxcNOTUwMzEzMTg0MDQ5WjAWAgUCQQAAFhcNOTUw" + "MzE1MTkxNjU0WjAWAgUCQQAAGhcNOTUwMzE1MTk0MDQxWjAWAgUCQQAAHxcNOTUw" + "MzI0MTk0NDMzWjAWAgUCcgAABRcNOTUwMzI5MjAwNzExWjAWAgUCcgAAERcNOTUw" + "MzMwMDIzNDI2WjAWAgUCQQAAIBcNOTUwNDA3MDExMzIxWjAWAgUCcgAAHhcNOTUw" + "NDA4MDAwMjU5WjAWAgUCcgAAQRcNOTUwNDI4MTcxNzI0WjAWAgUCcgAAOBcNOTUw" + "NDI4MTcyNzIxWjAWAgUCcgAATBcNOTUwNTAyMDIxMjI2WjANBgkqhkiG9w0BAQIF" + "AAN+AHqOEJXSDejYy0UwxxrH/9+N2z5xu/if0J6qQmK92W0hW158wpJg+ovV3+wQ" + "wvIEPRL2rocL0tKfAsVq1IawSJzSNgxG0lrcla3MrJBnZ4GaZDu4FutZh72MR3Gt" + "JaAL3iTJHJD55kK2D/VoyY1djlsPuNh6AEgdVwFAyp0v"); // // ecdsa cert with extra octet string. // byte[] oldEcdsa = Base64.decode( "MIICljCCAkCgAwIBAgIBATALBgcqhkjOPQQBBQAwgY8xCzAJBgNVBAYTAkFVMSgwJ" + "gYDVQQKEx9UaGUgTGVnaW9uIG9mIHRoZSBCb3VuY3kgQ2FzdGxlMRIwEAYDVQQHEw" + "lNZWxib3VybmUxETAPBgNVBAgTCFZpY3RvcmlhMS8wLQYJKoZIhvcNAQkBFiBmZWV" + "kYmFjay1jcnlwdG9AYm91bmN5Y2FzdGxlLm9yZzAeFw0wMTEyMDcwMTAwMDRaFw0w" + "MTEyMDcwMTAxNDRaMIGPMQswCQYDVQQGEwJBVTEoMCYGA1UEChMfVGhlIExlZ2lvb" + "iBvZiB0aGUgQm91bmN5IENhc3RsZTESMBAGA1UEBxMJTWVsYm91cm5lMREwDwYDVQ" + "QIEwhWaWN0b3JpYTEvMC0GCSqGSIb3DQEJARYgZmVlZGJhY2stY3J5cHRvQGJvdW5" + "jeWNhc3RsZS5vcmcwgeQwgb0GByqGSM49AgEwgbECAQEwKQYHKoZIzj0BAQIef///" + "////////////f///////gAAAAAAAf///////MEAEHn///////////////3///////" + "4AAAAAAAH///////AQeawFsO9zxiUHQ1lSSFHXKcanbL7J9HTd5YYXClCwKBB8CD/" + "qWPNyogWzMM7hkK+35BcPTWFc9Pyf7vTs8uaqvAh5///////////////9///+eXpq" + "fXZBx+9FSJoiQnQsDIgAEHwJbbcU7xholSP+w9nFHLebJUhqdLSU05lq/y9X+DHAw" + "CwYHKoZIzj0EAQUAA0MAMEACHnz6t4UNoVROp74ma4XNDjjGcjaqiIWPZLK8Bdw3G" + "QIeLZ4j3a6ividZl344UH+UPUE7xJxlYGuy7ejTsqRR"); byte[] uncompressedPtEC = Base64.decode( "MIIDKzCCAsGgAwIBAgICA+kwCwYHKoZIzj0EAQUAMGYxCzAJBgNVBAYTAkpQ" + "MRUwEwYDVQQKEwxuaXRlY2guYWMuanAxDjAMBgNVBAsTBWFpbGFiMQ8wDQYD" + "VQQDEwZ0ZXN0Y2ExHzAdBgkqhkiG9w0BCQEWEHRlc3RjYUBsb2NhbGhvc3Qw" + "HhcNMDExMDEzMTE1MzE3WhcNMjAxMjEyMTE1MzE3WjBmMQswCQYDVQQGEwJK" + "UDEVMBMGA1UEChMMbml0ZWNoLmFjLmpwMQ4wDAYDVQQLEwVhaWxhYjEPMA0G" + "A1UEAxMGdGVzdGNhMR8wHQYJKoZIhvcNAQkBFhB0ZXN0Y2FAbG9jYWxob3N0" + "MIIBczCCARsGByqGSM49AgEwggEOAgEBMDMGByqGSM49AQECKEdYWnajFmnZ" + "tzrukK2XWdle2v+GsD9l1ZiR6g7ozQDbhFH/bBiMDQcwVAQoJ5EQKrI54/CT" + "xOQ2pMsd/fsXD+EX8YREd8bKHWiLz8lIVdD5cBNeVwQoMKSc6HfI7vKZp8Q2" + "zWgIFOarx1GQoWJbMcSt188xsl30ncJuJT2OoARRBAqJ4fD+q6hbqgNSjTQ7" + "htle1KO3eiaZgcJ8rrnyN8P+5A8+5K+H9aQ/NbBR4Gs7yto5PXIUZEUgodHA" + "TZMSAcSq5ZYt4KbnSYaLY0TtH9CqAigEwZ+hglbT21B7ZTzYX2xj0x+qooJD" + "hVTLtIPaYJK2HrMPxTw6/zfrAgEPA1IABAnvfFcFDgD/JicwBGn6vR3N8MIn" + "mptZf/mnJ1y649uCF60zOgdwIyI7pVSxBFsJ7ohqXEHW0x7LrGVkdSEiipiH" + "LYslqh3xrqbAgPbl93GUo0IwQDAPBgNVHRMBAf8EBTADAQH/MA4GA1UdDwEB" + "/wQEAwIBxjAdBgNVHQ4EFgQUAEo62Xm9H6DcsE0zUDTza4BRG90wCwYHKoZI" + "zj0EAQUAA1cAMFQCKAQsCHHSNOqfJXLgt3bg5+k49hIBGVr/bfG0B9JU3rNt" + "Ycl9Y2zfRPUCKAK2ccOQXByAWfsasDu8zKHxkZv7LVDTFjAIffz3HaCQeVhD" + "z+fauEg="); byte[] keyUsage = Base64.decode( "MIIE7TCCBFagAwIBAgIEOAOR7jANBgkqhkiG9w0BAQQFADCByTELMAkGA1UE" + "BhMCVVMxFDASBgNVBAoTC0VudHJ1c3QubmV0MUgwRgYDVQQLFD93d3cuZW50" + "cnVzdC5uZXQvQ2xpZW50X0NBX0luZm8vQ1BTIGluY29ycC4gYnkgcmVmLiBs" + "aW1pdHMgbGlhYi4xJTAjBgNVBAsTHChjKSAxOTk5IEVudHJ1c3QubmV0IExp" + "bWl0ZWQxMzAxBgNVBAMTKkVudHJ1c3QubmV0IENsaWVudCBDZXJ0aWZpY2F0" + "aW9uIEF1dGhvcml0eTAeFw05OTEwMTIxOTI0MzBaFw0xOTEwMTIxOTU0MzBa" + "MIHJMQswCQYDVQQGEwJVUzEUMBIGA1UEChMLRW50cnVzdC5uZXQxSDBGBgNV" + "BAsUP3d3dy5lbnRydXN0Lm5ldC9DbGllbnRfQ0FfSW5mby9DUFMgaW5jb3Jw" + "LiBieSByZWYuIGxpbWl0cyBsaWFiLjElMCMGA1UECxMcKGMpIDE5OTkgRW50" + "cnVzdC5uZXQgTGltaXRlZDEzMDEGA1UEAxMqRW50cnVzdC5uZXQgQ2xpZW50" + "IENlcnRpZmljYXRpb24gQXV0aG9yaXR5MIGdMA0GCSqGSIb3DQEBAQUAA4GL" + "ADCBhwKBgQDIOpleMRffrCdvkHvkGf9FozTC28GoT/Bo6oT9n3V5z8GKUZSv" + "x1cDR2SerYIbWtp/N3hHuzeYEpbOxhN979IMMFGpOZ5V+Pux5zDeg7K6PvHV" + "iTs7hbqqdCz+PzFur5GVbgbUB01LLFZHGARS2g4Qk79jkJvh34zmAqTmT173" + "iwIBA6OCAeAwggHcMBEGCWCGSAGG+EIBAQQEAwIABzCCASIGA1UdHwSCARkw" + "ggEVMIHkoIHhoIHepIHbMIHYMQswCQYDVQQGEwJVUzEUMBIGA1UEChMLRW50" + "cnVzdC5uZXQxSDBGBgNVBAsUP3d3dy5lbnRydXN0Lm5ldC9DbGllbnRfQ0Ff" + "SW5mby9DUFMgaW5jb3JwLiBieSByZWYuIGxpbWl0cyBsaWFiLjElMCMGA1UE" + "CxMcKGMpIDE5OTkgRW50cnVzdC5uZXQgTGltaXRlZDEzMDEGA1UEAxMqRW50" + "cnVzdC5uZXQgQ2xpZW50IENlcnRpZmljYXRpb24gQXV0aG9yaXR5MQ0wCwYD" + "VQQDEwRDUkwxMCygKqAohiZodHRwOi8vd3d3LmVudHJ1c3QubmV0L0NSTC9D" + "bGllbnQxLmNybDArBgNVHRAEJDAigA8xOTk5MTAxMjE5MjQzMFqBDzIwMTkx" + "MDEyMTkyNDMwWjALBgNVHQ8EBAMCAQYwHwYDVR0jBBgwFoAUxPucKXuXzUyW" + "/O5bs8qZdIuV6kwwHQYDVR0OBBYEFMT7nCl7l81MlvzuW7PKmXSLlepMMAwG" + "A1UdEwQFMAMBAf8wGQYJKoZIhvZ9B0EABAwwChsEVjQuMAMCBJAwDQYJKoZI" + "hvcNAQEEBQADgYEAP66K8ddmAwWePvrqHEa7pFuPeJoSSJn59DXeDDYHAmsQ" + "OokUgZwxpnyyQbJq5wcBoUv5nyU7lsqZwz6hURzzwy5E97BnRqqS5TvaHBkU" + "ODDV4qIxJS7x7EU47fgGWANzYrAQMY9Av2TgXD7FTx/aEkP/TOYGJqibGapE" + "PHayXOw="); byte[] nameCert = Base64.decode( "MIIEFjCCA3+gAwIBAgIEdS8BozANBgkqhkiG9w0BAQUFADBKMQswCQYDVQQGEwJE"+ "RTERMA8GA1UEChQIREFURVYgZUcxKDAMBgcCggYBCgcUEwExMBgGA1UEAxQRQ0Eg"+ "REFURVYgRDAzIDE6UE4wIhgPMjAwMTA1MTAxMDIyNDhaGA8yMDA0MDUwOTEwMjI0"+ "OFowgYQxCzAJBgNVBAYTAkRFMQ8wDQYDVQQIFAZCYXllcm4xEjAQBgNVBAcUCU7I"+ "dXJuYmVyZzERMA8GA1UEChQIREFURVYgZUcxHTAbBgNVBAUTFDAwMDAwMDAwMDA4"+ "OTU3NDM2MDAxMR4wHAYDVQQDFBVEaWV0bWFyIFNlbmdlbmxlaXRuZXIwgaEwDQYJ"+ "KoZIhvcNAQEBBQADgY8AMIGLAoGBAJLI/LJLKaHoMk8fBECW/od8u5erZi6jI8Ug"+ "C0a/LZyQUO/R20vWJs6GrClQtXB+AtfiBSnyZOSYzOdfDI8yEKPEv8qSuUPpOHps"+ "uNCFdLZF1vavVYGEEWs2+y+uuPmg8q1oPRyRmUZ+x9HrDvCXJraaDfTEd9olmB/Z"+ "AuC/PqpjAgUAwAAAAaOCAcYwggHCMAwGA1UdEwEB/wQCMAAwDwYDVR0PAQH/BAUD"+ "AwdAADAxBgNVHSAEKjAoMCYGBSskCAEBMB0wGwYIKwYBBQUHAgEWD3d3dy56cy5k"+ "YXRldi5kZTApBgNVHREEIjAggR5kaWV0bWFyLnNlbmdlbmxlaXRuZXJAZGF0ZXYu"+ "ZGUwgYQGA1UdIwR9MHuhc6RxMG8xCzAJBgNVBAYTAkRFMT0wOwYDVQQKFDRSZWd1"+ "bGllcnVuZ3NiZWjIb3JkZSBmyHVyIFRlbGVrb21tdW5pa2F0aW9uIHVuZCBQb3N0"+ "MSEwDAYHAoIGAQoHFBMBMTARBgNVBAMUCjVSLUNBIDE6UE6CBACm8LkwDgYHAoIG"+ "AQoMAAQDAQEAMEcGA1UdHwRAMD4wPKAUoBKGEHd3dy5jcmwuZGF0ZXYuZGWiJKQi"+ "MCAxCzAJBgNVBAYTAkRFMREwDwYDVQQKFAhEQVRFViBlRzAWBgUrJAgDBAQNMAsT"+ "A0VVUgIBBQIBATAdBgNVHQ4EFgQUfv6xFP0xk7027folhy+ziZvBJiwwLAYIKwYB"+ "BQUHAQEEIDAeMBwGCCsGAQUFBzABhhB3d3cuZGlyLmRhdGV2LmRlMA0GCSqGSIb3"+ "DQEBBQUAA4GBAEOVX6uQxbgtKzdgbTi6YLffMftFr2mmNwch7qzpM5gxcynzgVkg"+ "pnQcDNlm5AIbS6pO8jTCLfCd5TZ5biQksBErqmesIl3QD+VqtB+RNghxectZ3VEs"+ "nCUtcE7tJ8O14qwCb3TxS9dvIUFiVi4DjbxX46TdcTbTaK8/qr6AIf+l"); byte[] probSelfSignedCert = Base64.decode( "MIICxTCCAi6gAwIBAgIQAQAAAAAAAAAAAAAAAAAAATANBgkqhkiG9w0BAQUFADBF" + "MScwJQYDVQQKEx4gRElSRUNUSU9OIEdFTkVSQUxFIERFUyBJTVBPVFMxGjAYBgNV" + "BAMTESBBQyBNSU5FRkkgQiBURVNUMB4XDTA0MDUwNzEyMDAwMFoXDTE0MDUwNzEy" + "MDAwMFowRTEnMCUGA1UEChMeIERJUkVDVElPTiBHRU5FUkFMRSBERVMgSU1QT1RT" + "MRowGAYDVQQDExEgQUMgTUlORUZJIEIgVEVTVDCBnzANBgkqhkiG9w0BAQEFAAOB" + "jQAwgYkCgYEAveoCUOAukZdcFCs2qJk76vSqEX0ZFzHqQ6faBPZWjwkgUNwZ6m6m" + "qWvvyq1cuxhoDvpfC6NXILETawYc6MNwwxsOtVVIjuXlcF17NMejljJafbPximEt" + "DQ4LcQeSp4K7FyFlIAMLyt3BQ77emGzU5fjFTvHSUNb3jblx0sV28c0CAwEAAaOB" + "tTCBsjAfBgNVHSMEGDAWgBSEJ4bLbvEQY8cYMAFKPFD1/fFXlzAdBgNVHQ4EFgQU" + "hCeGy27xEGPHGDABSjxQ9f3xV5cwDgYDVR0PAQH/BAQDAgEGMBEGCWCGSAGG+EIB" + "AQQEAwIBBjA8BgNVHR8ENTAzMDGgL6AthitodHRwOi8vYWRvbmlzLnBrNy5jZXJ0" + "cGx1cy5uZXQvZGdpLXRlc3QuY3JsMA8GA1UdEwEB/wQFMAMBAf8wDQYJKoZIhvcN" + "AQEFBQADgYEAmToHJWjd3+4zknfsP09H6uMbolHNGG0zTS2lrLKpzcmkQfjhQpT9" + "LUTBvfs1jdjo9fGmQLvOG+Sm51Rbjglb8bcikVI5gLbclOlvqLkm77otjl4U4Z2/" + "Y0vP14Aov3Sn3k+17EfReYUZI4liuB95ncobC4e8ZM++LjQcIM0s+Vs="); byte[] gost34102001base = Base64.decode( "MIIB1DCCAYECEEjpVKXP6Wn1yVz3VeeDQa8wCgYGKoUDAgIDBQAwbTEfMB0G" + "A1UEAwwWR29zdFIzNDEwLTIwMDEgZXhhbXBsZTESMBAGA1UECgwJQ3J5cHRv" + "UHJvMQswCQYDVQQGEwJSVTEpMCcGCSqGSIb3DQEJARYaR29zdFIzNDEwLTIw" + "MDFAZXhhbXBsZS5jb20wHhcNMDUwMjAzMTUxNjQ2WhcNMTUwMjAzMTUxNjQ2" + "WjBtMR8wHQYDVQQDDBZHb3N0UjM0MTAtMjAwMSBleGFtcGxlMRIwEAYDVQQK" + "DAlDcnlwdG9Qcm8xCzAJBgNVBAYTAlJVMSkwJwYJKoZIhvcNAQkBFhpHb3N0" + "UjM0MTAtMjAwMUBleGFtcGxlLmNvbTBjMBwGBiqFAwICEzASBgcqhQMCAiQA" + "BgcqhQMCAh4BA0MABECElWh1YAIaQHUIzROMMYks/eUFA3pDXPRtKw/nTzJ+" + "V4/rzBa5lYgD0Jp8ha4P5I3qprt+VsfLsN8PZrzK6hpgMAoGBiqFAwICAwUA" + "A0EAHw5dw/aw/OiNvHyOE65kvyo4Hp0sfz3csM6UUkp10VO247ofNJK3tsLb" + "HOLjUaqzefrlGb11WpHYrvWFg+FcLA=="); byte[] gost341094base = Base64.decode( "MIICDzCCAbwCEBcxKsIb0ghYvAQeUjfQdFAwCgYGKoUDAgIEBQAwaTEdMBsG" + "A1UEAwwUR29zdFIzNDEwLTk0IGV4YW1wbGUxEjAQBgNVBAoMCUNyeXB0b1By" + "bzELMAkGA1UEBhMCUlUxJzAlBgkqhkiG9w0BCQEWGEdvc3RSMzQxMC05NEBl" + "eGFtcGxlLmNvbTAeFw0wNTAyMDMxNTE2NTFaFw0xNTAyMDMxNTE2NTFaMGkx" + "HTAbBgNVBAMMFEdvc3RSMzQxMC05NCBleGFtcGxlMRIwEAYDVQQKDAlDcnlw" + "dG9Qcm8xCzAJBgNVBAYTAlJVMScwJQYJKoZIhvcNAQkBFhhHb3N0UjM0MTAt" + "OTRAZXhhbXBsZS5jb20wgaUwHAYGKoUDAgIUMBIGByqFAwICIAIGByqFAwIC" + "HgEDgYQABIGAu4Rm4XmeWzTYLIB/E6gZZnFX/oxUJSFHbzALJ3dGmMb7R1W+" + "t7Lzk2w5tUI3JoTiDRCKJA4fDEJNKzsRK6i/ZjkyXJSLwaj+G2MS9gklh8x1" + "G/TliYoJgmjTXHemD7aQEBON4z58nJHWrA0ILD54wbXCtrcaqCqLRYGTMjJ2" + "+nswCgYGKoUDAgIEBQADQQBxKNhOmjgz/i5CEgLOyKyz9pFGkDcaymsWYQWV" + "v7CZ0pTM8IzMzkUBW3GHsUjCFpanFZDfg2zuN+3kT+694n9B"); byte[] gost341094A = Base64.decode( "MIICSDCCAfWgAwIBAgIBATAKBgYqhQMCAgQFADCBgTEXMBUGA1UEAxMOZGVmYXVsdDM0MTAtOTQx" + "DTALBgNVBAoTBERpZ3QxDzANBgNVBAsTBkNyeXB0bzEOMAwGA1UEBxMFWS1vbGExDDAKBgNVBAgT" + "A01FTDELMAkGA1UEBhMCcnUxGzAZBgkqhkiG9w0BCQEWDHRlc3RAdGVzdC5ydTAeFw0wNTAzMjkx" + "MzExNTdaFw0wNjAzMjkxMzExNTdaMIGBMRcwFQYDVQQDEw5kZWZhdWx0MzQxMC05NDENMAsGA1UE" + "ChMERGlndDEPMA0GA1UECxMGQ3J5cHRvMQ4wDAYDVQQHEwVZLW9sYTEMMAoGA1UECBMDTUVMMQsw" + "CQYDVQQGEwJydTEbMBkGCSqGSIb3DQEJARYMdGVzdEB0ZXN0LnJ1MIGlMBwGBiqFAwICFDASBgcq" + "hQMCAiACBgcqhQMCAh4BA4GEAASBgIQACDLEuxSdRDGgdZxHmy30g/DUYkRxO9Mi/uSHX5NjvZ31" + "b7JMEMFqBtyhql1HC5xZfUwZ0aT3UnEFDfFjLP+Bf54gA+LPkQXw4SNNGOj+klnqgKlPvoqMGlwa" + "+hLPKbS561WpvB2XSTgbV+pqqXR3j6j30STmybelEV3RdS2Now8wDTALBgNVHQ8EBAMCB4AwCgYG" + "KoUDAgIEBQADQQBCFy7xWRXtNVXflKvDs0pBdBuPzjCMeZAXVxK8vUxsxxKu76d9CsvhgIFknFRi" + "wWTPiZenvNoJ4R1uzeX+vREm"); byte[] gost341094B = Base64.decode( "MIICSDCCAfWgAwIBAgIBATAKBgYqhQMCAgQFADCBgTEXMBUGA1UEAxMOcGFyYW0xLTM0MTAtOTQx" + "DTALBgNVBAoTBERpZ3QxDzANBgNVBAsTBkNyeXB0bzEOMAwGA1UEBxMFWS1PbGExDDAKBgNVBAgT" + "A01lbDELMAkGA1UEBhMCcnUxGzAZBgkqhkiG9w0BCQEWDHRlc3RAdGVzdC5ydTAeFw0wNTAzMjkx" + "MzEzNTZaFw0wNjAzMjkxMzEzNTZaMIGBMRcwFQYDVQQDEw5wYXJhbTEtMzQxMC05NDENMAsGA1UE" + "ChMERGlndDEPMA0GA1UECxMGQ3J5cHRvMQ4wDAYDVQQHEwVZLU9sYTEMMAoGA1UECBMDTWVsMQsw" + "CQYDVQQGEwJydTEbMBkGCSqGSIb3DQEJARYMdGVzdEB0ZXN0LnJ1MIGlMBwGBiqFAwICFDASBgcq" + "hQMCAiADBgcqhQMCAh4BA4GEAASBgEa+AAcZmijWs1M9x5Pn9efE8D9ztG1NMoIt0/hNZNqln3+j" + "lMZjyqPt+kTLIjtmvz9BRDmIDk6FZz+4LhG2OTL7yGpWfrMxMRr56nxomTN9aLWRqbyWmn3brz9Y" + "AUD3ifnwjjIuW7UM84JNlDTOdxx0XRUfLQIPMCXe9cO02Xskow8wDTALBgNVHQ8EBAMCB4AwCgYG" + "KoUDAgIEBQADQQBzFcnuYc/639OTW+L5Ecjw9KxGr+dwex7lsS9S1BUgKa3m1d5c+cqI0B2XUFi5" + "4iaHHJG0dCyjtQYLJr0OZjRw"); byte[] gost34102001A = Base64.decode( "MIICCzCCAbigAwIBAgIBATAKBgYqhQMCAgMFADCBhDEaMBgGA1UEAxMRZGVmYXVsdC0zNDEwLTIw" + "MDExDTALBgNVBAoTBERpZ3QxDzANBgNVBAsTBkNyeXB0bzEOMAwGA1UEBxMFWS1PbGExDDAKBgNV" + "BAgTA01lbDELMAkGA1UEBhMCcnUxGzAZBgkqhkiG9w0BCQEWDHRlc3RAdGVzdC5ydTAeFw0wNTAz" + "MjkxMzE4MzFaFw0wNjAzMjkxMzE4MzFaMIGEMRowGAYDVQQDExFkZWZhdWx0LTM0MTAtMjAwMTEN" + "MAsGA1UEChMERGlndDEPMA0GA1UECxMGQ3J5cHRvMQ4wDAYDVQQHEwVZLU9sYTEMMAoGA1UECBMD" + "TWVsMQswCQYDVQQGEwJydTEbMBkGCSqGSIb3DQEJARYMdGVzdEB0ZXN0LnJ1MGMwHAYGKoUDAgIT" + "MBIGByqFAwICIwEGByqFAwICHgEDQwAEQG/4c+ZWb10IpeHfmR+vKcbpmSOClJioYmCVgnojw0Xn" + "ned0KTg7TJreRUc+VX7vca4hLQaZ1o/TxVtfEApK/O6jDzANMAsGA1UdDwQEAwIHgDAKBgYqhQMC" + "AgMFAANBAN8y2b6HuIdkD3aWujpfQbS1VIA/7hro4vLgDhjgVmev/PLzFB8oTh3gKhExpDo82IEs" + "ZftGNsbbyp1NFg7zda0="); byte[] gostCA1 = Base64.decode( "MIIDNDCCAuGgAwIBAgIQZLcKDcWcQopF+jp4p9jylDAKBgYqhQMCAgQFADBm" + "MQswCQYDVQQGEwJSVTEPMA0GA1UEBxMGTW9zY293MRcwFQYDVQQKEw5PT08g" + "Q3J5cHRvLVBybzEUMBIGA1UECxMLRGV2ZWxvcG1lbnQxFzAVBgNVBAMTDkNQ" + "IENTUCBUZXN0IENBMB4XDTAyMDYwOTE1NTIyM1oXDTA5MDYwOTE1NTkyOVow" + "ZjELMAkGA1UEBhMCUlUxDzANBgNVBAcTBk1vc2NvdzEXMBUGA1UEChMOT09P" + "IENyeXB0by1Qcm8xFDASBgNVBAsTC0RldmVsb3BtZW50MRcwFQYDVQQDEw5D" + "UCBDU1AgVGVzdCBDQTCBpTAcBgYqhQMCAhQwEgYHKoUDAgIgAgYHKoUDAgIe" + "AQOBhAAEgYAYglywKuz1nMc9UiBYOaulKy53jXnrqxZKbCCBSVaJ+aCKbsQm" + "glhRFrw6Mwu8Cdeabo/ojmea7UDMZd0U2xhZFRti5EQ7OP6YpqD0alllo7za" + "4dZNXdX+/ag6fOORSLFdMpVx5ganU0wHMPk67j+audnCPUj/plbeyccgcdcd" + "WaOCASIwggEeMAsGA1UdDwQEAwIBxjAPBgNVHRMBAf8EBTADAQH/MB0GA1Ud" + "DgQWBBTe840gTo4zt2twHilw3PD9wJaX0TCBygYDVR0fBIHCMIG/MDygOqA4" + "hjYtaHR0cDovL2ZpZXdhbGwvQ2VydEVucm9sbC9DUCUyMENTUCUyMFRlc3Ql" + "MjBDQSgzKS5jcmwwRKBCoECGPmh0dHA6Ly93d3cuY3J5cHRvcHJvLnJ1L0Nl" + "cnRFbnJvbGwvQ1AlMjBDU1AlMjBUZXN0JTIwQ0EoMykuY3JsMDmgN6A1hjMt" + "ZmlsZTovL1xcZmlld2FsbFxDZXJ0RW5yb2xsXENQIENTUCBUZXN0IENBKDMp" + "LmNybC8wEgYJKwYBBAGCNxUBBAUCAwMAAzAKBgYqhQMCAgQFAANBAIJi7ni7" + "9rwMR5rRGTFftt2k70GbqyUEfkZYOzrgdOoKiB4IIsIstyBX0/ne6GsL9Xan" + "G2IN96RB7KrowEHeW+k="); byte[] gostCA2 = Base64.decode( "MIIC2DCCAoWgAwIBAgIQe9ZCugm42pRKNcHD8466zTAKBgYqhQMCAgMFADB+" + "MRowGAYJKoZIhvcNAQkBFgtzYmFAZGlndC5ydTELMAkGA1UEBhMCUlUxDDAK" + "BgNVBAgTA01FTDEUMBIGA1UEBxMLWW9zaGthci1PbGExDTALBgNVBAoTBERp" + "Z3QxDzANBgNVBAsTBkNyeXB0bzEPMA0GA1UEAxMGc2JhLUNBMB4XDTA0MDgw" + "MzEzMzE1OVoXDTE0MDgwMzEzNDAxMVowfjEaMBgGCSqGSIb3DQEJARYLc2Jh" + "QGRpZ3QucnUxCzAJBgNVBAYTAlJVMQwwCgYDVQQIEwNNRUwxFDASBgNVBAcT" + "C1lvc2hrYXItT2xhMQ0wCwYDVQQKEwREaWd0MQ8wDQYDVQQLEwZDcnlwdG8x" + "DzANBgNVBAMTBnNiYS1DQTBjMBwGBiqFAwICEzASBgcqhQMCAiMBBgcqhQMC" + "Ah4BA0MABEDMSy10CuOH+i8QKG2UWA4XmCt6+BFrNTZQtS6bOalyDY8Lz+G7" + "HybyipE3PqdTB4OIKAAPsEEeZOCZd2UXGQm5o4HaMIHXMBMGCSsGAQQBgjcU" + "AgQGHgQAQwBBMAsGA1UdDwQEAwIBhjAPBgNVHRMBAf8EBTADAQH/MB0GA1Ud" + "DgQWBBRJJl3LcNMxkZI818STfoi3ng1xoDBxBgNVHR8EajBoMDGgL6Athito" + "dHRwOi8vc2JhLmRpZ3QubG9jYWwvQ2VydEVucm9sbC9zYmEtQ0EuY3JsMDOg" + "MaAvhi1maWxlOi8vXFxzYmEuZGlndC5sb2NhbFxDZXJ0RW5yb2xsXHNiYS1D" + "QS5jcmwwEAYJKwYBBAGCNxUBBAMCAQAwCgYGKoUDAgIDBQADQQA+BRJHbc/p" + "q8EYl6iJqXCuR+ozRmH7hPAP3c4KqYSC38TClCgBloLapx/3/WdatctFJW/L" + "mcTovpq088927shE"); byte[] inDirectCrl = Base64.decode( "MIIdXjCCHMcCAQEwDQYJKoZIhvcNAQEFBQAwdDELMAkGA1UEBhMCREUxHDAaBgNV" +"BAoUE0RldXRzY2hlIFRlbGVrb20gQUcxFzAVBgNVBAsUDlQtVGVsZVNlYyBUZXN0" +"MS4wDAYHAoIGAQoHFBMBMTAeBgNVBAMUF1QtVGVsZVNlYyBUZXN0IERJUiA4OlBO" +"Fw0wNjA4MDQwODQ1MTRaFw0wNjA4MDQxNDQ1MTRaMIIbfzB+AgQvrj/pFw0wMzA3" +"MjIwNTQxMjhaMGcwZQYDVR0dAQH/BFswWaRXMFUxCzAJBgNVBAYTAkRFMRwwGgYD" +"VQQKFBNEZXV0c2NoZSBUZWxla29tIEFHMSgwDAYHAoIGAQoHFBMBMTAYBgNVBAMU" +"EVNpZ0cgVGVzdCBDQSA0OlBOMH4CBC+uP+oXDTAzMDcyMjA1NDEyOFowZzBlBgNV" +"HR0BAf8EWzBZpFcwVTELMAkGA1UEBhMCREUxHDAaBgNVBAoUE0RldXRzY2hlIFRl" +"bGVrb20gQUcxKDAMBgcCggYBCgcUEwExMBgGA1UEAxQRU2lnRyBUZXN0IENBIDQ6" +"UE4wfgIEL64/5xcNMDQwNDA1MTMxODE3WjBnMGUGA1UdHQEB/wRbMFmkVzBVMQsw" +"CQYDVQQGEwJERTEcMBoGA1UEChQTRGV1dHNjaGUgVGVsZWtvbSBBRzEoMAwGBwKC" +"BgEKBxQTATEwGAYDVQQDFBFTaWdHIFRlc3QgQ0EgNDpQTjB+AgQvrj/oFw0wNDA0" +"MDUxMzE4MTdaMGcwZQYDVR0dAQH/BFswWaRXMFUxCzAJBgNVBAYTAkRFMRwwGgYD" +"VQQKFBNEZXV0c2NoZSBUZWxla29tIEFHMSgwDAYHAoIGAQoHFBMBMTAYBgNVBAMU" +"EVNpZ0cgVGVzdCBDQSA0OlBOMH4CBC+uP+UXDTAzMDExMzExMTgxMVowZzBlBgNV" +"HR0BAf8EWzBZpFcwVTELMAkGA1UEBhMCREUxHDAaBgNVBAoUE0RldXRzY2hlIFRl" +"bGVrb20gQUcxKDAMBgcCggYBCgcUEwExMBgGA1UEAxQRU2lnRyBUZXN0IENBIDQ6" +"UE4wfgIEL64/5hcNMDMwMTEzMTExODExWjBnMGUGA1UdHQEB/wRbMFmkVzBVMQsw" +"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"); byte[] directCRL = Base64.decode( "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" +"MQ=="); private final byte[] pkcs7CrlProblem = Base64.decode( "MIIwSAYJKoZIhvcNAQcCoIIwOTCCMDUCAQExCzAJBgUrDgMCGgUAMAsGCSqG" + "SIb3DQEHAaCCEsAwggP4MIIC4KADAgECAgF1MA0GCSqGSIb3DQEBBQUAMEUx" + "CzAJBgNVBAYTAlVTMRYwFAYDVQQKEw1HZW9UcnVzdCBJbmMuMR4wHAYDVQQD" + "ExVHZW9UcnVzdCBDQSBmb3IgQWRvYmUwHhcNMDQxMjAyMjEyNTM5WhcNMDYx" + "MjMwMjEyNTM5WjBMMQswCQYDVQQGEwJVUzEVMBMGA1UEChMMR2VvVHJ1c3Qg" + "SW5jMSYwJAYDVQQDEx1HZW9UcnVzdCBBZG9iZSBPQ1NQIFJlc3BvbmRlcjCB" + "nzANBgkqhkiG9w0BAQEFAAOBjQAwgYkCgYEA4gnNYhtw7U6QeVXZODnGhHMj" + "+OgZ0DB393rEk6a2q9kq129IA2e03yKBTfJfQR9aWKc2Qj90dsSqPjvTDHFG" + "Qsagm2FQuhnA3fb1UWhPzeEIdm6bxDsnQ8nWqKqxnWZzELZbdp3I9bBLizIq" + "obZovzt60LNMghn/unvvuhpeVSsCAwEAAaOCAW4wggFqMA4GA1UdDwEB/wQE" + "AwIE8DCB5QYDVR0gAQH/BIHaMIHXMIHUBgkqhkiG9y8BAgEwgcYwgZAGCCsG" + "AQUFBwICMIGDGoGAVGhpcyBjZXJ0aWZpY2F0ZSBoYXMgYmVlbiBpc3N1ZWQg" + "aW4gYWNjb3JkYW5jZSB3aXRoIHRoZSBBY3JvYmF0IENyZWRlbnRpYWxzIENQ" + "UyBsb2NhdGVkIGF0IGh0dHA6Ly93d3cuZ2VvdHJ1c3QuY29tL3Jlc291cmNl" + "cy9jcHMwMQYIKwYBBQUHAgEWJWh0dHA6Ly93d3cuZ2VvdHJ1c3QuY29tL3Jl" + "c291cmNlcy9jcHMwEwYDVR0lBAwwCgYIKwYBBQUHAwkwOgYDVR0fBDMwMTAv" + "oC2gK4YpaHR0cDovL2NybC5nZW90cnVzdC5jb20vY3Jscy9hZG9iZWNhMS5j" + "cmwwHwYDVR0jBBgwFoAUq4BZw2WDbR19E70Zw+wajw1HaqMwDQYJKoZIhvcN" + "AQEFBQADggEBAENJf1BD7PX5ivuaawt90q1OGzXpIQL/ClzEeFVmOIxqPc1E" + "TFRq92YuxG5b6+R+k+tGkmCwPLcY8ipg6ZcbJ/AirQhohzjlFuT6YAXsTfEj" + "CqEZfWM2sS7crK2EYxCMmKE3xDfPclYtrAoz7qZvxfQj0TuxHSstHZv39wu2" + "ZiG1BWiEcyDQyTgqTOXBoZmfJtshuAcXmTpgkrYSrS37zNlPTGh+pMYQ0yWD" + "c8OQRJR4OY5ZXfdna01mjtJTOmj6/6XPoLPYTq2gQrc2BCeNJ4bEhLb7sFVB" + "PbwPrpzTE/HRbQHDrzj0YimDxeOUV/UXctgvYwHNtEkcBLsOm/uytMYwggSh" + "MIIDiaADAgECAgQ+HL0oMA0GCSqGSIb3DQEBBQUAMGkxCzAJBgNVBAYTAlVT" + "MSMwIQYDVQQKExpBZG9iZSBTeXN0ZW1zIEluY29ycG9yYXRlZDEdMBsGA1UE" + "CxMUQWRvYmUgVHJ1c3QgU2VydmljZXMxFjAUBgNVBAMTDUFkb2JlIFJvb3Qg" + "Q0EwHhcNMDMwMTA4MjMzNzIzWhcNMjMwMTA5MDAwNzIzWjBpMQswCQYDVQQG" + "EwJVUzEjMCEGA1UEChMaQWRvYmUgU3lzdGVtcyBJbmNvcnBvcmF0ZWQxHTAb" + "BgNVBAsTFEFkb2JlIFRydXN0IFNlcnZpY2VzMRYwFAYDVQQDEw1BZG9iZSBS" + "b290IENBMIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEAzE9UhPen" + "ouczU38/nBKIayyZR2d+Dx65rRSI+cMQ2B3w8NWfaQovWTWwzGypTJwVoJ/O" + "IL+gz1Ti4CBmRT85hjh+nMSOByLGJPYBErA131XqaZCw24U3HuJOB7JCoWoT" + "aaBm6oCREVkqmwh5WiBELcm9cziLPC/gQxtdswvwrzUaKf7vppLdgUydPVmO" + "rTE8QH6bkTYG/OJcjdGNJtVcRc+vZT+xqtJilvSoOOq6YEL09BxKNRXO+E4i" + "Vg+VGMX4lp+f+7C3eCXpgGu91grwxnSUnfMPUNuad85LcIMjjaDKeCBEXDxU" + "ZPHqojAZn+pMBk0GeEtekt8i0slns3rSAQIDAQABo4IBTzCCAUswEQYJYIZI" + "AYb4QgEBBAQDAgAHMIGOBgNVHR8EgYYwgYMwgYCgfqB8pHoweDELMAkGA1UE" + "BhMCVVMxIzAhBgNVBAoTGkFkb2JlIFN5c3RlbXMgSW5jb3Jwb3JhdGVkMR0w" + "GwYDVQQLExRBZG9iZSBUcnVzdCBTZXJ2aWNlczEWMBQGA1UEAxMNQWRvYmUg" + "Um9vdCBDQTENMAsGA1UEAxMEQ1JMMTArBgNVHRAEJDAigA8yMDAzMDEwODIz" + "MzcyM1qBDzIwMjMwMTA5MDAwNzIzWjALBgNVHQ8EBAMCAQYwHwYDVR0jBBgw" + "FoAUgrc4SpOqmxDvgLvZVOLxD/uAnN4wHQYDVR0OBBYEFIK3OEqTqpsQ74C7" + "2VTi8Q/7gJzeMAwGA1UdEwQFMAMBAf8wHQYJKoZIhvZ9B0EABBAwDhsIVjYu" + "MDo0LjADAgSQMA0GCSqGSIb3DQEBBQUAA4IBAQAy2p9DdcH6b8lv26sdNjc+" + "vGEZNrcCPB0jWZhsnu5NhedUyCAfp9S74r8Ad30ka3AvXME6dkm10+AjhCpx" + "aiLzwScpmBX2NZDkBEzDjbyfYRzn/SSM0URDjBa6m02l1DUvvBHOvfdRN42f" + "kOQU8Rg/vulZEjX5M5LznuDVa5pxm5lLyHHD4bFhCcTl+pHwQjo3fTT5cujN" + "qmIcIenV9IIQ43sFti1oVgt+fpIsb01yggztVnSynbmrLSsdEF/bJ3Vwj/0d" + "1+ICoHnlHOX/r2RAUS2em0fbQqV8H8KmSLDXvpJpTaT2KVfFeBEY3IdRyhOy" + "Yp1PKzK9MaXB+lKrBYjIMIIEyzCCA7OgAwIBAgIEPhy9tTANBgkqhkiG9w0B" + "AQUFADBpMQswCQYDVQQGEwJVUzEjMCEGA1UEChMaQWRvYmUgU3lzdGVtcyBJ" + "bmNvcnBvcmF0ZWQxHTAbBgNVBAsTFEFkb2JlIFRydXN0IFNlcnZpY2VzMRYw" + "FAYDVQQDEw1BZG9iZSBSb290IENBMB4XDTA0MDExNzAwMDMzOVoXDTE1MDEx" + "NTA4MDAwMFowRTELMAkGA1UEBhMCVVMxFjAUBgNVBAoTDUdlb1RydXN0IElu" + "Yy4xHjAcBgNVBAMTFUdlb1RydXN0IENBIGZvciBBZG9iZTCCASIwDQYJKoZI" + "hvcNAQEBBQADggEPADCCAQoCggEBAKfld+BkeFrnOYW8r9L1WygTDlTdSfrO" + "YvWS/Z6Ye5/l+HrBbOHqQCXBcSeCpz7kB2WdKMh1FOE4e9JlmICsHerBLdWk" + "emU+/PDb69zh8E0cLoDfxukF6oVPXj6WSThdSG7H9aXFzRr6S3XGCuvgl+Qw" + "DTLiLYW+ONF6DXwt3TQQtKReJjOJZk46ZZ0BvMStKyBaeB6DKZsmiIo89qso" + "13VDZINH2w1KvXg0ygDizoNtbvgAPFymwnsINS1klfQlcvn0x0RJm9bYQXK3" + "5GNZAgL3M7Lqrld0jMfIUaWvuHCLyivytRuzq1dJ7E8rmidjDEk/G+27pf13" + "fNZ7vR7M+IkCAwEAAaOCAZ0wggGZMBIGA1UdEwEB/wQIMAYBAf8CAQEwUAYD" + "VR0gBEkwRzBFBgkqhkiG9y8BAgEwODA2BggrBgEFBQcCARYqaHR0cHM6Ly93" + "d3cuYWRvYmUuY29tL21pc2MvcGtpL2Nkc19jcC5odG1sMBQGA1UdJQQNMAsG" + "CSqGSIb3LwEBBTCBsgYDVR0fBIGqMIGnMCKgIKAehhxodHRwOi8vY3JsLmFk" + "b2JlLmNvbS9jZHMuY3JsMIGAoH6gfKR6MHgxCzAJBgNVBAYTAlVTMSMwIQYD" + "VQQKExpBZG9iZSBTeXN0ZW1zIEluY29ycG9yYXRlZDEdMBsGA1UECxMUQWRv" + "YmUgVHJ1c3QgU2VydmljZXMxFjAUBgNVBAMTDUFkb2JlIFJvb3QgQ0ExDTAL" + "BgNVBAMTBENSTDEwCwYDVR0PBAQDAgEGMB8GA1UdIwQYMBaAFIK3OEqTqpsQ" + "74C72VTi8Q/7gJzeMB0GA1UdDgQWBBSrgFnDZYNtHX0TvRnD7BqPDUdqozAZ" + "BgkqhkiG9n0HQQAEDDAKGwRWNi4wAwIEkDANBgkqhkiG9w0BAQUFAAOCAQEA" + "PzlZLqIAjrFeEWEs0uC29YyJhkXOE9mf3YSaFGsITF+Gl1j0pajTjyH4R35Q" + "r3floW2q3HfNzTeZ90Jnr1DhVERD6zEMgJpCtJqVuk0sixuXJHghS/KicKf4" + "YXJJPx9epuIRF1siBRnznnF90svmOJMXApc0jGnYn3nQfk4kaShSnDaYaeYR" + "DJKcsiWhl6S5zfwS7Gg8hDeyckhMQKKWnlG1CQrwlSFisKCduoodwRtWgft8" + "kx13iyKK3sbalm6vnVc+5nufS4vI+TwMXoV63NqYaSroafBWk0nL53zGXPEy" + "+A69QhzEViJKn2Wgqt5gt++jMMNImbRObIqgfgF1VjCCBUwwggQ0oAMCAQIC" + "AgGDMA0GCSqGSIb3DQEBBQUAMEUxCzAJBgNVBAYTAlVTMRYwFAYDVQQKEw1H" + "ZW9UcnVzdCBJbmMuMR4wHAYDVQQDExVHZW9UcnVzdCBDQSBmb3IgQWRvYmUw" + "HhcNMDYwMzI0MTU0MjI5WhcNMDkwNDA2MTQ0MjI5WjBzMQswCQYDVQQGEwJV" + "UzELMAkGA1UECBMCTUExETAPBgNVBAoTCEdlb1RydXN0MR0wGwYDVQQDExRN" + "YXJrZXRpbmcgRGVwYXJ0bWVudDElMCMGCSqGSIb3DQEJARYWbWFya2V0aW5n" + "QGdlb3RydXN0LmNvbTCCASIwDQYJKoZIhvcNAQEBBQADggEPADCCAQoCggEB" + "ANmvajTO4XJvAU2nVcLmXeCnAQX7RZt+7+ML3InmqQ3LCGo1weop09zV069/" + "1x/Nmieol7laEzeXxd2ghjGzwfXafqQEqHn6+vBCvqdNPoSi63fSWhnuDVWp" + "KVDOYgxOonrXl+Cc43lu4zRSq+Pi5phhrjDWcH74a3/rdljUt4c4GFezFXfa" + "w2oTzWkxj2cTSn0Szhpr17+p66UNt8uknlhmu4q44Speqql2HwmCEnpLYJrK" + "W3fOq5D4qdsvsLR2EABLhrBezamLI3iGV8cRHOUTsbTMhWhv/lKfHAyf4XjA" + "z9orzvPN5jthhIfICOFq/nStTgakyL4Ln+nFAB/SMPkCAwEAAaOCAhYwggIS" + "MA4GA1UdDwEB/wQEAwIF4DCB5QYDVR0gAQH/BIHaMIHXMIHUBgkqhkiG9y8B" + "AgEwgcYwgZAGCCsGAQUFBwICMIGDGoGAVGhpcyBjZXJ0aWZpY2F0ZSBoYXMg" + "YmVlbiBpc3N1ZWQgaW4gYWNjb3JkYW5jZSB3aXRoIHRoZSBBY3JvYmF0IENy" + "ZWRlbnRpYWxzIENQUyBsb2NhdGVkIGF0IGh0dHA6Ly93d3cuZ2VvdHJ1c3Qu" + "Y29tL3Jlc291cmNlcy9jcHMwMQYIKwYBBQUHAgEWJWh0dHA6Ly93d3cuZ2Vv" + "dHJ1c3QuY29tL3Jlc291cmNlcy9jcHMwOgYDVR0fBDMwMTAvoC2gK4YpaHR0" + "cDovL2NybC5nZW90cnVzdC5jb20vY3Jscy9hZG9iZWNhMS5jcmwwHwYDVR0j" + "BBgwFoAUq4BZw2WDbR19E70Zw+wajw1HaqMwRAYIKwYBBQUHAQEEODA2MDQG" + "CCsGAQUFBzABhihodHRwOi8vYWRvYmUtb2NzcC5nZW90cnVzdC5jb20vcmVz" + "cG9uZGVyMBQGA1UdJQQNMAsGCSqGSIb3LwEBBTA8BgoqhkiG9y8BAQkBBC4w" + "LAIBAYYnaHR0cDovL2Fkb2JlLXRpbWVzdGFtcC5nZW90cnVzdC5jb20vdHNh" + "MBMGCiqGSIb3LwEBCQIEBTADAgEBMAwGA1UdEwQFMAMCAQAwDQYJKoZIhvcN" + "AQEFBQADggEBAAOhy6QxOo+i3h877fvDvTa0plGD2bIqK7wMdNqbMDoSWied" + "FIcgcBOIm2wLxOjZBAVj/3lDq59q2rnVeNnfXM0/N0MHI9TumHRjU7WNk9e4" + "+JfJ4M+c3anrWOG3NE5cICDVgles+UHjXetHWql/LlP04+K2ZOLb6LE2xGnI" + "YyLW9REzCYNAVF+/WkYdmyceHtaBZdbyVAJq0NAJPsfgY1pWcBo31Mr1fpX9" + "WrXNTYDCqMyxMImJTmN3iI68tkXlNrhweQoArKFqBysiBkXzG/sGKYY6tWKU" + "pzjLc3vIp/LrXC5zilROes8BSvwu1w9qQrJNcGwo7O4uijoNtyYil1Exgh1Q" + "MIIdTAIBATBLMEUxCzAJBgNVBAYTAlVTMRYwFAYDVQQKEw1HZW9UcnVzdCBJ" + "bmMuMR4wHAYDVQQDExVHZW9UcnVzdCBDQSBmb3IgQWRvYmUCAgGDMAkGBSsO" + "AwIaBQCgggxMMBgGCSqGSIb3DQEJAzELBgkqhkiG9w0BBwEwIwYJKoZIhvcN" + "AQkEMRYEFP4R6qIdpQJzWyzrqO8X1ZfJOgChMIIMCQYJKoZIhvcvAQEIMYIL" + "+jCCC/agggZ5MIIGdTCCA6gwggKQMA0GCSqGSIb3DQEBBQUAMEUxCzAJBgNV" + "BAYTAlVTMRYwFAYDVQQKEw1HZW9UcnVzdCBJbmMuMR4wHAYDVQQDExVHZW9U" + "cnVzdCBDQSBmb3IgQWRvYmUXDTA2MDQwNDE3NDAxMFoXDTA2MDQwNTE3NDAx" + "MFowggIYMBMCAgC5Fw0wNTEwMTEyMDM2MzJaMBICAVsXDTA0MTEwNDE1MDk0" + "MVowEwICALgXDTA1MTIxMjIyMzgzOFowEgIBWhcNMDQxMTA0MTUwOTMzWjAT" + "AgIA5hcNMDUwODI3MDQwOTM4WjATAgIAtxcNMDYwMTE2MTc1NTEzWjATAgIA" + "hhcNMDUxMjEyMjIzODU1WjATAgIAtRcNMDUwNzA2MTgzODQwWjATAgIA4BcN" + "MDYwMzIwMDc0ODM0WjATAgIAgRcNMDUwODAyMjIzMTE1WjATAgIA3xcNMDUx" + "MjEyMjIzNjUwWjASAgFKFw0wNDExMDQxNTA5MTZaMBICAUQXDTA0MTEwNDE1" + "MDg1M1owEgIBQxcNMDQxMDAzMDEwMDQwWjASAgFsFw0wNDEyMDYxOTQ0MzFa" + "MBMCAgEoFw0wNjAzMDkxMjA3MTJaMBMCAgEkFw0wNjAxMTYxNzU1MzRaMBIC" + "AWcXDTA1MDMxODE3NTYxNFowEwICAVEXDTA2MDEzMTExMjcxMVowEgIBZBcN" + "MDQxMTExMjI0ODQxWjATAgIA8RcNMDUwOTE2MTg0ODAxWjATAgIBThcNMDYw" + "MjIxMjAxMDM2WjATAgIAwRcNMDUxMjEyMjIzODE2WjASAgFiFw0wNTAxMTAx" + "NjE5MzRaMBICAWAXDTA1MDExMDE5MDAwNFowEwICAL4XDTA1MDUxNzE0NTYx" + "MFowDQYJKoZIhvcNAQEFBQADggEBAEKhRMS3wVho1U3EvEQJZC8+JlUngmZQ" + "A78KQbHPWNZWFlNvPuf/b0s7Lu16GfNHXh1QAW6Y5Hi1YtYZ3YOPyMd4Xugt" + "gCdumbB6xtKsDyN5RvTht6ByXj+CYlYqsL7RX0izJZ6mJn4fjMkqzPKNOjb8" + "kSn5T6rn93BjlATtCE8tPVOM8dnqGccRE0OV59+nDBXc90UMt5LdEbwaUOap" + "snVB0oLcNm8d/HnlVH6RY5LnDjrT4vwfe/FApZtTecEWsllVUXDjSpwfcfD/" + "476/lpGySB2otALqzImlA9R8Ok3hJ8dnF6hhQ5Oe6OJMnGYgdhkKbxsKkdib" + "tTVl3qmH5QAwggLFMIIBrQIBATANBgkqhkiG9w0BAQUFADBpMQswCQYDVQQG" + "EwJVUzEjMCEGA1UEChMaQWRvYmUgU3lzdGVtcyBJbmNvcnBvcmF0ZWQxHTAb" + "BgNVBAsTFEFkb2JlIFRydXN0IFNlcnZpY2VzMRYwFAYDVQQDEw1BZG9iZSBS" + "b290IENBFw0wNjAxMjcxODMzMzFaFw0wNzAxMjcwMDAwMDBaMIHeMCMCBD4c" + "vUAXDTAzMDEyMTIzNDY1NlowDDAKBgNVHRUEAwoBBDAjAgQ+HL1BFw0wMzAx" + "MjEyMzQ3MjJaMAwwCgYDVR0VBAMKAQQwIwIEPhy9YhcNMDMwMTIxMjM0NzQy" + "WjAMMAoGA1UdFQQDCgEEMCMCBD4cvWEXDTA0MDExNzAxMDg0OFowDDAKBgNV" + "HRUEAwoBBDAjAgQ+HL2qFw0wNDAxMTcwMTA5MDVaMAwwCgYDVR0VBAMKAQQw" + "IwIEPhy9qBcNMDQwMTE3MDEzOTI5WjAMMAoGA1UdFQQDCgEEoC8wLTAKBgNV" + "HRQEAwIBDzAfBgNVHSMEGDAWgBSCtzhKk6qbEO+Au9lU4vEP+4Cc3jANBgkq" + "hkiG9w0BAQUFAAOCAQEAwtXF9042wG39icUlsotn5tpE3oCusLb/hBpEONhx" + "OdfEQOq0w5hf/vqaxkcf71etA+KpbEUeSVaHMHRPhx/CmPrO9odE139dJdbt" + "9iqbrC9iZokFK3h/es5kg73xujLKd7C/u5ngJ4mwBtvhMLjFjF2vJhPKHL4C" + "IgMwdaUAhrcNzy16v+mw/VGJy3Fvc6oCESW1K9tvFW58qZSNXrMlsuidgunM" + "hPKG+z0SXVyCqL7pnqKiaGddcgujYGOSY4S938oVcfZeZQEODtSYGlzldojX" + "C1U1hCK5+tHAH0Ox/WqRBIol5VCZQwJftf44oG8oviYq52aaqSejXwmfT6zb" + "76GCBXUwggVxMIIFbQoBAKCCBWYwggViBgkrBgEFBQcwAQEEggVTMIIFTzCB" + "taIWBBS+8EpykfXdl4h3z7m/NZfdkAQQERgPMjAwNjA0MDQyMDIwMTVaMGUw" + "YzA7MAkGBSsOAwIaBQAEFEb4BuZYkbjBjOjT6VeA/00fBvQaBBT3fTSQniOp" + "BbHBSkz4xridlX0bsAICAYOAABgPMjAwNjA0MDQyMDIwMTVaoBEYDzIwMDYw" + "NDA1MDgyMDE1WqEjMCEwHwYJKwYBBQUHMAECBBIEEFqooq/R2WltD7TposkT" + "BhMwDQYJKoZIhvcNAQEFBQADgYEAMig6lty4b0JDsT/oanfQG5x6jVKPACpp" + "1UA9SJ0apJJa7LeIdDFmu5C2S/CYiKZm4A4P9cAu0YzgLHxE4r6Op+HfVlAG" + "6bzUe1P/hi1KCJ8r8wxOZAktQFPSzs85RAZwkHMfB0lP2e/h666Oye+Zf8VH" + "RaE+/xZ7aswE89HXoumgggQAMIID/DCCA/gwggLgoAMCAQICAXUwDQYJKoZI" + "hvcNAQEFBQAwRTELMAkGA1UEBhMCVVMxFjAUBgNVBAoTDUdlb1RydXN0IElu" + "Yy4xHjAcBgNVBAMTFUdlb1RydXN0IENBIGZvciBBZG9iZTAeFw0wNDEyMDIy" + "MTI1MzlaFw0wNjEyMzAyMTI1MzlaMEwxCzAJBgNVBAYTAlVTMRUwEwYDVQQK" + "EwxHZW9UcnVzdCBJbmMxJjAkBgNVBAMTHUdlb1RydXN0IEFkb2JlIE9DU1Ag" + "UmVzcG9uZGVyMIGfMA0GCSqGSIb3DQEBAQUAA4GNADCBiQKBgQDiCc1iG3Dt" + "TpB5Vdk4OcaEcyP46BnQMHf3esSTprar2SrXb0gDZ7TfIoFN8l9BH1pYpzZC" + "P3R2xKo+O9MMcUZCxqCbYVC6GcDd9vVRaE/N4Qh2bpvEOydDydaoqrGdZnMQ" + "tlt2ncj1sEuLMiqhtmi/O3rQs0yCGf+6e++6Gl5VKwIDAQABo4IBbjCCAWow" + "DgYDVR0PAQH/BAQDAgTwMIHlBgNVHSABAf8EgdowgdcwgdQGCSqGSIb3LwEC" + "ATCBxjCBkAYIKwYBBQUHAgIwgYMagYBUaGlzIGNlcnRpZmljYXRlIGhhcyBi" + "ZWVuIGlzc3VlZCBpbiBhY2NvcmRhbmNlIHdpdGggdGhlIEFjcm9iYXQgQ3Jl" + "ZGVudGlhbHMgQ1BTIGxvY2F0ZWQgYXQgaHR0cDovL3d3dy5nZW90cnVzdC5j" + "b20vcmVzb3VyY2VzL2NwczAxBggrBgEFBQcCARYlaHR0cDovL3d3dy5nZW90" + "cnVzdC5jb20vcmVzb3VyY2VzL2NwczATBgNVHSUEDDAKBggrBgEFBQcDCTA6" + "BgNVHR8EMzAxMC+gLaArhilodHRwOi8vY3JsLmdlb3RydXN0LmNvbS9jcmxz" + "L2Fkb2JlY2ExLmNybDAfBgNVHSMEGDAWgBSrgFnDZYNtHX0TvRnD7BqPDUdq" + "ozANBgkqhkiG9w0BAQUFAAOCAQEAQ0l/UEPs9fmK+5prC33SrU4bNekhAv8K" + "XMR4VWY4jGo9zURMVGr3Zi7Eblvr5H6T60aSYLA8txjyKmDplxsn8CKtCGiH" + "OOUW5PpgBexN8SMKoRl9YzaxLtysrYRjEIyYoTfEN89yVi2sCjPupm/F9CPR" + "O7EdKy0dm/f3C7ZmIbUFaIRzINDJOCpM5cGhmZ8m2yG4BxeZOmCSthKtLfvM" + "2U9MaH6kxhDTJYNzw5BElHg5jlld92drTWaO0lM6aPr/pc+gs9hOraBCtzYE" + "J40nhsSEtvuwVUE9vA+unNMT8dFtAcOvOPRiKYPF45RX9Rdy2C9jAc20SRwE" + "uw6b+7K0xjANBgkqhkiG9w0BAQEFAASCAQC7a4yICFGCEMPlJbydK5qLG3rV" + "sip7Ojjz9TB4nLhC2DgsIHds8jjdq2zguInluH2nLaBCVS+qxDVlTjgbI2cB" + "TaWS8nglC7nNjzkKAsa8vThA8FZUVXTW0pb74jNJJU2AA27bb4g+4WgunCrj" + "fpYp+QjDyMmdrJVqRmt5eQN+dpVxMS9oq+NrhOSEhyIb4/rejgNg9wnVK1ms" + "l5PxQ4x7kpm7+Ua41//owkJVWykRo4T1jo4eHEz1DolPykAaKie2VKH/sMqR" + "Spjh4E5biKJLOV9fKivZWKAXByXfwUbbMsJvz4v/2yVHFy9xP+tqB5ZbRoDK" + "k8PzUyCprozn+/22oYIPijCCD4YGCyqGSIb3DQEJEAIOMYIPdTCCD3EGCSqG" + "SIb3DQEHAqCCD2Iwgg9eAgEDMQswCQYFKw4DAhoFADCB+gYLKoZIhvcNAQkQ" + "AQSggeoEgecwgeQCAQEGAikCMCEwCQYFKw4DAhoFAAQUoT97qeCv3FXYaEcS" + "gY8patCaCA8CAiMHGA8yMDA2MDQwNDIwMjA1N1owAwIBPAEB/wIIO0yRre3L" + "8/6ggZCkgY0wgYoxCzAJBgNVBAYTAlVTMRYwFAYDVQQIEw1NYXNzYWNodXNl" + "dHRzMRAwDgYDVQQHEwdOZWVkaGFtMRUwEwYDVQQKEwxHZW9UcnVzdCBJbmMx" + "EzARBgNVBAsTClByb2R1Y3Rpb24xJTAjBgNVBAMTHGFkb2JlLXRpbWVzdGFt" + "cC5nZW90cnVzdC5jb22gggzJMIIDUTCCAjmgAwIBAgICAI8wDQYJKoZIhvcN" + "AQEFBQAwRTELMAkGA1UEBhMCVVMxFjAUBgNVBAoTDUdlb1RydXN0IEluYy4x" + "HjAcBgNVBAMTFUdlb1RydXN0IENBIGZvciBBZG9iZTAeFw0wNTAxMTAwMTI5" + "MTBaFw0xNTAxMTUwODAwMDBaMIGKMQswCQYDVQQGEwJVUzEWMBQGA1UECBMN" + "TWFzc2FjaHVzZXR0czEQMA4GA1UEBxMHTmVlZGhhbTEVMBMGA1UEChMMR2Vv" + "VHJ1c3QgSW5jMRMwEQYDVQQLEwpQcm9kdWN0aW9uMSUwIwYDVQQDExxhZG9i" + "ZS10aW1lc3RhbXAuZ2VvdHJ1c3QuY29tMIGfMA0GCSqGSIb3DQEBAQUAA4GN" + "ADCBiQKBgQDRbxJotLFPWQuuEDhKtOMaBUJepGxIvWxeahMbq1DVmqnk88+j" + "w/5lfPICPzQZ1oHrcTLSAFM7Mrz3pyyQKQKMqUyiemzuG/77ESUNfBNSUfAF" + "PdtHuDMU8Is8ABVnFk63L+wdlvvDIlKkE08+VTKCRdjmuBVltMpQ6QcLFQzm" + "AQIDAQABo4GIMIGFMDoGA1UdHwQzMDEwL6AtoCuGKWh0dHA6Ly9jcmwuZ2Vv" + "dHJ1c3QuY29tL2NybHMvYWRvYmVjYTEuY3JsMB8GA1UdIwQYMBaAFKuAWcNl" + "g20dfRO9GcPsGo8NR2qjMA4GA1UdDwEB/wQEAwIGwDAWBgNVHSUBAf8EDDAK" + "BggrBgEFBQcDCDANBgkqhkiG9w0BAQUFAAOCAQEAmnyXjdtX+F79Nf0KggTd" + "6YC2MQD9s09IeXTd8TP3rBmizfM+7f3icggeCGakNfPRmIUMLoa0VM5Kt37T" + "2X0TqzBWusfbKx7HnX4v1t/G8NJJlT4SShSHv+8bjjU4lUoCmW2oEcC5vXwP" + "R5JfjCyois16npgcO05ZBT+LLDXyeBijE6qWmwLDfEpLyILzVRmyU4IE7jvm" + "rgb3GXwDUvd3yQXGRRHbPCh3nj9hBGbuzyt7GnlqnEie3wzIyMG2ET/wvTX5" + "4BFXKNe7lDLvZj/MXvd3V7gMTSVW0kAszKao56LfrVTgp1VX3UBQYwmQqaoA" + "UwFezih+jEvjW6cYJo/ErDCCBKEwggOJoAMCAQICBD4cvSgwDQYJKoZIhvcN" + "AQEFBQAwaTELMAkGA1UEBhMCVVMxIzAhBgNVBAoTGkFkb2JlIFN5c3RlbXMg" + "SW5jb3Jwb3JhdGVkMR0wGwYDVQQLExRBZG9iZSBUcnVzdCBTZXJ2aWNlczEW" + "MBQGA1UEAxMNQWRvYmUgUm9vdCBDQTAeFw0wMzAxMDgyMzM3MjNaFw0yMzAx" + "MDkwMDA3MjNaMGkxCzAJBgNVBAYTAlVTMSMwIQYDVQQKExpBZG9iZSBTeXN0" + "ZW1zIEluY29ycG9yYXRlZDEdMBsGA1UECxMUQWRvYmUgVHJ1c3QgU2Vydmlj" + "ZXMxFjAUBgNVBAMTDUFkb2JlIFJvb3QgQ0EwggEiMA0GCSqGSIb3DQEBAQUA" + "A4IBDwAwggEKAoIBAQDMT1SE96ei5zNTfz+cEohrLJlHZ34PHrmtFIj5wxDY" + "HfDw1Z9pCi9ZNbDMbKlMnBWgn84gv6DPVOLgIGZFPzmGOH6cxI4HIsYk9gES" + "sDXfVeppkLDbhTce4k4HskKhahNpoGbqgJERWSqbCHlaIEQtyb1zOIs8L+BD" + "G12zC/CvNRop/u+mkt2BTJ09WY6tMTxAfpuRNgb84lyN0Y0m1VxFz69lP7Gq" + "0mKW9Kg46rpgQvT0HEo1Fc74TiJWD5UYxfiWn5/7sLd4JemAa73WCvDGdJSd" + "8w9Q25p3zktwgyONoMp4IERcPFRk8eqiMBmf6kwGTQZ4S16S3yLSyWezetIB" + "AgMBAAGjggFPMIIBSzARBglghkgBhvhCAQEEBAMCAAcwgY4GA1UdHwSBhjCB" + "gzCBgKB+oHykejB4MQswCQYDVQQGEwJVUzEjMCEGA1UEChMaQWRvYmUgU3lz" + "dGVtcyBJbmNvcnBvcmF0ZWQxHTAbBgNVBAsTFEFkb2JlIFRydXN0IFNlcnZp" + "Y2VzMRYwFAYDVQQDEw1BZG9iZSBSb290IENBMQ0wCwYDVQQDEwRDUkwxMCsG" + "A1UdEAQkMCKADzIwMDMwMTA4MjMzNzIzWoEPMjAyMzAxMDkwMDA3MjNaMAsG" + "A1UdDwQEAwIBBjAfBgNVHSMEGDAWgBSCtzhKk6qbEO+Au9lU4vEP+4Cc3jAd" + "BgNVHQ4EFgQUgrc4SpOqmxDvgLvZVOLxD/uAnN4wDAYDVR0TBAUwAwEB/zAd" + "BgkqhkiG9n0HQQAEEDAOGwhWNi4wOjQuMAMCBJAwDQYJKoZIhvcNAQEFBQAD" + "ggEBADLan0N1wfpvyW/bqx02Nz68YRk2twI8HSNZmGye7k2F51TIIB+n1Lvi" + "vwB3fSRrcC9cwTp2SbXT4COEKnFqIvPBJymYFfY1kOQETMONvJ9hHOf9JIzR" + "REOMFrqbTaXUNS+8Ec6991E3jZ+Q5BTxGD++6VkSNfkzkvOe4NVrmnGbmUvI" + "ccPhsWEJxOX6kfBCOjd9NPly6M2qYhwh6dX0ghDjewW2LWhWC35+kixvTXKC" + "DO1WdLKduastKx0QX9sndXCP/R3X4gKgeeUc5f+vZEBRLZ6bR9tCpXwfwqZI" + "sNe+kmlNpPYpV8V4ERjch1HKE7JinU8rMr0xpcH6UqsFiMgwggTLMIIDs6AD" + "AgECAgQ+HL21MA0GCSqGSIb3DQEBBQUAMGkxCzAJBgNVBAYTAlVTMSMwIQYD" + "VQQKExpBZG9iZSBTeXN0ZW1zIEluY29ycG9yYXRlZDEdMBsGA1UECxMUQWRv" + "YmUgVHJ1c3QgU2VydmljZXMxFjAUBgNVBAMTDUFkb2JlIFJvb3QgQ0EwHhcN" + "MDQwMTE3MDAwMzM5WhcNMTUwMTE1MDgwMDAwWjBFMQswCQYDVQQGEwJVUzEW" + "MBQGA1UEChMNR2VvVHJ1c3QgSW5jLjEeMBwGA1UEAxMVR2VvVHJ1c3QgQ0Eg" + "Zm9yIEFkb2JlMIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEAp+V3" + "4GR4Wuc5hbyv0vVbKBMOVN1J+s5i9ZL9nph7n+X4esFs4epAJcFxJ4KnPuQH" + "ZZ0oyHUU4Th70mWYgKwd6sEt1aR6ZT788Nvr3OHwTRwugN/G6QXqhU9ePpZJ" + "OF1Ibsf1pcXNGvpLdcYK6+CX5DANMuIthb440XoNfC3dNBC0pF4mM4lmTjpl" + "nQG8xK0rIFp4HoMpmyaIijz2qyjXdUNkg0fbDUq9eDTKAOLOg21u+AA8XKbC" + "ewg1LWSV9CVy+fTHREmb1thBcrfkY1kCAvczsuquV3SMx8hRpa+4cIvKK/K1" + "G7OrV0nsTyuaJ2MMST8b7bul/Xd81nu9Hsz4iQIDAQABo4IBnTCCAZkwEgYD" + "VR0TAQH/BAgwBgEB/wIBATBQBgNVHSAESTBHMEUGCSqGSIb3LwECATA4MDYG" + "CCsGAQUFBwIBFipodHRwczovL3d3dy5hZG9iZS5jb20vbWlzYy9wa2kvY2Rz" + "X2NwLmh0bWwwFAYDVR0lBA0wCwYJKoZIhvcvAQEFMIGyBgNVHR8Egaowgacw" + "IqAgoB6GHGh0dHA6Ly9jcmwuYWRvYmUuY29tL2Nkcy5jcmwwgYCgfqB8pHow" + "eDELMAkGA1UEBhMCVVMxIzAhBgNVBAoTGkFkb2JlIFN5c3RlbXMgSW5jb3Jw" + "b3JhdGVkMR0wGwYDVQQLExRBZG9iZSBUcnVzdCBTZXJ2aWNlczEWMBQGA1UE" + "AxMNQWRvYmUgUm9vdCBDQTENMAsGA1UEAxMEQ1JMMTALBgNVHQ8EBAMCAQYw" + "HwYDVR0jBBgwFoAUgrc4SpOqmxDvgLvZVOLxD/uAnN4wHQYDVR0OBBYEFKuA" + "WcNlg20dfRO9GcPsGo8NR2qjMBkGCSqGSIb2fQdBAAQMMAobBFY2LjADAgSQ" + "MA0GCSqGSIb3DQEBBQUAA4IBAQA/OVkuogCOsV4RYSzS4Lb1jImGRc4T2Z/d" + "hJoUawhMX4aXWPSlqNOPIfhHflCvd+Whbarcd83NN5n3QmevUOFUREPrMQyA" + "mkK0mpW6TSyLG5ckeCFL8qJwp/hhckk/H16m4hEXWyIFGfOecX3Sy+Y4kxcC" + "lzSMadifedB+TiRpKFKcNphp5hEMkpyyJaGXpLnN/BLsaDyEN7JySExAopae" + "UbUJCvCVIWKwoJ26ih3BG1aB+3yTHXeLIorextqWbq+dVz7me59Li8j5PAxe" + "hXrc2phpKuhp8FaTScvnfMZc8TL4Dr1CHMRWIkqfZaCq3mC376Mww0iZtE5s" + "iqB+AXVWMYIBgDCCAXwCAQEwSzBFMQswCQYDVQQGEwJVUzEWMBQGA1UEChMN" + "R2VvVHJ1c3QgSW5jLjEeMBwGA1UEAxMVR2VvVHJ1c3QgQ0EgZm9yIEFkb2Jl" + "AgIAjzAJBgUrDgMCGgUAoIGMMBoGCSqGSIb3DQEJAzENBgsqhkiG9w0BCRAB" + "BDAcBgkqhkiG9w0BCQUxDxcNMDYwNDA0MjAyMDU3WjAjBgkqhkiG9w0BCQQx" + "FgQUp7AnXBqoNcarvO7fMJut1og2U5AwKwYLKoZIhvcNAQkQAgwxHDAaMBgw" + "FgQU1dH4eZTNhgxdiSABrat6zsPdth0wDQYJKoZIhvcNAQEBBQAEgYCinr/F" + "rMiQz/MRm9ZD5YGcC0Qo2dRTPd0Aop8mZ4g1xAhKFLnp7lLsjCbkSDpVLDBh" + "cnCk7CV+3FT5hlvt8OqZlR0CnkSnCswLFhrppiWle6cpxlwGqyAteC8uKtQu" + "wjE5GtBKLcCOAzQYyyuNZZeB6oCZ+3mPhZ62FxrvvEGJCgAAAAAAAAAAAAAA" + "AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA" + "AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA" + "AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA" + "AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA" + "AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA" + "AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA" + "AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA" + "AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA" + "AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA=="); private final byte[] emptyDNCert = Base64.decode( "MIICfTCCAeagAwIBAgIBajANBgkqhkiG9w0BAQQFADB8MQswCQYDVQQGEwJVUzEMMAoGA1UEChMD" + "Q0RXMQkwBwYDVQQLEwAxCTAHBgNVBAcTADEJMAcGA1UECBMAMRowGAYDVQQDExFUZW1wbGFyIFRl" + "c3QgMTAyNDEiMCAGCSqGSIb3DQEJARYTdGVtcGxhcnRlc3RAY2R3LmNvbTAeFw0wNjA1MjIwNTAw" + "MDBaFw0xMDA1MjIwNTAwMDBaMHwxCzAJBgNVBAYTAlVTMQwwCgYDVQQKEwNDRFcxCTAHBgNVBAsT" + "ADEJMAcGA1UEBxMAMQkwBwYDVQQIEwAxGjAYBgNVBAMTEVRlbXBsYXIgVGVzdCAxMDI0MSIwIAYJ" + "KoZIhvcNAQkBFhN0ZW1wbGFydGVzdEBjZHcuY29tMIGfMA0GCSqGSIb3DQEBAQUAA4GNADCBiQKB" + "gQDH3aJpJBfM+A3d84j5YcU6zEQaQ76u5xO9NSBmHjZykKS2kCcUqPpvVOPDA5WgV22dtKPh+lYV" + "iUp7wyCVwAKibq8HIbihHceFqMKzjwC639rMoDJ7bi/yzQWz1Zg+075a4FGPlUKn7Yfu89wKkjdW" + "wDpRPXc/agqBnrx5pJTXzQIDAQABow8wDTALBgNVHQ8EBAMCALEwDQYJKoZIhvcNAQEEBQADgYEA" + "RRsRsjse3i2/KClFVd6YLZ+7K1BE0WxFyY2bbytkwQJSxvv3vLSuweFUbhNxutb68wl/yW4GLy4b" + "1QdyswNxrNDXTuu5ILKhRDDuWeocz83aG2KGtr3JlFyr3biWGEyn5WUOE6tbONoQDJ0oPYgI6CAc" + "EHdUp0lioOCt6UOw7Cs="); private final byte[] gostRFC4491_94 = Base64.decode( "MIICCzCCAboCECMO42BGlSTOxwvklBgufuswCAYGKoUDAgIEMGkxHTAbBgNVBAMM" + "FEdvc3RSMzQxMC05NCBleGFtcGxlMRIwEAYDVQQKDAlDcnlwdG9Qcm8xCzAJBgNV" + "BAYTAlJVMScwJQYJKoZIhvcNAQkBFhhHb3N0UjM0MTAtOTRAZXhhbXBsZS5jb20w" + "HhcNMDUwODE2MTIzMjUwWhcNMTUwODE2MTIzMjUwWjBpMR0wGwYDVQQDDBRHb3N0" + "UjM0MTAtOTQgZXhhbXBsZTESMBAGA1UECgwJQ3J5cHRvUHJvMQswCQYDVQQGEwJS" + "VTEnMCUGCSqGSIb3DQEJARYYR29zdFIzNDEwLTk0QGV4YW1wbGUuY29tMIGlMBwG" + "BiqFAwICFDASBgcqhQMCAiACBgcqhQMCAh4BA4GEAASBgLuEZuF5nls02CyAfxOo" + "GWZxV/6MVCUhR28wCyd3RpjG+0dVvrey85NsObVCNyaE4g0QiiQOHwxCTSs7ESuo" + "v2Y5MlyUi8Go/htjEvYJJYfMdRv05YmKCYJo01x3pg+2kBATjeM+fJyR1qwNCCw+" + "eMG1wra3Gqgqi0WBkzIydvp7MAgGBiqFAwICBANBABHHCH4S3ALxAiMpR3aPRyqB" + "g1DjB8zy5DEjiULIc+HeIveF81W9lOxGkZxnrFjXBSqnjLeFKgF1hffXOAP7zUM="); private final byte[] gostRFC4491_2001 = Base64.decode( "MIIB0DCCAX8CECv1xh7CEb0Xx9zUYma0LiEwCAYGKoUDAgIDMG0xHzAdBgNVBAMM" + "Fkdvc3RSMzQxMC0yMDAxIGV4YW1wbGUxEjAQBgNVBAoMCUNyeXB0b1BybzELMAkG" + "A1UEBhMCUlUxKTAnBgkqhkiG9w0BCQEWGkdvc3RSMzQxMC0yMDAxQGV4YW1wbGUu" + "Y29tMB4XDTA1MDgxNjE0MTgyMFoXDTE1MDgxNjE0MTgyMFowbTEfMB0GA1UEAwwW" + "R29zdFIzNDEwLTIwMDEgZXhhbXBsZTESMBAGA1UECgwJQ3J5cHRvUHJvMQswCQYD" + "VQQGEwJSVTEpMCcGCSqGSIb3DQEJARYaR29zdFIzNDEwLTIwMDFAZXhhbXBsZS5j" + "b20wYzAcBgYqhQMCAhMwEgYHKoUDAgIkAAYHKoUDAgIeAQNDAARAhJVodWACGkB1" + "CM0TjDGJLP3lBQN6Q1z0bSsP508yfleP68wWuZWIA9CafIWuD+SN6qa7flbHy7Df" + "D2a8yuoaYDAIBgYqhQMCAgMDQQA8L8kJRLcnqeyn1en7U23Sw6pkfEQu3u0xFkVP" + "vFQ/3cHeF26NG+xxtZPz3TaTVXdoiYkXYiD02rEx1bUcM97i"); private PublicKey dudPublicKey = new PublicKey() { public String getAlgorithm() { return null; } public String getFormat() { return null; } public byte[] getEncoded() { return null; } }; public String getName() { return "CertTest"; } public void checkCertificate( int id, byte[] bytes) { ByteArrayInputStream bIn; String dump = ""; try { bIn = new ByteArrayInputStream(bytes); CertificateFactory fact = CertificateFactory.getInstance("X.509", "BC"); Certificate cert = fact.generateCertificate(bIn); PublicKey k = cert.getPublicKey(); // System.out.println(cert); } catch (Exception e) { fail(dump + System.getProperty("line.separator") + getName() + ": "+ id + " failed - exception " + e.toString(), e); } } public void checkNameCertificate( int id, byte[] bytes) { ByteArrayInputStream bIn; String dump = ""; try { bIn = new ByteArrayInputStream(bytes); CertificateFactory fact = CertificateFactory.getInstance("X.509", "BC"); X509Certificate cert = (X509Certificate)fact.generateCertificate(bIn); PublicKey k = cert.getPublicKey(); if (!cert.getIssuerDN().toString().equals("C=DE,O=DATEV eG,0.2.262.1.10.7.20=1+CN=CA DATEV D03 1:PN")) { fail(id + " failed - name test."); } // System.out.println(cert); } catch (Exception e) { fail(dump + System.getProperty("line.separator") + getName() + ": "+ id + " failed - exception " + e.toString(), e); } } public void checkKeyUsage( int id, byte[] bytes) { ByteArrayInputStream bIn; String dump = ""; try { bIn = new ByteArrayInputStream(bytes); CertificateFactory fact = CertificateFactory.getInstance("X.509", "BC"); X509Certificate cert = (X509Certificate)fact.generateCertificate(bIn); PublicKey k = cert.getPublicKey(); if (cert.getKeyUsage()[7]) { fail("error generating cert - key usage wrong."); } // System.out.println(cert); } catch (Exception e) { fail(dump + System.getProperty("line.separator") + getName() + ": "+ id + " failed - exception " + e.toString(), e); } } public void checkSelfSignedCertificate( int id, byte[] bytes) { ByteArrayInputStream bIn; String dump = ""; try { bIn = new ByteArrayInputStream(bytes); CertificateFactory fact = CertificateFactory.getInstance("X.509", "BC"); Certificate cert = fact.generateCertificate(bIn); PublicKey k = cert.getPublicKey(); cert.verify(k); // System.out.println(cert); } catch (Exception e) { fail(dump + System.getProperty("line.separator") + getName() + ": "+ id + " failed - exception " + e.toString(), e); } } /** * Test a generated certificate with the sun provider */ private void sunProviderCheck(byte[] encoding) throws CertificateException { CertificateFactory certFact = CertificateFactory.getInstance("X.509"); certFact.generateCertificate(new ByteArrayInputStream(encoding)); } /** * we generate a self signed certificate for the sake of testing - RSA */ public void checkCreation1() throws Exception { // // a sample key pair. // RSAPublicKeySpec pubKeySpec = new RSAPublicKeySpec( new BigInteger("b4a7e46170574f16a97082b22be58b6a2a629798419be12872a4bdba626cfae9900f76abfb12139dce5de56564fab2b6543165a040c606887420e33d91ed7ed7", 16), new BigInteger("11", 16)); RSAPrivateCrtKeySpec privKeySpec = new RSAPrivateCrtKeySpec( new BigInteger("b4a7e46170574f16a97082b22be58b6a2a629798419be12872a4bdba626cfae9900f76abfb12139dce5de56564fab2b6543165a040c606887420e33d91ed7ed7", 16), new BigInteger("11", 16), new BigInteger("9f66f6b05410cd503b2709e88115d55daced94d1a34d4e32bf824d0dde6028ae79c5f07b580f5dce240d7111f7ddb130a7945cd7d957d1920994da389f490c89", 16), new BigInteger("c0a0758cdf14256f78d4708c86becdead1b50ad4ad6c5c703e2168fbf37884cb", 16), new BigInteger("f01734d7960ea60070f1b06f2bb81bfac48ff192ae18451d5e56c734a5aab8a5", 16), new BigInteger("b54bb9edff22051d9ee60f9351a48591b6500a319429c069a3e335a1d6171391", 16), new BigInteger("d3d83daf2a0cecd3367ae6f8ae1aeb82e9ac2f816c6fc483533d8297dd7884cd", 16), new BigInteger("b8f52fc6f38593dabb661d3f50f8897f8106eee68b1bce78a95b132b4e5b5d19", 16)); // // set up the keys // PrivateKey privKey; PublicKey pubKey; KeyFactory fact = KeyFactory.getInstance("RSA", "BC"); privKey = fact.generatePrivate(privKeySpec); pubKey = fact.generatePublic(pubKeySpec); // // distinguished name table. // X500NameBuilder builder = new X500NameBuilder(BCStyle.INSTANCE); builder.addRDN(BCStyle.C, "AU"); builder.addRDN(BCStyle.O, "The Legion of the Bouncy Castle"); builder.addRDN(BCStyle.L, "Melbourne"); builder.addRDN(BCStyle.ST, "Victoria"); builder.addRDN(BCStyle.E, "feedback-crypto@bouncycastle.org"); // // extensions // // // create the certificate - version 3 - without extensions // ContentSigner sigGen = new JcaContentSignerBuilder("SHA256WithRSAEncryption").setProvider(BC).build(privKey); X509v3CertificateBuilder certGen = new JcaX509v3CertificateBuilder(builder.build(), BigInteger.valueOf(1), new Date(System.currentTimeMillis() - 50000), new Date(System.currentTimeMillis() + 50000),builder.build(), pubKey); X509Certificate cert = new JcaX509CertificateConverter().setProvider(BC).getCertificate(certGen.build(sigGen)); cert.checkValidity(new Date()); cert.verify(pubKey); cert.verify(cert.getPublicKey()); Set dummySet = cert.getNonCriticalExtensionOIDs(); if (dummySet != null) { fail("non-critical oid set should be null"); } dummySet = cert.getCriticalExtensionOIDs(); if (dummySet != null) { fail("critical oid set should be null"); } // // create the certificate - version 3 - with extensions // sigGen = new JcaContentSignerBuilder("MD5WithRSAEncryption").setProvider(BC).build(privKey); certGen = new JcaX509v3CertificateBuilder(builder.build(), BigInteger.valueOf(1) , new Date(System.currentTimeMillis() - 50000) , new Date(System.currentTimeMillis() + 50000) , builder.build() , pubKey) .addExtension(new ASN1ObjectIdentifier("2.5.29.15"), true, new X509KeyUsage(X509KeyUsage.encipherOnly)) .addExtension(new ASN1ObjectIdentifier("2.5.29.37"), true, new DERSequence(KeyPurposeId.anyExtendedKeyUsage)) .addExtension(new ASN1ObjectIdentifier("2.5.29.17"), true, new GeneralNames(new GeneralName[] { new GeneralName(GeneralName.rfc822Name, "test@test.test"), new GeneralName(GeneralName.dNSName, "dom.test.test") })); X509CertificateHolder certHolder = certGen.build(sigGen); cert = new JcaX509CertificateConverter().setProvider(BC).getCertificate(certHolder); cert.checkValidity(new Date()); cert.verify(pubKey); cert.verify(cert.getPublicKey()); ContentVerifierProvider contentVerifierProvider = new JcaContentVerifierProviderBuilder().setProvider(BC).build(pubKey); if (!certHolder.isSignatureValid(contentVerifierProvider)) { fail("signature test failed"); } ByteArrayInputStream bIn = new ByteArrayInputStream(cert.getEncoded()); CertificateFactory certFact = CertificateFactory.getInstance("X.509", "BC"); cert = (X509Certificate)certFact.generateCertificate(bIn); if (!cert.getKeyUsage()[7]) { fail("error generating cert - key usage wrong."); } List l = cert.getExtendedKeyUsage(); if (!l.get(0).equals(KeyPurposeId.anyExtendedKeyUsage.getId())) { fail("failed extended key usage test"); } Collection c = cert.getSubjectAlternativeNames(); Iterator it = c.iterator(); while (it.hasNext()) { List gn = (List)it.next(); if (!gn.get(1).equals("test@test.test") && !gn.get(1).equals("dom.test.test")) { fail("failed subject alternative names test"); } } sunProviderCheck(certHolder.getEncoded()); sunProviderCheck(cert.getEncoded()); // System.out.println(cert); // // create the certificate - version 1 // sigGen = new JcaContentSignerBuilder("MD5WithRSAEncryption").setProvider(BC).build(privKey); X509v1CertificateBuilder certGen1 = new JcaX509v1CertificateBuilder(builder.build(), BigInteger.valueOf(1), new Date(System.currentTimeMillis() - 50000),new Date(System.currentTimeMillis() + 50000),builder.build(),pubKey); cert = new JcaX509CertificateConverter().setProvider(BC).getCertificate(certGen1.build(sigGen)); cert.checkValidity(new Date()); cert.verify(pubKey); cert.verify(cert.getPublicKey()); bIn = new ByteArrayInputStream(cert.getEncoded()); certFact = CertificateFactory.getInstance("X.509", "BC"); cert = (X509Certificate)certFact.generateCertificate(bIn); // System.out.println(cert); if (!cert.getIssuerDN().equals(cert.getSubjectDN())) { fail("name comparison fails"); } sunProviderCheck(certHolder.getEncoded()); sunProviderCheck(cert.getEncoded()); // // a lightweight key pair. // RSAKeyParameters lwPubKey = new RSAKeyParameters( false, new BigInteger("b4a7e46170574f16a97082b22be58b6a2a629798419be12872a4bdba626cfae9900f76abfb12139dce5de56564fab2b6543165a040c606887420e33d91ed7ed7", 16), new BigInteger("11", 16)); RSAPrivateCrtKeyParameters lwPrivKey = new RSAPrivateCrtKeyParameters( new BigInteger("b4a7e46170574f16a97082b22be58b6a2a629798419be12872a4bdba626cfae9900f76abfb12139dce5de56564fab2b6543165a040c606887420e33d91ed7ed7", 16), new BigInteger("11", 16), new BigInteger("9f66f6b05410cd503b2709e88115d55daced94d1a34d4e32bf824d0dde6028ae79c5f07b580f5dce240d7111f7ddb130a7945cd7d957d1920994da389f490c89", 16), new BigInteger("c0a0758cdf14256f78d4708c86becdead1b50ad4ad6c5c703e2168fbf37884cb", 16), new BigInteger("f01734d7960ea60070f1b06f2bb81bfac48ff192ae18451d5e56c734a5aab8a5", 16), new BigInteger("b54bb9edff22051d9ee60f9351a48591b6500a319429c069a3e335a1d6171391", 16), new BigInteger("d3d83daf2a0cecd3367ae6f8ae1aeb82e9ac2f816c6fc483533d8297dd7884cd", 16), new BigInteger("b8f52fc6f38593dabb661d3f50f8897f8106eee68b1bce78a95b132b4e5b5d19", 16)); // // distinguished name table. // builder = new X500NameBuilder(BCStyle.INSTANCE); builder.addRDN(BCStyle.C, "AU"); builder.addRDN(BCStyle.O, "The Legion of the Bouncy Castle"); builder.addRDN(BCStyle.L, "Melbourne"); builder.addRDN(BCStyle.ST, "Victoria"); builder.addRDN(BCStyle.E, "feedback-crypto@bouncycastle.org"); // // extensions // // // create the certificate - version 3 - without extensions // AlgorithmIdentifier sigAlgId = new DefaultSignatureAlgorithmIdentifierFinder().find("SHA256WithRSAEncryption"); AlgorithmIdentifier digAlgId = new DefaultDigestAlgorithmIdentifierFinder().find(sigAlgId); sigGen = new BcRSAContentSignerBuilder(sigAlgId, digAlgId).build(lwPrivKey); SubjectPublicKeyInfo pubInfo = new SubjectPublicKeyInfo(new AlgorithmIdentifier(PKCSObjectIdentifiers.rsaEncryption, DERNull.INSTANCE), new RSAPublicKey(lwPubKey.getModulus(), lwPubKey.getExponent())); certGen = new X509v3CertificateBuilder(builder.build(), BigInteger.valueOf(1), new Date(System.currentTimeMillis() - 50000), new Date(System.currentTimeMillis() + 50000), builder.build(), pubInfo); certHolder = certGen.build(sigGen); cert = new JcaX509CertificateConverter().setProvider(BC).getCertificate(certHolder); cert.checkValidity(new Date()); cert.verify(pubKey); contentVerifierProvider = new BcRSAContentVerifierProviderBuilder(new DefaultDigestAlgorithmIdentifierFinder()).build(lwPubKey); if (!certHolder.isSignatureValid(contentVerifierProvider)) { fail("lw sig verification failed"); } } /** * we generate a self signed certificate for the sake of testing - DSA */ public void checkCreation2() throws Exception { // // set up the keys // PrivateKey privKey; PublicKey pubKey; try { KeyPairGenerator g = KeyPairGenerator.getInstance("DSA", "SUN"); g.initialize(512, new SecureRandom()); KeyPair p = g.generateKeyPair(); privKey = p.getPrivate(); pubKey = p.getPublic(); } catch (Exception e) { fail("error setting up keys - " + e.toString()); return; } // // distinguished name table. // X500NameBuilder builder = createStdBuilder(); // // extensions // // // create the certificate - version 3 // ContentSigner sigGen = new JcaContentSignerBuilder("SHA1withDSA").setProvider(BC).build(privKey); JcaX509v3CertificateBuilder certGen = new JcaX509v3CertificateBuilder(builder.build(),BigInteger.valueOf(1),new Date(System.currentTimeMillis() - 50000),new Date(System.currentTimeMillis() + 50000),builder.build(),pubKey); X509Certificate cert = new JcaX509CertificateConverter().setProvider(BC).getCertificate(certGen.build(sigGen)); cert.checkValidity(new Date()); cert.verify(pubKey); ByteArrayInputStream bIn = new ByteArrayInputStream(cert.getEncoded()); CertificateFactory fact = CertificateFactory.getInstance("X.509", BC); cert = (X509Certificate)fact.generateCertificate(bIn); // System.out.println(cert); // // create the certificate - version 1 // sigGen = new JcaContentSignerBuilder("SHA1withDSA").setProvider(BC).build(privKey); JcaX509v1CertificateBuilder certGen1 = new JcaX509v1CertificateBuilder(builder.build(),BigInteger.valueOf(1),new Date(System.currentTimeMillis() - 50000),new Date(System.currentTimeMillis() + 50000),builder.build(),pubKey); cert = new JcaX509CertificateConverter().setProvider(BC).getCertificate(certGen1.build(sigGen)); cert.checkValidity(new Date()); cert.verify(pubKey); bIn = new ByteArrayInputStream(cert.getEncoded()); fact = CertificateFactory.getInstance("X.509", BC); cert = (X509Certificate)fact.generateCertificate(bIn); //System.out.println(cert); // // exception test // try { certGen1 = new JcaX509v1CertificateBuilder(builder.build(),BigInteger.valueOf(1),new Date(System.currentTimeMillis() - 50000),new Date(System.currentTimeMillis() + 50000),builder.build(),dudPublicKey); fail("key without encoding not detected in v1"); } catch (IllegalArgumentException e) { // expected } } private X500NameBuilder createStdBuilder() { X500NameBuilder builder = new X500NameBuilder(BCStyle.INSTANCE); builder.addRDN(BCStyle.C, "AU"); builder.addRDN(BCStyle.O, "The Legion of the Bouncy Castle"); builder.addRDN(BCStyle.L, "Melbourne"); builder.addRDN(BCStyle.ST, "Victoria"); builder.addRDN(BCStyle.E, "feedback-crypto@bouncycastle.org"); return builder; } /** * we generate a self signed certificate for the sake of testing - ECDSA */ public void checkCreation3() { ECCurve curve = new ECCurve.Fp( new BigInteger("883423532389192164791648750360308885314476597252960362792450860609699839"), // q new BigInteger("7fffffffffffffffffffffff7fffffffffff8000000000007ffffffffffc", 16), // a new BigInteger("6b016c3bdcf18941d0d654921475ca71a9db2fb27d1d37796185c2942c0a", 16)); // b ECParameterSpec spec = new ECParameterSpec( curve, curve.decodePoint(Hex.decode("020ffa963cdca8816ccc33b8642bedf905c3d358573d3f27fbbd3b3cb9aaaf")), // G new BigInteger("883423532389192164791648750360308884807550341691627752275345424702807307")); // n ECPrivateKeySpec privKeySpec = new ECPrivateKeySpec( new BigInteger("876300101507107567501066130761671078357010671067781776716671676178726717"), // d spec); ECPublicKeySpec pubKeySpec = new ECPublicKeySpec( curve.decodePoint(Hex.decode("025b6dc53bc61a2548ffb0f671472de6c9521a9d2d2534e65abfcbd5fe0c70")), // Q spec); // // set up the keys // PrivateKey privKey; PublicKey pubKey; try { KeyFactory fact = KeyFactory.getInstance("ECDSA", BC); privKey = fact.generatePrivate(privKeySpec); pubKey = fact.generatePublic(pubKeySpec); } catch (Exception e) { fail("error setting up keys - " + e.toString()); return; } // // distinguished name table. // X500NameBuilder builder = createStdBuilder(); // // toString test // X500Name p = builder.build(); String s = p.toString(); if (!s.equals("C=AU,O=The Legion of the Bouncy Castle,L=Melbourne,ST=Victoria,E=feedback-crypto@bouncycastle.org")) { fail("ordered X509Principal test failed - s = " + s + "."); } // p = new X509Principal(attrs); // s = p.toString(); // // // // // we need two of these as the hash code for strings changed... // // // if (!s.equals("O=The Legion of the Bouncy Castle,E=feedback-crypto@bouncycastle.org,ST=Victoria,L=Melbourne,C=AU") && !s.equals("ST=Victoria,L=Melbourne,C=AU,E=feedback-crypto@bouncycastle.org,O=The Legion of the Bouncy Castle")) // { // fail("unordered X509Principal test failed."); // } // // create the certificate - version 3 // try { ContentSigner sigGen = new JcaContentSignerBuilder("SHA1withECDSA").setProvider(BC).build(privKey); JcaX509v3CertificateBuilder certGen = new JcaX509v3CertificateBuilder(builder.build(),BigInteger.valueOf(1),new Date(System.currentTimeMillis() - 50000),new Date(System.currentTimeMillis() + 50000),builder.build(),pubKey); X509Certificate cert = new JcaX509CertificateConverter().setProvider(BC).getCertificate(certGen.build(sigGen)); cert.checkValidity(new Date()); cert.verify(pubKey); ByteArrayInputStream bIn = new ByteArrayInputStream(cert.getEncoded()); CertificateFactory fact = CertificateFactory.getInstance("X.509", BC); cert = (X509Certificate)fact.generateCertificate(bIn); // // try with point compression turned off // ((ECPointEncoder)pubKey).setPointFormat("UNCOMPRESSED"); certGen = new JcaX509v3CertificateBuilder(builder.build(),BigInteger.valueOf(1),new Date(System.currentTimeMillis() - 50000),new Date(System.currentTimeMillis() + 50000),builder.build(),pubKey); cert = new JcaX509CertificateConverter().setProvider(BC).getCertificate(certGen.build(sigGen)); cert.checkValidity(new Date()); cert.verify(pubKey); bIn = new ByteArrayInputStream(cert.getEncoded()); fact = CertificateFactory.getInstance("X.509", BC); cert = (X509Certificate)fact.generateCertificate(bIn); // System.out.println(cert); } catch (Exception e) { fail("error setting generating cert - " + e.toString()); } X509Principal pr = new X509Principal("O=\"The Bouncy Castle, The Legion of\",E=feedback-crypto@bouncycastle.org,ST=Victoria,L=Melbourne,C=AU"); if (!pr.toString().equals("O=The Bouncy Castle\\, The Legion of,E=feedback-crypto@bouncycastle.org,ST=Victoria,L=Melbourne,C=AU")) { fail("string based X509Principal test failed."); } pr = new X509Principal("O=The Bouncy Castle\\, The Legion of,E=feedback-crypto@bouncycastle.org,ST=Victoria,L=Melbourne,C=AU"); if (!pr.toString().equals("O=The Bouncy Castle\\, The Legion of,E=feedback-crypto@bouncycastle.org,ST=Victoria,L=Melbourne,C=AU")) { fail("string based X509Principal test failed."); } } /** * we generate a self signed certificate for the sake of testing - SHA224withECDSA */ private void createECCert(String algorithm, DERObjectIdentifier algOid) throws Exception { ECCurve.Fp curve = new ECCurve.Fp( new BigInteger("6864797660130609714981900799081393217269435300143305409394463459185543183397656052122559640661454554977296311391480858037121987999716643812574028291115057151"), // q (or p) new BigInteger("01FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFC", 16), // a new BigInteger("0051953EB9618E1C9A1F929A21A0B68540EEA2DA725B99B315F3B8B489918EF109E156193951EC7E937B1652C0BD3BB1BF073573DF883D2C34F1EF451FD46B503F00", 16)); // b ECParameterSpec spec = new ECParameterSpec( curve, curve.decodePoint(Hex.decode("0200C6858E06B70404E9CD9E3ECB662395B4429C648139053FB521F828AF606B4D3DBAA14B5E77EFE75928FE1DC127A2FFA8DE3348B3C1856A429BF97E7E31C2E5BD66")), // G new BigInteger("01FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFA51868783BF2F966B7FCC0148F709A5D03BB5C9B8899C47AEBB6FB71E91386409", 16)); // n ECPrivateKeySpec privKeySpec = new ECPrivateKeySpec( new BigInteger("5769183828869504557786041598510887460263120754767955773309066354712783118202294874205844512909370791582896372147797293913785865682804434049019366394746072023"), // d spec); ECPublicKeySpec pubKeySpec = new ECPublicKeySpec( curve.decodePoint(Hex.decode("02006BFDD2C9278B63C92D6624F151C9D7A822CC75BD983B17D25D74C26740380022D3D8FAF304781E416175EADF4ED6E2B47142D2454A7AC7801DD803CF44A4D1F0AC")), // Q spec); // // set up the keys // PrivateKey privKey; PublicKey pubKey; KeyFactory fact = KeyFactory.getInstance("ECDSA", BC); privKey = fact.generatePrivate(privKeySpec); pubKey = fact.generatePublic(pubKeySpec); // // distinguished name table. // X500NameBuilder builder = createStdBuilder(); // // create the certificate - version 3 // ContentSigner sigGen = new JcaContentSignerBuilder(algorithm).setProvider(BC).build(privKey); X509v3CertificateBuilder certGen = new JcaX509v3CertificateBuilder(builder.build(),BigInteger.valueOf(1),new Date(System.currentTimeMillis() - 50000),new Date(System.currentTimeMillis() + 50000),builder.build(),pubKey); X509Certificate cert = new JcaX509CertificateConverter().setProvider(BC).getCertificate(certGen.build(sigGen)); cert.checkValidity(new Date()); cert.verify(pubKey); ByteArrayInputStream bIn = new ByteArrayInputStream(cert.getEncoded()); CertificateFactory certFact = CertificateFactory.getInstance("X.509", BC); cert = (X509Certificate)certFact.generateCertificate(bIn); // // try with point compression turned off // ((ECPointEncoder)pubKey).setPointFormat("UNCOMPRESSED"); certGen = new JcaX509v3CertificateBuilder(builder.build(),BigInteger.valueOf(1),new Date(System.currentTimeMillis() - 50000),new Date(System.currentTimeMillis() + 50000),builder.build(),pubKey); cert = new JcaX509CertificateConverter().setProvider(BC).getCertificate(certGen.build(sigGen)); cert.checkValidity(new Date()); cert.verify(pubKey); bIn = new ByteArrayInputStream(cert.getEncoded()); certFact = CertificateFactory.getInstance("X.509", BC); cert = (X509Certificate)certFact.generateCertificate(bIn); if (!cert.getSigAlgOID().equals(algOid.toString())) { fail("ECDSA oid incorrect."); } if (cert.getSigAlgParams() != null) { fail("sig parameters present"); } Signature sig = Signature.getInstance(algorithm, BC); sig.initVerify(pubKey); sig.update(cert.getTBSCertificate()); if (!sig.verify(cert.getSignature())) { fail("EC certificate signature not mapped correctly."); } // System.out.println(cert); } private void checkCRL( int id, byte[] bytes) { ByteArrayInputStream bIn; String dump = ""; try { bIn = new ByteArrayInputStream(bytes); CertificateFactory fact = CertificateFactory.getInstance("X.509", BC); CRL cert = fact.generateCRL(bIn); // System.out.println(cert); } catch (Exception e) { fail(dump + System.getProperty("line.separator") + getName() + ": "+ id + " failed - exception " + e.toString(), e); } } public void checkCRLCreation1() throws Exception { KeyPairGenerator kpGen = KeyPairGenerator.getInstance("RSA", BC); Date now = new Date(); KeyPair pair = kpGen.generateKeyPair(); X509v2CRLBuilder crlGen = new X509v2CRLBuilder(new X500Name("CN=Test CA"), now); crlGen.setNextUpdate(new Date(now.getTime() + 100000)); crlGen.addCRLEntry(BigInteger.ONE, now, CRLReason.privilegeWithdrawn); crlGen.addExtension(X509Extensions.AuthorityKeyIdentifier, false, new AuthorityKeyIdentifierStructure(pair.getPublic())); X509CRLHolder crl = crlGen.build(new JcaContentSignerBuilder("SHA256withRSAEncryption").setProvider(BC).build(pair.getPrivate())); if (!crl.getIssuer().equals(new X500Name("CN=Test CA"))) { fail("failed CRL issuer test"); } Extension authExt = crl.getExtension(Extension.authorityKeyIdentifier); if (authExt == null) { fail("failed to find CRL extension"); } AuthorityKeyIdentifier authId = new AuthorityKeyIdentifierStructure(authExt); X509CRLEntryHolder entry = crl.getRevokedCertificate(BigInteger.ONE); if (entry == null) { fail("failed to find CRL entry"); } if (!entry.getSerialNumber().equals(BigInteger.ONE)) { fail("CRL cert serial number does not match"); } if (!entry.hasExtensions()) { fail("CRL entry extension not found"); } Extension ext = entry.getExtension(X509Extension.reasonCode); if (ext != null) { ASN1Enumerated reasonCode = (ASN1Enumerated)ASN1Enumerated.getInstance(ext.getParsedValue()); if (reasonCode.getValue().intValue() != CRLReason.privilegeWithdrawn) { fail("CRL entry reasonCode wrong"); } } else { fail("CRL entry reasonCode not found"); } } public void checkCRLCreation2() throws Exception { KeyPairGenerator kpGen = KeyPairGenerator.getInstance("RSA", BC); Date now = new Date(); KeyPair pair = kpGen.generateKeyPair(); X509v2CRLBuilder crlGen = new JcaX509v2CRLBuilder(new X500Principal("CN=Test CA"), now); crlGen.setNextUpdate(new Date(now.getTime() + 100000)); Vector extOids = new Vector(); Vector extValues = new Vector(); CRLReason crlReason = CRLReason.lookup(CRLReason.privilegeWithdrawn); try { extOids.addElement(X509Extensions.ReasonCode); extValues.addElement(new X509Extension(false, new DEROctetString(crlReason.getEncoded()))); } catch (IOException e) { throw new IllegalArgumentException("error encoding reason: " + e); } X509Extensions entryExtensions = new X509Extensions(extOids, extValues); crlGen.addCRLEntry(BigInteger.ONE, now, entryExtensions); crlGen.addExtension(X509Extensions.AuthorityKeyIdentifier, false, new AuthorityKeyIdentifierStructure(pair.getPublic())); X509CRLHolder crlHolder = crlGen.build(new JcaContentSignerBuilder("SHA256withRSAEncryption").setProvider(BC).build(pair.getPrivate())); X509CRL crl = new JcaX509CRLConverter().setProvider(BC).getCRL(crlHolder); if (!crl.getIssuerX500Principal().equals(new X500Principal("CN=Test CA"))) { fail("failed CRL issuer test"); } byte[] authExt = crl.getExtensionValue(X509Extensions.AuthorityKeyIdentifier.getId()); if (authExt == null) { fail("failed to find CRL extension"); } AuthorityKeyIdentifier authId = new AuthorityKeyIdentifierStructure(authExt); X509CRLEntry entry = crl.getRevokedCertificate(BigInteger.ONE); if (entry == null) { fail("failed to find CRL entry"); } if (!entry.getSerialNumber().equals(BigInteger.ONE)) { fail("CRL cert serial number does not match"); } if (!entry.hasExtensions()) { fail("CRL entry extension not found"); } byte[] ext = entry.getExtensionValue(X509Extensions.ReasonCode.getId()); if (ext != null) { DEREnumerated reasonCode = (DEREnumerated)X509ExtensionUtil.fromExtensionValue(ext); if (reasonCode.getValue().intValue() != CRLReason.privilegeWithdrawn) { fail("CRL entry reasonCode wrong"); } } else { fail("CRL entry reasonCode not found"); } } public void checkCRLCreation3() throws Exception { KeyPairGenerator kpGen = KeyPairGenerator.getInstance("RSA", BC); Date now = new Date(); KeyPair pair = kpGen.generateKeyPair(); X509v2CRLBuilder crlGen = new JcaX509v2CRLBuilder(new X500Principal("CN=Test CA"), now); crlGen.setNextUpdate(new Date(now.getTime() + 100000)); Vector extOids = new Vector(); Vector extValues = new Vector(); CRLReason crlReason = CRLReason.lookup(CRLReason.privilegeWithdrawn); try { extOids.addElement(X509Extensions.ReasonCode); extValues.addElement(new X509Extension(false, new DEROctetString(crlReason.getEncoded()))); } catch (IOException e) { throw new IllegalArgumentException("error encoding reason: " + e); } X509Extensions entryExtensions = new X509Extensions(extOids, extValues); crlGen.addCRLEntry(BigInteger.ONE, now, entryExtensions); crlGen.addExtension(X509Extensions.AuthorityKeyIdentifier, false, new AuthorityKeyIdentifierStructure(pair.getPublic())); X509CRLHolder crlHolder = crlGen.build(new JcaContentSignerBuilder("SHA256withRSAEncryption").setProvider(BC).build(pair.getPrivate())); X509CRL crl = new JcaX509CRLConverter().setProvider(BC).getCRL(crlHolder); if (!crl.getIssuerX500Principal().equals(new X500Principal("CN=Test CA"))) { fail("failed CRL issuer test"); } byte[] authExt = crl.getExtensionValue(X509Extensions.AuthorityKeyIdentifier.getId()); if (authExt == null) { fail("failed to find CRL extension"); } AuthorityKeyIdentifier authId = new AuthorityKeyIdentifierStructure(authExt); X509CRLEntry entry = crl.getRevokedCertificate(BigInteger.ONE); if (entry == null) { fail("failed to find CRL entry"); } if (!entry.getSerialNumber().equals(BigInteger.ONE)) { fail("CRL cert serial number does not match"); } if (!entry.hasExtensions()) { fail("CRL entry extension not found"); } byte[] ext = entry.getExtensionValue(X509Extensions.ReasonCode.getId()); if (ext != null) { DEREnumerated reasonCode = (DEREnumerated)X509ExtensionUtil.fromExtensionValue(ext); if (reasonCode.getValue().intValue() != CRLReason.privilegeWithdrawn) { fail("CRL entry reasonCode wrong"); } } else { fail("CRL entry reasonCode not found"); } // // check loading of existing CRL // now = new Date(); crlGen = new X509v2CRLBuilder(new X500Name("CN=Test CA"), now); crlGen.setNextUpdate(new Date(now.getTime() + 100000)); crlGen.addCRL(new JcaX509CRLHolder(crl)); crlGen.addCRLEntry(BigInteger.valueOf(2), now, entryExtensions); crlGen.addExtension(X509Extension.authorityKeyIdentifier, false, new AuthorityKeyIdentifierStructure(pair.getPublic())); crlHolder = crlGen.build(new JcaContentSignerBuilder("SHA256withRSAEncryption").setProvider(BC).build(pair.getPrivate())); int count = 0; boolean oneFound = false; boolean twoFound = false; Iterator it = crlHolder.getRevokedCertificates().iterator(); while (it.hasNext()) { X509CRLEntryHolder crlEnt = (X509CRLEntryHolder)it.next(); if (crlEnt.getSerialNumber().intValue() == 1) { oneFound = true; Extension extn = crlEnt.getExtension(X509Extension.reasonCode); if (extn != null) { ASN1Enumerated reasonCode = (ASN1Enumerated)ASN1Enumerated.getInstance(extn.getParsedValue()); if (reasonCode.getValue().intValue() != CRLReason.privilegeWithdrawn) { fail("CRL entry reasonCode wrong"); } } else { fail("CRL entry reasonCode not found"); } } else if (crlEnt.getSerialNumber().intValue() == 2) { twoFound = true; } count++; } if (count != 2) { fail("wrong number of CRLs found"); } if (!oneFound || !twoFound) { fail("wrong CRLs found in copied list"); } // // check factory read back // CertificateFactory cFact = CertificateFactory.getInstance("X.509", BC); X509CRL readCrl = (X509CRL)cFact.generateCRL(new ByteArrayInputStream(crlHolder.getEncoded())); if (readCrl == null) { fail("crl not returned!"); } Collection col = cFact.generateCRLs(new ByteArrayInputStream(crlHolder.getEncoded())); if (col.size() != 1) { fail("wrong number of CRLs found in collection"); } } /** * we generate a self signed certificate for the sake of testing - GOST3410 */ public void checkCreation4() throws Exception { // // set up the keys // PrivateKey privKey; PublicKey pubKey; KeyPairGenerator g = KeyPairGenerator.getInstance("GOST3410", BC); GOST3410ParameterSpec gost3410P = new GOST3410ParameterSpec("GostR3410-94-CryptoPro-A"); g.initialize(gost3410P, new SecureRandom()); KeyPair p = g.generateKeyPair(); privKey = p.getPrivate(); pubKey = p.getPublic(); // // distinguished name table. // X500NameBuilder builder = createStdBuilder(); // // extensions // // // create the certificate - version 3 // ContentSigner sigGen = new JcaContentSignerBuilder("GOST3411withGOST3410").setProvider(BC).build(privKey); X509v3CertificateBuilder certGen = new JcaX509v3CertificateBuilder(builder.build(),BigInteger.valueOf(1),new Date(System.currentTimeMillis() - 50000),new Date(System.currentTimeMillis() + 50000),builder.build(),pubKey); X509Certificate cert = new JcaX509CertificateConverter().setProvider(BC).getCertificate(certGen.build(sigGen)); cert.checkValidity(new Date()); // // check verifies in general // cert.verify(pubKey); // // check verifies with contained key // cert.verify(cert.getPublicKey()); ByteArrayInputStream bIn = new ByteArrayInputStream(cert.getEncoded()); CertificateFactory fact = CertificateFactory.getInstance("X.509", BC); cert = (X509Certificate)fact.generateCertificate(bIn); //System.out.println(cert); //check getEncoded() byte[] bytes = cert.getEncoded(); } public void checkCreation5() throws Exception { // // a sample key pair. // RSAPublicKeySpec pubKeySpec = new RSAPublicKeySpec( new BigInteger("b4a7e46170574f16a97082b22be58b6a2a629798419be12872a4bdba626cfae9900f76abfb12139dce5de56564fab2b6543165a040c606887420e33d91ed7ed7", 16), new BigInteger("11", 16)); RSAPrivateCrtKeySpec privKeySpec = new RSAPrivateCrtKeySpec( new BigInteger("b4a7e46170574f16a97082b22be58b6a2a629798419be12872a4bdba626cfae9900f76abfb12139dce5de56564fab2b6543165a040c606887420e33d91ed7ed7", 16), new BigInteger("11", 16), new BigInteger("9f66f6b05410cd503b2709e88115d55daced94d1a34d4e32bf824d0dde6028ae79c5f07b580f5dce240d7111f7ddb130a7945cd7d957d1920994da389f490c89", 16), new BigInteger("c0a0758cdf14256f78d4708c86becdead1b50ad4ad6c5c703e2168fbf37884cb", 16), new BigInteger("f01734d7960ea60070f1b06f2bb81bfac48ff192ae18451d5e56c734a5aab8a5", 16), new BigInteger("b54bb9edff22051d9ee60f9351a48591b6500a319429c069a3e335a1d6171391", 16), new BigInteger("d3d83daf2a0cecd3367ae6f8ae1aeb82e9ac2f816c6fc483533d8297dd7884cd", 16), new BigInteger("b8f52fc6f38593dabb661d3f50f8897f8106eee68b1bce78a95b132b4e5b5d19", 16)); // // set up the keys // SecureRandom rand = new SecureRandom(); PrivateKey privKey; PublicKey pubKey; KeyFactory fact = KeyFactory.getInstance("RSA", BC); privKey = fact.generatePrivate(privKeySpec); pubKey = fact.generatePublic(pubKeySpec); // // distinguished name table. // Vector ord = new Vector(); Vector values = new Vector(); X500NameBuilder builder = createStdBuilder(); // // create base certificate - version 3 // ContentSigner sigGen = new JcaContentSignerBuilder("MD5WithRSAEncryption").setProvider(BC).build(privKey); X509v3CertificateBuilder certGen = new JcaX509v3CertificateBuilder(builder.build(),BigInteger.valueOf(1),new Date(System.currentTimeMillis() - 50000),new Date(System.currentTimeMillis() + 50000),builder.build(),pubKey) .addExtension(new ASN1ObjectIdentifier("2.5.29.15"), true, new X509KeyUsage(X509KeyUsage.encipherOnly)) .addExtension(new ASN1ObjectIdentifier("2.5.29.37"), true, new DERSequence(KeyPurposeId.anyExtendedKeyUsage)) .addExtension(new ASN1ObjectIdentifier("2.5.29.17"), true, new GeneralNames(new GeneralName(GeneralName.rfc822Name, "test@test.test"))); X509Certificate baseCert = new JcaX509CertificateConverter().setProvider(BC).getCertificate(certGen.build(sigGen)); // // copy certificate // certGen = new JcaX509v3CertificateBuilder(builder.build(),BigInteger.valueOf(1),new Date(System.currentTimeMillis() - 50000),new Date(System.currentTimeMillis() + 50000),builder.build(),pubKey) .copyAndAddExtension(new ASN1ObjectIdentifier("2.5.29.15"), true, baseCert) .copyAndAddExtension(new ASN1ObjectIdentifier("2.5.29.37"), false, baseCert); X509Certificate cert = new JcaX509CertificateConverter().setProvider(BC).getCertificate(certGen.build(sigGen)); cert.checkValidity(new Date()); cert.verify(pubKey); if (!areEqual(baseCert.getExtensionValue("2.5.29.15"), cert.getExtensionValue("2.5.29.15"))) { fail("2.5.29.15 differs"); } if (!areEqual(baseCert.getExtensionValue("2.5.29.37"), cert.getExtensionValue("2.5.29.37"))) { fail("2.5.29.37 differs"); } // // exception test // try { certGen.copyAndAddExtension(new ASN1ObjectIdentifier("2.5.99.99"), true, new JcaX509CertificateHolder(baseCert)); fail("exception not thrown on dud extension copy"); } catch (NullPointerException e) { // expected } // try // { // certGen.setPublicKey(dudPublicKey); // // certGen.generate(privKey, BC); // // fail("key without encoding not detected in v3"); // } // catch (IllegalArgumentException e) // { // // expected // } } private void testForgedSignature() throws Exception { String cert = "MIIBsDCCAVoCAQYwDQYJKoZIhvcNAQEFBQAwYzELMAkGA1UEBhMCQVUxEzARBgNV" + "BAgTClF1ZWVuc2xhbmQxGjAYBgNVBAoTEUNyeXB0U29mdCBQdHkgTHRkMSMwIQYD" + "VQQDExpTZXJ2ZXIgdGVzdCBjZXJ0ICg1MTIgYml0KTAeFw0wNjA5MTEyMzU4NTVa" + "Fw0wNjEwMTEyMzU4NTVaMGMxCzAJBgNVBAYTAkFVMRMwEQYDVQQIEwpRdWVlbnNs" + "YW5kMRowGAYDVQQKExFDcnlwdFNvZnQgUHR5IEx0ZDEjMCEGA1UEAxMaU2VydmVy" + "IHRlc3QgY2VydCAoNTEyIGJpdCkwXDANBgkqhkiG9w0BAQEFAANLADBIAkEAn7PD" + "hCeV/xIxUg8V70YRxK2A5jZbD92A12GN4PxyRQk0/lVmRUNMaJdq/qigpd9feP/u" + "12S4PwTLb/8q/v657QIDAQABMA0GCSqGSIb3DQEBBQUAA0EAbynCRIlUQgaqyNgU" + "DF6P14yRKUtX8akOP2TwStaSiVf/akYqfLFm3UGka5XbPj4rifrZ0/sOoZEEBvHQ" + "e20sRA=="; CertificateFactory certFact = CertificateFactory.getInstance("X.509", BC); X509Certificate x509 = (X509Certificate)certFact.generateCertificate(new ByteArrayInputStream(Base64.decode(cert))); try { x509.verify(x509.getPublicKey()); fail("forged RSA signature passed"); } catch (Exception e) { // expected } } private void pemTest() throws Exception { CertificateFactory cf = CertificateFactory.getInstance("X.509", BC); Certificate cert = readPEMCert(cf, PEMData.CERTIFICATE_1); if (cert == null) { fail("PEM cert not read"); } cert = readPEMCert(cf, "-----BEGIN CERTIFICATE-----" + PEMData.CERTIFICATE_2); if (cert == null) { fail("PEM cert with extraneous header not read"); } CRL crl = cf.generateCRL(new ByteArrayInputStream(PEMData.CRL_1.getBytes("US-ASCII"))); if (crl == null) { fail("PEM crl not read"); } Collection col = cf.generateCertificates(new ByteArrayInputStream(PEMData.CERTIFICATE_2.getBytes("US-ASCII"))); if (col.size() != 1 || !col.contains(cert)) { fail("PEM cert collection not right"); } col = cf.generateCRLs(new ByteArrayInputStream(PEMData.CRL_2.getBytes("US-ASCII"))); if (col.size() != 1 || !col.contains(crl)) { fail("PEM crl collection not right"); } } private static Certificate readPEMCert(CertificateFactory cf, String pemData) throws CertificateException, UnsupportedEncodingException { return cf.generateCertificate(new ByteArrayInputStream(pemData.getBytes("US-ASCII"))); } private void pkcs7Test() throws Exception { /* ASN1EncodableVector certs = new ASN1EncodableVector(); certs.add(new ASN1InputStream(CertPathTest.rootCertBin).readObject()); certs.add(new DERTaggedObject(false, 2, new ASN1InputStream(AttrCertTest.attrCert).readObject())); ASN1EncodableVector crls = new ASN1EncodableVector(); crls.add(new ASN1InputStream(CertPathTest.rootCrlBin).readObject()); SignedData sigData = new SignedData(new DERSet(), new ContentInfo(CMSObjectIdentifiers.data, null), new DERSet(certs), new DERSet(crls), new DERSet()); ContentInfo info = new ContentInfo(CMSObjectIdentifiers.signedData, sigData); CertificateFactory cf = CertificateFactory.getInstance("X.509", BC); X509Certificate cert = (X509Certificate)cf.generateCertificate(new ByteArrayInputStream(info.getEncoded())); if (cert == null || !areEqual(cert.getEncoded(), certs.get(0).getDERObject().getEncoded())) { fail("PKCS7 cert not read"); } X509CRL crl = (X509CRL)cf.generateCRL(new ByteArrayInputStream(info.getEncoded())); if (crl == null || !areEqual(crl.getEncoded(), crls.get(0).getDERObject().getEncoded())) { fail("PKCS7 crl not read"); } Collection col = cf.generateCertificates(new ByteArrayInputStream(info.getEncoded())); if (col.size() != 1 || !col.contains(cert)) { fail("PKCS7 cert collection not right"); } col = cf.generateCRLs(new ByteArrayInputStream(info.getEncoded())); if (col.size() != 1 || !col.contains(crl)) { fail("PKCS7 crl collection not right"); } // data with no certificates or CRLs sigData = new SignedData(new DERSet(), new ContentInfo(CMSObjectIdentifiers.data, null), new DERSet(), new DERSet(), new DERSet()); info = new ContentInfo(CMSObjectIdentifiers.signedData, sigData); cert = (X509Certificate)cf.generateCertificate(new ByteArrayInputStream(info.getEncoded())); if (cert != null) { fail("PKCS7 cert present"); } crl = (X509CRL)cf.generateCRL(new ByteArrayInputStream(info.getEncoded())); if (crl != null) { fail("PKCS7 crl present"); } // data with absent certificates and CRLS sigData = new SignedData(new DERSet(), new ContentInfo(CMSObjectIdentifiers.data, null), null, null, new DERSet()); info = new ContentInfo(CMSObjectIdentifiers.signedData, sigData); cert = (X509Certificate)cf.generateCertificate(new ByteArrayInputStream(info.getEncoded())); if (cert != null) { fail("PKCS7 cert present"); } crl = (X509CRL)cf.generateCRL(new ByteArrayInputStream(info.getEncoded())); if (crl != null) { fail("PKCS7 crl present"); } // // sample message // InputStream in = new ByteArrayInputStream(pkcs7CrlProblem); Collection certCol = cf.generateCertificates(in); Collection crlCol = cf.generateCRLs(in); if (crlCol.size() != 0) { fail("wrong number of CRLs: " + crlCol.size()); } if (certCol.size() != 4) { fail("wrong number of Certs: " + certCol.size()); } */ } private void createPSSCert(String algorithm) throws Exception { KeyPair pair = generateLongFixedKeys(); PrivateKey privKey = pair.getPrivate(); PublicKey pubKey = pair.getPublic(); // // distinguished name table. // X500NameBuilder builder = createStdBuilder(); // // create base certificate - version 3 // ContentSigner sigGen = new JcaContentSignerBuilder(algorithm).setProvider(BC).build(privKey); JcaX509v3CertificateBuilder certGen = new JcaX509v3CertificateBuilder(builder.build(),BigInteger.valueOf(1), new Date(System.currentTimeMillis() - 50000),new Date(System.currentTimeMillis() + 50000),builder.build(),pubKey); certGen.addExtension(new ASN1ObjectIdentifier("2.5.29.15"), true, new X509KeyUsage(X509KeyUsage.encipherOnly)); certGen.addExtension(new ASN1ObjectIdentifier("2.5.29.37"), true, new DERSequence(KeyPurposeId.anyExtendedKeyUsage)); certGen.addExtension(new ASN1ObjectIdentifier("2.5.29.17"), true, new GeneralNames(new GeneralName(GeneralName.rfc822Name, "test@test.test"))); X509Certificate baseCert = new JcaX509CertificateConverter().setProvider(BC).getCertificate(certGen.build(sigGen)); baseCert.verify(pubKey); } private KeyPair generateLongFixedKeys() throws NoSuchAlgorithmException, NoSuchProviderException, InvalidKeySpecException { RSAPublicKeySpec pubKeySpec = new RSAPublicKeySpec( new BigInteger("a56e4a0e701017589a5187dc7ea841d156f2ec0e36ad52a44dfeb1e61f7ad991d8c51056ffedb162b4c0f283a12a88a394dff526ab7291cbb307ceabfce0b1dfd5cd9508096d5b2b8b6df5d671ef6377c0921cb23c270a70e2598e6ff89d19f105acc2d3f0cb35f29280e1386b6f64c4ef22e1e1f20d0ce8cffb2249bd9a2137",16), new BigInteger("010001",16)); RSAPrivateCrtKeySpec privKeySpec = new RSAPrivateCrtKeySpec( new BigInteger("a56e4a0e701017589a5187dc7ea841d156f2ec0e36ad52a44dfeb1e61f7ad991d8c51056ffedb162b4c0f283a12a88a394dff526ab7291cbb307ceabfce0b1dfd5cd9508096d5b2b8b6df5d671ef6377c0921cb23c270a70e2598e6ff89d19f105acc2d3f0cb35f29280e1386b6f64c4ef22e1e1f20d0ce8cffb2249bd9a2137",16), new BigInteger("010001",16), new BigInteger("33a5042a90b27d4f5451ca9bbbd0b44771a101af884340aef9885f2a4bbe92e894a724ac3c568c8f97853ad07c0266c8c6a3ca0929f1e8f11231884429fc4d9ae55fee896a10ce707c3ed7e734e44727a39574501a532683109c2abacaba283c31b4bd2f53c3ee37e352cee34f9e503bd80c0622ad79c6dcee883547c6a3b325",16), new BigInteger("e7e8942720a877517273a356053ea2a1bc0c94aa72d55c6e86296b2dfc967948c0a72cbccca7eacb35706e09a1df55a1535bd9b3cc34160b3b6dcd3eda8e6443",16), new BigInteger("b69dca1cf7d4d7ec81e75b90fcca874abcde123fd2700180aa90479b6e48de8d67ed24f9f19d85ba275874f542cd20dc723e6963364a1f9425452b269a6799fd",16), new BigInteger("28fa13938655be1f8a159cbaca5a72ea190c30089e19cd274a556f36c4f6e19f554b34c077790427bbdd8dd3ede2448328f385d81b30e8e43b2fffa027861979",16), new BigInteger("1a8b38f398fa712049898d7fb79ee0a77668791299cdfa09efc0e507acb21ed74301ef5bfd48be455eaeb6e1678255827580a8e4e8e14151d1510a82a3f2e729",16), new BigInteger("27156aba4126d24a81f3a528cbfb27f56886f840a9f6e86e17a44b94fe9319584b8e22fdde1e5a2e3bd8aa5ba8d8584194eb2190acf832b847f13a3d24a79f4d",16)); KeyFactory fact = KeyFactory.getInstance("RSA", BC); return new KeyPair(fact.generatePublic(pubKeySpec), fact.generatePrivate(privKeySpec)); } private void rfc4491Test() throws Exception { CertificateFactory certFact = CertificateFactory.getInstance("X.509", BC); X509Certificate x509 = (X509Certificate)certFact.generateCertificate(new ByteArrayInputStream(gostRFC4491_94)); x509.verify(x509.getPublicKey(), BC); x509 = (X509Certificate)certFact.generateCertificate(new ByteArrayInputStream(gostRFC4491_2001)); x509.verify(x509.getPublicKey(), BC); } private void testNullDerNullCert() throws Exception { KeyPair pair = generateLongFixedKeys(); PublicKey pubKey = pair.getPublic(); PrivateKey privKey = pair.getPrivate(); ContentSigner sigGen = new JcaContentSignerBuilder("MD5WithRSAEncryption").setProvider(BC).build(privKey); JcaX509v3CertificateBuilder certGen = new JcaX509v3CertificateBuilder(new X500Name("CN=Test"),BigInteger.valueOf(1),new Date(System.currentTimeMillis() - 50000),new Date(System.currentTimeMillis() + 50000),new X500Name("CN=Test"),pubKey); X509Certificate cert = new JcaX509CertificateConverter().setProvider(BC).getCertificate(certGen.build(sigGen)); X509CertificateStructure struct = X509CertificateStructure.getInstance(ASN1Primitive.fromByteArray(cert.getEncoded())); ASN1Encodable tbsCertificate = struct.getTBSCertificate(); AlgorithmIdentifier sig = struct.getSignatureAlgorithm(); ASN1EncodableVector v = new ASN1EncodableVector(); v.add(tbsCertificate); v.add(new AlgorithmIdentifier(sig.getAlgorithm())); v.add(struct.getSignature()); // verify ByteArrayInputStream bIn; String dump = ""; try { bIn = new ByteArrayInputStream(new DERSequence(v).getEncoded()); CertificateFactory fact = CertificateFactory.getInstance("X.509", BC); cert = (X509Certificate)fact.generateCertificate(bIn); cert.verify(cert.getPublicKey()); } catch (Exception e) { fail(dump + System.getProperty("line.separator") + getName() + ": testNullDerNull failed - exception " + e.toString(), e); } } private void testDirect() throws Exception { KeyStore keyStore = KeyStore.getInstance("PKCS12", "BC"); ByteArrayInputStream input = new ByteArrayInputStream(testCAp12); keyStore.load(input, "test".toCharArray()); X509Certificate certificate = (X509Certificate) keyStore.getCertificate("ca"); PrivateKey privateKey = (PrivateKey) keyStore.getKey("ca", null); X500Name issuer = X500Name.getInstance(certificate.getIssuerX500Principal().getEncoded()); X509v2CRLBuilder builder = new X509v2CRLBuilder(issuer, new Date()); builder.addCRLEntry(certificate.getSerialNumber(), new Date(), CRLReason.cACompromise); JcaContentSignerBuilder contentSignerBuilder = new JcaContentSignerBuilder("SHA256WithRSAEncryption"); contentSignerBuilder.setProvider("BC"); X509CRLHolder cRLHolder = builder.build(contentSignerBuilder.build(privateKey)); if (!cRLHolder.isSignatureValid(new JcaContentVerifierProviderBuilder().setProvider("BC").build(certificate))) { fail("CRL signature not valid"); } X509CRLEntryHolder cRLEntryHolder = cRLHolder.getRevokedCertificate(certificate.getSerialNumber()); if (!cRLEntryHolder.getCertificateIssuer().equals(new GeneralNames(new GeneralName(cRLHolder.getIssuer())))) { fail("certificate issuer incorrect"); } JcaX509CRLConverter converter = new JcaX509CRLConverter(); converter.setProvider("BC"); X509CRL crl = converter.getCRL(cRLHolder); crl.verify(certificate.getPublicKey()); if (!crl.isRevoked(certificate)) { fail("Certificate should be revoked"); } // now encode the CRL and load the CRL with the JCE provider CertificateFactory fac = CertificateFactory.getInstance("X.509"); X509CRL jceCRL = (X509CRL) fac.generateCRL(new ByteArrayInputStream(crl.getEncoded())); jceCRL.verify(certificate.getPublicKey()); if (!jceCRL.isRevoked(certificate)) { fail("This certificate should also be revoked"); } } private void testIndirect() throws Exception { KeyStore keyStore = KeyStore.getInstance("PKCS12", "BC"); ByteArrayInputStream input = new ByteArrayInputStream(testCAp12); keyStore.load(input, "test".toCharArray()); X509Certificate certificate = (X509Certificate) keyStore.getCertificate("ca"); PrivateKey privateKey = (PrivateKey) keyStore.getKey("ca", null); X500Name crlIssuer = X500Name.getInstance(certificate.getSubjectX500Principal().getEncoded()); X500Name caName = X500Name.getInstance(certificate.getIssuerX500Principal().getEncoded()); X509v2CRLBuilder builder = new X509v2CRLBuilder(crlIssuer, new Date()); builder.addExtension(Extension.issuingDistributionPoint, true, new IssuingDistributionPoint(null, true, false)); ExtensionsGenerator extGen = new ExtensionsGenerator(); extGen.addExtension(Extension.reasonCode, false, CRLReason.lookup(CRLReason.cACompromise)); extGen.addExtension(Extension.certificateIssuer, true, new GeneralNames(new GeneralName(caName))); builder.addCRLEntry(certificate.getSerialNumber(), new Date(), extGen.generate()); JcaContentSignerBuilder contentSignerBuilder = new JcaContentSignerBuilder("SHA256WithRSAEncryption"); contentSignerBuilder.setProvider("BC"); X509CRLHolder cRLHolder = builder.build(contentSignerBuilder.build(privateKey)); if (!cRLHolder.isSignatureValid(new JcaContentVerifierProviderBuilder().setProvider("BC").build(certificate))) { fail("CRL signature not valid"); } X509CRLEntryHolder cRLEntryHolder = cRLHolder.getRevokedCertificate(certificate.getSerialNumber()); if (!cRLEntryHolder.getCertificateIssuer().equals(new GeneralNames(new GeneralName(X500Name.getInstance(certificate.getIssuerX500Principal().getEncoded()))))) { fail("certificate issuer incorrect"); } JcaX509CRLConverter converter = new JcaX509CRLConverter(); converter.setProvider("BC"); X509CRL crl = converter.getCRL(cRLHolder); crl.verify(certificate.getPublicKey()); if (!crl.isRevoked(certificate)) { fail("Certificate should be revoked"); } // now encode the CRL and load the CRL with the JCE provider CertificateFactory fac = CertificateFactory.getInstance("X.509"); X509CRL jceCRL = (X509CRL) fac.generateCRL(new ByteArrayInputStream(crl.getEncoded())); jceCRL.verify(certificate.getPublicKey()); if (!jceCRL.isRevoked(certificate)) { fail("This certificate should also be revoked"); } } private void testIndirect2() throws Exception { KeyStore keyStore = KeyStore.getInstance("PKCS12", "BC"); ByteArrayInputStream input = new ByteArrayInputStream(testCAp12); keyStore.load(input, "test".toCharArray()); X509Certificate certificate = (X509Certificate) keyStore.getCertificate("ca"); PrivateKey privateKey = (PrivateKey) keyStore.getKey("ca", null); X500Name crlIssuer = X500Name.getInstance(certificate.getSubjectX500Principal().getEncoded()); X500Name caName = X500Name.getInstance(certificate.getIssuerX500Principal().getEncoded()); X509v2CRLBuilder builder = new X509v2CRLBuilder(crlIssuer, new Date()); builder.addExtension(Extension.issuingDistributionPoint, true, new IssuingDistributionPoint(null, true, false)); builder.addCRLEntry(BigInteger.valueOf(100), new Date(), CRLReason.cACompromise); builder.addCRLEntry(BigInteger.valueOf(120), new Date(), CRLReason.cACompromise); ExtensionsGenerator extGen = new ExtensionsGenerator(); extGen.addExtension(Extension.reasonCode, false, CRLReason.lookup(CRLReason.cACompromise)); extGen.addExtension(Extension.certificateIssuer, true, new GeneralNames(new GeneralName(caName))); builder.addCRLEntry(certificate.getSerialNumber(), new Date(), extGen.generate()); builder.addCRLEntry(BigInteger.valueOf(130), new Date(), CRLReason.cACompromise); JcaContentSignerBuilder contentSignerBuilder = new JcaContentSignerBuilder("SHA256WithRSAEncryption"); contentSignerBuilder.setProvider("BC"); X509CRLHolder cRLHolder = builder.build(contentSignerBuilder.build(privateKey)); if (!cRLHolder.isSignatureValid(new JcaContentVerifierProviderBuilder().setProvider("BC").build(certificate))) { fail("CRL signature not valid"); } X509CRLEntryHolder cRLEntryHolder = cRLHolder.getRevokedCertificate(certificate.getSerialNumber()); if (!cRLEntryHolder.getCertificateIssuer().equals(new GeneralNames(new GeneralName(caName)))) { fail("certificate issuer incorrect"); } cRLEntryHolder = cRLHolder.getRevokedCertificate(BigInteger.valueOf(130)); if (!cRLEntryHolder.getCertificateIssuer().equals(new GeneralNames(new GeneralName(caName)))) { fail("certificate issuer incorrect"); } cRLEntryHolder = cRLHolder.getRevokedCertificate(BigInteger.valueOf(100)); if (!cRLEntryHolder.getCertificateIssuer().equals(new GeneralNames(new GeneralName(cRLHolder.getIssuer())))) { fail("certificate issuer incorrect"); } JcaX509CRLConverter converter = new JcaX509CRLConverter(); converter.setProvider("BC"); X509CRL crl = converter.getCRL(cRLHolder); crl.verify(certificate.getPublicKey()); } // issuing distribution point must be set for an indirect CRL to be recognised private void testMalformedIndirect() throws Exception { KeyStore keyStore = KeyStore.getInstance("PKCS12", "BC"); ByteArrayInputStream input = new ByteArrayInputStream(testCAp12); keyStore.load(input, "test".toCharArray()); X509Certificate certificate = (X509Certificate) keyStore.getCertificate("ca"); PrivateKey privateKey = (PrivateKey) keyStore.getKey("ca", null); X500Name crlIssuer = X500Name.getInstance(certificate.getSubjectX500Principal().getEncoded()); X500Name caName = X500Name.getInstance(certificate.getIssuerX500Principal().getEncoded()); X509v2CRLBuilder builder = new X509v2CRLBuilder(crlIssuer, new Date()); ExtensionsGenerator extGen = new ExtensionsGenerator(); extGen.addExtension(Extension.reasonCode, false, CRLReason.lookup(CRLReason.cACompromise)); extGen.addExtension(Extension.certificateIssuer, true, new GeneralNames(new GeneralName(caName))); builder.addCRLEntry(certificate.getSerialNumber(), new Date(), extGen.generate()); JcaContentSignerBuilder contentSignerBuilder = new JcaContentSignerBuilder("SHA256WithRSAEncryption"); contentSignerBuilder.setProvider("BC"); X509CRLHolder cRLHolder = builder.build(contentSignerBuilder.build(privateKey)); if (!cRLHolder.isSignatureValid(new JcaContentVerifierProviderBuilder().setProvider("BC").build(certificate))) { fail("CRL signature not valid"); } X509CRLEntryHolder cRLEntryHolder = cRLHolder.getRevokedCertificate(certificate.getSerialNumber()); if (!cRLEntryHolder.getCertificateIssuer().equals(new GeneralNames(new GeneralName(cRLHolder.getIssuer())))) { fail("certificate issuer incorrect"); } JcaX509CRLConverter converter = new JcaX509CRLConverter(); converter.setProvider("BC"); X509CRL crl = converter.getCRL(cRLHolder); crl.verify(certificate.getPublicKey()); if (crl.isRevoked(certificate)) { throw new Exception("Certificate should not be revoked"); } } public void performTest() throws Exception { testDirect(); testIndirect(); testIndirect2(); testMalformedIndirect(); checkCertificate(1, cert1); checkCertificate(2, cert2); checkCertificate(3, cert3); checkCertificate(4, cert4); checkCertificate(5, cert5); checkCertificate(6, oldEcdsa); checkCertificate(7, cert7); checkKeyUsage(8, keyUsage); checkSelfSignedCertificate(9, uncompressedPtEC); checkNameCertificate(10, nameCert); checkSelfSignedCertificate(11, probSelfSignedCert); checkSelfSignedCertificate(12, gostCA1); checkSelfSignedCertificate(13, gostCA2); checkSelfSignedCertificate(14, gost341094base); checkSelfSignedCertificate(15, gost34102001base); checkSelfSignedCertificate(16, gost341094A); checkSelfSignedCertificate(17, gost341094B); checkSelfSignedCertificate(17, gost34102001A); checkCRL(1, crl1); checkCreation1(); checkCreation2(); checkCreation3(); checkCreation4(); checkCreation5(); createECCert("SHA1withECDSA", X9ObjectIdentifiers.ecdsa_with_SHA1); createECCert("SHA224withECDSA", X9ObjectIdentifiers.ecdsa_with_SHA224); createECCert("SHA256withECDSA", X9ObjectIdentifiers.ecdsa_with_SHA256); createECCert("SHA384withECDSA", X9ObjectIdentifiers.ecdsa_with_SHA384); createECCert("SHA512withECDSA", X9ObjectIdentifiers.ecdsa_with_SHA512); createPSSCert("SHA1withRSAandMGF1"); createPSSCert("SHA224withRSAandMGF1"); createPSSCert("SHA256withRSAandMGF1"); createPSSCert("SHA384withRSAandMGF1"); checkCRLCreation1(); checkCRLCreation2(); checkCRLCreation3(); pemTest(); pkcs7Test(); rfc4491Test(); testForgedSignature(); testNullDerNullCert(); checkCertificate(18, emptyDNCert); } public static void main( String[] args) { Security.addProvider(new BouncyCastleProvider()); runTest(new CertTest()); } } bouncycastle-1.49.orig/test/jdk1.4/org/bouncycastle/pqc/0000755000175000017500000000000012152033550022444 5ustar ebourgebourgbouncycastle-1.49.orig/test/jdk1.4/org/bouncycastle/pqc/crypto/0000755000175000017500000000000012152033550023764 5ustar ebourgebourgbouncycastle-1.49.orig/test/jdk1.4/org/bouncycastle/pqc/crypto/test/0000755000175000017500000000000012152033550024743 5ustar ebourgebourgbouncycastle-1.49.orig/test/jdk1.4/org/bouncycastle/pqc/crypto/test/AllTests.java0000644000175000017500000000165712132630507027355 0ustar ebourgebourgpackage org.bouncycastle.pqc.crypto.test; import junit.framework.Test; import junit.framework.TestCase; import junit.framework.TestSuite; import org.bouncycastle.util.test.SimpleTestResult; public class AllTests extends TestCase { public void testCrypto() { org.bouncycastle.util.test.Test[] tests = RegressionTest.tests; // for (int i = 0; i != tests.length; i++) // { // SimpleTestResult result = (SimpleTestResult)tests[i].perform(); // // if (!result.isSuccessful()) // { // fail(result.toString()); // } // } } public static void main (String[] args) { junit.textui.TestRunner.run(suite()); } public static Test suite() { TestSuite suite = new TestSuite("Lightweight PQ Crypto Tests"); suite.addTestSuite(AllTests.class); return suite; } } bouncycastle-1.49.orig/test/jdk1.4/org/bouncycastle/mail/0000755000175000017500000000000012152033550022603 5ustar ebourgebourgbouncycastle-1.49.orig/test/jdk1.4/org/bouncycastle/mail/smime/0000755000175000017500000000000012152033550023715 5ustar ebourgebourgbouncycastle-1.49.orig/test/jdk1.4/org/bouncycastle/mail/smime/test/0000755000175000017500000000000012152033550024674 5ustar ebourgebourgbouncycastle-1.49.orig/test/jdk1.4/org/bouncycastle/mail/smime/test/AllTests.java0000644000175000017500000000115210503212044027264 0ustar ebourgebourgpackage org.bouncycastle.mail.smime.test; import junit.framework.Test; import junit.framework.TestSuite; public class AllTests { public static void main (String[] args) throws Exception { junit.textui.TestRunner.run (suite()); } public static Test suite() throws Exception { TestSuite suite= new TestSuite("SMIME tests"); suite.addTest(SMIMESignedTest.suite()); suite.addTest(SMIMEEnvelopedTest.suite()); suite.addTest(SMIMECompressedTest.suite()); suite.addTest(SMIMEMiscTest.suite()); return suite; } } bouncycastle-1.49.orig/test/jdk1.4/org/bouncycastle/cms/0000755000175000017500000000000012152033550022443 5ustar ebourgebourgbouncycastle-1.49.orig/test/jdk1.4/org/bouncycastle/cms/test/0000755000175000017500000000000012152033550023422 5ustar ebourgebourgbouncycastle-1.49.orig/test/jdk1.4/org/bouncycastle/cms/test/EnvelopedDataTest.java0000644000175000017500000007653111066571364027671 0ustar ebourgebourgpackage org.bouncycastle.cms.test; import junit.framework.Test; import junit.framework.TestCase; import junit.framework.TestSuite; import org.bouncycastle.asn1.ASN1InputStream; import org.bouncycastle.asn1.ASN1Sequence; import org.bouncycastle.asn1.DERObjectIdentifier; import org.bouncycastle.asn1.DEROctetString; import org.bouncycastle.asn1.kisa.KISAObjectIdentifiers; import org.bouncycastle.asn1.nist.NISTObjectIdentifiers; import org.bouncycastle.asn1.ntt.NTTObjectIdentifiers; import org.bouncycastle.asn1.pkcs.PKCSObjectIdentifiers; import org.bouncycastle.cms.CMSEnvelopedData; import org.bouncycastle.cms.CMSEnvelopedDataGenerator; import org.bouncycastle.cms.CMSException; import org.bouncycastle.cms.CMSProcessableByteArray; import org.bouncycastle.cms.KeyTransRecipientInformation; import org.bouncycastle.cms.PKCS5Scheme2PBEKey; import org.bouncycastle.cms.RecipientInformation; import org.bouncycastle.cms.RecipientInformationStore; import org.bouncycastle.cms.PKCS5Scheme2UTF8PBEKey; import org.bouncycastle.cms.PasswordRecipientInformation; import org.bouncycastle.util.encoders.Base64; import org.bouncycastle.util.encoders.Hex; import javax.crypto.SecretKey; import javax.crypto.spec.SecretKeySpec; import java.security.GeneralSecurityException; import java.security.Key; import java.security.KeyFactory; import java.security.KeyPair; import java.security.NoSuchAlgorithmException; import java.security.NoSuchProviderException; import java.security.PrivateKey; import java.security.Security; import java.security.cert.X509Certificate; import java.security.spec.PKCS8EncodedKeySpec; import java.util.Arrays; import java.util.Collection; import java.util.Iterator; public class EnvelopedDataTest extends TestCase { private static String _signDN; private static KeyPair _signKP; private static X509Certificate _signCert; private static String _origDN; private static KeyPair _origKP; private static X509Certificate _origCert; private static String _reciDN; private static KeyPair _reciKP; private static X509Certificate _reciCert; private static KeyPair _origEcKP; private static KeyPair _reciEcKP; private static X509Certificate _reciEcCert; private static boolean _initialised = false; private byte[] oldKEK = Base64.decode( "MIAGCSqGSIb3DQEHA6CAMIACAQIxQaI/MD0CAQQwBwQFAQIDBAUwDQYJYIZIAWUDBAEFBQAEI" + "Fi2eHTPM4bQSjP4DUeDzJZLpfemW2gF1SPq7ZPHJi1mMIAGCSqGSIb3DQEHATAUBggqhkiG9w" + "0DBwQImtdGyUdGGt6ggAQYk9X9z01YFBkU7IlS3wmsKpm/zpZClTceAAAAAAAAAAAAAA=="); private byte[] ecKeyAgreeMsgAES256 = Base64.decode( "MIAGCSqGSIb3DQEHA6CAMIACAQIxgcShgcECAQOgQ6FBMAsGByqGSM49AgEF" + "AAMyAAPdXlSTpub+qqno9hUGkUDl+S3/ABhPziIB5yGU4678tgOgU5CiKG9Z" + "kfnabIJ3nZYwGgYJK4EFEIZIPwACMA0GCWCGSAFlAwQBLQUAMFswWTAtMCgx" + "EzARBgNVBAMTCkFkbWluLU1EU0UxETAPBgNVBAoTCDRCQ1QtMklEAgEBBCi/" + "rJRLbFwEVW6PcLLmojjW9lI/xGD7CfZzXrqXFw8iHaf3hTRau1gYMIAGCSqG" + "SIb3DQEHATAdBglghkgBZQMEASoEEMtCnKKPwccmyrbgeSIlA3qggAQQDLw8" + "pNJR97bPpj6baG99bQQQwhEDsoj5Xg1oOxojHVcYzAAAAAAAAAAAAAA="); private byte[] ecKeyAgreeMsgAES128 = Base64.decode( "MIAGCSqGSIb3DQEHA6CAMIACAQIxgbShgbECAQOgQ6FBMAsGByqGSM49AgEF" + "AAMyAAL01JLEgKvKh5rbxI/hOxs/9WEezMIsAbUaZM4l5tn3CzXAN505nr5d" + "LhrcurMK+tAwGgYJK4EFEIZIPwACMA0GCWCGSAFlAwQBBQUAMEswSTAtMCgx" + "EzARBgNVBAMTCkFkbWluLU1EU0UxETAPBgNVBAoTCDRCQ1QtMklEAgEBBBhi" + "FLjc5g6aqDT3f8LomljOwl1WTrplUT8wgAYJKoZIhvcNAQcBMB0GCWCGSAFl" + "AwQBAgQQzXjms16Y69S/rB0EbHqRMaCABBAFmc/QdVW6LTKdEy97kaZzBBBa" + "fQuviUS03NycpojELx0bAAAAAAAAAAAAAA=="); private byte[] ecKeyAgreeMsgDESEDE = Base64.decode( "MIAGCSqGSIb3DQEHA6CAMIACAQIxgcahgcMCAQOgQ6FBMAsGByqGSM49AgEF" + "AAMyAALIici6Nx1WN5f0ThH2A8ht9ovm0thpC5JK54t73E1RDzCifePaoQo0" + "xd6sUqoyGaYwHAYJK4EFEIZIPwACMA8GCyqGSIb3DQEJEAMGBQAwWzBZMC0w" + "KDETMBEGA1UEAxMKQWRtaW4tTURTRTERMA8GA1UEChMINEJDVC0ySUQCAQEE" + "KJuqZQ1NB1vXrKPOnb4TCpYOsdm6GscWdwAAZlm2EHMp444j0s55J9wwgAYJ" + "KoZIhvcNAQcBMBQGCCqGSIb3DQMHBAjwnsDMsafCrKCABBjyPvqFOVMKxxut" + "VfTx4fQlNGJN8S2ATRgECMcTQ/dsmeViAAAAAAAAAAAAAA=="); private byte[] ecMQVKeyAgreeMsgAES128 = Base64.decode( "MIAGCSqGSIb3DQEHA6CAMIACAQIxgf2hgfoCAQOgQ6FBMAsGByqGSM49AgEF" + "AAMyAAPDKU+0H58tsjpoYmYCInMr/FayvCCkupebgsnpaGEB7qS9vzcNVUj6" + "mrnmiC2grpmhRwRFMEMwQTALBgcqhkjOPQIBBQADMgACZpD13z9c7DzRWx6S" + "0xdbq3S+EJ7vWO+YcHVjTD8NcQDcZcWASW899l1PkL936zsuMBoGCSuBBRCG" + "SD8AEDANBglghkgBZQMEAQUFADBLMEkwLTAoMRMwEQYDVQQDEwpBZG1pbi1N" + "RFNFMREwDwYDVQQKEwg0QkNULTJJRAIBAQQYFq58L71nyMK/70w3nc6zkkRy" + "RL7DHmpZMIAGCSqGSIb3DQEHATAdBglghkgBZQMEAQIEEDzRUpreBsZXWHBe" + "onxOtSmggAQQ7csAZXwT1lHUqoazoy8bhAQQq+9Zjj8iGdOWgyebbfj67QAA" + "AAAAAAAAAAA="); private byte[] ecKeyAgreeKey = Base64.decode( "MIG2AgEAMBAGByqGSM49AgEGBSuBBAAiBIGeMIGbAgEBBDC8vp7xVTbKSgYVU5Wc" + "hGkWbzaj+yUFETIWP1Dt7+WSpq3ikSPdl7PpHPqnPVZfoIWhZANiAgSYHTgxf+Dd" + "Tt84dUvuSKkFy3RhjxJmjwIscK6zbEUzKhcPQG2GHzXhWK5x1kov0I74XpGhVkya" + "ElH5K6SaOXiXAzcyNGggTOk4+ZFnz5Xl0pBje3zKxPhYu0SnCw7Pcqw="); private byte[] bobPrivRsaEncrypt = Base64.decode( "MIIChQIBADANBgkqhkiG9w0BAQEFAASCAmAwggJcAgEAAoGBAKnhZ5g/OdVf" + "8qCTQV6meYmFyDVdmpFb+x0B2hlwJhcPvaUi0DWFbXqYZhRBXM+3twg7CcmR" + "uBlpN235ZR572akzJKN/O7uvRgGGNjQyywcDWVL8hYsxBLjMGAgUSOZPHPtd" + "YMTgXB9T039T2GkB8QX4enDRvoPGXzjPHCyqaqfrAgMBAAECgYBnzUhMmg2P" + "mMIbZf8ig5xt8KYGHbztpwOIlPIcaw+LNd4Ogngwy+e6alatd8brUXlweQqg" + "9P5F4Kmy9Bnah5jWMIR05PxZbMHGd9ypkdB8MKCixQheIXFD/A0HPfD6bRSe" + "TmPwF1h5HEuYHD09sBvf+iU7o8AsmAX2EAnYh9sDGQJBANDDIsbeopkYdo+N" + "vKZ11mY/1I1FUox29XLE6/BGmvE+XKpVC5va3Wtt+Pw7PAhDk7Vb/s7q/WiE" + "I2Kv8zHCueUCQQDQUfweIrdb7bWOAcjXq/JY1PeClPNTqBlFy2bKKBlf4hAr" + "84/sajB0+E0R9KfEILVHIdxJAfkKICnwJAiEYH2PAkA0umTJSChXdNdVUN5q" + "SO8bKlocSHseIVnDYDubl6nA7xhmqU5iUjiEzuUJiEiUacUgFJlaV/4jbOSn" + "I3vQgLeFAkEAni+zN5r7CwZdV+EJBqRd2ZCWBgVfJAZAcpw6iIWchw+dYhKI" + "FmioNRobQ+g4wJhprwMKSDIETukPj3d9NDAlBwJAVxhn1grStavCunrnVNqc" + "BU+B1O8BiR4yPWnLMcRSyFRVJQA7HCp8JlDV6abXd8vPFfXuC9WN7rOvTKF8" + "Y0ZB9qANMAsGA1UdDzEEAwIAEA=="); private byte[] rfc4134ex5_1 = Base64.decode( "MIIBHgYJKoZIhvcNAQcDoIIBDzCCAQsCAQAxgcAwgb0CAQAwJjASMRAwDgYD" + "VQQDEwdDYXJsUlNBAhBGNGvHgABWvBHTbi7NXXHQMA0GCSqGSIb3DQEBAQUA" + "BIGAC3EN5nGIiJi2lsGPcP2iJ97a4e8kbKQz36zg6Z2i0yx6zYC4mZ7mX7FB" + "s3IWg+f6KgCLx3M1eCbWx8+MDFbbpXadCDgO8/nUkUNYeNxJtuzubGgzoyEd" + "8Ch4H/dd9gdzTd+taTEgS0ipdSJuNnkVY4/M652jKKHRLFf02hosdR8wQwYJ" + "KoZIhvcNAQcBMBQGCCqGSIb3DQMHBAgtaMXpRwZRNYAgDsiSf8Z9P43LrY4O" + "xUk660cu1lXeCSFOSOpOJ7FuVyU="); private byte[] rfc4134ex5_2 = Base64.decode( "MIIBZQYJKoZIhvcNAQcDoIIBVjCCAVICAQIxggEAMIG9AgEAMCYwEjEQMA4G" + "A1UEAxMHQ2FybFJTQQIQRjRrx4AAVrwR024uzV1x0DANBgkqhkiG9w0BAQEF" + "AASBgJQmQojGi7Z4IP+CVypBmNFoCDoEp87khtgyff2N4SmqD3RxPx+8hbLQ" + "t9i3YcMwcap+aiOkyqjMalT03VUC0XBOGv+HYI3HBZm/aFzxoq+YOXAWs5xl" + "GerZwTOc9j6AYlK4qXvnztR5SQ8TBjlzytm4V7zg+TGrnGVNQBNw47Ewoj4C" + "AQQwDQQLTWFpbExpc3RSQzIwEAYLKoZIhvcNAQkQAwcCAToEGHcUr5MSJ/g9" + "HnJVHsQ6X56VcwYb+OfojTBJBgkqhkiG9w0BBwEwGgYIKoZIhvcNAwIwDgIC" + "AKAECJwE0hkuKlWhgCBeKNXhojuej3org9Lt7n+wWxOhnky5V50vSpoYRfRR" + "yw=="); public EnvelopedDataTest() { } private static void init() throws Exception { if (!_initialised) { _initialised = true; _signDN = "O=Bouncy Castle, C=AU"; _signKP = CMSTestUtil.makeKeyPair(); _signCert = CMSTestUtil.makeCertificate(_signKP, _signDN, _signKP, _signDN); _origDN = "CN=Bob, OU=Sales, O=Bouncy Castle, C=AU"; _origKP = CMSTestUtil.makeKeyPair(); _origCert = CMSTestUtil.makeCertificate(_origKP, _origDN, _signKP, _signDN); _reciDN = "CN=Doug, OU=Sales, O=Bouncy Castle, C=AU"; _reciKP = CMSTestUtil.makeKeyPair(); _reciCert = CMSTestUtil.makeCertificate(_reciKP, _reciDN, _signKP, _signDN); _origEcKP = CMSTestUtil.makeEcDsaKeyPair(); _reciEcKP = CMSTestUtil.makeEcDsaKeyPair(); _reciEcCert = CMSTestUtil.makeCertificate(_reciEcKP, _reciDN, _signKP, _signDN); } } public static void main( String args[]) throws Exception { junit.textui.TestRunner.run(EnvelopedDataTest.suite()); } public static Test suite() throws Exception { init(); return new CMSTestSetup(new TestSuite(EnvelopedDataTest.class)); } public void testKeyTrans() throws Exception { byte[] data = "WallaWallaWashington".getBytes(); CMSEnvelopedDataGenerator edGen = new CMSEnvelopedDataGenerator(); edGen.addKeyTransRecipient(_reciCert); CMSEnvelopedData ed = edGen.generate( new CMSProcessableByteArray(data), CMSEnvelopedDataGenerator.DES_EDE3_CBC, "BC"); RecipientInformationStore recipients = ed.getRecipientInfos(); assertEquals(ed.getEncryptionAlgOID(), CMSEnvelopedDataGenerator.DES_EDE3_CBC); Collection c = recipients.getRecipients(); assertEquals(1, c.size()); Iterator it = c.iterator(); while (it.hasNext()) { RecipientInformation recipient = (RecipientInformation)it.next(); assertEquals(recipient.getKeyEncryptionAlgOID(), PKCSObjectIdentifiers.rsaEncryption.getId()); byte[] recData = recipient.getContent(_reciKP.getPrivate(), "BC"); assertEquals(true, Arrays.equals(data, recData)); } } public void testKeyTransCAST5SunJCE() throws Exception { if (Security.getProvider("SunJCE") == null) { return; } String version = System.getProperty("java.version"); if (version.startsWith("1.4") || version.startsWith("1.3")) { return; } byte[] data = "WallaWallaWashington".getBytes(); CMSEnvelopedDataGenerator edGen = new CMSEnvelopedDataGenerator(); edGen.addKeyTransRecipient(_reciCert); CMSEnvelopedData ed = edGen.generate( new CMSProcessableByteArray(data), CMSEnvelopedDataGenerator.CAST5_CBC, "SunJCE"); RecipientInformationStore recipients = ed.getRecipientInfos(); assertEquals(ed.getEncryptionAlgOID(), CMSEnvelopedDataGenerator.CAST5_CBC); Collection c = recipients.getRecipients(); assertEquals(1, c.size()); Iterator it = c.iterator(); while (it.hasNext()) { RecipientInformation recipient = (RecipientInformation)it.next(); assertEquals(recipient.getKeyEncryptionAlgOID(), PKCSObjectIdentifiers.rsaEncryption.getId()); byte[] recData = recipient.getContent(_reciKP.getPrivate(), "SunJCE"); assertEquals(true, Arrays.equals(data, recData)); } } public void testKeyTransRC4() throws Exception { byte[] data = "WallaWallaBouncyCastle".getBytes(); CMSEnvelopedDataGenerator edGen = new CMSEnvelopedDataGenerator(); edGen.addKeyTransRecipient(_reciCert); CMSEnvelopedData ed = edGen.generate( new CMSProcessableByteArray(data), "1.2.840.113549.3.4", "BC"); RecipientInformationStore recipients = ed.getRecipientInfos(); assertEquals(ed.getEncryptionAlgOID(), "1.2.840.113549.3.4"); Collection c = recipients.getRecipients(); assertEquals(1, c.size()); Iterator it = c.iterator(); while (it.hasNext()) { RecipientInformation recipient = (RecipientInformation)it.next(); byte[] recData = recipient.getContent(_reciKP.getPrivate(), "BC"); assertEquals(true, Arrays.equals(data, recData)); } } public void testKeyTrans128RC4() throws Exception { byte[] data = "WallaWallaBouncyCastle".getBytes(); CMSEnvelopedDataGenerator edGen = new CMSEnvelopedDataGenerator(); edGen.addKeyTransRecipient(_reciCert); CMSEnvelopedData ed = edGen.generate( new CMSProcessableByteArray(data), "1.2.840.113549.3.4", 128, "BC"); RecipientInformationStore recipients = ed.getRecipientInfos(); assertEquals(ed.getEncryptionAlgOID(), "1.2.840.113549.3.4"); Collection c = recipients.getRecipients(); Iterator it = c.iterator(); if (it.hasNext()) { RecipientInformation recipient = (RecipientInformation)it.next(); byte[] recData = recipient.getContent(_reciKP.getPrivate(), "BC"); assertEquals(true, Arrays.equals(data, recData)); } else { fail("no recipient found"); } } public void testKeyTransODES() throws Exception { byte[] data = "WallaWallaBouncyCastle".getBytes(); CMSEnvelopedDataGenerator edGen = new CMSEnvelopedDataGenerator(); edGen.addKeyTransRecipient(_reciCert); CMSEnvelopedData ed = edGen.generate( new CMSProcessableByteArray(data), "1.3.14.3.2.7", "BC"); RecipientInformationStore recipients = ed.getRecipientInfos(); assertEquals(ed.getEncryptionAlgOID(), "1.3.14.3.2.7"); Collection c = recipients.getRecipients(); Iterator it = c.iterator(); if (it.hasNext()) { RecipientInformation recipient = (RecipientInformation)it.next(); byte[] recData = recipient.getContent(_reciKP.getPrivate(), "BC"); assertEquals(true, Arrays.equals(data, recData)); } else { fail("no recipient found"); } } public void testKeyTransSmallAES() throws Exception { byte[] data = new byte[] { 0, 1, 2, 3 }; CMSEnvelopedDataGenerator edGen = new CMSEnvelopedDataGenerator(); edGen.addKeyTransRecipient(_reciCert); CMSEnvelopedData ed = edGen.generate( new CMSProcessableByteArray(data), CMSEnvelopedDataGenerator.AES128_CBC, "BC"); RecipientInformationStore recipients = ed.getRecipientInfos(); assertEquals(ed.getEncryptionAlgOID(), CMSEnvelopedDataGenerator.AES128_CBC); Collection c = recipients.getRecipients(); Iterator it = c.iterator(); if (it.hasNext()) { RecipientInformation recipient = (RecipientInformation)it.next(); byte[] recData = recipient.getContent(_reciKP.getPrivate(), "BC"); assertEquals(true, Arrays.equals(data, recData)); } else { fail("no recipient found"); } } public void testKeyTransCAST5() throws Exception { tryKeyTrans(CMSEnvelopedDataGenerator.CAST5_CBC, new DERObjectIdentifier(CMSEnvelopedDataGenerator.CAST5_CBC), ASN1Sequence.class); } public void testKeyTransAES128() throws Exception { tryKeyTrans(CMSEnvelopedDataGenerator.AES128_CBC, NISTObjectIdentifiers.id_aes128_CBC, DEROctetString.class); } public void testKeyTransAES192() throws Exception { tryKeyTrans(CMSEnvelopedDataGenerator.AES192_CBC, NISTObjectIdentifiers.id_aes192_CBC, DEROctetString.class); } public void testKeyTransAES256() throws Exception { tryKeyTrans(CMSEnvelopedDataGenerator.AES256_CBC, NISTObjectIdentifiers.id_aes256_CBC, DEROctetString.class); } public void testKeyTransSEED() throws Exception { tryKeyTrans(CMSEnvelopedDataGenerator.SEED_CBC, KISAObjectIdentifiers.id_seedCBC, DEROctetString.class); } public void testKeyTransCamellia128() throws Exception { tryKeyTrans(CMSEnvelopedDataGenerator.CAMELLIA128_CBC, NTTObjectIdentifiers.id_camellia128_cbc, DEROctetString.class); } public void testKeyTransCamellia192() throws Exception { tryKeyTrans(CMSEnvelopedDataGenerator.CAMELLIA192_CBC, NTTObjectIdentifiers.id_camellia192_cbc, DEROctetString.class); } public void testKeyTransCamellia256() throws Exception { tryKeyTrans(CMSEnvelopedDataGenerator.CAMELLIA256_CBC, NTTObjectIdentifiers.id_camellia256_cbc, DEROctetString.class); } private void tryKeyTrans(String generatorOID, DERObjectIdentifier checkOID, Class asn1Params) throws Exception { byte[] data = "WallaWallaWashington".getBytes(); CMSEnvelopedDataGenerator edGen = new CMSEnvelopedDataGenerator(); edGen.addKeyTransRecipient(_reciCert); CMSEnvelopedData ed = edGen.generate( new CMSProcessableByteArray(data), generatorOID, "BC"); RecipientInformationStore recipients = ed.getRecipientInfos(); assertEquals(checkOID.getId(), ed.getEncryptionAlgOID()); if (asn1Params != null) { ASN1InputStream aIn = new ASN1InputStream(ed.getEncryptionAlgParams()); assertTrue(asn1Params.isAssignableFrom(aIn.readObject().getClass())); } Collection c = recipients.getRecipients(); assertEquals(1, c.size()); Iterator it = c.iterator(); if (!it.hasNext()) { fail("no recipients found"); } while (it.hasNext()) { RecipientInformation recipient = (RecipientInformation)it.next(); assertEquals(recipient.getKeyEncryptionAlgOID(), PKCSObjectIdentifiers.rsaEncryption.getId()); byte[] recData = recipient.getContent(_reciKP.getPrivate(), "BC"); assertEquals(true, Arrays.equals(data, recData)); } } public void testErrorneousKEK() throws Exception { byte[] data = "WallaWallaWashington".getBytes(); SecretKey kek = new SecretKeySpec(new byte[] { 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16 }, "AES"); CMSEnvelopedData ed = new CMSEnvelopedData(oldKEK); RecipientInformationStore recipients = ed.getRecipientInfos(); assertEquals(ed.getEncryptionAlgOID(), CMSEnvelopedDataGenerator.DES_EDE3_CBC); Collection c = recipients.getRecipients(); Iterator it = c.iterator(); if (it.hasNext()) { RecipientInformation recipient = (RecipientInformation)it.next(); assertEquals(recipient.getKeyEncryptionAlgOID(), NISTObjectIdentifiers.id_aes128_wrap.getId()); byte[] recData = recipient.getContent(kek, "BC"); assertEquals(true, Arrays.equals(data, recData)); } else { fail("no recipient found"); } } public void testDESKEK() throws Exception { tryKekAlgorithm(CMSTestUtil.makeDesede192Key(), new DERObjectIdentifier("1.2.840.113549.1.9.16.3.6")); } public void testRC2128KEK() throws Exception { tryKekAlgorithm(CMSTestUtil.makeRC2128Key(), new DERObjectIdentifier("1.2.840.113549.1.9.16.3.7")); } public void testAES128KEK() throws Exception { tryKekAlgorithm(CMSTestUtil.makeAESKey(128), NISTObjectIdentifiers.id_aes128_wrap); } public void testAES192KEK() throws Exception { tryKekAlgorithm(CMSTestUtil.makeAESKey(192), NISTObjectIdentifiers.id_aes192_wrap); } public void testAES256KEK() throws Exception { tryKekAlgorithm(CMSTestUtil.makeAESKey(256), NISTObjectIdentifiers.id_aes256_wrap); } public void testSEED128KEK() throws Exception { tryKekAlgorithm(CMSTestUtil.makeSEEDKey(), KISAObjectIdentifiers.id_npki_app_cmsSeed_wrap); } public void testCamellia128KEK() throws Exception { tryKekAlgorithm(CMSTestUtil.makeCamelliaKey(128), NTTObjectIdentifiers.id_camellia128_wrap); } public void testCamellia192KEK() throws Exception { tryKekAlgorithm(CMSTestUtil.makeCamelliaKey(192), NTTObjectIdentifiers.id_camellia192_wrap); } public void testCamellia256KEK() throws Exception { tryKekAlgorithm(CMSTestUtil.makeCamelliaKey(256), NTTObjectIdentifiers.id_camellia256_wrap); } private void tryKekAlgorithm(SecretKey kek, DERObjectIdentifier algOid) throws NoSuchAlgorithmException, NoSuchProviderException, CMSException { byte[] data = "WallaWallaWashington".getBytes(); CMSEnvelopedDataGenerator edGen = new CMSEnvelopedDataGenerator(); byte[] kekId = new byte[] { 1, 2, 3, 4, 5 }; edGen.addKEKRecipient(kek, kekId); CMSEnvelopedData ed = edGen.generate( new CMSProcessableByteArray(data), CMSEnvelopedDataGenerator.DES_EDE3_CBC, "BC"); RecipientInformationStore recipients = ed.getRecipientInfos(); Collection c = recipients.getRecipients(); Iterator it = c.iterator(); assertEquals(ed.getEncryptionAlgOID(), CMSEnvelopedDataGenerator.DES_EDE3_CBC); if (it.hasNext()) { RecipientInformation recipient = (RecipientInformation)it.next(); assertEquals(algOid.getId(), recipient.getKeyEncryptionAlgOID()); byte[] recData = recipient.getContent(kek, "BC"); assertTrue(Arrays.equals(data, recData)); } else { fail("no recipient found"); } } public void testECKeyAgree() throws Exception { byte[] data = Hex.decode("504b492d4320434d5320456e76656c6f706564446174612053616d706c65"); CMSEnvelopedDataGenerator edGen = new CMSEnvelopedDataGenerator(); edGen.addKeyAgreementRecipient(CMSEnvelopedDataGenerator.ECDH_SHA1KDF, _origEcKP.getPrivate(), _origEcKP.getPublic(), _reciEcCert, CMSEnvelopedDataGenerator.AES128_WRAP, "BC"); CMSEnvelopedData ed = edGen.generate( new CMSProcessableByteArray(data), CMSEnvelopedDataGenerator.AES128_CBC, "BC"); RecipientInformationStore recipients = ed.getRecipientInfos(); assertEquals(ed.getEncryptionAlgOID(), CMSEnvelopedDataGenerator.AES128_CBC); Collection c = recipients.getRecipients(); Iterator it = c.iterator(); if (it.hasNext()) { RecipientInformation recipient = (RecipientInformation)it.next(); byte[] recData = recipient.getContent(_reciEcKP.getPrivate(), "BC"); assertEquals(true, Arrays.equals(data, recData)); } else { fail("no recipient found"); } } public void testECKeyAgreeVectors() throws Exception { PKCS8EncodedKeySpec privSpec = new PKCS8EncodedKeySpec(ecKeyAgreeKey); KeyFactory fact = KeyFactory.getInstance("ECDH", "BC"); PrivateKey privKey = fact.generatePrivate(privSpec); verifyECKeyAgreeVectors(privKey, "2.16.840.1.101.3.4.1.42", ecKeyAgreeMsgAES256); verifyECKeyAgreeVectors(privKey, "2.16.840.1.101.3.4.1.2", ecKeyAgreeMsgAES128); verifyECKeyAgreeVectors(privKey, "1.2.840.113549.3.7", ecKeyAgreeMsgDESEDE); } /* public void testECMQVKeyAgreeVectors() throws Exception { PKCS8EncodedKeySpec privSpec = new PKCS8EncodedKeySpec(ecKeyAgreeKey); KeyFactory fact = KeyFactory.getInstance("ECDH", "BC"); PrivateKey privKey = fact.generatePrivate(privSpec); verifyECMQVKeyAgreeVectors(privKey, "2.16.840.1.101.3.4.1.2", ecMQVKeyAgreeMsgAES128); } */ public void testPasswordAES256() throws Exception { passwordTest(CMSEnvelopedDataGenerator.AES256_CBC); passwordUTF8Test(CMSEnvelopedDataGenerator.AES256_CBC); } public void testPasswordDESEDE() throws Exception { passwordTest(CMSEnvelopedDataGenerator.DES_EDE3_CBC); passwordUTF8Test(CMSEnvelopedDataGenerator.DES_EDE3_CBC); } public void testRFC4134ex5_1() throws Exception { byte[] data = Hex.decode("5468697320697320736f6d652073616d706c6520636f6e74656e742e"); KeyFactory kFact = KeyFactory.getInstance("RSA", "BC"); Key key = kFact.generatePrivate(new PKCS8EncodedKeySpec(bobPrivRsaEncrypt)); CMSEnvelopedData ed = new CMSEnvelopedData(rfc4134ex5_1); RecipientInformationStore recipients = ed.getRecipientInfos(); assertEquals("1.2.840.113549.3.7", ed.getEncryptionAlgOID()); Collection c = recipients.getRecipients(); Iterator it = c.iterator(); if (it.hasNext()) { RecipientInformation recipient = (RecipientInformation)it.next(); byte[] recData = recipient.getContent(key, "BC"); assertEquals(true, Arrays.equals(data, recData)); } else { fail("no recipient found"); } } public void testRFC4134ex5_2() throws Exception { byte[] data = Hex.decode("5468697320697320736f6d652073616d706c6520636f6e74656e742e"); KeyFactory kFact = KeyFactory.getInstance("RSA", "BC"); Key key = kFact.generatePrivate(new PKCS8EncodedKeySpec(bobPrivRsaEncrypt)); CMSEnvelopedData ed = new CMSEnvelopedData(rfc4134ex5_2); RecipientInformationStore recipients = ed.getRecipientInfos(); assertEquals("1.2.840.113549.3.2", ed.getEncryptionAlgOID()); Collection c = recipients.getRecipients(); Iterator it = c.iterator(); if (it.hasNext()) { while (it.hasNext()) { RecipientInformation recipient = (RecipientInformation)it.next(); byte[] recData; if (recipient instanceof KeyTransRecipientInformation) { recData = recipient.getContent(key, "BC"); assertEquals(true, Arrays.equals(data, recData)); } } } else { fail("no recipient found"); } } public void testOriginatorInfo() throws Exception { CMSEnvelopedData env = new CMSEnvelopedData(CMSSampleMessages.originatorMessage); RecipientInformationStore recipients = env.getRecipientInfos(); assertEquals(CMSEnvelopedDataGenerator.DES_EDE3_CBC, env.getEncryptionAlgOID()); } private void passwordTest(String algorithm) throws Exception { byte[] data = Hex.decode("504b492d4320434d5320456e76656c6f706564446174612053616d706c65"); CMSEnvelopedDataGenerator edGen = new CMSEnvelopedDataGenerator(); edGen.addPasswordRecipient(new PKCS5Scheme2PBEKey("password".toCharArray(), new byte[20], 5), algorithm); CMSEnvelopedData ed = edGen.generate( new CMSProcessableByteArray(data), CMSEnvelopedDataGenerator.AES128_CBC, "BC"); RecipientInformationStore recipients = ed.getRecipientInfos(); assertEquals(ed.getEncryptionAlgOID(), CMSEnvelopedDataGenerator.AES128_CBC); Collection c = recipients.getRecipients(); Iterator it = c.iterator(); if (it.hasNext()) { RecipientInformation recipient = (RecipientInformation)it.next(); byte[] recData = recipient.getContent(new PKCS5Scheme2PBEKey("password".toCharArray(), new byte[20], 5), "BC"); assertEquals(true, Arrays.equals(data, recData)); } else { fail("no recipient found"); } } private void passwordUTF8Test(String algorithm) throws Exception { byte[] data = Hex.decode("504b492d4320434d5320456e76656c6f706564446174612053616d706c65"); CMSEnvelopedDataGenerator edGen = new CMSEnvelopedDataGenerator(); edGen.addPasswordRecipient(new PKCS5Scheme2UTF8PBEKey("abc\u5639\u563b".toCharArray(), new byte[20], 5), algorithm); CMSEnvelopedData ed = edGen.generate( new CMSProcessableByteArray(data), CMSEnvelopedDataGenerator.AES128_CBC, "BC"); RecipientInformationStore recipients = ed.getRecipientInfos(); assertEquals(ed.getEncryptionAlgOID(), CMSEnvelopedDataGenerator.AES128_CBC); Collection c = recipients.getRecipients(); Iterator it = c.iterator(); if (it.hasNext()) { RecipientInformation recipient = (RecipientInformation)it.next(); byte[] recData = recipient.getContent(new PKCS5Scheme2UTF8PBEKey("abc\u5639\u563b".toCharArray(), new byte[20], 5), "BC"); assertEquals(true, Arrays.equals(data, recData)); } else { fail("no recipient found"); } } private void verifyECKeyAgreeVectors(PrivateKey privKey, String wrapAlg, byte[] message) throws CMSException, GeneralSecurityException { byte[] data = Hex.decode("504b492d4320434d5320456e76656c6f706564446174612053616d706c65"); CMSEnvelopedData ed = new CMSEnvelopedData(message); RecipientInformationStore recipients = ed.getRecipientInfos(); Collection c = recipients.getRecipients(); Iterator it = c.iterator(); assertEquals(wrapAlg, ed.getEncryptionAlgOID()); if (it.hasNext()) { RecipientInformation recipient = (RecipientInformation)it.next(); assertEquals("1.3.133.16.840.63.0.2", recipient.getKeyEncryptionAlgOID()); byte[] recData = recipient.getContent(privKey, "BC"); assertTrue(Arrays.equals(data, recData)); } else { fail("no recipient found"); } } private void verifyECMQVKeyAgreeVectors(PrivateKey privKey, String wrapAlg, byte[] message) throws CMSException, GeneralSecurityException { byte[] data = Hex.decode("504b492d4320434d5320456e76656c6f706564446174612053616d706c65"); CMSEnvelopedData ed = new CMSEnvelopedData(message); RecipientInformationStore recipients = ed.getRecipientInfos(); Collection c = recipients.getRecipients(); Iterator it = c.iterator(); assertEquals(wrapAlg, ed.getEncryptionAlgOID()); if (it.hasNext()) { RecipientInformation recipient = (RecipientInformation)it.next(); assertEquals("1.3.133.16.840.63.0.16", recipient.getKeyEncryptionAlgOID()); byte[] recData = recipient.getContent(privKey, "BC"); assertTrue(Arrays.equals(data, recData)); } else { fail("no recipient found"); } } } bouncycastle-1.49.orig/test/jdk1.4/org/bouncycastle/jce/0000755000175000017500000000000012152033550022422 5ustar ebourgebourgbouncycastle-1.49.orig/test/jdk1.4/org/bouncycastle/jce/provider/0000755000175000017500000000000012152033550024254 5ustar ebourgebourgbouncycastle-1.49.orig/test/jdk1.4/org/bouncycastle/jce/provider/test/0000755000175000017500000000000012152033550025233 5ustar ebourgebourgbouncycastle-1.49.orig/test/jdk1.4/org/bouncycastle/jce/provider/test/PKCS12StoreTest.java0000644000175000017500000010710410452142654030670 0ustar ebourgebourgpackage org.bouncycastle.jce.provider.test; import java.io.ByteArrayInputStream; import java.io.ByteArrayOutputStream; import java.math.BigInteger; import java.security.KeyFactory; import java.security.KeyStore; import java.security.PrivateKey; import java.security.PublicKey; import java.security.Security; import java.security.cert.Certificate; import java.security.cert.X509Certificate; import java.security.interfaces.RSAPrivateKey; import java.security.spec.RSAPrivateCrtKeySpec; import java.security.spec.RSAPublicKeySpec; import java.util.Date; import java.util.Enumeration; import java.util.Hashtable; import org.bouncycastle.jce.X509Principal; import org.bouncycastle.x509.X509V3CertificateGenerator; import org.bouncycastle.jce.provider.BouncyCastleProvider; import org.bouncycastle.util.encoders.Base64; import org.bouncycastle.util.test.SimpleTest; /** * Exercise the various key stores, making sure we at least get back what we put in! *

    * This tests both the PKCS12 key store. */ public class PKCS12StoreTest extends SimpleTest { static char[] passwd = { 'h', 'e', 'l', 'l', 'o', ' ', 'w', 'o', 'r', 'l', 'd' }; // // pkcs-12 pfx-pdu // byte[] pkcs12 = Base64.decode( "MIACAQMwgAYJKoZIhvcNAQcBoIAkgAQBMAQBgAQBMAQBgAQBBgQBCQQJKoZI" + "hvcNAQcBBAGgBAGABAEkBAGABAEEBAEBBAEwBAEEBAEDBAOCAzQEAQQEAQEE" + "ATAEAQQEAQMEA4IDMAQBBAQBAQQBBgQBBAQBAQQBCwQBBAQBCwQLKoZIhvcN" + "AQwKAQIEAQQEAQEEAaAEAQQEAQMEA4ICpQQBBAQBAQQBMAQBBAQBAwQDggKh" + "BAEEBAEBBAEwBAEEBAEBBAEbBAEEBAEBBAEGBAEEBAEBBAEKBAEEBAEKBAoq" + "hkiG9w0BDAEDBAEEBAEPBA8wDQQIoagiwNZPJR4CAQEEAQQEAQEEAQQEAQQE" + "AQMEA4ICgAQBBAQDggKABIICgEPG0XlhMFyrs4ZWDrvEzl51ICfXd6K2ql2l" + "nnxhszUbigtSj6x49VEx4PfOB9fQFeidc5L5An+nKp646NBMIY0UwXGs8BLQ" + "au59jtOs987+l7QYIvl6fdGUIuLPhVSnZZDyqD+HQjU/0/ccKFHRif4tlEQq" + "aErvZbFeH0pg4ijf1HfgX6gBJGRKdO+msa4qKGnZdHCSLZehyyxvxAmURetg" + "yhtEl7RmedTB+4TDs7atekqxkNlD9tfwDUX6sb0IH6qbEA6P/DlVMdaD54Cl" + "QDxRzOfIIjklZhv5OMFWtPK0aYPcqyxzLpw1qRAyoTVXpidkj/hpIpgCVBP/" + "k5s2+WdGbLgA/4/zSrF6feRCE5llzM2IGxiHVq4oPzzngl3R+Fi5VCPDMcuW" + "NRuIOzJA+RNV2NPOE/P3knThDnwiImq+rfxmvZ1u6T06s20RmWK6cxp7fTEw" + "lQ9BOsv+mmyV8dr6cYJq4IlRzHdFOyEUBDwfHThyribNKKobO50xh2f93xYj" + "Rn5UMOQBJIe3b7OKZt5HOIMrJSZO02IZgvImi9yQWi96PnWa419D1cAsLWvM" + "xiN0HqZMbDFfxVM2BZmsxiexLhkHWKwLqfQDzRjJfmVww8fnXpWZhFXKyut9" + "gMGEyCNoba4RU3QI/wHKWYaK74qtJpsucuLWBH6UcsHsCry6VZkwRxWwC0lb" + "/F3Bm5UKHax5n9JHJ2amQm9zW3WJ0S5stpPObfmg5ArhbPY+pVOsTqBRlop1" + "bYJLD/X8Qbs468Bwzej0FhoEU59ZxFrbjLSBsMUYrVrwD83JE9kEazMLVchc" + "uCB9WT1g0hxYb7VA0BhOrWhL8F5ZH72RMCYLPI0EAQQEAQEEATEEAQQEAQEE" + "AXgEAQQEAQEEATAEAQQEAQEEAVEEAQQEAQEEAQYEAQQEAQEEAQkEAQQEAQkE" + "CSqGSIb3DQEJFAQBBAQBAQQBMQQBBAQBAQQBRAQBBAQBAQQBHgQBBAQBAQQB" + "QgQBBAQBQgRCAEQAYQB2AGkAZAAgAEcALgAgAEgAbwBvAGsAJwBzACAAVgBl" + "AHIAaQBTAGkAZwBuACwAIABJAG4AYwAuACAASQBEBAEEBAEBBAEwBAEEBAEB" + "BAEjBAEEBAEBBAEGBAEEBAEBBAEJBAEEBAEJBAkqhkiG9w0BCRUEAQQEAQEE" + "ATEEAQQEAQEEARYEAQQEAQEEAQQEAQQEAQEEARQEAQQEARQEFKEcMJ798oZL" + "FkH0OnpbUBnrTLgWBAIAAAQCAAAEAgAABAEwBAGABAEGBAEJBAkqhkiG9w0B" + "BwYEAaAEAYAEATAEAYAEAQIEAQEEAQAEATAEAYAEAQYEAQkECSqGSIb3DQEH" + "AQQBMAQBGwQBBgQBCgQKKoZIhvcNAQwBBgQPMA0ECEE7euvmxxwYAgEBBAGg" + "BAGABAEEBAEIBAgQIWDGlBWxnwQBBAQBCAQI2WsMhavhSCcEAQQEAQgECPol" + "uHJy9bm/BAEEBAEQBBCiRxtllKXkJS2anKD2q3FHBAEEBAEIBAjKy6BRFysf" + "7gQBBAQDggMwBIIDMJWRGu2ZLZild3oz7UBdpBDUVMOA6eSoWiRIfVTo4++l" + "RUBm8TpmmGrVkV32PEoLkoV+reqlyWCvqqSjRzi3epQiVwPQ6PV+ccLqxDhV" + "pGWDRQ5UttDBC2+u4fUQVZi2Z1i1g2tsk6SzB3MKUCrjoWKvaDUUwXo5k9Vz" + "qSLWCLTZCjs3RaY+jg3NbLZYtfMDdYovhCU2jMYV9adJ8MxxmJRz+zPWAJph" + "LH8hhfkKG+wJOSszqk9BqGZUa/mnZyzeQSMTEFga1ZB/kt2e8SZFWrTZEBgJ" + "oszsL5MObbwMDowNurnZsnS+Mf7xi01LeG0VT1fjd6rn9BzVwuMwhoqyoCNo" + "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"); byte[] certUTF = Base64.decode( "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" + "RgICCAA="); byte[] pkcs12noFriendly = Base64.decode( "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" + "tTy3wnQisALy9aYECKiM2gZrLi+fAAA="); static char[] noFriendlyPassword = "sschette12".toCharArray(); byte[] pkcs12StorageIssue = Base64.decode( "MIIO8QIBAzCCDrEGCSqGSIb3DQEHAaCCDqIEgg6eMIIOmjCCBBMGCSqGSIb3" + "DQEHAaCCBAQEggQAMIID/DCCA/gGCyqGSIb3DQEMCgECoIICtjCCArIwHAYK" + "KoZIhvcNAQwBAzAOBAgURJ+/5hA2pgICB9AEggKQYZ4POE8clgH9Bjd1XO8m" + "sr6NiRBiA08CllHSOn2RzyAgHTa+cKaWrEVVJ9mCd9XveSUCoBF9E1C3jSl0" + "XIqLNgYd6mWK9BpeMRImM/5crjy///K4ab9kymzkc5qc0pIpdCQCZ04YmtFP" + "B80VCgyaoh2xoxqgjBCIgdSg5XdepdA5nXkG9EsQ1oVUyCykv20lKgKKRseG" + "Jo23AX8YUYR7ANqP2gz9lvlX6RBczuoZ62ujopUexiQgt5SZx97sgo3o/b/C" + "px17A2L4wLdeAYCMCsZhC2UeaqnZCHSsvnPZfRGiuSEGbV5gHLmXszLDaEdQ" + "Bo873GTpKTTzBfRFzNCtYtZRqh2AUsInWZWQUcCeX6Ogwa0wTonkp18/tqsh" + "Fj1fVpnsRmjJTTXFxkPtUw5GPJnDAM0t1xqV7kOjN76XnZrMyk2azQ1Mf3Hn" + "sGpF+VRGH6JtxbM0Jm5zD9uHcmkSfNR3tP/+vHOB1mkIR9tD2cHvBg7pAlPD" + "RfDVWynhS+UBNlQ0SEM/pgR7PytRSUoKc/hhe3N8VerF7VL3BwWfBLlZFYZH" + "FvPQg4coxF7+We7nrSQfXvdVBP9Zf0PTdf3pbZelGCPVjOzbzY/o/cB23IwC" + "ONxlY8SC1nJDXrPZ5sY51cg/qUqor056YqipRlI6I+FoTMmMDKPAiV1V5ibo" + "DNQJkyv/CAbTX4+oFlxgddTwYcPZgd/GoGjiP9yBHHdRISatHwMcM06CzXJS" + "s3MhzXWD4aNxvvSpXAngDLdlB7cm4ja2klmMzL7IuxzLXFQFFvYf7IF5I1pC" + "YZOmTlJgp0efL9bHjuHFnh0S0lPtlGDOjJ/4YpWvSKDplcPiXhaFVjsUtclE" + "oxCC5xppRm8QWS8xggEtMA0GCSsGAQQBgjcRAjEAMBMGCSqGSIb3DQEJFTEG" + "BAQBAAAAMGkGCSsGAQQBgjcRATFcHloATQBpAGMAcgBvAHMAbwBmAHQAIABS" + "AFMAQQAgAFMAQwBoAGEAbgBuAGUAbAAgAEMAcgB5AHAAdABvAGcAcgBhAHAA" + "aABpAGMAIABQAHIAbwB2AGkAZABlAHIwgZsGCSqGSIb3DQEJFDGBjR6BigA3" + "AGQAZQBmADUAYgA0ADMANgBjAGEAYgBkADAAMAAyAGQAZAAyADkAMAAzAGIA" + "MQA2ADgANgBjADcAOQA0ADgAXwA0ADYAZgAyADYAZgBkADQALQA4ADEAMgBk" + "AC0ANABlAGYAYgAtADgAMAA4ADgALQA0ADUAYQBiADkAMQA5ADEAMAA3AGMA" + "YzCCCn8GCSqGSIb3DQEHBqCCCnAwggpsAgEAMIIKZQYJKoZIhvcNAQcBMBwG" + "CiqGSIb3DQEMAQYwDgQIbr2xdnQ9inMCAgfQgIIKOHg9VKz+jlM+3abi3cp6" + "/XMathxDSEJLrxJs6j5DAVX17S4sw1Q/1pptjdMdd8QtTfUB6JpfgJ5Kpn+h" + "gZMf6M8wWue0U/RZN0D9w7o+2n+X3ItdEXu80eJVDOm7I2p8qiXtijbMbXRL" + "Cup1lgfPM5uv2D63/hmWRXLeG8eySrJnKENngpM559V8TI2JcTUBy1ZP3kcH" + "KbcJ/tVPnIIe4qguxfsTmDtAQviGvWUohbt+RGFmtqfgntK7o6b+S8uRSwEs" + "fOU/pnVE9M1ugtNJZI/xeGJq6umZWXA/OrAcK7feWUwqRvfivDGQJEoggByd" + "4/g92PhK1JGkwlCb1HdfhOOKKChowQ4zVvSOm+uBxARGhk2i5uW9I20I0vSJ" + "px42O2VFVJweOchfp+wBtSHBKYP1ZXyXWMvOtULClosSeesbYMAwvyBfpYEz" + "3rQt/1iZkqDmEisXk8X1aEKG1KSWaSPyb/+6glWikDm+YdQw3Khu7IZt1l/H" + "qWGecccel+R9mT4YjRzHlahUYk4U+RNVasVpH1Kxz2j3CZqL+b3jQOwSAPd/" + "hKI+S/pjIpBPfiC4WxORAzGZzY2j+a79B70h1DO1D9jGur3vJDbdmGBNgs6d" + "nonE1B527SICcGeXY1MtnZCLOPvySih0AvOekbN9x2CJg+Hp9e7A3Fxni53/" + "oMLr9wGRRDki72eXCXW98mU8VJofoWYS1/VBLXGf/f+tJ9J02PpzxleqPH9T" + "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" + "g141BQ=="); static char[] storagePassword = "pass".toCharArray(); byte[] pkcs12nopass = Base64.decode( "MIIMvgIBAzCCDIQGCSqGSIb3DQEHAaCCDHUEggxxMIIMbTCCCS8GCSqGSIb3" + "DQEHBqCCCSAwggkcAgEAMIIJFQYJKoZIhvcNAQcBMBwGCiqGSIb3DQEMAQYw" + "DgQIfnlhuZRR6/YCAggAgIII6DYgeRwq5n9kzvohZ3JuK+fB+9jZ7Or6EGBA" + "GDxtBfHmSNUBWJEV/I8wV1zrKKoW/CaoZfA61pyrVZRd/roaqBx/koTFoh/g" + "woyyWTRV9gYTXSVqPQgCH+e2dISAa6UGO+/YOWOOwG2X3t8tS+3FduFQFLt5" + "cvUP98zENdm57Aef5pKpBSZDLIAoTASfmqwszWABRh2p/wKOHcCQ9Aj2e2vs" + "pls/ntIv81MqPuxHttwX8e+3dKWGFrJRztLpCD2aua8VkSsHFsPxEHkezX4O" + "6/VCjMCRFGophTS4dgKKtQIhZ9i/ESlr6sGKgIpyG99ALFpNEhtTKe+T3boE" + "sEkhGDquSpu4PGz2m0W5sej1DyFkKX4zIbeMDAb1y3O7aP0F+Llo9QSeGsOA" + "aCwND3NUAKBMOHzwdyNQcuCGCqY8j5rrSt99A5FMs3UVW3XU6hRCx7JlzO05" + "PNCkcPRSnKSNzBhIR5W0qj4PAZnQTfX+wbtUaDLIqsObX4Muh2l3gl+JmdpO" + "53U7ILqN8PAPly1eT+fIrUmlMmFhvo6LbTB7B2K728wsA/5wROlud/mOQz4s" + "quS288YsnVc9ExSZKodWa3Pqcdb/cgKNJYDxrR6/eBHOj+0RLK/1yTK9ghj7" + "IPYHoEqQbw768WK92RjM+RFGlXASkQhR9y4weWj/388uAWMIbQ+R2Zi4nb31" + "knjqRPFThysG1bsRL04/9PgysaasfS9KYOeAlLqp+Ar4gJrof5fytBuY+6wm" + "/J8eEdNw7VPV1cz/4rhrd2sfJQwDEN/iZoy8rTwe7wozpwZI0lwH11BBbav+" + "1AMfI79jjxhqOeo7uxE2NzUmSd05JYI7a94tcRzGQyGEKpGxYCRamzFW23qb" + "vG5Hcqi7Tdd7eTxw4c60l/vQLSo38g6ST5yZrK3URLiAtpioPyjrq2jnVfie" + "QLsiAHhpHF01+t+OcKv3UjwdEyBmQ34h9klwiG7iwBFXZaPXFCF2Np1TqFVG" + "jjBzmB+hRddEiYwN+XGCKB2Cvgc5ZMQ8LG9jQmEKLmOjuumz1ciAVY2qtl1s" + "HYSvfNsIAV/gGzHshOVF19JmGtcQt3pMtupoRh+sh8jY2/x5eIKrj2Jx6HPd" + "p/6IPUr54j0xSd6j7gWuXMj/eKp/utMNuBzAhkydnhXYedvTDYIj7SyPPIHa" + "qtam8rxTDWn2AOxp7OXTgPmo1GU2zW1OLL1D3MFlS+oaRMfhgNrhW+QP5ay6" + "ge4QLijpnSM+p0CbFAOClwzgdJV56bBVV09sDqSBXnG9MeEv5nDaH3I+GpPA" + "UgDkaI4zT61kaGgk0uNMf3czy2ycoQzTx0iHDTXSdSqvUC1yFza8UG4AYaKz" + "14gtSL7StvZtK0Y8oI084BINI1LgrWyrOLj7vkds4WrKhXm21BtM1GbN/pFh" + "XI41h+XoD8KnEPqJ36rAgBo1uHqTNJCC7YikDE/dEvq6MkOx+Nug1YZRHEyi" + "3AHry5u1HJHtxT34HXBwRXvnstuFhvU6cjc1WY1dJhu1p82TGnx7OBo/QbcM" + "8MRrWmWuU5eW4jWbriGNGYfvZy+tHnGwy0bIeqrsHOG6/JwvfmYYXe64sryH" + "5Qo96SZtcTJZaNFwuBY+bFUuOWm8YrT1L7Gl2Muf3pEVtNHLeYARBo1jEAym" + "Cb4jw0oodZqbPKdyyzUZu69fdTJiQkMUcKDfHJEGK0Li9SvtdqJLiiJs57Tb" + "YfOvn+TIuC40ssJFtmtlGCVH/0vtKLWYeW1NYAMzgI/nlhQ7W6Aroh8sZnqv" + "SwxeQmRJaVLxiV6YveTKuVlCbqNVLeEtKYAujgnJtPemGCPbwZpwlBw6V+Dz" + "oXveOBcUqATztWJeNv7RbU0Mk7k057+DNxXBIU+eHRGquyHQSBXxBbA+OFuu" + "4SPfEAyoYed0HEaoKN9lIsBW1xTROI30MZvaJXvPdLsa8izXGPLnTGmoI+fv" + "tJ644HtBCCCr3Reu82ZsTSDMxspZ9aa4ro9Oza+R5eULXDhVXedbhJBYiPPo" + "J37El5lRqOgu2SEilhhVQq3ZCugsinCaY9P/RtWG4CFnH1IcIT5+/mivB48I" + "2XfH6Xq6ziJdj2/r86mhEnz9sKunNvYPBDGlOvI7xucEf9AiEQoTR1xyFDbW" + "ljL4BsJqgsHN02LyUzLwqMstwv+/JH1wUuXSK40Kik/N7+jEFW2C+/N8tN7l" + "RPKSLaTjxVuTfdv/BH1dkV4iGFgpQrdWkWgkb+VZP9xE2mLz715eIAg13x6+" + "n97tc9Hh375xZJqwr3QyYTXWpsK/vx04RThv8p0qMdqKvf3jVQWwnCnoeBv2" + "L4h/uisOLY18qka/Y48ttympG+6DpmzXTwD1LycoG2SOWckCMmJhZK40+zr3" + "NVmWf6iJtbLGMxI/kzTqbTaOfXc2MroertyM1rILRSpgnJFxJfai5Enspr9b" + "SCwlP718jG2lQsnYlw8CuxoZAiaNy4MmC5Y3qNl3hlcggcHeLodyGkSyRsBg" + "cEiKSL7JNvqr0X/nUeW28zVxkmQsWlp3KmST8agf+r+sQvw52fXNLdYznGZV" + "rJrwgNOoRj0Z70MwTns3s/tCqDEsy5Sv/5dZW2uQEe7/wvmsP2WLu73Rwplg" + "1dwi/Uo9lO9dkEzmoIK5wMPCDINxL1K+0Y79q0tIAEMDgaIxmtRpEh8/TEsA" + "UwyEErkDsQqgGviH+ePmawJ/yehYHTRfYUgdUflwApJxRx65pDeSYkiYboMU" + "8WSAQY2nh/p9hLlS4zbz9dCK2tzVyRkJgqNy/c4IpiHEx2l1iipW9vENglqx" + "dYP4uqD8e3OOLjDQKizWx2t1u7GRwoEVQ3d3QzzOvsRcv7h+6vNsmYqE6phe" + "wKFZLctpSn21zkyut444ij4sSr1OG68dEXLY0t0mATfTmXXy5GJBsdK/lLfk" + "YTIPYYeDMle9aEicDqaKqkZUuYPnVchGp8UFMJ3M0n48OMDdDvpzBLTxxZeW" + "cK5v/m3OEo3jgxy9wXfZdz//J3zXXqvX8LpMy1K9X0uCBTz6ERlawviMQhg1" + "1okD5zCCAzYGCSqGSIb3DQEHAaCCAycEggMjMIIDHzCCAxsGCyqGSIb3DQEM" + "CgECoIICpjCCAqIwHAYKKoZIhvcNAQwBAzAOBAj3QoojTSbZqgICCAAEggKA" + "YOSp5XGdnG1pdm9CfvlAaUSHRCOyNLndoUTqteTZjHTEM9bGwNXAx4/R5H2Q" + "PnPm5HB/ynVSXX0uKdW6YlbqUyAdV3eqE4X3Nl+K7ZoXmgAFnMr0tveBhT1b" + "7rTi0TN4twjJzBTkKcxT8XKjvpVizUxGo+Ss5Wk8FrWLHAiC5dZvgRemtGcM" + "w5S09Pwj+qXpjUhX1pB5/63qWPrjVf+Bfmlz4bWcqogGk0i7eg+OdTeWMrW0" + "KR9nD1+/uNEyc4FdGtdIPnM+ax0E+vcco0ExQpTXe0xoX4JW7O71d550Wp89" + "hAVPNrJA5eUbSWNsuz+38gjUJ+4XaAEhcA7HZIp6ZyxtzSJUoh7oqpRktoxu" + "3cSVqVxIqAEqlNn6j0vbKfW91Od5DI5L+BIxY4xqXS7fdwipj9r6qWA8t9QU" + "C2r1A+xXpZ4jEh6inHW9qlfACBBrYf8pSDakSR6yTbaA07LExw0IXz5oiQYt" + "s7yx231CZlOH88bBmruLOIZsJjeg/lf63zI7Gg4F85QG3RqEJnY2pinLUTP7" + "R62VErFZPc2a85r2dbFH1mSQIj/rT1IKe32zIW8xoHC4VwrPkT3bcLFAu2TH" + "5k5zSI/gZUKjPDxb2dwLM4pvsj3gJ9vcFZp6BCuLkZc5rd7CyD8HK9PrBLKd" + "H3Yngy4A08W4U3XUtIux95WE+5O/UEmSF7fr2vT//DwZArGUpBPq4Bikb8cv" + "0wpOwUv8r0DXveeaPsxdipXlt29Ayywcs6KIidLtCaCX6/0u/XtMsGNFS+ah" + "OlumTGBFpbLnagvIf0GKNhbg2lTjflACnxIj8d+QWsnrIU1uC1JRRKCnhpi2" + "veeWd1m8GUb3aTFiMCMGCSqGSIb3DQEJFTEWBBS9g+Xmq/8B462FWFfaLWd/" + "rlFxOTA7BgkqhkiG9w0BCRQxLh4sAEMAZQByAHQAeQBmAGkAawBhAHQAIAB1" + "AHoAeQB0AGsAbwB3AG4AaQBrAGEwMTAhMAkGBSsOAwIaBQAEFKJpUOIj0OtI" + "j2CPp38YIFBEqvjsBAi8G+yhJe3A/wICCAA="); /** * we generate a self signed certificate for the sake of testing - RSA */ public Certificate createCert( PublicKey pubKey, PrivateKey privKey) throws Exception { // // distinguished name table. // Hashtable attrs = new Hashtable(); attrs.put(X509Principal.C, "AU"); attrs.put(X509Principal.O, "The Legion of the Bouncy Castle"); attrs.put(X509Principal.L, "Melbourne"); attrs.put(X509Principal.ST, "Victoria"); attrs.put(X509Principal.EmailAddress, "feedback-crypto@bouncycastle.org"); // // extensions // // // create the certificate - version 3 // X509V3CertificateGenerator certGen = new X509V3CertificateGenerator(); certGen.setSerialNumber(BigInteger.valueOf(1)); certGen.setIssuerDN(new X509Principal(attrs)); certGen.setNotBefore(new Date(System.currentTimeMillis() - 1000L * 60 * 60 * 24 * 30)); certGen.setNotAfter(new Date(System.currentTimeMillis() + (1000L * 60 * 60 * 24 * 30))); certGen.setSubjectDN(new X509Principal(attrs)); certGen.setPublicKey(pubKey); certGen.setSignatureAlgorithm("MD5WithRSAEncryption"); X509Certificate cert = certGen.generateX509Certificate(privKey); cert.checkValidity(new Date()); cert.verify(pubKey); return cert; } public void testPKCS12Store() throws Exception { BigInteger mod = new BigInteger("bb1be8074e4787a8d77967f1575ef72dd7582f9b3347724413c021beafad8f32dba5168e280cbf284df722283dad2fd4abc750e3d6487c2942064e2d8d80641aa5866d1f6f1f83eec26b9b46fecb3b1c9856a303148a5cc899c642fb16f3d9d72f52526c751dc81622c420c82e2cfda70fe8d13f16cc7d6a613a5b2a2b5894d1", 16); KeyStore store = KeyStore.getInstance("PKCS12", "BC"); ByteArrayInputStream stream = new ByteArrayInputStream(pkcs12); store.load(stream, passwd); Enumeration en = store.aliases(); String pName = null; while (en.hasMoreElements()) { String n = (String)en.nextElement(); if (store.isKeyEntry(n)) { pName = n; } } PrivateKey key = (PrivateKey)store.getKey(pName, null); if (!((RSAPrivateKey)key).getModulus().equals(mod)) { fail("Modulus doesn't match."); } Certificate[] ch = store.getCertificateChain(pName); if (ch.length != 3) { fail("chain was wrong length"); } if (!((X509Certificate)ch[0]).getSerialNumber().equals(new BigInteger("96153094170511488342715101755496684211"))) { fail("chain[0] wrong certificate."); } if (!((X509Certificate)ch[1]).getSerialNumber().equals(new BigInteger("279751514312356623147411505294772931957"))) { fail("chain[1] wrong certificate."); } if (!((X509Certificate)ch[2]).getSerialNumber().equals(new BigInteger("11341398017"))) { fail("chain[2] wrong certificate."); } // // save test // ByteArrayOutputStream bOut = new ByteArrayOutputStream(); store.store(bOut, passwd); stream = new ByteArrayInputStream(bOut.toByteArray()); store.load(stream, passwd); key = (PrivateKey)store.getKey(pName, null); if (!((RSAPrivateKey)key).getModulus().equals(mod)) { fail("Modulus doesn't match."); } store.deleteEntry(pName); if (store.getKey(pName, null) != null) { fail("Failed deletion test."); } // // cert chain test // store.setCertificateEntry("testCert", ch[2]); if (store.getCertificateChain("testCert") != null) { fail("Failed null chain test."); } // // UTF 8 single cert test // store = KeyStore.getInstance("PKCS12", "BC"); stream = new ByteArrayInputStream(certUTF); store.load(stream, "user".toCharArray()); if (store.getCertificate("37") == null) { fail("Failed to find UTF cert."); } // // try for a self generated certificate // RSAPublicKeySpec pubKeySpec = new RSAPublicKeySpec( new BigInteger("b4a7e46170574f16a97082b22be58b6a2a629798419be12872a4bdba626cfae9900f76abfb12139dce5de56564fab2b6543165a040c606887420e33d91ed7ed7", 16), new BigInteger("11", 16)); RSAPrivateCrtKeySpec privKeySpec = new RSAPrivateCrtKeySpec( new BigInteger("b4a7e46170574f16a97082b22be58b6a2a629798419be12872a4bdba626cfae9900f76abfb12139dce5de56564fab2b6543165a040c606887420e33d91ed7ed7", 16), new BigInteger("11", 16), new BigInteger("9f66f6b05410cd503b2709e88115d55daced94d1a34d4e32bf824d0dde6028ae79c5f07b580f5dce240d7111f7ddb130a7945cd7d957d1920994da389f490c89", 16), new BigInteger("c0a0758cdf14256f78d4708c86becdead1b50ad4ad6c5c703e2168fbf37884cb", 16), new BigInteger("f01734d7960ea60070f1b06f2bb81bfac48ff192ae18451d5e56c734a5aab8a5", 16), new BigInteger("b54bb9edff22051d9ee60f9351a48591b6500a319429c069a3e335a1d6171391", 16), new BigInteger("d3d83daf2a0cecd3367ae6f8ae1aeb82e9ac2f816c6fc483533d8297dd7884cd", 16), new BigInteger("b8f52fc6f38593dabb661d3f50f8897f8106eee68b1bce78a95b132b4e5b5d19", 16)); // // set up the keys // PrivateKey privKey = null; PublicKey pubKey = null; try { KeyFactory fact = KeyFactory.getInstance("RSA", "BC"); privKey = fact.generatePrivate(privKeySpec); pubKey = fact.generatePublic(pubKeySpec); } catch (Exception e) { fail("error setting up keys - " + e.toString()); } Certificate[] chain = new Certificate[1]; chain[0] = createCert(pubKey, privKey); store = KeyStore.getInstance("PKCS12", "BC"); store.load(null, null); store.setKeyEntry("privateKey", privKey, null, chain); if (!store.containsAlias("privateKey")) { fail("couldn't find alias privateKey"); } if (store.isCertificateEntry("privateKey")) { fail("cert identified as certificate entry"); } if (!store.isKeyEntry("privateKey")) { fail("cert not dentified as key entry"); } if (!"privateKey".equals(store.getCertificateAlias(chain[0]))) { fail("Did not return alias for key certificate privateKey"); } store.store(new ByteArrayOutputStream(), passwd); // // no friendly name test // store = KeyStore.getInstance("PKCS12", "BC"); stream = new ByteArrayInputStream(pkcs12noFriendly); store.load(stream, noFriendlyPassword); en = store.aliases(); pName = null; while (en.hasMoreElements()) { String n = (String)en.nextElement(); if (store.isKeyEntry(n)) { pName = n; } } ch = store.getCertificateChain(pName); for (int i = 0; i != ch.length; i++) { //System.out.println(ch[i]); } if (ch.length != 1) { fail("no cert found in pkcs12noFriendly"); } // // failure tests // ch = store.getCertificateChain("dummy"); store.getCertificate("dummy"); // // storage test // store = KeyStore.getInstance("PKCS12", "BC"); stream = new ByteArrayInputStream(pkcs12StorageIssue); store.load(stream, storagePassword); en = store.aliases(); pName = null; while (en.hasMoreElements()) { String n = (String)en.nextElement(); if (store.isKeyEntry(n)) { pName = n; } } ch = store.getCertificateChain(pName); if (ch.length != 2) { fail("Certificate chain wrong length"); } store.store(new ByteArrayOutputStream(), storagePassword); // // basic certificate check // store.setCertificateEntry("cert", ch[1]); if (!store.containsAlias("cert")) { fail("couldn't find alias cert"); } if (!store.isCertificateEntry("cert")) { fail("cert not identified as certificate entry"); } if (store.isKeyEntry("cert")) { fail("cert identified as key entry"); } if (!"cert".equals(store.getCertificateAlias(ch[1]))) { fail("Did not return alias for certificate entry"); } // // test of reading incorrect zero-length encoding // store = KeyStore.getInstance("PKCS12", "BC"); stream = new ByteArrayInputStream(pkcs12nopass); store.load(stream, "".toCharArray()); } public String getName() { return "PKCS12Store"; } public void performTest() throws Exception { testPKCS12Store(); } public static void main( String[] args) { Security.addProvider(new BouncyCastleProvider()); runTest(new PKCS12StoreTest()); } } bouncycastle-1.49.orig/test/jdk1.4/org/bouncycastle/jce/provider/test/NamedCurveTest.java0000644000175000017500000001154310405216351030774 0ustar ebourgebourgpackage org.bouncycastle.jce.provider.test; import java.math.BigInteger; import java.security.KeyFactory; import java.security.KeyPair; import java.security.KeyPairGenerator; import java.security.SecureRandom; import java.security.Security; import java.security.spec.PKCS8EncodedKeySpec; import java.security.spec.X509EncodedKeySpec; import javax.crypto.KeyAgreement; import org.bouncycastle.jce.ECNamedCurveTable; import org.bouncycastle.jce.interfaces.ECPrivateKey; import org.bouncycastle.jce.interfaces.ECPublicKey; import org.bouncycastle.jce.provider.BouncyCastleProvider; import org.bouncycastle.jce.spec.ECNamedCurveParameterSpec; import org.bouncycastle.jce.spec.ECParameterSpec; import org.bouncycastle.util.test.SimpleTestResult; import org.bouncycastle.util.test.Test; import org.bouncycastle.util.test.TestResult; public class NamedCurveTest implements Test { private String name; NamedCurveTest() { this("prime192v1"); } NamedCurveTest( String name) { this.name = name; } public TestResult perform() { try { ECParameterSpec ecSpec = ECNamedCurveTable.getParameterSpec(name); if (ecSpec == null) { return new SimpleTestResult(false, getName() + " no curve for " + name + " found."); } KeyPairGenerator g = KeyPairGenerator.getInstance("ECDH", "BC"); g.initialize(ecSpec, new SecureRandom()); // // a side // KeyPair aKeyPair = g.generateKeyPair(); KeyAgreement aKeyAgree = KeyAgreement.getInstance("ECDHC", "BC"); aKeyAgree.init(aKeyPair.getPrivate()); // // b side // KeyPair bKeyPair = g.generateKeyPair(); KeyAgreement bKeyAgree = KeyAgreement.getInstance("ECDHC", "BC"); bKeyAgree.init(bKeyPair.getPrivate()); // // agreement // aKeyAgree.doPhase(bKeyPair.getPublic(), true); bKeyAgree.doPhase(aKeyPair.getPublic(), true); BigInteger k1 = new BigInteger(aKeyAgree.generateSecret()); BigInteger k2 = new BigInteger(bKeyAgree.generateSecret()); if (!k1.equals(k2)) { return new SimpleTestResult(false, getName() + " 2-way test failed"); } // // public key encoding test // byte[] pubEnc = aKeyPair.getPublic().getEncoded(); KeyFactory keyFac = KeyFactory.getInstance("ECDH", "BC"); X509EncodedKeySpec pubX509 = new X509EncodedKeySpec(pubEnc); ECPublicKey pubKey = (ECPublicKey)keyFac.generatePublic(pubX509); if (!pubKey.getQ().equals(((ECPublicKey)aKeyPair.getPublic()).getQ())) { return new SimpleTestResult(false, getName() + ": public key encoding (Q test) failed"); } if (!(pubKey.getParameters() instanceof ECNamedCurveParameterSpec)) { return new SimpleTestResult(false, getName() + ": public key encoding not named curve"); } // // private key encoding test // byte[] privEnc = aKeyPair.getPrivate().getEncoded(); PKCS8EncodedKeySpec privPKCS8 = new PKCS8EncodedKeySpec(privEnc); ECPrivateKey privKey = (ECPrivateKey)keyFac.generatePrivate(privPKCS8); if (!privKey.getD().equals(((ECPrivateKey)aKeyPair.getPrivate()).getD())) { return new SimpleTestResult(false, getName() + ": private key encoding (D test) failed"); } if (!(privKey.getParameters() instanceof ECNamedCurveParameterSpec)) { return new SimpleTestResult(false, getName() + ": private key encoding not named curve"); } if (!((ECNamedCurveParameterSpec)privKey.getParameters()).getName().equals(name)) { return new SimpleTestResult(false, getName() + ": private key encoding wrong named curve"); } return new SimpleTestResult(true, getName() + ": Okay"); } catch (Exception e) { return new SimpleTestResult(false, getName() + ": exception - " + e.toString()); } } public String getName() { return "NamedCurve"; } public static void main( String[] args) { Security.addProvider(new BouncyCastleProvider()); Test test; if (args.length == 0) { test = new NamedCurveTest(); } else { test = new NamedCurveTest(args[0]); } TestResult result = test.perform(); System.out.println(result.toString()); } } bouncycastle-1.49.orig/test/jdk1.4/org/bouncycastle/jce/provider/test/ImplicitlyCaTest.java0000644000175000017500000001650011701463553031334 0ustar ebourgebourgpackage org.bouncycastle.jce.provider.test; import java.math.BigInteger; import java.security.KeyFactory; import java.security.KeyPair; import java.security.KeyPairGenerator; import java.security.SecureRandom; import java.security.Security; import java.security.Signature; import java.security.spec.PKCS8EncodedKeySpec; import java.security.spec.X509EncodedKeySpec; import org.bouncycastle.asn1.ASN1InputStream; import org.bouncycastle.asn1.DERNull; import org.bouncycastle.asn1.pkcs.PrivateKeyInfo; import org.bouncycastle.asn1.x509.SubjectPublicKeyInfo; import org.bouncycastle.jcajce.provider.config.ConfigurableProvider; import org.bouncycastle.jce.interfaces.ECPrivateKey; import org.bouncycastle.jce.interfaces.ECPublicKey; import org.bouncycastle.jce.provider.BouncyCastleProvider; import org.bouncycastle.jce.spec.ECParameterSpec; import org.bouncycastle.jce.spec.ECPrivateKeySpec; import org.bouncycastle.jce.spec.ECPublicKeySpec; import org.bouncycastle.math.ec.ECCurve; import org.bouncycastle.util.encoders.Hex; import org.bouncycastle.util.test.FixedSecureRandom; import org.bouncycastle.util.test.SimpleTest; public class ImplicitlyCaTest extends SimpleTest { byte[] k1 = Hex.decode("d5014e4b60ef2ba8b6211b4062ba3224e0427dd3"); byte[] k2 = Hex.decode("345e8d05c075c3a508df729a1685690e68fcfb8c8117847e89063bca1f85d968fd281540b6e13bd1af989a1fbf17e06462bf511f9d0b140fb48ac1b1baa5bded"); SecureRandom random = new FixedSecureRandom(new byte[][] { k1, k2 }); public void performTest() throws Exception { KeyPairGenerator g = KeyPairGenerator.getInstance("ECDSA", "BC"); ECCurve curve = new ECCurve.Fp( new BigInteger("883423532389192164791648750360308885314476597252960362792450860609699839"), // q new BigInteger("7fffffffffffffffffffffff7fffffffffff8000000000007ffffffffffc", 16), // a new BigInteger("6b016c3bdcf18941d0d654921475ca71a9db2fb27d1d37796185c2942c0a", 16)); // b ECParameterSpec ecSpec = new ECParameterSpec( curve, curve.decodePoint(Hex.decode("020ffa963cdca8816ccc33b8642bedf905c3d358573d3f27fbbd3b3cb9aaaf")), // G new BigInteger("883423532389192164791648750360308884807550341691627752275345424702807307")); // n ConfigurableProvider config = (ConfigurableProvider)Security.getProvider("BC"); config.setParameter(ConfigurableProvider.EC_IMPLICITLY_CA, ecSpec); g.initialize(null, new SecureRandom()); KeyPair p = g.generateKeyPair(); ECPrivateKey sKey = (ECPrivateKey)p.getPrivate(); ECPublicKey vKey = (ECPublicKey)p.getPublic(); testECDSA(sKey, vKey); testBCParamsAndQ(sKey, vKey); testEncoding(sKey, vKey); testKeyFactory(); } private void testKeyFactory() throws Exception { KeyPairGenerator g = KeyPairGenerator.getInstance("ECDSA", "BC"); ECCurve curve = new ECCurve.Fp( new BigInteger("883423532389192164791648750360308885314476597252960362792450860609699839"), // q new BigInteger("7fffffffffffffffffffffff7fffffffffff8000000000007ffffffffffc", 16), // a new BigInteger("6b016c3bdcf18941d0d654921475ca71a9db2fb27d1d37796185c2942c0a", 16)); // b ECParameterSpec ecSpec = new ECParameterSpec( curve, curve.decodePoint(Hex.decode("020ffa963cdca8816ccc33b8642bedf905c3d358573d3f27fbbd3b3cb9aaaf")), // G new BigInteger("883423532389192164791648750360308884807550341691627752275345424702807307")); // n ConfigurableProvider config = (ConfigurableProvider)Security.getProvider("BC"); config.setParameter(ConfigurableProvider.EC_IMPLICITLY_CA, ecSpec); g.initialize(null, new SecureRandom()); KeyPair p = g.generateKeyPair(); ECPrivateKey sKey = (ECPrivateKey)p.getPrivate(); ECPublicKey vKey = (ECPublicKey)p.getPublic(); KeyFactory fact = KeyFactory.getInstance("ECDSA", "BC"); vKey = (ECPublicKey)fact.generatePublic(new ECPublicKeySpec(vKey.getQ(), null)); sKey = (ECPrivateKey)fact.generatePrivate(new ECPrivateKeySpec(sKey.getD(), null)); testECDSA(sKey, vKey); testBCParamsAndQ(sKey, vKey); testEncoding(sKey, vKey); ECPublicKey vKey2 = (ECPublicKey)fact.generatePublic(new ECPublicKeySpec(vKey.getQ(), ecSpec)); ECPrivateKey sKey2 = (ECPrivateKey)fact.generatePrivate(new ECPrivateKeySpec(sKey.getD(), ecSpec)); if (!vKey.equals(vKey2) || vKey.hashCode() != vKey2.hashCode()) { fail("private equals/hashCode failed"); } if (!sKey.equals(sKey2) || sKey.hashCode() != sKey2.hashCode()) { fail("private equals/hashCode failed"); } } private void testECDSA( ECPrivateKey sKey, ECPublicKey vKey) throws Exception { byte[] data = { 1, 2, 3, 4, 5, 6, 7, 8, 9, 0 }; Signature s = Signature.getInstance("ECDSA", "BC"); s.initSign(sKey); s.update(data); byte[] sigBytes = s.sign(); s = Signature.getInstance("ECDSA", "BC"); s.initVerify(vKey); s.update(data); if (!s.verify(sigBytes)) { fail("ECDSA verification failed"); } } private void testEncoding( ECPrivateKey privKey, ECPublicKey pubKey) throws Exception { KeyFactory kFact = KeyFactory.getInstance("ECDSA", "BC"); byte[] bytes = privKey.getEncoded(); PrivateKeyInfo sInfo = PrivateKeyInfo.getInstance(new ASN1InputStream(bytes).readObject()); if (!sInfo.getAlgorithmId().getParameters().equals(DERNull.INSTANCE)) { fail("private key parameters wrong"); } ECPrivateKey sKey = (ECPrivateKey)kFact.generatePrivate(new PKCS8EncodedKeySpec(bytes)); if (!sKey.equals(privKey)) { fail("private equals failed"); } if (sKey.hashCode() != privKey.hashCode()) { fail("private hashCode failed"); } bytes = pubKey.getEncoded(); SubjectPublicKeyInfo vInfo = SubjectPublicKeyInfo.getInstance(new ASN1InputStream(bytes).readObject()); if (!vInfo.getAlgorithmId().getParameters().equals(DERNull.INSTANCE)) { fail("public key parameters wrong"); } ECPublicKey vKey = (ECPublicKey)kFact.generatePublic(new X509EncodedKeySpec(bytes)); if (!vKey.equals(pubKey) || vKey.hashCode() != pubKey.hashCode()) { fail("public equals/hashCode failed"); } testBCParamsAndQ(sKey, vKey); testECDSA(sKey, vKey); } private void testBCParamsAndQ( ECPrivateKey sKey, ECPublicKey vKey) { if (sKey.getParameters() != null) { fail("parameters exposed in private key"); } if (vKey.getParameters() != null) { fail("parameters exposed in public key"); } if (vKey.getQ().getCurve() != null) { fail("curve exposed in public point"); } } public String getName() { return "ImplicitlyCA"; } public static void main( String[] args) { Security.addProvider(new BouncyCastleProvider()); runTest(new ImplicitlyCaTest()); } } bouncycastle-1.49.orig/test/jdk1.4/org/bouncycastle/jce/provider/test/RSATest.java0000644000175000017500000004412410336343713027377 0ustar ebourgebourgpackage org.bouncycastle.jce.provider.test; import java.math.BigInteger; import java.security.KeyFactory; import java.security.KeyPair; import java.security.KeyPairGenerator; import java.security.PrivateKey; import java.security.PublicKey; import java.security.SecureRandom; import java.security.Security; import java.security.interfaces.RSAPublicKey; import java.security.spec.RSAKeyGenParameterSpec; import java.security.spec.RSAPrivateCrtKeySpec; import java.security.spec.RSAPrivateKeySpec; import java.security.spec.RSAPublicKeySpec; import javax.crypto.Cipher; import org.bouncycastle.jce.provider.BouncyCastleProvider; import org.bouncycastle.util.encoders.Hex; import org.bouncycastle.util.test.SimpleTest; public class RSATest extends SimpleTest { /** * a fake random number generator - we just want to make sure the random numbers * aren't random so that we get the same output, while still getting to test the * key generation facilities. */ private class FixedSecureRandom extends SecureRandom { byte[] seed = { (byte)0xaa, (byte)0xfd, (byte)0x12, (byte)0xf6, (byte)0x59, (byte)0xca, (byte)0xe6, (byte)0x34, (byte)0x89, (byte)0xb4, (byte)0x79, (byte)0xe5, (byte)0x07, (byte)0x6d, (byte)0xde, (byte)0xc2, (byte)0xf0, (byte)0x6c, (byte)0xb5, (byte)0x8f }; public void nextBytes( byte[] bytes) { int offset = 0; while ((offset + seed.length) < bytes.length) { System.arraycopy(seed, 0, bytes, offset, seed.length); offset += seed.length; } System.arraycopy(seed, 0, bytes, offset, bytes.length - offset); } } private RSAPublicKeySpec pubKeySpec = new RSAPublicKeySpec( new BigInteger("b4a7e46170574f16a97082b22be58b6a2a629798419be12872a4bdba626cfae9900f76abfb12139dce5de56564fab2b6543165a040c606887420e33d91ed7ed7", 16), new BigInteger("11", 16)); private RSAPrivateCrtKeySpec privKeySpec = new RSAPrivateCrtKeySpec( new BigInteger("b4a7e46170574f16a97082b22be58b6a2a629798419be12872a4bdba626cfae9900f76abfb12139dce5de56564fab2b6543165a040c606887420e33d91ed7ed7", 16), new BigInteger("11", 16), new BigInteger("9f66f6b05410cd503b2709e88115d55daced94d1a34d4e32bf824d0dde6028ae79c5f07b580f5dce240d7111f7ddb130a7945cd7d957d1920994da389f490c89", 16), new BigInteger("c0a0758cdf14256f78d4708c86becdead1b50ad4ad6c5c703e2168fbf37884cb", 16), new BigInteger("f01734d7960ea60070f1b06f2bb81bfac48ff192ae18451d5e56c734a5aab8a5", 16), new BigInteger("b54bb9edff22051d9ee60f9351a48591b6500a319429c069a3e335a1d6171391", 16), new BigInteger("d3d83daf2a0cecd3367ae6f8ae1aeb82e9ac2f816c6fc483533d8297dd7884cd", 16), new BigInteger("b8f52fc6f38593dabb661d3f50f8897f8106eee68b1bce78a95b132b4e5b5d19", 16)); private RSAPublicKeySpec isoPubKeySpec = new RSAPublicKeySpec( new BigInteger("0100000000000000000000000000000000bba2d15dbb303c8a21c5ebbcbae52b7125087920dd7cdf358ea119fd66fb064012ec8ce692f0a0b8e8321b041acd40b7", 16), new BigInteger("03", 16)); private RSAPrivateKeySpec isoPrivKeySpec = new RSAPrivateKeySpec( new BigInteger("0100000000000000000000000000000000bba2d15dbb303c8a21c5ebbcbae52b7125087920dd7cdf358ea119fd66fb064012ec8ce692f0a0b8e8321b041acd40b7", 16), new BigInteger("2aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaac9f0783a49dd5f6c5af651f4c9d0dc9281c96a3f16a85f9572d7cc3f2d0f25a9dbf1149e4cdc32273faadd3fda5dcda7", 16)); private RSAPublicKeySpec pub2048KeySpec = new RSAPublicKeySpec( new BigInteger("a7295693155b1813bb84877fb45343556e0568043de5910872a3a518cc11e23e2db74eaf4545068c4e3d258a2718fbacdcc3eafa457695b957e88fbf110aed049a992d9c430232d02f3529c67a3419935ea9b569f85b1bcd37de6b899cd62697e843130ff0529d09c97d813cb15f293751ff56f943fbdabb63971cc7f4f6d5bff1594416b1f5907bde5a84a44f9802ef29b43bda1960f948f8afb8766c1ab80d32eec88ed66d0b65aebe44a6d0b3c5e0ab051aaa1b912fbcc17b8e751ddecc5365b6db6dab0020c3057db4013a51213a5798a3aab67985b0f4d88627a54a0f3f0285fbcb4afdfeb65cb153af66825656d43238b75503231500753f4e421e3c57", 16), new BigInteger("10001", 16)); private RSAPrivateCrtKeySpec priv2048KeySpec = new RSAPrivateCrtKeySpec( new BigInteger("a7295693155b1813bb84877fb45343556e0568043de5910872a3a518cc11e23e2db74eaf4545068c4e3d258a2718fbacdcc3eafa457695b957e88fbf110aed049a992d9c430232d02f3529c67a3419935ea9b569f85b1bcd37de6b899cd62697e843130ff0529d09c97d813cb15f293751ff56f943fbdabb63971cc7f4f6d5bff1594416b1f5907bde5a84a44f9802ef29b43bda1960f948f8afb8766c1ab80d32eec88ed66d0b65aebe44a6d0b3c5e0ab051aaa1b912fbcc17b8e751ddecc5365b6db6dab0020c3057db4013a51213a5798a3aab67985b0f4d88627a54a0f3f0285fbcb4afdfeb65cb153af66825656d43238b75503231500753f4e421e3c57", 16), new BigInteger("10001", 16), new BigInteger("65dad56ac7df7abb434e4cb5eeadb16093aa6da7f0033aad3815289b04757d32bfee6ade7749c8e4a323b5050a2fb9e2a99e23469e1ed4ba5bab54336af20a5bfccb8b3424cc6923db2ffca5787ed87aa87aa614cd04cedaebc8f623a2d2063017910f436dff18bb06f01758610787f8b258f0a8efd8bd7de30007c47b2a1031696c7d6523bc191d4d918927a7e0b09584ed205bd2ff4fc4382678df82353f7532b3bbb81d69e3f39070aed3fb64fce032a089e8e64955afa5213a6eb241231bd98d702fba725a9b205952fda186412d9e0d9344d2998c455ad8c2bae85ee672751466d5288304032b5b7e02f7e558c7af82c7fbf58eea0bb4ef0f001e6cd0a9", 16), new BigInteger("d4fd9ac3474fb83aaf832470643609659e511b322632b239b688f3cd2aad87527d6cf652fb9c9ca67940e84789444f2e99b0cb0cfabbd4de95396106c865f38e2fb7b82b231260a94df0e01756bf73ce0386868d9c41645560a81af2f53c18e4f7cdf3d51d80267372e6e0216afbf67f655c9450769cca494e4f6631b239ce1b", 16), new BigInteger("c8eaa0e2a1b3a4412a702bccda93f4d150da60d736c99c7c566fdea4dd1b401cbc0d8c063daaf0b579953d36343aa18b33dbf8b9eae94452490cc905245f8f7b9e29b1a288bc66731a29e1dd1a45c9fd7f8238ff727adc49fff73991d0dc096206b9d3a08f61e7462e2b804d78cb8c5eccdb9b7fbd2ad6a8fea46c1053e1be75", 16), new BigInteger("10edcb544421c0f9e123624d1099feeb35c72a8b34e008ac6fa6b90210a7543f293af4e5299c8c12eb464e70092805c7256e18e5823455ba0f504d36f5ccacac1b7cd5c58ff710f9c3f92646949d88fdd1e7ea5fed1081820bb9b0d2a8cd4b093fecfdb96dabd6e28c3a6f8c186dc86cddc89afd3e403e0fcf8a9e0bcb27af0b", 16), new BigInteger("97fc25484b5a415eaa63c03e6efa8dafe9a1c8b004d9ee6e80548fefd6f2ce44ee5cb117e77e70285798f57d137566ce8ea4503b13e0f1b5ed5ca6942537c4aa96b2a395782a4cb5b58d0936e0b0fa63b1192954d39ced176d71ef32c6f42c84e2e19f9d4dd999c2151b032b97bd22aa73fd8c5bcd15a2dca4046d5acc997021", 16), new BigInteger("4bb8064e1eff7e9efc3c4578fcedb59ca4aef0993a8312dfdcb1b3decf458aa6650d3d0866f143cbf0d3825e9381181170a0a1651eefcd7def786b8eb356555d9fa07c85b5f5cbdd74382f1129b5e36b4166b6cc9157923699708648212c484958351fdc9cf14f218dbe7fbf7cbd93a209a4681fe23ceb44bab67d66f45d1c9d", 16)); public void performTest() throws Exception { KeyFactory fact; byte[] input = new byte[] { (byte)0x54, (byte)0x85, (byte)0x9b, (byte)0x34, (byte)0x2c, (byte)0x49, (byte)0xea, (byte)0x2a }; byte[][] output = new byte[][] { Hex.decode("8b427f781a2e59dd9def386f1956b996ee07f48c96880e65a368055ed8c0a8831669ef7250b40918b2b1d488547e72c84540e42bd07b03f14e226f04fbc2d929"), Hex.decode("2ec6e1a1711b6c7b8cd3f6a25db21ab8bb0a5f1d6df2ef375fa708a43997730ffc7c98856dbbe36edddcdd1b2d2a53867d8355af94fea3aeec128da908e08f4c"), Hex.decode("0850ac4e5a8118323200c8ed1e5aaa3d5e635172553ccac66a8e4153d35c79305c4440f11034ab147fccce21f18a50cf1c0099c08a577eb68237a91042278965"), Hex.decode("1c9649bdccb51056751fe43837f4eb43bada472accf26f65231666d5de7d11950d8379b3596dfdf75c6234274896fa8d18ad0865d3be2ac4d6687151abdf01e93941dcef18fa63186c9351d1506c89d09733c5ff4304208c812bdd21a50f56fde115e629e0e973721c9fcc87e89295a79853dee613962a0b2f2fc57163fd99057a3c776f13c20c26407eb8863998d7e53b543ba8d0a295a9a68d1a149833078c9809ad6a6dad7fc22a95ad615a73138c54c018f40d99bf8eeecd45f5be526f2d6b01aeb56381991c1ab31a2e756f15e052b9cd5638b2eff799795c5bae493307d5eb9f8c21d438de131fe505a4e7432547ab19224094f9e4be1968bd0793b79d"), Hex.decode("4c4afc0c24dddaedd4f9a3b23be30d35d8e005ffd36b3defc5d18acc830c3ed388ce20f43a00e614fd087c814197bc9fc2eff9ad4cc474a7a2ef3ed9c0f0a55eb23371e41ee8f2e2ed93ea3a06ca482589ab87e0d61dcffda5eea1241408e43ea1108726cdb87cc3aa5e9eaaa9f72507ca1352ac54a53920c94dccc768147933d8c50aefd9d1da10522a40133cd33dbc0524669e70f771a88d65c4716d471cd22b08b9f01f24e4e9fc7ffbcfa0e0a7aed47b345826399b26a73be112eb9c5e06fc6742fc3d0ef53d43896403c5105109cfc12e6deeaf4a48ba308e039774b9bdb31a9b9e133c81c321630cf0b4b2d1f90717b24c3268e1fea681ea9cdc709342"), Hex.decode("06b5b26bd13515f799e5e37ca43cace15cd82fd4bf36b25d285a6f0998d97c8cb0755a28f0ae66618b1cd03e27ac95eaaa4882bc6dc0078cd457d4f7de4154173a9c7a838cfc2ac2f74875df462aae0cfd341645dc51d9a01da9bdb01507f140fa8a016534379d838cc3b2a53ac33150af1b242fc88013cb8d914e66c8182864ee6de88ce2879d4c05dd125409620a96797c55c832fb2fb31d4310c190b8ed2c95fdfda2ed87f785002faaec3f35ec05cf70a3774ce185e4882df35719d582dd55ac31257344a9cba95189dcbea16e8c6cb7a235a0384bc83b6183ca8547e670fe33b1b91725ae0c250c9eca7b5ba78bd77145b70270bf8ac31653006c02ca9c"), Hex.decode("135f1be3d045526235bf9d5e43499d4ee1bfdf93370769ae56e85dbc339bc5b7ea3bee49717497ee8ac3f7cd6adb6fc0f17812390dcd65ac7b87fef7970d9ff9"), Hex.decode("00319bb9becb49f3ed1bca26d0fcf09b0b0a508e4d0bd43b350f959b72cd25b3af47d608fdcd248eada74fbe19990dbeb9bf0da4b4e1200243a14e5cab3f7e610c") }; SecureRandom rand = new FixedSecureRandom(); fact = KeyFactory.getInstance("RSA", "BC"); PrivateKey privKey = fact.generatePrivate(privKeySpec); PublicKey pubKey = fact.generatePublic(pubKeySpec); PrivateKey priv2048Key = fact.generatePrivate(priv2048KeySpec); PublicKey pub2048Key = fact.generatePublic(pub2048KeySpec); // // No Padding // Cipher c = Cipher.getInstance("RSA", "BC"); c.init(Cipher.ENCRYPT_MODE, pubKey, rand); byte[] out = c.doFinal(input); if (!areEqual(out, output[0])) { fail("NoPadding test failed on encrypt expected " + new String(Hex.encode(output[0])) + " got " + new String(Hex.encode(out))); } c.init(Cipher.DECRYPT_MODE, privKey); out = c.doFinal(out); if (!areEqual(out, input)) { fail("NoPadding test failed on decrypt expected " + new String(Hex.encode(input)) + " got " + new String(Hex.encode(out))); } // // No Padding - incremental // c = Cipher.getInstance("RSA", "BC"); c.init(Cipher.ENCRYPT_MODE, pubKey, rand); c.update(input); out = c.doFinal(); if (!areEqual(out, output[0])) { fail("NoPadding test failed on encrypt expected " + new String(Hex.encode(output[0])) + " got " + new String(Hex.encode(out))); } c.init(Cipher.DECRYPT_MODE, privKey); out = c.doFinal(out); if (!areEqual(out, input)) { fail("NoPadding test failed on decrypt expected " + new String(Hex.encode(input)) + " got " + new String(Hex.encode(out))); } // // No Padding - maximum length // c = Cipher.getInstance("RSA", "BC"); byte[] modBytes = ((RSAPublicKey)pubKey).getModulus().toByteArray(); byte[] maxInput = new byte[modBytes.length - 1]; maxInput[0] |= 0x7f; c.init(Cipher.ENCRYPT_MODE, pubKey, rand); out = c.doFinal(maxInput); c.init(Cipher.DECRYPT_MODE, privKey); out = c.doFinal(out); if (!areEqual(out, maxInput)) { fail("NoPadding test failed on decrypt expected " + new String(Hex.encode(input)) + " got " + new String(Hex.encode(out))); } // // PKCS1 V 1.5 // c = Cipher.getInstance("RSA/ECB/PKCS1Padding", "BC"); c.init(Cipher.ENCRYPT_MODE, pubKey, rand); out = c.doFinal(input); if (!areEqual(out, output[1])) { fail("PKCS1 test failed on encrypt expected " + new String(Hex.encode(output[1])) + " got " + new String(Hex.encode(out))); } c.init(Cipher.DECRYPT_MODE, privKey); out = c.doFinal(out); if (!areEqual(out, input)) { fail("PKCS1 test failed on decrypt expected " + new String(Hex.encode(input)) + " got " + new String(Hex.encode(out))); } // // OAEP - SHA1 // c = Cipher.getInstance("RSA/NONE/OAEPPadding", "BC"); c.init(Cipher.ENCRYPT_MODE, pubKey, rand); out = c.doFinal(input); if (!areEqual(out, output[2])) { fail("OAEP test failed on encrypt expected " + new String(Hex.encode(output[2])) + " got " + new String(Hex.encode(out))); } c = Cipher.getInstance("RSA/NONE/OAEPWithSHA1AndMGF1Padding", "BC"); c.init(Cipher.DECRYPT_MODE, privKey); out = c.doFinal(out); if (!areEqual(out, input)) { fail("OAEP test failed on decrypt expected " + new String(Hex.encode(input)) + " got " + new String(Hex.encode(out))); } // // OAEP - SHA224 // c = Cipher.getInstance("RSA/NONE/OAEPWithSHA224AndMGF1Padding", "BC"); c.init(Cipher.ENCRYPT_MODE, pub2048Key, rand); out = c.doFinal(input); if (!areEqual(out, output[3])) { fail("OAEP SHA-224 test failed on encrypt expected " + new String(Hex.encode(output[2])) + " got " + new String(Hex.encode(out))); } c.init(Cipher.DECRYPT_MODE, priv2048Key); out = c.doFinal(out); if (!areEqual(out, input)) { fail("OAEP SHA-224 test failed on decrypt expected " + new String(Hex.encode(input)) + " got " + new String(Hex.encode(out))); } // // OAEP - SHA 256 // c = Cipher.getInstance("RSA/NONE/OAEPWithSHA256AndMGF1Padding", "BC"); c.init(Cipher.ENCRYPT_MODE, pub2048Key, rand); out = c.doFinal(input); if (!areEqual(out, output[4])) { fail("OAEP SHA-256 test failed on encrypt expected " + new String(Hex.encode(output[2])) + " got " + new String(Hex.encode(out))); } c.init(Cipher.DECRYPT_MODE, priv2048Key); out = c.doFinal(out); if (!areEqual(out, input)) { fail("OAEP SHA-256 test failed on decrypt expected " + new String(Hex.encode(input)) + " got " + new String(Hex.encode(out))); } // // OAEP - SHA 384 // c = Cipher.getInstance("RSA/NONE/OAEPWithSHA384AndMGF1Padding", "BC"); c.init(Cipher.ENCRYPT_MODE, pub2048Key, rand); out = c.doFinal(input); if (!areEqual(out, output[5])) { fail("OAEP SHA-384 test failed on encrypt expected " + new String(Hex.encode(output[2])) + " got " + new String(Hex.encode(out))); } c.init(Cipher.DECRYPT_MODE, priv2048Key); out = c.doFinal(out); if (!areEqual(out, input)) { fail("OAEP SHA-384 test failed on decrypt expected " + new String(Hex.encode(input)) + " got " + new String(Hex.encode(out))); } // // OAEP - MD5 // c = Cipher.getInstance("RSA/NONE/OAEPWithMD5AndMGF1Padding", "BC"); c.init(Cipher.ENCRYPT_MODE, pubKey, rand); out = c.doFinal(input); if (!areEqual(out, output[6])) { fail("OAEP MD5 test failed on encrypt expected " + new String(Hex.encode(output[2])) + " got " + new String(Hex.encode(out))); } c.init(Cipher.DECRYPT_MODE, privKey); out = c.doFinal(out); if (!areEqual(out, input)) { fail("OAEP MD5 test failed on decrypt expected " + new String(Hex.encode(input)) + " got " + new String(Hex.encode(out))); } // // ISO9796-1 // byte[] isoInput = Hex.decode("fedcba9876543210fedcba9876543210fedcba9876543210fedcba9876543210"); PrivateKey isoPrivKey = fact.generatePrivate(isoPrivKeySpec); PublicKey isoPubKey = fact.generatePublic(isoPubKeySpec); c = Cipher.getInstance("RSA/NONE/ISO9796-1Padding", "BC"); c.init(Cipher.ENCRYPT_MODE, isoPrivKey); out = c.doFinal(isoInput); if (!areEqual(out, output[7])) { fail("ISO9796-1 test failed on encrypt expected " + new String(Hex.encode(output[3])) + " got " + new String(Hex.encode(out))); } c.init(Cipher.DECRYPT_MODE, isoPubKey); out = c.doFinal(out); if (!areEqual(out, isoInput)) { fail("ISO9796-1 test failed on decrypt expected " + new String(Hex.encode(input)) + " got " + new String(Hex.encode(out))); } // // // generation with parameters test. // KeyPairGenerator keyPairGen = KeyPairGenerator.getInstance("RSA", "BC"); // // 768 bit RSA with e = 2^16-1 // keyPairGen.initialize( new RSAKeyGenParameterSpec(768, BigInteger.valueOf(65537)), new SecureRandom()); KeyPair kp = keyPairGen.generateKeyPair(); pubKey = kp.getPublic(); privKey = kp.getPrivate(); c.init(Cipher.ENCRYPT_MODE, pubKey, rand); out = c.doFinal(input); c.init(Cipher.DECRYPT_MODE, privKey); out = c.doFinal(out); if (!areEqual(out, input)) { fail("key generation test failed on decrypt expected " + new String(Hex.encode(input)) + " got " + new String(Hex.encode(out))); } } public String getName() { return "RSATest"; } public static void main( String[] args) { Security.addProvider(new BouncyCastleProvider()); runTest(new RSATest()); } } bouncycastle-1.49.orig/test/jdk1.4/org/bouncycastle/jce/provider/test/DHTest.java0000644000175000017500000004747110336343713027255 0ustar ebourgebourgpackage org.bouncycastle.jce.provider.test; import java.io.ByteArrayInputStream; import java.io.ByteArrayOutputStream; import java.io.ObjectInputStream; import java.io.ObjectOutputStream; import java.math.BigInteger; import java.security.AlgorithmParameterGenerator; import java.security.AlgorithmParameters; import java.security.Key; import java.security.KeyFactory; import java.security.KeyPair; import java.security.KeyPairGenerator; import java.security.SecureRandom; import java.security.Security; import java.security.spec.PKCS8EncodedKeySpec; import java.security.spec.X509EncodedKeySpec; import javax.crypto.KeyAgreement; import javax.crypto.interfaces.DHPrivateKey; import javax.crypto.interfaces.DHPublicKey; import javax.crypto.spec.DHParameterSpec; import org.bouncycastle.jce.interfaces.ECPrivateKey; import org.bouncycastle.jce.interfaces.ECPublicKey; import org.bouncycastle.jce.provider.BouncyCastleProvider; import org.bouncycastle.jce.spec.ECParameterSpec; import org.bouncycastle.math.ec.ECCurve; import org.bouncycastle.util.encoders.Hex; import org.bouncycastle.util.test.SimpleTestResult; import org.bouncycastle.util.test.Test; import org.bouncycastle.util.test.TestResult; public class DHTest implements Test { private BigInteger g512 = new BigInteger("153d5d6172adb43045b68ae8e1de1070b6137005686d29d3d73a7749199681ee5b212c9b96bfdcfa5b20cd5e3fd2044895d609cf9b410b7a0f12ca1cb9a428cc", 16); private BigInteger p512 = new BigInteger("9494fec095f3b85ee286542b3836fc81a5dd0a0349b4c239dd38744d488cf8e31db8bcb7d33b41abb9e5a33cca9144b1cef332c94bf0573bf047a3aca98cdf3b", 16); private BigInteger g768 = new BigInteger("7c240073c1316c621df461b71ebb0cdcc90a6e5527e5e126633d131f87461c4dc4afc60c2cb0f053b6758871489a69613e2a8b4c8acde23954c08c81cbd36132cfd64d69e4ed9f8e51ed6e516297206672d5c0a69135df0a5dcf010d289a9ca1", 16); private BigInteger p768 = new BigInteger("8c9dd223debed1b80103b8b309715be009d48860ed5ae9b9d5d8159508efd802e3ad4501a7f7e1cfec78844489148cd72da24b21eddd01aa624291c48393e277cfc529e37075eccef957f3616f962d15b44aeab4039d01b817fde9eaa12fd73f", 16); private BigInteger g1024 = new BigInteger("1db17639cdf96bc4eabba19454f0b7e5bd4e14862889a725c96eb61048dcd676ceb303d586e30f060dbafd8a571a39c4d823982117da5cc4e0f89c77388b7a08896362429b94a18a327604eb7ff227bffbc83459ade299e57b5f77b50fb045250934938efa145511166e3197373e1b5b1e52de713eb49792bedde722c6717abf", 16); private BigInteger p1024 = new BigInteger("a00e283b3c624e5b2b4d9fbc2653b5185d99499b00fd1bf244c6f0bb817b4d1c451b2958d62a0f8a38caef059fb5ecd25d75ed9af403f5b5bdab97a642902f824e3c13789fed95fa106ddfe0ff4a707c85e2eb77d49e68f2808bcea18ce128b178cd287c6bc00efa9a1ad2a673fe0dceace53166f75b81d6709d5f8af7c66bb7", 16); public String getName() { return "DH"; } private TestResult testGP( int size, BigInteger g, BigInteger p) { DHParameterSpec dhParams = new DHParameterSpec(p, g); try { KeyPairGenerator keyGen = KeyPairGenerator.getInstance("DH", "BC"); keyGen.initialize(dhParams); // // a side // KeyPair aKeyPair = keyGen.generateKeyPair(); KeyAgreement aKeyAgree = KeyAgreement.getInstance("DH", "BC"); aKeyAgree.init(aKeyPair.getPrivate()); // // b side // KeyPair bKeyPair = keyGen.generateKeyPair(); KeyAgreement bKeyAgree = KeyAgreement.getInstance("DH", "BC"); bKeyAgree.init(bKeyPair.getPrivate()); // // agreement // aKeyAgree.doPhase(bKeyPair.getPublic(), true); bKeyAgree.doPhase(aKeyPair.getPublic(), true); BigInteger k1 = new BigInteger(aKeyAgree.generateSecret()); BigInteger k2 = new BigInteger(bKeyAgree.generateSecret()); if (!k1.equals(k2)) { return new SimpleTestResult(false, size + " bit 2-way test failed"); } // // public key encoding test // byte[] pubEnc = aKeyPair.getPublic().getEncoded(); KeyFactory keyFac = KeyFactory.getInstance("DH", "BC"); X509EncodedKeySpec pubX509 = new X509EncodedKeySpec(pubEnc); DHPublicKey pubKey = (DHPublicKey)keyFac.generatePublic(pubX509); DHParameterSpec spec = pubKey.getParams(); if (!spec.getG().equals(dhParams.getG()) || !spec.getP().equals(dhParams.getP())) { return new SimpleTestResult(false, size + " bit public key encoding/decoding test failed on parameters"); } if (!((DHPublicKey)aKeyPair.getPublic()).getY().equals(pubKey.getY())) { return new SimpleTestResult(false, size + " bit public key encoding/decoding test failed on y value"); } // // public key serialisation test // ByteArrayOutputStream bOut = new ByteArrayOutputStream(); ObjectOutputStream oOut = new ObjectOutputStream(bOut); oOut.writeObject(aKeyPair.getPublic()); ByteArrayInputStream bIn = new ByteArrayInputStream(bOut.toByteArray()); ObjectInputStream oIn = new ObjectInputStream(bIn); pubKey = (DHPublicKey)oIn.readObject(); spec = pubKey.getParams(); if (!spec.getG().equals(dhParams.getG()) || !spec.getP().equals(dhParams.getP())) { return new SimpleTestResult(false, size + " bit public key serialisation test failed on parameters"); } if (!((DHPublicKey)aKeyPair.getPublic()).getY().equals(pubKey.getY())) { return new SimpleTestResult(false, size + " bit public key serialisation test failed on y value"); } // // private key encoding test // byte[] privEnc = aKeyPair.getPrivate().getEncoded(); PKCS8EncodedKeySpec privPKCS8 = new PKCS8EncodedKeySpec(privEnc); DHPrivateKey privKey = (DHPrivateKey)keyFac.generatePrivate(privPKCS8); spec = privKey.getParams(); if (!spec.getG().equals(dhParams.getG()) || !spec.getP().equals(dhParams.getP())) { return new SimpleTestResult(false, size + " bit private key encoding/decoding test failed on parameters"); } if (!((DHPrivateKey)aKeyPair.getPrivate()).getX().equals(privKey.getX())) { return new SimpleTestResult(false, size + " bit private key encoding/decoding test failed on y value"); } // // private key serialisation test // bOut = new ByteArrayOutputStream(); oOut = new ObjectOutputStream(bOut); oOut.writeObject(aKeyPair.getPrivate()); bIn = new ByteArrayInputStream(bOut.toByteArray()); oIn = new ObjectInputStream(bIn); privKey = (DHPrivateKey)oIn.readObject(); spec = privKey.getParams(); if (!spec.getG().equals(dhParams.getG()) || !spec.getP().equals(dhParams.getP())) { return new SimpleTestResult(false, size + " bit private key serialisation test failed on parameters"); } if (!((DHPrivateKey)aKeyPair.getPrivate()).getX().equals(privKey.getX())) { return new SimpleTestResult(false, size + " bit private key serialisation test failed on y value"); } // // three party test // KeyPairGenerator aPairGen = KeyPairGenerator.getInstance("DH", "BC"); aPairGen.initialize(spec); KeyPair aPair = aPairGen.generateKeyPair(); KeyPairGenerator bPairGen = KeyPairGenerator.getInstance("DH", "BC"); bPairGen.initialize(spec); KeyPair bPair = bPairGen.generateKeyPair(); KeyPairGenerator cPairGen = KeyPairGenerator.getInstance("DH", "BC"); cPairGen.initialize(spec); KeyPair cPair = cPairGen.generateKeyPair(); aKeyAgree.init(aPair.getPrivate()); bKeyAgree.init(bPair.getPrivate()); KeyAgreement cKeyAgree = KeyAgreement.getInstance("DH", "BC"); cKeyAgree.init(cPair.getPrivate()); Key ac = aKeyAgree.doPhase(cPair.getPublic(), false); Key ba = bKeyAgree.doPhase(aPair.getPublic(), false); Key cb = cKeyAgree.doPhase(bPair.getPublic(), false); aKeyAgree.doPhase(cb, true); bKeyAgree.doPhase(ac, true); cKeyAgree.doPhase(ba, true); BigInteger aShared = new BigInteger(aKeyAgree.generateSecret()); BigInteger bShared = new BigInteger(bKeyAgree.generateSecret()); BigInteger cShared = new BigInteger(cKeyAgree.generateSecret()); if (!aShared.equals(bShared)) { return new SimpleTestResult(false, size + " bit 3-way test failed (a and b differ)"); } if (!cShared.equals(bShared)) { return new SimpleTestResult(false, size + " bit 3-way test failed (c and b differ)"); } } catch (Exception e) { return new SimpleTestResult(false, size + " bit 2-way test failed - exception: " + e); } return new SimpleTestResult(true, this.getName() + ": Okay"); } private TestResult testRandom( int size) { try { AlgorithmParameterGenerator a = AlgorithmParameterGenerator.getInstance("DH", "BC"); a.init(size, new SecureRandom()); AlgorithmParameters params = a.generateParameters(); byte[] encodeParams = params.getEncoded(); AlgorithmParameters a2 = AlgorithmParameters.getInstance("DH", "BC"); a2.init(encodeParams); // a and a2 should be equivalent! byte[] encodeParams_2 = a2.getEncoded(); if (!arrayEquals(encodeParams, encodeParams_2)) { return new SimpleTestResult(false, this.getName() + ": encode/decode parameters failed"); } DHParameterSpec dhP = (DHParameterSpec)params.getParameterSpec(DHParameterSpec.class); return testGP(size, dhP.getG(), dhP.getP()); } catch (Exception e) { return new SimpleTestResult(false, this.getName() + ": exception - " + e.toString()); } } private TestResult testECDH() { try { KeyPairGenerator g = KeyPairGenerator.getInstance("ECDH", "BC"); ECCurve curve = new ECCurve.Fp( new BigInteger("883423532389192164791648750360308885314476597252960362792450860609699839"), // q new BigInteger("7fffffffffffffffffffffff7fffffffffff8000000000007ffffffffffc", 16), // a new BigInteger("6b016c3bdcf18941d0d654921475ca71a9db2fb27d1d37796185c2942c0a", 16)); // b ECParameterSpec ecSpec = new ECParameterSpec( curve, curve.decodePoint(Hex.decode("020ffa963cdca8816ccc33b8642bedf905c3d358573d3f27fbbd3b3cb9aaaf")), // G new BigInteger("883423532389192164791648750360308884807550341691627752275345424702807307")); // n g.initialize(ecSpec, new SecureRandom()); // // a side // KeyPair aKeyPair = g.generateKeyPair(); KeyAgreement aKeyAgree = KeyAgreement.getInstance("ECDH", "BC"); aKeyAgree.init(aKeyPair.getPrivate()); // // b side // KeyPair bKeyPair = g.generateKeyPair(); KeyAgreement bKeyAgree = KeyAgreement.getInstance("ECDH", "BC"); bKeyAgree.init(bKeyPair.getPrivate()); // // agreement // aKeyAgree.doPhase(bKeyPair.getPublic(), true); bKeyAgree.doPhase(aKeyPair.getPublic(), true); BigInteger k1 = new BigInteger(aKeyAgree.generateSecret()); BigInteger k2 = new BigInteger(bKeyAgree.generateSecret()); if (!k1.equals(k2)) { return new SimpleTestResult(false, "ECDH 2-way test failed"); } // // public key encoding test // byte[] pubEnc = aKeyPair.getPublic().getEncoded(); KeyFactory keyFac = KeyFactory.getInstance("ECDH", "BC"); X509EncodedKeySpec pubX509 = new X509EncodedKeySpec(pubEnc); ECPublicKey pubKey = (ECPublicKey)keyFac.generatePublic(pubX509); if (!pubKey.getQ().equals(((ECPublicKey)aKeyPair.getPublic()).getQ())) { return new SimpleTestResult(false, "ECDH public key encoding (Q test) failed"); } if (!pubKey.getParameters().getG().equals(((ECPublicKey)aKeyPair.getPublic()).getParameters().getG())) { return new SimpleTestResult(false, "ECDH public key encoding (G test) failed"); } // // private key encoding test // byte[] privEnc = aKeyPair.getPrivate().getEncoded(); PKCS8EncodedKeySpec privPKCS8 = new PKCS8EncodedKeySpec(privEnc); ECPrivateKey privKey = (ECPrivateKey)keyFac.generatePrivate(privPKCS8); if (!privKey.getD().equals(((ECPrivateKey)aKeyPair.getPrivate()).getD())) { return new SimpleTestResult(false, "ECDH private key encoding (D test) failed"); } if (!privKey.getParameters().getG().equals(((ECPrivateKey)aKeyPair.getPrivate()).getParameters().getG())) { return new SimpleTestResult(false, "ECDH private key encoding (G test) failed"); } } catch (Exception e) { return new SimpleTestResult(false, "ECDH 2-way test failed - exception: " + e); } return new SimpleTestResult(true, this.getName() + ": Okay"); } private TestResult testECDHC() { try { KeyPairGenerator g = KeyPairGenerator.getInstance("ECDH", "BC"); ECCurve curve = new ECCurve.Fp( new BigInteger("883423532389192164791648750360308885314476597252960362792450860609699839"), // q new BigInteger("7fffffffffffffffffffffff7fffffffffff8000000000007ffffffffffc", 16), // a new BigInteger("6b016c3bdcf18941d0d654921475ca71a9db2fb27d1d37796185c2942c0a", 16)); // b ECParameterSpec ecSpec = new ECParameterSpec( curve, curve.decodePoint(Hex.decode("020ffa963cdca8816ccc33b8642bedf905c3d358573d3f27fbbd3b3cb9aaaf")), // G new BigInteger("883423532389192164791648750360308884807550341691627752275345424702807307")); // n g.initialize(ecSpec, new SecureRandom()); // // a side // KeyPair aKeyPair = g.generateKeyPair(); KeyAgreement aKeyAgree = KeyAgreement.getInstance("ECDHC", "BC"); aKeyAgree.init(aKeyPair.getPrivate()); // // b side // KeyPair bKeyPair = g.generateKeyPair(); KeyAgreement bKeyAgree = KeyAgreement.getInstance("ECDHC", "BC"); bKeyAgree.init(bKeyPair.getPrivate()); // // agreement // aKeyAgree.doPhase(bKeyPair.getPublic(), true); bKeyAgree.doPhase(aKeyPair.getPublic(), true); BigInteger k1 = new BigInteger(aKeyAgree.generateSecret()); BigInteger k2 = new BigInteger(bKeyAgree.generateSecret()); if (!k1.equals(k2)) { return new SimpleTestResult(false, "ECDHC 2-way test failed"); } // // public key encoding test // byte[] pubEnc = aKeyPair.getPublic().getEncoded(); KeyFactory keyFac = KeyFactory.getInstance("ECDH", "BC"); X509EncodedKeySpec pubX509 = new X509EncodedKeySpec(pubEnc); ECPublicKey pubKey = (ECPublicKey)keyFac.generatePublic(pubX509); if (!pubKey.getQ().equals(((ECPublicKey)aKeyPair.getPublic()).getQ())) { return new SimpleTestResult(false, "ECDH public key encoding (Q test) failed"); } if (!pubKey.getParameters().getN().equals(((ECPublicKey)aKeyPair.getPublic()).getParameters().getN())) { return new SimpleTestResult(false, "ECDH public key encoding (N test) failed"); } // // private key encoding test // byte[] privEnc = aKeyPair.getPrivate().getEncoded(); PKCS8EncodedKeySpec privPKCS8 = new PKCS8EncodedKeySpec(privEnc); ECPrivateKey privKey = (ECPrivateKey)keyFac.generatePrivate(privPKCS8); if (!privKey.getD().equals(((ECPrivateKey)aKeyPair.getPrivate()).getD())) { return new SimpleTestResult(false, "ECDH private key encoding (D test) failed"); } if (!privKey.getParameters().getN().equals(((ECPrivateKey)aKeyPair.getPrivate()).getParameters().getN())) { return new SimpleTestResult(false, "ECDH private key encoding (N test) failed"); } } catch (Exception e) { return new SimpleTestResult(false, "ECDHC 2-way test failed - exception: " + e); } return new SimpleTestResult(true, this.getName() + ": Okay"); } private TestResult testExceptions() { DHParameterSpec dhParams = new DHParameterSpec(p512, g512); try { KeyAgreement aKeyAgree = KeyAgreement.getInstance("DH", "BC"); aKeyAgree.generateSecret("DES"); } catch (IllegalStateException e) { // okay } catch (Exception e) { return new SimpleTestResult(false, "Unexpected exception: " + e, e); } return new SimpleTestResult(true, this.getName() + ": Okay"); } private boolean arrayEquals( byte[] a, byte[] b) { if (a.length != b.length) { return false; } for (int i = 0; i != a.length; i++) { if (a[i] != b[i]) { return false; } } return true; } public TestResult perform() { TestResult result; result = testGP(512, g512, p512); if (!result.isSuccessful()) { return result; } result = testGP(768, g768, p768); if (!result.isSuccessful()) { return result; } result = testGP(1024, g1024, p1024); if (!result.isSuccessful()) { return result; } result = testRandom(256); if (!result.isSuccessful()) { return result; } result = testECDH(); if (!result.isSuccessful()) { return result; } result = testECDHC(); if (!result.isSuccessful()) { return result; } result = testExceptions(); if (!result.isSuccessful()) { return result; } return result; } public static void main( String[] args) { Security.addProvider(new BouncyCastleProvider()); DHTest test = new DHTest(); TestResult result = test.perform(); System.out.println(result); } } bouncycastle-1.49.orig/test/jdk1.4/org/bouncycastle/jce/provider/test/PSSTest.java0000644000175000017500000002123610336343713027416 0ustar ebourgebourgpackage org.bouncycastle.jce.provider.test; import java.math.BigInteger; import java.security.AlgorithmParameters; import java.security.KeyFactory; import java.security.KeyPair; import java.security.KeyPairGenerator; import java.security.PrivateKey; import java.security.PublicKey; import java.security.SecureRandom; import java.security.Security; import java.security.Signature; import java.security.spec.PSSParameterSpec; import java.security.spec.RSAPrivateCrtKeySpec; import java.security.spec.RSAPublicKeySpec; import org.bouncycastle.jce.provider.BouncyCastleProvider; import org.bouncycastle.util.encoders.Hex; import org.bouncycastle.util.test.SimpleTestResult; import org.bouncycastle.util.test.Test; import org.bouncycastle.util.test.TestResult; public class PSSTest implements Test { private class FixedRandom extends SecureRandom { byte[] vals; FixedRandom( byte[] vals) { this.vals = vals; } public void nextBytes( byte[] bytes) { System.arraycopy(vals, 0, bytes, 0, vals.length); } } private boolean arrayEquals( byte[] a, byte[] b) { if (a.length != b.length) { return false; } for (int i = 0; i != a.length; i++) { if (a[i] != b[i]) { return false; } } return true; } private RSAPublicKeySpec pubKeySpec = new RSAPublicKeySpec( new BigInteger("a56e4a0e701017589a5187dc7ea841d156f2ec0e36ad52a44dfeb1e61f7ad991d8c51056ffedb162b4c0f283a12a88a394dff526ab7291cbb307ceabfce0b1dfd5cd9508096d5b2b8b6df5d671ef6377c0921cb23c270a70e2598e6ff89d19f105acc2d3f0cb35f29280e1386b6f64c4ef22e1e1f20d0ce8cffb2249bd9a2137",16), new BigInteger("010001",16)); private RSAPrivateCrtKeySpec privKeySpec = new RSAPrivateCrtKeySpec( new BigInteger("a56e4a0e701017589a5187dc7ea841d156f2ec0e36ad52a44dfeb1e61f7ad991d8c51056ffedb162b4c0f283a12a88a394dff526ab7291cbb307ceabfce0b1dfd5cd9508096d5b2b8b6df5d671ef6377c0921cb23c270a70e2598e6ff89d19f105acc2d3f0cb35f29280e1386b6f64c4ef22e1e1f20d0ce8cffb2249bd9a2137",16), new BigInteger("010001",16), new BigInteger("33a5042a90b27d4f5451ca9bbbd0b44771a101af884340aef9885f2a4bbe92e894a724ac3c568c8f97853ad07c0266c8c6a3ca0929f1e8f11231884429fc4d9ae55fee896a10ce707c3ed7e734e44727a39574501a532683109c2abacaba283c31b4bd2f53c3ee37e352cee34f9e503bd80c0622ad79c6dcee883547c6a3b325",16), new BigInteger("e7e8942720a877517273a356053ea2a1bc0c94aa72d55c6e86296b2dfc967948c0a72cbccca7eacb35706e09a1df55a1535bd9b3cc34160b3b6dcd3eda8e6443",16), new BigInteger("b69dca1cf7d4d7ec81e75b90fcca874abcde123fd2700180aa90479b6e48de8d67ed24f9f19d85ba275874f542cd20dc723e6963364a1f9425452b269a6799fd",16), new BigInteger("28fa13938655be1f8a159cbaca5a72ea190c30089e19cd274a556f36c4f6e19f554b34c077790427bbdd8dd3ede2448328f385d81b30e8e43b2fffa027861979",16), new BigInteger("1a8b38f398fa712049898d7fb79ee0a77668791299cdfa09efc0e507acb21ed74301ef5bfd48be455eaeb6e1678255827580a8e4e8e14151d1510a82a3f2e729",16), new BigInteger("27156aba4126d24a81f3a528cbfb27f56886f840a9f6e86e17a44b94fe9319584b8e22fdde1e5a2e3bd8aa5ba8d8584194eb2190acf832b847f13a3d24a79f4d",16)); // PSSExample1.1 private byte[] msg1a = Hex.decode("cdc87da223d786df3b45e0bbbc721326d1ee2af806cc315475cc6f0d9c66e1b62371d45ce2392e1ac92844c310102f156a0d8d52c1f4c40ba3aa65095786cb769757a6563ba958fed0bcc984e8b517a3d5f515b23b8a41e74aa867693f90dfb061a6e86dfaaee64472c00e5f20945729cbebe77f06ce78e08f4098fba41f9d6193c0317e8b60d4b6084acb42d29e3808a3bc372d85e331170fcbf7cc72d0b71c296648b3a4d10f416295d0807aa625cab2744fd9ea8fd223c42537029828bd16be02546f130fd2e33b936d2676e08aed1b73318b750a0167d0"); private byte[] slt1a = Hex.decode("dee959c7e06411361420ff80185ed57f3e6776af"); private byte[] sig1a = Hex.decode("9074308fb598e9701b2294388e52f971faac2b60a5145af185df5287b5ed2887e57ce7fd44dc8634e407c8e0e4360bc226f3ec227f9d9e54638e8d31f5051215df6ebb9c2f9579aa77598a38f914b5b9c1bd83c4e2f9f382a0d0aa3542ffee65984a601bc69eb28deb27dca12c82c2d4c3f66cd500f1ff2b994d8a4e30cbb33c"); private byte[] sig1b = Hex.decode("96ea348db4db2947aee807bd687411a880913706f21b383a1002b97e43656e5450a9d1812efbedd1ed159f8307986adf48bada66a8efd14bd9e2f6f6f458e73b50c8ce6e3079011c5b4bd1600a2601a66198a1582574a43f13e0966c6c2337e6ca0886cd9e1b1037aeadef1382117d22b35e7e4403f90531c8cfccdf223f98e4"); private byte[] sig1c = Hex.decode("9e64cc1062c537b142480bc5af407b55904ead970e20e0f8f6664279c96c6da6b03522160f224a85cc413dfe6bd00621485b665abac6d90ff38c9af06f4ddd6c7c81540439e5795601a1343d9feb465712ff8a5f5150391522fb5a9b8e2225a555f4efaa5e5c0ed7a19b27074c2d9f6dbbd0c893ba02c4a35b115d337bccd7a2"); public TestResult perform() { try { KeyFactory fact = KeyFactory.getInstance("RSA", "BC"); PrivateKey privKey = fact.generatePrivate(privKeySpec); PublicKey pubKey = fact.generatePublic(pubKeySpec); Signature s = Signature.getInstance("SHA1withRSA/PSS", "BC"); s.initSign(privKey, new FixedRandom(slt1a)); s.update(msg1a); byte[] sig = s.sign(); if (!arrayEquals(sig1a, sig)) { return new SimpleTestResult(false, "PSS Sign test expected " + new String(Hex.encode(sig1a)) + " got " + new String(Hex.encode(sig))); } s = Signature.getInstance("SHA1withRSAandMGF1", "BC"); s.initVerify(pubKey); s.update(msg1a); if (!s.verify(sig1a)) { return new SimpleTestResult(false, "SHA1 signature verification failed"); } s = Signature.getInstance("SHA1withRSAandMGF1", "BC"); s.setParameter(new PSSParameterSpec(20)); s.initVerify(pubKey); s.update(msg1a); if (!s.verify(sig1a)) { return new SimpleTestResult(false, "SHA1 signature verification with default parameters failed"); } AlgorithmParameters pss = s.getParameters(); if (!arrayEquals(pss.getEncoded(), new byte[] { 0x30, 0x00 })) { return new SimpleTestResult(false, "failed default encoding test."); } s = Signature.getInstance("SHA256withRSA/PSS", "BC"); s.initSign(privKey, new FixedRandom(slt1a)); s.update(msg1a); sig = s.sign(); pss = s.getParameters(); if (!arrayEquals(sig1b, sig)) { return new SimpleTestResult(false, "PSS Sign test expected " + new String(Hex.encode(sig1b)) + " got " + new String(Hex.encode(sig))); } s = Signature.getInstance("SHA256withRSAandMGF1", "BC"); s.setParameter(pss.getParameterSpec(PSSParameterSpec.class)); s.initVerify(pubKey); s.update(msg1a); if (!s.verify(sig1b)) { return new SimpleTestResult(false, "SHA256 signature verification failed"); } // // 512 test -with zero salt length // s = Signature.getInstance("SHA512withRSAandMGF1", "BC"); s.setParameter(new PSSParameterSpec(0)); s.initSign(privKey); s.update(msg1a); sig = s.sign(); pss = s.getParameters(); if (!arrayEquals(sig1c, sig)) { return new SimpleTestResult(false, "PSS Sign test expected " + new String(Hex.encode(sig1c)) + " got " + new String(Hex.encode(sig))); } s = Signature.getInstance("SHA512withRSAandMGF1", "BC"); s.setParameter(pss.getParameterSpec(PSSParameterSpec.class)); s.initVerify(pubKey); s.update(msg1a); if (!s.verify(sig1c)) { return new SimpleTestResult(false, "SHA512 signature verification failed"); } return new SimpleTestResult(true, getName() + ": Okay"); } catch (Exception e) { return new SimpleTestResult(false, getName() + ": exception - " + e.toString(), e); } } public String getName() { return "PSSTest"; } public static void main( String[] args) { Security.addProvider(new BouncyCastleProvider()); Test test = new PSSTest(); TestResult result = test.perform(); System.out.println(result.toString()); } } bouncycastle-1.49.orig/test/jdk1.4/org/bouncycastle/jce/provider/test/RegressionTest.java0000644000175000017500000000411711346354060031067 0ustar ebourgebourgpackage org.bouncycastle.jce.provider.test; import java.security.Security; import org.bouncycastle.jce.provider.BouncyCastleProvider; import org.bouncycastle.util.test.SimpleTestResult; import org.bouncycastle.util.test.Test; import org.bouncycastle.util.test.TestResult; public class RegressionTest { public static Test[] tests = { new FIPSDESTest(), new DESedeTest(), new AESTest(), new AESSICTest(), new GOST28147Test(), new PBETest(), new BlockCipherTest(), new MacTest(), new HMacTest(), new SealedTest(), new RSATest(), new DHTest(), new DSATest(), new ImplicitlyCaTest(), new GOST3410Test(), new ElGamalTest(), new ECIESTest(), new SigTest(), new AttrCertTest(), new CertTest(), new PKCS10CertRequestTest(), new EncryptedPrivateKeyInfoTest(), new KeyStoreTest(), new PKCS12StoreTest(), new DigestTest(), new PSSTest(), new WrapTest(), new DoFinalTest(), new CipherStreamTest(), new NamedCurveTest(), new PKIXTest(), new PKIXPolicyMappingTest(), new NetscapeCertRequestTest(), new CertPathTest(), new CertStoreTest(), new CertPathValidatorTest(), new CertPathBuilderTest(), new NISTCertPathTest(), new SerialisationTest(), new AttrCertSelectorTest() }; public static void main( String[] args) { Security.addProvider(new BouncyCastleProvider()); System.out.println("Testing " + Security.getProvider("BC").getInfo() + " version: " + Security.getProvider("BC").getVersion()); for (int i = 0; i != tests.length; i++) { TestResult result = tests[i].perform(); if (((SimpleTestResult)result).getException() != null) { ((SimpleTestResult)result).getException().printStackTrace(); } System.out.println(result); } } } bouncycastle-1.49.orig/test/jdk1.4/org/bouncycastle/jce/provider/test/ECIESTest.java0000644000175000017500000001570310336343713027603 0ustar ebourgebourgpackage org.bouncycastle.jce.provider.test; import java.math.BigInteger; import java.security.AlgorithmParameters; import java.security.KeyPair; import java.security.KeyPairGenerator; import java.security.PrivateKey; import java.security.PublicKey; import java.security.SecureRandom; import java.security.Security; import javax.crypto.Cipher; import org.bouncycastle.jce.provider.BouncyCastleProvider; import org.bouncycastle.jce.spec.ECParameterSpec; import org.bouncycastle.jce.spec.IEKeySpec; import org.bouncycastle.jce.spec.IESParameterSpec; import org.bouncycastle.math.ec.ECCurve; import org.bouncycastle.util.encoders.Hex; import org.bouncycastle.util.test.SimpleTestResult; import org.bouncycastle.util.test.Test; import org.bouncycastle.util.test.TestResult; /** * test for ECIES - Elliptic Curve Integrated Encryption Scheme */ public class ECIESTest implements Test { ECIESTest() { } public String getName() { return "ECIES"; } private boolean sameAs( byte[] a, byte[] b) { if (a.length != b.length) { return false; } for (int i = 0; i != a.length; i++) { if (a[i] != b[i]) { return false; } } return true; } public TestResult perform() { TestResult res; try { KeyPairGenerator g = KeyPairGenerator.getInstance("ECIES", "BC"); ECCurve curve = new ECCurve.Fp( new BigInteger("883423532389192164791648750360308885314476597252960362792450860609699839"), // q new BigInteger("7fffffffffffffffffffffff7fffffffffff8000000000007ffffffffffc", 16), // a new BigInteger("6b016c3bdcf18941d0d654921475ca71a9db2fb27d1d37796185c2942c0a", 16)); // b ECParameterSpec ecSpec = new ECParameterSpec( curve, curve.decodePoint(Hex.decode("020ffa963cdca8816ccc33b8642bedf905c3d358573d3f27fbbd3b3cb9aaaf")), // G new BigInteger("883423532389192164791648750360308884807550341691627752275345424702807307")); // n g.initialize(ecSpec, new SecureRandom()); res = performTest(g); if (!res.isSuccessful()) { return res; } g = KeyPairGenerator.getInstance("ECIES", "BC"); g.initialize(192, new SecureRandom()); res = performTest(g); if (!res.isSuccessful()) { return res; } g = KeyPairGenerator.getInstance("ECIES", "BC"); g.initialize(239, new SecureRandom()); res = performTest(g); if (!res.isSuccessful()) { return res; } g = KeyPairGenerator.getInstance("ECIES", "BC"); g.initialize(256, new SecureRandom()); res = performTest(g); if (!res.isSuccessful()) { return res; } res = performDefTest(g); if (!res.isSuccessful()) { return res; } } catch (Exception ex) { return new SimpleTestResult(false, this.getName() + ": stream cipher test exception " + ex.toString()); } return new SimpleTestResult(true, this.getName() + ": Okay"); } public TestResult performTest( KeyPairGenerator g) { try { // // a side // KeyPair aKeyPair = g.generateKeyPair(); PublicKey aPub = aKeyPair.getPublic(); PrivateKey aPriv = aKeyPair.getPrivate(); // // b side // KeyPair bKeyPair = g.generateKeyPair(); PublicKey bPub = bKeyPair.getPublic(); PrivateKey bPriv = bKeyPair.getPrivate(); // // stream test // Cipher c1 = Cipher.getInstance("ECIES", "BC"); Cipher c2 = Cipher.getInstance("ECIES", "BC"); IEKeySpec c1Key = new IEKeySpec(aPriv, bPub); IEKeySpec c2Key = new IEKeySpec(bPriv, aPub); byte[] d = new byte[] { 1, 2, 3, 4, 5, 6, 7, 8 }; byte[] e = new byte[] { 8, 7, 6, 5, 4, 3, 2, 1 }; IESParameterSpec param = new IESParameterSpec(d, e, 128); c1.init(Cipher.ENCRYPT_MODE, c1Key, param); c2.init(Cipher.DECRYPT_MODE, c2Key, param); byte[] message = Hex.decode("1234567890abcdef"); byte[] out1 = c1.doFinal(message, 0, message.length); byte[] out2 = c2.doFinal(out1, 0, out1.length); if (!sameAs(out2, message)) { return new SimpleTestResult(false, this.getName() + ": stream cipher test failed"); } } catch (Exception ex) { return new SimpleTestResult(false, this.getName() + ": stream cipher test exception " + ex.toString()); } return new SimpleTestResult(true, this.getName() + ": Okay"); } public TestResult performDefTest( KeyPairGenerator g) { try { // // a side // KeyPair aKeyPair = g.generateKeyPair(); PublicKey aPub = aKeyPair.getPublic(); PrivateKey aPriv = aKeyPair.getPrivate(); // // b side // KeyPair bKeyPair = g.generateKeyPair(); PublicKey bPub = bKeyPair.getPublic(); PrivateKey bPriv = bKeyPair.getPrivate(); // // stream test // Cipher c1 = Cipher.getInstance("ECIES", "BC"); Cipher c2 = Cipher.getInstance("ECIES", "BC"); IEKeySpec c1Key = new IEKeySpec(aPriv, bPub); IEKeySpec c2Key = new IEKeySpec(bPriv, aPub); c1.init(Cipher.ENCRYPT_MODE, c1Key); AlgorithmParameters param = c1.getParameters(); c2.init(Cipher.DECRYPT_MODE, c2Key, param); byte[] message = Hex.decode("1234567890abcdef"); byte[] out1 = c1.doFinal(message, 0, message.length); byte[] out2 = c2.doFinal(out1, 0, out1.length); if (!sameAs(out2, message)) { return new SimpleTestResult(false, this.getName() + ": stream cipher test failed"); } } catch (Exception ex) { return new SimpleTestResult(false, this.getName() + ": stream cipher test exception " + ex.toString()); } return new SimpleTestResult(true, this.getName() + ": Okay"); } public static void main( String[] args) { Security.addProvider(new BouncyCastleProvider()); ECIESTest test = new ECIESTest(); TestResult result = test.perform(); System.out.println(result); } } bouncycastle-1.49.orig/test/jdk1.3/0000755000175000017500000000000012152033550016376 5ustar ebourgebourgbouncycastle-1.49.orig/test/jdk1.3/org/0000755000175000017500000000000012152033550017165 5ustar ebourgebourgbouncycastle-1.49.orig/test/jdk1.3/org/bouncycastle/0000755000175000017500000000000012152033550021660 5ustar ebourgebourgbouncycastle-1.49.orig/test/jdk1.3/org/bouncycastle/openpgp/0000755000175000017500000000000012152033550023330 5ustar ebourgebourgbouncycastle-1.49.orig/test/jdk1.3/org/bouncycastle/openpgp/test/0000755000175000017500000000000012152033550024307 5ustar ebourgebourgbouncycastle-1.49.orig/test/jdk1.3/org/bouncycastle/openpgp/test/AllTests.java0000644000175000017500000000213412104157573026716 0ustar ebourgebourgpackage org.bouncycastle.openpgp.test; import java.security.Security; import junit.framework.Test; import junit.framework.TestCase; import junit.framework.TestSuite; import org.bouncycastle.jce.provider.BouncyCastleProvider; import org.bouncycastle.util.test.SimpleTestResult; public class AllTests extends TestCase { public void testPGP() { Security.addProvider(new BouncyCastleProvider()); org.bouncycastle.util.test.Test[] tests = RegressionTest.tests; for (int i = 0; i != tests.length; i++) { SimpleTestResult result = (SimpleTestResult)tests[i].perform(); if (!result.isSuccessful()) { fail(result.toString()); } } } public static void main (String[] args) { junit.textui.TestRunner.run(suite()); } public static Test suite() { TestSuite suite = new TestSuite("OpenPGP Tests"); suite.addTestSuite(AllTests.class); suite.addTestSuite(DSA2Test.class); return suite; } } bouncycastle-1.49.orig/test/jdk1.3/org/bouncycastle/crypto/0000755000175000017500000000000012152033550023200 5ustar ebourgebourgbouncycastle-1.49.orig/test/jdk1.3/org/bouncycastle/crypto/test/0000755000175000017500000000000012152033550024157 5ustar ebourgebourgbouncycastle-1.49.orig/test/jdk1.3/org/bouncycastle/crypto/test/DSATest.java0000644000175000017500000005641312147606476026323 0ustar ebourgebourgpackage org.bouncycastle.crypto.test; import java.math.BigInteger; import java.security.SecureRandom; import org.bouncycastle.crypto.AsymmetricCipherKeyPair; import org.bouncycastle.crypto.digests.SHA224Digest; import org.bouncycastle.crypto.digests.SHA256Digest; import org.bouncycastle.crypto.generators.DSAKeyPairGenerator; import org.bouncycastle.crypto.generators.DSAParametersGenerator; import org.bouncycastle.crypto.params.DSAKeyGenerationParameters; import org.bouncycastle.crypto.params.DSAParameterGenerationParameters; import org.bouncycastle.crypto.params.DSAParameters; import org.bouncycastle.crypto.params.DSAPrivateKeyParameters; import org.bouncycastle.crypto.params.DSAPublicKeyParameters; import org.bouncycastle.crypto.params.DSAValidationParameters; import org.bouncycastle.crypto.params.ParametersWithRandom; import org.bouncycastle.crypto.signers.DSASigner; import org.bouncycastle.util.Arrays; import org.bouncycastle.util.BigIntegers; import org.bouncycastle.util.encoders.Hex; import org.bouncycastle.util.test.FixedSecureRandom; import org.bouncycastle.util.test.SimpleTest; /** * Test based on FIPS 186-2, Appendix 5, an example of DSA, and FIPS 168-3 test vectors. */ public class DSATest extends SimpleTest { byte[] k1 = Hex.decode("d5014e4b60ef2ba8b6211b4062ba3224e0427dd3"); byte[] k2 = Hex.decode("345e8d05c075c3a508df729a1685690e68fcfb8c8117847e89063bca1f85d968fd281540b6e13bd1af989a1fbf17e06462bf511f9d0b140fb48ac1b1baa5bded"); SecureRandom random = new FixedSecureRandom(new byte[][] { k1, k2}); byte[] keyData = Hex.decode("b5014e4b60ef2ba8b6211b4062ba3224e0427dd3"); SecureRandom keyRandom = new FixedSecureRandom(new byte[][] { keyData, keyData }); BigInteger pValue = new BigInteger("8df2a494492276aa3d25759bb06869cbeac0d83afb8d0cf7cbb8324f0d7882e5d0762fc5b7210eafc2e9adac32ab7aac49693dfbf83724c2ec0736ee31c80291", 16); BigInteger qValue = new BigInteger("c773218c737ec8ee993b4f2ded30f48edace915f", 16); public String getName() { return "DSA"; } public void performTest() { BigInteger r = new BigInteger("68076202252361894315274692543577577550894681403"); BigInteger s = new BigInteger("1089214853334067536215539335472893651470583479365"); DSAParametersGenerator pGen = new DSAParametersGenerator(); pGen.init(512, 20, random); DSAParameters params = pGen.generateParameters(); DSAValidationParameters pValid = params.getValidationParameters(); if (pValid.getCounter() != 105) { fail("Counter wrong"); } if (!pValue.equals(params.getP()) || !qValue.equals(params.getQ())) { fail("p or q wrong"); } DSAKeyPairGenerator dsaKeyGen = new DSAKeyPairGenerator(); DSAKeyGenerationParameters genParam = new DSAKeyGenerationParameters(keyRandom, params); dsaKeyGen.init(genParam); AsymmetricCipherKeyPair pair = dsaKeyGen.generateKeyPair(); ParametersWithRandom param = new ParametersWithRandom(pair.getPrivate(), keyRandom); DSASigner dsa = new DSASigner(); dsa.init(true, param); byte[] message = BigIntegers.asUnsignedByteArray(new BigInteger("968236873715988614170569073515315707566766479517")); BigInteger[] sig = dsa.generateSignature(message); if (!r.equals(sig[0])) { fail("r component wrong.", r, sig[0]); } if (!s.equals(sig[1])) { fail("s component wrong.", s, sig[1]); } dsa.init(false, pair.getPublic()); if (!dsa.verifySignature(message, sig[0], sig[1])) { fail("verification fails"); } //dsa2Test1(); //dsa2Test2(); //dsa2Test3(); //dsa2Test4(); } private void dsa2Test1() { byte[] seed = Hex.decode("ED8BEE8D1CB89229D2903CBF0E51EE7377F48698"); DSAParametersGenerator pGen = new DSAParametersGenerator(); pGen.init(new DSAParameterGenerationParameters(1024, 160, 10, new DSATestSecureRandom(seed))); DSAParameters params = pGen.generateParameters(); DSAValidationParameters pv = params.getValidationParameters(); if (pv.getCounter() != 5) { fail("counter incorrect"); } if (!Arrays.areEqual(seed, pv.getSeed())) { fail("seed incorrect"); } if (!params.getQ().equals(new BigInteger("E950511EAB424B9A19A2AEB4E159B7844C589C4F", 16))) { fail("Q incorrect"); } if (!params.getP().equals(new BigInteger( "E0A67598CD1B763B" + "C98C8ABB333E5DDA0CD3AA0E5E1FB5BA8A7B4EABC10BA338" + "FAE06DD4B90FDA70D7CF0CB0C638BE3341BEC0AF8A7330A3" + "307DED2299A0EE606DF035177A239C34A912C202AA5F83B9" + "C4A7CF0235B5316BFC6EFB9A248411258B30B839AF172440" + "F32563056CB67A861158DDD90E6A894C72A5BBEF9E286C6B", 16))) { fail("P incorrect"); } if (!params.getG().equals(new BigInteger( "D29D5121B0423C27" + "69AB21843E5A3240FF19CACC792264E3BB6BE4F78EDD1B15" + "C4DFF7F1D905431F0AB16790E1F773B5CE01C804E509066A" + "9919F5195F4ABC58189FD9FF987389CB5BEDF21B4DAB4F8B" + "76A055FFE2770988FE2EC2DE11AD92219F0B351869AC24DA" + "3D7BA87011A701CE8EE7BFE49486ED4527B7186CA4610A75", 16))) { fail("G incorrect"); } DSAKeyPairGenerator kpGen = new DSAKeyPairGenerator(); kpGen.init(new DSAKeyGenerationParameters(new FixedSecureRandom(Hex.decode("D0EC4E50BB290A42E9E355C73D8809345DE2E139")), params)); AsymmetricCipherKeyPair kp = kpGen.generateKeyPair(); DSAPublicKeyParameters pub = (DSAPublicKeyParameters)kp.getPublic(); DSAPrivateKeyParameters priv = (DSAPrivateKeyParameters)kp.getPrivate(); if (!pub.getY().equals(new BigInteger( "25282217F5730501" + "DD8DBA3EDFCF349AAFFEC20921128D70FAC44110332201BB" + "A3F10986140CBB97C726938060473C8EC97B4731DB004293" + "B5E730363609DF9780F8D883D8C4D41DED6A2F1E1BBBDC97" + "9E1B9D6D3C940301F4E978D65B19041FCF1E8B518F5C0576" + "C770FE5A7A485D8329EE2914A2DE1B5DA4A6128CEAB70F79", 16))) { fail("Y value incorrect"); } if (!priv.getX().equals( new BigInteger("D0EC4E50BB290A42E9E355C73D8809345DE2E139", 16))) { fail("X value incorrect"); } DSASigner signer = new DSASigner(); signer.init(true, new ParametersWithRandom(kp.getPrivate(), new FixedSecureRandom(Hex.decode("349C55648DCF992F3F33E8026CFAC87C1D2BA075")))); byte[] msg = Hex.decode("A9993E364706816ABA3E25717850C26C9CD0D89D"); BigInteger[] sig = signer.generateSignature(msg); if (!sig[0].equals(new BigInteger("636155AC9A4633B4665D179F9E4117DF68601F34", 16))) { fail("R value incorrect"); } if (!sig[1].equals(new BigInteger("6C540B02D9D4852F89DF8CFC99963204F4347704", 16))) { fail("S value incorrect"); } signer.init(false, kp.getPublic()); if (!signer.verifySignature(msg, sig[0], sig[1])) { fail("signature not verified"); } } private void dsa2Test2() { byte[] seed = Hex.decode("5AFCC1EFFC079A9CCA6ECA86D6E3CC3B18642D9BE1CC6207C84002A9"); DSAParametersGenerator pGen = new DSAParametersGenerator(new SHA224Digest()); pGen.init(new DSAParameterGenerationParameters(2048, 224, 10, new DSATestSecureRandom(seed))); DSAParameters params = pGen.generateParameters(); DSAValidationParameters pv = params.getValidationParameters(); if (pv.getCounter() != 21) { fail("counter incorrect"); } if (!Arrays.areEqual(seed, pv.getSeed())) { fail("seed incorrect"); } if (!params.getQ().equals(new BigInteger("90EAF4D1AF0708B1B612FF35E0A2997EB9E9D263C9CE659528945C0D", 16))) { fail("Q incorrect"); } if (!params.getP().equals(new BigInteger( "C196BA05AC29E1F9C3C72D56DFFC6154" + "A033F1477AC88EC37F09BE6C5BB95F51C296DD20D1A28A06" + "7CCC4D4316A4BD1DCA55ED1066D438C35AEBAABF57E7DAE4" + "28782A95ECA1C143DB701FD48533A3C18F0FE23557EA7AE6" + "19ECACC7E0B51652A8776D02A425567DED36EABD90CA33A1" + "E8D988F0BBB92D02D1D20290113BB562CE1FC856EEB7CDD9" + "2D33EEA6F410859B179E7E789A8F75F645FAE2E136D252BF" + "FAFF89528945C1ABE705A38DBC2D364AADE99BE0D0AAD82E" + "5320121496DC65B3930E38047294FF877831A16D5228418D" + "E8AB275D7D75651CEFED65F78AFC3EA7FE4D79B35F62A040" + "2A1117599ADAC7B269A59F353CF450E6982D3B1702D9CA83", 16))) { fail("P incorrect"); } if (!params.getG().equals(new BigInteger( "A59A749A11242C58C894E9E5A91804E8"+ "FA0AC64B56288F8D47D51B1EDC4D65444FECA0111D78F35F"+ "C9FDD4CB1F1B79A3BA9CBEE83A3F811012503C8117F98E50"+ "48B089E387AF6949BF8784EBD9EF45876F2E6A5A495BE64B"+ "6E770409494B7FEE1DBB1E4B2BC2A53D4F893D418B715959"+ "2E4FFFDF6969E91D770DAEBD0B5CB14C00AD68EC7DC1E574"+ "5EA55C706C4A1C5C88964E34D09DEB753AD418C1AD0F4FDF"+ "D049A955E5D78491C0B7A2F1575A008CCD727AB376DB6E69"+ "5515B05BD412F5B8C2F4C77EE10DA48ABD53F5DD498927EE"+ "7B692BBBCDA2FB23A516C5B4533D73980B2A3B60E384ED20"+ "0AE21B40D273651AD6060C13D97FD69AA13C5611A51B9085", 16))) { fail("G incorrect"); } DSAKeyPairGenerator kpGen = new DSAKeyPairGenerator(); kpGen.init(new DSAKeyGenerationParameters(new FixedSecureRandom(Hex.decode("00D0F09ED3E2568F6CADF9224117DA2AEC5A4300E009DE1366023E17")), params)); AsymmetricCipherKeyPair kp = kpGen.generateKeyPair(); DSAPublicKeyParameters pub = (DSAPublicKeyParameters)kp.getPublic(); DSAPrivateKeyParameters priv = (DSAPrivateKeyParameters)kp.getPrivate(); if (!pub.getY().equals(new BigInteger( "70035C9A3B225B258F16741F3941FBF0" + "6F3D056CD7BD864604CBB5EE9DD85304EE8E8E4ABD5E9032" + "11DDF25CE149075510ACE166970AFDC7DF552B7244F342FA" + "02F7A621405B754909D757F97290E1FE5036E904CF593446" + "0C046D95659821E1597ED9F2B1F0E20863A6BBD0CE74DACB" + "A5D8C68A90B29C2157CDEDB82EC12B81EE3068F9BF5F7F34" + "6ECA41ED174CCCD7D154FA4F42F80FFE1BF46AE9D8125DEB" + "5B4BA08A72BDD86596DBEDDC9550FDD650C58F5AE5133509" + "A702F79A31ECB490F7A3C5581631F7C5BE4FF7F9E9F27FA3" + "90E47347AD1183509FED6FCF198BA9A71AB3335B4F38BE8D" + "15496A00B6DC2263E20A5F6B662320A3A1EC033AA61E3B68", 16))) { fail("Y value incorrect"); } if (!priv.getX().equals( new BigInteger("00D0F09ED3E2568F6CADF9224117DA2AEC5A4300E009DE1366023E17", 16))) { fail("X value incorrect"); } DSASigner signer = new DSASigner(); signer.init(true, new ParametersWithRandom(kp.getPrivate(), new FixedSecureRandom(Hex.decode("735959CC4463B8B440E407EECA8A473BF6A6D1FE657546F67D401F05")))); byte[] msg = Hex.decode("23097D223405D8228642A477BDA255B32AADBCE4BDA0B3F7E36C9DA7"); BigInteger[] sig = signer.generateSignature(msg); if (!sig[0].equals(new BigInteger("4400138D05F9639CAF54A583CAAF25D2B76D0C3EAD752CE17DBC85FE", 16))) { fail("R value incorrect"); } if (!sig[1].equals(new BigInteger("874D4F12CB13B61732D398445698CFA9D92381D938AA57EE2C9327B3", 16))) { fail("S value incorrect"); } signer.init(false, kp.getPublic()); if (!signer.verifySignature(msg, sig[0], sig[1])) { fail("signature not verified"); } } private void dsa2Test3() { byte[] seed = Hex.decode("4783081972865EA95D43318AB2EAF9C61A2FC7BBF1B772A09017BDF5A58F4FF0"); DSAParametersGenerator pGen = new DSAParametersGenerator(new SHA256Digest()); pGen.init(new DSAParameterGenerationParameters(2048, 256, 10, new DSATestSecureRandom(seed))); DSAParameters params = pGen.generateParameters(); DSAValidationParameters pv = params.getValidationParameters(); if (pv.getCounter() != 12) { fail("counter incorrect"); } if (!Arrays.areEqual(seed, pv.getSeed())) { fail("seed incorrect"); } if (!params.getQ().equals(new BigInteger("C24ED361870B61E0D367F008F99F8A1F75525889C89DB1B673C45AF5867CB467", 16))) { fail("Q incorrect"); } if (!params.getP().equals(new BigInteger( "F56C2A7D366E3EBDEAA1891FD2A0D099" + "436438A673FED4D75F594959CFFEBCA7BE0FC72E4FE67D91" + "D801CBA0693AC4ED9E411B41D19E2FD1699C4390AD27D94C" + "69C0B143F1DC88932CFE2310C886412047BD9B1C7A67F8A2" + "5909132627F51A0C866877E672E555342BDF9355347DBD43" + "B47156B2C20BAD9D2B071BC2FDCF9757F75C168C5D9FC431" + "31BE162A0756D1BDEC2CA0EB0E3B018A8B38D3EF2487782A" + "EB9FBF99D8B30499C55E4F61E5C7DCEE2A2BB55BD7F75FCD" + "F00E48F2E8356BDB59D86114028F67B8E07B127744778AFF" + "1CF1399A4D679D92FDE7D941C5C85C5D7BFF91BA69F9489D" + "531D1EBFA727CFDA651390F8021719FA9F7216CEB177BD75", 16))) { fail("P incorrect"); } if (!params.getG().equals(new BigInteger( "8DC6CC814CAE4A1C05A3E186A6FE27EA" + "BA8CDB133FDCE14A963A92E809790CBA096EAA26140550C1" + "29FA2B98C16E84236AA33BF919CD6F587E048C52666576DB" + "6E925C6CBE9B9EC5C16020F9A44C9F1C8F7A8E611C1F6EC2" + "513EA6AA0B8D0F72FED73CA37DF240DB57BBB27431D61869" + "7B9E771B0B301D5DF05955425061A30DC6D33BB6D2A32BD0" + "A75A0A71D2184F506372ABF84A56AEEEA8EB693BF29A6403" + "45FA1298A16E85421B2208D00068A5A42915F82CF0B858C8" + "FA39D43D704B6927E0B2F916304E86FB6A1B487F07D8139E" + "428BB096C6D67A76EC0B8D4EF274B8A2CF556D279AD267CC" + "EF5AF477AFED029F485B5597739F5D0240F67C2D948A6279", 16))) { fail("G incorrect"); } DSAKeyPairGenerator kpGen = new DSAKeyPairGenerator(); kpGen.init(new DSAKeyGenerationParameters(new FixedSecureRandom(Hex.decode("0CAF2EF547EC49C4F3A6FE6DF4223A174D01F2C115D49A6F73437C29A2A8458C")), params)); AsymmetricCipherKeyPair kp = kpGen.generateKeyPair(); DSAPublicKeyParameters pub = (DSAPublicKeyParameters)kp.getPublic(); DSAPrivateKeyParameters priv = (DSAPrivateKeyParameters)kp.getPrivate(); if (!pub.getY().equals(new BigInteger( "2828003D7C747199143C370FDD07A286" + "1524514ACC57F63F80C38C2087C6B795B62DE1C224BF8D1D" + "1424E60CE3F5AE3F76C754A2464AF292286D873A7A30B7EA" + "CBBC75AAFDE7191D9157598CDB0B60E0C5AA3F6EBE425500" + "C611957DBF5ED35490714A42811FDCDEB19AF2AB30BEADFF" + "2907931CEE7F3B55532CFFAEB371F84F01347630EB227A41" + "9B1F3F558BC8A509D64A765D8987D493B007C4412C297CAF" + "41566E26FAEE475137EC781A0DC088A26C8804A98C23140E" + "7C936281864B99571EE95C416AA38CEEBB41FDBFF1EB1D1D" + "C97B63CE1355257627C8B0FD840DDB20ED35BE92F08C49AE" + "A5613957D7E5C7A6D5A5834B4CB069E0831753ECF65BA02B", 16))) { fail("Y value incorrect"); } if (!priv.getX().equals( new BigInteger("0CAF2EF547EC49C4F3A6FE6DF4223A174D01F2C115D49A6F73437C29A2A8458C", 16))) { fail("X value incorrect"); } DSASigner signer = new DSASigner(); signer.init(true, new ParametersWithRandom(kp.getPrivate(), new FixedSecureRandom(Hex.decode("0CAF2EF547EC49C4F3A6FE6DF4223A174D01F2C115D49A6F73437C29A2A8458C")))); byte[] msg = Hex.decode("BA7816BF8F01CFEA414140DE5DAE2223B00361A396177A9CB410FF61F20015AD"); BigInteger[] sig = signer.generateSignature(msg); if (!sig[0].equals(new BigInteger("315C875DCD4850E948B8AC42824E9483A32D5BA5ABE0681B9B9448D444F2BE3C", 16))) { fail("R value incorrect"); } if (!sig[1].equals(new BigInteger("89718D12E54A8D9ED066E4A55F7ED5A2229CD23B9A3CEE78F83ED6AA61F6BCB9", 16))) { fail("S value incorrect"); } signer.init(false, kp.getPublic()); if (!signer.verifySignature(msg, sig[0], sig[1])) { fail("signature not verified"); } } private void dsa2Test4() { byte[] seed = Hex.decode("193AFCA7C1E77B3C1ECC618C81322E47B8B8B997C9C83515C59CC446C2D9BD47"); DSAParametersGenerator pGen = new DSAParametersGenerator(new SHA256Digest()); pGen.init(new DSAParameterGenerationParameters(3072, 256, 10, new DSATestSecureRandom(seed))); DSAParameters params = pGen.generateParameters(); DSAValidationParameters pv = params.getValidationParameters(); if (pv.getCounter() != 20) { fail("counter incorrect"); } if (!Arrays.areEqual(seed, pv.getSeed())) { fail("seed incorrect"); } if (!params.getQ().equals(new BigInteger("CFA0478A54717B08CE64805B76E5B14249A77A4838469DF7F7DC987EFCCFB11D", 16))) { fail("Q incorrect"); } if (!params.getP().equals(new BigInteger( "90066455B5CFC38F9CAA4A48B4281F292C260FEEF01FD610" + "37E56258A7795A1C7AD46076982CE6BB956936C6AB4DCFE0" + "5E6784586940CA544B9B2140E1EB523F009D20A7E7880E4E" + "5BFA690F1B9004A27811CD9904AF70420EEFD6EA11EF7DA1" + "29F58835FF56B89FAA637BC9AC2EFAAB903402229F491D8D" + "3485261CD068699B6BA58A1DDBBEF6DB51E8FE34E8A78E54" + "2D7BA351C21EA8D8F1D29F5D5D15939487E27F4416B0CA63" + "2C59EFD1B1EB66511A5A0FBF615B766C5862D0BD8A3FE7A0" + "E0DA0FB2FE1FCB19E8F9996A8EA0FCCDE538175238FC8B0E" + "E6F29AF7F642773EBE8CD5402415A01451A840476B2FCEB0" + "E388D30D4B376C37FE401C2A2C2F941DAD179C540C1C8CE0" + "30D460C4D983BE9AB0B20F69144C1AE13F9383EA1C08504F" + "B0BF321503EFE43488310DD8DC77EC5B8349B8BFE97C2C56" + "0EA878DE87C11E3D597F1FEA742D73EEC7F37BE43949EF1A" + "0D15C3F3E3FC0A8335617055AC91328EC22B50FC15B941D3" + "D1624CD88BC25F3E941FDDC6200689581BFEC416B4B2CB73", 16))) { fail("P incorrect"); } if (!params.getG().equals(new BigInteger( "5E5CBA992E0A680D885EB903AEA78E4A45A469103D448EDE" + "3B7ACCC54D521E37F84A4BDD5B06B0970CC2D2BBB715F7B8" + "2846F9A0C393914C792E6A923E2117AB805276A975AADB52" + "61D91673EA9AAFFEECBFA6183DFCB5D3B7332AA19275AFA1" + "F8EC0B60FB6F66CC23AE4870791D5982AAD1AA9485FD8F4A" + "60126FEB2CF05DB8A7F0F09B3397F3937F2E90B9E5B9C9B6" + "EFEF642BC48351C46FB171B9BFA9EF17A961CE96C7E7A7CC" + "3D3D03DFAD1078BA21DA425198F07D2481622BCE45969D9C" + "4D6063D72AB7A0F08B2F49A7CC6AF335E08C4720E31476B6" + "7299E231F8BD90B39AC3AE3BE0C6B6CACEF8289A2E2873D5" + "8E51E029CAFBD55E6841489AB66B5B4B9BA6E2F784660896" + "AFF387D92844CCB8B69475496DE19DA2E58259B090489AC8" + "E62363CDF82CFD8EF2A427ABCD65750B506F56DDE3B98856" + "7A88126B914D7828E2B63A6D7ED0747EC59E0E0A23CE7D8A" + "74C1D2C2A7AFB6A29799620F00E11C33787F7DED3B30E1A2" + "2D09F1FBDA1ABBBFBF25CAE05A13F812E34563F99410E73B", 16))) { fail("G incorrect"); } DSAKeyPairGenerator kpGen = new DSAKeyPairGenerator(); kpGen.init(new DSAKeyGenerationParameters(new FixedSecureRandom(Hex.decode("3ABC1587297CE7B9EA1AD6651CF2BC4D7F92ED25CABC8553F567D1B40EBB8764")), params)); AsymmetricCipherKeyPair kp = kpGen.generateKeyPair(); DSAPublicKeyParameters pub = (DSAPublicKeyParameters)kp.getPublic(); DSAPrivateKeyParameters priv = (DSAPrivateKeyParameters)kp.getPrivate(); if (!pub.getY().equals(new BigInteger( "8B891C8692D3DE875879390F2698B26FBECCA6B075535DCE" + "6B0C862577F9FA0DEF6074E7A7624121224A595896ABD4CD" + "A56B2CEFB942E025D2A4282FFAA98A48CDB47E1A6FCB5CFB" + "393EF35AF9DF913102BB303C2B5C36C3F8FC04ED7B8B69FE" + "FE0CF3E1FC05CFA713B3435B2656E913BA8874AEA9F93600" + "6AEB448BCD005D18EC3562A33D04CF25C8D3D69844343442" + "FA3DB7DE618C5E2DA064573E61E6D5581BFB694A23AC87FD" + "5B52D62E954E1376DB8DDB524FFC0D469DF978792EE44173" + "8E5DB05A7DC43E94C11A2E7A4FBE383071FA36D2A7EC8A93" + "88FE1C4F79888A99D3B6105697C2556B79BB4D7E781CEBB3" + "D4866AD825A5E830846072289FDBC941FA679CA82F5F78B7" + "461B2404DB883D215F4E0676CF5493950AC5591697BFEA8D" + "1EE6EC016B89BA51CAFB5F9C84C989FA117375E94578F28B" + "E0B34CE0545DA46266FD77F62D8F2CEE92AB77012AFEBC11" + "008985A821CD2D978C7E6FE7499D1AAF8DE632C21BB48CA5" + "CBF9F31098FD3FD3854C49A65D9201744AACE540354974F9", 16))) { fail("Y value incorrect"); } if (!priv.getX().equals( new BigInteger("3ABC1587297CE7B9EA1AD6651CF2BC4D7F92ED25CABC8553F567D1B40EBB8764", 16))) { fail("X value incorrect"); } DSASigner signer = new DSASigner(); signer.init(true, new ParametersWithRandom(kp.getPrivate(), new FixedSecureRandom(Hex.decode("A6902C1E6E3943C5628061588A8B007BCCEA91DBF12915483F04B24AB0678BEE")))); byte[] msg = Hex.decode("BA7816BF8F01CFEA414140DE5DAE2223B00361A396177A9CB410FF61F20015AD"); BigInteger[] sig = signer.generateSignature(msg); if (!sig[0].equals(new BigInteger("5F184E645A38BE8FB4A6871B6503A9D12924C7ABE04B71410066C2ECA6E3BE3E", 16))) { fail("R value incorrect"); } if (!sig[1].equals(new BigInteger("91EB0C7BA3D4B9B60B825C3D9F2CADA8A2C9D7723267B033CBCDCF8803DB9C18", 16))) { fail("S value incorrect"); } signer.init(false, kp.getPublic()); if (!signer.verifySignature(msg, sig[0], sig[1])) { fail("signature not verified"); } } public static void main( String[] args) { runTest(new DSATest()); } private class DSATestSecureRandom extends FixedSecureRandom { private boolean first = true; public DSATestSecureRandom(byte[] value) { super(value); } public void nextBytes(byte[] bytes) { if (first) { super.nextBytes(bytes); first = false; } else { bytes[bytes.length - 1] = 2; } } } } bouncycastle-1.49.orig/test/jdk1.3/org/bouncycastle/cert/0000755000175000017500000000000012152033550022615 5ustar ebourgebourgbouncycastle-1.49.orig/test/jdk1.3/org/bouncycastle/cert/crmf/0000755000175000017500000000000012152033550023544 5ustar ebourgebourgbouncycastle-1.49.orig/test/jdk1.3/org/bouncycastle/cert/crmf/test/0000755000175000017500000000000012152033550024523 5ustar ebourgebourgbouncycastle-1.49.orig/test/jdk1.3/org/bouncycastle/cert/crmf/test/AllTests.java0000644000175000017500000003545011521717164027141 0ustar ebourgebourgpackage org.bouncycastle.cert.crmf.test; import java.io.IOException; import java.math.BigInteger; import java.security.GeneralSecurityException; import java.security.KeyPair; import java.security.KeyPairGenerator; import java.security.PrivateKey; import java.security.PublicKey; import java.security.SecureRandom; import java.security.Security; import java.security.cert.X509Certificate; import java.security.interfaces.RSAPublicKey; import java.util.Date; import junit.framework.Test; import junit.framework.TestCase; import junit.framework.TestSuite; import org.bouncycastle.asn1.ASN1ObjectIdentifier; import org.bouncycastle.asn1.crmf.CRMFObjectIdentifiers; import org.bouncycastle.asn1.crmf.EncKeyWithID; import org.bouncycastle.asn1.crmf.EncryptedValue; import org.bouncycastle.asn1.x500.X500Name; import org.bouncycastle.asn1.x509.GeneralName; import org.bouncycastle.cert.X509CertificateHolder; import org.bouncycastle.cert.X509v1CertificateBuilder; import org.bouncycastle.cert.crmf.EncryptedValueBuilder; import org.bouncycastle.cert.crmf.EncryptedValuePadder; import org.bouncycastle.cert.crmf.EncryptedValueParser; import org.bouncycastle.cert.crmf.FixedLengthMGF1Padder; import org.bouncycastle.cert.crmf.PKIArchiveControl; import org.bouncycastle.cert.crmf.PKMACBuilder; import org.bouncycastle.cert.crmf.ValueDecryptorGenerator; import org.bouncycastle.cert.crmf.jcajce.JcaCertificateRequestMessage; import org.bouncycastle.cert.crmf.jcajce.JcaCertificateRequestMessageBuilder; import org.bouncycastle.cert.crmf.jcajce.JcaEncryptedValueBuilder; import org.bouncycastle.cert.crmf.jcajce.JcaPKIArchiveControlBuilder; import org.bouncycastle.cert.crmf.jcajce.JceAsymmetricValueDecryptorGenerator; import org.bouncycastle.cert.crmf.jcajce.JceCRMFEncryptorBuilder; import org.bouncycastle.cert.crmf.jcajce.JcePKMACValuesCalculator; import org.bouncycastle.cert.jcajce.JcaX509CertificateConverter; import org.bouncycastle.cert.jcajce.JcaX509v1CertificateBuilder; import org.bouncycastle.cert.jcajce.JcaX509CertificateHolder; import org.bouncycastle.cms.CMSAlgorithm; import org.bouncycastle.cms.CMSEnvelopedDataGenerator; import org.bouncycastle.cms.RecipientId; import org.bouncycastle.cms.RecipientInformation; import org.bouncycastle.cms.RecipientInformationStore; import org.bouncycastle.cms.jcajce.JceCMSContentEncryptorBuilder; import org.bouncycastle.cms.jcajce.JceKeyTransEnvelopedRecipient; import org.bouncycastle.cms.jcajce.JceKeyTransRecipientId; import org.bouncycastle.cms.jcajce.JceKeyTransRecipientInfoGenerator; import org.bouncycastle.jce.provider.BouncyCastleProvider; import org.bouncycastle.operator.OperatorCreationException; import org.bouncycastle.operator.jcajce.JcaContentSignerBuilder; import org.bouncycastle.operator.jcajce.JcaContentVerifierProviderBuilder; import org.bouncycastle.operator.jcajce.JceAsymmetricKeyWrapper; import org.bouncycastle.util.Arrays; public class AllTests extends TestCase { private static final byte[] TEST_DATA = "Hello world!".getBytes(); private static final String BC = BouncyCastleProvider.PROVIDER_NAME; private static final String PASSPHRASE = "hello world"; /* * * INFRASTRUCTURE * */ public AllTests(String name) { super(name); } public static void main(String args[]) { junit.textui.TestRunner.run(AllTests.class); } public static Test suite() { return new TestSuite(AllTests.class); } public void setUp() { Security.addProvider(new BouncyCastleProvider()); } public void tearDown() { } public void testBasicMessageWithArchiveControl() throws Exception { KeyPairGenerator kGen = KeyPairGenerator.getInstance("RSA", BC); kGen.initialize(512); KeyPair kp = kGen.generateKeyPair(); X509Certificate cert = makeV1Certificate(kp, "CN=Test", kp, "CN=Test"); JcaCertificateRequestMessageBuilder certReqBuild = new JcaCertificateRequestMessageBuilder(BigInteger.ONE); certReqBuild.setPublicKey(kp.getPublic()) .setSubject(new X500Name("CN=Test")); certReqBuild.addControl(new JcaPKIArchiveControlBuilder(kp.getPrivate(), new X500Name("CN=Test")) .addRecipientGenerator(new JceKeyTransRecipientInfoGenerator(cert).setProvider(BC)) .build(new JceCMSContentEncryptorBuilder(new ASN1ObjectIdentifier(CMSEnvelopedDataGenerator.AES128_CBC)).setProvider(BC).build())); JcaCertificateRequestMessage certReqMsg = new JcaCertificateRequestMessage(certReqBuild.build()); assertEquals(new X500Name("CN=Test"), certReqMsg.getCertTemplate().getSubject()); assertEquals(kp.getPublic(), certReqMsg.getPublicKey()); PKIArchiveControl archiveControl = (PKIArchiveControl)certReqMsg.getControl(CRMFObjectIdentifiers.id_regCtrl_pkiArchiveOptions); assertEquals(PKIArchiveControl.encryptedPrivKey, archiveControl.getArchiveType()); assertTrue(archiveControl.isEnvelopedData()); RecipientInformationStore recips = archiveControl.getEnvelopedData().getRecipientInfos(); RecipientId recipientId = new JceKeyTransRecipientId(cert); RecipientInformation recipientInformation = recips.get(recipientId); assertNotNull(recipientInformation); EncKeyWithID encKeyWithID = EncKeyWithID.getInstance(recipientInformation.getContent(new JceKeyTransEnvelopedRecipient(kp.getPrivate()).setProvider(BC))); assertTrue(encKeyWithID.hasIdentifier()); assertFalse(encKeyWithID.isIdentifierUTF8String()); assertEquals(new GeneralName(X500Name.getInstance(new X500Name("CN=Test").getEncoded())), encKeyWithID.getIdentifier()); assertTrue(Arrays.areEqual(kp.getPrivate().getEncoded(), encKeyWithID.getPrivateKey().getEncoded())); } public void testProofOfPossessionWithoutSender() throws Exception { KeyPairGenerator kGen = KeyPairGenerator.getInstance("RSA", BC); kGen.initialize(512); KeyPair kp = kGen.generateKeyPair(); X509Certificate cert = makeV1Certificate(kp, "CN=Test", kp, "CN=Test"); JcaCertificateRequestMessageBuilder certReqBuild = new JcaCertificateRequestMessageBuilder(BigInteger.ONE); certReqBuild.setPublicKey(kp.getPublic()) .setAuthInfoPKMAC(new PKMACBuilder(new JcePKMACValuesCalculator()), "fred".toCharArray()) .setProofOfPossessionSigningKeySigner(new JcaContentSignerBuilder("SHA1withRSA").setProvider(BC).build(kp.getPrivate())); certReqBuild.addControl(new JcaPKIArchiveControlBuilder(kp.getPrivate(), new X500Name("CN=test")) .addRecipientGenerator(new JceKeyTransRecipientInfoGenerator(cert).setProvider(BC)) .build(new JceCMSContentEncryptorBuilder(new ASN1ObjectIdentifier(CMSEnvelopedDataGenerator.AES128_CBC)).setProvider(BC).build())); JcaCertificateRequestMessage certReqMsg = new JcaCertificateRequestMessage(certReqBuild.build()); // check that internal check on popo signing is working okay try { certReqMsg.isValidSigningKeyPOP(new JcaContentVerifierProviderBuilder().setProvider(BC).build(kp.getPublic())); fail("IllegalStateException not thrown"); } catch (IllegalStateException e) { // ignore } assertTrue(certReqMsg.isValidSigningKeyPOP(new JcaContentVerifierProviderBuilder().setProvider(BC).build(kp.getPublic()), new PKMACBuilder(new JcePKMACValuesCalculator().setProvider(BC)), "fred".toCharArray())); assertEquals(kp.getPublic(), certReqMsg.getPublicKey()); } public void testProofOfPossessionWithSender() throws Exception { KeyPairGenerator kGen = KeyPairGenerator.getInstance("RSA", BC); kGen.initialize(512); KeyPair kp = kGen.generateKeyPair(); X509Certificate cert = makeV1Certificate(kp, "CN=Test", kp, "CN=Test"); JcaCertificateRequestMessageBuilder certReqBuild = new JcaCertificateRequestMessageBuilder(BigInteger.ONE); certReqBuild.setPublicKey(kp.getPublic()) .setAuthInfoSender(new X500Name("CN=Test")) .setProofOfPossessionSigningKeySigner(new JcaContentSignerBuilder("SHA1withRSA").setProvider(BC).build(kp.getPrivate())); certReqBuild.addControl(new JcaPKIArchiveControlBuilder(kp.getPrivate(), new X500Name("CN=test")) .addRecipientGenerator(new JceKeyTransRecipientInfoGenerator(cert).setProvider(BC)) .build(new JceCMSContentEncryptorBuilder(new ASN1ObjectIdentifier(CMSEnvelopedDataGenerator.AES128_CBC)).setProvider(BC).build())); JcaCertificateRequestMessage certReqMsg = new JcaCertificateRequestMessage(certReqBuild.build()); // check that internal check on popo signing is working okay try { certReqMsg.isValidSigningKeyPOP(new JcaContentVerifierProviderBuilder().setProvider(BC).build(kp.getPublic()), new PKMACBuilder(new JcePKMACValuesCalculator().setProvider(BC)), "fred".toCharArray()); fail("IllegalStateException not thrown"); } catch (IllegalStateException e) { // ignore } assertTrue(certReqMsg.isValidSigningKeyPOP(new JcaContentVerifierProviderBuilder().setProvider(BC).build(kp.getPublic()))); assertEquals(kp.getPublic(), certReqMsg.getPublicKey()); } public void testEncryptedValue() throws Exception { KeyPairGenerator kGen = KeyPairGenerator.getInstance("RSA", BC); kGen.initialize(512); KeyPair kp = kGen.generateKeyPair(); X509Certificate cert = makeV1Certificate(kp, "CN=Test", kp, "CN=Test"); JcaEncryptedValueBuilder build = new JcaEncryptedValueBuilder(new JceAsymmetricKeyWrapper(cert.getPublicKey()).setProvider(BC), new JceCRMFEncryptorBuilder(CMSAlgorithm.AES128_CBC).setProvider(BC).build()); EncryptedValue value = build.build(cert); ValueDecryptorGenerator decGen = new JceAsymmetricValueDecryptorGenerator(kp.getPrivate()).setProvider(BC); // try direct encryptedValueParserTest(value, decGen, cert); // try indirect encryptedValueParserTest(EncryptedValue.getInstance(value.getEncoded()), decGen, cert); } private void encryptedValueParserTest(EncryptedValue value, ValueDecryptorGenerator decGen, X509Certificate cert) throws Exception { EncryptedValueParser parser = new EncryptedValueParser(value); X509CertificateHolder holder = parser.readCertificateHolder(decGen); assertTrue(Arrays.areEqual(cert.getEncoded(), holder.getEncoded())); } public void testEncryptedValuePassphrase() throws Exception { char[] passphrase = PASSPHRASE.toCharArray(); KeyPairGenerator kGen = KeyPairGenerator.getInstance("RSA", BC); kGen.initialize(512); KeyPair kp = kGen.generateKeyPair(); X509Certificate cert = makeV1Certificate(kp, "CN=Test", kp, "CN=Test"); EncryptedValueBuilder build = new EncryptedValueBuilder(new JceAsymmetricKeyWrapper(cert.getPublicKey()).setProvider(BC), new JceCRMFEncryptorBuilder(CMSAlgorithm.AES128_CBC).setProvider(BC).build()); EncryptedValue value = build.build(passphrase); ValueDecryptorGenerator decGen = new JceAsymmetricValueDecryptorGenerator(kp.getPrivate()).setProvider(BC); // try direct encryptedValuePassphraseParserTest(value, null, decGen, cert); // try indirect encryptedValuePassphraseParserTest(EncryptedValue.getInstance(value.getEncoded()), null, decGen, cert); } public void testEncryptedValuePassphraseWithPadding() throws Exception { char[] passphrase = PASSPHRASE.toCharArray(); KeyPairGenerator kGen = KeyPairGenerator.getInstance("RSA", BC); kGen.initialize(512); KeyPair kp = kGen.generateKeyPair(); X509Certificate cert = makeV1Certificate(kp, "CN=Test", kp, "CN=Test"); FixedLengthMGF1Padder mgf1Padder = new FixedLengthMGF1Padder(200, new SecureRandom()); EncryptedValueBuilder build = new EncryptedValueBuilder(new JceAsymmetricKeyWrapper(cert.getPublicKey()).setProvider(BC), new JceCRMFEncryptorBuilder(CMSAlgorithm.AES128_CBC).setProvider(BC).build(), mgf1Padder); EncryptedValue value = build.build(passphrase); ValueDecryptorGenerator decGen = new JceAsymmetricValueDecryptorGenerator(kp.getPrivate()).setProvider(BC); // try direct encryptedValuePassphraseParserTest(value, mgf1Padder, decGen, cert); // try indirect encryptedValuePassphraseParserTest(EncryptedValue.getInstance(value.getEncoded()), mgf1Padder, decGen, cert); } private void encryptedValuePassphraseParserTest(EncryptedValue value, EncryptedValuePadder padder, ValueDecryptorGenerator decGen, X509Certificate cert) throws Exception { EncryptedValueParser parser = new EncryptedValueParser(value, padder); assertTrue(Arrays.areEqual(PASSPHRASE.toCharArray(), parser.readPassphrase(decGen))); } private static X509Certificate makeV1Certificate(KeyPair subKP, String _subDN, KeyPair issKP, String _issDN) throws GeneralSecurityException, IOException, OperatorCreationException { PublicKey subPub = subKP.getPublic(); PrivateKey issPriv = issKP.getPrivate(); PublicKey issPub = issKP.getPublic(); X509v1CertificateBuilder v1CertGen = new JcaX509v1CertificateBuilder( new X500Name(_issDN), BigInteger.valueOf(System.currentTimeMillis()), new Date(System.currentTimeMillis()), new Date(System.currentTimeMillis() + (1000L * 60 * 60 * 24 * 100)), new X500Name(_subDN), subPub); JcaContentSignerBuilder signerBuilder = null; if (issPub instanceof RSAPublicKey) { signerBuilder = new JcaContentSignerBuilder("SHA1WithRSA"); } else if (issPub.getAlgorithm().equals("DSA")) { signerBuilder = new JcaContentSignerBuilder("SHA1withDSA"); } else if (issPub.getAlgorithm().equals("ECDSA")) { signerBuilder = new JcaContentSignerBuilder("SHA1withECDSA"); } else if (issPub.getAlgorithm().equals("ECGOST3410")) { signerBuilder = new JcaContentSignerBuilder("GOST3411withECGOST3410"); } else { signerBuilder = new JcaContentSignerBuilder("GOST3411WithGOST3410"); } signerBuilder.setProvider(BC); X509Certificate _cert = new JcaX509CertificateConverter().setProvider(BC).getCertificate(v1CertGen.build(signerBuilder.build(issPriv))); _cert.checkValidity(new Date()); _cert.verify(issPub); return _cert; } } bouncycastle-1.49.orig/test/jdk1.3/org/bouncycastle/cert/test/0000755000175000017500000000000012152033550023574 5ustar ebourgebourgbouncycastle-1.49.orig/test/jdk1.3/org/bouncycastle/cert/test/AttrCertTest.java0000644000175000017500000006545711731467175027070 0ustar ebourgebourgpackage org.bouncycastle.cert.test; import java.io.ByteArrayInputStream; import java.io.IOException; import java.math.BigInteger; import java.security.KeyFactory; import java.security.PrivateKey; import java.security.PublicKey; import java.security.Security; import java.security.cert.CertificateFactory; import java.security.cert.X509Certificate; import java.security.spec.RSAPrivateCrtKeySpec; import java.security.spec.RSAPublicKeySpec; import java.util.ArrayList; import java.util.Collection; import java.util.Date; import java.util.List; import java.util.Set; import org.bouncycastle.asn1.ASN1Encodable; import org.bouncycastle.asn1.ASN1EncodableVector; import org.bouncycastle.asn1.ASN1ObjectIdentifier; import org.bouncycastle.asn1.ASN1String; import org.bouncycastle.asn1.DEROctetString; import org.bouncycastle.asn1.DERSequence; import org.bouncycastle.asn1.x500.X500Name; import org.bouncycastle.asn1.x509.Attribute; import org.bouncycastle.asn1.x509.GeneralName; import org.bouncycastle.asn1.x509.GeneralNames; import org.bouncycastle.asn1.x509.Extension; import org.bouncycastle.cert.AttributeCertificateHolder; import org.bouncycastle.cert.AttributeCertificateIssuer; import org.bouncycastle.cert.X509AttributeCertificateHolder; import org.bouncycastle.cert.X509v2AttributeCertificateBuilder; import org.bouncycastle.cert.jcajce.JcaCertStore; import org.bouncycastle.cert.jcajce.JcaX509CertificateHolder; import org.bouncycastle.jce.provider.BouncyCastleProvider; import org.bouncycastle.operator.ContentSigner; import org.bouncycastle.operator.jcajce.JcaContentSignerBuilder; import org.bouncycastle.operator.jcajce.JcaContentVerifierProviderBuilder; import org.bouncycastle.util.Store; import org.bouncycastle.util.encoders.Base64; import org.bouncycastle.util.test.SimpleTest; public class AttrCertTest extends SimpleTest { private static final String BC = BouncyCastleProvider.PROVIDER_NAME; private static final RSAPrivateCrtKeySpec RSA_PRIVATE_KEY_SPEC = new RSAPrivateCrtKeySpec( new BigInteger("b4a7e46170574f16a97082b22be58b6a2a629798419be12872a4bdba626cfae9900f76abfb12139dce5de56564fab2b6543165a040c606887420e33d91ed7ed7", 16), new BigInteger("11", 16), new BigInteger("9f66f6b05410cd503b2709e88115d55daced94d1a34d4e32bf824d0dde6028ae79c5f07b580f5dce240d7111f7ddb130a7945cd7d957d1920994da389f490c89", 16), new BigInteger("c0a0758cdf14256f78d4708c86becdead1b50ad4ad6c5c703e2168fbf37884cb", 16), new BigInteger("f01734d7960ea60070f1b06f2bb81bfac48ff192ae18451d5e56c734a5aab8a5", 16), new BigInteger("b54bb9edff22051d9ee60f9351a48591b6500a319429c069a3e335a1d6171391", 16), new BigInteger("d3d83daf2a0cecd3367ae6f8ae1aeb82e9ac2f816c6fc483533d8297dd7884cd", 16), new BigInteger("b8f52fc6f38593dabb661d3f50f8897f8106eee68b1bce78a95b132b4e5b5d19", 16)); public static byte[] attrCert = Base64.decode( "MIIHQDCCBqkCAQEwgZChgY2kgYowgYcxHDAaBgkqhkiG9w0BCQEWDW1sb3JjaEB2" + "dC5lZHUxHjAcBgNVBAMTFU1hcmt1cyBMb3JjaCAobWxvcmNoKTEbMBkGA1UECxMS" + "VmlyZ2luaWEgVGVjaCBVc2VyMRAwDgYDVQQLEwdDbGFzcyAyMQswCQYDVQQKEwJ2" + "dDELMAkGA1UEBhMCVVMwgYmkgYYwgYMxGzAZBgkqhkiG9w0BCQEWDHNzaGFoQHZ0" + "LmVkdTEbMBkGA1UEAxMSU3VtaXQgU2hhaCAoc3NoYWgpMRswGQYDVQQLExJWaXJn" + "aW5pYSBUZWNoIFVzZXIxEDAOBgNVBAsTB0NsYXNzIDExCzAJBgNVBAoTAnZ0MQsw" + "CQYDVQQGEwJVUzANBgkqhkiG9w0BAQQFAAIBBTAiGA8yMDAzMDcxODE2MDgwMloY" + "DzIwMDMwNzI1MTYwODAyWjCCBU0wggVJBgorBgEEAbRoCAEBMYIFORaCBTU8UnVs" + "ZSBSdWxlSWQ9IkZpbGUtUHJpdmlsZWdlLVJ1bGUiIEVmZmVjdD0iUGVybWl0Ij4K" + "IDxUYXJnZXQ+CiAgPFN1YmplY3RzPgogICA8U3ViamVjdD4KICAgIDxTdWJqZWN0" + "TWF0Y2ggTWF0Y2hJZD0idXJuOm9hc2lzOm5hbWVzOnRjOnhhY21sOjEuMDpmdW5j" + "dGlvbjpzdHJpbmctZXF1YWwiPgogICAgIDxBdHRyaWJ1dGVWYWx1ZSBEYXRhVHlw" + "ZT0iaHR0cDovL3d3dy53My5vcmcvMjAwMS9YTUxTY2hlbWEjc3RyaW5nIj4KICAg" + "ICAgIENOPU1hcmt1cyBMb3JjaDwvQXR0cmlidXRlVmFsdWU+CiAgICAgPFN1Ympl" + "Y3RBdHRyaWJ1dGVEZXNpZ25hdG9yIEF0dHJpYnV0ZUlkPSJ1cm46b2FzaXM6bmFt" + "ZXM6dGM6eGFjbWw6MS4wOnN1YmplY3Q6c3ViamVjdC1pZCIgRGF0YVR5cGU9Imh0" + "dHA6Ly93d3cudzMub3JnLzIwMDEvWE1MU2NoZW1hI3N0cmluZyIgLz4gCiAgICA8" + "L1N1YmplY3RNYXRjaD4KICAgPC9TdWJqZWN0PgogIDwvU3ViamVjdHM+CiAgPFJl" + "c291cmNlcz4KICAgPFJlc291cmNlPgogICAgPFJlc291cmNlTWF0Y2ggTWF0Y2hJ" + "ZD0idXJuOm9hc2lzOm5hbWVzOnRjOnhhY21sOjEuMDpmdW5jdGlvbjpzdHJpbmct" + "ZXF1YWwiPgogICAgIDxBdHRyaWJ1dGVWYWx1ZSBEYXRhVHlwZT0iaHR0cDovL3d3" + "dy53My5vcmcvMjAwMS9YTUxTY2hlbWEjYW55VVJJIj4KICAgICAgaHR0cDovL3p1" + "bmkuY3MudnQuZWR1PC9BdHRyaWJ1dGVWYWx1ZT4KICAgICA8UmVzb3VyY2VBdHRy" + "aWJ1dGVEZXNpZ25hdG9yIEF0dHJpYnV0ZUlkPSJ1cm46b2FzaXM6bmFtZXM6dGM6" + "eGFjbWw6MS4wOnJlc291cmNlOnJlc291cmNlLWlkIiBEYXRhVHlwZT0iaHR0cDov" + "L3d3dy53My5vcmcvMjAwMS9YTUxTY2hlbWEjYW55VVJJIiAvPiAKICAgIDwvUmVz" + "b3VyY2VNYXRjaD4KICAgPC9SZXNvdXJjZT4KICA8L1Jlc291cmNlcz4KICA8QWN0" + "aW9ucz4KICAgPEFjdGlvbj4KICAgIDxBY3Rpb25NYXRjaCBNYXRjaElkPSJ1cm46" + "b2FzaXM6bmFtZXM6dGM6eGFjbWw6MS4wOmZ1bmN0aW9uOnN0cmluZy1lcXVhbCI+" + "CiAgICAgPEF0dHJpYnV0ZVZhbHVlIERhdGFUeXBlPSJodHRwOi8vd3d3LnczLm9y" + "Zy8yMDAxL1hNTFNjaGVtYSNzdHJpbmciPgpEZWxlZ2F0ZSBBY2Nlc3MgICAgIDwv" + "QXR0cmlidXRlVmFsdWU+CgkgIDxBY3Rpb25BdHRyaWJ1dGVEZXNpZ25hdG9yIEF0" + "dHJpYnV0ZUlkPSJ1cm46b2FzaXM6bmFtZXM6dGM6eGFjbWw6MS4wOmFjdGlvbjph" + "Y3Rpb24taWQiIERhdGFUeXBlPSJodHRwOi8vd3d3LnczLm9yZy8yMDAxL1hNTFNj" + "aGVtYSNzdHJpbmciIC8+IAogICAgPC9BY3Rpb25NYXRjaD4KICAgPC9BY3Rpb24+" + "CiAgPC9BY3Rpb25zPgogPC9UYXJnZXQ+CjwvUnVsZT4KMA0GCSqGSIb3DQEBBAUA" + "A4GBAGiJSM48XsY90HlYxGmGVSmNR6ZW2As+bot3KAfiCIkUIOAqhcphBS23egTr" + "6asYwy151HshbPNYz+Cgeqs45KkVzh7bL/0e1r8sDVIaaGIkjHK3CqBABnfSayr3" + "Rd1yBoDdEv8Qb+3eEPH6ab9021AsLEnJ6LWTmybbOpMNZ3tv"); byte[] signCert = Base64.decode( "MIIGjTCCBXWgAwIBAgICAPswDQYJKoZIhvcNAQEEBQAwaTEdMBsGCSqGSIb3DQEJ" + "ARYOaXJtaGVscEB2dC5lZHUxLjAsBgNVBAMTJVZpcmdpbmlhIFRlY2ggQ2VydGlm" + "aWNhdGlvbiBBdXRob3JpdHkxCzAJBgNVBAoTAnZ0MQswCQYDVQQGEwJVUzAeFw0w" + "MzAxMzExMzUyMTRaFw0wNDAxMzExMzUyMTRaMIGDMRswGQYJKoZIhvcNAQkBFgxz" + "c2hhaEB2dC5lZHUxGzAZBgNVBAMTElN1bWl0IFNoYWggKHNzaGFoKTEbMBkGA1UE" + "CxMSVmlyZ2luaWEgVGVjaCBVc2VyMRAwDgYDVQQLEwdDbGFzcyAxMQswCQYDVQQK" + "EwJ2dDELMAkGA1UEBhMCVVMwgZ8wDQYJKoZIhvcNAQEBBQADgY0AMIGJAoGBAPDc" + "scgSKmsEp0VegFkuitD5j5PUkDuzLjlfaYONt2SN8WeqU4j2qtlCnsipa128cyKS" + "JzYe9duUdNxquh5BPIkMkHBw4jHoQA33tk0J/sydWdN74/AHPpPieK5GHwhU7GTG" + "rCCS1PJRxjXqse79ExAlul+gjQwHeldAC+d4A6oZAgMBAAGjggOmMIIDojAMBgNV" + "HRMBAf8EAjAAMBEGCWCGSAGG+EIBAQQEAwIFoDAOBgNVHQ8BAf8EBAMCA/gwHQYD" + "VR0lBBYwFAYIKwYBBQUHAwIGCCsGAQUFBwMEMB0GA1UdDgQWBBRUIoWAzlXbzBYE" + "yVTjQFWyMMKo1jCBkwYDVR0jBIGLMIGIgBTgc3Fm+TGqKDhen+oKfbl+xVbj2KFt" + "pGswaTEdMBsGCSqGSIb3DQEJARYOaXJtaGVscEB2dC5lZHUxLjAsBgNVBAMTJVZp" + "cmdpbmlhIFRlY2ggQ2VydGlmaWNhdGlvbiBBdXRob3JpdHkxCzAJBgNVBAoTAnZ0" + "MQswCQYDVQQGEwJVU4IBADCBiwYJYIZIAYb4QgENBH4WfFZpcmdpbmlhIFRlY2gg" + "Q2VydGlmaWNhdGlvbiBBdXRob3JpdHkgZGlnaXRhbCBjZXJ0aWZpY2F0ZXMgYXJl" + "IHN1YmplY3QgdG8gcG9saWNpZXMgbG9jYXRlZCBhdCBodHRwOi8vd3d3LnBraS52" + "dC5lZHUvY2EvY3BzLy4wFwYDVR0RBBAwDoEMc3NoYWhAdnQuZWR1MBkGA1UdEgQS" + "MBCBDmlybWhlbHBAdnQuZWR1MEMGCCsGAQUFBwEBBDcwNTAzBggrBgEFBQcwAoYn" + "aHR0cDovL2JveDE3Ny5jYy52dC5lZHUvY2EvaXNzdWVycy5odG1sMEQGA1UdHwQ9" + "MDswOaA3oDWGM2h0dHA6Ly9ib3gxNzcuY2MudnQuZWR1L2h0ZG9jcy1wdWJsaWMv" + "Y3JsL2NhY3JsLmNybDBUBgNVHSAETTBLMA0GCysGAQQBtGgFAQEBMDoGCysGAQQB" + "tGgFAQEBMCswKQYIKwYBBQUHAgEWHWh0dHA6Ly93d3cucGtpLnZ0LmVkdS9jYS9j" + "cHMvMD8GCWCGSAGG+EIBBAQyFjBodHRwOi8vYm94MTc3LmNjLnZ0LmVkdS9jZ2kt" + "cHVibGljL2NoZWNrX3Jldl9jYT8wPAYJYIZIAYb4QgEDBC8WLWh0dHA6Ly9ib3gx" + "NzcuY2MudnQuZWR1L2NnaS1wdWJsaWMvY2hlY2tfcmV2PzBLBglghkgBhvhCAQcE" + "PhY8aHR0cHM6Ly9ib3gxNzcuY2MudnQuZWR1L35PcGVuQ0E4LjAxMDYzMC9jZ2kt" + "cHVibGljL3JlbmV3YWw/MCwGCWCGSAGG+EIBCAQfFh1odHRwOi8vd3d3LnBraS52" + "dC5lZHUvY2EvY3BzLzANBgkqhkiG9w0BAQQFAAOCAQEAHJ2ls9yjpZVcu5DqiE67" + "r7BfkdMnm7IOj2v8cd4EAlPp6OPBmjwDMwvKRBb/P733kLBqFNWXWKTpT008R0KB" + "8kehbx4h0UPz9vp31zhGv169+5iReQUUQSIwTGNWGLzrT8kPdvxiSAvdAJxcbRBm" + "KzDic5I8PoGe48kSCkPpT1oNmnivmcu5j1SMvlx0IS2BkFMksr0OHiAW1elSnE/N" + "RuX2k73b3FucwVxB3NRo3vgoHPCTnh9r4qItAHdxFlF+pPtbw2oHESKRfMRfOIHz" + "CLQWSIa6Tvg4NIV3RRJ0sbCObesyg08lymalQMdkXwtRn5eGE00SHWwEUjSXP2gR" + "3g=="); static byte[] certWithBaseCertificateID = Base64.decode( "MIIBqzCCARQCAQEwSKBGMD6kPDA6MQswCQYDVQQGEwJJVDEOMAwGA1UEChMFVU5JVE4xDDAKBgNV" + "BAsTA0RJVDENMAsGA1UEAxMEcm9vdAIEAVMVjqB6MHikdjB0MQswCQYDVQQGEwJBVTEoMCYGA1UE" + "ChMfVGhlIExlZ2lvbiBvZiB0aGUgQm91bmN5IENhc3RsZTEjMCEGA1UECxMaQm91bmN5IFByaW1h" + "cnkgQ2VydGlmaWNhdGUxFjAUBgNVBAMTDUJvdW5jeSBDYXN0bGUwDQYJKoZIhvcNAQEFBQACBQKW" + "RhnHMCIYDzIwMDUxMjEyMTIwMDQyWhgPMjAwNTEyMTkxMjAxMzJaMA8wDQYDVRhIMQaBBGVWSVAw" + "DQYJKoZIhvcNAQEFBQADgYEAUAVin9StDaA+InxtXq/av6rUQLI9p1X6louBcj4kYJnxRvTrHpsr" + "N3+i9Uq/uk5lRdAqmPFvcmSbuE3TRAsjrXON5uFiBBKZ1AouLqcr8nHbwcdwjJ9TyUNO9I4hfpSH" + "UHHXMtBKgp4MOkhhX8xTGyWg3hp23d3GaUeg/IYlXBI="); byte[] holderCertWithBaseCertificateID = Base64.decode( "MIIBwDCCASmgAwIBAgIEAVMVjjANBgkqhkiG9w0BAQUFADA6MQswCQYDVQQGEwJJVDEOMAwGA1UE" + "ChMFVU5JVE4xDDAKBgNVBAsTA0RJVDENMAsGA1UEAxMEcm9vdDAeFw0wNTExMTExMjAxMzJaFw0w" + "NjA2MTYxMjAxMzJaMD4xCzAJBgNVBAYTAklUMQ4wDAYDVQQKEwVVTklUTjEMMAoGA1UECxMDRElU" + "MREwDwYDVQQDEwhMdWNhQm9yejBaMA0GCSqGSIb3DQEBAQUAA0kAMEYCQQC0p+RhcFdPFqlwgrIr" + "5YtqKmKXmEGb4ShypL26Ymz66ZAPdqv7EhOdzl3lZWT6srZUMWWgQMYGiHQg4z2R7X7XAgERoxUw" + "EzARBglghkgBhvhCAQEEBAMCBDAwDQYJKoZIhvcNAQEFBQADgYEAsX50VPQQCWmHvPq9y9DeCpmS" + "4szcpFAhpZyn6gYRwY9CRZVtmZKH8713XhkGDWcIEMcG0u3oTz3tdKgPU5uyIPrDEWr6w8ClUj4x" + "5aVz5c2223+dVY7KES//JSB2bE/KCIchN3kAioQ4K8O3e0OL6oDVjsqKGw5bfahgKuSIk/Q="); public String getName() { return "AttrCertTest"; } private void testCertWithBaseCertificateID() throws Exception { X509AttributeCertificateHolder attrCert = new X509AttributeCertificateHolder(certWithBaseCertificateID); CertificateFactory fact = CertificateFactory.getInstance("X.509", "BC"); X509Certificate cert = (X509Certificate)fact.generateCertificate(new ByteArrayInputStream(holderCertWithBaseCertificateID)); AttributeCertificateHolder holder = attrCert.getHolder(); if (holder.getEntityNames() != null) { fail("entity names set when none expected"); } if (!holder.getSerialNumber().equals(cert.getSerialNumber())) { fail("holder serial number doesn't match"); } if (!holder.getIssuer()[0].equals(new JcaX509CertificateHolder(cert).getIssuer())) { fail("holder issuer doesn't match"); } if (!holder.match(new JcaX509CertificateHolder(cert))) { fail("holder not matching holder certificate"); } if (!holder.equals(holder.clone())) { fail("holder clone test failed"); } if (!attrCert.getIssuer().equals(attrCert.getIssuer().clone())) { fail("issuer clone test failed"); } //equalityAndHashCodeTest(attrCert, certWithBaseCertificateID); } private void equalityAndHashCodeTest(X509AttributeCertificateHolder attrCert, byte[] encoding) throws IOException { if (!attrCert.equals(attrCert)) { fail("same certificate not equal"); } if (!attrCert.getHolder().equals(attrCert.getHolder())) { fail("same holder not equal"); } if (!attrCert.getIssuer().equals(attrCert.getIssuer())) { fail("same issuer not equal"); } if (attrCert.getHolder().equals(attrCert.getIssuer())) { fail("wrong holder equal"); } if (attrCert.getIssuer().equals(attrCert.getHolder())) { fail("wrong issuer equal"); } X509AttributeCertificateHolder attrCert2 = new X509AttributeCertificateHolder(encoding); if (attrCert2.getHolder().hashCode() != attrCert.getHolder().hashCode()) { fail("holder hashCode test failed"); } if (!attrCert2.getHolder().equals(attrCert.getHolder())) { fail("holder equals test failed"); } if (attrCert2.getIssuer().hashCode() != attrCert.getIssuer().hashCode()) { fail("issuer hashCode test failed"); } if (!attrCert2.getIssuer().equals(attrCert.getIssuer())) { fail("issuer equals test failed"); } } private void testGenerateWithCert() throws Exception { CertificateFactory fact = CertificateFactory.getInstance("X.509","BC"); X509Certificate iCert = (X509Certificate)fact.generateCertificate(new ByteArrayInputStream(signCert)); // // a sample key pair. // RSAPublicKeySpec pubKeySpec = new RSAPublicKeySpec( new BigInteger("b4a7e46170574f16a97082b22be58b6a2a629798419be12872a4bdba626cfae9900f76abfb12139dce5de56564fab2b6543165a040c606887420e33d91ed7ed7", 16), new BigInteger("11", 16)); // // set up the keys // PrivateKey privKey; PublicKey pubKey; KeyFactory kFact = KeyFactory.getInstance("RSA", "BC"); privKey = kFact.generatePrivate(RSA_PRIVATE_KEY_SPEC); pubKey = kFact.generatePublic(pubKeySpec); X509v2AttributeCertificateBuilder gen = new X509v2AttributeCertificateBuilder( new AttributeCertificateHolder(new JcaX509CertificateHolder(iCert)), new AttributeCertificateIssuer(new X500Name("cn=test")), BigInteger.valueOf(1), new Date(System.currentTimeMillis() - 50000), new Date(System.currentTimeMillis() + 50000)); // the actual attributes GeneralName roleName = new GeneralName(GeneralName.rfc822Name, "DAU123456789"); ASN1EncodableVector roleSyntax = new ASN1EncodableVector(); roleSyntax.add(roleName); // roleSyntax OID: 2.5.24.72; gen.addAttribute(new ASN1ObjectIdentifier("2.5.24.72"), new DERSequence(roleSyntax)); ContentSigner sigGen = new JcaContentSignerBuilder("SHA1WithRSAEncryption").setProvider(BC).build(privKey); X509AttributeCertificateHolder aCert = gen.build(sigGen); if (!aCert.isValidOn(new Date())) { fail("certificate invalid"); } if (!aCert.isSignatureValid(new JcaContentVerifierProviderBuilder().setProvider(BC).build(pubKey))) { fail("certificate signature not valid"); } AttributeCertificateHolder holder = aCert.getHolder(); if (holder.getEntityNames() != null) { fail("entity names set when none expected"); } if (!holder.getSerialNumber().equals(iCert.getSerialNumber())) { fail("holder serial number doesn't match"); } if (!holder.getIssuer()[0].equals(new JcaX509CertificateHolder(iCert).getIssuer())) { fail("holder issuer doesn't match"); } if (!holder.match(new JcaX509CertificateHolder(iCert))) { fail("generated holder not matching holder certificate"); } Attribute[] attrs = aCert.getAttributes(new ASN1ObjectIdentifier("2.5.24.72")); if (attrs == null) { fail("attributes related to 2.5.24.72 not found"); } Attribute attr = attrs[0]; if (!attr.getAttrType().getId().equals("2.5.24.72")) { fail("attribute oid mismatch"); } ASN1Encodable[] values = attr.getAttrValues().toArray(); GeneralName role = GeneralNames.getInstance(values[0]).getNames()[0]; if (role.getTagNo() != GeneralName.rfc822Name) { fail("wrong general name type found in role"); } if (!((ASN1String)role.getName()).getString().equals("DAU123456789")) { fail("wrong general name value found in role"); } X509Certificate sCert = (X509Certificate)fact.generateCertificate(new ByteArrayInputStream(holderCertWithBaseCertificateID)); if (holder.match(new JcaX509CertificateHolder(sCert))) { fail("generated holder matching wrong certificate"); } equalityAndHashCodeTest(aCert, aCert.getEncoded()); } private void testGenerateWithPrincipal() throws Exception { CertificateFactory fact = CertificateFactory.getInstance("X.509","BC"); X509Certificate iCert = (X509Certificate)fact.generateCertificate(new ByteArrayInputStream(signCert)); // // a sample key pair. // RSAPublicKeySpec pubKeySpec = new RSAPublicKeySpec( new BigInteger("b4a7e46170574f16a97082b22be58b6a2a629798419be12872a4bdba626cfae9900f76abfb12139dce5de56564fab2b6543165a040c606887420e33d91ed7ed7", 16), new BigInteger("11", 16)); // // set up the keys // PrivateKey privKey; PublicKey pubKey; KeyFactory kFact = KeyFactory.getInstance("RSA", "BC"); privKey = kFact.generatePrivate(RSA_PRIVATE_KEY_SPEC); pubKey = kFact.generatePublic(pubKeySpec); X509v2AttributeCertificateBuilder gen = new X509v2AttributeCertificateBuilder( new AttributeCertificateHolder(new JcaX509CertificateHolder(iCert).getSubject()), new AttributeCertificateIssuer(new X500Name("cn=test")), BigInteger.valueOf(1), new Date(System.currentTimeMillis() - 50000), new Date(System.currentTimeMillis() + 50000)); // the actual attributes GeneralName roleName = new GeneralName(GeneralName.rfc822Name, "DAU123456789"); ASN1EncodableVector roleSyntax = new ASN1EncodableVector(); roleSyntax.add(roleName); // roleSyntax OID: 2.5.24.72 gen.addAttribute(new ASN1ObjectIdentifier("2.5.24.72"), new DERSequence(roleSyntax)); ContentSigner sigGen = new JcaContentSignerBuilder("SHA1WithRSAEncryption").setProvider(BC).build(privKey); X509AttributeCertificateHolder aCert = gen.build(sigGen); if (!aCert.isValidOn(new Date())) { fail("certificate invalid"); } if (!aCert.isSignatureValid(new JcaContentVerifierProviderBuilder().setProvider(BC).build(pubKey))) { fail("certificate signature not valid"); } AttributeCertificateHolder holder = aCert.getHolder(); if (holder.getEntityNames() == null) { fail("entity names not set when expected"); } if (holder.getSerialNumber() != null) { fail("holder serial number found when none expected"); } if (holder.getIssuer() != null) { fail("holder issuer found when none expected"); } if (!holder.match(new JcaX509CertificateHolder(iCert))) { fail("generated holder not matching holder certificate"); } X509Certificate sCert = (X509Certificate)fact.generateCertificate(new ByteArrayInputStream(holderCertWithBaseCertificateID)); if (holder.match(sCert)) { fail("principal generated holder matching wrong certificate"); } equalityAndHashCodeTest(aCert, aCert.getEncoded()); } public void performTest() throws Exception { X509AttributeCertificateHolder aCert = new X509AttributeCertificateHolder(attrCert); CertificateFactory fact = CertificateFactory.getInstance("X.509","BC"); X509Certificate sCert = (X509Certificate)fact.generateCertificate(new ByteArrayInputStream(signCert)); if (!aCert.isSignatureValid(new JcaContentVerifierProviderBuilder().setProvider(BC).build(sCert))) { fail("certificate signature not valid"); } // // search test // List list = new ArrayList(); list.add(sCert); Store store = new JcaCertStore(list); Collection certs = store.getMatches(aCert.getIssuer()); if (certs.size() != 1 || !certs.contains(new JcaX509CertificateHolder(sCert))) { fail("sCert not found by issuer"); } Attribute[] attrs = aCert.getAttributes(new ASN1ObjectIdentifier("1.3.6.1.4.1.6760.8.1.1")); if (attrs == null || attrs.length != 1) { fail("attribute not found"); } // // reencode test // aCert = new X509AttributeCertificateHolder(aCert.getEncoded()); if (!aCert.isSignatureValid(new JcaContentVerifierProviderBuilder().setProvider(BC).build(sCert))) { fail("certificate signature not valid"); } X509AttributeCertificateHolder saCert = new X509AttributeCertificateHolder(aCert.getEncoded()); if (!aCert.getNotAfter().equals(saCert.getNotAfter())) { fail("failed date comparison"); } // base generator test // // a sample key pair. // RSAPublicKeySpec pubKeySpec = new RSAPublicKeySpec( new BigInteger("b4a7e46170574f16a97082b22be58b6a2a629798419be12872a4bdba626cfae9900f76abfb12139dce5de56564fab2b6543165a040c606887420e33d91ed7ed7", 16), new BigInteger("11", 16)); RSAPrivateCrtKeySpec privKeySpec = RSA_PRIVATE_KEY_SPEC; // // set up the keys // PrivateKey privKey; PublicKey pubKey; KeyFactory kFact = KeyFactory.getInstance("RSA", "BC"); privKey = kFact.generatePrivate(privKeySpec); pubKey = kFact.generatePublic(pubKeySpec); X509v2AttributeCertificateBuilder gen = new X509v2AttributeCertificateBuilder( aCert.getHolder(), aCert.getIssuer(), aCert.getSerialNumber(), new Date(System.currentTimeMillis() - 50000), new Date(System.currentTimeMillis() + 50000)); gen.addAttribute(attrs[0].getAttrType(), attrs[0].getAttributeValues()); ContentSigner sigGen = new JcaContentSignerBuilder("SHA1WithRSAEncryption").setProvider(BC).build(privKey); aCert = gen.build(sigGen); if (!aCert.isValidOn(new Date())) { fail("certificate not valid"); } if (!aCert.isSignatureValid(new JcaContentVerifierProviderBuilder().setProvider(BC).build(pubKey))) { fail("signature not valid"); } // as the issuer is the same this should still work (even though it is not // technically correct certs = store.getMatches(aCert.getIssuer()); if (certs.size() != 1 || !certs.contains(new JcaX509CertificateHolder(sCert))) { fail("sCert not found by issuer"); } attrs = aCert.getAttributes(new ASN1ObjectIdentifier("1.3.6.1.4.1.6760.8.1.1")); if (attrs == null || attrs.length != 1) { fail("attribute not found"); } // // reencode test // aCert = new X509AttributeCertificateHolder(aCert.getEncoded()); if (!aCert.isSignatureValid(new JcaContentVerifierProviderBuilder().setProvider(BC).build(pubKey))) { fail("signature not valid"); } AttributeCertificateIssuer issuer = aCert.getIssuer(); X500Name[] principals = issuer.getNames(); // // test holder // AttributeCertificateHolder holder = aCert.getHolder(); if (holder.getEntityNames() == null) { fail("entity names not set"); } if (holder.getSerialNumber() != null) { fail("holder serial number set when none expected"); } if (holder.getIssuer() != null) { fail("holder issuer set when none expected"); } principals = holder.getEntityNames(); // X500Principal principal0 = new X500Principal(principals[0].getEncoded()); // if (!principal0.toString().equals("C=US, O=vt, OU=Class 2, OU=Virginia Tech User, CN=Markus Lorch (mlorch), EMAILADDRESS=mlorch@vt.edu")) // { // fail("principal[0] for entity names don't match"); // } // // extension test // if (aCert.hasExtensions()) { fail("hasExtensions true with no extensions"); } gen.addExtension(new ASN1ObjectIdentifier("1.1"), true, new DEROctetString(new byte[10])); gen.addExtension(new ASN1ObjectIdentifier("2.2"), false, new DEROctetString(new byte[20])); aCert = gen.build(new JcaContentSignerBuilder("SHA1withRSA").setProvider(BC).build(privKey)); Set exts = aCert.getCriticalExtensionOIDs(); if (exts.size() != 1 || !exts.contains(new ASN1ObjectIdentifier("1.1"))) { fail("critical extension test failed"); } exts = aCert.getNonCriticalExtensionOIDs(); if (exts.size() != 1 || !exts.contains(new ASN1ObjectIdentifier("2.2"))) { fail("non-critical extension test failed"); } if (aCert.getCriticalExtensionOIDs().isEmpty()) { fail("critical extensions not found"); } Extension ext = aCert.getExtension(new ASN1ObjectIdentifier("1.1")); ASN1Encodable extValue = ext.getParsedValue(); if (!extValue.equals(new DEROctetString(new byte[10]))) { fail("wrong extension value found for 1.1"); } testCertWithBaseCertificateID(); testGenerateWithCert(); testGenerateWithPrincipal(); } public static void main( String[] args) { Security.addProvider(new BouncyCastleProvider()); runTest(new AttrCertTest()); } } bouncycastle-1.49.orig/test/jdk1.3/org/bouncycastle/cert/test/ConverterTest.java0000644000175000017500000000452411726264471027271 0ustar ebourgebourgpackage org.bouncycastle.cert.test; import java.math.BigInteger; import org.bouncycastle.jce.cert.X509CertSelector; import junit.framework.Test; import junit.framework.TestCase; import junit.framework.TestSuite; import org.bouncycastle.asn1.DEROctetString; import org.bouncycastle.asn1.x500.X500Name; import org.bouncycastle.cert.selector.X509CertificateHolderSelector; import org.bouncycastle.cert.selector.jcajce.JcaSelectorConverter; import org.bouncycastle.cert.selector.jcajce.JcaX509CertSelectorConverter; import org.bouncycastle.util.Arrays; public class ConverterTest extends TestCase { public void testCertificateSelectorConversion() throws Exception { JcaX509CertSelectorConverter converter = new JcaX509CertSelectorConverter(); JcaSelectorConverter toSelector = new JcaSelectorConverter(); X509CertificateHolderSelector sid1 = new X509CertificateHolderSelector(new X500Name("CN=Test"), BigInteger.valueOf(1), new byte[20]); X509CertSelector conv = converter.getCertSelector(sid1); assertTrue(conv.getIssuerAsString().equals("CN=Test")); assertTrue(Arrays.areEqual(conv.getSubjectKeyIdentifier(), new DEROctetString(new byte[20]).getEncoded())); assertEquals(conv.getSerialNumber(), sid1.getSerialNumber()); X509CertificateHolderSelector sid2 = toSelector.getCertificateHolderSelector(conv); assertEquals(sid1, sid2); sid1 = new X509CertificateHolderSelector(new X500Name("CN=Test"), BigInteger.valueOf(1)); conv = converter.getCertSelector(sid1); assertTrue(conv.getIssuerAsString().equals("CN=Test")); assertNull(conv.getSubjectKeyIdentifier()); assertEquals(conv.getSerialNumber(), sid1.getSerialNumber()); sid2 = toSelector.getCertificateHolderSelector(conv); assertEquals(sid1, sid2); sid1 = new X509CertificateHolderSelector(new byte[20]); conv = converter.getCertSelector(sid1); assertNull(conv.getIssuerAsString()); assertTrue(Arrays.areEqual(conv.getSubjectKeyIdentifier(), new DEROctetString(new byte[20]).getEncoded())); assertNull(conv.getSerialNumber()); sid2 = toSelector.getCertificateHolderSelector(conv); assertEquals(sid1, sid2); } public static Test suite() { return new TestSuite(ConverterTest.class); } } bouncycastle-1.49.orig/test/jdk1.3/org/bouncycastle/cert/test/PKCS10Test.java0000644000175000017500000006223612132666221026216 0ustar ebourgebourgpackage org.bouncycastle.cert.test; import java.math.BigInteger; import java.security.KeyFactory; import java.security.KeyPair; import java.security.KeyPairGenerator; import java.security.PrivateKey; import java.security.PublicKey; import java.security.SecureRandom; import java.security.Security; import java.security.Signature; import java.security.spec.RSAPrivateCrtKeySpec; import java.security.spec.RSAPublicKeySpec; import java.util.Vector; import org.bouncycastle.asn1.DERObjectIdentifier; import org.bouncycastle.asn1.DEROctetString; import org.bouncycastle.asn1.cryptopro.CryptoProObjectIdentifiers; import org.bouncycastle.asn1.pkcs.Attribute; import org.bouncycastle.asn1.pkcs.PKCSObjectIdentifiers; import org.bouncycastle.asn1.x500.X500Name; import org.bouncycastle.asn1.x500.X500NameBuilder; import org.bouncycastle.asn1.x500.style.BCStyle; import org.bouncycastle.asn1.x509.BasicConstraints; import org.bouncycastle.asn1.x509.KeyUsage; import org.bouncycastle.asn1.x509.SubjectKeyIdentifier; import org.bouncycastle.asn1.x509.X509Extension; import org.bouncycastle.asn1.x509.X509Extensions; import org.bouncycastle.asn1.x9.X9ObjectIdentifiers; import org.bouncycastle.jce.ECGOST3410NamedCurveTable; import org.bouncycastle.jce.ECNamedCurveTable; import org.bouncycastle.jce.interfaces.ECPointEncoder; import org.bouncycastle.jce.provider.BouncyCastleProvider; import org.bouncycastle.jce.spec.ECNamedCurveParameterSpec; import org.bouncycastle.jce.spec.ECParameterSpec; import org.bouncycastle.jce.spec.ECPrivateKeySpec; import org.bouncycastle.jce.spec.ECPublicKeySpec; import org.bouncycastle.math.ec.ECCurve; import org.bouncycastle.operator.ContentSigner; import org.bouncycastle.operator.ContentVerifierProvider; import org.bouncycastle.operator.jcajce.JcaContentSignerBuilder; import org.bouncycastle.operator.jcajce.JcaContentVerifierProviderBuilder; import org.bouncycastle.pkcs.PKCS10CertificationRequest; import org.bouncycastle.pkcs.PKCS10CertificationRequestBuilder; import org.bouncycastle.pkcs.jcajce.JcaPKCS10CertificationRequest; import org.bouncycastle.pkcs.jcajce.JcaPKCS10CertificationRequestBuilder; import org.bouncycastle.util.Arrays; import org.bouncycastle.util.encoders.Base64; import org.bouncycastle.util.encoders.Hex; import org.bouncycastle.util.test.SimpleTest; import org.bouncycastle.x509.extension.SubjectKeyIdentifierStructure; /** **/ public class PKCS10Test extends SimpleTest { private static final String BC = BouncyCastleProvider.PROVIDER_NAME; private byte[] gost3410EC_A = Base64.decode( "MIIBOzCB6wIBADB/MQ0wCwYDVQQDEwR0ZXN0MRUwEwYDVQQKEwxEZW1vcyBDbyBMdGQxHjAcBgNV" +"BAsTFUNyeXB0b2dyYXBoeSBkaXZpc2lvbjEPMA0GA1UEBxMGTW9zY293MQswCQYDVQQGEwJydTEZ" +"MBcGCSqGSIb3DQEJARYKc2RiQGRvbC5ydTBjMBwGBiqFAwICEzASBgcqhQMCAiMBBgcqhQMCAh4B" +"A0MABEBYx0P2D7YuuZo5HgdIAUKAXcLBDZ+4LYFgbKjrfStVfH59lc40BQ2FZ7M703hLpXK8GiBQ" +"GEYpKaAuQZnMIpByoAAwCAYGKoUDAgIDA0EAgXMcTrhdOY2Er2tHOSAgnMezqrYxocZTWhxmW5Rl" +"JY6lbXH5rndCn4swFzXU+YhgAsJv1wQBaoZEWRl5WV4/nA=="); private byte[] gost3410EC_B = Base64.decode( "MIIBPTCB7QIBADCBgDENMAsGA1UEAxMEdGVzdDEWMBQGA1UEChMNRGVtb3MgQ28gTHRkLjEeMBwG" +"A1UECxMVQ3J5cHRvZ3JhcGh5IGRpdmlzaW9uMQ8wDQYDVQQHEwZNb3Njb3cxCzAJBgNVBAYTAnJ1" +"MRkwFwYJKoZIhvcNAQkBFgpzZGJAZG9sLnJ1MGMwHAYGKoUDAgITMBIGByqFAwICIwIGByqFAwIC" +"HgEDQwAEQI5SLoWT7dZVilbV9j5B/fyIDuDs6x4pjqNC2TtFYbpRHrk/Wc5g/mcHvD80tsm5o1C7" +"7cizNzkvAVUM4VT4Dz6gADAIBgYqhQMCAgMDQQAoT5TwJ8o+bSrxckymyo3diwG7ZbSytX4sRiKy" +"wXPWRS9LlBvPO2NqwpS2HUnxSU8rzfL9fJcybATf7Yt1OEVq"); private byte[] gost3410EC_C = Base64.decode( "MIIBRDCB9AIBADCBhzEVMBMGA1UEAxMMdGVzdCByZXF1ZXN0MRUwEwYDVQQKEwxEZW1vcyBDbyBM" +"dGQxHjAcBgNVBAsTFUNyeXB0b2dyYXBoeSBkaXZpc2lvbjEPMA0GA1UEBxMGTW9zY293MQswCQYD" +"VQQGEwJydTEZMBcGCSqGSIb3DQEJARYKc2RiQGRvbC5ydTBjMBwGBiqFAwICEzASBgcqhQMCAiMD" +"BgcqhQMCAh4BA0MABEBcmGh7OmR4iqqj+ycYo1S1fS7r5PhisSQU2Ezuz8wmmmR2zeTZkdMYCOBa" +"UTMNms0msW3wuYDho7nTDNscHTB5oAAwCAYGKoUDAgIDA0EAVoOMbfyo1Un4Ss7WQrUjHJoiaYW8" +"Ime5LeGGU2iW3ieAv6es/FdMrwTKkqn5dhd3aL/itFg5oQbhyfXw5yw/QQ=="); private byte[] gost3410EC_ExA = Base64.decode( "MIIBOzCB6wIBADB/MQ0wCwYDVQQDEwR0ZXN0MRUwEwYDVQQKEwxEZW1vcyBDbyBMdGQxHjAcBgNV" + "BAsTFUNyeXB0b2dyYXBoeSBkaXZpc2lvbjEPMA0GA1UEBxMGTW9zY293MQswCQYDVQQGEwJydTEZ" + "MBcGCSqGSIb3DQEJARYKc2RiQGRvbC5ydTBjMBwGBiqFAwICEzASBgcqhQMCAiQABgcqhQMCAh4B" + "A0MABEDkqNT/3f8NHj6EUiWnK4JbVZBh31bEpkwq9z3jf0u8ZndG56Vt+K1ZB6EpFxLT7hSIos0w" + "weZ2YuTZ4w43OgodoAAwCAYGKoUDAgIDA0EASk/IUXWxoi6NtcUGVF23VRV1L3undB4sRZLp4Vho" + "gQ7m3CMbZFfJ2cPu6QyarseXGYHmazoirH5lGjEo535c1g=="); private byte[] gost3410EC_ExB = Base64.decode( "MIIBPTCB7QIBADCBgDENMAsGA1UEAxMEdGVzdDEWMBQGA1UEChMNRGVtb3MgQ28gTHRkLjEeMBwG" + "A1UECxMVQ3J5cHRvZ3JhcGh5IGRpdmlzaW9uMQ8wDQYDVQQHEwZNb3Njb3cxCzAJBgNVBAYTAnJ1" + "MRkwFwYJKoZIhvcNAQkBFgpzZGJAZG9sLnJ1MGMwHAYGKoUDAgITMBIGByqFAwICJAEGByqFAwIC" + "HgEDQwAEQMBWYUKPy/1Kxad9ChAmgoSWSYOQxRnXo7KEGLU5RNSXA4qMUvArWzvhav+EYUfTbWLh" + "09nELDyHt2XQcvgQHnSgADAIBgYqhQMCAgMDQQAdaNhgH/ElHp64mbMaEo1tPCg9Q22McxpH8rCz" + "E0QBpF4H5mSSQVGI5OAXHToetnNuh7gHHSynyCupYDEHTbkZ"); public String getName() { return "PKCS10CertRequest"; } private void generationTest(int keySize, String keyName, String sigName, String provider) throws Exception { KeyPairGenerator kpg = KeyPairGenerator.getInstance(keyName, "BC"); kpg.initialize(keySize); KeyPair kp = kpg.generateKeyPair(); X500NameBuilder x500NameBld = new X500NameBuilder(BCStyle.INSTANCE); x500NameBld.addRDN(BCStyle.C, "AU"); x500NameBld.addRDN(BCStyle.O, "The Legion of the Bouncy Castle"); x500NameBld.addRDN(BCStyle.L, "Melbourne"); x500NameBld.addRDN(BCStyle.ST, "Victoria"); x500NameBld.addRDN(BCStyle.EmailAddress, "feedback-crypto@bouncycastle.org"); X500Name subject = x500NameBld.build(); PKCS10CertificationRequestBuilder requestBuilder = new JcaPKCS10CertificationRequestBuilder(subject, kp.getPublic()); PKCS10CertificationRequest req1 = requestBuilder.build(new JcaContentSignerBuilder(sigName).setProvider(provider).build(kp.getPrivate())); JcaPKCS10CertificationRequest req2 = new JcaPKCS10CertificationRequest(req1.getEncoded()).setProvider(provider); if (!req2.isSignatureValid(new JcaContentVerifierProviderBuilder().setProvider(provider).build(kp.getPublic()))) { fail(sigName + ": Failed verify check."); } if (!Arrays.areEqual(req2.getPublicKey().getEncoded(), req1.getSubjectPublicKeyInfo().getEncoded())) { fail(keyName + ": Failed public key check."); } } /* * we generate a self signed certificate for the sake of testing - SHA224withECDSA */ private void createECRequest(String algorithm, DERObjectIdentifier algOid, DERObjectIdentifier curveOid) throws Exception { ECNamedCurveParameterSpec spec = ECNamedCurveTable.getParameterSpec(curveOid.getId()); KeyPairGenerator ecGen = KeyPairGenerator.getInstance("ECDSA", "BC"); ecGen.initialize(spec); // // set up the keys // PrivateKey privKey; PublicKey pubKey; KeyPair pair = ecGen.generateKeyPair(); privKey = pair.getPrivate(); pubKey = pair.getPublic(); ContentSigner signer = new JcaContentSignerBuilder(algorithm).setProvider(BC).build(privKey); PKCS10CertificationRequestBuilder reqBuilder = new JcaPKCS10CertificationRequestBuilder(new X500Name("CN=XXX"), pubKey); PKCS10CertificationRequest req = reqBuilder.build(signer); ContentVerifierProvider verifier = new JcaContentVerifierProviderBuilder().setProvider(BC).build(pubKey); if (!req.isSignatureValid(verifier)) { fail("Failed verify check EC."); } req = new PKCS10CertificationRequest(req.getEncoded()); if (!req.isSignatureValid(verifier)) { fail("Failed verify check EC encoded."); } // // try with point compression turned off // ((ECPointEncoder)pubKey).setPointFormat("UNCOMPRESSED"); reqBuilder = new JcaPKCS10CertificationRequestBuilder(new X500Name("CN=XXX"), pubKey); req = reqBuilder.build(signer); if (!req.isSignatureValid(verifier)) { fail("Failed verify check EC uncompressed."); } req = new PKCS10CertificationRequest(req.getEncoded()); if (!req.isSignatureValid(verifier)) { fail("Failed verify check EC uncompressed encoded."); } if (!req.toASN1Structure().getSignatureAlgorithm().getAlgorithm().equals(algOid)) { fail("ECDSA oid incorrect."); } if (req.toASN1Structure().getSignatureAlgorithm().getParameters() != null) { fail("ECDSA parameters incorrect."); } Signature sig = Signature.getInstance(algorithm, "BC"); sig.initVerify(pubKey); sig.update(req.toASN1Structure().getCertificationRequestInfo().getEncoded()); if (!sig.verify(req.toASN1Structure().getSignature().getBytes())) { fail("signature not mapped correctly."); } } private void createECRequest(String algorithm, DERObjectIdentifier algOid) throws Exception { ECCurve.Fp curve = new ECCurve.Fp( new BigInteger("6864797660130609714981900799081393217269435300143305409394463459185543183397656052122559640661454554977296311391480858037121987999716643812574028291115057151"), // q (or p) new BigInteger("01FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFC", 16), // a new BigInteger("0051953EB9618E1C9A1F929A21A0B68540EEA2DA725B99B315F3B8B489918EF109E156193951EC7E937B1652C0BD3BB1BF073573DF883D2C34F1EF451FD46B503F00", 16)); // b ECParameterSpec spec = new ECParameterSpec( curve, curve.decodePoint(Hex.decode("0200C6858E06B70404E9CD9E3ECB662395B4429C648139053FB521F828AF606B4D3DBAA14B5E77EFE75928FE1DC127A2FFA8DE3348B3C1856A429BF97E7E31C2E5BD66")), // G new BigInteger("01FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFA51868783BF2F966B7FCC0148F709A5D03BB5C9B8899C47AEBB6FB71E91386409", 16)); // n ECPrivateKeySpec privKeySpec = new ECPrivateKeySpec( new BigInteger("5769183828869504557786041598510887460263120754767955773309066354712783118202294874205844512909370791582896372147797293913785865682804434049019366394746072023"), // d spec); ECPublicKeySpec pubKeySpec = new ECPublicKeySpec( curve.decodePoint(Hex.decode("02006BFDD2C9278B63C92D6624F151C9D7A822CC75BD983B17D25D74C26740380022D3D8FAF304781E416175EADF4ED6E2B47142D2454A7AC7801DD803CF44A4D1F0AC")), // Q spec); // // set up the keys // PrivateKey privKey; PublicKey pubKey; KeyFactory fact = KeyFactory.getInstance("ECDSA", "BC"); privKey = fact.generatePrivate(privKeySpec); pubKey = fact.generatePublic(pubKeySpec); PKCS10CertificationRequest req = new JcaPKCS10CertificationRequestBuilder( new X500Name("CN=XXX"), pubKey).build(new JcaContentSignerBuilder(algorithm).setProvider(BC).build(privKey)); if (!req.isSignatureValid(new JcaContentVerifierProviderBuilder().setProvider(BC).build(pubKey))) { fail("Failed verify check EC."); } req = new PKCS10CertificationRequest(req.getEncoded()); if (!req.isSignatureValid(new JcaContentVerifierProviderBuilder().setProvider(BC).build(pubKey))) { fail("Failed verify check EC encoded."); } // // try with point compression turned off // ((ECPointEncoder)pubKey).setPointFormat("UNCOMPRESSED"); req = new JcaPKCS10CertificationRequestBuilder( new X500Name("CN=XXX"), pubKey).build(new JcaContentSignerBuilder(algorithm).setProvider(BC).build(privKey)); if (!req.isSignatureValid(new JcaContentVerifierProviderBuilder().setProvider(BC).build(pubKey))) { fail("Failed verify check EC uncompressed."); } JcaPKCS10CertificationRequest jcaReq = new JcaPKCS10CertificationRequest(new PKCS10CertificationRequest(req.getEncoded())); if (!jcaReq.isSignatureValid(new JcaContentVerifierProviderBuilder().setProvider(BC).build(jcaReq.getPublicKey()))) { fail("Failed verify check EC uncompressed encoded."); } if (!jcaReq.getSignatureAlgorithm().getAlgorithm().equals(algOid)) { fail("ECDSA oid incorrect."); } if (jcaReq.getSignatureAlgorithm().getParameters() != null) { fail("ECDSA parameters incorrect."); } Signature sig = Signature.getInstance(algorithm, BC); sig.initVerify(pubKey); sig.update(req.toASN1Structure().getCertificationRequestInfo().getEncoded()); if (!sig.verify(req.getSignature())) { fail("signature not mapped correctly."); } } private void createECGOSTRequest() throws Exception { String algorithm = "GOST3411withECGOST3410"; KeyPairGenerator ecGostKpg = KeyPairGenerator.getInstance("ECGOST3410", "BC"); ecGostKpg.initialize(ECGOST3410NamedCurveTable.getParameterSpec("GostR3410-2001-CryptoPro-A"), new SecureRandom()); // // set up the keys // KeyPair pair = ecGostKpg.generateKeyPair(); PrivateKey privKey = pair.getPrivate(); PublicKey pubKey = pair.getPublic(); PKCS10CertificationRequest req = new JcaPKCS10CertificationRequestBuilder( new X500Name("CN=XXX"), pubKey).build(new JcaContentSignerBuilder(algorithm).setProvider(BC).build(privKey)); if (!req.isSignatureValid(new JcaContentVerifierProviderBuilder().setProvider(BC).build(pubKey))) { fail("Failed verify check EC."); } req = new PKCS10CertificationRequest(req.getEncoded()); if (!req.isSignatureValid(new JcaContentVerifierProviderBuilder().setProvider(BC).build(pubKey))) { fail("Failed verify check EC encoded."); } if (!req.getSignatureAlgorithm().getAlgorithm().equals(CryptoProObjectIdentifiers.gostR3411_94_with_gostR3410_2001)) { fail("ECGOST oid incorrect."); } if (req.getSignatureAlgorithm().getParameters() != null) { fail("ECGOST parameters incorrect."); } Signature sig = Signature.getInstance(algorithm, "BC"); sig.initVerify(pubKey); sig.update(req.toASN1Structure().getCertificationRequestInfo().getEncoded()); if (!sig.verify(req.getSignature())) { fail("signature not mapped correctly."); } } private void createPSSTest(String algorithm) throws Exception { RSAPublicKeySpec pubKeySpec = new RSAPublicKeySpec( new BigInteger("a56e4a0e701017589a5187dc7ea841d156f2ec0e36ad52a44dfeb1e61f7ad991d8c51056ffedb162b4c0f283a12a88a394dff526ab7291cbb307ceabfce0b1dfd5cd9508096d5b2b8b6df5d671ef6377c0921cb23c270a70e2598e6ff89d19f105acc2d3f0cb35f29280e1386b6f64c4ef22e1e1f20d0ce8cffb2249bd9a2137",16), new BigInteger("010001",16)); RSAPrivateCrtKeySpec privKeySpec = new RSAPrivateCrtKeySpec( new BigInteger("a56e4a0e701017589a5187dc7ea841d156f2ec0e36ad52a44dfeb1e61f7ad991d8c51056ffedb162b4c0f283a12a88a394dff526ab7291cbb307ceabfce0b1dfd5cd9508096d5b2b8b6df5d671ef6377c0921cb23c270a70e2598e6ff89d19f105acc2d3f0cb35f29280e1386b6f64c4ef22e1e1f20d0ce8cffb2249bd9a2137",16), new BigInteger("010001",16), new BigInteger("33a5042a90b27d4f5451ca9bbbd0b44771a101af884340aef9885f2a4bbe92e894a724ac3c568c8f97853ad07c0266c8c6a3ca0929f1e8f11231884429fc4d9ae55fee896a10ce707c3ed7e734e44727a39574501a532683109c2abacaba283c31b4bd2f53c3ee37e352cee34f9e503bd80c0622ad79c6dcee883547c6a3b325",16), new BigInteger("e7e8942720a877517273a356053ea2a1bc0c94aa72d55c6e86296b2dfc967948c0a72cbccca7eacb35706e09a1df55a1535bd9b3cc34160b3b6dcd3eda8e6443",16), new BigInteger("b69dca1cf7d4d7ec81e75b90fcca874abcde123fd2700180aa90479b6e48de8d67ed24f9f19d85ba275874f542cd20dc723e6963364a1f9425452b269a6799fd",16), new BigInteger("28fa13938655be1f8a159cbaca5a72ea190c30089e19cd274a556f36c4f6e19f554b34c077790427bbdd8dd3ede2448328f385d81b30e8e43b2fffa027861979",16), new BigInteger("1a8b38f398fa712049898d7fb79ee0a77668791299cdfa09efc0e507acb21ed74301ef5bfd48be455eaeb6e1678255827580a8e4e8e14151d1510a82a3f2e729",16), new BigInteger("27156aba4126d24a81f3a528cbfb27f56886f840a9f6e86e17a44b94fe9319584b8e22fdde1e5a2e3bd8aa5ba8d8584194eb2190acf832b847f13a3d24a79f4d",16)); KeyFactory fact = KeyFactory.getInstance("RSA", "BC"); PrivateKey privKey = fact.generatePrivate(privKeySpec); PublicKey pubKey = fact.generatePublic(pubKeySpec); PKCS10CertificationRequest req = new JcaPKCS10CertificationRequestBuilder( new X500Name("CN=XXX"), pubKey).build(new JcaContentSignerBuilder(algorithm).setProvider(BC).build(privKey)); if (!req.isSignatureValid(new JcaContentVerifierProviderBuilder().setProvider(BC).build(pubKey))) { fail("Failed verify check PSS."); } JcaPKCS10CertificationRequest jcaReq = new JcaPKCS10CertificationRequest(req.getEncoded()).setProvider(BC); if (!jcaReq.isSignatureValid(new JcaContentVerifierProviderBuilder().setProvider(BC).build(jcaReq.getPublicKey()))) { fail("Failed verify check PSS encoded."); } if (!jcaReq.getSignatureAlgorithm().getAlgorithm().equals(PKCSObjectIdentifiers.id_RSASSA_PSS)) { fail("PSS oid incorrect."); } if (jcaReq.getSignatureAlgorithm().getParameters() == null) { fail("PSS parameters incorrect."); } Signature sig = Signature.getInstance(algorithm, "BC"); sig.initVerify(pubKey); sig.update(jcaReq.toASN1Structure().getCertificationRequestInfo().getEncoded()); if (!sig.verify(req.getSignature())) { fail("signature not mapped correctly."); } } // previous code found to cause a NullPointerException private void nullPointerTest() throws Exception { KeyPairGenerator keyGen = KeyPairGenerator.getInstance("RSA", "BC"); keyGen.initialize(1024, new SecureRandom()); KeyPair pair = keyGen.generateKeyPair(); Vector oids = new Vector(); Vector values = new Vector(); oids.addElement(X509Extension.basicConstraints); values.addElement(new X509Extension(true, new DEROctetString(new BasicConstraints(true)))); oids.addElement(X509Extension.keyUsage); values.addElement(new X509Extension(true, new DEROctetString( new KeyUsage(KeyUsage.keyCertSign | KeyUsage.cRLSign)))); SubjectKeyIdentifier subjectKeyIdentifier = new SubjectKeyIdentifierStructure(pair.getPublic()); X509Extension ski = new X509Extension(false, new DEROctetString(subjectKeyIdentifier)); oids.addElement(X509Extension.subjectKeyIdentifier); values.addElement(ski); PKCS10CertificationRequest p1 = new JcaPKCS10CertificationRequestBuilder( new X500Name("cn=csr"), pair.getPublic()) .addAttribute(PKCSObjectIdentifiers.pkcs_9_at_extensionRequest, new X509Extensions(oids, values)) .build(new JcaContentSignerBuilder("SHA1withRSA").setProvider(BC).build(pair.getPrivate())); PKCS10CertificationRequest p2 = new JcaPKCS10CertificationRequestBuilder( new X500Name("cn=csr"), pair.getPublic()) .addAttribute(PKCSObjectIdentifiers.pkcs_9_at_extensionRequest, new X509Extensions(oids, values)) .build(new JcaContentSignerBuilder("SHA1withRSA").setProvider(BC).build(pair.getPrivate())); if (!p1.equals(p2)) { fail("cert request comparison failed"); } Attribute[] attr1 = p1.getAttributes(); Attribute[] attr2 = p1.getAttributes(); checkAttrs(1, attr1, attr2); attr1 = p1.getAttributes(PKCSObjectIdentifiers.pkcs_9_at_extensionRequest); attr2 = p1.getAttributes(PKCSObjectIdentifiers.pkcs_9_at_extensionRequest); checkAttrs(1, attr1, attr2); } private void checkAttrs(int expectedLength, Attribute[] attr1, Attribute[] attr2) { if (expectedLength != attr1.length) { fail("expected length mismatch"); } if (attr1.length != attr2.length) { fail("atrribute length mismatch"); } for (int i = 0; i != attr1.length; i++) { if (!attr1[i].equals(attr2[i])) { fail("atrribute mismatch"); } } } public void performTest() throws Exception { generationTest(512, "RSA", "SHA1withRSA", "BC"); generationTest(512, "GOST3410", "GOST3411withGOST3410", "BC"); if (Security.getProvider("SunRsaSign") != null) { generationTest(512, "RSA", "SHA1withRSA", "SunRsaSign"); } // elliptic curve GOST A parameter set JcaPKCS10CertificationRequest req = new JcaPKCS10CertificationRequest(gost3410EC_A).setProvider(BC); if (!req.isSignatureValid(new JcaContentVerifierProviderBuilder().setProvider(BC).build(req.getPublicKey()))) { fail("Failed verify check gost3410EC_A."); } // elliptic curve GOST B parameter set req = new JcaPKCS10CertificationRequest(gost3410EC_B).setProvider(BC); if (!req.isSignatureValid(new JcaContentVerifierProviderBuilder().setProvider(BC).build(req.getPublicKey()))) { fail("Failed verify check gost3410EC_B."); } // elliptic curve GOST C parameter set req = new JcaPKCS10CertificationRequest(gost3410EC_C).setProvider(BC); if (!req.isSignatureValid(new JcaContentVerifierProviderBuilder().setProvider(BC).build(req.getPublicKey()))) { fail("Failed verify check gost3410EC_C."); } // elliptic curve GOST ExA parameter set req = new JcaPKCS10CertificationRequest(gost3410EC_ExA).setProvider(BC); if (!req.isSignatureValid(new JcaContentVerifierProviderBuilder().setProvider(BC).build(req.getPublicKey()))) { fail("Failed verify check gost3410EC_ExA."); } // elliptic curve GOST ExB parameter set req = new JcaPKCS10CertificationRequest(gost3410EC_ExB).setProvider(BC); if (!req.isSignatureValid(new JcaContentVerifierProviderBuilder().setProvider(BC).build(req.getPublicKey()))) { fail("Failed verify check gost3410EC_ExA."); } // elliptic curve openSSL KeyPairGenerator g = KeyPairGenerator.getInstance("ECDSA", "BC"); ECCurve curve = new ECCurve.Fp( new BigInteger("883423532389192164791648750360308885314476597252960362792450860609699839"), // q new BigInteger("7fffffffffffffffffffffff7fffffffffff8000000000007ffffffffffc", 16), // a new BigInteger("6b016c3bdcf18941d0d654921475ca71a9db2fb27d1d37796185c2942c0a", 16)); // b ECParameterSpec ecSpec = new ECParameterSpec( curve, curve.decodePoint(Hex.decode("020ffa963cdca8816ccc33b8642bedf905c3d358573d3f27fbbd3b3cb9aaaf")), // G new BigInteger("883423532389192164791648750360308884807550341691627752275345424702807307")); // n g.initialize(ecSpec, new SecureRandom()); KeyPair kp = g.generateKeyPair(); req = new JcaPKCS10CertificationRequest(new JcaPKCS10CertificationRequestBuilder( new X500Name("CN=XXX"), kp.getPublic()).build(new JcaContentSignerBuilder( "ECDSAWITHSHA1").setProvider(BC).build(kp.getPrivate()))); if (!req.isSignatureValid(new JcaContentVerifierProviderBuilder().setProvider(BC).build(req.getPublicKey()))) { fail("Failed verify check EC."); } createECRequest("SHA1withECDSA", X9ObjectIdentifiers.ecdsa_with_SHA1); createECRequest("SHA224withECDSA", X9ObjectIdentifiers.ecdsa_with_SHA224); createECRequest("SHA256withECDSA", X9ObjectIdentifiers.ecdsa_with_SHA256); createECRequest("SHA384withECDSA", X9ObjectIdentifiers.ecdsa_with_SHA384); createECRequest("SHA512withECDSA", X9ObjectIdentifiers.ecdsa_with_SHA512); createECRequest("SHA1withECDSA", X9ObjectIdentifiers.ecdsa_with_SHA1, new DERObjectIdentifier("1.3.132.0.34")); createECGOSTRequest(); createPSSTest("SHA1withRSAandMGF1"); createPSSTest("SHA224withRSAandMGF1"); createPSSTest("SHA256withRSAandMGF1"); createPSSTest("SHA384withRSAandMGF1"); nullPointerTest(); } public static void main( String[] args) { Security.addProvider(new BouncyCastleProvider()); runTest(new PKCS10Test()); } } bouncycastle-1.49.orig/test/jdk1.3/org/bouncycastle/cert/test/AllTests.java0000644000175000017500000000314712104157573026210 0ustar ebourgebourgpackage org.bouncycastle.cert.test; import java.security.Security; import junit.framework.Test; import junit.framework.TestCase; import junit.framework.TestSuite; import org.bouncycastle.jce.provider.BouncyCastleProvider; import org.bouncycastle.util.test.SimpleTestResult; public class AllTests extends TestCase { public void testSimpleTests() { org.bouncycastle.util.test.Test[] tests = new org.bouncycastle.util.test.Test[] { new CertTest(), new PKCS10Test(), new AttrCertSelectorTest(), new AttrCertTest(), new X509ExtensionUtilsTest() }; for (int i = 0; i != tests.length; i++) { SimpleTestResult result = (SimpleTestResult)tests[i].perform(); if (!result.isSuccessful()) { if (result.getException() != null) { result.getException().printStackTrace(); } fail(result.toString()); } } } public static void main (String[] args) { junit.textui.TestRunner.run(suite()); } public static Test suite() { TestSuite suite = new TestSuite("Cert Tests"); if (Security.getProvider("BC") == null) { Security.addProvider(new BouncyCastleProvider()); } suite.addTestSuite(AllTests.class); suite.addTestSuite(BcAttrCertSelectorTest.class); suite.addTestSuite(BcAttrCertSelectorTest.class); suite.addTestSuite(BcAttrCertTest.class); suite.addTestSuite(BcPKCS10Test.class); suite.addTest(ConverterTest.suite()); return suite; } } bouncycastle-1.49.orig/test/jdk1.3/org/bouncycastle/cert/test/CertTest.java0000644000175000017500000043300612132666221026207 0ustar ebourgebourgpackage org.bouncycastle.cert.test; import java.io.ByteArrayInputStream; import java.io.IOException; import java.io.UnsupportedEncodingException; import java.math.BigInteger; import java.security.KeyFactory; import java.security.KeyPair; import java.security.KeyPairGenerator; import java.security.KeyStore; import java.security.NoSuchAlgorithmException; import java.security.NoSuchProviderException; import java.security.PrivateKey; import java.security.PublicKey; import java.security.SecureRandom; import java.security.Security; import java.security.Signature; import java.security.cert.CRL; import java.security.cert.Certificate; import java.security.cert.CertificateException; import java.security.cert.CertificateFactory; import java.security.cert.X509CRL; import java.security.cert.X509CRLEntry; import java.security.cert.X509Certificate; import java.security.spec.InvalidKeySpecException; import java.security.spec.RSAPrivateCrtKeySpec; import java.security.spec.RSAPublicKeySpec; import java.util.Collection; import java.util.Date; import java.util.Iterator; import java.util.Set; import java.util.Vector; import org.bouncycastle.asn1.ASN1Encodable; import org.bouncycastle.asn1.ASN1EncodableVector; import org.bouncycastle.asn1.ASN1Enumerated; import org.bouncycastle.asn1.ASN1ObjectIdentifier; import org.bouncycastle.asn1.ASN1Primitive; import org.bouncycastle.asn1.DEREnumerated; import org.bouncycastle.asn1.DERNull; import org.bouncycastle.asn1.DERObjectIdentifier; import org.bouncycastle.asn1.DEROctetString; import org.bouncycastle.asn1.DERSequence; import org.bouncycastle.asn1.pkcs.PKCSObjectIdentifiers; import org.bouncycastle.asn1.pkcs.RSAPublicKey; import org.bouncycastle.asn1.x500.X500Name; import org.bouncycastle.asn1.x500.X500NameBuilder; import org.bouncycastle.asn1.x500.style.BCStyle; import org.bouncycastle.asn1.x509.AlgorithmIdentifier; import org.bouncycastle.asn1.x509.AuthorityKeyIdentifier; import org.bouncycastle.asn1.x509.CRLReason; import org.bouncycastle.asn1.x509.Extension; import org.bouncycastle.asn1.x509.ExtensionsGenerator; import org.bouncycastle.asn1.x509.GeneralName; import org.bouncycastle.asn1.x509.GeneralNames; import org.bouncycastle.asn1.x509.IssuingDistributionPoint; import org.bouncycastle.asn1.x509.KeyPurposeId; import org.bouncycastle.asn1.x509.SubjectPublicKeyInfo; import org.bouncycastle.asn1.x509.X509CertificateStructure; import org.bouncycastle.asn1.x509.X509Extension; import org.bouncycastle.asn1.x509.X509Extensions; import org.bouncycastle.asn1.x9.X9ObjectIdentifiers; import org.bouncycastle.cert.X509CRLEntryHolder; import org.bouncycastle.cert.X509CRLHolder; import org.bouncycastle.cert.X509CertificateHolder; import org.bouncycastle.cert.X509v1CertificateBuilder; import org.bouncycastle.cert.X509v2CRLBuilder; import org.bouncycastle.cert.X509v3CertificateBuilder; import org.bouncycastle.cert.jcajce.JcaX509CRLConverter; import org.bouncycastle.cert.jcajce.JcaX509CRLHolder; import org.bouncycastle.cert.jcajce.JcaX509CertificateConverter; import org.bouncycastle.cert.jcajce.JcaX509CertificateHolder; import org.bouncycastle.cert.jcajce.JcaX509v1CertificateBuilder; import org.bouncycastle.cert.jcajce.JcaX509v2CRLBuilder; import org.bouncycastle.cert.jcajce.JcaX509v3CertificateBuilder; import org.bouncycastle.crypto.params.RSAKeyParameters; import org.bouncycastle.crypto.params.RSAPrivateCrtKeyParameters; import org.bouncycastle.jce.PrincipalUtil; import org.bouncycastle.jce.X509KeyUsage; import org.bouncycastle.jce.X509Principal; import org.bouncycastle.jce.interfaces.ECPointEncoder; import org.bouncycastle.jce.provider.BouncyCastleProvider; import org.bouncycastle.jce.spec.ECParameterSpec; import org.bouncycastle.jce.spec.ECPrivateKeySpec; import org.bouncycastle.jce.spec.ECPublicKeySpec; import org.bouncycastle.jce.spec.GOST3410ParameterSpec; import org.bouncycastle.math.ec.ECCurve; import org.bouncycastle.operator.ContentSigner; import org.bouncycastle.operator.ContentVerifierProvider; import org.bouncycastle.operator.DefaultDigestAlgorithmIdentifierFinder; import org.bouncycastle.operator.DefaultSignatureAlgorithmIdentifierFinder; import org.bouncycastle.operator.bc.BcRSAContentSignerBuilder; import org.bouncycastle.operator.bc.BcRSAContentVerifierProviderBuilder; import org.bouncycastle.operator.jcajce.JcaContentSignerBuilder; import org.bouncycastle.operator.jcajce.JcaContentVerifierProviderBuilder; import org.bouncycastle.util.encoders.Base64; import org.bouncycastle.util.encoders.Hex; import org.bouncycastle.util.test.SimpleTest; import org.bouncycastle.x509.extension.AuthorityKeyIdentifierStructure; import org.bouncycastle.x509.extension.X509ExtensionUtil; public class CertTest extends SimpleTest { private static final String BC = org.bouncycastle.jce.provider.BouncyCastleProvider.PROVIDER_NAME; // test CA byte[] testCAp12 = Base64.decode( "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" + "HLhcYQcQ1R+RucctAgIEAAAA"); // // server.crt // byte[] cert1 = Base64.decode( "MIIDXjCCAsegAwIBAgIBBzANBgkqhkiG9w0BAQQFADCBtzELMAkGA1UEBhMCQVUx" + "ETAPBgNVBAgTCFZpY3RvcmlhMRgwFgYDVQQHEw9Tb3V0aCBNZWxib3VybmUxGjAY" + "BgNVBAoTEUNvbm5lY3QgNCBQdHkgTHRkMR4wHAYDVQQLExVDZXJ0aWZpY2F0ZSBB" + "dXRob3JpdHkxFTATBgNVBAMTDENvbm5lY3QgNCBDQTEoMCYGCSqGSIb3DQEJARYZ" + "d2VibWFzdGVyQGNvbm5lY3Q0LmNvbS5hdTAeFw0wMDA2MDIwNzU2MjFaFw0wMTA2" + "MDIwNzU2MjFaMIG4MQswCQYDVQQGEwJBVTERMA8GA1UECBMIVmljdG9yaWExGDAW" + "BgNVBAcTD1NvdXRoIE1lbGJvdXJuZTEaMBgGA1UEChMRQ29ubmVjdCA0IFB0eSBM" + "dGQxFzAVBgNVBAsTDldlYnNlcnZlciBUZWFtMR0wGwYDVQQDExR3d3cyLmNvbm5l" + "Y3Q0LmNvbS5hdTEoMCYGCSqGSIb3DQEJARYZd2VibWFzdGVyQGNvbm5lY3Q0LmNv" + "bS5hdTCBnzANBgkqhkiG9w0BAQEFAAOBjQAwgYkCgYEArvDxclKAhyv7Q/Wmr2re" + "Gw4XL9Cnh9e+6VgWy2AWNy/MVeXdlxzd7QAuc1eOWQkGQEiLPy5XQtTY+sBUJ3AO" + "Rvd2fEVJIcjf29ey7bYua9J/vz5MG2KYo9/WCHIwqD9mmG9g0xLcfwq/s8ZJBswE" + "7sb85VU+h94PTvsWOsWuKaECAwEAAaN3MHUwJAYDVR0RBB0wG4EZd2VibWFzdGVy" + "QGNvbm5lY3Q0LmNvbS5hdTA6BglghkgBhvhCAQ0ELRYrbW9kX3NzbCBnZW5lcmF0" + "ZWQgY3VzdG9tIHNlcnZlciBjZXJ0aWZpY2F0ZTARBglghkgBhvhCAQEEBAMCBkAw" + "DQYJKoZIhvcNAQEEBQADgYEAotccfKpwSsIxM1Hae8DR7M/Rw8dg/RqOWx45HNVL" + "iBS4/3N/TO195yeQKbfmzbAA2jbPVvIvGgTxPgO1MP4ZgvgRhasaa0qCJCkWvpM4" + "yQf33vOiYQbpv4rTwzU8AmRlBG45WdjyNIigGV+oRc61aKCTnLq7zB8N3z1TF/bF" + "5/8="); // // ca.crt // byte[] cert2 = Base64.decode( "MIIDbDCCAtWgAwIBAgIBADANBgkqhkiG9w0BAQQFADCBtzELMAkGA1UEBhMCQVUx" + "ETAPBgNVBAgTCFZpY3RvcmlhMRgwFgYDVQQHEw9Tb3V0aCBNZWxib3VybmUxGjAY" + "BgNVBAoTEUNvbm5lY3QgNCBQdHkgTHRkMR4wHAYDVQQLExVDZXJ0aWZpY2F0ZSBB" + "dXRob3JpdHkxFTATBgNVBAMTDENvbm5lY3QgNCBDQTEoMCYGCSqGSIb3DQEJARYZ" + "d2VibWFzdGVyQGNvbm5lY3Q0LmNvbS5hdTAeFw0wMDA2MDIwNzU1MzNaFw0wMTA2" + "MDIwNzU1MzNaMIG3MQswCQYDVQQGEwJBVTERMA8GA1UECBMIVmljdG9yaWExGDAW" + "BgNVBAcTD1NvdXRoIE1lbGJvdXJuZTEaMBgGA1UEChMRQ29ubmVjdCA0IFB0eSBM" + "dGQxHjAcBgNVBAsTFUNlcnRpZmljYXRlIEF1dGhvcml0eTEVMBMGA1UEAxMMQ29u" + "bmVjdCA0IENBMSgwJgYJKoZIhvcNAQkBFhl3ZWJtYXN0ZXJAY29ubmVjdDQuY29t" + "LmF1MIGfMA0GCSqGSIb3DQEBAQUAA4GNADCBiQKBgQDgs5ptNG6Qv1ZpCDuUNGmv" + "rhjqMDPd3ri8JzZNRiiFlBA4e6/ReaO1U8ASewDeQMH6i9R6degFdQRLngbuJP0s" + "xcEE+SksEWNvygfzLwV9J/q+TQDyJYK52utb++lS0b48A1KPLwEsyL6kOAgelbur" + "ukwxowprKUIV7Knf1ajetQIDAQABo4GFMIGCMCQGA1UdEQQdMBuBGXdlYm1hc3Rl" + "ckBjb25uZWN0NC5jb20uYXUwDwYDVR0TBAgwBgEB/wIBADA2BglghkgBhvhCAQ0E" + "KRYnbW9kX3NzbCBnZW5lcmF0ZWQgY3VzdG9tIENBIGNlcnRpZmljYXRlMBEGCWCG" + "SAGG+EIBAQQEAwICBDANBgkqhkiG9w0BAQQFAAOBgQCsGvfdghH8pPhlwm1r3pQk" + "msnLAVIBb01EhbXm2861iXZfWqGQjrGAaA0ZpXNk9oo110yxoqEoSJSzniZa7Xtz" + "soTwNUpE0SLHvWf/SlKdFWlzXA+vOZbzEv4UmjeelekTm7lc01EEa5QRVzOxHFtQ" + "DhkaJ8VqOMajkQFma2r9iA=="); // // testx509.pem // byte[] cert3 = Base64.decode( "MIIBWzCCAQYCARgwDQYJKoZIhvcNAQEEBQAwODELMAkGA1UEBhMCQVUxDDAKBgNV" + "BAgTA1FMRDEbMBkGA1UEAxMSU1NMZWF5L3JzYSB0ZXN0IENBMB4XDTk1MDYxOTIz" + "MzMxMloXDTk1MDcxNzIzMzMxMlowOjELMAkGA1UEBhMCQVUxDDAKBgNVBAgTA1FM" + "RDEdMBsGA1UEAxMUU1NMZWF5L3JzYSB0ZXN0IGNlcnQwXDANBgkqhkiG9w0BAQEF" + "AANLADBIAkEAqtt6qS5GTxVxGZYWa0/4u+IwHf7p2LNZbcPBp9/OfIcYAXBQn8hO" + "/Re1uwLKXdCjIoaGs4DLdG88rkzfyK5dPQIDAQABMAwGCCqGSIb3DQIFBQADQQAE" + "Wc7EcF8po2/ZO6kNCwK/ICH6DobgLekA5lSLr5EvuioZniZp5lFzAw4+YzPQ7XKJ" + "zl9HYIMxATFyqSiD9jsx"); // // v3-cert1.pem // byte[] cert4 = Base64.decode( "MIICjTCCAfigAwIBAgIEMaYgRzALBgkqhkiG9w0BAQQwRTELMAkGA1UEBhMCVVMx" + "NjA0BgNVBAoTLU5hdGlvbmFsIEFlcm9uYXV0aWNzIGFuZCBTcGFjZSBBZG1pbmlz" + "dHJhdGlvbjAmFxE5NjA1MjgxMzQ5MDUrMDgwMBcROTgwNTI4MTM0OTA1KzA4MDAw" + "ZzELMAkGA1UEBhMCVVMxNjA0BgNVBAoTLU5hdGlvbmFsIEFlcm9uYXV0aWNzIGFu" + "ZCBTcGFjZSBBZG1pbmlzdHJhdGlvbjEgMAkGA1UEBRMCMTYwEwYDVQQDEwxTdGV2" + "ZSBTY2hvY2gwWDALBgkqhkiG9w0BAQEDSQAwRgJBALrAwyYdgxmzNP/ts0Uyf6Bp" + "miJYktU/w4NG67ULaN4B5CnEz7k57s9o3YY3LecETgQ5iQHmkwlYDTL2fTgVfw0C" + "AQOjgaswgagwZAYDVR0ZAQH/BFowWDBWMFQxCzAJBgNVBAYTAlVTMTYwNAYDVQQK" + "Ey1OYXRpb25hbCBBZXJvbmF1dGljcyBhbmQgU3BhY2UgQWRtaW5pc3RyYXRpb24x" + "DTALBgNVBAMTBENSTDEwFwYDVR0BAQH/BA0wC4AJODMyOTcwODEwMBgGA1UdAgQR" + "MA8ECTgzMjk3MDgyM4ACBSAwDQYDVR0KBAYwBAMCBkAwCwYJKoZIhvcNAQEEA4GB" + "AH2y1VCEw/A4zaXzSYZJTTUi3uawbbFiS2yxHvgf28+8Js0OHXk1H1w2d6qOHH21" + "X82tZXd/0JtG0g1T9usFFBDvYK8O0ebgz/P5ELJnBL2+atObEuJy1ZZ0pBDWINR3" + "WkDNLCGiTkCKp0F5EWIrVDwh54NNevkCQRZita+z4IBO"); // // v3-cert2.pem // byte[] cert5 = Base64.decode( "MIICiTCCAfKgAwIBAgIEMeZfHzANBgkqhkiG9w0BAQQFADB9MQswCQYDVQQGEwJD" + "YTEPMA0GA1UEBxMGTmVwZWFuMR4wHAYDVQQLExVObyBMaWFiaWxpdHkgQWNjZXB0" + "ZWQxHzAdBgNVBAoTFkZvciBEZW1vIFB1cnBvc2VzIE9ubHkxHDAaBgNVBAMTE0Vu" + "dHJ1c3QgRGVtbyBXZWIgQ0EwHhcNOTYwNzEyMTQyMDE1WhcNOTYxMDEyMTQyMDE1" + "WjB0MSQwIgYJKoZIhvcNAQkBExVjb29rZUBpc3NsLmF0bC5ocC5jb20xCzAJBgNV" + "BAYTAlVTMScwJQYDVQQLEx5IZXdsZXR0IFBhY2thcmQgQ29tcGFueSAoSVNTTCkx" + "FjAUBgNVBAMTDVBhdWwgQS4gQ29va2UwXDANBgkqhkiG9w0BAQEFAANLADBIAkEA" + "6ceSq9a9AU6g+zBwaL/yVmW1/9EE8s5you1mgjHnj0wAILuoB3L6rm6jmFRy7QZT" + "G43IhVZdDua4e+5/n1ZslwIDAQABo2MwYTARBglghkgBhvhCAQEEBAMCB4AwTAYJ" + "YIZIAYb4QgENBD8WPVRoaXMgY2VydGlmaWNhdGUgaXMgb25seSBpbnRlbmRlZCBm" + "b3IgZGVtb25zdHJhdGlvbiBwdXJwb3Nlcy4wDQYJKoZIhvcNAQEEBQADgYEAi8qc" + "F3zfFqy1sV8NhjwLVwOKuSfhR/Z8mbIEUeSTlnH3QbYt3HWZQ+vXI8mvtZoBc2Fz" + "lexKeIkAZXCesqGbs6z6nCt16P6tmdfbZF3I3AWzLquPcOXjPf4HgstkyvVBn0Ap" + "jAFN418KF/Cx4qyHB4cjdvLrRjjQLnb2+ibo7QU="); // // pem encoded pkcs7 // byte[] cert6 = Base64.decode( "MIAGCSqGSIb3DQEHAqCAMIACAQExCzAJBgUrDgMCGgUAMIAGCSqGSIb3DQEHAQAAoIIJbzCCAj0w" + "ggGmAhEAzbp/VvDf5LxU/iKss3KqVTANBgkqhkiG9w0BAQIFADBfMQswCQYDVQQGEwJVUzEXMBUG" + "A1UEChMOVmVyaVNpZ24sIEluYy4xNzA1BgNVBAsTLkNsYXNzIDEgUHVibGljIFByaW1hcnkgQ2Vy" + "dGlmaWNhdGlvbiBBdXRob3JpdHkwHhcNOTYwMTI5MDAwMDAwWhcNMjgwODAxMjM1OTU5WjBfMQsw" + "CQYDVQQGEwJVUzEXMBUGA1UEChMOVmVyaVNpZ24sIEluYy4xNzA1BgNVBAsTLkNsYXNzIDEgUHVi" + "bGljIFByaW1hcnkgQ2VydGlmaWNhdGlvbiBBdXRob3JpdHkwgZ8wDQYJKoZIhvcNAQEBBQADgY0A" + "MIGJAoGBAOUZv22jVmEtmUhx9mfeuY3rt56GgAqRDvo4Ja9GiILlc6igmyRdDR/MZW4MsNBWhBiH" + "mgabEKFz37RYOWtuwfYV1aioP6oSBo0xrH+wNNePNGeICc0UEeJORVZpH3gCgNrcR5EpuzbJY1zF" + "4Ncth3uhtzKwezC6Ki8xqu6jZ9rbAgMBAAEwDQYJKoZIhvcNAQECBQADgYEATD+4i8Zo3+5DMw5d" + "6abLB4RNejP/khv0Nq3YlSI2aBFsfELM85wuxAc/FLAPT/+Qknb54rxK6Y/NoIAK98Up8YIiXbix" + "3YEjo3slFUYweRb46gVLlH8dwhzI47f0EEA8E8NfH1PoSOSGtHuhNbB7Jbq4046rPzidADQAmPPR" + "cZQwggMuMIICl6ADAgECAhEA0nYujRQMPX2yqCVdr+4NdTANBgkqhkiG9w0BAQIFADBfMQswCQYD" + "VQQGEwJVUzEXMBUGA1UEChMOVmVyaVNpZ24sIEluYy4xNzA1BgNVBAsTLkNsYXNzIDEgUHVibGlj" + "IFByaW1hcnkgQ2VydGlmaWNhdGlvbiBBdXRob3JpdHkwHhcNOTgwNTEyMDAwMDAwWhcNMDgwNTEy" + "MjM1OTU5WjCBzDEXMBUGA1UEChMOVmVyaVNpZ24sIEluYy4xHzAdBgNVBAsTFlZlcmlTaWduIFRy" + "dXN0IE5ldHdvcmsxRjBEBgNVBAsTPXd3dy52ZXJpc2lnbi5jb20vcmVwb3NpdG9yeS9SUEEgSW5j" + "b3JwLiBCeSBSZWYuLExJQUIuTFREKGMpOTgxSDBGBgNVBAMTP1ZlcmlTaWduIENsYXNzIDEgQ0Eg" + "SW5kaXZpZHVhbCBTdWJzY3JpYmVyLVBlcnNvbmEgTm90IFZhbGlkYXRlZDCBnzANBgkqhkiG9w0B" + "AQEFAAOBjQAwgYkCgYEAu1pEigQWu1X9A3qKLZRPFXg2uA1Ksm+cVL+86HcqnbnwaLuV2TFBcHqB" + "S7lIE1YtxwjhhEKrwKKSq0RcqkLwgg4C6S/7wju7vsknCl22sDZCM7VuVIhPh0q/Gdr5FegPh7Yc" + "48zGmo5/aiSS4/zgZbqnsX7vyds3ashKyAkG5JkCAwEAAaN8MHowEQYJYIZIAYb4QgEBBAQDAgEG" + "MEcGA1UdIARAMD4wPAYLYIZIAYb4RQEHAQEwLTArBggrBgEFBQcCARYfd3d3LnZlcmlzaWduLmNv" + "bS9yZXBvc2l0b3J5L1JQQTAPBgNVHRMECDAGAQH/AgEAMAsGA1UdDwQEAwIBBjANBgkqhkiG9w0B" + "AQIFAAOBgQCIuDc73dqUNwCtqp/hgQFxHpJqbS/28Z3TymQ43BuYDAeGW4UVag+5SYWklfEXfWe0" + "fy0s3ZpCnsM+tI6q5QsG3vJWKvozx74Z11NMw73I4xe1pElCY+zCphcPXVgaSTyQXFWjZSAA/Rgg" + "5V+CprGoksVYasGNAzzrw80FopCubjCCA/gwggNhoAMCAQICEBbbn/1G1zppD6KsP01bwywwDQYJ" + "KoZIhvcNAQEEBQAwgcwxFzAVBgNVBAoTDlZlcmlTaWduLCBJbmMuMR8wHQYDVQQLExZWZXJpU2ln" + "biBUcnVzdCBOZXR3b3JrMUYwRAYDVQQLEz13d3cudmVyaXNpZ24uY29tL3JlcG9zaXRvcnkvUlBB" + "IEluY29ycC4gQnkgUmVmLixMSUFCLkxURChjKTk4MUgwRgYDVQQDEz9WZXJpU2lnbiBDbGFzcyAx" + "IENBIEluZGl2aWR1YWwgU3Vic2NyaWJlci1QZXJzb25hIE5vdCBWYWxpZGF0ZWQwHhcNMDAxMDAy" + "MDAwMDAwWhcNMDAxMjAxMjM1OTU5WjCCAQcxFzAVBgNVBAoTDlZlcmlTaWduLCBJbmMuMR8wHQYD" + "VQQLExZWZXJpU2lnbiBUcnVzdCBOZXR3b3JrMUYwRAYDVQQLEz13d3cudmVyaXNpZ24uY29tL3Jl" + "cG9zaXRvcnkvUlBBIEluY29ycC4gYnkgUmVmLixMSUFCLkxURChjKTk4MR4wHAYDVQQLExVQZXJz" + "b25hIE5vdCBWYWxpZGF0ZWQxJzAlBgNVBAsTHkRpZ2l0YWwgSUQgQ2xhc3MgMSAtIE1pY3Jvc29m" + "dDETMBEGA1UEAxQKRGF2aWQgUnlhbjElMCMGCSqGSIb3DQEJARYWZGF2aWRAbGl2ZW1lZGlhLmNv" + "bS5hdTCBnzANBgkqhkiG9w0BAQEFAAOBjQAwgYkCgYEAqxBsdeNmSvFqhMNwhQgNzM8mdjX9eSXb" + "DawpHtQHjmh0AKJSa3IwUY0VIsyZHuXWktO/CgaMBVPt6OVf/n0R2sQigMP6Y+PhEiS0vCJBL9aK" + "0+pOo2qXrjVBmq+XuCyPTnc+BOSrU26tJsX0P9BYorwySiEGxGanBNATdVL4NdUCAwEAAaOBnDCB" + "mTAJBgNVHRMEAjAAMEQGA1UdIAQ9MDswOQYLYIZIAYb4RQEHAQgwKjAoBggrBgEFBQcCARYcaHR0" + "cHM6Ly93d3cudmVyaXNpZ24uY29tL3JwYTARBglghkgBhvhCAQEEBAMCB4AwMwYDVR0fBCwwKjAo" + "oCagJIYiaHR0cDovL2NybC52ZXJpc2lnbi5jb20vY2xhc3MxLmNybDANBgkqhkiG9w0BAQQFAAOB" + "gQBC8yIIdVGpFTf8/YiL14cMzcmL0nIRm4kGR3U59z7UtcXlfNXXJ8MyaeI/BnXwG/gD5OKYqW6R" + "yca9vZOxf1uoTBl82gInk865ED3Tej6msCqFzZffnSUQvOIeqLxxDlqYRQ6PmW2nAnZeyjcnbI5Y" + "syQSM2fmo7n6qJFP+GbFezGCAkUwggJBAgEBMIHhMIHMMRcwFQYDVQQKEw5WZXJpU2lnbiwgSW5j" + "LjEfMB0GA1UECxMWVmVyaVNpZ24gVHJ1c3QgTmV0d29yazFGMEQGA1UECxM9d3d3LnZlcmlzaWdu" + "LmNvbS9yZXBvc2l0b3J5L1JQQSBJbmNvcnAuIEJ5IFJlZi4sTElBQi5MVEQoYyk5ODFIMEYGA1UE" + "AxM/VmVyaVNpZ24gQ2xhc3MgMSBDQSBJbmRpdmlkdWFsIFN1YnNjcmliZXItUGVyc29uYSBOb3Qg" + "VmFsaWRhdGVkAhAW25/9Rtc6aQ+irD9NW8MsMAkGBSsOAwIaBQCggbowGAYJKoZIhvcNAQkDMQsG" + "CSqGSIb3DQEHATAcBgkqhkiG9w0BCQUxDxcNMDAxMDAyMTczNTE4WjAjBgkqhkiG9w0BCQQxFgQU" + "gZjSaBEY2oxGvlQUIMnxSXhivK8wWwYJKoZIhvcNAQkPMU4wTDAKBggqhkiG9w0DBzAOBggqhkiG" + "9w0DAgICAIAwDQYIKoZIhvcNAwICAUAwBwYFKw4DAgcwDQYIKoZIhvcNAwICASgwBwYFKw4DAh0w" + "DQYJKoZIhvcNAQEBBQAEgYAzk+PU91/ZFfoiuKOECjxEh9fDYE2jfDCheBIgh5gdcCo+sS1WQs8O" + "HreQ9Nop/JdJv1DQMBK6weNBBDoP0EEkRm1XCC144XhXZC82jBZohYmi2WvDbbC//YN58kRMYMyy" + "srrfn4Z9I+6kTriGXkrpGk9Q0LSGjmG2BIsqiF0dvwAAAAAAAA=="); // // dsaWithSHA1 cert // byte[] cert7 = Base64.decode( "MIIEXAYJKoZIhvcNAQcCoIIETTCCBEkCAQExCzAJBgUrDgMCGgUAMAsGCSqG" + "SIb3DQEHAaCCAsMwggK/MIIB4AIBADCBpwYFKw4DAhswgZ0CQQEkJRHP+mN7" + "d8miwTMN55CUSmo3TO8WGCxgY61TX5k+7NU4XPf1TULjw3GobwaJX13kquPh" + "fVXk+gVy46n4Iw3hAhUBSe/QF4BUj+pJOF9ROBM4u+FEWA8CQQD4mSJbrABj" + "TUWrlnAte8pS22Tq4/FPO7jHSqjijUHfXKTrHL1OEqV3SVWcFy5j/cqBgX/z" + "m8Q12PFp/PjOhh+nMA4xDDAKBgNVBAMTA0lEMzAeFw05NzEwMDEwMDAwMDBa" + "Fw0zODAxMDEwMDAwMDBaMA4xDDAKBgNVBAMTA0lEMzCB8DCBpwYFKw4DAhsw" + "gZ0CQQEkJRHP+mN7d8miwTMN55CUSmo3TO8WGCxgY61TX5k+7NU4XPf1TULj" + "w3GobwaJX13kquPhfVXk+gVy46n4Iw3hAhUBSe/QF4BUj+pJOF9ROBM4u+FE" + "WA8CQQD4mSJbrABjTUWrlnAte8pS22Tq4/FPO7jHSqjijUHfXKTrHL1OEqV3" + "SVWcFy5j/cqBgX/zm8Q12PFp/PjOhh+nA0QAAkEAkYkXLYMtGVGWj9OnzjPn" + "sB9sefSRPrVegZJCZbpW+Iv0/1RP1u04pHG9vtRpIQLjzUiWvLMU9EKQTThc" + "eNMmWDCBpwYFKw4DAhswgZ0CQQEkJRHP+mN7d8miwTMN55CUSmo3TO8WGCxg" + "Y61TX5k+7NU4XPf1TULjw3GobwaJX13kquPhfVXk+gVy46n4Iw3hAhUBSe/Q" + "F4BUj+pJOF9ROBM4u+FEWA8CQQD4mSJbrABjTUWrlnAte8pS22Tq4/FPO7jH" + "SqjijUHfXKTrHL1OEqV3SVWcFy5j/cqBgX/zm8Q12PFp/PjOhh+nAy8AMCwC" + "FBY3dBSdeprGcqpr6wr3xbG+6WW+AhRMm/facKJNxkT3iKgJbp7R8Xd3QTGC" + "AWEwggFdAgEBMBMwDjEMMAoGA1UEAxMDSUQzAgEAMAkGBSsOAwIaBQCgXTAY" + "BgkqhkiG9w0BCQMxCwYJKoZIhvcNAQcBMBwGCSqGSIb3DQEJBTEPFw0wMjA1" + "MjQyMzEzMDdaMCMGCSqGSIb3DQEJBDEWBBS4WMsoJhf7CVbZYCFcjoTRzPkJ" + "xjCBpwYFKw4DAhswgZ0CQQEkJRHP+mN7d8miwTMN55CUSmo3TO8WGCxgY61T" + "X5k+7NU4XPf1TULjw3GobwaJX13kquPhfVXk+gVy46n4Iw3hAhUBSe/QF4BU" + "j+pJOF9ROBM4u+FEWA8CQQD4mSJbrABjTUWrlnAte8pS22Tq4/FPO7jHSqji" + "jUHfXKTrHL1OEqV3SVWcFy5j/cqBgX/zm8Q12PFp/PjOhh+nBC8wLQIVALID" + "dt+MHwawrDrwsO1Z6sXBaaJsAhRaKssrpevmLkbygKPV07XiAKBG02Zvb2Jh" + "cg=="); // // testcrl.pem // byte[] crl1 = Base64.decode( "MIICjTCCAfowDQYJKoZIhvcNAQECBQAwXzELMAkGA1UEBhMCVVMxIDAeBgNVBAoT" + "F1JTQSBEYXRhIFNlY3VyaXR5LCBJbmMuMS4wLAYDVQQLEyVTZWN1cmUgU2VydmVy" + "IENlcnRpZmljYXRpb24gQXV0aG9yaXR5Fw05NTA1MDIwMjEyMjZaFw05NTA2MDEw" + "MDAxNDlaMIIBaDAWAgUCQQAABBcNOTUwMjAxMTcyNDI2WjAWAgUCQQAACRcNOTUw" + "MjEwMDIxNjM5WjAWAgUCQQAADxcNOTUwMjI0MDAxMjQ5WjAWAgUCQQAADBcNOTUw" + "MjI1MDA0NjQ0WjAWAgUCQQAAGxcNOTUwMzEzMTg0MDQ5WjAWAgUCQQAAFhcNOTUw" + "MzE1MTkxNjU0WjAWAgUCQQAAGhcNOTUwMzE1MTk0MDQxWjAWAgUCQQAAHxcNOTUw" + "MzI0MTk0NDMzWjAWAgUCcgAABRcNOTUwMzI5MjAwNzExWjAWAgUCcgAAERcNOTUw" + "MzMwMDIzNDI2WjAWAgUCQQAAIBcNOTUwNDA3MDExMzIxWjAWAgUCcgAAHhcNOTUw" + "NDA4MDAwMjU5WjAWAgUCcgAAQRcNOTUwNDI4MTcxNzI0WjAWAgUCcgAAOBcNOTUw" + "NDI4MTcyNzIxWjAWAgUCcgAATBcNOTUwNTAyMDIxMjI2WjANBgkqhkiG9w0BAQIF" + "AAN+AHqOEJXSDejYy0UwxxrH/9+N2z5xu/if0J6qQmK92W0hW158wpJg+ovV3+wQ" + "wvIEPRL2rocL0tKfAsVq1IawSJzSNgxG0lrcla3MrJBnZ4GaZDu4FutZh72MR3Gt" + "JaAL3iTJHJD55kK2D/VoyY1djlsPuNh6AEgdVwFAyp0v"); // // ecdsa cert with extra octet string. // byte[] oldEcdsa = Base64.decode( "MIICljCCAkCgAwIBAgIBATALBgcqhkjOPQQBBQAwgY8xCzAJBgNVBAYTAkFVMSgwJ" + "gYDVQQKEx9UaGUgTGVnaW9uIG9mIHRoZSBCb3VuY3kgQ2FzdGxlMRIwEAYDVQQHEw" + "lNZWxib3VybmUxETAPBgNVBAgTCFZpY3RvcmlhMS8wLQYJKoZIhvcNAQkBFiBmZWV" + "kYmFjay1jcnlwdG9AYm91bmN5Y2FzdGxlLm9yZzAeFw0wMTEyMDcwMTAwMDRaFw0w" + "MTEyMDcwMTAxNDRaMIGPMQswCQYDVQQGEwJBVTEoMCYGA1UEChMfVGhlIExlZ2lvb" + "iBvZiB0aGUgQm91bmN5IENhc3RsZTESMBAGA1UEBxMJTWVsYm91cm5lMREwDwYDVQ" + "QIEwhWaWN0b3JpYTEvMC0GCSqGSIb3DQEJARYgZmVlZGJhY2stY3J5cHRvQGJvdW5" + "jeWNhc3RsZS5vcmcwgeQwgb0GByqGSM49AgEwgbECAQEwKQYHKoZIzj0BAQIef///" + "////////////f///////gAAAAAAAf///////MEAEHn///////////////3///////" + "4AAAAAAAH///////AQeawFsO9zxiUHQ1lSSFHXKcanbL7J9HTd5YYXClCwKBB8CD/" + "qWPNyogWzMM7hkK+35BcPTWFc9Pyf7vTs8uaqvAh5///////////////9///+eXpq" + "fXZBx+9FSJoiQnQsDIgAEHwJbbcU7xholSP+w9nFHLebJUhqdLSU05lq/y9X+DHAw" + "CwYHKoZIzj0EAQUAA0MAMEACHnz6t4UNoVROp74ma4XNDjjGcjaqiIWPZLK8Bdw3G" + "QIeLZ4j3a6ividZl344UH+UPUE7xJxlYGuy7ejTsqRR"); byte[] uncompressedPtEC = Base64.decode( "MIIDKzCCAsGgAwIBAgICA+kwCwYHKoZIzj0EAQUAMGYxCzAJBgNVBAYTAkpQ" + "MRUwEwYDVQQKEwxuaXRlY2guYWMuanAxDjAMBgNVBAsTBWFpbGFiMQ8wDQYD" + "VQQDEwZ0ZXN0Y2ExHzAdBgkqhkiG9w0BCQEWEHRlc3RjYUBsb2NhbGhvc3Qw" + "HhcNMDExMDEzMTE1MzE3WhcNMjAxMjEyMTE1MzE3WjBmMQswCQYDVQQGEwJK" + "UDEVMBMGA1UEChMMbml0ZWNoLmFjLmpwMQ4wDAYDVQQLEwVhaWxhYjEPMA0G" + "A1UEAxMGdGVzdGNhMR8wHQYJKoZIhvcNAQkBFhB0ZXN0Y2FAbG9jYWxob3N0" + "MIIBczCCARsGByqGSM49AgEwggEOAgEBMDMGByqGSM49AQECKEdYWnajFmnZ" + "tzrukK2XWdle2v+GsD9l1ZiR6g7ozQDbhFH/bBiMDQcwVAQoJ5EQKrI54/CT" + "xOQ2pMsd/fsXD+EX8YREd8bKHWiLz8lIVdD5cBNeVwQoMKSc6HfI7vKZp8Q2" + "zWgIFOarx1GQoWJbMcSt188xsl30ncJuJT2OoARRBAqJ4fD+q6hbqgNSjTQ7" + "htle1KO3eiaZgcJ8rrnyN8P+5A8+5K+H9aQ/NbBR4Gs7yto5PXIUZEUgodHA" + "TZMSAcSq5ZYt4KbnSYaLY0TtH9CqAigEwZ+hglbT21B7ZTzYX2xj0x+qooJD" + "hVTLtIPaYJK2HrMPxTw6/zfrAgEPA1IABAnvfFcFDgD/JicwBGn6vR3N8MIn" + "mptZf/mnJ1y649uCF60zOgdwIyI7pVSxBFsJ7ohqXEHW0x7LrGVkdSEiipiH" + "LYslqh3xrqbAgPbl93GUo0IwQDAPBgNVHRMBAf8EBTADAQH/MA4GA1UdDwEB" + "/wQEAwIBxjAdBgNVHQ4EFgQUAEo62Xm9H6DcsE0zUDTza4BRG90wCwYHKoZI" + "zj0EAQUAA1cAMFQCKAQsCHHSNOqfJXLgt3bg5+k49hIBGVr/bfG0B9JU3rNt" + "Ycl9Y2zfRPUCKAK2ccOQXByAWfsasDu8zKHxkZv7LVDTFjAIffz3HaCQeVhD" + "z+fauEg="); byte[] keyUsage = Base64.decode( "MIIE7TCCBFagAwIBAgIEOAOR7jANBgkqhkiG9w0BAQQFADCByTELMAkGA1UE" + "BhMCVVMxFDASBgNVBAoTC0VudHJ1c3QubmV0MUgwRgYDVQQLFD93d3cuZW50" + "cnVzdC5uZXQvQ2xpZW50X0NBX0luZm8vQ1BTIGluY29ycC4gYnkgcmVmLiBs" + "aW1pdHMgbGlhYi4xJTAjBgNVBAsTHChjKSAxOTk5IEVudHJ1c3QubmV0IExp" + "bWl0ZWQxMzAxBgNVBAMTKkVudHJ1c3QubmV0IENsaWVudCBDZXJ0aWZpY2F0" + "aW9uIEF1dGhvcml0eTAeFw05OTEwMTIxOTI0MzBaFw0xOTEwMTIxOTU0MzBa" + "MIHJMQswCQYDVQQGEwJVUzEUMBIGA1UEChMLRW50cnVzdC5uZXQxSDBGBgNV" + "BAsUP3d3dy5lbnRydXN0Lm5ldC9DbGllbnRfQ0FfSW5mby9DUFMgaW5jb3Jw" + "LiBieSByZWYuIGxpbWl0cyBsaWFiLjElMCMGA1UECxMcKGMpIDE5OTkgRW50" + "cnVzdC5uZXQgTGltaXRlZDEzMDEGA1UEAxMqRW50cnVzdC5uZXQgQ2xpZW50" + "IENlcnRpZmljYXRpb24gQXV0aG9yaXR5MIGdMA0GCSqGSIb3DQEBAQUAA4GL" + "ADCBhwKBgQDIOpleMRffrCdvkHvkGf9FozTC28GoT/Bo6oT9n3V5z8GKUZSv" + "x1cDR2SerYIbWtp/N3hHuzeYEpbOxhN979IMMFGpOZ5V+Pux5zDeg7K6PvHV" + "iTs7hbqqdCz+PzFur5GVbgbUB01LLFZHGARS2g4Qk79jkJvh34zmAqTmT173" + "iwIBA6OCAeAwggHcMBEGCWCGSAGG+EIBAQQEAwIABzCCASIGA1UdHwSCARkw" + "ggEVMIHkoIHhoIHepIHbMIHYMQswCQYDVQQGEwJVUzEUMBIGA1UEChMLRW50" + "cnVzdC5uZXQxSDBGBgNVBAsUP3d3dy5lbnRydXN0Lm5ldC9DbGllbnRfQ0Ff" + "SW5mby9DUFMgaW5jb3JwLiBieSByZWYuIGxpbWl0cyBsaWFiLjElMCMGA1UE" + "CxMcKGMpIDE5OTkgRW50cnVzdC5uZXQgTGltaXRlZDEzMDEGA1UEAxMqRW50" + "cnVzdC5uZXQgQ2xpZW50IENlcnRpZmljYXRpb24gQXV0aG9yaXR5MQ0wCwYD" + "VQQDEwRDUkwxMCygKqAohiZodHRwOi8vd3d3LmVudHJ1c3QubmV0L0NSTC9D" + "bGllbnQxLmNybDArBgNVHRAEJDAigA8xOTk5MTAxMjE5MjQzMFqBDzIwMTkx" + "MDEyMTkyNDMwWjALBgNVHQ8EBAMCAQYwHwYDVR0jBBgwFoAUxPucKXuXzUyW" + "/O5bs8qZdIuV6kwwHQYDVR0OBBYEFMT7nCl7l81MlvzuW7PKmXSLlepMMAwG" + "A1UdEwQFMAMBAf8wGQYJKoZIhvZ9B0EABAwwChsEVjQuMAMCBJAwDQYJKoZI" + "hvcNAQEEBQADgYEAP66K8ddmAwWePvrqHEa7pFuPeJoSSJn59DXeDDYHAmsQ" + "OokUgZwxpnyyQbJq5wcBoUv5nyU7lsqZwz6hURzzwy5E97BnRqqS5TvaHBkU" + "ODDV4qIxJS7x7EU47fgGWANzYrAQMY9Av2TgXD7FTx/aEkP/TOYGJqibGapE" + "PHayXOw="); byte[] nameCert = Base64.decode( "MIIEFjCCA3+gAwIBAgIEdS8BozANBgkqhkiG9w0BAQUFADBKMQswCQYDVQQGEwJE"+ "RTERMA8GA1UEChQIREFURVYgZUcxKDAMBgcCggYBCgcUEwExMBgGA1UEAxQRQ0Eg"+ "REFURVYgRDAzIDE6UE4wIhgPMjAwMTA1MTAxMDIyNDhaGA8yMDA0MDUwOTEwMjI0"+ "OFowgYQxCzAJBgNVBAYTAkRFMQ8wDQYDVQQIFAZCYXllcm4xEjAQBgNVBAcUCU7I"+ "dXJuYmVyZzERMA8GA1UEChQIREFURVYgZUcxHTAbBgNVBAUTFDAwMDAwMDAwMDA4"+ "OTU3NDM2MDAxMR4wHAYDVQQDFBVEaWV0bWFyIFNlbmdlbmxlaXRuZXIwgaEwDQYJ"+ "KoZIhvcNAQEBBQADgY8AMIGLAoGBAJLI/LJLKaHoMk8fBECW/od8u5erZi6jI8Ug"+ "C0a/LZyQUO/R20vWJs6GrClQtXB+AtfiBSnyZOSYzOdfDI8yEKPEv8qSuUPpOHps"+ "uNCFdLZF1vavVYGEEWs2+y+uuPmg8q1oPRyRmUZ+x9HrDvCXJraaDfTEd9olmB/Z"+ "AuC/PqpjAgUAwAAAAaOCAcYwggHCMAwGA1UdEwEB/wQCMAAwDwYDVR0PAQH/BAUD"+ "AwdAADAxBgNVHSAEKjAoMCYGBSskCAEBMB0wGwYIKwYBBQUHAgEWD3d3dy56cy5k"+ "YXRldi5kZTApBgNVHREEIjAggR5kaWV0bWFyLnNlbmdlbmxlaXRuZXJAZGF0ZXYu"+ "ZGUwgYQGA1UdIwR9MHuhc6RxMG8xCzAJBgNVBAYTAkRFMT0wOwYDVQQKFDRSZWd1"+ "bGllcnVuZ3NiZWjIb3JkZSBmyHVyIFRlbGVrb21tdW5pa2F0aW9uIHVuZCBQb3N0"+ "MSEwDAYHAoIGAQoHFBMBMTARBgNVBAMUCjVSLUNBIDE6UE6CBACm8LkwDgYHAoIG"+ "AQoMAAQDAQEAMEcGA1UdHwRAMD4wPKAUoBKGEHd3dy5jcmwuZGF0ZXYuZGWiJKQi"+ "MCAxCzAJBgNVBAYTAkRFMREwDwYDVQQKFAhEQVRFViBlRzAWBgUrJAgDBAQNMAsT"+ "A0VVUgIBBQIBATAdBgNVHQ4EFgQUfv6xFP0xk7027folhy+ziZvBJiwwLAYIKwYB"+ "BQUHAQEEIDAeMBwGCCsGAQUFBzABhhB3d3cuZGlyLmRhdGV2LmRlMA0GCSqGSIb3"+ "DQEBBQUAA4GBAEOVX6uQxbgtKzdgbTi6YLffMftFr2mmNwch7qzpM5gxcynzgVkg"+ "pnQcDNlm5AIbS6pO8jTCLfCd5TZ5biQksBErqmesIl3QD+VqtB+RNghxectZ3VEs"+ "nCUtcE7tJ8O14qwCb3TxS9dvIUFiVi4DjbxX46TdcTbTaK8/qr6AIf+l"); byte[] probSelfSignedCert = Base64.decode( "MIICxTCCAi6gAwIBAgIQAQAAAAAAAAAAAAAAAAAAATANBgkqhkiG9w0BAQUFADBF" + "MScwJQYDVQQKEx4gRElSRUNUSU9OIEdFTkVSQUxFIERFUyBJTVBPVFMxGjAYBgNV" + "BAMTESBBQyBNSU5FRkkgQiBURVNUMB4XDTA0MDUwNzEyMDAwMFoXDTE0MDUwNzEy" + "MDAwMFowRTEnMCUGA1UEChMeIERJUkVDVElPTiBHRU5FUkFMRSBERVMgSU1QT1RT" + "MRowGAYDVQQDExEgQUMgTUlORUZJIEIgVEVTVDCBnzANBgkqhkiG9w0BAQEFAAOB" + "jQAwgYkCgYEAveoCUOAukZdcFCs2qJk76vSqEX0ZFzHqQ6faBPZWjwkgUNwZ6m6m" + "qWvvyq1cuxhoDvpfC6NXILETawYc6MNwwxsOtVVIjuXlcF17NMejljJafbPximEt" + "DQ4LcQeSp4K7FyFlIAMLyt3BQ77emGzU5fjFTvHSUNb3jblx0sV28c0CAwEAAaOB" + "tTCBsjAfBgNVHSMEGDAWgBSEJ4bLbvEQY8cYMAFKPFD1/fFXlzAdBgNVHQ4EFgQU" + "hCeGy27xEGPHGDABSjxQ9f3xV5cwDgYDVR0PAQH/BAQDAgEGMBEGCWCGSAGG+EIB" + "AQQEAwIBBjA8BgNVHR8ENTAzMDGgL6AthitodHRwOi8vYWRvbmlzLnBrNy5jZXJ0" + "cGx1cy5uZXQvZGdpLXRlc3QuY3JsMA8GA1UdEwEB/wQFMAMBAf8wDQYJKoZIhvcN" + "AQEFBQADgYEAmToHJWjd3+4zknfsP09H6uMbolHNGG0zTS2lrLKpzcmkQfjhQpT9" + "LUTBvfs1jdjo9fGmQLvOG+Sm51Rbjglb8bcikVI5gLbclOlvqLkm77otjl4U4Z2/" + "Y0vP14Aov3Sn3k+17EfReYUZI4liuB95ncobC4e8ZM++LjQcIM0s+Vs="); byte[] gost34102001base = Base64.decode( "MIIB1DCCAYECEEjpVKXP6Wn1yVz3VeeDQa8wCgYGKoUDAgIDBQAwbTEfMB0G" + "A1UEAwwWR29zdFIzNDEwLTIwMDEgZXhhbXBsZTESMBAGA1UECgwJQ3J5cHRv" + "UHJvMQswCQYDVQQGEwJSVTEpMCcGCSqGSIb3DQEJARYaR29zdFIzNDEwLTIw" + "MDFAZXhhbXBsZS5jb20wHhcNMDUwMjAzMTUxNjQ2WhcNMTUwMjAzMTUxNjQ2" + "WjBtMR8wHQYDVQQDDBZHb3N0UjM0MTAtMjAwMSBleGFtcGxlMRIwEAYDVQQK" + "DAlDcnlwdG9Qcm8xCzAJBgNVBAYTAlJVMSkwJwYJKoZIhvcNAQkBFhpHb3N0" + "UjM0MTAtMjAwMUBleGFtcGxlLmNvbTBjMBwGBiqFAwICEzASBgcqhQMCAiQA" + "BgcqhQMCAh4BA0MABECElWh1YAIaQHUIzROMMYks/eUFA3pDXPRtKw/nTzJ+" + "V4/rzBa5lYgD0Jp8ha4P5I3qprt+VsfLsN8PZrzK6hpgMAoGBiqFAwICAwUA" + "A0EAHw5dw/aw/OiNvHyOE65kvyo4Hp0sfz3csM6UUkp10VO247ofNJK3tsLb" + "HOLjUaqzefrlGb11WpHYrvWFg+FcLA=="); byte[] gost341094base = Base64.decode( "MIICDzCCAbwCEBcxKsIb0ghYvAQeUjfQdFAwCgYGKoUDAgIEBQAwaTEdMBsG" + "A1UEAwwUR29zdFIzNDEwLTk0IGV4YW1wbGUxEjAQBgNVBAoMCUNyeXB0b1By" + "bzELMAkGA1UEBhMCUlUxJzAlBgkqhkiG9w0BCQEWGEdvc3RSMzQxMC05NEBl" + "eGFtcGxlLmNvbTAeFw0wNTAyMDMxNTE2NTFaFw0xNTAyMDMxNTE2NTFaMGkx" + "HTAbBgNVBAMMFEdvc3RSMzQxMC05NCBleGFtcGxlMRIwEAYDVQQKDAlDcnlw" + "dG9Qcm8xCzAJBgNVBAYTAlJVMScwJQYJKoZIhvcNAQkBFhhHb3N0UjM0MTAt" + "OTRAZXhhbXBsZS5jb20wgaUwHAYGKoUDAgIUMBIGByqFAwICIAIGByqFAwIC" + "HgEDgYQABIGAu4Rm4XmeWzTYLIB/E6gZZnFX/oxUJSFHbzALJ3dGmMb7R1W+" + "t7Lzk2w5tUI3JoTiDRCKJA4fDEJNKzsRK6i/ZjkyXJSLwaj+G2MS9gklh8x1" + "G/TliYoJgmjTXHemD7aQEBON4z58nJHWrA0ILD54wbXCtrcaqCqLRYGTMjJ2" + "+nswCgYGKoUDAgIEBQADQQBxKNhOmjgz/i5CEgLOyKyz9pFGkDcaymsWYQWV" + "v7CZ0pTM8IzMzkUBW3GHsUjCFpanFZDfg2zuN+3kT+694n9B"); byte[] gost341094A = Base64.decode( "MIICSDCCAfWgAwIBAgIBATAKBgYqhQMCAgQFADCBgTEXMBUGA1UEAxMOZGVmYXVsdDM0MTAtOTQx" + "DTALBgNVBAoTBERpZ3QxDzANBgNVBAsTBkNyeXB0bzEOMAwGA1UEBxMFWS1vbGExDDAKBgNVBAgT" + "A01FTDELMAkGA1UEBhMCcnUxGzAZBgkqhkiG9w0BCQEWDHRlc3RAdGVzdC5ydTAeFw0wNTAzMjkx" + "MzExNTdaFw0wNjAzMjkxMzExNTdaMIGBMRcwFQYDVQQDEw5kZWZhdWx0MzQxMC05NDENMAsGA1UE" + "ChMERGlndDEPMA0GA1UECxMGQ3J5cHRvMQ4wDAYDVQQHEwVZLW9sYTEMMAoGA1UECBMDTUVMMQsw" + "CQYDVQQGEwJydTEbMBkGCSqGSIb3DQEJARYMdGVzdEB0ZXN0LnJ1MIGlMBwGBiqFAwICFDASBgcq" + "hQMCAiACBgcqhQMCAh4BA4GEAASBgIQACDLEuxSdRDGgdZxHmy30g/DUYkRxO9Mi/uSHX5NjvZ31" + "b7JMEMFqBtyhql1HC5xZfUwZ0aT3UnEFDfFjLP+Bf54gA+LPkQXw4SNNGOj+klnqgKlPvoqMGlwa" + "+hLPKbS561WpvB2XSTgbV+pqqXR3j6j30STmybelEV3RdS2Now8wDTALBgNVHQ8EBAMCB4AwCgYG" + "KoUDAgIEBQADQQBCFy7xWRXtNVXflKvDs0pBdBuPzjCMeZAXVxK8vUxsxxKu76d9CsvhgIFknFRi" + "wWTPiZenvNoJ4R1uzeX+vREm"); byte[] gost341094B = Base64.decode( "MIICSDCCAfWgAwIBAgIBATAKBgYqhQMCAgQFADCBgTEXMBUGA1UEAxMOcGFyYW0xLTM0MTAtOTQx" + "DTALBgNVBAoTBERpZ3QxDzANBgNVBAsTBkNyeXB0bzEOMAwGA1UEBxMFWS1PbGExDDAKBgNVBAgT" + "A01lbDELMAkGA1UEBhMCcnUxGzAZBgkqhkiG9w0BCQEWDHRlc3RAdGVzdC5ydTAeFw0wNTAzMjkx" + "MzEzNTZaFw0wNjAzMjkxMzEzNTZaMIGBMRcwFQYDVQQDEw5wYXJhbTEtMzQxMC05NDENMAsGA1UE" + "ChMERGlndDEPMA0GA1UECxMGQ3J5cHRvMQ4wDAYDVQQHEwVZLU9sYTEMMAoGA1UECBMDTWVsMQsw" + "CQYDVQQGEwJydTEbMBkGCSqGSIb3DQEJARYMdGVzdEB0ZXN0LnJ1MIGlMBwGBiqFAwICFDASBgcq" + "hQMCAiADBgcqhQMCAh4BA4GEAASBgEa+AAcZmijWs1M9x5Pn9efE8D9ztG1NMoIt0/hNZNqln3+j" + "lMZjyqPt+kTLIjtmvz9BRDmIDk6FZz+4LhG2OTL7yGpWfrMxMRr56nxomTN9aLWRqbyWmn3brz9Y" + "AUD3ifnwjjIuW7UM84JNlDTOdxx0XRUfLQIPMCXe9cO02Xskow8wDTALBgNVHQ8EBAMCB4AwCgYG" + "KoUDAgIEBQADQQBzFcnuYc/639OTW+L5Ecjw9KxGr+dwex7lsS9S1BUgKa3m1d5c+cqI0B2XUFi5" + "4iaHHJG0dCyjtQYLJr0OZjRw"); byte[] gost34102001A = Base64.decode( "MIICCzCCAbigAwIBAgIBATAKBgYqhQMCAgMFADCBhDEaMBgGA1UEAxMRZGVmYXVsdC0zNDEwLTIw" + "MDExDTALBgNVBAoTBERpZ3QxDzANBgNVBAsTBkNyeXB0bzEOMAwGA1UEBxMFWS1PbGExDDAKBgNV" + "BAgTA01lbDELMAkGA1UEBhMCcnUxGzAZBgkqhkiG9w0BCQEWDHRlc3RAdGVzdC5ydTAeFw0wNTAz" + "MjkxMzE4MzFaFw0wNjAzMjkxMzE4MzFaMIGEMRowGAYDVQQDExFkZWZhdWx0LTM0MTAtMjAwMTEN" + "MAsGA1UEChMERGlndDEPMA0GA1UECxMGQ3J5cHRvMQ4wDAYDVQQHEwVZLU9sYTEMMAoGA1UECBMD" + "TWVsMQswCQYDVQQGEwJydTEbMBkGCSqGSIb3DQEJARYMdGVzdEB0ZXN0LnJ1MGMwHAYGKoUDAgIT" + "MBIGByqFAwICIwEGByqFAwICHgEDQwAEQG/4c+ZWb10IpeHfmR+vKcbpmSOClJioYmCVgnojw0Xn" + "ned0KTg7TJreRUc+VX7vca4hLQaZ1o/TxVtfEApK/O6jDzANMAsGA1UdDwQEAwIHgDAKBgYqhQMC" + "AgMFAANBAN8y2b6HuIdkD3aWujpfQbS1VIA/7hro4vLgDhjgVmev/PLzFB8oTh3gKhExpDo82IEs" + "ZftGNsbbyp1NFg7zda0="); byte[] gostCA1 = Base64.decode( "MIIDNDCCAuGgAwIBAgIQZLcKDcWcQopF+jp4p9jylDAKBgYqhQMCAgQFADBm" + "MQswCQYDVQQGEwJSVTEPMA0GA1UEBxMGTW9zY293MRcwFQYDVQQKEw5PT08g" + "Q3J5cHRvLVBybzEUMBIGA1UECxMLRGV2ZWxvcG1lbnQxFzAVBgNVBAMTDkNQ" + "IENTUCBUZXN0IENBMB4XDTAyMDYwOTE1NTIyM1oXDTA5MDYwOTE1NTkyOVow" + "ZjELMAkGA1UEBhMCUlUxDzANBgNVBAcTBk1vc2NvdzEXMBUGA1UEChMOT09P" + "IENyeXB0by1Qcm8xFDASBgNVBAsTC0RldmVsb3BtZW50MRcwFQYDVQQDEw5D" + "UCBDU1AgVGVzdCBDQTCBpTAcBgYqhQMCAhQwEgYHKoUDAgIgAgYHKoUDAgIe" + "AQOBhAAEgYAYglywKuz1nMc9UiBYOaulKy53jXnrqxZKbCCBSVaJ+aCKbsQm" + "glhRFrw6Mwu8Cdeabo/ojmea7UDMZd0U2xhZFRti5EQ7OP6YpqD0alllo7za" + "4dZNXdX+/ag6fOORSLFdMpVx5ganU0wHMPk67j+audnCPUj/plbeyccgcdcd" + "WaOCASIwggEeMAsGA1UdDwQEAwIBxjAPBgNVHRMBAf8EBTADAQH/MB0GA1Ud" + "DgQWBBTe840gTo4zt2twHilw3PD9wJaX0TCBygYDVR0fBIHCMIG/MDygOqA4" + "hjYtaHR0cDovL2ZpZXdhbGwvQ2VydEVucm9sbC9DUCUyMENTUCUyMFRlc3Ql" + "MjBDQSgzKS5jcmwwRKBCoECGPmh0dHA6Ly93d3cuY3J5cHRvcHJvLnJ1L0Nl" + "cnRFbnJvbGwvQ1AlMjBDU1AlMjBUZXN0JTIwQ0EoMykuY3JsMDmgN6A1hjMt" + "ZmlsZTovL1xcZmlld2FsbFxDZXJ0RW5yb2xsXENQIENTUCBUZXN0IENBKDMp" + "LmNybC8wEgYJKwYBBAGCNxUBBAUCAwMAAzAKBgYqhQMCAgQFAANBAIJi7ni7" + "9rwMR5rRGTFftt2k70GbqyUEfkZYOzrgdOoKiB4IIsIstyBX0/ne6GsL9Xan" + "G2IN96RB7KrowEHeW+k="); byte[] gostCA2 = Base64.decode( "MIIC2DCCAoWgAwIBAgIQe9ZCugm42pRKNcHD8466zTAKBgYqhQMCAgMFADB+" + "MRowGAYJKoZIhvcNAQkBFgtzYmFAZGlndC5ydTELMAkGA1UEBhMCUlUxDDAK" + "BgNVBAgTA01FTDEUMBIGA1UEBxMLWW9zaGthci1PbGExDTALBgNVBAoTBERp" + "Z3QxDzANBgNVBAsTBkNyeXB0bzEPMA0GA1UEAxMGc2JhLUNBMB4XDTA0MDgw" + "MzEzMzE1OVoXDTE0MDgwMzEzNDAxMVowfjEaMBgGCSqGSIb3DQEJARYLc2Jh" + "QGRpZ3QucnUxCzAJBgNVBAYTAlJVMQwwCgYDVQQIEwNNRUwxFDASBgNVBAcT" + "C1lvc2hrYXItT2xhMQ0wCwYDVQQKEwREaWd0MQ8wDQYDVQQLEwZDcnlwdG8x" + "DzANBgNVBAMTBnNiYS1DQTBjMBwGBiqFAwICEzASBgcqhQMCAiMBBgcqhQMC" + "Ah4BA0MABEDMSy10CuOH+i8QKG2UWA4XmCt6+BFrNTZQtS6bOalyDY8Lz+G7" + "HybyipE3PqdTB4OIKAAPsEEeZOCZd2UXGQm5o4HaMIHXMBMGCSsGAQQBgjcU" + "AgQGHgQAQwBBMAsGA1UdDwQEAwIBhjAPBgNVHRMBAf8EBTADAQH/MB0GA1Ud" + "DgQWBBRJJl3LcNMxkZI818STfoi3ng1xoDBxBgNVHR8EajBoMDGgL6Athito" + "dHRwOi8vc2JhLmRpZ3QubG9jYWwvQ2VydEVucm9sbC9zYmEtQ0EuY3JsMDOg" + "MaAvhi1maWxlOi8vXFxzYmEuZGlndC5sb2NhbFxDZXJ0RW5yb2xsXHNiYS1D" + "QS5jcmwwEAYJKwYBBAGCNxUBBAMCAQAwCgYGKoUDAgIDBQADQQA+BRJHbc/p" + "q8EYl6iJqXCuR+ozRmH7hPAP3c4KqYSC38TClCgBloLapx/3/WdatctFJW/L" + "mcTovpq088927shE"); byte[] inDirectCrl = Base64.decode( "MIIdXjCCHMcCAQEwDQYJKoZIhvcNAQEFBQAwdDELMAkGA1UEBhMCREUxHDAaBgNV" +"BAoUE0RldXRzY2hlIFRlbGVrb20gQUcxFzAVBgNVBAsUDlQtVGVsZVNlYyBUZXN0" +"MS4wDAYHAoIGAQoHFBMBMTAeBgNVBAMUF1QtVGVsZVNlYyBUZXN0IERJUiA4OlBO" +"Fw0wNjA4MDQwODQ1MTRaFw0wNjA4MDQxNDQ1MTRaMIIbfzB+AgQvrj/pFw0wMzA3" +"MjIwNTQxMjhaMGcwZQYDVR0dAQH/BFswWaRXMFUxCzAJBgNVBAYTAkRFMRwwGgYD" +"VQQKFBNEZXV0c2NoZSBUZWxla29tIEFHMSgwDAYHAoIGAQoHFBMBMTAYBgNVBAMU" +"EVNpZ0cgVGVzdCBDQSA0OlBOMH4CBC+uP+oXDTAzMDcyMjA1NDEyOFowZzBlBgNV" +"HR0BAf8EWzBZpFcwVTELMAkGA1UEBhMCREUxHDAaBgNVBAoUE0RldXRzY2hlIFRl" +"bGVrb20gQUcxKDAMBgcCggYBCgcUEwExMBgGA1UEAxQRU2lnRyBUZXN0IENBIDQ6" +"UE4wfgIEL64/5xcNMDQwNDA1MTMxODE3WjBnMGUGA1UdHQEB/wRbMFmkVzBVMQsw" +"CQYDVQQGEwJERTEcMBoGA1UEChQTRGV1dHNjaGUgVGVsZWtvbSBBRzEoMAwGBwKC" +"BgEKBxQTATEwGAYDVQQDFBFTaWdHIFRlc3QgQ0EgNDpQTjB+AgQvrj/oFw0wNDA0" +"MDUxMzE4MTdaMGcwZQYDVR0dAQH/BFswWaRXMFUxCzAJBgNVBAYTAkRFMRwwGgYD" +"VQQKFBNEZXV0c2NoZSBUZWxla29tIEFHMSgwDAYHAoIGAQoHFBMBMTAYBgNVBAMU" +"EVNpZ0cgVGVzdCBDQSA0OlBOMH4CBC+uP+UXDTAzMDExMzExMTgxMVowZzBlBgNV" +"HR0BAf8EWzBZpFcwVTELMAkGA1UEBhMCREUxHDAaBgNVBAoUE0RldXRzY2hlIFRl" +"bGVrb20gQUcxKDAMBgcCggYBCgcUEwExMBgGA1UEAxQRU2lnRyBUZXN0IENBIDQ6" +"UE4wfgIEL64/5hcNMDMwMTEzMTExODExWjBnMGUGA1UdHQEB/wRbMFmkVzBVMQsw" +"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"); byte[] directCRL = Base64.decode( "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" +"MQ=="); private final byte[] pkcs7CrlProblem = Base64.decode( "MIIwSAYJKoZIhvcNAQcCoIIwOTCCMDUCAQExCzAJBgUrDgMCGgUAMAsGCSqG" + "SIb3DQEHAaCCEsAwggP4MIIC4KADAgECAgF1MA0GCSqGSIb3DQEBBQUAMEUx" + "CzAJBgNVBAYTAlVTMRYwFAYDVQQKEw1HZW9UcnVzdCBJbmMuMR4wHAYDVQQD" + "ExVHZW9UcnVzdCBDQSBmb3IgQWRvYmUwHhcNMDQxMjAyMjEyNTM5WhcNMDYx" + "MjMwMjEyNTM5WjBMMQswCQYDVQQGEwJVUzEVMBMGA1UEChMMR2VvVHJ1c3Qg" + "SW5jMSYwJAYDVQQDEx1HZW9UcnVzdCBBZG9iZSBPQ1NQIFJlc3BvbmRlcjCB" + "nzANBgkqhkiG9w0BAQEFAAOBjQAwgYkCgYEA4gnNYhtw7U6QeVXZODnGhHMj" + "+OgZ0DB393rEk6a2q9kq129IA2e03yKBTfJfQR9aWKc2Qj90dsSqPjvTDHFG" + "Qsagm2FQuhnA3fb1UWhPzeEIdm6bxDsnQ8nWqKqxnWZzELZbdp3I9bBLizIq" + "obZovzt60LNMghn/unvvuhpeVSsCAwEAAaOCAW4wggFqMA4GA1UdDwEB/wQE" + "AwIE8DCB5QYDVR0gAQH/BIHaMIHXMIHUBgkqhkiG9y8BAgEwgcYwgZAGCCsG" + "AQUFBwICMIGDGoGAVGhpcyBjZXJ0aWZpY2F0ZSBoYXMgYmVlbiBpc3N1ZWQg" + "aW4gYWNjb3JkYW5jZSB3aXRoIHRoZSBBY3JvYmF0IENyZWRlbnRpYWxzIENQ" + "UyBsb2NhdGVkIGF0IGh0dHA6Ly93d3cuZ2VvdHJ1c3QuY29tL3Jlc291cmNl" + "cy9jcHMwMQYIKwYBBQUHAgEWJWh0dHA6Ly93d3cuZ2VvdHJ1c3QuY29tL3Jl" + "c291cmNlcy9jcHMwEwYDVR0lBAwwCgYIKwYBBQUHAwkwOgYDVR0fBDMwMTAv" + "oC2gK4YpaHR0cDovL2NybC5nZW90cnVzdC5jb20vY3Jscy9hZG9iZWNhMS5j" + "cmwwHwYDVR0jBBgwFoAUq4BZw2WDbR19E70Zw+wajw1HaqMwDQYJKoZIhvcN" + "AQEFBQADggEBAENJf1BD7PX5ivuaawt90q1OGzXpIQL/ClzEeFVmOIxqPc1E" + "TFRq92YuxG5b6+R+k+tGkmCwPLcY8ipg6ZcbJ/AirQhohzjlFuT6YAXsTfEj" + "CqEZfWM2sS7crK2EYxCMmKE3xDfPclYtrAoz7qZvxfQj0TuxHSstHZv39wu2" + "ZiG1BWiEcyDQyTgqTOXBoZmfJtshuAcXmTpgkrYSrS37zNlPTGh+pMYQ0yWD" + "c8OQRJR4OY5ZXfdna01mjtJTOmj6/6XPoLPYTq2gQrc2BCeNJ4bEhLb7sFVB" + "PbwPrpzTE/HRbQHDrzj0YimDxeOUV/UXctgvYwHNtEkcBLsOm/uytMYwggSh" + "MIIDiaADAgECAgQ+HL0oMA0GCSqGSIb3DQEBBQUAMGkxCzAJBgNVBAYTAlVT" + "MSMwIQYDVQQKExpBZG9iZSBTeXN0ZW1zIEluY29ycG9yYXRlZDEdMBsGA1UE" + "CxMUQWRvYmUgVHJ1c3QgU2VydmljZXMxFjAUBgNVBAMTDUFkb2JlIFJvb3Qg" + "Q0EwHhcNMDMwMTA4MjMzNzIzWhcNMjMwMTA5MDAwNzIzWjBpMQswCQYDVQQG" + "EwJVUzEjMCEGA1UEChMaQWRvYmUgU3lzdGVtcyBJbmNvcnBvcmF0ZWQxHTAb" + "BgNVBAsTFEFkb2JlIFRydXN0IFNlcnZpY2VzMRYwFAYDVQQDEw1BZG9iZSBS" + "b290IENBMIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEAzE9UhPen" + "ouczU38/nBKIayyZR2d+Dx65rRSI+cMQ2B3w8NWfaQovWTWwzGypTJwVoJ/O" + "IL+gz1Ti4CBmRT85hjh+nMSOByLGJPYBErA131XqaZCw24U3HuJOB7JCoWoT" + "aaBm6oCREVkqmwh5WiBELcm9cziLPC/gQxtdswvwrzUaKf7vppLdgUydPVmO" + "rTE8QH6bkTYG/OJcjdGNJtVcRc+vZT+xqtJilvSoOOq6YEL09BxKNRXO+E4i" + "Vg+VGMX4lp+f+7C3eCXpgGu91grwxnSUnfMPUNuad85LcIMjjaDKeCBEXDxU" + "ZPHqojAZn+pMBk0GeEtekt8i0slns3rSAQIDAQABo4IBTzCCAUswEQYJYIZI" + "AYb4QgEBBAQDAgAHMIGOBgNVHR8EgYYwgYMwgYCgfqB8pHoweDELMAkGA1UE" + "BhMCVVMxIzAhBgNVBAoTGkFkb2JlIFN5c3RlbXMgSW5jb3Jwb3JhdGVkMR0w" + "GwYDVQQLExRBZG9iZSBUcnVzdCBTZXJ2aWNlczEWMBQGA1UEAxMNQWRvYmUg" + "Um9vdCBDQTENMAsGA1UEAxMEQ1JMMTArBgNVHRAEJDAigA8yMDAzMDEwODIz" + "MzcyM1qBDzIwMjMwMTA5MDAwNzIzWjALBgNVHQ8EBAMCAQYwHwYDVR0jBBgw" + "FoAUgrc4SpOqmxDvgLvZVOLxD/uAnN4wHQYDVR0OBBYEFIK3OEqTqpsQ74C7" + "2VTi8Q/7gJzeMAwGA1UdEwQFMAMBAf8wHQYJKoZIhvZ9B0EABBAwDhsIVjYu" + "MDo0LjADAgSQMA0GCSqGSIb3DQEBBQUAA4IBAQAy2p9DdcH6b8lv26sdNjc+" + "vGEZNrcCPB0jWZhsnu5NhedUyCAfp9S74r8Ad30ka3AvXME6dkm10+AjhCpx" + "aiLzwScpmBX2NZDkBEzDjbyfYRzn/SSM0URDjBa6m02l1DUvvBHOvfdRN42f" + "kOQU8Rg/vulZEjX5M5LznuDVa5pxm5lLyHHD4bFhCcTl+pHwQjo3fTT5cujN" + "qmIcIenV9IIQ43sFti1oVgt+fpIsb01yggztVnSynbmrLSsdEF/bJ3Vwj/0d" + "1+ICoHnlHOX/r2RAUS2em0fbQqV8H8KmSLDXvpJpTaT2KVfFeBEY3IdRyhOy" + "Yp1PKzK9MaXB+lKrBYjIMIIEyzCCA7OgAwIBAgIEPhy9tTANBgkqhkiG9w0B" + "AQUFADBpMQswCQYDVQQGEwJVUzEjMCEGA1UEChMaQWRvYmUgU3lzdGVtcyBJ" + "bmNvcnBvcmF0ZWQxHTAbBgNVBAsTFEFkb2JlIFRydXN0IFNlcnZpY2VzMRYw" + "FAYDVQQDEw1BZG9iZSBSb290IENBMB4XDTA0MDExNzAwMDMzOVoXDTE1MDEx" + "NTA4MDAwMFowRTELMAkGA1UEBhMCVVMxFjAUBgNVBAoTDUdlb1RydXN0IElu" + "Yy4xHjAcBgNVBAMTFUdlb1RydXN0IENBIGZvciBBZG9iZTCCASIwDQYJKoZI" + "hvcNAQEBBQADggEPADCCAQoCggEBAKfld+BkeFrnOYW8r9L1WygTDlTdSfrO" + "YvWS/Z6Ye5/l+HrBbOHqQCXBcSeCpz7kB2WdKMh1FOE4e9JlmICsHerBLdWk" + "emU+/PDb69zh8E0cLoDfxukF6oVPXj6WSThdSG7H9aXFzRr6S3XGCuvgl+Qw" + "DTLiLYW+ONF6DXwt3TQQtKReJjOJZk46ZZ0BvMStKyBaeB6DKZsmiIo89qso" + "13VDZINH2w1KvXg0ygDizoNtbvgAPFymwnsINS1klfQlcvn0x0RJm9bYQXK3" + "5GNZAgL3M7Lqrld0jMfIUaWvuHCLyivytRuzq1dJ7E8rmidjDEk/G+27pf13" + "fNZ7vR7M+IkCAwEAAaOCAZ0wggGZMBIGA1UdEwEB/wQIMAYBAf8CAQEwUAYD" + "VR0gBEkwRzBFBgkqhkiG9y8BAgEwODA2BggrBgEFBQcCARYqaHR0cHM6Ly93" + "d3cuYWRvYmUuY29tL21pc2MvcGtpL2Nkc19jcC5odG1sMBQGA1UdJQQNMAsG" + "CSqGSIb3LwEBBTCBsgYDVR0fBIGqMIGnMCKgIKAehhxodHRwOi8vY3JsLmFk" + "b2JlLmNvbS9jZHMuY3JsMIGAoH6gfKR6MHgxCzAJBgNVBAYTAlVTMSMwIQYD" + "VQQKExpBZG9iZSBTeXN0ZW1zIEluY29ycG9yYXRlZDEdMBsGA1UECxMUQWRv" + "YmUgVHJ1c3QgU2VydmljZXMxFjAUBgNVBAMTDUFkb2JlIFJvb3QgQ0ExDTAL" + "BgNVBAMTBENSTDEwCwYDVR0PBAQDAgEGMB8GA1UdIwQYMBaAFIK3OEqTqpsQ" + "74C72VTi8Q/7gJzeMB0GA1UdDgQWBBSrgFnDZYNtHX0TvRnD7BqPDUdqozAZ" + "BgkqhkiG9n0HQQAEDDAKGwRWNi4wAwIEkDANBgkqhkiG9w0BAQUFAAOCAQEA" + "PzlZLqIAjrFeEWEs0uC29YyJhkXOE9mf3YSaFGsITF+Gl1j0pajTjyH4R35Q" + "r3floW2q3HfNzTeZ90Jnr1DhVERD6zEMgJpCtJqVuk0sixuXJHghS/KicKf4" + "YXJJPx9epuIRF1siBRnznnF90svmOJMXApc0jGnYn3nQfk4kaShSnDaYaeYR" + "DJKcsiWhl6S5zfwS7Gg8hDeyckhMQKKWnlG1CQrwlSFisKCduoodwRtWgft8" + "kx13iyKK3sbalm6vnVc+5nufS4vI+TwMXoV63NqYaSroafBWk0nL53zGXPEy" + "+A69QhzEViJKn2Wgqt5gt++jMMNImbRObIqgfgF1VjCCBUwwggQ0oAMCAQIC" + "AgGDMA0GCSqGSIb3DQEBBQUAMEUxCzAJBgNVBAYTAlVTMRYwFAYDVQQKEw1H" + "ZW9UcnVzdCBJbmMuMR4wHAYDVQQDExVHZW9UcnVzdCBDQSBmb3IgQWRvYmUw" + "HhcNMDYwMzI0MTU0MjI5WhcNMDkwNDA2MTQ0MjI5WjBzMQswCQYDVQQGEwJV" + "UzELMAkGA1UECBMCTUExETAPBgNVBAoTCEdlb1RydXN0MR0wGwYDVQQDExRN" + "YXJrZXRpbmcgRGVwYXJ0bWVudDElMCMGCSqGSIb3DQEJARYWbWFya2V0aW5n" + "QGdlb3RydXN0LmNvbTCCASIwDQYJKoZIhvcNAQEBBQADggEPADCCAQoCggEB" + "ANmvajTO4XJvAU2nVcLmXeCnAQX7RZt+7+ML3InmqQ3LCGo1weop09zV069/" + "1x/Nmieol7laEzeXxd2ghjGzwfXafqQEqHn6+vBCvqdNPoSi63fSWhnuDVWp" + "KVDOYgxOonrXl+Cc43lu4zRSq+Pi5phhrjDWcH74a3/rdljUt4c4GFezFXfa" + "w2oTzWkxj2cTSn0Szhpr17+p66UNt8uknlhmu4q44Speqql2HwmCEnpLYJrK" + "W3fOq5D4qdsvsLR2EABLhrBezamLI3iGV8cRHOUTsbTMhWhv/lKfHAyf4XjA" + "z9orzvPN5jthhIfICOFq/nStTgakyL4Ln+nFAB/SMPkCAwEAAaOCAhYwggIS" + "MA4GA1UdDwEB/wQEAwIF4DCB5QYDVR0gAQH/BIHaMIHXMIHUBgkqhkiG9y8B" + "AgEwgcYwgZAGCCsGAQUFBwICMIGDGoGAVGhpcyBjZXJ0aWZpY2F0ZSBoYXMg" + "YmVlbiBpc3N1ZWQgaW4gYWNjb3JkYW5jZSB3aXRoIHRoZSBBY3JvYmF0IENy" + "ZWRlbnRpYWxzIENQUyBsb2NhdGVkIGF0IGh0dHA6Ly93d3cuZ2VvdHJ1c3Qu" + "Y29tL3Jlc291cmNlcy9jcHMwMQYIKwYBBQUHAgEWJWh0dHA6Ly93d3cuZ2Vv" + "dHJ1c3QuY29tL3Jlc291cmNlcy9jcHMwOgYDVR0fBDMwMTAvoC2gK4YpaHR0" + "cDovL2NybC5nZW90cnVzdC5jb20vY3Jscy9hZG9iZWNhMS5jcmwwHwYDVR0j" + "BBgwFoAUq4BZw2WDbR19E70Zw+wajw1HaqMwRAYIKwYBBQUHAQEEODA2MDQG" + "CCsGAQUFBzABhihodHRwOi8vYWRvYmUtb2NzcC5nZW90cnVzdC5jb20vcmVz" + "cG9uZGVyMBQGA1UdJQQNMAsGCSqGSIb3LwEBBTA8BgoqhkiG9y8BAQkBBC4w" + "LAIBAYYnaHR0cDovL2Fkb2JlLXRpbWVzdGFtcC5nZW90cnVzdC5jb20vdHNh" + "MBMGCiqGSIb3LwEBCQIEBTADAgEBMAwGA1UdEwQFMAMCAQAwDQYJKoZIhvcN" + "AQEFBQADggEBAAOhy6QxOo+i3h877fvDvTa0plGD2bIqK7wMdNqbMDoSWied" + "FIcgcBOIm2wLxOjZBAVj/3lDq59q2rnVeNnfXM0/N0MHI9TumHRjU7WNk9e4" + "+JfJ4M+c3anrWOG3NE5cICDVgles+UHjXetHWql/LlP04+K2ZOLb6LE2xGnI" + "YyLW9REzCYNAVF+/WkYdmyceHtaBZdbyVAJq0NAJPsfgY1pWcBo31Mr1fpX9" + "WrXNTYDCqMyxMImJTmN3iI68tkXlNrhweQoArKFqBysiBkXzG/sGKYY6tWKU" + "pzjLc3vIp/LrXC5zilROes8BSvwu1w9qQrJNcGwo7O4uijoNtyYil1Exgh1Q" + "MIIdTAIBATBLMEUxCzAJBgNVBAYTAlVTMRYwFAYDVQQKEw1HZW9UcnVzdCBJ" + "bmMuMR4wHAYDVQQDExVHZW9UcnVzdCBDQSBmb3IgQWRvYmUCAgGDMAkGBSsO" + "AwIaBQCgggxMMBgGCSqGSIb3DQEJAzELBgkqhkiG9w0BBwEwIwYJKoZIhvcN" + "AQkEMRYEFP4R6qIdpQJzWyzrqO8X1ZfJOgChMIIMCQYJKoZIhvcvAQEIMYIL" + "+jCCC/agggZ5MIIGdTCCA6gwggKQMA0GCSqGSIb3DQEBBQUAMEUxCzAJBgNV" + "BAYTAlVTMRYwFAYDVQQKEw1HZW9UcnVzdCBJbmMuMR4wHAYDVQQDExVHZW9U" + "cnVzdCBDQSBmb3IgQWRvYmUXDTA2MDQwNDE3NDAxMFoXDTA2MDQwNTE3NDAx" + "MFowggIYMBMCAgC5Fw0wNTEwMTEyMDM2MzJaMBICAVsXDTA0MTEwNDE1MDk0" + "MVowEwICALgXDTA1MTIxMjIyMzgzOFowEgIBWhcNMDQxMTA0MTUwOTMzWjAT" + "AgIA5hcNMDUwODI3MDQwOTM4WjATAgIAtxcNMDYwMTE2MTc1NTEzWjATAgIA" + "hhcNMDUxMjEyMjIzODU1WjATAgIAtRcNMDUwNzA2MTgzODQwWjATAgIA4BcN" + "MDYwMzIwMDc0ODM0WjATAgIAgRcNMDUwODAyMjIzMTE1WjATAgIA3xcNMDUx" + "MjEyMjIzNjUwWjASAgFKFw0wNDExMDQxNTA5MTZaMBICAUQXDTA0MTEwNDE1" + "MDg1M1owEgIBQxcNMDQxMDAzMDEwMDQwWjASAgFsFw0wNDEyMDYxOTQ0MzFa" + "MBMCAgEoFw0wNjAzMDkxMjA3MTJaMBMCAgEkFw0wNjAxMTYxNzU1MzRaMBIC" + "AWcXDTA1MDMxODE3NTYxNFowEwICAVEXDTA2MDEzMTExMjcxMVowEgIBZBcN" + "MDQxMTExMjI0ODQxWjATAgIA8RcNMDUwOTE2MTg0ODAxWjATAgIBThcNMDYw" + "MjIxMjAxMDM2WjATAgIAwRcNMDUxMjEyMjIzODE2WjASAgFiFw0wNTAxMTAx" + "NjE5MzRaMBICAWAXDTA1MDExMDE5MDAwNFowEwICAL4XDTA1MDUxNzE0NTYx" + "MFowDQYJKoZIhvcNAQEFBQADggEBAEKhRMS3wVho1U3EvEQJZC8+JlUngmZQ" + "A78KQbHPWNZWFlNvPuf/b0s7Lu16GfNHXh1QAW6Y5Hi1YtYZ3YOPyMd4Xugt" + "gCdumbB6xtKsDyN5RvTht6ByXj+CYlYqsL7RX0izJZ6mJn4fjMkqzPKNOjb8" + "kSn5T6rn93BjlATtCE8tPVOM8dnqGccRE0OV59+nDBXc90UMt5LdEbwaUOap" + "snVB0oLcNm8d/HnlVH6RY5LnDjrT4vwfe/FApZtTecEWsllVUXDjSpwfcfD/" + "476/lpGySB2otALqzImlA9R8Ok3hJ8dnF6hhQ5Oe6OJMnGYgdhkKbxsKkdib" + "tTVl3qmH5QAwggLFMIIBrQIBATANBgkqhkiG9w0BAQUFADBpMQswCQYDVQQG" + "EwJVUzEjMCEGA1UEChMaQWRvYmUgU3lzdGVtcyBJbmNvcnBvcmF0ZWQxHTAb" + "BgNVBAsTFEFkb2JlIFRydXN0IFNlcnZpY2VzMRYwFAYDVQQDEw1BZG9iZSBS" + "b290IENBFw0wNjAxMjcxODMzMzFaFw0wNzAxMjcwMDAwMDBaMIHeMCMCBD4c" + "vUAXDTAzMDEyMTIzNDY1NlowDDAKBgNVHRUEAwoBBDAjAgQ+HL1BFw0wMzAx" + "MjEyMzQ3MjJaMAwwCgYDVR0VBAMKAQQwIwIEPhy9YhcNMDMwMTIxMjM0NzQy" + "WjAMMAoGA1UdFQQDCgEEMCMCBD4cvWEXDTA0MDExNzAxMDg0OFowDDAKBgNV" + "HRUEAwoBBDAjAgQ+HL2qFw0wNDAxMTcwMTA5MDVaMAwwCgYDVR0VBAMKAQQw" + "IwIEPhy9qBcNMDQwMTE3MDEzOTI5WjAMMAoGA1UdFQQDCgEEoC8wLTAKBgNV" + "HRQEAwIBDzAfBgNVHSMEGDAWgBSCtzhKk6qbEO+Au9lU4vEP+4Cc3jANBgkq" + "hkiG9w0BAQUFAAOCAQEAwtXF9042wG39icUlsotn5tpE3oCusLb/hBpEONhx" + "OdfEQOq0w5hf/vqaxkcf71etA+KpbEUeSVaHMHRPhx/CmPrO9odE139dJdbt" + "9iqbrC9iZokFK3h/es5kg73xujLKd7C/u5ngJ4mwBtvhMLjFjF2vJhPKHL4C" + "IgMwdaUAhrcNzy16v+mw/VGJy3Fvc6oCESW1K9tvFW58qZSNXrMlsuidgunM" + "hPKG+z0SXVyCqL7pnqKiaGddcgujYGOSY4S938oVcfZeZQEODtSYGlzldojX" + "C1U1hCK5+tHAH0Ox/WqRBIol5VCZQwJftf44oG8oviYq52aaqSejXwmfT6zb" + "76GCBXUwggVxMIIFbQoBAKCCBWYwggViBgkrBgEFBQcwAQEEggVTMIIFTzCB" + "taIWBBS+8EpykfXdl4h3z7m/NZfdkAQQERgPMjAwNjA0MDQyMDIwMTVaMGUw" + "YzA7MAkGBSsOAwIaBQAEFEb4BuZYkbjBjOjT6VeA/00fBvQaBBT3fTSQniOp" + "BbHBSkz4xridlX0bsAICAYOAABgPMjAwNjA0MDQyMDIwMTVaoBEYDzIwMDYw" + "NDA1MDgyMDE1WqEjMCEwHwYJKwYBBQUHMAECBBIEEFqooq/R2WltD7TposkT" + "BhMwDQYJKoZIhvcNAQEFBQADgYEAMig6lty4b0JDsT/oanfQG5x6jVKPACpp" + "1UA9SJ0apJJa7LeIdDFmu5C2S/CYiKZm4A4P9cAu0YzgLHxE4r6Op+HfVlAG" + "6bzUe1P/hi1KCJ8r8wxOZAktQFPSzs85RAZwkHMfB0lP2e/h666Oye+Zf8VH" + "RaE+/xZ7aswE89HXoumgggQAMIID/DCCA/gwggLgoAMCAQICAXUwDQYJKoZI" + "hvcNAQEFBQAwRTELMAkGA1UEBhMCVVMxFjAUBgNVBAoTDUdlb1RydXN0IElu" + "Yy4xHjAcBgNVBAMTFUdlb1RydXN0IENBIGZvciBBZG9iZTAeFw0wNDEyMDIy" + "MTI1MzlaFw0wNjEyMzAyMTI1MzlaMEwxCzAJBgNVBAYTAlVTMRUwEwYDVQQK" + "EwxHZW9UcnVzdCBJbmMxJjAkBgNVBAMTHUdlb1RydXN0IEFkb2JlIE9DU1Ag" + "UmVzcG9uZGVyMIGfMA0GCSqGSIb3DQEBAQUAA4GNADCBiQKBgQDiCc1iG3Dt" + "TpB5Vdk4OcaEcyP46BnQMHf3esSTprar2SrXb0gDZ7TfIoFN8l9BH1pYpzZC" + "P3R2xKo+O9MMcUZCxqCbYVC6GcDd9vVRaE/N4Qh2bpvEOydDydaoqrGdZnMQ" + "tlt2ncj1sEuLMiqhtmi/O3rQs0yCGf+6e++6Gl5VKwIDAQABo4IBbjCCAWow" + "DgYDVR0PAQH/BAQDAgTwMIHlBgNVHSABAf8EgdowgdcwgdQGCSqGSIb3LwEC" + "ATCBxjCBkAYIKwYBBQUHAgIwgYMagYBUaGlzIGNlcnRpZmljYXRlIGhhcyBi" + "ZWVuIGlzc3VlZCBpbiBhY2NvcmRhbmNlIHdpdGggdGhlIEFjcm9iYXQgQ3Jl" + "ZGVudGlhbHMgQ1BTIGxvY2F0ZWQgYXQgaHR0cDovL3d3dy5nZW90cnVzdC5j" + "b20vcmVzb3VyY2VzL2NwczAxBggrBgEFBQcCARYlaHR0cDovL3d3dy5nZW90" + "cnVzdC5jb20vcmVzb3VyY2VzL2NwczATBgNVHSUEDDAKBggrBgEFBQcDCTA6" + "BgNVHR8EMzAxMC+gLaArhilodHRwOi8vY3JsLmdlb3RydXN0LmNvbS9jcmxz" + "L2Fkb2JlY2ExLmNybDAfBgNVHSMEGDAWgBSrgFnDZYNtHX0TvRnD7BqPDUdq" + "ozANBgkqhkiG9w0BAQUFAAOCAQEAQ0l/UEPs9fmK+5prC33SrU4bNekhAv8K" + "XMR4VWY4jGo9zURMVGr3Zi7Eblvr5H6T60aSYLA8txjyKmDplxsn8CKtCGiH" + "OOUW5PpgBexN8SMKoRl9YzaxLtysrYRjEIyYoTfEN89yVi2sCjPupm/F9CPR" + "O7EdKy0dm/f3C7ZmIbUFaIRzINDJOCpM5cGhmZ8m2yG4BxeZOmCSthKtLfvM" + "2U9MaH6kxhDTJYNzw5BElHg5jlld92drTWaO0lM6aPr/pc+gs9hOraBCtzYE" + "J40nhsSEtvuwVUE9vA+unNMT8dFtAcOvOPRiKYPF45RX9Rdy2C9jAc20SRwE" + "uw6b+7K0xjANBgkqhkiG9w0BAQEFAASCAQC7a4yICFGCEMPlJbydK5qLG3rV" + "sip7Ojjz9TB4nLhC2DgsIHds8jjdq2zguInluH2nLaBCVS+qxDVlTjgbI2cB" + "TaWS8nglC7nNjzkKAsa8vThA8FZUVXTW0pb74jNJJU2AA27bb4g+4WgunCrj" + "fpYp+QjDyMmdrJVqRmt5eQN+dpVxMS9oq+NrhOSEhyIb4/rejgNg9wnVK1ms" + "l5PxQ4x7kpm7+Ua41//owkJVWykRo4T1jo4eHEz1DolPykAaKie2VKH/sMqR" + "Spjh4E5biKJLOV9fKivZWKAXByXfwUbbMsJvz4v/2yVHFy9xP+tqB5ZbRoDK" + "k8PzUyCprozn+/22oYIPijCCD4YGCyqGSIb3DQEJEAIOMYIPdTCCD3EGCSqG" + "SIb3DQEHAqCCD2Iwgg9eAgEDMQswCQYFKw4DAhoFADCB+gYLKoZIhvcNAQkQ" + "AQSggeoEgecwgeQCAQEGAikCMCEwCQYFKw4DAhoFAAQUoT97qeCv3FXYaEcS" + "gY8patCaCA8CAiMHGA8yMDA2MDQwNDIwMjA1N1owAwIBPAEB/wIIO0yRre3L" + "8/6ggZCkgY0wgYoxCzAJBgNVBAYTAlVTMRYwFAYDVQQIEw1NYXNzYWNodXNl" + "dHRzMRAwDgYDVQQHEwdOZWVkaGFtMRUwEwYDVQQKEwxHZW9UcnVzdCBJbmMx" + "EzARBgNVBAsTClByb2R1Y3Rpb24xJTAjBgNVBAMTHGFkb2JlLXRpbWVzdGFt" + "cC5nZW90cnVzdC5jb22gggzJMIIDUTCCAjmgAwIBAgICAI8wDQYJKoZIhvcN" + "AQEFBQAwRTELMAkGA1UEBhMCVVMxFjAUBgNVBAoTDUdlb1RydXN0IEluYy4x" + "HjAcBgNVBAMTFUdlb1RydXN0IENBIGZvciBBZG9iZTAeFw0wNTAxMTAwMTI5" + "MTBaFw0xNTAxMTUwODAwMDBaMIGKMQswCQYDVQQGEwJVUzEWMBQGA1UECBMN" + "TWFzc2FjaHVzZXR0czEQMA4GA1UEBxMHTmVlZGhhbTEVMBMGA1UEChMMR2Vv" + "VHJ1c3QgSW5jMRMwEQYDVQQLEwpQcm9kdWN0aW9uMSUwIwYDVQQDExxhZG9i" + "ZS10aW1lc3RhbXAuZ2VvdHJ1c3QuY29tMIGfMA0GCSqGSIb3DQEBAQUAA4GN" + "ADCBiQKBgQDRbxJotLFPWQuuEDhKtOMaBUJepGxIvWxeahMbq1DVmqnk88+j" + "w/5lfPICPzQZ1oHrcTLSAFM7Mrz3pyyQKQKMqUyiemzuG/77ESUNfBNSUfAF" + "PdtHuDMU8Is8ABVnFk63L+wdlvvDIlKkE08+VTKCRdjmuBVltMpQ6QcLFQzm" + "AQIDAQABo4GIMIGFMDoGA1UdHwQzMDEwL6AtoCuGKWh0dHA6Ly9jcmwuZ2Vv" + "dHJ1c3QuY29tL2NybHMvYWRvYmVjYTEuY3JsMB8GA1UdIwQYMBaAFKuAWcNl" + "g20dfRO9GcPsGo8NR2qjMA4GA1UdDwEB/wQEAwIGwDAWBgNVHSUBAf8EDDAK" + "BggrBgEFBQcDCDANBgkqhkiG9w0BAQUFAAOCAQEAmnyXjdtX+F79Nf0KggTd" + "6YC2MQD9s09IeXTd8TP3rBmizfM+7f3icggeCGakNfPRmIUMLoa0VM5Kt37T" + "2X0TqzBWusfbKx7HnX4v1t/G8NJJlT4SShSHv+8bjjU4lUoCmW2oEcC5vXwP" + "R5JfjCyois16npgcO05ZBT+LLDXyeBijE6qWmwLDfEpLyILzVRmyU4IE7jvm" + "rgb3GXwDUvd3yQXGRRHbPCh3nj9hBGbuzyt7GnlqnEie3wzIyMG2ET/wvTX5" + "4BFXKNe7lDLvZj/MXvd3V7gMTSVW0kAszKao56LfrVTgp1VX3UBQYwmQqaoA" + "UwFezih+jEvjW6cYJo/ErDCCBKEwggOJoAMCAQICBD4cvSgwDQYJKoZIhvcN" + "AQEFBQAwaTELMAkGA1UEBhMCVVMxIzAhBgNVBAoTGkFkb2JlIFN5c3RlbXMg" + "SW5jb3Jwb3JhdGVkMR0wGwYDVQQLExRBZG9iZSBUcnVzdCBTZXJ2aWNlczEW" + "MBQGA1UEAxMNQWRvYmUgUm9vdCBDQTAeFw0wMzAxMDgyMzM3MjNaFw0yMzAx" + "MDkwMDA3MjNaMGkxCzAJBgNVBAYTAlVTMSMwIQYDVQQKExpBZG9iZSBTeXN0" + "ZW1zIEluY29ycG9yYXRlZDEdMBsGA1UECxMUQWRvYmUgVHJ1c3QgU2Vydmlj" + "ZXMxFjAUBgNVBAMTDUFkb2JlIFJvb3QgQ0EwggEiMA0GCSqGSIb3DQEBAQUA" + "A4IBDwAwggEKAoIBAQDMT1SE96ei5zNTfz+cEohrLJlHZ34PHrmtFIj5wxDY" + "HfDw1Z9pCi9ZNbDMbKlMnBWgn84gv6DPVOLgIGZFPzmGOH6cxI4HIsYk9gES" + "sDXfVeppkLDbhTce4k4HskKhahNpoGbqgJERWSqbCHlaIEQtyb1zOIs8L+BD" + "G12zC/CvNRop/u+mkt2BTJ09WY6tMTxAfpuRNgb84lyN0Y0m1VxFz69lP7Gq" + "0mKW9Kg46rpgQvT0HEo1Fc74TiJWD5UYxfiWn5/7sLd4JemAa73WCvDGdJSd" + "8w9Q25p3zktwgyONoMp4IERcPFRk8eqiMBmf6kwGTQZ4S16S3yLSyWezetIB" + "AgMBAAGjggFPMIIBSzARBglghkgBhvhCAQEEBAMCAAcwgY4GA1UdHwSBhjCB" + "gzCBgKB+oHykejB4MQswCQYDVQQGEwJVUzEjMCEGA1UEChMaQWRvYmUgU3lz" + "dGVtcyBJbmNvcnBvcmF0ZWQxHTAbBgNVBAsTFEFkb2JlIFRydXN0IFNlcnZp" + "Y2VzMRYwFAYDVQQDEw1BZG9iZSBSb290IENBMQ0wCwYDVQQDEwRDUkwxMCsG" + "A1UdEAQkMCKADzIwMDMwMTA4MjMzNzIzWoEPMjAyMzAxMDkwMDA3MjNaMAsG" + "A1UdDwQEAwIBBjAfBgNVHSMEGDAWgBSCtzhKk6qbEO+Au9lU4vEP+4Cc3jAd" + "BgNVHQ4EFgQUgrc4SpOqmxDvgLvZVOLxD/uAnN4wDAYDVR0TBAUwAwEB/zAd" + "BgkqhkiG9n0HQQAEEDAOGwhWNi4wOjQuMAMCBJAwDQYJKoZIhvcNAQEFBQAD" + "ggEBADLan0N1wfpvyW/bqx02Nz68YRk2twI8HSNZmGye7k2F51TIIB+n1Lvi" + "vwB3fSRrcC9cwTp2SbXT4COEKnFqIvPBJymYFfY1kOQETMONvJ9hHOf9JIzR" + "REOMFrqbTaXUNS+8Ec6991E3jZ+Q5BTxGD++6VkSNfkzkvOe4NVrmnGbmUvI" + "ccPhsWEJxOX6kfBCOjd9NPly6M2qYhwh6dX0ghDjewW2LWhWC35+kixvTXKC" + "DO1WdLKduastKx0QX9sndXCP/R3X4gKgeeUc5f+vZEBRLZ6bR9tCpXwfwqZI" + "sNe+kmlNpPYpV8V4ERjch1HKE7JinU8rMr0xpcH6UqsFiMgwggTLMIIDs6AD" + "AgECAgQ+HL21MA0GCSqGSIb3DQEBBQUAMGkxCzAJBgNVBAYTAlVTMSMwIQYD" + "VQQKExpBZG9iZSBTeXN0ZW1zIEluY29ycG9yYXRlZDEdMBsGA1UECxMUQWRv" + "YmUgVHJ1c3QgU2VydmljZXMxFjAUBgNVBAMTDUFkb2JlIFJvb3QgQ0EwHhcN" + "MDQwMTE3MDAwMzM5WhcNMTUwMTE1MDgwMDAwWjBFMQswCQYDVQQGEwJVUzEW" + "MBQGA1UEChMNR2VvVHJ1c3QgSW5jLjEeMBwGA1UEAxMVR2VvVHJ1c3QgQ0Eg" + "Zm9yIEFkb2JlMIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEAp+V3" + "4GR4Wuc5hbyv0vVbKBMOVN1J+s5i9ZL9nph7n+X4esFs4epAJcFxJ4KnPuQH" + "ZZ0oyHUU4Th70mWYgKwd6sEt1aR6ZT788Nvr3OHwTRwugN/G6QXqhU9ePpZJ" + "OF1Ibsf1pcXNGvpLdcYK6+CX5DANMuIthb440XoNfC3dNBC0pF4mM4lmTjpl" + "nQG8xK0rIFp4HoMpmyaIijz2qyjXdUNkg0fbDUq9eDTKAOLOg21u+AA8XKbC" + "ewg1LWSV9CVy+fTHREmb1thBcrfkY1kCAvczsuquV3SMx8hRpa+4cIvKK/K1" + "G7OrV0nsTyuaJ2MMST8b7bul/Xd81nu9Hsz4iQIDAQABo4IBnTCCAZkwEgYD" + "VR0TAQH/BAgwBgEB/wIBATBQBgNVHSAESTBHMEUGCSqGSIb3LwECATA4MDYG" + "CCsGAQUFBwIBFipodHRwczovL3d3dy5hZG9iZS5jb20vbWlzYy9wa2kvY2Rz" + "X2NwLmh0bWwwFAYDVR0lBA0wCwYJKoZIhvcvAQEFMIGyBgNVHR8Egaowgacw" + "IqAgoB6GHGh0dHA6Ly9jcmwuYWRvYmUuY29tL2Nkcy5jcmwwgYCgfqB8pHow" + "eDELMAkGA1UEBhMCVVMxIzAhBgNVBAoTGkFkb2JlIFN5c3RlbXMgSW5jb3Jw" + "b3JhdGVkMR0wGwYDVQQLExRBZG9iZSBUcnVzdCBTZXJ2aWNlczEWMBQGA1UE" + "AxMNQWRvYmUgUm9vdCBDQTENMAsGA1UEAxMEQ1JMMTALBgNVHQ8EBAMCAQYw" + "HwYDVR0jBBgwFoAUgrc4SpOqmxDvgLvZVOLxD/uAnN4wHQYDVR0OBBYEFKuA" + "WcNlg20dfRO9GcPsGo8NR2qjMBkGCSqGSIb2fQdBAAQMMAobBFY2LjADAgSQ" + "MA0GCSqGSIb3DQEBBQUAA4IBAQA/OVkuogCOsV4RYSzS4Lb1jImGRc4T2Z/d" + "hJoUawhMX4aXWPSlqNOPIfhHflCvd+Whbarcd83NN5n3QmevUOFUREPrMQyA" + "mkK0mpW6TSyLG5ckeCFL8qJwp/hhckk/H16m4hEXWyIFGfOecX3Sy+Y4kxcC" + "lzSMadifedB+TiRpKFKcNphp5hEMkpyyJaGXpLnN/BLsaDyEN7JySExAopae" + "UbUJCvCVIWKwoJ26ih3BG1aB+3yTHXeLIorextqWbq+dVz7me59Li8j5PAxe" + "hXrc2phpKuhp8FaTScvnfMZc8TL4Dr1CHMRWIkqfZaCq3mC376Mww0iZtE5s" + "iqB+AXVWMYIBgDCCAXwCAQEwSzBFMQswCQYDVQQGEwJVUzEWMBQGA1UEChMN" + "R2VvVHJ1c3QgSW5jLjEeMBwGA1UEAxMVR2VvVHJ1c3QgQ0EgZm9yIEFkb2Jl" + "AgIAjzAJBgUrDgMCGgUAoIGMMBoGCSqGSIb3DQEJAzENBgsqhkiG9w0BCRAB" + "BDAcBgkqhkiG9w0BCQUxDxcNMDYwNDA0MjAyMDU3WjAjBgkqhkiG9w0BCQQx" + "FgQUp7AnXBqoNcarvO7fMJut1og2U5AwKwYLKoZIhvcNAQkQAgwxHDAaMBgw" + "FgQU1dH4eZTNhgxdiSABrat6zsPdth0wDQYJKoZIhvcNAQEBBQAEgYCinr/F" + "rMiQz/MRm9ZD5YGcC0Qo2dRTPd0Aop8mZ4g1xAhKFLnp7lLsjCbkSDpVLDBh" + "cnCk7CV+3FT5hlvt8OqZlR0CnkSnCswLFhrppiWle6cpxlwGqyAteC8uKtQu" + "wjE5GtBKLcCOAzQYyyuNZZeB6oCZ+3mPhZ62FxrvvEGJCgAAAAAAAAAAAAAA" + "AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA" + "AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA" + "AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA" + "AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA" + "AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA" + "AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA" + "AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA" + "AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA" + "AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA=="); private final byte[] emptyDNCert = Base64.decode( "MIICfTCCAeagAwIBAgIBajANBgkqhkiG9w0BAQQFADB8MQswCQYDVQQGEwJVUzEMMAoGA1UEChMD" + "Q0RXMQkwBwYDVQQLEwAxCTAHBgNVBAcTADEJMAcGA1UECBMAMRowGAYDVQQDExFUZW1wbGFyIFRl" + "c3QgMTAyNDEiMCAGCSqGSIb3DQEJARYTdGVtcGxhcnRlc3RAY2R3LmNvbTAeFw0wNjA1MjIwNTAw" + "MDBaFw0xMDA1MjIwNTAwMDBaMHwxCzAJBgNVBAYTAlVTMQwwCgYDVQQKEwNDRFcxCTAHBgNVBAsT" + "ADEJMAcGA1UEBxMAMQkwBwYDVQQIEwAxGjAYBgNVBAMTEVRlbXBsYXIgVGVzdCAxMDI0MSIwIAYJ" + "KoZIhvcNAQkBFhN0ZW1wbGFydGVzdEBjZHcuY29tMIGfMA0GCSqGSIb3DQEBAQUAA4GNADCBiQKB" + "gQDH3aJpJBfM+A3d84j5YcU6zEQaQ76u5xO9NSBmHjZykKS2kCcUqPpvVOPDA5WgV22dtKPh+lYV" + "iUp7wyCVwAKibq8HIbihHceFqMKzjwC639rMoDJ7bi/yzQWz1Zg+075a4FGPlUKn7Yfu89wKkjdW" + "wDpRPXc/agqBnrx5pJTXzQIDAQABow8wDTALBgNVHQ8EBAMCALEwDQYJKoZIhvcNAQEEBQADgYEA" + "RRsRsjse3i2/KClFVd6YLZ+7K1BE0WxFyY2bbytkwQJSxvv3vLSuweFUbhNxutb68wl/yW4GLy4b" + "1QdyswNxrNDXTuu5ILKhRDDuWeocz83aG2KGtr3JlFyr3biWGEyn5WUOE6tbONoQDJ0oPYgI6CAc" + "EHdUp0lioOCt6UOw7Cs="); private final byte[] gostRFC4491_94 = Base64.decode( "MIICCzCCAboCECMO42BGlSTOxwvklBgufuswCAYGKoUDAgIEMGkxHTAbBgNVBAMM" + "FEdvc3RSMzQxMC05NCBleGFtcGxlMRIwEAYDVQQKDAlDcnlwdG9Qcm8xCzAJBgNV" + "BAYTAlJVMScwJQYJKoZIhvcNAQkBFhhHb3N0UjM0MTAtOTRAZXhhbXBsZS5jb20w" + "HhcNMDUwODE2MTIzMjUwWhcNMTUwODE2MTIzMjUwWjBpMR0wGwYDVQQDDBRHb3N0" + "UjM0MTAtOTQgZXhhbXBsZTESMBAGA1UECgwJQ3J5cHRvUHJvMQswCQYDVQQGEwJS" + "VTEnMCUGCSqGSIb3DQEJARYYR29zdFIzNDEwLTk0QGV4YW1wbGUuY29tMIGlMBwG" + "BiqFAwICFDASBgcqhQMCAiACBgcqhQMCAh4BA4GEAASBgLuEZuF5nls02CyAfxOo" + "GWZxV/6MVCUhR28wCyd3RpjG+0dVvrey85NsObVCNyaE4g0QiiQOHwxCTSs7ESuo" + "v2Y5MlyUi8Go/htjEvYJJYfMdRv05YmKCYJo01x3pg+2kBATjeM+fJyR1qwNCCw+" + "eMG1wra3Gqgqi0WBkzIydvp7MAgGBiqFAwICBANBABHHCH4S3ALxAiMpR3aPRyqB" + "g1DjB8zy5DEjiULIc+HeIveF81W9lOxGkZxnrFjXBSqnjLeFKgF1hffXOAP7zUM="); private final byte[] gostRFC4491_2001 = Base64.decode( "MIIB0DCCAX8CECv1xh7CEb0Xx9zUYma0LiEwCAYGKoUDAgIDMG0xHzAdBgNVBAMM" + "Fkdvc3RSMzQxMC0yMDAxIGV4YW1wbGUxEjAQBgNVBAoMCUNyeXB0b1BybzELMAkG" + "A1UEBhMCUlUxKTAnBgkqhkiG9w0BCQEWGkdvc3RSMzQxMC0yMDAxQGV4YW1wbGUu" + "Y29tMB4XDTA1MDgxNjE0MTgyMFoXDTE1MDgxNjE0MTgyMFowbTEfMB0GA1UEAwwW" + "R29zdFIzNDEwLTIwMDEgZXhhbXBsZTESMBAGA1UECgwJQ3J5cHRvUHJvMQswCQYD" + "VQQGEwJSVTEpMCcGCSqGSIb3DQEJARYaR29zdFIzNDEwLTIwMDFAZXhhbXBsZS5j" + "b20wYzAcBgYqhQMCAhMwEgYHKoUDAgIkAAYHKoUDAgIeAQNDAARAhJVodWACGkB1" + "CM0TjDGJLP3lBQN6Q1z0bSsP508yfleP68wWuZWIA9CafIWuD+SN6qa7flbHy7Df" + "D2a8yuoaYDAIBgYqhQMCAgMDQQA8L8kJRLcnqeyn1en7U23Sw6pkfEQu3u0xFkVP" + "vFQ/3cHeF26NG+xxtZPz3TaTVXdoiYkXYiD02rEx1bUcM97i"); private PublicKey dudPublicKey = new PublicKey() { public String getAlgorithm() { return null; } public String getFormat() { return null; } public byte[] getEncoded() { return null; } }; public String getName() { return "CertTest"; } public void checkCertificate( int id, byte[] bytes) { ByteArrayInputStream bIn; String dump = ""; try { bIn = new ByteArrayInputStream(bytes); CertificateFactory fact = CertificateFactory.getInstance("X.509", "BC"); Certificate cert = fact.generateCertificate(bIn); PublicKey k = cert.getPublicKey(); // System.out.println(cert); } catch (Exception e) { fail(dump + System.getProperty("line.separator") + getName() + ": "+ id + " failed - exception " + e.toString(), e); } } public void checkNameCertificate( int id, byte[] bytes) { ByteArrayInputStream bIn; String dump = ""; try { bIn = new ByteArrayInputStream(bytes); CertificateFactory fact = CertificateFactory.getInstance("X.509", "BC"); X509Certificate cert = (X509Certificate)fact.generateCertificate(bIn); PublicKey k = cert.getPublicKey(); if (!cert.getIssuerDN().toString().equals("C=DE,O=DATEV eG,0.2.262.1.10.7.20=1+CN=CA DATEV D03 1:PN")) { fail(id + " failed - name test."); } // System.out.println(cert); } catch (Exception e) { fail(dump + System.getProperty("line.separator") + getName() + ": "+ id + " failed - exception " + e.toString(), e); } } public void checkKeyUsage( int id, byte[] bytes) { ByteArrayInputStream bIn; String dump = ""; try { bIn = new ByteArrayInputStream(bytes); CertificateFactory fact = CertificateFactory.getInstance("X.509", "BC"); X509Certificate cert = (X509Certificate)fact.generateCertificate(bIn); PublicKey k = cert.getPublicKey(); if (cert.getKeyUsage()[7]) { fail("error generating cert - key usage wrong."); } // System.out.println(cert); } catch (Exception e) { fail(dump + System.getProperty("line.separator") + getName() + ": "+ id + " failed - exception " + e.toString(), e); } } public void checkSelfSignedCertificate( int id, byte[] bytes) { ByteArrayInputStream bIn; String dump = ""; try { bIn = new ByteArrayInputStream(bytes); CertificateFactory fact = CertificateFactory.getInstance("X.509", "BC"); Certificate cert = fact.generateCertificate(bIn); PublicKey k = cert.getPublicKey(); cert.verify(k); // System.out.println(cert); } catch (Exception e) { fail(dump + System.getProperty("line.separator") + getName() + ": "+ id + " failed - exception " + e.toString(), e); } } /** * Test a generated certificate with the sun provider */ private void sunProviderCheck(byte[] encoding) throws CertificateException { CertificateFactory certFact = CertificateFactory.getInstance("X.509"); certFact.generateCertificate(new ByteArrayInputStream(encoding)); } /** * we generate a self signed certificate for the sake of testing - RSA */ public void checkCreation1() throws Exception { // // a sample key pair. // RSAPublicKeySpec pubKeySpec = new RSAPublicKeySpec( new BigInteger("b4a7e46170574f16a97082b22be58b6a2a629798419be12872a4bdba626cfae9900f76abfb12139dce5de56564fab2b6543165a040c606887420e33d91ed7ed7", 16), new BigInteger("11", 16)); RSAPrivateCrtKeySpec privKeySpec = new RSAPrivateCrtKeySpec( new BigInteger("b4a7e46170574f16a97082b22be58b6a2a629798419be12872a4bdba626cfae9900f76abfb12139dce5de56564fab2b6543165a040c606887420e33d91ed7ed7", 16), new BigInteger("11", 16), new BigInteger("9f66f6b05410cd503b2709e88115d55daced94d1a34d4e32bf824d0dde6028ae79c5f07b580f5dce240d7111f7ddb130a7945cd7d957d1920994da389f490c89", 16), new BigInteger("c0a0758cdf14256f78d4708c86becdead1b50ad4ad6c5c703e2168fbf37884cb", 16), new BigInteger("f01734d7960ea60070f1b06f2bb81bfac48ff192ae18451d5e56c734a5aab8a5", 16), new BigInteger("b54bb9edff22051d9ee60f9351a48591b6500a319429c069a3e335a1d6171391", 16), new BigInteger("d3d83daf2a0cecd3367ae6f8ae1aeb82e9ac2f816c6fc483533d8297dd7884cd", 16), new BigInteger("b8f52fc6f38593dabb661d3f50f8897f8106eee68b1bce78a95b132b4e5b5d19", 16)); // // set up the keys // PrivateKey privKey; PublicKey pubKey; KeyFactory fact = KeyFactory.getInstance("RSA", "BC"); privKey = fact.generatePrivate(privKeySpec); pubKey = fact.generatePublic(pubKeySpec); // // distinguished name table. // X500NameBuilder builder = new X500NameBuilder(BCStyle.INSTANCE); builder.addRDN(BCStyle.C, "AU"); builder.addRDN(BCStyle.O, "The Legion of the Bouncy Castle"); builder.addRDN(BCStyle.L, "Melbourne"); builder.addRDN(BCStyle.ST, "Victoria"); builder.addRDN(BCStyle.E, "feedback-crypto@bouncycastle.org"); // // extensions // // // create the certificate - version 3 - without extensions // ContentSigner sigGen = new JcaContentSignerBuilder("SHA256WithRSAEncryption").setProvider(BC).build(privKey); X509v3CertificateBuilder certGen = new JcaX509v3CertificateBuilder(builder.build(), BigInteger.valueOf(1), new Date(System.currentTimeMillis() - 50000), new Date(System.currentTimeMillis() + 50000),builder.build(), pubKey); X509Certificate cert = new JcaX509CertificateConverter().setProvider(BC).getCertificate(certGen.build(sigGen)); cert.checkValidity(new Date()); cert.verify(pubKey); cert.verify(cert.getPublicKey()); Set dummySet = cert.getNonCriticalExtensionOIDs(); if (dummySet != null) { fail("non-critical oid set should be null"); } dummySet = cert.getCriticalExtensionOIDs(); if (dummySet != null) { fail("critical oid set should be null"); } // // create the certificate - version 3 - with extensions // sigGen = new JcaContentSignerBuilder("MD5WithRSAEncryption").setProvider(BC).build(privKey); certGen = new JcaX509v3CertificateBuilder(builder.build(), BigInteger.valueOf(1) , new Date(System.currentTimeMillis() - 50000) , new Date(System.currentTimeMillis() + 50000) , builder.build() , pubKey) .addExtension(new ASN1ObjectIdentifier("2.5.29.15"), true, new X509KeyUsage(X509KeyUsage.encipherOnly)) .addExtension(new ASN1ObjectIdentifier("2.5.29.37"), true, new DERSequence(KeyPurposeId.anyExtendedKeyUsage)) .addExtension(new ASN1ObjectIdentifier("2.5.29.17"), true, new GeneralNames(new GeneralName[] { new GeneralName(GeneralName.rfc822Name, "test@test.test"), new GeneralName(GeneralName.dNSName, "dom.test.test") })); X509CertificateHolder certHolder = certGen.build(sigGen); cert = new JcaX509CertificateConverter().setProvider(BC).getCertificate(certHolder); cert.checkValidity(new Date()); cert.verify(pubKey); cert.verify(cert.getPublicKey()); ContentVerifierProvider contentVerifierProvider = new JcaContentVerifierProviderBuilder().setProvider(BC).build(pubKey); if (!certHolder.isSignatureValid(contentVerifierProvider)) { fail("signature test failed"); } ByteArrayInputStream bIn = new ByteArrayInputStream(cert.getEncoded()); CertificateFactory certFact = CertificateFactory.getInstance("X.509", "BC"); cert = (X509Certificate)certFact.generateCertificate(bIn); if (!cert.getKeyUsage()[7]) { fail("error generating cert - key usage wrong."); } /* List l = cert.getExtendedKeyUsage(); if (!l.get(0).equals(KeyPurposeId.anyExtendedKeyUsage.getId())) { fail("failed extended key usage test"); } Collection c = cert.getSubjectAlternativeNames(); Iterator it = c.iterator(); while (it.hasNext()) { List gn = (List)it.next(); if (!gn.get(1).equals("test@test.test") && !gn.get(1).equals("dom.test.test")) { fail("failed subject alternative names test"); } } */ sunProviderCheck(certHolder.getEncoded()); sunProviderCheck(cert.getEncoded()); // System.out.println(cert); // // create the certificate - version 1 // sigGen = new JcaContentSignerBuilder("MD5WithRSAEncryption").setProvider(BC).build(privKey); X509v1CertificateBuilder certGen1 = new JcaX509v1CertificateBuilder(builder.build(), BigInteger.valueOf(1), new Date(System.currentTimeMillis() - 50000),new Date(System.currentTimeMillis() + 50000),builder.build(),pubKey); cert = new JcaX509CertificateConverter().setProvider(BC).getCertificate(certGen1.build(sigGen)); cert.checkValidity(new Date()); cert.verify(pubKey); cert.verify(cert.getPublicKey()); bIn = new ByteArrayInputStream(cert.getEncoded()); certFact = CertificateFactory.getInstance("X.509", "BC"); cert = (X509Certificate)certFact.generateCertificate(bIn); // System.out.println(cert); if (!cert.getIssuerDN().equals(cert.getSubjectDN())) { fail("name comparison fails"); } sunProviderCheck(certHolder.getEncoded()); sunProviderCheck(cert.getEncoded()); // // a lightweight key pair. // RSAKeyParameters lwPubKey = new RSAKeyParameters( false, new BigInteger("b4a7e46170574f16a97082b22be58b6a2a629798419be12872a4bdba626cfae9900f76abfb12139dce5de56564fab2b6543165a040c606887420e33d91ed7ed7", 16), new BigInteger("11", 16)); RSAPrivateCrtKeyParameters lwPrivKey = new RSAPrivateCrtKeyParameters( new BigInteger("b4a7e46170574f16a97082b22be58b6a2a629798419be12872a4bdba626cfae9900f76abfb12139dce5de56564fab2b6543165a040c606887420e33d91ed7ed7", 16), new BigInteger("11", 16), new BigInteger("9f66f6b05410cd503b2709e88115d55daced94d1a34d4e32bf824d0dde6028ae79c5f07b580f5dce240d7111f7ddb130a7945cd7d957d1920994da389f490c89", 16), new BigInteger("c0a0758cdf14256f78d4708c86becdead1b50ad4ad6c5c703e2168fbf37884cb", 16), new BigInteger("f01734d7960ea60070f1b06f2bb81bfac48ff192ae18451d5e56c734a5aab8a5", 16), new BigInteger("b54bb9edff22051d9ee60f9351a48591b6500a319429c069a3e335a1d6171391", 16), new BigInteger("d3d83daf2a0cecd3367ae6f8ae1aeb82e9ac2f816c6fc483533d8297dd7884cd", 16), new BigInteger("b8f52fc6f38593dabb661d3f50f8897f8106eee68b1bce78a95b132b4e5b5d19", 16)); // // distinguished name table. // builder = new X500NameBuilder(BCStyle.INSTANCE); builder.addRDN(BCStyle.C, "AU"); builder.addRDN(BCStyle.O, "The Legion of the Bouncy Castle"); builder.addRDN(BCStyle.L, "Melbourne"); builder.addRDN(BCStyle.ST, "Victoria"); builder.addRDN(BCStyle.E, "feedback-crypto@bouncycastle.org"); // // extensions // // // create the certificate - version 3 - without extensions // AlgorithmIdentifier sigAlgId = new DefaultSignatureAlgorithmIdentifierFinder().find("SHA256WithRSAEncryption"); AlgorithmIdentifier digAlgId = new DefaultDigestAlgorithmIdentifierFinder().find(sigAlgId); sigGen = new BcRSAContentSignerBuilder(sigAlgId, digAlgId).build(lwPrivKey); SubjectPublicKeyInfo pubInfo = new SubjectPublicKeyInfo(new AlgorithmIdentifier(PKCSObjectIdentifiers.rsaEncryption, DERNull.INSTANCE), new RSAPublicKey(lwPubKey.getModulus(), lwPubKey.getExponent())); certGen = new X509v3CertificateBuilder(builder.build(), BigInteger.valueOf(1), new Date(System.currentTimeMillis() - 50000), new Date(System.currentTimeMillis() + 50000), builder.build(), pubInfo); certHolder = certGen.build(sigGen); cert = new JcaX509CertificateConverter().setProvider(BC).getCertificate(certHolder); cert.checkValidity(new Date()); cert.verify(pubKey); contentVerifierProvider = new BcRSAContentVerifierProviderBuilder(new DefaultDigestAlgorithmIdentifierFinder()).build(lwPubKey); if (!certHolder.isSignatureValid(contentVerifierProvider)) { fail("lw sig verification failed"); } } /** * we generate a self signed certificate for the sake of testing - DSA */ public void checkCreation2() throws Exception { // // set up the keys // PrivateKey privKey; PublicKey pubKey; try { KeyPairGenerator g = KeyPairGenerator.getInstance("DSA", "SUN"); g.initialize(512, new SecureRandom()); KeyPair p = g.generateKeyPair(); privKey = p.getPrivate(); pubKey = p.getPublic(); } catch (Exception e) { fail("error setting up keys - " + e.toString()); return; } // // distinguished name table. // X500NameBuilder builder = createStdBuilder(); // // extensions // // // create the certificate - version 3 // ContentSigner sigGen = new JcaContentSignerBuilder("SHA1withDSA").setProvider(BC).build(privKey); JcaX509v3CertificateBuilder certGen = new JcaX509v3CertificateBuilder(builder.build(),BigInteger.valueOf(1),new Date(System.currentTimeMillis() - 50000),new Date(System.currentTimeMillis() + 50000),builder.build(),pubKey); X509Certificate cert = new JcaX509CertificateConverter().setProvider(BC).getCertificate(certGen.build(sigGen)); cert.checkValidity(new Date()); cert.verify(pubKey); ByteArrayInputStream bIn = new ByteArrayInputStream(cert.getEncoded()); CertificateFactory fact = CertificateFactory.getInstance("X.509", BC); cert = (X509Certificate)fact.generateCertificate(bIn); // System.out.println(cert); // // create the certificate - version 1 // sigGen = new JcaContentSignerBuilder("SHA1withDSA").setProvider(BC).build(privKey); JcaX509v1CertificateBuilder certGen1 = new JcaX509v1CertificateBuilder(builder.build(),BigInteger.valueOf(1),new Date(System.currentTimeMillis() - 50000),new Date(System.currentTimeMillis() + 50000),builder.build(),pubKey); cert = new JcaX509CertificateConverter().setProvider(BC).getCertificate(certGen1.build(sigGen)); cert.checkValidity(new Date()); cert.verify(pubKey); bIn = new ByteArrayInputStream(cert.getEncoded()); fact = CertificateFactory.getInstance("X.509", BC); cert = (X509Certificate)fact.generateCertificate(bIn); //System.out.println(cert); // // exception test // try { certGen1 = new JcaX509v1CertificateBuilder(builder.build(),BigInteger.valueOf(1),new Date(System.currentTimeMillis() - 50000),new Date(System.currentTimeMillis() + 50000),builder.build(),dudPublicKey); fail("key without encoding not detected in v1"); } catch (IllegalArgumentException e) { // expected } } private X500NameBuilder createStdBuilder() { X500NameBuilder builder = new X500NameBuilder(BCStyle.INSTANCE); builder.addRDN(BCStyle.C, "AU"); builder.addRDN(BCStyle.O, "The Legion of the Bouncy Castle"); builder.addRDN(BCStyle.L, "Melbourne"); builder.addRDN(BCStyle.ST, "Victoria"); builder.addRDN(BCStyle.E, "feedback-crypto@bouncycastle.org"); return builder; } /** * we generate a self signed certificate for the sake of testing - ECDSA */ public void checkCreation3() { ECCurve curve = new ECCurve.Fp( new BigInteger("883423532389192164791648750360308885314476597252960362792450860609699839"), // q new BigInteger("7fffffffffffffffffffffff7fffffffffff8000000000007ffffffffffc", 16), // a new BigInteger("6b016c3bdcf18941d0d654921475ca71a9db2fb27d1d37796185c2942c0a", 16)); // b ECParameterSpec spec = new ECParameterSpec( curve, curve.decodePoint(Hex.decode("020ffa963cdca8816ccc33b8642bedf905c3d358573d3f27fbbd3b3cb9aaaf")), // G new BigInteger("883423532389192164791648750360308884807550341691627752275345424702807307")); // n ECPrivateKeySpec privKeySpec = new ECPrivateKeySpec( new BigInteger("876300101507107567501066130761671078357010671067781776716671676178726717"), // d spec); ECPublicKeySpec pubKeySpec = new ECPublicKeySpec( curve.decodePoint(Hex.decode("025b6dc53bc61a2548ffb0f671472de6c9521a9d2d2534e65abfcbd5fe0c70")), // Q spec); // // set up the keys // PrivateKey privKey; PublicKey pubKey; try { KeyFactory fact = KeyFactory.getInstance("ECDSA", BC); privKey = fact.generatePrivate(privKeySpec); pubKey = fact.generatePublic(pubKeySpec); } catch (Exception e) { fail("error setting up keys - " + e.toString()); return; } // // distinguished name table. // X500NameBuilder builder = createStdBuilder(); // // toString test // X500Name p = builder.build(); String s = p.toString(); if (!s.equals("C=AU,O=The Legion of the Bouncy Castle,L=Melbourne,ST=Victoria,E=feedback-crypto@bouncycastle.org")) { fail("ordered X509Principal test failed - s = " + s + "."); } // p = new X509Principal(attrs); // s = p.toString(); // // // // // we need two of these as the hash code for strings changed... // // // if (!s.equals("O=The Legion of the Bouncy Castle,E=feedback-crypto@bouncycastle.org,ST=Victoria,L=Melbourne,C=AU") && !s.equals("ST=Victoria,L=Melbourne,C=AU,E=feedback-crypto@bouncycastle.org,O=The Legion of the Bouncy Castle")) // { // fail("unordered X509Principal test failed."); // } // // create the certificate - version 3 // try { ContentSigner sigGen = new JcaContentSignerBuilder("SHA1withECDSA").setProvider(BC).build(privKey); JcaX509v3CertificateBuilder certGen = new JcaX509v3CertificateBuilder(builder.build(),BigInteger.valueOf(1),new Date(System.currentTimeMillis() - 50000),new Date(System.currentTimeMillis() + 50000),builder.build(),pubKey); X509Certificate cert = new JcaX509CertificateConverter().setProvider(BC).getCertificate(certGen.build(sigGen)); cert.checkValidity(new Date()); cert.verify(pubKey); ByteArrayInputStream bIn = new ByteArrayInputStream(cert.getEncoded()); CertificateFactory fact = CertificateFactory.getInstance("X.509", BC); cert = (X509Certificate)fact.generateCertificate(bIn); // // try with point compression turned off // ((ECPointEncoder)pubKey).setPointFormat("UNCOMPRESSED"); certGen = new JcaX509v3CertificateBuilder(builder.build(),BigInteger.valueOf(1),new Date(System.currentTimeMillis() - 50000),new Date(System.currentTimeMillis() + 50000),builder.build(),pubKey); cert = new JcaX509CertificateConverter().setProvider(BC).getCertificate(certGen.build(sigGen)); cert.checkValidity(new Date()); cert.verify(pubKey); bIn = new ByteArrayInputStream(cert.getEncoded()); fact = CertificateFactory.getInstance("X.509", BC); cert = (X509Certificate)fact.generateCertificate(bIn); // System.out.println(cert); } catch (Exception e) { fail("error setting generating cert - " + e.toString()); } X509Principal pr = new X509Principal("O=\"The Bouncy Castle, The Legion of\",E=feedback-crypto@bouncycastle.org,ST=Victoria,L=Melbourne,C=AU"); if (!pr.toString().equals("O=The Bouncy Castle\\, The Legion of,E=feedback-crypto@bouncycastle.org,ST=Victoria,L=Melbourne,C=AU")) { fail("string based X509Principal test failed."); } pr = new X509Principal("O=The Bouncy Castle\\, The Legion of,E=feedback-crypto@bouncycastle.org,ST=Victoria,L=Melbourne,C=AU"); if (!pr.toString().equals("O=The Bouncy Castle\\, The Legion of,E=feedback-crypto@bouncycastle.org,ST=Victoria,L=Melbourne,C=AU")) { fail("string based X509Principal test failed."); } } /** * we generate a self signed certificate for the sake of testing - SHA224withECDSA */ private void createECCert(String algorithm, DERObjectIdentifier algOid) throws Exception { ECCurve.Fp curve = new ECCurve.Fp( new BigInteger("6864797660130609714981900799081393217269435300143305409394463459185543183397656052122559640661454554977296311391480858037121987999716643812574028291115057151"), // q (or p) new BigInteger("01FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFC", 16), // a new BigInteger("0051953EB9618E1C9A1F929A21A0B68540EEA2DA725B99B315F3B8B489918EF109E156193951EC7E937B1652C0BD3BB1BF073573DF883D2C34F1EF451FD46B503F00", 16)); // b ECParameterSpec spec = new ECParameterSpec( curve, curve.decodePoint(Hex.decode("0200C6858E06B70404E9CD9E3ECB662395B4429C648139053FB521F828AF606B4D3DBAA14B5E77EFE75928FE1DC127A2FFA8DE3348B3C1856A429BF97E7E31C2E5BD66")), // G new BigInteger("01FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFA51868783BF2F966B7FCC0148F709A5D03BB5C9B8899C47AEBB6FB71E91386409", 16)); // n ECPrivateKeySpec privKeySpec = new ECPrivateKeySpec( new BigInteger("5769183828869504557786041598510887460263120754767955773309066354712783118202294874205844512909370791582896372147797293913785865682804434049019366394746072023"), // d spec); ECPublicKeySpec pubKeySpec = new ECPublicKeySpec( curve.decodePoint(Hex.decode("02006BFDD2C9278B63C92D6624F151C9D7A822CC75BD983B17D25D74C26740380022D3D8FAF304781E416175EADF4ED6E2B47142D2454A7AC7801DD803CF44A4D1F0AC")), // Q spec); // // set up the keys // PrivateKey privKey; PublicKey pubKey; KeyFactory fact = KeyFactory.getInstance("ECDSA", BC); privKey = fact.generatePrivate(privKeySpec); pubKey = fact.generatePublic(pubKeySpec); // // distinguished name table. // X500NameBuilder builder = createStdBuilder(); // // create the certificate - version 3 // ContentSigner sigGen = new JcaContentSignerBuilder(algorithm).setProvider(BC).build(privKey); X509v3CertificateBuilder certGen = new JcaX509v3CertificateBuilder(builder.build(),BigInteger.valueOf(1),new Date(System.currentTimeMillis() - 50000),new Date(System.currentTimeMillis() + 50000),builder.build(),pubKey); X509Certificate cert = new JcaX509CertificateConverter().setProvider(BC).getCertificate(certGen.build(sigGen)); cert.checkValidity(new Date()); cert.verify(pubKey); ByteArrayInputStream bIn = new ByteArrayInputStream(cert.getEncoded()); CertificateFactory certFact = CertificateFactory.getInstance("X.509", BC); cert = (X509Certificate)certFact.generateCertificate(bIn); // // try with point compression turned off // ((ECPointEncoder)pubKey).setPointFormat("UNCOMPRESSED"); certGen = new JcaX509v3CertificateBuilder(builder.build(),BigInteger.valueOf(1),new Date(System.currentTimeMillis() - 50000),new Date(System.currentTimeMillis() + 50000),builder.build(),pubKey); cert = new JcaX509CertificateConverter().setProvider(BC).getCertificate(certGen.build(sigGen)); cert.checkValidity(new Date()); cert.verify(pubKey); bIn = new ByteArrayInputStream(cert.getEncoded()); certFact = CertificateFactory.getInstance("X.509", BC); cert = (X509Certificate)certFact.generateCertificate(bIn); if (!cert.getSigAlgOID().equals(algOid.toString())) { fail("ECDSA oid incorrect."); } if (cert.getSigAlgParams() != null) { fail("sig parameters present"); } Signature sig = Signature.getInstance(algorithm, BC); sig.initVerify(pubKey); sig.update(cert.getTBSCertificate()); if (!sig.verify(cert.getSignature())) { fail("EC certificate signature not mapped correctly."); } // System.out.println(cert); } private void checkCRL( int id, byte[] bytes) { ByteArrayInputStream bIn; String dump = ""; try { bIn = new ByteArrayInputStream(bytes); CertificateFactory fact = CertificateFactory.getInstance("X.509", BC); CRL cert = fact.generateCRL(bIn); // System.out.println(cert); } catch (Exception e) { fail(dump + System.getProperty("line.separator") + getName() + ": "+ id + " failed - exception " + e.toString(), e); } } public void checkCRLCreation1() throws Exception { KeyPairGenerator kpGen = KeyPairGenerator.getInstance("RSA", BC); Date now = new Date(); KeyPair pair = kpGen.generateKeyPair(); X509v2CRLBuilder crlGen = new X509v2CRLBuilder(new X500Name("CN=Test CA"), now); crlGen.setNextUpdate(new Date(now.getTime() + 100000)); crlGen.addCRLEntry(BigInteger.valueOf(1), now, CRLReason.privilegeWithdrawn); crlGen.addExtension(X509Extensions.AuthorityKeyIdentifier, false, new AuthorityKeyIdentifierStructure(pair.getPublic())); X509CRLHolder crl = crlGen.build(new JcaContentSignerBuilder("SHA256withRSAEncryption").setProvider(BC).build(pair.getPrivate())); if (!crl.getIssuer().equals(new X500Name("CN=Test CA"))) { fail("failed CRL issuer test"); } Extension authExt = crl.getExtension(Extension.authorityKeyIdentifier); if (authExt == null) { fail("failed to find CRL extension"); } AuthorityKeyIdentifier authId = new AuthorityKeyIdentifierStructure(authExt); X509CRLEntryHolder entry = crl.getRevokedCertificate(BigInteger.valueOf(1)); if (entry == null) { fail("failed to find CRL entry"); } if (!entry.getSerialNumber().equals(BigInteger.valueOf(1))) { fail("CRL cert serial number does not match"); } if (!entry.hasExtensions()) { fail("CRL entry extension not found"); } Extension ext = entry.getExtension(X509Extension.reasonCode); if (ext != null) { ASN1Enumerated reasonCode = (ASN1Enumerated)ASN1Enumerated.getInstance(ext.getParsedValue()); if (reasonCode.getValue().intValue() != CRLReason.privilegeWithdrawn) { fail("CRL entry reasonCode wrong"); } } else { fail("CRL entry reasonCode not found"); } } public void checkCRLCreation2() throws Exception { KeyPairGenerator kpGen = KeyPairGenerator.getInstance("RSA", BC); Date now = new Date(); KeyPair pair = kpGen.generateKeyPair(); X509v2CRLBuilder crlGen = new X509v2CRLBuilder(new X500Name("CN=Test CA"), now); crlGen.setNextUpdate(new Date(now.getTime() + 100000)); Vector extOids = new Vector(); Vector extValues = new Vector(); CRLReason crlReason = CRLReason.lookup(CRLReason.privilegeWithdrawn); try { extOids.addElement(X509Extensions.ReasonCode); extValues.addElement(new X509Extension(false, new DEROctetString(crlReason.getEncoded()))); } catch (IOException e) { throw new IllegalArgumentException("error encoding reason: " + e); } X509Extensions entryExtensions = new X509Extensions(extOids, extValues); crlGen.addCRLEntry(BigInteger.valueOf(1), now, entryExtensions); crlGen.addExtension(X509Extensions.AuthorityKeyIdentifier, false, new AuthorityKeyIdentifierStructure(pair.getPublic())); X509CRLHolder crlHolder = crlGen.build(new JcaContentSignerBuilder("SHA256withRSAEncryption").setProvider(BC).build(pair.getPrivate())); X509CRL crl = new JcaX509CRLConverter().setProvider(BC).getCRL(crlHolder); if (!PrincipalUtil.getIssuerX509Principal(crl).equals(new X509Principal("CN=Test CA"))) { fail("failed CRL issuer test"); } byte[] authExt = crl.getExtensionValue(X509Extensions.AuthorityKeyIdentifier.getId()); if (authExt == null) { fail("failed to find CRL extension"); } AuthorityKeyIdentifier authId = new AuthorityKeyIdentifierStructure(authExt); X509CRLEntry entry = crl.getRevokedCertificate(BigInteger.valueOf(1)); if (entry == null) { fail("failed to find CRL entry"); } if (!entry.getSerialNumber().equals(BigInteger.valueOf(1))) { fail("CRL cert serial number does not match"); } if (!entry.hasExtensions()) { fail("CRL entry extension not found"); } byte[] ext = entry.getExtensionValue(X509Extensions.ReasonCode.getId()); if (ext != null) { DEREnumerated reasonCode = (DEREnumerated)X509ExtensionUtil.fromExtensionValue(ext); if (reasonCode.getValue().intValue() != CRLReason.privilegeWithdrawn) { fail("CRL entry reasonCode wrong"); } } else { fail("CRL entry reasonCode not found"); } } public void checkCRLCreation3() throws Exception { KeyPairGenerator kpGen = KeyPairGenerator.getInstance("RSA", BC); Date now = new Date(); KeyPair pair = kpGen.generateKeyPair(); X509v2CRLBuilder crlGen = new JcaX509v2CRLBuilder(new X500Name("CN=Test CA"), now); crlGen.setNextUpdate(new Date(now.getTime() + 100000)); Vector extOids = new Vector(); Vector extValues = new Vector(); CRLReason crlReason = CRLReason.lookup(CRLReason.privilegeWithdrawn); try { extOids.addElement(X509Extensions.ReasonCode); extValues.addElement(new X509Extension(false, new DEROctetString(crlReason.getEncoded()))); } catch (IOException e) { throw new IllegalArgumentException("error encoding reason: " + e); } X509Extensions entryExtensions = new X509Extensions(extOids, extValues); crlGen.addCRLEntry(BigInteger.valueOf(1), now, entryExtensions); crlGen.addExtension(X509Extensions.AuthorityKeyIdentifier, false, new AuthorityKeyIdentifierStructure(pair.getPublic())); X509CRLHolder crlHolder = crlGen.build(new JcaContentSignerBuilder("SHA256withRSAEncryption").setProvider(BC).build(pair.getPrivate())); X509CRL crl = new JcaX509CRLConverter().setProvider(BC).getCRL(crlHolder); if (!PrincipalUtil.getIssuerX509Principal(crl).equals(new X509Principal("CN=Test CA"))) { fail("failed CRL issuer test"); } byte[] authExt = crl.getExtensionValue(X509Extensions.AuthorityKeyIdentifier.getId()); if (authExt == null) { fail("failed to find CRL extension"); } AuthorityKeyIdentifier authId = new AuthorityKeyIdentifierStructure(authExt); X509CRLEntry entry = crl.getRevokedCertificate(BigInteger.valueOf(1)); if (entry == null) { fail("failed to find CRL entry"); } if (!entry.getSerialNumber().equals(BigInteger.valueOf(1))) { fail("CRL cert serial number does not match"); } if (!entry.hasExtensions()) { fail("CRL entry extension not found"); } byte[] ext = entry.getExtensionValue(X509Extensions.ReasonCode.getId()); if (ext != null) { DEREnumerated reasonCode = (DEREnumerated)X509ExtensionUtil.fromExtensionValue(ext); if (reasonCode.getValue().intValue() != CRLReason.privilegeWithdrawn) { fail("CRL entry reasonCode wrong"); } } else { fail("CRL entry reasonCode not found"); } // // check loading of existing CRL // now = new Date(); crlGen = new X509v2CRLBuilder(new X500Name("CN=Test CA"), now); crlGen.setNextUpdate(new Date(now.getTime() + 100000)); crlGen.addCRL(new JcaX509CRLHolder(crl)); crlGen.addCRLEntry(BigInteger.valueOf(2), now, entryExtensions); crlGen.addExtension(X509Extension.authorityKeyIdentifier, false, new AuthorityKeyIdentifierStructure(pair.getPublic())); crlHolder = crlGen.build(new JcaContentSignerBuilder("SHA256withRSAEncryption").setProvider(BC).build(pair.getPrivate())); int count = 0; boolean oneFound = false; boolean twoFound = false; Iterator it = crlHolder.getRevokedCertificates().iterator(); while (it.hasNext()) { X509CRLEntryHolder crlEnt = (X509CRLEntryHolder)it.next(); if (crlEnt.getSerialNumber().intValue() == 1) { oneFound = true; Extension extn = crlEnt.getExtension(X509Extension.reasonCode); if (extn != null) { ASN1Enumerated reasonCode = (ASN1Enumerated)ASN1Enumerated.getInstance(extn.getParsedValue()); if (reasonCode.getValue().intValue() != CRLReason.privilegeWithdrawn) { fail("CRL entry reasonCode wrong"); } } else { fail("CRL entry reasonCode not found"); } } else if (crlEnt.getSerialNumber().intValue() == 2) { twoFound = true; } count++; } if (count != 2) { fail("wrong number of CRLs found"); } if (!oneFound || !twoFound) { fail("wrong CRLs found in copied list"); } // // check factory read back // CertificateFactory cFact = CertificateFactory.getInstance("X.509", BC); X509CRL readCrl = (X509CRL)cFact.generateCRL(new ByteArrayInputStream(crlHolder.getEncoded())); if (readCrl == null) { fail("crl not returned!"); } Collection col = cFact.generateCRLs(new ByteArrayInputStream(crlHolder.getEncoded())); if (col.size() != 1) { fail("wrong number of CRLs found in collection"); } } /** * we generate a self signed certificate for the sake of testing - GOST3410 */ public void checkCreation4() throws Exception { // // set up the keys // PrivateKey privKey; PublicKey pubKey; KeyPairGenerator g = KeyPairGenerator.getInstance("GOST3410", BC); GOST3410ParameterSpec gost3410P = new GOST3410ParameterSpec("GostR3410-94-CryptoPro-A"); g.initialize(gost3410P, new SecureRandom()); KeyPair p = g.generateKeyPair(); privKey = p.getPrivate(); pubKey = p.getPublic(); // // distinguished name table. // X500NameBuilder builder = createStdBuilder(); // // extensions // // // create the certificate - version 3 // ContentSigner sigGen = new JcaContentSignerBuilder("GOST3411withGOST3410").setProvider(BC).build(privKey); X509v3CertificateBuilder certGen = new JcaX509v3CertificateBuilder(builder.build(),BigInteger.valueOf(1),new Date(System.currentTimeMillis() - 50000),new Date(System.currentTimeMillis() + 50000),builder.build(),pubKey); X509Certificate cert = new JcaX509CertificateConverter().setProvider(BC).getCertificate(certGen.build(sigGen)); cert.checkValidity(new Date()); // // check verifies in general // cert.verify(pubKey); // // check verifies with contained key // cert.verify(cert.getPublicKey()); ByteArrayInputStream bIn = new ByteArrayInputStream(cert.getEncoded()); CertificateFactory fact = CertificateFactory.getInstance("X.509", BC); cert = (X509Certificate)fact.generateCertificate(bIn); //System.out.println(cert); //check getEncoded() byte[] bytes = cert.getEncoded(); } public void checkCreation5() throws Exception { // // a sample key pair. // RSAPublicKeySpec pubKeySpec = new RSAPublicKeySpec( new BigInteger("b4a7e46170574f16a97082b22be58b6a2a629798419be12872a4bdba626cfae9900f76abfb12139dce5de56564fab2b6543165a040c606887420e33d91ed7ed7", 16), new BigInteger("11", 16)); RSAPrivateCrtKeySpec privKeySpec = new RSAPrivateCrtKeySpec( new BigInteger("b4a7e46170574f16a97082b22be58b6a2a629798419be12872a4bdba626cfae9900f76abfb12139dce5de56564fab2b6543165a040c606887420e33d91ed7ed7", 16), new BigInteger("11", 16), new BigInteger("9f66f6b05410cd503b2709e88115d55daced94d1a34d4e32bf824d0dde6028ae79c5f07b580f5dce240d7111f7ddb130a7945cd7d957d1920994da389f490c89", 16), new BigInteger("c0a0758cdf14256f78d4708c86becdead1b50ad4ad6c5c703e2168fbf37884cb", 16), new BigInteger("f01734d7960ea60070f1b06f2bb81bfac48ff192ae18451d5e56c734a5aab8a5", 16), new BigInteger("b54bb9edff22051d9ee60f9351a48591b6500a319429c069a3e335a1d6171391", 16), new BigInteger("d3d83daf2a0cecd3367ae6f8ae1aeb82e9ac2f816c6fc483533d8297dd7884cd", 16), new BigInteger("b8f52fc6f38593dabb661d3f50f8897f8106eee68b1bce78a95b132b4e5b5d19", 16)); // // set up the keys // SecureRandom rand = new SecureRandom(); PrivateKey privKey; PublicKey pubKey; KeyFactory fact = KeyFactory.getInstance("RSA", BC); privKey = fact.generatePrivate(privKeySpec); pubKey = fact.generatePublic(pubKeySpec); // // distinguished name table. // Vector ord = new Vector(); Vector values = new Vector(); X500NameBuilder builder = createStdBuilder(); // // create base certificate - version 3 // ContentSigner sigGen = new JcaContentSignerBuilder("MD5WithRSAEncryption").setProvider(BC).build(privKey); X509v3CertificateBuilder certGen = new JcaX509v3CertificateBuilder(builder.build(),BigInteger.valueOf(1),new Date(System.currentTimeMillis() - 50000),new Date(System.currentTimeMillis() + 50000),builder.build(),pubKey) .addExtension(new ASN1ObjectIdentifier("2.5.29.15"), true, new X509KeyUsage(X509KeyUsage.encipherOnly)) .addExtension(new ASN1ObjectIdentifier("2.5.29.37"), true, new DERSequence(KeyPurposeId.anyExtendedKeyUsage)) .addExtension(new ASN1ObjectIdentifier("2.5.29.17"), true, new GeneralNames(new GeneralName(GeneralName.rfc822Name, "test@test.test"))); X509Certificate baseCert = new JcaX509CertificateConverter().setProvider(BC).getCertificate(certGen.build(sigGen)); // // copy certificate // certGen = new JcaX509v3CertificateBuilder(builder.build(),BigInteger.valueOf(1),new Date(System.currentTimeMillis() - 50000),new Date(System.currentTimeMillis() + 50000),builder.build(),pubKey) .copyAndAddExtension(new ASN1ObjectIdentifier("2.5.29.15"), true, baseCert) .copyAndAddExtension(new ASN1ObjectIdentifier("2.5.29.37"), false, baseCert); X509Certificate cert = new JcaX509CertificateConverter().setProvider(BC).getCertificate(certGen.build(sigGen)); cert.checkValidity(new Date()); cert.verify(pubKey); if (!areEqual(baseCert.getExtensionValue("2.5.29.15"), cert.getExtensionValue("2.5.29.15"))) { fail("2.5.29.15 differs"); } if (!areEqual(baseCert.getExtensionValue("2.5.29.37"), cert.getExtensionValue("2.5.29.37"))) { fail("2.5.29.37 differs"); } // // exception test // try { certGen.copyAndAddExtension(new ASN1ObjectIdentifier("2.5.99.99"), true, new JcaX509CertificateHolder(baseCert)); fail("exception not thrown on dud extension copy"); } catch (NullPointerException e) { // expected } // try // { // certGen.setPublicKey(dudPublicKey); // // certGen.generate(privKey, BC); // // fail("key without encoding not detected in v3"); // } // catch (IllegalArgumentException e) // { // // expected // } } private void testForgedSignature() throws Exception { String cert = "MIIBsDCCAVoCAQYwDQYJKoZIhvcNAQEFBQAwYzELMAkGA1UEBhMCQVUxEzARBgNV" + "BAgTClF1ZWVuc2xhbmQxGjAYBgNVBAoTEUNyeXB0U29mdCBQdHkgTHRkMSMwIQYD" + "VQQDExpTZXJ2ZXIgdGVzdCBjZXJ0ICg1MTIgYml0KTAeFw0wNjA5MTEyMzU4NTVa" + "Fw0wNjEwMTEyMzU4NTVaMGMxCzAJBgNVBAYTAkFVMRMwEQYDVQQIEwpRdWVlbnNs" + "YW5kMRowGAYDVQQKExFDcnlwdFNvZnQgUHR5IEx0ZDEjMCEGA1UEAxMaU2VydmVy" + "IHRlc3QgY2VydCAoNTEyIGJpdCkwXDANBgkqhkiG9w0BAQEFAANLADBIAkEAn7PD" + "hCeV/xIxUg8V70YRxK2A5jZbD92A12GN4PxyRQk0/lVmRUNMaJdq/qigpd9feP/u" + "12S4PwTLb/8q/v657QIDAQABMA0GCSqGSIb3DQEBBQUAA0EAbynCRIlUQgaqyNgU" + "DF6P14yRKUtX8akOP2TwStaSiVf/akYqfLFm3UGka5XbPj4rifrZ0/sOoZEEBvHQ" + "e20sRA=="; CertificateFactory certFact = CertificateFactory.getInstance("X.509", BC); X509Certificate x509 = (X509Certificate)certFact.generateCertificate(new ByteArrayInputStream(Base64.decode(cert))); try { x509.verify(x509.getPublicKey()); fail("forged RSA signature passed"); } catch (Exception e) { // expected } } private void pemTest() throws Exception { CertificateFactory cf = CertificateFactory.getInstance("X.509", BC); Certificate cert = readPEMCert(cf, PEMData.CERTIFICATE_1); if (cert == null) { fail("PEM cert not read"); } cert = readPEMCert(cf, "-----BEGIN CERTIFICATE-----" + PEMData.CERTIFICATE_2); if (cert == null) { fail("PEM cert with extraneous header not read"); } CRL crl = cf.generateCRL(new ByteArrayInputStream(PEMData.CRL_1.getBytes("US-ASCII"))); if (crl == null) { fail("PEM crl not read"); } Collection col = cf.generateCertificates(new ByteArrayInputStream(PEMData.CERTIFICATE_2.getBytes("US-ASCII"))); if (col.size() != 1 || !col.contains(cert)) { fail("PEM cert collection not right"); } col = cf.generateCRLs(new ByteArrayInputStream(PEMData.CRL_2.getBytes("US-ASCII"))); if (col.size() != 1 || !col.contains(crl)) { fail("PEM crl collection not right"); } } private static Certificate readPEMCert(CertificateFactory cf, String pemData) throws CertificateException, UnsupportedEncodingException { return cf.generateCertificate(new ByteArrayInputStream(pemData.getBytes("US-ASCII"))); } private void pkcs7Test() throws Exception { /* ASN1EncodableVector certs = new ASN1EncodableVector(); certs.add(new ASN1InputStream(CertPathTest.rootCertBin).readObject()); certs.add(new DERTaggedObject(false, 2, new ASN1InputStream(AttrCertTest.attrCert).readObject())); ASN1EncodableVector crls = new ASN1EncodableVector(); crls.add(new ASN1InputStream(CertPathTest.rootCrlBin).readObject()); SignedData sigData = new SignedData(new DERSet(), new ContentInfo(CMSObjectIdentifiers.data, null), new DERSet(certs), new DERSet(crls), new DERSet()); ContentInfo info = new ContentInfo(CMSObjectIdentifiers.signedData, sigData); CertificateFactory cf = CertificateFactory.getInstance("X.509", BC); X509Certificate cert = (X509Certificate)cf.generateCertificate(new ByteArrayInputStream(info.getEncoded())); if (cert == null || !areEqual(cert.getEncoded(), certs.get(0).getDERObject().getEncoded())) { fail("PKCS7 cert not read"); } X509CRL crl = (X509CRL)cf.generateCRL(new ByteArrayInputStream(info.getEncoded())); if (crl == null || !areEqual(crl.getEncoded(), crls.get(0).getDERObject().getEncoded())) { fail("PKCS7 crl not read"); } Collection col = cf.generateCertificates(new ByteArrayInputStream(info.getEncoded())); if (col.size() != 1 || !col.contains(cert)) { fail("PKCS7 cert collection not right"); } col = cf.generateCRLs(new ByteArrayInputStream(info.getEncoded())); if (col.size() != 1 || !col.contains(crl)) { fail("PKCS7 crl collection not right"); } // data with no certificates or CRLs sigData = new SignedData(new DERSet(), new ContentInfo(CMSObjectIdentifiers.data, null), new DERSet(), new DERSet(), new DERSet()); info = new ContentInfo(CMSObjectIdentifiers.signedData, sigData); cert = (X509Certificate)cf.generateCertificate(new ByteArrayInputStream(info.getEncoded())); if (cert != null) { fail("PKCS7 cert present"); } crl = (X509CRL)cf.generateCRL(new ByteArrayInputStream(info.getEncoded())); if (crl != null) { fail("PKCS7 crl present"); } // data with absent certificates and CRLS sigData = new SignedData(new DERSet(), new ContentInfo(CMSObjectIdentifiers.data, null), null, null, new DERSet()); info = new ContentInfo(CMSObjectIdentifiers.signedData, sigData); cert = (X509Certificate)cf.generateCertificate(new ByteArrayInputStream(info.getEncoded())); if (cert != null) { fail("PKCS7 cert present"); } crl = (X509CRL)cf.generateCRL(new ByteArrayInputStream(info.getEncoded())); if (crl != null) { fail("PKCS7 crl present"); } // // sample message // InputStream in = new ByteArrayInputStream(pkcs7CrlProblem); Collection certCol = cf.generateCertificates(in); Collection crlCol = cf.generateCRLs(in); if (crlCol.size() != 0) { fail("wrong number of CRLs: " + crlCol.size()); } if (certCol.size() != 4) { fail("wrong number of Certs: " + certCol.size()); } */ } private void createPSSCert(String algorithm) throws Exception { KeyPair pair = generateLongFixedKeys(); PrivateKey privKey = pair.getPrivate(); PublicKey pubKey = pair.getPublic(); // // distinguished name table. // X500NameBuilder builder = createStdBuilder(); // // create base certificate - version 3 // ContentSigner sigGen = new JcaContentSignerBuilder(algorithm).setProvider(BC).build(privKey); JcaX509v3CertificateBuilder certGen = new JcaX509v3CertificateBuilder(builder.build(),BigInteger.valueOf(1), new Date(System.currentTimeMillis() - 50000),new Date(System.currentTimeMillis() + 50000),builder.build(),pubKey); certGen.addExtension(new ASN1ObjectIdentifier("2.5.29.15"), true, new X509KeyUsage(X509KeyUsage.encipherOnly)); certGen.addExtension(new ASN1ObjectIdentifier("2.5.29.37"), true, new DERSequence(KeyPurposeId.anyExtendedKeyUsage)); certGen.addExtension(new ASN1ObjectIdentifier("2.5.29.17"), true, new GeneralNames(new GeneralName(GeneralName.rfc822Name, "test@test.test"))); X509Certificate baseCert = new JcaX509CertificateConverter().setProvider(BC).getCertificate(certGen.build(sigGen)); baseCert.verify(pubKey); } private KeyPair generateLongFixedKeys() throws NoSuchAlgorithmException, NoSuchProviderException, InvalidKeySpecException { RSAPublicKeySpec pubKeySpec = new RSAPublicKeySpec( new BigInteger("a56e4a0e701017589a5187dc7ea841d156f2ec0e36ad52a44dfeb1e61f7ad991d8c51056ffedb162b4c0f283a12a88a394dff526ab7291cbb307ceabfce0b1dfd5cd9508096d5b2b8b6df5d671ef6377c0921cb23c270a70e2598e6ff89d19f105acc2d3f0cb35f29280e1386b6f64c4ef22e1e1f20d0ce8cffb2249bd9a2137",16), new BigInteger("010001",16)); RSAPrivateCrtKeySpec privKeySpec = new RSAPrivateCrtKeySpec( new BigInteger("a56e4a0e701017589a5187dc7ea841d156f2ec0e36ad52a44dfeb1e61f7ad991d8c51056ffedb162b4c0f283a12a88a394dff526ab7291cbb307ceabfce0b1dfd5cd9508096d5b2b8b6df5d671ef6377c0921cb23c270a70e2598e6ff89d19f105acc2d3f0cb35f29280e1386b6f64c4ef22e1e1f20d0ce8cffb2249bd9a2137",16), new BigInteger("010001",16), new BigInteger("33a5042a90b27d4f5451ca9bbbd0b44771a101af884340aef9885f2a4bbe92e894a724ac3c568c8f97853ad07c0266c8c6a3ca0929f1e8f11231884429fc4d9ae55fee896a10ce707c3ed7e734e44727a39574501a532683109c2abacaba283c31b4bd2f53c3ee37e352cee34f9e503bd80c0622ad79c6dcee883547c6a3b325",16), new BigInteger("e7e8942720a877517273a356053ea2a1bc0c94aa72d55c6e86296b2dfc967948c0a72cbccca7eacb35706e09a1df55a1535bd9b3cc34160b3b6dcd3eda8e6443",16), new BigInteger("b69dca1cf7d4d7ec81e75b90fcca874abcde123fd2700180aa90479b6e48de8d67ed24f9f19d85ba275874f542cd20dc723e6963364a1f9425452b269a6799fd",16), new BigInteger("28fa13938655be1f8a159cbaca5a72ea190c30089e19cd274a556f36c4f6e19f554b34c077790427bbdd8dd3ede2448328f385d81b30e8e43b2fffa027861979",16), new BigInteger("1a8b38f398fa712049898d7fb79ee0a77668791299cdfa09efc0e507acb21ed74301ef5bfd48be455eaeb6e1678255827580a8e4e8e14151d1510a82a3f2e729",16), new BigInteger("27156aba4126d24a81f3a528cbfb27f56886f840a9f6e86e17a44b94fe9319584b8e22fdde1e5a2e3bd8aa5ba8d8584194eb2190acf832b847f13a3d24a79f4d",16)); KeyFactory fact = KeyFactory.getInstance("RSA", BC); return new KeyPair(fact.generatePublic(pubKeySpec), fact.generatePrivate(privKeySpec)); } private void rfc4491Test() throws Exception { CertificateFactory certFact = CertificateFactory.getInstance("X.509", BC); X509Certificate x509 = (X509Certificate)certFact.generateCertificate(new ByteArrayInputStream(gostRFC4491_94)); x509.verify(x509.getPublicKey(), BC); x509 = (X509Certificate)certFact.generateCertificate(new ByteArrayInputStream(gostRFC4491_2001)); x509.verify(x509.getPublicKey(), BC); } private void testNullDerNullCert() throws Exception { KeyPair pair = generateLongFixedKeys(); PublicKey pubKey = pair.getPublic(); PrivateKey privKey = pair.getPrivate(); ContentSigner sigGen = new JcaContentSignerBuilder("MD5WithRSAEncryption").setProvider(BC).build(privKey); JcaX509v3CertificateBuilder certGen = new JcaX509v3CertificateBuilder(new X500Name("CN=Test"),BigInteger.valueOf(1),new Date(System.currentTimeMillis() - 50000),new Date(System.currentTimeMillis() + 50000),new X500Name("CN=Test"),pubKey); X509Certificate cert = new JcaX509CertificateConverter().setProvider(BC).getCertificate(certGen.build(sigGen)); X509CertificateStructure struct = X509CertificateStructure.getInstance(ASN1Primitive.fromByteArray(cert.getEncoded())); ASN1Encodable tbsCertificate = struct.getTBSCertificate(); AlgorithmIdentifier sig = struct.getSignatureAlgorithm(); ASN1EncodableVector v = new ASN1EncodableVector(); v.add(tbsCertificate); v.add(new AlgorithmIdentifier(sig.getAlgorithm())); v.add(struct.getSignature()); // verify ByteArrayInputStream bIn; String dump = ""; try { bIn = new ByteArrayInputStream(new DERSequence(v).getEncoded()); CertificateFactory fact = CertificateFactory.getInstance("X.509", BC); cert = (X509Certificate)fact.generateCertificate(bIn); cert.verify(cert.getPublicKey()); } catch (Exception e) { fail(dump + System.getProperty("line.separator") + getName() + ": testNullDerNull failed - exception " + e.toString(), e); } } private void testDirect() throws Exception { KeyStore keyStore = KeyStore.getInstance("PKCS12", "BC"); ByteArrayInputStream input = new ByteArrayInputStream(testCAp12); keyStore.load(input, "test".toCharArray()); X509Certificate certificate = (X509Certificate) keyStore.getCertificate("ca"); PrivateKey privateKey = (PrivateKey) keyStore.getKey("ca", null); X500Name issuer = X500Name.getInstance(PrincipalUtil.getIssuerX509Principal(certificate).getEncoded()); X509v2CRLBuilder builder = new X509v2CRLBuilder(issuer, new Date()); builder.addCRLEntry(certificate.getSerialNumber(), new Date(), CRLReason.cACompromise); JcaContentSignerBuilder contentSignerBuilder = new JcaContentSignerBuilder("SHA256WithRSAEncryption"); contentSignerBuilder.setProvider("BC"); X509CRLHolder cRLHolder = builder.build(contentSignerBuilder.build(privateKey)); JcaX509CRLConverter converter = new JcaX509CRLConverter(); converter.setProvider("BC"); X509CRL crl = converter.getCRL(cRLHolder); crl.verify(certificate.getPublicKey()); if (!crl.isRevoked(certificate)) { fail("Certificate should be revoked"); } // now encode the CRL and load the CRL with the JCE provider CertificateFactory fac = CertificateFactory.getInstance("X.509"); X509CRL jceCRL = (X509CRL) fac.generateCRL(new ByteArrayInputStream(crl.getEncoded())); jceCRL.verify(certificate.getPublicKey()); if (!jceCRL.isRevoked(certificate)) { fail("This certificate should also be revoked"); } } private void testIndirect() throws Exception { KeyStore keyStore = KeyStore.getInstance("PKCS12", "BC"); ByteArrayInputStream input = new ByteArrayInputStream(testCAp12); keyStore.load(input, "test".toCharArray()); X509Certificate certificate = (X509Certificate) keyStore.getCertificate("ca"); PrivateKey privateKey = (PrivateKey) keyStore.getKey("ca", null); X500Name crlIssuer = X500Name.getInstance(PrincipalUtil.getSubjectX509Principal(certificate).getEncoded()); X500Name caName = X500Name.getInstance(PrincipalUtil.getIssuerX509Principal(certificate).getEncoded()); X509v2CRLBuilder builder = new X509v2CRLBuilder(crlIssuer, new Date()); builder.addExtension(Extension.issuingDistributionPoint, true, new IssuingDistributionPoint(null, true, false)); ExtensionsGenerator extGen = new ExtensionsGenerator(); extGen.addExtension(Extension.reasonCode, false, CRLReason.lookup(CRLReason.cACompromise)); extGen.addExtension(Extension.certificateIssuer, true, new GeneralNames(new GeneralName(caName))); builder.addCRLEntry(certificate.getSerialNumber(), new Date(), extGen.generate()); JcaContentSignerBuilder contentSignerBuilder = new JcaContentSignerBuilder("SHA256WithRSAEncryption"); contentSignerBuilder.setProvider("BC"); X509CRLHolder cRLHolder = builder.build(contentSignerBuilder.build(privateKey)); JcaX509CRLConverter converter = new JcaX509CRLConverter(); converter.setProvider("BC"); X509CRL crl = converter.getCRL(cRLHolder); crl.verify(certificate.getPublicKey()); if (!crl.isRevoked(certificate)) { fail("Certificate should be revoked"); } // now encode the CRL and load the CRL with the JCE provider CertificateFactory fac = CertificateFactory.getInstance("X.509"); X509CRL jceCRL = (X509CRL) fac.generateCRL(new ByteArrayInputStream(crl.getEncoded())); jceCRL.verify(certificate.getPublicKey()); if (!jceCRL.isRevoked(certificate)) { fail("This certificate should also be revoked"); } } // issuing distribution point must be set for an indirect CRL to be recognised private void testMalformedIndirect() throws Exception { KeyStore keyStore = KeyStore.getInstance("PKCS12", "BC"); ByteArrayInputStream input = new ByteArrayInputStream(testCAp12); keyStore.load(input, "test".toCharArray()); X509Certificate certificate = (X509Certificate) keyStore.getCertificate("ca"); PrivateKey privateKey = (PrivateKey) keyStore.getKey("ca", null); X500Name crlIssuer = X500Name.getInstance(PrincipalUtil.getSubjectX509Principal(certificate).getEncoded()); X500Name caName = X500Name.getInstance(PrincipalUtil.getIssuerX509Principal(certificate).getEncoded()); X509v2CRLBuilder builder = new X509v2CRLBuilder(crlIssuer, new Date()); ExtensionsGenerator extGen = new ExtensionsGenerator(); extGen.addExtension(Extension.reasonCode, false, CRLReason.lookup(CRLReason.cACompromise)); extGen.addExtension(Extension.certificateIssuer, true, new GeneralNames(new GeneralName(caName))); builder.addCRLEntry(certificate.getSerialNumber(), new Date(), extGen.generate()); JcaContentSignerBuilder contentSignerBuilder = new JcaContentSignerBuilder("SHA256WithRSAEncryption"); contentSignerBuilder.setProvider("BC"); X509CRLHolder cRLHolder = builder.build(contentSignerBuilder.build(privateKey)); JcaX509CRLConverter converter = new JcaX509CRLConverter(); converter.setProvider("BC"); X509CRL crl = converter.getCRL(cRLHolder); crl.verify(certificate.getPublicKey()); if (crl.isRevoked(certificate)) { throw new Exception("Certificate should not be revoked"); } } public void performTest() throws Exception { testDirect(); testIndirect(); testMalformedIndirect(); checkCertificate(1, cert1); checkCertificate(2, cert2); checkCertificate(3, cert3); checkCertificate(4, cert4); checkCertificate(5, cert5); checkCertificate(6, oldEcdsa); checkCertificate(7, cert7); checkKeyUsage(8, keyUsage); checkSelfSignedCertificate(9, uncompressedPtEC); checkNameCertificate(10, nameCert); checkSelfSignedCertificate(11, probSelfSignedCert); checkSelfSignedCertificate(12, gostCA1); checkSelfSignedCertificate(13, gostCA2); checkSelfSignedCertificate(14, gost341094base); checkSelfSignedCertificate(15, gost34102001base); checkSelfSignedCertificate(16, gost341094A); checkSelfSignedCertificate(17, gost341094B); checkSelfSignedCertificate(17, gost34102001A); checkCRL(1, crl1); checkCreation1(); checkCreation2(); checkCreation3(); checkCreation4(); checkCreation5(); createECCert("SHA1withECDSA", X9ObjectIdentifiers.ecdsa_with_SHA1); createECCert("SHA224withECDSA", X9ObjectIdentifiers.ecdsa_with_SHA224); createECCert("SHA256withECDSA", X9ObjectIdentifiers.ecdsa_with_SHA256); createECCert("SHA384withECDSA", X9ObjectIdentifiers.ecdsa_with_SHA384); createECCert("SHA512withECDSA", X9ObjectIdentifiers.ecdsa_with_SHA512); createPSSCert("SHA1withRSAandMGF1"); createPSSCert("SHA224withRSAandMGF1"); createPSSCert("SHA256withRSAandMGF1"); createPSSCert("SHA384withRSAandMGF1"); checkCRLCreation1(); checkCRLCreation2(); checkCRLCreation3(); pemTest(); pkcs7Test(); rfc4491Test(); testForgedSignature(); testNullDerNullCert(); checkCertificate(18, emptyDNCert); } public static void main( String[] args) { Security.addProvider(new BouncyCastleProvider()); runTest(new CertTest()); } } bouncycastle-1.49.orig/test/jdk1.3/org/bouncycastle/mail/0000755000175000017500000000000012152033550022602 5ustar ebourgebourgbouncycastle-1.49.orig/test/jdk1.3/org/bouncycastle/mail/smime/0000755000175000017500000000000012152033550023714 5ustar ebourgebourgbouncycastle-1.49.orig/test/jdk1.3/org/bouncycastle/mail/smime/test/0000755000175000017500000000000012152033550024673 5ustar ebourgebourgbouncycastle-1.49.orig/test/jdk1.3/org/bouncycastle/mail/smime/test/SMIMECompressedTest.java0000644000175000017500000001657011726307327031322 0ustar ebourgebourgpackage org.bouncycastle.mail.smime.test; import java.io.ByteArrayOutputStream; import java.io.InputStream; import java.security.KeyPair; import org.bouncycastle.jce.cert.CertStore; import org.bouncycastle.jce.cert.CollectionCertStoreParameters; import java.security.cert.X509Certificate; import java.util.ArrayList; import java.util.Collection; import java.util.Iterator; import java.util.List; import javax.mail.Session; import javax.mail.internet.MimeBodyPart; import javax.mail.internet.MimeMessage; import javax.mail.internet.MimeMultipart; import junit.framework.Test; import junit.framework.TestCase; import junit.framework.TestSuite; import org.bouncycastle.asn1.ASN1EncodableVector; import org.bouncycastle.asn1.cms.AttributeTable; import org.bouncycastle.asn1.smime.SMIMECapabilitiesAttribute; import org.bouncycastle.asn1.smime.SMIMECapability; import org.bouncycastle.asn1.smime.SMIMECapabilityVector; import org.bouncycastle.cms.SignerInformation; import org.bouncycastle.cms.SignerInformationStore; import org.bouncycastle.cms.jcajce.JcaX509CertSelectorConverter; import org.bouncycastle.cms.test.CMSTestUtil; import org.bouncycastle.mail.smime.SMIMECompressed; import org.bouncycastle.mail.smime.SMIMECompressedGenerator; import org.bouncycastle.mail.smime.SMIMECompressedParser; import org.bouncycastle.mail.smime.SMIMESigned; import org.bouncycastle.mail.smime.SMIMESignedGenerator; import org.bouncycastle.mail.smime.SMIMEUtil; import org.bouncycastle.util.Arrays; public class SMIMECompressedTest extends TestCase { private static final String COMPRESSED_CONTENT_TYPE = "application/pkcs7-mime; name=\"smime.p7z\"; smime-type=compressed-data"; private static final JcaX509CertSelectorConverter selectorConverter = new JcaX509CertSelectorConverter(); boolean DEBUG = true; MimeBodyPart msg; String signDN; KeyPair signKP; X509Certificate signCert; String origDN; KeyPair origKP; X509Certificate origCert; String reciDN; KeyPair reciKP; X509Certificate reciCert; KeyPair dsaSignKP; X509Certificate dsaSignCert; KeyPair dsaOrigKP; X509Certificate dsaOrigCert; /* * * INFRASTRUCTURE * */ public SMIMECompressedTest( String name) throws Exception { super(name); msg = SMIMETestUtil.makeMimeBodyPart("Hello world!"); signDN = "O=Bouncy Castle, C=AU"; signKP = CMSTestUtil.makeKeyPair(); signCert = CMSTestUtil.makeCertificate(signKP, signDN, signKP, signDN); origDN = "CN=Eric H. Echidna, E=eric@bouncycastle.org, O=Bouncy Castle, C=AU"; origKP = CMSTestUtil.makeKeyPair(); origCert = CMSTestUtil.makeCertificate(origKP, origDN, signKP, signDN); } public static void main(String args[]) { junit.textui.TestRunner.run(SMIMECompressedTest.class); } public static Test suite() { return new SMIMETestSetup(new TestSuite(SMIMECompressedTest.class)); } public void testHeaders() throws Exception { SMIMECompressedGenerator cgen = new SMIMECompressedGenerator(); MimeBodyPart cbp = cgen.generate(msg, SMIMECompressedGenerator.ZLIB); assertEquals(COMPRESSED_CONTENT_TYPE, cbp.getHeader("Content-Type")[0]); assertEquals("attachment; filename=\"smime.p7z\"", cbp.getHeader("Content-Disposition")[0]); assertEquals("S/MIME Compressed Message", cbp.getHeader("Content-Description")[0]); } public void testBasic() throws Exception { SMIMECompressedGenerator cgen = new SMIMECompressedGenerator(); ByteArrayOutputStream bOut = new ByteArrayOutputStream(); MimeBodyPart cbp = cgen.generate(msg, SMIMECompressedGenerator.ZLIB); SMIMECompressed sc = new SMIMECompressed(cbp); msg.writeTo(bOut); assertTrue(Arrays.areEqual(bOut.toByteArray(), sc.getContent())); } public void testParser() throws Exception { SMIMECompressedGenerator cgen = new SMIMECompressedGenerator(); ByteArrayOutputStream bOut1 = new ByteArrayOutputStream(); ByteArrayOutputStream bOut2 = new ByteArrayOutputStream(); MimeBodyPart cbp = cgen.generate(msg, SMIMECompressedGenerator.ZLIB); SMIMECompressedParser sc = new SMIMECompressedParser(cbp); msg.writeTo(bOut1); InputStream in = sc.getContent().getContentStream(); int ch; while ((ch = in.read()) >= 0) { bOut2.write(ch); } assertTrue(Arrays.areEqual(bOut1.toByteArray(), bOut2.toByteArray())); } /* * test compressing and uncompressing of a multipart-signed message. */ public void testCompressedSHA1WithRSA() throws Exception { List certList = new ArrayList(); certList.add(origCert); certList.add(signCert); CertStore certs = CertStore.getInstance("Collection", new CollectionCertStoreParameters(certList), "BC"); ASN1EncodableVector signedAttrs = new ASN1EncodableVector(); SMIMECapabilityVector caps = new SMIMECapabilityVector(); caps.addCapability(SMIMECapability.dES_EDE3_CBC); caps.addCapability(SMIMECapability.rC2_CBC, 128); caps.addCapability(SMIMECapability.dES_CBC); signedAttrs.add(new SMIMECapabilitiesAttribute(caps)); SMIMESignedGenerator gen = new SMIMESignedGenerator(); gen.addSigner(origKP.getPrivate(), origCert, SMIMESignedGenerator.DIGEST_SHA1, new AttributeTable(signedAttrs), null); gen.addCertificatesAndCRLs(certs); MimeMultipart smp = gen.generate(msg, "BC"); MimeMessage bp2 = new MimeMessage((Session)null); bp2.setContent(smp); bp2.saveChanges(); SMIMECompressedGenerator cgen = new SMIMECompressedGenerator(); MimeBodyPart cbp = cgen.generate(bp2, SMIMECompressedGenerator.ZLIB); SMIMECompressed cm = new SMIMECompressed(cbp); MimeMultipart mm = (MimeMultipart)SMIMEUtil.toMimeBodyPart(cm.getContent()).getContent(); SMIMESigned s = new SMIMESigned(mm); ByteArrayOutputStream _baos = new ByteArrayOutputStream(); msg.writeTo(_baos); _baos.close(); byte[] _msgBytes = _baos.toByteArray(); _baos = new ByteArrayOutputStream(); s.getContent().writeTo(_baos); _baos.close(); byte[] _resBytes = _baos.toByteArray(); assertEquals(true, Arrays.areEqual(_msgBytes, _resBytes)); certs = s.getCertificatesAndCRLs("Collection", "BC"); SignerInformationStore signers = s.getSignerInfos(); Collection c = signers.getSigners(); Iterator it = c.iterator(); while (it.hasNext()) { SignerInformation signer = (SignerInformation)it.next(); Collection certCollection = certs.getCertificates(selectorConverter.getCertSelector(signer.getSID())); Iterator certIt = certCollection.iterator(); X509Certificate cert = (X509Certificate)certIt.next(); assertEquals(true, signer.verify(cert, "BC")); } } } bouncycastle-1.49.orig/test/jdk1.3/org/bouncycastle/mail/smime/test/SMIMEMiscTest.java0000644000175000017500000003005711726307327030105 0ustar ebourgebourgpackage org.bouncycastle.mail.smime.test; import java.io.ByteArrayOutputStream; import java.io.File; import java.io.FileInputStream; import java.io.FileOutputStream; import java.security.KeyPair; import java.security.Security; import org.bouncycastle.jce.cert.CertStore; import org.bouncycastle.jce.cert.CollectionCertStoreParameters; import java.security.cert.X509Certificate; import java.util.ArrayList; import java.util.Arrays; import java.util.Collection; import java.util.Iterator; import java.util.List; import java.util.Properties; import javax.mail.Address; import javax.mail.Message; import javax.mail.Session; import javax.mail.internet.InternetAddress; import javax.mail.internet.MimeBodyPart; import javax.mail.internet.MimeMessage; import javax.mail.internet.MimeMultipart; import junit.framework.Test; import junit.framework.TestCase; import junit.framework.TestSuite; import org.bouncycastle.asn1.ASN1EncodableVector; import org.bouncycastle.asn1.cms.AttributeTable; import org.bouncycastle.asn1.smime.SMIMECapabilitiesAttribute; import org.bouncycastle.asn1.smime.SMIMECapability; import org.bouncycastle.asn1.smime.SMIMECapabilityVector; import org.bouncycastle.cms.CMSException; import org.bouncycastle.cms.RecipientInformation; import org.bouncycastle.cms.SignerInformation; import org.bouncycastle.cms.SignerInformationStore; import org.bouncycastle.cms.jcajce.JcaX509CertSelectorConverter; import org.bouncycastle.cms.test.CMSTestUtil; import org.bouncycastle.jce.provider.BouncyCastleProvider; import org.bouncycastle.mail.smime.SMIMECompressedGenerator; import org.bouncycastle.mail.smime.SMIMEEnveloped; import org.bouncycastle.mail.smime.SMIMEEnvelopedGenerator; import org.bouncycastle.mail.smime.SMIMESigned; import org.bouncycastle.mail.smime.SMIMESignedGenerator; import org.bouncycastle.mail.smime.SMIMESignedParser; import org.bouncycastle.mail.smime.SMIMEUtil; import org.bouncycastle.mail.smime.util.FileBackedMimeBodyPart; public class SMIMEMiscTest extends TestCase { static MimeBodyPart msg; static String signDN; static KeyPair signKP; static X509Certificate signCert; static String origDN; static KeyPair origKP; static X509Certificate origCert; static String reciDN; static KeyPair reciKP; static X509Certificate reciCert; private static final JcaX509CertSelectorConverter selectorConverter = new JcaX509CertSelectorConverter(); KeyPair dsaSignKP; X509Certificate dsaSignCert; KeyPair dsaOrigKP; X509Certificate dsaOrigCert; static { try { msg = SMIMETestUtil.makeMimeBodyPart("Hello world!\n"); signDN = "O=Bouncy Castle, C=AU"; signKP = CMSTestUtil.makeKeyPair(); signCert = CMSTestUtil.makeCertificate(signKP, signDN, signKP, signDN); origDN = "CN=Eric H. Echidna, E=eric@bouncycastle.org, O=Bouncy Castle, C=AU"; origKP = CMSTestUtil.makeKeyPair(); origCert = CMSTestUtil.makeCertificate(origKP, origDN, signKP, signDN); } catch (Exception e) { throw new RuntimeException("problem setting up signed test class: " + e); } } /* * * INFRASTRUCTURE * */ public SMIMEMiscTest(String name) { super(name); } public static void main(String args[]) { Security.addProvider(new BouncyCastleProvider()); junit.textui.TestRunner.run(SMIMEMiscTest.class); } public static Test suite() { return new SMIMETestSetup(new TestSuite(SMIMEMiscTest.class)); } public void testSHA256WithRSAParserEncryptedWithAES() throws Exception { List certList = new ArrayList(); certList.add(origCert); certList.add(signCert); CertStore certs = CertStore.getInstance("Collection", new CollectionCertStoreParameters(certList), "BC"); SMIMEEnvelopedGenerator encGen = new SMIMEEnvelopedGenerator(); encGen.addKeyTransRecipient(origCert); MimeBodyPart mp = encGen.generate(msg, SMIMEEnvelopedGenerator.AES128_CBC, "BC"); ASN1EncodableVector signedAttrs = generateSignedAttributes(); SMIMESignedGenerator gen = new SMIMESignedGenerator(); gen.addSigner(origKP.getPrivate(), origCert, SMIMESignedGenerator.DIGEST_SHA256, new AttributeTable(signedAttrs), null); gen.addCertificatesAndCRLs(certs); MimeMultipart smm = gen.generate(mp, "BC"); File tmpFile = File.createTempFile("bcTest", ".mime"); MimeMessage msg = createMimeMessage(tmpFile, smm); SMIMESignedParser s = new SMIMESignedParser((MimeMultipart)msg.getContent()); certs = s.getCertificatesAndCRLs("Collection", "BC"); verifyMessageBytes(mp, s.getContent()); verifySigners(certs, s.getSignerInfos()); tmpFile.delete(); } public void testSHA256WithRSACompressed() throws Exception { List certList = new ArrayList(); certList.add(origCert); certList.add(signCert); CertStore certs = CertStore.getInstance("Collection", new CollectionCertStoreParameters(certList), "BC"); SMIMECompressedGenerator cGen = new SMIMECompressedGenerator(); MimeBodyPart mp = cGen.generate(msg, SMIMECompressedGenerator.ZLIB); ASN1EncodableVector signedAttrs = generateSignedAttributes(); SMIMESignedGenerator gen = new SMIMESignedGenerator(); gen.addSigner(origKP.getPrivate(), origCert, SMIMESignedGenerator.DIGEST_SHA256, new AttributeTable(signedAttrs), null); gen.addCertificatesAndCRLs(certs); MimeMultipart smm = gen.generate(mp, "BC"); File tmpFile = File.createTempFile("bcTest", ".mime"); MimeMessage msg = createMimeMessage(tmpFile, smm); SMIMESigned s = new SMIMESigned((MimeMultipart)msg.getContent()); certs = s.getCertificatesAndCRLs("Collection", "BC"); verifyMessageBytes(mp, s.getContent()); verifySigners(certs, s.getSignerInfos()); tmpFile.delete(); } public void testQuotePrintableSigPreservation() throws Exception { MimeMessage msg = new MimeMessage((Session)null, getClass().getResourceAsStream("qp-soft-break.eml")); SMIMEEnvelopedGenerator encGen = new SMIMEEnvelopedGenerator(); encGen.addKeyTransRecipient(origCert); MimeBodyPart mp = encGen.generate(msg, SMIMEEnvelopedGenerator.AES128_CBC, "BC"); SMIMEEnveloped env = new SMIMEEnveloped(mp); RecipientInformation ri = (RecipientInformation)env.getRecipientInfos().getRecipients().iterator().next(); MimeBodyPart mm = SMIMEUtil.toMimeBodyPart(ri.getContentStream(origKP.getPrivate(), "BC")); SMIMESigned s = new SMIMESigned((MimeMultipart)mm.getContent()); Collection c = s.getSignerInfos().getSigners(); Iterator it = c.iterator(); CertStore certs = s.getCertificatesAndCRLs("Collection", "BC"); while (it.hasNext()) { SignerInformation signer = (SignerInformation)it.next(); Collection certCollection = certs.getCertificates(selectorConverter.getCertSelector(signer.getSID())); Iterator certIt = certCollection.iterator(); X509Certificate cert = (X509Certificate)certIt.next(); assertEquals(true, signer.verify(cert, "BC")); } ((FileBackedMimeBodyPart)mm).dispose(); } public void testSHA256WithRSAParserCompressed() throws Exception { List certList = new ArrayList(); certList.add(origCert); certList.add(signCert); CertStore certs = CertStore.getInstance("Collection", new CollectionCertStoreParameters(certList), "BC"); SMIMECompressedGenerator cGen = new SMIMECompressedGenerator(); MimeBodyPart mp = cGen.generate(msg, SMIMECompressedGenerator.ZLIB); ASN1EncodableVector signedAttrs = generateSignedAttributes(); SMIMESignedGenerator gen = new SMIMESignedGenerator(); gen.addSigner(origKP.getPrivate(), origCert, SMIMESignedGenerator.DIGEST_SHA256, new AttributeTable(signedAttrs), null); gen.addCertificatesAndCRLs(certs); MimeMultipart smm = gen.generate(mp, "BC"); File tmpFile = File.createTempFile("bcTest", ".mime"); MimeMessage msg = createMimeMessage(tmpFile, smm); SMIMESignedParser s = new SMIMESignedParser((MimeMultipart)msg.getContent()); certs = s.getCertificatesAndCRLs("Collection", "BC"); verifyMessageBytes(mp, s.getContent()); verifySigners(certs, s.getSignerInfos()); tmpFile.delete(); } public void testBrokenEnvelope() throws Exception { Session session = Session.getDefaultInstance(System.getProperties(), null); MimeMessage msg = new MimeMessage(session, getClass().getResourceAsStream("brokenEnv.message")); try { new SMIMEEnveloped(msg); } catch (CMSException e) { if (!e.getMessage().equals("Malformed content.")) { fail("wrong exception on bogus envelope"); } } } private void verifySigners(CertStore certs, SignerInformationStore signers) throws Exception { Collection c = signers.getSigners(); Iterator it = c.iterator(); while (it.hasNext()) { SignerInformation signer = (SignerInformation)it.next(); Collection certCollection = certs.getCertificates(selectorConverter.getCertSelector(signer.getSID())); Iterator certIt = certCollection.iterator(); X509Certificate cert = (X509Certificate)certIt.next(); assertEquals(true, signer.verify(cert, "BC")); } } private void verifyMessageBytes(MimeBodyPart a, MimeBodyPart b) throws Exception { ByteArrayOutputStream bOut1 = new ByteArrayOutputStream(); a.writeTo(bOut1); bOut1.close(); ByteArrayOutputStream bOut2 = new ByteArrayOutputStream(); b.writeTo(bOut2); bOut2.close(); assertEquals(true, Arrays.equals(bOut1.toByteArray(), bOut2.toByteArray())); } /** * Create a mime message representing the multipart. We need to do * this as otherwise no raw content stream for the message will exist. */ private MimeMessage createMimeMessage(File tmpFile, MimeMultipart smm) throws Exception { FileOutputStream fOut = new FileOutputStream(tmpFile); Properties props = System.getProperties(); Session session = Session.getDefaultInstance(props, null); Address fromUser = new InternetAddress("\"Eric H. Echidna\""); Address toUser = new InternetAddress("example@bouncycastle.org"); MimeMessage body = new MimeMessage(session); body.setFrom(fromUser); body.setRecipient(Message.RecipientType.TO, toUser); body.setSubject("example signed message"); body.setContent(smm, smm.getContentType()); body.saveChanges(); body.writeTo(fOut); fOut.close(); return new MimeMessage(session, new FileInputStream(tmpFile)); } private ASN1EncodableVector generateSignedAttributes() { ASN1EncodableVector signedAttrs = new ASN1EncodableVector(); SMIMECapabilityVector caps = new SMIMECapabilityVector(); caps.addCapability(SMIMECapability.dES_EDE3_CBC); caps.addCapability(SMIMECapability.rC2_CBC, 128); caps.addCapability(SMIMECapability.dES_CBC); signedAttrs.add(new SMIMECapabilitiesAttribute(caps)); return signedAttrs; } } bouncycastle-1.49.orig/test/jdk1.3/org/bouncycastle/mail/smime/test/SMIMESignedTest.java0000644000175000017500000012441211726307327030422 0ustar ebourgebourgpackage org.bouncycastle.mail.smime.test; import java.io.ByteArrayOutputStream; import java.io.File; import java.io.FileNotFoundException; import java.io.FilterOutputStream; import java.io.IOException; import java.io.OutputStream; import java.io.UnsupportedEncodingException; import java.security.KeyPair; import java.security.MessageDigest; import org.bouncycastle.jce.cert.CertStore; import org.bouncycastle.jce.cert.CollectionCertStoreParameters; import java.security.cert.X509Certificate; import java.util.ArrayList; import java.util.Arrays; import java.util.Collection; import java.util.Collections; import java.util.Date; import java.util.Enumeration; import java.util.Iterator; import java.util.List; import java.util.Map; import java.util.Properties; import javax.mail.BodyPart; import javax.mail.MessagingException; import javax.mail.Session; import javax.mail.internet.ContentType; import javax.mail.internet.InternetHeaders; import javax.mail.internet.MimeBodyPart; import javax.mail.internet.MimeMessage; import javax.mail.internet.MimeMultipart; import junit.framework.Test; import junit.framework.TestCase; import junit.framework.TestSuite; import org.bouncycastle.asn1.ASN1EncodableVector; import org.bouncycastle.asn1.ASN1OctetString; import org.bouncycastle.asn1.DERSet; import org.bouncycastle.asn1.cms.Attribute; import org.bouncycastle.asn1.cms.AttributeTable; import org.bouncycastle.asn1.cms.CMSAttributes; import org.bouncycastle.asn1.cms.Time; import org.bouncycastle.asn1.cryptopro.CryptoProObjectIdentifiers; import org.bouncycastle.asn1.nist.NISTObjectIdentifiers; import org.bouncycastle.asn1.pkcs.PKCSObjectIdentifiers; import org.bouncycastle.asn1.smime.SMIMECapabilitiesAttribute; import org.bouncycastle.asn1.smime.SMIMECapability; import org.bouncycastle.asn1.smime.SMIMECapabilityVector; import org.bouncycastle.asn1.teletrust.TeleTrusTObjectIdentifiers; import org.bouncycastle.cms.SignerInformation; import org.bouncycastle.cms.SignerInformationStore; import org.bouncycastle.cms.jcajce.JcaX509CertSelectorConverter; import org.bouncycastle.cms.test.CMSTestUtil; import org.bouncycastle.mail.smime.SMIMESigned; import org.bouncycastle.mail.smime.SMIMESignedGenerator; import org.bouncycastle.mail.smime.SMIMESignedParser; import org.bouncycastle.mail.smime.util.CRLFOutputStream; import org.bouncycastle.mail.smime.util.FileBackedMimeBodyPart; import org.bouncycastle.x509.X509AttributeCertificate; import org.bouncycastle.x509.X509CollectionStoreParameters; import org.bouncycastle.x509.X509Store; public class SMIMESignedTest extends TestCase { static MimeBodyPart msg; static MimeBodyPart msgR; static MimeBodyPart msgRN; static String _origDN; static KeyPair _origKP; static X509Certificate _origCert; static String _signDN; static KeyPair _signKP; static X509Certificate _signCert; static String reciDN; static KeyPair reciKP; static X509Certificate reciCert; private static KeyPair _signGostKP; private static X509Certificate _signGostCert; private static KeyPair _signEcDsaKP; private static X509Certificate _signEcDsaCert; private static KeyPair _signEcGostKP; private static X509Certificate _signEcGostCert; private static final JcaX509CertSelectorConverter selectorConverter = new JcaX509CertSelectorConverter(); KeyPair dsaSignKP; X509Certificate dsaSignCert; KeyPair dsaOrigKP; X509Certificate dsaOrigCert; static { try { msg = SMIMETestUtil.makeMimeBodyPart("Hello world!\n"); msgR = SMIMETestUtil.makeMimeBodyPart("Hello world!\r"); msgRN = SMIMETestUtil.makeMimeBodyPart("Hello world!\r\n"); _origDN = "O=Bouncy Castle, C=AU"; _origKP = CMSTestUtil.makeKeyPair(); _origCert = CMSTestUtil.makeCertificate(_origKP, _origDN, _origKP, _origDN); _signDN = "CN=Eric H. Echidna, E=eric@bouncycastle.org, O=Bouncy Castle, C=AU"; _signKP = CMSTestUtil.makeKeyPair(); _signCert = CMSTestUtil.makeCertificate(_signKP, _signDN, _origKP, _origDN); _signGostKP = CMSTestUtil.makeGostKeyPair(); _signGostCert = CMSTestUtil.makeCertificate(_signGostKP, _signDN, _origKP, _origDN); _signEcDsaKP = CMSTestUtil.makeEcDsaKeyPair(); _signEcDsaCert = CMSTestUtil.makeCertificate(_signEcDsaKP, _signDN, _origKP, _origDN); _signEcGostKP = CMSTestUtil.makeEcGostKeyPair(); _signEcGostCert = CMSTestUtil.makeCertificate(_signEcGostKP, _signDN, _origKP, _origDN); } catch (Exception e) { throw new RuntimeException("problem setting up signed test class: " + e); } } private static class LineOutputStream extends FilterOutputStream { private static byte newline[]; public LineOutputStream(OutputStream outputstream) { super(outputstream); } public void writeln(String s) throws MessagingException { try { byte abyte0[] = getBytes(s); super.out.write(abyte0); super.out.write(newline); } catch(Exception exception) { throw new MessagingException("IOException", exception); } } public void writeln() throws MessagingException { try { super.out.write(newline); } catch(Exception exception) { throw new MessagingException("IOException", exception); } } static { newline = new byte[2]; newline[0] = 13; newline[1] = 10; } private static byte[] getBytes(String s) { char ac[] = s.toCharArray(); int i = ac.length; byte abyte0[] = new byte[i]; int j = 0; while (j < i) { abyte0[j] = (byte)ac[j++]; } return abyte0; } } /* * * INFRASTRUCTURE * */ public SMIMESignedTest(String name) { super(name); } public static void main(String args[]) { junit.textui.TestRunner.run(SMIMESignedTest.class); } public static Test suite() { return new SMIMETestSetup(new TestSuite(SMIMESignedTest.class)); } public void testHeaders() throws Exception { MimeMultipart smm = generateMultiPartRsa(SMIMESignedGenerator.DIGEST_SHA1, msg, SMIMESignedGenerator.RFC3851_MICALGS); BodyPart bp = smm.getBodyPart(1); assertEquals("application/pkcs7-signature; name=smime.p7s; smime-type=signed-data", bp.getHeader("Content-Type")[0]); assertEquals("attachment; filename=\"smime.p7s\"", bp.getHeader("Content-Disposition")[0]); assertEquals("S/MIME Cryptographic Signature", bp.getHeader("Content-Description")[0]); } public void testHeadersEncapsulated() throws Exception { List certList = new ArrayList(); certList.add(_signCert); certList.add(_origCert); CertStore certs = CertStore.getInstance("Collection", new CollectionCertStoreParameters(certList), "BC"); ASN1EncodableVector signedAttrs = generateSignedAttributes(); SMIMESignedGenerator gen = new SMIMESignedGenerator(); gen.addSigner(_signKP.getPrivate(), _signCert, SMIMESignedGenerator.DIGEST_SHA1, new AttributeTable(signedAttrs), null); gen.addCertificatesAndCRLs(certs); MimeBodyPart res = gen.generateEncapsulated(msg, "BC"); assertEquals("application/pkcs7-mime; name=smime.p7m; smime-type=signed-data", res.getHeader("Content-Type")[0]); assertEquals("attachment; filename=\"smime.p7m\"", res.getHeader("Content-Disposition")[0]); assertEquals("S/MIME Cryptographic Signed Data", res.getHeader("Content-Description")[0]); } public void testMultipartTextText() throws Exception { MimeBodyPart part1 = createTemplate("text/html", "7bit"); MimeBodyPart part2 = createTemplate("text/xml", "7bit"); multipartMixedTest(part1, part2); } public void testMultipartTextBinary() throws Exception { MimeBodyPart part1 = createTemplate("text/html", "7bit"); MimeBodyPart part2 = createTemplate("text/xml", "binary"); multipartMixedTest(part1, part2); } public void testMultipartBinaryText() throws Exception { MimeBodyPart part1 = createTemplate("text/xml", "binary"); MimeBodyPart part2 = createTemplate("text/html", "7bit"); multipartMixedTest(part1, part2); } public void testMultipartBinaryBinary() throws Exception { MimeBodyPart part1 = createTemplate("text/xml", "binary"); MimeBodyPart part2 = createTemplate("text/html", "binary"); multipartMixedTest(part1, part2); } public void testSHA1WithRSAPSS() throws Exception { rsaPSSTest(SMIMESignedGenerator.DIGEST_SHA1); } public void testSHA224WithRSAPSS() throws Exception { rsaPSSTest(SMIMESignedGenerator.DIGEST_SHA224); } public void testSHA256WithRSAPSS() throws Exception { rsaPSSTest(SMIMESignedGenerator.DIGEST_SHA256); } public void testSHA384WithRSAPSS() throws Exception { rsaPSSTest(SMIMESignedGenerator.DIGEST_SHA384); } public void multipartMixedTest(MimeBodyPart part1, MimeBodyPart part2) throws Exception { MimeMultipart mp = new MimeMultipart(); mp.addBodyPart(part1); mp.addBodyPart(part2); MimeBodyPart m = new MimeBodyPart(); m.setContent(mp); MimeMultipart smm = generateMultiPartRsa(SMIMESignedGenerator.DIGEST_SHA1, m, SMIMESignedGenerator.RFC3851_MICALGS); SMIMESigned s = new SMIMESigned(smm); verifySigners(s.getCertificatesAndCRLs("Collection", "BC"), s.getSignerInfos()); AttributeTable attr = ((SignerInformation)s.getSignerInfos().getSigners().iterator().next()).getSignedAttributes(); Attribute a = attr.get(CMSAttributes.messageDigest); byte[] contentDigest = ASN1OctetString.getInstance(a.getAttrValues().getObjectAt(0)).getOctets(); mp = (MimeMultipart)m.getContent(); ContentType contentType = new ContentType(mp.getContentType()); String boundary = "--" + contentType.getParameter("boundary"); ByteArrayOutputStream bOut = new ByteArrayOutputStream(); LineOutputStream lOut = new LineOutputStream(bOut); Enumeration headers = m.getAllHeaderLines(); while (headers.hasMoreElements()) { lOut.writeln((String)headers.nextElement()); } lOut.writeln(); // CRLF separator lOut.writeln(boundary); writePart(mp.getBodyPart(0), bOut); lOut.writeln(); // CRLF terminator lOut.writeln(boundary); writePart(mp.getBodyPart(1), bOut); lOut.writeln(); lOut.writeln(boundary + "--"); MessageDigest dig = MessageDigest.getInstance("SHA1", "BC"); assertTrue(Arrays.equals(contentDigest, dig.digest(bOut.toByteArray()))); } private void writePart(BodyPart part, ByteArrayOutputStream bOut) throws MessagingException, IOException { if (part.getHeader("Content-Transfer-Encoding")[0].equals("binary")) { part.writeTo(bOut); } else { part.writeTo(new CRLFOutputStream(bOut)); } } public void testSHA1WithRSA() throws Exception { MimeMultipart smm = generateMultiPartRsa(SMIMESignedGenerator.DIGEST_SHA1, msg, SMIMESignedGenerator.RFC3851_MICALGS); SMIMESigned s = new SMIMESigned(smm); verifyMessageBytes(msg, s.getContent()); verifySigners(s.getCertificatesAndCRLs("Collection", "BC"), s.getSignerInfos()); } public void testSHA1WithRSAAddSigners() throws Exception { MimeMultipart smm = generateMultiPartRsa(SMIMESignedGenerator.DIGEST_SHA1, msg, SMIMESignedGenerator.RFC3851_MICALGS); SMIMESigned s = new SMIMESigned(smm); List certList = new ArrayList(); certList.add(_signCert); certList.add(_origCert); CertStore certs = CertStore.getInstance("Collection", new CollectionCertStoreParameters(certList), "BC"); SMIMESignedGenerator gen = new SMIMESignedGenerator(); gen.addSigners(s.getSignerInfos()); gen.addCertificatesAndCRLs(certs); SMIMESigned newS = new SMIMESigned(gen.generate(msg, "BC")); verifyMessageBytes(msg, newS.getContent()); verifySigners(newS.getCertificatesAndCRLs("Collection", "BC"), newS.getSignerInfos()); } public void testMD5WithRSAAddSignersSHA1() throws Exception { MimeMultipart smm = generateMultiPartRsa(SMIMESignedGenerator.DIGEST_SHA1, msg, SMIMESignedGenerator.RFC3851_MICALGS); SMIMESigned s = new SMIMESigned(smm); List certList = new ArrayList(); certList.add(_signCert); certList.add(_origCert); CertStore certs = CertStore.getInstance("Collection", new CollectionCertStoreParameters(certList), "BC"); SMIMESignedGenerator gen = new SMIMESignedGenerator(); gen.addSigner(_signKP.getPrivate(), _signCert, SMIMESignedGenerator.DIGEST_MD5); gen.addSigners(s.getSignerInfos()); gen.addCertificatesAndCRLs(certs); smm = gen.generate(msg, "BC"); SMIMESigned newS = new SMIMESigned(gen.generate(msg, "BC")); verifyMessageBytes(msg, newS.getContent()); verifySigners(newS.getCertificatesAndCRLs("Collection", "BC"), newS.getSignerInfos()); assertEquals("\"md5,sha-1\"", getMicAlg(smm)); } public void testSHA1WithRSACanonicalization() throws Exception { Date testTime = new Date(); MimeMultipart smm = generateMultiPartRsa(SMIMESignedGenerator.DIGEST_SHA1, msg, testTime, SMIMESignedGenerator.RFC3851_MICALGS); byte[] sig1 = getEncodedStream(smm); smm = generateMultiPartRsa(SMIMESignedGenerator.DIGEST_SHA1, msgR, testTime, SMIMESignedGenerator.RFC3851_MICALGS); byte[] sig2 = getEncodedStream(smm); assertTrue(Arrays.equals(sig1, sig2)); smm = generateMultiPartRsa(SMIMESignedGenerator.DIGEST_SHA1, msgRN, testTime, SMIMESignedGenerator.RFC3851_MICALGS); byte[] sig3 = getEncodedStream(smm); assertTrue(Arrays.equals(sig1, sig3)); } private byte[] getEncodedStream(MimeMultipart smm) throws IOException, MessagingException { ByteArrayOutputStream bOut = new ByteArrayOutputStream(); smm.getBodyPart(1).writeTo(bOut); return bOut.toByteArray(); } public void testSHA1WithRSAEncapsulated() throws Exception { MimeBodyPart res = generateEncapsulatedRsa(SMIMESignedGenerator.DIGEST_SHA1, msg); SMIMESigned s = new SMIMESigned(res); verifyMessageBytes(msg, s.getContent()); verifySigners(s.getCertificatesAndCRLs("Collection", "BC"), s.getSignerInfos()); } public void testSHA1WithRSAEncapsulatedParser() throws Exception { MimeBodyPart res = generateEncapsulatedRsa(SMIMESignedGenerator.DIGEST_SHA1, msg); SMIMESignedParser s = new SMIMESignedParser(res); FileBackedMimeBodyPart content = (FileBackedMimeBodyPart)s.getContent(); verifyMessageBytes(msg, content); content.dispose(); verifySigners(s.getCertificatesAndCRLs("Collection", "BC"), s.getSignerInfos()); s.close(); } public void testSHA1WithRSAEncapsulatedParserAndFile() throws Exception { File tmp = File.createTempFile("bcTest", ".mime"); MimeBodyPart res = generateEncapsulatedRsa(SMIMESignedGenerator.DIGEST_SHA1, msg); SMIMESignedParser s = new SMIMESignedParser(res, tmp); FileBackedMimeBodyPart content = (FileBackedMimeBodyPart)s.getContent(); verifyMessageBytes(msg, s.getContent()); verifySigners(s.getCertificatesAndCRLs("Collection", "BC"), s.getSignerInfos()); assertTrue(tmp.exists()); s.close(); content.dispose(); assertFalse(tmp.exists()); } public void testMD5WithRSA() throws Exception { MimeMultipart smm = generateMultiPartRsa(SMIMESignedGenerator.DIGEST_MD5, msg, SMIMESignedGenerator.RFC3851_MICALGS); SMIMESigned s = new SMIMESigned(smm); assertEquals("md5", getMicAlg(smm)); assertEquals(getDigestOid(s.getSignerInfos()), PKCSObjectIdentifiers.md5.toString()); verifyMessageBytes(msg, s.getContent()); verifySigners(s.getCertificatesAndCRLs("Collection", "BC"), s.getSignerInfos()); } public void testSHA224WithRSA() throws Exception { MimeMultipart smm = generateMultiPartRsa(SMIMESignedGenerator.DIGEST_SHA224, msg, SMIMESignedGenerator.RFC3851_MICALGS); SMIMESigned s = new SMIMESigned(smm); assertEquals("sha224", getMicAlg(smm)); assertEquals(getDigestOid(s.getSignerInfos()), NISTObjectIdentifiers.id_sha224.toString()); verifyMessageBytes(msg, s.getContent()); verifySigners(s.getCertificatesAndCRLs("Collection", "BC"), s.getSignerInfos()); } public void testSHA256WithRSA() throws Exception { MimeMultipart smm = generateMultiPartRsa(SMIMESignedGenerator.DIGEST_SHA256, msg, SMIMESignedGenerator.RFC3851_MICALGS); SMIMESigned s = new SMIMESigned(smm); assertEquals("sha256", getMicAlg(smm)); assertEquals(getDigestOid(s.getSignerInfos()), NISTObjectIdentifiers.id_sha256.toString()); verifyMessageBytes(msg, s.getContent()); verifySigners(s.getCertificatesAndCRLs("Collection", "BC"), s.getSignerInfos()); } public void testSHA384WithRSA() throws Exception { MimeMultipart smm = generateMultiPartRsa(SMIMESignedGenerator.DIGEST_SHA384, msg, SMIMESignedGenerator.RFC3851_MICALGS); SMIMESigned s = new SMIMESigned(smm); assertEquals("sha384", getMicAlg(smm)); assertEquals(getDigestOid(s.getSignerInfos()), NISTObjectIdentifiers.id_sha384.toString()); verifyMessageBytes(msg, s.getContent()); verifySigners(s.getCertificatesAndCRLs("Collection", "BC"), s.getSignerInfos()); } public void testSHA512WithRSA() throws Exception { MimeMultipart smm = generateMultiPartRsa(SMIMESignedGenerator.DIGEST_SHA512, msg, SMIMESignedGenerator.RFC3851_MICALGS); SMIMESigned s = new SMIMESigned(smm); assertEquals("sha512", getMicAlg(smm)); assertEquals(getDigestOid(s.getSignerInfos()), NISTObjectIdentifiers.id_sha512.toString()); verifyMessageBytes(msg, s.getContent()); verifySigners(s.getCertificatesAndCRLs("Collection", "BC"), s.getSignerInfos()); } public void testRIPEMD160WithRSA() throws Exception { MimeMultipart smm = generateMultiPartRsa(SMIMESignedGenerator.DIGEST_RIPEMD160, msg, SMIMESignedGenerator.RFC3851_MICALGS); SMIMESigned s = new SMIMESigned(smm); assertEquals("unknown", getMicAlg(smm)); assertEquals(getDigestOid(s.getSignerInfos()), TeleTrusTObjectIdentifiers.ripemd160.toString()); verifyMessageBytes(msg, s.getContent()); verifySigners(s.getCertificatesAndCRLs("Collection", "BC"), s.getSignerInfos()); } public void testGOST3411WithGOST3410() throws Exception { MimeMultipart smm = generateMultiPartGost(msg); SMIMESigned s = new SMIMESigned(smm); assertEquals("gostr3411-94", getMicAlg(smm)); assertEquals(getDigestOid(s.getSignerInfos()), CryptoProObjectIdentifiers.gostR3411.getId()); verifyMessageBytes(msg, s.getContent()); verifySigners(s.getCertificatesAndCRLs("Collection", "BC"), s.getSignerInfos()); } public void testGOST3411WithECGOST3410() throws Exception { MimeMultipart smm = generateMultiPartECGost(msg); SMIMESigned s = new SMIMESigned(smm); assertEquals("gostr3411-94", getMicAlg(smm)); assertEquals(getDigestOid(s.getSignerInfos()), CryptoProObjectIdentifiers.gostR3411.getId()); verifyMessageBytes(msg, s.getContent()); verifySigners(s.getCertificatesAndCRLs("Collection", "BC"), s.getSignerInfos()); } public void testSHA224WithRSAParser() throws Exception { MimeMultipart smm = generateMultiPartRsa(SMIMESignedGenerator.DIGEST_SHA224, msg, SMIMESignedGenerator.RFC3851_MICALGS); SMIMESignedParser s = new SMIMESignedParser(smm); CertStore certs = s.getCertificatesAndCRLs("Collection", "BC"); assertEquals(getDigestOid(s.getSignerInfos()), NISTObjectIdentifiers.id_sha224.toString()); verifyMessageBytes(msg, s.getContent()); verifySigners(certs, s.getSignerInfos()); } public void testSHA224WithRSAParserEncryptedWithDES() throws Exception { List certList = new ArrayList(); certList.add(_signCert); certList.add(_origCert); CertStore certs = CertStore.getInstance("Collection", new CollectionCertStoreParameters(certList), "BC"); ASN1EncodableVector signedAttrs = generateSignedAttributes(); SMIMESignedGenerator gen = new SMIMESignedGenerator(); gen.addSigner(_signKP.getPrivate(), _signCert, SMIMESignedGenerator.DIGEST_SHA224, new AttributeTable(signedAttrs), null); gen.addCertificatesAndCRLs(certs); MimeMultipart smm = gen.generate(msg, "BC"); SMIMESignedParser s = new SMIMESignedParser(smm); certs = s.getCertificatesAndCRLs("Collection", "BC"); assertEquals(getDigestOid(s.getSignerInfos()), NISTObjectIdentifiers.id_sha224.toString()); verifyMessageBytes(msg, s.getContent()); verifySigners(certs, s.getSignerInfos()); } public void testSHA1withDSA() throws Exception { dsaSignKP = CMSTestUtil.makeDsaKeyPair(); dsaSignCert = CMSTestUtil.makeCertificate(dsaSignKP, _origDN, dsaSignKP, _origDN); dsaOrigKP = CMSTestUtil.makeDsaKeyPair(); dsaOrigCert = CMSTestUtil.makeCertificate(dsaOrigKP, _signDN, dsaSignKP, _origDN); List certList = new ArrayList(); certList.add(dsaOrigCert); certList.add(dsaSignCert); CertStore certs = CertStore.getInstance("Collection", new CollectionCertStoreParameters(certList), "BC"); SMIMESignedGenerator gen = new SMIMESignedGenerator(); gen.addSigner(dsaOrigKP.getPrivate(), dsaOrigCert, SMIMESignedGenerator.DIGEST_SHA1); gen.addCertificatesAndCRLs(certs); MimeMultipart smm = gen.generate(msg, "BC"); SMIMESigned s = new SMIMESigned(smm); verifyMessageBytes(msg, s.getContent()); verifySigners(s.getCertificatesAndCRLs("Collection", "BC"), s.getSignerInfos()); } public void testSHA256WithRSABinary() throws Exception { MimeBodyPart msg = generateBinaryPart(); MimeMultipart smm = generateMultiPartRsa(SMIMESignedGenerator.DIGEST_SHA256, msg, SMIMESignedGenerator.RFC3851_MICALGS); SMIMESigned s = new SMIMESigned(smm); verifyMessageBytes(msg, s.getContent()); verifySigners(s.getCertificatesAndCRLs("Collection", "BC"), s.getSignerInfos()); } public void testSHA256WithRSABinaryWithParser() throws Exception { MimeBodyPart msg = generateBinaryPart(); MimeMultipart smm = generateMultiPartRsa(SMIMESignedGenerator.DIGEST_SHA256, msg, SMIMESignedGenerator.RFC3851_MICALGS); SMIMESignedParser s = new SMIMESignedParser(smm); verifyMessageBytes(msg, s.getContent()); verifySigners(s.getCertificatesAndCRLs("Collection", "BC"), s.getSignerInfos()); } public void testWithAttributeCertificate() throws Exception { List certList = new ArrayList(); certList.add(_signCert); certList.add(_origCert); CertStore certs = CertStore.getInstance("Collection", new CollectionCertStoreParameters(certList), "BC"); ASN1EncodableVector signedAttrs = generateSignedAttributes(); SMIMESignedGenerator gen = new SMIMESignedGenerator(); gen.addSigner(_signKP.getPrivate(), _signCert, SMIMESignedGenerator.DIGEST_SHA256, new AttributeTable(signedAttrs), null); gen.addCertificatesAndCRLs(certs); X509AttributeCertificate attrCert = CMSTestUtil.getAttributeCertificate(); X509Store store = X509Store.getInstance("AttributeCertificate/Collection", new X509CollectionStoreParameters(Collections.singleton(attrCert)), "BC"); gen.addAttributeCertificates(store); SMIMESigned s = new SMIMESigned(gen.generateEncapsulated(msg, "BC")); verifyMessageBytes(msg, s.getContent()); verifySigners(s.getCertificatesAndCRLs("Collection", "BC"), s.getSignerInfos()); X509Store attrCerts = s.getAttributeCertificates("Collection", "BC"); assertTrue(attrCerts.getMatches(null).contains(attrCert)); } private void rsaPSSTest(String digestOID) throws Exception { MimeMultipart smm = generateMultiPartRsaPSS(digestOID, msg, null); SMIMESignedParser s = new SMIMESignedParser(smm); CertStore certs = s.getCertificatesAndCRLs("Collection", "BC"); assertEquals(getDigestOid(s.getSignerInfos()), digestOID); verifyMessageBytes(msg, s.getContent()); verifySigners(certs, s.getSignerInfos()); } private MimeBodyPart generateBinaryPart() throws MessagingException { byte[] content = new byte[] { 1, 2, 3, 4, 5, 6, 7, 8, 9, 0, 10, 11, 12, 13, 14, 10, 10, 15, 16 }; InternetHeaders ih = new InternetHeaders(); ih.setHeader("Content-Transfer-Encoding", "binary"); return new MimeBodyPart(ih, content); } private MimeMultipart generateMultiPartRsa( String digestOid, MimeBodyPart msg, Date signingTime, Map micalgs) throws Exception { List certList = new ArrayList(); certList.add(_signCert); certList.add(_origCert); CertStore certs = CertStore.getInstance("Collection", new CollectionCertStoreParameters(certList), "BC"); ASN1EncodableVector signedAttrs = generateSignedAttributes(); if (signingTime != null) { signedAttrs.add(new Attribute(CMSAttributes.signingTime, new DERSet(new Time(signingTime)))); } SMIMESignedGenerator gen = new SMIMESignedGenerator(micalgs); gen.addSigner(_signKP.getPrivate(), _signCert, digestOid, new AttributeTable(signedAttrs), null); gen.addCertificatesAndCRLs(certs); return gen.generate(msg, "BC"); } private MimeMultipart generateMultiPartRsaPSS( String digestOid, MimeBodyPart msg, Date signingTime) throws Exception { List certList = new ArrayList(); certList.add(_signCert); certList.add(_origCert); CertStore certs = CertStore.getInstance("Collection", new CollectionCertStoreParameters(certList), "BC"); ASN1EncodableVector signedAttrs = generateSignedAttributes(); if (signingTime != null) { signedAttrs.add(new Attribute(CMSAttributes.signingTime, new DERSet(new Time(signingTime)))); } SMIMESignedGenerator gen = new SMIMESignedGenerator(); gen.addSigner(_signKP.getPrivate(), _signCert, SMIMESignedGenerator.ENCRYPTION_RSA_PSS, digestOid, new AttributeTable(signedAttrs), null); gen.addCertificatesAndCRLs(certs); return gen.generate(msg, "BC"); } private MimeMultipart generateMultiPartGost( MimeBodyPart msg) throws Exception { List certList = new ArrayList(); certList.add(_signCert); certList.add(_signGostCert); CertStore certs = CertStore.getInstance("Collection", new CollectionCertStoreParameters(certList), "BC"); SMIMESignedGenerator gen = new SMIMESignedGenerator(); gen.addSigner(_signGostKP.getPrivate(), _signGostCert, SMIMESignedGenerator.DIGEST_GOST3411); gen.addCertificatesAndCRLs(certs); return gen.generate(msg, "BC"); } private MimeMultipart generateMultiPartECGost( MimeBodyPart msg) throws Exception { List certList = new ArrayList(); certList.add(_signCert); certList.add(_signEcGostCert); CertStore certs = CertStore.getInstance("Collection", new CollectionCertStoreParameters(certList), "BC"); SMIMESignedGenerator gen = new SMIMESignedGenerator(); gen.addSigner(_signEcGostKP.getPrivate(), _signEcGostCert, SMIMESignedGenerator.DIGEST_GOST3411); gen.addCertificatesAndCRLs(certs); return gen.generate(msg, "BC"); } private MimeMultipart generateMultiPartRsa(String digestOid, MimeBodyPart msg, Map micalgs) throws Exception { return generateMultiPartRsa(digestOid, msg, null, micalgs); } private MimeBodyPart generateEncapsulatedRsa(String digestOid, MimeBodyPart msg) throws Exception { List certList = new ArrayList(); certList.add(_signCert); certList.add(_origCert); CertStore certs = CertStore.getInstance("Collection", new CollectionCertStoreParameters(certList), "BC"); ASN1EncodableVector signedAttrs = generateSignedAttributes(); SMIMESignedGenerator gen = new SMIMESignedGenerator(); gen.addSigner(_signKP.getPrivate(), _signCert, digestOid, new AttributeTable(signedAttrs), null); gen.addCertificatesAndCRLs(certs); return gen.generateEncapsulated(msg, "BC"); } public void testCertificateManagement() throws Exception { List certList = new ArrayList(); certList.add(_signCert); certList.add(_origCert); CertStore certs = CertStore.getInstance("Collection", new CollectionCertStoreParameters(certList), "BC"); SMIMESignedGenerator gen = new SMIMESignedGenerator(); gen.addCertificatesAndCRLs(certs); MimeBodyPart smm = gen.generateCertificateManagement("BC"); SMIMESigned s = new SMIMESigned(smm); certs = s.getCertificatesAndCRLs("Collection", "BC"); assertEquals(2, certs.getCertificates(null).size()); } public void testMimeMultipart() throws Exception { MimeBodyPart m = createMultipartMessage(); List certList = new ArrayList(); certList.add(_signCert); certList.add(_origCert); CertStore certs = CertStore.getInstance("Collection", new CollectionCertStoreParameters(certList), "BC"); ASN1EncodableVector signedAttrs = generateSignedAttributes(); SMIMESignedGenerator gen = new SMIMESignedGenerator("binary"); gen.addSigner(_signKP.getPrivate(), _signCert, SMIMESignedGenerator.DIGEST_SHA1, new AttributeTable(signedAttrs), null); gen.addCertificatesAndCRLs(certs); MimeMultipart mm = gen.generate(m, "BC"); SMIMESigned s = new SMIMESigned(mm); verifySigners(s.getCertificatesAndCRLs("Collection", "BC"), s.getSignerInfos()); byte[] contentDigest = (byte[])gen.getGeneratedDigests().get(SMIMESignedGenerator.DIGEST_SHA1); AttributeTable table = ((SignerInformation)s.getSignerInfos().getSigners().iterator().next()).getSignedAttributes(); Attribute hash = table.get(CMSAttributes.messageDigest); assertTrue(MessageDigest.isEqual(contentDigest, ((ASN1OctetString)hash.getAttrValues().getObjectAt(0)).getOctets())); } public void testMimeMultipartBinaryReader() throws Exception { MimeBodyPart m = createMultipartMessage(); List certList = new ArrayList(); certList.add(_signCert); certList.add(_origCert); CertStore certs = CertStore.getInstance("Collection", new CollectionCertStoreParameters(certList), "BC"); ASN1EncodableVector signedAttrs = generateSignedAttributes(); SMIMESignedGenerator gen = new SMIMESignedGenerator("binary"); gen.addSigner(_signKP.getPrivate(), _signCert, SMIMESignedGenerator.DIGEST_SHA1, new AttributeTable(signedAttrs), null); gen.addCertificatesAndCRLs(certs); MimeMultipart mm = gen.generate(m, "BC"); SMIMESigned s = new SMIMESigned(mm, "binary"); verifySigners(s.getCertificatesAndCRLs("Collection", "BC"), s.getSignerInfos()); } public void testMimeMultipartBinaryParser() throws Exception { MimeBodyPart m = createMultipartMessage(); List certList = new ArrayList(); certList.add(_signCert); certList.add(_origCert); CertStore certs = CertStore.getInstance("Collection", new CollectionCertStoreParameters(certList), "BC"); ASN1EncodableVector signedAttrs = generateSignedAttributes(); SMIMESignedGenerator gen = new SMIMESignedGenerator("binary"); gen.addSigner(_signKP.getPrivate(), _signCert, SMIMESignedGenerator.DIGEST_SHA1, new AttributeTable(signedAttrs), null); gen.addCertificatesAndCRLs(certs); MimeMultipart mm = gen.generate(m, "BC"); SMIMESignedParser s = new SMIMESignedParser(mm, "binary"); verifySigners(s.getCertificatesAndCRLs("Collection", "BC"), s.getSignerInfos()); } public void testMimeMultipartBinaryParserGetMimeContent() throws Exception { MimeBodyPart m = createMultipartMessage(); List certList = new ArrayList(); certList.add(_signCert); certList.add(_origCert); CertStore certs = CertStore.getInstance("Collection", new CollectionCertStoreParameters(certList), "BC"); ASN1EncodableVector signedAttrs = generateSignedAttributes(); SMIMESignedGenerator gen = new SMIMESignedGenerator("binary"); gen.addSigner(_signKP.getPrivate(), _signCert, SMIMESignedGenerator.DIGEST_SHA1, new AttributeTable(signedAttrs), null); gen.addCertificatesAndCRLs(certs); MimeMultipart mm = gen.generate(m, "BC"); SMIMESignedParser s = new SMIMESignedParser(mm, "binary"); verifySigners(s.getCertificatesAndCRLs("Collection", "BC"), s.getSignerInfos()); MimeMessage bp = s.getContentAsMimeMessage(Session.getDefaultInstance(new Properties())); } private MimeBodyPart createMultipartMessage() throws MessagingException { MimeBodyPart msg1 = new MimeBodyPart(); msg1.setText("Hello part 1!\n"); MimeBodyPart msg2 = new MimeBodyPart(); msg2.setText("Hello part 2!\n"); MimeMultipart mp = new MimeMultipart(); mp.addBodyPart(msg1); mp.addBodyPart(msg2); MimeBodyPart m = new MimeBodyPart(); m.setContent(mp); return m; } public void testQuotable() throws Exception { MimeMessage message = loadMessage("quotable.message"); SMIMESigned s = new SMIMESigned((MimeMultipart)message.getContent()); verifySigners(s.getCertificatesAndCRLs("Collection", "BC"), s.getSignerInfos()); } public void testQuotableParser() throws Exception { MimeMessage message = loadMessage("quotable.message"); SMIMESignedParser s = new SMIMESignedParser((MimeMultipart)message.getContent()); verifySigners(s.getCertificatesAndCRLs("Collection", "BC"), s.getSignerInfos()); } public void testEmbeddedMulti() throws Exception { MimeMessage message = loadMessage("embeddedmulti.message"); SMIMESigned s = new SMIMESigned((MimeMultipart)message.getContent()); verifySigners(s.getCertificatesAndCRLs("Collection", "BC"), s.getSignerInfos()); } public void testEmbeddedMultiParser() throws Exception { MimeMessage message = loadMessage("embeddedmulti.message"); SMIMESignedParser s = new SMIMESignedParser((MimeMultipart)message.getContent()); verifySigners(s.getCertificatesAndCRLs("Collection", "BC"), s.getSignerInfos()); } public void testMultiAlternative() throws Exception { MimeMessage message = loadMessage("multi-alternative.eml"); SMIMESigned s = new SMIMESigned((MimeMultipart)message.getContent()); verifySigners(s.getCertificatesAndCRLs("Collection", "BC"), s.getSignerInfos()); } public void testExtraNlInPostamble() throws Exception { MimeMessage message = loadMessage("extra-nl.eml"); SMIMESigned s = new SMIMESigned((MimeMultipart)message.getContent()); verifySigners(s.getCertificatesAndCRLs("Collection", "BC"), s.getSignerInfos()); } public void testSignAttachmentOnly() throws Exception { MimeMessage m = loadMessage("attachonly.eml"); List certList = new ArrayList(); certList.add(_signCert); certList.add(_origCert); CertStore certs = CertStore.getInstance("Collection", new CollectionCertStoreParameters(certList), "BC"); ASN1EncodableVector signedAttrs = generateSignedAttributes(); SMIMESignedGenerator gen = new SMIMESignedGenerator("binary"); gen.addSigner(_signKP.getPrivate(), _signCert, SMIMESignedGenerator.DIGEST_SHA1, new AttributeTable(signedAttrs), null); gen.addCertificatesAndCRLs(certs); MimeMultipart mm = gen.generate(m, "BC"); SMIMESigned s = new SMIMESigned(mm); verifySigners(s.getCertificatesAndCRLs("Collection", "BC"), s.getSignerInfos()); SMIMESignedParser sp = new SMIMESignedParser(mm); verifySigners(sp.getCertificatesAndCRLs("Collection", "BC"), sp.getSignerInfos()); } public void testMultiAlternativeParser() throws Exception { MimeMessage message = loadMessage("multi-alternative.eml"); SMIMESignedParser s = new SMIMESignedParser((MimeMultipart)message.getContent()); verifySigners(s.getCertificatesAndCRLs("Collection", "BC"), s.getSignerInfos()); } public void testBasicAS2() throws Exception { MimeMessage message = loadMessage("basicAS2.message"); SMIMESigned s = new SMIMESigned((MimeMultipart)message.getContent()); verifySigners(s.getCertificatesAndCRLs("Collection", "BC"), s.getSignerInfos()); } public void testBasicAS2Parser() throws Exception { MimeMessage message = loadMessage("basicAS2.message"); SMIMESignedParser s = new SMIMESignedParser((MimeMultipart)message.getContent()); verifySigners(s.getCertificatesAndCRLs("Collection", "BC"), s.getSignerInfos()); } private String getDigestOid(SignerInformationStore s) { return ((SignerInformation)s.getSigners().iterator().next()).getDigestAlgOID(); } private void verifySigners(CertStore certs, SignerInformationStore signers) throws Exception { Collection c = signers.getSigners(); Iterator it = c.iterator(); while (it.hasNext()) { SignerInformation signer = (SignerInformation)it.next(); Collection certCollection = certs.getCertificates(selectorConverter.getCertSelector(signer.getSID())); Iterator certIt = certCollection.iterator(); X509Certificate cert = (X509Certificate)certIt.next(); assertEquals(true, signer.verify(cert, "BC")); } } private void verifyMessageBytes(MimeBodyPart a, MimeBodyPart b) throws Exception { ByteArrayOutputStream bOut1 = new ByteArrayOutputStream(); a.writeTo(bOut1); bOut1.close(); ByteArrayOutputStream bOut2 = new ByteArrayOutputStream(); b.writeTo(bOut2); bOut2.close(); assertEquals(true, Arrays.equals(bOut1.toByteArray(), bOut2.toByteArray())); } private ASN1EncodableVector generateSignedAttributes() { ASN1EncodableVector signedAttrs = new ASN1EncodableVector(); SMIMECapabilityVector caps = new SMIMECapabilityVector(); caps.addCapability(SMIMECapability.dES_EDE3_CBC); caps.addCapability(SMIMECapability.rC2_CBC, 128); caps.addCapability(SMIMECapability.dES_CBC); signedAttrs.add(new SMIMECapabilitiesAttribute(caps)); return signedAttrs; } private MimeMessage loadMessage(String name) throws MessagingException, FileNotFoundException { Session session = Session.getDefaultInstance(System.getProperties(), null); return new MimeMessage(session, getClass().getResourceAsStream(name)); } private MimeBodyPart createTemplate(String contentType, String contentTransferEncoding) throws UnsupportedEncodingException, MessagingException { byte[] content = "\n\n \n\n\n".getBytes("US-ASCII"); InternetHeaders ih = new InternetHeaders(); ih.setHeader("Content-Type", contentType); ih.setHeader("Content-Transfer-Encoding", contentTransferEncoding); return new MimeBodyPart(ih, content); } private String getMicAlg(MimeMultipart mm) { String contentType = mm.getContentType(); String micAlg = contentType.substring(contentType.indexOf("micalg=") + 7); return micAlg.substring(0, micAlg.indexOf(';')); } } bouncycastle-1.49.orig/test/jdk1.3/org/bouncycastle/i18n/0000755000175000017500000000000012152033550022437 5ustar ebourgebourgbouncycastle-1.49.orig/test/jdk1.3/org/bouncycastle/i18n/test/0000755000175000017500000000000012152033550023416 5ustar ebourgebourgbouncycastle-1.49.orig/test/jdk1.3/org/bouncycastle/i18n/test/AllTests.java0000644000175000017500000000115510621563607026030 0ustar ebourgebourg package org.bouncycastle.i18n.test; import org.bouncycastle.i18n.filter.test.HTMLFilterTest; import org.bouncycastle.i18n.filter.test.SQLFilterTest; import junit.framework.Test; import junit.framework.TestCase; import junit.framework.TestSuite; public class AllTests extends TestCase { public static void main (String[] args) { junit.textui.TestRunner.run (suite()); } public static Test suite() { TestSuite suite = new TestSuite("i18n tests"); suite.addTestSuite(HTMLFilterTest.class); suite.addTestSuite(SQLFilterTest.class); return suite; } } bouncycastle-1.49.orig/test/jdk1.3/org/bouncycastle/cms/0000755000175000017500000000000012152033550022442 5ustar ebourgebourgbouncycastle-1.49.orig/test/jdk1.3/org/bouncycastle/cms/test/0000755000175000017500000000000012152033550023421 5ustar ebourgebourgbouncycastle-1.49.orig/test/jdk1.3/org/bouncycastle/cms/test/ConverterTest.java0000644000175000017500000000743011726264414027112 0ustar ebourgebourgpackage org.bouncycastle.cms.test; import java.math.BigInteger; import org.bouncycastle.jce.cert.X509CertSelector; import junit.framework.Test; import junit.framework.TestCase; import junit.framework.TestSuite; import org.bouncycastle.asn1.DEROctetString; import org.bouncycastle.asn1.x500.X500Name; import org.bouncycastle.cms.KeyTransRecipientId; import org.bouncycastle.cms.SignerId; import org.bouncycastle.cms.jcajce.JcaSelectorConverter; import org.bouncycastle.cms.jcajce.JcaX509CertSelectorConverter; import org.bouncycastle.util.Arrays; public class ConverterTest extends TestCase { public void testSignerIdConversion() throws Exception { JcaX509CertSelectorConverter converter = new JcaX509CertSelectorConverter(); JcaSelectorConverter toSelector = new JcaSelectorConverter(); SignerId sid1 = new SignerId(new X500Name("CN=Test"), BigInteger.valueOf(1), new byte[20]); X509CertSelector conv = converter.getCertSelector(sid1); assertTrue(conv.getIssuerAsString().equals("CN=Test")); assertTrue(Arrays.areEqual(conv.getSubjectKeyIdentifier(), new DEROctetString(new byte[20]).getEncoded())); assertEquals(conv.getSerialNumber(), sid1.getSerialNumber()); SignerId sid2 = toSelector.getSignerId(conv); assertEquals(sid1, sid2); sid1 = new SignerId(new X500Name("CN=Test"), BigInteger.valueOf(1)); conv = converter.getCertSelector(sid1); assertTrue(conv.getIssuerAsString().equals("CN=Test")); assertNull(conv.getSubjectKeyIdentifier()); assertEquals(conv.getSerialNumber(), sid1.getSerialNumber()); sid2 = toSelector.getSignerId(conv); assertEquals(sid1, sid2); sid1 = new SignerId(new byte[20]); conv = converter.getCertSelector(sid1); assertNull(conv.getIssuerAsString()); assertTrue(Arrays.areEqual(conv.getSubjectKeyIdentifier(), new DEROctetString(new byte[20]).getEncoded())); assertNull(conv.getSerialNumber()); sid2 = toSelector.getSignerId(conv); assertEquals(sid1, sid2); } public void testRecipientIdConversion() throws Exception { JcaX509CertSelectorConverter converter = new JcaX509CertSelectorConverter(); JcaSelectorConverter toSelector = new JcaSelectorConverter(); KeyTransRecipientId ktid1 = new KeyTransRecipientId(new X500Name("CN=Test"), BigInteger.valueOf(1), new byte[20]); X509CertSelector conv = converter.getCertSelector(ktid1); assertTrue(conv.getIssuerAsString().equals("CN=Test")); assertTrue(Arrays.areEqual(conv.getSubjectKeyIdentifier(), new DEROctetString(new byte[20]).getEncoded())); assertEquals(conv.getSerialNumber(), ktid1.getSerialNumber()); KeyTransRecipientId ktid2 = toSelector.getKeyTransRecipientId(conv); assertEquals(ktid1, ktid2); ktid1 = new KeyTransRecipientId(new X500Name("CN=Test"), BigInteger.valueOf(1)); conv = converter.getCertSelector(ktid1); assertTrue(conv.getIssuerAsString().equals("CN=Test")); assertNull(conv.getSubjectKeyIdentifier()); assertEquals(conv.getSerialNumber(), ktid1.getSerialNumber()); ktid2 = toSelector.getKeyTransRecipientId(conv); assertEquals(ktid1, ktid2); ktid1 = new KeyTransRecipientId(new byte[20]); conv = converter.getCertSelector(ktid1); assertNull(conv.getIssuerAsString()); assertTrue(Arrays.areEqual(conv.getSubjectKeyIdentifier(), new DEROctetString(new byte[20]).getEncoded())); assertNull(conv.getSerialNumber()); ktid2 = toSelector.getKeyTransRecipientId(conv); assertEquals(ktid1, ktid2); } public static Test suite() throws Exception { return new TestSuite(ConverterTest.class); } } bouncycastle-1.49.orig/test/jdk1.3/org/bouncycastle/cms/test/Rfc4134Test.java0000644000175000017500000003425611726307327026200 0ustar ebourgebourgpackage org.bouncycastle.cms.test; import java.io.ByteArrayInputStream; import java.io.FileInputStream; import java.io.IOException; import java.security.KeyFactory; import java.security.MessageDigest; import java.security.NoSuchAlgorithmException; import java.security.NoSuchProviderException; import java.security.PrivateKey; import java.security.PublicKey; import java.security.Security; import org.bouncycastle.jce.cert.CertStore; import java.security.cert.CertificateFactory; import java.security.cert.X509Certificate; import java.security.interfaces.DSAParams; import java.security.interfaces.DSAPublicKey; import java.security.spec.DSAPublicKeySpec; import java.security.spec.InvalidKeySpecException; import java.security.spec.PKCS8EncodedKeySpec; import java.util.Arrays; import java.util.Collection; import java.util.Iterator; import junit.framework.Test; import junit.framework.TestCase; import junit.framework.TestSuite; import org.bouncycastle.asn1.ASN1EncodableVector; import org.bouncycastle.asn1.DERSequence; import org.bouncycastle.asn1.DERUTF8String; import org.bouncycastle.asn1.cms.Attribute; import org.bouncycastle.asn1.cms.AttributeTable; import org.bouncycastle.asn1.cms.CMSAttributes; import org.bouncycastle.asn1.cms.CMSObjectIdentifiers; import org.bouncycastle.asn1.pkcs.PKCSObjectIdentifiers; import org.bouncycastle.cms.CMSEnvelopedData; import org.bouncycastle.cms.CMSEnvelopedDataGenerator; import org.bouncycastle.cms.CMSEnvelopedDataParser; import org.bouncycastle.cms.CMSException; import org.bouncycastle.cms.CMSProcessableByteArray; import org.bouncycastle.cms.CMSSignedData; import org.bouncycastle.cms.CMSSignedDataParser; import org.bouncycastle.cms.CMSTypedStream; import org.bouncycastle.cms.RecipientInformation; import org.bouncycastle.cms.RecipientInformationStore; import org.bouncycastle.cms.SignerInformation; import org.bouncycastle.cms.SignerInformationStore; import org.bouncycastle.cms.jcajce.JcaX509CertSelectorConverter; import org.bouncycastle.jce.provider.BouncyCastleProvider; import org.bouncycastle.util.encoders.Hex; import org.bouncycastle.util.io.Streams; public class Rfc4134Test extends TestCase { private static final String BC = BouncyCastleProvider.PROVIDER_NAME; private static final String TEST_DATA_HOME = "bc.test.data.home"; private static byte[] exContent = getRfc4134Data("ExContent.bin"); private static byte[] sha1 = Hex.decode("406aec085279ba6e16022d9e0629c0229687dd48"); private static final JcaX509CertSelectorConverter selectorConverter = new JcaX509CertSelectorConverter(); public Rfc4134Test(String name) { super(name); } public static void main(String args[]) { Security.addProvider(new BouncyCastleProvider()); junit.textui.TestRunner.run(Rfc4134Test.class); } public static Test suite() throws Exception { return new CMSTestSetup(new TestSuite(Rfc4134Test.class)); } public void test4_1() throws Exception { byte[] data = getRfc4134Data("4.1.bin"); CMSSignedData signedData = new CMSSignedData(data); verifySignatures(signedData); CMSSignedDataParser parser = new CMSSignedDataParser(data); verifySignatures(parser); } public void test4_2() throws Exception { byte[] data = getRfc4134Data("4.2.bin"); CMSSignedData signedData = new CMSSignedData(data); verifySignatures(signedData); CMSSignedDataParser parser = new CMSSignedDataParser(data); verifySignatures(parser); } public void testRfc4_3() throws Exception { byte[] data = getRfc4134Data("4.3.bin"); CMSSignedData signedData = new CMSSignedData(new CMSProcessableByteArray(exContent), data); verifySignatures(signedData, sha1); CMSSignedDataParser parser = new CMSSignedDataParser( new CMSTypedStream(new ByteArrayInputStream(exContent)), data); verifySignatures(parser); } public void test4_4() throws Exception { byte[] data = getRfc4134Data("4.4.bin"); byte[] counterSigCert = getRfc4134Data("AliceRSASignByCarl.cer"); CMSSignedData signedData = new CMSSignedData(data); verifySignatures(signedData, sha1); verifySignerInfo4_4(getFirstSignerInfo(signedData.getSignerInfos()), counterSigCert); CMSSignedDataParser parser = new CMSSignedDataParser(data); verifySignatures(parser); verifySignerInfo4_4(getFirstSignerInfo(parser.getSignerInfos()), counterSigCert); } public void test4_5() throws Exception { byte[] data = getRfc4134Data("4.5.bin"); CMSSignedData signedData = new CMSSignedData(data); verifySignatures(signedData); CMSSignedDataParser parser = new CMSSignedDataParser(data); verifySignatures(parser); } public void test4_6() throws Exception { byte[] data = getRfc4134Data("4.6.bin"); CMSSignedData signedData = new CMSSignedData(data); verifySignatures(signedData); CMSSignedDataParser parser = new CMSSignedDataParser(data); verifySignatures(parser); } public void test4_7() throws Exception { byte[] data = getRfc4134Data("4.7.bin"); CMSSignedData signedData = new CMSSignedData(data); verifySignatures(signedData); CMSSignedDataParser parser = new CMSSignedDataParser(data); verifySignatures(parser); } public void test5_1() throws Exception { byte[] data = getRfc4134Data("5.1.bin"); CMSEnvelopedData envelopedData = new CMSEnvelopedData(data); verifyEnvelopedData(envelopedData, CMSEnvelopedDataGenerator.DES_EDE3_CBC); CMSEnvelopedDataParser envelopedParser = new CMSEnvelopedDataParser(data); verifyEnvelopedData(envelopedParser, CMSEnvelopedDataGenerator.DES_EDE3_CBC); } public void test5_2() throws Exception { byte[] data = getRfc4134Data("5.2.bin"); CMSEnvelopedData envelopedData = new CMSEnvelopedData(data); verifyEnvelopedData(envelopedData, CMSEnvelopedDataGenerator.RC2_CBC); CMSEnvelopedDataParser envelopedParser = new CMSEnvelopedDataParser(data); verifyEnvelopedData(envelopedParser, CMSEnvelopedDataGenerator.RC2_CBC); } private void verifyEnvelopedData(CMSEnvelopedData envelopedData, String symAlgorithmOID) throws NoSuchAlgorithmException, NoSuchProviderException, InvalidKeySpecException, CMSException { byte[] privKeyData = getRfc4134Data("BobPrivRSAEncrypt.pri"); PKCS8EncodedKeySpec keySpec = new PKCS8EncodedKeySpec(privKeyData); KeyFactory keyFact = KeyFactory.getInstance("RSA", BC); PrivateKey privKey = keyFact.generatePrivate(keySpec); RecipientInformationStore recipients = envelopedData.getRecipientInfos(); assertEquals(envelopedData.getEncryptionAlgOID(), symAlgorithmOID); Collection c = recipients.getRecipients(); assertTrue(c.size() >= 1 && c.size() <= 2); Iterator it = c.iterator(); verifyRecipient((RecipientInformation)it.next(), privKey); if (c.size() == 2) { RecipientInformation recInfo = (RecipientInformation)it.next(); assertEquals(PKCSObjectIdentifiers.id_alg_CMSRC2wrap.getId(), recInfo.getKeyEncryptionAlgOID()); } } private void verifyEnvelopedData(CMSEnvelopedDataParser envelopedParser, String symAlgorithmOID) throws NoSuchAlgorithmException, NoSuchProviderException, InvalidKeySpecException, CMSException { byte[] privKeyData = getRfc4134Data("BobPrivRSAEncrypt.pri"); PKCS8EncodedKeySpec keySpec = new PKCS8EncodedKeySpec(privKeyData); KeyFactory keyFact = KeyFactory.getInstance("RSA", BC); PrivateKey privKey = keyFact.generatePrivate(keySpec); RecipientInformationStore recipients = envelopedParser.getRecipientInfos(); assertEquals(envelopedParser.getEncryptionAlgOID(), symAlgorithmOID); Collection c = recipients.getRecipients(); assertTrue(c.size() >= 1 && c.size() <= 2); Iterator it = c.iterator(); verifyRecipient((RecipientInformation)it.next(), privKey); if (c.size() == 2) { RecipientInformation recInfo = (RecipientInformation)it.next(); assertEquals(PKCSObjectIdentifiers.id_alg_CMSRC2wrap.getId(), recInfo.getKeyEncryptionAlgOID()); } } private void verifyRecipient(RecipientInformation recipient, PrivateKey privKey) throws CMSException, NoSuchProviderException { assertEquals(recipient.getKeyEncryptionAlgOID(), PKCSObjectIdentifiers.rsaEncryption.getId()); byte[] recData = recipient.getContent(privKey, BC); assertEquals(true, Arrays.equals(exContent, recData)); } private void verifySignerInfo4_4(SignerInformation signerInfo, byte[] counterSigCert) throws Exception { verifyCounterSignature(signerInfo, counterSigCert); verifyContentHint(signerInfo); } private SignerInformation getFirstSignerInfo(SignerInformationStore store) { return (SignerInformation)store.getSigners().iterator().next(); } private void verifyCounterSignature(SignerInformation signInfo, byte[] certificate) throws Exception { SignerInformation csi = (SignerInformation)signInfo.getCounterSignatures().getSigners().iterator().next(); CertificateFactory certFact = CertificateFactory.getInstance("X.509", BC); X509Certificate cert = (X509Certificate)certFact.generateCertificate(new ByteArrayInputStream(certificate)); assertTrue(csi.verify(cert, BC)); } private void verifyContentHint(SignerInformation signInfo) { AttributeTable attrTable = signInfo.getUnsignedAttributes(); Attribute attr = attrTable.get(CMSAttributes.contentHint); assertEquals(1, attr.getAttrValues().size()); ASN1EncodableVector v = new ASN1EncodableVector(); v.add(new DERUTF8String("Content Hints Description Buffer")); v.add(CMSObjectIdentifiers.data); assertTrue(attr.getAttrValues().getObjectAt(0).equals(new DERSequence(v))); } private void verifySignatures(CMSSignedData s, byte[] contentDigest) throws Exception { CertStore certStore = s.getCertificatesAndCRLs("Collection", BC); SignerInformationStore signers = s.getSignerInfos(); Collection c = signers.getSigners(); Iterator it = c.iterator(); while (it.hasNext()) { SignerInformation signer = (SignerInformation)it.next(); Collection certCollection = certStore.getCertificates(selectorConverter.getCertSelector(signer.getSID())); Iterator certIt = certCollection.iterator(); X509Certificate cert = (X509Certificate)certIt.next(); verifySigner(signer, cert); if (contentDigest != null) { assertTrue(MessageDigest.isEqual(contentDigest, signer.getContentDigest())); } } Collection certColl = certStore.getCertificates(null); Collection crlColl = certStore.getCRLs(null); assertEquals(certColl.size(), s.getCertificates("Collection", BC).getMatches(null).size()); assertEquals(crlColl.size(), s.getCRLs("Collection", BC).getMatches(null).size()); } private void verifySignatures(CMSSignedData s) throws Exception { verifySignatures(s, null); } private void verifySignatures(CMSSignedDataParser sp) throws Exception { CMSTypedStream sc = sp.getSignedContent(); if (sc != null) { sc.drain(); } CertStore certs = sp.getCertificatesAndCRLs("Collection", BC); SignerInformationStore signers = sp.getSignerInfos(); Collection c = signers.getSigners(); Iterator it = c.iterator(); while (it.hasNext()) { SignerInformation signer = (SignerInformation)it.next(); Collection certCollection = certs.getCertificates(selectorConverter.getCertSelector(signer.getSID())); Iterator certIt = certCollection.iterator(); X509Certificate cert = (X509Certificate)certIt.next(); verifySigner(signer, cert); } } private void verifySigner(SignerInformation signer, X509Certificate cert) throws Exception { if (cert.getPublicKey() instanceof DSAPublicKey) { DSAPublicKey key = (DSAPublicKey)cert.getPublicKey(); if (key.getParams() == null) { assertEquals(true, signer.verify(getInheritedKey(key), BC)); } else { assertEquals(true, signer.verify(cert, BC)); } } else { assertEquals(true, signer.verify(cert, BC)); } } private PublicKey getInheritedKey(DSAPublicKey key) throws Exception { CertificateFactory certFact = CertificateFactory.getInstance("X.509", BC); X509Certificate cert = (X509Certificate)certFact.generateCertificate(new ByteArrayInputStream(getRfc4134Data("CarlDSSSelf.cer"))); DSAParams dsaParams = ((DSAPublicKey)cert.getPublicKey()).getParams(); DSAPublicKeySpec dsaPubKeySpec = new DSAPublicKeySpec( key.getY(), dsaParams.getP(), dsaParams.getQ(), dsaParams.getG()); KeyFactory keyFactory = KeyFactory.getInstance("DSA", BC); return keyFactory.generatePublic(dsaPubKeySpec); } private static byte[] getRfc4134Data(String name) { String dataHome = System.getProperty(TEST_DATA_HOME); if (dataHome == null) { throw new IllegalStateException(TEST_DATA_HOME + " property not set"); } try { return Streams.readAll(new FileInputStream(dataHome + "/rfc4134/" + name)); } catch (IOException e) { throw new RuntimeException(e.toString()); } } } bouncycastle-1.49.orig/test/jdk1.3/org/bouncycastle/cms/test/SignedDataTest.java0000644000175000017500000017773511726307327027167 0ustar ebourgebourgpackage org.bouncycastle.cms.test; import java.io.ByteArrayInputStream; import java.io.IOException; import java.security.KeyFactory; import java.security.KeyPair; import java.security.MessageDigest; import java.security.NoSuchAlgorithmException; import org.bouncycastle.jce.cert.CertStore; import org.bouncycastle.jce.cert.CollectionCertStoreParameters; import java.security.cert.X509CRL; import java.security.cert.X509Certificate; import java.security.spec.PKCS8EncodedKeySpec; import java.security.spec.X509EncodedKeySpec; import java.util.ArrayList; import java.util.Collection; import java.util.Collections; import java.util.HashMap; import java.util.Iterator; import java.util.List; import java.util.Map; import junit.framework.Test; import junit.framework.TestCase; import junit.framework.TestSuite; import org.bouncycastle.asn1.ASN1EncodableVector; import org.bouncycastle.asn1.ASN1InputStream; import org.bouncycastle.asn1.ASN1OctetString; import org.bouncycastle.asn1.DEROctetString; import org.bouncycastle.asn1.DERSet; import org.bouncycastle.asn1.cms.Attribute; import org.bouncycastle.asn1.cms.AttributeTable; import org.bouncycastle.asn1.cms.CMSAttributes; import org.bouncycastle.asn1.cms.ContentInfo; import org.bouncycastle.asn1.oiw.OIWObjectIdentifiers; import org.bouncycastle.asn1.pkcs.PKCSObjectIdentifiers; import org.bouncycastle.cms.CMSConfig; import org.bouncycastle.cms.CMSProcessable; import org.bouncycastle.cms.CMSProcessableByteArray; import org.bouncycastle.cms.CMSSignedData; import org.bouncycastle.cms.CMSSignedDataGenerator; import org.bouncycastle.cms.CMSSignedDataParser; import org.bouncycastle.cms.SignerId; import org.bouncycastle.cms.SignerInformation; import org.bouncycastle.cms.SignerInformationStore; import org.bouncycastle.cms.jcajce.JcaX509CertSelectorConverter; import org.bouncycastle.jce.provider.BouncyCastleProvider; import org.bouncycastle.util.encoders.Base64; import org.bouncycastle.util.io.Streams; import org.bouncycastle.x509.X509AttributeCertificate; import org.bouncycastle.x509.X509CollectionStoreParameters; import org.bouncycastle.x509.X509Store; public class SignedDataTest extends TestCase { private static final String BC = BouncyCastleProvider.PROVIDER_NAME; boolean DEBUG = true; private static String _origDN; private static KeyPair _origKP; private static X509Certificate _origCert; private static String _signDN; private static KeyPair _signKP; private static X509Certificate _signCert; private static KeyPair _signGostKP; private static X509Certificate _signGostCert; private static KeyPair _signEcDsaKP; private static X509Certificate _signEcDsaCert; private static KeyPair _signEcGostKP; private static X509Certificate _signEcGostCert; private static KeyPair _signDsaKP; private static X509Certificate _signDsaCert; private static String _reciDN; private static KeyPair _reciKP; private static X509Certificate _reciCert; private static X509CRL _signCrl; private static boolean _initialised = false; private byte[] disorderedMessage = Base64.decode( "SU9fc3RkaW5fdXNlZABfX2xpYmNfc3RhcnRfbWFpbgBnZXRob3N0aWQAX19n" + "bW9uX3M="); private byte[] disorderedSet = Base64.decode( "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" + "gQBpSRdnDb6AcNVaXSmGo6+kVPIBhot1LzJOGaPyDNpGXxd7LV4tMBF1U7gr" + "4k1g9BO6YiMWvw9uiTZmn0CfV8+k4fWEuG/nmafRoGIuay2f+ILuT+C0rnp1" + "4FgMsEhuVNJJAmb12QV0PZII+UneyhAneZuQQzVUkTcVgYxogxdSOzCCAlUw" + "ggHBoAMCAQICBACdekowCgYGKyQDAwECBQAwbzELMAkGA1UEBhMCREUxPTA7" + "BgNVBAoUNFJlZ3VsaWVydW5nc2JlaMhvcmRlIGbIdXIgVGVsZWtvbW11bmlr" + "YXRpb24gdW5kIFBvc3QxITAMBgcCggYBCgcUEwExMBEGA1UEAxQKNlItQ2Eg" + "MTpQTjAiGA8yMDAxMDIwMTEzNDcwN1oYDzIwMDUwMzIyMDg1NTUxWjBvMQsw" + "CQYDVQQGEwJERTE9MDsGA1UEChQ0UmVndWxpZXJ1bmdzYmVoyG9yZGUgZsh1" + "ciBUZWxla29tbXVuaWthdGlvbiB1bmQgUG9zdDEhMAwGBwKCBgEKBxQTATEw" + "EQYDVQQDFAo1Ui1DQSAxOlBOMIGhMA0GCSqGSIb3DQEBAQUAA4GPADCBiwKB" + "gQCKHkFTJx8GmoqFTxEOxpK9XkC3NZ5dBEKiUv0Ife3QMqeGMoCUnyJxwW0k" + "2/53duHxtv2yHSZpFKjrjvE/uGwdOMqBMTjMzkFg19e9JPv061wyADOucOIa" + "NAgha/zFt9XUyrHF21knKCvDNExv2MYIAagkTKajLMAw0bu1J0FadQIFAMAA" + "AAEwCgYGKyQDAwECBQADgYEAV1yTi+2gyB7sUhn4PXmi/tmBxAfe5oBjDW8m" + "gxtfudxKGZ6l/FUPNcrSc5oqBYxKWtLmf3XX87LcblYsch617jtNTkMzhx9e" + "qxiD02ufcrxz2EVt0Akdqiz8mdVeqp3oLcNU/IttpSrcA91CAnoUXtDZYwb/" + "gdQ4FI9l3+qo/0UwggJVMIIBwaADAgECAgQAxIymMAoGBiskAwMBAgUAMG8x" + "CzAJBgNVBAYTAkRFMT0wOwYDVQQKFDRSZWd1bGllcnVuZ3NiZWjIb3JkZSBm" + "yHVyIFRlbGVrb21tdW5pa2F0aW9uIHVuZCBQb3N0MSEwDAYHAoIGAQoHFBMB" + "MTARBgNVBAMUCjZSLUNhIDE6UE4wIhgPMjAwMTEwMTUxMzMxNThaGA8yMDA1" + "MDYwMTA5NTIxN1owbzELMAkGA1UEBhMCREUxPTA7BgNVBAoUNFJlZ3VsaWVy" + "dW5nc2JlaMhvcmRlIGbIdXIgVGVsZWtvbW11bmlrYXRpb24gdW5kIFBvc3Qx" + "ITAMBgcCggYBCgcUEwExMBEGA1UEAxQKN1ItQ0EgMTpQTjCBoTANBgkqhkiG" + "9w0BAQEFAAOBjwAwgYsCgYEAiokD/j6lEP4FexF356OpU5teUpGGfUKjIrFX" + "BHc79G0TUzgVxqMoN1PWnWktQvKo8ETaugxLkP9/zfX3aAQzDW4Zki6x6GDq" + "fy09Agk+RJvhfbbIzRkV4sBBco0n73x7TfG/9NTgVr/96U+I+z/1j30aboM6" + "9OkLEhjxAr0/GbsCBQDAAAABMAoGBiskAwMBAgUAA4GBAHWRqRixt+EuqHhR" + "K1kIxKGZL2vZuakYV0R24Gv/0ZR52FE4ECr+I49o8FP1qiGSwnXB0SwjuH2S" + "iGiSJi+iH/MeY85IHwW1P5e+bOMvEOFhZhQXQixOD7totIoFtdyaj1XGYRef" + "0f2cPOjNJorXHGV8wuBk+/j++sxbd/Net3FtMIICVTCCAcGgAwIBAgIEAMSM" + "pzAKBgYrJAMDAQIFADBvMQswCQYDVQQGEwJERTE9MDsGA1UEChQ0UmVndWxp" + "ZXJ1bmdzYmVoyG9yZGUgZsh1ciBUZWxla29tbXVuaWthdGlvbiB1bmQgUG9z" + "dDEhMAwGBwKCBgEKBxQTATEwEQYDVQQDFAo3Ui1DQSAxOlBOMCIYDzIwMDEx" + "MDE1MTMzNDE0WhgPMjAwNTA2MDEwOTUyMTdaMG8xCzAJBgNVBAYTAkRFMT0w" + "OwYDVQQKFDRSZWd1bGllcnVuZ3NiZWjIb3JkZSBmyHVyIFRlbGVrb21tdW5p" + "a2F0aW9uIHVuZCBQb3N0MSEwDAYHAoIGAQoHFBMBMTARBgNVBAMUCjZSLUNh" + "IDE6UE4wgaEwDQYJKoZIhvcNAQEBBQADgY8AMIGLAoGBAIOiqxUkzVyqnvth" + "ihnltsE5m1Xn5TZKeR/2MQPStc5hJ+V4yptEtIx+Fn5rOoqT5VEVWhcE35wd" + "bPvgJyQFn5msmhPQT/6XSGOlrWRoFummXN9lQzAjCj1sgTcmoLCVQ5s5WpCA" + "OXFwVWu16qndz3sPItn3jJ0F3Kh3w79NglvPAgUAwAAAATAKBgYrJAMDAQIF" + "AAOBgQBi5W96UVDoNIRkCncqr1LLG9vF9SGBIkvFpLDIIbcvp+CXhlvsdCJl" + "0pt2QEPSDl4cmpOet+CxJTdTuMeBNXxhb7Dvualog69w/+K2JbPhZYxuVFZs" + "Zh5BkPn2FnbNu3YbJhE60aIkikr72J4XZsI5DxpZCGh6xyV/YPRdKSljFjCC" + "AlQwggHAoAMCAQICAwyDqzAKBgYrJAMDAQIFADBvMQswCQYDVQQGEwJERTE9" + "MDsGA1UEChQ0UmVndWxpZXJ1bmdzYmVoyG9yZGUgZsh1ciBUZWxla29tbXVu" + "aWthdGlvbiB1bmQgUG9zdDEhMAwGBwKCBgEKBxQTATEwEQYDVQQDFAo1Ui1D" + "QSAxOlBOMCIYDzIwMDAwMzIyMDk0MTI3WhgPMjAwNDAxMjExNjA0NTNaMG8x" + "CzAJBgNVBAYTAkRFMT0wOwYDVQQKFDRSZWd1bGllcnVuZ3NiZWjIb3JkZSBm" + "yHVyIFRlbGVrb21tdW5pa2F0aW9uIHVuZCBQb3N0MSEwDAYHAoIGAQoHFBMB" + "MTARBgNVBAMUCjRSLUNBIDE6UE4wgaEwDQYJKoZIhvcNAQEBBQADgY8AMIGL" + "AoGBAI8x26tmrFJanlm100B7KGlRemCD1R93PwdnG7svRyf5ZxOsdGrDszNg" + "xg6ouO8ZHQMT3NC2dH8TvO65Js+8bIyTm51azF6clEg0qeWNMKiiXbBXa+ph" + "hTkGbXiLYvACZ6/MTJMJ1lcrjpRF7BXtYeYMcEF6znD4pxOqrtbf9z5hAgUA" + "wAAAATAKBgYrJAMDAQIFAAOBgQB99BjSKlGPbMLQAgXlvA9jUsDNhpnVm3a1" + "YkfxSqS/dbQlYkbOKvCxkPGA9NBxisBM8l1zFynVjJoy++aysRmcnLY/sHaz" + "23BF2iU7WERy18H3lMBfYB6sXkfYiZtvQZcWaO48m73ZBySuiV3iXpb2wgs/" + "Cs20iqroAWxwq/W/9jCCAlMwggG/oAMCAQICBDsFZ9UwCgYGKyQDAwECBQAw" + "bzELMAkGA1UEBhMCREUxITAMBgcCggYBCgcUEwExMBEGA1UEAxQKNFItQ0Eg" + "MTpQTjE9MDsGA1UEChQ0UmVndWxpZXJ1bmdzYmVoyG9yZGUgZsh1ciBUZWxl" + "a29tbXVuaWthdGlvbiB1bmQgUG9zdDAiGA8xOTk5MDEyMTE3MzUzNFoYDzIw" + "MDQwMTIxMTYwMDAyWjBvMQswCQYDVQQGEwJERTE9MDsGA1UEChQ0UmVndWxp" + "ZXJ1bmdzYmVoyG9yZGUgZsh1ciBUZWxla29tbXVuaWthdGlvbiB1bmQgUG9z" + "dDEhMAwGBwKCBgEKBxQTATEwEQYDVQQDFAozUi1DQSAxOlBOMIGfMA0GCSqG" + "SIb3DQEBAQUAA4GNADCBiQKBgI4B557mbKQg/AqWBXNJhaT/6lwV93HUl4U8" + "u35udLq2+u9phns1WZkdM3gDfEpL002PeLfHr1ID/96dDYf04lAXQfombils" + "of1C1k32xOvxjlcrDOuPEMxz9/HDAQZA5MjmmYHAIulGI8Qg4Tc7ERRtg/hd" + "0QX0/zoOeXoDSEOBAgTAAAABMAoGBiskAwMBAgUAA4GBAIyzwfT3keHI/n2P" + "LrarRJv96mCohmDZNpUQdZTVjGu5VQjVJwk3hpagU0o/t/FkdzAjOdfEw8Ql" + "3WXhfIbNLv1YafMm2eWSdeYbLcbB5yJ1od+SYyf9+tm7cwfDAcr22jNRBqx8" + "wkWKtKDjWKkevaSdy99sAI8jebHtWz7jzydKMIID9TCCA16gAwIBAgICbMcw" + "DQYJKoZIhvcNAQEFBQAwSzELMAkGA1UEBhMCREUxEjAQBgNVBAoUCVNpZ250" + "cnVzdDEoMAwGBwKCBgEKBxQTATEwGAYDVQQDFBFDQSBTSUdOVFJVU1QgMTpQ" + "TjAeFw0wNDA3MzAxMzAyNDZaFw0wNzA3MzAxMzAyNDZaMDwxETAPBgNVBAMM" + "CFlhY29tOlBOMQ4wDAYDVQRBDAVZYWNvbTELMAkGA1UEBhMCREUxCjAIBgNV" + "BAUTATEwgZ8wDQYJKoZIhvcNAQEBBQADgY0AMIGJAoGBAIWzLlYLQApocXIp" + "pgCCpkkOUVLgcLYKeOd6/bXAnI2dTHQqT2bv7qzfUnYvOqiNgYdF13pOYtKg" + "XwXMTNFL4ZOI6GoBdNs9TQiZ7KEWnqnr2945HYx7UpgTBclbOK/wGHuCdcwO" + "x7juZs1ZQPFG0Lv8RoiV9s6HP7POqh1sO0P/AgMBAAGjggH1MIIB8TCBnAYD" + "VR0jBIGUMIGRgBQcZzNghfnXoXRm8h1+VITC5caNRqFzpHEwbzELMAkGA1UE" + "BhMCREUxPTA7BgNVBAoUNFJlZ3VsaWVydW5nc2JlaMhvcmRlIGbIdXIgVGVs" + "ZWtvbW11bmlrYXRpb24gdW5kIFBvc3QxITAMBgcCggYBCgcUEwExMBEGA1UE" + "AxQKNVItQ0EgMTpQToIEALs8rjAdBgNVHQ4EFgQU2e5KAzkVuKaM9I5heXkz" + "bcAIuR8wDgYDVR0PAQH/BAQDAgZAMBIGA1UdIAQLMAkwBwYFKyQIAQEwfwYD" + "VR0fBHgwdjB0oCygKoYobGRhcDovL2Rpci5zaWdudHJ1c3QuZGUvbz1TaWdu" + "dHJ1c3QsYz1kZaJEpEIwQDEdMBsGA1UEAxMUQ1JMU2lnblNpZ250cnVzdDE6" + "UE4xEjAQBgNVBAoTCVNpZ250cnVzdDELMAkGA1UEBhMCREUwYgYIKwYBBQUH" + "AQEEVjBUMFIGCCsGAQUFBzABhkZodHRwOi8vZGlyLnNpZ250cnVzdC5kZS9T" + "aWdudHJ1c3QvT0NTUC9zZXJ2bGV0L2h0dHBHYXRld2F5LlBvc3RIYW5kbGVy" + "MBgGCCsGAQUFBwEDBAwwCjAIBgYEAI5GAQEwDgYHAoIGAQoMAAQDAQH/MA0G" + "CSqGSIb3DQEBBQUAA4GBAHn1m3GcoyD5GBkKUY/OdtD6Sj38LYqYCF+qDbJR" + "6pqUBjY2wsvXepUppEler+stH8mwpDDSJXrJyuzf7xroDs4dkLl+Rs2x+2tg" + "BjU+ABkBDMsym2WpwgA8LCdymmXmjdv9tULxY+ec2pjSEzql6nEZNEfrU8nt" + "ZCSCavgqW4TtMYIBejCCAXYCAQEwUTBLMQswCQYDVQQGEwJERTESMBAGA1UE" + "ChQJU2lnbnRydXN0MSgwDAYHAoIGAQoHFBMBMTAYBgNVBAMUEUNBIFNJR05U" + "UlVTVCAxOlBOAgJsxzAJBgUrDgMCGgUAoIGAMBgGCSqGSIb3DQEJAzELBgkq" + "hkiG9w0BBwEwIwYJKoZIhvcNAQkEMRYEFIYfhPoyfGzkLWWSSLjaHb4HQmaK" + "MBwGCSqGSIb3DQEJBTEPFw0wNTAzMjQwNzM4MzVaMCEGBSskCAYFMRgWFi92" + "YXIvZmlsZXMvdG1wXzEvdGVzdDEwDQYJKoZIhvcNAQEFBQAEgYA2IvA8lhVz" + "VD5e/itUxbFboKxeKnqJ5n/KuO/uBCl1N14+7Z2vtw1sfkIG+bJdp3OY2Cmn" + "mrQcwsN99Vjal4cXVj8t+DJzFG9tK9dSLvD3q9zT/GQ0kJXfimLVwCa4NaSf" + "Qsu4xtG0Rav6bCcnzabAkKuNNvKtH8amSRzk870DBg=="); public static byte[] xtraCounterSig = Base64.decode( "MIIR/AYJKoZIhvcNAQcCoIIR7TCCEekCAQExCzAJBgUrDgMCGgUAMBoGCSqG" + "SIb3DQEHAaANBAtIZWxsbyB3b3JsZKCCDnkwggTPMIIDt6ADAgECAgRDnYD3" + "MA0GCSqGSIb3DQEBBQUAMFgxCzAJBgNVBAYTAklUMRowGAYDVQQKExFJbi5U" + "ZS5TLkEuIFMucC5BLjEtMCsGA1UEAxMkSW4uVGUuUy5BLiAtIENlcnRpZmlj" + "YXRpb24gQXV0aG9yaXR5MB4XDTA4MDkxMjExNDMxMloXDTEwMDkxMjExNDMx" + "MlowgdgxCzAJBgNVBAYTAklUMSIwIAYDVQQKDBlJbnRlc2EgUy5wLkEuLzA1" + "MjYyODkwMDE0MSowKAYDVQQLDCFCdXNpbmVzcyBDb2xsYWJvcmF0aW9uICYg" + "U2VjdXJpdHkxHjAcBgNVBAMMFU1BU1NJTUlMSUFOTyBaSUNDQVJESTERMA8G" + "A1UEBAwIWklDQ0FSREkxFTATBgNVBCoMDE1BU1NJTUlMSUFOTzEcMBoGA1UE" + "BRMTSVQ6WkNDTVNNNzZIMTRMMjE5WTERMA8GA1UELhMIMDAwMDI1ODUwgaAw" + "DQYJKoZIhvcNAQEBBQADgY4AMIGKAoGBALeJTjmyFgx1SIP6c2AuB/kuyHo5" + "j/prKELTALsFDimre/Hxr3wOSet1TdQfFzU8Lu+EJqgfV9cV+cI1yeH1rZs7" + "lei7L3tX/VR565IywnguX5xwvteASgWZr537Fkws50bvTEMyYOj1Tf3FZvZU" + "z4n4OD39KI4mfR9i1eEVIxR3AgQAizpNo4IBoTCCAZ0wHQYDVR0RBBYwFIES" + "emljY2FyZGlAaW50ZXNhLml0MC8GCCsGAQUFBwEDBCMwITAIBgYEAI5GAQEw" + "CwYGBACORgEDAgEUMAgGBgQAjkYBBDBZBgNVHSAEUjBQME4GBgQAizABATBE" + "MEIGCCsGAQUFBwIBFjZodHRwOi8vZS10cnVzdGNvbS5pbnRlc2EuaXQvY2Ff" + "cHViYmxpY2EvQ1BTX0lOVEVTQS5odG0wDgYDVR0PAQH/BAQDAgZAMIGDBgNV" + "HSMEfDB6gBQZCQOW0bjFWBt+EORuxPagEgkQqKFcpFowWDELMAkGA1UEBhMC" + "SVQxGjAYBgNVBAoTEUluLlRlLlMuQS4gUy5wLkEuMS0wKwYDVQQDEyRJbi5U" + "ZS5TLkEuIC0gQ2VydGlmaWNhdGlvbiBBdXRob3JpdHmCBDzRARMwOwYDVR0f" + "BDQwMjAwoC6gLIYqaHR0cDovL2UtdHJ1c3Rjb20uaW50ZXNhLml0L0NSTC9J" + "TlRFU0EuY3JsMB0GA1UdDgQWBBTf5ItL8KmQh541Dxt7YxcWI1254TANBgkq" + "hkiG9w0BAQUFAAOCAQEAgW+uL1CVWQepbC/wfCmR6PN37Sueb4xiKQj2mTD5" + "UZ5KQjpivy/Hbuf0NrfKNiDEhAvoHSPC31ebGiKuTMFNyZPHfPEUnyYGSxea" + "2w837aXJFr6utPNQGBRi89kH90sZDlXtOSrZI+AzJJn5QK3F9gjcayU2NZXQ" + "MJgRwYmFyn2w4jtox+CwXPQ9E5XgxiMZ4WDL03cWVXDLX00EOJwnDDMUNTRI" + "m9Zv+4SKTNlfFbi9UTBqWBySkDzAelsfB2U61oqc2h1xKmCtkGMmN9iZT+Qz" + "ZC/vaaT+hLEBFGAH2gwFrYc4/jTBKyBYeU1vsAxsibIoTs1Apgl6MH75qPDL" + "BzCCBM8wggO3oAMCAQICBEOdgPcwDQYJKoZIhvcNAQEFBQAwWDELMAkGA1UE" + "BhMCSVQxGjAYBgNVBAoTEUluLlRlLlMuQS4gUy5wLkEuMS0wKwYDVQQDEyRJ" + "bi5UZS5TLkEuIC0gQ2VydGlmaWNhdGlvbiBBdXRob3JpdHkwHhcNMDgwOTEy" + "MTE0MzEyWhcNMTAwOTEyMTE0MzEyWjCB2DELMAkGA1UEBhMCSVQxIjAgBgNV" + "BAoMGUludGVzYSBTLnAuQS4vMDUyNjI4OTAwMTQxKjAoBgNVBAsMIUJ1c2lu" + "ZXNzIENvbGxhYm9yYXRpb24gJiBTZWN1cml0eTEeMBwGA1UEAwwVTUFTU0lN" + "SUxJQU5PIFpJQ0NBUkRJMREwDwYDVQQEDAhaSUNDQVJESTEVMBMGA1UEKgwM" + "TUFTU0lNSUxJQU5PMRwwGgYDVQQFExNJVDpaQ0NNU003NkgxNEwyMTlZMREw" + "DwYDVQQuEwgwMDAwMjU4NTCBoDANBgkqhkiG9w0BAQEFAAOBjgAwgYoCgYEA" + "t4lOObIWDHVIg/pzYC4H+S7IejmP+msoQtMAuwUOKat78fGvfA5J63VN1B8X" + "NTwu74QmqB9X1xX5wjXJ4fWtmzuV6Lsve1f9VHnrkjLCeC5fnHC+14BKBZmv" + "nfsWTCznRu9MQzJg6PVN/cVm9lTPifg4Pf0ojiZ9H2LV4RUjFHcCBACLOk2j" + "ggGhMIIBnTAdBgNVHREEFjAUgRJ6aWNjYXJkaUBpbnRlc2EuaXQwLwYIKwYB" + "BQUHAQMEIzAhMAgGBgQAjkYBATALBgYEAI5GAQMCARQwCAYGBACORgEEMFkG" + "A1UdIARSMFAwTgYGBACLMAEBMEQwQgYIKwYBBQUHAgEWNmh0dHA6Ly9lLXRy" + "dXN0Y29tLmludGVzYS5pdC9jYV9wdWJibGljYS9DUFNfSU5URVNBLmh0bTAO" + "BgNVHQ8BAf8EBAMCBkAwgYMGA1UdIwR8MHqAFBkJA5bRuMVYG34Q5G7E9qAS" + "CRCooVykWjBYMQswCQYDVQQGEwJJVDEaMBgGA1UEChMRSW4uVGUuUy5BLiBT" + "LnAuQS4xLTArBgNVBAMTJEluLlRlLlMuQS4gLSBDZXJ0aWZpY2F0aW9uIEF1" + "dGhvcml0eYIEPNEBEzA7BgNVHR8ENDAyMDCgLqAshipodHRwOi8vZS10cnVz" + "dGNvbS5pbnRlc2EuaXQvQ1JML0lOVEVTQS5jcmwwHQYDVR0OBBYEFN/ki0vw" + "qZCHnjUPG3tjFxYjXbnhMA0GCSqGSIb3DQEBBQUAA4IBAQCBb64vUJVZB6ls" + "L/B8KZHo83ftK55vjGIpCPaZMPlRnkpCOmK/L8du5/Q2t8o2IMSEC+gdI8Lf" + "V5saIq5MwU3Jk8d88RSfJgZLF5rbDzftpckWvq6081AYFGLz2Qf3SxkOVe05" + "Ktkj4DMkmflArcX2CNxrJTY1ldAwmBHBiYXKfbDiO2jH4LBc9D0TleDGIxnh" + "YMvTdxZVcMtfTQQ4nCcMMxQ1NEib1m/7hIpM2V8VuL1RMGpYHJKQPMB6Wx8H" + "ZTrWipzaHXEqYK2QYyY32JlP5DNkL+9ppP6EsQEUYAfaDAWthzj+NMErIFh5" + "TW+wDGyJsihOzUCmCXowfvmo8MsHMIIEzzCCA7egAwIBAgIEQ52A9zANBgkq" + "hkiG9w0BAQUFADBYMQswCQYDVQQGEwJJVDEaMBgGA1UEChMRSW4uVGUuUy5B" + "LiBTLnAuQS4xLTArBgNVBAMTJEluLlRlLlMuQS4gLSBDZXJ0aWZpY2F0aW9u" + "IEF1dGhvcml0eTAeFw0wODA5MTIxMTQzMTJaFw0xMDA5MTIxMTQzMTJaMIHY" + "MQswCQYDVQQGEwJJVDEiMCAGA1UECgwZSW50ZXNhIFMucC5BLi8wNTI2Mjg5" + "MDAxNDEqMCgGA1UECwwhQnVzaW5lc3MgQ29sbGFib3JhdGlvbiAmIFNlY3Vy" + "aXR5MR4wHAYDVQQDDBVNQVNTSU1JTElBTk8gWklDQ0FSREkxETAPBgNVBAQM" + "CFpJQ0NBUkRJMRUwEwYDVQQqDAxNQVNTSU1JTElBTk8xHDAaBgNVBAUTE0lU" + "OlpDQ01TTTc2SDE0TDIxOVkxETAPBgNVBC4TCDAwMDAyNTg1MIGgMA0GCSqG" + "SIb3DQEBAQUAA4GOADCBigKBgQC3iU45shYMdUiD+nNgLgf5Lsh6OY/6ayhC" + "0wC7BQ4pq3vx8a98DknrdU3UHxc1PC7vhCaoH1fXFfnCNcnh9a2bO5Xouy97" + "V/1UeeuSMsJ4Ll+ccL7XgEoFma+d+xZMLOdG70xDMmDo9U39xWb2VM+J+Dg9" + "/SiOJn0fYtXhFSMUdwIEAIs6TaOCAaEwggGdMB0GA1UdEQQWMBSBEnppY2Nh" + "cmRpQGludGVzYS5pdDAvBggrBgEFBQcBAwQjMCEwCAYGBACORgEBMAsGBgQA" + "jkYBAwIBFDAIBgYEAI5GAQQwWQYDVR0gBFIwUDBOBgYEAIswAQEwRDBCBggr" + "BgEFBQcCARY2aHR0cDovL2UtdHJ1c3Rjb20uaW50ZXNhLml0L2NhX3B1YmJs" + "aWNhL0NQU19JTlRFU0EuaHRtMA4GA1UdDwEB/wQEAwIGQDCBgwYDVR0jBHww" + "eoAUGQkDltG4xVgbfhDkbsT2oBIJEKihXKRaMFgxCzAJBgNVBAYTAklUMRow" + "GAYDVQQKExFJbi5UZS5TLkEuIFMucC5BLjEtMCsGA1UEAxMkSW4uVGUuUy5B" + "LiAtIENlcnRpZmljYXRpb24gQXV0aG9yaXR5ggQ80QETMDsGA1UdHwQ0MDIw" + "MKAuoCyGKmh0dHA6Ly9lLXRydXN0Y29tLmludGVzYS5pdC9DUkwvSU5URVNB" + "LmNybDAdBgNVHQ4EFgQU3+SLS/CpkIeeNQ8be2MXFiNdueEwDQYJKoZIhvcN" + "AQEFBQADggEBAIFvri9QlVkHqWwv8Hwpkejzd+0rnm+MYikI9pkw+VGeSkI6" + "Yr8vx27n9Da3yjYgxIQL6B0jwt9XmxoirkzBTcmTx3zxFJ8mBksXmtsPN+2l" + "yRa+rrTzUBgUYvPZB/dLGQ5V7Tkq2SPgMySZ+UCtxfYI3GslNjWV0DCYEcGJ" + "hcp9sOI7aMfgsFz0PROV4MYjGeFgy9N3FlVwy19NBDicJwwzFDU0SJvWb/uE" + "ikzZXxW4vVEwalgckpA8wHpbHwdlOtaKnNodcSpgrZBjJjfYmU/kM2Qv72mk" + "/oSxARRgB9oMBa2HOP40wSsgWHlNb7AMbImyKE7NQKYJejB++ajwywcxggM8" + "MIIDOAIBATBgMFgxCzAJBgNVBAYTAklUMRowGAYDVQQKExFJbi5UZS5TLkEu" + "IFMucC5BLjEtMCsGA1UEAxMkSW4uVGUuUy5BLiAtIENlcnRpZmljYXRpb24g" + "QXV0aG9yaXR5AgRDnYD3MAkGBSsOAwIaBQAwDQYJKoZIhvcNAQEBBQAEgYB+" + "lH2cwLqc91mP8prvgSV+RRzk13dJdZvdoVjgQoFrPhBiZCNIEoHvIhMMA/sM" + "X6euSRZk7EjD24FasCEGYyd0mJVLEy6TSPmuW+wWz/28w3a6IWXBGrbb/ild" + "/CJMkPgLPGgOVD1WDwiNKwfasiQSFtySf5DPn3jFevdLeMmEY6GCAjIwggEV" + "BgkqhkiG9w0BCQYxggEGMIIBAgIBATBgMFgxCzAJBgNVBAYTAklUMRowGAYD" + "VQQKExFJbi5UZS5TLkEuIFMucC5BLjEtMCsGA1UEAxMkSW4uVGUuUy5BLiAt" + "IENlcnRpZmljYXRpb24gQXV0aG9yaXR5AgRDnYD3MAkGBSsOAwIaBQAwDQYJ" + "KoZIhvcNAQEBBQAEgYBHlOULfT5GDigIvxP0qZOy8VbpntmzaPF55VV4buKV" + "35J+uHp98gXKp0LrHM69V5IRKuyuQzHHFBqsXxsRI9o6KoOfgliD9Xc+BeMg" + "dKzQhBhBYoFREq8hQM0nSbqDNHYAQyNHMzUA/ZQUO5dlFuH8Dw3iDYAhNtfd" + "PrlchKJthDCCARUGCSqGSIb3DQEJBjGCAQYwggECAgEBMGAwWDELMAkGA1UE" + "BhMCSVQxGjAYBgNVBAoTEUluLlRlLlMuQS4gUy5wLkEuMS0wKwYDVQQDEyRJ" + "bi5UZS5TLkEuIC0gQ2VydGlmaWNhdGlvbiBBdXRob3JpdHkCBEOdgPcwCQYF" + "Kw4DAhoFADANBgkqhkiG9w0BAQEFAASBgEeU5Qt9PkYOKAi/E/Spk7LxVume" + "2bNo8XnlVXhu4pXfkn64en3yBcqnQusczr1XkhEq7K5DMccUGqxfGxEj2joq" + "g5+CWIP1dz4F4yB0rNCEGEFigVESryFAzSdJuoM0dgBDI0czNQD9lBQ7l2UW" + "4fwPDeINgCE2190+uVyEom2E"); byte[] noSignedAttrSample2 = Base64.decode( "MIIIlAYJKoZIhvcNAQcCoIIIhTCCCIECAQExCzAJBgUrDgMCGgUAMAsGCSqG" + "SIb3DQEHAaCCB3UwggOtMIIDa6ADAgECAgEzMAsGByqGSM44BAMFADCBkDEL" + "MAkGA1UEBhMCVVMxCzAJBgNVBAgTAkNBMRIwEAYDVQQHEwlQYWxvIEFsdG8x" + "HTAbBgNVBAoTFFN1biBNaWNyb3N5c3RlbXMgSW5jMSMwIQYDVQQLExpKYXZh" + "IFNvZnR3YXJlIENvZGUgU2lnbmluZzEcMBoGA1UEAxMTSkNFIENvZGUgU2ln" + "bmluZyBDQTAeFw0wMTA1MjkxNjQ3MTFaFw0wNjA1MjgxNjQ3MTFaMG4xHTAb" + "BgNVBAoTFFN1biBNaWNyb3N5c3RlbXMgSW5jMSMwIQYDVQQLExpKYXZhIFNv" + "ZnR3YXJlIENvZGUgU2lnbmluZzEoMCYGA1UEAxMfVGhlIExlZ2lvbiBvZiB0" + "aGUgQm91bmN5IENhc3RsZTCCAbcwggEsBgcqhkjOOAQBMIIBHwKBgQD9f1OB" + "HXUSKVLfSpwu7OTn9hG3UjzvRADDHj+AtlEmaUVdQCJR+1k9jVj6v8X1ujD2" + "y5tVbNeBO4AdNG/yZmC3a5lQpaSfn+gEexAiwk+7qdf+t8Yb+DtX58aophUP" + "BPuD9tPFHsMCNVQTWhaRMvZ1864rYdcq7/IiAxmd0UgBxwIVAJdgUI8VIwvM" + "spK5gqLrhAvwWBz1AoGBAPfhoIXWmz3ey7yrXDa4V7l5lK+7+jrqgvlXTAs9" + "B4JnUVlXjrrUWU/mcQcQgYC0SRZxI+hMKBYTt88JMozIpuE8FnqLVHyNKOCj" + "rh4rs6Z1kW6jfwv6ITVi8ftiegEkO8yk8b6oUZCJqIPf4VrlnwaSi2ZegHtV" + "JWQBTDv+z0kqA4GEAAKBgBWry/FCAZ6miyy39+ftsa+h9lxoL+JtV0MJcUyQ" + "E4VAhpAwWb8vyjba9AwOylYQTktHX5sAkFvjBiU0LOYDbFSTVZSHMRJgfjxB" + "SHtICjOEvr1BJrrOrdzqdxcOUge5n7El124BCrv91x5Ol8UTwtiO9LrRXF/d" + "SyK+RT5n1klRo3YwdDARBglghkgBhvhCAQEEBAMCAIcwDgYDVR0PAQH/BAQD" + "AgHGMB0GA1UdDgQWBBQwMY4NRcco1AO3w1YsokfDLVseEjAPBgNVHRMBAf8E" + "BTADAQH/MB8GA1UdIwQYMBaAFGXi9IbJ007wkU5Yomr12HhamsGmMAsGByqG" + "SM44BAMFAAMvADAsAhRmigTu6QV0sTfEkVljgij/hhdVfAIUQZvMxAnIHc30" + "y/u0C1T5UEG9glUwggPAMIIDfqADAgECAgEQMAsGByqGSM44BAMFADCBkDEL" + "MAkGA1UEBhMCVVMxCzAJBgNVBAgTAkNBMRIwEAYDVQQHEwlQYWxvIEFsdG8x" + "HTAbBgNVBAoTFFN1biBNaWNyb3N5c3RlbXMgSW5jMSMwIQYDVQQLExpKYXZh" + "IFNvZnR3YXJlIENvZGUgU2lnbmluZzEcMBoGA1UEAxMTSkNFIENvZGUgU2ln" + "bmluZyBDQTAeFw0wMTA0MjUwNzAwMDBaFw0yMDA0MjUwNzAwMDBaMIGQMQsw" + "CQYDVQQGEwJVUzELMAkGA1UECBMCQ0ExEjAQBgNVBAcTCVBhbG8gQWx0bzEd" + "MBsGA1UEChMUU3VuIE1pY3Jvc3lzdGVtcyBJbmMxIzAhBgNVBAsTGkphdmEg" + "U29mdHdhcmUgQ29kZSBTaWduaW5nMRwwGgYDVQQDExNKQ0UgQ29kZSBTaWdu" + "aW5nIENBMIIBtzCCASwGByqGSM44BAEwggEfAoGBAOuvNwQeylEeaV2w8o/2" + "tUkfxqSZBdcpv3S3avUZ2B7kG/gKAZqY/3Cr4kpWhmxTs/zhyIGMMfDE87CL" + "5nAG7PdpaNuDTHIpiSk2F1w7SgegIAIqRpdRHXDICBgLzgxum3b3BePn+9Nh" + "eeFgmiSNBpWDPFEg4TDPOFeCphpyDc7TAhUAhCVF4bq5qWKreehbMLiJaxv/" + "e3UCgYEAq8l0e3Tv7kK1alNNO92QBnJokQ8LpCl2LlU71a5NZVx+KjoEpmem" + "0HGqpde34sFyDaTRqh6SVEwgAAmisAlBGTMAssNcrkL4sYvKfJbYEH83RFuq" + "zHjI13J2N2tAmahVZvqoAx6LShECactMuCUGHKB30sms0j3pChD6dnC3+9wD" + "gYQAAoGALQmYXKy4nMeZfu4gGSo0kPnXq6uu3WtylQ1m+O8nj0Sy7ShEx/6v" + "sKYnbwBnRYJbB6hWVjvSKVFhXmk51y50dxLPGUr1LcjLcmHETm/6R0M/FLv6" + "vBhmKMLZZot6LS/CYJJLFP5YPiF/aGK+bEhJ+aBLXoWdGRD5FUVRG3HU9wuj" + "ZjBkMBEGCWCGSAGG+EIBAQQEAwIABzAPBgNVHRMBAf8EBTADAQH/MB8GA1Ud" + "IwQYMBaAFGXi9IbJ007wkU5Yomr12HhamsGmMB0GA1UdDgQWBBRl4vSGydNO" + "8JFOWKJq9dh4WprBpjALBgcqhkjOOAQDBQADLwAwLAIUKvfPPJdd+Xi2CNdB" + "tNkNRUzktJwCFEXNdWkOIfod1rMpsun3Mx0z/fxJMYHoMIHlAgEBMIGWMIGQ" + "MQswCQYDVQQGEwJVUzELMAkGA1UECBMCQ0ExEjAQBgNVBAcTCVBhbG8gQWx0" + "bzEdMBsGA1UEChMUU3VuIE1pY3Jvc3lzdGVtcyBJbmMxIzAhBgNVBAsTGkph" + "dmEgU29mdHdhcmUgQ29kZSBTaWduaW5nMRwwGgYDVQQDExNKQ0UgQ29kZSBT" + "aWduaW5nIENBAgEzMAkGBSsOAwIaBQAwCwYHKoZIzjgEAQUABC8wLQIVAIGV" + "khm+kbV4a/+EP45PHcq0hIViAhR4M9os6IrJnoEDS3Y3l7O6zrSosA=="); private JcaX509CertSelectorConverter selectorConverter = new JcaX509CertSelectorConverter(); /* * * INFRASTRUCTURE * */ public SignedDataTest(String name) { super(name); } public static void main(String args[]) { junit.textui.TestRunner.run(SignedDataTest.class); } public static Test suite() throws Exception { init(); return new CMSTestSetup(new TestSuite(SignedDataTest.class)); } private static void init() throws Exception { if (!_initialised) { _initialised = true; _origDN = "O=Bouncy Castle, C=AU"; _origKP = CMSTestUtil.makeKeyPair(); _origCert = CMSTestUtil.makeCertificate(_origKP, _origDN, _origKP, _origDN); _signDN = "CN=Bob, OU=Sales, O=Bouncy Castle, C=AU"; _signKP = CMSTestUtil.makeKeyPair(); _signCert = CMSTestUtil.makeCertificate(_signKP, _signDN, _origKP, _origDN); _signGostKP = CMSTestUtil.makeGostKeyPair(); _signGostCert = CMSTestUtil.makeCertificate(_signGostKP, _signDN, _origKP, _origDN); _signDsaKP = CMSTestUtil.makeDsaKeyPair(); _signDsaCert = CMSTestUtil.makeCertificate(_signDsaKP, _signDN, _origKP, _origDN); _signEcDsaKP = CMSTestUtil.makeEcDsaKeyPair(); _signEcDsaCert = CMSTestUtil.makeCertificate(_signEcDsaKP, _signDN, _origKP, _origDN); _signEcGostKP = CMSTestUtil.makeEcGostKeyPair(); _signEcGostCert = CMSTestUtil.makeCertificate(_signEcGostKP, _signDN, _origKP, _origDN); _reciDN = "CN=Doug, OU=Sales, O=Bouncy Castle, C=AU"; _reciKP = CMSTestUtil.makeKeyPair(); _reciCert = CMSTestUtil.makeCertificate(_reciKP, _reciDN, _signKP, _signDN); _signCrl = CMSTestUtil.makeCrl(_signKP); } } private void verifySignatures(CMSSignedData s, byte[] contentDigest) throws Exception { CertStore certStore = s.getCertificatesAndCRLs("Collection", BC); SignerInformationStore signers = s.getSignerInfos(); Collection c = signers.getSigners(); Iterator it = c.iterator(); while (it.hasNext()) { SignerInformation signer = (SignerInformation)it.next(); Collection certCollection = certStore.getCertificates(selectorConverter.getCertSelector(signer.getSID())); Iterator certIt = certCollection.iterator(); X509Certificate cert = (X509Certificate)certIt.next(); assertEquals(true, signer.verify(cert, BC)); if (contentDigest != null) { assertTrue(MessageDigest.isEqual(contentDigest, signer.getContentDigest())); } } Collection certColl = certStore.getCertificates(null); Collection crlColl = certStore.getCRLs(null); assertEquals(certColl.size(), s.getCertificates("Collection", BC).getMatches(null).size()); assertEquals(crlColl.size(), s.getCRLs("Collection", BC).getMatches(null).size()); } private void verifySignatures(CMSSignedData s) throws Exception { verifySignatures(s, null); } public void testDetachedVerification() throws Exception { byte[] data = "Hello World!".getBytes(); List certList = new ArrayList(); CMSProcessable msg = new CMSProcessableByteArray(data); certList.add(_origCert); certList.add(_signCert); CertStore certs = CertStore.getInstance("Collection", new CollectionCertStoreParameters(certList), BC); CMSSignedDataGenerator gen = new CMSSignedDataGenerator(); gen.addSigner(_origKP.getPrivate(), _origCert, CMSSignedDataGenerator.DIGEST_SHA1); gen.addSigner(_origKP.getPrivate(), _origCert, CMSSignedDataGenerator.DIGEST_MD5); gen.addCertificatesAndCRLs(certs); CMSSignedData s = gen.generate(msg, BC); MessageDigest sha1 = MessageDigest.getInstance("SHA1", BC); MessageDigest md5 = MessageDigest.getInstance("MD5", BC); Map hashes = new HashMap(); byte[] sha1Hash = sha1.digest(data); byte[] md5Hash = md5.digest(data); hashes.put(CMSSignedDataGenerator.DIGEST_SHA1, sha1Hash); hashes.put(CMSSignedDataGenerator.DIGEST_MD5, md5Hash); s = new CMSSignedData(hashes, s.getEncoded()); verifySignatures(s, null); } public void testSHA1AndMD5WithRSAEncapsulatedRepeated() throws Exception { List certList = new ArrayList(); CMSProcessable msg = new CMSProcessableByteArray("Hello World!".getBytes()); certList.add(_origCert); certList.add(_signCert); CertStore certs = CertStore.getInstance("Collection", new CollectionCertStoreParameters(certList), BC); CMSSignedDataGenerator gen = new CMSSignedDataGenerator(); gen.addSigner(_origKP.getPrivate(), _origCert, CMSSignedDataGenerator.DIGEST_SHA1); gen.addSigner(_origKP.getPrivate(), _origCert, CMSSignedDataGenerator.DIGEST_MD5); gen.addCertificatesAndCRLs(certs); CMSSignedData s = gen.generate(msg, true, BC); ByteArrayInputStream bIn = new ByteArrayInputStream(s.getEncoded()); ASN1InputStream aIn = new ASN1InputStream(bIn); s = new CMSSignedData(ContentInfo.getInstance(aIn.readObject())); certs = s.getCertificatesAndCRLs("Collection", BC); SignerInformationStore signers = s.getSignerInfos(); assertEquals(2, signers.size()); Collection c = signers.getSigners(); Iterator it = c.iterator(); SignerId sid = null; while (it.hasNext()) { SignerInformation signer = (SignerInformation)it.next(); Collection certCollection = certs.getCertificates(selectorConverter.getCertSelector(signer.getSID())); Iterator certIt = certCollection.iterator(); X509Certificate cert = (X509Certificate)certIt.next(); sid = signer.getSID(); assertEquals(true, signer.verify(cert, BC)); // // check content digest // byte[] contentDigest = (byte[])gen.getGeneratedDigests().get(signer.getDigestAlgOID()); AttributeTable table = signer.getSignedAttributes(); Attribute hash = table.get(CMSAttributes.messageDigest); assertTrue(MessageDigest.isEqual(contentDigest, ((ASN1OctetString)hash.getAttrValues().getObjectAt(0)).getOctets())); } c = signers.getSigners(sid); assertEquals(2, c.size()); // // try using existing signer // gen = new CMSSignedDataGenerator(); gen.addSigners(s.getSignerInfos()); gen.addCertificatesAndCRLs(s.getCertificatesAndCRLs("Collection", BC)); s = gen.generate(msg, true, BC); bIn = new ByteArrayInputStream(s.getEncoded()); aIn = new ASN1InputStream(bIn); s = new CMSSignedData(ContentInfo.getInstance(aIn.readObject())); certs = s.getCertificatesAndCRLs("Collection", BC); signers = s.getSignerInfos(); c = signers.getSigners(); it = c.iterator(); assertEquals(2, c.size()); while (it.hasNext()) { SignerInformation signer = (SignerInformation)it.next(); Collection certCollection = certs.getCertificates(selectorConverter.getCertSelector(signer.getSID())); Iterator certIt = certCollection.iterator(); X509Certificate cert = (X509Certificate)certIt.next(); assertEquals(true, signer.verify(cert, BC)); } checkSignerStoreReplacement(s, signers); } public void testSHA1WithRSANoAttributes() throws Exception { List certList = new ArrayList(); CMSProcessable msg = new CMSProcessableByteArray("Hello world!".getBytes()); certList.add(_origCert); certList.add(_signCert); CertStore certs = CertStore.getInstance("Collection", new CollectionCertStoreParameters(certList), BC); CMSSignedDataGenerator gen = new CMSSignedDataGenerator(); gen.addSigner(_origKP.getPrivate(), _origCert, CMSSignedDataGenerator.DIGEST_SHA1); gen.addCertificatesAndCRLs(certs); CMSSignedData s = gen.generate(CMSSignedDataGenerator.DATA, msg, false, BC, false); // // compute expected content digest // MessageDigest md = MessageDigest.getInstance("SHA1", BC); verifySignatures(s, md.digest("Hello world!".getBytes())); } public void testSHA1WithRSAViaConfig() throws Exception { List certList = new ArrayList(); CMSProcessable msg = new CMSProcessableByteArray("Hello world!".getBytes()); certList.add(_origCert); certList.add(_signCert); CertStore certs = CertStore.getInstance("Collection", new CollectionCertStoreParameters(certList), BC); // set some bogus mappings. CMSConfig.setSigningEncryptionAlgorithmMapping(PKCSObjectIdentifiers.rsaEncryption.getId(), "XXXX"); CMSConfig.setSigningDigestAlgorithmMapping(OIWObjectIdentifiers.idSHA1.getId(), "YYYY"); CMSSignedDataGenerator gen = new CMSSignedDataGenerator(); gen.addSigner(_origKP.getPrivate(), _origCert, CMSSignedDataGenerator.DIGEST_SHA1); gen.addCertificatesAndCRLs(certs); CMSSignedData s; try { // try the bogus mappings s = gen.generate(CMSSignedDataGenerator.DATA, msg, false, BC, false); } catch (NoSuchAlgorithmException e) { if (!e.getMessage().startsWith("Unknown signature type requested: YYYYWITHXXXX")) { throw e; } } finally { // reset to the real ones CMSConfig.setSigningEncryptionAlgorithmMapping(PKCSObjectIdentifiers.rsaEncryption.getId(), "RSA"); CMSConfig.setSigningDigestAlgorithmMapping(OIWObjectIdentifiers.idSHA1.getId(), "SHA1"); } s = gen.generate(CMSSignedDataGenerator.DATA, msg, false, BC, false); // // compute expected content digest // MessageDigest md = MessageDigest.getInstance("SHA1", BC); verifySignatures(s, md.digest("Hello world!".getBytes())); } public void testSHA1WithRSAAndAttributeTable() throws Exception { MessageDigest md = MessageDigest.getInstance("SHA1", BC); List certList = new ArrayList(); CMSProcessable msg = new CMSProcessableByteArray("Hello world!".getBytes()); certList.add(_origCert); certList.add(_signCert); CertStore certs = CertStore.getInstance("Collection", new CollectionCertStoreParameters(certList), BC); CMSSignedDataGenerator gen = new CMSSignedDataGenerator(); Attribute attr = new Attribute(CMSAttributes.messageDigest, new DERSet( new DEROctetString( md.digest("Hello world!".getBytes())))); ASN1EncodableVector v = new ASN1EncodableVector(); v.add(attr); gen.addSigner(_origKP.getPrivate(), _origCert, CMSSignedDataGenerator.DIGEST_SHA1, new AttributeTable(v), null); gen.addCertificatesAndCRLs(certs); CMSSignedData s = gen.generate(CMSSignedDataGenerator.DATA, null, false, BC); // // the signature is detached, so need to add msg before passing on // s = new CMSSignedData(msg, s.getEncoded()); // // compute expected content digest // verifySignatures(s, md.digest("Hello world!".getBytes())); } public void testSHA1WithRSAEncapsulated() throws Exception { encapsulatedTest(_signKP, _signCert, CMSSignedDataGenerator.DIGEST_SHA1); } public void testSHA1WithRSAEncapsulatedSubjectKeyID() throws Exception { subjectKeyIDTest(_signKP, _signCert, CMSSignedDataGenerator.DIGEST_SHA1); } public void testSHA1WithRSAPSS() throws Exception { rsaPSSTest("SHA1", CMSSignedDataGenerator.DIGEST_SHA1); } public void testSHA224WithRSAPSS() throws Exception { rsaPSSTest("SHA224", CMSSignedDataGenerator.DIGEST_SHA224); } public void testSHA256WithRSAPSS() throws Exception { rsaPSSTest("SHA256", CMSSignedDataGenerator.DIGEST_SHA256); } public void testSHA384WithRSAPSS() throws Exception { rsaPSSTest("SHA384", CMSSignedDataGenerator.DIGEST_SHA384); } public void testSHA224WithRSAEncapsulated() throws Exception { encapsulatedTest(_signKP, _signCert, CMSSignedDataGenerator.DIGEST_SHA224); } public void testSHA256WithRSAEncapsulated() throws Exception { encapsulatedTest(_signKP, _signCert, CMSSignedDataGenerator.DIGEST_SHA256); } public void testRIPEMD128WithRSAEncapsulated() throws Exception { encapsulatedTest(_signKP, _signCert, CMSSignedDataGenerator.DIGEST_RIPEMD128); } public void testRIPEMD160WithRSAEncapsulated() throws Exception { encapsulatedTest(_signKP, _signCert, CMSSignedDataGenerator.DIGEST_RIPEMD160); } public void testRIPEMD256WithRSAEncapsulated() throws Exception { encapsulatedTest(_signKP, _signCert, CMSSignedDataGenerator.DIGEST_RIPEMD256); } public void testECDSAEncapsulated() throws Exception { encapsulatedTest(_signEcDsaKP, _signEcDsaCert, CMSSignedDataGenerator.DIGEST_SHA1); } public void testECDSAEncapsulatedSubjectKeyID() throws Exception { subjectKeyIDTest(_signEcDsaKP, _signEcDsaCert, CMSSignedDataGenerator.DIGEST_SHA1); } public void testECDSASHA224Encapsulated() throws Exception { encapsulatedTest(_signEcDsaKP, _signEcDsaCert, CMSSignedDataGenerator.DIGEST_SHA224); } public void testECDSASHA256Encapsulated() throws Exception { encapsulatedTest(_signEcDsaKP, _signEcDsaCert, CMSSignedDataGenerator.DIGEST_SHA256); } public void testECDSASHA384Encapsulated() throws Exception { encapsulatedTest(_signEcDsaKP, _signEcDsaCert, CMSSignedDataGenerator.DIGEST_SHA384); } public void testECDSASHA512Encapsulated() throws Exception { encapsulatedTest(_signEcDsaKP, _signEcDsaCert, CMSSignedDataGenerator.DIGEST_SHA512); } public void testECDSASHA512EncapsulatedWithKeyFactoryAsEC() throws Exception { X509EncodedKeySpec pubSpec = new X509EncodedKeySpec(_signEcDsaKP.getPublic().getEncoded()); PKCS8EncodedKeySpec privSpec = new PKCS8EncodedKeySpec(_signEcDsaKP.getPrivate().getEncoded()); KeyFactory keyFact = KeyFactory.getInstance("EC", BC); KeyPair kp = new KeyPair(keyFact.generatePublic(pubSpec), keyFact.generatePrivate(privSpec)); encapsulatedTest(kp, _signEcDsaCert, CMSSignedDataGenerator.DIGEST_SHA512); } public void testDSAEncapsulated() throws Exception { encapsulatedTest(_signDsaKP, _signDsaCert, CMSSignedDataGenerator.DIGEST_SHA1); } public void testDSAEncapsulatedSubjectKeyID() throws Exception { subjectKeyIDTest(_signDsaKP, _signDsaCert, CMSSignedDataGenerator.DIGEST_SHA1); } public void testGOST3411WithGOST3410Encapsulated() throws Exception { encapsulatedTest(_signGostKP, _signGostCert, CMSSignedDataGenerator.DIGEST_GOST3411); } public void testGOST3411WithECGOST3410Encapsulated() throws Exception { encapsulatedTest(_signEcGostKP, _signEcGostCert, CMSSignedDataGenerator.DIGEST_GOST3411); } public void testSHA1WithRSACounterSignature() throws Exception { List certList = new ArrayList(); CMSProcessable msg = new CMSProcessableByteArray("Hello World!".getBytes()); certList.add(_signCert); certList.add(_origCert); certList.add(_signCrl); CertStore certsAndCrls = CertStore.getInstance("Collection", new CollectionCertStoreParameters(certList), BC); CMSSignedDataGenerator gen = new CMSSignedDataGenerator(); gen.addSigner(_signKP.getPrivate(), _signCert, CMSSignedDataGenerator.DIGEST_SHA1); gen.addCertificatesAndCRLs(certsAndCrls); CMSSignedData s = gen.generate(msg, true, BC); SignerInformation origSigner = (SignerInformation)s.getSignerInfos().getSigners().toArray()[0]; SignerInformationStore counterSigners1 = gen.generateCounterSigners(origSigner, BC); SignerInformationStore counterSigners2 = gen.generateCounterSigners(origSigner, BC); SignerInformation signer1 = SignerInformation.addCounterSigners(origSigner, counterSigners1); SignerInformation signer2 = SignerInformation.addCounterSigners(signer1, counterSigners2); SignerInformationStore cs = signer2.getCounterSignatures(); Collection csSigners = cs.getSigners(); assertEquals(2, csSigners.size()); Iterator it = csSigners.iterator(); while (it.hasNext()) { SignerInformation cSigner = (SignerInformation)it.next(); Collection certCollection = certsAndCrls.getCertificates(selectorConverter.getCertSelector(cSigner.getSID())); Iterator certIt = certCollection.iterator(); X509Certificate cert = (X509Certificate)certIt.next(); assertNull(cSigner.getSignedAttributes().get(PKCSObjectIdentifiers.pkcs_9_at_contentType)); assertEquals(true, cSigner.verify(cert, BC)); } } private void rsaPSSTest(String digestName, String digestOID) throws Exception { List certList = new ArrayList(); CMSProcessable msg = new CMSProcessableByteArray("Hello world!".getBytes()); certList.add(_origCert); certList.add(_signCert); CertStore certs = CertStore.getInstance("Collection", new CollectionCertStoreParameters(certList), BC); CMSSignedDataGenerator gen = new CMSSignedDataGenerator(); gen.addSigner(_origKP.getPrivate(), _origCert, CMSSignedDataGenerator.ENCRYPTION_RSA_PSS, digestOID); gen.addCertificatesAndCRLs(certs); CMSSignedData s = gen.generate(CMSSignedDataGenerator.DATA, msg, false, BC, false); // // compute expected content digest // MessageDigest md = MessageDigest.getInstance(digestName, BC); verifySignatures(s, md.digest("Hello world!".getBytes())); } private void subjectKeyIDTest( KeyPair signaturePair, X509Certificate signatureCert, String digestAlgorithm) throws Exception { List certList = new ArrayList(); CMSProcessable msg = new CMSProcessableByteArray("Hello World!".getBytes()); certList.add(signatureCert); certList.add(_origCert); certList.add(_signCrl); CertStore certsAndCrls = CertStore.getInstance("Collection", new CollectionCertStoreParameters(certList), BC); CMSSignedDataGenerator gen = new CMSSignedDataGenerator(); gen.addSigner(signaturePair.getPrivate(), CMSTestUtil.createSubjectKeyId(signatureCert.getPublicKey()).getKeyIdentifier(), digestAlgorithm); gen.addCertificatesAndCRLs(certsAndCrls); CMSSignedData s = gen.generate(msg, true, BC); assertEquals(3, s.getVersion()); ByteArrayInputStream bIn = new ByteArrayInputStream(s.getEncoded()); ASN1InputStream aIn = new ASN1InputStream(bIn); s = new CMSSignedData(ContentInfo.getInstance(aIn.readObject())); certsAndCrls = s.getCertificatesAndCRLs("Collection", BC); SignerInformationStore signers = s.getSignerInfos(); Collection c = signers.getSigners(); Iterator it = c.iterator(); while (it.hasNext()) { SignerInformation signer = (SignerInformation)it.next(); Collection certCollection = certsAndCrls.getCertificates(selectorConverter.getCertSelector(signer.getSID())); Iterator certIt = certCollection.iterator(); X509Certificate cert = (X509Certificate)certIt.next(); assertEquals(true, signer.verify(cert, BC)); } // // check for CRLs // Collection crls = certsAndCrls.getCRLs(null); assertEquals(1, crls.size()); assertTrue(crls.contains(_signCrl)); // // try using existing signer // gen = new CMSSignedDataGenerator(); gen.addSigners(s.getSignerInfos()); gen.addCertificatesAndCRLs(s.getCertificatesAndCRLs("Collection", BC)); s = gen.generate(msg, true, BC); bIn = new ByteArrayInputStream(s.getEncoded()); aIn = new ASN1InputStream(bIn); s = new CMSSignedData(ContentInfo.getInstance(aIn.readObject())); certsAndCrls = s.getCertificatesAndCRLs("Collection", BC); signers = s.getSignerInfos(); c = signers.getSigners(); it = c.iterator(); while (it.hasNext()) { SignerInformation signer = (SignerInformation)it.next(); Collection certCollection = certsAndCrls.getCertificates(selectorConverter.getCertSelector(signer.getSID())); Iterator certIt = certCollection.iterator(); X509Certificate cert = (X509Certificate)certIt.next(); assertEquals(true, signer.verify(cert, BC)); } checkSignerStoreReplacement(s, signers); } private void encapsulatedTest( KeyPair signaturePair, X509Certificate signatureCert, String digestAlgorithm) throws Exception { List certList = new ArrayList(); CMSProcessable msg = new CMSProcessableByteArray("Hello World!".getBytes()); certList.add(signatureCert); certList.add(_origCert); certList.add(_signCrl); CertStore certsAndCrls = CertStore.getInstance("Collection", new CollectionCertStoreParameters(certList), BC); CMSSignedDataGenerator gen = new CMSSignedDataGenerator(); gen.addSigner(signaturePair.getPrivate(), signatureCert, digestAlgorithm); gen.addCertificatesAndCRLs(certsAndCrls); CMSSignedData s = gen.generate(msg, true, BC); ByteArrayInputStream bIn = new ByteArrayInputStream(s.getEncoded()); ASN1InputStream aIn = new ASN1InputStream(bIn); s = new CMSSignedData(ContentInfo.getInstance(aIn.readObject())); certsAndCrls = s.getCertificatesAndCRLs("Collection", BC); SignerInformationStore signers = s.getSignerInfos(); Collection c = signers.getSigners(); Iterator it = c.iterator(); while (it.hasNext()) { SignerInformation signer = (SignerInformation)it.next(); Collection certCollection = certsAndCrls.getCertificates(selectorConverter.getCertSelector(signer.getSID())); Iterator certIt = certCollection.iterator(); X509Certificate cert = (X509Certificate)certIt.next(); assertEquals(true, signer.verify(cert, BC)); } // // check for CRLs // Collection crls = certsAndCrls.getCRLs(null); assertEquals(1, crls.size()); assertTrue(crls.contains(_signCrl)); // // try using existing signer // gen = new CMSSignedDataGenerator(); gen.addSigners(s.getSignerInfos()); gen.addCertificatesAndCRLs(s.getCertificatesAndCRLs("Collection", BC)); s = gen.generate(msg, true, BC); bIn = new ByteArrayInputStream(s.getEncoded()); aIn = new ASN1InputStream(bIn); s = new CMSSignedData(ContentInfo.getInstance(aIn.readObject())); certsAndCrls = s.getCertificatesAndCRLs("Collection", BC); signers = s.getSignerInfos(); c = signers.getSigners(); it = c.iterator(); while (it.hasNext()) { SignerInformation signer = (SignerInformation)it.next(); Collection certCollection = certsAndCrls.getCertificates(selectorConverter.getCertSelector(signer.getSID())); Iterator certIt = certCollection.iterator(); X509Certificate cert = (X509Certificate)certIt.next(); assertEquals(true, signer.verify(cert, BC)); } checkSignerStoreReplacement(s, signers); } // // signerInformation store replacement test. // private void checkSignerStoreReplacement( CMSSignedData orig, SignerInformationStore signers) throws Exception { CMSSignedData s = CMSSignedData.replaceSigners(orig, signers); CertStore certs = s.getCertificatesAndCRLs("Collection", BC); signers = s.getSignerInfos(); Collection c = signers.getSigners(); Iterator it = c.iterator(); while (it.hasNext()) { SignerInformation signer = (SignerInformation)it.next(); Collection certCollection = certs.getCertificates(selectorConverter.getCertSelector(signer.getSID())); Iterator certIt = certCollection.iterator(); X509Certificate cert = (X509Certificate)certIt.next(); assertEquals(true, signer.verify(cert, BC)); } } public void testUnsortedAttributes() throws Exception { CMSSignedData s = new CMSSignedData(new CMSProcessableByteArray(disorderedMessage), disorderedSet); CertStore certs = s.getCertificatesAndCRLs("Collection", BC); SignerInformationStore signers = s.getSignerInfos(); Collection c = signers.getSigners(); Iterator it = c.iterator(); while (it.hasNext()) { SignerInformation signer = (SignerInformation)it.next(); Collection certCollection = certs.getCertificates(selectorConverter.getCertSelector(signer.getSID())); Iterator certIt = certCollection.iterator(); X509Certificate cert = (X509Certificate)certIt.next(); assertEquals(true, signer.verify(cert, BC)); } } public void testNullContentWithSigner() throws Exception { List certList = new ArrayList(); certList.add(_origCert); certList.add(_signCert); CertStore certs = CertStore.getInstance("Collection", new CollectionCertStoreParameters(certList), BC); CMSSignedDataGenerator gen = new CMSSignedDataGenerator(); gen.addSigner(_origKP.getPrivate(), _origCert, CMSSignedDataGenerator.DIGEST_SHA1); gen.addCertificatesAndCRLs(certs); CMSSignedData s = gen.generate(null, false, BC); ByteArrayInputStream bIn = new ByteArrayInputStream(s.getEncoded()); ASN1InputStream aIn = new ASN1InputStream(bIn); s = new CMSSignedData(ContentInfo.getInstance(aIn.readObject())); verifySignatures(s); } public void testWithAttributeCertificate() throws Exception { List certList = new ArrayList(); CMSProcessable msg = new CMSProcessableByteArray("Hello World!".getBytes()); certList.add(_signDsaCert); CertStore certs = CertStore.getInstance("Collection", new CollectionCertStoreParameters(certList), BC); CMSSignedDataGenerator gen = new CMSSignedDataGenerator(); gen.addSigner(_origKP.getPrivate(), _origCert, CMSSignedDataGenerator.DIGEST_SHA1); gen.addCertificatesAndCRLs(certs); X509AttributeCertificate attrCert = CMSTestUtil.getAttributeCertificate(); X509Store store = X509Store.getInstance("AttributeCertificate/Collection", new X509CollectionStoreParameters(Collections.singleton(attrCert)), BC); gen.addAttributeCertificates(store); CMSSignedData sd = gen.generate(msg, BC); assertEquals(4, sd.getVersion()); store = sd.getAttributeCertificates("Collection", BC); Collection coll = store.getMatches(null); assertEquals(1, coll.size()); assertTrue(coll.contains(attrCert)); // // create new certstore // certList = new ArrayList(); certList.add(_origCert); certList.add(_signCert); certs = CertStore.getInstance("Collection", new CollectionCertStoreParameters(certList), BC); // // replace certs // sd = CMSSignedData.replaceCertificatesAndCRLs(sd, certs); verifySignatures(sd); } public void testCertStoreReplacement() throws Exception { List certList = new ArrayList(); CMSProcessable msg = new CMSProcessableByteArray("Hello World!".getBytes()); certList.add(_signDsaCert); CertStore certs = CertStore.getInstance("Collection", new CollectionCertStoreParameters(certList), BC); CMSSignedDataGenerator gen = new CMSSignedDataGenerator(); gen.addSigner(_origKP.getPrivate(), _origCert, CMSSignedDataGenerator.DIGEST_SHA1); gen.addCertificatesAndCRLs(certs); CMSSignedData sd = gen.generate(msg, BC); // // create new certstore // certList = new ArrayList(); certList.add(_origCert); certList.add(_signCert); certs = CertStore.getInstance("Collection", new CollectionCertStoreParameters(certList), BC); // // replace certs // sd = CMSSignedData.replaceCertificatesAndCRLs(sd, certs); verifySignatures(sd); } public void testEncapsulatedCertStoreReplacement() throws Exception { List certList = new ArrayList(); CMSProcessable msg = new CMSProcessableByteArray("Hello World!".getBytes()); certList.add(_signDsaCert); CertStore certs = CertStore.getInstance("Collection", new CollectionCertStoreParameters(certList), BC); CMSSignedDataGenerator gen = new CMSSignedDataGenerator(); gen.addSigner(_origKP.getPrivate(), _origCert, CMSSignedDataGenerator.DIGEST_SHA1); gen.addCertificatesAndCRLs(certs); CMSSignedData sd = gen.generate(msg, true, BC); // // create new certstore // certList = new ArrayList(); certList.add(_origCert); certList.add(_signCert); certs = CertStore.getInstance("Collection", new CollectionCertStoreParameters(certList), BC); // // replace certs // sd = CMSSignedData.replaceCertificatesAndCRLs(sd, certs); verifySignatures(sd); } public void testCertOrdering1() throws Exception { List certList = new ArrayList(); CMSProcessable msg = new CMSProcessableByteArray("Hello World!".getBytes()); certList.add(_origCert); certList.add(_signCert); certList.add(_signDsaCert); CertStore certs = CertStore.getInstance("Collection", new CollectionCertStoreParameters(certList), BC); CMSSignedDataGenerator gen = new CMSSignedDataGenerator(); gen.addSigner(_origKP.getPrivate(), _origCert, CMSSignedDataGenerator.DIGEST_SHA1); gen.addCertificatesAndCRLs(certs); CMSSignedData sd = gen.generate(msg, true, BC); certs = sd.getCertificatesAndCRLs("Collection", BC); Iterator it = certs.getCertificates(null).iterator(); assertEquals(_origCert, it.next()); assertEquals(_signCert, it.next()); assertEquals(_signDsaCert, it.next()); } public void testCertOrdering2() throws Exception { List certList = new ArrayList(); CMSProcessable msg = new CMSProcessableByteArray("Hello World!".getBytes()); certList.add(_signCert); certList.add(_signDsaCert); certList.add(_origCert); CertStore certs = CertStore.getInstance("Collection", new CollectionCertStoreParameters(certList), BC); CMSSignedDataGenerator gen = new CMSSignedDataGenerator(); gen.addSigner(_origKP.getPrivate(), _origCert, CMSSignedDataGenerator.DIGEST_SHA1); gen.addCertificatesAndCRLs(certs); CMSSignedData sd = gen.generate(msg, true, BC); certs = sd.getCertificatesAndCRLs("Collection", BC); Iterator it = certs.getCertificates(null).iterator(); assertEquals(_signCert, it.next()); assertEquals(_signDsaCert, it.next()); assertEquals(_origCert, it.next()); } public void testSignerStoreReplacement() throws Exception { List certList = new ArrayList(); CMSProcessable msg = new CMSProcessableByteArray("Hello World!".getBytes()); certList.add(_origCert); certList.add(_signCert); CertStore certs = CertStore.getInstance("Collection", new CollectionCertStoreParameters(certList), BC); CMSSignedDataGenerator gen = new CMSSignedDataGenerator(); gen.addSigner(_origKP.getPrivate(), _origCert, CMSSignedDataGenerator.DIGEST_SHA1); gen.addCertificatesAndCRLs(certs); CMSSignedData original = gen.generate(msg, true, BC); // // create new Signer // gen = new CMSSignedDataGenerator(); gen.addSigner(_origKP.getPrivate(), _origCert, CMSSignedDataGenerator.DIGEST_SHA224); gen.addCertificatesAndCRLs(certs); CMSSignedData newSD = gen.generate(msg, true, BC); // // replace signer // CMSSignedData sd = CMSSignedData.replaceSigners(original, newSD.getSignerInfos()); SignerInformation signer = (SignerInformation)sd.getSignerInfos().getSigners().iterator().next(); assertEquals(CMSSignedDataGenerator.DIGEST_SHA224, signer.getDigestAlgOID()); // we use a parser here as it requires the digests to be correct in the digest set, if it // isn't we'll get a NullPointerException CMSSignedDataParser sp = new CMSSignedDataParser(sd.getEncoded()); sp.getSignedContent().drain(); verifySignatures(sp); } public void testEncapsulatedSamples() throws Exception { testSample("PSSSignDataSHA1Enc.sig"); testSample("PSSSignDataSHA256Enc.sig"); testSample("PSSSignDataSHA512Enc.sig"); } public void testSamples() throws Exception { testSample("PSSSignData.data", "PSSSignDataSHA1.sig"); testSample("PSSSignData.data", "PSSSignDataSHA256.sig"); testSample("PSSSignData.data", "PSSSignDataSHA512.sig"); } public void testCounterSig() throws Exception { CMSSignedData sig = new CMSSignedData(getInput("counterSig.p7m")); SignerInformationStore ss = sig.getSignerInfos(); Collection signers = ss.getSigners(); SignerInformationStore cs = ((SignerInformation)signers.iterator().next()).getCounterSignatures(); Collection csSigners = cs.getSigners(); assertEquals(1, csSigners.size()); Iterator it = csSigners.iterator(); while (it.hasNext()) { SignerInformation cSigner = (SignerInformation)it.next(); Collection certCollection = sig.getCertificatesAndCRLs("Collection", BC).getCertificates(selectorConverter.getCertSelector(cSigner.getSID())); Iterator certIt = certCollection.iterator(); X509Certificate cert = (X509Certificate)certIt.next(); assertNull(cSigner.getSignedAttributes().get(PKCSObjectIdentifiers.pkcs_9_at_contentType)); assertEquals(true, cSigner.verify(cert, BC)); } verifySignatures(sig); } private void testSample(String sigName) throws Exception { CMSSignedData sig = new CMSSignedData(getInput(sigName)); verifySignatures(sig); } private void testSample(String messageName, String sigName) throws Exception { CMSSignedData sig = new CMSSignedData(new CMSProcessableByteArray(getInput(messageName)), getInput(sigName)); verifySignatures(sig); } private byte[] getInput(String name) throws IOException { return Streams.readAll(getClass().getResourceAsStream(name)); } public void testForMultipleCounterSignatures() throws Exception { CMSSignedData sd = new CMSSignedData(xtraCounterSig); for (Iterator sI = sd.getSignerInfos().getSigners().iterator(); sI.hasNext();) { SignerInformation sigI = (SignerInformation)sI.next(); SignerInformationStore counter = sigI.getCounterSignatures(); List sigs = new ArrayList(counter.getSigners()); assertEquals(2, sigs.size()); } } private void verifySignatures(CMSSignedDataParser sp) throws Exception { CertStore certs = sp.getCertificatesAndCRLs("Collection", BC); SignerInformationStore signers = sp.getSignerInfos(); Collection c = signers.getSigners(); Iterator it = c.iterator(); while (it.hasNext()) { SignerInformation signer = (SignerInformation)it.next(); Collection certCollection = certs.getCertificates(selectorConverter.getCertSelector(signer.getSID())); Iterator certIt = certCollection.iterator(); X509Certificate cert = (X509Certificate)certIt.next(); assertEquals(true, signer.verify(cert, BC)); } } } bouncycastle-1.49.orig/test/jdk1.3/org/bouncycastle/cms/test/AllTests.java0000644000175000017500000000143110634152313026020 0ustar ebourgebourgpackage org.bouncycastle.cms.test; import junit.framework.Test; import junit.framework.TestSuite; import javax.crypto.Cipher; import java.security.Security; public class AllTests { public static void main (String[] args) throws Exception { junit.textui.TestRunner.run(suite()); } public static Test suite() throws Exception { TestSuite suite = new TestSuite("CMS tests"); suite.addTest(CompressedDataTest.suite()); suite.addTest(SignedDataTest.suite()); suite.addTest(EnvelopedDataTest.suite()); suite.addTest(CompressedDataStreamTest.suite()); suite.addTest(SignedDataStreamTest.suite()); suite.addTest(EnvelopedDataStreamTest.suite()); return suite; } } bouncycastle-1.49.orig/test/jdk1.3/org/bouncycastle/cms/test/SignedDataStreamTest.java0000644000175000017500000011424411726307327030325 0ustar ebourgebourgpackage org.bouncycastle.cms.test; import java.io.BufferedOutputStream; import java.io.ByteArrayInputStream; import java.io.ByteArrayOutputStream; import java.io.OutputStream; import java.security.InvalidKeyException; import java.security.KeyPair; import java.security.MessageDigest; import java.security.NoSuchAlgorithmException; import org.bouncycastle.jce.cert.CertStore; import org.bouncycastle.jce.cert.CollectionCertStoreParameters; import java.security.cert.X509CRL; import java.security.cert.X509Certificate; import java.util.ArrayList; import java.util.Collection; import java.util.Collections; import java.util.Hashtable; import java.util.Iterator; import java.util.List; import java.util.Map; import junit.framework.Test; import junit.framework.TestCase; import junit.framework.TestSuite; import org.bouncycastle.asn1.ASN1ObjectIdentifier; import org.bouncycastle.asn1.ASN1OctetString; import org.bouncycastle.asn1.DEROctetString; import org.bouncycastle.asn1.DERSet; import org.bouncycastle.asn1.cms.Attribute; import org.bouncycastle.asn1.cms.AttributeTable; import org.bouncycastle.asn1.cms.CMSAttributes; import org.bouncycastle.cms.CMSAttributeTableGenerator; import org.bouncycastle.cms.CMSProcessable; import org.bouncycastle.cms.CMSProcessableByteArray; import org.bouncycastle.cms.CMSSignedData; import org.bouncycastle.cms.CMSSignedDataGenerator; import org.bouncycastle.cms.CMSSignedDataParser; import org.bouncycastle.cms.CMSSignedDataStreamGenerator; import org.bouncycastle.cms.CMSSignedGenerator; import org.bouncycastle.cms.CMSTypedStream; import org.bouncycastle.cms.DefaultSignedAttributeTableGenerator; import org.bouncycastle.cms.SignerInformation; import org.bouncycastle.cms.SignerInformationStore; import org.bouncycastle.cms.jcajce.JcaX509CertSelectorConverter; import org.bouncycastle.jce.provider.BouncyCastleProvider; import org.bouncycastle.util.encoders.Base64; import org.bouncycastle.x509.X509AttributeCertificate; import org.bouncycastle.x509.X509CollectionStoreParameters; import org.bouncycastle.x509.X509Store; public class SignedDataStreamTest extends TestCase { private static final String BC = BouncyCastleProvider.PROVIDER_NAME; private static final String TEST_MESSAGE = "Hello World!"; private static String _signDN; private static KeyPair _signKP; private static X509Certificate _signCert; private static String _origDN; private static KeyPair _origKP; private static X509Certificate _origCert; private static String _reciDN; private static KeyPair _reciKP; private static X509Certificate _reciCert; private static KeyPair _origDsaKP; private static X509Certificate _origDsaCert; private static X509CRL _signCrl; private static X509CRL _origCrl; private static boolean _initialised = false; private static final JcaX509CertSelectorConverter selectorConverter = new JcaX509CertSelectorConverter(); public SignedDataStreamTest(String name) { super(name); } private static void init() throws Exception { if (!_initialised) { _initialised = true; _signDN = "O=Bouncy Castle, C=AU"; _signKP = CMSTestUtil.makeKeyPair(); _signCert = CMSTestUtil.makeCertificate(_signKP, _signDN, _signKP, _signDN); _origDN = "CN=Bob, OU=Sales, O=Bouncy Castle, C=AU"; _origKP = CMSTestUtil.makeKeyPair(); _origCert = CMSTestUtil.makeCertificate(_origKP, _origDN, _signKP, _signDN); _origDsaKP = CMSTestUtil.makeDsaKeyPair(); _origDsaCert = CMSTestUtil.makeCertificate(_origDsaKP, _origDN, _signKP, _signDN); _reciDN = "CN=Doug, OU=Sales, O=Bouncy Castle, C=AU"; _reciKP = CMSTestUtil.makeKeyPair(); _reciCert = CMSTestUtil.makeCertificate(_reciKP, _reciDN, _signKP, _signDN); _signCrl = CMSTestUtil.makeCrl(_signKP); _origCrl = CMSTestUtil.makeCrl(_origKP); } } private void verifySignatures(CMSSignedDataParser sp, byte[] contentDigest) throws Exception { CertStore certStore = sp.getCertificatesAndCRLs("Collection", BC); SignerInformationStore signers = sp.getSignerInfos(); Collection c = signers.getSigners(); Iterator it = c.iterator(); while (it.hasNext()) { SignerInformation signer = (SignerInformation)it.next(); Collection certCollection = certStore.getCertificates(selectorConverter.getCertSelector(signer.getSID())); Iterator certIt = certCollection.iterator(); X509Certificate cert = (X509Certificate)certIt.next(); assertEquals(true, signer.verify(cert, BC)); if (contentDigest != null) { assertTrue(MessageDigest.isEqual(contentDigest, signer.getContentDigest())); } } Collection certColl = certStore.getCertificates(null); Collection crlColl = certStore.getCRLs(null); assertEquals(certColl.size(), sp.getCertificates("Collection", BC).getMatches(null).size()); assertEquals(crlColl.size(), sp.getCRLs("Collection", BC).getMatches(null).size()); } private void verifySignatures(CMSSignedDataParser sp) throws Exception { verifySignatures(sp, null); } private void verifyEncodedData(ByteArrayOutputStream bOut) throws Exception { CMSSignedDataParser sp; sp = new CMSSignedDataParser(bOut.toByteArray()); sp.getSignedContent().drain(); verifySignatures(sp); sp.close(); } private void checkSigParseable(byte[] sig) throws Exception { CMSSignedDataParser sp = new CMSSignedDataParser(sig); sp.getVersion(); CMSTypedStream sc = sp.getSignedContent(); if (sc != null) { sc.drain(); } sp.getCertificatesAndCRLs("Collection", BC); sp.getSignerInfos(); sp.close(); } public void testEarlyInvalidKeyException() throws Exception { try { CMSSignedDataStreamGenerator gen = new CMSSignedDataStreamGenerator(); gen.addSigner( _origKP.getPrivate(), _origCert, "DSA", // DOESN'T MATCH KEY ALG CMSSignedDataStreamGenerator.DIGEST_SHA1, BC); fail("Expected InvalidKeyException in addSigner"); } catch (InvalidKeyException e) { // Ignore } } public void testEarlyNoSuchAlgorithmException() throws Exception { try { CMSSignedDataStreamGenerator gen = new CMSSignedDataStreamGenerator(); gen.addSigner( _origKP.getPrivate(), _origCert, CMSSignedDataStreamGenerator.DIGEST_SHA1, // BAD OID! CMSSignedDataStreamGenerator.DIGEST_SHA1, BC); fail("Expected NoSuchAlgorithmException in addSigner"); } catch (NoSuchAlgorithmException e) { // Ignore } } public void testSha1EncapsulatedSignature() throws Exception { byte[] encapSigData = Base64.decode( "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" + "n7MsJMoKN3Kd2Vzh6s10PFgeAAAAAAAA"); CMSSignedDataParser sp = new CMSSignedDataParser(encapSigData); sp.getSignedContent().drain(); verifySignatures(sp); } public void testSHA1WithRSANoAttributes() throws Exception { List certList = new ArrayList(); CMSProcessable msg = new CMSProcessableByteArray(TEST_MESSAGE.getBytes()); certList.add(_origCert); certList.add(_signCert); CertStore certs = CertStore.getInstance("Collection", new CollectionCertStoreParameters(certList), BC); CMSSignedDataGenerator gen = new CMSSignedDataGenerator(); gen.addSigner(_origKP.getPrivate(), _origCert, CMSSignedDataGenerator.DIGEST_SHA1); gen.addCertificatesAndCRLs(certs); CMSSignedData s = gen.generate(CMSSignedDataGenerator.DATA, msg, false, BC, false); CMSSignedDataParser sp = new CMSSignedDataParser( new CMSTypedStream(new ByteArrayInputStream(TEST_MESSAGE.getBytes())), s.getEncoded()); sp.getSignedContent().drain(); // // compute expected content digest // MessageDigest md = MessageDigest.getInstance("SHA1", BC); verifySignatures(sp, md.digest(TEST_MESSAGE.getBytes())); } public void testDSANoAttributes() throws Exception { List certList = new ArrayList(); CMSProcessable msg = new CMSProcessableByteArray(TEST_MESSAGE.getBytes()); certList.add(_origDsaCert); certList.add(_signCert); CertStore certs = CertStore.getInstance("Collection", new CollectionCertStoreParameters(certList), BC); CMSSignedDataGenerator gen = new CMSSignedDataGenerator(); gen.addSigner(_origDsaKP.getPrivate(), _origDsaCert, CMSSignedDataGenerator.DIGEST_SHA1); gen.addCertificatesAndCRLs(certs); CMSSignedData s = gen.generate(CMSSignedDataGenerator.DATA, msg, false, BC, false); CMSSignedDataParser sp = new CMSSignedDataParser( new CMSTypedStream(new ByteArrayInputStream(TEST_MESSAGE.getBytes())), s.getEncoded()); sp.getSignedContent().drain(); // // compute expected content digest // MessageDigest md = MessageDigest.getInstance("SHA1", BC); verifySignatures(sp, md.digest(TEST_MESSAGE.getBytes())); } public void testSHA1WithRSA() throws Exception { List certList = new ArrayList(); ByteArrayOutputStream bOut = new ByteArrayOutputStream(); certList.add(_origCert); certList.add(_signCert); certList.add(_signCrl); certList.add(_origCrl); CertStore certsAndCrls = CertStore.getInstance("Collection", new CollectionCertStoreParameters(certList), BC); CMSSignedDataStreamGenerator gen = new CMSSignedDataStreamGenerator(); gen.addSigner(_origKP.getPrivate(), _origCert, CMSSignedDataStreamGenerator.DIGEST_SHA1, BC); gen.addCertificatesAndCRLs(certsAndCrls); OutputStream sigOut = gen.open(bOut); sigOut.write(TEST_MESSAGE.getBytes()); sigOut.close(); checkSigParseable(bOut.toByteArray()); CMSSignedDataParser sp = new CMSSignedDataParser( new CMSTypedStream(new ByteArrayInputStream(TEST_MESSAGE.getBytes())), bOut.toByteArray()); sp.getSignedContent().drain(); // // compute expected content digest // MessageDigest md = MessageDigest.getInstance("SHA1", BC); verifySignatures(sp, md.digest(TEST_MESSAGE.getBytes())); // // try using existing signer // gen = new CMSSignedDataStreamGenerator(); gen.addSigners(sp.getSignerInfos()); gen.addCertificatesAndCRLs(sp.getCertificatesAndCRLs("Collection", BC)); bOut.reset(); sigOut = gen.open(bOut, true); sigOut.write(TEST_MESSAGE.getBytes()); sigOut.close(); verifyEncodedData(bOut); // // look for the CRLs // Collection col = certsAndCrls.getCRLs(null); assertEquals(2, col.size()); assertTrue(col.contains(_signCrl)); assertTrue(col.contains(_origCrl)); } public void testSHA1WithRSANonData() throws Exception { List certList = new ArrayList(); ByteArrayOutputStream bOut = new ByteArrayOutputStream(); certList.add(_origCert); certList.add(_signCert); certList.add(_signCrl); certList.add(_origCrl); CertStore certsAndCrls = CertStore.getInstance("Collection", new CollectionCertStoreParameters(certList), BC); CMSSignedDataStreamGenerator gen = new CMSSignedDataStreamGenerator(); gen.addSigner(_origKP.getPrivate(), _origCert, CMSSignedDataStreamGenerator.DIGEST_SHA1, BC); gen.addCertificatesAndCRLs(certsAndCrls); OutputStream sigOut = gen.open(bOut, "1.2.3.4", true); sigOut.write(TEST_MESSAGE.getBytes()); sigOut.close(); CMSSignedDataParser sp = new CMSSignedDataParser(bOut.toByteArray()); CMSTypedStream stream = sp.getSignedContent(); assertEquals(new ASN1ObjectIdentifier("1.2.3.4"), stream.getContentType()); stream.drain(); // // compute expected content digest // MessageDigest md = MessageDigest.getInstance("SHA1", BC); verifySignatures(sp, md.digest(TEST_MESSAGE.getBytes())); } public void testSHA1AndMD5WithRSA() throws Exception { List certList = new ArrayList(); ByteArrayOutputStream bOut = new ByteArrayOutputStream(); certList.add(_origCert); certList.add(_signCert); CertStore certs = CertStore.getInstance("Collection", new CollectionCertStoreParameters(certList), BC); CMSSignedDataStreamGenerator gen = new CMSSignedDataStreamGenerator(); gen.addSigner(_origKP.getPrivate(), _origCert, CMSSignedDataStreamGenerator.DIGEST_SHA1, BC); gen.addSigner(_origKP.getPrivate(), _origCert, CMSSignedDataStreamGenerator.DIGEST_MD5, BC); gen.addCertificatesAndCRLs(certs); OutputStream sigOut = gen.open(bOut); sigOut.write(TEST_MESSAGE.getBytes()); sigOut.close(); checkSigParseable(bOut.toByteArray()); CMSSignedDataParser sp = new CMSSignedDataParser( new CMSTypedStream(new ByteArrayInputStream(TEST_MESSAGE.getBytes())), bOut.toByteArray()); sp.getSignedContent().drain(); verifySignatures(sp); } public void testSHA1WithRSAEncapsulatedBufferedStream() throws Exception { List certList = new ArrayList(); ByteArrayOutputStream bOut = new ByteArrayOutputStream(); certList.add(_origCert); certList.add(_signCert); CertStore certs = CertStore.getInstance("Collection", new CollectionCertStoreParameters(certList), BC); // // find unbuffered length // CMSSignedDataStreamGenerator gen = new CMSSignedDataStreamGenerator(); gen.addSigner(_origKP.getPrivate(), _origCert, CMSSignedDataStreamGenerator.DIGEST_SHA1, BC); gen.addCertificatesAndCRLs(certs); OutputStream sigOut = gen.open(bOut, true); for (int i = 0; i != 2000; i++) { sigOut.write(i & 0xff); } sigOut.close(); CMSSignedDataParser sp = new CMSSignedDataParser(bOut.toByteArray()); sp.getSignedContent().drain(); verifySignatures(sp); int unbufferedLength = bOut.toByteArray().length; // // find buffered length with buffered stream - should be equal // bOut = new ByteArrayOutputStream(); gen = new CMSSignedDataStreamGenerator(); gen.addSigner(_origKP.getPrivate(), _origCert, CMSSignedDataStreamGenerator.DIGEST_SHA1, BC); gen.addCertificatesAndCRLs(certs); sigOut = gen.open(bOut, true); BufferedOutputStream bfOut = new BufferedOutputStream(sigOut, 300); for (int i = 0; i != 2000; i++) { bfOut.write(i & 0xff); } bfOut.close(); verifyEncodedData(bOut); assertTrue(bOut.toByteArray().length == unbufferedLength); } public void testSHA1WithRSAEncapsulatedBuffered() throws Exception { List certList = new ArrayList(); ByteArrayOutputStream bOut = new ByteArrayOutputStream(); certList.add(_origCert); certList.add(_signCert); CertStore certs = CertStore.getInstance("Collection", new CollectionCertStoreParameters(certList), BC); // // find unbuffered length // CMSSignedDataStreamGenerator gen = new CMSSignedDataStreamGenerator(); gen.addSigner(_origKP.getPrivate(), _origCert, CMSSignedDataStreamGenerator.DIGEST_SHA1, BC); gen.addCertificatesAndCRLs(certs); OutputStream sigOut = gen.open(bOut, true); for (int i = 0; i != 2000; i++) { sigOut.write(i & 0xff); } sigOut.close(); CMSSignedDataParser sp = new CMSSignedDataParser(bOut.toByteArray()); sp.getSignedContent().drain(); verifySignatures(sp); int unbufferedLength = bOut.toByteArray().length; // // find buffered length - buffer size less than default // bOut = new ByteArrayOutputStream(); gen = new CMSSignedDataStreamGenerator(); gen.setBufferSize(300); gen.addSigner(_origKP.getPrivate(), _origCert, CMSSignedDataStreamGenerator.DIGEST_SHA1, BC); gen.addCertificatesAndCRLs(certs); sigOut = gen.open(bOut, true); for (int i = 0; i != 2000; i++) { sigOut.write(i & 0xff); } sigOut.close(); verifyEncodedData(bOut); assertTrue(bOut.toByteArray().length > unbufferedLength); } public void testSHA1WithRSAEncapsulated() throws Exception { List certList = new ArrayList(); ByteArrayOutputStream bOut = new ByteArrayOutputStream(); certList.add(_origCert); certList.add(_signCert); CertStore certs = CertStore.getInstance("Collection", new CollectionCertStoreParameters(certList), BC); CMSSignedDataStreamGenerator gen = new CMSSignedDataStreamGenerator(); gen.addSigner(_origKP.getPrivate(), _origCert, CMSSignedDataStreamGenerator.DIGEST_SHA1, BC); gen.addCertificatesAndCRLs(certs); OutputStream sigOut = gen.open(bOut, true); sigOut.write(TEST_MESSAGE.getBytes()); sigOut.close(); CMSSignedDataParser sp = new CMSSignedDataParser(bOut.toByteArray()); sp.getSignedContent().drain(); verifySignatures(sp); byte[] contentDigest = (byte[])gen.getGeneratedDigests().get(CMSSignedGenerator.DIGEST_SHA1); AttributeTable table = ((SignerInformation)sp.getSignerInfos().getSigners().iterator().next()).getSignedAttributes(); Attribute hash = table.get(CMSAttributes.messageDigest); assertTrue(MessageDigest.isEqual(contentDigest, ((ASN1OctetString)hash.getAttrValues().getObjectAt(0)).getOctets())); // // try using existing signer // gen = new CMSSignedDataStreamGenerator(); gen.addSigners(sp.getSignerInfos()); gen.addCertificatesAndCRLs(sp.getCertificatesAndCRLs("Collection", BC)); bOut.reset(); sigOut = gen.open(bOut, true); sigOut.write(TEST_MESSAGE.getBytes()); sigOut.close(); CMSSignedData sd = new CMSSignedData(new CMSProcessableByteArray(TEST_MESSAGE.getBytes()), bOut.toByteArray()); assertEquals(1, sd.getSignerInfos().getSigners().size()); verifyEncodedData(bOut); } public void testSHA1WithRSAEncapsulatedSubjectKeyID() throws Exception { List certList = new ArrayList(); ByteArrayOutputStream bOut = new ByteArrayOutputStream(); certList.add(_origCert); certList.add(_signCert); CertStore certs = CertStore.getInstance("Collection", new CollectionCertStoreParameters(certList), BC); CMSSignedDataStreamGenerator gen = new CMSSignedDataStreamGenerator(); gen.addSigner(_origKP.getPrivate(), CMSTestUtil.createSubjectKeyId(_origCert.getPublicKey()).getKeyIdentifier(), CMSSignedDataStreamGenerator.DIGEST_SHA1, BC); gen.addCertificatesAndCRLs(certs); OutputStream sigOut = gen.open(bOut, true); sigOut.write(TEST_MESSAGE.getBytes()); sigOut.close(); CMSSignedDataParser sp = new CMSSignedDataParser(bOut.toByteArray()); sp.getSignedContent().drain(); verifySignatures(sp); byte[] contentDigest = (byte[])gen.getGeneratedDigests().get(CMSSignedGenerator.DIGEST_SHA1); AttributeTable table = ((SignerInformation)sp.getSignerInfos().getSigners().iterator().next()).getSignedAttributes(); Attribute hash = table.get(CMSAttributes.messageDigest); assertTrue(MessageDigest.isEqual(contentDigest, ((ASN1OctetString)hash.getAttrValues().getObjectAt(0)).getOctets())); // // try using existing signer // gen = new CMSSignedDataStreamGenerator(); gen.addSigners(sp.getSignerInfos()); gen.addCertificatesAndCRLs(sp.getCertificatesAndCRLs("Collection", BC)); bOut.reset(); sigOut = gen.open(bOut, true); sigOut.write(TEST_MESSAGE.getBytes()); sigOut.close(); CMSSignedData sd = new CMSSignedData(new CMSProcessableByteArray(TEST_MESSAGE.getBytes()), bOut.toByteArray()); assertEquals(1, sd.getSignerInfos().getSigners().size()); verifyEncodedData(bOut); } public void testAttributeGenerators() throws Exception { final ASN1ObjectIdentifier dummyOid1 = new ASN1ObjectIdentifier("1.2.3"); final ASN1ObjectIdentifier dummyOid2 = new ASN1ObjectIdentifier("1.2.3.4"); List certList = new ArrayList(); ByteArrayOutputStream bOut = new ByteArrayOutputStream(); certList.add(_origCert); certList.add(_signCert); CertStore certs = CertStore.getInstance("Collection", new CollectionCertStoreParameters(certList), BC); CMSSignedDataStreamGenerator gen = new CMSSignedDataStreamGenerator(); CMSAttributeTableGenerator signedGen = new DefaultSignedAttributeTableGenerator() { public AttributeTable getAttributes(Map parameters) { Hashtable table = createStandardAttributeTable(parameters); DEROctetString val = new DEROctetString((byte[])parameters.get(CMSAttributeTableGenerator.DIGEST)); Attribute attr = new Attribute(dummyOid1, new DERSet(val)); table.put(attr.getAttrType(), attr); return new AttributeTable(table); } }; CMSAttributeTableGenerator unsignedGen = new CMSAttributeTableGenerator() { public AttributeTable getAttributes(Map parameters) { DEROctetString val = new DEROctetString((byte[])parameters.get(CMSAttributeTableGenerator.SIGNATURE)); Attribute attr = new Attribute(dummyOid2, new DERSet(val)); return new AttributeTable(new DERSet(attr)); } }; gen.addSigner(_origKP.getPrivate(), _origCert, CMSSignedDataStreamGenerator.DIGEST_SHA1, signedGen, unsignedGen, BC); gen.addCertificatesAndCRLs(certs); OutputStream sigOut = gen.open(bOut, true); sigOut.write(TEST_MESSAGE.getBytes()); sigOut.close(); CMSSignedDataParser sp = new CMSSignedDataParser(bOut.toByteArray()); sp.getSignedContent().drain(); verifySignatures(sp); // // check attributes // SignerInformationStore signers = sp.getSignerInfos(); Collection c = signers.getSigners(); Iterator it = c.iterator(); while (it.hasNext()) { SignerInformation signer = (SignerInformation)it.next(); checkAttribute(signer.getContentDigest(), signer.getSignedAttributes().get(dummyOid1)); checkAttribute(signer.getSignature(), signer.getUnsignedAttributes().get(dummyOid2)); } } private void checkAttribute(byte[] expected, Attribute attr) { DEROctetString value = (DEROctetString)attr.getAttrValues().getObjectAt(0); assertEquals(new DEROctetString(expected), value); } public void testWithAttributeCertificate() throws Exception { List certList = new ArrayList(); certList.add(_signCert); CertStore certs = CertStore.getInstance("Collection", new CollectionCertStoreParameters(certList), BC); CMSSignedDataStreamGenerator gen = new CMSSignedDataStreamGenerator(); gen.addSigner(_origKP.getPrivate(), _origCert, CMSSignedDataGenerator.DIGEST_SHA1, BC); gen.addCertificatesAndCRLs(certs); X509AttributeCertificate attrCert = CMSTestUtil.getAttributeCertificate(); X509Store store = X509Store.getInstance("AttributeCertificate/Collection", new X509CollectionStoreParameters(Collections.singleton(attrCert)), BC); gen.addAttributeCertificates(store); ByteArrayOutputStream bOut = new ByteArrayOutputStream(); OutputStream sigOut = gen.open(bOut, true); sigOut.write(TEST_MESSAGE.getBytes()); sigOut.close(); CMSSignedDataParser sp = new CMSSignedDataParser(bOut.toByteArray()); sp.getSignedContent().drain(); assertEquals(4, sp.getVersion()); store = sp.getAttributeCertificates("Collection", BC); Collection coll = store.getMatches(null); assertEquals(1, coll.size()); assertTrue(coll.contains(attrCert)); } public void testSignerStoreReplacement() throws Exception { List certList = new ArrayList(); ByteArrayOutputStream bOut = new ByteArrayOutputStream(); byte[] data = TEST_MESSAGE.getBytes(); certList.add(_origCert); certList.add(_signCert); CertStore certs = CertStore.getInstance("Collection", new CollectionCertStoreParameters(certList), BC); CMSSignedDataStreamGenerator gen = new CMSSignedDataStreamGenerator(); gen.addSigner(_origKP.getPrivate(), _origCert, CMSSignedDataStreamGenerator.DIGEST_SHA1, BC); gen.addCertificatesAndCRLs(certs); OutputStream sigOut = gen.open(bOut, false); sigOut.write(data); sigOut.close(); checkSigParseable(bOut.toByteArray()); // // create new Signer // ByteArrayInputStream original = new ByteArrayInputStream(bOut.toByteArray()); bOut.reset(); gen = new CMSSignedDataStreamGenerator(); gen.addSigner(_origKP.getPrivate(), _origCert, CMSSignedDataStreamGenerator.DIGEST_SHA224, BC); gen.addCertificatesAndCRLs(certs); sigOut = gen.open(bOut); sigOut.write(data); sigOut.close(); checkSigParseable(bOut.toByteArray()); CMSSignedData sd = new CMSSignedData(bOut.toByteArray()); // // replace signer // ByteArrayOutputStream newOut = new ByteArrayOutputStream(); CMSSignedDataParser.replaceSigners(original, sd.getSignerInfos(), newOut); sd = new CMSSignedData(new CMSProcessableByteArray(data), newOut.toByteArray()); SignerInformation signer = (SignerInformation)sd.getSignerInfos().getSigners().iterator().next(); assertEquals(signer.getDigestAlgOID(), CMSSignedDataStreamGenerator.DIGEST_SHA224); CMSSignedDataParser sp = new CMSSignedDataParser(new CMSTypedStream(new ByteArrayInputStream(data)), newOut.toByteArray()); sp.getSignedContent().drain(); verifySignatures(sp); } public void testEncapsulatedSignerStoreReplacement() throws Exception { List certList = new ArrayList(); ByteArrayOutputStream bOut = new ByteArrayOutputStream(); certList.add(_origCert); certList.add(_signCert); CertStore certs = CertStore.getInstance("Collection", new CollectionCertStoreParameters(certList), BC); CMSSignedDataStreamGenerator gen = new CMSSignedDataStreamGenerator(); gen.addSigner(_origKP.getPrivate(), _origCert, CMSSignedDataStreamGenerator.DIGEST_SHA1, BC); gen.addCertificatesAndCRLs(certs); OutputStream sigOut = gen.open(bOut, true); sigOut.write(TEST_MESSAGE.getBytes()); sigOut.close(); // // create new Signer // ByteArrayInputStream original = new ByteArrayInputStream(bOut.toByteArray()); bOut.reset(); gen = new CMSSignedDataStreamGenerator(); gen.addSigner(_origKP.getPrivate(), _origCert, CMSSignedDataStreamGenerator.DIGEST_SHA224, BC); gen.addCertificatesAndCRLs(certs); sigOut = gen.open(bOut, true); sigOut.write(TEST_MESSAGE.getBytes()); sigOut.close(); CMSSignedData sd = new CMSSignedData(bOut.toByteArray()); // // replace signer // ByteArrayOutputStream newOut = new ByteArrayOutputStream(); CMSSignedDataParser.replaceSigners(original, sd.getSignerInfos(), newOut); sd = new CMSSignedData(newOut.toByteArray()); SignerInformation signer = (SignerInformation)sd.getSignerInfos().getSigners().iterator().next(); assertEquals(signer.getDigestAlgOID(), CMSSignedDataStreamGenerator.DIGEST_SHA224); CMSSignedDataParser sp = new CMSSignedDataParser(newOut.toByteArray()); sp.getSignedContent().drain(); verifySignatures(sp); } public void testCertStoreReplacement() throws Exception { List certList = new ArrayList(); ByteArrayOutputStream bOut = new ByteArrayOutputStream(); byte[] data = TEST_MESSAGE.getBytes(); certList.add(_origDsaCert); CertStore certs = CertStore.getInstance("Collection", new CollectionCertStoreParameters(certList), BC); CMSSignedDataStreamGenerator gen = new CMSSignedDataStreamGenerator(); gen.addSigner(_origKP.getPrivate(), _origCert, CMSSignedDataStreamGenerator.DIGEST_SHA1, BC); gen.addCertificatesAndCRLs(certs); OutputStream sigOut = gen.open(bOut); sigOut.write(data); sigOut.close(); checkSigParseable(bOut.toByteArray()); // // create new certstore with the right certificates // certList = new ArrayList(); certList.add(_origCert); certList.add(_signCert); certs = CertStore.getInstance("Collection", new CollectionCertStoreParameters(certList), BC); // // replace certs // ByteArrayInputStream original = new ByteArrayInputStream(bOut.toByteArray()); ByteArrayOutputStream newOut = new ByteArrayOutputStream(); CMSSignedDataParser.replaceCertificatesAndCRLs(original, certs, newOut); CMSSignedDataParser sp = new CMSSignedDataParser(new CMSTypedStream(new ByteArrayInputStream(data)), newOut.toByteArray()); sp.getSignedContent().drain(); verifySignatures(sp); } public void testEncapsulatedCertStoreReplacement() throws Exception { List certList = new ArrayList(); ByteArrayOutputStream bOut = new ByteArrayOutputStream(); certList.add(_origDsaCert); CertStore certs = CertStore.getInstance("Collection", new CollectionCertStoreParameters(certList), BC); CMSSignedDataStreamGenerator gen = new CMSSignedDataStreamGenerator(); gen.addSigner(_origKP.getPrivate(), _origCert, CMSSignedDataStreamGenerator.DIGEST_SHA1, BC); gen.addCertificatesAndCRLs(certs); OutputStream sigOut = gen.open(bOut, true); sigOut.write(TEST_MESSAGE.getBytes()); sigOut.close(); // // create new certstore with the right certificates // certList = new ArrayList(); certList.add(_origCert); certList.add(_signCert); certs = CertStore.getInstance("Collection", new CollectionCertStoreParameters(certList), BC); // // replace certs // ByteArrayInputStream original = new ByteArrayInputStream(bOut.toByteArray()); ByteArrayOutputStream newOut = new ByteArrayOutputStream(); CMSSignedDataParser.replaceCertificatesAndCRLs(original, certs, newOut); CMSSignedDataParser sp = new CMSSignedDataParser(newOut.toByteArray()); sp.getSignedContent().drain(); verifySignatures(sp); } public void testCertOrdering1() throws Exception { List certList = new ArrayList(); ByteArrayOutputStream bOut = new ByteArrayOutputStream(); certList.add(_origCert); certList.add(_signCert); CertStore certs = CertStore.getInstance("Collection", new CollectionCertStoreParameters(certList), BC); CMSSignedDataStreamGenerator gen = new CMSSignedDataStreamGenerator(); gen.addSigner(_origKP.getPrivate(), _origCert, CMSSignedDataStreamGenerator.DIGEST_SHA1, BC); gen.addCertificatesAndCRLs(certs); OutputStream sigOut = gen.open(bOut, true); sigOut.write(TEST_MESSAGE.getBytes()); sigOut.close(); CMSSignedDataParser sp = new CMSSignedDataParser(bOut.toByteArray()); sp.getSignedContent().drain(); certs = sp.getCertificatesAndCRLs("Collection", BC); Iterator it = certs.getCertificates(null).iterator(); assertEquals(_origCert, it.next()); assertEquals(_signCert, it.next()); } public void testCertOrdering2() throws Exception { List certList = new ArrayList(); ByteArrayOutputStream bOut = new ByteArrayOutputStream(); certList.add(_signCert); certList.add(_origCert); CertStore certs = CertStore.getInstance("Collection", new CollectionCertStoreParameters(certList), BC); CMSSignedDataStreamGenerator gen = new CMSSignedDataStreamGenerator(); gen.addSigner(_origKP.getPrivate(), _origCert, CMSSignedDataStreamGenerator.DIGEST_SHA1, BC); gen.addCertificatesAndCRLs(certs); OutputStream sigOut = gen.open(bOut, true); sigOut.write(TEST_MESSAGE.getBytes()); sigOut.close(); CMSSignedDataParser sp = new CMSSignedDataParser(bOut.toByteArray()); sp.getSignedContent().drain(); certs = sp.getCertificatesAndCRLs("Collection", BC); Iterator it = certs.getCertificates(null).iterator(); assertEquals(_signCert, it.next()); assertEquals(_origCert, it.next()); } public static Test suite() throws Exception { init(); return new CMSTestSetup(new TestSuite(SignedDataStreamTest.class)); } } bouncycastle-1.49.orig/test/jdk1.3/org/bouncycastle/tsp/0000755000175000017500000000000012152033550022466 5ustar ebourgebourgbouncycastle-1.49.orig/test/jdk1.3/org/bouncycastle/tsp/test/0000755000175000017500000000000012152033550023445 5ustar ebourgebourgbouncycastle-1.49.orig/test/jdk1.3/org/bouncycastle/tsp/test/TSPTest.java0000644000175000017500000004766411726307327025653 0ustar ebourgebourgpackage org.bouncycastle.tsp.test; import java.math.BigInteger; import java.security.KeyPair; import java.security.PrivateKey; import org.bouncycastle.jce.cert.CertStore; import org.bouncycastle.jce.cert.CollectionCertStoreParameters; import java.security.cert.X509Certificate; import java.util.ArrayList; import java.util.Collection; import java.util.Date; import java.util.HashSet; import java.util.List; import junit.framework.TestCase; import org.bouncycastle.asn1.cmp.PKIFailureInfo; import org.bouncycastle.asn1.cms.AttributeTable; import org.bouncycastle.asn1.pkcs.PKCSObjectIdentifiers; import org.bouncycastle.tsp.GenTimeAccuracy; import org.bouncycastle.tsp.TSPAlgorithms; import org.bouncycastle.tsp.TSPValidationException; import org.bouncycastle.tsp.TimeStampRequest; import org.bouncycastle.tsp.TimeStampRequestGenerator; import org.bouncycastle.tsp.TimeStampResponse; import org.bouncycastle.tsp.TimeStampResponseGenerator; import org.bouncycastle.tsp.TimeStampToken; import org.bouncycastle.tsp.TimeStampTokenGenerator; import org.bouncycastle.tsp.TimeStampTokenInfo; import org.bouncycastle.util.Arrays; public class TSPTest extends TestCase { public void testGeneral() throws Exception { String signDN = "O=Bouncy Castle, C=AU"; KeyPair signKP = TSPTestUtil.makeKeyPair(); X509Certificate signCert = TSPTestUtil.makeCACertificate(signKP, signDN, signKP, signDN); String origDN = "CN=Eric H. Echidna, E=eric@bouncycastle.org, O=Bouncy Castle, C=AU"; KeyPair origKP = TSPTestUtil.makeKeyPair(); X509Certificate origCert = TSPTestUtil.makeCertificate(origKP, origDN, signKP, signDN); List certList = new ArrayList(); certList.add(origCert); certList.add(signCert); CertStore certs = CertStore.getInstance("Collection", new CollectionCertStoreParameters(certList), "BC"); basicTest(origKP.getPrivate(), origCert, certs); responseValidationTest(origKP.getPrivate(), origCert, certs); incorrectHashTest(origKP.getPrivate(), origCert, certs); badAlgorithmTest(origKP.getPrivate(), origCert, certs); timeNotAvailableTest(origKP.getPrivate(), origCert, certs); badPolicyTest(origKP.getPrivate(), origCert, certs); tokenEncodingTest(origKP.getPrivate(), origCert, certs); certReqTest(origKP.getPrivate(), origCert, certs); testAccuracyZeroCerts(origKP.getPrivate(), origCert, certs); testAccuracyWithCertsAndOrdering(origKP.getPrivate(), origCert, certs); testNoNonse(origKP.getPrivate(), origCert, certs); } private void basicTest( PrivateKey privateKey, X509Certificate cert, CertStore certs) throws Exception { TimeStampTokenGenerator tsTokenGen = new TimeStampTokenGenerator( privateKey, cert, TSPAlgorithms.SHA1, "1.2"); tsTokenGen.setCertificatesAndCRLs(certs); TimeStampRequestGenerator reqGen = new TimeStampRequestGenerator(); TimeStampRequest request = reqGen.generate(TSPAlgorithms.SHA1, new byte[20], BigInteger.valueOf(100)); TimeStampResponseGenerator tsRespGen = new TimeStampResponseGenerator(tsTokenGen, TSPAlgorithms.ALLOWED); TimeStampResponse tsResp = tsRespGen.generate(request, new BigInteger("23"), new Date(), "BC"); tsResp = new TimeStampResponse(tsResp.getEncoded()); TimeStampToken tsToken = tsResp.getTimeStampToken(); tsToken.validate(cert, "BC"); AttributeTable table = tsToken.getSignedAttributes(); assertNotNull("no signingCertificate attribute found", table.get(PKCSObjectIdentifiers.id_aa_signingCertificate)); } private void responseValidationTest( PrivateKey privateKey, X509Certificate cert, CertStore certs) throws Exception { TimeStampTokenGenerator tsTokenGen = new TimeStampTokenGenerator( privateKey, cert, TSPAlgorithms.MD5, "1.2"); tsTokenGen.setCertificatesAndCRLs(certs); TimeStampRequestGenerator reqGen = new TimeStampRequestGenerator(); TimeStampRequest request = reqGen.generate(TSPAlgorithms.SHA1, new byte[20], BigInteger.valueOf(100)); TimeStampResponseGenerator tsRespGen = new TimeStampResponseGenerator(tsTokenGen, TSPAlgorithms.ALLOWED); TimeStampResponse tsResp = tsRespGen.generate(request, new BigInteger("23"), new Date(), "BC"); tsResp = new TimeStampResponse(tsResp.getEncoded()); TimeStampToken tsToken = tsResp.getTimeStampToken(); tsToken.validate(cert, "BC"); // // check validation // tsResp.validate(request); try { request = reqGen.generate(TSPAlgorithms.SHA1, new byte[20], BigInteger.valueOf(101)); tsResp.validate(request); fail("response validation failed on invalid nonce."); } catch (TSPValidationException e) { // ignore } try { request = reqGen.generate(TSPAlgorithms.SHA1, new byte[22], BigInteger.valueOf(100)); tsResp.validate(request); fail("response validation failed on wrong digest."); } catch (TSPValidationException e) { // ignore } try { request = reqGen.generate(TSPAlgorithms.MD5, new byte[20], BigInteger.valueOf(100)); tsResp.validate(request); fail("response validation failed on wrong digest."); } catch (TSPValidationException e) { // ignore } } private void incorrectHashTest( PrivateKey privateKey, X509Certificate cert, CertStore certs) throws Exception { TimeStampTokenGenerator tsTokenGen = new TimeStampTokenGenerator( privateKey, cert, TSPAlgorithms.SHA1, "1.2"); tsTokenGen.setCertificatesAndCRLs(certs); TimeStampRequestGenerator reqGen = new TimeStampRequestGenerator(); TimeStampRequest request = reqGen.generate(TSPAlgorithms.SHA1, new byte[16]); TimeStampResponseGenerator tsRespGen = new TimeStampResponseGenerator(tsTokenGen, TSPAlgorithms.ALLOWED); TimeStampResponse tsResp = tsRespGen.generate(request, new BigInteger("23"), new Date(), "BC"); tsResp = new TimeStampResponse(tsResp.getEncoded()); TimeStampToken tsToken = tsResp.getTimeStampToken(); if (tsToken != null) { fail("incorrectHash - token not null."); } PKIFailureInfo failInfo = tsResp.getFailInfo(); if (failInfo == null) { fail("incorrectHash - failInfo set to null."); } if (failInfo.intValue() != PKIFailureInfo.badDataFormat) { fail("incorrectHash - wrong failure info returned."); } } private void badAlgorithmTest( PrivateKey privateKey, X509Certificate cert, CertStore certs) throws Exception { TimeStampTokenGenerator tsTokenGen = new TimeStampTokenGenerator( privateKey, cert, TSPAlgorithms.SHA1, "1.2"); tsTokenGen.setCertificatesAndCRLs(certs); TimeStampRequestGenerator reqGen = new TimeStampRequestGenerator(); TimeStampRequest request = reqGen.generate("1.2.3.4.5", new byte[20]); TimeStampResponseGenerator tsRespGen = new TimeStampResponseGenerator(tsTokenGen, TSPAlgorithms.ALLOWED); TimeStampResponse tsResp = tsRespGen.generate(request, new BigInteger("23"), new Date(), "BC"); tsResp = new TimeStampResponse(tsResp.getEncoded()); TimeStampToken tsToken = tsResp.getTimeStampToken(); if (tsToken != null) { fail("badAlgorithm - token not null."); } PKIFailureInfo failInfo = tsResp.getFailInfo(); if (failInfo == null) { fail("badAlgorithm - failInfo set to null."); } if (failInfo.intValue() != PKIFailureInfo.badAlg) { fail("badAlgorithm - wrong failure info returned."); } } private void timeNotAvailableTest( PrivateKey privateKey, X509Certificate cert, CertStore certs) throws Exception { TimeStampTokenGenerator tsTokenGen = new TimeStampTokenGenerator( privateKey, cert, TSPAlgorithms.SHA1, "1.2"); tsTokenGen.setCertificatesAndCRLs(certs); TimeStampRequestGenerator reqGen = new TimeStampRequestGenerator(); TimeStampRequest request = reqGen.generate("1.2.3.4.5", new byte[20]); TimeStampResponseGenerator tsRespGen = new TimeStampResponseGenerator(tsTokenGen, TSPAlgorithms.ALLOWED); TimeStampResponse tsResp = tsRespGen.generate(request, new BigInteger("23"), null, "BC"); tsResp = new TimeStampResponse(tsResp.getEncoded()); TimeStampToken tsToken = tsResp.getTimeStampToken(); if (tsToken != null) { fail("timeNotAvailable - token not null."); } PKIFailureInfo failInfo = tsResp.getFailInfo(); if (failInfo == null) { fail("timeNotAvailable - failInfo set to null."); } if (failInfo.intValue() != PKIFailureInfo.timeNotAvailable) { fail("timeNotAvailable - wrong failure info returned."); } } private void badPolicyTest( PrivateKey privateKey, X509Certificate cert, CertStore certs) throws Exception { TimeStampTokenGenerator tsTokenGen = new TimeStampTokenGenerator( privateKey, cert, TSPAlgorithms.SHA1, "1.2"); tsTokenGen.setCertificatesAndCRLs(certs); TimeStampRequestGenerator reqGen = new TimeStampRequestGenerator(); reqGen.setReqPolicy("1.1"); TimeStampRequest request = reqGen.generate(TSPAlgorithms.SHA1, new byte[20]); TimeStampResponseGenerator tsRespGen = new TimeStampResponseGenerator(tsTokenGen, TSPAlgorithms.ALLOWED, new HashSet()); TimeStampResponse tsResp = tsRespGen.generate(request, new BigInteger("23"), new Date(), "BC"); tsResp = new TimeStampResponse(tsResp.getEncoded()); TimeStampToken tsToken = tsResp.getTimeStampToken(); if (tsToken != null) { fail("badPolicy - token not null."); } PKIFailureInfo failInfo = tsResp.getFailInfo(); if (failInfo == null) { fail("badPolicy - failInfo set to null."); } if (failInfo.intValue() != PKIFailureInfo.unacceptedPolicy) { fail("badPolicy - wrong failure info returned."); } } private void certReqTest( PrivateKey privateKey, X509Certificate cert, CertStore certs) throws Exception { TimeStampTokenGenerator tsTokenGen = new TimeStampTokenGenerator( privateKey, cert, TSPAlgorithms.MD5, "1.2"); tsTokenGen.setCertificatesAndCRLs(certs); TimeStampRequestGenerator reqGen = new TimeStampRequestGenerator(); // // request with certReq false // reqGen.setCertReq(false); TimeStampRequest request = reqGen.generate(TSPAlgorithms.SHA1, new byte[20], BigInteger.valueOf(100)); TimeStampResponseGenerator tsRespGen = new TimeStampResponseGenerator(tsTokenGen, TSPAlgorithms.ALLOWED); TimeStampResponse tsResp = tsRespGen.generate(request, new BigInteger("23"), new Date(), "BC"); tsResp = new TimeStampResponse(tsResp.getEncoded()); TimeStampToken tsToken = tsResp.getTimeStampToken(); assertNull(tsToken.getTimeStampInfo().getGenTimeAccuracy()); // check for abscence of accuracy assertEquals("1.2", tsToken.getTimeStampInfo().getPolicy().getId()); try { tsToken.validate(cert, "BC"); } catch (TSPValidationException e) { fail("certReq(false) verification of token failed."); } CertStore respCerts = tsToken.getCertificatesAndCRLs("Collection", "BC"); Collection certsColl = respCerts.getCertificates(null); if (!certsColl.isEmpty()) { fail("certReq(false) found certificates in response."); } } private void tokenEncodingTest( PrivateKey privateKey, X509Certificate cert, CertStore certs) throws Exception { TimeStampTokenGenerator tsTokenGen = new TimeStampTokenGenerator( privateKey, cert, TSPAlgorithms.SHA1, "1.2.3.4.5.6"); tsTokenGen.setCertificatesAndCRLs(certs); TimeStampRequestGenerator reqGen = new TimeStampRequestGenerator(); TimeStampRequest request = reqGen.generate(TSPAlgorithms.SHA1, new byte[20], BigInteger.valueOf(100)); TimeStampResponseGenerator tsRespGen = new TimeStampResponseGenerator(tsTokenGen, TSPAlgorithms.ALLOWED); TimeStampResponse tsResp = tsRespGen.generate(request, new BigInteger("23"), new Date(), "BC"); tsResp = new TimeStampResponse(tsResp.getEncoded()); TimeStampResponse tsResponse = new TimeStampResponse(tsResp.getEncoded()); if (!Arrays.areEqual(tsResponse.getEncoded(), tsResp.getEncoded()) || !Arrays.areEqual(tsResponse.getTimeStampToken().getEncoded(), tsResp.getTimeStampToken().getEncoded())) { fail(); } } private void testAccuracyZeroCerts( PrivateKey privateKey, X509Certificate cert, CertStore certs) throws Exception { TimeStampTokenGenerator tsTokenGen = new TimeStampTokenGenerator( privateKey, cert, TSPAlgorithms.MD5, "1.2"); tsTokenGen.setCertificatesAndCRLs(certs); tsTokenGen.setAccuracySeconds(1); tsTokenGen.setAccuracyMillis(2); tsTokenGen.setAccuracyMicros(3); TimeStampRequestGenerator reqGen = new TimeStampRequestGenerator(); TimeStampRequest request = reqGen.generate(TSPAlgorithms.SHA1, new byte[20], BigInteger.valueOf(100)); TimeStampResponseGenerator tsRespGen = new TimeStampResponseGenerator(tsTokenGen, TSPAlgorithms.ALLOWED); TimeStampResponse tsResp = tsRespGen.generate(request, new BigInteger("23"), new Date(), "BC"); tsResp = new TimeStampResponse(tsResp.getEncoded()); TimeStampToken tsToken = tsResp.getTimeStampToken(); tsToken.validate(cert, "BC"); // // check validation // tsResp.validate(request); // // check tstInfo // TimeStampTokenInfo tstInfo = tsToken.getTimeStampInfo(); // // check accuracy // GenTimeAccuracy accuracy = tstInfo.getGenTimeAccuracy(); assertEquals(1, accuracy.getSeconds()); assertEquals(2, accuracy.getMillis()); assertEquals(3, accuracy.getMicros()); assertEquals(new BigInteger("23"), tstInfo.getSerialNumber()); assertEquals("1.2", tstInfo.getPolicy().getId()); // // test certReq // CertStore store = tsToken.getCertificatesAndCRLs("Collection", "BC"); Collection certificates = store.getCertificates(null); assertEquals(0, certificates.size()); } private void testAccuracyWithCertsAndOrdering( PrivateKey privateKey, X509Certificate cert, CertStore certs) throws Exception { TimeStampTokenGenerator tsTokenGen = new TimeStampTokenGenerator( privateKey, cert, TSPAlgorithms.MD5, "1.2.3"); tsTokenGen.setCertificatesAndCRLs(certs); tsTokenGen.setAccuracySeconds(3); tsTokenGen.setAccuracyMillis(1); tsTokenGen.setAccuracyMicros(2); tsTokenGen.setOrdering(true); TimeStampRequestGenerator reqGen = new TimeStampRequestGenerator(); reqGen.setCertReq(true); TimeStampRequest request = reqGen.generate(TSPAlgorithms.SHA1, new byte[20], BigInteger.valueOf(100)); assertTrue(request.getCertReq()); TimeStampResponseGenerator tsRespGen = new TimeStampResponseGenerator(tsTokenGen, TSPAlgorithms.ALLOWED); TimeStampResponse tsResp = tsRespGen.generate(request, new BigInteger("23"), new Date(), "BC"); tsResp = new TimeStampResponse(tsResp.getEncoded()); TimeStampToken tsToken = tsResp.getTimeStampToken(); tsToken.validate(cert, "BC"); // // check validation // tsResp.validate(request); // // check tstInfo // TimeStampTokenInfo tstInfo = tsToken.getTimeStampInfo(); // // check accuracy // GenTimeAccuracy accuracy = tstInfo.getGenTimeAccuracy(); assertEquals(3, accuracy.getSeconds()); assertEquals(1, accuracy.getMillis()); assertEquals(2, accuracy.getMicros()); assertEquals(new BigInteger("23"), tstInfo.getSerialNumber()); assertEquals("1.2.3", tstInfo.getPolicy().getId()); assertEquals(true, tstInfo.isOrdered()); assertEquals(tstInfo.getNonce(), BigInteger.valueOf(100)); // // test certReq // CertStore store = tsToken.getCertificatesAndCRLs("Collection", "BC"); Collection certificates = store.getCertificates(null); assertEquals(2, certificates.size()); } private void testNoNonse( PrivateKey privateKey, X509Certificate cert, CertStore certs) throws Exception { TimeStampTokenGenerator tsTokenGen = new TimeStampTokenGenerator( privateKey, cert, TSPAlgorithms.MD5, "1.2.3"); tsTokenGen.setCertificatesAndCRLs(certs); TimeStampRequestGenerator reqGen = new TimeStampRequestGenerator(); TimeStampRequest request = reqGen.generate(TSPAlgorithms.SHA1, new byte[20]); assertFalse(request.getCertReq()); TimeStampResponseGenerator tsRespGen = new TimeStampResponseGenerator(tsTokenGen, TSPAlgorithms.ALLOWED); TimeStampResponse tsResp = tsRespGen.generate(request, new BigInteger("24"), new Date(), "BC"); tsResp = new TimeStampResponse(tsResp.getEncoded()); TimeStampToken tsToken = tsResp.getTimeStampToken(); tsToken.validate(cert, "BC"); // // check validation // tsResp.validate(request); // // check tstInfo // TimeStampTokenInfo tstInfo = tsToken.getTimeStampInfo(); // // check accuracy // GenTimeAccuracy accuracy = tstInfo.getGenTimeAccuracy(); assertNull(accuracy); assertEquals(new BigInteger("24"), tstInfo.getSerialNumber()); assertEquals("1.2.3", tstInfo.getPolicy().getId()); assertEquals(false, tstInfo.isOrdered()); assertNull(tstInfo.getNonce()); // // test certReq // CertStore store = tsToken.getCertificatesAndCRLs("Collection", "BC"); Collection certificates = store.getCertificates(null); assertEquals(0, certificates.size()); } } bouncycastle-1.49.orig/test/jdk1.3/org/bouncycastle/jce/0000755000175000017500000000000012152033550022421 5ustar ebourgebourgbouncycastle-1.49.orig/test/jdk1.3/org/bouncycastle/jce/provider/0000755000175000017500000000000012152033550024253 5ustar ebourgebourgbouncycastle-1.49.orig/test/jdk1.3/org/bouncycastle/jce/provider/test/0000755000175000017500000000000012152033550025232 5ustar ebourgebourgbouncycastle-1.49.orig/test/jdk1.3/org/bouncycastle/jce/provider/test/AttrCertTest.java0000644000175000017500000003330610531736576030513 0ustar ebourgebourgpackage org.bouncycastle.jce.provider.test; import java.io.ByteArrayInputStream; import java.math.BigInteger; import java.security.KeyFactory; import java.security.Principal; import java.security.PrivateKey; import java.security.PublicKey; import java.security.Security; import org.bouncycastle.jce.cert.CertStore; import java.security.cert.CertificateFactory; import org.bouncycastle.jce.cert.CollectionCertStoreParameters; import java.security.cert.X509Certificate; import java.security.spec.RSAPrivateCrtKeySpec; import java.security.spec.RSAPublicKeySpec; import java.util.ArrayList; import java.util.Collection; import java.util.Date; import java.util.List; import java.util.Set; import org.bouncycastle.x509.AttributeCertificateHolder; import org.bouncycastle.x509.AttributeCertificateIssuer; import org.bouncycastle.x509.X509Attribute; import org.bouncycastle.x509.X509AttributeCertificate; import org.bouncycastle.x509.X509V2AttributeCertificate; import org.bouncycastle.x509.X509V2AttributeCertificateGenerator; import org.bouncycastle.asn1.DEROctetString; import org.bouncycastle.jce.provider.BouncyCastleProvider; import org.bouncycastle.util.encoders.Base64; import org.bouncycastle.util.test.SimpleTest; public class AttrCertTest extends SimpleTest { static byte[] attrCert = Base64.decode( "MIIHQDCCBqkCAQEwgZChgY2kgYowgYcxHDAaBgkqhkiG9w0BCQEWDW1sb3JjaEB2" + "dC5lZHUxHjAcBgNVBAMTFU1hcmt1cyBMb3JjaCAobWxvcmNoKTEbMBkGA1UECxMS" + "VmlyZ2luaWEgVGVjaCBVc2VyMRAwDgYDVQQLEwdDbGFzcyAyMQswCQYDVQQKEwJ2" + "dDELMAkGA1UEBhMCVVMwgYmkgYYwgYMxGzAZBgkqhkiG9w0BCQEWDHNzaGFoQHZ0" + "LmVkdTEbMBkGA1UEAxMSU3VtaXQgU2hhaCAoc3NoYWgpMRswGQYDVQQLExJWaXJn" + "aW5pYSBUZWNoIFVzZXIxEDAOBgNVBAsTB0NsYXNzIDExCzAJBgNVBAoTAnZ0MQsw" + "CQYDVQQGEwJVUzANBgkqhkiG9w0BAQQFAAIBBTAiGA8yMDAzMDcxODE2MDgwMloY" + "DzIwMDMwNzI1MTYwODAyWjCCBU0wggVJBgorBgEEAbRoCAEBMYIFORaCBTU8UnVs" + "ZSBSdWxlSWQ9IkZpbGUtUHJpdmlsZWdlLVJ1bGUiIEVmZmVjdD0iUGVybWl0Ij4K" + "IDxUYXJnZXQ+CiAgPFN1YmplY3RzPgogICA8U3ViamVjdD4KICAgIDxTdWJqZWN0" + "TWF0Y2ggTWF0Y2hJZD0idXJuOm9hc2lzOm5hbWVzOnRjOnhhY21sOjEuMDpmdW5j" + "dGlvbjpzdHJpbmctZXF1YWwiPgogICAgIDxBdHRyaWJ1dGVWYWx1ZSBEYXRhVHlw" + "ZT0iaHR0cDovL3d3dy53My5vcmcvMjAwMS9YTUxTY2hlbWEjc3RyaW5nIj4KICAg" + "ICAgIENOPU1hcmt1cyBMb3JjaDwvQXR0cmlidXRlVmFsdWU+CiAgICAgPFN1Ympl" + "Y3RBdHRyaWJ1dGVEZXNpZ25hdG9yIEF0dHJpYnV0ZUlkPSJ1cm46b2FzaXM6bmFt" + "ZXM6dGM6eGFjbWw6MS4wOnN1YmplY3Q6c3ViamVjdC1pZCIgRGF0YVR5cGU9Imh0" + "dHA6Ly93d3cudzMub3JnLzIwMDEvWE1MU2NoZW1hI3N0cmluZyIgLz4gCiAgICA8" + "L1N1YmplY3RNYXRjaD4KICAgPC9TdWJqZWN0PgogIDwvU3ViamVjdHM+CiAgPFJl" + "c291cmNlcz4KICAgPFJlc291cmNlPgogICAgPFJlc291cmNlTWF0Y2ggTWF0Y2hJ" + "ZD0idXJuOm9hc2lzOm5hbWVzOnRjOnhhY21sOjEuMDpmdW5jdGlvbjpzdHJpbmct" + "ZXF1YWwiPgogICAgIDxBdHRyaWJ1dGVWYWx1ZSBEYXRhVHlwZT0iaHR0cDovL3d3" + "dy53My5vcmcvMjAwMS9YTUxTY2hlbWEjYW55VVJJIj4KICAgICAgaHR0cDovL3p1" + "bmkuY3MudnQuZWR1PC9BdHRyaWJ1dGVWYWx1ZT4KICAgICA8UmVzb3VyY2VBdHRy" + "aWJ1dGVEZXNpZ25hdG9yIEF0dHJpYnV0ZUlkPSJ1cm46b2FzaXM6bmFtZXM6dGM6" + "eGFjbWw6MS4wOnJlc291cmNlOnJlc291cmNlLWlkIiBEYXRhVHlwZT0iaHR0cDov" + "L3d3dy53My5vcmcvMjAwMS9YTUxTY2hlbWEjYW55VVJJIiAvPiAKICAgIDwvUmVz" + "b3VyY2VNYXRjaD4KICAgPC9SZXNvdXJjZT4KICA8L1Jlc291cmNlcz4KICA8QWN0" + "aW9ucz4KICAgPEFjdGlvbj4KICAgIDxBY3Rpb25NYXRjaCBNYXRjaElkPSJ1cm46" + "b2FzaXM6bmFtZXM6dGM6eGFjbWw6MS4wOmZ1bmN0aW9uOnN0cmluZy1lcXVhbCI+" + "CiAgICAgPEF0dHJpYnV0ZVZhbHVlIERhdGFUeXBlPSJodHRwOi8vd3d3LnczLm9y" + "Zy8yMDAxL1hNTFNjaGVtYSNzdHJpbmciPgpEZWxlZ2F0ZSBBY2Nlc3MgICAgIDwv" + "QXR0cmlidXRlVmFsdWU+CgkgIDxBY3Rpb25BdHRyaWJ1dGVEZXNpZ25hdG9yIEF0" + "dHJpYnV0ZUlkPSJ1cm46b2FzaXM6bmFtZXM6dGM6eGFjbWw6MS4wOmFjdGlvbjph" + "Y3Rpb24taWQiIERhdGFUeXBlPSJodHRwOi8vd3d3LnczLm9yZy8yMDAxL1hNTFNj" + "aGVtYSNzdHJpbmciIC8+IAogICAgPC9BY3Rpb25NYXRjaD4KICAgPC9BY3Rpb24+" + "CiAgPC9BY3Rpb25zPgogPC9UYXJnZXQ+CjwvUnVsZT4KMA0GCSqGSIb3DQEBBAUA" + "A4GBAGiJSM48XsY90HlYxGmGVSmNR6ZW2As+bot3KAfiCIkUIOAqhcphBS23egTr" + "6asYwy151HshbPNYz+Cgeqs45KkVzh7bL/0e1r8sDVIaaGIkjHK3CqBABnfSayr3" + "Rd1yBoDdEv8Qb+3eEPH6ab9021AsLEnJ6LWTmybbOpMNZ3tv"); byte[] signCert = Base64.decode( "MIIGjTCCBXWgAwIBAgICAPswDQYJKoZIhvcNAQEEBQAwaTEdMBsGCSqGSIb3DQEJ" + "ARYOaXJtaGVscEB2dC5lZHUxLjAsBgNVBAMTJVZpcmdpbmlhIFRlY2ggQ2VydGlm" + "aWNhdGlvbiBBdXRob3JpdHkxCzAJBgNVBAoTAnZ0MQswCQYDVQQGEwJVUzAeFw0w" + "MzAxMzExMzUyMTRaFw0wNDAxMzExMzUyMTRaMIGDMRswGQYJKoZIhvcNAQkBFgxz" + "c2hhaEB2dC5lZHUxGzAZBgNVBAMTElN1bWl0IFNoYWggKHNzaGFoKTEbMBkGA1UE" + "CxMSVmlyZ2luaWEgVGVjaCBVc2VyMRAwDgYDVQQLEwdDbGFzcyAxMQswCQYDVQQK" + "EwJ2dDELMAkGA1UEBhMCVVMwgZ8wDQYJKoZIhvcNAQEBBQADgY0AMIGJAoGBAPDc" + "scgSKmsEp0VegFkuitD5j5PUkDuzLjlfaYONt2SN8WeqU4j2qtlCnsipa128cyKS" + "JzYe9duUdNxquh5BPIkMkHBw4jHoQA33tk0J/sydWdN74/AHPpPieK5GHwhU7GTG" + "rCCS1PJRxjXqse79ExAlul+gjQwHeldAC+d4A6oZAgMBAAGjggOmMIIDojAMBgNV" + "HRMBAf8EAjAAMBEGCWCGSAGG+EIBAQQEAwIFoDAOBgNVHQ8BAf8EBAMCA/gwHQYD" + "VR0lBBYwFAYIKwYBBQUHAwIGCCsGAQUFBwMEMB0GA1UdDgQWBBRUIoWAzlXbzBYE" + "yVTjQFWyMMKo1jCBkwYDVR0jBIGLMIGIgBTgc3Fm+TGqKDhen+oKfbl+xVbj2KFt" + "pGswaTEdMBsGCSqGSIb3DQEJARYOaXJtaGVscEB2dC5lZHUxLjAsBgNVBAMTJVZp" + "cmdpbmlhIFRlY2ggQ2VydGlmaWNhdGlvbiBBdXRob3JpdHkxCzAJBgNVBAoTAnZ0" + "MQswCQYDVQQGEwJVU4IBADCBiwYJYIZIAYb4QgENBH4WfFZpcmdpbmlhIFRlY2gg" + "Q2VydGlmaWNhdGlvbiBBdXRob3JpdHkgZGlnaXRhbCBjZXJ0aWZpY2F0ZXMgYXJl" + "IHN1YmplY3QgdG8gcG9saWNpZXMgbG9jYXRlZCBhdCBodHRwOi8vd3d3LnBraS52" + "dC5lZHUvY2EvY3BzLy4wFwYDVR0RBBAwDoEMc3NoYWhAdnQuZWR1MBkGA1UdEgQS" + "MBCBDmlybWhlbHBAdnQuZWR1MEMGCCsGAQUFBwEBBDcwNTAzBggrBgEFBQcwAoYn" + "aHR0cDovL2JveDE3Ny5jYy52dC5lZHUvY2EvaXNzdWVycy5odG1sMEQGA1UdHwQ9" + "MDswOaA3oDWGM2h0dHA6Ly9ib3gxNzcuY2MudnQuZWR1L2h0ZG9jcy1wdWJsaWMv" + "Y3JsL2NhY3JsLmNybDBUBgNVHSAETTBLMA0GCysGAQQBtGgFAQEBMDoGCysGAQQB" + "tGgFAQEBMCswKQYIKwYBBQUHAgEWHWh0dHA6Ly93d3cucGtpLnZ0LmVkdS9jYS9j" + "cHMvMD8GCWCGSAGG+EIBBAQyFjBodHRwOi8vYm94MTc3LmNjLnZ0LmVkdS9jZ2kt" + "cHVibGljL2NoZWNrX3Jldl9jYT8wPAYJYIZIAYb4QgEDBC8WLWh0dHA6Ly9ib3gx" + "NzcuY2MudnQuZWR1L2NnaS1wdWJsaWMvY2hlY2tfcmV2PzBLBglghkgBhvhCAQcE" + "PhY8aHR0cHM6Ly9ib3gxNzcuY2MudnQuZWR1L35PcGVuQ0E4LjAxMDYzMC9jZ2kt" + "cHVibGljL3JlbmV3YWw/MCwGCWCGSAGG+EIBCAQfFh1odHRwOi8vd3d3LnBraS52" + "dC5lZHUvY2EvY3BzLzANBgkqhkiG9w0BAQQFAAOCAQEAHJ2ls9yjpZVcu5DqiE67" + "r7BfkdMnm7IOj2v8cd4EAlPp6OPBmjwDMwvKRBb/P733kLBqFNWXWKTpT008R0KB" + "8kehbx4h0UPz9vp31zhGv169+5iReQUUQSIwTGNWGLzrT8kPdvxiSAvdAJxcbRBm" + "KzDic5I8PoGe48kSCkPpT1oNmnivmcu5j1SMvlx0IS2BkFMksr0OHiAW1elSnE/N" + "RuX2k73b3FucwVxB3NRo3vgoHPCTnh9r4qItAHdxFlF+pPtbw2oHESKRfMRfOIHz" + "CLQWSIa6Tvg4NIV3RRJ0sbCObesyg08lymalQMdkXwtRn5eGE00SHWwEUjSXP2gR" + "3g=="); static byte[] certWithBaseCertificateID = Base64.decode( "MIIBqzCCARQCAQEwSKBGMD6kPDA6MQswCQYDVQQGEwJJVDEOMAwGA1UEChMFVU5JVE4xDDAKBgNV" + "BAsTA0RJVDENMAsGA1UEAxMEcm9vdAIEAVMVjqB6MHikdjB0MQswCQYDVQQGEwJBVTEoMCYGA1UE" + "ChMfVGhlIExlZ2lvbiBvZiB0aGUgQm91bmN5IENhc3RsZTEjMCEGA1UECxMaQm91bmN5IFByaW1h" + "cnkgQ2VydGlmaWNhdGUxFjAUBgNVBAMTDUJvdW5jeSBDYXN0bGUwDQYJKoZIhvcNAQEFBQACBQKW" + "RhnHMCIYDzIwMDUxMjEyMTIwMDQyWhgPMjAwNTEyMTkxMjAxMzJaMA8wDQYDVRhIMQaBBGVWSVAw" + "DQYJKoZIhvcNAQEFBQADgYEAUAVin9StDaA+InxtXq/av6rUQLI9p1X6louBcj4kYJnxRvTrHpsr" + "N3+i9Uq/uk5lRdAqmPFvcmSbuE3TRAsjrXON5uFiBBKZ1AouLqcr8nHbwcdwjJ9TyUNO9I4hfpSH" + "UHHXMtBKgp4MOkhhX8xTGyWg3hp23d3GaUeg/IYlXBI="); public String getName() { return "AttrCertTest"; } public void performTest() throws Exception { X509AttributeCertificate aCert = new X509V2AttributeCertificate(attrCert); CertificateFactory fact = CertificateFactory.getInstance("X.509","BC"); X509Certificate sCert = (X509Certificate)fact.generateCertificate(new ByteArrayInputStream(signCert)); aCert.verify(sCert.getPublicKey(), "BC"); // // search test // List list = new ArrayList(); list.add(sCert); CollectionCertStoreParameters ccsp = new CollectionCertStoreParameters(list); CertStore store = CertStore.getInstance("Collection", ccsp); Collection certs = store.getCertificates(aCert.getIssuer()); if (certs.size() != 1 || !certs.contains(sCert)) { fail("sCert not found by issuer"); } X509Attribute[] attrs = aCert.getAttributes("1.3.6.1.4.1.6760.8.1.1"); if (attrs == null || attrs.length != 1) { fail("attribute not found"); } // // reencode test // aCert = new X509V2AttributeCertificate(aCert.getEncoded()); aCert.verify(sCert.getPublicKey(), "BC"); X509AttributeCertificate saCert = new X509V2AttributeCertificate(new ByteArrayInputStream(aCert.getEncoded())); if (!aCert.getNotAfter().equals(saCert.getNotAfter())) { fail("failed date comparison"); } // base generator test // // a sample key pair. // RSAPublicKeySpec pubKeySpec = new RSAPublicKeySpec( new BigInteger("b4a7e46170574f16a97082b22be58b6a2a629798419be12872a4bdba626cfae9900f76abfb12139dce5de56564fab2b6543165a040c606887420e33d91ed7ed7", 16), new BigInteger("11", 16)); RSAPrivateCrtKeySpec privKeySpec = new RSAPrivateCrtKeySpec( new BigInteger("b4a7e46170574f16a97082b22be58b6a2a629798419be12872a4bdba626cfae9900f76abfb12139dce5de56564fab2b6543165a040c606887420e33d91ed7ed7", 16), new BigInteger("11", 16), new BigInteger("9f66f6b05410cd503b2709e88115d55daced94d1a34d4e32bf824d0dde6028ae79c5f07b580f5dce240d7111f7ddb130a7945cd7d957d1920994da389f490c89", 16), new BigInteger("c0a0758cdf14256f78d4708c86becdead1b50ad4ad6c5c703e2168fbf37884cb", 16), new BigInteger("f01734d7960ea60070f1b06f2bb81bfac48ff192ae18451d5e56c734a5aab8a5", 16), new BigInteger("b54bb9edff22051d9ee60f9351a48591b6500a319429c069a3e335a1d6171391", 16), new BigInteger("d3d83daf2a0cecd3367ae6f8ae1aeb82e9ac2f816c6fc483533d8297dd7884cd", 16), new BigInteger("b8f52fc6f38593dabb661d3f50f8897f8106eee68b1bce78a95b132b4e5b5d19", 16)); // // set up the keys // PrivateKey privKey; PublicKey pubKey; KeyFactory kFact = KeyFactory.getInstance("RSA", "BC"); privKey = kFact.generatePrivate(privKeySpec); pubKey = kFact.generatePublic(pubKeySpec); X509V2AttributeCertificateGenerator gen = new X509V2AttributeCertificateGenerator(); gen.addAttribute(attrs[0]); gen.setHolder(aCert.getHolder()); gen.setIssuer(aCert.getIssuer()); gen.setNotBefore(new Date(System.currentTimeMillis() - 50000)); gen.setNotAfter(new Date(System.currentTimeMillis() + 50000)); gen.setSerialNumber(aCert.getSerialNumber()); gen.setSignatureAlgorithm("SHA1WithRSAEncryption"); aCert = gen.generateCertificate(privKey, "BC"); aCert.checkValidity(); aCert.verify(pubKey, "BC"); // as the issuer is the same this should still work (even though it is not // technically correct certs = store.getCertificates(aCert.getIssuer()); if (certs.size() != 1 || !certs.contains(sCert)) { fail("sCert not found by issuer"); } attrs = aCert.getAttributes("1.3.6.1.4.1.6760.8.1.1"); if (attrs == null || attrs.length != 1) { fail("attribute not found"); } // // reencode test // aCert = new X509V2AttributeCertificate(aCert.getEncoded()); aCert.verify(pubKey, "BC"); AttributeCertificateIssuer issuer = aCert.getIssuer(); Principal[] principals = issuer.getPrincipals(); AttributeCertificateHolder holder = aCert.getHolder(); principals = holder.getEntityNames(); if (principals == null) { fail("entity names not found."); } // // extension test // if (aCert.hasUnsupportedCriticalExtension()) { fail("unsupported extensions found with no extensions"); } gen.addExtension("1.1", true, new DEROctetString(new byte[10])); gen.addExtension("2.2", false, new DEROctetString(new byte[10])); aCert = gen.generateCertificate(privKey, "BC"); Set exts = aCert.getCriticalExtensionOIDs(); if (exts.size() != 1 || !exts.contains("1.1")) { fail("critical extension test failed"); } exts = aCert.getNonCriticalExtensionOIDs(); if (exts.size() != 1 || !exts.contains("2.2")) { fail("non-critical extension test failed"); } if (!aCert.hasUnsupportedCriticalExtension()) { fail("unsupported extensions not found"); } } public static void main( String[] args) { Security.addProvider(new BouncyCastleProvider()); runTest(new AttrCertTest()); } } bouncycastle-1.49.orig/test/jdk1.3/org/bouncycastle/jce/provider/test/MultiCertStoreTest.java0000644000175000017500000000661010634152313031667 0ustar ebourgebourgpackage org.bouncycastle.jce.provider.test; import org.bouncycastle.util.test.SimpleTest; import org.bouncycastle.jce.provider.BouncyCastleProvider; import org.bouncycastle.jce.MultiCertStoreParameters; import org.bouncycastle.jce.PrincipalUtil; import java.security.cert.CertificateFactory; import java.security.cert.X509Certificate; import java.security.cert.X509CRL; import org.bouncycastle.jce.cert.CollectionCertStoreParameters; import org.bouncycastle.jce.cert.CertStore; import org.bouncycastle.jce.cert.X509CertSelector; import org.bouncycastle.jce.cert.X509CRLSelector; import java.security.Security; import java.io.ByteArrayInputStream; import java.util.List; import java.util.ArrayList; import java.util.Collection; import java.util.Iterator; public class MultiCertStoreTest extends SimpleTest { public void performTest() throws Exception { basicTest(); } private void basicTest() throws Exception { CertificateFactory cf = CertificateFactory.getInstance("X.509", "BC"); X509Certificate rootCert = (X509Certificate)cf .generateCertificate(new ByteArrayInputStream( CertPathTest.rootCertBin)); X509Certificate interCert = (X509Certificate)cf .generateCertificate(new ByteArrayInputStream( CertPathTest.interCertBin)); X509Certificate finalCert = (X509Certificate)cf .generateCertificate(new ByteArrayInputStream( CertPathTest.finalCertBin)); X509CRL rootCrl = (X509CRL)cf.generateCRL(new ByteArrayInputStream( CertPathTest.rootCrlBin)); X509CRL interCrl = (X509CRL)cf .generateCRL(new ByteArrayInputStream( CertPathTest.interCrlBin)); // Testing CollectionCertStore generation from List List list = new ArrayList(); list.add(rootCert); list.add(interCert); list.add(finalCert); list.add(rootCrl); list.add(interCrl); CollectionCertStoreParameters ccsp = new CollectionCertStoreParameters(list); CertStore store1 = CertStore.getInstance("Collection", ccsp, "BC"); CertStore store2 = CertStore.getInstance("Collection", ccsp, "BC"); List storeList = new ArrayList(); storeList.add(store1); storeList.add(store2); CertStore store = CertStore.getInstance("Multi", new MultiCertStoreParameters(storeList)); // Searching for rootCert by subjectDN X509CertSelector targetConstraints = new X509CertSelector(); targetConstraints.setSubject(PrincipalUtil.getSubjectX509Principal(rootCert).getName()); Collection certs = store.getCertificates(targetConstraints); if (certs.size() != 2 || !certs.contains(rootCert)) { fail("2 rootCerts not found by subjectDN"); } store = CertStore.getInstance("Multi", new MultiCertStoreParameters(storeList, false)); certs = store.getCertificates(targetConstraints); if (certs.size() != 1 || !certs.contains(rootCert)) { fail("1 rootCert not found by subjectDN"); } } public String getName() { return "MultiCertStore"; } public static void main(String[] args) { Security.addProvider(new BouncyCastleProvider()); runTest(new MultiCertStoreTest()); } } bouncycastle-1.49.orig/test/jdk1.3/org/bouncycastle/jce/provider/test/CertPathTest.java0000644000175000017500000003255210331053204030451 0ustar ebourgebourgpackage org.bouncycastle.jce.provider.test; import java.io.ByteArrayInputStream; import java.io.ByteArrayOutputStream; import java.io.IOException; import java.io.ObjectOutputStream; import java.security.InvalidKeyException; import java.security.NoSuchAlgorithmException; import java.security.NoSuchProviderException; import java.security.PublicKey; import java.security.Security; import java.security.SignatureException; import java.security.cert.Certificate; import java.security.cert.CertificateEncodingException; import java.security.cert.CertificateException; import java.security.cert.X509Certificate; import java.util.ArrayList; import java.util.Collections; import java.util.Iterator; import java.util.List; import java.util.Vector; import org.bouncycastle.jce.cert.CertPath; import org.bouncycastle.jce.cert.CertificateFactory; import org.bouncycastle.jce.provider.BouncyCastleProvider; import org.bouncycastle.util.encoders.Hex; import org.bouncycastle.util.test.SimpleTestResult; import org.bouncycastle.util.test.Test; import org.bouncycastle.util.test.TestResult; public class CertPathTest implements Test { static byte[] rootCertBin = Hex.decode( "3082023c308201a5a003020102020101300d06092a864886f70d0101040500305c310b300906035504061302415531283026060355040a131f546865204c6567696f6e206f662074686520426f756e637920436173746c6531233021060355040b131a426f756e6379205072696d617279204365727469666963617465301e170d3032303132323133353230385a170d3032303332333133353230385a305c310b300906035504061302415531283026060355040a131f546865204c6567696f6e206f662074686520426f756e637920436173746c6531233021060355040b131a426f756e6379205072696d61727920436572746966696361746530819d300d06092a864886f70d010101050003818b0030818702818100b259d2d6e627a768c94be36164c2d9fc79d97aab9253140e5bf17751197731d6f7540d2509e7b9ffee0a70a6e26d56e92d2edd7f85aba85600b69089f35f6bdbf3c298e05842535d9f064e6b0391cb7d306e0a2d20c4dfb4e7b49a9640bdea26c10ad69c3f05007ce2513cee44cfe01998e62b6c3637d3fc0391079b26ee36d5020111a310300e300c0603551d13040530030101ff300d06092a864886f70d0101040500038181002584a067f9d3e9a02efcf33d9fb870176311ad7741551397a3717cfa71f8724907bdfe9846d25205c9241631df9c0dabd5a980ccdb69fdfcad3694fbe6939f7dffd730d67242400b6fcc9aa718e87f1d7ea58832e4f47d253c7843cc6f4c0a206fb141b959ff639b986cc3470bd576f176cf4d4f402b549ec14e90349b8fb8f5"); static byte[] interCertBin = Hex.decode( "308202fe30820267a003020102020102300d06092a864886f70d0101040500305c310b300906035504061302415531283026060355040a131f546865204c6567696f6e206f662074686520426f756e637920436173746c6531233021060355040b131a426f756e6379205072696d617279204365727469666963617465301e170d3032303132323133353230395a170d3032303332333133353230395a3061310b300906035504061302415531283026060355040a131f546865204c6567696f6e206f662074686520426f756e637920436173746c6531283026060355040b131f426f756e637920496e7465726d65646961746520436572746966696361746530819f300d06092a864886f70d010101050003818d00308189028181008de0d113c5e736969c8d2b047a243f8fe18edad64cde9e842d3669230ca486f7cfdde1f8eec54d1905fff04acc85e61093e180cadc6cea407f193d44bb0e9449b8dbb49784cd9e36260c39e06a947299978c6ed8300724e887198cfede20f3fbde658fa2bd078be946a392bd349f2b49c486e20c405588e306706c9017308e69020300ffffa381ca3081c7301d0603551d0e041604149408336f3240f78737dad120aaed2ea76ec9c91e3081840603551d23047d307b8014c0361907adc48897a85e726f6b09ebe5e6f1295ca160a45e305c310b300906035504061302415531283026060355040a131f546865204c6567696f6e206f662074686520426f756e637920436173746c6531233021060355040b131a426f756e6379205072696d617279204365727469666963617465820101300c0603551d13040530030101ff301106096086480186f8420101040403020060300d06092a864886f70d010104050003818100a06b166b48c82ba1f81c8f142c14974050266f7b9d003e39e24e53d6f82ce43f4099937aa69b818a5193c5a842521cdb59a44b8837c2caddea70d8e013d6c9fd5e572010ee5cc6894c91783af13909eb53bd79d3c9bf6e268b0c13c41c6b16365287975683ece8a4dad9c8394faf707a00348ed01ac59287734411af4e878486"); static byte[] finalCertBin = Hex.decode( "30820259308201c2a003020102020103300d06092a864886f70d01010405003061310b300906035504061302415531283026060355040a131f546865204c6567696f6e206f662074686520426f756e637920436173746c6531283026060355040b131f426f756e637920496e7465726d656469617465204365727469666963617465301e170d3032303132323133353230395a170d3032303332333133353230395a3065310b300906035504061302415531283026060355040a131f546865204c6567696f6e206f662074686520426f756e637920436173746c6531123010060355040713094d656c626f75726e65311830160603550403130f4572696320482e2045636869646e61305a300d06092a864886f70d01010105000349003046024100b4a7e46170574f16a97082b22be58b6a2a629798419be12872a4bdba626cfae9900f76abfb12139dce5de56564fab2b6543165a040c606887420e33d91ed7ed7020111a3633061301d0603551d0e04160414d06cec6d3583bc55121b0ccb3efed726a6166468301f0603551d230418301680149408336f3240f78737dad120aaed2ea76ec9c91e300c0603551d1304053003010100301106096086480186f8420101040403020001300d06092a864886f70d010104050003818100135db1857d0bb8bf108ce4df2cba4d1cf9e4a4578c0197b4da4e6ddd4c62d25debc5ed0916341aa577caa8eebf21409f065bb94369e3f006536a0a715c429c5888504b84030a181c88cb72fc99c11571d3171f869865cee722af474b5279df9ccd6ec3b04bf0fae272ca15266b74a5ce2d14548a0c76a07b4f97dbc25ed7d0ef"); static byte[] rootCrlBin = Hex.decode( "3082012430818e020101300d06092a864886f70d0101050500305c310b300906035504061302415531283026060355040a131f546865204c6567696f6e206f662074686520426f756e637920436173746c6531233021060355040b131a426f756e6379205072696d617279204365727469666963617465170d3032303132323133353230395a170d3032303332333133353230395a300d06092a864886f70d0101050500038181001255a218c620add68a7a8a561f331d2d510b42515c53f3701f2f49946ff2513a0c6e8e606e3488679f8354dc06a79a84c5233c9c9c9f746bbf4d19e49e730850b3bb7e672d59200d3da12512a91f7bc6f56036250789860ade5b0859a2a8fd24904b271624a544c8e894f293bb0f7018679e3499bf06548618ba473b7852a577"); static byte[] interCrlBin = Hex.decode( "30820129308193020101300d06092a864886f70d01010505003061310b300906035504061302415531283026060355040a131f546865204c6567696f6e206f662074686520426f756e637920436173746c6531283026060355040b131f426f756e637920496e7465726d656469617465204365727469666963617465170d3032303132323133353230395a170d3032303332333133353230395a300d06092a864886f70d01010505000381810046e2743d2faa0a3ed3555fc860a6fed78da96ce967c0db6ec8f40de95ec8cab9c720698d705f1cd8a75a400c0b15f23751cdfd5491abb9d416f0585f425e6802a3612a30cecd593abdcd15c632e0a4e2a7a3049649138ae0367431dd626d079c13c1449058547d796f53660acd5b432e7dacf31315ed3c21eb8948a7c043f418"); private TestResult testExceptions() { byte[] enc = { (byte)0, (byte)2, (byte)3, (byte)4, (byte)5 }; MyCertPath mc = new MyCertPath(enc); ByteArrayOutputStream os = new ByteArrayOutputStream(); ByteArrayInputStream is = null; byte[] arr = null; try { ObjectOutputStream oos = new ObjectOutputStream(os); oos.writeObject(mc); oos.flush(); oos.close(); } catch (IOException e) { return new SimpleTestResult(false, getName() + ": unexpected exception.", e); } try { CertificateFactory cFac = CertificateFactory.getInstance("X.509", "BC"); arr = os.toByteArray(); is = new ByteArrayInputStream(arr); cFac.generateCertPath(is); } catch (CertificateException e) { // ignore okay } catch (Exception e) { return new SimpleTestResult(false, getName() + ": failed exception test.", e); } return new SimpleTestResult(true, getName() + ": Okay"); } public TestResult perform() { try { CertificateFactory cf = CertificateFactory.getInstance("X.509", "BC"); X509Certificate rootCert = (X509Certificate)cf .generateCertificate(new ByteArrayInputStream(rootCertBin)); X509Certificate interCert = (X509Certificate)cf .generateCertificate(new ByteArrayInputStream(interCertBin)); X509Certificate finalCert = (X509Certificate)cf .generateCertificate(new ByteArrayInputStream(finalCertBin)); // Testing CertPath generation from List List list = new ArrayList(); list.add(interCert); CertPath certPath1 = cf.generateCertPath(list); // Testing CertPath encoding as PkiPath byte[] encoded = certPath1.getEncoded("PkiPath"); // Testing CertPath generation from InputStream ByteArrayInputStream inStream = new ByteArrayInputStream(encoded); CertPath certPath2 = cf.generateCertPath(inStream, "PkiPath"); // Comparing both CertPathes if (!certPath2.equals(certPath1)) { return new SimpleTestResult(false, this.getName() + ": CertPath differ after encoding and decoding."); } encoded = certPath1.getEncoded("PKCS7"); // Testing CertPath generation from InputStream inStream = new ByteArrayInputStream(encoded); certPath2 = cf.generateCertPath(inStream, "PKCS7"); // Comparing both CertPathes if (!certPath2.equals(certPath1)) { return new SimpleTestResult(false, this.getName() + ": CertPath differ after encoding and decoding."); } encoded = certPath1.getEncoded("PEM"); // Testing CertPath generation from InputStream inStream = new ByteArrayInputStream(encoded); certPath2 = cf.generateCertPath(inStream, "PEM"); // Comparing both CertPathes if (!certPath2.equals(certPath1)) { return new SimpleTestResult(false, this.getName() + ": CertPath differ after encoding and decoding."); } TestResult res = testExceptions(); if (!res.isSuccessful()) { return res; } } catch (Exception e) { return new SimpleTestResult(false, this.getName() + ": exception - " + e.toString(), e); } return new SimpleTestResult(true, this.getName() + ": Okay"); } public String getName() { return "CertPath"; } public static void main(String[] args) { Security.addProvider(new BouncyCastleProvider()); Test test = new CertPathTest(); TestResult result = test.perform(); System.out.println(result.toString()); } private static class MyCertificate extends Certificate { private final byte[] encoding; public MyCertificate(String type, byte[] encoding) { super(type); // don't copy to allow null parameter in test this.encoding = encoding; } public byte[] getEncoded() throws CertificateEncodingException { // do copy to force NPE in test return (byte[])encoding.clone(); } public void verify(PublicKey key) throws CertificateException, NoSuchAlgorithmException, InvalidKeyException, NoSuchProviderException, SignatureException { } public void verify(PublicKey key, String sigProvider) throws CertificateException, NoSuchAlgorithmException, InvalidKeyException, NoSuchProviderException, SignatureException { } public String toString() { return "[My test Certificate, type: " + getType() + "]"; } public PublicKey getPublicKey() { return new PublicKey() { public String getAlgorithm() { return "TEST"; } public byte[] getEncoded() { return new byte[] { (byte)1, (byte)2, (byte)3 }; } public String getFormat() { return "TEST_FORMAT"; } }; } } private static class MyCertPath extends CertPath { private final Vector certificates; private final Vector encodingNames; private final byte[] encoding; public MyCertPath(byte[] encoding) { super("MyEncoding"); this.encoding = encoding; certificates = new Vector(); certificates.add(new MyCertificate("MyEncoding", encoding)); encodingNames = new Vector(); encodingNames.add("MyEncoding"); } public List getCertificates() { return Collections.unmodifiableList(certificates); } public byte[] getEncoded() throws CertificateEncodingException { return (byte[])encoding.clone(); } public byte[] getEncoded(String encoding) throws CertificateEncodingException { if (getType().equals(encoding)) { return (byte[])this.encoding.clone(); } throw new CertificateEncodingException("Encoding not supported: " + encoding); } public Iterator getEncodings() { return Collections.unmodifiableCollection(encodingNames).iterator(); } } } bouncycastle-1.49.orig/test/jdk1.3/org/bouncycastle/jce/provider/test/X509StoreTest.java0000644000175000017500000002736310531736755030452 0ustar ebourgebourgpackage org.bouncycastle.jce.provider.test; import org.bouncycastle.jce.PrincipalUtil; import org.bouncycastle.jce.X509Principal; import org.bouncycastle.jce.provider.BouncyCastleProvider; import org.bouncycastle.util.test.SimpleTest; import org.bouncycastle.x509.X509AttributeCertStoreSelector; import org.bouncycastle.x509.X509AttributeCertificate; import org.bouncycastle.x509.X509CRLStoreSelector; import org.bouncycastle.x509.X509CertPairStoreSelector; import org.bouncycastle.x509.X509CertStoreSelector; import org.bouncycastle.x509.X509CertificatePair; import org.bouncycastle.x509.X509CollectionStoreParameters; import org.bouncycastle.x509.X509Store; import org.bouncycastle.x509.X509V2AttributeCertificate; import java.io.ByteArrayInputStream; import java.math.BigInteger; import java.security.Security; import java.security.cert.CertificateFactory; import java.security.cert.X509CRL; import java.security.cert.X509Certificate; import java.util.ArrayList; import java.util.Collection; import java.util.Collections; import java.util.Date; import java.util.List; public class X509StoreTest extends SimpleTest { private void certPairTest() throws Exception { CertificateFactory cf = CertificateFactory.getInstance("X.509", "BC"); X509Certificate rootCert = (X509Certificate)cf .generateCertificate(new ByteArrayInputStream( CertPathTest.rootCertBin)); X509Certificate interCert = (X509Certificate)cf .generateCertificate(new ByteArrayInputStream( CertPathTest.interCertBin)); X509Certificate finalCert = (X509Certificate)cf .generateCertificate(new ByteArrayInputStream( CertPathTest.finalCertBin)); // Testing CollectionCertStore generation from List X509CertificatePair pair1 = new X509CertificatePair(rootCert, interCert); List certList = new ArrayList(); certList.add(pair1); certList.add(new X509CertificatePair(interCert, finalCert)); X509CollectionStoreParameters ccsp = new X509CollectionStoreParameters(certList); X509Store certStore = X509Store.getInstance("CertificatePair/Collection", ccsp, "BC"); X509CertPairStoreSelector selector = new X509CertPairStoreSelector(); X509CertStoreSelector fwSelector = new X509CertStoreSelector(); fwSelector.setSerialNumber(rootCert.getSerialNumber()); selector.setForwardSelector(fwSelector); Collection col = certStore.getMatches(selector); if (col.size() != 1 || !col.contains(pair1)) { fail("failed pair1 test"); } col = certStore.getMatches(null); if (col.size() != 2) { fail("failed null test"); } } public void performTest() throws Exception { CertificateFactory cf = CertificateFactory.getInstance("X.509", "BC"); X509Certificate rootCert = (X509Certificate)cf .generateCertificate(new ByteArrayInputStream( CertPathTest.rootCertBin)); X509Certificate interCert = (X509Certificate)cf .generateCertificate(new ByteArrayInputStream( CertPathTest.interCertBin)); X509Certificate finalCert = (X509Certificate)cf .generateCertificate(new ByteArrayInputStream( CertPathTest.finalCertBin)); X509CRL rootCrl = (X509CRL)cf.generateCRL(new ByteArrayInputStream( CertPathTest.rootCrlBin)); X509CRL interCrl = (X509CRL)cf .generateCRL(new ByteArrayInputStream( CertPathTest.interCrlBin)); // Testing CollectionCertStore generation from List List certList = new ArrayList(); certList.add(rootCert); certList.add(interCert); certList.add(finalCert); X509CollectionStoreParameters ccsp = new X509CollectionStoreParameters(certList); X509Store certStore = X509Store.getInstance("Certificate/Collection", ccsp, "BC"); // set default to be the same as for SUN X500 name X509Principal.DefaultReverse = true; // Searching for rootCert by subjectDN X509CertStoreSelector targetConstraints = new X509CertStoreSelector(); targetConstraints.setSubject(PrincipalUtil.getSubjectX509Principal(rootCert).getEncoded()); Collection certs = certStore.getMatches(targetConstraints); if (certs.size() != 1 || !certs.contains(rootCert)) { fail("rootCert not found by subjectDN"); } // Searching for rootCert by subjectDN encoded as byte targetConstraints = new X509CertStoreSelector(); targetConstraints.setSubject(PrincipalUtil.getSubjectX509Principal(rootCert).getEncoded()); certs = certStore.getMatches(targetConstraints); if (certs.size() != 1 || !certs.contains(rootCert)) { fail("rootCert not found by encoded subjectDN"); } X509Principal.DefaultReverse = false; // Searching for rootCert by public key encoded as byte targetConstraints = new X509CertStoreSelector(); targetConstraints.setSubjectPublicKey(rootCert.getPublicKey().getEncoded()); certs = certStore.getMatches(targetConstraints); if (certs.size() != 1 || !certs.contains(rootCert)) { fail("rootCert not found by encoded public key"); } // Searching for interCert by issuerDN targetConstraints = new X509CertStoreSelector(); targetConstraints.setIssuer(PrincipalUtil.getSubjectX509Principal(rootCert).getEncoded()); certs = certStore.getMatches(targetConstraints); if (certs.size() != 2) { fail("did not found 2 certs"); } if (!certs.contains(rootCert)) { fail("rootCert not found"); } if (!certs.contains(interCert)) { fail("interCert not found"); } // Searching for attribute certificates X509V2AttributeCertificate attrCert = new X509V2AttributeCertificate(AttrCertTest.attrCert); X509AttributeCertificate attrCert2 = new X509V2AttributeCertificate(AttrCertTest.certWithBaseCertificateID); List attrList = new ArrayList(); attrList.add(attrCert); attrList.add(attrCert2); ccsp = new X509CollectionStoreParameters(attrList); X509Store store = X509Store.getInstance("AttributeCertificate/Collection", ccsp, "BC"); X509AttributeCertStoreSelector attrSelector = new X509AttributeCertStoreSelector(); attrSelector.setHolder(attrCert.getHolder()); if (!attrSelector.getHolder().equals(attrCert.getHolder())) { fail("holder get not correct"); } Collection attrs = store.getMatches(attrSelector); if (attrs.size() != 1 || !attrs.contains(attrCert)) { fail("attrCert not found on holder"); } attrSelector.setHolder(attrCert2.getHolder()); if (attrSelector.getHolder().equals(attrCert.getHolder())) { fail("holder get not correct"); } attrs = store.getMatches(attrSelector); if (attrs.size() != 1 || !attrs.contains(attrCert2)) { fail("attrCert2 not found on holder"); } attrSelector = new X509AttributeCertStoreSelector(); attrSelector.setIssuer(attrCert.getIssuer()); if (!attrSelector.getIssuer().equals(attrCert.getIssuer())) { fail("issuer get not correct"); } attrs = store.getMatches(attrSelector); if (attrs.size() != 1 || !attrs.contains(attrCert)) { fail("attrCert not found on issuer"); } attrSelector.setIssuer(attrCert2.getIssuer()); if (attrSelector.getIssuer().equals(attrCert.getIssuer())) { fail("issuer get not correct"); } attrs = store.getMatches(attrSelector); if (attrs.size() != 1 || !attrs.contains(attrCert2)) { fail("attrCert2 not found on issuer"); } attrSelector = new X509AttributeCertStoreSelector(); attrSelector.setAttributeCert(attrCert); if (!attrSelector.getAttributeCert().equals(attrCert)) { fail("attrCert get not correct"); } attrs = store.getMatches(attrSelector); if (attrs.size() != 1 || !attrs.contains(attrCert)) { fail("attrCert not found on attrCert"); } attrSelector = new X509AttributeCertStoreSelector(); attrSelector.setSerialNumber(attrCert.getSerialNumber()); if (!attrSelector.getSerialNumber().equals(attrCert.getSerialNumber())) { fail("serial number get not correct"); } attrs = store.getMatches(attrSelector); if (attrs.size() != 1 || !attrs.contains(attrCert)) { fail("attrCert not found on serial number"); } attrSelector = (X509AttributeCertStoreSelector)attrSelector.clone(); if (!attrSelector.getSerialNumber().equals(attrCert.getSerialNumber())) { fail("serial number get not correct"); } attrs = store.getMatches(attrSelector); if (attrs.size() != 1 || !attrs.contains(attrCert)) { fail("attrCert not found on serial number"); } attrSelector = new X509AttributeCertStoreSelector(); attrSelector.setAttributeCertificateValid(attrCert.getNotBefore()); if (!attrSelector.getAttributeCertificateValid().equals(attrCert.getNotBefore())) { fail("valid get not correct"); } attrs = store.getMatches(attrSelector); if (attrs.size() != 1 || !attrs.contains(attrCert)) { fail("attrCert not found on valid"); } attrSelector = new X509AttributeCertStoreSelector(); attrSelector.setAttributeCertificateValid(new Date(attrCert.getNotBefore().getTime() - 100)); attrs = store.getMatches(attrSelector); if (attrs.size() != 0) { fail("attrCert found on before"); } attrSelector.setAttributeCertificateValid(new Date(attrCert.getNotAfter().getTime() + 100)); attrs = store.getMatches(attrSelector); if (attrs.size() != 0) { fail("attrCert found on after"); } attrSelector.setSerialNumber(BigInteger.valueOf(10000)); attrs = store.getMatches(attrSelector); if (attrs.size() != 0) { fail("attrCert found on wrong serial number"); } attrSelector.setAttributeCert(null); attrSelector.setAttributeCertificateValid(null); attrSelector.setHolder(null); attrSelector.setIssuer(null); attrSelector.setSerialNumber(null); if (attrSelector.getAttributeCert() != null) { fail("null attrCert"); } if (attrSelector.getAttributeCertificateValid() != null) { fail("null attrCertValid"); } if (attrSelector.getHolder() != null) { fail("null attrCert holder"); } if (attrSelector.getIssuer() != null) { fail("null attrCert issuer"); } if (attrSelector.getSerialNumber() != null) { fail("null attrCert serial"); } attrs = certStore.getMatches(attrSelector); if (attrs.size() != 0) { fail("error using wrong selector (attrs)"); } certPairTest(); } public String getName() { return "X509Store"; } public static void main(String[] args) { Security.addProvider(new BouncyCastleProvider()); runTest(new X509StoreTest()); } } bouncycastle-1.49.orig/test/jdk1.3/org/bouncycastle/jce/provider/test/PKIXPolicyMappingTest.java0000644000175000017500000005357211703444643032232 0ustar ebourgebourgpackage org.bouncycastle.jce.provider.test; import java.io.IOException; import java.math.BigInteger; import java.security.InvalidAlgorithmParameterException; import java.security.KeyFactory; import java.security.NoSuchAlgorithmException; import java.security.NoSuchProviderException; import java.security.PrivateKey; import java.security.PublicKey; import java.security.Security; import org.bouncycastle.jce.PrincipalUtil; import org.bouncycastle.jce.cert.CertPathBuilder; import org.bouncycastle.jce.cert.CertStore; import org.bouncycastle.jce.cert.CollectionCertStoreParameters; import org.bouncycastle.jce.cert.PKIXBuilderParameters; import org.bouncycastle.jce.cert.PKIXCertPathBuilderResult; import org.bouncycastle.jce.cert.TrustAnchor; import org.bouncycastle.jce.cert.X509CertSelector; import java.security.cert.X509Certificate; import java.security.cert.CertificateEncodingException; import java.security.spec.RSAPrivateCrtKeySpec; import java.security.spec.RSAPublicKeySpec; import java.util.Date; import java.util.HashSet; import java.util.Hashtable; import java.util.Set; import org.bouncycastle.asn1.ASN1EncodableVector; import org.bouncycastle.asn1.ASN1ObjectIdentifier; import org.bouncycastle.asn1.DERSequence; import org.bouncycastle.asn1.x509.BasicConstraints; import org.bouncycastle.asn1.x509.PolicyInformation; import org.bouncycastle.asn1.x509.PolicyMappings; import org.bouncycastle.asn1.x509.X509Extensions; import org.bouncycastle.jce.X509Principal; import org.bouncycastle.jce.provider.BouncyCastleProvider; import org.bouncycastle.util.test.SimpleTest; import org.bouncycastle.util.test.TestFailedException; import org.bouncycastle.x509.X509V3CertificateGenerator; public class PKIXPolicyMappingTest extends SimpleTest { static X509V3CertificateGenerator v3CertGen = new X509V3CertificateGenerator(); public String getName() { return "PKIXPolicyMapping"; } /** * TrustAnchor's Cert */ private X509Certificate createTrustCert( PublicKey pubKey, PrivateKey privKey) throws Exception { String issuer = "C=JP, O=policyMappingAdditionalTest, OU=trustAnchor"; String subject = "C=JP, O=policyMappingAdditionalTest, OU=trustAnchor"; v3CertGen.setSerialNumber(BigInteger.valueOf(10)); v3CertGen.setIssuerDN(new X509Principal(issuer)); v3CertGen.setNotBefore(new Date(System.currentTimeMillis() - 1000L * 60 * 60 * 24 * 30)); v3CertGen.setNotAfter(new Date(System.currentTimeMillis() + (1000L * 60 * 60 * 24 * 30))); v3CertGen.setSubjectDN(new X509Principal(subject)); v3CertGen.setPublicKey(pubKey); v3CertGen.setSignatureAlgorithm("SHA1WithRSAEncryption"); X509Certificate cert = v3CertGen.generateX509Certificate(privKey); return cert; } /** * intermediate cert */ private X509Certificate createIntmedCert( PublicKey pubKey, PrivateKey caPrivKey, PublicKey caPubKey, ASN1EncodableVector policies, Hashtable policyMap) throws Exception { String issuer = "C=JP, O=policyMappingAdditionalTest, OU=trustAnchor"; String subject = "C=JP, O=policyMappingAdditionalTest, OU=intmedCA"; v3CertGen.reset(); v3CertGen.setSerialNumber(BigInteger.valueOf(20)); v3CertGen.setIssuerDN(new X509Principal(issuer)); v3CertGen.setNotBefore(new Date(System.currentTimeMillis() - 1000L * 60 * 60 * 24 * 30)); v3CertGen.setNotAfter(new Date(System.currentTimeMillis() + (1000L * 60 * 60 * 24 * 30))); v3CertGen.setSubjectDN(new X509Principal(subject)); v3CertGen.setPublicKey(pubKey); v3CertGen.setSignatureAlgorithm("SHA1WithRSAEncryption"); v3CertGen.addExtension(X509Extensions.CertificatePolicies, true, new DERSequence(policies)); v3CertGen.addExtension(X509Extensions.BasicConstraints, true, new BasicConstraints(true)); v3CertGen.addExtension(X509Extensions.PolicyMappings, true, new PolicyMappings(policyMap)); X509Certificate cert = v3CertGen.generateX509Certificate(caPrivKey); return cert; } /** * endEntity cert */ private X509Certificate createEndEntityCert( PublicKey pubKey, PrivateKey caPrivKey, PublicKey caPubKey, ASN1EncodableVector policies) throws Exception { String issuer = "C=JP, O=policyMappingAdditionalTest, OU=intMedCA"; String subject = "C=JP, O=policyMappingAdditionalTest, OU=endEntity"; v3CertGen.reset(); v3CertGen.setSerialNumber(BigInteger.valueOf(20)); v3CertGen.setIssuerDN(new X509Principal(issuer)); v3CertGen.setNotBefore(new Date(System.currentTimeMillis() - 1000L * 60 * 60 * 24 * 30)); v3CertGen.setNotAfter(new Date(System.currentTimeMillis() + (1000L * 60 * 60 * 24 * 30))); v3CertGen.setSubjectDN(new X509Principal(subject)); v3CertGen.setPublicKey(pubKey); v3CertGen.setSignatureAlgorithm("SHA1WithRSAEncryption"); v3CertGen.addExtension(X509Extensions.CertificatePolicies,true,new DERSequence(policies)); X509Certificate cert = v3CertGen.generateX509Certificate(caPrivKey); return cert; } private String testPolicies( int index, X509Certificate trustCert, X509Certificate intCert, X509Certificate endCert, Set requirePolicies, boolean okay) throws IOException, InvalidAlgorithmParameterException, NoSuchAlgorithmException, NoSuchProviderException, CertificateEncodingException { Set trust = new HashSet(); trust.add(new TrustAnchor(trustCert, null)); X509CertSelector targetConstraints = new X509CertSelector(); targetConstraints.setSubject(PrincipalUtil.getSubjectX509Principal(endCert).getEncoded()); PKIXBuilderParameters params = new PKIXBuilderParameters(trust, targetConstraints); Set certs = new HashSet(); certs.add(intCert); certs.add(endCert); CollectionCertStoreParameters pr = new CollectionCertStoreParameters(certs); CertStore store = CertStore.getInstance("Collection",pr); params.addCertStore(store); params.setRevocationEnabled(false); if (requirePolicies != null) { params.setExplicitPolicyRequired(true); params.setInitialPolicies(requirePolicies); } CertPathBuilder cpb = CertPathBuilder.getInstance("PKIX","BC"); // CertPathBuilder cpb = CertPathBuilder.getInstance("PKIX","SUN"); PKIXCertPathBuilderResult result = null; try { result = (PKIXCertPathBuilderResult)cpb.build(params); if (!okay) { fail(index + ": path validated when failure expected."); } // if (result.getPolicyTree() != null) // { // System.out.println("OK"); // System.out.println("policy: " + result.getPolicyTree()); // } // else // { // System.out.println("OK: policy tree = null"); // } return ""; } catch (TestFailedException e) { throw e; } catch (Exception e) { if (okay) { fail(index + ": path failed to validate when success expected."); } return e.getMessage(); } } public void performTest() throws Exception { // // personal keys // RSAPublicKeySpec pubKeySpec = new RSAPublicKeySpec( new BigInteger("b4a7e46170574f16a97082b22be58b6a2a629798419be12872a4bdba626cfae9900f76abfb12139dce5de56564fab2b6543165a040c606887420e33d91ed7ed7", 16), new BigInteger("11", 16)); RSAPrivateCrtKeySpec privKeySpec = new RSAPrivateCrtKeySpec( new BigInteger("b4a7e46170574f16a97082b22be58b6a2a629798419be12872a4bdba626cfae9900f76abfb12139dce5de56564fab2b6543165a040c606887420e33d91ed7ed7", 16), new BigInteger("11", 16), new BigInteger("9f66f6b05410cd503b2709e88115d55daced94d1a34d4e32bf824d0dde6028ae79c5f07b580f5dce240d7111f7ddb130a7945cd7d957d1920994da389f490c89", 16), new BigInteger("c0a0758cdf14256f78d4708c86becdead1b50ad4ad6c5c703e2168fbf37884cb", 16), new BigInteger("f01734d7960ea60070f1b06f2bb81bfac48ff192ae18451d5e56c734a5aab8a5", 16), new BigInteger("b54bb9edff22051d9ee60f9351a48591b6500a319429c069a3e335a1d6171391", 16), new BigInteger("d3d83daf2a0cecd3367ae6f8ae1aeb82e9ac2f816c6fc483533d8297dd7884cd", 16), new BigInteger("b8f52fc6f38593dabb661d3f50f8897f8106eee68b1bce78a95b132b4e5b5d19", 16)); // // intermediate keys. // RSAPublicKeySpec intPubKeySpec = new RSAPublicKeySpec( new BigInteger("8de0d113c5e736969c8d2b047a243f8fe18edad64cde9e842d3669230ca486f7cfdde1f8eec54d1905fff04acc85e61093e180cadc6cea407f193d44bb0e9449b8dbb49784cd9e36260c39e06a947299978c6ed8300724e887198cfede20f3fbde658fa2bd078be946a392bd349f2b49c486e20c405588e306706c9017308e69", 16), new BigInteger("ffff", 16)); RSAPrivateCrtKeySpec intPrivKeySpec = new RSAPrivateCrtKeySpec( new BigInteger("8de0d113c5e736969c8d2b047a243f8fe18edad64cde9e842d3669230ca486f7cfdde1f8eec54d1905fff04acc85e61093e180cadc6cea407f193d44bb0e9449b8dbb49784cd9e36260c39e06a947299978c6ed8300724e887198cfede20f3fbde658fa2bd078be946a392bd349f2b49c486e20c405588e306706c9017308e69", 16), new BigInteger("ffff", 16), new BigInteger("7deb1b194a85bcfd29cf871411468adbc987650903e3bacc8338c449ca7b32efd39ffc33bc84412fcd7df18d23ce9d7c25ea910b1ae9985373e0273b4dca7f2e0db3b7314056ac67fd277f8f89cf2fd73c34c6ca69f9ba477143d2b0e2445548aa0b4a8473095182631da46844c356f5e5c7522eb54b5a33f11d730ead9c0cff", 16), new BigInteger("ef4cede573cea47f83699b814de4302edb60eefe426c52e17bd7870ec7c6b7a24fe55282ebb73775f369157726fcfb988def2b40350bdca9e5b418340288f649", 16), new BigInteger("97c7737d1b9a0088c3c7b528539247fd2a1593e7e01cef18848755be82f4a45aa093276cb0cbf118cb41117540a78f3fc471ba5d69f0042274defc9161265721", 16), new BigInteger("6c641094e24d172728b8da3c2777e69adfd0839085be7e38c7c4a2dd00b1ae969f2ec9d23e7e37090fcd449a40af0ed463fe1c612d6810d6b4f58b7bfa31eb5f", 16), new BigInteger("70b7123e8e69dfa76feb1236d0a686144b00e9232ed52b73847e74ef3af71fb45ccb24261f40d27f98101e230cf27b977a5d5f1f15f6cf48d5cb1da2a3a3b87f", 16), new BigInteger("e38f5750d97e270996a286df2e653fd26c242106436f5bab0f4c7a9e654ce02665d5a281f2c412456f2d1fa26586ef04a9adac9004ca7f913162cb28e13bf40d", 16)); // // ca keys // RSAPublicKeySpec caPubKeySpec = new RSAPublicKeySpec( new BigInteger("b259d2d6e627a768c94be36164c2d9fc79d97aab9253140e5bf17751197731d6f7540d2509e7b9ffee0a70a6e26d56e92d2edd7f85aba85600b69089f35f6bdbf3c298e05842535d9f064e6b0391cb7d306e0a2d20c4dfb4e7b49a9640bdea26c10ad69c3f05007ce2513cee44cfe01998e62b6c3637d3fc0391079b26ee36d5", 16), new BigInteger("11", 16)); RSAPrivateCrtKeySpec caPrivKeySpec = new RSAPrivateCrtKeySpec( new BigInteger("b259d2d6e627a768c94be36164c2d9fc79d97aab9253140e5bf17751197731d6f7540d2509e7b9ffee0a70a6e26d56e92d2edd7f85aba85600b69089f35f6bdbf3c298e05842535d9f064e6b0391cb7d306e0a2d20c4dfb4e7b49a9640bdea26c10ad69c3f05007ce2513cee44cfe01998e62b6c3637d3fc0391079b26ee36d5", 16), new BigInteger("11", 16), new BigInteger("92e08f83cc9920746989ca5034dcb384a094fb9c5a6288fcc4304424ab8f56388f72652d8fafc65a4b9020896f2cde297080f2a540e7b7ce5af0b3446e1258d1dd7f245cf54124b4c6e17da21b90a0ebd22605e6f45c9f136d7a13eaac1c0f7487de8bd6d924972408ebb58af71e76fd7b012a8d0e165f3ae2e5077a8648e619", 16), new BigInteger("f75e80839b9b9379f1cf1128f321639757dba514642c206bbbd99f9a4846208b3e93fbbe5e0527cc59b1d4b929d9555853004c7c8b30ee6a213c3d1bb7415d03", 16), new BigInteger("b892d9ebdbfc37e397256dd8a5d3123534d1f03726284743ddc6be3a709edb696fc40c7d902ed804c6eee730eee3d5b20bf6bd8d87a296813c87d3b3cc9d7947", 16), new BigInteger("1d1a2d3ca8e52068b3094d501c9a842fec37f54db16e9a67070a8b3f53cc03d4257ad252a1a640eadd603724d7bf3737914b544ae332eedf4f34436cac25ceb5", 16), new BigInteger("6c929e4e81672fef49d9c825163fec97c4b7ba7acb26c0824638ac22605d7201c94625770984f78a56e6e25904fe7db407099cad9b14588841b94f5ab498dded", 16), new BigInteger("dae7651ee69ad1d081ec5e7188ae126f6004ff39556bde90e0b870962fa7b926d070686d8244fe5a9aa709a95686a104614834b0ada4b10f53197a5cb4c97339", 16)); // // set up the keys // KeyFactory fact = KeyFactory.getInstance("RSA", "BC"); PrivateKey caPrivKey = fact.generatePrivate(caPrivKeySpec); PublicKey caPubKey = fact.generatePublic(caPubKeySpec); PrivateKey intPrivKey = fact.generatePrivate(intPrivKeySpec); PublicKey intPubKey = fact.generatePublic(intPubKeySpec); PrivateKey privKey = fact.generatePrivate(privKeySpec); PublicKey pubKey = fact.generatePublic(pubKeySpec); X509Certificate trustCert = createTrustCert(caPubKey, caPrivKey); ASN1EncodableVector intPolicies = null; Hashtable map = null; ASN1EncodableVector policies = null; Set requirePolicies = null; X509Certificate intCert = null; X509Certificate endCert = null; /** * valid test_00 */ intPolicies = new ASN1EncodableVector(); intPolicies.add(new PolicyInformation(new ASN1ObjectIdentifier("2.5.29.32.0"))); map = new Hashtable(); map.put("2.16.840.1.101.3.2.1.48.1","2.16.840.1.101.3.2.1.48.2"); intCert = createIntmedCert(intPubKey, caPrivKey, caPubKey, intPolicies, map); policies = new ASN1EncodableVector(); policies.add(new PolicyInformation(new ASN1ObjectIdentifier("2.16.840.1.101.3.2.1.48.2"))); endCert = createEndEntityCert(pubKey, intPrivKey, intPubKey, policies); requirePolicies = null; String msg = testPolicies(0, trustCert, intCert, endCert, requirePolicies, true); checkMessage(0, msg, ""); /** * test_01 */ intPolicies = new ASN1EncodableVector(); intPolicies.add(new PolicyInformation(new ASN1ObjectIdentifier("2.5.29.32.0"))); map = new Hashtable(); map.put("2.16.840.1.101.3.2.1.48.1","2.16.840.1.101.3.2.1.48.2"); intCert = createIntmedCert(intPubKey, caPrivKey, caPubKey, intPolicies, map); policies = new ASN1EncodableVector(); policies.add(new PolicyInformation(new ASN1ObjectIdentifier("2.16.840.1.101.3.2.1.48.2"))); endCert = createEndEntityCert(pubKey, intPrivKey, intPubKey, policies); requirePolicies = new HashSet(); requirePolicies.add("2.16.840.1.101.3.2.1.48.1"); msg = testPolicies(1, trustCert, intCert, endCert, requirePolicies, true); checkMessage(1, msg, ""); /** * test_02 */ intPolicies = new ASN1EncodableVector(); intPolicies.add(new PolicyInformation(new ASN1ObjectIdentifier("2.5.29.32.0"))); map = new Hashtable(); map.put("2.16.840.1.101.3.2.1.48.1","2.16.840.1.101.3.2.1.48.2"); intCert = createIntmedCert(intPubKey, caPrivKey, caPubKey, intPolicies, map); policies = new ASN1EncodableVector(); policies.add(new PolicyInformation(new ASN1ObjectIdentifier("2.16.840.1.101.3.2.1.48.2"))); endCert = createEndEntityCert(pubKey, intPrivKey, intPubKey, policies); requirePolicies = new HashSet(); requirePolicies.add("2.5.29.32.0"); msg = testPolicies(2, trustCert, intCert, endCert, requirePolicies, true); checkMessage(2, msg, ""); /** * test_03 */ intPolicies = new ASN1EncodableVector(); intPolicies.add(new PolicyInformation(new ASN1ObjectIdentifier("2.16.840.1.101.3.2.1.48.3"))); intPolicies.add(new PolicyInformation(new ASN1ObjectIdentifier("2.5.29.32.0"))); map = new Hashtable(); map.put("2.16.840.1.101.3.2.1.48.1","2.16.840.1.101.3.2.1.48.2"); intCert = createIntmedCert(intPubKey, caPrivKey, caPubKey, intPolicies, map); policies = new ASN1EncodableVector(); policies.add(new PolicyInformation(new ASN1ObjectIdentifier("2.16.840.1.101.3.2.1.48.2"))); endCert = createEndEntityCert(pubKey, intPrivKey, intPubKey, policies); requirePolicies = new HashSet(); requirePolicies.add("2.16.840.1.101.3.2.1.48.1"); msg = testPolicies(3, trustCert, intCert, endCert, requirePolicies, true); checkMessage(3, msg, ""); /** * test_04 */ intPolicies = new ASN1EncodableVector(); intPolicies.add(new PolicyInformation(new ASN1ObjectIdentifier("2.16.840.1.101.3.2.1.48.3"))); intPolicies.add(new PolicyInformation(new ASN1ObjectIdentifier("2.5.29.32.0"))); map = new Hashtable(); map.put("2.16.840.1.101.3.2.1.48.1","2.16.840.1.101.3.2.1.48.2"); intCert = createIntmedCert(intPubKey, caPrivKey, caPubKey, intPolicies, map); policies = new ASN1EncodableVector(); policies.add(new PolicyInformation(new ASN1ObjectIdentifier("2.16.840.1.101.3.2.1.48.3"))); endCert = createEndEntityCert(pubKey, intPrivKey, intPubKey, policies); requirePolicies = new HashSet(); requirePolicies.add("2.16.840.1.101.3.2.1.48.3"); msg = testPolicies(4, trustCert, intCert, endCert, requirePolicies, true); checkMessage(4, msg, ""); /** * test_05 */ intPolicies = new ASN1EncodableVector(); intPolicies.add(new PolicyInformation(new ASN1ObjectIdentifier("2.5.29.32.0"))); map = new Hashtable(); map.put("2.16.840.1.101.3.2.1.48.1","2.16.840.1.101.3.2.1.48.2"); intCert = createIntmedCert(intPubKey, caPrivKey, caPubKey, intPolicies, map); policies = new ASN1EncodableVector(); policies.add(new PolicyInformation(new ASN1ObjectIdentifier("2.16.840.1.101.3.2.1.48.2"))); endCert = createEndEntityCert(pubKey, intPrivKey, intPubKey, policies); requirePolicies = new HashSet(); requirePolicies.add("2.16.840.1.101.3.2.1.48.2"); msg = testPolicies(5, trustCert, intCert, endCert, requirePolicies, false); checkMessage(5, msg, "Path processing failed on policy."); /** * test_06 */ intPolicies = new ASN1EncodableVector(); intPolicies.add(new PolicyInformation(new ASN1ObjectIdentifier("2.5.29.32.0"))); map = new Hashtable(); map.put("2.16.840.1.101.3.2.1.48.1","2.16.840.1.101.3.2.1.48.2"); intCert = createIntmedCert(intPubKey, caPrivKey, caPubKey, intPolicies, map); policies = new ASN1EncodableVector(); policies.add(new PolicyInformation(new ASN1ObjectIdentifier("2.16.840.1.101.3.2.1.48.1"))); endCert = createEndEntityCert(pubKey, intPrivKey, intPubKey, policies); requirePolicies = new HashSet(); requirePolicies.add("2.16.840.1.101.3.2.1.48.1"); msg = testPolicies(6, trustCert, intCert, endCert, requirePolicies, true); checkMessage(6, msg, ""); /** * test_07 */ intPolicies = new ASN1EncodableVector(); intPolicies.add(new PolicyInformation(new ASN1ObjectIdentifier("2.5.29.32.0"))); map = new Hashtable(); map.put("2.16.840.1.101.3.2.1.48.1","2.16.840.1.101.3.2.1.48.2"); intCert = createIntmedCert(intPubKey, caPrivKey, caPubKey, intPolicies, map); policies = new ASN1EncodableVector(); policies.add(new PolicyInformation(new ASN1ObjectIdentifier("2.16.840.1.101.3.2.1.48.2"))); endCert = createEndEntityCert(pubKey, intPrivKey, intPubKey, policies); requirePolicies = new HashSet(); requirePolicies.add("2.16.840.1.101.3.2.1.48.3"); msg = testPolicies(7, trustCert, intCert, endCert, requirePolicies, false); checkMessage(7, msg, "Path processing failed on policy."); /** * test_08 */ intPolicies = new ASN1EncodableVector(); intPolicies.add(new PolicyInformation(new ASN1ObjectIdentifier("2.5.29.32.0"))); map = new Hashtable(); map.put("2.16.840.1.101.3.2.1.48.1","2.16.840.1.101.3.2.1.48.2"); intCert = createIntmedCert(intPubKey, caPrivKey, caPubKey, intPolicies, map); policies = new ASN1EncodableVector(); policies.add(new PolicyInformation(new ASN1ObjectIdentifier("2.16.840.1.101.3.2.1.48.3"))); endCert = createEndEntityCert(pubKey, intPrivKey, intPubKey, policies); requirePolicies = new HashSet(); requirePolicies.add("2.16.840.1.101.3.2.1.48.1"); msg = testPolicies(8, trustCert, intCert, endCert, requirePolicies, false); checkMessage(8, msg, "Path processing failed on policy."); } private void checkMessage( int index, String msg, String expected) { if (!msg.equals(expected)) { fail("test " + index + " failed got: " + msg + " expected: " + expected); } } public static void main( String[] args) { Security.addProvider(new BouncyCastleProvider()); runTest(new PKIXPolicyMappingTest()); } } bouncycastle-1.49.orig/test/jdk1.3/org/bouncycastle/jce/provider/test/PSSTest.java0000644000175000017500000001473710331053204027411 0ustar ebourgebourgpackage org.bouncycastle.jce.provider.test; import java.math.BigInteger; import java.security.KeyFactory; import java.security.PrivateKey; import java.security.PublicKey; import java.security.SecureRandom; import java.security.Security; import java.security.Signature; import java.security.spec.RSAPrivateCrtKeySpec; import java.security.spec.RSAPublicKeySpec; import org.bouncycastle.jce.provider.BouncyCastleProvider; import org.bouncycastle.util.encoders.Hex; import org.bouncycastle.util.test.SimpleTestResult; import org.bouncycastle.util.test.Test; import org.bouncycastle.util.test.TestResult; public class PSSTest implements Test { private class FixedRandom extends SecureRandom { byte[] vals; FixedRandom( byte[] vals) { this.vals = vals; } public void nextBytes( byte[] bytes) { System.arraycopy(vals, 0, bytes, 0, vals.length); } } private boolean arrayEquals( byte[] a, byte[] b) { if (a.length != b.length) { return false; } for (int i = 0; i != a.length; i++) { if (a[i] != b[i]) { return false; } } return true; } private RSAPublicKeySpec pubKeySpec = new RSAPublicKeySpec( new BigInteger("a56e4a0e701017589a5187dc7ea841d156f2ec0e36ad52a44dfeb1e61f7ad991d8c51056ffedb162b4c0f283a12a88a394dff526ab7291cbb307ceabfce0b1dfd5cd9508096d5b2b8b6df5d671ef6377c0921cb23c270a70e2598e6ff89d19f105acc2d3f0cb35f29280e1386b6f64c4ef22e1e1f20d0ce8cffb2249bd9a2137",16), new BigInteger("010001",16)); private RSAPrivateCrtKeySpec privKeySpec = new RSAPrivateCrtKeySpec( new BigInteger("a56e4a0e701017589a5187dc7ea841d156f2ec0e36ad52a44dfeb1e61f7ad991d8c51056ffedb162b4c0f283a12a88a394dff526ab7291cbb307ceabfce0b1dfd5cd9508096d5b2b8b6df5d671ef6377c0921cb23c270a70e2598e6ff89d19f105acc2d3f0cb35f29280e1386b6f64c4ef22e1e1f20d0ce8cffb2249bd9a2137",16), new BigInteger("010001",16), new BigInteger("33a5042a90b27d4f5451ca9bbbd0b44771a101af884340aef9885f2a4bbe92e894a724ac3c568c8f97853ad07c0266c8c6a3ca0929f1e8f11231884429fc4d9ae55fee896a10ce707c3ed7e734e44727a39574501a532683109c2abacaba283c31b4bd2f53c3ee37e352cee34f9e503bd80c0622ad79c6dcee883547c6a3b325",16), new BigInteger("e7e8942720a877517273a356053ea2a1bc0c94aa72d55c6e86296b2dfc967948c0a72cbccca7eacb35706e09a1df55a1535bd9b3cc34160b3b6dcd3eda8e6443",16), new BigInteger("b69dca1cf7d4d7ec81e75b90fcca874abcde123fd2700180aa90479b6e48de8d67ed24f9f19d85ba275874f542cd20dc723e6963364a1f9425452b269a6799fd",16), new BigInteger("28fa13938655be1f8a159cbaca5a72ea190c30089e19cd274a556f36c4f6e19f554b34c077790427bbdd8dd3ede2448328f385d81b30e8e43b2fffa027861979",16), new BigInteger("1a8b38f398fa712049898d7fb79ee0a77668791299cdfa09efc0e507acb21ed74301ef5bfd48be455eaeb6e1678255827580a8e4e8e14151d1510a82a3f2e729",16), new BigInteger("27156aba4126d24a81f3a528cbfb27f56886f840a9f6e86e17a44b94fe9319584b8e22fdde1e5a2e3bd8aa5ba8d8584194eb2190acf832b847f13a3d24a79f4d",16)); // PSSExample1.1 private byte[] msg1a = Hex.decode("cdc87da223d786df3b45e0bbbc721326d1ee2af806cc315475cc6f0d9c66e1b62371d45ce2392e1ac92844c310102f156a0d8d52c1f4c40ba3aa65095786cb769757a6563ba958fed0bcc984e8b517a3d5f515b23b8a41e74aa867693f90dfb061a6e86dfaaee64472c00e5f20945729cbebe77f06ce78e08f4098fba41f9d6193c0317e8b60d4b6084acb42d29e3808a3bc372d85e331170fcbf7cc72d0b71c296648b3a4d10f416295d0807aa625cab2744fd9ea8fd223c42537029828bd16be02546f130fd2e33b936d2676e08aed1b73318b750a0167d0"); private byte[] slt1a = Hex.decode("dee959c7e06411361420ff80185ed57f3e6776af"); private byte[] sig1a = Hex.decode("9074308fb598e9701b2294388e52f971faac2b60a5145af185df5287b5ed2887e57ce7fd44dc8634e407c8e0e4360bc226f3ec227f9d9e54638e8d31f5051215df6ebb9c2f9579aa77598a38f914b5b9c1bd83c4e2f9f382a0d0aa3542ffee65984a601bc69eb28deb27dca12c82c2d4c3f66cd500f1ff2b994d8a4e30cbb33c"); private byte[] sig1b = Hex.decode("96ea348db4db2947aee807bd687411a880913706f21b383a1002b97e43656e5450a9d1812efbedd1ed159f8307986adf48bada66a8efd14bd9e2f6f6f458e73b50c8ce6e3079011c5b4bd1600a2601a66198a1582574a43f13e0966c6c2337e6ca0886cd9e1b1037aeadef1382117d22b35e7e4403f90531c8cfccdf223f98e4"); public TestResult perform() { try { KeyFactory fact = KeyFactory.getInstance("RSA", "BC"); PrivateKey privKey = fact.generatePrivate(privKeySpec); PublicKey pubKey = fact.generatePublic(pubKeySpec); Signature s = Signature.getInstance("SHA1withRSA/PSS", "BC"); s.initSign(privKey, new FixedRandom(slt1a)); s.update(msg1a); byte[] sig = s.sign(); if (!arrayEquals(sig1a, sig)) { return new SimpleTestResult(false, "PSS Sign test expected " + new String(Hex.encode(sig1a)) + " got " + new String(Hex.encode(sig))); } s = Signature.getInstance("SHA1withRSAandMGF1", "BC"); s.initVerify(pubKey); s.update(msg1a); if (!s.verify(sig1a)) { return new SimpleTestResult(false, "SHA1 signature verification failed"); } s = Signature.getInstance("SHA256WithRSA/PSS", "BC"); s.initSign(privKey, new FixedRandom(slt1a)); s.update(msg1a); sig = s.sign(); if (!arrayEquals(sig1b, sig)) { return new SimpleTestResult(false, "PSS Sign test expected " + new String(Hex.encode(sig1b)) + " got " + new String(Hex.encode(sig))); } s = Signature.getInstance("SHA256withRSAandMGF1", "BC"); s.initVerify(pubKey); s.update(msg1a); if (!s.verify(sig1b)) { return new SimpleTestResult(false, "SHA256 signature verification failed"); } return new SimpleTestResult(true, getName() + ": Okay"); } catch (Exception e) { return new SimpleTestResult(false, getName() + ": exception - " + e.toString()); } } public String getName() { return "PSSTest"; } public static void main( String[] args) { Security.addProvider(new BouncyCastleProvider()); Test test = new PSSTest(); TestResult result = test.perform(); System.out.println(result.toString()); } } bouncycastle-1.49.orig/test/jdk1.3/org/bouncycastle/jce/provider/test/CertStoreTest.java0000644000175000017500000001332110523731355030657 0ustar ebourgebourgpackage org.bouncycastle.jce.provider.test; import java.io.ByteArrayInputStream; import java.security.Security; import org.bouncycastle.jce.PrincipalUtil; import org.bouncycastle.jce.cert.CertStore; import java.security.cert.CertificateFactory; import org.bouncycastle.jce.cert.CollectionCertStoreParameters; import java.security.cert.X509CRL; import org.bouncycastle.jce.cert.X509CRLSelector; import org.bouncycastle.jce.cert.X509CertSelector; import java.security.cert.X509Certificate; import java.util.ArrayList; import java.util.Collection; import java.util.List; import org.bouncycastle.jce.provider.BouncyCastleProvider; import org.bouncycastle.util.test.SimpleTestResult; import org.bouncycastle.util.test.Test; import org.bouncycastle.util.test.TestResult; public class CertStoreTest implements Test { public TestResult perform() { try { CertificateFactory cf = CertificateFactory.getInstance("X.509", "BC"); X509Certificate rootCert = (X509Certificate)cf .generateCertificate(new ByteArrayInputStream( CertPathTest.rootCertBin)); X509Certificate interCert = (X509Certificate)cf .generateCertificate(new ByteArrayInputStream( CertPathTest.interCertBin)); X509Certificate finalCert = (X509Certificate)cf .generateCertificate(new ByteArrayInputStream( CertPathTest.finalCertBin)); X509CRL rootCrl = (X509CRL)cf.generateCRL(new ByteArrayInputStream( CertPathTest.rootCrlBin)); X509CRL interCrl = (X509CRL)cf .generateCRL(new ByteArrayInputStream( CertPathTest.interCrlBin)); // Testing CollectionCertStore generation from List List list = new ArrayList(); list.add(rootCert); list.add(interCert); list.add(finalCert); list.add(rootCrl); list.add(interCrl); CollectionCertStoreParameters ccsp = new CollectionCertStoreParameters( list); CertStore store = CertStore.getInstance("Collection", ccsp, "BC"); // Searching for rootCert by subjectDN X509CertSelector targetConstraints = new X509CertSelector(); targetConstraints.setSubject(PrincipalUtil.getSubjectX509Principal(rootCert).getName()); Collection certs = store.getCertificates(targetConstraints); if (certs.size() != 1 || !certs.contains(rootCert)) { return new SimpleTestResult(false, this.getName() + ": rootCert not found by subjectDN"); } // Searching for rootCert by subjectDN encoded as byte targetConstraints = new X509CertSelector(); targetConstraints.setSubject(PrincipalUtil.getSubjectX509Principal(rootCert) .getEncoded()); certs = store.getCertificates(targetConstraints); if (certs.size() != 1 || !certs.contains(rootCert)) { return new SimpleTestResult(false, this.getName() + ": rootCert not found by encoded subjectDN"); } // Searching for rootCert by public key encoded as byte targetConstraints = new X509CertSelector(); targetConstraints.setSubjectPublicKey(rootCert.getPublicKey() .getEncoded()); certs = store.getCertificates(targetConstraints); if (certs.size() != 1 || !certs.contains(rootCert)) { return new SimpleTestResult(false, this.getName() + ": rootCert not found by encoded public key"); } // Searching for interCert by issuerDN targetConstraints = new X509CertSelector(); targetConstraints.setIssuer(PrincipalUtil.getSubjectX509Principal(rootCert) .getEncoded()); certs = store.getCertificates(targetConstraints); if (certs.size() != 2) { return new SimpleTestResult(false, this.getName() + ": did not found 2 certs"); } if (!certs.contains(rootCert)) { return new SimpleTestResult(false, this.getName() + ": rootCert not found"); } if (!certs.contains(interCert)) { return new SimpleTestResult(false, this.getName() + ": interCert not found"); } // Searching for rootCrl by issuerDN X509CRLSelector targetConstraintsCRL = new X509CRLSelector(); targetConstraintsCRL.addIssuerName(PrincipalUtil.getIssuerX509Principal(rootCrl) .getEncoded()); Collection crls = store.getCRLs(targetConstraintsCRL); if (crls.size() != 1 || !crls.contains(rootCrl)) { return new SimpleTestResult(false, this.getName() + ": rootCrl not found"); } } catch (Exception e) { return new SimpleTestResult(false, this.getName() + ": exception - " + e.toString(), e); } return new SimpleTestResult(true, this.getName() + ": Okay"); } public String getName() { return "CertStore"; } public static void main(String[] args) { Security.addProvider(new BouncyCastleProvider()); Test test = new CertStoreTest(); TestResult result = test.perform(); System.out.println(result.toString()); } } bouncycastle-1.49.orig/test/jdk1.3/org/bouncycastle/jce/provider/test/PBETest.java0000644000175000017500000004243310336344002027350 0ustar ebourgebourgpackage org.bouncycastle.jce.provider.test; import java.security.AlgorithmParameters; import java.security.Security; import javax.crypto.Cipher; import javax.crypto.Mac; import javax.crypto.SecretKey; import javax.crypto.SecretKeyFactory; import javax.crypto.spec.IvParameterSpec; import javax.crypto.spec.PBEKeySpec; import javax.crypto.spec.PBEParameterSpec; import javax.crypto.spec.SecretKeySpec; import org.bouncycastle.crypto.Digest; import org.bouncycastle.crypto.PBEParametersGenerator; import org.bouncycastle.crypto.digests.SHA1Digest; import org.bouncycastle.crypto.digests.SHA256Digest; import org.bouncycastle.crypto.generators.OpenSSLPBEParametersGenerator; import org.bouncycastle.crypto.generators.PKCS12ParametersGenerator; import org.bouncycastle.crypto.params.KeyParameter; import org.bouncycastle.crypto.params.ParametersWithIV; import org.bouncycastle.jce.provider.BouncyCastleProvider; import org.bouncycastle.util.encoders.Hex; import org.bouncycastle.util.test.SimpleTestResult; import org.bouncycastle.util.test.Test; import org.bouncycastle.util.test.TestResult; /** * test out the various PBE modes, making sure the JCE implementations * are compatible woth the light weight ones. */ public class PBETest implements Test { private class OpenSSLTest implements Test { char[] password; String baseAlgorithm; String algorithm; int keySize; int ivSize; OpenSSLTest( String baseAlgorithm, String algorithm, int keySize, int ivSize) { this.password = algorithm.toCharArray(); this.baseAlgorithm = baseAlgorithm; this.algorithm = algorithm; this.keySize = keySize; this.ivSize = ivSize; } public String getName() { return "OpenSSLPBE"; } public TestResult perform() { byte[] salt = new byte[16]; int iCount = 100; for (int i = 0; i != salt.length; i++) { salt[i] = (byte)i; } try { OpenSSLPBEParametersGenerator pGen = new OpenSSLPBEParametersGenerator(); pGen.init( PBEParametersGenerator.PKCS5PasswordToBytes(password), salt); ParametersWithIV params = (ParametersWithIV)pGen.generateDerivedParameters(keySize, ivSize); SecretKeySpec encKey = new SecretKeySpec(((KeyParameter)params.getParameters()).getKey(), baseAlgorithm); Cipher c; if (baseAlgorithm.equals("RC4")) { c = Cipher.getInstance(baseAlgorithm, "BC"); c.init(Cipher.ENCRYPT_MODE, encKey); } else { c = Cipher.getInstance(baseAlgorithm + "/CBC/PKCS7Padding", "BC"); c.init(Cipher.ENCRYPT_MODE, encKey, new IvParameterSpec(params.getIV())); } byte[] enc = c.doFinal(salt); c = Cipher.getInstance(algorithm, "BC"); PBEKeySpec keySpec = new PBEKeySpec(password); SecretKeyFactory fact = SecretKeyFactory.getInstance(algorithm, "BC"); c.init(Cipher.DECRYPT_MODE, fact.generateSecret(keySpec), new PBEParameterSpec(salt, iCount)); byte[] dec = c.doFinal(enc); if (!arrayEquals(salt, dec)) { return new SimpleTestResult(false, getName() + ": " + algorithm + "failed encryption/decryption test"); } return new SimpleTestResult(true, getName() + ": Okay"); } catch (Exception e) { return new SimpleTestResult(false, getName() + ": " + algorithm + " failed - exception " + e, e); } } } private class PKCS12Test implements Test { char[] password; String baseAlgorithm; String algorithm; Digest digest; int keySize; int ivSize; PKCS12Test( String baseAlgorithm, String algorithm, Digest digest, int keySize, int ivSize) { this.password = algorithm.toCharArray(); this.baseAlgorithm = baseAlgorithm; this.algorithm = algorithm; this.digest = digest; this.keySize = keySize; this.ivSize = ivSize; } public String getName() { return "PKCS12PBE"; } public TestResult perform() { byte[] salt = new byte[digest.getDigestSize()]; int iCount = 100; digest.doFinal(salt, 0); try { PKCS12ParametersGenerator pGen = new PKCS12ParametersGenerator(digest); pGen.init( PBEParametersGenerator.PKCS12PasswordToBytes(password), salt, iCount); ParametersWithIV params = (ParametersWithIV)pGen.generateDerivedParameters(keySize, ivSize); SecretKeySpec encKey = new SecretKeySpec(((KeyParameter)params.getParameters()).getKey(), baseAlgorithm); Cipher c; if (baseAlgorithm.equals("RC4")) { c = Cipher.getInstance(baseAlgorithm, "BC"); c.init(Cipher.ENCRYPT_MODE, encKey); } else { c = Cipher.getInstance(baseAlgorithm + "/CBC/PKCS7Padding", "BC"); c.init(Cipher.ENCRYPT_MODE, encKey, new IvParameterSpec(params.getIV())); } byte[] enc = c.doFinal(salt); c = Cipher.getInstance(algorithm, "BC"); PBEKeySpec keySpec = new PBEKeySpec(password); SecretKeyFactory fact = SecretKeyFactory.getInstance(algorithm, "BC"); c.init(Cipher.DECRYPT_MODE, fact.generateSecret(keySpec), new PBEParameterSpec(salt, iCount)); byte[] dec = c.doFinal(enc); if (!arrayEquals(salt, dec)) { return new SimpleTestResult(false, getName() + ": " + algorithm + "failed encryption/decryption test"); } // // get the parameters // AlgorithmParameters param = c.getParameters(); PBEParameterSpec spec = (PBEParameterSpec)param.getParameterSpec(PBEParameterSpec.class); if (!arrayEquals(salt, spec.getSalt())) { return new SimpleTestResult(false, getName() + ": " + algorithm + "failed salt test"); } if (iCount != spec.getIterationCount()) { return new SimpleTestResult(false, getName() + ": " + algorithm + "failed count test"); } // // try using parameters // keySpec = new PBEKeySpec(password); c.init(Cipher.DECRYPT_MODE, fact.generateSecret(keySpec), param); dec = c.doFinal(enc); if (!arrayEquals(salt, dec)) { return new SimpleTestResult(false, getName() + ": " + algorithm + "failed encryption/decryption test"); } return new SimpleTestResult(true, getName() + ": Okay"); } catch (Exception e) { return new SimpleTestResult(false, getName() + ": " + algorithm + " failed - exception " + e, e); } } } private PKCS12Test[] pkcs12Tests = { new PKCS12Test("DESede", "PBEWITHSHAAND3-KEYTRIPLEDES-CBC", new SHA1Digest(), 192, 64), new PKCS12Test("DESede", "PBEWITHSHAAND2-KEYTRIPLEDES-CBC", new SHA1Digest(), 128, 64), new PKCS12Test("RC4", "PBEWITHSHAAND128BITRC4", new SHA1Digest(), 128, 0), new PKCS12Test("RC4", "PBEWITHSHAAND40BITRC4", new SHA1Digest(), 40, 0), new PKCS12Test("RC2", "PBEWITHSHAAND128BITRC2-CBC", new SHA1Digest(), 128, 64), new PKCS12Test("RC2", "PBEWITHSHAAND40BITRC2-CBC", new SHA1Digest(), 40, 64), new PKCS12Test("AES", "PBEWithSHA1And128BitAES-CBC-BC", new SHA1Digest(), 128, 128), new PKCS12Test("AES", "PBEWithSHA1And192BitAES-CBC-BC", new SHA1Digest(), 192, 128), new PKCS12Test("AES", "PBEWithSHA1And256BitAES-CBC-BC", new SHA1Digest(), 256, 128), new PKCS12Test("AES", "PBEWithSHA256And128BitAES-CBC-BC", new SHA256Digest(), 128, 128), new PKCS12Test("AES", "PBEWithSHA256And192BitAES-CBC-BC", new SHA256Digest(), 192, 128), new PKCS12Test("AES", "PBEWithSHA256And256BitAES-CBC-BC", new SHA256Digest(), 256, 128) }; private OpenSSLTest openSSLTests[] = { new OpenSSLTest("AES", "PBEWITHMD5AND128BITAES-CBC-OPENSSL", 128, 128), new OpenSSLTest("AES", "PBEWITHMD5AND192BITAES-CBC-OPENSSL", 192, 128), new OpenSSLTest("AES", "PBEWITHMD5AND256BITAES-CBC-OPENSSL", 256, 128) }; static byte[] message = Hex.decode("4869205468657265"); private byte[] hMac1 = Hex.decode("bcc42174ccb04f425d9a5c8c4a95d6fd7c372911"); private byte[] hMac2 = Hex.decode("cb1d8bdb6aca9e3fa8980d6eb41ab28a7eb2cfd6"); private Cipher makePBECipher( String algorithm, int mode, char[] password, byte[] salt, int iterationCount) throws Exception { PBEKeySpec pbeSpec = new PBEKeySpec(password); SecretKeyFactory keyFact = SecretKeyFactory.getInstance(algorithm, "BC"); PBEParameterSpec defParams = new PBEParameterSpec(salt, iterationCount); Cipher cipher = Cipher.getInstance(algorithm, "BC"); cipher.init(mode, keyFact.generateSecret(pbeSpec), defParams); return cipher; } private boolean arrayEquals( byte[] a, byte[] b) { if (a.length != b.length) { return false; } for (int i = 0; i != a.length; i++) { if (a[i] != b[i]) { return false; } } return true; } public TestResult testPBEHMac( String hmacName, byte[] output) { SecretKey key; byte[] out; Mac mac; try { SecretKeyFactory fact = SecretKeyFactory.getInstance(hmacName, "BC"); key = fact.generateSecret(new PBEKeySpec("hello".toCharArray())); mac = Mac.getInstance(hmacName, "BC"); } catch (Exception e) { return new SimpleTestResult(false, getName() + ": Failed - exception " + e.toString(), e); } try { mac.init(key, new PBEParameterSpec(new byte[20], 100)); } catch (Exception e) { return new SimpleTestResult(false, getName() + ": Failed - exception " + e.toString(), e); } mac.reset(); mac.update(message, 0, message.length); out = mac.doFinal(); if (!arrayEquals(out, output)) { return new SimpleTestResult(false, getName() + ": Failed - expected " + new String(Hex.encode(output)) + " got " + new String(Hex.encode(out))); } return new SimpleTestResult(true, getName() + ": Okay"); } public TestResult perform() { byte[] input = Hex.decode("1234567890abcdefabcdef1234567890fedbca098765"); try { // // DES // Cipher cEnc = Cipher.getInstance("DES/CBC/PKCS7Padding", "BC"); cEnc.init(Cipher.ENCRYPT_MODE, new SecretKeySpec(Hex.decode("30e69252758e5346"), "DES"), new IvParameterSpec(Hex.decode("7c1c1ab9c454a688"))); byte[] out = cEnc.doFinal(input); char[] password = { 'p', 'a', 's', 's', 'w', 'o', 'r', 'd' }; Cipher cDec = makePBECipher( "PBEWithSHA1AndDES", Cipher.DECRYPT_MODE, password, Hex.decode("7d60435f02e9e0ae"), 2048); byte[] in = cDec.doFinal(out); if (!arrayEquals(input, in)) { return new SimpleTestResult(false, getName() + ": DES failed"); } // // DESede // cEnc = Cipher.getInstance("DESede/CBC/PKCS7Padding", "BC"); cEnc.init(Cipher.ENCRYPT_MODE, new SecretKeySpec(Hex.decode("732f2d33c801732b7206756cbd44f9c1c103ddd97c7cbe8e"), "DES"), new IvParameterSpec(Hex.decode("b07bf522c8d608b8"))); out = cEnc.doFinal(input); cDec = makePBECipher( "PBEWithSHAAnd3-KeyTripleDES-CBC", Cipher.DECRYPT_MODE, password, Hex.decode("7d60435f02e9e0ae"), 2048); in = cDec.doFinal(out); if (!arrayEquals(input, in)) { return new SimpleTestResult(false, getName() + ": DESede failed"); } // // 40Bit RC2 // cEnc = Cipher.getInstance("RC2/CBC/PKCS7Padding", "BC"); cEnc.init(Cipher.ENCRYPT_MODE, new SecretKeySpec(Hex.decode("732f2d33c8"), "RC2"), new IvParameterSpec(Hex.decode("b07bf522c8d608b8"))); out = cEnc.doFinal(input); cDec = makePBECipher( "PBEWithSHAAnd40BitRC2-CBC", Cipher.DECRYPT_MODE, password, Hex.decode("7d60435f02e9e0ae"), 2048); in = cDec.doFinal(out); if (!arrayEquals(input, in)) { return new SimpleTestResult(false, getName() + ": RC2 failed"); } // // 128bit RC4 // cEnc = Cipher.getInstance("RC4", "BC"); cEnc.init(Cipher.ENCRYPT_MODE, new SecretKeySpec(Hex.decode("732f2d33c801732b7206756cbd44f9c1"), "RC4")); out = cEnc.doFinal(input); cDec = makePBECipher( "PBEWithSHAAnd128BitRC4", Cipher.DECRYPT_MODE, password, Hex.decode("7d60435f02e9e0ae"), 2048); in = cDec.doFinal(out); if (!arrayEquals(input, in)) { return new SimpleTestResult(false, getName() + ": RC4 failed"); } for (int i = 0; i != pkcs12Tests.length; i++) { TestResult res = pkcs12Tests[i].perform(); if (!res.isSuccessful()) { return res; } } for (int i = 0; i != openSSLTests.length; i++) { TestResult res = openSSLTests[i].perform(); if (!res.isSuccessful()) { return res; } } TestResult res = testPBEHMac("PBEWithHMacSHA1", hMac1); if (!res.isSuccessful()) { return res; } res = testPBEHMac("PBEWithHMacRIPEMD160", hMac2); if (!res.isSuccessful()) { return res; } return new SimpleTestResult(true, getName() + ": Okay"); } catch (Exception e) { return new SimpleTestResult(false, getName() + ": exception - " + e.toString(), e); } } public String getName() { return "PBETest"; } public static void main( String[] args) { Security.addProvider(new BouncyCastleProvider()); Test test = new PBETest(); TestResult result = test.perform(); System.out.println(result.toString()); } } bouncycastle-1.49.orig/test/jdk1.3/org/bouncycastle/jce/provider/test/CertPathBuilderTest.java0000644000175000017500000001547010604446274032000 0ustar ebourgebourgpackage org.bouncycastle.jce.provider.test; import java.io.ByteArrayInputStream; import java.math.BigInteger; import java.security.KeyPair; import java.security.Security; import org.bouncycastle.jce.cert.CertPath; import org.bouncycastle.jce.cert.CertPathBuilder; import org.bouncycastle.jce.cert.CertStore; import org.bouncycastle.jce.cert.CertificateFactory; import org.bouncycastle.jce.cert.CollectionCertStoreParameters; import org.bouncycastle.jce.cert.PKIXBuilderParameters; import org.bouncycastle.jce.cert.PKIXCertPathBuilderResult; import org.bouncycastle.jce.cert.TrustAnchor; import java.security.cert.X509CRL; import org.bouncycastle.jce.cert.X509CertSelector; import java.security.cert.X509Certificate; import java.util.ArrayList; import java.util.Calendar; import java.util.Collections; import java.util.Date; import java.util.HashSet; import java.util.List; import java.util.Set; import org.bouncycastle.jce.PrincipalUtil; import org.bouncycastle.jce.provider.BouncyCastleProvider; import org.bouncycastle.util.test.SimpleTestResult; import org.bouncycastle.util.test.Test; import org.bouncycastle.util.test.TestResult; public class CertPathBuilderTest implements Test { public TestResult baseTest() { try { CertificateFactory cf = CertificateFactory.getInstance("X.509", "BC"); // initialise CertStore X509Certificate rootCert = (X509Certificate)cf.generateCertificate(new ByteArrayInputStream(CertPathTest.rootCertBin)); X509Certificate interCert = (X509Certificate)cf.generateCertificate(new ByteArrayInputStream(CertPathTest.interCertBin)); X509Certificate finalCert = (X509Certificate)cf.generateCertificate(new ByteArrayInputStream(CertPathTest.finalCertBin)); X509CRL rootCrl = (X509CRL)cf.generateCRL(new ByteArrayInputStream(CertPathTest.rootCrlBin)); X509CRL interCrl = (X509CRL)cf.generateCRL(new ByteArrayInputStream(CertPathTest.interCrlBin)); List list = new ArrayList(); list.add(rootCert); list.add(interCert); list.add(finalCert); list.add(rootCrl); list.add(interCrl); CollectionCertStoreParameters ccsp = new CollectionCertStoreParameters(list); CertStore store = CertStore.getInstance("Collection", ccsp, "BC"); Calendar validDate = Calendar.getInstance(); validDate.set(2002,2,21,2,21,10); //Searching for rootCert by subjectDN without CRL Set trust = new HashSet(); trust.add(new TrustAnchor(rootCert, null)); CertPathBuilder cpb = CertPathBuilder.getInstance("PKIX","BC"); X509CertSelector targetConstraints = new X509CertSelector(); targetConstraints.setSubject(PrincipalUtil.getSubjectX509Principal(finalCert).getEncoded()); PKIXBuilderParameters params = new PKIXBuilderParameters(trust, targetConstraints); params.addCertStore(store); params.setDate(validDate.getTime()); PKIXCertPathBuilderResult result = (PKIXCertPathBuilderResult) cpb.build(params); CertPath path = result.getCertPath(); if (path.getCertificates().size() != 2) { return new SimpleTestResult(false, this.getName() + ": wrong number of certs in baseTest path"); } } catch (Exception e) { return new SimpleTestResult(false, this.getName() + ": exception - " + e.toString(), e); } return new SimpleTestResult(true, this.getName() + ": Okay"); } public TestResult v0Test() { try { // create certificates and CRLs KeyPair rootPair = TestUtils.generateRSAKeyPair(); KeyPair interPair = TestUtils.generateRSAKeyPair(); KeyPair endPair = TestUtils.generateRSAKeyPair(); X509Certificate rootCert = TestUtils.generateRootCert(rootPair); X509Certificate interCert = TestUtils.generateIntermediateCert(interPair.getPublic(), rootPair.getPrivate(), rootCert); X509Certificate endCert = TestUtils.generateEndEntityCert(endPair.getPublic(), interPair.getPrivate(), interCert); BigInteger revokedSerialNumber = BigInteger.valueOf(2); X509CRL rootCRL = TestUtils.createCRL(rootCert, rootPair.getPrivate(), revokedSerialNumber); X509CRL interCRL = TestUtils.createCRL(interCert, interPair.getPrivate(), revokedSerialNumber); // create CertStore to support path building List list = new ArrayList(); list.add(rootCert); list.add(interCert); list.add(endCert); list.add(rootCRL); list.add(interCRL); CollectionCertStoreParameters params = new CollectionCertStoreParameters(list); CertStore store = CertStore.getInstance("Collection", params); // build the path CertPathBuilder builder = CertPathBuilder.getInstance("PKIX", "BC"); X509CertSelector pathConstraints = new X509CertSelector(); pathConstraints.setSubject(PrincipalUtil.getSubjectX509Principal(endCert).getEncoded()); PKIXBuilderParameters buildParams = new PKIXBuilderParameters(Collections.singleton(new TrustAnchor(rootCert, null)), pathConstraints); buildParams.addCertStore(store); buildParams.setDate(new Date()); PKIXCertPathBuilderResult result = (PKIXCertPathBuilderResult)builder.build(buildParams); CertPath path = result.getCertPath(); if (path.getCertificates().size() != 2) { return new SimpleTestResult(false, this.getName() + ": wrong number of certs in v0Test path"); } } catch (Exception e) { return new SimpleTestResult(false, this.getName() + ": exception - " + e.toString(), e); } return new SimpleTestResult(true, this.getName() + ": Okay"); } /* (non-Javadoc) * @see org.bouncycastle.util.test.Test#perform() */ public TestResult perform() { TestResult res = baseTest(); if (!res.isSuccessful()) { return res; } return v0Test(); } public String getName() { return "CertPathBuilder"; } public static void main( String[] args) { Security.addProvider(new BouncyCastleProvider()); Test test = new CertPathBuilderTest(); TestResult result = test.perform(); System.out.println(result.toString()); } } bouncycastle-1.49.orig/test/jdk1.3/org/bouncycastle/jce/provider/test/CertPathValidatorTest.java0000644000175000017500000003101311033554730032320 0ustar ebourgebourgpackage org.bouncycastle.jce.provider.test; import java.io.ByteArrayInputStream; import java.security.PublicKey; import java.security.Security; import org.bouncycastle.jce.cert.CertPath; import org.bouncycastle.jce.cert.CertPathValidator; import org.bouncycastle.jce.cert.CertPathValidatorException; import org.bouncycastle.jce.cert.CertStore; import org.bouncycastle.jce.cert.CertificateFactory; import org.bouncycastle.jce.cert.CollectionCertStoreParameters; import org.bouncycastle.jce.cert.PKIXCertPathValidatorResult; import org.bouncycastle.jce.cert.PKIXParameters; import org.bouncycastle.jce.cert.PolicyNode; import org.bouncycastle.jce.cert.TrustAnchor; import java.security.cert.X509CRL; import java.security.cert.X509Certificate; import java.util.ArrayList; import java.util.Calendar; import java.util.HashSet; import java.util.List; import java.util.Set; import org.bouncycastle.jce.provider.BouncyCastleProvider; import org.bouncycastle.util.encoders.Base64; import org.bouncycastle.util.test.SimpleTest; public class CertPathValidatorTest extends SimpleTest { private byte[] AC_PR = Base64.decode( "LS0tLS1CRUdJTiBDRVJUSUZJQ0FURS0tLS0tDQpNSUlFU1RDQ0F6R2dBd0lC" + "QWdJQkJUQU5CZ2txaGtpRzl3MEJBUVVGQURDQnRERUxNQWtHQTFVRUJoTUNR" + "bEl4DQpFekFSQmdOVkJBb1RDa2xEVUMxQ2NtRnphV3d4UFRBN0JnTlZCQXNU" + "TkVsdWMzUnBkSFYwYnlCT1lXTnBiMjVoDQpiQ0JrWlNCVVpXTnViMnh2WjJs" + "aElHUmhJRWx1Wm05eWJXRmpZVzhnTFNCSlZFa3hFVEFQQmdOVkJBY1RDRUp5" + "DQpZWE5wYkdsaE1Rc3dDUVlEVlFRSUV3SkVSakV4TUM4R0ExVUVBeE1vUVhW" + "MGIzSnBaR0ZrWlNCRFpYSjBhV1pwDQpZMkZrYjNKaElGSmhhWG9nUW5KaGMy" + "bHNaV2x5WVRBZUZ3MHdNakEwTURReE9UTTVNREJhRncwd05UQTBNRFF5DQpN" + "elU1TURCYU1HRXhDekFKQmdOVkJBWVRBa0pTTVJNd0VRWURWUVFLRXdwSlEx" + "QXRRbkpoYzJsc01UMHdPd1lEDQpWUVFERXpSQmRYUnZjbWxrWVdSbElFTmxj" + "blJwWm1sallXUnZjbUVnWkdFZ1VISmxjMmxrWlc1amFXRWdaR0VnDQpVbVZ3" + "ZFdKc2FXTmhNSUlCSWpBTkJna3Foa2lHOXcwQkFRRUZBQU9DQVE4QU1JSUJD" + "Z0tDQVFFQXMwc0t5NGsrDQp6b016aldyMTQxeTVYQ045UGJMZERFQXN2cjZ4" + "Z0NCN1l5bEhIQ1NBYmpGR3dOQ0R5NlVxN1h0VjZ6UHdIMXpGDQpFWENlS3Jm" + "UUl5YXBXSEZ4V1VKajBMblFrY1RZM1FOR1huK0JuVk9EVTZDV3M1c3NoZktH" + "RXZyVlQ1Z214V1NmDQp4OFlsdDgzY1dwUE1QZzg3VDlCaHVIbHQzazh2M2Ev" + "NmRPbmF2dytOYTAyZExBaDBlNzZqcCtQUS9LK0pHZlBuDQphQjVVWURrZkd0" + "em5uTTNBV01tY3VJK0o0ek5OMDZaa3ZnbDFsdEo2UU1qcnZEUFlSak9ndDlT" + "cklpY1NmbEo4DQptVDdHWGRRaXJnQUNXc3g1QURBSklRK253TU1vNHlyTUtx" + "SlFhNFFDMHhhT0QvdkdVcG9SaDQzT0FTZFp3c3YvDQpPWFlybmVJeVAwVCs4" + "UUlEQVFBQm80RzNNSUcwTUQwR0ExVWRId1EyTURRd01xQXdvQzZHTEdoMGRI" + "QTZMeTloDQpZM0poYVhvdWFXTndZbkpoYzJsc0xtZHZkaTVpY2k5TVExSmhZ" + "M0poYVhvdVkzSnNNQklHQTFVZElBUUxNQWt3DQpCd1lGWUV3QkFRRXdIUVlE" + "VlIwT0JCWUVGREpUVFlKNE9TWVB5T09KZkVMZXhDaHppK2hiTUI4R0ExVWRJ" + "d1FZDQpNQmFBRklyNjhWZUVFUk0xa0VMNlYwbFVhUTJreFBBM01BNEdBMVVk" + "RHdFQi93UUVBd0lCQmpBUEJnTlZIUk1CDQpBZjhFQlRBREFRSC9NQTBHQ1Nx" + "R1NJYjNEUUVCQlFVQUE0SUJBUUJRUFNoZ1lidnFjaWV2SDVVb3ZMeXhkbkYr" + "DQpFcjlOeXF1SWNkMnZ3Y0N1SnpKMkQ3WDBUcWhHQ0JmUEpVVkdBVWorS0NP" + "SDFCVkgva1l1OUhsVHB1MGtKWFBwDQpBQlZkb2hJUERqRHhkbjhXcFFSL0Yr" + "ejFDaWtVcldIMDR4eTd1N1p6UUpLSlBuR0loY1FpOElyRm1PYkllMEc3DQpY" + "WTZPTjdPRUZxY21KTFFHWWdtRzFXMklXcytQd1JwWTdENGhLVEFoVjFSNkVv" + "amE1L3BPcmVDL09kZXlQWmVxDQo1SUZTOUZZZk02U0Npd2hrK3l2Q1FHbVo0" + "YzE5SjM0ZjVFYkRrK1NQR2tEK25EQ0E3L3VMUWNUMlJURE14SzBaDQpuZlo2" + "Nm1Sc0ZjcXRGaWdScjVFcmtKZDdoUVV6eHNOV0VrNzJEVUFIcVgvNlNjeWtt" + "SkR2V0plSUpqZlcNCi0tLS0tRU5EIENFUlRJRklDQVRFLS0tLS0NCg=="); private byte[] AC_RAIZ_ICPBRASIL = Base64.decode( "LS0tLS1CRUdJTiBDRVJUSUZJQ0FURS0tLS0tDQpNSUlFdURDQ0E2Q2dBd0lC" + "QWdJQkJEQU5CZ2txaGtpRzl3MEJBUVVGQURDQnRERUxNQWtHQTFVRUJoTUNR" + "bEl4DQpFekFSQmdOVkJBb1RDa2xEVUMxQ2NtRnphV3d4UFRBN0JnTlZCQXNU" + "TkVsdWMzUnBkSFYwYnlCT1lXTnBiMjVoDQpiQ0JrWlNCVVpXTnViMnh2WjJs" + "aElHUmhJRWx1Wm05eWJXRmpZVzhnTFNCSlZFa3hFVEFQQmdOVkJBY1RDRUp5" + "DQpZWE5wYkdsaE1Rc3dDUVlEVlFRSUV3SkVSakV4TUM4R0ExVUVBeE1vUVhW" + "MGIzSnBaR0ZrWlNCRFpYSjBhV1pwDQpZMkZrYjNKaElGSmhhWG9nUW5KaGMy" + "bHNaV2x5WVRBZUZ3MHdNVEV4TXpBeE1qVTRNREJhRncweE1URXhNekF5DQpN" + "elU1TURCYU1JRzBNUXN3Q1FZRFZRUUdFd0pDVWpFVE1CRUdBMVVFQ2hNS1NV" + "TlFMVUp5WVhOcGJERTlNRHNHDQpBMVVFQ3hNMFNXNXpkR2wwZFhSdklFNWhZ" + "Mmx2Ym1Gc0lHUmxJRlJsWTI1dmJHOW5hV0VnWkdFZ1NXNW1iM0p0DQpZV05o" + "YnlBdElFbFVTVEVSTUE4R0ExVUVCeE1JUW5KaGMybHNhV0V4Q3pBSkJnTlZC" + "QWdUQWtSR01URXdMd1lEDQpWUVFERXloQmRYUnZjbWxrWVdSbElFTmxjblJw" + "Wm1sallXUnZjbUVnVW1GcGVpQkNjbUZ6YVd4bGFYSmhNSUlCDQpJakFOQmdr" + "cWhraUc5dzBCQVFFRkFBT0NBUThBTUlJQkNnS0NBUUVBd1BNdWR3WC9odm0r" + "VWgyYi9sUUFjSFZBDQppc2FtYUxrV2Rrd1A5L1MvdE9LSWdSckw2T3krWklH" + "bE9VZGQ2dVl0azlNYS8zcFVwZ2NmTkFqMHZZbTVnc3lqDQpRbzllbXNjK3g2" + "bTRWV3drOWlxTVpTQ0s1RVFrQXEvVXQ0bjdLdUxFMStnZGZ0d2RJZ3hmVXNQ" + "dDRDeU5yWTUwDQpRVjU3S00yVVQ4eDVycm16RWpyN1RJQ0dwU1VBbDJnVnFl" + "NnhhaWkrYm1ZUjFRcm1XYUJTQUc1OUxya3Jqcll0DQpiUmhGYm9VRGUxREsr" + "NlQ4czVMNms4Yzhva3BiSHBhOXZlTXp0RFZDOXNQSjYwTVdYaDZhblZLbzFV" + "Y0xjYlVSDQp5RWVOdlpuZVZSS0FBVTZvdXdkakR2d2xzYUt5ZEZLd2VkMFRv" + "UTQ3Ym1VS2djbSt3VjNlVFJrMzZVT25Ud0lEDQpBUUFCbzRIU01JSFBNRTRH" + "QTFVZElBUkhNRVV3UXdZRllFd0JBUUF3T2pBNEJnZ3JCZ0VGQlFjQ0FSWXNh" + "SFIwDQpjRG92TDJGamNtRnBlaTVwWTNCaWNtRnphV3d1WjI5MkxtSnlMMFJR" + "UTJGamNtRnBlaTV3WkdZd1BRWURWUjBmDQpCRFl3TkRBeW9EQ2dMb1lzYUhS" + "MGNEb3ZMMkZqY21GcGVpNXBZM0JpY21GemFXd3VaMjkyTG1KeUwweERVbUZq" + "DQpjbUZwZWk1amNtd3dIUVlEVlIwT0JCWUVGSXI2OFZlRUVSTTFrRUw2VjBs" + "VWFRMmt4UEEzTUE4R0ExVWRFd0VCDQovd1FGTUFNQkFmOHdEZ1lEVlIwUEFR" + "SC9CQVFEQWdFR01BMEdDU3FHU0liM0RRRUJCUVVBQTRJQkFRQVpBNWMxDQpV" + "L2hnSWg2T2NnTEFmaUpnRldwdm1EWldxbFYzMC9iSEZwajhpQm9iSlNtNXVE" + "cHQ3VGlyWWgxVXhlM2ZRYUdsDQpZakplKzl6ZCtpelBSYkJxWFBWUUEzNEVY" + "Y3drNHFwV3VmMWhIcmlXZmRyeDhBY3FTcXI2Q3VRRndTcjc1Rm9zDQpTemx3" + "REFEYTcwbVQ3d1pqQW1RaG5aeDJ4SjZ3ZldsVDlWUWZTLy9KWWVJYzdGdWUy" + "Sk5MZDAwVU9TTU1haUsvDQp0NzllbktOSEVBMmZ1cEgzdkVpZ2Y1RWg0YlZB" + "TjVWb2hyVG02TVk1M3g3WFFaWnIxTUU3YTU1bEZFblNlVDB1DQptbE9BalIy" + "bUFidlNNNVg1b1NaTnJtZXRkenlUajJmbENNOENDN01MYWIwa2tkbmdSSWxV" + "QkdIRjEvUzVubVBiDQpLKzlBNDZzZDMzb3FLOG44DQotLS0tLUVORCBDRVJU" + "SUZJQ0FURS0tLS0tDQo="); private byte[] schefer = Base64.decode( "MIIEnDCCBAWgAwIBAgICIPAwDQYJKoZIhvcNAQEEBQAwgcAxCzAJBgNVBAYT" + "AkRFMQ8wDQYDVQQIEwZIRVNTRU4xGDAWBgNVBAcTDzY1MDA4IFdpZXNiYWRl" + "bjEaMBgGA1UEChMRU0NIVUZBIEhPTERJTkcgQUcxGjAYBgNVBAsTEVNDSFVG" + "QSBIT0xESU5HIEFHMSIwIAYDVQQDExlJbnRlcm5ldCBCZW51dHplciBTZXJ2" + "aWNlMSowKAYJKoZIhvcNAQkBFht6ZXJ0aWZpa2F0QHNjaHVmYS1vbmxpbmUu" + "ZGUwHhcNMDQwMzMwMTEwODAzWhcNMDUwMzMwMTEwODAzWjCBnTELMAkGA1UE" + "BhMCREUxCjAIBgNVBAcTASAxIzAhBgNVBAoTGlNIUyBJbmZvcm1hdGlvbnNz" + "eXN0ZW1lIEFHMRwwGgYDVQQLExM2MDAvMDU5NDktNjAwLzA1OTQ5MRgwFgYD" + "VQQDEw9TY2hldHRlciBTdGVmYW4xJTAjBgkqhkiG9w0BCQEWFlN0ZWZhbi5T" + "Y2hldHRlckBzaHMuZGUwgZ8wDQYJKoZIhvcNAQEBBQADgY0AMIGJAoGBAJD0" + "95Bi76fkAMjJNTGPDiLPHmZXNsmakngDeS0juzKMeJA+TjXFouhYh6QyE4Bl" + "Nf18fT4mInlgLefwf4t6meIWbiseeTo7VQdM+YrbXERMx2uHsRcgZMsiMYHM" + "kVfYMK3SMJ4nhCmZxrBkoTRed4gXzVA1AA8YjjTqMyyjvt4TAgMBAAGjggHE" + "MIIBwDAJBgNVHRMEAjAAMBEGCWCGSAGG+EIBAQQEAwIEsDALBgNVHQ8EBAMC" + "BNAwOQYJYIZIAYb4QgENBCwWKlplcnRpZmlrYXQgbnVyIGZ1ZXIgU0NIVUZB" + "LU9ubGluZSBndWVsdGlnLjAdBgNVHQ4EFgQUXReirhBfg0Yhf6MsBWoo/nPa" + "hGwwge0GA1UdIwSB5TCB4oAUf2UyCaBV9JUeG9lS1Yo6OFBUdEKhgcakgcMw" + "gcAxCzAJBgNVBAYTAkRFMQ8wDQYDVQQIEwZIRVNTRU4xGDAWBgNVBAcTDzY1" + "MDA4IFdpZXNiYWRlbjEaMBgGA1UEChMRU0NIVUZBIEhPTERJTkcgQUcxGjAY" + "BgNVBAsTEVNDSFVGQSBIT0xESU5HIEFHMSIwIAYDVQQDExlJbnRlcm5ldCBC" + "ZW51dHplciBTZXJ2aWNlMSowKAYJKoZIhvcNAQkBFht6ZXJ0aWZpa2F0QHNj" + "aHVmYS1vbmxpbmUuZGWCAQAwIQYDVR0RBBowGIEWU3RlZmFuLlNjaGV0dGVy" + "QHNocy5kZTAmBgNVHRIEHzAdgRt6ZXJ0aWZpa2F0QHNjaHVmYS1vbmxpbmUu" + "ZGUwDQYJKoZIhvcNAQEEBQADgYEAWzZtN9XQ9uyrFXqSy3hViYwV751+XZr0" + "YH5IFhIS+9ixNAu8orP3bxqTaMhpwoU7T/oSsyGGSkb3fhzclgUADbA2lrOI" + "GkeB/m+FArTwRbwpqhCNTwZywOp0eDosgPjCX1t53BB/m/2EYkRiYdDGsot0" + "kQPOVGSjQSQ4+/D+TM8="); public void performTest() throws Exception { CertificateFactory cf = CertificateFactory.getInstance("X.509", "BC"); // initialise CertStore X509Certificate rootCert = (X509Certificate)cf.generateCertificate(new ByteArrayInputStream(CertPathTest.rootCertBin)); X509Certificate interCert = (X509Certificate)cf.generateCertificate(new ByteArrayInputStream(CertPathTest.interCertBin)); X509Certificate finalCert = (X509Certificate)cf.generateCertificate(new ByteArrayInputStream(CertPathTest.finalCertBin)); X509CRL rootCrl = (X509CRL)cf.generateCRL(new ByteArrayInputStream(CertPathTest.rootCrlBin)); X509CRL interCrl = (X509CRL)cf.generateCRL(new ByteArrayInputStream(CertPathTest.interCrlBin)); List list = new ArrayList(); list.add(rootCert); list.add(interCert); list.add(finalCert); list.add(rootCrl); list.add(interCrl); CollectionCertStoreParameters ccsp = new CollectionCertStoreParameters(list); CertStore store = CertStore.getInstance("Collection", ccsp); Calendar validDate = Calendar.getInstance(); validDate.set(2002,2,21,2,21,10); //validating path List certchain = new ArrayList(); certchain.add(finalCert); certchain.add(interCert); CertPath cp = CertificateFactory.getInstance("X.509","BC").generateCertPath(certchain); Set trust = new HashSet(); trust.add(new TrustAnchor(rootCert, null)); CertPathValidator cpv = CertPathValidator.getInstance("PKIX","BC"); PKIXParameters param = new PKIXParameters(trust); param.addCertStore(store); param.setDate(validDate.getTime()); PKIXCertPathValidatorResult result = (PKIXCertPathValidatorResult) cpv.validate(cp, param); PolicyNode policyTree = result.getPolicyTree(); PublicKey subjectPublicKey = result.getPublicKey(); if (!subjectPublicKey.equals(finalCert.getPublicKey())) { fail("wrong public key returned"); } // // invalid path containing a valid one test // try { // initialise CertStore rootCert = (X509Certificate)cf.generateCertificate(new ByteArrayInputStream(AC_RAIZ_ICPBRASIL)); interCert = (X509Certificate)cf.generateCertificate(new ByteArrayInputStream(AC_PR)); finalCert = (X509Certificate)cf.generateCertificate(new ByteArrayInputStream(schefer)); list = new ArrayList(); list.add(rootCert); list.add(interCert); list.add(finalCert); ccsp = new CollectionCertStoreParameters(list); store = CertStore.getInstance("Collection", ccsp); validDate = Calendar.getInstance(); validDate.set(2004,2,21,2,21,10); //validating path certchain = new ArrayList(); certchain.add(finalCert); certchain.add(interCert); cp = CertificateFactory.getInstance("X.509","BC").generateCertPath(certchain); trust = new HashSet(); trust.add(new TrustAnchor(rootCert, null)); cpv = CertPathValidator.getInstance("PKIX","BC"); param = new PKIXParameters(trust); param.addCertStore(store); param.setRevocationEnabled(false); param.setDate(validDate.getTime()); result =(PKIXCertPathValidatorResult) cpv.validate(cp, param); policyTree = result.getPolicyTree(); subjectPublicKey = result.getPublicKey(); fail("Invalid path validated"); } catch (Exception e) { if (e instanceof CertPathValidatorException && e.getMessage().startsWith("Could not validate certificate signature.")) { return; } fail("unexpected exception", e); } } public String getName() { return "CertPathValidator"; } public static void main( String[] args) { Security.addProvider(new BouncyCastleProvider()); runTest(new CertPathValidatorTest()); } } bouncycastle-1.49.orig/test/jdk1.3/org/bouncycastle/jce/provider/test/nist/0000755000175000017500000000000012152033550026207 5ustar ebourgebourgbouncycastle-1.49.orig/test/jdk1.3/org/bouncycastle/jce/provider/test/nist/NistCertPathTest.java0000644000175000017500000010115012104173672032267 0ustar ebourgebourgpackage org.bouncycastle.jce.provider.test.nist; import java.io.FileInputStream; import java.io.InputStream; import java.security.Security; import org.bouncycastle.jce.cert.CertPath; import org.bouncycastle.jce.cert.CertPathBuilder; import org.bouncycastle.jce.cert.CertPathBuilderException; import org.bouncycastle.jce.cert.CertPathValidator; import org.bouncycastle.jce.cert.CertPathValidatorException; import org.bouncycastle.jce.cert.CertStore; import org.bouncycastle.jce.cert.CertificateFactory; import org.bouncycastle.jce.cert.CollectionCertStoreParameters; import org.bouncycastle.jce.cert.PKIXBuilderParameters; import org.bouncycastle.jce.cert.PKIXCertPathBuilderResult; import org.bouncycastle.jce.cert.PKIXCertPathValidatorResult; import org.bouncycastle.jce.cert.PKIXParameters; import org.bouncycastle.jce.cert.TrustAnchor; import java.security.cert.X509CRL; import org.bouncycastle.jce.cert.X509CertSelector; import java.security.cert.X509Certificate; import java.util.ArrayList; import java.util.Arrays; import java.util.Collections; import java.util.GregorianCalendar; import java.util.HashMap; import java.util.HashSet; import java.util.List; import java.util.Map; import java.util.Set; import junit.framework.Test; import junit.framework.TestCase; import junit.framework.TestSuite; import org.bouncycastle.asn1.ASN1Encodable; import org.bouncycastle.asn1.ASN1Encoding; import org.bouncycastle.asn1.x509.X509Extension; import org.bouncycastle.x509.extension.X509ExtensionUtil; /** * NIST CertPath test data for RFC 3280 */ public class NistCertPathTest extends TestCase { private static final String TEST_DATA_HOME = "bc.test.data.home"; private static final String GOOD_CA_CERT = "GoodCACert"; private static final String GOOD_CA_CRL = "GoodCACRL"; private static final String TRUST_ANCHOR_ROOT_CRL = "TrustAnchorRootCRL"; private static final String TRUST_ANCHOR_ROOT_CERTIFICATE = "TrustAnchorRootCertificate"; private static final char[] PKCS12_PASSWORD = "password".toCharArray(); private static final String ANY_POLICY = "2.5.29.32.0"; private static final String NIST_TEST_POLICY_1 = "2.16.840.1.101.3.2.1.48.1"; private static final String NIST_TEST_POLICY_2 = "2.16.840.1.101.3.2.1.48.2"; private static final String NIST_TEST_POLICY_3 = "2.16.840.1.101.3.2.1.48.3"; private static Map certs = new HashMap(); private static Map crls = new HashMap(); private static Set noPolicies = Collections.EMPTY_SET; private static Set anyPolicy = Collections.singleton(ANY_POLICY); private static Set nistTestPolicy1 = Collections.singleton(NIST_TEST_POLICY_1); private static Set nistTestPolicy2 = Collections.singleton(NIST_TEST_POLICY_2); private static Set nistTestPolicy3 = Collections.singleton(NIST_TEST_POLICY_3); private static Set nistTestPolicy1And2 = new HashSet(Arrays.asList(new String[] { NIST_TEST_POLICY_1, NIST_TEST_POLICY_2 })); public void setUp() { if (Security.getProvider("BC") == null) { Security.addProvider(new org.bouncycastle.jce.provider.BouncyCastleProvider()); } } public void testValidSignaturesTest1() throws Exception { doTest(TRUST_ANCHOR_ROOT_CERTIFICATE, new String[] { "ValidCertificatePathTest1EE", GOOD_CA_CERT}, new String[] { GOOD_CA_CRL, TRUST_ANCHOR_ROOT_CRL }); } public void testInvalidCASignatureTest2() throws Exception { doExceptionTest(TRUST_ANCHOR_ROOT_CERTIFICATE, new String[] { "ValidCertificatePathTest1EE", "BadSignedCACert" }, new String[] { "BadSignedCACRL", TRUST_ANCHOR_ROOT_CRL}, 1, "TrustAnchor found but certificate validation failed."); } public void testInvalidEESignatureTest3() throws Exception { doExceptionTest(TRUST_ANCHOR_ROOT_CERTIFICATE, new String[] { GOOD_CA_CERT, "InvalidEESignatureTest3EE" }, new String[] { TRUST_ANCHOR_ROOT_CRL, GOOD_CA_CRL }, 0, "Could not validate certificate signature."); } public void testValidDSASignaturesTest4() throws Exception { doTest(TRUST_ANCHOR_ROOT_CERTIFICATE, new String[] { "DSACACert", "ValidDSASignaturesTest4EE" }, new String[] { TRUST_ANCHOR_ROOT_CRL, "DSACACRL" }); } // 4.1.5 public void testValidDSAParameterInheritanceTest5() throws Exception { doTest(TRUST_ANCHOR_ROOT_CERTIFICATE, new String[] { "DSACACert", "DSAParametersInheritedCACert", "ValidDSAParameterInheritanceTest5EE" }, new String[] { TRUST_ANCHOR_ROOT_CRL, "DSACACRL", "DSAParametersInheritedCACRL" }); } public void testInvalidDSASignaturesTest6() throws Exception { doExceptionTest(TRUST_ANCHOR_ROOT_CERTIFICATE, new String[] { "DSACACert", "InvalidDSASignatureTest6EE" }, new String[] { TRUST_ANCHOR_ROOT_CRL, "DSACACRL" }, 0, "Could not validate certificate signature."); } public void testCANotBeforeDateTest1() throws Exception { doExceptionTest(TRUST_ANCHOR_ROOT_CERTIFICATE, new String[] { "BadnotBeforeDateCACert", "InvalidCAnotBeforeDateTest1EE" }, new String[] { TRUST_ANCHOR_ROOT_CRL, "BadnotBeforeDateCACRL" }, 1, "Could not validate certificate: certificate not valid till 20470101120100GMT+00:00"); } public void testInvalidEENotBeforeDateTest2() throws Exception { doExceptionTest(TRUST_ANCHOR_ROOT_CERTIFICATE, new String[] { GOOD_CA_CERT, "InvalidEEnotBeforeDateTest2EE" }, new String[] { TRUST_ANCHOR_ROOT_CRL, GOOD_CA_CRL }, 0, "Could not validate certificate: certificate not valid till 20470101120100GMT+00:00"); } public void testValidPre2000UTCNotBeforeDateTest3() throws Exception { doTest(TRUST_ANCHOR_ROOT_CERTIFICATE, new String[] { GOOD_CA_CERT, "Validpre2000UTCnotBeforeDateTest3EE" }, new String[] { TRUST_ANCHOR_ROOT_CRL, GOOD_CA_CRL }); } public void testValidGeneralizedTimeNotBeforeDateTest4() throws Exception { doTest(TRUST_ANCHOR_ROOT_CERTIFICATE, new String[] { GOOD_CA_CERT, "ValidGeneralizedTimenotBeforeDateTest4EE" }, new String[] { TRUST_ANCHOR_ROOT_CRL, GOOD_CA_CRL }); } public void testInvalidCANotAfterDateTest5() throws Exception { doExceptionTest(TRUST_ANCHOR_ROOT_CERTIFICATE, new String[] { "BadnotAfterDateCACert", "InvalidCAnotAfterDateTest5EE" }, new String[] { TRUST_ANCHOR_ROOT_CRL, "BadnotAfterDateCACRL" }, 1, "Could not validate certificate: certificate expired on 20020101120100GMT+00:00"); } public void testInvalidEENotAfterDateTest6() throws Exception { doExceptionTest(TRUST_ANCHOR_ROOT_CERTIFICATE, new String[] { GOOD_CA_CERT, "InvalidEEnotAfterDateTest6EE" }, new String[] { TRUST_ANCHOR_ROOT_CRL, GOOD_CA_CRL }, 0, "Could not validate certificate: certificate expired on 20020101120100GMT+00:00"); } public void testInvalidValidPre2000UTCNotAfterDateTest7() throws Exception { doExceptionTest(TRUST_ANCHOR_ROOT_CERTIFICATE, new String[] { GOOD_CA_CERT, "Invalidpre2000UTCEEnotAfterDateTest7EE" }, new String[] { TRUST_ANCHOR_ROOT_CRL, GOOD_CA_CRL }, 0, "Could not validate certificate: certificate expired on 19990101120100GMT+00:00"); } public void testInvalidNegativeSerialNumberTest15() throws Exception { doExceptionTest(TRUST_ANCHOR_ROOT_CERTIFICATE, new String[] { "NegativeSerialNumberCACert", "InvalidNegativeSerialNumberTest15EE" }, new String[] { TRUST_ANCHOR_ROOT_CRL, "NegativeSerialNumberCACRL" }, 0, "Certificate revocation after Fri Apr 20 00:57:20", "reason: keyCompromise"); } // // 4.8 Certificate Policies // public void testAllCertificatesSamePolicyTest1() throws Exception { String[] certList = new String[] { GOOD_CA_CERT, "ValidCertificatePathTest1EE" }; String[] crlList = new String[] { TRUST_ANCHOR_ROOT_CRL, GOOD_CA_CRL }; doTest(TRUST_ANCHOR_ROOT_CERTIFICATE, certList, crlList, noPolicies); doTest(TRUST_ANCHOR_ROOT_CERTIFICATE, certList, crlList, nistTestPolicy1); doExceptionTest(TRUST_ANCHOR_ROOT_CERTIFICATE, certList, crlList, nistTestPolicy2, -1, "Path processing failed on policy."); doTest(TRUST_ANCHOR_ROOT_CERTIFICATE, certList, crlList, nistTestPolicy1And2); } public void testAllCertificatesNoPoliciesTest2() throws Exception { doTest(TRUST_ANCHOR_ROOT_CERTIFICATE, new String[] { "NoPoliciesCACert", "AllCertificatesNoPoliciesTest2EE" }, new String[] { TRUST_ANCHOR_ROOT_CRL, "NoPoliciesCACRL" }); doExceptionTest(TRUST_ANCHOR_ROOT_CERTIFICATE, new String[] { "NoPoliciesCACert", "AllCertificatesNoPoliciesTest2EE" }, new String[] { TRUST_ANCHOR_ROOT_CRL, "NoPoliciesCACRL" }, noPolicies, 1, "No valid policy tree found when one expected."); } public void testDifferentPoliciesTest3() throws Exception { doTest(TRUST_ANCHOR_ROOT_CERTIFICATE, new String[] { GOOD_CA_CERT, "PoliciesP2subCACert", "DifferentPoliciesTest3EE" }, new String[] { TRUST_ANCHOR_ROOT_CRL, GOOD_CA_CRL, "PoliciesP2subCACRL" }); doExceptionTest(TRUST_ANCHOR_ROOT_CERTIFICATE, new String[] { GOOD_CA_CERT, "PoliciesP2subCACert", "DifferentPoliciesTest3EE" }, new String[] { TRUST_ANCHOR_ROOT_CRL, GOOD_CA_CRL, "PoliciesP2subCACRL" }, noPolicies, 1, "No valid policy tree found when one expected."); doExceptionTest(TRUST_ANCHOR_ROOT_CERTIFICATE, new String[] { GOOD_CA_CERT, "PoliciesP2subCACert", "DifferentPoliciesTest3EE" }, new String[] { TRUST_ANCHOR_ROOT_CRL, GOOD_CA_CRL, "PoliciesP2subCACRL" }, nistTestPolicy1And2, 1, "No valid policy tree found when one expected."); } public void testDifferentPoliciesTest4() throws Exception { doExceptionTest(TRUST_ANCHOR_ROOT_CERTIFICATE, new String[] { GOOD_CA_CERT, "GoodsubCACert", "DifferentPoliciesTest4EE" }, new String[] { TRUST_ANCHOR_ROOT_CRL, GOOD_CA_CRL, "GoodsubCACRL" }, 0, "No valid policy tree found when one expected."); } public void testDifferentPoliciesTest5() throws Exception { doExceptionTest(TRUST_ANCHOR_ROOT_CERTIFICATE, new String[] { GOOD_CA_CERT, "PoliciesP2subCA2Cert", "DifferentPoliciesTest5EE" }, new String[] { TRUST_ANCHOR_ROOT_CRL, GOOD_CA_CRL, "PoliciesP2subCA2CRL" }, 0, "No valid policy tree found when one expected."); } public void testOverlappingPoliciesTest6() throws Exception { String[] certList = new String[] { "PoliciesP1234CACert", "PoliciesP1234subCAP123Cert", "PoliciesP1234subsubCAP123P12Cert", "OverlappingPoliciesTest6EE" }; String[] crlList = new String[] { TRUST_ANCHOR_ROOT_CRL, "PoliciesP1234CACRL", "PoliciesP1234subCAP123CRL", "PoliciesP1234subsubCAP123P12CRL" }; doTest(TRUST_ANCHOR_ROOT_CERTIFICATE, certList, crlList); doTest(TRUST_ANCHOR_ROOT_CERTIFICATE, certList, crlList, nistTestPolicy1); doExceptionTest(TRUST_ANCHOR_ROOT_CERTIFICATE, certList, crlList, nistTestPolicy2, -1, "Path processing failed on policy."); } public void testDifferentPoliciesTest7() throws Exception { String[] certList = new String[] { "PoliciesP123CACert", "PoliciesP123subCAP12Cert", "PoliciesP123subsubCAP12P1Cert", "DifferentPoliciesTest7EE" }; String[] crlList = new String[] { TRUST_ANCHOR_ROOT_CRL, "PoliciesP123CACRL", "PoliciesP123subCAP12CRL", "PoliciesP123subsubCAP12P1CRL" }; doExceptionTest(TRUST_ANCHOR_ROOT_CERTIFICATE, certList, crlList, 0, "No valid policy tree found when one expected."); } public void testDifferentPoliciesTest8() throws Exception { String[] certList = new String[] { "PoliciesP12CACert", "PoliciesP12subCAP1Cert", "PoliciesP12subsubCAP1P2Cert", "DifferentPoliciesTest8EE" }; String[] crlList = new String[] { TRUST_ANCHOR_ROOT_CRL, "PoliciesP12CACRL", "PoliciesP12subCAP1CRL", "PoliciesP12subsubCAP1P2CRL" }; doExceptionTest(TRUST_ANCHOR_ROOT_CERTIFICATE, certList, crlList, 1, "No valid policy tree found when one expected."); } public void testDifferentPoliciesTest9() throws Exception { String[] certList = new String[] { "PoliciesP123CACert", "PoliciesP123subCAP12Cert", "PoliciesP123subsubCAP12P2Cert", "PoliciesP123subsubsubCAP12P2P1Cert", "DifferentPoliciesTest9EE" }; String[] crlList = new String[] { TRUST_ANCHOR_ROOT_CRL, "PoliciesP123CACRL", "PoliciesP123subCAP12CRL", "PoliciesP123subsubCAP2P2CRL", "PoliciesP123subsubsubCAP12P2P1CRL" }; doExceptionTest(TRUST_ANCHOR_ROOT_CERTIFICATE, certList, crlList, 1, "No valid policy tree found when one expected."); } public void testAllCertificatesSamePoliciesTest10() throws Exception { String[] certList = new String[] { "PoliciesP12CACert", "AllCertificatesSamePoliciesTest10EE" }; String[] crlList = new String[] { TRUST_ANCHOR_ROOT_CRL, "PoliciesP12CACRL" }; doTest(TRUST_ANCHOR_ROOT_CERTIFICATE, certList, crlList); doTest(TRUST_ANCHOR_ROOT_CERTIFICATE, certList, crlList, nistTestPolicy1); doTest(TRUST_ANCHOR_ROOT_CERTIFICATE, certList, crlList, nistTestPolicy2); } public void testAllCertificatesAnyPolicyTest11() throws Exception { String[] certList = new String[] { "anyPolicyCACert", "AllCertificatesanyPolicyTest11EE" }; String[] crlList = new String[] { TRUST_ANCHOR_ROOT_CRL, "anyPolicyCACRL" }; PKIXCertPathValidatorResult result = doTest(TRUST_ANCHOR_ROOT_CERTIFICATE, certList, crlList); result = doTest(TRUST_ANCHOR_ROOT_CERTIFICATE, certList, crlList, nistTestPolicy1); } public void testDifferentPoliciesTest12() throws Exception { String[] certList = new String[] { "PoliciesP3CACert", "DifferentPoliciesTest12EE" }; String[] crlList = new String[] { TRUST_ANCHOR_ROOT_CRL, "PoliciesP3CACRL" }; doExceptionTest(TRUST_ANCHOR_ROOT_CERTIFICATE, certList, crlList, 0, "No valid policy tree found when one expected."); } public void testAllCertificatesSamePoliciesTest13() throws Exception { String[] certList = new String[] { "PoliciesP123CACert", "AllCertificatesSamePoliciesTest13EE" }; String[] crlList = new String[] { TRUST_ANCHOR_ROOT_CRL, "PoliciesP123CACRL" }; doTest(TRUST_ANCHOR_ROOT_CERTIFICATE, certList, crlList, nistTestPolicy1); doTest(TRUST_ANCHOR_ROOT_CERTIFICATE, certList, crlList, nistTestPolicy2); doTest(TRUST_ANCHOR_ROOT_CERTIFICATE, certList, crlList, nistTestPolicy3); } public void testAnyPolicyTest14() throws Exception { String[] certList = new String[] { "anyPolicyCACert", "AnyPolicyTest14EE" }; String[] crlList = new String[] { TRUST_ANCHOR_ROOT_CRL, "anyPolicyCACRL" }; doTest(TRUST_ANCHOR_ROOT_CERTIFICATE, certList, crlList, nistTestPolicy1); doExceptionTest(TRUST_ANCHOR_ROOT_CERTIFICATE, certList, crlList, nistTestPolicy2, -1, "Path processing failed on policy."); } public void testUserNoticeQualifierTest15() throws Exception { String[] certList = new String[] { "UserNoticeQualifierTest15EE" }; String[] crlList = new String[] { TRUST_ANCHOR_ROOT_CRL }; doTest(TRUST_ANCHOR_ROOT_CERTIFICATE, certList, crlList); doTest(TRUST_ANCHOR_ROOT_CERTIFICATE, certList, crlList, nistTestPolicy1); doExceptionTest(TRUST_ANCHOR_ROOT_CERTIFICATE, certList, crlList, nistTestPolicy2, -1, "Path processing failed on policy."); } public void testUserNoticeQualifierTest16() throws Exception { String[] certList = new String[] { GOOD_CA_CERT, "UserNoticeQualifierTest16EE" }; String[] crlList = new String[] { TRUST_ANCHOR_ROOT_CRL, GOOD_CA_CRL }; PKIXCertPathValidatorResult result = doTest(TRUST_ANCHOR_ROOT_CERTIFICATE, certList, crlList); result = doTest(TRUST_ANCHOR_ROOT_CERTIFICATE, certList, crlList, nistTestPolicy1); doExceptionTest(TRUST_ANCHOR_ROOT_CERTIFICATE, certList, crlList, nistTestPolicy2, -1, "Path processing failed on policy."); } public void testUserNoticeQualifierTest17() throws Exception { String[] certList = new String[] { GOOD_CA_CERT, "UserNoticeQualifierTest17EE" }; String[] crlList = new String[] { TRUST_ANCHOR_ROOT_CRL, GOOD_CA_CRL }; doTest(TRUST_ANCHOR_ROOT_CERTIFICATE, certList, crlList); doTest(TRUST_ANCHOR_ROOT_CERTIFICATE, certList, crlList, nistTestPolicy1); doExceptionTest(TRUST_ANCHOR_ROOT_CERTIFICATE, certList, crlList, nistTestPolicy2, -1, "Path processing failed on policy."); } public void testUserNoticeQualifierTest18() throws Exception { String[] certList = new String[] { "PoliciesP12CACert", "UserNoticeQualifierTest18EE" }; String[] crlList = new String[] { TRUST_ANCHOR_ROOT_CRL, "PoliciesP12CACRL" }; doTest(TRUST_ANCHOR_ROOT_CERTIFICATE, certList, crlList, nistTestPolicy1); doTest(TRUST_ANCHOR_ROOT_CERTIFICATE, certList, crlList, nistTestPolicy2); } public void testUserNoticeQualifierTest19() throws Exception { String[] certList = new String[] { "UserNoticeQualifierTest19EE" }; String[] crlList = new String[] { TRUST_ANCHOR_ROOT_CRL }; doTest(TRUST_ANCHOR_ROOT_CERTIFICATE, certList, crlList, nistTestPolicy1); doExceptionTest(TRUST_ANCHOR_ROOT_CERTIFICATE, certList, crlList, nistTestPolicy2, -1, "Path processing failed on policy."); } public void testInvalidInhibitPolicyMappingTest1() throws Exception { String[] certList = new String[] { "inhibitPolicyMapping0CACert", "inhibitPolicyMapping0subCACert", "InvalidinhibitPolicyMappingTest1EE" }; String[] crlList = new String[] { TRUST_ANCHOR_ROOT_CRL, "inhibitPolicyMapping0CACRL", "inhibitPolicyMapping0subCACRL" }; doExceptionTest(TRUST_ANCHOR_ROOT_CERTIFICATE, certList, crlList, null, 0, "No valid policy tree found when one expected."); } public void testValidinhibitPolicyMappingTest2() throws Exception { String[] certList = new String[] { "inhibitPolicyMapping1P12CACert", "inhibitPolicyMapping1P12subCACert", "ValidinhibitPolicyMappingTest2EE" }; String[] crlList = new String[] { TRUST_ANCHOR_ROOT_CRL, "inhibitPolicyMapping1P12CACRL", "inhibitPolicyMapping1P12subCACRL" }; doTest(TRUST_ANCHOR_ROOT_CERTIFICATE, certList, crlList, nistTestPolicy1); } // 4.12.7 public void testValidSelfIssuedinhibitAnyPolicyTest7() throws Exception { String[] certList = new String[] { "inhibitAnyPolicy1CACert", "inhibitAnyPolicy1SelfIssuedCACert", "inhibitAnyPolicy1subCA2Cert", "ValidSelfIssuedinhibitAnyPolicyTest7EE" }; String[] crlList = new String[] { TRUST_ANCHOR_ROOT_CRL, "inhibitAnyPolicy1CACRL", "inhibitAnyPolicy1subCA2CRL" }; doBuilderTest(TRUST_ANCHOR_ROOT_CERTIFICATE, certList, crlList, null, false, false); } // 4.4.19 public void testValidSeparateCertificateandCRLKeysTest19() throws Exception { String[] certList = new String[] { "SeparateCertificateandCRLKeysCertificateSigningCACert", "SeparateCertificateandCRLKeysCRLSigningCert", "ValidSeparateCertificateandCRLKeysTest19EE" }; String[] crlList = new String[] { TRUST_ANCHOR_ROOT_CRL, "SeparateCertificateandCRLKeysCRL" }; doBuilderTest(TRUST_ANCHOR_ROOT_CERTIFICATE, certList, crlList, null, false, false); } public void testValidpathLenConstraintTest13() throws Exception { String[] certList = new String[] { "pathLenConstraint6CACert", "pathLenConstraint6subCA4Cert", "pathLenConstraint6subsubCA41Cert", "pathLenConstraint6subsubsubCA41XCert", "ValidpathLenConstraintTest13EE" }; String[] crlList = new String[] { TRUST_ANCHOR_ROOT_CRL, "pathLenConstraint6CACRL", "pathLenConstraint6subCA4CRL", "pathLenConstraint6subsubCA41CRL", "pathLenConstraint6subsubsubCA41XCRL" }; doTest(TRUST_ANCHOR_ROOT_CERTIFICATE, certList, crlList, null); } // 4.4.10 public void testInvalidUnknownCRLExtensionTest10() throws Exception { String[] certList = new String[] { "UnknownCRLExtensionCACert", "InvalidUnknownCRLExtensionTest10EE" }; String[] crlList = new String[] { TRUST_ANCHOR_ROOT_CRL, "UnknownCRLExtensionCACRL" }; doExceptionTest(TRUST_ANCHOR_ROOT_CERTIFICATE, certList, crlList, null, 0, "CRL contains unsupported critical extensions."); } // 4.14.3 public void testInvaliddistributionPointTest3() throws Exception { String[] certList = new String[] { "distributionPoint1CACert", "InvaliddistributionPointTest3EE" }; String[] crlList = new String[] { TRUST_ANCHOR_ROOT_CRL, "distributionPoint1CACRL" }; doExceptionTest(TRUST_ANCHOR_ROOT_CERTIFICATE, certList, crlList, null, 0, "No match for certificate CRL issuing distribution point name to cRLIssuer CRL distribution point."); } // 4.14.5 public void testValiddistributionPointTest5() throws Exception { String[] certList = new String[] { "distributionPoint2CACert", "ValiddistributionPointTest5EE" }; String[] crlList = new String[] { TRUST_ANCHOR_ROOT_CRL, "distributionPoint2CACRL" }; doTest(TRUST_ANCHOR_ROOT_CERTIFICATE, certList, crlList, null); } // 4.14.8 public void testInvaliddistributionPointTest8() throws Exception { String[] certList = new String[] { "distributionPoint2CACert", "InvaliddistributionPointTest8EE" }; String[] crlList = new String[] { TRUST_ANCHOR_ROOT_CRL, "distributionPoint2CACRL" }; doExceptionTest(TRUST_ANCHOR_ROOT_CERTIFICATE, certList, crlList, null, 0, "No match for certificate CRL issuing distribution point name to cRLIssuer CRL distribution point."); } // 4.14.9 public void testInvaliddistributionPointTest9() throws Exception { String[] certList = new String[] { "distributionPoint2CACert", "InvaliddistributionPointTest9EE" }; String[] crlList = new String[] { TRUST_ANCHOR_ROOT_CRL, "distributionPoint2CACRL" }; doExceptionTest(TRUST_ANCHOR_ROOT_CERTIFICATE, certList, crlList, null, 0, "No match for certificate CRL issuing distribution point name to cRLIssuer CRL distribution point."); } // 4.14.17 public void testInvalidonlySomeReasonsTest17() throws Exception { String[] certList = new String[] { "onlySomeReasonsCA2Cert", "InvalidonlySomeReasonsTest17EE" }; String[] crlList = new String[] { TRUST_ANCHOR_ROOT_CRL, "onlySomeReasonsCA2CRL1", "onlySomeReasonsCA2CRL2" }; doExceptionTest(TRUST_ANCHOR_ROOT_CERTIFICATE, certList, crlList, null, 0, "Certificate status could not be determined."); } // section 4.14: tests 17, 24, 25, 30, 31, 32, 33, 35 // section 4.15: tests 5, 7 private void doExceptionTest( String trustAnchor, String[] certs, String[] crls, int index, String message) throws Exception { try { doTest(trustAnchor, certs, crls); fail("path accepted when should be rejected"); } catch (CertPathValidatorException e) { assertEquals(index, e.getIndex()); assertEquals(message, e.getMessage()); } } private void doExceptionTest( String trustAnchor, String[] certs, String[] crls, Set policies, int index, String message) throws Exception { try { doTest(trustAnchor, certs, crls, policies); fail("path accepted when should be rejected"); } catch (CertPathValidatorException e) { assertEquals(index, e.getIndex()); assertEquals(message, e.getMessage()); } } private void doExceptionTest( String trustAnchor, String[] certs, String[] crls, int index, String mesStart, String mesEnd) throws Exception { try { doTest(trustAnchor, certs, crls); fail("path accepted when should be rejected"); } catch (CertPathValidatorException e) { assertEquals(index, e.getIndex()); assertTrue(e.getMessage().startsWith(mesStart)); assertTrue(e.getMessage().endsWith(mesEnd)); } } private PKIXCertPathValidatorResult doTest( String trustAnchor, String[] certs, String[] crls) throws Exception { return doTest(trustAnchor, certs, crls, null); } private PKIXCertPathValidatorResult doTest( String trustAnchor, String[] certs, String[] crls, Set policies) throws Exception { Set trustedSet = Collections.singleton(getTrustAnchor(trustAnchor)); List certsAndCrls = new ArrayList(); X509Certificate endCert = loadCert(certs[certs.length - 1]); for (int i = 0; i != certs.length - 1; i++) { certsAndCrls.add(loadCert(certs[i])); } certsAndCrls.add(endCert); CertPath certPath = CertificateFactory.getInstance("X.509","BC").generateCertPath(certsAndCrls); for (int i = 0; i != crls.length; i++) { certsAndCrls.add(loadCrl(crls[i])); } CertStore store = CertStore.getInstance("Collection", new CollectionCertStoreParameters(certsAndCrls), "BC"); CertPathValidator validator = CertPathValidator.getInstance("PKIX","BC"); PKIXParameters params = new PKIXParameters(trustedSet); params.addCertStore(store); params.setRevocationEnabled(true); params.setDate(new GregorianCalendar(2010, 1, 1).getTime()); if (policies != null) { params.setExplicitPolicyRequired(true); params.setInitialPolicies(policies); } return (PKIXCertPathValidatorResult)validator.validate(certPath, params); } private PKIXCertPathBuilderResult doBuilderTest( String trustAnchor, String[] certs, String[] crls, Set initialPolicies, boolean policyMappingInhibited, boolean anyPolicyInhibited) throws Exception { Set trustedSet = Collections.singleton(getTrustAnchor(trustAnchor)); List certsAndCrls = new ArrayList(); X509Certificate endCert = loadCert(certs[certs.length - 1]); for (int i = 0; i != certs.length - 1; i++) { certsAndCrls.add(loadCert(certs[i])); } certsAndCrls.add(endCert); for (int i = 0; i != crls.length; i++) { certsAndCrls.add(loadCrl(crls[i])); } CertStore store = CertStore.getInstance("Collection", new CollectionCertStoreParameters(certsAndCrls), "BC"); CertPathBuilder builder = CertPathBuilder.getInstance("PKIX", "BC"); X509CertSelector endSelector = new X509CertSelector(); endSelector.setCertificate(endCert); PKIXBuilderParameters builderParams = new PKIXBuilderParameters(trustedSet, endSelector); if (initialPolicies != null) { builderParams.setInitialPolicies(initialPolicies); builderParams.setExplicitPolicyRequired(true); } if (policyMappingInhibited) { builderParams.setPolicyMappingInhibited(policyMappingInhibited); } if (anyPolicyInhibited) { builderParams.setAnyPolicyInhibited(anyPolicyInhibited); } builderParams.addCertStore(store); builderParams.setDate(new GregorianCalendar(2010, 1, 1).getTime()); try { return (PKIXCertPathBuilderResult)builder.build(builderParams); } catch (CertPathBuilderException e) { throw (Exception)e.getCause(); } } private X509Certificate loadCert( String certName) { X509Certificate cert = (X509Certificate)certs.get(certName); if (cert != null) { return cert; } try { InputStream in = new FileInputStream(getPkitsHome() + "/certs/" + certName + ".crt"); CertificateFactory fact = CertificateFactory.getInstance("X.509", "BC"); cert = (X509Certificate)fact.generateCertificate(in); certs.put(certName, cert); return cert; } catch (Exception e) { throw new IllegalStateException("exception loading certificate " + certName + ": " + e); } } private X509CRL loadCrl( String crlName) throws Exception { X509CRL crl = (X509CRL)certs.get(crlName); if (crl != null) { return crl; } try { InputStream in = new FileInputStream(getPkitsHome() + "/crls/" + crlName + ".crl"); CertificateFactory fact = CertificateFactory.getInstance("X.509", "BC"); crl = (X509CRL)fact.generateCRL(in); crls.put(crlName, crl); return crl; } catch (Exception e) { throw new IllegalStateException("exception loading CRL: " + crlName); } } private TrustAnchor getTrustAnchor(String trustAnchorName) throws Exception { X509Certificate cert = loadCert(trustAnchorName); byte[] extBytes = cert.getExtensionValue(X509Extension.nameConstraints.getId()); if (extBytes != null) { ASN1Encodable extValue = X509ExtensionUtil.fromExtensionValue(extBytes); return new TrustAnchor(cert, extValue.toASN1Primitive().getEncoded(ASN1Encoding.DER)); } return new TrustAnchor(cert, null); } private String getPkitsHome() { String dataHome = System.getProperty(TEST_DATA_HOME); if (dataHome == null) { throw new IllegalStateException(TEST_DATA_HOME + " property not set"); } return dataHome + "/PKITS"; } public static void main (String[] args) throws Exception { junit.textui.TestRunner.run(suite()); } public static Test suite() throws Exception { TestSuite suite = new TestSuite("NIST CertPath Tests"); suite.addTestSuite(NistCertPathTest.class); return suite; } } bouncycastle-1.49.orig/test/jdk1.3/org/bouncycastle/jce/provider/test/NISTCertPathTest.java0000644000175000017500000122475111251332523031162 0ustar ebourgebourgpackage org.bouncycastle.jce.provider.test; import java.io.ByteArrayInputStream; import java.security.GeneralSecurityException; import java.security.Security; import java.security.cert.*; import org.bouncycastle.jce.PrincipalUtil; import org.bouncycastle.jce.cert.CollectionCertStoreParameters; import org.bouncycastle.jce.cert.TrustAnchor; import org.bouncycastle.jce.cert.CertStore; import org.bouncycastle.jce.cert.PKIXBuilderParameters; import org.bouncycastle.jce.cert.X509CertSelector; import org.bouncycastle.jce.cert.CertPathBuilder; import org.bouncycastle.jce.cert.CertPathBuilderResult; import java.util.HashSet; import java.util.Set; import java.util.Vector; import org.bouncycastle.asn1.ASN1InputStream; import org.bouncycastle.asn1.ASN1OctetString; import org.bouncycastle.jce.provider.BouncyCastleProvider; import org.bouncycastle.util.encoders.Base64; import org.bouncycastle.util.test.SimpleTest; /* * These tests are taken from the NIST X.509 Validation Test Suite * available at: http://csrc.nist.gov/pki/testing/x509paths.html * * Only the relevant certificate and crl data has been kept, in order * to keep the class size to a minimum. * */ public class NISTCertPathTest extends SimpleTest { private static final String TEST_POLICY_1 = "2.16.840.1.101.3.1.48.1"; private static final String TEST_POLICY_2 = "2.16.840.1.101.3.1.48.2"; private static final String TEST_POLICY_3 = "2.16.840.1.101.3.1.48.3"; private static final String TEST_POLICY_4 = "2.16.840.1.101.3.1.48.4"; private static final String TEST_POLICY_5 = "2.16.840.1.101.3.1.48.5"; private static Set ANY; private static Set TP1; private static Set TP2; private static Set TP3; private static Set TP4; private static Set TP1_TP2; static { ANY = new HashSet(); TP1 = new HashSet(); TP1.add(TEST_POLICY_1); TP2 = new HashSet(); TP2.add(TEST_POLICY_2); TP3 = new HashSet(); TP3.add(TEST_POLICY_3); TP4 = new HashSet(); TP4.add(TEST_POLICY_4); TP1_TP2 = new HashSet(); TP1_TP2.add(TEST_POLICY_1); TP1_TP2.add(TEST_POLICY_2); } /* * * FIELDS * */ private CertificateFactory fact; private X509Certificate trustedCert; private X509CRL trustedCRL; private Set trustedSet; private int testCount; private Vector testFail; private StringBuffer resultBuf; public String getName() { return "NISTCertPathTest"; } public void performTest() { init(); test(" 1", TEST_1_DATA , true , false); test(" 2", TEST_2_DATA , false, false); test(" 3", TEST_3_DATA , false, false); test(" 4", TEST_4_DATA , true , false); test(" 5", TEST_5_DATA , false, false); test(" 6", TEST_6_DATA , false, false); test(" 7", TEST_7_DATA , true , false); test(" 8", TEST_8_DATA , false, false); test(" 9", TEST_9_DATA , false, false); test("10", TEST_10_DATA, false, false); test("11", TEST_11_DATA, false, false); test("12", TEST_12_DATA, true , false); test("13", TEST_13_DATA, false, false); test("14", TEST_14_DATA, false, false); test("15", TEST_15_DATA, true , false); test("16", TEST_16_DATA, true , false); test("17", TEST_17_DATA, true , false); test("18", TEST_18_DATA, true , false); test("19", TEST_19_DATA, false, false); test("20", TEST_20_DATA, false, false); test("21", TEST_21_DATA, false, false); test("22", TEST_22_DATA, false, false); test("23", TEST_23_DATA, false, false); test("24", TEST_24_DATA, true , false); test("25", TEST_25_DATA, false, false); test("26", TEST_26_DATA, true , false); test("27", TEST_27_DATA, true , false); test("28", TEST_28_DATA, false, false); test("29", TEST_29_DATA, false, false); test("30", TEST_30_DATA, true , false); test("31", TEST_31_DATA, false, false); test("32", TEST_32_DATA, false, false); test("33", TEST_33_DATA, true , false); test("34a", TEST_34_DATA, ANY , true , true , false); test("34b", TEST_34_DATA, ANY , false, true , false); test("34c", TEST_34_DATA, TP1 , true , true , false); test("34d", TEST_34_DATA, TP1 , false, true , false); test("34e", TEST_34_DATA, TP2 , true , false, false); test("34f", TEST_34_DATA, TP2 , false, true , false); test("35a", TEST_35_DATA, false, true , false); test("35b", TEST_35_DATA, true , false, false); test("36a", TEST_36_DATA, false, true , false); test("36b", TEST_36_DATA, true , false, false); test("37a", TEST_37_DATA, false, true , false); test("37b", TEST_37_DATA, true , false, false); test("38a", TEST_38_DATA, false, true , false); test("38b", TEST_38_DATA, true , false, false); test("39a", TEST_39_DATA, ANY , true , true , false); test("39b", TEST_39_DATA, ANY , false, true , false); test("39c", TEST_39_DATA, TP1 , true , true , false); test("39d", TEST_39_DATA, TP1 , false, true , false); test("39e", TEST_39_DATA, TP2 , true , false, false); test("39f", TEST_39_DATA, TP2 , false, true , false); test("40a", TEST_40_DATA, false, true , false); test("40b", TEST_40_DATA, true , false, false); test("41a", TEST_41_DATA, false, true , false); test("41b", TEST_41_DATA, true , false, false); test("42a", TEST_42_DATA, false, true , false); test("42b", TEST_42_DATA, true , false, false); test("43a", TEST_43_DATA, false, true , false); test("43b", TEST_43_DATA, true , false, false); test("44a", TEST_44_DATA, false, true , false); test("44b", TEST_44_DATA, true , false, false); test("45a", TEST_45_DATA, false, false, false); test("45b", TEST_45_DATA, true , false, false); test("46a", TEST_46_DATA, ANY , false, true , false); test("46b", TEST_46_DATA, ANY , true , true , false); test("46c", TEST_46_DATA, TP1 , true , true , false); test("46d", TEST_46_DATA, TP1 , false, true , false); test("46e", TEST_46_DATA, TP2 , true , false, false); test("46f", TEST_46_DATA, TP2 , false, false, false); test("47a", TEST_47_DATA, false, false, false); test("47b", TEST_47_DATA, true , false, false); test("48a", TEST_48_DATA, TP1 , false, true , false); test("48b", TEST_48_DATA, TP1 , true , true , false); test("48c", TEST_48_DATA, ANY , false, true , false); test("48d", TEST_48_DATA, ANY , true , true , false); test("48e", TEST_48_DATA, TP2 , false, true , false); test("48f", TEST_48_DATA, TP2 , true , false, false); test("49a", TEST_49_DATA, TP1 , false, true , false); test("49b", TEST_49_DATA, TP1 , true , true , false); test("49c", TEST_49_DATA, TP3 , false, true , false); test("49d", TEST_49_DATA, TP3 , true , false, false); test("49e", TEST_49_DATA, ANY , false, true , false); test("49f", TEST_49_DATA, ANY , true , true , false); test("50a", TEST_50_DATA, TP1 , false, true , false); test("50b", TEST_50_DATA, TP1 , true , true , false); test("50c", TEST_50_DATA, TP1_TP2 , false, true , false); test("50d", TEST_50_DATA, TP1_TP2 , true , true , false); test("50e", TEST_50_DATA, ANY , false, true , false); test("50f", TEST_50_DATA, ANY , true , true , false); test("51a", TEST_51_DATA, false, true , false); test("51b", TEST_51_DATA, true , false, false); test("52a", TEST_52_DATA, TP1 , false, true , false); test("52b", TEST_52_DATA, TP1 , true , false, false); test("52c", TEST_52_DATA, TP1_TP2 , false, true , false); test("52d", TEST_52_DATA, TP1_TP2 , true , false, false); test("52e", TEST_52_DATA, ANY , false, true , false); test("52f", TEST_52_DATA, ANY , true , true , false); test("53a", TEST_53_DATA, TP1 , false, true , false); test("53b", TEST_53_DATA, TP1 , true , true , false); test("53c", TEST_53_DATA, TP1_TP2 , false, true , false); test("53d", TEST_53_DATA, TP1_TP2 , true , true , false); test("53e", TEST_53_DATA, TP4 , false, true , false); test("53f", TEST_53_DATA, TP4 , true , false, false); test("53g", TEST_53_DATA, ANY , false, true , false); test("53h", TEST_53_DATA, ANY , true , true , false); test("54", TEST_54_DATA, false, false); test("55", TEST_55_DATA, false, false); test("56", TEST_56_DATA, true , false); test("57", TEST_57_DATA, true , false); test("58", TEST_58_DATA, false, false); test("59", TEST_59_DATA, false, false); test("60", TEST_60_DATA, false, false); test("61", TEST_61_DATA, false, false); test("62", TEST_62_DATA, true , false); test("63", TEST_63_DATA, true , false); test("64", TEST_64_DATA, false, false); test("65", TEST_65_DATA, false, false); test("66", TEST_66_DATA, false, false); test("67", TEST_67_DATA, true , false); test("68", TEST_68_DATA, false, false); test("69", TEST_69_DATA, false, false); test("70", TEST_70_DATA, false, false); test("71", TEST_71_DATA, false, false); test("72", TEST_72_DATA, false, false); test("73", TEST_73_DATA, false, false); test("74", TEST_74_DATA, true , false); test("75", TEST_75_DATA, false, false); test("76", TEST_76_DATA, false, false); resultBuf.append("NISTCertPathTest -- Failed: ").append(testFail.size()).append('/').append(testCount).append('\n'); if (!testFail.isEmpty()) { fail(resultBuf.toString()); } } private void init() { try { fact = CertificateFactory.getInstance("X.509", "BC"); trustedCert = (X509Certificate)fact .generateCertificate(new ByteArrayInputStream(Base64 .decode(Trust_Anchor_CP_01_01_crt))); trustedCRL = (X509CRL)fact.generateCRL(new ByteArrayInputStream( Base64.decode(Trust_Anchor_CRL_CP_01_01_crl))); trustedSet = new HashSet(); byte[] _ncBytes = null; byte[] _octBytes = trustedCert.getExtensionValue("2.5.29.30"); if (_octBytes != null) { ASN1InputStream _ais = new ASN1InputStream( new ByteArrayInputStream(_octBytes)); ASN1OctetString _oct = ASN1OctetString.getInstance(_ais .readObject()); _ais.close(); _ncBytes = _oct.getOctets(); } trustedSet.add(new TrustAnchor(trustedCert, _ncBytes)); testCount = 0; testFail = new Vector(); resultBuf = new StringBuffer(); } catch (Exception ex) { throw new RuntimeException(ex.getMessage()); } } private X509Certificate decodeCertificate(String _str) throws GeneralSecurityException { return (X509Certificate)fact .generateCertificate(new ByteArrayInputStream(Base64 .decode(_str))); } private X509CRL decodeCRL(String _str) throws GeneralSecurityException { return (X509CRL)fact.generateCRL(new ByteArrayInputStream(Base64 .decode(_str))); } private CertStore makeCertStore(String[] _strs) throws GeneralSecurityException { Vector _vec = new Vector(); _vec.addElement(trustedCRL); for (int i = 0; i < _strs.length; i++) { if (_strs[i].startsWith("MIIC")) { _vec.addElement(fact .generateCertificate(new ByteArrayInputStream(Base64 .decode(_strs[i])))); } else if (_strs[i].startsWith("MIIB")) { _vec.addElement(fact.generateCRL(new ByteArrayInputStream( Base64.decode(_strs[i])))); } else { throw new IllegalArgumentException("Invalid certificate or crl"); } } // Insert elements backwards to muck up forward ordering dependency Vector _vec2 = new Vector(); for (int i = _vec.size() - 1; i >= 0; i--) { _vec2.add(_vec.elementAt(i)); } return CertStore.getInstance("Collection", new CollectionCertStoreParameters(_vec2), "BC"); } private void test(String _name, String[] _data, boolean _accept, boolean _debug) { test(_name, _data, null, false, _accept, _debug); } private void test(String _name, String[] _data, boolean _explicit, boolean _accept, boolean _debug) { test(_name, _data, null, _explicit, _accept, _debug); } private void test(String _name, String[] _data, Set _ipolset, boolean _explicit, boolean _accept, boolean _debug) { testCount++; boolean _pass = true; try { CertPathBuilder _cpb = CertPathBuilder.getInstance("PKIX", "BC"); X509Certificate _ee = decodeCertificate(_data[_data.length - 1]); X509CertSelector _select = new X509CertSelector(); _select.setSubject(PrincipalUtil.getSubjectX509Principal(_ee).getEncoded()); PKIXBuilderParameters _param = new PKIXBuilderParameters( trustedSet, _select); _param.setExplicitPolicyRequired(_explicit); _param.addCertStore(makeCertStore(_data)); _param.setRevocationEnabled(true); if (_ipolset != null) { _param.setInitialPolicies(_ipolset); } CertPathBuilderResult _result = _cpb.build(_param); if (!_accept) { System.out.println("Accept when it should reject"); _pass = false; testFail.addElement(_name); } } catch (Exception ex) { if (_accept) { System.out.println("Reject when it should accept"); _pass = false; testFail.addElement(_name); } } resultBuf.append("NISTCertPathTest -- ").append(_name).append(": ") .append(_pass ? "\n" : "Failed.\n"); } public static void main( String[] args) { Security.addProvider(new BouncyCastleProvider()); runTest(new NISTCertPathTest()); } /* * Trust Anchor * */ public static final String Trust_Anchor_CP_01_01_crt = "MIICbDCCAdWgAwIBAgIDAYafMA0GCSqGSIb3DQEBBQUAMF4xCzAJBgNVBAYTAlVTMRgwFg" + "YDVQQKEw9VLlMuIEdvdmVybm1lbnQxDDAKBgNVBAsTA0RvRDEQMA4GA1UECxMHVGVzdGlu" + "ZzEVMBMGA1UEAxMMVHJ1c3QgQW5jaG9yMB4XDTk5MDEwMTEyMDEwMFoXDTQ4MDEwMTEyMD" + "EwMFowXjELMAkGA1UEBhMCVVMxGDAWBgNVBAoTD1UuUy4gR292ZXJubWVudDEMMAoGA1UE" + "CxMDRG9EMRAwDgYDVQQLEwdUZXN0aW5nMRUwEwYDVQQDEwxUcnVzdCBBbmNob3IwgZ8wDQ" + "YJKoZIhvcNAQEBBQADgY0AMIGJAoGBANPzucEztz+nJ/ZBHVyceZ2q0pUQt4TO2qPlWAw+" + "TotWvz6qIS1QE/7zGS56yxHP89O4X1efnZeArx2VVxLfNNS9865N53ymINQETtpjYT49Ko" + "03z8U8yfn68DlIBHi9sN31JEYzoUafF58Eu883lAwTQ6qQrJF4HbrzGIQqgitHAgMBAAGj" + "ODA2MBEGA1UdDgQKBAirmuv5wudUjzAMBgNVHRMEBTADAQH/MBMGA1UdIwQMMAqACKua6/" + "nC51SPMA0GCSqGSIb3DQEBBQUAA4GBABZWD2Gsh4tP62QSG8OFWUpo4TulIcFZLpGsaP4T" + "/2Nt7lXUoIJMN7wWjqkmYf5/Rvo4HxNcimq3EkeYcrm1VoDueJUYGvRjcCY5mxkghI27Yl" + "/fLKE9/BvQOrvYzBs2EqKrrT7m4VK0dRMR7CeVpmPP08z0Tti6uK2tzBplp1pF"; public static final String Trust_Anchor_CRL_CP_01_01_crl = "MIIBbzCB2QIBATANBgkqhkiG9w0BAQUFADBeMQswCQYDVQQGEwJVUzEYMBYGA1UEChMPVS" + "5TLiBHb3Zlcm5tZW50MQwwCgYDVQQLEwNEb0QxEDAOBgNVBAsTB1Rlc3RpbmcxFTATBgNV" + "BAMTDFRydXN0IEFuY2hvchcNOTkwMTAxMTIwMTAwWhcNNDgwMTAxMTIwMTAwWjAiMCACAS" + "cXDTk5MDEwMTEyMDAwMFowDDAKBgNVHRUEAwoBAaAjMCEwCgYDVR0UBAMCAQEwEwYDVR0j" + "BAwwCoAIq5rr+cLnVI8wDQYJKoZIhvcNAQEFBQADgYEAC7lqZwejJRW7QvzH11/7cYcL3r" + "acgMxH3PSU/ufvyLk7ahR++RtHary/WeCvRdyznLiIOA8ZBiguWtVPqsNysNn7WLofQIVa" + "+/TD3T+lece4e1NwGQvj5Q+e2wRtGXg+gCuTjTKUFfKRnWz7O7RyiJKKim0jtAF4RkCpLe" + "bNChY="; /* * test1 * */ public static final String End_Certificate_CP_01_01_crt = "MIIChjCCAe+gAwIBAgIBATANBgkqhkiG9w0BAQUFADBeMQswCQYDVQQGEwJVUzEYMBYGA1" + "UEChMPVS5TLiBHb3Zlcm5tZW50MQwwCgYDVQQLEwNEb0QxEDAOBgNVBAsTB1Rlc3Rpbmcx" + "FTATBgNVBAMTDFRydXN0IEFuY2hvcjAeFw05ODAxMDExMjAxMDBaFw00ODAxMDExMjAxMD" + "BaMGAxCzAJBgNVBAYTAlVTMRgwFgYDVQQKEw9VLlMuIEdvdmVybm1lbnQxDDAKBgNVBAsT" + "A0RvRDEQMA4GA1UECxMHVGVzdGluZzEXMBUGA1UEAxMOVXNlcjEtQ1AuMDEuMDEwgZ8wDQ" + "YJKoZIhvcNAQEBBQADgY0AMIGJAoGBAMY07G8M4FkOvF+6LpO7BKcDuXCKudfl1+bKSowj" + "2GCza8uIiMfYSH5k+fYb43lGQeRh9yVHcfNQlE7yfGo3tgxGv5yWpeKvDMqL8Iy6Q0oIjm" + "qH80ZOz21dUkermcckzTEOfe/R2fNpJPv8M24pq29SdYAqu+CpLDHFtws9O+q1AgMBAAGj" + "UjBQMA4GA1UdDwEB/wQEAwIF4DAWBgNVHSAEDzANMAsGCWCGSAFlAwEwATARBgNVHQ4ECg" + "QIrNv88bwFLtIwEwYDVR0jBAwwCoAIq5rr+cLnVI8wDQYJKoZIhvcNAQEFBQADgYEAK4hP" + "goWtZbHf6qWfRfmrPrz9hDH1644NrJop2Y7MXzuTtpo1zp4NCG4+ii0CSOfvhugc8yOmq3" + "I6olgE0V16VtC5br2892UHYZ55Q4oQ9BWouVVlOyY9rogOB160BnsqBELFhT0Wf6mnbsdD" + "G+BB5fFyeK61aYDWV84kS7cSX5w="; public static final String[] TEST_1_DATA = new String[] { End_Certificate_CP_01_01_crt, }; /* * test2 * */ public static final String Intermediate_Certificate_CP_01_02_crt = "MIIClTCCAf6gAwIBAgIBAjANBgkqhkiG9w0BAQUFADBeMQswCQYDVQQGEwJVUzEYMBYGA1" + "UEChMPVS5TLiBHb3Zlcm5tZW50MQwwCgYDVQQLEwNEb0QxEDAOBgNVBAsTB1Rlc3Rpbmcx" + "FTATBgNVBAMTDFRydXN0IEFuY2hvcjAeFw05ODAxMDExMjAxMDBaFw00ODAxMDExMjAxMD" + "BaMF4xCzAJBgNVBAYTAlVTMRgwFgYDVQQKEw9VLlMuIEdvdmVybm1lbnQxDDAKBgNVBAsT" + "A0RvZDEQMA4GA1UECxMHVGVzdGluZzEVMBMGA1UEAxMMQ0ExLUNQLjAxLjAyMIGfMA0GCS" + "qGSIb3DQEBAQUAA4GNADCBiQKBgQDWOZ4hk+K6NX/l+OiHC4pfKCWFt+XM2n/TxwkqY+mt" + "j9Co77rPPPtVA7mDKU4OiYT74mIWH52HQBZr+PRmOFh0Z9S1oTpLbxNLCDc6OmQKBo6iex" + "SIt/jOatFFmzmTZ78Kq9s3nfrOVA83ggmPDTPkuG5GwcxPgFq0vRmAJ0CESQIDAQABo2Mw" + "YTAPBgNVHRMBAf8EBTADAQH/MA4GA1UdDwEB/wQEAwIBBjAWBgNVHSAEDzANMAsGCWCGSA" + "FlAwEwATARBgNVHQ4ECgQI5o5Am09NlOYwEwYDVR0jBAwwCoAIq5rr+cLnVI8wDQYJKoZI" + "hvcNAQEFBQADgYEA3C7Ye5/Te14LIwo/LK2fnpobbQA3dhOn5UgqZ8lKbQ/HV1D8/eU9dK" + "2v5gW43XvFq4whK0WKLBvBFchKtp9T1QX3CI2WCqdJRyqla6TkQsS36T17/ww2nzy1853Y" + "hfDYNsge5XW8YZNfNjjVxcR3RnyFxPax1YIlISiGdI0dnag="; public static final String Intermediate_CRL_CP_01_02_crl = "MIIBSzCBtQIBATANBgkqhkiG9w0BAQUFADBeMQswCQYDVQQGEwJVUzEYMBYGA1UEChMPVS" + "5TLiBHb3Zlcm5tZW50MQwwCgYDVQQLEwNEb2QxEDAOBgNVBAsTB1Rlc3RpbmcxFTATBgNV" + "BAMTDENBMS1DUC4wMS4wMhcNOTkwMTAxMTIwMTAwWhcNNDgwMTAxMTIwMTAwWqAjMCEwCg" + "YDVR0UBAMCAQEwEwYDVR0jBAwwCoAI5o5Am09NlOYwDQYJKoZIhvcNAQEFBQADgYEAl26W" + "g1Gqq3R93XPjghABVocfeIi8zcSJ0YAKqbifh5V3JCC8Piy19GzZdL244GqBDls44IAhKj" + "YuXN2mSohdqwULbye4agAgfl37XhhwsBDTYwaJiv3njFQ6Ml7KJ3STmoIpmlLvrXibDuHX" + "ocuNGo72ckhOdBpXd+PhgGuoTis="; public static final String End_Certificate_CP_01_02_crt = "MIIChjCCAe+gAwIBAgIBAzANBgkqhkiG9w0BAQUFADBeMQswCQYDVQQGEwJVUzEYMBYGA1" + "UEChMPVS5TLiBHb3Zlcm5tZW50MQwwCgYDVQQLEwNEb2QxEDAOBgNVBAsTB1Rlc3Rpbmcx" + "FTATBgNVBAMTDENBMS1DUC4wMS4wMjAeFw05ODAxMDExMjAxMDBaFw00ODAxMDExMjAxMD" + "BaMGAxCzAJBgNVBAYTAlVTMRgwFgYDVQQKEw9VLlMuIEdvdmVybm1lbnQxDDAKBgNVBAsT" + "A0RvRDEQMA4GA1UECxMHVGVzdGluZzEXMBUGA1UEAxMOVXNlcjEtQ1AuMDEuMDIwgZ8wDQ" + "YJKoZIhvcNAQEBBQADgY0AMIGJAoGBALwJrZT6bJXQnZzc3socZ/mNsEag4BTdym99ZCP2" + "3PGsTCfV2z7+p4DehIFrn/N/a1d1nvyqRqpQGPU86tl1CWgFtXS+zCctDR71P76bjd6yef" + "5vxxdO/SBIRHfQTjM8F3BTLkrC+PVl5wbaLcEXRORXrFvBvsj0oqwZ4C8ZObh/AgMBAAGj" + "UjBQMA4GA1UdDwEB/wQEAwIF4DAWBgNVHSAEDzANMAsGCWCGSAFlAwEwATARBgNVHQ4ECg" + "QIf5mSjuNhs/gwEwYDVR0jBAwwCoAI5o5Am09NlOYwDQYJKoZIhvcNAQEFBQADgYEAK7wd" + "MyLlIZ/Qsqj3/A3Gat0d5BORtFTZH0VdlVVOWN1JCZxrnjeIFB92NNzUROemxgBxzneuWN" + "SlYlcpTk25pAbs6RMdbT8dovKQkQkF2TXeQ+4qktFaLQntVT8UsEzHR4Diw0/gH8tseGqF" + "F7FyiW8ni6zInSO+embUKiibj9I="; public static final String[] TEST_2_DATA = new String[] { Intermediate_Certificate_CP_01_02_crt, Intermediate_CRL_CP_01_02_crl, End_Certificate_CP_01_02_crt }; /* * test3 * */ public static final String Intermediate_Certificate_CP_01_03_crt = "MIIClTCCAf6gAwIBAgIBBDANBgkqhkiG9w0BAQUFADBeMQswCQYDVQQGEwJVUzEYMBYGA1" + "UEChMPVS5TLiBHb3Zlcm5tZW50MQwwCgYDVQQLEwNEb0QxEDAOBgNVBAsTB1Rlc3Rpbmcx" + "FTATBgNVBAMTDFRydXN0IEFuY2hvcjAeFw05ODAxMDExMjAxMDBaFw00ODAxMDExMjAxMD" + "BaMF4xCzAJBgNVBAYTAlVTMRgwFgYDVQQKEw9VLlMuIEdvdmVybm1lbnQxDDAKBgNVBAsT" + "A0RvZDEQMA4GA1UECxMHVGVzdGluZzEVMBMGA1UEAxMMQ0ExLUNQLjAxLjAzMIGfMA0GCS" + "qGSIb3DQEBAQUAA4GNADCBiQKBgQC4RZ0R82sA+BfyynFeoIDG7c5IlZ8HorEv+O4Ij3Oy" + "7FR1MB4no8hDEBPBf5fCrAR/8PVxCZjVj2HOwnSAqUQgxo6WPcmkabux12k8kK6yeKq3b7" + "u5fL6tb7eKElQzsz8Je4z4rCDkI10vV+X0VZ5Ip/Es428dw2KoN8eyGmw3+QIDAQABo2Mw" + "YTAPBgNVHRMBAf8EBTADAQH/MA4GA1UdDwEB/wQEAwIBBjAWBgNVHSAEDzANMAsGCWCGSA" + "FlAwEwATARBgNVHQ4ECgQIz08WhMpG2JswEwYDVR0jBAwwCoAIq5rr+cLnVI8wDQYJKoZI" + "hvcNAQEFBQADgYEAQ+iqlFvbvDejO/m+RCHh2UuUau1FuABObkPOu2Tv9yTWvTSWDRygdO" + "LQRiOLsjgrdXPdbDutVGjllBoTN8cdz3SWjCpampg5TBikArxmNEYMDQvL6n2lkUcetRJR" + "gQ7TYLvFj9+SycKXfM5CUXAyCfcU/QwDghhZgc99AuDZtJc="; public static final String Intermediate_CRL_CP_01_03_crl = "MIIBSzCBtQIBATANBgkqhkiG9w0BAQUFADBeMQswCQYDVQQGEwJVUzEYMBYGA1UEChMPVS" + "5TLiBHb3Zlcm5tZW50MQwwCgYDVQQLEwNEb2QxEDAOBgNVBAsTB1Rlc3RpbmcxFTATBgNV" + "BAMTDENBMS1DUC4wMS4wMxcNOTkwMTAxMTIwMTAwWhcNNDgwMTAxMTIwMTAwWqAjMCEwCg" + "YDVR0UBAMCAQEwEwYDVR0jBAwwCoAIz08WhMpG2JswDQYJKoZIhvcNAQEFBQADgYEAoyO/" + "xcpJ0Obj4rTXhHFd7XMzslt79njkEgdwnon9BaYB3xSmkEXCMwLMurrjVYKaB6SWAiPeUv" + "G7ScDHJE6UFVJwIt4vP/M7gTOJ7uak33aWi9e5DeIuLqE6pFqTGu+uoBkkd82SHg2GhJhZ" + "VXDtJ3UcO/3JQPbslc02s9HiRBg="; public static final String End_Certificate_CP_01_03_crt = "MIIChjCCAe+gAwIBAgIBBTANBgkqhkiG9w0BAQUFADBeMQswCQYDVQQGEwJVUzEYMBYGA1" + "UEChMPVS5TLiBHb3Zlcm5tZW50MQwwCgYDVQQLEwNEb2QxEDAOBgNVBAsTB1Rlc3Rpbmcx" + "FTATBgNVBAMTDENBMS1DUC4wMS4wMzAeFw05ODAxMDExMjAxMDBaFw00ODAxMDExMjAxMD" + "BaMGAxCzAJBgNVBAYTAlVTMRgwFgYDVQQKEw9VLlMuIEdvdmVybm1lbnQxDDAKBgNVBAsT" + "A0RvRDEQMA4GA1UECxMHVGVzdGluZzEXMBUGA1UEAxMOVXNlcjEtQ1AuMDEuMDMwgZ8wDQ" + "YJKoZIhvcNAQEBBQADgY0AMIGJAoGBANAD1vQj//4BGEXW1Q7HX/AUyFJFyHoYcvg5y4u/" + "8Sj6okriXj3knnBKDiJLpKfcsO5p5MQS5QzAc+lxErXD+duiw8lm61hj0StsRzhDFsaC1g" + "akjzU70R2Tmz/djUnqO3aa2wICc4NVAXnIMMsH/b6XXFZpC0/C32TPTv9aa9mrAgMBAAGj" + "UjBQMA4GA1UdDwEB/wQEAwIF4DAWBgNVHSAEDzANMAsGCWCGSAFlAwEwATARBgNVHQ4ECg" + "QIPw2wltiRqz4wEwYDVR0jBAwwCoAIz08WhMpG2JswDQYJKoZIhvcNAQEFBQADgYEAln42" + "iR3eHyazF8CRjS9Jnas/26MaBtjUyDtcSjTVDWFlccwrQ7TgtzjkNm9fCmgSyvryDnUYGM" + "DoEjwYNLIgtCAkVIEBTmJvlqiPHH+tV5oJvIav+Fn8okHpuuK44umDcdKiFWlOyxrShxzV" + "3Bez/eHklaPTw/VsVhyh+Uru5zM="; public static final String[] TEST_3_DATA = new String[] { Intermediate_Certificate_CP_01_03_crt, Intermediate_CRL_CP_01_03_crl, End_Certificate_CP_01_03_crt }; /* * test4 * */ public static final String Intermediate_Certificate_1_CP_02_01_crt = "MIIClTCCAf6gAwIBAgIBBjANBgkqhkiG9w0BAQUFADBeMQswCQYDVQQGEwJVUzEYMBYGA1" + "UEChMPVS5TLiBHb3Zlcm5tZW50MQwwCgYDVQQLEwNEb0QxEDAOBgNVBAsTB1Rlc3Rpbmcx" + "FTATBgNVBAMTDFRydXN0IEFuY2hvcjAeFw05OTAxMDExMjAxMDBaFw00ODAxMDExMjAxMD" + "BaMF4xCzAJBgNVBAYTAlVTMRgwFgYDVQQKEw9VLlMuIEdvdmVybm1lbnQxDDAKBgNVBAsT" + "A0RvZDEQMA4GA1UECxMHVGVzdGluZzEVMBMGA1UEAxMMQ0ExLUNQLjAyLjAxMIGfMA0GCS" + "qGSIb3DQEBAQUAA4GNADCBiQKBgQC/lQLtWKzklgYuzhjMiK2CzFmzODsEY/JIVNdn9T8M" + "W4ufpGwnfIV62EUHCFeMYydKBm8Hyjbjrz1otINJmrGL5WSAX1/UPtHy1chgXOsFYD6nAH" + "jZAJJGw74nUbKw5+L1wUHU8qXABaaTrRpS1UdKSq4TCZ18NCjC4Oxcf/yDdQIDAQABo2Mw" + "YTAPBgNVHRMBAf8EBTADAQH/MA4GA1UdDwEB/wQEAwIBBjAWBgNVHSAEDzANMAsGCWCGSA" + "FlAwEwATARBgNVHQ4ECgQINsJcxaBqdugwEwYDVR0jBAwwCoAIq5rr+cLnVI8wDQYJKoZI" + "hvcNAQEFBQADgYEAOQP3iUX7FtJlL9nvu4F+8o/N5vr+OB28OsbYtW+Q1FzEfjkUGtT9Ri" + "teradpN/xUnS/oj3BfqFtNANkYKrBeqRtm2VeOC3kdCVFnWFME2aoRAQZbWvOwCFc3yLA7" + "JBdENtDNI54yYHMHPA4/2CuNQq1Iu1ektAS95DIe7ddxL18="; public static final String Intermediate_Certificate_2_CP_02_01_crt = "MIIClTCCAf6gAwIBAgIBBzANBgkqhkiG9w0BAQUFADBeMQswCQYDVQQGEwJVUzEYMBYGA1" + "UEChMPVS5TLiBHb3Zlcm5tZW50MQwwCgYDVQQLEwNEb2QxEDAOBgNVBAsTB1Rlc3Rpbmcx" + "FTATBgNVBAMTDENBMS1DUC4wMi4wMTAeFw05OTAxMDExMjAxMDBaFw00ODAxMDExMjAxMD" + "BaMF4xCzAJBgNVBAYTAlVTMRgwFgYDVQQKEw9VLlMuIEdvdmVybm1lbnQxDDAKBgNVBAsT" + "A0RvZDEQMA4GA1UECxMHVGVzdGluZzEVMBMGA1UEAxMMQ0EyLUNQLjAyLjAxMIGfMA0GCS" + "qGSIb3DQEBAQUAA4GNADCBiQKBgQCx/mIo1Ma/IN8OR7KOjclvIwsv0JFXD/T258DruDZU" + "uGoYiEbAc/ZN7R8OHI7dnv9pBfsvyEl7m2DVoLZnP0eXJTHjdZxb1TwPHoSIysi9u3xWlP" + "Rg+v+GGfKLB9pL0m8SZh97SngerZI14w7vQy0kkXziGatSpBoXtWNmsHJNuQIDAQABo2Mw" + "YTAPBgNVHRMBAf8EBTADAQH/MA4GA1UdDwEB/wQEAwIBBjAWBgNVHSAEDzANMAsGCWCGSA" + "FlAwEwATARBgNVHQ4ECgQIoI0mSmDmzZUwEwYDVR0jBAwwCoAINsJcxaBqdugwDQYJKoZI" + "hvcNAQEFBQADgYEAcfs1pH12Qwdhv4NOJO2xxgMZZo8+A9Zl9c7RxsvuoZOOyCxoE9wT/l" + "PdUpGoGxtIPoWQs1qXEXnAlXJCXjLCJUHIG1/E6gQUXW0Ty6Ztpc5Dz06pPTN2gt+41B3J" + "sL/Klqc4iyCaWr8sYgEPQ8nColWRmIwk9gAasPNkNhyxA3Y="; public static final String Intermediate_CRL_1_CP_02_01_crl = "MIIBSzCBtQIBATANBgkqhkiG9w0BAQUFADBeMQswCQYDVQQGEwJVUzEYMBYGA1UEChMPVS" + "5TLiBHb3Zlcm5tZW50MQwwCgYDVQQLEwNEb2QxEDAOBgNVBAsTB1Rlc3RpbmcxFTATBgNV" + "BAMTDENBMS1DUC4wMi4wMRcNOTkwMTAxMTIwMTAwWhcNNDgwMTAxMTIwMTAwWqAjMCEwCg" + "YDVR0UBAMCAQEwEwYDVR0jBAwwCoAINsJcxaBqdugwDQYJKoZIhvcNAQEFBQADgYEAlBaV" + "VfrZqvyRhGXNYFik169nBHiNfKpw8k1YgFAQeNYdmfScq1KHmKzDhsx9kQteczBL7ltviK" + "TN3CKlZW82c16mfd4yYx0l5tkU80lwKCHSUzx92+qrvYjSMup+bqSsi8JhqByBf6b0JbKf" + "yx53Vpw1OCzjxrVHcfHPx8Q/vR4="; public static final String Intermediate_CRL_2_CP_02_01_crl = "MIIBSzCBtQIBATANBgkqhkiG9w0BAQUFADBeMQswCQYDVQQGEwJVUzEYMBYGA1UEChMPVS" + "5TLiBHb3Zlcm5tZW50MQwwCgYDVQQLEwNEb2QxEDAOBgNVBAsTB1Rlc3RpbmcxFTATBgNV" + "BAMTDENBMi1DUC4wMi4wMRcNOTkwMTAxMTIwMTAwWhcNNDgwMTAxMTIwMTAwWqAjMCEwCg" + "YDVR0UBAMCAQEwEwYDVR0jBAwwCoAIoI0mSmDmzZUwDQYJKoZIhvcNAQEFBQADgYEAhAHP" + "QxpcrTTN0GXeOwoMXuQUoHMvezEpM0BYOVLzI3KbRXWa9iWZINr99cRQvonMtOGkhIH3iS" + "wSNbsjmF9HX5UvNzrofOWataVP+macpCuNlK0NS3xxJjKRWOB9C1Ib7tiSSrQqIPcchlF6" + "vofy2ALEL6Usa1UTVYMhzGYnVZU="; public static final String End_Certificate_CP_02_01_crt = "MIIChjCCAe+gAwIBAgIBCDANBgkqhkiG9w0BAQUFADBeMQswCQYDVQQGEwJVUzEYMBYGA1" + "UEChMPVS5TLiBHb3Zlcm5tZW50MQwwCgYDVQQLEwNEb2QxEDAOBgNVBAsTB1Rlc3Rpbmcx" + "FTATBgNVBAMTDENBMi1DUC4wMi4wMTAeFw05OTAxMDExMjAxMDBaFw00ODAxMDExMjAxMD" + "BaMGAxCzAJBgNVBAYTAlVTMRgwFgYDVQQKEw9VLlMuIEdvdmVybm1lbnQxDDAKBgNVBAsT" + "A0RvRDEQMA4GA1UECxMHVGVzdGluZzEXMBUGA1UEAxMOVXNlcjEtQ1AuMDIuMDEwgZ8wDQ" + "YJKoZIhvcNAQEBBQADgY0AMIGJAoGBAOzYq2murB5ZjQd4wReI51Lc1F5VwK90OMGRfi71" + "YvwdRjgCudeDXZGW5ayid82y+eTDKFSzo1Li/BPTUXMpeqHHMCmLeefqxAWmz3aDoilF8I" + "Q53PlejnXJdntsal44w6WdP6ssiXlwzcZDnobAfuDTPgsnWWfzAkr1/LqEw/QZAgMBAAGj" + "UjBQMA4GA1UdDwEB/wQEAwIF4DAWBgNVHSAEDzANMAsGCWCGSAFlAwEwATARBgNVHQ4ECg" + "QIP5tVdEyxotcwEwYDVR0jBAwwCoAIoI0mSmDmzZUwDQYJKoZIhvcNAQEFBQADgYEAkVx9" + "S/20Hir8qMnfMpMGTgMKoVeWoljxim83IkNs1Xqe1oLGHdyDUA66uF8wPkoTqGrfDYvgBa" + "5Mi0iJREnMWoiWvCe467+L1b2gtvRBMl9bcRj40bvelk0Wn4lBl3VuKXarP5M0PKT5OWvN" + "2cPLNeXHvV6ZIrC4rmK2ISpIXX4="; public static final String[] TEST_4_DATA = new String[] { Intermediate_Certificate_1_CP_02_01_crt, Intermediate_Certificate_2_CP_02_01_crt, Intermediate_CRL_1_CP_02_01_crl, Intermediate_CRL_2_CP_02_01_crl, End_Certificate_CP_02_01_crt }; /* * test5 * */ public static final String Intermediate_Certificate_CP_02_02_crt = "MIIClTCCAf6gAwIBAgIBCTANBgkqhkiG9w0BAQUFADBeMQswCQYDVQQGEwJVUzEYMBYGA1" + "UEChMPVS5TLiBHb3Zlcm5tZW50MQwwCgYDVQQLEwNEb0QxEDAOBgNVBAsTB1Rlc3Rpbmcx" + "FTATBgNVBAMTDFRydXN0IEFuY2hvcjAeFw00NzAxMDExMjAxMDBaFw00ODAxMDExMjAxMD" + "BaMF4xCzAJBgNVBAYTAlVTMRgwFgYDVQQKEw9VLlMuIEdvdmVybm1lbnQxDDAKBgNVBAsT" + "A0RvZDEQMA4GA1UECxMHVGVzdGluZzEVMBMGA1UEAxMMQ0ExLUNQLjAyLjAyMIGfMA0GCS" + "qGSIb3DQEBAQUAA4GNADCBiQKBgQDHJmlRKb+mjc61iiqGe9gx/VUMLNmGrXGRYKMmYSxO" + "Q5sGLoztd2XtEgtZEPwvzd9KLKGP3XmgTrc4BGohqoFoG9Qb+w2ZGFwVC22GpeSoXc+J2u" + "2t3uRKYgboHpB0Jk42XLy+2wSEtS+/er7cFu2ufdPsvT4J1AqiuZSco96vtQIDAQABo2Mw" + "YTAPBgNVHRMBAf8EBTADAQH/MA4GA1UdDwEB/wQEAwIBBjAWBgNVHSAEDzANMAsGCWCGSA" + "FlAwEwATARBgNVHQ4ECgQIBvoP1E6PGiMwEwYDVR0jBAwwCoAIq5rr+cLnVI8wDQYJKoZI" + "hvcNAQEFBQADgYEAmOyFq2vZrUNDVWRcyzYvZhs1uQ4zgXtfqnPE0V19RgaYffCrSCI86z" + "5kyDUyZwbGABMxBaVxEw536MesyDTdZdEVw6lN5RRtxr8/WEiSH6oI6t0xNxuNOkSNpz4d" + "28HA4UfUvtXK8RK2YZnPAd6UXsRUPBPXKEpzy4v/9RyihSg="; public static final String Intermediate_CRL_CP_02_02_crl = "MIIBSzCBtQIBATANBgkqhkiG9w0BAQUFADBeMQswCQYDVQQGEwJVUzEYMBYGA1UEChMPVS" + "5TLiBHb3Zlcm5tZW50MQwwCgYDVQQLEwNEb2QxEDAOBgNVBAsTB1Rlc3RpbmcxFTATBgNV" + "BAMTDENBMS1DUC4wMi4wMhcNOTkwMTAxMTIwMTAwWhcNNDgwMTAxMTIwMTAwWqAjMCEwCg" + "YDVR0UBAMCAQEwEwYDVR0jBAwwCoAIBvoP1E6PGiMwDQYJKoZIhvcNAQEFBQADgYEAALlA" + "f3IDWexcdkMQHWTdGeFe+bG5dBvVPL5ZyQUw9DWbLwrjw/Jm4v9t+HLjETLSymsFT4bW21" + "OwnEiAAdaKT96k5t+sTyU5QQ6HL/jRXLHLGdCQgMFCglm5iNqaCLIFoMAVCaFkYtFUE3m/" + "iVt+319JOh5UyshMuWrAEW0IGGQ="; public static final String End_Certificate_CP_02_02_crt = "MIIChjCCAe+gAwIBAgIBCjANBgkqhkiG9w0BAQUFADBeMQswCQYDVQQGEwJVUzEYMBYGA1" + "UEChMPVS5TLiBHb3Zlcm5tZW50MQwwCgYDVQQLEwNEb2QxEDAOBgNVBAsTB1Rlc3Rpbmcx" + "FTATBgNVBAMTDENBMS1DUC4wMi4wMjAeFw05ODAxMDExMjAxMDBaFw00ODAxMDExMjAxMD" + "BaMGAxCzAJBgNVBAYTAlVTMRgwFgYDVQQKEw9VLlMuIEdvdmVybm1lbnQxDDAKBgNVBAsT" + "A0RvRDEQMA4GA1UECxMHVGVzdGluZzEXMBUGA1UEAxMOVXNlcjEtQ1AuMDIuMDIwgZ8wDQ" + "YJKoZIhvcNAQEBBQADgY0AMIGJAoGBAL/Src6e8qXwL+KJs5+v+JsakZdSDqMAFJUMfA2O" + "OO2TIqcvDFHzqesX+G+28MUwy6++ux07CD3FCaapgzBN4zO4RfKcamxFReKMKcEvNVVCOO" + "wO4Lvku1Sad14oYyGLOMzZwZFjRp8paaz5g87k70EOPBLeDlFMcch36czw53sLAgMBAAGj" + "UjBQMA4GA1UdDwEB/wQEAwIF4DAWBgNVHSAEDzANMAsGCWCGSAFlAwEwATARBgNVHQ4ECg" + "QIPoHc2Sfk6XUwEwYDVR0jBAwwCoAIBvoP1E6PGiMwDQYJKoZIhvcNAQEFBQADgYEAFHhm" + "o6QRFdO1x1wp7Jb1QQAlChFfP8MrGVNK04Ur8f+wfkwIypTDifJ0AoFpjcM3Ohu9Ixvb9q" + "3kCSIWKDnWtDWw1/dN8mPL5If5gGqPA0+wRbUKVKvduOg7hKr4mWjKw7oYiaJuIIoN9RRZ" + "ejzltd0NEaODNPW/JaKeQUVgZbY="; public static final String[] TEST_5_DATA = new String[] { Intermediate_Certificate_CP_02_02_crt, Intermediate_CRL_CP_02_02_crl, End_Certificate_CP_02_02_crt }; /* * test6 * */ public static final String Intermediate_Certificate_CP_02_03_crt = "MIIClTCCAf6gAwIBAgIBCzANBgkqhkiG9w0BAQUFADBeMQswCQYDVQQGEwJVUzEYMBYGA1" + "UEChMPVS5TLiBHb3Zlcm5tZW50MQwwCgYDVQQLEwNEb0QxEDAOBgNVBAsTB1Rlc3Rpbmcx" + "FTATBgNVBAMTDFRydXN0IEFuY2hvcjAeFw05ODAxMDExMjAxMDBaFw00ODAxMDExMjAxMD" + "BaMF4xCzAJBgNVBAYTAlVTMRgwFgYDVQQKEw9VLlMuIEdvdmVybm1lbnQxDDAKBgNVBAsT" + "A0RvZDEQMA4GA1UECxMHVGVzdGluZzEVMBMGA1UEAxMMQ0ExLUNQLjAyLjAzMIGfMA0GCS" + "qGSIb3DQEBAQUAA4GNADCBiQKBgQCaJ7NcOvb22F6HjMF1R/AORa4+pKFfFfd9teXPpVWC" + "9InTq+alY11QaSj27Qg0znOIItmf2W/8Dub9sjnbg+SgAkoV5+CAkplodRNC8AbD4x8rh/" + "fioQ8lb0Qb4Dn9I0n2wjOgitmMRdE2uW4uwVpH52vsMyenbDVxVI7jA4NS/wIDAQABo2Mw" + "YTAPBgNVHRMBAf8EBTADAQH/MA4GA1UdDwEB/wQEAwIBBjAWBgNVHSAEDzANMAsGCWCGSA" + "FlAwEwATARBgNVHQ4ECgQIC2T+/BkG93AwEwYDVR0jBAwwCoAIq5rr+cLnVI8wDQYJKoZI" + "hvcNAQEFBQADgYEApr6kDXVY5jYt23wC9n3LmhoxDoWh8cBQxcWmr1wpVxIrCbaP0/y00a" + "29wbewKfucUoh/W2OfjNcohjpKRrnVmOpi5vN7SmbZIHaxbKLzyQ7JwF17aznyCSZVrGpF" + "A/S49T5rlCm8KDBcc2ym7gRJzwUApbC0Wws4Pg46czrpQlg="; public static final String Intermediate_CRL_CP_02_03_crl = "MIIBSzCBtQIBATANBgkqhkiG9w0BAQUFADBeMQswCQYDVQQGEwJVUzEYMBYGA1UEChMPVS" + "5TLiBHb3Zlcm5tZW50MQwwCgYDVQQLEwNEb2QxEDAOBgNVBAsTB1Rlc3RpbmcxFTATBgNV" + "BAMTDENBMS1DUC4wMi4wMxcNOTkwMTAxMTIwMTAwWhcNNDgwMTAxMTIwMTAwWqAjMCEwCg" + "YDVR0UBAMCAQEwEwYDVR0jBAwwCoAIC2T+/BkG93AwDQYJKoZIhvcNAQEFBQADgYEAlBFY" + "vPxhFYsjFOIfQkd7MwKIi7vgPgoWTP5f+QlI0ison5n4N3rYJv31hTZRRRP99JZce1hY6J" + "Qiv1OtkpG7VfQIhr0FAGxTNaJD6F6rLbGjG8cap4+VibFQf5gZv0XQcyW4akYiRqSXImYn" + "NVlNyaxiJja+5GA9XVqvWOjjz4o="; public static final String End_Certificate_CP_02_03_crt = "MIIChjCCAe+gAwIBAgIBDDANBgkqhkiG9w0BAQUFADBeMQswCQYDVQQGEwJVUzEYMBYGA1" + "UEChMPVS5TLiBHb3Zlcm5tZW50MQwwCgYDVQQLEwNEb2QxEDAOBgNVBAsTB1Rlc3Rpbmcx" + "FTATBgNVBAMTDENBMS1DUC4wMi4wMzAeFw00NzAxMDExMjAxMDBaFw00ODAxMDExMjAxMD" + "BaMGAxCzAJBgNVBAYTAlVTMRgwFgYDVQQKEw9VLlMuIEdvdmVybm1lbnQxDDAKBgNVBAsT" + "A0RvRDEQMA4GA1UECxMHVGVzdGluZzEXMBUGA1UEAxMOVXNlcjEtQ1AuMDIuMDMwgZ8wDQ" + "YJKoZIhvcNAQEBBQADgY0AMIGJAoGBAMlW6FOLwhRsKZM6p0ww4QEWjQzjpjYhKnz3BnLw" + "SdGZqMe4wzZnDWc/0eyDOMCSYXIWQhlDMqQn2zCVPbDKzMRkdEeRSvE6ghhYP/hn3ipjSw" + "D8QwaqofCp0sFkbDPke+xD2tMhLdUyNKynPjpSQmYtfoA98PD7so3cSAtrYuSDAgMBAAGj" + "UjBQMA4GA1UdDwEB/wQEAwIF4DAWBgNVHSAEDzANMAsGCWCGSAFlAwEwATARBgNVHQ4ECg" + "QIc/X6kp7teCQwEwYDVR0jBAwwCoAIC2T+/BkG93AwDQYJKoZIhvcNAQEFBQADgYEAStub" + "g3DzhJgzYO+ZmRc0acldZGwZFm6F1Ckc1JzQDgVHU0bnCANgBcJj49UV2MwbNKPQdVzdwo" + "c91rfwrSY/PrvVQ9tUonZ28y/esFRBAdJTLf4u++p/gI3vfCvEXa5xVTIz1Hc+iKzAGKrI" + "cveDHy3ZZluQ3J6tbHs2BhnQFXM="; public static final String[] TEST_6_DATA = new String[] { Intermediate_Certificate_CP_02_03_crt, Intermediate_CRL_CP_02_03_crl, End_Certificate_CP_02_03_crt }; /* * test7 * */ public static final String Intermediate_Certificate_CP_02_04_crt = "MIIClTCCAf6gAwIBAgIBDTANBgkqhkiG9w0BAQUFADBeMQswCQYDVQQGEwJVUzEYMBYGA1" + "UEChMPVS5TLiBHb3Zlcm5tZW50MQwwCgYDVQQLEwNEb0QxEDAOBgNVBAsTB1Rlc3Rpbmcx" + "FTATBgNVBAMTDFRydXN0IEFuY2hvcjAeFw05ODAxMDExMjAxMDBaFw00ODAxMDExMjAxMD" + "BaMF4xCzAJBgNVBAYTAlVTMRgwFgYDVQQKEw9VLlMuIEdvdmVybm1lbnQxDDAKBgNVBAsT" + "A0RvZDEQMA4GA1UECxMHVGVzdGluZzEVMBMGA1UEAxMMQ0ExLUNQLjAyLjA0MIGfMA0GCS" + "qGSIb3DQEBAQUAA4GNADCBiQKBgQDgZy2Xs5pIoJrT7GuagmKLrn8F9rj8p8w2wELorGhM" + "1HJMVOurH+o+y6RXd0oMGJkKNrhjEnbHKm3PBYiLgpCjVEcFNhQF1OOxJ7RdahvA9ifsuw" + "jV1TxTGq35jeaJYASRXb2TiNfzuPWSVm0MWr5zz+YB6NNuvjxwEBgZvNiV8QIDAQABo2Mw" + "YTAPBgNVHRMBAf8EBTADAQH/MA4GA1UdDwEB/wQEAwIBBjAWBgNVHSAEDzANMAsGCWCGSA" + "FlAwEwATARBgNVHQ4ECgQIWAOnkHkwSVkwEwYDVR0jBAwwCoAIq5rr+cLnVI8wDQYJKoZI" + "hvcNAQEFBQADgYEAMiHozz92EOhSXU/krwQVs0GNEWoAUH3LHt70Zr01dFzEF6QhA/wUa4" + "+V4XwbMob+q4zGnTHj+tL9ChGWi3NDGELQ4cN64OMPsToGKkepLy+sDwdm9LaUP1bDvPxd" + "v2hjlskJ7TEu4+6ltXSG/k36Jk8C0/I/ayNGbYcEcLyes3s="; public static final String Intermediate_CRL_CP_02_04_crl = "MIIBSzCBtQIBATANBgkqhkiG9w0BAQUFADBeMQswCQYDVQQGEwJVUzEYMBYGA1UEChMPVS" + "5TLiBHb3Zlcm5tZW50MQwwCgYDVQQLEwNEb2QxEDAOBgNVBAsTB1Rlc3RpbmcxFTATBgNV" + "BAMTDENBMS1DUC4wMi4wNBcNOTkwMTAxMTIwMTAwWhcNNDgwMTAxMTIwMTAwWqAjMCEwCg" + "YDVR0UBAMCAQEwEwYDVR0jBAwwCoAIWAOnkHkwSVkwDQYJKoZIhvcNAQEFBQADgYEAVtCi" + "IocktnWOwWiaOc7tTUJvvH5+IYVyB/XhmMhF7cDbL292gyrnuh1+3+lHwZQBPoF9kzF0vt" + "WaweG7mDvYKxENQODdph/VcnypgUiFTWRTIPB1ZXfCTMWYf2QSalpHRDR4vVsqF748QbcG" + "E9mbzvLUz6NDA+Vf8wEwZehqSDM="; public static final String End_Certificate_CP_02_04_crt = "MIIChjCCAe+gAwIBAgIBDjANBgkqhkiG9w0BAQUFADBeMQswCQYDVQQGEwJVUzEYMBYGA1" + "UEChMPVS5TLiBHb3Zlcm5tZW50MQwwCgYDVQQLEwNEb2QxEDAOBgNVBAsTB1Rlc3Rpbmcx" + "FTATBgNVBAMTDENBMS1DUC4wMi4wNDAeFw01MDAxMDExMjAxMDBaFw00ODAxMDExMjAxMD" + "BaMGAxCzAJBgNVBAYTAlVTMRgwFgYDVQQKEw9VLlMuIEdvdmVybm1lbnQxDDAKBgNVBAsT" + "A0RvRDEQMA4GA1UECxMHVGVzdGluZzEXMBUGA1UEAxMOVXNlcjEtQ1AuMDIuMDQwgZ8wDQ" + "YJKoZIhvcNAQEBBQADgY0AMIGJAoGBALBX5GIQtvwswWwMDDPnphIk1rJSbcq7iClXLM2E" + "kgvBu+hbOzb0v9mtl0KJB71TWJCfwceVQiXc3Gk+YduujAbZRVTkROf9UOWD9bfrI7g+52" + "g4ms2n7evCO33b+kGEf4I014xl8dJDWtHK9Bhr+569RW9TzO06IeVeTD7whxMXAgMBAAGj" + "UjBQMA4GA1UdDwEB/wQEAwIF4DAWBgNVHSAEDzANMAsGCWCGSAFlAwEwATARBgNVHQ4ECg" + "QIuKXv5WkUTWAwEwYDVR0jBAwwCoAIWAOnkHkwSVkwDQYJKoZIhvcNAQEFBQADgYEAiu0B" + "yR5Ru8qVsgRqkOpCvrJnkqBAImbbR6+BUYH0juRxxKzKnbFOjU6a9WvkKpEBB8Q2xLynPN" + "68ecLpnOynx3xj2sWWSVbsRKPy0iOesQblKrq3yHAm4lhzoWA8t1Xz29Ko1WxylDhyxGpR" + "QAWsyGVCfJFlsZE0ibw3erlWTnA="; public static final String[] TEST_7_DATA = new String[] { Intermediate_Certificate_CP_02_04_crt, Intermediate_CRL_CP_02_04_crl, End_Certificate_CP_02_04_crt }; /* * test8 * */ public static final String Intermediate_Certificate_CP_02_05_crt = "MIIClTCCAf6gAwIBAgIBDzANBgkqhkiG9w0BAQUFADBeMQswCQYDVQQGEwJVUzEYMBYGA1" + "UEChMPVS5TLiBHb3Zlcm5tZW50MQwwCgYDVQQLEwNEb0QxEDAOBgNVBAsTB1Rlc3Rpbmcx" + "FTATBgNVBAMTDFRydXN0IEFuY2hvcjAeFw05ODAxMDExMjAxMDBaFw00ODAxMDExMjAxMD" + "BaMF4xCzAJBgNVBAYTAlVTMRgwFgYDVQQKEw9VLlMuIEdvdmVybm1lbnQxDDAKBgNVBAsT" + "A0RvZDEQMA4GA1UECxMHVGVzdGluZzEVMBMGA1UEAxMMQ0ExLUNQLjAyLjA1MIGfMA0GCS" + "qGSIb3DQEBAQUAA4GNADCBiQKBgQC2d80bD1RounqjKizkZJYPFUuVWZQ8W2nZDkEp8qR9" + "fRWCAGOZGs84tgHj5gasmxy1mxJc9ogyQ2mcZhJRitRm5LVNuGevO6JmfqYtJxbW54aZGE" + "5AWSRXqjJKJEih4VmPjA3vjQaSZSZJnu0DSnO82qWfu1ZUDlvIG6dfKJWRQQIDAQABo2Mw" + "YTAPBgNVHRMBAf8EBTADAQH/MA4GA1UdDwEB/wQEAwIBBjAWBgNVHSAEDzANMAsGCWCGSA" + "FlAwEwATARBgNVHQ4ECgQI3uNhI+QuI4owEwYDVR0jBAwwCoAIq5rr+cLnVI8wDQYJKoZI" + "hvcNAQEFBQADgYEAG/+Rpk8dYrSFdaEO8Ch5tuvvKTOMi7W/DRA4B4xR7WyRJmosPB+37c" + "teGKVzqFND22Xc8xQH/b/nxYW08sCSLAfN0cRusoSWwWSRtPO2f9fyC/BqCy2B2kQLFNPM" + "Bk22jNFwLqPUeZn1UHN05RFAqVx325kpl2m1V7tw/mrXATI="; public static final String Intermediate_CRL_CP_02_05_crl = "MIIBSzCBtQIBATANBgkqhkiG9w0BAQUFADBeMQswCQYDVQQGEwJVUzEYMBYGA1UEChMPVS" + "5TLiBHb3Zlcm5tZW50MQwwCgYDVQQLEwNEb2QxEDAOBgNVBAsTB1Rlc3RpbmcxFTATBgNV" + "BAMTDENBMS1DUC4wMi4wNRcNOTkwMTAxMTIwMTAwWhcNNDgwMTAxMTIwMTAwWqAjMCEwCg" + "YDVR0UBAMCAQEwEwYDVR0jBAwwCoAI3uNhI+QuI4owDQYJKoZIhvcNAQEFBQADgYEAWZUI" + "2VGY4pak0kICONP/CKvamYFs5txJfR69AC5tEJ+Fy3PmSeHkLUZf/oc9d8EEyr0MsIjRHj" + "N4X4MquMlk4FflZcc8GblQK8LdXBK4Dy1SiXHA5GB3U1AmgzAzEQGwGRZnzWP5+rJ65upX" + "vksAYyPQmruRM0O5sElctPn6B+Y="; public static final String End_Certificate_CP_02_05_crt = "MIICiDCCAfGgAwIBAgIBEDANBgkqhkiG9w0BAQUFADBeMQswCQYDVQQGEwJVUzEYMBYGA1" + "UEChMPVS5TLiBHb3Zlcm5tZW50MQwwCgYDVQQLEwNEb2QxEDAOBgNVBAsTB1Rlc3Rpbmcx" + "FTATBgNVBAMTDENBMS1DUC4wMi4wNTAgGA8yMDUwMDEwMTEyMDEwMFoXDTQ4MDEwMTEyMD" + "EwMFowYDELMAkGA1UEBhMCVVMxGDAWBgNVBAoTD1UuUy4gR292ZXJubWVudDEMMAoGA1UE" + "CxMDRG9EMRAwDgYDVQQLEwdUZXN0aW5nMRcwFQYDVQQDEw5Vc2VyMS1DUC4wMi4wNTCBnz" + "ANBgkqhkiG9w0BAQEFAAOBjQAwgYkCgYEAviLKpW4iblWNLQfmBJJ+ruMgygmjRWfoFGya" + "Ndv2ma0Ugqm5xXq8c0orbnezwSp+tnzZZhG5KDNZr5+z3krCkqOGGzuUvVLqeJxPOLu7Js" + "y472nAA7+FhwfZrXUI+Vg9F4qF+Ye81ivDrYVAEmalCpCyHOAKdvwkwQjRucifu90CAwEA" + "AaNSMFAwDgYDVR0PAQH/BAQDAgXgMBYGA1UdIAQPMA0wCwYJYIZIAWUDATABMBEGA1UdDg" + "QKBAjgph7BA5L7dzATBgNVHSMEDDAKgAje42Ej5C4jijANBgkqhkiG9w0BAQUFAAOBgQBr" + "MDMv9NWCTIQ3blMEqPiEyjiBhSJl88Cu797P4lIn+gc6E+0vZp61X7B2k5CHgsnxyVLK5e" + "bwl0bYAPKwRI9yzHLrj71RNw8HA7PCRPn1GNrtBBbIpLE0/sqLo51UPu/377+CnzYhIycL" + "tvS0KDLUTDSY/OowDcplF6Xwnt8cUQ=="; public static final String[] TEST_8_DATA = new String[] { Intermediate_Certificate_CP_02_05_crt, Intermediate_CRL_CP_02_05_crl, End_Certificate_CP_02_05_crt }; /* * test9 * */ public static final String Intermediate_Certificate_CP_03_01_crt = "MIIClTCCAf6gAwIBAgIBETANBgkqhkiG9w0BAQUFADBeMQswCQYDVQQGEwJVUzEYMBYGA1" + "UEChMPVS5TLiBHb3Zlcm5tZW50MQwwCgYDVQQLEwNEb0QxEDAOBgNVBAsTB1Rlc3Rpbmcx" + "FTATBgNVBAMTDFRydXN0IEFuY2hvcjAeFw05ODAxMDExMjAxMDBaFw0wMDAxMDExMjAxMD" + "BaMF4xCzAJBgNVBAYTAlVTMRgwFgYDVQQKEw9VLlMuIEdvdmVybm1lbnQxDDAKBgNVBAsT" + "A0RvZDEQMA4GA1UECxMHVGVzdGluZzEVMBMGA1UEAxMMQ0ExLUNQLjAzLjAxMIGfMA0GCS" + "qGSIb3DQEBAQUAA4GNADCBiQKBgQCuF8mub5cgUYZytrRjJ5Rhc2fgazGxWIj6EIKzeSpo" + "FwScItRX9KxnTIXEBTguBk7eQUsbN8yu49/Mlq45EAnemyZRBWzLFLYLPCco7pyTsWm7Ps" + "2FAGJ3vE9pC9xaZC+KrwF3Ho+DZNDwhj5InXTP8pChAIPfB8/7V/2mk0lN0wIDAQABo2Mw" + "YTAPBgNVHRMBAf8EBTADAQH/MA4GA1UdDwEB/wQEAwIBBjAWBgNVHSAEDzANMAsGCWCGSA" + "FlAwEwATARBgNVHQ4ECgQI4mI6Ojs0onswEwYDVR0jBAwwCoAIq5rr+cLnVI8wDQYJKoZI" + "hvcNAQEFBQADgYEAMVGzU6f4YOHpHla+YuGCjHOUZYrA9J25G3UFFoPr2JZEG+Fb5hRQUh" + "4S1qUQKXn6dpVua+qTJDk3Tg2N8OdIHG/gy0hvYHsxhLCSDQBsfPN7p3FClM7r/VHOqgAN" + "vzT+KYvxx6gwn6O+n7ERkrBIfkyrGFhnmjx3+VOCc9P4SDE="; public static final String Intermediate_CRL_CP_03_01_crl = "MIIBSzCBtQIBATANBgkqhkiG9w0BAQUFADBeMQswCQYDVQQGEwJVUzEYMBYGA1UEChMPVS" + "5TLiBHb3Zlcm5tZW50MQwwCgYDVQQLEwNEb2QxEDAOBgNVBAsTB1Rlc3RpbmcxFTATBgNV" + "BAMTDENBMS1DUC4wMy4wMRcNOTkwMTAxMTIwMTAwWhcNNDgwMTAxMTIwMTAwWqAjMCEwCg" + "YDVR0UBAMCAQEwEwYDVR0jBAwwCoAI4mI6Ojs0onswDQYJKoZIhvcNAQEFBQADgYEAfwYf" + "4kAG4srB2VxWimJs1HwXTaPDooellQclZ5hP/EluT7oe03+ReFef6uXbHt/xRdeaoQhJGy" + "SP8dWf6UIbL82oaSYqChIvAZD6zTMavEgSET0PlUsK1aEMTpMEtKPvedFSOTNBaMNvMzSW" + "t5xwurn63qyXTOxHf4m2L4w8+i0="; public static final String End_Certificate_CP_03_01_crt = "MIIChjCCAe+gAwIBAgIBEjANBgkqhkiG9w0BAQUFADBeMQswCQYDVQQGEwJVUzEYMBYGA1" + "UEChMPVS5TLiBHb3Zlcm5tZW50MQwwCgYDVQQLEwNEb2QxEDAOBgNVBAsTB1Rlc3Rpbmcx" + "FTATBgNVBAMTDENBMS1DUC4wMy4wMTAeFw05ODAxMDExMjAxMDBaFw00ODAxMDExMjAxMD" + "BaMGAxCzAJBgNVBAYTAlVTMRgwFgYDVQQKEw9VLlMuIEdvdmVybm1lbnQxDDAKBgNVBAsT" + "A0RvRDEQMA4GA1UECxMHVGVzdGluZzEXMBUGA1UEAxMOVXNlcjEtQ1AuMDMuMDEwgZ8wDQ" + "YJKoZIhvcNAQEBBQADgY0AMIGJAoGBAJ/ALaZ+MdNxKDH49+7jUm+17DII5QQEfjk8IaEU" + "syApOhsByOG06HPItiBEnnfDDxU5kjsZDtw/9LlouBocNXAJt+ZmL3QYyOgeH4SQ4f21rw" + "7j8fw57gUkP5oWhEc0loXr/hB92hoKbsBoRpv8F1zPZcPNLUnyUzqLH5+CeIibAgMBAAGj" + "UjBQMA4GA1UdDwEB/wQEAwIF4DAWBgNVHSAEDzANMAsGCWCGSAFlAwEwATARBgNVHQ4ECg" + "QI822isg/wPCowEwYDVR0jBAwwCoAI4mI6Ojs0onswDQYJKoZIhvcNAQEFBQADgYEAilIn" + "OD0iQrLrHRkO4zr9S9VXAJXJV3l9wfbLBweXM3q/zt4HGKBw4Wq1Yn+AfDxXrBtJA5hP5e" + "d7CDd4eM93yeKozdZCLNZfUM8sJ2/MRh07tvwJ19e2STklED8b/ndmr5my8H8jjJDaaYww" + "qTSnXqpcqsUsj+kV4Mk0DvVWT3w="; public static final String[] TEST_9_DATA = new String[] { Intermediate_Certificate_CP_03_01_crt, Intermediate_CRL_CP_03_01_crl, End_Certificate_CP_03_01_crt }; /* * test10 * */ public static final String Intermediate_Certificate_CP_03_02_crt = "MIIClTCCAf6gAwIBAgIBEzANBgkqhkiG9w0BAQUFADBeMQswCQYDVQQGEwJVUzEYMBYGA1" + "UEChMPVS5TLiBHb3Zlcm5tZW50MQwwCgYDVQQLEwNEb0QxEDAOBgNVBAsTB1Rlc3Rpbmcx" + "FTATBgNVBAMTDFRydXN0IEFuY2hvcjAeFw05ODAxMDExMjAxMDBaFw00ODAxMDExMjAxMD" + "BaMF4xCzAJBgNVBAYTAlVTMRgwFgYDVQQKEw9VLlMuIEdvdmVybm1lbnQxDDAKBgNVBAsT" + "A0RvZDEQMA4GA1UECxMHVGVzdGluZzEVMBMGA1UEAxMMQ0ExLUNQLjAzLjAyMIGfMA0GCS" + "qGSIb3DQEBAQUAA4GNADCBiQKBgQC4AbP8gDUUcIa8w4pEsGgbYH2sz08QMUXd4xwx691i" + "9QCcyWSovQO4Jozeb9JwtyN2+f3T+JqZL/gwUHuLO2IEXpzE2C8FzQg6Ma+TiSrlvGJfec" + "TlSooFmEtD3Xh6I6N5PM1fpyyY2sOOhARN5S6qR9BOuxkBAqrAT0fgqD2TswIDAQABo2Mw" + "YTAPBgNVHRMBAf8EBTADAQH/MA4GA1UdDwEB/wQEAwIBBjAWBgNVHSAEDzANMAsGCWCGSA" + "FlAwEwATARBgNVHQ4ECgQI97nJCqq6+kIwEwYDVR0jBAwwCoAIq5rr+cLnVI8wDQYJKoZI" + "hvcNAQEFBQADgYEAWwpfh9oOOvj9xHS0zcczaUIHTkpjgk09I+pERlu0Z0+rHvpZGge4Ov" + "NDFtMc4TgthGcydbIwiKogjtGBM2/sNHIO2jcpNeOtNKLxrzD4Y0Ve164kXBu9Mmsxx4sG" + "7XUXZWgiOPfu/HmyPVdzbIReJdQO515SNx7JdgVyUkyhBxM="; public static final String Intermediate_CRL_CP_03_02_crl = "MIIBSzCBtQIBATANBgkqhkiG9w0BAQUFADBeMQswCQYDVQQGEwJVUzEYMBYGA1UEChMPVS" + "5TLiBHb3Zlcm5tZW50MQwwCgYDVQQLEwNEb2QxEDAOBgNVBAsTB1Rlc3RpbmcxFTATBgNV" + "BAMTDENBMS1DUC4wMy4wMhcNOTkwMTAxMTIwMTAwWhcNNDgwMTAxMTIwMTAwWqAjMCEwCg" + "YDVR0UBAMCAQEwEwYDVR0jBAwwCoAI97nJCqq6+kIwDQYJKoZIhvcNAQEFBQADgYEAC9Hv" + "NevV6/Oz3wcgEbDgZYRKJRdr4OW4Es7R4ahjz3sH6GXZ1HiEjx2+frmp8LMshQ4D+hpjRk" + "drSPko1M4a/fQCYxbonZ0xjpYw067dwLmr56+GPJAxkzcSmFKXx+ejyQpG+9+qCR+zm98V" + "lop6besAaGUjZKnYShIQOfNzDZk="; public static final String End_Certificate_CP_03_02_crt = "MIIChjCCAe+gAwIBAgIBFDANBgkqhkiG9w0BAQUFADBeMQswCQYDVQQGEwJVUzEYMBYGA1" + "UEChMPVS5TLiBHb3Zlcm5tZW50MQwwCgYDVQQLEwNEb2QxEDAOBgNVBAsTB1Rlc3Rpbmcx" + "FTATBgNVBAMTDENBMS1DUC4wMy4wMjAeFw05ODAxMDExMjAxMDBaFw0wMDAxMDExMjAxMD" + "BaMGAxCzAJBgNVBAYTAlVTMRgwFgYDVQQKEw9VLlMuIEdvdmVybm1lbnQxDDAKBgNVBAsT" + "A0RvRDEQMA4GA1UECxMHVGVzdGluZzEXMBUGA1UEAxMOVXNlcjEtQ1AuMDMuMDIwgZ8wDQ" + "YJKoZIhvcNAQEBBQADgY0AMIGJAoGBAMJMiW+G4bgoRaYz2OUu/+PQ/yp4JgFOB3Vegf5/" + "vIrF4gsnoQxOCCsO5JTLrbS5fi3COjvM5w9/SZpNHtSfyWb9afmx4DdrT1bNjma7I6PCid" + "yxMzX4iTLeaMRnqBk4A+/0Wf2+4VzCqr8aViIiQ7u2JfZiTQ4dZxDoUW6G8lrbAgMBAAGj" + "UjBQMA4GA1UdDwEB/wQEAwIF4DAWBgNVHSAEDzANMAsGCWCGSAFlAwEwATARBgNVHQ4ECg" + "QIEjny2GzFXGQwEwYDVR0jBAwwCoAI97nJCqq6+kIwDQYJKoZIhvcNAQEFBQADgYEAJw3T" + "3aL3pYbZhswgshOvJ9Y1qv65R6rClSxB5lqBw6+Qki4ZpW57NK8LwaGS03XzDUPaDi4/9R" + "hGCHpP24fIskS4n4jNZgKpGtt6VEVorUH7cOLNCw2cuwMlKbkyZnNdx2JqTMMlHzNJ3cmy" + "aX3F70IY0OZbwCKdUo/uMVC6hss="; public static final String[] TEST_10_DATA = new String[] { Intermediate_Certificate_CP_03_02_crt, Intermediate_CRL_CP_03_02_crl, End_Certificate_CP_03_02_crt }; /* * test11 * */ public static final String Intermediate_Certificate_CP_03_03_crt = "MIIClTCCAf6gAwIBAgIBFTANBgkqhkiG9w0BAQUFADBeMQswCQYDVQQGEwJVUzEYMBYGA1" + "UEChMPVS5TLiBHb3Zlcm5tZW50MQwwCgYDVQQLEwNEb0QxEDAOBgNVBAsTB1Rlc3Rpbmcx" + "FTATBgNVBAMTDFRydXN0IEFuY2hvcjAeFw05ODAxMDExMjAxMDBaFw00ODAxMDExMjAxMD" + "BaMF4xCzAJBgNVBAYTAlVTMRgwFgYDVQQKEw9VLlMuIEdvdmVybm1lbnQxDDAKBgNVBAsT" + "A0RvZDEQMA4GA1UECxMHVGVzdGluZzEVMBMGA1UEAxMMQ0ExLUNQLjAzLjAzMIGfMA0GCS" + "qGSIb3DQEBAQUAA4GNADCBiQKBgQCjLYKGKEMJgC/r0NH7vubQZ5qPEFEEN6QdLUWWqf/O" + "Yqo9hboQq6S8dFHp3DVR5x/4NOdNRjsTABbXsnz8U+L7+4CorhDhXj29weGMYIIfJ3XSIb" + "T7sE/GOPmXeGhrTv2zucI1j80sN5nTEoiGFm10LQqAgoyV46BxDltf3/D7wwIDAQABo2Mw" + "YTAPBgNVHRMBAf8EBTADAQH/MA4GA1UdDwEB/wQEAwIBBjAWBgNVHSAEDzANMAsGCWCGSA" + "FlAwEwATARBgNVHQ4ECgQIhCIOyzfScpAwEwYDVR0jBAwwCoAIq5rr+cLnVI8wDQYJKoZI" + "hvcNAQEFBQADgYEAA18kQijoJebmTQS7n/q/fQx2iblOJaJAWQLHeGCCGqKxCjUpOxuD+y" + "xMspmTKdQqEkqQ5vpHdFYQ5MYuecqAdp6woWUNQGVd4HHPmHsAW3Oppwb0yLggYs8IVHjm" + "dNO1pYb+YYciCKBtX8D1OnedIRcrQmDMJUjbfmAEv/4b0EM="; public static final String Intermediate_CRL_CP_03_03_crl = "MIIBSzCBtQIBATANBgkqhkiG9w0BAQUFADBeMQswCQYDVQQGEwJVUzEYMBYGA1UEChMPVS" + "5TLiBHb3Zlcm5tZW50MQwwCgYDVQQLEwNEb2QxEDAOBgNVBAsTB1Rlc3RpbmcxFTATBgNV" + "BAMTDENBMS1DUC4wMy4wMxcNOTkwMTAxMTIwMTAwWhcNNDgwMTAxMTIwMTAwWqAjMCEwCg" + "YDVR0UBAMCAQEwEwYDVR0jBAwwCoAIhCIOyzfScpAwDQYJKoZIhvcNAQEFBQADgYEAk34j" + "SxMr8p1h1qJWlfoh4er9pu1AkkHujovan6Ctx89VwFdOS5Kw82OCvD+nmJAHrFuncNlClf" + "51G8FCEAFLhMNwic4WAxrBX15hcUTaWk8Wj00dfUFwjG8/Kv3QUCDBN8f3KC8/oBeORRX9" + "dHW5ei2IUKuD1ITCeIoyRDBxQIg="; public static final String End_Certificate_CP_03_03_crt = "MIIChjCCAe+gAwIBAgIBFjANBgkqhkiG9w0BAQUFADBeMQswCQYDVQQGEwJVUzEYMBYGA1" + "UEChMPVS5TLiBHb3Zlcm5tZW50MQwwCgYDVQQLEwNEb2QxEDAOBgNVBAsTB1Rlc3Rpbmcx" + "FTATBgNVBAMTDENBMS1DUC4wMy4wMzAeFw05ODAxMDExMjAxMDBaFw01MDA3MDExMjAxMD" + "BaMGAxCzAJBgNVBAYTAlVTMRgwFgYDVQQKEw9VLlMuIEdvdmVybm1lbnQxDDAKBgNVBAsT" + "A0RvRDEQMA4GA1UECxMHVGVzdGluZzEXMBUGA1UEAxMOVXNlcjEtQ1AuMDMuMDMwgZ8wDQ" + "YJKoZIhvcNAQEBBQADgY0AMIGJAoGBALSw1Ey7kzFzzjMS4oTSrZH/95NMHLxtUSaVGMCy" + "0q2iLfGZ79eTS9megQUranYlIuK411yvFtskbFKf0idMKBtM8nX3Rxubm5EnbnpgvNrBEg" + "0FbOPqpSaR+8pxZ6lweB45tkzLU3OZeAZSpGOY1UvT/htn6Ae8JQAVajSvYyfNAgMBAAGj" + "UjBQMA4GA1UdDwEB/wQEAwIF4DAWBgNVHSAEDzANMAsGCWCGSAFlAwEwATARBgNVHQ4ECg" + "QIF014kOHikvcwEwYDVR0jBAwwCoAIhCIOyzfScpAwDQYJKoZIhvcNAQEFBQADgYEAdLMM" + "zGPPvBLgPbhn2tba/7HiaZaayHIxTXmpW0KAhP+8hwapOitrtLGPwqVtxQ3GoSMZJPMDCV" + "WsrT3OZm27G6ytqqNZ2ZO49UC7WwQ49TVlN79Ui9RZIBnRzlMIDNKsyuohfSRhFZTkWdoH" + "/y8ulY8k4xBThV8e8IRgtYj3nhc="; public static final String[] TEST_11_DATA = new String[] { Intermediate_Certificate_CP_03_03_crt, Intermediate_CRL_CP_03_03_crl, End_Certificate_CP_03_03_crt }; /* * test12 * */ public static final String Intermediate_Certificate_CP_03_04_crt = "MIIClTCCAf6gAwIBAgIBFzANBgkqhkiG9w0BAQUFADBeMQswCQYDVQQGEwJVUzEYMBYGA1" + "UEChMPVS5TLiBHb3Zlcm5tZW50MQwwCgYDVQQLEwNEb0QxEDAOBgNVBAsTB1Rlc3Rpbmcx" + "FTATBgNVBAMTDFRydXN0IEFuY2hvcjAeFw05ODAxMDExMjAxMDBaFw00ODAxMDExMjAxMD" + "BaMF4xCzAJBgNVBAYTAlVTMRgwFgYDVQQKEw9VLlMuIEdvdmVybm1lbnQxDDAKBgNVBAsT" + "A0RvZDEQMA4GA1UECxMHVGVzdGluZzEVMBMGA1UEAxMMQ0ExLUNQLjAzLjA0MIGfMA0GCS" + "qGSIb3DQEBAQUAA4GNADCBiQKBgQDbUii3czeUQ2zNlxvrhnJ0LcBGxCDHFr3xx+plDg3f" + "uasDKCY/VjCLEfQ5a2oqcovvGKsd2CPXbCFJtimW1R7Dvt+a0y95fppsdseorYDikiBlOj" + "ja6LR3Cz3bslYc133C+W/MKHMJ0tdvtTk+SJrq7lqs+iv/b/xHC3k/gDjIswIDAQABo2Mw" + "YTAPBgNVHRMBAf8EBTADAQH/MA4GA1UdDwEB/wQEAwIBBjAWBgNVHSAEDzANMAsGCWCGSA" + "FlAwEwATARBgNVHQ4ECgQIFNw3o1kc4XkwEwYDVR0jBAwwCoAIq5rr+cLnVI8wDQYJKoZI" + "hvcNAQEFBQADgYEAn/pr7/noYyjXSKEe/eLk3l4Rb6PEhNAnzySmxGkjIjWKAgh5IVYSGV" + "KFO/FaNOiYkRFHwXZFNj71q7gbM+HwALurN0Mr/MUA1TSpPy7YhFL0SWq3C3XsC/dVJ50b" + "HmTW+dGcxboX0h9HeKFxp3VyOY/dUut2oc+s/TnmqQII1CU="; public static final String Intermediate_CRL_CP_03_04_crl = "MIIBSzCBtQIBATANBgkqhkiG9w0BAQUFADBeMQswCQYDVQQGEwJVUzEYMBYGA1UEChMPVS" + "5TLiBHb3Zlcm5tZW50MQwwCgYDVQQLEwNEb2QxEDAOBgNVBAsTB1Rlc3RpbmcxFTATBgNV" + "BAMTDENBMS1DUC4wMy4wNBcNOTkwMTAxMTIwMTAwWhcNNDgwMTAxMTIwMTAwWqAjMCEwCg" + "YDVR0UBAMCAQEwEwYDVR0jBAwwCoAIFNw3o1kc4XkwDQYJKoZIhvcNAQEFBQADgYEAMoJ5" + "jGE1AxxfluixG8Sk7H4W2rqSEkQyNHfnlKSMbh9KZA3evI8HGKGGfkbBNoe4/HauZ4NVFw" + "FXgllCp+TI8Qd+HafFoDv6ff1K7T86p6r7tE3AEM1XmbnfohP3/ivpIzustv/f2rqjxILK" + "Ldvrth2/OlNygwY+D54lcWH1DX8="; public static final String End_Certificate_CP_03_04_crt = "MIICiDCCAfGgAwIBAgIBGDANBgkqhkiG9w0BAQUFADBeMQswCQYDVQQGEwJVUzEYMBYGA1" + "UEChMPVS5TLiBHb3Zlcm5tZW50MQwwCgYDVQQLEwNEb2QxEDAOBgNVBAsTB1Rlc3Rpbmcx" + "FTATBgNVBAMTDENBMS1DUC4wMy4wNDAgFw05ODAxMDExMjAxMDBaGA8yMDUwMDEwMTEyMD" + "EwMFowYDELMAkGA1UEBhMCVVMxGDAWBgNVBAoTD1UuUy4gR292ZXJubWVudDEMMAoGA1UE" + "CxMDRG9EMRAwDgYDVQQLEwdUZXN0aW5nMRcwFQYDVQQDEw5Vc2VyMS1DUC4wMy4wNDCBnz" + "ANBgkqhkiG9w0BAQEFAAOBjQAwgYkCgYEAuSL9tB1JW6JPUO2Xw6TMYkPX41lru3EPyYko" + "YgXy4giy6LGoqbgtskHehD22v3rfWjqOd9iV2PBio/vYE4zEz0H0n84dpnBvog6A1AlE19" + "PkQ1txjzIA52FQIRwRfZ38LaulQEfJ0a+fiRHQiM960O3YvHXV+GEbNcw4jo8b0sUCAwEA" + "AaNSMFAwDgYDVR0PAQH/BAQDAgXgMBYGA1UdIAQPMA0wCwYJYIZIAWUDATABMBEGA1UdDg" + "QKBAh9/WgM+UT6bTATBgNVHSMEDDAKgAgU3DejWRzheTANBgkqhkiG9w0BAQUFAAOBgQDR" + "I6PKUGg876/fSljtqxXCR4CoGAAurNFOcM4EWeoc6ZvuDOi3P7rNYiYAXXlmp7epOAgvZP" + "EV4vS16ODaJO6qIMR1YsaGEPo0ecT2pEStvP37X6pb5TdyjyKYF3586IN6TJdFMFsW/Lqg" + "tucl9bGlWmfTVwxTexq6+D8diK48KQ=="; public static final String[] TEST_12_DATA = new String[] { Intermediate_Certificate_CP_03_04_crt, Intermediate_CRL_CP_03_04_crl, End_Certificate_CP_03_04_crt }; /* * test13 * */ public static final String Intermediate_Certificate_CP_04_01_crt = "MIIClTCCAf6gAwIBAgIBGTANBgkqhkiG9w0BAQUFADBeMQswCQYDVQQGEwJVUzEYMBYGA1" + "UEChMPVS5TLiBHb3Zlcm5tZW50MQwwCgYDVQQLEwNEb0QxEDAOBgNVBAsTB1Rlc3Rpbmcx" + "FTATBgNVBAMTDFRydXN0IEFuY2hvcjAeFw05ODAxMDExMjAxMDBaFw00ODAxMDExMjAxMD" + "BaMF4xCzAJBgNVBAYTAlVTMRgwFgYDVQQKEw9VLlMuIEdvdmVybm1lbnQxDDAKBgNVBAsT" + "A0RvZDEQMA4GA1UECxMHVGVzdGluZzEVMBMGA1UEAxMMQ0ExLUNQLjA0LjAxMIGfMA0GCS" + "qGSIb3DQEBAQUAA4GNADCBiQKBgQC5UJ+KMj8tAmzr3OGYL2gSFcNTf8ik+ZVxlaPVGHyS" + "KjYQBAEbefhfg5Ps2aIuqBwYkbtFXuHif5GEhgObA4InCyESeRjYLGcVMqwSZzAOFAR0dP" + "1LzgzQs3ZgG9JX5MO5wEZ8IMnVN4Otu4XIlWSgIpUNS2vyet8Zi7t9fX+JewIDAQABo2Mw" + "YTAPBgNVHRMBAf8EBTADAQH/MA4GA1UdDwEB/wQEAwIBBjAWBgNVHSAEDzANMAsGCWCGSA" + "FlAwEwATARBgNVHQ4ECgQIOZvfph4Uu9YwEwYDVR0jBAwwCoAIq5rr+cLnVI8wDQYJKoZI" + "hvcNAQEFBQADgYEAXMyscmGpKSLG3hQltMQLegy0+g5wzgOrbFOWxZmiVNR+zSsHDD3UAH" + "H4SyTozlooC0jAY4yAhZ5RX6SSJKx9fHsOZD9ldCmst14qLk3pkI+M0QiPBZkVTx5/7dR2" + "wGkuNKSVWH6woOq7BbEzpO7xMlrUr6tgHt4Dc6Evt1pVZls="; public static final String Intermediate_CRL_CP_04_01_crl = "MIIBSzCBtQIBATANBgkqhkiG9w0BAQUFADBeMQswCQYDVQQGEwJVUzEYMBYGA1UEChMPVS" + "5TLiBHb3Zlcm5tZW50MQwwCgYDVQQLEwNEb2QxEDAOBgNVBAsTB1Rlc3RpbmcxFTATBgNV" + "BAMTDENBMS1DUC4wNC4wMRcNOTkwMTAxMTIwMTAwWhcNNDgwMTAxMTIwMTAwWqAjMCEwCg" + "YDVR0UBAMCAQEwEwYDVR0jBAwwCoAIOZvfph4Uu9YwDQYJKoZIhvcNAQEFBQADgYEAe79z" + "iEUgP/mvouJ9ufit1y4SjnHQWik75W65eGn/XGArRrBqJ8jZVJE4/rpDBbzm2V0hQoWU8z" + "zchZFlesUyqQZ9KUlT0YGR0YPcNw/V+58RonWWfmU3M2DvWDrXgCOXPm61+AYq4+kTowsG" + "0stmeML6NxjDzWpfAgI/MpXqe80="; public static final String End_Certificate_CP_04_01_crt = "MIIChjCCAe+gAwIBAgIBGjANBgkqhkiG9w0BAQUFADBeMQswCQYDVQQGEwJVUzEYMBYGA1" + "UEChMPVS5TLiBHb3Zlcm5tZW50MQwwCgYDVQQLEwNEb2QxEDAOBgNVBAsTB1Rlc3Rpbmcx" + "FTATBgNVBAMTDENBMS1DUC45OS45OTAeFw05ODAxMDExMjAxMDBaFw00ODAxMDExMjAxMD" + "BaMGAxCzAJBgNVBAYTAlVTMRgwFgYDVQQKEw9VLlMuIEdvdmVybm1lbnQxDDAKBgNVBAsT" + "A0RvRDEQMA4GA1UECxMHVGVzdGluZzEXMBUGA1UEAxMOVXNlcjEtQ1AuMDQuMDEwgZ8wDQ" + "YJKoZIhvcNAQEBBQADgY0AMIGJAoGBAPiAZKXPjK8jvaNj34VynyKPK7dQtFysBPKFW5Y1" + "Bc+OMsyd2pPpQoJYcQTMMomlAqoBvSXUJCMNly/BxVuvn7l6I9crtx6PjBBUlEzdcsscaa" + "EaHuCCVl+Msnr66cSV3GqVGAhujun81+lyurcTEog3ftsohwbQnfA76qNU/N3/AgMBAAGj" + "UjBQMA4GA1UdDwEB/wQEAwIF4DAWBgNVHSAEDzANMAsGCWCGSAFlAwEwATARBgNVHQ4ECg" + "QIJZPDbf2xNv8wEwYDVR0jBAwwCoAIOZvfph4Uu9YwDQYJKoZIhvcNAQEFBQADgYEAZf4L" + "1RDHDXwwA2CgcIhM4CAfZ72CR2zOan0at38VVFB3u9vs4VLwFcrOQCIjDbdLijc0XWLima" + "4vCD1qrsv6Hk5+6113HfFNmD8mp6X5jAwoNPa/I4kmFOA8iIm4TTk7M75vQyCQTPG0VzbU" + "Nu3uwTbXKm5ME9C5MFMf7z347CM="; public static final String[] TEST_13_DATA = new String[] { Intermediate_Certificate_CP_04_01_crt, Intermediate_CRL_CP_04_01_crl, End_Certificate_CP_04_01_crt }; /* * test14 * */ public static final String Intermediate_Certificate_CP_04_02_crt = "MIIClTCCAf6gAwIBAgIBGzANBgkqhkiG9w0BAQUFADBeMQswCQYDVQQGEwJVUzEYMBYGA1" + "UEChMPVS5TLiBHb3Zlcm5tZW50MQwwCgYDVQQLEwNEb0QxEDAOBgNVBAsTB1Rlc3Rpbmcx" + "FTATBgNVBAMTDFRydXN0IEFuY2hvcjAeFw05ODAxMDExMjAxMDBaFw00ODAxMDExMjAxMD" + "BaMF4xCzAJBgNVBAYTAlVTMRgwFgYDVQQKEw9VLlMuIEdvdmVybm1lbnQxDDAKBgNVBAsT" + "A0RvRDEQMA4GA1UECxMHVGVzdGluZzEVMBMGA1UEAxMMQ0ExLUNQLjA0LjAyMIGfMA0GCS" + "qGSIb3DQEBAQUAA4GNADCBiQKBgQCteErspc5ekSOel/wmjn/XQ0HUy4XzxB5Zj0nGn9FD" + "PbjF2LERCHOn5aBnIMHYhyr7PDynwbvSx2egzGC6wGe9Zrri1MteirQ9Ppw7062IIleloy" + "UAiuwvD+s0npKsvboarQsCMfOB1hOB1tGG1bjXP6B5B187SZXuR3KawggyJwIDAQABo2Mw" + "YTAPBgNVHRMBAf8EBTADAQH/MA4GA1UdDwEB/wQEAwIBBjAWBgNVHSAEDzANMAsGCWCGSA" + "FlAwEwATARBgNVHQ4ECgQIUjnGp96itUMwEwYDVR0jBAwwCoAIq5rr+cLnVI8wDQYJKoZI" + "hvcNAQEFBQADgYEAR6fmN+9p5AWy/asEAiVBnbY9q7EQXyB8WuZK9FtFmupe3hlfcTq84E" + "A+TGvXOlNr05/1iLRv82GsWXDif7DlGVPN8CS1+0kb5Ve8Pmv2ziiWVREqWx916ioPjDRp" + "wvdGcCNC26+fyvv5TrP8uzojurl1ZlVRRqi2sIbopVX5r8w="; public static final String Intermediate_CRL_CP_04_02_crl = "MIIBSzCBtQIBATANBgkqhkiG9w0BAQUFADBeMQswCQYDVQQGEwJVUzEYMBYGA1UEChMPVS" + "5TLiBHb3Zlcm5tZW50MQwwCgYDVQQLEwNEb0QxEDAOBgNVBAsTB1Rlc3RpbmcxFTATBgNV" + "BAMTDENBMS1DUC4wNC4wMhcNOTkwMTAxMTIwMTAwWhcNNDgwMTAxMTIwMTAwWqAjMCEwCg" + "YDVR0UBAMCAQEwEwYDVR0jBAwwCoAIUjnGp96itUMwDQYJKoZIhvcNAQEFBQADgYEAZkXJ" + "aJG4QDE02wFURwaxWuv2VyD7m+N/2B0/9KR+6UKVpsMd2XHq+G3SlFOa6dA/fHUdhtUs2D" + "gpx3SfQYbcgKFrryZHqJDK230eP3F41S9g5XJTRaNR5iZvxvh4bmSf4l6a5MXsKEoBoJoT" + "j8cU4qg6j7Xk4NpIR1JbWiSIYQc="; public static final String End_Certificate_CP_04_02_crt = "MIIChjCCAe+gAwIBAgIBHDANBgkqhkiG9w0BAQUFADBeMQswCQYDVQQGEwJVUzEYMBYGA1" + "UEChMPVS5TLiBHb3Zlcm5tZW50MRAwDgYDVQQLEwdUZXN0aW5nMQwwCgYDVQQLEwNEb0Qx" + "FTATBgNVBAMTDENBMS1DUC4wNC4wMjAeFw05ODAxMDExMjAxMDBaFw00ODAxMDExMjAxMD" + "BaMGAxCzAJBgNVBAYTAlVTMRgwFgYDVQQKEw9VLlMuIEdvdmVybm1lbnQxDDAKBgNVBAsT" + "A0RvRDEQMA4GA1UECxMHVGVzdGluZzEXMBUGA1UEAxMOVXNlcjEtQ1AuMDQuMDIwgZ8wDQ" + "YJKoZIhvcNAQEBBQADgY0AMIGJAoGBALM7mfq+hpLfvQdqZUJfIx/2gFcgHS2AsgZn0An+" + "Yn61WtG8K2+lt/a8aypa/q+J93RVkRYKWKFQcJHiRgx7DMlXElVnfQbSFuLX46ng4hqmQL" + "sSOKmXDld2BlyMZ41B3rfdhJT8P12RMR6uAwvc9CH3b0UTcsc498Kj+JeaRbzxAgMBAAGj" + "UjBQMA4GA1UdDwEB/wQEAwIF4DAWBgNVHSAEDzANMAsGCWCGSAFlAwEwATARBgNVHQ4ECg" + "QIo7S64S6t5nswEwYDVR0jBAwwCoAIUjnGp96itUMwDQYJKoZIhvcNAQEFBQADgYEApNT5" + "Y+9Jc28m5Qwjm+/8SKk83iCPnIW3BsAvQUB9Wmd1+kMZvqLySQjm1tBBbcGYuSERMJ2Et5" + "eoTdL9B6EG2CZYnPqu1vk0TVugRxs7IJm4h5z4MCInf2g1KTt0AMEasQW6ZTj7DIkkU48Z" + "EKLPoBGXfD9t9Y9cmdj1e1RQbog="; public static final String[] TEST_14_DATA = new String[] { Intermediate_Certificate_CP_04_02_crt, Intermediate_CRL_CP_04_02_crl, End_Certificate_CP_04_02_crt }; /* * test15 * */ public static final String Intermediate_Certificate_CP_04_03_crt = "MIICmzCCAgSgAwIBAgIBHTANBgkqhkiG9w0BAQUFADBeMQswCQYDVQQGEwJVUzEYMBYGA1" + "UEChMPVS5TLiBHb3Zlcm5tZW50MQwwCgYDVQQLEwNEb0QxEDAOBgNVBAsTB1Rlc3Rpbmcx" + "FTATBgNVBAMTDFRydXN0IEFuY2hvcjAeFw05ODAxMDExMjAxMDBaFw00ODAxMDExMjAxMD" + "BaMGQxCzAJBgNVBAYTAlVTMRgwFgYDVQQKEw9VLlMuIEdvdmVybm1lbnQxDDAKBgNVBAsT" + "A0RvZDEQMA4GA1UECxMHVGVzdGluZzEbMBkGA1UEAxMSICBDQTEgLSAgIENQLjA0LjAzMI" + "GfMA0GCSqGSIb3DQEBAQUAA4GNADCBiQKBgQD11QBcw4P2rTUfPmbVNYqdo0AMmcB3Yxsx" + "Iz5me/S1I2PJLtRh9KP7lUV20SMEFsFKtE1C+9O7ODtOUCJA/6ECeXbyj20SbG1E2oQrZe" + "gkcn7IQDUgnuedzdFj4kTevok6ao9hycg+qeZrL6oeBD2XQCd9nqMmzhihNu/QOSnp5wID" + "AQABo2MwYTAPBgNVHRMBAf8EBTADAQH/MA4GA1UdDwEB/wQEAwIBBjAWBgNVHSAEDzANMA" + "sGCWCGSAFlAwEwATARBgNVHQ4ECgQInx+ELo31rJMwEwYDVR0jBAwwCoAIq5rr+cLnVI8w" + "DQYJKoZIhvcNAQEFBQADgYEAriYMoRDpSPI4HWrxN1rjqWIzggz8p1wpbEFgK5o/Fi2KT3" + "jCd6bfCcIFDpoXNqlsc+dvzc4XB1Eg/Qbcror8HP8LSxrbFw/y7VhC+wCaDCmhcqQn3rp/" + "WaOWnR7/H7HlKM9m1u7MBtwlxHINnLKwPHIA1XwmAnItAXIL2yHRJhU="; public static final String Intermediate_CRL_CP_04_03_crl = "MIIBUTCBuwIBATANBgkqhkiG9w0BAQUFADBkMQswCQYDVQQGEwJVUzEYMBYGA1UEChMPVS" + "5TLiBHb3Zlcm5tZW50MQwwCgYDVQQLEwNEb2QxEDAOBgNVBAsTB1Rlc3RpbmcxGzAZBgNV" + "BAMTEiAgQ0ExIC0gICBDUC4wNC4wMxcNOTkwMTAxMTIwMTAwWhcNNDgwMTAxMTIwMTAwWq" + "AjMCEwCgYDVR0UBAMCAQEwEwYDVR0jBAwwCoAInx+ELo31rJMwDQYJKoZIhvcNAQEFBQAD" + "gYEAvJgOX6tewnRbC9Ch+Fe4KjkB9IAhe5anQKGfnDHuLfga6JEjOzyfhonWZeppJwvYpl" + "1rZbsKICNphMDkd/eaWnn8Q9w02ah4kzIb0LuzrNBrxpFv9AAidfGU2VeF0gRi02jtAZsh" + "gUNbrdC+ovA8mAsBigy+HMzCi61+wrumwvo="; public static final String End_Certificate_CP_04_03_crt = "MIICijCCAfOgAwIBAgIBHjANBgkqhkiG9w0BAQUFADBiMQswCQYDVQQGEwJVUzEYMBYGA1" + "UEChMPVS5TLiBHb3Zlcm5tZW50MQwwCgYDVQQLEwNEb2QxEDAOBgNVBAsTB1Rlc3Rpbmcx" + "GTAXBgNVBAMTEGNhMSAtIENQLjA0LjAzICAwHhcNOTgwMTAxMTIwMTAwWhcNNDgwMTAxMT" + "IwMTAwWjBgMQswCQYDVQQGEwJVUzEYMBYGA1UEChMPVS5TLiBHb3Zlcm5tZW50MQwwCgYD" + "VQQLEwNEb0QxEDAOBgNVBAsTB1Rlc3RpbmcxFzAVBgNVBAMTDlVzZXIxLUNQLjA0LjAzMI" + "GfMA0GCSqGSIb3DQEBAQUAA4GNADCBiQKBgQC2Rd0VKnTIrME7hzpnpIPGXGXZCjpf5lSO" + "19zvB3WdZumLGdwUBXpIQTrl5teYgL62PpOwNC93URZDEUt+rqoqvs8E7MpF3IulStp2+H" + "/xa6Ihf4OmkgKjpHNTWOIFXeRJ4sVgWuH6cqQ+6GL+0fa1sed1crsEgTTAGYNhFi6ebwID" + "AQABo1IwUDAOBgNVHQ8BAf8EBAMCBeAwFgYDVR0gBA8wDTALBglghkgBZQMBMAEwEQYDVR" + "0OBAoECBNwCFdDgPCqMBMGA1UdIwQMMAqACJ8fhC6N9ayTMA0GCSqGSIb3DQEBBQUAA4GB" + "ABAjSPg794yiVz9RqdNxic8TGnApNrZui/vwr1U8ZkETZfx8W1fWgQ0z7KjryML5IOmvps" + "zycM7by6jb2kMmxI1SQCwjiNQ1fb1osrNAj2bRfpp2YgjjbHx1XkddommtVc0V8kvyQBcb" + "7NdxfbwKr8AtpiWTWIajc2uqUlELsLzr"; public static final String[] TEST_15_DATA = new String[] { Intermediate_Certificate_CP_04_03_crt, Intermediate_CRL_CP_04_03_crl, End_Certificate_CP_04_03_crt }; /* * test16 * */ public static final String Intermediate_Certificate_CP_04_04_crt = "MIIClzCCAgCgAwIBAgIBHzANBgkqhkiG9w0BAQUFADBeMQswCQYDVQQGEwJVUzEYMBYGA1" + "UEChMPVS5TLiBHb3Zlcm5tZW50MQwwCgYDVQQLEwNEb0QxEDAOBgNVBAsTB1Rlc3Rpbmcx" + "FTATBgNVBAMTDFRydXN0IEFuY2hvcjAeFw05ODAxMDExMjAxMDBaFw00ODAxMDExMjAxMD" + "BaMGAxCzAJBgNVBAYTAlVTMRgwFgYDVQQKEw9VLlMuIEdvdmVybm1lbnQxDDAKBgNVBAsT" + "A0RvZDEQMA4GA1UECxMHVGVzdGluZzEXMBUGA1UEAxMOQ0ExIC0gQ1AuMDQuMDQwgZ8wDQ" + "YJKoZIhvcNAQEBBQADgY0AMIGJAoGBAOFf5hr4R8IqTp53qQSiBEjOFQ3Q3ICcafl+FLzm" + "K3xIFqERjyXARsTM4gDQ9yntFeNp2TiIi98xBrz7D8TlrbTAmxO/PUfAQ68tXpz9Id/XrU" + "WeAKxMZULPL9nPFcGQoh0qq3JKpFRSb3Iobryfysblm7cCDDCJOI7uK14XZtTFAgMBAAGj" + "YzBhMA8GA1UdEwEB/wQFMAMBAf8wDgYDVR0PAQH/BAQDAgEGMBYGA1UdIAQPMA0wCwYJYI" + "ZIAWUDATABMBEGA1UdDgQKBAjior7qCuLBljATBgNVHSMEDDAKgAirmuv5wudUjzANBgkq" + "hkiG9w0BAQUFAAOBgQBhh55gTy5htqjxW1Ch2hRrRikhBH7LJz1PmDuzwiIOtnWL+EiQOY" + "T6h3NV1j8Kn5S4KhUOrhnvrPXRi22HdqRzEPl7y/wXm6G0XcgYlyy2ofZKdYVWCVStKAMW" + "5SwV2wC5RPK2KphdhnlEqss6QVRUsliDDjnf9Saiey9nzJAfNw=="; public static final String Intermediate_CRL_CP_04_04_crl = "MIIBTTCBtwIBATANBgkqhkiG9w0BAQUFADBgMQswCQYDVQQGEwJVUzEYMBYGA1UEChMPVS" + "5TLiBHb3Zlcm5tZW50MQwwCgYDVQQLEwNEb2QxEDAOBgNVBAsTB1Rlc3RpbmcxFzAVBgNV" + "BAMTDkNBMSAtIENQLjA0LjA0Fw05OTAxMDExMjAxMDBaFw00ODAxMDExMjAxMDBaoCMwIT" + "AKBgNVHRQEAwIBATATBgNVHSMEDDAKgAjior7qCuLBljANBgkqhkiG9w0BAQUFAAOBgQBI" + "VlXD5FnIiO8tavLJ8qo/qRhbBNgUbFBdAgAY6yVnFNP6YN4qPineYPN6NV1XdqNDrZh2Nz" + "GHzX3YDo1Uv9yABVR0NvXCaMIW5/raqZp/on6bPuQLgJe9UisOPKunzehTm/NmO1RW9dwU" + "37UzC0XnVHyVipDVh07DrTKBUtQJQw=="; public static final String End_Certificate_CP_04_04_crt = "MIICjTCCAfagAwIBAgIBIDANBgkqhkiG9w0BAQUFADBlMQswCQYDVQQGEwJVUzEZMBcGA1" + "UEChMQVS5TLiAgR292ZXJubWVudDEMMAoGA1UECxMDRG9EMRAwDgYDVQQLEwdUZXN0aW5n" + "MRswGQYDVQQDExJDQTEgICAgLSAgQ1AuMDQuMDQwHhcNOTgwMTAxMTIwMTAwWhcNNDgwMT" + "AxMTIwMTAwWjBgMQswCQYDVQQGEwJVUzEYMBYGA1UEChMPVS5TLiBHb3Zlcm5tZW50MQww" + "CgYDVQQLEwNEb0QxEDAOBgNVBAsTB1Rlc3RpbmcxFzAVBgNVBAMTDlVzZXIxLUNQLjA0Lj" + "A0MIGfMA0GCSqGSIb3DQEBAQUAA4GNADCBiQKBgQCegy6qOnM14CS7+enBElgh2DLtF5bn" + "ah0yfA18/hbqnmUaWOWJQllyXa8QFawnvdXOOEXJm1ErIm3rDYihkbUTP+ybOBH9dprWtl" + "1cSGL9CkoxwzkJRLQTu5xG72EhET3S3kwqZsmYbgy4MduGKv9VGFbv75Wr17Vo9K4Lz6QK" + "vQIDAQABo1IwUDAOBgNVHQ8BAf8EBAMCBeAwFgYDVR0gBA8wDTALBglghkgBZQMBMAEwEQ" + "YDVR0OBAoECEc4b3BP059HMBMGA1UdIwQMMAqACOKivuoK4sGWMA0GCSqGSIb3DQEBBQUA" + "A4GBADj73jXpPLev5crwZIoXCJd/nXXp1fJzEEbByWggsR9cFHN4wnp7N6gpIxQbLQwjmo" + "cLPC1pHQ3A5VHVrCbxAk6nifmSvnKFWHTBftZGpfTGkrXbURFF64T/CB4O+JXr1eBUGheN" + "Q0T8L17UNgi3oBENKjASWnpjxvD2QrOnH0rb"; public static final String[] TEST_16_DATA = new String[] { Intermediate_Certificate_CP_04_04_crt, Intermediate_CRL_CP_04_04_crl, End_Certificate_CP_04_04_crt }; /* * test17 * */ public static final String Intermediate_Certificate_CP_04_05_crt = "MIIClzCCAgCgAwIBAgIBITANBgkqhkiG9w0BAQUFADBeMQswCQYDVQQGEwJVUzEYMBYGA1" + "UEChMPVS5TLiBHb3Zlcm5tZW50MQwwCgYDVQQLEwNEb0QxEDAOBgNVBAsTB1Rlc3Rpbmcx" + "FTATBgNVBAMTDFRydXN0IEFuY2hvcjAeFw05ODAxMDExMjAxMDBaFw00ODAxMDExMjAxMD" + "BaMGAxCzAJBgNVBAYTAlVTMRgwFgYDVQQKEw9VLlMuIEdvdmVybm1lbnQxDDAKBgNVBAsT" + "A0RvZDEQMA4GA1UECxMHVGVzdGluZzEXMBUGA1UEAxMOICBDQTEtQ1AuMDQuMDUwgZ8wDQ" + "YJKoZIhvcNAQEBBQADgY0AMIGJAoGBAMBsWmrcKH0J9bkI3zHthZ0S3904f3fMUSasY5qp" + "7CSQ0sbXTwP947sfAPK4Dso6Bpwl0WExRCdFHd6qfY9wR+NtfuI/DkFEY8WveoqM4Vskpi" + "cutWghCx14PiPY5YGFn8VvXu7wbuHp4TnHtUCMEUt3EfYO5oqm+/I8y0eTKMNHAgMBAAGj" + "YzBhMA8GA1UdEwEB/wQFMAMBAf8wDgYDVR0PAQH/BAQDAgEGMBYGA1UdIAQPMA0wCwYJYI" + "ZIAWUDATABMBEGA1UdDgQKBAjOoKlp+BfGqTATBgNVHSMEDDAKgAirmuv5wudUjzANBgkq" + "hkiG9w0BAQUFAAOBgQDLhQ/RJFqMDNRonAHZ30DYyphf8do4q6ARikhhXSSa6G2G/PzbpS" + "x3T+3G8ot+NnFhtf9ZWo7KfwmFEbUA/B/X2vJaJbNImkMDT1aTY5sPXtA69B3QKQVz7HST" + "f5XH6DjuoV0/m1M153A4vf1Z783dOPw1MzOq19t+6tYFeELEHQ=="; public static final String Intermediate_CRL_CP_04_05_crl = "MIIBTTCBtwIBATANBgkqhkiG9w0BAQUFADBgMQswCQYDVQQGEwJVUzEYMBYGA1UEChMPVS" + "5TLiBHb3Zlcm5tZW50MQwwCgYDVQQLEwNEb2QxEDAOBgNVBAsTB1Rlc3RpbmcxFzAVBgNV" + "BAMTDiAgQ0ExLUNQLjA0LjA1Fw05OTAxMDExMjAxMDBaFw00ODAxMDExMjAxMDBaoCMwIT" + "AKBgNVHRQEAwIBATATBgNVHSMEDDAKgAjOoKlp+BfGqTANBgkqhkiG9w0BAQUFAAOBgQAp" + "6gLCdPQw7Hisnr1i3QbD7GybqfD6b1s10GQ3c/j59RYDe1Fk47Srs9ol/baleasWjcdt8M" + "SlTc66KvK9YPFAqIdYoOW4FidpJBF/1cvSc2hGYwVsxLnXKr9CJ5Py5vBCCjovIRiLdzoL" + "ZoteOKFIEHkV7V8V2OTFawxpW9hkiA=="; public static final String End_Certificate_CP_04_05_crt = "MIICiDCCAfGgAwIBAgIBIjANBgkqhkiG9w0BAQUFADBgMQswCQYDVQQGEwJVUzEYMBYGA1" + "UEChMPVS5TLiBHb3Zlcm5tZW50MQwwCgYDVQQLEwNEb2QxEDAOBgNVBAsTB1Rlc3Rpbmcx" + "FzAVBgNVBAMTDkNBMS1DUC4wNC4wNSAgMB4XDTk4MDEwMTEyMDEwMFoXDTQ4MDEwMTEyMD" + "EwMFowYDELMAkGA1UEBhMCVVMxGDAWBgNVBAoTD1UuUy4gR292ZXJubWVudDEMMAoGA1UE" + "CxMDRG9EMRAwDgYDVQQLEwdUZXN0aW5nMRcwFQYDVQQDEw5Vc2VyMS1DUC4wNC4wNTCBnz" + "ANBgkqhkiG9w0BAQEFAAOBjQAwgYkCgYEAwZsiUhXiFHN9dfJb0Yyy+rYtV8gx+d0+8WkW" + "5C68nQgSqqk2uSTpvZbx0bpHF+s+LKppj2M2tt/AfZgVQHTsp5rO0IftZE2iLwqejj0rYU" + "Poprq1PE3vVhs818ZlDS0PTUP97YxLysQjq2jS/d/9lF5pS3sMlP4Usp24gXX0vG0CAwEA" + "AaNSMFAwDgYDVR0PAQH/BAQDAgXgMBYGA1UdIAQPMA0wCwYJYIZIAWUDATABMBEGA1UdDg" + "QKBAjpC0ZvCXrvBTATBgNVHSMEDDAKgAjOoKlp+BfGqTANBgkqhkiG9w0BAQUFAAOBgQB7" + "YwJWcx+PU1sUZUOVleoB5amHFu0GT+Hy7cRa82UJMHFkz0bmnyEV8CBNcnn0xa5iVfwe2y" + "5ZKwy61DLR3MPTar9eKITL67uZag9w+1tnIf594XRbEiUzn20uxuDFX3oPoZCemtWdVanj" + "2T+9TVQKfrp15+qzOCObNNRHZw29EA=="; public static final String[] TEST_17_DATA = new String[] { Intermediate_Certificate_CP_04_05_crt, Intermediate_CRL_CP_04_05_crl, End_Certificate_CP_04_05_crt }; /* * test18 * */ public static final String Intermediate_Certificate_CP_04_06_crt = "MIIClTCCAf6gAwIBAgIBIzANBgkqhkiG9w0BAQUFADBeMQswCQYDVQQGEwJVUzEYMBYGA1" + "UEChMPVS5TLiBHb3Zlcm5tZW50MQwwCgYDVQQLEwNEb0QxEDAOBgNVBAsTB1Rlc3Rpbmcx" + "FTATBgNVBAMTDFRydXN0IEFuY2hvcjAeFw05ODAxMDExMjAxMDBaFw00ODAxMDExMjAxMD" + "BaMF4xCzAJBgNVBAYTAlVTMRgwFgYDVQQKEw9VLlMuIEdvdmVybm1lbnQxDDAKBgNVBAsT" + "A0RvZDEQMA4GA1UECxMHVGVzdGluZzEVMBMGA1UEAxMMQ0ExLUNQLjA0LjA2MIGfMA0GCS" + "qGSIb3DQEBAQUAA4GNADCBiQKBgQD0t0dfe82Su58bJdn4dh7E3OCam1AUPTzPnt7DwT2w" + "1XwD76OCUYP7SBBjsLYDDfUCb2ek96pSK4jpzyE6/4IOtfObe7OW+iBT9YAB5WeW+SmvEO" + "TIX+xo13sbz6rG6j9svcOxtth98yv7mxzV/ZwTNBSO72CcfDXIIq20TVunlwIDAQABo2Mw" + "YTAPBgNVHRMBAf8EBTADAQH/MA4GA1UdDwEB/wQEAwIBBjAWBgNVHSAEDzANMAsGCWCGSA" + "FlAwEwATARBgNVHQ4ECgQI0AufZEn1f9AwEwYDVR0jBAwwCoAIq5rr+cLnVI8wDQYJKoZI" + "hvcNAQEFBQADgYEAbfhxuNBYizxfMZNcyiN61j+7LXZZo3SmMU21UmOhPBTmdTbIkuVCI+" + "F1jSWdu3eGShVNJ3jmkidDvojMm+E8ZZ1YGHYfgeG16dDQudaGUjGmOfYzzlkFmsaf0paG" + "4y4sBerPsZCmhN7BanGh3qYPFvadSmp3OapGfEmDtS+BbVQ="; public static final String Intermediate_CRL_CP_04_06_crl = "MIIBSzCBtQIBATANBgkqhkiG9w0BAQUFADBeMQswCQYDVQQGEwJVUzEYMBYGA1UEChMPVS" + "5TLiBHb3Zlcm5tZW50MQwwCgYDVQQLEwNEb2QxEDAOBgNVBAsTB1Rlc3RpbmcxFTATBgNV" + "BAMTDENBMS1DUC4wNC4wNhcNOTkwMTAxMTIwMTAwWhcNNDgwMTAxMTIwMTAwWqAjMCEwCg" + "YDVR0UBAMCAQEwEwYDVR0jBAwwCoAI0AufZEn1f9AwDQYJKoZIhvcNAQEFBQADgYEAIAI7" + "W6K69twJZnHx6CoIMs5+P9DrJ2yKHptmntlOCTSJirC/xdj0Zv2k5FW84VrTtdCSZDT1Ce" + "4Dh69fT2sUUexJb/4IcDtzloiuASSJzKWCeVIj9A8e6+coNUJVKtRKRX8bHJ5Un7xpFrY6" + "t1hdxt8gUecAAdXEFGuZ3QEHHN0="; public static final String End_Certificate_CP_04_06_crt = "MIIChjCCAe+gAwIBAgIBJDANBgkqhkiG9w0BAQUFADBeMQswCQYDVQQGEwJVUzEYMBYGA1" + "UEChMPdS5zLiBHT1ZFUk5NRU5UMQwwCgYDVQQLEwNEb0QxEDAOBgNVBAsTB1RFU1RJTkcx" + "FTATBgNVBAMTDGNhMS1DUC4wNC4wNjAeFw05ODAxMDExMjAxMDBaFw00ODAxMDExMjAxMD" + "BaMGAxCzAJBgNVBAYTAlVTMRgwFgYDVQQKEw9VLlMuIEdvdmVybm1lbnQxDDAKBgNVBAsT" + "A0RvRDEQMA4GA1UECxMHVGVzdGluZzEXMBUGA1UEAxMOVXNlcjEtQ1AuMDQuMDYwgZ8wDQ" + "YJKoZIhvcNAQEBBQADgY0AMIGJAoGBAKq8rAPXsu1RVm3vT7od7CDLn8k/C3x3wvfzoWrm" + "W0cmlhp9xRy5a3HWiJATD8yCKY1psBgnrOpv37sdtUX4P2kf668HrYOaGo365fKPeT5Wjm" + "gp0pL3sXKNNsCuJPd3wKAXGHAi1R9arZFYPsKJlfQl1774dwAvzxSOMr5+pbnzAgMBAAGj" + "UjBQMA4GA1UdDwEB/wQEAwIF4DAWBgNVHSAEDzANMAsGCWCGSAFlAwEwATARBgNVHQ4ECg" + "QI33MEYdo5YX4wEwYDVR0jBAwwCoAI0AufZEn1f9AwDQYJKoZIhvcNAQEFBQADgYEAo8Ge" + "ADBoJFEIRzdO37uasuyIBhClTUgyFhEKemMBN6aelYeiJMX6FZIL3DgZOce4dg7Zg3Ak/w" + "B5m8XlGQLW9xIbpEzY/Iq9kr+qK6k9YmvtcOiHFbnudCFNZngTQZpxjiDaj4eA48uqKIxs" + "51taC5gOv9LYWPnugN8TsUUFZ1s="; public static final String[] TEST_18_DATA = new String[] { Intermediate_Certificate_CP_04_06_crt, Intermediate_CRL_CP_04_06_crl, End_Certificate_CP_04_06_crt }; /* * test19 * */ public static final String Intermediate_Certificate_CP_05_01_crt = "MIIClTCCAf6gAwIBAgIBJTANBgkqhkiG9w0BAQUFADBeMQswCQYDVQQGEwJVUzEYMBYGA1" + "UEChMPVS5TLiBHb3Zlcm5tZW50MQwwCgYDVQQLEwNEb0QxEDAOBgNVBAsTB1Rlc3Rpbmcx" + "FTATBgNVBAMTDFRydXN0IEFuY2hvcjAeFw05ODAxMDExMjAxMDBaFw00ODAxMDExMjAxMD" + "BaMF4xCzAJBgNVBAYTAlVTMRgwFgYDVQQKEw9VLlMuIEdvdmVybm1lbnQxDDAKBgNVBAsT" + "A0RvZDEQMA4GA1UECxMHVGVzdGluZzEVMBMGA1UEAxMMQ0ExLUNQLjA1LjAxMIGfMA0GCS" + "qGSIb3DQEBAQUAA4GNADCBiQKBgQCshocJtyGsxeEd2ouVTVKp+HuhDjnDk9eXtaLQIKaB" + "7aTODHYbq1mC+1LO5DmRV5PBVd8NuuCA+1DmzFrfYl+nMCjjgOkC0//Gf9O85Hi/n21q0T" + "F+oVa1j9fc7nAgLIziexaXrflYSbaeNWkwHHftGUninKPuNGM2re0krEeurQIDAQABo2Mw" + "YTAPBgNVHRMBAf8EBTADAQH/MA4GA1UdDwEB/wQEAwIBBjAWBgNVHSAEDzANMAsGCWCGSA" + "FlAwEwATARBgNVHQ4ECgQIaUi/P20o4LcwEwYDVR0jBAwwCoAIq5rr+cLnVI8wDQYJKoZI" + "hvcNAQEFBQADgYEAWBLeJl4qlAPKxmBM5QZ2JYsbCV3VBeYGAKQ+4L7ehS63VQMCwIjBCI" + "LaHGIFfCqecDNd6cpYIArdx4tY7X2/Zxm3j5ocngpI1Tv8zydQcFeraILglsHf2UZUuK/N" + "6jKGjwL68C8YwmA+u6ZhcQFD2Xg4wSMC/xxzAs9zEAQGBPo="; public static final String End_Certificate_CP_05_01_crt = "MIIChjCCAe+gAwIBAgIBJjANBgkqhkiG9w0BAQUFADBeMQswCQYDVQQGEwJVUzEYMBYGA1" + "UEChMPVS5TLiBHb3Zlcm5tZW50MQwwCgYDVQQLEwNEb2QxEDAOBgNVBAsTB1Rlc3Rpbmcx" + "FTATBgNVBAMTDENBMS1DUC4wNS4wMTAeFw05ODAxMDExMjAxMDBaFw00ODAxMDExMjAxMD" + "BaMGAxCzAJBgNVBAYTAlVTMRgwFgYDVQQKEw9VLlMuIEdvdmVybm1lbnQxDDAKBgNVBAsT" + "A0RvRDEQMA4GA1UECxMHVGVzdGluZzEXMBUGA1UEAxMOVXNlcjEtQ1AuMDUuMDEwgZ8wDQ" + "YJKoZIhvcNAQEBBQADgY0AMIGJAoGBAO9ODA12Fky/Md5AELkaOvOwB31UlfZq3SHAOvs0" + "Y4NYoA7Q5KDIwW8RNzMSKD30z51VlgOAaBVR6HLo6rkcWB4wGiV7EPelewdSOdk72IrnYR" + "npJEm2KEuLkHB+gejgk+paw8CejxMsrvT6loN8Pz0btBKxWaCfknTIyXVyQsolAgMBAAGj" + "UjBQMA4GA1UdDwEB/wQEAwIF4DAWBgNVHSAEDzANMAsGCWCGSAFlAwEwATARBgNVHQ4ECg" + "QI5LtSKs/inGMwEwYDVR0jBAwwCoAIaUi/P20o4LcwDQYJKoZIhvcNAQEFBQADgYEAOMrC" + "38uzHckKMkiawXhPUHtDQfyR7bLweS2qro7GyndfxPpeMJwjzVxqvQBtMuHON+al8jyXpy" + "BsEryV6qvdFC1vczLzJHAJZmLe5np27zQIXOObsyYcOG+aPq727/pKoD90DAlBvrxNW0ox" + "x7citflEYpmOEv9Do5xiO3MuCFw="; public static final String[] TEST_19_DATA = new String[] { Intermediate_Certificate_CP_05_01_crt, End_Certificate_CP_05_01_crt }; /* * test20 * */ public static final String Intermediate_Certificate_CP_06_01_crt = "MIIClTCCAf6gAwIBAgIBJzANBgkqhkiG9w0BAQUFADBeMQswCQYDVQQGEwJVUzEYMBYGA1" + "UEChMPVS5TLiBHb3Zlcm5tZW50MQwwCgYDVQQLEwNEb0QxEDAOBgNVBAsTB1Rlc3Rpbmcx" + "FTATBgNVBAMTDFRydXN0IEFuY2hvcjAeFw05ODAxMDExMjAxMDBaFw00ODAxMDExMjAxMD" + "BaMF4xCzAJBgNVBAYTAlVTMRgwFgYDVQQKEw9VLlMuIEdvdmVybm1lbnQxDDAKBgNVBAsT" + "A0RvZDEQMA4GA1UECxMHVGVzdGluZzEVMBMGA1UEAxMMQ0ExLUNQLjA2LjAxMIGfMA0GCS" + "qGSIb3DQEBAQUAA4GNADCBiQKBgQDI4MXZB08BfUHxo//4Re7Ax0qWkHgy6nb+/XaLQ2Fw" + "Pbvpb5mkhLhqDZBSX3KQL0YiJ8p81tmdvRQH/LbFzX/3OKBTUfV5imYy979A2NEb4otFp6" + "EDSskZhttY3d2IzUICoCWUXhObnmkHJ2jEc81bggFkK5Lir1m/tKq2IOPFJQIDAQABo2Mw" + "YTAPBgNVHRMBAf8EBTADAQH/MA4GA1UdDwEB/wQEAwIBBjAWBgNVHSAEDzANMAsGCWCGSA" + "FlAwEwATARBgNVHQ4ECgQICIAmlz6+Cc0wEwYDVR0jBAwwCoAIq5rr+cLnVI8wDQYJKoZI" + "hvcNAQEFBQADgYEA0ZvIG2cnk32p6uxqGw8Bu40NrfHu9gNkJL5MhDHJXA6OxU5BX5bWZp" + "LnKXLoHiqSdtEdmy5cLZw3kggxndxjsnRFMyCawaYupJBhlgquFbuvBtA8rMtkc5H4zudP" + "ZcOcvXu7Xw58K+1caSGURL+A6uXFPnMUBd1+k+ejbtO8Pto="; public static final String Intermediate_CRL_CP_06_01_crl = "MIIBSzCBtQIBATANBgkqhkiG9w0BAQUFADBeMQswCQYDVQQGEwJVUzEYMBYGA1UEChMPVS" + "5TLiBHb3Zlcm5tZW50MQwwCgYDVQQLEwNEb2QxEDAOBgNVBAsTB1Rlc3RpbmcxFTATBgNV" + "BAMTDENBMS1DUC4wNi4wMRcNOTkwMTAxMTIwMTAwWhcNNDgwMTAxMTIwMTAwWqAjMCEwCg" + "YDVR0UBAMCAQEwEwYDVR0jBAwwCoAICIAmlz6+Cc0wDQYJKoZIhvcNAQEFBQADgYEAbkJe" + "jfc1rztCbtC6xJZ3iZEDDMW2CxFvOvSwhmCjPqVY3lrCPNSQzdjmqepioCnu7ongP+HAA7" + "hM7bm+SoN7KzXKufQ7C2ONoAwvoPZgnoidg7RVECxUByD6AJu04yd2wCLYRpCfS2tDtXLh" + "HEDpe+ELwv35pbkCMlCO2u7J+Tc="; public static final String End_Certificate_CP_06_01_crt = "MIIChjCCAe+gAwIBAgIBKDANBgkqhkiG9w0BAQUFADBeMQswCQYDVQQGEwJVUzEYMBYGA1" + "UEChMPVS5TLiBHb3Zlcm5tZW50MQwwCgYDVQQLEwNEb2QxEDAOBgNVBAsTB1Rlc3Rpbmcx" + "FTATBgNVBAMTDENBMS1DUC4wNi4wMTAeFw05ODAxMDExMjAxMDBaFw00ODAxMDExMjAxMD" + "BaMGAxCzAJBgNVBAYTAlVTMRgwFgYDVQQKEw9VLlMuIEdvdmVybm1lbnQxDDAKBgNVBAsT" + "A0RvRDEQMA4GA1UECxMHVGVzdGluZzEXMBUGA1UEAxMOVXNlcjEtQ1AuMDYuMDEwgZ8wDQ" + "YJKoZIhvcNAQEBBQADgY0AMIGJAoGBAOh7lUwMRet7t/ABI6mo27CsnRzQ64Xx7f1dqxrJ" + "NuuSRslVShaWnwiGHjc+5/TS7Urfj9VO0dseBCzPsyYFoIX1q7Q5zlArwy24qpXTGMmlpE" + "GByzi7jkXO8w5+wqh3+8RFrQQzr71zLtAVV/qPUyleuF8M8jzkwfPvawunmwdLAgMBAAGj" + "UjBQMA4GA1UdDwEB/wQEAwIF4DAWBgNVHSAEDzANMAsGCWCGSAFlAwEwATARBgNVHQ4ECg" + "QIayC0PPU9zyswEwYDVR0jBAwwCoAICIAmlz6+Cc0wDQYJKoZIhvcNAQEFBQADgYEAPz7b" + "UvaEV7Myjhe8LJO/soj84X71rvVPtBPrhYjWTJ6p69GCfJRyho3vAUIt8RFal1GFb72c45" + "DQGkcVzLLJw8cDP3ajtWac5HZ9dNPJkW+Kh12l9gqjn061XAjQ4XnbbwQDYCuXhguPE9v3" + "kzDbimwVwIEOB/4SARX37y7TUWk="; public static final String[] TEST_20_DATA = new String[] { Intermediate_Certificate_CP_06_01_crt, Intermediate_CRL_CP_06_01_crl, End_Certificate_CP_06_01_crt }; /* * test21 * */ public static final String Intermediate_Certificate_CP_06_02_crt = "MIIClTCCAf6gAwIBAgIBKTANBgkqhkiG9w0BAQUFADBeMQswCQYDVQQGEwJVUzEYMBYGA1" + "UEChMPVS5TLiBHb3Zlcm5tZW50MQwwCgYDVQQLEwNEb0QxEDAOBgNVBAsTB1Rlc3Rpbmcx" + "FTATBgNVBAMTDFRydXN0IEFuY2hvcjAeFw05ODAxMDExMjAxMDBaFw00ODAxMDExMjAxMD" + "BaMF4xCzAJBgNVBAYTAlVTMRgwFgYDVQQKEw9VLlMuIEdvdmVybm1lbnQxDDAKBgNVBAsT" + "A0RvZDEQMA4GA1UECxMHVGVzdGluZzEVMBMGA1UEAxMMQ0ExLUNQLjA2LjAyMIGfMA0GCS" + "qGSIb3DQEBAQUAA4GNADCBiQKBgQC/IejV3DmeaLW8OwMfAGyr5+8NOxM1C+UBYslbOfWj" + "KUGdhlX6TxFc5AOJVJBpS/QjeA+RWoUCxnxKb9QSlOrBmADrcnGz8zV0/c0JDLaU3oSgsV" + "EWZE0SexBVWrKcl1j7wN0RuxMeAp342/YoyvBwea3VeqJkmSCc7Y2TjruWEQIDAQABo2Mw" + "YTAPBgNVHRMBAf8EBTADAQH/MA4GA1UdDwEB/wQEAwIBBjAWBgNVHSAEDzANMAsGCWCGSA" + "FlAwEwATARBgNVHQ4ECgQIaHxWOdHsLbUwEwYDVR0jBAwwCoAIq5rr+cLnVI8wDQYJKoZI" + "hvcNAQEFBQADgYEAuzeq/lqp0qs62krK6EA81Silhy42l/KmynE3mVu9GPBgQS0BUDi7+r" + "QQ+m0UxYElzj2SNO4J5aBYeC98lVJFCHX7QE8yVOoPBQd5rA+rrz4HD9QoP7glxTqLU6Tc" + "9VFd+iaFpqsVtSh2bxH2BtUB2ARgebTklaNl5VPbu0+yc2I="; public static final String Intermediate_CRL_CP_06_02_crl = "MIIBbzCB2QIBATANBgkqhkiG9w0BAQUFADBeMQswCQYDVQQGEwJVUzEYMBYGA1UEChMPVS" + "5TLiBHb3Zlcm5tZW50MQwwCgYDVQQLEwNEb2QxEDAOBgNVBAsTB1Rlc3RpbmcxFTATBgNV" + "BAMTDENBMS1DUC4wNi4wMhcNOTkwMTAxMTIwMTAwWhcNNDgwMTAxMTIwMTAwWjAiMCACAS" + "oXDTk5MDEwMTEyMDAwMFowDDAKBgNVHRUEAwoBAaAjMCEwCgYDVR0UBAMCAQEwEwYDVR0j" + "BAwwCoAIaHxWOdHsLbUwDQYJKoZIhvcNAQEFBQADgYEAYGaAzVoUdlSZ3uGKiRPfHAFIoK" + "T79hNOvtOxaGA0aIek9OypDrDqYAh/s2jsXSheL0pr/v9WRIHvtCt7ytXDxVyn4Nxjpfv7" + "BkAMMiccdUx1OH1VElTRkmmtMe7ROzUeHUGzXJNPex1Bc9BvSChH18bWYckyOZdYJBjctC" + "KJFgw="; public static final String End_Certificate_CP_06_02_crt = "MIIChjCCAe+gAwIBAgIBKjANBgkqhkiG9w0BAQUFADBeMQswCQYDVQQGEwJVUzEYMBYGA1" + "UEChMPVS5TLiBHb3Zlcm5tZW50MQwwCgYDVQQLEwNEb2QxEDAOBgNVBAsTB1Rlc3Rpbmcx" + "FTATBgNVBAMTDENBMS1DUC4wNi4wMjAeFw05ODAxMDExMjAxMDBaFw00ODAxMDExMjAxMD" + "BaMGAxCzAJBgNVBAYTAlVTMRgwFgYDVQQKEw9VLlMuIEdvdmVybm1lbnQxDDAKBgNVBAsT" + "A0RvRDEQMA4GA1UECxMHVGVzdGluZzEXMBUGA1UEAxMOVXNlcjEtQ1AuMDYuMDIwgZ8wDQ" + "YJKoZIhvcNAQEBBQADgY0AMIGJAoGBAK4D9H8JxeIrFuOmx0cSkIYNS0p7cDSBlcc57Na3" + "+1k7lJD7mE9ZP6/47YsDVK2bwe4aTKCTXtPk/kGQ6bsLswJXbyW4k4+f5LeAYoXgbmZXjA" + "WF+BKIl8uKetsqC3HkCeqhBaY1AGUqef4oOAkakEP+1jYFumNYtMaB+9x/0ncBAgMBAAGj" + "UjBQMA4GA1UdDwEB/wQEAwIF4DAWBgNVHSAEDzANMAsGCWCGSAFlAwEwATARBgNVHQ4ECg" + "QIC9MiJNI71RMwEwYDVR0jBAwwCoAIaHxWOdHsLbUwDQYJKoZIhvcNAQEFBQADgYEAo/ib" + "mIxteityjZlszjCc/s7yM/0snL78pYpMOZ3P2TPKkYh2Th4+Bw8JqX10+M/zwFBj5Bw7Im" + "zCIRfS3GFuKmcVcyHB4OZLMcQZtXWA8GOZ94YvWq5TBINlVtThQtusQj15KBq2TJNNFUyD" + "pBdvyo05AnEsRY0HbIQu6ZhNQ40="; public static final String[] TEST_21_DATA = new String[] { Intermediate_Certificate_CP_06_02_crt, Intermediate_CRL_CP_06_02_crl, End_Certificate_CP_06_02_crt }; /* * test22 * */ public static final String Intermediate_Certificate_IC_01_01_crt = "MIIChDCCAe2gAwIBAgIBKzANBgkqhkiG9w0BAQUFADBeMQswCQYDVQQGEwJVUzEYMBYGA1" + "UEChMPVS5TLiBHb3Zlcm5tZW50MQwwCgYDVQQLEwNEb0QxEDAOBgNVBAsTB1Rlc3Rpbmcx" + "FTATBgNVBAMTDFRydXN0IEFuY2hvcjAeFw05ODAxMDExMjAxMDBaFw00ODAxMDExMjAxMD" + "BaMF4xCzAJBgNVBAYTAlVTMRgwFgYDVQQKEw9VLlMuIEdvdmVybm1lbnQxDDAKBgNVBAsT" + "A0RvZDEQMA4GA1UECxMHVGVzdGluZzEVMBMGA1UEAxMMQ0ExLUlDLjAxLjAxMIGfMA0GCS" + "qGSIb3DQEBAQUAA4GNADCBiQKBgQDDOu1J/VIzbB4VcS2Dwf2fsHOmIj3iatM8y61V7CrN" + "RCxCWTJ1Os8e/mFWOi/zN+0afizA0UzJDTe8L++/RlP68IFg5Ju2OhXqQC3HbUZmQ7ve9g" + "QdWTfur3oEJV6/XoVE4WG0Ic7D1p7BENb3LUT+8MJdSboTvAggA1CiOI6zRQIDAQABo1Iw" + "UDAOBgNVHQ8BAf8EBAMCAQYwFgYDVR0gBA8wDTALBglghkgBZQMBMAEwEQYDVR0OBAoECP" + "RyRiSV+4XrMBMGA1UdIwQMMAqACKua6/nC51SPMA0GCSqGSIb3DQEBBQUAA4GBAJlmJ9EW" + "9ujUosqHZyZkniu2vX8VOL52OnxtLxw3LqxLyuxivjyYCaMAaJNr7/xfm3C2ozh9mQyZTQ" + "6TpBapLFUH8QsEKUhy57MDUgIvZsyOvvjJh3AXfSkXDaMZ3ncLg6x0wwjN/Hxu9i+IhX1W" + "1E7/5foGx7AEVfwY7Fo9S82d"; public static final String Intermediate_CRL_IC_01_01_crl = "MIIBSzCBtQIBATANBgkqhkiG9w0BAQUFADBeMQswCQYDVQQGEwJVUzEYMBYGA1UEChMPVS" + "5TLiBHb3Zlcm5tZW50MQwwCgYDVQQLEwNEb2QxEDAOBgNVBAsTB1Rlc3RpbmcxFTATBgNV" + "BAMTDENBMS1JQy4wMS4wMRcNOTkwMTAxMTIwMTAwWhcNNDgwMTAxMTIwMTAwWqAjMCEwCg" + "YDVR0UBAMCAQEwEwYDVR0jBAwwCoAI9HJGJJX7heswDQYJKoZIhvcNAQEFBQADgYEAV4DM" + "F5gU8MZ6E/mnjAWS+dIRKUBJV1GZJ+hOysdbmK1hD0mj5Pd5qTzlcvLjuatIoIsB5DCpYd" + "AcNRLVvF5EJFhVjqsPzRlfUZth0Xqa+U/DeHjVxHxYsLEOSt+v2bLkbGh88SmOAk6F8xj1" + "l7YIfPX5cIkUBTVZlsUt51slMXc="; public static final String End_Certificate_IC_01_01_crt = "MIIChjCCAe+gAwIBAgIBLDANBgkqhkiG9w0BAQUFADBeMQswCQYDVQQGEwJVUzEYMBYGA1" + "UEChMPVS5TLiBHb3Zlcm5tZW50MQwwCgYDVQQLEwNEb2QxEDAOBgNVBAsTB1Rlc3Rpbmcx" + "FTATBgNVBAMTDENBMS1JQy4wMS4wMTAeFw05ODAxMDExMjAxMDBaFw00ODAxMDExMjAxMD" + "BaMGAxCzAJBgNVBAYTAlVTMRgwFgYDVQQKEw9VLlMuIEdvdmVybm1lbnQxDDAKBgNVBAsT" + "A0RvRDEQMA4GA1UECxMHVGVzdGluZzEXMBUGA1UEAxMOVXNlcjEtSUMuMDEuMDEwgZ8wDQ" + "YJKoZIhvcNAQEBBQADgY0AMIGJAoGBAPrk1fosBu0hemIKgTDCeV/RoFbbsm02X4LfZonX" + "KeGRGYZXz4tpWgbNpjKBq1e/2bOO1DCn9I8I2kjvZdOkabk4MLeuRDo/sqlNndu4Ar5502" + "pAo4A2V0QLR4IDHAJoDpxtSFrqELOiiyCx9O9V19ywe5pcBFrxVEWDqTnBUeDJAgMBAAGj" + "UjBQMA4GA1UdDwEB/wQEAwIF4DAWBgNVHSAEDzANMAsGCWCGSAFlAwEwATARBgNVHQ4ECg" + "QIbI6BhABrmQ8wEwYDVR0jBAwwCoAI9HJGJJX7heswDQYJKoZIhvcNAQEFBQADgYEAYzYy" + "M0wbzNhZftAWz7TfFi64uA9WmTmd4MeK9vga4ChswT4H1zlaV1Sr+3hqpGmOoP5AUd9XIq" + "O/ui+/gFaeuOLI+ATmK+V2KHGAneMwzcw9qbXRc+xZqGGjbXMb3Bowe3qrj3mhyowfa1n7" + "x5xB7XEOqO6sfWxLdDjLVo4sn88="; public static final String[] TEST_22_DATA = new String[] { Intermediate_Certificate_IC_01_01_crt, Intermediate_CRL_IC_01_01_crl, End_Certificate_IC_01_01_crt }; /* * test23 * */ public static final String Intermediate_Certificate_IC_02_01_crt = "MIICkjCCAfugAwIBAgIBLTANBgkqhkiG9w0BAQUFADBeMQswCQYDVQQGEwJVUzEYMBYGA1" + "UEChMPVS5TLiBHb3Zlcm5tZW50MQwwCgYDVQQLEwNEb0QxEDAOBgNVBAsTB1Rlc3Rpbmcx" + "FTATBgNVBAMTDFRydXN0IEFuY2hvcjAeFw05ODAxMDExMjAxMDBaFw00ODAxMDExMjAxMD" + "BaMF4xCzAJBgNVBAYTAlVTMRgwFgYDVQQKEw9VLlMuIEdvdmVybm1lbnQxDDAKBgNVBAsT" + "A0RvZDEQMA4GA1UECxMHVGVzdGluZzEVMBMGA1UEAxMMQ0ExLUlDLjAyLjAxMIGfMA0GCS" + "qGSIb3DQEBAQUAA4GNADCBiQKBgQDemJgZnOzXOwNGqRA3Xq9aMrAWQU4oFuhSELsEYfLZ" + "GO3ntBjJLqCn+rs3FjR9N94cu63TduOAgqlXqrNbvyO1+SF9m35JXreqn/OS6KrK6c8W2I" + "pDAWJcr89nGyyCXMoJeaOOtj8m2NjZblmCZvtAl5UMOew73GE7Z5fE+jtA2wIDAQABo2Aw" + "XjAMBgNVHRMBAf8EAjAAMA4GA1UdDwEB/wQEAwIBBjAWBgNVHSAEDzANMAsGCWCGSAFlAw" + "EwATARBgNVHQ4ECgQIhT9GjaaHj68wEwYDVR0jBAwwCoAIq5rr+cLnVI8wDQYJKoZIhvcN" + "AQEFBQADgYEAWhKJUujLapxpz/DoD/w48HMzkL6UQCxQPOAjwwHicX8wFcKmcrWLVBdVC3" + "0+ywrzMraWhaq+QCOqsgtxCwTZrfUxbCNqhKS0lZijCMgNN4Jht+PAZ22tzEsw7nCwiMM2" + "n1jeKF/3btoDEUvZn9SuzhkIyxy7Q8l2tbNOsANqpxE="; public static final String Intermediate_CRL_IC_02_01_crl = "MIIBSzCBtQIBATANBgkqhkiG9w0BAQUFADBeMQswCQYDVQQGEwJVUzEYMBYGA1UEChMPVS" + "5TLiBHb3Zlcm5tZW50MQwwCgYDVQQLEwNEb2QxEDAOBgNVBAsTB1Rlc3RpbmcxFTATBgNV" + "BAMTDENBMS1JQy4wMi4wMRcNOTkwMTAxMTIwMTAwWhcNNDgwMTAxMTIwMTAwWqAjMCEwCg" + "YDVR0UBAMCAQEwEwYDVR0jBAwwCoAIhT9GjaaHj68wDQYJKoZIhvcNAQEFBQADgYEAJsjf" + "oS3F1KMpcVBOC1Z6P5N20TYLCCHG6KETlBA3Rjf8ehNxJKJW0lGd7qHpVHp4BGvkSfaOAa" + "OrC0G59wjDEY+Ci4QS46OYzBcHXMFX5HF2xMq+y5SfQnyV6MQUVVkxJRjgsTLrYwP2JaYm" + "BK/zExhqQgPfgcR+56swBPXqogo="; public static final String End_Certificate_IC_02_01_crt = "MIIChjCCAe+gAwIBAgIBLjANBgkqhkiG9w0BAQUFADBeMQswCQYDVQQGEwJVUzEYMBYGA1" + "UEChMPVS5TLiBHb3Zlcm5tZW50MQwwCgYDVQQLEwNEb2QxEDAOBgNVBAsTB1Rlc3Rpbmcx" + "FTATBgNVBAMTDENBMS1JQy4wMi4wMTAeFw05ODAxMDExMjAxMDBaFw00ODAxMDExMjAxMD" + "BaMGAxCzAJBgNVBAYTAlVTMRgwFgYDVQQKEw9VLlMuIEdvdmVybm1lbnQxDDAKBgNVBAsT" + "A0RvRDEQMA4GA1UECxMHVGVzdGluZzEXMBUGA1UEAxMOVXNlcjEtSUMuMDIuMDEwgZ8wDQ" + "YJKoZIhvcNAQEBBQADgY0AMIGJAoGBANbTVeAxOibAO3KGqxxY3VqKXDr9tKJN+igpKb4w" + "goR0ZnWGDusSVm4pvneZ9qfmi8A0sM0E91+B2hAwsU6Y9RoA7nPsTkFYi5F+hHGIF46Op6" + "8blGrZraGf9bsWXCZFoLoxcgltwjGPQqyZ5mnnm8cxUbtaWmgo28MK1yBH/sS5AgMBAAGj" + "UjBQMA4GA1UdDwEB/wQEAwIF4DAWBgNVHSAEDzANMAsGCWCGSAFlAwEwATARBgNVHQ4ECg" + "QI3gkBNo/SISMwEwYDVR0jBAwwCoAIhT9GjaaHj68wDQYJKoZIhvcNAQEFBQADgYEAQGl1" + "7uT2xxYDks6HolrQIpesIoPqEiZ8TkizEBuLG3sUKsC7klHwy2iyVvA6nRUDwf/XzDLpGW" + "/Gn0KTW6ZYIX6snOC1+7HX5OJglQx8tDpDvcAgyocK8PvCrHfu9o33J49aSeLAVpoCHwne" + "tTtJxVfTMmjYWKeDbHHHi8a2YTI="; public static final String[] TEST_23_DATA = new String[] { Intermediate_Certificate_IC_02_01_crt, Intermediate_CRL_IC_02_01_crl, End_Certificate_IC_02_01_crt }; /* * test24 * */ public static final String Intermediate_Certificate_IC_02_02_crt = "MIIClTCCAf6gAwIBAgIBLzANBgkqhkiG9w0BAQUFADBeMQswCQYDVQQGEwJVUzEYMBYGA1" + "UEChMPVS5TLiBHb3Zlcm5tZW50MQwwCgYDVQQLEwNEb0QxEDAOBgNVBAsTB1Rlc3Rpbmcx" + "FTATBgNVBAMTDFRydXN0IEFuY2hvcjAeFw05ODAxMDExMjAxMDBaFw00ODAxMDExMjAxMD" + "BaMF4xCzAJBgNVBAYTAlVTMRgwFgYDVQQKEw9VLlMuIEdvdmVybm1lbnQxDDAKBgNVBAsT" + "A0RvZDEQMA4GA1UECxMHVGVzdGluZzEVMBMGA1UEAxMMQ0ExLUlDLjAyLjAyMIGfMA0GCS" + "qGSIb3DQEBAQUAA4GNADCBiQKBgQDoeA32BPwgq8pLJoR/tbOSjHtAz6fmzvzJrhJMvl64" + "ccVuIzGxzOneYsO/ZYWy3ZGtlCoMZJRnS83tw0ikU9vQUwBw7DEcfRlLKYkY68rp25N1V5" + "JEjnlHw+RvubdGkonWzUNJFbY1GA24J3no2GZHiLPgWmGb1jsA8Ag32MUrCQIDAQABo2Mw" + "YTAPBgNVHRMBAf8EBTADAQH/MA4GA1UdDwEB/wQEAwIBBjAWBgNVHSAEDzANMAsGCWCGSA" + "FlAwEwATARBgNVHQ4ECgQIKx4Ybzu2PaYwEwYDVR0jBAwwCoAIq5rr+cLnVI8wDQYJKoZI" + "hvcNAQEFBQADgYEAotGeNFzmktvcxpCRcpuARHkv1lW+LegvbDBnSPvGnr1+Cn9rZcuLup" + "u8ex6VJ7KWtgWBtzdOelerO6ytfWQ67uNpTOuc0SDdk/f3tCagdx44LBVQywuq/Kj57ZuN" + "jpe4J8UPZSBFFK+P3gTX3S/lIKsDi6xjRnqFLSQYGX2XiIE="; public static final String Intermediate_CRL_IC_02_02_crl = "MIIBSzCBtQIBATANBgkqhkiG9w0BAQUFADBeMQswCQYDVQQGEwJVUzEYMBYGA1UEChMPVS" + "5TLiBHb3Zlcm5tZW50MQwwCgYDVQQLEwNEb2QxEDAOBgNVBAsTB1Rlc3RpbmcxFTATBgNV" + "BAMTDENBMS1JQy4wMi4wMhcNOTkwMTAxMTIwMTAwWhcNNDgwMTAxMTIwMTAwWqAjMCEwCg" + "YDVR0UBAMCAQEwEwYDVR0jBAwwCoAIKx4Ybzu2PaYwDQYJKoZIhvcNAQEFBQADgYEAOfuX" + "wRv4skbPZAbOH/LVXdc/cA7vCSTAnWecN3ZKm/eCsxbyRxqn7fcDyHmqg5H3Ac5UOlMHR4" + "FMe0Dp+Yu4Xg8xg3zRvE/3M/5jyRILGGi7olh4ikkOMD+UlreysvYvUX2MVP1iM9qAkXh8" + "E8n/LZIlABN2GGkFEMRMJA6KTXg="; public static final String End_Certificate_IC_02_02_crt = "MIIChjCCAe+gAwIBAgIBMDANBgkqhkiG9w0BAQUFADBeMQswCQYDVQQGEwJVUzEYMBYGA1" + "UEChMPVS5TLiBHb3Zlcm5tZW50MQwwCgYDVQQLEwNEb2QxEDAOBgNVBAsTB1Rlc3Rpbmcx" + "FTATBgNVBAMTDENBMS1JQy4wMi4wMjAeFw05ODAxMDExMjAxMDBaFw00ODAxMDExMjAxMD" + "BaMGAxCzAJBgNVBAYTAlVTMRgwFgYDVQQKEw9VLlMuIEdvdmVybm1lbnQxDDAKBgNVBAsT" + "A0RvRDEQMA4GA1UECxMHVGVzdGluZzEXMBUGA1UEAxMOVXNlcjEtSUMuMDIuMDIwgZ8wDQ" + "YJKoZIhvcNAQEBBQADgY0AMIGJAoGBAKogqWGx9EpJ/0G7ORopyIQ4IZXYKKTE48WqOJbu" + "nLD3txGjMUb5Xefl/QyTfd6J758ddGzPiKs1zWO6riffJLIBoOFDmt8tchPBJuIM3gKgXe" + "VcZMyF5mebm5/GZekMOjbs8P/zbLdrlu1D9CZWZMXONYitdluSg2moMGbewS2NAgMBAAGj" + "UjBQMA4GA1UdDwEB/wQEAwIF4DAWBgNVHSAEDzANMAsGCWCGSAFlAwEwATARBgNVHQ4ECg" + "QIP8N7OmNGshEwEwYDVR0jBAwwCoAIKx4Ybzu2PaYwDQYJKoZIhvcNAQEFBQADgYEAwkpF" + "j6Kv+OcKrUtOgnH9QddB0Ej0oU6B5/5Hhhf3liAPKtllDHnhUj6nqfh4APNq/iqYFOkKMR" + "RUZoaj6kakJNSOlgvRIiQfuFIgv3CqLZnhr85YFRnKgoluZE1pq3TvunoiKyJbCjbmyCos" + "Rd32gVcJq024xvY2eVBTl6tfn5A="; public static final String[] TEST_24_DATA = new String[] { Intermediate_Certificate_IC_02_02_crt, Intermediate_CRL_IC_02_02_crl, End_Certificate_IC_02_02_crt }; /* * test25 * */ public static final String Intermediate_Certificate_IC_02_03_crt = "MIICjzCCAfigAwIBAgIBMTANBgkqhkiG9w0BAQUFADBeMQswCQYDVQQGEwJVUzEYMBYGA1" + "UEChMPVS5TLiBHb3Zlcm5tZW50MQwwCgYDVQQLEwNEb0QxEDAOBgNVBAsTB1Rlc3Rpbmcx" + "FTATBgNVBAMTDFRydXN0IEFuY2hvcjAeFw05ODAxMDExMjAxMDBaFw00ODAxMDExMjAxMD" + "BaMF4xCzAJBgNVBAYTAlVTMRgwFgYDVQQKEw9VLlMuIEdvdmVybm1lbnQxDDAKBgNVBAsT" + "A0RvZDEQMA4GA1UECxMHVGVzdGluZzEVMBMGA1UEAxMMQ0ExLUlDLjAyLjAzMIGfMA0GCS" + "qGSIb3DQEBAQUAA4GNADCBiQKBgQC7LFt+yGItQFqSEPi03ICIr5ydWnFPQHZdEMNu2tRU" + "3XiOpfam1wl0xgAPGBkQK768OfidpP/i1hgYOU/isOB5dyALscvIQ9XJG1OWQXBBLgKuCb" + "MS5fuDhBNa4KiFuGMbJ3/UjluRsD9qaXwGUavc436JwbRHvW8FomaBYYY1hQIDAQABo10w" + "WzAJBgNVHRMEAjAAMA4GA1UdDwEB/wQEAwIBBjAWBgNVHSAEDzANMAsGCWCGSAFlAwEwAT" + "ARBgNVHQ4ECgQIPsBg9tMABhAwEwYDVR0jBAwwCoAIq5rr+cLnVI8wDQYJKoZIhvcNAQEF" + "BQADgYEANZcayTTX+FGhtRUJ+XuYA7jR14CJL6qTHPvdSMgHNw9mGXI/7sO5I4v1vayOCI" + "YQ9luBvrTYlMPmuej8+bhM8YTYpiiOjVFANwvSKArI9U2CAGBcoBMXydykkm8qYw4gtYQT" + "neiOz7VqI9plLWA111IRMgayD3CAt4Ntpzd1VSE="; public static final String Intermediate_CRL_IC_02_03_crl = "MIIBSzCBtQIBATANBgkqhkiG9w0BAQUFADBeMQswCQYDVQQGEwJVUzEYMBYGA1UEChMPVS" + "5TLiBHb3Zlcm5tZW50MQwwCgYDVQQLEwNEb2QxEDAOBgNVBAsTB1Rlc3RpbmcxFTATBgNV" + "BAMTDENBMS1JQy4wMi4wMxcNOTkwMTAxMTIwMTAwWhcNNDgwMTAxMTIwMTAwWqAjMCEwCg" + "YDVR0UBAMCAQEwEwYDVR0jBAwwCoAIPsBg9tMABhAwDQYJKoZIhvcNAQEFBQADgYEAVeQi" + "tT1FRUaJlhfpkfjZr6VHmvGnqYapdo4DRT/pm8tsp1LbZZXpYW638ztwgZNgeBRPFlcb+x" + "8naQjEkoaYzLbCYfdY+PPVDv7ym15PE48Kve8ImvANY0YnTGS8pcKdK1dpNKBnYYMOG9JN" + "+H5K/4cSm/WMCKIuKdsiAWFYauE="; public static final String End_Certificate_IC_02_03_crt = "MIIChjCCAe+gAwIBAgIBMjANBgkqhkiG9w0BAQUFADBeMQswCQYDVQQGEwJVUzEYMBYGA1" + "UEChMPVS5TLiBHb3Zlcm5tZW50MQwwCgYDVQQLEwNEb2QxEDAOBgNVBAsTB1Rlc3Rpbmcx" + "FTATBgNVBAMTDENBMS1JQy4wMi4wMzAeFw05ODAxMDExMjAxMDBaFw00ODAxMDExMjAxMD" + "BaMGAxCzAJBgNVBAYTAlVTMRgwFgYDVQQKEw9VLlMuIEdvdmVybm1lbnQxDDAKBgNVBAsT" + "A0RvRDEQMA4GA1UECxMHVGVzdGluZzEXMBUGA1UEAxMOVXNlcjEtSUMuMDIuMDMwgZ8wDQ" + "YJKoZIhvcNAQEBBQADgY0AMIGJAoGBALGbo9yEujZ9RFU+Vmxb5+Rx1VdIG/3E/5hXV/xI" + "OFu4mEfYh2tBhP2qIMH2KbrR1tiW5t4DvTCBM3NKKqp75wpiuu7E3q6imt1pLbGW13NVL+" + "81gYWXnCnzHpxYjMTIqqCkPIAeOG+SBJ1MgERbL+NBl+AK3WG4TeQ8vw7r2CGrAgMBAAGj" + "UjBQMA4GA1UdDwEB/wQEAwIF4DAWBgNVHSAEDzANMAsGCWCGSAFlAwEwATARBgNVHQ4ECg" + "QIS/HbII+ki/kwEwYDVR0jBAwwCoAIPsBg9tMABhAwDQYJKoZIhvcNAQEFBQADgYEAWHy4" + "sHrTkqY1XjDBY5XpNEyhP6htcnjYD9bos4wjxPlJUyxdIWACWrLDE+R5iRCOYsh/nDAJEt" + "CUcVASukvP6VLJaFjyxUOaCp6JCVV+txk7Fh0S/Ur3Zyysfp5LllP1plOA3N/k1Hliljp0" + "+bnSiDhA1+3hJh0gDMjWUdRq9yM="; public static final String[] TEST_25_DATA = new String[] { Intermediate_Certificate_IC_02_03_crt, Intermediate_CRL_IC_02_03_crl, End_Certificate_IC_02_03_crt }; /* * test26 * */ public static final String Intermediate_Certificate_IC_02_04_crt = "MIICkjCCAfugAwIBAgIBMzANBgkqhkiG9w0BAQUFADBeMQswCQYDVQQGEwJVUzEYMBYGA1" + "UEChMPVS5TLiBHb3Zlcm5tZW50MQwwCgYDVQQLEwNEb0QxEDAOBgNVBAsTB1Rlc3Rpbmcx" + "FTATBgNVBAMTDFRydXN0IEFuY2hvcjAeFw05ODAxMDExMjAxMDBaFw00ODAxMDExMjAxMD" + "BaMF4xCzAJBgNVBAYTAlVTMRgwFgYDVQQKEw9VLlMuIEdvdmVybm1lbnQxDDAKBgNVBAsT" + "A0RvZDEQMA4GA1UECxMHVGVzdGluZzEVMBMGA1UEAxMMQ0ExLUlDLjAyLjA0MIGfMA0GCS" + "qGSIb3DQEBAQUAA4GNADCBiQKBgQDf5u5ouGQlQmdNfc4ell3RXKWmtq+ar9VKMme3kp8D" + "cbDbUaVwlvhWTkOKxb9I208wfGG2nQiArezIwutlASf7sWo16EPapmGdCF+rp1dpjAPBUu" + "fruEyCZ8nu2ITD52wuPY9OAcKHQE2/bBpCJWkw97fYX6Q9PPW5uobWoUJtOwIDAQABo2Aw" + "XjAMBgNVHRMEBTADAQH/MA4GA1UdDwEB/wQEAwIBBjAWBgNVHSAEDzANMAsGCWCGSAFlAw" + "EwATARBgNVHQ4ECgQIjDm8K5YcGakwEwYDVR0jBAwwCoAIq5rr+cLnVI8wDQYJKoZIhvcN" + "AQEFBQADgYEAEQIJeZj/HE3HvjjJV7PdU+2Ze8OeCYeeWDocxrA647xpeOksVXBXKmq2OV" + "NqoFk7YNtlSUqiS2TlqjGqLtKYetk7a17qS/8EIQct+H5KWdvkLkYMkfIAAMJvJZHPGxEv" + "j+oVPAi9FITRbFdN8Jvdo9MAuU2q8d2x8MF236RmEds="; public static final String Intermediate_CRL_IC_02_04_crl = "MIIBSzCBtQIBATANBgkqhkiG9w0BAQUFADBeMQswCQYDVQQGEwJVUzEYMBYGA1UEChMPVS" + "5TLiBHb3Zlcm5tZW50MQwwCgYDVQQLEwNEb2QxEDAOBgNVBAsTB1Rlc3RpbmcxFTATBgNV" + "BAMTDENBMS1JQy4wMi4wNBcNOTkwMTAxMTIwMTAwWhcNNDgwMTAxMTIwMTAwWqAjMCEwCg" + "YDVR0UBAMCAQEwEwYDVR0jBAwwCoAIjDm8K5YcGakwDQYJKoZIhvcNAQEFBQADgYEAV5bX" + "7WsT8sWeA0iQ7V/+ZQESDzvyHA7Ziju0iRsvTL7qOVF/Nl5v+zND+ZNPhdJDKEM/Q0lEaA" + "ybe0E73NMmM1qRX1daAwE++jHukF9TMeNl750HJaS667H6jcjeRrHUJDD0+AgqrZY52dL6" + "CPM3V4QSvdfc1/xtKmNIZWSSoqY="; public static final String End_Certificate_IC_02_04_crt = "MIIChjCCAe+gAwIBAgIBNDANBgkqhkiG9w0BAQUFADBeMQswCQYDVQQGEwJVUzEYMBYGA1" + "UEChMPVS5TLiBHb3Zlcm5tZW50MQwwCgYDVQQLEwNEb2QxEDAOBgNVBAsTB1Rlc3Rpbmcx" + "FTATBgNVBAMTDENBMS1JQy4wMi4wNDAeFw05ODAxMDExMjAxMDBaFw00ODAxMDExMjAxMD" + "BaMGAxCzAJBgNVBAYTAlVTMRgwFgYDVQQKEw9VLlMuIEdvdmVybm1lbnQxDDAKBgNVBAsT" + "A0RvRDEQMA4GA1UECxMHVGVzdGluZzEXMBUGA1UEAxMOVXNlcjEtSUMuMDIuMDQwgZ8wDQ" + "YJKoZIhvcNAQEBBQADgY0AMIGJAoGBAMW45d5dPrzUJbuRIDeQ5gIJRYxi80PxPvxSmJe8" + "ScG1A+l75SAtgLGWAxBqxPSzL+teBBUsnmf2Xsc8/qQHHev74uat0lxq9YrZ3npLW2YNo2" + "CfxLK0M7F1/bhkHK2f9ttIvOrrKI67BeEjfACULdJEhl431uWINWV0pY+fHq+pAgMBAAGj" + "UjBQMA4GA1UdDwEB/wQEAwIF4DAWBgNVHSAEDzANMAsGCWCGSAFlAwEwATARBgNVHQ4ECg" + "QII61NnUvgvjYwEwYDVR0jBAwwCoAIjDm8K5YcGakwDQYJKoZIhvcNAQEFBQADgYEAjwgL" + "6qMnnqUvNspsDaYpPQzTCqXkqshZhsy5G/nLk621H/YbNGlnZ6asHGljYVYMzjmcny16y6" + "ntiv9QPB7YorAx27WT7pQPFla96s+nM/rfwWHPWI6QGDsquPriwJm/MwQC+1oDXEFKvdIL" + "0urejfd5hgiXYbRRwMI7km97iHg="; public static final String[] TEST_26_DATA = new String[] { Intermediate_Certificate_IC_02_04_crt, Intermediate_CRL_IC_02_04_crl, End_Certificate_IC_02_04_crt }; /* * test27 * */ public static final String Intermediate_Certificate_IC_04_01_crt = "MIICjzCCAfigAwIBAgIBNTANBgkqhkiG9w0BAQUFADBeMQswCQYDVQQGEwJVUzEYMBYGA1" + "UEChMPVS5TLiBHb3Zlcm5tZW50MQwwCgYDVQQLEwNEb0QxEDAOBgNVBAsTB1Rlc3Rpbmcx" + "FTATBgNVBAMTDFRydXN0IEFuY2hvcjAeFw05ODAxMDExMjAxMDBaFw00ODAxMDExMjAxMD" + "BaMF4xCzAJBgNVBAYTAlVTMRgwFgYDVQQKEw9VLlMuIEdvdmVybm1lbnQxDDAKBgNVBAsT" + "A0RvZDEQMA4GA1UECxMHVGVzdGluZzEVMBMGA1UEAxMMQ0ExLUlDLjA0LjAxMIGfMA0GCS" + "qGSIb3DQEBAQUAA4GNADCBiQKBgQDBtNwpr9LZBF2LRtAp9Tb1FZnfM3b/Jv2sdO5zc/Bk" + "sO4ByUgY+Mux9dEvFrkVWBK110TvXn+dj+85TuboILv4MDKlu+tI/rtuadXGwwDIg8TQnz" + "uyC7LWhxM5JZs1/Is+sPKUY4PTCHs3+EHPBWf2tFiP3l6ZftkySEiL6+2LSQIDAQABo10w" + "WzAMBgNVHRMEBTADAQH/MAsGA1UdDwQEAwIBBjAWBgNVHSAEDzANMAsGCWCGSAFlAwEwAT" + "ARBgNVHQ4ECgQIbMuZ73onuZswEwYDVR0jBAwwCoAIq5rr+cLnVI8wDQYJKoZIhvcNAQEF" + "BQADgYEAhaTSc2xafdP/QceMm9YJ/rZJ5gTgBR/SlmKQwd2BclHabG+Fozdg4delDjtRXS" + "FKY3sFWBFZHVeprh4T93Oj6IVA5X4DIuUeBpprtS+psCnWZxdtcUWmbyYQwZNCifG5C5D0" + "lRwxlMlv40xT2oCM1zPZpfmqemBDUPJ2OhkCjvo="; public static final String Intermediate_CRL_IC_04_01_crl = "MIIBSzCBtQIBATANBgkqhkiG9w0BAQUFADBeMQswCQYDVQQGEwJVUzEYMBYGA1UEChMPVS" + "5TLiBHb3Zlcm5tZW50MQwwCgYDVQQLEwNEb2QxEDAOBgNVBAsTB1Rlc3RpbmcxFTATBgNV" + "BAMTDENBMS1JQy4wNC4wMRcNOTkwMTAxMTIwMTAwWhcNNDgwMTAxMTIwMTAwWqAjMCEwCg" + "YDVR0UBAMCAQEwEwYDVR0jBAwwCoAIbMuZ73onuZswDQYJKoZIhvcNAQEFBQADgYEAMk6D" + "Rztz1AyFnFr1KAlbjLLwxtQplf2eIc//zUkDFVUHtX5TrEC/ijUaItjdkOoPGQfpnL0w8x" + "wyqWndMh593QPCqIJTtv/iACoiJNZ90ZJS0adcdZ+AEmQpa0Zv0e1JOqRrPoAfTq4HrOfR" + "vhBwhvKQNtTExupW/EBudznKC6Q="; public static final String End_Certificate_IC_04_01_crt = "MIIChjCCAe+gAwIBAgIBNjANBgkqhkiG9w0BAQUFADBeMQswCQYDVQQGEwJVUzEYMBYGA1" + "UEChMPVS5TLiBHb3Zlcm5tZW50MQwwCgYDVQQLEwNEb2QxEDAOBgNVBAsTB1Rlc3Rpbmcx" + "FTATBgNVBAMTDENBMS1JQy4wNC4wMTAeFw05ODAxMDExMjAxMDBaFw00ODAxMDExMjAxMD" + "BaMGAxCzAJBgNVBAYTAlVTMRgwFgYDVQQKEw9VLlMuIEdvdmVybm1lbnQxDDAKBgNVBAsT" + "A0RvRDEQMA4GA1UECxMHVGVzdGluZzEXMBUGA1UEAxMOVXNlcjEtSUMuMDQuMDEwgZ8wDQ" + "YJKoZIhvcNAQEBBQADgY0AMIGJAoGBAM2dGkraKGdIi6EXxAu6/ekMqDloX5YSVBGh4Hp2" + "faujr1u4j8Lp8afqjngRxFUpTqGbqH0ETgm4cVPXmc9rUvUzYTMdxTUmIZ+iW+ULZEvzNB" + "712kxRPCD2kDFN2fH2ai8miXr434w+weLm8VQN4jJGo4nswhSs2w1gsUmWyn/ZAgMBAAGj" + "UjBQMA4GA1UdDwEB/wQEAwIF4DAWBgNVHSAEDzANMAsGCWCGSAFlAwEwATARBgNVHQ4ECg" + "QITsLx/sO1edwwEwYDVR0jBAwwCoAIbMuZ73onuZswDQYJKoZIhvcNAQEFBQADgYEAeKft" + "0RM8/b3zQodaKrTdWiFyLg5fzoOsTecSfdFPXoqz9J5ejLVkvJevSmfXJrIUhKXySzsQi+" + "GazuTh/hvWjwUTIvmupi+EiFudnMpXCro8bgi48+NkepNjXvjsSmOfzlrK3SxtpH5dqonL" + "6LHjGyg+Xp0Nor1m5g1rLHyrcEk="; public static final String[] TEST_27_DATA = new String[] { Intermediate_Certificate_IC_04_01_crt, Intermediate_CRL_IC_04_01_crl, End_Certificate_IC_04_01_crt }; /* * test28 * */ public static final String Intermediate_Certificate_IC_05_01_crt = "MIIClTCCAf6gAwIBAgIBNzANBgkqhkiG9w0BAQUFADBeMQswCQYDVQQGEwJVUzEYMBYGA1" + "UEChMPVS5TLiBHb3Zlcm5tZW50MQwwCgYDVQQLEwNEb0QxEDAOBgNVBAsTB1Rlc3Rpbmcx" + "FTATBgNVBAMTDFRydXN0IEFuY2hvcjAeFw05ODAxMDExMjAxMDBaFw00ODAxMDExMjAxMD" + "BaMF4xCzAJBgNVBAYTAlVTMRgwFgYDVQQKEw9VLlMuIEdvdmVybm1lbnQxDDAKBgNVBAsT" + "A0RvZDEQMA4GA1UECxMHVGVzdGluZzEVMBMGA1UEAxMMQ0ExLUlDLjA1LjAxMIGfMA0GCS" + "qGSIb3DQEBAQUAA4GNADCBiQKBgQDM3aWmgX3OzAaBg6lnWjpFQ9ufeTOia3+lIUqn+Ypf" + "5OH/s9dLRqg1ZynV3YIUyzaJPP/YlUEmrhheJn3Bjw25bHeIKdge73pfEbuBAugbUMS75D" + "csBV7Ze9D+sVw8w/LtT3ZPcvM3Vju4d+c14Ip/8pC15jlgQPhwVQSf0x3V2QIDAQABo2Mw" + "YTAPBgNVHRMBAf8EBTADAQH/MA4GA1UdDwEB/wQEAwIBAjAWBgNVHSAEDzANMAsGCWCGSA" + "FlAwEwATARBgNVHQ4ECgQIJ2DFtxoQnXkwEwYDVR0jBAwwCoAIq5rr+cLnVI8wDQYJKoZI" + "hvcNAQEFBQADgYEASvdcfBOh2d1dC10pGLZLI3T+oSPCup/U9riynIR3RxZsIaS/+Q2s81" + "oeg++WQV6pyYvCLneZIp0efvqh5DThNV9lhBcJjlYwm/T8Hi2IaRGsSMwIvzrFN7zxA/zu" + "tW98wigAKM2myk/nlYxmholgbQkQ7ZxYM3lD1TDRl69N66Q="; public static final String Intermediate_CRL_IC_05_01_crl = "MIIBSzCBtQIBATANBgkqhkiG9w0BAQUFADBeMQswCQYDVQQGEwJVUzEYMBYGA1UEChMPVS" + "5TLiBHb3Zlcm5tZW50MQwwCgYDVQQLEwNEb2QxEDAOBgNVBAsTB1Rlc3RpbmcxFTATBgNV" + "BAMTDENBMS1JQy4wNS4wMRcNOTkwMTAxMTIwMTAwWhcNNDgwMTAxMTIwMTAwWqAjMCEwCg" + "YDVR0UBAMCAQEwEwYDVR0jBAwwCoAIJ2DFtxoQnXkwDQYJKoZIhvcNAQEFBQADgYEAK7Ym" + "Y9PjX5CpVewe2E9PNxj3dLYElghaQyapYoVtNq3jDqLMWspdmHdNdeaQoXsjlSJe0Zy8xH" + "ZvpimwifnFZ5hq4yByzHjzNMpcA2yFtg2MtPWGEia+BmaZYZi3X0lR+OShKpNLFc4CfVM/" + "aWG6W2BulHjIAThZhTg3uRekDzs="; public static final String End_Certificate_IC_05_01_crt = "MIIChjCCAe+gAwIBAgIBODANBgkqhkiG9w0BAQUFADBeMQswCQYDVQQGEwJVUzEYMBYGA1" + "UEChMPVS5TLiBHb3Zlcm5tZW50MQwwCgYDVQQLEwNEb2QxEDAOBgNVBAsTB1Rlc3Rpbmcx" + "FTATBgNVBAMTDENBMS1JQy4wNS4wMTAeFw05ODAxMDExMjAxMDBaFw00ODAxMDExMjAxMD" + "BaMGAxCzAJBgNVBAYTAlVTMRgwFgYDVQQKEw9VLlMuIEdvdmVybm1lbnQxDDAKBgNVBAsT" + "A0RvRDEQMA4GA1UECxMHVGVzdGluZzEXMBUGA1UEAxMOVXNlcjEtSUMuMDUuMDEwgZ8wDQ" + "YJKoZIhvcNAQEBBQADgY0AMIGJAoGBALlcUtceuxDznvI3pVM7YddPcBOrNvrOtpuLOa1L" + "Lj9LeNH6+8CzRZnMsUtt+bRGqCKMEJLUIIstWwGg4SskXWk2m+nDKm5Ai6Kyx4nldpgtgQ" + "xZSEwNcwRhpy7TtmLkxDVM9DoTbIbK0dZ7aWw4bXVHPK/lnOMtOaJbFDq0sLfxAgMBAAGj" + "UjBQMA4GA1UdDwEB/wQEAwIF4DAWBgNVHSAEDzANMAsGCWCGSAFlAwEwATARBgNVHQ4ECg" + "QIiXgrRBVcDf0wEwYDVR0jBAwwCoAIJ2DFtxoQnXkwDQYJKoZIhvcNAQEFBQADgYEAhyO6" + "SP6brWDDKZwdQGULno4Om5+DuilJKamyEcvSqE666z1KhvOCdLicqwVa6tQiAL6akrt5Kv" + "R+TT0xqHR4JGosGLGolvK4DLrMeD+PRK7m1a+nJl44luo5Mn48HrKI7jn7n8Lp9bNdCHvr" + "NHaQksCIR/Q8xoucPa+8sCTVSj4="; public static final String[] TEST_28_DATA = new String[] { Intermediate_Certificate_IC_05_01_crt, Intermediate_CRL_IC_05_01_crl, End_Certificate_IC_05_01_crt }; /* * test29 * */ public static final String Intermediate_Certificate_IC_05_02_crt = "MIICkjCCAfugAwIBAgIBOTANBgkqhkiG9w0BAQUFADBeMQswCQYDVQQGEwJVUzEYMBYGA1" + "UEChMPVS5TLiBHb3Zlcm5tZW50MQwwCgYDVQQLEwNEb0QxEDAOBgNVBAsTB1Rlc3Rpbmcx" + "FTATBgNVBAMTDFRydXN0IEFuY2hvcjAeFw05ODAxMDExMjAxMDBaFw00ODAxMDExMjAxMD" + "BaMF4xCzAJBgNVBAYTAlVTMRgwFgYDVQQKEw9VLlMuIEdvdmVybm1lbnQxDDAKBgNVBAsT" + "A0RvZDEQMA4GA1UECxMHVGVzdGluZzEVMBMGA1UEAxMMQ0ExLUlDLjA1LjAyMIGfMA0GCS" + "qGSIb3DQEBAQUAA4GNADCBiQKBgQCrtIYqo2Is8Cd6Ld+fyWC755oA6hQiiruooaR/6O4z" + "ikyhOUztnHkOGMF5H4CKWafwwVrfFtqe7iop3N6AToEIpNlJLVy3cj14A/IASVYSSNFeHd" + "O44Id1NWhPiKx3paPTWslMEdKQV9BlXb7gu8pQpvqTa/38hNQ9vdil/4QZbQIDAQABo2Aw" + "XjAPBgNVHRMBAf8EBTADAQH/MAsGA1UdDwQEAwIBAjAWBgNVHSAEDzANMAsGCWCGSAFlAw" + "EwATARBgNVHQ4ECgQI9P78RavuWW8wEwYDVR0jBAwwCoAIq5rr+cLnVI8wDQYJKoZIhvcN" + "AQEFBQADgYEA0sAEmWBYSazUav6RtuNFtZgNrlQ2i5i138VzRHoF/kq/CxeR/lINQqgJhC" + "ZlUnlslUuM86g8OQGlR8SS0Wsi0MdCQCtPCKA2hStlTx9MMux2IZAGoyHy6P95UE9qINHE" + "fYZUYjO9rh96fzNyJ5Oy2kJdJWdhFXtSh3BSOe0ZD+Y="; public static final String Intermediate_CRL_IC_05_02_crl = "MIIBSzCBtQIBATANBgkqhkiG9w0BAQUFADBeMQswCQYDVQQGEwJVUzEYMBYGA1UEChMPVS" + "5TLiBHb3Zlcm5tZW50MQwwCgYDVQQLEwNEb2QxEDAOBgNVBAsTB1Rlc3RpbmcxFTATBgNV" + "BAMTDENBMS1JQy4wNS4wMhcNOTkwMTAxMTIwMTAwWhcNNDgwMTAxMTIwMTAwWqAjMCEwCg" + "YDVR0UBAMCAQEwEwYDVR0jBAwwCoAI9P78RavuWW8wDQYJKoZIhvcNAQEFBQADgYEAlPLh" + "+CMqRcbLgUKEAL2UlSY5tjsF8At0hf000kec93TnBf7f1NKYVJ5eyeoh/WK4s+k4paAA5E" + "/P2C8JMlGXNTrqKZXMy2zIlufE1ymXAZCKLOLC5ezXRSpwIsBWxko2nfw8Bz/mZO/bCSCT" + "nDwkH8BJIbFV51vJFlyyOmZnCz4="; public static final String End_Certificate_IC_05_02_crt = "MIIChjCCAe+gAwIBAgIBOjANBgkqhkiG9w0BAQUFADBeMQswCQYDVQQGEwJVUzEYMBYGA1" + "UEChMPVS5TLiBHb3Zlcm5tZW50MQwwCgYDVQQLEwNEb2QxEDAOBgNVBAsTB1Rlc3Rpbmcx" + "FTATBgNVBAMTDENBMS1JQy4wNS4wMjAeFw05ODAxMDExMjAxMDBaFw00ODAxMDExMjAxMD" + "BaMGAxCzAJBgNVBAYTAlVTMRgwFgYDVQQKEw9VLlMuIEdvdmVybm1lbnQxDDAKBgNVBAsT" + "A0RvRDEQMA4GA1UECxMHVGVzdGluZzEXMBUGA1UEAxMOVXNlcjEtSUMuMDUuMDIwgZ8wDQ" + "YJKoZIhvcNAQEBBQADgY0AMIGJAoGBAMPsWBfT8HqaiLnoUCPAFniq502odL4uVqzOOxkx" + "evZtjh7NaFlRjuYjTofdkj/IAgg7lkkBEW3auK47Td3TvqnHO401PqvOFNTlbhr5wDLmXS" + "WWcR6XrvgYL3Z3wx15/z6eojcSgu07kdvKqzuLzcDs+noG8lbcruokX0A186pVAgMBAAGj" + "UjBQMA4GA1UdDwEB/wQEAwIF4DAWBgNVHSAEDzANMAsGCWCGSAFlAwEwATARBgNVHQ4ECg" + "QImgomUTkzwbEwEwYDVR0jBAwwCoAI9P78RavuWW8wDQYJKoZIhvcNAQEFBQADgYEATAEq" + "YVV0iYdYomPqxbTapSCJFAMQO/WZhN9brCXP88+jRfk6cAHzTodQOYTOAVe8YXa904505e" + "RA11NNTViP3s/AseGWuqbWjsom9mbR+tVkvufGqPQtm1JhfLgR/68e29AI7tj7zIJyFVYD" + "nLRXGwMGnosqSHDle+WYyfok6a8="; public static final String[] TEST_29_DATA = new String[] { Intermediate_Certificate_IC_05_02_crt, Intermediate_CRL_IC_05_02_crl, End_Certificate_IC_05_02_crt }; /* * test30 * */ public static final String Intermediate_Certificate_IC_05_03_crt = "MIICkjCCAfugAwIBAgIBOzANBgkqhkiG9w0BAQUFADBeMQswCQYDVQQGEwJVUzEYMBYGA1" + "UEChMPVS5TLiBHb3Zlcm5tZW50MQwwCgYDVQQLEwNEb0QxEDAOBgNVBAsTB1Rlc3Rpbmcx" + "FTATBgNVBAMTDFRydXN0IEFuY2hvcjAeFw05ODAxMDExMjAxMDBaFw00ODAxMDExMjAxMD" + "BaMF4xCzAJBgNVBAYTAlVTMRgwFgYDVQQKEw9VLlMuIEdvdmVybm1lbnQxDDAKBgNVBAsT" + "A0RvZDEQMA4GA1UECxMHVGVzdGluZzEVMBMGA1UEAxMMQ0ExLUlDLjA1LjAzMIGfMA0GCS" + "qGSIb3DQEBAQUAA4GNADCBiQKBgQCajRjoRNL9HFTytLLx7C8WYouW0uONGsrtGS5tKMiW" + "oLlQUkohqB2a2PhA1InNGQqnbDtNdqKbR1k6EzD6MyegvXK1sXs0ZE8gt0LZYio7Xp3k+Q" + "7i4Rk5iTruAUrV8bFMYmeIXHXL/9rl5LQV8YRp/Ut3Bg3VECzfhQG4EavMlwIDAQABo2Aw" + "XjAPBgNVHRMBAf8EBTADAQH/MAsGA1UdDwQEAwIBBjAWBgNVHSAEDzANMAsGCWCGSAFlAw" + "EwATARBgNVHQ4ECgQI9041oiwvHsgwEwYDVR0jBAwwCoAIq5rr+cLnVI8wDQYJKoZIhvcN" + "AQEFBQADgYEAYwGYwLsA/kxYZG/RM+kvoH+mUebrBVZRBxjovYsYzNznD26fssjBFfiTmg" + "zwZJfG7MZRsgDSRsS+bxuTlXMVeGRKH8fVj7PNq05sS18QZQOF0CCKzg9DLkCzkzkEWBxc" + "5ersciPrL90UarOIPIJWUxQ/5sdMS/wZtYTU34rNNWE="; public static final String Intermediate_CRL_IC_05_03_crl = "MIIBSzCBtQIBATANBgkqhkiG9w0BAQUFADBeMQswCQYDVQQGEwJVUzEYMBYGA1UEChMPVS" + "5TLiBHb3Zlcm5tZW50MQwwCgYDVQQLEwNEb2QxEDAOBgNVBAsTB1Rlc3RpbmcxFTATBgNV" + "BAMTDENBMS1JQy4wNS4wMxcNOTkwMTAxMTIwMTAwWhcNNDgwMTAxMTIwMTAwWqAjMCEwCg" + "YDVR0UBAMCAQEwEwYDVR0jBAwwCoAI9041oiwvHsgwDQYJKoZIhvcNAQEFBQADgYEAJHTp" + "k+RRsD0dUv59J1GQMWjQTjVz39Xaonx2sk38WHcrHBB78L0W6Skjvt082PwZg32sb7FQBt" + "boAQ3PIKpXMnFnkjnkyaFihrnMdfa0abCPtQhFl3yra+w+1a2RDjQBZOOdq3xlFcLi9unT" + "YYome7eS93wchIvNWFpgwF5A5XY="; public static final String End_Certificate_IC_05_03_crt = "MIIChjCCAe+gAwIBAgIBPDANBgkqhkiG9w0BAQUFADBeMQswCQYDVQQGEwJVUzEYMBYGA1" + "UEChMPVS5TLiBHb3Zlcm5tZW50MQwwCgYDVQQLEwNEb2QxEDAOBgNVBAsTB1Rlc3Rpbmcx" + "FTATBgNVBAMTDENBMS1JQy4wNS4wMzAeFw05ODAxMDExMjAxMDBaFw00ODAxMDExMjAxMD" + "BaMGAxCzAJBgNVBAYTAlVTMRgwFgYDVQQKEw9VLlMuIEdvdmVybm1lbnQxDDAKBgNVBAsT" + "A0RvRDEQMA4GA1UECxMHVGVzdGluZzEXMBUGA1UEAxMOVXNlcjEtSUMuMDUuMDMwgZ8wDQ" + "YJKoZIhvcNAQEBBQADgY0AMIGJAoGBAMYxdSZq7qRBdPOz6H+l0GGAtymAWTshfZZCubHK" + "lQjbVq98qudORfhCOZgOy83j/mo2KAecBhxaxB9YA5ggWNAgaKtFvknvjFemtBCZwt6cVK" + "8LCyUGKzStwAV1+HSDlHxdWo7pRwP0beXFvFECrX418osGt6E/v7Cz++ZtvaDhAgMBAAGj" + "UjBQMA4GA1UdDwEB/wQEAwIF4DAWBgNVHSAEDzANMAsGCWCGSAFlAwEwATARBgNVHQ4ECg" + "QIgTuCLfTVa+QwEwYDVR0jBAwwCoAI9041oiwvHsgwDQYJKoZIhvcNAQEFBQADgYEAQRuC" + "rAx9zzu9QwOq9weNit9PNgFHBpo3Gh9jPVYGJjOQxeSqqou503xi82H3W30FT/3ESCO7IF" + "hfpr/uQZVEmUQnvDsVwbKvED1QF9qkTp6ILk38ITJJgfb+sdSL3bsUeNqVXd0C9wzVoErc" + "OuoCulwkZzfoIOlO2YAjAnR1nUc="; public static final String[] TEST_30_DATA = new String[] { Intermediate_Certificate_IC_05_03_crt, Intermediate_CRL_IC_05_03_crl, End_Certificate_IC_05_03_crt }; /* * test31 * */ public static final String Intermediate_Certificate_IC_06_01_crt = "MIIClTCCAf6gAwIBAgIBPTANBgkqhkiG9w0BAQUFADBeMQswCQYDVQQGEwJVUzEYMBYGA1" + "UEChMPVS5TLiBHb3Zlcm5tZW50MQwwCgYDVQQLEwNEb0QxEDAOBgNVBAsTB1Rlc3Rpbmcx" + "FTATBgNVBAMTDFRydXN0IEFuY2hvcjAeFw05ODAxMDExMjAxMDBaFw00ODAxMDExMjAxMD" + "BaMF4xCzAJBgNVBAYTAlVTMRgwFgYDVQQKEw9VLlMuIEdvdmVybm1lbnQxDDAKBgNVBAsT" + "A0RvZDEQMA4GA1UECxMHVGVzdGluZzEVMBMGA1UEAxMMQ0ExLUlDLjA2LjAxMIGfMA0GCS" + "qGSIb3DQEBAQUAA4GNADCBiQKBgQDmutL9PY/BLXvXMEDQLQnWE7dCOsrLNvJiuSjDdznF" + "vBz6WS/RqUr9zsDFknpOWB3Epo2syV4ZFto+v4VWNo61uaClIEsw5x1y0saG19px34KVpQ" + "wkpvLeRZySdCydKdE1rptYR/JbHvPo5TU4mxOo6L7JeEwAvjSI4tK4rwJ4MwIDAQABo2Mw" + "YTAPBgNVHRMBAf8EBTADAQH/MA4GA1UdDwEB/wQEAwICBDAWBgNVHSAEDzANMAsGCWCGSA" + "FlAwEwATARBgNVHQ4ECgQI1BB9j6Jyny4wEwYDVR0jBAwwCoAIq5rr+cLnVI8wDQYJKoZI" + "hvcNAQEFBQADgYEAajWMbY8zL8jS2VUjCPBMuIjUvBfy55+92EXg5pZnyNNwN1diZfJFiB" + "rrPWEg3Fa4NMLgaDKWZsYkOcDDo8I+Qb9FsU9LphCzQ1ubIEuxu6KPX9X29BscFOxUnZCz" + "yuzVfadACxi5Y7Bz5pN5LfC/jEb2iXjkdN5Rm8AqT81syIo="; public static final String Intermediate_CRL_IC_06_01_crl = "MIIBSzCBtQIBATANBgkqhkiG9w0BAQUFADBeMQswCQYDVQQGEwJVUzEYMBYGA1UEChMPVS" + "5TLiBHb3Zlcm5tZW50MQwwCgYDVQQLEwNEb2QxEDAOBgNVBAsTB1Rlc3RpbmcxFTATBgNV" + "BAMTDENBMS1JQy4wNi4wMRcNOTkwMTAxMTIwMTAwWhcNNDgwMTAxMTIwMTAwWqAjMCEwCg" + "YDVR0UBAMCAQEwEwYDVR0jBAwwCoAI1BB9j6Jyny4wDQYJKoZIhvcNAQEFBQADgYEAxH4/" + "mgACT847PyufmF1nob9TSqBj+cM5ye2bgv83gTVd3B1Gopr75Tnu4iP10d0PpSXjySWCjB" + "0HPJ7BdxzkKxSrcM5vcb/jLdk9PqMUS30ohexsx1xK+E38pDJdLX4kbJ3E62AgyXm9WQlD" + "9xsDk7TMXwuxHT4fX070HL6lWGI="; public static final String End_Certificate_IC_06_01_crt = "MIIChjCCAe+gAwIBAgIBPjANBgkqhkiG9w0BAQUFADBeMQswCQYDVQQGEwJVUzEYMBYGA1" + "UEChMPVS5TLiBHb3Zlcm5tZW50MQwwCgYDVQQLEwNEb2QxEDAOBgNVBAsTB1Rlc3Rpbmcx" + "FTATBgNVBAMTDENBMS1JQy4wNi4wMTAeFw05ODAxMDExMjAxMDBaFw00ODAxMDExMjAxMD" + "BaMGAxCzAJBgNVBAYTAlVTMRgwFgYDVQQKEw9VLlMuIEdvdmVybm1lbnQxDDAKBgNVBAsT" + "A0RvRDEQMA4GA1UECxMHVGVzdGluZzEXMBUGA1UEAxMOVXNlcjEtSUMuMDYuMDEwgZ8wDQ" + "YJKoZIhvcNAQEBBQADgY0AMIGJAoGBAO1VOl25MTf068LOgzmQOmyh8MXunBrQ4t6UYuEj" + "H7v+owR9JTDXpfzLPcYfkR+BH2jjISSHIJsUDesKVhpmhABNXcOI5tiRNkeDlV2zKCBXKC" + "wFi5qkhrE8FUCP0hL8YzbybOrYZYSVEP8GgIgMSQcTvhN/Tor0o1jdJvRLmevXAgMBAAGj" + "UjBQMA4GA1UdDwEB/wQEAwIF4DAWBgNVHSAEDzANMAsGCWCGSAFlAwEwATARBgNVHQ4ECg" + "QIFJA9XGd9UZUwEwYDVR0jBAwwCoAI1BB9j6Jyny4wDQYJKoZIhvcNAQEFBQADgYEApRQC" + "OTU9cp16BHM2n0TdZThgj9kSAQ4wHk/dKNOjYNEWu6n/GQ0alxy1dyRzpsr058FOvft23Z" + "Kp0YhdKG/7F1hkcoNvC2yN+Re44n7S+F/jcEPTWnOX6h1Nkw8OS7Uz2fZ8t61iHjqjX4sv" + "M/cKP+AkC8g7p2tfdkP1fQ6ww5E="; public static final String[] TEST_31_DATA = new String[] { Intermediate_Certificate_IC_06_01_crt, Intermediate_CRL_IC_06_01_crl, End_Certificate_IC_06_01_crt }; /* * test32 * */ public static final String Intermediate_Certificate_IC_06_02_crt = "MIICkjCCAfugAwIBAgIBPzANBgkqhkiG9w0BAQUFADBeMQswCQYDVQQGEwJVUzEYMBYGA1" + "UEChMPVS5TLiBHb3Zlcm5tZW50MQwwCgYDVQQLEwNEb0QxEDAOBgNVBAsTB1Rlc3Rpbmcx" + "FTATBgNVBAMTDFRydXN0IEFuY2hvcjAeFw05ODAxMDExMjAxMDBaFw00ODAxMDExMjAxMD" + "BaMF4xCzAJBgNVBAYTAlVTMRgwFgYDVQQKEw9VLlMuIEdvdmVybm1lbnQxDDAKBgNVBAsT" + "A0RvZDEQMA4GA1UECxMHVGVzdGluZzEVMBMGA1UEAxMMQ0ExLUlDLjA2LjAyMIGfMA0GCS" + "qGSIb3DQEBAQUAA4GNADCBiQKBgQC0JoTnPaI/HT2eAqCW1204nRNjcA8EQSp87tvHLpWy" + "5aafmxeJxvk5V9Ba7Ye8eY8yX9losbNUpHJFNdE46fD5qp/oS7Cn3NXA0dwIDQEn1X9vaz" + "nqtZtMjt1S/yGv2xDOb2LKT9zRrqSvxGszCHFUBcJ4HDFJMAdhXPUZiLyXVQIDAQABo2Aw" + "XjAPBgNVHRMBAf8EBTADAQH/MAsGA1UdDwQEAwICBDAWBgNVHSAEDzANMAsGCWCGSAFlAw" + "EwATARBgNVHQ4ECgQI7j2LO1CcsE4wEwYDVR0jBAwwCoAIq5rr+cLnVI8wDQYJKoZIhvcN" + "AQEFBQADgYEAfXIh0oYlM2pagAWzTuYqTl0NavtfqibPgolvhgIG/XmmjswHOg/JVCLb7O" + "jIYtEG2MAD0xQXwu0mc9Deufed2embP/wc0qVG7rj7lxUq6p0aMQJNndBw4m9KlSnjdzyG" + "lwE9pNd2BgEeD516J2k7dspCZHDw3qLer4i2JYoCo2Y="; public static final String Intermediate_CRL_IC_06_02_crl = "MIIBSzCBtQIBATANBgkqhkiG9w0BAQUFADBeMQswCQYDVQQGEwJVUzEYMBYGA1UEChMPVS" + "5TLiBHb3Zlcm5tZW50MQwwCgYDVQQLEwNEb2QxEDAOBgNVBAsTB1Rlc3RpbmcxFTATBgNV" + "BAMTDENBMS1JQy4wNi4wMhcNOTkwMTAxMTIwMTAwWhcNNDgwMTAxMTIwMTAwWqAjMCEwCg" + "YDVR0UBAMCAQEwEwYDVR0jBAwwCoAI7j2LO1CcsE4wDQYJKoZIhvcNAQEFBQADgYEAJej7" + "23qVtwkcvCTPb6afTosYMnVppPXWbtvqn0N5mAFHQfE27x1YPOXOQHBrpQuTyiUdUmPXiH" + "xMKbuR5o2lfdQgew9hbYVk6GegSu+DBC1JKv2YSTgzgRAlJfyByDZ7mbJwZWHVHys08oGk" + "adG6zstavg5EkEeRuAp47T+7cZc="; public static final String End_Certificate_IC_06_02_crt = "MIIChjCCAe+gAwIBAgIBQDANBgkqhkiG9w0BAQUFADBeMQswCQYDVQQGEwJVUzEYMBYGA1" + "UEChMPVS5TLiBHb3Zlcm5tZW50MQwwCgYDVQQLEwNEb2QxEDAOBgNVBAsTB1Rlc3Rpbmcx" + "FTATBgNVBAMTDENBMS1JQy4wNi4wMjAeFw05ODAxMDExMjAxMDBaFw00ODAxMDExMjAxMD" + "BaMGAxCzAJBgNVBAYTAlVTMRgwFgYDVQQKEw9VLlMuIEdvdmVybm1lbnQxDDAKBgNVBAsT" + "A0RvRDEQMA4GA1UECxMHVGVzdGluZzEXMBUGA1UEAxMOVXNlcjEtSUMuMDYuMDIwgZ8wDQ" + "YJKoZIhvcNAQEBBQADgY0AMIGJAoGBAMkIzl9+NRTZf/xaA8noiHRt65Zo6Zp57YvCKUe+" + "YfoC8koMq12MBgrc0IyIfJoqEDEMfD1WbitZdGZMQZ7D9BP2Bk09NXLEAAuj+waFhYk0bW" + "vHBH90O7HpMGmxwHmzOjDV3JHYsU8hq77/5gRFDNRkSCJe2A1Maj8Gcqi6tYf5AgMBAAGj" + "UjBQMA4GA1UdDwEB/wQEAwIF4DAWBgNVHSAEDzANMAsGCWCGSAFlAwEwATARBgNVHQ4ECg" + "QIYDfThEjNL28wEwYDVR0jBAwwCoAI7j2LO1CcsE4wDQYJKoZIhvcNAQEFBQADgYEAJiHT" + "CjLGZK5Lyw+7ICDHs3eS1OGJH/wfsLcBP5sLER41qJfrXGTl2XdKvBMIpriUmJYzjkjof4" + "bvS/VPDNlhI9AJadicW8LM4L3qpy7/YV4Dd/C/BJphJ6cZcT+hjaRKeC7gQVjMeC/npu/p" + "jLgIgzf7HC4WYnaS3h9oYl0cMJk="; public static final String[] TEST_32_DATA = new String[] { Intermediate_Certificate_IC_06_02_crt, Intermediate_CRL_IC_06_02_crl, End_Certificate_IC_06_02_crt }; /* * test33 * */ public static final String Intermediate_Certificate_IC_06_03_crt = "MIICkjCCAfugAwIBAgIBQTANBgkqhkiG9w0BAQUFADBeMQswCQYDVQQGEwJVUzEYMBYGA1" + "UEChMPVS5TLiBHb3Zlcm5tZW50MQwwCgYDVQQLEwNEb0QxEDAOBgNVBAsTB1Rlc3Rpbmcx" + "FTATBgNVBAMTDFRydXN0IEFuY2hvcjAeFw05ODAxMDExMjAxMDBaFw00ODAxMDExMjAxMD" + "BaMF4xCzAJBgNVBAYTAlVTMRgwFgYDVQQKEw9VLlMuIEdvdmVybm1lbnQxDDAKBgNVBAsT" + "A0RvZDEQMA4GA1UECxMHVGVzdGluZzEVMBMGA1UEAxMMQ0ExLUlDLjA2LjAzMIGfMA0GCS" + "qGSIb3DQEBAQUAA4GNADCBiQKBgQCuUtIYFbVjg8VLLUqIEQ6r7hjTaqYVs8DJnJPHUWPA" + "JW9HEIV+d6hj/so76Bff4KJRX7MgoXbvq4ivmn8656N7YSGk9GPuJ25SXK7RJyoqzG/x2R" + "AVUCx/wG99VXVDZhd5ZAVBG2JCkHImsWAei6/Tz8UgXmmLBM8rZNJ/hNtTBwIDAQABo2Aw" + "XjAPBgNVHRMBAf8EBTADAQH/MAsGA1UdDwQEAwIBBjAWBgNVHSAEDzANMAsGCWCGSAFlAw" + "EwATARBgNVHQ4ECgQIpwUlwG1W+sMwEwYDVR0jBAwwCoAIq5rr+cLnVI8wDQYJKoZIhvcN" + "AQEFBQADgYEAqJhUfgar10fl5qG+oH34s/JS3ku0dRm4cTQvqUNOWA9ALnBhSkmOpoMMzH" + "sE9FXXcZ072a8/ecpviP04X5mt5QSLreh3hPVvgWv1LiZ9YkS4Z2kcr+3Gx7zj4gQgT5vG" + "QPpbIBAtBRH5xNHIYQsk6kOe2+t7b0Q82Wnj8UoznmQ="; public static final String Intermediate_CRL_IC_06_03_crl = "MIIBSzCBtQIBATANBgkqhkiG9w0BAQUFADBeMQswCQYDVQQGEwJVUzEYMBYGA1UEChMPVS" + "5TLiBHb3Zlcm5tZW50MQwwCgYDVQQLEwNEb2QxEDAOBgNVBAsTB1Rlc3RpbmcxFTATBgNV" + "BAMTDENBMS1JQy4wNi4wMxcNOTkwMTAxMTIwMTAwWhcNNDgwMTAxMTIwMTAwWqAjMCEwCg" + "YDVR0UBAMCAQEwEwYDVR0jBAwwCoAIpwUlwG1W+sMwDQYJKoZIhvcNAQEFBQADgYEAKCp7" + "ViY1cajXpbjCIqe8yo/98SQRIxoTNgp7EUaaV17FeHZ59nJhRtsF1XnLP4cK0lPBkKFhHK" + "2XyDEWx2hK3X7Z3lSAtn12WFJHOP5T5i0DmYfMJYAFbuPD0JQEWCM3aYsgbXKbbFH1BURh" + "L/uy3arVBP4FaJB8gH678K4J1p4="; public static final String End_Certificate_IC_06_03_crt = "MIIChjCCAe+gAwIBAgIBQjANBgkqhkiG9w0BAQUFADBeMQswCQYDVQQGEwJVUzEYMBYGA1" + "UEChMPVS5TLiBHb3Zlcm5tZW50MQwwCgYDVQQLEwNEb2QxEDAOBgNVBAsTB1Rlc3Rpbmcx" + "FTATBgNVBAMTDENBMS1JQy4wNi4wMzAeFw05ODAxMDExMjAxMDBaFw00ODAxMDExMjAxMD" + "BaMGAxCzAJBgNVBAYTAlVTMRgwFgYDVQQKEw9VLlMuIEdvdmVybm1lbnQxDDAKBgNVBAsT" + "A0RvRDEQMA4GA1UECxMHVGVzdGluZzEXMBUGA1UEAxMOVXNlcjEtSUMuMDYuMDMwgZ8wDQ" + "YJKoZIhvcNAQEBBQADgY0AMIGJAoGBALZw+GpvdleGlmdqZ/zEO2DUGhwgrsselBUNnEzR" + "bcuzr5O1WwiG6aLjrPxIXeL1wLS1/u9AD9p3CQU0XFhi+bEI9+LLnt2y3707O+AQxy1PnQ" + "6qmYE4jMwqDGHn8WVanN2joFT3isLH5wJD0Jh74eoG0tqCHUyOiXaZNo78qgB3AgMBAAGj" + "UjBQMA4GA1UdDwEB/wQEAwIF4DAWBgNVHSAEDzANMAsGCWCGSAFlAwEwATARBgNVHQ4ECg" + "QIJOeyCnvfJtAwEwYDVR0jBAwwCoAIpwUlwG1W+sMwDQYJKoZIhvcNAQEFBQADgYEAJbz1" + "RipbW6uu7B+f2Ol1iq4AVOUuET2S9vi9ojReyAIka3q1XUceZCm5Et0KqpOoOLiu8IRuNB" + "bvKwRcZ4hcVEXv5bRMqaPEK2B0VrRAV/Llj5A+RGn6yc1ZdkJeBRhoSsaHn5whfICaiJX6" + "j3lMpo/CiMRViL+gZLU3SdKqvdY="; public static final String[] TEST_33_DATA = new String[] { Intermediate_Certificate_IC_06_03_crt, Intermediate_CRL_IC_06_03_crl, End_Certificate_IC_06_03_crt }; /* * test34 * */ public static final String Intermediate_Certificate_PP_01_01_crt = "MIIClTCCAf6gAwIBAgIBQzANBgkqhkiG9w0BAQUFADBeMQswCQYDVQQGEwJVUzEYMBYGA1" + "UEChMPVS5TLiBHb3Zlcm5tZW50MQwwCgYDVQQLEwNEb0QxEDAOBgNVBAsTB1Rlc3Rpbmcx" + "FTATBgNVBAMTDFRydXN0IEFuY2hvcjAeFw05ODAxMDExMjAxMDBaFw00ODAxMDExMjAxMD" + "BaMF4xCzAJBgNVBAYTAlVTMRgwFgYDVQQKEw9VLlMuIEdvdmVybm1lbnQxDDAKBgNVBAsT" + "A0RvZDEQMA4GA1UECxMHVGVzdGluZzEVMBMGA1UEAxMMQ0ExLVBQLjAxLjAxMIGfMA0GCS" + "qGSIb3DQEBAQUAA4GNADCBiQKBgQDRkBhJJVgOXHjydAHAnokd/XfEiW+bnWd2ZPJrMBmP" + "7TlvVpxOGqLd6lGdbelbSyAzut1i8lyYn9NSDR0PcyehCSS+MsKS2uNKsTEuH3mlMK/7C5" + "B1qggKqE8f7opyl9+U+Qyi1WQj01gY6XYXaCxksCB0Oqx2737d7QWMvl15dQIDAQABo2Mw" + "YTAPBgNVHRMBAf8EBTADAQH/MA4GA1UdDwEB/wQEAwIBBjAWBgNVHSAEDzANMAsGCWCGSA" + "FlAwEwATARBgNVHQ4ECgQIO1U69B4DBHQwEwYDVR0jBAwwCoAIq5rr+cLnVI8wDQYJKoZI" + "hvcNAQEFBQADgYEAcHWV4Q4z7C+IC4bWgIf1+BzkszCN+LSb4JquR7GgICESbwF2JzR+xL" + "7yoKvB/NBcCqtMY4Hi1DHACbIGJwRe68vVHzz4CmYEK50UUCbAtiAiy9Od6wwrTyFyacBd" + "CBjiO6mkFEp6jOsoIgXRfxK4kDNcMkGUUwMbSR/wZKFuImc="; public static final String Intermediate_CRL_PP_01_01_crl = "MIIBSzCBtQIBATANBgkqhkiG9w0BAQUFADBeMQswCQYDVQQGEwJVUzEYMBYGA1UEChMPVS" + "5TLiBHb3Zlcm5tZW50MQwwCgYDVQQLEwNEb2QxEDAOBgNVBAsTB1Rlc3RpbmcxFTATBgNV" + "BAMTDENBMS1QUC4wMS4wMRcNOTkwMTAxMTIwMTAwWhcNNDgwMTAxMTIwMTAwWqAjMCEwCg" + "YDVR0UBAMCAQEwEwYDVR0jBAwwCoAIO1U69B4DBHQwDQYJKoZIhvcNAQEFBQADgYEAHtbX" + "MUofQlCnbJhgLQw96jsBRu0Kdx/Rk4LWxEbZQOWNaD7aukASjEv63d1qZIDgpefuUNTz5s" + "3eascdtI6iyWFtBO3r6tihtkkSbxocN2Rz7OlR4rW9VwuUirxP0145nMd5CEL03/CNABP5" + "zUo1bNgswHW3z/RaH6h0j0yTkbo="; public static final String End_Certificate_PP_01_01_crt = "MIIChjCCAe+gAwIBAgIBRDANBgkqhkiG9w0BAQUFADBeMQswCQYDVQQGEwJVUzEYMBYGA1" + "UEChMPVS5TLiBHb3Zlcm5tZW50MQwwCgYDVQQLEwNEb2QxEDAOBgNVBAsTB1Rlc3Rpbmcx" + "FTATBgNVBAMTDENBMS1QUC4wMS4wMTAeFw05ODAxMDExMjAxMDBaFw00ODAxMDExMjAxMD" + "BaMGAxCzAJBgNVBAYTAlVTMRgwFgYDVQQKEw9VLlMuIEdvdmVybm1lbnQxDDAKBgNVBAsT" + "A0RvRDEQMA4GA1UECxMHVGVzdGluZzEXMBUGA1UEAxMOVXNlcjEtUFAuMDEuMDEwgZ8wDQ" + "YJKoZIhvcNAQEBBQADgY0AMIGJAoGBALQaTS1wvv551g3BP9JYBMM+KXXLzxtOwPlO5NR4" + "LwuJJB2WuO4vmbn8AG35in/0JqwjZeroLQvbCPxZseXsyA0+7cMO0qcjRJ5l5WdFsahT6g" + "z1YW8pYYY5i2eDUkIRsM7roHMiNjt3zpkuUGX0xZQfAxhuWnRIvlGg5J4r7UOdAgMBAAGj" + "UjBQMA4GA1UdDwEB/wQEAwIF4DAWBgNVHSAEDzANMAsGCWCGSAFlAwEwATARBgNVHQ4ECg" + "QIeyLSANVaTpQwEwYDVR0jBAwwCoAIO1U69B4DBHQwDQYJKoZIhvcNAQEFBQADgYEAvZ4a" + "SQMNl+Q++D9yVaGr+37XJyxs4yow5e5YM9LXn1qBASQ+GNfqPWoe2cPCPYKj32yulxyFEu" + "RHrbhpEQe+nrKWJgO9W1bmfwgQDin29ne/JCQPlznhd3EPFvCkmPLnTyJmSLR6B2VxvndM" + "GO8JEbj3KCf51uf3VnC/Qj11mX8="; public static final String[] TEST_34_DATA = new String[] { Intermediate_Certificate_PP_01_01_crt, Intermediate_CRL_PP_01_01_crl, End_Certificate_PP_01_01_crt }; /* * test35 * */ public static final String Intermediate_Certificate_PP_01_02_crt = "MIICfTCCAeagAwIBAgIBRTANBgkqhkiG9w0BAQUFADBeMQswCQYDVQQGEwJVUzEYMBYGA1" + "UEChMPVS5TLiBHb3Zlcm5tZW50MQwwCgYDVQQLEwNEb0QxEDAOBgNVBAsTB1Rlc3Rpbmcx" + "FTATBgNVBAMTDFRydXN0IEFuY2hvcjAeFw05ODAxMDExMjAxMDBaFw00ODAxMDExMjAxMD" + "BaMF4xCzAJBgNVBAYTAlVTMRgwFgYDVQQKEw9VLlMuIEdvdmVybm1lbnQxDDAKBgNVBAsT" + "A0RvZDEQMA4GA1UECxMHVGVzdGluZzEVMBMGA1UEAxMMQ0ExLVBQLjAxLjAyMIGfMA0GCS" + "qGSIb3DQEBAQUAA4GNADCBiQKBgQCkQQXRO+dnU2v7EbaqQNmfPD8v0s5Wa50hl9M1Gfr5" + "5nuVUZs/RI//1VksTNrW10MVh11nsxpA/XRPntEIbHiH1OoECd4dnZBiA/2xEueM02fTjj" + "fb/t7g+pr9dSU/TzCVZDVWFBcPn4VNz7BBqIrTAOXaJkyBZ8hh7vyiE1Y2VQIDAQABo0sw" + "STAPBgNVHRMBAf8EBTADAQH/MA4GA1UdDwEB/wQEAwIBBjARBgNVHQ4ECgQIoTKVlZ8YCR" + "AwEwYDVR0jBAwwCoAIq5rr+cLnVI8wDQYJKoZIhvcNAQEFBQADgYEADhtnd6ifr6kyfC5D" + "UWuAXLtoccMj8Jaur/1YT1DgnH1XbBsEeZwm9Jkzr1a3cXPIHgaHYgXvBeGUtZ3XhbCSGp" + "8U6clJz3lm3qKPKkb5rdDrpdTaPnEJJjS3C4ZK1L7UZtQga2Enlelm5vIkhjsF3Sexe1kY" + "mzqiLZZ8yLxJ/Tg="; public static final String Intermediate_CRL_PP_01_02_crl = "MIIBSzCBtQIBATANBgkqhkiG9w0BAQUFADBeMQswCQYDVQQGEwJVUzEYMBYGA1UEChMPVS" + "5TLiBHb3Zlcm5tZW50MQwwCgYDVQQLEwNEb2QxEDAOBgNVBAsTB1Rlc3RpbmcxFTATBgNV" + "BAMTDENBMS1QUC4wMS4wMhcNOTkwMTAxMTIwMTAwWhcNNDgwMTAxMTIwMTAwWqAjMCEwCg" + "YDVR0UBAMCAQEwEwYDVR0jBAwwCoAIoTKVlZ8YCRAwDQYJKoZIhvcNAQEFBQADgYEAn94u" + "sT8ZYNzfHIdnx0+fV0jglL0Kn1duz+ehKHow+RGqH+J9opMYuXVD+rVQnLdZl5LbFBcv+5" + "TSP9WR9QtyoXar4/jmY2FFdBjfgO9w7p7OHD4WxblJmfPVOvrzFm/slZE39Oe5Qn4KlS03" + "9tttEFTKDH3qREQbT6g4k4ExxYM="; public static final String End_Certificate_PP_01_02_crt = "MIICbjCCAdegAwIBAgIBRjANBgkqhkiG9w0BAQUFADBeMQswCQYDVQQGEwJVUzEYMBYGA1" + "UEChMPVS5TLiBHb3Zlcm5tZW50MQwwCgYDVQQLEwNEb2QxEDAOBgNVBAsTB1Rlc3Rpbmcx" + "FTATBgNVBAMTDENBMS1QUC4wMS4wMjAeFw05ODAxMDExMjAxMDBaFw00ODAxMDExMjAxMD" + "BaMGAxCzAJBgNVBAYTAlVTMRgwFgYDVQQKEw9VLlMuIEdvdmVybm1lbnQxDDAKBgNVBAsT" + "A0RvRDEQMA4GA1UECxMHVGVzdGluZzEXMBUGA1UEAxMOVXNlcjEtUFAuMDEuMDIwgZ8wDQ" + "YJKoZIhvcNAQEBBQADgY0AMIGJAoGBANBwkwTWdZ977UAx6CCpXc9T4MX9T3/Tt6LbtY9I" + "eXxI9W15eXm/aqrKiXhULB+oF9/qNeUi2fAtrURZ7hgHbTaswr8CZ3Uwc6Rbkyj2GGiM6Z" + "8sKFztYZfFyGBiNEwfTT0yaUUQ6etIFqPuL/6qLvqXmvNPxFb9gjTH/azs/MdNAgMBAAGj" + "OjA4MA4GA1UdDwEB/wQEAwIF4DARBgNVHQ4ECgQIW1/BRCbe3c0wEwYDVR0jBAwwCoAIoT" + "KVlZ8YCRAwDQYJKoZIhvcNAQEFBQADgYEAPJg24q7wCU8CVlxFLchoe7txhkzApkVMIJ9G" + "+QTnraHDn0CZS6undCsJw8mrTNBQPHFn2Ixa5lrPfJvwW4Med1bcJKbwR4TveL1WeYYq6+" + "9k1kS/7KmqyKAKC/s504jAc7qgMd4b08oLxbGVfFVjWG/ZMbO770FrsyRHHs2rTOU="; public static final String[] TEST_35_DATA = new String[] { Intermediate_Certificate_PP_01_02_crt, Intermediate_CRL_PP_01_02_crl, End_Certificate_PP_01_02_crt }; /* * test36 * */ public static final String Intermediate_Certificate_1_PP_01_03_crt = "MIIClTCCAf6gAwIBAgIBRzANBgkqhkiG9w0BAQUFADBeMQswCQYDVQQGEwJVUzEYMBYGA1" + "UEChMPVS5TLiBHb3Zlcm5tZW50MQwwCgYDVQQLEwNEb0QxEDAOBgNVBAsTB1Rlc3Rpbmcx" + "FTATBgNVBAMTDFRydXN0IEFuY2hvcjAeFw05ODAxMDExMjAxMDBaFw00ODAxMDExMjAxMD" + "BaMF4xCzAJBgNVBAYTAlVTMRgwFgYDVQQKEw9VLlMuIEdvdmVybm1lbnQxDDAKBgNVBAsT" + "A0RvZDEQMA4GA1UECxMHVGVzdGluZzEVMBMGA1UEAxMMQ0ExLVBQLjAxLjAzMIGfMA0GCS" + "qGSIb3DQEBAQUAA4GNADCBiQKBgQDL/XgMvoeszcAzZqMYnv1At5u83Gb/CEX3fv6O1jL4" + "W3XbdvBNIZpuTwQhTH4Iofk9rIuQdkR7xOmbk4AqZINuas3Y1CPdzss7teraK0CNralNl1" + "jPYK+ClDBHt32Iw3bAl7RqWX73hl3YH6/7cvG4XCo1HqeeFFHUGa7HXGXq9QIDAQABo2Mw" + "YTAPBgNVHRMBAf8EBTADAQH/MA4GA1UdDwEB/wQEAwIBBjAWBgNVHSAEDzANMAsGCWCGSA" + "FlAwEwAjARBgNVHQ4ECgQITMu5Qbn1Cm4wEwYDVR0jBAwwCoAIq5rr+cLnVI8wDQYJKoZI" + "hvcNAQEFBQADgYEAuCnzXbHg87PIYYRbCCiXKDKA3MOcEKuxpNaSbtm12DQWpnvzmaK5nB" + "D/Ebko97CS7u9Tpwa7TmTyi39bYzY0dmVaotCDzfSTpzw6qHZl/w8riS+cKr0mimnjW1cq" + "kGPyHf0zBBqh0liGbd7EOLIBln0ASrn8V+G4Tj0Q6aQVcko="; public static final String Intermediate_Certificate_2_PP_01_03_crt = "MIIClTCCAf6gAwIBAgIBSDANBgkqhkiG9w0BAQUFADBeMQswCQYDVQQGEwJVUzEYMBYGA1" + "UEChMPVS5TLiBHb3Zlcm5tZW50MQwwCgYDVQQLEwNEb2QxEDAOBgNVBAsTB1Rlc3Rpbmcx" + "FTATBgNVBAMTDENBMS1QUC4wMS4wMzAeFw05ODAxMDExMjAxMDBaFw00ODAxMDExMjAxMD" + "BaMF4xCzAJBgNVBAYTAlVTMRgwFgYDVQQKEw9VLlMuIEdvdmVybm1lbnQxDDAKBgNVBAsT" + "A0RvZDEQMA4GA1UECxMHVGVzdGluZzEVMBMGA1UEAxMMQ0EyLVBQLjAxLjAzMIGfMA0GCS" + "qGSIb3DQEBAQUAA4GNADCBiQKBgQCu1Fq+gBJsBf5EjKKtNIxgdtgPMObby7tKH7fTJxYE" + "5LPyPi/IiWQ5Mi/8BCG3zmQhu9ZdBbpal350qCGVTbaMlnpi98D4WwXSw7e8oHIJIK689p" + "Q6Z5cf8hgwPnwDpYLeEaqxwhd4bu0x1lG1fUISA0ZZIQaEeNSJfdh15IkAswIDAQABo2Mw" + "YTAPBgNVHRMBAf8EBTADAQH/MA4GA1UdDwEB/wQEAwIBBjAWBgNVHSAEDzANMAsGCWCGSA" + "FlAwEwATARBgNVHQ4ECgQILRhQwULcyPYwEwYDVR0jBAwwCoAITMu5Qbn1Cm4wDQYJKoZI" + "hvcNAQEFBQADgYEAlEVOqXcdeTU7wT0l+/BJhlG5iaAcanAsOaJFZsXPjLMSjhldQe11/z" + "BsrrqjcpdctcmBarKO4MnwqVU9DN2RZ/v5Gps6OcPxj3T8wlrCGe4l6s9d1FncBMJ0RAUe" + "QEn2JLkQW5JWRBQ00+RXJYFuIM6Ger2MipWj1oOciv9MMoc="; public static final String Intermediate_CRL_1_PP_01_03_crl = "MIIBSzCBtQIBATANBgkqhkiG9w0BAQUFADBeMQswCQYDVQQGEwJVUzEYMBYGA1UEChMPVS" + "5TLiBHb3Zlcm5tZW50MQwwCgYDVQQLEwNEb2QxEDAOBgNVBAsTB1Rlc3RpbmcxFTATBgNV" + "BAMTDENBMS1QUC4wMS4wMxcNOTkwMTAxMTIwMTAwWhcNNDgwMTAxMTIwMTAwWqAjMCEwCg" + "YDVR0UBAMCAQEwEwYDVR0jBAwwCoAITMu5Qbn1Cm4wDQYJKoZIhvcNAQEFBQADgYEAycux" + "rzvy2IiYfFkTw7QgGuBhxIQPbSIbfudqyUumuviHJkIMZpPwYj2wltjyiRaozrDAWq8mlc" + "PsFYNr2lUYN5Cj4BhNQCNZlyBw7LLdzRgza55zVjmYkHWedyZm3kPWe7Y0w8xc/XIvi3iC" + "qlwV+X85cgHNJarx3GEYdb7Yos4="; public static final String Intermediate_CRL_2_PP_01_03_crl = "MIIBSzCBtQIBATANBgkqhkiG9w0BAQUFADBeMQswCQYDVQQGEwJVUzEYMBYGA1UEChMPVS" + "5TLiBHb3Zlcm5tZW50MQwwCgYDVQQLEwNEb2QxEDAOBgNVBAsTB1Rlc3RpbmcxFTATBgNV" + "BAMTDENBMi1QUC4wMS4wMxcNOTkwMTAxMTIwMTAwWhcNNDgwMTAxMTIwMTAwWqAjMCEwCg" + "YDVR0UBAMCAQEwEwYDVR0jBAwwCoAILRhQwULcyPYwDQYJKoZIhvcNAQEFBQADgYEAbcjU" + "+8l6pSik8PcuIzWndAg/w8uRfAgR5W9hPSXZChlx7uM+48wK98DGEXuTkJcbeclZia+Mpi" + "J5u3qG1zhoL1aHr+RqyJrjiWKC4/rDBuiUk/ftU54mrYn0qev3aSjf/GLtpcC8kC3gpqD+" + "20bvxLjBG3Vc9ZrxDvzfj8cD9K4="; public static final String End_Certificate_PP_01_03_crt = "MIIChjCCAe+gAwIBAgIBSTANBgkqhkiG9w0BAQUFADBeMQswCQYDVQQGEwJVUzEYMBYGA1" + "UEChMPVS5TLiBHb3Zlcm5tZW50MQwwCgYDVQQLEwNEb2QxEDAOBgNVBAsTB1Rlc3Rpbmcx" + "FTATBgNVBAMTDENBMi1QUC4wMS4wMzAeFw05ODAxMDExMjAxMDBaFw00ODAxMDExMjAxMD" + "BaMGAxCzAJBgNVBAYTAlVTMRgwFgYDVQQKEw9VLlMuIEdvdmVybm1lbnQxDDAKBgNVBAsT" + "A0RvRDEQMA4GA1UECxMHVGVzdGluZzEXMBUGA1UEAxMOVXNlcjEtUFAuMDEuMDMwgZ8wDQ" + "YJKoZIhvcNAQEBBQADgY0AMIGJAoGBAMO0l0+X6jfT8cY4DumtseTryyIJ7h+nraogXmYo" + "uhFGvMUWEAZVGD4x9QTTVEL/UCqNfzpI//Pp/uZpDudSgOX0ZdAbykObqCAEO85msK+eie" + "8baS1cW1XGjCuWDqNZko3Uo3c5lLPlRMbZ3hjvA1zmYh3prYnOh032GZAArVcVAgMBAAGj" + "UjBQMA4GA1UdDwEB/wQEAwIF4DAWBgNVHSAEDzANMAsGCWCGSAFlAwEwATARBgNVHQ4ECg" + "QIMh2aWvtm0mgwEwYDVR0jBAwwCoAILRhQwULcyPYwDQYJKoZIhvcNAQEFBQADgYEAigVE" + "FlCgbgKLR9FWIiwnz1bZ0MKsfhytllCI+jGx0Q3o3CxCGXs9PvL6BPDdMOxNIT/oU2uG64" + "EhZEjcZCnUknGx9OkkSSVq44P/pGuUx1g4Kx4i8gsJ/UPrPpYv/3heuMcKWCr92l33cxPT" + "IU+kmAtqy0MBvBKL4p635+MSIVA="; public static final String[] TEST_36_DATA = new String[] { Intermediate_Certificate_1_PP_01_03_crt, Intermediate_Certificate_2_PP_01_03_crt, Intermediate_CRL_1_PP_01_03_crl, Intermediate_CRL_2_PP_01_03_crl, End_Certificate_PP_01_03_crt }; /* * test37 * */ public static final String Intermediate_Certificate_1_PP_01_04_crt = "MIIClTCCAf6gAwIBAgIBSjANBgkqhkiG9w0BAQUFADBeMQswCQYDVQQGEwJVUzEYMBYGA1" + "UEChMPVS5TLiBHb3Zlcm5tZW50MQwwCgYDVQQLEwNEb0QxEDAOBgNVBAsTB1Rlc3Rpbmcx" + "FTATBgNVBAMTDFRydXN0IEFuY2hvcjAeFw05ODAxMDExMjAxMDBaFw00ODAxMDExMjAxMD" + "BaMF4xCzAJBgNVBAYTAlVTMRgwFgYDVQQKEw9VLlMuIEdvdmVybm1lbnQxDDAKBgNVBAsT" + "A0RvZDEQMA4GA1UECxMHVGVzdGluZzEVMBMGA1UEAxMMQ0ExLVBQLjAxLjA0MIGfMA0GCS" + "qGSIb3DQEBAQUAA4GNADCBiQKBgQC9gxMP8j4L+ISffY9wkislQ/V5sO9LzZOncYK93lZf" + "HXJG1MPSQzFPNzDLSc2zsilA03v6q+zr4NRrRWwWGmB34NGM4aqkoxox/7ngTn0MIq5gZ2" + "eOx0FbjA9W9DHEceVDS6kgs9lFcN2W+muCG2/fGqQUED9Fzl9JSM/tE8XAKwIDAQABo2Mw" + "YTAPBgNVHRMBAf8EBTADAQH/MA4GA1UdDwEB/wQEAwIBBjAWBgNVHSAEDzANMAsGCWCGSA" + "FlAwEwATARBgNVHQ4ECgQIgdUt9H4i6kwwEwYDVR0jBAwwCoAIq5rr+cLnVI8wDQYJKoZI" + "hvcNAQEFBQADgYEAxPe0vM0BvormJLF5HxkyFcTtoombfDGANoLoyj+PTWRD6z1/AcAx5K" + "rn/0J1sZo13M2ezaZUABbbpNH9X0OS225IJF4mXNpfkYhsz/+jNPGjRpN2p0K+DhMSawUw" + "QfGv2x6f31k6WCdy/769i1mwKP6Rpph2nkRyYW8MwO0N5HU="; public static final String Intermediate_Certificate_2_PP_01_04_crt = "MIIClTCCAf6gAwIBAgIBSzANBgkqhkiG9w0BAQUFADBeMQswCQYDVQQGEwJVUzEYMBYGA1" + "UEChMPVS5TLiBHb3Zlcm5tZW50MQwwCgYDVQQLEwNEb2QxEDAOBgNVBAsTB1Rlc3Rpbmcx" + "FTATBgNVBAMTDENBMS1QUC4wMS4wNDAeFw05ODAxMDExMjAxMDBaFw00ODAxMDExMjAxMD" + "BaMF4xCzAJBgNVBAYTAlVTMRgwFgYDVQQKEw9VLlMuIEdvdmVybm1lbnQxDDAKBgNVBAsT" + "A0RvZDEQMA4GA1UECxMHVGVzdGluZzEVMBMGA1UEAxMMQ0EyLVBQLjAxLjA0MIGfMA0GCS" + "qGSIb3DQEBAQUAA4GNADCBiQKBgQC7YCtN67S/ItOzaSGqTvfEE483HoQGiQZ0ob3+0beK" + "kmbSGADBQVBKe/sLJEKddyV2Gl8S4x+cKaKBWUI8lMZViJwWqVnyAFd8ZiAB/BpXaKKgP5" + "pFsg10Yo/EtsxGlLSTLurst0azNnFv7ca5Hb8te3T91eaI6y59IjbsRgilSQIDAQABo2Mw" + "YTAPBgNVHRMBAf8EBTADAQH/MA4GA1UdDwEB/wQEAwIBBjAWBgNVHSAEDzANMAsGCWCGSA" + "FlAwEwATARBgNVHQ4ECgQIGazrt+QRNCkwEwYDVR0jBAwwCoAIgdUt9H4i6kwwDQYJKoZI" + "hvcNAQEFBQADgYEAUIz/MSc6K5eaIAg8skaAgm6rSPvcU/711b9G0qsIs6YqvEz4zhGi5X" + "nalYYXfaSQzomuRuABNvuR1Ydaw/B9OdPMro0DhX8VpY6NzCL5Qj60/I4is5a+Hzgk82ck" + "eAC3okPHbVMd7R9kdFsWNE3Capnv7rriqXO3vwFw8b9vXD4="; public static final String Intermediate_CRL_1_PP_01_04_crl = "MIIBSzCBtQIBATANBgkqhkiG9w0BAQUFADBeMQswCQYDVQQGEwJVUzEYMBYGA1UEChMPVS" + "5TLiBHb3Zlcm5tZW50MQwwCgYDVQQLEwNEb2QxEDAOBgNVBAsTB1Rlc3RpbmcxFTATBgNV" + "BAMTDENBMS1QUC4wMS4wNBcNOTkwMTAxMTIwMTAwWhcNNDgwMTAxMTIwMTAwWqAjMCEwCg" + "YDVR0UBAMCAQEwEwYDVR0jBAwwCoAIgdUt9H4i6kwwDQYJKoZIhvcNAQEFBQADgYEAkR24" + "ebKfvEhDA0C7sawukQbv/q8mjSS3CrhA/oqeb8bML1IlW8rjHSXuRU/n3oeyAZuxLCAQMU" + "TPG6Vq4dOu8XC1RY74xIm8ps4mE0xB8/nI5kadHUSDPtUZhNzc8tv+z7fUGRaVGL7CBEpq" + "ICyQKYytCwxyf4xu2Ip71Uy2tuo="; public static final String Intermediate_CRL_2_PP_01_04_crl = "MIIBSzCBtQIBATANBgkqhkiG9w0BAQUFADBeMQswCQYDVQQGEwJVUzEYMBYGA1UEChMPVS" + "5TLiBHb3Zlcm5tZW50MQwwCgYDVQQLEwNEb2QxEDAOBgNVBAsTB1Rlc3RpbmcxFTATBgNV" + "BAMTDENBMi1QUC4wMS4wNBcNOTkwMTAxMTIwMTAwWhcNNDgwMTAxMTIwMTAwWqAjMCEwCg" + "YDVR0UBAMCAQEwEwYDVR0jBAwwCoAIGazrt+QRNCkwDQYJKoZIhvcNAQEFBQADgYEAjpUo" + "XSj0HX7Wm4w1FiRBBazInGOhSQX9VP2GcGb5lfr3GKt75Y+C+C9qd5X25DVkA4M1gPBK+u" + "XjSMQoHAmFJychQG23rcGcuDJlzRMyfvPCF9dOGLFdmkuHSo5hQUyYsxnXV8cWLIkR1AUz" + "PtUbTJL9g98R/OJFsCBiPi+By6w="; public static final String End_Certificate_PP_01_04_crt = "MIIChjCCAe+gAwIBAgIBTDANBgkqhkiG9w0BAQUFADBeMQswCQYDVQQGEwJVUzEYMBYGA1" + "UEChMPVS5TLiBHb3Zlcm5tZW50MQwwCgYDVQQLEwNEb2QxEDAOBgNVBAsTB1Rlc3Rpbmcx" + "FTATBgNVBAMTDENBMi1QUC4wMS4wNDAeFw05ODAxMDExMjAxMDBaFw00ODAxMDExMjAxMD" + "BaMGAxCzAJBgNVBAYTAlVTMRgwFgYDVQQKEw9VLlMuIEdvdmVybm1lbnQxDDAKBgNVBAsT" + "A0RvRDEQMA4GA1UECxMHVGVzdGluZzEXMBUGA1UEAxMOVXNlcjEtUFAuMDEuMDQwgZ8wDQ" + "YJKoZIhvcNAQEBBQADgY0AMIGJAoGBAOtf65MaydWM3bmMT8tAGCX8gZkx1JlgQyBlJT67" + "2APIkfmKRFK/dBtSwwCVGHZG4JYBrrwMpzUPrkGKYI6ZVIvvPnPfadZns9i5SM5LZFS+a5" + "JfbRnSJd8dXhZsKHxqkxIWwG6+VgnRKXE/Uc4m8TePQJZEOra5ezna5yhvqUwPAgMBAAGj" + "UjBQMA4GA1UdDwEB/wQEAwIF4DAWBgNVHSAEDzANMAsGCWCGSAFlAwEwAjARBgNVHQ4ECg" + "QI4iNoMjKiXMkwEwYDVR0jBAwwCoAIGazrt+QRNCkwDQYJKoZIhvcNAQEFBQADgYEAmOjp" + "2EupE1AmgjGfiGK1fk9kf39yQXK1EDsyO6KLdWL/bmWeYi/G7ZE57/+yVVADJuHI8xVIDZ" + "LAC0u5p35OLgbcmmA5bs52KWJJfa0nbgGpVaUSMg9SkEGS997OsgExWMvYhdFIKXlq4Rwc" + "ca89Hg1GlXdrpfD2OCDNBvcWB5Y="; public static final String[] TEST_37_DATA = new String[] { Intermediate_Certificate_1_PP_01_04_crt, Intermediate_Certificate_2_PP_01_04_crt, Intermediate_CRL_1_PP_01_04_crl, Intermediate_CRL_2_PP_01_04_crl, End_Certificate_PP_01_04_crt }; /* * test38 * */ public static final String Intermediate_Certificate_1_PP_01_05_crt = "MIIClTCCAf6gAwIBAgIBTTANBgkqhkiG9w0BAQUFADBeMQswCQYDVQQGEwJVUzEYMBYGA1" + "UEChMPVS5TLiBHb3Zlcm5tZW50MQwwCgYDVQQLEwNEb0QxEDAOBgNVBAsTB1Rlc3Rpbmcx" + "FTATBgNVBAMTDFRydXN0IEFuY2hvcjAeFw05ODAxMDExMjAxMDBaFw00ODAxMDExMjAxMD" + "BaMF4xCzAJBgNVBAYTAlVTMRgwFgYDVQQKEw9VLlMuIEdvdmVybm1lbnQxDDAKBgNVBAsT" + "A0RvZDEQMA4GA1UECxMHVGVzdGluZzEVMBMGA1UEAxMMQ0ExLVBQLjAxLjA1MIGfMA0GCS" + "qGSIb3DQEBAQUAA4GNADCBiQKBgQDFzEEzV/yUEORIOufyqpZzKpYz5aPyBbcDf8AMMCM5" + "tEz7j39cf1f227cbrTcAaUfYFwkrb07RU4bTS2X+U2Ak7Q5OROz5rrZBbsfwF3yHhwHxCg" + "KLjbwz7D+OJdNfv7x2HRckwfMUkmP4cEuJIIPwj1ieBbsnUi9dkWZePwl80QIDAQABo2Mw" + "YTAPBgNVHRMBAf8EBTADAQH/MA4GA1UdDwEB/wQEAwIBBjAWBgNVHSAEDzANMAsGCWCGSA" + "FlAwEwATARBgNVHQ4ECgQIjsCjmszYCHMwEwYDVR0jBAwwCoAIq5rr+cLnVI8wDQYJKoZI" + "hvcNAQEFBQADgYEAWMUBdOdHMB/SV5kPUk+zut9g/1v/GyxyB60mq9jGqjrIsk4a9JRqa5" + "MWju+6kVfSLelAOCR24EQsXnZM/5Qqg3Wb/SFJXWDcBnfWQWgh8UmJfmPhD7jViG5QVIxn" + "iALNCYtz373L+IDECLMO6S3wcTPsHdYv14jl6BKtabwIpE4="; public static final String Intermediate_Certificate_2_PP_01_05_crt = "MIIClTCCAf6gAwIBAgIBTjANBgkqhkiG9w0BAQUFADBeMQswCQYDVQQGEwJVUzEYMBYGA1" + "UEChMPVS5TLiBHb3Zlcm5tZW50MQwwCgYDVQQLEwNEb2QxEDAOBgNVBAsTB1Rlc3Rpbmcx" + "FTATBgNVBAMTDENBMS1QUC4wMS4wNTAeFw05ODAxMDExMjAxMDBaFw00ODAxMDExMjAxMD" + "BaMF4xCzAJBgNVBAYTAlVTMRgwFgYDVQQKEw9VLlMuIEdvdmVybm1lbnQxDDAKBgNVBAsT" + "A0RvZDEQMA4GA1UECxMHVGVzdGluZzEVMBMGA1UEAxMMQ0EyLVBQLjAxLjA1MIGfMA0GCS" + "qGSIb3DQEBAQUAA4GNADCBiQKBgQCZzdj+ixWCuxJGMjcoHUwSNqI9Wt9gYwXUTl+dWg/E" + "lg2SPJP7lrBOibAhSmaTorhunUSEf2adhdxhuGrd5Ucp6G0oZAa6ZDWaID4rKYWsI7d5kv" + "mrUhDEEdzk2s4PCoPiQm4dKwRg2rIvA5Dv+W1ldqSVSG376zVrQ5xdjDUX5QIDAQABo2Mw" + "YTAPBgNVHRMBAf8EBTADAQH/MA4GA1UdDwEB/wQEAwIBBjAWBgNVHSAEDzANMAsGCWCGSA" + "FlAwEwAjARBgNVHQ4ECgQIUASviIKBmJgwEwYDVR0jBAwwCoAIjsCjmszYCHMwDQYJKoZI" + "hvcNAQEFBQADgYEAa3c+0Drcq7iWP7K+gE6Mz/0ATQoiG87irXWfWBUGWtYnsh6K+1THMl" + "ibmZjYhsztK1P5rm6qL6HAyw0PhrRE9imqZ16cgiMomh65BWQImOeiXx9YWIPvjXWsE6iV" + "E31XShr9b9OZBA2+Zpydc3ID/SQzy9PiTAfL5yJiW/JZvFw="; public static final String Intermediate_CRL_1_PP_01_05_crl = "MIIBSzCBtQIBATANBgkqhkiG9w0BAQUFADBeMQswCQYDVQQGEwJVUzEYMBYGA1UEChMPVS" + "5TLiBHb3Zlcm5tZW50MQwwCgYDVQQLEwNEb2QxEDAOBgNVBAsTB1Rlc3RpbmcxFTATBgNV" + "BAMTDENBMS1QUC4wMS4wNRcNOTkwMTAxMTIwMTAwWhcNNDgwMTAxMTIwMTAwWqAjMCEwCg" + "YDVR0UBAMCAQEwEwYDVR0jBAwwCoAIjsCjmszYCHMwDQYJKoZIhvcNAQEFBQADgYEAZIzN" + "pXT89MplQgcXcA/K7YKlf62QCbw3rE+bUQiumJMlNGiVdaNJ8T66ObyoOWE+s+KN/Oetlu" + "HglQ7r6RG68gHYtZZiO6kmxq+wor65dFGQyRggpD+D47yioEgR12wUUksL/8oBW1pfGW2B" + "dR4sNWjzV5k5EWbLYu7wxj2/ubo="; public static final String Intermediate_CRL_2_PP_01_05_crl = "MIIBSzCBtQIBATANBgkqhkiG9w0BAQUFADBeMQswCQYDVQQGEwJVUzEYMBYGA1UEChMPVS" + "5TLiBHb3Zlcm5tZW50MQwwCgYDVQQLEwNEb2QxEDAOBgNVBAsTB1Rlc3RpbmcxFTATBgNV" + "BAMTDENBMi1QUC4wMS4wNRcNOTkwMTAxMTIwMTAwWhcNNDgwMTAxMTIwMTAwWqAjMCEwCg" + "YDVR0UBAMCAQEwEwYDVR0jBAwwCoAIUASviIKBmJgwDQYJKoZIhvcNAQEFBQADgYEAlZ06" + "h2L/89GvCtU1K1VtbHPMN/LAUYJrWFID1Eo+Cf/5wKEGBr8hxRtvshTK436zqVQRQN/XTq" + "7u0SLxvIixNRErlmUlGByi5vumN2OA77SxOyqYLCnBXTd5tWbFGz/udjaNk1MxOK0MQxPV" + "9R+HHUUVojRnAIQvlcqx/sMzU5o="; public static final String End_Certificate_PP_01_05_crt = "MIIChjCCAe+gAwIBAgIBTzANBgkqhkiG9w0BAQUFADBeMQswCQYDVQQGEwJVUzEYMBYGA1" + "UEChMPVS5TLiBHb3Zlcm5tZW50MQwwCgYDVQQLEwNEb2QxEDAOBgNVBAsTB1Rlc3Rpbmcx" + "FTATBgNVBAMTDENBMi1QUC4wMS4wNTAeFw05ODAxMDExMjAxMDBaFw00ODAxMDExMjAxMD" + "BaMGAxCzAJBgNVBAYTAlVTMRgwFgYDVQQKEw9VLlMuIEdvdmVybm1lbnQxDDAKBgNVBAsT" + "A0RvRDEQMA4GA1UECxMHVGVzdGluZzEXMBUGA1UEAxMOVXNlcjEtUFAuMDEuMDUwgZ8wDQ" + "YJKoZIhvcNAQEBBQADgY0AMIGJAoGBALyBn2GKvoKNHcu3AEJRCbWOyUpCc/onvRoQgWRr" + "wE7vMI7vjqnoR8mXdWDW5u9DFu9V5pb/yHBWn1zpgFGNnLrqn8irwR9i6Q+qlu4lXL5WSr" + "DqBqEKxrOBDPgkVz8Ldjt/Hy57qEukBarvpAwTc4XEJPAmxNrboMeGCEn2UShbAgMBAAGj" + "UjBQMA4GA1UdDwEB/wQEAwIF4DAWBgNVHSAEDzANMAsGCWCGSAFlAwEwATARBgNVHQ4ECg" + "QIaV3Cd/83r08wEwYDVR0jBAwwCoAIUASviIKBmJgwDQYJKoZIhvcNAQEFBQADgYEAVJXz" + "gooT1qd6rdehnLxJMf1HZ6JuqpyoQjzWF1jA3SkJmBDMXvAkMmIcQ7r5CZHaVF0iMQl5JW" + "fxPtM9Bws6jZhVL0TkwJHmbnSvbzUkJYeXPCP7ags4bu5I32co1nFVF6wf3aQDZeLFj/TU" + "1GCQ4rh80T5oknuazD4xXAYx9sE="; public static final String[] TEST_38_DATA = new String[] { Intermediate_Certificate_1_PP_01_05_crt, Intermediate_Certificate_2_PP_01_05_crt, Intermediate_CRL_1_PP_01_05_crl, Intermediate_CRL_2_PP_01_05_crl, End_Certificate_PP_01_05_crt }; /* * test39 * */ public static final String Intermediate_Certificate_1_PP_01_06_crt = "MIICvjCCAiegAwIBAgIBUDANBgkqhkiG9w0BAQUFADBeMQswCQYDVQQGEwJVUzEYMBYGA1" + "UEChMPVS5TLiBHb3Zlcm5tZW50MQwwCgYDVQQLEwNEb0QxEDAOBgNVBAsTB1Rlc3Rpbmcx" + "FTATBgNVBAMTDFRydXN0IEFuY2hvcjAeFw05ODAxMDExMjAxMDBaFw00ODAxMDExMjAxMD" + "BaMF4xCzAJBgNVBAYTAlVTMRgwFgYDVQQKEw9VLlMuIEdvdmVybm1lbnQxDDAKBgNVBAsT" + "A0RvZDEQMA4GA1UECxMHVGVzdGluZzEVMBMGA1UEAxMMQ0ExLVBQLjAxLjA2MIGfMA0GCS" + "qGSIb3DQEBAQUAA4GNADCBiQKBgQCjeJAwaZ0cw6O76hu15XadwJiTsIJcXZxGAETq8H9p" + "VJs7kJh57oLpO/lG8zG89QS9g1ozxaaGDWsSyXsDzv1eqDVZg3ISQu6XcKdDu8EwgQDY3S" + "EGkJ2AidFue3l0kEwR9+rtsuVKd/P+ULF1hWcoyLB/sQD5z8GvIiDKyRBiFwIDAQABo4GL" + "MIGIMA8GA1UdEwEB/wQFMAMBAf8wDgYDVR0PAQH/BAQDAgEGMD0GA1UdIAQ2MDQwCwYJYI" + "ZIAWUDATABMAsGCWCGSAFlAwEwAjALBglghkgBZQMBMAMwCwYJYIZIAWUDATAEMBEGA1Ud" + "DgQKBAh9i6tKUsPTgTATBgNVHSMEDDAKgAirmuv5wudUjzANBgkqhkiG9w0BAQUFAAOBgQ" + "B/Gxsb5lxSTN21CrjBp2aE+U1oTP2MpIFWUD1q8KWhZZF1iCQ7orcDVITqJPdPxDu1YwKk" + "zOegc4YBSJzHZqF/W4Kw4wisMfnWLTsUAeP/Ucz4vXk5rsf7IRssFG6PLxVmtRZizoxl9a" + "DO9abTM/jV8Mgi1IB6LdWgmtosBGBzbQ=="; public static final String Intermediate_Certificate_2_PP_01_06_crt = "MIICrzCCAhigAwIBAgIBUTANBgkqhkiG9w0BAQUFADBeMQswCQYDVQQGEwJVUzEYMBYGA1" + "UEChMPVS5TLiBHb3Zlcm5tZW50MQwwCgYDVQQLEwNEb2QxEDAOBgNVBAsTB1Rlc3Rpbmcx" + "FTATBgNVBAMTDENBMS1QUC4wMS4wNjAeFw05ODAxMDExMjAxMDBaFw00ODAxMDExMjAxMD" + "BaMF4xCzAJBgNVBAYTAlVTMRgwFgYDVQQKEw9VLlMuIEdvdmVybm1lbnQxDDAKBgNVBAsT" + "A0RvZDEQMA4GA1UECxMHVGVzdGluZzEVMBMGA1UEAxMMQ0EyLVBQLjAxLjA2MIGfMA0GCS" + "qGSIb3DQEBAQUAA4GNADCBiQKBgQC8DbqYUf437toWlRkOQA5PloqYQjWYpiR67yGSjQHp" + "j/HlduTYFS4qfUbLCjH4qsNUH8yQDvogImQw5M1IQOsUAqO6mYFxjqUWccuOaHT6XfUaOs" + "DDHr/tQUvhz3LJryaILiPlNcQF8QiYpujM1utVRyFpmUrMAlOvWUB93c/xUQIDAQABo30w" + "ezAPBgNVHRMBAf8EBTADAQH/MA4GA1UdDwEB/wQEAwIBBjAwBgNVHSAEKTAnMAsGCWCGSA" + "FlAwEwATALBglghkgBZQMBMAIwCwYJYIZIAWUDATADMBEGA1UdDgQKBAgQxGVMTJml1TAT" + "BgNVHSMEDDAKgAh9i6tKUsPTgTANBgkqhkiG9w0BAQUFAAOBgQALJtPqY5uROJ+2QYTekn" + "fSUc0gC7j3/cngIvxGT385xDLTrd6TjYSi+12+vU7RNd3MIZoz1o7RpWQV6C751WtOFuZi" + "iXeQ758aLqfhjYSVW/NHkO8vjrAMUzUbgjqb03k7q5JgtT6udB+9ySmou2/RxYW5p/IT17" + "euMVGmQb/RFg=="; public static final String Intermediate_Certificate_3_PP_01_06_crt = "MIICojCCAgugAwIBAgIBUjANBgkqhkiG9w0BAQUFADBeMQswCQYDVQQGEwJVUzEYMBYGA1" + "UEChMPVS5TLiBHb3Zlcm5tZW50MQwwCgYDVQQLEwNEb2QxEDAOBgNVBAsTB1Rlc3Rpbmcx" + "FTATBgNVBAMTDENBMi1QUC4wMS4wNjAeFw05ODAxMDExMjAxMDBaFw00ODAxMDExMjAxMD" + "BaMF4xCzAJBgNVBAYTAlVTMRgwFgYDVQQKEw9VLlMuIEdvdmVybm1lbnQxDDAKBgNVBAsT" + "A0RvZDEQMA4GA1UECxMHVGVzdGluZzEVMBMGA1UEAxMMQ0EzLVBQLjAxLjA2MIGfMA0GCS" + "qGSIb3DQEBAQUAA4GNADCBiQKBgQCsQqIx0ayxpIE8NduclvK1ubbNkXyvr0RDqnGOoyTj" + "yMtnfnwRbclkFCNBdalZYofuTWP0reqvqGqsBj+RS3uazvDBqVmn0J0AGRiLILummgEFRJ" + "ow8IB1hduDYJpDMrHRpfXpbG2H3fzN1XeX/B0hUZgdQ86GyK2qrmyIcyqZXwIDAQABo3Aw" + "bjAPBgNVHRMBAf8EBTADAQH/MA4GA1UdDwEB/wQEAwIBBjAjBgNVHSAEHDAaMAsGCWCGSA" + "FlAwEwATALBglghkgBZQMBMAIwEQYDVR0OBAoECNKJMmEWCA+jMBMGA1UdIwQMMAqACBDE" + "ZUxMmaXVMA0GCSqGSIb3DQEBBQUAA4GBAKv9F3+Y4N8RX4bRZ4fFTKri2rrB4BsVrBFpOr" + "SLzKnuyO1O5gg45d70pSHUAVBn3pz0f/6WwWLECq9tB7/Fphi0TyqeFmkRnysygZGlvLgs" + "L19bpIgVPkjFFziMGuzdAFIGy8vnV19yJ2euMygEHr20yiGBUaHHnKyuOGbDg4i7"; public static final String Intermediate_CRL_1_PP_01_06_crl = "MIIBSzCBtQIBATANBgkqhkiG9w0BAQUFADBeMQswCQYDVQQGEwJVUzEYMBYGA1UEChMPVS" + "5TLiBHb3Zlcm5tZW50MQwwCgYDVQQLEwNEb2QxEDAOBgNVBAsTB1Rlc3RpbmcxFTATBgNV" + "BAMTDENBMS1QUC4wMS4wNhcNOTkwMTAxMTIwMTAwWhcNNDgwMTAxMTIwMTAwWqAjMCEwCg" + "YDVR0UBAMCAQEwEwYDVR0jBAwwCoAIfYurSlLD04EwDQYJKoZIhvcNAQEFBQADgYEARL4u" + "DZvfcQDYanTfwU/hWAJDdDO7m7oQZLy3o0PTqXkk2Jd2v3+M2U8UN2PcuqZXT1lwS/piiW" + "Sc1x1YndD0qUtV4bOZ9SESPhCeOc1lQTk5mMf/zqFxQqYv8rfDB5O3QY4bjS7QQzSsvmal" + "TGCnoHmUJ4skmZJrQAzYnXyD9G4="; public static final String Intermediate_CRL_2_PP_01_06_crl = "MIIBSzCBtQIBATANBgkqhkiG9w0BAQUFADBeMQswCQYDVQQGEwJVUzEYMBYGA1UEChMPVS" + "5TLiBHb3Zlcm5tZW50MQwwCgYDVQQLEwNEb2QxEDAOBgNVBAsTB1Rlc3RpbmcxFTATBgNV" + "BAMTDENBMi1QUC4wMS4wNhcNOTkwMTAxMTIwMTAwWhcNNDgwMTAxMTIwMTAwWqAjMCEwCg" + "YDVR0UBAMCAQEwEwYDVR0jBAwwCoAIEMRlTEyZpdUwDQYJKoZIhvcNAQEFBQADgYEAcEyr" + "sgLhVq0L6N5fww/U6TW4lqaVAEtjqxluWRyZnL3AJLEHfwh1lllCG5dNM5fahGDOW/53fV" + "+gW5l92bsi2D/lAkDfNUdQdi5ZpQG9y2zhTArUlx9z1+KXklCi2Gg1X22gi+cYbK2hfzk6" + "kNGP1v42bjrkF/ECczpy3e41rEg="; public static final String Intermediate_CRL_3_PP_01_06_crl = "MIIBSzCBtQIBATANBgkqhkiG9w0BAQUFADBeMQswCQYDVQQGEwJVUzEYMBYGA1UEChMPVS" + "5TLiBHb3Zlcm5tZW50MQwwCgYDVQQLEwNEb2QxEDAOBgNVBAsTB1Rlc3RpbmcxFTATBgNV" + "BAMTDENBMy1QUC4wMS4wNhcNOTkwMTAxMTIwMTAwWhcNNDgwMTAxMTIwMTAwWqAjMCEwCg" + "YDVR0UBAMCAQEwEwYDVR0jBAwwCoAI0okyYRYID6MwDQYJKoZIhvcNAQEFBQADgYEAp3uQ" + "Tn2HC65TFmSjzvjuStIJwJcVahNcTWiGdtfTalZrMtuC9vUgQq0K1QIa7QNC9C3hQlzb5e" + "bO7JhJDs+5GZnnsqHN3pvdKEoueRfWBjUGpPnSGFD61ysf9aDFY2j9Amf3zcBFsXZs4+DM" + "dIENndbjkwqCV4zRTajAqCsIy20="; public static final String End_Certificate_PP_01_06_crt = "MIIClTCCAf6gAwIBAgIBUzANBgkqhkiG9w0BAQUFADBeMQswCQYDVQQGEwJVUzEYMBYGA1" + "UEChMPVS5TLiBHb3Zlcm5tZW50MQwwCgYDVQQLEwNEb2QxEDAOBgNVBAsTB1Rlc3Rpbmcx" + "FTATBgNVBAMTDENBMy1QUC4wMS4wNjAeFw05ODAxMDExMjAxMDBaFw00ODAxMDExMjAxMD" + "BaMF4xCzAJBgNVBAYTAlVTMRgwFgYDVQQKEw9VLlMuIEdvdmVybm1lbnQxDDAKBgNVBAsT" + "A0RvZDEQMA4GA1UECxMHVGVzdGluZzEVMBMGA1UEAxMMQ0E0LVBQLjAxLjA2MIGfMA0GCS" + "qGSIb3DQEBAQUAA4GNADCBiQKBgQC+IxiNJMOQG2gx1xd9ELNuzs9LrVJVRLvgP0lpWrx2" + "2HTEXPDB6YmrEg/YgyptmQ5Z4K6CEgJz3EdDOarCSGcL7DmcSEwEw46MV3piS5DrHwQ4GH" + "a2/ENSh3lF+6dliBwbQR2necmQ5g8ekqkWNb65pLl6RCNGkntJpdu8w5GWbwIDAQABo2Mw" + "YTAPBgNVHRMBAf8EBTADAQH/MA4GA1UdDwEB/wQEAwIF4DAWBgNVHSAEDzANMAsGCWCGSA" + "FlAwEwATARBgNVHQ4ECgQIMf/eRyakKwgwEwYDVR0jBAwwCoAI0okyYRYID6MwDQYJKoZI" + "hvcNAQEFBQADgYEADgpHRDgyPuK4dc+m2p0IELHUAK3qsdTZzBXsaA0rkkk1aRjI6DQ2qg" + "b4crRU3spQgYwBC7KQYd/hp8Lk17iX6fdV/9wol0DxTGhamOJA0uRl768awRArf4cEUElF" + "uWPN8D3wJEfL6BWgReUJWg8V9HEtdvXZZgzFN/CgHRkQ2RM="; public static final String[] TEST_39_DATA = new String[] { Intermediate_Certificate_1_PP_01_06_crt, Intermediate_Certificate_2_PP_01_06_crt, Intermediate_Certificate_3_PP_01_06_crt, Intermediate_CRL_1_PP_01_06_crl, Intermediate_CRL_2_PP_01_06_crl, Intermediate_CRL_3_PP_01_06_crl, End_Certificate_PP_01_06_crt }; /* * test40 * */ public static final String Intermediate_Certificate_1_PP_01_07_crt = "MIICrzCCAhigAwIBAgIBVDANBgkqhkiG9w0BAQUFADBeMQswCQYDVQQGEwJVUzEYMBYGA1" + "UEChMPVS5TLiBHb3Zlcm5tZW50MQwwCgYDVQQLEwNEb0QxEDAOBgNVBAsTB1Rlc3Rpbmcx" + "FTATBgNVBAMTDFRydXN0IEFuY2hvcjAeFw05ODAxMDExMjAxMDBaFw00ODAxMDExMjAxMD" + "BaMF4xCzAJBgNVBAYTAlVTMRgwFgYDVQQKEw9VLlMuIEdvdmVybm1lbnQxDDAKBgNVBAsT" + "A0RvZDEQMA4GA1UECxMHVGVzdGluZzEVMBMGA1UEAxMMQ0ExLVBQLjAxLjA3MIGfMA0GCS" + "qGSIb3DQEBAQUAA4GNADCBiQKBgQDs3Z/FfgJOyKp+Ds8xiQBM053cWylYbD+g+zuWDz3d" + "nD0eF77TLPITL7hwI058Pn3tXHlveuKMFqbvzWUgFXaBoHmmRohIj1eqfJQhlmKLjlSYyC" + "N4xhLVi7vg71ZjFdRk1k8ME1HDfpb2WXqXh9LyRYY8b/aqL+NHe1PUDbT6FQIDAQABo30w" + "ezAPBgNVHRMBAf8EBTADAQH/MA4GA1UdDwEB/wQEAwIBBjAwBgNVHSAEKTAnMAsGCWCGSA" + "FlAwEwATALBglghkgBZQMBMAIwCwYJYIZIAWUDATADMBEGA1UdDgQKBAgvehPxsTfSBDAT" + "BgNVHSMEDDAKgAirmuv5wudUjzANBgkqhkiG9w0BAQUFAAOBgQBpdMBEONGcpFitMN1ihf" + "W441E4HVTQwtF+h56aagVFndUF1gQsVEdDNmvvN/jdlzXotcfdEj1lOahmcwWbPOlNx3PB" + "LUPAcaNM9SCrXWi1gKJK3gXC2OAxj0mT5XhfPlAdfhZXTBZLqMqebmk6kVwa+VyPPZFHGy" + "BW0fV2ClJ69Q=="; public static final String Intermediate_Certificate_2_PP_01_07_crt = "MIICojCCAgugAwIBAgIBVTANBgkqhkiG9w0BAQUFADBeMQswCQYDVQQGEwJVUzEYMBYGA1" + "UEChMPVS5TLiBHb3Zlcm5tZW50MQwwCgYDVQQLEwNEb2QxEDAOBgNVBAsTB1Rlc3Rpbmcx" + "FTATBgNVBAMTDENBMS1QUC4wMS4wNzAeFw05ODAxMDExMjAxMDBaFw00ODAxMDExMjAxMD" + "BaMF4xCzAJBgNVBAYTAlVTMRgwFgYDVQQKEw9VLlMuIEdvdmVybm1lbnQxDDAKBgNVBAsT" + "A0RvZDEQMA4GA1UECxMHVGVzdGluZzEVMBMGA1UEAxMMQ0EyLVBQLjAxLjA3MIGfMA0GCS" + "qGSIb3DQEBAQUAA4GNADCBiQKBgQCrO/98w96Bg5YTTmtdc9sL8AOABGcYx5J8E1Y7/GhU" + "2sInc/j0dtBbE0Tj4KFIKpVLD0m2mTyHVCUA0/QGiS1Tq6DzmZW/V36Clya3CoX9rDTJyU" + "cKHpgntV19fFAK58aksyKCdP9jjLpbSspzOlIc+mVW+hkjgw3NcuY6fAOQvQIDAQABo3Aw" + "bjAPBgNVHRMBAf8EBTADAQH/MA4GA1UdDwEB/wQEAwIBBjAjBgNVHSAEHDAaMAsGCWCGSA" + "FlAwEwATALBglghkgBZQMBMAIwEQYDVR0OBAoECEmeATXRkM5EMBMGA1UdIwQMMAqACC96" + "E/GxN9IEMA0GCSqGSIb3DQEBBQUAA4GBAG/Qv60jyImedUXtCYl0QpQ1Ne2ZLxvUHRLms8" + "B1nXC/Rze7zfz5cwiyQn+6XN2rhuYFdTMDEFZDIjeeCLNllfan4GUAdRGtoJnfoLOGLlQf" + "RW1ONc80cxd1NTxHqxOtqpWdoJQEn8070WLqQPACEs88XYKBZ00sF9ZdSg5vhHUu"; public static final String Intermediate_Certificate_3_PP_01_07_crt = "MIIClTCCAf6gAwIBAgIBVjANBgkqhkiG9w0BAQUFADBeMQswCQYDVQQGEwJVUzEYMBYGA1" + "UEChMPVS5TLiBHb3Zlcm5tZW50MQwwCgYDVQQLEwNEb2QxEDAOBgNVBAsTB1Rlc3Rpbmcx" + "FTATBgNVBAMTDENBMi1QUC4wMS4wNzAeFw05ODAxMDExMjAxMDBaFw00ODAxMDExMjAxMD" + "BaMF4xCzAJBgNVBAYTAlVTMRgwFgYDVQQKEw9VLlMuIEdvdmVybm1lbnQxDDAKBgNVBAsT" + "A0RvZDEQMA4GA1UECxMHVGVzdGluZzEVMBMGA1UEAxMMQ0EzLVBQLjAxLjA3MIGfMA0GCS" + "qGSIb3DQEBAQUAA4GNADCBiQKBgQC+5b7o4iWl80ntDMKGcnquLQDTGlf6Gy/8y34Vw08/" + "8ij+nuHMiKpo6UCF0OpDcnkJ2ovvMsY5dAb5ErhH64UbnMlKbghnGv0sVidtipoC8u7ey1" + "YUIzDCdmbNvTfho6IXKzH8ev//K+FJd3qBuKHl9u2Kk5+igsyb+bPSid7d/QIDAQABo2Mw" + "YTAPBgNVHRMBAf8EBTADAQH/MA4GA1UdDwEB/wQEAwIBBjAWBgNVHSAEDzANMAsGCWCGSA" + "FlAwEwATARBgNVHQ4ECgQIUDKu7h5EQ70wEwYDVR0jBAwwCoAISZ4BNdGQzkQwDQYJKoZI" + "hvcNAQEFBQADgYEAnKhR3OvdgtVtmio7ikCvjxlSoKVbUleazxONOxHUAKdXEv0/mSOTwp" + "hPPIoE2xAqPOOHvXPmzmJpPADjrfhU6afJ7ThDRFTMk4ZLOkT1SvRlymK7uWhj5bhUgi6S" + "UQ2LUmrY2hIN4cTrrzZvDw2Q/6UIuqpmySXEOHDL5T5MXEo="; public static final String Intermediate_CRL_1_PP_01_07_crl = "MIIBSzCBtQIBATANBgkqhkiG9w0BAQUFADBeMQswCQYDVQQGEwJVUzEYMBYGA1UEChMPVS" + "5TLiBHb3Zlcm5tZW50MQwwCgYDVQQLEwNEb2QxEDAOBgNVBAsTB1Rlc3RpbmcxFTATBgNV" + "BAMTDENBMS1QUC4wMS4wNxcNOTkwMTAxMTIwMTAwWhcNNDgwMTAxMTIwMTAwWqAjMCEwCg" + "YDVR0UBAMCAQEwEwYDVR0jBAwwCoAIL3oT8bE30gQwDQYJKoZIhvcNAQEFBQADgYEA4gZR" + "71wRXNdxWe7kaQPAw44UUw+cN1bDBU0RV7nwYAFDYxDIaDGOfjhUVTMBq4rb51S7uqIqYS" + "F6j7BdLXl9WVRJobfkRH0t0cBnuSeQRz3ckrZrCuvyxb3PEL3pbf0UH1i/BfoG+EHJAY7R" + "OVOL/dyoXeX6ehH6ImGhucDixS0="; public static final String Intermediate_CRL_2_PP_01_07_crl = "MIIBSzCBtQIBATANBgkqhkiG9w0BAQUFADBeMQswCQYDVQQGEwJVUzEYMBYGA1UEChMPVS" + "5TLiBHb3Zlcm5tZW50MQwwCgYDVQQLEwNEb2QxEDAOBgNVBAsTB1Rlc3RpbmcxFTATBgNV" + "BAMTDENBMi1QUC4wMS4wNxcNOTkwMTAxMTIwMTAwWhcNNDgwMTAxMTIwMTAwWqAjMCEwCg" + "YDVR0UBAMCAQEwEwYDVR0jBAwwCoAISZ4BNdGQzkQwDQYJKoZIhvcNAQEFBQADgYEAfzKw" + "NHrl10PJDHa3olBYXYzXi94zxDsEQSIb+W4pPXUfDZijPqL1NzapLqc/uL1Sl28GmLDrbm" + "nCrlMn1Kt/gI6XndOnSyC9Sg6WDxAI3HTHxlG5MHLBn9Lb36CHobnwep1BMo8zl2clh0Kz" + "PIxQSGXM1BDpHkwF5eoFAolDih4="; public static final String Intermediate_CRL_3_PP_01_07_crl = "MIIBSzCBtQIBATANBgkqhkiG9w0BAQUFADBeMQswCQYDVQQGEwJVUzEYMBYGA1UEChMPVS" + "5TLiBHb3Zlcm5tZW50MQwwCgYDVQQLEwNEb2QxEDAOBgNVBAsTB1Rlc3RpbmcxFTATBgNV" + "BAMTDENBMy1QUC4wMS4wNxcNOTkwMTAxMTIwMTAwWhcNNDgwMTAxMTIwMTAwWqAjMCEwCg" + "YDVR0UBAMCAQEwEwYDVR0jBAwwCoAIUDKu7h5EQ70wDQYJKoZIhvcNAQEFBQADgYEAj7+M" + "EeIe1GmJpbRUFqbNrDvT5tHjKQMNdbe5Y8F920U5t0ig1Up60kc7hs7LH57i6R/quPOpym" + "a9Eo9Bql+P2Bg9FELih5/a4B021TZBmmdSI5fwQZ6Q5PjgG58Zl2cJitNYvGi7tVUBojA5" + "CSN7KBMyipia9ivxm9a/llJPrQY="; public static final String End_Certificate_PP_01_07_crt = "MIIClTCCAf6gAwIBAgIBVzANBgkqhkiG9w0BAQUFADBeMQswCQYDVQQGEwJVUzEYMBYGA1" + "UEChMPVS5TLiBHb3Zlcm5tZW50MQwwCgYDVQQLEwNEb2QxEDAOBgNVBAsTB1Rlc3Rpbmcx" + "FTATBgNVBAMTDENBMy1QUC4wMS4wNzAeFw05ODAxMDExMjAxMDBaFw00ODAxMDExMjAxMD" + "BaMF4xCzAJBgNVBAYTAlVTMRgwFgYDVQQKEw9VLlMuIEdvdmVybm1lbnQxDDAKBgNVBAsT" + "A0RvZDEQMA4GA1UECxMHVGVzdGluZzEVMBMGA1UEAxMMQ0E0LVBQLjAxLjA3MIGfMA0GCS" + "qGSIb3DQEBAQUAA4GNADCBiQKBgQC/RmUcYHxgQRHCUh5cMug/J2o8DzYbT+2pIehJkNCr" + "zfqemV3qshLdMct5GV73oEkG5b6n7tj3/hI1TLh/A3LQpKROAGZybdo9fk4Pa0+6V6ql/U" + "NnSpcAKct/f3IvchGo9nBGdi9aE+j+xKhMM6E8xj1+Jc7Z0xz7zE4+qRbeZQIDAQABo2Mw" + "YTAPBgNVHRMBAf8EBTADAQH/MA4GA1UdDwEB/wQEAwIF4DAWBgNVHSAEDzANMAsGCWCGSA" + "FlAwEwAjARBgNVHQ4ECgQI/y572lfRyH4wEwYDVR0jBAwwCoAIUDKu7h5EQ70wDQYJKoZI" + "hvcNAQEFBQADgYEANl9zdMKbaq14OP45PeK9D4ftOSuliW2di1qAX38FQoWPYLLoaDU0Q1" + "9I54PDY/UYRR9jKDl1WPhV6cD+65eadtiOZVr/h1CaW/HxTloouzN4z1zCXMC7AxZKo+EI" + "XLN8f4w7hKLFYgf6gP9+iVi+T2gKfH5Ch2zjRhlmGFRgsBQ="; public static final String[] TEST_40_DATA = new String[] { Intermediate_Certificate_1_PP_01_07_crt, Intermediate_Certificate_2_PP_01_07_crt, Intermediate_Certificate_3_PP_01_07_crt, Intermediate_CRL_1_PP_01_07_crl, Intermediate_CRL_2_PP_01_07_crl, Intermediate_CRL_3_PP_01_07_crl, End_Certificate_PP_01_07_crt }; /* * test41 * */ public static final String Intermediate_Certificate_1_PP_01_08_crt = "MIICojCCAgugAwIBAgIBWDANBgkqhkiG9w0BAQUFADBeMQswCQYDVQQGEwJVUzEYMBYGA1" + "UEChMPVS5TLiBHb3Zlcm5tZW50MQwwCgYDVQQLEwNEb0QxEDAOBgNVBAsTB1Rlc3Rpbmcx" + "FTATBgNVBAMTDFRydXN0IEFuY2hvcjAeFw05ODAxMDExMjAxMDBaFw00ODAxMDExMjAxMD" + "BaMF4xCzAJBgNVBAYTAlVTMRgwFgYDVQQKEw9VLlMuIEdvdmVybm1lbnQxDDAKBgNVBAsT" + "A0RvZDEQMA4GA1UECxMHVGVzdGluZzEVMBMGA1UEAxMMQ0ExLVBQLjAxLjA4MIGfMA0GCS" + "qGSIb3DQEBAQUAA4GNADCBiQKBgQDDe20HLq7R8b0fWTsEiNV3Z5IbQseZ8QCW+1cb6yM+" + "ArKLJDnXx8zmTHSHQCpw3G7xhGsxA1btm0cSC5P/1bw/kFWsSLRe2NFF6oKU+7c+cgIUMB" + "kzyXk+kpWAQRb7hcb50iKdKFtO8gMNGMAxlHRI05/1tThyAs9suI4TrxTS9QIDAQABo3Aw" + "bjAPBgNVHRMBAf8EBTADAQH/MA4GA1UdDwEB/wQEAwIBBjAjBgNVHSAEHDAaMAsGCWCGSA" + "FlAwEwATALBglghkgBZQMBMAIwEQYDVR0OBAoECFxr9vgF31fKMBMGA1UdIwQMMAqACKua" + "6/nC51SPMA0GCSqGSIb3DQEBBQUAA4GBABaX7TYfmSyVmzGCVbTFweUuPilo4wzy7z/w0x" + "y4uSaM/YMtixUdDPpTHOJNYDdeV85v+w9oezdL2ZYAaGn7tldC6k8ouq/6hOGGST+ziHJS" + "gTOD8UVBQPRPvWEwgmDIprnzrVRz8rG6uqslXNiBDnO9BMGpRo4dy8YpOmV6BPCD"; public static final String Intermediate_Certificate_2_PP_01_08_crt = "MIIClTCCAf6gAwIBAgIBWTANBgkqhkiG9w0BAQUFADBeMQswCQYDVQQGEwJVUzEYMBYGA1" + "UEChMPVS5TLiBHb3Zlcm5tZW50MQwwCgYDVQQLEwNEb2QxEDAOBgNVBAsTB1Rlc3Rpbmcx" + "FTATBgNVBAMTDENBMS1QUC4wMS4wODAeFw05ODAxMDExMjAxMDBaFw00ODAxMDExMjAxMD" + "BaMF4xCzAJBgNVBAYTAlVTMRgwFgYDVQQKEw9VLlMuIEdvdmVybm1lbnQxDDAKBgNVBAsT" + "A0RvZDEQMA4GA1UECxMHVGVzdGluZzEVMBMGA1UEAxMMQ0EyLVBQLjAxLjA4MIGfMA0GCS" + "qGSIb3DQEBAQUAA4GNADCBiQKBgQC8nLZcMLHYKxVqbhwJiqQbAYhf7S6ck2O9AhNor935" + "Bfm7/8qVZbBAotQy1PoCjSW0UYdknDolWvi8aAtO0f9XVrAv6BZVVW9j3osIGN/XUThaN+" + "9dZ83kGpyjeoitpGK4wbFNDteuBFYp+8gFNupnX7JQwUK3aGwBUucbe7puRQIDAQABo2Mw" + "YTAPBgNVHRMBAf8EBTADAQH/MA4GA1UdDwEB/wQEAwIBBjAWBgNVHSAEDzANMAsGCWCGSA" + "FlAwEwATARBgNVHQ4ECgQIL0xyFYBk4OcwEwYDVR0jBAwwCoAIXGv2+AXfV8owDQYJKoZI" + "hvcNAQEFBQADgYEAPk+Lys0Ueoyhp544EH9Hqy9+gY+l/+N99v7KvBlZWKuhkwZDE+qAYT" + "P/SOPsWe8ADZE2iQ4pOlpK8jSqtJSdK69RgGL9omLnR04L9c/zKLArBE+VmoV7mohcQp8x" + "aB4q/g3QnAqwfFYDjIWW3H6gRAeQ5MOtKdz/4042fJxc5L8="; public static final String Intermediate_Certificate_3_PP_01_08_crt = "MIIClTCCAf6gAwIBAgIBWjANBgkqhkiG9w0BAQUFADBeMQswCQYDVQQGEwJVUzEYMBYGA1" + "UEChMPVS5TLiBHb3Zlcm5tZW50MQwwCgYDVQQLEwNEb2QxEDAOBgNVBAsTB1Rlc3Rpbmcx" + "FTATBgNVBAMTDENBMi1QUC4wMS4wODAeFw05ODAxMDExMjAxMDBaFw00ODAxMDExMjAxMD" + "BaMF4xCzAJBgNVBAYTAlVTMRgwFgYDVQQKEw9VLlMuIEdvdmVybm1lbnQxDDAKBgNVBAsT" + "A0RvZDEQMA4GA1UECxMHVGVzdGluZzEVMBMGA1UEAxMMQ0EzLVBQLjAxLjA4MIGfMA0GCS" + "qGSIb3DQEBAQUAA4GNADCBiQKBgQCvy6bNOyVaP8JTwiySFa3Sj+rdSqzkalK5gA7DLk4q" + "AyvnAK64HgbCsb8dpnSi94WBDsocrQ4C1Ltoahc/AZyRVLA/REsAh1r3/0FALZgYiIxvSF" + "m3ihKb3P9URBbotzhl1ahRZPSrcxKwNXEmxB0gjixGW7GZTARq3Il5ressRwIDAQABo2Mw" + "YTAPBgNVHRMBAf8EBTADAQH/MA4GA1UdDwEB/wQEAwIBBjAWBgNVHSAEDzANMAsGCWCGSA" + "FlAwEwAjARBgNVHQ4ECgQIwFtfZBe/KqUwEwYDVR0jBAwwCoAIL0xyFYBk4OcwDQYJKoZI" + "hvcNAQEFBQADgYEAeZhpIDEYyV/LkOtUf1TryemJExQ1jdfirJ3AUtoFIoWz1p9aqnV6Po" + "GAMozjtdyotfSA2O8c065DwD+CvUXPmdD+2vWpX/2hJPj+x++UvvntAokD2UE9HCeEvBHK" + "rr59hvKKd6GChyhAjLris202eTLIiMEoyZy9X/Wt1nXF8/g="; public static final String Intermediate_CRL_1_PP_01_08_crl = "MIIBSzCBtQIBATANBgkqhkiG9w0BAQUFADBeMQswCQYDVQQGEwJVUzEYMBYGA1UEChMPVS" + "5TLiBHb3Zlcm5tZW50MQwwCgYDVQQLEwNEb2QxEDAOBgNVBAsTB1Rlc3RpbmcxFTATBgNV" + "BAMTDENBMS1QUC4wMS4wOBcNOTkwMTAxMTIwMTAwWhcNNDgwMTAxMTIwMTAwWqAjMCEwCg" + "YDVR0UBAMCAQEwEwYDVR0jBAwwCoAIXGv2+AXfV8owDQYJKoZIhvcNAQEFBQADgYEAhkwT" + "E/EGAe32J883qVrh1wG5xQzO/GGfp/zuDYGL2k1zZ2zq7MajKfzBoXXQ3WPh5dTK1sy5o5" + "boPHG0pge0B4/2JvuDVS539+9HAPansUNsrMXzOblg1acjdKtuk4oS8PIYkM/lbA6yJl6F" + "QMbdIthWqa2gjaWKll3R8fVUjxI="; public static final String Intermediate_CRL_2_PP_01_08_crl = "MIIBSzCBtQIBATANBgkqhkiG9w0BAQUFADBeMQswCQYDVQQGEwJVUzEYMBYGA1UEChMPVS" + "5TLiBHb3Zlcm5tZW50MQwwCgYDVQQLEwNEb2QxEDAOBgNVBAsTB1Rlc3RpbmcxFTATBgNV" + "BAMTDENBMi1QUC4wMS4wOBcNOTkwMTAxMTIwMTAwWhcNNDgwMTAxMTIwMTAwWqAjMCEwCg" + "YDVR0UBAMCAQEwEwYDVR0jBAwwCoAIL0xyFYBk4OcwDQYJKoZIhvcNAQEFBQADgYEAN6BQ" + "sEQT5YCvs9vlUSdG4gjTgNkyQTCdmSIcufpK4MG/AoW/Fn5zJXxiMyHmvT/dkk/UOf82/s" + "41YI/Inz4qRmGF4IL7jo+l7V+OI1n+Vf4ClgZU6ocb9d1dFoBkJu3xI9dcWK6ExpzaBUXw" + "rPJilV4M5luGbszdDCs9cLjmiRA="; public static final String Intermediate_CRL_3_PP_01_08_crl = "MIIBSzCBtQIBATANBgkqhkiG9w0BAQUFADBeMQswCQYDVQQGEwJVUzEYMBYGA1UEChMPVS" + "5TLiBHb3Zlcm5tZW50MQwwCgYDVQQLEwNEb2QxEDAOBgNVBAsTB1Rlc3RpbmcxFTATBgNV" + "BAMTDENBMy1QUC4wMS4wOBcNOTkwMTAxMTIwMTAwWhcNNDgwMTAxMTIwMTAwWqAjMCEwCg" + "YDVR0UBAMCAQEwEwYDVR0jBAwwCoAIwFtfZBe/KqUwDQYJKoZIhvcNAQEFBQADgYEAkmDx" + "t+r59llppKmm9mSTof9/BX2rNyG9LfIH7wweoDi9be2vYOLy0NU1kJ8f3/muEw2v7hWDri" + "k9ROLDFnb/S8MYVT0l4rymRhpshPF1uMTOZmfJUCfTX9jIaShztSScqcGSP0a3EUfDD14R" + "1yMu2pdlMM35llE0lV3uf/eUNr0="; public static final String End_Certificate_PP_01_08_crt = "MIIClTCCAf6gAwIBAgIBWzANBgkqhkiG9w0BAQUFADBeMQswCQYDVQQGEwJVUzEYMBYGA1" + "UEChMPVS5TLiBHb3Zlcm5tZW50MQwwCgYDVQQLEwNEb2QxEDAOBgNVBAsTB1Rlc3Rpbmcx" + "FTATBgNVBAMTDENBMy1QUC4wMS4wODAeFw05ODAxMDExMjAxMDBaFw00ODAxMDExMjAxMD" + "BaMF4xCzAJBgNVBAYTAlVTMRgwFgYDVQQKEw9VLlMuIEdvdmVybm1lbnQxDDAKBgNVBAsT" + "A0RvZDEQMA4GA1UECxMHVGVzdGluZzEVMBMGA1UEAxMMQ0E0LVBQLjAxLjA4MIGfMA0GCS" + "qGSIb3DQEBAQUAA4GNADCBiQKBgQDTWNp6Oz39wwU8AFDzYVs3UfVvXg+t6j/qFavnvllI" + "NO6aU1o4Hnk1wfmTPZPErc00/MfizMSumTYYRl21hEZWhjNO5uQIHrF9V/4OToo2iOfsPd" + "gxwpSokwxcl7CJyadwUxhRDYCLhSORXoCK1CPQZjwb+uQz799O5ozb0WVNYQIDAQABo2Mw" + "YTAPBgNVHRMBAf8EBTADAQH/MA4GA1UdDwEB/wQEAwIF4DAWBgNVHSAEDzANMAsGCWCGSA" + "FlAwEwAjARBgNVHQ4ECgQIO1TNJtWwaiIwEwYDVR0jBAwwCoAIwFtfZBe/KqUwDQYJKoZI" + "hvcNAQEFBQADgYEANmP9hyFnYvi8gdtRe8ERoEG90NwoyPTsB8sXd40f+Sm1QxKqMPzKPL" + "7bOtY12JGwZ55a6HFVgpw4PnU+0iOcCMHS5OQQLtyirxX2HfioiXEmcmRJT6FvLHrGIHGv" + "KNcfc3rUiksdOb6+j2k8x4IwQ6pBEHQwY8U4Y4DgqALlqM0="; public static final String[] TEST_41_DATA = new String[] { Intermediate_Certificate_1_PP_01_08_crt, Intermediate_Certificate_2_PP_01_08_crt, Intermediate_Certificate_3_PP_01_08_crt, Intermediate_CRL_1_PP_01_08_crl, Intermediate_CRL_2_PP_01_08_crl, Intermediate_CRL_3_PP_01_08_crl, End_Certificate_PP_01_08_crt }; /* * test42 * */ public static final String Intermediate_Certificate_1_PP_01_09_crt = "MIICrzCCAhigAwIBAgIBXDANBgkqhkiG9w0BAQUFADBeMQswCQYDVQQGEwJVUzEYMBYGA1" + "UEChMPVS5TLiBHb3Zlcm5tZW50MQwwCgYDVQQLEwNEb0QxEDAOBgNVBAsTB1Rlc3Rpbmcx" + "FTATBgNVBAMTDFRydXN0IEFuY2hvcjAeFw05ODAxMDExMjAxMDBaFw00ODAxMDExMjAxMD" + "BaMF4xCzAJBgNVBAYTAlVTMRgwFgYDVQQKEw9VLlMuIEdvdmVybm1lbnQxDDAKBgNVBAsT" + "A0RvZDEQMA4GA1UECxMHVGVzdGluZzEVMBMGA1UEAxMMQ0ExLVBQLjAxLjA5MIGfMA0GCS" + "qGSIb3DQEBAQUAA4GNADCBiQKBgQDJqSSqGjgI3JUJfA/XkloAOg2QtZeAGp2nCq1Oiply" + "MTjJpMpEOSRYrEIgKMGnBPq33seP7X/obCT2jgexmbFT2TmPirM+h1aqbGQ7QAqsx80BdE" + "ofdcfiNosLbbzli9qFrbarO7fJfBhzraBFGDJj3N8nLi2YtP9IieFYJ/MhKwIDAQABo30w" + "ezAPBgNVHRMBAf8EBTADAQH/MA4GA1UdDwEB/wQEAwIBBjAwBgNVHSAEKTAnMAsGCWCGSA" + "FlAwEwATALBglghkgBZQMBMAIwCwYJYIZIAWUDATADMBEGA1UdDgQKBAiVRMrZuHQ7VjAT" + "BgNVHSMEDDAKgAirmuv5wudUjzANBgkqhkiG9w0BAQUFAAOBgQCetZy9JMzUVveSPE2fQY" + "4fRVChyvIc9nCE4wbzhnRl3zduBGmAwTFr7dRWSFTnEq1c2b6B5nJtCzmt4Ovapf69sIlM" + "s3iV16eBB1WTNCY8YlAsnmZ7q/AR0t0vX+hh6QV6zN5xqulOM4Y8csZEx3RWJzV/LjE5w7" + "mKvofBEUoqQA=="; public static final String Intermediate_Certificate_2_PP_01_09_crt = "MIICojCCAgugAwIBAgIBXTANBgkqhkiG9w0BAQUFADBeMQswCQYDVQQGEwJVUzEYMBYGA1" + "UEChMPVS5TLiBHb3Zlcm5tZW50MQwwCgYDVQQLEwNEb2QxEDAOBgNVBAsTB1Rlc3Rpbmcx" + "FTATBgNVBAMTDENBMS1QUC4wMS4wOTAeFw05ODAxMDExMjAxMDBaFw00ODAxMDExMjAxMD" + "BaMF4xCzAJBgNVBAYTAlVTMRgwFgYDVQQKEw9VLlMuIEdvdmVybm1lbnQxDDAKBgNVBAsT" + "A0RvZDEQMA4GA1UECxMHVGVzdGluZzEVMBMGA1UEAxMMQ0EyLVBQLjAxLjA5MIGfMA0GCS" + "qGSIb3DQEBAQUAA4GNADCBiQKBgQDWUTlTieoi7aLGUYOAgqUC2J/6JarOWfv4vobpwjAA" + "DjvQGqg/GCZP7FgD/72Z4YefZKJEFZTDnYfmy2qh6iBYxcvLsJ+PJGzPCObNSmyq8gpeXy" + "KKEeCZtEev1tSywTT6E5Dhee4dX0QHE4ydZEliMMXGRW/8ffT6x54CPwVylQIDAQABo3Aw" + "bjAPBgNVHRMBAf8EBTADAQH/MA4GA1UdDwEB/wQEAwIBBjAjBgNVHSAEHDAaMAsGCWCGSA" + "FlAwEwATALBglghkgBZQMBMAIwEQYDVR0OBAoECAMhmGN8+qXoMBMGA1UdIwQMMAqACJVE" + "ytm4dDtWMA0GCSqGSIb3DQEBBQUAA4GBALNjokGrTnWsPn5KrlO+g3R8tAGM90JQDjfrap" + "xWM+nN+dUVVdGU6w2pAOAq2UhfySiP42qiFChnPK9oOqPF2Or7/kcmXZzBfZkE/FnJGNUA" + "gs9je1nZvTPQYsF094OqE7QdJi2k3seA1tqejA1kihMHpwQNmIp8bFpqn4dPO6ys"; public static final String Intermediate_Certificate_3_PP_01_09_crt = "MIIClTCCAf6gAwIBAgIBXjANBgkqhkiG9w0BAQUFADBeMQswCQYDVQQGEwJVUzEYMBYGA1" + "UEChMPVS5TLiBHb3Zlcm5tZW50MQwwCgYDVQQLEwNEb2QxEDAOBgNVBAsTB1Rlc3Rpbmcx" + "FTATBgNVBAMTDENBMi1QUC4wMS4wOTAeFw05ODAxMDExMjAxMDBaFw00ODAxMDExMjAxMD" + "BaMF4xCzAJBgNVBAYTAlVTMRgwFgYDVQQKEw9VLlMuIEdvdmVybm1lbnQxDDAKBgNVBAsT" + "A0RvZDEQMA4GA1UECxMHVGVzdGluZzEVMBMGA1UEAxMMQ0EzLVBQLjAxLjA5MIGfMA0GCS" + "qGSIb3DQEBAQUAA4GNADCBiQKBgQDHUpHhF4ANNLOywnvpqyDgzLMtatW3ZxgLBBRYk6TE" + "jMgTVKmRasVRTA9uatGG4b2f70YWs9cOd4ylQDqPEDdKNZ47bqZdX6RAU3j1dO9LBwWDbp" + "NvZ3zuDBRDoCZClIcBESDYweaZ9nUgKl/WxTeCnMwqkfSJGYBBcHIonRPnGwIDAQABo2Mw" + "YTAPBgNVHRMBAf8EBTADAQH/MA4GA1UdDwEB/wQEAwIBBjAWBgNVHSAEDzANMAsGCWCGSA" + "FlAwEwAjARBgNVHQ4ECgQIyppef22OmjEwEwYDVR0jBAwwCoAIAyGYY3z6pegwDQYJKoZI" + "hvcNAQEFBQADgYEAOySUCY+PZxomhWgTRSKRodOIe/QSfCMSC+0iw24a2TuJzFLjN9pSm9" + "0C2PqWbfwD1uDjrteO1NK+1yhtIDySiptR9GmR/fhL7NJ+z7M4fEJBjjeeI9/aEIuHuBFT" + "TVHfwsJxnZtjujtOdl56B825LsKW8Otumd2A43N9wIgSyBg="; public static final String Intermediate_Certificate_4_PP_01_09_crt = "MIIClTCCAf6gAwIBAgIBXzANBgkqhkiG9w0BAQUFADBeMQswCQYDVQQGEwJVUzEYMBYGA1" + "UEChMPVS5TLiBHb3Zlcm5tZW50MQwwCgYDVQQLEwNEb2QxEDAOBgNVBAsTB1Rlc3Rpbmcx" + "FTATBgNVBAMTDENBMy1QUC4wMS4wOTAeFw05ODAxMDExMjAxMDBaFw00ODAxMDExMjAxMD" + "BaMF4xCzAJBgNVBAYTAlVTMRgwFgYDVQQKEw9VLlMuIEdvdmVybm1lbnQxDDAKBgNVBAsT" + "A0RvZDEQMA4GA1UECxMHVGVzdGluZzEVMBMGA1UEAxMMQ0E0LVBQLjAxLjA5MIGfMA0GCS" + "qGSIb3DQEBAQUAA4GNADCBiQKBgQDR8/c35YqAswoRMgQswlTbKB9oYEzrFSC0G4dt8ydP" + "O4PyQs+J8wUVrRVMiVDTLO9rUnzR1T3iA0dqM+SvWMIA8pMWKyNV58f73ZPJIejhxMmOZa" + "sSLHceMmmMRy1zyk38i3ZJP3YhvxffTjWyTZ9k2xSDX+6KNnkiKkJSKpl6nwIDAQABo2Mw" + "YTAPBgNVHRMBAf8EBTADAQH/MA4GA1UdDwEB/wQEAwIBBjAWBgNVHSAEDzANMAsGCWCGSA" + "FlAwEwATARBgNVHQ4ECgQIpcWcVIIu63kwEwYDVR0jBAwwCoAIyppef22OmjEwDQYJKoZI" + "hvcNAQEFBQADgYEAckgV11ND/D1vfPEMUbDGUvtmsziHiSuEoDLJqSAhOmcX+evKWOfoVo" + "f7og+0ajuul7yuB+7YX1AakOw+33k++Rsgg4o+ImZq3+VScpgnIQ037OOhgH3umwFRC0r3" + "NpWqhmQuz+mHnKiK3X+IDsQOFkhnpNs06CQSZzmrzbYlQU0="; public static final String Intermediate_CRL_1_PP_01_09_crl = "MIIBSzCBtQIBATANBgkqhkiG9w0BAQUFADBeMQswCQYDVQQGEwJVUzEYMBYGA1UEChMPVS" + "5TLiBHb3Zlcm5tZW50MQwwCgYDVQQLEwNEb2QxEDAOBgNVBAsTB1Rlc3RpbmcxFTATBgNV" + "BAMTDENBMS1QUC4wMS4wORcNOTkwMTAxMTIwMTAwWhcNNDgwMTAxMTIwMTAwWqAjMCEwCg" + "YDVR0UBAMCAQEwEwYDVR0jBAwwCoAIlUTK2bh0O1YwDQYJKoZIhvcNAQEFBQADgYEAkEc6" + "qHGOWZXYTQ5fsWyJgEtuJyl8uJ+gMcikcMut5SIJTTtOz+q3wclYDevT8z1MM25kNdgwyg" + "b1bwHNAG8I72eIDtGfLrChFwU3qpvVMTG9gPYJb05Q8On56nsBu/PnnzJervzxjViaeOuv" + "kjwwfmWqGkyiK433WxzgPqE48eA="; public static final String Intermediate_CRL_2_PP_01_09_crl = "MIIBSzCBtQIBATANBgkqhkiG9w0BAQUFADBeMQswCQYDVQQGEwJVUzEYMBYGA1UEChMPVS" + "5TLiBHb3Zlcm5tZW50MQwwCgYDVQQLEwNEb2QxEDAOBgNVBAsTB1Rlc3RpbmcxFTATBgNV" + "BAMTDENBMi1QUC4wMS4wORcNOTkwMTAxMTIwMTAwWhcNNDgwMTAxMTIwMTAwWqAjMCEwCg" + "YDVR0UBAMCAQEwEwYDVR0jBAwwCoAIAyGYY3z6pegwDQYJKoZIhvcNAQEFBQADgYEAV9Md" + "8PaNoIlT7WIwnelqrbwsR66vAaT8w3gu8XDYXu+MOYThfyERUvtH6AUrHWfiRvWEzKljHH" + "3BQB0Zsa9Zz3U5cLzJcqtqDc1lH53aIA8MflrfMVrYSF684s28FikcukmA5Fw3+7S3TJ18" + "Hq7plHwTCidVD6yG35hsPwcjTrE="; public static final String Intermediate_CRL_3_PP_01_09_crl = "MIIBSzCBtQIBATANBgkqhkiG9w0BAQUFADBeMQswCQYDVQQGEwJVUzEYMBYGA1UEChMPVS" + "5TLiBHb3Zlcm5tZW50MQwwCgYDVQQLEwNEb2QxEDAOBgNVBAsTB1Rlc3RpbmcxFTATBgNV" + "BAMTDENBMy1QUC4wMS4wORcNOTkwMTAxMTIwMTAwWhcNNDgwMTAxMTIwMTAwWqAjMCEwCg" + "YDVR0UBAMCAQEwEwYDVR0jBAwwCoAIyppef22OmjEwDQYJKoZIhvcNAQEFBQADgYEAjBaP" + "V/TFQtDLxQFIBCbfqhlgpOfvJBatjNuvB0TuD2rsGS1eaLNfTfyVKlOLpxoKwKYMu36kIO" + "l/+KEPDq+ofy7uDZ6GLK3KZ/WiJyriqBQjFCvlhNTW1cjA7Ejk2lOM/A46mrUS9xC+aITh" + "d+/UYGt6O/e256cOwQCUaF2z328="; public static final String Intermediate_CRL_4_PP_01_09_crl = "MIIBSzCBtQIBATANBgkqhkiG9w0BAQUFADBeMQswCQYDVQQGEwJVUzEYMBYGA1UEChMPVS" + "5TLiBHb3Zlcm5tZW50MQwwCgYDVQQLEwNEb2QxEDAOBgNVBAsTB1Rlc3RpbmcxFTATBgNV" + "BAMTDENBNC1QUC4wMS4wORcNOTkwMTAxMTIwMTAwWhcNNDgwMTAxMTIwMTAwWqAjMCEwCg" + "YDVR0UBAMCAQEwEwYDVR0jBAwwCoAIpcWcVIIu63kwDQYJKoZIhvcNAQEFBQADgYEApZ1l" + "w5SJoU8zeKwX5jpVWiFFFomDgKsNlkkX5mF88l0B6MiYbGqJIowJRfeIlxvPOf20imN7Z8" + "l38DRXFacDQP4y5kxM420dp+ljQL5q9RsrC1+OS7I7TGgGwPoZTO4mHVk8nx9MyT+kW1OU" + "x9qRYWN0CLmP22kutYBndny222Y="; public static final String End_Certificate_PP_01_09_crt = "MIIChjCCAe+gAwIBAgIBYDANBgkqhkiG9w0BAQUFADBeMQswCQYDVQQGEwJVUzEYMBYGA1" + "UEChMPVS5TLiBHb3Zlcm5tZW50MQwwCgYDVQQLEwNEb2QxEDAOBgNVBAsTB1Rlc3Rpbmcx" + "FTATBgNVBAMTDENBNC1QUC4wMS4wOTAeFw05ODAxMDExMjAxMDBaFw00ODAxMDExMjAxMD" + "BaMGAxCzAJBgNVBAYTAlVTMRgwFgYDVQQKEw9VLlMuIEdvdmVybm1lbnQxDDAKBgNVBAsT" + "A0RvRDEQMA4GA1UECxMHVGVzdGluZzEXMBUGA1UEAxMOVXNlcjEtUFAuMDEuMDkwgZ8wDQ" + "YJKoZIhvcNAQEBBQADgY0AMIGJAoGBALiOjwwwUk1HNwf2rdzPL2okKTgL+lMdzhC7cbq3" + "6A409EY7iipPCcsDsheo9EaTNOHV9xjWDqOhqjA38h4hGNkRUVOlTW2r8SoHISn3gDXfrh" + "aHbU3owscAmt1nuA7rzo7L1eBPsisIIxAY16uAmVN5RdiAAaP8VUdshcNI4/1jAgMBAAGj" + "UjBQMA4GA1UdDwEB/wQEAwIF4DAWBgNVHSAEDzANMAsGCWCGSAFlAwEwATARBgNVHQ4ECg" + "QIGZIY3nffEXowEwYDVR0jBAwwCoAIpcWcVIIu63kwDQYJKoZIhvcNAQEFBQADgYEA0Svm" + "aqjaeQx/lnF223xlCTsU7XzOxbHetRWfeCTw0QrWQaTrKjWTS/TNyzLhGuPBFg+NTTvWML" + "gzteo/WWdF8+d2rOis9FVRCe/Euok6ZCL/xgzaE86ZSQg0jj6458TpuC2cszSaifRSlhL5" + "ogy4ADWgJxdVcBrgADo6QZXkXXw="; public static final String[] TEST_42_DATA = new String[] { Intermediate_Certificate_1_PP_01_09_crt, Intermediate_Certificate_2_PP_01_09_crt, Intermediate_Certificate_3_PP_01_09_crt, Intermediate_Certificate_4_PP_01_09_crt, Intermediate_CRL_1_PP_01_09_crl, Intermediate_CRL_2_PP_01_09_crl, Intermediate_CRL_3_PP_01_09_crl, Intermediate_CRL_4_PP_01_09_crl, End_Certificate_PP_01_09_crt }; /* * test43 * */ public static final String Intermediate_Certificate_1_PP_06_01_crt = "MIICozCCAgygAwIBAgIBYTANBgkqhkiG9w0BAQUFADBeMQswCQYDVQQGEwJVUzEYMBYGA1" + "UEChMPVS5TLiBHb3Zlcm5tZW50MQwwCgYDVQQLEwNEb0QxEDAOBgNVBAsTB1Rlc3Rpbmcx" + "FTATBgNVBAMTDFRydXN0IEFuY2hvcjAeFw05ODAxMDExMjAxMDBaFw00ODAxMDExMjAxMD" + "BaMF4xCzAJBgNVBAYTAlVTMRgwFgYDVQQKEw9VLlMuIEdvdmVybm1lbnQxDDAKBgNVBAsT" + "A0RvZDEQMA4GA1UECxMHVGVzdGluZzEVMBMGA1UEAxMMQ0ExLVBQLjA2LjAxMIGfMA0GCS" + "qGSIb3DQEBAQUAA4GNADCBiQKBgQC4mu1oBHB9BeorCFJIuSw5tszmmYBD4bjTklsAfjrz" + "OknQsYxEoHfifpdgivh1fMUk+mK5YWUz0G8/edquKbJhPBTTWp8opsGzTATsTLSEzkKbVM" + "DQ84ttxrhJWlrVRlouZTnD5HoLUvujY4EdydmKsjj6UBt/tGL5EKodymcEtwIDAQABo3Ew" + "bzAPBgNVHRMBAf8EBTADAQH/MA4GA1UdDwEB/wQEAwIBBjAWBgNVHSAEDzANMAsGCWCGSA" + "FlAwEwATAMBgNVHSQEBTADgAEKMBEGA1UdDgQKBAiGRi8YRte8PzATBgNVHSMEDDAKgAir" + "muv5wudUjzANBgkqhkiG9w0BAQUFAAOBgQDHOaIki9TogVJn54FRPl+7FyzBJ2DnR4RTM/" + "q1K3COWRdtvmGqtBBtAccxWziQJ5TnAQn1XA0cFPoCgymGPRcUz+0+C+3VhJ/m9LggVP3/" + "pjJEG0fsmJtUYPyphUlXeUzf4qSj34SlJws3DIHTR8ozAR75HZmlMRnxyZBLl+jAng=="; public static final String Intermediate_Certificate_2_PP_06_01_crt = "MIIClTCCAf6gAwIBAgIBYjANBgkqhkiG9w0BAQUFADBeMQswCQYDVQQGEwJVUzEYMBYGA1" + "UEChMPVS5TLiBHb3Zlcm5tZW50MQwwCgYDVQQLEwNEb2QxEDAOBgNVBAsTB1Rlc3Rpbmcx" + "FTATBgNVBAMTDENBMS1QUC4wNi4wMTAeFw05ODAxMDExMjAxMDBaFw00ODAxMDExMjAxMD" + "BaMF4xCzAJBgNVBAYTAlVTMRgwFgYDVQQKEw9VLlMuIEdvdmVybm1lbnQxDDAKBgNVBAsT" + "A0RvZDEQMA4GA1UECxMHVGVzdGluZzEVMBMGA1UEAxMMQ0EyLVBQLjA2LjAxMIGfMA0GCS" + "qGSIb3DQEBAQUAA4GNADCBiQKBgQC2rptuREzhGfEJ3U8ILPBq+z0s+aafMvBRHpqkipDq" + "bC7v9zpwg1K18F4MYiATpPAEfdEeprKs0mWfdusF93BoMBVm1y0zRgDRUNdyB5GFO8g8+2" + "yNEO6L37c1PwrMLnvJakaqwbbnwlcMcKtLHoX19fyveQQg5DNj8WcKZj397wIDAQABo2Mw" + "YTAPBgNVHRMBAf8EBTADAQH/MA4GA1UdDwEB/wQEAwIBBjAWBgNVHSAEDzANMAsGCWCGSA" + "FlAwEwATARBgNVHQ4ECgQIJPt6qKdFeYEwEwYDVR0jBAwwCoAIhkYvGEbXvD8wDQYJKoZI" + "hvcNAQEFBQADgYEAkFJGNze9/6YX7Rv8FR9obFGACIJ7Om4YQQRW9WM9pEDgKls7g9b9El" + "dJxLKOlWoRoYZIrbEam19traE2O3dxqRevPoYvfAqkR089BkxH/cFYyfqw64IpjDG84dsY" + "XieajI/Ov/HjgF0VQKF3+Y1ZiDjb2OHNgMkqs9VmUHaE+94="; public static final String Intermediate_Certificate_3_PP_06_01_crt = "MIIClTCCAf6gAwIBAgIBYzANBgkqhkiG9w0BAQUFADBeMQswCQYDVQQGEwJVUzEYMBYGA1" + "UEChMPVS5TLiBHb3Zlcm5tZW50MQwwCgYDVQQLEwNEb2QxEDAOBgNVBAsTB1Rlc3Rpbmcx" + "FTATBgNVBAMTDENBMi1QUC4wNi4wMTAeFw05ODAxMDExMjAxMDBaFw00ODAxMDExMjAxMD" + "BaMF4xCzAJBgNVBAYTAlVTMRgwFgYDVQQKEw9VLlMuIEdvdmVybm1lbnQxDDAKBgNVBAsT" + "A0RvZDEQMA4GA1UECxMHVGVzdGluZzEVMBMGA1UEAxMMQ0EzLVBQLjA2LjAxMIGfMA0GCS" + "qGSIb3DQEBAQUAA4GNADCBiQKBgQCzxfyi52gw/5tt6/9aNAXdY3wZYH1GifzGoN4cg8Mt" + "++5xmTdrc2A9/5biaTUVC0x/Ml6mm940NA9mM/EoEu4SdnP2crNCIFHWNlYz3cJtYJ68rE" + "rEU+S0gnYaYRiwNGhVpAjV+FPDr0Ghgp5rYQ61evAhmRuNAFwYocUw80G6JQIDAQABo2Mw" + "YTAPBgNVHRMBAf8EBTADAQH/MA4GA1UdDwEB/wQEAwIBBjAWBgNVHSAEDzANMAsGCWCGSA" + "FlAwEwATARBgNVHQ4ECgQIZ9yMlboxCIEwEwYDVR0jBAwwCoAIJPt6qKdFeYEwDQYJKoZI" + "hvcNAQEFBQADgYEATNnRMQmvTxRcSMUL4pa5bejuX2Ixy/OfZIAlJWt9AfLW2tHmdAaGpD" + "GhTHKfyQQ+HrIMQ+lXau8Yu6nzWXAY8pKpKD1Hbd355VE4dYZ7aPvcAulZHeV0F2EFn09x" + "qQ1frHDRoCOc11B5qV5hnwgDE/ByZh1+OWUcR4tBQKyEF4g="; public static final String Intermediate_Certificate_4_PP_06_01_crt = "MIIClTCCAf6gAwIBAgIBZDANBgkqhkiG9w0BAQUFADBeMQswCQYDVQQGEwJVUzEYMBYGA1" + "UEChMPVS5TLiBHb3Zlcm5tZW50MQwwCgYDVQQLEwNEb2QxEDAOBgNVBAsTB1Rlc3Rpbmcx" + "FTATBgNVBAMTDENBMy1QUC4wNi4wMTAeFw05ODAxMDExMjAxMDBaFw00ODAxMDExMjAxMD" + "BaMF4xCzAJBgNVBAYTAlVTMRgwFgYDVQQKEw9VLlMuIEdvdmVybm1lbnQxDDAKBgNVBAsT" + "A0RvZDEQMA4GA1UECxMHVGVzdGluZzEVMBMGA1UEAxMMQ0E0LVBQLjA2LjAxMIGfMA0GCS" + "qGSIb3DQEBAQUAA4GNADCBiQKBgQDB66hLZx1WGcCqmOxHK/rotXOpccJQOB2L3kpWP1M2" + "ZiWufUguLw45XShdqu31OgmGw0/w9ugwy96aRL+Tiluj4xjIAxJCav5cXF8Dt2Ex7hjIHm" + "XV0rHbJUiduHEh3fQphgtzlR4QxG6i/i4SbcsoJzsws8x3qOqRPaWDtyWs0QIDAQABo2Mw" + "YTAPBgNVHRMBAf8EBTADAQH/MA4GA1UdDwEB/wQEAwIBBjAWBgNVHSAEDzANMAsGCWCGSA" + "FlAwEwATARBgNVHQ4ECgQIyZsLNvyyIZEwEwYDVR0jBAwwCoAIZ9yMlboxCIEwDQYJKoZI" + "hvcNAQEFBQADgYEAc7G4BAUsQeqNp/Kv8TKJckfxWygz54PrkBICNw/eGuGamVJMRkYCP3" + "yJ8NW4jY/rfxzKKyjVB09XuNBLDwYdR5Z5UHSg6Ijes3j8tehZ+9DwEQrR+WQf/adHIsxn" + "/347MHrSQF7CJzE9tAu6AOu53lKxLeH6C/5YI611or2Ql1I="; public static final String Intermediate_CRL_1_PP_06_01_crl = "MIIBSzCBtQIBATANBgkqhkiG9w0BAQUFADBeMQswCQYDVQQGEwJVUzEYMBYGA1UEChMPVS" + "5TLiBHb3Zlcm5tZW50MQwwCgYDVQQLEwNEb2QxEDAOBgNVBAsTB1Rlc3RpbmcxFTATBgNV" + "BAMTDENBMS1QUC4wNi4wMRcNOTkwMTAxMTIwMTAwWhcNNDgwMTAxMTIwMTAwWqAjMCEwCg" + "YDVR0UBAMCAQEwEwYDVR0jBAwwCoAIhkYvGEbXvD8wDQYJKoZIhvcNAQEFBQADgYEAC7ev" + "Pqe0veUX+zF51d/NiG6VwgEwOP1HlzD/saDn/FYXStTQDwoIyFjmZ9z0yLGIaVI1O9BWVD" + "CTU3bCU1dBg61Blo3rI3TlNqmGrYRUSJ857QM9c/G+/+V0XJ/HgId39Pufd9Tob150XNMs" + "9h0PvqjhYjG1bARMRa8JB4KTBU4="; public static final String Intermediate_CRL_2_PP_06_01_crl = "MIIBSzCBtQIBATANBgkqhkiG9w0BAQUFADBeMQswCQYDVQQGEwJVUzEYMBYGA1UEChMPVS" + "5TLiBHb3Zlcm5tZW50MQwwCgYDVQQLEwNEb2QxEDAOBgNVBAsTB1Rlc3RpbmcxFTATBgNV" + "BAMTDENBMi1QUC4wNi4wMRcNOTkwMTAxMTIwMTAwWhcNNDgwMTAxMTIwMTAwWqAjMCEwCg" + "YDVR0UBAMCAQEwEwYDVR0jBAwwCoAIJPt6qKdFeYEwDQYJKoZIhvcNAQEFBQADgYEAiUbi" + "qQ3X/hTgjhpQGDZi/7EnZcqSgiAFMreV30/mav2NtXDITE9DqZzCS9x1vHBp4BBsQwYVvp" + "XvLVSgns4pFwR+0Whc+tPo2j9ScePq3sICsqleWTN1DvuoP9rBe8w7pDN4guA59Kbeku75" + "5CMA5YjiTUomK4UaqI3htwkBlWo="; public static final String Intermediate_CRL_3_PP_06_01_crl = "MIIBSzCBtQIBATANBgkqhkiG9w0BAQUFADBeMQswCQYDVQQGEwJVUzEYMBYGA1UEChMPVS" + "5TLiBHb3Zlcm5tZW50MQwwCgYDVQQLEwNEb2QxEDAOBgNVBAsTB1Rlc3RpbmcxFTATBgNV" + "BAMTDENBMy1QUC4wNi4wMRcNOTkwMTAxMTIwMTAwWhcNNDgwMTAxMTIwMTAwWqAjMCEwCg" + "YDVR0UBAMCAQEwEwYDVR0jBAwwCoAIZ9yMlboxCIEwDQYJKoZIhvcNAQEFBQADgYEANowv" + "f/scWT6FFT393XEpWcTnA18hBT5Nkddw6mHjKBq7ndtBQkydMO8Wym1IeQ2qYbAqu3ifNZ" + "SKF3PfgJjYPBKImzJdHTKfcclMC5H8Y9JDN0voeyONr9NiXcoj+p24YNYjb+PFI6avRYo7" + "Xyrqvwnvng/IY9zLtc7SYYUIODk="; public static final String Intermediate_CRL_4_PP_06_01_crl = "MIIBSzCBtQIBATANBgkqhkiG9w0BAQUFADBeMQswCQYDVQQGEwJVUzEYMBYGA1UEChMPVS" + "5TLiBHb3Zlcm5tZW50MQwwCgYDVQQLEwNEb2QxEDAOBgNVBAsTB1Rlc3RpbmcxFTATBgNV" + "BAMTDENBNC1QUC4wNi4wMRcNOTkwMTAxMTIwMTAwWhcNNDgwMTAxMTIwMTAwWqAjMCEwCg" + "YDVR0UBAMCAQEwEwYDVR0jBAwwCoAIyZsLNvyyIZEwDQYJKoZIhvcNAQEFBQADgYEAsnA9" + "ERwsi2mK540oPL45mLdOjGnet7+HhNk14q0hvALTYGB1vEjijc+Yvf6mHJGRbiG207BpJ1" + "DWeWBY8TLe4YJXlSrWwx1jD46rCt7gdqXAdLpMo+i35yfQ19ZqeWcRLkspmczoUJLJaJza" + "eLRrnjv62GLJ09KVKpZBGhV3SUM="; public static final String End_Certificate_PP_06_01_crt = "MIICbjCCAdegAwIBAgIBZTANBgkqhkiG9w0BAQUFADBeMQswCQYDVQQGEwJVUzEYMBYGA1" + "UEChMPVS5TLiBHb3Zlcm5tZW50MQwwCgYDVQQLEwNEb2QxEDAOBgNVBAsTB1Rlc3Rpbmcx" + "FTATBgNVBAMTDENBNC1QUC4wNi4wMTAeFw05ODAxMDExMjAxMDBaFw00ODAxMDExMjAxMD" + "BaMGAxCzAJBgNVBAYTAlVTMRgwFgYDVQQKEw9VLlMuIEdvdmVybm1lbnQxDDAKBgNVBAsT" + "A0RvRDEQMA4GA1UECxMHVGVzdGluZzEXMBUGA1UEAxMOVXNlcjEtUFAuMDYuMDEwgZ8wDQ" + "YJKoZIhvcNAQEBBQADgY0AMIGJAoGBAKrLB7XA0PKY0qtSC5lMBvvIvbyjBM8XmANrN9Wx" + "66QxEuloRAz0D5uAu7TnJBv6qNuIPGFl74yusKCSkjEkBMdVpBCfDvpG1/Tz3sALSlxmnz" + "xbK2ytOncbYuYrzvXttx6wkhLrBLlnfuwpZwGZOr/Pt6WwQJWjXxgTNJ6dcgXbAgMBAAGj" + "OjA4MA4GA1UdDwEB/wQEAwIF4DARBgNVHQ4ECgQIv0gg7LxDM+swEwYDVR0jBAwwCoAIyZ" + "sLNvyyIZEwDQYJKoZIhvcNAQEFBQADgYEAgzlxBGGOBvHw20eOzSswMqrHopNMcvwuEO+Z" + "Mr0h8U2/HIiRqKWQaxMyM8A0oULGJny3B/0WtkfVQ2EIibZGiKIjC1RPAB3QmL0vgSyUmF" + "s/LZbzugpJW6jvfov7N4O+u0J5rYniRxa4bgrXa89TY9kwDMbr6/z4oiI8bq3gEsw="; public static final String[] TEST_43_DATA = new String[] { Intermediate_Certificate_1_PP_06_01_crt, Intermediate_Certificate_2_PP_06_01_crt, Intermediate_Certificate_3_PP_06_01_crt, Intermediate_Certificate_4_PP_06_01_crt, Intermediate_CRL_1_PP_06_01_crl, Intermediate_CRL_2_PP_06_01_crl, Intermediate_CRL_3_PP_06_01_crl, Intermediate_CRL_4_PP_06_01_crl, End_Certificate_PP_06_01_crt }; /* * test44 * */ public static final String Intermediate_Certificate_1_PP_06_02_crt = "MIICozCCAgygAwIBAgIBZjANBgkqhkiG9w0BAQUFADBeMQswCQYDVQQGEwJVUzEYMBYGA1" + "UEChMPVS5TLiBHb3Zlcm5tZW50MQwwCgYDVQQLEwNEb0QxEDAOBgNVBAsTB1Rlc3Rpbmcx" + "FTATBgNVBAMTDFRydXN0IEFuY2hvcjAeFw05ODAxMDExMjAxMDBaFw00ODAxMDExMjAxMD" + "BaMF4xCzAJBgNVBAYTAlVTMRgwFgYDVQQKEw9VLlMuIEdvdmVybm1lbnQxDDAKBgNVBAsT" + "A0RvZDEQMA4GA1UECxMHVGVzdGluZzEVMBMGA1UEAxMMQ0ExLVBQLjA2LjAyMIGfMA0GCS" + "qGSIb3DQEBAQUAA4GNADCBiQKBgQDjg5+XWZwW1gLAOldsRshbCXmUCmt1Vs+oZsvyH+6d" + "2PwKs8ydrz+oD0/D8V7cRXucj7q7cJSLhEY1wJoTTgrWeRg1hQioAXzPW3ZkaZuzhpi+cC" + "qeZzN5nPvqK18GWvpffNbUUVfOuaHzzHmhmhgQyZaNG7JHwpWM10UMzMawOwIDAQABo3Ew" + "bzAPBgNVHRMBAf8EBTADAQH/MA4GA1UdDwEB/wQEAwIBBjAWBgNVHSAEDzANMAsGCWCGSA" + "FlAwEwATAMBgNVHSQEBTADgAEFMBEGA1UdDgQKBAh5am+tkndt5zATBgNVHSMEDDAKgAir" + "muv5wudUjzANBgkqhkiG9w0BAQUFAAOBgQAF0h1iaxxZUp43AjP5gSvbW6JfFRW/ugH9SU" + "n3e1B29LMH3F/ML0joVhPx5CIVpX4nfaYzdeje9+E2/bHMBGSCFeHz9S/KoBLLiI0GNhzh" + "I6MytvPMPRx7hkuROouQ69TnslJiGCcoo+MD0fA2YwO1bCtyLdeVHYhJZWQ2Sg8PHQ=="; public static final String Intermediate_Certificate_2_PP_06_02_crt = "MIIClTCCAf6gAwIBAgIBZzANBgkqhkiG9w0BAQUFADBeMQswCQYDVQQGEwJVUzEYMBYGA1" + "UEChMPVS5TLiBHb3Zlcm5tZW50MQwwCgYDVQQLEwNEb2QxEDAOBgNVBAsTB1Rlc3Rpbmcx" + "FTATBgNVBAMTDENBMS1QUC4wNi4wMjAeFw05ODAxMDExMjAxMDBaFw00ODAxMDExMjAxMD" + "BaMF4xCzAJBgNVBAYTAlVTMRgwFgYDVQQKEw9VLlMuIEdvdmVybm1lbnQxDDAKBgNVBAsT" + "A0RvZDEQMA4GA1UECxMHVGVzdGluZzEVMBMGA1UEAxMMQ0EyLVBQLjA2LjAyMIGfMA0GCS" + "qGSIb3DQEBAQUAA4GNADCBiQKBgQDF4KSKxo8HvQ59E77LcuLpZ7ujNDjb30KB+EbIuRmy" + "khXAkhq2Rp2Iqd3OhC0AXmhSF+enJq3h0dqyxNWP08SIuK5ia3OIeatl1UgEyukuAnrLuI" + "A7PFUQAGZmDG4OuHv28zza4n/SwfCaKfi8qatIwpwF/29ycB8wYBrHThQD0wIDAQABo2Mw" + "YTAPBgNVHRMBAf8EBTADAQH/MA4GA1UdDwEB/wQEAwIBBjAWBgNVHSAEDzANMAsGCWCGSA" + "FlAwEwATARBgNVHQ4ECgQIKFZV4vjfOOQwEwYDVR0jBAwwCoAIeWpvrZJ3becwDQYJKoZI" + "hvcNAQEFBQADgYEAuj8P5ga8Xv9eFjk4AdRMx/Fj/doRAOLZfs+OnrduRXPLe7CFKDxhFx" + "xYOma8In08cgXVVnRR+2nZ54h5qjCYpskGNx+yZRY8+HW3XXE3KpS7QgTnc/1XshUy9VGm" + "2qX0k661f2d3KnSKiKVKtM/y/j/nNyxPugDz1Yy50NtzQOE="; public static final String Intermediate_Certificate_3_PP_06_02_crt = "MIIClTCCAf6gAwIBAgIBaDANBgkqhkiG9w0BAQUFADBeMQswCQYDVQQGEwJVUzEYMBYGA1" + "UEChMPVS5TLiBHb3Zlcm5tZW50MQwwCgYDVQQLEwNEb2QxEDAOBgNVBAsTB1Rlc3Rpbmcx" + "FTATBgNVBAMTDENBMi1QUC4wNi4wMjAeFw05ODAxMDExMjAxMDBaFw00ODAxMDExMjAxMD" + "BaMF4xCzAJBgNVBAYTAlVTMRgwFgYDVQQKEw9VLlMuIEdvdmVybm1lbnQxDDAKBgNVBAsT" + "A0RvZDEQMA4GA1UECxMHVGVzdGluZzEVMBMGA1UEAxMMQ0EzLVBQLjA2LjAyMIGfMA0GCS" + "qGSIb3DQEBAQUAA4GNADCBiQKBgQCitrzXkbO4hAQpBRQE880MFBPq84umX9pyKbV3iMqK" + "Z7HBYwZOvEwGQxG+TX1PIj0Jz27oyvoqpLeMkbn9L3K0BuS0AZKlWIOGPPHWpYTDoQCCs9" + "Mba1evVT/1CMxESsv2kgf49YHMs/6TtxQX0qj5TQzXrkM6CMBc5zyPBDWORQIDAQABo2Mw" + "YTAPBgNVHRMBAf8EBTADAQH/MA4GA1UdDwEB/wQEAwIBBjAWBgNVHSAEDzANMAsGCWCGSA" + "FlAwEwATARBgNVHQ4ECgQIxLES0WIVZQYwEwYDVR0jBAwwCoAIKFZV4vjfOOQwDQYJKoZI" + "hvcNAQEFBQADgYEAdQeDAOFys//2xUFwBilhqr32/jh4gT/ijxRjG0msKTYXmWcCQv9Tms" + "smtIMtiwwnByhjTdQAtOmEyDm/CFW0/NBnxlRvqZKt+PRtscpExVy7xnnm2MBITTa+9xkC" + "A361jSDPnRPEOZoKdMRRzNnW4f59m0huibeFNRYJ7y8BnHs="; public static final String Intermediate_Certificate_4_PP_06_02_crt = "MIIClTCCAf6gAwIBAgIBaTANBgkqhkiG9w0BAQUFADBeMQswCQYDVQQGEwJVUzEYMBYGA1" + "UEChMPVS5TLiBHb3Zlcm5tZW50MQwwCgYDVQQLEwNEb2QxEDAOBgNVBAsTB1Rlc3Rpbmcx" + "FTATBgNVBAMTDENBMy1QUC4wNi4wMjAeFw05ODAxMDExMjAxMDBaFw00ODAxMDExMjAxMD" + "BaMF4xCzAJBgNVBAYTAlVTMRgwFgYDVQQKEw9VLlMuIEdvdmVybm1lbnQxDDAKBgNVBAsT" + "A0RvZDEQMA4GA1UECxMHVGVzdGluZzEVMBMGA1UEAxMMQ0E0LVBQLjA2LjAyMIGfMA0GCS" + "qGSIb3DQEBAQUAA4GNADCBiQKBgQCg0yQG7oewLD2eFfPuj2DPBgT47iEri2IVeS/r5hUD" + "nZhxzT2/+UsQfiS+ufdC2Xq+QAcXFcAifPbvRs9xo2q0uLz26mwSq1TH8ilHLKatKwJ/Yf" + "hcRAfEWDwhLJGRhZ7YrKu8xczZgyxwaeu5m38lEaLIRyaVfVSrw8WhN4z4ewIDAQABo2Mw" + "YTAPBgNVHRMBAf8EBTADAQH/MA4GA1UdDwEB/wQEAwIBBjAWBgNVHSAEDzANMAsGCWCGSA" + "FlAwEwATARBgNVHQ4ECgQI/dKmuI1u6I0wEwYDVR0jBAwwCoAIxLES0WIVZQYwDQYJKoZI" + "hvcNAQEFBQADgYEAOEcMpdSAVKUzQ1A7LJnWOh5Tul6yXw6qMsdZNGOZ3vYBXH3vHnSHvp" + "MqJQ1JIX/4XSiKF8En5dVI/ooNabgyORpPnLGDvrshvO/09iaDlQXxWRsoGAFhcIe7Ibp+" + "3g6hnBO5U+0pbInioKVYf/1VyZSUK1QQMutshMIye/8gyZw="; public static final String Intermediate_CRL_1_PP_06_02_crl = "MIIBSzCBtQIBATANBgkqhkiG9w0BAQUFADBeMQswCQYDVQQGEwJVUzEYMBYGA1UEChMPVS" + "5TLiBHb3Zlcm5tZW50MQwwCgYDVQQLEwNEb2QxEDAOBgNVBAsTB1Rlc3RpbmcxFTATBgNV" + "BAMTDENBMS1QUC4wNi4wMhcNOTkwMTAxMTIwMTAwWhcNNDgwMTAxMTIwMTAwWqAjMCEwCg" + "YDVR0UBAMCAQEwEwYDVR0jBAwwCoAIeWpvrZJ3becwDQYJKoZIhvcNAQEFBQADgYEAEJ28" + "g5iyw3ZOqs5ly7O2X0YWtgKK3BnPztxygCUWO1xVy/QbMM5ybAU/UPbJC2pUnkOZMX+h30" + "RYp/kV9w2o15V1hxj2M0tR8fQ0WXudwi20pZO56uHb+WSaETOmPVoNH5efeXsTvtbHQR5w" + "95L2vNeEzJEy1l7S/sasUUoQvqY="; public static final String Intermediate_CRL_2_PP_06_02_crl = "MIIBSzCBtQIBATANBgkqhkiG9w0BAQUFADBeMQswCQYDVQQGEwJVUzEYMBYGA1UEChMPVS" + "5TLiBHb3Zlcm5tZW50MQwwCgYDVQQLEwNEb2QxEDAOBgNVBAsTB1Rlc3RpbmcxFTATBgNV" + "BAMTDENBMi1QUC4wNi4wMhcNOTkwMTAxMTIwMTAwWhcNNDgwMTAxMTIwMTAwWqAjMCEwCg" + "YDVR0UBAMCAQEwEwYDVR0jBAwwCoAIKFZV4vjfOOQwDQYJKoZIhvcNAQEFBQADgYEApLIK" + "X/YJYhSfn7yLTAlKjnhpH1QDlFeaE6/+uj6j7ZgpK6HBjHOvfwbrjurl+L3ZTLrY1FCL4/" + "SUgXrJxbAyMANlg4Z8u6o73F9cur2gi3sgv5d6FjJ8VwuKYWY2dwZNeXwlWE/W0h01Vd9H" + "QVuctFxzQaJQdQBadw/XqzvLlyw="; public static final String Intermediate_CRL_3_PP_06_02_crl = "MIIBSzCBtQIBATANBgkqhkiG9w0BAQUFADBeMQswCQYDVQQGEwJVUzEYMBYGA1UEChMPVS" + "5TLiBHb3Zlcm5tZW50MQwwCgYDVQQLEwNEb2QxEDAOBgNVBAsTB1Rlc3RpbmcxFTATBgNV" + "BAMTDENBMy1QUC4wNi4wMhcNOTkwMTAxMTIwMTAwWhcNNDgwMTAxMTIwMTAwWqAjMCEwCg" + "YDVR0UBAMCAQEwEwYDVR0jBAwwCoAIxLES0WIVZQYwDQYJKoZIhvcNAQEFBQADgYEAE5J9" + "wJKAb3veF4GhHeoIgy6JvMsrjv7d7dhT+ZIKq+wPNk1909X/Zo1GXxJSjMaMgkLlXa0QN6" + "LtSJxbyMRCKSJfqTKOezFXirZ7MEQ04FT0z6Hp0m+E2Q7dGs52ZOV3YZBhQUlH+aQ8WNu2" + "6clf4VqBiUYgGhkE95PhN5AAnOU="; public static final String Intermediate_CRL_4_PP_06_02_crl = "MIIBSzCBtQIBATANBgkqhkiG9w0BAQUFADBeMQswCQYDVQQGEwJVUzEYMBYGA1UEChMPVS" + "5TLiBHb3Zlcm5tZW50MQwwCgYDVQQLEwNEb2QxEDAOBgNVBAsTB1Rlc3RpbmcxFTATBgNV" + "BAMTDENBNC1QUC4wNi4wMhcNOTkwMTAxMTIwMTAwWhcNNDgwMTAxMTIwMTAwWqAjMCEwCg" + "YDVR0UBAMCAQEwEwYDVR0jBAwwCoAI/dKmuI1u6I0wDQYJKoZIhvcNAQEFBQADgYEAKgk1" + "HJ7OW203z9H7jNGxoLCN9bGDKOFcWlWuruzXWOAn+AomjSZpqZkZU1qyKrFaKM320sfn8C" + "ZJPnVWaVMLBLNddDRWUjJrUHtNdnnZEuYPYlRVb0MmwaxHHR0ZBUIaniqoLuvtQIB9N++T" + "bu4cjx33mN6MX0oWr4Bbq7ovPnE="; public static final String End_Certificate_PP_06_02_crt = "MIICbjCCAdegAwIBAgIBajANBgkqhkiG9w0BAQUFADBeMQswCQYDVQQGEwJVUzEYMBYGA1" + "UEChMPVS5TLiBHb3Zlcm5tZW50MQwwCgYDVQQLEwNEb2QxEDAOBgNVBAsTB1Rlc3Rpbmcx" + "FTATBgNVBAMTDENBNC1QUC4wNi4wMjAeFw05ODAxMDExMjAxMDBaFw00ODAxMDExMjAxMD" + "BaMGAxCzAJBgNVBAYTAlVTMRgwFgYDVQQKEw9VLlMuIEdvdmVybm1lbnQxDDAKBgNVBAsT" + "A0RvRDEQMA4GA1UECxMHVGVzdGluZzEXMBUGA1UEAxMOVXNlcjEtUFAuMDYuMDIwgZ8wDQ" + "YJKoZIhvcNAQEBBQADgY0AMIGJAoGBANAr4hFku3Y6jI+vD6JTRFc7ZLL9tIxT7Mq+QcDd" + "rRHgSEXhPL3MM//3ZFXca3w4rXOUVQyANQncywNM3uwl7T9jC0MD2kJ9PsNGQL2bQcSajX" + "jrxT403PVFsa6ZrLMU0hwomSO4nJBLCJj3i1rlX9esYbRNCqzep2OMWgAWRUsrAgMBAAGj" + "OjA4MA4GA1UdDwEB/wQEAwIF4DARBgNVHQ4ECgQIMBvQP4Q8w2UwEwYDVR0jBAwwCoAI/d" + "KmuI1u6I0wDQYJKoZIhvcNAQEFBQADgYEAnmNf+3jJp4mo4YDznASTMnrBBdXuskhnRXSQ" + "Gj5dNq6PxEXM+CmBhaNlnFYcr7UCtcD8XwampfyO52tvAZW5kWQKsxyowVtsxtwkAtj6/f" + "trIeulIM0B1xjyXJshmVST5u6gZ3OegsAyuqyAbo9B1IvkNFOldt624aEG43jq7ho="; public static final String[] TEST_44_DATA = new String[] { Intermediate_Certificate_1_PP_06_02_crt, Intermediate_Certificate_2_PP_06_02_crt, Intermediate_Certificate_3_PP_06_02_crt, Intermediate_Certificate_4_PP_06_02_crt, Intermediate_CRL_1_PP_06_02_crl, Intermediate_CRL_2_PP_06_02_crl, Intermediate_CRL_3_PP_06_02_crl, Intermediate_CRL_4_PP_06_02_crl, End_Certificate_PP_06_02_crt }; /* * test45 * */ public static final String Intermediate_Certificate_1_PP_06_03_crt = "MIICozCCAgygAwIBAgIBazANBgkqhkiG9w0BAQUFADBeMQswCQYDVQQGEwJVUzEYMBYGA1" + "UEChMPVS5TLiBHb3Zlcm5tZW50MQwwCgYDVQQLEwNEb0QxEDAOBgNVBAsTB1Rlc3Rpbmcx" + "FTATBgNVBAMTDFRydXN0IEFuY2hvcjAeFw05ODAxMDExMjAxMDBaFw00ODAxMDExMjAxMD" + "BaMF4xCzAJBgNVBAYTAlVTMRgwFgYDVQQKEw9VLlMuIEdvdmVybm1lbnQxDDAKBgNVBAsT" + "A0RvZDEQMA4GA1UECxMHVGVzdGluZzEVMBMGA1UEAxMMQ0ExLVBQLjA2LjAzMIGfMA0GCS" + "qGSIb3DQEBAQUAA4GNADCBiQKBgQCrUMqMxZ4sSrH6sKv2y6nYKagLvUHaforCnf4z/5O1" + "PeldaW4ANtNPA8SkVBES/zoKgvrLJUmqRi4b+BGhCVqLU77PvWyiPOS40tpJfw7m9pPK53" + "aeaLC9M6rarjdOvF8MkdtytCMU/Ef1NsuJULwEP+XB90k4lHr9EzbgKhXvoQIDAQABo3Ew" + "bzAPBgNVHRMBAf8EBTADAQH/MA4GA1UdDwEB/wQEAwIBBjAWBgNVHSAEDzANMAsGCWCGSA" + "FlAwEwATAMBgNVHSQEBTADgAEEMBEGA1UdDgQKBAhF0iXZmlIKsTATBgNVHSMEDDAKgAir" + "muv5wudUjzANBgkqhkiG9w0BAQUFAAOBgQCmab7noekyx5TzxAqWoQiC9S/aZJtvLkuH1p" + "KiZnclMpRvIL1CVOukkzLTZXY0EcCHnXuVGjw+9vmiQWGGw8t6TGCXo/CtCo934HGBxOfQ" + "MVysEjst7L7TDQsqxk4j9O8cU/TFWsghW9Ihu7SVIn8RJmknKMB2xkIhcDe8S8dmxw=="; public static final String Intermediate_Certificate_2_PP_06_03_crt = "MIIClTCCAf6gAwIBAgIBbDANBgkqhkiG9w0BAQUFADBeMQswCQYDVQQGEwJVUzEYMBYGA1" + "UEChMPVS5TLiBHb3Zlcm5tZW50MQwwCgYDVQQLEwNEb2QxEDAOBgNVBAsTB1Rlc3Rpbmcx" + "FTATBgNVBAMTDENBMS1QUC4wNi4wMzAeFw05ODAxMDExMjAxMDBaFw00ODAxMDExMjAxMD" + "BaMF4xCzAJBgNVBAYTAlVTMRgwFgYDVQQKEw9VLlMuIEdvdmVybm1lbnQxDDAKBgNVBAsT" + "A0RvZDEQMA4GA1UECxMHVGVzdGluZzEVMBMGA1UEAxMMQ0EyLVBQLjA2LjAzMIGfMA0GCS" + "qGSIb3DQEBAQUAA4GNADCBiQKBgQCmT7wL9WwWBr1oY9bHIq4IrJOkbOARK3zOeyZSbBBB" + "zxcky5kjC9pamMpyZjga+q0CGd2rq9eUjQ2FXZsBSgf/X9B0/g9trNMebYgGnYmHHX2JK+" + "doyAX+h3afDbZzZ696S0Hw7yRx00+teQe/Gx4h4qKPwbJIW5Bep9SBysikJQIDAQABo2Mw" + "YTAPBgNVHRMBAf8EBTADAQH/MA4GA1UdDwEB/wQEAwIBBjAWBgNVHSAEDzANMAsGCWCGSA" + "FlAwEwATARBgNVHQ4ECgQInXHgY/+onu4wEwYDVR0jBAwwCoAIRdIl2ZpSCrEwDQYJKoZI" + "hvcNAQEFBQADgYEAhlboR5gzYWluWIaFM5R1Ko0/rprrv5BHONRiXjLfAPkzZmd7FLDE2j" + "BlU7s7IenICeST4c7HG5zqBigK1814GG75nq5htCGUnM6pn8/gvc58+ckKeWgbJxC5I/0u" + "olCCs8ORbWIEGWmghGg1USxeI1RQwXGgE8XwtabVibJOVBk="; public static final String Intermediate_Certificate_3_PP_06_03_crt = "MIIClTCCAf6gAwIBAgIBbTANBgkqhkiG9w0BAQUFADBeMQswCQYDVQQGEwJVUzEYMBYGA1" + "UEChMPVS5TLiBHb3Zlcm5tZW50MQwwCgYDVQQLEwNEb2QxEDAOBgNVBAsTB1Rlc3Rpbmcx" + "FTATBgNVBAMTDENBMi1QUC4wNi4wMzAeFw05ODAxMDExMjAxMDBaFw00ODAxMDExMjAxMD" + "BaMF4xCzAJBgNVBAYTAlVTMRgwFgYDVQQKEw9VLlMuIEdvdmVybm1lbnQxDDAKBgNVBAsT" + "A0RvZDEQMA4GA1UECxMHVGVzdGluZzEVMBMGA1UEAxMMQ0EzLVBQLjA2LjAzMIGfMA0GCS" + "qGSIb3DQEBAQUAA4GNADCBiQKBgQDEouRlqTFQiJQSwc+yhjpvA0dUIbRrNwLF+EPfUWq0" + "FV1UV0a5lb5BGPW4RGUEbFwsgGCHsfLiY7WmUpC1e6332PZPnrnoJbf28paeiZ8KqcAKZE" + "pGPWKCmFBwBW23q1w/v/CxcXJoBx5OC1yxG3fGH7CZSzc+4Z/+PxLk9yoASwIDAQABo2Mw" + "YTAPBgNVHRMBAf8EBTADAQH/MA4GA1UdDwEB/wQEAwIBBjAWBgNVHSAEDzANMAsGCWCGSA" + "FlAwEwATARBgNVHQ4ECgQIc24GzUM6/LswEwYDVR0jBAwwCoAInXHgY/+onu4wDQYJKoZI" + "hvcNAQEFBQADgYEANLxcLvJqjyu94HN+X6tTxGcN1s43kQh8yRGotW2ptuA2jmGlAhI8QQ" + "sXHO0o0bFLBC/Uv0L0YlEJhK1w0ct7Awwn4UYgqupxug2f84yamcvFa1es3osIMJoi0GPz" + "1WDBM711efRtbzvK6t/4fJ01nG2BlMeEbctVqrehuAip4p4="; public static final String Intermediate_Certificate_4_PP_06_03_crt = "MIIClTCCAf6gAwIBAgIBbjANBgkqhkiG9w0BAQUFADBeMQswCQYDVQQGEwJVUzEYMBYGA1" + "UEChMPVS5TLiBHb3Zlcm5tZW50MQwwCgYDVQQLEwNEb2QxEDAOBgNVBAsTB1Rlc3Rpbmcx" + "FTATBgNVBAMTDENBMy1QUC4wNi4wMzAeFw05ODAxMDExMjAxMDBaFw00ODAxMDExMjAxMD" + "BaMF4xCzAJBgNVBAYTAlVTMRgwFgYDVQQKEw9VLlMuIEdvdmVybm1lbnQxDDAKBgNVBAsT" + "A0RvZDEQMA4GA1UECxMHVGVzdGluZzEVMBMGA1UEAxMMQ0E0LVBQLjA2LjAzMIGfMA0GCS" + "qGSIb3DQEBAQUAA4GNADCBiQKBgQDNuzSN3BiT84M3Dy6KeTQkMqWNuYGTENWPP8WvQ0Ot" + "ggue/lemC+IqYBtIEYtk3A30eKKnF28WIbPlB3oSykrPVV5dMhYGF9ysOtp4wyETHtzdv0" + "7HyqlMHOCPiFplbwjUSo0uEIRVgS3luBJi9onTpcn97/i0S7VsM2nooooaowIDAQABo2Mw" + "YTAPBgNVHRMBAf8EBTADAQH/MA4GA1UdDwEB/wQEAwIBBjAWBgNVHSAEDzANMAsGCWCGSA" + "FlAwEwATARBgNVHQ4ECgQIDjpr8w0dRq0wEwYDVR0jBAwwCoAIc24GzUM6/LswDQYJKoZI" + "hvcNAQEFBQADgYEArE6qUMnjXiB5eKiAFc9Elw1dYsQArtnDQAfFGtShDulxYKq9+pxory" + "4kTMUZZCJc7awEC11tdJp7xJGcpjCJl4I2wBcHiCcVcnwQijqM719PqoQKydXB9MSrXqmU" + "2CyakSzBpb82VooVNx0IZ3h0nXQSE3V0qSXXCaImJcOIGMo="; public static final String Intermediate_CRL_1_PP_06_03_crl = "MIIBSzCBtQIBATANBgkqhkiG9w0BAQUFADBeMQswCQYDVQQGEwJVUzEYMBYGA1UEChMPVS" + "5TLiBHb3Zlcm5tZW50MQwwCgYDVQQLEwNEb2QxEDAOBgNVBAsTB1Rlc3RpbmcxFTATBgNV" + "BAMTDENBMS1QUC4wNi4wMxcNOTkwMTAxMTIwMTAwWhcNNDgwMTAxMTIwMTAwWqAjMCEwCg" + "YDVR0UBAMCAQEwEwYDVR0jBAwwCoAIRdIl2ZpSCrEwDQYJKoZIhvcNAQEFBQADgYEAQrHK" + "VV2MJPJLNdPoEuqFXRTEclSmYhUWC5lthK0JnKUbCUj2cMAku2UdN5sRgVG0475dXV2nvn" + "huxy+IQVt5OJ+PNZ9MYZlC2CfYsBiW9DEYMA603XhVvX/bxx80MwxNby18oyo/V9ycSyJw" + "XzUmzYRUtohHk39r3eUSAt5H7zM="; public static final String Intermediate_CRL_2_PP_06_03_crl = "MIIBSzCBtQIBATANBgkqhkiG9w0BAQUFADBeMQswCQYDVQQGEwJVUzEYMBYGA1UEChMPVS" + "5TLiBHb3Zlcm5tZW50MQwwCgYDVQQLEwNEb2QxEDAOBgNVBAsTB1Rlc3RpbmcxFTATBgNV" + "BAMTDENBMi1QUC4wNi4wMxcNOTkwMTAxMTIwMTAwWhcNNDgwMTAxMTIwMTAwWqAjMCEwCg" + "YDVR0UBAMCAQEwEwYDVR0jBAwwCoAInXHgY/+onu4wDQYJKoZIhvcNAQEFBQADgYEADOEh" + "jV8V8y17mFstkVwigOAKURbi7sD24RkLd1QG0Bn21JiwpkGY8Z4vetQps+VX586xKzz6v6" + "Sj+TJk3jfHCiEAk6a7PLxRcVCCi6y70mzEBCwn6fS5NDfxzxYYLgq+dlUiVwqXsHksEvUz" + "2Z5dpuLhbUGxHiqazNE9iq9pEEE="; public static final String Intermediate_CRL_3_PP_06_03_crl = "MIIBSzCBtQIBATANBgkqhkiG9w0BAQUFADBeMQswCQYDVQQGEwJVUzEYMBYGA1UEChMPVS" + "5TLiBHb3Zlcm5tZW50MQwwCgYDVQQLEwNEb2QxEDAOBgNVBAsTB1Rlc3RpbmcxFTATBgNV" + "BAMTDENBMy1QUC4wNi4wMxcNOTkwMTAxMTIwMTAwWhcNNDgwMTAxMTIwMTAwWqAjMCEwCg" + "YDVR0UBAMCAQEwEwYDVR0jBAwwCoAIc24GzUM6/LswDQYJKoZIhvcNAQEFBQADgYEAK/zi" + "r7ASgtWA0xGQVrqhHsXH9bdaj+FceW6ivoXo3z6xCFLvzu2uenEu5g849+YI0KMomHsDAY" + "tX8qO3XEaLGchbhIfywgRVDlSF8ytMKhJTS05R/vZSZAl+eoT3mC92Grihsd3wublyNZ7a" + "d925Py/oFp3J+geUkKJQK+RVu4M="; public static final String Intermediate_CRL_4_PP_06_03_crl = "MIIBSzCBtQIBATANBgkqhkiG9w0BAQUFADBeMQswCQYDVQQGEwJVUzEYMBYGA1UEChMPVS" + "5TLiBHb3Zlcm5tZW50MQwwCgYDVQQLEwNEb2QxEDAOBgNVBAsTB1Rlc3RpbmcxFTATBgNV" + "BAMTDENBNC1QUC4wNi4wMxcNOTkwMTAxMTIwMTAwWhcNNDgwMTAxMTIwMTAwWqAjMCEwCg" + "YDVR0UBAMCAQEwEwYDVR0jBAwwCoAIDjpr8w0dRq0wDQYJKoZIhvcNAQEFBQADgYEAcBag" + "81RFYMBAf8aRP5VXPcfu0OxgJvVE25ZHGLCkLD4TPKAXMjZMHWrf34+5FW7aigDO1YhGA+" + "2zVtVj8k71DichiCCGXQvH50AqFgeNXNQwn9WcpQ8rRkfmyhlccfeM+MzHI1giRw/RjvCN" + "0dfJL9g3c7peW+VCKn85REZ1ne4="; public static final String End_Certificate_PP_06_03_crt = "MIICbjCCAdegAwIBAgIBbzANBgkqhkiG9w0BAQUFADBeMQswCQYDVQQGEwJVUzEYMBYGA1" + "UEChMPVS5TLiBHb3Zlcm5tZW50MQwwCgYDVQQLEwNEb2QxEDAOBgNVBAsTB1Rlc3Rpbmcx" + "FTATBgNVBAMTDENBNC1QUC4wNi4wMzAeFw05ODAxMDExMjAxMDBaFw00ODAxMDExMjAxMD" + "BaMGAxCzAJBgNVBAYTAlVTMRgwFgYDVQQKEw9VLlMuIEdvdmVybm1lbnQxDDAKBgNVBAsT" + "A0RvRDEQMA4GA1UECxMHVGVzdGluZzEXMBUGA1UEAxMOVXNlcjEtUFAuMDYuMDMwgZ8wDQ" + "YJKoZIhvcNAQEBBQADgY0AMIGJAoGBAKBSOacrUg5H5yuISkqmJuQcK2ao+Ib0FmIKCuek" + "8mm2HEiux+K5/yIAYsQnz9eDKzKWaS73exPniKOXABHaL6dxsptbdBqWB6II2kIl0BFz9P" + "82qjz6DMwpUhj5Pwfy5q0Bz8grTe31ZYP19y8AHgcWna+eiY4fNVXVkIEJOJ6tAgMBAAGj" + "OjA4MA4GA1UdDwEB/wQEAwIF4DARBgNVHQ4ECgQIaZQ3Q55so58wEwYDVR0jBAwwCoAIDj" + "pr8w0dRq0wDQYJKoZIhvcNAQEFBQADgYEAnNYKc2pSFZ9PtR4gQyVI3j+gQ97tcWu6Alxm" + "4T48fSb2KtFGuozJyCv0aYjtuZ9ava9r4v04lyFPoAjWYbALHC9F+vz7JLNr4VstuMdy5O" + "ax+PvJjKGACSXD7QjXJ48qvm+v8OnMbkzf8+rY3LoTJ2KhXo9Ey4+UmU/YuZ0PXuY="; public static final String[] TEST_45_DATA = new String[] { Intermediate_Certificate_1_PP_06_03_crt, Intermediate_Certificate_2_PP_06_03_crt, Intermediate_Certificate_3_PP_06_03_crt, Intermediate_Certificate_4_PP_06_03_crt, Intermediate_CRL_1_PP_06_03_crl, Intermediate_CRL_2_PP_06_03_crl, Intermediate_CRL_3_PP_06_03_crl, Intermediate_CRL_4_PP_06_03_crl, End_Certificate_PP_06_03_crt }; /* * test46 * */ public static final String Intermediate_Certificate_1_PP_06_04_crt = "MIICozCCAgygAwIBAgIBcDANBgkqhkiG9w0BAQUFADBeMQswCQYDVQQGEwJVUzEYMBYGA1" + "UEChMPVS5TLiBHb3Zlcm5tZW50MQwwCgYDVQQLEwNEb0QxEDAOBgNVBAsTB1Rlc3Rpbmcx" + "FTATBgNVBAMTDFRydXN0IEFuY2hvcjAeFw05ODAxMDExMjAxMDBaFw00ODAxMDExMjAxMD" + "BaMF4xCzAJBgNVBAYTAlVTMRgwFgYDVQQKEw9VLlMuIEdvdmVybm1lbnQxDDAKBgNVBAsT" + "A0RvZDEQMA4GA1UECxMHVGVzdGluZzEVMBMGA1UEAxMMQ0ExLVBQLjA2LjA0MIGfMA0GCS" + "qGSIb3DQEBAQUAA4GNADCBiQKBgQDFoR/YTJlGYenu2IRsTiT6jwIA7yOnFbM9JXcqYIP5" + "jSgtn/wVztPHgVWP+582foXJ+oEcThQVZ+RBXYt6VU5o7eVCsGJjqMd0DbRzTO+poelVoY" + "1UEJMrKG0xSEex0T6XLQ+jPU9o5tlXoLYsXvpvbIrCJ0o8kuk4MWTzenDKJwIDAQABo3Ew" + "bzAPBgNVHRMBAf8EBTADAQH/MA4GA1UdDwEB/wQEAwIBBjAWBgNVHSAEDzANMAsGCWCGSA" + "FlAwEwATAMBgNVHSQEBTADgAEAMBEGA1UdDgQKBAgVwXynYDSYEDATBgNVHSMEDDAKgAir" + "muv5wudUjzANBgkqhkiG9w0BAQUFAAOBgQC6MnYM9cY3CNb7/KKZvoaSwF/Se5iZYnbdPn" + "WCnKydnN1AhlDN3kEw0gjTmZo/MkvPqku2aPzg5EiZ0eyeJaR6a4aiICU9z/Hiet19mBF6" + "BtAUdt0fJ7aL5WPAc4BKXUbONd6vkQNv8uLcBmsqZ4wXDj7ZVBMGKcuDq7uClb0xYw=="; public static final String Intermediate_Certificate_2_PP_06_04_crt = "MIIClTCCAf6gAwIBAgIBcTANBgkqhkiG9w0BAQUFADBeMQswCQYDVQQGEwJVUzEYMBYGA1" + "UEChMPVS5TLiBHb3Zlcm5tZW50MQwwCgYDVQQLEwNEb2QxEDAOBgNVBAsTB1Rlc3Rpbmcx" + "FTATBgNVBAMTDENBMS1QUC4wNi4wNDAeFw05ODAxMDExMjAxMDBaFw00ODAxMDExMjAxMD" + "BaMF4xCzAJBgNVBAYTAlVTMRgwFgYDVQQKEw9VLlMuIEdvdmVybm1lbnQxDDAKBgNVBAsT" + "A0RvZDEQMA4GA1UECxMHVGVzdGluZzEVMBMGA1UEAxMMQ0EyLVBQLjA2LjA0MIGfMA0GCS" + "qGSIb3DQEBAQUAA4GNADCBiQKBgQDHqX/4IZpOCsHWgdJ6mICN94nXz/KqsXPNymadVdZA" + "nVU0fHdMcxehAvsBKju5d791Psly1Xyyda8KQ0BKPgGed6jNKb89JzuEtPBov0VMzskqwR" + "irjaDCwYKtibiDe+T/kEN9Sq5pbexHcaTbAIeQrAIoSUmGdQ/Up6PYplb0jwIDAQABo2Mw" + "YTAPBgNVHRMBAf8EBTADAQH/MA4GA1UdDwEB/wQEAwIBBjAWBgNVHSAEDzANMAsGCWCGSA" + "FlAwEwATARBgNVHQ4ECgQISKcQDqdBecUwEwYDVR0jBAwwCoAIFcF8p2A0mBAwDQYJKoZI" + "hvcNAQEFBQADgYEAkAQaOoZYAZOCk881Ro+SIclAj2lp+arAkWPP/gwN4/0lpH62eWqlmY" + "okWRBjk6+iwCgRxQ56uUjJhE08p5juZ5V32ie3RW+S1ZBPtL/T/+Tqp9HNQQ3GjW1yc/yI" + "sWQxrd7QKzTER37HBiOr5WjEjn+dzuWlJtClcQetqMLtMgM="; public static final String Intermediate_Certificate_3_PP_06_04_crt = "MIIClTCCAf6gAwIBAgIBcjANBgkqhkiG9w0BAQUFADBeMQswCQYDVQQGEwJVUzEYMBYGA1" + "UEChMPVS5TLiBHb3Zlcm5tZW50MQwwCgYDVQQLEwNEb2QxEDAOBgNVBAsTB1Rlc3Rpbmcx" + "FTATBgNVBAMTDENBMi1QUC4wNi4wNDAeFw05ODAxMDExMjAxMDBaFw00ODAxMDExMjAxMD" + "BaMF4xCzAJBgNVBAYTAlVTMRgwFgYDVQQKEw9VLlMuIEdvdmVybm1lbnQxDDAKBgNVBAsT" + "A0RvZDEQMA4GA1UECxMHVGVzdGluZzEVMBMGA1UEAxMMQ0EzLVBQLjA2LjA0MIGfMA0GCS" + "qGSIb3DQEBAQUAA4GNADCBiQKBgQC2tnVj8KHGCm8XBPvDYWZMp3yOKQxuORze6a764qIC" + "hkdO7hQbgJ9YiuAF/y62W17FnbhKPX6ninaZG0N77bznKvivSC3+T1jIVhw+kpxRh9MRya" + "L2p+zHJEyO/9JaKWzJZiVi4kebW+hwNgSZc7FSYsAbW7lr4ujDei/yn/AJEwIDAQABo2Mw" + "YTAPBgNVHRMBAf8EBTADAQH/MA4GA1UdDwEB/wQEAwIBBjAWBgNVHSAEDzANMAsGCWCGSA" + "FlAwEwATARBgNVHQ4ECgQIaAEiWf4JpfQwEwYDVR0jBAwwCoAISKcQDqdBecUwDQYJKoZI" + "hvcNAQEFBQADgYEAHNsZDCWtOqt741IJNA9OwpymTA4ES1BRJquEvGj5+4RH2pxi67bYd1" + "kWTPF1qFC2R1sugSNhbU0wOBMdKUJtKWNacPsK0HbD7CPqt4THOcMXFO36b/2gqHqy9rc/" + "slWuIwbtT/tEC+Mk67GEATWNPifoPT7TjWHM3RhsDnagZXw="; public static final String Intermediate_Certificate_4_PP_06_04_crt = "MIIClTCCAf6gAwIBAgIBczANBgkqhkiG9w0BAQUFADBeMQswCQYDVQQGEwJVUzEYMBYGA1" + "UEChMPVS5TLiBHb3Zlcm5tZW50MQwwCgYDVQQLEwNEb2QxEDAOBgNVBAsTB1Rlc3Rpbmcx" + "FTATBgNVBAMTDENBMy1QUC4wNi4wNDAeFw05ODAxMDExMjAxMDBaFw00ODAxMDExMjAxMD" + "BaMF4xCzAJBgNVBAYTAlVTMRgwFgYDVQQKEw9VLlMuIEdvdmVybm1lbnQxDDAKBgNVBAsT" + "A0RvZDEQMA4GA1UECxMHVGVzdGluZzEVMBMGA1UEAxMMQ0E0LVBQLjA2LjA0MIGfMA0GCS" + "qGSIb3DQEBAQUAA4GNADCBiQKBgQDgdk/smDJ5yZYJDH4SG7pIDCzGNZeLO9RI3ybOx4/B" + "M3YQu3DDFSOv8kq6PgL8ThC8Dk6t1jSbT8QVzaGgx0KMV3p6pIMdaVNkOjVjUb+L0nXVfr" + "XYpFLON6tZLgh8oIbiz4KznKmsxo6VdYwyUeHmkpGcL5y+8qLspCNdRJnDGwIDAQABo2Mw" + "YTAPBgNVHRMBAf8EBTADAQH/MA4GA1UdDwEB/wQEAwIBBjAWBgNVHSAEDzANMAsGCWCGSA" + "FlAwEwATARBgNVHQ4ECgQIgSY376EamQowEwYDVR0jBAwwCoAIaAEiWf4JpfQwDQYJKoZI" + "hvcNAQEFBQADgYEAEztvmGSVnDGGeNlIoR+wfRM8ndJogvUxLBZm4N96mDZ9Y+Nr99Dqvw" + "+mMI3BU0miA5kDO9aFrKIgow3cpruoedhnBUsxTfhrNaFEwp+ORUb3tWn7sSxLfnTim4Vq" + "y6j/EfUK2CS4ZAy7J5BADWSqDezPnrb5UaY1JFKMuLyGRac="; public static final String Intermediate_CRL_1_PP_06_04_crl = "MIIBSzCBtQIBATANBgkqhkiG9w0BAQUFADBeMQswCQYDVQQGEwJVUzEYMBYGA1UEChMPVS" + "5TLiBHb3Zlcm5tZW50MQwwCgYDVQQLEwNEb2QxEDAOBgNVBAsTB1Rlc3RpbmcxFTATBgNV" + "BAMTDENBMS1QUC4wNi4wNBcNOTkwMTAxMTIwMTAwWhcNNDgwMTAxMTIwMTAwWqAjMCEwCg" + "YDVR0UBAMCAQEwEwYDVR0jBAwwCoAIFcF8p2A0mBAwDQYJKoZIhvcNAQEFBQADgYEAPlIW" + "SxwW2LE8qxeD+M+HypNwai7j9XxUA2MhBbGVnsrhH+DKX5VeyP/nyZn2hBoGWhs05IpG2P" + "S0odnyhbgGSXSj+IOfkZkVT0BmuEJmqv75R15LBzeyONks+eSEhoOIGAaIN4WgJ5mzjSrI" + "ddDu3c4s6QO/OFVrNF1F6e4laSU="; public static final String Intermediate_CRL_2_PP_06_04_crl = "MIIBSzCBtQIBATANBgkqhkiG9w0BAQUFADBeMQswCQYDVQQGEwJVUzEYMBYGA1UEChMPVS" + "5TLiBHb3Zlcm5tZW50MQwwCgYDVQQLEwNEb2QxEDAOBgNVBAsTB1Rlc3RpbmcxFTATBgNV" + "BAMTDENBMi1QUC4wNi4wNBcNOTkwMTAxMTIwMTAwWhcNNDgwMTAxMTIwMTAwWqAjMCEwCg" + "YDVR0UBAMCAQEwEwYDVR0jBAwwCoAISKcQDqdBecUwDQYJKoZIhvcNAQEFBQADgYEAE5wt" + "y3+jVnr8de/Yi0LV70v3JDHimwG2pQcuDRhR1NLPr4oC+2uxMqwxVzdHITDb3yI2ZT9pVh" + "PV3UvX85avMdA0/JyaMWSKNpbSah1eNfMwMBY2vzh1Q7f5n+7HYYM+I2kz7HARPvwsLP9d" + "j4mY7Kq7uiOFdnQzJ6LWjm8qEMs="; public static final String Intermediate_CRL_3_PP_06_04_crl = "MIIBSzCBtQIBATANBgkqhkiG9w0BAQUFADBeMQswCQYDVQQGEwJVUzEYMBYGA1UEChMPVS" + "5TLiBHb3Zlcm5tZW50MQwwCgYDVQQLEwNEb2QxEDAOBgNVBAsTB1Rlc3RpbmcxFTATBgNV" + "BAMTDENBMy1QUC4wNi4wNBcNOTkwMTAxMTIwMTAwWhcNNDgwMTAxMTIwMTAwWqAjMCEwCg" + "YDVR0UBAMCAQEwEwYDVR0jBAwwCoAIaAEiWf4JpfQwDQYJKoZIhvcNAQEFBQADgYEAOm2f" + "m3IdcDnIS915tEZzDmIbTFPBkIn0wjUreZKb9uNxE2a8Jixq+UP2uiyYWiWmXnRdVB1Gsb" + "ofc5f8ctNgSPVTSYB0U5apIauXjV0y7WMUrLNrDFa5m9lxLRhF9kvXVL8zPhVfMpujnXre" + "A8WS4UjDMuveyQL6yASGoZvB+Ps="; public static final String Intermediate_CRL_4_PP_06_04_crl = "MIIBSzCBtQIBATANBgkqhkiG9w0BAQUFADBeMQswCQYDVQQGEwJVUzEYMBYGA1UEChMPVS" + "5TLiBHb3Zlcm5tZW50MQwwCgYDVQQLEwNEb2QxEDAOBgNVBAsTB1Rlc3RpbmcxFTATBgNV" + "BAMTDENBNC1QUC4wNi4wNBcNOTkwMTAxMTIwMTAwWhcNNDgwMTAxMTIwMTAwWqAjMCEwCg" + "YDVR0UBAMCAQEwEwYDVR0jBAwwCoAIgSY376EamQowDQYJKoZIhvcNAQEFBQADgYEAznK9" + "ekskl4uWU+2Xqp3Pj14wvXuzfPAqFlHR0jl5By7T82JRiRa6LGX6T953vcwwJBsYG1hMqH" + "pgbnUGB8APQ6YNXN+7ZkudaG6fMVX6bCr8zT+nVSj7PHIK2VFsC1Jpm5SoQMHH6DFit/oH" + "tm4tdV8+nupMBQn1ZtxQHgUUF14="; public static final String End_Certificate_PP_06_04_crt = "MIIChjCCAe+gAwIBAgIBdDANBgkqhkiG9w0BAQUFADBeMQswCQYDVQQGEwJVUzEYMBYGA1" + "UEChMPVS5TLiBHb3Zlcm5tZW50MQwwCgYDVQQLEwNEb2QxEDAOBgNVBAsTB1Rlc3Rpbmcx" + "FTATBgNVBAMTDENBNC1QUC4wNi4wNDAeFw05ODAxMDExMjAxMDBaFw00ODAxMDExMjAxMD" + "BaMGAxCzAJBgNVBAYTAlVTMRgwFgYDVQQKEw9VLlMuIEdvdmVybm1lbnQxDDAKBgNVBAsT" + "A0RvRDEQMA4GA1UECxMHVGVzdGluZzEXMBUGA1UEAxMOVXNlcjEtUFAuMDYuMDQwgZ8wDQ" + "YJKoZIhvcNAQEBBQADgY0AMIGJAoGBAOCVJmtrW8Z2WGGRNjEgyp2NJn1xaIVDwlxL4C0n" + "UAPpo1WM/rarQTYejT2Yo8H39TdRfiAlggF0Qsce0W//atey8WewGsFlUem6a4OFwg1X2h" + "CN/COL0eC4a6lwkdOKmqgxSyWNWeKxXRTM8+EYQIem78uY7A8XuzVUmOpzYWoLAgMBAAGj" + "UjBQMA4GA1UdDwEB/wQEAwIF4DAWBgNVHSAEDzANMAsGCWCGSAFlAwEwATARBgNVHQ4ECg" + "QION6UOZ2Eky4wEwYDVR0jBAwwCoAIgSY376EamQowDQYJKoZIhvcNAQEFBQADgYEAXota" + "1N1UrMxj2a/vdII92Wi8uEetcHo9vmiJVYxwPFkp+qo1q93Ww8Qnfp7xzaZwLgVoUOAF8U" + "TRUVnzqoSwmRrfyEMfrgej3eiBjcU+zS9mNlx9mUUSLmlY+xMeejyVDCntRn6YJWWLesVq" + "eFOjyNux97/XnGT3T1w0J+wShu4="; public static final String[] TEST_46_DATA = new String[] { Intermediate_Certificate_1_PP_06_04_crt, Intermediate_Certificate_2_PP_06_04_crt, Intermediate_Certificate_3_PP_06_04_crt, Intermediate_Certificate_4_PP_06_04_crt, Intermediate_CRL_1_PP_06_04_crl, Intermediate_CRL_2_PP_06_04_crl, Intermediate_CRL_3_PP_06_04_crl, Intermediate_CRL_4_PP_06_04_crl, End_Certificate_PP_06_04_crt }; /* * test47 * */ public static final String Intermediate_Certificate_1_PP_06_05_crt = "MIICozCCAgygAwIBAgIBdTANBgkqhkiG9w0BAQUFADBeMQswCQYDVQQGEwJVUzEYMBYGA1" + "UEChMPVS5TLiBHb3Zlcm5tZW50MQwwCgYDVQQLEwNEb0QxEDAOBgNVBAsTB1Rlc3Rpbmcx" + "FTATBgNVBAMTDFRydXN0IEFuY2hvcjAeFw05ODAxMDExMjAxMDBaFw00ODAxMDExMjAxMD" + "BaMF4xCzAJBgNVBAYTAlVTMRgwFgYDVQQKEw9VLlMuIEdvdmVybm1lbnQxDDAKBgNVBAsT" + "A0RvZDEQMA4GA1UECxMHVGVzdGluZzEVMBMGA1UEAxMMQ0ExLVBQLjA2LjA1MIGfMA0GCS" + "qGSIb3DQEBAQUAA4GNADCBiQKBgQDMIUtQ/CgudxHAwAAn8jUsdAY8u7WDslOC4nNbWn5C" + "tILgZ2hGIZhEnhzP+VCV8ke8zLo1DX0hCRYAgzk5XTGAimExHFv/yDdhpJWEnqMRljkCHx" + "Hg3XE1439qutBdmWvGUlRF0hQrd9Q/Ubr+PjEzP3a0EUmXo7LYuQKMcFsC4wIDAQABo3Ew" + "bzAPBgNVHRMBAf8EBTADAQH/MA4GA1UdDwEB/wQEAwIBBjAWBgNVHSAEDzANMAsGCWCGSA" + "FlAwEwATAMBgNVHSQEBTADgAEHMBEGA1UdDgQKBAgha8GqGbO1nDATBgNVHSMEDDAKgAir" + "muv5wudUjzANBgkqhkiG9w0BAQUFAAOBgQAEG5C3P1A/MYpNJ0qvi26v04GGUWDQWRW1q9" + "1392XpAxDdv7kODf1FUMpfBpcUblagxrX7Npthv6/6W8poBTjvJuq5BfnnOMQrCwnsNfRy" + "Y7b1mAZIvcOBhWe+bFVqRLUqZ+JseWkw0YgZIGtX41Znwl0VcFQKJ4lNkuaBgXXdGw=="; public static final String Intermediate_Certificate_2_PP_06_05_crt = "MIICozCCAgygAwIBAgIBdjANBgkqhkiG9w0BAQUFADBeMQswCQYDVQQGEwJVUzEYMBYGA1" + "UEChMPVS5TLiBHb3Zlcm5tZW50MQwwCgYDVQQLEwNEb2QxEDAOBgNVBAsTB1Rlc3Rpbmcx" + "FTATBgNVBAMTDENBMS1QUC4wNi4wNTAeFw05ODAxMDExMjAxMDBaFw00ODAxMDExMjAxMD" + "BaMF4xCzAJBgNVBAYTAlVTMRgwFgYDVQQKEw9VLlMuIEdvdmVybm1lbnQxDDAKBgNVBAsT" + "A0RvZDEQMA4GA1UECxMHVGVzdGluZzEVMBMGA1UEAxMMQ0EyLVBQLjA2LjA1MIGfMA0GCS" + "qGSIb3DQEBAQUAA4GNADCBiQKBgQC36j0YkXZZSw3qQaxD0g2BfrKYperkGjVAfLwOtOxB" + "0A3Ufx2ECl/MqNOvi/QWlTkKwnrqw0aEnD25iS1DFM4jMZBmdfJg80oa+y6TJoZcIb+3bv" + "SK5o3ArCFWkhTHHggIIY3H9dQOgAeYQF57Vb0iu59GPfnYJO8y8ZpxGIYcjQIDAQABo3Ew" + "bzAPBgNVHRMBAf8EBTADAQH/MA4GA1UdDwEB/wQEAwIBBjAWBgNVHSAEDzANMAsGCWCGSA" + "FlAwEwATAMBgNVHSQEBTADgAECMBEGA1UdDgQKBAhUpoGZzfV7EjATBgNVHSMEDDAKgAgh" + "a8GqGbO1nDANBgkqhkiG9w0BAQUFAAOBgQAjrFHzC1FLvssJTfV5YsGfw7Luj4EqLDQd6b" + "MgtBSwPnXqMTUAZpDETyeYvcgM+L2tasB26MSy6IttSKsaJpHPCP+BIs0jji5xosuCX6Cs" + "wI2gE/LjF85rjZnldrlDShw01DlcmWlWwudit/ieO71Xc8i0F4EhSaTUJX12po5Xkg=="; public static final String Intermediate_Certificate_3_PP_06_05_crt = "MIICozCCAgygAwIBAgIBdzANBgkqhkiG9w0BAQUFADBeMQswCQYDVQQGEwJVUzEYMBYGA1" + "UEChMPVS5TLiBHb3Zlcm5tZW50MQwwCgYDVQQLEwNEb2QxEDAOBgNVBAsTB1Rlc3Rpbmcx" + "FTATBgNVBAMTDENBMi1QUC4wNi4wNTAeFw05ODAxMDExMjAxMDBaFw00ODAxMDExMjAxMD" + "BaMF4xCzAJBgNVBAYTAlVTMRgwFgYDVQQKEw9VLlMuIEdvdmVybm1lbnQxDDAKBgNVBAsT" + "A0RvZDEQMA4GA1UECxMHVGVzdGluZzEVMBMGA1UEAxMMQ0EzLVBQLjA2LjA1MIGfMA0GCS" + "qGSIb3DQEBAQUAA4GNADCBiQKBgQDFWhChPQNFYQpLBmVmXSGF2py1wcfhZgZurv0E5AgE" + "BZwBo2bxSeC36lBQyR3OABGI4nQoEegSQWwuS2Pk3+emG2MZ8R5QINAkMlAKTp5Gj7KTlm" + "3VVJRx7/VduoFx8sZPjkpvF1bSL+KOH4UZny1xqqTj4bJ+oGu58INeSNVa+wIDAQABo3Ew" + "bzAPBgNVHRMBAf8EBTADAQH/MA4GA1UdDwEB/wQEAwIBBjAWBgNVHSAEDzANMAsGCWCGSA" + "FlAwEwATAMBgNVHSQEBTADgAEEMBEGA1UdDgQKBAjN4PvsHY9+YzATBgNVHSMEDDAKgAhU" + "poGZzfV7EjANBgkqhkiG9w0BAQUFAAOBgQA8KmWbAQOnM59zry9TNtLbA2P5y8R/sO771S" + "yQYcu6undt9t7UEiOepDp/z3CGsITm9RdtXAobZ5ZqhW+3Ll+UnML1itiCytOPbfC7iiUO" + "S5jviQnpgJncZD2Lp65yNAB7lMmMleFO15Bsk8VNmzMDMsFtzo508Bs6T33ZW69/vg=="; public static final String Intermediate_Certificate_4_PP_06_05_crt = "MIIClTCCAf6gAwIBAgIBeDANBgkqhkiG9w0BAQUFADBeMQswCQYDVQQGEwJVUzEYMBYGA1" + "UEChMPVS5TLiBHb3Zlcm5tZW50MQwwCgYDVQQLEwNEb2QxEDAOBgNVBAsTB1Rlc3Rpbmcx" + "FTATBgNVBAMTDENBMy1QUC4wNi4wNTAeFw05ODAxMDExMjAxMDBaFw00ODAxMDExMjAxMD" + "BaMF4xCzAJBgNVBAYTAlVTMRgwFgYDVQQKEw9VLlMuIEdvdmVybm1lbnQxDDAKBgNVBAsT" + "A0RvZDEQMA4GA1UECxMHVGVzdGluZzEVMBMGA1UEAxMMQ0E0LVBQLjA2LjA1MIGfMA0GCS" + "qGSIb3DQEBAQUAA4GNADCBiQKBgQDxx57R4j64xdbjpTl7reLby/T2ym4rESC90aBkC2/E" + "/YUSjsuGG9GiHEVgoGzoQGQNQV0v9ZMIvuoI6q7Fd6VZhIVGE0MGzTFNA9QEEDGPc10ZxC" + "Gyh9mZYp77PMuhQ12Iv3aDW9KNTr09+HyhK7d3Se7toXLwjE5pKt+A4ZvBFQIDAQABo2Mw" + "YTAPBgNVHRMBAf8EBTADAQH/MA4GA1UdDwEB/wQEAwIBBjAWBgNVHSAEDzANMAsGCWCGSA" + "FlAwEwATARBgNVHQ4ECgQIwmq0fugIX0kwEwYDVR0jBAwwCoAIzeD77B2PfmMwDQYJKoZI" + "hvcNAQEFBQADgYEAbAbRorTyh6zfAmdg0lfeZyCyW9k4NWfhUs46iSOl6lkZH8c1eoAF5/" + "q0pOF+CtI3F9VMhfUXChEbVj7QENctU7kDiFe8300OWD5h1VUi+WTK4CG7B36/BjkrVOuG" + "Os76P9l1WaC+/WRZdcqgFMfPjpn3R179dImBDwZiCMMbVqc="; public static final String Intermediate_CRL_1_PP_06_05_crl = "MIIBSzCBtQIBATANBgkqhkiG9w0BAQUFADBeMQswCQYDVQQGEwJVUzEYMBYGA1UEChMPVS" + "5TLiBHb3Zlcm5tZW50MQwwCgYDVQQLEwNEb2QxEDAOBgNVBAsTB1Rlc3RpbmcxFTATBgNV" + "BAMTDENBMS1QUC4wNi4wNRcNOTkwMTAxMTIwMTAwWhcNNDgwMTAxMTIwMTAwWqAjMCEwCg" + "YDVR0UBAMCAQEwEwYDVR0jBAwwCoAIIWvBqhmztZwwDQYJKoZIhvcNAQEFBQADgYEADX3u" + "wxpN+p8N2HqmhFw8w9LCeoR3Xa/uaqgqh4i/VkDuAC4Bi7VbIO6rcxDO2uAdZgNhb/hnRq" + "cvKLcy0vrovCa2EPHcFo7dJl7si2q09EeuHT4+lZt/Ek/VOkwHhvh2o6yEvKOGXCnF9hZr" + "8YbOIknboEz+tRfxoJArRBwpJkE="; public static final String Intermediate_CRL_2_PP_06_05_crl = "MIIBSzCBtQIBATANBgkqhkiG9w0BAQUFADBeMQswCQYDVQQGEwJVUzEYMBYGA1UEChMPVS" + "5TLiBHb3Zlcm5tZW50MQwwCgYDVQQLEwNEb2QxEDAOBgNVBAsTB1Rlc3RpbmcxFTATBgNV" + "BAMTDENBMi1QUC4wNi4wNRcNOTkwMTAxMTIwMTAwWhcNNDgwMTAxMTIwMTAwWqAjMCEwCg" + "YDVR0UBAMCAQEwEwYDVR0jBAwwCoAIVKaBmc31exIwDQYJKoZIhvcNAQEFBQADgYEAQz7u" + "dfU4yAHFLH5BgeZkYh0l2lZ95af+E/67MSCjQSF7RWWWTffbDMc4HmiRlZLvQdltyGCKmi" + "kuzcPP8vyYOBQmoIKQ6c2LItBjXVavLdpe91yCOhCWXVVlnMFq5ztrvBEpfO0GVUOnPWfG" + "1Ugit3SEd4DbhYFTBYHbbOKRWsU="; public static final String Intermediate_CRL_3_PP_06_05_crl = "MIIBSzCBtQIBATANBgkqhkiG9w0BAQUFADBeMQswCQYDVQQGEwJVUzEYMBYGA1UEChMPVS" + "5TLiBHb3Zlcm5tZW50MQwwCgYDVQQLEwNEb2QxEDAOBgNVBAsTB1Rlc3RpbmcxFTATBgNV" + "BAMTDENBMy1QUC4wNi4wNRcNOTkwMTAxMTIwMTAwWhcNNDgwMTAxMTIwMTAwWqAjMCEwCg" + "YDVR0UBAMCAQEwEwYDVR0jBAwwCoAIzeD77B2PfmMwDQYJKoZIhvcNAQEFBQADgYEAkiW6" + "h9a8v+IITd+p0jxukj2FYfmED59ZXAlYhQdQAGlPE71rOXn6ZPURYoGf7qlmBwQffpksOb" + "Byb+PX+CBTUNXzhgTzD7ifM9xOhCEKVKai9acQfvokU56OHwfq5AnkRykLZ7IdvdYCP57k" + "ynrNNV35dsMZXg23/PpreumlOkE="; public static final String Intermediate_CRL_4_PP_06_05_crl = "MIIBSzCBtQIBATANBgkqhkiG9w0BAQUFADBeMQswCQYDVQQGEwJVUzEYMBYGA1UEChMPVS" + "5TLiBHb3Zlcm5tZW50MQwwCgYDVQQLEwNEb2QxEDAOBgNVBAsTB1Rlc3RpbmcxFTATBgNV" + "BAMTDENBNC1QUC4wNi4wNRcNOTkwMTAxMTIwMTAwWhcNNDgwMTAxMTIwMTAwWqAjMCEwCg" + "YDVR0UBAMCAQEwEwYDVR0jBAwwCoAIwmq0fugIX0kwDQYJKoZIhvcNAQEFBQADgYEAnTbS" + "MBWyoPaslaLpAMmJ+D6kmmKAdRYurA0okU/QP+0W+YNPV4DducAQUDy8Cg3RkpRK2ze0ad" + "l6TUW8g83hj9TXSBp+XZuVvzerMCjOeBqhskZN4Ly8101ZZmMmdYdSc3PEhqkme6iZzjwB" + "ZooAN2dIYjuBj1c1/t5qH80CMAI="; public static final String End_Certificate_PP_06_05_crt = "MIICbjCCAdegAwIBAgIBeTANBgkqhkiG9w0BAQUFADBeMQswCQYDVQQGEwJVUzEYMBYGA1" + "UEChMPVS5TLiBHb3Zlcm5tZW50MQwwCgYDVQQLEwNEb2QxEDAOBgNVBAsTB1Rlc3Rpbmcx" + "FTATBgNVBAMTDENBNC1QUC4wNi4wNTAeFw05ODAxMDExMjAxMDBaFw00ODAxMDExMjAxMD" + "BaMGAxCzAJBgNVBAYTAlVTMRgwFgYDVQQKEw9VLlMuIEdvdmVybm1lbnQxDDAKBgNVBAsT" + "A0RvRDEQMA4GA1UECxMHVGVzdGluZzEXMBUGA1UEAxMOVXNlcjEtUFAuMDYuMDUwgZ8wDQ" + "YJKoZIhvcNAQEBBQADgY0AMIGJAoGBALyVMklPv3uwTPzLG70sXIwKSEt65yiU71ibHyhH" + "wJ/6dXy3HK2UETkRBK7UVSOYq005EbO9s/3oR3zt7QTFifvRTsIjl1L4TCLC2a8ApBr3BH" + "xmBWcJDf427Pk1fm5qDdEmZnpyIlpKaKIiBcdtwZfjr0lROL8RNcvgtJPdu/ndAgMBAAGj" + "OjA4MA4GA1UdDwEB/wQEAwIF4DARBgNVHQ4ECgQISjAUfyAwSA0wEwYDVR0jBAwwCoAIwm" + "q0fugIX0kwDQYJKoZIhvcNAQEFBQADgYEAC6Af3cJUh/IQgWdbC2Vmk96sYjDlAsbA2keY" + "J0bgBcNaIVoJ/W0B3rSawqSU+Vv64p7kcuAl6cbvIXPB++19V23jj6HUs1JxtPJZ9IWkS/" + "FRakv6lD7+j1OdzJvDR8AMZWmPFHJdQnJwQ+I1YOU/O/ShawOnGCmihpIULUINFhk="; public static final String[] TEST_47_DATA = new String[] { Intermediate_Certificate_1_PP_06_05_crt, Intermediate_Certificate_2_PP_06_05_crt, Intermediate_Certificate_3_PP_06_05_crt, Intermediate_Certificate_4_PP_06_05_crt, Intermediate_CRL_1_PP_06_05_crl, Intermediate_CRL_2_PP_06_05_crl, Intermediate_CRL_3_PP_06_05_crl, Intermediate_CRL_4_PP_06_05_crl, End_Certificate_PP_06_05_crt }; /* * test48 * */ public static final String Intermediate_Certificate_PP_08_01_crt = "MIIClTCCAf6gAwIBAgIBejANBgkqhkiG9w0BAQUFADBeMQswCQYDVQQGEwJVUzEYMBYGA1" + "UEChMPVS5TLiBHb3Zlcm5tZW50MQwwCgYDVQQLEwNEb0QxEDAOBgNVBAsTB1Rlc3Rpbmcx" + "FTATBgNVBAMTDFRydXN0IEFuY2hvcjAeFw05ODAxMDExMjAxMDBaFw00ODAxMDExMjAxMD" + "BaMF4xCzAJBgNVBAYTAlVTMRgwFgYDVQQKEw9VLlMuIEdvdmVybm1lbnQxDDAKBgNVBAsT" + "A0RvZDEQMA4GA1UECxMHVGVzdGluZzEVMBMGA1UEAxMMQ0ExLVBQLjA4LjAxMIGfMA0GCS" + "qGSIb3DQEBAQUAA4GNADCBiQKBgQCp2vHVX08nyKe+S8NPkNJOZ9Xng22TbYXhUHtXw9yv" + "ZmPkRhwDrZfBLXZcdZFixidkky3kCzv8Q3aPyPByM2ozH+AHJzEMbwifhyvUbANcS+Jts3" + "lsZHarN7VyiXO+8J2OtYqX9qzmrAOHGleB2cJopEcmAMdrzgt1JIo98SUs4wIDAQABo2Mw" + "YTAPBgNVHRMBAf8EBTADAQH/MA4GA1UdDwEB/wQEAwIBBjAWBgNVHSAEDzANMAsGCWCGSA" + "FlAwEwATARBgNVHQ4ECgQIoRYqHNcbLacwEwYDVR0jBAwwCoAIq5rr+cLnVI8wDQYJKoZI" + "hvcNAQEFBQADgYEAXchRFC94Pl25d3Kl4wBcueQLyWPRuH9zS0ZPLAqKLcWVdcg3fYMuJ5" + "SypMMpxLaVjN7xq0KjML1gLiPQPk18iA2TOAUMblvjUl1uFzDdD6SqQidEZh2h3wxFtbLP" + "U7qBBki7i1+Xn072Bpn2paw/vlh4K+ut0tFQ2BAhqVnQGJ8="; public static final String Intermediate_CRL_PP_08_01_crl = "MIIBSzCBtQIBATANBgkqhkiG9w0BAQUFADBeMQswCQYDVQQGEwJVUzEYMBYGA1UEChMPVS" + "5TLiBHb3Zlcm5tZW50MQwwCgYDVQQLEwNEb2QxEDAOBgNVBAsTB1Rlc3RpbmcxFTATBgNV" + "BAMTDENBMS1QUC4wOC4wMRcNOTkwMTAxMTIwMTAwWhcNNDgwMTAxMTIwMTAwWqAjMCEwCg" + "YDVR0UBAMCAQEwEwYDVR0jBAwwCoAIoRYqHNcbLacwDQYJKoZIhvcNAQEFBQADgYEARyX9" + "2+LoXD2fIAACBMPDgds6m3Equ+Aawlr0kuppPO4ydCU4kiEgtVGK+kY5GzP6fUpAKjC8mh" + "BrozojhAbkJekDoN0BIJ42Iab70VmdWXRQhPsUDhQwEt+9eSgy+HfiFfpcL1VJx8uY4XMh" + "VB3hmapIe99P/T2QkZ+Pl8j0MgY="; public static final String End_Certificate_PP_08_01_crt = "MIIChjCCAe+gAwIBAgIBezANBgkqhkiG9w0BAQUFADBeMQswCQYDVQQGEwJVUzEYMBYGA1" + "UEChMPVS5TLiBHb3Zlcm5tZW50MQwwCgYDVQQLEwNEb2QxEDAOBgNVBAsTB1Rlc3Rpbmcx" + "FTATBgNVBAMTDENBMS1QUC4wOC4wMTAeFw05ODAxMDExMjAxMDBaFw00ODAxMDExMjAxMD" + "BaMGAxCzAJBgNVBAYTAlVTMRgwFgYDVQQKEw9VLlMuIEdvdmVybm1lbnQxDDAKBgNVBAsT" + "A0RvRDEQMA4GA1UECxMHVGVzdGluZzEXMBUGA1UEAxMOVXNlcjEtUFAuMDguMDEwgZ8wDQ" + "YJKoZIhvcNAQEBBQADgY0AMIGJAoGBANYtrtpgxNl+9jF3TN1B9bSEGQci+cQOKpFsmrtF" + "AyiGBxKONgGSgSFFuFIhyBKZF5ROaKX1P8lsQkrpnuybUi+Z9ADdyoaLUDD/z/kp5sebAZ" + "ujmF8HVlqHYj5Ls2smS9EdSN1zgPTXIOTeZd/lv1iFppRZv6cBqlaoapQJsb1JAgMBAAGj" + "UjBQMA4GA1UdDwEB/wQEAwIF4DAWBgNVHSAEDzANMAsGCWCGSAFlAwEwATARBgNVHQ4ECg" + "QIZjcOdw0ZTCYwEwYDVR0jBAwwCoAIoRYqHNcbLacwDQYJKoZIhvcNAQEFBQADgYEAarsn" + "13/g0vOKxy0okOp2JXEsPdsP7aWnCfR8N4+7gFD6dVnkgCIyc5Kbs7MbhB9gtIxYhHOV9W" + "MaW9QAcBH+eXciFDfQBfaMBkL34ssE/TsZ92r/bhBwKRcH54f96G0QWUnoNMt4U/1j2mKn" + "faFirltqEPUu9mv4FiQ0pNT9yH0="; public static final String[] TEST_48_DATA = new String[] { Intermediate_Certificate_PP_08_01_crt, Intermediate_CRL_PP_08_01_crl, End_Certificate_PP_08_01_crt }; /* * test49 * */ public static final String Intermediate_Certificate_PP_08_02_crt = "MIICojCCAgugAwIBAgIBfDANBgkqhkiG9w0BAQUFADBeMQswCQYDVQQGEwJVUzEYMBYGA1" + "UEChMPVS5TLiBHb3Zlcm5tZW50MQwwCgYDVQQLEwNEb0QxEDAOBgNVBAsTB1Rlc3Rpbmcx" + "FTATBgNVBAMTDFRydXN0IEFuY2hvcjAeFw05ODAxMDExMjAxMDBaFw00ODAxMDExMjAxMD" + "BaMF4xCzAJBgNVBAYTAlVTMRgwFgYDVQQKEw9VLlMuIEdvdmVybm1lbnQxDDAKBgNVBAsT" + "A0RvZDEQMA4GA1UECxMHVGVzdGluZzEVMBMGA1UEAxMMQ0ExLVBQLjA4LjAyMIGfMA0GCS" + "qGSIb3DQEBAQUAA4GNADCBiQKBgQCmAgNA68ABUEppM9Oo3guiGvguvtrWQzsQIJfMBrE4" + "/Scwc4SPK4PiJD+kVwtXinXpVclBMQge10uZ48lSJTihfZscJw3RSHt70H4CpPQm44QS7P" + "7fQqpcZKZvMWmY6A8jju3Phbuq2WgJCIxxVw886GNIAXW8C4ZFmXCjwiGGHwIDAQABo3Aw" + "bjAPBgNVHRMBAf8EBTADAQH/MA4GA1UdDwEB/wQEAwIBBjAjBgNVHSAEHDAaMAsGCWCGSA" + "FlAwEwATALBglghkgBZQMBMAIwEQYDVR0OBAoECOhZ4RAlqGGcMBMGA1UdIwQMMAqACKua" + "6/nC51SPMA0GCSqGSIb3DQEBBQUAA4GBAGEVSOcNaUu50f6AgGBtz1MDdRiHe08W/nzCNn" + "0K1/UqrIXVJ7IYgbOLkL3cdHy4PdngCyEblzl5Cwp9chh2zL0PTUbV1uJIBW32ks1HuAVQ" + "FTZqx0iuopY5AqRCJVDJt4HB5PKObwnmLPNWicI4Juap13j/Tcnw1EP7E7n6OejC"; public static final String Intermediate_CRL_PP_08_02_crl = "MIIBSzCBtQIBATANBgkqhkiG9w0BAQUFADBeMQswCQYDVQQGEwJVUzEYMBYGA1UEChMPVS" + "5TLiBHb3Zlcm5tZW50MQwwCgYDVQQLEwNEb2QxEDAOBgNVBAsTB1Rlc3RpbmcxFTATBgNV" + "BAMTDENBMS1QUC4wOC4wMhcNOTkwMTAxMTIwMTAwWhcNNDgwMTAxMTIwMTAwWqAjMCEwCg" + "YDVR0UBAMCAQEwEwYDVR0jBAwwCoAI6FnhECWoYZwwDQYJKoZIhvcNAQEFBQADgYEACLHw" + "iDARFoF4GauIHnoZlfj6nlOHAFfNSXq06Vvl713bsoAiOSV+2goZjRG62uxhampE+gCdXx" + "1nwhKQ5R5jOGGOxgLtBFNZwKmD0KiDOSvfIVJ0kYCcaB4mSm0a/7pcCPrrE5ofvkmTW6Wx" + "k/YIuBZdDoqZC91v4tnu0fSch9Q="; public static final String End_Certificate_PP_08_02_crt = "MIICkzCCAfygAwIBAgIBfTANBgkqhkiG9w0BAQUFADBeMQswCQYDVQQGEwJVUzEYMBYGA1" + "UEChMPVS5TLiBHb3Zlcm5tZW50MQwwCgYDVQQLEwNEb2QxEDAOBgNVBAsTB1Rlc3Rpbmcx" + "FTATBgNVBAMTDENBMS1QUC4wOC4wMjAeFw05ODAxMDExMjAxMDBaFw00ODAxMDExMjAxMD" + "BaMGAxCzAJBgNVBAYTAlVTMRgwFgYDVQQKEw9VLlMuIEdvdmVybm1lbnQxDDAKBgNVBAsT" + "A0RvRDEQMA4GA1UECxMHVGVzdGluZzEXMBUGA1UEAxMOVXNlcjEtUFAuMDguMDIwgZ8wDQ" + "YJKoZIhvcNAQEBBQADgY0AMIGJAoGBAOJsz8ys71e8UB+VDTBAocVQvADiqh0LjdML3pET" + "B6VvikiHgbB1PJufxDses+v0WD74ChZEa/octNcMFqMgBlhVBEfvbyGTjiN97LzdZ7SPyd" + "DsDulqwBG9sACryUGHqwHYnUbjOqsThOXFB8Sg/CGGawpZAosm2AuH2gqNvNuJAgMBAAGj" + "XzBdMA4GA1UdDwEB/wQEAwIF4DAjBgNVHSAEHDAaMAsGCWCGSAFlAwEwATALBglghkgBZQ" + "MBMAIwEQYDVR0OBAoECOiMLE2l5u16MBMGA1UdIwQMMAqACOhZ4RAlqGGcMA0GCSqGSIb3" + "DQEBBQUAA4GBAFf4BCbNtduwn5InkfdtFbQOqhPLAn/5eIhxhVhUu7TekWT7ktdaVQFzGF" + "G2h1+gXgFP+YKjJy7kGzEVQjlWtuC0l74EwybNHnYAoDg4itKe+0OSNNXdyOmn+i0tE0nx" + "sWN19VvhLGFC8p38gd0oDr1ziYdg0z2Mx4IlMDxl7QhT"; public static final String[] TEST_49_DATA = new String[] { Intermediate_Certificate_PP_08_02_crt, Intermediate_CRL_PP_08_02_crl, End_Certificate_PP_08_02_crt }; /* * test50 * */ public static final String Intermediate_Certificate_PP_08_03_crt = "MIICkDCCAfmgAwIBAgIBfjANBgkqhkiG9w0BAQUFADBeMQswCQYDVQQGEwJVUzEYMBYGA1" + "UEChMPVS5TLiBHb3Zlcm5tZW50MQwwCgYDVQQLEwNEb0QxEDAOBgNVBAsTB1Rlc3Rpbmcx" + "FTATBgNVBAMTDFRydXN0IEFuY2hvcjAeFw05ODAxMDExMjAxMDBaFw00ODAxMDExMjAxMD" + "BaMF4xCzAJBgNVBAYTAlVTMRgwFgYDVQQKEw9VLlMuIEdvdmVybm1lbnQxDDAKBgNVBAsT" + "A0RvZDEQMA4GA1UECxMHVGVzdGluZzEVMBMGA1UEAxMMQ0ExLVBQLjA4LjAzMIGfMA0GCS" + "qGSIb3DQEBAQUAA4GNADCBiQKBgQDKZDgBum5Ud5i8HWlCKInJ1x9goZ7TQJ+LdfA9iGU1" + "47xJL5eFcERWy4dr5wM5GNRW/DHXlnA/qsRVE29EuRh6qAVgcPGAfmJxz7s5yhmErfmiQ3" + "0rh6+pma/EhcjntXqwIqnk1qt6mEk7x9UKO3ksFCVsDEA67/dvownjcZB59wIDAQABo14w" + "XDAPBgNVHRMBAf8EBTADAQH/MA4GA1UdDwEB/wQEAwIBBjARBgNVHSAECjAIMAYGBFUdIA" + "AwEQYDVR0OBAoECGtTrZIwYYHbMBMGA1UdIwQMMAqACKua6/nC51SPMA0GCSqGSIb3DQEB" + "BQUAA4GBAM3t13xJJraRiJDAwZFxhTNR570wMdSRiF3yWSRtOjEv8NTVFj/T1oJJ8h9Gqh" + "hMpTTHU7uGCyVB9S1HCelmS+1zteKr0B+WVzBl9yuhvku3farz6zgIVK3v5hQ6xC4H4Lac" + "NDhTTKBkRfDf9KskFoxJ/AGxPdZtIEC92DFSblQB"; public static final String Intermediate_CRL_PP_08_03_crl = "MIIBSzCBtQIBATANBgkqhkiG9w0BAQUFADBeMQswCQYDVQQGEwJVUzEYMBYGA1UEChMPVS" + "5TLiBHb3Zlcm5tZW50MQwwCgYDVQQLEwNEb2QxEDAOBgNVBAsTB1Rlc3RpbmcxFTATBgNV" + "BAMTDENBMS1QUC4wOC4wMxcNOTkwMTAxMTIwMTAwWhcNNDgwMTAxMTIwMTAwWqAjMCEwCg" + "YDVR0UBAMCAQEwEwYDVR0jBAwwCoAIa1OtkjBhgdswDQYJKoZIhvcNAQEFBQADgYEAcUHo" + "D00X/pd3D5KGa5C6dY18RsnUovkjUkegGTpbhQfmYZIdBatj7Kv75FeUJ9UpqCUjxHgdiE" + "EVy60NLVGP2VRuJ1m8vfDz8hu5PaiVjneQoRw2M9ieBnz3PjSETDdBGJLWHyCBZbp/W2+0" + "iqcZK7Fm9O5EL4PUO6QIwuH76q0="; public static final String End_Certificate_PP_08_03_crt = "MIICgTCCAeqgAwIBAgIBfzANBgkqhkiG9w0BAQUFADBeMQswCQYDVQQGEwJVUzEYMBYGA1" + "UEChMPVS5TLiBHb3Zlcm5tZW50MQwwCgYDVQQLEwNEb2QxEDAOBgNVBAsTB1Rlc3Rpbmcx" + "FTATBgNVBAMTDENBMS1QUC4wOC4wMzAeFw05ODAxMDExMjAxMDBaFw00ODAxMDExMjAxMD" + "BaMGAxCzAJBgNVBAYTAlVTMRgwFgYDVQQKEw9VLlMuIEdvdmVybm1lbnQxDDAKBgNVBAsT" + "A0RvRDEQMA4GA1UECxMHVGVzdGluZzEXMBUGA1UEAxMOVXNlcjEtUFAuMDguMDMwgZ8wDQ" + "YJKoZIhvcNAQEBBQADgY0AMIGJAoGBALsXEPrCg91CObTl5OrHIB5GshIDXgqBmjzxfWPK" + "ih4STWeBe2eIFO9pONXcM5lstEu2XLBPP6QBMUMWOrphJejrJ3eDQHs404bBnt95O/x17i" + "665CZtg1jUqoO1kOBOComx2AJGZ46RdBExbfd0tTtdHWtRhMsnQchI+WtEyotdAgMBAAGj" + "TTBLMA4GA1UdDwEB/wQEAwIF4DARBgNVHSAECjAIMAYGBFUdIAAwEQYDVR0OBAoECEWZkJ" + "TYQ3z5MBMGA1UdIwQMMAqACGtTrZIwYYHbMA0GCSqGSIb3DQEBBQUAA4GBAHki/TrpHiKW" + "gvERhguQ/uOqHHZNXsog+fgGVFFMOWwJ9bq4aHKd1fDZpyZF4vBxW7llbhuSt+ob2TNlkR" + "wkqzfGL+3xOTKNRgzDwJcil8akC1N5uBftrQk+eL7rM1PezWRM7fIbpmv5ZieIVswtTPF5" + "1Rl3G+JXUBy9E95espls"; public static final String[] TEST_50_DATA = new String[] { Intermediate_Certificate_PP_08_03_crt, Intermediate_CRL_PP_08_03_crl, End_Certificate_PP_08_03_crt }; /* * test51 * */ public static final String Intermediate_Certificate_PP_08_04_crt = "MIICljCCAf+gAwIBAgICAIAwDQYJKoZIhvcNAQEFBQAwXjELMAkGA1UEBhMCVVMxGDAWBg" + "NVBAoTD1UuUy4gR292ZXJubWVudDEMMAoGA1UECxMDRG9EMRAwDgYDVQQLEwdUZXN0aW5n" + "MRUwEwYDVQQDEwxUcnVzdCBBbmNob3IwHhcNOTgwMTAxMTIwMTAwWhcNNDgwMTAxMTIwMT" + "AwWjBeMQswCQYDVQQGEwJVUzEYMBYGA1UEChMPVS5TLiBHb3Zlcm5tZW50MQwwCgYDVQQL" + "EwNEb2QxEDAOBgNVBAsTB1Rlc3RpbmcxFTATBgNVBAMTDENBMS1QUC4wOC4wNDCBnzANBg" + "kqhkiG9w0BAQEFAAOBjQAwgYkCgYEAsrM3A06j1zDz6VuZh+O2UrAPcKtwSA6KxTShUpgr" + "t9UB5iIAEvxcDTwDlubEv/cJjDcFj9N57otzW4ppnuT2ztE4ROmkNb0xL6u00deS1yGjXB" + "wy1G9g8bYDdAXOJlv0tjHOBqXlyKoMny82BOBL2vsCstiqxl14Q3/wBD1w29MCAwEAAaNj" + "MGEwDwYDVR0TAQH/BAUwAwEB/zAOBgNVHQ8BAf8EBAMCAQYwFgYDVR0gBA8wDTALBglghk" + "gBZQMBMAMwEQYDVR0OBAoECJiAkexK6/c7MBMGA1UdIwQMMAqACKua6/nC51SPMA0GCSqG" + "SIb3DQEBBQUAA4GBAL4xwcpXZQPTTPYIQ8CMoVla/5P1x6BPmPqSkvh1D/o4ds9Ll9kHBz" + "//X1ZM8SzYcEO+1r75JUzoHsvDw9yYAk2oclLsCORAPqD8Owhv3jv0QQtYSmf0Sxt5FLx0" + "MRP9keY/DURRf9KitO4glOawtRtYMq2BeeJk1xusY0KqEnQr"; public static final String Intermediate_CRL_PP_08_04_crl = "MIIBSzCBtQIBATANBgkqhkiG9w0BAQUFADBeMQswCQYDVQQGEwJVUzEYMBYGA1UEChMPVS" + "5TLiBHb3Zlcm5tZW50MQwwCgYDVQQLEwNEb2QxEDAOBgNVBAsTB1Rlc3RpbmcxFTATBgNV" + "BAMTDENBMS1QUC4wOC4wNBcNOTkwMTAxMTIwMTAwWhcNNDgwMTAxMTIwMTAwWqAjMCEwCg" + "YDVR0UBAMCAQEwEwYDVR0jBAwwCoAImICR7Err9zswDQYJKoZIhvcNAQEFBQADgYEAcN3a" + "jIEcXsQatb0fvVcFnO7d7lzNtgbqL3MtaqJ/PjkRJ/rO7JAXQRwdajUZF4ECHylZKE2HUG" + "Dk+vidV98T8mNmb0TEuuLV+J1G0q8ezMXRJtDt/2m3y1VBireXlEMd1DdgpsDdCQ4va+XJ" + "qv0TvVhfxWry+LrVb6Bf5ItexXg="; public static final String End_Certificate_PP_08_04_crt = "MIIChzCCAfCgAwIBAgICAIEwDQYJKoZIhvcNAQEFBQAwXjELMAkGA1UEBhMCVVMxGDAWBg" + "NVBAoTD1UuUy4gR292ZXJubWVudDEMMAoGA1UECxMDRG9kMRAwDgYDVQQLEwdUZXN0aW5n" + "MRUwEwYDVQQDEwxDQTEtUFAuMDguMDQwHhcNOTgwMTAxMTIwMTAwWhcNNDgwMTAxMTIwMT" + "AwWjBgMQswCQYDVQQGEwJVUzEYMBYGA1UEChMPVS5TLiBHb3Zlcm5tZW50MQwwCgYDVQQL" + "EwNEb0QxEDAOBgNVBAsTB1Rlc3RpbmcxFzAVBgNVBAMTDlVzZXIxLVBQLjA4LjA0MIGfMA" + "0GCSqGSIb3DQEBAQUAA4GNADCBiQKBgQDPJWa/cB7WW7tkGxFhcwxqE+BycXe3Ru2qGbun" + "NPQZ/j44UT2C6rl1wZwugCY0sR6mXR/P/NR7czZvg4Tt6lwcNtc8PeafFMUeu0u0Kg9uWn" + "fzQQKeIgRVcEzGTGMPGWXS0ed6X/1+Dj8A+T/tqXKUtM3Jpe0pCmm9CIrYCXLPRQIDAQAB" + "o1IwUDAOBgNVHQ8BAf8EBAMCBeAwFgYDVR0gBA8wDTALBglghkgBZQMBMAQwEQYDVR0OBA" + "oECKm9IOyOM1h+MBMGA1UdIwQMMAqACJiAkexK6/c7MA0GCSqGSIb3DQEBBQUAA4GBAEXy" + "dlTkkZaYK6sUJCiPeCPxfj5cdo/G4RGBImMJbTeDyVTvXSH9G2yWUMqBGnYLrwdJJeXjF3" + "89miJgnJ+1r/r3r2/NeAUuJDsOHRMFh0KXFmgubyw/kGsZBe3279hDnND8ZjfQBmKQD17f" + "PycWTTAC5p6GM8tGERiDSnMc5rmm"; public static final String[] TEST_51_DATA = new String[] { Intermediate_Certificate_PP_08_04_crt, Intermediate_CRL_PP_08_04_crl, End_Certificate_PP_08_04_crt }; /* * test52 * */ public static final String Intermediate_Certificate_PP_08_05_crt = "MIICljCCAf+gAwIBAgICAIIwDQYJKoZIhvcNAQEFBQAwXjELMAkGA1UEBhMCVVMxGDAWBg" + "NVBAoTD1UuUy4gR292ZXJubWVudDEMMAoGA1UECxMDRG9EMRAwDgYDVQQLEwdUZXN0aW5n" + "MRUwEwYDVQQDEwxUcnVzdCBBbmNob3IwHhcNOTgwMTAxMTIwMTAwWhcNNDgwMTAxMTIwMT" + "AwWjBeMQswCQYDVQQGEwJVUzEYMBYGA1UEChMPVS5TLiBHb3Zlcm5tZW50MQwwCgYDVQQL" + "EwNEb2QxEDAOBgNVBAsTB1Rlc3RpbmcxFTATBgNVBAMTDENBMS1QUC4wOC4wNTCBnzANBg" + "kqhkiG9w0BAQEFAAOBjQAwgYkCgYEAwH2d+D0pH8y4QJAPpE0s2oWucV1jlE4pBMGNNPJ5" + "FIRmyRCt90IpzmK/EuqT6iSZYd9hIB9wa180ByN67PK1z4loLFMUL2RmbWeAFlGy5eEFOy" + "4d479qfy6JCOzt0TKhYzhukLUqGLa4DDTzvnnUx0o86aLvGq0K5s6DRlNyc08CAwEAAaNj" + "MGEwDwYDVR0TAQH/BAUwAwEB/zAOBgNVHQ8BAf8EBAMCAQYwFgYDVR0gBA8wDTALBglghk" + "gBZQMBMAMwEQYDVR0OBAoECDSeuxr4EVgaMBMGA1UdIwQMMAqACKua6/nC51SPMA0GCSqG" + "SIb3DQEBBQUAA4GBAKoGi6qlODB8Lc86PtGXfBhW769jB8xzgmENE59sqNBEvYa/oK9Xxm" + "1JX1OGEQMq/mqwZXg6hSczpexCIO4tUH8QKTU68yvqcZoZCDV8FLM8aEUPtUoPIpluhAtN" + "scGfb3uXoV9fg7q1Pi5YlKMnNrDIq1tH1CAGKMDRrjW63Q8C"; public static final String Intermediate_CRL_PP_08_05_crl = "MIIBSzCBtQIBATANBgkqhkiG9w0BAQUFADBeMQswCQYDVQQGEwJVUzEYMBYGA1UEChMPVS" + "5TLiBHb3Zlcm5tZW50MQwwCgYDVQQLEwNEb2QxEDAOBgNVBAsTB1Rlc3RpbmcxFTATBgNV" + "BAMTDENBMS1QUC4wOC4wNRcNOTkwMTAxMTIwMTAwWhcNNDgwMTAxMTIwMTAwWqAjMCEwCg" + "YDVR0UBAMCAQEwEwYDVR0jBAwwCoAINJ67GvgRWBowDQYJKoZIhvcNAQEFBQADgYEAv5Hs" + "nYPZO1fGC/Z2lIbbUKjIv0+BrR9HbG+b76wXeJTVxfXMlZe0cpOR/KD29DyxI3G4IedHRy" + "zL8iCDWYbA86arJzl5GZJ1MC2A586vNn/6wiiT6nP3iMj2z/nyvan8L30KNBm9IDXQExOu" + "PNE/wOWYBxxCjg551fpXfJKqDIo="; public static final String End_Certificate_PP_08_05_crt = "MIIChzCCAfCgAwIBAgICAIMwDQYJKoZIhvcNAQEFBQAwXjELMAkGA1UEBhMCVVMxGDAWBg" + "NVBAoTD1UuUy4gR292ZXJubWVudDEMMAoGA1UECxMDRG9kMRAwDgYDVQQLEwdUZXN0aW5n" + "MRUwEwYDVQQDEwxDQTEtUFAuMDguMDUwHhcNOTgwMTAxMTIwMTAwWhcNNDgwMTAxMTIwMT" + "AwWjBgMQswCQYDVQQGEwJVUzEYMBYGA1UEChMPVS5TLiBHb3Zlcm5tZW50MQwwCgYDVQQL" + "EwNEb0QxEDAOBgNVBAsTB1Rlc3RpbmcxFzAVBgNVBAMTDlVzZXIxLVBQLjA4LjA1MIGfMA" + "0GCSqGSIb3DQEBAQUAA4GNADCBiQKBgQC4BZFTwOqI+71v8CdiYbe7x0qYveN524h6+iLh" + "oEqvzuVKVqvQgVSaSLPcMhoCGDv3nqyP57Znl/3I09vLU6F4HKLtjO9E0PZu8EXOKLjeWP" + "XmJQkdHfODj/TrrWSsrdorl7s7gdWEUFlbiWvUVUtkqLNbGLJZ5Q1xZvBRLS7loQIDAQAB" + "o1IwUDAOBgNVHQ8BAf8EBAMCBeAwFgYDVR0gBA8wDTALBglghkgBZQMBMAMwEQYDVR0OBA" + "oECBDaTXbN11BBMBMGA1UdIwQMMAqACDSeuxr4EVgaMA0GCSqGSIb3DQEBBQUAA4GBAGVa" + "QNtd4LgoVZQ+Uy1lSr6sog4fsGaoQJCZcvrMJwGpMF0FJsGtOb0R2mfwHi1YXqPF5qZY2I" + "7cVbwVtRQzbXunk1z12k0iIesMtYUncxb/SBstC7VNS8HNZm9ese+YM6Ac8mGT+IUZsPcP" + "gI9fQ1L/2u+/3L4fweca1R45xm5M"; public static final String[] TEST_52_DATA = new String[] { Intermediate_Certificate_PP_08_05_crt, Intermediate_CRL_PP_08_05_crl, End_Certificate_PP_08_05_crt }; /* * test53 * */ public static final String Intermediate_Certificate_PP_08_06_crt = "MIICsDCCAhmgAwIBAgICAIQwDQYJKoZIhvcNAQEFBQAwXjELMAkGA1UEBhMCVVMxGDAWBg" + "NVBAoTD1UuUy4gR292ZXJubWVudDEMMAoGA1UECxMDRG9EMRAwDgYDVQQLEwdUZXN0aW5n" + "MRUwEwYDVQQDEwxUcnVzdCBBbmNob3IwHhcNOTgwMTAxMTIwMTAwWhcNNDgwMTAxMTIwMT" + "AwWjBeMQswCQYDVQQGEwJVUzEYMBYGA1UEChMPVS5TLiBHb3Zlcm5tZW50MQwwCgYDVQQL" + "EwNEb2QxEDAOBgNVBAsTB1Rlc3RpbmcxFTATBgNVBAMTDENBMS1QUC4wOC4wNjCBnzANBg" + "kqhkiG9w0BAQEFAAOBjQAwgYkCgYEAlSIH/+6DEL1P9tkgbsI2PcW0w9dmqMTLP3jKYPsr" + "sSWI5bcv55sk6RItVr3hGgkaskZoHeamUBAiGPksVyrqmRwSCJzQDLnLdMnjjudvPjp1ZZ" + "9UCufTtMPFvnEuVBx5e8A13AQ4OyHqaJgWRVoRJd6vwTa5jzfYCCMJZHHKpcUCAwEAAaN9" + "MHswDwYDVR0TAQH/BAUwAwEB/zAOBgNVHQ8BAf8EBAMCAQYwMAYDVR0gBCkwJzALBglghk" + "gBZQMBMAEwCwYJYIZIAWUDATACMAsGCWCGSAFlAwEwAzARBgNVHQ4ECgQI8837JGF7vMAw" + "EwYDVR0jBAwwCoAIq5rr+cLnVI8wDQYJKoZIhvcNAQEFBQADgYEAKmgbxzWI6V2twYDp65" + "Gu8zn883CnI08s2FEVupvrKduxYmg+ZDkTBE3ZJFxcOuxJf58MRfDWy8C4jJhLnT3JSSSg" + "sY3n93jzc0s2h5y2wd1bUTDLqhqWCshisDG/88rpv938O8luiUEwltolzKTa+ScA6nXSQt" + "LT4I6O3vbTx2g="; public static final String Intermediate_CRL_PP_08_06_crl = "MIIBSzCBtQIBATANBgkqhkiG9w0BAQUFADBeMQswCQYDVQQGEwJVUzEYMBYGA1UEChMPVS" + "5TLiBHb3Zlcm5tZW50MQwwCgYDVQQLEwNEb2QxEDAOBgNVBAsTB1Rlc3RpbmcxFTATBgNV" + "BAMTDENBMS1QUC4wOC4wNhcNOTkwMTAxMTIwMTAwWhcNNDgwMTAxMTIwMTAwWqAjMCEwCg" + "YDVR0UBAMCAQEwEwYDVR0jBAwwCoAI8837JGF7vMAwDQYJKoZIhvcNAQEFBQADgYEAHua+" + "lC3wP4G6796jjr6wuu7xEQqY1azsLVsGtL7YL8fm42rl7hgU40SuFIc7Kc+A7oEEkKgvmu" + "SLMIv7q5O8J26fQOuduGWQAncPYB8w7sNWjCZbdjVbjp1XIApcAL3djCbLZ8/NYsCoOuwx" + "hRQKX1hIn+rNDi1DMD4H99QdDGE="; public static final String End_Certificate_PP_08_06_crt = "MIICoTCCAgqgAwIBAgICAIUwDQYJKoZIhvcNAQEFBQAwXjELMAkGA1UEBhMCVVMxGDAWBg" + "NVBAoTD1UuUy4gR292ZXJubWVudDEMMAoGA1UECxMDRG9kMRAwDgYDVQQLEwdUZXN0aW5n" + "MRUwEwYDVQQDEwxDQTEtUFAuMDguMDYwHhcNOTgwMTAxMTIwMTAwWhcNNDgwMTAxMTIwMT" + "AwWjBgMQswCQYDVQQGEwJVUzEYMBYGA1UEChMPVS5TLiBHb3Zlcm5tZW50MQwwCgYDVQQL" + "EwNEb0QxEDAOBgNVBAsTB1Rlc3RpbmcxFzAVBgNVBAMTDlVzZXIxLVBQLjA4LjA2MIGfMA" + "0GCSqGSIb3DQEBAQUAA4GNADCBiQKBgQDnaYU/lu+u+LmLQwyACSsRyxQEEvgriE7ApmHj" + "sNBcd3lovFQMfw9MyOOMsInOgQZU8p/invnhx11/pwi77ViQQ780unhHt5H/tteaYwcsDR" + "cUxR/8jK0DBnbVWvm8S/NGb8BxfbRmDHBTWGZ70hDSCJypWRfHQj0I/SAqAW/VuwIDAQAB" + "o2wwajAOBgNVHQ8BAf8EBAMCBeAwMAYDVR0gBCkwJzALBglghkgBZQMBMAEwCwYJYIZIAW" + "UDATACMAsGCWCGSAFlAwEwAzARBgNVHQ4ECgQIhh/KikcKA7EwEwYDVR0jBAwwCoAI8837" + "JGF7vMAwDQYJKoZIhvcNAQEFBQADgYEAbHK3lkqbGy61lu9d22uO2H3hzwvjmlccZo8pro" + "ord45d2nRIxw2ag4dS1YRFrefVdxZtKeR9+5o+tQtvmTcDOer4u6NZ/sVVElTb1d6axtL0" + "i4cmqv6bGWYECEwtwmPGqAavp9pPZjNRbkBGy9qhVNTXfDQYpA8yzXWO/xUrwNU="; public static final String[] TEST_53_DATA = new String[] { Intermediate_Certificate_PP_08_06_crt, Intermediate_CRL_PP_08_06_crl, End_Certificate_PP_08_06_crt }; /* * test54 * */ public static final String Intermediate_Certificate_1_PL_01_01_crt = "MIICmTCCAgKgAwIBAgICAIYwDQYJKoZIhvcNAQEFBQAwXjELMAkGA1UEBhMCVVMxGDAWBg" + "NVBAoTD1UuUy4gR292ZXJubWVudDEMMAoGA1UECxMDRG9EMRAwDgYDVQQLEwdUZXN0aW5n" + "MRUwEwYDVQQDEwxUcnVzdCBBbmNob3IwHhcNOTgwMTAxMTIwMTAwWhcNNDgwMTAxMTIwMT" + "AwWjBeMQswCQYDVQQGEwJVUzEYMBYGA1UEChMPVS5TLiBHb3Zlcm5tZW50MQwwCgYDVQQL" + "EwNEb2QxEDAOBgNVBAsTB1Rlc3RpbmcxFTATBgNVBAMTDENBMS1QTC4wMS4wMTCBnzANBg" + "kqhkiG9w0BAQEFAAOBjQAwgYkCgYEAxDV2d7qXbpCvOzBimskBLsgexpEYaHv0s7gOaqhC" + "4A3K8sxdjyW6QdGZhKX8tCMqnlPp9CNbpY4tQQ5oTSk5pj6HwAsTfGcDwXJnjKWx1FJ7rD" + "meZZ8c2K7a8voBl6FoPGn8CMhO0WmM9Eyb/vDUPdCZzScb+z/BxTcV1BPFdq0CAwEAAaNm" + "MGQwEgYDVR0TAQH/BAgwBgEB/wIBADAOBgNVHQ8BAf8EBAMCAQYwFgYDVR0gBA8wDTALBg" + "lghkgBZQMBMAEwEQYDVR0OBAoECBpj0+Gcq32oMBMGA1UdIwQMMAqACKua6/nC51SPMA0G" + "CSqGSIb3DQEBBQUAA4GBAB/9veHrkLeu8jkwXggJtwqPTmkrIBcX+pz85BTSETYeLOzF46" + "onk+qt+IHptlrm3D7ny2Y5M0dQQ6tPzhGZxCEg9RoDibZGtsx+qeAh1ZjeEpEcQyp/idWY" + "asH+EIuEIOZA9c1ySxI/3v3ZfzaSGS8jsgSDkLB4JumrE9ZkLNd1"; public static final String Intermediate_Certificate_2_PL_01_01_crt = "MIICljCCAf+gAwIBAgICAIcwDQYJKoZIhvcNAQEFBQAwXjELMAkGA1UEBhMCVVMxGDAWBg" + "NVBAoTD1UuUy4gR292ZXJubWVudDEMMAoGA1UECxMDRG9kMRAwDgYDVQQLEwdUZXN0aW5n" + "MRUwEwYDVQQDEwxDQTEtUEwuMDEuMDEwHhcNOTgwMTAxMTIwMTAwWhcNNDgwMTAxMTIwMT" + "AwWjBeMQswCQYDVQQGEwJVUzEYMBYGA1UEChMPVS5TLiBHb3Zlcm5tZW50MQwwCgYDVQQL" + "EwNEb2QxEDAOBgNVBAsTB1Rlc3RpbmcxFTATBgNVBAMTDENBMi1QTC4wMS4wMTCBnzANBg" + "kqhkiG9w0BAQEFAAOBjQAwgYkCgYEA3B3UKG3tEL6FQz6dL6iqSvzgGsm1Fg5uzK8npkEq" + "g2caUM7huYFfXeur1mu6iKiROcGX8ZYxrPi9Orh39YVrSu2EUWvqQui4QScf4dIlzAOunv" + "0gAa/lIVTHgZhIomKND6/tZLU251dJiFhoV6bXx2tor83vWFVPx2oVd5LL5S0CAwEAAaNj" + "MGEwDwYDVR0TAQH/BAUwAwEB/zAOBgNVHQ8BAf8EBAMCAQYwFgYDVR0gBA8wDTALBglghk" + "gBZQMBMAEwEQYDVR0OBAoECJmK3jFTIl6lMBMGA1UdIwQMMAqACBpj0+Gcq32oMA0GCSqG" + "SIb3DQEBBQUAA4GBADkYLTg4RncTpAFmpUy7WGOMvoFV15nDoi91OMxhxVkbGSE0DJFxi3" + "hPKcfUNvzy0bEUUTaqOXdbIkoLTG77NTckJxurSRyam0jA0+6SUYZ6F9fVotwMul2EiVl9" + "XP5oCt7LkgqVgMASuwfzMnQozB6Oi/YP2OdSPXLipI6rl2dx"; public static final String Intermediate_CRL_1_PL_01_01_crl = "MIIBSzCBtQIBATANBgkqhkiG9w0BAQUFADBeMQswCQYDVQQGEwJVUzEYMBYGA1UEChMPVS" + "5TLiBHb3Zlcm5tZW50MQwwCgYDVQQLEwNEb2QxEDAOBgNVBAsTB1Rlc3RpbmcxFTATBgNV" + "BAMTDENBMS1QTC4wMS4wMRcNOTkwMTAxMTIwMTAwWhcNNDgwMTAxMTIwMTAwWqAjMCEwCg" + "YDVR0UBAMCAQEwEwYDVR0jBAwwCoAIGmPT4ZyrfagwDQYJKoZIhvcNAQEFBQADgYEAd8YZ" + "8jibr8yjcGYSDicJuyUvHBZntTVQ1sP5XVmtCZcYcQCVjbC0auYTEP5snXbGPW5qeEaaXB" + "MhekMr776hP4Kl3g4AjguFl3XQGcURlgNd8LsTpMMdNWC7XwooOF2FzFjD1ru0BSEWabzW" + "NNaVeuMMbu2N0lc6NDJvRC8LkhA="; public static final String Intermediate_CRL_2_PL_01_01_crl = "MIIBSzCBtQIBATANBgkqhkiG9w0BAQUFADBeMQswCQYDVQQGEwJVUzEYMBYGA1UEChMPVS" + "5TLiBHb3Zlcm5tZW50MQwwCgYDVQQLEwNEb2QxEDAOBgNVBAsTB1Rlc3RpbmcxFTATBgNV" + "BAMTDENBMi1QTC4wMS4wMRcNOTkwMTAxMTIwMTAwWhcNNDgwMTAxMTIwMTAwWqAjMCEwCg" + "YDVR0UBAMCAQEwEwYDVR0jBAwwCoAImYreMVMiXqUwDQYJKoZIhvcNAQEFBQADgYEAZFec" + "GtjOfp8pT0n1dMF/x9n8y5tM+G3LLnZvDJspLc/sqP3E3B/sHBiis81caEkQQAOTBU5goJ" + "0KOFAUOfEq+IX5uvNhuPuinx0OsSak+2Annvi12zodMQKPNm1uMVt2bMHHHZVEVTqcv36g" + "xgdbp0YKTmuvSy6s8NtGFpkNmnU="; public static final String End_Certificate_PL_01_01_crt = "MIIChzCCAfCgAwIBAgICAIgwDQYJKoZIhvcNAQEFBQAwXjELMAkGA1UEBhMCVVMxGDAWBg" + "NVBAoTD1UuUy4gR292ZXJubWVudDEMMAoGA1UECxMDRG9kMRAwDgYDVQQLEwdUZXN0aW5n" + "MRUwEwYDVQQDEwxDQTItUEwuMDEuMDEwHhcNOTgwMTAxMTIwMTAwWhcNNDgwMTAxMTIwMT" + "AwWjBgMQswCQYDVQQGEwJVUzEYMBYGA1UEChMPVS5TLiBHb3Zlcm5tZW50MQwwCgYDVQQL" + "EwNEb0QxEDAOBgNVBAsTB1Rlc3RpbmcxFzAVBgNVBAMTDlVzZXIxLVBMLjAxLjAxMIGfMA" + "0GCSqGSIb3DQEBAQUAA4GNADCBiQKBgQDCAUPp5j4V5XTA44Ra1EWkp9HgS4w3uXJ7/Vhi" + "K5bARFrDOOxjV8nmr5hoUYr4jwdi2Rl+60TQK/F08gdcGxdyc9p/yiU5HyAP6i+4iqmvaW" + "9b2egNyZ5tOmpl/Q9FSFWa9d/PYBKM5Sj/r73RtA+/chc4uq3uyLekSRQGh1MieQIDAQAB" + "o1IwUDAOBgNVHQ8BAf8EBAMCBeAwFgYDVR0gBA8wDTALBglghkgBZQMBMAEwEQYDVR0OBA" + "oECAiL3A4CkaFyMBMGA1UdIwQMMAqACJmK3jFTIl6lMA0GCSqGSIb3DQEBBQUAA4GBAJtH" + "mNNvCt/0uFbHdvUvCuBeZ9cggfpTyUS4X8zgcLDPFbw6VvX65umOZpceZI6hwcre+LZahi" + "gUEPvXppncEObkeVTcYdOTSDoxh5tZyee1P4sbD9H+suGWeewqUDvFs2ymHtxlkpOttitR" + "xQc2U6VlCuZ4XU8SwucyhW0z51e4"; public static final String[] TEST_54_DATA = new String[] { Intermediate_Certificate_1_PL_01_01_crt, Intermediate_Certificate_2_PL_01_01_crt, Intermediate_CRL_1_PL_01_01_crl, Intermediate_CRL_2_PL_01_01_crl, End_Certificate_PL_01_01_crt }; /* * test55 * */ public static final String Intermediate_Certificate_1_PL_01_02_crt = "MIICmTCCAgKgAwIBAgICAIkwDQYJKoZIhvcNAQEFBQAwXjELMAkGA1UEBhMCVVMxGDAWBg" + "NVBAoTD1UuUy4gR292ZXJubWVudDEMMAoGA1UECxMDRG9EMRAwDgYDVQQLEwdUZXN0aW5n" + "MRUwEwYDVQQDEwxUcnVzdCBBbmNob3IwHhcNOTgwMTAxMTIwMTAwWhcNNDgwMTAxMTIwMT" + "AwWjBeMQswCQYDVQQGEwJVUzEYMBYGA1UEChMPVS5TLiBHb3Zlcm5tZW50MQwwCgYDVQQL" + "EwNEb2QxEDAOBgNVBAsTB1Rlc3RpbmcxFTATBgNVBAMTDENBMS1QTC4wMS4wMjCBnzANBg" + "kqhkiG9w0BAQEFAAOBjQAwgYkCgYEA4QmGXEeVKCn1aQx27r+EBuQqfi8fP7gyV5JLkaSu" + "DOUrqXg8dQxHsBNCf3XilGIvjNFZjVUPdS8FNqC+if9D164VyGQlv/JUor/GlvwVfyotUO" + "U1PqSzFrAALYTmfm/ZqhMvGYloStSDxlzjDmyKadskzOxZZDNSe5s8dvUpYn0CAwEAAaNm" + "MGQwEgYDVR0TAQH/BAgwBgEB/wIBADAOBgNVHQ8BAf8EBAMCAQYwFgYDVR0gBA8wDTALBg" + "lghkgBZQMBMAEwEQYDVR0OBAoECGk7qDbbBgRbMBMGA1UdIwQMMAqACKua6/nC51SPMA0G" + "CSqGSIb3DQEBBQUAA4GBAD+eI+jg4jmeC3pJRGEF/hbPPYvL6aocjqqbZyNKN5FWItccQo" + "PWg/GK1GpusDZadesZBDo6fLIUJzL+OumrIYJLB3HxQsmyOXB1gRg1hcva71RWFJYzx01U" + "eB8lCbk8Zu24HzLzqjfVuwKOFFELWDEq7bd6Re/aKSHtNnDbsgSE"; public static final String Intermediate_Certificate_2_PL_01_02_crt = "MIICljCCAf+gAwIBAgICAIowDQYJKoZIhvcNAQEFBQAwXjELMAkGA1UEBhMCVVMxGDAWBg" + "NVBAoTD1UuUy4gR292ZXJubWVudDEMMAoGA1UECxMDRG9kMRAwDgYDVQQLEwdUZXN0aW5n" + "MRUwEwYDVQQDEwxDQTEtUEwuMDEuMDIwHhcNOTgwMTAxMTIwMTAwWhcNNDgwMTAxMTIwMT" + "AwWjBeMQswCQYDVQQGEwJVUzEYMBYGA1UEChMPVS5TLiBHb3Zlcm5tZW50MQwwCgYDVQQL" + "EwNEb2QxEDAOBgNVBAsTB1Rlc3RpbmcxFTATBgNVBAMTDENBMi1QTC4wMS4wMjCBnzANBg" + "kqhkiG9w0BAQEFAAOBjQAwgYkCgYEAl/HiHoos7eHaDIFhMmvIPk63UT33Z+0iiCIuKLW7" + "tgkT8ia1Yg++np1pC3oqYVeKkXqMcjgonPGQhcek12vLt3/+2PYyYirOTVZaiO9pKQ5An8" + "ZMWXIJmCEAMHabPO1RnetvRv5JZFxZY9jIUnD2fUADzzUh/eHN6Pur0DDrI6sCAwEAAaNj" + "MGEwDwYDVR0TAQH/BAUwAwEB/zAOBgNVHQ8BAf8EBAMCAQYwFgYDVR0gBA8wDTALBglghk" + "gBZQMBMAEwEQYDVR0OBAoECPk0C10KQLZuMBMGA1UdIwQMMAqACGk7qDbbBgRbMA0GCSqG" + "SIb3DQEBBQUAA4GBAMJ4+BZQxpxWhNbo8bpGkbbcKT3kfKYrHjHsZADC+/gAJSVL854b1W" + "VKsGr1YcCX10V1Gcqb6Jgziy+AzRLhcJngszcz0A7LxrMH+FIyWEPgZnOyQCa8B/9bnsh9" + "bC1gEmXGOVtWboIFOEdGghEbm/ENnQyj+HbIk3jhF3QYbXhw"; public static final String Intermediate_CRL_1_PL_01_02_crl = "MIIBSzCBtQIBATANBgkqhkiG9w0BAQUFADBeMQswCQYDVQQGEwJVUzEYMBYGA1UEChMPVS" + "5TLiBHb3Zlcm5tZW50MQwwCgYDVQQLEwNEb2QxEDAOBgNVBAsTB1Rlc3RpbmcxFTATBgNV" + "BAMTDENBMS1QTC4wMS4wMhcNOTkwMTAxMTIwMTAwWhcNNDgwMTAxMTIwMTAwWqAjMCEwCg" + "YDVR0UBAMCAQEwEwYDVR0jBAwwCoAIaTuoNtsGBFswDQYJKoZIhvcNAQEFBQADgYEAZEt+" + "FjRuXgnOZg70geqS4hVsF1VWWawlAVGmjPsbRH7rADXPUE2bYL54wLdwt/6QYwHqy2KwCf" + "d4OkWkwn9xwGS4j+XBCw9Y4nbWI+wrsZ9W7vgbeIaVUUUZu6hoin1GxrGDcfbM+bhYzQAA" + "gNmKIWdlJ4tKD2KNgg0KmZPoj/k="; public static final String Intermediate_CRL_2_PL_01_02_crl = "MIIBSzCBtQIBATANBgkqhkiG9w0BAQUFADBeMQswCQYDVQQGEwJVUzEYMBYGA1UEChMPVS" + "5TLiBHb3Zlcm5tZW50MQwwCgYDVQQLEwNEb2QxEDAOBgNVBAsTB1Rlc3RpbmcxFTATBgNV" + "BAMTDENBMi1QTC4wMS4wMhcNOTkwMTAxMTIwMTAwWhcNNDgwMTAxMTIwMTAwWqAjMCEwCg" + "YDVR0UBAMCAQEwEwYDVR0jBAwwCoAI+TQLXQpAtm4wDQYJKoZIhvcNAQEFBQADgYEAXwZO" + "wr9mrO6yUOoopNjcIcDssCUksYco1PFgWx9O/hGq9ktdoGoGcECGhdkHTLe2ab3WFl9jzW" + "1/lkysD9Jl3VjbnbRB3dPQlrSfiv7cYBLnfKvyF/CxQg/wCtWo46GJJQgOx/WHzi9aF08m" + "tQuJEtl7RgoByUSvLtmvKjQWEnc="; public static final String End_Certificate_PL_01_02_crt = "MIICljCCAf+gAwIBAgICAIswDQYJKoZIhvcNAQEFBQAwXjELMAkGA1UEBhMCVVMxGDAWBg" + "NVBAoTD1UuUy4gR292ZXJubWVudDEMMAoGA1UECxMDRG9kMRAwDgYDVQQLEwdUZXN0aW5n" + "MRUwEwYDVQQDEwxDQTItUEwuMDEuMDIwHhcNOTgwMTAxMTIwMTAwWhcNNDgwMTAxMTIwMT" + "AwWjBeMQswCQYDVQQGEwJVUzEYMBYGA1UEChMPVS5TLiBHb3Zlcm5tZW50MQwwCgYDVQQL" + "EwNEb2QxEDAOBgNVBAsTB1Rlc3RpbmcxFTATBgNVBAMTDENBMy1QTC4wMS4wMjCBnzANBg" + "kqhkiG9w0BAQEFAAOBjQAwgYkCgYEA0/rXOZwUebRaHcPPFeKTB2OWIzIAgavqb5HerPAe" + "c3sJCdNOSLc0OX0dFblso97WR8uueF9I7QeGg3ayQjzDVqm5Tu77ZaCuyb6UU8+fY2eqwD" + "5lCVuLfJr9U2JD5b2TcdvAD9RqfhefclVjDj9rObLjvzLg3AefO3drsfBtAIMCAwEAAaNj" + "MGEwDwYDVR0TAQH/BAUwAwEB/zAOBgNVHQ8BAf8EBAMCAeYwFgYDVR0gBA8wDTALBglghk" + "gBZQMBMAEwEQYDVR0OBAoECDBWCFTOp3evMBMGA1UdIwQMMAqACPk0C10KQLZuMA0GCSqG" + "SIb3DQEBBQUAA4GBAI/JpU3gHo8Izsbjlx6bkQo/e/hD634N5lSMtVHIGnoVLu99dvroRu" + "2DO8Fhnv6VZpMvYoAc5oEgUqx9hw3bfS/XN9GXaeMssjwN/qM6lzCsvMG7DA9sf59xjf4Y" + "2+u4KTye4PdpmWaseDDJ1wAihTHEaofnQdaoUffxQgw5UcAf"; public static final String[] TEST_55_DATA = new String[] { Intermediate_Certificate_1_PL_01_02_crt, Intermediate_Certificate_2_PL_01_02_crt, Intermediate_CRL_1_PL_01_02_crl, Intermediate_CRL_2_PL_01_02_crl, End_Certificate_PL_01_02_crt }; /* * test56 * */ public static final String Intermediate_Certificate_PL_01_03_crt = "MIICmTCCAgKgAwIBAgICAIwwDQYJKoZIhvcNAQEFBQAwXjELMAkGA1UEBhMCVVMxGDAWBg" + "NVBAoTD1UuUy4gR292ZXJubWVudDEMMAoGA1UECxMDRG9EMRAwDgYDVQQLEwdUZXN0aW5n" + "MRUwEwYDVQQDEwxUcnVzdCBBbmNob3IwHhcNOTgwMTAxMTIwMTAwWhcNNDgwMTAxMTIwMT" + "AwWjBeMQswCQYDVQQGEwJVUzEYMBYGA1UEChMPVS5TLiBHb3Zlcm5tZW50MQwwCgYDVQQL" + "EwNEb2QxEDAOBgNVBAsTB1Rlc3RpbmcxFTATBgNVBAMTDENBMS1QTC4wMS4wMzCBnzANBg" + "kqhkiG9w0BAQEFAAOBjQAwgYkCgYEA60y6V2WkNCB34dcGfu+Jo3YHQZXzgp76+HgnyFmP" + "DLj9DjZHqifD3gW8Zk7L+yK4PfLDSHjbrXM9GY1ser6XwhaJQDPUBBYW5X3XTOmDWmV63J" + "YeRF5r7cfF2h3eEZ460GRLK5tt0Zr8V+hA9oOvwqynrIhDYC/tCzE28ciqA+sCAwEAAaNm" + "MGQwEgYDVR0TAQH/BAgwBgEB/wIBADAOBgNVHQ8BAf8EBAMCAQYwFgYDVR0gBA8wDTALBg" + "lghkgBZQMBMAEwEQYDVR0OBAoECPE2FCetVerZMBMGA1UdIwQMMAqACKua6/nC51SPMA0G" + "CSqGSIb3DQEBBQUAA4GBABUOUWwyfyrRIw7dRIVfLlWyp5R1I+Kmq5e8st0AEMVpPAmLoy" + "0s+46Xf+THXZy5em1P3bSVTSUhTs+XD6tbFFUcTrX0mQJlshR7yD/A0siMDUNzzt9LJQvP" + "dwNjQSA2keOrV9q/2CAGce4daL4Wz54jfh33YVqJ8sHT4E8CxQb7"; public static final String Intermediate_CRL_PL_01_03_crl = "MIIBSzCBtQIBATANBgkqhkiG9w0BAQUFADBeMQswCQYDVQQGEwJVUzEYMBYGA1UEChMPVS" + "5TLiBHb3Zlcm5tZW50MQwwCgYDVQQLEwNEb2QxEDAOBgNVBAsTB1Rlc3RpbmcxFTATBgNV" + "BAMTDENBMS1QTC4wMS4wMxcNOTkwMTAxMTIwMTAwWhcNNDgwMTAxMTIwMTAwWqAjMCEwCg" + "YDVR0UBAMCAQEwEwYDVR0jBAwwCoAI8TYUJ61V6tkwDQYJKoZIhvcNAQEFBQADgYEA6FnB" + "LXWt4B/3oP0PXERYh7ZV39yu/tm9DHBQGcGDF8JIspU7F+mH/+37U/lT6BQxpKOpgOgGeP" + "nTQeQzN9sRsXxFO22SkHbdPCao84qvv485epgzqFcVsCRBwBBLcnNLMg891q0EYsTW9vSw" + "Dx7V4CawyYAYGz1MqYuY6SSs6Q0="; public static final String End_Certificate_PL_01_03_crt = "MIIChzCCAfCgAwIBAgICAI0wDQYJKoZIhvcNAQEFBQAwXjELMAkGA1UEBhMCVVMxGDAWBg" + "NVBAoTD1UuUy4gR292ZXJubWVudDEMMAoGA1UECxMDRG9kMRAwDgYDVQQLEwdUZXN0aW5n" + "MRUwEwYDVQQDEwxDQTEtUEwuMDEuMDMwHhcNOTgwMTAxMTIwMTAwWhcNNDgwMTAxMTIwMT" + "AwWjBgMQswCQYDVQQGEwJVUzEYMBYGA1UEChMPVS5TLiBHb3Zlcm5tZW50MQwwCgYDVQQL" + "EwNEb0QxEDAOBgNVBAsTB1Rlc3RpbmcxFzAVBgNVBAMTDlVzZXIxLVBMLjAxLjAzMIGfMA" + "0GCSqGSIb3DQEBAQUAA4GNADCBiQKBgQCwt6B9gpDz/x/vnowXf1MdkAPeaCWZ3pYikgxE" + "ZLrMuulFaI1UDnAzgSuSvoHE80VKGKjSkrzIX9OFfeilW5rNZAXoZrjtkaJd1Q8l5AtjFn" + "0tlLytDzIMYo5Tiq/n3IiTdbEzGYzEOCcSyVaQdB7K1WgYI/z/UAaWV/GbqCX1zQIDAQAB" + "o1IwUDAOBgNVHQ8BAf8EBAMCBeAwFgYDVR0gBA8wDTALBglghkgBZQMBMAEwEQYDVR0OBA" + "oECMQHLiufEm0IMBMGA1UdIwQMMAqACPE2FCetVerZMA0GCSqGSIb3DQEBBQUAA4GBAD5/" + "vGn/rpoHvny/mfh6n2zVNNQLTEBiddfAdCWpeBFcwxS5lpxfm4dAWgHhprZTMirF9yS+wO" + "wWQ4G9/wiqfAtoaNN1qkHMlUMOAPsOSff6ClgP+1uzKVqQa9NTd5HAeMdYfYjMa/fcF/37" + "plCs5ZsJjb9lhEjNd/tq4/aALQmt"; public static final String[] TEST_56_DATA = new String[] { Intermediate_Certificate_PL_01_03_crt, Intermediate_CRL_PL_01_03_crl, End_Certificate_PL_01_03_crt }; /* * test57 * */ public static final String Intermediate_Certificate_PL_01_04_crt = "MIICmTCCAgKgAwIBAgICAI4wDQYJKoZIhvcNAQEFBQAwXjELMAkGA1UEBhMCVVMxGDAWBg" + "NVBAoTD1UuUy4gR292ZXJubWVudDEMMAoGA1UECxMDRG9EMRAwDgYDVQQLEwdUZXN0aW5n" + "MRUwEwYDVQQDEwxUcnVzdCBBbmNob3IwHhcNOTgwMTAxMTIwMTAwWhcNNDgwMTAxMTIwMT" + "AwWjBeMQswCQYDVQQGEwJVUzEYMBYGA1UEChMPVS5TLiBHb3Zlcm5tZW50MQwwCgYDVQQL" + "EwNEb2QxEDAOBgNVBAsTB1Rlc3RpbmcxFTATBgNVBAMTDENBMS1QTC4wMS4wNDCBnzANBg" + "kqhkiG9w0BAQEFAAOBjQAwgYkCgYEA06yd2NQEAgpv0kQQEOzhHHU4YqHgtvJgkdLYxb2W" + "Zordrm4b/43UDnLmsI0790V76y9Aa+Y8SIMBBRBJgnlppFJrFsPaOMO98M3/mXkQotVbY1" + "59P/AjWMxpzP9h8Bs8KuoPqnl5jN0UZAF4kRoNXHzyS445VBp4DtWz/jcCPm8CAwEAAaNm" + "MGQwEgYDVR0TAQH/BAgwBgEB/wIBADAOBgNVHQ8BAf8EBAMCAQYwFgYDVR0gBA8wDTALBg" + "lghkgBZQMBMAEwEQYDVR0OBAoECHxLORDZ1KKNMBMGA1UdIwQMMAqACKua6/nC51SPMA0G" + "CSqGSIb3DQEBBQUAA4GBACHmDOaoC0Hr2cmfuQvdyGDF7/RlvTUJ7cvGypCa724SwAZGZk" + "Tf5GwxgjVcLHY5RlX2kDm9vjneDzP88U3587qA2ZRwxhheK0RGp1kudNQ5y2gAGKZ7YSc0" + "SENMDxUAa6HUkn9Rfo4rf5ULuGNJZXQZ3DtP+lZSwzkUeCVjKhyQ"; public static final String Intermediate_CRL_PL_01_04_crl = "MIIBSzCBtQIBATANBgkqhkiG9w0BAQUFADBeMQswCQYDVQQGEwJVUzEYMBYGA1UEChMPVS" + "5TLiBHb3Zlcm5tZW50MQwwCgYDVQQLEwNEb2QxEDAOBgNVBAsTB1Rlc3RpbmcxFTATBgNV" + "BAMTDENBMS1QTC4wMS4wNBcNOTkwMTAxMTIwMTAwWhcNNDgwMTAxMTIwMTAwWqAjMCEwCg" + "YDVR0UBAMCAQEwEwYDVR0jBAwwCoAIfEs5ENnUoo0wDQYJKoZIhvcNAQEFBQADgYEAb8lX" + "19SlVNRkc9SKNpRLZQom67djZfMSIPIDkBALfMepdevbquzgO7AufTuiDn5Zqe6J6odTv6" + "RrQReo64XB4+Lx2pXOe8bZEbzZk0HvzLl9DjN7zxyNglNK+Hd2xS4yT4ps4fBdvXvWAXEx" + "6DfvWHbGFDoH2auomCKJtCVXxCI="; public static final String End_Certificate_PL_01_04_crt = "MIICljCCAf+gAwIBAgICAI8wDQYJKoZIhvcNAQEFBQAwXjELMAkGA1UEBhMCVVMxGDAWBg" + "NVBAoTD1UuUy4gR292ZXJubWVudDEMMAoGA1UECxMDRG9kMRAwDgYDVQQLEwdUZXN0aW5n" + "MRUwEwYDVQQDEwxDQTEtUEwuMDEuMDQwHhcNOTgwMTAxMTIwMTAwWhcNNDgwMTAxMTIwMT" + "AwWjBeMQswCQYDVQQGEwJVUzEYMBYGA1UEChMPVS5TLiBHb3Zlcm5tZW50MQwwCgYDVQQL" + "EwNEb2QxEDAOBgNVBAsTB1Rlc3RpbmcxFTATBgNVBAMTDENBMi1QTC4wMS4wNDCBnzANBg" + "kqhkiG9w0BAQEFAAOBjQAwgYkCgYEA14bXc39XiWvb4r1jzbADzrpfbg2Y9sGBkefSQHsM" + "QZ1SRLR7uexWD7MuDYh4ZYBL+WPhaJJr3a1jnAIp54h68m8mwS13DgrxBF2/hrVKEm9IRG" + "s13hoM4Mjjogn/Lvc1xLvB5lctHjZrNRZjyrt+PqDDmqZqgCOmcD61PhrfAoECAwEAAaNj" + "MGEwDwYDVR0TAQH/BAUwAwEB/zAOBgNVHQ8BAf8EBAMCAeYwFgYDVR0gBA8wDTALBglghk" + "gBZQMBMAEwEQYDVR0OBAoECB9hXgJfzBvTMBMGA1UdIwQMMAqACHxLORDZ1KKNMA0GCSqG" + "SIb3DQEBBQUAA4GBAB0HgiURRd/REVfc5DenIPhMu8riVcwVgTUwatsCWragUhXpCtvJmf" + "z4vGo1rKYai2dltVX6am+NDvN5tROcM0bvC8lOCc/iPfI5eWTy9SJ2nxvs1+q809Rj0rno" + "zS77TIE8rD7Q8ZUd3qNUiBwdjBoc9misgyN7zUulg4Ueebvv"; public static final String[] TEST_57_DATA = new String[] { Intermediate_Certificate_PL_01_04_crt, Intermediate_CRL_PL_01_04_crl, End_Certificate_PL_01_04_crt }; /* * test58 * */ public static final String Intermediate_Certificate_1_PL_01_05_crt = "MIICmTCCAgKgAwIBAgICAJAwDQYJKoZIhvcNAQEFBQAwXjELMAkGA1UEBhMCVVMxGDAWBg" + "NVBAoTD1UuUy4gR292ZXJubWVudDEMMAoGA1UECxMDRG9EMRAwDgYDVQQLEwdUZXN0aW5n" + "MRUwEwYDVQQDEwxUcnVzdCBBbmNob3IwHhcNOTgwMTAxMTIwMTAwWhcNNDgwMTAxMTIwMT" + "AwWjBeMQswCQYDVQQGEwJVUzEYMBYGA1UEChMPVS5TLiBHb3Zlcm5tZW50MQwwCgYDVQQL" + "EwNEb2QxEDAOBgNVBAsTB1Rlc3RpbmcxFTATBgNVBAMTDENBMS1QTC4wMS4wNTCBnzANBg" + "kqhkiG9w0BAQEFAAOBjQAwgYkCgYEA/rVBEGZ4jibDhREeRGV3jPnv05esRL8/En1Bu35y" + "QrAHi32+kBu42vwwDbeuiTZd/B90bn5srJZoW83rxXxNnpxqbnjN3GgIcRiUVyaVRTp9/U" + "IT8B9h09b9yT8gpQ5qR0+JDcOHCfJwpogAsyJJa6AM5p/q3TeF39ugfVOWt/cCAwEAAaNm" + "MGQwEgYDVR0TAQH/BAgwBgEB/wIBBjAOBgNVHQ8BAf8EBAMCAQYwFgYDVR0gBA8wDTALBg" + "lghkgBZQMBMAEwEQYDVR0OBAoECJ7/mkuLuEIGMBMGA1UdIwQMMAqACKua6/nC51SPMA0G" + "CSqGSIb3DQEBBQUAA4GBADC0A2KMMSSmGI9p85WG7XZVMBX/xdDYOHO0e3ORTRFS3kj9rK" + "a0yUjc1X+p22AA8kUyOLpYIulfDjPrLKN2E/hWSf3+XWMiC7JfX01F+BBl/avEZoymaZB4" + "dkH1Hym4IMJoSaEOgf5HFKBnFEA6aUcr+oDYGUP+Sc1dmJMjBW72"; public static final String Intermediate_Certificate_2_PL_01_05_crt = "MIICmTCCAgKgAwIBAgICAJEwDQYJKoZIhvcNAQEFBQAwXjELMAkGA1UEBhMCVVMxGDAWBg" + "NVBAoTD1UuUy4gR292ZXJubWVudDEMMAoGA1UECxMDRG9kMRAwDgYDVQQLEwdUZXN0aW5n" + "MRUwEwYDVQQDEwxDQTEtUEwuMDEuMDUwHhcNOTgwMTAxMTIwMTAwWhcNNDgwMTAxMTIwMT" + "AwWjBeMQswCQYDVQQGEwJVUzEYMBYGA1UEChMPVS5TLiBHb3Zlcm5tZW50MQwwCgYDVQQL" + "EwNEb2QxEDAOBgNVBAsTB1Rlc3RpbmcxFTATBgNVBAMTDENBMi1QTC4wMS4wNTCBnzANBg" + "kqhkiG9w0BAQEFAAOBjQAwgYkCgYEArir4GaS6r0Tv9PMbaOXYdPKADNpVbJe79G5t/F6x" + "7Tz1rwUR+m10E+Jq9RsV+fU/nUzzjJXHbPLZnfodUVVmrXgzvQ8+B2N4jJtdNLG66j2PZG" + "+P8GQzVK9drDh54VHXdvxAYCXs7GaIprWmCQsxZOKjhFU3YDiRRK8qJGpBG/cCAwEAAaNm" + "MGQwEgYDVR0TAQH/BAgwBgEB/wIBADAOBgNVHQ8BAf8EBAMCAQYwFgYDVR0gBA8wDTALBg" + "lghkgBZQMBMAEwEQYDVR0OBAoECMmrFr30fUzZMBMGA1UdIwQMMAqACJ7/mkuLuEIGMA0G" + "CSqGSIb3DQEBBQUAA4GBAI4qJF6STCi+elUbpZIP7YmcaQsS0PE4G3+LJoMg1LT3rSeobK" + "Aj/yUetmA7y0B5i0svKjRChLOpfClNPVPCx/+mc75+LG+dh1eVG/qk2UH/lrqLN0XLl8tA" + "IwZeoPaegBQAIp9oEjhDN1fWtKIkOe6A6wYdH2VPvsqC8g02VcwD"; public static final String Intermediate_Certificate_3_PL_01_05_crt = "MIICmTCCAgKgAwIBAgICAJIwDQYJKoZIhvcNAQEFBQAwXjELMAkGA1UEBhMCVVMxGDAWBg" + "NVBAoTD1UuUy4gR292ZXJubWVudDEMMAoGA1UECxMDRG9kMRAwDgYDVQQLEwdUZXN0aW5n" + "MRUwEwYDVQQDEwxDQTItUEwuMDEuMDUwHhcNOTgwMTAxMTIwMTAwWhcNNDgwMTAxMTIwMT" + "AwWjBeMQswCQYDVQQGEwJVUzEYMBYGA1UEChMPVS5TLiBHb3Zlcm5tZW50MQwwCgYDVQQL" + "EwNEb2QxEDAOBgNVBAsTB1Rlc3RpbmcxFTATBgNVBAMTDENBMy1QTC4wMS4wNTCBnzANBg" + "kqhkiG9w0BAQEFAAOBjQAwgYkCgYEAtRC2/PDG3kx8LpzfWC0yJph5h3LXZJZW0W2voss1" + "HYPP1/MBoQY067dfbALilVRh9asCNL4F45uu0lT24qS9vjW8SzBOLA18GsVYRmWO7EP+Cd" + "9f3mgPIMJ5n+UjW+yhBwh0Z2pzVElkX9CxECrs1Mt2ulyuwWA1lR8nRMaTUeMCAwEAAaNm" + "MGQwEgYDVR0TAQH/BAgwBgEB/wIBADAOBgNVHQ8BAf8EBAMCAQYwFgYDVR0gBA8wDTALBg" + "lghkgBZQMBMAEwEQYDVR0OBAoECAlV3mzXYPyuMBMGA1UdIwQMMAqACMmrFr30fUzZMA0G" + "CSqGSIb3DQEBBQUAA4GBAG28iHdlA+nTs/b9pi+m9eMy7niELjIWL9fMgn1r4iXQ0TsPYi" + "tgpoip+BB4G/jz7MPx/N4nwyAPV+C9wN8cAHALf/ka2MxAORYFVFI+5PDgXzm78ILqj91f" + "vOFN4jemizTES4/dHxfmdctnsTRpU9ALQgfJLhxEQISOPwuemKB0"; public static final String Intermediate_CRL_1_PL_01_05_crl = "MIIBSzCBtQIBATANBgkqhkiG9w0BAQUFADBeMQswCQYDVQQGEwJVUzEYMBYGA1UEChMPVS" + "5TLiBHb3Zlcm5tZW50MQwwCgYDVQQLEwNEb2QxEDAOBgNVBAsTB1Rlc3RpbmcxFTATBgNV" + "BAMTDENBMS1QTC4wMS4wNRcNOTkwMTAxMTIwMTAwWhcNNDgwMTAxMTIwMTAwWqAjMCEwCg" + "YDVR0UBAMCAQEwEwYDVR0jBAwwCoAInv+aS4u4QgYwDQYJKoZIhvcNAQEFBQADgYEA5i45" + "gETFAw6l9Awex9IAVIqYTA1dnbDyrUYDRdzd0x6OxSPODvNfQCwqwlTJXrHidCPO8jRhMS" + "Zcdn/MTlIeHa6OERFcjOiwOpeTgtchvpTdDchs5ve8Ik+myue+cfgpEVKOE+ZQ2T2tcyz/" + "+DbeMptECfJ0lVfCKIY7ZOzBPaQ="; public static final String Intermediate_CRL_2_PL_01_05_crl = "MIIBSzCBtQIBATANBgkqhkiG9w0BAQUFADBeMQswCQYDVQQGEwJVUzEYMBYGA1UEChMPVS" + "5TLiBHb3Zlcm5tZW50MQwwCgYDVQQLEwNEb2QxEDAOBgNVBAsTB1Rlc3RpbmcxFTATBgNV" + "BAMTDENBMi1QTC4wMS4wNRcNOTkwMTAxMTIwMTAwWhcNNDgwMTAxMTIwMTAwWqAjMCEwCg" + "YDVR0UBAMCAQEwEwYDVR0jBAwwCoAIyasWvfR9TNkwDQYJKoZIhvcNAQEFBQADgYEAdsNe" + "ugM8sd8bmIDkYXce2WmS5Zx6QUQ0yT6Ij4OR5/F4CG4Vl+k3JkNPuAiNSs2Z9HeML+F/W8" + "3yEPe/mdLV4nLw4B/b1/8DmgZN4r1ojaWuHAg+KrA3Zz3Rc/hwQfvBy49mf4NGtY4ArbeB" + "DYKz5sVlrwR+gOCR5jm4IC7WEDs="; public static final String Intermediate_CRL_3_PL_01_05_crl = "MIIBSzCBtQIBATANBgkqhkiG9w0BAQUFADBeMQswCQYDVQQGEwJVUzEYMBYGA1UEChMPVS" + "5TLiBHb3Zlcm5tZW50MQwwCgYDVQQLEwNEb2QxEDAOBgNVBAsTB1Rlc3RpbmcxFTATBgNV" + "BAMTDENBMy1QTC4wMS4wNRcNOTkwMTAxMTIwMTAwWhcNNDgwMTAxMTIwMTAwWqAjMCEwCg" + "YDVR0UBAMCAQEwEwYDVR0jBAwwCoAICVXebNdg/K4wDQYJKoZIhvcNAQEFBQADgYEAqYex" + "FaIykZo17O2URpofe8x04L/VsfA9jV28zUgNFruAGld/kUh4rYvgwrdbNZ8NmEFDp9J9aL" + "93af3bzoNvWCik2VrQLd5nccCFiC04B+LUH9Y2p+7vV2ojrtBks5SMW0q4HaNyPSQu8Fst" + "4mYVf+QIYZC3iVAF4rsKnaxwzIU="; public static final String End_Certificate_PL_01_05_crt = "MIIChzCCAfCgAwIBAgICAJMwDQYJKoZIhvcNAQEFBQAwXjELMAkGA1UEBhMCVVMxGDAWBg" + "NVBAoTD1UuUy4gR292ZXJubWVudDEMMAoGA1UECxMDRG9kMRAwDgYDVQQLEwdUZXN0aW5n" + "MRUwEwYDVQQDEwxDQTMtUEwuMDEuMDUwHhcNOTgwMTAxMTIwMTAwWhcNNDgwMTAxMTIwMT" + "AwWjBgMQswCQYDVQQGEwJVUzEYMBYGA1UEChMPVS5TLiBHb3Zlcm5tZW50MQwwCgYDVQQL" + "EwNEb0QxEDAOBgNVBAsTB1Rlc3RpbmcxFzAVBgNVBAMTDlVzZXIxLVBMLjAxLjA1MIGfMA" + "0GCSqGSIb3DQEBAQUAA4GNADCBiQKBgQDCXJjzKGcLyONTyOa6sQHvIKZIAh0pWdteUiXf" + "b7yjCn6Z52SCHxB9GZERHwR7fbJpoE3oDcYUY+8pH65bIVm1p3zr5deo4v85DEZQ50cU9a" + "WEUAO/5X57P7pYb9/47abu0cdsLIWeE+O94HpZS8vz8mxRQKLj27gPY1KzzTbrZQIDAQAB" + "o1IwUDAOBgNVHQ8BAf8EBAMCBeAwFgYDVR0gBA8wDTALBglghkgBZQMBMAEwEQYDVR0OBA" + "oECG8ILlM9oqZwMBMGA1UdIwQMMAqACAlV3mzXYPyuMA0GCSqGSIb3DQEBBQUAA4GBAF6S" + "x3aunfgnDmo42aPOzDh536WSkTTbX9bmUNyg3IQHl/3xhVqjS76bMqreYhx5nh4VNx/Z3N" + "LD0W75XmASCk0wtW9S1MoxzJMFIozRruaE3oykrbyMMOt0Br5CV12ofUd0WybDkXfNAIze" + "IRgps3nORHWjV1GwXe8uNoUn6/z7"; public static final String[] TEST_58_DATA = new String[] { Intermediate_Certificate_1_PL_01_05_crt, Intermediate_Certificate_2_PL_01_05_crt, Intermediate_Certificate_3_PL_01_05_crt, Intermediate_CRL_1_PL_01_05_crl, Intermediate_CRL_2_PL_01_05_crl, Intermediate_CRL_3_PL_01_05_crl, End_Certificate_PL_01_05_crt }; /* * test59 * */ public static final String Intermediate_Certificate_1_PL_01_06_crt = "MIICmTCCAgKgAwIBAgICAJQwDQYJKoZIhvcNAQEFBQAwXjELMAkGA1UEBhMCVVMxGDAWBg" + "NVBAoTD1UuUy4gR292ZXJubWVudDEMMAoGA1UECxMDRG9EMRAwDgYDVQQLEwdUZXN0aW5n" + "MRUwEwYDVQQDEwxUcnVzdCBBbmNob3IwHhcNOTgwMTAxMTIwMTAwWhcNNDgwMTAxMTIwMT" + "AwWjBeMQswCQYDVQQGEwJVUzEYMBYGA1UEChMPVS5TLiBHb3Zlcm5tZW50MQwwCgYDVQQL" + "EwNEb2QxEDAOBgNVBAsTB1Rlc3RpbmcxFTATBgNVBAMTDENBMS1QTC4wMS4wNjCBnzANBg" + "kqhkiG9w0BAQEFAAOBjQAwgYkCgYEAweCAiEGMLycmodjrUMIWEEFshkvhX2r90wGl+/pU" + "Ia9NSdT23zYzE4Uo8Is1ywyV+YfvgR22j/RXF6j8OK+XZ8jlgfjVTAhjCnTWY9LDR7qAyk" + "8zuuITxJrYpiPoxqZs9BXLfGkDbye5VpVJXvQdbJNxgKO0hkBBDfe+T9+qw6ECAwEAAaNm" + "MGQwEgYDVR0TAQH/BAgwBgEB/wIBBjAOBgNVHQ8BAf8EBAMCAQYwFgYDVR0gBA8wDTALBg" + "lghkgBZQMBMAEwEQYDVR0OBAoECG1DiuoAwV6aMBMGA1UdIwQMMAqACKua6/nC51SPMA0G" + "CSqGSIb3DQEBBQUAA4GBAMFvtFiMDMP6n3CrqQLSzhpK5Qu0uxa56ARXIKSIqi0OUZAu9v" + "sCXxMvaG/R5bElwi7ybYZ5KUSN+PnDmlUxWWL5Ib5RZdXgj7L83oyLTQmbDMvka6rSWHgw" + "Jq8qHVslhh+l+YNOb4fzs8x9ctCrs/BgjX8wkORpQbigU0BUJ9sX"; public static final String Intermediate_Certificate_2_PL_01_06_crt = "MIICmTCCAgKgAwIBAgICAJUwDQYJKoZIhvcNAQEFBQAwXjELMAkGA1UEBhMCVVMxGDAWBg" + "NVBAoTD1UuUy4gR292ZXJubWVudDEMMAoGA1UECxMDRG9kMRAwDgYDVQQLEwdUZXN0aW5n" + "MRUwEwYDVQQDEwxDQTEtUEwuMDEuMDYwHhcNOTgwMTAxMTIwMTAwWhcNNDgwMTAxMTIwMT" + "AwWjBeMQswCQYDVQQGEwJVUzEYMBYGA1UEChMPVS5TLiBHb3Zlcm5tZW50MQwwCgYDVQQL" + "EwNEb2QxEDAOBgNVBAsTB1Rlc3RpbmcxFTATBgNVBAMTDENBMi1QTC4wMS4wNjCBnzANBg" + "kqhkiG9w0BAQEFAAOBjQAwgYkCgYEAwf6Nf0+r7JvE6BO4MbDbS1T1SCzn78haBAmqGZLS" + "Ac4xQTydvmzr9PwiWlU0xjFfKItqRMt7rfzTTPfvvnwxsAfQNPtxKzi30yCNq/VotMA7j5" + "iQYaVe2OWVHu13agbXLEZ0pL/ZkmQ3Gvo6UhF4dRmCnjFbd5cMTxQVHUrwgyECAwEAAaNm" + "MGQwEgYDVR0TAQH/BAgwBgEB/wIBADAOBgNVHQ8BAf8EBAMCAQYwFgYDVR0gBA8wDTALBg" + "lghkgBZQMBMAEwEQYDVR0OBAoECE3tS4AYmwZDMBMGA1UdIwQMMAqACG1DiuoAwV6aMA0G" + "CSqGSIb3DQEBBQUAA4GBADcBTKbhx8PCunjRVJkcLBCcVGHs9HfkChDafwBO51fe5uhHE2" + "QBpW3J8ZsevuFQiEZvuy2RVFktE6ZoKD8wxwBFhs+OIxe2mergQPy6jHuxoSUiPzr3CVXZ" + "UsNxe7j3IcJLqbJ15UqGFH5yph7Sa4Ym6x747miF6W9knNkjcx3K"; public static final String Intermediate_Certificate_3_PL_01_06_crt = "MIICmTCCAgKgAwIBAgICAJYwDQYJKoZIhvcNAQEFBQAwXjELMAkGA1UEBhMCVVMxGDAWBg" + "NVBAoTD1UuUy4gR292ZXJubWVudDEMMAoGA1UECxMDRG9kMRAwDgYDVQQLEwdUZXN0aW5n" + "MRUwEwYDVQQDEwxDQTItUEwuMDEuMDYwHhcNOTgwMTAxMTIwMTAwWhcNNDgwMTAxMTIwMT" + "AwWjBeMQswCQYDVQQGEwJVUzEYMBYGA1UEChMPVS5TLiBHb3Zlcm5tZW50MQwwCgYDVQQL" + "EwNEb2QxEDAOBgNVBAsTB1Rlc3RpbmcxFTATBgNVBAMTDENBMy1QTC4wMS4wNjCBnzANBg" + "kqhkiG9w0BAQEFAAOBjQAwgYkCgYEAwq2YlDLHX4KktKnzLCYjnk079IDgXENrkRBuZHTB" + "IQyZoiBH4ZWHreZKs3LvznP8uSd8eEL8keNw4PwZ6aT1LF/Jr/UlrFQNnpLzQVXwGGAuzh" + "tFJYRlOfI5cCZYAcpjnyUV4GW+MuwBdoqDycMjmqIv/8A8vupjahffcmBAassCAwEAAaNm" + "MGQwEgYDVR0TAQH/BAgwBgEB/wIBADAOBgNVHQ8BAf8EBAMCAQYwFgYDVR0gBA8wDTALBg" + "lghkgBZQMBMAEwEQYDVR0OBAoECB+qYFJjEkJ5MBMGA1UdIwQMMAqACE3tS4AYmwZDMA0G" + "CSqGSIb3DQEBBQUAA4GBADiXredACtRQTV2TKgu5SDdPlczj7cZZUARJiJKiRfjmxHCc1q" + "m/Oh7sHkqRvlHqjoX8qp4iSchoZWdOAE5O/q4Ef6rViejDFVyN2ZmlhP6KIiRxznrvYfF1" + "n08K7CHgHWvDaumm4pNmWeF03nuasHrY0W9h1uk5poVuzaWDpx3A"; public static final String Intermediate_CRL_1_PL_01_06_crl = "MIIBSzCBtQIBATANBgkqhkiG9w0BAQUFADBeMQswCQYDVQQGEwJVUzEYMBYGA1UEChMPVS" + "5TLiBHb3Zlcm5tZW50MQwwCgYDVQQLEwNEb2QxEDAOBgNVBAsTB1Rlc3RpbmcxFTATBgNV" + "BAMTDENBMS1QTC4wMS4wNhcNOTkwMTAxMTIwMTAwWhcNNDgwMTAxMTIwMTAwWqAjMCEwCg" + "YDVR0UBAMCAQEwEwYDVR0jBAwwCoAIbUOK6gDBXpowDQYJKoZIhvcNAQEFBQADgYEAiHM1" + "xFuYt6tDscqzwj0mLHPHULnR44/vNyPUg0KnV03Dd4XbFHz0FtwDKgVTBZ8x7ybp83ubJH" + "tE/p8nPW5kN25WQOlYkZoAcMpEXjTzlo9evU0W3nyzJjmlT8YEI7vnmWFz/ahzy6WFwPue" + "h862EKh2zVO4hoqZYEuDQI33fOc="; public static final String Intermediate_CRL_2_PL_01_06_crl = "MIIBSzCBtQIBATANBgkqhkiG9w0BAQUFADBeMQswCQYDVQQGEwJVUzEYMBYGA1UEChMPVS" + "5TLiBHb3Zlcm5tZW50MQwwCgYDVQQLEwNEb2QxEDAOBgNVBAsTB1Rlc3RpbmcxFTATBgNV" + "BAMTDENBMi1QTC4wMS4wNhcNOTkwMTAxMTIwMTAwWhcNNDgwMTAxMTIwMTAwWqAjMCEwCg" + "YDVR0UBAMCAQEwEwYDVR0jBAwwCoAITe1LgBibBkMwDQYJKoZIhvcNAQEFBQADgYEAuDSF" + "W1KOc4x41HGvdRaw/NtipD2y6zSh3mtRoo7Q6J2BvJvunymZNEziozBOiUgT8zMgbdbm4a" + "PEwlHRaoJP8+yxJIlKaHa9Hc7Yz4SOwSrLicf7EnBSct3Mze0b48UYqbn1q+lf/zKaUGrP" + "M6oqtE8Fam06T+WUfutU53zTtSs="; public static final String Intermediate_CRL_3_PL_01_06_crl = "MIIBSzCBtQIBATANBgkqhkiG9w0BAQUFADBeMQswCQYDVQQGEwJVUzEYMBYGA1UEChMPVS" + "5TLiBHb3Zlcm5tZW50MQwwCgYDVQQLEwNEb2QxEDAOBgNVBAsTB1Rlc3RpbmcxFTATBgNV" + "BAMTDENBMy1QTC4wMS4wNhcNOTkwMTAxMTIwMTAwWhcNNDgwMTAxMTIwMTAwWqAjMCEwCg" + "YDVR0UBAMCAQEwEwYDVR0jBAwwCoAIH6pgUmMSQnkwDQYJKoZIhvcNAQEFBQADgYEAcPfO" + "+Rj2KmO1CxjuKLEiOUAIq5YmR4U06IcCBGMxlrdHVXHM3vepBKUlMDaT4UGcleABMPX9Iz" + "/31ofyXlZ/fQJOoTZt0CI7SOPQE5ZkUsR3BDuUqf1+sWwBYyBHkrC95JhJkM4LfGS5K19p" + "fp0j0bguzNCXSBRTfjSZhy80tcs="; public static final String End_Certificate_PL_01_06_crt = "MIICljCCAf+gAwIBAgICAJcwDQYJKoZIhvcNAQEFBQAwXjELMAkGA1UEBhMCVVMxGDAWBg" + "NVBAoTD1UuUy4gR292ZXJubWVudDEMMAoGA1UECxMDRG9kMRAwDgYDVQQLEwdUZXN0aW5n" + "MRUwEwYDVQQDEwxDQTMtUEwuMDEuMDYwHhcNOTgwMTAxMTIwMTAwWhcNNDgwMTAxMTIwMT" + "AwWjBeMQswCQYDVQQGEwJVUzEYMBYGA1UEChMPVS5TLiBHb3Zlcm5tZW50MQwwCgYDVQQL" + "EwNEb2QxEDAOBgNVBAsTB1Rlc3RpbmcxFTATBgNVBAMTDENBNC1QTC4wMS4wNjCBnzANBg" + "kqhkiG9w0BAQEFAAOBjQAwgYkCgYEA3asAqJcjXngEuyM/W3+TAE+Qr4JtNUdwBtmrpGlo" + "fAvJdmXHARyiN/Zn6Si8bGI8Wz8J4Y+Ll7zLdaMU4MCZo6hwZiaQwkh9a+ZecCpLpjs4mz" + "MSf5zHSwTYiXKMazlmnGEITVyKLmAiLSyGeeJvOJVqVo/NZXRGVlmnPxZFfgsCAwEAAaNj" + "MGEwDwYDVR0TAQH/BAUwAwEB/zAOBgNVHQ8BAf8EBAMCAeYwFgYDVR0gBA8wDTALBglghk" + "gBZQMBMAEwEQYDVR0OBAoECLZuS770NcDsMBMGA1UdIwQMMAqACB+qYFJjEkJ5MA0GCSqG" + "SIb3DQEBBQUAA4GBAGM18aR2i8vSywsWhcLrRN1Xckl/HiBPNphobfKoER4NG29cFjUPQX" + "zukjQcJl2clAXNCVtcsKCoYRP3YUyAB6At+yskuuJXtES7FIzM3rt/UpDS5ktVC3gh+jgE" + "pPhMILYIXFzYY1hifkpagfO+mkcr7RqHU3tHAr6LCWjqrB9g"; public static final String[] TEST_59_DATA = new String[] { Intermediate_Certificate_1_PL_01_06_crt, Intermediate_Certificate_2_PL_01_06_crt, Intermediate_Certificate_3_PL_01_06_crt, Intermediate_CRL_1_PL_01_06_crl, Intermediate_CRL_2_PL_01_06_crl, Intermediate_CRL_3_PL_01_06_crl, End_Certificate_PL_01_06_crt }; /* * test60 * */ public static final String Intermediate_Certificate_1_PL_01_07_crt = "MIICmTCCAgKgAwIBAgICAJgwDQYJKoZIhvcNAQEFBQAwXjELMAkGA1UEBhMCVVMxGDAWBg" + "NVBAoTD1UuUy4gR292ZXJubWVudDEMMAoGA1UECxMDRG9EMRAwDgYDVQQLEwdUZXN0aW5n" + "MRUwEwYDVQQDEwxUcnVzdCBBbmNob3IwHhcNOTgwMTAxMTIwMTAwWhcNNDgwMTAxMTIwMT" + "AwWjBeMQswCQYDVQQGEwJVUzEYMBYGA1UEChMPVS5TLiBHb3Zlcm5tZW50MQwwCgYDVQQL" + "EwNEb2QxEDAOBgNVBAsTB1Rlc3RpbmcxFTATBgNVBAMTDENBMS1QTC4wMS4wNzCBnzANBg" + "kqhkiG9w0BAQEFAAOBjQAwgYkCgYEA5HkS45NLuqq9ZwF79+pTGtQnGWO7DFdetYeQTbeD" + "sisjZMsK0sCCR5xAKYQsJSS4v/8LQUdxlQR30LMV0SQUKFMJyFsMiSsO8subb6sVINWn8A" + "tL4zcQK0WiASUZOEkybAFJtP31PahzI5wfD1cikE1M4BlDij5WeaIjt/RTHKUCAwEAAaNm" + "MGQwEgYDVR0TAQH/BAgwBgEB/wIBBjAOBgNVHQ8BAf8EBAMCAQYwFgYDVR0gBA8wDTALBg" + "lghkgBZQMBMAEwEQYDVR0OBAoECLSUEn5d8YywMBMGA1UdIwQMMAqACKua6/nC51SPMA0G" + "CSqGSIb3DQEBBQUAA4GBANLO+kEiswkGzEh4ZcF5LtfnPZlnG4gTPSNugeWJc+Xedqmttp" + "jZ35fr1hiRe2Q1UcyTd4ThkPknawwZednbsZVPqw8u1mo7kuAeL9KrCk199vL4bV8Ag/kj" + "HJ8TAy40UDB6hMm7l4j8mEKwV03THVrz1Vvz59CQXj+iseH6yUNO"; public static final String Intermediate_Certificate_2_PL_01_07_crt = "MIICmTCCAgKgAwIBAgICAJkwDQYJKoZIhvcNAQEFBQAwXjELMAkGA1UEBhMCVVMxGDAWBg" + "NVBAoTD1UuUy4gR292ZXJubWVudDEMMAoGA1UECxMDRG9kMRAwDgYDVQQLEwdUZXN0aW5n" + "MRUwEwYDVQQDEwxDQTEtUEwuMDEuMDcwHhcNOTgwMTAxMTIwMTAwWhcNNDgwMTAxMTIwMT" + "AwWjBeMQswCQYDVQQGEwJVUzEYMBYGA1UEChMPVS5TLiBHb3Zlcm5tZW50MQwwCgYDVQQL" + "EwNEb2QxEDAOBgNVBAsTB1Rlc3RpbmcxFTATBgNVBAMTDENBMi1QTC4wMS4wNzCBnzANBg" + "kqhkiG9w0BAQEFAAOBjQAwgYkCgYEAu78gmT5HwmBHEe+K8fLLgGaPpcv13ZjrgL4twTBS" + "OkZn5LL9GcfkPuA5WIAZkVYfCWSDPqcAGoOWUIDADfBfdcyLteUH+xI01rHKiLDVexMvU9" + "vqCmcBKhxK3S6wraW5YhOO0bx4oPrZXVIjyG8fh4e5WTEykzvUWJ8ZbzSJ9JsCAwEAAaNm" + "MGQwEgYDVR0TAQH/BAgwBgEB/wIBATAOBgNVHQ8BAf8EBAMCAQYwFgYDVR0gBA8wDTALBg" + "lghkgBZQMBMAEwEQYDVR0OBAoECCT+fDEaN7GaMBMGA1UdIwQMMAqACLSUEn5d8YywMA0G" + "CSqGSIb3DQEBBQUAA4GBANpKr98PiXAdcXlbgSgif0213H+tg3WwUNKZTw8MpqPyrN2/DZ" + "HBi6e2KWXLTxttV9AZBRvcKwsveS6oc31eulMe8nHxRNRfadvF6dL3Tsig6HAQkartcJMI" + "yfW4V3EhXbCdziQkre7XcR9WK5bpQoX04HWeew6YTxjG/cL9MIJR"; public static final String Intermediate_Certificate_3_PL_01_07_crt = "MIICmTCCAgKgAwIBAgICAJowDQYJKoZIhvcNAQEFBQAwXjELMAkGA1UEBhMCVVMxGDAWBg" + "NVBAoTD1UuUy4gR292ZXJubWVudDEMMAoGA1UECxMDRG9kMRAwDgYDVQQLEwdUZXN0aW5n" + "MRUwEwYDVQQDEwxDQTItUEwuMDEuMDcwHhcNOTgwMTAxMTIwMTAwWhcNNDgwMTAxMTIwMT" + "AwWjBeMQswCQYDVQQGEwJVUzEYMBYGA1UEChMPVS5TLiBHb3Zlcm5tZW50MQwwCgYDVQQL" + "EwNEb2QxEDAOBgNVBAsTB1Rlc3RpbmcxFTATBgNVBAMTDENBMy1QTC4wMS4wNzCBnzANBg" + "kqhkiG9w0BAQEFAAOBjQAwgYkCgYEAr7YezMXvnkSuNCdXch2HRAEVuCqfzpVRCj6laJI9" + "Q+NxgXwzaOwnImvwER3Hblh1l0MAt5/I/9hhqCN+918ueME50MkoM1wPbcmrRIlwWLGSVZ" + "yBKeyPHrLbdPqVIexUlQk7PasLm/Qx4SvRGVe9IMLrEzPV3MFJtrJoWaMobQkCAwEAAaNm" + "MGQwEgYDVR0TAQH/BAgwBgEB/wIBATAOBgNVHQ8BAf8EBAMCAQYwFgYDVR0gBA8wDTALBg" + "lghkgBZQMBMAEwEQYDVR0OBAoECKw8JlHMvVfuMBMGA1UdIwQMMAqACCT+fDEaN7GaMA0G" + "CSqGSIb3DQEBBQUAA4GBAA5JEDEDyqfZzTGzOoMV+8RVke+a4qgOo7rnOEdletgGFEwz8A" + "tiMHBxR+UMxuHS82Hz3+F8XlyYIwlrG9wWVcB/tOyzgVyA28Yux9Q/meU7T6dco/AnmOdr" + "2XL6Xm5iLnARG+PkUPHOsxuweyB/sSUSA8ZJPowNRWTik57ul/bO"; public static final String Intermediate_Certificate_4_PL_01_07_crt = "MIICljCCAf+gAwIBAgICAJswDQYJKoZIhvcNAQEFBQAwXjELMAkGA1UEBhMCVVMxGDAWBg" + "NVBAoTD1UuUy4gR292ZXJubWVudDEMMAoGA1UECxMDRG9kMRAwDgYDVQQLEwdUZXN0aW5n" + "MRUwEwYDVQQDEwxDQTMtUEwuMDEuMDcwHhcNOTgwMTAxMTIwMTAwWhcNNDgwMTAxMTIwMT" + "AwWjBeMQswCQYDVQQGEwJVUzEYMBYGA1UEChMPVS5TLiBHb3Zlcm5tZW50MQwwCgYDVQQL" + "EwNEb2QxEDAOBgNVBAsTB1Rlc3RpbmcxFTATBgNVBAMTDENBNC1QTC4wMS4wNzCBnzANBg" + "kqhkiG9w0BAQEFAAOBjQAwgYkCgYEA7mNS8dGz0gkXDbBRzP2ypdNMahJbM3cSMHO0hYpn" + "uRsiXGUhIB0K4WVbnz6tr7Hch3yltK4H1Y12Lf8cXEETR2sE9lCY2A3r8/VM5OUbou5Y8k" + "wIf03VhP7cGKonaFtlj/WD77fidDePVp1Nk28gV0T2F/l4pM5TEJrq5C9PSUcCAwEAAaNj" + "MGEwDwYDVR0TAQH/BAUwAwEB/zAOBgNVHQ8BAf8EBAMCAQYwFgYDVR0gBA8wDTALBglghk" + "gBZQMBMAEwEQYDVR0OBAoECJBEcZsMRq6CMBMGA1UdIwQMMAqACKw8JlHMvVfuMA0GCSqG" + "SIb3DQEBBQUAA4GBACfbHKpuRJnZ5UU0sih8RuywhUo6Getwl/p6fsi87wYI61pvYru+hm" + "4R4eAMZvg7MrAarS3Iu3zKBU1HKeq1i+hpwTIXrngR8eL2fU/X6GPzdte3+3tjhah38bqF" + "zDon+N6ap4MKWRk033SsFYo1K88Mena2tGuFForJlV9DOF1l"; public static final String Intermediate_CRL_1_PL_01_07_crl = "MIIBSzCBtQIBATANBgkqhkiG9w0BAQUFADBeMQswCQYDVQQGEwJVUzEYMBYGA1UEChMPVS" + "5TLiBHb3Zlcm5tZW50MQwwCgYDVQQLEwNEb2QxEDAOBgNVBAsTB1Rlc3RpbmcxFTATBgNV" + "BAMTDENBMS1QTC4wMS4wNxcNOTkwMTAxMTIwMTAwWhcNNDgwMTAxMTIwMTAwWqAjMCEwCg" + "YDVR0UBAMCAQEwEwYDVR0jBAwwCoAItJQSfl3xjLAwDQYJKoZIhvcNAQEFBQADgYEAJtaE" + "I1+PCNL1/bgEVKWUIwvh58ugnWhxzbFW6hNJwNEz9/yt+FLZfNrT/Ezort4VVQFLQg7+Gj" + "KrkIujqfRJG4LXrXAV8ZsvSPuwyQ+hM1GdHGDPhj9x6DkjFusxJYUEs5BzlX7ovpnaIPSW" + "RPsatheSzu48pMOCmyTKE3MpuZg="; public static final String Intermediate_CRL_2_PL_01_07_crl = "MIIBSzCBtQIBATANBgkqhkiG9w0BAQUFADBeMQswCQYDVQQGEwJVUzEYMBYGA1UEChMPVS" + "5TLiBHb3Zlcm5tZW50MQwwCgYDVQQLEwNEb2QxEDAOBgNVBAsTB1Rlc3RpbmcxFTATBgNV" + "BAMTDENBMi1QTC4wMS4wNxcNOTkwMTAxMTIwMTAwWhcNNDgwMTAxMTIwMTAwWqAjMCEwCg" + "YDVR0UBAMCAQEwEwYDVR0jBAwwCoAIJP58MRo3sZowDQYJKoZIhvcNAQEFBQADgYEALiV+" + "BFpXhgTjiMZBYLVuc/fqhHcXeXOGOmJZoKUnIXjETH3rzkkt5k4tMN00ycZVgpRwn3ZyQs" + "cFLcW8taau1J7iQOmGY/7qIT0eFx2OlgNmxqirmwx4OM5VSH5mEpnp9NOr1rfut1GDRzw0" + "tZ+nhD/PGDXYPu+QPX6jii0vdHo="; public static final String Intermediate_CRL_3_PL_01_07_crl = "MIIBSzCBtQIBATANBgkqhkiG9w0BAQUFADBeMQswCQYDVQQGEwJVUzEYMBYGA1UEChMPVS" + "5TLiBHb3Zlcm5tZW50MQwwCgYDVQQLEwNEb2QxEDAOBgNVBAsTB1Rlc3RpbmcxFTATBgNV" + "BAMTDENBMy1QTC4wMS4wNxcNOTkwMTAxMTIwMTAwWhcNNDgwMTAxMTIwMTAwWqAjMCEwCg" + "YDVR0UBAMCAQEwEwYDVR0jBAwwCoAIrDwmUcy9V+4wDQYJKoZIhvcNAQEFBQADgYEASY47" + "p94jEh9FZ1TrPS82nWC3Z6ZKdaD9pUbaJpRnAId59QdBaD2Cxq+SfM3HTlz8grCAPKwulv" + "jDDhXhp4H/m63Q/pJbyl3bbMxnphMOoDwB9wwKIUQPM5wagMovF/UYtC8MoC++m2kuZ1eb" + "fR/OIJuQr+k/kD5Axhw/xolKPdE="; public static final String Intermediate_CRL_4_PL_01_07_crl = "MIIBSzCBtQIBATANBgkqhkiG9w0BAQUFADBeMQswCQYDVQQGEwJVUzEYMBYGA1UEChMPVS" + "5TLiBHb3Zlcm5tZW50MQwwCgYDVQQLEwNEb2QxEDAOBgNVBAsTB1Rlc3RpbmcxFTATBgNV" + "BAMTDENBNC1QTC4wMS4wNxcNOTkwMTAxMTIwMTAwWhcNNDgwMTAxMTIwMTAwWqAjMCEwCg" + "YDVR0UBAMCAQEwEwYDVR0jBAwwCoAIkERxmwxGroIwDQYJKoZIhvcNAQEFBQADgYEAMhIQ" + "lE+BdCO6NBz+YgcH+tjP0n4OCdQ+7uxUxUYmPtPbsLwbDDEEZUjykgwiA6P47Cqh5fXB6G" + "tfInh1cmQi3y2IEHK+bRSx321qczOh34Yx2hw5vp+JFttbQAEl/BHixklrFBrXjN0UsWGC" + "ibXcZy0YjerWTp/yceoABz9p94U="; public static final String End_Certificate_PL_01_07_crt = "MIIChzCCAfCgAwIBAgICAJwwDQYJKoZIhvcNAQEFBQAwXjELMAkGA1UEBhMCVVMxGDAWBg" + "NVBAoTD1UuUy4gR292ZXJubWVudDEMMAoGA1UECxMDRG9kMRAwDgYDVQQLEwdUZXN0aW5n" + "MRUwEwYDVQQDEwxDQTQtUEwuMDEuMDcwHhcNOTgwMTAxMTIwMTAwWhcNNDgwMTAxMTIwMT" + "AwWjBgMQswCQYDVQQGEwJVUzEYMBYGA1UEChMPVS5TLiBHb3Zlcm5tZW50MQwwCgYDVQQL" + "EwNEb0QxEDAOBgNVBAsTB1Rlc3RpbmcxFzAVBgNVBAMTDlVzZXIxLVBMLjAxLjA3MIGfMA" + "0GCSqGSIb3DQEBAQUAA4GNADCBiQKBgQCdH60mBM1eInACvOB83zLrtiebq9B5UBlAAVS8" + "9ucDwGx1HOJwhwk2AmvhN7pYuDc+BFzuNtgHojqZSDpRMA3rVsGlgOkZ3sOQzvxB73w+/X" + "XmCYpwcEGLpK4egl8r1aOYm0Zm4OxqWhNu9+Do7nrJczDLi8k/qh8/+Rfdtvt4kwIDAQAB" + "o1IwUDAOBgNVHQ8BAf8EBAMCBeAwFgYDVR0gBA8wDTALBglghkgBZQMBMAEwEQYDVR0OBA" + "oECEmVurZ+7UXFMBMGA1UdIwQMMAqACJBEcZsMRq6CMA0GCSqGSIb3DQEBBQUAA4GBAANe" + "AbvpAHwBu9+FlI4DOb65Z+h5f2Ok59FVbVqAj3zkMRkawppngK3CMY/1BQlGXOlHvE+CGz" + "x/7DsiV0O3rxOUjutt00PNxCyIM2pcOZeGUaAu5DJWn0SRwzTMJa4M5K+7wh/4sSPWyxKi" + "ueDq2VXvIgAfEVC8Lv44sxcOduSZ"; public static final String[] TEST_60_DATA = new String[] { Intermediate_Certificate_1_PL_01_07_crt, Intermediate_Certificate_2_PL_01_07_crt, Intermediate_Certificate_3_PL_01_07_crt, Intermediate_Certificate_4_PL_01_07_crt, Intermediate_CRL_1_PL_01_07_crl, Intermediate_CRL_2_PL_01_07_crl, Intermediate_CRL_3_PL_01_07_crl, Intermediate_CRL_4_PL_01_07_crl, End_Certificate_PL_01_07_crt }; /* * test61 * */ public static final String Intermediate_Certificate_1_PL_01_08_crt = "MIICmTCCAgKgAwIBAgICAJ0wDQYJKoZIhvcNAQEFBQAwXjELMAkGA1UEBhMCVVMxGDAWBg" + "NVBAoTD1UuUy4gR292ZXJubWVudDEMMAoGA1UECxMDRG9EMRAwDgYDVQQLEwdUZXN0aW5n" + "MRUwEwYDVQQDEwxUcnVzdCBBbmNob3IwHhcNOTgwMTAxMTIwMTAwWhcNNDgwMTAxMTIwMT" + "AwWjBeMQswCQYDVQQGEwJVUzEYMBYGA1UEChMPVS5TLiBHb3Zlcm5tZW50MQwwCgYDVQQL" + "EwNEb2QxEDAOBgNVBAsTB1Rlc3RpbmcxFTATBgNVBAMTDENBMS1QTC4wMS4wODCBnzANBg" + "kqhkiG9w0BAQEFAAOBjQAwgYkCgYEAsr+i9HxgO6LnOa6xOHfe9BeLVTo4iZd8rp6UTc02" + "C0MmsSjvIgn3UiayU7aoHcTH8tAXSV5bn0CIH4B46qLym//oE69hUFImy6d1kKgNoaUKWB" + "HztKVtswSSPjIUf7pbyp0wasYMN6fIKYyLpLXUxzA2DrD0kP2Y8ElQJKl2HocCAwEAAaNm" + "MGQwEgYDVR0TAQH/BAgwBgEB/wIBBjAOBgNVHQ8BAf8EBAMCAQYwFgYDVR0gBA8wDTALBg" + "lghkgBZQMBMAEwEQYDVR0OBAoECPMW3WMPtaowMBMGA1UdIwQMMAqACKua6/nC51SPMA0G" + "CSqGSIb3DQEBBQUAA4GBAH2N6S9ggfmRJkzhs82uOPXaHF62YEg1pbNxaCyJJbSt2iIIyy" + "NPSlE1OufPPH3pO7p5xcYi90LCI//0tlUL8y7aULFNygbshFY3B8MSgCz3KPA3UKdtIZYe" + "7lqP9/ob5wmkjtLpx6oZ4/38jxqe37pH1IwVjaUnoeElSo3EkCI5"; public static final String Intermediate_Certificate_2_PL_01_08_crt = "MIICmTCCAgKgAwIBAgICAJ4wDQYJKoZIhvcNAQEFBQAwXjELMAkGA1UEBhMCVVMxGDAWBg" + "NVBAoTD1UuUy4gR292ZXJubWVudDEMMAoGA1UECxMDRG9kMRAwDgYDVQQLEwdUZXN0aW5n" + "MRUwEwYDVQQDEwxDQTEtUEwuMDEuMDgwHhcNOTgwMTAxMTIwMTAwWhcNNDgwMTAxMTIwMT" + "AwWjBeMQswCQYDVQQGEwJVUzEYMBYGA1UEChMPVS5TLiBHb3Zlcm5tZW50MQwwCgYDVQQL" + "EwNEb2QxEDAOBgNVBAsTB1Rlc3RpbmcxFTATBgNVBAMTDENBMi1QTC4wMS4wODCBnzANBg" + "kqhkiG9w0BAQEFAAOBjQAwgYkCgYEAqZZolrig33i1rEwdP1pin8a5PgzSk7fT+qhrJRCg" + "UTOW5WyPtakrLTUipDcR07t8tIe0NsjRoph7+fAwbjWBfbJdydndHHGx5BqWg8Xi4zFhFd" + "6Mc5O6KO7Yqxs8lmthv/RAdL4Eiir9d9hqskKOtQKbLWz+Bz3+9NwfLGzwzPcCAwEAAaNm" + "MGQwEgYDVR0TAQH/BAgwBgEB/wIBATAOBgNVHQ8BAf8EBAMCAQYwFgYDVR0gBA8wDTALBg" + "lghkgBZQMBMAEwEQYDVR0OBAoECFjxM3RkbbhNMBMGA1UdIwQMMAqACPMW3WMPtaowMA0G" + "CSqGSIb3DQEBBQUAA4GBAJOJKBubTS/kLnfXN5YbQfggxbO2c7DTxx2LhrnPiyVDEow+Xf" + "lMv4YK5olH6UUm02D8cv6Wxg4NeTtBBnwKQG/GV4Ssgc/rrpEzM7jFRQcUzPu0jfya2fX8" + "ZNBnSDjovlN6vmZHtiksjh66h3a0aVusEuOQXD29ogMR8qAGYQaZ"; public static final String Intermediate_Certificate_3_PL_01_08_crt = "MIICmTCCAgKgAwIBAgICAJ8wDQYJKoZIhvcNAQEFBQAwXjELMAkGA1UEBhMCVVMxGDAWBg" + "NVBAoTD1UuUy4gR292ZXJubWVudDEMMAoGA1UECxMDRG9kMRAwDgYDVQQLEwdUZXN0aW5n" + "MRUwEwYDVQQDEwxDQTItUEwuMDEuMDgwHhcNOTgwMTAxMTIwMTAwWhcNNDgwMTAxMTIwMT" + "AwWjBeMQswCQYDVQQGEwJVUzEYMBYGA1UEChMPVS5TLiBHb3Zlcm5tZW50MQwwCgYDVQQL" + "EwNEb2QxEDAOBgNVBAsTB1Rlc3RpbmcxFTATBgNVBAMTDENBMy1QTC4wMS4wODCBnzANBg" + "kqhkiG9w0BAQEFAAOBjQAwgYkCgYEAogLtEcWxzzkkIYe+KrwKhaQjjGQqy2KDsW00U5lx" + "+XJoT8eKd5pxFdCa0SPn/jkNILVeh07mIHec1WF8SOeveVT4Ewd3nG/6ZGoVVq6l0j+3RM" + "jpJbp26BPR69nFn6rmFUMoSNq0VG8Zl+UBqnjq83G3umJCJMMRekUTULSFEGUCAwEAAaNm" + "MGQwEgYDVR0TAQH/BAgwBgEB/wIBATAOBgNVHQ8BAf8EBAMCAQYwFgYDVR0gBA8wDTALBg" + "lghkgBZQMBMAEwEQYDVR0OBAoECGAFYeJIhrRzMBMGA1UdIwQMMAqACFjxM3RkbbhNMA0G" + "CSqGSIb3DQEBBQUAA4GBABHamiW7sPLQ83nXt3LZemcAp4QaDB8X94EuJGBwshEcKLoOHb" + "/3cZkPRbOiRQUh/YdpfyApndGFSi0DtwM2Z7yup+MzdrR0wzQoNS95A51nHE7XdCuVFemc" + "LTJ5rdd2BLK3OB5lQagVLzAY9Bs1vaeXKT2Cy+gSUkTIekWcsH3K"; public static final String Intermediate_Certificate_4_PL_01_08_crt = "MIICljCCAf+gAwIBAgICAKAwDQYJKoZIhvcNAQEFBQAwXjELMAkGA1UEBhMCVVMxGDAWBg" + "NVBAoTD1UuUy4gR292ZXJubWVudDEMMAoGA1UECxMDRG9kMRAwDgYDVQQLEwdUZXN0aW5n" + "MRUwEwYDVQQDEwxDQTMtUEwuMDEuMDgwHhcNOTgwMTAxMTIwMTAwWhcNNDgwMTAxMTIwMT" + "AwWjBeMQswCQYDVQQGEwJVUzEYMBYGA1UEChMPVS5TLiBHb3Zlcm5tZW50MQwwCgYDVQQL" + "EwNEb2QxEDAOBgNVBAsTB1Rlc3RpbmcxFTATBgNVBAMTDENBNC1QTC4wMS4wODCBnzANBg" + "kqhkiG9w0BAQEFAAOBjQAwgYkCgYEAxVjjKlLlZzeZhamPO2NDnRtWM1oWZ3/kdwdBRn50" + "o1NRXb60Ir2HjniK1dRdbijAvR5uItLe9tmj4nusBiaPUGM0HNlEdQWSzble8rvUsP0apw" + "uJusV7zLvzwwbgLbMYT+8lMhxWXM34xszP+dgjWASQOVao1Uqs/MLLibOuueUCAwEAAaNj" + "MGEwDwYDVR0TAQH/BAUwAwEB/zAOBgNVHQ8BAf8EBAMCAQYwFgYDVR0gBA8wDTALBglghk" + "gBZQMBMAEwEQYDVR0OBAoECFMFrvh2hQ18MBMGA1UdIwQMMAqACGAFYeJIhrRzMA0GCSqG" + "SIb3DQEBBQUAA4GBAFsCOJ4DzuMOKti5PvF71ZKOtcTHSv123ZNdPIbK6OatT9YhVuUOYB" + "AjMavggywrb+QOXOFfJMctQlS3y/JE9YyoNNt/4UTdx1jQ3I2ablonmzjt8eN5GJ9jUXth" + "fHjxnmGUeWlAvwMjEdzdigkyuWCi9LJfjyHtTjSf9n7w2rU+"; public static final String Intermediate_CRL_1_PL_01_08_crl = "MIIBSzCBtQIBATANBgkqhkiG9w0BAQUFADBeMQswCQYDVQQGEwJVUzEYMBYGA1UEChMPVS" + "5TLiBHb3Zlcm5tZW50MQwwCgYDVQQLEwNEb2QxEDAOBgNVBAsTB1Rlc3RpbmcxFTATBgNV" + "BAMTDENBMS1QTC4wMS4wOBcNOTkwMTAxMTIwMTAwWhcNNDgwMTAxMTIwMTAwWqAjMCEwCg" + "YDVR0UBAMCAQEwEwYDVR0jBAwwCoAI8xbdYw+1qjAwDQYJKoZIhvcNAQEFBQADgYEAG2Aq" + "R1oelnrTgh56m6Mm+Lsm0Sf+Ot1W7LzZmMDwoZgmGLcTduVktx+XrtiDDWsf58hmneT1q0" + "5wl4yNH8y/VCAA3SM/gOq4ddOEiS8GbuEYo5P/julH/U3g6M0vfPUZ5y+7V0s35jIbTkjX" + "76n3Rhf88nvTscYvMdqrYyUhAmg="; public static final String Intermediate_CRL_2_PL_01_08_crl = "MIIBSzCBtQIBATANBgkqhkiG9w0BAQUFADBeMQswCQYDVQQGEwJVUzEYMBYGA1UEChMPVS" + "5TLiBHb3Zlcm5tZW50MQwwCgYDVQQLEwNEb2QxEDAOBgNVBAsTB1Rlc3RpbmcxFTATBgNV" + "BAMTDENBMi1QTC4wMS4wOBcNOTkwMTAxMTIwMTAwWhcNNDgwMTAxMTIwMTAwWqAjMCEwCg" + "YDVR0UBAMCAQEwEwYDVR0jBAwwCoAIWPEzdGRtuE0wDQYJKoZIhvcNAQEFBQADgYEAX/+I" + "DkAx7PLTi2x6aYbLacPRaUSjMne84MDaEkYiA64Vo3eL6FbKe14z2mBsM2W7x8xDnxjZ0N" + "RbhcFZ2E6A1ct6HMunuKxjoROIsdWhrYMqJfKKMTWMviz1UjtupsGUWS0dVQCquAr6DJmr" + "W88P8wgiVH2VZsc+edDmCGDunrI="; public static final String Intermediate_CRL_3_PL_01_08_crl = "MIIBSzCBtQIBATANBgkqhkiG9w0BAQUFADBeMQswCQYDVQQGEwJVUzEYMBYGA1UEChMPVS" + "5TLiBHb3Zlcm5tZW50MQwwCgYDVQQLEwNEb2QxEDAOBgNVBAsTB1Rlc3RpbmcxFTATBgNV" + "BAMTDENBMy1QTC4wMS4wOBcNOTkwMTAxMTIwMTAwWhcNNDgwMTAxMTIwMTAwWqAjMCEwCg" + "YDVR0UBAMCAQEwEwYDVR0jBAwwCoAIYAVh4kiGtHMwDQYJKoZIhvcNAQEFBQADgYEASw1+" + "6rGDKgpUtXcCziQCjy8mHFD2zV6x/Ppxm2Gj0U+5eFnIbMPmr4TUYwfSOROUycsiJX/Wa8" + "HEuqWJhIdcsHMA7TYf0iSXK597Bljjg4F/1Rgz0wqLjgMuA59eFbKjJ6zP1E6Sv2Ck0Ea9" + "HJsv5zFA1ljVnNWoQwoHsuLk/wk="; public static final String Intermediate_CRL_4_PL_01_08_crl = "MIIBSzCBtQIBATANBgkqhkiG9w0BAQUFADBeMQswCQYDVQQGEwJVUzEYMBYGA1UEChMPVS" + "5TLiBHb3Zlcm5tZW50MQwwCgYDVQQLEwNEb2QxEDAOBgNVBAsTB1Rlc3RpbmcxFTATBgNV" + "BAMTDENBNC1QTC4wMS4wOBcNOTkwMTAxMTIwMTAwWhcNNDgwMTAxMTIwMTAwWqAjMCEwCg" + "YDVR0UBAMCAQEwEwYDVR0jBAwwCoAIUwWu+HaFDXwwDQYJKoZIhvcNAQEFBQADgYEAHHKd" + "U1SccTsK99BUDrvF930ejNRAvHQM9xv80wcUAy18x+TLwBH8vDTmP210/C5Zk9pQs+rLDd" + "doQQbWJrQkznyB1OSK0T41KZ9L0UE+YmFGJjz0PEzYHV0Kc57j5uc7Fsi8Xu20Y8JeTaJs" + "FUXVsvnCuoSxYmwY1futFWHJG7Q="; public static final String End_Certificate_PL_01_08_crt = "MIICljCCAf+gAwIBAgICAKEwDQYJKoZIhvcNAQEFBQAwXjELMAkGA1UEBhMCVVMxGDAWBg" + "NVBAoTD1UuUy4gR292ZXJubWVudDEMMAoGA1UECxMDRG9kMRAwDgYDVQQLEwdUZXN0aW5n" + "MRUwEwYDVQQDEwxDQTQtUEwuMDEuMDgwHhcNOTgwMTAxMTIwMTAwWhcNNDgwMTAxMTIwMT" + "AwWjBeMQswCQYDVQQGEwJVUzEYMBYGA1UEChMPVS5TLiBHb3Zlcm5tZW50MQwwCgYDVQQL" + "EwNEb2QxEDAOBgNVBAsTB1Rlc3RpbmcxFTATBgNVBAMTDENBNS1QTC4wMS4wODCBnzANBg" + "kqhkiG9w0BAQEFAAOBjQAwgYkCgYEAwgNkhQrcqmjhkES6DNAW3uQLKILcFlrFvOlWfDPo" + "ngXzCKeed85npqL+Enxo4sLarEiywuDLrDgPf0gKnZXQWBmzWViZhvTsiAemH7iNsNS68s" + "hhb0vnLzlPpDUJDv7KVKW8VbM7nvplKptlEE6g5kmj3iEmM4l2u8Z/pmQoTsMCAwEAAaNj" + "MGEwDwYDVR0TAQH/BAUwAwEB/zAOBgNVHQ8BAf8EBAMCAeYwFgYDVR0gBA8wDTALBglghk" + "gBZQMBMAEwEQYDVR0OBAoECLfApJ09y/ZNMBMGA1UdIwQMMAqACFMFrvh2hQ18MA0GCSqG" + "SIb3DQEBBQUAA4GBAG2ANLc/ib9ayz0B0L6/XQf/xuwETEq8kb5vWml/PbcFD1b/uwRHI8" + "vTvM559nZgtzkhS5ZAvNBTh1CB9Ox/nugHc4srbH6/Wcd94pMQx/sfCB/C6zZ5Tbm7Y4jp" + "hkjnxwGUYTvgNzxmaAPLyCfqY7KwhCSzns2M+yuncEKqlzuT"; public static final String[] TEST_61_DATA = new String[] { Intermediate_Certificate_1_PL_01_08_crt, Intermediate_Certificate_2_PL_01_08_crt, Intermediate_Certificate_3_PL_01_08_crt, Intermediate_Certificate_4_PL_01_08_crt, Intermediate_CRL_1_PL_01_08_crl, Intermediate_CRL_2_PL_01_08_crl, Intermediate_CRL_3_PL_01_08_crl, Intermediate_CRL_4_PL_01_08_crl, End_Certificate_PL_01_08_crt }; /* * test62 * */ public static final String Intermediate_Certificate_1_PL_01_09_crt = "MIICmTCCAgKgAwIBAgICAKIwDQYJKoZIhvcNAQEFBQAwXjELMAkGA1UEBhMCVVMxGDAWBg" + "NVBAoTD1UuUy4gR292ZXJubWVudDEMMAoGA1UECxMDRG9EMRAwDgYDVQQLEwdUZXN0aW5n" + "MRUwEwYDVQQDEwxUcnVzdCBBbmNob3IwHhcNOTgwMTAxMTIwMTAwWhcNNDgwMTAxMTIwMT" + "AwWjBeMQswCQYDVQQGEwJVUzEYMBYGA1UEChMPVS5TLiBHb3Zlcm5tZW50MQwwCgYDVQQL" + "EwNEb2QxEDAOBgNVBAsTB1Rlc3RpbmcxFTATBgNVBAMTDENBMS1QTC4wMS4wOTCBnzANBg" + "kqhkiG9w0BAQEFAAOBjQAwgYkCgYEA4slldx8rhfz5l2i0rwib2McrCyQkadTjJRoEGQCV" + "xT0dmw7GhDa6wJg2ozXLLk5y7ZCwlmBOTEoNbigHvcKSnJT8R/S+F4KqBz5d5dbRMNEKYz" + "jdbD7Sm7id+eyfq1s5cpmta2lBJ5gTaC9YPSOY2mucGcJ1muYzdOc6h+PCCNMCAwEAAaNm" + "MGQwEgYDVR0TAQH/BAgwBgEB/wIBBjAOBgNVHQ8BAf8EBAMCAQYwFgYDVR0gBA8wDTALBg" + "lghkgBZQMBMAEwEQYDVR0OBAoECO7tq4dJC8OgMBMGA1UdIwQMMAqACKua6/nC51SPMA0G" + "CSqGSIb3DQEBBQUAA4GBAHbth0HjAygIoWVrz59ZBPntOn5nzgUGpH60aSDOS6i9ZOKSoC" + "7wCOEt6IpKO7M7SNznxaX2uhFTYotneyq3qENvqZVXKhE6wQRsdK4kG10cxSB5AXPHJRgk" + "W9+p+Nb0iYVKwHdDCW8KHYIroGhSkKxuflwxhK6DcwQuA7y5q7r7"; public static final String Intermediate_Certificate_2_PL_01_09_crt = "MIICmTCCAgKgAwIBAgICAKMwDQYJKoZIhvcNAQEFBQAwXjELMAkGA1UEBhMCVVMxGDAWBg" + "NVBAoTD1UuUy4gR292ZXJubWVudDEMMAoGA1UECxMDRG9kMRAwDgYDVQQLEwdUZXN0aW5n" + "MRUwEwYDVQQDEwxDQTEtUEwuMDEuMDkwHhcNOTgwMTAxMTIwMTAwWhcNNDgwMTAxMTIwMT" + "AwWjBeMQswCQYDVQQGEwJVUzEYMBYGA1UEChMPVS5TLiBHb3Zlcm5tZW50MQwwCgYDVQQL" + "EwNEb2QxEDAOBgNVBAsTB1Rlc3RpbmcxFTATBgNVBAMTDENBMi1QTC4wMS4wOTCBnzANBg" + "kqhkiG9w0BAQEFAAOBjQAwgYkCgYEA70v7BFxmToZHF5M29JK6N0Ha6n729cv1U912mH9O" + "NTz9tafa+jv4W7njScv21CJbNlUO5rlAFcTlXY0U9vbqHEufhtwRQqi7+pkfa+Ig8bwl26" + "4U8L5rgmSvZJpEiiKfkmF2Rz9+zPPhHjk58ZcKoAcyhOdZ60KqmaaU/TVtEq8CAwEAAaNm" + "MGQwEgYDVR0TAQH/BAgwBgEB/wIBBDAOBgNVHQ8BAf8EBAMCAQYwFgYDVR0gBA8wDTALBg" + "lghkgBZQMBMAEwEQYDVR0OBAoECKOwR13+P/BlMBMGA1UdIwQMMAqACO7tq4dJC8OgMA0G" + "CSqGSIb3DQEBBQUAA4GBAN71oLHr0+uf6zCOC5L7oeCOGMUwvZyROu8eTztZrPYGjaamSm" + "Z0ZmUPOJP3g5nO6tHf34Tb9CTkwPdPicEaXuxflkSbJBV3mUFQ1BUDlyYTuaL8uT2N61dg" + "xt5RgYTIGsW3/2XrRvXsH91gSiEkccoUyjKnQcX3oZmEeITb6H8m"; public static final String Intermediate_Certificate_3_PL_01_09_crt = "MIICmTCCAgKgAwIBAgICAKQwDQYJKoZIhvcNAQEFBQAwXjELMAkGA1UEBhMCVVMxGDAWBg" + "NVBAoTD1UuUy4gR292ZXJubWVudDEMMAoGA1UECxMDRG9kMRAwDgYDVQQLEwdUZXN0aW5n" + "MRUwEwYDVQQDEwxDQTItUEwuMDEuMDkwHhcNOTgwMTAxMTIwMTAwWhcNNDgwMTAxMTIwMT" + "AwWjBeMQswCQYDVQQGEwJVUzEYMBYGA1UEChMPVS5TLiBHb3Zlcm5tZW50MQwwCgYDVQQL" + "EwNEb2QxEDAOBgNVBAsTB1Rlc3RpbmcxFTATBgNVBAMTDENBMy1QTC4wMS4wOTCBnzANBg" + "kqhkiG9w0BAQEFAAOBjQAwgYkCgYEAwMLmDs63ai7i4xC/1ufMFWeigJAlbKWMti/PeEKi" + "7LBfNJDRaO+1kde6QIo1vhkhKtokNu9ue3Rfo1+xGuZVohjRbHnmamEm5G3jihegPQgGCR" + "fDZoJDI9HMbwBa0RWw1Nes5igIVjdSHQKO/XTul1yyF2Dt03K2qeLwes+2FyECAwEAAaNm" + "MGQwEgYDVR0TAQH/BAgwBgEB/wIBATAOBgNVHQ8BAf8EBAMCAQYwFgYDVR0gBA8wDTALBg" + "lghkgBZQMBMAEwEQYDVR0OBAoECPEAjG80q0FoMBMGA1UdIwQMMAqACKOwR13+P/BlMA0G" + "CSqGSIb3DQEBBQUAA4GBAN9eiZXma2n0XgzdvYrlV/IEqBIhpcZ7gycjDumVBVITZJD2sJ" + "bkBi+N8dg7uovgxGxWGsyxqgAboLhMgbpbFzGh+HyIhQu/CeAx93PWYc5rP2l2Y8d7KJvk" + "p1GZEcG/nTakpjxTQ5MQYFsOHVsnDDOyaZYvqPuMrwGYsfoUa1wq"; public static final String Intermediate_Certificate_4_PL_01_09_crt = "MIICljCCAf+gAwIBAgICAKUwDQYJKoZIhvcNAQEFBQAwXjELMAkGA1UEBhMCVVMxGDAWBg" + "NVBAoTD1UuUy4gR292ZXJubWVudDEMMAoGA1UECxMDRG9kMRAwDgYDVQQLEwdUZXN0aW5n" + "MRUwEwYDVQQDEwxDQTMtUEwuMDEuMDkwHhcNOTgwMTAxMTIwMTAwWhcNNDgwMTAxMTIwMT" + "AwWjBeMQswCQYDVQQGEwJVUzEYMBYGA1UEChMPVS5TLiBHb3Zlcm5tZW50MQwwCgYDVQQL" + "EwNEb2QxEDAOBgNVBAsTB1Rlc3RpbmcxFTATBgNVBAMTDENBNC1QTC4wMS4wOTCBnzANBg" + "kqhkiG9w0BAQEFAAOBjQAwgYkCgYEAo4L9QEqzq2VXzkZI3cvUWR5v6vreKKQPfJPfEwNH" + "nMS0cgDjC4Fnw9ySI7Eb4A/OJGLIyg84mzTl6JX3kGoYr9/bJ8jOD7pN6CljXuHpwwmd7L" + "6Nf5Hy0ltjAIr5s67e33OWdPi4gApS4FN6nPSDkZotY73d1xqJYQQZWuNEsGUCAwEAAaNj" + "MGEwDwYDVR0TAQH/BAUwAwEB/zAOBgNVHQ8BAf8EBAMCAQYwFgYDVR0gBA8wDTALBglghk" + "gBZQMBMAEwEQYDVR0OBAoECLfU7BuxzXeCMBMGA1UdIwQMMAqACPEAjG80q0FoMA0GCSqG" + "SIb3DQEBBQUAA4GBABmQZOvwRpVsTD8uazfQpLJUZkuTap4OOPHie5xJsvOhGend2k+LiP" + "7btGoFrqmkyVV/+dNA8+45SRsnoOtgctiF2ubeqIvd7xf/J5C9Cmo+T89Mt7WEBEuDmEZm" + "JPXvOvyh6lRcYVSBnvVW5ZSstNAQKa/8xuyN0OrE1hJWbucn"; public static final String Intermediate_CRL_1_PL_01_09_crl = "MIIBSzCBtQIBATANBgkqhkiG9w0BAQUFADBeMQswCQYDVQQGEwJVUzEYMBYGA1UEChMPVS" + "5TLiBHb3Zlcm5tZW50MQwwCgYDVQQLEwNEb2QxEDAOBgNVBAsTB1Rlc3RpbmcxFTATBgNV" + "BAMTDENBMS1QTC4wMS4wORcNOTkwMTAxMTIwMTAwWhcNNDgwMTAxMTIwMTAwWqAjMCEwCg" + "YDVR0UBAMCAQEwEwYDVR0jBAwwCoAI7u2rh0kLw6AwDQYJKoZIhvcNAQEFBQADgYEAbXc1" + "QgR2TAvOPqJmRFFrDQkPVIVyEEDTwZy5aNnoAKK+AmJ5FZkBtbPJ8qt9UeYRh8lbX8+EIk" + "tyrAKw/1Kc3h7RDqAQ/p8t8kFwVQh2l4KTIukV8hYcj5sMKlt5f49ZwzWPyoOaLDomiUfI" + "OY/jaDMw293AjQXxGCDtnaTvh0o="; public static final String Intermediate_CRL_2_PL_01_09_crl = "MIIBSzCBtQIBATANBgkqhkiG9w0BAQUFADBeMQswCQYDVQQGEwJVUzEYMBYGA1UEChMPVS" + "5TLiBHb3Zlcm5tZW50MQwwCgYDVQQLEwNEb2QxEDAOBgNVBAsTB1Rlc3RpbmcxFTATBgNV" + "BAMTDENBMi1QTC4wMS4wORcNOTkwMTAxMTIwMTAwWhcNNDgwMTAxMTIwMTAwWqAjMCEwCg" + "YDVR0UBAMCAQEwEwYDVR0jBAwwCoAIo7BHXf4/8GUwDQYJKoZIhvcNAQEFBQADgYEAq6en" + "XtvIdh/DifGzWn11hqJIZxLQDGJZPoMmwSOLyB6OzsPrIg1xkOWZYEOELTR8+qP6emmx+D" + "CaEbUDLj60rso0gRQCBwTgHgjeMRpv8fGnV8MJgMv5BdzsGAGQbLSSY9FxtqeCPfZ6olHC" + "iUIopdZJZP8ZvGKQ6QGaMnLpJ78="; public static final String Intermediate_CRL_3_PL_01_09_crl = "MIIBSzCBtQIBATANBgkqhkiG9w0BAQUFADBeMQswCQYDVQQGEwJVUzEYMBYGA1UEChMPVS" + "5TLiBHb3Zlcm5tZW50MQwwCgYDVQQLEwNEb2QxEDAOBgNVBAsTB1Rlc3RpbmcxFTATBgNV" + "BAMTDENBMy1QTC4wMS4wORcNOTkwMTAxMTIwMTAwWhcNNDgwMTAxMTIwMTAwWqAjMCEwCg" + "YDVR0UBAMCAQEwEwYDVR0jBAwwCoAI8QCMbzSrQWgwDQYJKoZIhvcNAQEFBQADgYEAraCx" + "ruxopFbKvxOx/CIF4niG27ABB2ZwU6n4NBGYHo1Y9NjuytjjMZvQjMHyoayqpnF5TA1vXL" + "jXjI3VgQcK7A4ah/0FNLFGtczyY8kXXrpbmdg8+xdNJEG3/e5rDW5VSf7OY1XqU85ySUJQ" + "ZR5uiy8LxlDdaIT4WT7X5ezs3wk="; public static final String Intermediate_CRL_4_PL_01_09_crl = "MIIBSzCBtQIBATANBgkqhkiG9w0BAQUFADBeMQswCQYDVQQGEwJVUzEYMBYGA1UEChMPVS" + "5TLiBHb3Zlcm5tZW50MQwwCgYDVQQLEwNEb2QxEDAOBgNVBAsTB1Rlc3RpbmcxFTATBgNV" + "BAMTDENBNC1QTC4wMS4wORcNOTkwMTAxMTIwMTAwWhcNNDgwMTAxMTIwMTAwWqAjMCEwCg" + "YDVR0UBAMCAQEwEwYDVR0jBAwwCoAIt9TsG7HNd4IwDQYJKoZIhvcNAQEFBQADgYEATtjA" + "BdSZYnIbv1bCL+aSiioJg9S9yWGD1mjsA/CDzvkzSffeSpvqaSy+Zwwf+NDMMG6Cs+SgU+" + "sxQdJALAbb4sYGEyXj/Exh9BYHvgoVahH4NWuhm6LIN8RTcMDAtGoGYFNGXGuT8XRBUJZ/" + "tH9re3gpWaE1rjWeB/2ZBR5ONcM="; public static final String End_Certificate_PL_01_09_crt = "MIIChzCCAfCgAwIBAgICAKYwDQYJKoZIhvcNAQEFBQAwXjELMAkGA1UEBhMCVVMxGDAWBg" + "NVBAoTD1UuUy4gR292ZXJubWVudDEMMAoGA1UECxMDRG9kMRAwDgYDVQQLEwdUZXN0aW5n" + "MRUwEwYDVQQDEwxDQTQtUEwuMDEuMDkwHhcNOTgwMTAxMTIwMTAwWhcNNDgwMTAxMTIwMT" + "AwWjBgMQswCQYDVQQGEwJVUzEYMBYGA1UEChMPVS5TLiBHb3Zlcm5tZW50MQwwCgYDVQQL" + "EwNEb0QxEDAOBgNVBAsTB1Rlc3RpbmcxFzAVBgNVBAMTDlVzZXIxLVBMLjAxLjA5MIGfMA" + "0GCSqGSIb3DQEBAQUAA4GNADCBiQKBgQC+g1Puqjn+/Of35mqVVUricIV5x+bpZRCAgBDh" + "VYcmZFXLB/XnRd/mYTu0RR4ISEerC1km5tjGeCN2k3NGdZwz/wEh9kEL8WikSqpxUSUD/N" + "vQbliz4f3YECLcpNXKzkCvszeB5ZGHa0sLYDg3r62wy+1y2rtcrHzFEoMFgnnruwIDAQAB" + "o1IwUDAOBgNVHQ8BAf8EBAMCBeAwFgYDVR0gBA8wDTALBglghkgBZQMBMAEwEQYDVR0OBA" + "oECANGcL2klYf7MBMGA1UdIwQMMAqACLfU7BuxzXeCMA0GCSqGSIb3DQEBBQUAA4GBAHm+" + "/vQ7VxDry3VqiqKnNoOhAHTTIUphNWF4jddRqVc32IsjVaeTbcGwCIRflRm/lUplRvXXxb" + "JEbW9mP3nfTCREUdm49hjmo/szsPjgosFoEmuEKXThC81/y2vQkb4/jqRoOHEknU++38EU" + "Juv6Y6psZNa37x8Yn3i7S+b3TM2q"; public static final String[] TEST_62_DATA = new String[] { Intermediate_Certificate_1_PL_01_09_crt, Intermediate_Certificate_2_PL_01_09_crt, Intermediate_Certificate_3_PL_01_09_crt, Intermediate_Certificate_4_PL_01_09_crt, Intermediate_CRL_1_PL_01_09_crl, Intermediate_CRL_2_PL_01_09_crl, Intermediate_CRL_3_PL_01_09_crl, Intermediate_CRL_4_PL_01_09_crl, End_Certificate_PL_01_09_crt }; /* * test63 * */ public static final String Intermediate_Certificate_1_PL_01_10_crt = "MIICmTCCAgKgAwIBAgICAKcwDQYJKoZIhvcNAQEFBQAwXjELMAkGA1UEBhMCVVMxGDAWBg" + "NVBAoTD1UuUy4gR292ZXJubWVudDEMMAoGA1UECxMDRG9EMRAwDgYDVQQLEwdUZXN0aW5n" + "MRUwEwYDVQQDEwxUcnVzdCBBbmNob3IwHhcNOTgwMTAxMTIwMTAwWhcNNDgwMTAxMTIwMT" + "AwWjBeMQswCQYDVQQGEwJVUzEYMBYGA1UEChMPVS5TLiBHb3Zlcm5tZW50MQwwCgYDVQQL" + "EwNEb2QxEDAOBgNVBAsTB1Rlc3RpbmcxFTATBgNVBAMTDENBMS1QTC4wMS4xMDCBnzANBg" + "kqhkiG9w0BAQEFAAOBjQAwgYkCgYEAr4LmuvhSms70CnuAHIHwz45csKvBPVtcDjA1tWNb" + "NIvvNHBzyt6G8U4CTVKmsFAZOzrWJem3b/ZywM1WlDarGJAAa/SRIYZ/jQwaOIoPW4OUfK" + "ZQI6MO7uAPcIQ4ugtPth10viVqZYLZn/6O26Q905YsFltuPFl64KrJVJJBlLECAwEAAaNm" + "MGQwEgYDVR0TAQH/BAgwBgEB/wIBBjAOBgNVHQ8BAf8EBAMCAQYwFgYDVR0gBA8wDTALBg" + "lghkgBZQMBMAEwEQYDVR0OBAoECGRn9ckrcsEdMBMGA1UdIwQMMAqACKua6/nC51SPMA0G" + "CSqGSIb3DQEBBQUAA4GBANK+1qalm7Nl+PJHT9nQLVJ3ruQNAoMlH9fN52Q9BZCr30iWCd" + "+GhQIPRjxZ4GWojMnqbWzYQsxIR2PLdFc6SwjQrq+i2ES/LePDtaLQddS44/+GP/+qDpM9" + "Mqp3/Nbe1MfOKRBT57qgrxa8eUVieysoKeYX6yQpa8bab3qDwOTH"; public static final String Intermediate_Certificate_2_PL_01_10_crt = "MIICmTCCAgKgAwIBAgICAKgwDQYJKoZIhvcNAQEFBQAwXjELMAkGA1UEBhMCVVMxGDAWBg" + "NVBAoTD1UuUy4gR292ZXJubWVudDEMMAoGA1UECxMDRG9kMRAwDgYDVQQLEwdUZXN0aW5n" + "MRUwEwYDVQQDEwxDQTEtUEwuMDEuMTAwHhcNOTgwMTAxMTIwMTAwWhcNNDgwMTAxMTIwMT" + "AwWjBeMQswCQYDVQQGEwJVUzEYMBYGA1UEChMPVS5TLiBHb3Zlcm5tZW50MQwwCgYDVQQL" + "EwNEb2QxEDAOBgNVBAsTB1Rlc3RpbmcxFTATBgNVBAMTDENBMi1QTC4wMS4xMDCBnzANBg" + "kqhkiG9w0BAQEFAAOBjQAwgYkCgYEAx5tMLJ3LRxi9jAzCSNkj8zyrSO0cImNGf6ZCIzEU" + "V8LrmXjgiZboPTh9LWQ3msWDLpzaxVxDLBXG3eMO8ys46TfJKciyeoiB8wfuNGMKAccm8u" + "43XjWs1KAdNikWEZupYPgdmA92oRlVcHshG9PqP4+xA6sydpu3V18Nyfa0n3MCAwEAAaNm" + "MGQwEgYDVR0TAQH/BAgwBgEB/wIBBDAOBgNVHQ8BAf8EBAMCAQYwFgYDVR0gBA8wDTALBg" + "lghkgBZQMBMAEwEQYDVR0OBAoECDE3dDXkS7TxMBMGA1UdIwQMMAqACGRn9ckrcsEdMA0G" + "CSqGSIb3DQEBBQUAA4GBAE+8cyOUQ7y4atc4BlZNZvGNRZ63dbGDCM2AItTEAf4ETM9v7j" + "biUWTirJyoWsGxm2eIUk1V+EKxcuO3FotFUe7lS6thmVd6OYOSW+02RXMNklmptzK9I3AK" + "DZNh82ugLNyrrd06BSiED+0MoGVVI4gi3wdFtRiai+MgQVeWIB4i"; public static final String Intermediate_Certificate_3_PL_01_10_crt = "MIICmTCCAgKgAwIBAgICAKkwDQYJKoZIhvcNAQEFBQAwXjELMAkGA1UEBhMCVVMxGDAWBg" + "NVBAoTD1UuUy4gR292ZXJubWVudDEMMAoGA1UECxMDRG9kMRAwDgYDVQQLEwdUZXN0aW5n" + "MRUwEwYDVQQDEwxDQTItUEwuMDEuMTAwHhcNOTgwMTAxMTIwMTAwWhcNNDgwMTAxMTIwMT" + "AwWjBeMQswCQYDVQQGEwJVUzEYMBYGA1UEChMPVS5TLiBHb3Zlcm5tZW50MQwwCgYDVQQL" + "EwNEb2QxEDAOBgNVBAsTB1Rlc3RpbmcxFTATBgNVBAMTDENBMy1QTC4wMS4xMDCBnzANBg" + "kqhkiG9w0BAQEFAAOBjQAwgYkCgYEAsmSUL/UZBYMdqU0PecjCd+9U+1Ld3mKkH303Fido" + "K6k5S4ZObxVHKhYDJyp3CcVT2+nENjzIfQQQaA11UK7Uf/jmVs0IC8e2scWzq0W2BeOLef" + "jVgNgXGsXyfLi9T4KJPPyGsKlIU2R2xKxgHmAOt/tw6OYX/OaEfM1jiQza5lkCAwEAAaNm" + "MGQwEgYDVR0TAQH/BAgwBgEB/wIBATAOBgNVHQ8BAf8EBAMCAQYwFgYDVR0gBA8wDTALBg" + "lghkgBZQMBMAEwEQYDVR0OBAoECHYI07i4owpIMBMGA1UdIwQMMAqACDE3dDXkS7TxMA0G" + "CSqGSIb3DQEBBQUAA4GBAK23Kx99Y9HtFBVnHWW/NfvNro7I5Wx/ZCko6ulHm84FPAjhnL" + "tvc4jmfAZd0wYPKQKWwUKUDWNEwIU1qkxyJYACckue35GLzj8aLY/z+h037vGonFmNutMM" + "rcRdiV7gVD17dYLVTt0RgxsDVDtut+twqHgIaKtKyJnl9dSgFFv1"; public static final String Intermediate_Certificate_4_PL_01_10_crt = "MIICljCCAf+gAwIBAgICAKowDQYJKoZIhvcNAQEFBQAwXjELMAkGA1UEBhMCVVMxGDAWBg" + "NVBAoTD1UuUy4gR292ZXJubWVudDEMMAoGA1UECxMDRG9kMRAwDgYDVQQLEwdUZXN0aW5n" + "MRUwEwYDVQQDEwxDQTMtUEwuMDEuMTAwHhcNOTgwMTAxMTIwMTAwWhcNNDgwMTAxMTIwMT" + "AwWjBeMQswCQYDVQQGEwJVUzEYMBYGA1UEChMPVS5TLiBHb3Zlcm5tZW50MQwwCgYDVQQL" + "EwNEb2QxEDAOBgNVBAsTB1Rlc3RpbmcxFTATBgNVBAMTDENBNC1QTC4wMS4xMDCBnzANBg" + "kqhkiG9w0BAQEFAAOBjQAwgYkCgYEArgBnLCnqI6Sa7gXkZOvIKH4EL5i3CoG6eGG2R8aA" + "kjBs78IKGYj9gY7rRajAKSpf19zvfcW8+2gBDDj5AoCy6uDnBICmqdu+hkdokVi8dJHiTU" + "9LdS2TeuvFv47eiXoEBjMEAquCuSyHvW3lNrA+ESTnK3s7V4lBoO+o5mZD6dsCAwEAAaNj" + "MGEwDwYDVR0TAQH/BAUwAwEB/zAOBgNVHQ8BAf8EBAMCAQYwFgYDVR0gBA8wDTALBglghk" + "gBZQMBMAEwEQYDVR0OBAoECLTgYziQC9zmMBMGA1UdIwQMMAqACHYI07i4owpIMA0GCSqG" + "SIb3DQEBBQUAA4GBAEx8wgBjBglU98rocddKAEKXkt4MNzrpUMq75C9HtnuOtFgM2oY/OC" + "x67aZSTEph9ag6Hc+MyxWB5rzGD9j0y7OLsasE9AX8vjplUq50wq1xAFkGi1GnqRK/Oe7D" + "S6R66+UFHW/3KAeNe96aaJuMcx0TRbfkGbW1ASSi/ixMd9Gi"; public static final String Intermediate_CRL_1_PL_01_10_crl = "MIIBSzCBtQIBATANBgkqhkiG9w0BAQUFADBeMQswCQYDVQQGEwJVUzEYMBYGA1UEChMPVS" + "5TLiBHb3Zlcm5tZW50MQwwCgYDVQQLEwNEb2QxEDAOBgNVBAsTB1Rlc3RpbmcxFTATBgNV" + "BAMTDENBMS1QTC4wMS4xMBcNOTkwMTAxMTIwMTAwWhcNNDgwMTAxMTIwMTAwWqAjMCEwCg" + "YDVR0UBAMCAQEwEwYDVR0jBAwwCoAIZGf1yStywR0wDQYJKoZIhvcNAQEFBQADgYEAjkY5" + "nXjLst8CMz0fyEM7Ft2d9TOOJXV4TMAfSAP9QCnit8qzrdVdJ6TJIsJNZYBz9Ryr5K/iSw" + "KbYk0g6y/pskcMoHG3vJwNAxBbkf+fV7Eyve+90Z6oWDXHKLGCQQpdZ0a0wAqYeiScok8+" + "YHypEVLfbjWARR9fsci2Ps3tdvA="; public static final String Intermediate_CRL_2_PL_01_10_crl = "MIIBSzCBtQIBATANBgkqhkiG9w0BAQUFADBeMQswCQYDVQQGEwJVUzEYMBYGA1UEChMPVS" + "5TLiBHb3Zlcm5tZW50MQwwCgYDVQQLEwNEb2QxEDAOBgNVBAsTB1Rlc3RpbmcxFTATBgNV" + "BAMTDENBMi1QTC4wMS4xMBcNOTkwMTAxMTIwMTAwWhcNNDgwMTAxMTIwMTAwWqAjMCEwCg" + "YDVR0UBAMCAQEwEwYDVR0jBAwwCoAIMTd0NeRLtPEwDQYJKoZIhvcNAQEFBQADgYEAdpTU" + "xcywBjX2rD8Gu6zkDqlDmZfRXHDPtnf2RB4bHDx77kDEib6nH6DGoJdx8WnRTZsTjly3MG" + "62LfVmjp/bJyKHUQqBDrilv21EWsaI9JOr673Nk5iTZa/645GdgyLzSmxvcVDN40BAH0py" + "/2gvBQTPNzp2W1IR2mebuLdHwTI="; public static final String Intermediate_CRL_3_PL_01_10_crl = "MIIBSzCBtQIBATANBgkqhkiG9w0BAQUFADBeMQswCQYDVQQGEwJVUzEYMBYGA1UEChMPVS" + "5TLiBHb3Zlcm5tZW50MQwwCgYDVQQLEwNEb2QxEDAOBgNVBAsTB1Rlc3RpbmcxFTATBgNV" + "BAMTDENBMy1QTC4wMS4xMBcNOTkwMTAxMTIwMTAwWhcNNDgwMTAxMTIwMTAwWqAjMCEwCg" + "YDVR0UBAMCAQEwEwYDVR0jBAwwCoAIdgjTuLijCkgwDQYJKoZIhvcNAQEFBQADgYEATVf2" + "cEEGphsIe0AsqNJ5rENLe8DeDAV8R4XCKdeP5qmHmLMm9Z4pX8bIfU7bCoXiNIwGvIU6ag" + "FmHPNHEj70cQFVqCX/ZESc02hit+Os9g7pcl7s9QgwVUCMZdCiF/+pSEp3eCL5tFoKmAZe" + "nxkL0KOSuKmBzuqRtZufbhDvmbw="; public static final String Intermediate_CRL_4_PL_01_10_crl = "MIIBSzCBtQIBATANBgkqhkiG9w0BAQUFADBeMQswCQYDVQQGEwJVUzEYMBYGA1UEChMPVS" + "5TLiBHb3Zlcm5tZW50MQwwCgYDVQQLEwNEb2QxEDAOBgNVBAsTB1Rlc3RpbmcxFTATBgNV" + "BAMTDENBNC1QTC4wMS4xMBcNOTkwMTAxMTIwMTAwWhcNNDgwMTAxMTIwMTAwWqAjMCEwCg" + "YDVR0UBAMCAQEwEwYDVR0jBAwwCoAItOBjOJAL3OYwDQYJKoZIhvcNAQEFBQADgYEAbG2B" + "BhvRQ1pY/8VFeiCRFD8mBzq5iW5hWv2P7Zdp9zEbQo0fI4Kbis3OGemEttCxvAc/UPfogr" + "UudImf3s8sLV9BS59xQUGQlxZ5XBNlripY8EjHNWrwgy7/x4hzlZ9yYBbqoNOqnHLy/gbM" + "XZWoCbIK0co70lh1soOQ6eqLDKM="; public static final String End_Certificate_PL_01_10_crt = "MIICljCCAf+gAwIBAgICAKswDQYJKoZIhvcNAQEFBQAwXjELMAkGA1UEBhMCVVMxGDAWBg" + "NVBAoTD1UuUy4gR292ZXJubWVudDEMMAoGA1UECxMDRG9kMRAwDgYDVQQLEwdUZXN0aW5n" + "MRUwEwYDVQQDEwxDQTQtUEwuMDEuMTAwHhcNOTgwMTAxMTIwMTAwWhcNNDgwMTAxMTIwMT" + "AwWjBeMQswCQYDVQQGEwJVUzEYMBYGA1UEChMPVS5TLiBHb3Zlcm5tZW50MQwwCgYDVQQL" + "EwNEb2QxEDAOBgNVBAsTB1Rlc3RpbmcxFTATBgNVBAMTDENBNS1QTC4wMS4xMDCBnzANBg" + "kqhkiG9w0BAQEFAAOBjQAwgYkCgYEA3bx0qx8s4Zse6Ri6NqkLEKUPLIOhTFj/9Dh7sxvE" + "HpemBlTjbp2in08WTxEb9n8iAIWuGs3Vqm82ttBQmayjIaWD5oE/BE0oV/e91NAv/aRLsl" + "f7VtOb6vi8Ef6muOAjI2dUaUD6QONkqkJhnZ353uR3LZnsAEAW+InePGFNEGkCAwEAAaNj" + "MGEwDwYDVR0TAQH/BAUwAwEB/zAOBgNVHQ8BAf8EBAMCAeYwFgYDVR0gBA8wDTALBglghk" + "gBZQMBMAEwEQYDVR0OBAoECIokB8m8Vi4QMBMGA1UdIwQMMAqACLTgYziQC9zmMA0GCSqG" + "SIb3DQEBBQUAA4GBAKBGQwZQLQFXb+/kjP5xAtq+1rRtrblytjpv3ujJrKH1v2VB2+9boB" + "0YYYGJTy2Wuj0ZBEMeTzMO8Hol4Mq9pnYv5DCmfnZN3FuDidgnRsCjM3ZL7NcXXG9YwlKF" + "G2SXj0YfkSwN9gnyN11W8i+F/OSjlm+TDKHB3ePMcY8EnnXy"; public static final String[] TEST_63_DATA = new String[] { Intermediate_Certificate_1_PL_01_10_crt, Intermediate_Certificate_2_PL_01_10_crt, Intermediate_Certificate_3_PL_01_10_crt, Intermediate_Certificate_4_PL_01_10_crt, Intermediate_CRL_1_PL_01_10_crl, Intermediate_CRL_2_PL_01_10_crl, Intermediate_CRL_3_PL_01_10_crl, Intermediate_CRL_4_PL_01_10_crl, End_Certificate_PL_01_10_crt }; /* * test64 * */ public static final String Intermediate_Certificate_RL_02_01_crt = "MIICljCCAf+gAwIBAgICAKwwDQYJKoZIhvcNAQEFBQAwXjELMAkGA1UEBhMCVVMxGDAWBg" + "NVBAoTD1UuUy4gR292ZXJubWVudDEMMAoGA1UECxMDRG9EMRAwDgYDVQQLEwdUZXN0aW5n" + "MRUwEwYDVQQDEwxUcnVzdCBBbmNob3IwHhcNOTgwMTAxMTIwMTAwWhcNNDgwMTAxMTIwMT" + "AwWjBeMQswCQYDVQQGEwJVUzEYMBYGA1UEChMPVS5TLiBHb3Zlcm5tZW50MQwwCgYDVQQL" + "EwNEb2QxEDAOBgNVBAsTB1Rlc3RpbmcxFTATBgNVBAMTDENBMS1STC4wMi4wMTCBnzANBg" + "kqhkiG9w0BAQEFAAOBjQAwgYkCgYEA3AN+Y3Hl/9V0nKXHQotb/cA2VfZc5vrRu+ZjwKgK" + "6KasGegAorKSTybYX/fTbnaPwykDPfSscAnzAW5WdF9+wTLmvYc+6pkcx1ryKkGmofFMXi" + "bZ5LUO/oK0iuNjBKfLdWoi+hpciKyPb9Bs8SO/svKSNqTEbn9ts3q6tpbngoECAwEAAaNj" + "MGEwDwYDVR0TAQH/BAUwAwEB/zAOBgNVHQ8BAf8EBAMCAQYwFgYDVR0gBA8wDTALBglghk" + "gBZQMBMAEwEQYDVR0OBAoECGXQ07qiAqv2MBMGA1UdIwQMMAqACKua6/nC51SPMA0GCSqG" + "SIb3DQEBBQUAA4GBADKtN3OOaRdte0X4xLC6nTGaK/u7IEKQ0DjduDHwJR5w27zefrx48Z" + "dlq8t5lAfQJqWmfk7iCIW1QJPLcZOouWDP2S9Cb0YooGQRIEkMjpBn3Xufx0XUphtCDs3W" + "9LAMVXqfuce1tpZ6Dvrh6/H2X8rJMU29Czsz949bh6tcsHJi"; public static final String Intermediate_CRL_RL_02_01_crl = "MIIBSzCBtQIBATANBgkqhkiG9w0BAQUFADBeMQswCQYDVQQGEwJVUzEYMBYGA1UEChMPVS" + "5TLiBHb3Zlcm5tZW50MQwwCgYDVQQLEwNEb2QxEDAOBgNVBAsTB1Rlc3RpbmcxFTATBgNV" + "BAMTDENBMS1STC4wMi4wMRcNOTkwMTAxMTIwMTAwWhcNNDgwMTAxMTIwMTAwWqAjMCEwCg" + "YDVR0UBAMCAQEwEwYDVR0jBAwwCoAIZdDTuqICq/YwDQYJKoZIhvcNAQEFBQADgYEAxrDH" + "zKno1mkJqPTub0c9To6jC3CGTilV1E12oD0kFjkXqL40+W251qQ2wMC+G7ZrzBIc5dRuJ9" + "3feHZ7cc03/s3TziXDvSyfNOYpHzkPwT48HuSgBYgJ3uswwk+tDiA64NzbOJqssxxhFRok" + "9OpwC8eQkzgpA3a6816v2I3XL9s="; public static final String End_Certificate_RL_02_01_crt = "MIIChzCCAfCgAwIBAgICAK0wDQYJKoZIhvcNAQEFBQAwXjELMAkGA1UEBhMCVVMxGDAWBg" + "NVBAoTD1UuUy4gR292ZXJubWVudDEMMAoGA1UECxMDRG9kMRAwDgYDVQQLEwdUZXN0aW5n" + "MRUwEwYDVQQDEwxDQTEtUkwuMDIuMDEwHhcNOTgwMTAxMTIwMTAwWhcNNDgwMTAxMTIwMT" + "AwWjBgMQswCQYDVQQGEwJVUzEYMBYGA1UEChMPVS5TLiBHb3Zlcm5tZW50MQwwCgYDVQQL" + "EwNEb0QxEDAOBgNVBAsTB1Rlc3RpbmcxFzAVBgNVBAMTDlVzZXIxLVJMLjAyLjAxMIGfMA" + "0GCSqGSIb3DQEBAQUAA4GNADCBiQKBgQCykRGcIKuxia47yRmJT8XpNNi2LTTbUUTteIBp" + "DZBfz2ExeWLruO9Rn1/oB/EP+4apx4r9rQ2tGsvr/7qQYeQK8W7eJzZgvxFadY57IMfUNq" + "1nEnj0ZvuWrOSf+K9v6FWX5Y2uyZS5Uvb1VVQv0Ev890+yXTtthPTjepk3JkkouwIDAQAB" + "o1IwUDAOBgNVHQ8BAf8EBAMCBeAwFgYDVR0gBA8wDTALBglghkgBZQMBMAEwEQYDVR0OBA" + "oECFIkVrx7NRAdMBMGA1UdIwQMMAqACGXQ07qiAqv2MA0GCSqGSIb3DQEBBQUAA4GBAI+B" + "T6bFZruoeFHXsYVjkQ42jSdYB9JuQkG7JLKte5gGlhyR+jMlJBzxBgNIfvlmYSnbRFPbE8" + "eqsGm90hJJoUuVMkm0i03H13uddlS494O6HhTGpaKcYwp3hbLhVcaY3wFTqTCuZk1T7Oxq" + "ggTrCDYvNH+/ZpQuy6nB/FH3SAHS"; public static final String[] TEST_64_DATA = new String[] { Intermediate_Certificate_RL_02_01_crt, Intermediate_CRL_RL_02_01_crl, End_Certificate_RL_02_01_crt }; /* * test65 * */ public static final String Intermediate_Certificate_1_RL_03_01_crt = "MIICljCCAf+gAwIBAgICAK4wDQYJKoZIhvcNAQEFBQAwXjELMAkGA1UEBhMCVVMxGDAWBg" + "NVBAoTD1UuUy4gR292ZXJubWVudDEMMAoGA1UECxMDRG9EMRAwDgYDVQQLEwdUZXN0aW5n" + "MRUwEwYDVQQDEwxUcnVzdCBBbmNob3IwHhcNOTgwMTAxMTIwMTAwWhcNNDgwMTAxMTIwMT" + "AwWjBeMQswCQYDVQQGEwJVUzEYMBYGA1UEChMPVS5TLiBHb3Zlcm5tZW50MQwwCgYDVQQL" + "EwNEb2QxEDAOBgNVBAsTB1Rlc3RpbmcxFTATBgNVBAMTDENBMS1STC4wMy4wMTCBnzANBg" + "kqhkiG9w0BAQEFAAOBjQAwgYkCgYEAsZG8wsV3Kuo+jtnKxLYGBuAqQwUh6Cs7ioDTNUFI" + "UDDJ0lOP1HVTMBA7DEcyTCGvnQ02dEVVuCddBTQvG5RvW7G7cCEW37cS56/3yPsU1bD/cp" + "3C1pPJpoun04va91Sxtgcmx7jnz69QPVrucu6aI1sZyeOlvzb8K7DceaAfR98CAwEAAaNj" + "MGEwDwYDVR0TAQH/BAUwAwEB/zAOBgNVHQ8BAf8EBAMCAQYwFgYDVR0gBA8wDTALBglghk" + "gBZQMBMAEwEQYDVR0OBAoECMNzJ3SpyOLxMBMGA1UdIwQMMAqACKua6/nC51SPMA0GCSqG" + "SIb3DQEBBQUAA4GBABo7oKmQilgji3w1tGz1cMrWxZxqGJqOAKcHywli+oxFo2oxSfEuFS" + "tN2aEd2Ja5HU5a0ySztvByXF1TTNurGez7ARxmcS2kpoQtQXTloywza4A5N7iQwk0yyo/E" + "J4lrXUfVRwZHr7FwA7qMODtFb0+Zivv9JLaq19GhnRhzZyWp"; public static final String Intermediate_Certificate_2_RL_03_01_crt = "MIICljCCAf+gAwIBAgICAK8wDQYJKoZIhvcNAQEFBQAwXjELMAkGA1UEBhMCVVMxGDAWBg" + "NVBAoTD1UuUy4gR292ZXJubWVudDEMMAoGA1UECxMDRG9EMRAwDgYDVQQLEwdUZXN0aW5n" + "MRUwEwYDVQQDEwxUcnVzdCBBbmNob3IwHhcNOTgwMTAxMTIwMTAwWhcNNDgwMTAxMTIwMT" + "AwWjBeMQswCQYDVQQGEwJVUzEYMBYGA1UEChMPVS5TLiBHb3Zlcm5tZW50MQwwCgYDVQQL" + "EwNEb2QxEDAOBgNVBAsTB1Rlc3RpbmcxFTATBgNVBAMTDENBMi1STC4wMy4wMTCBnzANBg" + "kqhkiG9w0BAQEFAAOBjQAwgYkCgYEAt7yNq1QZsV3p7OR8rgPuY7x7Bvs+nPhcLR7zFOgR" + "+plQUwpWQ2PhuzReVV4jNasKtNK9MIWoeV+eV3pEiso5obb9+Byvha1F6gkYNZMPs9Iv86" + "cJSMtownNJVGVAL9FEpof1QKLp7kfn08EjkoGmGy85xy9uFytd2S8n5TlrBqcCAwEAAaNj" + "MGEwDwYDVR0TAQH/BAUwAwEB/zAOBgNVHQ8BAf8EBAMCAQYwFgYDVR0gBA8wDTALBglghk" + "gBZQMBMAEwEQYDVR0OBAoECAVwoCPFqMtqMBMGA1UdIwQMMAqACKua6/nC51SPMA0GCSqG" + "SIb3DQEBBQUAA4GBAL9GufFieduzBJaMtsXtKHMf64O/KAGLSh1YDXS+a7Ku+EFw+WteKU" + "Ob6+c1m7VH9P711eATQoACotCdKusPECqeYDEmT9keqA4f7cP4VcvGwhvSVQJsPuB3LL3S" + "LIILE4zhT+O9G+5v+mkG/pEDirRYk6ZkdM91bsUuzsX40uyn"; public static final String Intermediate_CRL_RL_03_01_crl = "MIIBSzCBtQIBATANBgkqhkiG9w0BAQUFADBeMQswCQYDVQQGEwJVUzEYMBYGA1UEChMPVS" + "5TLiBHb3Zlcm5tZW50MQwwCgYDVQQLEwNEb2QxEDAOBgNVBAsTB1Rlc3RpbmcxFTATBgNV" + "BAMTDENBMi1STC4wMy4wMRcNOTkwMTAxMTIwMTAwWhcNNDgwMTAxMTIwMTAwWqAjMCEwCg" + "YDVR0UBAMCAQEwEwYDVR0jBAwwCoAIBXCgI8Woy2owDQYJKoZIhvcNAQEFBQADgYEAkwyA" + "I1rrz6tOmEpBHDzuJfqY2nbXCIXFN6dVuaKNZWHJ4ZNIc4/t29Wa5GgXYrVXyXRcXP/u5k" + "NEhOX2/NwCm6vL8+tclYP5qPLrh/Dk4v3nvcTFLKCvclAbf4Il0zfMQx+RRnO5PPqPDu5i" + "1tHHwOtA8Q+oO71lZEwPE+pX1Sc="; public static final String End_Certificate_RL_03_01_crt = "MIIChzCCAfCgAwIBAgICALAwDQYJKoZIhvcNAQEFBQAwXjELMAkGA1UEBhMCVVMxGDAWBg" + "NVBAoTD1UuUy4gR292ZXJubWVudDEMMAoGA1UECxMDRG9kMRAwDgYDVQQLEwdUZXN0aW5n" + "MRUwEwYDVQQDEwxDQTEtUkwuMDMuMDEwHhcNOTgwMTAxMTIwMTAwWhcNNDgwMTAxMTIwMT" + "AwWjBgMQswCQYDVQQGEwJVUzEYMBYGA1UEChMPVS5TLiBHb3Zlcm5tZW50MQwwCgYDVQQL" + "EwNEb0QxEDAOBgNVBAsTB1Rlc3RpbmcxFzAVBgNVBAMTDlVzZXIxLVJMLjAzLjAxMIGfMA" + "0GCSqGSIb3DQEBAQUAA4GNADCBiQKBgQDPGLfi8/T5p63cbGE98mqO5VzkeI1r2/2TLgvY" + "RpL1h8i+CVYKoX37yYwNXf+HkHhj1OXJSNrm7853ctmDf2h1fv3f1+qJLg4VRVzlEgErNq" + "74OR7XLXV77kGOmhip2g5BF5VKeqAdj0pCo1E5ZFHpRPFq/0DDmSda6GKJ6Dl8hwIDAQAB" + "o1IwUDAOBgNVHQ8BAf8EBAMCBeAwFgYDVR0gBA8wDTALBglghkgBZQMBMAEwEQYDVR0OBA" + "oECOHM3uWxFmcrMBMGA1UdIwQMMAqACMNzJ3SpyOLxMA0GCSqGSIb3DQEBBQUAA4GBAFBu" + "doX0TZK/yoUcrSkP8AtFiv5c7QvyEtigFZTT+lbW/g4RX/oJGNZCu78yAxCczl+Z6ft+0V" + "wInwahjyyAgw4QXxtw3b9CfqvT7HH7hcQ6r9ZA/NA9XpzNtxKfmXjzCZWdfmLJrd8KCnU/" + "utKRAObRBKiaTGa178SEWvtkoIXd"; public static final String[] TEST_65_DATA = new String[] { Intermediate_Certificate_1_RL_03_01_crt, Intermediate_Certificate_2_RL_03_01_crt, Intermediate_CRL_RL_03_01_crl, End_Certificate_RL_03_01_crt }; /* * test66 * */ public static final String Intermediate_Certificate_RL_03_02_crt = "MIICljCCAf+gAwIBAgICALEwDQYJKoZIhvcNAQEFBQAwXjELMAkGA1UEBhMCVVMxGDAWBg" + "NVBAoTD1UuUy4gR292ZXJubWVudDEMMAoGA1UECxMDRG9EMRAwDgYDVQQLEwdUZXN0aW5n" + "MRUwEwYDVQQDEwxUcnVzdCBBbmNob3IwHhcNOTgwMTAxMTIwMTAwWhcNNDgwMTAxMTIwMT" + "AwWjBeMQswCQYDVQQGEwJVUzEYMBYGA1UEChMPVS5TLiBHb3Zlcm5tZW50MQwwCgYDVQQL" + "EwNEb2QxEDAOBgNVBAsTB1Rlc3RpbmcxFTATBgNVBAMTDENBMS1STC4wMy4wMjCBnzANBg" + "kqhkiG9w0BAQEFAAOBjQAwgYkCgYEAvoTuc2LYBOhziBe02f6F8l9MwX74O1lknBcJjGvq" + "JcirQx/6hQgBQT4hz4RRXNy7DSBr3swEw4eDNSeyd6kvG0h9oI3+SVmVyPPVi5eKDL1roI" + "OBzmfx1+Nn/CnwOf8VroKDutBBQ0gJ24IEjwp6er/8hEAVN/yIjIi/MTFeoRkCAwEAAaNj" + "MGEwDwYDVR0TAQH/BAUwAwEB/zAOBgNVHQ8BAf8EBAMCAQYwFgYDVR0gBA8wDTALBglghk" + "gBZQMBMAEwEQYDVR0OBAoECKtCUOlmMPu6MBMGA1UdIwQMMAqACKua6/nC51SPMA0GCSqG" + "SIb3DQEBBQUAA4GBAI9x8O/JgJuZV/s4OBUy3AvcW9QP3HWWBQSdxUdjSosT2schjn7wrR" + "gttL7vWjT1djsbATAHa5C3inG+VjGIq/NqWaPoHAucRNMs4oZX2ACZFuBLOb/qhywsKh5+" + "bjv4QgtqkUedzEratY6yQiJSiMSJVJSMzHosTVMX7oOp+cll"; public static final String Intermediate_CRL_RL_03_02_crl = "MIIBcDCB2gIBATANBgkqhkiG9w0BAQUFADBeMQswCQYDVQQGEwJVUzEYMBYGA1UEChMPVS" + "5TLiBHb3Zlcm5tZW50MQwwCgYDVQQLEwNEb2QxEDAOBgNVBAsTB1Rlc3RpbmcxFTATBgNV" + "BAMTDENBMS1STC4wMi4wMRcNOTkwMTAxMTIwMTAwWhcNNDgwMTAxMTIwMTAwWjAjMCECAg" + "CyFw05OTAxMDExMjAwMDBaMAwwCgYDVR0VBAMKAQGgIzAhMAoGA1UdFAQDAgEBMBMGA1Ud" + "IwQMMAqACKtCUOlmMPu6MA0GCSqGSIb3DQEBBQUAA4GBAAEZ0Hg6sKiVXIeK6zbQrKtMMz" + "Vz2K68+SqN1LAjlNW6u+HSTlAvhRIFO1Hv5Zj7qbO226rLxas/X2XWXpMlm84NHN8T4dZU" + "4Yo5rhhpCHckRxNYn3AFcfcV4ra1rrTtdx8e7e7/m0Ghog9Ny52ZuQThasL9caF0JxUx6d" + "zbBHPm"; public static final String End_Certificate_RL_03_02_crt = "MIIChzCCAfCgAwIBAgICALIwDQYJKoZIhvcNAQEFBQAwXjELMAkGA1UEBhMCVVMxGDAWBg" + "NVBAoTD1UuUy4gR292ZXJubWVudDEMMAoGA1UECxMDRG9kMRAwDgYDVQQLEwdUZXN0aW5n" + "MRUwEwYDVQQDEwxDQTEtUkwuMDMuMDIwHhcNOTgwMTAxMTIwMTAwWhcNNDgwMTAxMTIwMT" + "AwWjBgMQswCQYDVQQGEwJVUzEYMBYGA1UEChMPVS5TLiBHb3Zlcm5tZW50MQwwCgYDVQQL" + "EwNEb0QxEDAOBgNVBAsTB1Rlc3RpbmcxFzAVBgNVBAMTDlVzZXIxLVJMLjAzLjAyMIGfMA" + "0GCSqGSIb3DQEBAQUAA4GNADCBiQKBgQDNb6HGPRDulLMCCyCq6w2X8rHPtm1gN68JXFkX" + "j/BZsHhu29Z9hXj76hO//7O775EPVMSLyRy8t15yzYpXfZRHFaGB5bs8U2R5ClvsD2FR0H" + "t0JVfU6Ggn1lhO+jOiguJtXVRjofsfvHuiOe75ctaJ9lBpgwiV8tk4VRKz2e5xVwIDAQAB" + "o1IwUDAOBgNVHQ8BAf8EBAMCBeAwFgYDVR0gBA8wDTALBglghkgBZQMBMAEwEQYDVR0OBA" + "oECI3Gy0TgXMrwMBMGA1UdIwQMMAqACKtCUOlmMPu6MA0GCSqGSIb3DQEBBQUAA4GBAISQ" + "Qh9+7D6nk3FL5YQOzyZ0BSHQYjpbIVykJ+Lr4jBPKyGgCqW6jqWNg7X4waB77J2z/OkavY" + "A6qtpsk8r2wmG9thi8JyZZNhYMxAszHzFbBmSoxGRMvI0XarxgIu8Ky6V7jKVDLz12C3o9" + "H0yd+nZXilCD+p9BTjjg5bGUogJS"; public static final String[] TEST_66_DATA = new String[] { Intermediate_Certificate_RL_03_02_crt, Intermediate_CRL_RL_03_02_crl, End_Certificate_RL_03_02_crt }; /* * test67 * */ public static final String Intermediate_Certificate_RL_03_03_crt = "MIICljCCAf+gAwIBAgICALMwDQYJKoZIhvcNAQEFBQAwXjELMAkGA1UEBhMCVVMxGDAWBg" + "NVBAoTD1UuUy4gR292ZXJubWVudDEMMAoGA1UECxMDRG9EMRAwDgYDVQQLEwdUZXN0aW5n" + "MRUwEwYDVQQDEwxUcnVzdCBBbmNob3IwHhcNOTgwMTAxMTIwMTAwWhcNNDgwMTAxMTIwMT" + "AwWjBeMQswCQYDVQQGEwJVUzEYMBYGA1UEChMPVS5TLiBHb3Zlcm5tZW50MQwwCgYDVQQL" + "EwNEb2QxEDAOBgNVBAsTB1Rlc3RpbmcxFTATBgNVBAMTDENBMS1STC4wMy4wMzCBnzANBg" + "kqhkiG9w0BAQEFAAOBjQAwgYkCgYEAu/o0uxgTrAvNDrMNuG2eTla+AmkLVCIXBbsIo0gs" + "tLm29tLwfBh/8l5OC0y6Xeh5lx+NLdelsiZGRNaaWmWHj9Ji5V6rclr8sXRDUjxe12zLeh" + "0G+a0TfpL380cx9RItqQyA1ZRiUNymmJHnm13hwrf7LPirR9BMrtyTT2EI3cMCAwEAAaNj" + "MGEwDwYDVR0TAQH/BAUwAwEB/zAOBgNVHQ8BAf8EBAMCAQYwFgYDVR0gBA8wDTALBglghk" + "gBZQMBMAEwEQYDVR0OBAoECHYt39LYdEn0MBMGA1UdIwQMMAqACKua6/nC51SPMA0GCSqG" + "SIb3DQEBBQUAA4GBAIoSGa7MxnOuHoWM/BoJKsCeBmBHYCYDKmQ19JfsDHW8z8oAFiikFb" + "Gtw1Qpc0GFfJgN0cppaXfe5lDS6BWL2dPorhu3URfXKu84ATLwGmNhqLDY7zh/zPvLtG2m" + "izaMLC6ZwZL5KELpYpcP15EHPDquyP1xpV3fT17GjpG9IH8k"; public static final String Intermediate_CRL_1_RL_03_03_crl = "MIIBcDCB2gIBATANBgkqhkiG9w0BAQUFADBeMQswCQYDVQQGEwJVUzEYMBYGA1UEChMPVS" + "5TLiBHb3Zlcm5tZW50MQwwCgYDVQQLEwNEb2QxEDAOBgNVBAsTB1Rlc3RpbmcxFTATBgNV" + "BAMTDENBMS1STC4wMi4wMRcNOTkwMTAxMTIwMTAwWhcNNDgwMTAxMTIwMTAwWjAjMCECAg" + "C0Fw05OTAxMDExMjAwMDBaMAwwCgYDVR0VBAMKAQGgIzAhMAoGA1UdFAQDAgEBMBMGA1Ud" + "IwQMMAqACHYt39LYdEn0MA0GCSqGSIb3DQEBBQUAA4GBAI3HsXanos/N6uO3QVUaBZzmCt" + "w1HCHMrLVG614YlUQiEedQ/oEc7dwCeD1rUbGNVkFPIRvMkmUQo1klhKAlEUmrtW+aH+If" + "6oqumifqxvaycWidacbgNLIAMQtlQmniPF6Pq0dv8sNeKq4CE0gjRHOPJ2zIqy3kJ3tZYB" + "pTguwO"; public static final String Intermediate_CRL_2_RL_03_03_crl = "MIIBSzCBtQIBATANBgkqhkiG9w0BAQUFADBeMQswCQYDVQQGEwJVUzEYMBYGA1UEChMPVS" + "5TLiBHb3Zlcm5tZW50MQwwCgYDVQQLEwNEb2QxEDAOBgNVBAsTB1Rlc3RpbmcxFTATBgNV" + "BAMTDENBMS1STC4wMy4wMxcNOTkwMTAxMTIwMTAwWhcNNDgwMTAxMTIwMTAwWqAjMCEwCg" + "YDVR0UBAMCAQEwEwYDVR0jBAwwCoAIdi3f0th0SfQwDQYJKoZIhvcNAQEFBQADgYEAXZSZ" + "ySsD7U6ETy9ZRmiKUCJMUV9CIhCY0mEihHjW0DhFTyV1Hr01yN5zUr/IFVuP/Xcx36IX4l" + "dVv6/MgR1GeM/BUGZhm4z6YwfAosZ1N3zayIy/pP3fa1rVRl8cgCxc/8qxg9nH9p6yPpxM" + "AOOu6TLYquk/dA7wJPEW7MPixXY="; public static final String End_Certificate_RL_03_03_crt = "MIIChzCCAfCgAwIBAgICALQwDQYJKoZIhvcNAQEFBQAwXjELMAkGA1UEBhMCVVMxGDAWBg" + "NVBAoTD1UuUy4gR292ZXJubWVudDEMMAoGA1UECxMDRG9kMRAwDgYDVQQLEwdUZXN0aW5n" + "MRUwEwYDVQQDEwxDQTEtUkwuMDMuMDMwHhcNOTgwMTAxMTIwMTAwWhcNNDgwMTAxMTIwMT" + "AwWjBgMQswCQYDVQQGEwJVUzEYMBYGA1UEChMPVS5TLiBHb3Zlcm5tZW50MQwwCgYDVQQL" + "EwNEb0QxEDAOBgNVBAsTB1Rlc3RpbmcxFzAVBgNVBAMTDlVzZXIxLVJMLjAzLjAzMIGfMA" + "0GCSqGSIb3DQEBAQUAA4GNADCBiQKBgQC5LNxAB+lm514Hk2ykrFUb7fCX0ryIEMg0mgeT" + "/z8Iw7xisht57koK4PTXY863aunfNNh+8oFTHZnoLB5dbkROj1nFRgcWPezzv1wNkZEpxn" + "NINtTPBogW22NPznoZ/rSk9JRFe0sCOVazkW9tZbY2ARqyJsYU1ez5tQIkDS47kQIDAQAB" + "o1IwUDAOBgNVHQ8BAf8EBAMCBeAwFgYDVR0gBA8wDTALBglghkgBZQMBMAEwEQYDVR0OBA" + "oECMWddsi+qmxKMBMGA1UdIwQMMAqACHYt39LYdEn0MA0GCSqGSIb3DQEBBQUAA4GBAAv8" + "nrJaqEycAyIKdPBYTUqaxjkv4SmonDDJG9OqvD78/o9hUKKteoMkNUp8eexTkWk0L72L4N" + "/eXB30+m65E841V+Dy8L4bXh15n4qz4cyMt8Kvm7nbCqcgpiyBJmBxzfaXDLSthlmhcJ4X" + "zDFnav1LEw5fZklt7cnMl4YvLD8d"; public static final String[] TEST_67_DATA = new String[] { Intermediate_Certificate_RL_03_03_crt, Intermediate_CRL_1_RL_03_03_crl, Intermediate_CRL_2_RL_03_03_crl, End_Certificate_RL_03_03_crt }; /* * test68 * */ public static final String Intermediate_Certificate_1_RL_05_01_crt = "MIICljCCAf+gAwIBAgICALUwDQYJKoZIhvcNAQEFBQAwXjELMAkGA1UEBhMCVVMxGDAWBg" + "NVBAoTD1UuUy4gR292ZXJubWVudDEMMAoGA1UECxMDRG9EMRAwDgYDVQQLEwdUZXN0aW5n" + "MRUwEwYDVQQDEwxUcnVzdCBBbmNob3IwHhcNOTgwMTAxMTIwMTAwWhcNNDgwMTAxMTIwMT" + "AwWjBeMQswCQYDVQQGEwJVUzEYMBYGA1UEChMPVS5TLiBHb3Zlcm5tZW50MQwwCgYDVQQL" + "EwNEb2QxEDAOBgNVBAsTB1Rlc3RpbmcxFTATBgNVBAMTDENBMS1STC4wNS4wMTCBnzANBg" + "kqhkiG9w0BAQEFAAOBjQAwgYkCgYEA59vHTe5A9AcT237mW7HdSfh8Pu4P2wJNLT7RXczN" + "7DD/P6mAkugSgPTXwwlE1oSB/hCxAtEPhwONYZFYlRClFJidHDdVApalB7UbosTghsUzAg" + "Lqw7NL+w9i3Un2G7JM2oWwugozQn/1hzr2Cii2TIB6K0RWKoPBJvaWUURS/G8CAwEAAaNj" + "MGEwDwYDVR0TAQH/BAUwAwEB/zAOBgNVHQ8BAf8EBAMCAQYwFgYDVR0gBA8wDTALBglghk" + "gBZQMBMAEwEQYDVR0OBAoECP55Cc4eBca8MBMGA1UdIwQMMAqACKua6/nC51SPMA0GCSqG" + "SIb3DQEBBQUAA4GBALX594y5uF4Rt7CoRHeKZ5h8QiG7mc+kQDMjaSU4KJwNVVL0mJatQG" + "w90yFfhvprlgDt9UIAvpF6z5gysbrjHXJaEhVlXeg9D5mcxsL4THEc8f6oU1GjfT/SOD9l" + "QrT/keX3D9lcFEaTOgi0HIZ7aFIJgoWjXF/9kNNMEAs8sJNI"; public static final String Intermediate_Certificate_2_RL_05_01_crt = "MIICljCCAf+gAwIBAgICALYwDQYJKoZIhvcNAQEFBQAwXjELMAkGA1UEBhMCVVMxGDAWBg" + "NVBAoTD1UuUy4gR292ZXJubWVudDEMMAoGA1UECxMDRG9kMRAwDgYDVQQLEwdUZXN0aW5n" + "MRUwEwYDVQQDEwxDQTEtUkwuMDUuMDEwHhcNOTgwMTAxMTIwMTAwWhcNNDgwMTAxMTIwMT" + "AwWjBeMQswCQYDVQQGEwJVUzEYMBYGA1UEChMPVS5TLiBHb3Zlcm5tZW50MQwwCgYDVQQL" + "EwNEb2QxEDAOBgNVBAsTB1Rlc3RpbmcxFTATBgNVBAMTDENBMi1STC4wNS4wMTCBnzANBg" + "kqhkiG9w0BAQEFAAOBjQAwgYkCgYEAtl4hX6HlF0M+lSBTG8jHiB06hOy87LL81yAE2JQt" + "/6F+LZjuOBTCIc2yO2bVM3XzUnjyYDBYGnBFp/7XpRoiADuPJSfmkzmezpyJc+hm96UR1g" + "Bpo+pPKbRTWuM+FYy+vPtaDk5wKOrmyNx440PwbzxTN3JeWz17xeYE98bXMc0CAwEAAaNj" + "MGEwDwYDVR0TAQH/BAUwAwEB/zAOBgNVHQ8BAf8EBAMCAQYwFgYDVR0gBA8wDTALBglghk" + "gBZQMBMAEwEQYDVR0OBAoECJOjtwEYV9VSMBMGA1UdIwQMMAqACP55Cc4eBca8MA0GCSqG" + "SIb3DQEBBQUAA4GBAFbkOffoIjWSfxEuKszoK7Fj27Hf5jlV92xqXtBLURjNGi9jCLUIUd" + "QLnONZLJYo70Z6XaGjpAK1EtZKVWsz11JDq5egE1zNES//9Tz8xDtJ7Lcq0mwneVFxmBuL" + "gxkw4GKbBFKz10FoSP7VJWaeW080WwKnp96Me5GtZRe260N1"; public static final String Intermediate_CRL_1_RL_05_01_crl = "MIIBhTCB7wIBATANBgkqhkiG9w0BAQUFADBeMQswCQYDVQQGEwJVUzEYMBYGA1UEChMPVS" + "5TLiBHb3Zlcm5tZW50MQwwCgYDVQQLEwNEb2QxEDAOBgNVBAsTB1Rlc3RpbmcxFTATBgNV" + "BAMTDENBMS1STC4wNS4wMRcNOTkwMTAxMTIwMTAwWhcNNDgwMTAxMTIwMTAwWjA4MDYCAg" + "C2Fw05OTAxMDExMjAwMDBaMCEwCgYDVR0VBAMKAQEwEwYJYIZIAWUCAQwCAQH/BAMCAQCg" + "IzAhMAoGA1UdFAQDAgEBMBMGA1UdIwQMMAqACP55Cc4eBca8MA0GCSqGSIb3DQEBBQUAA4" + "GBAIdOaBfpAEKWLrSvepVjk3UTfEfsSP6y+kFMl33YXy18xUvVpLarGu6YjQIpXiL+ulkP" + "eF8TAc9AarUjvDf0kcslIOt3NhdMxR4/F614Ds/rPEXs4c7n4kCkvAlFg/19iIFeCaynx3" + "X0s/v1SwzgAUHi3P+OwAGDApDTyKbnmzvt"; public static final String Intermediate_CRL_2_RL_05_01_crl = "MIIBSzCBtQIBATANBgkqhkiG9w0BAQUFADBeMQswCQYDVQQGEwJVUzEYMBYGA1UEChMPVS" + "5TLiBHb3Zlcm5tZW50MQwwCgYDVQQLEwNEb2QxEDAOBgNVBAsTB1Rlc3RpbmcxFTATBgNV" + "BAMTDENBMi1STC4wNS4wMRcNOTkwMTAxMTIwMTAwWhcNNDgwMTAxMTIwMTAwWqAjMCEwCg" + "YDVR0UBAMCAQEwEwYDVR0jBAwwCoAIk6O3ARhX1VIwDQYJKoZIhvcNAQEFBQADgYEAfOOd" + "JiLUCFSurAafQEBfxE9KVrgFC+W9m64cmERicO1QL9aDVIDGJAIY1pdvWVdhLBIKwSugwB" + "ZH3ToptY+VizvFN1gkKGL2OuvDsXPHn1+QgmqvxYFPmvwDcwuxZ/3zD1VeHgEIKo9ugRnW" + "F8G2Ph6SWUxJCjJQpB7WIbydowI="; public static final String End_Certificate_RL_05_01_crt = "MIIChzCCAfCgAwIBAgICALcwDQYJKoZIhvcNAQEFBQAwXjELMAkGA1UEBhMCVVMxGDAWBg" + "NVBAoTD1UuUy4gR292ZXJubWVudDEMMAoGA1UECxMDRG9kMRAwDgYDVQQLEwdUZXN0aW5n" + "MRUwEwYDVQQDEwxDQTItUkwuMDUuMDEwHhcNOTgwMTAxMTIwMTAwWhcNNDgwMTAxMTIwMT" + "AwWjBgMQswCQYDVQQGEwJVUzEYMBYGA1UEChMPVS5TLiBHb3Zlcm5tZW50MQwwCgYDVQQL" + "EwNEb0QxEDAOBgNVBAsTB1Rlc3RpbmcxFzAVBgNVBAMTDlVzZXIxLVJMLjA1LjAxMIGfMA" + "0GCSqGSIb3DQEBAQUAA4GNADCBiQKBgQC9NWkW/mia20c5gM3DpcTsBWTNC/d/Cob+OVrS" + "lYytMjK4htO3MavavMZNTLAYFCXWhZ+Uo/uiAF0ddE4HaFI418eKJMSSbQyed0TG5Udw/t" + "3dhYeLzLEmVc0r00q5v+CLINsCNQAKaPV71UvoHrE092zZjmtacuAetBS1Q2ufpwIDAQAB" + "o1IwUDAOBgNVHQ8BAf8EBAMCBeAwFgYDVR0gBA8wDTALBglghkgBZQMBMAEwEQYDVR0OBA" + "oECGNPOXdCLpZ3MBMGA1UdIwQMMAqACJOjtwEYV9VSMA0GCSqGSIb3DQEBBQUAA4GBALTo" + "hfBEPdzZ6A9QNStakOhmhHYox70xOPuWqzSbIugZv4chKXNQGiUAoOGImTw1mcun/uPNtd" + "0bT+O+a9yX5gzW55CSmR/teHkTkND1mJhOMuYOmaCaBHnqgIIe1iEhMZQgag70+/tSmmQm" + "UpWGpxeK2c02tBK6gEmnqk75bKRT"; public static final String[] TEST_68_DATA = new String[] { Intermediate_Certificate_1_RL_05_01_crt, Intermediate_Certificate_2_RL_05_01_crt, Intermediate_CRL_1_RL_05_01_crl, Intermediate_CRL_2_RL_05_01_crl, End_Certificate_RL_05_01_crt }; /* * test69 * */ public static final String Intermediate_Certificate_RL_05_02_crt = "MIICljCCAf+gAwIBAgICALgwDQYJKoZIhvcNAQEFBQAwXjELMAkGA1UEBhMCVVMxGDAWBg" + "NVBAoTD1UuUy4gR292ZXJubWVudDEMMAoGA1UECxMDRG9EMRAwDgYDVQQLEwdUZXN0aW5n" + "MRUwEwYDVQQDEwxUcnVzdCBBbmNob3IwHhcNOTgwMTAxMTIwMTAwWhcNNDgwMTAxMTIwMT" + "AwWjBeMQswCQYDVQQGEwJVUzEYMBYGA1UEChMPVS5TLiBHb3Zlcm5tZW50MQwwCgYDVQQL" + "EwNEb2QxEDAOBgNVBAsTB1Rlc3RpbmcxFTATBgNVBAMTDENBMS1STC4wNS4wMjCBnzANBg" + "kqhkiG9w0BAQEFAAOBjQAwgYkCgYEAouNcO1wHvKHPR15L7Fohr/QbTkPWGr9QYp2MXEDy" + "BRGHt63Ob+yNvsP/C74GJA+PzvcRELSnJxmBVbdRN5y/u4S6Zt4yTTcrvp4vl//luoGLOX" + "NHhCXbrGavyoP/iKpbfP7fy948AN34i95HuZENoGPjG5stX0uk12P087S2tPcCAwEAAaNj" + "MGEwDwYDVR0TAQH/BAUwAwEB/zAOBgNVHQ8BAf8EBAMCAQYwFgYDVR0gBA8wDTALBglghk" + "gBZQMBMAEwEQYDVR0OBAoECFi86MGPmMsXMBMGA1UdIwQMMAqACKua6/nC51SPMA0GCSqG" + "SIb3DQEBBQUAA4GBAFVZVMZEsaVuL0qX5Ls94+x8gBklxPfxgfG5LeBR2/YcqW+7BhsVA1" + "GQhjBtwqCU9SOL16oTrqgw2+YeWBjaYuNYVlxfdifd0pQydpE1iDQWxmoKLzSDmtWgRYhz" + "v0TB6j8q+0x5Q0OOrHX0jdIiBnHrLmReCK8dY1x6fb6I0tTH"; public static final String Intermediate_CRL_RL_05_02_crl = "MIIBhTCB7wIBATANBgkqhkiG9w0BAQUFADBeMQswCQYDVQQGEwJVUzEYMBYGA1UEChMPVS" + "5TLiBHb3Zlcm5tZW50MQwwCgYDVQQLEwNEb2QxEDAOBgNVBAsTB1Rlc3RpbmcxFTATBgNV" + "BAMTDENBMS1STC4wNS4wMhcNOTkwMTAxMTIwMTAwWhcNNDgwMTAxMTIwMTAwWjA4MDYCAg" + "C5Fw05OTAxMDExMjAwMDBaMCEwCgYDVR0VBAMKAQEwEwYJYIZIAWUCAQwCAQH/BAMCAQCg" + "IzAhMAoGA1UdFAQDAgEBMBMGA1UdIwQMMAqACFi86MGPmMsXMA0GCSqGSIb3DQEBBQUAA4" + "GBAFMN6PWjz2bA1RRySYNXde2rKiYkZYghbtT4ig2yDJBKOiPnjdx+jriFJxGYpt7BvcNx" + "cDfijmDZ1clzprIvz0lFO6IwsQiWtLxOz4Doj6K2AD+7IxuGLceaXmubvi4e6VVC3xXGsu" + "OYsNgFzsdUXIazi74+eOcj4dqrHAepbhXT"; public static final String End_Certificate_RL_05_02_crt = "MIIChzCCAfCgAwIBAgICALkwDQYJKoZIhvcNAQEFBQAwXjELMAkGA1UEBhMCVVMxGDAWBg" + "NVBAoTD1UuUy4gR292ZXJubWVudDEMMAoGA1UECxMDRG9kMRAwDgYDVQQLEwdUZXN0aW5n" + "MRUwEwYDVQQDEwxDQTEtUkwuMDUuMDIwHhcNOTgwMTAxMTIwMTAwWhcNNDgwMTAxMTIwMT" + "AwWjBgMQswCQYDVQQGEwJVUzEYMBYGA1UEChMPVS5TLiBHb3Zlcm5tZW50MQwwCgYDVQQL" + "EwNEb0QxEDAOBgNVBAsTB1Rlc3RpbmcxFzAVBgNVBAMTDlVzZXIxLVJMLjA1LjAyMIGfMA" + "0GCSqGSIb3DQEBAQUAA4GNADCBiQKBgQCuWE1aFx3Zjk6gM0Wy6ijcUegbiGvhjBgqIGwv" + "YissT0v3KGAKoh5wGeKC+rePQNbZ91j4XDLvUNUdNw8HVNdNG/igIwsuaJ9teKSbqrAw9X" + "aD2YjJz/I6X6WXFd/eQ+g9lY3eidOXJkglYSwWMxUV62RUZbGyqjR1so+XpmYxCQIDAQAB" + "o1IwUDAOBgNVHQ8BAf8EBAMCBeAwFgYDVR0gBA8wDTALBglghkgBZQMBMAEwEQYDVR0OBA" + "oECLLbuNyVkkK9MBMGA1UdIwQMMAqACFi86MGPmMsXMA0GCSqGSIb3DQEBBQUAA4GBACKt" + "GgxIRXYHZGZgwYHjNzquM1pUJTbxxm3qYA4U6r44oAo1UzQTDpHOalflreGFvG05l1BCnQ" + "olQ8rcXU25v/CDfyww7cl8l7IxjYz7PNht7R97vjfMVqqButbn+BmU6D5kR9YXDCDPzaQ5" + "DrKNk+3tIjJNj6YhxhqC2tPG9RIN"; public static final String[] TEST_69_DATA = new String[] { Intermediate_Certificate_RL_05_02_crt, Intermediate_CRL_RL_05_02_crl, End_Certificate_RL_05_02_crt }; /* * test70 * */ public static final String Intermediate_Certificate_1_RL_06_01_crt = "MIICljCCAf+gAwIBAgICALowDQYJKoZIhvcNAQEFBQAwXjELMAkGA1UEBhMCVVMxGDAWBg" + "NVBAoTD1UuUy4gR292ZXJubWVudDEMMAoGA1UECxMDRG9EMRAwDgYDVQQLEwdUZXN0aW5n" + "MRUwEwYDVQQDEwxUcnVzdCBBbmNob3IwHhcNOTgwMTAxMTIwMTAwWhcNNDgwMTAxMTIwMT" + "AwWjBeMQswCQYDVQQGEwJVUzEYMBYGA1UEChMPVS5TLiBHb3Zlcm5tZW50MQwwCgYDVQQL" + "EwNEb2QxEDAOBgNVBAsTB1Rlc3RpbmcxFTATBgNVBAMTDENBMS1STC4wNi4wMTCBnzANBg" + "kqhkiG9w0BAQEFAAOBjQAwgYkCgYEAmhxr4ckU5C3E57odZjgcxl46ZF2QVy+K86YoLOGT" + "mq34NSHTFxP93mrNqMYdFKFedUTNI68HkecFVvVKoXsDNBnhyyCTQ3xXhBcMUXFByB+55k" + "W5LeQ8l1G2ugsyZ7Z+P8uylrpeGJt4RjOTilhcI2mnfZ7S+arFGe4KYgnsaFUCAwEAAaNj" + "MGEwDwYDVR0TAQH/BAUwAwEB/zAOBgNVHQ8BAf8EBAMCAQYwFgYDVR0gBA8wDTALBglghk" + "gBZQMBMAEwEQYDVR0OBAoECOS4X3XqhyJYMBMGA1UdIwQMMAqACKua6/nC51SPMA0GCSqG" + "SIb3DQEBBQUAA4GBALCPtNwXGxVSUNGErkBHSYCHyqlA55jKQQvZ4P0PznWEQ/gBJx34hq" + "LxiBO2G+iDomzHszeM77TXkQBpNxCUw26Jxv2HuvyBXuSprgjw5F1tvLqwsBAnD5vsb0uD" + "NrkKIzJSIBFQ1SRhuCObaXnamfPJHBmkP25t4QqEvoXMtVHB"; public static final String Intermediate_Certificate_2_RL_06_01_crt = "MIICljCCAf+gAwIBAgICALswDQYJKoZIhvcNAQEFBQAwXjELMAkGA1UEBhMCVVMxGDAWBg" + "NVBAoTD1UuUy4gR292ZXJubWVudDEMMAoGA1UECxMDRG9kMRAwDgYDVQQLEwdUZXN0aW5n" + "MRUwEwYDVQQDEwxDQTEtUkwuMDYuMDEwHhcNOTgwMTAxMTIwMTAwWhcNNDgwMTAxMTIwMT" + "AwWjBeMQswCQYDVQQGEwJVUzEYMBYGA1UEChMPVS5TLiBHb3Zlcm5tZW50MQwwCgYDVQQL" + "EwNEb2QxEDAOBgNVBAsTB1Rlc3RpbmcxFTATBgNVBAMTDENBMi1STC4wNi4wMTCBnzANBg" + "kqhkiG9w0BAQEFAAOBjQAwgYkCgYEA2IKrW6HDZJVFw3e4cC7v/jPGXAexI4B88707NhAc" + "qxSVfGTPJBdfWo5pkptZKN5/L5n6+rixLItHnei/uwBCHvhwzeEIGo1yVCgz6R2MoNB966" + "Q5CHWfT43BUjp0rZLJkK4hVKNyXB78NVv2Fly+XWBDEnzQvgVPWbGOvzE3zh0CAwEAAaNj" + "MGEwDwYDVR0TAQH/BAUwAwEB/zAOBgNVHQ8BAf8EBAMCAQYwFgYDVR0gBA8wDTALBglghk" + "gBZQMBMAEwEQYDVR0OBAoECK/1z9Xbu2jGMBMGA1UdIwQMMAqACOS4X3XqhyJYMA0GCSqG" + "SIb3DQEBBQUAA4GBAAa/MVC+8ozm9py40a4o/kHbkkmFNQr4s9yi3KXXuVxsNvquFMXm4a" + "gC8GPoNjvV+RPRmU8wOM6I2/PPl2JEQRb7NDM8LkY/m/Au4GHVeln6FKlldiRm0A+YIr19" + "ip2RHOldikAjUUYv7JT3SP34sjtq2e8bsXfWEPG5BA/wxtm7"; public static final String Intermediate_CRL_1_RL_06_01_crl = "MIIBhTCB7wIBATANBgkqhkiG9w0BAQUFADBeMQswCQYDVQQGEwJVUzEYMBYGA1UEChMPVS" + "5TLiBHb3Zlcm5tZW50MQwwCgYDVQQLEwNEb2QxEDAOBgNVBAsTB1Rlc3RpbmcxFTATBgNV" + "BAMTDENBMS1STC4wNi4wMRcNOTkwMTAxMTIwMTAwWhcNNDgwMTAxMTIwMTAwWjAjMCECAg" + "C7Fw05OTAxMDExMjAwMDBaMAwwCgYDVR0VBAMKAQGgODA2MAoGA1UdFAQDAgEBMBMGCWCG" + "SAFlAgEMAgEB/wQDAgEAMBMGA1UdIwQMMAqACOS4X3XqhyJYMA0GCSqGSIb3DQEBBQUAA4" + "GBAJSexboWDaqLVY6iiWt8ZX5GwuNwDBN1R2TgM95H7JqjMgoWML887dKk24p4eKACFMWI" + "Ji9nwsqdZ/h1FtPhYpSoJ8l8vo4imMKr+tTnMngDNpMMZPQyRY1AK1jSrLhEtUdjiEtrTY" + "rG56RNt4YyUtNxxfkEymvwJxmO/4YcAz/l"; public static final String Intermediate_CRL_2_RL_06_01_crl = "MIIBSzCBtQIBATANBgkqhkiG9w0BAQUFADBeMQswCQYDVQQGEwJVUzEYMBYGA1UEChMPVS" + "5TLiBHb3Zlcm5tZW50MQwwCgYDVQQLEwNEb2QxEDAOBgNVBAsTB1Rlc3RpbmcxFTATBgNV" + "BAMTDENBMi1STC4wNi4wMRcNOTkwMTAxMTIwMTAwWhcNNDgwMTAxMTIwMTAwWqAjMCEwCg" + "YDVR0UBAMCAQEwEwYDVR0jBAwwCoAIr/XP1du7aMYwDQYJKoZIhvcNAQEFBQADgYEAImRg" + "n9A7px9exOJL4Se9jsSHzZ3sAd3y16LdAb+HLtYLl1swNB4KPE+OebtzEoYiSzVVwezdlm" + "5WseZjfbd0q01srZI4FeACZe99iBSpKymdKxw2gRvfYZ8ZMwFpK2mQq9cmygFn53iOwP7j" + "3KE+lllielu7sYyEnkliF9wsaG0="; public static final String End_Certificate_RL_06_01_crt = "MIIChzCCAfCgAwIBAgICALwwDQYJKoZIhvcNAQEFBQAwXjELMAkGA1UEBhMCVVMxGDAWBg" + "NVBAoTD1UuUy4gR292ZXJubWVudDEMMAoGA1UECxMDRG9kMRAwDgYDVQQLEwdUZXN0aW5n" + "MRUwEwYDVQQDEwxDQTItUkwuMDYuMDEwHhcNOTgwMTAxMTIwMTAwWhcNNDgwMTAxMTIwMT" + "AwWjBgMQswCQYDVQQGEwJVUzEYMBYGA1UEChMPVS5TLiBHb3Zlcm5tZW50MQwwCgYDVQQL" + "EwNEb0QxEDAOBgNVBAsTB1Rlc3RpbmcxFzAVBgNVBAMTDlVzZXIxLVJMLjA2LjAxMIGfMA" + "0GCSqGSIb3DQEBAQUAA4GNADCBiQKBgQDZVBNzD7LZW6mC2GSbVPjpcJ7sWISYsL2eHqXb" + "/PuxtbOneOjYqx0GeL9pxDGSSNl2NrlG0G1HTU2MaEOVA6h96W9e5ADV/pzGPMr97z+3BV" + "unxLX+ciM3T7rUQm/LueQTEC2Ww19T6QOg2i8rEadYT0OoW6OcvyuomemspxgClQIDAQAB" + "o1IwUDAOBgNVHQ8BAf8EBAMCBeAwFgYDVR0gBA8wDTALBglghkgBZQMBMAEwEQYDVR0OBA" + "oECK5pHDrhL7xjMBMGA1UdIwQMMAqACK/1z9Xbu2jGMA0GCSqGSIb3DQEBBQUAA4GBAF3J" + "Kskjs4jp+BBoei9YWYtmOupn9w3oGyhknNh2jz7api5Gtgk2SyKfYFvN6EhWZJEab0hPFe" + "WuYwO7zNCLGHw0cFXT/R48ogd6JkH6xDwj4afZDkWVTu8oaVD4h1rTYS6WPRzizAozOzhi" + "tmIo+MV/lCG8+jdVtFgeKycI8aX7"; public static final String[] TEST_70_DATA = new String[] { Intermediate_Certificate_1_RL_06_01_crt, Intermediate_Certificate_2_RL_06_01_crt, Intermediate_CRL_1_RL_06_01_crl, Intermediate_CRL_2_RL_06_01_crl, End_Certificate_RL_06_01_crt }; /* * test71 * */ public static final String Intermediate_Certificate_RL_06_02_crt = "MIICljCCAf+gAwIBAgICAL0wDQYJKoZIhvcNAQEFBQAwXjELMAkGA1UEBhMCVVMxGDAWBg" + "NVBAoTD1UuUy4gR292ZXJubWVudDEMMAoGA1UECxMDRG9EMRAwDgYDVQQLEwdUZXN0aW5n" + "MRUwEwYDVQQDEwxUcnVzdCBBbmNob3IwHhcNOTgwMTAxMTIwMTAwWhcNNDgwMTAxMTIwMT" + "AwWjBeMQswCQYDVQQGEwJVUzEYMBYGA1UEChMPVS5TLiBHb3Zlcm5tZW50MQwwCgYDVQQL" + "EwNEb2QxEDAOBgNVBAsTB1Rlc3RpbmcxFTATBgNVBAMTDENBMS1STC4wNi4wMjCBnzANBg" + "kqhkiG9w0BAQEFAAOBjQAwgYkCgYEAxMlJ0vbkMRGzuEDTDGuPmwDzU1xn3dFDZ1Tx6ONP" + "fwNN5gk6r9kYl5TZ8f5TbkQSnOzyhDSqX8dGumCSgukETXtYBU2+KiIAtliu5NJRbXe3La" + "vn102HxaHDLGsR0FFLiFM9GVhOOXryJoXoGZqUwvqbWyaQQEzrV4RWmuOv7xMCAwEAAaNj" + "MGEwDwYDVR0TAQH/BAUwAwEB/zAOBgNVHQ8BAf8EBAMCAQYwFgYDVR0gBA8wDTALBglghk" + "gBZQMBMAEwEQYDVR0OBAoECFNaMo88Vb5MMBMGA1UdIwQMMAqACKua6/nC51SPMA0GCSqG" + "SIb3DQEBBQUAA4GBAJsjJG4/U1OWCJPB1u7UD3TPKRgOR9hT5l3LzFw5s0CEGt2Beg25LP" + "GEGcr0sEdosVQI5m5CuPolpmlQv0FkZv5M1W+uXX+F/6edtMDEquDpdR97ihQSLZjFFqjE" + "ytuaD4gqtL/BKBbz3e93mOmR9Wi+kWlXOYl0j8wpU9ePSjDV"; public static final String Intermediate_CRL_RL_06_02_crl = "MIIBhTCB7wIBATANBgkqhkiG9w0BAQUFADBeMQswCQYDVQQGEwJVUzEYMBYGA1UEChMPVS" + "5TLiBHb3Zlcm5tZW50MQwwCgYDVQQLEwNEb2QxEDAOBgNVBAsTB1Rlc3RpbmcxFTATBgNV" + "BAMTDENBMS1STC4wNi4wMhcNOTkwMTAxMTIwMTAwWhcNNDgwMTAxMTIwMTAwWjAjMCECAg" + "C+Fw05OTAxMDExMjAwMDBaMAwwCgYDVR0VBAMKAQGgODA2MAoGA1UdFAQDAgEBMBMGCWCG" + "SAFlAgEMAgEB/wQDAgEAMBMGA1UdIwQMMAqACFNaMo88Vb5MMA0GCSqGSIb3DQEBBQUAA4" + "GBAAKNj5xmtE7wzO1p5igiAmCDV6KuYsiPAQPHPEBlmo85vzvWv2hpEtmk4nDhehogl0QX" + "rhvRRqR+cPE5vBLB8mAStW+ZR6FXQPnmU5qGHqCQ4Wh6TWZesd7oyftoS7bJD5Xdf5ErA9" + "qijWoz8FgxZHVnAFmjA0rUINkdQ5JfE5oj"; public static final String End_Certificate_RL_06_02_crt = "MIIChzCCAfCgAwIBAgICAL4wDQYJKoZIhvcNAQEFBQAwXjELMAkGA1UEBhMCVVMxGDAWBg" + "NVBAoTD1UuUy4gR292ZXJubWVudDEMMAoGA1UECxMDRG9kMRAwDgYDVQQLEwdUZXN0aW5n" + "MRUwEwYDVQQDEwxDQTEtUkwuMDYuMDIwHhcNOTgwMTAxMTIwMTAwWhcNNDgwMTAxMTIwMT" + "AwWjBgMQswCQYDVQQGEwJVUzEYMBYGA1UEChMPVS5TLiBHb3Zlcm5tZW50MQwwCgYDVQQL" + "EwNEb0QxEDAOBgNVBAsTB1Rlc3RpbmcxFzAVBgNVBAMTDlVzZXIxLVJMLjA2LjAyMIGfMA" + "0GCSqGSIb3DQEBAQUAA4GNADCBiQKBgQD3UzwrnwKRlP00Pn49iI35S0wLn7c1I3rsmzdm" + "YFicetxHNeOKXLg1CN1bqkbAJ+N39fKjrkusqb2T+R3zhAV5LeLT4fzbHYdU7f4r6xgW2/" + "b2WLv+QVR+ldTsVxgPp/ZUgYi4/vAow4Q/6IT+zWtlawMBob/nLjVl+jQ9N4coFwIDAQAB" + "o1IwUDAOBgNVHQ8BAf8EBAMCBeAwFgYDVR0gBA8wDTALBglghkgBZQMBMAEwEQYDVR0OBA" + "oECPhq75noL+9WMBMGA1UdIwQMMAqACFNaMo88Vb5MMA0GCSqGSIb3DQEBBQUAA4GBAIU2" + "5bLX/NyDC8dKUxRwVn8oc3YPQjK0zXGdUr15Ib+cLdRyFVCuAyxVdpTf/csuga6tDhGuTL" + "B18mTE/fAjhUOiKiOLD6m4P77Nj67l2NTi86RimsI/Z6r5+bU31ahrls/7kr788+f4oEIY" + "TyOJecojsJUOG3qzK9J50iszclxg"; public static final String[] TEST_71_DATA = new String[] { Intermediate_Certificate_RL_06_02_crt, Intermediate_CRL_RL_06_02_crl, End_Certificate_RL_06_02_crt }; /* * test72 * */ public static final String Intermediate_Certificate_RL_07_01_crt = "MIICljCCAf+gAwIBAgICAL8wDQYJKoZIhvcNAQEFBQAwXjELMAkGA1UEBhMCVVMxGDAWBg" + "NVBAoTD1UuUy4gR292ZXJubWVudDEMMAoGA1UECxMDRG9EMRAwDgYDVQQLEwdUZXN0aW5n" + "MRUwEwYDVQQDEwxUcnVzdCBBbmNob3IwHhcNOTgwMTAxMTIwMTAwWhcNNDgwMTAxMTIwMT" + "AwWjBeMQswCQYDVQQGEwJVUzEYMBYGA1UEChMPVS5TLiBHb3Zlcm5tZW50MQwwCgYDVQQL" + "EwNEb2QxEDAOBgNVBAsTB1Rlc3RpbmcxFTATBgNVBAMTDENBMS1STC4wNy4wMTCBnzANBg" + "kqhkiG9w0BAQEFAAOBjQAwgYkCgYEAxjHxSRwJjEkLG9Al5uSQ22QI8N/hJ8hhkhh9qlaJ" + "mHusM8sWpAp2vnuumlThTA2zZbptXZ8Krb7i/Kpym4wo3ZkEThwi/ijsM5QCunQJmESRGD" + "yPZJjfhWjoC+lCjbmzsOGLMETpgSEMy+EyoXkRCnKmXcmCMS8HjLrqdnwiWBUCAwEAAaNj" + "MGEwDwYDVR0TAQH/BAUwAwEB/zAOBgNVHQ8BAf8EBAMCAQYwFgYDVR0gBA8wDTALBglghk" + "gBZQMBMAEwEQYDVR0OBAoECHPEkeIs8GuwMBMGA1UdIwQMMAqACKua6/nC51SPMA0GCSqG" + "SIb3DQEBBQUAA4GBABCmgEnb8dfnG9lWQKT5BmQm459WqRQAiqdfqf9w0qRMuVrdfLMwqx" + "oq4uh10A3d+auHohgT2fT9RzNaWnRoNaH9K6qLQsdCUZdqjbEGdyiIFzvWP9MkV9nhDlo2" + "GgiU68HfnpKO/WA9EaRHyEzwT9o4SA7hAbz+3L12hB2WLSOg"; public static final String Intermediate_CRL_RL_07_01_crl = "MIIBSzCBtQIBATANBgkqhkiG9w0BAQUFADBeMQswCQYDVQQGEwJVUzEYMBYGA1UEChMPVS" + "5TLiBHb3Zlcm5tZW50MQwwCgYDVQQLEwNEb2QxEDAOBgNVBAsTB1Rlc3RpbmcxFTATBgNV" + "BAMTDENBMS1STC4wNy4wMRcNOTgwMTAxMDYwMTAwWhcNOTgwMTAxMTIwMTAwWqAjMCEwCg" + "YDVR0UBAMCAQEwEwYDVR0jBAwwCoAIc8SR4izwa7AwDQYJKoZIhvcNAQEFBQADgYEAOyZr" + "f1tRnuzoq7dgQo+eOYhb5JyRyrNaSwNnRy82wOP+/G3NH8V3NGonDFOOcd9SoLTbeW4o71" + "vdOrKZgom5H2MZK5M4wTdfPAfXB1wBxOMzW5jXzsRtaha4l6EPI+GVL0eXN+aW3k/pscdA" + "ToI+OxTmRRnCYS6yW3qL9RoTIXQ="; public static final String End_Certificate_RL_07_01_crt = "MIIChzCCAfCgAwIBAgICAMAwDQYJKoZIhvcNAQEFBQAwXjELMAkGA1UEBhMCVVMxGDAWBg" + "NVBAoTD1UuUy4gR292ZXJubWVudDEMMAoGA1UECxMDRG9kMRAwDgYDVQQLEwdUZXN0aW5n" + "MRUwEwYDVQQDEwxDQTEtUkwuMDcuMDEwHhcNOTgwMTAxMTIwMTAwWhcNNDgwMTAxMTIwMT" + "AwWjBgMQswCQYDVQQGEwJVUzEYMBYGA1UEChMPVS5TLiBHb3Zlcm5tZW50MQwwCgYDVQQL" + "EwNEb0QxEDAOBgNVBAsTB1Rlc3RpbmcxFzAVBgNVBAMTDlVzZXIxLVJMLjA3LjAxMIGfMA" + "0GCSqGSIb3DQEBAQUAA4GNADCBiQKBgQCrm/Zem9Tt2UJFUKdAhTNwvhLo03uOax74ZgbV" + "YNTCpKeEWkV5d5d7DRC4mCTX1yjIlg6K4l7T+sRGI4XAcDRgYLuoyG1X958XCXSdIPTdbK" + "Hxs/tFv4mrCwi1kU+zjyzDoqgjT6kUxgM39rfcvDMH6qSzHQKgTFp7Tj/DHiELqwIDAQAB" + "o1IwUDAOBgNVHQ8BAf8EBAMCBeAwFgYDVR0gBA8wDTALBglghkgBZQMBMAEwEQYDVR0OBA" + "oECGFR8c6rRbhcMBMGA1UdIwQMMAqACHPEkeIs8GuwMA0GCSqGSIb3DQEBBQUAA4GBAANZ" + "TVR288mKpDDzm9XZMZ9+K1kPZ+eQYX+vUul11luVw27AIJGR8Fb4PIGl4+ALvqU3NQP/6v" + "d+zvS7IfiR6q7aLS3w111BUCgDhTJAp3oSo12qfcp+2DB1M9QfjrM9nKgmh5bBJigdJwJM" + "W8HHKStUMLdxg+qkZJgZpnyowCFM"; public static final String[] TEST_72_DATA = new String[] { Intermediate_Certificate_RL_07_01_crt, Intermediate_CRL_RL_07_01_crl, End_Certificate_RL_07_01_crt }; /* * test73 * */ public static final String Intermediate_Certificate_RL_07_02_crt = "MIICljCCAf+gAwIBAgICAMEwDQYJKoZIhvcNAQEFBQAwXjELMAkGA1UEBhMCVVMxGDAWBg" + "NVBAoTD1UuUy4gR292ZXJubWVudDEMMAoGA1UECxMDRG9EMRAwDgYDVQQLEwdUZXN0aW5n" + "MRUwEwYDVQQDEwxUcnVzdCBBbmNob3IwHhcNNTAwMTAxMDYwMDMwWhcNNDgwMTAxMTIwMT" + "AwWjBeMQswCQYDVQQGEwJVUzEYMBYGA1UEChMPVS5TLiBHb3Zlcm5tZW50MQwwCgYDVQQL" + "EwNEb2QxEDAOBgNVBAsTB1Rlc3RpbmcxFTATBgNVBAMTDENBMS1STC4wNy4wMjCBnzANBg" + "kqhkiG9w0BAQEFAAOBjQAwgYkCgYEA0CvEneaAPtxZOTqlh/TXBM6V0bQgKbO58yEyURcO" + "Zi7jzYsmNtN9Tsr0wAlD41/ZONsW4MMzZ13UCc0aGa+eE8XRULBe5cgaGxJKwVnEqz3W8z" + "v1MjOk7Anb8TkxMSlWlptC6V3eRA85p5Id9gXbIrP3E3NuSfyx6246oLjNnbECAwEAAaNj" + "MGEwDwYDVR0TAQH/BAUwAwEB/zAOBgNVHQ8BAf8EBAMCAQYwFgYDVR0gBA8wDTALBglghk" + "gBZQMBMAEwEQYDVR0OBAoECIb5Ia6wKcHtMBMGA1UdIwQMMAqACKua6/nC51SPMA0GCSqG" + "SIb3DQEBBQUAA4GBAAYEHQY+Z4qv4bYLmd+sz4aNGwZF7FT6ZIQ43OSeb+t+ibL7rZ0X0y" + "4SCTMs1mAB44IA6RFurmeCFk0ladRCn3A1xaVI1HlHen13ovzDA9ogL4CWbYXvCUv/znQY" + "yVSQCTKwT8iVam8xS1MsNCe408iVjhRfR6u9Hi31M+Pf+AUe"; public static final String Intermediate_CRL_RL_07_02_crl = "MIIBSzCBtQIBATANBgkqhkiG9w0BAQUFADBeMQswCQYDVQQGEwJVUzEYMBYGA1UEChMPVS" + "5TLiBHb3Zlcm5tZW50MQwwCgYDVQQLEwNEb2QxEDAOBgNVBAsTB1Rlc3RpbmcxFTATBgNV" + "BAMTDENBMS1STC4wNy4wMhcNNTAwMTAxMDYwMTAwWhcNNTAwMTAxMTIwMTAwWqAjMCEwCg" + "YDVR0UBAMCAQEwEwYDVR0jBAwwCoAIhvkhrrApwe0wDQYJKoZIhvcNAQEFBQADgYEALVUq" + "3Wq/Opvp9ifmQ4VXz4dgLNR+5Nz3muJ4RZt5R5b4R3RYllhgXNYw2EbEVCFjnfm97z73Ke" + "wzVV+fo/u5GbqJHN2cAVEHarOpasLxySktNA1Cwq5OTzUF0dYISqYbyBvVcaOQBvU/Lwj7" + "MQJJVVq96iDKnAJYBX03EHKbBeg="; public static final String End_Certificate_RL_07_02_crt = "MIIChzCCAfCgAwIBAgICAMIwDQYJKoZIhvcNAQEFBQAwXjELMAkGA1UEBhMCVVMxGDAWBg" + "NVBAoTD1UuUy4gR292ZXJubWVudDEMMAoGA1UECxMDRG9kMRAwDgYDVQQLEwdUZXN0aW5n" + "MRUwEwYDVQQDEwxDQTEtUkwuMDcuMDIwHhcNOTgwMTAxMTIwMTAwWhcNNDgwMTAxMTIwMT" + "AwWjBgMQswCQYDVQQGEwJVUzEYMBYGA1UEChMPVS5TLiBHb3Zlcm5tZW50MQwwCgYDVQQL" + "EwNEb0QxEDAOBgNVBAsTB1Rlc3RpbmcxFzAVBgNVBAMTDlVzZXIxLVJMLjA3LjAyMIGfMA" + "0GCSqGSIb3DQEBAQUAA4GNADCBiQKBgQD6YgsbjW9IL7/SBORKssFUZBUxmluOpxJK/7d7" + "JA2pxbg7L96xHFPWN36CYDJzTscNpbGrD3G2MPkg4GqoTo0rU28NYVzj4SwqYoSLIbXB+r" + "SVgWcxNgbJ+4x9bK3YccNLR1PWEFxz1NckhCLBmb5pI4E34MCxQ6PvFO02I19FwQIDAQAB" + "o1IwUDAOBgNVHQ8BAf8EBAMCBeAwFgYDVR0gBA8wDTALBglghkgBZQMBMAEwEQYDVR0OBA" + "oECIutV9ItCIbZMBMGA1UdIwQMMAqACIb5Ia6wKcHtMA0GCSqGSIb3DQEBBQUAA4GBALQE" + "cBr31h3jKUHcuf3yztr9NWUkGMDM0NCXHOpQl7JbV3P5BjvaiRYWlUrN7+92G8EaUFORto" + "zp8GG+d/MvFooVQOvpOzyhautYWyqq3AWpZLppnxNk1mRAdjUAvJaONtv37eLsma0bhtLM" + "j62sQQ6CdoKbMtIEGuJgpwWqHYwY"; public static final String[] TEST_73_DATA = new String[] { Intermediate_Certificate_RL_07_02_crt, Intermediate_CRL_RL_07_02_crl, End_Certificate_RL_07_02_crt }; /* * test74 * */ public static final String Intermediate_Certificate_RL_07_03_crt = "MIICljCCAf+gAwIBAgICAMMwDQYJKoZIhvcNAQEFBQAwXjELMAkGA1UEBhMCVVMxGDAWBg" + "NVBAoTD1UuUy4gR292ZXJubWVudDEMMAoGA1UECxMDRG9EMRAwDgYDVQQLEwdUZXN0aW5n" + "MRUwEwYDVQQDEwxUcnVzdCBBbmNob3IwHhcNOTgwMTAxMTIwMTAwWhcNNDgwMTAxMTIwMT" + "AwWjBeMQswCQYDVQQGEwJVUzEYMBYGA1UEChMPVS5TLiBHb3Zlcm5tZW50MQwwCgYDVQQL" + "EwNEb2QxEDAOBgNVBAsTB1Rlc3RpbmcxFTATBgNVBAMTDENBMS1STC4wNy4wMzCBnzANBg" + "kqhkiG9w0BAQEFAAOBjQAwgYkCgYEA8QzGjV0NVTNrOgkeqTkQFCOvl7M0qmjmYJjuw4R3" + "YfQIXDN0m9HR2JKp5WKTSUedmWviGS7NbGSzLR7+6OkLwSoxN9PkA/fMko7O0KWBfduhvn" + "jymlDMb2GPb1hBjScbq8fVJHwzqUm+BtEO2MXwXKYY2hZr+OEyEGhSEThp90MCAwEAAaNj" + "MGEwDwYDVR0TAQH/BAUwAwEB/zAOBgNVHQ8BAf8EBAMCAQYwFgYDVR0gBA8wDTALBglghk" + "gBZQMBMAEwEQYDVR0OBAoECFwl2XphEZRSMBMGA1UdIwQMMAqACKua6/nC51SPMA0GCSqG" + "SIb3DQEBBQUAA4GBAAb5GERgYVGuOb62gVZAAnhuk5K7CCkWZucOv6iI7pAgI6S7pvool/" + "dXHC0tzgQ+/MkuWcr+22k/ya7f+iSfiYokjnQkgoYFYk3PkjyOXA3mzs5qhF0nOP6Gvmz4" + "asONA+qZSqa4pjxF9Kn8L64f9yeyEXnckmbzdmbjAFCveQIP"; public static final String Intermediate_CRL_RL_07_03_crl = "MIIBTTCBtwIBATANBgkqhkiG9w0BAQUFADBeMQswCQYDVQQGEwJVUzEYMBYGA1UEChMPVS" + "5TLiBHb3Zlcm5tZW50MQwwCgYDVQQLEwNEb2QxEDAOBgNVBAsTB1Rlc3RpbmcxFTATBgNV" + "BAMTDENBMS1STC4wNy4wMxcNOTkwMTAxMDYwMTAwWhgPMjA1MDAxMDExMjAxMDBaoCMwIT" + "AKBgNVHRQEAwIBATATBgNVHSMEDDAKgAhcJdl6YRGUUjANBgkqhkiG9w0BAQUFAAOBgQAz" + "DMl8P16hylNkUEw4z9//PJFObNPZCYdmzBfp0K3tNRrOAouUVegyX0gDHi8O+bmmJNgcnC" + "tMRXx+D4qP7bx5fDS2MVQhSsncf6u4UZ8pxbRc0JmwR5oGZLPQabrctgmEmg8ZKGApKtsf" + "pGyvvTwaAzM+GaWXD68bBEN3VfVdeQ=="; public static final String End_Certificate_RL_07_03_crt = "MIIChzCCAfCgAwIBAgICAMQwDQYJKoZIhvcNAQEFBQAwXjELMAkGA1UEBhMCVVMxGDAWBg" + "NVBAoTD1UuUy4gR292ZXJubWVudDEMMAoGA1UECxMDRG9kMRAwDgYDVQQLEwdUZXN0aW5n" + "MRUwEwYDVQQDEwxDQTEtUkwuMDcuMDMwHhcNOTgwMTAxMTIwMTAwWhcNNDgwMTAxMTIwMT" + "AwWjBgMQswCQYDVQQGEwJVUzEYMBYGA1UEChMPVS5TLiBHb3Zlcm5tZW50MQwwCgYDVQQL" + "EwNEb0QxEDAOBgNVBAsTB1Rlc3RpbmcxFzAVBgNVBAMTDlVzZXIxLVJMLjA3LjAzMIGfMA" + "0GCSqGSIb3DQEBAQUAA4GNADCBiQKBgQDU6mec24uBaVip7fFWHas+o/lpZBOfj/IPHXQ9" + "QaRZwmJZBB81AX3BJ60DD12o/+RXdHl7B2Eh9kYv/QEXOKmyhJFSPa0Lv7MQ/hCIcL4m1U" + "FDGtJ3SUixZMqVBP0xjwXoNS88zzaCBL+co2TxhBrYMzeNQOX1eEkXMT4pvULmAwIDAQAB" + "o1IwUDAOBgNVHQ8BAf8EBAMCBeAwFgYDVR0gBA8wDTALBglghkgBZQMBMAEwEQYDVR0OBA" + "oECBBgFdYLuvk9MBMGA1UdIwQMMAqACFwl2XphEZRSMA0GCSqGSIb3DQEBBQUAA4GBAAof" + "dPOGa4ZxRPcLw6zWM/NLzF3XYDqXAsZBsC75r0GRrogqEYn07tVUDNaQczDtjRLBRNmxWE" + "+qCkJwc+wOBJqOFUxcuhK9oag6OE94+UIHdh3Td9i2ELZXj9RSNchnjyFohj5gk1dJSO41" + "86Ls3mCT9JcssR0dSxxkF0ENfZCG"; public static final String[] TEST_74_DATA = new String[] { Intermediate_Certificate_RL_07_03_crt, Intermediate_CRL_RL_07_03_crl, End_Certificate_RL_07_03_crt }; /* * test75 * */ public static final String Intermediate_Certificate_RL_08_01_crt = "MIICljCCAf+gAwIBAgICAMUwDQYJKoZIhvcNAQEFBQAwXjELMAkGA1UEBhMCVVMxGDAWBg" + "NVBAoTD1UuUy4gR292ZXJubWVudDEMMAoGA1UECxMDRG9EMRAwDgYDVQQLEwdUZXN0aW5n" + "MRUwEwYDVQQDEwxUcnVzdCBBbmNob3IwHhcNOTgwMTAxMTIwMTAwWhcNNDgwMTAxMTIwMT" + "AwWjBeMQswCQYDVQQGEwJVUzEYMBYGA1UEChMPVS5TLiBHb3Zlcm5tZW50MQwwCgYDVQQL" + "EwNEb2QxEDAOBgNVBAsTB1Rlc3RpbmcxFTATBgNVBAMTDENBMS1STC4wOC4wMTCBnzANBg" + "kqhkiG9w0BAQEFAAOBjQAwgYkCgYEAs2YRTEl3C1TmmneJ6K110nSACn+KXxSOTGAGN5xv" + "XW751StpE2iEQIbRVPQdMzmcQX0bcg/WpdrewPQld9NRjFj7it+9YNQh7vMKhZwoAPoDmv" + "TnTdTEuV0c1FLVDVhiaAD9KMBa4fBLRfTKVzgzAr+oNqLhm3YBd2JWRHg+fA8CAwEAAaNj" + "MGEwDwYDVR0TAQH/BAUwAwEB/zAOBgNVHQ8BAf8EBAMCAQYwFgYDVR0gBA8wDTALBglghk" + "gBZQMBMAEwEQYDVR0OBAoECB4we8+hIrkKMBMGA1UdIwQMMAqACKua6/nC51SPMA0GCSqG" + "SIb3DQEBBQUAA4GBABTQI82uCMwQ4bgUWr9lawSI5DyWg3KY13F45rAlmKyckgne9SHbCH" + "+Lvm3XkkIqKmeHfJ3QTf7bpz6eErn3CxRrGm5JWblcYbVT+smjboJ9A0BXifqINYLy3qGc" + "AnNRkPq8OUREj2sU1qWKagUIgA/Vk2WyZhcUiApJPHI4fwv9"; public static final String Intermediate_CRL_RL_08_01_crl = "MIIBWjCBxAIBATANBgkqhkiG9w0BAQUFADBeMQswCQYDVQQGEwJVUzEYMBYGA1UEChMPVS" + "5TLiBHb3Zlcm5tZW50MQwwCgYDVQQLEwNEb2QxEDAOBgNVBAsTB1Rlc3RpbmcxFTATBgNV" + "BAMTDENBMS1STC4wOC4wMRcNOTkwMTAxMTIwMTAwWhcNNDgwMTAxMTIwMTAwWqAyMDAwCg" + "YDVR0UBAMCAQEwDQYDVR0bAQH/BAMCAQEwEwYDVR0jBAwwCoAIHjB7z6EiuQowDQYJKoZI" + "hvcNAQEFBQADgYEAkjF0oERt5XW2i70gyspkEYIHyGCHnqngky5yuwQSRrlW7t0vGdKV7W" + "50evTeSVV41uhi1MBcccpx1MdRcB5vsatFSSKcKx4NF3PuHXxXCm2HkfXQy4K5zftE3jOZ" + "5s+yTHiw3s/QSErtHRca+TQcEZwamI+p402TEa6e82l6xHI="; public static final String End_Certificate_RL_08_01_crt = "MIIChzCCAfCgAwIBAgICAMYwDQYJKoZIhvcNAQEFBQAwXjELMAkGA1UEBhMCVVMxGDAWBg" + "NVBAoTD1UuUy4gR292ZXJubWVudDEMMAoGA1UECxMDRG9kMRAwDgYDVQQLEwdUZXN0aW5n" + "MRUwEwYDVQQDEwxDQTEtUkwuMDguMDEwHhcNOTgwMTAxMTIwMTAwWhcNNDgwMTAxMTIwMT" + "AwWjBgMQswCQYDVQQGEwJVUzEYMBYGA1UEChMPVS5TLiBHb3Zlcm5tZW50MQwwCgYDVQQL" + "EwNEb0QxEDAOBgNVBAsTB1Rlc3RpbmcxFzAVBgNVBAMTDlVzZXIxLVJMLjA4LjAxMIGfMA" + "0GCSqGSIb3DQEBAQUAA4GNADCBiQKBgQDfEMqWMqk3Rre5m4ILtQIz45JImvU379Al/S6t" + "2y/TzimJc4nhIKQp80VaZA/gwu/DcvMgJPM+FFz5U5rRkDaYASsc34tZUESF5LC6ZbtGqf" + "J96IKdajvkGLsHyI7dseuwaQ0FlOwcmKMSR898MGNNbKxaQNLEXsIFypRDsN6JhwIDAQAB" + "o1IwUDAOBgNVHQ8BAf8EBAMCBeAwFgYDVR0gBA8wDTALBglghkgBZQMBMAEwEQYDVR0OBA" + "oECMT22ARjB1ABMBMGA1UdIwQMMAqACB4we8+hIrkKMA0GCSqGSIb3DQEBBQUAA4GBAIaP" + "EqI7oHl/+h3MszG4VB1Va9NTN0kaysTyjQSVBi9jhOlPkzuXc2wI1bymBhatHEn6OrgP13" + "vsOiH2BiyudYcYjKpwI4FUiyKLIc0CXzM0VYFoMzb91QtsK1EnvAPDKNYVVFXrL7ABVIK4" + "hU6HfMMUbnpKWBxT5274iHScX8tL"; public static final String[] TEST_75_DATA = new String[] { Intermediate_Certificate_RL_08_01_crt, Intermediate_CRL_RL_08_01_crl, End_Certificate_RL_08_01_crt }; /* * test76 * */ public static final String Intermediate_Certificate_RL_09_01_crt = "MIICljCCAf+gAwIBAgICAMcwDQYJKoZIhvcNAQEFBQAwXjELMAkGA1UEBhMCVVMxGDAWBg" + "NVBAoTD1UuUy4gR292ZXJubWVudDEMMAoGA1UECxMDRG9EMRAwDgYDVQQLEwdUZXN0aW5n" + "MRUwEwYDVQQDEwxUcnVzdCBBbmNob3IwHhcNOTgwMTAxMTIwMTAwWhcNNDgwMTAxMTIwMT" + "AwWjBeMQswCQYDVQQGEwJVUzEYMBYGA1UEChMPVS5TLiBHb3Zlcm5tZW50MQwwCgYDVQQL" + "EwNEb2QxEDAOBgNVBAsTB1Rlc3RpbmcxFTATBgNVBAMTDENBMS1STC4wOS4wMTCBnzANBg" + "kqhkiG9w0BAQEFAAOBjQAwgYkCgYEAsvkvLv5fMFYvohaXO8a7GgU4rDHe9iL7LP1VeNUg" + "GIdJGqPEnuggQ/guhrBHafGh1NtmlEbmPJ4WQ99dBbPHHeO8sfCgkmWC0SqPODoI+t3qJE" + "kf2z9dWoAij15RXPliywZz+S6bTtcEQAREyBQ6M8/HJ83wRXp/uCpdPOSxVPkCAwEAAaNj" + "MGEwDwYDVR0TAQH/BAUwAwEB/zAOBgNVHQ8BAf8EBAMCAQYwFgYDVR0gBA8wDTALBglghk" + "gBZQMBMAEwEQYDVR0OBAoECISY4bvGMEBTMBMGA1UdIwQMMAqACKua6/nC51SPMA0GCSqG" + "SIb3DQEBBQUAA4GBAAd7g+dWso4V/Vr+QIoNLueCBAYWdOF+Yz3VeomcsDAs2V8E+xcZaq" + "jo2LrMygYCeMxVfXx/ZdhLPOaZ+ahNAbk+nWRwj35JdTNAAbMMWFdZUgR6N+uzx1v7i86p" + "AWUpRJ9IYPgUoQ5pmjdf3Ru1nrLfRt4yp+kNHWp6IL/+MwcM"; public static final String Intermediate_CRL_RL_09_01_crl = "MIIBXDCBxgIBATANBgkqhkiG9w0BAQUFADBeMQswCQYDVQQGEwJVUzEYMBYGA1UEChMPVS" + "5TLiBHb3Zlcm5tZW50MQwwCgYDVQQLEwNEb2QxEDAOBgNVBAsTB1Rlc3RpbmcxFTATBgNV" + "BAMTDENBMS1STC4wOS4wMRcNOTkwMTAxMTIwMTAwWhcNNDgwMTAxMTIwMTAwWqA0MDIwCg" + "YDVR0UBAMCAQEwDwYDVR0cAQH/BAUwA4IB/zATBgNVHSMEDDAKgAiEmOG7xjBAUzANBgkq" + "hkiG9w0BAQUFAAOBgQAKTXYgqlP+upFIwOSpdaVKDT8aqFzY9nSIsxHg5Wdl43U7p44LvQ" + "lW8XKhw74oQl1ExU5s7mDaEqB0JIozGzmoNyKsErgWKNW+lpKSxR5+1EHOB6Oo2KijpTsv" + "GFrHFCnF09f9JaTaMRIXOljx3rMO1UZsftKy/L9z3aUz8hQRnQ=="; public static final String End_Certificate_RL_09_01_crt = "MIIChzCCAfCgAwIBAgICAMgwDQYJKoZIhvcNAQEFBQAwXjELMAkGA1UEBhMCVVMxGDAWBg" + "NVBAoTD1UuUy4gR292ZXJubWVudDEMMAoGA1UECxMDRG9kMRAwDgYDVQQLEwdUZXN0aW5n" + "MRUwEwYDVQQDEwxDQTEtUkwuMDkuMDEwHhcNOTgwMTAxMTIwMTAwWhcNNDgwMTAxMTIwMT" + "AwWjBgMQswCQYDVQQGEwJVUzEYMBYGA1UEChMPVS5TLiBHb3Zlcm5tZW50MQwwCgYDVQQL" + "EwNEb0QxEDAOBgNVBAsTB1Rlc3RpbmcxFzAVBgNVBAMTDlVzZXIxLVJMLjA5LjAxMIGfMA" + "0GCSqGSIb3DQEBAQUAA4GNADCBiQKBgQDpz09VCXzAhH4/ifMk0RAzaBqJCXaHHqAdO/TW" + "6uvOVtl+fGvWXhXmSSCUfzg5xBqdUXrqcyxOME3vdgF1uOFZ4q2K6+Zuxmm+GCOCIpe+Gl" + "Jzqz4WKXG0iaXXQOYa56itNc/6Z6D/aAjNJavI19w0lmb9l6U2WBfn3LywxHp4dwIDAQAB" + "o1IwUDAOBgNVHQ8BAf8EBAMCBeAwFgYDVR0gBA8wDTALBglghkgBZQMBMAEwEQYDVR0OBA" + "oECOri1JgnJfLjMBMGA1UdIwQMMAqACISY4bvGMEBTMA0GCSqGSIb3DQEBBQUAA4GBADmV" + "Ee0xy25Z0HtmWwprKPjJDr/p7TgzbmNC58pUPkgtxnJFP4yrzNB9FQBWSfnjZpzQkLSU7i" + "7O6cf5HkqjQqoPErDnJLWgGzjbF80v2IIyZk7rEpAAM4MwjIk7hFvJK8QkTht9F4N1zj2X" + "0TQkmlbo9Z4SFj/3fsbl9h2GdKuU"; public static final String[] TEST_76_DATA = new String[] { Intermediate_Certificate_RL_09_01_crt, Intermediate_CRL_RL_09_01_crl, End_Certificate_RL_09_01_crt }; } bouncycastle-1.49.orig/test/jdk1.3/org/bouncycastle/jce/provider/test/CertTest.java0000644000175000017500000036147612132666221027660 0ustar ebourgebourgpackage org.bouncycastle.jce.provider.test; import org.bouncycastle.asn1.ASN1EncodableVector; import org.bouncycastle.asn1.ASN1InputStream; import org.bouncycastle.asn1.DEREnumerated; import org.bouncycastle.asn1.DERObjectIdentifier; import org.bouncycastle.asn1.DEROctetString; import org.bouncycastle.asn1.DERSequence; import org.bouncycastle.asn1.DERSet; import org.bouncycastle.asn1.DERTaggedObject; import org.bouncycastle.asn1.cms.CMSObjectIdentifiers; import org.bouncycastle.asn1.cms.ContentInfo; import org.bouncycastle.asn1.cms.SignedData; import org.bouncycastle.asn1.x509.AuthorityKeyIdentifier; import org.bouncycastle.asn1.x509.CRLReason; import org.bouncycastle.asn1.x509.GeneralName; import org.bouncycastle.asn1.x509.GeneralNames; import org.bouncycastle.asn1.x509.KeyPurposeId; import org.bouncycastle.asn1.x509.X509Extension; import org.bouncycastle.asn1.x509.X509Extensions; import org.bouncycastle.asn1.x9.X9ObjectIdentifiers; import org.bouncycastle.jce.X509KeyUsage; import org.bouncycastle.jce.X509Principal; import org.bouncycastle.jce.interfaces.ECPointEncoder; import org.bouncycastle.jce.provider.BouncyCastleProvider; import org.bouncycastle.jce.spec.ECParameterSpec; import org.bouncycastle.jce.spec.ECPrivateKeySpec; import org.bouncycastle.jce.spec.ECPublicKeySpec; import org.bouncycastle.jce.spec.GOST3410ParameterSpec; import org.bouncycastle.math.ec.ECCurve; import org.bouncycastle.util.encoders.Base64; import org.bouncycastle.util.encoders.Hex; import org.bouncycastle.util.test.SimpleTest; import org.bouncycastle.x509.X509V1CertificateGenerator; import org.bouncycastle.x509.X509V2CRLGenerator; import org.bouncycastle.x509.X509V3CertificateGenerator; import org.bouncycastle.x509.extension.AuthorityKeyIdentifierStructure; import org.bouncycastle.x509.extension.X509ExtensionUtil; import java.io.ByteArrayInputStream; import java.io.IOException; import java.io.InputStream; import java.math.BigInteger; import java.security.KeyFactory; import java.security.KeyPair; import java.security.KeyPairGenerator; import java.security.PrivateKey; import java.security.PublicKey; import java.security.SecureRandom; import java.security.Security; import java.security.Signature; import java.security.cert.CRL; import java.security.cert.Certificate; import java.security.cert.CertificateFactory; import java.security.cert.CertificateParsingException; import java.security.cert.X509CRL; import java.security.cert.X509CRLEntry; import java.security.cert.X509Certificate; import java.security.spec.RSAPrivateCrtKeySpec; import java.security.spec.RSAPublicKeySpec; import java.util.Collection; import java.util.Date; import java.util.Hashtable; import java.util.Iterator; import java.util.List; import java.util.Set; import java.util.Vector; public class CertTest extends SimpleTest { // // server.crt // byte[] cert1 = Base64.decode( "MIIDXjCCAsegAwIBAgIBBzANBgkqhkiG9w0BAQQFADCBtzELMAkGA1UEBhMCQVUx" + "ETAPBgNVBAgTCFZpY3RvcmlhMRgwFgYDVQQHEw9Tb3V0aCBNZWxib3VybmUxGjAY" + "BgNVBAoTEUNvbm5lY3QgNCBQdHkgTHRkMR4wHAYDVQQLExVDZXJ0aWZpY2F0ZSBB" + "dXRob3JpdHkxFTATBgNVBAMTDENvbm5lY3QgNCBDQTEoMCYGCSqGSIb3DQEJARYZ" + "d2VibWFzdGVyQGNvbm5lY3Q0LmNvbS5hdTAeFw0wMDA2MDIwNzU2MjFaFw0wMTA2" + "MDIwNzU2MjFaMIG4MQswCQYDVQQGEwJBVTERMA8GA1UECBMIVmljdG9yaWExGDAW" + "BgNVBAcTD1NvdXRoIE1lbGJvdXJuZTEaMBgGA1UEChMRQ29ubmVjdCA0IFB0eSBM" + "dGQxFzAVBgNVBAsTDldlYnNlcnZlciBUZWFtMR0wGwYDVQQDExR3d3cyLmNvbm5l" + "Y3Q0LmNvbS5hdTEoMCYGCSqGSIb3DQEJARYZd2VibWFzdGVyQGNvbm5lY3Q0LmNv" + "bS5hdTCBnzANBgkqhkiG9w0BAQEFAAOBjQAwgYkCgYEArvDxclKAhyv7Q/Wmr2re" + "Gw4XL9Cnh9e+6VgWy2AWNy/MVeXdlxzd7QAuc1eOWQkGQEiLPy5XQtTY+sBUJ3AO" + "Rvd2fEVJIcjf29ey7bYua9J/vz5MG2KYo9/WCHIwqD9mmG9g0xLcfwq/s8ZJBswE" + "7sb85VU+h94PTvsWOsWuKaECAwEAAaN3MHUwJAYDVR0RBB0wG4EZd2VibWFzdGVy" + "QGNvbm5lY3Q0LmNvbS5hdTA6BglghkgBhvhCAQ0ELRYrbW9kX3NzbCBnZW5lcmF0" + "ZWQgY3VzdG9tIHNlcnZlciBjZXJ0aWZpY2F0ZTARBglghkgBhvhCAQEEBAMCBkAw" + "DQYJKoZIhvcNAQEEBQADgYEAotccfKpwSsIxM1Hae8DR7M/Rw8dg/RqOWx45HNVL" + "iBS4/3N/TO195yeQKbfmzbAA2jbPVvIvGgTxPgO1MP4ZgvgRhasaa0qCJCkWvpM4" + "yQf33vOiYQbpv4rTwzU8AmRlBG45WdjyNIigGV+oRc61aKCTnLq7zB8N3z1TF/bF" + "5/8="); // // ca.crt // byte[] cert2 = Base64.decode( "MIIDbDCCAtWgAwIBAgIBADANBgkqhkiG9w0BAQQFADCBtzELMAkGA1UEBhMCQVUx" + "ETAPBgNVBAgTCFZpY3RvcmlhMRgwFgYDVQQHEw9Tb3V0aCBNZWxib3VybmUxGjAY" + "BgNVBAoTEUNvbm5lY3QgNCBQdHkgTHRkMR4wHAYDVQQLExVDZXJ0aWZpY2F0ZSBB" + "dXRob3JpdHkxFTATBgNVBAMTDENvbm5lY3QgNCBDQTEoMCYGCSqGSIb3DQEJARYZ" + "d2VibWFzdGVyQGNvbm5lY3Q0LmNvbS5hdTAeFw0wMDA2MDIwNzU1MzNaFw0wMTA2" + "MDIwNzU1MzNaMIG3MQswCQYDVQQGEwJBVTERMA8GA1UECBMIVmljdG9yaWExGDAW" + "BgNVBAcTD1NvdXRoIE1lbGJvdXJuZTEaMBgGA1UEChMRQ29ubmVjdCA0IFB0eSBM" + "dGQxHjAcBgNVBAsTFUNlcnRpZmljYXRlIEF1dGhvcml0eTEVMBMGA1UEAxMMQ29u" + "bmVjdCA0IENBMSgwJgYJKoZIhvcNAQkBFhl3ZWJtYXN0ZXJAY29ubmVjdDQuY29t" + "LmF1MIGfMA0GCSqGSIb3DQEBAQUAA4GNADCBiQKBgQDgs5ptNG6Qv1ZpCDuUNGmv" + "rhjqMDPd3ri8JzZNRiiFlBA4e6/ReaO1U8ASewDeQMH6i9R6degFdQRLngbuJP0s" + "xcEE+SksEWNvygfzLwV9J/q+TQDyJYK52utb++lS0b48A1KPLwEsyL6kOAgelbur" + "ukwxowprKUIV7Knf1ajetQIDAQABo4GFMIGCMCQGA1UdEQQdMBuBGXdlYm1hc3Rl" + "ckBjb25uZWN0NC5jb20uYXUwDwYDVR0TBAgwBgEB/wIBADA2BglghkgBhvhCAQ0E" + "KRYnbW9kX3NzbCBnZW5lcmF0ZWQgY3VzdG9tIENBIGNlcnRpZmljYXRlMBEGCWCG" + "SAGG+EIBAQQEAwICBDANBgkqhkiG9w0BAQQFAAOBgQCsGvfdghH8pPhlwm1r3pQk" + "msnLAVIBb01EhbXm2861iXZfWqGQjrGAaA0ZpXNk9oo110yxoqEoSJSzniZa7Xtz" + "soTwNUpE0SLHvWf/SlKdFWlzXA+vOZbzEv4UmjeelekTm7lc01EEa5QRVzOxHFtQ" + "DhkaJ8VqOMajkQFma2r9iA=="); // // testx509.pem // byte[] cert3 = Base64.decode( "MIIBWzCCAQYCARgwDQYJKoZIhvcNAQEEBQAwODELMAkGA1UEBhMCQVUxDDAKBgNV" + "BAgTA1FMRDEbMBkGA1UEAxMSU1NMZWF5L3JzYSB0ZXN0IENBMB4XDTk1MDYxOTIz" + "MzMxMloXDTk1MDcxNzIzMzMxMlowOjELMAkGA1UEBhMCQVUxDDAKBgNVBAgTA1FM" + "RDEdMBsGA1UEAxMUU1NMZWF5L3JzYSB0ZXN0IGNlcnQwXDANBgkqhkiG9w0BAQEF" + "AANLADBIAkEAqtt6qS5GTxVxGZYWa0/4u+IwHf7p2LNZbcPBp9/OfIcYAXBQn8hO" + "/Re1uwLKXdCjIoaGs4DLdG88rkzfyK5dPQIDAQABMAwGCCqGSIb3DQIFBQADQQAE" + "Wc7EcF8po2/ZO6kNCwK/ICH6DobgLekA5lSLr5EvuioZniZp5lFzAw4+YzPQ7XKJ" + "zl9HYIMxATFyqSiD9jsx"); // // v3-cert1.pem // byte[] cert4 = Base64.decode( "MIICjTCCAfigAwIBAgIEMaYgRzALBgkqhkiG9w0BAQQwRTELMAkGA1UEBhMCVVMx" + "NjA0BgNVBAoTLU5hdGlvbmFsIEFlcm9uYXV0aWNzIGFuZCBTcGFjZSBBZG1pbmlz" + "dHJhdGlvbjAmFxE5NjA1MjgxMzQ5MDUrMDgwMBcROTgwNTI4MTM0OTA1KzA4MDAw" + "ZzELMAkGA1UEBhMCVVMxNjA0BgNVBAoTLU5hdGlvbmFsIEFlcm9uYXV0aWNzIGFu" + "ZCBTcGFjZSBBZG1pbmlzdHJhdGlvbjEgMAkGA1UEBRMCMTYwEwYDVQQDEwxTdGV2" + "ZSBTY2hvY2gwWDALBgkqhkiG9w0BAQEDSQAwRgJBALrAwyYdgxmzNP/ts0Uyf6Bp" + "miJYktU/w4NG67ULaN4B5CnEz7k57s9o3YY3LecETgQ5iQHmkwlYDTL2fTgVfw0C" + "AQOjgaswgagwZAYDVR0ZAQH/BFowWDBWMFQxCzAJBgNVBAYTAlVTMTYwNAYDVQQK" + "Ey1OYXRpb25hbCBBZXJvbmF1dGljcyBhbmQgU3BhY2UgQWRtaW5pc3RyYXRpb24x" + "DTALBgNVBAMTBENSTDEwFwYDVR0BAQH/BA0wC4AJODMyOTcwODEwMBgGA1UdAgQR" + "MA8ECTgzMjk3MDgyM4ACBSAwDQYDVR0KBAYwBAMCBkAwCwYJKoZIhvcNAQEEA4GB" + "AH2y1VCEw/A4zaXzSYZJTTUi3uawbbFiS2yxHvgf28+8Js0OHXk1H1w2d6qOHH21" + "X82tZXd/0JtG0g1T9usFFBDvYK8O0ebgz/P5ELJnBL2+atObEuJy1ZZ0pBDWINR3" + "WkDNLCGiTkCKp0F5EWIrVDwh54NNevkCQRZita+z4IBO"); // // v3-cert2.pem // byte[] cert5 = Base64.decode( "MIICiTCCAfKgAwIBAgIEMeZfHzANBgkqhkiG9w0BAQQFADB9MQswCQYDVQQGEwJD" + "YTEPMA0GA1UEBxMGTmVwZWFuMR4wHAYDVQQLExVObyBMaWFiaWxpdHkgQWNjZXB0" + "ZWQxHzAdBgNVBAoTFkZvciBEZW1vIFB1cnBvc2VzIE9ubHkxHDAaBgNVBAMTE0Vu" + "dHJ1c3QgRGVtbyBXZWIgQ0EwHhcNOTYwNzEyMTQyMDE1WhcNOTYxMDEyMTQyMDE1" + "WjB0MSQwIgYJKoZIhvcNAQkBExVjb29rZUBpc3NsLmF0bC5ocC5jb20xCzAJBgNV" + "BAYTAlVTMScwJQYDVQQLEx5IZXdsZXR0IFBhY2thcmQgQ29tcGFueSAoSVNTTCkx" + "FjAUBgNVBAMTDVBhdWwgQS4gQ29va2UwXDANBgkqhkiG9w0BAQEFAANLADBIAkEA" + "6ceSq9a9AU6g+zBwaL/yVmW1/9EE8s5you1mgjHnj0wAILuoB3L6rm6jmFRy7QZT" + "G43IhVZdDua4e+5/n1ZslwIDAQABo2MwYTARBglghkgBhvhCAQEEBAMCB4AwTAYJ" + "YIZIAYb4QgENBD8WPVRoaXMgY2VydGlmaWNhdGUgaXMgb25seSBpbnRlbmRlZCBm" + "b3IgZGVtb25zdHJhdGlvbiBwdXJwb3Nlcy4wDQYJKoZIhvcNAQEEBQADgYEAi8qc" + "F3zfFqy1sV8NhjwLVwOKuSfhR/Z8mbIEUeSTlnH3QbYt3HWZQ+vXI8mvtZoBc2Fz" + "lexKeIkAZXCesqGbs6z6nCt16P6tmdfbZF3I3AWzLquPcOXjPf4HgstkyvVBn0Ap" + "jAFN418KF/Cx4qyHB4cjdvLrRjjQLnb2+ibo7QU="); // // pem encoded pkcs7 // byte[] cert6 = Base64.decode( "MIAGCSqGSIb3DQEHAqCAMIACAQExCzAJBgUrDgMCGgUAMIAGCSqGSIb3DQEHAQAAoIIJbzCCAj0w" + "ggGmAhEAzbp/VvDf5LxU/iKss3KqVTANBgkqhkiG9w0BAQIFADBfMQswCQYDVQQGEwJVUzEXMBUG" + "A1UEChMOVmVyaVNpZ24sIEluYy4xNzA1BgNVBAsTLkNsYXNzIDEgUHVibGljIFByaW1hcnkgQ2Vy" + "dGlmaWNhdGlvbiBBdXRob3JpdHkwHhcNOTYwMTI5MDAwMDAwWhcNMjgwODAxMjM1OTU5WjBfMQsw" + "CQYDVQQGEwJVUzEXMBUGA1UEChMOVmVyaVNpZ24sIEluYy4xNzA1BgNVBAsTLkNsYXNzIDEgUHVi" + "bGljIFByaW1hcnkgQ2VydGlmaWNhdGlvbiBBdXRob3JpdHkwgZ8wDQYJKoZIhvcNAQEBBQADgY0A" + "MIGJAoGBAOUZv22jVmEtmUhx9mfeuY3rt56GgAqRDvo4Ja9GiILlc6igmyRdDR/MZW4MsNBWhBiH" + "mgabEKFz37RYOWtuwfYV1aioP6oSBo0xrH+wNNePNGeICc0UEeJORVZpH3gCgNrcR5EpuzbJY1zF" + "4Ncth3uhtzKwezC6Ki8xqu6jZ9rbAgMBAAEwDQYJKoZIhvcNAQECBQADgYEATD+4i8Zo3+5DMw5d" + "6abLB4RNejP/khv0Nq3YlSI2aBFsfELM85wuxAc/FLAPT/+Qknb54rxK6Y/NoIAK98Up8YIiXbix" + "3YEjo3slFUYweRb46gVLlH8dwhzI47f0EEA8E8NfH1PoSOSGtHuhNbB7Jbq4046rPzidADQAmPPR" + "cZQwggMuMIICl6ADAgECAhEA0nYujRQMPX2yqCVdr+4NdTANBgkqhkiG9w0BAQIFADBfMQswCQYD" + "VQQGEwJVUzEXMBUGA1UEChMOVmVyaVNpZ24sIEluYy4xNzA1BgNVBAsTLkNsYXNzIDEgUHVibGlj" + "IFByaW1hcnkgQ2VydGlmaWNhdGlvbiBBdXRob3JpdHkwHhcNOTgwNTEyMDAwMDAwWhcNMDgwNTEy" + "MjM1OTU5WjCBzDEXMBUGA1UEChMOVmVyaVNpZ24sIEluYy4xHzAdBgNVBAsTFlZlcmlTaWduIFRy" + "dXN0IE5ldHdvcmsxRjBEBgNVBAsTPXd3dy52ZXJpc2lnbi5jb20vcmVwb3NpdG9yeS9SUEEgSW5j" + "b3JwLiBCeSBSZWYuLExJQUIuTFREKGMpOTgxSDBGBgNVBAMTP1ZlcmlTaWduIENsYXNzIDEgQ0Eg" + "SW5kaXZpZHVhbCBTdWJzY3JpYmVyLVBlcnNvbmEgTm90IFZhbGlkYXRlZDCBnzANBgkqhkiG9w0B" + "AQEFAAOBjQAwgYkCgYEAu1pEigQWu1X9A3qKLZRPFXg2uA1Ksm+cVL+86HcqnbnwaLuV2TFBcHqB" + "S7lIE1YtxwjhhEKrwKKSq0RcqkLwgg4C6S/7wju7vsknCl22sDZCM7VuVIhPh0q/Gdr5FegPh7Yc" + "48zGmo5/aiSS4/zgZbqnsX7vyds3ashKyAkG5JkCAwEAAaN8MHowEQYJYIZIAYb4QgEBBAQDAgEG" + "MEcGA1UdIARAMD4wPAYLYIZIAYb4RQEHAQEwLTArBggrBgEFBQcCARYfd3d3LnZlcmlzaWduLmNv" + "bS9yZXBvc2l0b3J5L1JQQTAPBgNVHRMECDAGAQH/AgEAMAsGA1UdDwQEAwIBBjANBgkqhkiG9w0B" + "AQIFAAOBgQCIuDc73dqUNwCtqp/hgQFxHpJqbS/28Z3TymQ43BuYDAeGW4UVag+5SYWklfEXfWe0" + "fy0s3ZpCnsM+tI6q5QsG3vJWKvozx74Z11NMw73I4xe1pElCY+zCphcPXVgaSTyQXFWjZSAA/Rgg" + "5V+CprGoksVYasGNAzzrw80FopCubjCCA/gwggNhoAMCAQICEBbbn/1G1zppD6KsP01bwywwDQYJ" + "KoZIhvcNAQEEBQAwgcwxFzAVBgNVBAoTDlZlcmlTaWduLCBJbmMuMR8wHQYDVQQLExZWZXJpU2ln" + "biBUcnVzdCBOZXR3b3JrMUYwRAYDVQQLEz13d3cudmVyaXNpZ24uY29tL3JlcG9zaXRvcnkvUlBB" + "IEluY29ycC4gQnkgUmVmLixMSUFCLkxURChjKTk4MUgwRgYDVQQDEz9WZXJpU2lnbiBDbGFzcyAx" + "IENBIEluZGl2aWR1YWwgU3Vic2NyaWJlci1QZXJzb25hIE5vdCBWYWxpZGF0ZWQwHhcNMDAxMDAy" + "MDAwMDAwWhcNMDAxMjAxMjM1OTU5WjCCAQcxFzAVBgNVBAoTDlZlcmlTaWduLCBJbmMuMR8wHQYD" + "VQQLExZWZXJpU2lnbiBUcnVzdCBOZXR3b3JrMUYwRAYDVQQLEz13d3cudmVyaXNpZ24uY29tL3Jl" + "cG9zaXRvcnkvUlBBIEluY29ycC4gYnkgUmVmLixMSUFCLkxURChjKTk4MR4wHAYDVQQLExVQZXJz" + "b25hIE5vdCBWYWxpZGF0ZWQxJzAlBgNVBAsTHkRpZ2l0YWwgSUQgQ2xhc3MgMSAtIE1pY3Jvc29m" + "dDETMBEGA1UEAxQKRGF2aWQgUnlhbjElMCMGCSqGSIb3DQEJARYWZGF2aWRAbGl2ZW1lZGlhLmNv" + "bS5hdTCBnzANBgkqhkiG9w0BAQEFAAOBjQAwgYkCgYEAqxBsdeNmSvFqhMNwhQgNzM8mdjX9eSXb" + "DawpHtQHjmh0AKJSa3IwUY0VIsyZHuXWktO/CgaMBVPt6OVf/n0R2sQigMP6Y+PhEiS0vCJBL9aK" + "0+pOo2qXrjVBmq+XuCyPTnc+BOSrU26tJsX0P9BYorwySiEGxGanBNATdVL4NdUCAwEAAaOBnDCB" + "mTAJBgNVHRMEAjAAMEQGA1UdIAQ9MDswOQYLYIZIAYb4RQEHAQgwKjAoBggrBgEFBQcCARYcaHR0" + "cHM6Ly93d3cudmVyaXNpZ24uY29tL3JwYTARBglghkgBhvhCAQEEBAMCB4AwMwYDVR0fBCwwKjAo" + "oCagJIYiaHR0cDovL2NybC52ZXJpc2lnbi5jb20vY2xhc3MxLmNybDANBgkqhkiG9w0BAQQFAAOB" + "gQBC8yIIdVGpFTf8/YiL14cMzcmL0nIRm4kGR3U59z7UtcXlfNXXJ8MyaeI/BnXwG/gD5OKYqW6R" + "yca9vZOxf1uoTBl82gInk865ED3Tej6msCqFzZffnSUQvOIeqLxxDlqYRQ6PmW2nAnZeyjcnbI5Y" + "syQSM2fmo7n6qJFP+GbFezGCAkUwggJBAgEBMIHhMIHMMRcwFQYDVQQKEw5WZXJpU2lnbiwgSW5j" + "LjEfMB0GA1UECxMWVmVyaVNpZ24gVHJ1c3QgTmV0d29yazFGMEQGA1UECxM9d3d3LnZlcmlzaWdu" + "LmNvbS9yZXBvc2l0b3J5L1JQQSBJbmNvcnAuIEJ5IFJlZi4sTElBQi5MVEQoYyk5ODFIMEYGA1UE" + "AxM/VmVyaVNpZ24gQ2xhc3MgMSBDQSBJbmRpdmlkdWFsIFN1YnNjcmliZXItUGVyc29uYSBOb3Qg" + "VmFsaWRhdGVkAhAW25/9Rtc6aQ+irD9NW8MsMAkGBSsOAwIaBQCggbowGAYJKoZIhvcNAQkDMQsG" + "CSqGSIb3DQEHATAcBgkqhkiG9w0BCQUxDxcNMDAxMDAyMTczNTE4WjAjBgkqhkiG9w0BCQQxFgQU" + "gZjSaBEY2oxGvlQUIMnxSXhivK8wWwYJKoZIhvcNAQkPMU4wTDAKBggqhkiG9w0DBzAOBggqhkiG" + "9w0DAgICAIAwDQYIKoZIhvcNAwICAUAwBwYFKw4DAgcwDQYIKoZIhvcNAwICASgwBwYFKw4DAh0w" + "DQYJKoZIhvcNAQEBBQAEgYAzk+PU91/ZFfoiuKOECjxEh9fDYE2jfDCheBIgh5gdcCo+sS1WQs8O" + "HreQ9Nop/JdJv1DQMBK6weNBBDoP0EEkRm1XCC144XhXZC82jBZohYmi2WvDbbC//YN58kRMYMyy" + "srrfn4Z9I+6kTriGXkrpGk9Q0LSGjmG2BIsqiF0dvwAAAAAAAA=="); // // dsaWithSHA1 cert // byte[] cert7 = Base64.decode( "MIIEXAYJKoZIhvcNAQcCoIIETTCCBEkCAQExCzAJBgUrDgMCGgUAMAsGCSqG" + "SIb3DQEHAaCCAsMwggK/MIIB4AIBADCBpwYFKw4DAhswgZ0CQQEkJRHP+mN7" + "d8miwTMN55CUSmo3TO8WGCxgY61TX5k+7NU4XPf1TULjw3GobwaJX13kquPh" + "fVXk+gVy46n4Iw3hAhUBSe/QF4BUj+pJOF9ROBM4u+FEWA8CQQD4mSJbrABj" + "TUWrlnAte8pS22Tq4/FPO7jHSqjijUHfXKTrHL1OEqV3SVWcFy5j/cqBgX/z" + "m8Q12PFp/PjOhh+nMA4xDDAKBgNVBAMTA0lEMzAeFw05NzEwMDEwMDAwMDBa" + "Fw0zODAxMDEwMDAwMDBaMA4xDDAKBgNVBAMTA0lEMzCB8DCBpwYFKw4DAhsw" + "gZ0CQQEkJRHP+mN7d8miwTMN55CUSmo3TO8WGCxgY61TX5k+7NU4XPf1TULj" + "w3GobwaJX13kquPhfVXk+gVy46n4Iw3hAhUBSe/QF4BUj+pJOF9ROBM4u+FE" + "WA8CQQD4mSJbrABjTUWrlnAte8pS22Tq4/FPO7jHSqjijUHfXKTrHL1OEqV3" + "SVWcFy5j/cqBgX/zm8Q12PFp/PjOhh+nA0QAAkEAkYkXLYMtGVGWj9OnzjPn" + "sB9sefSRPrVegZJCZbpW+Iv0/1RP1u04pHG9vtRpIQLjzUiWvLMU9EKQTThc" + "eNMmWDCBpwYFKw4DAhswgZ0CQQEkJRHP+mN7d8miwTMN55CUSmo3TO8WGCxg" + "Y61TX5k+7NU4XPf1TULjw3GobwaJX13kquPhfVXk+gVy46n4Iw3hAhUBSe/Q" + "F4BUj+pJOF9ROBM4u+FEWA8CQQD4mSJbrABjTUWrlnAte8pS22Tq4/FPO7jH" + "SqjijUHfXKTrHL1OEqV3SVWcFy5j/cqBgX/zm8Q12PFp/PjOhh+nAy8AMCwC" + "FBY3dBSdeprGcqpr6wr3xbG+6WW+AhRMm/facKJNxkT3iKgJbp7R8Xd3QTGC" + "AWEwggFdAgEBMBMwDjEMMAoGA1UEAxMDSUQzAgEAMAkGBSsOAwIaBQCgXTAY" + "BgkqhkiG9w0BCQMxCwYJKoZIhvcNAQcBMBwGCSqGSIb3DQEJBTEPFw0wMjA1" + "MjQyMzEzMDdaMCMGCSqGSIb3DQEJBDEWBBS4WMsoJhf7CVbZYCFcjoTRzPkJ" + "xjCBpwYFKw4DAhswgZ0CQQEkJRHP+mN7d8miwTMN55CUSmo3TO8WGCxgY61T" + "X5k+7NU4XPf1TULjw3GobwaJX13kquPhfVXk+gVy46n4Iw3hAhUBSe/QF4BU" + "j+pJOF9ROBM4u+FEWA8CQQD4mSJbrABjTUWrlnAte8pS22Tq4/FPO7jHSqji" + "jUHfXKTrHL1OEqV3SVWcFy5j/cqBgX/zm8Q12PFp/PjOhh+nBC8wLQIVALID" + "dt+MHwawrDrwsO1Z6sXBaaJsAhRaKssrpevmLkbygKPV07XiAKBG02Zvb2Jh" + "cg=="); // // testcrl.pem // byte[] crl1 = Base64.decode( "MIICjTCCAfowDQYJKoZIhvcNAQECBQAwXzELMAkGA1UEBhMCVVMxIDAeBgNVBAoT" + "F1JTQSBEYXRhIFNlY3VyaXR5LCBJbmMuMS4wLAYDVQQLEyVTZWN1cmUgU2VydmVy" + "IENlcnRpZmljYXRpb24gQXV0aG9yaXR5Fw05NTA1MDIwMjEyMjZaFw05NTA2MDEw" + "MDAxNDlaMIIBaDAWAgUCQQAABBcNOTUwMjAxMTcyNDI2WjAWAgUCQQAACRcNOTUw" + "MjEwMDIxNjM5WjAWAgUCQQAADxcNOTUwMjI0MDAxMjQ5WjAWAgUCQQAADBcNOTUw" + "MjI1MDA0NjQ0WjAWAgUCQQAAGxcNOTUwMzEzMTg0MDQ5WjAWAgUCQQAAFhcNOTUw" + "MzE1MTkxNjU0WjAWAgUCQQAAGhcNOTUwMzE1MTk0MDQxWjAWAgUCQQAAHxcNOTUw" + "MzI0MTk0NDMzWjAWAgUCcgAABRcNOTUwMzI5MjAwNzExWjAWAgUCcgAAERcNOTUw" + "MzMwMDIzNDI2WjAWAgUCQQAAIBcNOTUwNDA3MDExMzIxWjAWAgUCcgAAHhcNOTUw" + "NDA4MDAwMjU5WjAWAgUCcgAAQRcNOTUwNDI4MTcxNzI0WjAWAgUCcgAAOBcNOTUw" + "NDI4MTcyNzIxWjAWAgUCcgAATBcNOTUwNTAyMDIxMjI2WjANBgkqhkiG9w0BAQIF" + "AAN+AHqOEJXSDejYy0UwxxrH/9+N2z5xu/if0J6qQmK92W0hW158wpJg+ovV3+wQ" + "wvIEPRL2rocL0tKfAsVq1IawSJzSNgxG0lrcla3MrJBnZ4GaZDu4FutZh72MR3Gt" + "JaAL3iTJHJD55kK2D/VoyY1djlsPuNh6AEgdVwFAyp0v"); // // ecdsa cert with extra octet string. // byte[] oldEcdsa = Base64.decode( "MIICljCCAkCgAwIBAgIBATALBgcqhkjOPQQBBQAwgY8xCzAJBgNVBAYTAkFVMSgwJ" + "gYDVQQKEx9UaGUgTGVnaW9uIG9mIHRoZSBCb3VuY3kgQ2FzdGxlMRIwEAYDVQQHEw" + "lNZWxib3VybmUxETAPBgNVBAgTCFZpY3RvcmlhMS8wLQYJKoZIhvcNAQkBFiBmZWV" + "kYmFjay1jcnlwdG9AYm91bmN5Y2FzdGxlLm9yZzAeFw0wMTEyMDcwMTAwMDRaFw0w" + "MTEyMDcwMTAxNDRaMIGPMQswCQYDVQQGEwJBVTEoMCYGA1UEChMfVGhlIExlZ2lvb" + "iBvZiB0aGUgQm91bmN5IENhc3RsZTESMBAGA1UEBxMJTWVsYm91cm5lMREwDwYDVQ" + "QIEwhWaWN0b3JpYTEvMC0GCSqGSIb3DQEJARYgZmVlZGJhY2stY3J5cHRvQGJvdW5" + "jeWNhc3RsZS5vcmcwgeQwgb0GByqGSM49AgEwgbECAQEwKQYHKoZIzj0BAQIef///" + "////////////f///////gAAAAAAAf///////MEAEHn///////////////3///////" + "4AAAAAAAH///////AQeawFsO9zxiUHQ1lSSFHXKcanbL7J9HTd5YYXClCwKBB8CD/" + "qWPNyogWzMM7hkK+35BcPTWFc9Pyf7vTs8uaqvAh5///////////////9///+eXpq" + "fXZBx+9FSJoiQnQsDIgAEHwJbbcU7xholSP+w9nFHLebJUhqdLSU05lq/y9X+DHAw" + "CwYHKoZIzj0EAQUAA0MAMEACHnz6t4UNoVROp74ma4XNDjjGcjaqiIWPZLK8Bdw3G" + "QIeLZ4j3a6ividZl344UH+UPUE7xJxlYGuy7ejTsqRR"); byte[] uncompressedPtEC = Base64.decode( "MIIDKzCCAsGgAwIBAgICA+kwCwYHKoZIzj0EAQUAMGYxCzAJBgNVBAYTAkpQ" + "MRUwEwYDVQQKEwxuaXRlY2guYWMuanAxDjAMBgNVBAsTBWFpbGFiMQ8wDQYD" + "VQQDEwZ0ZXN0Y2ExHzAdBgkqhkiG9w0BCQEWEHRlc3RjYUBsb2NhbGhvc3Qw" + "HhcNMDExMDEzMTE1MzE3WhcNMjAxMjEyMTE1MzE3WjBmMQswCQYDVQQGEwJK" + "UDEVMBMGA1UEChMMbml0ZWNoLmFjLmpwMQ4wDAYDVQQLEwVhaWxhYjEPMA0G" + "A1UEAxMGdGVzdGNhMR8wHQYJKoZIhvcNAQkBFhB0ZXN0Y2FAbG9jYWxob3N0" + "MIIBczCCARsGByqGSM49AgEwggEOAgEBMDMGByqGSM49AQECKEdYWnajFmnZ" + "tzrukK2XWdle2v+GsD9l1ZiR6g7ozQDbhFH/bBiMDQcwVAQoJ5EQKrI54/CT" + "xOQ2pMsd/fsXD+EX8YREd8bKHWiLz8lIVdD5cBNeVwQoMKSc6HfI7vKZp8Q2" + "zWgIFOarx1GQoWJbMcSt188xsl30ncJuJT2OoARRBAqJ4fD+q6hbqgNSjTQ7" + "htle1KO3eiaZgcJ8rrnyN8P+5A8+5K+H9aQ/NbBR4Gs7yto5PXIUZEUgodHA" + "TZMSAcSq5ZYt4KbnSYaLY0TtH9CqAigEwZ+hglbT21B7ZTzYX2xj0x+qooJD" + "hVTLtIPaYJK2HrMPxTw6/zfrAgEPA1IABAnvfFcFDgD/JicwBGn6vR3N8MIn" + "mptZf/mnJ1y649uCF60zOgdwIyI7pVSxBFsJ7ohqXEHW0x7LrGVkdSEiipiH" + "LYslqh3xrqbAgPbl93GUo0IwQDAPBgNVHRMBAf8EBTADAQH/MA4GA1UdDwEB" + "/wQEAwIBxjAdBgNVHQ4EFgQUAEo62Xm9H6DcsE0zUDTza4BRG90wCwYHKoZI" + "zj0EAQUAA1cAMFQCKAQsCHHSNOqfJXLgt3bg5+k49hIBGVr/bfG0B9JU3rNt" + "Ycl9Y2zfRPUCKAK2ccOQXByAWfsasDu8zKHxkZv7LVDTFjAIffz3HaCQeVhD" + "z+fauEg="); byte[] keyUsage = Base64.decode( "MIIE7TCCBFagAwIBAgIEOAOR7jANBgkqhkiG9w0BAQQFADCByTELMAkGA1UE" + "BhMCVVMxFDASBgNVBAoTC0VudHJ1c3QubmV0MUgwRgYDVQQLFD93d3cuZW50" + "cnVzdC5uZXQvQ2xpZW50X0NBX0luZm8vQ1BTIGluY29ycC4gYnkgcmVmLiBs" + "aW1pdHMgbGlhYi4xJTAjBgNVBAsTHChjKSAxOTk5IEVudHJ1c3QubmV0IExp" + "bWl0ZWQxMzAxBgNVBAMTKkVudHJ1c3QubmV0IENsaWVudCBDZXJ0aWZpY2F0" + "aW9uIEF1dGhvcml0eTAeFw05OTEwMTIxOTI0MzBaFw0xOTEwMTIxOTU0MzBa" + "MIHJMQswCQYDVQQGEwJVUzEUMBIGA1UEChMLRW50cnVzdC5uZXQxSDBGBgNV" + "BAsUP3d3dy5lbnRydXN0Lm5ldC9DbGllbnRfQ0FfSW5mby9DUFMgaW5jb3Jw" + "LiBieSByZWYuIGxpbWl0cyBsaWFiLjElMCMGA1UECxMcKGMpIDE5OTkgRW50" + "cnVzdC5uZXQgTGltaXRlZDEzMDEGA1UEAxMqRW50cnVzdC5uZXQgQ2xpZW50" + "IENlcnRpZmljYXRpb24gQXV0aG9yaXR5MIGdMA0GCSqGSIb3DQEBAQUAA4GL" + "ADCBhwKBgQDIOpleMRffrCdvkHvkGf9FozTC28GoT/Bo6oT9n3V5z8GKUZSv" + "x1cDR2SerYIbWtp/N3hHuzeYEpbOxhN979IMMFGpOZ5V+Pux5zDeg7K6PvHV" + "iTs7hbqqdCz+PzFur5GVbgbUB01LLFZHGARS2g4Qk79jkJvh34zmAqTmT173" + "iwIBA6OCAeAwggHcMBEGCWCGSAGG+EIBAQQEAwIABzCCASIGA1UdHwSCARkw" + "ggEVMIHkoIHhoIHepIHbMIHYMQswCQYDVQQGEwJVUzEUMBIGA1UEChMLRW50" + "cnVzdC5uZXQxSDBGBgNVBAsUP3d3dy5lbnRydXN0Lm5ldC9DbGllbnRfQ0Ff" + "SW5mby9DUFMgaW5jb3JwLiBieSByZWYuIGxpbWl0cyBsaWFiLjElMCMGA1UE" + "CxMcKGMpIDE5OTkgRW50cnVzdC5uZXQgTGltaXRlZDEzMDEGA1UEAxMqRW50" + "cnVzdC5uZXQgQ2xpZW50IENlcnRpZmljYXRpb24gQXV0aG9yaXR5MQ0wCwYD" + "VQQDEwRDUkwxMCygKqAohiZodHRwOi8vd3d3LmVudHJ1c3QubmV0L0NSTC9D" + "bGllbnQxLmNybDArBgNVHRAEJDAigA8xOTk5MTAxMjE5MjQzMFqBDzIwMTkx" + "MDEyMTkyNDMwWjALBgNVHQ8EBAMCAQYwHwYDVR0jBBgwFoAUxPucKXuXzUyW" + "/O5bs8qZdIuV6kwwHQYDVR0OBBYEFMT7nCl7l81MlvzuW7PKmXSLlepMMAwG" + "A1UdEwQFMAMBAf8wGQYJKoZIhvZ9B0EABAwwChsEVjQuMAMCBJAwDQYJKoZI" + "hvcNAQEEBQADgYEAP66K8ddmAwWePvrqHEa7pFuPeJoSSJn59DXeDDYHAmsQ" + "OokUgZwxpnyyQbJq5wcBoUv5nyU7lsqZwz6hURzzwy5E97BnRqqS5TvaHBkU" + "ODDV4qIxJS7x7EU47fgGWANzYrAQMY9Av2TgXD7FTx/aEkP/TOYGJqibGapE" + "PHayXOw="); byte[] nameCert = Base64.decode( "MIIEFjCCA3+gAwIBAgIEdS8BozANBgkqhkiG9w0BAQUFADBKMQswCQYDVQQGEwJE"+ "RTERMA8GA1UEChQIREFURVYgZUcxKDAMBgcCggYBCgcUEwExMBgGA1UEAxQRQ0Eg"+ "REFURVYgRDAzIDE6UE4wIhgPMjAwMTA1MTAxMDIyNDhaGA8yMDA0MDUwOTEwMjI0"+ "OFowgYQxCzAJBgNVBAYTAkRFMQ8wDQYDVQQIFAZCYXllcm4xEjAQBgNVBAcUCU7I"+ "dXJuYmVyZzERMA8GA1UEChQIREFURVYgZUcxHTAbBgNVBAUTFDAwMDAwMDAwMDA4"+ "OTU3NDM2MDAxMR4wHAYDVQQDFBVEaWV0bWFyIFNlbmdlbmxlaXRuZXIwgaEwDQYJ"+ "KoZIhvcNAQEBBQADgY8AMIGLAoGBAJLI/LJLKaHoMk8fBECW/od8u5erZi6jI8Ug"+ "C0a/LZyQUO/R20vWJs6GrClQtXB+AtfiBSnyZOSYzOdfDI8yEKPEv8qSuUPpOHps"+ "uNCFdLZF1vavVYGEEWs2+y+uuPmg8q1oPRyRmUZ+x9HrDvCXJraaDfTEd9olmB/Z"+ "AuC/PqpjAgUAwAAAAaOCAcYwggHCMAwGA1UdEwEB/wQCMAAwDwYDVR0PAQH/BAUD"+ "AwdAADAxBgNVHSAEKjAoMCYGBSskCAEBMB0wGwYIKwYBBQUHAgEWD3d3dy56cy5k"+ "YXRldi5kZTApBgNVHREEIjAggR5kaWV0bWFyLnNlbmdlbmxlaXRuZXJAZGF0ZXYu"+ "ZGUwgYQGA1UdIwR9MHuhc6RxMG8xCzAJBgNVBAYTAkRFMT0wOwYDVQQKFDRSZWd1"+ "bGllcnVuZ3NiZWjIb3JkZSBmyHVyIFRlbGVrb21tdW5pa2F0aW9uIHVuZCBQb3N0"+ "MSEwDAYHAoIGAQoHFBMBMTARBgNVBAMUCjVSLUNBIDE6UE6CBACm8LkwDgYHAoIG"+ "AQoMAAQDAQEAMEcGA1UdHwRAMD4wPKAUoBKGEHd3dy5jcmwuZGF0ZXYuZGWiJKQi"+ "MCAxCzAJBgNVBAYTAkRFMREwDwYDVQQKFAhEQVRFViBlRzAWBgUrJAgDBAQNMAsT"+ "A0VVUgIBBQIBATAdBgNVHQ4EFgQUfv6xFP0xk7027folhy+ziZvBJiwwLAYIKwYB"+ "BQUHAQEEIDAeMBwGCCsGAQUFBzABhhB3d3cuZGlyLmRhdGV2LmRlMA0GCSqGSIb3"+ "DQEBBQUAA4GBAEOVX6uQxbgtKzdgbTi6YLffMftFr2mmNwch7qzpM5gxcynzgVkg"+ "pnQcDNlm5AIbS6pO8jTCLfCd5TZ5biQksBErqmesIl3QD+VqtB+RNghxectZ3VEs"+ "nCUtcE7tJ8O14qwCb3TxS9dvIUFiVi4DjbxX46TdcTbTaK8/qr6AIf+l"); byte[] probSelfSignedCert = Base64.decode( "MIICxTCCAi6gAwIBAgIQAQAAAAAAAAAAAAAAAAAAATANBgkqhkiG9w0BAQUFADBF" + "MScwJQYDVQQKEx4gRElSRUNUSU9OIEdFTkVSQUxFIERFUyBJTVBPVFMxGjAYBgNV" + "BAMTESBBQyBNSU5FRkkgQiBURVNUMB4XDTA0MDUwNzEyMDAwMFoXDTE0MDUwNzEy" + "MDAwMFowRTEnMCUGA1UEChMeIERJUkVDVElPTiBHRU5FUkFMRSBERVMgSU1QT1RT" + "MRowGAYDVQQDExEgQUMgTUlORUZJIEIgVEVTVDCBnzANBgkqhkiG9w0BAQEFAAOB" + "jQAwgYkCgYEAveoCUOAukZdcFCs2qJk76vSqEX0ZFzHqQ6faBPZWjwkgUNwZ6m6m" + "qWvvyq1cuxhoDvpfC6NXILETawYc6MNwwxsOtVVIjuXlcF17NMejljJafbPximEt" + "DQ4LcQeSp4K7FyFlIAMLyt3BQ77emGzU5fjFTvHSUNb3jblx0sV28c0CAwEAAaOB" + "tTCBsjAfBgNVHSMEGDAWgBSEJ4bLbvEQY8cYMAFKPFD1/fFXlzAdBgNVHQ4EFgQU" + "hCeGy27xEGPHGDABSjxQ9f3xV5cwDgYDVR0PAQH/BAQDAgEGMBEGCWCGSAGG+EIB" + "AQQEAwIBBjA8BgNVHR8ENTAzMDGgL6AthitodHRwOi8vYWRvbmlzLnBrNy5jZXJ0" + "cGx1cy5uZXQvZGdpLXRlc3QuY3JsMA8GA1UdEwEB/wQFMAMBAf8wDQYJKoZIhvcN" + "AQEFBQADgYEAmToHJWjd3+4zknfsP09H6uMbolHNGG0zTS2lrLKpzcmkQfjhQpT9" + "LUTBvfs1jdjo9fGmQLvOG+Sm51Rbjglb8bcikVI5gLbclOlvqLkm77otjl4U4Z2/" + "Y0vP14Aov3Sn3k+17EfReYUZI4liuB95ncobC4e8ZM++LjQcIM0s+Vs="); byte[] gost34102001base = Base64.decode( "MIIB1DCCAYECEEjpVKXP6Wn1yVz3VeeDQa8wCgYGKoUDAgIDBQAwbTEfMB0G" + "A1UEAwwWR29zdFIzNDEwLTIwMDEgZXhhbXBsZTESMBAGA1UECgwJQ3J5cHRv" + "UHJvMQswCQYDVQQGEwJSVTEpMCcGCSqGSIb3DQEJARYaR29zdFIzNDEwLTIw" + "MDFAZXhhbXBsZS5jb20wHhcNMDUwMjAzMTUxNjQ2WhcNMTUwMjAzMTUxNjQ2" + "WjBtMR8wHQYDVQQDDBZHb3N0UjM0MTAtMjAwMSBleGFtcGxlMRIwEAYDVQQK" + "DAlDcnlwdG9Qcm8xCzAJBgNVBAYTAlJVMSkwJwYJKoZIhvcNAQkBFhpHb3N0" + "UjM0MTAtMjAwMUBleGFtcGxlLmNvbTBjMBwGBiqFAwICEzASBgcqhQMCAiQA" + "BgcqhQMCAh4BA0MABECElWh1YAIaQHUIzROMMYks/eUFA3pDXPRtKw/nTzJ+" + "V4/rzBa5lYgD0Jp8ha4P5I3qprt+VsfLsN8PZrzK6hpgMAoGBiqFAwICAwUA" + "A0EAHw5dw/aw/OiNvHyOE65kvyo4Hp0sfz3csM6UUkp10VO247ofNJK3tsLb" + "HOLjUaqzefrlGb11WpHYrvWFg+FcLA=="); byte[] gost341094base = Base64.decode( "MIICDzCCAbwCEBcxKsIb0ghYvAQeUjfQdFAwCgYGKoUDAgIEBQAwaTEdMBsG" + "A1UEAwwUR29zdFIzNDEwLTk0IGV4YW1wbGUxEjAQBgNVBAoMCUNyeXB0b1By" + "bzELMAkGA1UEBhMCUlUxJzAlBgkqhkiG9w0BCQEWGEdvc3RSMzQxMC05NEBl" + "eGFtcGxlLmNvbTAeFw0wNTAyMDMxNTE2NTFaFw0xNTAyMDMxNTE2NTFaMGkx" + "HTAbBgNVBAMMFEdvc3RSMzQxMC05NCBleGFtcGxlMRIwEAYDVQQKDAlDcnlw" + "dG9Qcm8xCzAJBgNVBAYTAlJVMScwJQYJKoZIhvcNAQkBFhhHb3N0UjM0MTAt" + "OTRAZXhhbXBsZS5jb20wgaUwHAYGKoUDAgIUMBIGByqFAwICIAIGByqFAwIC" + "HgEDgYQABIGAu4Rm4XmeWzTYLIB/E6gZZnFX/oxUJSFHbzALJ3dGmMb7R1W+" + "t7Lzk2w5tUI3JoTiDRCKJA4fDEJNKzsRK6i/ZjkyXJSLwaj+G2MS9gklh8x1" + "G/TliYoJgmjTXHemD7aQEBON4z58nJHWrA0ILD54wbXCtrcaqCqLRYGTMjJ2" + "+nswCgYGKoUDAgIEBQADQQBxKNhOmjgz/i5CEgLOyKyz9pFGkDcaymsWYQWV" + "v7CZ0pTM8IzMzkUBW3GHsUjCFpanFZDfg2zuN+3kT+694n9B"); byte[] gost341094A = Base64.decode( "MIICSDCCAfWgAwIBAgIBATAKBgYqhQMCAgQFADCBgTEXMBUGA1UEAxMOZGVmYXVsdDM0MTAtOTQx" + "DTALBgNVBAoTBERpZ3QxDzANBgNVBAsTBkNyeXB0bzEOMAwGA1UEBxMFWS1vbGExDDAKBgNVBAgT" + "A01FTDELMAkGA1UEBhMCcnUxGzAZBgkqhkiG9w0BCQEWDHRlc3RAdGVzdC5ydTAeFw0wNTAzMjkx" + "MzExNTdaFw0wNjAzMjkxMzExNTdaMIGBMRcwFQYDVQQDEw5kZWZhdWx0MzQxMC05NDENMAsGA1UE" + "ChMERGlndDEPMA0GA1UECxMGQ3J5cHRvMQ4wDAYDVQQHEwVZLW9sYTEMMAoGA1UECBMDTUVMMQsw" + "CQYDVQQGEwJydTEbMBkGCSqGSIb3DQEJARYMdGVzdEB0ZXN0LnJ1MIGlMBwGBiqFAwICFDASBgcq" + "hQMCAiACBgcqhQMCAh4BA4GEAASBgIQACDLEuxSdRDGgdZxHmy30g/DUYkRxO9Mi/uSHX5NjvZ31" + "b7JMEMFqBtyhql1HC5xZfUwZ0aT3UnEFDfFjLP+Bf54gA+LPkQXw4SNNGOj+klnqgKlPvoqMGlwa" + "+hLPKbS561WpvB2XSTgbV+pqqXR3j6j30STmybelEV3RdS2Now8wDTALBgNVHQ8EBAMCB4AwCgYG" + "KoUDAgIEBQADQQBCFy7xWRXtNVXflKvDs0pBdBuPzjCMeZAXVxK8vUxsxxKu76d9CsvhgIFknFRi" + "wWTPiZenvNoJ4R1uzeX+vREm"); byte[] gost341094B = Base64.decode( "MIICSDCCAfWgAwIBAgIBATAKBgYqhQMCAgQFADCBgTEXMBUGA1UEAxMOcGFyYW0xLTM0MTAtOTQx" + "DTALBgNVBAoTBERpZ3QxDzANBgNVBAsTBkNyeXB0bzEOMAwGA1UEBxMFWS1PbGExDDAKBgNVBAgT" + "A01lbDELMAkGA1UEBhMCcnUxGzAZBgkqhkiG9w0BCQEWDHRlc3RAdGVzdC5ydTAeFw0wNTAzMjkx" + "MzEzNTZaFw0wNjAzMjkxMzEzNTZaMIGBMRcwFQYDVQQDEw5wYXJhbTEtMzQxMC05NDENMAsGA1UE" + "ChMERGlndDEPMA0GA1UECxMGQ3J5cHRvMQ4wDAYDVQQHEwVZLU9sYTEMMAoGA1UECBMDTWVsMQsw" + "CQYDVQQGEwJydTEbMBkGCSqGSIb3DQEJARYMdGVzdEB0ZXN0LnJ1MIGlMBwGBiqFAwICFDASBgcq" + "hQMCAiADBgcqhQMCAh4BA4GEAASBgEa+AAcZmijWs1M9x5Pn9efE8D9ztG1NMoIt0/hNZNqln3+j" + "lMZjyqPt+kTLIjtmvz9BRDmIDk6FZz+4LhG2OTL7yGpWfrMxMRr56nxomTN9aLWRqbyWmn3brz9Y" + "AUD3ifnwjjIuW7UM84JNlDTOdxx0XRUfLQIPMCXe9cO02Xskow8wDTALBgNVHQ8EBAMCB4AwCgYG" + "KoUDAgIEBQADQQBzFcnuYc/639OTW+L5Ecjw9KxGr+dwex7lsS9S1BUgKa3m1d5c+cqI0B2XUFi5" + "4iaHHJG0dCyjtQYLJr0OZjRw"); byte[] gost34102001A = Base64.decode( "MIICCzCCAbigAwIBAgIBATAKBgYqhQMCAgMFADCBhDEaMBgGA1UEAxMRZGVmYXVsdC0zNDEwLTIw" + "MDExDTALBgNVBAoTBERpZ3QxDzANBgNVBAsTBkNyeXB0bzEOMAwGA1UEBxMFWS1PbGExDDAKBgNV" + "BAgTA01lbDELMAkGA1UEBhMCcnUxGzAZBgkqhkiG9w0BCQEWDHRlc3RAdGVzdC5ydTAeFw0wNTAz" + "MjkxMzE4MzFaFw0wNjAzMjkxMzE4MzFaMIGEMRowGAYDVQQDExFkZWZhdWx0LTM0MTAtMjAwMTEN" + "MAsGA1UEChMERGlndDEPMA0GA1UECxMGQ3J5cHRvMQ4wDAYDVQQHEwVZLU9sYTEMMAoGA1UECBMD" + "TWVsMQswCQYDVQQGEwJydTEbMBkGCSqGSIb3DQEJARYMdGVzdEB0ZXN0LnJ1MGMwHAYGKoUDAgIT" + "MBIGByqFAwICIwEGByqFAwICHgEDQwAEQG/4c+ZWb10IpeHfmR+vKcbpmSOClJioYmCVgnojw0Xn" + "ned0KTg7TJreRUc+VX7vca4hLQaZ1o/TxVtfEApK/O6jDzANMAsGA1UdDwQEAwIHgDAKBgYqhQMC" + "AgMFAANBAN8y2b6HuIdkD3aWujpfQbS1VIA/7hro4vLgDhjgVmev/PLzFB8oTh3gKhExpDo82IEs" + "ZftGNsbbyp1NFg7zda0="); byte[] gostCA1 = Base64.decode( "MIIDNDCCAuGgAwIBAgIQZLcKDcWcQopF+jp4p9jylDAKBgYqhQMCAgQFADBm" + "MQswCQYDVQQGEwJSVTEPMA0GA1UEBxMGTW9zY293MRcwFQYDVQQKEw5PT08g" + "Q3J5cHRvLVBybzEUMBIGA1UECxMLRGV2ZWxvcG1lbnQxFzAVBgNVBAMTDkNQ" + "IENTUCBUZXN0IENBMB4XDTAyMDYwOTE1NTIyM1oXDTA5MDYwOTE1NTkyOVow" + "ZjELMAkGA1UEBhMCUlUxDzANBgNVBAcTBk1vc2NvdzEXMBUGA1UEChMOT09P" + "IENyeXB0by1Qcm8xFDASBgNVBAsTC0RldmVsb3BtZW50MRcwFQYDVQQDEw5D" + "UCBDU1AgVGVzdCBDQTCBpTAcBgYqhQMCAhQwEgYHKoUDAgIgAgYHKoUDAgIe" + "AQOBhAAEgYAYglywKuz1nMc9UiBYOaulKy53jXnrqxZKbCCBSVaJ+aCKbsQm" + "glhRFrw6Mwu8Cdeabo/ojmea7UDMZd0U2xhZFRti5EQ7OP6YpqD0alllo7za" + "4dZNXdX+/ag6fOORSLFdMpVx5ganU0wHMPk67j+audnCPUj/plbeyccgcdcd" + "WaOCASIwggEeMAsGA1UdDwQEAwIBxjAPBgNVHRMBAf8EBTADAQH/MB0GA1Ud" + "DgQWBBTe840gTo4zt2twHilw3PD9wJaX0TCBygYDVR0fBIHCMIG/MDygOqA4" + "hjYtaHR0cDovL2ZpZXdhbGwvQ2VydEVucm9sbC9DUCUyMENTUCUyMFRlc3Ql" + "MjBDQSgzKS5jcmwwRKBCoECGPmh0dHA6Ly93d3cuY3J5cHRvcHJvLnJ1L0Nl" + "cnRFbnJvbGwvQ1AlMjBDU1AlMjBUZXN0JTIwQ0EoMykuY3JsMDmgN6A1hjMt" + "ZmlsZTovL1xcZmlld2FsbFxDZXJ0RW5yb2xsXENQIENTUCBUZXN0IENBKDMp" + "LmNybC8wEgYJKwYBBAGCNxUBBAUCAwMAAzAKBgYqhQMCAgQFAANBAIJi7ni7" + "9rwMR5rRGTFftt2k70GbqyUEfkZYOzrgdOoKiB4IIsIstyBX0/ne6GsL9Xan" + "G2IN96RB7KrowEHeW+k="); byte[] gostCA2 = Base64.decode( "MIIC2DCCAoWgAwIBAgIQe9ZCugm42pRKNcHD8466zTAKBgYqhQMCAgMFADB+" + "MRowGAYJKoZIhvcNAQkBFgtzYmFAZGlndC5ydTELMAkGA1UEBhMCUlUxDDAK" + "BgNVBAgTA01FTDEUMBIGA1UEBxMLWW9zaGthci1PbGExDTALBgNVBAoTBERp" + "Z3QxDzANBgNVBAsTBkNyeXB0bzEPMA0GA1UEAxMGc2JhLUNBMB4XDTA0MDgw" + "MzEzMzE1OVoXDTE0MDgwMzEzNDAxMVowfjEaMBgGCSqGSIb3DQEJARYLc2Jh" + "QGRpZ3QucnUxCzAJBgNVBAYTAlJVMQwwCgYDVQQIEwNNRUwxFDASBgNVBAcT" + "C1lvc2hrYXItT2xhMQ0wCwYDVQQKEwREaWd0MQ8wDQYDVQQLEwZDcnlwdG8x" + "DzANBgNVBAMTBnNiYS1DQTBjMBwGBiqFAwICEzASBgcqhQMCAiMBBgcqhQMC" + "Ah4BA0MABEDMSy10CuOH+i8QKG2UWA4XmCt6+BFrNTZQtS6bOalyDY8Lz+G7" + "HybyipE3PqdTB4OIKAAPsEEeZOCZd2UXGQm5o4HaMIHXMBMGCSsGAQQBgjcU" + "AgQGHgQAQwBBMAsGA1UdDwQEAwIBhjAPBgNVHRMBAf8EBTADAQH/MB0GA1Ud" + "DgQWBBRJJl3LcNMxkZI818STfoi3ng1xoDBxBgNVHR8EajBoMDGgL6Athito" + "dHRwOi8vc2JhLmRpZ3QubG9jYWwvQ2VydEVucm9sbC9zYmEtQ0EuY3JsMDOg" + "MaAvhi1maWxlOi8vXFxzYmEuZGlndC5sb2NhbFxDZXJ0RW5yb2xsXHNiYS1D" + "QS5jcmwwEAYJKwYBBAGCNxUBBAMCAQAwCgYGKoUDAgIDBQADQQA+BRJHbc/p" + "q8EYl6iJqXCuR+ozRmH7hPAP3c4KqYSC38TClCgBloLapx/3/WdatctFJW/L" + "mcTovpq088927shE"); byte[] inDirectCrl = Base64.decode( "MIIdXjCCHMcCAQEwDQYJKoZIhvcNAQEFBQAwdDELMAkGA1UEBhMCREUxHDAaBgNV" +"BAoUE0RldXRzY2hlIFRlbGVrb20gQUcxFzAVBgNVBAsUDlQtVGVsZVNlYyBUZXN0" +"MS4wDAYHAoIGAQoHFBMBMTAeBgNVBAMUF1QtVGVsZVNlYyBUZXN0IERJUiA4OlBO" +"Fw0wNjA4MDQwODQ1MTRaFw0wNjA4MDQxNDQ1MTRaMIIbfzB+AgQvrj/pFw0wMzA3" +"MjIwNTQxMjhaMGcwZQYDVR0dAQH/BFswWaRXMFUxCzAJBgNVBAYTAkRFMRwwGgYD" +"VQQKFBNEZXV0c2NoZSBUZWxla29tIEFHMSgwDAYHAoIGAQoHFBMBMTAYBgNVBAMU" +"EVNpZ0cgVGVzdCBDQSA0OlBOMH4CBC+uP+oXDTAzMDcyMjA1NDEyOFowZzBlBgNV" +"HR0BAf8EWzBZpFcwVTELMAkGA1UEBhMCREUxHDAaBgNVBAoUE0RldXRzY2hlIFRl" +"bGVrb20gQUcxKDAMBgcCggYBCgcUEwExMBgGA1UEAxQRU2lnRyBUZXN0IENBIDQ6" +"UE4wfgIEL64/5xcNMDQwNDA1MTMxODE3WjBnMGUGA1UdHQEB/wRbMFmkVzBVMQsw" +"CQYDVQQGEwJERTEcMBoGA1UEChQTRGV1dHNjaGUgVGVsZWtvbSBBRzEoMAwGBwKC" +"BgEKBxQTATEwGAYDVQQDFBFTaWdHIFRlc3QgQ0EgNDpQTjB+AgQvrj/oFw0wNDA0" +"MDUxMzE4MTdaMGcwZQYDVR0dAQH/BFswWaRXMFUxCzAJBgNVBAYTAkRFMRwwGgYD" +"VQQKFBNEZXV0c2NoZSBUZWxla29tIEFHMSgwDAYHAoIGAQoHFBMBMTAYBgNVBAMU" +"EVNpZ0cgVGVzdCBDQSA0OlBOMH4CBC+uP+UXDTAzMDExMzExMTgxMVowZzBlBgNV" +"HR0BAf8EWzBZpFcwVTELMAkGA1UEBhMCREUxHDAaBgNVBAoUE0RldXRzY2hlIFRl" +"bGVrb20gQUcxKDAMBgcCggYBCgcUEwExMBgGA1UEAxQRU2lnRyBUZXN0IENBIDQ6" +"UE4wfgIEL64/5hcNMDMwMTEzMTExODExWjBnMGUGA1UdHQEB/wRbMFmkVzBVMQsw" +"CQYDVQQGEwJERTEcMBoGA1UEChQTRGV1dHNjaGUgVGVsZWtvbSBBRzEoMAwGBwKC" +"BgEKBxQTATEwGAYDVQQDFBFTaWdHIFRlc3QgQ0EgNDpQTjB+AgQvrj/jFw0wMzAx" +"MTMxMTI2NTZaMGcwZQYDVR0dAQH/BFswWaRXMFUxCzAJBgNVBAYTAkRFMRwwGgYD" +"VQQKFBNEZXV0c2NoZSBUZWxla29tIEFHMSgwDAYHAoIGAQoHFBMBMTAYBgNVBAMU" +"EVNpZ0cgVGVzdCBDQSA0OlBOMH4CBC+uP+QXDTAzMDExMzExMjY1NlowZzBlBgNV" +"HR0BAf8EWzBZpFcwVTELMAkGA1UEBhMCREUxHDAaBgNVBAoUE0RldXRzY2hlIFRl" +"bGVrb20gQUcxKDAMBgcCggYBCgcUEwExMBgGA1UEAxQRU2lnRyBUZXN0IENBIDQ6" +"UE4wfgIEL64/4hcNMDQwNzEzMDc1ODM4WjBnMGUGA1UdHQEB/wRbMFmkVzBVMQsw" +"CQYDVQQGEwJERTEcMBoGA1UEChQTRGV1dHNjaGUgVGVsZWtvbSBBRzEoMAwGBwKC" +"BgEKBxQTATEwGAYDVQQDFBFTaWdHIFRlc3QgQ0EgNDpQTjB+AgQvrj/eFw0wMzAy" +"MTcwNjMzMjVaMGcwZQYDVR0dAQH/BFswWaRXMFUxCzAJBgNVBAYTAkRFMRwwGgYD" +"VQQKFBNEZXV0c2NoZSBUZWxla29tIEFHMSgwDAYHAoIGAQoHFBMBMTAYBgNVBAMU" +"EVNpZ0cgVGVzdCBDQSA0OlBOMH4CBC+uP98XDTAzMDIxNzA2MzMyNVowZzBlBgNV" +"HR0BAf8EWzBZpFcwVTELMAkGA1UEBhMCREUxHDAaBgNVBAoUE0RldXRzY2hlIFRl" +"bGVrb20gQUcxKDAMBgcCggYBCgcUEwExMBgGA1UEAxQRU2lnRyBUZXN0IENBIDQ6" +"UE4wfgIEL64/0xcNMDMwMjE3MDYzMzI1WjBnMGUGA1UdHQEB/wRbMFmkVzBVMQsw" +"CQYDVQQGEwJERTEcMBoGA1UEChQTRGV1dHNjaGUgVGVsZWtvbSBBRzEoMAwGBwKC" +"BgEKBxQTATEwGAYDVQQDFBFTaWdHIFRlc3QgQ0EgNDpQTjB+AgQvrj/dFw0wMzAx" +"MTMxMTI4MTRaMGcwZQYDVR0dAQH/BFswWaRXMFUxCzAJBgNVBAYTAkRFMRwwGgYD" +"VQQKFBNEZXV0c2NoZSBUZWxla29tIEFHMSgwDAYHAoIGAQoHFBMBMTAYBgNVBAMU" +"EVNpZ0cgVGVzdCBDQSA0OlBOMH4CBC+uP9cXDTAzMDExMzExMjcwN1owZzBlBgNV" +"HR0BAf8EWzBZpFcwVTELMAkGA1UEBhMCREUxHDAaBgNVBAoUE0RldXRzY2hlIFRl" +"bGVrb20gQUcxKDAMBgcCggYBCgcUEwExMBgGA1UEAxQRU2lnRyBUZXN0IENBIDQ6" +"UE4wfgIEL64/2BcNMDMwMTEzMTEyNzA3WjBnMGUGA1UdHQEB/wRbMFmkVzBVMQsw" +"CQYDVQQGEwJERTEcMBoGA1UEChQTRGV1dHNjaGUgVGVsZWtvbSBBRzEoMAwGBwKC" +"BgEKBxQTATEwGAYDVQQDFBFTaWdHIFRlc3QgQ0EgNDpQTjB+AgQvrj/VFw0wMzA0" +"MzAxMjI3NTNaMGcwZQYDVR0dAQH/BFswWaRXMFUxCzAJBgNVBAYTAkRFMRwwGgYD" +"VQQKFBNEZXV0c2NoZSBUZWxla29tIEFHMSgwDAYHAoIGAQoHFBMBMTAYBgNVBAMU" +"EVNpZ0cgVGVzdCBDQSA0OlBOMH4CBC+uP9YXDTAzMDQzMDEyMjc1M1owZzBlBgNV" +"HR0BAf8EWzBZpFcwVTELMAkGA1UEBhMCREUxHDAaBgNVBAoUE0RldXRzY2hlIFRl" +"bGVrb20gQUcxKDAMBgcCggYBCgcUEwExMBgGA1UEAxQRU2lnRyBUZXN0IENBIDQ6" +"UE4wfgIEL64/xhcNMDMwMjEyMTM0NTQwWjBnMGUGA1UdHQEB/wRbMFmkVzBVMQsw" +"CQYDVQQGEwJERTEcMBoGA1UEChQTRGV1dHNjaGUgVGVsZWtvbSBBRzEoMAwGBwKC" +"BgEKBxQTATEwGAYDVQQDFBFUVEMgVGVzdCBDQSAxMTpQTjCBkAIEL64/xRcNMDMw" +"MjEyMTM0NTQwWjB5MHcGA1UdHQEB/wRtMGukaTBnMQswCQYDVQQGEwJERTEcMBoG" +"A1UEChQTRGV1dHNjaGUgVGVsZWtvbSBBRzEQMA4GA1UECxQHVGVsZVNlYzEoMAwG" +"BwKCBgEKBxQTATEwGAYDVQQDFBFTaWdHIFRlc3QgQ0EgNTpQTjB+AgQvrj/CFw0w" +"MzAyMTIxMzA5MTZaMGcwZQYDVR0dAQH/BFswWaRXMFUxCzAJBgNVBAYTAkRFMRww" +"GgYDVQQKFBNEZXV0c2NoZSBUZWxla29tIEFHMSgwDAYHAoIGAQoHFBMBMTAYBgNV" +"BAMUEVRUQyBUZXN0IENBIDExOlBOMIGQAgQvrj/BFw0wMzAyMTIxMzA4NDBaMHkw" +"dwYDVR0dAQH/BG0wa6RpMGcxCzAJBgNVBAYTAkRFMRwwGgYDVQQKFBNEZXV0c2No" +"ZSBUZWxla29tIEFHMRAwDgYDVQQLFAdUZWxlU2VjMSgwDAYHAoIGAQoHFBMBMTAY" +"BgNVBAMUEVNpZ0cgVGVzdCBDQSA1OlBOMH4CBC+uP74XDTAzMDIxNzA2MzcyNVow" +"ZzBlBgNVHR0BAf8EWzBZpFcwVTELMAkGA1UEBhMCREUxHDAaBgNVBAoUE0RldXRz" +"Y2hlIFRlbGVrb20gQUcxKDAMBgcCggYBCgcUEwExMBgGA1UEAxQRVFRDIFRlc3Qg" +"Q0EgMTE6UE4wgZACBC+uP70XDTAzMDIxNzA2MzcyNVoweTB3BgNVHR0BAf8EbTBr" +"pGkwZzELMAkGA1UEBhMCREUxHDAaBgNVBAoUE0RldXRzY2hlIFRlbGVrb20gQUcx" +"EDAOBgNVBAsUB1RlbGVTZWMxKDAMBgcCggYBCgcUEwExMBgGA1UEAxQRU2lnRyBU" +"ZXN0IENBIDU6UE4wgZACBC+uP7AXDTAzMDIxMjEzMDg1OVoweTB3BgNVHR0BAf8E" +"bTBrpGkwZzELMAkGA1UEBhMCREUxHDAaBgNVBAoUE0RldXRzY2hlIFRlbGVrb20g" +"QUcxEDAOBgNVBAsUB1RlbGVTZWMxKDAMBgcCggYBCgcUEwExMBgGA1UEAxQRU2ln" +"RyBUZXN0IENBIDU6UE4wgZACBC+uP68XDTAzMDIxNzA2MzcyNVoweTB3BgNVHR0B" +"Af8EbTBrpGkwZzELMAkGA1UEBhMCREUxHDAaBgNVBAoUE0RldXRzY2hlIFRlbGVr" +"b20gQUcxEDAOBgNVBAsUB1RlbGVTZWMxKDAMBgcCggYBCgcUEwExMBgGA1UEAxQR" +"U2lnRyBUZXN0IENBIDU6UE4wfgIEL64/kxcNMDMwNDEwMDUyNjI4WjBnMGUGA1Ud" +"HQEB/wRbMFmkVzBVMQswCQYDVQQGEwJERTEcMBoGA1UEChQTRGV1dHNjaGUgVGVs" +"ZWtvbSBBRzEoMAwGBwKCBgEKBxQTATEwGAYDVQQDFBFUVEMgVGVzdCBDQSAxMTpQ" +"TjCBkAIEL64/khcNMDMwNDEwMDUyNjI4WjB5MHcGA1UdHQEB/wRtMGukaTBnMQsw" +"CQYDVQQGEwJERTEcMBoGA1UEChQTRGV1dHNjaGUgVGVsZWtvbSBBRzEQMA4GA1UE" +"CxQHVGVsZVNlYzEoMAwGBwKCBgEKBxQTATEwGAYDVQQDFBFTaWdHIFRlc3QgQ0Eg" +"NTpQTjB+AgQvrj8/Fw0wMzAyMjYxMTA0NDRaMGcwZQYDVR0dAQH/BFswWaRXMFUx" +"CzAJBgNVBAYTAkRFMRwwGgYDVQQKFBNEZXV0c2NoZSBUZWxla29tIEFHMSgwDAYH" +"AoIGAQoHFBMBMTAYBgNVBAMUEVRUQyBUZXN0IENBIDExOlBOMIGQAgQvrj8+Fw0w" +"MzAyMjYxMTA0NDRaMHkwdwYDVR0dAQH/BG0wa6RpMGcxCzAJBgNVBAYTAkRFMRww" +"GgYDVQQKFBNEZXV0c2NoZSBUZWxla29tIEFHMRAwDgYDVQQLFAdUZWxlU2VjMSgw" +"DAYHAoIGAQoHFBMBMTAYBgNVBAMUEVNpZ0cgVGVzdCBDQSA1OlBOMH4CBC+uPs0X" +"DTAzMDUyMDA1MjczNlowZzBlBgNVHR0BAf8EWzBZpFcwVTELMAkGA1UEBhMCREUx" +"HDAaBgNVBAoUE0RldXRzY2hlIFRlbGVrb20gQUcxKDAMBgcCggYBCgcUEwExMBgG" +"A1UEAxQRVFRDIFRlc3QgQ0EgMTE6UE4wgZACBC+uPswXDTAzMDUyMDA1MjczNlow" +"eTB3BgNVHR0BAf8EbTBrpGkwZzELMAkGA1UEBhMCREUxHDAaBgNVBAoUE0RldXRz" +"Y2hlIFRlbGVrb20gQUcxEDAOBgNVBAsUB1RlbGVTZWMxKDAMBgcCggYBCgcUEwEx" +"MBgGA1UEAxQRU2lnRyBUZXN0IENBIDY6UE4wfgIEL64+PBcNMDMwNjE3MTAzNDE2" +"WjBnMGUGA1UdHQEB/wRbMFmkVzBVMQswCQYDVQQGEwJERTEcMBoGA1UEChQTRGV1" +"dHNjaGUgVGVsZWtvbSBBRzEoMAwGBwKCBgEKBxQTATEwGAYDVQQDFBFUVEMgVGVz" +"dCBDQSAxMTpQTjCBkAIEL64+OxcNMDMwNjE3MTAzNDE2WjB5MHcGA1UdHQEB/wRt" +"MGukaTBnMQswCQYDVQQGEwJERTEcMBoGA1UEChQTRGV1dHNjaGUgVGVsZWtvbSBB" +"RzEQMA4GA1UECxQHVGVsZVNlYzEoMAwGBwKCBgEKBxQTATEwGAYDVQQDFBFTaWdH" +"IFRlc3QgQ0EgNjpQTjCBkAIEL64+OhcNMDMwNjE3MTAzNDE2WjB5MHcGA1UdHQEB" +"/wRtMGukaTBnMQswCQYDVQQGEwJERTEcMBoGA1UEChQTRGV1dHNjaGUgVGVsZWtv" +"bSBBRzEQMA4GA1UECxQHVGVsZVNlYzEoMAwGBwKCBgEKBxQTATEwGAYDVQQDFBFT" +"aWdHIFRlc3QgQ0EgNjpQTjB+AgQvrj45Fw0wMzA2MTcxMzAxMDBaMGcwZQYDVR0d" +"AQH/BFswWaRXMFUxCzAJBgNVBAYTAkRFMRwwGgYDVQQKFBNEZXV0c2NoZSBUZWxl" +"a29tIEFHMSgwDAYHAoIGAQoHFBMBMTAYBgNVBAMUEVRUQyBUZXN0IENBIDExOlBO" +"MIGQAgQvrj44Fw0wMzA2MTcxMzAxMDBaMHkwdwYDVR0dAQH/BG0wa6RpMGcxCzAJ" +"BgNVBAYTAkRFMRwwGgYDVQQKFBNEZXV0c2NoZSBUZWxla29tIEFHMRAwDgYDVQQL" +"FAdUZWxlU2VjMSgwDAYHAoIGAQoHFBMBMTAYBgNVBAMUEVNpZ0cgVGVzdCBDQSA2" +"OlBOMIGQAgQvrj43Fw0wMzA2MTcxMzAxMDBaMHkwdwYDVR0dAQH/BG0wa6RpMGcx" +"CzAJBgNVBAYTAkRFMRwwGgYDVQQKFBNEZXV0c2NoZSBUZWxla29tIEFHMRAwDgYD" +"VQQLFAdUZWxlU2VjMSgwDAYHAoIGAQoHFBMBMTAYBgNVBAMUEVNpZ0cgVGVzdCBD" +"QSA2OlBOMIGQAgQvrj42Fw0wMzA2MTcxMzAxMDBaMHkwdwYDVR0dAQH/BG0wa6Rp" +"MGcxCzAJBgNVBAYTAkRFMRwwGgYDVQQKFBNEZXV0c2NoZSBUZWxla29tIEFHMRAw" +"DgYDVQQLFAdUZWxlU2VjMSgwDAYHAoIGAQoHFBMBMTAYBgNVBAMUEVNpZ0cgVGVz" +"dCBDQSA2OlBOMIGQAgQvrj4zFw0wMzA2MTcxMDM3NDlaMHkwdwYDVR0dAQH/BG0w" +"a6RpMGcxCzAJBgNVBAYTAkRFMRwwGgYDVQQKFBNEZXV0c2NoZSBUZWxla29tIEFH" +"MRAwDgYDVQQLFAdUZWxlU2VjMSgwDAYHAoIGAQoHFBMBMTAYBgNVBAMUEVNpZ0cg" +"VGVzdCBDQSA2OlBOMH4CBC+uPjEXDTAzMDYxNzEwNDI1OFowZzBlBgNVHR0BAf8E" +"WzBZpFcwVTELMAkGA1UEBhMCREUxHDAaBgNVBAoUE0RldXRzY2hlIFRlbGVrb20g" +"QUcxKDAMBgcCggYBCgcUEwExMBgGA1UEAxQRVFRDIFRlc3QgQ0EgMTE6UE4wgZAC" +"BC+uPjAXDTAzMDYxNzEwNDI1OFoweTB3BgNVHR0BAf8EbTBrpGkwZzELMAkGA1UE" +"BhMCREUxHDAaBgNVBAoUE0RldXRzY2hlIFRlbGVrb20gQUcxEDAOBgNVBAsUB1Rl" +"bGVTZWMxKDAMBgcCggYBCgcUEwExMBgGA1UEAxQRU2lnRyBUZXN0IENBIDY6UE4w" +"gZACBC+uPakXDTAzMTAyMjExMzIyNFoweTB3BgNVHR0BAf8EbTBrpGkwZzELMAkG" +"A1UEBhMCREUxHDAaBgNVBAoUE0RldXRzY2hlIFRlbGVrb20gQUcxEDAOBgNVBAsU" +"B1RlbGVTZWMxKDAMBgcCggYBCgcUEwExMBgGA1UEAxQRU2lnRyBUZXN0IENBIDY6" +"UE4wgZACBC+uPLIXDTA1MDMxMTA2NDQyNFoweTB3BgNVHR0BAf8EbTBrpGkwZzEL" +"MAkGA1UEBhMCREUxHDAaBgNVBAoUE0RldXRzY2hlIFRlbGVrb20gQUcxEDAOBgNV" +"BAsUB1RlbGVTZWMxKDAMBgcCggYBCgcUEwExMBgGA1UEAxQRU2lnRyBUZXN0IENB" +"IDY6UE4wgZACBC+uPKsXDTA0MDQwMjA3NTQ1M1oweTB3BgNVHR0BAf8EbTBrpGkw" +"ZzELMAkGA1UEBhMCREUxHDAaBgNVBAoUE0RldXRzY2hlIFRlbGVrb20gQUcxEDAO" +"BgNVBAsUB1RlbGVTZWMxKDAMBgcCggYBCgcUEwExMBgGA1UEAxQRU2lnRyBUZXN0" +"IENBIDY6UE4wgZACBC+uOugXDTA1MDEyNzEyMDMyNFoweTB3BgNVHR0BAf8EbTBr" +"pGkwZzELMAkGA1UEBhMCREUxHDAaBgNVBAoUE0RldXRzY2hlIFRlbGVrb20gQUcx" +"EDAOBgNVBAsUB1RlbGVTZWMxKDAMBgcCggYBCgcUEwExMBgGA1UEAxQRU2lnRyBU" +"ZXN0IENBIDY6UE4wgZACBC+uOr4XDTA1MDIxNjA3NTcxNloweTB3BgNVHR0BAf8E" +"bTBrpGkwZzELMAkGA1UEBhMCREUxHDAaBgNVBAoUE0RldXRzY2hlIFRlbGVrb20g" +"QUcxEDAOBgNVBAsUB1RlbGVTZWMxKDAMBgcCggYBCgcUEwExMBgGA1UEAxQRU2ln" +"RyBUZXN0IENBIDY6UE4wgZACBC+uOqcXDTA1MDMxMDA1NTkzNVoweTB3BgNVHR0B" +"Af8EbTBrpGkwZzELMAkGA1UEBhMCREUxHDAaBgNVBAoUE0RldXRzY2hlIFRlbGVr" +"b20gQUcxEDAOBgNVBAsUB1RlbGVTZWMxKDAMBgcCggYBCgcUEwExMBgGA1UEAxQR" +"U2lnRyBUZXN0IENBIDY6UE4wgZACBC+uOjwXDTA1MDUxMTEwNDk0NloweTB3BgNV" +"HR0BAf8EbTBrpGkwZzELMAkGA1UEBhMCREUxHDAaBgNVBAoUE0RldXRzY2hlIFRl" +"bGVrb20gQUcxEDAOBgNVBAsUB1RlbGVTZWMxKDAMBgcCggYBCgcUEwExMBgGA1UE" +"AxQRU2lnRyBUZXN0IENBIDY6UE4wgaoCBC+sbdUXDTA1MTExMTEwMDMyMVowgZIw" +"gY8GA1UdHQEB/wSBhDCBgaR/MH0xCzAJBgNVBAYTAkRFMRwwGgYDVQQKFBNEZXV0" +"c2NoZSBUZWxla29tIEFHMR8wHQYDVQQLFBZQcm9kdWt0emVudHJ1bSBUZWxlU2Vj" +"MS8wDAYHAoIGAQoHFBMBMTAfBgNVBAMUGFRlbGVTZWMgUEtTIFNpZ0cgQ0EgMTpQ" +"TjCBlQIEL64uaBcNMDYwMTIzMTAyNTU1WjB+MHwGA1UdHQEB/wRyMHCkbjBsMQsw" +"CQYDVQQGEwJERTEcMBoGA1UEChQTRGV1dHNjaGUgVGVsZWtvbSBBRzEWMBQGA1UE" +"CxQNWmVudHJhbGUgQm9ubjEnMAwGBwKCBgEKBxQTATEwFwYDVQQDFBBUVEMgVGVz" +"dCBDQSA5OlBOMIGVAgQvribHFw0wNjA4MDEwOTQ4NDRaMH4wfAYDVR0dAQH/BHIw" +"cKRuMGwxCzAJBgNVBAYTAkRFMRwwGgYDVQQKFBNEZXV0c2NoZSBUZWxla29tIEFH" +"MRYwFAYDVQQLFA1aZW50cmFsZSBCb25uMScwDAYHAoIGAQoHFBMBMTAXBgNVBAMU" +"EFRUQyBUZXN0IENBIDk6UE6ggZswgZgwCwYDVR0UBAQCAhEMMB8GA1UdIwQYMBaA" +"FANbyNumDI9545HwlCF26NuOJC45MA8GA1UdHAEB/wQFMAOEAf8wVwYDVR0SBFAw" +"ToZMbGRhcDovL3Brc2xkYXAudHR0Yy5kZS9vdT1ULVRlbGVTZWMgVGVzdCBESVIg" +"ODpQTixvPURldXRzY2hlIFRlbGVrb20gQUcsYz1kZTANBgkqhkiG9w0BAQUFAAOB" +"gQBewL5gLFHpeOWO07Vk3Gg7pRDuAlvaovBH4coCyCWpk5jEhUfFSYEDuaQB7do4" +"IlJmeTHvkI0PIZWJ7bwQ2PVdipPWDx0NVwS/Cz5jUKiS3BbAmZQZOueiKLFpQq3A" +"b8aOHA7WHU4078/1lM+bgeu33Ln1CGykEbmSjA/oKPi/JA=="); byte[] directCRL = Base64.decode( "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" +"MQ=="); private final byte[] pkcs7CrlProblem = Base64.decode( "MIIwSAYJKoZIhvcNAQcCoIIwOTCCMDUCAQExCzAJBgUrDgMCGgUAMAsGCSqG" + "SIb3DQEHAaCCEsAwggP4MIIC4KADAgECAgF1MA0GCSqGSIb3DQEBBQUAMEUx" + "CzAJBgNVBAYTAlVTMRYwFAYDVQQKEw1HZW9UcnVzdCBJbmMuMR4wHAYDVQQD" + "ExVHZW9UcnVzdCBDQSBmb3IgQWRvYmUwHhcNMDQxMjAyMjEyNTM5WhcNMDYx" + "MjMwMjEyNTM5WjBMMQswCQYDVQQGEwJVUzEVMBMGA1UEChMMR2VvVHJ1c3Qg" + "SW5jMSYwJAYDVQQDEx1HZW9UcnVzdCBBZG9iZSBPQ1NQIFJlc3BvbmRlcjCB" + "nzANBgkqhkiG9w0BAQEFAAOBjQAwgYkCgYEA4gnNYhtw7U6QeVXZODnGhHMj" + "+OgZ0DB393rEk6a2q9kq129IA2e03yKBTfJfQR9aWKc2Qj90dsSqPjvTDHFG" + "Qsagm2FQuhnA3fb1UWhPzeEIdm6bxDsnQ8nWqKqxnWZzELZbdp3I9bBLizIq" + "obZovzt60LNMghn/unvvuhpeVSsCAwEAAaOCAW4wggFqMA4GA1UdDwEB/wQE" + "AwIE8DCB5QYDVR0gAQH/BIHaMIHXMIHUBgkqhkiG9y8BAgEwgcYwgZAGCCsG" + "AQUFBwICMIGDGoGAVGhpcyBjZXJ0aWZpY2F0ZSBoYXMgYmVlbiBpc3N1ZWQg" + "aW4gYWNjb3JkYW5jZSB3aXRoIHRoZSBBY3JvYmF0IENyZWRlbnRpYWxzIENQ" + "UyBsb2NhdGVkIGF0IGh0dHA6Ly93d3cuZ2VvdHJ1c3QuY29tL3Jlc291cmNl" + "cy9jcHMwMQYIKwYBBQUHAgEWJWh0dHA6Ly93d3cuZ2VvdHJ1c3QuY29tL3Jl" + "c291cmNlcy9jcHMwEwYDVR0lBAwwCgYIKwYBBQUHAwkwOgYDVR0fBDMwMTAv" + "oC2gK4YpaHR0cDovL2NybC5nZW90cnVzdC5jb20vY3Jscy9hZG9iZWNhMS5j" + "cmwwHwYDVR0jBBgwFoAUq4BZw2WDbR19E70Zw+wajw1HaqMwDQYJKoZIhvcN" + "AQEFBQADggEBAENJf1BD7PX5ivuaawt90q1OGzXpIQL/ClzEeFVmOIxqPc1E" + "TFRq92YuxG5b6+R+k+tGkmCwPLcY8ipg6ZcbJ/AirQhohzjlFuT6YAXsTfEj" + "CqEZfWM2sS7crK2EYxCMmKE3xDfPclYtrAoz7qZvxfQj0TuxHSstHZv39wu2" + "ZiG1BWiEcyDQyTgqTOXBoZmfJtshuAcXmTpgkrYSrS37zNlPTGh+pMYQ0yWD" + "c8OQRJR4OY5ZXfdna01mjtJTOmj6/6XPoLPYTq2gQrc2BCeNJ4bEhLb7sFVB" + "PbwPrpzTE/HRbQHDrzj0YimDxeOUV/UXctgvYwHNtEkcBLsOm/uytMYwggSh" + "MIIDiaADAgECAgQ+HL0oMA0GCSqGSIb3DQEBBQUAMGkxCzAJBgNVBAYTAlVT" + "MSMwIQYDVQQKExpBZG9iZSBTeXN0ZW1zIEluY29ycG9yYXRlZDEdMBsGA1UE" + "CxMUQWRvYmUgVHJ1c3QgU2VydmljZXMxFjAUBgNVBAMTDUFkb2JlIFJvb3Qg" + "Q0EwHhcNMDMwMTA4MjMzNzIzWhcNMjMwMTA5MDAwNzIzWjBpMQswCQYDVQQG" + "EwJVUzEjMCEGA1UEChMaQWRvYmUgU3lzdGVtcyBJbmNvcnBvcmF0ZWQxHTAb" + "BgNVBAsTFEFkb2JlIFRydXN0IFNlcnZpY2VzMRYwFAYDVQQDEw1BZG9iZSBS" + "b290IENBMIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEAzE9UhPen" + "ouczU38/nBKIayyZR2d+Dx65rRSI+cMQ2B3w8NWfaQovWTWwzGypTJwVoJ/O" + "IL+gz1Ti4CBmRT85hjh+nMSOByLGJPYBErA131XqaZCw24U3HuJOB7JCoWoT" + "aaBm6oCREVkqmwh5WiBELcm9cziLPC/gQxtdswvwrzUaKf7vppLdgUydPVmO" + "rTE8QH6bkTYG/OJcjdGNJtVcRc+vZT+xqtJilvSoOOq6YEL09BxKNRXO+E4i" + "Vg+VGMX4lp+f+7C3eCXpgGu91grwxnSUnfMPUNuad85LcIMjjaDKeCBEXDxU" + "ZPHqojAZn+pMBk0GeEtekt8i0slns3rSAQIDAQABo4IBTzCCAUswEQYJYIZI" + "AYb4QgEBBAQDAgAHMIGOBgNVHR8EgYYwgYMwgYCgfqB8pHoweDELMAkGA1UE" + "BhMCVVMxIzAhBgNVBAoTGkFkb2JlIFN5c3RlbXMgSW5jb3Jwb3JhdGVkMR0w" + "GwYDVQQLExRBZG9iZSBUcnVzdCBTZXJ2aWNlczEWMBQGA1UEAxMNQWRvYmUg" + "Um9vdCBDQTENMAsGA1UEAxMEQ1JMMTArBgNVHRAEJDAigA8yMDAzMDEwODIz" + "MzcyM1qBDzIwMjMwMTA5MDAwNzIzWjALBgNVHQ8EBAMCAQYwHwYDVR0jBBgw" + "FoAUgrc4SpOqmxDvgLvZVOLxD/uAnN4wHQYDVR0OBBYEFIK3OEqTqpsQ74C7" + "2VTi8Q/7gJzeMAwGA1UdEwQFMAMBAf8wHQYJKoZIhvZ9B0EABBAwDhsIVjYu" + "MDo0LjADAgSQMA0GCSqGSIb3DQEBBQUAA4IBAQAy2p9DdcH6b8lv26sdNjc+" + "vGEZNrcCPB0jWZhsnu5NhedUyCAfp9S74r8Ad30ka3AvXME6dkm10+AjhCpx" + "aiLzwScpmBX2NZDkBEzDjbyfYRzn/SSM0URDjBa6m02l1DUvvBHOvfdRN42f" + "kOQU8Rg/vulZEjX5M5LznuDVa5pxm5lLyHHD4bFhCcTl+pHwQjo3fTT5cujN" + "qmIcIenV9IIQ43sFti1oVgt+fpIsb01yggztVnSynbmrLSsdEF/bJ3Vwj/0d" + "1+ICoHnlHOX/r2RAUS2em0fbQqV8H8KmSLDXvpJpTaT2KVfFeBEY3IdRyhOy" + "Yp1PKzK9MaXB+lKrBYjIMIIEyzCCA7OgAwIBAgIEPhy9tTANBgkqhkiG9w0B" + "AQUFADBpMQswCQYDVQQGEwJVUzEjMCEGA1UEChMaQWRvYmUgU3lzdGVtcyBJ" + "bmNvcnBvcmF0ZWQxHTAbBgNVBAsTFEFkb2JlIFRydXN0IFNlcnZpY2VzMRYw" + "FAYDVQQDEw1BZG9iZSBSb290IENBMB4XDTA0MDExNzAwMDMzOVoXDTE1MDEx" + "NTA4MDAwMFowRTELMAkGA1UEBhMCVVMxFjAUBgNVBAoTDUdlb1RydXN0IElu" + "Yy4xHjAcBgNVBAMTFUdlb1RydXN0IENBIGZvciBBZG9iZTCCASIwDQYJKoZI" + "hvcNAQEBBQADggEPADCCAQoCggEBAKfld+BkeFrnOYW8r9L1WygTDlTdSfrO" + "YvWS/Z6Ye5/l+HrBbOHqQCXBcSeCpz7kB2WdKMh1FOE4e9JlmICsHerBLdWk" + "emU+/PDb69zh8E0cLoDfxukF6oVPXj6WSThdSG7H9aXFzRr6S3XGCuvgl+Qw" + "DTLiLYW+ONF6DXwt3TQQtKReJjOJZk46ZZ0BvMStKyBaeB6DKZsmiIo89qso" + "13VDZINH2w1KvXg0ygDizoNtbvgAPFymwnsINS1klfQlcvn0x0RJm9bYQXK3" + "5GNZAgL3M7Lqrld0jMfIUaWvuHCLyivytRuzq1dJ7E8rmidjDEk/G+27pf13" + "fNZ7vR7M+IkCAwEAAaOCAZ0wggGZMBIGA1UdEwEB/wQIMAYBAf8CAQEwUAYD" + "VR0gBEkwRzBFBgkqhkiG9y8BAgEwODA2BggrBgEFBQcCARYqaHR0cHM6Ly93" + "d3cuYWRvYmUuY29tL21pc2MvcGtpL2Nkc19jcC5odG1sMBQGA1UdJQQNMAsG" + "CSqGSIb3LwEBBTCBsgYDVR0fBIGqMIGnMCKgIKAehhxodHRwOi8vY3JsLmFk" + "b2JlLmNvbS9jZHMuY3JsMIGAoH6gfKR6MHgxCzAJBgNVBAYTAlVTMSMwIQYD" + "VQQKExpBZG9iZSBTeXN0ZW1zIEluY29ycG9yYXRlZDEdMBsGA1UECxMUQWRv" + "YmUgVHJ1c3QgU2VydmljZXMxFjAUBgNVBAMTDUFkb2JlIFJvb3QgQ0ExDTAL" + "BgNVBAMTBENSTDEwCwYDVR0PBAQDAgEGMB8GA1UdIwQYMBaAFIK3OEqTqpsQ" + "74C72VTi8Q/7gJzeMB0GA1UdDgQWBBSrgFnDZYNtHX0TvRnD7BqPDUdqozAZ" + "BgkqhkiG9n0HQQAEDDAKGwRWNi4wAwIEkDANBgkqhkiG9w0BAQUFAAOCAQEA" + "PzlZLqIAjrFeEWEs0uC29YyJhkXOE9mf3YSaFGsITF+Gl1j0pajTjyH4R35Q" + "r3floW2q3HfNzTeZ90Jnr1DhVERD6zEMgJpCtJqVuk0sixuXJHghS/KicKf4" + "YXJJPx9epuIRF1siBRnznnF90svmOJMXApc0jGnYn3nQfk4kaShSnDaYaeYR" + "DJKcsiWhl6S5zfwS7Gg8hDeyckhMQKKWnlG1CQrwlSFisKCduoodwRtWgft8" + "kx13iyKK3sbalm6vnVc+5nufS4vI+TwMXoV63NqYaSroafBWk0nL53zGXPEy" + "+A69QhzEViJKn2Wgqt5gt++jMMNImbRObIqgfgF1VjCCBUwwggQ0oAMCAQIC" + "AgGDMA0GCSqGSIb3DQEBBQUAMEUxCzAJBgNVBAYTAlVTMRYwFAYDVQQKEw1H" + "ZW9UcnVzdCBJbmMuMR4wHAYDVQQDExVHZW9UcnVzdCBDQSBmb3IgQWRvYmUw" + "HhcNMDYwMzI0MTU0MjI5WhcNMDkwNDA2MTQ0MjI5WjBzMQswCQYDVQQGEwJV" + "UzELMAkGA1UECBMCTUExETAPBgNVBAoTCEdlb1RydXN0MR0wGwYDVQQDExRN" + "YXJrZXRpbmcgRGVwYXJ0bWVudDElMCMGCSqGSIb3DQEJARYWbWFya2V0aW5n" + "QGdlb3RydXN0LmNvbTCCASIwDQYJKoZIhvcNAQEBBQADggEPADCCAQoCggEB" + "ANmvajTO4XJvAU2nVcLmXeCnAQX7RZt+7+ML3InmqQ3LCGo1weop09zV069/" + "1x/Nmieol7laEzeXxd2ghjGzwfXafqQEqHn6+vBCvqdNPoSi63fSWhnuDVWp" + "KVDOYgxOonrXl+Cc43lu4zRSq+Pi5phhrjDWcH74a3/rdljUt4c4GFezFXfa" + "w2oTzWkxj2cTSn0Szhpr17+p66UNt8uknlhmu4q44Speqql2HwmCEnpLYJrK" + "W3fOq5D4qdsvsLR2EABLhrBezamLI3iGV8cRHOUTsbTMhWhv/lKfHAyf4XjA" + "z9orzvPN5jthhIfICOFq/nStTgakyL4Ln+nFAB/SMPkCAwEAAaOCAhYwggIS" + "MA4GA1UdDwEB/wQEAwIF4DCB5QYDVR0gAQH/BIHaMIHXMIHUBgkqhkiG9y8B" + "AgEwgcYwgZAGCCsGAQUFBwICMIGDGoGAVGhpcyBjZXJ0aWZpY2F0ZSBoYXMg" + "YmVlbiBpc3N1ZWQgaW4gYWNjb3JkYW5jZSB3aXRoIHRoZSBBY3JvYmF0IENy" + "ZWRlbnRpYWxzIENQUyBsb2NhdGVkIGF0IGh0dHA6Ly93d3cuZ2VvdHJ1c3Qu" + "Y29tL3Jlc291cmNlcy9jcHMwMQYIKwYBBQUHAgEWJWh0dHA6Ly93d3cuZ2Vv" + "dHJ1c3QuY29tL3Jlc291cmNlcy9jcHMwOgYDVR0fBDMwMTAvoC2gK4YpaHR0" + "cDovL2NybC5nZW90cnVzdC5jb20vY3Jscy9hZG9iZWNhMS5jcmwwHwYDVR0j" + "BBgwFoAUq4BZw2WDbR19E70Zw+wajw1HaqMwRAYIKwYBBQUHAQEEODA2MDQG" + "CCsGAQUFBzABhihodHRwOi8vYWRvYmUtb2NzcC5nZW90cnVzdC5jb20vcmVz" + "cG9uZGVyMBQGA1UdJQQNMAsGCSqGSIb3LwEBBTA8BgoqhkiG9y8BAQkBBC4w" + "LAIBAYYnaHR0cDovL2Fkb2JlLXRpbWVzdGFtcC5nZW90cnVzdC5jb20vdHNh" + "MBMGCiqGSIb3LwEBCQIEBTADAgEBMAwGA1UdEwQFMAMCAQAwDQYJKoZIhvcN" + "AQEFBQADggEBAAOhy6QxOo+i3h877fvDvTa0plGD2bIqK7wMdNqbMDoSWied" + "FIcgcBOIm2wLxOjZBAVj/3lDq59q2rnVeNnfXM0/N0MHI9TumHRjU7WNk9e4" + "+JfJ4M+c3anrWOG3NE5cICDVgles+UHjXetHWql/LlP04+K2ZOLb6LE2xGnI" + "YyLW9REzCYNAVF+/WkYdmyceHtaBZdbyVAJq0NAJPsfgY1pWcBo31Mr1fpX9" + "WrXNTYDCqMyxMImJTmN3iI68tkXlNrhweQoArKFqBysiBkXzG/sGKYY6tWKU" + "pzjLc3vIp/LrXC5zilROes8BSvwu1w9qQrJNcGwo7O4uijoNtyYil1Exgh1Q" + "MIIdTAIBATBLMEUxCzAJBgNVBAYTAlVTMRYwFAYDVQQKEw1HZW9UcnVzdCBJ" + "bmMuMR4wHAYDVQQDExVHZW9UcnVzdCBDQSBmb3IgQWRvYmUCAgGDMAkGBSsO" + "AwIaBQCgggxMMBgGCSqGSIb3DQEJAzELBgkqhkiG9w0BBwEwIwYJKoZIhvcN" + "AQkEMRYEFP4R6qIdpQJzWyzrqO8X1ZfJOgChMIIMCQYJKoZIhvcvAQEIMYIL" + "+jCCC/agggZ5MIIGdTCCA6gwggKQMA0GCSqGSIb3DQEBBQUAMEUxCzAJBgNV" + "BAYTAlVTMRYwFAYDVQQKEw1HZW9UcnVzdCBJbmMuMR4wHAYDVQQDExVHZW9U" + "cnVzdCBDQSBmb3IgQWRvYmUXDTA2MDQwNDE3NDAxMFoXDTA2MDQwNTE3NDAx" + "MFowggIYMBMCAgC5Fw0wNTEwMTEyMDM2MzJaMBICAVsXDTA0MTEwNDE1MDk0" + "MVowEwICALgXDTA1MTIxMjIyMzgzOFowEgIBWhcNMDQxMTA0MTUwOTMzWjAT" + "AgIA5hcNMDUwODI3MDQwOTM4WjATAgIAtxcNMDYwMTE2MTc1NTEzWjATAgIA" + "hhcNMDUxMjEyMjIzODU1WjATAgIAtRcNMDUwNzA2MTgzODQwWjATAgIA4BcN" + "MDYwMzIwMDc0ODM0WjATAgIAgRcNMDUwODAyMjIzMTE1WjATAgIA3xcNMDUx" + "MjEyMjIzNjUwWjASAgFKFw0wNDExMDQxNTA5MTZaMBICAUQXDTA0MTEwNDE1" + "MDg1M1owEgIBQxcNMDQxMDAzMDEwMDQwWjASAgFsFw0wNDEyMDYxOTQ0MzFa" + "MBMCAgEoFw0wNjAzMDkxMjA3MTJaMBMCAgEkFw0wNjAxMTYxNzU1MzRaMBIC" + "AWcXDTA1MDMxODE3NTYxNFowEwICAVEXDTA2MDEzMTExMjcxMVowEgIBZBcN" + "MDQxMTExMjI0ODQxWjATAgIA8RcNMDUwOTE2MTg0ODAxWjATAgIBThcNMDYw" + "MjIxMjAxMDM2WjATAgIAwRcNMDUxMjEyMjIzODE2WjASAgFiFw0wNTAxMTAx" + "NjE5MzRaMBICAWAXDTA1MDExMDE5MDAwNFowEwICAL4XDTA1MDUxNzE0NTYx" + "MFowDQYJKoZIhvcNAQEFBQADggEBAEKhRMS3wVho1U3EvEQJZC8+JlUngmZQ" + "A78KQbHPWNZWFlNvPuf/b0s7Lu16GfNHXh1QAW6Y5Hi1YtYZ3YOPyMd4Xugt" + "gCdumbB6xtKsDyN5RvTht6ByXj+CYlYqsL7RX0izJZ6mJn4fjMkqzPKNOjb8" + "kSn5T6rn93BjlATtCE8tPVOM8dnqGccRE0OV59+nDBXc90UMt5LdEbwaUOap" + "snVB0oLcNm8d/HnlVH6RY5LnDjrT4vwfe/FApZtTecEWsllVUXDjSpwfcfD/" + "476/lpGySB2otALqzImlA9R8Ok3hJ8dnF6hhQ5Oe6OJMnGYgdhkKbxsKkdib" + "tTVl3qmH5QAwggLFMIIBrQIBATANBgkqhkiG9w0BAQUFADBpMQswCQYDVQQG" + "EwJVUzEjMCEGA1UEChMaQWRvYmUgU3lzdGVtcyBJbmNvcnBvcmF0ZWQxHTAb" + "BgNVBAsTFEFkb2JlIFRydXN0IFNlcnZpY2VzMRYwFAYDVQQDEw1BZG9iZSBS" + "b290IENBFw0wNjAxMjcxODMzMzFaFw0wNzAxMjcwMDAwMDBaMIHeMCMCBD4c" + "vUAXDTAzMDEyMTIzNDY1NlowDDAKBgNVHRUEAwoBBDAjAgQ+HL1BFw0wMzAx" + "MjEyMzQ3MjJaMAwwCgYDVR0VBAMKAQQwIwIEPhy9YhcNMDMwMTIxMjM0NzQy" + "WjAMMAoGA1UdFQQDCgEEMCMCBD4cvWEXDTA0MDExNzAxMDg0OFowDDAKBgNV" + "HRUEAwoBBDAjAgQ+HL2qFw0wNDAxMTcwMTA5MDVaMAwwCgYDVR0VBAMKAQQw" + "IwIEPhy9qBcNMDQwMTE3MDEzOTI5WjAMMAoGA1UdFQQDCgEEoC8wLTAKBgNV" + "HRQEAwIBDzAfBgNVHSMEGDAWgBSCtzhKk6qbEO+Au9lU4vEP+4Cc3jANBgkq" + "hkiG9w0BAQUFAAOCAQEAwtXF9042wG39icUlsotn5tpE3oCusLb/hBpEONhx" + "OdfEQOq0w5hf/vqaxkcf71etA+KpbEUeSVaHMHRPhx/CmPrO9odE139dJdbt" + "9iqbrC9iZokFK3h/es5kg73xujLKd7C/u5ngJ4mwBtvhMLjFjF2vJhPKHL4C" + "IgMwdaUAhrcNzy16v+mw/VGJy3Fvc6oCESW1K9tvFW58qZSNXrMlsuidgunM" + "hPKG+z0SXVyCqL7pnqKiaGddcgujYGOSY4S938oVcfZeZQEODtSYGlzldojX" + "C1U1hCK5+tHAH0Ox/WqRBIol5VCZQwJftf44oG8oviYq52aaqSejXwmfT6zb" + "76GCBXUwggVxMIIFbQoBAKCCBWYwggViBgkrBgEFBQcwAQEEggVTMIIFTzCB" + "taIWBBS+8EpykfXdl4h3z7m/NZfdkAQQERgPMjAwNjA0MDQyMDIwMTVaMGUw" + "YzA7MAkGBSsOAwIaBQAEFEb4BuZYkbjBjOjT6VeA/00fBvQaBBT3fTSQniOp" + "BbHBSkz4xridlX0bsAICAYOAABgPMjAwNjA0MDQyMDIwMTVaoBEYDzIwMDYw" + "NDA1MDgyMDE1WqEjMCEwHwYJKwYBBQUHMAECBBIEEFqooq/R2WltD7TposkT" + "BhMwDQYJKoZIhvcNAQEFBQADgYEAMig6lty4b0JDsT/oanfQG5x6jVKPACpp" + "1UA9SJ0apJJa7LeIdDFmu5C2S/CYiKZm4A4P9cAu0YzgLHxE4r6Op+HfVlAG" + "6bzUe1P/hi1KCJ8r8wxOZAktQFPSzs85RAZwkHMfB0lP2e/h666Oye+Zf8VH" + "RaE+/xZ7aswE89HXoumgggQAMIID/DCCA/gwggLgoAMCAQICAXUwDQYJKoZI" + "hvcNAQEFBQAwRTELMAkGA1UEBhMCVVMxFjAUBgNVBAoTDUdlb1RydXN0IElu" + "Yy4xHjAcBgNVBAMTFUdlb1RydXN0IENBIGZvciBBZG9iZTAeFw0wNDEyMDIy" + "MTI1MzlaFw0wNjEyMzAyMTI1MzlaMEwxCzAJBgNVBAYTAlVTMRUwEwYDVQQK" + "EwxHZW9UcnVzdCBJbmMxJjAkBgNVBAMTHUdlb1RydXN0IEFkb2JlIE9DU1Ag" + "UmVzcG9uZGVyMIGfMA0GCSqGSIb3DQEBAQUAA4GNADCBiQKBgQDiCc1iG3Dt" + "TpB5Vdk4OcaEcyP46BnQMHf3esSTprar2SrXb0gDZ7TfIoFN8l9BH1pYpzZC" + "P3R2xKo+O9MMcUZCxqCbYVC6GcDd9vVRaE/N4Qh2bpvEOydDydaoqrGdZnMQ" + "tlt2ncj1sEuLMiqhtmi/O3rQs0yCGf+6e++6Gl5VKwIDAQABo4IBbjCCAWow" + "DgYDVR0PAQH/BAQDAgTwMIHlBgNVHSABAf8EgdowgdcwgdQGCSqGSIb3LwEC" + "ATCBxjCBkAYIKwYBBQUHAgIwgYMagYBUaGlzIGNlcnRpZmljYXRlIGhhcyBi" + "ZWVuIGlzc3VlZCBpbiBhY2NvcmRhbmNlIHdpdGggdGhlIEFjcm9iYXQgQ3Jl" + "ZGVudGlhbHMgQ1BTIGxvY2F0ZWQgYXQgaHR0cDovL3d3dy5nZW90cnVzdC5j" + "b20vcmVzb3VyY2VzL2NwczAxBggrBgEFBQcCARYlaHR0cDovL3d3dy5nZW90" + "cnVzdC5jb20vcmVzb3VyY2VzL2NwczATBgNVHSUEDDAKBggrBgEFBQcDCTA6" + "BgNVHR8EMzAxMC+gLaArhilodHRwOi8vY3JsLmdlb3RydXN0LmNvbS9jcmxz" + "L2Fkb2JlY2ExLmNybDAfBgNVHSMEGDAWgBSrgFnDZYNtHX0TvRnD7BqPDUdq" + "ozANBgkqhkiG9w0BAQUFAAOCAQEAQ0l/UEPs9fmK+5prC33SrU4bNekhAv8K" + "XMR4VWY4jGo9zURMVGr3Zi7Eblvr5H6T60aSYLA8txjyKmDplxsn8CKtCGiH" + "OOUW5PpgBexN8SMKoRl9YzaxLtysrYRjEIyYoTfEN89yVi2sCjPupm/F9CPR" + "O7EdKy0dm/f3C7ZmIbUFaIRzINDJOCpM5cGhmZ8m2yG4BxeZOmCSthKtLfvM" + "2U9MaH6kxhDTJYNzw5BElHg5jlld92drTWaO0lM6aPr/pc+gs9hOraBCtzYE" + "J40nhsSEtvuwVUE9vA+unNMT8dFtAcOvOPRiKYPF45RX9Rdy2C9jAc20SRwE" + "uw6b+7K0xjANBgkqhkiG9w0BAQEFAASCAQC7a4yICFGCEMPlJbydK5qLG3rV" + "sip7Ojjz9TB4nLhC2DgsIHds8jjdq2zguInluH2nLaBCVS+qxDVlTjgbI2cB" + "TaWS8nglC7nNjzkKAsa8vThA8FZUVXTW0pb74jNJJU2AA27bb4g+4WgunCrj" + "fpYp+QjDyMmdrJVqRmt5eQN+dpVxMS9oq+NrhOSEhyIb4/rejgNg9wnVK1ms" + "l5PxQ4x7kpm7+Ua41//owkJVWykRo4T1jo4eHEz1DolPykAaKie2VKH/sMqR" + "Spjh4E5biKJLOV9fKivZWKAXByXfwUbbMsJvz4v/2yVHFy9xP+tqB5ZbRoDK" + "k8PzUyCprozn+/22oYIPijCCD4YGCyqGSIb3DQEJEAIOMYIPdTCCD3EGCSqG" + "SIb3DQEHAqCCD2Iwgg9eAgEDMQswCQYFKw4DAhoFADCB+gYLKoZIhvcNAQkQ" + "AQSggeoEgecwgeQCAQEGAikCMCEwCQYFKw4DAhoFAAQUoT97qeCv3FXYaEcS" + "gY8patCaCA8CAiMHGA8yMDA2MDQwNDIwMjA1N1owAwIBPAEB/wIIO0yRre3L" + "8/6ggZCkgY0wgYoxCzAJBgNVBAYTAlVTMRYwFAYDVQQIEw1NYXNzYWNodXNl" + "dHRzMRAwDgYDVQQHEwdOZWVkaGFtMRUwEwYDVQQKEwxHZW9UcnVzdCBJbmMx" + "EzARBgNVBAsTClByb2R1Y3Rpb24xJTAjBgNVBAMTHGFkb2JlLXRpbWVzdGFt" + "cC5nZW90cnVzdC5jb22gggzJMIIDUTCCAjmgAwIBAgICAI8wDQYJKoZIhvcN" + "AQEFBQAwRTELMAkGA1UEBhMCVVMxFjAUBgNVBAoTDUdlb1RydXN0IEluYy4x" + "HjAcBgNVBAMTFUdlb1RydXN0IENBIGZvciBBZG9iZTAeFw0wNTAxMTAwMTI5" + "MTBaFw0xNTAxMTUwODAwMDBaMIGKMQswCQYDVQQGEwJVUzEWMBQGA1UECBMN" + "TWFzc2FjaHVzZXR0czEQMA4GA1UEBxMHTmVlZGhhbTEVMBMGA1UEChMMR2Vv" + "VHJ1c3QgSW5jMRMwEQYDVQQLEwpQcm9kdWN0aW9uMSUwIwYDVQQDExxhZG9i" + "ZS10aW1lc3RhbXAuZ2VvdHJ1c3QuY29tMIGfMA0GCSqGSIb3DQEBAQUAA4GN" + "ADCBiQKBgQDRbxJotLFPWQuuEDhKtOMaBUJepGxIvWxeahMbq1DVmqnk88+j" + "w/5lfPICPzQZ1oHrcTLSAFM7Mrz3pyyQKQKMqUyiemzuG/77ESUNfBNSUfAF" + "PdtHuDMU8Is8ABVnFk63L+wdlvvDIlKkE08+VTKCRdjmuBVltMpQ6QcLFQzm" + "AQIDAQABo4GIMIGFMDoGA1UdHwQzMDEwL6AtoCuGKWh0dHA6Ly9jcmwuZ2Vv" + "dHJ1c3QuY29tL2NybHMvYWRvYmVjYTEuY3JsMB8GA1UdIwQYMBaAFKuAWcNl" + "g20dfRO9GcPsGo8NR2qjMA4GA1UdDwEB/wQEAwIGwDAWBgNVHSUBAf8EDDAK" + "BggrBgEFBQcDCDANBgkqhkiG9w0BAQUFAAOCAQEAmnyXjdtX+F79Nf0KggTd" + "6YC2MQD9s09IeXTd8TP3rBmizfM+7f3icggeCGakNfPRmIUMLoa0VM5Kt37T" + "2X0TqzBWusfbKx7HnX4v1t/G8NJJlT4SShSHv+8bjjU4lUoCmW2oEcC5vXwP" + "R5JfjCyois16npgcO05ZBT+LLDXyeBijE6qWmwLDfEpLyILzVRmyU4IE7jvm" + "rgb3GXwDUvd3yQXGRRHbPCh3nj9hBGbuzyt7GnlqnEie3wzIyMG2ET/wvTX5" + "4BFXKNe7lDLvZj/MXvd3V7gMTSVW0kAszKao56LfrVTgp1VX3UBQYwmQqaoA" + "UwFezih+jEvjW6cYJo/ErDCCBKEwggOJoAMCAQICBD4cvSgwDQYJKoZIhvcN" + "AQEFBQAwaTELMAkGA1UEBhMCVVMxIzAhBgNVBAoTGkFkb2JlIFN5c3RlbXMg" + "SW5jb3Jwb3JhdGVkMR0wGwYDVQQLExRBZG9iZSBUcnVzdCBTZXJ2aWNlczEW" + "MBQGA1UEAxMNQWRvYmUgUm9vdCBDQTAeFw0wMzAxMDgyMzM3MjNaFw0yMzAx" + "MDkwMDA3MjNaMGkxCzAJBgNVBAYTAlVTMSMwIQYDVQQKExpBZG9iZSBTeXN0" + "ZW1zIEluY29ycG9yYXRlZDEdMBsGA1UECxMUQWRvYmUgVHJ1c3QgU2Vydmlj" + "ZXMxFjAUBgNVBAMTDUFkb2JlIFJvb3QgQ0EwggEiMA0GCSqGSIb3DQEBAQUA" + "A4IBDwAwggEKAoIBAQDMT1SE96ei5zNTfz+cEohrLJlHZ34PHrmtFIj5wxDY" + "HfDw1Z9pCi9ZNbDMbKlMnBWgn84gv6DPVOLgIGZFPzmGOH6cxI4HIsYk9gES" + "sDXfVeppkLDbhTce4k4HskKhahNpoGbqgJERWSqbCHlaIEQtyb1zOIs8L+BD" + "G12zC/CvNRop/u+mkt2BTJ09WY6tMTxAfpuRNgb84lyN0Y0m1VxFz69lP7Gq" + "0mKW9Kg46rpgQvT0HEo1Fc74TiJWD5UYxfiWn5/7sLd4JemAa73WCvDGdJSd" + "8w9Q25p3zktwgyONoMp4IERcPFRk8eqiMBmf6kwGTQZ4S16S3yLSyWezetIB" + "AgMBAAGjggFPMIIBSzARBglghkgBhvhCAQEEBAMCAAcwgY4GA1UdHwSBhjCB" + "gzCBgKB+oHykejB4MQswCQYDVQQGEwJVUzEjMCEGA1UEChMaQWRvYmUgU3lz" + "dGVtcyBJbmNvcnBvcmF0ZWQxHTAbBgNVBAsTFEFkb2JlIFRydXN0IFNlcnZp" + "Y2VzMRYwFAYDVQQDEw1BZG9iZSBSb290IENBMQ0wCwYDVQQDEwRDUkwxMCsG" + "A1UdEAQkMCKADzIwMDMwMTA4MjMzNzIzWoEPMjAyMzAxMDkwMDA3MjNaMAsG" + "A1UdDwQEAwIBBjAfBgNVHSMEGDAWgBSCtzhKk6qbEO+Au9lU4vEP+4Cc3jAd" + "BgNVHQ4EFgQUgrc4SpOqmxDvgLvZVOLxD/uAnN4wDAYDVR0TBAUwAwEB/zAd" + "BgkqhkiG9n0HQQAEEDAOGwhWNi4wOjQuMAMCBJAwDQYJKoZIhvcNAQEFBQAD" + "ggEBADLan0N1wfpvyW/bqx02Nz68YRk2twI8HSNZmGye7k2F51TIIB+n1Lvi" + "vwB3fSRrcC9cwTp2SbXT4COEKnFqIvPBJymYFfY1kOQETMONvJ9hHOf9JIzR" + "REOMFrqbTaXUNS+8Ec6991E3jZ+Q5BTxGD++6VkSNfkzkvOe4NVrmnGbmUvI" + "ccPhsWEJxOX6kfBCOjd9NPly6M2qYhwh6dX0ghDjewW2LWhWC35+kixvTXKC" + "DO1WdLKduastKx0QX9sndXCP/R3X4gKgeeUc5f+vZEBRLZ6bR9tCpXwfwqZI" + "sNe+kmlNpPYpV8V4ERjch1HKE7JinU8rMr0xpcH6UqsFiMgwggTLMIIDs6AD" + "AgECAgQ+HL21MA0GCSqGSIb3DQEBBQUAMGkxCzAJBgNVBAYTAlVTMSMwIQYD" + "VQQKExpBZG9iZSBTeXN0ZW1zIEluY29ycG9yYXRlZDEdMBsGA1UECxMUQWRv" + "YmUgVHJ1c3QgU2VydmljZXMxFjAUBgNVBAMTDUFkb2JlIFJvb3QgQ0EwHhcN" + "MDQwMTE3MDAwMzM5WhcNMTUwMTE1MDgwMDAwWjBFMQswCQYDVQQGEwJVUzEW" + "MBQGA1UEChMNR2VvVHJ1c3QgSW5jLjEeMBwGA1UEAxMVR2VvVHJ1c3QgQ0Eg" + "Zm9yIEFkb2JlMIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEAp+V3" + "4GR4Wuc5hbyv0vVbKBMOVN1J+s5i9ZL9nph7n+X4esFs4epAJcFxJ4KnPuQH" + "ZZ0oyHUU4Th70mWYgKwd6sEt1aR6ZT788Nvr3OHwTRwugN/G6QXqhU9ePpZJ" + "OF1Ibsf1pcXNGvpLdcYK6+CX5DANMuIthb440XoNfC3dNBC0pF4mM4lmTjpl" + "nQG8xK0rIFp4HoMpmyaIijz2qyjXdUNkg0fbDUq9eDTKAOLOg21u+AA8XKbC" + "ewg1LWSV9CVy+fTHREmb1thBcrfkY1kCAvczsuquV3SMx8hRpa+4cIvKK/K1" + "G7OrV0nsTyuaJ2MMST8b7bul/Xd81nu9Hsz4iQIDAQABo4IBnTCCAZkwEgYD" + "VR0TAQH/BAgwBgEB/wIBATBQBgNVHSAESTBHMEUGCSqGSIb3LwECATA4MDYG" + "CCsGAQUFBwIBFipodHRwczovL3d3dy5hZG9iZS5jb20vbWlzYy9wa2kvY2Rz" + "X2NwLmh0bWwwFAYDVR0lBA0wCwYJKoZIhvcvAQEFMIGyBgNVHR8Egaowgacw" + "IqAgoB6GHGh0dHA6Ly9jcmwuYWRvYmUuY29tL2Nkcy5jcmwwgYCgfqB8pHow" + "eDELMAkGA1UEBhMCVVMxIzAhBgNVBAoTGkFkb2JlIFN5c3RlbXMgSW5jb3Jw" + "b3JhdGVkMR0wGwYDVQQLExRBZG9iZSBUcnVzdCBTZXJ2aWNlczEWMBQGA1UE" + "AxMNQWRvYmUgUm9vdCBDQTENMAsGA1UEAxMEQ1JMMTALBgNVHQ8EBAMCAQYw" + "HwYDVR0jBBgwFoAUgrc4SpOqmxDvgLvZVOLxD/uAnN4wHQYDVR0OBBYEFKuA" + "WcNlg20dfRO9GcPsGo8NR2qjMBkGCSqGSIb2fQdBAAQMMAobBFY2LjADAgSQ" + "MA0GCSqGSIb3DQEBBQUAA4IBAQA/OVkuogCOsV4RYSzS4Lb1jImGRc4T2Z/d" + "hJoUawhMX4aXWPSlqNOPIfhHflCvd+Whbarcd83NN5n3QmevUOFUREPrMQyA" + "mkK0mpW6TSyLG5ckeCFL8qJwp/hhckk/H16m4hEXWyIFGfOecX3Sy+Y4kxcC" + "lzSMadifedB+TiRpKFKcNphp5hEMkpyyJaGXpLnN/BLsaDyEN7JySExAopae" + "UbUJCvCVIWKwoJ26ih3BG1aB+3yTHXeLIorextqWbq+dVz7me59Li8j5PAxe" + "hXrc2phpKuhp8FaTScvnfMZc8TL4Dr1CHMRWIkqfZaCq3mC376Mww0iZtE5s" + "iqB+AXVWMYIBgDCCAXwCAQEwSzBFMQswCQYDVQQGEwJVUzEWMBQGA1UEChMN" + "R2VvVHJ1c3QgSW5jLjEeMBwGA1UEAxMVR2VvVHJ1c3QgQ0EgZm9yIEFkb2Jl" + "AgIAjzAJBgUrDgMCGgUAoIGMMBoGCSqGSIb3DQEJAzENBgsqhkiG9w0BCRAB" + "BDAcBgkqhkiG9w0BCQUxDxcNMDYwNDA0MjAyMDU3WjAjBgkqhkiG9w0BCQQx" + "FgQUp7AnXBqoNcarvO7fMJut1og2U5AwKwYLKoZIhvcNAQkQAgwxHDAaMBgw" + "FgQU1dH4eZTNhgxdiSABrat6zsPdth0wDQYJKoZIhvcNAQEBBQAEgYCinr/F" + "rMiQz/MRm9ZD5YGcC0Qo2dRTPd0Aop8mZ4g1xAhKFLnp7lLsjCbkSDpVLDBh" + "cnCk7CV+3FT5hlvt8OqZlR0CnkSnCswLFhrppiWle6cpxlwGqyAteC8uKtQu" + "wjE5GtBKLcCOAzQYyyuNZZeB6oCZ+3mPhZ62FxrvvEGJCgAAAAAAAAAAAAAA" + "AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA" + "AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA" + "AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA" + "AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA" + "AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA" + "AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA" + "AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA" + "AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA" + "AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA=="); private PublicKey dudPublicKey = new PublicKey() { public String getAlgorithm() { return null; } public String getFormat() { return null; } public byte[] getEncoded() { return null; } }; public String getName() { return "CertTest"; } public void checkCertificate( int id, byte[] bytes) { ByteArrayInputStream bIn; String dump = ""; try { bIn = new ByteArrayInputStream(bytes); CertificateFactory fact = CertificateFactory.getInstance("X.509", "BC"); Certificate cert = fact.generateCertificate(bIn); PublicKey k = cert.getPublicKey(); // System.out.println(cert); } catch (Exception e) { fail(dump + System.getProperty("line.separator") + getName() + ": "+ id + " failed - exception " + e.toString(), e); } } public void checkNameCertificate( int id, byte[] bytes) { ByteArrayInputStream bIn; String dump = ""; try { bIn = new ByteArrayInputStream(bytes); CertificateFactory fact = CertificateFactory.getInstance("X.509", "BC"); X509Certificate cert = (X509Certificate)fact.generateCertificate(bIn); PublicKey k = cert.getPublicKey(); if (!cert.getIssuerDN().toString().equals("C=DE,O=DATEV eG,0.2.262.1.10.7.20=1+CN=CA DATEV D03 1:PN")) { fail(id + " failed - name test."); } // System.out.println(cert); } catch (Exception e) { fail(dump + System.getProperty("line.separator") + getName() + ": "+ id + " failed - exception " + e.toString(), e); } } public void checkKeyUsage( int id, byte[] bytes) { ByteArrayInputStream bIn; String dump = ""; try { bIn = new ByteArrayInputStream(bytes); CertificateFactory fact = CertificateFactory.getInstance("X.509", "BC"); X509Certificate cert = (X509Certificate)fact.generateCertificate(bIn); PublicKey k = cert.getPublicKey(); if (cert.getKeyUsage()[7]) { fail("error generating cert - key usage wrong."); } // System.out.println(cert); } catch (Exception e) { fail(dump + System.getProperty("line.separator") + getName() + ": "+ id + " failed - exception " + e.toString(), e); } } public void checkSelfSignedCertificate( int id, byte[] bytes) { ByteArrayInputStream bIn; String dump = ""; try { bIn = new ByteArrayInputStream(bytes); CertificateFactory fact = CertificateFactory.getInstance("X.509", "BC"); Certificate cert = fact.generateCertificate(bIn); PublicKey k = cert.getPublicKey(); cert.verify(k); // System.out.println(cert); } catch (Exception e) { fail(dump + System.getProperty("line.separator") + getName() + ": "+ id + " failed - exception " + e.toString(), e); } } /** * we generate a self signed certificate for the sake of testing - RSA */ public void checkCreation1() throws Exception { // // a sample key pair. // RSAPublicKeySpec pubKeySpec = new RSAPublicKeySpec( new BigInteger("b4a7e46170574f16a97082b22be58b6a2a629798419be12872a4bdba626cfae9900f76abfb12139dce5de56564fab2b6543165a040c606887420e33d91ed7ed7", 16), new BigInteger("11", 16)); RSAPrivateCrtKeySpec privKeySpec = new RSAPrivateCrtKeySpec( new BigInteger("b4a7e46170574f16a97082b22be58b6a2a629798419be12872a4bdba626cfae9900f76abfb12139dce5de56564fab2b6543165a040c606887420e33d91ed7ed7", 16), new BigInteger("11", 16), new BigInteger("9f66f6b05410cd503b2709e88115d55daced94d1a34d4e32bf824d0dde6028ae79c5f07b580f5dce240d7111f7ddb130a7945cd7d957d1920994da389f490c89", 16), new BigInteger("c0a0758cdf14256f78d4708c86becdead1b50ad4ad6c5c703e2168fbf37884cb", 16), new BigInteger("f01734d7960ea60070f1b06f2bb81bfac48ff192ae18451d5e56c734a5aab8a5", 16), new BigInteger("b54bb9edff22051d9ee60f9351a48591b6500a319429c069a3e335a1d6171391", 16), new BigInteger("d3d83daf2a0cecd3367ae6f8ae1aeb82e9ac2f816c6fc483533d8297dd7884cd", 16), new BigInteger("b8f52fc6f38593dabb661d3f50f8897f8106eee68b1bce78a95b132b4e5b5d19", 16)); // // set up the keys // PrivateKey privKey; PublicKey pubKey; KeyFactory fact = KeyFactory.getInstance("RSA", "BC"); privKey = fact.generatePrivate(privKeySpec); pubKey = fact.generatePublic(pubKeySpec); // // distinguished name table. // Hashtable attrs = new Hashtable(); attrs.put(X509Principal.C, "AU"); attrs.put(X509Principal.O, "The Legion of the Bouncy Castle"); attrs.put(X509Principal.L, "Melbourne"); attrs.put(X509Principal.ST, "Victoria"); attrs.put(X509Principal.E, "feedback-crypto@bouncycastle.org"); Vector ord = new Vector(); Vector values = new Vector(); ord.addElement(X509Principal.C); ord.addElement(X509Principal.O); ord.addElement(X509Principal.L); ord.addElement(X509Principal.ST); ord.addElement(X509Principal.E); values.addElement("AU"); values.addElement("The Legion of the Bouncy Castle"); values.addElement("Melbourne"); values.addElement("Victoria"); values.addElement("feedback-crypto@bouncycastle.org"); // // extensions // // // create the certificate - version 3 - without extensions // X509V3CertificateGenerator certGen = new X509V3CertificateGenerator(); certGen.setSerialNumber(BigInteger.valueOf(1)); certGen.setIssuerDN(new X509Principal(attrs)); certGen.setNotBefore(new Date(System.currentTimeMillis() - 50000)); certGen.setNotAfter(new Date(System.currentTimeMillis() + 50000)); certGen.setSubjectDN(new X509Principal(attrs)); certGen.setPublicKey(pubKey); certGen.setSignatureAlgorithm("SHA256WithRSAEncryption"); X509Certificate cert = certGen.generate(privKey); cert.checkValidity(new Date()); cert.verify(pubKey); Set dummySet = cert.getNonCriticalExtensionOIDs(); if (dummySet != null) { fail("non-critical oid set should be null"); } dummySet = cert.getCriticalExtensionOIDs(); if (dummySet != null) { fail("critical oid set should be null"); } // // create the certificate - version 3 - with extensions // certGen = new X509V3CertificateGenerator(); certGen.setSerialNumber(BigInteger.valueOf(1)); certGen.setIssuerDN(new X509Principal(attrs)); certGen.setNotBefore(new Date(System.currentTimeMillis() - 50000)); certGen.setNotAfter(new Date(System.currentTimeMillis() + 50000)); certGen.setSubjectDN(new X509Principal(attrs)); certGen.setPublicKey(pubKey); certGen.setSignatureAlgorithm("MD5WithRSAEncryption"); certGen.addExtension("2.5.29.15", true, new X509KeyUsage(X509KeyUsage.encipherOnly)); certGen.addExtension("2.5.29.37", true, new DERSequence(KeyPurposeId.anyExtendedKeyUsage)); certGen.addExtension("2.5.29.17", true, new GeneralNames(new GeneralName(GeneralName.rfc822Name, "test@test.test"))); cert = certGen.generate(privKey); cert.checkValidity(new Date()); cert.verify(pubKey); ByteArrayInputStream sbIn = new ByteArrayInputStream(cert.getEncoded()); ASN1InputStream sdIn = new ASN1InputStream(sbIn); ByteArrayInputStream bIn = new ByteArrayInputStream(cert.getEncoded()); CertificateFactory certFact = CertificateFactory.getInstance("X.509", "BC"); cert = (X509Certificate)certFact.generateCertificate(bIn); if (!cert.getKeyUsage()[7]) { fail("error generating cert - key usage wrong."); } // System.out.println(cert); // // create the certificate - version 1 // X509V1CertificateGenerator certGen1 = new X509V1CertificateGenerator(); certGen1.setSerialNumber(BigInteger.valueOf(1)); certGen1.setIssuerDN(new X509Principal(ord, attrs)); certGen1.setNotBefore(new Date(System.currentTimeMillis() - 50000)); certGen1.setNotAfter(new Date(System.currentTimeMillis() + 50000)); certGen1.setSubjectDN(new X509Principal(ord, values)); certGen1.setPublicKey(pubKey); certGen1.setSignatureAlgorithm("MD5WithRSAEncryption"); cert = certGen1.generate(privKey); cert.checkValidity(new Date()); cert.verify(pubKey); bIn = new ByteArrayInputStream(cert.getEncoded()); certFact = CertificateFactory.getInstance("X.509", "BC"); cert = (X509Certificate)certFact.generateCertificate(bIn); // System.out.println(cert); if (!cert.getIssuerDN().equals(cert.getSubjectDN())) { fail("name comparison fails"); } } /** * we generate a self signed certificate for the sake of testing - DSA */ public void checkCreation2() { // // set up the keys // PrivateKey privKey; PublicKey pubKey; try { KeyPairGenerator g = KeyPairGenerator.getInstance("DSA", "SUN"); g.initialize(512, new SecureRandom()); KeyPair p = g.generateKeyPair(); privKey = p.getPrivate(); pubKey = p.getPublic(); } catch (Exception e) { fail("error setting up keys - " + e.toString()); return; } // // distinguished name table. // Hashtable attrs = new Hashtable(); attrs.put(X509Principal.C, "AU"); attrs.put(X509Principal.O, "The Legion of the Bouncy Castle"); attrs.put(X509Principal.L, "Melbourne"); attrs.put(X509Principal.ST, "Victoria"); attrs.put(X509Principal.E, "feedback-crypto@bouncycastle.org"); // // extensions // // // create the certificate - version 3 // X509V3CertificateGenerator certGen = new X509V3CertificateGenerator(); certGen.setSerialNumber(BigInteger.valueOf(1)); certGen.setIssuerDN(new X509Principal(attrs)); certGen.setNotBefore(new Date(System.currentTimeMillis() - 50000)); certGen.setNotAfter(new Date(System.currentTimeMillis() + 50000)); certGen.setSubjectDN(new X509Principal(attrs)); certGen.setPublicKey(pubKey); certGen.setSignatureAlgorithm("SHA1withDSA"); try { X509Certificate cert = certGen.generate(privKey); cert.checkValidity(new Date()); cert.verify(pubKey); ByteArrayInputStream bIn = new ByteArrayInputStream(cert.getEncoded()); CertificateFactory fact = CertificateFactory.getInstance("X.509", "BC"); cert = (X509Certificate)fact.generateCertificate(bIn); // System.out.println(cert); } catch (Exception e) { fail("error setting generating cert - " + e.toString()); } // // create the certificate - version 1 // X509V1CertificateGenerator certGen1 = new X509V1CertificateGenerator(); certGen1.setSerialNumber(BigInteger.valueOf(1)); certGen1.setIssuerDN(new X509Principal(attrs)); certGen1.setNotBefore(new Date(System.currentTimeMillis() - 50000)); certGen1.setNotAfter(new Date(System.currentTimeMillis() + 50000)); certGen1.setSubjectDN(new X509Principal(attrs)); certGen1.setPublicKey(pubKey); certGen1.setSignatureAlgorithm("SHA1withDSA"); try { X509Certificate cert = certGen1.generate(privKey); cert.checkValidity(new Date()); cert.verify(pubKey); ByteArrayInputStream bIn = new ByteArrayInputStream(cert.getEncoded()); CertificateFactory fact = CertificateFactory.getInstance("X.509", "BC"); cert = (X509Certificate)fact.generateCertificate(bIn); //System.out.println(cert); } catch (Exception e) { fail("error setting generating cert - " + e.toString()); } // // exception test // try { certGen.setPublicKey(dudPublicKey); fail("key without encoding not detected in v1"); } catch (IllegalArgumentException e) { // expected } } /** * we generate a self signed certificate for the sake of testing - ECDSA */ public void checkCreation3() { ECCurve curve = new ECCurve.Fp( new BigInteger("883423532389192164791648750360308885314476597252960362792450860609699839"), // q new BigInteger("7fffffffffffffffffffffff7fffffffffff8000000000007ffffffffffc", 16), // a new BigInteger("6b016c3bdcf18941d0d654921475ca71a9db2fb27d1d37796185c2942c0a", 16)); // b ECParameterSpec spec = new ECParameterSpec( curve, curve.decodePoint(Hex.decode("020ffa963cdca8816ccc33b8642bedf905c3d358573d3f27fbbd3b3cb9aaaf")), // G new BigInteger("883423532389192164791648750360308884807550341691627752275345424702807307")); // n ECPrivateKeySpec privKeySpec = new ECPrivateKeySpec( new BigInteger("876300101507107567501066130761671078357010671067781776716671676178726717"), // d spec); ECPublicKeySpec pubKeySpec = new ECPublicKeySpec( curve.decodePoint(Hex.decode("025b6dc53bc61a2548ffb0f671472de6c9521a9d2d2534e65abfcbd5fe0c70")), // Q spec); // // set up the keys // PrivateKey privKey; PublicKey pubKey; try { KeyFactory fact = KeyFactory.getInstance("ECDSA", "BC"); privKey = fact.generatePrivate(privKeySpec); pubKey = fact.generatePublic(pubKeySpec); } catch (Exception e) { fail("error setting up keys - " + e.toString()); return; } // // distinguished name table. // Hashtable attrs = new Hashtable(); Vector order = new Vector(); attrs.put(X509Principal.C, "AU"); attrs.put(X509Principal.O, "The Legion of the Bouncy Castle"); attrs.put(X509Principal.L, "Melbourne"); attrs.put(X509Principal.ST, "Victoria"); attrs.put(X509Principal.E, "feedback-crypto@bouncycastle.org"); order.addElement(X509Principal.C); order.addElement(X509Principal.O); order.addElement(X509Principal.L); order.addElement(X509Principal.ST); order.addElement(X509Principal.E); // // toString test // X509Principal p = new X509Principal(order, attrs); String s = p.toString(); if (!s.equals("C=AU,O=The Legion of the Bouncy Castle,L=Melbourne,ST=Victoria,E=feedback-crypto@bouncycastle.org")) { fail("ordered X509Principal test failed - s = " + s + "."); } p = new X509Principal(attrs); s = p.toString(); // // we need two of these as the hash code for strings changed... // if (!s.equals("O=The Legion of the Bouncy Castle,E=feedback-crypto@bouncycastle.org,ST=Victoria,L=Melbourne,C=AU") && !s.equals("ST=Victoria,L=Melbourne,C=AU,E=feedback-crypto@bouncycastle.org,O=The Legion of the Bouncy Castle")) { fail("unordered X509Principal test failed."); } // // create the certificate - version 3 // X509V3CertificateGenerator certGen = new X509V3CertificateGenerator(); certGen.setSerialNumber(BigInteger.valueOf(1)); certGen.setIssuerDN(new X509Principal(order, attrs)); certGen.setNotBefore(new Date(System.currentTimeMillis() - 50000)); certGen.setNotAfter(new Date(System.currentTimeMillis() + 50000)); certGen.setSubjectDN(new X509Principal(order, attrs)); certGen.setPublicKey(pubKey); certGen.setSignatureAlgorithm("SHA1withECDSA"); try { X509Certificate cert = certGen.generate(privKey); cert.checkValidity(new Date()); cert.verify(pubKey); ByteArrayInputStream bIn = new ByteArrayInputStream(cert.getEncoded()); CertificateFactory fact = CertificateFactory.getInstance("X.509", "BC"); cert = (X509Certificate)fact.generateCertificate(bIn); // // try with point compression turned off // ((ECPointEncoder)pubKey).setPointFormat("UNCOMPRESSED"); certGen.setPublicKey(pubKey); cert = certGen.generate(privKey, "BC"); cert.checkValidity(new Date()); cert.verify(pubKey); bIn = new ByteArrayInputStream(cert.getEncoded()); fact = CertificateFactory.getInstance("X.509", "BC"); cert = (X509Certificate)fact.generateCertificate(bIn); // System.out.println(cert); } catch (Exception e) { fail("error setting generating cert - " + e.toString()); } X509Principal pr = new X509Principal("O=\"The Bouncy Castle, The Legion of\",E=feedback-crypto@bouncycastle.org,ST=Victoria,L=Melbourne,C=AU"); if (!pr.toString().equals("O=The Bouncy Castle\\, The Legion of,E=feedback-crypto@bouncycastle.org,ST=Victoria,L=Melbourne,C=AU")) { fail("string based X509Principal test failed."); } pr = new X509Principal("O=The Bouncy Castle\\, The Legion of,E=feedback-crypto@bouncycastle.org,ST=Victoria,L=Melbourne,C=AU"); if (!pr.toString().equals("O=The Bouncy Castle\\, The Legion of,E=feedback-crypto@bouncycastle.org,ST=Victoria,L=Melbourne,C=AU")) { fail("string based X509Principal test failed."); } } /** * we generate a self signed certificate for the sake of testing - SHA224withECDSA */ private void createECCert(String algorithm, DERObjectIdentifier algOid) throws Exception { ECCurve.Fp curve = new ECCurve.Fp( new BigInteger("6864797660130609714981900799081393217269435300143305409394463459185543183397656052122559640661454554977296311391480858037121987999716643812574028291115057151"), // q (or p) new BigInteger("01FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFC", 16), // a new BigInteger("0051953EB9618E1C9A1F929A21A0B68540EEA2DA725B99B315F3B8B489918EF109E156193951EC7E937B1652C0BD3BB1BF073573DF883D2C34F1EF451FD46B503F00", 16)); // b ECParameterSpec spec = new ECParameterSpec( curve, curve.decodePoint(Hex.decode("0200C6858E06B70404E9CD9E3ECB662395B4429C648139053FB521F828AF606B4D3DBAA14B5E77EFE75928FE1DC127A2FFA8DE3348B3C1856A429BF97E7E31C2E5BD66")), // G new BigInteger("01FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFA51868783BF2F966B7FCC0148F709A5D03BB5C9B8899C47AEBB6FB71E91386409", 16)); // n ECPrivateKeySpec privKeySpec = new ECPrivateKeySpec( new BigInteger("5769183828869504557786041598510887460263120754767955773309066354712783118202294874205844512909370791582896372147797293913785865682804434049019366394746072023"), // d spec); ECPublicKeySpec pubKeySpec = new ECPublicKeySpec( curve.decodePoint(Hex.decode("02006BFDD2C9278B63C92D6624F151C9D7A822CC75BD983B17D25D74C26740380022D3D8FAF304781E416175EADF4ED6E2B47142D2454A7AC7801DD803CF44A4D1F0AC")), // Q spec); // // set up the keys // PrivateKey privKey; PublicKey pubKey; KeyFactory fact = KeyFactory.getInstance("ECDSA", "BC"); privKey = fact.generatePrivate(privKeySpec); pubKey = fact.generatePublic(pubKeySpec); // // distinguished name table. // Hashtable attrs = new Hashtable(); Vector order = new Vector(); attrs.put(X509Principal.C, "AU"); attrs.put(X509Principal.O, "The Legion of the Bouncy Castle"); attrs.put(X509Principal.L, "Melbourne"); attrs.put(X509Principal.ST, "Victoria"); attrs.put(X509Principal.E, "feedback-crypto@bouncycastle.org"); order.addElement(X509Principal.C); order.addElement(X509Principal.O); order.addElement(X509Principal.L); order.addElement(X509Principal.ST); order.addElement(X509Principal.E); // // create the certificate - version 3 // X509V3CertificateGenerator certGen = new X509V3CertificateGenerator(); certGen.setSerialNumber(BigInteger.valueOf(1)); certGen.setIssuerDN(new X509Principal(order, attrs)); certGen.setNotBefore(new Date(System.currentTimeMillis() - 50000)); certGen.setNotAfter(new Date(System.currentTimeMillis() + 50000)); certGen.setSubjectDN(new X509Principal(order, attrs)); certGen.setPublicKey(pubKey); certGen.setSignatureAlgorithm(algorithm); X509Certificate cert = certGen.generate(privKey, "BC"); cert.checkValidity(new Date()); cert.verify(pubKey); ByteArrayInputStream bIn = new ByteArrayInputStream(cert.getEncoded()); CertificateFactory certFact = CertificateFactory.getInstance("X.509", "BC"); cert = (X509Certificate)certFact.generateCertificate(bIn); // // try with point compression turned off // ((ECPointEncoder)pubKey).setPointFormat("UNCOMPRESSED"); certGen.setPublicKey(pubKey); cert = certGen.generate(privKey, "BC"); cert.checkValidity(new Date()); cert.verify(pubKey); bIn = new ByteArrayInputStream(cert.getEncoded()); certFact = CertificateFactory.getInstance("X.509", "BC"); cert = (X509Certificate)certFact.generateCertificate(bIn); if (!cert.getSigAlgOID().equals(algOid.toString())) { fail("ECDSA oid incorrect."); } if (cert.getSigAlgParams() != null) { fail("sig parameters present"); } Signature sig = Signature.getInstance(algorithm, "BC"); sig.initVerify(pubKey); sig.update(cert.getTBSCertificate()); if (!sig.verify(cert.getSignature())) { fail("EC certificate signature not mapped correctly."); } // System.out.println(cert); } private void checkCRL( int id, byte[] bytes) { ByteArrayInputStream bIn; String dump = ""; try { bIn = new ByteArrayInputStream(bytes); CertificateFactory fact = CertificateFactory.getInstance("X.509", "BC"); CRL cert = fact.generateCRL(bIn); // System.out.println(cert); } catch (Exception e) { fail(dump + System.getProperty("line.separator") + getName() + ": "+ id + " failed - exception " + e.toString(), e); } } public void checkCRLCreation1() throws Exception { KeyPairGenerator kpGen = KeyPairGenerator.getInstance("RSA", "BC"); X509V2CRLGenerator crlGen = new X509V2CRLGenerator(); Date now = new Date(); KeyPair pair = kpGen.generateKeyPair(); crlGen.setIssuerDN(new X509Principal("CN=Test CA")); crlGen.setThisUpdate(now); crlGen.setNextUpdate(new Date(now.getTime() + 100000)); crlGen.setSignatureAlgorithm("SHA256WithRSAEncryption"); crlGen.addCRLEntry(BigInteger.ONE, now, CRLReason.privilegeWithdrawn); crlGen.addExtension(X509Extensions.AuthorityKeyIdentifier, false, new AuthorityKeyIdentifierStructure(pair.getPublic())); X509CRL crl = crlGen.generate(pair.getPrivate(), "BC"); if (!crl.getIssuerDN().equals(new X509Principal("CN=Test CA"))) { fail("failed CRL issuer test"); } byte[] authExt = crl.getExtensionValue(X509Extensions.AuthorityKeyIdentifier.getId()); if (authExt == null) { fail("failed to find CRL extension"); } AuthorityKeyIdentifier authId = new AuthorityKeyIdentifierStructure(authExt); X509CRLEntry entry = crl.getRevokedCertificate(BigInteger.ONE); if (entry == null) { fail("failed to find CRL entry"); } if (!entry.getSerialNumber().equals(BigInteger.ONE)) { fail("CRL cert serial number does not match"); } if (!entry.hasExtensions()) { fail("CRL entry extension not found"); } byte[] ext = entry.getExtensionValue(X509Extensions.ReasonCode.getId()); if (ext != null) { DEREnumerated reasonCode = (DEREnumerated)X509ExtensionUtil.fromExtensionValue(ext); if (reasonCode.getValue().intValue() != CRLReason.privilegeWithdrawn) { fail("CRL entry reasonCode wrong"); } } else { fail("CRL entry reasonCode not found"); } } public void checkCRLCreation2() throws Exception { KeyPairGenerator kpGen = KeyPairGenerator.getInstance("RSA", "BC"); X509V2CRLGenerator crlGen = new X509V2CRLGenerator(); Date now = new Date(); KeyPair pair = kpGen.generateKeyPair(); crlGen.setIssuerDN(new X509Principal("CN=Test CA")); crlGen.setThisUpdate(now); crlGen.setNextUpdate(new Date(now.getTime() + 100000)); crlGen.setSignatureAlgorithm("SHA256WithRSAEncryption"); Vector extOids = new Vector(); Vector extValues = new Vector(); CRLReason crlReason = CRLReason.lookup(CRLReason.privilegeWithdrawn); try { extOids.addElement(X509Extensions.ReasonCode); extValues.addElement(new X509Extension(false, new DEROctetString(crlReason.getEncoded()))); } catch (IOException e) { throw new IllegalArgumentException("error encoding reason: " + e); } X509Extensions entryExtensions = new X509Extensions(extOids, extValues); crlGen.addCRLEntry(BigInteger.ONE, now, entryExtensions); crlGen.addExtension(X509Extensions.AuthorityKeyIdentifier, false, new AuthorityKeyIdentifierStructure(pair.getPublic())); X509CRL crl = crlGen.generate(pair.getPrivate(), "BC"); if (!crl.getIssuerDN().equals(new X509Principal("CN=Test CA"))) { fail("failed CRL issuer test"); } byte[] authExt = crl.getExtensionValue(X509Extensions.AuthorityKeyIdentifier.getId()); if (authExt == null) { fail("failed to find CRL extension"); } AuthorityKeyIdentifier authId = new AuthorityKeyIdentifierStructure(authExt); X509CRLEntry entry = crl.getRevokedCertificate(BigInteger.ONE); if (entry == null) { fail("failed to find CRL entry"); } if (!entry.getSerialNumber().equals(BigInteger.ONE)) { fail("CRL cert serial number does not match"); } if (!entry.hasExtensions()) { fail("CRL entry extension not found"); } byte[] ext = entry.getExtensionValue(X509Extensions.ReasonCode.getId()); if (ext != null) { DEREnumerated reasonCode = (DEREnumerated)X509ExtensionUtil.fromExtensionValue(ext); if (reasonCode.getValue().intValue() != CRLReason.privilegeWithdrawn) { fail("CRL entry reasonCode wrong"); } } else { fail("CRL entry reasonCode not found"); } } public void checkCRLCreation3() throws Exception { KeyPairGenerator kpGen = KeyPairGenerator.getInstance("RSA", "BC"); X509V2CRLGenerator crlGen = new X509V2CRLGenerator(); Date now = new Date(); KeyPair pair = kpGen.generateKeyPair(); crlGen.setIssuerDN(new X509Principal("CN=Test CA")); crlGen.setThisUpdate(now); crlGen.setNextUpdate(new Date(now.getTime() + 100000)); crlGen.setSignatureAlgorithm("SHA256WithRSAEncryption"); Vector extOids = new Vector(); Vector extValues = new Vector(); CRLReason crlReason = CRLReason.lookup(CRLReason.privilegeWithdrawn); try { extOids.addElement(X509Extensions.ReasonCode); extValues.addElement(new X509Extension(false, new DEROctetString(crlReason.getEncoded()))); } catch (IOException e) { throw new IllegalArgumentException("error encoding reason: " + e); } X509Extensions entryExtensions = new X509Extensions(extOids, extValues); crlGen.addCRLEntry(BigInteger.ONE, now, entryExtensions); crlGen.addExtension(X509Extensions.AuthorityKeyIdentifier, false, new AuthorityKeyIdentifierStructure(pair.getPublic())); X509CRL crl = crlGen.generate(pair.getPrivate(), "BC"); if (!crl.getIssuerDN().equals(new X509Principal("CN=Test CA"))) { fail("failed CRL issuer test"); } byte[] authExt = crl.getExtensionValue(X509Extensions.AuthorityKeyIdentifier.getId()); if (authExt == null) { fail("failed to find CRL extension"); } AuthorityKeyIdentifier authId = new AuthorityKeyIdentifierStructure(authExt); X509CRLEntry entry = crl.getRevokedCertificate(BigInteger.ONE); if (entry == null) { fail("failed to find CRL entry"); } if (!entry.getSerialNumber().equals(BigInteger.ONE)) { fail("CRL cert serial number does not match"); } if (!entry.hasExtensions()) { fail("CRL entry extension not found"); } byte[] ext = entry.getExtensionValue(X509Extensions.ReasonCode.getId()); if (ext != null) { DEREnumerated reasonCode = (DEREnumerated)X509ExtensionUtil.fromExtensionValue(ext); if (reasonCode.getValue().intValue() != CRLReason.privilegeWithdrawn) { fail("CRL entry reasonCode wrong"); } } else { fail("CRL entry reasonCode not found"); } // // check loading of existing CRL // crlGen = new X509V2CRLGenerator(); now = new Date(); crlGen.setIssuerDN(new X509Principal("CN=Test CA")); crlGen.setThisUpdate(now); crlGen.setNextUpdate(new Date(now.getTime() + 100000)); crlGen.setSignatureAlgorithm("SHA256WithRSAEncryption"); crlGen.addCRL(crl); crlGen.addCRLEntry(BigInteger.valueOf(2), now, entryExtensions); crlGen.addExtension(X509Extensions.AuthorityKeyIdentifier, false, new AuthorityKeyIdentifierStructure(pair.getPublic())); X509CRL newCrl = crlGen.generate(pair.getPrivate(), "BC"); int count = 0; boolean oneFound = false; boolean twoFound = false; Iterator it = newCrl.getRevokedCertificates().iterator(); while (it.hasNext()) { X509CRLEntry crlEnt = (X509CRLEntry)it.next(); if (crlEnt.getSerialNumber().intValue() == 1) { oneFound = true; } else if (crlEnt.getSerialNumber().intValue() == 2) { twoFound = true; } count++; } if (count != 2) { fail("wrong number of CRLs found"); } if (!oneFound || !twoFound) { fail("wrong CRLs found in copied list"); } // // check factory read back // CertificateFactory cFact = CertificateFactory.getInstance("X.509", "BC"); X509CRL readCrl = (X509CRL)cFact.generateCRL(new ByteArrayInputStream(newCrl.getEncoded())); if (readCrl == null) { fail("crl not returned!"); } Collection col = cFact.generateCRLs(new ByteArrayInputStream(newCrl.getEncoded())); if (col.size() != 1) { fail("wrong number of CRLs found in collection"); } } /** * we generate a self signed certificate for the sake of testing - GOST3410 */ public void checkCreation4() throws Exception { // // set up the keys // PrivateKey privKey; PublicKey pubKey; KeyPairGenerator g = KeyPairGenerator.getInstance("GOST3410", "BC"); GOST3410ParameterSpec gost3410P = new GOST3410ParameterSpec("GostR3410-94-CryptoPro-A"); g.initialize(gost3410P, new SecureRandom()); KeyPair p = g.generateKeyPair(); privKey = p.getPrivate(); pubKey = p.getPublic(); // // distinguished name table. // Hashtable attrs = new Hashtable(); attrs.put(X509Principal.C, "AU"); attrs.put(X509Principal.O, "The Legion of the Bouncy Castle"); attrs.put(X509Principal.L, "Melbourne"); attrs.put(X509Principal.ST, "Victoria"); attrs.put(X509Principal.E, "feedback-crypto@bouncycastle.org"); // // extensions // // // create the certificate - version 3 // X509V3CertificateGenerator certGen = new X509V3CertificateGenerator(); certGen.setSerialNumber(BigInteger.valueOf(1)); certGen.setIssuerDN(new X509Principal(attrs)); certGen.setNotBefore(new Date(System.currentTimeMillis() - 50000)); certGen.setNotAfter(new Date(System.currentTimeMillis() + 50000)); certGen.setSubjectDN(new X509Principal(attrs)); certGen.setPublicKey(pubKey); certGen.setSignatureAlgorithm("GOST3411withGOST3410"); X509Certificate cert = certGen.generate(privKey, "BC"); cert.checkValidity(new Date()); // // check verifies in general // cert.verify(pubKey); // // check verifies with contained key // cert.verify(cert.getPublicKey()); ByteArrayInputStream bIn = new ByteArrayInputStream(cert.getEncoded()); CertificateFactory fact = CertificateFactory.getInstance("X.509", "BC"); cert = (X509Certificate)fact.generateCertificate(bIn); //System.out.println(cert); //check getEncoded() byte[] bytesch = cert.getEncoded(); } public void checkCreation5() throws Exception { // // a sample key pair. // RSAPublicKeySpec pubKeySpec = new RSAPublicKeySpec( new BigInteger("b4a7e46170574f16a97082b22be58b6a2a629798419be12872a4bdba626cfae9900f76abfb12139dce5de56564fab2b6543165a040c606887420e33d91ed7ed7", 16), new BigInteger("11", 16)); RSAPrivateCrtKeySpec privKeySpec = new RSAPrivateCrtKeySpec( new BigInteger("b4a7e46170574f16a97082b22be58b6a2a629798419be12872a4bdba626cfae9900f76abfb12139dce5de56564fab2b6543165a040c606887420e33d91ed7ed7", 16), new BigInteger("11", 16), new BigInteger("9f66f6b05410cd503b2709e88115d55daced94d1a34d4e32bf824d0dde6028ae79c5f07b580f5dce240d7111f7ddb130a7945cd7d957d1920994da389f490c89", 16), new BigInteger("c0a0758cdf14256f78d4708c86becdead1b50ad4ad6c5c703e2168fbf37884cb", 16), new BigInteger("f01734d7960ea60070f1b06f2bb81bfac48ff192ae18451d5e56c734a5aab8a5", 16), new BigInteger("b54bb9edff22051d9ee60f9351a48591b6500a319429c069a3e335a1d6171391", 16), new BigInteger("d3d83daf2a0cecd3367ae6f8ae1aeb82e9ac2f816c6fc483533d8297dd7884cd", 16), new BigInteger("b8f52fc6f38593dabb661d3f50f8897f8106eee68b1bce78a95b132b4e5b5d19", 16)); // // set up the keys // SecureRandom rand = new SecureRandom(); PrivateKey privKey; PublicKey pubKey; KeyFactory fact = KeyFactory.getInstance("RSA", "BC"); privKey = fact.generatePrivate(privKeySpec); pubKey = fact.generatePublic(pubKeySpec); // // distinguished name table. // Hashtable attrs = new Hashtable(); attrs.put(X509Principal.C, "AU"); attrs.put(X509Principal.O, "The Legion of the Bouncy Castle"); attrs.put(X509Principal.L, "Melbourne"); attrs.put(X509Principal.ST, "Victoria"); attrs.put(X509Principal.E, "feedback-crypto@bouncycastle.org"); Vector ord = new Vector(); Vector values = new Vector(); ord.addElement(X509Principal.C); ord.addElement(X509Principal.O); ord.addElement(X509Principal.L); ord.addElement(X509Principal.ST); ord.addElement(X509Principal.E); values.addElement("AU"); values.addElement("The Legion of the Bouncy Castle"); values.addElement("Melbourne"); values.addElement("Victoria"); values.addElement("feedback-crypto@bouncycastle.org"); // // create base certificate - version 3 // X509V3CertificateGenerator certGen = new X509V3CertificateGenerator(); certGen.setSerialNumber(BigInteger.valueOf(1)); certGen.setIssuerDN(new X509Principal(attrs)); certGen.setNotBefore(new Date(System.currentTimeMillis() - 50000)); certGen.setNotAfter(new Date(System.currentTimeMillis() + 50000)); certGen.setSubjectDN(new X509Principal(attrs)); certGen.setPublicKey(pubKey); certGen.setSignatureAlgorithm("MD5WithRSAEncryption"); certGen.addExtension("2.5.29.15", true, new X509KeyUsage(X509KeyUsage.encipherOnly)); certGen.addExtension("2.5.29.37", true, new DERSequence(KeyPurposeId.anyExtendedKeyUsage)); certGen.addExtension("2.5.29.17", true, new GeneralNames(new GeneralName(GeneralName.rfc822Name, "test@test.test"))); X509Certificate baseCert = certGen.generate(privKey, "BC"); // // copy certificate // certGen = new X509V3CertificateGenerator(); certGen.setSerialNumber(BigInteger.valueOf(1)); certGen.setIssuerDN(new X509Principal(attrs)); certGen.setNotBefore(new Date(System.currentTimeMillis() - 50000)); certGen.setNotAfter(new Date(System.currentTimeMillis() + 50000)); certGen.setSubjectDN(new X509Principal(attrs)); certGen.setPublicKey(pubKey); certGen.setSignatureAlgorithm("MD5WithRSAEncryption"); certGen.copyAndAddExtension(new DERObjectIdentifier("2.5.29.15"), true, baseCert); certGen.copyAndAddExtension("2.5.29.37", false, baseCert); X509Certificate cert = certGen.generate(privKey, "BC"); cert.checkValidity(new Date()); cert.verify(pubKey); if (!areEqual(baseCert.getExtensionValue("2.5.29.15"), cert.getExtensionValue("2.5.29.15"))) { fail("2.5.29.15 differs"); } if (!areEqual(baseCert.getExtensionValue("2.5.29.37"), cert.getExtensionValue("2.5.29.37"))) { fail("2.5.29.37 differs"); } // // exception test // try { certGen.copyAndAddExtension("2.5.99.99", true, baseCert); fail("exception not thrown on dud extension copy"); } catch (CertificateParsingException e) { // expected } try { certGen.setPublicKey(dudPublicKey); certGen.generate(privKey, "BC"); fail("key without encoding not detected in v3"); } catch (IllegalArgumentException e) { // expected } } private void testForgedSignature() throws Exception { String cert = "MIIBsDCCAVoCAQYwDQYJKoZIhvcNAQEFBQAwYzELMAkGA1UEBhMCQVUxEzARBgNV" + "BAgTClF1ZWVuc2xhbmQxGjAYBgNVBAoTEUNyeXB0U29mdCBQdHkgTHRkMSMwIQYD" + "VQQDExpTZXJ2ZXIgdGVzdCBjZXJ0ICg1MTIgYml0KTAeFw0wNjA5MTEyMzU4NTVa" + "Fw0wNjEwMTEyMzU4NTVaMGMxCzAJBgNVBAYTAkFVMRMwEQYDVQQIEwpRdWVlbnNs" + "YW5kMRowGAYDVQQKExFDcnlwdFNvZnQgUHR5IEx0ZDEjMCEGA1UEAxMaU2VydmVy" + "IHRlc3QgY2VydCAoNTEyIGJpdCkwXDANBgkqhkiG9w0BAQEFAANLADBIAkEAn7PD" + "hCeV/xIxUg8V70YRxK2A5jZbD92A12GN4PxyRQk0/lVmRUNMaJdq/qigpd9feP/u" + "12S4PwTLb/8q/v657QIDAQABMA0GCSqGSIb3DQEBBQUAA0EAbynCRIlUQgaqyNgU" + "DF6P14yRKUtX8akOP2TwStaSiVf/akYqfLFm3UGka5XbPj4rifrZ0/sOoZEEBvHQ" + "e20sRA=="; CertificateFactory certFact = CertificateFactory.getInstance("X.509", "BC"); X509Certificate x509 = (X509Certificate)certFact.generateCertificate(new ByteArrayInputStream(Base64.decode(cert))); try { x509.verify(x509.getPublicKey()); fail("forged RSA signature passed"); } catch (Exception e) { // expected } } private void pemTest() throws Exception { CertificateFactory cf = CertificateFactory.getInstance("X.509", "BC"); Certificate cert = cf.generateCertificate(new ByteArrayInputStream(PEMData.CERTIFICATE_1.getBytes("US-ASCII"))); if (cert == null) { fail("PEM cert not read"); } CRL crl = cf.generateCRL(new ByteArrayInputStream(PEMData.CRL_1.getBytes("US-ASCII"))); if (crl == null) { fail("PEM crl not read"); } Collection col = cf.generateCertificates(new ByteArrayInputStream(PEMData.CERTIFICATE_2.getBytes("US-ASCII"))); if (col.size() != 1 || !col.contains(cert)) { fail("PEM cert collection not right"); } col = cf.generateCRLs(new ByteArrayInputStream(PEMData.CRL_2.getBytes("US-ASCII"))); if (col.size() != 1 || !col.contains(crl)) { fail("PEM crl collection not right"); } } private void pkcs7Test() throws Exception { ASN1EncodableVector certs = new ASN1EncodableVector(); certs.add(new ASN1InputStream(CertPathTest.rootCertBin).readObject()); certs.add(new DERTaggedObject(false, 2, new ASN1InputStream(AttrCertTest.attrCert).readObject())); ASN1EncodableVector crls = new ASN1EncodableVector(); crls.add(new ASN1InputStream(CertPathTest.rootCrlBin).readObject()); SignedData sigData = new SignedData(new DERSet(), new ContentInfo(CMSObjectIdentifiers.data, null), new DERSet(certs), new DERSet(crls), new DERSet()); ContentInfo info = new ContentInfo(CMSObjectIdentifiers.signedData, sigData); CertificateFactory cf = CertificateFactory.getInstance("X.509", "BC"); X509Certificate cert = (X509Certificate)cf.generateCertificate(new ByteArrayInputStream(info.getEncoded())); if (cert == null || !areEqual(cert.getEncoded(), certs.get(0).toASN1Primitive().getEncoded())) { fail("PKCS7 cert not read"); } X509CRL crl = (X509CRL)cf.generateCRL(new ByteArrayInputStream(info.getEncoded())); if (crl == null || !areEqual(crl.getEncoded(), crls.get(0).toASN1Primitive().getEncoded())) { fail("PKCS7 crl not read"); } Collection col = cf.generateCertificates(new ByteArrayInputStream(info.getEncoded())); if (col.size() != 1 || !col.contains(cert)) { fail("PKCS7 cert collection not right"); } col = cf.generateCRLs(new ByteArrayInputStream(info.getEncoded())); if (col.size() != 1 || !col.contains(crl)) { fail("PKCS7 crl collection not right"); } // data with no certificates or CRLs sigData = new SignedData(new DERSet(), new ContentInfo(CMSObjectIdentifiers.data, null), new DERSet(), new DERSet(), new DERSet()); info = new ContentInfo(CMSObjectIdentifiers.signedData, sigData); cert = (X509Certificate)cf.generateCertificate(new ByteArrayInputStream(info.getEncoded())); if (cert != null) { fail("PKCS7 cert present"); } crl = (X509CRL)cf.generateCRL(new ByteArrayInputStream(info.getEncoded())); if (crl != null) { fail("PKCS7 crl present"); } // data with absent certificates and CRLS sigData = new SignedData(new DERSet(), new ContentInfo(CMSObjectIdentifiers.data, null), null, null, new DERSet()); info = new ContentInfo(CMSObjectIdentifiers.signedData, sigData); cert = (X509Certificate)cf.generateCertificate(new ByteArrayInputStream(info.getEncoded())); if (cert != null) { fail("PKCS7 cert present"); } crl = (X509CRL)cf.generateCRL(new ByteArrayInputStream(info.getEncoded())); if (crl != null) { fail("PKCS7 crl present"); } // // sample message // InputStream in = new ByteArrayInputStream(pkcs7CrlProblem); Collection certCol = cf.generateCertificates(in); Collection crlCol = cf.generateCRLs(in); if (crlCol.size() != 0) { fail("wrong number of CRLs: " + crlCol.size()); } if (certCol.size() != 4) { fail("wrong number of Certs: " + certCol.size()); } } private void createPSSCert(String algorithm) throws Exception { RSAPublicKeySpec pubKeySpec = new RSAPublicKeySpec( new BigInteger("a56e4a0e701017589a5187dc7ea841d156f2ec0e36ad52a44dfeb1e61f7ad991d8c51056ffedb162b4c0f283a12a88a394dff526ab7291cbb307ceabfce0b1dfd5cd9508096d5b2b8b6df5d671ef6377c0921cb23c270a70e2598e6ff89d19f105acc2d3f0cb35f29280e1386b6f64c4ef22e1e1f20d0ce8cffb2249bd9a2137",16), new BigInteger("010001",16)); RSAPrivateCrtKeySpec privKeySpec = new RSAPrivateCrtKeySpec( new BigInteger("a56e4a0e701017589a5187dc7ea841d156f2ec0e36ad52a44dfeb1e61f7ad991d8c51056ffedb162b4c0f283a12a88a394dff526ab7291cbb307ceabfce0b1dfd5cd9508096d5b2b8b6df5d671ef6377c0921cb23c270a70e2598e6ff89d19f105acc2d3f0cb35f29280e1386b6f64c4ef22e1e1f20d0ce8cffb2249bd9a2137",16), new BigInteger("010001",16), new BigInteger("33a5042a90b27d4f5451ca9bbbd0b44771a101af884340aef9885f2a4bbe92e894a724ac3c568c8f97853ad07c0266c8c6a3ca0929f1e8f11231884429fc4d9ae55fee896a10ce707c3ed7e734e44727a39574501a532683109c2abacaba283c31b4bd2f53c3ee37e352cee34f9e503bd80c0622ad79c6dcee883547c6a3b325",16), new BigInteger("e7e8942720a877517273a356053ea2a1bc0c94aa72d55c6e86296b2dfc967948c0a72cbccca7eacb35706e09a1df55a1535bd9b3cc34160b3b6dcd3eda8e6443",16), new BigInteger("b69dca1cf7d4d7ec81e75b90fcca874abcde123fd2700180aa90479b6e48de8d67ed24f9f19d85ba275874f542cd20dc723e6963364a1f9425452b269a6799fd",16), new BigInteger("28fa13938655be1f8a159cbaca5a72ea190c30089e19cd274a556f36c4f6e19f554b34c077790427bbdd8dd3ede2448328f385d81b30e8e43b2fffa027861979",16), new BigInteger("1a8b38f398fa712049898d7fb79ee0a77668791299cdfa09efc0e507acb21ed74301ef5bfd48be455eaeb6e1678255827580a8e4e8e14151d1510a82a3f2e729",16), new BigInteger("27156aba4126d24a81f3a528cbfb27f56886f840a9f6e86e17a44b94fe9319584b8e22fdde1e5a2e3bd8aa5ba8d8584194eb2190acf832b847f13a3d24a79f4d",16)); KeyFactory fact = KeyFactory.getInstance("RSA", "BC"); PrivateKey privKey = fact.generatePrivate(privKeySpec); PublicKey pubKey = fact.generatePublic(pubKeySpec); // // distinguished name table. // Hashtable attrs = new Hashtable(); attrs.put(X509Principal.C, "AU"); attrs.put(X509Principal.O, "The Legion of the Bouncy Castle"); attrs.put(X509Principal.L, "Melbourne"); attrs.put(X509Principal.ST, "Victoria"); attrs.put(X509Principal.E, "feedback-crypto@bouncycastle.org"); Vector ord = new Vector(); Vector values = new Vector(); ord.addElement(X509Principal.C); ord.addElement(X509Principal.O); ord.addElement(X509Principal.L); ord.addElement(X509Principal.ST); ord.addElement(X509Principal.E); values.addElement("AU"); values.addElement("The Legion of the Bouncy Castle"); values.addElement("Melbourne"); values.addElement("Victoria"); values.addElement("feedback-crypto@bouncycastle.org"); // // create base certificate - version 3 // X509V3CertificateGenerator certGen = new X509V3CertificateGenerator(); certGen.setSerialNumber(BigInteger.valueOf(1)); certGen.setIssuerDN(new X509Principal(attrs)); certGen.setNotBefore(new Date(System.currentTimeMillis() - 50000)); certGen.setNotAfter(new Date(System.currentTimeMillis() + 50000)); certGen.setSubjectDN(new X509Principal(attrs)); certGen.setPublicKey(pubKey); certGen.setSignatureAlgorithm(algorithm); certGen.addExtension("2.5.29.15", true, new X509KeyUsage(X509KeyUsage.encipherOnly)); certGen.addExtension("2.5.29.37", true, new DERSequence(KeyPurposeId.anyExtendedKeyUsage)); certGen.addExtension("2.5.29.17", true, new GeneralNames(new GeneralName(GeneralName.rfc822Name, "test@test.test"))); X509Certificate baseCert = certGen.generate(privKey, "BC"); baseCert.verify(pubKey); } public void performTest() throws Exception { checkCertificate(1, cert1); checkCertificate(2, cert2); checkCertificate(4, cert4); checkCertificate(5, cert5); checkCertificate(6, oldEcdsa); checkCertificate(7, cert7); checkKeyUsage(8, keyUsage); checkSelfSignedCertificate(9, uncompressedPtEC); checkNameCertificate(10, nameCert); checkSelfSignedCertificate(11, probSelfSignedCert); checkSelfSignedCertificate(12, gostCA1); checkSelfSignedCertificate(13, gostCA2); checkSelfSignedCertificate(14, gost341094base); checkSelfSignedCertificate(15, gost34102001base); checkSelfSignedCertificate(16, gost341094A); checkSelfSignedCertificate(17, gost341094B); checkSelfSignedCertificate(17, gost34102001A); checkCRL(1, crl1); checkCreation1(); checkCreation2(); checkCreation3(); checkCreation4(); checkCreation5(); createECCert("SHA1withECDSA", X9ObjectIdentifiers.ecdsa_with_SHA1); createECCert("SHA224withECDSA", X9ObjectIdentifiers.ecdsa_with_SHA224); createECCert("SHA256withECDSA", X9ObjectIdentifiers.ecdsa_with_SHA256); createECCert("SHA384withECDSA", X9ObjectIdentifiers.ecdsa_with_SHA384); createECCert("SHA512withECDSA", X9ObjectIdentifiers.ecdsa_with_SHA512); createPSSCert("SHA1withRSAandMGF1"); createPSSCert("SHA224withRSAandMGF1"); createPSSCert("SHA256withRSAandMGF1"); createPSSCert("SHA384withRSAandMGF1"); checkCRLCreation1(); checkCRLCreation2(); checkCRLCreation3(); pemTest(); pkcs7Test(); testForgedSignature(); } public static void main( String[] args) { Security.addProvider(new BouncyCastleProvider()); runTest(new CertTest()); } } bouncycastle-1.49.orig/test/jdk1.3/org/bouncycastle/openssl/0000755000175000017500000000000012152033550023343 5ustar ebourgebourgbouncycastle-1.49.orig/test/jdk1.3/org/bouncycastle/openssl/test/0000755000175000017500000000000012152033550024322 5ustar ebourgebourgbouncycastle-1.49.orig/test/jdk1.3/org/bouncycastle/openssl/test/ReaderTest.java0000644000175000017500000002151711321535425027242 0ustar ebourgebourgpackage org.bouncycastle.openssl.test; import java.io.BufferedReader; import java.io.ByteArrayInputStream; import java.io.ByteArrayOutputStream; import java.io.IOException; import java.io.InputStream; import java.io.InputStreamReader; import java.io.OutputStreamWriter; import java.io.Reader; import java.security.KeyPair; import java.security.KeyPairGenerator; import java.security.PrivateKey; import java.security.PublicKey; import java.security.SecureRandom; import java.security.Security; import java.security.Signature; import java.security.interfaces.DSAPrivateKey; import java.security.interfaces.RSAPrivateKey; import org.bouncycastle.asn1.cms.CMSObjectIdentifiers; import org.bouncycastle.asn1.cms.ContentInfo; import org.bouncycastle.jce.provider.BouncyCastleProvider; import org.bouncycastle.jce.spec.ECNamedCurveParameterSpec; import org.bouncycastle.openssl.PEMReader; import org.bouncycastle.openssl.PEMWriter; import org.bouncycastle.openssl.PasswordFinder; import org.bouncycastle.util.test.SimpleTest; /** * basic class for reading test.pem - the password is "secret" */ public class ReaderTest extends SimpleTest { private static class Password implements PasswordFinder { char[] password; Password( char[] word) { this.password = word; } public char[] getPassword() { return password; } } public String getName() { return "PEMReaderTest"; } private PEMReader openPEMResource( String fileName, PasswordFinder pGet) { InputStream res = this.getClass().getResourceAsStream(fileName); Reader fRd = new BufferedReader(new InputStreamReader(res)); return new PEMReader(fRd, pGet); } public void performTest() throws Exception { PasswordFinder pGet = new Password("secret".toCharArray()); PEMReader pemRd = openPEMResource("test.pem", pGet); Object o; KeyPair pair; while ((o = pemRd.readObject()) != null) { if (o instanceof KeyPair) { //pair = (KeyPair)o; //System.out.println(pair.getPublic()); //System.out.println(pair.getPrivate()); } else { //System.out.println(o.toString()); } } // // pkcs 7 data // pemRd = openPEMResource("pkcs7.pem", null); ContentInfo d = (ContentInfo)pemRd.readObject(); if (!d.getContentType().equals(CMSObjectIdentifiers.envelopedData)) { fail("failed envelopedData check"); } // // ECKey // pemRd = openPEMResource("eckey.pem", null); ECNamedCurveParameterSpec spec = (ECNamedCurveParameterSpec)pemRd.readObject(); pair = (KeyPair)pemRd.readObject(); Signature sgr = Signature.getInstance("ECDSA", "BC"); sgr.initSign(pair.getPrivate()); byte[] message = new byte[] { (byte)'a', (byte)'b', (byte)'c' }; sgr.update(message); byte[] sigBytes = sgr.sign(); sgr.initVerify(pair.getPublic()); sgr.update(message); if (!sgr.verify(sigBytes)) { fail("EC verification failed"); } if (!pair.getPublic().getAlgorithm().equals("ECDSA")) { fail("wrong algorithm name on public got: " + pair.getPublic().getAlgorithm()); } if (!pair.getPrivate().getAlgorithm().equals("ECDSA")) { fail("wrong algorithm name on private"); } // // writer/parser test // KeyPairGenerator kpGen = KeyPairGenerator.getInstance("RSA", "BC"); pair = kpGen.generateKeyPair(); keyPairTest("RSA", pair); kpGen = KeyPairGenerator.getInstance("DSA", "BC"); kpGen.initialize(512, new SecureRandom()); pair = kpGen.generateKeyPair(); keyPairTest("DSA", pair); // // PKCS7 // ByteArrayOutputStream bOut = new ByteArrayOutputStream(); PEMWriter pWrt = new PEMWriter(new OutputStreamWriter(bOut)); pWrt.writeObject(d); pWrt.close(); pemRd = new PEMReader(new InputStreamReader(new ByteArrayInputStream(bOut.toByteArray()))); d = (ContentInfo)pemRd.readObject(); if (!d.getContentType().equals(CMSObjectIdentifiers.envelopedData)) { fail("failed envelopedData recode check"); } // OpenSSL test cases (as embedded resources) doOpenSslDsaTest("unencrypted"); doOpenSslRsaTest("unencrypted"); doOpenSslTests("aes128"); doOpenSslTests("aes192"); doOpenSslTests("aes256"); doOpenSslTests("blowfish"); doOpenSslTests("des1"); doOpenSslTests("des2"); doOpenSslTests("des3"); doOpenSslTests("rc2_128"); doOpenSslDsaTest("rc2_40_cbc"); doOpenSslRsaTest("rc2_40_cbc"); doOpenSslDsaTest("rc2_64_cbc"); doOpenSslRsaTest("rc2_64_cbc"); // heap space check - a failure by the ASN.1 library to detect an // out of band stream will cause this to run out of memory. try { pGet = new Password("7fd98".toCharArray()); pemRd = openPEMResource("test.pem", pGet); while ((o = pemRd.readObject()) != null) { } fail("bounds issue not detected"); } catch (IOException e) { } } private void keyPairTest( String name, KeyPair pair) throws IOException { PEMReader pemRd; ByteArrayOutputStream bOut = new ByteArrayOutputStream(); PEMWriter pWrt = new PEMWriter(new OutputStreamWriter(bOut)); pWrt.writeObject(pair.getPublic()); pWrt.close(); pemRd = new PEMReader(new InputStreamReader(new ByteArrayInputStream(bOut.toByteArray()))); PublicKey k = (PublicKey)pemRd.readObject(); if (!k.equals(pair.getPublic())) { fail("Failed public key read: " + name); } bOut = new ByteArrayOutputStream(); pWrt = new PEMWriter(new OutputStreamWriter(bOut)); pWrt.writeObject(pair.getPrivate()); pWrt.close(); pemRd = new PEMReader(new InputStreamReader(new ByteArrayInputStream(bOut.toByteArray()))); KeyPair kPair = (KeyPair)pemRd.readObject(); if (!kPair.getPrivate().equals(pair.getPrivate())) { fail("Failed private key read: " + name); } if (!kPair.getPublic().equals(pair.getPublic())) { fail("Failed private key public read: " + name); } } private void doOpenSslTests( String baseName) throws IOException { doOpenSslDsaModesTest(baseName); doOpenSslRsaModesTest(baseName); } private void doOpenSslDsaModesTest( String baseName) throws IOException { doOpenSslDsaTest(baseName + "_cbc"); doOpenSslDsaTest(baseName + "_cfb"); doOpenSslDsaTest(baseName + "_ecb"); doOpenSslDsaTest(baseName + "_ofb"); } private void doOpenSslRsaModesTest( String baseName) throws IOException { doOpenSslRsaTest(baseName + "_cbc"); doOpenSslRsaTest(baseName + "_cfb"); doOpenSslRsaTest(baseName + "_ecb"); doOpenSslRsaTest(baseName + "_ofb"); } private void doOpenSslDsaTest( String name) throws IOException { String fileName = "dsa/openssl_dsa_" + name + ".pem"; doOpenSslTestFile(fileName, DSAPrivateKey.class); } private void doOpenSslRsaTest( String name) throws IOException { String fileName = "rsa/openssl_rsa_" + name + ".pem"; doOpenSslTestFile(fileName, RSAPrivateKey.class); } private void doOpenSslTestFile( String fileName, Class expectedPrivKeyClass) throws IOException { PEMReader pr = openPEMResource("data/" + fileName, new Password("changeit".toCharArray())); Object o = pr.readObject(); if (o == null || !(o instanceof KeyPair)) { fail("Didn't find OpenSSL key"); } KeyPair kp = (KeyPair) o; PrivateKey privKey = kp.getPrivate(); if (!expectedPrivKeyClass.isInstance(privKey)) { fail("Returned key not of correct type"); } } public static void main( String[] args) { Security.addProvider(new BouncyCastleProvider()); runTest(new ReaderTest()); } } bouncycastle-1.49.orig/test/jdk1.3/org/bouncycastle/openssl/test/ParserTest.java0000644000175000017500000003622512150050437027272 0ustar ebourgebourgpackage org.bouncycastle.openssl.test; import java.io.BufferedReader; import java.io.ByteArrayInputStream; import java.io.ByteArrayOutputStream; import java.io.IOException; import java.io.InputStream; import java.io.InputStreamReader; import java.io.OutputStreamWriter; import java.io.Reader; import java.math.BigInteger; import java.security.KeyPair; import java.security.KeyPairGenerator; import java.security.PrivateKey; import java.security.PublicKey; import java.security.SecureRandom; import java.security.Security; import java.security.Signature; import java.security.interfaces.DSAPrivateKey; import java.security.interfaces.RSAPrivateCrtKey; import java.security.interfaces.RSAPrivateKey; import org.bouncycastle.asn1.ASN1ObjectIdentifier; import org.bouncycastle.asn1.cms.CMSObjectIdentifiers; import org.bouncycastle.asn1.cms.ContentInfo; import org.bouncycastle.asn1.pkcs.PrivateKeyInfo; import org.bouncycastle.asn1.x509.SubjectPublicKeyInfo; import org.bouncycastle.asn1.x9.ECNamedCurveTable; import org.bouncycastle.asn1.x9.X9ECParameters; import org.bouncycastle.cert.X509CertificateHolder; import org.bouncycastle.jce.provider.BouncyCastleProvider; import org.bouncycastle.openssl.PEMDecryptorProvider; import org.bouncycastle.openssl.PEMEncryptedKeyPair; import org.bouncycastle.openssl.PEMKeyPair; import org.bouncycastle.openssl.PEMParser; import org.bouncycastle.openssl.PEMWriter; import org.bouncycastle.openssl.PasswordFinder; import org.bouncycastle.openssl.jcajce.JcaPEMKeyConverter; import org.bouncycastle.openssl.jcajce.JceOpenSSLPKCS8DecryptorProviderBuilder; import org.bouncycastle.openssl.jcajce.JcePEMDecryptorProviderBuilder; import org.bouncycastle.operator.InputDecryptorProvider; import org.bouncycastle.pkcs.PKCS8EncryptedPrivateKeyInfo; import org.bouncycastle.util.test.SimpleTest; /** * basic class for reading test.pem - the password is "secret" */ public class ParserTest extends SimpleTest { private static class Password implements PasswordFinder { char[] password; Password( char[] word) { this.password = word; } public char[] getPassword() { return password; } } public String getName() { return "PEMParserTest"; } private PEMParser openPEMResource( String fileName) { InputStream res = this.getClass().getResourceAsStream(fileName); Reader fRd = new BufferedReader(new InputStreamReader(res)); return new PEMParser(fRd); } public void performTest() throws Exception { PEMParser pemRd = openPEMResource("test.pem"); Object o; PEMKeyPair pemPair; KeyPair pair; while ((o = pemRd.readObject()) != null) { if (o instanceof KeyPair) { //pair = (KeyPair)o; //System.out.println(pair.getPublic()); //System.out.println(pair.getPrivate()); } else { //System.out.println(o.toString()); } } // test bogus lines before begin are ignored. pemRd = openPEMResource("extratest.pem"); while ((o = pemRd.readObject()) != null) { if (!(o instanceof X509CertificateHolder)) { fail("wrong object found"); } } // // pkcs 7 data // pemRd = openPEMResource("pkcs7.pem"); ContentInfo d = (ContentInfo)pemRd.readObject(); if (!d.getContentType().equals(CMSObjectIdentifiers.envelopedData)) { fail("failed envelopedData check"); } // // ECKey // pemRd = openPEMResource("eckey.pem"); ASN1ObjectIdentifier ecOID = (ASN1ObjectIdentifier)pemRd.readObject(); X9ECParameters ecSpec = ECNamedCurveTable.getByOID(ecOID); if (ecSpec == null) { fail("ecSpec not found for named curve"); } pemPair = (PEMKeyPair)pemRd.readObject(); pair = new JcaPEMKeyConverter().setProvider("BC").getKeyPair(pemPair); Signature sgr = Signature.getInstance("ECDSA", "BC"); sgr.initSign(pair.getPrivate()); byte[] message = new byte[] { (byte)'a', (byte)'b', (byte)'c' }; sgr.update(message); byte[] sigBytes = sgr.sign(); sgr.initVerify(pair.getPublic()); sgr.update(message); if (!sgr.verify(sigBytes)) { fail("EC verification failed"); } if (!pair.getPublic().getAlgorithm().equals("ECDSA")) { fail("wrong algorithm name on public got: " + pair.getPublic().getAlgorithm()); } if (!pair.getPrivate().getAlgorithm().equals("ECDSA")) { fail("wrong algorithm name on private"); } // // ECKey -- explicit parameters // pemRd = openPEMResource("ecexpparam.pem"); ecSpec = (X9ECParameters)pemRd.readObject(); pemPair = (PEMKeyPair)pemRd.readObject(); pair = new JcaPEMKeyConverter().setProvider("BC").getKeyPair(pemPair); sgr = Signature.getInstance("ECDSA", "BC"); sgr.initSign(pair.getPrivate()); message = new byte[] { (byte)'a', (byte)'b', (byte)'c' }; sgr.update(message); sigBytes = sgr.sign(); sgr.initVerify(pair.getPublic()); sgr.update(message); if (!sgr.verify(sigBytes)) { fail("EC verification failed"); } if (!pair.getPublic().getAlgorithm().equals("ECDSA")) { fail("wrong algorithm name on public got: " + pair.getPublic().getAlgorithm()); } if (!pair.getPrivate().getAlgorithm().equals("ECDSA")) { fail("wrong algorithm name on private"); } // // writer/parser test // KeyPairGenerator kpGen = KeyPairGenerator.getInstance("RSA", "BC"); pair = kpGen.generateKeyPair(); keyPairTest("RSA", pair); kpGen = KeyPairGenerator.getInstance("DSA", "BC"); kpGen.initialize(512, new SecureRandom()); pair = kpGen.generateKeyPair(); keyPairTest("DSA", pair); // // PKCS7 // ByteArrayOutputStream bOut = new ByteArrayOutputStream(); PEMWriter pWrt = new PEMWriter(new OutputStreamWriter(bOut)); pWrt.writeObject(d); pWrt.close(); pemRd = new PEMParser(new InputStreamReader(new ByteArrayInputStream(bOut.toByteArray()))); d = (ContentInfo)pemRd.readObject(); if (!d.getContentType().equals(CMSObjectIdentifiers.envelopedData)) { fail("failed envelopedData recode check"); } // OpenSSL test cases (as embedded resources) doOpenSslDsaTest("unencrypted"); doOpenSslRsaTest("unencrypted"); doOpenSslTests("aes128"); doOpenSslTests("aes192"); doOpenSslTests("aes256"); doOpenSslTests("blowfish"); doOpenSslTests("des1"); doOpenSslTests("des2"); doOpenSslTests("des3"); doOpenSslTests("rc2_128"); doOpenSslDsaTest("rc2_40_cbc"); doOpenSslRsaTest("rc2_40_cbc"); doOpenSslDsaTest("rc2_64_cbc"); doOpenSslRsaTest("rc2_64_cbc"); doDudPasswordTest("7fd98", 0, "corrupted stream - out of bounds length found"); doDudPasswordTest("ef677", 1, "corrupted stream - out of bounds length found"); doDudPasswordTest("800ce", 2, "unknown tag 26 encountered"); doDudPasswordTest("b6cd8", 3, "DEF length 81 object truncated by 56"); doDudPasswordTest("28ce09", 4, "DEF length 110 object truncated by 28"); doDudPasswordTest("2ac3b9", 5, "DER length more than 4 bytes: 11"); doDudPasswordTest("2cba96", 6, "DEF length 100 object truncated by 35"); doDudPasswordTest("2e3354", 7, "DEF length 42 object truncated by 9"); doDudPasswordTest("2f4142", 8, "DER length more than 4 bytes: 14"); doDudPasswordTest("2fe9bb", 9, "DER length more than 4 bytes: 65"); doDudPasswordTest("3ee7a8", 10, "DER length more than 4 bytes: 57"); doDudPasswordTest("41af75", 11, "unknown tag 16 encountered"); doDudPasswordTest("1704a5", 12, "corrupted stream detected"); doDudPasswordTest("1c5822", 13, "unknown object in getInstance: org.bouncycastle.asn1.DERUTF8String"); doDudPasswordTest("5a3d16", 14, "corrupted stream detected"); doDudPasswordTest("8d0c97", 15, "corrupted stream detected"); doDudPasswordTest("bc0daf", 16, "corrupted stream detected"); doDudPasswordTest("aaf9c4d",17, "corrupted stream - out of bounds length found"); doNoPasswordTest(); // encrypted private key test InputDecryptorProvider pkcs8Prov = new JceOpenSSLPKCS8DecryptorProviderBuilder().build("password".toCharArray()); pemRd = openPEMResource("enckey.pem"); PKCS8EncryptedPrivateKeyInfo encPrivKeyInfo = (PKCS8EncryptedPrivateKeyInfo)pemRd.readObject(); JcaPEMKeyConverter converter = new JcaPEMKeyConverter().setProvider("BC"); RSAPrivateCrtKey privKey = (RSAPrivateCrtKey)converter.getPrivateKey(encPrivKeyInfo.decryptPrivateKeyInfo(pkcs8Prov)); if (!privKey.getPublicExponent().equals(new BigInteger("10001", 16))) { fail("decryption of private key data check failed"); } // general PKCS8 test pemRd = openPEMResource("pkcs8test.pem"); Object privInfo; while ((privInfo = pemRd.readObject()) != null) { if (privInfo instanceof PrivateKeyInfo) { privKey = (RSAPrivateCrtKey)converter.getPrivateKey(PrivateKeyInfo.getInstance(privInfo)); } else { privKey = (RSAPrivateCrtKey)converter.getPrivateKey(((PKCS8EncryptedPrivateKeyInfo)privInfo).decryptPrivateKeyInfo(pkcs8Prov)); } if (!privKey.getPublicExponent().equals(new BigInteger("10001", 16))) { fail("decryption of private key data check failed"); } } } private void keyPairTest( String name, KeyPair pair) throws IOException { PEMParser pemRd; ByteArrayOutputStream bOut = new ByteArrayOutputStream(); PEMWriter pWrt = new PEMWriter(new OutputStreamWriter(bOut)); pWrt.writeObject(pair.getPublic()); pWrt.close(); pemRd = new PEMParser(new InputStreamReader(new ByteArrayInputStream(bOut.toByteArray()))); SubjectPublicKeyInfo pub = SubjectPublicKeyInfo.getInstance(pemRd.readObject()); JcaPEMKeyConverter converter = new JcaPEMKeyConverter().setProvider("BC"); PublicKey k = converter.getPublicKey(pub); if (!k.equals(pair.getPublic())) { fail("Failed public key read: " + name); } bOut = new ByteArrayOutputStream(); pWrt = new PEMWriter(new OutputStreamWriter(bOut)); pWrt.writeObject(pair.getPrivate()); pWrt.close(); pemRd = new PEMParser(new InputStreamReader(new ByteArrayInputStream(bOut.toByteArray()))); KeyPair kPair = converter.getKeyPair((PEMKeyPair)pemRd.readObject()); if (!kPair.getPrivate().equals(pair.getPrivate())) { fail("Failed private key read: " + name); } if (!kPair.getPublic().equals(pair.getPublic())) { fail("Failed private key public read: " + name); } } private void doOpenSslTests( String baseName) throws IOException { doOpenSslDsaModesTest(baseName); doOpenSslRsaModesTest(baseName); } private void doOpenSslDsaModesTest( String baseName) throws IOException { doOpenSslDsaTest(baseName + "_cbc"); doOpenSslDsaTest(baseName + "_cfb"); doOpenSslDsaTest(baseName + "_ecb"); doOpenSslDsaTest(baseName + "_ofb"); } private void doOpenSslRsaModesTest( String baseName) throws IOException { doOpenSslRsaTest(baseName + "_cbc"); doOpenSslRsaTest(baseName + "_cfb"); doOpenSslRsaTest(baseName + "_ecb"); doOpenSslRsaTest(baseName + "_ofb"); } private void doOpenSslDsaTest( String name) throws IOException { String fileName = "dsa/openssl_dsa_" + name + ".pem"; doOpenSslTestFile(fileName, DSAPrivateKey.class); } private void doOpenSslRsaTest( String name) throws IOException { String fileName = "rsa/openssl_rsa_" + name + ".pem"; doOpenSslTestFile(fileName, RSAPrivateKey.class); } private void doOpenSslTestFile( String fileName, Class expectedPrivKeyClass) throws IOException { JcaPEMKeyConverter converter = new JcaPEMKeyConverter().setProvider("BC"); PEMDecryptorProvider decProv = new JcePEMDecryptorProviderBuilder().setProvider("BC").build("changeit".toCharArray()); PEMParser pr = openPEMResource("data/" + fileName); Object o = pr.readObject(); if (o == null || !((o instanceof PEMKeyPair) || (o instanceof PEMEncryptedKeyPair))) { fail("Didn't find OpenSSL key"); } KeyPair kp = (o instanceof PEMEncryptedKeyPair) ? converter.getKeyPair(((PEMEncryptedKeyPair)o).decryptKeyPair(decProv)) : converter.getKeyPair((PEMKeyPair)o); PrivateKey privKey = kp.getPrivate(); if (!expectedPrivKeyClass.isInstance(privKey)) { fail("Returned key not of correct type"); } } private void doDudPasswordTest(String password, int index, String message) { // illegal state exception check - in this case the wrong password will // cause an underlying class cast exception. try { PEMDecryptorProvider decProv = new JcePEMDecryptorProviderBuilder().setProvider("BC").build(password.toCharArray()); PEMParser pemRd = openPEMResource("test.pem"); Object o; while ((o = pemRd.readObject()) != null) { if (o instanceof PEMEncryptedKeyPair) { ((PEMEncryptedKeyPair)o).decryptKeyPair(decProv); } } fail("issue not detected: " + index); } catch (IOException e) { // ignore } } private void doNoPasswordTest() throws IOException { PEMDecryptorProvider decProv = new JcePEMDecryptorProviderBuilder().setProvider("BC").build("".toCharArray()); PEMParser pemRd = openPEMResource("smimenopw.pem"); Object o; PrivateKeyInfo key = null; while ((o = pemRd.readObject()) != null) { key = (PrivateKeyInfo)o; } if (key == null) { fail("private key not detected"); } } public static void main( String[] args) { Security.addProvider(new BouncyCastleProvider()); runTest(new ParserTest()); } } bouncycastle-1.49.orig/test/data/0000755000175000017500000000000012152033550016315 5ustar ebourgebourgbouncycastle-1.49.orig/test/data/openpgp/0000755000175000017500000000000012152033550017765 5ustar ebourgebourgbouncycastle-1.49.orig/test/data/openpgp/unicode/0000755000175000017500000000000012152033550021413 5ustar ebourgebourgbouncycastle-1.49.orig/test/data/openpgp/unicode/test.asc0000644000175000017500000000360312027000626023063 0ustar ebourgebourg-----BEGIN PGP PRIVATE KEY BLOCK----- Version: GnuPG v2.0.17 (MingW32) lQO+BFBcYqwBCAC53iWjgnHOw5eo2N+OWhyz17AnEh45aRtvs/U2cIU+aCM/VXx5 ig7GN6RcDirgnR/CTAwtdy6V/TFJ9Ej/hKu8hGsL/HCVegzs6hQo3rqXSLaAuH5i prdBQ0fFzCB08kbr1VkP9TyTGU6xfoEiDpk33TCbqM5Cx5+7gM5uuquTxE1SkyqV hd7M2p6LhvhtlHo5yx/mfPQhBCuRd/HtAXQux+UwFEeVh+1rxcKfygEeMHHkNg3F LJBLJW95XxTIxuScJADKhrFPjwtzVWh/chYOoK61O5rvbyRE5epHEOQYCD5X4+IN G22eInPaVkx9SS93Wm9UcjWEwfRY/kLDp3TjABEBAAH+AwMCSD3h6GM3cH63FXiH nknGYv5N7GZlI+F4m3k2+MbK/OcU2sv98Fa4b78Z5ONLH3oFwIm7NFa7fobmIHyv Xmcx9W06CrxpLUroqoRtEFGFrmap6yqAtnqDwtBqk6sar8QSH5HKX4xvBd1AOndk Htwk3cD5uN/VaIPEwgOlC+LpvQLQpMTNRpXn2NEvsj6RIEkyWxx/N7+w0B+pfeOY dhp8ra6kNs+1N5joMlA7tdBL9pMIiyHVfd077N2A/Fc7ONhDdIJBh9u72nTUa63H +2jE0LzwFQQrsnz2PRvyWa4XmXVFHOg1DRuoClZ1HXZseOAYtY4u9v+62I3SjVvG fVALDVMjwlw1omRupsq5Mn9kuvUcpmc+fcqNJIViO/tm0mFV6Brb802oq5xkstEz iEF38cpJJe2WcVwABEEd6T7SZTgzakRMaQAWZ6Avb/yRzBtQ0Nq1mpn22EYHphNY JJtNJ3qdtIIV0TR6X034px41Kp97ZFwVPMWsR0NeM+qOQ9w3vixFt9TGdBI8rOYh 8BSjaglz7FG8svOTfGp/Ja5nLgf3eO4hidQOQkNcRRZ9x+d/ajmZtCm6PBIfTfvH R9E7sMjt7CY5QAgqMK4ZwrK9BMrHlk5PLMF0/db53KTgAQcfO/skubU5ko/eWMFX gkPxAfCIbN8XP8DjzynxG7V80rngwtcOXLnWOfTce2fDiO1BGCnyu/S1JjRfCA3Y IuS5ZVpoIdssPrfXrMEKT2CP9w4R+ERsd869+bYAckaXZ6V7D6rjLYBn4LXCElmJ WUvevOIDRIxAUYoFuTY6jnAkQyu3/2bDwXOcGJQ3GDxMojXr8uejyeAW8NUa634C hJ8kuFxMXfNVhR9JnodSwe20QsFy7IUnVXergAPEVMSBhsDqFCnWuvgC8pb2dbh+ u7QgdGVzdCB1c2VyICh0ZXN0KSA8dGVzdEB0ZXN0LmNvbT6JATgEEwECACIFAlBc YqwCGw8GCwkIBwMCBhUIAgkKCwQWAgMBAh4BAheAAAoJEOyHJy78uYbSqWQH/11k itAUrb6aUKHVyvO0r6NEbQ6TSJCstfJ6N+Euhs14od7dWgPWfkaYh9BE0j6xTrAZ CxP8v0Swgha7b2AVNqxf5jxAJ7xNGNY/jdzeiB9Cp5ShrFGHFGmzCYUSe2hvyBX4 9cl9W6nKSflG+lFfcmp2wcynk/aRO0H5ieXw3eD+3SB9snAWEZzDHfUj2ifTbzPD 80Yd2mWz9pe1xyqxgnWQkAOIWUxWpECFz8wjA9U3257gEVgfN21Ng/vaVbxa1R4Z 2A+bLjt0jgdXw0XX69FDolko3cWuiWfJNbxsrfSCRYwFUxNVxK9rtm5padL/kZ8W l9icSUSiIoEfXj1iDh4= =2Azi -----END PGP PRIVATE KEY BLOCK----- bouncycastle-1.49.orig/test/data/openpgp/unicode/passphrase_for_test.txt0000644000175000017500000000000612027002400026215 0ustar ebourgebourgHändlebouncycastle-1.49.orig/test/data/openpgp/unicode/passphrase_cyr.txt0000644000175000017500000000001212030711270025170 0ustar ebourgebourgТеÑтЯbouncycastle-1.49.orig/test/data/openpgp/unicode/secring.gpg0000644000175000017500000000756312030705764023567 0ustar ebourgebourg•¾P\b¬¹Þ%£‚qÎרØßŽZ³×°'9io³õ6p…>h#?U|yŠÆ7¤\*àÂL -w.•ý1IôHÿ„«¼„k üp•z ìê(Þº—H¶€¸~b¦·ACGÅÌ tòFëÕYõ<“N±~"™7Ý0›¨ÎBÇŸ»€Înº«“ÄMR“*•…ÞÌÚž‹†øm”z9Ëæ|ô!+‘wñít.Çå0G•‡íkÅŸÊ0qä6 Å,K%oy_ÈÆäœ$ʆ±O sUhr ®µ;šïo$DåêGä>Wãâ mž"sÚVL}I/wZoTr5„ÁôXþBçtãþH=áèc7p~·x‡žIÆbþMìfe#áx›y6øÆÊüçÚËýðV¸o¿äãKzÀ‰»4V»~†æ |¯^g1õm: ¼i-J誄mQ…®f©ë*€¶zƒÂÐj“«¯Ä‘Ê_ŒoÝ@:wdÜ$ÝÀù¸ßÕhƒÄÂ¥ âé½ФÄÍF•çØÑ/²>‘ I2[7¿°Ð©}ã˜v|­®¤6ϵ7˜è2P;µÐKö“‹!Õ}Ý;ìÝ€üW;8ØCt‚A‡Û»ÚtÔk­ÇûhÄмð+²|ö=òY®™uEè5 ¨ Vuvlxൎ.öÿºØÒ[Æ}P S#Â\5¢dn¦Ê¹2dºõ¦g>}Ê$…b;ûfÒaUèÛóM¨«œd²Ñ3ˆAwñÊI%í–q\Aé>Òe83jDLig /oü‘ÌPÐÚµš™öØF¦X$›M'z´‚Ñ4z_Mø§5*Ÿ{d\<ŬGC^3êŽCÜ7¾,E·ÔÆt<¬æ!ð£j sìQ¼²ó“|j%®g.÷xî!‰ÔBC\E}Ççj9™´)º<MûÇGÑ;°Èíì&9@*0®²½ÊÇ–NO,ÁtýÖùܤà;û$¹µ9’ÞXÁW‚Cñðˆlß?ÀãÏ)ñµ|Ò¹àÂ×\¹Ö9ôÜ{gÈíA)ò»ôµ&4_ Ø"ä¹eZh!Û,>·×¬Á O`÷øDlwνù¶rF—g¥{ªã-€gàµÂY‰YKÞ¼âDŒ@Qй6:Žp$C+·ÿfÃÁsœ”7‰8"P\b¬  € ì‡'.ü¹†Ò©dÿ]dŠÐ­¾šP¡ÕÊ󴯣Dm“H¬µòz7á.†Íx¡ÞÝZÖ~F˜‡ÐDÒ>±N° ü¿D°‚»o`6¬_æ<@'¼MÖ?ÜÞˆB§”¡¬Q‡i³ …{hoÈøõÉ}[©ÊIùFúQ_rjvÁ̧“ö‘;Aù‰åðÝàþÝ }²pœÃõ#Ú'Óo3ÃóFÚe³ö—µÇ*±‚uˆYLV¤@…ÏÌ#Õ7ÛžàX7mMƒûÚU¼ZÕØ›.;tŽWÃE×ëÑC¢Y(ÝÅ®‰gÉ5¼l­ô‚EŒSUįk¶niiÒÿ‘Ÿ—ØœID¢"^=b°•áO­ 4ÿÓyL­ ‘PÀÜ!s'ÍKM(sžT=`3C¤Dzù|°í F@^iqÖ²„¸ä®W¥´V€S§f¢¦‰ä—ü †}û˜_t|Šåªb>cA¨·¹ìrÙ÷‹=-ßT'~¾Pë]uœ{f mð­W ß‹©æs°Bæ(_©‘ôýAþ+~õ{’ÿÀ,Lñoðñjz¾Ö%ªä´ú‘¼årå—hs+”îe'þ=n›ðn(Å=yì†v;ÉSƒ¼!Ón{+Ùê~´\ðã·“ Ÿo±ûz¡´Ÿ~ ù1…m-ÞYaP£ÚeA©'>ÄüOöìJ2}â™,4 ÛIp¹Á®Е£Ìéúð{hŒG¸»»“AN cáüQ@ê@Îd¨ÏæŒêÔHOýƒdÍ×Á•`2 \Kˆ)3§^ë|ŸS£š{à‚t /¿y¸…}úæ]”øú ý>ÂpPí=§¨ |åoššY×’œ^‘HufÞåüS=þŒpüiHPŠ`0 nLíëöÈ£LTAê½x”¯_Æ3u¡ &È}ÿ°[0)5›ª N3{ ´~;´!testuser86 ˆ` O­ 4 € ª*ªÇËAtY×  œô;õ¬Få3ˆ¸‹Á?,\45æP ÀÂF¦±PéÏNæÎZ¤P9—°cO­ 4µ”õcA4RC Oñ úDpŽTÛ7—ŒzJZ›hss~)­vkîÖÕ¶i–´Qnoä4¶24<<{‰¾å¯üØ»íºñZý3¢eÍÞg74D¡~ðB4ȯ¸|&'OFZìOßf AŠÝg†JC‡«…þ~ƒ2œOá¹$–wïz+ù&ù ·„£äMûhÚé[f9ôˆuªû®ö³½Z´¡«òOÔuoqÝQ,…c`o\å+̦‘”ZÓØ5v…Âbôâ£Â²}ÕeoËhKopï²Îþ;  †¤Ïø8ÞÁ šíoH Svå½½'lŠŽñ}¡nãgkþ6¬‰iäÕ@§XƒÕÍÔDtRT¸Û÷. Í 4–€qmZ‹6:pciÅrI¯ãÇàÚ1ã‹öF¼„AË2žŒ=/QyBjåaÐC¨ú~´”Ìß‹yû…ù•›yÐÜy¬4–¸ã³w^¥šÉoúN+‹ÕùÞÝßCËݶ`{cU¼P`é¶%×kx+¿Å}6R¦5˜Lþ Ý- !‚3‰Zs±»­uòƒwtc:èÝd zjë…¥GÿMŠÊ ÿf–—és‡m55+ÔàúúiÊ44S•éÐ`4½!­Ê ‰ŠÆé‚K¥5ä‘ÔæcVåË)`uŽ&vúÒ]ç Ïï'{ùÈ3¸ø•ˆ!Zôª½iûsy¿‹¾2¼ ív¶=màv¡þX­"¡.Ó·»5L kÍÌ‚/½Zg ¡´OµÛ~Ø*.K7×ô&uΞåB†å˜)4a½Ðê÷!¨;’EGéë98´~Ó= @Þ«-?ïÁñÄ>¾Ù1€·§‰Ï_ݽ°9ï AŽK¿¤è…½¸Ý¤HVvÍgcñ³úøjÍ }vËZ ¯Do·+*LíVi®ûSŸïÙéèºÙXÅp¹ÊëðFµ<b{öáß(>)Lš†ãJ¹û’/WIÔNbx:^œb”5tMÎÿ’DÀŒÎLSž‚¤+3² ˆ’(¹µEÜ'.,UÙ†/0+)Ÿw„$Es=žcË÷8׳FâN¶÷«Ž7ã@3)Ž+«¿)ë¤ŒÉ„ÕÆ?™$É»úAÁlò9eùߟ ”É GÞI4À.ãÁòëXý@Ò$ô¹™¦–¬ ‘ £zUôŠ•_žÃ íAùl•C4Õ!iþKÀ¿ŸÞœ èŒî¯2'¸®ªÜÑVª<Á©¡Â-ëmD†ýôÔîrç½Ì¥&e.÷]HÐè)ÝWìPdäƒ÷FdÕµu5µ2X„˜N^ÑHbÓæîPõí9&¼AèâÎ…g´Ì ôÂ6tpw'ÉaÍ[kM¬ÕŠ=xµ¯2ª(†×"„[\5q#9ÍRYvB4Oq(D£eä°lÝ| Cl›ˆ_Rë¨'Ü5Å öŽÈ¶óX-[þóww´ÓBp&Ô×ÔJ/4TzÄ Ûû¢ÄØÇÉ  sç1‹Kìp·³.•VzÜAR ûFÓ\å Ž¯UªPÜã¼¶+ãרå~ïÌ#íÕÖÑÜ,€µþx~#QHæt6ºÂP‰]ŒÂÐÎ Dzã]áW˜ª²qf´-test user2 (test certificate) ‰8"Pcú/  € F€çó– Dç ^ý…SJÒŽ{À}b‘\÷ùd60ún¤)Èé}2LБÀ³ù´…K’åð“Èí+è^K;@ ¡ùYUÔÏþõ â½3ÊÍOÀÚño­ý¤xÒÖ¬‘lˆ úù]O úp}Z(0ÆNAùý,fš¹aÙ™|êha6ë³Êõ¸Š¤9£ ¾lPd‘«Ùq Vã? ÇÝ|;qÕœë+س FƒkL›ì$£§Kض’Á‡»,8Þ C7G5ûŸ–jDš~R Ýð¬ƒ1é$5 ;´}Ó{ó»¹CdÃê_áv§gØØcîúTÖ¯• ì)^|ï”…§„w‰±§Ù °bouncycastle-1.49.orig/test/data/openpgp/dsa/0000755000175000017500000000000012152033550020534 5ustar ebourgebourgbouncycastle-1.49.orig/test/data/openpgp/dsa/sigs/0000755000175000017500000000000012152033550021501 5ustar ebourgebourgbouncycastle-1.49.orig/test/data/openpgp/dsa/sigs/dsa-2048-224-sign.gpg0000644000175000017500000000021510550421007024601 0ustar ebourgebourg£›ÀËÌÈ-h®îÂàøû ãi•Á”âD]# ]##ÝâÌô<—Їw=RsròÂó‹rRx¹:ÂX¹ØX™@R \œ0’ì¬6Ì»o_Þf~ðŸóƒCyžz¼Ö%ÞÜ{8<÷ñ†K¢þH˜iõa~Òñ%jSW+œ³›Íitt{Ýr?bouncycastle-1.49.orig/test/data/openpgp/dsa/sigs/dsa-1024-384-sign.gpg0000644000175000017500000000017210550421007024603 0ustar ebourgebourg£›ÀËÌÀ)xpË=Ž)—û×(' ¦'ê™è[˜èg¦ç¹T óx¤æää+„çå¤pu¸±0r2°±2d¸8`ú{æ ͸fá¨-Õ½èYc«ÿ"–×2 z>Ìb 3n’´{÷‘xU§NFbouncycastle-1.49.orig/test/data/openpgp/dsa/sigs/dsa-1024-256-sign.gpg0000644000175000017500000000017310550421007024602 0ustar ebourgebourg£›ÀËÌÀ!xpË=Ž)—û×(' ¦'ê™è™šég¦ç¹T ³y¤æää+„çå¤pu¸±0r0°±2d¸8`ú7e3̯·›µÚ·pCÒžï«íŽ~x±…i6ÃŽüæW¦e†ve<.ïUܳóQáîbouncycastle-1.49.orig/test/data/openpgp/dsa/sigs/dsa-7680-384-sign.gpg0000644000175000017500000000027010550421007024620 0ustar ebourgebourg£›ÀËÌÈ)Øú]fé/Ñ Œ§UJSŠuÍÍ, t-Lt‹3Óó\*¾õHÍÉÉWÏ/ÊIáåê¨caäd`ceI1pq À ønËXŸ.ù0jžÒlíÔ?yš?¥pM”9Rxþú»Gâ’=ï®üeXÁz1ÝSýéMÞ´Ú[k¸ zf¬QëTw¹ÎâpÜËLë)cô™ý ÕVÞIÿ³oËæ…‹ÅŠ„÷ÜšyqŽà£%5‡îbouncycastle-1.49.orig/test/data/openpgp/dsa/sigs/dsa-3072-256-sign.gpg0000644000175000017500000000022610550421007024606 0ustar ebourgebourg£›ÀËÌÈ!(µùÈí‹÷’63žV)L)NÔ5607Ò525Ó-ÎLÏs©xøÄ#5''_!<¿('…—«#Ž…Qƒ• $ÅÀÅ)3ÀéÃ?ÅËoÚ8”Ž-îüòôyýƒ¶2«™»ô­8¾S Ìb¦W÷å‹ …Ö~w³6^´|W†€œVÈ·–Ï\.Ë=¤\Ê·O]Æêúšbouncycastle-1.49.orig/test/data/openpgp/dsa/sigs/dsa-1024-224-sign.gpg0000644000175000017500000000017110550421007024573 0ustar ebourgebourg£›ÀËÌÀ-xpË=Ž)—û×(' ¦'ê™èqqfzžK¥Ð_Ôœœ|…ðü¢œ®7An6V& §Lÿ~^†Ý+Ä¥”üæ±(þ}nV;Svöã}u¬ ó •¢û:òzÛv›= Ÿ~°èÓ«ïbouncycastle-1.49.orig/test/data/openpgp/dsa/sigs/dsa-15360-512-sign.gpg0000644000175000017500000000033010550421007024660 0ustar ebourgebourg£›ÀËÌÈ%X”<ç©ÓÅä…Œ§UK„RŠu MÍ tM t‹3Óó\*^öHÍÉÉWÏ/ÊIáåê˜ËÂ(ÈÅÀÆÊ’bà’ÐÁø=T¢I¢²ræ­ï‚\Ëž‹:¢•³ãDä=sF{Y÷¦Õ‹Ê’®ÛÕIHÊÏ .úÿG¨_¸äņ%ç®9¿ì³ãÿèíŽÓB7òö¾^ýdC]‹¬è›Y¶úmÞsò&G¼•ut³¹w;óiå½äÿßórVDI¿›ÙâåöƒùggýÆy*Òëbouncycastle-1.49.orig/test/data/openpgp/dsa/sigs/dsa-1024-512-sign.gpg0000644000175000017500000000017210550421007024574 0ustar ebourgebourg£›ÀËÌÀ%xpË=Ž)—û×(' ¦'ê™èšég¦ç¹T|LöHÍÉÉWÏ/ÊIáêpcaäb`ceÉ0pq Àôç‰2,èh“yg¶ûYî–”^»Ü{R!‰U ó ;rDŽgLíßÄ¢ÿ(ïÁºË:®³bouncycastle-1.49.orig/test/data/openpgp/dsa/sigs/dsa-1024-160-sign.gpg0000644000175000017500000000017410550421007024575 0ustar ebourgebourg£›ÀËÌÈ$xpË=Ž)—ûO«”¦'ê™èšèg¦ç¹T<Úꑚ““¯ž_”“ÂËÕáÆÂ(ÈÄÀÆÊ’bà‰¦a~îºIbSZ/¼¹½ê² ŠÕºe, óŒŸõÇÚï(´öpÌŠ=sôáÚÿïKbouncycastle-1.49.orig/test/data/openpgp/dsa/keys/0000755000175000017500000000000012152033550021507 5ustar ebourgebourgbouncycastle-1.49.orig/test/data/openpgp/dsa/keys/DSA-3072-256.sec0000644000175000017500000000260410550421007023515 0ustar ebourgebourg•ùDwÈ ½#s*Š€?ÜuvÉFø,>–ô—ÏÔÂ8áµ`fÖu›‹‚%‰•úÖÊBuº¨y#©ŽYê³ê­ ®8œÄZþ=1§'w—'%¡â€,ÑV-ÏÞèû©¿¯I*ß¾Øîi -™…«fp^EwAêÄÁ¼g\%G±dÛÄv"iÄÛ&dÈ1$·ígO˜O¿™NR¹°¹EÙÑû¾LX—;VÇ"i¾GlC6G‰·vH=OÖÅ=n`Å}0·êw9ŽU,[þõFÊ:¯*àë0£ÆW³zYÐ,¹ªEê 1°¦5ï¸gµV¼µF¦ˆ$þ±.ŒË î‰s¿óî&Gí€_~qRU!”á¹T£ùE¯K¥Òå¸%¢¸ÿ–½êÀ|ƒ+nÍåó`N·ž Š1àdT…4[ºh(F\+f]çÇe¸ÛÿtV†@ÃmE‘¢Èîì =Š ó€?òÉÈL9<›y³²ápF^î.<°ú¿Øt¤0€îµ »8ü«—oúzLj{!™08uÏ_FïÊî}¼3¬gŠcæ ‚e#,²Çý ÿhüqù:30ò¾$_‚oº]à¨w”UM |îZc/š.z#̤ ÷ø¿Z‚ò=Œ&à[¿Çoѧ*æÈàèô°Ù}L©l˜&Â×RÝi8h´'*&§kñ³}9Jð4†ΊE'%sVCðÒ wÍ ð Ú9·õbnAÄÇ÷kù[A¤’Òa!|ÞÏG½F "»F¤¼²Ž ……ÿªp‹|Ú«Žd:†‘MF˘lí)»“zÑ}6ŒùÙv–¶Ýݺûð ÕÈ]À¯ÐE„ØœØ cN´eãÛ”5šƒíeÑ•—­âî~_|ÞoDþíy‡ªzõU0Ü”ªÞc¸‡a4_wBÞ Ð|üD‘]%ÙDŒk,™V xûç°.¹‰dù¾:ó~8 ®"*ËL¶ð7†ÎºQÒ‹ù1È—žŠÏ¥K T/ã‹ÎðvÐó¹ƒìI÷˜‡ÓûñU‡==ïÏS†Ž«H镱À–\<Ù°¡þmˆÂvŽˆ$å þ' Ú‡tÜ-¾JÎêößUñÖ“»%½Id+ÕÈ·˜5–Š~óµÇG—3ÍØ°"b¸ 0‡ ûNÁUN)òÈßÁw>ÕLâ*nÔG<ÈG¥/ìàŽîÇ]ƒ­ÀZt¸…CAÉû 6Sé;6 æåŒ¾ ¾ðqŒò¼‰-W 1…ö Ô2‡ÁìÍ¡Ð}G•„Á³\©º…ŒÁð?Ð?Ÿ×ÍœÐdí5¼)Å&ѲL§4b?ÇiDú yïÀo*]ï é÷/œ1›=ƒ9X¹±å3ÆÜü:¶®­¸Ñw÷â žC$Ú„Y«1<¼H¯#nfà1x ïqä#Ò³ cŒÏš®páÁBv~)ÝR…­+\.VÕ‰ï7«/‘Ÿ²Pß2†³,_Ó@ ÃÓÍßÄmPè»gí#s\_Xnæ=œwKŸ@®ö‘×û¸ÜAâ‹n ÙâÏuå‡$7¨[Òmf·+Û£Û¨mš©©AË Àþþ« ‡{P`´6ü$bPŠѯû ñŽ¡¼²Í‘õŸpÆ¿>šqګЈ ~cvȸ׻ ¢Î\Ùl {nvd¬¬ËM迌»ÿÙÐø0dvÝ1š…ɦM‘ÀzI°üïûaƇW°/àÕ·ü•6{$±7eFíƒÍõ;&„ÅŒ[kÝQ!â÷¾•˜?ó7Ŭ·Ü pýkÇ–|§Ù†¯1¦¡Ôú/‚E'Š£'ÞV†ìj‹¯äW¿³¾F­—EXƒt3¡ ySüDZÏå¬Gèᄼ,*Î>ʇ¹?½qß+uúŸèáO<õA2ù¤k8Ö¶YxiÂõ‰¤Üý¢ þAðx`t]W䊛ö:M®ô¼tscsÀµÐ¾ÈZý*[Ôý$øTÁSòöÄ뺣÷É‹;g+#Á×¥¼;Ö|ŽIÅlŒ§©ÈX#¯G¶g¹m@8n“ ðí;î*”*˺oí×`,[¾ö¨ør¡J9?Z­lC`òn‚úP|Ò³µŽ%^m–íSc`“ÀEÈýæÔPÁ Ít‰×8”ÚôŒš?…†B.b9 J žhŠx®X™Ç3yØ*ä$Ê53,Ýz"÷†NØØ’ÃŒovbã6_¤_WÌ ‡å…½´rb#$¢BÉ<3Œ©¡j\ÉooS\ÿ¦ <¶•t=AæHXyRH³CX‚É÷ÑðúÌ„ÿ¡s/óA™ãßîu” ÆþÚœ‘êíœd|©³ .Jø¥ þWü’²_Ô¬<ÌÕã#Ö?8& =}sÛ\^>“øHÁ({>ù »ƒ&oÏHìÿ&;{n¨Ð‡ïa' Gk˃o^œeFkˆå/t.¯kø?žNa7åŒ"ÈÏ´ìI*DÜQ1Ì–B¤Üº÷wåf¶›íI4Ë&Þ  ®Y—ÜŒê>«ÊŠ­JšW„2J$%a¾¡ üœ÷Dä¼°ójKKøÌô4²ÉÑq6ŠÇð!x—þЫU¦Ò¼JM¿±Å©˜¤™õÕ[L’ûýF³vËã¯ÃscœIÃHãAärŽÞKïòfn/†S¥‰É µj¬Õ…åNâÑÖgqм» Kû‹J( çg£vl–1šŸbYqê€ . äyÙù, ð…Ô’ÉÈýq Z©k*O¤˜†bm@¼¿{d~?bÆÕmî 1·xñ‹s ô¬‰Â³bÛ¹³üÞW·-^±Ä/£Äü³"hŸËñõ€\õ‰÷µÆ¾g"0Ûª®bË,ÀfY:ŒÛ!ê¢æ7¿lô‚Ôæ~/*K“UzŠDIÙhÉC@‡ï´Œ1œ9 À×I Ôg‡ x„ÏPUb ¨³b꟡¸`£>S°Ý,BFâoìpmTÄ)@X¿œ´·ŸFÂåK ›þ¤åêŠg‘îèû»§J(Óã·ž¨…Ã4:Ól´Í&ÌýºX@þ¸Rsèô¡FØ{ÛÞ³`q›®¶ƒSkn)"E½túÕwöÈg_ìt®Ú¨*È8’‹Ùõ–”,=þ5”Òéû©gŒubÝÇð!$ÏÝc§Óqáí+Þ·wHåž`¨o´kø.™J*¿ÏÅ7j)•Ã}bpª #´=3pÕÌl0I~ o¹ÐΉ&!P'… ;S[Qãàikħz¸Ã–h¬œÀ äC°42Lñ''ÚËu”Bò'ßö¶ST²ZÛ¾»äƒÙ%÷aVI…JžÅú~ø?Jõ°¢–ÒSQ<0GÍ‚¡¹Þ´f}¢¼mk5…òçëYOcrüþ-g©Ÿ.‰÷áG¼›ß*n>þÇ bq ¾ûO¬†l‰•ÜØvøoýøÜZáæ€bß7WÏÃú£B ;ÿC#Øm0±M ‡÷=¾Öüݹ’4›N p÷WÅB^+ùâÍP/Œ‡Ú­¯E¨ž·Ä[EÕVxyZxê¹Åé/ÝãÑÒ0<+LgÊ qâA`>­ûn¦âéKfœ„—t¯€¸+ ­yÐ$ØDµ~˜¸Ï-H ¼WÖYêýTàú¤KK£)ÕUgãXœ2Kû³»àáQ¡#£@¨ ‹kŒ»“=)‹î S¬éë¬ä(¦ÝW-n[v3…ìíp»ï?¨È…\LªÂÿ0ð¿ÙM9Íé2~Uì=#Ý0UŸ6L§Â³» œQ¼¢iö[#Ø~]6à‹ëð@O ZÿÍç%÷zø÷fnD/)¯Ñ_uÜÂ\R99T—ó·jñ•Lí̬÷ô‘p¯ˆÅ3M0•øˆÒ«ZÙ›£P2е‚gë´€UsJ4gõl|u^€T`÷œEy{äÅ„œäwÛüÍ ‘ìÈo á“MÅŽ)…gmdmC4¨Ï^Ÿj¶ùtÎ5…6é:Ücþôiל%‡ùQMÕ5ߊó„·MšÃêq=M<—`ð$’”¦îüáÚ¥©ªXPpa¢½¼q{Qò>ç´¦´pù¨íU!j hý§‚ŸØÃ¶úô®;© ºTä²+Ô¼²yͦÙ׸4. «#D„ù½þw·Œ©xP‹ Ÿìµµ¤C‹¤£æmV|-rô ÀÏ/Ti=ñ=s×T 8O.ØåÛ¨ /Ú‹ƒ0$‹ ‹û$RÕvÆ w0¤]œÈUW”&MÝ=g[èx òØÒÚSrö&¢¼É:2‘/ù0hMÚY JU|&OÿVÜüÐKš'°é&$9£‘ϰ¸nØÈõŸ÷}npEø*´WWCë²í{µÁ`ïÞ(ï…P¡"#Væ“ç§(Ò=çe‹áw'úo|{õXw…éF΢zº)ø$6ÄÃM 9p«ŠûwþD0Õa_K¨#KÍ fÂñ jNÆ!;6ª>B÷ð?à7z uã„kxÿfä÷[¡¡GuiÔâÝì.?¬Ä’¹kZ$Eö)6;䇨¾êª®ä^VÂ7L|½½Ä`õÑ*ÂòThs7XN¢‡æórëŸ3Œ<•¬ûX„ù'å“ÓÊeþž¨^®ÂàcvÑ¿(¤37l=]ÁêY5vµ_Kn”w‰H¾;$³c‡,ØÐåeæœëp4[Û"äãËèÎgú÷%I%Þ ižý·hxE;Z§Ð:SîX ö‡çä꺡ƒ4Ç#¬GÉáv¶ a¦=cÃäë6þº[¢ ßÖçu¿S}iýÿ±F¯¢F?QËÓͬzú_yÑ›Œ%Ù0ðù ÞúÊ_œƒÓsõ)_S߀sáoZ ƒ½®IO©îã½*¤ÆGD+®hØ+dw·¼lpQÐïÀÆaFŸ¬S )—È%ËìV ~1‰ÕÔ̺¥ÃÈ¡ÖC#Ž(@GaIŽÔí©ùš¬PØö±Ä)]ÉK"æwc–¤“6Ô]¯‰%T@²‰ŽZB'á°cD$O.%ÌÊ©úëŒIž…%²uœOlÁ”§xj€O ÞØÛr€ka¹ù\†úÛ± ´ª ŠìÝZÒŒ¢a±k–‹-¸üþ Ñíß´¿žø§}ÔÇ{D­`¡í¼·›­2ªÒã/LæW‡YÍ‹zÔØdêÎ'BB@# É–#¡‘ý›¦ª ÚºÃÿ{CÄAbsâyþIã°Me#+êvJ€ç¯?¦ÉÌ>7¹ˆ“P½t}ü#I‰Ê«èrT°ÏY‚týɪӾH´ñÒsJ®f“YÕöwàB _hÍÅ÷ì µo» ù­xj€ÔkN2Õ^G=’«@˜0Ëÿ¯tc¹¨³©>Ÿ;Ê-¶§²ãä+©IÄ¿;q QÄÑô6+dwpÍŒoÎ]ã6Äà°ußÂ*Fß+'l {ä$#Gp>ØOóÃCv$³kÓF9š¸ƒWKQêXΚ^Á$’ Ä NئK‘ÄÌêÃaŠV¢,ÿÞnÃ4B:E^ÆYøO¿©ÜL@̦G–gt «ôús }ë°’oUªk5ú–x۔ʼ É.´r;næ\eœîsÓÕDõÙ 9Ë ×IÅü»;©£:•.ì è…æßo0ÃM.eð‹ƒ¶>Ró¾‡b\é’šC³·k’%Q.,Ââ‹ç5{u·ºU¤¶§ØM‰‚áƒ=š2vh p!eHº YxZF/+©epçMÁoÔüº“îY÷Š×q8/0Ê(¤]+:¦{ÑÁqŽ?‚΃Ï+Q¸ÌÓ„N7Åvi„VÎñœÂl19PlÉëÕóƵU VøÔѧ—” PÙÆJWÜퟗ&´Ç-ÇÖ’a7¹Àìè/ ·ÿ¹v|Šm¶ª†˜îÂI2ßì %I™Tkªu`Õá’‚+e¾Gí!’`¡.Š=a{~Á‘c’aí>ãgñHår´<Ë–®ŒÒžúë*Fƒ±i®§c}Ýw¬š+A5Žk}ø^Ãï¨ Lz–þDîÄüÆ…üq‘ꤻ&i.Å¥òï$œÍ‹’"²Ï§†ÂÆ£4•ôHh¾6 Òë´“M²?eÝæUñ›Éx´_ØsmÜìûõz*ŽÎÐCÓ¦G7óÍY_e‰ÿO±=†€ý³ƒG”³ä vÕoÊ™Ò &Ü(¤Jݽ!@æ,úDD ÃBb%8ÖWâ]}^&þ£“ႉº!~u{dF”HmÀn?€†@›Â.i†:%‡«%&:›}žÛ gà6]®°­ØP¯ÙöËPM °‹ö=ƒvYg…WsÅ?oF÷7B©ž'¢ ÷b‡ùL ‡wCÃi5©ÎeñW×ü,¯Lš ˆHxކn„v︉£åINws€Íf†*8¢OUoÄ?Í.¹²'tçDÄüœ¬%DEë® Ñ è†¨­#j°)Edét,-ý² b·öj£&ÑçÚÅ’K¹^¿$òÚ>rjfej»GòÖ0loò>ç¼òvQw àåL Ùø•(CTÎÜÐÀø˜v /®¿¦W–žtŽ€mi(dϵ&¶q4k‘vÖÉß+±éWSfI3‘6šê»F ü›ñ[ä¯àFˬœ†áëÇ”Å5¹ÐÔÔAìvôïþ"¼]4~Û;Xž:XîäÙr-©½ûŒý.Eo^Žñ¢ßp|Fù&";p;S»êq_ã/¦¯AÏ©Y:ž“£q¤y~B,òä"¤¯…òõçÉ&ÈðΛ&eƒ’gè˜a¢ëúUС ÀU(L@±êЖEÑ·nÞvä ×â.êâ™íL®¦ðÁaZÞ=µ)šˆÝ@/œ*RZv‰ªèÉ/”幘j[HV…ûÔ¹¨¦á­-@&åFíB%È”?IŽCÐVñÎ`leÒ |PÞT¡~iÒ2±×ïŒB¿ˆíŽvH¨M0”Vµ½ Â+×BZ wÃýË7u‰ôôöÑ{Ÿ­Š×¢Š¡ØiDŒh‹£MØ|÷ù²•&áØÝÅÊ%ꊱET,‘M·ƒbz`þ"ÿ­®Ðæ¹9àÞÑ£eŽ¿VP‹îÀm¸Â?‰I&wo¡ÄZÞ6Χ¾ž/p\A ÐpfšïÂx.º %»û}ÙWg“w"%q¯-¹Å©dëµ)¤øº`\¡˹ő‚¢õ5`ÎÉ® !.s­o$Þö‡@ˆxt(¹©º§hœ°ŒßEg Æcwó¼Û·'†pùÝÛ)øYÊV¯Kv kÓ“´WMU Ö· 1±·(*¶@Ë^Ú™-uÇ YÊUduù¶•×ý{:j5¡]úÝ©WaÆ4^,ßöjÄóæ·×) ¨¾àèXbòác%úhpôm؇.ߟêI™Iœô¶ÝôrpoY‡Il}^Ⱦw·Ñ©Y°.íë®Ú­gæñ[W‹ ß—¼-íùN|S‘G£ß’13cÓ”!ÄÖ2Z 1VCÿL¸¤}= £8‡¡Á½Þ‘–'®HfÌ„ô3FgLeë/ꦼ4…f32ä°r«|àµàé/’‹Ð.áWæh•+‡¯Ô›ÙuꌎoÊ Ýn”héeÕ¯½½@¦ÔÍŠ•5K»y먖ª“`Eé Ê‘°ç!…åªâÄR3œçTPÍ qsPÑYÐO0mZez_FúÍ®Y·‡õ›þHÙ1¥½ëìiJû…EŒJ4¯mýLã  7äX“Ëo%ïê<vGãC¤äÞ+´ÞW¦),hp à’¸j ²’àî"ÍŸ²à-™/Dhî×rÔ âŠ÷Ú^hÓ,$5Û_œÞ©¿ÜHjWƒ.K;ew]Uk™©ÛjHÔ;ä2„¼ø×Ù>· Õ†³sWk‹6¥2çÚªnÇMédLްmi‰ Ùá8ÚöSãÅFà[k*ÈÖ‚ƒ³ú[ãt®mCe¢ žph X½ÝOHW’³5C¤‘é Tr½;+±¬w†’il•WNêJ¡RúÂê¶p‘u ;ê§e%ȼ¸]v¯à¹™âÝŽ¤àú´ DSA-15360-512ˆ¹ !Dxµ« € rcœåBÑc¡’©ÿ[ÍáX¬ûÊ„p>tUR»b-Îá™$¿áêb埛|‘Í žgMÛ&ïÒR¤O²÷ųh§pŠ_DóÂ=ö¢f+}ˆa« 1Nh,¡nòé3¼]·@Ôù}ÃUð8³³Çö‘lºYŒHJÍ |ý y ÙNJz=ŒÁ2«á¯bouncycastle-1.49.orig/test/data/openpgp/dsa/keys/DSA-2048-224.sec0000644000175000017500000000176410550421007023520 0ustar ebourgebourg•qDwVׂÜ,ÄŒNô¥È—þdÉ—DTâP§3ø;(›‰½`$o(rkßb6ƒòÏ20R'®N‹vtqt ï±`Ñ\~Šk½7˜@Œ„Ûˆ^ög A‘NË~¾ÈsfqÅQwpø¬>t[ÏñXÔ×íø·Âm ¡rÞ!( ÷YØn¢]­V‹Ú'•^~ÐÌ5Žs…”0® {ÂÕ¾¶n1ñIˆß' Mã ê¼ôö=ÌSZÀ %’ëü–È Yà[-Ÿåמ‚GD¸~O®îš½ÊGn}C¼ËAhâïרl^ƒ¶ébÍkéáåø®ÔB»ÿ'³4ÅØ7à´®œo8¶‚* ŸœÑÈôÀ! zÓýtVÚd,±ÎÈzqéŸZX¢-½‰Lù”{KBh[%%BA$•€e«Àì5è =QLéäÕ¯I¾–®¶ÔáDÌë8Xˆ,y‹ˆ”¤ ‡ãS”oÏZäk=¸Lé¼X¦É¥È76âó Ô)_‰YK-¨‡¡ÒÑ"íÑÞ!~>Ìœlrí[¯c`ݤIÜØ×˜Jç3É£‰'uŰ`Ô³;åcÚôLÆÃ7ÓÈLvˆH|´†BKM } ·ÉGÞw›ßˆm”L¶q>¨ÉwUf›ü]Õ¿¥¾O^›’/î©ÑF“Œh›½eµ¨¾Æ#ÿ›ü]fZ!zƒwòšûÍB²HÈ3?ýÙs·<–tˆ­wy,—HáGþ…ž)ýqƒi]…=l±kÛ‹`L Èwîœ ¦ß âxELòÄÖ´9„'Ðø¡€7¯²ÿI#& õQ©å-Ÿÿ3PÕŸÖ£!I,\Ù% Ø{‘uSS",P ŒŒr@ÈèZƒ<§âÚúì’´ÙüïÿêZÎU®Ýƒ ù`nÖ=Þ]p|4\yØŠ‡Ïß hÕk çãklCŒïñ»[Fù} ¼Ù£ ¥b1•T úúe™ŸŸuÿû> ¯¤‹ÊÚÀ8iþÕ³Lhmwà•P—ô[W©Ÿ¨AM^b‡@»æ7ÐÑJ¹Õ>+þN‹sï¢9ü`ø{ð%|¸ñN²]·ÑjÄì;‹ÉrM磉ýÏÜà'pz|<”û(&–ñi¯oÇ×|m6u†ã½´ DSA-2048-224ˆp DwV € 7'DAûô0Pà¥ä0Þì Uº÷ˆp,¤“H¦Vå9˜§‰{7Ý!`‹µ¿°c¼ýÖÀ.Ê?dƒ¨Þ=©T«lz_bouncycastle-1.49.orig/test/data/openpgp/dsa/keys/DSA-3072-256.pub0000644000175000017500000000247110550421007023533 0ustar ebourgebourg™®DwÈ ½#s*Š€?ÜuvÉFø,>–ô—ÏÔÂ8áµ`fÖu›‹‚%‰•úÖÊBuº¨y#©ŽYê³ê­ ®8œÄZþ=1§'w—'%¡â€,ÑV-ÏÞèû©¿¯I*ß¾Øîi -™…«fp^EwAêÄÁ¼g\%G±dÛÄv"iÄÛ&dÈ1$·ígO˜O¿™NR¹°¹EÙÑû¾LX—;VÇ"i¾GlC6G‰·vH=OÖÅ=n`Å}0·êw9ŽU,[þõFÊ:¯*àë0£ÆW³zYÐ,¹ªEê 1°¦5ï¸gµV¼µF¦ˆ$þ±.ŒË î‰s¿óî&Gí€_~qRU!”á¹T£ùE¯K¥Òå¸%¢¸ÿ–½êÀ|ƒ+nÍåó`N·ž Š1àdT…4[ºh(F\+f]çÇe¸ÛÿtV†@ÃmE‘¢Èîì =Š ó€?òÉÈL9<›y³²ápF^î.<°ú¿Øt¤0€îµ »8ü«—oúzLj{!™08uÏ_FïÊî}¼3¬gŠcæ ‚e#,²Çý ÿhüqù:30ò¾$_‚oº]à¨w”UM |îZc/š.z#̤ ÷ø¿Z‚ò=Œ&à[¿Çoѧ*æÈàèô°Ù}L©l˜&Â×RÝi8h´'*&§kñ³}9Jð4†ΊE'%sVCðÒ wÍ ð Ú9·õbnAÄÇ÷kù[A¤’Òa!|ÞÏG½F "»F¤¼²Ž ……ÿªp‹|Ú«Žd:†‘MF˘lí)»“zÑ}6ŒùÙv–¶Ýݺûð ÕÈ]À¯ÐE„ØœØ cN´eãÛ”5šƒíeÑ•—­âî~_|ÞoDþíy‡ªzõU0Ü”ªÞc¸‡a4_wBÞ Ð|üD‘]%ÙDŒk,™V xûç°.¹‰dù¾:ó~8 ®"*ËL¶ð7†ÎºQÒ‹ù1È—žŠÏ¥K T/ã‹ÎðvÐó¹ƒìI÷˜‡ÓûñU‡==ïÏS†Ž«H镱À–\<Ù°¡þmˆÂvŽˆ$å þ' Ú‡tÜ-¾JÎêößUñÖ“»%½Id+ÕÈ·˜5–Š~óµÇG—3ÍØ°"b¸ 0‡ ûNÁUN)òÈßÁw>ÕLâ*nÔG<ÈG¥/ìàŽîÇ]ƒ­ÀZt¸…CAÉû 6Sé;6 æåŒ¾ ¾ðqŒò¼‰-W 1…ö Ô2‡ÁìÍ¡Ð}G•„Á³\©º…ŒÁð?Ð?Ÿ×ÍœÐdí5¼)Å&ѲL§4b?ÇiDú yïÀo*]ï é÷/œ1›=ƒ9X¹±å3ÆÜü:¶®­¸Ñw÷â žC$Ú„Y«1<¼H¯#nfà1x ïqä#Ò³ cŒÏš®páÁBv~)ÝR…­+\.VÕ‰ï7«/‘Ÿ²Pß2†³,_Ó@ ÃÓÍßÄmPè»gí#s\_Xnæ=œwKŸ@®ö‘×û¸ÜAâ‹n ÙâÏuå‡$7¨[Òmf·+Û£Û¨mš©©AË À´ DSA-3072-256ˆx DwÈ € ³ÄÛÑÞb³Ûþ1…ÛVÿ@ÙádHïE宇Ӌ~9›iûâïÛ*ù\ÿG¦t7QÕûqÒì ¢Èȉ:ÖÐPµŸš…²<ébouncycastle-1.49.orig/test/data/openpgp/dsa/keys/DSA-2048-224.pub0000644000175000017500000000165510550421007023533 0ustar ebourgebourg™*DwVׂÜ,ÄŒNô¥È—þdÉ—DTâP§3ø;(›‰½`$o(rkßb6ƒòÏ20R'®N‹vtqt ï±`Ñ\~Šk½7˜@Œ„Ûˆ^ög A‘NË~¾ÈsfqÅQwpø¬>t[ÏñXÔ×íø·Âm ¡rÞ!( ÷YØn¢]­V‹Ú'•^~ÐÌ5Žs…”0® {ÂÕ¾¶n1ñIˆß' Mã ê¼ôö=ÌSZÀ %’ëü–È Yà[-Ÿåמ‚GD¸~O®îš½ÊGn}C¼ËAhâïרl^ƒ¶ébÍkéáåø®ÔB»ÿ'³4ÅØ7à´®œo8¶‚* ŸœÑÈôÀ! zÓýtVÚd,±ÎÈzqéŸZX¢-½‰Lù”{KBh[%%BA$•€e«Àì5è =QLéäÕ¯I¾–®¶ÔáDÌë8Xˆ,y‹ˆ”¤ ‡ãS”oÏZäk=¸Lé¼X¦É¥È76âó Ô)_‰YK-¨‡¡ÒÑ"íÑÞ!~>Ìœlrí[¯c`ݤIÜØ×˜Jç3É£‰'uŰ`Ô³;åcÚôLÆÃ7ÓÈLvˆH|´†BKM } ·ÉGÞw›ßˆm”L¶q>¨ÉwUf›ü]Õ¿¥¾O^›’/î©ÑF“Œh›½eµ¨¾Æ#ÿ›ü]fZ!zƒwòšûÍB²HÈ3?ýÙs·<–tˆ­wy,—HáGþ…ž)ýqƒi]…=l±kÛ‹`L Èwîœ ¦ß âxELòÄÖ´9„'Ðø¡€7¯²ÿI#& õQ©å-Ÿÿ3PÕŸÖ£!I,\Ù% Ø{‘uSS",P ŒŒr@ÈèZƒ<§âÚúì’´ÙüïÿêZÎU®Ýƒ ù`nÖ=Þ]p|4\yØŠ‡Ïß hÕk çãklCŒïñ»[Fù} ¼Ù£ ¥b1•T úúe™ŸŸuÿû> ¯¤‹ÊÚÀ8iþÕ³Lhmwà•P—ô[W©Ÿ¨AM^b‡@»æ7ÐÑJ¹Õ>+´ DSA-2048-224ˆp DwV € 7'DAûô0Pà¥ä0Þì Uº÷ˆp,¤“H¦Vå9˜§‰{7Ý!`‹µ¿°c¼ýÖÀ.Ê?dƒ¨Þ=©T«lz_bouncycastle-1.49.orig/test/data/openpgp/dsa/keys/DSA-7680-384.sec0000644000175000017500000000620410550421007023530 0ustar ebourgebourg• ÙDw¦“ƒ@º×S~'”í,—~LÆ ÚHÃ:ÀXJCOP'“aæ/¿'(ä¦íçdž˜ÊY?f3Dlº™-¾Þë¹#ú¶»õ°òŸ »“ÙÌSØ–ÛOÊg3PMþ(5ÚɉöÑ:3æ›fÙSŒÉgJlnÕ€{GõÐR>æB”ü‚Õ¿ÀA¡óG#øšûø£—äfQã­T~M¼Ê¡»%ƒM`¾áwN_?^ –G¸»ã/è ïbC Ò‘75‚p™=ÑÇ’ #Ø€)Ã#Ã)›&Å ..ˆÞ°Ûñøœ™W³˜/²œ9÷v3ŠIz–±·a,´”f”–ŒMÇ—焎ҕqç4ïÂõÿjU,ýc ãþ4Øk¹{ðå,ñâ`>Ö.CÛ=Ê4l¢Fµ‰F°ów“ËžÝ$‚sÁ›µ3qe¯î´ #¬ rj¿”}™#WŒuø6fD[BB bt–"Iµï23}_òBCrÃÐï»(5»«:ûFNùþ•އ0ž«sا+ÅÏ:>@FÈoVÃL.™œAO*ý]@rr«ëE)¤ÓÖ°Æ ´/NEÜm:/t­—J³[ÑÚÝ8ñÕW¶\¯îõÈz2·ã’m5Ì‘ñÍyª<$‹DItw¦\ðö5]˜%IæÝªÏâ'ÞôbýÅ1 · B«‰³é°ÂVž „slL+\D—òñO!±Ú(óKÝöÉË üÍÉ2RjÈðbºaÇûïC*ºõcÞoº%’qVýÚª½nZKÔTÃÚœxɲ4wÿ±‹!1}QJRF½D{I«,õ@Kè±R°Ûd:˜’[øßbSéÖŽ…êᆀ?ÈÇVDø=ÁB`DçxkZµa¯Ò·eïŸmEÑX¡iS+(·>»@h¥RÍÑA …ÔMÅR«ƒ¥ÌrÍ}± Ãûú<¬w«­9T ÖeÊûÙ¹H2iøþ"L„ÓÞgÐ èmýÆd@«ökÙF,êFlš× "^9S(¨©ßäßM#Ì6 êþkƒÖ'ÚeƒØqÀYÇPtºÌÓ+«kDm6û7Z÷ViÜë”`ôRjΓfÊSF¯ž»š´G“FõtZDzRÙ‡5S¹#7TWqq|N×%85}ºÅšSqÑÎ×õ`þÉ29(˜ Â.?É«è² `JT[ƱÛG4êÄôÿê‘kWÿêy€•Ø^šgÏi„yjŒÇ 牊ΟÚw&PØ«-Ã~†q›®~V-ý6l‹ºØ·aN@õbþŒñ,`ÐË(íyû²ŒáÛſҺSå._~Ïßû®P¼Îsú<Þeb„_¿]Ïb4+SÔ6w„ËßùlòG·"ÓӮȱúPOP²Õ¦NÇõì4–¤,/gÚxU^³‚ݤ3R ¼« 1aè 2R¬o0W?Ñ,}cÙ™žc8+·Cê¦ÿ“ã¯.Þèb‚¨gQwi­¨Kö`íVäóS÷Ú0J»fFgr'j ý’ø¿Ëmkª1Ìu¼,Ëfg·©I ÷m³´1Òo2)ÔLÂ&$=/ í¼**øÁKZ@8öø§ð¼èÁÏë³—Ì<¢qú—ûÿu®ä;ËÈ-†m‚Évïz Ã÷­–̺3°6ZÞDZMVƒHÿÞ¦qêöA™: [øA,æV]{C›éöo²0 ÚœX©ºƒ-$•¶ÈÆÐ)t+¥¸ðȇÄÝðîëjZz ;I±Å©çÉЦ³xHf‚ïWµ½ß]ï¹ ~•™r²œ#Ã@NP¨ »Ž,1ä­ȹ7‡Ä H';ŽâG¸üPàQ´§˜†#_ëúØ®rie¾Q¢XM¿U@ßL"¾¶µ,#DŽß. f§(…—LÏë‰T‚&”òí!ß”ÈÂÕåÝW°Ñ§™š´µŒzÀã•þoDÅÕs<åòj7GBæϙv¸T¹h4FƒOcâ¼§Ëû<_l‘…Ôík,?òÄ>ËÆ¯Å‡ Ûq/™ÎÑ588±3ûŽ‚àÔ>¹±º¬Æ}„\>­‚õ ‡]Â&Tž]Åkò\Œ…ÔóÇʇͼqËP†oÙGì¥?`¡ÆI‡![Eöa­IéTû/’ë¶©Ë*IpÎW±ò$RŒ©± ‰{šl!K/ÞîÜμ-†uBßT*¸côÉ1;;.ÅîGÚîm°¼K_3"0Õoy )G>yxÀ[þ,uè+ãˆ[`_8ÏêŠwH³âÜ%_ÒØvø•v0T]2w Ùö^SuyšàTÖç€1¨áÞfßõ£AµÙš´¹hóÜág/{'nšº0®l#5ù€n´ DSA-7680-384ˆ˜ Dw¦ € …÷¥Üô[`:M}åqÔJRá Àzh¹½Î)iyó ž”½ZjÂpê?Iw ±U¡ÌºñÛÁn°*V¬6®Hóû›ü0f“~,G|¡‘}ÔN ±¯A%Dv™LrU3(®ÐwŒ¤C€È¿(µÚØJxðaÑ–lãb) Û™üˆ7ɦQã/nÚ*|AHwí YkcÇ{ºXÉí49BT÷ã?ésä;A„í/ŸA YoC÷·&t•¾ÚJÛy©L®Š÷?NõüVJÁÌ59ÅMO΋u,Ý¡êZGb5—X¼ó‰uXŸ`7CÒûIüútpj ˆlCdeÕ8lŸh{žOªº Kðóß$4ä½@7RÒñá‹v(6‚”´Cáé÷èÇi¦ €¥rÐ÷[¢Ó%°;™naGW‚Ç´ DSA-1024-160ˆa!DxâR € Á´Þ”ÓŽ@[ŸvPß;«L°áÏÑÿ6îøô¸L:Ÿ}½À]÷îƒM•W…*îûÊ¢bouncycastle-1.49.orig/test/data/openpgp/dsa/keys/DSA-1024-160.sec0000644000175000017500000000112510550421007023477 0ustar ebourgebourg•áDxâR—ˆЬ³F<þ_m„`Þ€¢2¨å8Y°"*üU ÿËîà#˜æˆ)åFgù­‹ãuäÍØËÊ”ð¯{Ä!/¤ªw®Á,!šŒ)fÁÕ€µ §='ÖTÎ9\ŠBx ‹O\²j0^g¾|€"ˆök>Î)iyó ž”½ZjÂpê?Iw ±U¡ÌºñÛÁn°*V¬6®Hóû›ü0f“~,G|¡‘}ÔN ±¯A%Dv™LrU3(®ÐwŒ¤C€È¿(µÚØJxðaÑ–lãb) Û™üˆ7ɦQã/nÚ*|AHwí YkcÇ{ºXÉí49BT÷ã?ésä;A„í/ŸA YoC÷·&t•¾ÚJÛy©L®Š÷?NõüVJÁÌ59ÅMO΋u,Ý¡êZGb5—X¼ó‰uXŸ`7CÒûIüútpj ˆlCdeÕ8lŸh{žOªº Kðóß$4ä½@7RÒñá‹v(6‚”´Cáé÷èÇi¦ €¥rÐ÷[¢Ó%°;™naGW‚ÇþQm²d€ô-`‹ïÖqÃ¥yn:êœE<"{Ↄ»QŒ"ÅVýWúÝjh Ù$q§à´s \«aÂU´ DSA-1024-160ˆa!DxâR € Á´Þ”ÓŽ@[ŸvPß;«L°áÏÑÿ6îøô¸L:Ÿ}½À]÷îƒM•W…*îûÊ¢bouncycastle-1.49.orig/test/data/openpgp/dsa/keys/DSA-15360-512.sec0000644000175000017500000001400610550421007023572 0ustar ebourgebourg•9Dxµ«<øo¿ƒœ‘æCàÀaZ<†qk´Šl áö+ñQÚRaÑ¿»òýñ“eÕ Áî›_}Pun4X+ËzZó÷“9†­Û¶§nEcŒU~ЍuÎ4¨](Ž D1bâ*S-¤x›0c_x ø%>ˆ ~cvȸ׻ ¢Î\Ùl {nvd¬¬ËM迌»ÿÙÐø0dvÝ1š…ɦM‘ÀzI°üïûaƇW°/àÕ·ü•6{$±7eFíƒÍõ;&„ÅŒ[kÝQ!â÷¾•˜?ó7Ŭ·Ü pýkÇ–|§Ù†¯1¦¡Ôú/‚E'Š£'ÞV†ìj‹¯äW¿³¾F­—EXƒt3¡ ySüDZÏå¬Gèᄼ,*Î>ʇ¹?½qß+uúŸèáO<õA2ù¤k8Ö¶YxiÂõ‰¤Üý¢ þAðx`t]W䊛ö:M®ô¼tscsÀµÐ¾ÈZý*[Ôý$øTÁSòöÄ뺣÷É‹;g+#Á×¥¼;Ö|ŽIÅlŒ§©ÈX#¯G¶g¹m@8n“ ðí;î*”*˺oí×`,[¾ö¨ør¡J9?Z­lC`òn‚úP|Ò³µŽ%^m–íSc`“ÀEÈýæÔPÁ Ít‰×8”ÚôŒš?…†B.b9 J žhŠx®X™Ç3yØ*ä$Ê53,Ýz"÷†NØØ’ÃŒovbã6_¤_WÌ ‡å…½´rb#$¢BÉ<3Œ©¡j\ÉooS\ÿ¦ <¶•t=AæHXyRH³CX‚É÷ÑðúÌ„ÿ¡s/óA™ãßîu” ÆþÚœ‘êíœd|©³ .Jø¥ þWü’²_Ô¬<ÌÕã#Ö?8& =}sÛ\^>“øHÁ({>ù »ƒ&oÏHìÿ&;{n¨Ð‡ïa' Gk˃o^œeFkˆå/t.¯kø?žNa7åŒ"ÈÏ´ìI*DÜQ1Ì–B¤Üº÷wåf¶›íI4Ë&Þ  ®Y—ÜŒê>«ÊŠ­JšW„2J$%a¾¡ üœ÷Dä¼°ójKKøÌô4²ÉÑq6ŠÇð!x—þЫU¦Ò¼JM¿±Å©˜¤™õÕ[L’ûýF³vËã¯ÃscœIÃHãAärŽÞKïòfn/†S¥‰É µj¬Õ…åNâÑÖgqм» Kû‹J( çg£vl–1šŸbYqê€ . äyÙù, ð…Ô’ÉÈýq Z©k*O¤˜†bm@¼¿{d~?bÆÕmî 1·xñ‹s ô¬‰Â³bÛ¹³üÞW·-^±Ä/£Äü³"hŸËñõ€\õ‰÷µÆ¾g"0Ûª®bË,ÀfY:ŒÛ!ê¢æ7¿lô‚Ôæ~/*K“UzŠDIÙhÉC@‡ï´Œ1œ9 À×I Ôg‡ x„ÏPUb ¨³b꟡¸`£>S°Ý,BFâoìpmTÄ)@X¿œ´·ŸFÂåK ›þ¤åêŠg‘îèû»§J(Óã·ž¨…Ã4:Ól´Í&ÌýºX@þ¸Rsèô¡FØ{ÛÞ³`q›®¶ƒSkn)"E½túÕwöÈg_ìt®Ú¨*È8’‹Ùõ–”,=þ5”Òéû©gŒubÝÇð!$ÏÝc§Óqáí+Þ·wHåž`¨o´kø.™J*¿ÏÅ7j)•Ã}bpª #´=3pÕÌl0I~ o¹ÐΉ&!P'… ;S[Qãàikħz¸Ã–h¬œÀ äC°42Lñ''ÚËu”Bò'ßö¶ST²ZÛ¾»äƒÙ%÷aVI…JžÅú~ø?Jõ°¢–ÒSQ<0GÍ‚¡¹Þ´f}¢¼mk5…òçëYOcrüþ-g©Ÿ.‰÷áG¼›ß*n>þÇ bq ¾ûO¬†l‰•ÜØvøoýøÜZáæ€bß7WÏÃú£B ;ÿC#Øm0±M ‡÷=¾Öüݹ’4›N p÷WÅB^+ùâÍP/Œ‡Ú­¯E¨ž·Ä[EÕVxyZxê¹Åé/ÝãÑÒ0<+LgÊ qâA`>­ûn¦âéKfœ„—t¯€¸+ ­yÐ$ØDµ~˜¸Ï-H ¼WÖYêýTàú¤KK£)ÕUgãXœ2Kû³»àáQ¡#£@¨ ‹kŒ»“=)‹î S¬éë¬ä(¦ÝW-n[v3…ìíp»ï?¨È…\LªÂÿ0ð¿ÙM9Íé2~Uì=#Ý0UŸ6L§Â³» œQ¼¢iö[#Ø~]6à‹ëð@O ZÿÍç%÷zø÷fnD/)¯Ñ_uÜÂ\R99T—ó·jñ•Lí̬÷ô‘p¯ˆÅ3M0•øˆÒ«ZÙ›£P2е‚gë´€UsJ4gõl|u^€T`÷œEy{äÅ„œäwÛüÍ ‘ìÈo á“MÅŽ)…gmdmC4¨Ï^Ÿj¶ùtÎ5…6é:Ücþôiל%‡ùQMÕ5ߊó„·MšÃêq=M<—`ð$’”¦îüáÚ¥©ªXPpa¢½¼q{Qò>ç´¦´pù¨íU!j hý§‚ŸØÃ¶úô®;© ºTä²+Ô¼²yͦÙ׸4. «#D„ù½þw·Œ©xP‹ Ÿìµµ¤C‹¤£æmV|-rô ÀÏ/Ti=ñ=s×T 8O.ØåÛ¨ /Ú‹ƒ0$‹ ‹û$RÕvÆ w0¤]œÈUW”&MÝ=g[èx òØÒÚSrö&¢¼É:2‘/ù0hMÚY JU|&OÿVÜüÐKš'°é&$9£‘ϰ¸nØÈõŸ÷}npEø*´WWCë²í{µÁ`ïÞ(ï…P¡"#Væ“ç§(Ò=çe‹áw'úo|{õXw…éF΢zº)ø$6ÄÃM 9p«ŠûwþD0Õa_K¨#KÍ fÂñ jNÆ!;6ª>B÷ð?à7z uã„kxÿfä÷[¡¡GuiÔâÝì.?¬Ä’¹kZ$Eö)6;䇨¾êª®ä^VÂ7L|½½Ä`õÑ*ÂòThs7XN¢‡æórëŸ3Œ<•¬ûX„ù'å“ÓÊeþž¨^®ÂàcvÑ¿(¤37l=]ÁêY5vµ_Kn”w‰H¾;$³c‡,ØÐåeæœëp4[Û"äãËèÎgú÷%I%Þ ižý·hxE;Z§Ð:SîX ö‡çä꺡ƒ4Ç#¬GÉáv¶ a¦=cÃäë6þº[¢ ßÖçu¿S}iýÿ±F¯¢F?QËÓͬzú_yÑ›Œ%Ù0ðù ÞúÊ_œƒÓsõ)_S߀sáoZ ƒ½®IO©îã½*¤ÆGD+®hØ+dw·¼lpQÐïÀÆaFŸ¬S )—È%ËìV ~1‰ÕÔ̺¥ÃÈ¡ÖC#Ž(@GaIŽÔí©ùš¬PØö±Ä)]ÉK"æwc–¤“6Ô]¯‰%T@²‰ŽZB'á°cD$O.%ÌÊ©úëŒIž…%²uœOlÁ”§xj€O ÞØÛr€ka¹ù\†úÛ± ´ª ŠìÝZÒŒ¢a±k–‹-¸üþ Ñíß´¿žø§}ÔÇ{D­`¡í¼·›­2ªÒã/LæW‡YÍ‹zÔØdêÎ'BB@# É–#¡‘ý›¦ª ÚºÃÿ{CÄAbsâyþIã°Me#+êvJ€ç¯?¦ÉÌ>7¹ˆ“P½t}ü#I‰Ê«èrT°ÏY‚týɪӾH´ñÒsJ®f“YÕöwàB _hÍÅ÷ì µo» ù­xj€ÔkN2Õ^G=’«@˜0Ëÿ¯tc¹¨³©>Ÿ;Ê-¶§²ãä+©IÄ¿;q QÄÑô6+dwpÍŒoÎ]ã6Äà°ußÂ*Fß+'l {ä$#Gp>ØOóÃCv$³kÓF9š¸ƒWKQêXΚ^Á$’ Ä NئK‘ÄÌêÃaŠV¢,ÿÞnÃ4B:E^ÆYøO¿©ÜL@̦G–gt «ôús }ë°’oUªk5ú–x۔ʼ É.´r;næ\eœîsÓÕDõÙ 9Ë ×IÅü»;©£:•.ì è…æßo0ÃM.eð‹ƒ¶>Ró¾‡b\é’šC³·k’%Q.,Ââ‹ç5{u·ºU¤¶§ØM‰‚áƒ=š2vh p!eHº YxZF/+©epçMÁoÔüº“îY÷Š×q8/0Ê(¤]+:¦{ÑÁqŽ?‚΃Ï+Q¸ÌÓ„N7Åvi„VÎñœÂl19PlÉëÕóƵU VøÔѧ—” PÙÆJWÜퟗ&´Ç-ÇÖ’a7¹Àìè/ ·ÿ¹v|Šm¶ª†˜îÂI2ßì %I™Tkªu`Õá’‚+e¾Gí!’`¡.Š=a{~Á‘c’aí>ãgñHår´<Ë–®ŒÒžúë*Fƒ±i®§c}Ýw¬š+A5Žk}ø^Ãï¨ Lz–þDîÄüÆ…üq‘ꤻ&i.Å¥òï$œÍ‹’"²Ï§†ÂÆ£4•ôHh¾6 Òë´“M²?eÝæUñ›Éx´_ØsmÜìûõz*ŽÎÐCÓ¦G7óÍY_e‰ÿO±=†€ý³ƒG”³ä vÕoÊ™Ò &Ü(¤Jݽ!@æ,úDD ÃBb%8ÖWâ]}^&þ£“ႉº!~u{dF”HmÀn?€†@›Â.i†:%‡«%&:›}žÛ gà6]®°­ØP¯ÙöËPM °‹ö=ƒvYg…WsÅ?oF÷7B©ž'¢ ÷b‡ùL ‡wCÃi5©ÎeñW×ü,¯Lš ˆHxކn„v︉£åINws€Íf†*8¢OUoÄ?Í.¹²'tçDÄüœ¬%DEë® Ñ è†¨­#j°)Edét,-ý² b·öj£&ÑçÚÅ’K¹^¿$òÚ>rjfej»GòÖ0loò>ç¼òvQw àåL Ùø•(CTÎÜÐÀø˜v /®¿¦W–žtŽ€mi(dϵ&¶q4k‘vÖÉß+±éWSfI3‘6šê»F ü›ñ[ä¯àFˬœ†áëÇ”Å5¹ÐÔÔAìvôïþ"¼]4~Û;Xž:XîäÙr-©½ûŒý.Eo^Žñ¢ßp|Fù&";p;S»êq_ã/¦¯AÏ©Y:ž“£q¤y~B,òä"¤¯…òõçÉ&ÈðΛ&eƒ’gè˜a¢ëúUС ÀU(L@±êЖEÑ·nÞvä ×â.êâ™íL®¦ðÁaZÞ=µ)šˆÝ@/œ*RZv‰ªèÉ/”幘j[HV…ûÔ¹¨¦á­-@&åFíB%È”?IŽCÐVñÎ`leÒ |PÞT¡~iÒ2±×ïŒB¿ˆíŽvH¨M0”Vµ½ Â+×BZ wÃýË7u‰ôôöÑ{Ÿ­Š×¢Š¡ØiDŒh‹£MØ|÷ù²•&áØÝÅÊ%ꊱET,‘M·ƒbz`þ"ÿ­®Ðæ¹9àÞÑ£eŽ¿VP‹îÀm¸Â?‰I&wo¡ÄZÞ6Χ¾ž/p\A ÐpfšïÂx.º %»û}ÙWg“w"%q¯-¹Å©dëµ)¤øº`\¡˹ő‚¢õ5`ÎÉ® !.s­o$Þö‡@ˆxt(¹©º§hœ°ŒßEg Æcwó¼Û·'†pùÝÛ)øYÊV¯Kv kÓ“´WMU Ö· 1±·(*¶@Ë^Ú™-uÇ YÊUduù¶•×ý{:j5¡]úÝ©WaÆ4^,ßöjÄóæ·×) ¨¾àèXbòác%úhpôm؇.ߟêI™Iœô¶ÝôrpoY‡Il}^Ⱦw·Ñ©Y°.íë®Ú­gæñ[W‹ ß—¼-íùN|S‘G£ß’13cÓ”!ÄÖ2Z 1VCÿL¸¤}= £8‡¡Á½Þ‘–'®HfÌ„ô3FgLeë/ꦼ4…f32ä°r«|àµàé/’‹Ð.áWæh•+‡¯Ô›ÙuꌎoÊ Ýn”héeÕ¯½½@¦ÔÍŠ•5K»y먖ª“`Eé Ê‘°ç!…åªâÄR3œçTPÍ qsPÑYÐO0mZez_FúÍ®Y·‡õ›þHÙ1¥½ëìiJû…EŒJ4¯mýLã  7äX“Ëo%ïê<vGãC¤äÞ+´ÞW¦),hp à’¸j ²’àî"ÍŸ²à-™/Dhî×rÔ âŠ÷Ú^hÓ,$5Û_œÞ©¿ÜHjWƒ.K;ew]Uk™©ÛjHÔ;ä2„¼ø×Ù>· Õ†³sWk‹6¥2çÚªnÇMédLްmi‰ Ùá8ÚöSãÅFà[k*ÈÖ‚ƒ³ú[ãt®mCe¢ žph X½ÝOHW’³5C¤‘é Tr½;+±¬w†’il•WNêJ¡RúÂê¶p‘u ;ê§e%ȼ¸]v¯à¹™âÝŽ¤àúþü­kôoRÊÝ`¤»ZÄ¥ ub/ûš5jV/9†?™Eú{;†b/CÀc.u&ጶµHÈ;¯ËwÍvuc`‡íÍ *ÇŒjµ[D…´r'~:Ë• ˆ±YÑÜäî´,!J=ÐÇK»´ DSA-15360-512ˆ¹ !Dxµ« € rcœåBÑc¡’©ÿ[ÍáX¬ûÊ„p>tUR»b-Îá™$¿áêb埛|‘Í žgMÛ&ïÒR¤O²÷ųh§pŠ_DóÂ=ö¢f+}ˆa« 1Nh,¡nòé3¼]·@Ôù}ÃUð8³³Çö‘lºYŒHJÍ |ý y ÙNJz=ŒÁ2«á¯bouncycastle-1.49.orig/test/data/openpgp/dsa/keys/DSA-7680-384.pub0000644000175000017500000000605110550421007023544 0ustar ebourgebourg™ ~Dw¦“ƒ@º×S~'”í,—~LÆ ÚHÃ:ÀXJCOP'“aæ/¿'(ä¦íçdž˜ÊY?f3Dlº™-¾Þë¹#ú¶»õ°òŸ »“ÙÌSØ–ÛOÊg3PMþ(5ÚɉöÑ:3æ›fÙSŒÉgJlnÕ€{GõÐR>æB”ü‚Õ¿ÀA¡óG#øšûø£—äfQã­T~M¼Ê¡»%ƒM`¾áwN_?^ –G¸»ã/è ïbC Ò‘75‚p™=ÑÇ’ #Ø€)Ã#Ã)›&Å ..ˆÞ°Ûñøœ™W³˜/²œ9÷v3ŠIz–±·a,´”f”–ŒMÇ—焎ҕqç4ïÂõÿjU,ýc ãþ4Øk¹{ðå,ñâ`>Ö.CÛ=Ê4l¢Fµ‰F°ów“ËžÝ$‚sÁ›µ3qe¯î´ #¬ rj¿”}™#WŒuø6fD[BB bt–"Iµï23}_òBCrÃÐï»(5»«:ûFNùþ•އ0ž«sا+ÅÏ:>@FÈoVÃL.™œAO*ý]@rr«ëE)¤ÓÖ°Æ ´/NEÜm:/t­—J³[ÑÚÝ8ñÕW¶\¯îõÈz2·ã’m5Ì‘ñÍyª<$‹DItw¦\ðö5]˜%IæÝªÏâ'ÞôbýÅ1 · B«‰³é°ÂVž „slL+\D—òñO!±Ú(óKÝöÉË üÍÉ2RjÈðbºaÇûïC*ºõcÞoº%’qVýÚª½nZKÔTÃÚœxɲ4wÿ±‹!1}QJRF½D{I«,õ@Kè±R°Ûd:˜’[øßbSéÖŽ…êᆀ?ÈÇVDø=ÁB`DçxkZµa¯Ò·eïŸmEÑX¡iS+(·>»@h¥RÍÑA …ÔMÅR«ƒ¥ÌrÍ}± Ãûú<¬w«­9T ÖeÊûÙ¹H2iøþ"L„ÓÞgÐ èmýÆd@«ökÙF,êFlš× "^9S(¨©ßäßM#Ì6 êþkƒÖ'ÚeƒØqÀYÇPtºÌÓ+«kDm6û7Z÷ViÜë”`ôRjΓfÊSF¯ž»š´G“FõtZDzRÙ‡5S¹#7TWqq|N×%85}ºÅšSqÑÎ×õ`þÉ29(˜ Â.?É«è² `JT[ƱÛG4êÄôÿê‘kWÿêy€•Ø^šgÏi„yjŒÇ 牊ΟÚw&PØ«-Ã~†q›®~V-ý6l‹ºØ·aN@õbþŒñ,`ÐË(íyû²ŒáÛſҺSå._~Ïßû®P¼Îsú<Þeb„_¿]Ïb4+SÔ6w„ËßùlòG·"ÓӮȱúPOP²Õ¦NÇõì4–¤,/gÚxU^³‚ݤ3R ¼« 1aè 2R¬o0W?Ñ,}cÙ™žc8+·Cê¦ÿ“ã¯.Þèb‚¨gQwi­¨Kö`íVäóS÷Ú0J»fFgr'j ý’ø¿Ëmkª1Ìu¼,Ëfg·©I ÷m³´1Òo2)ÔLÂ&$=/ í¼**øÁKZ@8öø§ð¼èÁÏë³—Ì<¢qú—ûÿu®ä;ËÈ-†m‚Évïz Ã÷­–̺3°6ZÞDZMVƒHÿÞ¦qêöA™: [øA,æV]{C›éöo²0 ÚœX©ºƒ-$•¶ÈÆÐ)t+¥¸ðȇÄÝðîëjZz ;I±Å©çÉЦ³xHf‚ïWµ½ß]ï¹ ~•™r²œ#Ã@NP¨ »Ž,1ä­ȹ7‡Ä H';ŽâG¸üPàQ´§˜†#_ëúØ®rie¾Q¢XM¿U@ßL"¾¶µ,#DŽß. f§(…—LÏë‰T‚&”òí!ß”ÈÂÕåÝW°Ñ§™š´µŒzÀã•þoDÅÕs<åòj7GBæϙv¸T¹h4FƒOcâ¼§Ëû<_l‘…Ôík,?òÄ>ËÆ¯Å‡ Ûq/™ÎÑ588±3ûŽ‚àÔ>¹±º¬Æ}„\>­‚õ ‡]Â&Tž]Åkò\Œ…ÔóÇʇͼqËP†oÙGì¥?`¡ÆI‡![Eöa­IéTû/’ë¶©Ë*IpÎW±ò$RŒ©± ‰{šl!K/ÞîÜμ-†uBßT*¸côÉ1;;.ÅîGÚîm°¼K_3"0Õoy )G>yxÀ[´ DSA-7680-384ˆ˜ Dw¦ € …÷¥Üô[`:M}åqÔJRá Àzh¹½¾€Å,.0ô¯ÚKù=¹C„ÚªaÀ¤ihÛß'zäÛ7͇£¶åç°kˆÕêd“šg?*ôÒ•hÒ KP¤Ö÷kÕÄ @—d=ÌFçÕˆ]"¹™îØàÐ4W~Q®Ù|vB eÞ_ºazY Cjµa³Ct’ÕÞ½‹`i0Eǵ…¢€Ù˜ ’¶ ÆQý‚C ÚÙ¸·´ÍjŸ¥+,¤ìæ-*ã”Ñ/P«$…†yŒ98²;ZdŠ×àýNˆÆ§©˜ Ü®yvËÿ³ß/†¯þÞ±Åðkõ¡| <€°û¼éðh0¿Í¡ô4É?ÐxU«öäbIg´¬òŒ¤ƒs“dzÝ•#³Y¬ˆòç»9„ÜP•ƒÈ˜VBÍGð”Ò½®à⼊á™já;!š^rNW$“ÌF Ô›¹§5B‚ÑôÖšXHæÿ6ÊàžiäÁYû™X1ž ¡“ˆ& zòàŽâ¦—8sx#²/ÑüôphûjÁâ`â¢OU­l^x­àù¨J| 0a£³æ\³TëøÀÈŠÉpͼpì2Èú ¤k7a m ·±å¥m6åTewëf¯„—bÎ:C2.ó¾Zgm\|Å;§ö÷[¥ýˆ5.w¼ŒÚœè¦à¿pOBTX$n°Ë±=[ÞuÙ€s°- ²..ú²yOµ¹¼¨_÷ÚóØ:6à}« æ«tôž×ëü>M&2–û¥‘€õrÖÅ,C`ç  7k£øóp8«‹0%iêjæ ¶aØøˆb¸zFc5ÇÔJ"ïáß§yßž~‰øÂµ·%:¿—–“ 's¾®í|‹GlÒ >É}h5»­ D4 Ž]+4R~wÅX.509=0‚90‚¢ Joƒ0  *†H†÷ 0a1 0 UTest1 0 UTest1 0 UTest1 0 U Test1 0 U Test10U Test Client0 090729033115Z 100729033115Z0a1 0 UTest1 0 UTest1 0 UTest1 0 U Test1 0 U Test10U Test Client0Ÿ0  *†H†÷ 0‰©¦/0ø oõâ3©ÿÕÒüÓÂ;%:´so«_ƵÕSlú ·LVCü#t¸§ZùШ÷–ÿb3ïƒͦL”‚h0çïŽToL;Ãtp¸[†)V •؃z-…ý°]õènÙÉßrçË)4"µïìÍ?\aX%ƒü w_0  *†H†÷ b¬Õ™Õ¦4ÑÛ`n2ÙÜ&6-há î 3Ù)Ä7«»W'råþ¨#jbèE³ÚQ Ê&Mžˆs ñþoQu?<œŽLÚƇÄmÎúb ‚jl`>Jç4 "âíËZ+Mf¦…Ð’ù\¥˜-‰ýé ;¤ì³™Œ`?íserver"Ä‘@+X.509=0‚90‚¢ JoÂi0  *†H†÷ 0a1 0 UTest1 0 UTest1 0 UTest1 0 U Test1 0 U Test10U Test Server0 090729033049Z 100729033049Z0a1 0 UTest1 0 UTest1 0 UTest1 0 U Test1 0 U Test10U Test Server0Ÿ0  *†H†÷ 0‰£ÌR-ûKûñ#¿fø?º:F]M‚Ç/["C ©Üžâ•‚fô·ZþRYâÖm°œÀy³ÜÕ-Žãô-°ÙÆvÏÒ½D2i[qƒêgFGMXNBQ/ë6õ×Çù;éö?²+áŽ~Ï åÃõïK­¼_£ Û“ÓçXÙ0  *†H†÷ ò—ì¶ ¬n©}7­×>,8ú;6·Ë™³ˆ§¾¬&aç%Je«qbE?{²Ù]† чh¤ð#MÛø{±U—vâuÇŠ¹óÁb4¾ ʾ_e¸ì"ìK¬ä²y(ƺtHX˜ ¦úœD[)¹×—ƒ¹ÞËÚÚm‡~1„âçüú\™†é7÷(Œ)qºw¤áѺu:|'J®u^bouncycastle-1.49.orig/test/data/tls/keystores/client_store.dsa0000644000175000017500000000376311243512073024345 0ustar ebourgebourgþíþíclient"ľ0‚‹0 +*‚wQãB& õCÐ;@êhä„­\ ôßûÇþ:èþ!°·!5ÁãeÀe–b¶ÖÞ=†ÄBY CjJç4 "âíËZ+Mf¦…Ð’ù\¥˜-‰ýé ;¤ì³™Œ`?íserver"ÄnO»0‚·0 +*‚£å#—jû@ð¹C'ßÓåo5ã{,SwÚ l…Àl­Æ¿‹á]†*{æë®–×è$Þp¼õ¨¡Æý2Jÿ‚a918'fÖ- ­Çè†cø:ÄQk±Ý˾±(¦nfqcÔ Ÿ+u ôôðp·?$¬5° ®´€º·ÈTîq›JôÂÞªÍ0ÃŽdoU«t2œMøé\F.Þ1ÅòOÜ»F¯ Áä[5þë Âqз7ˆBŽØÌ¥(d.òœäoØ‘XI€²ÜÐC—梦f…™u²|‡…*CP²qÔ!µ!°¹ŽU¸Düü”Ì`UæŒQ/!Ù¢UÅ‹²?ß;*©¦Pè]àëD?@I_úþW:îÚÒ’‚goE?2|§{!Äj‰ÑvåýùuSËâŠç+ùlÊ”¢Ÿ¾z‡—õAú’goÓFœ]ÖÍ{‘©ù¬˜ªÃB.m 0 ‚¦àYÖ|1ù6­Ò?‘E_†|~RÛŸ¹[>E1+)Æ FŠÎë=×ï œEcxÕxG­Î Ãf tkC ÂB¯Š‚Ê"uÛí…#XùBüi4tj(㘞("§¾Š¸XȪóÊÕ„èfðíF¬âªX¯R@DN­it…÷<]âü †‘Ø8-UTjJ—¸ãC©éÃÁ„¬Hœƒå:Çhê{W‚Ç„ 5ÁôfíéÝ Û*7ÃÙÙü_Þ6û0è<}æ8F˜Ò ÓÝ<=j ÍÀb×ñ_{§g”zx{^c¶bx3Ná ¢¨ÐØrçpPãýZImžlX’Ù€O QE) vîñ;³TÒ[„ÇFvÐÀ`í8w3s¨ú·ákÏæd)uýÇ-ÙJF#}Õµ€™~ãW!sJ­'š®d¾@!€öõ=ÜÁPX.509=0‚90‚¢ JoÂi0  *†H†÷ 0a1 0 UTest1 0 UTest1 0 UTest1 0 U Test1 0 U Test10U Test Server0 090729033049Z 100729033049Z0a1 0 UTest1 0 UTest1 0 UTest1 0 U Test1 0 U Test10U Test Server0Ÿ0  *†H†÷ 0‰£ÌR-ûKûñ#¿fø?º:F]M‚Ç/["C ©Üžâ•‚fô·ZþRYâÖm°œÀy³ÜÕ-Žãô-°ÙÆvÏÒ½D2i[qƒêgFGMXNBQ/ë6õ×Çù;éö?²+áŽ~Ï åÃõïK­¼_£ Û“ÓçXÙ0  *†H†÷ ò—ì¶ ¬n©}7­×>,8ú;6·Ë™³ˆ§¾¬&aç%Je«qbE?{²Ù]† чh¤ð#MÛø{±U—vâuÇŠ¹óÁb4¾ ʾ_e¸ì"ìK¬ä²y(ƺtHX˜ ¦úœD[)¹×—ƒ¹ÞËÚÚm‡~1„âçüú\™†é&lqü>sÈ3éƒÌ7 4ã¤ÕX†bouncycastle-1.49.orig/test/data/scrypt/0000755000175000017500000000000012152033550017641 5ustar ebourgebourgbouncycastle-1.49.orig/test/data/scrypt/TestVectors.txt0000644000175000017500000000171111633667135022706 0ustar ebourgebourgscrypt(“”, “”, 16, 1, 1, 64) = 77 d6 57 62 38 65 7b 20 3b 19 ca 42 c1 8a 04 97 f1 6b 48 44 e3 07 4a e8 df df fa 3f ed e2 14 42 fc d0 06 9d ed 09 48 f8 32 6a 75 3a 0f c8 1f 17 e8 d3 e0 fb 2e 0d 36 28 cf 35 e2 0c 38 d1 89 06 scrypt(“password”, “NaCl”, 1024, 8, 16, 64) = fd ba be 1c 9d 34 72 00 78 56 e7 19 0d 01 e9 fe 7c 6a d7 cb c8 23 78 30 e7 73 76 63 4b 37 31 62 2e af 30 d9 2e 22 a3 88 6f f1 09 27 9d 98 30 da c7 27 af b9 4a 83 ee 6d 83 60 cb df a2 cc 06 40 scrypt(“pleaseletmein”, “SodiumChloride”, 16384, 8, 1, 64) = 70 23 bd cb 3a fd 73 48 46 1c 06 cd 81 fd 38 eb fd a8 fb ba 90 4f 8e 3e a9 b5 43 f6 54 5d a1 f2 d5 43 29 55 61 3f 0f cf 62 d4 97 05 24 2a 9a f9 e6 1e 85 dc 0d 65 1e 40 df cf 01 7b 45 57 58 87 scrypt(“pleaseletmein”, “SodiumChloride”, 1048576, 8, 1, 64) = 21 01 cb 9b 6a 51 1a ae ad db be 09 cf 70 f8 81 ec 56 8d 57 4a 2f fd 4d ab e5 ee 98 20 ad aa 47 8e 56 fd 8f 4b a5 d0 9f fa 1c 6d 92 7c 40 f4 c3 37 30 40 49 e8 a9 52 fb cb f4 5c 6f a7 7a 41 a4 bouncycastle-1.49.orig/test/data/cmp/0000755000175000017500000000000012152033550017074 5ustar ebourgebourgbouncycastle-1.49.orig/test/data/cmp/sample_cr.der0000644000175000017500000000075110757312750021553 0ustar ebourgebourg0‚å0ܤ01 0 U ARP1 0 UCH¤90710U AdminCA110U EJBCA Sample1 0 USE¡F0D *†H†ö}B 07saltNoMatterWhatThisStringIs0+0 +¢SenderKID-2008¤ 1203607015944¥ãßPÌÄTv°c𧥂À¢ê0ç0ä0Ý0Á¥01 0 U ARP1 0 UCH¦Ÿ0  *†H†÷ 0‰«®þãj%3f ©&Â5Ý}Õ»w¤ü‹ÜINp²nbp¡dÇ ù޳¿Û!ß:”Œj)º›‡9°IÞÛ,¦Ý¥)©O î½¢)÷ ïû­w“;ꌹe±ÙV“êF•O¸^PO亦ïÄ#ýû_Ûpk4±00 + DUMMY  î÷CÅÿù˜çá;×€¯æŠk·Ibouncycastle-1.49.orig/test/data/org/0000755000175000017500000000000012152033550017104 5ustar ebourgebourgbouncycastle-1.49.orig/test/data/org/bouncycastle/0000755000175000017500000000000012152033550021577 5ustar ebourgebourgbouncycastle-1.49.orig/test/data/org/bouncycastle/asn1/0000755000175000017500000000000012152033550022441 5ustar ebourgebourgbouncycastle-1.49.orig/test/data/org/bouncycastle/asn1/test/0000755000175000017500000000000012152033550023420 5ustar ebourgebourgbouncycastle-1.49.orig/test/data/org/bouncycastle/asn1/test/masterlist-content.data0000644000175000017500000000332411426456505030130 0ustar ebourgebourg0‚Ð1‚É0‚?0‚¨ 0  *†H†÷ 0;1 0 UQQ10 UState1 0 U Org10 UCSCA30 100629210008Z 130628210008Z0;1 0 UQQ10 UState1 0 U Org10 UCSCA30Ÿ0  *†H†÷ 0‰ÞÙˆ5å9Ëç"/…üÃòV·Ìo0½¿(]Û-_–0oà?µtPº]ü0%VmßKä²VÒŽ4±ñNvî©<\›Óõă– üÎËÎÊ {‚Ë×;Þ›&°éñ£âMÖÓWi¬§ó­o'†âc ¥sΤ=‹,ß²Á…¿ˆÃÃÇšœ~î‡@A£S0Q0Uÿ0ÿ0U‹fÆ9¥äúÆŒ05©K¯ÒR²(ˆ0U#0€‹fÆ9¥äúÆŒ05©K¯ÒR²(ˆ0  *†H†÷ ٖʱ¬ÊÇÔ”¿JCmû<ºCOùPºöÎN”)¢0Ç¢Ðýz±’0’-ŠVeŠ^-?±èÖ©OJË@†µ%ypá£Ù¨¯ V9DÇ2%©êjlª­ÇŸ| $»E¹}-™øˆ-HõïÒ†¬^^ %ÈJ bš¶xÂqH¨!0‚?0‚¨ 0  *†H†÷ 0;1 0 UUT10 UState1 0 U Org10 UCSCA10 100629205916Z 130628205916Z0;1 0 UUT10 UState1 0 U Org10 UCSCA10Ÿ0  *†H†÷ 0‰Þ;VU;þÀ³=™:op2Ž}•’Pz)çP ÈRˆ±ö¹O9"›ˆÀ@‚þ¼R…ó¯4s[!Þ0’žlL¢ôÃ(ËP Gç‘=¬;]£qÂu·f•Ì—6òlAÆ6þEx7Ó´w¬g&\‡}/²›´öîŸ÷Pv¦g)£S0Q0Uÿ0ÿ0Unô2µBŒ¨¹XhëTf/u¾s 0U#0€nô2µBŒ¨¹XhëTf/u¾s 0  *†H†÷ Ž Ò †àÈî¼þé"P–2{vÊàn`fÐ&*| õm4ŸAhø‡`TŠ(E\ѽ¾`VùÆâ‘¿Fåú‡½Ì¿’A7G°Ëìó)J,ÜXÃg¤Súl!²ºæì ú¬±-2ìÇ8È„8î•Ä9<1WL`;0‚?0‚¨ 0  *†H†÷ 0;1 0 UXX10 UState1 0 U Org10 UCSCA20 100629205942Z 130628205942Z0;1 0 UXX10 UState1 0 U Org10 UCSCA20Ÿ0  *†H†÷ 0‰ÂTuû›b°á¿L©ßF5j準÷¸"O{8Ènh7hÁ´Â¿KKâ×e‰Å¼”a¶Å}S6¾¯´@Œý¡Àrº*I®Þ ÔpÈ.Dwó²ÏøùgøcÌí=™èËñÃŽÞ-órÉÖ,rÃý2'ýgFn”Ž=Ø@Lá¸Û£S0Q0Uÿ0ÿ0U?Är<ûÀ‘‡AÊ–M'¨Ü0U#0€?Är<ûÀ‘‡AÊ–M'¨Ü0  *†H†÷ ’Q¨æà9ŒúÞÿ AÐï$c۽­ʱÃX/TñÍž/2䨸KÇgamKµ¶-?hþÈœiš–nÍJÖ³#KA™ñ>Å=(HÓg†¶N ¹ k¾|voCvápÌW*'þ¸øAB3ªí{K.Kúºˆ×bouncycastle-1.49.orig/test/data/org/bouncycastle/mail/0000755000175000017500000000000012152033550022521 5ustar ebourgebourgbouncycastle-1.49.orig/test/data/org/bouncycastle/mail/smime/0000755000175000017500000000000012152033550023633 5ustar ebourgebourgbouncycastle-1.49.orig/test/data/org/bouncycastle/mail/smime/test/0000755000175000017500000000000012152033550024612 5ustar ebourgebourgbouncycastle-1.49.orig/test/data/org/bouncycastle/mail/smime/test/validator.revoked.crl0000644000175000017500000000042410503212005030727 0ustar ebourgebourg0‚0{0  *†H†÷ 041 0 UCH1%0#USignedMailValidatorTest Root 060901100000Z0"0  060901093000Z0 0 U 0  *†H†÷ ‡6ÄY^IÆíëê’nþ@ý©'ÔNäaÙÁcº~—l^SaÉ0Þo*_&c,Ù^ü.S“TÏ:Tù-Eމç ¬.EÌj™|ðkÐrL±kÚ¸;žWˆ£4’—úoH±ËÁ=‹è¾Â2ÿ<ï׆o›Rž.¾Û!gb¿AðHX¢bouncycastle-1.49.orig/test/data/org/bouncycastle/mail/smime/test/cert.pem0000644000175000017500000000773512051700117026264 0ustar ebourgebourgCertificate: Data: Version: 3 (0x2) Serial Number: 9 (0x9) Signature Algorithm: sha1WithRSAEncryption Issuer: C=AT, ST=Austria, L=Vienna, O=Tiani Spirit GmbH, OU=Demo Environment, CN=Test CA/emailAddress=massimiliano.masi@tiani-spirit.com Validity Not Before: Oct 30 14:57:38 2012 GMT Not After : Apr 5 14:57:38 2192 GMT Subject: C=AT, ST=Austria, O=Tiani Spirit GmbH, OU=Test Environment, CN=massi@direct.tiani-spirit.net/emailAddress=massi@direct.tiani-spirit.net Subject Public Key Info: Public Key Algorithm: rsaEncryption RSA Public Key: (1024 bit) Modulus (1024 bit): 00:c0:be:a0:14:7e:2a:5a:32:7d:b2:6c:4d:01:d2: ae:92:4a:1b:26:00:9a:78:99:bd:e6:17:38:75:a2: ab:25:63:0c:19:e6:87:75:cb:16:99:84:97:30:c8: ca:fe:35:ec:3f:68:c5:7a:2b:22:34:ed:7b:79:c0: ed:7d:66:94:ba:6e:c7:d4:f1:0c:53:76:63:cf:ec: 9a:f5:bd:4d:97:19:4d:88:ab:c9:1d:6d:84:95:75: ed:7f:f4:43:57:19:7c:b3:c5:2e:4e:79:38:e7:9e: d4:24:ed:eb:b8:89:d4:0e:13:8c:04:c4:2d:f0:e2: ee:1f:92:be:30:44:11:6d:d1 Exponent: 65537 (0x10001) X509v3 extensions: X509v3 Basic Constraints: CA:FALSE Netscape Comment: OpenSSL Generated Certificate X509v3 Subject Key Identifier: 67:2B:7D:3B:53:94:55:6F:A8:54:C9:E9:45:E0:F8:39:BA:DB:E7:76 X509v3 Authority Key Identifier: keyid:64:C2:28:6E:51:39:46:A4:D0:F1:AE:76:45:6D:6F:38:15:78:FB:DA Signature Algorithm: sha1WithRSAEncryption 5b:05:41:59:db:b6:7b:a8:ce:73:7f:ce:23:d5:79:5e:90:a1: 65:ba:b9:69:c5:92:80:dd:4d:58:0f:68:91:57:e0:6e:71:3e: 0e:c8:67:45:9d:4b:8d:bc:14:de:c4:41:76:7d:2a:c3:42:f7: 3d:a0:a7:4f:32:26:d1:bb:05:84:6f:d3:f1:89:bd:1d:6e:ff: d2:37:4a:e4:f3:8f:14:02:5d:71:59:cd:e0:0c:f8:20:29:45: f2:d4:5e:0c:a5:71:d6:64:ea:97:1e:b6:55:ba:01:3a:1d:33: 84:aa:5c:3c:c0:57:5f:6e:23:86:15:7d:92:41:5b:88:8e:a1: cb:f1:03:eb:00:be:9e:f8:4d:df:7c:91:d9:a8:65:6d:d1:92: f6:03:b9:22:f0:9a:5b:d9:cb:32:4f:d9:39:d9:2b:54:c9:46: ae:ce:a3:98:62:82:82:23:c4:c2:ac:3d:85:b1:ed:33:52:92: 02:7b:4b:75:67:2c:6f:d0:39:cc:b1:25:8b:2f:72:f2:0e:35: 13:49:48:20:26:fc:98:8b:40:7e:19:4c:6b:37:39:45:d8:e5: 56:55:ff:d1:58:3b:b0:f0:53:96:71:d7:6e:29:f8:29:33:e9: 86:ee:34:29:b9:1a:30:6d:b9:ac:32:cf:a2:de:48:27:8b:6b: 8b:e9:9c:a4 -----BEGIN CERTIFICATE----- MIIDzjCCAragAwIBAgIBCTANBgkqhkiG9w0BAQUFADCBrDELMAkGA1UEBhMCQVQx EDAOBgNVBAgTB0F1c3RyaWExDzANBgNVBAcTBlZpZW5uYTEaMBgGA1UEChMRVGlh bmkgU3Bpcml0IEdtYkgxGTAXBgNVBAsTEERlbW8gRW52aXJvbm1lbnQxEDAOBgNV BAMTB1Rlc3QgQ0ExMTAvBgkqhkiG9w0BCQEWIm1hc3NpbWlsaWFuby5tYXNpQHRp YW5pLXNwaXJpdC5jb20wIBcNMTIxMDMwMTQ1NzM4WhgPMjE5MjA0MDUxNDU3Mzha MIGsMQswCQYDVQQGEwJBVDEQMA4GA1UECBMHQXVzdHJpYTEaMBgGA1UEChMRVGlh bmkgU3Bpcml0IEdtYkgxGTAXBgNVBAsTEFRlc3QgRW52aXJvbm1lbnQxJjAkBgNV BAMUHW1hc3NpQGRpcmVjdC50aWFuaS1zcGlyaXQubmV0MSwwKgYJKoZIhvcNAQkB Fh1tYXNzaUBkaXJlY3QudGlhbmktc3Bpcml0Lm5ldDCBnzANBgkqhkiG9w0BAQEF AAOBjQAwgYkCgYEAwL6gFH4qWjJ9smxNAdKukkobJgCaeJm95hc4daKrJWMMGeaH dcsWmYSXMMjK/jXsP2jFeisiNO17ecDtfWaUum7H1PEMU3Zjz+ya9b1NlxlNiKvJ HW2ElXXtf/RDVxl8s8UuTnk4557UJO3ruInUDhOMBMQt8OLuH5K+MEQRbdECAwEA AaN7MHkwCQYDVR0TBAIwADAsBglghkgBhvhCAQ0EHxYdT3BlblNTTCBHZW5lcmF0 ZWQgQ2VydGlmaWNhdGUwHQYDVR0OBBYEFGcrfTtTlFVvqFTJ6UXg+Dm62+d2MB8G A1UdIwQYMBaAFGTCKG5ROUak0PGudkVtbzgVePvaMA0GCSqGSIb3DQEBBQUAA4IB AQBbBUFZ27Z7qM5zf84j1XlekKFlurlpxZKA3U1YD2iRV+BucT4OyGdFnUuNvBTe xEF2fSrDQvc9oKdPMibRuwWEb9Pxib0dbv/SN0rk848UAl1xWc3gDPggKUXy1F4M pXHWZOqXHrZVugE6HTOEqlw8wFdfbiOGFX2SQVuIjqHL8QPrAL6e+E3ffJHZqGVt 0ZL2A7ki8Jpb2csyT9k52StUyUauzqOYYoKCI8TCrD2Fse0zUpICe0t1Zyxv0DnM sSWLL3LyDjUTSUggJvyYi0B+GUxrNzlF2OVWVf/RWDuw8FOWcdduKfgpM+mG7jQp uRowbbmsMs+i3kgni2uL6Zyk -----END CERTIFICATE----- bouncycastle-1.49.orig/test/data/org/bouncycastle/mail/smime/test/rawAS2.message0000644000175000017500000000601211651126746027273 0ustar ebourgebourgPOST / HTTP/1.1 Host: 216.18.74.3:21050 Cache-Control: no-cache User-Agent: bTrade, Inc. TDServer AS2 Service From: parcuri@btrade.com Reply-To: parcuri@btrade.com To: http://216.18.74.3:21050/ AS2-From: b*Trade AS2-To: 0010-450014-900 AS2-Version: 1.1 Date: Mon, 17 Feb 2003 21:01:00 GMT Subject: Test B Message-Id: <20030217210100_E02431B950@bTrade> Disposition-Notification-To: parcuri@btrade.com Disposition-Notification-Options: signed-receipt-protocol=optional, pkcs7-signature; signed-receipt-micalg=optional, sha1 Content-Type: multipart/signed; protocol="application/pkcs7-signature"; micAlg=sha1; boundary="=_0171E6C0-24241856-0171E6C0-24241856" Content-Length: 2386 --=_0171E6C0-24241856-0171E6C0-24241856 Content-Type: multipart/report; Report-Type=disposition-notification; BOUNDARY="=_0172E300-24306432-0172E300-24306432" --=_0172E300-24306432-0172E300-24306432 Your message was successfully received and forwarded to the appropriate system process. --=_0172E300-24306432-0172E300-24306432 Content-Type: message/disposition-notification Original-Recipient: rfc822;service@alpha.globalec.com Final-Recipient: rfc822;service@alpha.globalec.com Original-Message-ID: Received-Content-MIC: QlQ+zTPhpp34x/iVnffcT0IEZAw=,sha1 Disposition: Automatic-action/mdn-sent-automatically;processed --=_0172E300-24306432-0172E300-24306432-- --=_0171E6C0-24241856-0171E6C0-24241856 Content-Type: application/pkcs7-signature; name=EDIINTSIG.p7s 0‚è *†H†÷  ‚Ù0‚Õ1 0 +0  *†H†÷  ‚?0‚;0‚¤ sBgå̉íFâ T\~.0  *†H†÷ 0µ10USIBSERVICE8620AS210U Sterling Commerce1%0#U Commercial Delivery Services1'0% *†H†÷  opensystems@stercomm.com10 UDublin1 0 UOhio1 0 UUS0 070309142951Z 170309073333Z0µ10USIBSERVICE8620AS210U Sterling Commerce1%0#U Commercial Delivery Services1'0% *†H†÷  opensystems@stercomm.com10 UDublin1 0 UOhio1 0 UUS0Ÿ0  *†H†÷ 0‰¸$’=À€®Ö6‰Þv¼—¨B% ÅӫСL®\_ÃWÝZÅ´*Lº“9MHöÓ:NÇ»èƒ:û|qÝ!¥Þ¼ß,³=p1Í%øUTשQËù6ÑŒ¥ûÐà@7&M;Ô–Ô-<ѹ¶€ä>ÚêF?¶ÕômFEÏÅÂJWi Ø £‚H0‚D0 U 0€0UÄó%šwX,,‘’6²ñ½bÁ‡0îUæ0ã€Äó%šwX,,‘’6²ñ½bÁ‡¡¸0µ10USIBSERVICE8620AS210U Sterling Commerce1%0#U Commercial Delivery Services1'0% *†H†÷  opensystems@stercomm.com10 UDublin1 0 UOhio1 0 UUS‚sBgå̉íFâ T\~.0U% 0 +0Uÿð0  *†H†÷ ±×Oý뤶ã(…vÜ-öû‹t7G ø–n¡TqÖÒ´Òi“‹k,°óW%Î)'„fR4 º?ØÆJ+£'*•ØçañV¤rÊaôˆ± fk.°BÏ®Êä-@!±U6ˆÄ@Uîo·:³›]÷w’æ ½ÜÎòXAË1‚q0‚m0Ê0µ10USIBSERVICE8620AS210U Sterling Commerce1%0#U Commercial Delivery Services1'0% *†H†÷  opensystems@stercomm.com10 UDublin1 0 UOhio1 0 UUSsBgå̉íFâ T\~.0 +0  *†H†÷ €FÉï9ÇÔ§ÓêVy¾ý3™¢´Åˈ{LCøúŸ{7ÊÌiªFOÛL íØWµY‰L–©ˆT!Êëõó"‚î´fâÉ"ø3éSÙȃTj¥“O2§‡F)’uƒ‹sÙ²~oö¨ÌÑ‚DÄ:ýr³JW*ðqý£)É.&¡Â뮩 --=_0171E6C0-24241856-0171E6C0-24241856-- bouncycastle-1.49.orig/test/data/org/bouncycastle/mail/smime/test/certpath_end1.crt0000644000175000017500000000207610621263376030064 0ustar ebourgebourg-----BEGIN CERTIFICATE----- MIIC9TCCAl6gAwIBAgIBBjANBgkqhkiG9w0BAQUFADBeMRwwGgYDVQQDExNDcmVh dGVDZXJ0UGF0aEludGVyMQswCQYDVQQGEwJDSDEPMA0GA1UEBxMGWnVyaWNoMSAw HgYDVQQKExdTaWduZWRNYWlsVmFsaWRhdG9yVGVzdDAeFw0wNzA1MDkxMjI1MDJa Fw0yNzA1MDQxMjE2MTdaMFsxGTAXBgNVBAMTEENlcnRQYXRoVGVzdEVuZDExCzAJ BgNVBAYTAkNIMQ8wDQYDVQQHEwZadXJpY2gxIDAeBgNVBAoTF1NpZ25lZE1haWxW YWxpZGF0b3JUZXN0MIGfMA0GCSqGSIb3DQEBAQUAA4GNADCBiQKBgQDVSKmlYHT7 B4hiai8RLLiJqunR20xwud9dg4DzY9EIq0iq7+UoY7dFfxEC33yrn7CXZmbIf7oG VpdB7qbX2je0Ic1dFTWA+MCilZRG9/iI368LCmh2jk+oI0LvWRmAdu9wmYt7QQbd hXfaXgz+6hoMesEIdlHC8Eo5HMQy+6oPrQIDAQABo4HFMIHCMAwGA1UdEwEB/wQC MAAwHQYDVR0OBBYEFEHktAYE3g2aYdpVV6rM+xFZ4/ytMIGFBgNVHSMEfjB8gBT+ nhkY6yRaAlPnpWbb5oEUftM14KFhpF8wXTEbMBkGA1UEAxMSQ3JlYXRlQ2VydFBh dGhSb290MQswCQYDVQQGEwJDSDEPMA0GA1UEBxMGWnVyaWNoMSAwHgYDVQQKExdT aWduZWRNYWlsVmFsaWRhdG9yVGVzdIIBBDALBgNVHQ8EBAMCBLAwDQYJKoZIhvcN AQEFBQADgYEAoZgkLYp4RUW4tLqEbaP1QS9oETGMwBU/wZUzgl1Z2TsNJGe6BqNe VaflMyEb01j+wQ429+v05+wuc1wB5WcDFfGO8mi/g8ak4ha0m9V36QPJB5fhcPTu rwYPhu22Fy0CKDlAnuyEiGtzL79XSyYRkFr0Yqm/EXP+N/Fl+gQNgds= -----END CERTIFICATE----- bouncycastle-1.49.orig/test/data/org/bouncycastle/mail/smime/test/brokenEnv.message0000644000175000017500000000451211711651431030117 0ustar ebourgebourgContent-Type: application/pkcs7-signature; name=smime.p7s; smime-type=signed-data Content-Transfer-Encoding: base64 Content-Disposition: attachment; filename="smime.p7s" Content-Description: S/MIME Cryptographic Signature MIAGCSqGSIb3DQEHAqCAMIACAQExCzAJBgUrDgMCGgUAMIAGCSqGSIb3DQEHAQAAoIAwggP3MIID YKADAgECAgEHMA0GCSqGSIb3DQEBBAUAMIGoMQswCQYDVQQGEwJHQjEWMBQGA1UECBMNR3Vlcm5z ZXkgQy5JLjEWMBQGA1UEBxMNU3QgUGV0ZXIgUG9ydDEsMCoGA1UEChMjQ2hhbm5lbCBJc2xhbmRz IFN0b2NrIEV4Y2hhbmdlLCBMQkcxFjAUBgNVBAsTDUlUIERlcGFydG1lbnQxIzAhBgNVBAMTGkNJ U1ggQ2VydGlmaWNhdGUgQXV0aG9yaXR5MB4XDTExMDQyODEyNDUzMloXDTIxMDQyNTEyNDUzMlow gaExCzAJBgNVBAYTAkdCMRYwFAYDVQQIEw1HdWVybnNleSBDLkkuMSwwKgYDVQQKEyNDaGFubmVs IElzbGFuZHMgU3RvY2sgRXhjaGFuZ2UsIExCRzEWMBQGA1UECxMNSVQgRGVwYXJ0bWVudDERMA8G A1UEAxMIY2lzeC5jb20xITAfBgkqhkiG9w0BCQEWEmNpc3hhZG1pbkBjaXN4LmNvbTCBnzANBgkq hkiG9w0BAQEFAAOBjQAwgYkCgYEA4uONPbLSMV7EAisV+Gjcwt/M2pIycT5YJNSvJM9OKoBq2zY3 uXKLHVAo66azMSj+SkEctcT6oIKoGa5UxJxfRU+Ofi6ncn/aLL9ktOsqGPdJHmasXQuqor/WA6vg UNUjphpCnwdeTteEIHbeITdZIpxJHF2cRKrD8RxppvqYDqcCAwEAAaOCATQwggEwMAkGA1UdEwQC MAAwLAYJYIZIAYb4QgENBB8WHU9wZW5TU0wgR2VuZXJhdGVkIENlcnRpZmljYXRlMB0GA1UdDgQW BBRuc4NA/ZPwo7PhqJL3obdMXoacNjCB1QYDVR0jBIHNMIHKgBQiC3CXV10nqe2CmJZc9k9i+Kx9 DaGBrqSBqzCBqDELMAkGA1UEBhMCR0IxFjAUBgNVBAgTDUd1ZXJuc2V5IEMuSS4xFjAUBgNVBAcT DVN0IFBldGVyIFBvcnQxLDAqBgNVBAoTI0NoYW5uZWwgSXNsYW5kcyBTdG9jayBFeGNoYW5nZSwg TEJHMRYwFAYDVQQLEw1JVCBEZXBhcnRtZW50MSMwIQYDVQQDExpDSVNYIENlcnRpZmljYXRlIEF1 dGhvcml0eYIBADANBgkqhkiG9w0BAQQFAAOBgQDbA6qbz79aqrFl9jmVXFSutxUYuwweX61zRNLp vXWmXaGbUUcxSbQXoDJKrSr3vaDLNeqqLB/KjtpS8mestF4iQ7oT2bUjKSLeyrVDml/2sKS4oC8F lxYSnps6dAlph91DrayJ8c+oi7yD5uR5RUrwJaqwZVaAcCaC1whjoWt2tQAAMYIB6zCCAecCAQEw ga4wgagxCzAJBgNVBAYTAkdCMRYwFAYDVQQIEw1HdWVybnNleSBDLkkuMRYwFAYDVQQHEw1TdCBQ ZXRlciBQb3J0MSwwKgYDVQQKEyNDaGFubmVsIElzbGFuZHMgU3RvY2sgRXhjaGFuZ2UsIExCRzEW MBQGA1UECxMNSVQgRGVwYXJ0bWVudDEjMCEGA1UEAxMaQ0lTWCBDZXJ0aWZpY2F0ZSBBdXRob3Jp dHkCAQcwCQYFKw4DAhoFAKCBkzAYBgkqhkiG9w0BCQMxCwYJKoZIhvcNAQcBMBwGCSqGSIb3DQEJ BTEPFw0xMTA1MDYxMzI0MjNaMCMGCSqGSIb3DQEJBDEWBBSbT4isXzF6feE9PkJwETxWzE1MrTA0 BgkqhkiG9w0BCQ8xJzAlMAoGCCqGSIb3DQMHMA4GCCqGSIb3DQMCAgIAgDAHBgUrDgMCBzANBgkq hkiG9w0BAQEFAASBgKOxZ1YVjPcCD4QEVRxjym9+8NBJrf1ZuIU1XfBmTewQDT5ZdGlfISkg5AJq hlkYi7yTj9nbj1lZBluaVZjOfbguiWaOXcZRxC1MxrzlCaKOEqq/6ZiZwEV1TCrbM8ooTGrItnrR grXnenuy14P+N/QBlfYUyJIEv5eP+xAeBYnuAAAAAAAAbouncycastle-1.49.orig/test/data/org/bouncycastle/mail/smime/test/test192.message0000644000175000017500000000260012051700030027361 0ustar ebourgebourgContent-Type: application/pkcs7-mime; name="smime.p7m"; smime-type=enveloped-data Content-Transfer-Encoding: base64 Content-Disposition: attachment; filename="smime.p7m" Content-Description: S/MIME Encrypted Message MIAGCSqGSIb3DQEHA6CAMIACAQAxggFOMIIBSgIBADCBsjCBrDELMAkGA1UEBhMCQVQxEDAOBgNV BAgTB0F1c3RyaWExDzANBgNVBAcTBlZpZW5uYTEaMBgGA1UEChMRVGlhbmkgU3Bpcml0IEdtYkgx GTAXBgNVBAsTEERlbW8gRW52aXJvbm1lbnQxEDAOBgNVBAMTB1Rlc3QgQ0ExMTAvBgkqhkiG9w0B CQEWIm1hc3NpbWlsaWFuby5tYXNpQHRpYW5pLXNwaXJpdC5jb20CAQkwDQYJKoZIhvcNAQEBBQAE gYCGPa/6qOi8gnjOXzubcVZjJ8QIiEFhR6JOsRAu/6lMjofAF3+3EGa9VQ2+bFWkHNLCu/DoM+wU PI7bSIakfT4TsEGkol7z6U7oHQ144PJL0V8FVGh/KHqzqH269GWfw/8mDtDqFnktrA+C1MA4o3fI 4oVbQ04JVfpIfmFiiVc2cjCABgkqhkiG9w0BBwEwHQYJYIZIAWUDBAEWBBAkEBLEk1HlKh+pDYAW aorwoIAEggHAKXvIDQnLdv0Ut3e+L8J3wB88djODk+rnPnJYn10NHsvbsgBhISayYWP2+1qOHVWc SFkRJvhbvhPn/rgNSNfoTJ+TVMGtZEa4N4az0bzQix/YW2Y3Ct3ez0dxX3Id9fJXpHm6/nZ2NMvc vHl3M0Fz2gRb7Bb4zkWmy3CexA691wBXgnzwp1+PAikCTM5hMDxUZcBqr4aN/qJC63oduU4owKRu 04R3anTqCD4Zdg/qbAFbFHjXLb6uyrpBPRFXxzlQukRraY3VjEiKioaH2JkBUESaaecdK8Qg1rMW wVqah/GEVssAgprty3QJQAtEFuoreQKwD7pu15QeEjKV2Ou+bBgcmhlKMxOPYYOGpaf+kYEUJOM3 QWLWHZDUOv9/kx+UMcGpZAZTpY3VpK2LBAxnRoDhkkv2YSAA71l75ea7AylsRfucsp3PScAqnsqJ sKrWMLAfRt8in+PrP+kzM2ENE96q2sjkPWz/QiglGFLcumQ71KulxRCciakBfp8G3V2AfZMceZbZ 45fcGXfYXlBmD8gRlpfTlRsrVbBp4i/owo5KChnd4BWHpcXO3YUMW2Fw+K7k8uP3820j0QkLTvgI 6wAAAAAAAAAAAAA=bouncycastle-1.49.orig/test/data/org/bouncycastle/mail/smime/test/embeddedmulti.message0000644000175000017500000001536710554373304031010 0ustar ebourgebourgReceived: from AcerRalf (unknown [212.25.18.62]) (Authenticated sender: hauser@privasphere.com) by smtp-dev.privasphere.com (Postfix) with ESMTP id 2FE6D2805A for ; Wed, 17 Jan 2007 13:18:27 +0100 (CET) From: "Ralf Hauser192.168.1.253" To: Subject: Date: Wed, 17 Jan 2007 13:18:13 +0100 Message-ID: <00e601c73a31$90a3c950$2301a8c0@AcerRalf> MIME-Version: 1.0 X-Mailer: Microsoft Office Outlook 11 Thread-Index: Acc6MY7qitwhFBTHSemjvSo/JZss/A== Content-Type: multipart/signed; protocol="application/x-pkcs7-signature"; micalg=SHA1; boundary="----=_NextPart_000_00E0_01C73A39.F0BAF680" X-MimeOLE: Produced By Microsoft MimeOLE V6.00.2900.3028 This is a multi-part message in MIME format. ------=_NextPart_000_00E0_01C73A39.F0BAF680 Content-Type: multipart/mixed; boundary="----=_NextPart_001_00E1_01C73A39.F0BAF680" ------=_NextPart_001_00E1_01C73A39.F0BAF680 Content-Type: text/plain; charset="us-ascii" Content-Transfer-Encoding: 7bit Hello ------=_NextPart_001_00E1_01C73A39.F0BAF680 Content-Type: text/plain; name="ro.txt" Content-Transfer-Encoding: quoted-printable Content-Disposition: attachment; filename="ro.txt" Lieber Ralf Besten Dank f=FCr die =C4nderungsvorschl=E4ge. Ich werde das heute Abend = anpassen und dann einreichen.=20 Dann schauen wir. Von der Publizit=E4t her w=E4re eine = Ver=F6ffentlichung im IEEE Computer schon sehr gut. Sch=F6n, dass das mit der Offerte geklappt hat. ... Sch=F6ne Woche und Gruss, Rolf ------=_NextPart_001_00E1_01C73A39.F0BAF680-- ------=_NextPart_000_00E0_01C73A39.F0BAF680 Content-Type: application/x-pkcs7-signature; name="smime.p7s" Content-Transfer-Encoding: base64 Content-Disposition: attachment; filename="smime.p7s" MIAGCSqGSIb3DQEHAqCAMIACAQExCzAJBgUrDgMCGgUAMIAGCSqGSIb3DQEHAQAAoIIK9TCCAy0w ggKWoAMCAQICAQAwDQYJKoZIhvcNAQEEBQAwgdExCzAJBgNVBAYTAlpBMRUwEwYDVQQIEwxXZXN0 ZXJuIENhcGUxEjAQBgNVBAcTCUNhcGUgVG93bjEaMBgGA1UEChMRVGhhd3RlIENvbnN1bHRpbmcx KDAmBgNVBAsTH0NlcnRpZmljYXRpb24gU2VydmljZXMgRGl2aXNpb24xJDAiBgNVBAMTG1RoYXd0 ZSBQZXJzb25hbCBGcmVlbWFpbCBDQTErMCkGCSqGSIb3DQEJARYccGVyc29uYWwtZnJlZW1haWxA dGhhd3RlLmNvbTAeFw05NjAxMDEwMDAwMDBaFw0yMDEyMzEyMzU5NTlaMIHRMQswCQYDVQQGEwJa QTEVMBMGA1UECBMMV2VzdGVybiBDYXBlMRIwEAYDVQQHEwlDYXBlIFRvd24xGjAYBgNVBAoTEVRo YXd0ZSBDb25zdWx0aW5nMSgwJgYDVQQLEx9DZXJ0aWZpY2F0aW9uIFNlcnZpY2VzIERpdmlzaW9u MSQwIgYDVQQDExtUaGF3dGUgUGVyc29uYWwgRnJlZW1haWwgQ0ExKzApBgkqhkiG9w0BCQEWHHBl cnNvbmFsLWZyZWVtYWlsQHRoYXd0ZS5jb20wgZ8wDQYJKoZIhvcNAQEBBQADgY0AMIGJAoGBANRp 19SwlGRbcelH2AxRtupykbCEXn0tDY97Et+FJXUodDpCLGMnn5V7S+9+GYcdhuqj3bnOlmQawhRu RKx85o/oTQ9xH0A4pgCjh3j2+ZSGXq3qwF5269kUo11uenwMpUtVfwYZKX+emibVars4JAhqmMex 2qOYkf152+VaxBy5AgMBAAGjEzARMA8GA1UdEwEB/wQFMAMBAf8wDQYJKoZIhvcNAQEEBQADgYEA x+ySfk749ZalZ2IqpPBNEWDQb41gWGGsJrtSNVwIzzD7qEqWih9iQiOMFw/0umScF6xHKd+dmF7S bGBxXKKs3Hnj524ARx+1DSjoAp3kmv0T9KbZfLH43F8jJgmRgHPQFBveQ6mDJfLmnC8Vyv6mq4oH dYsM3VGEa+T40c53ooEwggM/MIICqKADAgECAgENMA0GCSqGSIb3DQEBBQUAMIHRMQswCQYDVQQG EwJaQTEVMBMGA1UECBMMV2VzdGVybiBDYXBlMRIwEAYDVQQHEwlDYXBlIFRvd24xGjAYBgNVBAoT EVRoYXd0ZSBDb25zdWx0aW5nMSgwJgYDVQQLEx9DZXJ0aWZpY2F0aW9uIFNlcnZpY2VzIERpdmlz aW9uMSQwIgYDVQQDExtUaGF3dGUgUGVyc29uYWwgRnJlZW1haWwgQ0ExKzApBgkqhkiG9w0BCQEW HHBlcnNvbmFsLWZyZWVtYWlsQHRoYXd0ZS5jb20wHhcNMDMwNzE3MDAwMDAwWhcNMTMwNzE2MjM1 OTU5WjBiMQswCQYDVQQGEwJaQTElMCMGA1UEChMcVGhhd3RlIENvbnN1bHRpbmcgKFB0eSkgTHRk LjEsMCoGA1UEAxMjVGhhd3RlIFBlcnNvbmFsIEZyZWVtYWlsIElzc3VpbmcgQ0EwgZ8wDQYJKoZI hvcNAQEBBQADgY0AMIGJAoGBAMSmPFVzVftOucqZWh5owHUEcJ3f6f+jHuy9zfVb8hp2vX8MOmHy v1HOAdTlUAow1wJjWiyJFXCO3cnwK4Vaqj9xVsuvPAsH5/EfkTYkKhPPK9Xzgnc9A74r/rsYPge/ QIACZNenprufZdHFKlSFD0gEf6e20TxhBEAeZBlyYLf7AgMBAAGjgZQwgZEwEgYDVR0TAQH/BAgw BgEB/wIBADBDBgNVHR8EPDA6MDigNqA0hjJodHRwOi8vY3JsLnRoYXd0ZS5jb20vVGhhd3RlUGVy c29uYWxGcmVlbWFpbENBLmNybDALBgNVHQ8EBAMCAQYwKQYDVR0RBCIwIKQeMBwxGjAYBgNVBAMT EVByaXZhdGVMYWJlbDItMTM4MA0GCSqGSIb3DQEBBQUAA4GBAEiM0VCD6gsuzA2jZqxnD3+vrL7C F6FDlpSdf0whuPg2H6otnzYvwPQcUCCTcDz9reFhYsPZOhl+hLGZGwDFGguCdJ4lUJRix9sncVcl jd2pnDmOjCBPZV+V2vf3h9bGCE6u9uo05RAaWzVNd+NWIXiC3CEZNd4ksdMdRv9dX2VPMIIEfTCC A+agAwIBAgIQQjOqV9vzq5eg0RX+DW6Z+jANBgkqhkiG9w0BAQUFADBiMQswCQYDVQQGEwJaQTEl MCMGA1UEChMcVGhhd3RlIENvbnN1bHRpbmcgKFB0eSkgTHRkLjEsMCoGA1UEAxMjVGhhd3RlIFBl cnNvbmFsIEZyZWVtYWlsIElzc3VpbmcgQ0EwHhcNMDYwOTIwMDQzMzAzWhcNMDcwOTIwMDQzMzAz WjCCAU8xDzANBgNVBAQTBkhhdXNlcjENMAsGA1UEKhMEUmFsZjEUMBIGA1UEAxMLUmFsZiBIYXVz ZXIxHTAbBgkqhkiG9w0BCQEWDmhhdXNlckBhY20ub3JnMSQwIgYJKoZIhvcNAQkBFhVyYWxmaGF1 c2VyQGJsdWV3aW4uY2gxIDAeBgkqhkiG9w0BCQEWEWtvYWxhQGZsYW1iZXJnLmNoMSAwHgYJKoZI hvcNAQkBFhFyYWxmaGF1c2VyQGdteC5jaDElMCMGCSqGSIb3DQEJARYWaGF1c2VyQHByaXZhc3Bo ZXJlLm9yZzEiMCAGCSqGSIb3DQEJARYTaGF1c2VyQGNvbXB1dGVyLm9yZzElMCMGCSqGSIb3DQEJ ARYWaGF1c2VyQHByaXZhc3BoZXJlLmNvbTEcMBoGCSqGSIb3DQEJARYNaGF1c2VyQHA0dS5jaDCC ASIwDQYJKoZIhvcNAQEBBQADggEPADCCAQoCggEBAKhDnDargun5HVSOWV93s4Yo37LFJU1dAax6 pb5DlhwnpWJ1r6B7VxAYAZNRtCGbJ9lvrFX4MvqDZNCD1pEWfotAvYwJESW1tQPbh1RbAHoJLoUs I/G3zSvx6JtRkhsfW/vddpzszZz+pYRr9QhoduP0CWoJ3YR+lImXC9iawOUIxjzspmEoupa+w/SD hT0Ie66vEnztrtJMVhaWYiCFcrdpkxiaYNVX9tYWoPt3dbkMD5DnNMUG6C4cSO8B+2RT2mi+wMxO 782Rr3SQFk3DlgvO/HHAn4GpGhQaexEo6AccBfIi4spp0HwOsKFaxWxzCyQfZZHF9233NZPbme+7 sxsCAwEAAaOBwDCBvTCBrAYDVR0RBIGkMIGhgQ5oYXVzZXJAYWNtLm9yZ4EVcmFsZmhhdXNlckBi bHVld2luLmNogRFrb2FsYUBmbGFtYmVyZy5jaIERcmFsZmhhdXNlckBnbXguY2iBFmhhdXNlckBw cml2YXNwaGVyZS5vcmeBE2hhdXNlckBjb21wdXRlci5vcmeBFmhhdXNlckBwcml2YXNwaGVyZS5j b22BDWhhdXNlckBwNHUuY2gwDAYDVR0TAQH/BAIwADANBgkqhkiG9w0BAQUFAAOBgQAFjXl1MSFJ ZtAcyCERaYlGpg/muMXf+bLeahfpAL7Nc+SrPmU22thhXGR3qHuxMXDUi5n6qE/Y+Dk9LcNxXVYQ mtqU/rqQN8UMGuTTDOqI5iEZ/3h5aATaF34Q6s63jWih2tz3wS2o2LuLqn8BeW7SEzwmbiXIAxEG PeL+fb3cWjGCA3kwggN1AgEBMHYwYjELMAkGA1UEBhMCWkExJTAjBgNVBAoTHFRoYXd0ZSBDb25z dWx0aW5nIChQdHkpIEx0ZC4xLDAqBgNVBAMTI1RoYXd0ZSBQZXJzb25hbCBGcmVlbWFpbCBJc3N1 aW5nIENBAhBCM6pX2/Orl6DRFf4Nbpn6MAkGBSsOAwIaBQCgggHYMBgGCSqGSIb3DQEJAzELBgkq hkiG9w0BBwEwHAYJKoZIhvcNAQkFMQ8XDTA3MDExNzEyMTgxMlowIwYJKoZIhvcNAQkEMRYEFCyM nI5LMqCPyL8fFoazmFt4ref8MGcGCSqGSIb3DQEJDzFaMFgwCgYIKoZIhvcNAwcwDgYIKoZIhvcN AwICAgCAMA0GCCqGSIb3DQMCAgFAMAcGBSsOAwIHMA0GCCqGSIb3DQMCAgEoMAcGBSsOAwIaMAoG CCqGSIb3DQIFMIGFBgkrBgEEAYI3EAQxeDB2MGIxCzAJBgNVBAYTAlpBMSUwIwYDVQQKExxUaGF3 dGUgQ29uc3VsdGluZyAoUHR5KSBMdGQuMSwwKgYDVQQDEyNUaGF3dGUgUGVyc29uYWwgRnJlZW1h aWwgSXNzdWluZyBDQQIQQjOqV9vzq5eg0RX+DW6Z+jCBhwYLKoZIhvcNAQkQAgsxeKB2MGIxCzAJ BgNVBAYTAlpBMSUwIwYDVQQKExxUaGF3dGUgQ29uc3VsdGluZyAoUHR5KSBMdGQuMSwwKgYDVQQD EyNUaGF3dGUgUGVyc29uYWwgRnJlZW1haWwgSXNzdWluZyBDQQIQQjOqV9vzq5eg0RX+DW6Z+jAN BgkqhkiG9w0BAQEFAASCAQBBT+gKdSLJTvjYyJwcsXUKFCCc49qE439FrvlNqkGUntAsjkli3edT tAO9Zf1FH1z97Wv4ZUIyizRlRW8y3hqqr2pdWeCiawrSy/t24hBzb0fjiojcjvZfp/IY73eKssQb zDVkECkdapbKcbCaSw7sjQvdocM4Ev2YKXWiOF5CX0QeIfsl5tqy2P32XF2KUXWvh63pxZ+MyTOo qb3fxrp8y8aWqmDitITqTVQ14vmd/bbNSUIes9UNjNTTT23wbBU/YBYgBwFP5xJzDe78OcZE8QVc 9Sr98OAwOttE6mwibQ2Cry2VlMKe/k0mdsPMvt7sOvCgMNa3ogCQ0SP3uXv3AAAAAAAA ------=_NextPart_000_00E0_01C73A39.F0BAF680-- bouncycastle-1.49.orig/test/data/org/bouncycastle/mail/smime/test/validator.fakeRoot.crt0000644000175000017500000000164010503212005031053 0ustar ebourgebourg-----BEGIN CERTIFICATE----- MIICgDCCAemgAwIBAgIBATANBgkqhkiG9w0BAQUFADA0MQswCQYDVQQGEwJDSDEl MCMGA1UEAxMcU2lnbmVkTWFpbFZhbGlkYXRvclRlc3QgUm9vdDAeFw0wNjA4MjUw OTE5NDJaFw0yMjA4MjkwOTE5NDJaMDQxCzAJBgNVBAYTAkNIMSUwIwYDVQQDExxT aWduZWRNYWlsVmFsaWRhdG9yVGVzdCBSb290MIGfMA0GCSqGSIb3DQEBAQUAA4GN ADCBiQKBgQDnwMC/V/kWv2+FhLrY0HsJfAyMuVSY8ep86SYW24kU3Ul7ukNzcMhd MOaLlW4E4i1Tq9b6PADRbTNLcUzGovEDhN/h2uNywe5GTy1lJyzreSjPhTG9Nhsy E5Kd5VVERopY2awba44dJDavgpuWjJUuzD2o/sJnbGnxne8oHr6j1QIDAQABo4Gh MIGeMA8GA1UdEwEB/wQFMAMBAf8wHQYDVR0OBBYEFAtJiqUe3RVQ9zEdchR1+gyw zI1nMFwGA1UdIwRVMFOAFAtJiqUe3RVQ9zEdchR1+gywzI1noTikNjA0MQswCQYD VQQGEwJDSDElMCMGA1UEAxMcU2lnbmVkTWFpbFZhbGlkYXRvclRlc3QgUm9vdIIB ATAOBgNVHQ8BAf8EBAMCAQYwDQYJKoZIhvcNAQEFBQADgYEAxcoyBGMek8GtTPmi uN1P1KNZNrl7JFffp3Z3FZ/cSgOlvhbgJ2qBMpSHOk7txgRmny0pbeXTRcesT9Wg EtJ5LOw6k/nLyXszv9SZnp0QgJj4OKZUIhwPOvuZgxcBZyN83C40Fg7t10c8v804 xY6nBCHlWmmq1UrBWb2kDkgjUmo= -----END CERTIFICATE----- bouncycastle-1.49.orig/test/data/org/bouncycastle/mail/smime/test/key.pem0000644000175000017500000000156712051700100026104 0ustar ebourgebourg-----BEGIN RSA PRIVATE KEY----- MIICXQIBAAKBgQDAvqAUfipaMn2ybE0B0q6SShsmAJp4mb3mFzh1oqslYwwZ5od1 yxaZhJcwyMr+New/aMV6KyI07Xt5wO19ZpS6bsfU8QxTdmPP7Jr1vU2XGU2Iq8kd bYSVde1/9ENXGXyzxS5OeTjnntQk7eu4idQOE4wExC3w4u4fkr4wRBFt0QIDAQAB AoGADrd/aZEokrKAPntedeEsSyc1Y3VwVf0HLuZe/TxqbPRfHCsp9KiJFTe2g5cR SM+9Nio9ydI5TmlDoExG1ehbOq7jlGEJVq4v8bnDqvD+f4abcE0WTJsIaloc3Feh D8V4bHuHnOawindmrmDV076XHCE+nDn0pYCziNKGynoPGbECQQDzC+OvxbdBkaed 65wN+Nsc4PpyQUwIA9xii+cIiJWd1TmZvDlae6QGJKY7zl70t5HthXPBtA1Iizl4 F3sCQgm/AkEAywRrzPRcYlIPQRuRG4KL1wdRAvbZTyUt/5JhPBRqytal9tlm21cX ZeCEPuTXNTIJiLmMRiqElTekg9qiYxXMbwJBAO2obpfuKef/2XtebFZtRTTT+ZHH r+UWgWYLj3qUtFiFq7FckGieBiHLrJFGlyuMZTFxEWQT//kzyppXu3zVvlkCQQCA +Y8OxxNF90Hvp/a41mfGtMQ3sOD/kew2GCWjyIjL0i/fsd/RavPXaho55qH+DorW DKLcFLjkH1Rp2+UcM8YLAkA6fKFgDrOH9+q5Gyh8oi+cEI9+OxRfA0+lbEjgZmJV 3b3e02Y7TIsAJvvoILfV8bHsjJhJZ+LeH8vJipYz3VFb -----END RSA PRIVATE KEY----- bouncycastle-1.49.orig/test/data/org/bouncycastle/mail/smime/test/certpath_inter1.crt0000644000175000017500000000211310621263376030427 0ustar ebourgebourg-----BEGIN CERTIFICATE----- MIIC/TCCAmagAwIBAgIBBDANBgkqhkiG9w0BAQUFADBdMRswGQYDVQQDExJDcmVh dGVDZXJ0UGF0aFJvb3QxCzAJBgNVBAYTAkNIMQ8wDQYDVQQHEwZadXJpY2gxIDAe BgNVBAoTF1NpZ25lZE1haWxWYWxpZGF0b3JUZXN0MB4XDTA3MDUwOTEyMjEyNloX DTI3MDUwNDEyMTYxN1owXjEcMBoGA1UEAxMTQ3JlYXRlQ2VydFBhdGhJbnRlcjEL MAkGA1UEBhMCQ0gxDzANBgNVBAcTBlp1cmljaDEgMB4GA1UEChMXU2lnbmVkTWFp bFZhbGlkYXRvclRlc3QwgZ8wDQYJKoZIhvcNAQEBBQADgY0AMIGJAoGBAOezbRC1 7BAAdFckLevyWLGj+3kDQ1DRRBaxGf7Ym40v1OZtUc4FhnFfGTHh5D0XMfvM3Wwq To5xi/iho7vI16s1ZAfnWN5pXubb9ZqNU7uYQdjmk50glTa2U28Hiskr1pxHis9F 8cyz5cTH2RG00LfLWMfGVHsrFIN3naeCupbdAgMBAAGjgcswgcgwDwYDVR0TAQH/ BAUwAwEB/zAdBgNVHQ4EFgQU/p4ZGOskWgJT56Vm2+aBFH7TNeAwgYUGA1UdIwR+ MHyAFCQH6UCakD8+qWKy8yY61DMSABfdoWGkXzBdMRswGQYDVQQDExJDcmVhdGVD ZXJ0UGF0aFJvb3QxCzAJBgNVBAYTAkNIMQ8wDQYDVQQHEwZadXJpY2gxIDAeBgNV BAoTF1NpZ25lZE1haWxWYWxpZGF0b3JUZXN0ggEBMA4GA1UdDwEB/wQEAwIBBjAN BgkqhkiG9w0BAQUFAAOBgQDBeipc+tTpOau+SOihZcCDFjZG3W8Q4iewmCzf3UHd 7tK85wVUts0BeAgDzeqD8b+oV+Q4HIv1RkSt+4foPgRu6ujljMkS9cQTYFkaogGp qwM4BeVFInXdjV4MfzCVJkIA2RZ56dKGGuZrMAtfHQl/9M6jlYs9uYHnj0BAVc+0 8Q== -----END CERTIFICATE----- bouncycastle-1.49.orig/test/data/org/bouncycastle/mail/smime/test/validator.revoked.eml0000644000175000017500000000611010503212005030722 0ustar ebourgebourgFrom: "Armin Häberling" To: testmail@bouncycastle.org Subject: Validator Test Revoked Message-ID: <27789929.11157107745125.JavaMail.armin@lappi> MIME-Version: 1.0 Content-Type: multipart/signed; protocol="application/pkcs7-signature"; micalg=sha1; boundary="----=_Part_0_10440721.1157107745088" ------=_Part_0_10440721.1157107745088 Content-Type: text/plain; charset=us-ascii Content-Transfer-Encoding: 7bit This is a Test Mail! ------=_Part_0_10440721.1157107745088 Content-Type: application/pkcs7-signature; name=smime.p7s; smime-type=signed-data Content-Transfer-Encoding: base64 Content-Disposition: attachment; filename="smime.p7s" Content-Description: S/MIME Cryptographic Signature MIAGCSqGSIb3DQEHAqCAMIACAQExCzAJBgUrDgMCGgUAMIAGCSqGSIb3DQEHAQAAoIIFMDCCAoAw ggHpoAMCAQICAQEwDQYJKoZIhvcNAQEFBQAwNDELMAkGA1UEBhMCQ0gxJTAjBgNVBAMTHFNpZ25l ZE1haWxWYWxpZGF0b3JUZXN0IFJvb3QwHhcNMDYwODI2MTI1NzUyWhcNMTYwODIzMTI1NzUyWjA0 MQswCQYDVQQGEwJDSDElMCMGA1UEAxMcU2lnbmVkTWFpbFZhbGlkYXRvclRlc3QgUm9vdDCBnzAN BgkqhkiG9w0BAQEFAAOBjQAwgYkCgYEA4s2LugTz/byjUAsZAGe0T1U3GTYzYckXSn2N75agogy3 eqWD7DC3CdiaCYj1qkogZXTiGlyziBa3oYqhy9wN9bFSobLlOJlNFvl2hdBS769nMfvCdoNWNc5R 8qI4BZBFJgm2OtnlQC8r0Kc2iUFqx/HSoN4svXfkYEIjXR5cJhcCAwEAAaOBoTCBnjAPBgNVHRMB Af8EBTADAQH/MB0GA1UdDgQWBBQ6maBDgpnIH6sSFWsCM6w1aLo+ljBcBgNVHSMEVTBTgBQ6maBD gpnIH6sSFWsCM6w1aLo+lqE4pDYwNDELMAkGA1UEBhMCQ0gxJTAjBgNVBAMTHFNpZ25lZE1haWxW YWxpZGF0b3JUZXN0IFJvb3SCAQEwDgYDVR0PAQH/BAQDAgEGMA0GCSqGSIb3DQEBBQUAA4GBAFcv F59aBSc8Hmxgtd05PdiOpHTEUaaQ8LdK9jdOBDtoHozNwHXoQLQZJN55Nowvori5s7yt25fjvB6h 5flkdnisqEU01I4+L/cySWPQQJFWOc+4D/BgfLGQUKK4Zenm3ky6UrywtXDvB7Af5CzZopf13i2k d6l1vZ/mXGe9/easMIICqDCCAhGgAwIBAgIBETANBgkqhkiG9w0BAQQFADA0MQswCQYDVQQGEwJD SDElMCMGA1UEAxMcU2lnbmVkTWFpbFZhbGlkYXRvclRlc3QgUm9vdDAeFw0wNjA5MDEwODQyMDda Fw0wNzA5MDEwODQyMDdaMF8xCzAJBgNVBAYTAkNIMSYwJAYJKoZIhvcNAQkBFhdhcm1pbmhhQHN0 dWRlbnQuZXRoei5jaDEoMCYGA1UEAxMfU2lnbmFkTWFpbFZhbGlkYXRvclRlc3QgUmV2b2tlZDCB nzANBgkqhkiG9w0BAQEFAAOBjQAwgYkCgYEAoodPf0lqx/AEPFa2tBT7M1oyyqaiyy7e6xOE7VAf 1cT3BtXt89Axwbzi5f4X/9U+1LeY1548fE2Am8yv4xicn2rEwABJ6ZWsYr4bYLjhbJIlL8rFc4a7 kVP5PD5qnfNRmWtV5jknCkMuZ5dMGq3pXRMv1YKI+dlBTzD2byB8Qf8CAwEAAaOBnjCBmzAMBgNV HRMBAf8EAjAAMB0GA1UdDgQWBBRqK+a+aCU6kNT5qXlXGjukjukntzBcBgNVHSMEVTBTgBQ6maBD gpnIH6sSFWsCM6w1aLo+lqE4pDYwNDELMAkGA1UEBhMCQ0gxJTAjBgNVBAMTHFNpZ25lZE1haWxW YWxpZGF0b3JUZXN0IFJvb3SCAQEwDgYDVR0PAQH/BAQDAgeAMA0GCSqGSIb3DQEBBAUAA4GBANtx kT4DnaoRV8dnb4dZgynP/h1LQ623aARgJaqsQ8ENxbDdaHUIBMP4qerTigJ/wRkpZykn9+Op2xNN 8vK4IXoDz8521fmhaD6Rs2sPei2toooYnjV1R8og1e/E6EjEKa/jfhbgfeZ5cpR/vt7hf5Icp7Df fJkWfKrnZqs2dqCaMYIBdTCCAXECAQEwOTA0MQswCQYDVQQGEwJDSDElMCMGA1UEAxMcU2lnbmVk TWFpbFZhbGlkYXRvclRlc3QgUm9vdAIBETAJBgUrDgMCGgUAoIGTMBgGCSqGSIb3DQEJAzELBgkq hkiG9w0BBwEwHAYJKoZIhvcNAQkFMQ8XDTA2MDkwMTEwNDkwNVowIwYJKoZIhvcNAQkEMRYEFOfM MMkli+RR5tUkh0EHvOIWN3FtMDQGCSqGSIb3DQEJDzEnMCUwCgYIKoZIhvcNAwcwDgYIKoZIhvcN AwICAgCAMAcGBSsOAwIHMA0GCSqGSIb3DQEBAQUABIGAEZ8GPKrbR3aA4MEH1ZYOhV2WFAvzVQMZ k0LcrM0jQhJTCS7037qHoz4aCPK1wayzaCtZwQs7dh7qHiLXQmTvj5bR034gIqL0ySM6T/Ny6WN0 I7ZoKj2gNvqOpBLrsytcGnW7a0XAnpWxEqegzVnJ8LjhAKUtLoes4nDqGTGrHzAAAAAAAAA= ------=_Part_0_10440721.1157107745088-- bouncycastle-1.49.orig/test/data/org/bouncycastle/mail/smime/test/validator.keyUsage.eml0000644000175000017500000000611110503212005031041 0ustar ebourgebourgFrom: "Armin Häberling" To: testmail@bouncycastle.org Message-ID: <27789929.11156769558002.JavaMail.armin@lappi> Subject: Validator Test KeyUsage MIME-Version: 1.0 Content-Type: multipart/signed; protocol="application/pkcs7-signature"; micalg=sha1; boundary="----=_Part_0_10440721.1156769557965" ------=_Part_0_10440721.1156769557965 Content-Type: text/plain; charset=us-ascii Content-Transfer-Encoding: 7bit This is a Test Mail! ------=_Part_0_10440721.1156769557965 Content-Type: application/pkcs7-signature; name=smime.p7s; smime-type=signed-data Content-Transfer-Encoding: base64 Content-Disposition: attachment; filename="smime.p7s" Content-Description: S/MIME Cryptographic Signature MIAGCSqGSIb3DQEHAqCAMIACAQExCzAJBgUrDgMCGgUAMIAGCSqGSIb3DQEHAQAAoIIFMTCCAoAw ggHpoAMCAQICAQEwDQYJKoZIhvcNAQEFBQAwNDELMAkGA1UEBhMCQ0gxJTAjBgNVBAMTHFNpZ25l ZE1haWxWYWxpZGF0b3JUZXN0IFJvb3QwHhcNMDYwODI2MTI1NzUyWhcNMTYwODIzMTI1NzUyWjA0 MQswCQYDVQQGEwJDSDElMCMGA1UEAxMcU2lnbmVkTWFpbFZhbGlkYXRvclRlc3QgUm9vdDCBnzAN BgkqhkiG9w0BAQEFAAOBjQAwgYkCgYEA4s2LugTz/byjUAsZAGe0T1U3GTYzYckXSn2N75agogy3 eqWD7DC3CdiaCYj1qkogZXTiGlyziBa3oYqhy9wN9bFSobLlOJlNFvl2hdBS769nMfvCdoNWNc5R 8qI4BZBFJgm2OtnlQC8r0Kc2iUFqx/HSoN4svXfkYEIjXR5cJhcCAwEAAaOBoTCBnjAPBgNVHRMB Af8EBTADAQH/MB0GA1UdDgQWBBQ6maBDgpnIH6sSFWsCM6w1aLo+ljBcBgNVHSMEVTBTgBQ6maBD gpnIH6sSFWsCM6w1aLo+lqE4pDYwNDELMAkGA1UEBhMCQ0gxJTAjBgNVBAMTHFNpZ25lZE1haWxW YWxpZGF0b3JUZXN0IFJvb3SCAQEwDgYDVR0PAQH/BAQDAgEGMA0GCSqGSIb3DQEBBQUAA4GBAFcv F59aBSc8Hmxgtd05PdiOpHTEUaaQ8LdK9jdOBDtoHozNwHXoQLQZJN55Nowvori5s7yt25fjvB6h 5flkdnisqEU01I4+L/cySWPQQJFWOc+4D/BgfLGQUKK4Zenm3ky6UrywtXDvB7Af5CzZopf13i2k d6l1vZ/mXGe9/easMIICqTCCAhKgAwIBAgIBCDANBgkqhkiG9w0BAQQFADA0MQswCQYDVQQGEwJD SDElMCMGA1UEAxMcU2lnbmVkTWFpbFZhbGlkYXRvclRlc3QgUm9vdDAeFw0wNjA4MjYxMzE0NTFa Fw0wNzA4MjYxMzE0NTFaMGAxCzAJBgNVBAYTAkNIMSYwJAYJKoZIhvcNAQkBFhdhcm1pbmhhQHN0 dWRlbnQuZXRoei5jaDEpMCcGA1UEAxMgU2lnbmVkTWFpbFZhbGlkYXRvclRlc3QgS2V5VXNhZ2Uw gZ8wDQYJKoZIhvcNAQEBBQADgY0AMIGJAoGBAL1u9FMa5xb8FqhYxynhy8HBFTXey0FlaVTPYefi PSQAyzIvLEo8ykboCPvTiwfrV4ja7nQ5HrJr22/gP1YYK/VH+O9WcU42+cj2j0eRv+wr6PXmHAMc au/RtONZW7uhKahdF9TDVLmkjxBvaGYfykMP63CcetN87aOxDTUemTizAgMBAAGjgZ4wgZswDAYD VR0TAQH/BAIwADAdBgNVHQ4EFgQUO3drE7TX2tJ9Rw0WEjHKUTBje78wXAYDVR0jBFUwU4AUOpmg Q4KZyB+rEhVrAjOsNWi6PpahOKQ2MDQxCzAJBgNVBAYTAkNIMSUwIwYDVQQDExxTaWduZWRNYWls VmFsaWRhdG9yVGVzdCBSb290ggEBMA4GA1UdDwEB/wQEAwIEEDANBgkqhkiG9w0BAQQFAAOBgQA0 NRzBd+OzlwId90bdmQWwpWDMDZ5PRtv+edmXlhqxlyybQQrxe6KkO5CzdkvsAs0Q+gBKYpVpk64H ZTczpA3PFGNYeLyYAd7MOKBKhGo6QSQhaZpN3N9f6SnRNzoLDcs8Ym7BNSVNoAzWzSrmZMuuIWQv nx0eEGWiC1hyRfehBDGCAXUwggFxAgEBMDkwNDELMAkGA1UEBhMCQ0gxJTAjBgNVBAMTHFNpZ25l ZE1haWxWYWxpZGF0b3JUZXN0IFJvb3QCAQgwCQYFKw4DAhoFAKCBkzAYBgkqhkiG9w0BCQMxCwYJ KoZIhvcNAQcBMBwGCSqGSIb3DQEJBTEPFw0wNjA4MjgxMjUyMzhaMCMGCSqGSIb3DQEJBDEWBBTn zDDJJYvkUebVJIdBB7ziFjdxbTA0BgkqhkiG9w0BCQ8xJzAlMAoGCCqGSIb3DQMHMA4GCCqGSIb3 DQMCAgIAgDAHBgUrDgMCBzANBgkqhkiG9w0BAQEFAASBgIJqukQ2lOCg1Oc1mM914vDvPb8WzHkP M2bUBoVub47lYUKpKeOb/l+YXQCdDQbxps/vkbja7Atyyim2A0QVXykZoErzCG/gYdsXWMUrm3c/ r4QlEvNdKg0KU12kt17ZtIy7gVYi4YKbuUyKf6TsmjkhUFLiYSLgGpNUdBgPpq0OAAAAAAAA ------=_Part_0_10440721.1156769557965-- bouncycastle-1.49.orig/test/data/org/bouncycastle/mail/smime/test/test256.message0000644000175000017500000000260012051700051027365 0ustar ebourgebourgContent-Type: application/pkcs7-mime; name="smime.p7m"; smime-type=enveloped-data Content-Transfer-Encoding: base64 Content-Disposition: attachment; filename="smime.p7m" Content-Description: S/MIME Encrypted Message MIAGCSqGSIb3DQEHA6CAMIACAQAxggFOMIIBSgIBADCBsjCBrDELMAkGA1UEBhMCQVQxEDAOBgNV BAgTB0F1c3RyaWExDzANBgNVBAcTBlZpZW5uYTEaMBgGA1UEChMRVGlhbmkgU3Bpcml0IEdtYkgx GTAXBgNVBAsTEERlbW8gRW52aXJvbm1lbnQxEDAOBgNVBAMTB1Rlc3QgQ0ExMTAvBgkqhkiG9w0B CQEWIm1hc3NpbWlsaWFuby5tYXNpQHRpYW5pLXNwaXJpdC5jb20CAQkwDQYJKoZIhvcNAQEBBQAE gYALxKaiVW43jHjDiJ4kC6N90lpyG0jxeJ7nynWaR4YkDiUQ/jE8cJwRX0jBQeWKRvf3Y+XhRuB3 B76cKxBGTgMh6pCuLoIvgBJq54kqql/xz3hO7QRvvuHnEljlw2uhd0PQqQYe8oLdu1Yqyo9+9Jsx I7QX43E2H5b3nNGND24djDCABgkqhkiG9w0BBwEwHQYJYIZIAWUDBAEqBBD+UNge0S52HEPuFBEq IEvYoIAEggHAcOET1XS7H/OZALZ0cyns3p6kxgAlblE4BvMQnAen8VlhDehp130WdDF4jC+zRjza ZftPatKq/Hlhu0wuj+FZESjy2d2hR7FT8qCqGda70IyyOhloG7Ym+17E0MyYQsH38i+uC8NjcSeo egggsQoidePpg/9BNFMA4j6vORFcNBvnwj71mV2icx7mUud97cXobJnrfm3hmEmYkm7wL413cibH b8K3yNu/hMqJViT0GvlhQdR9hDgu5i2WhiE2UTaFu3xL2xNhzXBvhOwj/gikzFIWva4S/2JfK3M8 A0lYu6f1vYUF2jazi81wQFEF7qKyp7zx7X2iZjn8DDSCY73izHafF1JJijDFaHrD5245kaSJ7MKP jJ/HWk9lbed0ay8f96QuvWEEKSy4xejy6w7DKxKr4icN7KDE5Nyc2ZAJxmCm50B7yHpNZfKQ38E+ e/bCgvAESFcnw9pRJz9mXmwazxEvCpoO/ezgmgro+59CCRKqdUeOyyLQg6d7xqUcgeY1SoDxzEre i4IBlig6+HWLs+9OPMa2fuYYIVZvg7mpeM4lEfdhRssWBWwTTmrtwRbAaT7BTCtlvfqzpHrycp5O zgAAAAAAAAAAAAA=bouncycastle-1.49.orig/test/data/org/bouncycastle/mail/smime/test/quotable.message0000644000175000017500000000612610503212005027771 0ustar ebourgebourgX-Account-Key: account3 Received: from xfe0.d.ethz.ch ([82.130.124.40]) by EX0.d.ethz.ch with Microsoft SMTPSVC(6.0.3790.2499); Tue, 15 Aug 2006 16:15:12 +0200 Received: from cwlappi ([85.1.15.108]) by xfe0.d.ethz.ch over TLS secured channel with Microsoft SMTPSVC(6.0.3790.2499); Tue, 15 Aug 2006 16:15:12 +0200 Message-ID: <001001c6c075$08fe0690$1200000a@cwlappi> From: =?utf-8?Q?Armin_H=C3=A4berling?= To: Subject: testmail Date: Tue, 15 Aug 2006 16:12:31 +0200 MIME-Version: 1.0 Content-Type: multipart/signed; protocol="application/x-pkcs7-signature"; micalg=SHA1; boundary="----=_NextPart_000_000B_01C6C085.9C581740" X-Priority: 3 X-MSMail-Priority: Normal X-Mailer: Microsoft Outlook Express 6.00.2800.1409 X-MimeOLE: Produced By Microsoft MimeOLE V6.00.2800.1409 Return-Path: arminha@student.ethz.ch X-OriginalArrivalTime: 15 Aug 2006 14:15:12.0469 (UTC) FILETIME=[38E22850:01C6C075] This is a multi-part message in MIME format. ------=_NextPart_000_000B_01C6C085.9C581740 Content-Type: text/plain; charset="utf-8" Content-Transfer-Encoding: quoted-printable This is a testmail with a very long line that needs to be broken and = some non-ascii chars to enforce quoted-printable encoding: = =C3=A0=C3=A9=C3=A8 ------=_NextPart_000_000B_01C6C085.9C581740 Content-Type: application/x-pkcs7-signature; name="smime.p7s" Content-Transfer-Encoding: base64 Content-Disposition: attachment; filename="smime.p7s" MIAGCSqGSIb3DQEHAqCAMIACAQExCzAJBgUrDgMCGgUAMIAGCSqGSIb3DQEHAQAAoIICnzCCApsw ggIEoAMCAQICAQEwDQYJKoZIhvcNAQEFBQAwcjEnMCUGA1UEAx4eAEEAcgBtAGkAbgAgAEgA5ABi AGUAcgBsAGkAbgBnMQswCQYDVQQGEwJDSDESMBAGA1UEBxMJT3R0ZW5iYWNoMSYwJAYJKoZIhvcN AQkBFhdhcm1pbmhhQHN0dWRlbnQuZXRoei5jaDAeFw0wNjA1MDgxMzM2MjNaFw0wNzA1MDgxMzM2 MjNaMHIxJzAlBgNVBAMeHgBBAHIAbQBpAG4AIABIAOQAYgBlAHIAbABpAG4AZzELMAkGA1UEBhMC Q0gxEjAQBgNVBAcTCU90dGVuYmFjaDEmMCQGCSqGSIb3DQEJARYXYXJtaW5oYUBzdHVkZW50LmV0 aHouY2gwgZ8wDQYJKoZIhvcNAQEBBQADgY0AMIGJAoGBAM/WQ3bS/o+4qdxcZmf517QuUopWmPZp a5QHEyu36dh2tIWMQSc0Qk1mRiV4eA4ZdHVkWzBKrEdus4xsT/iVNTmeOmQ/Py4uDqVgrRJqeqtM AcgWk+SBPxITEmdgGtnAeIGu7VYcYhcLCHR5vhbXKPbSTswHD6qh/OsaSQ2Zfew5AgMBAAGjQTA/ MAkGA1UdEwQCMAAwDgYDVR0PAQH/BAQDAgeAMCIGA1UdEQQbMBmBF2FybWluaGFAc3R1ZGVudC5l dGh6LmNoMA0GCSqGSIb3DQEBBQUAA4GBAAtm1j2ATEh3fi9HAYD8Dev+6VI/mPNXvSCFWtY7UoyH 0fy41dmLWyJZ81KcSR5804CdpGNrr4cKIWGfXZXEL9DOScaArgLsaO3nJThaTrc6koqvFgevUtNG VKRDogEbDvZjsx7lZzSJz6Ioum4uM0zGIcCAgLz6FIAmqOO1SUZOMYIB2jCCAdYCAQEwdzByMScw JQYDVQQDHh4AQQByAG0AaQBuACAASADkAGIAZQByAGwAaQBuAGcxCzAJBgNVBAYTAkNIMRIwEAYD VQQHEwlPdHRlbmJhY2gxJjAkBgkqhkiG9w0BCQEWF2FybWluaGFAc3R1ZGVudC5ldGh6LmNoAgEB MAkGBSsOAwIaBQCggbowGAYJKoZIhvcNAQkDMQsGCSqGSIb3DQEHATAcBgkqhkiG9w0BCQUxDxcN MDYwODE1MTQxMjMxWjAjBgkqhkiG9w0BCQQxFgQUcfo6jNgOyesiBRskKXFqJtqkg3IwWwYJKoZI hvcNAQkPMU4wTDAKBggqhkiG9w0DBzAOBggqhkiG9w0DAgICAIAwDQYIKoZIhvcNAwICAUAwBwYF Kw4DAgcwDQYIKoZIhvcNAwICASgwBwYFKw4DAh0wDQYJKoZIhvcNAQEBBQAEgYBLQB3SDXom8ruD eoESk6zJQxLxZCgR92FCTHuWlSLHjLZWEAYU+i3Tn87tP5p9+fpj1nHZ1lQdZULONpYzpHjCzVUC mQ2KQAhiY81UDA3+ctjnAaYUnZXy+bUVCNinNux8dshsSXO8pcFZKf/n75K7Im/aMznYCuSMgkU7 sUsz4QAAAAAAAA== ------=_NextPart_000_000B_01C6C085.9C581740-- bouncycastle-1.49.orig/test/data/org/bouncycastle/mail/smime/test/validator.validMail.eml0000644000175000017500000000612310503212005031171 0ustar ebourgebourgFrom: "Armin Häberling" To: testmail@bouncycastle.org Subject: Validator Valid Mail Message-ID: <27789929.11157362574316.JavaMail.armin@lappi> MIME-Version: 1.0 Content-Type: multipart/signed; protocol="application/pkcs7-signature"; micalg=sha1; boundary="----=_Part_0_10440721.1157362574277" ------=_Part_0_10440721.1157362574277 Content-Type: text/plain; charset=us-ascii Content-Transfer-Encoding: 7bit This is a Test Mail! ------=_Part_0_10440721.1157362574277 Content-Type: application/pkcs7-signature; name=smime.p7s; smime-type=signed-data Content-Transfer-Encoding: base64 Content-Disposition: attachment; filename="smime.p7s" Content-Description: S/MIME Cryptographic Signature MIAGCSqGSIb3DQEHAqCAMIACAQExCzAJBgUrDgMCGgUAMIAGCSqGSIb3DQEHAQAAoIIFOTCCAoAw ggHpoAMCAQICAQEwDQYJKoZIhvcNAQEFBQAwNDELMAkGA1UEBhMCQ0gxJTAjBgNVBAMTHFNpZ25l ZE1haWxWYWxpZGF0b3JUZXN0IFJvb3QwHhcNMDYwODI2MTI1NzUyWhcNMTYwODIzMTI1NzUyWjA0 MQswCQYDVQQGEwJDSDElMCMGA1UEAxMcU2lnbmVkTWFpbFZhbGlkYXRvclRlc3QgUm9vdDCBnzAN BgkqhkiG9w0BAQEFAAOBjQAwgYkCgYEA4s2LugTz/byjUAsZAGe0T1U3GTYzYckXSn2N75agogy3 eqWD7DC3CdiaCYj1qkogZXTiGlyziBa3oYqhy9wN9bFSobLlOJlNFvl2hdBS769nMfvCdoNWNc5R 8qI4BZBFJgm2OtnlQC8r0Kc2iUFqx/HSoN4svXfkYEIjXR5cJhcCAwEAAaOBoTCBnjAPBgNVHRMB Af8EBTADAQH/MB0GA1UdDgQWBBQ6maBDgpnIH6sSFWsCM6w1aLo+ljBcBgNVHSMEVTBTgBQ6maBD gpnIH6sSFWsCM6w1aLo+lqE4pDYwNDELMAkGA1UEBhMCQ0gxJTAjBgNVBAMTHFNpZ25lZE1haWxW YWxpZGF0b3JUZXN0IFJvb3SCAQEwDgYDVR0PAQH/BAQDAgEGMA0GCSqGSIb3DQEBBQUAA4GBAFcv F59aBSc8Hmxgtd05PdiOpHTEUaaQ8LdK9jdOBDtoHozNwHXoQLQZJN55Nowvori5s7yt25fjvB6h 5flkdnisqEU01I4+L/cySWPQQJFWOc+4D/BgfLGQUKK4Zenm3ky6UrywtXDvB7Af5CzZopf13i2k d6l1vZ/mXGe9/easMIICsTCCAhqgAwIBAgIBFjANBgkqhkiG9w0BAQQFADA0MQswCQYDVQQGEwJD SDElMCMGA1UEAxMcU2lnbmVkTWFpbFZhbGlkYXRvclRlc3QgUm9vdDAeFw0wNjA5MDEwOTIzMzZa Fw0wNzA5MDEwOTIzMzZaMGgxCzAJBgNVBAYTAkNIMSYwJAYJKoZIhvcNAQkBFhdhcm1pbmhhQHN0 dWRlbnQuZXRoei5jaDExMC8GA1UEAxMoU2lnbmVkTWFpbFZhbGlkYXRvclRlc3QgQ29ycnVwdFJv b3RTdG9yZTCBnzANBgkqhkiG9w0BAQEFAAOBjQAwgYkCgYEAw2WD0isnkyL9BwALaABrTchtCMsU 2iPLO1uKjHJqtm7Yq0SczaFNL5nGA+SDmB+w8pd6873WZa2LMJ74+rWu6UDzhogKjEjQ2dGtT7nV LgXdGxbhENhfBr70usLiZO8/g6f5Dfn97rlsZY+JTmn/cImS882BYUZPr7l4W47zce8CAwEAAaOB njCBmzAMBgNVHRMBAf8EAjAAMB0GA1UdDgQWBBSHDJP6mOuxvt5UN9tg6teTOtEvtTBcBgNVHSME VTBTgBQ6maBDgpnIH6sSFWsCM6w1aLo+lqE4pDYwNDELMAkGA1UEBhMCQ0gxJTAjBgNVBAMTHFNp Z25lZE1haWxWYWxpZGF0b3JUZXN0IFJvb3SCAQEwDgYDVR0PAQH/BAQDAgeAMA0GCSqGSIb3DQEB BAUAA4GBAEOgb3NswNP+fWEXpAyOGrNqie06K19RHGTz2D6l+XaXI/JkxqkcIDAix4fiBeuf/HMN LW6dW0dVSQ5MJhSW24h3avDx54JG/Ht++OC+jUqrN0vW0Gy2FZSU1+tTE2P5fyhL+BP/RTMYZJ+J pY6nRjuKo9T/7cflvYuS6R15e+2xMYIBdTCCAXECAQEwOTA0MQswCQYDVQQGEwJDSDElMCMGA1UE AxMcU2lnbmVkTWFpbFZhbGlkYXRvclRlc3QgUm9vdAIBFjAJBgUrDgMCGgUAoIGTMBgGCSqGSIb3 DQEJAzELBgkqhkiG9w0BBwEwHAYJKoZIhvcNAQkFMQ8XDTA2MDkwNDA5MzYxNFowIwYJKoZIhvcN AQkEMRYEFOfMMMkli+RR5tUkh0EHvOIWN3FtMDQGCSqGSIb3DQEJDzEnMCUwCgYIKoZIhvcNAwcw DgYIKoZIhvcNAwICAgCAMAcGBSsOAwIHMA0GCSqGSIb3DQEBAQUABIGAlmuwaJgNHp3iTS4gcAnt 5QRH0vEMjejc54FKhxGBlYzynROkXnhVEWnNIGNxwZsr+SVZDcABnTuAEMsQA9duYOCubSpIkq/G s8172uHpc/y4yvDpWekrEiF5X1LhJhvJxsac/6zAQl0yjO4waN78JzVSFK3lPzk1XA60oIOxhPoA AAAAAAA= ------=_Part_0_10440721.1157362574277-- bouncycastle-1.49.orig/test/data/org/bouncycastle/mail/smime/test/multi-alternative.eml0000644000175000017500000002130011001237562030754 0ustar ebourgebourgX-MimeOLE: Produced By Microsoft Exchange V6.5 Received: from OLDA0047.ewenet.ewe.de ([10.1.96.3]) by OLCA0072.ewenet.ewe.de with Microsoft SMTPSVC(6.0.3790.2499); Wed, 9 Apr 2008 10:26:33 +0200 MIME-Version: 1.0 Content-Type: multipart/signed; protocol="application/x-pkcs7-signature"; micalg=sha1; boundary="----F439FEDC23FA084281EC7880F017B061" Received: from OLCA0075.ewenet.ewe.de ([10.1.96.31]) by OLDA0047.ewenet.ewe.de with Microsoft SMTPSVC(6.0.3790.2499); Wed, 9 Apr 2008 10:26:33 +0200 Received: from OLCA0075 ([10.1.111.4]) by OLCA0075.ewenet.ewe.de with InterScan Messaging Security Suite; Wed, 09 Apr 2008 10:26:31 +0200 Received: from mail2.ewetel.de ([212.6.122.116]) by OLCA0075 (SonicWALL 6.0.1.9157) with ESMTP; Wed, 09 Apr 2008 10:26:31 +0200 Received: from bmr-trust.bmr-pdc.bmr.de (fw.maschinenringe.com [217.237.187.194]) by mail2.ewetel.de (8.12.1/8.12.9) with ESMTP id m398QU2e022814 for ; Wed, 9 Apr 2008 10:26:31 +0200 (CEST) Return-Path: X-CheckCompat: OK X-OriginalArrivalTime: 09 Apr 2008 08:26:33.0309 (UTC) FILETIME=[6B2EE8D0:01C89A1B] X-Mlf-Threat: nothreat X-Mlf-Threat-Detailed: nothreat;none;none;list_addrbk_sender X-Mlf-UniqueId: i200804090826310047017 Content-class: urn:content-classes:message Subject: CONTRL__9904144000002_9900496000005_20080409_141316.txt Date: Wed, 9 Apr 2008 10:24:17 +0200 Message-ID: <20080409102423$11@83589aa1> X-MS-Has-Attach: yes X-MS-TNEF-Correlator: Thread-Topic: CONTRL__9904144000002_9900496000005_20080409_141316.txt Thread-Index: AciaG2tUJ9bAYyY8TAeFf/Nmys4P7w== From: To: This is an S/MIME signed message ------F439FEDC23FA084281EC7880F017B061 Content-Type: multipart/mixed; boundary="------------=_NextPart_000_000_000" --------------=_NextPart_000_000_000 Content-Type: multipart/alternative; boundary="------alternative_boundary" --------alternative_boundary Content-Type: text/plain; charset=ISO-8859-1 Content-Transfer-Encoding: quoted-printable In Beantwortung Ihrer Datei 'CONTRL__9904144000002_9900496000005_20080409_= 141316.txt' lieferte der AKTIF-EDI-Service folgende Ergebnisse: --------------------------------------------------------------------------= -------- Dateiname gepackt verschl. Kommentar/Signaturdat= ei =3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D= =3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D= =3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D= =3D=3D=3D=3D=3D=3D=3D=3D CONTRL__9904144000002_9900496... not not --------------------------------------------------------------------------= -------- In response of your processed file 'CONTRL__9904144000002_9900496000005_20= 080409_141316.txt' the AKTIF-EDI-Service sent to you the following results: --------------------------------------------------------------------------= -------- filename compressed encrypted comment/sigfile =3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D= =3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D= =3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D= =3D=3D=3D=3D=3D=3D=3D=3D CONTRL__9904144000002_9900496... not not --------------------------------------------------------------------------= -------- -- autogenerated email by AKTIF EDI Service (aedic.sm). Please do not respond to this emailaddress. --------alternative_boundary Content-Type: text/html; charset=ISO-8859-1 Content-Transfer-Encoding: quoted-printable processed file AKTIF EDI-Service: Konvertierte Datei/converted file 'CONTRL__9= 904144000002_9900496000005_20080409_141316.txt'


    Datei
    fil= e
    Komprimierung
    com= pression
    Verschl=FCsselung
    enc= ryption
    Signaturdatei/Kommentar
    sig= naturefile/comment
    CONTRL__9904144000002_9900496000005_20080409_141316.txt keine/none keine/none  



    -- 
    autogenerated email by AKTIF-EDIService (aedic.sm). Please do not respond to this emailaddress.
    --------alternative_boundary-- --------------=_NextPart_000_000_000 Content-Type: application/octet-stream; name="CONTRL__9904144000002_9900496000005_20080409_141316.txt" Content-Transfer-Encoding: quoted-printable Content-Disposition: attachment; filename="CONTRL__9904144000002_9900496000005_20080409_141316.txt" UNA:+.? 'UNB+UNOC:3+9904144000002:500+9900496000005:500+080409:1024+141316'= UNH+129534+CONTRL:D:3:UN:1.3'UCI+90410000031762+9900496000005:500+990414400= 0002:500+8'UNT+3+129534'UNZ+1+141316' --------------=_NextPart_000_000_000-- ------F439FEDC23FA084281EC7880F017B061 Content-Type: application/x-pkcs7-signature; name="smime.p7s" Content-Transfer-Encoding: base64 Content-Disposition: attachment; filename="smime.p7s" MIIHSwYJKoZIhvcNAQcCoIIHPDCCBzgCAQExCzAJBgUrDgMCGgUAMAsGCSqGSIb3 DQEHAaCCBSswggUnMIIED6ADAgECAg59rQABAALWS8Z6CaQRPzANBgkqhkiG9w0B AQUFADB7MQswCQYDVQQGEwJERTEcMBoGA1UEChMTVEMgVHJ1c3RDZW50ZXIgR21i SDElMCMGA1UECxMcVEMgVHJ1c3RDZW50ZXIgQ2xhc3MgMyBMMSBDQTEnMCUGA1UE AxMeVEMgVHJ1c3RDZW50ZXIgQ2xhc3MgMyBMMSBDQSBWMB4XDTA4MDIwNDE0NDY1 MFoXDTExMDIwNDE0NDY1MFowgcoxCzAJBgNVBAYTAkRFMQ8wDQYDVQQIEwZCYXll cm4xHDAaBgNVBAcTE05ldWJ1cmcgYS4gZC4gRG9uYXUxKDAmBgNVBAoTH01hc2No aW5lbnJpbmdlIERldXRzY2hsYW5kIEdtYkgxFDASBgNVBAsTC0xhbmRlbmVyZ2ll MSUwIwYDVQQDExxMYW5kZW5lcmdpZSBUZWFtIENlcnRpZmljYXRlMSUwIwYJKoZI hvcNAQkBFhZFRElGQUNUQGxhbmRlbmVyZ2llLmRlMIGfMA0GCSqGSIb3DQEBAQUA A4GNADCBiQKBgQDIx6ipt3UiRoRiqxFNMdPGxfmV/8J/tTvdsYUbJiHPTeSXTjTN aqBJuGRLT+Lctq+DhLN+Y3ZRv2H/xelSFrjxM670e2jL4WjbnMZ/5LkptruZ+8qZ 1fGNrqBRVDr8QPXCC9bf+V+0AP9FkzYbuf/BRrPt9B2rvdwnieVpze1CXQIDAQAB o4IB2zCCAdcwgZUGCCsGAQUFBwEBBIGIMIGFMFAGCCsGAQUFBzAChkRodHRwOi8v d3d3LnRydXN0Y2VudGVyLmRlL2NlcnRzZXJ2aWNlcy9jYWNlcnRzL3RjX2NsYXNz M19MMV9DQV9WLmNydDAxBggrBgEFBQcwAYYlaHR0cDovL29jc3AuVi50Y2NsYXNz My50cnVzdGNlbnRlci5kZTAfBgNVHSMEGDAWgBTrZQCH1qACAaoa11MeclBuaJwb /jAMBgNVHRMBAf8EAjAAMEoGA1UdIARDMEEwPwYJKoIUACwBAQEDMDIwMAYIKwYB BQUHAgEWJGh0dHA6Ly93d3cudHJ1c3RjZW50ZXIuZGUvZ3VpZGVsaW5lczAOBgNV HQ8BAf8EBAMCBeAwHQYDVR0OBBYEFOXs++f6hPt293ZHilOZciZ8lPy1MEcGA1Ud HwRAMD4wPKA6oDiGNmh0dHA6Ly93d3cudHJ1c3RjZW50ZXIuZGUvY3JsL3YyL3Rj X2NsYXNzM19MMV9DQV9WLmNybDAnBgNVHSUEIDAeBggrBgEFBQcDAgYIKwYBBQUH AwQGCCsGAQUFBwMHMCEGA1UdEQQaMBiBFkVESUZBQ1RAbGFuZGVuZXJnaWUuZGUw DQYJKoZIhvcNAQEFBQADggEBAORAxacE5bh+9uDyf97ctXXuOOTchhyffARgMueo kNIPjwcM+czYLsUc6nkvkbvKJqU1cVt2jbcM/JL6W4nllAEtONyiSiFrJQWp4dQ8 paOAjerqXrkiPvARpfYTsHSuUFrFvzIk8lOyqGeur+tHhOG7PQOAdnlFKkZofGqt Wrhu605UsOBICgpkyjXQFEAK5rS7t7r8ddlfu+ijj9le1uzSFlnpljmARX2gfRR5 /E6J101HgNWX7VyS6XxCgod/AzXk+Z5WQwz0PTkpN1ccCXgN0LQzRCW+n4S8XqvQ y5P5AqUeWSbsD2YQffnsC+l1fwk/XrJhMkILal84qgluC3cxggHoMIIB5AIBATCB jTB7MQswCQYDVQQGEwJERTEcMBoGA1UEChMTVEMgVHJ1c3RDZW50ZXIgR21iSDEl MCMGA1UECxMcVEMgVHJ1c3RDZW50ZXIgQ2xhc3MgMyBMMSBDQTEnMCUGA1UEAxMe VEMgVHJ1c3RDZW50ZXIgQ2xhc3MgMyBMMSBDQSBWAg59rQABAALWS8Z6CaQRPzAJ BgUrDgMCGgUAoIGxMBgGCSqGSIb3DQEJAzELBgkqhkiG9w0BBwEwHAYJKoZIhvcN AQkFMQ8XDTA4MDQwOTA4MjgyOFowIwYJKoZIhvcNAQkEMRYEFM8H2qjq/duh/IHZ nha4pDA3Qi3KMFIGCSqGSIb3DQEJDzFFMEMwCgYIKoZIhvcNAwcwDgYIKoZIhvcN AwICAgCAMA0GCCqGSIb3DQMCAgFAMAcGBSsOAwIHMA0GCCqGSIb3DQMCAgEoMA0G CSqGSIb3DQEBAQUABIGANd6GNxqQcegeoN6+CTV5SyfE7aD8k00uiUV6zPFlwM3p 2bbIPthbCsAHyRx/sUngRlP2XfMuPR+vc8/ACbhGWdKQqhQDFHQgbZALiLhyHJrp kMNr5ZWzKce1iM15GhsKUViiuTBhhK2LQolwB9gnKkBMwbF9bLPuMXNvallydtM= ------F439FEDC23FA084281EC7880F017B061-- bouncycastle-1.49.orig/test/data/org/bouncycastle/mail/smime/test/validator.noEmail.eml0000644000175000017500000000602310503212005030652 0ustar ebourgebourgFrom: "Armin Häberling" To: testmail@bouncycastle.org Message-ID: <4815156.11156777376176.JavaMail.armin@lappi> Subject: Validator Test NoEmail MIME-Version: 1.0 Content-Type: multipart/signed; protocol="application/pkcs7-signature"; micalg=sha1; boundary="----=_Part_0_30549415.1156777376134" ------=_Part_0_30549415.1156777376134 Content-Type: text/plain; charset=us-ascii Content-Transfer-Encoding: 7bit This is a Test Mail! ------=_Part_0_30549415.1156777376134 Content-Type: application/pkcs7-signature; name=smime.p7s; smime-type=signed-data Content-Transfer-Encoding: base64 Content-Disposition: attachment; filename="smime.p7s" Content-Description: S/MIME Cryptographic Signature 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 uakjejzgUAAAAAAAAA== ------=_Part_0_30549415.1156777376134-- bouncycastle-1.49.orig/test/data/org/bouncycastle/mail/smime/test/validator.notYetValid.eml0000644000175000017500000000612010503212005031526 0ustar ebourgebourgFrom: "Armin Häberling" To: testmail@bouncycastle.org Message-ID: <27789929.11156777441202.JavaMail.armin@lappi> Subject: Validator Test NotYetValid MIME-Version: 1.0 Content-Type: multipart/signed; protocol="application/pkcs7-signature"; micalg=sha1; boundary="----=_Part_0_10440721.1156777441165" ------=_Part_0_10440721.1156777441165 Content-Type: text/plain; charset=us-ascii Content-Transfer-Encoding: 7bit This is a Test Mail! ------=_Part_0_10440721.1156777441165 Content-Type: application/pkcs7-signature; name=smime.p7s; smime-type=signed-data Content-Transfer-Encoding: base64 Content-Disposition: attachment; filename="smime.p7s" Content-Description: S/MIME Cryptographic Signature MIAGCSqGSIb3DQEHAqCAMIACAQExCzAJBgUrDgMCGgUAMIAGCSqGSIb3DQEHAQAAoIIFNDCCAoAw ggHpoAMCAQICAQEwDQYJKoZIhvcNAQEFBQAwNDELMAkGA1UEBhMCQ0gxJTAjBgNVBAMTHFNpZ25l ZE1haWxWYWxpZGF0b3JUZXN0IFJvb3QwHhcNMDYwODI2MTI1NzUyWhcNMTYwODIzMTI1NzUyWjA0 MQswCQYDVQQGEwJDSDElMCMGA1UEAxMcU2lnbmVkTWFpbFZhbGlkYXRvclRlc3QgUm9vdDCBnzAN BgkqhkiG9w0BAQEFAAOBjQAwgYkCgYEA4s2LugTz/byjUAsZAGe0T1U3GTYzYckXSn2N75agogy3 eqWD7DC3CdiaCYj1qkogZXTiGlyziBa3oYqhy9wN9bFSobLlOJlNFvl2hdBS769nMfvCdoNWNc5R 8qI4BZBFJgm2OtnlQC8r0Kc2iUFqx/HSoN4svXfkYEIjXR5cJhcCAwEAAaOBoTCBnjAPBgNVHRMB Af8EBTADAQH/MB0GA1UdDgQWBBQ6maBDgpnIH6sSFWsCM6w1aLo+ljBcBgNVHSMEVTBTgBQ6maBD gpnIH6sSFWsCM6w1aLo+lqE4pDYwNDELMAkGA1UEBhMCQ0gxJTAjBgNVBAMTHFNpZ25lZE1haWxW YWxpZGF0b3JUZXN0IFJvb3SCAQEwDgYDVR0PAQH/BAQDAgEGMA0GCSqGSIb3DQEBBQUAA4GBAFcv F59aBSc8Hmxgtd05PdiOpHTEUaaQ8LdK9jdOBDtoHozNwHXoQLQZJN55Nowvori5s7yt25fjvB6h 5flkdnisqEU01I4+L/cySWPQQJFWOc+4D/BgfLGQUKK4Zenm3ky6UrywtXDvB7Af5CzZopf13i2k d6l1vZ/mXGe9/easMIICrDCCAhWgAwIBAgIBDTANBgkqhkiG9w0BAQQFADA0MQswCQYDVQQGEwJD SDElMCMGA1UEAxMcU2lnbmVkTWFpbFZhbGlkYXRvclRlc3QgUm9vdDAeFw0wNjEyMjgxNDE5MzFa Fw0wNzEyMjgxNDE5MzFaMGMxCzAJBgNVBAYTAkNIMSYwJAYJKoZIhvcNAQkBFhdhcm1pbmhhQHN0 dWRlbnQuZXRoei5jaDEsMCoGA1UEAxMjU2lnbmVkTWFpbFZhbGlkYXRvclRlc3QgTm90WWV0VmFs aWQwgZ8wDQYJKoZIhvcNAQEBBQADgY0AMIGJAoGBAN4ESUKZllIFOH0/QbYzQEYzVP5er6v+UynN IcICWjNWoTpyZYPz3OBf/dcFsYpiId010dvmlKUz/+73ePu0Azs/f/i3EYAfCOZq6I3S0kHTKlDf cdYkyOC0G+3+K2mtPesnhUtY15CRC863aRAzOkfUwx3JY7r1eiRGoTxAmQ81AgMBAAGjgZ4wgZsw DAYDVR0TAQH/BAIwADAdBgNVHQ4EFgQUDrU8oJTrV0Gngioz349nweBkSREwXAYDVR0jBFUwU4AU OpmgQ4KZyB+rEhVrAjOsNWi6PpahOKQ2MDQxCzAJBgNVBAYTAkNIMSUwIwYDVQQDExxTaWduZWRN YWlsVmFsaWRhdG9yVGVzdCBSb290ggEBMA4GA1UdDwEB/wQEAwIHgDANBgkqhkiG9w0BAQQFAAOB gQCK3JrnWfdgFD4QivLyk70X7n2ZUQ7nJ8MNLHyG/Oo5EY91MyuIV8T+D2nLID0O32OfoSU7/Krt 1rkTmYILOCE1a2w1j6ahjhN3RbIqKIU3mR1Ru/FdeCXZ/JbduMY571QeSmAW2kPZVfl5CWvqrfi7 eFdO2zN1jqgRK/1PLUF4+TGCAXUwggFxAgEBMDkwNDELMAkGA1UEBhMCQ0gxJTAjBgNVBAMTHFNp Z25lZE1haWxWYWxpZGF0b3JUZXN0IFJvb3QCAQ0wCQYFKw4DAhoFAKCBkzAYBgkqhkiG9w0BCQMx CwYJKoZIhvcNAQcBMBwGCSqGSIb3DQEJBTEPFw0wNjA4MjgxNTA0MDFaMCMGCSqGSIb3DQEJBDEW BBTnzDDJJYvkUebVJIdBB7ziFjdxbTA0BgkqhkiG9w0BCQ8xJzAlMAoGCCqGSIb3DQMHMA4GCCqG SIb3DQMCAgIAgDAHBgUrDgMCBzANBgkqhkiG9w0BAQEFAASBgKi/iQYZRy9dL+3UNfif/Nvj3QfX TEJU0KCr5d6gylgwwSsjIXIndrDw53kpxyerKymd5niKNC1+tzfKL/F/YarNMjClq1XmUSKDk36W nqCJ6QjEvG70i5rKH2uADgsLR6+h8v9YxMhL+b+eZTvch7RsYAuxJISxixuo6e88ffv/AAAAAAAA ------=_Part_0_10440721.1156777441165-- bouncycastle-1.49.orig/test/data/org/bouncycastle/mail/smime/test/certpath_inter2.crt0000644000175000017500000000211310621263376030430 0ustar ebourgebourg-----BEGIN CERTIFICATE----- MIIC/TCCAmagAwIBAgIBAzANBgkqhkiG9w0BAQUFADBdMRswGQYDVQQDExJDcmVh dGVDZXJ0UGF0aFJvb3QxCzAJBgNVBAYTAkNIMQ8wDQYDVQQHEwZadXJpY2gxIDAe BgNVBAoTF1NpZ25lZE1haWxWYWxpZGF0b3JUZXN0MB4XDTA3MDUwOTEyMTkzOVoX DTI3MDUwNDEyMTYxN1owXjEcMBoGA1UEAxMTQ3JlYXRlQ2VydFBhdGhJbnRlcjEL MAkGA1UEBhMCQ0gxDzANBgNVBAcTBlp1cmljaDEgMB4GA1UEChMXU2lnbmVkTWFp bFZhbGlkYXRvclRlc3QwgZ8wDQYJKoZIhvcNAQEBBQADgY0AMIGJAoGBAJnJs3kA HttsQSJA9gxe0og85sX469Vq0xY9gfEBrp0EGUH50HSLVNHRhZnXlibcya7/XWwV pESg+HTc/XhOQtwGn68eJ/K1ka7JqeFnN3VzwduqNignnc6WEXndrZIPLP+7a7VZ zWoWxa+C2mwjFHHza3WZmP7d6fbu+DFsXsA1AgMBAAGjgcswgcgwDwYDVR0TAQH/ BAUwAwEB/zAdBgNVHQ4EFgQUT80cD5r01h/r6kQ3AnOOfp5LMlQwgYUGA1UdIwR+ MHyAFCQH6UCakD8+qWKy8yY61DMSABfdoWGkXzBdMRswGQYDVQQDExJDcmVhdGVD ZXJ0UGF0aFJvb3QxCzAJBgNVBAYTAkNIMQ8wDQYDVQQHEwZadXJpY2gxIDAeBgNV BAoTF1NpZ25lZE1haWxWYWxpZGF0b3JUZXN0ggEBMA4GA1UdDwEB/wQEAwIBBjAN BgkqhkiG9w0BAQUFAAOBgQAZBu5xl7ZhMJkMmwXH3Tm8XCqllzXXW0GyZ8jfuMLT msnmC9aPnz6NjH6FVHnM9SA+twsx1gaTfbq6zKSTN03lV31ltG1qa5SUuOvOggdR qM15JwzRaGgGGuIc3pswid5tUpKv0koVMNmvIrL3G3pvfOggYjhLAhOuf9WC8AX6 4w== -----END CERTIFICATE----- bouncycastle-1.49.orig/test/data/org/bouncycastle/mail/smime/test/certpath_end2.crt0000644000175000017500000000207210621263376030061 0ustar ebourgebourg-----BEGIN CERTIFICATE----- MIIC8jCCAlugAwIBAgIBBDANBgkqhkiG9w0BAQUFADBeMRwwGgYDVQQDExNDcmVh dGVDZXJ0UGF0aEludGVyMQswCQYDVQQGEwJDSDEPMA0GA1UEBxMGWnVyaWNoMSAw HgYDVQQKExdTaWduZWRNYWlsVmFsaWRhdG9yVGVzdDAeFw0wNzA1MDkxMjI2Mjda Fw0yNzA1MDQxMjE2MTdaMFsxGTAXBgNVBAMTEENlcnRQYXRoVGVzdEVuZDIxCzAJ BgNVBAYTAkNIMQ8wDQYDVQQHEwZadXJpY2gxIDAeBgNVBAoTF1NpZ25lZE1haWxW YWxpZGF0b3JUZXN0MIGfMA0GCSqGSIb3DQEBAQUAA4GNADCBiQKBgQDQdNwZUoe/ 12YNmNDZdtNA1CVw2hAAqLAfiGWFITigAFGVt09Ex7m/HOvhw9/ogUpC5/0k0skC MqhjSAJ50hypTV3zo+N6Mzq3ZFhvMHGp06T9HlbbFnGENOH3W6cDPbLnIwoIP7sI JNyEGlo8JP7OROamxvGvhJJuk/IUcPXFIwIDAQABo4HCMIG/MAkGA1UdEwQCMAAw HQYDVR0OBBYEFFfOzh3DrqqTiNSFSE5lKqylwWNKMIGFBgNVHSMEfjB8gBRPzRwP mvTWH+vqRDcCc45+nksyVKFhpF8wXTEbMBkGA1UEAxMSQ3JlYXRlQ2VydFBhdGhS b290MQswCQYDVQQGEwJDSDEPMA0GA1UEBxMGWnVyaWNoMSAwHgYDVQQKExdTaWdu ZWRNYWlsVmFsaWRhdG9yVGVzdIIBAzALBgNVHQ8EBAMCBLAwDQYJKoZIhvcNAQEF BQADgYEAk7VP0T1EfmHfUeQLbkr4KpbM+6mqtwuMZkDeoamJ35RkCsHM6rGiXpgS OVHayJTYgOOHoxDgNIwD+nelHdL/4EFp+Mctpubbhgp3ZZEJ1gGmc8mQ2jmp1XP6 XY6yRAm914AOVAcceeZ3D+a8ViG808EbZHehhlirbBWxkI6FApo= -----END CERTIFICATE----- bouncycastle-1.49.orig/test/data/org/bouncycastle/mail/smime/test/test128.message0000644000175000017500000000260012051700003027360 0ustar ebourgebourgContent-Type: application/pkcs7-mime; name="smime.p7m"; smime-type=enveloped-data Content-Transfer-Encoding: base64 Content-Disposition: attachment; filename="smime.p7m" Content-Description: S/MIME Encrypted Message MIAGCSqGSIb3DQEHA6CAMIACAQAxggFOMIIBSgIBADCBsjCBrDELMAkGA1UEBhMCQVQxEDAOBgNV BAgTB0F1c3RyaWExDzANBgNVBAcTBlZpZW5uYTEaMBgGA1UEChMRVGlhbmkgU3Bpcml0IEdtYkgx GTAXBgNVBAsTEERlbW8gRW52aXJvbm1lbnQxEDAOBgNVBAMTB1Rlc3QgQ0ExMTAvBgkqhkiG9w0B CQEWIm1hc3NpbWlsaWFuby5tYXNpQHRpYW5pLXNwaXJpdC5jb20CAQkwDQYJKoZIhvcNAQEBBQAE gYCsQAqbQQiRBnvrva4gJGG4ES/9EzpSxTNdM2RRT9XnE+efUCO8e6dyyRWbBZo9UCFr7ZV8/uCm GTCX1ZGvsdP1nDHOnPKxDWasl6bzu0DtcXp5gYsxp9tXMmEh0pISSaeWctjjd7cz60vjsHg7y2j5 bArDfqBtnu4sJLbw/+C+hjCABgkqhkiG9w0BBwEwHQYJYIZIAWUDBAECBBDJDeXO+Imz/4Ejw8dC u7e0oIAEggHABb6EdlbZjFEQmw2Gc4k3uAvljBZX3munp4KE316Whb/thgJ014ntD5vGEZl5r2hD byvlrvDVQPAlq7s5K78KyGxzfcbzw3CK44TgH9Lmnf8cnWnaim6pspy9YbnnG4r1RW6LSqMFIMbO jrPuK0EKBaD5nuw1bFPo348841cltUqS/Tj3XpN9Cu5S2l7REcWWi7KP8qCOBlW/3D3WuW4TdOBg p3gL8qbpbinThexnaCaEdipjfA1dDplxTxJND9KS9WHRzWzrAW0l7iJ4MWfVluCqUOQodOz22jrw 2OA462NjZv92/vJ6MZYlFhYZrRdD6qyM6cLMK3AbOuCbxJSQ8E+A0xbgDjDg86viOSvzVuoLC0R4 C3IABR8EuHhz+1zBiFMYDIBNUqB7xXdROCo15LKSQqcPwvIjmcCxD86RxpR0xh2hnDC1Yf28th4W 9yzZ0xOm1z+yhkztAqkPlXewI5t5hFwULGsLHyZdCmjwL8ehuszkzFxubrbJzmF/kUhQD7ZyZSIZ KvqfL/jcchyMMxNaGervpQEyzDZMiR21CJpZvFMTsQJwfVifskJlw2JRwgeWfeoSJYOzm0O8OrR0 bQAAAAAAAAAAAAA=bouncycastle-1.49.orig/test/data/org/bouncycastle/mail/smime/test/qp-soft-break.eml0000644000175000017500000001505610647050322027776 0ustar ebourgebourgFrom: Subject: test quoted-printable soft breaks X-MimeOLE: Produced By Microsoft MimeOLE V6.00.2800.1896 MIME-Version: 1.0 Content-Type: multipart/signed; micalg=sha1; protocol="application/x-pkcs7-signature"; boundary="{EAD5F12C-E5A7-421A-AD27-CF4EF58E43B5}" Date: Tue, 17 Jul 2007 11:27:34 +1000 Message-Id: <1184635654.3066.1074.camel@anteater.myretsu.com> This is a multi-part message in MIME format. --{EAD5F12C-E5A7-421A-AD27-CF4EF58E43B5} Content-Type: text/plain; format=flowed; charset="iso-8859-1"; reply-type=response Content-Transfer-Encoding: quoted-printable test = 123456 = --{EAD5F12C-E5A7-421A-AD27-CF4EF58E43B5} Content-Type: application/x-pkcs7-signature; name="smime.p7s" Content-Transfer-Encoding: base64 Content-Disposition: attachment; filename="smime.p7s" MIIQ5AYJKoZIhvcNAQcCoIIQ1TCCENECAQExCzAJBgUrDgMCGgUAMAsGCSqGSIb3DQEHAaCCDrQw ggQ2MIIDHqADAgECAgEBMA0GCSqGSIb3DQEBBQUAMG8xCzAJBgNVBAYTAlNFMRQwEgYDVQQKEwtB ZGRUcnVzdCBBQjEmMCQGA1UECxMdQWRkVHJ1c3QgRXh0ZXJuYWwgVFRQIE5ldHdvcmsxIjAgBgNV BAMTGUFkZFRydXN0IEV4dGVybmFsIENBIFJvb3QwHhcNMDAwNTMwMTA0ODM4WhcNMjAwNTMwMTA0 ODM4WjBvMQswCQYDVQQGEwJTRTEUMBIGA1UEChMLQWRkVHJ1c3QgQUIxJjAkBgNVBAsTHUFkZFRy dXN0IEV4dGVybmFsIFRUUCBOZXR3b3JrMSIwIAYDVQQDExlBZGRUcnVzdCBFeHRlcm5hbCBDQSBS b290MIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEAt/caM+byAAQtOeBOW+0fvGwPzbX6 I7bO3psRM5ekKUx9k5+9SryT7QMa44/P5W1QWtaXKZRagLBJetsulf24yr83OC0ePpFBrXBWx/BP P+gynnTKyJBU6cZfD3idmkA8Dqxhql4Uj56HoWpQ3NeaTq8Fs6ZxlJxxs1BgCscTnTgHhgKo6ahp JhiQq0ywTyOrOk+E2N/On+Fpb7vXQtdrROTHre5tQV9yWnEIN7N5ZaRZoJQ39wAvDcKSctrQOHLb FKhFxF0qfbe01sTurM0TRLfJK91DACX6YblpalgjEbenM49WdVn1zSnXRrcKK2W200JvFbK4e/vv 6V1T1TRaJwIDAQABo4HcMIHZMB0GA1UdDgQWBBStvZh6NLQm9/rEJlTvA73gJMtUGjALBgNVHQ8E BAMCAQYwDwYDVR0TAQH/BAUwAwEB/zCBmQYDVR0jBIGRMIGOgBStvZh6NLQm9/rEJlTvA73gJMtU GqFzpHEwbzELMAkGA1UEBhMCU0UxFDASBgNVBAoTC0FkZFRydXN0IEFCMSYwJAYDVQQLEx1BZGRU cnVzdCBFeHRlcm5hbCBUVFAgTmV0d29yazEiMCAGA1UEAxMZQWRkVHJ1c3QgRXh0ZXJuYWwgQ0Eg Um9vdIIBATANBgkqhkiG9w0BAQUFAAOCAQEAsJvghSXC1iPiD5YGkp1BmJzZhHmB2R5bFAcjNmWP sNh3u6xBbEdgg1Gw+TI95/z2JhPHgBalv1r8h894eYkhmuJMBwqGNbzy3lHE0pa33H5O7nD9HDnr DAJRFC2OvRbgwd9Gdeckrez0QrSFk3AQZ7qdBjVKGNMresxRQqF6Y9Hmu6HFK8I2vhMN5r1jfnl7 pwkNQKtq3Y+Kw/b2jBpCBVHURfWfp2IhaBUgQzyZ53y9JNipkRdziD9WGzE4GLRxD5rNyA6eji4b 4YyYg8sfMfFETMYEc0l2YA/H+L0XgGsu6cxMDlqaeQ8gCi7VnmMmHlWSlNiCF1p70LzHj06GBDCC BIowggNyoAMCAQICECf06hH0eobEbp27bqkXBwcwDQYJKoZIhvcNAQEFBQAwbzELMAkGA1UEBhMC U0UxFDASBgNVBAoTC0FkZFRydXN0IEFCMSYwJAYDVQQLEx1BZGRUcnVzdCBFeHRlcm5hbCBUVFAg TmV0d29yazEiMCAGA1UEAxMZQWRkVHJ1c3QgRXh0ZXJuYWwgQ0EgUm9vdDAeFw0wNTA2MDcwODA5 MTBaFw0yMDA1MzAxMDQ4MzhaMIGuMQswCQYDVQQGEwJVUzELMAkGA1UECBMCVVQxFzAVBgNVBAcT DlNhbHQgTGFrZSBDaXR5MR4wHAYDVQQKExVUaGUgVVNFUlRSVVNUIE5ldHdvcmsxITAfBgNVBAsT GGh0dHA6Ly93d3cudXNlcnRydXN0LmNvbTE2MDQGA1UEAxMtVVROLVVTRVJGaXJzdC1DbGllbnQg QXV0aGVudGljYXRpb24gYW5kIEVtYWlsMIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEA sjmFpPJ9q0E7YkY3rs3BYHW8OWX5ShpHornMSMxqmNVNNRm5pELlzkniii8efNIxB8dOtINknS4p 1aJkxIW9hVE1eaROaJB7HHqkkqgX8pgV8pPMyaQylbsMTzC9mKALi+VuG6JG+ni8om+rWV6lL8/K 2m2qL+usobNqqrcuZzWLeeEeaYji5kbNoKXqvgvOdjp6Dpvq/NonWz1zHyLmSGHGTPNpsaguG7bU MSAsvIKKjqQOpdeJQ/wWWq8dcdcRWdq6hw2v+vPhwvCkxWeM1tZUOt4KpLoDd7NlyP0e03RiqhjK aJMeoYV+9Udly/hNVyh00jT/MLbu9mIwFIws6wIDAQABo4HhMIHeMB8GA1UdIwQYMBaAFK29mHo0 tCb3+sQmVO8DveAky1QaMB0GA1UdDgQWBBSJgmd9xJ0mcABLtFBIfN49rgRufTAOBgNVHQ8BAf8E BAMCAQYwDwYDVR0TAQH/BAUwAwEB/zB7BgNVHR8EdDByMDigNqA0hjJodHRwOi8vY3JsLmNvbW9k b2NhLmNvbS9BZGRUcnVzdEV4dGVybmFsQ0FSb290LmNybDA2oDSgMoYwaHR0cDovL2NybC5jb21v ZG8ubmV0L0FkZFRydXN0RXh0ZXJuYWxDQVJvb3QuY3JsMA0GCSqGSIb3DQEBBQUAA4IBAQAZ2IkR byispgCi54fBm5AD236hEv0e8+LwAamUVEJrmgnEoG3XkJIEA2Z5Q3H8+G+v23ZF4jcaPd3kWQR4 rBz0g0bzes9bhHIt5UbBuhgRKfPLSXmHPLptBZ2kbWhPrXIUNqi5sf2/z3/wpGqUNVCPz4FtVbHd WTBK322gnGQfSXzvNrv042n0+DmPWq1LhTq3Du3Tzw1EovsEv+QvcI4l+1pUBrPQxLxtjftzMizp m4QkLdZ/kXpoAlAfDj9N6cz1u2fo3BwuO/xOzf4CjuOoEwqlJkRl6RDyTVKnrtw+ymsyXEFs/vVd oOr/0fqbhlhtPZZH5f4ulQTCAMyOofK7MIIF6DCCBNCgAwIBAgIQCePao6/G/NvD/FZe/9X+gzAN BgkqhkiG9w0BAQUFADCBrjELMAkGA1UEBhMCVVMxCzAJBgNVBAgTAlVUMRcwFQYDVQQHEw5TYWx0 IExha2UgQ2l0eTEeMBwGA1UEChMVVGhlIFVTRVJUUlVTVCBOZXR3b3JrMSEwHwYDVQQLExhodHRw Oi8vd3d3LnVzZXJ0cnVzdC5jb20xNjA0BgNVBAMTLVVUTi1VU0VSRmlyc3QtQ2xpZW50IEF1dGhl bnRpY2F0aW9uIGFuZCBFbWFpbDAeFw0wNjEwMTcwMDAwMDBaFw0wNzEwMTcyMzU5NTlaMIIBAzEL MAkGA1UEBhMCTkwxEDAOBgNVBBETBzEwMTggTVIxCzAJBgNVBAgTAm5hMRIwEAYDVQQHEwlBbXN0 ZXJkYW0xIzAhBgNVBAkTGk9vc3RlbmJ1cmdlcnZvb3JzdHJhYXQgMTMyMQ8wDQYDVQQKEwZJemVj b20xLDAqBgNVBAsTI0lzc3VlZCB0aHJvdWdoIEl6ZWNvbSBFLVBLSSBNYW5hZ2VyMR8wHQYDVQQL ExZDb3Jwb3JhdGUgU2VjdXJlIEVtYWlsMRkwFwYDVQQDExBNYXJ0aWpuIEJyaW5rZXJzMSEwHwYJ KoZIhvcNAQkBFhJtYXJ0aWpuQGl6ZWNvbS5jb20wgZ8wDQYJKoZIhvcNAQEBBQADgY0AMIGJAoGB AMNSdYvS0y7TTNCcQE3MZc7moOI7Yxj7e3Gu8cIG3nA1OdxtiqLo0ZwypaUu+93dybPs/8GipAtm 9gAlGnzr1I00OKgzEcYWTaPI9XQZLojOiKQAHJPwoQc9kLqk+pOzJF01oUumCmLL4wFdTMOBxtfU bEZwk+VOUm7qp99TdWDjAgMBAAGjggIsMIICKDAfBgNVHSMEGDAWgBSJgmd9xJ0mcABLtFBIfN49 rgRufTAdBgNVHQ4EFgQUJ565V+w9ohuzMvp9gj/B5KU97PAwDgYDVR0PAQH/BAQDAgWgMAwGA1Ud EwEB/wQCMAAwHQYDVR0lBBYwFAYIKwYBBQUHAwQGCCsGAQUFBwMCMBEGCWCGSAGG+EIBAQQEAwIF oDBGBgNVHSAEPzA9MDsGDCsGAQQBsjEBAgEDBTArMCkGCCsGAQUFBwIBFh1odHRwczovL3NlY3Vy ZS5jb21vZG8ubmV0L0NQUzCBpQYDVR0fBIGdMIGaMEygSqBIhkZodHRwOi8vY3JsLmNvbW9kb2Nh LmNvbS9VVE4tVVNFUkZpcnN0LUNsaWVudEF1dGhlbnRpY2F0aW9uYW5kRW1haWwuY3JsMEqgSKBG hkRodHRwOi8vY3JsLmNvbW9kby5uZXQvVVROLVVTRVJGaXJzdC1DbGllbnRBdXRoZW50aWNhdGlv bmFuZEVtYWlsLmNybDCBhgYIKwYBBQUHAQEEejB4MDsGCCsGAQUFBzAChi9odHRwOi8vY3J0LmNv bW9kb2NhLmNvbS9VVE5BZGRUcnVzdENsaWVudENBLmNydDA5BggrBgEFBQcwAoYtaHR0cDovL2Ny dC5jb21vZG8ubmV0L1VUTkFkZFRydXN0Q2xpZW50Q0EuY3J0MB0GA1UdEQQWMBSBEm1hcnRpam5A aXplY29tLmNvbTANBgkqhkiG9w0BAQUFAAOCAQEAQ/SWmflyk4BRnuupDmUizFYMgQ1CG+xjjmvl 5Vfm28mEq9bn6AK6SQ0uwlhzCgeJse1rrN9EtSdAxPMg5tfYl9l6RtP4eFcG+mm29VHW4nA7fR2a e2/x6vD4mQ7iOZoFK+7dH1TqYdLiMGp/ixf2BbKSFsAf/fkjcWSNCc9Yn1FDpHyQpJWCIKDV46Ft 777xaitXSAXzzrHr/5Bd8GIigefj4eZAFfb0AHToo1AxZLTmM7S/7f534dqZcMuMqte/L84MGK1+ eX2NuXplpeGRWqDR+ZPH3rVLsC6yYwQk+mhL2jS9T0/hp0CNUdG1BnaBq4AY9+X8AYW4HfibjxA6 NjGCAfgwggH0AgEBMIHDMIGuMQswCQYDVQQGEwJVUzELMAkGA1UECBMCVVQxFzAVBgNVBAcTDlNh bHQgTGFrZSBDaXR5MR4wHAYDVQQKExVUaGUgVVNFUlRSVVNUIE5ldHdvcmsxITAfBgNVBAsTGGh0 dHA6Ly93d3cudXNlcnRydXN0LmNvbTE2MDQGA1UEAxMtVVROLVVTRVJGaXJzdC1DbGllbnQgQXV0 aGVudGljYXRpb24gYW5kIEVtYWlsAhAJ49qjr8b828P8Vl7/1f6DMAkGBSsOAwIaBQCggYswGAYJ KoZIhvcNAQkDMQsGCSqGSIb3DQEHATAcBgkqhkiG9w0BCQUxDxcNMDcwNzA2MTAzNTI1WjAjBgkq hkiG9w0BCQQxFgQUSct8Yv8Xs0hDZI1xnTnGFmP3pZQwLAYJKoZIhvcNAQkPMR8wHTAPBggqhkiG 9w0DAjADAgE6MAoGCCqGSIb3DQMHMA0GCSqGSIb3DQEBAQUABIGAF49uqfoqWpTzvQSQPZu799YI dqP+K/GiV6OSIz+YasWzmwszu6tzromuvu+8UYvGfcLfvkZKfP+8sIIJOIxvaCrmTfVMnt9RY+SJ +eLqRl7dHpMvK/DWaaXgBF5kyZz1IQMeL/7hQ79VDD59wJdlHFz197AQDmYYYik1BumyJdI= --{EAD5F12C-E5A7-421A-AD27-CF4EF58E43B5}--bouncycastle-1.49.orig/test/data/org/bouncycastle/mail/smime/test/outlook_2010_beta_sime_msg.eml0000644000175000017500000000225111473053170032332 0ustar ebourgebourgTo: Subject: A broken S/MIME encrypted message Message-ID: <000c01cadd1e$d8e3b700$8aab2500$@Domain> MIME-Version: 1.0 Content-Type: application/pkcs7-mime; smime-type=enveloped-data; name="smime.p7m" Content-Transfer-Encoding: base64 Content-Disposition: attachment; filename="smime.p7m" X-Mailer: Microsoft Outlook 14.0 Content-Language: de-ch Thread-Index: AQFr/6ANUmscMMg1FM+V1UOpE+aAWw== X-OlkEid: 6BA45F2275AB6A6FE4DFFB4B935BAE4D26E31DCF MIAGCSqGSIb3DQEHA6CAMIACAQIxggEwMIIBLAIBAoAUIhnlBNV1CzfSDMkwsUEp4aLlg7EwDQYJ KoZIhvcNAQEBBQAEggEAn/Bn8zPfBT1xi5ECKKN43RnEnWZt/cDSfmCkyhX/6lI8VNlnJQhdWonN 2H6TCKB4YEWZ1Lyr6NrE7kxjW8w1F5AxYnlpY66soBbQib1a3bdmu7Oz8JxEqVlfmDpM7n2yGQPQ e9PP8j3UGyC7AtprwERkpuTBetH2FYfwM3uRgypLCRDsKYiy8QOna6Ii+3+lphCCn3SOo/Gmcv+7 lh2W1w4MkX1zdWR5SuCt3tBZlz5VkMngB/Uzo9EE3zDWxqvzEHqvME57hc+GPht+4OZ7kQKOiGV8 2kK9o+KkSy69IT/3kpspoSdv2T0drsWtHv3MlybdU9RGj2Lycx16xtSnhTCABgkqhkiG9w0BBwEw FAYIKoZIhvcNAwcECPd/Rxmju5lYoIAEgYjp+9tsQvSJJqpmZIWdheOfOWc7JH3yyaiVk8JG2pmc Brrqpsufu0U61JYVkc6K6UtwCwaN8frbNkuDZgp7uIHYgwxdFB5n5HQC0rS7X+pc5/UQ64ymi02O 8J6ARYi9+VkvWOOjpOBwMoN6oTrqHmW7Tl1ES7mqaK8ICFY3TvxAD38gmX0CIM3+AAAAAAAAAAAA AA== bouncycastle-1.49.orig/test/data/org/bouncycastle/mail/smime/test/circular.eml0000644000175000017500000001417210604407432027126 0ustar ebourgebourgDate: Tue, 03 Apr 2007 09:02:23 +0200 From: =?ISO-8859-1?Q?Armin_H=E4berling?= MIME-Version: 1.0 To: armin@privasphere.com Subject: circular ref Content-Type: multipart/signed; protocol="application/x-pkcs7-signature"; micalg=sha1; boundary="----223806D65A40B3FD04B0923E0F2BE258" This is an S/MIME signed message ------223806D65A40B3FD04B0923E0F2BE258 Content-Type: text/plain hello world ------223806D65A40B3FD04B0923E0F2BE258 Content-Type: application/x-pkcs7-signature; name="smime.p7s" Content-Transfer-Encoding: base64 Content-Disposition: attachment; filename="smime.p7s" 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 ggHuMIIB6gIBATCBkzCBjTEPMA0GA1UEAxMGSW50ZXIzMQswCQYDVQQGEwJDSDEP MA0GA1UEBxMGWnVyaWNoMQswCQYDVQQIEwJaSDEXMBUGA1UEChMOUHJpdmFzcGhl cmUgQUcxEDAOBgNVBAsTB1Rlc3RpbmcxJDAiBgkqhkiG9w0BCQEWFWFybWluQHBy aXZhc3BoZXJlLmNvbQIBBTAJBgUrDgMCGgUAoIGxMBgGCSqGSIb3DQEJAzELBgkq hkiG9w0BBwEwHAYJKoZIhvcNAQkFMQ8XDTA3MDQwMzA2NTYyNlowIwYJKoZIhvcN AQkEMRYEFKeO/7XYkuP8qqcwdpUZxDQkXVATMFIGCSqGSIb3DQEJDzFFMEMwCgYI KoZIhvcNAwcwDgYIKoZIhvcNAwICAgCAMA0GCCqGSIb3DQMCAgFAMAcGBSsOAwIH MA0GCCqGSIb3DQMCAgEoMA0GCSqGSIb3DQEBAQUABIGAlgTquUTDfwxT0Bt/+KRh mYkGyQX3WRHjGeIfBD82FsvZF0VLG8OGs+k8vA5BLs4jsZTqGvFsjbDc4m1tiRRS VYnrj8oQ+D3g/Jzpv9CHMpLstTk5ZT/UCnI9grAEaKQfrGbnDPsxhOtAQMFfyb3t r5NuLyMnmvuwC+pYhkweiYY= ------223806D65A40B3FD04B0923E0F2BE258-- bouncycastle-1.49.orig/test/data/org/bouncycastle/mail/smime/test/johndoe.p120000644000175000017500000000452611473053176026606 0ustar ebourgebourg0‚ R0‚  *†H†÷  ‚ ‚ 0‚ 0‚— *†H†÷  ‚ˆ0‚„0‚} *†H†÷ 0 *†H†÷  0±F6kÝ€‚Pœz…||T«Úü–x5ƒ~}k¹”íò/ˆî×6 í}Ã…Ac§ê‚ÍøØ l>¼¾ÞaY šƒÉTá‰ÇÍføe`™0ä}8Þ ß Žt‡—|/xö ˜øS“"ä\Cm–aœ.³ï^Œz§2’eéE9ÞÔÆ¾Œ¢à²ïÂJ¤Aêh†¦àò3ç7’•WΟƒçqEÿšÖåç¯ëò1kv¸óbC 0Ê,wÊkD5îs d ˜¥¹N a4Ëf˜½äwιIà„ 8̶“| F´’âží<¡²»œ‹k独9õðnHNS'´1m"ŒÊ¿0¦2vAÌ/5óžsÌëpiÇÂZ5¥°“´)˜šÆ/A샭ü…X²A y㦧úL)r3â·°8Ÿ€F‹çB´ï€R)*¨Ëšk:¹çê4ÿÔ¸Ív*yKÃQéa¬ãó8ÀˆZwOö9J7\Ö5Á]ó”è¾Ýð@´ƒÿ ˜°Àþf@åOïr¸Ñ5>¯zª¾KT \p¼N­M%¬6ÕìþÁA»Uãd™;d§¬Ò;Pž#Œxn<å 4Rº*ßÿÄžúÌ >9Á?ÛöËà¨BÜ’ô¬IBªü~2})ó»ÔÛt¹(=ÎüT6áÅÌ^ÆýríÇ‚œX ³»]“­ÍÖéaW*9Àª|É£¦}Çy­÷˜ÊºrçÛPÊÛ„á9Ë–Ž‡;Wûc|æì„X‚4¼“Àùùx¦P$e C$væÚ;RX” ’žl{=Â4âBƒˆ']òƒ~õÒª þwu÷LE„µ3"Êm˜T/ÿùã„uÓè™ûʵpåÚ~—³ùÕ_Jºãá*'ëk=ÒÍÙBO0‚b *†H†÷  ‚S‚O0‚K0‚G *†H†÷   ‚î0‚ê0 *†H†÷  0pˆPû‘pv‚Èe¨1nÀädtQ—@ˆ>ïó¼]ÁDÖ.æÚ ÌM Ä:J-4¶A `ÆÅ …–e×Õ(ÁÅh3¬lMš#}+>;¶/ ¢ã´ââ`¡ð;òÂ’ýUü×E•|ÁQ9þu6 š†ô^@ºYvov>tSâ¸y{÷–ÆQ&÷ËSÝS|hÄÍP#78—h`»ùضÜé¹1ʜЪƠh5„R…iŽc2© ä‚:`[¢)f£®aú± QLK #ô!ðN5L‰ÕûYæÔ’SøK)lic%,œÎWdÙiɜɾ]Š "'ÕnJ™G4zˆ3ÀL<$„9.|ÕÖ‡ãkç;wúèø9Éæu†ž– >©â4긘ò (æz­- 9•½"t,.ë@äžwÇÄÕÿ´]„ä«êø($¤½ÇÎÆ:ܾ?{—1s%œã'Ià¤ú¯:´ŽŠºØFŒó2ªÔÕ¦ŠÖÒD`{8Ãæ|ݯsu°×Ö¶ŠþFuÅV½Y¥Ììëf wX­{ÿVyÒý­Êã–^’ÒWö)€´ÇkÀr; ïÉW oÖŠóê­ I¢õª–Þ´€fO´é‰Aé¾ ÕYeÈ0**ŽÇ_{å”bi··y{YÝ ž³jˆŒéIÎX $>ñ|-btîäÿήñL=òù˜ŽÀÇûËpŸTéJZ*¦p·tŸ6F{–+sMD"Š<¡4 T@éIzªKÞ';!Ð2cZÏÍ Ñ…?v+^2ãL¿3ûX‚T]¢Í:ãc¨ÈÎöþß¶Æ«å}1 ˜ƒŒÐƒ…€P-ôÂBoQœÂh±& $ì^±Õ­U ¡~¼šñšut PH?¥„¿µ!ém§z´Ä|³àŸ}•ºÌó é4ƒ'æuµ|?¨èÍ(Pó³ÒQó´ý®Ù—-áƒúØÍ~€ÐlAQìýé¤)áÌd]Qž7ƒ7²Ÿ+ËÃFm^Jî;ͱº!·wZ»‰§&ž¸_>üÌ,Á§?Óv"ã܉•ú±ÿö=]Øõ9Ü-šÔþI«*–oé¢Pß¼ªëU™ÙÜçê4ë{pjf#S }™§tf´‘Hqâ!cH}¶˜2Âá*ê&¡·ÊéWö/º}Ô Date: Tue, 08 Sep 2009 08:45:17 +0200 (16:45 EST) From: Martijn Brinkers User-agent: Thunderbird 2.0.0.23 (X11/20090817) Mime-version: 1.0 To: David Hook Subject: Re: Verification fails Content-Type: multipart/signed; protocol="application/pkcs7-signature"; micalg=sha1; boundary="----=_Part_0_1891120562.1252227015696" ------=_Part_0_1891120562.1252227015696 Content-Type: multipart/mixed; boundary="----RIM_0_1252227013353_1978_08_20" Content-Transfer-Encoding: 7bit ------RIM_0_1252227013353_1978_08_20 Content-Type: text/xml Content-Transfer-Encoding: 7bit Content-Description: Djigzo for BlackBerry Meta Info FF ------RIM_0_1252227013353_1978_08_20 Content-Type: message/rfc822; name=secure-message.eml Content-Transfer-Encoding: 7bit Content-Disposition: attachment; filename="secure-message.eml" From: simulation@this.machine To: FF Subject: Stest Date: Sun, 6 Sep 2009 08:50:13 +0000 MIME-Version: 1.0 Content-Type: text/plain; charset=US-ASCII Content-Transfer-Encoding: 7bit Test ------RIM_0_1252227013353_1978_08_20-- ------=_Part_0_1891120562.1252227015696 Content-Type: application/pkcs7-signature; name=smime.p7s; smime-type=signed-data Content-Transfer-Encoding: base64 Content-Disposition: attachment; filename="smime.p7s" Content-Description: S/MIME Cryptographic Signature MIIEygYJKoZIhvcNAQcCoIIEuzCCBLcCAQExCzAJBgUrDgMCGgUAMAsGCSqGSIb3DQEHAaCCAzMw ggMvMIICmKADAgECAhABFf0OXumQ2UJsk96nIOlwMA0GCSqGSIb3DQEBBQUAMGQxCzAJBgNVBAYT Ak5MMQswCQYDVQQIDAJOSDESMBAGA1UEBwwJQW1zdGVyZGFtMRUwEwYDVQQDDAxNSVRNIFRlc3Qg Q0ExHTAbBgkqhkiG9w0BCQEWDmNhQGV4YW1wbGUuY29tMB4XDTA3MTEwMTExNTIzNVoXDTI3MTEy MTExNTIzNVowTzELMAkGA1UEBhMCTkwxCzAJBgNVBAgMAk5IMRIwEAYDVQQHDAlBbXN0ZXJkYW0x HzAdBgkqhkiG9w0BCQEWEHRlc3RAZXhhbXBsZS5jb20wgZ8wDQYJKoZIhvcNAQEBBQADgY0AMIGJ AoGBAIyFNEWoO3mTGD2O0koeuESL3ohHVcUTQaIBaDQ9KpurWUd+ZDpXF+W76pNdrFHKo6P7/4kF m+nWv2r41zlb3oyMRfia60UwgFOH80Akkd781SMDHy73CFxj23G/6eJTeJKfWzwLU+Dgc+XtcyHe HtZWTjhyUM7yeN0Vp3J4JGIPAgMBAAGjgfYwgfMwDgYDVR0PAQH/BAQDAgXgMB0GA1UdJQQWMBQG CCsGAQUFBwMCBggrBgEFBQcDBDAeBgNVHREBAf8EFDASgRB0ZXN0QGV4YW1wbGUuY29tMIGhBgNV HSMEgZkwgZaAFCgcMtAhe+dQPgYTRQq7MLNgBtJ2oWykajBoMQswCQYDVQQGEwJOTDELMAkGA1UE CAwCTkgxEjAQBgNVBAcMCUFtc3RlcmRhbTEXMBUGA1UEAwwOTUlUTSBUZXN0IFJvb3QxHzAdBgkq hkiG9w0BCQEWEHJvb3RAZXhhbXBsZS5jb22CEAEV/K1rU2/Y1J5ykizR8NowDQYJKoZIhvcNAQEF BQADgYEAW2F41M5JCkUUuv/oWpTA6weAti43ZbOz9CaCmuGyPZ9nH4tA+PgIJCJE5+m8uSBGSfiH oDe5ho+buit6uAr0AtfSZ4KzIN+NjTLKymtVIB9CwASA/Q+1c/BtuHkj3MIS2TshGQ0BPbUx6wmg wb4FhFTF50ksRyu51D95gJVX9lcxggFfMIIBWwIBATB4MGQxCzAJBgNVBAYTAk5MMQswCQYDVQQI DAJOSDESMBAGA1UEBwwJQW1zdGVyZGFtMRUwEwYDVQQDDAxNSVRNIFRlc3QgQ0ExHTAbBgkqhkiG 9w0BCQEWDmNhQGV4YW1wbGUuY29tAhABFf0OXumQ2UJsk96nIOlwMAkGBSsOAwIaBQCgPzAYBgkq hkiG9w0BCQMxCwYJKoZIhvcNAQcBMCMGCSqGSIb3DQEJBDEWBBQOP97YHKFoE/zVQEpktr9KVACK JzANBgkqhkiG9w0BAQEFAASBgGGr31bH+iIQhBPYQS40Vmvy5fZfpNuSGFIHdDS9kvfZC/MstMh9 n5yYe4ctUy1lUlwOvfU6KWqZDqKqgwTF91LpM45ysiizKbMQnvS4SzNeON9q0LJdwTodj9V9AzT/ X4ug10KDIoKdx8aspMktXRtx6glWbrCe1BHYsDMocQ8/ ------=_Part_0_1891120562.1252227015696-- bouncycastle-1.49.orig/test/data/org/bouncycastle/mail/smime/test/validator.shortKey.eml0000644000175000017500000000562610503212005031106 0ustar ebourgebourgFrom: "Armin Häberling" To: testmail@bouncycastle.org Message-ID: <4815156.11156777526635.JavaMail.armin@lappi> Subject: Validator Test ShortKey MIME-Version: 1.0 Content-Type: multipart/signed; protocol="application/pkcs7-signature"; micalg=sha1; boundary="----=_Part_0_30549415.1156777526599" ------=_Part_0_30549415.1156777526599 Content-Type: text/plain; charset=us-ascii Content-Transfer-Encoding: 7bit This is a Test Mail! ------=_Part_0_30549415.1156777526599 Content-Type: application/pkcs7-signature; name=smime.p7s; smime-type=signed-data Content-Transfer-Encoding: base64 Content-Disposition: attachment; filename="smime.p7s" Content-Description: S/MIME Cryptographic Signature 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 ------=_Part_0_30549415.1156777526599-- bouncycastle-1.49.orig/test/data/org/bouncycastle/mail/smime/test/attachonly.eml0000644000175000017500000006461011150350341027463 0ustar ebourgebourgDate: Sun, 22 Feb 2009 16:27:30 +0100 From: foo@bar.org User-Agent: Thunderbird 2.0.0.19 (Windows/20081209) MIME-Version: 1.0 To: foo@bar.org Subject: testfile.doc X-Enigmail-Version: 0.95.7 Content-Type: application/msword; name="testfile.doc" Content-Transfer-Encoding: base64 Content-Disposition: attachment; filename="testfile.doc" 0M8R4KGxGuEAAAAAAAAAAAAAAAAAAAAAPgADAP7/CQAGAAAAAAAAAAAAAAABAAAAIQAAAAAA AAAAEAAAIwAAAAEAAAD+////AAAAACAAAAD///////////////////////////////////// //////////////////////////////////////////////////////////////////////// //////////////////////////////////////////////////////////////////////// //////////////////////////////////////////////////////////////////////// //////////////////////////////////////////////////////////////////////// //////////////////////////////////////////////////////////////////////// //////////////////////////////////////////////////////////////////////// //////////////////////////////////////////////////////////////////////// ///////////////////////////////////spcEAOSAJBAAA8BK/AAAAAAAAEAAAAAAABAAA BQQAAA4AYmpiav3P/c8AAAAAAAAAAAAAAAAAAAAAAAAHBBYALgwAAJ+lAACfpQAABQAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAD//w8AAAAAAAAAAAD//w8AAAAAAAAAAAD//w8A AAAAAAAAAAAAAAAAAAAAAGwAAAAAALIAAAAAAAAAsgAAALIAAAAAAAAAsgAAAAAAAACyAAAA AAAAALIAAAAAAAAAsgAAABQAAAAAAAAAAAAAAMYAAAAAAAAA4AAAAAAAAADgAAAAAAAAAOAA AAAAAAAA4AAAAAwAAADsAAAADAAAAMYAAAAAAAAAgQEAALYAAAAEAQAAAAAAAAQBAAAAAAAA BAEAAAAAAAAEAQAAAAAAAAQBAAAAAAAABAEAAAAAAAAEAQAAAAAAAAQBAAAAAAAAJAEAAAIA AAAmAQAAAAAAACYBAAAAAAAAJgEAAAAAAAAmAQAAAAAAACYBAAAAAAAAJgEAAAAAAAA3AgAA IAIAAFcEAABAAAAAJgEAABUAAAAAAAAAAAAAAAAAAAAAAAAAsgAAAAAAAAAEAQAAAAAAAAAA AAAAAAAAAAAAAAAAAAAEAQAAAAAAAAQBAAAAAAAABAEAAAAAAAAEAQAAAAAAACYBAAAAAAAA JAEAAAAAAACyAAAAAAAAALIAAAAAAAAABAEAAAAAAAAAAAAAAAAAAAQBAAAAAAAAOwEAABYA AAAkAQAAAAAAACQBAAAAAAAAJAEAAAAAAAAEAQAAEAAAALIAAAAAAAAABAEAAAAAAACyAAAA AAAAAAQBAAAAAAAAJAEAAAAAAAAAAAAAAAAAACQBAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAABAEAAAAAAAAkAQAAAAAAACQBAAAAAAAA JAEAAAAAAAAAAAAAAAAAACQBAAAAAAAAsgAAAAAAAACyAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAJAEAAAAAAAAEAQAA AAAAAPgAAAAMAAAAMPa/DAKVyQHGAAAAGgAAAOAAAAAAAAAAFAEAAAAAAAAkAQAAAAAAAAAA AAAAAAAAJAEAAAAAAABRAQAAMAAAAIEBAAAAAAAAJAEAAAAAAACXBAAAAAAAABQBAAAQAAAA lwQAAAAAAAAkAQAAAAAAACQBAAAAAAAAxgAAAAAAAADGAAAAAAAAALIAAAAAAAAAsgAAAAAA AACyAAAAAAAAALIAAAAAAAAAAgDZAAAAVGVzdA0AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAABAAA BQQAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAQAEAAAFBAAA/QAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAEAAAABAAQAAAUE AAD+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAIBAQEsADGQaAEfsIIuILDGQSGwiQUisIkFI5CJBSSQbgQlsAAA F7DEAhiwxAIMkMQCAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAFAAPAAoAAQBpAA8AAwAAAAAAAAAAADwAAEDx/wIAPAAMAAgA UwB0AGEAbgBkAGEAcgBkAAAAAgAAABgAQ0oYAF9IAQRhShgAbUgHBHNIBwR0SAcEAAAAAAAA AAAAAAAAAAAAAAAAQgBBQPL/oQBCAAwAGQBBAGIAcwBhAHQAegAtAFMAdABhAG4AZABhAHIA ZABzAGMAaAByAGkAZgB0AGEAcgB0AAAAAAAAAAAAAAAAAAAAAAAFAAAABAAADAAAAAD///// AAAAAAcAAACaQAAAADAAAAAAAAAAgAAAAIAABAAABQQAAAMAAAAABAAABQQAAAQAAAAABAAA BQQAAAUAAAAAAAAABAAAAAcAAAAEAAcAAAAAAAQAAAAHAAAABQAHAP9AAhAAAAAAAAAABQAA AEAAAAgAQAAA//8BAAAABwBVAG4AawBuAG8AdwBuAP//AQAIAAAAAAAAAAAAAAD//wEAAAAA AP//AAACAP//AAAAAP//AAACAP//AAAAAAMAAABHFpABAAACAgYDBQQFAgMEh3oAIAAAAIAI AAAAAAAAAP8BAAAAAAAAVABpAG0AZQBzACAATgBlAHcAIABSAG8AbQBhAG4AAAA1FpABAgAF BQECAQcGAgUHAAAAAAAAABAAAAAAAAAAAAAAAIAAAAAAUwB5AG0AYgBvAGwAAAAzJpABAAAC CwYEAgICAgIEh3oAIAAAAIAIAAAAAAAAAP8BAAAAAAAAQQByAGkAYQBsAAAAIgAEADEIiBgA 8MQCAACpAQAAAAAatNIGAAAAAAAAAAABAAAAAAAAAAAABAAAAAEAAQAAAAQAAxABAAAAAAAA AAAAAAABAAEAAAABAAAAAAAAAAAAAPAQAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAIkFiQW0ALQAgYESMAAAEAAZAGQAAAAZAAAABAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAC AAAAAAAAAAAAAQAAAADwEAAIAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAP//EgAA AAAAAAAAAAAAAAAAAAsASQBsAGwAdQBtAGkAbgBhAHQAaQBlAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAP7/AAAFAQIAAAAAAAAAAAAAAAAAAAAAAAEAAADghZ/y+U9oEKuRCAArJ7PZ MAAAACwBAAAOAAAAAQAAAHgAAAACAAAAgAAAAAMAAACMAAAABAAAAJgAAAAFAAAArAAAAAcA AAC4AAAACAAAAMwAAAAJAAAA2AAAABIAAADkAAAADAAAAAABAAAOAAAADAEAAA8AAAAUAQAA EAAAABwBAAATAAAAJAEAAAIAAADkBAAAHgAAAAEAAAAAAHMAHgAAAAEAAAAAAHMAHgAAAAwA AABJbGx1bWluYXRpZQAeAAAAAQAAAABsbHUeAAAACwAAAE5vcm1hbC5kb3QAAB4AAAABAAAA AG9ybR4AAAACAAAAMQBybR4AAAATAAAATWljcm9zb2Z0IFdvcmQgOS4wAABAAAAAAHR53QGV yQEDAAAAAQAAAAMAAAAAAAAAAwAAAAQAAAADAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAD+/wAABQECAAAAAAAAAAAAAAAAAAAAAAABAAAAAtXN1ZwuGxCTlwgAKyz5rjAAAADoAAAA DAAAAAEAAABoAAAADwAAAHAAAAAFAAAAfAAAAAYAAACEAAAAEQAAAIwAAAAXAAAAlAAAAAsA AACcAAAAEAAAAKQAAAATAAAArAAAABYAAAC0AAAADQAAALwAAAAMAAAAyQAAAAIAAADkBAAA HgAAAAIAAAAgAAAAAwAAAAEAAAADAAAAAQAAAAMAAAAEAAAAAwAAAPwKCQALAAAAAAAAAAsA AAAAAAAACwAAAAAAAAALAAAAAAAAAB4QAAABAAAAAQAAAAAMEAAAAgAAAB4AAAAGAAAAVGl0 ZWwAAwAAAAEAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAQAAAAIA AAADAAAABAAAAAUAAAAGAAAABwAAAP7///8JAAAACgAAAAsAAAAMAAAADQAAAA4AAAAPAAAA /v///xEAAAASAAAAEwAAABQAAAAVAAAAFgAAABcAAAD+////GQAAABoAAAAbAAAAHAAAAB0A AAAeAAAAHwAAAP7////9////IgAAAP7////+/////v////////////////////////////// //////////////////////////////////////////////////////////////////////// //////////////////////////////////////////////////////////////////////// //////////////////////////////////////////////////////////////////////// //////////////////////////////////////////////////////////////////////// //////////////////////////////////////////////////////////////////////// //////////////////////////////////////////////////////////////////////// //////////////////////////9SAG8AbwB0ACAARQBuAHQAcgB5AAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAFgAFAf//////////AwAAAAYJAgAAAAAA wAAAAAAAAEYAAAAAAAAAAAAAAAAgk8kMApXJASQAAACAAAAAAAAAADEAVABhAGIAbABlAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAOAAIA ////////////////AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAACAAAAAAQ AAAAAAAAVwBvAHIAZABEAG8AYwB1AG0AZQBuAHQAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAABoAAgEFAAAA//////////8AAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAABAAAAAAAAAFAFMAdQBtAG0AYQByAHkASQBuAGYAbwByAG0A YQB0AGkAbwBuAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAKAACAQIAAAAEAAAA/////wAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAABAAAAAAEAAAAAAAAAUARABvAGMA dQBtAGUAbgB0AFMAdQBtAG0AYQByAHkASQBuAGYAbwByAG0AYQB0AGkAbwBuAAAAAAAAAAAA AAA4AAIB////////////////AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA GAAAAAAQAAAAAAAAAQBDAG8AbQBwAE8AYgBqAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAABIAAgEBAAAABgAAAP////8AAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAagAAAAAAAABPAGIAagBlAGMAdABQAG8AbwBsAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAFgABAP////////// /////wAAAAAAAAAAAAAAAAAAAAAAAAAAIJPJDAKVyQEgk8kMApXJAQAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAA////////////////AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAQAAAP7///////////////////////////////////////// //////////////////////////////////////////////////////////////////////// //////////////////////////////////////////////////////////////////////// //////////////////////////////////////////////////////////////////////// //////////////////////////////////////////////////////////////////////// //////////////////////////////////////////////////////////////////////// //////////////////////////////////////////////////////////////////////// //////////////////////////////////////////////////////////////////////// //////////////////////////////////////////////////////////////////////// //////////////////////////////////////////////////////////8BAP7/AwoAAP// //8GCQIAAAAAAMAAAAAAAABGGAAAAE1pY3Jvc29mdCBXb3JkLURva3VtZW50AAoAAABNU1dv cmREb2MAEAAAAFdvcmQuRG9jdW1lbnQuOAD0ObJxAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAA==bouncycastle-1.49.orig/test/data/org/bouncycastle/mail/smime/test/dotnet_encrypted_mail.eml0000644000175000017500000461610011604226344031703 0ustar ebourgebourgReceived: from LTP-Stripp ([99.9.9.127]:24627) by xmailserver.test with [XMail 1.27 ESMTP Server] id for from ; Tue, 28 Jun 2011 14:01:56 -0600 MIME-Version: 1.0 From: "Fred" To: "Fred" Date: 28 Jun 2011 14:01:57 -0600 Subject: Encrypted Email Content-Type: application/pkcs7-mime; smime-type=signed-data; name=smime.p7m Content-Transfer-Encoding: base64 MIMN8LwGCSqGSIb3DQEHA6CDDfCsMIMN8KcCAQIxga4wgasCAQKAFIjtu3xke0FjSAokQCs8 0HhyPDCzMA0GCSqGSIb3DQEBAQUABIGAbH385AdtLvHrSW/bkZeL1cLZbaesYHNg0RqARie0 MPgNm8JucrBzy6cPLlCpzxfDE6g9f1gKkUub3vNuVjathhbNhCjHRVJyyosJX1j94/eM4dd3 nYBzjLFCHKN/Em1CxOtb2GJyISwVSmzP6FAGnxDI7XQgXP0u3Y+cAeVwODcwgw3v7gYJKoZI hvcNAQcBMBQGCCqGSIb3DQMHBAjk9qF/h5EA9oCDDe/IuPuBe+t9w4xtRcgPZEheSpqnKvXV aKfGPqo1KBCDx4+0FIHKkaIROrKZGxmRVu9CCzHQQauXvsGvk4t+zdshUYPLWGrm5SLQgDAX IIV5tvr5BmC6CmW+sneZig6OcdVxefW8E9ivZyjL01spTxjZAP+/vbUhKC/SgoF5+wyVZXZF uNuH6JuJID3AQ2FjaSqbxTpT3G2r8HyfDoTYiOhRRFohufpzFTfPh357L8Fiv4RHFAx5VdpN c7fHOoOuDmIq1Ur77Csk4DH2vLgAVEAfj78OK2f7xeXTJ3AxrOGm8opYcNYTLeWPwtgDkcu9 8fVqa1MVG47g/KGUuGX6+ksDM1RWy8BxE0uz3BjZkO4qClxSXZlKzml1/rGjdWmTQ601NfwS JnWwDrybdUgLTu5E03vNydRtJ9ZfNcm9DXNWM71iehdDI//ZZnwZTnozFhFQC8oOyR7GbNud wTW1vWoM1rlUzThddE37DKIVxWU6xVZinLFkdPKEPvrAJf2Y8o5YesCHseIhVZAxewfMfxSA wqr72cjdTNFSFRGfBat0QkcQczevuitaMZYJ/HnyPl6lul42ibzeh6J3a7D8jxZuTRp+b0jD 6XA7gluWnQVvEb9dLl4xhNptY6ZqVCm4RjBByyFmhtlwrcmbeiIz+jWE5Hr/wP1T5LemLrTY ko7iQ4pZcngxpELyOxD9C0RpaMmr21ytN3K7sw5UFXWe6a4/9+/oAP08muM5mmYwLX0vIjLx 5WLL0Z+9RpnnWlgTX24/z89m0FinmVlCEbv+ULu3vh3wrcCXdJfrBuGCZL5EiTRso8dUe9P6 WhMTsuUkz2izAiU1aG0o81/j7s/DrZv4u2xh1gly5rVVfSTiBkppbQULz6uo6iWz4L59t/6H 9N0UoIf7YBA4z8FZn4LIhuSXV25Y+dDV+vslWSR7ZiUg1b0elbrQ6+qjGEuzs9a0r9ckaghr MXTOVFRfkTosQwMBHOVjr4iKTkAb6fkEGR8SqmGeBtaiKXGh8cXwzxn+5L/Q9M9gnRqtQQj/ o29A1WkCa+ZJiZDnRT2FRZgvtDg85ZTkraxXogLq82XM4CDDLldC6xXGxaf/1HdsWfWA6ebx nwqfXJ0shKnjms6goVZi3ufh6h+a6kEixDNO3tKuyjJ1jTbp/H/pIdgV8v9s9j1lj3UJlEml mTjhjYFK92969Aeu77GKmUpezkeM9CitK7gLKFE2j1sVhb4SHx/EakShhs7WH+jMAy1Mvrd4 IJaQcJ0vk3Ph4wi46O7TckMuVggnCJSuzcEWXVogOfsfrFWn/z5IYzdIafnv13tGFWGrczm8 X+FiSu+2BbsERC547ueSUCo3YqBRneBsW90RYg6OMpFXmHrbtHoLgo2U86aHLDl8HW3jcTR2 IHdJryl+EzswDvhXNLvzxW0oRCgSPKCfKkONvXoSRwW68MdfuyF1j2aCbkNtr+OPQmBW8Bbk FL7T2wgzha4zS3sm5Y7Qf6ClKQLAFCtKG0Xq01V8/xujIWdfDYXi4BnXLvIj5xC/4W0xFP0m oxg6GHl+QFwUVv5EQeRspQ39g86uD3Od0oZGBj5hMEdvjDbxKsq8MVX9pVM99tWNmikeixaQ h6bgEYboch4KPJyvez1WNsRODSyTr08P9QLYLFS+flLgC+8pIYYgQ1lZ+tlk9xhEyAfuG7FU i3kV3fgQxdMoLpZl+80sGDkFHRFhl9H2zYf5ihkQKTDhcN/+G6+uGjWYax3IjXoGr6b0wzN7 GmcR2rbf28uds+BjTKOo1hKoNtlesgTcSFay0KQyzQ48tSAp0J8ezpaYKlYQnTlsFNAv2Ed9 b2jKz9uZx//bDRil/7ovzTB+p9nS8gQKzX/3DsDsW6OFzZ1YzsRe6owrA+BDwqPZQUopSlLQ 0eOmprWVfV6ssoBAPg/HhDokecyyt0HD2tYeFccgqd4TKzXIVCwiYO7VwE5ITdaACRR/n5ea XANxmyy/7Pu4/kVgauQkeX9JA8LOeK0mQfqBptSYVJJ01mrPaOwQ87GVAjWNLZS/xnjSQBUN laPZ4CTQBUIOqb5hRhOzdGaqhYlhhlbu8XKrVbxLJJ7l8+t5OjE0SxHm2eGiN9skHvr4/K4M AVYt7wCwXVYjnhdOhXlV0kv8DnXh91M0Jttl4EHgF2I7LQffhNo++ZDl8W2SXcIK3K16yur/ WJcz+m+5JVhS5ElAB04HAHKb1P9FIuZAXvFls2oB5LLHx3Tsftx2Qoqjob+1MPSla6E3iddR h1uTlOCVgvL72ebsJiK42RPzjQ/AqPNWbcQXDlitB/MkBbTFop/0VhJ3HBxdjERLPoilOUsf 2FCmaymzw3xHxtRmawFZzIjw0Cq88N2s95g3zXsnY7Mo0vE6B0woTZiF+45WxsOt11dtOz/F tbrjx/xggIPSqM29D25OGNxwecfLcJztO9/Ng6/CIVfmh+9D69ioa1qbMqR+bmZUWxtOTNMZ MYJRinMc9BroVAy9ET8wAIegJGvZE/apjopJGHokV5PAFvJujbUH1w3JxMcKl8QjJM9+o0LH Dc35hhdoNrwSGidOTSRTZCbEEYnUZhvLjjeIMyIOhBuInwfkAHch5xj9qfUG1iLNtB3U7KYT Xljg5CYktz2daq8gXZ9UhoZipR+e41OdEIdOAr31gmBlOtiN3R67sB0f46tdH6glpyVJTXpc xRRiafsS6138A9WiOqANHRgrssWmIEcx05/b0MYgRUCKwtBchxWB+h2hdR1LyLEd1sTcwaLH z++PvWZ+2LDAowoOARGKttT0Z5gIRuNbcEQdTVoQWie5Xm6wTa2Q/Lm7ooYSfxrye8VAxtsp Splr8UKLaMUntKppkfW1Er2R3m59DIHy4Z1wyzr9hDG59Kw34HCULTGHrO66Ok72nGyumXQI y0jIF+Fe3d3FiUak8a8AjYq1nJt+gCSW6cZgYMJ99hsq2reXLsX8w1q+3OI6AdoqRIjwNBqy 3blzKIUnfwPCnIioEqyqs0vpTR60wQjbBa+XpfiTAOuH/vPDuM6fYMpgIvvmqFLmhX1iU0IU DyQNNY4RBd5TIoMI3h10Yj4PvvyLD+/gXTb1hQUBRBToDOD6BxxiAXpepjMapOnIASaJQPwg bKMTxZcKBZEqr/pIc32dP805SegarRX3EgxpEP9ZZsRHqEt551pwkpCFr02ulG2Seyshc/DK O6QIaowgpkrxrV8gf/o3MbBxEpkk/AS2wodrl+dVDB9ZE6aZePga/2fcnG2749/kKEoF8IuG gQC+5OoLPvnQn5Vwi+T15d6Rj0ZBsOVY6vvN4c/bAWLgyVZWiZaJJtM1akPK2chYdQp+9efI POitqqrUGU3ZR2nPD28GSP14efpEq+jhZM7DqUf9zSfrKdC6M/Fkoh7I5GdPqYw7LnFfD6i6 KRA5Erhko3V3ikyvw+VtgKaQMjN9DNR81DGkCfFNTrDkneCSWrsQTzh7qCEy1LrLrCYTYog4 zyQGkTE9r5V6/6jdZFfqqhAN7AUHF4bj+wsl39+hytSzBMiZSfm6IHxFNRnzKgpf6At+DLbQ yteX0CGZ4DU7lTPC58KMaMGvBFd+SoyWT3MxBsCyxxlSJW4SLFP64i+/HvQU5NtOPjLBvbTK /CrtSQzuc0KpgOEhSAg6q41jfPBkNgJa47u9SSkERebd3emfo415djW/B1/DgPm48PMCQTNu sZ3xidUPWs65I7FWABrR+ffsAkrJPdylETbnD20TdAhYuRaGSNSM+yiXAI5P2KDZ9Dr9/5Y8 1rMwsC8zNwoV3lX1OOAAbEC6dI0QewN5jSUoABRFNOe2N8PL+PYQxZ5or8KoglrGbs2shZV6 T6MEyxO3rjvM08SH18wcg3f3J1pXnWC5Gxz/wku2SYifsLv2Fu3yCrgERxg1ODSM+9NiZX4t vNy4/F4tU+TTzdR9qonstxM7CMuZcB9jbn8cAZlhwI7lH9AVr4c+/UZ6xkziaPfNvHrhP5up jW/hGxV542v5sQeCmrxcyawEuJZhc6Mt2ugHf4Z5ziqCdlslctYh+/J6Vxte2gb7A/+aKM36 Lois91Sdqsw10/dSXE+aEkukIeJjefmjLsOM+cVOeuhBpH7Lgee5POWjY3YxAq/Ll+3//tjt qNEjKJa8v9TZtjxom3C+Xcqr3xVXsdV300BYegkf+9m2mdR9ROrZqD62StI9IimS/MMXIjAx LRzmX18bVtxvQ2uwGpw4DIa8Q/1mv1cD7GcWlUXruUSpA+A52F8F6YqbEHpjs2ROpyHXawVo u3eSxgs25abZ6anXd9U/e69EOi+UK+bGwml1ak6nyigpdssZ8+zUaZiUdkqZy7OaoWf4n4eJ 4d49mAkFFqpEdp3HYZ32j5S444Bh9Ti4/NR13pUYX5/AE6ZslRZXNMy4JhBEyRZcc8cdDXAk IJ1TXdQIrNO8ojF8lwaEVfnK/4sqcW7rdXoPeAQ1+mBzBZPCLQYhG52Z0ES55XvMiysflgeD QsIL13OdJlvsamLWQ7N5axrkN86+gyoUGfRVWECXtgeG/RyQgvZxXzTNWo/CQ5IG7DKPM0ks ATABQNkpAMlK4YbsCsMDyffytqC9gLSiyKaSGduCoHENVObjFAFqT2J9a2jrnltGEyoM/u/P uqqoA740ZLaS9mq0CDQozvZrbQ1uaBbyUzV0yDNkE/tIQN/5YVYMhfvhVFPnQilzK90a9Uy7 yKMAIl9kNTXvEYxlivdRpBm4HQZP128VGKiXzdeVmH+ZHgMViSiNX3UeZrcXnkXC4Mkbg0Xx tSNS6djnUMPgUdzeteHKsK5QLVQXrrHm6BYNs1qvy+GQCo50nLIqLslj+GKNLDl+7QYxSlN6 MMhEXG+MGarwXd7KzCEwTTjml8Ihx4DeVF6uxNpK7ZI7IDCZUPQIPeH5sIMaIOy870ud/7wQ KSCetUGydT9WDpvutXBh1OZHSeDz8FrKQZtRQ3DKbL19BSRkziQrBuImTLyTaDyD0H5WApJ6 UEPRlzF3yJRoO1j38UfLKAP+PZnJeilbgcxLod9wRM0gbB3ZC0/AVV9SpifeKQMBGgaiBJ7Z xHCuJm/FDs8IKT8mnsDa2KA8GU8/joWV8rLk8/tgtH5eR0uAouwuTzMgXYqb6FKURHwDzkr0 dafU0Z2QGdmSnozbkq182VOKm9+Q6WSzkrblutxHHhNvvnllmoHTf92U7Mq9NboOabtbS/gO pZqoyOMD8ND3tI2xuVkNiqTQfC6Y2/nl6hCsjlSnW93xUY/CtAkVyHV+DOn8LtCd6nmHazIz FWo/2ZkJtORSUrQdGIdBRCNCX/dCHQ7reMZ5cQn3bucsJnhDzcgdloXoFrrfnkgNlmZ1M1CN kQx5wz7ilx85tidvXcfpBnd4zRLmz4aTjuoo4yKCAaV1HB+uM+V8DLthLRZSqSVLgJvK3I8k nt0usMPvnoLzyACkRrVikzu+vPSCR2WpjZggMoqrorSfncQb2/C98BB0SwztyRQs8rn5Csow 8zJRPHWBri7uBJZLUPJjo3pCvYnsdt4uWou8Ccsph/wLS52t91VGq47CMPhokNQelVSH6CZH but0m6qnG18R/P6JKRIDDB9oNKmvJbGDhpB9hgsWrJXRtf4tWyWr6UVg9tl+Ezq2nqlBMDVT W6dcM91jfZjaBEnOx/eDOsdMrFsshOvDzStwt1XN3NvjcvwMzxS1DBVD1oATUDL5LYij+XYZ Q0VHKYwhNupggLFYNr1ukvlH1PhXWLL4JFhCoPQkOzpNYejtmketvC4fMOb7wOwBlvNr83ic JjhRauRW6ZAUc853rlTWOohIx2HXURIQRamy1AKNDJG49W69gkrlG4EAmQ4DDR7k6QtoCilo HUuLE6Cw46fv9Cg7TvqojoM55ONb8X07bpHwbSZ2xjDxBPuTrAEXQ9RGqaLQKxkKQNczjP2+ bfepD6wBqXe1DnrPBAvHTULmS+mr1gf/B5S+ncdfHmpFKl3Z1OpPvzWbprbSmCRe1/y4PUUh xGQvOwrNb3Mg0Y7QyyZy+8NKV1bA+ETH2VcXJWjSfHGJ18Lr3onvyNMgvl88WrU/TSjLP1h3 WJ3s+nQBCV+L4GM99tJhhXv9S5bWchC9jb3BO+1xHnfDKax3Od+O1umGxs7VrZJyWqPGtRzs LXgSEMGgBc54G0AHC7TWpbouPoyzehHloG6zdtyEkHku0pq5utQD9i8yuGJHOzZjle86UdL9 +46WkBgabfKu91NGz4ronjH9Ofh+0syfbm5zLcWzHs/8vaHY1/SiUfyHndnt+7tj3/hYGfYz r0QZqBUaGZaPJYOe6vvXz04d3sx2te6xGClrebe/iGHkuEOMYZd7FnbmNuIsPpSJ06XBFKR8 Xj4OrqqpjcW0wtpmNTmQ58UPqdx3nLWs9w+VU88DhnoJGUiL+9VbQhIK93TWptFk7GBttb47 vXL/xo7CaYxOTAlSch6zW7KOz9URl6An5oj0Xr46QUYHAbtZDzYSGqNXL9LdWDmF6Sm8/m8T MDUrcjxsbKtStO2SrLVz0P2VTVzqGHtymR2gRgNunp5KsrTjmIyIO0t6/X5xgNz1U68YSgjM MM5szp1U5q0eBHxm3oDm/DeowRQ9aHz+qqkcQDS3YXK7cqKCChV3Cdz4Yhb4bwGmQl1OHLGV p1dzrMMeXUAaxf0VhkhGDiwEBTkVY65MQzRmXbWfq59M+IZzmFJs2tmKdzI5Gb8vYFbVeEJM hvJbR2UU875ciNWthAi9H44xv+Rn5vEJcYTYXXZN6pO243ZcIbzLnw3J3jhp42ffO0khuWB4 PU0Eo495mVduurXGpiaeiFOmJjFvu3GCCJnrRO0BHI78dmUtEsi/2P/J8KzG/rloZbqQNF+K /QQtspzlWeGlB78S7TX6vMt/tvxlJ+wysXvh+pvz4x40Dkw5+2cvRzLXQAd8AOKYU/Sf5IgP sk/7V3OYgGkItC4RPLhj+nGCRvo3n7BK/4BSIdBgjkm9WLiTAo8mszmXFXV2Egavq7VJFmen QUMMTeAjqX7zZrEnGDuVtIBZcfT5Jm6gBlCxDxzI6bukv3Uup9k+j7nZizKR3m/gIs+YXx5W jm4MEO4P3GHxYnHuEdek/smRQzt9c+ewvbj1rLI+Y5Fuehyc5yeatl8L7IcfsTqV9svf6obQ kyd3KQF2lWMLOnrT+FR3xBPj49Qai/+4/D66A9ruNTND5e3A9+Dz2XSdbLwEZ3IvraK0wej/ Qfb98+NZ/DAFqzL9mG5Oav0qcbkDEX9ve7iXaZRVGlrJc2Qq3/nVSYMatv3m62ot9BdDkrat VR1gELbj1Yv9e0mzsXtAh++I5Xl27epy8fJLR0ZUs7Sw/TXPdUEv42sKXcbo6amP0uxr8X4Q ppj3KNeN0etRcxc9jY9JmTQRX8qkFTsU1YIyQa0cNcG4EaLfoGA7RnbmXgUrgrox11vrqiZ3 uULmY9cetFZqi3cYJBum/hw0vQqpjK8jXW9eTiNUiDJPWbmcGldhvdhv6XOWxpo22DVd8DvW KxENicsalbI+H/Mv0D8pG/N4J3JIKYJbsd9PZ4yIOjQVDQr9lPxrSruZMfFMOE+8kkWwJ8Ug 07nqfz+FdaQOdXcZjGKE86z/EOXSAeSG9Q+BfjvVyCRSE0iLMf2UYFV5oYnyZ+n5Lw/VM62V kOny5L0G6LdzbU5AKRh/8ElTIcm+LPK3OLUtw49DZoj8ifOHcEF4gPhUpv1VSmn8Kpx3U51m NOm1VMV6fOo1Chu3jcZSoTrSUzDuyEDhj/wxUgF5/34PD1hX1+pqtc2Bqv1hkOdJO8LaIZOz X8H/XjG9ug8MZ8gUGZB1lI6w7v2bsq9ujhYaTOchVcGMVtfDyfZ7JKFUea8yGGxbmds0VHrZ hiw8wajCV9i2NTT4HTnaZ+NMs8ISfSF3ukAbT+VGkPIZWW+upBIIyHquCZa5RUvOTpTPD4f+ twYhTQ21jGA33NBErFtBGWnSgS733Ob67MbNWrbxCORmFtx9Ztr9XunQsKdnTcEPtyDcUIua 6TMDPFD2ovZsG8tP7cXZ7LxQUH6zxDHpUeyhRMsefDkkhIY6N/RBaJ1CtOGej1PMrsZHvnBr CMPTE99Tk+Jb1rBHjYTqUjeMaOOFEfXL2GhoBYtxigpCgAtyfdQnIbYw+K917qYWVKPqW1+o fYD4INOCMf3+y1OdGt7l/hT4Tc7TRF1sHpZ73pl70rMpOmp06X7hT0DGj3AHtLzLGYc6QdBk JRL3i8uju7EZUTRcuh+BHmUVeJqXj5fRMT9VZtIe6f9qhOVMx7xIWW2BJGSM4BtsPfIHVbQ5 lvlr9yc+89a2kPXqn30WYuE8xEin4QomOau1Wcj7Re8TT8gE5wyElXfoSDiiAZXvlC1UZ/8U IW6NYE6rN71qIA2YpvRmyfJO5TPdJuGyhfEeGXEx9b6SisIKwQnK/SAdjhFvFq1M++38a2H2 eGRu5WQZIayTyHqmevCQzHFf87KOOxAwmSIzkJMtNwKEXXPt0TZ2bBbHf0k7inB52rNFd37o /rE65hgOq20WwTSND0kSHEasvyYy+e8zOgtCDPydGtufxBDLTmhV0a0j18Aulw91e3EtOojj Ec6jBwGilBQ2bsLBDal5qVJBjDZSMwA7Fjr24uheVwpv4gbcqMq/hmv1+oa3fFbRzD414wqc 3OgdnehLCNAWz7E7oVWYfyH6TzvvohxEO6YOPj1iNClku17OvKoCtLRUhC2bWLF3rUei7qnP utYeb1FVY14Nzor6Vq4YkoxG7eXauUOX1Pgx81Iuy/B0WRGa+IftOYnRhRmTmK6VhgT0QMGB vQRa2pDDCaueBaTKIBrheK6WH53Actrb6WnTDLPAvw9jiVvGkR9msGdKcQm78heGoCq3NSIX HtMXU4vnyGHGCmIT+JawzDC0AvEnQ3zbTUsvA3TMYiTNEXu+hIhfqD/SSMRbxfTIl1vdHBXe ii8cLLzm27IS8nhXaTSmFwEeeAlkSVaHzNVJIyHui3RAdQIpcJDakJSHPa1cTsQe3jZghRw3 jGeSiIKHmHhL5Ys4JH0XmPqDyxr4GE2UjSa6Q1oEKPOjAQs+W2trVBQ2JSpmnC6Q4nGAfhOL NouHH1oGo+V12nuCxxNFOM3vTjhzU8vQpbAw8OtuXPsAic7719aG7OlLqRX2HZMkaXllEkIs 7Aqwejvtawn7Lp7C7xl72o23VBRWD6mbaIa2QB4U4JaHXg0PqJd1yleTCWgxJn4QeEC7gp9l Ecb1GkJsElPluHTz5/2A9KvM8T2+FiO+uHuY2Vvzq6xksZpsVEFPIF4eWRQL9NPebutnUATH B4OfcXhb7LNiWCCXWCTU5sTqL5nz1FfDEQKLmFt+43ltmQKYAvOQPtGF1vZn1LM86IuJnC7j rqNLKc4jxU4lnz4GTnB2OcuxXSVle6DnWx11XKkI10GLByOsO/nyaXvTBFoa3pYu77/3eAiU y2EZIONRIOv3kebjPN+hWE2x5Z66lTg62imq/0iaaZQfYeT9Ozcm+EGYoZFC3Q2yOe3ufgOD TIhR9mu4AHL5AHtgc8sSairfKoTic9s8wWKQBfDe/wUfdRn9f/Oa+A2A9TzMk24NIlElgI0e Un0I1DUE96bfriZLzhRrqAi8Lx4J6SR3uyKPXmN0NgXzDTRlRv23QOUc4JYQ0fkzihwBNUgr +pKpYk3OXqYukMATDmGZENcujUA/tgO2ndlC3pEChSdX7pUDIkPBsvEd80Slhlk/ulaeAllw HuAw6HeWsoI0ouSUEHVcO36CspmhsJzEfVqqb/aNSvb6RZ083OKCI8CxQls0xKKEU+h1A/Hg J52RT5mHqmrvErJSRvGMO1K8OSWWsvKQrNNbre+jEGBpGnF5AnZfkKt1lyhOM9IqHQBNyxEi AfYLFCN7y59RgqT9wQmpIRTY54c8DU2nh0oeo0PrKfN8MoffFiBF5Oldm4+/ad5eRtEEKjc3 NARHava+z0eHjHli0R7a08oa7Alk/4aC213qMptnTdjJ+mmzC5KYsWVSy/ViSdTih3sYJZIk nkiH6/kMdkaHD1eetF9XmXgojP/pgpJd8jum7lwW8p2/SEcG2IHR/kw7GxBrUudc1WyU+EDY NPaQOF9WfortWTuCqhdxuAuAKnM6LvZ0Vb5hpQiAtAhNWXfDsucu16UEmbSNUQLNaM/qdnCZ K8Sjuok7ys3FlJGdwY1PsOKndfi3NDNry333czU2oD6nMnZHO0kO3FDOZFU8eoTWvh2tle/L Yst93Ixp6/Oc+jWNyweGtdnoFMpL2wO9UpTM2q5ElDGEEy4nGoKRVFNDNrFvEtQ/ed9LfgMO 2/q3B8QDwuO6MJMJKyy7BULJJsVCxITkyv0xbKaeeRmCLXBuVxOpwCOODmQErwfRx/b4z2xd HbTkWANu1vD4WQxXyVeOIRh+RKpfF10hbig0uPSkkhIKOngi8UBmuYsfpSQqAYycBaQw3xR3 C8K6mqXs9uxL3Oam9qHl2UEsgqCADY8W5z/SU7h7WDrjmYe6MF/CnLnKYUWwWyemMF4sMZDb FjMuGk05YoVD4x9RYL4YOkl8TL4V0BEYd1Ti3AGV5n2IpupYUe7jPYTW/v4tM/MZE0NU5sXc 7O+hYkzQvG3VCNqvzLUzrUrRM60NNDXaj2sylnKX/5JtikvnnkqadmsxlHV7c5safq+p2c3e VJO2SeDN2CRazbIy/7zhkw/LW+Skqg36LsoMnI4lf9wxHOm9sv5hUHP+BIoo1oNf1r0KYy+g bP90bNc9tBbusrd6B0DhmNw9skxORva2paEeR6JQWXjlFKZJv1ojVZTvDD2ur4qeRWLz43hb NwW3el0wc9rFW+qze1WNJ/QL6XOaO6ZxLJq/yL3w6lNlM5KQ3Uws4naLMyXwOri6cJ50GshC beFEi+R9siNXM1yvZ7Px4wCHR3gTDXoVfd9fbFvKBBcAKGNkLNmC91pEmYZ3RnOJ3XJrFdqI 6G1uGpQu5XeMfBg0OFEYEOMB2vxcp+Pb2ja4cuGNUvGqG1cs+WxfdUgr2WRTEhZRqpW/zjhs yXZ3HRCTVsqYrI8wIDjByOZpEemQ3+jNuIzifyLIwH+iMVc2ADgyUEpNxCwOKpBE0JCdEiNl DDgTgabjHLwNA4WDzCV4KVkplF18ELcCMk7YLVAY/gbDQq15BJCmYyyUFj5+cEcYRKmeygI+ AC0a05WWcMwDKdM/Q84qQ/PrfD5P1RHwBPk58/RwQbZTFsFZZYNhaaNc6g1c0PC3/d6PaFrD TpjUstLqhuDZ/enqmRLtdOsTmTVCL1KYGvAPLld/rRwz50i19uHS4Vd4+Z5jZht9Pp7N/qDM 9djpz3S9xH4zxEHuTkUsWlKNCHfowCXSpFp9jIs2buLIFumA78QS+n30xssdjRBOc+xFEBwz 4wL6f6omkQXtgxkm3UH98RvZ45JbbibR1WGU4FqXqlglDwq43ndUtPTRvO2bqKxnCvlZCWQW h0XV26/s+TjbD7Xqov6jgj5Ca2B2I49otdSJd5qj5lyU2ZBomCboJjxqfh6kRNh8UH7zt8Jx 1lPnZt+xJEse2B2GFh/NyYfkf0iKjy1ZO2d4PYz0waXX3b1V2Qs+Kn8+W3MDY8KxjlXF+tUB qJK9nV6s0FIXAQaWSIsEscQgoVHtiQROt0Je8I8WhqK6OAzq9aF7yNLzbvRKNWj3Sor2+1pI KQgjCVmkAzBxXUXJrSczY4NAmz3XVJEiNMOKBkhq0RVAk2hG0CjMkiaMqiJyDWqKZamF3xV1 9DgNnx1wlxBVoAbp6h/8M6GN/+2pwx4dXXzUf2VwI8x/k10j+u7fA/o9XYI0897TRiYi6Gco U8AvhD0zt5CT8moJw0szkF8Ajay1HNuxrdzMPc7rtr0g3OXU5TjjdlLMYkmf9D15oARfcGpD yq5orIQC+b7F6h/7WVyFk/StuIy4a3mYHFBIoAwv7+h0bjL+DDCN9opX1pXUhaldJk5NaUhD Tr26f1xzTVeE17YwGtxyE8r1i2Szy1oIZAImLtpxEhpmGZ9Yp56XX9ROJ7NI6st53mLGV5e/ uhRdHxeb8FB7dLG6RuZdNDPfGDmDqKpJJo6o0wlbYmW5tFV/XpCy2KBZQpRCV0eUDMCno8Yp +rqYQZ/RYR4k8N/Hs83mG98iQG42sZX9NErhhDOklzIQ3BoQ19YpDgidjropopLoOlvP45nj 1wtUgQTv75OaIuwecG0fH9GkGbAJ9csgEKbWmu2hl+OUPRKiTcZrYUtkcdc1ZNsM3sSa4Rsw XCW2lRd8uFlolqoyMwadYE2Fcnh0bf5Iis2iQBwHYKaOjGYOk9fWQjsdcM6dBplbt11OcuO2 YEYtfXh3jG0XzP9ieJTq0fr9rvpwFzwLVeZSAgmskE1m0k/5m51iEPQTxHenp4G1+BJrom4I VxNVslNur2LAAwZaxaeq6AHEAGlWb7KD7EI4SugXuBeRhuKfLD72oqrHKvOqsZZ/OEXwg2be cDh01S04po/zvdwRmSunw/qnJk/Q3REsm9lsNaZx/DJbNhPEbXbURAfr7ar3PWvqWcjkZk9P G/u2UscWpBVjZ7oKa9ORkH+lZeNB/a7O+BhP2O9LnDFyUCOb8EvOaB79hnnOJKLq4akPwL9V o3cqj8bbio0ubDCVfHtNtx8IzdO27Aep19utVmdfC5KTQXO0wyEYmt8XxwdfxhvahwIsPmJS AuObc1s06O7rvfp4HooTDATP8e+40jIcGoOTkRkR9MvU85pdZRhis0+h0NhSxv0Mquzc+W4K ed3H7IgeC5mXefC7X6MDPAunWJ+4VuQ2sN+M67FhdH6b+kvBQGrT85yO+QvlMxoxE9ITC1/p pYdis1xVQci/Xg4YyEAY/ovlRbARFapgHX1BiA6m0qic8ysuuADITAdqlF+2RRRBL4Q4p4nF utch6hjk+RKRkRWLc4fY04TZgOm7a5OOK7KHb5d72Zdf2tSHkSb4dHbLk+cS3xebgHtOYh5x a0p64mzGmWmaMM+SGSB4r40PlNiFsUR4dNkd+SFGRCSpJUBjaZNA2qFHtiVXWoPdUQPSe8t6 9uuFb3RgLbPcqan+v13uC+RXaQz51Ickwmg0pMENicyMVLp+I73v7iUrIpj6pSMzLduBgbbz t0Q5XERsA8k3Uvp9oDZo6qA3RN8+daDJR5XhnhhDnV+1B+z9IuRcRY9xxpSXhNPqV+EsYPWR CwQECDMuMg4j3dv6hxHDd/mGeQ4CuKWKtmFERTW5mf5CmVfu64OBKZYY6nUJ1tav43PtYbB5 7ysLCdLHaWEFZhlxPiJYCpUKji3FerwaCcC4tmYQRAi5a//kgBsuyv7Igdx8akWq3NPOYzTE cVqvkLbTPNiLBjacpGvjtf1cBWyK1+bZ9RY4wAavDXFojwHDehleIsKc0hVBTqYZXf6zzAmY nAEA+7yzq/TFo8jocojZU9egG0Hnc6V1tIJf66RYBrf0VulNlr3PqKdmr8OtALWIis1EwUUj eroZs4B4JSdE9Am7pX885YISgG9RkPYni5iAL3X8asX5OKqQB5TBk/lxL/tfykv4u5i73DxV XO7IxsLy7s3JUkiyjAEaXfZH5ZFo51C2zvXP+4feSFYRYpX45sKp6s24pTOnq6mYXE6TVqdp z237+PzsB2D91/CvUL6F3GLeYUIBiDYluI9H97rWdYebr3Ja+P4jakbsEoDdFrO14iqmP9aI yClVVxxWNYzM8hGeU/P8WzG5aVBFn4A10myCPN5A55Q7ePmUMJr/hFJlAaCehbwDc7VFZPhP lE9gy0PC2Hr7PLd79sbt6un64spUmhTq4/HY6UciYawn27wb2yG4Y8utshmMKRvJzIHvQm7S zVc2dGsaZTWbWaOm1nybf1WDpdDbKJOHTH9LVyDA65GknPd9oS26P6/zycIBUXyx7tb81Kft 53uhZXsL7trlj+oy8AEAzonMiCn+D+p+mOL9wY1UKFdc2I1bVMGp5FvzidcOKpEKmbBDWLlF 1B7344wGskFgp1eXPENFc9yQcMNVENCUp7/aFA34l9Jz5fy+eX1DoaoZNpcIFkbFiI3n3lCf nzGrFXVvHlqnib4oPo7G9ifNeLCWFvLMnZes54Q13gTdX6t3mNqsYmnHO84LYW0zLRJ8KvKo 2t3du7aeZmwMKGE3gjUDeR1t1dM45yoG6qE+TOMOEyqI+Gi9rHdO1YV5R0yMSCtQ9ZfRjf+M DnZQihCRe4rcZtmy2bbZ97XvhRpdisoED3PFdacP+WbMeQZuwbiST4ZYkzBf2Uo+ST98A+pA NAQvxdNAt3Qamj/nSWLA7b6StVAmeM6VcwBWj3Ey8/T2E1uc2ChHxAhWx26qjfLJjWYD95js 7mvGB9g4JuwqMteiF02cpfrtiEdJQSt4P2AhNMAz8czZZiNpw0QMK3V6zAOsnmjf2x3xo9ou UMbSuuXfdZGH3Q/zYXIUvKfHvS00s4yYUbO3epjk5L534PAKrrbMNfaV06R/sAfpPkyyN5qk IrwzYq7RROnfhiEUpe3xPDI3gYXXd8F3J/+qxod0KqKyUc8ILxNY3cBKVsQtM8ZMcrwGE4Ms OIa0/hIYd1/6JBhvhW58tEv0iUP4+oryDjCEoWF1ddJbM0JfYyY4fi61L56yP8R9krDqatw/ VifHB8R3PTwk5ksE6ZMogce0uw6S5f9nv37Rnv4009hCPTyO7ToiS+k1r2R2G2E/QcvuYIoe vrXAK5Xb/uuCvCiZnW4pz7AIDDan168t2psIMSJspBaTLWDwGxHlLVmVho2yHX31QyISMy0s 1io8M/6LRf9ndPObe87MLvHaZoelPZ7RKF7z+fw/jVd5Kv+FIUmS+BIwpW/D9Yabu0JuhUxU emJt+w2zODRz8GakQ7vTruo0kwDV3v+5wxqxvzGhJfKA/IBMKzqnxgJEbzNqIKQCqdx96bF/ ixbT//Jr8sun9t1nvKH7IsAAQBRmNEbi3NPNc89lDUIRa7WWvIe3AO50+fz8g4vKNdzjyp0Q r3b7vQiRAzLVH7r3B8KacSAzBJOVM679HsJXU4lWFhAcQ2zPgEIE5tipoPm4t7izBPwuJ1bA w3quTFFmDGCOrNcAjHH4txFk9jrvAiYj2L3nJBNTWy4tienz1JSvQpZYhbljut4VUrmuGwcI 52M7UMY1FQo8fWzUxmYiK+9ksQFgBL1GsskfffCG0o/vFy/0drK+7ZC+Oj+aB88m9X64N0yk Hv9q9tD9C8/Sy6VLvWZeyZy5wLBwZzEEiWUEug389SO/Tu61QyuMPuQCVfy7Nxy6SGFDxHZT rvU7Yj0LN//l0XMLYg5gnNA1WSydJ+0bVV+JVYHH26ATf+kVWOJmigZT+hV2Chn7YAUM53lg al+0CJ50tRuYQdNZf9B1/uAIohLjzZyEpXCsxfskzSYgGwTW4ywyref+kuu4ntBayeDO3LlP 9UhhDiP0RSUF5WHKZ0xNYHDZKzfbk6VhIPFXPQ/2FVhh8ttV9Rq7BtsGnJw+4UOMfkYzcnlL MOJa9A8iOsrc8U80E8qrjHQANbI0Q1xeGsvK1o+L0DiOnpm/JmBLfdvEJJdc+oe3F7rA3Coq Tim+WvpTUzqkctRDwYzHhfHLuTHyN29O7Z8gLxL3dPM0bUK9QljmBeZ7nx7wVREytG3sCZlS Y9zesrHH9jQyTguoYm9XRvPbWYxhWr3SgJmCTi02IlYnMr2HuYH/vQ+ih+713n7P3DclyqVn QphnadxqlkOiis59Ie/LtipPv4q24MOszCmmxs4gCC0l6Qu5OUbN3hpXSa3jHlJjtXicb+Fy V2UNWjPkdTn04JSA8OJS/9LlaTH3dpSvdQhcvpR4tvMOlq13Xt24uknrnD9RuiR72ycnK1Aj tiTtp7dfgoQTpv/hybXG5OP+rmd4z2gnW7Ls/9jOoERo5q000rICxacXWsakQ1cMQYjDZAhP kom8s6gAlBgtCjKf/8VjZogwlRgiB7Yr+bbaA14EtDso2s3Rqiwb839nx8bWYthnCnZCMId7 UipbKzsjZr8N1ZENfhWtZ/7uvHBQYYnN4Mq6BmAyAHEBu9VzuKQJIOq3n6ZNLSNkP78w6+zl bTNwf5pkhXbQaqleeKxkreQCCIMHa27tDm4gIY95YTfFxiBnao1JRqtZY58PY0UksfmvD8cs 3xU6DQQs8HSfcsibw54mURFH7rwyFgc642ezSAjmZrqhXlVPFilk1/Z6ub5sLu7fth0N75wt AOEaxkgIBoDQi8dZtx7mE5ypoulr7Nzywn4qMb47x2tuJw8TuJVvj1EKVvcU7ZltUESWo8c+ Wl1QPyzfvTmtrXghiW8PpkFpBgFmf+Df/66TF+oHBLpO2gPDCqIAs4sMMRG8lJ6WVACX728D kKDsPpsUv4E6KPkukXFLaMnxPV0wWqTKvJaYEANW3+Pcu+q8nLm2rYsbitoO7A/oZLwoCmzE eSjWFq3DHc5Oy7+QANFgS6e/8RyoGiQWkqYzbo5jCKKLMJdPVAGVNKpDkYJE7mXvHSxZP8Ii fffr1sG6GJaIPTXylwbQvpF76t26WxTfw5XDLG8Q4HeoTsN7N7CsG/cPIAvwJAFbYkoyc+qE 9Z4waBdnJQp+c4T5yeVybNcZ7U4sFPUa/9qR9N+SgY2fZD4yyPBp9FwB+YOzFkxqtBsgOWsF UQ1gDYi/Er+0k4szNWRKm2nRTchbizYQ8WI/C1jCmOiQSlr1Hm6F7GOMgxlriGW4ummVlwiP ++0NKT3DlfivSpRVeF3rVdzY+vYt7Vs6yv/aNA1ewkepJWJrjyGo4VaYldVnOKF/8WrfCn4X pybaLsx6Jpur3eD0lPx7DNp9dSICm/R8sa3cbVVKoJnCUst5LNSx6znvQAbUBGoH+W3pcYMK FWO6ZXUp3CYBai8qYN7jILJ5i2mQVG6OVg5xQfqVj1tVrtNXN4EIhnpQVPKDJUrXlg/2fZvG qdo56MSzTt7Riv27Rs62tOsLXbTHnryNpRPWgeD5328XnCJyodMqwsZNwYKNI0XCkYk/vruI cxQY41H0A/2R1+6jBmc6hSm49PXWE6ONZ/lWSxk2t6TBbz/0DhNI/yOfVo1rruUZtFGvoeOx 07ZfgeXq9OHPeoVFyfUa7GXFQ92rmKfLJWnsbzLPvb3CSlQHDsSssuDYMa58UbLmv1lanGW3 O/LaTddEFxJV4QMYNQoev85epmeO5GB5BhBJ/QWPLm/6r2gow887PZWOXZOfSc/DTPQ+g+Vc qIPhRLVhxKQnundbyTiHCm+n9pKiPoTK4lYe3CV8Si5YTH4k/K5oiMTEPAEGNEu+zxTqyngb K0tib/0DZyDTX+kXokg+IHr2zWHzIOK4M/KbIJNo+MrbZm6zfkOTbxvaYsBk2B4ao/52ViJ6 3TACn6QrBUaCMp8+5s+9TZWjrioOIbZ2pZEuklDN7sKC0SbulwLMgyBV1UhCJ6350o5e1/zr 76BuxnWhRkDAsfgczNOeKyip3cnvL623NgC9tfIGo3zj9DUWW4yLPHddrorGvVjx69C0c3S5 rZ/edG8mUNuotGB8xBpVTMvhQc7aIuG4d+33NUAlo8AFwI05EsTMD2yAlPw96WwW3HJbY0Ul nwbGj+47Esb1aGI2uHxPyEYGWutNcGLiYVvRolf0+42hAfZvfebC9jXK+H49UnkIVhv2xS0q GW3/qbs+jsAs9sUUAGDwz9/XmcmaNgvNXD0wINKzZvS2Sbfz0C60uWNkbgPRvbJm/p+P37HT 3e0jA7JFlRCaZQJgsZyLQdkgg5cZzaY6FZOh69REy4wOEo8/txhZL6QZMc/1Dsjh6HyN5jeJ b9Wuj5XnrHRH64DiueZ+W/ljRQssg5vj1izQyKqN3t1jQlZPqOdsptGNOAhaLJlMgWaT07JE vvY3RN69LIDI18Wjdpt1AutiRSRI82wwfuxdnIhDRYSyRmZ2ySpGz4iz7HIHEnXzVnEa9XUy xbQ70ClRKNtOYCg7pWFhIF9BndmkbGz/rV8JmTP4ZhMnp5GXnZ5BDpD9Cys4RdXn5fX8YXBe w7K5K1oKOfLpk+QGc8Xe02lphvnvdYUoOyJ8JeO5RlhOaSbDZQdO+iF7LiMaOLeB4Xv/dBKA 93xElqvPAXYu6lX5d4eIbFvuToqm0kYoLaESsrN8sHUmLM8h5I8yxCZuOSBlbbsXyHxoh2i8 fta7e2IKIIp3pq0nsLOIJZrlwZotcVPJ3NscInQhVcI/3pCHE5XYmB1LYd0TJd8rcpz8CTId XcTgs6Z/vlxDq76vYJFPjIPuSH5GjtXGVYWrrYKbyLMW4KNzmhusJJWn+qVe/b8JQTXkp7Tf JTDjn1dsPGnyV9yC14Yq5lvNIJod9vIM9dHcn+EpxJM+q7zT9tmX1gfxDPhmEH06DcAx4MAw wp1OLDXiDXuQJqVwERApIK+FA1FcjXRddYd23Tjf9oY+gv8+Erk3nOmovC2MfW37Qk2HYx+4 Bp/2kSEKEUMALs4JjEnDu3iKrBz/RtXuuejdAJM97reOZxoNhhVqSMx9bGLF/rfxxKf8jk+w NcHL/WOvNoSCdJe9JPeWa8Oqkd8ISuBn7+zQYEIOloRfTBxvYwyEJW7Xn2xdfNISAB+9ZoQM pRl8225HIpYAy4unVNeY4sjdPeqSnMMZwYu9R3x5qxveJzf/PjWfPUaRCSoTiCJJ3lt9PYds FreluwKH9vRFOB5uvU365ax3MIwtweUrtpGexzN9m3q7ofhoKTilfmFbhgkx74V7j4y0xO5L TPzlXEVR7Lsm/F13lVic3F3gPfzF4K7D4xSadKp5oZDPyjGRIR7QDcGx5iJyjMPMKjl4zj+f bSqldkA7HKWNkQTo0eOUjaa8lWCnr1TlaNLphC5H1K8cYoji+DIK6lQkg20i/edINOl5toas MK9kkxno3Y16tTkRErBLcR6ucnhfGAlNO1TfGM6EEFODTRH3TrSaQAGdKCoUqvxGJH8YLyKY LHeqFinvZaOiqU59Wk2g5EoiuqadtVf62a4dAZja47AFuGLPcqkhu5oh2C1lfylNn4ee87z/ RJZKK+LfGKLEZLu79XLU+GEde6Bq+NC7whnOe2Bne8ai9idYf4wsZ0icYy6yL+KHbrkSdxNo DFz8NVHz02K0D/NCnY8xYDcWGgO1nDbyS34zwzjb0e8L/aDoTUnk7spgLykTBnriOhgQFe1F FrAKY3oD+3g2oAFIVC6CeRvwP6pa9O75qvO+8FKY0/w+T+5jMxY0dCmHhOT81uWH6kjUqfCa 1N6BwtlF9wSHf3chh067kY6buUv2yRkJbUJo0LsiPJfulk6OUvzcQ5pPvsZmsuy8RySUNKvV qijqwtkVPyvFlEWyk0tPhuVd0LyiJzJT6DLWCqCKI26bdUsrtr+8zYgiwveQrSPRjF1++r7r jAKgFQLgHYZT9vcTzwXcYW2wkbCSTRzaS9WtCQuqtHG2/0UmhZrHhXAKGZ6/bsvwlUB1E4SB mpMfmCv3dopC/WK8xIznlkXccMqDUhYAERa7CLpEP9L2Th/An2PzHa9xQgKUYXml+InJa4x4 7l4JZSDwvBwtXLxFPRFLnh5ctcxYnwoyVoShfV/eqi+vSEgE4pthb7qoXR+CLRo/kx+2JZcM 7kGzzC9UxD6iPPNSohNjbh+C1CXeKxxi4JAa/4ZUB9F9LJT7fXLBK7mp5FHknIA4/bzoAU7e uOILS2K6vvoQWiNzcnNy7I5SGue8sw2StEZ7nJetgabtRivLBFENyNBrOfZYIPcHZ6rjYLhO OEtHN5KwlZgXNO15LdMZc842vGDPgDLp1Rm1sVmjTzSXmuhYkpzghy+dwd+LsAApOU36Y0Rl 7QNwvflBiigSE5urqsnZqMDtlUtSFlAo1t5e0PrKLwy91QYiBXv++lcAolgJExBxWVpBKROq QcTWctweCMUv6yrBdNnKY98kLO/Ii7QwxbE2Ic0muZJgv4pBGgTSdmP6nhzr+ff+tXF5hSBp yQPlb04+0WWMYWBHfukN2ck54eviGDrc1Ozv8JNgloO4ICEDtIRraSe/PndZq/+0WAIVKETb wto46wsqZVgoMDPhXyJLNmjCVisLXGIoYsapENeW46zPPmh+LtFO7EjpR1CmqQpZ/qLdTVqL R5HTOT113742rAKfE8oTdUel7FhHd3Wxgdi0wdNeWgQnO6vqIq/INEMA5X2Gr50ScwAZuP2Z I/lAab3u3zFmT4wuP3AVEKBBZh9Q8jeXO3HFX1Nh3ulNVFCXL0NpKVdmDTsBgEKA0Cah7Mgh A02xdDVX9Jrk61KdkvL1EHBxtXpuoGzzWK6FVpcZY0I6kn8uqppWmH/+LFkxx2NXkyOZ4Hg7 sHgntBSGauwsretgMhemafW/uDpBwv57HBN8NJxlWnBU6EcEjNMJqvT9lNlZmJ0RTijwToNI Wemi5O4nRC6nZgo1TNSOPHI56qxzx/Nn7QHH7AWehD+xVhQvIc77V7cqFT50xWcwNh64OvSx /AX29PE3A7gvYCwT5791xFh4GF54yIZ5AyP5X1dzf9OJVU6Ag1c5GMlo2FZpAu14XtKhJjG3 lmGth6x7w/QBi22u5FYeos76H4a93A4wqQw6u/a8fj44vOhwAVWhC6NWU4EUo4+Q3d6/aKzU y0w9dQ3h6h+RDIRZKhKSNQyOSbGBk0cGqPSaXyAKLTTTu2udZhFLfc/TDsDkZwGFpldIkAPS U7BLwadvR1KNyGRxyfC10s+3oQanUXniG+/7xx4L8u9BWr7FDj/IA/YzeXkPo5+ACkgrhf9g kjv8WV2l7Doh/CCaMHUoPFg2jfuuBonTksekxD7lvoevG0/SZBodWgv9BBh6c1eryYFJqS3I x8lTYVSaUNO5FVUshfN4OsvS45KZIB0fQGeAWQFXnrnXAAzStEPNfSp5752tAnNFHhtww1n+ o4UFAo7XSkIrGxKkS07eIdx7B+23WCCKuJCLCPNRCuKCObz0Qf3u9P0Bz6rUZhfOor+5oC5V VwhvmNUzfnmJC9fx54JTtduRbvwvaIScuyK52oqh/Ya80b0oxq2Gov5t8oe6LUAQckn5g28y lrdjlMxWdVLTSO37bGWktg9o4wGzXkcLL0yOChsx+wkmBcWvOCeq4dJpweJn+12RDK3e5kDP 0fSx9p6XQL0vt/OcHU5Cy0eyNp+f6MtuLiFmoGo8cLGmVtgReLic3Vp1pObp4qizRkdIDXCX jAHEbTLJZ+Xb1Uez2dQzYkSQxQsU0IzLVWHvUNYqpfJiaL0ckmvRNpgXE5cKx004+3K5m/Bq JUUBwhO5jQ7I0uL4YGF5pIlWVAoksW8rA6xpbL8HoLlCzSC82eQHHez8vG+BNP4Ykg+rqnBm ZqycUF5moiNM2oTOuwJtktaF2msrdLLVNLuRm1KV2/DenwbZ0I2GRmkmBlEhpAL0ZR0domGQ 0Xuw7pJz/pGC5U4p+V6LtGpD/Ne2nZf35ZehlNhZfv1Hj/8sci42yNhfp/5WLHQ89+dL7I3n ZpCwsAqcaPmw480pKdeQytI5VtwoP0fTkYpvLrQA4dkPnQk+zFCDPcN4kP/Liq6RW6uBT3KO ACeEJ0OWAMvO2nxAixW/bDWqGTGT7hp5RHC/y4xD7Q682bKgHF6fZ0F2M3ApcO6WyRvLN+GX YPwVMnfUmk3Q3SErlnFaQh0+VDaN2NWBg6RNNMni7zgb/qdnsM+FwVSH2Jho6BFavCNyAERV FfiyG7w0u/5qlXyK1e/1QOCH4vuUrVaJ0JB8m4vbmrvssGKUvjm4zOrKvKcFPpiLv2JhuZn1 MVzCopfEhQrpbP5BQsKgnlQTU6Se42aejwwIsCNeqq3nyuaP5+VdJY1t7dkspGiT+Iz27eks oAkQdAqlHoURLJ2MQVzqgg0J+jb/syjBp8D5TJw7vALA8BrKAQVjiXE4YnS2qpz66LxxLPRO ompx4H3TB7X3j4Sri2WS+1UjLxNP/ncBywcF9JJAa0JGXLvFUxUrV5q8/oBaAyXZA6oOlSpQ ff7qQfVqtclhhd/G5Q6uqD6Q46q0X/41pHl8wftOPFlRX1P9JeMm76wylBzBbkqrNuvzxFyC Og3kBPxfUV28jhxU1SYHn0j8BlOnNdMx7v/4gUK3wo/jzT+HrZHQq9XMmTfqi7CHHzs5wfFo oX830aQtphHnQc6EVR7MoIfFff3wNaqvj9TmQ33wddagsf+rdipc60ABFwEwbuc3VYJYrGzc cdpMl3h7SJiZVb8lO6iJbmpZbuZKoB3b0gDCI4UV0j1MxgjfGx36mfUjMWIJhqHHzd4CdseW eI2gVCMu7HVwQHdLlzffig8VryrreBLkclJYs5XrCb+VbaL6JqjCXxmqBUGqNNrT1erRqkB/ Iib04x4VhevreYtn6Zpe6ifZ9pBokzMnDVJBUDjpaUhNIrUnz1hI/gyHclJxp35twesmZsM3 04n63TvKeKjNRG4XyUIjt+r/xlts/ETugjhy9kidE1NCXBnKPnRd0qTFIP+6BwJ8L42596/g 53IEF1dMV+0iLHcSAqDD4Q1M7O/GZ1VN+9sYoHF3nnb6RyaRd7gM9Hx9sp5yJcLCUUyWSLXV bLQ/bdT6Y1+g4tQkWEaou6pLTEstEHnLynY7sLzcqpnOqHk0GLedkrAQb6/EJsiegtWXrAUE c01G5ZkJVYpa28ZH2ZXQDdJY0FBp/I8VJwxspcbCz0NDOeuNwHdsOqdmEEBelkECExsp2O7R EN8S1vNxLLxOX3K6nerTanh7v4dz9pFD5/omcAlG/WMTP2C0aRUas0Xkhc802eB7rHztAl00 t8sOU3c9QvwI7RzGbezeurM2k+dNueijphXMqmRtg2s1SDKxKJ+giI1NFQrMX9ABpRJp03U6 RgRxZ9a4WZlWXxrPVOFKf3ci/NFfGHoqRklWUzt0cwD6bp7NekIY5b2mrfephNUJky7xow7P oC4uTT2NfZgiZc3wUEeHx6E0v0XiqgPbDMyn2KoUslB41vG8kECA67r4EoNSEnjiXA8YJiyp GSUzR0oEHNp+emWS1OsgQqtg2t9lbhTitl+feDXWqt/LwWfCh9eZxtCN2DMPhXuxu8uS1d1g E50GJ8NswNbUI6DqxR+kQEHtH8clJU74v/zC+SPwmmxKCiY7VUcfVx10QQ1CTBKeb/OA8zjb xCRuis2jHXkHVGKLsURWTMm3/X8cvRrap3E4aFXoRIm9B2yeimaaqreY/6JUlZ19gkIUqnI4 X3wR3vsqrynh4mwdi7oPUPZWj6sPGLRLEsqyvqEm8Pea65Z3HNeIpFCwfQFN4iDe+hkbMWph hMqX4wehYNYDly7rgToPAWn6vmu9WHxln35Iea479HRgdVBN4+NQhit4QOPqFfrurMXHHBrx 4cZb4OUiShn3xMzPxvzYp4JRwT/xdX8wmyFtqkHBgqg5eSadU5tEMItaBengjxUeCKOPtFjH 8mFZx+AjO++ONn8Oowzj7Zavcgj1h1e0VeKM0xvRrO6wVTosAY0VKWHN+3HIhYfASgGIYEX/ BchIUL1YPaVDEabmgkV8Z/xcBkBuJW6b1mSocxbzkL0ob8ru597+cytEO+7W0Vequ8RiXHDD pu9wIAG3DZ7FfpoyMAlIOWKsN5JzXJhfxO8zr70NFuPkwVgdL5lMlDCo7bM8r23yOmbCh4kp cuFvO9o7jzbfaQkxqtQ1Gj2f0kas2t7rzdNYlP498JuH/JwprYqzpK20Z9v84ass6MRZBQh9 aaos1Ps/c/Euzx3BFnuGVikWqBYVKy4XfumRDCIWW8E982xpgiQGj55xhX9UpEEy+OUwjHS6 6JCrJHmrPAx8ryZzQJwxzwNJ7aW3ztmTLICc6lxdj+JeLSIeCmscgPizYCAv9HRmLZNvLuyz GsLKzYP5wcgz5tJm2/Ap+ItnWyaOlTJTaPu+eXN2f51YnDDLcSV21WzlzkyMHoN8MWFU635E gAvRtQHG4Abm3HuLjL/RXjahCJcp3TRTrf3DqmDkqzNHjdbbRKamak+5fZpCh4I5LCfSRPac ON3C3scuxlBnvYMACR5uFtdZjLt0yFDqdAl9b6r085whLvJ23fRJz5JRO+RqC2oZ829KdKZe MmMSCCknrJ/cDmpBLY0EaDDe/ewFDsWUK34ItSELEi+JIOsDBgv2W4j84BH6dkoMaIJj/aQj iqY6v57UwjygnbJUjfjVBDKxq9twWitgOuLCc8/eIwfyxz5YCsn91i6GHGqMxMmxPSlHpdfx E8XN3qGdESDpTrMaV0u2bh6cxrh3LcYUjfyDeJacEOxLFVSO6va45tNCo38kS0enpfOHM4Vo akdgm3fdWWxeSj7NRMtexvigtfD0p+5cXLvwAflGxv/+/A+dIZN8dyv8L1kROwNUO8lDxN5q VIEoWg+jYq+mgJD3Ck/+wvXFXSt2YAhcBmQ3RAzkUlyu0K0PQLVTtOZJbiC0e80LfekSTWEa /wrmkoeiW3tZ8oNL8MyhE3DAkyLJjjtjHuOMN3fOT69h6WMvOXlZIqQWwiedu/3NmHR27MfI hi5zslKYjZaq00u3wk/Myc4O/lvYs6DzWdOfxMFgPu/eqWEdDMqvltgOtST3jA4FIr6hvtgK XXyk54uVD5KsELlH9oZvg16RU9Oji++EUJlgRskIVHR/BmDktQDqRHKmt4COTDpkFyBqnZ/r 6bol4boivJvJTcQBVxSgmaPbDKaAL/yzvr01bcLSUANPJC9swPzOJN1m63Q+O+vptJhJP6lq nk8XHRDa90JK92RMxIAC5eSndG6yjeblwNsywPoC1G0dnndeqXrKp54Tpy7NM+O3ieWxEqbc oH5l3bBm7qNKrpePVov+YLzdNZwyShZgQcdmiJsOUCl8+7eXModBWz6sB7+3lOozKwi0zotl 5YJdtYZcLEL+SH8+IhiAS3Gzb1bI6av3ezna6SRomODc2OQtKGriqQXHGBgptFxDen/0nnyj WVVe5eJxAgXTvwDuHP9RhKK4D5bG/i4aOXblTdyJGj2zKb36n8+TJAc5G/vp/rb1EMVuuoNd NZkrLhSaMX4/RqDb/SWOo3y9hpO4Gb7JMkT7cDxY+ZvvoICoiMOoVVkkXp1ktDQxSJVI6uFv Me6I7QKtet1FpDPbTMRhq1uAN58igCQjmVwhbT4LXBX72VOZkWjbCR6HShXQWxG5K2hKbf97 LWg291jjuJgIat/1nYYBLLoNgHuhuwhOUiVHJvdfKEJYGCXXldzoZ+vyM/SZqR/eo22tavyT bYiudOFn8aNq99jb19Q/2BJwyWM0OsScchiietJsCuFvAG/ZbJkb4L17n2a0sxhzg0imgXy7 Yq/8u+0DjkciywptyTznv55WSrbYhsWCYzsa+/ijhDLStZEy2Oq2/1NOBFevIsJfTJsufJdp 9gcUq5/jis8ND7vLB6wBVG5/KB9fm8P3dcYr0VIE9UsqwyKXG3fnB93CoGCCYV8iZny83ZU0 aNNCyBAlEukXIOIb/9+kTR38934bWKx85+chHa8TFEthwbF2DnxoTDYcB8Jp4upGNbAKA5VU /nKMqU7H2rax6jBfG1V5KtyqX+Ds8Atf6asyKJSXRAC+/ACBea8VTcR1McngaK/iXAMeEzBH Zl7epo7XlPGKN+awo4MhmAQ3FOx9CHSvo4z2IFVspC+pyMssMbUIrIYnBjhESlX2aRVq4+5Y x/WctFZW81ClbdDwKWC/L1lORqhFGQTkcfLVkkneDWAqTZ0JvXb0ZBBL0bqqEKeAdMnWo7Qz D52eOf8ta22SW6LSOXrwnnG/Gh8jn/ozf89BneHVOB2tN31G7wKqGOnWJ+hFWYbwR85yX0IY UTmLMZ9nHveGpyzIb6pej4o5DGBR9pNGURzNkO8EK2PHvDHYaw4UEniti0W6C/vjahcXuSzg 4Di8LHCntxgUEIiVFrbUTbQTblBF7xEC1m6DyhddSPbN9kDVpi5Rj91uSSFPRBZiYzCLOhxg MZNCKBmFVytAZFheHkr8f/wxNttzo4OPAL6AQihyeYnKZuv/HDAv0tiOcXFQscHHRplffBfA qispZ7F6A89RkJGpPmdFNM6ducNnQ6qAFgq22V0ZzZFKIP8dJwJDCxhK1Icp0TxRMb6ns++J PiGNWPie6d1YRFhf6n5nP3JhHPRY/G/NWIhelIwbFMDwlLCkMZ/Hge2/8ruc0QVI+LvpyfpB nm97WEZcyYLpRHn55ux4KcUDnZYLQRWE+FHxllFHRXzH9U3plv/QWVClNaHDYJOk51YHhl3K MCyTX6yJ3vpoY9nLra65r3RxwM8Nn0qglGQzKjGGsLGMvhCjl8SEjqrKaNpKSl+hyDX86kzJ UhF2ELDiSX/dG8fS/Ihk5KGCXnfW8nahOrDMJICjd/+hgxNUKpOCxQMadHYzCmmWGWZI/dCJ Vi38wvVUl5dHALY6Nm4tgLsORiKvRpn8kF3gIqt9an5PjC/AKdCTz7r/cETFUScLTqgpPbLM 4uMqDuAGrTOEgeEB6aW89ovdDdrt8sjNWcXwUqMYwKXtJqg/bkpSzDYpEj/Aa6Qwuze5WE0n rptJr6GmA0/mTPPuH0Oxc0KPrypCsDQMtA1uc9tLG48gKseNCUkVVu0jXa10qkd7+L0sxsKK DANLDzKkjfMTjnF0feOZc7w27lIeXR3QhSm51oz9YD0LzOTQGyvEHCUigJgBcXDpIJpqJpe/ G9kfybT/7ijmEKZWaUbV16PVHpsxi0bclcBUb57epCMtsE5LWJtwD3qNLMbKSum1/91i/vD/ W48JJkb4spnXVvLHghXlDT+cfx0rFiLbyQMCYseJ1AKxOuD1kMy1A8X+hTcMRaj3j75Zt1sq eY95a1NstaxcywU7obQ+nhL9OVQm35LYYfn5Y1kiePENpqzBXnE4Ctf9hG/r2BpCmvuT39rw 4NOP5lGvDORfTI8ZrGjg0bjem/g9141TNf0AdpYJFTU1XXNqZHQv7zZdENuXaBXyHUDxIfEw DWSOW+Dei/Fvx928UP96ctRetAPy9Aogt7CFLP11K1i4o5BOP4vG8UXuNhzIJaTIRwkEM/MZ FHLtNPUV37d+7CrsXMiMHA1LhNkGVhFVTtg1M4z31Gt0T+SF9fXLcSs1INESY25lgRDTYjQC j9/tkjVk2b7Yi6eJ3unW7qpObuotHr2eVImcnR6abY6+yeO2Ddnx/mmd8+KUDuVn8ggpqbqd zJNZ7Ic2n5s1lzytCcx2vNsqRBe7i195p5j4BODFnVFMF9PYttZQP5fa/noReexDl0NY8ov+ Y9rwMKwuvf3FKb5pWLuwTvmRgymgsjOtd/SQjZQfEUyC7alRNhxgroDyhjw83rQXZgc5LnNc M7uDLBpQ5+QLqgtHT5auXaDhFB8DWp4W2d419e06lS0d+ysiZfCyqqglFKPH5N/R6PrMXMpE giqb4509szcqR5liqHU/47MKXDQQ/5stocBUW/gO4u52Shg7/hXqcPJ3WDhYmIG0ZPXcIsVe 2XNTrI69/NbJVYy/MRJK8Ys89V4jUFphAILgUua48lKWqakUG77vtYMZG8I+dhhHfu4ADZrz iJDt4NpjINmXfamZfy1qulnLVWiHszidAoVu/KwGlUIl2zRShScCsUtsc3mUUk6WCcrT9Mg7 msBneyWOyuZf+dIvYbh6F064NfjvO3F5d+k0me/FeuNx4oL1HHLjv2kR2dMKDMpSJMmtC70+ uT+zu/zNuJ5NupIiYsfpA8keM9sMGs4sySBaAT4SuOgvON6inGdcIdek0vFuphLfDGPf8KHR Jx1QwD3EykwBDcn1EcwW2N19QaBxk6i0rarsfWjbv7szytUa8MXaiT7lnc0ilqScnSkOLOJq UVOmnH0mTKDjFMSMHiF/+T8QCZGSkpoTvuK2Vump0GLbMl7CY98AseBsz3GRE7TYi3CXzi+m /U/LzhIUg0nPwNrVi6Fe6P9jCRbYfwvheIju/rjdyVl53QGaxAHvPY6EDGLDz9FBMtQ9MbXH k8dkVTRliioiOUztpkeM2yrEpf6LT6Gz8MP3gdma5/nLaKb/3Gqip/8Mf3axYGFBfL//4VVy VKU+XibqXIOjN3HBaO0WrNSQ8eBj+6Kl6TMLH1qtRCAjnetSob4ATUFYCv6FGeCNSvFLbJAy vBC3dM9ymjZ5mowuqQekx/QqmWXRALUnKLI9cUvxRQRso3yVxbqqlsSZ0q+ZpT+v58GvXUe6 eAisxGdX1sZ+rocjeNRyHz9LE0HmXU52EmmS0ym73TcH+E1NyQtPMcEOHbmI130dvfpDSUmT HUEngL32IIOjMtS2AxD37ojB3De0cgei0+EXCyVRXhWAj/Mmg/jU1XJplqb01t0v6IhHt9Zk LuJ8YYS9lUHMVWGMt8USrVrKqy9eGGh8bSIAv+npx/toObRq3Fi9ecm7lXLNPnbuPvvcdUAR Wjh5Gfcll9VX+ZMXGk/ryxsyEdUDKyeMXs731EHxqQw6CpQNtRUd/CvgsdhsvAPmu//P+ngK zgAH+PXBR3JiiJ41T6CZ0Jg2N5MViWiqKkP97UhfU9WL6gkiIZ7u4+As9zDJcJ5WlnM6gvWT tzXuvCxhkFGMAB1Bw6waET/50aCB3sjGEr1I4moMcRRo29/gZxoBtCsGyRTpWcmPPbNYtqKe QWh9aCFAEQUWfhG0J/8pNONy211Tp8Zus4JoKqC3iM7DSK+Xal+jiR/kww5Q4WzaR5Wj5rQ7 k45smFZqZoe79H0Qf0VwTb6IGrBOzlHG7NSAaabIXLgJLDQjBLHYU/QHQBj59PhAhftUUlWV VJ2EcvDHdS9uI/biCSQ3TkEjr1S3j/JXh+LbKtWHkZIOMEYI58mPOMd4oBe8iGTrx5PoNwhP FQeVvk0me0DVCfE5RUFhrbfEKifiQDLv8FF450H0GPhOnb8cbQ+ZZ6Rb+UJCANe3W/f8WakL Wo1e0a8DB+06OTImXnd5g2iPuMDa7jFWhhrv/JVFMRXckpeTs1NVBAcn7pLCGd3FhlEY0gxO bBAnlA8beXgsj3kK3Vtx2V7BppKw4pfPGA+T6KlxapnjN+yuPIAdVqHQMK3APGZmkDOHlaLP HhgG/wWGUeUatHnHblczSp/qiNkqgjeJFv84tgHKNzsWm11Hiwt06EW5Did+C8wG6W7ag0kN 4o8fjPofPCkGARM4I82xAnoyb/7EG8vxMRu44PcvzNEWkM9oaz7T8CBDFF+Vh/DsyZMZuHTP YhR9fpwu7xk1G3Bwdet+ltB8r4/kce2Cz1wEs/BaJDD5o6Z9cdWCz49eGqCKfl/cm7LVUJyN 6sJYHBhgDQ1HCrSgd30ZojDqp+8mXajmebJ+wXJ5NJ7eFQM2SWid+1GK0x4gMqRQxjmOKdBe jjMVEcTFhCQmea0tNY0PDGO5YHjNdmaspr4N8E1KuEW2+VPyzmtqxd1Jfz+VLdPhZUJ7YZ5u lQSXyd4FmTR69j3jO+LgjoVq6BUwTIzetQFX3V9XCK4ggtu4aTlWF97rGoYxK2doIzzEjMaZ HSU0rh0DxCwGgsWeZUySfBeLGUqGH9IjJIYMo8e/ob/PCmDar5HfrKXKHSFQjwHTqo41Qdux 9NQDNKdfi0FejKlTDIXOcyeLRfm0DIbyJBloRtVlDOmzks21OFG0M7b2VFRb8RxveA1nPweB 4Xuy6pf67uP/ucw7kqZ4DVlfdeuyaAu0/sXSVLmSk0Oq5oZdjk5tzU10K1U4aYgNhPas5lU9 T+HJkTJmoV0jnqc48TedQZEBGLM9v1BWXklWs5VgsbyXRRWYv4kCcI0LIT7Lja7h3STlcBhM Ad+2bG7vZpIMXrDtCJd0kVQg2LA7ScayCng7vuZgKX+BrznxH82RgG52SYft1K7JXULyXgVS ZYzoxoLEgz3ZV7+a2KhnX+awiNU6ZBGXRglrwcHcSY580/pNXDY8iB4hTR1S6U13eY2QCMUm 8Q20jXygnBndyEz3UpMsdLjoFUSzN7SjSObND9G+FNp3/rpqIDA3O+FY5KWMmSWINGBMrrJd /Q3nUxIioGokdt4DkEtCnWshJogtkbxjx0nf++UbI9Xe5OtVcScYXUPN53oxMZL+OciQVU4e f89o4RhmxEliLVJ5jtZa9GuntLLMbaQF7wcBSzzbkzHS59sMrvDQRV9QO+45T/n9ncAfmJrX dHCanxgZ5WpWr0q+pxA+QRKtfECO4iXIaEEtfIsT8mwp9OyukNIw700xsWZ4bfeTpogo480f hi7e7fNwlhVjeF+4C+ysap+0nzd8je/4nLlyIElUzQC51Fhf7Cta8X0ZqxKGu9iRlwcpj9Kv j7cposLAHyFKdZOhD9MifyRwH5QHDmsjttVLpAbQDDpI3r/9fAJzy4wbcIpKJSOR+Iq6xzZy 4OMvYEMiqZMdVtp1xtlhaUaJr/7ZLc8G4mAUsQZpzUum2DaEVr3N5u57Wf/PSkiKKzExXMZa ypqyH0p5YcamdV7RedJLjBLOjeNkvJuvgGVIu8hvdnjhgg5XHc7xoWZW7g3LZ4mpP9LlHT9A rFU0HoUAVzFRuloIv9Av8FBHeU7Osy8aS6w330yTpMl2E41InY2pieltFw5lmddi2LmvCb4Z WnHFrR6M1IMDbFcsCBM932nco8Tb8q3D72q8Onqd1Ugj+BHq08uZh6NcO9v33QLiueeYY+Nf gSf5xyTxTz5vv/xMIWZgIQYZikDjiU3yAOMuxiSUtnhABqjC7ZoMxGoyzbLaMWbP9HQt56UC JW+XvfCHo0zpe5Sa1gvccIRC0ku0XdA5hPbdDY60XZwaBLbbGkVTGza9ihqxvnkp0031Xci3 Y9Sm6JKGUQ338Xwqkcl8m4OUHzB+gS7YiBr+ARJKwlsoukUf3rrpIYowF8V0G4e2NqIzkECN eaCXU6WptwszWYU1zDvLKNMqOLWJtOEglpb10BCJl+FkpWOGsLkr+aMdGOZAOOQYZLPYzK8F S3281qvJhVz8W1htfqkFLJmJ4F2oK3608Tee+afUV73b3zlOgaX26JGgaoW7hK7gNR7uzxM+ uUNl13owOkpVmSaHk4xHukFKM2nnrCvjLI3gymDynzkM6bx0PKnSFfM923Wk8KJbEmsN+/96 gGY678cCzdtQ2BOFFcNjY2o8s6FoNOU/5YEJkYIrl0Ye1ZC0eSNkRf46hqVt63AOmJEZUEWz uYHOGyKudPrIg564iFen0K2IP6QdOXQKTqfcfgGaemYJYr6cMFrwsrD+yEa7Au8MOqAFRUrf MRXp2Z5Yai6aTB631BnH27JKRq5TsF0+NA6kJDLDz/jK8d/Cu7BKglWcRQ+bgOYfcou04IJN I87j+4Vt+1oXto1spCheI2g80ePften9dmvzj0qQfrK04fnfWn8RhBYES4nxkk9VXcd3pWtH wuRs8ocuFMcJs58tIHRboHTKjStD525k72oIDcdc7ihcgCs6ylGu5atz6sa5/P2okqYUd3sb al6CtmMcYgypofha++wZaRNmbFy9+9q9b38wkEqUvd/kZq11U59C4a5Vnam/VxRPZ2A+9ihQ Askiomi0UG5SXXVPupGoWC7KepP2REgbg8ADI9nPIqliRwH6tQf634lM1ENzZ69mMG14sr0q SOdYIcfExUbskho1W5scj/62YAQqNifQnAvZOV1G18X4GDJ115qHQJ+uJINV0GIZ+UMd5nAM SJV0WN1NXxh5iYVvnAMyUgUZAEF2lB+dUclznlmuqF4KYJxeYJr9p40X+4JF9Z5GvoLbnn5y cttbh+inRQ4Lp0JyKYRo67i7WkL3xJpQsD//cLApZH4RBUIp61Dv4GpHS636Nf7ftXOUKed/ EqqbXsYji9IJIzQ7t4mR9SwrZMJrSXWAVy75YRm6Iqvyc8vGiHGhvRpy5xmVAIGAeqtRBLsX wnQdTkIw2X4TSBVn8NB/OLNYazk128IOyx5iQ9DJrGdNbaz8I1iR/qLgXBriAM4mwAC2J4gP ZhXUEI1o6I1626FOwEfAfvsl7+pbl9uDAKIEQTg837rNvsZTkupLnlZMkYTxcDqebmCiMhQ6 SsTS4X+rcIK55phRFn1ML82/4ZzOAgqTuacY54npc0bMLbfkJDVEyE50pkRFkMuyDd7VFMOC 7JkYGhi9oEBWycHhrSKYlybE0rzCJvHIGV0n9wfsTDsFwNU6QSrKw1MTJK+RlyJmXcbJX9JH JCL/o+MCHJKfSMFiIhnKRbfMw8LG6UvZfqx98J2aK6FGXIbAj/l1ZRNmAnhN8FBzvVjOcAoT fboPi8cV+iGzTZNS9fb1kStqJUKhPiE+8lWVADsOpm/0TEqfDy/U18DkC31L4SQO8o9EemKN DLF3q8LygybNUj5cSsyMoFgA/DBo59zkJeTVBX7h/xw7BEL/tbIFWH3K66tAR2xUAb4tqyG1 DyvqFSCB8YhY6itzf2dnj+aqvc4XIKro8IjQu2Bt+nUy9v27eABpi+OWqK3iWv103QcJ4zA3 fbIq+E8+LBykr5W2Tm76u3at2SHkd4I6sMlLELwk8mIRXAtlvdoiqeNsb70JhNLByLMYursb q8yQOMIOHUiZouxMv8hOgloty3Qq/zT8REsjg1x/I5Zt/VID3IvY4rGmJI+MVNUZ1j+LWtAT TMIU0vrAxbH3JyC+6luMTYjd4eGdeYgozpR74jMTc2r5CJwqZQhmuAMN1YO/REs4nsWpWYP8 EeEoFO4aWVMY9Z7vIFhyRyKwyL4hnhUBxFiLbEKxODudXMPR3MdG9t0lnf2JMUNOrblMnSGx aUgZxpxiywZk3diffIKUy7C0f4DCRMiACPVkRxuhd8BEMMUkMSLD7ZbyNpj92oD93cF0KQA7 Kdx6WKW4Odz2ar8HpITMAbaVWcyy3rc8MUTTAwYTlQra/uqB4jZJeoPVEHUHORqoEHxg61sI W+4SyThN8KEPfTO0pJzrAZ2dXm7q4Zxty81Vg4p7ZXafKq8DiV5MQF+IJgHut/10JQPiyduZ YduH338tJbcfWSkJP5PMd8Y+u8B9xjTkk4CZCIJAY4NQYmy0nWepvUm7AHQk6703y5lVdT94 YQdk4F+zpJoDWdDYGfflIJ1JQ1CykiREDLoVdPmUG9mSWTKedqull7fJM696SNa3q7tvPiVJ t5QJwukAcoZYDgXYvQD+IRFSpyeSMCz0U+PFl1do9C/+Yw3Ga0W+6ZRP8Ei5t/Tezxk4TCsi eyPGHKXl41exVKDF751hk7QxXogXTT+GXGHBpH7icRV2nWEh1o4nVzygVqGvim+5XGNeZ8MT yBUHwWJsNoywjxgnjjzOneG8Aq790TZvXDN+DXcoJ+hUt2RviC1m2ORI5yvpJhk16DxnhRi3 8btq66MHKxUFyLxDSOpHdIZ8wge0bmIEirZXurJZx7l7mop3ojd259MjBJu3wz0MWKkrMlAf oNsCXKD4x/STKcqTSWMl7VDDcZovGelXRD5Zoc6NXKuDnhc4IIp9DD/0fy16MOLXytVYU3Cw EgvPBCGxDejR/JUYIzcfANJCGt+KiYnj9+UmK8BUgEstMd5oozko923B2RtLD1osHp11rQAa XfSJ6XFCdBTRLFE7cBxw2RipILKZncMuWGZtJcXv9qFQhDnH1QDmmc/fU7fYARtxlotmaKHf QOPJKu5i87IdM828lSlawtGn7QgYddL7ObC1epvxTbG9yIRe8o1glJmfLEUk/0wtgtZxeNiH u92gC/89Qf3YqcVuG443dvCoQ1zlGeUm/6aDkh70a8DG6HO2/w0A7NNPMMyexaQvtftlVPuc 9veSqQ4716dspLHbtFXjhMRjin0tTVqfn5OaFRBn39BldHcEuqtM416TljPLTtodFWLW6A4V wVvJrQtnAfxLtAzXCQShVtzf9eCuldURXsaB7vvv2eb5bOM5CRMFAW8F9WVP6dwgkuFR2/84 E/YQGtLAz5gqCTOQ6QmzmGywmP62UO6wDONrZ0pRC1P1cQ5tamjDB6GjYEg16nb3ezozMzjH umBALhAQUMEIgSvyP/6ukK1noa63TSbAbJEH0ygxobQBgyI4rQkf99TFqJug1Crbc/vkDK6o 507RQlxxb+VW9KALReC6JxGvRbV6ZJmFGfMOWH870zOwRR40iwIWLt2/0t6eJuzc8WtZP9nX SpZHvmzubPz843FY3bAv/I+S+o0Oa8pyiGLUsG09oa6nnZGaX1diC9SzyA7RcgE8/VNwcryB ZTRBdDONO16gLxZiMb+jIUjB3iSJHNwBV8kQub0b0Uc1JbVq065VqKogo9EHKaP5fyocUYmH olezUBlXS6BZlHyZANPEaz3j5Mnafk3ku9Zg3GbagF0KU8AwnC6jB5InK3QEGrdbVgEfS1q9 Uh274dcOFmfClny7JOxEoS1QVi6S7GbYE5iyBrbCVkrMbMi1LYk6hw1IzSuKVyukJP5VzI/U 6QtSsfv8MCTRbPH7IuKCRkAwJI9LvGFX14miQcv11tn0qfJOoZlVY7ArUaB8gMhs5HXQjXwF 71+S13e2CEmvX3Y2bnibPRGVZrDyKKTurfpRppKBd8hm1NEtWiTkiGFjbRUP5GOIPLXAk2R3 2wbOKUtWZ1UVGHYhpbym9fkJcjaRmjd11K+k9EVyxUeGxmp7PO9hrtr6kjccvmD155IHfNvi UyxWrTCBIvjCcUKXqCgd6oJoUQPlTYlZHzRy9YWOrHNvL7sTLGC6s8n/TIiCVdirmyjTRCwp DqEnM3xHBi8JAUrl7IpwFSpmNu8tvnP3cDFb7UDzoDnANXdpoPk5yHUNcA9w/kvAJBZhEnL9 jBFIAq4eWNT7FFENqw7XZdBHG1L2Svki7cq+yKin+zHeQ3esIOuPoUWJGzVeSbTefnhbBAwQ zxiIzONMpkcjWm3LtluXpe9Qvs5VY08Nk5ovgYDWpO2B80knLv6n4c986RB7BuXt4ouLwfKp s0sutnx7h7L7UQURmWhuSHeqV1J9QZzpes6c+85gSGvMZ8mxi+gIHa0hhLcKJNTA+aoQUhu4 vaIgmE6lbYgUY3xNyCaBPf3A0bRKaIZq24H+Nj6BuaG4ZenlJY0sIIQRFxTDTfCYq1miMnCw P3mP6Fx5OdMlopeLZMoXzU1AMfppLw4foiYhNmLrfhgLLdFWoT584E2ESH+uElp/w3FJxNJi 7t3lJ5FQ2CUac7cMZg5scBKOtpDTzM4ZXEEIIh0RDctseeROZ1k37cWrWBecsbKFANBfc8Ox Ec/ARPRh5CdlgqLH0laZIPZ0qSqbfbYqrl5IgduIO6sZTTT1DlqMp14NzIVmLrR+iBlV1kcY KbDwzqLAFtwarU8fZ7fPQ+NA0skXr0KxGl86vsBLNfUEVgHFp8b7LqO1KWuVZCfNK+hessMQ NmIo1IqweMNvFYrr+ylTtAClV3+TCrYu7UeAC/eQyjrJIgW9+eaUd/qEKddaiKtli40weF47 0wAXVmSEriKBTaGFBuXYxvxOIfNXjCAUf4QN57EPn1xElilg0dDv9ul9TS3Yl9SI080hfom+ gm1GsDgCNaGOzeyX6pX2nc6QI+RLak59oC1EfQKO5E3w6V8W8C7ZhErRgQ4P8JRUgNnRkvQ3 vC97rHf/l2/GuBsObybo6Eg6aMt6VUbCzVEpCHvP92RWqMGRJqTSwvNyEgOcRsBtuKL4/5Xr WKmnQjK3ZzOr6x3/n6osDcLhzoZbI9SKXgx5BNyJfR5xnliIf5xL3bEDCk2hSZxzcGfFSWRD z/ekMN/hb2QnkLryB2CtoZaSWArvJ8XB5yvhy54cYJyBpFe2rA6ll1fmjQ9B4l+N/I0EdZZx l6GuaSjIacfj5zKmfYLm4UYSklzzpydCV6nAItE/yHUdg77JZVEriA8DB13JNZMzLMEY3Meo ji92KnUZMzqQUSujtwdGxvXlZtN7/qcZFILNbcJ93Z67wE9NHa01/4WBLhc6Vp5LJ5yCGkrv sAwuH+keLYHQKI9N1I3afvZSxuqZ32tBdNL4Bv2+F50DmuRa5TkCJspJugctEMw7GwirV94f Gnr4IqW6+PCndk3DD8CLGcr96kYFil/PG/DasXbVvFeH46sewis5oroK0VuYi7rKSYH4i3C/ UKMftfC2SfusLZue3kWfxWgFz20cDj9PbI7HIr2kc432tHvJLJR9MJmbPgL98h2zmFsoayX3 VDjRi5yfjFYEmvpIHPle1gxWa5pOU4iCOf5rafjLYd0Tax+0854lCu2Y4eJR2I4vew4PNJiL rAWUlzmXr8JTDKznBHR7P+vodK/SRqS6AaP1yN+hmYr5Orsygn0jygXrE15jkzhytazv8f9T knsdu5j1jDy+k/9I6xz1HOrdpgE6aqKfSuQUKgbbtA4zm91EZW7UemXJFprZVDiQKYiRn7Rj tA3iWPhtQ6hWW7zIsCnSemgxmfqH50Fwa6t8+wApN+KczfERCRO7YZj0NJc2+V3f7QS8EZMy 6dr2NhL+Q1d/jeTfkFvb2L4MmQ+3dYF7a9TPEJ53Un9ceq1RGGDefL2gOBfhO14+34RmxKTU c6/H5tKTIjb+g4nyBEpk/EXwmBpZjX+EhIFmdAngv4cmz8o/m11hGyd9s7ex9EkkG/9P3vz2 CpsRJMTkPMWphULHXN0OFF7kel7wSOYjmGe3V3dX+5dhmgUj7YLfGObrkHDzUi50UcYdSWBd /88Di5qIybHWyrvwcAA4WScQ9rxZ3tbS7NZvUg78P6Cxz+StIKylsnnJn5qXXV3zfWeEWMGC ZQkaLHUEOy/YgClgweIRE99uyVCd0MgMCjL6go/ESwVpFzs4c/qc7gRpPIDgSyAQL4HJ9IXW xH0mt+jnWWibmjoCZsPNKW0wKDB8Okgbp4KVIk+gFFWlBO0MTnD9nj55GzuItNnQE24GEshb SMz3E3SzF4akrkaLlQNMK+PmxLSqKWhkea5pTrPuaLTxopaB4mZiGFvg5MG9/RXjySNuLlU4 QrAQq1geVOoBhThsOT+qQWwFcYcCp/fwoo1W09ICVBi73Y02yc6+7pgqncoVRdyYTV8gyN0D o80yLqTLZCesSeDqwXFy0Tt2PzFd+CxiGBbbIYYKiW9IBCxcWYimyjgceM6WoNtqVdAuhFQE 4PQ1j9+Nl5+KTvug5CMtn1WmoeuB63WdfNSyWXLqHHIVWmkGgrAhszmgSUMci23pAUn57sM7 c9p+xxKlz4KEcUKA5OD/7hGrfXILwf1Y9CQ/FYJxRnUqPSmJx4r7NemErPSIe0nVHLBXZS/H Y8bmyYtktoModEwvdp8VjBORMdBApoGub1g7JKnXXkFtN5hPubGkzccxuGsxOEXiPKKwpgso SxEArRwP1EDaa+LEcOkJqQuE26la6zsIVCyyRJ2aY0mJ88i5lCrnq7eLh0vQMaOwKWAUVxv3 6PuY2T5yGjglFRfnsvWHR6G3lJqKwun6pZ3BYG0G3aRsezwKMbQg+6OlFDbQr0nNHZCoNgZb Dxq54wBa+Pwodq/CdyqsGwtwLKYKQqwitXcdm6hul9TXm75aDHd/fTKWJ0jpwlRepgGzy0bm r9PO3p7wxHmRIEvo2uaacDHk8+RxxcD8r+Ru4WcMJxm/MDQHfn2CIGVXUnpJw4cQ6cHnG1q6 2tyASSJFCwxWHdoqGVFEWMpoz33612r6bgEDVl1ryEsb9cKCWgFCK8bb6tAHtonVOuYZ2Yo7 7YKVR0DBLfjuTNFTV0oH4UaKrKjTC63vbHC53gElBQi2NfTOyynbOPgMOTaQP2RwdDxpEhZt 3hR25T3zys/WdtXuk2ZAbm6nIHDS3xENeykOLTY7+/NwrMRkm+VPMvDGIbFrHZFNVybjp+b0 ElUPqvijhln7I1EqUsyR5NCmLgfWLzn1izTz/9CiuzfS9rLsJ3kvvXPlls91RSkNu4+mALfO dNTyw2RgvQtNuSC3fplIyj43o+aKBcEsqp0A05MD5C8lxKNW71Ta961jnMrNwtfIr30se2Xx C8J5333pNkuREMjInLjCtQGhm90JInuVxCcpgmGxK4Cj95JZEE7eRmFKLVUf8HUvCJJYtw1h BigHhyc+VQHfUpYM+Fj+w/B5UqGDdfvUwz8FTFI6EDHkTwI6/GTfDJutFikAvQ8x7Nzeml8y C9A6usdSdC11Nv/3aajWUk/GeMg8ada1sU7/hUNtxYJgqY07415Qje4oIlLOwa3O2+pa1BdV z/4g2+lUQjfNClvP6iVzxyTno/FXOT7a0u58n6v2EwwD/msS/IFp9U8r2TMoN/sQV93svT2y nS0IfvakFNLBZQNQQ4GNWa3KZ00dWIYh6NusObq9wrx2FVSOMsBLa5/1x3bDLScBflT7asOJ 8Ygc1RAr07xxSOe+BT5wPYV3IOoApnw6BmqeD++Uolh+KW1BTLdzx7enF7MXyR1fdQzK8uV+ QDWpf002KdL7TqA5T1bdiOCGKags+0KyWn+Bf97/2Z2KThHMcmKXd+LAHQQLtqcfzOKVrRaG 4y92AtATTcp7StPaSTiMq9dkGna9x+XvXTJqc5nHR6sjU+S2eAz5Pf2vkwcYzmdP8+FB6ULw KgkkFYnbsXsDJf0m/mDcZmlJDv+oHdRlJWXZq0lgYr42hfTl6eWY+oDer58DPnqVkKv3opf+ 5fxNPcrPs6hZIbue36RZ/g/vLHBasf0KWzcW0cbChdUjJU2yReqnMg/SwJdWFFCcGmNtmVDy q4MV9LJeKA+Y/x8iyUrOtsQY9YDiNJi56ekVlCHQgv9yXFu5rsdnZwkxidzWq67nzAxhlD1s UjWePEHqY0vRvh0olgZuHZOC16Z5TU/VeEDY+yzK2ZcY9Yp8xCHWFYNWKhdFPPBpxEyzqpZY n0Y0YvwfSuiinG0ftfjH2fz8C7ym6cxlTfDuqitjlydLE9iocrVQEz3SH6NyDFVXU137EmoT LmsFsSdXcKiO2Js9C/BjMsZ3tqxU2w2XS4P3sx7Xj2fGKlgl3Y2XK4rVlVZRxh06IqiYPlx8 bxprT7rudR3zh/bxV8yCZOK6Wod26BJRwAYChkWNLVgyh4PsHtx3z9DmuH3ZU49qF7htwm11 +SRjiMl0nUgF4i33RHHrW5/LyI+JG+RmDq+RewApd51l+gfExLSmnGF6RSJ2NlVLJ4Rrqque F0xMaubYnGXWglcrWH0py/dBOKaCHcBKygtlcD0W+K1Bqi6v/40A2iCRGEkd9b5ZfpT2mmJr Mk5p/QSzvQVNHNBljWOVVcUGr/HZ6SMNa3Za3EIgqD4tYOHr7w9NdzNQyc+HG3PwFVl1wpDY vuHck07pb+2ygERDC2VVReedacsISpQyOMFkW384TWGZWXUE6xMm8JHUMwDo3GT/yXHRdi3q SBF9ZQrgcM9tlpritgYbsqcOGV/maH3Q8tol2yCMtAdkU2EZbOwn9kM/WpQ6CbKon/RxmHFJ dJnie8j7vDoIF9W+bkKfTyftUnAtUvkBgdS29L6aNMzr3xoAvf7Ts2HpXacEvKOGBP/wc0jR l9yznoaPFer4vDC3rf52xUBKyjeKiBC3Jo4pk10aEHDVmw+Ymqk4PIJd1Xrod2SoJM5ke4Df HXuDKMr0WGhMLMqqZ5SNqD11Rhut6Mg6PPzm+oVwRPWZWIgV/G+tZ+lOhVRf6zKA+i41VjL7 2ulkI6m9TTx8ctZ38rLdyWhhANg+caQCybMsa/ekHxc+9/H5UNWT/QrGHVB6ohBbC/1EJls1 WMSVMOvxy3xAAboUlXeibeFYv2+/iygWpHQiyGBpNjwcVJ2n/tR7cuzlaQzirvSA5b+EL4pN vBh22ZhvOZ1QTLVxr8XGDsNuwLQxNhb/ctUc9ZMXX9rAQ7BE9v7AOfhvEYYOVtv58tQamm/K jSMrtAv+8nEhmlZ9sseM1BSpKUYYyZwBxZfp2l2HpgoUd2kcfgqtcpk1A/R4IwbSEmqZpHnN M1+koacjaWiYQbw3MDnF9EuPZj0SmtXHbWwAcwLrteOOZRfh4D8yLpkdKAiQ7bKyAkH3kAAx ddA3WcLf1YXCGQHb/AfVgDUXXVZ2grPJwFeQaPvIkEEu5mX8QVyWbrjVWd/cMtLm5ZKzrhJB gm2qjG1xgqEIKpl95GLJ1c1nIxx1VkcjMLFnsmD3vBYeUBmwxLsaCXt5m4TxKbkaEwdU4wmW KxKI+RIAcjLXxvMWcYFzhXVxwiNLzIbo3Hy0YLMlZLtBuW+gUZUg/gQytTZV0T7pUT624eSo f51snfffMQtYWZN89vSmVwAKQeeY4TDFuCGr88yDeE3CRt2xnxgrZ9DUSFnTg20ehcuTH6I1 3OQHj5ALAfrwl0AcTWT3y/SRVbpfOio/ao+9b3JzCf5agalUdVEkIiwF84KQ5kMYAj/cCFlF bLD3/hlzQloWOsju79vI7IQQK9lm4VvsSTvBaJxWX7CzDQ9vtDoSnIgK0kco3ui+QqEB2D79 2dSkPJrafNrmOabB0/3kjX1+mADo95C863n43zU8oLDDbx7JxMexTcgBGmnlFLEAuoxNwbaJ 0C2jP20H2YJnqR8ryv0PW+CxA4wrzCUio5f5/CJz1LQGHqvO0o5qEQQV0+1l3KXxZj2byz5Z SOIbMBxaRyhKSR3pxR4fi5Ivy/xtURNXp9U6WiYg8SxWWOxmjoL3HJk9lw1YPwLklgGJ0XCm casY04EBMu3S8VP67yfauv9i8W11vwZvrbqyPhc29DETjqrTGvykp4Nz1f+PEArmSodVEaOt X+8+YxhyyicrMfdOl+rDMo/eruWIGJrU5wskXEg/ewP+2E4uHQlI582VIy5otvdUVx4klkex CUjCU/T/h9Au9O3OXGSf6/PXxGkhibN9cQeOxsAe30A53eterGH+DaPkZx4a05jRgn3jUypP WcUi9T+p7XZDEre543d5NgEKao/gZTzP9LqaEZ7ZLVBE8j+KiBOKhSzMs8xgU6MMjHSxmHTW 7Ze8w1m+f/d44mjzQCaZ1G16nGP/YJPUbKxcRMqQ996G2qu3uczL/ebqrkR23PMLa1/34PZc i0zDirRQUo2OKL9xPD/hcs6k2rxAfMxlw3qakSAg+ZJNN2D6oTvUmYocmQp3gTFn/UbAVgf8 jrSjmSks079Lz0A7s8uqjB0QCoAH2/XlSHp3mX+68WUiY8iagu+/3yTIfcg3rBmcb3Ouwpec LO/J9Ck4bY8bPueIAWrVG6+xo8nTe2asr/S4T1lGfJBbNouvXIjKFf2+KFQrPVVR9Kecu1B5 jWmUt4g19VwMbXkL/aWJzl7/O0TvnqmMlA9VO4uIQZ8IOTAZ3ifPkDN57kCwsqQuPlJ/q8kY JJy39lLl0PtaKF+/4zzkNN55FEXeM2Ycy4HOU86iwrIRQMntuVD18ErSh0046K+gB3fZkyCH Shgz/JfcvBLuETMH9+ihdX/OrGZiDywyXpXiBlobSsfJEd7pubQJWnZ+J28jIIA9+MU3vyKY yT/sJift04ptetOEPVkgL2rH8/bgaNOkKk8g03mLOXM1zwTlglQkvau5YFqh3Bvpdl1rq74B yyDTzT+KGS+jSVMzmiZnVFPFOMqyNwxSZyl8z5duLvMgXQGaXW9dlfA1Ka/gOBtKtVDI9At1 /QgwL61leglMvSgupb4azcEyKO6cFSHzjXQxBaKLe/CJZaUj/YWJKAIFHXvuCpET8I//5CmQ qPaWi27tDKLXWOP7nSZ/uWu0PAFkFme8UR28CIHnTBH7lytdf+OnYV/n/ZhBVXmTSH7ZzyRi fFpTWFBtXtBJj+SpVfcbhmRhddq03fVmdSBB7RGc5yCpeu+ERWgsti5gVTjtL2BJ4s/SJJcS zlb5Eb+GXmMfT323Uz3QUzkFEyQb2yH761FcyWCSLOFXmR1YFg0lWqkzWeF5gYHNOur/C3Pq 38bkfYGY36rIf1NGzQgML0vekD0EppKvLaMbmPRahFVCCUaPOwqZf7vx5Ll8Be6FsNpnfNCM 6HOJ+dBwkq8IerLe0AVGVpkCFsyzIhSEpwMBE1XmhKCaoo7r6BLHeoku6eUupTpKbjcTzmNx +5fvVFpsCIfpSl+FHeMH5JyZJu666I9amsb6eTaqs5CoLaCF6AxZ94IwZCAmxuEnWM+CBi/i v7/ERn2JnwPiJpX3DRjdVKFi5YCs8PNzqpTTqwjtiIAt2JhJtXF94qowff62g1NGOqL7CcG+ Gn6cTBMp9iUNssskunrun+aFuy3ht/F1jnUNPbCLSFi4KRLoDcLx61mEWt++ndiIstqtlibJ xCtRJg8EoPlO62RPDFBd1CoVAnEgyTQ9g5Zqv87w2aCRwA3AFRSKqD4nxMnOEV7o+bHX0zCG 2bXBH/PE/ISM1yFpdSOHOBkavjdeAEdG3l/ScjB0xjWuf8/+ENSi3mdcbF6SlI/L+dMZimbv UVWslmwUnGV5240a8Ele7ijudtaEQAnovCKkB3kcxiO253H9XkFmUIJTELk0negUCjh22KQP BASqRHl+VAgdYbaISwU3DO9MDDJrxGW6r1MY4fP+BrmLxXLpPb+nWhvvRqyxrt9qjTw95IQK wqJ7V0n8oRIlWESgF3UV/XEAOcp63bAvMMP4oCvWYV7KmeAHbc1Ur3LuJdQSVnBZe2RufoQd 2AhHwAmWwGJxVE+RWbBuPD7g+zHJlauzi0m6zO5sHjq6MTJNaol2kzAjUrMPlOSh2ToPYbe7 TAocSuLDiNLgZNrlUjdOkSOgqALVk7+dRNUVyAIdkiUuRfLaDebbIMBaEEcQDzb/Bv3GVoaD IcGvgUVtaw3Vm+Cs8JQvy9cchpFiu0pUn7TcrKQvqri3OobSp8ZZkAhi5jB466UGq+yq2auB JRmtHzGTKfF4SF4ODZg9MSi8cIsTWmwyQAYiiFNWIcmWqgVFYmRXHArxEbBORc91e7reOMEL IuQfRbFqCPD6zf5LgJaeZ1Xvpv8C/i5hw2zWduv5DgeoAKru0ey5MGHpmpXfly75dYCK+3+e nVyPpaZksGH5Fxo43qDu81x6Uvlrbuk7UWc/1MmOfcY0rw/lsuLcI/XPS9XiWj9QI2DxSUFv jZnj+KRi+Y4sNnQfrHqXZc8OkMqyqkss8WjRFYe6BG53BT7E37cahqcoHcbbpNYZXys6HEWd JIOQY/aWN7OvxHGrxgJEUYZPWljcsO568CYuwh17D59lO8RShLXVbJYAsythg1sq2Fbrqe9j IlmYNgqSaccUS0PvrVbZ9fWUJ7mvwGDZjp+4V3bF+JgrOXEVaxt1fFDwnVZaYPQXObCFN6fF ofpj/0YmNIdUFDHJmWCLP6fJwUqD3Tvtb9hNb/nQD43jyPKDFVDZDyeO+PijJDs2kdi7Y17K jmqOm219JKs6C1q0YPhvQ0jw6dOpUzcfKyo9WR7X5enk53F6DBcTHw7iFazpNWOy9ky1Ko5u NIjUi8RP2qKiMfPlNhYAWAPeyZHlwWFK2NOJt/CvVEU1+SI3CF6ZD0uwzF3o1UemL2EBdQRr 58j2heo7ebnEpCoiw2QiQCO39SjBMiIrAwVXvvD4JvMdjfqtnwjVN860CwOppNaMxRZG/UI2 oo8509DYgythiRKjvf6u+5lQuw8+gbCeHlkxuGekh+9iS8gEE9Cm3OI+dyjm9qcwUzvw0fMS 1EVZ3ihZkjXYjx/bd1k9Jd4TWlCs9rlmP3A6/WeJOa4kIADR0k7Dm6kjcPbBIbPUPU5snz0O NrlyAxJkOeYUUGMyVieAY2drMvZx5FdbFGnZIkz1XcPwREfsxfZUuJyOr6oDxkC6gZkyXNxk T1gbQvnf25FUoGZkk1cgSP57IlvaVUGxcg0UCxcOQiU7XCM2hJVAOCqAkQTdmfKNPxR/SovE CxfXB3/sXrw5HFNGQGMM38AoILe0Onxw3YxuoK+WAwegYeasGxq0MIcdBql816d3BlXWiaMu 5q0Tg9rx01mMcA/2GVCwvgRuB92+FdRSWVLsRR+hxoRv9hAJ1tyds3vVNtVO50cS/mI8Uood vJ1BlsNSvsQ4Lt9cbf9zbAOS8wkCeHpUjcQRGrpcWgmw9Ys4jzfzNuKV9c1h3QsmA6ezeeGI 0ZJzEhsTclR6vihk/Lt6lWKdKQ2/aTzpTCRqIzL28vmdxM8D/+ZbVscTeyFSa9oLN1KEt96k 1vcxLPYM+er4eoQdCqbMYtw+2UkiS84n0TkX1kCN9esTs6Xe6EB5GlvsKCPjv8AXJEetAaQ5 q5ewrh+1l8qDDjNvMXxf5wm9KuJWOXC2KCmts4ZjHATS5HRWj8f0kpiZLSWgRRS3DPfvfBCw /2rYoWu2f6Vnzli0mB0WJGmqOGdpcuvHWW+rymFelyU8jaXre3EY3ue2K/1zk4bGrtODQ6b0 34yWqYZbhzdpnx7rqqvni+IGqUZIjxJJd7tfHXvbGUqwax26V3rzWdweu4IL9CbOWuFFB8V8 +6ZhfCRJleQiAxQLdMow2hq1Xq95DySK7my3BRvl0MYZhdsfUz0An6mRK4NhMW4mPXYFt8RI X0BD0sJj6tc+j1iUhrBPY4RO8mJA/a7aEq5M93VAl4gWqrTeZIPXGa9YuQAzaSTDubWijoHP sQYjL/Jeh1fNED9mYFRxBfV1Vd+qeq4XA791DeYQZoK/1hXdDIQnssT1f980V9BxoUxf9Vsr wxZpyaauOihQJzV4pHtj5kbCZjW7Qot0WRHLFAt9tfCpEG47QH0LcH7j3Oe+0aOQTLZcshQO /azizEx2tUd6A08zeivJebsorSLxHEURPWsHyNIonOe4bfrBAXIB3r3r8202I9o6/CGBc4h4 Wd2PK5gO8v0NUWDQyaR8TrX1bnWyFF6kcwCF7XnkkY5sh+siG3k7AjkL3HuJWekv4lfe/wvm mKlVlN2eZnkthU7+swzhBHR4JXmbnZ8n+LMAQj2mlZclRibDVDz/mgcpeigedEFl+pup7BLW uYaGMtEw/6mb4ydvqra4Rc8c4qrBvCYaHUP5GlsIcWrOlys2ncEE+RKiM5NXmJtqEikgI4Yo fO/PUe9mmqgFyfa6hznAkrfgSoMlTO4ORL6fkYfHLx7UGeEZRYeLhMDk2J/vhSGvuaOHjW55 3bNhuwsX8HnkIihtNnmwc+TpfrUVxd6WmqeOASUxjr9fIYUCpm8hVxWPi6exmYtak0JalJMj 66LCOZ4Pf6irg9Pn1pJo/udTp9OUOBp4TqrBGSy+6/kOSQbB6eL+mJLfzmkGm/wpbaCCh7oc tlWd2LLdFMZ+qvtDc4put/0M/lhPhPqIP46aRcRbyF4PIh4COCe2MwW0/j1G/vZhdvcisbQX wrCS8Yfj8rIvyHrvCAN59mu7YuKcDudLLd4Wuec3x4DC2Whd2/y/nkS3Ta3kmbkeLFwdrrkg Y++Wxdz6v3xU/dGb8aj/3CpEZ5nbqKtSAhdNKonPjstM3D4ff50yCcb9lH8bhL+EDbeJJ7SW HTlW1jkYlmnifu+ILFE9xf5w+TUB06VqFMeQs5wPFWlZpo2w/VucGukEm76tFjbo3JCqJTV5 kAnuIEPJQFLyjj76iSPMVTlgDWBYVRcIjt3imAEc1wzNoF3fGdoJYFJBuaTAfi6hfaPVX/A/ jiy9Kxg4m33bXQ8wK5amFwkaYKOozwrwCC/WNZ2uZSnzMsIIynG6fdVPfJeSG1zt8lxnrlVH M5UbaarH4OjST7igRcMZ4m8ygck6MZPS1aPnJYHx8GMCux0EEcXmbeoGBn3x0q1roHVf8Vfu UY3Fbgxf1dJ7rIknWaSNQsT8HdLMYPsvEs9eQ6nlNNtXjXnOSXjFznnWvQOD4hDPLwv+StI1 XOlrZEKCz1LFMUDaKShh/XoUDnE1ipl8VKiPlWcDqeJLjkFzrFkgZXWayc/96wdyt4b0YoFt /j1WKWJN2utS3P9dPFbPzs7Ll+O8Rb0sc6T9KObPX19U+5SjrrFzwFiUpUusWANwpX8TW41e qjYefdJeYUu2LOMrLeVdRWiP0LnTY3LpkqLm4xPYmQC2mTEBItXtF8WOxoOxkTWXxyfUse5/ uAi7Ky+Nxg/ZDwoL3f2diS8SXNe/qmB6fKc2xtWJasWbU3a6XI5mE7q+1GPbhcUCzemUd2Xr 4C/AIJ0fJoVtjfSECIz+FgaDtMpPR1PyszKziCAL8vKsSzOeJZUL7TMa0cxen7RmRY0lLDhB ra3y4X8Y+eF8miI6RAsMJms3wFr3oAiiuaWqBsSYmBzI5n52tIUjyUimQoM8M4vJN/JbEqyF LqID98jom7Bjg+/PcuHj4eEbk0XGtf39pun57lD6aze6OZCHSrtvdbWJ1MgWKS30lb7q4dbs yp7Oh92EGdH9PBKb9V/a5IiuDvip0bcUEi09w7GLPyxrH3zU2aRST/98uDJ8oJHlLQ7pkr9i FEAUQxFs1QO5Uu7oNyfa9MOHcFclWOeMZ2QvUvaVqiOrHVCNjeDA5bG45I+t+091PPGryfew AB62MBTSPsfWoBzifPYeadFGYHqdQfPV346My9K7CN/rGsqgG6LfCsX4hO4HlqpCFC+rMmhi Q5rQzeYjsiNcvIFcki0yMvwuWJa6vaxO2Mw+3wAfhPC+dLHJLeml1tWDAwNqLn+tMIWj2ZTP YVR6JeboJR41dlrF2NebTPn5x158BWPO1nE1T3vFMWN7qu9QmEgiw9SpKZHnqmPoqLVRTN45 JeBp0dEtMHIOPpd0g79wLXkI+96kkXygnYzO3xEa+/xk7AukZl7hRKB1LVCDAwwwmItxv6Ee z/bpbmszs6HTrTscleoOpd2MxW3EudQsXIrAzyTC8WhKi05HqXcCbsa3ywUVj8GqXPHPhWjd 5rd/0+rq2flaIgZJ9/tLNmpdNpP7Z15ic36jWuxS/ULs7sADhBQ6zf919PQvHwuD1kkaezsU CYq0l4cHCVYxqytPuWjN76XNqT+owly42GZB/oROgDBaZrT72lL7ZONdjwPaDGvsKZjcIN0o GogxIVOnLIfxsQA1pzxdOR+9oOm+VTWLADKxjpGRm4tgSC8w0T0Ulu5pLtPXQnIiwXbcVnzT EHIrqtcK12NIYJHELpUcnHsVE1//O4a1CBI2H7kYewJ+6miH5o6+aOwMM/d2djiMjVNM780Q HioTa36dhhbDleFy6lu31oqtpGixd3DOlGqmkRhvvMWGJZshwHQq4R1anWXpqMZs0EJx/OCl t+3ET4BawjmpG+AtBtIGIbYQUcgxgT3rmZpWjprwIlOmW2bafE3Sh3ilZpJ8NjZKvNN5r6XN vCHpZtcVGgIxD/8uMhQafHsT30OEr4G0pB2u9daoAZLMSk1XJzin8yQx4RbAgprvlJrYdUcm 86GIF6m3aWExHc0OVrATfObVvLBR9aWY15l0r9xI8ys4ae7/dEQQI648onjHXgy6elc9AMvT NXb0Z5eyWU9AWxV0hVusbEQXTiQzNYWM2d9LNqMMPeIvw98j5q6M2vvg6c8qDM8+n8eU9taH d/G2TlCyXz4bI3otXqTw9Tf0Kg/82O3na2yFZl54M3g4qzLr9l02nXejUI8PKHe+QqOZKaxm rCi4VQ7/y9nXnNrweJaqMILFOEtOcYb106ustOeI9YMres7fYLlMCuZ2REA3DazQ5JIJ6pXQ PFI9pAjEjY1GjDehy9MdIm4so8Xkvy1eaMLuuvegELL4dBQfb0cjpM3DjHYfUToELpWp7t7T eLVDT3yFNuA++YrRzXEWlLRlu5yRr+cMKAHgUfKWyR0e4rntjF3iohPZaZ8bb4is7GEEWLrk +ehHCFF0K41Gi3cH2L2RpomPqn6mFau+fUx0OPtMMv4s+2tKnPpVPq4ywWswiFvCIp5Ypr/M vCDOGf/WtUKxYpr1zyrkW6FkZMpnqgJ++S/xdSyH5OhaDLDr18bXCHT2UmnA9e4BdJXHjm+7 VA299nbIVX1zBVLNOiJn+O9p1PrkEIyF6Txo6Bszb0crdB7CmsOxSxx/ft/XN7ZfXo8YnlnE +1RqXI8sQHBw/FSkXwXBvKIzLgdeuFzMEvpDKtcqlGDNsNX4lSX+WteHGOZrv26279IhrDxn C3GXwp8x3zXfFJMDX23LhChxtbfT1o6lL+q55I2uLE5zWjUe9naQ0tyaHnifNOHnJf+BPb/4 IZd6tWPXJbvvN4e/Xkp54place6ysrB/rtvRM5fu9EUxd989lPNuvLWMlwlIxqS1vVbhRAQP RudpJZnnAUqbG+mv5vUk1rfWHAnfwsfQ1tPIdNY5GoM+dm8lhIZ2YkUXmyVQDfQA07fRe/pj yTj/RS8yDTp48wqGES4dhE4EbKUl5yZ89TGwx0axgBEytvbiCCOdiOSnTmpq/jr43pypPxPD j6yZXke1aYrAtyJcnNACIDAAFzt9Um6uFsr567vw3lZOKMxqEJR0YYmhY1KbuR0NdcNupR2F vzNo1BezTCmhN+jpjq6dItvNy/qSdunE3reviPrEPsfh3JmWkMb9zbmxCV2KZsWD/8f6cErm sPdTk8/HfubEcegcg2Dp5yIgQKcRfByXEjRFrVwEaR68bH8KtPNOYeixesEZgiTxASchgS3Y 43KVuX4Pxl9Ev4EPZFsFJgOZ0ybjyIDvNvD/Qt1ZrpUMwRgKGHUQLFsldIOZPMXidxJ3898T 18Dbq2wwBwjc6ZRDh1AFL+dTR7hv+nntpBSBaHRjzOtNPLqTwZZYczVPiWtPBnmaZ+iioQAz a1NHDi5CeSilx7O9s57xtvFn6PEFnY+SRfkqvUJls3U/bjphQSJYcfcmGqX8ouSrLrNJzqrR XRdu75lpQ0ePvB18lcZ58cUbdZ8bDo0L534Bva8ppySqhKZoFuxUVvT2Jrw+QC7jlJN3Q5JA y4/EbxnXhBRJLREwhunwwefMnchPycaVmCoJCXctDW0xS/s5IU/PYYgcBilQ1XoVTaeJQGF5 XPr72fMfENr1pt+G+LJ8mJ+3bSPTLJlY4oRD/Mz22ooHarW7DmXIaOS/93/7cA12adR0vlpe cu9lZjou6ydtZjidgb0HwmyXsBJnOVgD+Kz9K9ZEEivShcSk9BrIuMIg5njDc7ADYXqLLMJw lnPz7Qhjt/MkXWBjwdqqOVCwe+pXf8+Ha/Yo8RLeqsaf/6Xd8H2R/VXKZiG5qA4s560dkjIZ /KoNwq6Ke4G2QzCm/uQLXuF0PEkxKjeTX03SVQqwhNyCJwO2s3YcBVhrs2yoVBRZ6BG+E1Yo G5u5kE3zC3JJTLkwE80BxtudeS3SQBJdC2+O4//d018lYlYO+/WHPDnJ8o+1qgIJWaDGzHRD DzMM7Jmghv1bzdAxPHYVebC8gyGMBQgmw0ig9N0oYU+YX/LsLMgGlvtRA9ktP+IQJgnqKCJA KoaW1FnKrA1AFebCTGBGTxHuCWVayVISmeekOvsK092f9ihxpt5xikm36ofMXQPXVWe7ZCwE O5yPQ9NrbUMjbhxjnvGAWgBbIJ/TWl6jiuDYNb+uktNKKEh/NmCZKTMzn5pkQXy/yxOIuEE8 gSGswidEEhQLKqQe+3VUjKFpAbPJjtIzEKPT9f5wJRrXB1Ig//l44O446i8z4INyUAV8m37v 186i/K2GTZCuaQp3693SUVQTKSXbJeaXfoxDhsxmWZw4NKVZi4QR5N4KKAc461cSzTA8ab72 C3GGl+Eu1fL8pb3cHY1m+2svozFqYPeZYEzd9EQIL7+vvG9ZFG0+MOXfdoEHNB3BhKXCnCyi h2USG7IPBzq2mJjvr3VBZfkFE/oUjl9iqZfjEhhmlryCpXV6zmf0ztpzhkmwiaV8HKf8FjhR G74wLQUPfsO2+uR0lwjJhS76I9eDZzGykvHvODNnC7lLGLVkmd0bdeAGvoeujjQncTlPTKxm kSauI+CukK7kQTNKLxE3sWs5b+SqMlWHQAM/Vkxt6WMzNeKhDExL9M3p+rGbiTqN79mfIMQt TIFSil8l30jXSm28SWatFXXN/qu9b9csWJSydYHta8T8GynjNqzr4fSOLoooihJ8/ByNxnuR cUtlTcQLlTsgU/VKJOirVEfHoDyeA7TrZyetvQlVxpF50yXq/pZOZs/1ZzC71ug/jPtmZKc4 2mzpEHxCkRmx07D3JMVO6qbr7P7Z+WKfSfhWhpU6qq8DKUsG3LppzSp+Je8hI5PEQ77hdyZS GBKOVAxG+6SE4cr1bHHgM5HEve3KNol8jNtTrjONYkl9L7ULm07xxqMrh3Z7VANInD8tmYFH upo/HXCZL9mhlAzlbKvLGn3gM4wJbaGuH8LTeVVAGpuiZ0YFs7oOVgyVYA+itL0Qodb2gPry fUTgPOJg8/fMYriHy7uUcWxke+hglMng9ZYnsmIehGt8od5bngdVoqy39zpBwLe6IPiRexYF OqonGBH0cZiPHCPgpxfKynOAOA+QDr8aHForYJN3GqNXoL/8Vd4WWgLTIn2BoakoB5tAspcx exkF485tYbtYSVApcCHdZERxL9VZAAGCAkhyUwIX0PnkjjYvO9ZUzKNokQiXnRy7E7vIzrsx ccSemIMagvAJ++fdh7mXWgSV/1UvJQXYGRytQz/fr1NPpsVA7u5BdyckYoesH8FM2BM6jweB fszXeEusu/kryastojrWQS1+raIMWCAtO8wqxImHFUcO//VJ234OithzsraRYpje/o2wEZiw BlCKraNCKE9SsEzMGxnoEon56a1oBdF0L4Qu42JSsJpiHd8DI2SdGTppuZNzSSTLlkp6yzWE iHI3IE0MUZoei+c7blMXpvT/q/Tavv76KsUYiJhaoJSUfkHCm1Nt3GE1wZfHw9xo3pQ1UB77 gYcL3lBk9xfvFNVdFgqkMAtbBLTdd5xctutregJAqsNAyqvpf5COK3Aj8tsV5HgMQ+6ayOnl Q51uhxs7/rAzky8m83tFo0pSi41vNUE33Op58SvfinF6Sg4/c8oXX4S3RVg7Y3D28wFt+8yV pqxs/UcHIZmr5wFc9Gd55lvdV+joabsK74VE+wRun1eQew3gP4aM/RPu1ug2wuOtvIY533Pd 49kar6hzLbStiCXpSzIzD2+EvbUVzxHFfKK0ub2r3Gfu2LGbcWhsIzarOMAB11jluKUgRPYf u10KNIL3gT3dtziEfe6JMxQlTru/WxHh2VC2zV5P+Wk4MxhWbT5XP8c8CQhFkZS7v/cfJJC7 ZyCma/p2xsqs73BctM/t06fEmOm6IwB/E488dHuuOkAEOmeC8wLaIIo85herY/qArEnVTc2K sxQ6LIf1gvKwYflED0YRaItEiB18/jXcBFj/r/GxU/AhuNETzBxmZ3VOMC94XViZxWieuGT0 JMOZc3Q6+VPw58AfRF5SYaK05GmvJtLDN7ftA2KlY4vQwehJ12Orw8wD0cHXHBVHs+00Kfrb Zh+JDKjKmp9uJjZNtrx9U9cIB6nct54hGzy7qazLkAjZI4AqlDJYcl6oJvpNATwiAMv7w3iH hoF+1bh5NSFKb1RO+uc1NU3fm7M1rwqLL+7zlDm7PwklPm9CvPUafhB1JcNFCWAptM081taL aJMkOrL9Bo+XJbk5GP0pFFDt8ZsulYIbIR1E5yvZciPYodVQGjogeV30fx7QMuuC3YQ2f1eE T78uW+uVdDvCQvQgDmHoBu6fh62o6qx6ZI5F6sf6quEShDtsD425/PraDNd0kLTfYzEeqqAS rlddl5dwzRWaYmpp8OGy2fqFt28SZaBd8uLeSEcQrGqaLuA5hK4Yh80l3aqXFDCkJhQ/C3yk ENLUS/i/nmHJiWxEHxEG2NYga7Z3zluhLWBkO2NQ/uat6A6k/Iy3i6FcNcYgE1cp2dhoclzt bk90Iub3oU3XRO8VesNhGKjlnbYngjrfeOkh1y5Z7p7iF7a/U4OKv757umgocU5Ui/iO2ZJS aP5FtxjRcUmJ10teDoV2PdryyjN5bSiOHw/kZzH9AYaGgPSBYpDmi23N1tjTYCuJ0dCvSaKH kCV1oAQybrnRx7jRsIRIVN6qsy5rFGCWPpJ+MiboVqhhjtUd12P2sIU0B/O9OFO5BLiFxE1v 9bJr/ESx2VhZ5iZ24FpySudWOMeFg3zuLD+M/INF/H9BAIjwCr6qZXue0ukcWzmuiCzcGBvd 0dbT81QnPu9lU1HauOtWXWupoxE+iehHO8QEmCPx6nNocjEVvWmpfXZbvr19WCdYYEb98YsR OfPcYpVDLMT/tS3BvYcPNTqXphPtegrx4ew+vLcCt+HirR0Tp88QzAFByqIxbzUhczAPz5G3 5QrcthZxpINNOeHKUQuh7982cZdLVqH7xSaRxWPlwTgeqYSdvY2pdxipaGD/tJwfROUK+8Ov ktBXWfvzqHlvQ2YH2ZlRIphBFmd6qYHBd5aCAAufCuzd7J+esEoKTc8PYWYQ1JYpdDBy4gBR s50kZszRVtDWdLSkE1ncUvI72n1aZZoE/zAL0VF+2FXFJ8TwJq1DIm2wJVNX+GWZnezQt/pT Pp/4aVsNvETeQBFKnTK8YMlzW4Cznch7YVTaESOiAxC6CkoFd4y4HBEmv60Wuk89qQPvCvZ/ hkYz0R3owjhqVEcaS3MMkY7ZSs3qvBsfEKIhQHBOOGZoCosERi+OMOa9xbWqZFL4ActJwEmi onH3WzlsvpNKzSsWsskrKpqxcGM59CdsLmC+fQjte9UYpb6rq2cdJ4aaTJMJPvB0+nrAzRpL NlvRYvTH9fNOZyi7ApZ1TgSZL6QB1E/KPElYNQsASxdmu7K/gxT1jecczh6mWbngHFQtDGoj OZXL6wTf7ixvHY3qnXJoE8NUrM6nhBoJ8RLxKrnMyyCHSfQYOr58HyfdW18czkeOi971KNM5 50u9lueYxnNhcZs8hjSPNKTc7kvNCk/4DsfnIMZdlxuxAtFqFqAPB8gnNkF+x0bg4F08omSX u2XergH0IRp+RabUB08gG7P06P26R8mGNZqfHEuEEn9a4yihzUW/GVyIDex02PwISMfyY7K5 gBCBXS35vPsu/kvMubvHWhipGKNrTNWNKPWcasQBp4ABRPzAKHWSmKdO2wp435PC/flP6ZS0 EVNUDWSmwRw2Vbj9yxB4Gh0BvNELuXSvF/HtwOgjf4t4x/ZROZL4FFlGoq4OpQsXYwnZRlNp /zJ59pOFvr+zLKCQv8Qgx77d3qnoIle6ZVUIKfB9ThLcuNVubFXD87ld/BzjGti1LoRPdBFj ZzhnZSt3t8P/NiHRviYtcl6Fcadsi0DohDeSkh/hKHaC5rAHB6iUlkq5wAcoY7/t/PjHAYdZ IWzYM9sPYzIbwBFjjj78DZT7l18mx1Hm9197FU2Dc6Y9Hy0vI59F6mfkQZb6lB6ASCNqLI/+ nKqlz21dylK8MZ/mdbdnhrA70glpi0hLrJb3zoczwcbK9j/GFusB4kjWHNfBLzldmbxFD6Yd zBia6g68NdDX71p+vEVebr8TpyPVC6E/bJYL/RZD/fI+RqVkGCt02ewqdXtPcnAFdBDyebiI IPpoeHJcBbnNap5oiSUeoKtRBRq5azAmmQxiYSBNKyWoq3uXOfdjwu6ZTXbKcSkn0VrMNR0r Wix7Bo21qF16mmodTSsdyaU1XLmsRPDC/QtyRCJsmRg6NEyQ94xMCaZA0MAt3311sNoSdrvk T+NT5Gjzc/+hw6/wdeGMhUQJrSi3PbVNgp1ORXzNPdZtVKE+FMtN3TsI1S5nXRRQxsYwpqFV esmwLEo7xkftjvCTc0ooYJTv0Mfe7a3x5WOtAc+9HHgYzBL+CONNIqq3eNOSGFDPMhVBQ7iy 5yfISaGs1C2tsXLgSQsPQBKEYyjct70YlLEc0rlIUm/5Pl3VSstojjpelWa6E0D2D6EqNUUT D/V29EOK7z9x/W6Pkn+QCgTjrlxq9yJ2I2tuN3FWTsRCZeSPdsAz9dt3R6mNHKBeXQ314wVA TN8TFKq3x1aCFJxvW7CtOM29DOgkvAuuatS7PlXh5ZprrBBCq2Vm2YLj500yjhzOl00VnYc0 tqGkCy37wYQyX0+rN8GU5uRPDo23IxHkqQnombNL9XHM33GLIWyQjSwvy/FH3r0QMZQ936e0 knZ/TCs1WPMASc6/HIHHHpN3xmB4jfZOgvMSqMHkjkUqZzWFwFez8YXAeTpOljnOG4cDlUta lEhAk99wkRgc2l2EhELQZ4it8HnehTJV7azLEFL8zdFv5H2uYv834yWt2P/+N+oBY72ZGvxN 6/uNLpSa9XXFQAPvWgsTfuCqJ3YQxEhDOI/Zd/4FFhvqpTsaiG0STQT3lukLV4uYY+nFsmes zgooZPoF3K01Dbf6jxAkjzQJa4JU1ji6q7xGu5xSnvNBSn78jjgX1WPIBZ0bk1+HjgajEzMR mQQRe8vcdq39zJ5gINbIIYrsqgrbyTvGBgHlJ3tyN8t09Uf1rFhkcibZIwRZjiNYzr/MfUdN /jswfy3QF4m25gHRMGN02xML7eEfGAdAQhc3zMFeTc+ijnPWuHHTUxhqaTm0Pl24tc1mynJ3 mh+36itIDkc3KuFnPItvMJn04l7CWHmo78j/1uRM0oQUITv3paLHOx4jZZU00y/wG4Roo1EA tIP5+GWsGgpJ0pZXUdkmAYhVEQ3T8vI98PEEwuavXkqOWPRXvOY3TtAnjAiNa8PHZPnP1SUV gPE+/B6w/oEmuXgXbLt/SbcD9CQu4/Pul6nJ90WKBOSKyBAEw6zl1xq55+ekF+GF0JBg4jB8 DrNV0SN/1Lr1VshYJhElUxBbnR5dRL3yTVRibuCzOc2X45Y9NQE5pWZEAJi3ArRXYRifljid Uz5CebbB4KCyoYG03yx/fgmsnSKlMfsVHlcC3P0ydBX0WqKk2e+bOpqF4X7w9MkLK+XQpQVm LiKCrFSGDp3vGv0eMCLfRRX+0V9C0w4SLWiNB7l6aa7MUGv7sZXZDcmih4jcmnVh0GfL5cx5 S4gYi6q89GtUXgsdVXyDR9bcDq269aTiHw5+8HcpNaSNC+amQlldEfeJk063URNtFMRtJcoy ydLF4rIMEB/O0Wqo9yaA0DBOqPZ4cOqpwkJr0FPNqw7B0zxYQcToMTZJHfg4dTGCGwgRYJ50 wPN9Xyzt9MD/nGfXjW1MiJYlsHMsZWHd4KrCyZuz/NQq6iBzoK8Yv7PbqapZg5IIzjbx7wZ6 s7Nl7dDaLYsTClWsoplalwKnFKxcYVx3yDfnLDgIivUI2gqGhCM1cdnPTELqPBon9SkQYwLQ 2Ou0ogls07Eysx2igM1YTeIBnQfUZuh8t1qBM73kCTW6UPCGVbsMAJOl/YZKjYAgzf5xEYxh h7exHo9ONumIqdiY89y9Qals7SC4Kz9qgmbukCENk0uSqfEoK91s/X1ZM75uRomDll+Enl6S 2yuHgBeCjamlI2evZ3GvLHiTVmX7CvodSmFoL8cu28GqvW8HUmYZGVWqq1QyoLQL2hUcFJHZ ukWOmDPEibjMFnxc/4UMwAxWLThAFWl2fjgWy4idgYHTEGqTDZImbqMTFY5Nr8DScgxHVkJd f7CXORQyv/GhqI2zoDCwADb7H1sL4BfZxKauHNQOlyKWB+fXO3NilxHOBGdrmnmM3I+5s/K6 IeVYMrA1EvvBDEBidIgbcYHyt08/ii/qpbbkOGZrt2lenyO/+6G50cRSTMQjMQvRgiP2kTTx bhrrIbOFwXj54681AIMi5HHXdRKlCGpVxWZe6VdXdnie0WRiizYt4ZSD984LCN+92IgFLNFC 58fsktx0B80twQaQxnq3bTLBAJamXjm45PJbypRAzhqBFECF9rpaCvAUmPlYq+09Pw6LjkkY KFPHKJihTFS3o/N3StMhPKhQFsCKpaomgqduEodadS8Pge1/cvdWIMvc/s6fr9O05xgh+fnc /YHEvXgcgmvHlQLogh1V42Uy+KqlhXAROCXliVsWcnIGzB61GXtXWD+uK0aSHwnKEu5Ob8Us p5IRXwv1mvYMjVSYPwyGkGyXYhvcszw54RIhWCZejQNBAeu5zmuFDxeQh3yMx8nAVKDrz7pB JZ8y01mDZxoYqJDjicO49CQ5tMFugO2cW7GIpCdRhaJv27tNkcyYaV89HH106U4CkFryeYnN Uee0dGQeLeefqvi7JGFQ+zJPbv3UxJ2qoqLHCrfXi8Th9LcgPk3zkbrCT8H0BkAmMK/Lctbp 8+PU067ixidZ7MI/77nxXGQdxJ+rjfL0W0mIzj7o+uPmV367llpNpw0Kl6u0Lhk0sZhzzTRD Rcbgx+3588ldLZUZ0dKUymMpDDX+9TxMC8jRwHLXhjCzBR0eim4AqH5qk43ywRaAwM1CN7f3 NMsq6sh5JCQUM8apAjMOt7j/WXyK60e01GmlQVowe01mYS+ZRJrAqL0cLPJKLEhPreF5dRgk 3ZlQuX0arFh2VYuQLXypnA2nzB+mCfzIMljXtZSeBcfnKfHGgYuI4kDfDXZCV9Y5Ze4Q7Sfa Z9x+YyEj/xUojSPbF24tmYgkShcakmCpoqgY1J+9qqfP4yfGCsknuLTvUKhO2iE602zGPbPa ODFzvJQFXvjux/woXoQpPwe38TNCaHi4Q+3WIRvYH3LoID3HXXKmvClxaUG5DGRWuKJ0A4dr MBQXAbR1tX1gsFaClEy1fTfkdz6XZ8gWXnP31lwTcOrEPQ5TO3Eu2DEHEc/a9nHAmSNWnYcN ROdayyovarYevS/TEUBtV1mvvlYSt+5Zls3O71OOsXK21fIHKYrCfN4PMYfg9hOvtyLIm7Zg Jtg93IxACu00Efi34+S7ksxpv4FhMho1k2QS6JwrgxOuDwoQ0HQO07szZ+q5PnbZimgYLCyY AdsDgK/1qW/tZqOqf7nBSN9gONXgc4WnZCrgHUKrLGwKIHiZF+nAxZYuT5ys5EE07QjSPUGR fh8YJfkYsO2P9nxPfU7IoPJ68xO2qk0t7nMaC9Y2j2l7eUwUrElJUSxm0vEknI8VzWAojF6U xX1LrpCcUqcHDwW0QuroiWHdgZv5JLT/FLx+sriz1CaCzllrqHOeIP7LiaIoC0DyF8shBP9O TNl0xlO4kaiQOAPR5rpH4XEgQvA5CEBwoT76MII50PihbZk55QHnxuLnLkpTgT6yjhLEToUm +Grl9Mb9KfxtqP692ws+mg/TiyxOZCyLn66NtXnJFnez5nIItd+jP4gTRAlniVo546bgKWMs OKVeX4EpJep+JOyFi7qNf9QHSi+jnBdHWgX5O5LqzEREXW4AVIV/93ud2FsKnYGnG+EXJhV0 KVT6NBBS4IDA6cMzxHalyDdN7TxbJSJdZy47uIfc6YsxV/F9k9LEgx/dnbMscIiP+d8JiIaq eb4Lg7ru30cyhRL5uCdBmlFS5Y2A7cRy/c0NfQ5alVOnGca+rAK5UnNiXzMem86BbUYhiaA1 9IbDAETfv3r6zbdOEA5GZrnE2Dhx8e4DyHHLlIcoOXQONWWMnGFQWnQ42xZKSeWIxIcPOX7K +IVDS2SdeXePiw6ozz4LUZ9IMIayyp8ScE4Qfu3dNG9gll/nx8oyb0zHOnTacW8xw+5ttLkH 7P4hQOdFsb98wqqJNVqxK0lmcjSagNIBRz2WaULJV0TVTYKjEIt0+xcA6eCcWqVWrsS0kHvN q8evyxbrfuZT9VMvIBhc8QSXReILr4IT6n6DtYlhMRcl8cJHy7u/Q8nwtEXGsahXxXzh8QTg +5i+82TNVqzi1vR+d0svW76MwUxLFGjczF9h4hG+wO3P3RwWLcvAB5ynnyihBOFbaNnGXaBZ cFsjiXeoLhqnTUNCKcIaA/4Zng/W5mzcamKGV9xvovhMglocf2xlEB90iR5mdJXj0CcF9wkF 7g+bdzJTvjIC0lLMnzOLR/JLA8SM9SkzP1r2y34SzK9ajm152pCDtllhUVIDSlViVQjBCJR0 13rp46khTmsquCheefg0m3S6GmmvAuTZGiNJpju6oXE8FUzUqeYOR2uHV/cwr4I8Tz/8fGLO SzTH/yUYUHyaydJ0X1edPS2ogNjYoX5nagUjhgxmcR9hOYOYrxryZzVDRtEi4yN8nwc0Nnoq rLmELfdtvSCHKo/fn31cSj0QGHnL3SC4lPcsRAyki7Mt1iM2gwgR2RjJwYszgezdMxEqD5EA GOqwzGuyj7YyyRFD4snZaAGflEEn/nGnsQza0jnt34L6iEHe+/5I2vm57rpU+Ix+IZ3dA4nm +CFTEQnCzg7nl/FdfwkHpvDgp4Gq4niBJCIGYYQBKMwhfooGY7uNc5x5qmta7H6y66+CLicb ZQ4eWo7g221P7zMU889xeWh43j6kTJGYfLxTqPO949EY+9dUKACUZIBLuNmRRwz0M+v+0+GB oN3QsRAnkHGdKRZfitUJipF/8I8MuRGqOHFqZURmWHpSqPpUcXkIJ+XoqvtL9Fz+AGXtV1nH wV2dUUyImlUArR9SjMR4M0Y9e6mAtf0RgbY4izF4wl8y4dO3NKp6fF2ll99UgZjFgxGCvDrR fS1m6VOdoiMapSaglJMxR8R4aZCrH2M7lq6JvbV42Zxo5VhyTWQ62uXONnfFWmDiEI8sY/0Q zIhTY8Kkg9UoEX2DM90Ua6Ix0Jd6JY1B6gYCmhvlvtCXkA2zSWK0QDEhmkgq/1PJZcHF0B/U dEKCMeIEUuPzhGQ5PaCpoeUX9f7+24EzIeuo0i29Xeq17LQg4oAap/2iGjDRGilQ/mSYVKJ3 UK8s6jaefF4UuJl82rKrNcZXlkrv2bEH1a4KXIfjWlaPt6TqpXNesA/Qj7G/Vo0e8/utb+Gh ArNWiFf3STUalvXOxsxVPrsXsCtUfVLRNRrMc9pp/aNTDK8wKX9IK7dQ3tfpk0xFKeT14xjQ dOKQCaZkW0W4PrankkU5h0RUv/AfchkT85v0cK0lp4ciLo+RHCk7c1WHtUCsXI/oL5C6b8lI ChPLFylcf41nmhRlMZsPCZEeW50BTGdHDXIaOjFfCBZIxw+3XFIn2qlAgNx7/W+EP/P9jNQS nAM/y7PGCGuAM2KMbmVgLI0Zf8bM9P1/O4WQhh6mgQAlbSlrgQWJ+mJZbGOw33c43XW5a7PB VsUD671T8iTnOsa3NFHRohOpiuCY68VpikaQCY/8fPbUOxr7OSJ+R04vK6torF6oMWvaM/Qf qtn3N88USejSMtbIPXdOJ8pJYq1DDUSsLlopTFfquWk2WlQzg3r5DkKrGZdaS5UY1QoF/YTX ZRpOa9Qn3pB6WVkFBYIcgE1+bx21xYdTq71VZCc44vMmn1omwenPfSGwrcQOylLu6e6Qa7E0 qVOOyucC2MfpHLbw8UwibB9JUyi0ptyiZLfvxgdbcj0e4Cfl91/XjaHarX/b4TikBqLvhR4q 8U/DxcjoYa6RsaJGW5Mg3gW0ou1BcXut4IemkMRd3lQk0lUeMO3zdsb1tb6ScQ7zpDfWOKMb SGV5n6dbOL+54Sv9avgiR/PHyRus6ix1IDOvmEtEuKZlbeUUO2idMdLBsjkyX61TWVj5Fjrh uDuOJxo13ebJGjMf5Uo5JGjnPJeZezSnB7p5r9DQOh85OtlWiLwlViUmLYJXn5AMAEkR+HkR Zwb1Fam5GaGlQDCTJppbfShH4HoScB5rhmCNQcxVi50gH+nGh3YAaOTIhPLTODunddUk9vwE 6IFeLaLMPKmLAUGbmR9aXNHzibB3ZZNPIFNvvrWxWsv61fgTKGWbMDnCOrCLa0tyi+OK6lh8 B/W7jGVNcFq7wSDlT+yrGj+05Sewgcoyf8M5jxtzd9Lk4ocwloqPn3ljpJymcTTRqz9Ju9PU vX4lsTgZPRQcUevaLJB68BVsmoyTJwHGOmqqFG9hwtfJX1LNRmumiNHjyfH1iLcJMEVUnKvd ks/jRqFqKiZd7lSG/XACDWc2drm5szopKT2OVY8ncdKjCW08/wb1lDoa9hpG5s/6K+HpoeZd swQ33AGpohZQwjrdC1pjsI5RP2v8gbRmg5JrYqGNgF6MOkOdDpdSzR2eYjEfYIPXnpjl0HE6 RXyV2Z3fgVZrcegZd3AE1W/CEnHHNx23ohWF4AIaNvR/jHWPNE0JDd24z3hIlGSkx86kAz4o Tzut224T1+kNI5MwCT/kegyBG/f/R+UKJIoDmtl/t4K5aVXCUEfvdRfchH8XAswyvLdC875U VN/4Qe905Mz5S6zpeZKxaAJy8c9d8e15AMU4F9jbGVuusCtoYoA78kjJQYl8MTNkPASBVPmQ toNxDCgriowfyBYhYKp7RzfstcxrqEYCZ/KzuZzafHZ83hB1jP27b4ev2+wk0Qo0qJIZhaRY ctZQbvWZKn6X1Pny6Y43Wet/eE4vT9iK5vWodwhsZ8MPDpTjKKxAe64LQ0xGiqs73Gaf5FKj nyhUmM2P45p3dwfePYGFTntthJmXBBHNfVSBuk53JSIosZrDWX+Bh0cDIQmf8YbQDDtyp6Yj fcdZQ+uR0rsks0mXmsMZZH09AOg1dPjrQOF0m1jaGWzxfBsynFNwFGZm7ipa9y/UMgaI5HnI 1/JKTbWiwYy528dHyRhv5Z3QqSWfpGcCgWOTtmUeLj3T0SF1yvQClFddwZf9BBW2VHVeG5Nm /EP9iPUnmy8ZYU4tlpWszpOBoyT2eK6GFu6iuCiduvFTj8WI4fcbuWZtz5aGS6visJ/bF9PI LGLZIYmiRhn7QGI1iOMjOcno/60fuWSU/Rj8PTYMOyWfmV0vlylPDRpST7h1KJCoXBxWJjBw I0Iv0g6w/KxJdFtL0mAfUnBmw64Ayo1Ld92a1ya+0NaimEZ4hfBistzjOnEqsp2ZWCTmhQ3B G6SXNk2Gk6gXKzNdHbCZct4YITfgP8wySw44uM1AoqmKo6IGZ5+hCohbbeteyw5JY9hN5O2A 4wZvK5VbPgA1ZAe+pIDs2Ubhat9hy/3f70VjDSUH0Wq+srDb7aA8pqUDmNLGWMeD6PpZ4IMa wbzzGUjFIjXg4Rp8S2csZOmBcW8wcROEE6qijlrjQm/z0fGxLFK2bce5LxMdrHwQPJCf0xmn p+tb5jgpGTJcrcwsWdZkweeft8Qa/5Op+hM399MqEnxbn1VLUYos1q6OqtMtQH3A74K8pGea xWaJ3QbHc0UvuRDWaWOMaU90GHVQiMyYBLtvaR/NIEU0dxSeBysKp+84gv16wk973VQm8YJt WdEslUYuCALXo4/tARvYBtUPvU+aptB75o1f6PDV+ImGwynMMacClWK2pO32spKAInit1RML 1FgsdruKqVVVS3qTlu0cHEceVma8T2hnet9UJXr8hb+RkGNoVaDg+TT6sDTAzVFLtr/vn080 y6tf9x9UEtRBg+hbuI8pQillXtWCw/j2rWz5J4tU2qJD+vH0F5CDnE8wV7wNA4gcUAeXGi+2 0jQfP5wtLpKVDkgupCvyJVTEAb13n6D4hCz4Fz9XaueyDnRnvYyALpP1eQQt+T+wLJiy3yg8 PIXN8yryDg3aHNE0zszrjHSHHDsx6u1xnYnQcC7OaRiQyWH3c9zVLE5l0LSPLsly0RScGfdi Ie9LWl1YlX/R6i0tAt61phA8HFiB+gDpRHEv+TqKzq9ZcpBYsicqDvPOjGVb/ljC4bWhP7DH Pyf9hvMG816sdo8QWkku+tlL2Jy+1YwoamMzqsgv+ljpF3KlXNsFHgfyuTPjvztXOvYDb8Zs BSkMGFZXPg1SmGTvB9buOMsrrg1uHgxsIB4jxG7E7NGfoNQv96mqksABU2qSOQvBFgYloH0V /AOaJIDIJmnf/wABxqmAkJRNYISWaGNRmYq4ayC0ku66TCrkSkrbCmjLzNve+TSiLsqBtxWo SaK+0wdmNOqg6dFSRuV/rTVGGwVXL8zhe7l8w60PttlovK2TXIBPbN19Jt0gB9RzKWOMk+FT wF0OyPwlU5sSZm2P5V5agnPyP6WP/wBsQw6QAa5OcbLa559TVps5IcorjEAr4ngLNd0upLMe AmFGhEqW9TMay6ywlO6n0dIKrlqZPC5WDitstkV5xJ93nbQpXKPnqb3KPjb8+0dDJV+2/zrS z+36AsK83kL681PaQ3vcrSPipx9UceFszoFRwaZIbSA6+s2z2AuRVTkb9RQiUrggoAUJjlcX rbjqFXF07CprRDMkdfcJKYZM3z3JhGSuUBknm5lgsEH4dWTdx3KCXk7cih+cnbFZ9Oa1GdK/ BwFIcfz1x1R/gwdJ8IxR+g5hi22atn2Dj/8ZncvObz98XUnBJWDgKXzWX7XjgfoY7ycfnIIj SdcyNlPu2NBsdG5OL0l3bc/B+amScV0LBVf09NwezdTH+Bf0ZIJzgnMEenDrNemRUQR8LFYf No4bhL4jxFhcw/dxY7TY9rCT4Epwx9wTt8vFJl/Q12PwaL5IMxtAcz2LzARZ97YDMFpGzfcu 36yu3j59HhMrCBuGNO7lqpDjjxVANhvgujm0Jz3hrJrcL1s2jnzF8qU/pCTbGkwy+2j2B+K1 kTK2lBXDAbyFe5njgY5EtCeHXc6+Z7on57fjEqEAD6k3DkcoKJqGHmr4w1UlopwaaJLjccVM /2LO1MQPSZIcUhyPI6LKM95Do0Lw/k8ZzIx2wRAZkRefdR+oSM0yd3NhhQLBuQxckp1P2IU4 OBMuYGjg/LnmtDFQuM6yeqt3EGDVB5IQEbYOcokdfwTQtILQrD7Lpxv+Lxis0uNAq4dZyuQz uwl18KBALjO6AiBWSHBdD/l/yPmFK3ZvgCFSabxIRpaODNE0SDG8NazSogdeyOGHvQYw54Ze wswMvMQlt2bPkjN9no8ck6oDETeLW6eP/4ggg+zjm2khiXRXnSSeOHhiabxS76rGaEIUjF43 oTtTjghzPFrQp+/1fUA4OMTTx1ADTRFkQiQBPT3GL+UouMsVTB/pMnaQmvXkFK/1yoQwh8Hc ySxfUnrAL7PVKcaot/JuGuEsid4qZ2Ed9h7Fwn7UNZI10eafngI3sLTVu8FwLNBS65RP+mh7 YOVSVW/cBXl850ej07CaVystsL5ZWeE9go4sYR3utEcctG9+DYpM0OIjsnuJNUjSIXC6YGxy rOjae45ghK52eTrVYdHAmtxT0eaLO2rzeiPtLvmhqb/MWx3K4U5S2XdPIs7ccZSpuu0s2ZKO y+qVCu0luPn3cHHxKcT8mg/S2Aaeon4oHg9/g69szz6x+57capF7wJVvvy3Y7eB6F6ubItU1 9KVSkt1k1n9nPdWp/0qGOEKazbyeXv5R4J7wYo9G+f04xkS5iIEQIUgWvc1B/pRzFsyjutvi H05Gta61n+fZrTuCD5CQ07VDdHa32MGTvi3v8xYlpVSvefOP6ZMBNBbo8h3IokU5ryE5eBAC BlF0fWVgh+2h8VKQpf8hasGUL1la0TqklOnLmJE8ottopdlFAUoVTbwtmAzTDqrRgZXBabbg EuixG4RYyHQ4k8vhU/Dz8zIQwUjnL7I2VjeNgFrImA9a9S+F6EUyW+bU4KYDke3WPZLIbM10 s8Sevc3IuTzitwRshdAX9NLiRkyTgerUXrtAeMsJIjj5yxwkcFYGrQnFxii5XbdUHJtcWeUc 9QDb7rY++qGsqJ6mNds6kwtFoL80LbFq36EQ3GxhjzmVw2NgyGlALXY3Qs2ERVFzOCG/okuF 7g3xC8hLCsTpR1Hw2lMHXof0N+SVVVGQVqU2g89F7S9wcFGRitn/MzLB+G3mGruYlGUiwoK+ tScv3PXNelGRaFwKK8DPXm+xGMHdZj37tnOrsylWPzlKPgOptn0Q4fFDYhtsSqmRs8JoRBBJ o9NS6EQP2RU3v/opg0HMMgEbLOhbTYNRY0uEMdBiOCbUpcX4lJ/6P944FO8QXQaEE1WqikCX 5WQJeJgmZp6L3KqC2sKw4dep0az5H5wqpVjuznDfdcKoONrn5YWzqWmhe4JADXv+zUyG3jrt JGp8naA9bYPBQDZ0kH4bQroupFdorQDqaPQfu2lEOqQzRnFafVhjPCEGXU3ZdpKGw6lWUoIX 53FLQpSBlsxs5/R1DX1zrgDdMz8OyVfRBLv7BJ/fUafVvEXlWvynJaewIaHsR0MhSubBU+BV 5GyTR+U4hJ78207u2JUmeUQ02cFEmH9eewGHo40hmtlKcsO1b9v0b+yvFVyS8K231R1pHqFu N1qp0MQ/zA9VgP+lNsd12Dkc0C1ZN0RymkNBf2DSrxNRdsA62m5RG5W7LrrhzIDvbojSXcbK TM/3BlpkSIAAfQV0hbkxtjNiYAiAt8qdWM4Wvs0Bz2uaqFoj3ex17deJ3av6fbw5QN1501Ze 2uEDdbs8vgCMZ1BHZCJvg4m/N2hkdlg0w1H31GmO1HFffWi8nxWEngCVwX/sm1hluexRCxDC h1HzPrKNXhVwj4X8xhOdsNdDlRn3nCkvSsXafNg0WHCYdkKjxHu2CvLpcrCdZRZ/S2GDeIH7 eFYm3OOBI9UopZEKLf9DZCHiibNqlpTJFHltUXLQ4ZSFLVV3nhDuglfjCf+9J0lP4jawZfeZ E//s+ggG9yIpl/bF3VcJPwRGSosprSUdFrRKemXch5ZhTnCupA6o0QnhVUbeJetHu+drmk0r Knmc7E04ni/GFvAgoYwJVqk8uC1KzB0wXFjucb+3UtC24A3OqDlKxWApW6RFZsO9n3Wq18Mp RAdV71rPfFFeOcTPd+cOj2g//GX/oHGriuwXKB/0fFGHkH737jwNT3igKY25Sf+YqViaiVbR XkbPJev//nOS3Pnqzo1lhfsWdtCa5wmFyY0HFFk6571YpTr4p2nbcWzFL7yU/aXzxXOws/K4 mmQkygx6YV2QN8iCcmSQkqtCSLNs6NiMRPnM1Tis8ISulULWY+aTv2abYfH0yEkU4Wz+rB3R rZsOyrKLthEBlvtczwoOa/X9BTr5zr/YxKn7O4h15tO+CyAjr1kS8h6rpxBM2xrDNHKoaJdO UzdqJO7diSZoys+Kbqq3QUL+3CykYY+VRQuZkJ+aV69rowDW91kR6uyc8xIS4v5WEUz6j2d+ RTOXAp9fPEdE38UkK3it/OzAvc6Fv2PAHNP4qG57ujXTvcbpSeq2Tk/toUE1qS7xH/8VGm+8 /EORrgT8OphbVLY/DVCTivhUZruVLeY0VS63pePJjMS3v+SMEQ80JgMQzdK3zjf8qBHnCJGq yQ3qFUSqmmsG5jeFFbd1dbwKYlJPQT4qPEqn93rLIcySWfNxqfs4ayFpzlxED+ZZBXi6o5Ae havssgHZerKQoRZOUKsX+wPnMiySi/vFy1dw8TeGjF2WfUh6a6ZGn34FYAiW97OwM4erHgUJ tdVHAEWqMUAWmkVB/fAeQ4yphylyrmeKqgX03JN6De+NKoB9IyIqCXzg4+TmFydL+uJJlgPP gayVY+8EusjRsB9Fb7XfSWs+IG5Q6/1sKGPTsLm5tr8sz9pie4IsFGxuA1dZChf1QE9ngg5L +XyuXfcdYXQ+IfvLT7KLFmQGKOBGQJR8vt7S3TsUIO/7tXEqAjhmldSKa7pmIVGu6F25z8Of HsRzH/5c+bPokGe4qt9bXIceQR6kv3hxlNQ6uvWDMB3P2n8fSHuwCI9tj8tliGLJXmvIkfnJ B/9f7r2vMfZmDnAJSC+43G8obZeKjMiPjUhR8p5ntzaJHMe7I0zJn5MzNKA5jZ69Ys0wDPSr AhpW/I1fcb/C51smzAIqa3PM0Ju/aK7CE576tAaHcE6u63OCXLvEk1r0Ax4SMI3tIhn4dath sHHUkdN2fvN5GgkiZA4kCcD5ZZkVtcKktmDOzN9YpB+v3yExpvvHtSRbAZ/SMQT1bUSBmb7P kKA6N9v0xnsDWuEADz84ytP1VRt4hAWVWeJtYb+CQlpDxTH80b/vACSeWPUc5o2L8ji2SWs6 ZLvtd4ddjMCMGyKT4vnOugyz7Pp58vGLH/DfmBz+whaulN0h/9afIEmhMJn+Q6oaZLnMp/qQ H6uLbwO9M0nKmZIqq/N7GYVtQADScO2PV6VoxcvFJvYAIs0QmAwEm8AFCsF6H59Xe+ArWxT5 HtRyjew9CiIcPTGKVgCzcJx2Jp+K/BoPC0nFl3vBItNjbAxh/ljjV18z8t7vhmdilsFdbC1c QSq6yqzAwSpmQymnJGKLGwczW/Jvw/B759A7prpI1/DbqoOJpkBJwFjE9T47ulKZYD7Emi1H oiZZxO6FL8dpFw6Ey3jZP4sjcYc7BuigAYIrsCVl0YauV7AZqG/7bvU2BFikb+ACgdy1Guq1 V0oTQwc21nH0Grh+4sGiH25tNCwO1C3qrnLDAVz/2pkCmE+Em8PfaxtLylyu09WSYCI1/zLy Dpukl2b6fsPsbQBaR8nB2he2mkrgJGA+Ip8vQ4Rm4/PGzrWzT9nxFOhf+TdNBwH4kLi/GUby YNKJqFGw7gPgQypQfoVZ4ZWilAPRAw6RrlgP1wIDRO++bYixn8yRhy51d+MqpakrovXTmeHC isb9QSCtmK+OUaiXdTZTjcHAzGl/lU08XPbuD5F/bmrazHu2GbZTG/m+PRh8Sqdur9JSartI LfOY1HfF5sC9L3ve003pV/10+xovZ16Hru3sqBQfqA6mEnNNTubI6hAD5YfiXjPov+kNpyd3 R9HEtfl75771+V1ZBnCN2leYxB/NbA7UuBiZ2hdnH8gZ8jq0PKPxKysYlRo4jqvtmlSm1zaL jlkTKzH2RreJUo4Gf6jGRusi1JGAB5ylxV4gM00CBvuzFCvJW5gy3QjlZPgo0ElbjtajHl52 VF+7NfC4IZ2FtQTW3zhW5HsztP3X43BLv1wvKFgJr4sTkKYv7HEmJoMasZATAp3z27q4b/8k kX1WMdGb8Ydq113zxWHsaCSVymoOsmPA5KNECCL06M3QFj2GSo89bEzm8aTIw8TwyMDvRVZj lF5OIcXi7WL6lzIr1nboQTKjMEWx7Fxwq9KjsT8hIc/GqgefWwtQSMSDpRw4WFaeN0PW2mLN 8gdZ+WC7sqI6wzJrAAVDR7hfSlbdQCnEAcEhdGjB9Ic0bvrSsXdjDI3ADfB6GCFLJ8N230Cr tYQjF+R/OlQLXXsz8rDEGqHEFPeSBwzUaxIK1lxpY7o5+46TioMPHy6AJERYkpgQu9SowcUp 1TPvEXl6/yZMsl/qIjlGwTuc4Bnh8rmBVPE3/qWE9S1wLLHeQjM2SZ5ijeYuOXWnjs81Ctyf Iw1Z9dNzXI2QWoJco2x3rd0UW0I3LLNwMucvojSLiNMxyvZeuiLS9V+plhDrWZaI2NF8v3Rc ckQ7tO7VhhdpLFT0a70nnXvpy2ZCDOtAGoa4btWmdAcr47W/cZTRIexWJtcN4Bm6B7WDyBeB h7njDHzwAsgH3Uv2QaguM/8rJZQx8ssKQCI7ecHR1RbNdQQda9bAH1MuNLYUsxuG6mS4q0tC KaPW78HLFNocT/TieNL8rb3ErXhPt5z9gH7Cu/6LV090+YqIzUadxp30AsPVc+C36GUOG2ht xpFNmmnuRRfpwtRd+7+Udn0FZGXPyQ2QjNaP4Z9NiJQatfB8u9sDTKQW0a+vkNsp7A41qfSs VPDAwNoe8Vg3VJm4R9pCe/6ai5LncpZLTru6HMkBr9aJWdeuOKTKlJjLTBEbaGhM7lH7JrVv rtpqNMy47j0BIgdMXa8hwJarzIhZpIgKJSYW7qyc70MvKxF6n8KVzqjOxTacJ+PaA8fYyxUk tIoCbg/biOf7OrI9m3k0x7OWZnXYZHwv1RIUNOiX7VOghr9D2sOlfTVMj1SpmfPl29kOdPlI 8nm9lbr7omLPHZTiBnRe5rCY2YKsDBUpGqBZlPSKzHlcvLzsvX95qEr+a9cZAS8JbP9dkVAW rIOY4GaQaLgVZdGFsUgMF7ByooxpRdBb28evprM8rvcDMtEy9yY82RIT3oGAqhVXN3zTM2Ye L8wexVVP/5fBwokHcxf1OuBslK3DXRJELLzbeFHkGUYTeccAvwAtAdvcWT5BA2dA9AbtptDM O5SaIn3wY+e9ML0SkDkcSdUX5FYKlKfy6NbiPgCflnTpP/inv8kk+draqpIjIKKZ0Ff3DNdf 14F2HmZf6taeuHgp2V26GvA34PtAMwGxFIWoFh5X6YRsHAuod1PDifnyHuOLvBNjY++jbvVd qnGW4IsaMH273NpkzSJtPWzcETnEkv/flBKBmXkLZJibdla6M3m7cyu64Km3zmK1Fkrxc+YV uk02IZo91RyLkaEzL9f0NCijeQ23SKJKF6VUK+V5E8cetmoVWZANwRUxeaiGtBRlkTERAN91 0Q8Kfue+zldQ7YzJASiNfjmtlyS+e6VdmOkyEPcI5JsuhaBJxT8WtTgiRWcO8wLh7l/ksHnM 1a8zo21xLYuqDhIS6wNaWk9Erc6boaX5UBEEDkHJnirWxe2I/445qecB0vvZUa1w5M53sYW4 Vm4mAxnnYe0PDNc/p3l/ujQNDHxbHWTIK45PXuP0HgTgm0TErQYcgKSpjyPr+X0IGlKdSyCo sJOeWV2DsnGcjnVHWwdO1tdsb2CNg5KDvzn3WsrrXuS9F590HV3ogsDYc1T3gWo9qMVAw0NT +cG/025IA647C2+7WvFIRcql+enaP83E4sPguI4/7Do0wLmXxfO7+zdvIKmI8raQVpruR1a7 p8IXbzpF8VjSCaxRZ0pkEy4fVjJX/n/eLvdnX7ZVlR1Ii8ut4zPxGGSYVMmxD7EhFTXi1l18 V7lKzoqT2qsxt73KKIkGcabHAjGyHtNpwxnv/FJwjWPp1Z0ZGUOwsqBnmaq7fA0pfovH48c7 ZXqeB/MtjzzHb34J8xOZF+cQH/IoSC87JRXk612QyCu3Y/70Eo11CQBXf1Zt0LgmIJPvpFIq we8bRoIf2uRm/1AonuyTYKZGPgVyBckuCfiIYydinfQya3raPYdf5HxamQn1iNXYc864pAJe wdbrpbjidlneRx7FYuhLzsgQqTw+0FiL2ZJM7+9CgUH2JUaU082rp9t3apBHWqxzSh9Ie/2G 0XU23FVGoB2tZFD3y7uBwwLoghCYsFerCPzr02xvwJywNuPOJh15LVKcsjWzr/FK7etH6bI0 9WmD15/i4B/jlZFWVGcMpAgu0DZtlQo/+lIYqUCtLprvm6caqbuOdBtZShvnX9m1+wMLVj2J MTDLP14rXxeBc8wxdZoT4elcaYJYYyAoGAASJF5ADSoC3xyXKMYx7zy29xQdvRABvirgx2cf WmtZHAwfOvNZE0CrukPczdOmkBQLv7i7M48tJ3UhU21R1B9CkaBHZ0/OsRLPF/z+Z/8VuGDI 2qENvucvPjgEPHI0EMku4rnGiGFED0F9yk+k7Ctz1J/Cxi3mOEKI099ZP7D1zHC5cNSzBqH5 D/fdc1/i1/sn3l73DFDXKS/XGZk1XL7wQMJ+/I4IXiO9hnBzYG6UZeeDMSR1bEh/wkkwgeJt xOABq20NSTES/wc7JuePXKcl/hGeGMyVhOw/jHGeN5lP4E81f5CiwQj1mFz2hLI5qONK7ITL iJfvCzz0Lw5iRRWUEvDuEzYmzYTUiQwLUPoXI3crjjvZBvecJ61Wc3G8U/itZWVa6mw2WW7o Fa7ZQWBsCpgDwdZcYEIN/fedVKmdL0RGpsr9eWKv0ZjdQgTrotFlkwbz+RhANl90E0WzT5Y1 221uCLhD3frAr+MQmIv1OB/v8d+8WSwy6ONRMWoNJLjZ3ab5kCyvj8AOffIHK3DuWzLN0A9w iAQ9ZZGkfof6zrviT9fufS5pxn1FR++HbVpj6Sc+u3gs7FztecEFc589Xgq3Y5Zb9c3ypX5r ep5dIBfeozqJ3udsCZoYmuZvc9eQL+hszXk37XYCI8vc02TPPMj+pbOynQtKAZPLfSwggZZ9 io8qOL8sYimUc7FN8te4eMHhBug9L5SclLomAIprBKb/M+q2BfakQ4AqbIeqJCdL7T2gCy8u XID7i02+QNg1P97owiMOi7IHCV43L2pR/HR7evyF2uWWXlt5+nEcoXXShpjM36yhu0uV6SyM iNHQ8Av6MGnayVIVToU3ngzBWBrcmkVlNis934Jrd0tUt9hHzhXInRL0cSjFiASoSWnF2MBh qeR2C5XSdfn56JyWHDU/HBQ+6htG6zs0xEa0UbVwpAIrjl5k7lRzzp2n4XkjzjQORRO6+LlN wZNj9BKrYj7r0t+lbpEeAjpY0lvADmgJvgWN8L+5NyrMGPDrh1tETJEHTy6MJbGxGdrSYhkp cGjBDbYu6JfUpc6T6Ho5jRo/BuZbBx0CgjjFBdpGM8AppijSelW65yXkBMdJtc7G6ijeCP1C OobY67d6F+xzP/9J8GVZ2AzdJeToByqtzBBpVa2CgzKrU9/WcvTAi+31jTS+oeadEpsIIdSN MRCOOQ2dxWsNhyXVZnmmQ3vddmApqNNRIxYSLcTkdn4nexlT3abvS8kMbVNvlODJPyiaxbCb 6atGlhPuccj0AE+6tt0twK6DTuiNJXPZuJmveXG+4vjaN9rJ7tb2r67vnNmgFLQMHe11tfxC ZEWDxN5Kd1ZxTNApwO9qNsT2TCzkTBLjiE6M7LpkXNdAfBAlCjbYkZnpCbU+DhdJLZwuentv XF3FOuWqwz9o4W5XddNhz5IJ7OawlduTq07iP480KJh6XrX19U76tzwLFbV48FyaOi5XS4Lz ZXYk86PoqlClPCUsL1G92IjzKFpi6YVl+jX1C8jUvVFVCDoc5jknMOom7iGzthyaB/gXXBVR Aw+P0DxUQcwasXaqGZ1uUCFQwwoCFXleu65x4mlfuOOQW5SKlmrxQE0vpGkvHn7EmL9d5sMM h+sR2DvkXK4LOv2p+7g3DqoTNDa1ZP3GvEttDbnaRgWbydPvOEm8kne8282PebrzOqVhhBnu mdDaIWd+P+kaXkqxk5dZScdsrjlan63xQ6VKCiYOcO5D4PvtYY3ZZZDP8Aphyh8/lH9U1n37 vcufwkainC0S4ROUCPFBC9jgblJJPepDgqYE8Ea6Ozd1fLiiqBzJvLS2U4/9IXGBSUQ6ZCDr /DQPO3++Ejw182o3mDTOK9q81XlEMJl9jc3FS7pMM2t0gAV995Mu4Y1ed9glcSuy24Kqy9Hn tPVNPxk5C3cl9BvMFku/IKD221K5BGksLWXFuS1z/bGBFag8j1LvMltgt43l8ova8sVlnCdd D2284QkcYiuQi84sTSJ95SRJqct+ODHbzaNuxpd03JCPdMvBJyjK4zMUWGn+xBp42X2Xdfka ofA+ZgUx0SAlsZc+4IcJRBwj91NAOWkQlk+PIG5IuV6p5fC3T2NtnTI56Ra2R/2xRgFSFo+B 7yFqVjeRWP6vh7fApp83Gmi7J82fbuNRqFF/d2KItBaBKhkHrMEy5a8qpe4CQEpsH8m3ZeuP faT5glVt8EdWGGCKdAhWiqbbq7i10PyskvbtYSVTruyTFQnAOOPVwiMuQMliDydqIcuxfnag S7xfEl/bISCN0+/Kx0KAfsnGNGP+9Tn53+T5OeCTJcZINLbOKGbdJHLqiqGKVMyGR4LVy7tw xfZQlJQPMkFGQAAXdMA7ZiiV1UMAPfxXJJnhjZzcmuhqDbkxz+TrG2XRj+itQnhYpZeL8N6e LFn7dIScjWyHrAVEgPr74lq7kkxLeY4JCeN7te3C3Mjt/PmuUdxq0/E2B0hhZH1uLjXwcOMb 6n+Gl+vWgBWRsRu3rtSx5647iOLqaUNpGuIhE6eA2ZiPKYl0oK53Hh3V2hJJij8VywrQJdLF aWaPXIf1fnQOZT5wf6lAzT218DmKcXpRlXzY67O6oP67qaW7G6X8ytZKxdlvU+o5C/un+Thn JV+XoLQ6VQVPVSolX0hxjXoEDZWTKr6+o/egx8sush0E0LP1PZiswJZdV1jA4W/lZOrN8A3W SE8JABSKA1urjb5W/UxCPxwRuZraXq5pFt9PhMv7GT8nACWFDZ93szDtcB4JNkqIhPAUBvxe rM5xWFN6ASmT+PStAPji5aipdCGtcJzAKh9DA1M8gKOJs2OH2f4hKq4nhyzdzIhaOH8K23+R XNnTuuGY3ZW2k0CJ/F7FAJG5G58RD+ZIKDCNhnMv6HzpI9jocCIKIqcl545/t3R5fkFRRV3t dvfr+adqH6X+bv7QutjYQxAWaze4upt3X3Iki1w6ddKJvXp7BssK9ceCoH9G4SB8YmncnbRK vhZictLhfNrvKJtpNHdG68j0wScWwRFgQP0x+91SJcxiaHVdygfoUjzoo6f8whozfsEA6DVD nGx9QEUXJ/LZYqxxyua7FjGolXERSXycBlhXmSHd6SYQ2aIpONg5taSBdu69NlPWSeFSl5Be yONRictUiEFnRexY8ohXnCYzeuisDLO0Q7abIKjQPaBLY5laeRQshcRzW81GlkW+1zEhhrbn 1KssQqeG4swO+BLpRLq4bVP+iwzkDcMVr+bEm3p3I1lVspp5EAUUipsl+b2ZHKTrHmcGz9wc Cul8xAYdUQznpwOUl/AqVAgocJeqjVL1aibuAZ4nXIzKqnQIEO1GXQEKsjYaFLTKf8LwWA+2 D/kI7buwaHDsFo87oGHXoE/ETlgHPzXYhuCanZjtBZ5/u+J+QwDH5ARoQfV2tSAc2oGjvQeD 7/mptUtbMiNsIovLVIa7ALF311gL2i+F486QO09xaVrJZVzIblWcedFkoPlV4QB2NTqqmJGR fKTumghaGtL0SPOsYkSejL+6LmTwEs88lzLNv/erf6OqqlufPrz0den7wnI2oZTsop4wthwE gxinM0V9EU0uZOrIXrOHRQAPSgRVb1vLmhwZhAvNsXuAZpcJZSOaZnBkfwoMLDBMcC++loFf cpgnjZBQqsTQ01bo2q5z204Xg13kTy3Tjs92qJ/X1YZBvSQ1SwNcZHjy4X5uw3JohFuvrFw/ RDZWr95iIqwbFctyVZmAys7dNHrKhK+Dxr1Nz+wkGBudUQwBZ3C84Y9iPemnMrouDluLFwl9 vdr0v4lgWJ/MigLUJ63YpggY1fbOpkDW6nPLuerMIIUqNwgxhe7PNFhG+qPt+9Ul1Mf0Vaw/ d8Q2TN8jlRL5cqcnyWGzk15Pgdu0KHPnnF8Qh3Hxol6yR+1KNDuhAo/hJK3vuWngX8ZeF53H ew4eOcanerAtuvs5RZQRm/rPJOuXA8x8Qfo6/votN/KuaJrTWqmbdyEGefL5MYlwj9ADW7iW 9MMba24qIUsuz6pLzGmnUKfiYV6AJOE5FC94ypkJsHT6VXMhi9knIDl39xpO9IarTjLqgrfM ecX9hxUKsOu7OZRC3y4TK0To/Kaf4bVnLAdB+EKExGhvNkjQNmFN94K7qw8GAhR5l5LBe9KV xUN76HqMVZmujE3gNbrhvd9UNeWAp0CT/l7T2VPv5rddFRw4mmyah6+7d2YVJiwrcYBlp6ZH iJXtCUoz3ZgxyWvCeXn5E1un+BJk6+Mw30PhKlLzHy5o76qHz4ZgJz1aWFdZ8/CeDEyW1fNR RbyKLb0+30iVFbBGtuKadv2J5C7/nTiojS/I+DaQlZ79dspZ3hwIrxhpMl/HpqBYwfxti9Bl OKiWoO7RjySrZrUXjmf+PZTIfq1YtkyFQf9z4NNEmR59go2DIZCw351lcM8NgGF15JjlCeiW GvhF16CU6fUEbHB8KNyfSG55ayzqeYSVZkuCWyh9DJ0uYaPk6qtSWgt21X6RdhL6cl43tLvO mbY3vrxTfyph6fNfa8pM0j23Jp+HNDBjCIvQZ+xLnFHoRV3XyBpae6dxjAlQcgkGJD3zcccN YmJzRcxCDiXd+RM/vNmrj+ZOGKnQJDvSq2oliO5OTWYI822oPCwMp3DaFj4N47V5bGpJnh9t gXrKUHwTmwaQAyTyoSty1cCE6dKQlme1QAucyXBdA82UBx5/9uL6olm3cIDYFLlbNeI7urna xrlwDOpLfVd5XOKYm28HR+9QRw6fXgDZ+OsFQxlckhIXBWfg48meClmcL/Z62VkPk0B5Dzy4 xEwEi7rokw/92uGn7Ebl/TEgof8EZRZiqGCIcfBpjJe4o2TXD9aM2FQyDSY/mrYjePOusm+n QgHVH41FMFqA98SX5cfyqSw4/Foo/dUaEsSAAqVC8UegNJ1sHRu5A47Vj6v0PfwUhEtOnT9M ZHOQNijbvufMxvkTCugd0UQAgO7sDEghLg6vsF3Vxao5AAn4P3qTKYR50ThKDgjsMBc6oYb5 P83VcWyhsYoy8PTEYKqbbBTKnLI9yg2QU4jqIUZx+nt108d8Ca/6euO+sim0T+TEw5RFBLdO 21RZ7xTHGnEYjD86mkZu/Je0dIZMO8utI91IlqvrnNA01syQqUPCO23RxVxVMPQoNarQ+owd 7WXgR150n+mCW1F/8rFoo3bub9C3i/soIDW0Eg7sh5Xu2oZQs5dKIg1TDyhUmweFFkFdJ9J6 urZNF6aCnMLsp6dYDcogG30CXhOM6+ik+7g8xXHICjbn98hj9hVuLAEAqCTNa9Brsnx06Wns yBthMllKwjtv+dTEMEywsMeKazySRgytIDhB+Q8LruayYBq/yn/Waq7CWCD57NqHuSX1WZ+f lp8PkaMJKMri+Q5ba4qzrpTD+8CD/yhTt9E0nIWY83fZ3k8mnBnOCwZMY4QI6KPDtCkBxUbr usn8jJVd1K4n+F+g12jGaSfKjFiL1NxeUBETPCyGR9SDvqpV+VAJ28dl/YrPtM7zfNHMOnWG MlomNiS/gw7jotvbdnJ8CU+PpAUFm6Y5qaiYmX31t80MgOjf7DpZI3YhUdWPawOIyBmFqpqm CETz9bBbZnOaYJN1xof0dKH6uOHLtHj2N17K8wZ/ykvTFrGubbJ8Mud5BLX1Z1eQ2PHSMSQN QhBLy31WDpKYwFnfJrScd/xtZ4LJyH0NBCbUhWFGV+BtDANwbd/N3ct/KabgJXEnIea8BldS Z7xxHDiRqPwg3Cew4ab5oKH1s6byFe3W/1dsD2KeDImQ03ljOo3MRtRy22x7H0hZh6QqhXOo QD0TuEDlEeoNlyQYizfv5W3tuVYCPgPYZEFfP2Q1avdD5gI4aalN7owZ4cOrG3pIyMyMT4aZ nvzbHUrKism+PewcKgn0rjGKt+DFKWhTTTSWMiFK42YI7NOYuMMpeU2Nm9XfisJtEkmK1GUx Csn4Mz5O7Ax5O4tMPQ+O1/wZKmcMIjNTVbk/ZH5wXllw8qu4ZvKeL5tJzy6HF1QVjR4bq/t3 2y9C3eERxZYfwtJo0tl0FKm48dfsMPAanSRCY5MlNSQlXnzfTtwAxhXO55IXuqOkfj+DrUWJ DHse/OZX8W7iHTVpja/9Wd/DC5uYHp7Pde3YTLJTUOEI4AorQY9DMGkkT9Y56bu/RqgWIGCM ErckrXqT1bm0kHZk8JTNW8pDBSWtBZKq6t5yb68ijDFLWH04VlT1GKtkg8dtzhpdiGzUufNw 9C6iXHlAYckQs8N97m+uRebWmKJ5LI2z+BwQREf7b3CPbxfNNHyZdChTSYXPm77qyG7kxjVD 7PGZF4S/RWjQ/xyoP/Gi6tYNlaGl+urE5GaQ/2GUtfDY9+c4aP8kg7VfypZcJDvxWj1nxGpz tmc1vKQznXIzorLiMEpU0JfKoLr2tPI+VT4EfF3AGNfnVrpM8sVU0JlPks8CKG7m36/0bbMB IR3P1Dhqb75wSBgdaUiCvnLGvnbW0oe4GRqzsg0T9/ZvgBxg9kTY6ZCM382U/bQoeRbl7lIP Cxd5UgYULN9g/BS9iYcVHnL0bDL9rQ1oLPcrUNqDWnFewg8kbkGcETJWSiApv4zKAAqtwIiu rqnmOG8S1fYX1UDGgERw6RbNK+M1iGrHbasIdwpR59TkyrW+P8abwMTB321LcaZMM9xsm+vH 68IF1/mMJc76S6G4EW7DkQGK5QR2ngjcifetGYXBwuIO2k8Em1pnrJdvevU0RoH82tATy+S7 VmQB/LIBm2yGJmiQf5UWlbIzK6Ps0rIV42x6mNA6+OqR1bN3wwUfdQ3kpjNAeJ+rwN7eun5A 3acU9lzzEHaCIg6a/mx1K2g7uuNfV+Zqj1+kPHuAEysQGY/Vmqfr4HZy9xkK4sFW8A7PGiJ4 E67smdnoXYZkp7oDi3VI1JlG5Gi1djvlKgljdZptkyXjdCKDh+cIjDjUkugtunx37Gst/ut/ V4tzFZhHKCDBYoCLYeO2DJQwD8zFNxJlMt6fucm/dy33TFI1f03qdMfj5YnC1poe4AQCavC1 jceWjrIARt0q8zSmS+5u7jmt8WfwGFjEAMedBG9iOkLce842SwUzzpSs9S9zr/aOEaUgHKiv 0MyMqHLkh2Sw0PoTj9ByWvrpcVZEifIIog5uvcWafLtpijfruYdOyvQX8vY043Vlp3cEe3lg TYNTCCATXcQe9qhxHYTuJLifieKik1jp07LEr4G1eK5K3m0WhL2T9LivtdlIXgz07pqjI6kW fqAyfyK8h9/U+Ikg3p+owv41FvAY2nggmUN9hSHLF7zmhGZ0/0+FCN2EgbLgXrhD/MWcIUTe JBrjThU+6ssa9czQ8DZGUVhJI3R8/zvCkOC1CI9qghuwSXi0zUK5jOEkQTFQiMb/9Q2EHj+q MhcABMheda5VPSOvfkNQga4Pa4de1550bB3/N+x2Xfd++rXZxq1HFOMqEwERTNL8XBW6xt+j L6/TIpri/1XOKGjT9pNk8iOnYQDIco40wrdA9Ls2o+vvy54Q7MKbWw3+P4G4v3/PECOZ2WzC rWuJVuQWPboACGKMtvLfWkfNkUSi+vN7bjwpDxDlRuoAG9E+Zi3f2pBPGFnzwSlhUETvXW/W qpA6Lk4pVrUYmcCVepVhIdouz70O7ja6NDTip1ZN9N9NMwzUI6T3o0gs5SHpD3j5o5bI5gDr EL+WXZWN9gJRRAtrpf/CvXpzb1FW0jKDRSbyP3/QHTALWseNb1Vfqzyw+Ec9uJE3TiZeSyUq g7ogJbh3WnzsjwUeW9qH0yWv7R9oQ/MIYoJIs2nG0vYkoBM9NhO0thiGI5W46RZWIHroEGIl RnaIdbrhRM3pC2XMNN5ePalyshtTCMOUfzJl+BitLeF/P5fwhsyKO8b4MIeDAbhWLChskV0R CPjBaI+xatZNeNdygvgG7qosCfC27jDKk3WdaYkkgEcIAY5umLjn6CML3UMS1XeQDkdn96pz 9RWkmZimFzAt0+ikw1H1x+n8JayYSnydNaKAU6oJE7xaEH1d+NiidnrjJwsZdaOYN8Mtm+u+ HZBlXolq3yVgB1Q2vSve3ycDUJr/5wiguwu0PgToHxlls7hT9MfpUKQibCmK0bH48JrYQg6M d7Fi2thjVUlJuWW0WViCXWcajQV70Z1R0R1Ok2rLdsIBvVZorPV+ZdmLbIA+crbWcwH1Eur/ DHGtqbSb7jga25AfgQ4YmgGxAYqnpgpzCrYAodGbh/jkwQjYV1jjDRbMu4haoUV4dhPYkUk8 +mRPIoVI5hSOde0jpLeGFgvZjr0uIhMr+NwfeSB74ucd4l6jO+Bk4tnkQrpQ5jR5NZNWa+BF /9yzP34laDyW6R1hOdd9vWi2YBXC9XvOdgNp6Qi6wb/+p1N8gjLDCyloCzcM25a2/DMgvByq GnBfDeY+mC6L1UIorLrn79YlO+vS3WacfJILo5WVP7cKv8Mtx/UaOfQhRlpcB/Dwegx+k0xn mWARFAzcJv719Q5aR8WrxUMqiyt3tC5EQgPnfwRCuUzgfABt9rJmZT7FZEhf98wKshIwmeSE aHkYd2Q5WYUfCMEdYGsqa2EdIfH3+Ll6TdxpI1jKHLKsIZrp4L+8/EnuUb2vl5D+kbP6ZrPq 2QnA3p5EZGLmm2TUvskO/D4ju0SWyLzAWhaXvm78Fxa859b3Zy+L8/hlPccMdhRlZBxto8sw ztGzpczLQap8qPuOmyPl+th/5iL+BCJIq2qUK1GUCNjaG50ruUgbLBb17Y8Ih4PPrDZieD5/ 42VEfsVsgIWWeEr/PApb20hLI7uvJKCL9/kHDUEwIaX35+T5Eu544XDmaHQWVjMxseWfIDGI PCby26XGut+VVpa1EznKC/JTvv94TtZAfb0xoum8j8DL19XFLojX4stuki41Fmh48dYrpqTk SglwDB8yFCeCpNasqfzJeruEdhwsc1ME8HTds+vsL6DM4L+RwqHiMHjf0Dip71RCCO3gy++h 6/yXXPqS/uqrtowso5dP7fEdJuFvcqNgYRBctXAP6hbxvAd9ffaQMRVujdt+NZplTetZzqHm H8bKSle/BRnBGlZMCzGHOhMBm8wx8rMB12xeXdAsArgMBemYZowdkMvodo3comdz9U8wA3mu R+HSNnjuzdb8zfgmCSuLP/r62HnV9QDSlJnIV11DPgHzJH6WFDjJjoX75b6a7+A2EhiOVmR7 mi1B2XdEQtDKiff7Wn5vEtTXnbnWvTcVmF8AZcZqtiRHqLXZxZ6csnX/Y9nA/1z27k1HBNjj 5DkzHg2dczHwXnSLJr8u/IB3/9eWYij3WEjT/BBxBQIlL0AUPGbe93IrDzjpLwLRPbaLLg0f osC+wHRdvgoxfpsU3lahBYj4ead83gPIZJwjK/avYAaikoLtsV0JoY+9RvJ0j/LVI+m/JY14 SMWQMSfQ8TPf0vuIS4EFGTBsht/vvwLIKHWt4BUTyr3GjVKR44rDBwpW8RJawAWYaD160tqP nJ9QpDujs6EPRBcT+GXFk7jK5GQcAA/feNieU/GODYjToa3uDmAH5f7LUpL+yodbemrtGZAs Q2k3Q44fFJMskwGC6d9nScTDAFkWnupAK/z/5gx9qxq9C/mNC4g3OA7Ym02nZHRfiB1g+kh1 LBhNG+mgOXUUb29gYDNetud/aKhrsYBeScu5KrvwrQLkrGOystMtBwvYhkC5/Mb+WnXgGF/x wzCF1jbLaTHngs97+48JGtoaDjCL3jk+pVwQ6XQNMLc6Rfz77QVdmzUFbxEw+R7hrttTfElN gVmCO+3ClNJPgEiCSvbVqHnzkjvsHDuDOmeC2oY+sG6UpdRgyeinCHly95mqOWOvJXLx1Ck0 240NXalJUc2uQ07uS/1Oo23sRJyvgSJoB5lrZ6H/6cbjvIXd13Je9Csd+ZOucSoQEwBdT2Z9 mMRQp96OJit0y2k3E7UN1aOw1JRACopNPfV+PIgOqbestwuHjoFs4nOtkWaghjevkrgOLv6U mo7EjJbEvjMmoEzopmi5l8p26A9zfPVst487IoSqYPAtu3tt0+hUWd8be7rG+G01Y6lxIJGv +5WWhuLEJMPV80HEDPDAh0GcMYUOoYc7vMDCQEYehfL+5XbT2zeQUrb+dfqGKC+f2GmA4zyH bM62zsfeinjp53yQsXGXmqZHBMnOmULQBBLogwwcoGztQKLAe/W+DNkrX2hM2G5At75hpA4p TS6skndd2d3s8w1Bcc5JMGek+dABmQJjLNduGfaxkQwIZrGBkOd1MJuQm2aGU3Q4mLfvcXzZ eQgodPvT1aUY9Dr2HHmvNw54aaid2q3hSTI6eabDOhA+yJwFTmkI9nKXOU/SQECxp16pHZJW 3rLAgMOPW9ld2H4rDTWokc2AnPXDwpBIx0bJy5qxbk7OXOnHPsRFNHImZMziQsfyTyxLkjYR 2a8o6nKqtsE3SfsnV2LT1wihbb9TSn1lOtIb+yz4TLRt0ZUBzhWYFbEArLChZDV4W0rqkg9U xXe5mnzcOdI8cVQZDdA/NnExc+4O3w5Y37PEFPgbkS94ZPbzmKs7GNVqZG2xSO/WMJ7YJRKm DlMF1E/7djGcQJLxMCpkaGwDEbueUOnT2t5Zu+jP3ZuN73LR3e0putVfBLpRvsQKw7bQANjv QcCqhKNFYru00LmEogMOnFaXsZFFj2pQ/WwpsF0BzSj3TvfoilTbm5goizbTfnD5zLVQB/tt 5mncWBW4cAOGdL+2l6TZ4IGuYNm5biz04oQ4GOHhYR0ABaHdk4mpUh5QFaW3AYuuJteQTwbQ kvuGyLzHbqAob6SmNaYJ0vqVE+A2QfPv8fOVjAinFKE0nXOxsejFI4XktHDbvXfQjaf0P7Vm r5+6hWlFp7Qxirpnsdc9wvL6DlrJrcy/s/5/zI6PMTw6GQyC4Cgh+9V/tH04xEpQ6y2uJuWv /V+LJAASwP6ZiT3cd6Vy3yj8HlKy6tN9ohpPGwAGNMMml0P5Uv9cfpJWgNvMsAkmBlViJpYe hq3Xkvf+BiuVlgvm9Rqb1836UtF2O/cApJFA8byOxDtVmBhMhLXqudKNZHSEy0DX23hUSavy zsv69veGmbFUZLsN4b+M4ePcDLsQLPv2DfxlaneVsOPWcA3VfyyuxsTuA3KsBm0MwsL4FM9S +Q/aKrDFSYHGcQW41SMvOhHmkHiKPXH9K65CSqWLUt9qJs6pnWRHp4tF1GGt8jNCfCcTITKg IraZK41YUNAEeD8lYL+2Wr+p4WxNX9TFhhFmnaU/193wBVxHcrDKj64jY/DdnZCL8VK+DyaM TP9g3r9tZARMt3M3HcVRUupjE17bmhVIypQP5DUq7ef7oWjCRiazVvQeU0NS/2mjsFZX/iIY Cb6T0Zjvq8oR9LNIlx7rJILyBYCzn/dSHqE3KsjXT/4rCky1S6gMj6VhY8jBY3cp+0IpmjHY pfBc8baDq+b39WlRHJyyi7BfzPMdIE+3rQkdHNwR4uwvcmMg3AFuvD7MKLvv9yZDQ4pVjkuu hxF8sKKxFnnViNpEmQl9pJ/fX2T90ulzDkkOwcJQYJVMC0Fi8bcVgYa4O4la6AtQADQ3OazC eJshPXxD0YQDyQpU+8w3IV4u6wsXt4vJEpnr4osTaXaFtHXPO9gvP1b5ljmMY9ulhaI9EMQr 1utAIDGrZBBjTaU+EVA5J0U0nP3h07FoPZzvOcnCoKd5i7IMbOGuXLERECA0RBlBn/421pG2 5GgDBgrtLBqEfgM5np6s1/PBan1z3unlfHlGoL3y6kk7NSqEQq4dnJivOj0KAHtmOQFescbz MczKLBhMWDao3YT28rxuWqs3EPmsJ6syyiPwnAAsKhA916ngmKf2fLhukEvNApD3lYpgZ0Jh P+iJBqjbvDcsVTxxa6pd1n2/t+VJLztSvM9N3QDNXNyTcAscAV8ZqdCLpuWyTvdEeZbXEho8 PNxqIzX1YktbnZxy0+jt3xg/LuHIHpAvVVBl0zJ/CnzrxtAayOlYBobkL160qz0yfS4Mc7iW +qCp35/iUabQQ9Aeh9OhDdXXQBRYJUob1EaY7aN4QoZ5w6BACm1buNwNnGEm75zTM2otmWOs lqPclUKoGsuruoJCYaVXQ9SD+ziWwiCYx2d9+/+1f9NQeNafqJAJ95sPjukXtR4b/Kp921jv AmgEexgqnEFLAN0wODWuckrgIvFDxCggRtCebYMxKDLLRlkbVbbYFr2yrwCc2zwdi2EnUN+1 gexlz539dlsL/yugJbYS4jCA9FDhhsmODvRma0ZtZWDz+nNFzbCATQs5AJx2zqTZJ0i+rwnN H6ssKwMMO/7CqIG4MwIQCs9zwkk3OWYtiL7lRB6xfkwbfAtT2jgO0vGi1dVv+8v+kRjP9gEL Y1qcwoIauB1Gwq65wNTjbF8BX8QINDs7IVbYZ1DV/qQgk1NQQ5Qg04VxfSKhsBuuAa43jy8V rPMfv0Ns8BnYep4LkBxRWSrUJN1C6+H/pk2X0hjwpr5g8Yvob/kBfjggenMye0QuZW6QXtrw KX5dJu1qropfkgisBWImn3LynbycNvMZ+EHSivquUHml73Zm0tI0RegRlVE6vfQ7U5hsseX0 Il7yFv7fI3ug/yi2WyvISDvH91CkzaS3Z0hNU3IvkcLL3ft43uda8pY1uUIoYIpotpmUcAAO 5sezREHOx2IAQPcw8v29uA7zItegPvJEYt8btj3SxjqjV8Kc4/iFxLzfPAQWd8m7qEWiCNh1 d+cThs6AfrtNra8d1yB6/gUi3t/n7Mnt1jiNtZzo83ESitkmIfqnsj3g01wdHfPJCH7aQWVQ yrrNsGLqGnVaKrqqkmx3XXzdm9lSpkb6z5nimAmK/z2a8xJ7XbotU5H32YVPIzIxBOTul6uC vEhr5iI55HKAblmpIm+I8v3/n0HjAzfdFh5QeTuDPtpL4xPgz4+ra/tzF1dte5OSi8eOV8c4 cTYcPJPvx2D/0gZmWY/DJKlFlHLdkaL1Oq9mMmGvahfMahwMoXhHy/yLtCH3HFJ/VxHLW4ez 4PFgrlpIVWZqGhSJTlHtR6/AU9k0pi5IR3z/L/SwSj9hc+oLzOFpbL0IKaekOlCglR3TWDBP L7Ft6iXEqjUSaj82+jqqOsayZJFh7HAaXldaPnFs21GvVY5sti6m8Bz1rBORVbqSWEGRzerl rgmgBp294f82W0caeuI7jA0+I3WZ4NilrIItL7bx1vzrqagsWymLJTC+05f6V0heXPTyEd7A 5LTq0ooItSUfMjahqjJAnI4u4V61aT4Gk2vz2ke76WnCwCf21/P9cwa6e2I0ocUKEBCnGvVI deVIFqubJl8rTCX4oOQfyQhIHK3IQOP+QabnzDNaNEYMhWS/osIkuJ3Bo6tlpn5CYWmO1BY4 xk+s413y4jnXV0jJk0O2br08zvly54i6JC1xcxNwYBBNo1hehnZDcKMAJQXmD9oW0+WpRHDy sgymyCm4n256eDqUwE89pWU+fu1K92vbHk7k5r/W+qMFEctsVjbRBUoqQ1gVHe7fuY3Vn+/9 wXqa/PXVgUOWoyvrqooGDfaSO0aHYru7wDDKgJuMjciebatkxCUe7x9D254TZR5d2JNeXov6 YnBIZWDaOvHWl25ixvkl2PEVbVCh3IWUXm5ROi2jWoO60tVyHxIfOMLkQT2HFXzUEsY1wpTu akkcXI4FhTSgyVcrC7Z+sErA2hU0iLNNEeibNAbWj4khrw2ev6DgLLR+mm9YBRKzsx46F1Ix qGpiHHP90Brg8mbpFRuB739mGgk3gSjvIbwcrdmncHO3ZqRRAecw2WBq5iACY3HTYbwi2YMp XPfrHOneXf5xrQ+Y0+g6mIxIkBTNKQLBJBiWL96AQEsJ/3m3fA0P/8f0v+AvkVEWQXeYsF1X Y/YEuQ0lQGAIjw9mcLuGjbQmyuWnFiGfvpJk9mEJXsHfCibSINe1DWPiNovFbRQ75ZWeLz7y az1YYpdx4XVJNuHLA1pHtHpTlrt7ZsVqGmzZd+d73b4Rp6r2UVuH6Gj3HUOHoiafDS3wUbFa i6eGwSmEI0BqQ0c0tx4qsH6IZyfcGMkQhrAviG4S0u/iuU/uzHeY62wi2DCjl9YPxqTDD0sz 3kT2jS5bxmcE/rMXJSC02MJqxdcxcxN+SX8A5WxZv/p+yNL2AejohjNSARq+k1kOw6nq0s/g lHT8ZyA7AD8k+wjTIej4WQuKYNmbnjf9J4e27TBJLzyX5xb1YrpFgDoTljUSUQNDCK/ylV70 r4hZ2pmjAKOfvWBCM/Dpl7e6xei7Kcct7ez4IDSCttl+afDGJ4cfiGxURKa+fxZh9WB9jCy/ jCUaXeQV/lNvEXHQDYosAJxodcL+dPVh5cVxaMS9G0i6/t4kpfTStGAsLiBGgtIlLzLQDEc4 z8aXYKUzxFjTd5XUXgtkxvyGZa1xV+N0o+F5O0ShWrDE7vp0JZknSSL2mdHu2yIUua4DTXhY lKacd2t6AAM3pcaHfiitGmxqxysBHKs+u1yBaOgjuppvT4ge1HNLiMaiucx6ntjKRfMv/qLd u1ynZuPMfPtx4ahjYoo5VSMZTsjifxrmTkhowKUgCEiWazoUq1wLwrlP4VRv10NrDufRtk0Q xioTNzNI6eCN0E/u5fNLNBxGbvWjYQPCe8U3o+2zSAITaQAB4PJVSM3XH2+Vikt0L9abBRnn qCxIGcGkQx5k/w3cU7g8DbTsvEdm2p9RfPlZEqBqavUAO8stISEvMhj0AU7wKlNxJZsRzQpR KOyDP6YIviNeIhZJgWWmyKC1PF0uw5iUWeCy0zEyq40h307ZYHzmMx6fFhuEmrKtwbB/+1X9 9r5rnnVUNklwTNUuP59+I0y8GS3+eVYcjK77gWlX1zj/OB9CAC3FTUyyUjWE8pSYCzjHSl9L 49x9unwSUMDxoinSIA3w+w8jfblsXheEhVcwpWPVwlnJdv1a7I/1sCLqT2kAueVxKoobXk3q DRQUSC5jx/fQyxA4S3veMsm0dY7xkqCQG6sHk6EPqhPLtF6KkiLLgHdrXD3Mgggf5Vn/tIC1 RyVyexyjLNIE/gL5se3ZhW856EfW3HP22+I4YQew1MfzVHVKojYLcpFMViT12MPcFDiQVibW JMOXHZD9j6EuGynaziFfU/vAalM/LA8wNnOHLauJ8XAvsg7+stCu1F2xou2cPzfoVQY22bVo 0TZNx+jh2huQKz2UbO0DdO92DBsEdDO3U5rXYVQgvy9PJsaJDac/oO+J3z5NXbp0USXe90uT QykDsWTgmCjDOyfD3ifCQcaHZ6SLu0MldRewPqmz61NoL/B3Xr5uoX+27C7XfWIFTNZRbis3 0kKjXU7dFvH6nHKc5aYP4xjN/hfCKpAUJQdzywTcNR2dNj/tO5FAf2hl8BsU0dFWExY8X4R0 BVqVebBO147Egt8+ZTFoPmZZHtyxzR6pdA0MGpzfdGeyCv/QnoiSV1Kjm73tD8KQ/p3StU95 f8vQ6GPtSefNF8u+lZLA3yzD88i1Jt+9y54PZtO4RI5I1dynYqR9LCO4OWuLtlD9Lia5Z91q RvjXAD20/RDlXjTyEthUxzll89jVPvtaVs9psJWOoKhKTIo3B9m4ze2Ye87v/bW6Au5a+se2 ubxV2AUzp81L2ROI8jkqEd6ouLDgHLYvd6eJUkpS1VKz5uBNt6RYMS25q+NzCXhnqLCw0iXy gG+YFtQRRCjR8c/0XwbQsb3pdxLMWeHkNnx7uuFDBLrSRpphr/nAdCTkRrE+EmFXsRg8wDjd zQDvjgdw8AwQTYfRMHruyuZQl4pERbw9P+tNhWTBe7kOtNsbKY86yNyX2VF8/rlHEnxIew13 IzuYogXCm3wuvB2mcOTy8VHHKUGBn+X22pkGASPtTAxgHD+ZGP1X5qE+OiC35ajAGYiCruEX yNZCZIFNiEgoQNbVuovfadqDfKFuIXLK/DLxjrluYBjeAz84VKnpTNGjitCWeMpYwl+c04Um ox4Nxh2h737UgrIAR+V9B5AoooWt/kScau7WMa83CkZc69ac088ZvvxrJcXFgqv14PkQT9oP V1Xkv5B+WxmaC3mTPYFMwsihBe5sHM9G6R+fVDo17f6rVko3Ht4RwLMPgdvtmRQ/vTDa0p+m Tndd4l4RoMEgwcr4R+mJzN/KVuXxOkWhq/pHvUQ8laiqscq4GvDjdStFDGnEyTPkeVT9BPKR TEtuAEsNpUck61vandqwKQ9FMvJ4aj2vXRKPiwu/uR/Ey7Z8Oq8p+zsMy6oYuKKeVgkBB0wD j5cMolMZnjKwXlDbyChDlaCBUrSGP7Z83/0SNvAW7rOBfUXmIie02L6dkLYj+aNEl+LwqD6t n3MhOmrR6DzqLgEgNVtewzvPpw0bJOfRTQAm8B48IuC3RO4KTS4Cekgyqg/82NkI7by2I26+ iDTCjMwvMijrCYiYsABjdEF5GjV0hjhOMRofUHbOQfrUOmTzy56hXewmaoQJrLMhaX/T4Ry/ FREG3NZYOipWRHe4+ZDsXxhoYU950GqgaA8BEDbCBW9rwhaNGLhPErCm/NqqMzqVXQ3HM4c2 mAWR+8oNpyh9H/HJH0L9lVlNoPHslQ1tUGVvtbRCOcOtuvbY4o/2gHVXNSHDYNOg3BwDZWsc vt/exOXMgpee8LoIYnie1hB9ZeQCh/AspffKGD6hHibe7ZyVf/+UQP3vELa9oMuXHrhGBZlV 6Pn1h1w44AHOGgDw9nE/9EixB1mNsx7LNk1WSKiIQf+XM7AFTIWboxT1Fluf5zbcb9Ih2KTL mibDTPgAIrfEUbGeVO6jNgaJYJ7rNwiVX3w2N/i6/Q/Qr+MXaaeJmLmIeST/iuIl1aIPQSGG 9nXPKCpRtF+zpwnFai/n65M8d5CkDPu2fThuce9jpgK6FX5hsQ1v5iDg2A6K2szHrLYF4VCl ZaSmScB6jzqw+3TAJIXEvk9ubT7NNdBcNT7S8Up7+szWIDIAyCxVPTfozhzFDbGWwdXjoU38 oC7uiwFKhomBtTLNZndSIh3AzDTqnFVjG04QFupM+oxhuVcwUFXtXXJhJEaXroBIIwCWs9ca UbA8TGLpp+5I65SXg0D18iUmnr6T28rV5PIdJRgQ1Y9ZQhU2qBn7ODOOBQEsnboINPFMlfxj d/NQniyI0pYHIu6rGzgA0gtJ+BiBgkKoY3Sd9q7Wq8szbMNDZXPDOx/hiI8tWtzvfJRHiIgG TKdV9aKXhpHlutMhiBZsjqoX0FXh3sUSGRe++EJKBoq61zKadWWuN9AxVAyD42Pd6JWDddcA i6WR6pl6ZfNkbxFqy8Kvzg4r3x2XwzYbjVP4Ept/p/iJBUrkdzFO9qGf9wTrfZvM/y4cSP6J PoEdEcVjrM9c3oReyiI3Ke2JXWSTnynBikgot+DFbXk3SSKmx2IL2AO271TCckFl29U6n4mr v5IpXqBnf2LNkUIzl6wb0iHWcUUZwyId7xQ7bBfDs+PYKgz8vtLN+mA201PoaSFeQ10dl3eI GNKmxMP3ZTE1aN850MtvNuXiQ28Qb6fNisWhEgvtU+nnU6M5fr2jcSow4zlKdd4dMHfoiz9+ XIOdL/dJw+nMWImJJMss8g+n68L8kaCGzSI9htbMWROijEr1gka7LZgTCjUGD027abGwKHoW QkzPtG4hwRsZW9Aqjr1Jkv8ILZ0+nFJd22L3lp6BaEDBXeuhah4RoWtK0zEZuqBjGcH6Iqka 2WQCV/RUXicn0wJ9rARdsinhjm7HH9jteKGhxBpT89y6B2t9Dt6qmpoOSavg5o6Q4jFsP5Qs P6pNy6ZsiM9F6HIXOf0pT/JyBtaOWy3baDKZINcKP5Hs5winlVPU+eiRnLoE0e/GQow9M3On 08cajNc+1l3w3Bj5Me/svVjc8U9DsQK6tw4b4ZWrLrgTSgNbrjo2hr4+vopQwhoE1vOcoBFm nk5ET7UXk1ZtYoMryfyGoTKZ0oBMHOrJKrQf62QHAz5MEIUWI/B8dWyH/lePuBTSNs9MeqYn X5ejDC21uSVMSUOxUD3WL9zvVzZD0AUGZoQcM9wIzDK20yiyhfyAFLmpJRP5Pez8EBeLU/X1 7kRUKF0VllIrmdnxiWkJcxArVjxDieYQiyFVYLXmneAohwr3L3O3H+bxNSGO3yF+JGzlunhy I7en8cPnbk/cbfcHj1fyXL3s86zB1Vd/GuaXKkyMe7687Yr52t8L8jnGOkF1CRuYV59zCsDs 3tW2/T9VqRMcB5/vTQd9dmeJb+NU2GAL7zaTSlLP6BXAvaDvjac9wHELke9DL5O9sxkfns+4 SMRecbD6ofWjln2JbkVDeqm/OReW6cFCK8B7EDurOmYfsSTyCgTm1vp/LbcQdLS7tkLi89tx 7oMMAF5rLqzg1xdCJ1+2Zf83bzrYZqXDsdPW8K3yARx6y/XRaDVXTGyEn5aO6upfAgCJuD7v UZ7pR0gJ7nMt7yvKFBijryVovPIozVZIsjN+B/buv4PRQxCIyHdPuAFtms4yxkB3Fbf9h5BN y5NDx7chvM36LFEUbI4OLffMUSILTh5eXMNgWtNwiOCbWBs6odlQNOfRf4O3isTXQjmGGDuv ytX+3sHxtF2Nv3KrJT84Lx7me/RjhyJ79G2/dZSW0cDbUVmwiplQ+fsDo4r7lUHCaVGBiGqb 9emhFja2VakWK7KyzMkRZO5CuxfmLThV2ougHB8liePicEx0xxeE0cDa7JzG62s0iU1on/XI aCigFBlJyT+rJABzrXn+a2y6PS6hp6WCQGTaaV0iEfKxPrbsyVEgWHHdl21IFL2LMaT9NBBP sbM6q/KnrOfqKaEon7ktgwyGogNbFnllR57wYjx6CpazrI48J/SR5kj9Rk9kso1JcWwtSNXg cxCK6ojQPe48M5HjgQSm7Pu8gvHla9eTUnUHWyarht4iDKBPekk/HFq22+TrfzFdgZtyDdoX 2VWxhZ2p2iUvWp7xZ0djiJFW9fE4+I0BC7bw+JT1zF4oyhPkUYOkoyGL1OGUtI//bWWIaRM3 lo5vVSK7yU2aWoIJitTXKp0kB6E4S8v2hczj9phAyqkkQulyYsEupca458muEt11qg1Yoj2H NZ3pJla5o02AHGfy9VzKbBGH/z2VgE9fwqpwW4aNkFWoRAI33BvZc3s/DeQX+DFQthnxJCYb BdRwWvYH6l+8+knobYUIBiklSazYTuxT8cV/Rt1o4k2N71SatYfa2KopOwcK9Tk14Uc1qZDT b+cnLNu1Fort0rLeJiH9zBZ0VnSjzumNOJzZ7YwsM6nDwdohwQndZx2zLOs9EMFor/lBxL6Q H3GMUYGeO4y+GalTuLqEIY9bKQNS5+KbP9jMWgJC3l2dAJ/Y7YPm6ZcV0L7NBATOY+2BM+ML X9vvCtQRLsIRXg/NjaZRLmeUSPwu6zB6eKGUpj21+jIJMHP0rXl51qZJgOCkbH+mSs2IuxBo j4X9uuVex85vfwJvtnKGiZ0QhOb2QPFf9Lu4sTaD1UjYzbi+OIOjXTPKOxVZ6URRhL76BJty bQTKBKwRnUn1DVBn1eVy6NWClScB8b92sg7zsKgVv4P8/p624vcPZxOH2/cFp/W0baJjApIG O4joQThbtc/SSokD8CJmPMMRis1gR35j7RrnzSF6hBIhTZ1V66KWyvLUkX4YhLJ2cT9kNtZx T4e2J6+v2iK70Zlb98NSuu1w295aMORvFhSHx5OvNkmisKR20HR5sZqbzRHiyMB+WIEncYG+ uqr25skwC2k5Y/VgXF8otgjNtLMRTe2tJSS7Ts/wTOW2KEiIeeIFkFrRgTwvCFN1q8qwcDzh 83I61Q+pOwt5Q/W6AN/42HOQVUVuTKm8adwTosThI2cyJx+olkwPzTu75P9Zh+lhfArq8PZP CtlU50LJou88QWEFIJ/Acjg5zlgq8bwUOtqMsCI6hJm7EvFI9BI5E94yvmtP+4/UtjRt/HHN vN91vccwiCLGq+To8Q6tbAHq3fRCIHF/PvkLIsvVXFsJLCYEDh7l3VXjSObu32kWWPq1mvNY TSECp7TfuDrfNfbmK5RH6N24YXk3rCMEtDHnhZ0HhOIDJMCnDeQN53LtjXchsztbS3x3c+2+ A8C945xqKFgtlPCIUzB9BQOtQA/MuddsbvSb9f+Z2oY89GF+s5iP47y1tL8X5YgxVkNTFMxB h8JZVW+/i0Ez5JPYwCU8FIyyOmD8Ez3E+butrU/4hx4UY4lVIRBdbOOI2u9Ge3w+5R6IJGUc cSv8su5LQu0dvMHcIU1ikNN4WNlb56mj+Af7v+g65YK7/QaMRp2a1r1f4zgMBVVPzNzjFTbm 8Y/+o+raIC9kJf84063ZVpdYkjF4g3B0rR4yEHLop+iYScqBf2L2UJiC6k/IJcG5x1xwjEIl ZpaCjSKi4+wH0SmR0P4jZa+z76k6KBHV2/MJvSo3QK9goHZoF5De8cVY2z0CUqwU8qebZKQF ZpF6xEW9itxcd7od3KYyQBjO8d92Gr0F3Zjnrae74CsRF+HVhAmO1kCAM/E8j7dhNT6tiYFu urmZqOILh0R5vkgnWIta/btPs65tw56aDNdZ7OupIOEGzW0A/nVtZlJo6xkKFgpA45/NCkja byhld2NmzNJFw3O9pBstmz/uv5ZuIFxw/cq03r7ufrj+j9Rv0e67FlfItXz+lhiG+2NVj0N2 fEyw2Go4sHXWTexygG/rTn0seNAjmu07p2y2WQp+dE9ybu0dG7EdVUpRsNnRmsa2J0fZXo2F cd3nmBnp7dZFq1qTJZrJsuOYfAwWDjk//dCMuEcw/0s9CyqB0UrRJOR/unJ9v5gh7TzhE7Dd llYEAGQEHPPVmIrFMlz7R6ugZXvg2yVzA8n9i9vT3R/4CKChwf9ojvKim8RV8PlY1gvXn8Tl kHZ8CJbhxwH7pe8JDaRBtulnnYgT9HQsSOlGrL890VWhFRE420qOORAbTLJIHJH9Z2vnHdsg /AFl4bvwO+AHnt5i7EhcFDTHo1xWqIULm93bt150/bE8wLmYW2+XgueS9Omxh/Uab3lg4+GI 3Sq619tUlnAlPC/k1qh++yJrmThfa7PO2j2ZTo5CbeqylH/6cG3zvz0Ka4ft/5JJWbGr17PB NHU+0HKXXKHXkDvbDGyi7gT5vBvsDAasYT4J3NL3Y2K3S5a72rIx4vfCDVWBgds/J78EaBCi KG1UEPuJFIHWxmdwB8gemmi4pqxwAlVMsvldXBNOTOjQTY+7od09p3tNsOJ42BH8EBv3csGA cZZQ9allCNKIjfzlJLKODaHNPui1M+YYCLnQIFPJQhTjHm5Mn9boO2SGW+znpHCfbyRY0WmT kiR42jY99k/fENDc3WGSV0eMrUcSFKqhvQZvzteHV6Szz9J3QRwPDxpPGPvrzaUfm5aFj7X1 0YroGZTeZ9cDroQnijfHonGK7UYbpnd4dqLNPw4EoB0KhsmhwE8Q9xBg9sRF635UIaKh4h/r q714nb8+hSSot4rIIuE5OEdPnwnc+VwGOS/Pgi74xHBjheWMupsRA/+VWQwH3xYKXktXnLNi XkTIgc/EryAU9L8khmg8C6eTJLEmkaQW4/22ctjbqzdcwncRfoiVwol+ozTWxTcdH8KNqdLJ ENHdLSalKSpA6r+4+tkWdDIEgN9hZpBohI8GSzg131OCC1rirHoo/cBWQbejqlLIi1lcOqQY o8/AN/pvwwGv55xXs012glaJ66sg3Vf79MzQZ1V0IsJi1g+JV1cQW/PNhKJSqesr569L2xeq +KPKMMS/GA0CuUY/xrao8V7vXozwmy3WF8IVuYebDpbwUCYhUu54ino0wuP5iamgu29aoFGj ixDyKuXWh1MmnLFi4bN8vbTA2ymQGCrsi1q44mDWMcAfKOA20IW99QeH8uYNtrMRpRVnZoY8 0CSd7bQdESfOAOlWG7gcq+TCSVBwfbzuF3KeCfp1Y2hgYKjbizRqnWoj4677Twfeer4EHp32 cLBAMjjYFkfeJEhGyghTvUjpoT3BVNk/3depnYS3uAejeeZLbdAydJTx2J4ZfSHWr1qX8zuP s4bUl2GQ8o9frC7j/QwVvf8mx4YfcLwEvSlJFK3SsP0Y+HHGmrOTeDSX5dkUN737u4LYhUSp 8H0zU0qmZTnph0y3hoaDMRbCWX6W/2x4cT4fm5sYYumdkL4LCLaz0ecKpY59l+RN8541xv4E MEDs+0wegbQKYMe8rAi3wxWdvts7QOphvJR0AyBmS8mfxVvnQH96X434mzplPXIajaZuuGtP kKYzRkWi2xcltbfgIwgdW1+1QzKHkfOeRLxK4mU6nXAaUUBHj6xpN/7CWhvC+AGfTUL+FTwL C027dwnfCmJwLjbdrEfgMefDbJ5OF0FUxKv/C98rc7a0ZHL48F/+zLj6LfzrFUvp0W5MY/OU VrJfnBADRIsQdbNReL3RM25m7Uk5FT70k4ZutaKg+9gvTd4vHIMH6+eA7tKj5iSZpxLCNPj+ qpPz5XDb4e4Cfg1ULe8NAKxHT2dOCHEGUD3e/jAhe/j508CvH50pYyUvdIR3oM3ns/gpfzjy oSnO07GxdHnCJGwAsp5/0GwUsbAnvqeUeCjaoK8PcfcBAlzXxDiiuw6HMZHGN4k2rC7N1zoD RBfr0p7yOUEXITitQtS83p6eLXUNeqnlTKR6TdWVp6IEo2JIjyqMKEAFnsCVcsQ7FXvprkP7 Fy3atM64iDjdy6fUOSZXGtCDoM912Eogby2eZhSLDdci01SgSWB+ySJ/I1b8LtKXqIE4GmHU Tf52K9LvbZ0ilwV2SA0JDcdteqWwwAzwDbBtGbunUrAzj3AJmUpUqEQH+uLnmO44w9pb8Kb4 6m+4bsEDDoVoxTUFjlEDlOIQUmXC1hDvzPY0aqU4QQLlKExsFLpjRbzly+Mr4bQFVrrCQuRE I5SH274wXoOEURZQGszgYZY1u/0G0WdX9NXuJPwnhB/MCyAtntNQHwlR4xudHQXMyWNVfabh igI/mG3z7DDQqJl/1a2iGtV0XvkWHYdYZeB5//Tb107ZtMEx5Z6wWFE3iCb5fNtEr0jv8KtX neqC8rcCzRQAK1Z1N48lD7kKInqsM4zW/PzNAHtlhm3BFWaPlt7cU8I/ZA86TYfeZzC0hsmh 7+WWhVNf4qhIH9AKFI1itHktMTI4L3Q7JjxYrtoY25V1kaJSrh0tuCw2YL0iO02+mmEhh2/c 4jtsSagyj1vCBHM9k3X6KyzMJb/AAY1hwdphdva9QHW+Uv7gVa+QHv4gKsShgHcn/rnmgrsq nr8q8hDOWm/0WPse+JKC2h9eJF/0okud37O3nbYhVbiy5xslC4xXO8fGhoKO77nFJdnwPhdG A8F+y93IOaOuq5y6UGnkBWDfU+NPlbpS0jaigTWlPgdbnytP8PxeNxrfcxyk9dduobglFxw8 BhPsWfLKpShbeIDztLi/+2dkr0udUc2EFkfMpGDloKtceR+ae+tNC3JDxxvko0w13seVdQQ0 lE2K5JAOhevkuTFuCVXP32dEx0X5xi0USgiCDXpu4ATe+dDGUZUO3N7IKTIOxV3azUP4glj0 0PCImFRxAPW2XVhKSqSR1cj+fv0AyTXb7j8DBASKk9s2FL4KvVAsxKEX5VkJODGnWRrv0hVM 4e/MIy3rDhh/ZV3T5EeebaQL1G103T1zPwGT11VgXR4nQakIADN7lKUk4iUu4CEJ7qjcGFRF +Hup5k0sEyuGv/Ho1I5K13AzQundLalwwaqv1BrW9kt8Aacm3/j4EiIgNamj6S9Of37kHzqE iCEiXTrzGgFkSYhSjxiZs66+gdlDQPQ1E+obnmzWUUcJldzIy1cgCl8YyMmtUs6BPCB3sK8R dd1lhIGJPdiWg7g4FoBgNCHALuFgohjMaQD6G24KfHv6fTe80D1zYkBmtsAX4hJjQetjp8oM JeE+tiab1frcUFPpzol+Q6k3Ke9wfUerhlfFGdDr/K9pJxKI1F0wcjrGi3Naas2VRKqyX47w CxEiX9ucJQIHIjW7P0tB+Rw0KbKKnPmGwYjY67T5YUc8S5LgU7aqJdndgqLcLqR8xKtpXWTj dZAfMXR32SQwqu7VZArJUTNXT0ABeOuzD/XIcS50KxZ99nO7pXy0qQuUsNn6d2KSwhLc+0IK FpobIfCMdFqieY1BrMcBKHn3508YiSrFB08xRc7AP0dQXQ1sVQR9synRR8ZrNSX+BAkKsG8n /y5IOLbzzZXc4t3kabULhV53r1P9MhB4b+Klm0BgSTCopWjGrZiW/7IkMaa6HuVPHCtZf+lQ Dxovw/zfb235d7Ud+KPPWvb7V+CYgcPKPrBYqnM7mKiwCiV7XEn1CJbbMBk+0Y+lf0T/mvy7 YzidxrQHuZMFvalagOygdfRyIl85rQmUIIBjMSERCk+pZ3Pw5dGELGU/HbSdAe/XP7Zob5OU 42allzXYlxX24QEvyD46BIUvi/9IPud7I2pewX0JR2x83XrbJs2i5uKu0DtDYxBQMgqpiuMj HFZWX4LurnawRDuKiu3D1Z/Y5wgDdxhzyP3MnRkWu1oAbNV8JjuxaxbvV3Q8NtlbTEBsvv9F 5OvBnyqRHICR0ZoTOxs4FYIPoL6VGYDAV6P1fdUksZ7lKWD/c2VE1iDzoh+hTQz+1L1k2CME PO1UUe2lFQ2gaK+QtbzrepJoAX3E04W8o7Bg67cQYiw6a5jMSrYPlYhzGCa+o0E658jQUrxs hbUahtMYOaSqyc2USlBgcvDp+bqB0SePMLj/qxyJWOpjFOQkijeWMG1cnYFL1OAMCuXZJO2I SwLo3UjuYMuTzkWPQov36LhXeQI3TtZ6ZbzI7lGymHwzEiFHwWVEdutBKaEv6NW9JL2ozZp8 /CWYb3HtIwUb1KjpWaRs1duoBv+0o3yZnCFRp3URlN5IptTGdDwWsNhsHdSF/L6ascrVJucF X+AyAK8LBYqPhhkQkpkleKIPIRFhW65+8kAkQ6TxGO+8gns1Q/5zv8v78JmR2m9qkpw/WUAQ xo9MgxHFxCK1OK97zAqihwAj9z3o9yr498LeNdMJXPfMJtqeJCAZAXCSrv/rOea1JfQTi9Em XKL2A1p3aeIM3H8B5SPA7bhj0WyVeMdpJtuudUqXYwpf0S0Z44yyWjerm7Db31U8JC2zpssc K4vDFNKGkmBuEp3LdGsVb7cTOxTAaH6lyPF3OwOFgwQlGBx//d3KpJ6cXRJjbMeuHUtJqBqA p0YahBgJs9pIkBsmTAw9M7Q+atD0Yg0SBXoA57QFPempKJl1lJjunDJ00iOaeQAqIvk52thC epKxhpzs8NC316LJRUm+RJzmTwXbnOaa7YCPFaQc2nKWt5C127oAXFkxka/s4fNxlU3YJx/x pJrzGTeWU1foAgjPlqNUWT1+KEx/xQoOmC9sIXac5MHCa0PqBADTfKVySXC/1mXpmJQmsnJz AD7qWsBXqfRIyfCL3i4Ja3PgDlA5U2P1B28gwJY4G0YuDv1iJPN31Ry3yPHhCA3eFXBUWJIV Z7Ub5bTbL6YNtVLa3xneGDhfa0c9njFBfDcUoIyTTztvnYGLAbFxyWR6+81ftpL/pz+/HZTR 4yhGp12SRrlS6GAiCeAivhmMap9ZUwJYTttvkT+JCSw8KcbvtQeU+6fwqhRGVUYUB8FpgPJn OCQdGn7HJ1ZgJ+9OkS35M96PYdbNdPrGpvS9GapD4eauZDJHqV78xEtuO8Ey/YaKeOcobN6J TosS3BkfDkPyoV2lPhZTnFSY2fapTMcVwmo0gTbLn36PBh9Ykh88mW4UGYETfKmUBp6NnTfx QTfGGK/fc5UgbMFdn9Er6e0laxJTHC00jZuUmpJJ2JVbcH9Dw2/hte3HxwpFwzW8IRIRZQct h/5tcqarr17BJE7i8eT8/vbfWoXWhiapCTi/riCTRI5qwc2a+dkXhcBECOlwBZ76QSfZMSOx NWqjboowauAFNsp9kSAI3PruOBYhtnhGWYwXPq70ryPjRU7JrOKxO78H3WnYYhSqMmDN0xKl GcM7rXRuSky+jRjnPPqFmTHMK2DUdNkIZ4GWmDSF6Gz58ZZP3vpX5zKNIoXlMR+tKdwxN0dw 6Iu0oNKs2pq4cG2yBIhVUURw9osN5rEfsfaxlNh2NQze0g03mJ6HQMM/cB6XTp9wlZseMln6 KRdYQxMHlRUlJdAN0Jtc+H/5WubXu+SZxjaSEmaIt7l22HFiw8VJTrxKcn7g+bmGRBgUpTnY JBOdggzj3UXtPJKSFIVoTeidGcYsj827c2MB6uWCJxL64Q7DTcbjUMQj74m8K77/wHGpbevk ZLHXTKONSuvOCxfliPhYJeV9GtF1zOUH4QDemL+9OOyPDiRkVC6AdX7Ezph+T+Qd4gHcCVOM nF4/DmXIo+I1tUUaZ2PNyXtdLT7ooaxLCrVeTw6mIZyzAGDhjesljMRF6WDJgHeqw2lw/IF2 FHa7f7d0mbFkWapN66jvDMiwjWiSuJ9QTYl9HfhT/gyCDqwAvbnuADqh/g9BNRUEUNu/VQan +RC4DBO8mzIMvic53uaEmpISzVQBVM2dzHCMhOEXn4h+bdxOPnE3rM4g+Tavwidh4bfYigkj /7+HT20bF/NHjylIg2crTZdR786stdSsENe8XXbMi/ItHzQxAiWqT5Obn4uc/Bm37i0VTdXQ vq3t85MegOtUE/ja8GicqJsInuTsBV4/wxTkXTFg/mqOH0zBBzWLP5t97hOKG78mlNPAI0nm t7MnFjLya/VwmC6SJ5xzVF5bUksdUUK3bV05L7aH8iYw/sK76vdE2yQxmPBp9BgYcrH6Ltij tp9Y/6pMjIllXF3QsTJSa7hoRkuOEo8jcGaPiLevOkhg/DA5cmY3J+Kfzm5ea0YYWA+BU9P9 tWJtw8pkbIfG+KQcYLE+OlehWrqWrTsTHW4/X0ajC6IjT5DpE2B08K2ExnExR/fLVWGw+4bo tn+ThWUXQDZsscJ1HIoM8ZOioSsx4dOqocNgwI1eVDpAeHtqUSg99IzWVGdyxW6bzvKhaYsK g9uOVZvv1MhvKiCGiQ5Z4mdV73cRXydu0UewnSpH0CsTNf+zQ/rItQaWM60Q0kENAEFKxYV3 QZ1n262nWO437tqIWxmtT+DjRwt/6mgU+8inUMZ+JyXbhLpru59EYeiLNqxXzGSerJn1Cfd4 8PkjVfnAUKPGXrQlftAyP/orlxNjvMxGCj2UcQnJ97pwg18akjKK52YaYltctu2/+/sJJbYF zyMBAUK1qYwhra8fRsGUhWRwLD71VNTq1Q3ALFfeAmZq2Jxs/vjuBerLEB2D66XEsvUc2Kje E5FXA1b87Hhb1Ysv13tEC88j6j7DKPqrM62JytdMTroqMo1aWTL/AoJmI+Pwr+XvgfS7zj7N yJeBXSAA77sD4yWbf1Fj/7D8ZUl8NigkLvWt7Gb8+pvrTSwxcFp2qBn6jXhUEn4jefCuNIK9 3HgWRjKDzSnxr3IB+oHu/+Mz8CBPjDw97QPo9MKXTfEpTaFxFkpGtWZ/IRFhD8HAu2C7WcpM 6fwnzSDXwmT7niq6mpM4bmeFlcl3g1bcGOa55gZNyqruNgrphvyyfjgQV918KsWQw6w/W/jW Re/AM9GUjPyjrHtRYdqxQ4GrY/LqA7iFvqi0tfVzI8AVnyPxdkUgwO6eo1WKatfI5zUb+IzX ont01IVHUZxlEmOGVSx2eOcOfq2X75FHTiDCjcql9iInIbCmf2gICf5x51+srecUUuE4uUi/ 9g3XZYqXqN4pYcF4eJwEHWjxMXLIdMwN+U7KfpiDT55fpWqSqpPGxrhzBdos3yHhY9RwGdNL 3hvFIJQThy3VR1CEHOYHm1tj38p6ZNF3gRIlPKCgX8ufAFoMxaXxuQOsLMQZvdPq5qfJZD67 4mXVNxqGcHauPIBNr7eKtpfGNtasw/4BrE0sw58Blf+xB1Ze4xx+eKa+FHkHOhd9ZP9YBHZt rJCrRRvgOfPflnLQdjsYR8a5Qp2BgOWrIQbcxPqWiousHQyQuLNc9TSscjWK3uv/W6ksIZU3 BszLNUHwVguNcluipzeuicCuY+W3eflx2ib00RJB+QCKkGvhN0g2hv6PHFxOxHFioTIBNxAX szwhVi4u5iPzpnu2ya1F2ViuBkzkW/BT+ssT4Jjlhxdj1SwdUx56dU9vWgaT2/AXjXOpbvdb 7+gsnIHgI6YF/QIYBVfKLfrrXnTRJjXf+lulIjw5ATHldOUjeAc8sbHsIHO+YRMerYOZxcj9 6ixFfQWt7eqiHMo19/SdOhIdBICFobqN8dk0Gy+fZNW87fe5rqBWshFf3EZcLWXAUdsOwXK4 4LGA/9IJI4/xGhUou1NnQWVU81wmKCukZbrTkdvGTkn+rPbc4b/x9iLnIoV/H0yptvs9+aHt BmhwBNDkgHMZdxxVZF37GzKJQ89G0hT8/6Ic55x2IjlukqXsuoxRXy9anGldXr8nE/9eixxo F7QkFEo6M0ZHr2blyCW3Sy47o+oLTelz2Yni4nj7W4SE2xxlCPhtTqXLHWnAUOcT04zyGIqp 7MdX4F9q07PUS94sh079Ashohn7WzK0TcNevoA4/VGudJxgkkSCqpQnJlO+4mV6FQh3X55UQ W0E3AYQeiwxD00bRP9Ey95dugR6fGdRtCjnfEPLwFFY4b7TbNb/XmVcJuiQmgnDlo5RT+stC PPa9zt48Sa+iuahpclcnL8EOlCDfNnOuoKGoEFdXSw0k6GYIPKgVROXiR9xY8kpsPbr8Jq8t eaSnJFnEAp4ouE1MuoZDqlVnk5M6iOct/C0VMmA4mcd1Z1BVhKesYLLfN4kIqaxnEDWxM1Zf cicPayipxjVUBVHFdOGtErqcPGTN+8BFsv2evnwmYvLNcDJNPvLkbenHnpsnB+36WSugtKU1 /fJHfGO78aMWxzbij/SEZuRzfOVqwfX7uNESWqqWrFPj7mPYdtnGq7KS9zPlya6rH5HC7c27 LTA7WoubIVZL82t/XB+/6jQf5RsyR3MjCcnxo66zfpUZ5DYjdAby0FZBj/WiW5JF++MJKZwV ATXLLbyjCC3BTbVp1syQy2r+jTgVG8K4osH8rqg5HUX90FuvzRo59TQNMoggAimDNk2lyFW5 7Npuk0E8LP5Ma+37Go/skobQIbAL22f8l7L14SGvXzbaTsbx2yZzM2C+srRe0PwGVErlQ1/m uIKkG1qRsoF04UhTnFsDFfX7oDJbQ3nhxebgbOSoAj+BIn2VRPtOuTejdvC7MEhmXBQoXIRY W77lBBORUlgY/fxUNEsvg9gmgOrTTjwC8Q1sH8Ysir42b34/A+GMKi8hHRYBjVirc2SH5pET bYe5mPuw9wWmGWt8E7BglSoQPZ+Celg9hN6QhxndruOHVyXSNjtdXrAAHkusqX7QUWeaIPby 4HW04Y4PMECw+JGxAA2ZY9O7dAybrwN28U+JlZ4NhkCn+5zJTmJmBN30xl94LEx7RtVMtdql mSiUqHEmi9Il5MR25Ktz7o3b6LJ/RHlydVzU58xh2U4tCiJwfNuDk69WO27oZxv/hVFGXB8W L4U3+oXmD4kc71M7mHUex3AmyQlHgKAQYIDnyzg3a9hv3FKKj/T6oN8dlq4CQsh87LZ+WRzN a5srzI2rVWI92flUnZ/gn88a9o2wKIA6+dF6NnG/Do6Wzv3JxwcmA29MqIvoS4FbbjWlywfh vy5urLpl4JEMwzoF+kULmng9DddPEazhF+vfdUzDRJ31T3I6YkZmF0HARUYE7oTUbkJ9VVxR 4qeugU2Cu1j9hcdMKSJulgTy0s8Z7jWd+G1ZW11ltjRUz2Alm/7e95JG3xqZANYojDvdcD9M Fd1zb0pPZ1s+VbDvYiBfeW7PXh448Fydqpm3rxZ+hJz7ZN1+EbWe9D8fttaTJ4HJvhYMw4oK xJ/B6HEl6nDTNUO46lwJFvrh2G1712MDXN4n/dOj+DrmrND5H7RgWsJfXVrFqP0rhYnIKp5d MmHnQxP6WrBSqbks26/spcrOlUklt6MEUs90T3T5zcE5coVrBVDAL07reCvxqcd/gOg49bVh jRcBPfRcKpoaU0C2uynaNh5WnaOw/JPdc9MZhqsjx0TPHYO35qVJ2qiAJxzva+01i87hzNNd yf8K+rehrIqP43Sz/Qtg6jfIhCYC4in1GL98WRq6SCzTMN2HiQyNlEQT3RRa4n41DbhZ5AUt yQX52M+IaoT5EpPl2vyeQyRMNoPmHN9WnrQwC9o8NMhOhFqJD3g5e2rUsFAwabWAXE6IqYkH 8P4evs829C6lizfJf3NuUPpiwHjiksq73MVFItn6rFSqyeVFXn4ysYMzVvl/qC4IZx/7KTbW L0qmWlKo7weMFu3IWIOfILLCGsXDknQp+9t4EAT/QDLpz4s8d4hZtPhQ9ewv8AlnlGAC2xCN vKI785o0SjqxyqREItliP39KGuUhanh3TYAWIFtdUDdVfbXLs0x28JavzAnawV5LheEkU+Pg a0KvRg5GLPC5/FAN6SeG4tOor1/JFqiff8fIss6bS8frJxnWQgRG1r9QCiwAi0D2JnSnhGvl G5Q73wFVEOfwKJsjNCN7cUEuzppIoN+1uS5Mu8qH1S8SiEq8wa8IwmcV1pyjx6PY1Fjq0qF/ LE+dfffsiTmKoep62md6rmK7vR9y+QIiZvGCo1UwwhdkZ2uOphsi+ZEImXDoxL/ruuHw35Hi kjsFGA52/rFBbCzj6OGOirFkI0InSVxLn9tw/Gw9VHr5K8S4di4zEXFIR0x7OdOwhNdqOsUg 010dgP1975HG4NL1fBmaqJesFPmWWssq1ivf39CiHvSWh+6ToFa0QwzMGwHsGmA6VOW9lpqv Do9RbwEmsWAN6DO50rm9kM2f62jagdCnIYya990miOYeGfo/2NBMoJ7wbHSXj6fdR9nInxsH AZCox4CAJU/h5ax2EXO317CdbWMdU/rMXjhv7YYJYRMNEgY/WOGnDVASPsBzkRkLX+aUGbYy sBXZIK0HAHvPkcLZEXiPJi6n01IuKyb+kMTs/YKjzNvOIWknJnIe6LgH5fY6NOpzYJIur0tQ 3rITo+vDLEgBCyvC5C+hJ0F0M7ZdkCpElWSSqoq3rNhAwAf8OtxH2FP2ZgR2V5OtOlexPq+t Ud7LZ7nNOJg46+pyfYkQNGtEy5MeZLuwvKOfhIbbicKgmPfdHhv+eSLWYhZ9XaJILpYJCJR4 RnNtb/tJes3VVNj/xBnffSQvyKD1YTgrSWt/mRSzBIOjc+djpRB7A9mmM5BfEtDVJo+jcAPs eHQReQflL9IS+gAh84pZe0968bumLMq8kX36a/Wz+9s9apuUcoatRxBGPC3G2WvuRzKisE59 +m6dIXV66/8X5/xXANTTX/OS9Vd56i5cZDAlCJMaQpN0ck3stha95wsSGQkm5jmohmTBNo3Q 4EHRFHB6177FFET7q3eGLvTdLgXXaBLY74CZISn5izz7r7BVGLCUZUEWsEU+w0ZEqV+WhRQp 9J5o8OAi24JIX/aq1CMuCdgbYdfY378m2+66IMf+C4GhBa9BIOshbqgSNBJsXInQz3qkiycm an7I+PSFrKUEO5G51nrZD/MXdnzUkkLULrZ9yVsp4VATT9C9Kpbncqgw4qTHsjV9Yc8jQ9sH F+38xQatudvDaD4IB2I1/jdk2wt9uStI4xv0yhCr5Z9xg3ftzZnB/4OSBytMBmwdXOW4AdjB qD6j9cK1Ong3XVNX0thvscRDJ5FUCCJOE1HgZGw0yDHiRFG1mCJtSbibQdP9q2TDKEZr7Djh nf2iH+atlBteu7oUGtVhAwF/3UprsuVirVa/N0pMbliydL8k3RW/XOaNPll9iETuQ/661iUW KOkYcfz7evKEShLqIgjeVPjh9BjfKVQi+Ni8Jj/IFpHvdaNsYSxTtArCFmX3KZ1yFIf9uXFa 8yQjYnZelriLZoAl5TakbYnP3+7IOV2G6POKIyFJc+hSxQKfRq5TWAWc28NEBicT6uJvWPWa sVQPTI0/j/oMUEKZ/Nt4oK+fzs3tl58enJ+UuxtH1a/LCORsYfGkdOBkTKzsXThgb4OenNLa 2R372nrGebRFzAhQF8SaWRbr1WEuCJgwFP2QAoChp7Hz5tQsXH2sjuiK7GSwRRfLdZ3mWoOo EEeUPsfM7OqVwRZ+8jnOH919r4maCWPjmSdOHIyBMpKAkEOnDiLPRtmGmFawfwWnDo9kWVse Rkd2A6yM0svO3Yzu3UozF2e1BSqv0sgdSyuffZq2ijh/tksCzSyPFfXpZUB6+Ru/KMbnYSP0 cxi89i+dnayoA3mv8wneRAXkTDeS3B2fffDjNa+XFgHl7qlF35buOQ55C/S3I5icRNqzvttE dGr/QwpoCcVtd7KLWOomozPwU2mNUfof25tPPdbPzYoRmynjATfeZIQXrwwmBNvsVWyMZVVa HQxaQv7llbTBQ6ykpvWfhc1A29jPFIPIHJVrG/noj/zMlhQISd+z+3s+fcTyLDDwiTt/h5X1 30hNbrzt5VnNUQ0HbMI4mdk2lw2YJWeSbHW1l3J8rN0PsEBnX9JuyP5WBK5ga0hG+3WosYtZ OekQWdY24jLc6xc7d5jFpqyxPbqAkPEToCpCLoHNszdCiHAYNyucKy8bX7rVoH8L4oQiUmq3 TWxGAa5+KENIFYqVU5KKAyD8Rz/GxRIJCNIQJtCIJfjnjI9G7nUcqaKOapep91GXhKa9yuK7 cbaXJu7GJZJYHkq3vIYKul0+UJCMtDbEErpW0Sbkr6IQQBn6CMvKWbu/zAxQ8kUKN52TPoBF +Jw1wgC1LS6W6BdFM7JZzLamXtz7rTTi3c4F4B4lzWhz/HEEdps54xDVqzp1qrS17JbrCbIB uLYR0ZoSQQa2iaZriEYGX0rt1La4zIU9QC7fxfFeGOXwCso9XnOpQ8sK4fmh6jMproL/FXSn lHIhbXYuCu9/aN8A488oHCs7d3Iz+6p8uJ7jbODvTbITxlgDU9cNlM9b1rqe/Me3OpUN3DLI fGtZDUjfjkAP2gyY7PJzggoHGM4ZkmY14i2ar3blwg4goPPLWk+6PRzvVLSiH5dnKdb38oBF hu86T7Pl46FKvaCwwrK+ZxxDx3MF8cnveZqEGoV0HnWUS4nemmbDCWw6JoOHOzu4Fvq71p0n fzgcVXotlgtXwTcD8035WG6SfSmTT9I6rx8xX/LMxM1khJ2u5HYQdM4GrEC32VSwapVxurEZ CiPI9kEuAvp6pisot/bFwxtxLmixHyc4gnVH5j/9q3NUZlgFtcbVnj1tSn4DpHWpX0wW0Jnx 3xW8ayUPCjhQtKGb1TBrpbZ/0stxqTMGKVH4llrTE0dtfeZfRtiUF07EUUgb1t8iNOECU7NP iwVFc44wj2+2tn8ja19VFswB4sc/0+63ul1PO+ozQIXLlTwFGUbSCh54LhSTD5NrGiEC7EM2 LlfTCaR24fLSmtvG5mUvSO+0SIGjw7uYhEEmcf0aTTXrEnV5Ivpr2lxMT84HbfvDbgSDXyBM QH6DlrfKKvvBENlSUWxYFpYysqkCjGqtsYlkOM4/SRfhM+dmHj5Si5fMBr7KZk8d/oxIPI95 jHL0s879lRN1J6kNc3yUSSiZS8xSTzJCiZqJSivsr9FBXE2B9r4pKqIuW2XrjgVDV7pgYwuF Yu0ttgJnJZqWzqnGZ7L+pcu9DrZxbsKsmU8Dni3W+zwqFPQgRFfKh7nKvy//cK1Rju8MtGr3 DkT9DDbrrVm5jto6iMMAsIGsYD+SgKvkHbQgNJpKsmjQjLfZMtsS7BenErrFGYGhsIdwlgrI OjpRyMSfbiVrJFgPgcTTp5upBU6p6kOLxJRgIgl6MNxI4P+ahTzrAlgWL8Y0Ky2x6yUqFqlz BHcv9EvxnOzWl7QTyNGZS6d4c64BvjhPP6JkYKX4e+q+/h9QT9Y2WRMbSsgWelPnDeDd3KRd 2kl0cBTmIYswZnymIFxsiqx4/4ibEWE4EbfYvXByrcfHOl1YNw4pVJFdGPHNwlxDHCrIVyxW ZMA+0PCgtf4aBHlY284g4P7v1om6W9FN/M2DcPl2ngWYZTZuVVCziDAkf7tbaXMhbYsPfZL4 S2o3keZnB4SrzO400trKkrQw/sbs3ucHjYqzewqYXo2b/GvLGGwKJ02HQQGWqC6XveN6CfB9 SM+GEjTF8o9CpgR8LkrgVQFvAi4b18dDxY7is/cy+NP2Lb+QIkDDZXR0nCwsA7XGJGouwqgU Br05XqW8L6751I7FCEGry8WrO6D71BRJrd6j5p2LHScS2eng7cnYC/R9/nrR0t0uXThBcOd9 XHac7zT7UM2Ck6bXq06d2sltJyX85e+FZaDNsCwGaLigTUYdgFbWtzPFmZtw4WzpHn9Z5Lbn teh4FbW7zVPTNui4h0I9JIRooUiw1qyh3tw+UkgIGQOcAVlHyGOR2IDeAxW32O6btMpOKz20 m7tOisFgBmH7Xi5fb0vCrOF4A+P6ddYIm8f9LS3zM4T+aCoiJlbukck40gInHE/sp+NMBwee NjYIHNlPUfDIFff4OYTGvfz7vHaBxZpgpJV8SieKusnepMveEcLUEwmwAVWqskZO32Iif5KX YpQdb/FH/3u3lBDVFfNsHnIon+hkeMs6WrlgyWgqn5kG4DZW55bDUiEOZrYaSlk1tbNwsfmU CqVxI9RhWxvnfl7B+a56vcIH5pNXtiiWEmfk68wmkqC+PU1+tqy4jmRKFGgiILnZkFbG0auh ihb2ie7XWW0+7TM6WFi9Xn2Ag+vLnhwtItfrzDmmWJGMph/8B9qhigR0Q+SalUMULIX/S1gx DL+TKRBNLx3Xp8Kyqge6GCtQdWboA75byY93rWxnkxt1ex9trnz12cRUhhm1+Ia6be03AqJu tPopshfvvSLWWS2Fb+xuXuPtiUH1piSbJfdRcQvEgiSwpMT/PnfhLuj1OD21eiBv7DqojZOV e4i978JgztnoN5CkKhNAtWSP0mg4Utkvy9maXQvqw17Ge+YY2+fe8vQlqickb75cJr+wY5Z+ g+crrQuJmEh/J+J2bFGdvvfteZFl5MbGr9qJclo2bB/kVXkBkUCfVsDA3B56tXKobzaFH6xx ydCDb3UwDUQT44JUhb3xjgqWbfz5YBZXH1s1b/Hu1kvKxA5UI3n9ioAhEHsy7otS+pgvnxtM NTE1JVB2rnjmnyFEOAiObnYpAGA9Mkky71MRpSUk491DVGkb7rmQ/cQBksnqH9vL+JaaVHLz DWztmWwUHnjzI9+gxok5gldgbr1lDuv6u7TrBQwzPCvtcyERshBQACsS6UQGQS4/o5scHebM QlkKzQY34FC8jlpYjdSXXcrk7x1pZWop4pKHEbNudrRe/xdUSz9Y51cPzFHbFSG246U14eHO CIf5dVpYEljwpudD3GYHoOvqKZHxwzTqnPvkg5TxnQ8TTTWhPpnxjxWEyuZF1+MlkoKnkgWP FAGTPJjsg6YCjkd3rUBWAXlYEdlyO//azJ12qTcFEmE5KFBqqSLDlS3EM8eeUuwcl9dh8bCw /FKD00NlwOWkCsKF4jn/kTrCna7zZIy+pbV0VUHdMBkqPWXCjDLMh8fYtyYeHomyigG2N7wg lH2r7kx4NCCktpQbK53KSqquxDYhstBwcxwOj6dIRDYEsBrBrrNwjupWmzS32MWw42DUPJ5y bDmTTzWdzpd3t5juYoFeUk8BeW4cE3CdK8a2Kxmv7hejNxM/ZZnSknG4gnhDP7GNbZpFXMTU F9DXhl47KGEkA6GUEUe4mbQdFxv7Ekl9IO+663ig3LZ+Wvn4Ece2RgMY1B5hYT3wFSzNsEaN pYOVTFWZIRF+i2oOJaiRUTqlV0AOCEOLq9RaKCtNwx9+sxLVuZ0X+8Jn1Q5bNq852RUnkstZ 3bb0f5jJLHVr4N7Bs2wrDfYYKg7sigweCAi38GUlDlfxm4DdlEMAJBrqgNH4hCCP7ZHlhpoR 4eojaD+l97GG0OGpOnszRrWla3yTr9rUQMyNWDxghLVFJPccipo8OdZTeNiyxeWDkMUrLSxd IJvBpNMRLDTntaLKLRJBKakEwOjmxHv/vSzM0WU1GjVpugL8J1gDnAGDVvxG0HRoi+hu6/5y jSsFpE0a7DUub+gBQxl+LFC4uiKhBvX5QpxlFKlWOstqQQ8YiepFJUDfzwSCNLEQaI+A8ujL VAiT94HDzo9TEWVyMfOMuGYPiZhwsoavs0O0nw1fH5EwIRRCQn3RCPwIH8GEqKlg1siM3zEw ZlFVxMV+Ozhaf6hOo8JpuMB/9CR3fhCvmZ+N2V5gsz588yEUgJNm7di/5W9P/faDUxJ0UPKF EJOkXcLvoSTiGHGjhQ9C1LRPKKm06066J9HBwb0U8OR4mpOBUOkR0DnewXkB0diY8c+TNHVJ Xr5oCghgWT/LPzpfps5713XAliZ1hzWVnjFnA186fl98K/ZghZJnSgPamcTU++IW6KGvQwHw zMRd8W1qbNsXVlY2WdTfxK+fXeRUc0yB4uZBh7rCrQPD3bJHwDhDQzeGIu1pr4asZoUnxXWj /byZBzvvZaieTnPM/ROUvvsLTsSygYDriaSRihmaUwgD6hSyNdhLtyDi/8l0ppesGXBlq09m 0wN75s16+IhlhQA6eMT5qwStAs3EtVzcmMn1wLB7lOuFp5N2v6NC8BKS4q+BFUMpJgGyoYxq 8VT3Rz8AC+Ucc733othLnztYmDN/FWctyLEifCmXSh4+CljIcckLP0nEAuWJnJLu74hcrENx riThqGsd5KO7xr+EdviXiTz6Vef9pqYAsEnMCKsjPkCfKucYkc9bQUA6kv1Bg17ETBTQMcFl ogNdw6p8yB/VH/+KV00PoemEzVtX1tCKR54vBMOalXGrf2iNdd6b41QBK+bYqhosHQRJ56Ko k7e5VyXuuMCFZYJS/DlgACYwrcyfyWrMGlLXhY3oPEgztPSmBRVZYnsqDUkAkkoZ1ddyMJuB LYq+4BwHyMRFqoutt5r5VUaPV19bRVvbj6cq1wY/fxdgYcyAI+sxnfIK8AGg6WLgJ6E6+kb4 8yrAW7VByObevFaDDo4P1uNlO8lvaJz9xwAIHdP82o+QX4CXd3YqfHiRLw+jRkw95gR7rZgD lRDlGS4vyh+CDfWxBVMqX7kL8TjrcTOQpxdmbBzSaeru5ZGP4zWDEw9B9c2IoheFNBzBzPrt Cz5JufhWl3DUV5C5aUv9EBHUaaiO/mB4PyG5VMzD0w50x6jC9IwpIw2kTZ4ateTl2sH3wTp5 fhnwCJknGLpZ78Vzju+d1SbJuZKbaq2rqVzVOR7+Pk1R+phVUYFSO2akNNjHY/1vNB5br9wr GkOifNNur1fJ6anqWWVyqC/FTvqZjnGvpsYbq4iKv/jonzX6SnoJ5GmB5Df7hNhAErEQ74Ep t5b93smrbGuPCsLI1zOSoL3RatngDyAkOp7Kpfs4fOuyuXv5mh1S++pY1bfLa1kEe1rxKm4O aKqdzl14xXlg3xUfQZWaEaQoIg0fnOXbRdsRQe8DWg1DokIghMIvfVrynxmifntSTXwEokNb 4MP2FuJ+MkCI4wv64kZ1EjCUWFFRKRxgtHFDHif367bidOBKM5BS/+ATrjp65B5lT8dy3iMM VOzE5+8xZj6IAPxza2Nokhu3bSgxHaBWYzo2XDwfZy0xMXWB/wEwvJAOOLRBlt6nPFwKVxwH CFP+9QoL+kp7UwRPApzaN4yD11T1yYmiHaXXAo6NlP4o/Ut2C6aRiaTJgHAeJ7dwXZK7iiaI 7NUKsQgczRF1qjFA5PcYyB3ppVpe8iGRiKLaaxYa9zkJ5r5w7oFmk+bBBde4SffKb6/br+pD n8RRbVE7GIYooAiGK7/lRhlzOICvlrIiEjm35MENJBHxMn6ngjf2CSW3hABJ73wfjQ7wYTEv AKc1/ZSBD1Hrl2FD6c9kMw8ZBD1F2VuSQ7XrrRF2F5/AVluOv14oVaB3GRmz1zcexUXGNmou DX04tth0K8axrdKY9XXDuUhyScYGsARLfZHjh5VKnnQBmYlKgJ6ajKZl7niv8WCGsSb97grh zTE1rp4sNHz1w2WP9AiF96lg6slRwrHmjEIZNo2T7+SIOTCPuoPpwy6vsFm901I2w8Gz/8NP DTUxJTOW/B6mpYfehaexP1vIjVSZw/+Sph5cxqEeTlHO3zkwyEvE0rN0PhHklUoluhv154CV +8096N/08hKt1FffzH+kd1l8bcarRq3TlPFFxI1tI8Mqrko4LwJSdy2Kcg3Yo9xPQjpb9Wp7 +cihY//y8u77pDre7w/tcD6iZm2Pdzw+wVQ9MildwvulFyUYol8gWeVwF7e6I3BWdUp1kcqS A6Kk2I1e5rx4MlRku1hkzUU9AQhKltK767vZ/lzdHxwNbK5OBjIc+MYD4qkH3l7lIDa6upnQ ODlSjjbnMKRXnQbYOs4Zn8I6mhxv8wM6cMFn50Kt58gRUBC2dLu3ocAwBr+xMqelCAROtNDU gkXZ5QBofRa33QYUbHDmVZx0jFCYc7GDTJgwCgcizLU8VxLdun/kTF8680ffHcCDlG3F3YxO VAcrE+qVt4C/oyZd5Xbswnf05/VO2ycjfAmgX6h2VYki8uCcNfiM703rkTo0siWJeH0UGYbo x+yxpjeUc6G6OqhSzoweDp9MkecwQ0MyTxjYi9cWqlwYtacxzSdRbPawwliXr4Qzv/qYy7oz ydz/t9+hFKu4cBZ5+KlGTwchZhMYknMKoGyD4x/oFb1J8KvVz8xaXAlhS24fdcmr7wIA8fZy ResqJ01e3hN5wzRUu45zBn5agbcU/HzbtaREEbjR5SAUdHmnjPs4cf2h7Y6l32cc6PY2oOBG TynqpRMHaI58O0N6ZhsI+hFGx/YBClY/0Z/aDDA+Qu7cXRalMxOB871B1QKX44xemjI1ixYv VgpzrmMCXQm7lfil9bay/KqgXh+mNc9Wq2eZE/mCk8rxniFsWQ9r6bQOE/ApFy5S98Nwp0kM 8bxkWYrmSMQa+h37ciTPmeLkUFEDqEICzr2BxEwN9fzA5nKshdvqzaEkxxcVnRlK4shDRT2p GnXJSO/Tcav7fRWn5YzR7xF3SdH1kJK+SpzeOqSgx5sOHtQk1bA1EBY52HkBs2W8WUCsuFd5 eIpEld0FiImnOuwHZ0eBjGd1NTh9GKgdSJHpqu8tgVY+lmCXsBWpKpgV08vrF0B86NWBJNQv akL/KkMTEyQ+A7dLttoPOlkmY3v5IfGUwf0ufdMOnxA1Ygm/J+a88o1gbCLrOgOdOGkrkvr9 vt5WevurzV0J+/4vV+5WIM/1gXpvnqyQcFn7RudSOHahReamO7Xt3wdJ1ic8AUkkqSFObB8a KuJkCpaQt4bNSJcDd9Nc5ilcsiQjKlSrafjM1to0MFJl8w3DBD09c8MLLmdEn5YHKFtVxD2Y L581MYQ6xo4tLS5wzj0L8WpsJ0UaN1hMMNeHucScLBXU3z0yO/0ouCRn78t+PmC+kVDbwQc+ 48+hj7Znv8FFhFMkmc0XrRAFFGcaUs5R/iTXyhqcgSgPtmW+b3iLae2Gruye2ClXBJJR4J7U zqVq/1Un/Y3swNQ3GZwLomZ2UismjaR1delcVAN5HhFBsTfgcBjdHYRQXGYL+Yz4MDcQXGeh Ymu/CXQK+CR0OU/aApZIejA258xoBE3RUMnX3ZxrNRyCCVXu1Ea5TlEmRg0cqbkxNMfD8C5y MgKd4swpPrCtWNgncbHEaFifNSMihnmDD24aihafBUIxFD+Xsga8zhBBvGhPiLxBDNzBnQIL kZfXvaRBFlMG4yPiP+7JddlFSyRq5RIMLIXNDeemRGj+JgCFGWMtj+gvGeN9pmIISqv1++qh 0ga9LQzK9qxhpYCFmm5FDHLxTWMRqMZrcOHuKc3PKPcPwfdF1kHiBlpLqxdv3BZ5vruwUdQb N9vGRZn85M5nRgvXrXGNGOzMwWNuVcP0163dfG4uEj1cWurGFMLmU7aGB9vwpbxQIs3GN47w Uuvo/Ra22VVjqFpcvw9D9ZCXgF4LjkZjISI24q2Y3kDaVkIz4ZAaK8lMZe4CKNh+9WUQdaY0 mHuRINNS12OVSJZsst+cF57WZHe4k1NHlHxw8a3iuaRtKifuy1dGO6OcVn6ECRjRloSaKVZ7 nzCC1ZsOn8xDMFRfKWWMRrsM9WtwXe2EFHYUbbQwdSwdndObgEvbeER6+vSAwyF7BhO4zBSF 1IG6Fu+ulaBfZ/Zn/gfbyuUkfXBaqiyYiPrmTDxe6Q+MmW7iJTplwfxyYG7+9I6yG9ETn572 LCQ0oNFTqsGmvVtwTyV2AGvxjniptFBhbP3z59kixrFzFS8YQ+rtBzfEQo1DOAdJumC62//D BD76gfkjIzdThF2CdCvhkfhic8gdeZ9DeQ/N4Ijz/jH/rLrgF1q4tBSu9Y8NbYoNDxG5ypeG Txbe0lhnad32U8ROH/EEDdmoAqNF5tok8xn2Yu6XUBiug71zX+92d071jPd7nMvdusmYV4rc 5YDI5umDQCCvxHXWoH8WnM2LJvNJFMrvSirHhNb9V850kAL5J60d8Li5TQmPamPdsOHu6OSK wMLxhOt8eTyAyEwb8NnzR7iX/YlRNi8C+FDQ+jjIhK1Fg2JvqNBBXy+3m2YpWNRvmQ5q3/Hy ZOk3VTdl8HDWhRSx2L6zflsclc6Fx1Z/IAEM8mzz0+1OItlFfazlK3EZZjO/VNaQEkEaN/0b jbTsTpwrVwX1oieFbsAd9WOqw33zK1ohKaLtTNU2bu94YxHCts0ZjmEuHhEFkOpTD2CF4Lts lwepSbllW9f/wqwp4nQjkLHPi1vWneTviDiGLRlbnwIx5V0f4HLoKKy/CF1gu4RO97/oHlp/ arOEhUflpZSeLn6RJLBOozXDcGXqEufPg3N8wz7MwNXlJgsIch4qrAa/JJmOw72p3n/jHMNF hALHnzYZC/6o7YKHz2a626SJwpvoP2z8aHtZc04yUNDYS5xvnbN/Z36jKie0fcFw4JATWEzU 9mJmElHiQmkw92g+qiO2om9mbkMNijZyICgvKVGSGAKi7xM6Mz/19agsdq8/AiryhoCkIaES RkhNLtLJ7ct/O3Scd3oah5dC4EqZf4Ps8noxlbXI23nTopqs8kQSLIypO5jjdXJv6UXfA7F8 jRnh/NUh5u8v+U7kWqy9JV21lPm0iPONyGuXPNxkmVmdgtKooXFi1mhEWwZTuMd5P89wg2/s HqBaNlpzKeZKqzgYTp4A0yyUaC8PpfWLgyO6oVnVtV5mWzZmj0VzniFWedw2xMPwqI/paTaY RyCFt8KpNu1zOeGvtFWL8Wq0GL+n9i1iOKpJ863z4Z3jPV6TkCHGCktzfS0ccpFxdWDSskCF w+XXON8olvbK5mKuP4+UkeXVpWkhkHTPE0hFzyGmKujdDuluMdtsz0iy6IIS058ppH5Pxept 1SbsDUexohoHPGjk5ggPlLZNKlpnPQzi/Sqx6yEWTEc/bZHzGptzKxBf7rkfEzXhpN4oh9II 36GjlVohrCgs+0l5ptQm8vWEZlLe8tC321oRGIayLywBPVFnq1nuHFaM8+s/Ddd25RPypTHY DbI5iwQUs6TQsoz4PNVaxq/v94D4PV1YUa2ZOh/mz7K1SjFB8H4EJNevyLOEuC7Wa6lFlsMp 2kqWOsSCEg8xTCkLAV2Pz+yjnBpNfdqNvvXXkONnwlzdqYP0iAbHPhRiyNS0bm3udNnu1vA7 ZyXgC+G5fxfZXJrcgE7W1AfXY/RY4Gs28AzCzURlPf62E67qi8ft1fHgwT1/eY0inSoysgxy z2AIQ4uRauJW4rGESpgNWiT251IUR7GSLDHKw8D8J/MZIIpZv3aw0apVh43Vo7T6fhbM4QEX xS7JfxjOWB6SU7PfoIRBhj1lJt5VbAdB7dJe0kcTQKRTOZjM0U5JfGsILosVBk1xh80dpQcS 1FyXlUWs+1BMkVRTQZXiBVIC62s06oCvFPSSoonB/NRr9KiYa4Fc0thAUSiqiH8agGIAq5AM UVVxq4R+r2qRMT5mDqP1jDN2+Sw011YEfcZhPYPQksarKlzHJEzGkH7suY9I+z/KgvOjd1l7 AEDboCqdJPIwI4ett2E3MhXzMYoKnp4WvbqMOCtHUJPVpESaNmTVNNHd9HNB0Iq1Mx3+8u72 iVBMlE3Of9hCh6Mf6eBYclnriP3MHA2Dyqm/Ubt+ky9vkzGIlB2dCSAcOamxYaYa4yKn2FiR iNqtEA15TdRyRcjPTljWzN8kARV5F9DRnSq+KoddVcNXfDSsTKP3DuSJvqUO3J1X6H0A7ISA 0hhJlc3Lgr4tAsYYsVRFBScCL6/wzOf1XKX8lduJY89MbWdS6xC6FNMVGzPdzsrjXi8gZ487 0RbL9LRCIrvDbhHrxaLdsbhOHC+v+ufhX4+7LyjgwBGEDi6L+MPGFBJ0Finjk7cWv5QbMJV5 htgCqcly1CKXBPADfQBaiaZpek6vWVAsd+mRt7ieCEL85dbsQIcq0kqUEF1FJ6udNiP5EQN7 G71462bnEsjEDFhh7A/b2OC72cuFx8G/sQJPFSQ85E8WSbpDZ2LmmaV59/F9bA5Z7CaPWPiU fkEfTieNJKhYIKxYbPcUGblsEq0Kt1U8Jf77EJyx+hT3yj8S6MvDuRirFOKWVj994x2leZiM T5W3kjertQ899bmjXJYDldOxieBHyBuSuEeRQ+F+nr708scYsZTsuCtI3dw7dorqTvD1OXrA TPiSTbLg5O2+V7pS3DcjeW4Fi296fQpanGqwT6wYx2hzAKfN8rIZc9CYc1AM4cJzqVZZw2Z2 745e2vaKbxdGitId0ciabkBbm7E0yc6k2DK1Q/YCmv0rM/Tq1FZeqf/aaVvssrAalCOJLD2h MWgRzErUijCWEN0d7Xh4wlD3umbPsMGXr0buCaU/BB2MEvkgqKmTbaQOuQcGSLH0DMZwSIvP uDP4dgYHoU7xBcHrXb+5xlTr3lVSNGxAgGQwZBgME2mu3qHSIwGHarm3uB1VvJytU3B1DL1g 3dfcyuMjcahZJI3Pv4Ua+n67KiZwi54cPL6uhtoKA1JMrR7ZTES3J7tRAuDI5TxZ1o+ydZL9 C3PqJcPcHGhY66WQ5E85mdCu9gHZ/8ALC1mi47i3rQyZygu+3mNg/9NZmAWqeHDHw7Nhtcts NAbKFgyRsolq+s4VVdZxF3KLyy18++fbzzjQB8JSivW/r9KSZvILIyRN9ZrQn69eNE4ndAYX B/WI1rXzO89wD41QEZVGbJ/CPfPSh+5wYjchWv4kheDyRm8MKmYEy9UwTN3UGT/p/NZ46mSB JRMmgzxgxpT7CXhXl/8yzWJUWrBgm3yZIeJwEbSGqgs9bEUUbvCDTcjn653vQjRRQ2d5ZORR AZBbp4wJLrwaUeJicKqT3RBatZtu+PMu0NRa8W5MsYiXUB3PqZiLLeYoWFLkI8aAWlwf9A4B g2qq59oCn2loSek+Or9UytGWDyCuUHgr/wMh7Xj5I0JupayTzqJ3RzUbRoSXluHhuhG7KeZu QgiJc2tnWMzOl4Y4fTCdWQXo8PG/9gRG9TgFuvf7JdErXhhr8ehcWUudpxi+AWoKKculIs0u drJQClVWu8R05z6tyt5xlCGXBWkCdjz98+dswODeIPQHKOvY0bImDH1g+kRs50/pTReTsFQq 6nDMB8svYuP/OFTsuC5GKy2AUSEMr63Dxcwv/yxzBG5BTCG7s5SoOpR+GrTMMLe6PXNAVhkG WG9pyKGXO6R4vk4VRjSoHCRo5x2MpJT9DAbRbTza1YcnEN2NcfxtAn96IozF+c4XFWOF5d4Y nFAuj5crCUNvt4n0k9gAPTOSyyky+/dZ2dlr9xBOBrDsmhaP4WAZVWlrgm8wpsa20873Y7gN Z9yWnY+aJmTwOeqPWCuTi2czuePFP6R6lc1C6rQIBT+pNyHYSaULjNz9cE/CwhdXfzwUvjGC Vex4Lpuh1rGUMkzKxOaR4AHMk+IDwKjvKmKfFsgDAUJMob+r1LIbi8eJannyXFe5/vSaoP8/ jG7Ma9E3y+rFl5n+zEU7xK2wDLWt+/PjUFN8CbAyAPazMhMTVR8Uz1Xa/Xp3kNgWybvT2ROH OvkLaD1ifSHjgyPYLZjamFcWjYiAES5MYlA5ow0SKWCerIqKnIrheymSjERZP2KPeT+QPxLk VJvZ+13aIa5r4O2gMue6cDWncbaCBg09+l8xjaEeInFNMcu00AHQ4gA/fIZHGyP0F8kLvrUb KFCyjjb/gy7/nfhabfVJoRLhjiDpYzu11OJM9CnuKtiENp+IDsnuAQPfO/8AJyRSAQh6txAx lLESAhioGLIyEPUX6GbZhLFs3nibtwEyRWlcskMpnbs85ulTYzgwm/vRIfXgtyV/RTmvFYVJ 3gDZtW36IN7vB1D3gNk6tPRoM9+D5Q6y+i3d9lTPzJzgOVGXGboMs6Vb1y00WMrGRAC71vRz F6GF02vhOnuEg8JC4OE4FWRO7y+4p0OYd11mbW5QhPu2yvN92SA0FY3iNFpsO1buzdbW1G1D lobGBt69bkUH3/+OlcavgYt+MXOb7aIJ+/Xuo2n5cWes+bShkhHiSoZl2XlFnFdQOWiJMCLu 0VmUZlNZ9YOZFRSUkWNbA4roWNBgVDvc4xIimY+T6ap5dgHWPtRunraltnX0B+wL+nMoXrNx AvFuPNa+LHRQ6AaeYGp80VK8lPBbaFQ3flNrEoCSmf8tjRZVBL9bas/OoWF2gK7A8pxKulpu MttZwgWoSaYbEuV3y/WdkdvuV+/5SxGHcMINhKFr0bzjpt+i4r/FuRjfuCi+RJSE4oazQHCS SXPwmugDRceI2WOQvRxUzRC2hygtGpu1WiVpWX5gy89JfftT0IuT7VyYoryReDnKesrAEfoC w8cjNtrgGHSusyMkEABhd8y1Jl3L6wrbhzW6hCozeCWBnr+qZ3vOEbquPVB/3VOOrJ8wcUP8 eJrMCsAofkNLGP5tMc3uWtM/hg3nYjM7WdIG48G6jcbdXKmMYa9i018N2gz8wFQGgs2IwwxT Cwjk3DD7Ik07kgy44ZfynZPGK5/iZW0Ks2zlLl4gGsiTnccIwPhtFBnaitDrIcSPlQpmYjD+ kNSQIfN17lDOHPORe3Pota6OsftUDVEMte6hcqNf1RK2pmR3THJhvdwgpsLPkEyoJFeflzAR Bbdt+zDyybUPzchuQr8PWVmnasuLzysfy+hROUH6+Ivaev52xNwLykCymPX60wHRAOtWS1mE ydebvSAhRV5vOTQ7iXQIi140GOeKY2Mluxb9ISz6d6i2wuq1lrztGSXwHRc+KsVRHeYfcY3a HrKW3f+G2sxWxBrdml4c2gX7YCXsUyH8TQhdLDD3tlty7Em0Kb1D6ISZmWrkPg0hDkKAfWj0 U3wqNHMVMDpoN71NaWnIxffjaBWR40KfqH7kJGNnuumKXkCGLDC+ll5e8BazOf3rcq8bSQgT +xQ2W7TgVvoR2x3PByKUyLiJqmh335MYoc/MNs2qJJ75IY0olI8jkh08W91qtM1xCIbqcykL hMned7UGMFxqoegoz8LX3qzcCHC4jHDO3XpjpcTBIwnxUxOcjzHx2hqoIW4/OSZVz8tV0XjL 7E5kRcB/r9CAyVP9VdC1/Wz4lFDGHqZMbz3gF1i0X3W+9cU9vem5Ve3PtfYbguPe3UwN49/S jhl+4NuYrtgX9Sd2Ntuw9BteSInROck4P5QoMellBfsDvT2K9QNEBc8AsH8IscbIWMuHFoLa MJ5Yg5VO0fGMQWgrsdqAF/PuUfu/E12Za1Et3PqCpWMU1YvB5KrD91ObWEKbvXi057zay63Y qwIpt/atKtWV0GquXxpDB5vL2vtdYX7LpJ2VkVsvFpTUY1lzLE4WBYyNGVxIrxx2VvoaNnny 1WATDPZ8nohmA5Khuaq/RBqiIHnMGn7kYJwPZFCnWJqLj4czGcHBjpetmK6iq9bI4zM3gGp/ 9fSwecr8XsgQb3x4hC46ORcGm5H6fXiyITTx00L5E/ff8v9XXf3caZmAGvroFdCAUtB5ZssA 6lqYawMqMhMBbMGo3wPjD6KzNau0QT15jeBaUDAOeiiEf1vIlgloTQ5SuMdsujvbLI7y/lFD 2KqfiH2amRvAiWHI87lCdaKD2xwUhQoJrJVAJGie102M1/BOvqvxRvpjlcVRje0lq+In4e+J kvJXXmUjRNdar0J2hBteXtgNL0HhC7RyoPWXRiL/ryeagc3dci3T8M6aJ/utXxfGWENyH4Rj T7y/VGWIrlXc+nxkHp8Ikq8cvYYghyPTvosTjL2J3ysBq2uvdiw4bP4uzraLjhxWKbsNdOBb qGV02VsfqmHj6oUJTePmxbgVI7EsufKCKWLSlVwXKo58waS+38w3kwft5meHS1YzRnk1VGIi JgW1rsvgbasVk/YWzPyQX+9+wp299HALCHmmNzWWnU1lfL44C50DhlT7+i/Qa9E9XFTD31ey KnrV9wT8gw3pV8okic3gAZ+qwEi9qs/xPgkUoWm7/CVl5/YdHzXaUp4MkoQo4tHGkL0dJxVl 5YhzCkAmvOEtqrarJkS3JQF9TGg38n+BtxRU+8M6epoyGTHxE7F83NQL49edm+OywJTdR3sH OOmBv92aLXYp1LGpaizsuQP7imnz/svw3QCnu5+R2ZR6GKSyIwfhdKxHLPyjSWTTXMoyQODZ BcN48TxUMqvQyiGCmVQNqLo21nKS8ky6jEfC2iz87VOdax9oB6cjkscAqau6N1bNenc68SRy nz/kGT3kgcZ7oaJ7+7oAoLivxCLnHTSVQL5oFGR+juaZ1p8ta2mccWOOehBfIKhW/dTLowE8 oWccysbk/5MohMN2FyxXe7zHosA87OiHDh4ZmvVVB0YfmXTTuz299vefrbxR4vikX8iPh7EQ zjfUG/nB6wuGLEUK0aLrI0BKJfqcRzgfVtnpP2bHi0zbZnM+Bje/7Yt6L0b9AaV4EiNaDXh0 UA+sb1JrLDQFYUJxaWPxjz33BmlZ2nl7EaWfKEliu16hjNFj4rlMAZgTroD68lndOtT8BUQH C/ERjvxP6CJI3kxK6maUubZYuiLi0TMF6HIIIK0405h6PqDkmQh00ehG/IlybChBn65eiryU eNDhldY2w43O7tjF2MWKI3pzTUIFT4tV/LlgEsr2eSYryyRz9iEiWFUlV2W7pVdeO0IZ7+Mg zITDMeubI45hw1UYkjOaaRd5qz9YPukgnImSTuizFkvfzbd+0dbCzAJ3KeHkgEIjPP1zD0sZ bmLFpEzAB3H0WHI2wXcaXwhp0jJO7H6uE7n9Ul3gDdmwDtIlXqup1XZyxbr7scg8mEYn+YRO TjDtBUxwjqa0WW+JZxRJ0sJxbPw77j1l+VN4vWWV35AJ7OeSlb6CFtV2SN17Hdp1GkFaQ471 mWCyxFTWneQAt8Kf6FvfJZn3GfVRGsZB3r6oXkn+TFiobYy4ICiwqqlSrObbUynK0obIi0EU h9dDJvEcVBL4ro1BKd4Vuu06BIJ8N1nJ+8SH8BvagMcHBu6c+9MArXiVG7R0XN5aFJU04lLW QV5wTzAaNsJOP28JwQVMB7xpAutZPY6y1rlHwwBjxYw1Fv66G9sOWq4TTeRZ0nuiUVt2W8N/ z/iUaXy2WgGmmxvXg8MjxaxgvXMBhcXUJQD7/LwBGrAn39SRbtFHCbN4gdyEDLFP1Tl2xjna ANimXblBo2SCDZbTatGo7UhVNg0oniIY/6DrU6TJM/IpttnQENtK48DJJa2ZMz+uZ4mU/abQ 12bcRoebAqv1fgMdsbGbxiNp/Uqf+vePOXv2t5iARtbXtTVryxFn+9EWcAcwXXfr4tEwhLki P4P5Hq53GXLQ6MFzuInwTA6NDsIPDnZAnM+d6MIZdBxyOxuNWojX0+U4QJaujvTzOvRlnu69 XJSeEX1t+El46IWCrYaDXl998I8ZJswQCOzI9/tmj/DUTTYbh/DDD+J/Z24eBffGM6pM/gBm AgqE20jxXSdBfw/+npKIJ5BqrKkja+U9PJbBK+ku0goG3qXcWM7MXKKjQ/sAfG4Xi/OnyTDH CSNYC4eNdx13EEodH45F8rNGix0N2EiRq6Wzv9k5ZaLNqH3UTRRXR11Iqvg5wMa0M6KekMkF rJqwRqSkiJg23QbZhW7q3ZXBSbGYZtTEm75v4nC/hEfujIvDnAYRMA0bSh9xxIGMbpo8NWql Gy3+29MbVTd/cavMXdaxpDsMo3HwAB50+pn0N2RuXKcK/oONZ6bXzwym6pbzHPgFIb0JXyiN 5j60PUHzIvtBnXaZTliQptAmSkLbltbDFjCFZ2rFGZ07A+bNweivIuYKCiGeczjfZhCKKwH3 9x/nNNPPyHuDfjKTScKEBkwgj9+LLjsb9sCFYbDeGO7QeJDEDj6eQT4p6NyJZdHlcGkNTZA+ QCLsaWE9bL+g8bgJQUHkKXsVoX3zy3054pK48XRg2GksK7K3JCRkvkbuXW7W0n4im88wSHr6 EJ9NFXvvon0j2azTc33w925Hyu05bVShrHHPsBZyVYjlv7jPT+ES0WTn9jcVew2c2hsIgY3F 7EGh+O7bkok7LwtvmypaVPMzrcuidsDJccvgUSftVEsA/sB1VWyEZPAuREkAdZFnoFqFgO48 FTWhcLoV8HUN5rwEkyXKEOTQxsmt+jvm5k+eYfV9uwRRNBNMd/2CjAZe6ir0UYBcbdlN7B+Y PlaRrOE5Oy+utru5xCRIaUPLZ5ZeFZZLbgWWNy2ph6FpNv563o6UwRYVZMs5/KL70DXEQn0X DxNWPfPMvZUoO7ouGBOKnbhpm9vzeVvt8S1azyc7nWJHtEsyfS0G6oEd/1J7sCgyvodCcnby /zBWZ2TtXPhk3NOFLFkWwGRqGIUEQNMeoQJCSYeD4B8w/DWmhdWLNqa/SgjSB8ouebZKKeKO ThSNyHiA1KkY3kfflFI31iSYhg5SMJaHQ33/dmeIJ5V/ja2psSvKEu/JP/YxB2ijObkxCSOS HhNCNS2HwfqC/ubaKWkgDS1F+rcaO6Wwgp5APywiM3f6hRWwvXkOQtB6J1FSRXpC5xDpu8DI yqUEFyB8dEpX83PuQ2/vRHYbML75/+PzpupEE8Cl435U8Z9H9sASvB2L4ykiQLgfQcwZJCbD 5SI7SHgP4bVlUVf1U9yxuWpFhUAk5QLFW2NivfbYLIlOANn9Vfi5qJD1+alfqBdP8+6aSM5V /0LCrVjbPS/Kn9xeKfNn1BG/0UxqpoMho5P42TSzJrsfy4/TjmEB8zfVUwkRSiAqjV4uO8Sx RePYX1XqJmPRG/Ouef5T1EtnDfwqdHzsIkDAGG7CGm0A/fdg9ceq7n7vxb9S2gAeBUxSwxE9 n7d4nCaWI49v2Opr9b5V9XrHE9ywni/TVxKTSf8qt7KowBlK7gDfjurB+IAo2yGl+zvWqqqH 69o7+/OwFOiQ/nY1m/IWflo9z+OK1g23vA0IygmuwCpWSFAMj5kWgGATLPNOyHi1ezfGpYA1 +fS0FRNvCauGaKEYEgt0EFiEm/E5p+LoCQ56i/V37DweOlqH26AhLrTFxAII+1eezIWTd1/c Kvff6l+j1QdmHTVasG5laSMJlby/eGhwyfo5ihdTjp/8q9mGSEKbXEppTFO1oVvEGKn5fPQ/ TyF806ci95J9s5P99zW9T4P3JTIvrTofVvu4X9R/oaakGa7oHTLnobUbS3TnTK94L7aeQIVU DFwYW8WIfQ80xWahhgnHC8tL+K1LlKez2EiZKCa4onuxFah3FmCJRocrZkVM0+a8//JUWDLQ Sm7hdJEGSkVVG8dEP2V8yYN+LjkbiKtz+6hmw+RIESm/ctXJ4E2jAPiW1jNmZyA8ezz8/ems Sigh2Gu9r8U8yyRQq2xRizzSUj+8AU94mb4Xl/UupCOXbuOW8ZLhtQRLZohRGfYziaC+EDGE 3LUNb+AC/gl9SJCZhxgaP/2pQWzEooVgP548XC6mDQ2MnbfsOd1heKqmxt3LnszKpMNf70yg Jk2eMRPWqEELHNhaMYpS8oh2Ekw8a88jPPCGKZeNrPAfc+OVek/Dw4PQVa+e9vdtkdcRF9h+ 6M1e+0HjtptBN1tP6HFcyEkuuXImym0uEMWKacEBX4k/VFb93cV2Z6b8XAXn8qChjZoQkt4d bACN+A8+0dguru8qIY8RBO4QmTx+OBKm/6I721ZLq2RjmxVCepQzXC95GEgP/xNLVtGSP9z/ xYl6K9f2Fw6nXcUIyrXuiCC2ufYsq+fFqKIrckIdedjQwb7EK/WNZqfbNCzNu0SpIetufbqz /VMM2JunvNwkH8V0fM6U1ijqeCgoC5JZK4D4DqYwrXRCDMITItqzkg4I6XRBl9PqwnXTwvh8 klPzkbOQTl5gcO1qCnJf9JBiNYxINHN1IF4nNBFfeKFnDxAQfkRJBs9tur7TmYWDD+TJbiTl AMR6iMPewm1wY3LNHUdNvc2Fs/truGAICG4C0uBpc2gl+2ej5s93DsEl+In1tjaPijVQko3q +qC9bOM9++Ve2EwpJCckUs/Gpm4FYc5j99Zn9RKPTPWJDU+LxC8RzZzMk7cj22/81MbTHE0+ u9iPIWKGAdwfT54RKUa+P+c/qQAlu8/pP1KVkye2DWaQUbpi+3Gk6sUuodi1yFeqy9ret3rY XRtLirpbwk/irotXOsrn5WuJEnlKkFNfM4uGpT60fZzT/6LyCs/8tveZyGuZwQxbW8oNnnaK kq4aphrHBpGQsXI8k5P/uViItvV/t+h+kSbiknuEtAuOBLOMFFrqRzzPe+GCZZKcx+HzgzaC Bm2v4ktZsT5vEe+Wtud/18+t5W9I1GL5S2Tf4T7lMHdHa/y2x+BlZ/JxZDpRqOhx3q8gYGrO DzWyv9jH+02qXVqlKts3nH6W4XcAYS/f9qtojpSMhx+y81hEXXkY4QYU9oFCbevAJfG3LvR9 TwEOcciNyURzxl2Aexjcn/xtCauhZigvhjH8vvHKrwn0JsOmrPg5wRChUAyjyouu1ALwmnZb W/vlvLL3uJ2J+LtchF5SmJxSaY7ss8eKHtSpTYTh6fSKTXk8KVahRLFbF9mANEs2MpBH5K4X bpvD5vTf7xoz5mM//NmxUaLOEW6wjwJc1TOcAaXu385wRYVEiX6Ell8Tt2dnTeg7E70Yxlya r9ew+NfH0a3KWgQaWwM/E2AYCxPzL3RLzeRKF43+sJ58d/Dwz4QGUTGmPbdEGd54QdZYjgup x3lnU9OZHq18iHCt2ScO82VqHv91yMi4NttSrHWE/XtZriSa1xnbL3zsUERDENz5gaXl6Yn2 JpoB6iFACzjL5VspPM4o1Ei/gRdyopbFDS1tNk3i+iL6y0ETGK3TIU4SpObRzPaKFaVF75zV YJ9KtECq5Nryy61I1PJVBgf9jHJ4+FmsyhsrpgCsGTm8ixYHNVGZARzR2kBvf33s9wybm1EX Ku5GlfIlDaR+6GApDHyGp4c1IzcYZR9pmlh8JKksTGbLeJ31/YEDQo3jjWdf5pVEl/1rW4wS q8PM3g4ioJOMULfatj3h2aflBTLn9GVa7i2mBnPUs0ysnhKg8LPYU9wQIgZ3iXiRh3fNSn38 qzClGl0wAKf/GZv+YueFwghOAawfp+UtOSWVIoliJbQoJ0wgMielm4mA2tkV4GLRDS5q+V2h xd5mS4X2zFQNS9Lw9bgzg9wJRUje6s4l9VMKaR3LGSqDu/rIaS+RXPf7V+LfHqNqvs8WGozh NCptjNrK9EUId9yHxy9Pp84Q3Fbegzz+o3uA4z3aBr/yF++0ev7uy6g0gTxOQe8KyExnVDpN VzR2hsUhZk37kH/2l+ku6iNhCisfD3kdXXWfftZYQaTZOOIzPB5hbgHSxbKRGD7yBOYOXfKp im9LaQpqdDkn5fZ90gj5x8sv53hDJ7Jk0vghYioV1A5KDVFXsYfpijQCfsWu+mvAoHjGbAFM 1+gTGunvVN5gputapjLA5WEg0oUAx3t4IIQZUn7cLLPzKYE0JJHW/D5yn6mlJyINeQrVc28R UUlfr1i4j+5fP23RLbQFLOJxlbonUFvrOFRiytbl64ql9juQbvdxwOoi/s+78cBCGqAXegGb Njj1JNyudjYa5X5J9gdjSsS7vbj/5GYygcyZIPIvvNjsL54P1QLhrNp6q1Z4uHUetZdSSq38 +chOUN66K6boLrNkbnY+Goqg0oI/uFJ6eweyMV2bBtzSL7q0pQhmTSyoO0kcZUljVNXB5QYZ +orBGwhuvb9QhlTjuMpO47eF9NdjkKD93MFVWJdejtg0512agNt5SI/iHo1Ojt4C4EAY/e62 ocY/ypjxdmjN9yrWry/nRytc58jT/c3NE2jh1bq0+KGSXQ78mgprnK7kvo1LoLZj0ujHS9EG 898zNJEy9mC7WcypIbzebyxYZtLqGtGH98SSztH64V6vUBKF/+T4IBtEl0qWLtC09PE7W69t YQOoxsLVfHcXRJjQaoNtt1LSrIkFw7GZZvKIhIe90o2M3CuydKHSbSO6KSHEDas2F5yBdovN iH7YGfDs7jJQ0xl8OcW8D+hOcIpKf+pyfTr0DtikHA7lwYNbVpCxbch4ygWjfxBpkG1AXNcT D3OBB8B0eYoyRYfhqHUltd6RsKr6Logfackty5YNfltoYItSFAZb1N+SXZMDPa/mB4H0IKhi 2MaG0FTniwmzh1cCnIeXQmsw59QsJrMltXLhcrM43jzt1xgxRxdKABL42z17cqp6+xoaZyR4 wCQOgFKNDisDWNkzHhlcdXPLqLZxSzLcrL/KETFvh5eGXLcT/qjztsWWxEGpcxvjnA7dwxMH f+UfuoFgZw+ZzR3EWK2ZyaAFgtJUXjCgKP3CVNHpVNOmTzaQqFzNLeVZzU2enCU3mmJ2cxZc HbMZqbgJKOOgnPPuSqp2yvwt1ecOzPZm7tHATwXdBUd+dIks5TWXQU0SsDZszsXDMD8A93Ta qs7waZ1N09gkMke7L0cbuA/vRq9AVBRRFCAIM7K90/qIPDBM4SoLWKNFfXsWDxMoUZKAi/wt PwbkEiWVGYbaiiju39N9fBS6xK6F5XwXCKyIMTed9F7TQMzEDrT+4auf1PWKM7L6B1ZdcmWK Yd6dEdu1dUAhH1M+7z9IkCWlcMITFhzB+Nh7srurswWfotPoDu0sxrS0K/FywgYLHXUQJR2v qvVPyu39vqXbX0xgQOpEOh/a4RzlMPk44CDZ/GjbI3Wjt8xwvtm22j1K+LGeh4kKkpeW9MYN n2yUMW/FrKyyBj//rtQqJaIOaYLN9TdtsWZ+0xSRGDl7RZ6z2IXGEMYysQpAPp8b81w2nO4x qu5aP3z7LLduAckPpM0CR5pTry3XRLllH2SQkGyTxVH6zlCcv992OlEWnoHB0uW5e5mBSUzY UdoQMelAvp1xKCjJfMEatF0maENot8TCNmMK0w9eqIiV2FOcHLukgdUN2Km4kaXaF/BirQSN mxSeXiqtfUZww5eDtdpEMDhN0TZDiJ+ZX6LjZu48RerXDGPouB02mrqSdIwWnbs2mbIGl0He IWL9V/CVcacc9WLcYi/qRt/pot3io3cWnfvDRmfC6oHyghInexdeyTHFNxEXpmWRd5t57Hcw 07wxfC9BpKRLBMDjEc6I3zEc+BXFkMEt/Gn2yArqAME/FkS2tHVXUm4PQsnNWmvhJRanFbK1 k9UTFN08qj2vG88S2JedOEqr02AGANkgotgFSfYy+EMQcOkxSpwB0TpcFgjgairefeaL8gFh LkFEljUGC6Q4/UNqdoL5YByMPsuPCydY81X5sSRx1Ce+8YWoe78d5e68lblXcXJCZjRBSpT3 AicrABviedZoM5a/fkEWtcfrAVG7Efj376ztvRDvzlWeutAeAqaV1/PTpzMOdZftuZ6jNjIk mtExNX7WZmjFfmq7cJvOBNAKT7tpJybsP+cCB2xZFp+3qneJeERvhiC4anx/YXNcZq5bnb6r 2LyA4eXY9s9NhyJvlparI5tTRb3roSoaeBE6hyK39y7oVJrUnSCATJdwaYSCVTpEWXK6nnns Ud5M/JP5YS+VcN44/h3mI9Cmy2IxHC+dgBMlf0CAQtN3Yv9xJ8TvyHkFCRVlvu2ty9rCwirG lE2tJQzEPIN/GZU09NDfxT+47/hPf8/tgKOJL6GrwSYbQOYULwe5q+HQw6rWVreeZUbKg6Ca aLdsU4nTMdXfid48qngU2sgHpg/D4FPhQ1oKM9Y8deDnUPaUHjiaYX3/mpV5WCc38OqiwUJJ WouMWdSfZAnuseVveH404qtREFJNmtsn7tBRWbNymT2+RPlO15YZBkP4K9bYq+k4kMwpcCdp VS4w5v90OrI5N5/cJYHib8Rns7G6Ht5N6nEEY2IDjYUlU7AwF/rd2dgeyBFe0U8ult/iBIoW /SPGU/7y+ZxHAnFVxXFvN+jhhX04Y0lPFwdf3kodi+JBkjGuB9yJzrskoKQp4LTroVqT6XZZ hANxBp7mERFWDgC0lP3v711zKZD3r0SL1ZREnfOdE1WIrzemx/MFEQ9v40Jby1Qrfn59eBfR QLaW2+63S8I1PQTBO/eBCp93QfTDHVYFT6z5brtYbbQKpgLv24z6zi0HGyOIkvCBR7YBzSJZ 1FnYdQEF9A2jX5ykSwuxtXTHvpc3IYI3v3LTVfdtDlW2X9Wv1mvb1Xh3533lN6NvFLrfp4+q EnSUSTJSwQHvpJBWjV5tvxuoZV/UZtSRnrypg7yY70eOj4/n8KQolnuUo84pd/Ao310vX+8D gaqPziW4e7xLX0JHzkITnYXWPf50rbWHvCw5qREBihJPjo9N16KQfxC2veouGqpYghEs3rvu V2ig7whSgHDnfZeOqWY7+usS1obsKoXJSRcECB4GLweexIb5DWs92UoXIBsyQYABVA/L9pSL gPkmAMGmMRZit+CsULRMeZnLaWmkvYCHTSpScsFrU+zPADC/wvKAss7Bi13nrnBnrS3psR5U BSZTFtXLhWf9+fJ7PgT7LXMRWUmDEOMKhruL6n4BDbB7gJVFvjDck/Dkx45xJCd7qlV07Cu+ cgDlpUmjIgtXeTumKSFCjDYrqyjCBN8KA8siFtoMUSh9PqVP4cy47ZlnBaNy7KUamnChNURX c36vq1ScQyjTdky3XJFKtes/V0HN4Jd3lRsf5Hzp38P5OU5mOoawEhV3g3wyzByJYznZMO1P VCLUkOAvh5gquPwnBuVu2A/DiAc8dJa0490KWVWJxtq2ZsamsEbwWs+IEeebDy9sFjlzWyXK 9IEeMrG/3bGj4fArJmt+d3ci2sKn44SB3RvVyX53O1UIKDVMaM8pLANbFV472OjNgeBSBsde xUSeH0HxNKSCEQVJbPl5U8lEcmmKUZGQZyotsjXWR1xafl3rsFZnAacj/X2VHzQ2aq+nEiSS Z44sgGB07Zt1KdvauRapMVf7QCgl2ocN3u5gE97ycv8PHUe9RyV70RrH03QPlwNnbacMeAHr TWsWiFlkkanR9E937Vf8vKShsuP5Lr+JMYr4zh0qfP8PxYl2bNx3cpYvOODFWwWpMjnQnXZ8 1bg5r2AaLZGY+L5ilEEM1eM4TDRK79CKZywG3UE5u3RiPo/OHvNwx1fLx+wCjQpxSZUnRUVG 0UYjQFVx+Kfsa+PrJAr9BcH6KBiOJzd6rwK9FUPAVimyBf913ff9Wd1TTNIlcGGCySWsv+cF dkgDKde82+cnuqv7BQRX+obOcQ3NiZwqwuziQwK2NmRTJ5OzbTeCQKrfZsZeGCwHK+ISG2Da FzhF7A7YtlrkjWkrd+6PeiLgJTWhwdBPriDrAnTLtsrOXs2ZZh2emx6IDi1kbEW1+aNmgK/U luaqubIJEpFdUZeGmnRlDkHk+SqOk7OCznxKagI0HnLBNKFZgnvJ8vUKvuM4wgP6tqwbnuYA cr8Cm7tDzoCM8l7L8Mc6Xf4/itet2gVS8OTSWagErMRRl5Q6Wx9FEQTAWw3LBaZ7Lmn8o/e6 Zq+D1rJf83CkDGuyUy5F08PyE1+YU7aWTCqvcdK/5f6hPpD34wjD3z0dhjvxeUisMbWEV5it h1oJNhMu8L4zErtMonzZLTTeS3B38rxaPOND6v8CmNhP+4E7ItgfaQ+k02nOkh7KgVbFNXGK dS6ng/ARMEQQ96unubj6eR1aJeth20N+YpVo37rsUXT/1ZAlcls0uoQqhDCjaYMkDsS82qtr HcQ6T2dL+aayga9DbQ7uPctJf1QErTFStapJgAOsN2NPTIeGJX/zr/I1V2wqZMiChpn3iJK5 5bGlbocK6XwoFhs/apU12WSWhmzxZ5K0AOBij4pfuhGvbY3/82xHQVUZT1x6a3fsMOQVREUV b9xFEdhtSVpte+ty+gYyvg2sMDymUT1gsNMJQgy25haTmRMD6a5pOZPKcLzqm0ED6no0k30l eFMJGdSpV16J21kPyxMVtqi4c0lZGO3OCebq71gGYrdGcaud9DwFlR1TrhXca24c76bYexah T1t86/QA67ALw76Cuf/oKcxQo62/QWFGNjPdRIRDhHjD8Wk1NoGf4rgpnLJoZvVIna5hjMHe NLgin7kZYAC3xBILEgLzaVF4G/C5vULGBw4zdR3O5/Lr9Mjliz+QLUMpT6WS3mAlu9Gzrrnx reMovfWeNsK75K7lQbSdQHnmk1Wgb8nnzHhED5Q3c/jjJ3ZTQJD6um1oKYTrxu1kJd8zAGi5 UPCZEBD6gckeyjTl8kygZdnUNJK1NALPdlfMhU3IjHDvTVcZwLrh5GPgY12NDVYXb745UaAx nXZO6hslOb70rdRSRn+dMQ46hu7uk1+IF4wrj6fNq/o9Ia33iBHTJ/ssASDwaBYKheI3dRcB tXfSPCJwR6Gw0h344FdpOJtSFo80QU2cB3m/FVh0jARhpi9KldFzhnD7aTakT3tOeez6bpaJ 74a6PwJ+MABnerFIs+EzxuvguB3UQif0PMIGBwtohrWOefjDqj9GJg1aUwq8SR830GgtBSZO 8clJxug9MHEfqUOYo3Yl2vsml4Csle0z6ldXWk39iTB5zgyYw8U8wvlj7Df7RcwFOd/XRskB x4jrR/NSSrImqmmSJUc8dBKZKwLrHqtFkZhHYR8Tk/g2a3DvetGRcPa/xZGPatiUNqOIsqXa zUhdipLUjB+UcKOTdHLMgylmWAMoWv3MbSQfyYHxDniyn9nQ/ZLy7piXtrShzS92DQs0TEnp AfqN0WQht35IpJl0WLV5a2dPesMdkHyKRMpPwcKq8I8YUhH1nATU7/PbafJfWDVP36IfZMUd +cWIHeMAKysW69Tc8PqdCVepUb2NCyX205pN+g5ZloCTc7xNeqFtXxLOL698RsSMQjY6/FPS g8DFJLYrCXXErwOiWUINfnpkIXEFmJOAU94x8kXb1OpxtJfjFPM1T2FlkZVO6YXL9EDUzEc/ mdkJ8H6ZBl2y58ZPuKKq7M6jDlu/NALdvO2ft/ufpu4k1ZZtk6fIa7OcAEGtMTKab4dtudH4 4suBjxaTg1tUIL6AZkUnlwCm2vJ9k5HbXUll2iGF2JYMZoEN7YUvyGsE499aKs37vbNr+a40 tCQ0lnCWp33sLDL8fQtCh+zEJamimOx2hbU6pqT3ETx1KZjJ/TKf/ZQkX+BtBGYRRbj+PSvE L2pIu89j5Cur/OgrzyuwdQra9Tvpq3q5syo+pZ9uVT8qUvxX81MT1oZOMsfADOVoZzthoPha fB7dLityE0f/HJB1BVc2BdAoE4sihmu1dbU67XYF3WcQOeM1VuptQ3/GIfG5xenWQ+E0pONp joULXbVJYB6I3dtOOSfgG6aYrei5orqVwGq/pJ+URpIk34c6rflIlvGuY0wh/UT+HVD612Zc GuwWFyOD9BPGW/+Frd3cgmRVdrqDiw0bpsoihfLudEl2S65fHFZYXNtY9+Ic8rEbkwUaW9Z3 E9+WTyVF55ZsCRlwukvK7ZZ6vThKg8oeZ13aAtxQaHaFe8TrO194AsseOF4RV2DjrU2pLJ6+ Cp83N/H8ZnL+nBM3jRHbj1WS6Zdq7ZC3Gyj1VHNYIEEqX8gcdrEfEHH/QgyBlaGU97iGrvzv MwOouIDJRxuYpqt1t6cjRAlhKHFRRe7X9UZLUe8gg+MBYDveONv7T3hq21zy/j1j88VaFvjv fo+7wYPxWIXHwoGk99dGW0+6Ko7NC33jFATWUrAIk+OPD6MzlT5E9W3+1FNRVyuerKiGs656 ioB16YFH1A1ozwLGDZMvEvRbbXe34WCTJKzEvs5bL1hl28/jX6Dw0+gljcerbYCOrDBadVpq QfXK7CuxgJQnjLH+oB9+cRyXjdSAANxDOdM6RQrF1pvU2Fa7RXHkGp34NcQ5gMTzAXsilDG+ Df7EThVvZO1tD9XlfDTnSztN2Ug6uquT7/FRZQqwtvDwhH22WDhrR7JDqAj8WO12dHOLMWPX KG7bsXlD+0d+zrqbXcOSjl1KIiS+LTK6axre2UF3iMQoluu9L3wCFtgSBLq+AJbsjSjjdh/l hFrkFIsHV2dxx+nL9qkKh1Ljn4a+cgD0u9l21tU/wUXO/2OZibDXnT22HQc1/dgNQhMIbp7S FDWRHB+NMUBEjUpAQlkkQ4FlUXUmu2LiSwbluCLbSLHhOlHFplphTrD0v3buYl8S0Dupm2HL ukoV5dz1TLaTAsOfnBIfRPBLkSKtlq0+I6COTRuV6vgxd1nGmshmoXNV0Wv8DJijuHb38rQf RcHoSxCcH84Qpg8Fda+7e8Y5CIRVIZV3l06QgH061+7+Ood6xjsWeiCstj3/9hQCJhWdych4 GL6jGtZ2j8XC/RwukThxlM3xtL+1LoN3HQTq1bCPuefRR5VSjVZM6sQ0XsThPj4AhUbXQd/B GCUlbyniI027zPppaeh72eTulaAT26GnlqEh7Erlk+sziupJZwS7Ios1dALBgjoi+tKsUC9O 6uO8fPpbekHmbqOsj42s7qO7ouTSjh15jZ1ghDM5QtnIajq12oNs7yMkNbua/eSUWYWw70O5 rFp2GBTGsoYZnbnKa2K1J2UesbSPNlvpFm8H8FZap+3tu6J1Hiry/QlOcm3h+c2t2uMLtM57 W/bLRkzKawktn7oAfLjEjb3uCaF1GSs0LQ1PPDjgdvnkmNmTs1ViznBXp6YTjoee5QNI3a2+ yTtSBClv8tbB8YgnyV4Numt7XZ18vK9jAz8hS2s2pwq8HHPG1ohAPaCOuBj3xKm/v5fc+yYy 2AMYtpZTMqO78CVT99fG1RSB9Q6kwxcmoOJ6BmTeHG+GFQUkokhXQYXYyDUkiwf93qtom21T hBX76sUqpmEwzNSWmyJHH0Fj6n1ERcm79O9kM9OurheohIF4JOlt20JUrI6fikAtNGFadLeL gbUt9IE/AyjIqsyGmX4Q2HpIjbjUzM+7JXdyzxjRpChIfmUTJ3sS4kaY0llAlc4GpXBp0Wjt L6AG7CBDO77EGB5ApUsgJKhdn8JNds6CQw9EStKVaBJXOEOrHDZUkJmSxaXfee8EQckWts+c yNzqrGPLttIIHSR0ja7mhUTGm9ujcGxBjL9twlXntxyBXnDYqBArc+7AVBUb7TE4rJC6zoJu JA8pFTJOWNl27pQ+uKPDvp3XaBs/5tDoLdfRYZDvPHAXpJjcOe88+/pmuxwf4atH0tuAffzr ZksRVxf7uQY3t8hm3ihGTg+fW61NbiUSgrG+J4+Ugl+DXJlPWjfr7Q9NizbVFuXr+62PH6P+ 6O14LsvPrWD0E4mCuoBlxN3/XWGzEQ+GIsscbgND8I4yGQ6ptKt9RpjUJ+jmQRmlwk9sqeyS e/um0daDLUrAYtQ8hu8UHEpZwGqXhycgi5j98RxXpCQrcvUt0Bw/rHuj8qNt/ZBJvowdiZYk RaAqE7BFMatR1aWakvDP0QaAE+4008HasMpZYBGW4MpMpC8wJ9MEKbnK/t4ApROEVXAwHKXv dhGbH4nwDRb5Rlq70ybqotRgKLDHfcnG+vBfECBibm8nvIq1BYCn57o7Bmzimf35IaPRhJlu pYZsUdgB8OYV26PBvKAOwsvCqHNPwkXeZs7RptaMsxBb8m+kDZCUKP6Qj4O+gMT9FIGPRc8M KMtGlw5R4KOVrynjKsh1udbf5ZAXN/b8+8S3NpK5G8VwPAMcIlDjXo2QVA8UQRB0iXvh7dtM EpigZGCiG6g25j8fJLwgTHDY07KhM59Hwn4uLKmVdBGEPbB3uAC8AFDWfi9svEJRrw4siMmg uAAKTVJdzohnopdKKRpEiE4Hf520ir+lurnfJ2PatVkOaz1Ilg9Hq91NFJafihc/zl2VKjFN QU3iPY7d/5jFxwvv1S3N1ymBXvNrj4GLd56rObMesPeOtlcPKhBStxlwOgGAxN3t7ZYDKU7O 5NFRLUBDHjxlSkDmirpoD6mflhcqmq85jw0oghkaU9Xntn6U2tNBveaQExsN2nSH83sdR9Ow 0HGVbVBwJWRZiZ5QWBWMCyimugajJo6iRD2worHn3ESZPCNJk1RPMK07FrHGpSsB2kQk9HQf n+CSbIHTU8GORk3u5RulV08VdkkWo/KWYsNdLttmemZqWb3GwmsupPDYQr2w/EEFbq6bS2em pA3M0VGbuW8ZSBMQmG1UOQ60+RB7dPt/6HxV2aB8r7YHDCpZmgT2doNS1UzCCntpK3yli4I2 VIN6ex0gCtaz2oA5/mE3N7Q/29k3tKDKU/sZih/pKPeQPA43c2UTUNwI9qYubJhy8VFUSBWf Be0XoUTliCKuKudhdw4U0t4xY2ICY7+kWdZNR+ZYnnRlyOCyEvTgyF6vvoUHlmG+Dvo3XUU+ UKAL0Q+J9DvkKb13DO8uN6McZnJKHoTtcgu5M+QHr87BZfPrQ9sj+i9N7DP/JfypKeLMOy4D haWrovWOWsCcTG3FnJZqAwT8r+W4q+wb880pw4YDKmSVnTTMidcNk7sp9raHivBuN9MK7/gR 9mmzCsbrExKYvmfi5SwPFBobGZo/9Wkhv6yYJO8f6rUkhR+6JdeZ14L5zanNasz8mpKtiXP4 Z1uBuIBoKKnR8Eruq8hIT28+exB40Rh6wK0oXtjAHWVyAFXP6GoWHbX73jULo1thBPOMMFRN Licj2vpPPSRcmEceWtQ01zS1UT4LNQJM3+70rvjK141MYamjqkXXwcL9NVcrWPUrGq3pXurS SUncj90V1WDl9rfCeVKJRpiCd90pK9cE4/z8tLeGmQujnRrVq8NYU9EtCgAvgeONqPB0hU/R LJjFKtew+oH9T5ZRAQP0JSeTuqHamqh6BRqhArTRNvoGRTLNukEAlLNr38Yr4NKBdSK0mOvO 2fdiJ9WgH+/R6PPYKZk2X2grW0i72qsQFcQPaIiYCC7nOsMzB+5HJ4FJ1rgCkWoHaTQP7amh 2m2qDvMsk+RVicWR/XyHmawZG9+auPMNtzeLNLa2y9f+cg6zlZbRPk1k+wxfkBHaG+EOlD8t gBN8gN2gVst4UIxxDNPguiK3E89APXk/ml38u7MoFNuiYPLqlQncKWfbXgY0r4rcbWf1/K2f 7S54EbxkhoXFCrjQiZ/SuDAd/f4BoNvB1DS4dhIZWMf62OAYkk4JJkS4ZHIPP6K4xiC3Lqcd K8bhGcNUaTZHO6qAg1s5qPl39eoD29OhqX0hYcE2OVgirMW4DNZSNvqpf3Xail8sfU4KzNLq 2LKRckb9SxGtslH/n8m+mx52rLVcLeShkvaQKTl2faGfPoF2aAEuU8Y4BL2S+nNolIU1Ylcv ihHkZK+7+spSMr9O2MrQX6CM6D4tNnZ/IcXTcDTSX0YhyuDFDp0GaJOXkWeW4ojase8G94UM SkoXDYaFnEE11FK4JJY9coTF4m/NWDk7ACvLs3c6T7IMnwGnRfSkMupkpBCxRsJ3t7j4rjyq JQdiMt+MaJnDm36JOGv412AVCymAvZBTwIvGN9WVHioIi/ZviNJrXYwzG34IyloL+8mURLaT n13EcTdCfRhctLiOGzEsPwJP9lNLrOpq/rRLcysRGr6ut8ACdcbps/vlVUCm/4BbKFMgO90W A9ta30duI7BFFrJ00HXJz7vdsMPnxRNwHn0mWgwf9WZzQaGfOPKur14f8EOzbf/0NK3LC+gB 2ymjg72ZpsiA037QT3sXfnYNHMC8gAT89kTM/U1rQik8UegAps+nwON48ioTVJpyBpltM5ib jEZgQzFE7t2EotzG7KqDhk6tW6/HTzowX9zzYQBeuDaGq2zaR7R7qman1BxjGIoBGL5UU6/r gIHIMV9cXwoWDwjEpX0N/1eD/rzhtJZdeNKhBVCkwhYDarnakiMYk+RjxkNFhU3P/0ia0NgF 4Zp8EkZkt3B9MgHF/0tDpOPCoaBwWet3DRYB+OzLMwN5BXdR8T/I00PaClxhdQCknzDmQLfk nW2xAMUDRfYIB+qr4x+CkZfFKofG9UZs8is4mwA/u8SXwXu3nvBBJJzG4fxKMugBJmHZiNx2 KXOFugUHFn56qbA0cyUF5C5vJ0OHpwaqtkQ2o3UqOtwQcgmuKDqFEZB3UPO3A/WJJfLz1UVZ UQ9cSbbdWZtiJBoWze9vSYUyxG8L0z40TRDto+2POm3G1nPJew6Yv6YdokuNaosTeOWLmN6J vqI5Lp8MjOU2qiahkOWyA7tpzOObet12v6UWdvWpYzZnWVewOzNNPfnP00vi8oXLQmFCWn22 K9iCDeqDFNqETotFAefHc4fR3nYddq6NwGOl3e5h9tu6roxIrrDnhDYKJuQ+XymE+z/nH0Na 68ViKx7ev5Trb61GHUdh4/Z+BVGgk4HVzjZ15nGUk6cXOzC4b1hHNNSR5qAC3oPvRDQTrEVX M+WMPfseqNGl+Z35WGIM5C0R4Kp8A/jBMlboapGUomDgRMAy5KiBp2KM1eeOMmEsNzVP/L0Y 3aWuBkGazo8C0sy7roy6xXelIC7HmjD8Vj78+/alQQJkK9sdK0V8lvX2lXvdWHrEJjFcGmAz di/KJf57d3Rxst7gvn4iyENc1zzfI2GM7mPxoHBqEk8Bzwt2Jg4KyIzJsPoDeAmhYB4WZ/2m Lneg57KxxQQlQTxJbOdmKamK9TfMmBtkpU74EGRwQ0Mp5vtIgjJFb5HpJ14N3XgfIXWVDNq3 JskfygYufWydaSEGgJVt0kyyEau3eKwQ1R+/OncKGzCG0wr+CS5QYUidiHpfp6pJgQsgMrJ+ xPWHqbty79/Tc2cT+uPSboqVlZv2Xbccpvk0fSYfMJgXE4Wulj0L20imtctL9DjnblZxGzK8 ZfeqUWjXHEnrvXm/tWe6HwRpsZ9dw3Jf1cTj5N87gXVu/RKQ3Q/kdVmkcsSjjsCZrJ+8LZCG B3XBI1C+TrasIYUB5/mhngbsEzgLwPTb4NvWukz8rUGeC16Al9Vyk3qi8ZDBU8/iH3sfsp5F UdjGIxzHUMFwUR5nrPDqYyIR/XIaccbas/+y0FX8iFErJnRsyKoODBB6BajxIu9sKc5XkQag R5qPMNdjXF2uHnXNj9HNMSCWpiI8hVGFpRWnB0cZ6dHzaW6/JqaeKOjphpkx2fEceWXYkR+I QoLLcuWeA7QIK0HnvjqfhbW+HPrzDA4YnlEU2TFoP+A/hkNRwsQG1/Io3P/qSPRSULzcEE9t dl3bFgWMaJPHPbn8XMZ5W74CSrdvmX/e6tu9ub6ItM0US79JHSwk92mr/HU+K4Cc562l4mUI t905yZdd5/RPMQoLHH4w7P/KeGXy47UKwMpU9jhPXztRarV2YnzOLrYJbQBg5cq75yUYfVLD FNSBB7JHLSC8Js2FyBIP7PnGyqq3KV3TGnhmRQ0P7IWHfZXYFod4BdXsUPmcf17Sd6lZw8Tj P/wuxXcfyDfmdrbVyFabjpSnpaC94gi9mGQ53toMS6Qp0OhFh+FBkeXdF+hJfoXnJ4nq3Pcw 3n4pLai+As/DeU95KN6dQ3lxC7FDUIruAhXzNzZobzJZMiK0GoJfcnlWwXrkjzJQ3Y+3yqk3 TgaTkW+pg0F1ofy7J8PhmSOXBRfrJAhGQbcKxe1K7l4IDpCn3FNEArH3ezQhMYBLjwbuuBQz XRlerk1gJBqhk64SYDWbO1p7kkj1YsS5KycrGZ0T4Xph8vjvJykcSZe3ijY678F8sdndsVT1 ojKwzQz4hI154toAE6D5aaqYrlF5917Rl8hctwI0bk403VEwgRVvXuZ49AJP4tkAXXB9sa1X LoE6VlcgJWyZWEcv14US+T/279c4jw/0NGNKwQNFjAjsF2UbVZQShgqD9FlCQ3F4HHUufcKx YLr8zzREQj7/UJdhFipL9pgOA24fXlNWDbxCkHvtVcSwo9b9yjyCU+b9D5LT0PSKnt9S2j+K RTLMPTE9+viddRLWFvP6YttZz2hbbl1qb2gLoNfNvfLjJaJwsWmI4X8SwfKbne+bGFG+rCM4 /s6WtGTTTR4qzSzxIh3nWrDIz0s6QgXtem0hyrj+CiEAFV2yJWerxd/meuwtO+Z73M160wYt gd10Up4WsKiNArSNbD9rAR8uYy10EsTPmbVkffJDaElE60NHgEmxHZev0HTrillVYVy2zc4V JsZ0UBFX/l+zdgjbXUR4HtZXvQ6IQq7987KbU+jtNhAmWB3FEh9sG2zsZHsgRc1Oj/DnhWMA DgPFNd6BVoQ7de0ON30zQQZpMhiivvw2TNPwO16S1j7HDsMzNumHIkmPg45swCGMdB957wyV ci76L3OQFfqQPVCnyJ0N0Zaz8SFl0ywHi1hRw8m7Qf0X7ue7tdK/2pj3jphGHuMxB2eZ8VGS 1ckj2siAVZ1w7v+JPGN6s78P446vEx/a7QJUJqT/XAleYghS7h5L1uIN6G7/ev/FK5qPd5mb Mz2obt49fltSVtKl3kkzt1qFJKVxsEENxm81LcOZNAGlF+DDVKtGHV7cFiKUPsjO65bDaT3U hxStgYKAacuyu2YD9VVIiUZZ8R/UVNjJThDVcEKyNwxgTyedzrQ6D6AW3bB91mfrFgmvv/88 qQZyXuwVJ7OEw8RTGh6XngfcA/HBJyPcx7okgiyx8dOgZq5SMShvHgW+i3V07Aynl7pNWsjo kDG4HS/7vFcdZP5FDpIwBS70QFeLpLXvdPprRf7wHxc/0GB1Mvc75Og3pnykyl68Gbusjsb7 fBFA+HTiBoCZWix7NcpC/c6Wk4nHzENd6F1RCs3mgcJfMzcviGsS8JbEQxDxrFRunqqZOb/E EfwXmPxkP82Vm6c08hPv+Q7WtH64f7wP2OkwfI9W1xectj7pXB/lCfb1aUEs9Eevj7tK0T96 laxvn/Zy8mHxGg30MqwxRrsUixdEG3LQRNOPvUdAIPV1mMMce06ocEs2WpPE+tVdTHX63RL/ voxQvngxgD8whIknEV5p7fyqAdnvCiWMqFOJJDYeGcwAJr0kzgHCihC3x0L4tJQssoxya4JA svgmGlv8i6xF1DSc4JnaIgLJYtFjfGRFVrySDE2KLpStkFZsQVxjcbFEPeJcyAB/XN3D6MQO 42hHyqHhj1ID8RSTJlTrj4KSy8CTru7GOo3QizFTCP1b/xrbPZx1FrHnLrxskwSGjUfdXy1g wkZvdKOdfGZIYmxgq71zKB/cG7Y+8kom+VgN5n3qJJVm7Nfv5w/DqbAPl/JXxEbXy7k4luZR lblygo1/Iug48/CpPyUa4lIpZr72JCmXQdzcq4nDrhN2S1atyajQq+NtdaTAXoawsIay/zYE 5ycToEH3qHZ/pnapkwTF1sQxGLY40PuC5i3JgVYuhq+JNcHG90Ks/kEKk49be7vpr+URPJyL pCR00HPl6LHI3b9kkEsbZX7tv5u5COI7RJzmYX2xVKACUHXi7pq78t/4hLyJ3252lHBSgYxt w9mrFzGUczjHwjAzVngcP4K13stDE9i1etITQ13l1D5Tsl/JZExfO7Ouj36ybvPkfz7d+AT5 gvx0IAnhsdm59N+LuqukCutoALb0fjAXcneI1IbvUoTzRcGCxzn0QwpMs4/Puw/OCfoD7Uvf bXZ1pfUVdjTcq0olAm2Rh7nglP92SMz62w4oD7fhznkkGPJs+eZZpN5eN1GgsKgCPuOD23cr 3fDC0gdauT9/OQd5O7g0g/G8mvIygEUbtk/R5IyqKh7I8AbUlMsnh/g6MaSNxqoLMRLkxLGc dELg97nHvQPJpykwKGVtf2ycYI5JBfgfsnV4wd4AA9Q2c+nT1HMwNthwbsqXjgGc0dkIWrDf ZOYclavKmBKEkvG8s142DFyB+PdFc3yl4GJ4eyPmDIc4arQBYH5HAwFdS203Auhw6Tgx5SOV vfFHwdVHfS9v1lRNHOyJXdfH8bzcEzCsUcYkJHPhdG/TlQNfP9Rg9d8rp28Jc4nPTWEsnyzF sM3aiKcDSmbzCZMKTFGhWs5PQN2NODgDFInuk3xdfVvuYKYYr6Bs2BNcTLmbfSixEiN5xBQP MTv30QY7+m+2BBbkSyNe1tWpV2O0Y42FHFiNu4bvsRgcelprOYLBdrhb+/cniZ9agdeAlb3f Hqjk1ih0j2BCQCC33FIxNGIwiwQ+pJJGN+saB6FZ0RQL7g1ka9bVgTlrswuQG1WLiTQEOBGm SwWmz8Zi6riOU9nMzX6TyymvclR5m1auySHo407Gl21QBhSUJacj4Xk9VI+vzlqYsrBKNBYj eFJViuUEV1tZM3bt1+jIFjzu5T0R2yON0o4T9iz88F0d0WB+z+PaWsC2U39Yxqo+pFXjov2f LJePj+G2qb4H0nYBAdXN4f1SX/rSN5ixvPtELslBvWtrjQE8uNW6EV8R4VXFdo8rDbPSB8S/ j/S5zOOoigfp8nycJ+9jdoe0YCzFN/ZlvMSgzTf1kW1jrYAa4uUC3rf1qb13ACwj1+ezcjxC F3DKJ8OiyBjQ5b2N8u5qG3smayhJLsj/wJGq14MkpB4MZUoDzU8dzOhfmmwLX1ClhGw92ISh WFiJCMPUX/O8aGc2YLSH+W4HVcoIjmPIpccVz5OywjWzg8WW6c5rsIzSyiIGQjz6c0cxupAo hx4oqyYOCBfy0R8Eko1RRrzmKwTEDRp1z+/cQwBsUJB0uN2rDVkUECUsOkpMbbw9aAYa37Ym oHFUeP2+EmQnMNAUWEyoWMecFPTmXOusceSJzULoQpwOfvgOZqdW9nLaUNjUBeLvD7gCOwYI 6+JRf+DX25SakyFPrl3vdXkUCR0rBtAnCWuatEMWGAKpFOptCYSNFiotT+uTaWdIagsOY/Dg 4/eYOblXuLVU3oCYJi6WwvFN/IFmuJZTLoJ/xE8I7hYEey8ddw4S33vKhWCZ8gJOnsVugeTy CVUd1LnCuoyzszB7xX2Z1I/IpE5RbwX6DUGOlCalsA1neLTD+JzeE4xn6yMz+CSn1vDSsYig pfbal5d/P1xCXD0KMmYaAIyHwrDVGeYmNR1qdrqDwnRbWwlw2dmUHxvjrOIEoL10NMPQyWii 9oHSEKe+K+hkMrYvuA7cfN3/YDjssohAYYR2bsZrDIfTtH4WC4Im+GXIq3JeszSoNPOIjuka nV0EgFAqtmvshGUi1WdO31bazEGEXYV5fW863yF4kMuuXkd3eGtYqD306JkVubmTROfPBMSP O5/5Wg2S8HwVYT0SQ4o5PrG2+r3NFXicYCTJt/tf5hKFP22VmyNY+1KyDPEt35shhqzYu5rk IHP6fXKoCimNUel2whar+R0z/vDyd1dVSHLtalWdhUqVKyjQU5K7IkJSHCmaxKTEgryN3Xlb ozkWELKe022HfpP+7yI3Ot/blT8eVea3OpV1XJlOI8Lc+3HTH7PFGpyM+Yfgisi8Yx0GiKek EGCYSWXF7sq6VE0K1KnpXcT5pMK2hnD1CH3zXtQCbZepPUNEhIQYJn8BwKlcEpUNgsLPd3hL Gc8maNL3lIDrUWJxj9o6p6EHLyvipfHNwgfeF3DHyRVW57moWEgkYeAnq06Q5SisxYevCOmj rpXM+8rAj9noCLE04QFOCo1gaUEySlGGOZMxROzRb6mJPVSSrYtkH0MdkFl30Dpav5th/ima XZSW6O2N4cBSg+WxiPSI7GiBz/24yZqaV+72wgjjquN/Y0PxTKCn7Y+paLj+M37qypCS39/G Uk/8yGeLwuLflJibBWW4txJtDqou7zpFPViUA66AqJNLhgnwLuniq4Ufz023Mn55F/lrUmgM RYj+UkIr9moLqQW1hT8SHSruWSgAUA1Gk8PMcxStHPghXQZ58ctY/2ejBr7tFEcZpZsChPVT g1BXP51ggKqe+UvKV1b1ULN6M6ClX3t+1o4xcASX0gG4e+hxSKflPaPJwoxZ/lgjj07WslE7 bKd7Lc07bPPYb18B6GqZVDSNCTmDPPFVxcKxJ90sKGPic2Gp54W+hfu/X0gL8/zlZx1a0sHK PSCq13wnDX/zxfocEG96Vkf62ZTf9AgikQVsJ9QlzlhELXunTPwy9fZss04f6GFu1EzsUzwb Ucx4M8HXLxq/eCH7ZJwFoplsDQBaHGYTcBG8KVXb1dWcow3q+dwg1uOi8HfL/rJZ/+ZdwImz StqT2wA/GE56YH+Hw4nkSXMfm3SVpjlli9OlZnNsuz6YD7XIytRRHSsjx089KuDoXUxEDI4u m/JteSqhnX3liXGX6PD2uMie9bz/3xHHvI2qsQuZfCHrMJPz166ezYnsmhUeK+OY5dXRp3MU 8bcxp7CXouc+8KOOoxLZHvHeqZ5iICYv0HrFwo5ryJS2Ol0uktJC7DhLVSfY1U5CTkwdKAQ1 gQfGjKz75/y60xxMUb8fqT98Z6ju/U+BgfDBcogpj9WoOMTZJAxl6JEL4dcpolQa1lRvx08j scei1vOpYbd4iAeKkD0BuuGjsY7OxAMFEl7Ze+kcsyWp2dpLIe68DbXMMbyKrrQyI4IrUXMA 9S4bCGA9Il8jOdDFTkaV0sQW9DqDdMZREzDMBMvMJHYwny2N6iyPlyvvZZ3wJYRgTNbAF2Nd RY2QG8ElVB9ObRfd1wrNBOTE2QSphddrgJOqIUjzt3FonBxHqO3DoU5davuudN+Iijhjgdc7 HaTUe4Jp6/t+S1737hFClT7wvHx08scl61n61VMFoJugdcHu1/zSDhG4xhAKTKuNETxTtB4Z ZhAQkyQO4ZWkSoCtEgS8yuTL0fUI24TcmO6y8N1aZmFb7TFbXDSk+Y+IVdS0IjwNKtA6ivRT bGFB7hm48E9hQyDAMntXmx79vhTlZWhrEdjgR2xx8MV2UqOKoQBRsmCCCKLJKjtKcd9L7xFg wuXjCnLxXESaJDLTp6eEySPWupYRqo3Xbi5s0tOXPdsgyLA1jw2it3AJBcOxFDLqEgX5qr4O YleUVWK+TDj8Hi3x0thi9Mx7Qir8sGfny/DjIrVFms+y5dKOgcCnZhyRjC4s5tKKo9aSE5AK hmRKA999628e8si/pYSt5VLdutFDhCiZ+fKJNS2Qq2q45I8auRcNqpZ9TEp4zzhR3LphyW5q oPevghMUmTTuaU5ux4YwP8RXCxuNsvDRTG9cTTZKx6jYS96Feb7sGJOqu9ELWDrMvCMTGouD EdsR5BAphu2Am5I3T5vHk/RNbs5EA/U1gacEKopnnESkNOdyqM7BM8Y3ev0qhSjgtZgGvslX zFklK12iNEzhwBR8F0+RQSoKR1a6marhW70mrqzqt+7OXOZFxYt3yhagX5PsEk3MTKk4iSNV IUTQVz56NuG6maAphxX0ldQ4G/IPruFqZHY+Id7MshqYVVRIqcGrpNJIqHYuh/H4WL4xZLrt yWWQKsdYOeVC+FeeLlMgZYmc9Fs4c09s30y1Cp4BY9UeaUptW/aRqgume81y3iiyI9phfyqd KAiYV/akZ7CAfLMic8YuOXV7Gg8rLxT4x8qnv1GkpiznDfXUIkvCc72UtcSU6Bo6KGUOqD+X E92Yf+EzNk3tWHnU8EOVINT/gR7RhREWzu9ITpmNcRmjo5fu0tCK6ZAT5GWtzcCXe6tid2iP erhDdbQ3dlATcuYUQLUuC1CMnGDTcXY3qGles/xYFcnyxkpKlN29HNAnF5Evqn74h8GgS5kQ RtzaIuE7vB2Lo7TozP7s9isKGMMRipGS0iNsl1pU1WFRRh9uABpnNlqWMp2gnp0t6qnVGURW qfEws2psyQ5Mu3nEX9+Elk4u0M6XRA3PI4RySEMEzHRjtgaGT0S2oQWWCOUJ7e5LfytcCBDI y33HVhm3Ga4BUoVgLbdk/+ngzRpEm8TPl9ePn+vS7tkspcctCE6YqS0MNtPUW7WuTxEAhAaP KhZi0BP9p+a8J/sU0G9k/cSlyWF//fB5LDvGasYPbZR7u6ixuNFiVse7MEMYVlyRT4NJFBlc AvZ7XN7ZDQeGiLRh0HkhnHaQiu1OM+vAbtLpVOWMCjA08SzLeQEYXAjKBbWMTw+dHjK9eW3r D7gm6BvV7AfWR2FedOdidZLmPwezXyBwQEA2gRyq8bgd26zdjdFSCicLZAWmIovsix/ZUH2A I2Upl4Y/pqEqU6Z4RSSBgfEGmzHTynFfLJhEfVuS0AxsP5wGNzn+wqsagNxseZwQVw7NCcev z2lwtEtE76pdPUiWGqMdh0lL3CNLJhTG/RFLulV3uBQ1eiIayy3w/3fao7Kp+f5eNzs/h8CY rEYMqTEhrgGC/U+O2tg40OIDLoqWZwRoYYBUszMh1FZTTh1aKtTFUEh1Q+ktdfPBAiksY3LE fEZ1Tvy7REntl4Hx9SOUTjoMtj0iBURzcUIaVhOPSxqLaNhX7mv97yhGEuYZHVt/ntlyLSY0 3WUq71Ipe1e2hBTM+YvyeQbJg1bbpoXT1i4bXnSMqXOzUpCSSKtbU1wgL8+L35EHqsnRATML 8g4jQVyohLz8GYRE2QNoWmJr5xlm+TrN9oh5stfd7w4a44wbPZCE5YlybftJPGHzE88WI5RY d1IDSmLh26pDCxvtEmy94UACAkekiBD0jyptRgYyPNnLez5jhIXnukJ6FtI/UdIksV8OmBzK eHIJCZRq/boGUJ0nlUqVLATfVXmiFNmyJHnGcBwV+Wc7ELNYNAhxzQyaEpNrKdXE5tGLe0G0 94A5JisM9OGaFZqxHj8sfpS2pxdGEVl8tVT5MlN3t2SE+dBgPMGmPOPKQBmUGqPRTLTW+I2I t1IwXBFzTCKuDJ5+ugjOzhqyZjH5o7rhgCRlTYJXvr8cfbx12ZPbi/Q4qPhpsmBuGBahWbGD LhfuqvZrCKqrCSF9Lg6m4SePsC2kaXx5o0jGXfZT5Mp5erlH4yef18tGE/n8PjkreEzBr8Kv GPy3jBiMmcTu8ysR8cNRArzDsxY/YJ3tajsUFVW18mPUAQ46hBeYxm6wxLqBPCNwY/iSYsdI dVB0ZyLGn9DoTJX47PwPrSxb24+mbusrfAqGlC+bqsDYIkdNCY3yUeyLy69S6p1NiFYluIaC +FBANknuOZat+8Yiw5Wjojc8DQZgIAlz7P43IwfKsG1Obn5hAp1XpkCtWHPVGngzDwz3MsVn fsnHJ+hLTA9HWs6twhd4IVzPyO2z3ycUb+EA5L5xOFU09RgFhJTGV7Zun4hn3Xzy5gHoGWr8 Twd8immB9JH+fbUgXOkLsy7wmq6ReUtBTo5X05xFucz0M2NYnW4bANZoJ1uf1o0lkq/0BlpE +9hLIDasGrJ0EBeYtjxWvsg2swmnWcE0NzM/CE9qeXpP55kTsrMGhZXjK6WQRdNF8DOSzVRH FsPj3whWkt+BaQjSOJsJKRssVv/DW6smqesp/O8azF9Fexg6Mu0uO6ekyj9/Zpu5pjOB8Twa ZRbQJYE3pQ8vZEMSGN25YsDnZd454BmS9fJRHS6RU9YAI08AlEA5DC7VR1aq/ItyMI9yKiRS ImDxyOyHI2cFRkZvJ8PA2DWZhm8D8Sj1nyqyC78fwDkGRxjqoC0ohO7cpPcQr7AuxAC7+9nk CLPczmx0KDoZ0VANmXu7DYjTi0V+hPQrBpBdDDVdT3u9tTSDrmmFOWAzzwwrnmdV4o1St0mu 9SNV+GzqO1FhKJ266CopCps6UBKKRYYhu39q/QSjTiNkj8rbCnRpVQ3dknCxGcag+LQ6vNni V/0IicvA8XEqZa16LI2PaodgBh1RM3Jh5MOaGH+V2DkFne7pvxbu6T8t4Gu0zvXaGznqVtJM TFCEuzRGY/iMaWL+mlut2l+12nDtEgKgLUOjrUgf/g46K6QVs2LpDKLMnaBPT/3bzLHfjZec eKXrrROAS2uNBO2deUCcv3NglcjQ4mTPArhq1Op3DA0lHdRGCjejVhUr3Ltld6Jyb4WoVL3U BM3UgPllbO/Z5YS11gIv/jvRzeiq8nIbTeVAPOAY8CR0FyJnFpjI7Q23oEV/HMssJtAz2yQ3 knHEg9Ewq18DHZr1SpY8Ohjce6VmJqqemPc8J+joL5pgdvrUzvYBUoZE0/Ol8Wc/nI/YiIz2 6ywMomo5Z2Iz66Wt9RhKqGR90DGJShyhao/XA6qHKgm1FL7zWYpgtWwoYCsB0kKf4a8JWxqf 377pXB9MYw4bBTWjEueOmLnG+YjsY01ucrEOSbnZDLoxO3VCUIFN73OE1I2Ht1nBy7SG8ne0 BSCegAjGlMwyvykM2uTWWsYihTl9RjNa6X0TMwUcmzJeZ7TBXMnWNfYgo/TfqjUBpHWaOnIg uWcJOQqEkoncgiTs4Cg97IGejUEsf78EzRv45QPcCMV3/uoTUTvtiT9ykSZQyy7Mju+FLRpc C90F0j3j/DQOKDmQtPDTeNdClymCm3FVqU4r4gb/0SUotJePWzvhWiHD55YsTK1i67zRn3KD W4CNhd57jynSavLhvh7iW+DvTAAf109Hb5UOIdhaEflWfbg7CF5Z+CKaWzMUhMW1PVEOyiCO vLC23s5pJmNDeDqR7tRKUB9ksYD5eLlARiVE0BxkLwmsrLTP78oCaDZQcuy06gKprZBc5RWA JVA7W3Hti7qe6TD+9pjz5xskue5ykxt6fUOXv+QvA2mSUWmyWaky09uJYIZMKt4IMv0XDaZL D9a3rYFy3lAJbqAaeRZIeM5PLa2BmVC7k3K+uVDm2ic8Bh1hnYE0ozWeVJJThsjG/tQ8oRzo xN6awTvdfHqT0ywUvv6OX0VqQiDF79qH7vNSxjblZk9iuXOkEqpcNX/h0PXkiRSC+RECBBcl 5JCVU44qICL/NIo5lYlCPsq2gTVOFb8QopEIahyEawePvB1o1S5+jiq5ElXc0P/czyC5Vvj4 zjQa+WXNM+OpWlM/FXCtbXAkF39hN6xGlp/RK6p1gizo6QU9ooUYentZMviFT3/MxnXv/Wfo +kv/U7zgoJvvqK/cCMgc+8VaWx4ugBtcjrt/vh4Tsh36/ul/0UQFb1HABamgUmvvnLPMBupd YhvGzdlP1lgWnCdwvGBr0KUn0OOhyRDm1PzBQklcyA5Gr9z5jXoqpiaa/E/WtS0ZnaPKBVeO plRlDT7WzVkMemRT65yjFBgc8xxm03A6dABXe23IL2smcKcqoQqszkCTW6A1EQSR6BWyMaUF fgRst9DKKuKSzZ3YIxr2k3j6eLCwPyVJWXxAOHj6RB/5uR+dNIX30tmoI0FWoZxgjjDJHLgF xNypAmjMICaXW5qUWo7zacZCxB4W855LlI27BDZ0dRKSjg8qfvZImTUTVZUiV1bLkic1i+sP FQleDPqudyNFiE/4jNGFMqVYFzxm8ltvWFSmiPb4tXGP08q40Tvoe6Vc1HDLB9BFpILbs8gQ PwSxvkFsaZ2FDVfwZ3XikRk8WlLMvyG7/pCx9EYI9L96t4OATw7B2Ei0MQxjygoI02fWIWVX 06VlMFHkyj4WFpsgNAunll+fyBU0vzqM9yzkbh5pxOSkJc42to5C32cG3I+WZc77uyL+9LkA jSZT8keGtMEzm7P0zIsjIy6LBFaUYi9d5iGtkDHnC5bURGzCbzsoWIOG/0jZtRfSOAJZ3jRL Oqo+3aQmRs0AQDP5BglrSeIk0FhLHzPwrSC9kYlSg8z5wbvTZhQ1Flrxrw6Qmdi1n7miHCkD op3F0LMlYHSuBY5GBwYx31sCar9xWrqPF8IHJW9h8AOEc06cxYm1DrygpTZHD+7vc61KU1ic iwEgGrMEeyGenHZmTD7pW/w7cMB78+C9Mq+5+WeIYiPYr/moDKZwjFCJF+gcCfy8UypRgCPv CuWvbsdtGDuKYk3mCkHd+xSS+CRz9eG36+5H4lCecb3N7G99lErIMCtGuQ9w05ZQmanAkYO1 nt2wP88UemWzCn392XeOkIzSI9/TDmxFe27nyNvqw2hKjSg28RnpZ6xHqlYI3pehkJLq7cJD H7PgtTAt/779mE4nobruP38RVdMPkhUNgTWumMIFnzSN9HTezn3XBx6BxghkJsjiptV1uRg5 ra72h788Erkr3mqKegbOg+FCX+Tlm6EU0O6PWizXB4UD4BXDkzRDO7Vw4F4wM3aUE+j5yZmN 8XgxMNYcWBOtH7X8cK9OjiTrVMeikY4OejaLk87R7z2F86gWmT8fjEgyHTwAviaLt/CBK/6N /dmZT8Zc4uVCF4LjUbVMQwf+l8EuFZytAmJDNaJo+qitQHZlrZV68+lB4CKZphMJUGNPHCwg eignoJTtdcZHQlUm6xAOzsXTYEzrEIFrmgGHmbPJzblAcIu2Ft4Ddy1GP9nM+Y51KYr/glmO hzPVG1ZRWWLcsyiIblcsu/DhIt21Ak/DpfLb8rY4iD5mZQ12vsD0WbWFj85qkzKt8gYTGhxb W1g4sFg5swlcInzFHbWe5PT0BnMWsZjGFfSkftLFrMEyr8TwhKHKyFsCZNWdz7F+oDIrLN3w z4Rlq17iIbryM+p4gO7frr77fKV6D2ty5ms2nKUf0DtV5RECQ2jE5xMIL+KMQz6WEXe2oE8e Y/19ed3NDD2HMsagsLIgEIEqzRGHP3TIqfabfKATnjT2ojZPGXZWewK0OOwX2ezFyC5GmFRl cCxPmLv9QiGs2cJPBIy+JNwiLdMa5/SrRK6Jf3wEaW4xspBJoLccTuXRoTNAw5wLheOMYdTi 7OKUt5LZbkQkUJRVkqKIQrMWW1o9RWCgR0JxZ7aHL0Us2PpIw++ylqO5ce3pUdcmMvZZw+L3 fvT5TAFKcp9yo57jTtvPFUBeiVaNABfKToYK4hoosQD5539dgYwkfjr/YSJskjCxw46Ld8/h 1U2BS3FSVxtNk7uSieNOKd+lP2hJeIBO3pPYcQwog1cy81s1AHx9eVcMoH3/B2TAG/v8p7OC jduQvVyYn0pcOnrXHh7gCgPcV8Cmw3YkHAvqdlNCZf/2UmLKDBHLAACpMjeeG3LST5er91L4 xIo/3sP0gj4CB5vDRb6ls0bHh19T3oWb4Gk/sDZtf9FhpD/vWpMWP9Sb2OQhbkYzNVw17+LX ryXLnNKSz7Xf5WbbjRsMaf2kDu6pg1w7YW4GyE1wDyqzqdefD+Gr1YTmO72bkltGBhwmO+oQ R9PikG8p45PhXdqZdg/YOnxvPmstsFOSekDpK3yAvPg57095jKkltxx7XYtIGpuQW4gfBPR3 jpAon5cwU1j7JFohxMTnzkam0wu62JQQ5uGLLQPih4a1u7448d9gxZWEc14C5C0VBUM2Q/Y3 HRUoAa8Thw7EFllMQyg5P+4j4cvnZiuF0SQnhmocklsWLgWmzp7Cty/jsrQ/3FrZqLXZmrzt +rJ8SdyhhlW5r7nXkcGh2mFgLBEamy12h4NLHuJyZrw8FEadVQ/tMVIVVTFFtDCtuUpxN90C 2Ukk53OHXY32NtElfsNfvsSkl7GEuJNXagrfKHZs1PTnlWN1Kk31qROmImyPxAMp6VeX9Xfp 43B0HwfbPeUCEdUF3E4J5AiaJYrdvRFpN7JUYUSiddoWTA2+fQmmQ9BCqbjG/hNVmRoiF6sd kT9jEcURP/0tSkwsPqsSi6IIAZaCGTJBXXHDxUv7b8lKMCe9s0QcWlRs3KWaQTt3V95z4oBc UFU50Qsw8AZbXQvWQ044AyO23BupNrzpjm+zz5AU3DC61xtTJWDIY8lLPJFUJ2Cnvseo2drR Ln5x1PviKmOwy3MboFXqOyxOiXIkrdgWQCN88CajOxu7KO3/jYjvTVnSXMexOqYVflQ8cvig bppQV3jldSxeH2OzyhhtJgbuK+b3N9vfjTkxvkQ+kE5qrQ0phLa40wPvKa2SVpSIibzZP4Fj N2JlscCMq27UwflDmkQQ4ImB19KpysVDUhqLA+TO5/I9qqKuiAvZxHCmSwNJk6dPrvJ7usEb /2q8bF4NVJEEda1VYlgpJqvDq0d6o2EojaSvXR9w4QZRWXuMFfcR3wlOKkCBZTnvfZuSoofR y7Bk0Zg8mMkQYKKVMJrbRRf2IepFrEE3qL7R90Ze31jPfoo4IRAHFuaXUMnxVceCpw1Zqije xsUdPKH8fqjudB//QAQlbm4O6spZExI+6QJetQz1KcNlJ6slxt9Y5T6/ev+RWNYB/iw34Q7X Pw69TPxSWZVPQN2rlCkJqL8zlAMQ16ZBwf0kRtPNI/wljvJ+emqFz0X85M/DjA9Sfg1mE/la TdNikHBWFMJ9B41sjrPXZT/XG7QzFw16MysQOVcY/TyN4hbJaxWu4C/FAGbpvgDKBeMGgBGx NGHdR6B4D/Zq/M2uF6JqzdqdlXgYodlvQR8HgJJo5+YSTv1YGEZSxhUq71qkyC6pOWLvut2X bwFKG6NiGTe+xKCao33mbdgutSNlUZPx3AiVfMtHuMpm5XlGBVHYpdXrsXGcrC8l4QYWFAdq hIp8fZotODsbsgIUgHpgsyDiJ7JL5hysD8LbIa0zRxic7dIVNe9cNRPMqmFvLO1NGa+7w8O9 097/R+aHIJ9ASLIepj67zR50X+pFMmdrVCqcRaIZEd7KN/7NMNkGvQ2zy1KSyukV3saV/KLW wB3G5G5iCzaiYMsN4Qv6wsFh6yc3+ZWUHYnEJBsblMWsSYEJIELtjOOV2MuWpvGs8UbqXVlp xsyBzumljeMFfDY6GFEPxxY0DisCS1gJIODKg1bb3fUqet0OWKGcgVTXPzZ9b5V2+8zn5GzB 7bD24yIBBQhQZcfT8k/WIcdgQZ1sEzZxj1NGlv+AIx9xvQGqrj4gfrtc/qFAEOxgPc6YSMLj nXKmmF+8hMeMWLF4vnHtGebyEZEayIcXidyqfwPWnhdKg63eSLiownBApmL1ksDPkL6uZ4/6 pcGLPPPn9K19abBrOxgOTu3yY1d7DcBd/XQrBj9FCr9BL/C2S5dP9L8I8l3d1rCHn35QMtUh XwaAaa8OjVgIaofbUIiLfatcXpKAi+qEoxwYZJLeZhX/l82awXMJOn9Xat9LxSEuvsyjPHgM ipGUe49AsW5Ti3gstL6877FWaofJx7FOgp6G1p7QrqyGofyxj7Im9mpMS6f2wwfwZ61q/PFQ mpJtWHJnZbOVE3OHPG2xTxL+Id+t+tFzOMrPoMC46fjUAJLE+JtgHS/lEqaRAbw8IhdfzfY+ ZmExWanUOc21LqMgueLah2ydhjw74aMHQOJYumzf5z6v5PB3TE09hzisjpG5ye/RZ1wDyO4B VR2AD8kpJGFYxTf6/9WnVd9tQ7EN3mOR2VzTAQ0w9tYomajeQsTuQ83YBqyPpssQocl0/Iwx dY+PrQMqV/zFXz2PismUeahzIGk7XDZzPkLfAC9Wp6fMP6kv2zVJV10OyRhjvVe9p+JwYXjL jm1lhqaLBu0X0LCkXNTGNc9BkdPqN8q3Z9v+lSx3HxTtemH8MQQPt92h80fIK4KleYI4ub38 ipfkSFhlNw+Tm1G0db8hZaMdidmZtWQevKcwGjUVWzjqrY1qGmp5we+ikN1WKrKSqgnQOeQv IPZCzJgDtvHLwkc2NZ+Q/USdqFbu8T1dBenbur4IGlrKY2A/G5kdgOKAuemw6p6TDimgyR6b v6gvo4Q5tOpwSfqPlWDeyBnFsMfgHAHWYkgWwddOsq+6rforfPAvkteoIO+SyzcZowFPY4ZQ q98yadqEoSPPOWpJTXNF3+AQBgeN4Bbv1nlgI1WXJmYrXWktExPwfWmRRa8zBJZAquueKPUK U4L4Gh/DyVddIJ/PCXErWNrOzAyNftnrwtldbrm84vA9fm20zcNEhgAriagj648/CABzDRhS F0nKaXO5VCHfxyF07X/z3wODWPETf5hk7vjyC5xEG3RNuhRvruCfV/kLySbS01SeG9yGx+d4 ASSCgd1cWYWyMa5oIb/gl1AlD5lXZse4Ral/N0dhaP9WKlLNr8wVJmXsk6FnpXmx3/H172zQ nxa+turWumtPZiQF+207d6vlEzwg+aYvY090MC71lr4QEd+h9zL6NRVqCWSMk2yWyTfwaY79 VV+ZtyfkvpFY7fFL9OOT1cN0T63vgmtEtCYcYFh+EcmjOt68NqSzOd04RcrDBXP4bxtgbkKk YDow0ugaaF4WVQiYqr9n7+7bVMweEhFNH0w6PPW2E91O4Ani1lFl1Dwe8Bn/nXktuPTpzJmk BAB7/RggiRHFmt7ybLCesLp4o2S/zR7r5hyTrhSuGAGweBNonpTW/rLlOdy3EiPGIElKXtu8 0GnhCo9FMbE21EArjuX2sHgfjaCv9fcNPnliMObM1dqamNFuyO5hJSw/Ac0oAKwD6whOpkWi 0iouCOqTuxNdUC5fwHbepijuzObQD5xrPj5c6vr/TsUxvNQpsRrTwlFAe54hmrhkKAKyw77b SEYv438hNqbYBF++eq6BqODSIsm03VoyTHBWlIqFN+j6tjH/b6cnhntliUzvNN+AHbEMD9ha TyUp73ImcgYvvY3M/kcpCS2dqpRQq7OKBI4v1dti8AGiuBkDBjLANt4zbN1TkC7rKdX5Ubj1 dF7NU472bDv/Th1zzpy+Sl2QE9Ku/ym7vz4tRYsEmZadHOmjHv6+aqhrAlIPBrtMLKsDtKin cINbFPEFapoTDQN7Dx25wfQ3tFsq+r4Z4+fotKzq0zsSbCdp9HtgRkOusu2XJvXOKBC9Dtl8 XwcEzGknFMWFIpMgCwuqFBzWbSjTWZgWl9u79o3sBrH110pZA7EqQT1Bnf2e7Y7fDpcM4V1L LLMRu+rtZi7sO39zo/7bXvZhaD+XGYPdd7hVaiprYi7386AvFlTI4gWBcx4KsOdn/upRFgxt uhjwIZnqWJvJpdVC7dnpNC092PICENelC2yA7Z4zE3BB4M7Y0KRomO1UZktfPlhQi5uivYEb 1zwBsvV5bAZ1/k3rQ7FkNG9qfN0wVlQ2MmsvlH1Z7UEhfQvuTY2pDSA71RwrlteMRIOJ0PCf CLCCuaIWz06xI5xtAcbFdKymWz6do6FKMtmOYtorT/RQ0nEoTqW5B/Y/O2keFezOUrSfdy9V Pxx/SaWW1OUwYwh1ePr0BE2tJdVEyA6JuKVd0ydWFJHPml+xf8/7zGloJelyD8PYr7s8TdJw VsYHhtFXl4LUNS+0VYrumWGvWvnXw6+qUaaT5N6dmgPOVr4Kh12DV/nIB7TaCoqI6QE52IOX rk69AUlu3jATj15FGzvO0vmh68k+8MgORItGLh3b/sTo5OXqC+kDIE1OtbgeBqByjgPtJJkl mOWYucd7p3rPI0R4ZfSuPRkwrrGTgOA33KQ7lIpk4g9zvdT6N/MKGqR+UuQOkHUMeuiB9rdz Wl7Zppvf+x0kGmCONOQ5cT8slrzTV/qwjpmJte87WKuWHuvt07foE6ypXDNA8wNkDihrA17+ 61gYBa18/yU8WZUeS7fzAMYAlVIHiBJmrxtkKxDng1Thjh5T9Lufd+xvgjFRpwSgNBu6imNg hcK/lmR6WT6oeKYpK5ZHyzaWHzPkVW1pvwDGe++wl95N2tS0VxA8jRWtvo09y5PTFdOBpZNy F5UcfYYuvlMjdw6Wt6c7bQBuD0DNJYUvX6ORmj78QgKBaPCvofW27v6yTZrQMam9WOgk10SY pHtQUw3SGgbAIEsDlzefn1XP5n88kbY7Bs9Pxg0Huvz9GR4P/xOa3oVHhGp6VjLVjpna4YoS dUEhTXcKHUEs9KuRVSjKHLJRzlXHfi6jT+IdVp31zN4PehXyWEOhEu4pBYzmLGQtUunkJaKE qVUyRN3/OrmZSuydSJ/dq6NORzLq6FKmY6+GFEyl4cajBhJO8N3qUs8LhSGcNP2QE/nHVHnE BWOfQO0r3kMOtP4m6C9CBQAKg4VjVj7CTm1Md4E1R1Z4eDf+VSiJArzu0dRxjI0VNHWuC7s4 5vGkI9PJ/8t4OQBukT2h1OCzx+3LPwwLoFI4W4zjPyydO7L41di5m4AAdg9NmzWBwwuVIY0Q vSVaHGes7B14So5D+8a3kha3kDwQZFN9S9cmbViT55p/LLWNdas37tzDxxkPz2QdrHcXeeVR QOfFM0KWLUj4kJ7ppFnklWXP68ldr7bBPy2VcOxVnGMhiKOAjiwIaEPWXh1QSuTaWik4LDYf GnYo5Xa+3z27Zw39vm6NutQ//PlodAX4G477h/biJXBnulOQiErWzZ6j0H3rDDNiTCSwD/dt uI6T58TbmlumsNn3FwfiWliF8A/pXx5KV+cSjjkOQH+cD8+I2cNbrwjhVP5NkOimjVzjeAbJ WVvB/USd5KULj8/1VO5FG70IFGaLzJfeFTSlg+LK4rzU71vvlu2OFTPzvQ+fstbk2Dls3/CZ P3tXPeo3dM/wUwFQ7Buu09aJk0zeupodjVA1d1c8m0oho5SqlSRqhDn0SVfonBVex6TmxDZ/ 2acmS7eYXbWrl26r5Jblk5uOJyPUo79ALI2r03ryrFkRUFCU3KxfVGRa04g2eV8gLfi5kSkA /Xwo/Epimexmei0YGYZiAJU0ehWqgjTV9q0z1UygpuRnb2AF7eJmQcGWnhnkd1Fmb5mgkaMX DFzhoLEgNpeizWohmvR0eCkELNc8cMEjhYm9Kwx5CVG0zk71veKQ2koPeKhCUSjdkG+LJU31 mkcz8E3SQhol09k8Y6qJ2wQC/pppqFGt7idvArA2hGsNGywXjbWKaProYnoOK5f8B8dL9XL/ +pSamGaDzxUDz0TQIeAinBqIC5Bz3SBZ8SbmeVPPoxTp3NHygp16+W8+z+seCBa78QSM7Ebq TUn4AQrqBqdzwE/b9MTUhJJoHOtu6yiZsUkHwscYAwreeLtFPzf21FAcVrMGwJCl11BvF6HC eHK0I/w4QxravQ7G2zxq5G4XKU/YZU5NzB1YIq4N/9yi0D78w0lAQmkRSV2xgrPfckFpZiRk Jozv5CqezFL7FEzlhKSZr2BifEzWAeJxFO15iyH/lwYMVoGEXXiVaS6YQWhg3sW3+38RHMF3 XAjL47yrth4QRDde7F+BuFEDyQGXs4QGkS3v9xjTXiQFpalEJFemoCSbrfhbly6fq5KIw6hC Wfgroiz+KlqP/yfPm68d3WDWPW8UWRQfAvSbo1BA6ExugoZFWzH9RoxnPJs2se57RyYQ+HVx 3BKE3WiQgqAJ9RLAo0OaYBtyWaCUfHJGOZ8Xc03pUJXgDVY6PQe2PY3pEU+VjZ/HiAKDdKqj MaNMdFncJvLOsSanwXTFG896ejUnsKA8VXWN1NoDFZ1KVSZlKuKVoCSjJ4n63ZCeSuDftnQv y0OG/7Xu+KC6KNetcUyntNcYg9R5X5VZcItMkwAbr7Z96tU/yZmX6oU8RBEiyMBHPSjPdC1z RIs5dOZoHaEVT2uWoVAfbpU4WbC8VIDb2/HxAQfG9xsmqdrWS28fhIvcmTzi46QzUAp6mh8G zY70xrxRss6iqtyKh5tvu5+oslW2+/4QQ/C9SBdwnfdAm+HqqotJiQ8yPlRQySu87bEGR1em wMX/duV4BB00HEW1pzcVAPu89Te87PnVkZQz/c5BocEq+6+Q1Rujg1wKxK7DoNz9ownTXCwH VKoNnlYDOpn+Pr5+kDvpMe+4hNB1ZSvkPs8DmcVKw4BkzpMCJSn1jFYlXoOSRy/K4tVBuZrA 5VmbgEPHfvArp7un9JgE7mu1m/yEQ3csK1YBzAc/jYH+0SG5WBKzYDPfzcd9Okuh7fUo3uQ+ A1m3q2xDptb5eHcpDG05sF2NZ/xXWJ71A5ybfSyhufEwHgudUByRqyxf6YfBvaa5yHnx7Gew U0n5WarkOrcLjKacFMYyuh5lF0OUozA9rDnufpgyvr9GlAVWrjD3epCF4aCVg7lj2z1/w+zL 0SXtnacfujQBgh/Jw405IFTzr76CMSrNEizETTkyMq5NFsoQgFJ/YL5G7+MfPg/Q9/0+yXkN cqBuNuaKTAHZD62Qpe2jeCLjcvaVj7fWKb/vFKRnNUiCfklbb0nqUgUesyQr5PWGfOvFL7ac vyBdAX4WuBiREkz4++lhqynj3H28Ma4giWTK3QEisYMBH+TGFXdfARL4VhRwbuwhJHhvRBoM SBMM2HgYu/1oi9hLPdS5sDiBsfBTOon5Eqmm+44wNz8iwqX7whRAY+Zu7KuTYGLqR1h+q4Xy fudCsv1XoqHa2EJtXktqHGXKlbCj396NkDXckzRwx7fxd8LfVAHT5S3tkvvThaDDAXFf/0hQ NwZw4T5NJqSVeRhX0R77nr2rfcWHlnhV1F/YchjZoKynng5r2EsC//rzIh6LTKJQTpnx9BtX T6CI9Wlb7Kl12bJKHxe34uKT0lHoX56jTwz39WnMYqiWhcpWlDF9dzSILDu3Jlj3keJHnfe7 M4ek9+dtuGQtRaIQyMbmFZD1IL4Aw8C3c7959Q6qHOaCteg617qTdZEKMCqVqo2Y7y5TbugM KzTYIzBaZ20dxr/o6P0apmabFWbIC9ziE0lZpeeyOAOaYlMbImPY4XgLekvNFktOqJQbrOuR z3RGRD3/XKH9ZItIiCTH6Xjjd1Q/gqzev9j6oHGCR78BLL5WfKpHyn33jLiOBrqMT3oNPoMm OLV3TCjLQjVfDOA8+ByR5MAiHYjrFtZFjMnPFuMQAF/vpNVpdI8hG3BS6aUjuGbxn4APPvg4 loUNoR61KH1oElcF4XtI4pimxbBZ8CJV9c/dvtdq2wta4nf1v2mWLVoBRjAI45R8AwDVpZSl Wrk6WeAhMibcLPSG6qfSv9eE0ZFWvrlsirGo2yQcsX+zjj7AeHK9Bik3nZDXKQjemHIXQWsp VlOEzns8eAmJg1eUhJh9HgONwzDujqZfdcTbIgiWcKpgY+0duhhfu0GCYZnaL0+IW68+1uuW l18dobe3mUPW/6rEZ8K6EmIGLaQerdZoEjCyUu6vgpG0Ya+nTc2Fj4h61iCosvnU+V+7Rw/6 8VvuiUbtudED6QVfcMw1ypfLrzuJt0gbEejbVbkRfUZOIHHAYaJxqArZPg7bM1QDBVOLYHvD GUbZN6TtfGOjGYt9TLxfoffyoFbjCWlKve4Rtj2fIGgDvxR/xPn7nCvaXfIfy+Oa1ICZUXv6 SHxCp+YcTJdMFjmcQzUXDWFmNiRkAwjLUr44OCeh8X5qwo/3T3uaWXi7hhOGIBJLqNZIwACu 7UihvxBxZGHE+htxF7yghYf/mErtmBeOe7lJ/V4GXRBbJwWAPWQI7PCFNHJ8vnD/iJmxhxFI T+UbrgHphPvvb1sgUWKDuTFq9oYXvVr7YlYfseLgier0pBtf0/HH4+EniF4ehCU/M58BM+HI H2S1G17xuh8f3oD+4zG27wKrn4HxjQ0bJe0hAOP/W0iwQ8apP3Rudw3CMUQdqQquOwRDeYLR F2f8zT05xy+VLsBy4wuppqGbdkRq0CDUFAUP1hNUpDFTSIqs9a0RMNyqqhP2bn2ffMkrHQld 1Hh2QKCGFqmtg0V7GP++1RCVSqa3rA+l9LaJU8eUsyInaKF2la0nPtKvAjTJB76E+iIECJZW sGuupqftFplCEngFDBNAFdWiVawf5OojN3tsoRWB+h+rkUvdn7OE+ZVmh2mjhv/RtkA9mYOA 5nuaiShPF8wY/+/ZqfYJ2Ya/FLcx5OkoLNcPp2q0lxlW8Hof+88KozXrQ6tpoCBG0aoSr2R6 O8kZD1DGmkNxiKtEOyGoHeJu94hAHvBbKtUu0oWk9tUcNjW/JgstrDGimaGTe/nD6cpxwWR8 IYjbJPYhXLVTcPV6Tghraeoi1drYkgSLZodn2Q1DWYB0efGVomwiybFKyRHhHinAThMK28Ux ioWk/NMw/abcJPQ+VmOLtVBY/TXGf/HKtGQzpzxow3DxAINyAS3x6P18qJ5ilO1H5r+QJq6+ GdyBFKjExBLKagiKPcMX5b54pZtQrdt+m9cophxPntV6Kddh/P5CwWdNPKtsZaOTr3ryh2r5 WtvYHVMNPoOAP6tXKDRR9DzQFev4sVWqF2kY9HRfL+WOlSpvaxLIXkzHqx5qaxior0NGKzY2 RlqZtcLqOiX6vxoNwFNRuW7Nm8r6LyN4W2dlO2Tk9qsPVyZ7kDW+AfdgjlwIU9LXARzknGhR LDvmw/yO8qChn9QcEUtcvxRUCln1l07rC/AOgcM7CcG9pObp9IYFMaJ9TEhOLDoSta4FngEk V0urG92Txlby2S8iLQ7rXtW+tjE27DEAyjPaC16WJZRSgrzflmqUuF5cBaloFeBIUks+ZP04 EVA2EsbrFME8i2u1ryGk3DUkwsOu1cUHlO5cNQPNAMt9LwhF4W1FT8n8P//8MwfikeefCH28 XsBp3T8T77J2L1lNJ6xk1lquH91M2Yb+ZtWqS0K26jpBR7E8nNS5wFSFvMpl9qNLsPisA2lz V5xzbMBsvXj3yMANYNBD4Db8Q+PjmN7qfJ4YkRqTpe69agrucGL64nxQtjR9vvE7u7iEbYTF tNyJgbNpaTki8E1R4ory5baWoNAP1fX4fMJrVOqL99Fb9exMbmP/0RWvQRFeejEqhJckH6dA yvvuBGMD2smMtAcxvAVLdnE/lts2C8qnzqRxXHOE2pOHddlz4BRkgTyPenUb/5zUjhy+mw0h dVrVDvPL+xsQrdLFluzYmqob3nlnQ6Ds/+ndmA6NMxOs3aA7b/SPqMM0VZQEJVRhRKgwNoPM zsN9aNNk1/OFEJQBIuMcpQJLY+oIMSBTEu8Db37rS4x9GXA1o9KanEAsHeWL0j3q8bXLFjaT JHTMF+WRmv8i/0zlvRTjJ0BvXZnM4coFYXTaUohuymVVlZE03bEN2HfMJktWgDocSegpjLOc X0sthVH6VpUt8SocyhnxU2g7SF2nXJ686+I6YIvmYxbHb2IwIhniCYheQPLjXpfkm9AzO9ZQ ciftaq5MwyZkmJpA90/DL1/QateG7XFSKZn6zJGbK49pC0CfdxGBaw1zNnPn/nTGMJO2UGd0 Vrf90BGUnurMNcwDDCuVn8Ty+StnNzy+g0ZX2iRMLj3n0vfwXTkCENMH5MJt1n+5UpuIYlpC k0bwXuhGT0IDN8yukzk3Xmyp/Azc+hZn6ml6gsW186uNA/17FLqhFTDhvaZQ5DcfbILJkvje g0OnjP3Fd/wk3zPAbxxDefYPBNKGmVgkaHYK5HLNG+xIyMO0MDRtsc1qjpky5c5gmXLK8/0M DjchIPMDRsg+kGFPHOqFe5e/qStGbZiNAbY7pLV2TZeQ48TY3kucETuXvZPy7WHchzBMW1ft yPiO3luQ2ZiEY/pCiGDwt+smjgm3zBN6cCWYbEuaoBgjpFYs3LuDl/18Fc2MRtewFhwxdi4m vM+Yin8cjrMPEFtcoskf1PJTEHm7+XtVPgPjTfe9/ucHfHwdeEoemoPKge+bX0LmOZMRPowq Wfb31lVZw5pb1ZWghs5pDnbGgV9McGIDgupl+u+Jiqk8XGcEILOs1Dd8a6xNV/XyjnfJKhgd jaV3gZ9E+mxTYCpd1fCGG+se7pnwGqcypTtLevZiS9HotccUDy7Nev2hnY80OAgvVGjGf6dS YZvU+jEOYud7AXUIYpiRgo/0ATntfIiMpYA1KrO2q49tseYZjgA75DL2kgKEEoHmVbxsOzi0 w47UINT2uam3NsUOvgRRb/4RMsi/I3i1/+Nnu27QOo/SAEfi/rQtNjj+SM5Cwkne/UpdHC4p EnKcj7rm0D7K7NyNlF7FfOQBCj4gbaHdCQSpgsmcu7hhOdjoZGv3EVN0fwLr3OV22x61w7hi LMTcrKOItRpbOA5jrAn+oqrs0lR7VYy3XFEk1oKyEC1UyY10GRp4FRhRy//+0x+7jIB91ABK Ai49Unx2l6EeewgoQgfp+yUZfAwrt96peLARFaIZq1YHBowzB/TZgyCyhoJvj3M+G6IB+h8T Md7gX2/5VAMEk7Q0Ucn7cFCfEb8YPXO5hrUUKEzhiNJUZ818LtzuEWoJARsMyxBPZTEcMaMq y5BTrjAKT63ezRsyfgLPnIjh5dd4ULSpSXOgpZI7gCYIKnbqsnRefWFRwEU4qtxSuU2FxWg5 wm/N7xdidOD/1URTa6RksLc3ma+nyr/SEd1UGykRrO8hsKICZadkXXidjZno4TcCGy+BE6ld EBt5khjJ8gb3rd1EBs/8kPGUOMfmzuFrRpkIb3t8sKSDo6dwj7YfCEv4Nzk/daKKkxY9JYtJ aVqk2AQPULtRsWxCnh6m43K8XI2FziCooI9ihgbDe9sByMS1a5r5l19OgYpbUR1rq7tKFVA3 XcDzMP3Fl/JJoyTRdw3DcKhDhbuiATg9x91vmoSj0TeQOW2j9LzvRvTlBX1pgmdsGGSMkpq0 HEKLHuuBh4W1+mIOxEhI87/0wwU628umZomh7u30cHXUbITcjNztopVQBu5ACeRsAu39ygEM oaScGDOfS262OwsAIOpPP2EOoNOkzgUyaM/7om/62XG+3RgheLy/rlxwhoECSRBIFMoOdRo0 S7uhGy19sHaHJ/v053sB6x6zZuvDnFEm0GCsw/ji6VNMKE3N3LQtLo4+X63xnGgHnY6k6JZu rt61itnib+ViWmNKphylD4JKhx/Ou+Aok1LuMvtwbebmgeAH6SX3pKxA6+V/ihJMRSx9o62d qv8c6rP7NT8QZcLXDZFur93bgxHsXeeBEJPIGoz0dxbP/ZvkRl9Db12m17/gwBYttD42Qe2s SJFvQ0i6KkDRXnNb1KzuW0lrLEtT5LWHCTZxoS4usMCj7DvPh9gv8LaAJRUeNayd4OP2k0uL rEq+UkC2hrXHU4BpYwgjTJuYkXFocx9netWIr1MyL9vNKS1xGC2Vv3fCEZPKMjSlNVdYST/t humfA9HoxW+2iZNh+aD3bJg/uccJiZve/76j/BX4VpiGfuXQZCpYQQcufmFv1Efkza+A7IJG v67ALdoqPnXFQkz2nWyWwJM5zkvSj6jfEcWBRFmrn3dEzblNuVS0ostjOWEeEsaQNLxPW1Rx Z/qScLe5i+nFY/GSJRZ5FovEzXmYE3aqLMSpxBgbjKZhwIzo0grSfxT0C25Jc7SwZUzQfVoK VTYOLK4JvyANXIQudTSUj1qyRDjd90waX6mltIDjxhd49zsE5zXsFXRTE4kFpELSICVJGGlE Woaf5LpHgPXnZNjYIpx1MNVGQ9N/Mgyk2ZX+0zd1+WFhn4p78uVwEIBItAOnIDf8VxpUcdt2 9Iq5rtsf2AJwHSDFgDW1D4VfOTiNVTfkprdw2xpPgSdaCOsVreOBtNQyyB2XfsMt831GnTOG E7ARWFflhkz/Ci6SKdIjX970ZMXFHxPkZwRl94cmQt9CuHUzQa4JQHsQvb/noOtN7lLelNk4 A8zzQSysaq3Q0kAP4/vBQJYncw/vW9AvX+AoSssmRpuevmQDGNtKbZ2ceHgSDMMd46M+xxZH SbqsBrCA9U7yFjTOSkzw/xRXEnJLhiYeShIMwWu3ijAxqe1TyAhGCK2a284QYySE4KNIK5hO UR4wq79YTqHxwjyXlDThIfEBFYmWNRYIezjY6c1L+fVa++hLa12VvkhCUqAO5dLhF8FhBDju aK5irZ1SFVyeru51RPs3pG7zAGevRrjf2qYUkAlUU16VSfFNYrumy/GxPGU15SYO84mPoTpK USrzjGdwOrS0LuwIRBzDh8Db3xI2rGN0Oajy4iatvkFfS4e+8kV5gVmnOu4CAEtEyC8DIb6L npIUin93kCBVHgGOhN85//2vzVlrWky7hpjnse2R5nggvhRypsi7EJOkKfbhwDhHJ220Hb8t MqtC69sTymahdassTWm0SthgIZrNXPgA8SYVum8hbjYw5UUcJ9bm1l4UhJLo50FgYBJx7zhi iPanmzIp+edExTcJAVWMHX78HqfuIVweuEN2/85COWEhM4yNDfmt7mf3sAxmhn8ox3PJHLnu BR03oh4hg2XHqWwBxB0Z4qMJ+KqgW6/i/rGbR+6D7foJR9nSMdz9fZ9aGG7tTxc+IQTiN3er S8ud8m8LPVXXC0WjvKMvc3QIlMUWjVO/OuT8SHQePpfkgANxLcU7mFWnfsVhZVmfQITGqmrd pToxR0y8C7Ul1LTjcZphAaQSpwEaifGMGqGfK9IRI+c7DtZ+lMLRPNcIZHxgMoeUCM5/qads h2KNB/1hdcEhO5l0JUxtOHtxjzr069tmc1wr5T+xYtmv4xP783wuY1ZIojxtGcwrAWo8ZGlh mjBjDXz8YD8Dg56XW9uX3Q+OAav2sJ2BBfyU+wJYcYyFVi1OfofuczORqb2dIQc2EtRgo6xQ O0yg9Eh0GPKrcbtpV+KbxpHoM2yiQjYwRAaEzzkCd2SWGE9uWlzgZ+ZSsI7xQxwqdcxSG31i iqfISBNJuFlq/ULz5Se6y9CkSv816FCvXTJB1nj2nso+x7tbNy2EGMWRkC7hD9mmYu8zeH/k mHJxj+poB0AckshGJ4mH1ZZxWT/CggHgdDfSNx2njjI8DcziCdRa1Scu/do290TMDdOEj3wV sWAVdWI6mQkkEWGWAn5VUKy/enKDywxhSgN9zxlBPc5dBF4iM/kqOJtk+60G5pBBP32A4plu 7Vv0D4WI8kHiN+i0ea9OWzkHxk1xydFCNZKqbbySGlfO8IqMF0lEDYuJ+Si28fSqcAfa08k4 LigMGmW0cBdPcdRdCt2/82VltSEqrdxZdajmqrT2rkp9tDYMK0mYbvwh/owTTjyT51eFSaR4 gbmpEkPog19xknsFuDSK4hPVLcNDYVNFAs5bB62fAbtTB/RdUb2NdoWMqTIYb9CjLyai8CIr 1/gZQJuNCTIJ8RNRxnPb9yT0Eb2mqrltJGkG9/S9gwCXt/knzzjiFLmsr/u0LJJvS+SS3ZYP vTNaubu3DgG1x6MVNuvCySIYA8dHKY9AvIgGxggIhM/Br6hFcWiG6jv40mRf1m5bedTAFE0M nBnHXrMWaD4PYh8g6AGbYLvJResZWND0BTHOT/G04cc5ErLMgDk0J670VPdGhj4J3iU0Pk2R jOT+gm0c/3Iex/ZyvkMmPE5pBDMnazmktOK9V3ICchqcS8Hg3L0wPm76BAYiyIEGDT26NK/r x8Omia2oueCzJp1VqZhhNbSy/Jvxj4o1mZyu8xlpSNoRWXCPad+QMYRfJrzcan2oYQNHHUGt VkDwywCCg85TI40QHIvmE4INW7peC84HxeYPjGD4LyLpjQdVHolt8b5ZfOjYYmC59nRuMSwg e4OoWZknrfhmYiv7Hb3I/oDSfE7UiuNcqX0H6EtIEhElUaR2+t443LhU7/UbsbIwdY8ny2S/ /scLm65S+V4XQVfhVOb3r9ofXJiBueuCwk23EsWq+k4je4mB8+aOgg52kIdomNh9CMu++yR4 r6N+o7U9fRVes8evwMKLsJqd88lhaM/48265eoebxGfprkXBcTyvrXTsR3RtajBNeR4ysRsL jqqAT0HcMbw2207FC2I7DUFjxZFBD8dBDo5v2yaTMkeHz14cXTl8JRnBm5TdshPmYrihmx6b X1TEJGxMusz2T6MgWRgdBuBNLD5xyKF009lkX3r7UXcZaKtx/KaCrHpJoUMRf8cU+2dZe40D vqxzlECoFTHEY9wjGfNMhWYgrjU4iHuvW6n8njeCvnGosNrZxs/cZT2XD1kZyKaODO+AU8gL oHEDjD/jFV9+C+/kc4M71X/PIcpAMLSolpq327IlTShzbxfX2VAzT3AVsjwInoWoH7fAlRrn /D23/Z6TobT0Z1RtRwf8mkR8YZNg/FP+BedGAq81519YchfL1u8f1h8cM/QwAQk9IMB6WcYy DixqJLDEPV52V01W9ZEqFJS9/prMZT/5NG3YVUqWU/ltmz/sVi3eAFIVen44Leiyn20QC6zo 1DheQz1hRl04H/R87MgFZ8GZ5BLIaElsOmcPUwLCN9mc2wqIW7u9vQIE/whVs5wQQ0Ia9siS HOfvPeN72Q6oWAJMjClMb9B5ByuGFAcbJeXb0noMeT41Bw5FbfpqyMzKX2IHtPz5eYFk1BYU O5+szQCbXmPIb3mY79K5IUt8f7rlaesR6h83ibx2fRIn26BY+n0NEbyny82y8Tq0CLB1dJeg dndxorujKNfZl2UPZt9i45t9izlNWB5XCXCLsfcqQaFdGPlBEplvaritglwXyaeUuA9rqG01 6tT3n25zBxHUNXxUkCRdYlMNyeFfJma5f3Z8+LwsAiXm1zKUpncR2RV3LyDTGRsGnzgIoYAT A3Gs7s8r+R0BNy7XgUSLgLZRv3+U0pGhbHsm5iB/d9n/ojLJICb7r77GhbkTbVdTC0MUUAPy ekcfzTiA7MG+qAv98jwC+KuqQKmpOo9zthIqB09B4hpnfIwkk09etgZbSIpYQEWSBwq/wQPu GKz9to7+1DG3MCwwznXDO4XRS3s2o5BPO38oY9joMfok70Eq9bxfrRJwxMlKmfIjqonfNyUk j1ZKQgUMVTgjhDw3MG11XwEdkjEpQ1HerOiJccmYJWsg5bw2Y2u5wVxko4Gyst7w+Z5HxsZE BPrYpvJTrfPXhcCF4epwxVJy6owsgxeKzs9NWzQs0FZyHg9thuGj+x/jf6A8R2jrb7Ew6B9W zMPO/FnAledJUchzQDx1PQ2BaymHvgsE9EhibdvAThafuCDd+Jvdy2Ct//YNAf43XegJSeLg gu8mmlWY9em7g5UkOL0cRVaoq46IWTptlKJv+TMc19SgQPqDsJzLlXg65WNyK18dpqKtqNm4 t6zXh9tlGUHWi0T85v5LEkgHBJHPAvyppDbVLJYWagbSlyUv0ndS6iQfyQwYTpVV+5mQE8HX PSxPcwJEeJIdfzT0LAi3Jc0m25ASaqAqnGEWfoA3GewIVr0rBSt4jg06WtsmYy3E6VEerAqN eday76kqUC53rA805UYr1LhbGdEJOA873LepfNOCC9o2Mbx5hdTYZVMBFWdcv0e1oaddl9Cw xEFUpd3YzSfWNPPf7NEA0ZeIdeKPSAKauUgwFBY9VrsfVBcDmlJ2NhO00ox3QPmkNzmbGhKi B/Hh+yUmtBT7a5Ti1w18FD4sHWuJqz0RHx8tkcRIwmfCFM097dTh7A3PitiJ9RVDCBSIDJhv yKILx0/A3VQj7pvq7RaUJ6FBTQJTo5GkkPn0E6PGwRrx1W5OGBqkHyA5d38T296iUoSXQHEL U8FAI/7vJaCYyuY0pHVfek+wOJAU5mqzeN68hJubF0mKouB3KZfR48PEvBqLUapWoXI14UwP qAXIo4GA+zY0Q7LRp30HEQN7nL94cmnY68kGa4bUr1jPEDaCk+iCtvS/sRb5Z04ia2UDgRb9 NT8iX1434m7ZH9EAdNZ6qfHuxLrwn641RpeRnXWucm48KEoueNovniA3rByGqM+XuZurUSU/ luhj/JYSI+gOHZaUU+NsW6pwUMFpcGGuYq9qe1huwsqo9rKYmRaw0rowS+mNSZ6ksQ/aKDdA g2ElNwhocLiO+FbQTerhbtHGrP0m9Ol4sB7hPeanlgWqMSGGQsdg3k9qoraREUt3YGr8JktS lxBwM9LtUhzxTgyyiHgCOBUswlq6omolll+dYTCUMwSv8zERS0Ag8+NTEzFmdIa38F33fGTg GYaIvvoXhG4p4tkUXp2VMTyhkinWiu59XOktULIGammQfJIgVQLu2XPiGDKCUDv2G608LIp/ Iko1LShwHDgMVOMx3kxxt5dFBELS15KxdyFH2AKXruEWbDRMJlS8GgWyEMxRLWUO7NSwjrcq 4P3X5ZkKDAz4gQ6nD0y/mOXzv8P86VzxXxBibFoX8IpHFj50cghrQwbxJfruSaxsDIk+OM5R 5VNQSRFs2jOFAshogOmJfO4BD7ksFlKfgPBsgsCxt/lT79cNrDEv3vmCMOaNHteY31f3TKpz TikIrq7EtS8Sg5LcVp4s7eXVi3MmSwZLfAYm2kEiKITZRnWyjY2X79RtxYu4Q9LdxYkKcxlv n68Oz8dIEWEqTpqsC83RGjO22oAI5lRhgW63+veqpTTtjpXx5U++wh8Y1ig8MDR3td9rVqyT BLrOfCHd0NaWdY2/QZdaKU1Lpb2QIQBGi7yhaU+EsbVzWZ9oposqghPFE6JqmYUuXZpqvBTG Dw+ZPdEwRbCVkpRREyZNUpAyxHCMl+8iDwgqPUGji4ZiqEKC2pL/LdWO/g6o+7yaXmFYCdwD OPWc4V3gdG0ppNtChBkjy+PnD+PUejJGN0rrjMK9zNgQxrAjNkUn5xQ48x6fFASoQ0AZyg/C viVONDZOM5AdBzqJmICRgH2BsX4rVe2v32f1DdIfqFnA0I+plXq7F4uUKNj9oi8TFqi9qo8u NnVP4Y5EThIusGvE+6+btD8AiVa4agzoIb8Qsp4o0THiKTaRXwuvvT3rgrXOb+ZxvqKsIQ9T TJiMBn10pJ3devQoDIhtpv8dWBitSfv8fboj9MjWODXHoCjDXr9Cp4CG/gQmDZVrN7MlcFK+ Wj2GUmnsrLvuOc7OxwEcIqaKYsofwG1uufCxO6uPSXYoWwPwWu2NRcBJuHsNfUad/GK3GUWt H6aCBVdfoc/Oqqn9VWAMNQmENrhCcklqAD5ySh3HSvQX+8uiWbNEZHWvUB0VM7TM+t36E5yb nACEiTNFTh7+27AhUNJwRSm4UT/8XEYGwFFH9ABBDO++U3UaG012Vi5P31dIKCSzjhkqVRne iHPmZ49d9CxBY5edak/iTGuW4KK1mU9tRcJQ46iZGWpHTbRjWgwt9jUJHwYl0AtXalmGzUe6 CIBaq1hzNr0afdm1eeF7+LWZa1/EJXVULaKofQv5DgFSFJmavvv1pBTcLUFOpaNPZKieNQ3V g9/zY7mTvOZrnJa5m87corbB8Xw/D99XJjZYMPfwnE3re+T7ElO9Y5uFsux1n8MySS5zXG7p V9wexorqTTFl2E0aJicGck4N+UbRrlofbOtbWylAhuAzShCoVlXJhJPGhxuG8xXK3hGn5P1T KSMIMuQ1mIcHkhbf9g2utu1stdCW7FhyKdXA9RO4ePTpQRiggfUWRc4noemUTmwhEIUgFN1a r41jCBUV1mHR9TEtXmW2P321dMg5OwAQ5N4S83ZChx6w3DQ2bCKTSPmD8QTBZd+2kDw9JFaD V6geF+/AosDU5BHsHHFJK9HgRjqmtJYvdcw9KnF6wK3M2vXUPaWMrr2BziKGFRnBVBb91w99 IwHlA8eDhuF3CKZ7uIQgKBlX+yu1rcUMTwi8idYjVQAVnR5HPaUNy3WFnCSqTr1VuSUunDjr TLluBym/YVfNtwyHyhkiuz2gckA2uL5bqsZ8kFDS5kNDTrCOdifNtqjqZVIp02F+G333Ua+T ArPm54disBVYZBj0zHQrj1qxkqet2/Sk5YU3SI5LqRMRJ3m5sENMwlXOykduzT0vUwXM7xXC EwWI42Z2vQsPAXfzGKjUAUL12DZb2wHWpErosenZInqe0r4VJlvSX/gE/Ao1X/G9TBXhnPjW 5r/WN5XBOqrVMB/gwiuRUGJn5rpNd75aWjiKQ0IvNlARYzsTATfe3DZtPYk1mZBVU6+D+VCN 6EgGVakIBUnqzWG0oMEljV1fWoaLqrosRHhGvk05IGmfK/Nrv6PYrNkPvus7W/zwF38SCdyi 3h761m1Ugc3D/n6csoJHOrZN0OnW+bPz+Q585EkK0oQKFHpxHox16yHOR+8cPbWHj9ACJjVp RLzCB+R0znpP4dXkoz00ogy5fWJePOxsSu8HoUIgJdHypkSqRjUFUaOv8ygPV2xPLlnMrqI2 ngQuq6nNKUToDDX+eYnxfNwVYhBIIVZF0OuMn9+NLfPgGqLderm1yzVax6DSacPJzK0kmZ+/ G78hjEqa9eeFLzrrNTips4WsryUZuVP2vZcZXcC9SrJWtgBkxIGLEK5GfTVpJnh6a7gMiwZd wc2f8psSx0X5PaMqMDJcevYVIeQKTkfwRo0EZWw7FJq6luTgIQ4tjPE0u8+YzcZmdAIX442f inkMTTDeB3nhrAru8sBwaXpqak8e7ICS7RVuaDUdCzoiLCctJuYzDoAcvtFrJuJqjr+LL7E8 0hGBY3kR96n4ICMByd7lFp06ngvVteF3S4q/vMd5wMw71kClVcT9+lDjSnWy0KOugsRJ2mOS MfqwkFbhbtMK9j3RrxV1Xx7STDRYxGYQF3PG6e5c/84hgDQJPP7COb5ZYn1I9fIPKb/Rci6r 5oyfue/20iRbaAHYrVd9aiiUPVfnA1VVotRCuui0TZQzC7cone3Awk/jjSRl2zt4N88IL3jc eC0P5jlw/1zgHtt/r9/qSrqWZ+x/DL4oGj1+qV534Uklr04WSrEv+wx7Fx7YTh+i2lHCwn92 fSXVrjuD+EC4Jfeo7LfWC4TBGi7OnUqBUzXAG1SB1k3/YJgZjXsubfICuNuv52HKEJPK0A59 49MXJHH2GJcvxsMuJ7/UcsUKGbIIzt1rcalUFrF9xna+UKLzEv+tZ49aSjt3iad3cLFtUmur boRI6eWe3tOv6GrvgxICavbbZOCh8TxreomuM6cEvAQ/d8oWUAoP7etNrbN6o+FsF3Jjo+Op 7mUdi8nmvH6UA6FxeFt3RRW3Fs5xgbtNys+lncnSKMNDb6Dl3hopUyuBx134B8W6U3dmxKCr 49Um9qrOKFlbg1z4vx/nbYDh3cVzYuTn9EuKs5bLOS5bXBqwIO9gi0SKg02Fk+EBMP9Hyx9l WiNbLM13U08jv0zQ2rVrPRZvwAr/CFR3Ph5HYH30HHILaPyH6PJYZpTjDwuAE5mGwV8ejr/+ 9wKypkm3L1KIO8l5LKAjli71UcC1RmayyGLSN7pGGuSo1aHqF96E/9Qdrfm4FfOAriGvtauo s5PSmfS9v5qpsBWLJW/hmE3+qKR686Cnv/8Z5zRi2FuOCHHJ1IGka4YRXxPjSIizUdBtmidE OCpvpVVB/iptUfYz6bbJb0JAF3BUYotItAg0scGWsqw7gkssvxW/BXAE79v2OsW875Jgvmen BlHs6EQ93cgjQvXzASG0ak0S4N1N30VuvcEwpNo5F4gXqP8qbbe/7JHgy2f/CNqJKHROvKkJ YKhZmki1y7PpQAZXt1Wez+b2BgLe3SmpTXdBnEh595YtayhiDmmy27ahc7a2So1zG+Gab48S 3RLvdbi+XCl5/TZCqfLwb9uhb6bPg6Zo7sbU30ylK20IVD6KTloQHvA4PKY+DERikey+ON7x FKYr5LaYsAaNU3AfvwfNmcW2F6hA6x4/INsLOJjHv0Pnl3iy/5vxfWRJyOUrKMlk2NzX9Aw0 XdGVjh87mf6NGQ3GTnPa2Fx/QGUOwiZ60/jn4HEucZQqeBT6x7qJ84huouK7BrJjPVD0NoO6 A8GF671YtKHDincZp3jjAFmHZaW48jWDwNDQL1oc6b/VOI7zYMH+XJa+oG4A+D/8hYDi1ihX +OJn1c5ZVk/SbrEgIJC29IDoGvORJbogv6EUqvkBVHp6tcrTD7Nu+3DDVbGT9iI01sqOU6aU KvE3AAxW2bcLrqKo9wS4tYPBOJqiPBKvMpiaj6fwVBro0YIul7L51g8zFKky34oUg0+p9lEa k4bqtEBu69HBXhfR/hhi5cUdmHYXk7bouG6R8//QOY3O9dI0dtw6pXASOml4esdkY767Ygg+ mgquc6OLe3/hC64rSO9cDzSLoDT8UDvS541FXR8x4RzZGXKhjZ3g6zxOTkpC8U3fyVT/4Brc M+BWuXOXgM1U8CJ91dhPIV5sh9G2n7gzEOC7JR7klDRBxNGDoMxJygV0qX8aP91iW5UdYEkp RT/nZrEuFz6GLPDNmIM59hQ0o+5AQA9ml03oHINpiOtLlMYPwr08KQDEysv4xazDgD7cnDhe zNOR4chs1XjK3cNE/NnVk7806Mk3d9JyWJZ8+D6zLNdQpcdbufpQwQ1HkNWq4Mgd1Ad6bIYv p/JNCzMq/+pUdEnAA49io0BoaTqzdcSQWjJceH01/Lza46zY6oC6lGTTAhzV+KP1fZuxhN9z Pz1EVk28rmaA5S6riSZqR+ATAaYTAtiNllfR2bPPOs7nj9gvvOYIa4uwwk8nmogMZzEvoIbS yDMboaB70a6uVEuEIziVz6DSskgH3mz3plW7lKjZDNtG7DcWfre+y0bPCEyxMllX2Fgk64hh Jdnv86vkaX9O6X5hdnoVSLiVswtEB2VibjTDklAxS/SsEJ4fs48PqvzD8Tzp15IlTBrXTaYD l8rNGjkTj2/tIDX5Zzyafiwzd4AwY4USmQCesmpVWIMc+T2acfXjyE+9QqrqtVs2Mm0GvIcs 9FPAm1dGqxsBN5a5NRmzu2rD+LC46aS8KlIe7fefRD589LlLUP2BhvhFJbN2zOvajD1J2Eyk 4WQuU/TwdDs1ke2f3ZNl6TYZxra3Gf/qJ92kSduJg61TlySAYsJFX09fYoKCryOXntCmuUjU wefjlA3qCWobNlBAYxemDKgrrjGASUfaub31L7t3vf3sew9LuuufGq6nPn7rYLFBe2KcauLO uMNzqd6sDyceMvZoTcErTleFLX0AmLuYrLPkR+fMXfXZxCM+zBfORTccTnNQp2j6vG4GM0vA Q4Lg3b76MYP4GSoV8Xvb/AHa+lZx4XSAEv1gb4pGvwn3PhrI3IHVkoD4WlB4VLi4jmgxd2m7 8K0X+tF8kHbe6QASDBYoP4gvMhmgbdLH8kpJwLB/iOsVWb8tkUES1hStX75h9BUdTs17ulOb LZveJODQCEWwYM1vJ8JH9/gjr9UiKyPS3/JqsmrqgnT8iMEyIsxi/xsfNuka6YPIVB9+td2F g358Ieh1asukNrNbipkPOQCK7yq4jOGWMx3WNaLupKlGwIQ2PIqt7Bujs82ag5H5aVZDxGqU y8BsXXs9iFLsIacIB/BGqK+VsDRBSv4lDA4b4relyzNpck9w97hyU5z1iRPKBvSZsIs5CRnI Lm92jEW23eAoywxOYth5gBXUqDL+CEXF1WPG+OJrfeKCQXBn+ZxTxJod+kkRx2s6fromGsv0 IhQfDgVPqLLRHSoQaU8q+9tlM/JWThVzeKkMKXtLXKCL69N8Te8xFlHLAjOqS4BwDYlPHkKD T2JoGsYgMT0gNeDkWEk6nX85OQu7bcvhMotQ1BqWhha9egAGCsOB7Eqd6Q8rWSmm6ZKPAFyd OcLu8C31zLAHg5YcW/8vaNhgwLe9cI98ZVvD66+v6gamQdeQw3FWEvxxvBLNHTrxqKcwrEUH WfpVbjCOYcsEnT6F9MhhqgNe8UQqXLxGsDvgLAr/1gt/gXYHf+VWNfvP9AdpH9aeD4Rxj/NR Ix6kN6W0qkxqim3fkLD1egmtFf47q4rW/0azJBfS5tv3gsszFpwArpFpHkI8SOZlok+I2I84 Fxu3z3pkC75ya6ZWk8YPPookBKeMyLPOy8H8+HW2gtLH86jLHMBmk6U8fxMwMSwzUV157zgL 5IfccNd1TzdtW1qV05som8MDhmbVw7qj+Ocn75wanqpzVGMbL6NtTmMp9prOjDDMfqE/zbSV KVLlUkvl37uJP4AzExWk4pvS5zfwen7NoZ2Eji6eoIztCN2F1g7ybbdswMD5cHmIKz2cGjOl CeDXFuTXGhLTffG13tZYXS7M3bnIw5sfuF0BSj4Ro6IEPenhKPbg1/V7AuBDcSWFunihwO7P +R1LEtT802YE5JoKUb2I32X8lnUNvnO+zBDUQhSHVjBIZvGA/Y5JyekzE4RTMIydmjC5JM10 nZjnH5sF7IXQ7MGo8/Dkuj7VDEbBkj8s9SyE7HZEvJTJs+SAprg2ri9m1QZ76ovyaqWS6/hI iACYn+t0J+xduAN/mrWVFc5KcBCmIkr6R4htmhqzWgAbZlWZIdGV6YZJEOL2DMr2vG16uEZ2 hcoD29i3x6fNsT0UNN9CPQjWiXMH37H/wAXiKeVOJ8dafK5L4IzngFQbpp0z2fuZSRkblF8i ku7jcDwGM+dJN0hQbwwMcEmhQ92hnxMvnk/7yREzOO8epoBYHS2FOC8r9e3kFjMKFsZpJ99n EMYgF2oLIxI5GnJeTIGyFDDe/QXCp0TcAWjJTM4Pdmt3Jn5EGi8DGdIW95LBSfPjVC9mYA8o Fpoy+VpzlcJJ+sEKd0QxlD6saGst9zLSw8RVda0vT7jlZXy6zM5VlkQpHAlYMpv6RIBGi05W yfN3C++Wk0vZsHi7pzxqs4wHoHbFnbm50Qv3t2KpMp/evVZflxpJDabREBCzJSGGKClQZQIo 1USluUvLaS4miX/oE36M4Zy1//fFMBCQ4/Or0M4nCGbDZZqTVvcRsFPvR2TYpsScmJGTsmlQ 5phCShs5F8BdD4ZdJgPuCtEgcD6023QsulUT8sBkKz1TMt5MIDREG3ybezsQAkaWEJkx2mVW oojgVgSNEvcvg133f4Y3M48+tw5wrQsFfDDFLiNbVzeV4ODpIeCUx1SCWHsmz603VsNUYV6U h+Zpz1NC2Xku1Ravl+bNXPh2aIeTkpHSw27HljrbL2FYUsC1EcdmhHc1Lo2zxg0gZt3zPUlP peHJCb/jl/q7h48xMThuYpBhd0+ENd1XxKNQMz46xxisrro4vMK2VXptsxO1kx7FM6Yj/F5Y mjVPvvkJAhmBGiTiemqYP0KTCt/prg/CcwGRnPeugf8yERqko7VDF8kpx9vVvId+8XPUMxVr QKGbMWXGshp2Mx3nJ0sqnbDREg3JiKcoAA0pAIUmby6JCFTqu5g6rOYJBMvzqwDmg06siFC8 VzbmzPnw8p4Q4iUtgj/mbk4XKOoPa4WHhouCLj17TJKY3jfzdVWjgfqQXAOhJTcgGzK9bkPq UlFd5+l0HwCoTcnN/8zsaY+VDd6kojmJ9UmGl/LKG1CKTjfJsgtZXEs+jZ0hFCguptv7JETE IYYVXQpARlDSptioOdQLqEkuQLMVJ6tVpEhSmfOR54ZSXPvpuoyxjS/92SSxcmqYfUFhBC+i K33EUAyGD7z6LUUBA4/uHHgJHHxJNaj6P+OB72fNYI3OY2/8iSz+o/R0IuwhFdaXESksS7mP Za4HWpMtzkaJbOfs86cTH8ELDAyv1GopJEN/wF9A/sZ54Jw0YBEiFX6+5VE2O8ZPrDIORbM4 gs43aFXS0lNzmptc9DAfz4QXhUxvOf0L5iQNuttNlSMwxgd9MFgXuP0IDfmh+7PFTTYJ5g1o K7aatqdkj2V3b/MrigPzds31esMRnzdYYjiY3jPOjqTSzEHjT1BY40HJR3LGNLuk5b3gWdOu 0aGwRoJwsyebBCFAd1yDzmnyi3+zuNjE5+1ENXBnrxqUQ/i4vR0hbm4xGAF499zs5bBWO+35 e05cet+0d1zckA+jAYKWSdwY0KhL49dD79l1sB9lYj3DEVTgwkNsQOHkwu8OOq/XJUGdVmdC Y2xiW1dTQZZZdypIkzR+XgQLkgfoR5MLbwobX6rB5qyydvqzgeLRb8NK1AJ3FfSZ6+BJ/G11 2QYfpkRZrlDia4rjU0PHoevnB7DfDl36T0Zc4fu3si4PS2K7B2D993FN0Ak+AEM/asQAKNQX rLmu62F2/3bVIdaolpGiAvI7yfxWmtO2PZdkq9RUTRgBFQh0MGmV6s61EJ+i/5LhI0MqmWfU N4Wo4hUS1ZigwZoMBHIFBbyt+ch9X/2LVbhFuHdXP71rgj0PqKO3DZFJ4Su9owH/fha54FCp ciB/ZyJc0onCFn/bI91zeGqJY4x1SqfyBu/llzhXVx7gOiU7GzKhPAECE1xtblK1foehSYjA 0a5DZ2cQJa99ov14OG82F/SPrlpiJGOYS9uNQy/kKogET/MKqW/3khpvup0Q3hLM0N3iER4y CtsQfa/fzA+9XAlnPLUeC026/BnsGQURcisTws1BHvqrO+5S0W1OTF6QVTLG8mq4OmUxGxq7 yrg/PBDmUSkBHq75AcvjcpIcLUTz1njjcdsbx8NA7eRHyJiSt3a1DW+B9iWMnJFnyJHG2nqC GoCuRyHvgX1h5yzxjHWDoZlzEbmcjfts2fzk3ZsQ4FYEI0u8uGi9TXRwRkwJTJ5xm8VVpUe4 ckNivWIhHvV/DRCx4nZfFDPOaUEQyHrGUi99qsJlOWID/x2j0Yr3ClnbBA0UoQ7cP+J3Jw21 ZHb2l2EjoD+cPA1mknP5nSalwPe8KYVsL7toIRRvJTPhZtD2LywmFdYjMl0ykfDzGc1mt/j7 +ORUCadtW3DRsTAbxjWlghdirM6pkdoDrO1r4yUPtOVo+zESd/dOQBUtbKzINLimHCSp1yLS NMQ08zs0NCCXlFpjYlzH06vsuMa061EnSMe52JV92WjDKdKGoEidVnP1ADS+hkDpOMYDyd4u 86pbO+H4O0Yji/na+bQsuomTjLsT0f9G2L8BhWAO2ssat7zVzKQl2YwU6Fhv5NG6cW99GHS1 J4kfnYbp9yDnfk2TeHBA7FHm0uE2raFPIjQJItnNXOi/0KpVMVh+xqT8jklGge2FUKRM2tvS S6VFObeMxi8Hx3jy0GPVDs8/X5u1wdV873BbirS6mB876hTp2xWESfqei+ubf0QOo+/crbgS oEY+76Fp7kRkU8ZvDb05F++gQBrBtS/ikkyjoAB27AbGFszNSIg7zfbBdUs+3Kb8W1R90WJc dk5hpD0jWDFKAObwxz+44wkvMVHfdMaoUqcgKto6UugZz+Vof3rXUls1K/ruSrENLMO2l9UM VOW7mlwNFNp5RByfrEcgIg30uIppoKn2RT2HskWe8jKBwG5wvpYLTDPvVeCkCHa98p3dBlgA IDuRWf6TTokGnn7ECyDmj4TWUg3IDwy6V/tvkh8Zc/SF0uKLX2O+ChDTiPZzNjO0G/dfZiqU cJ5h6luVqrDMtCJBCmPNeXxQ5JtD3eu1dVBdoiDSIZZ48DrFQU2RJlDYJ3UhE73VddziqKQw YEp1qEShP0a/V81NCoo+j8ZVIl5EUoO/lo1l3ZWdZfUaRXXzfRmznjBPurv/dWTcP/prKnpd VJ80BbrDYsbwc0TGtPJcRbotQ+Esupy8+o/b7JVp+ET3J6ydLkJZi8SoPDo6ATBUhcdCpZJi DftGzxA3LJyV9YVyxsW5sNfSakgBOSTFXMW4nXUUbxTO/U40rSKex3jwxP6ggQTQLChyNOal fBewiwpicxWQ1ylBHZZKYCjlC0I8Spz47SFyPr52mLNahSiXU03JoGMJgRy5xrUzvW0Wl22z 7Tw1v8L9YqKvimdohYZvxUef/yXvZwxYcKyAbe6HnYLsPlCmP5JparCug2VzX2938nCwomHh 9nvaO9XniIOtO2QBN529+hPsvmIqSUzcbzeCJcs5M1/YXh8MfI6MTHouF9KNAXm471sGHLc5 diOnWXAeM1FTUv/UoEMV/bGJFPN3vvAUpvycboMF/GQAayt4Vhpv2H/CH6WW3KISwGV9o5GY mXK1KdcTYrVZh0bw6e7EqmsSCxlSj9YD8GPaDgrXcv0eiAn6lLg0mS6XNpR+Z7E5KwF8wTNI zzout2zpTSs4DMzTu5iQZDblPmQ5FdrietKtXBtoZdb1ZAm00xh+K7Mupl+OtIhKRm3QOqav S+41oMgbcd59dX2q9d1Xjce2wwXSue+cK/yvoVI507dwwtaAHYkSwTJI89P3U+Y3WBHeyDr4 oN4p6RFXnIvdid+L0H4Q/FpMzTv/xvEbVJLIoxiPrYiY6M4MkuQ+rf5fW6nEBPim/DtMB7D/ zgBdnAupxha9JjF3uFCpnLp42HX8iTWg9FsGCsoFVXheF4achFtT7IqDKT7LPFePJ47kkfk9 r1nKNpRSjW5FFfbdvBy7vO8zneUR3q3gaE2baYizI6WAWQbXUHs34M+MohuVskb4XenSKmyZ kSQ1TxyDBrGH0e4Y2N7zQ5w19SKvOMEfDLdKs0R/Cu2s1qta+0h16cqI5+PDEzmWTyfhcJZm LFrG1h2yWU0Mh2ZiizoJb+XGtn7SoWwmV7vmZl+Dd3jkO+tT2fWPuz1OAL+psUpl6h2/RpB6 T42Vcnzb7hlDI+e5E8muVnkisGy4GkSk/v348uMrr64N62UxKYXCAK7TdMhzaaIiDy0S/yoZ TYJr+j/oye6yrvCQD4XSTquez5nw6lYRNnKpSor5sgSgC9g/CkMwH/RRafU75H+j2yA99AC7 Py1JGkD+Brpja5uxucgRelWTVtXrnW7+S7JnPMeYzqDL6A7lDPM+ZHfhump1umriF+g9eeyw 2ENLL4fB/XTTS5H+gZxtm3KTKMvneV4FF/HC80G9wF3jpk77eeSw9uR3vaPXlNoKWKdMSiwL kspdVlkkEK8YOJRTzZloYWQkXjS9PlXoNVeaN3yaOj6w09s+XtgWXSOZXIuLzzgh3Uc4rucK rgPZgufKYOZqoy/dTi+t20pgIvZviHk/x1MEZ6UJ1mWAbPmrNEeRChvspYsLUKE/aVWwyOc5 KE0oCzTBWQeLZDIOuk0tjdSfvdGhgEsMHnwRelRPfLYUrI48GpkyPQHgEJfvQsdtfOOjKvVQ L5gYkd0+Kx3X4aoGi8J2C2U/R8vxGWg/lWubUX/xC1h1wFYx3nC2l4yl/b+FmpUcJJBeo7Fq SglUsmPwSreHtO/f1o3VWuMvVLuKSufbP9zgIrk9ly5ffff6Z4RkYdR8iWdfSIt52/ITulBg S+xVBcm8oaiglYcVrcXupCxTcfjdf1G+YWVnAyCy/Hl5hVHLlVvZoVnVz1xQzWaJuIB/fJf4 N8CEEjOqVxQ03rf93ZE9fmTOZbUGnek+1lgBrKyKmE2rShqrjxdEDI1ktbtuIpUGsU1F5Yel NZC6EA1Bb/U6zsou2ZcJQFYjOyVf4m1ApMBJhNlzJlQEcUZAUDhYzgDhh3S+m4E+vi+E1I4s c6u7jcntPp6VtZVwhgu3ZoyuKRJXkeYDfRrxn2lgv7ZvfPk0JMYfeY8K8tHIj6LPRweaLFgM ggRgcxzZLGFUNlLQhcmGbRmJfwKtHop5XZT8FBSyC+xb93A9dliUKliRC89b+s9J4pMXmWD0 837z9ET5tmBGCfwUkuC0fGPUc9Rkjd2EjS+lldE7GHUNA1KBA13HfZYHnE621mu+2ZI3aR1B ovMqkfKeHO8fQ2BafLGU7RGARBWmqe+MKoLgPWh8fxGKppOIBN90c2YrKNs7AIiUyX6XIIzW 5FcTaS5BxQFm0bz6YWgBgRAXdF9y+vjxiF/XJgkIG7LacUTJX9K0VNhsqSkSDUxyLoa0Zt8H SfIukhbn9MmijQryXwsC0JtMmwZ2WZR9cn+B/Ww1uFduQvnOFQBIuV7inetpNFdz61MUugkt JdiaXR/2uBFbQmfAQ5PiepTboG8pBXJCatW8ToPqjLDY046gmfFFz/CBRR4UWv0J3bUAeF7Y u49+/Kv5XGXhzsGAMNaoA34yYvxWuy7r6WEWMHZWLW2Dp2uSg2+Ud8W8fRX6AOJn4zpvZCPb F9OHpslKhCAdKwTf6wEEaAxMwWVkOdlsQ72JuE2keuUF/z53SL1X6Fnam9mvg0Yu5G4rVARf kUVnGorwiC+NmTfYmLO1dG/OOJtpinUwrLpRQXkbYox5CR/6RqEirML7CiDR86g6W78kMZ1O S0Zrh7dNRAzS9D3rtZsMUW77APcGadPu2oPgj8+xQmk26PhytbbeGhqvShxlopmJwQ7l8DPY MkVxfLFw2Y4fJz+LroWn9AVd2OtA/o7tLH9LD9cd/SVMaGt9gEHluhBBrY3jKBi3+5hI7luU SsFB+M6ozLD6tNJfPnCFuIOj2g3h5oiuMFetQ4YP3BBAQxDa4oguriqFjnKF9IquM+ZjY3LY 2RLij/RDeLliAeKB+IFq8HD5CriN4qIZmwRm34K+bcpnlbeV5DJyyuMffCYev7CoZNquF8jr 2Ai1hN9WCa9fWtevJFmMSu25WRuptv7T4Oo1hZUmCX+PAujTjhBNwm/1H5jalG4SvA5VHEN5 g7gzrRClewsXwNyiL9039cMeK+ikhZ8q662iJ89NFsC/KlzIg/OgNLiHYqaaz0sRwiHcZEKy doMsFNGkzCykHJL7VhLrdouG/G50XnSv2fhszmHJrhWTpbrObXEPNw0Nj9i363pkWcbK6mR1 LliGlKL2WHeJ7sKckxOBly9d8g8f4WjCTiK1pbOTgr0gDVocEhXcsjBQ0YCmfUn5wYCIjW3p GmwDsADCRIqtU/2xSkml57q8gpIFAWfGCPNq82Vg3wXZdbNzcKAl3Jsy/gJgai1jFkEEcG+Z Ao1alEBFimCMyUjENQWCLuIVSYqkSlK2gZ8L1l/6DpgzRh83mWS1KhWuwqGX+0NkK5XhdgmW zXMWPxrX9wKuhucLSVvXQ9APo88j0F4eqj8v31ogKGYro9zFGQuEsnezS9KjbrWDhbUoD6zG kFE1ntKvG3lgc2XUz4zXeHNiV1XHL1QzA06DeQS52G12h869Is26XSG9a7ZHn4tkMnI5Lsy8 CvdxMb1xG3lSZLe+C24GtWAPcZub4Yvo9eRORb6cHBEHYRol8fQIPbdr3GWCeXNlq/A1lGRp oc55GWVp9qJC7j75YsVt8wQug3ozrLuQY/+c/UiIx0CJqyXk1fGvI16dItWi6cYuUUv2ykly 0kmiX8ngjR8bM/e7H4rg4IcPAZag6UPX4Z1Zl/f7nJiaHOUYlfgNOefKOtb9m6rACuQ6usMA XSRNNeSeqeiac0R1YmcRjIkEuNIIvCunGvOUpKwP+cyvEdXiP+ZU+sNF7P+UBfU8iiHruPWA BTnxJNCt8Ct6JSc0rCoS/yPC07hYOtslB4kj0hW+FUbk9atTN7mu/14DMi6BP2Mn8swBjsVw 5fTGCgTFa1GpP1aAyELG9XWUalhkirKLa6rEwaLxStA4J8UTaS+nF8IsMQI/zNUNK3fOCndt njqMhNN1mEARBmzX0w8xPTML4Hf4x3iTm9MLa0Hs1dR++AxxBx4sbj8Fc3q42Bfvf6ov1Mro DiKjDhEOF2O/xuMy6jn6wgc7Wjynmqc00XHcI9qZRf9p7emH2j89Q5ZO34TuiQffhS7RJSq+ Hq5jmsG2dtedQBHVFNWdKsjsjxP9VI2PuqDCLRS+7MyI849H3fZvF6NCvRXCZMk0d1dmaB4u T7JtC2hy4Cxo0vEKLRcUfIlsBkWWUSllgA22O/9PCIlGaTfsZF66Ns5BsIGC6EVrAmzVOha3 SMlyyzabr+HP4YxiviAMZHbyTQ/gPrdX8K9jLOi1uUGAtBijjAGnT4uFknqL5JQX0SHNh6Gj f7vE/EEcJJ3AIjzxEs/gyzU35SRGZQjylfpSeMlkZS779e/vcm8LpNWuRjs1L4nWI7YvPbEu 50M/aE13Sv+KPGxSCA0vATLlOU4fFgYQimu3mY+MbZPgcXFy8RK0rAyzoubBHHH6ZGRXtx0T IKG83oBOGA2aVr3XCwLZq9r3Vf3ZlfhXoDe62YweECp4GYB8LzUpJXLhQykBy40ozfnad+84 T7QYcjDsNLI/KbtAFRQm2biKuDHpu6CcBYkPVf2/vF1yu377ZsnNKYyucdo+rlGvXdO1DzrC vhA72hhDEJaQECPNAuMqBf/ggjgQF/AYZRc3zu+ySgh/QYP47VfPLTtPwpJFx+jMaatcEYgY UZEEuA6jH68UWvDonokXwXieJsxaWPAYift3OFr6j7ewqu3U4/Et1ZO4vWb/ESBO+ZjrjGnA PxAPKY3OEEn9VI5uUED5X56xTS6KaPkpqMOIPUTVrHQpvJHnk5SQTJ8UY8iButwuACM0CDpk QgR902KJgAcMWSGjnzF22srGZOwDzXYsSJkj8gC2DtOIBt+MuHywge8zbTRUjeQ8LTtyHZqw VcqwYwAz+gYQMRduWIjLwkkqngxQYe8jsMU5iWMZbIcpqTVaY7mIpsDGVOgmjNphKquqGPvG eIMC9BOTXa34ewKH6bgjfUhL/irj9b6ri6w5NCtnDQLdW3s54EGgyhVZbD1NZc3THb2/TGky q4eW2GAoi9sX1OatU2qodsKmupB6P1twa+Pa9DDg1i6/9Kewf3naM0AUsiIkMbhZKXVpH85N +x0RX/bATIKWQWTIYIVPDgotRcDHWSTG0GE+wPGarW7QgWaCZG3otdZIV+kPNvv9W6AQJMSX ZyNd6pjcdvPbwzxovmqMlxqxiWiLYU1M435xFHUZTOSu4Ytjrj5OSa3EJxBEln7oc+mlj2OL tnJl24OzltU+ciWlyRGPdbtX1gAmozabLSvW2Gw7wsyquE0xmOa0+I6iboYe6fggrLuI8qSX GFM+sxLVVYM08RDpuxQ03oyJQdmTvQBbu0Lp47f/GE0QxojG4JEyq8++EnmjYeVj7PP1Hu3u pbpJl4YZgH+oKfI7wNMYePBZLln5FnNG4kKf6hBc66OPTcxn1u9mGV2yk/FkICArHl1nKCd6 SUfmWA5FbVWmrtzIby5bqVK+7VzkQhNF2moCp2djgW9DQaA3s9pR8AmgUwMyXQ1UF1KynCNW f84Tz1q0Lg5GejswBWcJlWpqx+QtDz+TrQTaCzGGj9JZkd4nDqom174zUqwJeygzsSToD0G/ PjviKkK3NIXBpbJWhHuK8ROMNBGFXbIBP6r8e+0WJc1BI6mC6qAFR71LNKMv1iWkkk6n692p 993t9MqNzvrDH3gk3x4oTbftvlTnmshETEfoLG690wBTdsg2klig9pXffomzzOIdEm2SedSU 6qUSiX3tywqLY7EU5RE4o8yetqRfw62FzvnD99zxjERcUbUvAK76res20R1VDBTFMdo716pu PRcASNJ2jqOwmd5kODIXtlCK6vNdJlycdQPQ34US7pqbymw9G5OYMDeJrdc3MogX1Aq5iZCr W4ZAQukWkk1YWqSDxuh51woVb285+v2rId9IbO8ZMMC3y8UBDCil7XfJApjw02L3Ps42ekqo ebv6vl58OO6i0GTK+pbCFI+B/ODjC5pNKLl8GvmhVZAVbg2jjj1vQTO0sFq8UdGtg4BlFGT+ zVCIT3FHVudZw0yrdkVwxj6noLMShkFgxzbIpwnM7m+o702WCqL/VmBB91vj4HyAQi5bc7Ld SfAh+WvMb3bAMRwKu7yQQmKUbKJnlLw84r07D5+XSoXA9uXsZBA+F4AObiTDYpNC9I6wlzIr WN5YKXHGLxMdvUUuBx4zdW33qHgYx8OnnTIvjiBrWsZUwkcZ0gktDqv7Qmb1bYwuZlSyjdgr A/LkqdR4lOB8M3gM3nbBBb9uRmaLAOm8ooFn60RnWnVqFINLDzzz+FpZmjryHmBHA+GTGIxK 1+/Hj4DP7LC0StwLbaLCIyhXnwwEuPGv9IKEsuZAg6F4cdRNghe2XV8QesR7E8jmsxLPW+fm P8qzSrhk2AjpwZjhM2480iGD9qekPtYl7+PC3laVIfxaICxXWc9jN9LgKq6qgo1feofSAtGi 6VuW1OHJB0LmdFi+xNVhk+7w+3ku7hjdcaqZ5mUhIv1Or4MKp43lqh+/BToD7IiVkwZTmjwH vnOgufjMeoaP3X83O8JO/D84g0wp92UUNo5hf3fs7u2oDTZwh2XlPXEHL2jNExcI02GAeB52 8O/4ye3VKbbaiKX53WNQnL/cQ+/PwwDSyFe99b70X6i+qLfPmH5t8JXfTL0nzfOfKlFq4OcX lDoRsOPwVFLAZyR4nuP1lYb6VL/Wanb5HEmlnI6dCEWkz6tAqm73Uezek/n6ZRWGvYJKhhXf qfBEXVJqnTcmC3ZSAFM0qhbcnPLzfxBrta200DyH8dXIaqXGdsz9Hat40ID4MPPaXnP/Z/FC czJIsoNP3MVqx1nRo/yUoseoVAGoIQ2BJcPkVuiV+4i8SOrbVrk/sPoJ2i04nwzSwTWynWb7 KtLh90Jt5SfLlGy+PdmXS/2DZh3vI9L30iPKdfpOIKlATjg9gngwMnOT8MbTciOU9TjXbBh7 CbbjHIYffwCdO0Ikb6VM9bhZNOPZhBRbdINvf1PeUT9OSRUFu0BZcJxLylnSkj1RXrUgpVL/ rY/uyPJa4sI/sqtKENJOMG0yYWptVSddTG9UC9/lhvsIrakpwTgY7Q4tsUnkPXaCgygDbQBe fbFWiaIlrpVccFEYqxek6P5EQ6bqYP3skJaNKFh5VmEQu7SabJw555oSmwN0IwMcsCcBsB+P 6mZ+XdwoytG5b2QYjrwKZ0NLBTXjWHEwdBotIOyUsf09AS53nkwnn0ifQEUIQrsaLZbTM1B3 hHIenB8ConLQWcnLXgDUPaTBizrnPzJ3O+ARreizVYyQToI14DiCrsa/tBidrGf7BAu/39JR gtM+NE3Fko3vV5pVsQ6rneiHFTvTL0Krta+vZw9c6vOYFzF3l5dMrTDWZJKTcuFJ4wIJVTxw 3nRzRVB/PIJkaWNDZ94TIcEyvHbeULvMOnC9l+dz6hnSRXEml7TkWL+A7e+mf1XU4lHYdFkZ ilcSEjNBC4uCA53gKaX46QY5cRYfNvMJ+QexrD0vEkhK0bkyMSGbSB7InejmK9c/Ad0V5Tob 7ki+o/4UE9UMvqRQdw2ifTxr/CKm75kZr/iedNp63cXKcnVnyZYF18dwCGihoDUYcb9EeMR3 MoTvxDlR7eCXJE/5P1TE6EgVf04i+F9rVWVm/QLXAfXzOn8cKE9C+SG8VNtLR98bqySWKlKq Y0Ai4ebMfuwaYjQ/fBgqnPR3JLHaIudUarfx9XXN7+3zUumdVRM1+Ofmyjp9MWhD3cBLg3t6 0RUrb6iSKVK5N4kDxypGPLzQAoVSR/lDfMStrl6B2y4LG2u+VKtLlK+V4//3CBnkd+GeOwYk cJSitOeP9LeQ0i2ljjJMrvm9crytgxkHACtsF/pi9w1ZSRnx/RY2VDQYLOXFD3p1QxDdSxvd RGOTf3tzwV/dWZg++/CjB/HR4ZAm8YEAXV58Wwh0p7eVN4X9KyJ/JmaThHUB5wQ/HzbMzs4R RZjx3NnSwlO0H6xJucncYj5gjDpHr6IuAtvmvBmH/QRu6XKIp9gRMRUFpNNfqLb61OJmT0JL cUgXd/hjaG0lTE+jIcXMhxG509b8krduOimzIbZWsoTzLoUJeeE9HkfJZIh3CjeH96IMqxDz VxuAKQGPUKIwz3VTtr2l1yZ84enh9vO5PTyzPGBDpeI5lqg/KEltCkJToDybNcGl74xA/gXY hU6tjM1UWS2aFJyEGJrKaBn/VeIbdE7tAyRTmPF30hFbQzU7jya7h0HpD8hJn5pURJ+6RI3p annLLfVIZIaVEB0/4BJMjypPRkSQUzb9vUXPHadHA/i2jpsh4NyX89chHbwfZTe39R2TIx5Y 2W4yWhBM3rV78f14GyU78HGcMwMtP6zVli4SEO6CoHK8lh2ggzODuQZr/MZYxzFK9jeZay4H ghRkhxQguabl+C7A5wIbqtcdaCu3GQgy2q0jqbvSIuTxEa6lurU851EEJuPl2ahluZDzHQUt Eaflp5qkLqc+2V42rfj2O1zTs9H68+zSAOrLbjCjpVobd8PT0Ik2tYjCf9tTV6PmCOKlubXF rj4CNNb5LJmH7p/rKn2S8otiptQ2Y4W4QnTOs0gVoHbPMloO+zFBZYhLm78SJfQxbv3v1a28 MGK37dEUcCqIPgDrQf41Mo4eJNlLA8PvM4+/5JO1cZFYvB5BYvluPMYLYgVGguAJobqTB6gv pVB0e1tRkwgL7pcnGm/5lUL1o/KRcw/SuP9EWzRNkXX7h+/DopZENO2WkVH3uxGxjButMpGP Wvy4cckXmljVlYBXoP/8PYSOu5pw6Bq4FOML5YKzV/1wv5ZHxqkGZFS4b/3RGejh4eJwKpZE Dnzl1YN9NB32Ubk/1ZVxO+d4fvL4Mp+OPPbTuYCBHqCI+/VWGXSxIgiuVSq/gFAKGEWMny/a fFl0jcU40kjH2O0bDZovM0sRsQUQPUgs7HSZKGfTqIAEc3i7P7i02eZtKmCdhkYpxV50Cw6p RYgWqoHj6bVKXUhadAzXP87e1D9sDKDbeH753W02GbRqPMaiOlkVnZ2yg0Z7l+Qlni0yLXzL BgwUTqX3oQDpvmxkCUpzQC6TfctEYHVYccADP770PBNSqZzhBzBNHhb6S97+tvtKXca1nXz6 JMfolm9qHrw8OJeTQLFJvz+Q7jKp8cuGsDIV5cWR6pr31vPtrq1zpqZvQuF1IvwvwN7oYRRg sOlA8FwBjVLVC8Rvm2Wg/vN8Bc1aVujTXAmCbDeg2J29QTvin6dRIwJOgs8W8gAPUeu+8Y82 ZHWhe065cqvL/EG03TO14XDJRebFmuhnzE//yzNYahXabNC7uDkHe/wzgCc0WrtsHCUvsGHI E6j8MyiC1TUeHDqoFTeZTZoPAOFqkZyb9klqncawqcm+phagrWqUl9q3mXwyc/inMANP+R7J fYFIiUVOsxwuEBeEiGpM3d0wwDekr4ba5TPToJi8jB+Jb05esMsT48nIshIKZr7pwdbq0XSD OnuP/qcegw5fMEpHjscZuVlFnIcj3AnCy4SQCXvr+eNzQDxaswA1ydfhLX99zd5O2CGF8cZd G36WHLbNi5x0xeWHn3hqNLwVAnjQCeupWkmUZenTvqhZrVIuFA+SPnXtX12xNPVdgcYY1hmm 5NSi4rsKrFIdhspew1pYTEspGOZYlTJq7WGSREL2W4/C8BmIZtzeNNmKJsO9gc/inYwYU6Aj iy8eHxp5kWPatb4D0uZldXmJXVLrpgURY20kGtB6IHyv8RpYXLqlXHY81zFXB7SBqAVkLxh1 Kowoe8IImvmcRIM6clV76u6wDcl7r4i07tHKx92Z8szlOHj2HnOXsISp7UQF+xh4ozeeaHo5 Z0bcBOPW3Q6Xf7Chma4DXuVEbMWviH1ypgZYQYcLoalHhp85quZU3WcWtDZi5zwirMPNIEHN 2LmeFDSX2yEEUIODF0J0DjFg7XT/tWj4kFYLVNUfKTnne6lilAGtPfAX/UxFd5ZTGut85xul R9pSPRQ4BbI7NOv2BZZj6M+G4ilVqctnwqHhgLB/x8OOkXzWcTurEDBWLRxZFYvXwAoVaAYI vYgibXh9/I8CQzwPxs9+uk0JJqE/ePr7+pLQCtCZ79/Ttt6xVCk0olyPErGA425gvAkUf1sj g6ywbD/Bv3+yVs8/E18xiILU7D1P/Y3Hv2Lrg3LIVhPcMPnYog9MWwuf41kzv/t+mJFQJMr5 +B1eixIsXG7skWnsNrCIqGkm3vcUGL1FB2yN4j2I/9Slw1CVz2sS2ekw3Rihii+AC4xyxL7Z Va9ar2ntQcK5e+tBvN/PjJZALmhDf7UMEcIA4NWSl8jzerYFiXlMfSW3duj6ZizGYhAhSU72 R/kd5HcG83J//UqlLrv/JBgzv0mkNxPfTQr+a96RtbgcA4HdFe89T4/I1VlNNOWsrPmMkgjc 9kdNDRpG3+ZQJFlTgGRusQhsvXxVRK/axVSte3TZyqAnH1V4EACfTpBigaKDff6wcrNf7VUd wRY0YUfRXHisadZmqAaVlK6c9CSveow5dnqw+7KTP3QBVKFVpvMYMMIqPTGBmx8fCJC7Stu2 7xGJUBxOE1DvfOkFCwQlB2Lt8rX+iv8ne118BKcYvRydAMyKkpEgDWePFoIEVjLOwRJBfv3l M/Cdleh8+MToCtztLo2UzrVuJI6tK/prG0eohYU/CoPY4oGu71uwSvvjjVIg1aZSP4x1tOe3 Fz1yV66dTGcvafxKP6eZtJIySyAWh9tx5ZF8Amv6heGls+hq9ypZVqh0p6DdoEoCeFp0eczJ ypfRx7JI2GyXNPAz1CofIlp4b2J9O+q0YGLPzeRU1u5353mvrsFDAITnIj2Wl8nbO+v1dzUY NWq/zkHFnz6MuRXHcaqNsYUzrW7G9q5BQ9P+f3gP4HEeYZovQj7EU+D6vydpICNUcuK4Zrr5 IG50VtKtjhBQtVrGP89HVt2s2JDHszJywglpvpgwgLi826ZelfMfd1/hhjUhiyIjJHraBzdO bycG6HByKlZq1g9cZYQI0Bz4V+p/0FOB4pgA+wb7EPXWF18bYCdtRl8jPcPvaBbp1EvTtqyM gBEbbVbSQlo5lqv+H8XJIQiFd1DLDgoIil+TXcaKO4O0NgvgXeWe2McllJhOyXX8hs+mp4jc lrO6EHIzfCaV34IXBeIRJ0PzuExwoQgLMc6rintackDUlxhkTyMy7Nnn23bo5Tae9rl9g5ok XJ6lsrESFDMNdfDBKRN6pdqM62d5KLSwNqBoR2D+xTfoDBzJBObTJKMrNwPO3h9SCJi2QPEB U2RG+3VjnvoivadKbfeP+ABNQ40XDB2UJLqhtcPMn6mD/KqsDd55/W/zRYc9YkRufIaLbVSD VhtXAMKBAMZD/20yCMapdRG/CTnFh/3E78AvoDEb41bS5kIe3v1ic355V5hsLKTGr5CpiMiI vloOqeafL3gb/h5Bm7+u3VDx61EVHK60/CCqq0aI+TgOWgMl5tkIsexqqLH3lc25ZOZN30xT mOquytadZJ5CzoffTrwlD3i2Zq5Dj2QEZyM33RUqninw5qtKf7v0F+Kbsf5mJy1hopYAXFUd GJyxGvs/UleyxWSuNn08WTYAPVTv7N/soOJMGsnvko5xEtHXDyRtQxor3fcEAOTc4s+WE7Ze 6a5SdSoq1LrrPHDtGGhGUkz1kqWZ99Xryw0hEGf+v5Gy9lE6LjoSrp7iIg3x5W60IBgfwak8 /iCDRQZTC58xolgDv6+jH/hk8F4TurckQORgKO8CWdrEfDwcvjl5HFzSGlM4mjw5ihOk7nrL cwowwp9hiu3A0XtfYYE9qIZmtyiIbbo3zCwFh0hScetu+g77JjP9rytm9pRNXpcqavCTP/cl 4vaWcqQclECLHji7hUxisIRqJ6nRWzg/aaaEtmw4dptmMT+yZMUGKniCriNjbrmf/zgq9TuV S3uxR2Y0gF5s4wFoJ96d2yg3/qJN/GY9WgnHQwCDLyIg7w5rp4CJyJ3F8cYE5Iqb7zjH4ZDa vjA1G9jLvJtMlyyFmPUdSUnR/sUXlYEhkK52/YGfFncf2NlIT5ilcDOpKEPydQizecMOgAzB dYogc2huKWEn9NV/zDOIkRvcdDEYwAYQM+uFgZyAoiwOhFlyJGQC2ZgyU0mUMteAknxZPDgj sphZvzdw7096M38S+LZH6SLA6reK/CahfSrBE9wZ6TumW8FsnpwfRTsiWVzrbRXhjy63qxpj 68HUmYMpkYcKldAFUG1uQLst3XzpQB+i4lVADKyGZ/IZQ744qrpGt/ZAIwTJ+IpvIFy1aFK2 Nu+VmIowLuHcW3ClLBTO6z9DW5Eu+5dyu7AYCfkrtVA+WR3SBEHCoMiHgfViivFcprek1lel tHWJ3kjrUgVgLLsZnOPU0i9bbJ7ZFpsRZ6ZwXdC40ErGT8qdbuqViwad4lhANzeIeiQuAT9O eyB73n6Nln0DvmhKuzGapG5wX8yJqtJH3q7yFLsclkUhpl9cso3IcKeUxECU9gWzkbN9Mrip ojGoRzNjZkisgRHQYV3wtCc/cTDXEeztu/IeIOzbQOHpV/0/fx85wF0vxSPWC3t1zU2QOeko S4SlCZHIhhyOd174QIGjCRLI9JoLTaEPrIIT6UIW08Zmr9SW9df7b2OZ3DPgI1Mc+Mo8udSi nbolxzU/f+Ox2k9n2d8H7j97sHrY/1WT1DRqNUQIeOwRnJa/VuICzu1KC88LPAlJgcus4KDG 44kfLvN5AXD+erTS7GoWFIWp6uH7Gv7XPHY5hFUpyTltSic2AedR13E0w7HnWeSgCUrJwgsS xwekJw4ZYyeiKnfFiQIoFMM6PBQviuvvr59weW9TX8vLhrjDYQHZJUJ5oclnWIn6yu23cdOl eODAnGLxCWxjMAd7PRKxLw0raBTpq9Agii7HXI6PPHv3WqrKII9NqXuY544k4SzOuxqEEE4l P4Fc67EPrHnyociKAStXVkX+1bicEkuMkvxL7OW/05MLgkQbn0Oxf1yK+AgK4MDqvybsYo5t qsuW2ZD2yBRUD0RdW4XpBT0ajKh9PI43ncp3BHa1WHNWalTwgyOjCm4tpiNxtGmsxDIL1s+v PucHkyDgEDvPVqtD3vRL294QmX39Xo6QDppF3s+SwuLb3SRM3TUX1cfecH1nq+nN04rksUoY /FDzbv4TIGZmkzMlgFZQhleS8dONruWSx/16fCHzbaH0IoiwYylCC4sVcdkYl9tZTnpFMj6F v5AwyskfR58b1ho9REKv9jN3wnsuW6LMOcgauwLSDWV4QvjtZzN5H5xeWSr1JTUu0T4Cs31Q kPnJjlNgmvV0RTE90iiUEV88+6u9TFgkhfuvo7tN4FnVupKXm072l+CgpQRHLHD553vLtmvi p95R3jgCcS3jqhBoUiG7V23Bxe0VE4MoFFjaNZ2gZieyLCoc4U9sQt5GpRebjjcF34dpZj9q bZWZh/6iIW+5LxIaVJYQ2sJhKUKr4v8KYU1BLO9JqW1itj26gj/WY+5tymyo/+4d8TqQj167 Zw5jnHjqvSizJLg55FKY5Ud9D1YMi9EnsQG5LAEI9okN56JcNdBMOllcJTdSmScAyZ4tI5TS voixpYK/9MPy9jmz7S3smtxVCMEyjpIZJPpslABhtiHXOFMlZNZGG9CDWs+vQ1plNbxkQ+2W DHDN4MwebDK1VFIYhtrLIEuTNGYDQMBF6R6ukwjGQLOfB4pZyPbO1/2e6Y2YgPdYOi+QI8QW X4bc1GlJ2iPXLClQSZO7rYbtrIuNG9dD3vmyZ/dzgrRiS/W3fQs+BvHmRWgLAVZr+nJTps09 9R8ypHv90VpFbhbMeAL+Br5Bl8DUZjpQaqUvlrd3yOKoeHLS6y+Z72vlYQ82jJYvGj+LalVP 2tSZIJyIPa/9bG4n/xguOhVkO01EZCOGqTsYDBDq8ZbXo7U3QbqxlndogJWEHZpPc3L7ZbNX Z5rzwjclLYLguJLFuyttKALD4V5NyUHXls8P0JNxr8gKYF8cvJgxkwHu7N3raHvDnANpOioB p5vY13fJcp9UR/cBkANWeIbU3ssuMjuEPHO0EtpeUMbjNio6MJ5fv7l2gC3gMhrgVAmsk9gx /ke46cP877np+S4mVhOK178jlA8J759atR1+Y95Zeq/wHg+5eC5pBad4/1NEKjyHyfATmfVQ Zdi4LeMj9NGPYoqTJF6YKd1jRRFivkyGW//NxVuY41uqX6SdQhR9klkVCRdPJuFqOeZhUUY8 w6VLOKn5pTtd52KPd+1AUOCVzsW6gTQyOJyg6d4f3cfvMCOu70Oiv4b0wolehcAsItREPxS+ PDUhfyiBhPsURK7nrh4Lpk/1WOjPVroG5P02zD+xan4Z+57zaUtL0tmZv7nTcf8JV+wgoWI4 xEvwSZMJhIOZ8FAQUuyihg62GSdeEp0PG/7D8Ju/iGpb3LNC/G/WMJinreKNSKnVFJ13gymy Hhog5ln3LfT7my0dPGkVKTP8oKJI8fzKzFKEZ+T3qUsJGDx98WGAZ02qUOeWcl/6ceBwRfjh /4Fh/QMEpXbZGwW+7cNdIcCe/o8L8HQqi12arBCZ5zgk8qvTu4Uieht8ziZ7blpGK4oZsoW8 Y5euTmYjulfwkXC3YzCzLYr1sHAab/sUhTzBWzbIs9PDkn5sW5v3bv2b4L25J6ygCvxKun1E 17VKeomgFjIS6EoBPt/YpTFRqhk62Q9SloN7GmNqL2wRNEOqu/hAv8rL3Z6L0Cay1uqFLkjM c2nKGT94292OpJ7tK5x2hfV1Z9/ZZH90dD9W12TCJ2i2u9Rpu5myQ81w9+Lt4iw2YHnhMeVm rbuHoq3mp5NUQFU+YF+7e7riDO5FY21TU5iqWksJw8xr/hauDrVOj/Ycwy7KKgtaBGZ1hzk9 gGS6H5CVNj+dnCeSUP/cj3ue1I7NkKM196PSiWDGdv+mHKvg+Rnh52A4+60qzMWmVNlHKegz m63zt4VcJoJzviRvDNKyOCyzgxSTKsmiQ915wCJun0I5bx95M0MwfhR7TQq8c/m8FlbqM00R crOqYhG9AYc1Of2d3sXVTH3GU/fygFPGxHufSsqBaNXmbyVgQELuA/eTRDJAiRvsywleqIaz 12zpIQs9kTlq6zVHnqnFJ0mKmN5IvatI2l1fktfr9NkVBMWBgPCtuQVZCm7AC3CEXFE2YYeU RG9Qo+6oMfqzbQoesMiiw5jblJV5TQ9q/9cpaSXR2vtRSa7uzRX59zhfqZ+BgiMFDmvbZ8W2 soXUTHbhuBgiY0EE3aUZKRiyvq4V/hdpLkfBIf0oIOW76JyaVdsMW7NWLBs9pyEUNqw0B/4+ oJHeXEPivBWUQ3jLGCaT4hCB5LSjufAkEZ+7tq64wCfg3nvH8thQ56i1SQQwExmKnSZKB2Fo 27HKTiMM5ikyOrmRWCKS/Lz4VNoQTypNHigm0G38kz0V7BUfFuKsJRpSXyvfQr6fk2+lFy1T XkUn4Mathd6f8SWfxj73+Zb2MOSYeDIK3tHMcr2DBWobE3CqRRQgUaLV11EJHVYSbYyqbas/ f0B5NUC1pDcF3i9E0Vieln3cOKF4y93sUauyyiajoW40vFR4Ujs+g7NsaVvYZCvbRBgVTLGt KDnpVESbflp7Qjqg3hX2mmrIaLaXu+q9Bo3xiMcMDjitH3Na9stGALragOMjZJ2RpQtfUlaU mgZRGJzsw1Rn58yvKt52aZF6sx04gAXPulaNJJz2lA2pqubR5JLn/XaKj/DvCwWBveKyUcJJ oBZ96JN8tQPtykgNwj1giIwycmBD1CSE0hqFmujyUvF9BNzQa40linXKbNkRsMODYXMuZbUs qMYr/iuYl8rEOBE2ha1UmBmioD4c8YkQRbFVZVlUj5jph3iIPiFiIDpDuEAG5tggK5/mRBui 3evEA53eb0iizxx3pjcJydoo/SyrAOJdAlfrbJbknGpLtANoAozIyD+th4YaSIXH8aoPflKz y50Wp8FqcmsLSvkVK3CJe4zuqX2U5DVVkC2pbv0XzOEJtvj4B/qR7t7qd1DzkhM86WNgmeUa DVx8Zs0D9hVw1Ifd+rQnb0qxxZUJbLXbsgKdb8bVAU2k6xilVGBVoGxZ7NzpK0a29rVBnIrh iASpgCzud4K++918IOdQk7/5nFwbYM51hMBTgyYQnN53BsRNJASfhoYXFXGwm18fq6ZfzUYY C9eX55txAFjVov6Ch3NL2QH8kMgEulWJbIQDaQ7h/Rz6qg+suSSR9oi6l4j4JMK/5i9MLj8j RWRIuGCr0nagn7Yrqr/fKQU2dM94RtTRxin3Vsw41bIm/qMc/EkHf4j9Atm921uJnoh73ISl t9cl87GiPcm9ER/WTPu5h0l7DyHsY5FmvPzm6gvq3wCJm446z4Ggtw0aIdNIOeTkybuVOG85 V/2c1yi/9szVcp4ZKMbMNG3LlhIMn7uehIvdOKerWAqpu48zxcjpqM2VOvDNXRTu+fkJd3Y5 c9/e9Cjq09F5baqjYcp8JiDBcyS8s+HdT9pg8gKaa5k+skRLR7QoNayFmd+Ek03L7yt3Wgj3 hZWWIfqYOR89H5fQmeyeCL/XWy1UrDETvav9NM0HObt2z3Z44LzEyAfvPpMG5TEiHmHUxVA2 3g81eV8cajl3uYci5qpgjSXVwLbz0ql5xUz/L28uBDTE5pdyW+W0M/8FayEBsvIgT4bvtpYW OHOhnOmESLamw1ZZVjDvHh8TsNTDpJZtWdTP+NDYlETSO5tP19yaIvpPpQ2LvFcZ/WqQZasG MGWRPXIGt2OqpjKA76y0ponGd1nWGomA7pHiJdf0QzjLjVXk5EWaAbzti0fBO+RY+2MNpRG+ Ghk3p0V4nhHw0TyVyE8GC0sJhFZmmmy0qZWKxOMfT7qhIbIglfTVwxs/MW9dpuptL2o8Te9P dA/nNkS+R/MdigpKaUMshU3jMtr7+Ws3ehfStXVnzU+qR78oRUSZQMNw9MGoNbv3fgrKEChs lJ/oM93bbNShbuxdt/XjIKlep/QmEJSGQnXrPZbLLk59rwizN5ENPb7wWVE17mgXGzbnCnQW 4/nVorcHzK2dPxX8ylSAH+sgA1idjlcPUp1nFSUCop3TCH3+25jsBQvzlE3ZyvWBbnn/mGpt 6Qg6LDyR+aBrWpswjwaw734VBlamOgkxO2xgR1MdCx8FfXL3teSqo2ZYiUc+i3E0CUiIzI3A /IWwsqa8wcb+pbhgdXlc35nalW0Y6a/27TkN7FCIA1wwTBQhlBGTEWze1cEa+1tX2FKrSkHg M8X51mcAtcYhJresoYtYPq985uM1K78ql530a3MB6Q7wv9SoX6qUNo3N0Rp6cJVItrb6sqnY Y2jSgFvoHiIzcZcok0xCx90R2kRdFw2ZYSjldOAhe3JdWqvEBS+mdyj11tdhyL4XYrjIAfzZ jdGYGugtEMd5O/C7DyrBLaqQMtgxrYzTUEkLqWXJYqnoQZNQvkcNIlxztLTmVh/mSVlLrnDz 8HWyByWz50HMEuFrx+5cqkhT4babfcW+KrqC5kpm/I9iDBwzDqEtQXumUTS0oV74Kiz7vlA8 qeaFLEM7PHcaaWOeje5J0cYuSXOX4bzeeNMRHPhN8CmQkOSATHM/9W2hECglJeO/B2LZpcnC I1tQyrUbtUoQxaBYCaXpz5CAUo34CArmZ9n/PLiGSXIsUSVqo6+7UBWqMmKQVDNr79iS7jv4 mNpQop7A12ILZnkhNlbajg+X9xHZ7m7SA3fDCAtgn5m7UO3lb90BN/TUWgjwybmaJxGyQ7pl uq7L8QYba3gUJtsxrGHR2Hy1kpr2RlMMNMHGCJSjlXY9KicYaI3DoEGLalnjbhsC6Jdal6sI EJvlFvLaCOFYHdcMy56yjwEe9tipMHEQutc/CfPHe3HYDg9CEvzHWR+/yzpUqKaAvBraxA5A V62q8is4wDW90XoF19ztNaFReO+Tx3VteAoAJw5ZHLylXp9MtJibTOSIKGt7GxbNFmgFVV+D 49CiMXkU77bS308CL88+FP8nzKMZqVUt4IZMObQ5ry89Y5kc1vsjYCm20UJn5zfMix/CEWLr Pb6q7gRN3HFXcxjpPBlE2/J09/kgiaVrJxBxd5QY+KAKRfG+QO99v0TtDY686e/akFFPt+JH eX9vOET/CpWmvM7FBR6Od1cWoqC2OLkPhjHwFlblsmbQSeHp6HX5G8pXE7pLkka/LGaz2P1p sVAJEnxkRlcjqS6HdhBI4Fq52FWy7tFJzmCArjg6shtP5IRJRPjubAHLU4/dOWHeysbIzj9m 1fp+o4XN4I8Di5/dOtD3/nnLM5VYkylBxmgWrEhXYlZ4QdhZnty1GY+6L3R37b0gtnGmQ9C9 0xmxXdS8HAMU2pxMzz+5MRTRaf/EB/h4AN5d3aXNsqAbJCSWRsjUCuhqWG8/Dp5Hxmt1/Nl2 35s3tjipYSrmCvbRpfKTT2CfHlo20w3Ud7w7w0hJ2df98yNA+i/ExdKxFL7uiJXZRksP1Y+L 60Yspqg6xgpAshD7avD8CbVOZdN79LECylr7k879+tqupSxr/B3+TFSKY3n+VVLPTQXIlljv KNYj0nD8nNWuucbUSlZgWjOhfQX0ZG6Ta/Ad57rRVlS7Xv9NMxkQd020dwq8DTLqsRd2Fozc 82tgjsXV6Ve0p2BfBl4M+VI1vRFGozobRl8m4XWbSx8u5ie9ABcYGO9J/l3v1ZeSiiPxlxuk ue8Cspu1JUhGnCYMsOE1/Ox9o4vKPuM29ctqGpjh84DxB2czNWbBqvZDd9CPEoaxcDdtil+y FtjN15xQlwm0KGtxKlf45I+TkwT4TcYK7SwK5kK07WA4HCh0EPVmpug69xm+Nh6OuK2eADrX gUtymEwLlqR72DK1GKdzFkUV0za8zsMXuK5INLxnYTzWvu8x/Yh4x4zTdI6kk+7L8a3aUfou LOaJwWo/GVFPqYILrC+8HFV8c4QUVfbaQmzjGIwQSDKaMsFhmkJx1ksDMJ+UsSi398z67Rhy po8aQS8A8eCPU9E8t/3NHDguo4iOYU9mXBMVAlUeRcDQwbTJo2dgAMZX105pD/2ILWMnf3Ef jLAc40grBnYYBJXvnpn0EiodhK6MqijxNJph4ASq6J20KSFcOn0BmZk//fq0ywb+RQGvYVQS MUwpUdllxNCs1w7L97v8qCAQDL5ijbT3nMW2PEG/T9BOgmXM+2DV/jFBvnrqkMNTbI7c76vc Sbi/RaFc09zrl9Z99oyej7Lg6GTZYNdrxSH6lW4E5jy3CykArXg6r3o3uqe/HOGpu/K7OWGO CT1kMx/uE5rY3rLv26K0tVU3UndvzjSJ+uGrwSUBaoElgWxKuMCSioKFopZ68DqfFyvcx+Wq f/FCodu20VYRXr+k6dahvIfCTGW9sZq8Bt1b5ypg/ReHQesmBTTeR6ySaXrFNPUsRoApSwJH X1/NH2dIvy/d3krsNXjbw79dB6DC0bszu8g+ReCBfB+96bAMKtdw2vGvxbdPW22t7Z8wgBSx O7VfuBkQJS4qyfXuKTSoVqvMkDDexXIQytDdp+YpaqSPfRHHO5axm7ShMWaVqzdfc+Y8h+M5 OUh4jhZyHPtqGpcoI7MmBSyvsd7/gT/eEmRZ+Au2IhJSf9566brx96czt7c0C5GYDlptS8St c3jTGZ0Af7UAqq4E3aiFzMU2agQBU6lgknqfn1w/NPLN/xwd+zSJOrJ3uw32+CELy4U52LTE LswsroX5yhrl/CgxjS7zoqcYmlC0N8gX0lqjEAH/37Rt1b53vKL9sOcDzoDHo2YPDIBX3r/9 SXVLREJCbJJeeW9xwjl28PTHCEqho7PRfFtLVyXn6bkS+/a5FEO6imyoi3S87+14wHQc5CmS XUHIPBmPBMmSMQJ2gqxAV03m/C2XSjI8SeomhXWJ4KoUFum/VHhUYmIHwjDwS6o6SdO7ZiN8 ZpbDrIw+7QggQ/AgWUTZHCto5nPnA7wXYBC1TSO7i7+f6tB5Z0+ZV5EuYSTE1CqF/TUGByYA mUoRLL8aJQJVqo/le/ZZ6lvMNEtTM2gABDUx41ZlyJZaxMyuVhThS3+0kgkj7MGzldFhaBpT Grgglxsw4GcHlKXRJfHB4BH6pvc1AC39Rpi0PH/ecW2tjQj42lCq0KxtnYDZgsM8Ly4J6uyD XmkGIErH4jlexsFYJkQaKuVQpQQvLOPXExZUgjt8CmH6FdMnUKhdwJovcAJ+efNlpoaqdEum jsJGGEe1pg/azzZzn7M6TR+c5Mq9VLMQbQepTvm54RyWtut0jj+lM//stloiCY9IzGn9Yx/J FdiY5deevmmqVUnsb9iQ2lFlJxj75MZ9JYUTcz7lC+XyAGyZKX+yJ3yOy5H/Milx73W9fEl9 dm2GXpLwjoe0uoa3IqTJFitkNdIuJChw41bxfJDnRArLgZni+rOYe6RBQYZ96FPQGyxHBEyF t1wLYM2L6IbsXVXLnMu7iTpbM2krmieLmvFItv5xG2a1cQJoKgRXde+cPdmamoShNu9NN4Aw ZQIy1+2k6rXZsLn9Q2cj/gFZRm6Ebv3846LLcRytaJ2+Y9cJo4Y3EssqKCgpv7NOB2iLdO9M zHiXcG5aS3S8B/n//v/9oV8VJExVY+rJf8LeRlD6WMqhFwlu4EJcZ2aQDino/CB+I3sDrGac Z7BxKEN9D/3TfRttVtlPXL6lIjfaLW71O/i19ThjW+ntysc75eWF4WDhXvd765yoheS2/Yb4 aK5b/gnEHXGyByKfPvkg3O5xHGum9bS2Z9vsSflBdkF/8A+mUi+v854AZxyNreigBDvtMnw7 E4QGD7B9ofUQ9WGa7xYY1cd+O9GsO1lG2O+8DoVh9AWoUr2vqsNHCvJr1qMYtVh04Rz9lktr IvEo9Y9hM2pcr0DXzhibK5t5ZDxWAl3N9XEJRL9jFYC6LSN9DLBEEdxkISPEij9Ih/Pi6qB+ gY5pS1A6/uHIKiBF5tLgsEBjdIIvp64vnksv/yFqUhDjs/jIWj0QGcXVAGuhlMEgLVJ9Ju7o g0i1v8DaGkargkvxnk1qhjviw5i9qs9vCh+KfDIFs2l+mcPzxMnhMjisdMZiTylTCZKnOgre 1e2OjKWbwV4iY9Iy272kQ/R422HrHWayfw7tAyrqpz6USda7FleMR9ch17uKxWjqUNNjukwD Ixqbe2HMFH4P0SRXiti62zqmP/Lt5RbCpukNShap7XfGYWsa1zsDkhLGYWW6CPSsipPF8Ejn RP+vARi4dSgiL2Vxa2kvGUH8L7HjJytoMXGrWFe0t1i/UO4ZDbLMA9IfnpUE/g3R9fLK5j1I S77/xYTtI811Zed7vP5koNIq6J+QPDdMKmxkBy4ZMeImVNR9NQwaEC5uxjf+GYiqPiV2O5K3 9cixjthXBkDb6i6x/IbAb36Tx6Wz4gfk+AwkEk/Dw8DBnm9rYOT9CE/V4Pd9Y4TGyzY7LsUy Nj2JRuqhedVV9Se46LTvokA4y+kRmoY7fC2tDgjtUnUVwdYCLrhvpo7IxGzb/dQIIxbAHvvK qqkwCgRIuebp2iz1BuRON5PX/hlxGRdKtdHCR8PzgQkPX5n5YUdyP9YWaQOu3wKrub+qZAyH I5sBkotLn0vOVuLUVtUZryVV6JwmusOmRDnyfwEveauQc/0OTTSwg4KIIJJHx1dBR7KtID2s IcvRISzwz7JtPJqbls7GeVX/ZExAPd4z3W9D38dZftZGdcJTQRFYLRm2EVIEO47cepN89NBV Esy/HDqZM12l6Mj3URy7oydoNaXhXZpGKj8nplBZtKx0tq1NUPDa9gY51llNgJu8s6YDXRM1 IcAtnxPEfnuT1WAl9gZG6OH28NhBUTUEUeN6j5fVD6H+8B5HRneJg4ipZVqBW6iUKQwpCOdS e9lLXCtZZP9yT2TiZedbtAh/InRT8dyH3QAHEMbriqbbi5peDW4DJTSxVCQ6gqMoTMdjh9dT DZXQNS25TXpCCxisN8pbAxYA0xEG1ZIlYvqTGr1hBgm1YHx7YXNLMpy+OrM40CzyMPYGQmka DSHDQp2tqLQVy78wn9LWtuVeXUZbn8H2eSoDlzLXIqZ9jysbcgR3yj1OEXZ99QsEBGWbzgzN uHVKKA5PVH3i98bsvDhfbbIkztfQxH20eKbW807luCnLF07qD6fAQxbW8+otBpYueqz4QFrx cd99L4FtvuFP08kw/XCQO2QepRvYKaUlaWcP5mpoMCmPpZKV/qpeme+zB8B5E9VkRyxX9cCD JdNpxK9F/k6tM482dKte5KGNCLZUG0NzPXLYngW89agtjv4xcH4DzMNS15nGikLRFYJV4rY+ w5VfxZNWYTm919TpdiAWlJFoLlQzlYBaeHLYGtz8iAjtheIFUQ0qeO8C4Wu184wJ2DD7Yde4 bF43KAlfhIVuR9QplfO1emzLmgFdwA46f+L5KZRkShLfayeNhe6Rb+u3GzCtjpGJ+65J3ks5 ZUia7jy0p6FgymPPkuI8607/wSOGmm347aHkBjNeQBH4xBo4upzW05+XDgxR66T92lBc0VRl zjcV7tRPNii7ZulhkkvbbFhBuGp4L9RAdJ+9giA2lnQCdGviaLOayGbD/GhrSsS1oPIkw/L0 2mC7V7uP9j2Dfz9IsDgyQmBm6PkILwvALFNHwSKWNXuWULa7Pw2FlURw6VmWarVFPlGG4fI7 XGT0MgBrOoWM9/2eFsreYI9ZpXWBhyR37tHc6pWH1SMbiznev2eMW6Rnl3XoD0PVj/qYxT/Z 6UJhD8JXYtvdzApWrnyibKgGOXxhKZ981Bfb+iwgxzW+OhwkpzcvDLmmSEv7wU8SWg4hYSOC mZup+25FV5K97qZZ+StKAYgwFItpGO8rwyPm2CQ68u6yEha0oYyOeMCY3e32MUiMoCJUHdSx TjmX3Q0N0/JnsfewYn5eSm1wUD5+M7ZQ+xryDH5epsORo6stvGQQ9iVq66JwsweG71UZDpZc 91ORElOXDKYYHP+oepkRGg8H5yytsO7fqSChu0CCi0B2o5FR63biUQyiUmpBp04q1XseHFG+ 04rpZe/ODL79fCgvJDAon5wV+t6ZNjntFuEm7fhV3DDMWckM8brho4FRvlWDN4wV0FLcXr5G dHx/lwurRoO0/NcGf94TniLIx/4V1dX6j4/uVmpCJ1unwZ8EaKzljNHfThAFdS0hYLfWBPgv clY/ETfEXzGANY0StKSfyDZDIDaDxab1+mvI1mmGwxWwnWf/5r3HsYKFFDW/7N19seOdJSIr r5NRZaVBpTDMy26cHFREyECj4sn2EEd5Ewsa3DZSKgV2Hr9PmKsrSBRek72H1X8SDiLNarYc 5NbiEe+mVKGl/qYnxGCJX6MeLzwcLh+P7rDCv2nqlQzKoWGDa7KTuJVg3oHNCr+VLWwDu9R8 /nCljXVTBZ6mNV4Q0CQYef8+SodDF8BN9qwUX3iL+3nt+JU+QqoeHC/YVA/gv5HbGeVuhf+M 9tvs3EopMg5RxqtDiaOnRLCYw9JV1n9xJ1iOfHDE0ITABlquYA1p9IKHDGD2n0UgS5W+lgtg cYzEJWkcYnXuGdErF3/96w41uLxEO/Ccy+HsKBNLh8voAdA9sNH0wCFjz8U0ynETCQ5f9/Cw h5GaqU98RiYKb+h3omQKJKQ89/iPVt+AiuBhYq93wlhrhYhn5qCAfRJ8sKYkxKWgNyfDTQ6Z TamjJ9VP5UhwxZY43fhYEKTmSXgEz8ohEbDUppzZqnZew7lMxzKFq9ESwTXil3oFaSUSx+9R 1hBEITPlzhfHx0q/xwBa9e9oVNL4zoCIqK47DQF9Dp8j+l9t++jYP1uMJIY2wJL0RvlDjGs6 Qes56YKEO3p4P3q9J6XWeA/8XCsbFcdTBz7EoKee4xkkv67VrA1cBNE5DCAexhtgu3IfYDXJ TUrXLDyDlsibw6WOJQ8VQZRUo53IwfXUvZT6vfN40rDhjdmkm8z7fEp1/M1kictpH72VHQZg 9KueDOPTxIh9ZfGyAxT195DL0JLjuyVR+eK4EcO4BaMoEX+x++gyn9qNelLIhfzzSOhTmHmJ C297ZWmmRKZjqNLLCRqEHeFUsBSdhaHRyC2AyTiWPDAubta7S5GiCgcTOk3wnl7kJqYzk23b aKPo3z3TUqzbyBegbaZkB3f8hxCCETomxMzMVwdCxfkRdxpy6dbdw9ReGXiNQOtdRVXD5beC RJdMS1MvuL0eZeNOEVlMXE6Qiibm90aEbB0V2qsOSlnO7ymWrUh8gsjTC0h1vzOfhuvOUMV6 0MjUPF3m90sO+srKbjs2+i05M/VtRamiwGi9fpwWu5e5MtjiAw/f3mUgcMCskAvThNMLnkXy M/JBg+0IvnIes23Tzfai0HIZXMs9WLxfXURFinq+EqPLQARhrMK7BiuyTOLtuHBn4ZISY6NU 2f9Scb52EYiEAYy2A5wPh4A1rpuc+FmZNe0vQY0y4GQOOaKEOS0XGuTA81WZ54mnNXAEs+EZ WF+772WaJHgKXVRESx4Ob4GUe9Bh8o9O/DhekL12RFSDY2YoYJpSL46bH+dGcNf65ueoHxuY uDlhFIXLoxgEDH6NBoEK5t1ylcVYrcZyTaMYoWdXTbbiLSbCc4O+2AoO8nZpcL6aEsQey74g UHvkAH2IVty9FLf3AJHXDyQVSph0KAC+6FV4WbwC3ve87jYFGgxc7uQRcnQqrq8vpshd869j ZIF7VB8+IT57LBCKKLVFJk77EXHgR+SKON44tadH7QPQSAZfO8e8QB0+xyI48pVBbSEZk0vA 0MFRPFrFFUQuaT9YDhWXgGzZGiyBdeMwrtu6fzHiHt8vihCdL7Us+EArznxtvL6flZugNtw8 LpnRTlL6D28I4np+2gz1JPhtJWTbfXpUgx3AUZ9fOev/moXG28+GpOjGxFjpdBbcldWTzFHw cUWjlrv/IO2Me5im/pXjpsX36an+OkipMd3GCPk4GU5Gg5L2bvm2XuwFFwvrSTbgzyaOI+u3 IXKKKMQsqpGrx7+FrXgz8XKvjPNeD9+JYjct5tUCFkX/276622fbA86tplkZ4Yg7BEdJisy3 /TUXK+2JW7u3uFqA2NC7asUZ6qxLWBoIyVKMiYlXs314pT/97Bn7WXreYKZ4pLba1MmQvldL g8T65MMUXyX89a60bfcF706djVh7bQbzq7uF6mAvSuK0gLrVwY1DBiM/iKCBgmf6PJsnfuo4 osFGrft4L55cD2My/nL9dEf1DnNc+5U1xvzwhwg34Uo6y7H2rJBg2lhUecXDAupgG1jeiJ9m eQPPUgMGIoF/HVNkq/dPoX/gboe+eN9Hqz1wm2dzY+XYe0CQqdgi1pZShvHrabkmTJ/wrQxs lQRYPFaJp1O5Jolf28JJogkxHQywTEepv4i/aSD4G5YptLBKs8Ldgb7vd83CbpmGxzgBDoPQ lFvik8aa9CqFC2afRdoDQZzzO8zAHgsOqHIBM3QJG49k8iFDNTXyAKOchfc+Co/H/FLr/IF3 pfwdP3NEDt68sswouG6D+81FN5EfqWVuI2LjTAeEpIEjxn/i02RRjFprAgB0gBeH7DpJByh3 46M//qP7NqJ9ZbB6dmFr+GKFe/h77W7KLK14ZkOZcX5fBoX0xlRmdqElly4DcjmLICLpXuwW couRCVYFReZnWlkfJzM/zoLMexAMEHgNhHVw4vpi6L/oPv6Rvcw5ykgQ20Qr0lZFBR/BmGER YGbGC4HUWJfqPNboLPBdCznrnwJ1MaO88quN/0m8H0UP/yVJPMzm4RYaOSFaBFHsppIV13XA CoUVQwm+V6OPA1NXRjZcxZ1PjBcHfaWdjGSYhsiIq8EJSxoo1pVXG/lptIpHZabEVWj0UlVe Ys7aN3aI7DK72h/P6PmJdsBmksVtIgg6RiuuP2M4f/SvOGADOrrPDFZh6b0qcU8Y3WmaPa54 X/xMWdz0YeoYD7M8JEqJO+a3sJMUWaHrduMUixnLQdqO4NdVuiWfEJTdZ0lR7GfOYm/6kfy+ vNukNxHcMnuc5wQuOhJLSlMFoZHP2iKL7rb0y82OGudoj2at5KSCl+W0bXYqarEmRo1l0GBa o6842IcukWBveHER+6NcyLU9Ypbu+jLeVVRlx+/6y5pqeCMY3n5gVS3Gs04yrGoK6crZp/P6 n9/NjQfzN2lAsbDfnxaZw47u3F8w1ngv49WSRaSVdgifCINc9VOpJVhl/g9gu/AahMP/0wLi r0n0LSgEGygq6xF9tPSx+ywEaQi9JbilIueiZSz68DmkjG7dpoTinTj/2X9bo26IDnIdaS84 AiqjBZY1fKmFjld5crp2RrTdWZY2zZniJIF/ZxKj29GxCXU9PsDU+kaI52wb2WLHTn+nfNF6 dsWjKXnf4ddaJmMb/WqiCAmi7LIjC2feiNDAaota9NaQDKbeGRCZ1PqfqcQMa1xOjV5biTzj pV2PrtaLD0e/NiT5PfEnApJDGkuKApe/dZOxtV7vEf/CtYLFPBNclVOywf1xnPGsRdQN7Xm5 8tidWjbWOiNgXAIzEi2QUlvdhJ19N/YQK/9MrGtDPvogUgaKmUJ6MGGidpV+skcyYstirO32 nH+ovKPEqptbBGzmrNziZcORMz4o048Lx6hjcFssd/gs23IkR3fHzf2/yjosxpH2iq1c+5K2 eA7nxqabneDrln2RfSYSTTG6gWPVcoAij92gUSq1L3IOMepAzU+gOlLa8arIFCDj3RRXkPGO wnftjPL5tNhgOjgWZ0Tnt0+Hg4N6gFI6FY0xlgy+4UM/5T5gSV2Zzn9BNeLotmy8MhTDYr9d e2e1XQEH4XJLhXQHWT4frnRtAZMy5UzE3bnntBfLo/WheqZugqMXMr3u56ZhsYN0mjGo1LFp UyeE+vkK4an43b0CxtU0qq93k891pFp96qD5L/0Mc1v8o0ev9I3Ljpf+B35Ww5HB+RLfbtGr u5U9dtvGWVu9RXmrkBAZjeWpukzKi2X3KyEzZOuSx6GNv9BvGyTURo83Rewd1aonm3XzIK4R jpnkKVku1HFCKlySutHsUonFF+zkDYEIYFYIfmYnNpbGuZdAP7VjHWlcadkbRguYuIjEM7fS 8AqwsQwNSgdl/LhzsS0hDe5zUKG40CvM2MXLbo/zfyf9ANXT3ttdcDbiZWqhMofOwuuxh1xK 8U2imG+LLVC83M7JB1ChaDK1JlfbnGmdB9o82Mjg0hRn3Jv0BRTFieNfisNovQIyuYuD0zeF ljc15NI1jhkw5ocyom78VCNb/oBNpVb/BmFbeTR38jwBTK9KvyAZbT/jhClBsFt1GCidNMfd 67qYquOvE8F8lQzQBsdu199VoDf+Keu+fLdogxGtJf4vAsDgy2NFF6kntu5QkJhQk6f1MzWv 3fvTIePX5H7VJnESzaPmLA0uGRo8gbqlPaFP5Q5HaMuMSSU3OiWF0osB8jq79MLCDwoyCf2V BCCvzHU5Kthtf2TqSiOY94EA9HuF9YtuDZf9G9B/zEZ4FSw8fbRHZgrCXm0ztZsE5yxsWJXR C71Yq/yETsCwmnjb75/fmhzN1/y2QTxzWdFm9XH62jvTOOQgmcvB1eRT9Tbh4hZY81XQ+JWt Zv+frvCX2EU67M71AIqC1Sb+kfx8fjNcNUY8L7OA1HQSxSD6ShZ/0LpWU71iN5tXJVRhe69d ppBaerngBRRUNe6SWJKVX3YoHC00GtIUP7y4VmW8mz9qiqj7YanvQmoQmULW4q6Uk4+xNzbr S4Ws5H6rNCy9MdYiQuquGMpVg0E/4Xaytdt+5Nu/mdunhiizRuCn+UYGN/MR5oWzsnhWrGsl MaQDiWWgxQfQRmadLpaW8kbSJClJ3Vng89yM79Y20vA4Ve7fN6XCFs3+xCrH8NKv1tkeUBak 9sSjV9LN+CbCwn66hFW15MnOO7KCkAkEZkh9NoEzYjfN49Ol/ZfL+HpwKQc2x608Oo9SYBnt kLKXVGGhf5I6fm8TR0drzW/8v9bL0SjQnnPq04nyOV/E3u/dctuV3Ddy5z8R3VtzeT1Ncbns 0VUhLj3/rWy+bqsbVERh/DeIfS9snKSWHMfbj7RLenyPwXOXFDwCwxFsUbiRojqHHclZDXiV COwIj96Ins3HzBZfJHbR6bnZxGu2gcGpvvRmTBHltRLiQuYfTrdnefFg+Ku8yhYNXwdBBM2M jLySws7FbS8T8XQxG8zbPh9KwLW+DjPGJ5T/KYSUk2123qXueIEYw4Bo5OJ0XDK3ejbaQFCo ViYs8fqghctto2nLoUEy3jCxXf56AVyYcKeBB08+R+CLp3+BOKT+Kb+F0TmrfRfVuSNBeEHR IzWjGr+JoDgfh/YCIgm0sPULQjvlUUbWIHUVqajmKBAVQbLOIPpzxJ/iv7UWqRLavBtJ/cEH kELw+w4LTfWt50+cUJLW0OWwDVWQkhCTLB3oYcV59jC/b8YCsBh0ngonqgBZqISUw+5bE10l 81j9+t4vnyui7HXF8mJL/HbdA7wdNR+wy/75GDevmv3+wHudgawglkLukeX4qT7nFkqJOAP+ lQwe7AwuurFERUOoBMcgYabLY/Nr/QPJ1I3tj8fXXMF3aEJsrDfSm1CWs05gw0wJITIvnGmg JSWDLjlUtixAYoY5cLasnsjte39idcarFT6URgj6zwH8E4sri324nEQMIY7U3wG9gnFUY3Rl dth+fYHo+O0Q7rgkB3y1SAPEddJvYpqPx8J4dcNsgysylJYA5kahe7FbMEk+xedsfVf282gE /+un4wPwhEALKifgGobzXtZJb+gkhcw4VnKHL3LKOgnjKac9dW6Nkm6dfJqFF7z8XCnte7xX CDdiyRHO28qnN3LnZiZpsnnv/N7NnjJ4QRd0lMLO6P5sv64YmGKKan++zoWP5GMdIwO3VuXi AMIjzGn84xRuEXLTalXbOO0Y/m7/OSyGBLMKCOh4DST1OuVdNT+QRMrrrP11swLRER7M00TW 4xrMQo4c81hFk04kihP8tcOWnpE0GTZZt9Xtg2hRK4ofXnejB3A3Q2prpOplVGQoHr6AvMDv OCwAPxuUuIsbebMLPrAglxzKZghNK6OCPJdgX3ErMuYPZgstgEltt3OMvRID2HScI4JeKS9K NA/xHDoRlUz/MoeafUMhHjajK/080bMYx2GRmfCeFNbN2gQEaI50FACR+wmd9jfBk1mxqymv H05ERC+br3uGz0x93/R4552U3n3Pa0Clqx1pTLAZDv9VJS/6EAtY0I32aIGcapKjpQgyJdXS hetuhf1fR1Yag0yRc6Xx4e8giZ400gU72DxP8huz+z53HqSYDcBIYBkoSbbK9dTt5Ku5wC+o 7LKYHrheceI6454izpzo7/wyhtLcvCCa95Fb/1iEjhEC/qLC7iETyGBHZcgUMABwrggSWgrK tjPQfZZw8ZBes9k6lGJe06LhPlBQQbHphU/mdpEPea03mHjdDtC7IgC+ZSJtv447fo7ZCIsM 7wrnldGQmrB+lTVTW/+JKYyHA7NMOvVjtsERt91fPdvPsjGzb85bRF5MEwbLXECdPoE5XsR1 7tKaDjS47dVfyRqSCMO3WsUH8ceLzjLv9gAXbL2QQw1ZuqJCd7K3dEklxJ8KRJN1j0MCCMlV k+Vscgw6l3ZBpQBSfqTeSeD/jpXzA4xxsAGV6QLg6kUXplaPi/Bjqwib8uFrKiMeE+I+mjKb WGyT3mfsiWZFc+Zk7QfhNzaoW6PSdZ3umPE9r6VL4Gt+BY28w+V+ow/0KGa9mMHQ3fVZZamD c/KP/KaMTlicHGJP/G9/q3jgllBiE5edeuHUJKO5z9bJndKOjNV3JvP0AIZS9hO7OL+X1kr9 tjW07XvRsZwMc8InBe7xPjHLzxcASqqA4voVxwaI5kDkDcIaSED++KI76vaWujZTI/QCLksZ ru2yrlBmhI55+tjvtaUiBubO7VupUP+HCnl5ipwLKgvKDQBqlJwWG6BVYsCh7gACoAXl0i9i x3KzhZ/TQzZs96Ydw2BImXYZVIqiCnL/PKZdd6ARyLek2Zjd/dAawBU2kViwmkfiqMulXoZG sj6wZ3XvfFRVs2nTLk6PBsidR558xZgk+Qg3PVCLRcJii1lfqb2s6S/rclUM3eDuayywwOd+ rOXoJsxh0uZXvoyWcHSG/iZo+AzpPgYozqiT2fPjobdNaH27qOhyAGZur6Ar+ixA1s8WbpX5 eBRy0b4ecwSUuinklrY1YhHqp4BBGX4PDZXQ0Au5y1zSVbM4oErYrIj6Jrxl9vdtpcoGxUDh 45ojVbc7JyZC1hpk3PEJJFIr9DDzi1VwFa5AeTjZsEUOPEaAbSdkkfiht/9aHcLsBNJYcVwe 55AFHIfZkQUhUdFFrbZV3QWz/Tx1wbjH2V8mjialjLYKwBRL/6Wv+5zVWZO3xRxTFjCUj2Qd OSTlZpwdewrm3x9k4d93Jp3IFvJV1ZCly3/FY5P2/gSrP8Ms/CTS3hqMD4dZlVYD67UJsIIg rkQyrhJkPkKACLdiVitdlhKKq92QlSKMPXAL8f0Z90pGlWZtxfTTmW+CIKUsKAPiRwNQ8mIy fS3nw/18Y+Ac6C99MBDbW9euc8kW4J4oO81SPc+Tfd+XaqT80fOu3dYCX2bZVK7hzanwFf+6 kSkHTxp5isSQ14kEh9y0QPzL4iGJuJCgC1UiCEzLRlBwVzc4BGPJjZhmwQQAW5LW3hmrgv8b To1lMSe32OvgLaIflHTdrjzmX09iaK92vs7MMfaQy5KhlHRJx3hRuCG6ymulwAuDdLtcKSsc ri5o2BsucH3cuRLanpbbQz8nFVAgGWc5qxFFJMghFf/mjH2QPWK9gfQb6IiVtf8iFrGpshHE JL4XPF1gn0U7SdLmTjg/A7y+AIbDmo8yuI7BvD1nyM3zpOS6HL5NIjOk6gCOzKD7CdPoO7Ke CwgMceggTVGqGVbwaXJvM9DJH7VRFBTUsTni74kbtJbUiqDND8XMKUd02i7F+alEXnNEua2z CX/2o/flgWYieeHFwZuOiIkzl/4iyZdd1U2raVo5wya4lPNNepmUz3BhZ++F/V4MgesTJQbW 8TCkq8it1XwQ3fPsgGBIuciIbem7WRbT1PKVTsZ9G0rR0db9WoVKcjKt3Bbp+HOrE8X9O4HG Ne2GdTEla8P3yAzlt8FdLhFj1/rtM8SDpmwzjDMa/i+8IqEo8jNP0ar6+URgGaP4sJSgVFx4 acDSUDlmoGSuzSTPwx0mb4RbGHkf17lwoUanTbnP5RIJmPSa+Vuqr95nPeuJbHm0EInTi/Ps 1+LMfv7ZZEqnVtuhrBoWg4ob+RUeatxcZDPd4QgckzQz4vyuCPFHGRCqx+Vo+P+Y40rCfNJd iMVQGLuI2P4GIATsyXTlGhcPR8yaUvmMwpKF/iLp2HW2oYH2GzSaj5d9L8INJGAJc0lDgPvQ Jd7ed4xWqGSE3bKcKAnAo+VzUGRD6o9gyX7ORdQEP9hyNzDzRfuZtVr6MN0fskpjXd72LRml t8fuqw17Maj7hnojYmJhya9Ch2PNa5RX6co5Wcf4/IfFbDDyOoZOulnnlZPynLK0cltuWNJm ASZR8DM5Be9fxq79lUJ0I1GZpNM5rKWOu8CwhrG4NAL8dPwlk7/9Wpi0poKq7JWlflq3OdP6 RlMDE/sgIUeVlIVVYBtqweUgXuUMizxiP8s4ZH1Q98Xxl79TBYHsupNBJzUg1mmC2WLSrkXT 1wmvt0FdSu+f1v58aiQyczk51c/vbbbcQJR1T0ses2z3LSc9MP0YZQZbXJTblNtzBI1DG/7X SvBHnsTY0FXwFXUqJi7FzruAJ90yHM1cq63OohldpwUUEu02yay02VYFyn1qMoHOQt5OsApT 7uGDODVx6bmnAGRGt6YgxCg026vAB7xXnPDtaUuffJjRJgEfhzyCGBBq9wUn4wx1Gcd7IVd0 HHCdjam/DiywY5Ldfa0F3xgsUV0IVy5arTAFouAGrFmmD7Yw2JUkFTA46g6WSf1oQ2dI3i+c SNgkMYhRpUHEvDqII4XVxjT/uFH4jBY3NGqeXQTCvDnqGw3JY3SyZMFnb8OSOC+3W9CdXLv+ YzaAeh0Cwf8qCrnK5NyiPMSolLqKiDMhB/dEAv4cnxQ9AV7kmvDWTzSToV4yJSBuTK9Ox0BL 9Vfy0iyWK8E/smEC6kCyvYtbIyil4pcqvXlfGaxXiHNRNEi9DJemuVuSgqESeclQS/RmqhYJ DK6uyYlKFdWGKkmwG8x9uETOZL2e9/nua/76E1PIB2HjedSq+Fms3cavvYntPGvzhraVzdSb HfJAeir8lf1iqEH0T5GoGryRH6HGzcnom2+KVkLXdXKmqKJIuYMNoXteYn6924y3A9+ukjIu Pq+1g+m9uZ/0DfsFZpcGNDcDglEX6ReMkkq23cdx6+sbpyADE7DBQaDt1DVoXIFgwyeTH9N7 I8xODtzGwIw6WEHcTLIJbGmd+t7YnP3y1n9tS8XPiWPKQfNhqE9OKXrKoEvtjiU/E66qamoa yvs7zwzm1D9YV7STlwgc1I1fXAEcSO4v3ovhLR24iI7b5sTOe/11/xjefYaOMe/pzVeotxJB fU+Fy4F+cqSSCQF5szMZX7r6xzwr5Zrs1XUGlv14HkA8+EaU3wsMm8/BvydVWNVMkIXSV7kf X7e/QTeh/dmxEs8h4zzJbb3RG8aFpUC+KMpBP2LqNj9hL3ICQzPpU8GC+Go3vG9xF6JiY3oU q13wS3rOVtvtCMTXaPa8/W5Ru/yEmBd59/0wqF2tjy0TQiYhoK0zApJPUBgMzPWlKs7cmIdM 4Y8dmq3ssmVCKi7Xe5QrGOI/5DkQQogsOmo+2gnhUq2+myMDdRKvHCfNNm91YYZrhu4ydh3o PgAbZJjohiUaaFkULao0VGFY8duX1n/bwB57M36TxVF6gy2AMmpR46N9iR+fXAOLX7c+ihkE Y6tCLdiLF/z5FguiEimjnuXlDo7o+dkw9vMixd/a3HViNjSl7aRLdOjvrBq//tdlsHi0Y5Lk PzXgBd/RQP9KA0Eed19bq0Hgg8lWUhqXgJqiwO5o5cPOahLbiOnM7CSL8fgXQsyrIAoteNZD BvCBBClzPgDvwIGds2AQ4gaYpheAJo1/62jxgm5fXFuOtMge3pWR73VuW+vwuXjnZjX/wpKq AjGkxM41PiOXtexWWpI0uwVqPJ+iQO208L3kB5yGncCItY2ZL4wmrieS0lsTMa1EUtCr95Ai ZH5Jh1iSZqgozbKU6bM/mEkRqWh7eixBLrx3JKuKiWjYusOR16kgESa8qPXUoiXDfDbEzEFq NHdcubrLTknx/OAly4UopkYDUC1mAPhEEt0TCrX3c8f8+kz3DlAnkBvFnkpm9ghd4qCIA7Vc 825JHPZSLm2Ai5tjUIULKEwx4eJCIEYG5u7YzaztXsObYq25V4jfY8Xbpy0w9d1ZXVfh18pD DNgrBDZCZilx5MgMH330UQZ0Qg+3cFLNGwaNeZRS20MyNsFD1nFY70+1xQy1k7AxZWouBmv7 sM0Dq1Qs0GsT1t31GVriG5Ct3VbzVYr1buYOvK81eKLM/5kEVO9j6djDo/jS53Md4l01WF/j 3obc9qwE2cY317RLAnDIzQMTGF0Y54Q4Hd2hbRCHktH9rFgtlkJM+/V0oV+kMm51Vt8Puirq T99pbuvf7IQIDWpbuSqN9TcalRcANkDBsZynAYb9qSrMkjB91cOAA8YuFYrB0aAyp0XOhf4/ i3YTmNoeumvybMiD9PqCdkVp4tYPc+SAZEPYR202192J0gbWlvbMOPSG0L0CILxfuXPIAXyY StRgVQ8vwPy15wv1s8GQO97YoT1gN4qP4OWttWvDrimKIcqQexT3ZVemXHRrhp0u2DF8Jd32 ClczvOlijBFP6eSf5PZz4dwS0e4WJU8JsF1WlDxUitFT8IVLbiWTZ5ZqfD+W30tyCQMr+ey3 SDe4M/JK59YzcC6S+SbgTWJiPYzoEU6vsRkB5M27lWz2S1PUrLlltI2+2CqXBjJxv8zwWjOK Ny0nZ3R34/Fv6+8bEVWHg6HwgGfZUHcewmick0TvWeQAQ0rMkXrtReX72ENqRYjIOFhVAPdJ NRTq0QDpAisXZZcZVnlscAxz71JYP8Vo8bAQiZgbMTy7xG/mMzr5DX1ymGmtc2UGwbVolaRj xz7IpGK0iA4QtNNDaTxtT+c/9kjzM1sPZWytgnGG5t3sZXc/oo29anSnU/9Q1XoMC3hxLdji OEgIf/KDaBC+n3rWNnqwRr8CNhVt0hUp4n2TohPaOBvZU5o047+JkeVwI3eASrsiN74EU/Xl 6Bx0sWn4ORt0CBvnZMVv5Po5lBjXZmqXaC1O1eV+0rlimM9saz6JCzowVoRR7mZA2jQuoBAt cfFtWCmiX2PLa7GtKx92Sm8uamfrnnpttnK0JhriLfpK9a9INTS9eCGkGCpr7Bv+DpGPb6T7 zD6JXwdR/d7iLrKyiGdAiVPooAt9Zj3Q5qXWb8otECi/FNUmUyULWxmKkm/iXcyhr07YtmDI ZLafE4v8LQXpShAF5Abx8JqORqoqkDKNLc5iGI+z7+y9jsewjQnq0aM3HyH8jX7ETqCvKLLy G7pTGz3VMmajWFrSizMbT2fhCAG7ZpYsP3/cTDC8/rwhsCwl890Dy6iFQq9vGulsvLGXxOs/ yQjXRAZbTvzwviX6n+zJZr2FxJPqvNHh85029nfbIKoqByD63sDlwVEAMYRNe65APUPABwmR NwypDFp6IPzaRC3yI0O9fS0KKKQADs1AXilafZf1Ab/fuGknZyIN6tOWkj8rvFYIQ7szc39f J59HO5NAcHDGg806+5YDZjRaVqW5X6Pw7NgUL7jcREnzjRRgdoV5XpoHqmjRDH42qhW37Esx Y2iqpoiuIg6HPhHpy2pJaz4+PlpIa0SyVgpRaiU+GWW696RWHghftZyPAHpGbq1EzXQAXdF3 d+eVu26jRBhPOI17KaS3WAkpTuo7mfbDxV+PFceD3e7KFNWI73spGOs1KkS7Dw9eeBtHnqZv ZHFeeX3jwJGF34Vl/FhRM4QNcPn1wViVbn/RifgAXepRgagN/n7Tiey0hajjgIGQM2K2Omr/ qFzhxKosiUuCQWqkwywLGGYpkhu2yfF4AxNrXUaSyJK/tOD9Wy2f+cTQOHSLHcWkBzjnVi+7 hk0EU3aAzmChn/7IK/vTnG1uzBox+pyLzwkrgp3Eb3jhfGY70GyOrVxMdxeGNISXx3T+XTO3 yiz2sCTUIZcpp0RmN/GyRmVl0995H5yr55agV5Pr89gDkQCcFdntNuav8ouZowMmtoVEbox3 Zv8QyXwK6wMQ8ti7lm5MPzXnZUqkU8I8Z5hHcN2f5NGAtF3pDvSRqzXyx8djUDCft6bLVdNl FOQy2z1eCtsUUalcXBnc69EwweYhe5MwszhIoN43CHEn0eRuK/rRvBlNg/iJnxkleReYxjCA xjB9A3yb/aVRSOaQrCKJgNP4HkGRcyuOgHtbK0AzWnZy1XyqraaBqJa5w0GwMmR1PicDVJ+m ZgRHxxGD+ww1Ao87RsTXpNxiYDfQVXP16jyOh9zYh44e0u2F3Zrjkwde/c3IPhdV8gifaGiV YKvVfFd18CCyx4cO1EyDbPKzslQhAbox79sBRTD6PVX6Oy7t2MiyCPyw4Mr7+E0YzRQjUEwW 8HYrCGZcC4BZK5wSyc7tzipSjVpCYNrt5JO4NigfccTFUBL+/0v/THf39keziJZox2+8mjgm atNBQyExp4SnjbuwW+AaqkpdwayG5JF03rAIqoBS+ODTu13RrKMouzri4Ci4akdInCA893Ew Hs1BOk/LlvfKWW1VjoSlk9n6J4yafGRKH3HCAnhnGNX9TV0UQtGVJFpPo2hzHo7l6YdMRCmJ gQQYiqB5ZeQ06ZLds+aur2Ak0SyLLSqp8wOVj/tgvYbIHNAhAdcGPZxay3qSpynvYcD5Hear pi0j1ajTQsKYoeflMPVC7+8RpVxQwv0DFzpiy6/iGjHxYski/oJaG/3cMHMkMqiONaz0ZMhM 9tL5/XJ03XvKaxefQ/+74dFrUBXAYkpC13l5MQ45D42y/O50INrk2lLtuuoOYGuTA3XVcAuW 7H9s7TP5mHHyY7RuOoxtHJLL5w0ked/xlfFDBn6abl2zKMjlH7u++64IDxZDZetF2EOIIfSW /mp1coPQVKpCJPQ0e720J5Jy9f2nRSUJegkhBfxOhg1zpaSf4ghJ7Rq2Yta4opub6MlonUPj NjCz6Fu8f06X7WeiXOpOq7ydyE+F4dIuzIycqCf3p8iEV34BRktwEOTCIFhUwK1sXCkDzVjM tttxPAgps2L/vlXdT6+X9HezI79y3A0WE3VcbsJvRlYDMiYnYtYWPiKm0rnttLkk7NVRQup2 cl2WFtzd1Az5cbUF9eZPufR9VEW90lDzp/veSOsq76/q+ARQgReUqfZb19BQB+AKa5SXbFzw 1psgD8ckexpcqUQSy/gpa2AYj8SjaUXXajf4Al9SA7Duz6B+y8Kc3DW4kWPNNHX0BUARVAVJ m1BwSbm/4G1FCQQTdedJE9R58raQZncCZxW2QbQw7k2+D7IMHSZzt/AgiNkiHxfhaHuEaQ8C 3WOLyLqoM88GrURxUYtrsSMK3kFPN3GSPN/w9sCuRN+E69OUEBbHVSoI5KY/jbNZ5yNLTaHd /Tjp1c8lmkT96riHYIPTFSjJXNM2x1QXDt7miv2rmLpt1RojneDAMaTUBOEpu3sWpbTifOcA ihFlLrgbjtR6OnxjialefKj3RAN9IPBj0rv4Nw2PhD1cKh10GwBfJAgmZ5FlTG6WQ5NdDoZZ Fn+FEwyikLoH+dWUpu5DQCbdEAqFe6sXgr7PkL8S7XvQcPVZJDdV/pu0ZxTIPZbwuMz7xZVU e9ELxJFTigoPAeGJZxJ7hTeCV5jDmR1dHvmozNIbsY8fB8RYc+/2HlgGDG+DxpB9sXISRKBf 9G/KryyXEri1iUtckhYlSfds8U+y907pdehPEiOdWGgiW3Q4SDchFV/b3hiAp2PqDcxHTeai nY3mvLSl0J1iAjOKT4zMQiiyjV5V7eYEoNuqnGq96NuVJIDiR/JlLo4QUxL5K7GpAdxEs74v Mmbz64+e0K/9sO134OouJqQoUdg8ISPJL0OC86tCK6PYxcgv5gG2rBmPbqVeYcB1f0Zyslff Uj1rCUOi/EeFDRY6Bmb7APw3OxolTXv6h8Jc+Ey8ViQJRhUnd+YAATA8/NpP9n9mmUitvLQN KT6YB5g9NWjHT+riYqSAEiSFTHvSiYAAISmYoRJz3UEitMgXL9Bfau78YQefp6D1VJjMadTo /n/QMddPAEuUtAWnIu9kpT8/B1CsUJM4vIoZqlJKTj1O/nS7Ywlrgfn+MCYeT7IMHUdQBxXS WXHr2nwFugK5rLB7HpNW5x0crSyAQlIZMdiLyAcjrC2efXb95/ih0oZDOHaPRO7QFNKViaF2 8AxD2IFB7jHK1q4E2/b/va9BJqGF2Nt0SNAiwZNbgFLX1q9jveP7uVRbsnW2py+FEJP2bJMG H6XaZ3B4sR6AZFPKm2Q6g0qKUlIa4b2hEvxdAX+GWn5vyWl5h5s/O0sujINkoHhA8G92XixV NlfL5Uwi99pPGza+NJZlYw0kaEalYvjW49AQ8avoRkOeeKn1UlygKYeMjrTsAzEvgzmbinvq hB4yC0+QprEeLrxIomeeYPvXQW0BXoAgdVGTVvppyJ7KkgVDaSMy7rtJCgL9Wg4A8s1JGpej 5QfSKRBTPobqA9yS9toBGYeHwRZy8yssZeifGmTfDeYL/01L/UaO8ZLI28PxE3izysqzVP/R +UK/seNdckiWDeVzR4BiQWqxveDRpQAVkxr2C/dU/zkfDpk09AyBzsqSRJHo7bloS8JGA042 YmQ/IPjtlvZTLfCne9XL9tEN0WuGUY04zRULWdpGr/VUivjWTtxbTyhldyxSimljlmUNETyG G/VWXrUfotwMrDuGJG7lm47jCpMpSqbNt2S+xmMlBePUadIyVXureCkfA2f/KdkluduI/OxT TLFZxu7185sm7xaBWCZvKaazN9SZA+o0WL+V/lYLwIuCE15zGl90O+dK22hOrcQ5D+YdoU1f xectND4RbKCzVNnmXYsZcC+q07fee1iAIL8MoSqsrqCcrZ5RAWuN3bmFeNcSxspRdKfipLFR R+SQwnB34TWlRC8zcf37kZUuuu89jmHvmWpTu65z1/p9tkYvTSbVe7KIlEkWCjFdVZZOhIx0 0Sli/zHs5+nhZGUFwXgTwh84WnrqbgdhEWlQ4OdA8CJXy6XnHX3ru/rssc8tvDpPpWDuZ0yB yerMXA9/2FZaJQrMnie3Fw12FO75FH3ESoQ3L2jZsbvvuMvhh4NYwcooO2qaSI3L3KKmcQcn rJwhMypJaVS8gNYuZ5WW6T5oEi16GpPugiMJ2FlMwOOsYwZMWXMfbjHMckqLhO9zpfbBdS4w 30Vw8aJeUDePToS/l6r9CpDGpOQeKVZGiYHVHSXI6If4y1tA9Vvl9orsSJGlSQPPVDOfUX8x aclg3PU/5I6vB5QqjAd2jjmTTKri0eV3BjWBXpUWHvVovqNG/9Efzaf7tkP8xxDrG3driUdB xd8OxbJcW5OF9cmc0OnujkEf6AJEwd/LWzN8Xd/365vDcsMyNGXqoqbX3BTuabRA4kljg3rJ MEEaxxiuPQ0gVhgmt1Wj9JzlB9bHzM6EnpCwnYdsVCuz4KgcXym04uq8ol9J2f5Ogi7rZh0x PnzSmvLyvvJ+nij7/zGMpbZpN+woeb7y0wyEziezijDD7Od8ewcehFSj5GnBWk7kYIOWRf8C 8uaBDDjCG2XxJWpRPSe7VJYs3o7QcAUHE8w2O2y5MrNd5matmd6LOKF4tT7T36C0IqmNMT1D Z/NIV3FJfHlwCN6hCkoKIZB/OkOAUjzTWKz0jgkkIO9ZjZc/tiokaaSawRdkFP0s2I7wK/7/ QYJV37Sunqy1vA9nnxAARvUybw6Z0V5oHcppLeJhJXkx8WrlKJnytb4Om1+cV+4QJitYiwpe xgM14qLq/cIlThRwbgEgYbi51vcBFd8brbgUanntBkkILW0jX1umg8KOR4fwQhapZaTZrNnX ekzFcCBQrS++YQgYzTZXRKlvKaq6ao5zxfiAAgbbamo9Xug8qF8uOjnWsZ5VtiUZ4J3IclPr 969R7Dm8xu1qeDnL9M8Xld+CQRJDRkJk3wyQn+kJFA5ZY5n+BuQAQ0v1QwrZ8l5HnmJgTNQ/ tgHTflr4+k87hi1FGNMbk08B+xsLbDzxwCJhVqFJ0WKNFn4LRYvlSOjbaTFj/CRpVjHl8RIY fdjkrE5eKS84G8YWUOSZ9fz2z/qsrASTje+zQnk4l8B4LUPJqUlBtp41wmL1E5NSIynmR6G1 RtKmdrG2MC0gaIPRUjgd6eGnKlskzSw9ix0ppHu+mjeTwOgvO5PDw3wchyirE2HGFF0CKpgc oJ5vX8WFcljdpIxcX9MQnN7JR1B+U6MhwFz9DRn491pMWnLiMbVpt3nqzP/vaxxwTwrKAILu PDH7L+7S15GjRLlVABeh1NtzvCJPxLRnGdmDMRtRbnyQpCAON9dq5IcbIZYO3sQCEKW2fcOn oiZAjZw5G0xlybJ/sjQ1RGOU+4AUiRiSAYjkXJgrFGFW00PPuOxBOYGL7JedYY87/T8Pcj1h JjmCUHboNA3zEJm+nM0yIWNwFt0Qe+uChPKDuHtTHgfKtCMYFsF3yarNIziJnXGSJb8qM4rt yFsVKw0VifrKH0Y5+z3cEsUUX0kTbX3NXw9TNyjAyllFXLYQ+jpwEKA4pvdxCdbINxtBzxay aZgRHuADJ5RNcpAC4YPXoh7WTSQJHK1n7hC6mDrP+jF2SLV2v+/kOPqNYDVP0uzlv98WHf0d nG5W0q7bmxSH8a+CXk+ldHXpG5NYlh03FHvVIBSVS3phDZLZNsRkDjwAtIAwIix3NFqy029w eHf4m61c/eriZe99fn7UY7pzbDzRxZzfuZ4zziMC+lxMF73Q6FN5lxt2K7WJ4VnZMVUt5CHT /7/KutDlgZthlkToh+Y9hK6JwK+65xExqzsVqamQU71ds5t6iQnYPlE5FhFROkCUDvtLNBEO +LFe5WDx/4TGhzYaAJUC/DRpSNMM2BSnYEjcV3KdMTwXBGgkPwmtqAxXR3jmOaK6vsGoOVBV 7oTNqEjvezjFg/exMhxkuu61CMaO8Vi20wT2o2S5kEBtE1Y/NjlWWbxCviqDV44Riu2P/CVC iXi62CdbWEKC+HWoeUSBZlKCXGmYwhdaT9EN5kc9jLG6dt6S6F6cVuRduSpCVzFKkJmBL6Ao C/G1aPkPEsNJ7YhIkhQH1fyQGPXVIT7RO9KBft3rCizeQOZwMncX2laH03DFv1ft965ydl82 d00x4fVj4LFqcAK7S1UeWLpWopsl2Y6MAGkgeyUV60w2iWeot66RzOCqYpTvtNtde2szVV8f atADC2VuzIvJ+CN9/a4lksnGEGeeKisPo+fR5ywWwAEQ2M6UroAtlVLNtU1VOYcsGegiBCCJ 3bra/WhW+hDEh2hmKH6of0mNRjHf9UZEaU9q6A15Mceae0+KALaNVD8KukY3Wqf8AWRNmiHj 1nYI7+j5wBx93zVYJ5jiEuRLONlDDG9DJLQqcU+unPn1c48Ff8iEGHUcwzQEYU+yF6tQcuJt BKf+PfJ381QOyYmg+ikfnJUzvs3dlqoMVKs6LErINqa4lACKIS8Vgq0QJAT2NyTut1jQp7aX DQh+1rlQDGWWYejanM1SzSqOFq9AROKHO1r58NgeOB+QBwKSfp9F+qnyeHv5BF1fW7XjgTuT Epecb1GhJpeuV2Us1weJdUgasRuJCAWCGYDy0MVT0cl1OGmLJogi+AnQr3HrkcoHH0kbCGQY cBeVbAxikz4iaiVsAyvLLEW7Mq+3UQzi0DnK9yEsFZ2SXHU02RDj8fdKl4vRgOb7BM70UUbw YxhSaJ4PbgjH4qUuo/Sf73k/b4SMztEZTOMmwMLxHsH0bzyGm26bslbQsY6k3Pb7/uGMEJE1 0XTvJ0rryaQ5COH4DLNevn1F5y/SlHL6WUxxg/xkQoeaO40QLd1Y+cOiKl5d0pFdcu/DnmOv OA36bS7DdsozxB+I5e5zZ2LsyLHGqaQ+/Uh/MViJkbd2x7/VvM9/qn3MjT6hk7195fRda11T 7/vhY0an64PzxiEy54s25FI2kPTj1ewVpRd6PGnbOVyYWzAbKYQ9RYbHxkXfPri3KcnimErc hYsqHjBT7gB2MrrJQgciCjFhipbElO9SOaVp5UKq+D7YUJjBtpqr9i9uKVIYuDwWP8Z9ywtM BoRp2Fh9VBixinFRkl52iMafuAsH4w24sYMWbaNh2b5A8LtUGLpKinytofNm/TFovqDkEHl6 IgaJYwlDSA1gt/vx61nDh2NJu17nz699O+JZ1rL2dL11KLHVk4Ezx3m2STFVTm3MYbs0RgOZ m6o9U4gABcvpX3V2BicfFQOp2UeinQT7Mm+IUbqm5hlukVxt4DeITsTHODTonxJsHYDKGHA7 s0Q2Xb2PqSQbKt+eWCj714vR+TNk2G+Y2O7iXwOdEKTyxQWaUudOS1BgtgTckOG2qde9O1rW cQSHoUOZmt/dJY3iVsdczWwn5d2XpWuBv90taekNmVvx9842h+wj8/gnBy4zM4NPrsybWjsg JBVAHXjS4t2d9aG6zC/FknbisspTrECl827swXHNGbFpSs35wU7RgLaHxkyZZATcbYEY0GC/ lcZ5mzQSdazk6toxIxIaprz7JixCQePfzZ09a+H/xi+J7YBA10IcYtJjrOCqROGY5Uqz99lD Cc9xQc0eNWhNZ/5o75ONvqW6eV46uNihESjLP8JLJjawIWQHbrymNYgD9oAK0Km7tcEVjiCb Of8YqVS3W/8T0Ym8gTiV6pH7Xwo2WHFWt4QYjiTYV4bynBWrM5Rb51AcOX0zKHg3bBBmVthZ 8MvwwuINotX9SigFsFlPWXJK+Sc46k8PIVDv849USqyIPIuxCZ0IWluPXFZff34mxrPlwLS7 TyHcx0JHmBEapkP62G2osln3aCafmruWn2vWvDXxIQczEoiaf4NLzevVQNi7/h/NHMlGLnGE 9ezbCIIuG+Yk1sTDTocAZxyNm4R2R6yV8YltoYlmu24OrsEWR7nGT20UVscvooQd0EH+gDiA OtUTV+MNOne40ESImZFCg1l9JJ07JuH7S8RHPwofnxAU8vjo3ihSXE93qq+obLeeC0EBDAmD EuOncALeNUven0qya9SJCwRY2eTGelkJTd54lv6omti8b0GXejG42AAC8Ra83OjAoDRseiP6 SeNdjsYm4eZFuWSLeZAl/faBH3jn7WkYt2BxqiybdCiPhZPNIHaT7rR1KDQFZb9uEwCtJReU iqD5xdNt52JFJuUQUucuKC9E2FWqQ6mE03PC1apDYEIio4AGEaijqY5uALJvxD/C5wsAtbJQ svTu1xukIx879chvZDCu72FCgz+x4dOVdp8j31U4fKUzEWHF4dEMVqecPVozbAzcpdjlwJR2 MCYxPG5+Hd09iEHgIJmjmIpnT4seFiQLDCCNckhY6hTlVFhUBI7InFSVcM+Xq5MLYTV35M2T CJe2ZlQC/aeFHpiEXTxlEeohTdkbetzUUu6HvxR5PrUJsbc2Aa3ebboYUnlCtNVn4b5xMwQ+ VmjEjEma1QK1hOgynK0pSeCXvynC2Kgl1d4l9RiTiS6pWWzkirPi92oytXLAjxexFm4/bmSG cVXTF+n29XUuQFqiRVMQ7ftN09GhwAvXK6YQVQJAMD3a9r1oRXHE1HGaIdvNHZGySAelBzmu hu/N/nMX4zbJSkIEhKlso1l41vgYkjcinzQkcqUTLNxkUeD6l7p/YYBoUL4KY7t6NtEQ9ZrP f4u1DAItMHcmV1NtDrQFrQiN/fUYIrMH0v50QSpkvLdTMVqU+tvBc0T8sr7fE0EuEPE49iVn y6SGSZikU1+spp0jbKspT8dSlF7BEn8+D8I/ky4OvNl3CaR36eUSCVZHdDm/hKoN1BOr+NJU Lno2emUkWuscIYVJjMqWmvVBBs6KI2GD+JbrIzb6K4mlaQBU++qJSDsUjb/RDVaTiuM3gu63 pTExKGy+8pkahMXfdinj6pymeMZ3POTYMOv8cvCe8vItLQlK2snEgl1KoY0kaD2WalajYT8H TwMPdaGmCW7uQ5SAA5PE5agGKK6rp0a3BWmcq5OaBXF3tYRRZP3YSva4U15yaKE3J7+mNewS VwG1qLrjHA7GPkNP4B2+e0C6DElRkUE8aA7YfGqvCOGDiWmPLBwelIxhpOSYkGP2oMmZen+E qAktdUDYwmWxPcfHWv5jLVO3gGGEAM1XqBD6OpXAP4VG/P2emGsyg4Vyvaf82oUW1048gKVU MXmc77ArvfnuPLUuANiRyg9U0EpZgvFIobITpsBJJ0/d6eIa6niEmW8GLnICZqCnDoAIA7pU xkfFKA/b+Wswx7CGAO1hlW6IvegYh54Rkp+w3e1dTAvSfhgFXP+rPGXnp5jajjyzr+lewSnY 4dV8emzdSTz/hUXIqfeDEBdEseX63d7q8WDEPY/v7iPLydosJH1fjjIyDmt7EXonZIRGjFN6 gPE39xgb434DxJqtSWr5/SOWUllKeb5v2x7hNP8Zoo64TPgGtnti2weuoelkQqk+zla7dWrJ reNP+MXy+2e2mr+Ho64aN5zL+zgipGATZHfVrNY1cKAs47gFB3smu7kCQJw/sA8oelyKSBTU TgP+lcm7Io1tokAJcG0ND7uquROIhCtmm5fvXnnFNxjfsF8dQsaYgIeeqp2WygeLaQvgFuyr DvlnxNqihg5rKsN56tj9MFEttXUaKoc21U810/IIpC5zUis2HHZ+bJx8KLnSp9qQw3hsO8w3 EATit5y2qDcUuMHZnmFUgjNruM7hy+rjjWrhW/Iy+eHi0fDtWnyKFbIWK4Q7S2n/Gw+C5xFU FUZS5uOKE6EKTu92CXWBQCWMc4858Zh98w9eMs/rXlUQfyG9osIfd2bPbOB0BMy6LB1Q8HOU MyOj4YARTKDJFi1pnpRQgAZFX7swYWX6sMoZcNyZnbeHhXOkhDSVHT5d/n/ez9LsbSIHUze8 V9fT/5pjse7lhL1x6J/2j0tFVvI4mjq1vunRAPaVlecB8nJNACDyJRwMy5yJjiNrlif+OXNe c4qw8BGc4WEb3bveih21up+90I4s6VY9CyRaZ5a2Ce1Z24F4bWL2O1qgGnVY5b40mmo03s5c 3WsevwxsDaQKOfHq6OI8ILMPYJj5fVRLZzVxkoy/uZeqv+bFVwvUOjKjiGaOF8qPF4Nc5MHx qFsOkQ7Ps4rVXtS0BkHWXI/uJ824kXpk8Sv2Kx9CvfZn0Lkj1IXziQcudwI2EADY9+GZTjx9 B4k8ny5JKhsBfZ/BHhAQL0VQffmo2mD2Tp2H4RqIMvwAoXfwDQWPkRk4jJuU8WTBoBzJPjsH 2tOM+prKN4clflgInShAvbuxhGPR/oCLDUTeuE/3Rui5I5poZAUGJZOzXIYGZumE3ecj85Um gYRky7imVMKDYXvCcIDrVjAZrkk74DLN50SqaCwRPHOc9SLmJ0il7XtalPxXJxZQXrGB0ntB rjzrq6oc3hEeLIuWQgP7iMzlQPAe8bMpWwj7GQ7TNVAhGPBmV0/aK2zhWrbuRDXEqXtUutGp 3c+L1RehJxYfxydWEtj85BcZoab9yXZyMhgrv+Vt8Z+YIw4BZy0dOkX71U5rrG1S1gnJpo/D pM0iVsyyC14hrLbMQFllLXS2gs2tocjdDFExxzsR45UDSCdq5xKhonako5/8GTOXBnpR6Clr Dx+GgsJhv5JekOH2iR0+XByEDWByphu6QD769v6IH2orZL+pa2q4Se3UxkCBiYEU9NHXZipj CflJq5qLHYKaCtnEX2iA3sOPzRaaSwUxYtkWWY7Gx02UFNkOuV1MDrh1M6d6U2ClcLX98ExL PnNDWl6fL3qLj5pFRS2JCG3n2Qae77PcmOizAxpEMLxG/PVtGhphinBYqkBqcMEuPhj7PBRO ac1RAkpJRzV9kldbBTDUdzlIvK50HuDRyvdvHDPv5XyFP0v9Ns9v+Jfr+8RvQ7KiDw9EUI1p ABcIM3xsb9vGX3aZBD1dZFDad3m4PWZcfItLAohTFcubkMqWjHxHzcCQu9MJ2rTIuT5rMRqV E9ZZE08hZvRkGb71ZuvsaOk8Fcj3a619/Lv4GBjsPI8PzZrH6gkXLuyHlkuOlibvOTKacD3v nIwZr5MnzofE9d850iy0UDy0UfoxtxtkkyNHStfLHJAWshVXdUCrmaGu3i2pK5owqtN2G3cY np2tE080R3P7MVTUqWp2kFUOlLigTWk4ybR9mVeSeBGI4CCNU5yRBU1guNPksA8ndk7yjAEn qFGTobh/kuUYoTufzyzQKz7xvqXofw+mYNbMtmUKYikxnEog3gaJ72ZXywsEcyUhsR+bv76x lDBD31zkuOPAXcGkae2h1MuYwYHspbw9jL1S/mqNmBLvL9ohrqtkn43y9c4twO/U8+JK2L2U JLVToR9oyjFC85JIZHMc2uscyJIrlrZtO/USI3sUkbQ5EIDVdCV8LHhBIDjNNS0n157e2Yu5 bLAmHfRkac9kXhUGl+DSd+Bye0/Rnr4y37z3edqwgjf7/rzPi+61XlvbRj9LmkqSu/MVCRx1 P0VzyLzrDszeYdY4ENTOiayaWqbbtYL51pBmgxo43A2EmsWLstlgovWvqJXO4Q7cgGYuYAWK AsRUFxxK1MbU5eMmv/BqW1UcW5xOlmnd6KuJL6MeoCjxA4oJbxshbet/A17YmfBj9bp2TqkN rnYNbvb911XCd3SLzkU8oaIX513XKZCRcfLQIr0T10tILgKBEapB9cC7beIMRXyt97fO11B2 /KyMpKZOOq8iV2XOxZiZNWZpuFp3L7eUpSt69zIyH8PaMDyXuGQuV9cRiYdoDgV7pkGoUFUe u60xlwiMHajWRVUEYVTIYpzzAnfP+1OWo2Bx4c2lFiwU6SZF9DSY1V+qJiwlgI+SbLnmbpVf ECM1Fqi79vEiiQ5mSl1q3w5GVkyJmSNo/BqWQMxukjqRVzxkMJW92dd8iFRDaMXqGQDheIqM DxzIV35QheK9xGt/dJ7qLxIVxq0rN+qkhVeJUy5ZC3587ahK8JWK2tI0IIK2A0m2EG7xGcoG OiEtUy/JCiSHBzNH2VgJb7qXRhfnAOyTqvt6pN2k7mk3mWtkv6DJ12SLp0OdwAtxilq3Etde FavaxREX4nKY83+vRPZQ+ZPKB+GHLmnYoFm39HdZWyhnI2bu/dR4I9XpC2yCmQq54I+Qb2NZ l5KzOUS2YaOdIEtRyncLC8MsZNOogp+RFkyoWtfar0CfwvPaV+MjySaX8I3V0FmInHcAdiaf 5i7pUFfe+shGc3PN32iMRPXillsl5/OK37T46OsYn6JQtf28tex0QxVMS77HfZCyACYEhwVf HSkcQgxoAurZvOlZ+jruViVTNdqotv0V+6+CCBGVZTgC7T+ok7iMFPcTcxcuuLzFesAoB+0y g6Gx/V4vg6tzIKL/6QRNrCEi1Qo74vhRk4m2C4pxBIIx6WhZXOG2cJ4mcS87w3BP1SR6mfxd CcfGQdpsXpxOZCxGuqhml0IzSrZA7E7sPa0QV0u26WacT8jTcknS6X3wrVosfK0+QtUBnGX3 4ASS3s/A3+90NAelup2eWvwSMMQANGN3h+vXqYZ77iBnH+HxZKvyC7CrNC/vyq2q0eIT5QUY m4JuJ2riW8mVQ4X3HT3gKoIWWWrujv3NveXZ4IACxdFRSTFk0gJcocobF6SBYs84f6kJP8n3 jQAN8MWCuCcF9gVMJcgazl/276SARuuRtLKG5mDUaNR/kprArhzko13dTUEqdExkbP29TOJe +8drftdTfaLH3ZqoNC+0t/F/F3bkFyvwhEWwiy+YFGRdeah/kAhN9LLUYK4OOyr10VNHg2am fIOyepJ1lwGlyR2VqFtnFvtn3FAzCpD25zifZCIvncdyVvroEUa+kgcP0jkkJQizDkRSCDiS dEPQzTHzTzf1Yar1Fzi+Zon8NRbj8l7sttrt3uV3MiZMMJsQkbxd6L4ew9tQp+Bgovte3hmJ XZqwjBdTLt7YvRSSnmirTvUtGNLY6GtjwWlMwFJIs70XoIHajOyNk2jZ/x9r9jO7LIpCbEsn KlttgOjTawu+DcjkYPzX335ekOy0Goc9yoE2lAV/89aknDpKIkFoLmYbqtnIog+AKz0wb/0p 9UAiE5D1Xo+I73EFF+H9zU1DJhuWfD5hmOHOOLe9dvIf/HehhNafPJ+ZmHiKdEXy/kAzD88z shHy3QHJGns7iml+JOiJ0aIyWOj8FXKVPkuHO339+A6x5P3y4ul9GXKxdGaGGjy+EZy0pBoQ kH0/f2WQjY4SoMsjaViJIRZ3G3RIW4NR9LgmoZc0dbZlfKktzbWVw8hjQ498SfClkU7utm9e v0Hh6snvfCfOHieS036QBbGkzAsKgbe431ujuyJLkhgtqlLLZYk0x1DdumJDvVfq1guft+Qw yhdKCeeY5o4R6G60RNhzsKYWBQHVAa+0MIlZ+/3ztWPDn7Plbhu68ZOETR9E6ryNV8V6t0xr AJVKmWqgP2ucxkRxJui4uSjhowETL65g5xWoPrvUuJNRi/fPFJeVzLvbyFASufgpkRtyIOSY P4XQu6F8+j67EBHXZ90kfKzzTb70Yk/79ZiMYbQ3azsez+NyZYRtXJEPyldeibXuwr4NVPYI 7wZVW4aGlUtbmXM7TLkHVNZXSCicD4KF7baS6VGwD3HGGwLtRltObCVcX4TOq3cl/7OZMyph CjjIhCcwTsZvf2IKW+gdt3pJH6PjGnq897jcthSxdRIqHzLZNN1s0bJFiRy7ZvOVxmwaIc3u OZPCH6E98Yri24CyP134uJRbMZ5Xow+tAIBWQSrGqQLCieMRWaudhJaacPL41T28IjCCdjVW /ITi5M0fx+8IuH7rj6SOtvB8fkjLBlpa4Z8z1u1oF9QGr3gPu15UQd5bZaPvLUPkRl/EFZyR 7jMz1CrgECQVzOjevZzOYMZ94KuiQJ13WXwnK02POoZV46GaQIr4SHsS41ZWrFvYvabj2d8b dgPvPOAHC/oe3z+RV80AeYZpRrApLzsRWPkFMxrcXZGYb74tDZfAPmac/ce4UTOCqfMt/YsQ 4PdjWBZ/mmDxCGNw2hlVBhcKUfe7ADyudxduAWrhcyJ7CmoNvVsIXyplFpCf1dM14dsP6W0r KCufQ3hZh0seZKKjxOeLPlyPYAKTqV9wVkcmMomBpiqKMEuxAfZAMrr03uLH+pid8Be31cwq OITUNlW1tAu3yrvSejfE8u+dMloom4oRMo9aq59VErm9nTEZRi6Hc8d1km1pEcvm4FFUep/n vPAwek8WNjqqmlLjpPfjPKRzBcUxp5kZeZv9AeFWPYkJu+ZO+2E97Lx/umzNWtixDxvi5byZ CiftfkQ/cJV12qLrbEVluZteGritXbwdfF47bsh6EucS6XHxv2iXjAomb2djwxbKFIsr9EnR gmAWtH37RS2Xe6uzNwYF/aw9G+44W3K5I5tOhjBh4iec4lqQmY0PKZHG6Af4WGro7f5o20+7 P/au2xl6fSrgE89hhBr38mvqNK/lUGqcl7zhyAPbFUBk/HLpWOjOUg+aOwUfGhHfR0wIAvgT kcAc5k7PbRrPvYgLSpepsSpzbPaYyO+3QVpEeivXP10xFOqCjLr6rtD8PfScSuXe7YXhigdz B/iKqKVnur33kuwZJU15rUE7TxsvDwGpzAaIsysEZMPeD8PeHe1/rEHArm60re/GuCd4Mh0T +iNM1GOaeozAIbEfY514My026urLS5LfYJ9WPEnwODgLeSB8eZLoTOSb/NyjSzM8MBjjfDEE vBNfh/oMkCjFmezjck32aG4X4cLiLX2zV1Dp9UtvLNmkYBYJujTdMJw5nE1+KxVtHbR/g3dw 8XSpxmEMbKOWf+rHsG8SEzoxe/BKKGIHUOOgbSS7ibzyWGBmDYqDAa/Rtnazp6n3jhROdBiX PGtFgelx3psGI/1bd0gmf3qzuLdUbAdAdq1I6rluLecPpUO4Qv+TGeA/9sxoqPuBE1DOjjTH F8tIMaJJwuzqxHRXeQ+/En7RBJOUH6XPi3IkMm8bc+xw6N8X/rkzGaL+f62p1jH/g8uN7bFs JXfoyxlReGbHOf2F5vrTPwyjUhYTYEwr1SlxiA846KF6scINcrRNybSBsWVTZQF1Wfecwefc xKxoR6gANzq+7Jn++Ar6ZxJVfPpfvNINcbdNyzoTtFQCh3sVI2Bnh+VwqcqBb+V85TX+TQIS iMG3BmvIncNnO2tACHoMyTcLQr5mgTOxzX+E4qhW8gKSh8khc1cVc2J7AU4d/7oaJjoY/zE2 lN8xw5FSuoe02qKrdL1lUs4iR872EjmEUEz7/1Q8P1wkkSOk3tMJDrvHoaKI8oSvmYOCGGcc MIYu3zGKQM/VcbE0IHrZVB6WmW/fzEYBX2OXtQEKSojXl0DbgvlbOLc5H/nAuQqHFPDJ/cLU AoNmpsUlwpPx46WYOv437fcWG0UPM6K6guPd6FoddK+FJrEYGvymzSRyG5P2PifuMwoV24nU Z6pIcTRkliozd4gRjio9H9zFns0xZcyGP7zRvy0OBUjN5id/DVDJYRlH/Ag/Uzj2GJyQe16U DqFwcfUB5TeSgj/EwxuUBd8RLdT0KOy835/roh3ZZmS+z6cFRH3kOL0y7pk/nw5rzZjZAVI+ UHbhK7g8hegpwxAf0nrXa6jDIg4aNhRFodnh93kYXEM7/JcdLjdSwrBfyd19HBxniO/EiRRK WPxKD7Wm0QWuSnEziL3Pq5wRyb0lhZlZV1hj9iP+2A53kEx0EI1S50GtzUkNsId0/idOVLhG D5QR/2onotwx46D4wwp5wNd4mr2crOaRVdZEciVTD0kE5Q/KP8iBX2EILovVzaJ8XHBsgwgX 1ylSH98ZpXOyJ/uM1w4mDH1R32qfmRC2WzPeNLN2mBKM/rsDjEIcK2yf1mm7BoQ/ayIabU21 0XiCB5F5iyuPR436oQZlKQIEBS8jj26+p2C3dK3L0HPiwcjDXehPVZeg5PikwYn4Y9vEoJza T0BeV2CFYAvl2ToyaD5NZWElQfTUOgkrM+FdDH0uM5lsWzL/kAPvUoJGRpx297mQueBUIMHU J5k4mCAzcs5iokGxAJqC+GruVAESdNVorSiOsxGT2dso943MxXSp+NcwH1rLfuCgJgaekfil l2thNt76a88/24afvOjhdwUCkpyjGvizHQ8CUnKhwPQaT75svKcMFydmIHLOkCvenKKB4Yaf OhN1/N9ATpkdITTDeJw6jPudyFPmvAMUmjzUsr2tb7n5W2Y9T7hmP7kLgbEs17ZuKKYUmRH+ FawyKgQ0gxWq7RfFjKj4dfO/fE83qBvvvHoEINsF//6GUVUX5IgRUFBucoRurrY8h7Y1xst/ pz8FyUZwou9dbrhNU8/5l52Q/dh+7MWAPS9Ob51FDOlWROasKWrcZ8VA874+39qHj6SBARA9 QnPJMQnB4hDzgNZFB5o9rUy/LSY+SYONYcARfLyfCxInyFhnuOLSTqW5/d3GM2XhV9PMiSDy fNx1ynvkVsei+oa94opHEXvk287Pw00GWfEYRMIT4tq75v5NxmrFpWRrmAjy/Ol8vIb1oCpo XgZjuez2qjCjg92LqT5rvgoc7MoKIHVATZLdfBsHpm0K420d5f+ZbZqnkOP18XPw8UjfArgu csb1l/xK+g2YKKNSvHxGrlEVJCLC99GOONKrneyji1zpba2cE+zJboR2r14Y6F8kx8AyiK1W 7+kRKPEfVlF7WJ+lEwtlmZ7QVgOHuzWF/prN0jFi2zKp9Sg6KIJQ0bzlTSXqrgXpCSr8AMJZ VUS90hBqsMbMX7V2/UXo6XqnJCYle4M086S4tZN1FuZqvjgev75UL7BZ6y8xtmUOunASeRdd 4mYxKwEn6C6q9kxf+WHhEOZeXIiB23Iphj6VrAlQs2ey9SvxuAoj3KY7kWE95TR8tdGYDTOR zsAQEajmK76ghx2oK8AGqQxFnoXwbcOkhWovERtL+bxOPtQ3dgGin42BLXD35hRks2My58Ul DVxwRhwyJxDMItu1TT2AsEElvj5VInwu04tgZ4DgHTdZDDSRFKW7odFx2Gegq92keRUt0DGH NF/FCL8OKM+XQ5Tj6nNaI7VooQVQRcy4MYNr2nx4sM2vGyJCU9ncJbtr7kQEMr/fZw8A8u1f g00bOLDaijLMIKkn+D8ONIh7bzUEAkLMcR3mJ9bPqmiGNKPfS4Gc0RM2rVw3BRP6VPd9aOFr YS/BmobGzBLylOkkAPPrqIxR2HN+j49FRn4erLvP9ODMisb9U6/St3lXEpbmendzw++UnTJC XGRcndCcvNEmZh+2CF5bxtS/Mv1hWpJ1767BlQeBiJapTNme3ffqVFgV9H5UuTAYtO1iCHo+ QlxqhmjW3+aXTeOJFgP9frpGj5mnMQA12sXY9xpm2pQRUbgtZL5KvTgC0OMeI1pBpqXfGSF0 W2LuoRlz3V8YtaAJyFNHqZ7nZGWBQntpsArdJqxts2e2r5wjuEdqWo7UnAH5QxYEoh8xxEYx dZ5lqsBlHlIQfzAiJARktOW0uRWnDvd0yxeChkg9Gr075HkDIbpnNNHwWEoSn0B0g8IjQDrO /L0MrqNCeD9XqA1qwpr90x9qaBV7PxrzCg6yBYYycBeuE7C2lAGWVYNN9T/3pMVfjWstTHLe zhzOjANSba72MBTzYluJZPBjnAjMhPi28CovSIPOeovtpSaxr5I9AFELoA9mol3vwEBQFkgZ 57W0mR1YLJX2i51x32bMCS/HrAJpxhQ61RPgswkLfQNIJxOekYAOJWBxBX/W1so3eUnoNGci PHx18YPiccU9PGtWnyPwmrt7+VlBPnPUeG3QpXc5XaU+vMfiiq2UrJXjPerHFAYdFygfU5KY b1FmA+L7J5ukFZsX5k5Yurypx2U9kU8dHqOpzxwapLIQHgAxBOxFJzVw9WYWQatTRSlQsmjf YHRdvTzLv53Y/y/dmDRt8DrBeXCEsMOdoTZ1T37PJhwoQztP+SG2CGaYdUt+mvLdeHrPjefi JgIfwAR5GIl1syviMDT457sHShhjLRVZLw18H0LGfI4m8Qae7X7A0lqMxp2mHiWhYqBG5fo5 kOrx8kISAKt8hgjn8UG6kZVg5JAgZ+3sSntncWyg/0N0FuJhd2J1yuiOBaHrJBv7eTRj/ovT e7Aqb/dEV2eepmxQbC71XbGgImrgRzVM+fT0jJnc9J6x9ppkINmD/N1ZBy7ed4LfEKrni62K mecO7Hqcjm3FmtNxQC8BoCEqYdGMpZW8rCLl4DnOqY8NF8U9MqczQWM2Cek8k7rJfh7VxR7H ywU2F1/+oldC4ENmf4Tn7InVgYM+nsDHofmkpCRFWCIzsCR64Cylt80DBV2oocRiTCoXBt0T cPfFJ6hIVlEYsKKqjj7RGJ/j6Jtmx1d1L3h0FvAqQZN7iBOy7/ooyBkF6Rvgs0SJOI+8MyBB nGqq9VaPZE367r597MN7ZnjuM7Tsyy3X+f313BNLuj8ylQ/N3tVq9q6BhahePRMTaPd2/NEb OO0ZROSdk6NyTp6X6XaENx4IcXtV+/gTGrF8iB+GlLug6l5A7N+7YbDAJgy7BToXx0F6YUuB 45JFOltweLtXM+GYo6ctToAtZi6fiD76irgMDTxBR8iKt9LuGq+HX3e92nLgKv5USPbeqLIb vcCybxaS1+6wA4JPHU0yezPqDGiU3NaukUCYSEoUXR2QNpQ8kmHIjIixO1IltZBk09VWZMwz QCQQFcHz+fDEHChYhCg6ZrDULNgNlaHahn6mSCjajtKynxjk3H55O9+SoDsAhnmorMUtA0Aa LJ6wJPskHk7Fxn6Ey2MTMh70EkLg3DngdzCgm5Xxg4Jm0wWej/8mUZJ2KkKnQRs6zhz8+UUW vKWfdy5tRCyXR/k2cGGX4nhczacD8EreOKsNrnF+dwg/QVjFHYDCE4sNd6bHWis622D/P11x vO9eJ6GJ8io6Vfk44V6zR+Sc5OGsnx2TqK2TIeP3WsnHbLU+NID6+X/WuGoBynffkb2FHSoU S4FFR2fNk/tYPxorgxqQHuaQDff09vL5NkvIhN7K/loBDFiDhfJHuyJlGrm2LhngEcEzvwy7 0mUHTmctZ5mSS8pL89th1gPDEt2elIJ1+R1yCd7ZhNG1c2zhuBge7RuzSN+uCTyaLHJur6GM KHYC+mjBGuxfz+kag/UPawhqXmNRTVkNEfIB7yS5IiIPNbRJHsvl6qAqWqIQZkebRRzIXIsX O6EeFqw3YfbeNVf5/yKn8IuJLcTgphhje1ceKWQp1stzKHAKrPDUI09YJIT65LnaN/MRWh06 140TxKuEa2tUn3ZpPHERs+APULhtjot13h4fVZLR/w0m+udnA3Q4DjOCX82R+m9voBQyMKLt TJqPMvc5V4Op2RBecoM8fd4yjr58FIB6pQS+N9pyyZt0e6j64wtJkPSDdwe0LaA8XgHRNVIp VgRpVyk9G9VlgIJMNZrHP/GnPNmogcLm1gmMPZYk1l3bOIp42vtsGb5s0JrMO14xlwXVgO4a 4jbI9MmR+mEjDBdt6Q2rjtz5GWoFChWqYG1J1lc1+8doRUFE6I98sdDiKFgqfeA1Y+uLAKKM 0i10MxQL+25rzMGM/GlMfE/gBq1Grg8LzaVMWvWSBXWH5G9doFqHzRsRWqVGMJeX4ovHWOHJ bdHOSq8eMPyUqVlXG3G0zpfXxixGdRAzkPVO8ghopgAsypteIyEXsszyyF+Qf46KKdRoXe0v HiAPeu08ajW109O2FR5kaVDheiEb4UGumMrJ/6GUaH9JZN9pZKe2xHaQoS3zHfFSOauezt9Z b2k80cdOwiQ/m5GoHCCNIQ/gqRRdS8Z6A+PjwXYscBJQSAnHmRnEX1W1GcWYmXJVPUP6Zo1g lswkwHo6bkcZ/Vwu8NAjoY2DS1IzE9kOd+I8Cg8NWBJLLo5dArh/Hx7VH6cO8pXU4zM1Htij zMRyHzIVZfgRPTC73Wy+vnBCCKizhpVlIxNYsesEpKdkyFL7v8GJ28vjRV6tr2/8ef6oXQ8I L3TaGDPTUdBcf06XQHvkTAc3rKvCGIBVAA1W1mnGO7PgVpcTooRQHPhdn1g2CDiXh1qkd4fY mrJxQG2EUakrmWdwnlUMJXw1WG5KQnHVXNw8/S2AdFrEhpFQdKTeUDj5fAnlrm3fEcvm8Ob0 vK7iS9CkNlc4IKuH3FlNGBcC06HPERyt15lS6NWCGx9UCAfQZdaax5ZpEZ0DXus6w8WDOLmR J9ahtC7yY9VAVavEoO4115E4v13X1rD8nywtj5CNPQksyGUcfCWNKiomxf4CEJFelhhGgegK jF0TvCB1wf5ZL9yRwQ80RFDKbJrlErrDSkXAfaPpN6V6q0K4UEIxW/MOXOMmuD6cfk2k6Zvo nMzxuhEXLwMKV5gEBLTcov05xsou27XNobz6BJZJtkV9SR4QQhTmHwRKRC6RIUlbtor3UlfB LhZWON7GrR50XgbscqbW4MDEK3nR+1WmCqDY8Ajs4XAIJLvfvTTdx8f33RDxPidB2VssCWpc 3PUa7lzvLWXXDYRe1aXU3M9LZuAmn0wNTujnWOzJ5Z/mpluh9uG9SM6NPXR8e5Ka2IJYiCjz FXQrLCwVyToGGvLXX5w4DBlXaojmYq1rglcZqT94edFTD8wrIxKqsIkiyTkWkaoj6WmD6U0V 5wtnxBeZhxA5L3DWHneVoVjq842VoPTi7Rt+woSfm6kbN0b2zNxPoTUhv8ZLyt2QnDRUcYe2 4aSHXJoxmJcND3Gv68TVSsxb1j0Jq6co0LX0YEcMOLklfE/hUcXMa2CqmFOHCFakjB6YGYtC aJU45tE8nPVB5CANmqHq9G9E7SCFpkDCkUfsYmLxHUjEhXLeMSahg3vmOLFeqEnwc7rZo22A edOeTcPUgjJ8eV0Mq5yw6pAHEqqU4ElFtCkMVkVvEaWyR5OaMUKwfpDeIf8StR6wa153+tb9 JhaKbC0NlSW0phipgOpaFlCcnVGxd+vvDxFm8JnWEsYYucvVuFze+io3BQ0u5Rj6yqrrE8BF cnmx1qtyx6XtJm4OXzsUPQrL7hAy9Q10q+S+BeoMmzoxQ4M2ipx261V4ZsIA3unjCYPHcm+3 LTEQI4LBr4eGPe7j026svlc+p/QaQWKzYeiY7VGnPK9FiUrDXVwkwxeioUUXctlFc/muG9XA WHhtLxWiSCY1cEP35QuQ/3xJ4VSABC5ZB1XGXdZDuDixQpP3HsaNerg0MFRu885h1icAPy08 so9jeA22qVlaNZq1Ov3DsdB61KOl6MefMNhtHFZLKnLgCY5QXLA5Vc3BeRg9y4PDjmVYW7At uRYbVqJUuRAXjIPdSSyCyE/vYZYHd+R64ktCudNEFqv+TnmWuvZgidl/GOU60yZCPwL6wihd CkvXZhVc+iZ3jzDbbm/QxgtyX9O7Oa4Qmh85iZShgApqskv8S5vS9XDKFtKmzgu4Gobt5Aly vsYFg/I1ut0BL5d21OK4DH8k0skVy7h3C9xItsBsJZ0Z9qxmCLha6yAlnSCubvBPy1YKDsj9 Yts7vq4aYK+Nmuc2KNm7SfIqiT9UerEFTQE1lV0hjCYAVwajVXj3RG52cByoBVnuo90ORJEO HQf/LA3wdNxZzHxext2xJ7vt5B3jRVDSapXhBxhzEkfM8hUysYOQr8LN+qR5FIYV+clJTCNY l2Hn9BOnlGcBWHkU+j13rQ6k2Co8T0xZ2jurspnWKeIphtiht0mOHQJ9Kv/LyVL0YGEEsbco QK6KyOv34fDOqcIHdy3pAogmnSFoGBHfFPuz6lqyN1lO5RNgl/4zJXw3M2v4a39eeC7RuMg1 xQEuf4dt3CFYQ44P8VRsbPGr2bAyk+y9TazvSL+QtVUGoVgWhTFVnjwxak9nDlsgdE9Me9W0 1bENf2Sd/jSgaZQs75FAjTOiBxrIISxxKJ1nd1OYMVEw47SG0om6ydBF4XMBBCNaaZLX409m OGBdj00O+sKLXog/XNJynoRqgGBm6WsROFq15L6gIQnPcPIgbmLH1jnngchmwN8itzVR9izH T2WGm7kBb7yBCf+eLhOrWJLwfh5iQik0+r9rkIRan/mWlpp+XcxPVMKp1VKJjdfX1vjgOfIr Vv1ctRm1R9NRjATNkByPo8xSMTYoz6NRWJN/RYgIaQjGn3nfYWO9ndQQ4kdWj1gRF6FO/Ozy W0UiL9/sEXtJ5G6RdV5SzhIXThQwYpsi28hJFa/Bpv6pwB7w+SZ+3lq+Jwsln0iv0RppYMnd fyT1UVpBDmRxhEhVrxR3zaibToeqDIkxFGs/5lx4IBIRIZp4GtpIkK+Vj3pO/yLKiy4RnZ5f aOXY5tbWG0QrD3GblGa/H3qVRf3yoOZxOClPmnefIn4YNS06Y9CrGLPGz1EqeZvWcGI5kPIS Pu2r4yZIVngf5Jz3pWP7ihlGnuDWDAJVuAly7eUij9RYwWghRpizqJndIEqpWq+R1rJJ+xrb lJjh/bUJjAeO/SWHm5+fJuf1eqr+RYXyC163kQvR82O7Uytmfs6cTKjng80kv++VKh2j+zLu SO/SdSIbBSaalRYsPb24xM8uWolTcxNGpVtI1XvFU3isDiataC6kKLrxXjSVy9yeY5rj4Snz ifwXsFgXMMRgmvQybxHJQrIvCXS+BH/mIFV8VbOmgVhiWllb1hYu6lXPqM2/EbwzbEwTnRGa TGmTMDx8lKbN/0wBUEwWlYlf0I83NSVhCuogUxP0xbVz7oMofBHUJVR2zEbOIiUJ8xxHoaBN gpSDgza9ECxWvIKUCujubr34csOCWccJL3kiohSOHL8fEJbkeyGDC7V/7vVyc0hZMf3ffo/j edO3msupJicvfsP0EpfM/0G3rOzGMfXY7m+eMMlP8x19W5E+GH2I7gEYWwaJ7hVW+bSAgkcd yWfMu8OZaGE381kESGn3ETU/aKKAY73Vd70tmnKRHTDhVIEdMR0x8wXbJZMawWQgwnMTvC+G jcp9RGdTVJdoID6Dbm/oipM6zSqrLZ9110UzZxs/JHj73nXlvXjYrE0ysJVUiOB1bM/n0FOQ ggNB1SGisWVRJ/aeTYx/cXZwxFK6wbL1I7UV7QlEL0QQ9NRLl9ez6atMYQ3CoNoVR+sGc745 KkLfPu0D2f4RVHuChpo3od/2w60+oAzJlLRrFzJMarJ/3FTCr2/v/IvkGGIH90thte1VX62D LU/HL+VdEPmFM/R9496/e/RNskJCzItc6RPAiZWfM6kw2S8hdiKZyStS0sGnBu4KGUVVhME/ 1RFvcC8lSCxH9zdhF7TJ8HPmy6o/SyFQwVeSJCGB/QPFYeBULuYzx2uOXQajsgZse1UZdO7U i2mKHfbKR9Yae6GEQI+htfMPjvFxx2j8zGAohlRO4aiK8RFp2MxMesnSPkLyDnrYNp6gK1oT qsLbG6o5l+ZLOi8xOQS0WSHgqbLpAXakLpwbn7oT2/kTwroUg1497YzSIfTo8Pm+z5QLKF3l 9mp3XRC1ARgwMvJ+KWoX8L5uYpWDdYY8H9zT87GQQfVsSRR8hvyOzhxxFcf6eNPVh7GM1VzA 11r1+f7hEtEimEqejWlswIgpGphuSh/thQUHS/yndH+BnbMahY3m0L6BxiILtYKa1CNelep9 4dcxQEcHhfEsRksjpk5MgOOn1tvlICgLWXGQ1cdv+sv750ocqJ8yKxxKg1s35yk/IGsdVKcf yrfvpml9y5CfZjYBRLkLXTE9pJ19TA77NMorPO2slkuAgoEbhTvTn9MpPaYg5bNPhOWpUxQL 475jwtudrxMN+l8FXEwfr/jAaETqHKSfbzBuDW+H62vAfF63/Z8SppshSQ0H5dQHCRdMLnZi cuOCmBHRANkvhZ+LP4KDDYQqgo3q/mjCpVyJSCSqvP1AACSxOqcOs2uuW6zVOEfukFHc5WW9 /p8BbbyVi0F4TqaIMLgne+zTgAo7XfO8R26CSV9F1bhUa0WFa2hosOKMvD96Hw5qCzTijWoy aKBc+2O8Xt67hfibTp7G5dcUubuiw9zBQQDSYf6Zz9OGwFotvH7xTf7YSoTetR9xpUFIiNHN BtK+km0tBG711jrW5bohOH7ObLmaOSgqCSvdweccON9Q7w0PoO8kNHO5XTpcaoDdEfg+U/bu m2bF3V06UvEHSr4big5hzlqUG97tzR4dPrB73yi2xYBBMMWh1rf9FiSoHl488tK+W5CY8QpW h+VGziquarOZRkIgzflhIEbU1tw9F6daMslmJ1Lam/hDm93bsn7QEhgDLkclSSD6KI2Ve8Cc lZx1Gp1pKTwFaGvL9+JinGsQyrEgYjjsyWBw667gMyK5SwKw1pB9aFBxnugu7UKxfNsCsOiA qBUtK0erQT4K8yFtsLNJyZoSbH9VsaNI5OQjKNgpED1fIjAWZfb8A70NqPt6sXvEv9PcSMrV IU2dMIDhmhZiA5KSt/GG6hK4V6tBJ5rICa7e7F7ebkfiB/wXSN+vjAa9CM3K80RbvoZu3yUF 4GjQLHtAIvJwsAsuaFWm6FDGn3ndSQ+nAqhAlqoexZ8OemLFp1LItaiz2+tn+iCKxvM0DQrb suy29wFu9G5AIOM3R9GmptNSfvjbGnDps0Zqm6+SeOaWtsPctVVw4XTgK9wq3AQ//xQjgVlG Dqnp9eSY/WaxdhTwGeuWq8ZlMkIZbVRsZh86J+h1HWJkSe9oyhyZyuDGD0q0K15dY8d+Es8c WvhusAhIIoPtCfa9Njh86RUkUBS2K0W6f4ses+fjW9j1MAHrVzeo1tZVxwsv6VSEJZD/y1Am CUdcRW+3xQg4t4nFJoICW33/zMSpsFuOkSNxxiIGKiPylppDiXGpKci0OF5RnIJ2JjpK32/X JtKPphhMu/lj3imwfKk6ixyfWYOHDXwLAzAvy4IodCV7d97E5VEA5oH3f0lBQUu9H3Oy4gGh kj2adzopIujvdRxLXMgereY6gIfrSWT2JvcFOOxxGq5LuIWGE9ZKiSP6dwGpfAVbQdbNp1BV nlcj4U3T9qim2jNe9jRp/dY3LEPLV4Gwa/fIo58zOOtjbM9GWSqrCwQXx81lLfxqU0IrRiPr SNrUd0RGmVLRJfSox5RIZoucxUf0U3AwKMIJiEK2SqBMNNSqP2fbqfTRiNcNLjR447r//YYz Q2XqTS/ONnOzzlgAjguz5t1ZJJqcOJKnzebiWwt6gZQHpFaFmvxxfxiP4tEddUDrt/EiG0rU GPrHKQriZa2MDG4nga3xemhfK0OLXr//hBIde50rEXdHMGOanggMSj5SCWnbH4RtR/X6yEXw 65WRHDfQIZS+wh9BkB7fYDMe/CWaLRidpGGMbeUlX+nWjOhM9/IB+uvwPBT+0WIYcsAM9weS 85Yr2rkMlvxaZrVRmdCVn87Apn1axrNxec2kjGDcHp74LT685L+XFmDpQUowzXr4XFYEmuCK bhrFT7DZ6WsVTGYYo4emLEjTLSzwagpddi+HpTHl5JzmGHBb1zIYFoB+NdE3N+WSwW2eTeWB E88uFIDQWPuRFCP7kxXkss8al5LjJVOf1+Vo0cbN91Q6cavKxlA4xktCGfavx0JwzPn4HCBh kdcbbA5PugSKsB752I+Dg7HPJ+dlwEotxBr5A9Ef7yc/3YiYXv60THddCLtGhUmN0YSNFHZ8 VDOthoKR5sAKCiwyVJBLJHrRSSr0nIqHgGHoS5nkpxxzMZLmgYsJI9B1qP7PoXv0WFpdiYAY aWz5FEWqHgJTgTnE6YTDkBQyiv174F4pEAyYRSw70vdF7fNYwxWVDxp1Go86jmmK03BJ5OHp WwX//KLTNhqAuABTqLvo+5r0vz+XPmM635LxvyycRtDoFi2Z9vycPefP4yw+e53zpcMpzQkd Iuwtwtrl00SGSN4ouSo+4jtgO91p4sTtLdhRFG9xIVkGhgFyS85fEl+NoUod6WeNKCKvmjIX xLns5HtfD/2XlwOv58WpGrQaUcAzXw01bsdqFMTd0yywvpMxRBObZ/p1sQhL8wddz3mNfcv5 rMUtpT8NbYhs5apvGr1NesP4KHLURZSRfC5VGNMTjhxHgEZahDrnuXABCSki69l8/peSyVmJ 1zJ7CwlnXIvDYCojBEj59qQpxzW42duTI6eV1qpA8jISML/iT6l9exf7j7lXCCTFdjoii3rs pD5OvpxJ8vem4Nd16BmhOr1IxaR+tV8x3VOfS1f6nX+tZFLEUBoQYz6Hww63WgPwQSIAgmdq zmcQ0So3tT4dOEEag97ztNkr39YPqKZjdBob7iIa0/6UQJGzi8ky9iHPPMNn3mrzC8JmGUf9 3vQ2NrDLG4hEzMEV+8mKKvW6hSe38xKtbIrf31UdiAubR0xz1I300SKw/y3N/zfNTJDzQ+/9 0Zb5HQcqhJJKZ6sGbYXk3NCxKPbaBHpRBi/NFD1auP4v3c+z5o51KzVscWlLXFmGQLlW+Vjv BcBd/lPS6SnEGeKt9gLsUMm0brcxjfMT7VGGL4QY0YK+DRE2EXbulylZUNxfWZ6dejqg9OII 20T2PT65xKmI5I1GvwSb36mpkHrPZp9fdZGaQy5EVoQEKUkMlBoBsjsh5XqSo/1KrfigyQgG a24QcikXW85fXC09RF6OFsP1bI4PO5EWVSt/fpS+Hjvr108ES4Vo7kNQ65sM/fmhrbcOGury ZLWhdH9T02FegFJfANHcmqAAbmK7m1imfkxiJhAY1jwjGwIZtDZxfxkI6vc5KKcuJL4imtgz yyrPWIuC/TARfd3eMIYvpO0m0I2nC+tZbmna9uHjLEoWgOzHLGl+srV7KG6KemVXMwhXFEmp MglKQ0w4Uyy9wwG6SkY22P2dw4A8wvCZOJrMuJccnjKYhtTSjb9Gluv3VfamR0+MUmtNFXcN xe2XxMFuqmU4nf5dA96Uqe5y7vqoZG4hByy3FbA1O1D8uds70I2+prr+jstIQ8kzC9444o22 E6uMI96OPgccZ9tOTD4SJ4qwWlcrnVuBxJdXdohRRibwvhE0IMlCeG8A24/GkG8ryRxJCYrk dnAoHL7a1VDxZ+hphi4ZOGifJZStJJtrDfBfkR8YTus1nQmFrmd4xf7bNAeB/8LIw9paS/Ak s5fkI71TeuESIXnmVWO36HuHiZmfY62arHteebmBhKH/aMNY2KDZNqNV8MDeqZt0OhJXZjZF vnh0rjTkIOSjU5KZtqTEII4DXgvfh/TLWynlpEiOKfka1GWhUByyqMeWJwk8GBrmg+nsNIhG 6wnzppFDlXa2g3E9jtt6FnATSdIvhSw5Qj0QTWho8LFEMju2DwSkQdVWMvc0tPf5teRYeS5T yo//D3MMgbqSUb0Bn/3KCugWkMf9lGoXK4Cnyq72+bWCptFZLYaakWj8nUfQ4bOP9js2Va4X 1HUtNykOms7I9Y4mE7KR2bLFqtkxWNYyFpQOzqgAKTTspCND+UtEfWEOwO/f6x4mfHWk2jXC 5iJbErPqXPrTjfo+GE+mYZMig9cwuBBLJiNh9m+zCHqPOPh07uWg0cSOLreLCdwQ6G17jAhc 17hSYujMJLPXcxqJP1WtZMNztmbxHk7pQ13qB2QJaGpmvK1yV/fenPAir0KGJjHMz7XbNLNu PPYrLgHHkeatIcLiWIvX1xsO6fKfH4RkYhX7VrROgxD1o5DsgsI1jGqnRJbBSYE7g1b2P+rg bqkOUDlxLtkml8spipR5KnACJ8fFoaMiiuAypZuPOzNRFBSRZ4iEtpUCwc9MajWnc/NZ3gIw on4KpKFszRYLS3glNpM0eOjWIDOVzERHBPaqwpNNCEhde/LZLkbsppG801o/vYqnGsJHvmd8 +rRgmBv1bxRgZcdgDrnOxJ0ekaJt7lTy8/IV+VUHjh6Y2sAv5KaifB/cbB6Pen0N8UlgiRnP qRD/mpTKGcWQxkrMncGOISxR7+rF10Wr/Rbbq4RExq+vc61SVPwHh1sg4e/DJXZbi++lmfit GqNHomn3dWPv3am7PWNwZvcrCqOzmvz2AWgJQRdcpHICgXZbwrYDt8UwlMKebNpmw8U1p39s NVtz9kO86Fbf3DTnPsd8v0qQBa3usCI7uSuqbSQ70502TRVaSU5Sygk9PFR9WYgu2xZmtxyV 1IBI1vWA++tUp3EkDw0wI40wWXcFlEmzar1N4HvhvqWZ89iU664FjgAzYhArBeVEg6Scz55j E4f4+TR+R8S1UyB+ht2cmkAGVPHFmZ7SbPY52DBpN4X9nEPuwlME+56bSmEVlj7RcUIEcQ/h FiBsVUp6l0Zti/zwqt0EQDlEPC3LLlzmlCaBhamcLQ85r+tjyqPhP22e4YVMhbsdBRF8jxGV xoQJcigONCZFO7YvHhloHUYmMVh8aLmy/ufp8W2J1Jzf5KOpL2Gp7l7iOHnJjYB4aOHZtV01 wokIKA29VOQTTmWZC2CpA/igK55GfRJUYoa4CK9K+kENNowHitZ3yfGCp+XcMnd3Ssm0u1Xx gP986Zam5faw3ul+qZeU4Rk3xYkR9X5ib2vgY2dfB7Iv7VOKjyNxJ+FG295Gjo3Tbt8n5itY fsyvKuE73P6m8+TGsE2ogMYnuW87RTWXZjWnbZG7fJaYvgdYJGKCMXbpFq4hIrDtlFDnw7SU DTB7l4/Or11YA9V6rrNjuEZcOJXztn2QtXJJUTlcztb5hAQvRxFfmjj+gazIU3bOYTaU9OmN XgGE6XdaHL9V3zP8G5RUvsO0miwECCjRhf7juMiB1qQawouGc+UY+BcrqE6VO2x6n3pqdFEj NBrcsg2O+5jrB8licLFAtLl2cgbPSz2/1nMAUD15YCSgaStKlmK1PHXpjCu8vcbvhzmQshyx zF6FPFmNPSUofJXzGwlf2sF1Z7SG77xk1y1Jy9gnNrafihqrOCqqRrwP4lVFteIy89Bus8+n CpA0Wu1Fpa62jVWLswQy3uZhXksJLFyR0D/tfPVfd7ouQsl9fV+RtOxBWOiSiqNsfQhJCN/L DW37shXF72H8j/beZkuBGnsZZnryNFLnLRdSdfqM7q0cdzmiFK6jlraEm16ZtjHlbc9p00Om z0Km/WN4QN1Ugp4Lc54igtd0Kb4rQWJUbT9lrShNdjPPDzgHH3RVYz3UvwcAY7UPtOpv3PK6 SAMGfUh+JTN76W4LV33GnsXfSovrz1pd8Bvs/TxbYwNCBvxygrhNsmnlJTbSkmGulW2++0RS bO5LznKhpQQW8jzjF3uUC23wCHkHdhAs6ABq019G+jcusuiGID1AQTtGeQ1OTVFpuywPDzBE FgQE2nNx6YTLfpeZvu0BEk3QeruivyfdtV1x9ZgFblB70IJoLlPfF37p3LZAJPMSdoy0I9M2 2pwLY9d3kwtvLMNDOmBjyp2xJnA0Z4pqSKx0DMn8YMxVbiS1hnaXjLdrg2Ob024pa97VMOLE klKh4wt8lmpmsKaw693ySyG3wexif34Rm1w1fue0tOx9LRkR4bfvnt1qZ1Ljufh+da5IC1/w YSGpkztZdIYcoA3kdCAt5nuaLGRjlVH3UV95ke+gqHoT43AL2xvsspeGOB9fSl8kAeVnrJFV GJt/Sp/QoAnQxAuv5LxHiRzl1EjgOf2X9G3pI5EvrtpnjXHrSPwiVgLotksKk6wXn/INsRd1 IpkwCmkRTdK2GupB+19jgZfpOCN6bP12RMCDlOiZ3EDjSqMjuj0nWuvfv47AWKyToS3IEM6C BSE09tSU0yo5+6VVaM5ne9OiwnzulDGsjprnyAZL25PvBkZsP7TSHcL00QrLgeOMXOLT11WM CWNw6SUoVE18GNzTWlyWGdUxVg4MgoSgdDArCP0hN8m/Moae/YouftRQftJMEfJKssV3n1Aw aDHG/RbScm8aQHo3eP2QSozto9HI1e11f9m+xdKwXJXS30NR6tXkvwLN8OpDP7mtJSY7xgkF alFhpiMkfSgDgYxBySq4P8dPbuHqVVX71d//uKi96ZloA91njQmQBhDdX/KZ8EZouIbIc8zG K7DLTfPFGnqoJRJcQT7CemmqQk8URo3yq7xZNbkOPp0cl1SluL6h2BUfQxgzf1u08vbRBeAt YQCXr9Y5hl9dUPE1YgSDw30eTNEsbtRg00oSTt+ydMc7uQ2RPgTZEKag9mvMoihWUP5+3wpA +CO1UQbO1saovZ7AXGe2aCYZkKT6JxGjLIWv3V1JhDtQrfu98PY0/5EvF4foyEPvkTpOmuAt +1ERROgwBrjeITugsM2tXJD2GeJlwm6XTZu4uW9V9F2m99MZ+J+61F8HVU8HVmqAh4vVVdZB E1GYE0GLW8XvuZFXAvt1JqR5UWlBNdIxb/INzjIWlSRRHqXb2aMDl3d7JPiPwbeCxm5aauiA usO50ug6fjBb7VVr0xQyjlbKuWJLhu+gp6KhLQEMH/L5k0y3erixVTpefnKwwMpy+aA2EcDf 17A26C4uK/sYqNtph7appu2s+H0eHoanH7e5EDLL1f22+hhkbp3+ZHGboFzFesovK7CCm1Ub yHb6hZTKjHu3ktVOEs8XBhc0QjMbUAAbrD9vkN3gmqp8ozED8S+jptoZf4lrzln6qVQhquJk 5X2sg5AUV5SIZ4SumS8XmyBHnKiFKKc8iliXKzaoYAhYjcW440vWV1uHIb3lznq6vTNLPbdf mQmSa4WC4RL7NwrvphMGA1+0POQh2OIOktjS/SxpoP5Qwuhh9EEsq9f/sGUGbUZZ3DQiJ2KY +jGUEjA6tOSidDdR8SyGkdgI/sFIg4uDc6AbPgF28HM4GM/0RMX4IHOHaPVzXqNcgReZi7c8 zSrdqImQzTK5Cg8Oo9ON4dOuP2yzQJi1Kl4M/tB5nFczmoGtTcNSHpyWOXviASJXoaHSSB43 0e+8Bd5SPCg+Gl5hjWD5Mw/yHqPUzqSdV8oBeaDuhHN6D8KDwG5N3pJ32ZSQUZNAtQY4/ESe 1MjN3sxNrOdtVmZOsGV/n7/x8rbChVohvzuJT8JUKl/psryjtdqgnNC2qjAZxq0abyyzhduC dZZ+hUNANum8gABteyVlEOfUeVCvR8+43Ad5J0tKBubLa3vK1mHntzPz6bP1My7wbDMo58G+ rBlFaiIyCoio+Jgj+NC4nZk6zk6HbkrIFpE07nK0qSIkcfMl4oG8LqoM9huwrSo/g9M8C8KX AVeZfG/kpW7SZTf2NXQEclwamp9BPe9Uxe2l+4i8NJyveg//Qt/1E8zNkTsZGlxt+vaP8rif tQ3K9JAMY8C/Fe9CFB6mlqeJp5xnV0K6t8XgLlYilYbs9/ZfV1I93v/sHacgA+Ql6H/BAFbt KSJrCPkissdRFHPF0QCxVqVm3obppHbUefFbvpZOSmRIlUwpQWtkFN67GuFYYMGwv6cMtMPz omui8L16PiIa+bVC4GKmGelnW5XK9YfoC+MQvYaYoJ++7Q4nQLMna4GladOz1nzlgpad82Wk wTv19HtdJ2baaCPPWvuXWa1O9W54oHelvy7qTAK3n7MbWrUiBX0QR3tPHLO5jvZgkXbF5iLC XdXkqJjhAvDaM5txu57MISaE2RHQOp8qFhVedvN9Ml2KuThTUc/7m2v4H5nxeB0LxEHl3YQx DbVkukIlNvid5PgSwALwEAfJwi8apY1jO6Og/3ot8gykrMoR7OZBXZnbRYezY5E0n+NBB5fw xCGDc0YBw7YOJhaVDEhfTmsmu2mXeawtXFrZxRSUBBgfC+rZM0EvoV6ceG5BD49gJno72N4y dkHvEJPNA3xiQM4gI7CKVzfEENNO16xGjZWq1QmB4C7EeBX09C+R1TsECxV9YxUdGorp5g5z RDcPMJhjFwL1U5sn4rilryX8+8iwaVJoScFYK6lhsf994FEfwC7kzNAngQR6WeZsLmGgVyYS mXqBHgNkmTYJyPaVBYwtQ4TCpw9pSeHfSwPZezCXxFX1Afwk1DLyx2JxlFdj7uzMnxbUY3Rd 8G895qzC5+OzknW0epBOVFsSYKKTXcydXdUwKxq+mE3TQvxjN5iVZmEiicEUACv6UWs9AX6q jITYO2PO+rEQTbLrxw4XCOcVCSG1RcNC4G1tZxCC/Kzz8MU6Q2tghyafU0XiCUR/o2S04Jbf vGTvaLFVkBmR6lrGAeogjnwmVO8XIqMi6tE9MQC8JrOWC+v9SuFmNfTVp5bFtUjsEyrBaW0/ 9N9HmftGzLgD/JuCYiuCK9YUuKrLntwIYBfFsKbY2kxEc3nEAZdmgbTwI0jUmnoGGaCCZLxh PHomZS2Wy520R1l5g99AC1ZGr8FbYOurFiPY/y06T3HGUNOV0QtZ3RVVgjJ5ihswDw6Mlt5J JciljxddCrURG46r+B8qX/0q2LqCMMNNowNb6ktdKo9FGyh/kLgWQ2OH9OW1efMsY/9EAbjw lXcoB7m5sJvAYNaspNbNWkU+ZyL4q2ts9MZNvfpMqKYppRZTbeqy80TUiYrF64yX9c87NI8n Ep6yCjVAghKp2bDXGtio9h6d+PjE64Oi5tEbHIDCCYIc9BYkE0aSfrM0eGxlqZTN7QbuPUJj ZuF2dvQiTBNvsk+0gdpGgt7kIj8ZKN3b5oduUVHGPHPSe+5LTf02TaJw/8bXW3so0e4uHXo6 ChkkVJ2PcPSSrokNY0mX72KgBF9TqgOrirI/ccreUTCclOMYv8qI38XcQktzSgp+n8No+pJf Mj1sCyNmVgDjvgi6ZrmkeueSKhN3k59h9fZ2Q6Ob0CScOPQ9+YrMFqYbkk8kTL0NbCT+w94s jw39iYThJhkXyTV5rc01IfmdZALyELAYZclxXuNEdn0O6xa2UBibky33x1LoY0kyznu7pSgQ uycm/dQTiXji5trON+A1D41PLYVxOq/m8Uwq7YxJMexT0qHK4SaDhq44IoOTFaoewWhATgAf 6yqAkeAUVrG7H/nsbvYMazW5Gt0mSdcqI3bfozGgR33HCIypxQxPY5d5A7p5rYgz5xJyKAMy ILR2rzmenDpETGJepU8q2fiOFQ/z/uCwAaH7+kB26VBlcsPig8+J5oOhuVHvtWROuo2y0XyE MysqgVzmOzvjzpdPFUPueovz4Ptkc36CpRozK8bF9MyyWDgL70bmX5f5Um8IkcTi3lC6lokD ukubSJgw6tYgVWAn8l0sZr/xNbBcnbMU0AT2QvmHBuyi4cGvDCTYL+gmN8OP9TT1oBd6T3NK srZemasoz9duICMk75p1Jdxm0oYJp1pErYhNOMinaiSXMcx/aohTEf5cokWWFRgkqpAvKcEw IgXOLHtj3b/9xkGUm71y9Rwr/fjsfcheKxEOLztW8qkOoc2AndZe5tTRnEUND7CYoS2Ftewj ltySYIeyJMDHxN9+jihIbus5sZG0JPYHsAeL4IPZ43L+tQEgCSEdKICKImLEavtwFMFovQ8z +yC4ifIEYs1zY0mjlUTV72UQKalmRIJ9R65pD9QWHMxKJ4tc7MRwWdXgRDRYHoEjTlCQrp6X ednfmGLi915CbYfDdms0iUHe9QFUybxoV2xC0tnGqZVxBwSL55iAu3co/TWz0ptm5GQruNST 0QoE1n3OFCHWiRUSLIeuTsVU6/sdOChndjSO2jrkTDjcrM4frWWQEhM8C/rmbVlUbpOnDckh 04tpH5FZcsSZUosXvyPQF4TaQXyyodIddmAacD0QHtpZhR2szFnTGEmbgckixoKM4FmVVgU6 LdUAM+ygyYvLgizCub5vbsNq7XkmR9aVqn+4Ga13Vx4JJAguBGn4uemoybH41xgmgEB9WEit 0k20LQgLaLAlIMZNtfvpbzg3KrGs8Y9LKdAzw43bpqAUOpdPGGsVuOZqfRHVH2gwTg4pFkMU neG1tPY9wzPO6hnu6zixpuEuUZa5FLAnsqNZORcesST/nqGT/mEE03BtLD03Qfcaws74fdro +8eM1ifDMm+j3o2l8YXpe2gaEkAi5Sv7RuepvshDhtpuFHFCthiG11rUbGMmyNdmYxrGa96x D4QH+BrIpzQx0xhvWpph/qAxNUEfLtX+OB87MHK7LL93ljZ8jMqivZFoZcVoRMEtoOLr5Y0l QRVC23g2QAnpTn6VF28MYnN4hM+wyLfmFMQoCD+pxD0kyLgZRzqbs0KbM23BvIxRu3RfimGd D+NXNbAqDKFekIxgomErihyrHx3YsE7QRm3JSDQsLmcQHfVK8Ub4NoOTefgPfe7EvF+hFkBT ZQmvkw0fm/nKBI0VaOyixpSG+HY5nVmJ717KBWDs+kawJEUCvH9voJ/FTvL5olY4bIPA5x30 QG8pRtWuDEtG5/l8zsZKQgaZQJUH97PI21NsUOELnfv7tV902CPJTAKREI+2NHb0u+IbDzMh W+5W1H1iJT3/G91QvmvlLFYnJ+J3AiMR6luHQIdw+TSHrlMOaErhBxsp7dZ93KuFgACLI80L +eF1dD4YuTKIu3ldNqjMQRwBj6WO7K440MEys6xhwy3SRde7JU6ogVieVoS6bWtq5oU52LcU fMPsOTkfXQiUnN2p7lynE4R9LDKQyV5OJBjlw3II89NhENAuWyQx1FvAq1CYmwjZoffbFXum xXcbjzoFYF3aVnHQ86/yFMivwx+qmK20TzzS4eqgdxisKR/ZCx266FRjtgwI7Y5NmF79sAxS pUMaaWC74A2e7mIhjEMg+u/c1oJgK0kX71KH6uJDh3O8OmeAUuHugZ2ZmTLoF0A91PXmqZHS rYBeP3qVT5wJYvD1MgA0+zkP6WuGaSh5tIL4y8Qvzjn8CK3ou+ddCeBV7vnDxdiUPe42xioP CLoZ4H1ks0BoOMwIx6KHjujOQzGVRCSWw3pyBDuNOC9UbWqpAxQW+Si0dz1GdSe9A7ll3GSV vzogO8vaBC8iXcoCzamee8R/nb98ejLRDfI7/mTDwV5KvnzKZC4KIVALLpyPnMmvQDhJsh52 8tLLZmefHeQRInEzK6eQTrIirHgZA2kLMoBkY1qkCt3E5y7vTrYeKELOdCokWhH/RDKGLHmM UtZ0M3DR5/aZ2lo6OuwwMhDEPVperTO3wLEq9lJogWJRnwIhxWz4SGEuGA4OtOzQ4Bzc5Vvk 6+Gzlyx1HWDEoXokc4hAQWVe89Qg21a93ZNquiQOnpJEjt41ZilVhPHx1c6uKfuNSfcivS9k NLG9b97UTTS3aRIjQd3Z8CxjESU1jIdn3jv+/ftKtRw0iNUpyOWN3IT1vbGPbxXqd3ctPgB+ td/NrJylfHn/PAsXKjzKPgq1xuZ58XiXiyAk1dPXf4+zrQCaFUyWO7bBm6kwdbc8TfEjE3Mn eYLhRhQCNM+8eTxDKG5uco8+p2E8rMLh3up39xXySgJMyKKyTF/YJTlFpqzRpw3yqE/rj5eB g3AxZNe9yUrtN+Z4flzJkpRkf/E3YAgPlBaZxk+Evzj3RrdH/ybnMMRBiO7cYf86fLMInXJz Nn2Z9uLNexLvr1PvN3vos/iYXgdgEfuqI3z0g8sEX/icYMViZroDRV7x+QT5QsXADS2gJFAW hFUTUFa3wfoKOid/ucPic5mnIQmp/q3cELrSRcYHBnIflmF2CRp6J1tiU64oCV/RHGRLfH6c TJlZNrrDVx0om2AIeW5EYge/zvggTfj3oZ99f7ud9AQNF+PLCKl4BrEjSajd57xf9mk80LCC bJHGvIXF4l9x9qgv8++H3mnTbdYZPu5GeLr1aoYU1uTEWHexHnRPP0VO6NZqjjxIAS+ZCK13 qlRZqjLLklaogPCtaO3liY8okY1Lb9LMWtTtXTrTKxtUHXHKKHR2WSruUbKqcR5EZkueCWGs V5u8A3JU89cEtyZLWzuDKGCdUu3yt7wv0GJfhsk5q+ttLEkGb0ofIBfrqZP0VwpMQOlgUKm+ rbOP0ezN5TVhHZh25DocHs8RA6rRfFWkTdgIn7CqaFRy9YCAEE6FLqHcb7F6e08uwOYE6yBo WJjjghBC1RQ5Gi6tgtoM/4GwF4ARJA7fDPqIkxtZcQL0a3KRCNcIQ5Vptjl1TC8+8TZqjecy 5dANOwmpZSA4zaKWafmQ08AuPdKA3btKvtjCp22r8KSvvJRYcdtF+WU3sJHMQZ0hC085onri 0iNh8Zxla4U3Kc/vZaYomWuSfu8XZFIQNbfk8RzhNvRxXJ4+O/5+IN3Jq+GExvp1TFNgp1vh pP3YTCEfcF/7q7iDeMt4K6HV1/l/P1VaCskRFlEmRYgJvtFiBna15miWOig5TTigufNUkjC3 EXH42Kfm4TsFtgUktACzBa/dl1YyOdrlxqloyWDKsjf2QxN/TVqZ5MrEbTNxXBUrB+UjA3TF 6nGLmwFDwDFwOgi5ZmZ3LrYKMMI/haaO9CcfVypwtRVmlHqnyTscmQ8GUK60ygvZXEkeGjtp AeTVuu0CC0IuZzqXIVD7JhF53rNAE7x+twuzJw/RSSQZjbwCxSbx4Gbafr6wSc19XccDApJd BiQJ6idE2ae/JTzXYFIBizZDkGL4JrM1jb6ufBTT6CD3+gX7Vqn43sMunqrJ0gwDoAmiQaYJ 4HOr989lcPvwYPXObN1cNh5YHBfy5t6TJfaI4m6QJgcahU4fc9MqTWCWieqCl+FcsZym8FUI lQcJQBtubnokDzwkZAHfJn7UOBUHuZtPrZruJH2x1fLdYYmWeQF18q31N6agbgMI6917lyko sDqamRvztWV8IhiGTD7g01HWopOlwFNQA4z+DtfEtpYa8tqsCMVBcLm+BjaceQQOn+Wx20Eh pFtMH26P7f30oYQ7HDkgrwekRQht2nbgMbVNkSjjHoj2p79TqyO81vMeRLDPBiPyBx1b5vqB 1La1+rw9ldmVXizj6JJYyxDUj7aQY8H4HihCzYSWa9MsT+NDbvX8kLhotdbmY9+1Kvpu/xzO YxJNnJ6lx/DFALFZcYqDd8twV2DZpfr1rhU4FwhpcwVT2NuC6cUJL9B9y7Dn2Er0Pd6GbAW8 WKvrDACzukDCELcdRf7ouu+Ff/WJK8x+HEmL9/CcW+UJ7nfHVc8FL0/97sbCcCKT/vND3Ig/ +bII8ZlJaui/Y1DI2bumoZFIzYo0KVGKDDfWt0OfHZK3x5Ykj0PWCaLqnQJqvd3VE+gkyutj I/bpwK/2UCihuONqx+fsddLzzvmW1Ffpw5Ev1mOOD4MdGyXXGNg8NLfY5N5R+OxsF0PfDlp2 s/Ric+jFrcUvK/WarJiuh0kvK8/Suza3y3q3mj1GZrJA4CmEUlVij3GRuuiPK8zLf7yTyGNj 8NwnuapLbPfDxs2F4DGX5I6bFpvKygqRK2QOte+TzoA6kSHbsEtgOeX3V/+M1yr629T5DvH0 AI1RUs0T05KUG7JJatJHLm6h3JJCGncN5dlks+/n9tQu8n/+IIC10hbCJZ+nLXr99HB+7TRP yBZlC5IWRgSmMk2szABbC2pS2H8SJN0xf2MxbBDgERfnT0YMorjiELC1GyRMqkCm3RxQOg4B mFlYolBLkOpGInWcwnpHHj3YuDE+LGVE8mf73IrMqgDt6OnlDqa0lpICQtI9ESPdX1bLzPoH 88b8Hi42oU37W0BFy0YhBDS/PeHUPDM2ALCy/BDlBBFLLvp1Pjhxy5eystftGNn5WZ6ZlQBa dKBnW0Kifnsj5o2X9xejNYj45eCgsBZM2Naw/of6Zki4fsGeXkkEF6rlYcBsKeeF9gxZTsa/ VJFp/z6JbpkDl5pq4ERDbuVY66NYKMDTpNTNhyvTiKyzldB1v2FbnzHrqVKdESWfkAI/zCC+ TsZSpqtutRwhRH+C5VTpTKKqOIXesokPOJ+A0VRLj2fLtpm6xNjmHM/2xcmUgv54PsUcqr2a q8JPxNCFeDkB0I/DDu4NAqz6NaLmJh+QpRucvaRETmw7f3fs3hdOwWWa+4Exwsv2ucJaR6Pg kJ8IYHeQpzDOWva7VCUrGXoDU/GWHmCknHVS1FnXTLInHXyEyP9rmT+p9TAGugEdbELTsl8B FwIozsIPMBr0kSec4/vxdCULVPmYLyY66hT0UAXkSrNYdawaqjZQmet20vt3NKbls1OunVrC pEzPIg/fDb3ObWomGFuhs5kpk4ZFAlR+Y/TWF2GK83SUP6ZXmSNacwbpGZFlavgMaj652I+j kZqk6EikEurXwzGZxOUy7oKQO/4Pl7Wt6JPswjus1A3L0b2uK3cFsBxU483J0d7C/IwC2qwe v/1EHgaKolbFgYhMEdY1p9pRJHpBNy/yFa6fmOhJtrldPEpdH58RSir88OhNyJyOrJr/v/35 beV5BBQKK+pBm2Lmxxs1EJxYfeVxBEJ1Wv0xtteG4iHObB0evgt9kR7UL8fjbzRaVtkt5HiO 2W0EDaS0kFC8JMCTkcyUjSAZ/4vg+D2STX0xpvpwhxCShCdvBq1B4ec8Z/SEE42NPg2ZEuSo dIYg/NhqJyZN0muOenkauKf3eTXDqd3Udjm7AJsUjAhYkAhqF1tAHmVxWDev1Riyy8TMeWHD iUk72Nk6lW7P+vk+JeThsZnEQNwvRiEFmYn89y1X6qulcJsRHuM7by1LJvc3uY7i4wr+hdwY TZLOhlntW3qzwinUUjig7ALkzHcrjNOSM8zD+maUIjJpiA1WJXNcBZaSdZoYx/tPvwjfPGUp P5ocH6+c6fzs6ANLzWxSJ2xFteqL1OFjjlcYcIDUbMkepyps++hLc+lMl3OMnHqXgdKuXjNx 1Weuk2y4gCNDVogeIXYEUFcsARRK5wrlYbMr7pcU4CDZp9CJnz96sO33wyD7+Wu76FhTUxB7 TOwP2cwxzqNVFkxZwkwIjetSwb4Xwqvv5hir7utw9PCHukPrrRLzVRAKLVdFs6Mkkb6MhFS7 ACMXLM1y3iQr39kTmoUL3VmjaQalokhmJ3twinV0PAgs4+91IsMh5+UVrmmK5TAOr+RL2CPs TCRAZtBIcth0rHivmPqKnROP47rSLaGF7/uNtHUJtVtt3aTSmGT70GLd40DGKbn8Bb8Nc4S8 12LnLB2aS5Ou4dHBllgD7/VNvOs3GruciOHufvd2+BdEITWg9Py++FPZF/EuSmtQOvTMi5te Po2EDL1aWFXNhhYL2rpM8SQeAfMPkxYRvooRex/G2HyBAx296bPEcw0d6uSKNjlrJHx6r9DX 22Mtq5F/Y0JvhkYw7o+q+rbg2TgQpT1cFJqtnq4lwswD0XfjXFQIKwC+bjPeGUC0YnXt8iaq fuLRyfsHYmL/pCA+gzEkphq6Ig/RfpBILVbQTAK4NK7HJqmpmsy/KCMTYpdBT1vCASYu2YJa SJduVmxnEyDoqAd/VjFGBhljhJ0VbFhgdutCxnreAXudp/ZNZl/nNWhQPPfdqptgmq1rB4Q8 P/3/7Ecp0U1/OkYVcDr/b1Ulw1pnwh+M/HXGMNeBIRt7PrPqhgSh6gJ2DDjfFQ8zSHgu1Zc/ gJgh+gKraiRYHAiCmKWoge3cCT/kQJL67I6M5dGqZKiHeOOfSqZRlIbxRsKQW1NUQyb6AG6o poyx6j6T1ahBxVKcFQQiXeY6hIeFMadknSDOkdiQilvtpJE/98a1xFMxFnoaOHYb/AEnCOzi /iDIhzNCRFcWEkBiMUJ04Q8mHdE+7jXtSEY3bBhuiSrjT4lNm+eJHa31cmLg43c51sPHIlRv 7Pmw8GpOO9sai6kPtn7P7Td6U1YYTBcii3hyhTZ1ZTk7xbBQcRLWo0CXik067MvNlQ+gqNTi iH1MYSDrL72ylQbiijzccPbe59ylPmPzESTvJqWeoYPMAWU0vbb8Em6SViPTllMTXNgIjuxe CLG14CG7FqOrkUsVIeO3RT2Smkvpb9OkgZXWyyxL1aYEP8yQZP1cjFU4Klc7AP0vwxsdyf+g QU7HfaygSTaRE1J2nxWSQgMq4H0gNC3O4PMwWOzz4p0E39wz5RbwDJMJ+bAFRPWeww1Q2Z9P /v7w4FU+7C7AkWvuyYob/t63s42xLg/k3byZeQ4vWIsVaM8agNAznuiaY+a1Wc2PrtjPXrFY 4RguB60qZ2Sv+9/KHbC/2j3v59YSJAenWsPSa/O7xqf8E4QZZ/XyVxx6ihtcujWh6RpzejWP 0Gyw/cR29eqiW+XAU1TjQXHJgm6jzlfTmDrbheUSgwtgFQvCWB7qs74VbjtoTXGEj+Ejf+ls 6+eUxgJ1U96Ku743+q2P0wcJjTT2Hwz9pmoEL5BjmGqNZBP5oksqabK/bWMtPzIc9+nuUuCn WINFjFYJrC1SjcUwQ6igojR8YhTeY6gBarGLxeYc2XFbsqSEFo+zLSl6msLPoSCmw8ZXoZaL t1Z/mVDfVHVmx1e99kXnOS4HG7N0OKCdB+urzS6vwOI5brRChnHUahSOSwNTFfH5J27Qveht +tvMP63tJcbVqvAH1auRvpzkfWRIuBj2QwA4AupgXzt4rbZgDHShEh18Zk+Q02X+KqVY/jY9 9ST6c7zYwLiHiabSPlq6JOWcNdRxDg4mpEofXXhO6EnVCAZcQ2goylfr0NzYPOyz0u/wG4a4 1l8apduiCBZZQI8YlWvkWhmg2ur/5V2wfzHsk9n0XbjiE7dDjVS5WbnR8kDIch3CgdHBPHCE VCkVGkJiGwdFfVlgJsvhWkqwfDj1PjHlXyhpu6o6sFm6d0kwKdIfDXLNF3lSBaFZhIO5ezZ4 f5/e5PrKd+iFLllW4YVjFbpCY9iKb/INxeHnaVy7n5OMnpL7+fHOCPKyg1cwS1/BjeyIVJDJ MKKwj4r8WGugdnQ5R1445h0E8OHmx8gHiGnU/AB9Ss3OTox/Zrvo1TrbTes+gKeDPi6xt884 z2ihG9etCuHRzBOl8GAoke1d79HUkZvO6Qr6LA5m1cZA2JEZWExTnEVohBwuXtYFqnSpbfHM Wp1hYZyudMK2Uri3Sggr97FhlPFH8fWhncBAbwU8crEARCKd5E+nETB3NAQQkO9J2QoMbhhq eHjUGgphETL6DYYwgfk7hcXX9o8fNWG/sEdV+INsImX35BZ+1rOvjMsInXUA1Fb4Df03N4rO fNY82m7UkWnYEAXx5ANkNXuNSwuzPlajMhWMfhjrRhp2OK/gSpM1yd7tXZ0J/ZTC8mUJ18LE iFCDbo4lWrIzSvybzJYVNQWHGfWYo9jVvHsQCi1ZsgaHWzT/qfdL99UFRXT7jTykA3rU9/tA 0ydtGISxRULpNWL7sbiJZnpq5tEZ3Cv5VYBQK2LZ8f7VjkIbIE6mtkgFj9Nw13mzrnMLWmR5 PhUomfCH8ecNgzki07dmmaC+133zZdXwYcoCFpzGFeBlYY40MMv534gwqx87DMFr0xjZQ8Dm DnqjaCHfa7mKQOy+I9J/dIlz0Ut2eeBjbme/XVJhdkIRwpYAMVUuW3RlUJMuJeg0z2EQt531 1GkByK8sItEZaUuhcj0fpTMGtIxalFrVC7VhXLBDWUqtREalJy3YerJxTFpconBpWfKp6Qr6 I/5zlx4t5GZZZ+ogov5GL+fg1/llyZwJfs64GlPcDMTR2X3rp8nqyNyqeVJ78ejvzmbnK7Lc NEwPxUZ0VF/IxID9pfuyRjb1YvRchGXIB63VMNrmlWWsPaHCHWZkDIgUdz01+r9k1Z8vn6v+ r95vYUXgZU2aSeos/yPIUZSBpj+iFRwEUIkcFZbZKTG3erK8zJqVBnbQpPuLKoA97YdfhZ8c NWBUtpvuT16YtiZDwTLCjEGSlwVvQN1XCdxZHymTwlCqyJIgBz34wNItaBVkBEbUNJGG11PJ WzlX1CE+JNWr5Jvcxq1z6vYQdWJFCcp8BrYyQZ+gEZ5EXOpK1QnklGdy2rwtFg0KalUpA/hs bPpqgEKbI5IvnoexHaDYZWEAfEES09swLWXNLL1Cwwi9bx26nHEZk2AvUYoxAWzcFHedJK1i 1lbT/A4MVsrJ5MKqzhJKSO2M1K/MiYoidRnrFTkUh5MmlbAKl6N0ldOat6uYMPhJ4/UKdlZU mBo3n5+n6bvtfhNVMEOIzJkb6UPb7W9vTI7n2DDGo/9JprdM6ZNL5Ctm9zGknBgXB2NXS3m9 bMREziwwOdQqBGd8/t/BAoeBulA39xehzMFzONnS7fcRrgr/ytaqApPb4QZPt5+o4zMk+Hl4 BG0RnPLc5uEIrH6kP4feU/ybZHAY05bQc5kskz7Wp3X+u529Lob9wHRv8C0CiyTbqoX7idKP D8+Ohe49a/7WaFMJJVvRNVp0LEJHNuvcDMZHV6Aj6SV9tGqsO4tZ+tpz1UBHjU7vKoEDBk41 YIn09shc32pKr2jZATzr2VblCISvJE+0mAOSi69Irf9sT9rJ0lNv9IrV+HyiNnY4ngHBrZwU 9x8QRaS74hUd6sX50/v2PAyjq7Nf75pZKd9kSbuoEL+qmE8YJoHASJJWmULDQQcGEge9b4KD jri5+G5BFBriP5lRwb8PDOd2J6JQGbx0F+rDL6BNaSvpzVKXFt91oa5g2yhwfUl/ZQXNbEaJ jbYk8OncMSI6126UbLiwz16U/D5gBx9cggHRuOFCeYZAWjgiEWtTruElpuFumunnUEjptB2A KF6RLUIU6iKw6NgOVsA61AsPi/xKshd8bhTytPBZDOnj00HfmKRwbd3pHFAWPo7ZrWoJwK0d IL1TMp5pXeaPeKwSnzzeyyhetqrXx47s5pLLV918EDhXpDNbY7lC6bn3s5aYPn7KV8/RsRFr dyahr1ddb4CrR9+/u9UUdgvZQlHXETMxSiFEWL80nO/KSw7ngbhKEoFC0Uz1R41m2D2fNVQg ukckcl/2QndAWQLKdlKMDyOBxlE+7FuQG7vvejD9Yly3uZu+8fmdjUEcqfPE7rdY83HU6V8H s9U5y4Lwku46lMjeX/ZuikuFQnq6yyizPnyFHnIcBlvhG5ssDDzgs3OkibGKqn+U39cAbMER IivJH1pguPJynUpicV2J9StAneCRzxCK2wEmqCB0u3YZ99fCNukjpv8Y6zOVt7zyK5cE2QeT h9HylLYyWez17OprBTpJI1W022pAwFFwPMcLD4rYS1HVNPbonOhMdLzM0ft94wo0nwm7LCT+ +W673MVoy4GjKKUzwbDswLZcYrCd7zTQuwEcvWhjt7OToXX6fat6i1E7bvDD3tt3vHIpdKAt kzRDPvruFi5kvsxaNH7RzXgeMYLL+OkcF7fW7FKxMdRmhW1PtfXt3z6hTRtyIq/dXhIzuPpH Dy5cBTIMLZOCq++f+y4gatzzW6ypqUM7ycWRrPdREkDqD9oKfer6sTZFNSQ/NO3PuG4KycgS 6TuO9fWyVh5biOeR/cjmngiAeh3Z2qRglLcGxykUsPHfbSNthf9G0uYuaWY8sD422jYgRsHZ bfH9aaz44weDdcCr4tU6rYfQlurrSrLONSnldRnEtXRMLnsWtqBedhkK7SCVLS5Wbv/fC0Wa +O7qdK9QcbrN7dKtqEp1xHPXFqjuXc1Rv5f/jVIcnsrFGOOLfzbojjOl/NNIb3w/bVgqV2wB imhR52sovQGTQoEJJeoGmASzi7Dxv6pF3JHDKTzeaCgSrM/zboVttxTcsUABmTA9QsD5NjTQ k5DuPDNudP9C3DQrphA/R8q5c8wFQB0WX1Jc7m2AsXJmb3TJxEndk4OPdnq52AsmwYFt+Nrd Mt4wyIpizCUQIpmNQqc7LsvnXPJ9+/Km0WNoScwdkCZyGpQdnU37h607HQozOBK+eSwU7FoJ MlgM+LUA9mshViSyJhhpezHSNAcH4QlxqAneSzPC4RgwLXUNB+e6g6Wyz03QgM92b1cYay6P AuRs73fqWo5Il3bdWwgi3gf8PvRK9+FoLRndaiEnn2UgF30wP5o57xBRjiWcX0HnPz5DHWad FGIv8KeNu2gNAI9SuDh7seMuDIj//ocAinwCbNKpRaf9Qk2MpMOtXA9rgt1UXR1FDSeRCQty 7D0VIr2wN0QQiVmt0xccBFy4+/okzhjvTaQEVGSyaUZdmd5S49HLdOO8e88siWJYj1Q1DyKQ sCR38QjmJOeCMqAevIIEx3OLpB1jQngeq2r4zY5LJLPOLPQSEj9SNRJfNoMYxqvmxdh87ZLi Kov/rr+oDsQu3k63nHTLfwtq4/Z7ntTvQt87PWEqCj5miiTTEE7LqP4c9zmJrrocQ/9y2Ep6 zrQfCfeeNzjd2f94sqp7oOd8RmATWaH9nArliKyDSShWYVu/MvZ3xEnjeAQF6RqAmVNPqJor g8HTMYtB0KS2OJL1Nn6TPLar9grTFvXZIBammtDZ1USltEn1DKRucvKF1M3Tip3ifunLwVee qPj4nOH9cfSjcyF2D4uJuzcohhlJTXJVdafbn2CPlOP5Ub4yJcwz6SbOxIiMQ9eaqDSObodQ 2rsC6GV4Y56G/ZD3dXErudDtjxP2KxLOaEaWbMXWwYnJDlVVX3S8dubsHbvQpEO/zxMoH4Ju CKtZO0AYAZrWI+JK2CBrNdD+gutae6m07b3iIOpFEa8l3gv4DAOfqR/rVWf2ZACN7gDIrwbk XoGLEGAdocdU3c8bYhe1tHSu6AhzXgIPCzrM4e8bicVQ0KW4vTn20QHWOC5cheOg4rNzPKCu gPDd/Hesn6IzakBhf/suG5N/zbFcAkBMYiJC2c0V4I1kKUVMxjPrmqtETKRHZPwM0Z2tdX75 t7wFdV7ZZ/0tBIkIz2C0vCwySXFzi6Qy63r22ODqWqOTnAXrXwcFTu/W0VxZ6Ml4BAp9wB// /DVux/bDsKLZrBPE+p1KTRb+fesK9SNd2Y3G/ALqdEGKWCHNOo5wPjcyqgnbIesIsOHqk07B RqH5xFCc3qflK6NnsmQHrpgXs8kg4bq+YzJnTpg2b2n5lWpNeuXdseO6UYAwcD+i0Z/vRuZ6 h5enzZHvW1bVQt8tJ69/BpfqtBErOjfAzIp1B8KTrLBnwcrxgAJL1uQ2sGI1lSwz1ZubojML 9hJK5XtNAwN5b7unqYHlDfpschlW5Xo/iYdJFmss9WBfyBYFGWdG6qk79MeWDMNQ11nSyJr+ xt1P1pCrCkn4GonAuLxSLtiNMuJkIa4Q+lCskSmyblziIPMCZ4ukxPmAySaBl9+OPkPItBEO 8NeQbh4P/GtQFmApzPtIF9WmddpHFtwobAfg/aMKJwnL3FG0MeivH+en5NLZ4ERrtfqeDsjg iX6HEe85JAvSVvPFUsKcAn0PpJsm47+8xm5NeOC3nWu11tSeWI91gbtxPVt3Mmxa9uY9DPzd giot4BRxbltTZ13K4KfOcVxRSbvDe5PIkgo0AB/Ztcp5vPCeLrADZiXlxRHc1JQghxHI4x1H OaExMi8S8qVRugureFiIrf3sE/fNC+ipZZ64bihliP6qAMklZN8p9/NZhZZupqc6G5Jx8h/+ AnE+tN9Uc1N+G8CbWerpHqDCO+fmp75sOl5HRp9hWJQaP/vD/KIbnbZz+aqSTC3M5hniUWJE gXD7uuYlfvEbylm3GT86q4MEQQW27cqsRBhrVmx/7DDOpw2TTJc1mWU8BKKDghxPgxFYpUwb P7boSm9rPyTy4sjy1EocuqjdxY6hT6+eY4xUfGqVumqKqgHQEk68/su7jGkD5osHW6sjBSbQ M2Yu8HVNEfctdwV0PX4pyDB93XNEWvSYcS6rdXHKdzAIhoumJLGl4EFkCh06lVtJLKjf75H+ 9UkVolog3AP7W3aY5HDeYuaDmEPzpBmesZ7p4h5FDSsWUMQNvraJQXmXNvBvxK5GkfAAaDTr 1N1KL3oCVzrHro+IvnHWKn+hHS33tydnq+pT6hKosO3T4RLvtltL6qDgmqd1lJifJjYNKD/k Tt1Cba0UrjzhadJU/HgrpuP7XN7Zetn598TEAY8EceNAs2UDzHCpVl+83hj4/ivT9dOhSeOW EbJgnaR0Pz+D9Ul72iQC6HvROGSmZ4Sv7aEHhwXga7ItAd68c8BqO1vLt6lBjDMVcojcYYJP l8GmsvRGxvL+4Xqgw1fUMivrhXf7VWepCtiQR+avcdRtzl8AEfVxIECVD9QPmrGdjl9evMuh Zp1FSLAEdXeeilDHc3+pZoCVNkuPIWFjF5GO525yoAYDrxv8AXc7mY/OBTE5jRMXGYgLuLLF Isq5/hjxsAnYuUndZLhNvKAho09iWA1aNzzhs+p8aGl4J2jxtINrRn+Q9NQqRUrvUHcKKcUg 2CRESe0XF2DnfPgZBUdPyV6stuYFVRezyUtuyfl9oji23iihrjUhUzF3FR5oO0TRhHvGFQWU /OrATFHNRF94/sBD5KW2PucL8wdgvX5o8In13NlTz99QrSFyqwB1eIwQg+4u+0cgsjXz2onV vMj+f6e61qcWy8+4r0PePLzTsusGfsMxEVnQqLiBa15obtKpQb1wVtIpYtaohBEESjie5R7o WUazkqRGMpDz7Uf4GpsJ6iHggnCLjjGQqfl1iZ+t0KFnrdH8P7aksaXZXximI1CcfR0Wx5/Z hwgFXgLvAR8L0HKkUZ1g6PcbubFFqDWvPF91O0gBruj8VnIa6JJZQDG6t18E7D4RU635V6J4 c6qpL80D/p2Tduq9H23RecLOaahod+2DDwuBTF9RtlRDDv4dICZT9jjdSkJ6+SNl2AYQOjM3 RRR8J/lcpvrn8W5XrMlPRWRK9XMcUZL2b1H+J65gOdpYWc38oQfpm4qvut0H8P5aGik1sIrF If9NAd84wvZWKb5jZHNg9C/f1nekeZceIZPTN3a18Zcgwk37xE+lAOv28VTDWjlmomb3PgGC zVJZLirOAV/mmrnxSHm2Y+jrQj5r7Md7xu861xDL/zIg4Jsrf9UgUbHzKhL4q5tLDeUv1Z1F ssRmof/orF0mWAbc1fjcZstxjuzPK5kYkDzoZcxSvaAvLpf1tQWvktJd7OV98hZQNT54EolC 5vU4QFh3ZbMeOBjBsO2EhROERaghCc4BSgibZYUOB535soiyr/WKgaTdKuQdBa02ftY/FiOL Tbxh65wlhb019vozZmfBF+xzc/tMq8rD/EsOW1Di4qEq4YbvHEDEFg3WNC+Hzd7dE9wxbebv ZmAA+7gRruChHKo9idv3R5cWpHFY3mROHvs2TV97ViziKoA0VgQLCm4qSonrDlcJjzo+CCpd aGO7iHfi6YRq6+iwjcSuE9cmbLkUvwE3rsYEkSXmWdp/+OnSGmEGqO/lASTfGkm9QIlfs7Kc ugDONC1CdooelKdEz1wXm3QHWb8Fy+54nscAbLp+BJk/q+ePmuaabjMI7X5Aes/HyM0DlW/9 k35Q4mqEx1ST4XGoajJ/HTv/xyOySkjq68F0jxEzDbf7pvzeJinFdmdqGvroac7sPiiMXaB/ uhlfzDilGjhIhOl66YObfEU02bZPiphVFUJhR0lOzL6pYQoD0o9l7e5wIvhADghYFFaH1biq pCdP6xC+IJmj1o+85IIgzfRxnRvfGx3j2zAa7gPQfZcrVrsA4bASdi5G2+003eQysPd8wfL7 kYRCvN4Z28OeyzHaNaX2pwlgxyUZDKVhKYlHCTIakhlCA4s7X1MBUO58eDcwR0MbHjqDPBAz DTsfxZlQOzm7DQ2msPOj5LgwW98pTDMJp1efFne1G13/nrAJsYDZr8hY+A8zJ47T3pjyPpeZ Pgl2ZoBFa1euBZnnlbtGWaCHm76v5PRRdbuDDsvbFKUvyLKsCh6nzFh3Xdw7sAzOV4aGSVln 2iNTLaultSJfMKtkj0VnQsTd8TnWwNusSaEdvK68159H3/ehrivQsfCljXnbTJMWKookc+h0 WtAcXd+jEJGt1Ez3B6FNCLzTXCoTCT2KAy+tGAu+HDJLenKCh0FxAfChfwvgCmQ5iUPcFUew NjJ21F9Yt0oQ74L3NsTjuAOuZcoHMZXudR9rYEZrL1xJyEYD0+Wv6MVEY0BHswSwWT+VQNx1 IWEpBeoVUQrcEuldG5TbNLGaK20mcmAhFiICWzyXp7AphcJz+g4TzG0N40NBSMM+YQQ9s6Bw DhaCAlvBpAuvEcV/w7B2c+2Bv+ScGMPKqtly7sBTZQSSMh+PaabyRwqlcRp1q1MwS/B6E/JV Zhv9yNcauzE5VEsNJH8F4oiOvVGDvglXCxASjDJma9/aTa1utmXtyc3G/N91amBZMFZi9Iul X0GEN3k4H38Pli/ZHhYIbwtiatCIikUmAELmwFgJmgoIJTmL0qOaaZYlW1mvSDPC6UqLXW0D OgaMWvApX/Jc2+TZaHsa5gN4gh8RjiW40c6j5x3upycVzJim12p3QetsgMHhiYTied2KHbss bZcX3qsF/FMQ/Cj8easGXyTO4Ql4UodSHjIEmXzp4MjB89w+lmrC0JYLff4ft7cOOo4X+A9O EoyOUFF2LdkC8WC/XE2Fny3n8Sv6IqUVLoHLBv4CWCNpN4Zc533j7OMzVwvxbXCl4eWyeUC9 BudBi9xGnYCW7gQRo7mgxWvJsmKmesKjCnJFdsbvv0t7hToLI8NGzbHj3fSdpVwmn4eDV6w6 e2FcbeiLGycNfLTyK1+Uq2fSXab6S/kj34oPoYm6IoPq35SrburlXoZoppbg2whPbuvZIqwo t4PGsSMIr+3su2QmFfk86i6VK6HZ0F5CJmxyqndYjH6mPb5ZSTno6bHwc14Ulyr1WsS5Vg3k qccjY/BvleBo06X3GT28K2KguIhAgQzT/E2W6RocCcC8WcFM1DNHPZDDqgbEt6oL97KcLlwS fTmHlef8doS29FWFP7Pi+SNiqKTc+f07/pRGmjyIO6UsSuduUHllE8tciKZnrgihe8mgIyAg CBAzwZKsE+FR2U32dwviAfbAiuyp/6umAxnE3TLezNDRWsFqDi9EJpylC9iCfHFd3j6wkH6B TkOdeQZencTU1GGLbIONcGVVys0DToXU7Gq6Yati7dSBgL0xBe7atRYD23Oe+8veq0A/wuVL J4g/EqAApcjjsNudrQXkCaLjCREgQZeU65gBeVwS/XuU15FCZtMDWf8KtSHmbHMzeyLJm/dg j9/WKrGgFz1YTLcyCdiHUEdCcds5POT3k2zvoxpYrF+0BECE94e78bfO72ltgCxyEcSGW6gB yPygrJ8T+saJpxK9pbW1z3a1YOnUhC8twC4y23ppSC17HtsG7rz1kctvohWIpOdWZH7yzsdu Ehk5BU2VtGxoBFwcZBKN5qzcYopIMfEje0a2Qaih1AC54BeFNvdOoDYRLi5VJ3nfcRzFUkun umMC4CB2sDhBnjCfkLRzf3AEBAFxkXnuAFuiI1HvYR2HcfP+huNNs5QNucrGm98lHqRtW6RG LSYrrRuhb0PV0tU9rmzHdBmyllfGpWswAJwfsPQgAGgqdjf3fQZMBDPoGZXHMGmKRrv3tsfg oMa8mY2MLU81Z+EqfLD539lwN5kK0rCfQvSl2lncSImvNJmGRNWOccn6EbeY+ci2hBmMp0jD 8zivzyHsphv24l6LeUjcIks0H9Y7lMOg48rhkeZPw3frjJsJw1HTkU2/lA4xh2zMkzFmqpHd aRzwtTrMvCRKfHpvqPh076iUCiO7v2AuPcbYnid0SKP0I5NbKPlZ090JVY54fRAAbW2xUKCU 5/MacUU6Gqkh/ebfTOUr0b4cXquepQ7WzL7ZeG93ssV2h350g3J6utaSSSEp7iN9R4oS1S1B rP6svtSF+1wemzaWFLxt9zsf/shZ6If/SQc5gd7NdqvgSqlp7K48w1VNHz2eP6/w4og4I2QJ VXJTaVdWEuKQL8HUGLrLPPWoUryXEW3VBbecFssF89wK8kTdrT19/sGODU5b8z51TncjRZmM /SbC3CCmjRiF+PPsTn2Ro74BRHElGDPUISIIqdIds261/qga4z4OonLfU2Ba4IADwBEzX46k xd6GokbbsNUJScaYomy3IwhWm9ajt5kqPBZLFqJLwbXqieK7BVabDNIbN9eGmHAObfmeWqGM HMSYTAwfSgf7GF6Tu8i+H44SjvnAVLqY4wdh6ReWD9+STHA3uJv2W1KviekjXYie679bYa5q jG813uZcHPG0EdCtRF46QrlYW2stxKqb8mtU7WXAk7DC7Vvka7wxtMJbzMMF/rZsVgEEcJlT sUV5srj6eR4DZiugAZq3Qz4DgxASdqgUBMCdrwVW7uSHDgftWZGtjR9CUC4vmZSXHaOXTAT9 S0Vm7stkKpSqfssJJdndfKFOrBZyfpX0UQGvZwBNGKnr9YOtAd5v39/MMV322ySemFndRYQG J2xqS3Pe7ZGi6U7xVMIc/EJ/ca2kAF8+Ho3LAhpJADqPQxF+AmgQRsN/yqZgg4U1evNkxXD+ HYbRSvMODqvAvn0ksLWUmXS1X9Fh14QhYsda7wuzdwMVmegf/RsZLfwGJHNrBlGr2px6Xje0 PZv44ouFtmHBo/W+MeiKGHkqa41MVyZOWteWMTypiZUif073+LXa2EoorvvV7dLHDrMRWYF/ 8Ul+dRrnrX3+0WVXuMcAFrf1gmC4jNGIF+34m9tSFwKzTNvrZeEJGgFE52lHVBtOvlyVaSPz FWKfaIfHSN/xSuTWAb+Ut4QdeBR+V1+t+lMzcMAkCTgcKRIXV+7vGtuuDa3ClFU7uy52oMc8 fR0lUA1DDm4Ec7fzEpLIjH+R2Xcbym0yFhNg10w7D4tGCV7Y/i5TPXifeByIuAzUttTKki7P 5X6O428StyAXQTUW6B4V4z07rBHEvAvTKIGRJUZ9hAV9sd0wqo2Owqj8YW1c0LayVVB5d1fu 5AUv/xrhhJFVIUvfwkcmlc7FMxsqBFtQyXxDl0RRnufFvaJWvcKeJmJelbqHAWVloAVgEduI vM/kZbxltNuUQIT4mCyN2kzk/SBqyn8Hv3mRgKG2Vdvxeq7LPiXyyS1l44fqld+3kX6kY+Jn wqQ1sXGO0HSiA16ehXieTq2VkTjn9YKKVYw6VE4c5SDvIMZJoz0xasgEqasM5W+DjAPth6eO mVQu7fCwT25B1JPGplR/CACGgySp2ddPZ97lSmXx3qmr1O6IJujkUpxA0mLdO/TcBE+01Lqj ENFAO1fFZmmVlUYuYrr9Q0098L9woa5RWP50ANaZJDJ+wNZi81MX6uuprMxklOl5mX5r5yHH jCUdp+xR90nuMr96vX6WdwUT1sFWq+V0mj0cAu09/FHG+XnJeEAhi/CW2ZyCezsaHrmRM2PK 3p/HKkEOs8Dg1aoAFI+7nj4VAUXDZiGt4tUwIHPDnldCHVM24HakKEBdqjpgMHkYKrrlJebj 3P5lptAmWrAeVOD6B9Qx/t7Rnw4Pil8qR1/xi8cjdFGSNYyfo3+REDsmxQR5K758GkxuYExl 0N50Um4C1bL2imNqrh+pmBVL8q0+YYGGRz4v0M5xcCk8wL5m7OqgjN7r39F6YXmSAOx3GW9r s53G2QuJsck84We10PV6JWk82QNTrHo7VloIuXbeuWSoY/F4bnPGbuyWATD3IblUKpNxivSi JWbSsKf3ugGOPptqdiB6gWN7WnSA+BR/3gUPrh8BNVdURkm64/0/tNOoBt8Vjo3OxD2JZjUW 1M/zk+plKMpoZdzPtZYR3MJ94oSCAd2qs/+dWv2NVkdKDvX7xyu4OyXVx+fTnepjq9+dl9OH OXcHo9tQvuB4WKj4H4BhO4hsQDVuVYFV5KJyx7BOhJi5nwzN36BGVwXqLLaE/w3aUPSRqvNj fDZHnXkcavkE8Cdhj5oXUXqEMOsK7N8zHtIkSSTXSLWtx5TY4hJFRuysjM8F04vfQIBq7Ue2 MGOqnrzHKNon6UPdiPS28Yn/64mXiqoRrZvYOPC/W9xb3ggw/c3FoaWwBEF+vyGEjoLjCljt ZeVHHiNAK7SXMOmIbRZPXONn7kiQ25FGIBA+np6kMLHDB0RMSNXdCJ94Ya0WbH79NAaoNodm rvmG/PFyB8bSMv34HkZ59nofo17OYs0TsO2u477knN2O1TFt59TqqQ0ki2Mef8yXUTlUefzt KbF0wHAI3zR9ITrMHTilQT2876tM30Ff1zdeUlWptckpNF106aHieJ6o4zQz1laFYHn6Mkbn aX+Fphsq2x6DxmCw8/MP+bZns3rIfoGeEJUK/7Pe3PWrHRGe7R/I3+wMloMGSM9BZ2xl1CAq tm3S3YpG+Aa7TLVCDFy7CwkxcJmyI47aqfl1OL62Q6iCO9Ti39Nb13DXBCB4jJJu2DNGCz7X ziaZkc7Zq3+fPwaWecFat8puvvxcTYLVcV6gGlhODNSME/guWZ5eBWbXQRQG60710OGrswvU JecqOe3YnNxCPHypMg1eB/LBe+1a/PBxniW8raKS+JIyP20xm7jX2vYOH5m2faoY7R3uSHNX 2hCWK34bTT6BGwKTNvIh0QBwCZJYcvY0N4WgxWZKn754oLDRvoiKUrVyHe8yVdi9UgNekz7V hfAM7J4DUF1l4BO+pY1lCApe27shGRpfpI1PkqcxRIE1cX1vb24rJ6vnT3U5obPlCjKohc02 9Zo5uAmKOT0te7Y8JkEF19N+t/Qmft/p/cxCyoRSyxGSJtGdYSsESNH9pCKD0vktzC3Rayao zgGFgEiKm1Ze7/B5YlPc66Whytn/wHf1+P5AoU5BJOV6pHX9rbX5yYHL9hhHF5roLk0rL5lI +smmkjBIllaqRRqvFGiVucIkSEUxuGiKXGSzCkanF83DGmzQZuG/arn+hUXW+D2is3XyCQeu lYn9rFSdOBxZzvZz3UPxwGQ/O6jP5+P0hj54B2K6BmYpexHI05+8WHHoaMouP/qa/Jzfo02N jfAJLs0CAjYy9c5Dlitqxp5G09tDR56LezKYdIwEJZyKbG3/bw9/fQoAFGSbQMHtR6s1oEF0 4N49U5lv6/X/yxRDFQn7cKl3rrODIIzwaAfznsqG/tWKQCCEVToE8cZYnCLdIwuMqwpb2bGK ZzxDJmmK9HcGUGmBDBwbFUftXb0Ape42+FZKbA/II2+g1JZwOSyJX93tJF4ZlXPZyCe/cvbX cBg3C4C3gef8no0hfxvC8zkGeI4McU7qbtiIT5PYCO1YbGJWHaQAWFi0VQroGcW+S67vnse/ nr+d0h2jA51zXCJULq6ultA9nENfuYRHu9jCjWf+xMjuyN52Sm66ZQD21r8d71IsvYo6IMqs eM7u95VwlrC1Gys24OZRVEx6/RU6yRMTBgvBLqNKO8k3qJe87YgwaRTi0l7jbgxQGJhe8VJG WnmGbVXOyCCsfAGcZq+yRdXe/H4AL7OSItWtWm/9BU5ZOlhhwO4+VD5WN4p6b1pEY+KbW+ee X2LTQrAwblITdBydbxt6A2S+hehOKUbNeq8jlFqll7YUnHpytmX+HK9gJ5lqT2pZ9EnGJ38v 9ro1+6Yyl9pKN1sNlxtxfH45MrnapxS65cYrjTWWPSWiNGWnw7u1+jgsEz0b4VQ5e2z9bvRk eHkLrcR7hI/nJSiW1alsGt8G4Fb3kyVD8zG8Kd2oPnHmoKgfjDcdf4t6WVeXmRYphojfRRI8 jMiNNloTL+HgSSASoLtnjbgG7tkvyCh6Bagho5uMUtadGO/LeK5jhHil0rc85HeSIzZw0e6z ZGy2/n43BvipFvUTZuUWHaNquWe2rswAxdZqK0hETCJYVuWRsTdyQ1+nu6Ic4upNtyegzPbA AL8OH0FfLaIK2g7GZ11FjwMMu4LCsGKBpC35n6eVjJNd5MqakD9xYTS3Ig7S9SN5exspvZo6 iiCtE9b8xKOrP3vhRGjG4Z2rrxEeBQ8cGrvcBBI9vj3amDS5Bh2uC7RR9qss4Cs0jIVDWX2n pg1PXTe9Ar92wPv4gwls6gibDX6D/8ldTDhQutQnlxpPPBip1d5VHmuljOoAqLR/8/plfVDv I5Na2LSpdiEy3M8b+VUte37dHcNxQbk5bATkfLMu0QjIhIIkIO+l6Wxn9bQaxqk/HVqCvTpD HuHP7X+SDdesK5+aysYaXrSfbZtKbaVO9yW8hMKoVQoKXe54O9lRiD14oMlzwM5TcocUoH0N VMDBZ424SsGsd+m6+2WledjA+97C5tMKf7M+UBHWz7s3qoiWcDdHQvxO2maxzh2n0ytGSy4u J900WT1C2oskWNAI3zm+x7a3HWfMcNDpRxEd7rI4U/1kBbW1lwkrvZTXsu/to1V7EH9IqtVJ ylDPQEp5lzvkvzA5Rq3QwdtPW4QVmB0zi3+aMRxUhgtA78cVP/CjMXSqVvxbDSXpHd1/QlS9 QmNxT9Av2M246zd2iKSyTZFnn+4iefkn2+ruqaDD8TyU0A4JwrzZB+FXm7HlAxN7ecRNynV1 hQVh6l156hYs4X+DXqgsgPSzs6QdQtNobpBvHQB4BX/6H/ZNdPYK/jBt4J30F7XIQr3NlLIL W+cBSuGRgBqRdKdv9heax6jep3EIfVzuBI3EH6X1bcR517xybxPnkij7ywDgU51qM1eR7Fjz NClySuatDftdXmlQBk+Mb0z3Rm1VrLQpr+sw//uhRxHtTnjzKMTttiLMFDjKC6UTX2lzJZws 7/yIoJ1L1IlND2DepoEvoxbAVzB1tTWD+bQuedf0h65BnYMeyishtN7WNxYGtfoFrwffadIV vZJ74Ovix+6odTVELptsKQZAW8tNeA501OsnLuR1y9nWlenY06iktyHqaDkEZpf1kejoJ+qw it2ticUZG8gIpnlny8ABmkpESJaGbxI16SAU8vzZ7whyGnOo/rJxHdFReAuVBZ3y/1Fy8UJy J9fmkMhf9TdZ/xQd26odPiBsTjNzlkaEZSn13aeoPbrMgEjjSXACX2FVIXm2vXtJlzMqdyPD Mf8NRPwe3QEnOtLNbOR16oaEgvwRRfp46CVdGRTzUR55mc9jfPHz9yFLxaqnVHL44adK7GEb 9QETxZG+js91WIUWoSVfqq2ZNVcGdhD2nQcGfFngI8Nx8MqEtKXp0p/yu5j6EWGPw0fM06kQ 8Qvnyda2OQyLlJOHpaYOY+yIU0HLOrR/oJfwl7lmloj3AAD6lmsXVQv2UASeJ7dSwFOYXUnv JdziCRZX4t41mF7U+fL1M7ar1jzIKCrvnmH+azfAu0H+XVgmsGBxy/sKu0fXMB2xJlSIwG7a jOy2sMAbKIFyRzTUPEvs9U6YDrrXGPuX9VtgMCGCIRge5lF6hp4S/ohCvp2H9XhCd2mTxond jGYFWfHIZ+WkXGVB93BLh88cgh5/CCNQ7XCfGrfLnsJcOl44BvZrqOVpSrcrHZDxWB+Bzq5G Wk9VvjYxFnaQFRP/hcXv2kVA0ipeadiXfGZUBQNs/Wsb/Xu8CrM3Y3lrCFUotwESyIU3ueuR f0ePNsHDSrugAdds+jijIb5UpOPUPz+ziWFTCCod+v3HLxhAHnwYwMW5OTh+cvM07XYBvZrs goD6O+pSYooqqG9xZ3iitRBTkZk+pcNPf31l3dafnSFqJs5ZyB0cXGdkvXIrLX2I93TgMedS GZ1I/dBN8XNWQsfaGzl1kTx7ycTr1m0LzKTQklDOMJv5qNZucHKznCZwEA+X+ujoayN5hVFv XS4RAh7+mPki07zXRkSaMio9uF9clHrTdgk8S0HjSWPhPxPXyDSq57KOd2woogqy2pEe8APE IH4bSJdRq62Mi+oZGW7K478auRSB6w/Mrrb+vBl7d705ETGek0QeCgzIOQ6qYuSDhnD+58sj fAxtpttYDhm58r6IYpe06T1GAbI+l5bbwPwPGsksoGg7BpeSkLMOO+Zi6VLCBYqzfCvzua/3 5r3CmeB9X5pPv4mnZ1//4m4yFwXftDGT8G3lRuzUPgwM9ezx8ZzAx6+6tOGqDgBPyjULsLhB CHekVvBuIm2D1GvmH0YXy8Xr46s11qBHDtFfKhbZxMhSp5bZMd23wFgk7Q4zSw2VxgusiBWA rRa0e1DVPQx9ly1K+iJd+b2/WmI9yJdXi0ne4oIbZ0xxyvcfVdG3B8QeZKPZ2pDXE1Q5WkXV fXz81EX/uvkf24Q0bF/4ArZlM84V75Fg2IwwwyV7m1pO7Qa+p6LLUbN8K31LdhXbYSrj9a0y CQfjh9ptVxTKi+3MCIV7u37H+rJulsCP5ZHhosVJ0F7T754F13hcOvC5C9WTrhBJv5adr+9I PL3KpHCWK0HqJxLRcr1s2XykbA6UA3EK6Y+PkNffYyb5lotlFlP+oxoDU4r/x7KaaVXzZTVt Im6UY2loqb1+1mZhjbex6ABx6FMN+AUHt2PG8jxBs1Pik7Ql/8gQvGM49t9gKyesUWQuCzz3 lhUq4ZzZmuj+xStY7+TtSafyVVNYjDXqqZr45bnuLZdBhLYDVvoZ55LBBBCIhPvXEOZrNNhy f8oaAdd1EBpNn/NrbXqNPc0WY7wc6sIibBt/9HkSIm5HvtwRhEDa8BILsY03F+e4mK72UlMB 5wx3RLxEYxweS6YMg1g5h5L7RHqCdqUVwb1WKHIo99qKM2kd3o4OyiTdl8hS5St3LbKa1C+i Gn0Eh+/XQmRp4jt1mbnmL/Lc0lonBEu8oQNtF5gSXRkMwKDRv/Kz8YrUgFABEdaBoxBhDSyZ EulhkYs+FOpReIw0M6oV+ORwLpYvjO3KkVChMIufT2SMLaN9H1781R03QPLD1ICLllRurh4j RHWcENqAUt2D9SRveU6lCjq0jmZHgpew1Iqw3hZSnRKtGzUos/IvwxvktvKQjn+0IeZRWTph Dya2HwrOn4l9sF+bo1g8xOya42rJ9Up8YM9NBsUn+DuQhMsxz1Ct+Y34WcM4/5pRjN8iPP// 5zxsZOB3AWLsNYDMSCONT7XqE6ShkeVpwyhUPmUwRmDEqc1tOKMcpJGR6vw4LFpXYOsX4pgM +V3/i7jrbA6+CAUIGsr1kM0hgv6njcB8xpGUWJedZPMZ4apGAoH4uTYIZTJh9GE0fHsG7kBe s78dseiPJMBxr+G3fRuv+72zBWhAzdfZFXjA+q0ezyMk4QHVr9vPhT5N9dX3FGIJJR2246Bl 9wwRyw9B9Uz4IVUghJ2i119wQuK58MYwWRp3Yg4DusplRJFPgbd2GxOK8KAWbiq1nlMnm1+8 Htx6dr/iW6Tx9O6zh74l8WseFEjUtppcSErBMqx/2exhgkx2ZQ3i6/C7wpHgWUGZkRnffuDU QMfGhin2lUuCbcs51cTgIyUveeQGJxlbP+HYuEk9v/Qgps8XgTSgMIORrEFKgyw3AFNG93+j cAhzCsxFOidzkrCnlvdRwolkA1JVCJQQiDicc7O6wsCExuzRUxpuIFvy4oug1C4mEu7STj0J CfS67VyrXtJyGACgK2Z2G+9DNUFZqaRLCu1lfBbWjUXHhY123/0qXaXnPiokXOx/OeVJgX7q 92l/Bb8AvMmp7CYr6n4Ff0IC+klpcTkJmjyaSt1epA1xM+Y2ln93nGGSv59JuZOX1w1C00Ay KwY7PM92ZsuqWB1K4vTpxABUS1REaue1NwBtGIWJV/Ql3h2vtheIV4ZdEEnlBGnkxnaiaQaT XOKR8MPfuHdUZf0XC01hVzay0o0rRqflEmJv7c5yg5c7eC15xoWqgDWav2GHktg3wnO6z2Nd moTMY4k5kL5yWC8EDXNUXJaKhkdVqjwF6NG6e3C7K+JwhM9e3EmoTF/qImntxz0Le+xtYSYE uLbPViNmh4JIcTEoctZVMiazfFs8j4JhJEL9gUKyl/NOXB0Swl6E+NnCHYzzPzuX/eAPRmKx nc7CVwOPMdM9LeO+E6IqEg/NbL2b38NPFOVDFLHpCCn6w8djcDUoG3n27bScNU54Slr0F5zH xzlyguFQ3xdIqkH9Qg5YQiuV85U5yyNCiWOGIyag3UR5aUh2CZzqHBdINpjP6RhkMcAgCfGT tXGUF9VChzl+rmZSvmU9dWhscHlAepH7gjDISk3/lzjKfyhSsSs0h0eh14ScLfwijWCQmiVo TkQx//YNejL346IcBWGYMMYW9hWhYKFtCvanEpVWobLcOlTkDcURtlYF2SnGGFq2GXX5GE38 42Fzgt39EdPwjSmXvFV7XgkeK6oD9kLOdZhHlQOnQTqVxZABm33/abvCUZX03CO5m44yPz8B fAgnpNsOvI33xb8+8H9R0VBvruKmijbfK603RN8LuafwF8OAdZIhHvg5BwQite2uP8RuGqCg 2r/6Lr1f6dpmbPBZOg3o9NwKyObEmUWkn3m61Dc/l/JM0H+OFXn01CmgMsdrXzI9qMh9FkJ8 v6FlXcKK1detSNUPJu9J/tLvkjB34aZxA5vx0vMO5AUai8k6nb9N7yEK93JoNwluL/xWTlo3 pdFxxEpIfwS+1/cV51kTffiSGVCUVzGzuX9LjNqoO1Rreli/jvi3J9/vN1LouZdYF0mBZITT /oOyWfHGuDyPkkd+XoGxq4b0kssh4H7f8CNH7quO33Xp9OucNJFpJGz5pkbPHPaMCX7e0SGq pAaaTUieBKXoqhKpeJvLb7VJvr1jpZ96DOAQ0duA23FyRDyj4NM5v+PnPqDrHCoHbrHae5Zf dh3ChRCQBMuTcSitL7df7AQQlTF8bAaSmIj8Osumbcrt9jNyxWuKZC7A5g0COIPIlYuhNzuM E7WJkYH+VvnoWFxTSrXSBI712JEeww5ItqkoRUJl0UJ/x1O/WmUxjtGv2xWJkEhI56c3Fup2 86/Xiaxf2FN//VMMNjE+hWnctvwzTmbp0YJu59mfMhBFa/S+RD25NajvIt2S2k5BKy+NtwEz 5HL0mJZYbMia277RWIUn+IbbbSJ3mB1kGSg8S3RPllhG/UbzRk5Pubo2WP/wdbla2zYQ6nZH g1F+KpFGPwZIYQpIDBhcCtBjSwJ0MmHQVGlnTLzU0b/25PRkDn+1osgrf+T4D0Nv97W9qCBK 3YfMPtJW1z17U0y8GiwPyOwDHJVXQsRPXZG1YG2+9B4es4fdmqcUH/ou0dtVLLWprf0twXPO 3mLnHuoCLdWYUS49x0TOVs21fyHmN6UZAW72l6LCiLgRJzSjId3ExI3z0XWtuLwR6R6MWEkC qhwOtZqWctHWnkE/WN/MQcIAYh+bydtcxE10yCsdM8u/5o3HnnCYQALya7Cqe8GkI/6pHYMc PEEo6Hg/tUGATlEmVsElI7BOgbN+6+us1GjT9TO0jNNoO81rz8mfC1KaSeKzmwgHJoUPCRFm 9GaYKwVi95asdLkAZE9QoHlFi8ofX+SyvNnib3la3YIpsuKKbsfT2WH2mrFwvSbVcIhHve6X cYGdtJ2CcCn8KJ4C77VYXEY843Vld8B9hJ06ffN2Lqx3ZwsziTLpsjeuKCHc3/Y8kx0SLIa5 RiyZGN1RTh2YdropGnFJk1xKU6nR5NFA60eECB9fsuoZjgws40cN4zXIr5fG+VfLvVTnVLpf TGnT0sEh0pxK2wPHjYmm31MOL+awY/e/ulPcL00MgTxnXJFOe3B4XnxrmfNWNXVXNE1eg8u7 xa9riEd8z8zwpfP/XJ6/44j1FNW9G00Wc2qlJ1jF4WflqDyJ9IWoZOMxb49gukH3DmEnZeu9 qFzi57Y5zJZT/oqAL7n+1h5wvZmv3yU+//Du08tpC2UQa02tb/0nS9bsaTHVFDlMW7nIQS7w BFiuyniCLNac8sdA0w3pAvb5WrPlmQ8YgFOrdpMQ/FFbouJN16awlJRzotM/lkeorX4RUnDh YrQvQ9xlOWGe74nrrwBeMVFD//9CFXH169klhSt0OeSXO+q1AVg5iNnd6hPCnUTKZmzHNMZ/ Koh62mXDTo34sFbhmjbjKqc5YnI4NIOxdagiUC3oQuTMLzYWhx/6eYeHGZgdHLlEB2d1V+w8 xTFMOC/8zIl1kDHPLYsT/foKTr5deT3tDt4kBB08NiIF/cntwfHLC5dmqcfnDPVnwLvjGRFc ep67BZccy/G9xOkNcV+QbUJ7M5Okewi1DsXXCaP+/IVSu1eW0nf2AQwzydjdKqA/zBRyy+U8 aFunvxvdNKLuk6xPJK0VPPh4FesIqBgvIkL4BwrN8TZqTappfxxhmsvg277lbPlq8kut+iH0 bsdXIKxsYv1m1zPmWTq/q6esXGX2vpwcEVny18EJNUoOR5cwYG+68JiT+bvDlXgqbYFQaQ0o W97aaDFACKYd/2T53oHDQJEMc+H+d6gTwOw8Hc1Pu4VL+FDfa6/9A1U+yDx8HIuIouS9B9o1 BrQyAsvAcYbZ9eqT7RGlx9grmKYrvRg+LjuNX7C2YBHQmFLDBo9n6ateEKD3JU0FlNAVIHJ9 QQNqhOaxjMln44i2uAwjH3VVldkVLNudIno/zBjzeDkXsi9ydU9KMdYGfsQkz8PboeSQ1zg6 3/jYvbW/s5U2MBjFGY7Cte2pznBUjKX2mhDMthBqjlHt9tXpeIkiS+OXPIb7kv/RdjbVGjnl HcsXbNPTVfWkdFLrGrZHo7D5No9Whb+w3geOcF8uMcLpyMKryfrsqbgNWIocZS1V6iaK6BxV 0ENytJz6t+ylXPxFLg75iY8eDYgakOajj8UqztJkGv7YibhNbW9fq58CXHCtcksZNsGDv9UZ Amekd83OFHBMuCf+AI/hZII6l9XND32Xdh9Hi4i5WTjtIuYx/VLiUJNqcrJ5xwS4sVNvYPtq DpRxNKWDeN6ZN3adrmNvJwQSmHCHiFynFeZHEgRY2h+ZQygPQEpz/WhUpmvufe5T2BlsiIk/ tFzdKmx2oTy8lwmJMzza7rDV07lJkq3uPa9Gcv21EQAJ5ywF5mErGSFzmAkfI/hfAAiwgW54 /SzoYrRAXGUHqI8bMqebRGU1a3xxwMJtY2qvZj88wlT2Lvl0OwY9PwCCncZLnbKBXdgfJ60r ryethDzR8uq8x49sGO52390EsAtL5xo3Bvi1X+APlRBgGI99X59uR1sRKw9to9VqyEts+AH3 PjhjAaVCeLTprziGzgRu+PA/Vzc8PFN5121gBZaH+UABRPIUCHgxJzDJfYUZbrnWZOTXzW8r 1TW62r5/jLKSNsYDZ18DFCYpssvmw0zQKcb+kQVnJJErL5u22FLrnpcG5f79k1sHYwil/OWO Kgek/OYnQujwNQqgWaifvbtsi/TiAmdohvAbo27BxJxpKEt9c3Atwo02DepDVJxKII4hwjfQ 8M8/fkRjspX3Gl0K0P5ba/JgApbC7vEmN9hGMhXdoWJypu8uPcP1nBzzsv8BlhU9ixDnIBex ygn+wlntQdpW9HuaaJKDsj7WN9dgF/PSH22McoVDxqE9TSlD7CVc7fw1mCk5Xqo/zxSJI8TU q2dshBI3MqgiEHzcvIGyHIU2TJwePTEvBP+vNwjADfuD2VXfb/kEHmrsfqdcbrq076SclXEp PX3D63N2gKm9qvUqapT/3FF3icu9U1VL8CZ/DdT5qsRYqA3+qEHvX55cX7zczXJB7XL5aWKQ A4LUlxGTazKqhcgpm7Xf1ElupBTkq8PfFpWFfZ2xHZ1JvHgktbwcxKQP5kVq3oaTNR3E2qz5 KKnGkhPjtPQXe4awpbrMF5EKuZkee5j5kbjC6Noae96iyXFGDyljG2aHu/JlpY6xu4Uhmm6b KLWR0fnSurGwqtabU026PYSlJps7j6n3RKk65kmmKAOJaFqH5DKJVrSpVRKv0+ocn9nkw4PO edqEourmKZTSK3jK4PziCYJNr/4fHJsiiwpx+Cc5pXK4/0n1f7xSBCkVfGT4SNCFfFe8ZN2t QPYrolbOjEWY2PHk8zgeI6gm+Jzv468ZQ8ylZ62JACiu6W2Izf6krCEZgYTB1dFdpv78/iXn OzoawdPBosF4c/6FXnP7ruXio/5EQhDuhM2iWRNarD0WWsUTJ+xWvy1g6dCRLmZqe/SYWInB iRluRQbqMZZwj13wuFgwGXb0kmu4iuvUZYzZxqTK1ccxEzJfojbPFvjiaPXqC6I+f3qHhirO mvQ6AEzPrq1aV/i4cppinlDZFCltq6BGaVBdYc29RfAroe898m1BP0It3FzOD4JGVg2DXWq+ BBbVyYJpN5O0i2MZIk61EL0dk9ACSWdNHjDGC06fDqcCaqMyloWPwwYrp+XjQU1CAASGM3k3 ktFfIHX7q9vBTtoa4xb4Rg9p9O5bwQsFZiVEHxjmVVleuvrSMYI3Zpr9N9P7uUXhwtEUGVTz prP38tv+c1BV1KRrBtJUevVwZg1WjJTPO0npmcq/z3aSthVw4njLblJ4h//7Lm9LGOb52jxq CEnk1Ujd7q6EgReJc9NHBBf0Kd94FM0mXJq0ft0zGX0r9KtGzZfSL2m+cz96wSzw4sb/JH2E QEHfkhuRRz6ORdkhJVnytiWRPO9at6UvggAD/WXXxatR/yLAoAsytBLzLG8jjEVegNq6gxao o+fmZrjQPzT1rl5ZeU3+IxkU4hRfI3ZEm/Gn2WXzxO4BW+pJG9ToedcMwHo4nQTKR1Sijj3B XPAQ8lafXM+3dO6lHtZW7FS8PGldqR0+BxGOezIUQyRXxu72Fo/x9Y0rFjRyC4is3Jq/5HlV qtZ3UJmQgY3tcqF3PyIYx+wpvDnF0Ui5sQG5qnI9gBr1onnS3mSRj3F7wcquOBDCOXJ8V4T1 hmKQx3JbPsZiMrH4ggnN9ky22M4NQUfzPC6MrRTBsHGTzseWhjVlUZXqDygJp80ycxo3s47F ZG18o/+S/4mQzYqE8fNqf+mXy2F1yv5kSSQlcaj60NChwYbyTfRq3VmTy7tyxeWhZa295Xek mmejYybJWacehK1Ffu3DLm8eNtje5gq6BOQPOnA2kDqB3GD9Dbs9lr6v/QO2SUowSHqsySeL EaUJ93FttqRgM62yvCQH8XQhePfX0H8toJ16aENnFYlPxIvLnwAU/LuIjG4ejzLe4gb55TOF V0TD//qK+74whhoJJaMXrfb193gnshAANk7uRLgT2ZcCKP0281uKyLenbybD4rhJrSafjpBa /Vk+tN/j4njzIgx5RvZjWLBgneTgpujxg6fcB5kqcJU2DjBs5bBysxYpg2d/VtEIhr5fBBeN DBxiOAJgY+n5qwwM2rxlLKVZwcoSc9mFlax7zzxlPbq+0Unk4eMQ8d10zLYQFQJDkxpw43Vr uoXQM4Z+W4zHqfc90+riXTt7CJZSznOI6z8X6SCk8yMH2AP0OpOlDya3w6IBLyqRS8NFlq8Y isdUV4acJWA8aCtkhLwJMGgswZhSNCKvMTVXt/U9tCgMN8sx4woZpYJrtOKwDZwBx/73onVQ y76aZTGI8MkgTZkTGQBzyRw72d3MbDeimzFaMfX5IhmyrhTlPXSYE4zti3b4rs1qhtIQIrr7 XOA/0LUbAN1fWnSJ63vHvnWtmKWaw9DAHFU/WD4A0BQe2KLcdcN2Iob7VReMi3adZQCQCPn3 9MXb76RUXjx1aAh0+rWraeXQ3t57b2X5V9nfFhnKnBFK6CKpnlERQxn/GgXjP00KTSgV8+rY s2xpHO3zEpStyfDc9u+0glR4G1DH1JgSbCROzLW8A5aTQ6IerDQg+9MOn66HHUs7ccqxuVih kcoy0QjN1h9WiQJVEp+Uru4dWqrPCnSz078+uNCNdXSZILldE3Onhvx1LwX1fLrHG/5v1onW vXWVveoTa8hJ++0tgVqN3LDmvob2yKKPTkbqsjn0NxqlwgtoOmr0+XV/AoG2I9HJa+DTFvhB 2E0c+RLj8PfJxEyaW82fw9nUAlGMiDOnizFh3i8cBODRv4jkxmW6AmG8V0aXE4jWG+UAUUSN CTIbDNABe4NpxagGpFh5fYi0juuGdoQI2GbGyXKP3lKq6GJaiDqi8kPoUDtzIM5XOILtiPRH iovNAaGXkSG8oXraTHMzmhTGFeBsrH9rezhizMODDzZSCIVH1NtysChTCahgFessHW9vdWpq lQQE56iDE6FbNRa3jYNlkzQHIiIaYHYI+zNKDu/SrQEJfBH0mY5lVbw+BIWQ3QzpRXfNBvd5 xQfjTcw9u3WtmDm0HdEw/s6njaM6b8BcafPXRFWYk5y1gV6NPA2KXYMujYf4N40ORxU6VYBp YkDvohO9EPSnW04XZNUWJz1k74j4eQmrKOF1JkcWXDXefGE6oy2uq7JltYUIW3r3tMETkINH IMQNN/eDZFoZ3kMKzwHy2Qn6oR0O6N4+r55SelB8OknFJluNKH5AAt8bgv+70S04ueNg/1XZ 9ii7yD/Kp6/PtNHkQCXiyP6drPM0WYHro3/mOWgJftJgRZRFOlkiKTMMTsuSWPPoNSH7xwQe kiTGUh49V8/W35i9UPSdYvASpL5Qwq1L3zPuRo6wwLWLteOdfEDzGqRCjxxANG8Ow3cN0dnO WN/S2E13LsC7iHXqSNwrX4DVvc1+rhheSLLNvtOK+vv/9H+DZt/PJElhc5oYrSz4lfFZXNP9 IoFVktj8T7QdsTu/UqqqRyh/X0u7w09ErOtdcfZ261HSiM9RQccav/0lYkE28yaCP1hEnGQP i4unq+DLRhjZo+q7GxeGwiMxbLFofpokJMr1LRt1AJgVxhWN2Sk13Vph+H9hC/mzjYLpnqMZ e4NbMGtYEPFqPSG6ffQJ0y4Caz4nu4ICGMMR1sMpsSwUBWg++ivVW2mgNKW6Pmie8GOQp259 E6NVzwsn7sU4w00mWY6z4W5ILGzHNlMWeB06Bv6Hi5MqsRsJPXmuqe6qKA+nI15oHB04lFsb 7Bfb3xI6pBJ8b+lvuskB9vdObXqEVBEN3ZuOfaE2piVWI60Vn+GL86MNrebQf9F/Rmm0jRhg ErdwuhiHs/f2moUs5caWrYU8pFVgf1bOc0SqJYt88aRgfK4nhX9uQzjVRX0qBFsvJgUlsENv ngKWk8syyjb8gw8fPAjUQwLZkqRaCnGLa3lhSSJ6wgmJ65+CR2CnrCRjb6vzKf6yNye33hKv 0lqHR0W1VkycGB9ZlxNFj9gdnlb2RlRuyd2P5AnLSunKrPGo6wT1NchZz4lW/fyk9nNzGXDW 2fi+9b6XslQ6GkITSDZj8vdT0MO7LKtF0RN1LtdhZeApeX+tqeLVdvtTmODVchokzJHe7FCz nUHquEVGtgI7bz7b0DQg1WCmH0OAeH+u5oEMZNI3JNOCmZL3iJloGqwdcMqdOpUhpbkD0IZ5 angUpRNW6WFvyrbSZGSBvQVTbI9MQsUbQ5vokrh3CKv0Wb/OUrOuZVPYbiktjr/6BRZdyjkY CN52DBmrxl4NLG3pWjnrXNUD1nNqd+doc7mlV3Ohujk237SMxV6W8knUGOCYxuhbUu7q0+U3 /m6CrqQFF0Uqx8q2VhCu8eneSkccqWjLHh7XwMVHjFM+CHt2eTFXvvf46f4rTTWMdrdXKSdP e6J407Rnbu3hALe9+MKmot1ujNOlYZ/YB7RDAcyxzY1e/rdaBmYTjfhIL48sunBUpV+OcqDr qLQIzs8qb0e4xRDYY9NQ7bpKo/GvZBvmbAHPfJ46eQNfJFW+re3X67TEvlSqsT8uUuOtr0YU muYFO5mj3XVbIZ9pIAxqFrtCgKwl/Y9F1/uMh4tcw72cHkrhM+6vtseru8J7R5K6/t1w49WL ZZeUJCOepPz5bswlI2VTGhm95ECmRywwQqHLFYzUoOZ0fQIf3hnFnoLmpkqrhiJQgVCcPUsN 6iSUNBvIX82W66np1KonISUPu5RcqeMHiXrajIqiexB1XbEntoRNUOUallZPrATtbvSc6vCh kcCDRA/ryDKhypVbO8n5NcLohdiQYkjW+P92m/pg468+DY+Zn0pQHBcATu1NyZGwG6+bZWyE 95BRqGPMERta9x7flzvUynyzm9rqThr23N52W26w8Q2G9WUY7dPenj1c5E7737HX3/WgXizs oIxckcRYIzcuJoOIlQetyI+aWbYqUjXDIIrxO5NaPrNVXjfmZcFk6KbA2sfCS1Lne8Zh/hK0 AexUfHkn07RujG0pdRuBXVTITthIkbSE7or2jOT98OtD00VkEWHlpqO9a2l6rOI98i7S6ESj DSyPfK0wClS5PCRCBmD3tZtIjm8aM1sCmCBkvEPY0BwR7zCXKQiKKNjCQ1H0SwL/4qAe7n+i rtmCgHq7vZNUFeay66YVZ++nI+kS5/lV7II0Rqn5+t0XKDgWY4Rwgl+DEupGXYggzAi3kWFS wEoeH13+lOtyOl2SXIF54p39DEd03w4Gem90u5cIm9S7m7OiZp39qoHvSKFPNBLkI3ao+3z4 44x3+/QJ6VJlMYk8mKV3Xm/olH1k37Fz4TPnWtcRdmsg5i/pnBJ5QljXG5buSZMh8Grpn7Ns 6L4MJE+JI+VoytwPpfJpO9tNx398KWv1JA7gniXhWfN5nPrv8eNuHMffgzQHzQZx9cYR3X+u Qm6knhPk1lcBbsvq9Fq3CBXBtFAa8kkwiQEGZLf7OjLLHYoO63pbIyUa5ursacf9SiyIjuBx +44uEmwANzP5ekOrdVNNsmC4sf/Go5QVw+mcswIv9UnXh7uzXMw+uor45gTJ3ORw+KYla5CN YOUhxSdQweKavQM+EePrL/3t0r4Y5fy8DvqeJO3PBJe2DwkD7NwMSebdyIq0Mmm9wZT+QSyC oS6j+KpaKIj0x3lMp2x7clZ71KhBDSmPbfKzucOpKWOpCiBOnPHAb/2v33n3nKxd6voMFDge zQgSoFwOKtxeSZxz5K/mbXRiHqAfZcwuXcv7nB+qrEJ4S/Gn6yewwf65UK5dbRQ3eJpc1hfu i7Yxf2yVkVP8dPTCOFyX70n3N1F5pDeMw2nzWBDaCKfEBX67Klt9J01pBr7e/Zs5v+AhOibN PH1mSBx9Dr8ldh/cEwfGzhnP7b8LYY7+/jleLCH2PAHjwxgWE4lwDlYsdLcyqSAmMdFhTkQJ WbePnlioK8tQE7PbtqK8CXjPSmfyGJOUfhWl7wlXwDL0jOvvJFr7xmcJRjMD2FTNG5HavSFT bHGxCEe/7jJij7ui6tMI6VF5XeA93wA4lRI0gLnIMFYMaPp/7i0u4ugdxFFYt2UjpeJc5+q2 8qzc/KR8qNIO1MuLltfUYkGzud0vik/SPS1dznG1AGrfccgubQ1NPhTp4IHc1oZNh7NvnEfK mF3qj+aXXrhNFc+ZdhK6nk0WjQBF5YA/F+k9Hk7G30n0n90K9gbVmLIzad+Smjox/4Omq63n j56Bb2ug+DyQE1Ozc76i5xIuehVgTNtaEfXL8aAjegnjgdpt/gNy0DY+H5bvjMsskyPPbYnG KhiuZliv0WNIxENOwwCCaQsLvXy6aTkSSDZlw3OXjuZe/DtRpxN8MgG4x6hYZNrCXTmr0wgh AwYsKJoLX77PSPRRRe8HUdtPMH8Gd/We39OybswYjXgPqHnnyyd5FtRLMUVkgyv6fu0FCu2C MOa9EKM/2FLHaBu94xgMFlEICOPA09WiJXidqwreWQ63TYIBSboL7OS0QI9mQ1cYW92IRjSG cPinKG8sRjqN58JltnURciScrR6ywUaH0a9gW7H4kIU+fHObKP7IaQqAKj5us1Awh2H65CyM GkdX2iaYHe4zkQgimmrtMtgnC/BcTCE4w4IqjIYXz3QkuhZ/rPruW2C8Q17F3Yrt3R6QqiN7 ndaAYRbZi6weCnO/4uq8wBSLPS++PH6hAFk3zOg7FvESh2n2txbT0kwC8G143KXkAfGbVrIT QYGZY69nQpZStLJ0P0f6FhaY64+Dfo+vF2VHU0pEL0dmeakWKuCHFjHa3kPnUWggbsaZzt0x niYVAns1j6T4SMnUJ6hMBtA8Pm3aIeYSkKgwN/HlkFrnm+L0a5tPJ/NPCGhxtO4rZLTy9Gq2 8tj9GLJHXmT/JvKOY5lcMBsnV7bWd5uIik8y7wZzY/yA4hmHzfiH1Ruwpqnc00B/nBlwYowK NgJGYc3mNNxeRjKDn7pTts73FC77ori0RgIcnQv7SVca94c1zgwxQqTj6bVCXisQoSPD69Vs RJt4qLvJdJAHK55L9MdRueKjO+KSC45Vk9xexr5UwTEkv0VLMpU/IN7BNvtogJYial+CO7qS nfPxjfjS4UK8E+SdIrl2malas//zG1zPIHs/21Jp/2ZJDsT9XULeGVUSyuDXPS5FBvCh14jh x1/vx8pOs68bIsQvABjSPP7zjM9zXFh1JVrqigbt1B0+pb8HP+I4gDKHGVjAtuJ56Fz57Hg6 dF2LNeJvB5IKvGhJTaFtANvbus3AO+vajSe1iMgkA8n1QDFOsWqGJ2hRoJSFUWA53AAh7LAL 2yMCa78Jv/rxsbo7TEQBrc9/H+fzxxQzb/+SjQ+nZGUF8mgUt/OxaYhXrEo7B+HraAscqOR5 h59hpJLPsjQJ6D+eKCIn2NzSSSuHOwDU95dbaSYVYflsGQr+tKyBdM+KELX9UpegmgI5Fs7r OPQT3564auKa4RJ/yHGw9SQ7jaXtp1phuXu3+k4ak3rCnomWJUGihX3UEJ6sEQ7H8TTeMzxA vRw+Crdn4xzyBoB7x6SLwVfdVH5zKxvrG8n2tOcFIXD0/KHZYK1Fl0++03X57tK4t6fSPaDh +iMPlyuEQoVLIXykxycfVawogKJDE3gIpnDpdhZJrRzVOejAssnWg89VMF+MpOZ7/7Hupanp XRQq1MdLWS2SXOGTf7p0fqkT4OMoI+mR4qjKk880inz+EOTKQ7RXYGjSO+Y6/+rsRgG+KJD/ w0HpAtMPaRCM3LQYXOAuawGLXRGWvNyPEtR3p9s+ERSkIZGG/jqDurkCNWMnIZzm9sh/vJNx USrQKswDFhVDVnQ5wC83FWvZEHvTJWrN2jW/xOSAASZvENKKuCrm2JRsmLPs8H/QzbRPehmk +q8EZv62uQSZFRdW0NsXG/naSJ9f6WkQmPff+tw3eZXuDk6R4J7gBKTJPMPyPduA7nsZVsXT kQF+NXy7l1Sq3nmNrwlGyQj1gsLP7LKOE/w51BhOWmu1PAFc90XG1i4hg3uvUgA7F5HkitUM Il0+Vkxt2LMEirs785JZu2Bd9LXKHC6ZCSka5j9eWTdbKIRq9KvYNuOo8ZhHCy8v4ZlTg2oE aCCb5guNwmkbXmT0rpRn4jv/a0KvfRrYFH7hF9VNnmokakuAMR1zEZwCfmC/LMHh6lfctt4u DiVlJXsup3sun9tUdw8+FmysStjKy/GExGjHvIwsoL+2s+ZDEh1ewWJuHTaqFS3s95ybzsOL Y2rwW5Sw85xWLpHxG7I7V+7tIC3UanTLGfJdoUzCG3aMLGYer4J2d4TbPPJgipgn9eUiffHv IxNXwrya7ufEkPnxV2UsUzooiRl+maXTi0Hnd3u+QSL3P2IV+nc48QokzZ1RV2QBsCwL8gOD rsnaEA3eFacikOrTHFjeG6V80DUSD/oju8rzcJ7lD9xUqeD25TfcAkQ/rWj5op6SkocJqbBm uxVrKC5ti15j0uEe3cl55g/d9qnPzphoMvWMn93cJ0GT6oH7STzOMwf6WtDPZI2Sm8wGg7Li i7P+Rn9kazwhQzEr3XNbSySmeJkV1/5Qa4ICRCblZHz6PEhxDkNmMZnJAx7+kvkbMAnBRU2y 9t3omjI22yHnuO1HNKPOmFWBidRm1DCnQfX91YKiJ+POY6tSRMKmnQXRzd17/ltqL62r8It/ uWJeqOcljGJiap6DxNvOnPCztX4CyOKMFIjMWfa5N+g1at4FIE7jJRtZEQY046RXbZLApuLf oF1XYt467HIkTp5h33c9wi/bSRC5WDTQPcZqf92cvXWOGWU5MbwLIvEcddZI/IUL0/0Bvavy 2fevcm27QzKkuP15rHgjDhRl99ApK6u58/wsG16UezrfRwYt5AbprgKE8X48rXRkdagz6My1 1W1CGWsz37nGnps9DUjvewVr+nT3kLaPCFDqKBzjAysVS/xyrrXbyrCzt0IDFSe2BNHD5bzw yOLWhbfHzWJ45xAXT89En4rr6wYWXESU1PDhJHA0FNaoGMMIKB1lg31A6yp4iTU1rVEqPiEf ceUEoH1pmzCQ9PJfgfdrQNde0EI0tlD2P6vzg4bDf2/NcLhsVWZGTf6Wco7VrU1oDrA/g0Pa V3jOcF7mb0X9UUjrAvwhKvr6aysDo9C/9XtuyKz/yrrePptI22vR4FJym7wzTJ6rDk4w4g6C AtD5cfkaKLq0Qy371+OfJb3bJc4BdWatraCnhKdBPudgsQERZQkYlFTXBB1CPvTz5DrqQY0h Zge3vo2emXaKMEsGXDDpDI5rbpNuAcrwAF+rEauzMG3BGaN0uNqWD8IkKFcKcfT7KnDqTrex JJjrdEHWLQv5U9iV7WCLfz5q/vD+VyJCFunEV2NoycbkZo3YP+la7rQw+toLiAhO7ZhipDZ9 CGEiInqdfriH6GmCdF0AgCju57mwRbPNfQZU2dSmrMdRpoPcuVEwByP/fxnS7TTzLHE0p8j/ eYNMyUzL4yV+BX412q8ZpNNj1iSNvPnOkG2hRuo7/tTnn/AOxrRgtRLJTkkK9NRhoSJ485dR IL/ZKOs0As1L6+VGfpz1kzfpCeP0135HOpkQWJHnBDMDMah2xM6y5846tB7X46yLk7ZSj9/Z rnGP2/31QwSgXLut2lem/sIvFWAOeOmDwgLzZElverO3yBU0A0osEVUph19WFT8S31lrcSq9 sgS1cLK4IIcozVV/xlbD2kmIuyXJnIIB1d8uZglaUSRM9ehSRy+b10VsQVn5nz4gFF8M15am Zd1LleZcwvHSt0WIq3Eg1WYBoKXbhA5je4HGyCIJRYxss9tNgKfo7xanAWSiAXVMJxpImivy xsdhXWnrx9eYE8yO8U04hB8fdfVa+854v89pwMwav63zUKBOsIog3HiI96nDdHrcOaAPkBtd cu9Sm9+lAOj1Jh/JfWiwhnDCi16waitr3s8gMXgIIxRBofJA0PjIephNnIz1j+hWvD9oYhyN W0kVfmmoz6yC1Ylk9x96acgYJFPTv2Oi21CsVBdMipCBadWndPEQ0NEMrf6ZtEUGc2p2vZqB Rnlqsowb7tL53l0DUBXqZSHngBoy2QMPmebSwSdqq7FwHOdA/1Imk+v0SuLSbOVixTagyEoX LM1Ja99H/qQVChyC+1kTuHZVgzjxdf9Luy/8JDSkWXS31WClH2g5gKIyldsil+PRnytZTSTh nu5u58v4gg91YNEHY0LBW0uwzoHGLVOhfqP+BFifWZ384cZ7TFzZ/xT728ZmFf24hPCzpDl/ 0jSDcHTJKpz8f9hSbYtYPx+02IH5SXlYzK6X2bOyzbJ6gP4MAlqy9iApk+Zhg8fuajjMdAqO cOn7QCvPJqxGHNvVY/CedHDqe8pyTSvrLGvTHQ0XzqLesigH0BNjYj8bI/FfYQ4qVqDiuffB DkKk2KI1or5wlkDXUC4Ks6wovXEJfeMhMqflbhXoRsA1YEXOjIgpX5RpesAW/+oeoNcmD8cq clyIYTVhe4uo3c7dwzN2RMcu4YVH9RdYIlRiM815irJZtgao8mokOD2vmDxEnAN/otyiOIwq EboJa1FWodk6Jbr4cwUzv7KxwXfEPrt4DfzgKqODLY0pmWJ7+VHIqTIYWYTeDiRQNWT4Lj/k 5OaybnKJ3Gs+3Inur7k7hnygEwm5DJaxMCPv9uXKyt2nRmmeo6PHKMGoGfDJG2qRP5KTAMsX 4RCwn9GlNLr+vh5E5cZra+8+UD4gQsi1vYQR/kohbYEGxNvEBfhbDyWJmoxr41D/Qbaiw0Vx G2PWHR8rBmlUYpDOxsMFmAReBIyc40ooYv62HOHTcrXXWardvF8LMZaDjyIYhaC/a0uVAZG3 2zDo/DrXjUlpCFE6oF2qXUPFoi4F+NfqHAnfOlqccQvER8NeiRf8cqEJvobyRbrVn4LrOwwf hIS7Y673hq3KXdRuEH3mJQo0Do7uiwpZOitLHG8GF0cJcLpHhitbak6Q6aDN+Hpt2jgD2a51 RoEQFJcnrreb+UQwUbjxfNuhbSHEh1mQZqN+KUEwS1TG9kkH9gHR6sm3RiTuE/SuPGH5RBpl BmBh1KNnmoxzW1jfaMHS7BITP4JSQ+m3/t8LfjrrnNswO5W5yhqfZvZ4yvbvaMyRs4px6W5q ykVKxwoA+h1Z0rNthkCtnse6SwVg9+pbtJE29YD/FIe90FsSJSTtwZA5Xnb3E+++j2h474Vf 0q7vqoHMVHXao6d8Pyl5KW+HOh/nlN9wlk3yXioEVfMzAOKYWOnlTXjyAgxrI0Bj+PDKiMqx NnShU8pzGaQL0x/9bw5G71XmPDUGNCJe3HMTs8NTLN1j6Jjb0Eusmkofr1pUAty9Qwz59iKb MPhTxqe/aPxrqkjUPoKiAZRUoilhvaUnSaQhJVXR78ttAEr3EmoH8gnjGUs3SeqxjDMTEfDj W7EhY5+oXBH6JBRlX7qzGLwHoy/kr2tKU+onDbAoiLnKYF5IX9g8Mjxjhn+rPEmJFpqSnmBO T3Pch7L8pVE5WJ4jOHybjg3r+misoawqudI16BFE+ZOsqBq7MTFJpFt0TGbdlbTyB9VXFfv0 edKoOFloHutyjg/9h9LzdFiheiBp/x4DfWOMwm84mA/cRRJwTISukelyTmDpJK0d7Gyc0IuM pT+rb4DNgznd7MFExDZCyJIKusQA+29sU0qFYYz53wZyWUpIBtgGdEVJbnQGj/k3VddpD9wB ztwC/bNAQEd5pWODtfya8avzz62pavpjkMA0Ch8eTmA9WF5JIjFBfnbuxF1DP1yxiBXLnDq9 yC+dUlZZjuL0in8NIpGnH21Ypy3fUA90lIcgIzd7PQPaGhY7esdCfh3L+nTbB3w5jHBcbZWh NM/Ns3PUJujnDJHST81MTy5RdObu/oeGufqDzlRV04cNMUh06o94TPnTTbweUP8KSsQqoNCJ +nr5p/uscFXQU+91RxvjFsvl21w8C5qL+TStVfzNo2LYTarlcyAA7i0O/z9S/1ZV/xSksf/c d0ks5nU/ITeTP7C/RAFLQhxLjlgElOKi/Ew8hPqTlRDhi1qISX4GufhZNdsJqctwBz+08xPp 2ig4x0+aogOX7CaiJdRCal5/x3jrnf5r3B6j4tRSnFZz9Brb0J3FA/oDNkUTSOGJXYyLJvXA OjSnfVMY4i9JorNwDr9Hby30vLbCSyehQdEitexMBdorjwlktQ+KfLMZ6GVuQHB9T3UA7QNp lCGVsBVWTjqRNDBbvKr3cMGxOUJMTsiNDN+uAC4a2YMfC3POhmDWnALlqThvqK1V/U1hnT1U bN0V4QTqIAda7mDlMV9+MeUB6piO+YZU+GHHwTI8Z66NLNoXHw+m9IWLniqLqPPDcXsjdp+4 FoW1FyuTMbzbweH9JfugwJ0Oo1sRvARH4q4c5irGnBy3t2P0NieWUX/eEuaTeTXcYGjOh4SE DIG7elH1mgnzOaVXMhgIi+62kk2Hc6dfe28/xEsFA9HxZA/X158xjJ3jIURM7m4LClpInyt1 5ozFbkWhAK74MCfigARygTpvP+LtOh8GyP2EvlHY6pEYRMpUz4kGhy+8JrIk5edAuLNNeTz0 51Een1SR5cj1Ey/XvuSbMlAjW9mdcINCAaiP65vDGtTNp1DB9lBpOhwLEiH42qKhSZPpOU5p xNjkSsj1SnAHjoLlF63dAYWS+rSMi90yxDZfHYlei2q6/RAtsUE7GsHr1xssRqy0JN73DsEv EicnacoJm1hfjIIi9GH31N9sH9YksBhaV17NyK5IWXrsJYxCG26G8nhMMgQTk6gceHxNYjgb o84v9asN1JE63eHOejdm4tnz7em3nlZqUe6+d4CNF01h4cISmoDeZ9MNefVKUq8mZtRfnrOK n5hwc+w93xNwZpUzHa6JUa/yZrRz0BR668+X5XuCEUhXYNX2Q0JXsM1I58VDzUUy63nqQ49R wrgSEAZt/gsNDKlM3eWhbKoxnCqKCpDCju98pxbV53VZpIJnr2qf6iw+eaMRFGoyfEPPooiM 8WnYKiL5188QdtrECRpymHUotOQEt3peQKFKivzfuLzCej9fdEmSCWQHsGhPew9wBA4cD/60 F2Lqw+7sC76U8TiCc+e9nt7pzKlxP5arlM90DgmfABzujMC5KnCA1AJwka5bkwDVuESz1CMo 5Pn1dLYkUwRYlnclhHN0xhpQ0MAYBu4HLRd1GMLgicYojvXA6KzTPgmR7upBKHusWNUfkXxb 1UYE1pEofEhRxrXy0D4KGHen71Y3boLinOZaE7zSguMe7dhs14qQVwOUjattKe+ioa+//O9W 2pIvmntu1jfIoE6d0k41I0Nvth/s25VSyk78skBc9CNSuP8rS/dvFPpLZPlMNgMuh8eionbt tKCqDDbfbo5+repa5rvs/WFfLK3dKo/txrCbL/kpZyamX4nqeCpTFX3yPob7RDvrxkQ1SOub LA9T0dor7MBxNxJETigRbUBcdb0GrWD8UaQ4T0usQXP1+FdDu4+kM+M5nzgZSd2RoVftMAjX 1g0cJJSvcwI6b6qiT59W3SSg/1Ow1J0j7aFtYsSzWkkTeI7FVxwd9TvxX9g27/qNELBvBsC3 82Py/u1RqfioiNSZvmH8qB25IlVxe3DDsbz/XyAODeztH79hU7B4+UpVeUvx28O2q6lJSPLF zk2cECPTmntE35Onm2SJPYSzFYvPBwJNnuOhwybBwq/I5vTyhPpbJKUPksCVPoBP9m6yPGsz Wo+h1ITrxBZA5oCargEuvK3cH7A9B0C0pWfzmU4OcrSvEQ+YKblcMaOI1WppNXkYQpqIHtw5 6wBifgWhKRhAwGaDS8RTdyMad1kpDCK7cSg/e+9F6N84r5CqYFYZ8RlDzcmLy2xeqfXchnA7 JXEtXCGOcczMpLLHi7g0/abvYk2h+WojXTuj1Zn1mjKtm18n9mV2swa4+lXDqDhqpRo/Leuu raihJlY7FCgeCxMLHlEL0vuo6w9qgGyaJhYYrHm7ZXlnF2mFKHpIIPxITqdzA5TgPuF+sy4x T4jfvT3O2AAUk6NWkDUzg5BU2urwW2OtKPCWVvbQUCYqHGOD71EFDaSKuMO/7s4xMxC2Ck0c 8bjTLyg8+zrrj3Dw2CC3FCxUSwtvlbSg8EFlZGtt9v3jgNa3IIc0dLMoeaKneYTxCZjqHqLV sEyK1eHfpMIo3fobGrQohjchJ107/Tpk9jJC5FNZgtjgFUAtSZt5kH17+cYyIw4vsHOGuC6H 2QKqMFeg0liK54V2/K2V4oaub9/CNeqs7Bb/EmKwW0Yo/xuyQrH8G/dSLi+usNT1GNQd1OpJ Ddn23R2Q2QmAbKzuhKo0xHYXST/qoQtpezJeOYwfX1EgeFc9pG6DBg8eU8L0tGmez6ru6PxU bRMyuZ7TNa74BvOQFMQnh7kHDGCzlNlvi+flcA2JbihcnT0GK5H9g1UnrOx1YhCOfrQVpoM3 KFewh5yj4R5sx8qlM4oB0kKmv2GrZAKHiO1s7ovewoY5sT4mUdrejnDZEupYefNQ2LIp5m2l l3NVbhSB8cQ7frW+MOEidM0kdTHwItpu9j+99MvGc1rZ3QXALPegLcANDe00FunqdhJpoelV CJU/s9qSaDbviS+JIyGEf1ISsLDLorXmLKJkJZUZuBH+fqklj4lTKn6VKSHi60aGPZCYZeR2 iGyGP5UaCPB04CC83JI4diR0yMPAFdiL6x6Ak/FTQdbAhnMBwq3YlFW70Q3jPvTQarM864vv oS8Hn/9fNzmFurBlvkh5236qJ/7UiNesHtbGlyKj/ACDPs2Fid68bIlsZPDVZ3ZJlMX6CaUy fRPAENU07z0d5RZV1Gzv70Sp1+fpZyDDTfpUh/vIXxcPfgnBjPI0j9xdwBDpNAI0UYI8J1jD TxnW5DNCDXF5X8EVKjeeYUeRzHHlPI4TLVaeeeorMQvGMgZZ/U+gZc03SxLc4c4b5ewvjiIX NNL6sQdrmyABeqPiau2+kkKeAJWB1LIP2HMOPB8tJhy80Wcpa8DIzBlojB8Z/olePIeoMVow 9tiVdZCE5usuLGSk3bM90hD2JHYFPdNJKLpGxI3oyCjLowdHEsNAo8Fahnn1o87+WQLu7vNO NLcQu43MPbv7XIqs3n8F4v7NCC1pBLLMv8E3g8DiGYNdbtAk6D8msWlM2rNWMKdoFS3WxOmx MDLWr1t95+Uoe2H6d+4YXV6OT3si6gYwVo0U95saplZeUGpAcN9NChtrhMwdO2mvEZ3ljlEc GgpBrSLqV6uhwRf6H7vPDyC+C2P73Geb8tKn2RRYuO09vbmMyBqFg5giXzK83luXC3h+iuz7 MUnad2g5WtZKe6nOqVYwRCQBnyI8+t+RdojwCgPv1XNj2k8ee5dRD28pS//7VKTXEGN9AibE rWPo9YhL7Mz32tJ1qO2xo3I7Luyo0pYjq2vmTLWHuZGFDtcYhSLWVMdQEkGtzega88LyBBdK 6KfWB0vRBATV9C6l3yTvl83ioI0TYgUziecEBdbwksa4PFvstTcKllFwAdp23Ini9bSjKkwV 5cJhSV9NLxEORmSf6ryI3ABvGuM6/fN6W7nR2X2fQaF8rwFWSAFzMfbIyK8YMu3dPhrLmtyw Tx9VCHiJNhZw8ZGrj8sYLNGdITiJapK42zy7hZT1hVONK6p9EvUfDnZXjuyw2kJWNPL1iwoI D7YMnSozj88uoKdn4SfIf0otz1zYz1PP8f16me1DYIHzZoGlXTQbWv/eBYDKbbqSz5hGudeV HEe2GXg3tnmRuJFFDY3EJwQ+ccfpGCG+WNnutzAmyKZDSzXh7DN3F4palpJNWMlE5FDSwqYc uIef/pGMcC/WRLXnReXW5XZ5zPZk0SdS3vIpZRbdQefVHoEzA8QORZ2luK+mYZkpBDpNm3e2 BCFmNQz/XKzF2EIylNJu6f29xloR62I/ME/RrLYtQ9PunjKsAhBAz4Nqu4cTL+31eEiQ8lai S6eM/j6R8uyeTZT9ImfP64O1Ml1iQ3MBoZNnZSW5u0faFal0gYE8WqjbYZP9jMrVg8QVctNB DOhw5nf2PMK77zALzps89jfQjwcaQh0skpI3CXSpfmLHCg5aLF7yyxrPfu51oX4gMM7mbRfP VApzoLnvWTOhltVyL0cL/9ycMl4HczcJRf4VFYQnplINNiQz0HSuCM0x2VguTcILXABmy3DZ Fc6HlbhQT+4MJ0Wltoie5ZT9mXQrlQ/0JolZY/mdBaO8J4RdWZSch6lMeSUG7RkLYl0iDzej IfzvFh8JMNWybWKjvIehm4yEFXmOAxniUaHrz29LDRz1J3id9WTBZlEagkCwTiSncbXjH9TI Dl9EOti6VgntFihf9P22OVdWDfX2+JZMrA73qEB6dtndZDtDo7if22l/tV0r9PUUb9ldZBha QbyQbvIKWy5GEgA71oLj0BgFJR29j0M7QL57gX8LHXyBiIQNhs/7KpuLsQX7W2JQCndJZnDJ 0o98LMr+N0LZBnQRHG4hyHp230cQeA7SL0de3nNyVlE5pokexOwOMfZi4F1X/7tQe0GZfwFB r61DAR0BlLQg3WnejChH7yNunVzjaRl0Qtwc8lwniyLgACCClf8YaD2qnRIAJuAc1BTUI+vC J1Chx/nny6CuxBFcq1rNVo+TTIL7FqboeTLMfzytgY5BNlB6JJDcDtQVlM+MdS5TaXdDdMKq SpsmptavEytPxcKrIKXoBe8aRsFbobhtFMM/PPo9akCWcb/C2GfWE9lEcw/X3TwGOFSywCji KajEfrli51ztYC9a1dnrNzK0b65EAteus3E3SbWkvcqFK7TMepBb5uV7/OHHoFIn1AZ8lS4/ IwifZ0zS7bnpSREitggKSYBkmAf6UZJLDvczKijsu/oAc27WuwG7RB00AK9PTbNGlW9+cEQC H4AJEzJZGORz2aaBkhwCdT6MPCrT36ic/GMvk0OPqpkW7cySuhiggxeZXzCq0hOhLGea9q2E ESSE6PXkQH2udY9McmPzb5zl2z2P3QtWx+Mc0yvn3nmrrR4MncCIOgp265/D3DXFKQr7srqL J2YQK1hyntRNFjbodwESsgvH8m0999wYXQMs9Jd6R2SFwT3vedF4eEOdsVJQ6fs30IDWabr0 9uLmDcSXv7Y79lKdn9KQEmCEf2g6fE5YOC1Yo3M/bvmHZfOXbhSPCP8zzm46a6uKdu35aAhd DPYHJJjxXEg1NkOODNwasp2mdjEjbkrw2vpMvYz7pDvmIdSgXNUKdlskfj0ya3n6ltWcbTn1 VRqiKsfW3QGTJq7yQp+2yc3le2Q8CyIgmZJe4xT/fAihemggXmmgffhZB/F+E5ucvF2ntZiS LlTGKro1QJPR9hULaR70D9JVU1zKuUmnvAHuV7+7ERe8EUepJ0/zAwhrlP4L6YtxK/6M0X67 2SxtEQ/nH92JGergsCWpbldIwVClyc5UOC6peVvSVnAGeaS5n9NiOhBfG3wPzxhW5hdTCyI3 kxBwzv8e/NhtwpNs+4nue3sSS9yfiXy9LOmCFlm+M/CC2mMGSsPgi9YLpAAu/mKWndir8ivb PAkzuQwS/lXKv2g/AAnPKWIQ+rAUnY6n8YD42mr/VpIwHmJ7pnY/fIsj0uoHWLCNH0WTef0X EMVvy3jFiEEZ09Oat/FwLcmjZ8g8JvXq17Lv5RZR6x4JKrp1KWJlHKVTYOnEgA6CiPPZtOXs g/5EHVFxWH7q4stOGNl2G7HD2HbWLZN1jIPFoFCZxuCzm9AILE3rCiSJkzYjveZf0n+okwVq mDZ6UG7gi0Gbx1VmkwHr0KDITHiQ2h6jFgSL7/4uq9CtugVkMuzMXO7XUCE20S4nJb4ngo34 K9fLkY7d55xVIguKiUCagSf0TNeQuDVGYXq+hCpOBephQFpcIJT+2dKceO+clj2wRJdRm6dL bVS9njgX6ELx3ya7zN/9KTMfwJOe9dLml4WG/ZYQk8AWEOVEuBkZIHag1qU6ytw7oYsqNd5Z RXWBrQr/YJiCyMdLb8xaNlNY8CWoIi0t1xBZ9hqekWZJhsiCCUNBHTOb+69vQ9KwLZzK0Uey xMD1PNkyKen/25XRPbICKqA6/gFXs2Tah1/LZOVDmhRGlcSCRB++J+2scSWqek+pcjlXz39B aoUyMGglZokaLOZbh5Yt1Sr0IsfuUo8pEYrWdfBjkLE4dj1OI0eshqSU4iM4FbIzqw72q4hX EOW06jjXkakybiJwujeLGTmnDFUBlJu3fAoI+TaAYGpfGAH+MgUEQllx0uygbKmgk2TcUDeg +IOlWAcsQfad4m+WFycXzgKYNC1ZY1G2M3VNZoqFDkE5EO5geOEe3oMF/9UCyMpzd2Fr97u6 vP7htf/r7dBwYuUzrqVMH/dbbhJZSUGBSZlJ+b3jaCU94DA288KlqyzExGLKiYFwX/phY4lo Sw18zXimrJetzgvXGPjKdSLQmYKTP/DkpZ6Phdpl5hu7vWn/cMHLpnx4aUzlIVKeVAc0jtt0 wiFexJSLcFRZ7kBVCfAyxdflBNoaSlZRh4ZfveAKo4XmguHT98+6GxwxLtVLmvy+aYUL41/6 W/AjEi4tq+YGXbAGi+3HTlmF6EhJez9DXgXcnEWw43yzQ4bm4N2QcAeN2GkgIurSJI/8RO8R bXQpyVPgZiFBYxn+dZKaL3mvr8LhRECYEGxL2Mh/QuzI8WV3Hryq1d3WvLE0Uj9TWWcT7XrX kl8XSTdF0pG1Ng+44qGNGa8T/L+FK4ahp67DVmxd8Sxit+ZSYzMdgbgmsce3xIoKRE4EBEP7 rHXL5vRk0SrSbXQB7WzdD/+qDOsqTx2wxsmFcAhz1aViNIYUYYWAh314WmPX1LneM9rgCalb y8yDTS6cruu8/1QXI+6vz/ZcIagHPT/Q6u49Gu4aIdjJpvQW3Gystu7IfCppmeJhKuy57YGw Uk0Ya1oaw+xhZ+8G3YSkA/79F6Mzrqpv1kq9xlMC5ooPxhbBGnMyTYHHjUIVYSBEnL2iLxKE 4zmEMXvEWw1BlIGUbC33bJxx2cmfB325RN1k79OMA8gQE9b+5udo2r6qMwFFcCk//fz5byvq u3jrlbMCHTyVAUsAXs1zcA746mSBCYgDE4qSymG4svEd4L0hiVSi2/h8gU1i/BpA7yBgybJ/ Wxyxejs0LlUwihP8SFi+jfEBUvc+p1qhd06Sdf0FFylV+ENYH+5nwOSE9WIMSJ5fKGMOiPwk TbQaUC92lTaTl+5asTtbWluyhFFlNOnC/TG2AZkOGHTSsKdIamIXEkQlxjaFEV1NqyLfrB8/ u8hiTGGTwp50LZMG4RpKVs8/ddqfFRLyaL777n5GeZABExEjLJb7FsQL76Q9vgzvvhXpHQh9 3m1aMYD8zgUxBrg+FtYhDy4U604OBrmcbCl+TzcJQEVs7uaAgKhA9HYpbxA1Nlbrdri7dgU6 S0e5Rfjo0L5hd2HrKQBPUaJb0V0q03izsmuYKdmGold8DsAcYXaqCLqEZ6qNlTGVei52Q6kt JTWoiKj40+2S19ekXmol0dJ75Sdp8IbgdyZ37Kb2+aaID54eGtMAbUD5r/ixJwL+W7/V+rjY OTjVflrhbAMHFBb4NkWFbZsBxrKk8OReioA9VY208Fs/61p361QEJgr04O6gNcC+0IMakipU Dt0Z8zkKJDyXx52elp/+rz6W02FJqzizwwRC/N7KNBe6aFHqTYbmeu/nOb/FPuCCdN+5cUe4 FhMfM7mmgAvZq0O/CoSwQHBG3SrJ4HsbvXVR84x0cn6e7GHH0EGZEiORMGKb3I9G7jXpUQCV fTAIZzGxzV8fbjalR4F45yDril5FGwBry8oz+g2ss/obykT4/gsthIeTuOzr32psh6VKjxBU DRulDwZrG7VIv1J8Cclm6WUOhlLZEM/rs2lJbGI/Ewgu7xEJZQn1k9Tn3HA5vZ5/DzKzqznC 5fH6tBxWbEDDAvqJCo5Y6Dmf+IO1w6wBZa3ADsWPLmO/xmWvC986DRiDWPx0FxUIdJU8o5c4 FrDxeh/QEOR1DOWY4bSYEYhL8zPt0zdt358F0F+ipoYdVeMeXle0PdNozlbC8bzsHdvh7zuU u/b25oSWSFYZmYiwJjt2XsBGDU3YcFSBeaxnLDwV7UMJjE99z2WF53ohxcDBsp4aQWJBmv+H SPWwg+LHgifswA7uuGIMWbmif3243CswgQauhG9tWhKb385kmWG30BeFg68bVojvM6O8KT12 ITaNQtNH1fACFPh25494IUo+2nI0aMII8/G1lGAt3/D8EcaxJDuL7t1cugCzUQPX8MFH51uI etJ0w7xhO+brF0n3hszsa3Ug9MqvOw4iHjnQ3dMhnKBy5HmK4iceRsRKt741WCIwPdRnCKbT /f6ltkwknNiBXWrUkBMZCJnvZ0JB+jBMdQmOSppIN8bo5t8KRYANhEOpoBZaKcWf8P494gTf NOqxfOfJ6MqLwxFnNCAvBodyZF2YPqjD6q4B0d3SDbwwv2ZXCFjh9zW8n78DMYs1D6V6f+CW J2PsWISPeTSdXg9llJaW999Xws6HQzneIjN2zt8Q1SGheeECcmR3WPabo5efkuiB7MJvBf6E dT9qSTb+zpyy3zMnAwCcB24jFVUplFL16etthQkP+sowdjHuRqvG2vqETWxZ5Ku4y7DkpSf7 0HUOE1YQFr60Loo7chKHUZ9d7RqIm8w0kvkuJ3C+v5dcfi1Mcknb9D1KWLlEvYTFEHl6PYwv +q7r1Z3frFbHu1l/3rd2wQqRJDdrPro7JXTWsQTnb9ceIS1HN+/BgRywtWAbjj+LLNHzSXIb dEvUTkTWBrmbrckGzOsitwPPTf4rRER0ikabd/balIKNOIU6/B7lz3w1nVV+uc6Uo2cIsRPM fTOCxbcLcOaNP30d8JcfGW401hMJ7UUgg22/IuQ5leOvZikjlemw+HJsT2GOvPn3d63hkPrp 2iB0LrEog4Wt0DEtWDd3C3ZpSiRVzWRyOHg709VdQ/ywYAS3r5y20+XVMg/6AWz5DyCuvODw jF/6paXitYnSF+CnfNUjlS1rY0T/7lfMpHTQtVFBl7HgrhGNXK0xNXI5Q5dpaJ/8OBmlv3qg R1lgXbwURX1ASY3qlgKmio77WdENY7sbg8UBGrdEuA4c6Pr2pIanwOkBKfys4dZP1aLy6zc4 zAlZ5JKtzZvmmoWYBVkyjPCx1IUu4wNOlwF4XsirXVG8p/1KgJTBUu8aBTlN/sMjLL9J7Kfk fqW+0ODwSaQrYgsqhZGXshcuVMMpfI2jh2JnLhSr/0v1UPmOyRyM0Ze+UVdMrTVSIxQXpYCX BwULxTHoHvxpNKH6NOLliNW4U4Y5HtTBDafP7YMkWruFc+M7tbgMe07Up85ec11fBTPMQC5y pyqWH2aArw50sYAYFLlkqzaIWgU76tGXyh/REOoF1nEHLSqauweIzTXh6rh+WVEcNsjW+xBf rtKp2pUw4QIiu7Y2xuyJbSc/jo7/dYz0WeKWx0rixqP+Vn3WsynRit1LESxhm1/Md1Y9OYGx YvswF+zXYJ/NOyPypvEFQ8dGY6s5ZMjcyjqefBoGbmD2bsTVHLFSv7E8pOwR6UaBUBitRUAC 0UxF2PHb1XhWVqGnhWHMXm30NL+06Sbx6+MIJu4AM/K/ZNBLaPLtq/Pc//akEK1CVNnebSbM FRhNEgKAvDXzFTn9ayR92svH7xPApqyWiqKRsdgh6+leikZWYOyYT9yjtl8aSrc0yduXrUkR 5f2WBrZ5mkFmbeGiE/jd+dShu9o56/k4+QEGGRaafvD/Ky3nu0K5B80gViN0iTtlCcqblqe9 PWv8ncDHNBQTLMGL1F7B4bhj3uq5EzUKcisCbc8kxBmeJQRI4kRvVA9YjlfrT8AbrKo9IFWS GtzfIT4r83uXdkZkNBhrPJASW5VEtZc1sTIb2db3XE7L96SIGYcWaGA43dOSXcx0WzgbJfld KS9id8QZK6vBR08Ir4dstmShX9AA3g+tt207YcDG8qjNfucedSquwd/QdILfHG7Wwl4Dtpa8 ZS9pW8A496/KiC0DWp7xrDebp3wc4P7kocdCgMIyJuxOFuahjdX247CDbusGl0jsHcTup8s1 zENwGjhoNRLvdW25KnJieZsFfbVJ28va8KNZhcy88DAgDcY96nE0abkzmvRr/RlYyeEB+nw/ vZHEUwKrNUg734aEmrHgxjJfvWsEwM0JKm/t6mzdZAbvFeALCHNJDlu+pXp8CoIevdjGD3n/ exVt4054TxGZp0IX18qvjmgQsjWljjzsV7Fz9vtafV0tu2VDtij1ruE2sm8q55mdhv2pC7xD yk2TS4N2zC5F3BCna6zEG/xdfDubNEJEMfGb2iT7zRXtdKXpb5KKsmosK+8ffX3i19UxPKQc sDZoGeYcadayocerqKP/tvxEgG7MSULvRaXHpF0zpWA9srktTNi4CrG8SKdMJXs/d4S8JI4b 8ZkPvIGLj47mqodPWJRCxapjPLRg0rEuOyYmayGsOlGZ9QjmPWv7+XlscQJr2NxlFT4lYH10 1URPs8aSVJEdu5Qi7pZZX+KHiClWU2g10PmBJS9rUAcxepjt5V8WFjq2z8p26EhSEVYUF+ma lx6TbNaYzK6tZ3hsvHX4n+pKdHfUIhfPB9UDlPcAmo921a3OPVz+Ee2pyhTwPKE7PCM5xz87 OYaSHq+4jpFXHYSOQLSwTrGGvl1AnYv6XdRGavTFQsQOTfvg0ILrFRt7uO4Ns9e5yuRQOfC5 BT1Euae1HZADWLQXOEID8APmpA9uCJCD0SirwuC45yXmOeUI/RSxGWwUzTgo/vmbtZbkujNR jFbGZnBgTazt2bLTIgmtfDgb63lDzQIZrm1g7q/lNORwfexEeM5ueei21tRkYYotLwGtCqHy 5Tzw0ta1Mjb5X48TEmaKNQlgu5Q4VkkGrbzzWPOSNfazmeWGL4qiuY9hLMUkHvoHN6mt1Ixa 8R6+FV3k3se9GKBLwISJdL7IDwvb+WCPLijlpm0kxH/sbIun391gDYSuvmogMe7c99FYOtCF cJQX5r5EN6zQdH2QLraRYnM1vn+eRql43sKdTa6jWbxAV68uu76syTJenG+i+Hzi4Bywhwpq 0xmMrdH3ghk/pbubWDotc/5c+SPxTEM7LZQbptjsvsIk05cwusbg0aLshaGdRrpVfhbPJXYx oUQz3oddaMCNFglx11qFNjsosWoctrOFuBiwb59db7JHhztwPGwDYFjnPlryqOKpPPgFG/xz rPpfd7fKcT26ajgOGSAcnrHzswFFsAP/LpkXDpnvBf/epoFp2Khac3vVASDsu+1F/HbNxY2f 7J3+Gxx88QvpuPWQBfKeoZKHN0SQktEnbkR+wZYAhjsNMcgJ7M+Caoc/4UWofGgCbfKMvHj8 8dTVfRl9EGpm/Q95SqFbY1vstnowBe/NETZT8GB/5IH3WFvKf/C8wRBYDkPkTAuSyNJ4q4pi RegXZfsu8QrEP5HLWmWNGm3PxRTzB+rqvGhouKWAxUVkLZcnNdkszB3U9Vhc8kxz83FXAJS0 XP+pFx8ci53tTcmeZSsTUG/xj3MxH6cFdQfW+Sk5Bnnp2W4uckNz9lkbYwweLY5Sah9D6q4i 8KF9WaVBKFwPNCIWiBa9uAzwdjTrCcgyiii1Dn8QTx9QrAZ9dbGucyyjN3jY0/3rcJkv+P1f Tmul5X5bhrVHoekjBLHBJCwcJVi3BKEFbvVfNTtZA8At3WOmgx4ixVFoE3RMURvYOejnytSv ciWEDQikmnEGpo50HvbMvlQJbXgkT7bCGfbSUiyiFV44XMGEQWmdobxGH3ykXfp8etLPZ69k mh8ogyyS8dFta2R/FUVBIr9jlhVQoj/ldK4SHVzzBckHHyxkOZ/WoCkYt+3Hm+URpRTggV0S Vuz5yxhxifRJHJ80eRkUtnr0XCQ8ZGF6GQr860U4q7N5eg8rc9r3M6kGQZgry+ZjcnGlji7J 3dwmXfllWVtvfFKwMdo/EjV3UGMI4Y4Txqa02TJ350FK4QPKbRzgO1Kfsyc2nGjktYtnbG/x +bqB8e8owzqdBHQ2IsBBwgPc4vR+Pntgbt2sWYu5MgrqjmEWfFiDe3WQoRYpbWJGZzeFuiuS cuFsCSm9Q2OzlnhiOzaTnBkiy8S9IPqORCE1n/4/VrOdqEym+IRc73TutNhEF/+mmhUjJWII LItlSU7d+j3PT021VgFRVA1FRAoWWJIR8snCSfyL8LOI2UuBxHZYfdXo6dM+T9+fKrOIEO19 AO+v0wGn9guGIVm9qFv7x0VX7p+scZZhZaUO6OVonau6jbVGTjRoCxmxYglwHtY0tRmiP0BI zwgiYbrPJP8YIfEuNGXUiV+qZILMr+YwzhBEswlxjhCfi58GewSro8HAH52EOG0VH5PAvOdk hRlqdwLg+N+1T0W/Mw5bxlDw5yl7ZyG6V3L/4gJsVsodkYXu0ZUgvdWBvv1/rX0Jn5i4pRob n2pJrWmcnjcmDQIa4kWKy43SHaehneeSuJZPtgQFoniAV4mJZ8m9BTL4hOeK/iCdMwcb+7vO 0KEHBzSHn2MLxESRVEX7vzu42KK/0nUJeU7/7y84dc5RHFDmjwX+0PKjVgtIhAuv6eav6o19 1/XcJ05iwBtjlGHSQYA17YaUrrxQKxSC/+wJUlmueJM15O1e7YPpymw+sH3UTVY4PY3wy9no DCeuNlW5H8vCaPr0QDghNO0tBQeWed+1RJKuZD2E6ef89zrHCPzwPLSHpBiY+5ZwxNNe+peG aiaAP67SoZ+iZzUt3E62IvAugLBbe5xMUj6bmnfG2d5acoLrU7ta/RvygShG6Xga/kTyFo0V clo0vcP8+3e5YB9Z5ojVKklfuKAPGv9eGZBvvvyiRVlm0RhqppTLG2sE4/kzm0vybZCFSXM/ RWoWWkO5+/s7M4zrWBkZTtbOeErhKjVH5yksC477/JOo/UQ2iXjCb9tDNs0DoxpRo6ZaI0JJ Eqs5A27VG9DXeWoA4XJzfZqO2SDnBqPNhjzFJEHAaDpQkAzbxdzbx6lsALS8kjk5lImOI0pz q0KuOC1+Td7r8PjT+mZSEHsoZ6o3zpWmsaABpCVeFC95LCMsvZ9Pa4t0/k4vjimRWloC+GqC xCisAhsJEYiCzsSm0EUcFF22yp59UuTRjqJwJNFoW39I5nXLHAwtlPwhvIFI6Rn9f+tIR8v1 lV1N9i3xf2dneBo3uEWieUB2alVhHr4qrK+rsJf2+7zAAX0A16V/UZ3liU3kOx0iECcH8MFV wLyvdfL2eyupjko2Gye2LOQ0DXupuR82lIS15N391BDVt9lZr+AUMD4oe6ihBHuZm/cTKBL/ gWLpaI5ffZkhX5eIGZJJ5aiGJlMOssiWjFbHgq+rYmFFwHAWSQBVlzRZuQpJrEV0gZgLl2FP HMoV1xuNlm99yrx+arHAFJ+8GDu3zwD8wOSjhNnRa3T9A9Gi/CFfn6AMVvA+ny4y5k9wI0g2 uIhRpVoon6zGMlQc/2FgnLDQBvmPAoL1/APhIL1/sHUa912hqTFbIZ0cZbf73PBYdHHsIzLa pT+s7sOz2IjD4TkR6okkPMk2V47WaaMQLhNNIAKfT9fq7e3jdwE87KRpdbk/TnjusvbRgZfS tyG4ni6R3e5PmcUb46AV0hnhb4ZbDW3fZNz6TG4M+1ppxQGjwkau8bjgqvsTaGx9imYFrn9I adgun+XxHJhAyfUWqAlcLMoTul5GO0Y2l2Ur/R/P5M7IJrIgyfQ9Sxtu3RA2VeALU3wBuC3E rWRUIuIUUwpob3mlR04THjKGKU5c7GR/Ge1JNOQpsvNJfDQiE1O8FO0CCBBa+Hz2WhBgC7uN dw8PMUGrSGlOl4CiN9sfJDDY56lpqaj9eHBQ2eXQkm5tt7GaM6Ue8lLcXo3/nDEf1rZ9gHxS InqWjPAuei2IDfDRcjrd8MzmowNB6fZHg1bEnT6s5kOBJ1LFdGp9pN4NYHJFxhWbejRPr/VN R0lXhSufZjwaDkd9tZIZxEQhhj3VAQIB9XyiFD6p0ugSwxWx5adgGFF0yqSvJcZzMJ4Rnbsi L55vqlz5wvBrnnfzwq0S00FV0IVYsyuF+2/XK9eIFqchq+sgrUJ2WLvsjUDjSt3XsT7XZKrs WPBii0OlJ81v6rMtjIxY0+UOyyI8+8I210MlfUedSlXfWQScd9P0pbLJQQ06lIpZ5gW9aZy2 wYpvXeiD9FKJG8tewpOIFj8MVKY84+aRvenC/jsiIUWO0vRqOr4l8LxDQwKMvORjAmsANFsC FXJzHHjiSxt23EkyRRoVDSd2xA9KpOHH5eLkm0LCCw+Mrv6xVR8DbnZPjyaYwLZyK5DxkOje nIIDvG7i3Le6eDGKnJ8Kis68KKxq/L0SR0mVd+B90k76H4YRWU8F+y2W+5kRKQQyJ0IcVoyz JxSc1TzvD+fFZha2xbf9rxi3/5VNDq/Lt07UJ/Oa0Ag9WUGg3D6DSkI31vY/Avt/QKjwEWj1 /+u96FwrKfezOvYZe+j2f2D587xxAL1AXHLdVUGjviAjjgib4agyFpiD7Vj8UuxNG16nUSbi l9HDkPYJ33Hjx+5dy6zUtz81/6NFNFK56RN0DajlfuVQ8b7WskejhSpKbFAN9P+u/UGm269w 7H9wEbTkmefLgM/mxb5cygJR5qfyruHPwjeHmBIaplJJZCuN/EWliOVxqmNp/Fn4Djhrb0aa zqjB3kEWXIqsWidcERCD+JKY60gKbtKyA8q/YF0DSfOq3JMZE7L3t5QRXxR/tzV3D0b435Un eKdMqOl2A/b7DIQLoNWCGhEWaWynAbEA1ZCYX4xGctTeZXfAThEG0Q+wrlK0qbbSO1b+qv3G 08pXKMie4g1KeEUcoLcg278t4BUeQfQQ3wFmqy8u1M67VDXDk1rsteXpVq5ukTpk5l7Qxe25 O4MtCEYRyKZRS63w1VexqWEM2qlSIocAGZgjGId75SQafnsir9oC7Z4frBPPpBw1alXf2+GR Egi0D1XsGMPaHYZfoJjXdY3xBHJGqEMA1T7RUj+iVK4urgJ76cSUfv2oci6cF0jE271LpdX+ kZxwXHs00gaCh3O8pIyHCHfhehoLYsT7uHvW0bcLV0satmmQOHMWk7IqzNJ39CPaNuYwjdPd Cgo35VklXcNVk83yPTXzIhVFtFS4r4g51vjS50aayqz8Gs2zusE+C2osjUOMkRr+eSY+Jd37 Sdvut+Avct/LzG65OuJW1iGBFPbeAFPyEW4b6GplE4Bb8sp/mMlFhThM21pCPzO1Uvdr+VSL 9KSjypO46YDeZLplQUBr6YkBdG+VTpdsuxGiNstFflBbhyGnDb9IXeFHfzGqDJoEloplZB2k 9DlsDGdnNErDzn4TplRQ4UHly5yKPD8Qj2LYnQSCfudM5egfzWDCFdidG/oCHRxLuskw8Vh9 OhoxhVXl4+ZfKmTDJIR1uKDnI6tJIS60111hCsz6ncCGfOeSANhPS/0C9/iHcB0eXbyo20aX sOROexsVVow1KOkUR1e4yeVH24Tl1B8dVTLjTxbLI0KIK+vFprpV5wmLEiE6ZSG0tl73kHDR dmung33J1Kp5EL0RIR6fhp12SakPxe73jmII+xAlB7yuIz3BouHqyseOR0kO8gz2MQU4zDCo OtPgDM8gRScdq7Gn869/1JLcs2NAh4B74IrRCjRWGmprq+DjvV6zndio2ITlp0j0vHZoltnE /CPCtuX9J98/rT6LwA3+VXMbqLdYom1GMqM0WsFSvxu9BlzggmqVJ+49NjyvT7j37SdHELZS CuJtmT1D46z0Q08eguchXLb+Rn50WNHDbq9VQ6vYntyjL3VzlEh+SXsxujoe8NvRzq1OviLH QTv1jN3Bq2JTTQdW6NPrV+8mcN9oYNz/pyQRlmwGO2Af6duwQctn6/EWq3BO6ic54v2Yi4sE Vr+a4CE6VEiXWxnx+WXqO7VYNHNtLBWCtYvssaRgh/9TBqzHNh21uP1nGYnb9qAaNZRv5Tt7 FB0j2dsjczvnrEO5h/s0ql96cPkHKx4JAyE218I1aK0fPr5k+iqT+upaCawmnUKlhbQOiMga pSRhHiV/lTAKwrMl1B8pxb+vvvrvtDw+4m3bhyg0jrCpnbr4Qpv443AEYlY9h8mKZu168UUQ 5vUasQLBYYKlpCoG29G1KD87gTbL97p+ZvzzvTV7c3ogiRRmJvlO4eryyOTpVHcXgYYwczk4 0KkjIaL1UM4JGe1qVGURMj6WpnrTRLxzlA1x3TJEQkhZBp3zJ4b1DLsvC0aCvMBhirXcBDPK 0CQs7NREDCLWOntOd116c8fImEOgVIye4mJvNUf4edq37QemGWVgXkpiEytC3gNgwXPBkK0D BY9ikaBCKGYsLZMNKQZMgCudc4xrXbg6ktjoWy5xctE0Ob1VB7D44tVH9Hzyoa8haGBHPCTB xeuQzYoXx8G+xl2rAni85IIeR1Gw3xqzhJB1x+6P5/IG18ZaT11NCorGriY48E23hqX6BzhM 5J85n2FPlVI0RGl/2m7sNOzqkACENtRlkGXuXTncoqC0al54TlqMcZOkArHFiGNCcr6+8yh4 x6vALoXy6XYjrKLalzLgsDBvlwy2avubar4I84DxkdUX7wLoVqpHNmyttU9XBh2K5ed677TK F2z6JAI9ASUwy6cmFAvHtTUmSGNJ56m/iHn+uv+Ql2ZXbxeiECJlaAlu72DEOC1RfFX74Zkf OBW/3RDNgYYrnpvcMt2kqawY4gWJ9JT7VvXtVxD2LLcKAxHbsHww/6KxSPq0QC7liYkUnewl Jn31o8hmKwqFL5j7cLcMzD+ij7E/CmGrg9aHJM3QPvBwR8S0iDko85KqHW/CHB6OWhD0O54R NybLwcEp3aXddE6GBBUP52vb/64ayGM0VjPKdx5mPvhw9rcW5ImOZCLQ/vo2gyDRYqk3utvY 2qdc/1SACTb4tvA4VHYXTNkpUoZQBlJLeHy9IxCy6IA9FGiQYiz7jxYH90ojsvfWbc4TsD9L sbhOR2ScVnl9GhHaFQ20UXI8DJWv9tNBw/YjRlCqYb/Pl4qPfK7Pm4vysIvsAVY4rE6aX3Fa UWv64wOtx7TkCtpYiERA1Ul+qVDFiyhH5JgIfuawQbytRDtL1FHJf1fCFCdPF5AbErds/JG6 BCGhS7a+Xa539YBgtFEkkWeI/pPAAKJI4i1gTHfOWaDTv2u1RyYkV0dxdHuEWLekeKFbLzvy W6a1l+NY7/H1wPDC/ybJOM1OmBSnwSJLLBFz2mH7p6BIXpfjMaKNig8+N2dc4EgZom1kGGIg u/jERzQHel0KhIFcVpcJ9uqOTi/DFHbpEJ+UR3lHeP/FJQi3/Y5h8QcrSzMulh6qBeGWYr6/ d57T9EmNWs8KIMltlNt1Ye2JmJS0uNGPqchZ5HhtzM0eIAulw0s1fkykQQ6RCBNWvSZuWj6m 3cpKd0BjQZNi9KErPgWkPpiPjL1zWKQlSlLbfglNY7tnR7mz+m5dYjFDsybEDSzDP+3WUU9f /Ff8btYf2l4CWjFCVvJmZ9xqmyDz8rHQ0E8aoVmPBVpmxbni90qhNu9RY0Eaa8WicYr9z+6s 5iwFeRr6aLIpPdju3AztzxIH+dZP40Lsy3kZr/+uwx4aY8MHYd4lWAPqeaSROCX9dl95Wsxk 1HjaT/B1WExoM/xmuRJfXLNECuT57/2i0xxkivoWDzJw3YVKQgxUI/HC0ipW5tz/A+stFjPH zJ9Tb3ezZLuz7TeC1iLpsbfJoq7s+YunVmeQw5OJzAx8KAjzp37wIVnhLdx2iIdgi+LQQhxk io3fc75iZjBvuWhJMvZ5e52V7aoGG8k9oXA3A2s2RmgLaHTG6Gc2i/BAXJgNVmNhtdBfY8Ar cSXarQG90DgMpNkGQhoveDFi72X4PVsjhTBc/0+O6rwj3gLdEKaKQ+T6EyNF3gduE0GhQwrL mlvrq9bAmrtaCDdyX+Z2kxXz/EKnSCCq3DOVJdcDCWXaLRh2GJZIwAO8s3rkrwQRTxUBW12V Kh06dA566U+46BS+qp1NF4ZU33uNaKi4JtK7VUONHSJlFmdm5ZCcY/QTku5Mq/Bryqhinyq9 bbAVyPj9GZ5MGABq0tRj7OCrqYkqsefL7O+Ip7MleSIsbtzy5U6HD06cRSHfYIyQGN74chuS NmFigmKRIfbtgXxPPfKWNxJNZITPPnc+cScJn7GhrIPtYoEyVAzOyLvlBu1w2LNVLhtWsziw f5XTKADzOVHIr7YBqEXoswTII1kOkJ2SozpCPGq+zlmd+L6ktxNCssgJnjCeMN+D0RKnGHm7 wZqPLCLuQI98JMCUeT2FkL7vlObsBsrN9hrZ1/BKsr9i6jnYVNfSlUZp9x+pFCe0dT4YDqlB s4XuwYsim+/tGZNYGvQcEEX2O3fOj9+wWIFVQA42CIkFt64VHfpGWbktQ3zrKcxUBV3Gdjx/ FLI0DCIabH5IDYEfKjmtRhoyXqQzz2o/YTmVhHFcMU7kAOESNqx41kaPPsH/AAWdcBvICuVd Q9q9bvFOrpLtBOTrwdCL3G0arkieLIv01EO6Dt9TPU31JsX67beBdiwcROBz8h3vayVj5bRd Lu+65gFPzfGe5bwRw46KvpyM/NlmKFlfHkdbXToieaAW9H++hfwVWYnbTlVDmmj1N5vgm40X rHc5oiTUfJl72386HiqIEILOARtnIHdXo8OpCeqRPYSUicGGGhXSNrppZMXzwyRDFCbzDhee Okuj5dTMLGytUUkf9HJR64wkVhZbZzFM1SNxP2bKmx40w6/lYWhsOIN+xChDjNUFZdcE0zAo nmdjafjPqo81z/qPxz2TXNZA2Am0gR6ymxIQQfU1Dk7fBwc4tTtAKSPdAVjcMQGkSDICV/ua c4cIq+aIbO2z50CMYCFxNz3bFMqiaQt/b8bucjDPrgJqNEDD9vSuVIPRIf3o1YG4AlOxu+mv Po/kPXVpVgtVI9tjZK1Ww+h+JRa+bBHN4yFcfntPKWK2WPCzo1BO1JZZJUy77TB6myPt5Db1 DeynmTp4299KqXm5R8OHuaYcXHGSblQM4q2AFlrlXFpeck4+2sOHN84mKVq1i24B72bEcqgW dYVNp1SpQ0R/Aeonr5+IfC1vBYHDLMzCtAnup0+ck91D9i/x2wVEnsc6yJqyQ/vLtQS7pEsZ Ji5BaStETW2BatURL9lEEr2Dr3ekLokqvOaYrJABDoYondZ/ureOuqhYGPqxiS11LrMf79Bs qKo8W4Y/P+xjKxvHt2QpRqbgw0wWJN/TN9hDP3uMqqq3rc76Dp2jLz74RP5I4ht9Dreen+Tt BqwXr/tO1z4XBExjR1KYcRrjY86FDHDY6/X7G7gV6NuZTlgUgHFjz9+cAMWF/XlWznQhMvPl Qf+ehEs9Y7fD8FDNgTBT1pRJ3cmEnakbL99uafRAhddIoEYHsUUQrrD00BJGKVOFTW7y1Lyz bjs+XjUsZMY6ht9UFMQ2EjkXuXqAaxVwDwrtm13UghDJi/hYDr3VKAUyfwj3kzIAsIlE1ClK Q+yVi8zTWpWzY9r8/65m20K5E2cMrX0apfa+xr8RdtUC1BsiPl7HS9A5A7BUyp8iR+kPfG3A IySF5vHpUbt2QGawtvAkkTrs5kdz6pAD5R1/84TsLPUTR7z+9KyDiO7K/XGa9Lxzx/p2cD2l Osq18CGCixn93kM7F4t3i22cd4QMpAnKLZysep1CUD5H734ieuLsJmN7c543fpVGbKe/V0+8 3+/J5p6hbZL//63+zf6L2/shVgN1J4O88yk+rYg3gEzM0fALP0Gue9UgnJUM1ahfHu+87u37 ecdWiOpv22+O2uFT+8R2wOxwseP//UcyvizmwWolFMf16GuKkBIUgUI9ckWLQ0/EelzovrYS PPWeCF5yy0u9OEt/CvLvnBadV2DJoI/KNZv7avSe3WwLS/F5jPbdNpfKyGrce7/LJtOwcEbK Jr+NoXEKoiHTViSRl59zK+CIg6kMsHdOZsEdNshIiWVzqFco9Y0HHso5SZTb6vf3JuJWT+/b fqs6ZvR4ri1h5DseofjrGqObCR08kNI7tzx7ZgbgIAjJh3RDu9sHkCPy5mYtAkRwus5585rn XZ10ABi4z2XnHR6OwE/5t17MrQMJ8LAc1/BLEMl7NBssxBBemPn5W0UY0xIent2T/Kd6I2Rm dIGHnz6RxeYyq0/TTEJy7fzjy3PWLyL+dvWCDvUIbCx2ADE2CFpoVrGYEq2u+3FHg/Hd+mkT d87VEEhOF/CTt0o0x9bZgRmX+fBlBxctyO3ohCPh8BplNA0x2bmF5f5aiXYNzcIX0qLgCrWc bfnQmGvQZ2ky99T8C7fG8tmBfX6omx9XIuoImDaGBhUgQ0EP/A7MbLwvKE8totYNeY3e7GFc jP1edJyAap8fx/Fpqb6luLYGLBqI54AFp8VX7c4m7zB/j7IkMHG6m8Z+jTHoEvqCuPolfVc/ R0Ak+p+eF8pUEHOeABH9tzz0IseudSyE6Ek8VZXaKZgvLHkt9+6vwCxEgNzxnUQZbiSDFukQ Sm4zovbNp5Z0Qt+CQFLiptMeYPxjuXpY6TOqWQItykMrkw82v+5m0IaI5AkearAoUpXRYRlu opkxROaMqa4ZpJZeIi7rX++8waLe1O0+8Gudc1WX+i9FDUzzwN6yGJgLmd+j6HpouW6Uc5YL s57flyO9OoXJPSeDDy0VghowGnCFwHbUNFrmibbRkMGLBsqAaXJCK3FYDQ9EmGM5T3tCWdQt DsLTlh/njMZYs52tDNtFXkFHzshp68SweHT5O2eLsOoyVb9L3WHkfYXLfDCjvsSsKV5js8OK eUz5Xg6IZKyTyRf6zb6df6/vlg3JKnEZhY8zr+DkIvC8hnFJsTOpZ9PjiNdEl2pFuCHuzKMW yR8pYA1cF3bR36+2RnJVzO+2mnb5WBUErGtrAHiL5E8tTNLMjpuTThzDPws98uiLh1kAMkTl 2DD7Cxi4cfGB4wp6oruE38ZpVL+FtvU1D9LLcwF/dO3TvupVx5jFbrVjIlAlaimbrRa5yP8V a0TfJ0uZ4VdGPsb+Dlqn/hHlP44ZrmWJuPJI65BIXp468LVV/r8PCMFSOvlV3xfQjwsorN1p F1SRV6GfQbn2rqizkWwHX3a/2h5tnT7JG7TXVCTDJrym0ASOLMPRB5+zmCL1gIKE7s/Q9RqN M5F1rPm99OeosxpDy7OWJfnvFM+JPiQKTGyt6PHqMrTrwdeumGxNX3dp4jFQJTZaAYgaKAIB tzzk9BmzJzZnmAnt8YE3Bkpt1YIFzUqt31E+YmjZVknSnr8ZXy+BilfZHD9eUShESo3AWgNI X4TIl1H7upiWY2PfSqzsHFkMpJMn8Tc0Qtq1d4rBta9u24/kxs80riGXlPR0t9G1C4CaNFw/ Qz1fAhkqJcpKO6w0MaSOG8ODQWg8eF1J2yj5FIfXjkyIzRwA+QDM/rbYGNq+zaTOPEKM83Cv i8iO5/P9439MERKjkONPtI4mVSjjakL39b6NYOoK9ZdX/O3cD0rvxwGIy+oJiTC4iFOengr+ 8HtTvNEH0hxHw/BFV2EVKLcf1iqY0OSNF9t1VhLyLG7iG23f4LgVxYvv4RyzpST+YLDwu+Ed JFn3cDxe4Y9+EfNtuKB+YRfKX8sNUU/Z9cKJSp3NemNdoFTQigyVZ0rYsUdmaNFFcXrR+IIq lgUpQUPXFQjuFiS7qT5BLvjOEKUovpIno/ZY5SQw+qyWDQoq4nb9N9g7gCa45AmxfEciZZeN MbHgGfkehSjqa9tNWTnaIHNOs6vh8APg2Yk/w1FeYxFLjW44uFvciFK4QfDecOQXdanK4WFj afsQcrcJg+/3766+XeM7NjJsI01Z+/ngxy3CrBHJPH/Dz69oPSYVkdzKM4SvbmWr7hmMR+6K R9tOt+H5Umqr0uRz0fuvMJYD8wg/8fUnxK9zUpK+/hG2NyIdPMkFj1l3mBamlFIedRhwWufL 51N96zaTtvFp0zY97BuSR0iB8dl4UWiqwlz/ROjS2dTOKhqH5eq6Qb4v5r1CXO5c4z9ny738 S//wKIrTTDhgF/LMiRKZWJFd6GEzjJOtgsf+bTGVzrzBkucdoz5hPh7P4iNytDHcfSd57lO6 xB9fH5R4HmOGCDri/HpJYyoPGOGm5bv1smrtGR1tEN1MXg6k2rzaoLQL4wGldgLKSfgn6Q/H 0NbfdWoodqW4rW+1VmrmhBv2nBW8hYreBN7EfCVetnqu9IzhjFZjKt0ukooUD6yudmsQBUyx fYSsyAc9WmnPM1QqJI17513rvbjwQf/zlBZZlWTkH3i9c5+8fmBMJHAmAIfbH3Z5MbHD14lQ bqVVw9Deu3X7MRDMQmKjh/gK/LITM/lVrvqOh5Yf5FoBwASI7gN/VjXbfQrZHmWwHZ6g2zeG 6bNlcqm3sQdrNVI6WepQVZYfQuNqAznYnWDrFPQqNXnaBc4ppauz472NLSeZ7Qk0ddgnuABy +sIY+j+t4APg4s5ZLVRX3eI4/yDOcl1jAxxP9fDWbclboNyuCVP5Vu2+KuX6dBjMGr0jkUL+ 39qgmruk2VABqFoTPQ+CA2VXEFBH/cbMZ7c8Vnluir3GHoWzF+jFNZXOVYG7W3jvEtWrxnQF NYGlaKMJlgM9m6Wx+uJIb7cWOsyw781s28TiUU9woTMWPjwvBDxJtvmlvU/3OHbDfJPPDLH0 ARuuwKXh3sQyaQUHadq/zuhuVa8fiskv0buZOeKsVJPjVGZ0WlWckCfaxVlSlloYtV9axuu8 GwpHlfEXQ5sKa7IUox2JMcWSJjB+GbJDeWWXk4kh5TV2CyTGBrXIHmoyX9h/XOVayZQzWwoE C8fCcrBJHz/hbLQD2TVcJYLSXZw5zTZshI1ysF3gN94qIi/4zh0+NINPyTrbfu0N3n2uNpvf Jg4IP/w+01/U/c8WsZ93CTU9t8mgqyqwkK4yuMTjqiJSfYDIQB2lKubDcVOC3uDk1qJ9tUnU t0Du2IdLUgfmUj0z4TBkHbFq2j4Kxu9flmgffwChFzvTCgaVnrkXO/Ec69+NBRK2zeSKgodr kIfi9pGnczHCEGYlOU748N0rtbOaMmZoB9g5p+Gvd7/dV01B9tptjVRP2sbWWPeUznjYrrBX KEb3r5wlb1F8z/U12qH/u4AdbXXw+JZEtZFDy0Zh28XYGzXszdPyuDC8wYYmR+tJeWXgJgVf cofrQ8l1Nfye8J49YfjVHJ4051u8HgClZ3u2YJMo46DkdRMpg7xKBUGwZfpy+5XIuUteEY7Q x94jvEDwy/A8f2BLR7VdjgdN+ebP4r6TcojmRrRWIgcj05JMmEEf4KuDsynPThu/QwyK/aR0 Mqqa5yM+DBbEdbyQEqqq/xkGvAC1K9S4gQpTFFzJvln3M4tz4m+3teIUP/8NRDDd+9K6qSMx Vx+U9Sch+Ryvh9rQozw70Zu3MwSxfr4nj8kzNRNr6yAWjGgZvqxWrzHfdGmDiM9tbzK60SNp 1ui7xGp8gIW+Gp8+1jaR5oDR5bYCzRZwWLgAVW8tXsgaZhsmDUpyqFagcIrz7h59wfMUY2ZT etY6xWkGNCpuvTkiyWxXTQ9xv+Idy0G+9GXqfIr3DpF5Xo+hU//2T3Y+x1mmwaRw9r7o1dkT qSrt8LuPPfxNnCizPfvTQ6yUc+GcupebHjRG+XXSa0W67f8HWnF17DHFdOfnpDRPrPqbVu2E HFbi1gOPr8aWA9qLnHXHDLr1QqFG2KVDrNNuXiXYmGSE4/wGapuMOh8fWreMjSJ7VQRlAg+o ZojAZenzZlAAb8/wEFpgLUSWM87ZBs2QKurb53X/+Ks0d4ph6OW+vQ7nAXb/HRoYlf1TZml4 M+sGEwquBPs4B8r1my3DBEU8uPgu3q6+oVb7ORRDTrPMCxQvVswdjHbpR7OKdKtyfzBrv6dx Tk41w6qzGz+Bb3YuLYByo9SoA+Wh1B/G1T7BGgh/DyQof6CL3s9pYHcYI7FBXe3mTUYsyoj8 gku6gOrKWR3GPxKWjD+/n6E8jAQsegAt3hFDbdSbtmmuwf+Q96FM/s59BZtFFsbaafITSnt3 k85+jpyIqFdzGHsNhOX1apu5iKXeh+mUrGQiumPbrUscPl74s1zdpRTijr6dWaXxrVTbCce2 Yg0+0LVWoN0AeUQxybml5gGycQylrzFbMbrqGlCKFB2Yxcs5yyKXrjgMG2eiAFJJugtiYc7O gHeRWAANBDR2yDrliIaiGlNmnA5tII9uVlI9Snpy5zEQlwFgDcjuer5WYICRFKBYdIgpAT2z OOqSmZGANT1FUQ3djdN3dZBdxeFjfbukgVWsJhdaiE75MQyQUTbw6CrRY2s7hWPGJvrW4ezt EoSvZZVUawke5CYZh1oXvY6bphcQiV/z0Op5Eo38kWW71uZqE+JTldSrUczy1/+1VgziAQky qgLT7PEIfZMxDAdXj+/yef2U98V2/zw6g6tkHdSQu6yRhhKegG1we2HIwEzrSVctmJvRZwGD JwHb8YufZ2uTlFcOUEn/+FhDDIqSZAhVT4Vh9zWOGGP8wmN+FMfRknQLGyrJYwp9qsXS2tC7 EqY3elGyrlXhX+AMmxTH5RLq496rHHr1i+2+aQGmRzs/UmC//UHXoabPmgWH8yJAm3HHgAMU PYv7FXT/Wc0YJz2b1LOAlp9dHfABsAmggP12+LkYvOZBmUDhEEQU4r3VvExq27uYu0Obd9xX RFojWuimawyHIl8UVAE9gcVIVwCqCPbokGkJnvW0tY1MxIoAscLbXlR5Og1y6bRkgU0PeWDp HcHdP57ue3x6hfPLINMBqWrS5HAHbu21PIHZ85qPeZCxr5AKbZdj0+fjOyPLHFun0l9vtsrS OyT4vIW3JwFs275D3dUEisv6mHZqwG1Cwyk+ulgNI8VrYc4GWpS6nWHqsvjOADXAa8g70PYc qXBL017ds0ubFqhaFvESY3O8writ2zJrxfnTAIyGTK30qMVcttN4UFbxC0kW2N7KfQPAGMdi GXJZm2V01mOJT53Ktb2CfczRlXDE8DyTWwfRl+L5wlRN0Hyo4ETa1deIyBvzIzXRDIJMtObE fpqrwgXoBNtuxbm2E4UEM+BEmIipIpKSGuvJPxAqRgHtRejmLgEvpvpdsgcD2CcVShsJZgMR cUfYUrmXRRHy6NPvRlXkkpsQpBzsWQ4jHupoi27wWCSKxl+6ToY+kV7UU2Nn2T8EPfDx5Agd NK3DxMD3nRvT/lpdhRckF28tI1I7JEcKRsibaQcwdR5189Mo4xVtwRbmjnhBeYpIRu3rGkDl gOeTClAShTmFnhe1Iba8C0nkuB4cCTdR1GaiD5K5SXdFBrSjgWALZdbe9SNezQJXBMnA1gSp d+hwT19mF5oYy2Yd5xnO6wbCGWVn1BYyUsZqoUkEktcWQabSQ54sMKlwWlWRUsigqgNuzKAW 4MrbAnpCJSFzcVd7aMszQn1bFs051CEclURx76z4GyrrpQSoXR13bOqoVKLb2Wqso2Y9XNS1 fnCnMryIV8R9b3hqIkZnAT3/PW3gokhKHyPZVFuSwzbAEP6rdo1ZiiGW/oY5WwIRDv5Omcyw lKYvxAAvH0hLOi2suXUX3yECFcYTjifla1qBbSzBFmg7b64IPLG6FF9zALAMZYCVw1QTJWvO nUhJdjFC/MghtzJAUXS/EYimBgahZYYw+nDcsOI9o2WsZfbdAGgUqtaVBPH+ZXHP39Vte0jI E09VdWVe2pH6nUJqXIVVOdj01xZt0Lxu8L707A8W5OxC9cxuX/i52QvqWdHaVLsfBiFe8wut SWPQlKlmzRVjc4B5X9LLlK/fvZkomoTjlJWWHlZ+uVX481pyHm1BNSJaijbvMrQ4PLIZRxeb BtpOSIHJ3x/GfQeN4x+iTS/NNtRRFl3TqIBRVtvzX86bh5Z8Jra5E4m3aDipLGT/Hb9LvyWm zaIuY3N8jGr3dtilu1I33SKfXBr8jmcXSwN1LCi5G2FTgsi7WW//M8JxkOLXWnUFlqV0Wp87 RQrfubptWAgheNw+x7m/Q3IXAY6Ps/sJK3xa69b28uAJJnma+azOnmTBr5whTSQdFYjuN3fZ xxZ4dYe1HcqyhmFLCU595ApWfv3674rT4tI36XoJpQjXbwCuP+D+OaqKjt7snC+87PmoTjmN dMemJ9CqCXsVqWMqZeJSP9v0hNIgH+8PMTSrJXfiyIppumzcQChq4U1Ozqy4do6w/fnxlgCv cBNao4vPbD1n7qYEbm9EUVcXS0z1qqBoOgBKn525bx56fjz/ZDvKLHSWjopMA/Fmub8kpJAl zpkEh/GpZSrg1t2pzBSNcMKpCfvOoT3dlhoWfeW6TlpPJCsoaJTSjtJyG1gpsGJ8b36TBvpy 9gfqUAaXxNn0XIM3k6K3RxMsXEMsBUhA2CYh/KEs5DCMKCjmESfhnzCRyBzFrzxKicgzfEWj g45uGz8JCT+j255LafQChDvQd73b8ikcKik4hkIPP2ihwY+GHf6VTIdo2o/JNtXd89lNyRAg tRfwrupqJN0uCrFVwTj/VNWzm9tep66Bv3U2ZXJ3Xk/suyibxy8clKOGRAZnCDJB5Q2lI6oc /I0ibMuIWkAgttfbLL/2RnIEYuSfoRlv0HhhZOwaxDqFI2CmXTYJdiCrTKBs6FCdPsdSD4UQ U5FBJ01ApFOvX421r7KY/6HbawY07hIeclw4cu0uR+pCExqV6ZFHOSrcD6kCLqPGm2phQfiY 9MuwAklKO0GN2w9MOKq79MnFIV33Xe8Mrj7v70PoeqCwHu85kefKAW373FjueeQ2mgHCGeUE cotIDDaEFeI4iIrT7B6emk44CdMYCu4bM5sVlfhi9TWpZI7s99eDs7eaNkGDZirTS1AIe9xE h16Sf/dx6r2D9A8QFrnk2qc9G+DjPGsDK+QelgC3ZWCpPGpbfmKNoMHn1ajRN2Qa5j3Y8Mup W2G4bqKcKl+OOlDcT3Y/OdVkp0/GrF1tsxDwAJLdze1vKIU3h6JgZW1MPJO8SPTii2cUiBmI f+Uw0RxAB9+LGWQlxUS9UCDJa7zdqSO+WiGXsztzI+MGUVnADG7V0O0kCMVgpSriaX8lSSK2 tNkufhLaeXuyE1jmIhIgMC42Gk0wgJmrs6Z71Bui/qW1NXD0gT0zXosf1jZlan1kGpEmIGDW Qz2Ep+KunYocKale8T4Kgh/vHTho0CANdYblgyDmrlmqcupsKBd9NbuhrA5aYOF3tu+bHene XlXKGlFl5y4iI/V4KHOuvaQEwJoJaVjh5TxAHArT/rhCeVZhcTTb0PBiz7KWdCFK00JwcXZW 3a2Uwe3rK6CjCNv9YuO/7unSAd0LOTprkl2fg6MwSi77U19uZnBnodeM2Ec3cerUt9kFhuKW O8eYt/7ocZYLYjtGMJwreLykWblnez1kmoa05vQzlc+/B7tmEFE5ihwzP7Dh6hHaTGFWPVST vdls1yevfMmfprz7Lfms1YvgucYpw3p8BBZ8eCbDNMyy/NMw75JZzTH/oSVNpLdDjZx+vEag 8biymYK8uoy08oDeOTgVwFPjt0JnxxyEPJHU9V2Lh/dLBNug86nqxbDzsFuK/ZPuzqv3yjjf LaJWmlpIOnbJCqdH6TfJ9W8Gk4O5P7/8JQDXlvs0ZnUcRE8KqemWGnz9Rcq8HUTriLceQByZ AZdrKUO3dwl2Krs6BYStgHtFOpsSamUC12G0hWK6AIPrCU/s0vUprXnvyv8VgJmGMMuiCJrD lVb9quMKDjGmuf0m7RBbYXttPDPntNtWdCr7FXbkYY+BdKgLZRPXlruY5PzXncB5ujW2TDtw NtZThXx6Xqz8Y4J5WFKec88GiLYvw7Q1r4XFw2DfjvOhGImOybgdYXg1mPkMaLxJMG2ww9pZ wHeCNU/6PSFohExdfxAgaa/dQtCpxKVkXXV14BlltOvILxqlUkro7OnJodUyKg1T42boB5Rb 1jLDyXz7DRGnEiFRq0DnxeegqMTwhKCh3JnBCg6mkrpDGhcBCTbVUhun9zBJXmgOkgS/rwx1 +8d/pJTuVgPr+9ofDPbXs8lYPmxWgOpCF+iTNIrbtgA0LT381OBSXBpj4iX2eJlDShAK3Lvn v5oOIuDPkArPw3tkChRJbcFxMDH9weLbnHTmASBJDh9qlCDYG9r/G/+aO7M4tWXBQZ35wI0V 1T+aYovGeSC8y6YZkGSIh2K3JWjr9z2qYKPqvlVEJOQWKxjXj4tHSGofYMGL0OrEvMsyu5hH 3bz5nhBO/GMjybTlxEEjQwcCl6ZHcloJdTsR/V+6j5TcrzBed6HF0ihhpYa3WYPafSp1iM5d bmc81VJJB6YpHKMSaLsH+392QDp3UJJ65FPnrbNFY+CQJd30KdMyUQka3SytDCZzPXStipHm CngZ5vzPHimVXAqpaoc9iMeFQNY5TNGW6/OI4hIlD2YaoSv4PCvDwhAfjo49cZHeJENvMv8O CHjHbJIjQvB7ILw/42RHSEenVRqsk4HoPnOBG7ATeeb4b3Can7G73b+m2iHszmW89cL9VBa+ FrGJYDFUgEOVdYegr1R/M1bLk5Ia7a76xmmYnGxFjjqLo+ExNCBDKarqVeCY3Nwigmm+5U+z Hl2XaRi1rbwf2s7MOSbDlanKl/7uSstQtSL8fv4hCCh9S7IZcm5zFLIYVE+yV1TChhhHXRgS V4/OiuoVQCZTOj6lFnKF6YYq/qwRCQ7mhOnqSWcv0mneSr/QYqqmP0YA7WWLyshJjLEP2d61 hkgO92N7dinY8S+9OWaKq8ZI/v7dsNvR8nodbJRuQBLMf+5xcfB/yX7aoTUgbNjFwm948Wrc WNpU+nstxv/xY9VloeS0MLKx5MrQcAIv6tI6h2q56nuMuRzjthwyRuYFb4B3TTfNSGGDnQZR 4d5gOKNN8e+Gytz6Hy5FDfmjNRW+hOg8Dm0r4qFIybD6tbEE7G1Wzq7f/XDbRvbe/V3eK8CN DanM3v8GXPmh6QbGmZr8nhWRh2jy1LE0RLsNwTM3Z018SjKkgwMUFvg261KHIPOOXZFezKyh HLLkrQmtUIzydNGlrDc2esBts7qQ3mZ/HnCEfo+YUgVx9c0sEF92nYSKvwXDOeqzsMP1ZQ2X 262Xom4o3GU79svGrjUY3VoIFk5CRF5tEvUwMUZJN2KlhhOcoMwloTiyiIp+8Z0FOIKT62uX IN4oiwXr8DLAGnebMbDxR1nwvttPq1/jCFAM2kY26yhrOQENKlaee8mZRFhCGO2HidMfmUH7 exroELcPig+SLEtN+w/7zHmqUV1EcGO0xI1XfyD72+rgFya72eLWQ0FxizJrRautb2x760BG PDJ3Y4MSKDFNsxQ7Ybn9q9fKbYAgWlTb5DG6yusy1ZadJHwEUfoJe9FT6uKUlrQLhCKm3ona hNtlnrlwqol9m0oSeEE8wv1t0A+LyNdGFcCFq6aN/fV6O6XNZsNo9TkxYNsxRXDkdDYa3Dyh GN6o6Lpsr3gcEzuKPCzRK/hCpjg+PmWFnhK5skq47M+hRYP8wxgPd+DOzDXghGJN87DPcmID 4M9tfvmCCXzlTLfywvyZHstpQPhrja6Sfq4s0/3G31umd6tRVG7AJUoLrgYo6MFYlVHS8x12 vjbbNME/plEc324eFxzzjWjudAuudKX447cCyf1RM4Sq0D/sydphXpbPgjYjWlSb3SrY2C6G 5S6+8XIbcGjipgUsjNF0AXWR5TroJMRohxDbclFwb89l1yA5jLKViRhamwzQoywI78iV94Rp 8FVAjLJrXwy/h1EgpuuA2SlDL9dmZdKbX2hmqmaMHLgQ0xPpi+CiSaZSulfbuQe5YjIlbpK7 B187Fey8SSCKi0o/SU+gLhUd+xSm/06FmEvdF+7C4Iv0yPULHzw1K5w4/DX2fkgJIBdbofuF RuRRU8UvXxnHD6saX1AwDy3IusNDW8zSsiV7+h1J+Y/K+Ypvo2VDdIKdrfPcvf7bFrNPkUVt JlVo4jDouVusRrN957Nm0ggBRlQnZAYFn4AGL5I0MgMjXQ/bRlyfNiszXTrU0/iGq2GOooLQ 5uqozEsy8fe+skRwsKH5bnCNK6D7yoN82iVI5b0ryPnxaXrKCrW+I/yWp6tL9rbVdc/4WlPe xQct9CQ9KNSAwdP648l0gAOUaUtd8sRBRXkz9867Q6X4w18eMjQy4kMWF94CLLF3Yxitv2A4 8oSXR8/MRLH8X0l/t1X6/oiNevpazI1K8EH5fWVk/xpq/Gu17nM1FSWRHflC1WrleBMTOqZ5 lu9ZbaQcJmBehStxZs2t+aMEunkTU+EGPi4iwANG8r7IBeQ3VyYpoMFBYoJstdLZHecex707 drzWGIOzFJCKRDSO32tGmeYGooym3B0GbQhPvcw9OtMAIk2zwJhU1RA6d2D0Arwof7SmW1d4 PiYYFQKHLrGIDgZ59Ax9ssLLsEQNXs1qWQD5uqBXd46GXmpfTadQoymFOsqWYpbYgYEAsNpM 3VyJn7aLn8K2qzZ5z/qHg5gKvd+VOyM3dJGOALO0ySp+2OaFhyBlnioCbFaY3YnsQRMos65K cWeUBjfO9Uhv3gQWfl4mDoJzpxbt+4hKCLTvPFOmFj6DybYB08UEU73+rGwJkwnvCun9+RAu lAnHx6An7+CX8rSfuBCjYVAXUHXNMezRbi6r6ftfDe+A6eNL7jx/QnJeKxkq+FtRImF16aO6 /9mFGWxA30yAAkSh3LwUUhxC/NMJRmXtMt/BP5vWRtd7rrISIaAsR0SZCYkVkdcPMPaLFcl6 vFPU3AWpWEYctA0rNEJnE+qHRL5j0AT/tAd/Jgk06UgBW8U1o2LCbnL8PI+YVsp/yvTq8ONU 5eXnK+jjI4D1X3YmbmZea38g0nN95+flbuAfgh2DZmeOABFXTVhmyQamTeGRLG0gjsYZqT0d OE4XWfg8rjSDzGP2wTskhakRrXXJ4LFXA3W6A/gNBAqijgbnbcyPAjqKr7zqSjY4oyz/pMF6 t38OraWKq19r+nOW14/3X+StSPNYew3yu9HpppvRFwi9Egs0wIU89ciyutzVa//9z8btWVCp RMEuq7UU9IIRjxYPKCDJOjn4SPl/IxNA9vL6cxQG3waDWWU0uWfMFt64t0nh/i7AjCXYuiOL STrsZbj2Vtzq0+qaDGZdCZjJCtROGpFct5D2ttRH7bZwEviWV/zBmmyoTBVMh+1Bk2NFViTZ xvlECm9PEcfIS9pxrtr0PB8DLKjGlt0uhxCogFMt4kXy5RCVp52h5SXeUHDRh6hUS1zkP1NA W1I4zL0py7G0CFRqn5u72ThLHRw9qZyyELPVhVmhIJ76LrBVeN1DQ581c21Mc3Hh3xzuEgnt RrxPONVLCCpQobvzlTgfx8RWWfLwSQgHpoMBThhnRrbx/Zm7XAuWJMBAXOiWjT4ZRAmuPfJu bhxE7KVsBeh5FNcZ9SffifgTfELj1S7qSAbKKkPdw35WRwT1TFGsrMST/Y1uBrVWGntwdMia tg/W+xyemeGL0TSCum/gOndI4cJWl49TSDaHxaZ0Fx8LF59bOwxn3T01V32pgHH9XYAhRvmR 82E2br5MPyeoht0OL7I41a71Wu96G4HmyyYpjYVUTEV4wZ3yeTejnLDEjz0NVfzqg5qlysO3 NMiWuu4uiYwk/yu607ak15I1D5Uody9gEegj2rF6XdQyq9vojLtsrv/HCVB/3Gj1oCqVdB8f D37qsWJuopkM4Mq+GCKyBJpk1AaIkKkuQjdVnXSlOYhs05WToNeFkBLBWT5uIaHUjPHRQ73p Gzh8sRhXF+numeN24oiaJ+KFt39CMu3oMHZ8xmwxkyqSOlD2ygckhbUsjoqXnCE/we5MJcD9 9QQBZi4uOBfCa0ByEuVyG/MVlVUg4UUMZ0g4Llpws0qyNV7lvhPZddPZ/+l+83Qfd6dOqhY3 ggXcHrHsvyUNMXnV6Ub9jAv4tgMyZ9EiBxrY4QRpanXyoj3SSVen11WEtSJusRgawhG+uHbV eIqrY0GcmzUaPOl6NLPaklE9CJfTVtTiCUXisJKxu/0ivZlDBFj+7xL/6M42KO2ek5NTK142 DFNxv4wTpec6pjPPkkZiSw3lX8kRTnxdTJme4dkEN4+tboVGkdC4Tvx3nTgjuqJwHj9MUZsB O5gALDCPEQKRYCLCLzM7sfnjwMLk5ZbKhaFoxT4vaAnD30bxHJE1pzXFd6fd5/TxRhLbJydV KMw4CgV2QnTtB+sjzwSRImkhABtrteb6kOjEPJxBaESN3cbam9T++5bRxXFJ8mjJRRfoBjgj 2RDdmi98cCn0zn/QxnrohJM+LtiG3x0udyTaw4+7VY4AgbsobL2yP2ITPVGN+EjuHdptadYy 0Q8pHQY73H3pQReUalvtTqrURf43EQLhJ1TSgvcd/OCpGfsFeuy6yD6IfS6twwV72bnAU1sW HW0V9ERbD8QC80ZywnwnxVEygZAonvBmcPBU/oYtnsN0moUA1s9Nm/C1mrcJ+NS+lLM2Gi89 lMz7oKbQUlf9v+ohCf8QI6d/kSDOjAksqK6pUphZ07ShhJGTCQ+zxOMnWrvXjcQmsH2tcYjz zi+X/fiwN7y285O9TA3x46YxYwxO+W0DMOTTSDUgiqD5vg78dizX4YGODmiToV0ABjn6+dMH I9Hl1hM78G4nfBpxf8N0C05ROqN4jqWqF7sy8izSLTSKx3YJdgOOiRTyuDfHC8O4thO+kdDa NBhFqyS08r3Rxbb5vQooWP/irGKmjPO3r/UDv3mhqPuGL+2CzfrmxTMPTGrEfI/BXdR333C4 Fv8oSSNNmzYqNk+TR7bg4sJcHak4d+WjraK055fKpJPGMeiiAyXO6ZCQh71IhTOGj2c81lNu xqiTagOwAoOoY8IYukK74damyluRpfT4OA0gHT4XeDzLEKUpSPwTW5HLhUgy3WUgv7L6PDmN 9bHxgLHgStQ2BfX6/OtO/Gi+cTZcHMo+1RF8o9ju7PwFMT/9bXNxHKLuHwVOX1k6eBDvZtDD Nj2cmFk1N9qQh2WIokog5tQnk+xIdDlq/3qvKfD75DvO/su1XSXuW97EOFj312hiLuOkiXPI 5oyg1WdhSA9Sjo2XqzIFEJwRtVCl8lfi/D1RSbZCU0xKgi/GKY3Lm1Uy3KTjCVY4cqP4Anpf Xdcefe9iNsMhmfZviOX1/GAu+4gJU0ynXtBS9j3JwZ/0eTnNfdzaGCeZAnTRnanAhXWo88o5 g6cABBv2rpqpKM27h3NjL6hmcBJJ4KZs4VXcc1vOnr83hAni1W0lLhhylFIfGtpK5/DR8nu3 RQnyujZeZrgPTHIF69+ktXBgo4h28S96osF+D9uQAMa3+/dxOi1prRjmIIc6fsuSCORdLDcU KXKn2of8rhdmB3AwecNZYOfq0KcfrxLAO0chVkE+Dxw9/T/X0WHO/0JJ+D4JNAP4f1KQBw3W rqWeZzOGoJC/hryrSXx1f0RGbsbRC3oRdhwsOYI9dBzhIJbmeznvidJM3JotQdVAldr6OGs9 GIiwo922CABbd6s8YaH3FrL4thQmNhqjZZb8QcOwn/7NloZfqMjMSBhoAjbyubkXcFIh01IM rfDBMDABehd+W3j+AyAoD2p4wCvZvTRiMgedT087DR4aGEeN7XUVBXz5YgZUMifTMxLyHAf4 F4F5bbAtSmuRWCpo8i7Lratw+K3tgz5rvtW2EdQ8xP9iGec0EUpxYpwVTemb98O46zPWjTvX 3zymMk0A06FPWEVkHi6xlROOI80INMLqqwCiU1/ia+ILO1I9Obvg/xxYzE8hJDXE3FsaSPMI mJoAWrumpndI5Wl/CibUqhUnUD7gmqAKNsEFjQP9UO5EdK9SW0Kl04QSCvz3RGBYQ7PLq4d6 qBO/9UNnXKNcUuJg+JKBpe79PEOAE4RhV28e078gLFmlK3QJcNKI5HdC0VYzkbxZ0jxsAQUe IL8lPCN28duL5LFw+pNoArS2wsWs2azuA7I5PCBmdT+qzWiOcFtDvsN+kbAT0eICQVGYebZY JBrLxK6gT/nnQNqUO6/i2GEDzfWf1Hp33htgxvn0EuWdfJhADvHSp+sq07Sag997x2/mV9XB bgzv2tWMwaCSyVSNR8sXUC5Khq+wQcaAdIuwaJFVsMaApVo/dyiPw6pCH9aqZvVs7lLAMREo 1Sl80OfeYlXlQ/SLnRJB3JQwX9GTuB1+PuiuvJWJ9jhxsbQhiuyfEhvoyZwp7xxXJ96n6BCa LhysMq+6WQN0/ot2RFu4OWif4jqpplctX9VclQWpxfAxQd8wlpaNE6+wQQy4kpq8uiqiv6yt dY5OCtPFMBOjMgVtKB2VJSitIOCXf4GOFSEQuYFw7F2dvJDC+VvK8RMhLNUFJn+r+732NG0v YXekH4SFREjSs9doPQ34SzJ1p24Gbz36b8gdAkFWysWrRVjLAWXPeyNrLIguOGRfCWytAbKj FLs0H+B+LRsP19KgrSJ+uADFsebshc1WYeYY05xpCAKpegS2/0kRprYkF9EPoWJGqjPPMG8e ArJJpruu85MjiK2iIRFJTR/NBqetD4WMsXGokyFyNar68vbrfFRZaKLDbiLwroVaJ/NeZaQq Tijqgm+FbykDUkZGmEXG6J36cCpvE87oUKHIDpfoCokAbA0ouCd/nSo76ZQAWNg3qVD7ZDYV owbNqexbZe7n4u9CwPGh/VVcoOY3vFijbZM7UP9v8MzMCroDVzClFBa4eOuw7H+vcLkQW0k7 hRxH4zWAGCaBQMqIMlAXg0Gje+5yZKSSlotOHYrZJ0ktI81+FqtXBtEYz+uWJuq9ivXy/iWC zbRVa0VMU/WFd5AxOhsk6ysUd5qZX19CGBuIpmgk9RYh0BnuJgPb/sZjFhEnLM481wfVJC3H mraeG7MzblTSknZdRCwqz3TlUQpS0VrtraCDCAg8fnUCfh+GuU85ayOE8nFy/G7zK9BgcE25 AJQDpxLZhqAc8n1KYOJpUZYKS31F5RXMPq0z6wttteRAPVKTUM7BXxCzh/pTXSccxFyvEggf e19VXBTmZn5pi8b+wPn7Yr/G6tPokAGejkrrI3Ziy5xRrYRHb78POAvjKO7vg+q4jhhKAoOp MXpV0lcmHFMlGwP4cx6Llv4QG2F/Gku5jnA+RXJmpY3t/mu1Ve2Ml8Ck7cTzQyx5xCx552iw s+6Wz2GBNcypS6/IeUVrpCj12JX3yRsg9yViU4U1KvurGM2P9/2HoHyaNEflH9hiyfrdm817 yIIl0bHYe4M43kaexjjuOIqx6VanrdMWkuclzcB0CGC6GMACIVtc1pPBLXt5uW3KVLLx3pgM FUL4j3yrlOU6Oup+8NjExHVMPxDNy5yDhP8YlHex6mWsy3jk7NKTKYQ5NN4qt/4yZOEbbtXJ K1mMhLi+EqAPED6vvt4FoB/t4nbV5YFr52JtqYcDJjKyq1WZyer9Sj+7aHqkfLn7Em1Jb0bz y6nSpoYeNyoptuh7GOpfjilfOlLNnJzsEmTP9bWKssNqH1dAllGM/usXf6mR5EdHU5TqoSl6 4LdCBXFQc+i/KQtpJcgza4gjom79G7dk0Xzcwad8ohGPCjqocBzSOf4vmZWugofrKQaKcJ3H XQnOWuuKd79SVAncfk3cx4rJaEBZIHnLkavkzCe2OkBroU+3GLWd07awYtQYk0yhh/b+OTKm c0tX8R7GpHGObzrlP2NJwYlwrqzS6L1d0nbXTo6os9Ehp8WajDmFovOHFLSg7Id4z/Eb4cjE 1VP9bVrxwiWTFHbuwOOTMIDhbApwkno8KrJeB8bRRdOzFIjw9bHCsf+EdoNU7fOPJDPEEbjD RcWKQaNAV/GkCgFUO9hmc6erm7m+GJpG+q8vDHFtmx6XnCER8QYUq2gidSLTpKOAKtOmSJf7 jQuB3p4RxA9T/4oXl1LeAboZ2BvgbzlVXgP3Uj7JAUCIUcagcIiQngMjfx76RJAkSl6/ThzT HNlbJyWMNkJ/h/+BB2luLH5mJIuW5oQjujIZvqDuTFKiTCtQ/PX/rR926uA22JgXPZl/GX9P yNdGVFrObv9HexgE9/kqJHlEG4bTFFA+3N+wrqefloIFRdmjPu9+tTam+hDG+j+wNIaoDvqG kV9SwVC6pEbtfFTNgiYNdf/2lFXTnE1FJ5EFUbrix4OTaSEm0Dp29BcRCSjxM1doRM0vLtu8 gkXVNFwthtgpNzK+47xYcJLEnkDtwy6WI8PMX6QpA5RoDZSb9ntgAXqJnb/gh4KgqmFdPId6 jTIgMsMfgFv11mt0BHZ8SbS7UYQO8xBh7EREtEgaUDT6hMMJzGgO6tBPqYFuzRaiix4TKdxa uax2yPB7AuLtCIFG1oyhqhHXqgPBeUxFuhuZzP1mjqgF+kYQjqtxeu7ngwwpkyFOfCfY6+kB mgYlSzz/Xu0E28tUHMg1Bl9wjVBBAt5fT1dW+NjTClD5d8RM3tHzp3/cTsCYavR+q0t/7AE/ VFJBrFJOQAPfCFnYyMMWjl/6syE7KqmLhwEyUAN/SmBhq5yMoNLGiVBBusRJzObJrD5Fnlrc GhjbqVuZE9+JAuTsrCGxQCGV/YZsFfBJnKl3r1s2iKeEq+Py0l/x++gNY6mr/bWGcfp34oIm EFFqgySWvjYfzlmpnu/KkJPJevxFHNooIS8g4TOmHHvhdZlAt3BH5zQCa9xedEUn6Sydnyfz Q00n9+8XcAy5L9jMRdjtYxaEcG674PYekMGxXRGFIuVEsjYqfx4Zz4gWukmzbDtQ++7NSejg oi26ywN0bbR/lyp8Z6BMs3oQSLX00TGLK6DHKGElW3e8V9Xa2EtSic1GoRJEgpRH1YYAdrZJ 9VuBBh4bl9PwVyKbuMJXSZL4EyNaDTntIWuWeA1rzlDlonnrCBo8DYKEQFS7LAfNNx8SQ49b +RhY7dxPRARbMzMyddNGihvw39GFtT8FN9aHVPVT0MLjU1rt0OxcK1sanc3wkRFIkXI9FaSV LugZ3irykEgFgbzczQtDGSgCtoqZHwXQhv/LLOQoqtL6/zsJMoZ54m9tBsceB7hpiT6F3I6j NoCeBRUiGnXwE9gjpfQP7Els6TQuP9Cv3QHEMJYGdJBsEOGNIOH3mXGEyn3e2pHtAEO4zk3h Wj9Vtq9A2b0u2SUpiv/euUDdyIkD5T29huePhS7/EvUaS8QswIFtoB1zNQsg72j7SiJNTay5 jbRbCqpbfWb48SYpIcS3xOvTYeO2Lk4ucvA6MjJq/3F2fnWZfj/0+8oerxC4Aei7ZAwSye0+ codGgnFZ4oE2x+An8Pn+9ExXdEk72lhugh2EshebSZP7Ujo6vvUkXfPEmKBwtZ3ooN6Psp+O PDkdYitZxb6Kf8YICHkthefmZ1RNB6d4D84YOkxNEAZTiSSIBn3C+B3bX9QVUwe2yLcaEZRC JdgryH854sLlFYooXX8xDbYtkpdHNS3rw05Ur8dNVgRHLWiyBMwOZ0AV32f0Z2aOxpMBwyau Vyx4ANdka2R9t2YC+9oOYsbZ9sMUAaiSe/AOJX5gUowgv98mbY3LFXFrQTelO5o2KNGcij3a yznI9RvXQ8eSGzszv1WIoSOqXzmfqmcmznIvSVmFnf90Fu447MrCfB33ybIEQpjE2gfXCP8Y GPeVYYzaPspwyvFqZHxOz89NUdPo+GQIB6j+h6L9jynLNdS5yVYFgyDuigjDRkbIVurlPCAb xI6KjQJaX/Mnc3F6s6shVrRpn1VQnjKlUn+i1uvlSYrJ5v4bWsybdezG/txQel7jbb3x1fg/ aq/OhPpFTbbK3MTb+IKHPztgvzdBh8Ny/CnuPd8Vr5pp8g5Dm4Rt3EUmBZ8zR/6nW9hn4fz2 r+Drl+6bnb6UJunhzqDoZuraZBjsbEl/e1gQX1N/X1dgZ4eqw5GynCJrVozS8x+ByfHwYvgu lRwRlQdB3rQkCQ9H8u5XRXZVECKISf5/yfh9zggmEoJihXdu3rpmZrcQcFGHeDHw0qRUmShi 9lY0i9tPDIAs3fVaP8DLFLTe/P7GYlnCCh9sH8g+66/tymOR7au09m8JOlF2CMnTGwguOttA pjJbWT4DrymzL2mV5TnF9WoyuLMYAlAsPl6LUMx42xhTPqcv7hLvin5rZdK/9gMofh/Y/0EG jBmuL9zJyDOeQu1GJrLqI6Da/ftI8qtEdcDEPqFPJBvwPnCRuhgblV3y+5evRhQvCrU+NAe8 8SVjRvuroWsGyw9oEnbZcXrgcMn4TFSfXl6rbB+6f261VcRQfORsjyXkj8EWYVHT81e4x/D1 BR9UqNvU5ils0qjp655J9PWDHEcjMOOG0Nlb4XyxTa8cy8C+CCxYexLliX4P7Wki/WJaIIrO PLYeUknl89NcYmnlnw4oyWxBVrmloXWiQe3MrLL5E7ImPZ/+6iAF0V5V2xOVOFnOZFrmq2Yk N44dyO3BXFPF8rV3GwAnnmi2HLupWXZ8bpl0Sr0lP7NPwTscGt6lrYTu7pVQf7zDWdiGy4FP +doq7rXTbM0MqeQNoALIIR2lkjSM/wzjcJ9JrBBWx/tZVRALQUy+HXTcspTrIDGcVSFfC/as jjzrvLzKMXW+wfEA3BapxqymBUBaoOQCUICy+UBjEtCs53kHuV14hMxCOr59ltqX9pDj4exi auNSmBwRjTOc3CIXRluBZGtCEZQ2jI4Omxk3Wr2gkycTD3F9Y4EUiYje9z0qrQ7kmMpK3Wlo aMFdHu8em9H7PjNN0NA2mCa0W1FJAUk531V35uxW/oYC/+Dr4E+CoLWe58B6QOvLpslJaAoE I02I27copCQ01pm23U/7YRx642V9hYlMtSQPYsNDMEB2jXI52qzSvtW83zeXRNG2+ay+kqC8 rtK8lfbhFj3Nb6kgGCrmVC+45GOvlsFrhakNg8eKjrKe11ElN3GUjIrZRfv+KmE2ZBT/Lraf nG+lr8yGY/PsBfA/wl5RuEbrahLD7/fGRg3oCF8i3dwR+rPKmodrQWQOO8q6KFzILuUtwscu kx6/5gDbatgS9nZpXZZf6JleyUbfko7LjsvchAP2ENDuIFo5z5etD8/5MSLNn3oepRYGU7fg 02fdj9H/gdcDRDhPGx181eSLW87ViSme4hnCvm1PngqgL2V+k+whJnImUc6qfqExHs1aTTop qIVzwi4CKHF1BqUxJ/WHMcl1/9SVtWQCilj/DW5QmVW6h6h9aRPLA7DhvDam5247GMqTkVHY seuukx4pMgGhXULtqff5dUX13HLKqKRtmjsUHj9v2F2c0Pv9go3SLiADJ0hCRn3d2ggUaenD xRPM9FvUZN3rl+8UMG0HDeupVVVdaBK6QxdGz8WqgEsUPXxPHfnPQFlKc54d89vIeUOxYCNn v9RKZNWKoOIua7olyKboAQ3VGVBiH7t9yGNSm2ITg5ONjz7AgrIhJlgmVRsThdnWambttVWt y2N+Z/Drk4a+De/eDx8FqhUSnoOzHais1gW6qISw1jgBX83xiv0OD/kAUPgRLoNFvDznq+A7 BarEz9M+e6yVfQpU5B//TNilyvvXz2Glh/WqxYJZLBSkLukPJ1SnK7Resv4N8rbmTztrmOVG k9ls+xBjii2RbtlBstaapfc9yUByR9lgw+CK79IZ60sbAzmTX08QZ8OgaR9DacdH7XswDt86 jvhrkjKw4hvqOs9OCIA3uIzJnpUj6DTOg2QdfDLtvk+11zx3rzThiKx+cdF/iNov72jg1K5/ 7BpOUBb2ChZLUn5/7sEIGAxm/6uzMQiiSuIO6HKs6m8kdr2TmflXuHOnyYQNxApvQBxtxXXF FRl2DD6MUTTgNZU4O+UzTMXvBif/DOGSXjMvo6VKBOjPsvOv4XpbasWxnuh1Ag6XyAz2AIF4 r5AF+PqUCuuVolOMxzUUuJvdUtTJqA3qNSCJB7+5Go3TCGsigNLE1lMTFWyJddLbmUxzXw6g 3coWcnSgDiNhtqP+bJMjwuINz6JC25sMMyMfkqAmvfic4nHNDOh6QLT63brYdjJN8B/HVb3P kW0Oo70CoqNGolRU0A7U2LVL9JbSHwp8ITB5vLo4sE0gIrg53rqIazc2+U731pd7Xrz6XUrx CPfjSwOfXJnwMfibFrkY83FS6FlIulHiDeG10xU8R4l8CwybXReQH8ZHio/z2qQ4FxzyU40W BWNrB16XtbZumxrst+iKB9EQC/glmSFgE9HezTeODUO+051Yeu5z55X3lfaU98mcAyS9+AMO 8fLBXGxLtdJiU825dwaeaCC5JtyhS6y+wuAnGd60rH8QsWXEfKq7ytu/PHJY4ilXgTzSAjY0 y8z5t8YncxrUOXtpUHEdnVlBdY6h6yam+tzeL1imF4r1wAVNqpvwTdNUD8+McvCzj1vgNk4+ pLRUvh5r12QwuaC4ydvyfOG7Dz0osHfT6XeH1+NenjYQ63yRCLkR3KkcXqs1RoTvEFWQRvmK HkxfoAer/hzn+206xAEjlk40Qb65DSMS8k0lunTbN2klImUkW7ubWArBgoBlMCQj73Wc9jaY yUFlSW8fxD/3ph+m8RKrD8c4ds5K93KCBGhSveahI0iYtJVPQ3DFVF99MHOJo2ZEseKLcAog GAqX2rvTPc/xe2D0vkCzDUKWZpExmosaoFVrJzeQ3D9LR53a3wQmbBI0doiPjp8Dus+qU4jI bYht9rQmBRDRiuxPVrtNoyuWxJzA3eUX2EJ6G7x+L3l4wI56bNHw8/wZqNawNaKr5GrSdTZw WmAJIEFLBCg18QsFIXrAmUUugMMNRgRKs06j0nWVwL48t67qjQGXg+YaBBct6x0ez6YMjdk3 id163oj3tDZjjpogCkl/pEiJBTCvdQxkua5jtuOJ0wx5uA/B+ZtS06VUOwN4fHeaV3jezkmi ebgYGaqnjTNP9nmnKzhNYDkBVoz8N9ddrB/Zn37Q38x3eH75f1qiAFnCWR24OrGyI5s35XKH g50zP+O4Q2dt2HvqH1G+Nbb993+OZbdgu3KiyI2TuYuFHMqWitwUR9RxiPJI7lS47MzfKFtP Pv9XnjNBkA7F3GFb/mTCORMDdEsGimJjQdiFk5/ioRlIHxm+t1ITxnRgsxNJKmKxUp7RoacZ x9QDG6s/RpKHXh75bib5t819GIqN/7p+kG6Jbz+uRnXTUALQwvVG06LQ8KxN3EUWSvncH4KG nJI/y6UrpGqQi5KQ53AXLAoKHL2vm3Pb6ezLxQ6Y04WOXF8CmgcgVm0UHXXPoFRZ4AsBzdKq jUQZQskdBusol190yJBFbS26TZ32dDAy2OqKGBZz14tRZOOJoqROGb+iBQV4g7FMjrBTiCbP oYL7H9MvquPHFkbuB98yAIo/dL5MVHzft5dLOP7s1NA56csh/FNiFZWCM1KaOFk+nh56K1nf xTtsxbYx7RkIW4Ada/cV7Du5EyVw5DCH9CxbHX1xj9/CHUmqH98E6VNJZ0EjR1xo711BvL1q Ry7ojRY3Usbds9vukishLqqcSTbIjuKVBZmONdc4K1pGP0gDH/oMZsS1Qv4mRv3lRwlyLniQ qjAU/1upEXGQDz5ZKUE97PPvIqUWJAWErDFptg19Rg7DgR9aL94aajj8lCNPwkMQ0+pwm46a ED2pefaTy6AKrvvlK+okM8Gjlk1R/OEYigq5Rv5FIuagkaBPCLgCSLkeFoOFpuGRKp8Br7/R 1mC8gD9yfZHXlyl5eXx7B9aoFg1qnqIpKJcEyFX6GzUmux9EL8VKNmmPpZQr71L+X4cpyqe5 bnMqDmKQMOjBlCkhaAMQhXK9egcoE6gnDSYiHCrxhWvYba6ZTiyikTJhStZhYbXL0GoHVwdp gXNeLg3L2eS5FlhWpZ3J6xWNRhFNCA8OaM+SORvKebgjio7Iz+3TZoYV0GZ6GV9SosJ1BLLP 2guMKEvAduXLu2JEe9WQ+4uq+SnBRG2YzouyP/FNhftrNwarwWKVO/qTbNm4xaudKuL/hN0r p8yIQWZGwRRSXgU8cyXiKvnjd/CZh6DVrmrn6jNypEO1+iORnzC/hdV8LBjNlSCoI0q8KqrB wLK7msK6nJA1IBA40Kbcc9aNIC5r9bJj4yJMyYnHGq9ZlLcIrqQ83cnhv3IIw5mFw5W7V3Lz i7l2IkxXX05WrZtTbXv7kCfucyg0j6WkIP7u8kmBI3wq6ZnT47gOFJruKVjpkEoQ69Rb6DWT PUljCLtW7C3COhbAvfjiVYNjav98L5eWPcsHtj3uKVQ2l9dALHjtC+IpBbpKmrKKseIh9YZ2 dOTuZMDQaCgpWeWoN2i4hjwgMLZLYrdpGhQsJBx0wbvI2EdyeQhdu33Ag2wASSSrOjFyhM+A i6zMFfnDXAqUkTAYRRw6RBMGziEQyxtMWV+sobTG0HOaFnlfjOxq7qx7wohQ22qXZFkzRFNv 4+su12sCejTb+7ebMLK9sgKHQTvgxKX1kmzdynXcKPjflEpRc/Kzo5+XrUnksWWQ0sW57sWF 8mn6PS8YsJEaxlXF/yu50Xt0836fM943gUaOGCwYVRuws51AwsQ4IJLlgrmdasLPMMpS/IzX POB6Sf/Aqdq2ZBxvQ+Q6srzIQuPbFk3wFA/wSoVVVjpyDHbpwITfV0M8/vKXF68O2nwMP+l2 S3MFnL0hT/wAWLsuo9D9sBNo/jtIjqE1AbW+KhvtlrFzLdbTDhCgjj6AkPwdUFuCm83lswWd /Y7L/8S4bsA+GKZ/sUrOar4UHVM70VCM/gKIAGY19hvKaC5KLi3HfRJ71PzmdgS6Bnjh5ml3 dQJM7JC1JNOt6HDjKy9k2/3K8dcCdVwE3lF7FvE/roiTclfLeH/YhKMpuPPvM7R+5K4Y5x3D awnyNuP8HK/Ot5P8zFa6KISS5sp09/7v8Q/iV3AuRvUDOe58731L9MxmF+rB5P9SYA2P/crH D5YF+iTVhNkphgRf7fq6Kh6yUH31qSzScQNAnoZ9kHzV9kaRxwUpIh9gWs15PXMzwsJfU+8c wlwvdf+Qh57ReVpRxXMahSsa8mNh0zao3EnexOpaXDBE2RNV0TzEoCMhstOplhjtSk7VDRg1 pOUCcL6lOvnC9F/vYXjdLvZlwH8C/W+3ND/gmXmu8HXypwayrJBkZ5jWtCm0SXv9OFu3r6Wl g1D1w0nwH7qCWkWHdYK9xyXxwXrAKEB22R1S3/2n3X/WcNfzreNaHcnLB1Wrbu21ejQv6aa+ uhRPXFfBsxNGJ5twXrB9VsBSB0qoqtevd3QeoPV/15iWuvXPjfFmhSYRSIlxHnCmzOf8IMIC RGxVaOf059MUG9svtcDRHELH8OVCvuBtFVcz3e0petkzC4ijNa5JMqRkY/t6T78CfRPm8Gh7 EUaGQA0N1Bv3SrIMeq3iEguWVUBiE1BWfecAUI+0BBGTxNByJ/YSRuM5vWk0LyLxg25rTYWo OnqwrIQ7hvSeKsvlHpjSlKQWnItVsHOCxZJkjp+SKOPqUsLD/gCY4Sx48zmYnDIatRk8tJ96 DpeG4i0urUgQTKZ5tWQRJhKJ+C/iiGJX4fO6bP55lkVC0fPHY6CoX7yGczvphWh2ERqEiak7 +eISU81VR6hO8NQrAEBoQlZ/moHZUG/7v3B5xZnK6nqp4zFzmjruM0CYX3HNfMtMZANxeptP 6S7rKlmB7q6RJ+Zf64arx2kYcj5++RzxP7Ovvgr2OS4Txdr77HNTvNBe2sZZRLD60adJCOZY xJZSXiW3AnmURCK7kROURw14p9OcFOYAFux64J29fcI4LwYWTHq4b9wxmrP+3P5wXlbpJId0 W6BKwkjbfuHsDOrXD5QPGkd6PRy4laUwT8oFec+1QPQqFNCHLUmNg0YtfF4D/uKi1T+Rtnuz 2SvoZOEJbX0n/yybIiJtN7BbYtDbQthb93YFALGiJZVu+OANQoSmtpRLoBnXjXmddeEIoUvK +Ntn5Vtmo2Z+41sZZbx2mAIBgnabSsVSrExIsyyrel4o5atanZ0PFTbu6BXJxRflJJC+ATQQ IeX74MtTg4Ozv2LWedgUNV+tif27Zw0laH0Z2mkUT5AqgJnfgEOsg3ppCG7kdS64jm0ZMBFa /8YCCAxuBfnv42efYK5t24c0HBrrALrOXc5A75Gax0npsRcvLiXuh+Q66CKZ849QyGlXEDy7 SRuKDBeu2CRfAn2YAJw51sEWVkbzNSwrFYPfq5eWlB/BuV1al2dHlRjB3xOUR9P5fOSriP5F Fcw1xJn/ulrLriSmxp2UBWfY7eZMnaKtQT3aBPU076wfoU798/IFXoDbeqDznqF4DTSTbDCl ijv7Xjwaw6bKk5Hyf/xo/HgWj1D3lEjPTHBsXLkS8XY5n/r4oK3UQwzaXToYpWWXEXg4ZqD5 iS3jyupzM2fDZmg0uQnrh5YuydegoUJ9DVyzfD9ZTDV8UrewFsx9cmrQ4f5g0k3EhsKu9DTL UE+ONr+FXADkn2B8kAHLidMy3gg+T6SrW4Wikw9qXYDgLjSmNJh8u0uXcKbnLpCkbuzmtJ3U ed9IM2L8VPrk+mI+jeQzxHIr6X5f6qQppVSjQ78Ek3BwbNl1SnT14kw81qzWsakMFX2AoV8a LXaTO5C0WapH9s9MUfqj8HPRZTxvpp5VSXYNMAJNk9n8M2kRyLb0IkTtfYLZC9r9NtF6hWRq kqX0djSbKuO2kFJH3WTsrnHAK2XG/iZjtD7n0AJvr1me9DOC0l4A2Ywf0MBPk5AB3X24sPKo ouWo8R5R/FFjCfjkPZL3wZTONk2J7+yZFhGejba/+fOqwrrU+5e0gH6H0t3/ocYPQMNo+POu 1O+AR6+9BNZ9B45Oa5LonOx2foCtYR8Y6aPAcmRE2Qzs9Maa5VjKPRAW7egEFEqq8RfxAucd 1YJHFqVakSJjRCIMzR+C0RQFgjREEQ03R5zajSuB6K3ezrMgqH4dJK1mgor4t2uPRIPJx38K Oe1G++J0sA2eiuymNe2yn8ChtwKh9tEM5uWioKEQ/LoWNrV3e0Uo8KUc9gNTPvTVBAerRgyV bsL5LZsawE++O7kOjKVbtjJPtWWp0BLJPa+/s4xnaXL2Ag63BNXJ5GPZ+l4xy0tWqOcG2pJp TNsoC0uwOZpo4HY1Ev2HWbu3S34v9dHlag7BN6HIinYRNql33tEMwf5q+2yGHzj5S7fPEhuO fkcMNPNVk8LwoJqZKXhqGIY5rewyhAVUtANV6sdaB/d9xx9es3znyRK4LMCsCN0zZab6vQE/ fruUMWOdZcaHcxDV0RR9LUUtaevsnFYHCHBNlPEVi464Z2y82+8qjADE1NTKnTAqneenJ/xn pwyfOk+lxJuMhejDQ/EGo8VUzshG9SM129cOZ1NAsG8aaccGcYUyGtW/VYY7/42AgdLBpA9S 4iuj0i9Zub2ZO3tqpXtW5j5B1QE1sWad7JQlzo5r9S7jAr2Ut3/ozc5Ag0vK3sxVrjIIZz1X NixC28LfpLWzkBvDlLExym9e6H4TuL3R03DPBybvSYae6emT9lZXnexWcKylCvv5qNAtMG+V rEGkjUVPSdoop066Etftg7s95rlOg9ul7vjos/mYw+mbtFzqoXCh98/V0rcXixE41Cq3A+UN OVHI85+3OIa5YLWEI6sOdqe1dB0EQe6ZFAUCRCOztAplVe4w4fUPmOPUf7SBGjoBkSoICgIU ctPDQzq6qwIxTkhgjzmGTHW4TyQqa9QRhfzYD3l/EfGCWane/Mn+4bzX8EG82pIId+kNQvgz OBofhFOS/LHARbdKM5FnQ31Q/wHvryw8NTegoAFV9S2WwOKiT6KUIqvvxizRmiXJUevgbAu2 4utU4k4nUdWZaHOOeWi9BrcEm0DVhu6OF4Ll2nY/HMv7hI6FH7Mfvvz10ZRFmPWogFIT6grn 5/qF0cT+f+5GKHRtvIk1QgxGz1Mu6V9m6Eqdb/71AjWFcFzbe7DSmpwDXof8yz4epTkHYYL6 2x9mOEJy89BIfMq/V9n/Cs//SLJk2DYTTVzBS4xcuFX3yyNUE6ydhBUD58Y9zNP6299ZU5Yt 1U1Uv0ltOWt3whwD5pOciiztOWd5YbD9t/qqPyK3Qfoz7Y9l4fQVjz3k3VbHZJvm3UUMaEcR wh7MBd7NLNSB938dTw8nsSZMwqLMfHm227hO/M5hK08F4+jdChpofkKs+eSxb4jFW/nmZ7ct 7j13ru8GEdzwnDHO54muYv/08ZxXxxYHnH7QTw1dtqH1zdyCK5DKFfJgMGvYM9mshj2Ucg+i 2AkRQ5N9dpuvz6z+JfQSyYRqzmeSQ0Ka+zZhif212eop39ZSBIrQpmaNriz4suY7E5KJGDKl lYgk/sMhj81wQ3AcIiYdSefmmXVBZypMPtJHTFdhe0Gkn/jB6cnHZcLoRbdNfdr2TvJAvZ6K 68+r4xT/48yDHatfoJ1aDg5mIK/4vqNL+s90B67U/XcrCdEhB4E9mPZx/HZey/LYR3H567O2 m7l9ZSAPqtQdFxVbeLmjmGxrJ0NDdpLQsxC/YaIdMlv8/Df9HTvSiO5VIuhW8kT2xPVY62r5 rI42zkJL9ebrx1DtzIyZSPZuJ4FXxxAH6IyIxzFk+0Ivq1z35zp89UAxQZfHkC2bdYbY72Kp P/rnw1+cwsKk65AKh1WAxCkMM6jfzIdWQ6tzMGA6slOH0g0OsiJ86G7YNawAjATyfaZrUfa8 LaHFT+TVzRqX1F/B2WZE59lt1ZB+jMqIeXNBosVt5uoaLouqLYsUhQDPKOgTmlLuo12Trixg Y1NgZY5UxbY6UuErXCBLe7M+mrtCBrHViy9SYIswN8QTZ87kyg/B3K7plV2+zTPmayMDda5G KGWqlTxV8Sm+rTWTdVrVl/GFlrc46nuxGx1PN/Ifv41cTK2dBYIMimIN8MwEqrrjpk0vEwDw cFmZ7+wKGwLaEt2iBKp3hIR+hMy0I5quslCl1j9qSHY4QvIX8mvRY/8oNoxdGBqsaf7Y873n ctplu8idmF3SCiiTm+iyTCdjvPXI6sLMvH4TqASx3st5B/BncsWgZG+Bjd9OyEn72CjHoaHo bFfeMtEEmmNGjkEaXq/DwkYf2t9PKFAbLB7zK+gQN6Qt+/NRLdp97B0hpR/Lzz4MoiCbbSYl 9JOSS3UOL4jaBlZe+yBmvm13K3x1EdeL8CcyOiE4n6OET1d1FIrG8tuzj4hgf/ulZhaa7H1k GnqBPdHC2ckvy1F2m20Mg5jU43SEQ04KQT717gGV49bgd1ghR4esyn+FXwxRexkMPEdO/ZU2 raf/r0x1/LmLGLqACl6KyNPh6Q8QivmQdQGeaU8TmvJAMXDlIj4NX0trooIkDcdYwHY6wpqi Bg8H1CfDxWopT9JyZ+dXoWwVXcjYF5pSGPeCUYT/X7JSp49caKfH30b4GJsCxilVaX1OFmUZ PULioCyZlFH7sXJrOH03qO6MsRk0ODR1fIRQy3SSTbwCqxQXYHixAUKju/ESc2zJM5JPekx6 9yF0fKNzUu7XFz9Vr4084MfX4NI/OEwwVaxOtqSUyuIpduEtncpTOSgSyxPmdqut3bmPySGp UyF0gsWotq1WQkbuunqFDbbtX8CtkWXRPbTnuvMlPKUXBPjIZTSwoRfmub8uPAg3xAYii0uf BL0BxMAyX+Kr1r4pM48z9z8GA2lmUKsWfZsIUsWU/vW292ULbZhlBHKRxnWaOwwvxF9x8a6+ UYpP8du6UD9eaIwDIl/eL19HeRc3/jioCQabyPf+AMivcddkN6fqalIRpFAEVzy7SZrDWzto gUyKrhFH0qSUN3r11g/fVNhCManOJQ+3RcGobMSf0zn/Idbdi+C4pm4XTe1Y3NobKfziX1vC u9U7Q42NmMnKjAauee9D732Z380CKvU3lykG4EjV0Yv8wsTZ19Pbq7TyzVITFTaKk42UK3tE ZdlDgLSXOqaOEwgJt2n2sK5pTP1FnvzABw2wfeRlJwD/kP0E5SDODjpHgQ1trA0YoJfJ0hKP cwCrVVE2Uzbq1CUlomxLXTLwz111RetH7tF06T0dfTWbagotWGAt2iMRgrGPr3wvYt2VnMSN 65wzVSrob9QZ5WJdTIjfubMilraqxS9PnIODOPTQWSwqLbO6lT2Q92hZ7CaH72QBc/KwtucG cblFolhdSuRnf5jtvNPLgEdzV+BM0OJf6QX4l+jGBusRGrnDMRppcWcUHnM6DpMbwsAPPxk8 mo1hY2cP3/IgAc6ewFYNX6zs2ay2G74kEv2/uZzHoZZ6LlX3RGDS0MdDQBtZhdDghJqssj6T SPrkvBKMJXg9EaQTH1+27l4hd8JaCt/JYIDNJQWCAqaro97FiUzh807gHitk5cvMtIuJZJoA HjFriQH+plVWhp+V7rhCYeR7Y+T6lVO14k9vg2JauHQtQzON7uji7xDmBVY5NeP7V8Bl9sJq vQ+aNfB19Md2SxnYCm+42y0WzGd+OcbeMrARFNwahURBh1D41Jo1NBZoDO9GoY25VXbosGvb TVtTcrWVM+rjvOKVj0oe9yrV4ol97t8d4tdZxj3YxewENrt491wJzJruIBgWBNhXkEd96h2W qrfpfevJueXCN0wHpNy5WjurA6Q4uanZnhObV/CYC8n58EDv0CZaB0J2nlbjhhrxaLhHGV8Z NlDiiDCe6ypS8RTrKaZ1zDZTDKyN44wGzX5S8Rg0POwfkIqhbDSDFfV+6oiRvS3n1LqhRmp8 at7xEK18ti9ElfO8UbiWTgwObumBkeh7F51heCK4pjtAaNMhYXMM9B9a/XB/PhqT707GaOr0 41M5JUefvJ7p4j6vcmE0tRqUncj2SHhJwW+uVN7Qy1qTP1FRpZT/884xZIysWSyIXTsJMypw gW/YBGQEqkL6c4shoGxQkTjxKCW4vbjDNaHF9L/Zon5WIGeUwfRW4M46sAwqCsytVHIkbwt7 ok5QYgfl5VFD0pXivVAIAIM+7cPl26Nt3nFJflvU4EydDpCs30fXP1X9ItSoC8GOrmo1rA8U HMKuccao7TO12T45logpLK5329vFINqeaghXwJVx9ba7GePqqjvF4zjej9vwHNssZdKn2njT LU9WEyeUDG88Ded9gw+D6lR7JKeD73SL5vom6urkTto5+HRo7CqOll7/LRQ0YGTI0Li7+4+A wUBzUsUzn4YeS8QzdfPLDJMKX1GkO5HYy6qyhEA4fSkKErXzozjJFLSjgUlo3O5JJJkPtNZB m/tKl6yyKdUeoIRvgKkxoGJqmLesQZ9zsbS3++nCm5ymEj44d+meV/VWA5TfatnoOZqMe1Tz VUhMhXqm6htAL39CqqQXsa15dj2Ot5Gmvw9hDRZtVs7PY/HphQxWi9uzYdsY1frr0BCc2nah gcdPV5UxWy4ojvx4E9O2mcTaMPX5lBK1aygyaEraZJ2iCX6AQZOmhLKmXuE9tPxf4Y/z2JQn 0sdQLa3ef8aXpwZ2HpLCWwKAmaGUDpZHheEsxGksc7JA8Wh6MU6pbTL5ccCeEEB0XEeMcVJ5 ncca08j1hTzBeOnrgji+VolTgI1B4MqQeEZo+6kIzKLdW5bXklQmJlL2PnuAOzaN3tdegNy4 vdQczaQkPbJQbNz/4mpjffLbZTO7BGpfyN5X/dU+PZ3pXEj3qJ9ArDhQhvr4fSkLNReshC/O cp23dDSChZVgkhN9lVL/z+ZXT15nqrGxzbadki81FiAfgI/OdLouI4lwQ1M/ZWkOYCVwaCD5 r578ZJgoO7dpSM6IKINMHao4CF+uEG+F8SYYvK3Hw+88Fmbm213TX6fTqj4ZHHOS9WP27lbt RkeQ0ff2i4PLf287pqb1wENBCTIUDPc5Nluk5Y5KhU9zvjrm6AbX8TnupxsK+3jpjvwe7W1r /de3LcMmh4qb6QlHlZcFtODJR1vIeD3Vj6WOp9ILSygFT/HK66sRTTF5i+V1dPR1Y5UA6lWc s84NioYuhXlbeqyH8bDjyiTKv3Bs6NYSfLEAymqseyTkHrish34arB7P++IatQP+jhpfIIxb QTnMv6qJ/lLia5r7Hwn+ywktW/pw1/bl+Q/PmkOYV9oiVIvGBJSauQ0BzHsKL3hC7K0/h9cW TjDB1sMcGhuUe9NTcXG5rmLMG4Cd61KiANoseTc+WR35QpdhxPpxRrSRyFgKsbHvmL+nUSBB ZgAWrw7EQisA7P7quRl6mLV9BOsmE4DEScS6V0ZBPqxq/G6zvlItt+c9+zMUkO5AUOjrc1wF HYWiqsGyx1zRiAiI7YeNAGaby+QrSghSyqph4qY1BpsXEoadkdGVkMKMGqA2cQlCW1iM/BFX wcbP5jvNvU3gz9L4X9MnS0FdZ25+KuyAaZTOR+wN7MbFJUt+TF2KxoYs0lb0Y8kym2KZFRbn kMVgTo8wVEXDPReqm48RptPabXGp+8fNEq8WveIP9kV5YAVOLW8+ROMJPBnUBk3xUMXGpPoW 5JV1Otllpl3CabfuHuaEv95sQAEbOQnF8vQcBvcOfYnv7OKBSETKNgEAW4Xjd3+q8pM0uanD XeYW1YIjhIqGxLHGxpuyjYE8QDCAdXTNdkiTa+2sk6ez+btcw+4p/XbIRVmXY1eGgCY/9cNR DouEybJzi0tT8CoO4y5eCAyMbVSii3PQEDd7RS68Tf4KShIStYMu3KOakmpeOSF4Rz38Q6M4 w9W9RGakcu0Ys1Q2PSF8vsHiV5xu1k1A5KJcPJUsraGHrx2Y0PIkavHOhVspaC837C2B/cG5 cNo1lLP4lc13KQ2uO6AbkWBAdlNPJO6o7QdvkcPwOBAXfUVFtpUVTUHOUXHaofaueg+ncT+V FvVy4Pe45Jeh6seEu8MSdDR7qRWZZLYEOqfy6xWBoZkPFADlOAkn/A9jTJTpyZls4c8JDsb6 dMSFBv1lemVFCAZEZrEcfgFh20LSUM489ov1Zb4NIbzzhfPhH2h3AcfIUWiqbaUJHqfbQn2B agFTfpM/LQt48kb6Etn1HhRskA0TUbE89NFi7Tb/fiLlq49YpaQ636px8shK8j6id1tLlx86 1N1w9A352hYyPFrSPl7bIpevjbV456lRkoCxa0yVrIZ0rAqtbWsGahOxTgV83ZsYzB0snkT3 jYEoZsKfaMXy4i6+k+n0M6LjP62TfYLHkspwwdo91NoZzOyClYnsdluxTQCpRMrfDCgzjCdd GCF5Mu8qzUk9fxeOSKulJBapw7VkMC82v9fXvyCbtnFF2WeT8IwJEPNyzhKZTJ62uJLgxuv/ IoQQC4TxlYg5sQcVxLf3LaQOxgqcBffg3IadtcIcIHy0OZsxTUYW5lgcwrcZhXUFu0aCEHLx a7TPe4LKUy7vXrJK+jRXrBMVrOUZrYx7TdCiVhuRUit35D73rE9JizcnEsbxJ+3D/blUVJfp 0huhicSajEDkvX4oPjQflAs874xX6ATlKqVzLN1bSOUisq2Zvc8WBChBUFYj5Kk6vjlLBS5z uILaN8m7DBpHs2WACmbeTUpikbE098zi/YQX+29JYxMvxnUAarUtJEAtG7xEpfQN9cz8iGEX D4aB8/jjkWBQeNj9QWnphFpdths3Ot9K+TUEXcKOYZLdmKl9eX8WXojMLLi3VqxuNMPI1Jhk N/jlXoLP8MotBqLKzO4Ua9FPDLOZyiDloQQn6pux3tlojWY/k3ReGrWeBnZFgZt5JjENw8ie TdYnB3KJiPkOcQjvyQTVV+kKXbxHvVD+QaRwNwcZNr+qDfEpUdYHhqOqr0sJbnpG575ZLZ9J FAAFe2vq89j0hakSTZid+k6ri/rGpwSSOrreuHmySlO+b/wQCIJbTMO+upye5PtGlJ5wTnXR bovI3lClqqsNdAK2WeBekl2LJvpzIK9u8MADsp8DvLfHhG9D3imthbPCrDwd0ljpZ8tBBFkL FcnmojV2IHrOL/oxyvTg/33p3Ks26Q6vLqxrE/u/CGBtx1l+FpbSLScnMe0BV7VmC8tXd22n ZCPrDXUgDXkGa0Z70YK4KcQetzNm7ntDQJAQ1erEwTCnPI3PMVDbUsoAWrJKNWwn6Jw6wMIH iNMZiwQfem51FXEC/Ls51q1CPpqmmVlEXV/5PMb0NbRHoq+e+GfXxZLSOLfszhSiaOHrgpB9 jPCJOrRgQ6pzMcZDLevGl/dQsV1cpjSrYQeug3JEkXj+6QSoMAoI6zzLTM7PWW6y8aQB3HoN gh8tJ3Y+sgSAyqpSzQRis50qA+iBd2WC2QKvfNn5poe7nc13pJL5k2Es7KDmKcwT7kxVaQK8 TY3PMZH1aAOQePt+2cYP+ytCY5cwhFQmtan1YvFRs5GtWTx+HoIteBInMfDSytz63YhDz4xY SUMfRD5GITURpuIuVwbwp1zce0WGahQmp6XreQBqh9jdpS8rd411COr9yVgRD916lrw59asL 8t339vxNRw1Pj5JAaXld/YDsSZzAgmeNCanz8jPbvNFT0Dd3oMl2kdepsWczcqvmkg3WOCyD WDFCx30nX0wlMyXtJqHaBtxwSB79orluH1uz+hGfgHBmfPJ1Bc+MBQSGrwuek8yAJWXFlVm5 bR/7eV5e5Ah46xL7RB4Ii1osqO3zMIwc6/ZBqhSf6lHu5q3wkGSLyCu3kiIoKBGF3Plgvp9/ +aB3y6y6WTa5teBQtevhu/Ruo9QHpH1z4iz0VWLslWgb65FkeeFE5IUDlCx5Bd+MHSN+D9k8 vUdZxTuVmFIm5e0HP2MLS3ESh3XEOqaAkCq45ZNSz3tcjEtsE+fj5sLKg+fMzGBL98uACyKl WiUfje1w2bqRgptKUSLAJi3B5ojJ2bCgA+Arf6dPoxEj3IN9oP/FreGKyi1SvRWjysk0J/8m eGWcL4eADJRs6WH5OAER3n2aLBSChkPovLdDEhLTVGHIoEyR6pyugolROFGXwR0HlNeVSBJx Xu8geHNuYUWRogbkq79cSDeEnqtbFpOsr3stM9/R0H4h3EDoh/496x5NMzTJ7JsbR5+++Trm 2HSE3ol1RYx8cTMtoZkUuFyV81FS7IwniYaep+VOqmemvcP1G9OoSmlKcqykI9dFjrw+wvSJ HI1gL1q+r5IX3QhZuZ4yJsoTkf/dOUHMnICogX4jUuQJiaqUd6GajFo6XZlHcHPukimw5EUs XxG03YYo8z3HDIZTz4Ov7v+Ots8wZmuOSh2zOTGTD1NIWED7qjxCbW4shbTfSOn/PrYsT65+ 2bD+bH0PoQiBpC1hClQ6ViL+lbzqxOp1XdPYcWNOoENXSaxjxZnc6dbGeqDeAN0KymQG5K0w tY5xoagdcbEz9CK+8X7r5rZl75XgS0Ymb9aSVwb2XbIX4CFw+gKXmBojcCtpHe82zVhpbpv4 2v/cZxxdt70mwiLM4Q6X7+3AfLcC3DAyM+3VeWb7AC7YyHOGnA5K1gaUvcioR/iPXJmkXx85 3nZa1r1sXT6afRIPh9Ko3PaRIaBHQCNAzneBNgnMQlqGY1+T8k1R5tMmJCY/uFeQ4nkw/8Hk cbR/ze6I9/RecpCx0TWkkFmye22Wm0iAHOrpBvTNOqnJIJPmxE/0EBFh/7YiOrnzxPajnh9p 4z0KIpDxcheSsSpWPMZOKqoSYl06BBsey2IWa4QsM39OwncC6dUbDgemLpQhBEdBtOaWcalK iBlOEpZwcOyumlhnz4Ct4SLZuTKyD6l2c2gh7CDUWTadzq6EV5QDVZH/hAr3aCbEQp1eHKMI EYLw0a8CH9Y93IT9iQM9YNDb8+eDfy7N/Fk5uszwO9EpuIpwHUe5b6FCHTCKUTk4qABnN4U2 amE5yCPGM3c96JsMxLXAl3UCXpzACO1ApM/z4Hk5kBw9YPcIHtPEUsPdwbVPrxRy6hLKTsR/ LxQxHivXL8kuBNhvxssgFa3AJ6ixoHHrPccYUJaQDaohOstRMgqcZ4hmjFHXloSDGvVi1kmo BybZau+iJ4OKFVxv1xhRJQyc3Yx86kUSZXswWzVa/VKOW2NxPjEudwX73qxrtHBJ+Kfo6+yk N4JP4AkVlX7Y5rRIaH37BuYvLvVhlqcc44/eGODGqLKzxRWckUlKXp7lEZqfdnJOzj5zYyRw RCuYtpzPP9pGZx452Wqx0LUIlAfgIwK6d4qdx5VR3WqTmzMcUSTfMjAXJe36wSsBpuYCJmUV Bc7Xf8DW/LHjMvYEyZIMKbEBVecVlFQJhaMps2bA90RWVOiaL5q2ZeB/6bnL1qqkVLBmFtZE pdatB86gIvx08ICgj1aqImPz3x6RKIyI3e9vL/3Le4F29GexKAELJ6mHH/4cT2kA9nq+yXLE 7d3Oddg0WO0nZVmlhPzeHgsEB20+GjZrXIqNLSinSmUuXqgu/cuAQsYgsjkm3PGiEiqxzXxm njy6mU3pjrfPNCmmlRY3HHVv0aTGB0dGuuvjvGbyG2bgCWIqupQQxe0jBSWO2xzW1i6HEOXc 4yqfK2HNElW2/f02U7Rg7DJFFxgFByRSnByhsfUF6lYGYScU+LXlv/Sm8upXXqBx9Sb/WbMT kUblxaPWiNFJRx4VzNDrlVG5j1J+Dxho2nLZblHuFxLzNsdFTn6lwjOI9LWOTAxREKSnxOzD S6ZhSspNNwXby3fC22oDNTP0+9C+B/VBgDtUBxl4iAyEcxAPIa3s4XAvSWJ81lvcKTlTxdnL bNWq6h2f8MLcXbYy0p3WX8Gw1QVB0UVl6LPeoci+V7w7DQhZWbXJV4Abm3rL0u6cinU8i9bU yeljeT0F/1oXzJ3R/9+qN1eevyHlZgQACRGiaqRqtcY+cMusLiD/kkX6GUkL5llqjYaEAKO7 fM2Gz84vRTtjFcPoFVlfOdvV6E38qkGllJYqg0K4TEW/ppQF3rNKnTFd85bkr/MXPzOS8S+h U6jmq6LjgyacKpMWlSWeZeST9h48JR6kxx9Fyx373bKUzI/XcyA7JeibiLRbFG4wV4uq6Pjt lWbOWKTjJW3rn9gzyIT3NR3rO4TeZ8SJ/yQDaPVG/P/VSW6/WmlONf6JnHuGfl4hKNiVaVXz +iveS6UuOMjCCDbbYFdXXEUNG3r/WKUwG2J2hXnHdtMdIJcetlBhWcWY+/Tle05IVJ15sbi1 8/8IEp6Vp0FTHuYMeJiTKtmi1Rmk6rcffytXm73GjMMWOroiqc+acYMzT8wnwA88nL198AH8 w0ojpzd1iDhnaGub5VRXrjmow2dcpCvdxrMzL8tD7VtU0dZpUJijM+YcZmMWEVgfe+Jmn1bV KSgg/fIOUSggUcJOesdOqNjIcBOFcl5RnGAieXpryfozD9joKuF+qY/d2dtrB1qMa/IqikMa Lfn57wkRuvDJLDEnEmLvHRMNKQJoQbWY0DtMHQcel/KRGxivEsJrRdGSyejGc4txPju3v7/W ANigcSPTKWFpulVM5peRctXLmFGojJE6AcJPduKOwP5/p0dyRuvZmsseZNQzjnCEEn5Ff5Cq oU2dyC2uUzkK/0OPdVIUHemz4ci5P4tj50xAwEnN6ZXlDGZc1HVHPdLYO/Eh0t9yofKxMcbp upqbsb+g0cDtU0DzB9/5lSWu7P4k2bg62efWNT99XLiJDS1Xn8JRb4vARLk1oAZ3sBRQNMon gGE/ZDui5RZlutd2FpXwqz2RCBPCMCesvsDwgoNFeo9Za3bpclJBYxPGpjx+VyvN427TzNXl Ov5tqhNAPvdbK8W6YtDkWWRc0ZNfsk72sv/0qROyDIKJ9omUEB+nLFiXbWzb/9ItVQJFtUXA Ewnhc+590UkrOmlGSFOC20dxgliEpGpYeG/sIe7KMGYHZCg3qTTx7+dnawWeFexZrCckeOg1 Rj8LPHT609RQJTpyAwDH+dhZ1q6li1hErJvhg5/7RCz9ud2XLuKuJheMA25xMTgkS1m5VHqe +lftkrtBHjBwvk/FE59Nnj1Y+O15/QZlnbsSeLOuWXTuldjVY6BHy91qfCU5StjMtU8DkbVB sWQ2EXnz6Ocp/sT3PxrMjQr/FnvSLzRmr801KyYytbbODyspRNq9vS0Yi6jy3kSKoeHI1JZX FaDeYndbKN2SaLSKwjDbk7mleRnS6M8KhTR/tBdjGud9s6ZKXqG8H3GW6+eWgHTWTeLDEu2i zMnCLv50Xp2A+JY3rapEtMZKleeY3eaXfCa2BjTfWc/A0NhPiws8/0j+6kSJxaXvu9xUb57x ozJWdgQu3m313vM/ocXLHR1DFd2rzDwl40B/DCvHxRluEjbcVQ3450flaN2mV4U4t+0uD3n6 ++t5m1EXJyyt+5Vu1rjLH9CsNvmFTPbOVNY+GwRWkOzA0f9dPxRVabmHcgfzgPowTvBt8m2X 1NFkRLGN0FGi6LtHOOqpeA/nwRMDr3pz3SK6O/OOmA0Zb1uwEE1dYWgT5yhV0OmoJNNeUpDu Q9XW40TRweNeTHZju5XCDduf9qmNLNq7+a/WLR5o3VB7NkK7E9Gdmxf62LKMutXypsi+8KvC +AcdPbwZH0oC+ogbMfPNISWvwDatQEgtfblV8W+GxIq1zLCAeZmoRj94vbhZSO7hbQN2Lq4a WcrS6d+cDXVnuL7sCkidsBRF/c1Rl/PfD6CGN/uqKn0w+AGp+I0l/Uq/O4/cUHgchN5PNajw V6kl4+2lJuZ46NbBWcDkNvKtNEgKdY18f9z6ZKtQv6xZC8LtqKmz/bDIqh3GI5A4ME62dJcc TzPJEdhOr7XGJxp60u5KCTXMAstGue5NVLhyGYIXjEB/R3KUMUkPLOuVvDwa9kxoHVnsx5AZ OolG6GWDxUJGp6qtz924rGEoNXGlKkzLIRLZvzgEe0JC6t3/MZV0PsMzZc71dz9h+iDQc3P1 IPse9Zbw184gtGqhuZGge2zlts6JJCN6JcZsXy4jrpjSpjXbydV1iXUKsZT6tpBnLVu0s8C4 A4pYm3IlpdOsjFHvtXmolviijG3uYlJ2egNqoKdqxeGEvvSCHXl5iJ0LOni3iUvyRxmVHoKj 2TgDRJAgUpeyDN6z3ZLf8dbhDvbDMQJ64+UxFq+HRuRxSVOU7r95mL2d0WlcvdhANe3KItP5 3BrI8wozzQogixy/CMRf1UjuakvNp9Rl0XreLyKCgBPT670HzIwmQ4mPmJCfMNxTDHH32WVH SWipJhpz+3FkXpI5b51LC+KYeatfzkVW5/l4mH0djAGkzpb8rZHy+wDK5D9kcx83RxbtIK1H tPV14q1R2NK9L33m5oNCpV5osjSglUEL5EXA7Tx6mgbITVOhceHlvZxe243kfDFbSZxrBD/Y 8ZjBogq8+9CPNOtACEAdGTQJaVNb7CU2os5XP4I/Okjg9OUlHKYBTxTKyGlyNUv18rtYVDwt ro7wyEknPosZYjjBEuve+KVg9m3xQpDvjSnOP8QnEvSupCq341x2b7A9yMadw8pOUxUFuvBA x3om949Ie84691Z8i9h7m2lnpbrdpHLbglkdMsCUSrmqm0j4FE+tyt5bOB8eh6SjPfD0jECo EomXi0wiHhPY06SkLG/XhUEkH3ouIdchxxl3Zqk1+RMM6/3BYXXraNpAdrCf08YzCsOmjTHU fLxD7U8fk26+tSRIiqJlFE4cL11GTOB6FtkVzcBvE58eJj/GwLQ1mjrxuCKYAPKve7wRjVK2 /f1n8xtLIxp/Mmh7vq3tBNLa9ReoqkRkACBebHIYuDeqZ5GMI1apkfv11sEAR4g+gWhHFEkk D4zQPZDqRJtP3QsJ+TH/olnttQzYDnF/8YEU/af8crhhnzeU41LqGKHE0qPO/cwdukzh1h5X mZCuE/m5dRHsSYaNdxTUe1be+Q9KGGe1KRjZndHwDb8vlpritTzDKDa95F2ecONLAIQhsHYn Rq632LoapAmvwJE5BX40nJcDXH0D1T8mKZdmnqXVCRUIWps1Q0fTr7Qbb2uWN9OJtxM4DxDH KP+AZDfr6jBVsDgPv+iZHotN5vkN/Ym0l5BjvM2d6tHGZVDuqOtLLEfF8SeMBfVt+5Z7QanU AyPYkQDloNnB2SVxZU3cPqEMzL0n2ygaAQQaIBZ+ump68RKylMMU6X4bbj+eDY+VtyPuniOZ 9fmTakYZDAhLBcxnf+GyGcHqr9/ZUiDk07tQWW78gO04WTqBaFqoGSv8U+DgYfs+l+MVlLLa QyHCJezoWSjH5tbbq9aLkH0rG238NXT0FtIrqptcS3sqDxqkynQxoQf7ksl32H916w1VMWs/ i2HPQQNGTag06ikTj3abM8i9sw6Vkh2coukaWP+N81riBEyxW0lEeugMbqUPobdTTsirL9jT 0E7qlGpNpIWiWIwuYA8ZhAFsufofvtEf0kVFr7P8hvw9uN/JxHyquMn7mUD5kdKG8vAJROuS 6TViXCSTQov4UHzXztuUudnsRy8J6NexBS4VzrFrxxsZRBgjUJun26HYZO0WfptJoyynE8UG sscAeqRl+Ts4+cUnb1/IpyOV+TdLGxVbPdIS3IuLVJGQOw1BH/uaO51tFMNWHOnLDmWVXirH Z+Va2O728pA8W5hD0wleE14QN6HlLBlWNUhwh+77+Kr2xYgoIrU0i5cstdjYuCy01xmIMxEA d3YzUf890XZ+noFvsyubM+w0qCD88IBNSWNtMobcE5+rlyZKXrrMNstg0fpxayJkZ+pKERTr AH2NNWy/XObHgNh+6/NBDUA8tzBkrHue9tAtXos8cv9quPxI6Nyf52l7kVnVTlgbOF6nBS1Z L3gnzywqN5KiOenF/bGeSVI24rXK0115zfKgs8MyDPuQuZLqegrFZJjydr79qNWAcP/zBGO+ 4uM+pcd4eQuDbYz7GBjIaIQAyW29SBnp3ExDG8ILetdtbWVahhEtHCpNE0/RuEQuOeKABkBC 2pT6+itRpX4L1dOb2WzAV902HPaFa5D8a0SuseyYtFYLgTg5pyYw8rcLpqf5eISCX8HwDq72 3C+MffMHf24LAF97Jj4fwUkv6OpJZAFawFm2qv8Ap1wBEWB0oZ8UgovyESoIZACroAWI5i+x 7N9j/Zvap83A70LHOz46vI5AwH3pmhLy4c2qy7sZ4xsxvXAFx7BVKdxML7aTNB+nscuW6gzn TG99OdmxmB0WrqeEOpT2h/KlJWSlwDTtQdSDxAr2Ei3Mjo7uthsa0KdcX9QOOA0SO3x/sQ86 7nahxwj5NO5FhXIILIvaDBoWTJdNqkI6t0VCQw0uXjFk7u5CjHOmuG0BAZlQXc8Bb0uAas84 sVIKZ+JCk52K0zzUn8Ng561XLSG4j/SXeD4OYh2Hpb/Thq78QVaSitSFN6tMOL2dJ3BDj3u2 eCESeV8Y/IDaCMjjYBU5UL6w4BB5SvYv0rt4e6QWAH8BF1lemzfzj6SmzNMXueF4893H7t78 38sGM38yXNkKcLJ4R8pP2r36WG8dbX432cXKaqh/BLTOnA1SMChQ4oJAxahyqng9F/eWiPh/ RO2lPfnDJXuIXz9kDVpra/+d95C7R12RvhVLca6Q9ssCD4yVTogwzNAaRUmt6cjhz2wc5W+N 5jvpYZULJshVuTZdCGpO4HUEBT+bHQq1KU41CxpDyP6bhlLckBEmHJG/ycaWgHNlUoiHB4hq 7xdZDO3OCGnA/e2deE6ibXCwP7qLbBU0ilDQNq6E+VuSltttExGi57HL0PUorBN7NvVRm/vU xrP3+XbteB4QmzFxQZiIKmKfJovNwmgweK9FHA0mv+BMCBcu1DrKguCZQkJ5+Zo2O/T40Ntc STigV5Cv2bbGjhnCSkv+c9fDaY3Pvo7Y+1cjTFfyilSSr4KhWbnoyXPn05ISMmoetGab1PfB NUC4dpZW74SCJrYcvkrjvj4UYqrlhRovSEkE9TeLHkMkyeqVzTMlQClxgnoFWiPWqkHPwEK+ C/LxKgrYDe/Tm35eTuqfobrU4euUVo6pugrwNWHW9Zp6wWZGwL0oGSOncrPdGyG9mT467HA9 mNYTNcKtW4QykyUiV7OKiFFvHxnoM5/rq2R+aAzTGwZhgmeyIkGTVDEXRyInXaEU8Wr2CHcz OpYF/s1vvN4j6zwsR43ije1jVQ2cIItCAyyX4bbFIGo1FJGUb5uFEZFxTHMhLHDBbIj3gwBm IJuapbYOWLhzg/wJU4NHhln6KLWx7RFFwwJIbLbBX7Z32uMIcetSJpeusyuilSo7ETkaFVUJ A5ARFj4Mm202fn/jQ+pFm4YzaAohUw2dq2oPs+g4Y6Unmn1ikxPSjzXXQDGC4g3RXnOZ+pyK JcYORltdn60WTjyjMzX0XABjKVrQlMBnKcyJF7hV7DzA/aon8OV/CJ93u4Lew1W58FORt49H uu9PkFNazdR8C5lMZ6j3q1JRkwGz1K0tuXomaPT1OiyYjOlDLcXOkLbfnykmdIglYnmzg5uS ccYu6ZFP8xIVl7a1q7SlEoIoJQ+zKeR6SbG9mkab7fyUDpGO05USDAlzTyg6f5yVvW4A8gZL SYFf02aPe7itMhB00T9JDLD1Y+4FOPAQrxaKXKI76b/5emXhrKiXbZToDDGNlAa1UbKh3pcl 70OjvNYlCwqCL96isH1TJMhCNlgrh7wqncON64rTNJ17MHJlU/gPWby4gwqwgBQ3OYW1HNo6 zKYw5kIbTtmzZHbnxAyGEzdikl7A3DSjjGhwCIqAJqYP4XVrgVHILZEVne+K1Tm0J/m+JWia IVDg7eMH1EstLbExzKxxYPbdkqBgjaRHO1mzxWHs7F7VMZDPcXxUrL9LseeOlkOBeOuSkz1d GafbE588Ts00zgkolKhKAeYYxnvZHNAUm60vUJngxCE32hhcijySM91mXCF8b58moOF/9Kej gXsFHLqkmtjie2rDLmgoo6Nx664voImu7NMSip1NZ5j64eMRTW15ONl0nEuSe6b1DIZZwg++ 9DRWBBJafGnFRtOU7q8VAzUSbFVlRCT4yG7cqJIle4ut1FMPa+UbM8IiQdq0tkFnVPrsRQ6w eTXbHmzPGzbC69WZWP/8ybm3mDqoo5j8cTHQtBSGbANYWdnsVvu/VURKLgoG2DSw4TMgiA+A 5Ai0YusK33dnJRIasUlajEvUys9MF2/RAqEb7+G2CcTsxQStf3vUt5uZBMuQIaaqDTcSoe+b 8Evc9wHAJ1EDkHu/wg0+phMAJhasCmj0dXafaebGbWehA+uA70ywFN3m2NpCJxxyJxbR8LP8 8EhJqve73ajgVXqt7RMSAUoEZcQG7vDbOvTOqOxj4CQb1uEK9UJguFFDIOUXnwk9NUbVpmCv DyGxOjWyZCv+CSdaULUyq/oG/SPKHT7AzFyOWAYDzlhXp4h2wpQWS71td8ONLq3Y+CScbvRg kpWe1x38dDWNHuE9/tWx1kJ0nEo0Kw0r5pWNm3LDjWA9sGf/sqX+AWRhzxsiHa/wBRVtKPee JyvAkOPsLo4/JL4LivhV75dA8DnJhYUGn0+DlWKgdI1rbcGbsdfYzg3x2sN4WBmBgWMRDiOa hysyHGIRbwGVFuFb4poM8Cyyov2U8tTAPtB6eBt0Sfzg1B2GWym4/Vtu7s2oDF8dQCd5DxO4 0Ex1N+ojufm3xoTIJeU/LYoKwFc0L0v0B4LYcNNkjEBG6PrH/QgB3onuB394EY3dgqG4yHOL 9zHE1fS7wE8iOFHRMk1DRFAcvqcYs8/PsM+AtkRuX+pV/Vwxq0U3BAnBIKUUxENYuV0sgRTQ QmGcc1SuHWuGLhhp4z30ZJNI8BzlDNxAuAS8ZvCwF+c+MiJSvl67w7ZcNOrATUb06ELylzmn dnQw83eN7K3xqnlf9vCZavJB7hOGy2q8sLDAeIHs15eqO5cLFLG1JpDBOH0QXMcBq0g1kjNb Pbna0tpTwXFyw6UUVrO78gIdq9mZK4kB5is/rFTxH6u5fq3gJawFmSR2i1mfJkTlQadX1xHG Wp33XtzCKSm/vXzjORbruYS+w2z6ht8TsR0hYWW/calKh8IaLyrNaKrDBta+WMwHEjNKfOYW MM+MJiSCsOS0wjr0SRIEBlQaJRgGENi0kGwPbktauoifrC4xS3Y10uv1Owz7uqD0j3iycrC+ d5yUGhV+O+T7rU+Bkk7nC8Kq+olHbGGBCqN1crd4iV8mg6Q2XW9+gblwbKh9AwjsTXznbNB9 uEc5MdSILpVNbMjPxhTCqyFzcCV6YfnlFLX+OqohK7Nm/dks0o7urYDDNTHVHSrwff9weJUB 6QE9dTq4ykjshNnvHH7sV9bZCvPZm8/pB00xlqyKIqsyoPmbrjeItwsgNdj0+RRud9RmzkiF XSa9z6t9HEM0kRH1hIF7BE5hKg1JkTocy2qzfOI/1HAaPG1JvxT2gmjUoTm83wUQ/rQDpBo4 eCimU7OUgcR5UI30qsu6EBzY/RM5+d2d6a3JgQ7HBCCZaP9Xba5XmcKSO7CovhTy5/9CI3bO nqZrgH7R08Y0NUkFZm9393NhkxXhDTrVJkFfUJMVjgnBSChoApDiBVs4bR4e+KnMtxN3u1GV UcSh5vAFCB3UHz2R2apsTv3E92ohyY5O/e1NUQwX0rtifBJZoy7ffpQueNOKYVzlZlh7R5se h1Fk4iMjlewHPMqtktD/ZFvTtpzcGQS9W8I5m7n/HC8sYwyNXC9H85WB1NRfzdT0MFerruIl 4Mtoo/grdMGJ+C+8xPi8z+ZC+x6VN2iALKd8m0xzhJFFqmilDh1tIMWIA5i1JvSn3OMTA9ys MUCl/bGYb2QxWio+0VssysVG38uqvrUCCqMqJZ5EYq3SVeWDhhqwjq21u744X8lbV6BL7dA4 hJtLMG2cQMi6AFS4+x8tE/hWSY0sMgCEAVs/gTNdxuYrX/VeWs0xDfEtPC6JnL3l0p1Sdsz5 LtlblVsQU0iP+GSed+JMEAroC4/5PWAjgS0Ts+TbIaGq0Nx+to6KPYrjeSwKisW4So2th5yG Cl5bCcgYyrLzX45RZntarLGE5l231mH8S4cvlmdO+Avutw8+o/YWLUlYzOZdehWUGtT8pIKj e2xACtH900D9qgOXN51YTvQk5gA0DnySmZuEDarLsM09Nt/Sa1qhyMlDlxOfEBj+3iblMdGY 00hQ1yYPzCEFPm9gVA6m/npOeeokLcjXD5ZLEN+Kpeghj7XkEpQ39JgD8AVk8SRZy2LdzNlb sAZVZR4IWIMrAVxtkxqPzVojX29rhdQXu3vEKTJBrZxzocRMAFW1/Njggj24DikV9mTX2mvk mK8aOg4VyQEUHT4WTYGMEyITihxXEexZedepRPnhf16ajmQfbDHNAwvHfHfeuzxsLs7mzrpl XyS+KdrYqscWQ0KnBVBADZkUaVlBd+tIZV0yL3khohFfeGbMkIUf6tumRVs2AL8nenkDe9hZ e594144u9tFSXJsp9QBap6UUK/QQYDY80ZPtTIk7q4ovqJWL3sQqibIdPhiFvlgvuIfsHQ3T IA5rdRveJhXsj05nd8m5m6YDOek66mpDBdHP3KSomOY23jl9UVseJw4ZkMDPO6/iQrK21Xgq CVezMNrHwafVQaAwyd7cKa3hXyG6UN9PthxguoY0K7D7uexZop33Pt78uq1QOdHGqAqSAUuE 0Ul3A+Ms7dbo7s74b+Xoxh1P0B1kpDipLZEf/4lbu7d9YzGzhSCaGRQcXrNqLVgiHYFs37z4 AsGRWbgSDwFAXB97wB3huFY7zgYDT5nspVrxhWgOdU5Le6QYNQOK+oTSEIx54CuuOSiA7GLH g6fn0SpTbF4HQC8iDM0ygwPM9BoDKOZ8NUPTHok7Ruazsqj3ERxxJkBqCI6SxofgkN7uEhlY SIoEeOWlpTQSqO2ttx/wOLuhU7zI2hyUOouKRm/km+zIS7OrK6SBBrTFfapBAdEEz4GttU+q IiGsy1FvFQ9yl57LBfFvm/e77D5BqUMuiVyAo884SfeVacOEKwVq7e5wsL2WzRTrfNUFAKuo HsWKJTv68vIcUbbcDc5zrGU2B2pSUIsU00Huf1c8hnlPKRhOdavH8n09MnztFHU09MlxkUMv vTXypdHh7W7ToHvGBX3yD4ksrawTFOWuAkMnLdISCeMn/GI8fKxjxCaVI+bxczXJjfl2d6ML 1m2DHRvq3CdX4ntUhj3YkLjWqWgFr/Ai1nwVxcVFNKN4M8zV3f+Q3r2xyIXOLy1p7ZUUAodq THfbMGmnYglt0/zpyDOxDG39eOeota5LspNwf5gI/zLf91gXgDOXxmvFsUG2HiX3p6imX7h4 H1LtmDwhmvF+mHFVVQG5ak743Vw0Rt5KhLudwely+OMYIeM8shQpT3SVYf4grjHfM014BVs1 GE0+lU2plI137xGC68ww9EqI5vUZ0PTzMe9reP1k+gK498nxVbssEYChVDjGErF0qutEMOoD fF0ZaDuRBK+yd1lndmFiswQoAEclfeyKW1ICqVhZ32sWTEMqAZrONmAzf2t6vaqV0LHtxyCw GDo0GH754cmEl/aiM2XxkHeJM6RgDYOIO2FO3O5nJZhM1Knn4ELklFMHH/Z0WG8mQ4/P+DY6 XR59BaRxkdhsbS03fUu+WQsDVe5nKg7vH8U2ImMC0U5dPy5s3WsxvSAm7b0FnFF4C7Fkqj1A MCWKzfJaoFNutTmD9yr0hOXfEzC+FsB5kF3au+KcGWXAYQpck0UsvzI62HatDL5XZ4Kd9DgR wcNpk/CbSrXhO/vTldNe+uIDnMYwkjwQXa9xI6hm+G3Da//tRiI6KUOVDuCR2HoNPrDbDKPL qWNPPsHMzRndqX2vWimkKjwL6iksNj0R3yYjl4kZKHbanK6e5JCk1rgK6BgFjTzAv6k17esK Xw0dI6L+sTgeiLA9a7jMbdU/U9FAsaXtef8vKTsLrnAbMYSiabzlxtA5YnyTRYIYcW/drnnj d9iVYV9vTfRtHdrC9qqbF3tG3XvX29gP0IsnMnsx/fJvofhpcgbVMc4woFjEtWOLMtUIXg+1 ZZc7E9aTLkXW6UHOOi/AuYw66JK5umXHz6m3N+L6kLdPIXOXY4NqocXPVNDRPL6dCnDfWgvn JBCnlJMMyJ0mLQtiHtTQOk0/j6qvqZcgLzlAGMrUYBCitKuq/G/lxLYnbH3EVzkDLPfrofew ghDu4Li6581uQJ7/leD6xk93/JtEQTUh2h9mdRKvJ/0JwionEO/FwXReuRWGgyLcD7tN1clo ltm4KAYlc8w2ItZ/nhGom47LZGVP5MnFJ7wTN+g8XjcUrVttykH7XOc/x63d65UYiS0ZYbTb joPVz8uEfIlOl5MM/SsW8eRf6m+DFPX0e/NZXfevtD7rtnDOdcEmCxFb44a2FhINqXRRmH0Y EyOXobWmegyjhs2qiC0DsRWr7m+DxmSmswHvqVL7ki9N2kgPUWdGBXPEqqeGrgyYEpkIpz7h wjGgupxABm5UNe8DB4kEwaRvzLvf/v1EpSXlDtcJgLTiQtnVAR3+TnIiDQRJXlaYpjbMZsxQ LI/nqY5+6kPhZxl/6OO9S3uBWybOAzsm5macra58gAYh29pI+lGFesMnL8g/K59mrKghN0/R jvohFaUYquXwsrUkfGMmDjISOH7jumIejpln+N4a26nBfNxzhjvREtz32uDVMBiegkX3ApU1 saMy5apeeAnXFW4TeHJWYesavn9lcCnr9w4aCE2qcxvY1hbHfxewNtM0fJvetAsZWMJXgyY6 8hUB9wEE+tvQhMfIU1t5pkOxqT1OzGj8cYsOohSbObbJEnEMaWV9equim7TQKDw6LV0sG5iJ aEpADDD6GqsRpq+PQkTbD9vQDqd7bb1vwA6wasHpa2vJSZVm89EymAcxmK5PeLWYJTIUALFp gfA1ZCE7SBSHy4czmV8pt7DDX6I4duKGliGTwQap3J7Q5rTJ7xHOLtU5MHCIT85MePr0Wsqn EOER8PsFNuwfuFYnc3QVuPmHmMmfGwD49RHAKrn25VTkaGzwl13mP19DBoTujt4coC2Egmh0 2dh2/dr0yscC5NTEeGPVPLaogyxCA+rOn/jSkkc+aCce6oIhFbAab4jU+WtQR9QRhHCS+dca tBlovjvjlYTHl5cNPRbfafqm3zMfi0LX1eNwLP9oUxe7tI/3HbcyZU4gFLV4ovt0JLYxOpwe pF3BuEUp6+ce0ZOlinvT1OBRLPa4AtqvpNyQdj4BUC9rGDKsbpfpD1sZ+7RpBl1+rfXsg0IR +j37NA/CGMl+ktw5KRCKvGBFBr4rIuEi3/DPKwo8rjUh5gQfICUMS66IZX1fv4jJvVudfNRf 71JsX9PcYe3sKN1vpsGmbgHexUCxeW8SRXGbHMpqKzu7TRcjeqI/2a1Ji/wSBjzJwL055oga kogaCki9sEM9SJDw2wlRDtLVmlH4TxF38QkRoYpeuynS04QXlSRheZa9XvXtZHdkLXOQ3e5Y QzOnQXvALh4aH1L/70UUpdFFNjngUOCEvf5eJEQjSpj+VSR5AKnREa+n3pMgs9GOgUD23QO1 6QMYp6I+Kt80tl68hSVGV8ceIVaiPL1UQMLuUkuILLdLY5XwvjvbHLTsMuINrGQCvs5Pb+fj ioAuGisT/Yue7veytjFHmSy5Ln84O6iL7cn9o6j1jZCnGt/ZHgWmkaaWpbIIl1pmk7wMohTd sV6UQSc7PQGTQVBZdz6VkMMsvePNDy226yHAtqsVZW0Q8n1Gs6oO26zXyBA/iEVOBRDYpp56 wl5HWbOJaEfXH+a8++6y+XXxWXZOoYK6AQto+kfDL0y2DxjRrwQcMT9tZOTXaYzHsesJ6d4l pDCEnTzrLpA/vLH+mfjWdf89kUdde8h/4bTJnc7Zbt5i9Py7Cx1xY5/0+bdO37811h60wrZR BSqVEwavD8loTdi+oddgeb87tDFJvacaIYIa8UMnqpOK2y+zyXDdsLM/tTBg/3G5Z17pPMAy RVQbil8J7gzlmvSRFOS6bb8Recl3eP8dPSoUz1UFkN+gCZIHvpon2f0ZPDPX7n5PEuREZtSZ rBxsvoJv4nse2vMwakixuUqaMwe0m9f+GyrvwXViFEDyyOPRUTC2aKewKLKMSmoUAMnGvMQ6 h6W5pTIenf4TV4doc/KA4+l4ziM3mybzXcbyVDXCAAnfxI4qmd/o6kMrG+t+7v91oXR7vPJE WO1qLpAPNrR/TtDK+XvDwKEfaDtxdmN/K0ziaBFq3W0tmiSPQUxRbJa++GfljA6LFq1/Nb/6 B6vy+rSfg+e4DQRr6uuRre/Ym/GcPs/CsB9Dh9IjSY/Wo7r8CBpWQc5maXrYUb0qO6cpPP1p 2ckmu3e3XqaTg3+Rr3z+gH6ZzAhsfhqCw8sdmIfZZAYOp4vVQpaDF3ibaV65SOHF5PG5JBSm Ads9vZmY4D2kVD4XLt2XokOxbYkgyhQdemFmDuJ5yANAGgeknEagrt4Ih7BoszDCYn1Re8F4 7VU2VirNJJYYJMQpf84hG3fjVUhDawFKVnt6LbDYFR2pyDMdUsqyQFoO/i6sDOMtu+rnV9uU hac9Q+9VVrBDNj/IflKhWD+nRU6MKGw7iaCOcN57xn+quBBL0dCLoqHRRA+QN8UQkDIc/VEI vmHRoAmcdCxsPkr+6UmqA+1720xSzDbUJYKql4auEMnLL0J2g1FM09uFBkjpPSJ6L6vMQ1gj tBKAUKudOEDi1xPMmxQ+fL13mfWKhy2cezodWIdEm51HJctwj+fg6JZDMGv8BrM8MgtjQeDq ust6YB391r0o96QKqWDQ1B+b4O6BCbbWNXCHqug6wsj+OU5lWJ92w4/+NUdnTYnjs4bXf0tT jiA4gqg9OYqAKomK3/7VA4XEXQS3Orirya+atmRdzFBf70rgoNoeei26+kR353w1pWJUCa5Y 74HPv9xdQRn46exQYn0vPnQ+AswPPCGr9PgxZ+RskeRIWsDwSOnOeAR1cQ3CCsr6nLOJvJsf fGIjmxCIAyLJ7pqFg4wDeZLxoNM8v5APcmIOAdWamzdYTmFxNocBqIhizZikOPwRjJbxx7mt L/EJcWuV74SwpW2OhUQOLYbVGJgqEHN3oUmAYXixyjWHTY/H3nrrzyYN+bCOkuEE/lUadhRc cJVqjg197Rn1slfOBPrutO28XbZX34Ho5ybz80uha4dSmtmk998Q7hB/dtEXVSj2/E2GGmNM 9gDlcvKHket3OgGuKBLG2bBt5sAnToyI2ViV7RGGkssPi2rEEyqrx8swCypuxvZL5xRHlZJ0 fsbu5GPxmRUkZsqqxjaug793cmxeNITB9Nk4IEYfjCQFOTb+/+GQxRHmlkz2TQE6OiTucRfV Wzu5HygGaB7idPSJWvMOGI3bkQBbK6NOg8KTMCjhlxE9XTtPx0w4q9Kio7o5jjldLxKRoxFe 4wFiWSwPGZ5WpJlYvi6m5hR3iVo1dwqQtwMyoq3IeiktZCtke6AQUf3QVJyjqHfGEu/UqHfF OFkiTe5p4Esncd4c37/2wjCtEdPUcIaSs52OM+oG6LGMyrMtOr9HSNX25Va1kF9Xu3l/OR+w Xrzvpbey6KKFg3RV0fj95sbfp7nH9RZqFAptmZ9KgihvRr5NadZgRBhG4Vwya298mDVKCroi sPQHKuA2sgUgNdIZTdO4PzI3DICVH5AEndFOIGP9md74Al+/Xp0OMpUZzZ1vqlu3eXPQKKB2 5Y5gF779CefrdsRp7NvsH9Lf+IpEr9swOBsgyddWGFo17jE5nwUR+UqE9qPFnAYTP0XDXay1 7sWImfJKw5kXOCGVE52m0xYBKAIdDEFvHubpxdPnI1qrts+YqAhWMBPLJGNAHEZVVGpqNusW kvJhouZog6L6vBWl9sMWnpt6F0nzW4xRXXxyUf/YCe80IgEqwWr3y4dOt8eHIxTW0CVcGN/y 6T6FvcicJh2kwzKc7P3mzoSuPO4blXhKUzyDjCKGvA9kbkt4egjZakG45M5NQA6iooCwMDfP rCx5rzIVpuZ9xHxNMsktG2VYOuSjtd58g64zWtxr/36eJQcanGyLxPn+i/2JB9aJ9nxZrFSv MdJO8XeNwEHoLx2Cj3B8N9qHlJlpcHwTuTV4+peX41zBqvclIWXsoQOcQuQ/EiIdWhKcK1wI ZF96+3iGF8PD6t08wfz4r8tN7/Y6gXdTKMIKO+kM2y/vcxUUoG/XQ2lvJp4//UqHsTZ8FpO1 RgIxBsWI4/RsfRTB0Se9bsmZjQzzcxDvSV9FAIdtdNLi6x5zUHfiTSpAmET703CGqn4gnPNJ eJD1hps4O8X9i1KPdXoYbuC9e04DYh0Mx2h0lyCCcBLpSi8AuN4qE6HQ/MyBnin8Kk8vy1wP 5GcnGxbnHPTHZT0UQEc9PppaWTKUoQU2Pitxb5joe5pr0XMsadn58n7DxsAMxzsILwjw7/tv xFoq32qMwJNITWlX0jwkBMLTFh32Pt2sFbQWYR0r5VOnIACJpMN0QE8PhSC5Gs+eDpTQ+veW F1Oo8h6LzjOR5gpn7cOCM5iTGIBk/EU/3F6WlMpvTX5ywclmFXY/EWlbOEuLC75URkFCpt8O ySjLOg8Lx7wjx6OAOR8PEvyTGh6GhG55zDzXZAJUMgh8EkxZi2qKDtskHKLNKHvFRALE1rx1 KUuJtcK3hUVGl1eNSDNiayA4dTUdJHN2XbPOdnvinLMb3LpTLdOJ9S88AGGwlc+GR6KpFf10 HfGrKvsBjhqt8AbLPB+svuo5Kz3UDSjOPVWSYxrI58Y2Y0lbie7BP892j6X2WulJcA55C8jn GXuCdAr9K5gBXG2pJ89tdUd8FYjKHR96ccJXSLGiMFS5C0tROpuA8kk0nti834frDuRgBFU+ WpJF2TZPmNJ3hp2Sy2CFbD7OnTyXue/j90riJfyF6XcAsk5rjQKxKjiM58x0sLjWI1vn+24h ZwoaQoBW6tv8qLyVn9cUB44Jb4qAzqCr3VyZ6llsO2UibS37ss8dxkvtSXVUVjIOHAucHpCe WZE5eURcXCLa2+iq/31cFsQDwynMkV/EPVkMRbtJcDIrKxu+DKl8EiQuI/xs9FCwbbUyODEx V5xC1fF9seYadnAZd7p6E9qyvgoisZJhhKyV3rZlUSEV4XsL6ZsIBSEKYrSrLYV8+sv5A0jR 3Ukv8yoJkmybuK4rsNpcGoiXAZquHMN0hIXT6c7/l/ZpwV5gq4OOSb4XN7vPaMSm+4SvSRm7 WzNz8JuRNQHsdDNcgl4GZDuLK+KdYvd/io/ryEahTin6xZDebG2fJEkyMVClCNxZ0X5ByWdw VrXad09DTa1LVrn5YTeyFtZisUhSDCjRWDydAHJoLd+pvfI6QaWyG7SzroJNqK9NIddUMySF 2u3RkLJ5uy7iETwT3lKBGTj1UeVp2YbrXdUBG6DuGWwd4tI+DyxsGI/psaDY9gzaRkdSe96n KuBAuQSot8sm2fiaAQLGWNUb+u9Rxdce3xQUBSO/CUYRw4Mx0CWE28AzLKbiwqg9ZgUb2sOr UsoJjrmR7pr2nD2wUlKB+nrHN0CamraSNM9F84Q1up2/rEpFJK79FiziYjzuK4fSZNDeXDQO S4AQc//oqlFwit/p67ulciDwUus0cZ5jnEpw3VVugnDpCxrjYGT+4rx5lQxEoDRQXyGDDskz lqQG3c6+1Q6dgDDo6ixyGrNxBYaoJ9hqDUKzaYhWBMUhVREqtUe69nxmrWYMiTVfy8I5E87H jWXpfD6u7yRDdJxWO0W+CytVPWqvp3DqqWq2gTdlyBtjnZzzM29hisVJa8IjOoCXIqPqRrUz wVMBILyqZ78TI7xhEn8vFPZbDIvqSiJ1Sg+OIYn09tay7KOAD+sAn8l15kdM8Gl8AcPChS+N 6Tx71Z9vCxnFKyh3wSVhhHgIyenUA21sL8urB6g2iZZXwo5/wEwbKhDHx0dHws1LC2zqAdv0 r3q0IfkkihPpNkdDPGFUiRUoVLQfu/y5/c9pBavwmpgR+pNCBryGiv1NvwRjLNNUuJUUOLhU VBcPLHMt72Nw3OTCH1mWT1dj2zM8O6RRYUqO7kTjfymiuTE6HFzI7qPDwqh/iJAPLdG1UyRp 2NJK/aG02kI7XQCoCrMaX9jVmIjIbIFgeD1T9miLjbq47uBiEVeKF5d5IC5/tc8XbZfCw/+S 0+hiX4JbG4Qsxn/pmeQVo59U5dt7m4mgC4GRfVpBRgJsX1bJdFnfCQXjYELSuZakLxr/jAz3 bK46LPwuQ/R/iZuBtOr6qSrb6p4YZEvh5NX6nL+FDASsho98YbjUBh79LU0+S7Exc/ZlRcv3 WrPM8tA1e+JHLH7+CuBd8zlOwI2scXZrQzuWR4o7TexARVIwS3mlo5/u46AWBWCzu1zNz8ct UHjTh9bRkMH+JrF1pxSepLn3+kEy+25JgqqOgm3KrrjyO9pcCzk3t3JWha6hpm0GjqA+vQXC RUTeufll8St3FtEeE+R2yDLWTyt+0RPF25T5uTdjBUL3xR5i1htbwzKQD5SxciAQg2XL632G d7DlaBeGTDwNTwLAKbqRL34c15+aMqTkU812o3vgYITMEEBQIAiFN379mnmSHdgWgDGnITKo XeDFwZHXASPbB/fID+fi10MAVOMsgkJFBiaxLFBxFj8HbdnuylIzc42OwTieMZDz0JXtZM7s nLqwKabsFSwHIVk998sFvgWhrWJc8TJUWNUuMf/BsqFYxsufAoBTEn4aU2vKNqrNtMuK00Cj R0CZ3ZrDmdvdxYxbrqogUNOa9OqjXbxJJSBLcbYfGlzPOvYqz/SvU+njw/Zp2jSV0imj+uV7 H19bdu4dh15+17ETYc/vd/h7a5B7KwdtMIcdVGrarlidr1zk5JkbTO1e6RDOgHZlySPiBP8O 8cn/kC3THUx+ajbZeNv3N+Hjuoz/I0vo+fCTaSTw5mWeGJ46Jzz+O2Gw7lk9aPRn/If2Yso0 d0gfIDFb46Eq/lgQgB4H/+0IewqaOtdQpBRKxDkRr8iuXd3M5QXP4VlWKy1PzLxakukOWADS WK1g4GmciZFE8Yt2B0GBepwEZf57Yd7ynwkXPm2mVAppdyrHM6D67wy0e19PqJ6M5lJDp0I8 G+F5shBSn3irda2igiwyfT/QcSRRvrxHYL/gVpK03Ul0l76qxTAyT6XeU1IrzbJ0m0ERQ9Ex SYMQ2Htf2X+WLGFG+gYcaA+vQdoVh1BOIk2vm9bzxgDv7FkYEz8Mv1drVWFHq/8+KzPobAIC ZUsXHReZtVeguMGIuffIWQu5XxR0U9hYU33vKTsa07ZHKwsZT+2yFjERGd5I6uRlvmrPLM4G 786phzG7GPHBLsgUCoVSFZd83TkiQb8V4Pa/K6KlRlUsql+ijyrq2gj7bhu6yu/5df7bfX5j cZTKomKpu5pis9XpwfED5y4jg46vOq5IiqZOhMdlHXK5LXShbWjr8HcIgjRx5DSo5dB/J+NS ZMmoiJLuyrQ98DxHPbrP81kSB7oUUSYfqEd74Dk3kZ926UeSvq8aIqsfD5qR3Fbs5ehSPhsz n3U9vwhWr+VO3AwLGFrFl+Z11JhiPe8CWPiNHdw3Jfl9eaLPAucnKOw7hSqt+y5RQ9P5R0qZ 3Az8yd2BGPwDrd8AwTlpYfsPfZEU9o7QwaaltrIKSTOe5YzgEvSseioUXZCMdKdWd5I+ahrE VvuIE/7/bY7+HW1OXKDvJwS9AUCQsBG5o0RxIP5ia/270ge0f6qGA/4eBN838Vq/DvzchhT1 2Fl2efyTSsXTvMIZCPfTMRF0VXKxKkQgJHAL6inMk5A/0EUDBLKgcvVERwTaO0jaQPrljTwU g+GA6PyAf9wF+FtP8HsV8j/41BYklbuiAgL81w2kCP7LqxWLq6mA9N78Uj/ygCzaGnadE74L qG9l4nIduoYLzkRJVMs5P1Mhgz7U6dNV6Vr0KIaa3MF4URsNtnXckzxi2ZDGD8oEdhCZQz8P dzslT/S6qLc8w/uKmZWCTPGNRf0E6zufmx5LGEIGRDgz80N0ZID964bzc/QZ1PWZ0Man+3hU 6ZRNGBqdAaXgDgNIZdbXQbW0NMavx9UfIwk4amHHxYOje1rXUSS9bnlo3lK1v9LXu1RMF1Rg Sa5RWwntUHBFwwvxqXkTsQYUrs+LH90mU4cq6uJB8fTaLIAR3zEfP3MMJSA57oE36VJoMAxs 3l982IYwK8EGrG6laC7gDci8pa/Z3Cv8wLpExk9kAu3t3zQuMuvPNQ1UZA8xud57Y+bfwR4q uwzxbdqOI66KCzy3hWFtM1n3tjYZJbc7QcvhQGxH5hYvdYh4+YT+XkUW0AJgAfxYQyuMgB+H WqzkAWd4dvt/4/WZmDfAHldspcAax913kxn/xmybLW3jkReTS6t3nByHV4x4tftxHbqRj7r+ Q9A7aQZNPPA9MpTUUkghVRxirGnc5Mpbl2VRZgsD+3OlO12kMJSSmx8uXJJa5E/8XvZKRrAu DTkyPKtQELr4K7fQ436A+R/FV9hb5Ea5xaCsY7NOxDxdy+jUqv/LNrGvdkoLgg20uAyqD4EQ bVseaR8ScKbSmigKnN/PsHzmE8qCV4X7792tU7JJl3hdY/zNoLYPJnmnLeNBcNFiCvF/WEqR ya1ecP4IBwnN3r3xd3ISm8HlvCsS+nqpGKDfHE41T/vwq4rveDQ0YvS83x8NhNe9rJqfqXQG QQ2+bWs39hxVvo3JsrMLMEusDUNHBih7OS7JMeMr6mlNEa74kva8r9qy0bdnNPKhg0rfiCxs JCCdcWRQNil/oCuESzjD6dSlEm3+OX/EuXe8Ew0h8ASHsoDPb5vPBz85odKnjLeF+R6+guFN 3MFAKB3Vbs+Q3oT8srJTMko9DvtGN6hPYswna2KcyQuhJvIj73K6BgS+dJBFT4mDOzbqif9C FFBQl6AnFyDwGMFRhf2eut092VPO/zgFbfY3qVdVmD6BZKhz57LgVbFyUAiV+laBnEFfkgJ7 nPb+EhBNm4tlpCxJ7PflzmI5xoOM62LLF/UUIoXAefO5EtGkqGOmj0XwzTWbE0/A/iGYtet+ b9Oj6hEbdXv2FdfwbuU89hTsVNOpabVkTbl9yn2DLFYKN9mj8P3A1ISn9vmQyXKU0lUlAgPq T/SGvZNn3EbrP9HWefft/0d+supj7OGqytyEqHhBueUBX9nQd4aTgCiaKT4KTJdLY2Ywo1t9 TN5/i93u79Ppav8SXjx8O6y0cNB9AtuIbNodD1itlbVG8wA8M6vpxXLwvjRUPeJPu6x/BqEc fayGrmwOdatuvV2WDYHh2KqhYrT5cHVGRZwtYhzk1ZU/zV39y6w3gsFKdJEFOGGlhaoi3EVo KwgeXPRdKlNCnst7J1pBSd+ApO9+VObZDdFkqgG82qYorPnoS6BJveGKB5ki2dcaJHXgV/zw 6XG4H+pKhalGfB6UkrYWsopN4s1QGg+ZtVdBsGQIDJAAxiIJ6NTxKf/Mxs7I1HFq/Y7J+Epi UB/SKysffaDE7RKJkX5SWlTW7mTJyIK1OVUDpCMZpg7f47+k26H39g5C8QRs/cnNxFErAHKy iuif45ofEuGU0+h7a8eiXzKqmDVSGWU389nbmELudHKXPpaONA2hSTfp32192qiA7d/lNYWL 3CA0J69ny5AvjwTFXJxTeT65Ux+lDib//DTikp852+LlOt6mabFoKdoxL2EXNJbtK/9YMbE5 mVyW1VrAsq7+N6al7Ch3BkH1CuDS/9J2FpdolVpbbs4z5gqvhknOjsF7fHowuB3fbksc5mdG 8aVuNnyvkRZcYAp6qBRqU0WOsIOfwTturFL2ApOWlp5h6qt/6phkMlhh3B9Vk9ma5bk1Mzcc 9oYjo0rVBsYWvRhaiC0G0G8vWBEJOo3Qm6yqkrGX35k+bKnrAs0gJ6HSHIXLZoHbufA2/zET z6fKAWLkVeaGaO6hMchyU5WnN/0ZuyDZWKkjvVuc/meweYsua63g2l/cD6a2JinZDUGDbL3s Q++WZG3Nui12RYScG6Fyj+PrDvwRGIj0bUTTIxUv4a6owbwaKFTOHcd4jy/bZHTRyQ3+jOCK OOAwsDCoy7alor7sApSeQEt0fejv+q294Ma4r0MZ6h5javFeXFLGsOl3f0HRlna0XwcMFDkt dlMKR4aY8dpm6ezfpT8NRr7RNBsv3JIb6pvn0xTFIINtmG7vp7VXsDkyXFAk/aj1b/IW5MY1 AcqyKoeHcyBW83OYfoBhBnmV/FJ6fRFvPtoqXAt03i2P48hfAFgwsRU/OgU/YDsdUC8nWXeo Ik3/YqFMSfcLrvniXzDItW8F07NmChlh8Q3HEnO2vqBcNn6HBUwXXpd6+T/7G1kOY+Y0gunO wGrrE9dH5E3uXIFAdalQL+ibSAbB1Fv7p6hBjMkIxOr9St17CiUgu6uJ3qJlkHgEtqQrw5E9 z8Vt+1mB4Xtipf3bwk6ddvT2ZweY/B9n0BYWy5tWQy7iQs6cRCU07CV4TLbgBPDpN7diDa/0 jUgTgH917KkNlM7RQnMC7HrdjkfNMVumnPdmHM272NzkArcX0BmfuajAa85OBiLnGSRHqRNw TnUWEXN58SRF8JK8JaPQaEWB36ytoI9lBuC58mVGXwWNgX7IZRgFFwAXpC9K4O6XpEyX4hZR 7YoS4X4NJpw2hT8gezQfJrkIZnpNrR+IVg0dJLpvDtH1ibgtlgT5moiEYM/TE1lbZrIqTL4q Bag49ouVvGfjATVIpmUfY19dHLPymTOaph4alHs2/UcAhfFHDLdD9g2eQqL9ixICvxlF6a0X Bmj8MEhPscopLdSxmxSE8ayVy3yL2+TLl95k7gqwW4ytxcfH3QDp/F28I/ylKP3eDtDnRMyt QrDRM3pkuemCAK6IE/sW5Li6MaoUTocdfGCOFd/6acidXldCoWLj4PUk62Y/0gb6RXpLO+Wv Wlv3QJPhpjmCARQdyOruUOCxTnVqrxURSDgZH2ZMOot7g6I24pfFi9vl5x8rQ5SiTqyR+SJT LWPRYqGihkUwLWndJJUSTwsSyuKqaqV4PTTEjruVMdQhsG8O5BcmPpiDbybeUArVD5pUnnsm 4/ZoDmIFGVEcNDiq23LNRkQhTcKGPySJMUPshNBo3CbXuAStUbRqOXz52BEBTrPhhPP29EYJ +dWfYudl0rm0J68Mj0sh1GfKAfIRQRPJAz1BiXSq/nVIKAze5e6utUNiHsCJWwrWPVANVdnN dQ8ogRdZhHRYIVCZs3pMzaQ+qEQge2Tyme9lE1lzHGtuOyeQrnEpCvQ6jW/4gl7iSjnLz0hU JSEg0ZFa2B4wqX/a5JKm+KBgCV/WYCwRW5km9bdiY8MZCmtqq2tnA9ZyxJqLsKerGIe3eEh3 /5Z3lw1mejJijXD0wH7vrFgQ3ipTX0FgqU3SKB88AqETYrXcTT5kYHtJ8l2VTS6Po4LAvelI 2xaCHanzOQBtsGYKmeVV/NaskRLcnSm9qvtIs2HIZ91Hc74z439svoP4j+v7/mwuacz2qfLQ kYFJdv1nkgQjPtbsFOe+PwZR7wmJ0btUVPriAIChnGNMufehsCBIt0KlW6BlpCKLXxeAoZCk KuFAmuT3Cjm1D0gvbYwi+KDpqj7jIz+K6bHP3RW6YojMxAn5Xbo6nkNAoAlzjMAH2/8FwEGt 1PPC648mUCyIqWO3E9R6NTqDp78F99T8C+/JN2tJX3RBEYjyVIug4fqNUapoAzTit9WCLKHb Y+DHrQ73dvLM9VF1qdB1a0wJukAQJ7OW966vQSoX/5eBZRbnnkrzyOj7RF6bbSHgBqg/Kyr7 7U5aFGNCKInBuugYqag+2EkCf2xKyNqoI/FKCm+gLl0BjPDbTgoRPeXlal+Qntb6TkPLf51z JoJV6AQtvFvM3bJmg6+UY4nQ7ivFr3Gf0341x4/cGwa3dhpQBKJKBKQoeFc8lac9VlWy4Eev nB2eA/tfZHBLrHZSW7gm2cHn67jBO0Va0eOhuPwwigc6EGd5TtS2A/3S1Tfu42jUL2k28SK/ UI8nUw0aURxUyjcGOOI9jtyGy6g3KOpezunDZWW0FwKPrprV1a82Lp8mDKRIIHvA6rNnf9h3 oH5vyKTpFMDqgpA9DIDgatdT0rriKXGhzugm6EElhRhSVvOA6Y4MjXM0Fs54PGr1HKgiPZGX N0P/aSdNvcASv4Vcf/0mqBaQR3yjKjg/dEiPikywelQqAzMtntm56twySQ/UvlACKYJKguBx Ka4JLRrzo1nNy7JKY1DirZJdQ+XCU8ljPIluZVMe4y5OjOA2JmPu+A1+9cJRvmwPqX+c+OjQ RdXJ13BYRqsXqPtDkQ6uA9RmDf7SBHzpkIZ77AEgvlyMk3rfqioy2yG4y04zDWguDmDfWLFx KBy9X9YeY1dZq7G86lpyvge9uvxxP0Cm3NAPoBDQZD7P485J2ecJx2ME55ReTa48sScDR4MY 2EHZQL1IFrPgI7jObxYKFFkZFaKcnKYmio15PRcV+T8uBGwSkeXoz/T8U5Lj5dwoMHMpf9rj Q0HH7CSFAORzPuhFBfd/QZEqnP0PEMxl3vy7liGmX2cUt6FlCV6f+azShd6po/NYjbm7/M55 VIloMlo26c9Ye+RFo7406tLQ/nZ4dwMETXOU1w4hIUa1Z5MdhXBGs3ToWVjUsRzDBnvtXTgW KJMzmu5pYV2h6sK/ArQSRdxGq3uC8Eb/hHEvcTRI3IciUvhz2EbrjWiZ+IL71N5aQM9qI+pw MJtbH0Uxbd8A2R6BYUZSSRuSzbLwLXbhSnAO4pMdq/ATPXRaDE22if+hUn5cTMrfvkRllxDs ZzTHPdkLN8yJ+wgjbnxBcNu6eLNP5rVQU/kiJ/bWX1I0zoxC2qmEGGfQVET+TNYE5yDIIuP0 6O2maMkTl2KcWD2e43KlgKjmYf6ICC6Kr4Gs7JYYLk8seDRpv/g0FfKtvUXO/a6q158CP6fO 4WBbbFLzgpTE3KqGrk1m7+8v478oHROztaX11LQ9IMO4rWsIRMQixLEP5DK+x+uL8loZg0Am dvweJUg3dBdvBB0uUJdY+3lNSn7yhOXMLd3ZatOQUs4txqM/pqX0Rhpv2cBTKMqjTdsUtTvM m4sS0OmXpBAB68MN8Yae/aIkpNLyirnrPOQJfbgP/RdQNzrHbH5bzMMA+N5cm3VgBaebvHtO Muz3ZKQdlI/BovUs4GlKT9iQdOHr2D6q2elfDPTUatjQxBW1Z9gLJUdhz/2Z2woSKvQo/kG9 TcXwLEFcOUhFUR3ad3LPu6k4N28yXNC+bvME+BP4/euS/SJnHw8LhBdmKwvzajFFcGEUdMdZ 1uv6dcbJFrzN2HNlzhs7iy0qePoB6GmKGobEGFEc4Oy+8TPsMXk3c0g72zdwYBwfVAmfngfB 0IZH4pqCfi9GZzXyPsm4Ia78ZjYkuoJZFPaY09k/vRn4dCfy2ml6es/ZuSisfnKKZNzGYWdY RoIVg+tYwMV3I/HfGrKbaeluRN63tftZsMELvHZ+Dhj0ZWkZ7pg5V+xTf3kaB1n4jMYAh+P4 6TYkypEgEdyzZNiDnSfol32Z4gOY4oqiXJsvsyavwViihkaUp4s0a3gVeYyHfNZRF3tWeeWt 72gQaVhyTsdSLIVboeUNTxV0eXY5aSkWTRChplY/xo3BxvI4CgvuGt6w4C+3e6n1XjW9KA1V xFvF3EJp3kHUHA6ptdaGvMwWMYsCrqs2jPPKlq0gORA8sFR23M1Vr0oKwReEppkv1nekfDTZ 5lQSzR7fstJ4ZChaDeRGRorBkC+Qs+mla/pVzyI8OidO3Ovnp8HIoe5iWo5c2jLtLwP0FVyz OTFBAnW0RnjfjizFLTR6F7wEEHsfbnjzqiVmgoByEDzuRTi6nrVApl+QLVsUOmDAINM6fTHB BCDuAGNb+27knqCUcsB/21kdTxUTUtgX8/IbCHKppK5AqhblDrE8gkSv/zB9c8sgPIxNTYq9 jtaCMgZRXnqT+gSO+QuOhMrQ47zMYRx5uSFPmkUelE6T5AuI13TqYux08o+1hKanarIJnLc+ 99s0c5CUo4kd+5jQ3xQGmeljKeoc9PjaFBW0Ih2n4BDReOSBASoF95QDUoDExDZqyBu++Wfe ya8e+L08JVS3Q0BazAZR/XSULDVuHUjLqSBRXUZKnREY2dndW4+vbwphGQqhDKM8WmDyahyo EnRJ8pwqQnhfG47vFq58Ls6A2NSy2I+rrg/es7VOL5KCCqFzfTOkzVrNak1GzoU0yX+oaagc 4yS/lBoIzgiJ5TQ89Mt8m3cDfryeFYPGp4/Fun/pnHHKwOMbpPNCR2wcNx+X1qsmIqR6boen osXawukFfsOXGsQg1krg7P08Cepu8MWGE0XobvwCP32Ab5ZHDP7KA1jPW1JPe/qCTttychGb miVRzM4N0SzfHI6VV/IrBjUhrE3pnX0vShiQIU/1dtk2mFkqphoooy5BnGbNQqXZQXo3pn27 DFMdYjY1gqtnME+iqRFViOKNvDClRHD7EzZFQrudgRgHekxfK1EYbb0uMgn0NglUqxunJYmR iHIUpGmncRXo5u+S5wvF/oq0CvMC7XOXAIE8cidIClaxGQXzN2fQ1KK+qtGfp0QuU0Yj05fU NtVCWe9LZ7ZfstT9p9qwgkyB7uXbBGvOHQ5O9FyLY4/IrTmH8S600WRNB7VIcRHbnOni7sf0 1PyrCO+nq2AqkHMqcws1qG5sdJK9usP+Vv7WbsPdSuZ5C7SJc+DVE7dBofLFZdT+dQXTh4Rg rr9y2fxoigQkwcchSCYI4t8KipQBC8+hucK3RcBVVvBewJNY4RYZ5rr+WP7Ixk9zKdieHUXh uhfWFZmfYvoAmHKO8lwHIrVvECRcxPjTt0+1QTeZFXB4Gg/YGlStQxzdbGw5cGi2RgBQ3Gtt ckNr/IQTURf/9/ZZMFusVfd6NeRTVl1KI9uxGN1jtQ2GKb4R94nW78iTSjnm2mLpUHmEaYXQ Gb3k6UqBbh25bnbC+JV6cQ+77NWz5mgUgZTz5D9AUcqDgnbA4OFRBfcWA/6A3NWe9mjjAIDh 9OWhwk7MJReXajzSZ4St7LJnzY5Uagestv9QlK78nMRW81MPk2N5Px65rwxixUfxj7e4jZiL YDO7GsTl+gDpHde/DmJEEfHyXbphybJAuUnsdZ2HHWuTUYjoMm1Ejk+940pTh6O5DmkHquUn KRBlNhDqBIDzokBS1IpNFe/B7PXtCyIDWE4dWrpB1G/P4W0uJmV3v5aC3UHsCnvlJoY2HZsX aRFRXbFaO6CCrj+bUZ+Ukl4u323+kk6nToidQQKwlEh162ZcncP5buywxkopPbwN6fLzZNIo H6TSkkLVFR/rDbveI0mSEVk7ZKhKBASFYAfrBp7pSPSxLrdZex/r/MWaI57wfF+lBqdccpg+ 9Qakb26p+LbI93mCQOprtGGBCMBQ0E2ML4TXOlJmXb8fwhnMVsQud0ju+bwIDyQEWfN9RLvI FABhYGtdI6zdeRsIrhnQUcUd0L8YQn3FkTTcz2H1zQKWz0laGhluJpve1NQgWG6N+PQ12OZp X5hUSOM3wCpIZoC4j1+d+YLMTPdtpOu1HTitQ5SKP+LNFQRqzlZujskqb2JCEtcl/+0DD62E YX+8hzhRD3RTjQtGYbe8FZUSZIvZ097ERvjE+/S3vKrpjO4EjEXg0hoU74YXMZrgzC1AK/js xkoPnQtXKr1+PB3pnx+PTrfy5Xdd6xeFNVHMc3jUpohUR8Z8J865Wg3B3/ijDES6J4oG9Ym1 Jyqf3HTTwAe76TCrsLx6P2EPVaz5t+eBIMVR2tIR6eAX7aQNaFN3bV3fY5lvYqbmi6lPewRp uem4U+5esILpwA/CyuYpPsCnEXUT7LsEsrUaYf+mBkM9Qs3gim8LsPNgNtU/b2eR7LU98Ls3 c3opQx9GQc5MYhxZQearCZyhELzReBGlC4DXTeNlfR/Jo49XGo0RWg8W/2KWJfZfDjzRy/9X fUZa3ph7zNWklaBng7/byVA/V/pYqjwM2Hvm9wyGCb15/ddNoPuT+NhbwcQi+ImiUH0jVXxG 2MAM3qrB7b6YpoYREbzWCFDVUOOt2NBP5CYqpVfO7mXT5YekBmytfrn60idba2KX1fttsRYv fb+wdaNyvSlaN4EqLgVEXtpHiD9IOnUVQ611WKh4nZRyxRfMsLHQoGbMjglCHVlYcnT/BBo8 rSAu4eA74E1M3nNO8Bz+WmP+kkSQUcd343KLEWsHHULIkBhHL2of2IIuqol7weCtfegGqt+5 BY10uHmzDUCW20DrhW8o0JiiwzfJWj193OvOpfe9cuEWPKufXbbLzNNOQcGotOxEFxJz8YTK Hy5l1J+TPeHRvwk+IYCm7mJxO8rLXfHhK86bNgJ2S7uw6SoAx6nbTpZjkn0M2oU8o/BzA4iL icD3fmg1jGO+4AGCNuJD5p+j7c7UhN7uTpzhHL7nmjHCufd/ybdj2ZNfS140536Y3slyzqsN 0AhYZPw0qaGmurkxCwTrC16/8CcSswemA6Xvd/htU3JX2XVc1CMf0r67kyKRkJ2A5BtH7o8V yXT1retEFF2PjfAb92TfLWwBQ5iDkmJEgLP9xQJn0V6cakw4Oh7AY4DSwg2tBJLJ+5P/Afvn A65+TILzhXiEVXw5Git5ydUQRJmS7YKjHpbzLum2c/JSxXbI+6J5shT/w6R19aLM7ALl4mmy QHwtAMbdSR6gmTfHYTA++Ds3xu2WB0pg6UOT31eDe6cIdT38GfLZL5FyQoJOhznwo3/yVYg9 8jHd/pYrTBIZefJczUL9hD9lo3dB8PKvLghgybvNYFlqEcngYh1FGZ3NVsBfHMo/6xPbJB5/ Hg/POfoIjodEC1zcRVRwaynqiy8aUb8VPrYqYLism8QpmR3n6rliE/4tEqx/StPLS5osOm+i VRZrhwdWJ8k1DDS2XCmSUCoesA4dEOvHU+KT8sRBfT+3OB3UAV9E8qhl9a9ax4g7BOlB1lDU v54luqhfpHZDjdtaOSh6s43OM9uwOrc0ky7JsJcliwac1SolUykrK8mkqlx3wuQDjiVV0xBb 7Gi7KK+d4VjrIwFSdaD+6nDD+9pcYSdvDUbxHvRbAUtHVKaPnYwOGRW6QAnrb9SLKsHcogyI ko7LLTk/eFxFLiyEjjxOPLYWZYBI8qv7MGVCZMJJVheQsJwGxlhEVO+CBSl0AP2Bddw5skuW TvxmigegSnOsG691A0ScZccHGq2zhQd6mWE9CN3ioVHys36Ru9w7FzQEWA00LIUTczGcJ7Yt f7HKm9gsxhvv0Rj4TMPeeiITbWoTKYqDLtEnKVMNdefRATRH+43CFStOKxtpVNZ/x31yCEwP Qa9Qq4eTmMFJS3TquCzSv8HXUrd7vWSQ2haGGJmEEFgEFT6ulbExdl95Sx45XnX8DVjy/+uy jkYyOqjFv8uzIhr5BKy/5xGsQmeXWgRZ1S8FrcDPcXu0ZnZQZHZB8oy1QL6ME6sokjKUIoqU BZ3rzNm1KSPt+nrG6O+eIHO+coTg7R/h5mYtg0BSfh3ywtVGEZg8Uo76JZ6pD4kyVTHvk6Xz misVkR6TDcijbB2qsTbr6yl/RrqkDgV6QL8sqKNOyJSeeEDgho/T2Ty/dzBt5gMWu+TkO1Ua 1ObreK+DcV7Zevx/OFr7BMQHMreitJuSTM77I2msdfzXl4FrEDcdkPDEClM752nsZJR+Z/Wr 85II7DhKL1iTfNX/U9nQmWErTNZEpnIxK5t335flm0vdP6mWRgmpuVPWh0Jk7Qw2ZY0YqCoG n6fHvYvpu3z9Ko1U56uY4GRQFxguqIByfeevcsTrU3UHjq2dIOw2LUCStWldklnGcsp353Fz Rv1qL0rxgrgq7w47Sexd9E6oNOJYwmWguHd0982q0ZGoO0Yh+XauOyj1YfAQhqhN+1ubSSdV 0xsOPBqOnnJlJM6+YzGllh0cRLkWSzcanp1qDyMGwH7nwUJXhlAqxv+lBWwqijUgq4RtVYrL lKbhDfliSaKBdz9og7Sjkbat6K8CksBnTSvtp9e9JYqZ8te4B7XBDWbHwuhJm7PKTevTM23g mca5Dcui+HU+5+oKeRqCdeFK3lW1lC/u28GyO1Y8qC/q0NW6NdJyCX1hywMPn4Fujn5Ioyps vbMYU4Xg/RqnYX9X6qIKsrt2yo0Aq+ktKdWGWPq+CNqmrHAmH6G/RkP93EzksdhZBZMYaEWH KZ5NaK3Z8qCN9FrfQLEWXF4khUMbkSxZ157BG8nr7suS3Qw/SdXIdZG9dMQKcgSZ7IJtze9O bKCEtDVRRxg38J3V8qME0osaUPEkTPhAHtPkUbDxyCTeyzH+rsd514gOxyEkGUiuhETzhitD qP/w2Tb60RyPuYwqaYaedsvjRIO3pOw5CewedQ0PNqUSmFXxdAcXJVWCtiv0//fB2DYy18gn kfhX4jJ5mAkmW23zB0gRojS9y+g7pUj6VeYFnHqkoPWFndPsPxw5CkJkNtMAmd40NfEaInJ7 d36omsxU9kvL0gsq9H88u2UmaJ57rq182cnt05pxZAfpKGpyacVdq4HCExdkC4wZMrL6VIGT A9/FiggpuB8+TJv4ZEDhqfEhSLEYna6vOpDMR1FF1be8LuESQUMYcC57SAYGYdP+QwUaHbE1 5uWrumiIkF6ao7MAPKOrCM73fiksUWMfLc9ofRMrZGtupdXjovjBWek/toldvkPT9ZZNUq94 3YMYvzcCyE8S3X66xcXEZ9KeB8wlianjHLeTNGdvaKJmz2Q7+ApCjoeSRfmvmYlGaruYvLtW ivCakVaaIPuWHjlDX/dpxV5jZtnzNH1pvPsbloQW8jrM4LbZg6/Q7mm7kSOFO1RF73A+k3o7 Wtxc+yt7aLn0XNa4PdJKrqz7xhhQGfAXAuu5HMHYJagQnxfGoxm+iGpXXzAKQg8P74/PYQ4J u5IY7WBJOP3r5dF1x6botL4vW/en81MurBH8MiLcsk9Y4OWyOCn8SBnATLfH5jW3eLhNbk2g aVxKZ1zpK4cAUMYIBNCwSgFUV5v9uJAUwW792AorGwdT4MIpI7h/khEc5LqAHqUxSFB8qNEt QZj+qODQdCpsxUDS7eKkSwnCLcXvhPjJQtccGL7TYcugFvPyJsVq92wif8GVASpxND+Xf4qf G1Ugv4MwH3eeEFe20kcaEs4pkktibsdfAibtI9jLNsWYHJWga+La9lR73zoCzHkjtks5R9Mw Jgv2h0hTJ1aIYOqDlyOM+zb2KKq1TKdfyDnnjzyE31jalOdrD+blklfojjOobB/W+FPLOVqh LNkPo7xDjXItzturM6IWBWhtv1Y6dZ6HeJp17BEJu40jl6VL/vePF7gg5pPBMiIbGvyeadKx 8vP65vo/FGlVZQ8mok6MlVWZTfcKZUZps9m55Qw1zMDtgG9mMZFAPsEUHIaL2RUB+1oSjaIw 1Tvcg9eXOSDLLFodptQKlp1In2TOoz3kDJRJEYHOZ2jW/49BiYK80wtu9ugmM1EY3kkoCcmQ pSsHiYQClVYr3k6ByHy+jvD1ND6lvEEOVyIRM3Uzo20+x/MItN6pfDnJm/ZQFq3TGjRZbVfo Qk4nMvISIc0hUZm2qLOO+JIgP/g+t7pzYEOHFrG9eG15dUFQeW+dSLvioYhc1FV1QM/XcdXZ P9Q2xX2df1rm86DkNxGnOh84nP00hyA/aI75GJO0MfaCGGQjmm/ztuYI73lAweiNF9QJvdYY IoEnwchzwzdZbq8YoiUl+6uAGu0Ppq/UnXHIRNmxmZ7nuBidFzLmhyJbEzrCY5LeF6ESKK9t 4QJh+J31hlG+5l840xk5766c9wYLtHYSXhOcc4Jkyydqmas26FTs8rvAZE2LccUY5Y9dloQg b4ELJOoW1tKOIIgFBunvf0ShokUY64WVnXZYm0DGk4epB+n5DRhf1Ol1bERw+agznugrOVw4 E0P01O+iMYcrFQXX9jGARARUmxGa2hVXDVpCGcdeBBKaJMuQqdIS/HOK+pRDp96QiYqwnmkR RNmD+h4qOOELKk3XBrcD33XKPakje/UkpwmajObmfaVP7YYKnKO3vDzNIUTuOpdEwinuCYiE VHb/jtT7gYZEYmLdg6/WxK4d9RR7plf+mhYq7TplIZl1FSgiMM6WPwxtc1HlQHGCn+8N60xg pEZtdG3rqL2sZEJLxU3SXoCuCyYNrznsBNawsmW3j5WalkuJE/X4drLIN4cqfNNWwU6ItMeP n42y7NLV0ythZ59YkHh90hwzbpfSvE9/KTsFWQTXlZ5Iz54up+h1Pdbyt9bp1xL9E0ZXDRum wt2VK10hgfrcO8USlhPcZEaq/GFg0Qf2mgCh7rhOrdUEQ1U/xd2jF9cDmQ8B7lmkR6l1yo+8 KUVzKe/pwNaEM+2mPbMTjUak1Gi/mYEzlA0rTOQZLOp1XLKVms7922jA48NAOWP4oDITN2qR KNy9yOOdT9enEbpSd1D0n1AcppF07EQJzJQdLzUoD7AuCGgtwR6bjQZozVulPZK5nDqtFwzY 2TmIsQTcZZGU8NLTBMViUFMlqSEahsCLeScJlwf3uqGtCTbdx51mSlyVRl68GMJK10AK2GEV 7bizlsbSj0oWBUA8TDUPvTetCUN6UMI4SPkFznraavPP7yzaq5s14sm+T/gcxe5ZbrAgJLEC zIdyEe1MOUb8Os0OymqKijpayAQPLQUvlctJoL6sWc5FCogcbxw23EuDGlhQT6vlAHHEGZkS RwL/1zbNfya9VETESsC8I/tRCQSAmihMAgf2RoFMo1bchIyoY7XTZWS8NJcUwlSvqRXQi9lg sexPM7H0/k2OKkhGa/I1MXJx1GK+9lZ2YC0C6wcjFy3+oEtx8QPM1VB4L7v/3xgXVKmm7UMx /Y7gXpX7h1wejK8pWgq/5OQVaO2cQbZQ0Lx+elZJ74C6MK/nLkjk7BVsDbwZPeSIRgoGhR5+ lk8xiC9aBUOL3gXDPTjZdeWuHpHR6sdmd7Z8M+qZC938kMbmJJmfDC0IRUCUrd+vTqSp6ze6 /B3F+YiDH4saGDbjECCvOwFg//fiS8fqlUwFbos8pvzxCLZrVFrhYZ3TaOGyQI6le9UaFSF+ XXSHVetrWI+C+iwEfQ6DDJaE8Unq0nirZMwAB7PFeccvkT+g64aHrAPCs8s8g/dahJTZwHNy L+CWJyZq7ZVXnPTCaNQRL4LRIka3sDLSmUU1ybik/xa9zxhdF1o74kkugbBRjLXA0ciPZKfF iWXk4/Mw7mwP5PdUFB5XdDcZ9FhKdJtfR1t9Y5afK+JpPqu3SOFBwN8HQBR1fujgiAkQZsqO K6gE71IrSw4M8OVsyWRKq8+QcJjglTws7JLvRfG43babVHBbw+k6SVXr1qNvjeLM+dDpjuxl UeLgq79uH6vbD2UZo2DFZTYyqK+ExwtQI9bhnmSNo7n/Mfhr3kvXb3M6qo/rOpM+lA02AAon 4AahneNbM7W3VUgG2Fv9cd4My7AkoDlfyVLF3Xggy6VZvh48SuJTQ+mZ381eV8tF7k7tovdm jYm+2lm8be3HP11b958eVHbF51WIesxWSMJwWvV7pO9s3nNgnGT/pY/LE5SuKlex/hJVsZTj LpNWKuBPew3rizJO5sXxHECsXfPVJaO4tVOy4zzspiKlQWiaNn07VPofBBeweErnuzpgMuae /JuYBTSCnU7HHeYtW/jlb9bju8WROlDr2Re4ysNAh6ZvvalHAlLtjy//EZaNBIi/r3B1IlNb SUfNQph5zQkwm1clsi6Sinjrj6lB/Q1z6/XE7yB31vzy7V8ytg+pyANeOOdRioksT5Q4FUjS FR+uUvoqRCVN/CVJYPSQ+ajsK2ndT4vidqsTTBQxg6Vmrvcukw44xJVb0m2htoas5Y9hUbW5 MdcYHQAv1Fo0lt0dmYNrDNEP+d91jJD3fDHx82neT9qQtjMqgYeC0zQpH+6DdWhzg/MRKHsS QNJclm/AyA6o1xUR3kapCFEGrNBvOpcN70uXg0CpP9oIagF0ZsAYeDmTMrN11FMbapI9/966 bDqdWRtIfKo6pyIs1uRVK+brkSa+ZZAI2jqn87PXRejdgh7QhJwn8l0cazf0UaclHWMLUo81 fgm+0kK1dAsXHRlSTpNM6J88gq1RlJmfB9oOX58v7yzYdamE9KMxXpxzVeQWEmhlx4bwW16W bHo99K2TAmQt8P6DcCToTH72TfAG7iXTgJDDXoy39X3vyIn0SfJlTZzrqBMSsiUXMan9UhOe vtU8IzAVNYn2h/t8griY9nA6yyiIET+z7O7LXHyMC8nqmO6fyf7RGDHM/kdHoC1PfrmjVwEA aBM7MC6g+PS8TFZkcJgGo9Xyj6NYj1jRlJzLQcuAy0jd5z2rJ9E3/RVX/WdUcuEiIxb0np4P HiXlpcP/JphOe/MhUE+hC/SQT57LJVgBFKbU8LO2Y0CFMrA2nqi56SBjH+vdOg2RhGTn4s+c vN2Yt9dc0/41YT/VQNN1naVUP3cHkFugzt44vp3SDwQWeul0xDWHZrTCv+O2ef2ZehjPAcGT r7oTDI6HQsOZV/UgZbtUODSQ1GKTlaS7Nh6WhQJV0C0F0Lz0nCsKt/vheg/yM3rQ7S6ieXsu xVZGyzUkzJWWcOnOjIGXs3XfCC0ieL9tJzWZsF1ZVRh1QdZS8AtQXb13swS914a8Bx3VQ+W1 o7k0cADpjq4AVb8CuVWazhvVS2DCM37iOPiuo0VgHJ39Ju9daKkmfOKe7PlzSmTqrBPLTd69 kqjQbFG3leWKtw3iQO+jBq4/dN0WJMUXJLiy3+j6RBQ1qAM8/yCwnYD3jGlaVttJjMBlBFNQ c8mWN9P6Hc9MO+3/08v+zP0f/4DR5EAhx5WBVR8M22lr9om3ECsnumnm2x9BoCzVsUxnpIzE EfKzJ6wGNrTmYLMwd1w4iflX6TD5BRZGv1gOpB/ajdiq5/JfV4T0Ao8pGWWipNms5uKhRnp0 Blo+qW//RmTeP7bTHzEK0RGbhAZfBx+iph5592JZ3T6Ql+L8urfZ7jq+LhL+TAWOz0BCH6XH 13Vm57wImWjCiCce9ykr/l/fq5NN0tLLpNvlqEblXodgXE4/YLcdJP8ehK0JkxLF4A/VLvFK 8xzwtzwBFv6Swm01SSXKOWRwg9Ml/vOyNsf8bK1h/Y3fco4BpYlRfDBynuFBFl6Ib6S4Cr+Y PR2Q+MlH8zqTRclPnoCpwbAs7hUgqEvSfJRHDxdlu2uMvrzeybZ/j6s+ZRqxpXkgHAVJ6MfN oGh/SNMW+H+S44d30/8JW2/0MHEm/88JHz60Yi3Ij3AVN1YypwOGfza9l0v1SB9aN4CP+gLP YxNZg7zDnPzdEllX3PXylg6kUOheUXjz1/LY/Hfgy4WzDrduRS2aNp55Pj+cGs6LGUuQvrUv E0D99sUd5+FS1t6tFU9T8jOZ2UBOYQ5B7lxDoZ7sJL+W8DJ+qHgW95yUNLQgFdyRIpq7q2T/ Jc/5PqeD+6F7LPPJdJv2RyAFLbgCUPFZKLoIq6+ABXNI5oIBKfLfG1qaTkIzbCExtjdRdhFW N91LUAAgD6eIxF96QnLlQi47gW62NmkzaoUegHc7CDhMQiLE0xMAow1ZiyW7nY/aLxIWUUtW lbQlMi1c1aJtZCK7kI7E7m3f5CPLnXZo8E2JjCnbnkntXjcS+dafm4Q72HbWaI172AjVqDQN +UaMWwRNF0A10ViR+Mf6ogxOU7XV5wMNKTRyElLV1IMaxe8UpoKRq3qswvh4zXcdOir7WJtA 8xEeGLz1EoGwocuTq5KXFHqn+04eydXLAoQYkdD255a0zKKO0flEVd2rVsPzF0MOVHPWYkS9 l0WKUSzuJ9rinhL2bQCPCnn+GZo6Q/cCeqiObMjaE92FaZtzlEsbxFTEgYinwZesh8lC9TLb 1bGF8D2PF5FQ3Gf6SlMGo6ZQpZaf+Ce3Nyx7Sp5t9Mlni5k/tV+Z9B3oCS9ZpiJNeTsWNXiN yswSxm0jVxbo/2QjcYH3A6aIf6luTGLHCfapsT6SUiADGFdXPxRktGfTXq3ziHghyIWMfDfP d72Xao7bLSNT2xbj1AHrOaPzv+41N1iquf/dWIodg6ZPtMItTIcpB6zW4DpFjedJ3/6CX2GJ wOMqyTjAfakyBkJM+dGPYTDCUalfMjTfhQ4xYWShJF1RLFdzBqhbt4iQUN+XyEhS2xaWhI1o HApPKrNOWT/ED/SLkW13S2kZf5WZIgAjOWCvMFTmzHqvJvoGG0+fRt2aFA4DFQugdZzV/FTA OVU5RCqFV0rBQSHjJCeTUouJ3weXYqO0Xak0feldQP8cZ2ovOKPrqON4KG3ywycfgSi8uvQU 4YR7qOD0Kgpgw/M7G0SipaVrGvqA1e7OryKCHykge2Cdc8kEM+vH0NNigMEYYXNBjBtKkUwU PDdST4BnxG/84C7loh6ySTHg5ZqcxwN3Tu3GF6ZUGYGd9smX9DxPdELzhFT0mzQoxriBYYVi qqJfA0sHN9Nxa+ltUGDhs2cy1frI847M1m2pDhgwyEk9BztLTqu1S33kgNcPYlEMAFIIh8MZ WOLqcRI/4F6IsgIZ6/O7S6OeDm/bI1Pf+JgZ7/OLdfBM0/vvwn+xFvwP2C8apAXvnfOwddsC pLjssiOzztg5wTb0dw/TuWyKzVvxBj4IpLPillrgVMNMJe36Z7rCtrHGB1eBMofHa0zwDUNC sPgR2PcrbQex/T3K0zW98ZV2Zbdqtl9HFz2obgoV8gJPkhZbFo+lsOg/AGn0Vcy3yK4MWDKo zAYGK6s+sgi4cVSbhwbnPWIIM/nvIcCgrOmMEjECSu6iA9J3rYQgrU1i1gkQrV0Z+QPLz4rz 1xQ+BJbAycqGz4ghg5yyA4ofrOEnWu/mebe7qqRulbI/ST7xeSBhZ8BING4GiI0hOj2ArHA4 J9kOXCtY6WkMHTr+BG7JnpmGJZasS7+JSeWD2+0vfpNmkIRccxo+aI1U3nvNkqWGGfoqZvJ0 qlEnHx//UoXqQyS12I6EgugPZ5KmodlJ6RHkDu+iXAaEI0mi/LZ3gjK4GDxrUssMYrUWFHke UzYwoksijl4fDPrNJammIiQtRzgIaMK2ynyKD/Z8Xj3Vrwv6eMjRvKbPTgC9SypDQIG67RqI /simHa6T7UcLersyW5EMdGJvv5iAN1LdUzPQuCBPrf4lPZfRWvqRo8SioSDLPE1mT3sQTdH0 pSj628QXIeTTujhbHL4nUifSaZMKYfJ1s3OfiOGJtYTXXrbmkDjCLMOTEQoN/REAyazxG+ZD KgIMUR9hKjHvpaGP6loTGArcXqQoWNyECLy3OhaosEIaV897RA00TYPQUIUPP/mRhp8FTaCY oAmF+MI4okZzr6XIqH4SUZecBmFaOl0eqB2G/a95zjPDNKiWhRJxoPmD4j0iGr+7EJEyUt2/ jW3xmDMpTvM5dfELNSnnYN12SP+rhR42ir5WHqs8hKiVF3IQhCfy0WLE5T9f9wHQ2fZE1wSj Wy66W0WZTjM0pWEmi/jqYACK7ZxzrQc6hJPBOyUB0VyVLQhLRogWQfcbOXk2AaM21kcq+7MT 3qGpzFcaJQKtmV0qd1M4LX/YKDgZnqSPAgAXNBZ6tCl/RG5nBxT05Ow77d2fVcd0QQAz6Dke /Zs+YQUqf4v4KIb2IvOnnXBbZDDeWQ/Zu1qYkPvVzSdbAxH8vw36mlQqSuOaZGF21/ELKjaQ /BblXe2o7k3URkaB/9cmioN32neSTlhkJxa4fmJpaFYLoiOA+k5hD98U+gpoRMX5mfrfp3su HwOwC8sqTZ3aCUzCrBQwjnkrRLeU+2Fy5ZDmMgz+dqvkcxn+gBvF4ZKOaDHbIlma3rUHQ1bt 3ZCzRKEfwSVraFIbUnz/Q/mgfZGkR4hWJ71PXSBx8rwcJpjl3NP37KZVVOy6WEyqbHCojDOr jJRAiXg7RZXe/jYP6fWRybUX0Z0ZWZhLuQcLqG57csKzy4wq/g2Ch/2sH7V08TpVbgyCGSH9 iBxnsGqm/LB/Xfi6/P98NQTDEWoHp25Rd7X6Jg3QaubyL8vjDiTSZo5Q1DDoa5C0cNykUnMb sVYjrFPcVvVhGkF26AP0fhKUWN7079yJ5U6iwrCHuJ1/4nmbbfn7OtElY3pTyVBhOIwT/mcY inPipsXSCWKVMynwaA4gNnwR7m2tJXr8I6UAXLJwqYjaUFYb7Hgva5qehyNQO4p8BSMZoYwd dTzGXqH9cZqOC1qglS0Q9hW7fTMYTI9veX1k6sjkqmStw62ATUwEl/6+U6P0ZeHX8bHEq4xG dPDmLRwJcxPIXeXNkCStEFQ+qji7uza3wQTEDv92SyoJmzm8ZPjpfLL77NmBmysOETd1HyPL g6rkV7Ru9WXPRhDkiCHkxCSf2nwKv6LZn1XtRBfZeag/ytsp13dVc2rqzDGcEKcm6B8LlGVd CGv7ku9qvTxsB3c0OYpLkub3QD+ZhDFlwWmObRkskdiPNIZ0+TFWL+qct3ar6kMIjewHNWi3 9Z88kLqVwghgApO6pdkEvXLxO3zHXvsk5z/i+urjjqm6kKfMqZE0RhRWgCX9fovaeNys2QyG LoqcHdCYSY4Jn8cz0fmDtvc8e+7bxNRJtVLGyrP+CUQvoRsRSnb+g2nhawXBaSKA36ehjEVr 9kuPJfrD9m8zSs1ko74uGjFkwVpKtasqilA28SUV6RCgq0L3LC9a2SY6YODaj5lAjwC+GMET KxELTr5dnB5H3DbGlNumWs80FHTFedHPKCf+jFEp5o+r65rRJTOWuAMTgcrPu97SbrusibUf NYNzUEPyLo3zgyOFuaQVDk3Pgto9NUdDyOQM/D74MMtBburxG4MIuRiOc+lnSVah+859YHki UY2dsOe/ZeNTrwVihbPMogpHyiZ92alCuSf8ra0zR5Rq48yCsKPf2xjiqeJvhpO3c1BI4ttF YF15PkDpHOn9Q4Hjs6+hBcsts90sfOBwAxyQDCPrJzkIUWYTIZ4daVgZwpRUPoF422q+PGKu stz/SAX86GVHORxHObZ89fhm5CPKsV8pPK74QM+wKvUm6fn0BqXOkBQjyUa1hveZTg1VWSSj ztyFtCIOrfs6yhY7OfEZPTZEbBKaMj85/kW843MMCLk85kkK3xzMQsUYc4xGea44S95DYb6p gZhKudAOXRXz7vGk+XZtWSs6xILSBM5gSaVOBgJXOfnv3oOEAs9ebG+wImFHx9MQibsSWN+H tCE24LQ8tMvw5Jw74+gF56uuMoptTiYYp2kfMDV8l18MakkWQn0Tq1J8EQN7JkvzTFGiXESt ChRZgEYAba020w0MBP653ytbiFic5mK36RB+yuyJA5lOzymSzyYdf/qUxPQvCR+1lncj5Csk 7u/9JOdO3DFacUtEnpY/Yg7Rrz1VtHxbkktoMUI5d8gZ88M/UAoXk8lS8u9hcWZVuPivWrwO fKcJTVASXkVTkRnX4eeJm1RzsUyRBz3qTE7l/x1gpfuaNVFhoMusV+9JDByACV+Lkx+cnh5k tpuSQIn8pHfrLyWfItaOrRzNmEwvuEwoTa5oyzTbsSPoo+eUzQ94X3+mtVXFYiH6w5Oxsly8 Uc4FYOVDAC9TEeePwdEuqI8dg/rlZwui1an/Rtk6nVpx4X5EnXn+PPO7ygZ+Y2XEfRgHELFk P6RYKegGtggoXIP2edC5teJ3r/iMzovViCfPZ6NAiOWnV6x5G8zxdJNu+iMkUPbVJCmflbtA ybN76FVc/VYbDxcyNjFpg/bBx5/Na9dnr+hk96/8pPKpbOQ1/4ccoOMpxAeVPV6lRov6ZpKR aY0bjYp9VEWswQf6JRgWn08vWU5ELLgYlc+ZYq3pHLC8RmSM7kk8Nuh7cBOHi81H165ouaXd lIJ0b8aIL0C/Qzue+bc8/KYcdYXk328CZVhU8AL/0YwUzkBVduJ8X6zQaeuXDOoe5cjKlL1y bO6XjigI4//zJ4WwNYEiPiEyg89liNMh54teTAo3fEPwmPBCG3g37spGC3s+spS6HIF+A5xy oEogbtq60+rZa2fZ3BsFC2s9b9e8i3000Q3Cl75TSmR9w8JUejqIQDkqoFugBkkTFWf9vVMh hW51Cv802I8/utA+Bbr1o7zfIXNWkuOsg0EOnQO0HK+HW30jhYVvIO+ZDR7d2XsQGZ8xiIfC ZBuYd+hNtt6viMkDMYFS9zOpt+gvOprV6oMTkt7vSPDW5xGmtIdH9AXYnoZwrD76kZLlXhUU TKLTHMWOC4sJg/WL0p62OdXNqLNg/ZkdZwtj4m9uW8A9rSZHyFJq8mRI4n+8I+4vFw5LIMc0 frpqy/10Uvtb3Q6ZvBfHJmSPK5iQghcceP42OzM3Eiw20sMcOZdIWHlpxgYNZdCmcDbTeB0G huper2PV/1lCvvM/jeQoL682E5spuegfSVt9Ma7GWtdlG8xC7Pm6VglqAaGcZto7kbDkby5O H742pt96Y0NqyWD59NevcOg/q5DrQpgm0rfZ0Y30iMytXqq/76pCY0/TBL6/dqITlJ7b17LI wvYyq1jpeyslgVnqnocwecro/9ug4iYd+PMRG96vCtrFxdHWc5Av7y8hs33oSmLfLemHKtNs YVSPiw09p5DaIz+G47BeyKo3P70zrSD/V9g+iFLFx/z/MhtHNEo0FHsaSPBX6Qgf+CURfkw7 5yO5IOSUDwOUmBZrjbQntlj5BveqWIlqN0/9WuwTzXVDX0vVVWkEejwEtr21R5s+5oBTZ4Z8 nUb9Wp5dR73XT8nGUZTxoRIdpeJt6mkDxf7msqHncn2T2hBogLJ3hUCnJZ9MyZpyeI/c4x9a k8Zye7QAXmEQOT8Yv0703hAe82B87eNPH6WW0mmsb4M8jJ4BTcJ2Wm9KHSknT9GxO1c0D7j4 da/KdtaZdXDYcgDnnRJHHLR+1PJzYtOQXMEYf+HSSsVHWqSLNGCPHryq53OpHUz3IlQhOtv4 16/nF2YdVDA0Uq3rVK88Xms6Ai9MKAu/mafxbVkLoE75R9XRLV8zMpzXY7/0fK8x7+1rntJT 3KpDyb5luc5ydWBcb0P7kFhYwQZkhS6AZnzjRbWd2E4mMgoeOG/A85MfI5oC5a2g+D0hWpBH TOc6wT06U7X2f5l1q0jgFTt5jejA5QQATHTsk04bbfxbk+aKq9GLSQFxVrHcuDVOCFTW/Gfv GtavZ1JzDhFR9DsL/SEqqQcjRCzx1tYJKSNzFAI54kJWFx6KDOvkVPqXg0LoR9vKPUui1GwT Ix0oePZXVWldIqJpdnUT8qR8WfzsKGoAzUfXggiio85GOygvZaCG5/In5YFTvSvaJ3+A23Mc nLi9dsJ9IeQtnNKhLT18+KhTVsTNbvjHhxJrNVlVOT1XiwLlYKMDuTTKMKZ/t2sKGHR05XTl XWUN2XyfaPDESxS99EurdUvLrF7b2PRQDP/H7mzAfdPfKuX7A/2eZ/T+XzZsZShXYQiazPq6 e5js3FhG5tsOshTJ1raYIukevQuzrSU87GLJNtulVWHW4xH/VsnLEkLTEHFNkDRysSYT/ZDn jEasm085l1q+zWYhpw37uc4iKhVHhtRMNmhcDRY0n8m1EQWyatWEjGvnqQF/ujiVzHqJe6pD qBPAFD+TwrD2pHAd40DQw/9gSKXeki7/q8TAHHG8mqIyntyY3qKdkXXgiArvLxlsPocB081+ S0XdOpYZCxFtO80ssH/dfaTDKvdM/NhBm2K6zWo45IXF30KviiraYQizzY149/ZEerO2iOMT yKb0x0Lss7QUVXLGwobC9o8KfINyDGIIQ0ItnZekvlE4QngS57/jurT9UuwU//f5sKizsUc8 PML7n8Oe9pbrhENnLRsVZ/s/VBZ90WR9IFhea0XBSAHwKe7FiT5Nl00h/K2iPjd4zsRiq/Tt rbuPq3r89oiG/nvZ5QmOCjWV5VqxMzhw7X3zE+rQvs6HtJft++nWK3rWI/pbESXlOCVNEmm9 aDuv9bH57UucyFKdAYeglbtWF9q+5TXI4XXGu3uTAMbXFm+ZTS2hY8MKBFgyMM/P52PTOU2h SLYeXZ04hL8NlWbC8D7Ntu3upOSDNfldA12dva9RsC+9C6RCKeNkakpELfbaZeCf+KX5LZCp 8wuEZLtKsahAon6oq+RcRLNMqmzJySk+7AV0HkhTIGuWM2KTOUWi+Hq/YQmSbG0uEtrrEPhN Cgew+ErphRufjI3mWJC0yz4RK9sk7D16MnYQLRZhJ+2WGPOQOhrLUvl+NM9gaWjc0aJl4vho dfg5idiS44Zx6tlfIzJc3k/9Rm6rHu8I/mAwzgexFeCwzOVC6q8LTeOtsSvbwcNm4gbz7Kou xIfMtUxYj2/XhwYUZveJGyV31v2Q6FjhsXZxoIjFbLDWGAnbJj0xxBDfwUKXndK+tKGWd5km ytlX2qzA2Cs0PO/yXz2vi5CqqSk6VF3mW95HdLBN0PYfaxfG7vkg7LCQ2gitQFPoFjQiH3pu RAMPbZl8k9WDoLj0Y0gaWHzLPGShA26eNHijhrb5L9bxmFDF4Keq4skCSPh2TVDXIAAMZoDa YK5+B8k5xmOJz+8I5jsaD7uWQdAAaGQWF+6YvERvwMI/0DVaGaX0jHZb8zAfh4U6iCtYJXl2 GRvVTrARu+WcPN3t3jTJ2nI/fL/d6e24DB4hOTgXgiDILF8Wj3N0KIW/3n0IKUAdp6NnBC9v W8uaddgNpiNk1TpfpZOv655/8Oqi/iLpkqo1R+cHI7tFt72MOPegy4srPtTbsjqn/9TFaxNe 8K9eSZnYCisDWz7Rr/PUgogHpoFvDRJybdWhlvO5iEHXqweMjhUWknsNk6GSoqQmyN7YcKab zTKCJ/wVHvEWSt5/x5qX1mYj30GJ64vufjGYYKkXAEfmBTCXu9NmP7rGwYZIo8IGSwodGPzM mg0Gl04OwiyUZlxcpXsEbVpRun4VozNj+keEGQwfU0gBuWMSC5zzKqsB3HNZf+E/PNI7zYQn UmS0rgX2ExdYRFb5jxNT2tRKd6lnarns3gB61zlq9hOwhKioHThSGR9xIxohjAMUvejLmJG2 kj9fHe7FQwtVl/6KoKgOLM75tnE7f74nWO+93UQ1hqc8nQehTClJuhIWQYh1LxKerQGU360O gL+/VN2cFBvcp1LLkrSGB0D9CCAS7klFSXuHlwiykEHj+ICyJsuPrgixq3wljqFB8K2sHOcI kPBRIXOZb8bssd8505iakMWEjjrqAjdooTyCkimQBVCVEzqtxrIHn1lHGDpP+xBplGtFhJ4X 3P2YzviihEpxAIa1WehGin+V5jsvGOJcgAXaZX0cJg3Smi34dTIbl/62c4bGiOWbquTlE/h3 Gjp25IbxcGLOnPVRiK9qZZsrp9fAC+0RytA6zQDckxrKwJD9ejirdwTZop0iExh87ZgO5C6q i5MidWM8imtYjTZjD5NkY42mMKr1dgOFHSe77xRvBJKSQjprPhteFreDhCxsms0W9cyUgOLr kGzuar3V/r9ltE8lld52lfSI08vplJlTo6ZwFgAGAP08MwvLt6WEALXLhZ4Meo8XRfcFZTjo 1WK71vDNTJRZ2V9tKi0iQzc1/8EofGqom7UUBC9ohVQmnpL+FsfKcMRa39zHE739s0Gk5vaH tzU0xo8XD7zG89iZehuwZNezjD8O//THuFneajuQaeJ3O4P1AzOejLmzFui5COCXGl9ZZ01G eM/fYIRJOQQ6B6VIEJQ1fhwnE1JCsEE+xvUzXw0DM74A+6VubrR2gjq0MVNpTsc41T6Z7r6D j9iVjZwufIIQeC/mcCDOaDG6dIjEkvGp86E1iaIUAHvZxPzGUo2Xy2eBsmWjYQji8ZFwyWnS qYul63cL9G7XSUhzNGt83ottd/w8S3wTcvq0er/8v519Sw9yOG9nfTIFJ6EEo8r/3IOEZ4Q7 0kr5Q1zjv1m39r4J4ZZ17BsnK7mtJu9qJdFDAdOJbwUZmUrzB4602udUDGG3LAGXeQok+cEH oGjYZ2ec1cPM9tpQNN7bddpI+3M3JUu5lbFjkPLH06nMYXN0H+qUd/kAhN7BHeo4GMeF3vDr DnvYhkBrPvWzJIta/te2U4K/4JZjHFovXsE3zqxkcvvaSDXZx/hM1/BaNPGQP28qwBzlopY2 GNV20UifpuFoi+4AZbDj7fMQnDlvbQCG5AI8EFUe1iTT3tqt1M0C8SHOm31jLIQ4gjI/YHRW nRewM7Z/cdgORH5r0LaQHfIhi/zu/ZOAPdZYFL4QZyRNyerhIOk8LHzyVa0M2f2/hMboigTp abFIbLl9Nm2xYkzypvrdCX/Z/W5SJbG5h1doa7Op2sKJv4VoTpG+VOgcdyZeULY48PCtpYMz uGZayv9C4aqrc2ALZsuJ54xsvMzP07ijCavtY3DRsyA1i7G5gvr+LVanJ+DtNe13F9Vw/0iO 47VRhd4mwnOfFC+ZocJxRgpBPFHrux88e7aIZmYNzV36jK9nZEwFp3ZpMFKuOGW3PLmlVdef ctQSkRljG9kZ4pZaIfyIeAzmnYLhQn4fo4Sg7iYDWztRa5v/i1om1iYTS0Ikj5gIv9h09BU/ DaMCphataf4GPtQhJfDTHZI0Zb30HF+vsRgyhKMhUanmhDv5FuvKRWLhsHoN16EfIlYIXwdJ jRKFKidVU3rvY44JHVfpSN/44YhuafWdqebQOsMzTtXFN6B3LaW+PpsvWViSgrkjTH9UsQrc HvPIu7VIVbppozUdWLzAjNZcoNjlF7LVe2C/XiUSO1LyJRRgdvZ2N15suONwsLhhOsjYslz1 MCrlGzSG1tVffj+3Nzu18SJsI5otXt+w7QjLmCgs2Cu8QbJeQLSQtCgbKnuQYHz27nRr1y/i VblxANfxI9cqK3HNNrWHyLGIHBgTf6p5TbAcRp5mgzvfpvaRL6yiGw0QUBNSs1L60JTSqV+w jrogeemaedpATG1yQNhAY6KIPlmMjurvydAxcZMfb+MqTg9WWp2e304YzZ89NxhSIXVski4Y 1SUsXuOjEqH6uoGQMez26M+lvbE9ZxEtDSserwm9xEG0yMVloowW5DzBQfu2f6OWeCNWjIk0 8udf+X7hKb2IngqzcLJpn5Iq5tWvNh6uzOBBdytG4xxg/GEGwY0Y5Gsu/5tWZjfHnuQVYJxl Gnm+V3CNweQRbTqV6HP789VU5siDCOeLK3xHWrChZDz9AYWo0lSp7mUwAzGBGWTUgkFX5aCu pau/xhDvr4pL1nwz9rx56Ue/g/XCjtnosLqF8NBOhaszCXn7G4dAFxOS4tuFNfwNb8oUNWe6 U4zrdRwhiKJbRsAf0z8JA+UxzkreAblGo1zt3axWmOo/KF1uUvwKFnJLmPKdVRcWESHpELio VyUHlMb3mLw4OvhtaRNP/JtXiv/bQpK05Q/z2AwCJGQd5o/T83o3AlNTsF9wOYxfVGQHoPqA IJiAmxj3IMTlqATHEyEDGNg7FYxBdbn6XBJdq2PWb9wsLXVwTDOl6dQu1IdJcST3r5M56q+W XTO906AdhzLs3FEl9OuozZ/cC+ki/pwOZuw73B4j8p5TYH+1I/wZzO3JAmIYHlz9idRUH8NE vfpFejN/nX0QOWhDNg6T40BxymBkATPW0fOD9Av0oVt+Y/7TcsfZ8pdJCPObYjzbDNlxLSzo bXmwcg/6yHPjL8/mpCjpHFW070rO5QEZzVe4yMIYZdcrFHMiCQYioOlB4F0A8D8mwMOQ/YJQ 8Iegz2eRogqPkkLy6n/5NZIafJ4k8Z4OXx9CMorDXe4EU/6+Xoyu0u+aWDJb31CqrJXxUrue agKgoZ5rJxccYzwjosSIKu9vS9DeVU8wc7GcV8RNx7Ch8p08IBweLeZlMeBX9AHzxTcVusN0 hlW0MiMC0PRyUWvdEFb9Rm9/DJVvP//An9px75kOtNmrRFL1yKrTIOmL0QvmQSB2AOXojUzg KEnj7A7dOTo/WXrBImXSmFUC0zmxFUUARizH/K0hQgA1nPZpX4raVjePEhryegbh0UIPBeWI uui3O2TjP3JDjjh5mIe7fXiTk4lrxsGhpl1wm5nriXvmOHNHQiMH/GrxPZs9ae2YTGb7I88w ooo10zixg32JKqfbJDng2zS3ZlIqkkGqZJeDOanj99aO+aDbXCijk0qu3nLYG+qceyI93TsD AQQAUQCGG8ffRkgG309c6PUwqmPe7N6XqC5k8Cu2W3FLPt/xwqxQUpV4TbBQte4hdm7x3OjV +WQS1NCFqGvVqhaUonPhR7CSbI8OUiZds95jwpZLK1GJ3wxBxzcON+/QWGxeneu99qn+PtVt x+R2lhTcBh5mt27DMHizceY3GQrhrwq8ZZx0iAIg7cV3eYqcBfc9WqSy4xb4DVcljpmLCgK3 X5B18M8lddL+qDKUZGJ71tbmGdGL3kPQfO87jxvMjorCqHsAKRlwdXDxmVhEuxWwls/I+MtW fXCvSKfCTOgG9NBLh4x8w8zgTxyDq5pSF4jkVYSO6Rqxy/gyHnptgvm59govtAbd87tQzmpJ BRgPKGH1AsAKYHwJORDmWwHVuh8E6i9Drn+yuSgt+fzoTjoWkDzyA7HWsAt7Wj+Do0819eQy TOvo9ojD8mLhJ+lmixDmeTOfzoQu0dOLqvnq5YYmxyDtvVRTSlJTmOko6HrHqz21vg6fJHB3 CP3pkDJhu2KYdLCCoKwFhbFS4oKrWTRAwtCKBIwaBZq+OL2Ba/3Cotuo73o8wAD3X/y1njuV 01ofD4EdQnpbPNgbVfAx78vlNkTwhpaXkOPwCuYqzt3dgNPzQvVbKIvznC9OeW1Q3pIoqoLR Pt9mSLov3MlMPlG3lZeI2/gw5P23Rn7JUbGWoM9dDh27mjE/aJksX5G2o5PKBs/Igbwf/q6K vyizoOEL81Axc/l8Q8r8uQFHdAhSVySKScx1pdSyXKQmzS/672Ybnf+53DrbtA+IBv97xRL3 +KIr4jGaCxb6sfOj4JT07soJk/mIxiGjxEtdvUJFfUypIPacPXHG0qnZ0e6s03LA42+iFoLo R0sweWAHcjOCVyM0GR+4M38xiRyC3CKBKy6eG/PoS08JSSZPTLoIhwfSDbbdusvPbRvQwIzL v21jb4C13Rqkq5klZAR+jxrOv3MCba2gPvX6yazVTeKwFN7MkWAvWphRt2RzsL6L0UK/aPul kd1hJW+rSV0JJsfVOULyrSCXlBBixbVtaO27x7SDYmG+EsQuMs/iIUWefQuSQbLIVXhJzvUL S3G2INgw8fGksO7VL52G2a5zV2GHAQr+U2cTSezF/vHRW417dtJcyPSkjOid84BnXqATKd8W gidi4g9CQA9V124aE9GbmS8URrLJ18rjF3iHdqdZGZYe45Dk9m7IohAXu7Kv0tNjZnC+oxzZ MAK8GAU8DGDy5H07Wmk6Bp0ZxuYD+vJV0dQRFulUyc3UVHPFohPUEnkkR1CMozY/xecDF/wM tuXaoQlbLzz0MP4yWJeIIEJjvnnaw/yg6lHt6qpsc1hyliuXok+/hyJeywK21KKsPS63ANCg FACJQc+qoFp9bDp8FLByZMLkCSj3K5ntMOWbzfYCPdD+saZKXi9pC9s3YpMOqtHR8IG8kJ7y rRgaBbhWEBHhHynXxrOmOexwrE3xQFwBzfVsBXVVscxsD0+Nm/oNQNBDMfQfq6V+PkRsLPe9 pqLwQ2aH5DSdhfO51dGhkKjqHHsNsXipJwajchHUVD215+2FBaj+k9OGwthAkk5hh2xB4/Z4 nD/0BmFOmJPzMJ1dThwHy4Kp3FABM5mHiAEwtFC+Rj0xzl9ENNAqxHHUECXpFqRacqX6OzMg ImKLXyOpXj/evRjutQaSboJx2bjdX4TYQ97KwF0Up4NwMVZ6d1sLJ8PTsFqnXFZm3mzIKY8/ oZJjnHXk3nkMyjyYIOipOMP8HjsmpYE5dAPPF6C+Wdpj0o2+chJu70pl7W6r51LgGrVW0Gmk fn76w36STGK19JMvg+PAo3Ui+Bnz79qcuuPCJrNVYlbJqhm5M9Cng58+xaeVYDENtIpKsIcO k9wvAazF2TRIoGox7ZxVBhDrAwat8kxTmi6hgH4d34kpbT3cSBihR07VxzxGKQrohs/gd2al uEXL9IIOok6F/uUAiAH6TlTItwIgiMsqegRMsx1a/s97jPpuWUpxouO4MB0vt9Zdcz+Dzohj 2COOQ0/1hc8/Mr89CQOHJqgwZMosikZy6cR35nleDqklntsQc1TM1GF+vNGeODZ2fXyqhp9W FwjjYckZ9S/XqjXw01uF6v0+2jrTSIAw4XDXjA5v5ybzeLFH2riQl296ZpqhQeZf0ka+GZmX scQbpcLTW1J3ZU9LnWAjffqmib0KqdGJn8o2dCPnVDKMVH8OWjHtsf+oO3G//ACnq4De0SyQ SzcAg9l+MVBTsSXCrLE5HSitGSbiZLi9tFKvbb4hxTJyP9C12wbYSdoEM/KmKgIRwVWRB+gs 2rtPNyoF3e1RJGwLYvg189CNdVjymuii8Yot5fv93IZzyfKP/d+zwGZ/6mzZNl8Rwssoac/D FLpZVrYpaFBvKU5xev1SWs6CEor5t6OdJIdvha7upIYklRbyxENg8erDpGa0BtPTkTjjF+l2 J0rmjZbUKoYibANZBDlMYWyx+I6+39h3eTb0ED1PxYxOZfpghRRU3p1+SeEQDrekXvlOvve2 29lb89q7B6UFV4/AtFO9nTW383J30YhVConV8syC30TqfSCh5Et7LLlkXQlifL1qw0iyPrYn 0X2e7NfxOCOkjjbC6khfMg3tCF+yywD8AlhtU5ttVlXlZHTqPF6fnRrW6iQ5BUxBaaI8uZDQ XHZy2v1sWwfnhH9tx8Cgbhd6OXPWvB/FZIxEr/x1Zl4Gd2KHKhiO+7pbyNq6G3boejTS7E1M rDPuYWhGtRAKunmAPdyEJHXxkBrsHiIgpYyabv2rhW4aLIWbLimepFKWMJrl1Qdl0ySnClba FN+XKGdR4OOkN5Ej39VukPTDORcycMy4nAfbMkkdpw3N2k4jayfubrDpQ9ozkVq6tssqQ/O4 8zPEp5idvQOyFarzyAl03SsqIp5ybsooYTm+dQ9+MCHLGG0viVIN1Knb46LYlDLhsQF9NYJC vQlF0hMnTYVQ6s9JdVJjCebuPV/tSFMko5IBANlrVhVbJ28x9H1EviJlZ2EYCavUmSvwH5kZ P2aJwXVeC8PAnCk7znrL+8Oo/Y4BT5M+o5+jEg6IqiLMp2FVbv5CB+BPKA9/N3knr2bEPVW4 73MUqewVuAxEhG2SBjlL86hjY35yHAqtj9z6CTd26b+OJhf9wd1o5nLhRsm2Y+KKEvG/glWy WNSrgLhAjwO09+FkDtEt+/M9nNO30CxQtRr/VJZXy3SkKMiyTGNJYQqRksAQFHUVmQnhIsxe tRB2Qsm5r/bGKbeC7uSQQldekv9hGmJHre5W/EJctPj16/o80FoHEyj9Jmz5/qjL8T/CzuGh aFsC2+zH1y8WM+V4zCBiJhdLxutqnZ8eYRwTRirgWxGmHz8tq8vabX88fKis9dutce4K7pGM ZkWvQ4p55r3ir/MYpfCQdqvWw+XQtmqhqqqcc5Isdv1FL3AgJe1joVha3qbSBjxhntA2SShc jpkIIS7uDQg4caCiKMbPrfIyQUZ2K4XLxZASJhzolI85USc3uNTl340S5gWxr/sZxrNvdTb9 rLnMiWWVm09KVujlXzdvhyR08S6BfGKjmn0xs9LTi0u4BYGY3XTKtRmx6DxJ56RgSKOfiGTX LKcISl0iFkUF7g/sVLdQmqebw/WOPgkdK1aQwh1bO1G2hqzyZe2OYqT2oxMT339waZEqSpC1 Ckbnixe7D7pmyK4bWSRdM15hoRqC3WjBlvG1l+3BNIi3yTxs3DbQ/6YzdBr3nTVtTZbH8ryO tBJJqRawkAdOPHuurTdIlgDxn+4jfLMYwuqZizhBybXl4EvX0ARLF1ktltYFaC/25Mzcg/aP NuRBRxRivq9no9g6OVHZn9+bkoRcRLN3FWj9yYY55vPkNUGB4labPz5SWPonyKlGZkXvOihG v5pbCGP+UtdwmQQQaAOn8RgRTGqJc3XOrJ4L3SjluZM8nt6uAMZVBLCcYlx/pGrRjaPSZwjJ At17kvZBIvlXFJYARzzCDbUkkqvYppKSNkiIhrJJQMfwzyKJer/DejdG5vKKGGupt4F7fOVb Rs3SvGPaMwJMmoDi4XjkfrUmkzvspSgx+o6f7z/5whI0L/PoekcStODAObxnZtu+81pBEKTD 5ddl7jiwTAv53/WIn1tsY9ktZobcVYRRD7mU7iPyqnB4n4XiDdG2KHd9RzB0Pi5IiPgFgLEn dp/AyEbQo+uEA0q3UOdhkkDqBSh2sZUh15vTgZEE9nEoxMuYdC8oT/QOb4r+PdRuIIB1MjWy CRFO3VJobdW3ttR1FIAi8VzHFRly5YDRRJJ4l7Xt5UA0LELZa6vy7pV0CfwydOND1lp2m87q xMOkybE1Ws+lCzpjG9JlfEDasyhnRkSCTArDaFMlufZHpYxR/tm44SFByHsNEhemrrR9abJX rZo190YdcHZzKIzE6CLPODlsirUW+CjbZsg3RQGbzOlqfTB4i7uh7aYHvx+gz4G+3y8ILqrm uFCFkj/qVegy7Zzo/HtFaIWRsPihPdQ2XjeODFEBdhglFaFMFZK542b057rY1xNAJLoi75ma +LsCncsmkyWgHV4lNi3JzhvZ3fzKgjSpssJvS9wbFtfR0fUUvR4FbCuOJK8/odYweCesfshw EK8pnBPaEhzz5hhxl3zeaYW2rdGHhEijI5ed0c+6P9asyZsb04WygD/o8UEReFXX5s6HvwUB Pc85fj7hIn8A2VW5/wQj5Q6ftCQXZ9GTplCLdA+iCLAHWyMdAA8/Dj6X+iPg9cJNuXE8QKMk 44/DMXUNO2cHi+4KIBPpNITHJxUVxXlKCuxx+M/WdPla1nzlruW3SQVjHeM006YA1yZFgdGh 0T2SZ9eL8qc3fPblElyh9EWNKX/1zvYzFL9jZOP9h5CQvKrXCGEKElhgKvgEg3gUBYWRTqGb nXVftivn4kYdFlPfOXcBvl3Gk8ueVX8bU9EYv8FI01RRD5Qy8fzj7OlORG5xPe7usyLzGRw0 F1qnyMNDv63vzUqftEM9n+RBcMujIfdYzUzdgIk/0nW/TZOcZSXOynZe+w3mma9uZYQC+Aaq O7vG2/Wdx8GalrjYR+Na0T0D9V1iBZQRxLNip4usWJL19WiuRP97ULVHazOKzt21p6wE33Ck Eh1wmgrwsfcpuijHlU+HZbBwjSv7udbiseank/sIZsjsPgvXlvgvqweGMxEtEg3afTzsufj/ VhV1pz0sJ/kjkobAMjlfrOQxkn39PTtCIm3q1b+5RmhQhP+8Kj2l0fRFS1Hbr08RA5oApDom Cz5gAcuBhdeXIbHlELmgqd3yQICkqUV04y2FMUT9ij/SFMCSAMF+B5t/US0aqs/OVZYyi+Lc kTqniaMzyZ8Eyq2Uz//jeBhihZAtV5rMFQUeUvsSQnigOk32RJFaehErHmn587OR/zh7aFkB sgnwzgaBzqhCAjC9wM/15tMoDfcw3oJlcwsCIF8r0V0I1kmYo+KcaH0O0mPnw+OvGf7mKQW7 f9r5Or3sLhyVLx0ivKQfDisCJNKmebO+TGAuXX9Wf7udztU3SqTsXS4yH+W2NOtBd1YPU+RO xDfqCCyeI7dnjiOrCHu3hND7YV2fe660kGGjODM1TafWZY8F2Gw5VCPzqshNm1uYXF76NX4p /FNQbUdXv8QZ1ZVwVPpHgYFJnjKQnHX4EkUGBv4EGUfNAEMtBZSO4yVsArF+Fio2ViJXe8iV 6BZnkKvhHHACMQBzEheUJOH7fsbhTuwL80aACV8GylH8VwzfaiWZ5wp0AvgLFW82MVYQZF41 deUjtdPXYYXjK6BY+7vXBzTa2e0V++fjPHF52s5SK0W54LgdKaYNgX30W/GCMPXhDEbXPMOy 2c1J9ezRvBmnRwb9QP3XHTEdt1QpQiM1sc4WI3bg7OhgqgTPPRbsB9Fbvf0rDUVGn3VoFGs3 +tOOAbw/KaC7Wcsb9HAJqpbZ4dUkCcBFR/d7Q3Gk6qCqFewJIq/sDscc4kus8xiL33ilQoa3 qzknCCQeHFvHzDU4giNqqjXtdRaDjNsQUR//DSa6voODs6h5vpHQF7NDGuFDyz1K/0WLb0S3 IW7FsY5MkApuOAQZzP3oncCbziLFBloPCgTiDzRPlAK/a+/eFjsxTbIX3LSFuM505aq6Z8pF 138meHTTj46b24jV8EgHhakALU5ebQG1VoPpfgJjnVJ3MsTUnI/ugcvr8iRFK3Pd9hywbvOs ioqN46V9Dm6Xyw0r0y3gCH9Gdtdwn7uWTypECKaC3ZKjOzwMx9nqHI4UR8fhYetT98p6pLLQ NrU0YnpQ58CE0L0TMZvPLbzrdQkOtfHnvbUCRUoa9TiBLFxK09oR9Bj3maesxKaGCNpep13w qzIBiyOuyaK2Xi/4mNTVQ+/0uf9xxREnGf8aRP7qn410ZLoT3FMhbXHm6vdEq/Bg4S5d5zAb Tvqwo4SJz3pmWxBoHVDKg3jlmfMkEAY+NvxJK093ClkHIy2bYTMpqgnsRm0vwZZh9X5V0pZw Zltw0y4+tINmcoQbP85/dSjLFHAtewys+A2hyMVW4ncbLrmLoASqtRRIgiZpSVFQ62t86gPi i6SzWZ3K8Tq15h63H8cM0x82WY6+QmufRLle3QNRNN8LwaqtCxzsUdpM9SxPjWqj4cgWTEZ6 Nlnfm8Y79voyluR8zxwcMfMgDNTjXqzPGZvwIbCI0PZVyNcoBczFRn5N6MZasqH2XbuiWoEn A30C0xux0QcZe0Im7VYG+A+NUldg6VJD5evFhPPN39b2mVPbg4qX39LlvBlrM+Z+ZvWMUjGp 9NRjI3QdPGvKRrAc8vGAoe4F3WA48dBlsPIEB7hGsszkIAc4TOYSqePwKy86nnvBApJw7eBw gTj3bYrHth3e+LRSoPIFvu2A+EMp0YZyALveLSQnj5mLigFeDWnZFN9eKmUGpaNzHngrZA6c MNiFQ10LBGQr3o8AQ7r/TmIh2S0q1rE1usglYqhFkE9wDubAtjbiipwv7wZBAEY6hjZC9yO5 or/E2Lse9QfGH/rr1IStTsbm+5txbzXoENCQrdIcuYLxchwNXwc6WrGqtJLvtDbDNVYB32hu ipesYjGc7s5oq5IL0kfE/1cCbhgNESOymGCXF6BWsoVJUbR+7Ar/D+YxE0+Dmf9gAU514fv9 jNe9p+pkx8weWodNHntE/dkSJxhDryk7LfuVSO3cFD0JRxTZYVKyrnZr+V1vE4Y0DfyLTeLD lO74ZbZOEAW9/F7xThW8NLVWeChNQEcfQEU60LfFPqGbCa89pb2sKhd5SwFX9QkOdW3v6vg/ hTynQBT8c3EpLLJkw+YU+tK0Zddqvusyt+7OA9V3Riql48pG9mDciu818EsfwybbH3EnwID6 qce3F6PKwBOxjLuGdiwcPaNTHH2Um5jMSzEpQSyrRJSh5p8yG3aQXI73PyisMCzSVYku3KyH 0bpbyy1jLgjetE1ejEDeBBZoT/PfeyOse8RwSNNsRsZN0GFT+MrzZXDeik+Be62HWT9z4j+6 zOeqtxYa4SarGDHmLYDV3ACTD9cDNeIdw8/X2cLDJJU4i9irc8VU4YZ7PmMtOyf79Rlyrwno ltU67n0HxqhHTaQYsGxSj5Sgmp+h5P52qwG8tuVzHP0Rm6aMw0TeujRhX8OBPzPIMhK4x1dO ZTE/yedMk0gT3c0eSQyVjgEAZAuiDHF3x4tFOCvDYymuhCwo/YVE+akUATYfUd5D/Iv9Nc80 XiUYBBp3fWGwUvJUtbaEudxS4HONBwP6xSMuQZAnk3LlBhY8bEDf/FvhmAvoyHX7osRwF6PG A+XTG6ooBiVCWVkR8odeMnzlli3e+UEvI28iPR/SGVy9hrgMF1B2kDku0b/wjcAVYLMOQ7nQ 03ymnNFTnlF/tDYI/hag0KTMfBuHjTtkG323l9U60cJqwPs6Q2otgyKxKDru2DBEbXZHRuVg 1blJ67CZp3xQrFrli6QnlQaNk3ivG7HgvArYLg+JQR+2dR0b8aXe4/K7Yf///v9PTDyhU1Cc aTVw7Vh8IJjc/DdIC6wKHuezhLJqwfL6ho5twZennF6Uk5QXfYeyukIOnWsSq1crWdQrcHtz s4jm5nCLBUTkXMjpQRknFoZ33dkqOvaBNBEspGOW2Cn0BivYs6ATCx2TK9FvmK6EjiQHLa7q 32zZXZG8Tde7BfkrssvNMBu2sPvrwORxtMXaoFgwfuXn38Aue+r0FRU29e9WsIJyjmQwZdsU VuLLHhioahneTWQ/LovQU+Hl1JQztWZi4X4MuGFgtkYQzfJJlgx5B02LAeDPHfPt+j+8job2 +k36G9raB74fJiwGtgTQmekMFdtE6odCBPxA0qtuRmA4jXq7S2qIrjTTGTMWNCOWX+1qEjCQ OrsPfIDo6uQ1pe43w07QzOUTqkeJT/noaL8xgQ7KeIAqvWoR6ruDhv/v+UG6hQedTtcqWFOK L67l+ScwjHeyRQWmqwIwUl7uNE4NeO+snKXybOlcfx3Ff0CvIdwyHE5PEjmtjT5iw52XWsjk Bsn6+tJv2ZosOFmqY6Jv3uDH6RPg+n99kiU74Ai2kAoTM2wnDJE+6JeMQUnYLn6zJ2lUvSPu s1IFWyZPkhKn6f0aP+ydY3kKelYYXuOpViNfR+7+rBYJxgPPQXTqUK04wTaZkO4E2J4kVTEF Fg/qP/qg8uVV+BcWWPls4YWqvDOe6UPDr/0DKFrXj6f/kWwWr2fqXgW8xHC+IM2dgLT88VH4 8ovMNnDzhX7zwKC6fHvnKx0F0UCqfujcbq/MdKmwiNfLwNbzacwzaLPS/BFarf8VxoBI8cXo I0cwNs4wld7uWpLUE9w6w8uQqHf9mbaOc/3oABO05915t0IzdhSTcbpql1yabCqbxp2PeS9Y KJtL7hBbxPhoXkhaKBfT+noQathp34BgLvyGcfLVNikDO/rxd6FpLlHlG0UuEuWfnmcoZNtC a9sYWforiNjGzK1WFwc7KBa6eK3SVthPuSHta9pc8ExS8nMlUX8zpx69ftRUV+YtdgbkUI7X lo6nNYjWkVh1WLWGIE+NTG3YuSEUAJZelOs9hD4vBergcRFBJ95vS3bj0v5SaSZfjtbtPV75 VOfs/JqjSbgGFyTfl8BxTjp5EzkBf1P1mdtVr8peGcaoqYzlAD/XF1BBM+0/0Yp/WcwsUzj3 33DxQP7CriOk1kz9hRv8VMd0D42UG+T1IV4ppPMRHxdtcnvlkN6gFq6cPTR+xClNI2alMLBB cUB9Z6YAjRzYC4oYS8ybkZ2AVZMYVBbew0PTWaJQgSv3aUFsq8LkXJQ/9MWa7FudCQB4uOZC aHe7HehI8GKvB8y2wDw6fuy4nCVrdj4HAh1xDft/tUg8FNuYrpoOhKcLaJ2bKetzWgATK2rz 7JPvTAziP7+WcB+QmxfCAB9i3SUNGiiAvIJP6EIqFZm4wMkACbzB3nhfw7yF9TcBcKPWoRs2 MyV0fT1PLyEtXnhNDz5eL/zZnkoL0TY3V6BeiSUIRQhRmf+VfQLkHpAtMXAEfk8i130HZ8GY 8LWHbH9pl6BwNogSJEoaSMumc24Xw4udk7ZI5RJh5UYoFyeLlDuKQy85tSuC1vAQfYwezAeV CPwAn73gc1wL9jnwkZbvPxesrkluat73GNi/e+jmsV/oIiIiwDfasE7hoxeUW+7gkftuoc1T C8u82efvnmsgqStRoCk5NH2MTFK+9GDQwaaWDJZT6po4gYXn9urtKyIAXCBOEOywZ6ddptKb cH9Ha4jch0cJN9wSHZ93Jsl59ArY51cckSPVDIB1dnOlkxfQQFAmqgE6zfKgkNzSQs4k4uhU V4KtLzWoIC5tDBaEZJ8j389zqspvc2gCs8UjZuzI27aVp8ber8yzPRs7pOKV9jHQc/hsJY/G adfyUgpm57Cr6h8PUZGixsUfG8F4y1VNMo3nN7FNYee2ZoLrJWlm/vPZFqGIgWwe0Si/6YKH FR7IfxpuJxeRDnv9R2+By7dZPkR9sl79iady2sDjZeyWb/lejbThvEwl00u+3cx8ZK0YZApL ukOpbnq0CH1CthFS+AcVeWVKw9PxAzdu+buPvNmXlaR2s+/r/IyGUDKwZVY0TnShP4ZU1+Xg sknCSWo4frDDZUnSxtuYbeHOWc0dbFo8XzOJmAecFmeVxjHQji+mjM2cdyABm/nyo0UsA9X9 j9BptrAdlpFvyYqrjGMicSlbEWF3F1jOfYzxhxZolOxGPwrpqCbDdugCJEC1jmlUqhxUlxDJ WMAASYt9rL7t2ACjZYfxPG1PGOi9RQgpQ/E39SL6If7B3TSOj08U+GwWReZDDUEWyetiNR4y u/yBeJGNVMNmDnaAzTVtlgq37cs8+4KcfRsq35pE0D2JAQH9Z7BDOEE/vjwOaRb8Ecaj2wvv IOZJfxtbxCxkNVHTKEwuW7aufwrKWUNqw4JFbgzy3SxLCHUROeOMEaQ5KChRWiqDz/rubDpe uxMt2aK+EbAiUTFlFP6ll3NLaS7FUANgKW/XthXJ2feHyykBqCa+pkkKexEjeYrvLwdBDDUx BmclMARie3M6i1d7FFjxC9NJpHkxm24WtxU9OU2nas94n18SZmPcy+YtX5vbnNFGgmQlW+m4 FNhXZsaLgS5mUmGdhDA+7yoTgXTqMV0ODdOb2Owojoi8BAMeguzcUj2+XWra5cSO57bc0YdX GWNopZYWD1WfagM2ZSdZGpsPUvXM0yXLArMoOEsPnyZFEdNB4K3xCyCIvHPI3yoTSal60g4T n3/LteDKmUW2zRxOXlj/hm+U+obexwehjM5K7F+mY9a7T8oMpGpMIJvty27FlDlRvfwdTNKG K19UOvBf9Q9oiBTU1BlA+Bmf/OuMGaQvGkvzAVlSwSO4GBcL+5dCGL92gneq1jxr5uuQOHup kwGfLYYEWGjrLjuAdi1Qymz64/Dq3Z/ollV+sK1Hzhspe9/v6zBt+kIwNoBtcErC4p5gPyLP cv84cuAA3zsA8r1ZIFOAp7HbJtdMj/qoNMB/XqhRR5KfCp7oOobqa+nPonBjESHQBu2TeFeh 1OrGEpTRALyvFbRkcNx+58L5qIaOLmHg/m8jGlVMWA9M3xxpis4Uy7BbopbRQSXkgCpV/gXY YuvbZlAM/eizshfQCRqrL2eZM3yyJK3TegaI1HlM4x9rh1KBe5bEIQObWfDr6iYu6PXEYlxC S6/v/vgy+hvVPpiyqg2MNMZVQ95ZRtT4NIAWGvCfgwCLeiUFXCpcWOaqOsal/P11+sJ4I5fl BQ/qXakb01v+UByLj3aIb+Pv6Ms03rKpJurk+qHZiSfvqJOIRzJezwlRYRQ8jYUL9PMJxhyB AGRDYPg/e9DEjd64Fm2WiRTY/6s2YoUy9axS3/+FudVisUaE0fDn6B6t2GuM1hTAeDyKAQ4O vNE2aCv562RvAbYnE32Dqm7czYvgabXd+qbOTL6ZNO+lFoscGfZ7/0HZFm689n6MsjoqhsEv ulUKjkFowb69L8yHptcg1pSWqitOuSizeq1Uyu5ybpeEs+uKsoaUC3dxLyNyt5Pt1AXo6/z+ MhYOfMk0Oughu/uOon6ysha28yBzDxedKH8jxzSorkFf2+pn7QDJkGx8656RYXPu3rNA9s2x h0AJr5quzD9FRnvJNKRNwbO1og22RklYwWdxaSL4VFEK5sM3tpd4Nj2QvKY6QsMCxPKcshm3 9IGegsi9g8vmzzC8uZRHIP980/ZDSXTGPAYzUGPoV57W680s8Ik+y9pVlC/dFeKaemAi7Orx Oq//9NQsvru/hf/NYkOjS/3jmttRgEN5PYSTfBLSGRfqaCOa2iHgg0Boj0lT7NfL2lTZo/Vg UlD+HlK9Vqh/RH0x9hH893ToJSsPrN/7qnOuN7k0BXWZQdvAMSC7bygFljLKmF5fezONwf/G QQ9hgcDrhT5Due+XuQZSjMS2pmdmi0TjfTezQreRUdOyMacykO/9C+93BWj3N8Z54WGvfzFW s9kdNjHrnUdzgNuvZlXNvwhJkPj6DLAmMfb0MTeeoJ2dCUQvr/1Pko+6N8HbDPrXipzkgmyr BGkl59E6wUqFK2BWsl2RGqJRt8gBLm2vyZwUszQp92VJOpC7w2apPT4XcNm7l9uFH2W/DB2m Hxl3TWuf1kzoq9L0ByT3C65qdaMQMi1v+6a/OQ87FOtMzPUhzvFv1aBHfEYu1XQUUpfLgNIg Q5LONZY/nO4e15hjzk4Yty/lzbmS8QF2a6Ws5Vz/3eRjHUBEKhOW7SBo2wKQJQZnq/JuLgdK D3el4qx33aL0aAyb/VRyTMgcsKSg7ZecrGrsrxWz8KKIFMRjVXknqfAjbiwklb3XIMv1odZ2 x7M8sb/pjttzaSNEb3jLW+2rAlA5QCYGKFspNz+Zg+xLyFK4j5VO9o1loAdLeKDYd8jYpcRm hk5Mpj+qzOsipU3BMPdZTG9fQ08id403JN5f6m1ONzdcPT3h30qeGjlmeyFW3YDy2E9YXTlq Zvlw7OJOyC8/eq69hV/Ug8URUIpZ0Bh29qotEBmRxXW4HKFKLckhWhAH2/sgetYteI5I+G4F eY3CwPZwvqix+feRE1Ka3UplNo5Sagol6wOBDaAzIeoMOEx0oTIWLApatKKlyGD+S2qFJPm6 rv02ARn4bCB/ysNXxb26SVCxnBXhSajQ2V12hKs07/uCkRbNHYYPkZT+tYsg2xpQj1L80VMA 3hK4bwGzvPU5QjChr+hdS6dnskiemnZViUomW1xzGFxBGMwgQprGyNOh97KLwF1P4P5ylvy1 82VtE3iKOiol+wmfRd/ZHh55+dO4ovecSnYPmYfkhZP1MPsBgJWLuK94CFoHw0064TvJplaP YOA8J1Lo7abzR4o9nfKrWLQC4ZoGRGBGE0WfZdFGhU5XCQkHOh3PU5ZtnxUzhmz00VWyXhKO huPdmvYYpGXe1iyajDySOO+/oELFgy2qbDTjVAplVeAFwIsAPY+PHwmPUnuJ1IfT5c3rAqYC r2Is2RnWS7dfJoFw//Az8L4hWgCyi4j3AJUBpqVI/oAsHJzAjKsG6F7OETgCk+fZqo/B+a8M OCkdI3Cdb7lca5bHb2kXDFLu+J/qfLKEzWpflz25C422leXZL4FMLEDTgjRPiMxK2s1jBZhq rr5/KWIr3m/+he/yYaU+uZzQiGEeHAoCoYJJw3HUVvS5sXKqbNmE62WD1djjecg+1opn073P Z5B/a3NnJHUdccg814fPXl/tFRrpmb3CUDHTsyNOJposKTKkXULisTqiXotE+OPLIa+TImpm CZrMkjVdzgaK9prn35K+7qdzeb6OvaQUIxEh1GwmJ6e77jI36F4zkSvPS2Infqs2VX52Ij5A +J8AB0wwlo/SKl/Z63eoZqW78/CfSSnPf7xdF3Y8JB6Wd2sqwdmB0jpadpFc6TwXuBH036uh iDyILnViiCeg2eVcdWUsA7daC6IPFZ+aPbZGoxxB6RULYcV8syKc2OU0DkgmjTl8gy25DtKN m+WAMCJhFWxhoq7K9hfBVdd3Jyfx2Q9O+mKRtaHatl1xqNzT1/MY38lHCORX5alFOIcCAmvJ 2F6Q36SCMKM14VP9Ln9k+4kgdEOFnaOkd3IDWY9whNQKm7pBLyyJRqK6pyTpJZFjneczUawT TTsyJ5Kknu7H7NhqQ28VPBI9bSnP2SaWMX+oVy5h9o9kSDjX05kRbNf1qZpvSQsdnG1RGHOQ crdl4oyhZRcMqEunnEymBXRpWsBt9ihH5R0dfuuyLApDaVT98GkpnEIoAAjP3AgLYf6fMgf6 T9tmGyKSiIETdgAHHqh9YlfJxvS1yyzbsF+avMHQk2k7xpnLjSMwYGOOwvqPIbDnFEUPzZU4 PDZuwy2CGZFop4x8NurMrZhZS8uHjy6lcJm06peyh3rw6PuFAK1yBgy0o+Fg8LE2wxthNeYT diPj4Zlk0drxhGWjn8IhuX+zzfbr4zGffBT9nTYowGyZ7Eeue3ntdDwXT48vaGB+omKalXeo 0EiTz/4fvg/TUnfrZ2EYl7yPy1+lRaIe8Cypis4HjPi7FA42BYOhyjGKx6MQj7ib+5HxOtKg p7P6ZXN6tsZpcl4ZpcfRm0z88TmgGr1lLdVxIRJ4L9kUmWBmBiWl1aMxk7BXmzNVzEch0cH7 n+33rgdZjepWKKzdXRrruLwjGv0Dk/wiuF62xOso7slOpK3KILyP+DBhNm9bri1CAFXGzBoJ lD7nFGbZJgx7XT7uu83tA/2p9cYSfzXdJMTVMcjSPk5OBBAS1YGK7DRS/p/cmrctOpkPEEYd /D/Infvi/wOMgpyKWmqizJGZ1BwV1skfZwyQBLU0snverO+f1KlpYVvPh/cjFl+a1Aap9jC5 OWBk4Kc5FaFnZjWa2FoXukc7P8755pxI9J2ORBP+3VoD8I22R4yVeEqVG3XDuEmMJkJ8174C C2nL8Ypb9bd9DMhetB3UMHpHCrJB7ndAa4CXVPetVj/FMM0fNlYEmPeQKfRk95kNAGR5jvqB Og0gPB2+wtTgurly5fFxkXOaEau2hTjgPCfryI7cINivXCnq6fxxEySkgOBVkdqSyVwkWkTL Jn9xyZ+jgYhusslhbsmwKC67XFN+i96I9Nb6re92qG0/FC5Spsz1MN/zNoO819E5vu8aRyP5 Kx22hfib9bHK9s5qIrNu/HTjx8Wv1cMPusahLGOST73xDipolXaB1XwGmW9ZAz9nvXi1B3BZ 0N4cOBDRcZ/eCFYhuggy3jmHVsXr/8UNpzLikumtpq5E70V7qOZRJbWn7KYUEZIHRvBysfw8 i28vU/Inq3cYDp+YJJvkUmj7mUmzHBVhbR3VnIl18hP7T7jtf5HLGoHVz3CbERYQj6tIyiyV 19Ys+618+MPUhsfWptAVZDC2oVJzV9v15n6dSCYS5+vVfo4w+qtVog1tPKVv/bL5ia2A2a6/ sV2BlQd97HU4qyIAQVETf+uwTQj1OAOPnDbw5qfqe4TcRiatZrMOUzK62oFDXZx4IaxG3H+F e40ijxLviUcopGdPSfSyxJnpYM6XKoXBZum5W7+A0/Z5Or3RdQaa78MrRrJJu0yDEaFHGEBt Dr0XDy2Nbs9+CYLfcGB1vqmx68nQeWpz44pTtL6GoJc47CuMoeEvtOwxgwIZum0shDgBcJ1p nvq6mnXM8WtIE5ouByQwFuFSXN8HZ/IAMBgBK08Of7lX8tJwpv/V6jrEZPpbNnTTZTWz0QM4 3kX6KKuqI5D8Km+hqjGrjdB94yB4MPTr15D7RjZKr4nDbuj5/74M08ZDs8pbg47a26+DH7fF 6VGs5MvyKQ+8BsLIscKfZ9r3qWfkF0P1aWEL+0ujQysyPdBh0u39XIt6qDNdwuj4nRzOxzvZ s+lqxzVa0lf4nUkw48fZjPUU5vzeAQrdGlW1jN0IZLKm/zWw2QDQ5eLVrqqtuhIEBlAK1fZY bW7ZAkiMeFkJu4HAA+1XXaLMPHFCk9mtM7bqlX1q5XyKEaqgIdN+4vGG1EhRTwsGlII+WX7Y xpjCedwsJoq4EEXdgk+uCkpyDBGeh02gAsQ0rS25AqYetJ1mSTan6z4kat9K0ZGA1Hjow1bb EVNi/WE3eNnDBcQoCwUvtnJLd1fYBDUCr40a/KxvNxYeoAQ6E1gBhb0pkcGfhEpRZU4dY6lm Cq9JNKIwTA83z/WiSUC+Ut2/QQ5Sryrn9oGKNGQYjbJ79kTlhuLB25DHZntqWYAj2bqIYpO1 vvHX0FsozSqYsg1V4tNiOmTXotkG1rBT19p72oFGBSq2mRbShzrAh6ZoOpNZU5BMr48xUyfv rv1ECTmqwceLs0iYvDfgFwzCEVkPmB8jlN9In51zHrZd4mmDXgWLl3E5iFA/eHwVg18pw0XM y6+DhSVdlA11rEOfjT7JXLhO69/Ch7YPK1X7NUYzioXtztpz1XbRrEPvpJ5e7sMjMhBTY7es oM5AwUTwAdZ44uWGB9DSZx5IhLqtijWlBjCN91pJeUYSqcBpkWIw7Fa0cRxz+FnQog7Zpxif riPR7W0s3fJDWoQ2ArDbm1bWs2CJAew5TYhxxHaFvU5krm/LsKi3zeYMv9pvJZV5Vvsd7u9i UbXOrV0cLnaJozZiiyGR0+Pi6MSAkuPmbVlitdKdv9E8EVjSyfxbvxsvTjBKVLi09QsD1cIv mCnXJKHpQwb6e2eKiJk2AVJi7UopXRkIldQ99pfdEyUQQj3+4qW6t6DHgwNy7IQv2YD98sDi YGZooHtYv1SI4sfP345vdbRNJ4GRKlTQo2ttCRQUpqCTs8/yGIruIBVB7ifSYTeeor65j51z nW5r0bytwnDtL/INBrAuyJ1z/PSdnqAv0dCRC8cSt0qtAOfuUhZDAJd3jfcpHIZv3i8P7MHr 3sLz+gOX8RCFmYxsoOxZRlFRNYm1icwxIae1Wazq9b+is4oEvOTiP3jj/fY6MCtbMDiuMgVY nOm+wQZnEBwYb4875NeXRN8Gej6HogEszU8lIaMr4n8LHIWDAEZoEPHd6UTJCQb3GV7vsdLW JXvhKxMv+G+Wn6VpGucryTuB2uIi6/jZPo/zjSwFAmCNI8qvdvxao7GFSHYW+ga28Ttz+AaF d6TZz6EhgOgIr6tqM9nLJcn+RrrO2AZRFIGam6fkYuP2SnLIlwHspr/iRWbPYAqWVwQnvOGH pYMVHRdamIL92sFsrm3fC1UugZvILmEzj5UQmlIFC4d+Vxx6pCayl74HiLy2u64UDrLTOhSG EYtmgKZmuWW5G+/noyFY80iSCyHjoxLw7/otBPANn5JgTJRi+GKaUjfI7zGxAylThN/1UfSa ZeVkiswdxhvZ3lnIZk1MVFWqM2X6KYXFWftnOAf6Jt3RTq6IviaOTb+eaYo8L8vMxF91zOQx OYD9aFcShpQOaEu6+LC6JW1XrD84d2Z8Cwv/zM9nD0diUkxqgmBYY1wLwciHy3/bTwFVC38t qRckVQSqARR26vCml9BW0CzSgFnDl+DGAaR7v0WAKwdaDPCa2HPxl+/Hrd0hGIczvFnDdgct X/E70Tkj0wdGd/M5u+i7pK7TGBpijw20/prI7+0dfkZbW77Jr4EqlsbCcq2N4RQTBXArGFKo blnkB+wxiFYFmtwStb+6WzD+8Y31D19OfY3ViaGcCGFVfv+p/aSCtaxzvsSVyYuNM7YINiLH r8MQLdNPUf9jn/ZeyKn67gjHh/ZNKt9JTnHuz9RUge1XWDodCXXrzpGqSG9YNOmpGfg+sWqu 9qcpjsSQ6HzrOfYLt5OQK1jqELtrudkZR+sVOlYCeGiDZhltcnxawZpW7OK9HWFuJ9EA3rCg +qqxUHn7nIg0IE/2moXQ1z5UDKgA4oW+OHkDSyeowoLk0xoFWuSLEpBhYj82ar03L8BQ8lKj LbhhzLyKrMX5r437l7iqqvuBhM4BaciDBYkkwf5+K2xhbFh1/gN2AB9eJdUyHHjSgpKyrIfp ZtBGjkUZZF9tXkvEOJugS+SU/ryVkYGBi0/Di3p8xhUBuCy1jjPCwaVIWSmmt1eN751A3izq n1JxLD8OM8svyqeQFby8k+Df5ylbt2WTO9T27rLr/gIPAntuJfVEsVQOCo6PRxxZgKgx/lu0 sFKc5c1QalunE/KVfl4pHI4eRVI4qOBx6JguwhJTkwOZZq11Ic1kv8sprrpm7WhbfaLCajwc 49NlV5lbROQII7jlwx6dbmmPUz4NTa9dI6CiIjCMufoAkk18vij0/1byDMZIX+HF0u38oqcY ijh+G4UFW/pOlG/HS+PxBI23rlb4MLDq95Vs4mt9+3p1Cdf+oz85VplfMjgGWFQXaykkqEWU n+I+u3Inik5TzPo1e3tbKAukgDka5Mdxci70UhjTv1d0ZOjIv/Y498J9SCI1/Jb4MDwcEM6X 9VB99y3VXGvXXuSQ43AyT9bgFBVOPQzpn+4QFFcMnKig3JYjFwUTB0DsPTADqNbginzLOPPf jxsZWENhki5ysWNn88HZ6xZHh4rPypQWDFJDx+zmE9FVupkzpFf3BtKWMPxU/oNvsuKO7jZE SDs5e3Ynxfd1MCt7FKG0PV0dLK4co6S6iW0aTStFH5tie0cYonzjnYjcwzdRLOH163FJJ2Pq eZ/4UsbMnsjBK8TfLaOouzOS5rOX/yAbavxP91UrZiRn+RpXgbCwkwB6X/UDDa1IdXvTDErc 8uEHCbadln11eDe0iqtV99rHsMIC92y0pfrqrxSUpDNaN0oWHD9JxgjSS7KbbfhitLt7xjkz 5ZF4pAZD/B6uAkJfeynYL4uNL6qVj+i8e4TXirV1v8Nq4S+5qltyjOuxedRiXbHwPSK40tsT ZhC0HQGqPF3tL+Uotku7zhfJObTNB+JMhZZPE1N15rEtkmpolDiWLGZVec3jVyVoi4s3spQL Q+0gdvkQ04dZKOZOVvmhCfXNTsvVvSHqi506ArHMFNbZTqGTEx4Z8aGIdqkA0L4s8ReCRS1v AaPyJvepMffIDCYtmbExYweIDihee+7uYN/6FSJ8gukxa1E1pJTYplhwjN8Urcnfk5noE7iO qhk7ZLNLO0sl+qlADeUTDsH4Cp4O7L5yLoitYFNehujHiTGBywUtmI+C5H6OsRAALAfofnZ+ 0T1KsFW6lNKETR6sQyrPnuh9JXIhvOKRv1JLLxbAsaxBN+lU+vXAruBRXV2S3PF4uoDmed0E u/CpjH2PtgTVNOV7KYIDlO43bRS/QVkYF3CUlexgG7ie0dZXxH+0Y8ZGDmbhWrxappYVBllD zOnygORq3hSUg3DSK7+GS+NUq219BB7yjPcdgc1GO1QIidEoxl218ek8dC1qT4eo0Rbz3aiW ezDA6RxzaZ88uJjsvAUZhuGFcU10tdW7g+KdWvUvVfOJ7a2isYO38haLjSMDWGyax6C+8oDt 0ZN7QAJ0nw2kzcty0T5OKKBTlcLX8eRRsNJBvOyaD8zfzW/IdC4aI/mPvxbtwzx6i2ffBObQ Zst6fGn6g1AnO2Kic/Lw86ts4zpggbB8U7Ogf94WAQKyrCDLmhXbbp3/b/X9WtYBR9WJuUBi BSOaZQjCwF6UIq/qUcwmL02bvQBrtEAGTasV+/X4VIZMMfb/xH5KISNA4Piaa38iEeKamfIB Xu72n9rdJCrnac/fDvjNBXX/pnT8AipNAZ4bpu4ktSK60ZK24lenqXSkqB2rgw3plY3ijO3M xzYIz5Eq1/1oW0DB2nnWPBbZf9fdMJa5aT1H4TsH6UXyogJecHlk9x1uaus44pFXo73o8UQN 4K5HWXt7DnD6GFkG0ByzJen9zy97iM6qKF9chCyrn7PB8GeRO6gSILJ71NZl2BmPgPXuqfF6 BgGs4/5AZx4t8azulUF7D2zhHGeBdljfDDdhiu0p+WqD4uBXxFlu5L8Ad+LLnC1+fCnYVbz4 iopfjJgN+MVHlfBDh9EyvG6FrayMJ93EVc1qwBjlsnVYHDXb+af0Xqy+7otvcAYYnM1gXj2U x/NXEpj7o7FKXTeq7KDvWssSaPw+Xxcgv6aaH9ScljG1tEJGtKlbBJBAp6TToE/TOOu0FFRo 7+WKhJEnhumfGe3V7ou7no5RS+7YqiEEHZCd9d8B/CEFhoSiHgfwf/jlIUuVPRver5o/SBHt L4aV+VggwDcw5BRNk2zVRMkio+0qxfWPXxCIQUgttTu55Oy34e+HLH/lFYPi3lf7XPXdInbJ jdzQbrjl5vsXQoddGMAgei6hkaS8+oBIzPAHHPnTU1LFs4LJdkzOMASU5xjrxTaKSGDxBgFd MyGqo9sbQDbWQvkKyy1SDmOlC8lcajk+RQfxoqhzuTsDbuNt9vaYIytXRzI9h+Mc3sUNwwqm jYbzREszY/yHGZ/ZP+vuAYK97gciykzSWISrZsq9CDfGOgJ7vlgXLlxshk1+V5fzLpB0b/k+ hzBx2/i6Vr2TRV/Mfb7wY+2hGX0eCmxXxTxE5xmecBQNenkUQfBUtAo3fn93kBD68b7yp7+/ yfZgD0VQa0ZfDaPPoQz2eAD/xiyL5T73NKjLeFXfzBpr89nB2AK8J+TfJgamz0DvhYri16yC 0RelXS+vy56q9gm23/gcTId6l1eVmGiWlg26WXZUVO6qx+1UqjZJgDC0XbzXqTvwzj4tUiEm w+7BsItrSA34fdUQOsDBPhiE3Ckq3WS5wbmT51+FzFwjrPY2GwNKWPFC7xcpNcOi7tG8U7EJ IsHqpi3frz580jefCHpnlTxUdQ14nuE+C6U3obA+wdau6wlDGg8tF0SOlEhV94UjhRO0WUcu bNS7UnwADBx+uarJAWc1IVetSY8S5wZflaV6Pse4cfMOmOFehKS6FPUmhXMhDOfwieB8OQ1G e7EmkQwMgVj2sXVzeSEQAN3d4VBhtCiqmpMooeWCwMp1ACoG29oGM+IcZllNP0DZLBlkmcHc 9co3tSoyDNGXYoixOeNmbrq40nmcbcs5n1fXFDtaSr6ZqKaPqm94zbSsn6dv6zKltbXzLTaU d7qj7PUM92NTk8m1NDWC3QeklVKdh/FZf4PL0Jl9Ix1eKmCtebTuTJrC4gqQBxfOSlPFb4FD bMUHqJGYapbUeGyo8alQHywILxbPcAlZvdqTnRAqAoVkNRvUQ8hmrNp4mgOuvRignXFodKyL FpjLSrot5LOLJdUHh0ild9FS+TtanxLUC5qZQjjC2LoSse0Hdp7bKdpKaG06fc/zeRZ2pyvK m+8tiaZ+kpH+REv8R+b0oA4Qv+cgtgQ5MDGCWUiGr27MNutbRjYWCf62KkqMKWTn60NeG0Nm d68k5JlJcRlNF9i2tIRqZCUpXfWKXKhU7BMEjiawD5yEGZnKqlWwUabsTU9Jaqrt8Bj//gbn TcPanbTV9KOr6dBvYc42CZ9MP5NjAEEFYW+0bUWx5e3JpoOlA2BoKar+cS/4F2+Y93IUmoa1 6lveaGNoTypqQGXVhCmKl+oMZy13ADFFVjYVYbYxJ2DKVvkf2HRUY+uV+5fWRC7GVhygHPt7 S27F/XeiH5UF09doYhwTyGH8ANV4gHtN8zqZ530S+BONAw9S01GouPBnW44Y5Fn6bhB0AeBI n9HguwHV5xAX3Mw7wRdGxUdH0TYwpEey1Bu0aDfFk9XgeGQnv3Izr0tU7bfJjlW2CPI6Ngf3 50cSpg4QafpTwPosFnLXad+xLbJiTwnq4rPDe57h7be+GqwaYO+r31HNpjM0TBgUJ0dk7Sjb 1eEnXNlN8hG2i/lwTcv0KXvUbnlDPl46KC+fOmp7tXUxP7ZZk0NqLOaCUc5USAFDC87k53Pm PxaPKteEh4MJbGZd8LTzCt0MBsl88PMCXxJFn2SD9xJF6HbhyW9KCuuePCGFrybJb6TN6002 uVrAeJd+l4lFQIHwHiHmwNqLVeTXtkNxvmgo3+PoyGEFl8T6MknxoSGVMIwzYGm7HG1KgJSy hMq2THCJ6Ws7s4L/BGZiPljFdGpOFEfoKpVih6xkNLINmX87kVGGx5ZhIh3J4W8m68JezmYb hQBk+U3ms1OAhdPt2iZGe1F1sSV9bhCylM1xfOicp+dpr92p/e5mJ91NK6bMM8aDxTyj5+aU 6COLlJPQKQ8z0pOIFDmo2dY37qZzP+waVc3Olcmn5q+xtvkcVJjnwUOtcUvjMz+q++TG3d+J zJVmw/18EWVm6cPlc4FKGGd8SlHnhCEqZF/CnY6uYmQZbp8hurPPG8JrfzvOlPVrBE23c7xa 7LNBrTsRfc3dYzTbNfOdnXk8sSmFYy8Fri8svBipV6yPhUsxo2/f9pD9yHvGO7wKjJlWc03O SgfE0YruPqLBRf5PvbAWcu2SshWZKlBoyCyrxTZPqvtit+qq7/qWGTEhdzw2ajfRyk0MGcm1 +M/Y71J8JTxzRI/73szaX7ioBfrpAnHw1q82rA0JaioDF1CdWQM15Qa5+HkhBRftwgM9A3cd Osge+LLu5OJIgP7JG3O9l8if4G2qtiFdkbNa+gy7qlRUdcmrNoDc7kDBg8+kN2EfSuNv2v0p 8+CdCH5hrGpXa4nUdJ8FMNbIYt1gJJWzvra4EXxIHjyoRybi7RUHppTqeeEX5w3FDfd5udD7 oYEdCtKSKG8CjGWj5okWp499NB+UvAUQsMFg3ZSvZE8P4d/b2kSa3TxBIFBF2rf930JhmGCl 0Vuw3diVt+l+7Ajz/MFpNf5qHHMcsHujs+2ihqpLz6EbthLQmZ3IKZGRV6aYLYCouaJkjwp4 jy+I64rcxOY2z7G9yvOruV8y0kCJ0toOic7XgZ135nrvrHLiCYVV1WUJO16QvQg7MQrGBfTR NyY9C84jT+QXGI0aJyzrP1IRAmsKHybVPud4nzU/Z7ueKi57QSeUJpD67WXBlEEBTcMyZ4Nr 9DR7ZM2G3BPxeLdMIXIUD5IvkUnTjQY5yli1JM6ysFCZPnrXuBvW8lTta3zQFd1tyuOX3HoS 6BHNDCnTCXZ28v/x4X/+BvWSZpFL9P7oZFsJ1QnQ7BgavDBB1D9sl9dnghBSUlvUg6iNQfVg LoaapDw7YUxUIh+dgGvg5Ri4q52Fasuay1QpXcA+fAYihUZdn27uGMqMM6FrCVIsd3/oZBbI e9NMwmvhYF9s2eenVc6T5OaUfqBFI6GB+puGPhuvt70ePpvkrLI3bpFLlkHRiYSkn/rTQSbS bx9ZaKjjRgeClQcKGf1KTrU9d8rne1gGQL8JZXROwdjcWKLbmNxWL2w/OQYBesR+GCVxPfC0 0RnHtXP/ShySPM88JGWzZFWYIoLSUerR4ccIFTT2N+y4UYx5CUQKU2HzTd29TSU0gvNM+6Si Rss1HLbhne2BQx1UpnGCz2ldHQ5cfltK6l36+a/1qcfPEkXeDs+fAIGXhnVrX7etcCLl+epo b2u+aj6wtL2BGD4bbdkoeTf/eVTqNfGDNJjhGo19Itj4owYj/Qsab3hFAlj4AKB1GLB+ywKg +y+8EclWUWWmOBZRadS6UYwmNWUSfBgT2AiTfBtDK9yOkSXTl1t0D51jHa8+/bJIrh6tkgnP LPnvXeZWC+s6dCOYCJ4F3pZDE1yPPCVUMKvzeC00XxXww5uxCczLeCQFCshFF6ieHW7waP8a USevl13oP8Iew7HcSByCnDouVVnj8yReJhd2tcdcUVDgRfTqLV4Ieeg8lzUZl3cm4V7qol3Z 8OKrS9wnWoNV3c778lJWsee+mCuOJz17To3OAgN5Ma4GVod9VU//pEOldoOhw0ISFE9FGnO6 dwYxmdgniJIuKWSQBPqaEF1d7i2pHmaBAYLkV8jVG+1JG1x1aiaORwagK8Gja88dUYBXq+h3 YCwpB0Q+Jnz6mpp8vGTl52etW1oK3WtA8vdkRzcnSUSoWolJC8+AWO1KY8TyDZ3DFDl5FhWd L8B1dJySJqqx2iNf+7m9e5Lp0PuNEtq3LtMVIRf44hadRUk4TmeDJOe9k/5cY6Mc+1wEzBTs qVvQYj7IotX3gk9Chnev0R2k+eJrHLRqSdZyF8RPzxjQx3ya/OV77HgXNxy2+4k3mbNmMVdl 0mxJRH4WWA6ebKNxIJxz84jQNWgNxbtUrpVuqDL0nj7ei1IHNKPN30sn9Dgf9xKCj/QeM9Mg PjxB25inHj5MN1jP2xjaaKEJ4e+/IYkxT1USD0famRcvhROY6jV+EsYoVqjOtr+smT5OE8pl WIjyq9rNQiC1yFAO60IU6NWFLa1wc4HAZZmYWzF6jxWku2USQzXt+FcN9v/bxGoQjzBl1Ifi 9ZtJ+QYDazlv/rXUjlI87QOOw3eq8srg8nQ9kegbuv/iTpVZeKg9PdqD1wkAi8vhLAYPADJS 1y4LwMRkfFGy5BtD6y3thyZigqEo8NigUtiEiFUGCRp18Gfmdwu0bgVvNyoupgD1JmReY/h9 7NqXumhX3jr2REuGW86PRPdyFlaH1FLyfVZekO20+Q7nEZkIp6eVra6tnDvxl9KPMdNxybvB Mntxy7qxnr7MhJ/i5VgEieYOUJlM8NFYGCpplUqZyXuY68UfM3eI7BFjDEAxb+CiNFp94Xi4 MRgtFtHNx/0sthHnK3oIPPjlVYpGPK1wVKWKSoqwTMfRVYzrHTa4KeRZHfFQ8kRX4tIycLd9 4h2KmYy7GAx2xm/3QaGz8lDYDtnX1ypewDZmDOPlvEKvm39CInxyY3JXzms6TI2jxUKy0vQC +lAZqVQj757j9HNUBTLcsMFa3ue729sMOPPlfJCwT4jfY5Rv9BrS5pZRTkAw4/lGNBOAbt+7 8dvRKNRFWg3t7kROs+lqEnObUOm4qOT0Kxrm7SyI5qAQNVPofp1QuhRkS6FUfX51qBf/ABdE 9KgPCRMEvgm0IuBsjh4SDVoKP0duzNxDcBqOavXIy9tbqsLV8CTrbUK2OBg7F3GIxOTuSKMZ bQjbv2Tagu3VbP4HIz0UsKKkAy1KWVIsYwQX0KvIcBsLbJrzej0kE9fiMqEzk/dC3IlHPweR ANoOw4Z6gaYSvITOkFYlHOywQmb4dmBzLv6xcBxv6PNFGJE4y5Ci25od1Ud7+tjTPtQLJKc/ Vk8rrRg0nid2kb3XQjnribGz0VY0Zksriz6OsmexqjgECYSjehPnS6lwCXdBndihY9I+uNoT wWYK+Yd43xTPEUdyTmOF6IjqecBhfFxrgiyHTZGBMqRu5JKtJ/WE+WeayqVR0Bnalrcldq23 6cvRVmJu/JVfM60peaNFMNtG3KjCsVfQs1BETOzJqFfhaUeOHN6ubaNljo2VhzuKblmwa1AD WwOLb5eliE3tngKqA3dpv/m40qYRLY7OuAmC25Ck19iPcJj8dplWe9Q/G8t2syLhWoryIq+Z uPCgU8QMz39NqvfO6oslr2JOJVh9QkX3W9+o7inpHbM99dazb+nvfwEL3De2K/O2ONaewr8l TDn1u6Y/N2nQtdSEARUFwvS8NQAEtBaPaQNE1qaLlMUbWwr2H7sxjmisLLHseOpHXXkxMGv4 /yBIzUit87BM1lRY1i28JC15yo9q7VpLSBz+HyR0PSFjnWICczZHz+vnJmrNVvKYOZdvr2oC 9c4DKwhjyWa1n76h5Eomlsz96rnXhGUneuLPVZr6i6fECfxl6E+N4qNOIXCV3RJPiukdbwzw cfVtVyKSR/momOu6pi5g+DknfYhsUngVe5/2otjasGrKekB1j+T844no8+XK0uHUyt4Hedn8 5O7MSfzFPbl/ARTMIdZy5ZksgtTzxfr7iZHJZNpgo6J7/nLt5tPt5sRPrjICZDINLUMwwVM8 TN5l+kZrjV0o7UWAdn/o7MD7VrWACN71kz1ZEZh/pIlMhXOHT+Hkg/x1rtrd2p5I5RjThMPo lTHIhwmgQR3FEH3VzNcB95jRu8Xn4A2vO3xeCwuwSmleamATUBTfWaZBofVLwumOjAxOEF6w TNWMosrFzcODjGj45DCKnHR1JChlDq9da+w/r82WsVmoBL+wO3V0f1+2JdctBCOT+o6lZW0m tJZa1MZkVgko5JcLOHXIc8oLn5qcM48tpNyO2XCccptQHtVueSGpmeS/fzok3Z0ZCwUILxTf vouyvlh3K7S6Oh34e87yZEGbYBLEn2SlgW85h/SjDOQL3gqtMUhRTnzhg3EWCERBA/a+Jn0f 5xPs96DyUJLFm0UHR+G+JIlzl8ia1TfZ5g/L4OFpaIvFGAW4ogiiy6NQkLJxGqBRKn0zDZkK Fg6aWU7p7NovGJdAsA3UG6oTIXnQdCtUPN6KhD+s4o79SCZ09rbHHRwROv84W8lElF+XNHed YFNRjMEFDGoUMwWmx2oCaL95Cuyc4cjGZwVASnA29dilXLLK0AmQqI6fhkYPYHvx/UdLKN5Q 4Hsh5iRxxJrr/hgTkdKV6R7opHjQzGyTSsf7pEr50YPgvr/24etISdG+D3VNVC6iBWrHY/XU VC9uNsvXcj2rdY8xqVibpa5Jg5roqvjYzDHgBhMxJcrok0bftPN9UGgG7xvAlONGNnS3tpgR Kwq32ug0DLc2IQ1oNeyFWFqfTiNgdc36pqFUbbYmPwCEIvbgKlJ0KRP9VCZYHZPUR6hoUrYO cZAypB7yoIMSIK3hLt4ipj5DB0yvSrTUvRcsLgLGnnkQOwFd2LtfJ03Uaq4sDZgv+bwGjV3M ginfeG1vYj2AV66T3+QatAUo7vrdz6yoL0obpX3LjQNU6/O+ZFxEOdE/vXGGHZyz0KCNjlLm MCQAXBnP6WPSg5tXNwBwIGeUVaekrIQsh8JrVxQJGnGzDwsbcvptRzdvjnkAaL5PZfV3mDtS ckjwCPdfzgEPN0P4nwF8Ot8ltcqp894/X89LlDr0qzjnoiSBwXylNIWuFzt5anu8coHOJt57 npWd2Pmu235jeJJ/Lf+S775c3diavJambpOEHFwh0g0SYSNb99BRcktArJWothlhT53tea0T x5cKGAIShNmFdPNG9Cb6y9Yk6SXCe3RuHx5UqmW/DI50++jkcoXZjFxlNwyJ7BXLAxnTEOjP xlTwZZGJtCW8hucmHpCOLlVNJdDZumMy9GRh5OlqCYhk7i/PZDtS0AIl4QadKMdC2Q/nS+VX vtDg4iS7kbh3wVubP/m5/DD0NYF3bbbK+3SWO8etPn4+YQGPSYfhAIdngU6VFS59xwmvtmZb 9CBfTV17ce63VnpSQwLIgEL3AcayL2sCeLTJ2aoeT/ZAw8Cz5pNpsOsg2iYyR65MZ1RgY2nv fGdY4YIWXXG1Ua/nTPu0M63l/5454qnYZxT2wvpUmqNc78hmwyY/0g2FvHrX/4DfxW222JHo ZEmRAfIL5ZV+024hPcWBDvm7Wnnoh5oz15LJDWTh+LATv4dareXJZ/VlVGvTTXjqtb2wR0Ih t3gZQaz4Mfqqbv9mGP90IuCc1XsVA47DUgP3wQBLhwmwgIjYNq2Dzs9X/0jeNnGfqG2kDlse dU3jVnxs1u2eI0+ZjYKw1lhWldRdSGbHrA9mz0O3B6Cqrpfl4JydYxOtf+55ULXhdx5V+cr8 4k202lQCaFsv/wyAdHn8YjFPLgNqG7sPMZ1YZegPYYmGfTb3WEKAsMOl46qC74qOKfRN5mvc w2Bw2xAPlk+7v9i4WtM5D2uJ+a+h6vzzszc746yE4V2EBD6yXdXJ+IOjUnYLHI2s+CcQH+ye /wqh43iWs4ZTOCD+o4C5lE0ppm39SyX85MfOfVGW5HvgNqdNviEi48sxjzzcTyW1tS4PhgzM iwW0sSqSMPdQRO/QlrAv/dcTKrBwQFXHRxJuM1c7eQ30Ku8FNtv8aSVnyr7Q7gUzEs6ie5fk oLk9xoc8aRjdO4YCwcORWU3Jr+NDFQb7fhsymrYaWDdPJQR3Hvz2Zy93otU1foyf0lNVHKT7 p4g2gsn2V8bOAnsWunpU/Dz5k1oJD+BxRdUyNs07OVTJBV1l+qzf1YY3fZ80jzLnds4te6Uj kpSsdRKkB2jazWbf4fch8qCYzo3mQPUzOFD/UWc8QZEvoZeZ7B9xGCKFPB0fzN8VIfoBCsXY 4/QubsVh552piaA4d1xed5jSJXR2vx5eYcQ98OBHy2g8ibtpcF1oEi/Q+DEs+BaDC+4AQX1d dINJlD7MR1xuzMO/0e2W5eIkrHmgYESYJvqJScLhTFZ8k+iG4XEQxeD8tM/VFJoX/ZM300Jk +hkm/EYYhzx/fR24pHCidZye+JG2vqJBJ+qgm2VaGUmLmtE3KANAxP2aiX3vuMnm5IoOyl2s y/NLB6k047VkV4EC22rz3+41xcgmuf29m82PGbl+3/gG7tzBsk2yqjfl2XJ9V4cDmjpfzN6R 5Njo7XPCBbJ5Bch9r50dTHoS3O+5vAWpBAj3Voqq51M673PscP9I5YUjOehIQ6yKl2Etk1p/ p+T5bvjCcCDCHG3PJEylBkwF3FGBlMzKWLWperExptT+mXsyKSBuF0/qGeJN+OntScPHMncL teW1F0yP+KNkTpo9SEtG6dxB5K8p3I/Y/Wb0VRyEuaDkKJMmk63+fmSoVUOXmmc6V8uzPiij tbjuRZ3zTpUYndL25ybwFc9ttvACRMHrR5z4ZKrHyfkSoptwCkkrurdbpu9zCGwazhS+W2Yd ZhEs4Co/JwnAuPM6YlGeedK7d+70JL9QNW0tVBcX+ScNagIaFcEh7gA4aHD54RGjk4mf4Q4f ZhyEN47XO0VyeINKI0UPA1K46Kl1SJp3CpkvX6m+cDKxYo/N3GBXGpXIjC7Y/UXlvnW7uh66 MkJzkwvviyXudTgg4fMA5PwygdMYK+XX/BYl9vn9QWTgVcdUfVZWGEiIiVtOwZlMxmdR38rb v4FRoMJAyAUA/OMogNyfnXiRxAhmCxAYxl5fR11DDJ41tzGsE4jEqjpVV1uHIwSgK0Mg8fff jTDOJDpt1R6J6p9Ya1YtoEiY9dmUi8CmIkpBU9Et/dbThlds+vtjKxnn6YNU0KArTAJoDc7S VqvcFN7BzfWK6Tt0tu6h1awEUDWNWbFWduRUt4Iw8HXW26gUBxDmZ6wWIyFyxGicdeirv5MT buoRjdrhBLRgLvVwZkW3RFGOlsUnLlD//L3KS51xyGhgEVj10itypVmFYuj0520qjD7qtCcO bBAlrC4ppJhQ2wXx6xRJAkqGv+l3DrZXawF138AM00+bqmXhwwLw+MNRJzc4bqhc0xCewRau ASQ1QGFcNFLoUOHG/ZGWX8LidOMKZhUtccZWW65RfBQJGGDF6lP9jOR2RgN+LiP2ttp+Pc1w i2FUO4E0B7QYtNZGeCMXF8Mhr7pBQkfqgM3gDSMTpiXDnsn52jw56gDyiTlpjgFwBbQpKDu0 2MM00ddXn7rCZEi0LfbxTTxC9Sigryq2wYgLu+phSnII1Vloa/adkUgZgvslfofADpYHzQ9V MqJYJxq1+jc7VfxeTSAaMUx44olpRbL4mJjrTphv2EFRMxT0YsOsXpeS8LO/709x8MAjRCPJ TYwR/w4xWGClXtCsh6wJqV2mmvN8X6/CHkLd4Hi7n4tisPjln2qjYxA/6DZTRGnWNJQTxgMi tsuoQP/Qc4eL5fGzBHbRF558usSH13xcOYlF0bQLdhFoyIN7Ahsi3uVEEo446fdVK86EoDNa QqvSVyVVg3poDixLWMFnhO1hcKlOsDuMB2reSjmzqyjHVd/1PpmiQl7GCNxTzgCeQ1D7idYq ifoFrI3DsqNqcrfZt4mwcjCVvoDuVK0tre5zxfIBF6/8ZY9EnJxSFpg2jI8kbaV27ddLvfxr W6bK0Xj/o+S1jSkiT40PT5KGPU0r9fQKqdVZdOpXpDJuFDjp/XtZvVw82hpWrQSmfcffy4NX enxDj/8HjYh2VVSUH0B1zLYDvSc4Se+OxTekOsTkIPGHmmdTjZxbjI3hPWc1xM35piQa354U HH1GmGoQ58MXSSMsgTPegRuEpyENGofKFrkWYfv+2zJeXbzNCNOqEzXqz5YYBfLSFR3z8G/l t9FgwNPPEPtOku3oXkBUUTiyAueTz6MZVCnuOgY29eduHbBX4XVSeagI9dQZSWg90kl68sCP c65QhIe8/X18GctRYeSIbjCGhTzNejSW/VKDyLwIY92LJz/gDbLj1xm0Pvb/pBBAeB7YArxy hXIqpik7lNj2v+V0myrNJcghbha/GmuB3b05IIQ4dTSW/bG8JTn+HhrPZT3sJzBIJ9+wN2C8 TRzaQpIu0fo6eQNbK/5Ej+Ol/HWb/awRjsby+ZL6Oha6sfVfDWLX+b9Xc6fhNLB3YmFjGB9J cJWhJ24XspJYWG8rLAFuG7Rtq4IFiVU9HUSFJL/7GgN9xiO2qjIwz4tsGjKIRcJXuerQDEF8 23Qzz+YB2OpJerkcFjtjMsD0PNXDHhwPaHlfYIj+bb7Yqq6fgnq9FVPwjwrPwXcAx89owGTy yjotgvUiofXpCyhc7Ax5+wF+JLvoG9z+CTK54Ixp/XNo68BdljsSqNAjnMRJVWvm7b1ClJG8 x9SBwH57xp9oTdDZvKcs1rzKV8BHkT1JTx1Dpbxfbn/M67u20EtJcCLIPS8TzNbRTDCq3xSR sDmF4gWQmV5Fj2hKsbXc6ZmlKLhvfdY6FeoU5jjHxu0xQUhF/cr0PLVd0wTBSOt4RFJnfuOX beeF1eWBNJpfLOrobOwVG4YzgLaVXcglixYb01a6iZPaOzRV5Op7UedIM7of1aYsfva/bvLI HUdHeTkrKwWNIFhhWIAbNWhsB9Wjb+CHdiVluJ03wsIpErKi2BUBfi70gD0R6kugxLSlilhz mUg9LLC8EKKNPMPyy1WeD28qC59UcYomuReDPExx5/8zPWf6xjAFJhtaGQq1o8ikQ+t3a9Cs r87ppF9tCWRhfi6stFmCKJYt6E6t5jZQrpok882jnhqx+3agI/zhPSNn+ccFvBbmq7CnFdPH xv/38y2g234gxpEtx5p4O6Fl1RIvy39yHzZwYM8TYTIi7IZxjguV+Shg96wn8mWBzVKv3ZVg pXPjYDTEzc2h0AIMCneTD/1VwwG6Cp/AXo8ceD210MhkZthnxJdggacWKsm7JDV+jTsCpDx2 sGr3+6naE/n9PF12SMCDS3IHKTcvMDmkPOUhtJScsukLJD3OyJqsmxKc4m2+0mKUdGTneU10 4dDD53/mTizkYvP0Wqp5RfYbLuWvSjLp9OPI+qJ+LIDcLu3490KfnN+dr+xZf+2SE3QKmDiO q3utGomkLSBFt+srkBLFz8JFr1N4GmgL/BMe64ykGaHMYnpYawakSrABs30JFnyaY+vR64qo PyTNtVs2ALaFBmd6BGcmAWYkru5xCF22jjtQQuYZ7kVuGtZa0USr1ujAsSmz4ujK4Tc2W7X4 akiy92akcq111DcB8RS9DWtHr8byDqDUb6XGg/UWfHhv/uvfCsO8oy3CDtgaBGVzyyGEYmg+ 9g5Xhd0gAUNy2mgBzF1vk59JZAjhdQP4Qh8LbcSGrupDO/0VclHrL/SE4o2+UZt6DabvqblN pOXvhTPIwjbkFinrp+jFTgCjoPbRkBEWxNrCn9TkduQBMMxJ6d9L2cA6+15uO6BCUTDrDUOT 03glysoTHXaG+wQNXxdZ9WvkekhNFJLOO6S+bwQBTVNpTWwv+zNsentziGMIy9N3pxRMUkVb eU5uSvhXedNDegHaPnyMOd7QUIeUARyauEp1M1/xat9JpLZUvhiJQUeJhLyREzHCeDe9yqQ3 wO3iyjI4PfWPlaf2gA3/BuMJjLf3tt1qULZ2RtbHzdpIo5VRvs+iph1cAFEwj5Pwvg/N0crY iNE8fguhdUymG7g2AXyesbY3WlJZzpVT9jaotWMPbqVx9SnqPDLqNf/UQykHpsCbnc1vpezE GaYkX4B/fmZmSqHyn73nM0wmb15GU/4MOb2wgAEE5cZe3xRioIfHUR1TtJtCHS5TQurG8VVe O2Gow+ixgLoYs79de+1DyDUz44JZTcXAzR8CFH+5ALFjWKI6MDjU7XQ5L4zNVXTJZELmSKNE ar7pVtJo0t+gcSr7GTH9PMEA9GCP1oBNmh7Ow2jo2WeQUvA8+KZ3ygnNtPt9IiQHDr8K38rR 1SS30NeNK2hfzM33sE1U1p6pGeLpcGOGYP0DVJd2rntDSSIlZUZ9BmJImNRNVrDbXIF9UTUQ FSfX4C4jlZqYrrj349XE0fAqsOCzpVIv2ISQQEGvrH+VXLBlpCjB7cTzFmtC7n2LyQklJDqM Jt3NRjUbz1peTw/NTzoeCRJMwQHmJ6BnS4WdAMtVuyBYqa24keupw4oTl99Cn8mk3wewe91G tXkuiXQCoDTfF/KLgpGyoCON1/xeGl+xlFmz88GOzjYt7RoLJHpHOvn1xGqXcY7jE9d/j4lE tVXnHTbUlg1hUkhqm/46SMXucaba4xjhlSa8spPqAasKsjMn4uXB1IzyADXuIkzVJ8XDRA1t fTwL4dCY/+035uQiFBED2gC1ugZiFA3gKk6Ls1rEIsVhMhayBEgZNQWDgXktebWXNXXAN/pe AYrqEWemdEpjyoEVX+iMvUsqDnz+L95TC8e58S8+h6WFAUGniMDZYCywDEFzyGoiDHRNEqxl Zy8mWMoKxgb29LJtk2+itviKDW0MpkQCqDSWcUipgOZ+6yMGUCNA80w6xXtQrRXJRs3YBz9X iwHaLJsiKFAnfRfEqvMc1RnBK4XrU5URRb5JcN+E0eLmPt6zMw8cYSkyouD/n+t9CI8okSFB czrAeyqZlMwZAviehniKSUI+oFOgQHcTDnvn+Mv8Jz373nD9BdXmSibJHldftrfst+/3D3UJ /Hq2KKK60suV5ipkScn/JCnlTtSUGnONc+nliDhr+0pW2EHvdDpNghufelE/Xny7uDDKeVqn nsr3gSJaB/v7J8vT933+GT62pNY6cfDvp15YwVLYEy0TreB78UFUOa3hrf+fy1BPXSZujGD1 W9T11hl5CTrfBrwjjlq6bCsawfJb5yOpkhf2WutNdwLDomgnewd/MQaN7kRXEig49MDtZOWO NmpnZBflUrRxqAAzBOE+7r3+6GRYUCWnjisd9flVwpEuagb41JBKUSzgUr54YgPJDTsvRHJ5 xWHLqWH5khOftWBaxHKBseQdceFismghHME4hvSgewbdesbjby9HIWOrSoD8rWQHy0oIllZp FipcEsiW/heHfRuo1fCZyM42Cz7iyXEvqhqfmaR55b3z0ZUZNcKBorXyUmRiWT+8Upl0f+IN Xv8nEbC/batMAyQn8ufftjb5n5+TvOnhOuye6PWY0whXGaxkCWqEZ1NTFODbHPRYX0P/755R px26SYZNbRXWQvQtabZSlz+Rt3KCUDsqmJPBq1EUFVUQ2ZzafyaI6ycc/hp0KCOUbBoGaSOo vZPMwMSGbywPsi2noBRo26oS0dlfyrg4bifUiqMnRLiSdlhFxFk2nuzGWRrfwhsw1JkJ1gia LefnnvZYVQrei/9xxYGmmEFwtKW2ZX2iwtFxAbUx+bcUveR4vZCOXbrGNQq2KMdzfdEVuLo6 F9u4m+AkPQJ6pElU35tPaXLP2PmFwrfOGiCn6CXeZg0N+VN6Xha2pM4Vn1S48/bOLgg42vAo uBax+njkOZQX0AyHW34NwNxTnpqxzf6nfkrkbPlvzT92xip0TBPOhF1CvlzVbWSjNDYLCjRX wY72BoWVAN5bbPV0CCJedwmwtO8wH4CQcuel4t34hKm6KIbxBqquYdKyFQb1wMje7fMy2mgT NINwV0Tp5P9gVDbnj/29u5vHRCed3/takXhRD9/ZvZbMhOckAf+MCf7LlkVRRde5+8UmapFo NRtIcPOcTTsWFmi0A3r25CQAAPNAxD2yjvNSrMiV47hC+UTEo8u5G6aKRp4/GryeJIPzCxZ5 3mhYZ1cQURVqc7w0VWe8zhGL8SPP4abpwkjBebK4bEbvLz2OM8EbCtywS2u+M9Ei9gdSAwdw xtfpHgUMcmEVoTkjXD+iErQ/lnZqxf8F/0Ny9f9sEZOQYwK2+FATJUOU9yruoWWB7N/92GHs 4YLmTKlWO7KyGm17fmFRrFOc25MBWHdVOyD0xTOxzIzjrV8vfP4wLEZ4lhQcn881swxPs6RO kNvL+MCMpIAEehWT3wA8UuuIIsINoXcJl6WiwZUFgd2B9KwHhEUoRb9zeIFhMZ5iJDgcpF+m 7VYnUZaVGJ2oPYya5meEtTh8B4OuhAfnRaTYKGJIO8LNAKoStEp/EqQ0R0rY0ZVeYCRoBxIv lHAX/rISmGyNCgjPOayVvDWyo3Av/b+kzZ5MSG035rkgb7/RsF3lct0F22aAWVZWIJxFaYVo 1d/XEbi6Mhlnfj1Xr/NGgVEro7WKwRraateX/ZvtItQ7gunYuZ8iv6jyEg8EfSj8lcmOdfi6 +bMv2jLb9rYQrnh/inLnz8t6VSP9i/KLx0kw77o+ZDPGP3vRz09zNCsOkU8Pg/9xVX0zTKrF FkNzdZsPq+bWHnpoQg1T5Iby6Y2ezfDbFzRjfcX/hqnWY3GNFy4qf88d9kZwf6YhFE4kbpiE AxYa2zC93deKIzBmMkKyPTpzMPLVlj5Hmfu0miNW0G5yMA7En+3YB6iohvt0S5gLPxpKQWgF nf2GmgcOmiiawf/1vs6imgKgY0phkjzQFkX4D2kNbGNZ+lhNhqY+6w+6J/o1TIEUzR6rZRQi +slzirUMI2v2t7U54vJofwGOFXHd487IWqeQJny1iAfp5upUeORhhptn3EOdqlx2HtjGu+FM 0jQyp9qJpeBG71o2sUZmfD2CaGVyymtDEFJlcuaXH3DhuK6kRHvf//2nN1n9+yUnJyxdUkyM 8V5UwuTfNLPpQk0SQbjksZhHoYzMHNz9Pqit/KvkdgRhcCzCxiGDvO1bHf89neYBfoAosTr6 6klPpQ4lg3kDqJVAyMWFt+jpcDJNJvHhsOmkCzQuXFnM7b56Men721SaS27vctPJq2ZxUWao 8b4++htrBSibwfDiwtVEI44Ck+CUMxH8ttWHi+fbO8jHQhw8V8YhaMO8MezbG1ONco6niVL4 BJfY7R1uMxpAyi3Zj8DXfBncgD5GtMyIa+E6XKtenSagj1t8+JIXW3euP6FfVt4KUW8MR0FN RXTwgCDaMEg8WYwXaRSIseL0gJd/9DKNLoghn+UI/+H3I64/Sga8Bn6uyQdT/swxiLIxvWcT +ULxiUU5nKzQ2O6solBThH7q2IOuNmASLmnicyTxX5VHecG1K3rDEKFtKFoSYOjs0FqrdEy0 j52F+nulRG+MzKiTmRfBw6ndapDQumAXASzETJrj/zKDXvFFYHIpE7lunXKsGtKDlZlQIsuy /7YfSQWVUHCb5cu5zrfLbC9cYCVwQTPkbT4BCP19+znRaOabGN4eUphAWztRCXyuUD5O4f/V B1Xf5tIUTqTXv53B19H1rU2BOiNFVViLfwsLh+cUobFPCCHk5/juFFpQB3myJtBmYQogcIjX 1Wnpd4vBV9mjKg2k8shPP8IeqSi4Nx1SnS64lAHjLuWMKMru6N9Cv6Oi36jMscEC5RhicoD4 Q2cjdXGndHpg0j/5L5q8RSIliVuDxdnOSZR/2VQc923hD9N45xHHpqUhj/aWvg+dKHUbXs4x 9Dl659PVjqG786w2KgOq/1a98XrnWTxo63Y8ypxElpJOVm0orgugNT90VG/QAGZAwtK8DFn0 Ke7N6pRG4uAwgAJSQ1gJC4YOzwYc0HFKX4DYhV8QTcAgdVNxfccoYw57RHI4QPJ7zHOcx7O7 d6jpJ0PqQwf8kx/F+/8igpn/SgjBx2DySJHdAvi/elDRRYRmJjgyrauTZxVPElnXp3pPJOTL HHGfbmwOn/DKqRt8REuGT8ovhumCAKoKb2jEik0c5caFtzLXiwNrdDftygxV+ldeL6DFutS3 6cP+Qy+7bddNzZnlDf3Bkd5BJnefbWFq1fd04mtPohQwtdUzWfpxDQVPp3r0TcDJrJC3nNAm Q/i1juDxd+ipEQ+RADp5tRe3UqerZcNIgLWk06FMa/jEoFebTktyoGVG5/WedRHjjO4bc7gh /RorhxahLQ9ZLB8xlP9Qb1ZQGVNumd3MV52oZzQEZRW+dQZhNrYTqZ1602nfPB+whs5Jx8Ns c97r7msV8kPHbp8GB1txl2ZzOeG2+y7rEqYznOz6pnyyEkUGlCNjj/JrNDxTKJBWeHj4X7hc JlZVzhBARdL8K5/XxYpCdZxCk1/cGU00c1Cs1+JfXVLMSgOlq2eLRFlZpzi3QaM59TW/HT57 ABw4UO8zai46lJNhzlaQtKy58CcepGpEdcBKCJV+E6l+rkneAKUJfNTuEudWji0CaDi778Se JzcwBmi2G7ncBtnul9yjP3P+KlCA6++oC/8cWBJIGukR+bFZ60nzstU1k5iVk7lcfudFKHFK eIuL7nILNerA62G60Cu726GYs3FbRb3t4tc+ibjS4u9HJJA+SpSXggE1bDEtTuoQf0O4agL9 lOn0+I9hJjkejJE9r9oMJhA/JzywtiFRFNTfiOoWyqSq6exwHlTyD1oBDeQrtI574WiZ0eEj aBTlQckgj0IRnbLNfsTLsfLpoZ1tZA3/ZurWMQ8PAoDLNI8343PeOYNtuXpbqVR4KX30TqWX JTsMEAvatt7RThqyoBxGPbrLVXYyxR0UW1pDY4/2hpXROQ2hQBR3j7oQg3cjUhgYX6xTDstw 5E9+7poAYiItsnv6/xWKRPs3K3jo/hC1u9230khO93XRKxeUg2ne910GqBXiOiSSPUY6Je+W 3HSngfVMANV08LXh6fBHwEzVb2O1qTz1kDZzOq9knhEtoyRNbBKjHG8ApuFqIzFvE2bcQRTt lVi/LOGbrZVgmk8fmgawDp0nmH6frYysbWIQPgWPXYVbI+VfnznWC5RSAp2VPKUp+HLowI6H CjOC3G003297nm/weqZANfOZ88GvVHBFexOYAKTKrMmtPE15Y5OCTLCRaXhE7FJmUUoRL9cO SYDMHzScMvyszJRFoljYWl8w2mttJ91B6NY1tdhH9LD9uwOEFHYKTIprLNMrXwRbckydzIHp p0xXXATAtZ5mVb3tN4sHTvApMDnHxQ/PHSqdqFW2ApsaRBHPxQdlAuvzYqARhErhFmUZwfWo vPjraEQfGsS+F9013e2PDRGfUrxgRPdRFziQXD1k0so7USTC0QZZ6BfStuGkF0Wx2jJaehpd btZduyJRd6n/NfLiH7Z5Hb+YdbtfPgKRrOGXaLfDj4y8eaOiMypAZ2FqXHdqVQtQxCnN+mmR DcLDdDTJhpN+KbUskTQEf0eww11mgJNhKMZXoYfFXOlCXPDkt04D8yM6RI4FYiLURpsRHC71 /gkgTx98FozdUruNhqyJ5GKgHFo7mR+HSwgw5Z9Qx+QIp0WLDfcJ6/iXJIEiGrhInfLDj8I5 4XjR0UV6VSwkiJyQc9VnbMPWbG8TAzVQLFi+HuKcwGVAEWUiC4lWs4b+OY9FrSt5PRpaQgEz FQCmq3rjVmJVXg8j5T6lWwYOW415+/+ENr1tMiFbIV/SzLcuMydaFwIhVbL3cL0goznctRa3 +Z1BqAEWrgFDYXv8/457CFWQvsceE+dUn9xRDef5DJLIQMdV+Vr7sFjOSqAaFV/InPNGFaHU 1rsIOAxoEcNc/VV9KkLlwdOLXfVICoBMnVYsOB1GhqiK02C1YoWXsGh2fiY5XwDNyMUM5X80 EndxpaTGWSCjmzC2f0FZG5d+slivstCuiB1/4LHRYsrc0J8hUR+5NoGEZFUIWulxXSkN7iUY 6+EA+6DVZaQ1awCXcW3JSa0++FnlbU/LH3m7uenMQFQSrbP2bhN51Yh55e7nVuMtbroojDEU +IBKBjo27TXEV9a3S2gVCYgesWxMr/tDPjQzLVW6egy2NBc9Qu+AzB2iVF4Hoh1Y6IwnUgnl 8J5VFV3c9oxGueVpdZP2poEAGNfYcakNC8QbJvylmf2aHujNror8olgBnYQsLECFXXWWsaWD fqRMG/vK3Nn+adwjjYnH96MKJ0lVndBQHf6wS7Cv3XCihyDniY44hyrVIgGMK1WDNG//Yq8n tQ7/6kbt1hWdAwYryuBprzbYQwl8c76Gc19E9K+9TG2PkL0HFw61w+nRiJ40PpJeLQRHk3Fh NpqxmrqUlV/pupzBGIbH4xIxZE9btkIZah5PtGO4LFIS52ViJhq2B9iyiCIkvwioTXSAv7Bs BUxzSnSKMNKL7haLZ8DPC6nDiyJ5gm0/A8xHuxErKz4W8++QEdRv4WtrQWltPKbEgngWwe6n hVJ++k7DfgRHUQNSywn5Tc+7rQ4WTO3ez+Dlhz2T9T41S0xWd2BC9TZb9AQLW6uWbTetmgx9 EHGo4E2yRaaRGD9r10NF38lkUxY+WErjkfMe+Lt757f+JJfVt2wmYcgj2wmp4TFCNPUBz7A0 t1kxaP2wD/Osw5SjcPWr6wpytt3XKgJR4F9yeLvjEXTi89Q0OmM9bvP6Syy1RSWSsK6qsX57 3g/MbzYUunlP52cCzEC4LWoPwsV1fgoQKVdaizaD9HML1qXCeMTgHwmcyPTQFK5Claf1ZgP/ PK2hVK0UozcyXso40yBK4z0YzwL5BBWfydVrtLBk+9b6/XZmdY+EBCHPmzTS0Ffp1gXiO9ED a9/nogkoqy2GXN0DpZaIbvjBnvy5SLhPOqBSprSm6NHq0OI1EwKFrxw+IpkPWBGWw7XT3YBR tDcBaAYtIPDUztVrva10SQoTH6wAMfwW/vym1IFezjSm2ecAJgSyODDo2xfVKh+j1bL+2c0O 08v0VCdEVWlBT2accpymyz1oyqj7RZjcJd8HhDLR6aw41JVaPxHLbmUM+SUZCfpmtdJWXhGk 6n92C7cyaOjWvtYucp2uaaBPodHdRkyUTT1uRyxfHXbA5IUIcpU9Di3KPqGsqvSq5/KEbumz KdUxYbkvZX70tAMZnvLYKZM/wZ0py4j4Gv1z2R01fo39bgfnYr54KlG6ugsaDK2mh8FpIIJx QMbGCCYjgOybVrr7On1z26kIQ2KuTrBGZZLQ15l7/hWgZ9PNhkIhiaF+5WrsDtyKxcc/9YeK J0EXOTi2dFkpe9FuhKtfKLcxp+nIwdGS3t4GLsosWUwjPnLZhHobjiAVqQCoZ8SUVO3TMd96 EwixpjTFIrI1sfi8mNlZStQtavVEM4vklPYCFXOoSlBZC7aCMOm0DuvrMUSqwyLqWP4zS+lG qLwbshs7p5/TxrfDO8T05Ja3vXToBu8+fGSirZqs1dIeKiC0avMYgb8hJJVZ9q5I7cnxMkJR NcraGsxQdyHeqizUTeR+xTuBPwnyy5g/CRQdQf2wvIoojl0+oxLGOdI9MUm56lNU4AMBnGk5 gItyalKZCUtMq1ZIBxeFTIZwA/fPSWhH1bLCd1YU4uiQbWHNut1o05YSI1/tGHU2TeZmJGE5 kmF0laaBPpLbLqjnB6btd6EkZVSrl935mgvGefFisVlhYVd/2MDOzPFV5nUP+MoYVhoDvPFs xk5amgoqBpa/J+Ds4yOzYDu19x+gP0msIYNtGmoR8YCrtXfxGM0YV+TO7XRfe9BLxl/+T+xA G0OuMU2kULVFT5B6S80tQUPO2Xy7BAJNprrAmI7BFslKO1hqijZ5BGV0IEzi4qCauelHXTta TfglmwTbKfYBTq3hIHt57NVZCiKAEXRcECFm7C60n7F1AUt5c3caXM40bwqKkhQm6yfmvwct R9y4AnUy8NTFGNiT2npD/0t9u25wmV+guSVFNjmirSzra7qWLIKMPFvWpuOViPMzuddVOk/g 8uVAs/9jJ0Nu94eXaGAceN5SYLPI+sLk3grG2OIjufnQ0sF1PuoBNrid9U/nx4iZV0m1IAQu mi/AetJGBsyKKSW0pn7w+PAOdOm0u3P5uKcMeDoGMVa3eJm3UbSF4TE4VDlLGL+J20LLcDp9 cyqiJVVZn+rnJeuEKlsqYgcwkMf/bwnaGSaqk/Tm9eCCqPDytxgX2QwDXkXvVDTNOiNiBaCK zeSz9sjNqRILY//TwMJQ07mmKifTM1WCoBfBpORJBhC6vWvfcA952+01HR0KIb75N+cA40Bj elfxyvcua+C36OMyIHhiZIjmJVhE0b8OKA0804u4W2dLztjBEqn0J+F2gYvTIbT8eetB+nM4 mJwsPUqxh9GuiP+9k5fr2CiZi9k1JilvULT+WuLT3LoD2NqwGNBmtcBajJtX7EBNkQauf6Rx FnGWh6eDPrMtrr67xW+IHzx4rG/NDJqwxVNYmbPCps7YiQ1XOUK73gbVbikZ2zT3iqNJ2MRk ZBPmicLSoUjK0ygJP9lPfS4t6ALSSPmzEhR0qqodbfJBUiLNxZ6PZR6hC1NaFUIsNAIIkePM AFEbHaZEFRmhTjdmIZqtTq5/ML0EXLY7UQCyD1tX9WSuGYu0KwsBAsRkjZ73VWXS4260+x43 ZCiFunwh/7sWsVKYygXRFID7PYUmBIgZWCrfPvGJv8vjhXEA1T58PleXcStoKDrmQiRA6Zik z6r48BNZmxpxCAdbjo3jJYIYUFsL1O+5SudE/Fzql3rdANSbGNS1h1ukhUwso+0vPQt6fkWl 1FP1Of4mKq1pGfLohpAzU10bOavztoGMssuL+1Jq17AU0MY2B4UzLgF2GZpv37b7dJfzFkX9 B78bxOAHhSONiAfOrksU/HfchFn5M426AxBMvWkerCfzOojV758mio6CzxcDI1XYfMVYaOwH xezCyh/xGWR3Gb5GZhjur3vDU/M1lWe5S7kZgET2dhnimHTAlmn/077bxZ4FXrLZF6UJyyhh f7xqCeZRCPrZ9zwOpfCKGOJ1tc8xm2ebIVMHhJPNnfTqe/1+H/w06sVaI2nH735S/TBahOd+ 3r2KB98jK8Z0XsQZ7egGBjzqS4+H1SzhyaiWaOvb3bMhpjozt3b+v9MaMZCihdxvWsNryqrE uVUboO/UFHa2KWrHaOxsF/0eFTCX6lGao3iJSoDD1xnOwlwAVJ2Jmbfxc21Lu86NT2MUzwIK 7FYu9mcaenFU0WljGx2nOhNGi+sd2cL0s/XMev46sQP1eeLuThfOXxPYKriTFAQkb1dMagVx CAXjTjqHESYPFPg31u479xgll1AZfNoLXUS8KdsfOa/T63nk9XW3oUPlIgxxApwx7PIKstV9 0Qwghyq2HQBUkh4pPJbQoODAbK+C6UYw7GU0yqzNLC5TbffItV4K9gIi4r7AUuubosrXkCTA PTTISJeTL+PAlTkfgThHoll7yWpatfV+oX2lC8ixrwa9LSD6bEaZBOVp011AkSDPcIyu7pzJ 0sja+nmdxuRmirACDN1EmR1e3k6JcEqAn1DAb92GDeI4MY2JjqY1NSi03ZKLhAETL54Tjlik zkbAE2ebd1ZepnfuZqYij012VnZ85Ac1pPEJsLpzslDMRJ5k0nM77HhqCddQYKMl0J5jfORh uO/3N2dG5ZVOVok88SWPIVDbzPRKuYJ4lTkdwD2jpmAFQOqoNCDIiR6xlcu63SPhdRjgloYg sPchl8h+/JqO32EAuENT8nyQMXwKkPoEam2mpJqWif64yKoEizhoCsCyTLTbYo6quFNQUCkV vd9se8pRDsIGHZWb1gu2DZt17a6NZYfouvyzpFEVRggKIO7FT3ej8gxzvPFD6U7vr6gljzRE T/49Hzl5npn1RcUGEqDcXTa5RiZATaAfoiJeeBj2rYnVd0bAh4ICjR4MV/nzrnUdiR/NMWKq bg9JMNB6F45mATdqxuXn0LUmlAUsGw6mjyDlTZu95AzPHwFwRkEtDc+z+UFOPzd0L3OTQ1z7 arGpH6q2GJ0bOyT6o5w/55lgI8z50CypYPSreqIffFBJogAYBjmuNpo/qD2NPXXvBPzmVROp PgrMhJIoP8z2q/r9cErsW80o+5AVamimzblSceKHPmKHqQ6Uce4QK2a8oncL1STtuW78nLGh KS4pKfPo4HMhAoXznUbaIzfZbuUBG0EOVWIK08bWG0AZKSCbwyuy9zyDowTxnBYmCvH87Yc4 IEyT1zOv53u/5/I/Pmtl1Z2AJVHH0IQej47crE4ft25MYKPrZ2m1FMl53tkPhqKdWTPR1kp5 qgoh7tDvsDLJrj4xsYfspX1w6rXLFCyMQGCeo5qOzHQ5DCwfa26PIkg1t0SaE1PkLzPTsbIv t9JiYGQECfocgLy1QFqM9w1NrTzg2Ejfy49cEuDdR7/eOy9ZmAYvpdBdREK6WNs/I4b3rv0t bLIYLeaC/jkWXh8hBGuag8jCH6LsaPcKBMbcj0zyJurGt7aGiEg2pLoFahtZ3p7apMqKd8em LF6u7bAO3bn8f6xFvzOiUOZyXceSLxCvc64o9ORVie9TD6n4jADYlrr3Ikc7LN93yBQBQQPB SIxzf434nDo2SJy7p4HkJnJl0VChtIUtXpuOWlwA20NPpmIQZvcaitLAP6MYdrwZ/PQqC9F7 FptzuK8hM0vnPOuFO2njO2FLDn7kb9CtWq/FHUWNEm/tb876NOINWRHZSmm7QGGGTA9gyDsC kY5MgXyo7Pxu203WPqls4qZOK4oJ26PQ3fkPstC8rP8Xakbdv7gZrbxjWfUOXz9AaoQZsQQi 246g1M1IN+cRV5hK4wJQaFZXPzannyM3pM+GWgEapbpXcyH3wpoqMS/p1sa1KU9FLE5li4k1 zlONKEEmDwilpCvKKPumr9AIIC/Kej+K8gWvmfZZt4FhuECq/qsLYp8wX6RL/hYnxbVFHK20 CEp7/vkge7r+NNd44Sss+iy5WAXna8aCSlAioDu3CB82unTf2RHMD/SMQasAKtPWL8ARyYuP /I8mdn1/0Z7uKdY8fOd/yXwUvg+XjOGdqBv6/L4CN3JswUB6rFUA2bwvC5r6y9kiZlN4XGS3 52jfOM6kVtVt9VPMZ5DCRj/IQ4WYMbyCrWDO5G8alxlGb/e5uchwshFXgaRyMiciE/EIcwb4 uFZAt3jW6ZVtOsZLkUyfQSvS6GHmNHNQ1AlU7VkPs90HSe2uQANxVSFbfz3QSr2CZG2Z7C00 28cY+wFgJ+H6uVLYB5R/e1NBUnDg/K+CqbaY4vanPT/+MusHXoIHZg3K4/aVA1bOMp+Frmim YQV49klsTf2XdPrenjFrGqkZgH6SYbLiZi+VDVbfJDklnFpduFMHhjgsjReEz6KRRsO1DzeE eaRXNmUtVtwIWUflxB/YIVFZ8AHB+y3ABizKAVWh2m/yaD9fInw1pe46tL65vgf3aUJk4JQV nQnuHdM3aMuMHsPAgO+kxavHQAhRoVsS+h0RPq7UsIB3Yr0FgQStAGnYhaMrB8EkTn4uqVoK 4Sog4dV5fyad8sLQtpN6dYj3IulF8hZYsCv0nRBkh/arQKBhP6u07soIN+pNLa/omvAUE8sU 12JlWjvp30UUDQzZ/E7vzkpbnjlx4/aMTHV23cSE9yP2iTgclOjiGMW0osTKaVvkFgXW3+1q H3N9IRiac1powOr2+pWmCoh0YAMEZ3/AcOrrAiiuKo/66ay0iDvn3DYgnh54q91rZsOvC+OQ 8aLK6kIBcTTMExTuHkr1GcAt63CR1z+S5K923m4yz3urHy//L88MS6AJD+uIhu0/wBpHtTcv Hb6EWz3kA1lk5Hup24nsQYG8Yh2fJXALdgpepMzj+T+2K2GFfexoRSeoKsBmrJFxuOMmhZEW XazFrs5jNiWlEYsj5WXdn0I/pb5DF498IZhENkJ4aF83XF0tkqJwYs+JoFZHE/i1HZsxmszP Lc9KeOacCKdyFMIurbBw+Uov5yMkMgj8oL7L9SKY4oYT9XxbpLd3Qf2t+TkApQjltDczN92b ID/YZqGjNqrCotXnuKgbBeiL2K6b5yZm0QAVKCAuQDpIVUkZbterKOFZx0WZoN0Wxs9tZCFV hS4hn7nrt/ZbGB8IN+KrzG16jemuWmbdVjzgGc5GfzfnvRl6OJ9HFBqJU6/NK9mj3nLRgLF5 3e+3L3nrWUUn9FjiF6Xf7DUBVA5ic/K4AfzUkWHtZcx4j9CFni10YD0zlBTdOCBLQyKJbSct 0G6chsWQ8x1Uv1AJ1xOlYbADD95PemV3spwZFrkVuC5EelNVoaLPsxv51Y4jdHx2kJUdphRl ajNwjLQnwQ27vFAtsuv+dBKmoKxYJkCOAc5F9NIq6o7hvfjJ5GoCfh6+7znrgRQ9TfZKiyOq lI4xpQ0Yl8yjDW3mzFgW6+XALqR0UoP5GTh5eo0zYDWFL7ylh862lhyr9e+pWuRYGNrYztBZ qFxi7JNtnQoMbKAlfrAYWojWwopw4+RUyJTWJOLNlM1W4F2HGWRWbZ15MzThYEPCWrK8GgvC dX1360BfulXOW/31gf9b83uLFvE3QDDTJHAm9XyGEEEvvr/ghrD/zWVqMKpch5PXg7BolQox mf/l76jW3uSgdCG50MFHdzsVm0Tc3th8+0bph4IJsHmFC8iFa3DUz211IUKiuyOFelpWIeHl nvWA42THRYtdJfgywhxBurKbdAr03J3StS+qk1jTu/geK8fN8Bfe+de310ib+u0zRO9f/qSw ckksFVsqe72qyDJuObxmBkuKmO8OJ5hmb7zE8XqzfNx4fkB1quFY2AR8xdxg3WrO7CKiIksg WGeBapDnUZXiEUbyTfa6a+Od/o6KSUU5kJTqRZTH5XfSmhjOVs1XXklsTBlp0S34xBAZdL19 FvDwbW6SxillgDkUYQgHHD/ydesDHhjTs1B1w69o4To9aJBuqCD1xJwEGIbxzzQBrMuWH7rv Ao9YKrEDsQe+pl+ouWhDT7DxlKyBoj8XWnC2B33lbxe9qAZKR1NyOUtV70LLDoKDVkc4xpsG RqQElc7U/QeY0VWfZEW85g2E44QDvUrbpvDNQlMdwGaSvMKMpS+1UET5S3LfH26bEppiA1Rg nzS1Kks+BwNW5AAYWOxo098lCRTUw8TDozNbiI+JmQfu19siqZ76TtzRAw7NjfLXAWJga8Cf pzxpFZ9uOQ+nTm/kw3Txaozsdy9Zepkn8GYzB4+p4xLVLYvz89+6vli2X55dMEu10f/qp5QF vgDaOR3nWZ3ZjC7Vu0M8/xnBFtMFPgISAlo9yV9dG5FUNLp0zIl+0yGXpgejUFYijjOf5K9i ng4ljtkWVqaiXzFQV1HrZ/sUNOOCKZAMHKTa7MVyOv4pVzvNwFReidhkCzQn57TVksNaMSXs 0df5WFajrhBiyesO1j08t3jNn3F/RE54D45LtoqxhwAlUIkqrlVwpCzGL7FfzcC190siN/NP qzR3uKpIizo/+o1HeYYSkup6ZxR/ldMgaSVApAVyW4PRCaTwzTN20lFnM7/6d90Oief/pPzJ vmdvaVsNMCDFEYRN3Dov4cOksn1oyY4ZUZoTffG5EnSLEM0wfjqRZFIO6OsKszaOZYBdrMZ2 mm0tSPge7dTIOMpKLsgpyQ4J/I0T5/MqQTRBncwPqrf/kFOu8inqRfTdBD2RYx91VQ0otFVk oBDiD6sLE5VklmW3nx3EN+EOrIWy9fwJpdIndAexpyiVscX/rIabo+KWh2lL0Sm1XukiG30V Jf6ZuwbI4MfBPr8XmeKxZ4c268zpPwfLy3OVl8Hxfk7KmyThJ2RyEt7buuAbEoNH2zyarScc /ESEiTwiNOJHOKqixKGlX1K0MfRY42GFuIkEUBqzrDEj7+PmbBGaTDcMNfHbQFxNM5I+3+YJ TFLn4JGivwLX1XV2PDzMMlXFkb+RbMNcqBmHscD90AXKfJCv+Oi1W+pipWWgAsOCILQzjMHk rBYU24a5G/cbmrnMq9FVamiP55vJrKoTcUdoapp7UylQyfp/M35wIGlVkeC96yR/8bAP2Fnn XX8sl8d/z6Hk3D3kv/le0wSQPbdmYQXCMreVuyK2S+9NbArBcz0olngTE+aRmDUpCbCiyZv+ RhI+sfA9o4yWTK6VvertPaKRBeP4bo+2/X8rp1YUlZEpAKdpn1TZqDksDNaU47FQydC8ZCAR nWuu7EmEPvSjvKrPMhT8lQNtdIEsSNe7/6ogWi+SrQhlF/b61r3FJ5b9zAXySHyTtfGYVFFB utANS0x8rDkvfaPxp0LOetitRnSeMI2ky4Y2l2vRR81mEw/5xZETCJJXJZJqvHVTsUbhNI15 XH2evuNM6Cf0EO3xIuHU6z9allqffTzS5TQlmX2xkzwBjGlnsK2KLFHsf9gRZ5lSzU1u4OpD iXMS/Ee+NAu4LsNy04yQTvGOROUxUIOOiis/0qyVASWd+CbHUb5Dp6sCe4TDvev+DmtENhB8 EqjcJIkszb4iMoTDOcGCJuUGpoACHY1nosCNTfXaMxegXZZejJnOB78+HOWAetif1LHosRwf xhMtGOL67rIiJzkU2ZMX5Z5WtDEmzFKUwNLST9L3iDCTpYlxAqQhwn7r6MaYfp6yxwxob9Nw z/CtDiO7Zwijrl1bITjvCvkiaXwIhR3I4301lZa+39qp/NCxr7E6Or347g87vSpMEtvd+jFN CeppnNb5Z12frVfN039DB5dfxKbj4gIgkzQPbaE878a+M7dOym1jaCzoUldsN+OwVtu8NUyJ v3qhPwgV85FBzhzw0US/7+KobjSQV66+br4DjJdOZ+x1oIizIInwJ6BUjRBk9hOJA87M6qmu 8bjZQa3cbtP6HBx+3xAFFDrcgCN3ITPe63klP+tB19iQ6vqzjl6xoSY0qHUzFlU3bnoENxNZ K/a/BEaA3toady5TkFEgVW7nvYR+5bbecyipVKdi42lAK2KfrFA6BgsD45JIoI0jGap0PCIm +gr+vDQI/RiW9NZZwB5Q3U7QnOevYSb+jDsyC6wQAZOurApCIQhMrl4Oz83Iz1e4I89Ig5jR 8h/ObPUpWblr4x5PVa6zPEi/nXPiy/rOxnQahtShAcLzUc+rhvLKS3zBRUVf3OBnrOai8HZK urKhSTnybx5uXS6A2jBIc5NbzylxmuFSL7W8wooYDBMHrhyOEtuBeX7rtSZlgtSMG1TwuEcH a6GjFfzeiEXtYTxJ3T2QOGJoDrH+WV5eJQjk4jpBOzn6mHR05WdNQDHGVgvKcFtOEKL8zWNd aAzXuivoM7V3SvgkmHvpfcEqNayRahUiCj0p82z1ygjWkX4RYtJIaFUPkG0ExFPx0ypYYbhd EMAo7ULGKxRpU5QH4gI23AU9COnn17xrCnZRGLnGSr7y+9qMWsUBHEFRnB3BgXgnV2eiX2CP Au3xbhwWPg8PAE1pxFmHo/5TFQ5aCkmdk9DMwRaS9VtmmqMiwtCtvXSHP22rAPGlp+U7D3Uc 4wsFSgH2pVagx4he9e/BIqnpiIMSaAaUxRme/mGV2bGDIGK6BdvTveM8B8//6IooUdbEjVN/ gL3GeUytm3y/v91Lrv/0A6aLZ5Mu/1CcAM0hnFQsWqCFDAkyUq4F3u7kz1SQChX4ObGg6GEa yE+F9tKgAIJoTJo9ZG1yQcNLkA8QGo0mp8vUpmN3t1hWKeQeJTtYWV2l+qzyKawADaXhLysR wIDzX2Nll0WrMLMrIikSQDflFZFSKkGJfMn4r0L1NOttu0u6ItJgKjnmVcD4w1LD39BxgjDi Gz/3d/WXWmeFf1ydJ7MLQd/gskdzqT52JRnJCtXLsMM1T1B0DqOzT/5N8A2R1iX1EPsl0cvf BQrKBmTRP6WyY4Dbv0lB/6Jfcu3wvjzNJTrAvzCmCEjFhAfSMCbYMtwG9sKEBO9KbG6vLpgH yzuOXxDegWD4Z901wqfWluSIS/Cl2HGSiWCDew/y6bgCNGjcdN2WGDcM6ILpggj9oNFubAeh fKpfERPYvaQGW0r+Kvru+jab2kymVCu4nWBt07KlEYuvCgWgzTSOYT4BaqNxVVIRsCssICui qfMYx1Ki8OXcXR7cGea5O/hTNv6clwCaJA40v2VW/xomiB6PLYlOAd3SsD08XhI1xW4KwHwG 88LkAq0nLFkztM8w9Ym1k8+EDscRmVqehFF7l2TcisTMmE/NlkDGdeo+W0dexxadaZRsFu0M 1cVGwDbR8cNGvzu9aDTLNsTmdDjiPJ2wgGFFfLbKHo796Sr9zEhpMFIGAyrPTX+3bbqJ6UYh PT6qAF9ondKFVBfpsVL53ajxsA8hBEOJ3NMoyfUyVWKbCARTPThkIiN7GpiezHVbwC8W5sxH dgHJAaRxTWN+DWpxMRiyGhFNPRWHy76AKbpPldvZdKIjN+VLxowNWX79jB7UuBr4Zcl0k3Uk BMXqoVydZ6wlorOzFqqS5guIlUdmUYa86NIFVVBAu0rykLHWZ32winUQNFCutuk42rw6jMMb mxv62N0flq8a9sGeqYV6Ik8nGX+Rs3IbNrq5pFFLCpQNS02TLEwMUnJ99RhllY3F1PQpSedN dKQmnpmlm7Gav7MCbFijkE8AkvjztnuAbS088fahQc/QLoafiCc9VqNZ8iz/peBkzq1OD6t1 aVGuwzdo8ANoXZ3w1vnPW4tYCp9VhkLz2AhKlUq5+soVGx19GvJYIy+0FTPIw7XcgJTb3k+n GKFuuzl0cEbg4HvMuEp5GDHEccczTWlkBo+HOYFfySwapG3Fs/zRHTRMEvb6ejDd+SePKe6U xHZkg87j7nKRAPZCL827MM/+W5eFIrIWm7tYx81sCStIxdyJZINU913Rgnmhc9P3vEI6KjNC vvZk19eL8YgMOx9hfEUDupGiAxTY4EfvtSmmV6r22maDxDNwLsGoFAKIeXk1fxiv/6Avr/Y+ EamUFW86RPsHFDdrGocJmCq8RrULhf4m+G2GhkcVwKLPBRpcO1Zweo7HjFiAb9TCOYJ9Xb3i DIIM28HveZw9ViQCje6PsYfhc+FlSRR7LJiapbkMjye3BKxXWWA4qBRjZz+PESxjGQhOYHbI lXUsRmulxzbEtJJuU62tgzt/4Yu/UBZhNhONlL1Hzj88cuTvYEinncvqsxmW7IcI4V9kH024 9VsCJFOe4TptI6Jps9cZjwHl12ra7M38jt80Q8788yQoaGlrzS6JBIqERaU9cWoWT0s3j/Qv 3ySZZ1jKpbEXTlZ4Tyj6CDn3Cc4nuMBzpYeRo1R07mqL+UWN00DYVbuF1Wv7c7YQCnSJf7wW ybD1NUiTe+XdHPbEb+CXtjWeJt5Zx52shdfHpC5OQ6kYPQ+dzdM0lIgy5R4nz2zvnVH34tGl Jo5yZG7FzS+o4G/Mfg8rJZmhkr424rqXsIh2D4Is8Nkphm7K/6uKr3kpCjzDoVkgJVk1c4Qq SQVHMjmtoVuOIkWM2pM50GU9t+fKwyH9wBfGqIss0Nyi2vTHsA1HR1WuT9HCfyeyIOhySGh8 7XmZ5Qypbr7BNAo2qTPqOUhPup56s5EGCwPqnCLraEC0FRxTw+RfJdqXQBeAXDh/f/6wI5Y5 1QB7+XDBfj1fvdwGnegFOxb5Xk9DJ1cIIiE48cIUIdK5Ng4wayr/TRZEsERkKAywVQHrHJM8 Rh1KObvX0sqpDyR0MBs5FAE/bTDpttW5DwIvg1SLxoTjjgao4sCLhc3hcNtmtSK1Qr+W1Su6 uBO4NmFjyLbat6EIP4wMRjrUmjLn5kg1WrVA7d9AF/BzyrE7i/UYmANw/2yOB6hCpDiK4DC1 yhs8mK1gbY1c4G7CwqEARKQaYMu72luONfNzJmsigem3ULZxU2Em+wn3h7ATZualYLF9Mq7o /rGRZt8xrWvw2lp3io9BdgKBc/lImSzsVTB0rtHi1iKU++sSlwOSO2vIKy3LQYXDih/BrzTl um2WRzUC6gNCY4BbTxsOd9IlpApynjnUJB8Xty8xfBLzDjqkqIdxpsCSxaCl5LHsUlfD6V+G MTllMrkYHqfwgHwCCfLvBPdighJvNlnbMHjkoxE0wwBEpqna+rydgnNekQTjvIK5s5Eb2khH SR6U8E7W+0Bk1nqQAYgqa9yTGAKX4AkuttLKbkJx9uTdptm6OFW5i4Z5oF5ZCHHWcEVSkHJ/ xyH9Z1ecJxjwLV2RIkifbvC49QrkOsFX5K5y6FUHXE05xhzBFo0hvj7Rd1NIXiCrGjBdZIEm DL0KuAh4n2YbEMCOeVUficPt6qxEWq0B0opPXJLikA8s4fl1SuZEfcY6KHLuiAen+yvtPGvt YCGdsGamT5njw85p2SNCd1b862uTQq83l/8JOsJmsq3ByxrAJHH5+4ZLJvbDvxlVq0IWflMG WgZ41n7lU6IqDJUC6LSm+ODCPiCwltEEdopcy68A+mKE2pbd5xlSTLsBF3UWTfg53MTWM2dD PLBD+pqLbs5QtwBpl11RF11DcjRoM/CLzDqwM0IgXtBGKDUc0MugYRWMvOKbRuDjQctXg64b 2pB7J0+EBNO1KtamXPWaC05x4wF0yZlnBRm5wlBuj84nNgo+6Ro4FKcI+dafitxruPSTbQ2L B71lvjkRnEOKBQaCgb1//tYuhXV5A1NdqgU2AG+IXSyjrqHKbVHXgbyrt0I4u2DRZOrKOQW6 curxeBoRJd9v8qQnj48KcgOiYhGJx/+8LhyhyyxNgts2UreXPAr//LLeNXPQx9UUQta9w0hp 5WT5DsNJERp7b+wodq4oST0FwttcWCcTCXqvdB6OypUYsSLFnNANFZbg9PekbvIeCegYcw/H abePMxxWGw6tcgYS9ORPKHhA6FxBFKRxzI9YddAU5xcCOezN/Sq7D0vI8GhH17Pe3GyRQpIl U9K0Kb414+Eo1B5rUaXvgFPpNorlEdtlCbwD/AaxWxKw+kPF75U0xiEDFRdjoLf5rsDyZY2X HNn2bPGcf+DGU07g8T+dvLLyCbIClVx4Crfj6epmd82h2OcWFQAP3maN4+peheOYrLd+3fv6 xwixQyi9QE5/pjtrBAA3nlVf0AFmeF521Rqi8TNDNfmDy97vnwKnofRPWJlkOd/VldB3LDnX U0ZYD8SYlpOK0XMolU4cGKw1jcoBl7QENJiYU/Vcm3XjWeKxPimDUY6uswK8qLSSUdGkPQrs NHRIEto3WRZEXCATCTIZ8AGqb6oAKuSTUJLaReESoXJhkhkXBskZn4yGMhcARM4RSw7X3BYn UeYjh6UaDf9xAuJYRrJabohpvjTesrZQRNvYztDHLeNaeF4tXwEqXcVDeJF3HXIpyM0BuknK bZvsnargR9fYKqJLGTeRDf4DKYVLrBJ05GdfES+8tuoA6L+N19HRfJ6/5lENH4Kzn/Lv0yAa qaoKUYFAafGH8LEpr8J/XbBOd6wj0FRINRN27ve8hgRTv18XCXVA+rFg7fMFjmyRQtuhls71 1SNCJA6YCIN+61+peqYpEBnQKHp9zK4CAhmMLSmL4yTYVjCsDcl5oGRxFGGqSlfNudLg/M4L XBNQV200lU2kiJPm4rizyMDMvYk+IzAWC5eY0HZ3zVBd4SEmiTk97eaHfahrGJjpKfE6QD0z sJNfbGcgTrslAmMX24O/991Jw13T0ellss5BbjivSMgJQVSSw5/N5nwiJtm+a1lzs2arfnkt 3GmALc1XPNCW+/izmc566BcgolK5EISWS+c4pRJNxVEoV3B1vhCUN88DroHmRgwRtPn0wlY+ HBgxZHSoV2j41iauhOJ4vpag3TXuAMfk0mKxfnQgjLdaOxOj1H6R307V63NcxIrxlJfUoH0M qgH3q2zp/UM/RXX5lUAqJxB/JUIrOVcpZGS1vGb94WXoTx/WI4NRCnEQdW5VYdnru0oqdAYj W2jBBbHlFjlDFCz86Dc0U1AfkHobHPSYV/wFx/CEjGMFstNqyKxABQYdVkMwfFtlradiCWK5 kTEjKmsPPrleblmGGEUphg2k/nMV7+esTRmzuE86SvcJVwoSjnw6A6wmy5Soea1cp2XCidhm i5SQQptaDRihSF0XrMM9akLZ5hL9mcTgWlGekGBg0FDP7N/r43RWusQdaK9k/n+RMGmJOjPl RtcjksOekF6DSQmeNA+sdLQKRiVCnRO+MjFhhWtjIYCUO8cXxXhyv86ZUTUxWj2J2NQBPSSz 0JThotHBjL8RFsW9VXE6EcSYSBnM7CjG9HbviRsm+8dnJdpKGNw0h8ZJaZYNMQOkeGyp+EAH t48817nxbqQMWyCFr9a8cSq03O6Wxh/wUFLrUTzKElfXKpCvbahVAh0q5cjRrNokr9XwsbKM nhn4Ot3ZO6AhJDBAb6AZzsDjqBXZSdvnA0fqU11Hno5e5jjQoxKYCGQiamsWuOjdKhiVjunS N/lHBzDfAv3WhAvCM7APXgtoP0mwpDbYARpwo2lB2PEHuokJfTueM/VHxSF1NG4nza/3BB1c wINz/V9YNT4+ALclMPfp4TvidBR9ijZN1fFvYAu11sMgOVkBKXDrcQVOBzDzkLBMP3oUVgQs u3HXtqdMkRDKSEE5sujeMXAauiR9In3Wf20WKF29IHHaKnIfCNidMSP5B3AncGlg5ODPR7+l LWniGqqH7GOQ3/K2Jok/hivr/PlIUN4nI7U6Nm9dQkNm057TX1anHjsOe/cjlR5Jfkg3DSll AczgsPqEsNazaMieOxUJPXJdmydebgr29EEJOGdxkHBlz0y4KRsF6Hd+Q2gR3uCnvwpDFUHJ zjM+K1tB9zjrpx4YjXStr7lnjgiT1TzqUmum7V35XRE7TiWHWly0eCVar7zEVy2i7lMF7krm 0WSukDs02Z48eP+HshzPw0hywP/5/EX2y71qf834h8s2+poIUcZQ3krkRFi+GHYjgnXZmDfW 8u3Zo1w+L4b9yIImqLV57qAKQ4ySJToFJuol+oiaBLfr1+Qxn4YKWS/XKbYD7LwfrcRE+A8Z 2SbELNRnHNKC93kKnqnQbmMsrNkX5P0WW8c6u+7kIkzq+iwyKNDkp7WeXOLkpDSOLmvAvWsJ zRNvKswwdf+x4Y8tVC+4lF/50s1l5CWtBWUKu3ViHNDviBuD8grdOND/CNmC03oRi6Ko+Oou IjBcYvFvpkap7W6Y6rJBV5bvaUhEGcw7mXi+ZtxmjlYtUAubyLeJVcqxABxm69NKTs8kY4Nk 7TTKt+5bOylmOqjAWPofavNNRkBBaDT95BR13V7clZQkqb1ZDxavEf5qTSkYab4ZFcSy4KUT EjpVHVUdMgJls4H2LMJJSsqmfnLYz+h9saR2InSF3yDEV/q9xSJOQ4oXdIDAlZzBLcOzxHoQ nS+V9HjYXJy8r9U7OY4FAyHmQ84P5eLcMKqQFOxvDB+Ul3GHwW5OvjXHrIgjaWsQa7w2+OPH NZljV8viHbrO280IlOnBkWEzHsv152LC80uA2xDxHkkgHsGqEJMMxUwd0h1N7nixsuuPC17+ J6GLgkCNvmtNbcDkmp4DdZe6xikK7awGIgSVbGG4AnBscS+h/ZZDy2IjIkDtgsR8KKU78o97 PEWMFqc0MDjwKAGsBt/mfSIUqU80tgE6P/XU+h9dk4l2OXvlB6vH7sRMSuU+9T1Y7neTVybV awRGBzZPTaP2rg0OyKQAN/UGRDuOH5LGFrC0V3L3w6EXfAVGlWFc79jxWcmJKqY9BD2hwXkY EGRcALL0aLMWXoUNkamuRKHefsWeZbP6dVoJ3qGHssIRAtD/IlU9FyWh8N7C0S5IfVF7RpFW W6h8XeDH3salZPmFfBSV5wU4+3mWT5MZ+JFx5lzb/c/tZrH03ikiaf0d+hfePQ0lEi11lk9a /2ifRa9pb8YDVzISbQrPBw0mexEQ5oMG/y3n7WI1qtWOR4IcFKhg1clLqH8pbu/AyT8DYdNw Y1DCdbXis9f7vqi6O8N6rACKLIKqHwlOio3hmw0z9TCrp/Cc7OwEM3dGjwSGHKgO4Sci3ImO E2jXE6D70jSsD3l6OTsUqdGX+xdPViSwHPOaTXu8NH7TvEs6liQ6Q8JlJt9JvekhOJOB+ia/ FDCfiS0r85uS2swzkUFWTTVx2r0SiY0kbwXNuMcArm2JAjSNuNcEBIOA4JMcEaNDmUDEL7yi 0YDRuJ2wQ7II290WiCl1JPVhNTFY31jNesH4hGfYYpoPoxPZlrCUMAYyN/z9ecE+NiT6VvHi /MCt/5KZJAD45Mn5/ICkfJt9+i3WC22O6RXF2G+gVhrEQ/gIdYRoI8wXmX/lkCmwIG3nmv8D a0leB/wHntxXzNxNtyJ74/DYtNPtAEirR0+4Qytc95F31d50R0wiYlrOCyttnoWKb3RuDMb1 QQx6ISEyQcA5l7VJejUr7BVT4LI8W4eGNeV1h5sGgbo2oy1IF9fOl9kiTWbRJiDjyKt2+Vew SlgDl9xtx0J0DlnHWBf0t6zkSZ+xniqb+3rBFCypldI7Ezjt4ov0sxCLmq2/qoaTjDuPRvdO SJuFMiSko9zu8nJ8UOY9ahMEXRdn5amAq3n75XvnLoNZwfM3yNn4H+6u+XPs+LdlaC32XDV2 tKRFHL079QMZI8MtPpGE8ddWT6pWdFnL5qi8gpQWvvQ5tsI5+clxaXW+/YEmdxcptpZrEf77 /KRuAYILZsgBjyOwqcSkRZvK8yy1aCWLP5N7a7iB44k5wfkk3PbKoolURA0imY/quCTDqboD rNNPaLety/o1IJAKzyfszXdE7HmKtVflFXxXWpxSEZilnYePsg8nXVhPAmHzqnHZFQ2mHfmj zcio/o91Jm4v6SKHmMHC2aHd4JvHr0LG7g77LZtmS7u24G6wri43MKUNfOfL2nE2uhU3Cf5Y n7ZTNXPcKueEtVpLbYNh7OLXAGig07XkGrVMs+FyQ+usiYDSuqxSZAPnEEkcgNng0kNtNWUu cPkpiOuQwtbPLWx0tbb8x4dZ8LbBqzEbwlfHS1ubAqkGc5zS76bpThOX4TvYzZi5sTP4UOZm Vgf71t4avC6TXwufQt7bR6d85h4sQT6LMuN8/es6cOFPbzp37Ox9sFbMAdLsh24PhORTLH3p wbUmROkAaAixJTLXBlANpeS2zkdwhTNoKpP2zdd0QB+7h8gKP8lnUPzWabVe/bDNO1MGIL07 UWlpjcSO2BWuTX/Hxb4uD8ILvalDUzZQoK0YrzuCy8AtVZzJ+h/6Eg5RD3OIKaoCgXsyiks6 c36cftm/5CjSUWGe+olprEzYUath27bWsPXtlpq/COrrmXqkggaX1qnWLgSzfy0T014XghYz 1j+lwFymu1Z9M1nlHDalxKz81EYLKykCPeQg6kUY8P8UPnKX6w0ZV5w5weUUOAgz36/hGVUV 5J01V1v3cp5jrdUB9H2aVQ7re+fViIJeKn5mMv2QGXS6EERWCXEGoQaAotmWqMgi+vKN1O9j TG4MEVVO1q6fe8L5q4v6tmqt/oPhOrfar81tl99wfxAzl1DEvd2wyissMPdKcQpdbEgCksrF B7H/668VWsMDnIjh7waz8EBE/nKHgD+H4jjkMnezl1kc0zSMpaJbMwALDHeuXqk1g4L9Rs8G 0uXsceJ9tllh+u/slvkAx3PFWsb6kcJp2lzc7O0QcsM/exbQHgRxNM39oo9U5TO1LL+85hps NbbZ7GAUo5r4PsVqrmPQ1/0u8oXeDWjOcAzBxHlE665AaYHtI8Exv8ltLqKQ/Uwc1wrmbV/G EltSM0Tg6b6LFj5jJtLFOaB2r35eLtajhipRzYC5XQsib91dNtcG+a5c5wx0Fs6Uxu2M0AZl 7NQruRGcZ7v3gTxxDFFBOZba/+2d60Mwqdn55TSvG7itfKcTE1pgzpCkKpnfjPujOJwxpaxD YedFIQkt+C3LbV3ZXw+M/APRzsHgGsDzbI7JjwLC7optrXWD14HcaYUHb87CPZz+o2ZpVG06 Y7DTAFcPguRqiXW4CE5s1Ooch2/NXpZaFR3SlztqTCv6SpaYnXOI9Jm6jVhmSVVklB6NmRdj Hi1eVISUQ6GEM/bOYdxWrqhNrKZR8DaU8GX6bDblhqgqaWcWbObMRdVnXQhcn+VSCdRQC6Te nlOSgWeVEm+Ah86pdVe9m2Yu9NX06Nb4WI6jH07bL/PFMr76B1fGOXyYkDEpt2wFS71rlOt9 7Nx+gaQCr/SWKFQSfwTzmv5ukTIyUvdia/6AaGRatfCj3dX3gjKDZE0HtQsDV00oiPEQaHYX orEt3d7zDGTwo9V4fd7T9L3Cxio/pl792kILpsPxDrPByZ0jCcBV0gpspnN+YsWLyoGJUqEz x0VwVBrmNR4lxe1bXavMjf6C3yrsU0GxFv2xn9yunUKQKVzIgieAEJuurWjz36trA1zXy6K8 Ycpo9i0ivTdsPjNwa9F7DOVNxHC+yVu7NldWj2R8xe2ULAYENk42NY5B8gSqaTQVP6YFfh2X TLoC+XolPpTIjeNRqeLb+25hccexiik7CfOnR832QABQBnkfZ9wQjXTAJ4X7ru1oRCtOOrIb H4tcxkod4mlAoAcK+Y1rq9hKfSmxNTpFsn8fDwrga+R6eHGeKaO9gXBqrna9qHJNaAm5FHzt L6YZiWiKamnFSEhm6P5ea3nqHjUUV/OJYbrzSh0DimiRhrY4bnUp1raEcB9mhHQOOY/bdCX9 QC2QTfu7YRzno26UZSwIH9oswO/xuin5y0sri3zPx6w4mqpzHOSiNYn+HeEjRRP3nRRsgVB5 PdyhymCFWqahkeYus4FrDdr9UcJKRav9krilhVNqt1HwZ2yTNtlAoJo2RzyWCtJ8YRfOY3XN CIPZqwC6Cgy4cpvMHZR5b54wWIFc2Q1W/YbRv8eSnABksLTM0+SlL7EuSIpcryYilGOgLBox gznwjJRn1nbsCGRKGJ4B3ZrRmgDWOe2cLn66DBXisDDon8O+Wu/lWnU5rne2IKzsLOMgQTkr Oxr37lvEgJh3m45b/MMj63qsi9I6KEZcAbTXeQkbh+UAAFVp9bitWUjnuoOwF1wc4+WRYQj/ rwhfdvrXWIhEUV7KKxPyfXxeINb2BwKaG6VywPRVhONbXvf97Fn0P4CAL2auDNYKdWdPSD1q CFkyGENCKUEZ/szUivpiSlTNhJvEeQsSYivSW4sp7adMDM64UkB922n4SuUtjaHcwJmY2V4X Pbk6HAeWoYapqbrVNXRuoVvWs5UHfrQZoa7hHlJEU76NkwOh0HyGRr+NnaL43I2czM0GYxhd N42/X0Y/23N9pVZ0LV9bKhLkn15f1jd7IXzqMiQzTd642R2W87NYzYOanIJyUaI4Udduhco7 V1EGn/i4wZHmvzKTYfpdGY7OJxJrON1t1D9DBiXVFsQjxbR67vCYXltWw+MFHjU1F0Sx24A7 aRXXcouW6u+9J3Uzl7De5RikTJPlAmWXsP9RhU72Xy0X80JP1kLALWE8lMYuZ0+j9IRbrYAl DMMK5MKWkiXa+z6ZSITm9N/RxMz4BZkzlwxKLo9ReiTpq2c6elZwwMzTT7FX7XvV9jnF7h67 U/eGl5gSUElah2rF53gbpRLMchrpXZLpNEEPHDo+XaoWV1fq/OMMkiGd259kpS7/kLosn+IL HAAC+djTIbbpaR5QlylLjEGtFSF92j/583bqShP03KehJMfEJCQuxUlNZD651c2O84pT4ef1 fNkPncCASsaU+flUDJGH+RrAlHiBffSFcLIXfiocEVOs3CCmc1hoRi21n9G/yenPVYXWGSxM i7ju7Pe+cMlT7GO16TI5Q2xaa6dve/BRcUP2QqB1r0eooCL/2HshY3AmNFdY9Zlf1cHoin4Z GBtk/aTn3EWimMEwL5Nl6dVuEMd9HvVW/tlPGEFU543EPX036qDP1gef7XStaaVJrCjIpK4F tZGo5k165JTYJH4/0kppbRixBI7iipAcpvkujo08hEShMDLXrRoX1RWUJcUGwUN9KZus9TI5 PUtiAeT10ncTqYwUK36Vov1Re4zeIoIyXVnT5KCPGgONroAxdxVDMDJ8y0qyFE1wJeWVFbqt bptVNnCbW5Vq6FA2stbRYXKjK24AtLosTYk4kgCP7DWxUkMiu8YZdlrk/SKc9fJWFzRpZ2zb cmW7XsznQmYTgVd6rd3pDRorC14FY1Iqcl0UM3ZtIdksBodm5BHoZ2ZkHIuIYBXfwUBPCBdJ XQV0Tpwn98Bg33catpnBAe9uTSdw6El1hb9UGcZ+jE11xIieR7fkEEg4peXfYVM8FWAaFSVc Ohcdl4nVc3TegbyAJJ72O0YyUr9b+8/RbG3fO6/3hlUgA8ACyyN0yWofgLeqhM+AQgWbQMh1 IfxKl3qLbdbCr37gB/QOuVEvvb6EgMnBncEI14cLCjIJ6O6z8E99YZLqjl314OdhP44NpYoV WsUYdtor4tLJoY7TZ+rW/KP2TynJSz9QlobLuAy57b8EEPNSmJVmEsteSThNB+Py7rYPJ24C 4QaXBpWwxAPj7jnRdBzxW033QBGCWAqa0geKDwwDe0Jm/pmVtGtdnFqDXbuX8KNKVL1fMzt2 f+oU1+M+oh2zU/3eZwrQginZtP+2EQUSD2MLIy1k8B+esTFYy6qZsjJCRi7uDKT4xkWUaUca XNBcYoKp/O2fRD8ugPro3j/6txgn9/n43K+LhP94qsodk2kwCVPsvbGsCb6txVIdoZkZBXX+ AnpEqOLFupk71fR8c8Pq89iaFfs+Jv2ejW3PT38h+LebtR0G0aRsj02E6T/c2qf21N0FWO9V PDThnLZN2m5sG1EdyaE1LcSX1jLaJgiagR/tvUuGA9eet1F9i+cRyJHki+K4LeHV4yPuv+cG 5XGyKIqmUHuy7ytQPYHNoxL4KgIyjwm50eWCshxF5m0sEqljViaPXAWKF5l0W2T/bcSxYk2D YGj+3gvikwgurbKDmRNM9dLsZb9eRP9nkc9Gd3Q2DU4foRQcb5DHIp+KqmkzMp9EBaHNNHKa YeFVRSbPUODBu9en7FF7ANR79z3/EOhuyD/eXouO9HYfcPFOmTO3YCotnwPXyCil8DZvudSL 7CTn6nVzru4E6AQ73DwSlWKbLT1E75zBXFJcIW3SaKoRV6f7TiblEQrFbpAqZNFopp2Pa//X 8qNeaA2wJ0BAyOkfgmhZ4YHm8nuFvpyYGUxVTePR7+idmfJmyvf36FbtjxIOQryHhI87usT3 JiZrwNBkAbKnS7nxphcudcYVUNaSQAmK7cNBgUd15l+Ao9i1N4VrTLO/aFlYYl3UiyxzmY24 boA/y0vMNu1SwLd4wzyrUSU6wgHvWoHhyhZeGpE3EM89eo8Jsfl3B0JqtPjPAdg5hQO8Fvbf A/uPb1PyXCmXBAJ20lDKI+e0PlJ8Z/4JGn8UIyJiO3YgU6ohZviZP1op8MqP3DWwXn0BBHJX HRJeZsWQA9m4ykG5iKNtC3Y2Tzvw7od+reAZ2sZAI+hoof7ZOiqwp1rb1hz7njBpNTfb4yrS fpOGLV7VVDst1Luq1FnVIXCGLl/upy+y2IL4j1FJbIpOWo/6QgNgMBhGArDX/cWtOShK987v YcWlgiSEAdv/pbpa7BW+YNpevXVf0YgXzD/cghmCZNs6CfEc/6XUtMZEDb8nwX9qYzKV7HTx wKrZdaW8wBDior0iRedx2A9CHD42ygQLwXe/gZdznq5a9wK6C2PHz0RFeTrG34cgzOJl9JvW zWdfEbE2id25aU0zMf4AOtz8ciwPvgOu/8Gt/6+S+vYMCD/IlJIFzsLP54/d5PKyfNRlp6aS QEhmq1WeqzDVKGR6OcqVaD+eV5w6ZWU1bvE8cjt85JVZffzDN9Q2YU55rMZTlz3u6Z0lfGef BHJ4h/p8eCTUEDBh291RvBoPR2sDZp9Fp/Eqt+z93sL+qttN7V/IOO9VqDO8nzEKPTyuvNAZ LOfgw4ezw/eobDjwJUO4hffIp4lP5QtDaARkFcZ0xk8DcSmKGXsiyZl7evDzM88BPCBtov0p BcU5QWmRvZ87pmamWE1mhfasNCALzdZrAqADKzD0OcB+hws3i+L1utAnLeBR6j9WOb7U0yaJ JC4QOyo6o0faJJy5aR+Rdcnn/biHzIclbmORYYQgvFpugCGNVD+ZbZpygpM9Chy7bXbxirA/ 2LZZ8TWCaLIQeMQJqgLlo/sYpyPqYvZo3FXtLeX48hQvg7FSXvT2APrHMgTHfCoSS3a1Wxzz 3kLz0oxYI6mJX397gP7ybbM1TsAV8Cr367ZE1LIYuuQtwagKh7jIXPzJKqoO00GvKrKSDK2i 73/mxdonviUSdV0bapZ9Wj/cJWGYtITfcMRO1/YZeXnfmOMnHgkxkadjPk0B7h9l3+IfmF3P ZteP1hp+TNVdQThx/rmFTh6JaxoSkFopVQHApD+FDTnCHvDT42vFh3C6SQSTIR0JxACE/A3N c5WXi5VCqtRvHnRT2GsyNO8qNyO/WHBnLumBb55B8mTFlfGDJWbJ6ZKeg2/FBHJUCvOIn/dm /a1zKObDHn8SQO6rDVK8FLtbuTo09UFVwwsoA8SzMGeNmP84f75DV9HclSuFIQJpto4Ao7rq NBJf5SR6en2h7EY6RCIpyeq/sUDnrbfOW7XcBfVt/n3OoYhHeIalRwJULK8s1jgvB7yeOs8U UsSs17MlurKc9n7TkM8OOywtApReAkdiBVnnSoCSCDu1tXOf9bDTGiy/4eqctZVBPBfR7Djx pC71GF5BtxJjOhR352aXD9V/YHHPFqE25sJ7ccd6ym3mi42T8AtX7Bu3aEjcOruoGkLd157L gdpy27DHNvbupt/1yjKVgEUCpl1dOXVYEadnJxYQTcFTNjBr7/iN39u3cLPL1t/7iEMp1FAv Y+qz6N4A+mjVKub5coNVQfk7BY00yTiCDelH9pSI14Zes1DAILdplY4OfbmbjvcKGkbQXKn2 OwlOqukEiWzNHL3Ta95ZIIkyy11RejF/PMNzbGbT8ocE7FUpgF6XHqok94jYs4A6KL3wGaFn OYebUIc95sXyWh2JOvuvS/G6khLkUojeQChB4YiS5PtS8XvywaZSrV8oBnL9B1rlXNk4KmQ1 wWf/LAb+0JWv66m56iCdABkG0YoR5STQP21LZiv8CnSCFlo8/ZCD6kM8I1SjFZt5cWvCConp Vm0E2gUM/St33/f3F0VKgsDe4FGeo3h6UQhJ/Ik2ssyRbm633VZfWP3Luq0Ig/uwnmbgnwZK U+aYIkJExvzbz+eCP1AyTdtMp+Kf1GcJt1exKGObo+lKK3GhZvqrsB7VgA9TKqItGbOB3IT4 hUM5zL5EvBbl/z8meRLOTWXanKYi0KqM0TtQYAb87yH/EHWCR0QhF0U6B82lQTSt8DsZ4J7h OXVmfknLcVm2HeESnd2Dtg7/7P82S2FMZfjZdbryRmYlDo154eJbQMqlFsB2vt1/DIDlokLN +obamjzdrE+JcFouwmphnLvrhyNwypWm7El8dZYoZ7yWbj8wutrawBbz20iFVi6eCV/Vmlpc YPtmzS2ufRLCf+OjqPvOu+RYMN7FCV8Z4/GKvFBMVNDOtXHQUFSt8gOmLCOQkNNgvfb2KRpS rwu0xqcUcFLAKhO4CADnHwhZQKN1EKZYBP3VUh4o6CKmQPUHb6P33WlZTYWfNBHysqGSlz3H dYzrSjhLExEZd9+x5f3ckfinJOur6qs1N/C6K6vbsCczBAbdQDuM1/2PKn8N0oNMnmrPwt4r ypw8qZBSHQJ6kJ98sXPL1doXCooBSYlVxQ6J0GbUy2inTkeVK9RGlzkd5Wdm6FPfTPoFzBab 3/7dSU7ByfLA/85FrhANUmeWHFlxcEHjKwDzA+rP2MVn+awlGs83VfYjXCzHg/hmthLnAmZj +eSTQ94znKaNkKwt3moHVh75xAtLcx1R+h5JV8dTkfT0dHLWChSry7NSpqgwnYo3l/KXEmls yi92vvkPR6xrbnwqxix++oPCt3kodINCD5QjrPiA5QtL9Eqt5r4rneyo/xc66cDvYzTlT51n JkpNAa1/Xli/8+WdImMuu/x1K0CECq6xRDXZPncKUlsWCktW5j6+PYmXdZzDwk2piEZR3VS5 +F8GSeehOVBm4oqbagzZqMMRqS7rkDdgPB2cz2ONh/RlZmRRIgbs84nNUs0CV8jH8nzXPfuO KTgvA983FSelxLcLuu/zcN2beGY2aVDJHOnZP3FXyYHLhCiMgGenc6t8ftTGzUWBAg+zwdRo 12/JwAJCnnPDV7sxulksTgFI0Mny8L02SOSTeiUOzetwoocJx3k2FNRev78FKGCeJvWF3JtG ChPleiT1Ez3/syXafw/mvT2+Ae6I1gDwcBJbaxVma892/nwAy48vRnAkodhCfDPNF2jtl2Y+ QzVqWgqnPgV0nGmHZBiO0VYqWVVja78Eo9wLlSTAnry3RK1fyWKwzhLoMOKH8gCyKnd8Dwdd 5xIgO4VMO5hMrasBu8ki7cRC2sjkPZV9UymDjXpCsGzZCYAVSFUCg7fJFJdh7tHCz3VJmo0W IUoRIDu6sLXibpZrnhpuREMZ6gOeCl3VJ2n/6yo9XDqtQ76MCvdEYnl2hHc+L3ms+DLwkU3A uukjRF1pnhGB8wJHy0VM+oHxd2GlG6zqvmkxy0CyvIVt06vWNbpek/axVobFPfliwrhJ3di1 TFALkfkJjB7unTAMPjgl3EG5n6mfNuu0Wm/qoMlVM8gL9o3juFSVkUb0GJLUaoMPYdiuZPpy twWEzKF1CAreW0a9QEMuUhkvFHDcuAaHPGU2D/dwRnH1wUcqzXdtfA49I6b+f+7dqkOTlV1h a21Pmyli7DnD/yPofb1ZBi3QIpyrVt0JKCeBV6yeica8WOzDMtDstjjRB6fEuBIQXUrDxKQ0 OVtP9F3Nalqd6gsQN7KBq0ADZUamkEF3MdiYfDRexcYtakRW4+Kb3zybnSyRGCx0ba+3K9xD b2isG/i69yUFN/rQDJhCPz5HmlmiBlWgXFZ6yYhxOoa/Kwa/VzgRmcd1nShiDltP4/U5aqiZ sxEsAofZfxWfZ3mokSil3kAEAkb/G4rYJokesC14XWEMFHruESHSFpwUT5cEaFh56xoW/FGA zDB0LKWdmUZcVcQaCDEFaRQW5nEnEYq3uvRB2OPJZxkiRJ+AI2D8IWVBjwBx/aaUzbyYxFHS JHTVGJSE79v4qvVfjTkTwslIVI9YBzxO0mdsmfWH8k2a0DHsL2r4JzCibn7ystdQRfx+79KL zCPpKHNhenhdjAesj9P7G3lakd/tHaF2+jEajqNPcEHAtCaE0hISiDhaPP3XqGCG0kgDO/kP 6xIcWn1fOz7RZknlbHM5ZbX6QzXGj0/2ySKYH+fYxWwr6c8Cn4L2OYs0ImdsEu9fmlRYtxrK bVUbGlVp+cSCbborySYdzZGhDTGo16zOJtrOWPdnaR3DLkiQQg8kIKH7d+d6nCtAxF27jSFE cANmSOVZ2SINar3/ahlG3gTIINs3qieGVv9+2kDVnSg/LfkQZqiY6Xt7Yziq+OIQCGbRaN8A ualAaMCZ9pWop/GICKW8qwrp0qtAriKs3oYLMOU+N1A4XORHHhQmlJ7iPCvL/FmJpcDRvakl KJx/ssTlY+R6TvkfDKsz2b90+fvgVc5ibzSSOqiUngoZtoL1AKkwg0hvAfWKEWAsnVj1dz5u 7H6z4Huu3iktWgTzlajy188k21w5yaohFW8wd8RZYd8l5DBBTb9UIYaPXslqHMoGBdtChnKj kuADGDiTBfyUevtQrzZVPB5iBj9YdclHe2Yu6AqY3fh1TnFs/xqGdyd9dzy/1vUELtnW0IvE ufBdYK33Qj+UPWOJkULuEIQwyzpk53LqbdDLGCyx58fVwwkpk/gwIJNA5Smb/pP47I827ONF pnsyvn51+auaAKRL8ggIFt3MZ32kLP9ska2r1e7VuxJhp2NN5QzkXuTcNz2ZIJtRFE1IaPKM onPaC6ENPV7PeByd2Da26hVnlT6luS5Fj8K34CRYYkmAvNDz7S1V17eiqj3MVm4LqP1XWqjH rj6Ot+YQ5On/RAMtDg8XRokqRfz5iv852XQCvr+JM+DPU+aQGUHj4yPv274pdENrsWduA1od DcUy/1JStkKjUEygOmlyztOLbJ8tlME1c29sAkJNKyg4AmoU5yd/V6aXiKnNdDFcPN4QAxQS 8T53OExM2ESuB4qf2ub/euBVn6YT0Du4DV5nnsO1YnzaV4bj9eg/SEr6JKdSYD15I0BA7gtB x1OAx6UmaaIG+NGfQf0zRFPpU2AS2awjiPfkuL6krxibQDLhhrxF3YpBMZAWTDohsBfR4yFI H81MvEL255wqFdP9EYCQtyU75XCOhPXeOuAnYsl1iRH9jBp/3uaa7qRHYsHYMlvjafKDtYyi pGbEYKYsvlNUa+PenDQ3jrjkDhJqX1gJXm/iMUI8n5zUTPDeJIDUTcP50L3lcmY7UyjcYxz3 PxxoY7+6QcbE9hjUpn59PMlAfdZnKAYgtrKTtvVLiKE7ViQIprRKFKBWzMJLr4NylqeJ4LXI ffiIvPlF4pu5ZqcGrdlqNvEfbLO1hVoajGNRHPgOE178nL66dYD5k2Ppw8GreVnAFh7/oAoa ON7hTh7wrrpAMV4lE8p9vi+v2hc2VRQD5zHLLfp0S06DqsIV5d6qNNXkKdaH5ESfv2/0yYJY QyfpB5VVdvW+c2uHz/CH89CBVcPDe6HyX6ZVuEULJeu3Un1mD1DOwYG+GBnZdgnrNrlA5bq6 6In5pIs3bH97uQjU+btaEwqVeMToE9OEMhJuljD3UEDaM8Qdv1RcMwNunVYUA7yo+mF4Y74e PQvW0gUHwIvCvnRbCB9Hi/q47OEzIGwMWO4V/ASxOH9tyZGHaZmquyKBEFWKhOep4/uATOHd Rn+8MHb72xqjjtIhpI7MrBNhgyetPe9kDfoRuw6/3dXE1gt9ZwZYWBrATwE1+3D0JmMUvvSx 25nvq/ktg/4jv/FaKX2OpjuFOAr1C239NFHB4rYIxbamie6ReIXnwAZn+Q1UswGcCujUachz Ek/OgnxZG7C3e+9ulzicWAKEi7Td+7dHF8Q+VmPX0ohwh/Lu0ExaAsG3KiiGkfggJZh+gA0x FFB7BZzvKBP7Z2qze68jUv4C0ULZReeE+QtkP5LoToHM38xzKPxfXkUqF43RwCqSSzwmPDP3 eHn/utaioq3+si2m+h9uZUCFV2rlDKPlqojS2moX8SF4tQd8FylHFFw8KQ4sjVpXRlc5AYoY PceayomGr0FoLVqJNwYBlt9PQO1EBoUeHfodjiHEU3iMi/UaBGQNWbXH5c2OQk2Ufl9X5w8O 20eIx1gQHfLLxxG3yLVEgCAEAUQtKKE1ymQYrUo4/+cOIBHMZoKqHWy/aqCF4woLhCCZglhs +ISXm1T9GXJ4S0gvqkp7uLgV57+u5NIxo0Gl+oJ1W3R+yU/uSPkzlMu2DxU+IidWP1y4MWw/ mlf+Hwvm7nrjwKhaNS55hdMwN0DsdPcHW1vwD1V/EJ9ihTLo8OzPUx5w8a2pz1VTDQw7IP1p Ti43CgRXcTImd3KXni5FfnlFC1VLydBsxdFD+fkFWatXQ3+/f0qti7R4x9X5Kg2JdCxjgjP4 1HvsUfGMPagN2jm7Rcz1CzXeEjZADCK99/jIQPJtiJMFn3oMfgX4UHIC2ocY+90Ga81OjBvo BwwcPw374p/PRxxT2/dkG8oybSCZwmOpBYY/hdFpuwlIH3G7BlJ4YajVx89vzOgsKabz112H /4EuxZfx6qGJz3Of7XvRwxppXDW3jsIO4mJaKuyMvQEyX/9uCF7/EhvpBv4iLPSKPnPZg6F6 2wd9u9RMB6ICvLZj4LhG8PpVMTmsv/IG500y2ktx67U15Va3l3yVE8K1hcFTyWoiC9MKPDT3 6hC6AF+hXfqKiNTiIx+4SfOVT6E9NS1qoIjnJoJ+PnNashtcRXwUEH3bP6sy3V+vkdnqcNyz G6fjEpQtGN4AVgNjrNwrrYEBtC50D79C+17ddk482t/V2XpYw0NBjuUwRtaT80NrMITQSttnxOuC b/2S+UUb4mAxC2NLL3VwBkG/S9i8ePjqbOTIw6pnEGfAncz3Z0cpt7ypwJNy8WS7+vIojzgE gn796nMLASux/8/c207VzO4N6Wa1OMMXAz6eeNMbPwDJSKdIocntiHpYByvFzl4cII/SyvtD 9OPbHdmMgMPNxg5iXS9o0FdzkGcEzLOccFJpy4T7AW8C9p7mSNLgIMsVShVFs+qvNbUG68ro BMate/IkCpB2VjE6L4pFZcvPx4QKRIh9RVKhYBE0vGlheqfs2hAd+2TEAB0alFv6ZY9CE1aJ OavBb7pBytpC26OopZpCkpuYthY9QqBPW2ZUz1HttNVrTk1/P/wJUyXZlON1yM9bh8n1AoXf b/MklIZ7vSBGFJbUkvc0AT7LhPHeRP1wpSUI9sYydo/JOQWXzHvH9rMljYrYdFQQyNHpWh8p LSMHtZqhK4L3MyCNmeWEeGGuOkv4u24LqxhB0qVRe+Bxnn3k7DF/5lDBqeNVlawV8CzCsKB0 htc0OQ1Z4CE5Oa4BDdEO8IQubPFIHw46IyOzeyL978RAcgazddH2o3CGGnNSMfV9+VyMx/o3 W3pqItm7VWE95oFFowbfRmm16TBDOf/Dm/hruZpcW6A+5krtPXrA43RM/kFA519TwGbGobgT WB6l5g8RT3p0vBh+Omy+3JAcrgd1iSeCm1p6Xi1ZvlbrqtbkZuC0APHpNFnf7w4HI4BRbner CskSysziFhxLiEptmqPWTq3wCTT1YMvkVik2uGaKbaqkyWwAZ0vq3MNzxxAhXzclVvPma6sS XbY4MFr0/Dt+C1C1/4kLesYQPlwxYXTdA9z+gPhxXmYnGWz1w9n2DEsS4gehng5FNa+6GOB4 a69RfQ4IXrP/ZivK9iAbj/9xo/EDNxQ279x31MJnYWMwZJqx2Dfc7w6H+lCH9sYISK2G+cop uT/9H4COR/6OBgNv9ikLJvrX3NNutmfcGv0iT85cNLO3aO0EiUgKGYnU/b0B3BzVAQgYQadu FAdV8KOGLsHbeEcPDWvMLI6iYBtaw0fWnXxIxCMSPSY8FP452O60SCj+t6bJVY7r1OsptO3u M6Vvyj7ZiR+cql/vqIo3NRHpyt05eS9+ArVdGgzSCRYEjephsNJ413d/YD0Ctj+ZY7A2ycbJ whn0suVHSazydjEQPtdSOk8OI/Ykg3FUZECYLVRm3ysL7Pzr2e7oh7IYt0y4oaEmG1ScxOl4 tH0GJrqYTL46eLJ9ZfaLcyrfNTiNs4f29RnVzlD5n0Yck8jfUncsDtXYHy8mMHaqL4ZL9AMT iNs1/PFQZ1fSz2CrM+ASFSCDcj3QiWeFocA1WhrvQhRK9sDcUoSIxo3XlZCqKQ+euB0Dbj1h ulpkwPy8NJuCzTssTFKGempjTTdKfkWsKT9c0/hA4seKgdKgUUqNWQCXDE/oR/T5WpFkHtYP FjqiHlzT8y8z0b4Qb2kO5CNMvkbOI9Xar3SNO/++hlXvj3nwPZg2xI9s4PXl2FETiq9dtl7T pFoBH0n0cTJxw77vz4hU0ZE7uxWDqXZfkvoSSrX5EI34xdj945sTz8/0qDKCLX+K4s6sDjdL 3bgJtL8nFotCpzWx2WTvtej8mmz5zKDyQG9yN5CNnQUrrP8/T7YVTjExbLK6DZnzA73Fjk13 sya6LgUOSEi2Hh7L3KieoUE3kaINJP/UTqJSy6nZWY/PsmUzqOoWHJ6DKWs51Sa4vRrYUX4b hjJBFAAdZ6oiAT1gSFR/ypdZSSFg5FS6pwoHmq8mocaYUEhaG3xyknPEpp8UAGvKSoMU6lXc IgZs+xt20KXZ7drz8fcCQb2w92owBI0Qga7wYMFrPCJXeAwoyKXjQpQSi1i/hnDUQUORNG3v zZOH3yLACOlKf3QkPveoEdcERudAijZeBqCEzCx+da9IPGFfr/PtH/kGm0yfJTiIDbdWg5Eh x4trzMMKD2BAJJI36xY8hqTNouMnaI8sAxNMtYMjDRNynd3hgsSA4Xq4b0eLpxpS8B2blXxx mZuPNRLEvZtWvVhhKrrl9hz5m6I679efgPK0ID+0I5Oy5Svdj5+klRM3JVsIXqge2tNxP8LZ mHms79T2oe0TMTtx/Vi9A5OeIMstE6s64ShIcNgNkR0OtlHYGTSDFo2YJMbc3kwLrwOdY6v/ NFqp9Vqju014Y5iUsJLVIxZ4RJiG1k+3ykk+kMALJhaXNhCggCNg4Dn12mqxIBmlwfMYWTyd LuKFl3QeIDOWd+fSZILD8VzY7FNgJ+wS+Q14iaulOWjmIo38BJVXnVnwXKSgt48bhSuy3ZtL EH5e5D5lYwuzd2GGLgKwWMgQrmyegdEYqx1Us/MuuwuhpZIabF5Mvov7qKT2QYX/TSqnsd1v vcdun6V02qmAg0daKvmb/2Nb05vo9bcVHe36Ij9Y8o96vh4TTTZOLYXdV7s+lL/dEM4xpEeD 5naVjHVdQ/LlM6L0I6O0ITPzNWIkrCNLB1ckI4PnW/O13AypeAbtKqoyG+33kX5quGY8aq8/ GprrRs1NrISLkTU8aMV0zQXgm3K2o3p2+Ho4f/LrLd+VIF+SMmGgySHr1jA1TkqpSmmRk6Nw uqowjMbYIgUNK9KVJyKVqnk8g+kpdDjDFtQiTm1dEo9LcyNIj+7LY+gjLvAxKL4rf7TGIAlL gZEoCoK1GWguOMgoMq3sJyej5aRWhJmqilcOGEAb71topC1jvDql6/VuXUvKol5doTyvOcS4 vMweN9Fp3hxbRYTQlAYH3kPfW0zN4H4QjoLRjlEAmq78sKS235vpi8guTwOY3Zm+g29TlngB Fwyc5iFGkXbuXMhdKQ2kus9EMUtB9paqaHBoPqWbV6cvDsH8eMm87P40Y732dStU6ixRBYOw y9bvvAaWlPl18uA6jBWvLnXMDprWoVJKt8e9DLcvDPMAg68qgVhFUQiDnzIM9lJCW5/Ofx6+ +OUkgGL3I4qu5yR2zpfBweyLUyMWUB/MegQiLLJ1i2dzXYGZ9yloe0Lo9a15sAf72mqfNbu/ X/om2l4SsZF8VLLESQb4UAfNtJD4pZGDU4GrxpgEayswVWHo6bPQpI3v0WzKWal4C54Wnmvk k4DudaGtj6xImawurltlu8w1+ncG5haRnbHK2FEX7b2zPpMVLTB52c22dqlLQJ2eFXouyBFC mhfO5BuFztA1PhjTHeq5XOME0ukadqwd/m7lE/OB4pIrPa/uNYYYVLEJt+eNgKqCUWKjhRpu xvegl4QRgPKrkTCjQ+JzIOVZXUdCkBPdjgfpi458POddyEoGTaXBvDPlUT8kOHyDwhuTx4KS zHD3OCwtunHJhdry22NVW0vAcSbt2mEoIx7lRwXAmB0SGEyE5lLZ/KaKeT15Cn9Up+7vmuQn vLpmkEWTvwZ+qG54CCLGNO5RFWy8OiEX9nwms87rdnXJdsHXi0ezb6G2ddeTlG1DMzMi0K/G by/zF0eaPrOQWMUh/SI8g60e6HNpgzk+74GMqhAWHcrHZNii6aOv/NspIxRG2MK68VqsLwRH mP3GlwSBpUQhCGe/VbLFjjSbhsgiO+lBgHV4Xwc2/YgP5Inv86l3Bh+x1dJUIcNEBrsAmFrn uz2egJJhy8vLdvkBTdFoemUJ4xGi2FDmu+7z8xoc2/R6lm1nHrQ45vouuV5wvydpMy9Elecn Xeb/105mx+DV8CfYca1/RmugsWomDk93Ew+llcaH1upLOfWfxX5nX45XmKyF+qqgqvUWg2yB KsTnKk1AKxNZcJfBj8a87X0wo4l1Py4T+NAKhnif2owdJS1EnR3obu+9PFYyfxsy664lUy+7 vf0t87xu5dSNHeo8Ww4fnDOm+u9fo6Q+YH9W7egtkRGeAKajTYWdZ7GRtnewzXww3yGwPDTy 7r8u93tSl4tU0PymwAhbWE7hxIbXyRecT6cC0wlfZ9S8coZHcmRmirNsN6Y1EbB4VSFVNcsb iXMPNqhnLygl6DhxhFAJ3F3GAE4f9HGYAN54XyNfYO8foEX7CLGTo7DyAIOcDhnygGHFUzgk 0egaCN6gFRAJ+zcuKsWt/QLjiwFNfX09oDsRHaIsnIc8SdoeVDn/SiR6mbArjCr7B2Ca2ICM gpvKOw6McninwIjSqRLwZmmKKIQ7l8fHSk3P0IRE+HehlH+Cg6biJwcY5DOV/rnD9x/6qICp zNVVOAhIRjUznrQdITnOZCDVOwT26kd2xG3Z9PNH6apsaPZWUIhUZYusEx99o5ih9XaS5fiq LBKqTO1LmOltnE3dUQuwjbjH0kwdDpRbl8ZeYJcud7YwPnUUV/oRKj6N211qvGjj8vY3TXWj BIXSgbstoXVV+JfWVVNoc7K00W8NwAQNkz+V3fvNvniyqR1nU+wDhLeUY42oof6i/CNvQQHi YtrgVLuC5tLd0FPnhf9/MW4crN/Sxdhj1N2ix3D9bQ2E9eQQvk5AtZibMIVsHQkYNsFbmeco SYI2GGhdDCyd0Wp/fJIYIjiGzfRW5FBDwwjTsyMiGk3iKdoOS3lBna7+S3/wKDgG1/sUpYK7 F/PqRh8c5U0vkc8a2ntqf+gZ+U9SBLQaNTm6j7BW/r5NgiapVmzUyj0irizJ25srkKSpCrLl 1N8XxJaKUYZxLI5R2POgkbcsJg69vA/tZqHB3OndHDgAg4F6ZjhzDXvlEo+y1YeoVqYiboSg p0c4CDd2QbPBtnlgXhlk3k8UKoDGf79+7FaWrBlX9ijIzvb99ZicMtQfst5XAGyP1WIYOGts mCsc271dn0FXA9Xq0+dHNdH2DTVPmXSEqXhcn7eR8CsJ89T8oenIjuvROenTst3Myjhtec+X n90BSM99FDorzdvS+QVoDy6H2c9lQmt/ZbZLJ7fiWZhN7e2YNTgN70JimHSnVFrrQfFMf/6l 9uVUr7N+Z7mR/Qi5sMQ0eXqb8qAy6+FdYWIVl40SW6MV9Nbr0HFw1W361hrJbKq6kGzyPnFX Vf1QeC3L4Y3xDXLI/Ow+W51o+kPC1zn31/M7uLtIQyjtXRdgQUlrOTHMYIF6Lhswm8AxhRJi +1JAsbQeewXglawh6HMYr6Tc0QqAtT0WCB3OI3KNlBVZIqhZP1yNbG0bfZQ03PBpL/BBQe+1 83Y/eb3hI9gun3sySnUktFNso8rL/5u8DXwDgg1wf7uGoQKosiir3NoopP6i2h9bdZl7fECa qGwKZX9+snCI1zKTHCjlAq0xzDRe0/TYiDll3zJY99RwbM7iUWP7oopfwp2TFDCpI0QsH2kw GY7aJEyyeC75QzIa9/IEvaDsXNG+VFTWdy9QIsDGRafZr+9NNi+1tZHyb53kI1Sd3toOeLTm da7kTbcIfoLWhGZdfiCkKHSE3w2XyZl1Apvd9pkEKerueUC+LrquRhWYZFB2SXUSLHszVxj7 xs2ZakD7/IKgK0TG9zuNX7i50feCBv4Li3kBtZU5DzO2UO/j3pYWJxWwtNig1Hn1yJej+FfF wC6faJW56V6y8fw4I2ACiVSREvN3mHPCs1ikDuMrb9jGbh/AUPZNplHrMGriikKOtyZCfwsc DduShgVCOVYh1vJXf7Tr5T0P8joMq2jtFjgo1ZQ+Vc1hTdwLTrulaXXXJjYjXuEEJrwY0eJK Kh/awhVUKSM68aB7UgeMkR3eDDZTLOtUWlLYCBmlHA8NKTqOXqRahB+4UYrCmHMhCTX5BU1h 0FmoXXJeq9uBzqe8a7tPgaUzs0oTlJU3rdYUAYw4ALWkU0NSerDPEJjFrtSE0tsC9HVQ1afQ Hlp8zigwEljZsz5Cws4L1S+VfKMMRLah8r3eyp6fiRtUvrWYwaNnaHqxZ810oTgEwrHZd24J 2DfcEWY+321z2xFU2sLbhmiPg3Y7SrrV6MkmFgl86+eguSgqbGryDQYNVQsr0+gyWAjh845d d8JVAKPCa+VnUpb4pqChCCvhBgqHnNChjaXtEJUZAZAmnMP1AQ0rPQpMqFkaoIa/my+ijDof 454QDkB9dOslRZAXNMahGehAZU6Wgs2KWjj83PBqxmnMMi4vByVRa0OuXY4cE7RrJ6Cg8twE Fdk2LZ0GKjImR6bZc10AyecQDtc9Xsz+NUxyUguS5jZ+DutCZfflZHCKRTFrZVJh74gUd+1Z jLueNW4iUo0hGqIj8IWQVD75yLNWPZUXXHwB7VSt3IFYpHv+tTBW8YV+3T4SFlmZfHU8CPti XUPqQeRhLuFyKfqSFxp420KSMWaMNy1fFDywxAqMwpfZUpHoWspzslt+DbWpeOTaV9GQBxS2 Iizz3oLAmC9xi/yci592Rt7C2evYkmZPNK5hr4BXzxOZKM0gSf48TD/lWpU2DPriQ+En6dkW JUFcp0gXAMPq23Zh6UiuAItObp6/uQwykN2v8hMhxhdd2Dv1indYny2r5ZQDR+PlSjm+nRWP P5I/K2lewcVLc8+PmsRuy7IkbiogevcLh5siCJpleGU0XPvsT/e/1v0pdSlFmcQPfZ7KcoR5 WmhQbG4oeDKgnKlFKlQGp6dpY8XskE+m0RxBCIUh8RsOteZecDVc4KLDIPsdBxksGUlNsing H/4DG2R4++g+REWZljKhYGn8Kekcoo59W1mKlwFwAAAlJU404XMXczW3tINxGPvcjEt8og3P T2YMTZnDxIjyUqH5voVgfTy7TN4TqsA9ChH7HFbXw0ksZkOYtClGNbz+6DhEkW/TXdLJ4LX4 kYnzLt/xrCFZdmyD6UeSeZ51Kf0r/HxpJKGPIPAKmHyayZYZ4mJvXLNFkVBy9NTMKW3wn5Vq Ni6VYgIjcvn6ZpSMhZe91NTojmnZZ+rFhgmJDK2ZURPjfPQawQomJLe8EZzu2yGI/d5oidFE MiHriWhgKDwdmSa33uwX9rY0CK6bccuHXWV7J2QpW8sv5oV5suQtKKsnsu4UAI75qUlsRT77 NBU73/z/30U61h6x/yuwqIgljqn3rwpCMG3bDnoVtgtNfbAYjaMgubga7/lIO54EiDVrwYpN Kr9jcxCM3QQj9xYyjKpCAavcksntmE3mCHBP1V11KuGhSGkWYZtsPHR0KU4OM5j/JIJvM4RJ TWeoWJ0htiFb7igtigYHihYC1RLGZGil8XB2c3DIlnuobk6HoPNaYHi5Ja7Mae7u+e49yFyA +YS5GQX34H/sY23Bw5rdw1bbMGb52htezJwVyNAJre5QK0VTwHhbo5BRZkmp07OWXwiZO0CE 8pZG5quwBGrPtZEI9C6U+McdeXY3WJnIjtDhkF9lbdyi/8/ufN5scvJMQ66rajEJwhCZhogS 4kJMHZt93MLxdvybWEwJPiemnBh5LGXm0dRp/TjmPT2mkP0YfWh+Qkxq0ja7xtkunWWWhUwq cA3SKMurgeu5ZX2TZdNKg/LDH3Upaur8MDDHp50v12PjuSA+8IxtiwEbuV4XdB6ADtnuA9FG 3E/DQ15U6uUkW7mtJ+ydMrksL4j+sPn2fRecMRyCxp3N3o4vaZ485eiiCq6V1ubFeBU/Vq+T 8/3uqGCueWC4f49E7eLz36oFeuGD4pJbnT4DdfDdKxFVgcccK4G6EGYEpWaEj2eAfDMAQdzY cdeIy7XtO8+DkOKTCa81JqtNvCkPFKOLG+HXmi36rFMyl+OsVlJiejo+6mGFS53W4g0HD7g6 z+pnUM2VrXsNBA+yPXuw4h4eNhdDzT/rnhGV3z6IMhRUqAmW7UAISDedEj+o2o1Hm1m2RjIR g46NntKuHngIhiF03KVxdULZL01Nxqsb2agJZS2LtGNQ22C067U5KXfdWxX9RnnG4NNtmrLf YmdqZUPKc99BtvUN6UhE7r+NYa/JP7uZZYgUpDnppFmBgaa/wdoE9oyLa1R9Qn/496/Wyb9e qV3LL2/QEe05gPsM1X22/w98WkvydZP4WCO32wmUaAW9GH5qFnRxkZptVS2vu5+L67mSEntH sNpHIP2tuesId6PCtF+PwEJo9xgCLY+3Tm8LLLSyE7XEetPlas3dEYeIKOFp+AYZVx/oYn4E 9g/eYs6fBxZUwQ4nB9a6AMHqoeEdRJshQoMD+Hmp/YVZSk8SKydegunGYdkEG21pb6N31rpw lhWxoOBngXyaiAN3glxWjnIafg1K0DUXq4JR0P5BMzruI+/wK7b06HwMleQSZkHbbgiR3OO0 zrQVqbvWxu1WMZOUOCsHaYxZDWMAWNA9c8OHnWAkKPPIaSTlvlLUwj9ijr3uRXGoiDEB2mOk GbjB4xPbdzUpY2CMtlcAn2FatVbEKRKVYGnw2hYhlgGlFC1n3PL10J6MPLK4qZucwy+jRLO+ WKq+zMRct9h7Da26dwWCUQ+yWJOBDffARoO9CT0Hp3PFCDQvdhtJvOz/D8yYNxHg50sGLfa5 wqji9K8nwV59jnqRCiRUoiL45MKVhqkWjxdSWruyrZxQC3DaiGBtKN/PzbKFW4Nxr+kcT+zm R41tM5FkMhBry9FIqlkqJbf4jLg+V+OaRN81ZAeVfZLLPX+OgTfwfrc3fhIf/+j+07Yan3ua Wg2M2R8qNZKFZKuwDpfljBigqx32Rt29ckESu53TUWe5Gwaw5004si1QMdaeNTTPiPyU5cac DoZYUAaAWby1MjypgBVF7vH2tewGkr6PGOH9HEnYZ8dgWX07X9GTfX4WyRjwqiYNg+nBdkNP +JMJiU7cTbepoBEruImBKNT6CBPaD45a85jy4zGxlncIBgAycwHE1o9926fnOkb8apv0yydI 0BTa/5B/RUc6yfaB+KEKlbm89y6gnKMvfW2XH9XEwZnbv2SL+/iOjEuAeX0eCTc+YwZPcxq9 nksatGjLUlzYFvxlBwADCWhzpAa2DG4KH3XT77PFFH7AO1EpnMmcmojkuFDNAj+EOa0oaX8U mZKfhcI3YIzxjPCFgFZllnmCHB4wedhEOagP3+JHuyv/lJMi81VOqD4YPoYLlRCCr5KKuCP/ 6GkAL6D+n8yJDtWDPkw3A2+QoOvvSonoNcW/aXJTD8yPRK8jKo1CnRDn/trRsEDMPKagQi2+ kfPoasPsitMMjTmDyR6y8Rw9COngCc9FVv8JE+T+dCrw1sXImnJXlWfZsybHseriGny+v325 XUxZt2TJgPYU3euOb+mftkyYcfe7RXAEvyst0Dpn5Ka9O/sMa+kGMKeDnofNVOoqOoj64VoF aEvVXWrosFPtVO7sbEyqLW9H+ig96Bft/UILDpZ4gja+nmTu6Aav0YJBiey1uDZFG36ARW+C fiLvB2SHsxMatU0QJuJvxHS8W7wNjVVxduemClKaG1Ibm9k5F+0llHzVvaTdyCSYZWgXmybI bTVh5LbS777T98rdh8GtI5t0m6J2PLlB45Pk+oN6goDQBWxlhYKE8KgkPN3O5vAw5GZ32C9l RCA+iZsU9AV9jWLWGFZ3Lgz6LGv6uc1SX5wzYESEfXgZfbP1eOulLdGaIzpXUz3Ld570uk0l 1hiebFKWgzGn5+cCkqkmbNzA2aQDApjwVvPax3kWotmm972CUuf/oVpkCOJrvzmlFnHByW4r Zn1wi7dEfFbxHZCTmcHh/j9h/GvdjD84OSpsxcVMiDgkr7eod7lQcS+lyugTxm2FkVwCiNhj DtffYWjRFYPWPTXZCNCKMWMQn9Cw5xFn5ozMvpxoqJmcu9uNElUMCxrAjvlzLywAFW5WStQ5 u6yGPQqgzbgeW8h+NfgtdFK6iv/wHofeFgefMAHmhdHgifoy8y+jjIK+K7wYMkQgd5uvNXuj SFZj+F+58Vuj8ou08qTqgukfm65KJO3R1NFocs26J97knQxGhW4ibpJpfrg2qoxtxftPB/6/ wWxjIhNnGyQC7/6k+aNxMk7Q/0zRW9gj66XHcmcqTtU51SrcZ0fF8Sz7ahVTGklt/0uHmJqh z68QWEG7F12r0ECUGMEW/BT8b5qzwjxIFTNN8nGvhUTIRIYzq+VCwmZCdq5VmDlEVcWxWh3C lnrh8VuXgE2bDldG0kjiRyUbID1UBGgl3BF6q/F18IXLp6UgWw7HOaqkUv6FTgtm3hr9zNKH qmGo5KBpmn2uIwbFcjG+T7wwE7Gx4Xk1IZ5HECpBphCVEabdxtSgY+TpzV4tPKUaBowLnUBV VWos9zujd9BQ38eV1EmEPNFAGPxDIjTo0VxSSz7TbrrX2Fu+DLh2B0Mkc6JvHtHi5Exzo9Kz Eu9m21J8xOsK4O9r4ciRp/uT6e64LeMY/sVxvRFQL7xR535hVgaoQeaDF+QXBLFYMLHi0vug ZFIwUHqukeGmy3OtBJXwUUBQaurSLiQkb0mMV2EZnW2s3FSDfBxuDrUs6YeQ/bgmugkRml0M Y8cH+OwWvD2/I4s1nmGKbfM/h/6jUuXsSnH+WaY7HZDA5CicRTLJ2usQftzc7+ceZfj9t8a5 sXJU9WW70sy124ajDCrcJbXqLWsoeuFDBO4KhAnyJgiV6DCPb8AmK2MhdxgekG1xd29xLhUE W50wWpK2aA4ewcbczTmVd9UAAfNZQ5Ki2/vOzh4m6cQ6csft+GLCbHKYOjBR3AFwd6MQRegL p53PHj61ofxwJK8sxg+tx/mglgP9TECd9FupsFzAjE6+Odp2HvUHvrgr6qYNTfimMRD5aJaP syjD4KkOgezQ7wDg6vVSTnRGRR9+1hsfWvzoA4a34TqYytDzwFBiZBnNeUXI25whVrSFSaBS NPE9CeboQisjRHv3aECZPVoiySDamiWmuaWZleODuLNY6C5e8LNioIu0A3zPQ72fm9QpuBHO ZMO8AKx+kjoZQkB04CZHl/In8c3U+uGtuHcVRAb6Ep3ITRuV3uMc9T5iT8u02eDXXRWuQUnd wm1CKT3OixtKJlvn8en2YvxnQtyr56IanVF3bgpTJ3GKq66ERn0SvULnQWRJqt6jha9yvUYU RpACVtJ/qMmJm4bdEIq3UJ0wyLh8oMK7Jx1oMnRVAULu9vxZx3IQ6N4ATvfndvPQJh3SZEiy vRawT95GN/VF9rHNP81GSvJ+GQab3fIEld51ZjkAiCmMjplo0pFcaPYcguXxDKaGu0h0BVY9 kdMw3i8Jr/wzHbNLZAziojvcPIcRzKouMMukvE9VcqYDwWzNvLzuMZOwuIYVekLDYUeE4n+U 7fo0n3SLWjpVqCZlnPuXjxGuPfiKmqepVdu1kYOCy3SzYACZzzuUY2Ut+CQldJqWeyGTJwCH UTwf/SH8fPWZ/geXywJAdBfWX3tH31lOIlmDYywyTYVfF5VY8U4r6QQCoBLKyVk0NAclt6wE lXCuJ1VgPUNehx3p2qU1SKQ2YYABQ1DwLd4vTfInbtkNB03f6yyvltXzhqyB2xmqGOsq6/h3 ewTZ6M4z7rxoOER+vbdjUiMaax+gGqDsZAB50n7EXJUEjdQyo+5wipCUqyXx5DxhhM0M9ZI8 v/1YIBder5JgJva81PoYvv2Oz16QnlSfar0lXqYW337xN6f7GZGqhx3EIODI+Jb4A10pNJna yQdH87cvIZ7FjmSyEO5cJfTsfTgk9Q7FoW3lTlrFCR+tLxO48I3mv8FX83G4D+nVgnI6MAK8 QYh/ZGMMhZVXFYwrLrXf7InncBe2x3ld7hz0+WU/N3ojZRi7UcIQ555n/MXBF1eyZrlob0lP DzUmUDpksZuWzvGvg2Fa2RyMflCB7s0mJlQ1T7QQhA+04jrd8rr6dPr5IsCZwVW3oekssmxd CWUhr9PbLxOOxlAopLLle+fcb5ieTDISdfya4YwUcbotm5qfrt8JE8fykBb8Qt8xnlr8M0he JVa+RpEyNMTls/SugxL0dA/xd3wauAzMMPSk/9KBGNxWG7PWkEvXzDDpZLSkzBiFynfAAscE r8ARorr9sxZKUo/9GIBSL7aHK3pOltHh2DiDpZLSdRzWC3hHFKyAyjY0IflB2v92/ay68YTP H7HAOmdVnm+2E1JJNRw89K+z3vlNgp8C4+dhSxryokSMuvJcBzq8zB8gkl5RYHJ6/TZhgHnW XW1g4TDnGiSoUKERsui2cWX5R3BrE/MXHA4GMHfa2XtSqDm+ZcAB+LMMr80Oq4vRTxeUioCc ZOEUWOrZrljXdTNzAnyCzWXeGnVgMlHTGC8xbdkJmPeMrwDTApIVG5ToqpnvaaQBIQlBpw5x fA9dfmKIbe/XF6QPUJjOltLNL/m83x/ujNUig3xSgsjxdRjdUxDvib1yOuKWtzQEglA0PsFJ DW4oBc9vCb7GpOjiKmbuC8hE2Mldg1HNZBU/akRs/Ex/54n8OeH9uvkidvPYUNE1gB/SM4J+ Dp4H+grQVx2PQEKybgbrLNnu8VVHmMIB0Q0UCB6e6z0MyHJCwLBzYplBXeDmkBSWjlri1vJA 5FGVlT8w55GN57MAfZaUSRbLxn9BKAbipJ+GaEjOX/icBzjUu64Y1I8sNAYokTS5YSJCzFrB d8DBzfbP+ZgDaUVHwk/+918gj31VsUQ8Z9WmsmC7XbZ7+5SHL7w6XfLRHx4VdmitIPKUN2Sf w3+th3Ca6MICXI2OlhEKfFfyG8/C575vTgrO3glrwt3D26qbGgzJTSaKJjQ6g7dnKVUKXh5l KJVHUiGgksm7NrvpEV+tVGBr4mjYvvQ4Tg0dCg+6KN/Gsuc9NnsFh1DJ7r3AMkGvUNer+Nmg VwpZms0OnKnDN/DfNPfvwbCDBjK+CY55K4V/vRcg5Doi+qwmTZiTSXub8Eyp9FuYkINkvebB rgeRaSSIB+2ENidUXyg21RlgbyhEWG4szjvmFTlHvJQbmTfIOXQq+UW5G42MezpiWkxyCubn jud18lQkeoRh1aF05qmyhekAI8C6bzo6l4rpSvp3PvfsQNDSONM3VYLVaY8ctNV3yjepsmIS 86gYTtuNgM96XGwZihc00OWj6C6b0EzKO0Jyxk9eiSHntQ172H0k2LJC/BlyYUS2eqnAeBxJ dkvHkvYBaAHWnFwBKUIiVQB5/OI+btxmCz6vwU06RV2RmhD1DJWRSIxpXc/pzoSfoul/3rN5 3rN56Ux8ifAWdpNKZ7ao33YXtnwzSiP4RMCIKhHk4GTifNYcBioC9PLcIXJaQ0RVDUbF0KFB chT4aCGdym6YsgOQXSeoaejmYz5SKFmE7QvUPVMad9tdin77PmI3MHLPkA8J0b/HH4/BeDL0 Fap8+aG1WKkOYdySCH5UnRZ2yzYIwg/RQb+2HAf0x/pEjqa+2dIrLhSPVWQSO9X32UrpU4WI aI+7h79ntFxMSdrZK/vvTbP2aG74AkHycH+Y0Nesnhp736UlH/ZwTCOK/QxDmJ9tJHPYgqCk HNg0qNsshJNB3mOgkcpaK0mBg2ZB20LZ5vM/MI3NugeQlsvVFa5Ch09guQ3BgkCjVdUc6teF eEWmDZthznNzNWy9FQ0rYTJ7R/HjZoaFPCx9Yk7g3kYC+befttqTdVU4LfjJa9tBovhbN1dg mhSk9cgRNwZ6y+gCb/20qGnU+xSExzq0jUu2W+K9AmUdH6SPpqXEyO3hBXstQSOi/aYSDQtS 9CnHKk5NAf9wrmYp46Z4TPlE/4nuDI4+LRQ2cMjBd1MBu2rqz9qcMcxXY1q3ynSe2w2XIgTB QlLjUlG96LyeTCqD0JQyLdy2uaAbMPXczC0ISnq6gHcp+AAeH+5JBRsEvgMLbyROZyTWH0Bb zEiEIUZ+7UIgmT+vAqX0jUePoZ0puGFGdRikrL56Lvh8EtKKJ8KYsBGAZKyyzBivCqV39z5w TAfKR97Lq2WZ1TfI7frpAlAsaYXmIk+5UMYIPLyc+HLSciSZuCYBPSjxCpGCFAihYMY6A97V olIQBEDVOC7CpiubVyHup1r7KAZ+zjosTgdUlOFNUdu39PkbeWPi8l9zhAO/DApKCE+vetHx MJqxZOv0Jx8XGGZGJfCmy3JGySquTrSJyHUB4ljc3EPCb0oRMv2Z5Eq1Fet76jGY9FUftMbF LyV9zyGkCajiYSo5x8/tD8fDwEEcyn1/yUc1fcEX1Tx0VFACVa+K1HGF+0PRSnO9Jsh2N6DH Bojx/Tr84JHwwiDBfmJsd+WxfvXUtXGvKALiEqFcFlCe/c5oO/Lc4e6XdVD3vriLfrxkZ/NZ roHEp88DL6aJPOIXYpbJmcKDkHGdWtmW9ofEGUfOOTpLW5QKfa1yKSOVssFtJgEkmxLf7MvF 8+snsnNq8+H1CI2W9uMbww5UmVbVn0iV3qBFWWX18aoOG1VBLpNJdDel6HGO4g2PsVRYJTYE nEH9VaEWNb6fY9/injtGx5cYlGyc3neurpqVWIBdFaQ3B22hbBTg/yIh7WmXfc+EMl6YoDre F3X5il3y/jDDMo2CsHciEWky6S/cXQQ8+rgu5AL/iN9dWhnVOWJHgovSmtrB6oEoBEhV3v5L bi7rxJd4juo8RDd1h8oHbcduuTCfjhATN7g6p/v/o58Un3lomPpg8/8EZhcBvtBkHDCh+fax UCGpUCVEo4rz4UArqGxZXbavkSWPccyVPuJundMKwUgdaYRMpfmxP5vMV6uAV7tgU8QILr+K RbU/TJvtKA6/h4yPaa1Sxbhf6oTIZfYNrxagpxeu37Bf30dpSIOqnqCI2W96zsPVjp5tpwfw qBejC9jRAorNXjKV8RvgsacQ1UyaQA3Hx5XmT88tmMPwxS3+FYb7FI1y7jAvNpR90SCoUCE3 yHFTSDndD5FxP2BWnztdSASgd/2ttrio5aGPV6dBjufgUKyA+WfLQoSvxfCCjHWbqpp1UeQf F/cdR/Q/8SxLQ744Cw0zTlMWKkD9NUKXgyJl++zLk5lsGCZbsvXZKU3ZmkSNq5evA3LlsohW +Fa79Ws5T7cmNuzoyxJEpw6Xgk13zrl+sUcwY1EgoFMvFg9I983MB5sICoe1y57qSSgNmwaV Fotgw4W/0/zSOswOcCSLnfCFKxBy5klyLTLfQr8c3PayNGTGTab6xl8x6Tp920vteVavVH6n iCCSITMoT/SdWVo0hUxhbAH4c8xIPULVy1kLvKdL0DJqdxOG2po4nZsyJA0LpKlk1Vbbfch1 ff91jycQkmUXpVvowrUVDAtBnWjnU9j9moZp9N9NKH8MQtVBzhvsbcYHlEmHObxM/QeTKY0O hGxLoaYGdcx0We6GOx8+fVIHJkvbvWciTeKcWdrE4Rcce4B3bouuOl64ncJ1ioGzIWwqBz95 NzMevWZxM3RbVfDR+o3tO8yBJO1qXJ7Va1xhvrv+/NG6J0blNONUgoLUwBO/ON1cGgrWLRSb LwCHcqLACPTojGnQnrZttbDnkhpAVs1F7TWsSDokXDpaWuoZF08lwhDcyWOoZ4lMxyqNP9SU Qod3tlyF1awZDeK4nilrUmzWtN6oJRsf9G9Gmc890qoMS7fxJIwQh9kwLZojCW+XzCeHR2h6 AhO0+YmbN39VbHvMmaR/mSjOvS6zUtI0X2z6AllVXBkLTufSLyFvlpnaplHmt4lBG29SUmz/ OIhIZ3rvf43/7KMANN9ti0idre7AwpSfdjYOLKHwwKtwdhVCvnHnOS/FMi1QTP6fVmNjuYQS gsT7ZoEZjTZ8i/6TEb/eL0sdOEeFNacsLxOFBdogCHubH41dKGr3lfGzYQ01qrgDFhLc4FSq 9cOkXQpAbJzJSDAe8ZIG4KLDf6pHnaDDnxCQzFMmSj1KtKESIFC9asNV5ta9oaHt10JNFxnD DVwltKGwAv3r8j6n7o+0myl0W1JvgP7L2XI37dEfe9dq9cvPS/Na1huSAaO/w+fqP0AnK6oY 1Ikp824jGfQFi9sFATR41TFZn393duPeZPb5qO+2OfZh9yGcMY/OThB5i4DxVnV9GvLn7DDH ihoWhYJ5u/U2Q6oXwk4JPB+wtGn4bIXoYMcHoAWvKztJjDp1JP2pRnx4ddRE9B102fmQTdfP Ui4HFZ0DDpk4+rM6oKM1TPx3xfVTw994FsbS6Vax2xuZRqyuzXLEADkNGJ9XXNOc4/68/Z4l Krexc9NUsMVvqnuuK4WGw83lv35nLWYhzLL9UiX0NMz8X4jri+DVa+p/ZijPFc0PBVAf3Jgk zfCcgHfr8Oe9J5C/z7/ynzZFtp9vdYHMr1cB5xJITmiQ9yPZyDmfINMliZ5M4D3ysnMVsmcW y/UU6jh0aCS3x4wCLzGyOWaJMnGlH2rt+iIvRwU05OMoxH/mo3x6lNXC1GwmBecf/1M8QN31 GIZ5mxgUjkvFfR9bLEMB7y+xWOMuJ0VqNpWfaRoLFvpgyqPrOXr+5fJqM4FtJMmjPbmcqWbd Qkq8uwpeGDHKKLvU+AE6NfUb2B5lH0QMEbK0XajWh7UJrw3Pr5wlbg1oAoqGyZYvYopyPIrC P9+c+4F0DgZ3FfWOlJt73DUjUwuGAseFopMsTUkQJk4x+o4rHgT6Ap3udWJNRSt6r1sTLC/f 2wu4ZUmroWfjJ6p1/Qmdg/MOzcCEsxXlYkeXDgBqKzT1ofiVKcPL7k0yUfno83pra2p1kxvO oS0VySZy10FE2z1Gg6OXheRJuZqT8Ab6ozssDpQyyBufh0IhMbGSwxzO9gdeT/5AvrXW74Tb bZlHUvlPJrifXmUi9soZimKqDt2UFqqUN83xH+LDjhqSUmqFRcIX+pyaqTSKDcv+8UumXhEH OBa5GFVsrW59kgX1aZ4ADW7lT2V3vsWy+oS3uRlIcZDpi01TbbPnodEKIZdLTTdHXhF1pIJz tNqGRSPA7uh+OIi2pJ4oRF2FmwTzM6tHBMBqXcjGSQQ21UE1fXI694AtyU12P5MMbwBm8OkO KLcJipEt/alLYK9vKsib/B79O5Fz6BUNWtlq+Lq1XTdYuulHZtt8lhVNvCkLR2vF3wIZZ57e 6aJs7McYjfafpfnJfYF/kse7MQKsWds7uujWHrpMqbrT5GaJGq9zqHl9xzoO5Np5XPyPVfYH Hq4QS50Gq0Z4CbTonawgMX+uT508m7dYsGs8EdLJpejJ62YNtdmFEv/ptQVhJp5iH1+ixpR3 QV/S2+gp/fD4dkLSnquP1gUyPjNDvAwj2MDaBVMxTOqiR12HW2MGJUrXEQxsZrR9mBCyC8V9 Yg+FRfZ45GuEcbZhTbLqcmm3xJNU4NCrjKoOIEZ16h1k/Zey3cXXrD5mhxEP9mGqv5sIHddL UGjlIZeJMgjlSkVvyTB1OADxXEgMiwfoqmUEtWXqczeSWGptpV0hWSZ5S9YzfJqITp+HRyN3 Ux9lYWghKCxFlonB0+kaMMjUHziZbdlNojuboZXNyyEim4GlQ3yPPRCcbXwExCf12uH4qkf5 tC5IHloukPzPHn1W/57Zfin9fWz8WdDHA1SOf6UbObsIiQaNpmuy1kIVFsn6Lv3gaLA/tf8G hk+l0tTKtLaqCJ0PX+Zm9n8Bh34rWDjRH79A0e+vtJtzk2f21HKMU70YYrV7n1YBZUgXugzw t4qL+tFax6ozMYL0z5NG1yZRb+3Y+1xNMzqPfdPNB5WWjv1Qf2GetwhD0XFlK126Wqz0F91l R+Y1MaPagnnsplQl9j5/J/+GvpVudTrRalkb+eRC71vKIPdgT657GWhPGt2GaprPsAegdCIJ x9/YlrLUXG39ZO07PGtR9Ix+IZwIrhN592hL4Z96b0+R6hXlYnDnveCZgbrS8yupTL3bPr62 CVRCD+EUufgwMsJVqEN7ba/nZn71Tm6vI5KBKXaQ4OEn64pYI/uwSMEmNIcKXQADtXYilCB3 tfUQ7Ol7TzGYFai0wY+sk+qg57niy1rFUqy6dv3tZdoFkREbwmRAfVuagDnYYZanNN7Po8lX Dcv2QzficoIpkYuh146Zx3pIyKoIgYc2H3Tfusrr60yLurp2j9TklahoNxCHLuT87rOrtMxF piW7Z0OjabBn6FKYvr530V7GLK8FWYDeL5e2t2bUuMOgpURUjhax3NoFOUFr9rtAp+OQ0ddK 4jt03K0AxSdOIIjb4t0pzjt2OJzm9lZGoZ2ThNY+K3sdFuPqzbGlMlcCoi5dsnYQkO79ZTts nrRJpR+8zfDKPfkNhM9wcKUX2q3vCetP9o34OmFGIJrds+DGc/WutneJwu3eBKzmBqpItt1y baqIBSmGzaZ84b7Q4seiY3eEFKfAqaAbHUNPAkQDXSZIjVxDumz34ENuXPwkXzz88Me6ft5W Roc6p5FZoh1QeBKW661jkE2m4dglzID1ikKMexDe3xBcR3nSNuDMINx262G5Nm3vJYfPPEc8 zVWPx7xD8ioW3Unic327VLCZLyXDc4zWeVAS5rLoJ7NTrJRJJb+4LIcQcmL9MH2R5ykXlbuh fbkPcJ2nyAbDBpQhuAWOd8G/agdF53V6onYTicylcolIv+h+rESN9MFogSFpPa1o1tUw7NCV 80yfnJJGt5vO/h9lNi7Z6OJQCadEKSA9C6z9XFdKgF98Kfse4nc4aK7X/QMkU9GyF1E/c70n /EJSeY5FhbpJrqB1DTCmMOhcxcoaGZczyFtYX+tSdh1slZt7eJ0TLQqjTHW3qk1BHLuSprin uGEhZtaeY3zCt4HXEBZUbmJkkeoVG7l0hVjRPrknwQVTRN0Zl/X1y65P1Mjj3HE+izDVfgVt LV8b28d7ikLZNv3d4/oKkmd4vNEe2Spzm1S/1jSxicw5kfB66NcQfh9VRBgIqb9wbf4BiNWM sMw2BOqSHwAiVE00HSTNrGQ4UumBxrvhYHrrQmeFp8TKIILd3KTXJXZJwytg2IJ6Y6frZkHf wRVclHfJl+/ccGhzNO0svZXQaanpwGaTO3mZbAuiP2CfSmBxqlsMftWQoiBNoZi6Cepg6xUQ ZuBlEJnWO8BWzECToR4dRMnrlu1PIBYbaaYn+Vo0hjvKrnbDKccDMYp6FmepLlURtmTdZx9v qHVXmX9U+ajOl/zgQL+/vKV5uzNasNUJKPwrnPsIHrTKhL431I03tmG3XFUarHTbXNA8kQR6 QOKJkOZZ8LsD3APxADIkB0MMOxRaSrnnZNKUmkO8r16YIlKzsMBBPo5bMEvrTxkEXtVEjlv1 ZHXC5I5RT9GHGPZulxNT3+M5YDd+bFyyIdlqoB71p9xYGW5hBceKtfu14wx8mHJV4IwpuDvk wPIXwtEqh3CZvERK/6QTKlR3jJYoZp+nYuETkX95pgc8v/tO9EcGwbzfG/FlD1whkYCrQefQ RNKy28ZxU8Fuz5aOdz304DLSNvuubG4bmMjQlx/e5nL5fcxE813fLBP01B2uTQfsSJSHh2Vq PqJxUlWwb2j4sGRfFYKrG/RZ3Ffj6ar6EueGNu6oR3wZYFYsTsk/iRTBdMpJJRJplIlaoc2t QS0ydEQHeqkN8/7mvcLMOYRoZz729Eu/4fFlSlR1x60Ys4O70iotnANI7TSL2NoK0LCKTGsQ JUifIBetVd10eRzBXK++/1chjgFiImc7g7PYbyxmPEo6TyQMzv4NAvfGOUfeU9DUGHS39p14 FRQlM0Qz+kX1TsevfCo6IeleONPiRmOzVcE7g0gI+701PZTdtqCkFAL5TiRj76ejY1usBkxs ByeNmPGWPpicrQTVEK3Bl7b8ZMSVbnZHmfpiMd6xVkxJV+rSoqOCj4tFx/yytSrkDoIqlB5+ LyfpVTlMhdlF/G8n2l8SONacLj5kpGhx/CT7o6g44QvO8vGkJd6Rj6bf1lyTwE15/zDXcKzo woZnkTgl8NaDK3IgFA8wHv846GTkBp15/eJugyusgpLz1nGOYxb1lVNkoxnYXMEKD3AhZOuQ S+Ct346eogM8h7rRr9bqa6vAR1g0QKj9VU9Fx9XjeBkEL1p5gVKQvBrRYms33GHPf0cpTdrH OVV9TH9dXWUAaBTquZ6J59GN8CERvduVIKPep3FxYHN1buKjeAoKGa75F7ObYhzrzWsa3Riw HsTNuMneoTH4DovQXfYkTHj2nVbQsgs6+ESJ1Fq+gcaKDJpHEcStr9SwxccrMLyyjQl2kXCM TeRfOnvo885XR4j8mnMbZu9NN9GwhmzNtUO2NZnQ26rGMIcKHhzFLvO/kwxLbx/WgQoLxOe3 D7ULjcpDU5OgPhGgdBYeI/sKo06EGZxs4rWl1/2nL1yzyrqFuTcHYuX98gh1HPUm95f2Ppuu wNr2x2EAH1eluNjOjFwwr5zAnnEgJxF8DVIYW3LWu4pvLzR2JhgDfMFiL8c11PRAXHTx5Cfl KncpKM/71yqTZv+LUKbyQR0TawID97so9w+rAsmhpNVOEo0LyoLoJohQKe7y0ioXAvdTI7Yp 0GXZPGerNN3WJOvr4RIXQt/bXijL7jKKfmNzKhp3bycAZIztj76hNTl80J2LpWWgy2iYvRJQ N8mtU8m0SlJOMgAsSwnd0nZO6Hb8/TqRt5IBrvx189yzT5hkRA2YiYEbSsqVtAc2NKBKyhv6 P9gTjc0kV4MdFubWHMx/RO/zb+u3mbJ+kk3U4Q1Skzb/STZYWyTCFqXgoTjToMUVezwSaprW 7Y0K5E2rxZaSgWaUf0y/lT6jKlbIzHpKtnbHNtB2cd5fTqLl9z8T+StjoSaoK+jO0gMvsgCM 7kdx3LGC0Vdgbd6tZvmCyDqxa7Kj1zKbIf0q2QJVIVXgMdIjP4ZI1YQoePPef1Ox8uWR/92v qsyAx32BSn9zqCiDxxOlGinzgIrtJJO73Ojklkvc8MIfKL6YIFabb3SKwFz/VDB0/rS0kRmw AMJ5cUY6e9ufE27nTho6O3iHDYWpac6VsUdByPNAy09R5oZnTnxK/v82m19wL3NW5bsmUq5E j0FOPteZznQT9VG8J6vFkV01pHlWhE6aDFxa/p0eZC0pS0umMCStpuVN7IKsme0mHRYsvE+e mDR1NUhhDnA+lUIMd3zcbQEBSuk/Lek5Ji8jJELI17KGde//3/unTcYGK+9jZ8FNjATj61Nv MbwFrAEHlxC0D0biyTTpdj6gMZNXd87h1cF6WY6uJ5FvdoxRrmkWTggs7aPoLKdqYWb5npJG 3J4PGQRm3m752dLpLqJqX5RbN8DJ/HNwe74jngP4GhAcl/oxpdjku4Z9I3sLf1YpnpNL1mA/ j4kbw/BJJiJTFPl9Agk3SdIdWXgjzadbZwHi+QfnFUHLe7FaAn6J3F8WmG/73FXDJPvQk2pl Wa7DNxoeVcNWq1W/O0kecWwa/PWvKdJLheqnzY1DE/JHoqNvXLWS9HI7BVk6UJGmJL6kbLH6 GXw5rKA+VEYMeAlDkGpDCiTrLet0D1SUADsKS6BjeGwxhdP8ytl6eBy9/4JMMZPViDUFh5B2 mu+vfFpfLRLVi+xBBJ9XjdMW2eoD70m2d8dTyjE13cPdUA+vNBMmcHR6KHEtE84bjDEo0e6p kApk7MUTinQLr1UpsX4H4txL/NNuA1r6Wrxw5f+978alhmG6C6Tp+BpSQHIubEctNGu1rypN 5x2n2CORHEpo1iljpsPsA20OKZEPF/dASwi1pD2CulAxy44YSUs/WYPkwj5ngo0j5vDqPhpD HobPmaUdTTioPf3BszlbB1/r11JCwJe1whlUdijm3nj8yDZoIn/7ALfp7Aip/FanJeArdYU6 qvDY+uqRzNblwUTdHgTnv3Tq7ODZYStkRwl+sQhdna+oDQc1McCV270ytXWFNJFVJQVP8HJ5 RqDCA7KNV5wiv1SQ//++QlcjdUf7bHE5qDPxxqsWTS9tDpWMSoc0vHlIj4FN8rdF2wYoT0Rp +gTEpdgJZYxPQ0QO/PkL4CQjKCyV3H5dUs0DCA1Ab9qOBxAI7efNDIxb9ANX0PG2rikb6l8+ +9XERdv7eN2o2BUixDGyCG2uQlApJssIhWMXasgIo6bHRkeUK20wvq6KuxbicFKfi9/r+c0s M69pxY6JEDIyjRAhzAYdFCim16KWnpsIqE7URS9fTj9n3BjSuZlryilnYLUv381fai0o35kI nXCV8HWGlXiXhfX1cdiX6DO8dM4TGuzBOb3SQdVfAG4WE+FncD4MTrYSsACSu4foxRV1XuF/ XCPiNDGq8M1QQij6b/FnhZ1OtJR/PLkqQ3bS4Yi/sqsJq4PAYg/+np93NNGMQeFnATgkYUVK 0me/fPUG/EhVLbjVmVRPZ3sw9eiuZ8CKBQvhPs19+QOTGt6qFDf2OZVfBzRDrRDmAT6L7qbh RhdR0KWLMOsURVxSYcrLLuHNEWyv/8QQC2pzdlhxLZAbu/GylaVQ7Dmni6qlsJzmR0eyE+7u J1r2MuBCOSlUtQstwQzJDwdEugEAPsyPZd1D8gLHDLLBgGlXVRHoo+sXgLic+i2jrKMJJPAQ hEgdxTiCIQe+QMkuyxtiXHLNbIDal7wAOZBCDQJBz9yvSch4WNB80cBu1z8ntWm0B9HcFcrM cGZKORhfOdjaicjQIGyaP7x79aG1qNZ5KD49TSFIo2MNlWiYz1hDNOSDQ6QJRJvtgssTtnHb FIFqjvBs03pxxLFkDiW5R3MyoNoEGH4n3eBxVXo7d78OceK4jQjmI8NW3RlYiOQPOFIWBml+ +myYTpfV//qkdNFUsBPxKq3GYsbtfIC9P/KPX4/F1LtAIHXvLWsYdG69xk/Xlx+Au6RxIpC/ VBNmXe6ug58Qv/Tz2zSf6NejV4aox2Y2d+AsmCVZ59mtU7D9WYdBocmCuQ1p90ruZA07XR6n wSMtI/clRjXiNtbUhvV73hNViZwUY9wb/LPjOyKSddKjz9gEBqaCpizhcyKMghH1hFePLiLK naaPuUhTiuDsYpwCHe+mJisgICldXJIUuFi+fwSQxEbnscDs0cBPDUtH+YOblJ9RFfO/V1rU GILdkGTKyp961tWAMGSXHHmZMcKSnmXpfA5DiQ9TkTjn2DW57Dxlrd2zwaX2iKay8lkunZU4 hg2b9xwp0y8S7bx1cdrLXYCdPuzLUE1UHAYgroaxZ+5ZXfxnjtxwjDHWJv9up+Ylm74L8TAn SBcaAW9k+LrDuP4Kvgo1i47xwJs4bt2wx34vO7mYdLdaLAVJK27Yh3RebMLutADMcuNxcnPT K1Lk508r89thibLFCJZF6dJ12sC4GCEeRYOupAABGTl9hgQxlMN5t2WOtwC/SsxZgs4Afyzk fJPzi1v6ecOpm/mXDOB6+TdvOH6Gej3249ftZt0ekvkutM7QSTpO386E1g5kdSEh/dBgbCz7 HWpmpRdtwep7lo3s9Z9XV+dspPVrReR6o/C2AT16EhEz7H6NKLmjzHZwWviOwceOWEFpAvn7 QYYb/uzWF69uj8/DCdDxobdt/JZJuQvx5Nk5JRhsAEZwq9gYQMn1mlNPHXwfFFE7xUUCV+2J Dfa1BvNZtTLv0NiCHNcwKpJXfKtF1rd00yn9b8e5xIbkJv8WYbayGUGmYUGSdASb+mC8i9ie /7Mo2CY06/cWZKpZIAFtXEfkTJRhIBQAK+KzidlJMJm1FZiwYtgxUmDdE5OV4nHt5cRYTdlO p6COdaVIYioKcvNvSazxBoIVmq3zRaV8zVsQAk3DBXEmYOdkosL93TpS4Y9M2dhTYA1RHoCx 0fHfQcX1lpiXDQuITXkWGTAZMSaU9IxJcyx0dxpn5yfQR0p3do5pTqgUqm6r32VHBHfLsoMi TLQh3Pc0vqT8WZQnwMo436lnCzzmlGnUjB7Nw7TUH8qTaMGTG0Cp0ZRWXvyChDcycIfFzWQv ruqx+yIGDnlwoTS3b/qhcHpkYQIlCg0ghJIXVddLbwxZkWa6DKVkC+EVEVCGN8OlxMRxpOdp KM4cTfOi2PGipeapw7EKb8pfeEj9YY8/RHtjcOVMxBBzXSm46ttU8MuQDSnNeW1P3aJVxydw pB/U2L0lNdn0Vo82mr+3KmnoyzeRskrfQVg9viL8QLOCEOQUkq6veFdnEmXyuUrbPW1P45Gg U5sAy3Slfbfp3dz2DQUuAXYoI7kKszyMq5qI9SYo7AV3aNZKibe3LDEB3TS0x1hLLUN6IS8a eZnYVnwzucwb8ZHzeFcVuqIIA8cFWtoIs8Du6LyutGZrVYpK9AtmVao73HnQ8FhK+a/qK8oi A2Xiaklm2ff80HrUmkirVcVRv77630U4QWBb9bP01vn7CktXiOAIw0BSFxwyA2XwFU2seZC3 NOiTX6LVXbaAIrZV6lXclevOHJQcujiUN2VtXrRVjvWdKyDQwQMY1qDVge1WO8ZUgNl/7Hlk FNNzVKlflEOsdu8FNxQw09mkL/ciyoGZDA6/YV1nTlVo827Jd0DLQGneVUWwh1hD0TH6COd3 bbxq68f0d86Z5F/3KCuJBPFDrbpgOBgjuJmasiKzUIR2OG0JVI7lBSYoqiCccmt6xUz7O5AD p0wpzLdHTkks1VzmLx4LWRT8cIGXdQClv5vi+Laa31ijGTr44CQYvyaOkRMEIGR1JbyfpIBf Ivk12usHpPBL5XE3ttrbEpSCpWlJVglUiB9XoPPZfz/r1TN6TBaq2xAWReza5YKhn797MNdM 60MVwPI26eeZrVK7vPvCoF+HrIRHd7XKz6BXCVo6YNSZv4xjO9xByxeJbV+E79n6skaTPuo/ Btp68uQAOp35wkhTbt/pwi7rEIkpJC4kwV1Ki7qB6aOCMJAnb4ueX50IcE6ee9TOXOWUZM88 YfkDMHGGuSV3kaLgONrWGqgKXljyABuVadqRZSAJjKOM9/iNeUfwCSbv9aq8WyD6uy0nD7uR jZUGEN4NkXWk4tm4GJ0HTTkrr+5W80RF2/8kBBRQPGf1x/6a7G9JQisXgg78WjCryUzQY9bn 8mPqis/PN9jmWS+SXHiUpDeN+IW9pkh9UwXsNDkacg62G4pjGW4XBQzfDz9qHNxYA8VgMbDk 8aaUULmU+Wy9XQPbdLWQXZUaV5R5qGm2STzOn1nE11Za5iUwiI3j8VrcSd/MIj1/MCbgJGxe XVyBnW1cmk6cabLV1QS4aL5BUO6xokDD7GezA5F6gR5jCkOvaXd4Fbf0VCpdmbyq8t3Y2VdQ NScU9ZaK9d6dMxSg3YDSOby2F0JlhZykktwGeHPzaWEdOc6Q9SBjXQgyGtaPrE8q7GkLU1qN tE1oyOgclYoqOXomm2ntctH+4LNMvNFk3qCvEbExnJhdzgI+AqeOgSz/HteUpkY5jNSmHaMi XpAPmJ0zbZz5KcF8X/+tjI1z0yMeXt4LJlSzwAs9WyyNVaI5chfD6eVx9WoXUR6bP/HhdWmx W6K0YUA5djwwkv+OP4TlC/L005cAaP6GEqkOIbTWnm04wgxOaRqyEbCFCe5eXvZ3AeF15opg /J49f4bU5ieDBXJOg3oht1dCutqe+xSrXPOpccBcwKb2Hm27PpmeM0Edd6SWU3JoiEl0Xc2+ dwSV73jWhYFANliquFdZpM26SLBDDXeaGRhH3v5jDkoVyT/UuxodS/8D/DREuEuYkUlOepIa V9UfnSjXmQXXmL/FTUfqSyxBdILqEYiZFR0AJQh0iPTO29BkFx59OOYvV9RmlA3HeKBTc9Rw xzE9fDkm/nIsUO5uj5IENRLCtc63RaMH6TY5xy3wsRTdWuOSKbKOiha8eV4985QoU5kknmU2 +1gfrIXYFCoa34puqMeROM/Rk7ba5MdXNzc55OR+UeIgIuvZpZzpNCikukL0N3KlV5WhjVH0 6yZZm5CBAFLh627gT4GepUuqNIwm4Ibc1li3/o9syXDCekZtO0r+RU7NBOMPUY9QwRSxvhoY Uaa2oqSE0REvuWn9tqOBwuwrgeEjI9MCvI/BSqSU20KZ/c86oDWMiJe3InuWDaTAk6GU9DNl TKmUeoxzwFrF2peqrxbCM5HImRzXi1sqgYHMwHf+Yh0gNsKT7ZR5wdEfLkvvoSu1DE8bSgDl P+N1Xjs9IzFjShQFcsjOrAq7sRmRR2D4T27BaAe8HtaHvf4oHO8PJWve/YCAsBG/zlxLRBNm GKicj877jCgxsKM8T0lVe3mY44z8E/8c7bhKQgPmphedwgOAp0KRA5dPx5OXRI5ZVtYeLMaH 6kqKrby6Uc6qODIv1pT7n0OddfiYLhJTZ4bZTBJTnQSVEHMDoNHsnc4B9PcttXhFRFmnubrk 5tm4kHSWzQQiZEt5/epBi9Rk+sawz1kbZGsEAdfUGqokkkCwSCWeQvRo50GE6if/29RXj+so 7PhUUebdmnMSEzJgMD04WBDHiq6J8WQF73bHmWCYWlH7ht5GiEVTWIRldVEGk9Gz3+OyiS+a 4pZUfNZU1KIcKn7ekPCNwwijT/Lww6P13IeXXWQnQBhQLe8yb/1aNVCgUpDK7WF8qSKquBLO JgWcUHHk+il0LSxw5zRvPXTYKiJOWVflqgd98uWrl5xbYPSUiskYdZFRtYOhI70fNr0WRETz uDyL1CmtSEAsC2mKcVPX11Lc94h/tiBFl0hD/9peuUVxXIZMrD5+gMzAMi8q8oalzQu9jUM9 TPx40UpTzyqDm9JT/3EIDU1kusZXIClkvDd/zfmAB2OliOLQOdKGSTUctrsPoXkvWCZ2xwng XUTa1/g1qoCVNhVlmxsgeryBqfqs9s6jXx4RLHA1dRuIl6uC11mWa7Ej1zaeatEKGVmyIz46 wMD1cYivoekxQe7xjG9nqgZ1zE0U6pWxKMZDIftC0KAXDMGv+XxM/9Cq3NkINRsuWICT6a92 tm4aK+rFvv6wA/IPnwlH98xDc+gkNavkdZ4IjS/dkaAl2AoGIwjrSBCmKC/TiRMSMrq6dKuf x5wCVlyQs6BkQXo6naDLulOExgeVHp3/2WGlyu6Mmdv71nfN29+QD3UwrW68JftOTJTOYGUm 5Kpb/RkwM9PhhmEtrzbYgfnu7f0E5adTwVaitO+k11R+k1J8RYQpF21gkdx0R8gYC9E3c8vw rTGT5/kFO6kJRujz0fNiDf2bQrxQ/+1vBDVikRfXQpZpsClocTKqeHP3LKZJq+b9C+mDLXm6 V09jxhw+4KJgG7fXpZRdwCNps5kHOSDsaM1ffeeaySqSpVzxcKPP0DcE947JJ9qmzQuwdgDn +iTWznv69k9XZLznJynfsaU3iOcJyIauTL9c9uSKIhVAHBggsUs/3gmrAiz0rPoHig2L7DCK uSBt8csWILJ3zsiS8J0l2xYmz9+OdyMbxguBgPSNDRqUez4dl4+X+whOpYLbfemZLAOQq1W0 /D9tFpbGsb79VZALWcIv45kYPlY1dRQkRAVmTRJX14wYxCCmJ7u5jC9hb35lREfv45njwPw/ 0/jpL7REiMmN+ytkUAqGfV+2l4I8CtxVuwllhwUS9O6fSzFOEYpqhH9yInpWoNGYoWz+awyB oL30f8YkpWORA5dEHJidxe81RwhorXMvl08YLb2E6jYiV5/8WyOaw1Mfq8lFas1YWEwb+pUe Glav+V8+Db69gcKmWAqJsP9aTkHJ1p64VxSNnw+Sqbcjt/5y76DnC5YA4LDpF85F1Xhzsd1d Awyrvuu/LnRwum3QzpcNZOQ0qv5fbBIJR5uX2LJ7Z51/jWnaN4PcDMQx3QfVNQd9eGv3wwdc 8fNKyIP8FjcSVLSHAetdEajwP9baWkaQBuQOmqgfP9JPDq6u/WD6dgwVpohuFvYUMEziHUP5 1dmz+YZtyp4hC7eb8mX/AIv6CzIR4fiOAnwuVjBC9GmyDrsI8VEB3uV2MRWY+uqArRJyBTem ksnbbSGMue3NQscUpHdhL8JHydfYyFbAU2gBQoYjYhbXBP2EMvvb21la8fUpIAoTBYIknoAE BKkZPld+sgAB13TB5YLfvoSwTItHUeC/J0fBHi0VOOE/8jq4CCI9RTlCOAOohLpvP5bVToqM KIIGkjSK79s4OPR7CdehlW4vncK0w1vKGbuvJROrzBbqoDovyA1hkR6DGTNeuoSfauDXprf3 nLJFs2DffAB7Phd+3sduizNBuLcm1wQHL0M9j3XmCMYNtfVdQMqjrP+Pg/PsOql8xaEU6YJe AOSZsr9zf6bhtklgJXBJLBScRJimeRPQnuGLbqi5JEuM+d6iHTOzz9HHJsVfGwYod91SsU1v WcAEk4e/8kef8TitF5uYp4C5gTqOtpZULuW9R3TsHh2vtZq7e3EiVnHsc7yV7BtyUBIEklxE qeGu/KnnIEpGVgEA57EAVbJvIbqRTSqUx3TStDQFIZ/Dt92FivfyugWfWID0GxQKr5M1PLzd pFOq/gVRWcJX5qHI+u9mDBDvRADURHRKVagM9QuQ7lkvAOPcdYh8+eEb09Ldyxa8cV72j6uw yHHz32YMTeroJxdZtaZTt+ogtDmznJ15ajOzPbhEgR6sF69d3V4xk02EMEb1XfQWv0N2gQtc 7Yd5qGRnRbLpyFFIrZig/4340rx4i/+ZqZDwpXcWuB+aAW8jmkNYR6YXFwrZjsYdD0GQecu6 6NOmXWDzWIkaVcUTZcSo5DHQMV6yCc/TNvB8xpxzTPGXERN74ebv194SaLMTjR4fq4I6hwJE JEpOJRht+8/fkukPNZ5I13ONZDP3LC8GZYBfXMh2p81oSlAOeddzBEcOcIDxazI2Dsijg/Qb rclWWdbMzexqFQqbVprlhBpn+KL3TbDO/cXiTk9T1MZ4S5A+jk1yEwySJrvYcu6/eZSXWXN6 vlPNPFBDsy6nS+YidQBYvKdQk24VyQIx6BJhpmGW8qKV51XyVFPLCUxYLKqrEzLTG+khrVPi MVwyUuIjP9shoUW2T/3j+GxcmUHQjeyeOb7tcTJGfabCoANzEVCSgFtBvBaL7QflVFIwzvuW zymOj68DsuO/ahaMYmdUgZXTPz/ioaj/Za6NRP7UOiQKjp7TKvEf3HlqUIGUl0bqeayfguOF YyQdWc4qitbTnGtMH/IfUGUMvH9c7R7dfL+DaNaNcHWqsRjvRNsnUBjQqaqLpoD7hTmiNEMq ebU5IJiCh0HarF5+ghJHKw1McFcoYGnrJWz5cOgq986fgMRDE3+hQAXtPSoyVO/p4GzAX8Ow HH3WLBcUBuz0vatqre00++JmGcjWyebnhX+VglhGxuI2lKIRpOZfYWicL45vbsj3onTcHl/N v+fo+yYzbv7KvTuWqoqVXpasFutyzdmOaFzf0wm1vjUjEMhLhk3hvL6Kd6RgY2vuZxItf+bf CqkUkEVOZLxsA5ZU6gA0RkikcQcBidL5u/FN1GXbYOle4tXDRqqNi200MTiwU1yZw4AyI9uP NYjHPqPGzlBvBhxF5sIljSaRG7FhgHP4y50zd+Um3YrG0j3TPzHJCRRRf6qKXIWJHnhNvrkt IPjsqfqZ26GmSVJjy9gnpBErPEdo1Q5mr8eLi9P3jcP/7SsdfsTaLtqna2BgovOKhnmsqGE2 BiDzURelvq3Qg8XP7fHxOKTQsqRyE8NKakMpqekrqZaBPB+3vq9dxxOpi5mH8dbZEBvdYBH+ u2+puBu9LwpVI6m5go4lwt+47rFzqUQICfZNQyNbFRD2pbgRMCD+hJynhuILMUXZSS/WvzL/ K0xqrw8BRxyneH3NcXZ2h8HYruKpy+6n2OV1CthHLYpytV0ucXI+xCZFSmK9hV1y+3BDuX+3 pJ+aH7/gsRtNntmy3MHCoCOFotPUl7CWJML3XxfpbAM5QRA8zbos7g1ztGJlezJVfRElXi28 7cCjtAbgQvuOkuG/HM4oE5VBmNHABJbQZylUqQtKPSmeVRKSFnY4TIxImTgbTw13039Ha2hu W7+X5/o4zJsjHVRsAc2zqlDHvM3lbyb/iRdYqwZdO87KKvMhxuE7VHsya6AYdw9RLX+Isz0W Ch+Kk5um0lohJCgr2KdV7m+XAAqd/exJ2gkHzuRHG+c8a/Gvz84Qk/Bffh70l12hNuzqRYYe 1r7BC3gSnA5ChBqnnrwZKtbXCZSkUWiWqis0gd3xNyAc95yBToLpT1L8zQKP2u495wmXj+GK 9w9QbLfHxgH8A/Hr6wbyUk7XwJmOmMBcOs4Zz1Uy5IHwEDxZY1WL6BVw7NQDK1xh/biWnAUu 6ZztoAeeQquhslr5DKQSyxqsN4L1rmBL6Ikt/Zij15N83J6KbsGrp6Bhge8DNyr+3L2NlJn6 FKbxTas1hGldtVdtAVILnj3l2qUKiWYgZGn3t3mWdB1obTSHTUIJSnddd2KsxRKaJg7MnTeH evi9/Y88JN88xZYs74fXU4Ab3VQMvGzcnaPljBlxEx1T+taNTM+z4Cckm13TfV7/59Axe4IH w71f+rX66BvEcTWgocxJJxUDw0E6qVrLmdHKqibM041dUjx2Hmyo8b20K5ils5Oeo26aKsaE FcG6ZWhop8hVkrfDR8fYU8p7oL+tZIdc3VjOSr3BWUpRc6Ly8bxxjTxfoplC7t7U21l/v1HJ e3Ndfyc093+8UYL/MCLx5283K/yjlQQTDI0+J+LURDHJHIEXyxtF7OyE0Rgxjm8YVQq5NqLz KF1c22OvaC58lNr+3f0jfoEbCfHo4GH8zQQ/bBsMejvH8e5sG8RGxdFixYbTR7E5Ci/ARbLq 5YehtKI012tlqN7SaOch0E7SSu4Kp+iVrlaOKwkA4Am/avj62Y2iyBZHo/HTCr1FzKtK84Ry EJy2nx69tNh7XgJx8iOktNCRwZv9ZvzyqlA4IS5Khcx5yCl1NKV/SIWOVrMYjJrs8Moh4Ft3 N1Rw4z+mlN6rFQXDBWPvozELSKCNxs6wbL2CqVBufROiOSF4nNDTZKHm89jGtdCnyF8NHdag cJnSWpqwLdO2mTG1itd6y/nhYMvihmo+BR/me87sV7bwPEhsu9LiFGUmNUqXCfoluaAygV4M F/qjTltNgut7/klJqO9J4FT6+sT5+FgL9X6c/L6dokLNDQsBVGgVMm+lWMCka7CBmaeooV18 8RoEeXZBka5x0fOQilwx13g6QtJ50U+VcoL9xhs2t6zOf/9QnUE0lFAfFZFTrRCIrqkD6Lns wK+ObOtwcZv7+9a/PtF2UMM2G0JQHcXmkMwyF2tX/jbpq9GujzUd5/G00qKqtQHxqbKFTM5O pqhfEkh0ayhppr88Tx6LeovpdNrWZbmXiqO0dDuoUT8m5NjhOt47Xz1Q4+kzneYw3sTvpVxZ X6zBA8puqQAv6hlZzhOicJ8H3xlaWmnuTzyv9NA76anDCRpHmjUp5jZFLA0Xl3Nb/rossGgV K7W7xc3diavvDGOuFVY+lxGHBjczkJ0CKd7IvuBfMYdRwCpMa97L6ejYeMnlgJGqn+iVjaYB SmsqkxaJ2ynzUPrLRohosKnQ8Fc2KH09FVf3Mcnv4XUYv2dqNICRpcMpAI21damMvR/qyRiW tyhgnk5DYscKOdK0Vn81JtkmoVaZBPa5WJAd7oey2pK2XIdAh4YR6e1msddReCLGHnhrEPfM lhAI4Zbx56G6V0d9cX5KB599SHkS2JCthfoBRJgsjjn86HcKj/ToSO5yf6pMHlVBcmtdrQWl 8xrSy2GaQP+U2KzyqgPIKTfkPYojhgvhjd2yd36cfeTesG0H5HneuokiifJ9uX4HaEr26bGw JHzSZLm3MuffufcYcejZWVjpWBZGTPYWLOEjAmWyf8UOH4BlvmB5O9CUCGaikwIe/yvU8b5a mfwhCROxfenTPGRETlvF400V9rBadBMkCVflSXn6YHw5l9FRWBNLpfpwMUco8x0PwJz0//tH Laoh0e0SylE5gwMybLKwiXkNmdrOjSfug2e5R80RBXi+PYOaFReCBacu8L1g0TfzBvffLRcY llY1moCcvG3Xvu7wAuJRRbBpV2Cr5h0b/4oIBs1w4ukf71mcciPFiuEyvP6HVovErwMhpUPN h1sr3H6/0HjNKkZsOaEs9Uldok1K6VWopPrU3kv55RmoUgESSw4Avmoj2O+uE/GpH3vscQU/ c028V+5gg6z/LsSSibLpmGqcYYByiiZ14SMsQAUYupJAW8Miih/ZoEk11rYSnVbarVUUvfyJ SePe6cpYkofPmllf9r6Fdspt+J49xAkwDLXRAah7HBEVY2WZ8hpblyYx8c3i0rCplj97bg9V HE1EADcjLD5qsRfVjAqi/2JEK6SiSRX+xL6zV1+pw7OEHpGrJAZWYcDwpzk5JEU3xHvI9Ltn 1J0TYWkoxnuB7+qlnsRtD2wHUSiiBkbi1l62AfusuQNKt3Nw2uvG0k88eLbUr91zPi/8ka0/ qzazn1i9Kw6cfjC23lm1+haRstEraMnjRLoIw4BgpScqZPmWIcoDKaWSehm0IMcKg4zi2D/w pW2sX/ORW/oAd3yGHZqmhvIYY9odNOUib18xHWDG7ZeUhZU+iZ+ImBapxbeMBkwLCfY6A4LJ gAqFUhOhP7bPQoum/tJUn/MrPZV9+PDQ7kwqZp49MwTRd4PlbhbrasN+SQuNhTE/0k7SA1Ge w9bsbC6CXYSUlTBzXt8TuhopmEemoH+Iz5+rXWr7zGW000yM0oIiRVS2oMj6d8PortOp2I0T HjzXShJkwP7S8lxsx10OTCbgzoJ6CGsmMHZrWmNcYy7cTILMzVYDhaLsTEnEFER6oM58Vq3S Cyj17D1KXbvGpkm7iBxf83iILGms9yj52fqV9TL2epz9mecnr5GM9eMBqHgJJYD30VEXr+3+ MBtt2nU6ciShj8UfYm4TzwQ/j1YOzBBCrqzPLpIJcKKgCSelyi21LSycH4WhbctVfQmgJSys HEPbUliXpOyCvP1/rl7qwDEAg3Xzl8JGUWqP8sIE+mXtYG0Xmxsf2qgSkLqk/R1N1VpM4Yhy 9sHvtH3KVxnBMbd3I7q1uvOnnvKHfS0Zg55qqFCrfAmXWxYmkSzDDgR2kyp6TlSe8t5jn1hs YRJQEpgsmzqgOFwSMzV8K+hVGgSq+8PYRFl5hydKLRu4uiY2ghI8QJ32jDEWE+wPWHAej4v3 t77pHh/0+ovpJcdH2xv1vbDMxd3OTG1qIcgEg+xQ4O3lFpDw4951inY7ufcuj160igvzvjMx PP1QeB56A1yRv3qzoceaQZipozSejvlpY4P8AdeNFVS3id3Z3OjlamAgK0dCL4gAMRu6eo3R X03KEWKyngTYtAzTyrZBgeYTfwzp8Tv8N8Y8WzjQkH5NJ6BwYSUivbhnFfxahK8Bl/jPSI8B dD5ptFaiiSIrpvNPNvbc7iCUlkpQjoaBH7llpG1kGWy1PQuUdjs804gA/VScugZtHLZKkRiX olyoDvrs4lYGZL+rHmYQ6LMMEPtTeQlS+DupnDTGXrtsACcQNx/IW8R0Bkki6q82njzdHiAc 8L9R9hQ4xJdC8ljQbUrGA9a/v2qJFV+Rfn8SLOZn0GaIoDymIb7fW4sobESkvNwojBSOTtQV Niqta9zmiP3tYntf0Mrd8myTZ4p28X47pN6uD7UiZbYT/ZaE8MW09+bC7yXEhGkPhmPNe6mc h4ODZWGtvtjDFA+bcMD4o/8epjzbVp0G0KY+HQ3JSMevRB3cpCVG3aFGV4FBkmtD11MsxKHa uHbDs4emxWWukd6coKhxZHDKqv96hGtP1zCo31B1X/dy7qZayD4N9iCXrAJ89J6qZBvuxchT WERxj8M187uZUZyjE0SxGu6T8ZjkU/rUNRUTHpyTYd9hxGMmqtOpH4hZ1g06gAgmYhRjLK0H cx0a7eihr9T55IVMTA49Srd4ymqWCc1gvBwGxDOKGpEp44ErbrBiDDC/2XXJN0qAiuQ+lG2Y F5tm6DlB7b6brE2/rQQGqj3G9rZYrtPc7wrHI7fjhZRkKKi6wv5FQSZH+CB7H1QdHKk79bwK mKXnhocbJGbRqqO/ixnIyifiVaU758fGsHSf0zhTkl7JQHW3gxQxJ9Ua5hi8DvC8yylbKat5 J2gCo+iY0V+6iopxLf+ec2+s1jZxv8XT7NKq+rJcvGKBOtg2MenJp2/QH5tdNejCOVHezpcW PI7T4VQsmMi1SmCTTrGckts8WV33zoVYI4j/L8e3RURhubIQMLKdxBxCfphp2xnvEKbHrmWC wiDmcerfeIlr0BWtJ48FMfNzqeD4VXheHaYAvgUGVVW4Hv7vw3wX3/IA7FiPQ9yQgSmem1AV EDzD4uq+LJFFAfGWFvjNsKRdB3yG6++E68UKsClkKobIiVARTzIu0DN8FdQeJUCsKs9x/jx7 BMt+xxZR4j81C2znnccuYjc236jD4p+xIbxUtpV/rwwo+SuWO7KJOOyNTbvUGe6HEGvk1gKD Wt1XBNuB7QRbMzdTf4Z6akWh5OremhRWuGfwrqyb+sQekRcrDKbATcadUjSaaXivrL8qxwfb +rQ9dYJPAWid2GgfpUWdI1atETJZp1fsFHOOepHgb7xEVOHnWPdT2Pl1Js965fnrp0HOXD1T 8U1y4Nv6wZR/ZxI5FR1ET6AAdzNNrl0VAyJ6lZXepH4qLJpggONfDUQQ7uCrR7cQdlHPcira 2c6vopGlm6gDTJyZmnkScOL5XhxbfU53k1P3Uc4Gb6EuCB5V8+r8ztR1uUxBH3DKGReu6wya iGtbxoaOrKnP3hcENUhBpJLg00AXwzBlMnOBPulQNY5Kdu/ZUhAvfzR9aCau/pVQkdxQPD14 JTTuE5ZbnXKGzot6g9SvPIsNasuOekqpdJwNwwXNxbaIAd9prHtpSWU8ts3r6wyc8BakLklz UTJYFCzGIb1KJJIeolvQi0texFwuda4+Olynte2uUxJpvaCHB2jjOXfa1KIxuH9bc4o4Scrq c/G3D4iXJ5RcfT0AYEGcPhm9bzM0Tt4ZvvV5WppVDX4a3sEq/gc7J6HuQyxxgCU8XHk5J3yz 3spOwxHLKnXvYE4qdE/vbkXroZ/kN/nTXHAsdR6zfbF60g0k9zrPydi7TrteZvskvniTWeB+ R/9umsyahtrB7kwGQxx1SzWWjk+Do5o23SHM6GorqQXym4Mf23QKx8XGBHu7AvFdiWYFmgi7 3O0NeLC/YvjWKAQNsoZbWbXXrkYo8VgrFtc+N0Wri4JBaBR/XBjoNqLJhjTakuv3c4ZcmfYx jJNpmtYNbAEwF/B1IntmSIdPJpl7XvFhAsAquYf8ZQSfVCCXAJKavD70KCp90E34YGXLc+/s /wQERy/ZYKFAk5EeuKWVduVSc6OHnUXSwGEk6kxQiJV5cYeZEt0Vylmfhi4RQT1HXS4WCHye jISySLgRO+LreTlqfyVNUe1InOdPwgt5Fl42oq3L1Ayxinn/Baoi5Adrg7jsd9nI9HGmp4kQ qeWbJfiNEzr1ao+hxdIVeezdXMDblRzwqH5S4k4lAHSvEY9rq6kQCaBJR9cHMTQpTCIKmC7Z myD5Slxy5RG7/GNj53vuQkiE1nS6RcI+rJWgWQKjPh3eWM/C8Qi9x1TUNjwHOgz86W9I5lvE JVymhkMVjqE9/ZYbuKhqAdFgCB0esPGTcNrUIKhHKgVYjyhdXI2ElCwgP0LLjVcTxyIbYP5M gbCA0VIAjXn2NJCp4i1CeYgAXZ1MFA/F6FK5UZU+HUoaBrUZzioVJjOyyoYgzOIilOGE8MGW PHEHv9DqmoqfBxR8SZchS4m3RbniBX1tcHB1r3dXGMSNFDx2uQqcNXelQTjpMaK0qPlX0HrJ 9WMke8Hkpi95b4h5r4CHfX4HlCDRTUOv1+1ehfxGard7DLVFduIk2kriFm7GwIp94Q9v+2AI rXvoPGB2XHmSSpAxJxndnKZFD1VydyeZZyGmer/jF6uLnxr4LpTFNglN8ToUEdKCBoXV62pm lfkvdO4aNbWJJS04kmRQ2oGPy8R0sxhfQ9MRxQCEGQVh2YfQ+7GMUpg3dyUyRhhfEsr/y/zz qz9qfCwSDgP4s0fOl+4stpY57Fohaf351XIZYsCsuRMA5oin+c5eHK/WJCnGDjLXKl3ie33y 0y+lbleaUH5dgscN10m33btODXnual7bueB/YwtQFx/uRyf0AQjQa3tNHyQS+cteTOZMe2F2 b1yEN8xCueqljZ+3nWJdCyYRF4DVQOkUQ3xeIO+Ie6x6e0GBv/cHmX2EfAfhw56x3SRunirG bCGdtUds1iDUqig0DkQPITeNqPYIbuOVsK5ZZhR387lFKwvxrKKWqmtfGddOI1ipabC8cybH XHvAZmFnI3h4WG9N386AJZt+uXpa3sEjcEavMr1TOAX+vD3ea0MTQPFA7avkUrQMNM0M5Iz8 iLFjy2+cOHya8f4BVfISQD/7MJ2PqXN3BtG7rqhcRD1tFQK69znB/Wsk/BHTa/d/W2P8rQyc etpJsZk4Oe3TLeGSWoEDieU7+6A92LVJzSDKjafudO8LR7Oq/R952JPry4BDY2OgLynO1XWg n/DhA4jST9HuD4Bat3zY7eO314uTolUaflv/4rpPsKs2nt6YVuAsZkDzf6RXg2IyMeM9wTr6 yhlKrilu/p0YljNDPDGK5YKrWCPS2Hayt3yQGB8oduRegV6R8IOk1C1i5Su/INI06XMiT3MR ZKTzMQ07Z1FllhVdnJ091dT3QF09RI7kj8CrZh8a105IwlOjaDcqm1CyOJ9jzok5oEu+TtYZ PVc+3u5SmqcvdUy7yw9gnP7lDzc9iq6wkBG72Dme77ITlAIEwz/bOzdt0gTs9xm6KwRuF4qz FKYzjcaRd+6UEfKQWQ24OKQ3xgO1LnMS52WQbOija2zDlxC0AbWLrim7/Nh3YRTQCAaSbfqI RoSI2LWZOXhFwGvI7Q44q+zRprpgkVgzUdFqe9ZvuYo+hx2imqmp8g5LoMa7TYc+iOYmSBx1 kVRFCpQx4E8631nqEG9LRuzmbfpjnM3aIsebh1/8kuEhFlmH6LqgXOwCpkgDI7OURAEXjKJA ViHi9xLFfyKoR1rLAxsqHwJR9h5Pgu8UVT8dZbw5lYn90SZrwE5p7jOTiaBG8P8jl4CLwbBr q/bbZsdPbK/MwlgT+yCR14gDfgSVwlKJJPeNloYniL7g/eGO9XwTbLQfH9kF0r0Zwz7sfCbt BX4ntFD2x5WVrUkGbrnve1PTfFXnt5sAr2ACt+q6mx0xknqWTHSni5vCR7QboHk2cVp5hPDa txkEbLgY2plu+qq/EESsg6hmEJB94VcuUq1M0KClFEBeSuO26bl1V1zyW8yvqWQ8111cXBwz mRH3zYeBmzbmlvje9iGQbeVt12hskaWKqCsdW2gI2tkFKZIix9JIMZkKJ2fAeubVQ0ZBbls+ 2HTs2n25gI/haoIqFQX6hKb3MdNumzjfcwyFfRordxXBcnKPHopZv3stGqXVL7tfnoGCAq9c GAZI08zRhjjJxDqQfEhZUQIq7UcD+2xqtLMWk2c9gc4F+qoCV/juYeZvi0h6axy1LB+BD5az mkUfSS6xVmIL3r4oLrPfPKxtkAqQK8CDf3CGRe3HPf5EYsRodgSzgsDQH3NK1Oxijks2TINA 6ovTOPjDgyJbWuL7IE6OV7K/l0BKMkz/3J9XzKwbVyErj28v8IwVaovxVY3EsgEN+fHAlFU6 iXaEI7B/ys02AJ4KpA5Bx3hl41+tB8z2CX2021HvTzoeocouvccvOaHpJgUaBH8RuzuRPBkl JN94ABFo/h9KPABqCmT2itnUgBKeLPq99MwDsC861X666toz4bd8obLn0TJijg6DTtS62pLB QP8JMunbgkoYeERWSyTYbsNMEs3OEJoKnYP3XHu66y0YsCEB9a96nvK6b4f4SsK9+q3DcCv5 zO8suO0V/gqXuAE9lrlhLzVg+4S5LpUSZBl7Srm8VLRtsE0hTS1V38TtNcYYRyfdSeostoE9 UsOuQ6a4aVKlq+mbcstZccFwcil1FqmZ+25eJf4w9MzJT1U0j75AwSCueCukVq8NoZLtOPI0 UbCu5wWXFtYpNhnAfAPU+9HgzZG592Qb0n5Kt6raSXHPuv74XKAPJiV08Jq2BWKoj9n/meVY +QUqoaNkQb5xbWvxwNdOGLZiNws0QOHrHUmM8W1e0NQWrPW9f86TNOTJSQnnTfSbp/64z4t0 E8M8q4IiJtIFCgdShAb1k6UBoFyoC6NHm5LXUSM5INFSjR4DMEj3hqX3a4Qd3oiRRdae0aeV DBqy3SerzRXqGOHszgCKl0FkfGaPLlfmYybNWqOX0RXhCXcYfy1wZqU39Zzp7CZMqhOG+vTK 0E8h+yhBURcMFUoqAO4SPb8amikxPX+V7JGyUGygQqcTp7t41JuiYw3wAi6II+3JMLtGn7Rn b3FhM2PyD8fkG4qY6/aKMVbEqKhK6JVo3D+M47OLtacxYszqXGv8Cwcu8lHFUzs3lzuM5lMv 6r0uNwzW68YETv3QQZ4rKn4eZFLV12YMbTA62DsxMsrWXJB5xaEzHcPCFr9hS971m890aj18 is1001QiAyPPW+OJNXseZ7Zi64do41Y7P00IvgkKPZNATpi7mRuXwavi9m+hkdhnhSSJ2Rgw OFyqfzfCmbiqIpHtfp0f8V57oW0E3CtuTgy9LiE7lw7lay+tNfR9Yw3m6uPcVln15KZY+c1a s6i31nuK57DE9alkkSokmfz6UkLPsZIfN4KcCext+4tQErRz0TY/WhMGvDoYhYub7tDOSqQA QRtwlov5a5k1SkT/YasUHXSf7ev+EhnVAPyApk4yG/JklNbYu0YpWoPIYYRa+vS3IEuNWmar 9b2nKtqWtBvELsLCy9SwpQyBSW63NVte6ykFQ1Ul6c03efbjMfE5LND6V4iiFTHw90mBDGeE h3gyfx9oNgc8uyOzGHClVeYtcnenP9oug2DxVr0zbMwJ5bI4JMHa3FYn938V+WEcLz73Msir 2187wAGFESb8e5Qog5GfLiMW6re80iTJ5mQ8F8WPx1QRrZALBbF/gCgvKUO4BU42u3dph5U2 8fxmwM0M6E5rAh9VWdW59bWATZV3dawGMNqSAU5007v9yzkw45tvw43ANVhMp270AumxfIG8 rEHC4UynglPQQzuRA1cuxNVy0t/2Ic7PZdUs+EG+Vvu2zrgzRHqfcOte3jKcTeAvfeC8qZrJ fU0ybJ9uEhQ1p7hqDZQuuYttIBSZUnTgfgdljaWGB0BBdy120wLDLvxzPBnCzUwVb7ZsChYj lPSiS/mYIeqpwi7c4yqrBvG24u7b7ou+gQX7hD6hIHOEkzbiJQpZZP9uNqZ3og8AHQ3CYiqK xfdtmQR8G2KPoeKY4anIEb5Uxxz6UL4glemq0Fb1JFukS0/19IFqHUsZvEUhGWH49P3Ks2zU CtoLkqzQnGRV696GHf3SwXOZ5byGoqlEVHiwY9TF7cSQTWk03bccCwaqHNh0t86OI8VKWCPu ij+TtvMDXSh1wUDgsEDUL65SidHG+Ql7uJiBoBJqnCYYcEyZqr8dFuqQhtmJratCd+glOQcx +ownsfDi92Ag2Su/47lPE73ddmIvuYnKM7sje7SNnsHT2fsemHrGBniTDqVtlSmfivOQkzZo yQexHROJ4pSBc7xiWH+PkqMAwiGdQPp02/SARKDaUdrPc+BYqtiqZ6ACJKXDcssIJtcNdY+d JcnquI26Wh7OuilvSqmC3TsqRjMFyW3LYNpOy78sCert6G3l27X6Uc5hZH0mG6BgiYIiaeu1 JSknMvDDyXEkg4vEJ/q4YTvNx1wROfMWp016gyFSZnxaC66xE0CCkwRsu1d8V7CZ5EzN/VsV /oUqQ8kp4pJUsiRvUzaoVwDj60CR36fEgBwoJVVQ6yfr3AeanaA8XmgXdOdNtmtw9MeMM+9J Eqy3XOMzVQAwSp/48udScptrXcj8bQojBPQ/nXXh9bRJLe7jBC77YsMDdmwnkBo2VdvwAVxb KYYZ2kqqt+2lgtPJ7pqUROUkwR78TM11HibK48lLBr1idKBy3iRqvrOhFjSfT410ourSG0wM oC4ehIu5oxWolIy9rWHvT9itcQcmES1bMdkVdTytXoeYu6KJ0TFgkF9+vkuP4qbJhfGxo9kw F2+atXst4O9SDFTfUS3O3U380GcvwSbQb8BcQM6ae0MT7oP4lL+XEi77Y1SCUHdWWB6PSkvG 50tc9jD0Z4lDLg+oKE2wSHizLnMYvIdpQGqtWca3njqvrtfA8B9GsgkD0Oax9YwC9i1ted6g MWmr+5n5VS1ID0r0HIsSfupXY6iWAedkdkJUWQeSY3QL39dB0rZpUs/FyAm/N6weHADgDsZU IYm69JL8xXEQW7EEXLU9peCRJ2gly4yJk2UoD27uZwbC15omwIBq9FTjXDk7fmvZ/JWrngcg MjpyoHowa91G8ej/kYZwGSi/N0pdHdW3Fjy9LZp3FjZajPZyJDpIO5MZjj+s8tbdiuOXk9cI YeiYgoS8CPn5BepBGgYwrXgYn4mwFK7BGJGQhQ8v5kl6amEF+fxhrmOEc2hrq4NtSQH9PlkJ ZmNbta5qg2H0JGxEkWSgROJfHtARWz3IPwyBj+uZ1n3FkNGjeIlef6TMx0VNPlMSNksIJfkr 1BVjPrSD9XjYekXU10EeA36zGAMyfYSlgfJ2tisI0K7bDtQb6YvzKnHGQGy3SXZNBZQQbzrE +B7yU7tw2BZPBmFeGZbmaJ7hk/XSNsOBdXcfYXysYwUqxGfy03YHCfyVX3/8AXeY+1Xz5eI3 Lqv/DpV0CWuw03cXDlAA1jpvqzrzVYBL3B7rNSwDmxusTMFwfbuGNgIuNXHf5I/b5A1QPfWo W0PK5XJVbLJnAfYMzIln/KOD5NEtaX5pfJ8EMqXDsy0ECTt3cy6yEFlS5qacNP49HHL4SqiX MSGYw2WxiI6fSN2SMC/aDOihy7jZoKYuvBckBZw2jGMni2K1B8/TB3KyHOSTOD7B4nYOK+KG XssflN8DKrUGnzO6RuU3xt5mM3+DMqwQSp8iERlJuKNeUyHYiSAwHpoAXAH8XcJT5VFltVDf Z4XFyv1TesTnJ5sDVPQ3U6dI4DNjFd6dSpYjbYo2/ot/uMf/2Gw/WID6rzK23ZVvFPQzxFgc L8NI2FpWvrkFyFzhKEaieCCH9Esp4xh+cxgoQ0j5wFKAFiPtnEJghZdgi6ke80+fQEHWV+LV Vskr2blmNUScMey5Qn6Bs+gjtlMtL2OTcgTi4S3zJrhGZt3DusBNUDPgsdCytzMS6ECLz9P1 iAw1B+VvkT33618P9DOlaU3b1KdQsLz7FomfdZsZvRKee26XhABNZpgaCk2FyCmDNkYVNMpz CMM84MpDw3mxcX+uvUdn9Lc1giRorIPWWNiTFKQPMC3Y2Oz1UDwKN0iOLdI0DOuFeoKjekKr SPgn8iz2KYkVw1vR0nSJDhGvRNGEZpfVc6WXAj5nDih+8X2OIIuirqLPW9rco9+2oa2F9J1w 3UGb2Cgnml5sF0LAsYdhftv2eNVHjFXpZt7ESoR9bCK3wCTLrreA1c07fILcjqGZil228zRD hE9qt5SvGFqrEFIUBfSRIHoLGPZezMJJ8W0BhiS1gsT6TCxGg4U51gxIPZNhG9uvCx7YowEl AIySW0EDw9RTkgzT9qg3JTC9TaELLiHlYEFKCqao0+hsP8u5ZbC7ap7FqxpMbqyjgY7ThZAy eboRANHOOQ5oQQFQhIf4Ebzl0adEC6gbGrAO9e229jZOW1VRipsZSMCCgUpvzzIAOaw//2Nm MnxdAiURwEC9hcKMFAcJFH8AnNQeFS42ujg4jaH5dMjDdMKahNp32+ZiNFPNN0k2c7c8ZwLr OHGOVyZGKn23gACzHE3i2myxHUv5RgfUdkHNOdwUg8BM+cQ8+th/KaAROn601TUDPtWOBKJ0 R/BY+l4RKJDw8NvAcG+oR3wTt4zkVUM78FEG1q77PxkI5LpVINsjyen/18Rusp0kip5RnB99 cafl2Hgjg3NM67rspf/vHtUOiD2MCh4YuDB7YXfmlYibaWfEKKgH3knM+4w03gdedYaL/XZ1 C8okaHumW7Q1vw9kQwOxO+IuEouIsVV42LAyYpWajEYhuN2Um8mLbQhK9CXU4mNlicBTQ1Wo phN5+OouCQdSkDtEQ4pXl4PbPKXe4YG4JEDQsMT61HjMTOLZ/X4BPr4UtAnzGOEtbaPmjElQ 1dVJha7M4y5l3+LmQuTf0xuvucRntuz2pAb1EFalGIun87fzNDEFw2/tTO2P0se+RWA8OQQn XOrLncdiYvjqfpCKyy0VEqxOAFd5OgWJSSrGEwTXhLvTRH7JQ+hTtKUdAUZohpENqxvmPwdP 18nyEpmJiU4Xs2w3ndlP9pUsTO0sPFR8+nOBYgNY0wcJKSMS5e2Qgh0npA89aX4GjCpQ6q0K 42ldEZ/Pl8rLK3vzupd7S1Vw0W8Ra4gaW+uVd234IE06WG6J+n26yayuPgcW8/knm9SlWciW 94jaV7vCtvy3sg08YhlpEsRGNRm0BXWOrLMbX3eBrtIx5woHuOQITSvgxvlWZNq/OhRFhlXP vIWAg4dbM5TMWGSaG0VpxYMhF5qI/yh1mp0iEGQg23EpbE8EkMWqSXJ7PJg8f+aqlMarq8MJ hiUl788RIT/YLapW0FXnyJJGkJ/jYirs1bzd5ZVWxY2ReVE3D3AJ9R4MPfRcejBmT1LFy/MC x7DOiIDIJp4+T1EpIBuRslZNHFm3oZ1lAWrrp+h4IHAugvJBEmPjvfrbfvdS7j0mzJEOq318 HhsTb7aiLexWKnJ4DoX+By5YBy+/teDkj6Unu4HimZxS+Hu7sgNTtlBjiuZZ7FKEP64hQm/U Y3Ff/w4IesFxaDfjpUmcvlWPgPTiLsu2FiJ6+tjtdxC235b9ufQ+e16WU+ghXJceczwyrmJK OlPzx1pquMipcp8SBQyT/1ZGfq+Uels4y1Dz+gPCOTPSdUClafE8wr+UvHLgDVzGvxZi9XQs OTYgSU7lCUhAJ2EIxhNKM0/OFXEMZQltp7+tnFV5iU7TVcMYo7DG9j3G6VqPVPGtGKjqGqt6 Nua2YvxsuY99m3rko/XgdIfdWSfGklHFoZpJAVlgb1rfROfo54kbidHNVjrMRt3SOYxVGtMc KzQQ+1jtevSdQ85swBHV2qV110P45CE3F9WH3nMp2PxO6J6IX8HMd7KwnuV3pQ+p2H6d7PR4 fFjHV8pQtsydgxDe5uk1AtujQh13pXrNiLXp0HCamPlpcznPawVMBXEvvkMRGvZazs6Vaa/7 bAGd8rGvAQVL9tT81OAk0b7HGFUFoxZ7MPwHtoAAN/a3hbGCk8e49cBEz+iIkeIA4Ok+6I4G B6uir4CsG1MCXdp0qMWDkOfFr8CZzz1PUnkqjS72FL7rM4nOD7/tcGYX8HfxC3DhRMNOtKnh H4dRmVDSty41Oq2olcIyDSPScSU0P+lK8i6WlHXCrMb61rBFhmkQWUS7dqqZgTIrGBhnQcbA i98TxFc9fkbVHsLJsKXcE2edurrcK41DHe03c/wDGsqt2Sz+hWfMglbeiTwWHJmoE0kDYF3i XrgehBhPvEAviYLk/qs7Q7vNl1t7ndx4MZv6P1JwqGWlTNKcyAXD4QC7VEB8C/uB6c2x9Qwi Tfzuj6ZhCUnD81LGnavW6y3l//I8um+rl1PXUUMQnpW/GYfKw8m1yGTTaT5ha8w0XTSG3N/6 Ya1GnPM3fVP9XYJKSPuGgNkD4jKjwG1IE8Q/+Y19IXlt/NBlrAGok3bNqx9HvpCMAiXWrY8j yHdB2AsW/Cz1zqJ4r6PuxenGaCT1KkorKjQEMR9ZrHCu9knxSBBd2N4lgm60PI7FoLvdy72D YMv1+UsrVa50UsQli+O5EJ5Ha38GpwhwCgVJdic6JgrbTeson4g5fBHgC+8HDips6Zm9MWr2 L+PilC221ytB66dmUcVPxpD336fn51lVj4k540BmRN+BXuH+fG/Aw43yai6OUEnPCXYOHzdb ru75l5vyIoqqxwC7USlKg8WHuH4quXPOI2yaQln/4gza2g8WDG337DHTDU2Rs9BgR0uxfyby DyiWCE7aRwLV0sB+hpGCv2U188AjDJ0dN2Mmf7UZBzOv1VWzs9j4CPIhDcNnvMm1vfqmjvAM wLuO5NKj2FBb+3R3dVK2ASdRkQPovlmeTZISCCNoZ6GQE0YsNssTBOlSpCan6pdppQEg1UoM f8E05e7lBFMdh6WNDmFN+74TeKNwXHkx7MVa7esoX1UocDpVVFX47jH5D5rSzqPesbgJxbkE OG0f6Xk5k6YLR57GW367KwNsNqDHuMqYgFUMGif9pUswdl6xqDx69VTu6+9UCU7uRs4sd/e0 +o45hoeMV0Ry2YbO2YT/8/a2EtOzdIAQMAYKRur+OSz9hPghI/RRQemERVTI1jsyZn9zB+/E R3KzjOtAKJl1k5jJmdr+TZhN0mjoewDwbfvETfGW1jFZk1tS3IziCbZej/qCE1BzLtHHQF2D Tc7ukf8zZSEGhMuM+Qu3z2oJ6lA21qugusfVnTWlzqUdTk5SuCXJn9gq47w427bv0ZBduHJU 7c450fNTLPt6lhXv+M0s9ohwumwK+2twy/oyJbtm/Qc1UHE4FZ+XQ4grTQELIAtSDmi44eT8 UGcsSgXaEffjVDooOFiK+2xa0QhuY0tals7Cgc+yfafRPuK3n5xQwlVOxOss/JvAff5cbuO2 A4aPkE/Ujris1NXXbwi7mVcm0HNnqMNriK4Bw9CgscbGDXZZLypP/67+9wXn2skREUnMUnDu 1lb43A1iMaqcp2grbYlXq9VL7gMuYZXv9QjFzNvhVv+q5ynChImKujjJ8w7RGlcMXWOvPE5m w9E1Orc85ZZymFYutITOk2fTL0LP2l3f3W5BtGKlVow2JxHN/gbPvS2j12nuS0Jcq3tJUn8d XHXbuw4AjDeYk3rkjzvroCwlbRRTqoK1AwJAn+vlHZdHUL4vU/F94H4FOodvGDDSkrj6A9x8 hebHulsTvbpgMo8K59UzB07M8aMgnyp1r8RcaxlYXwS8xQoCVQi05PAF6BGPU68YkHQ8kZfk Z2+hEh2rq+sNn6F1QL7MlGIATDXzPqEb+PKqElj9P4H3KeanpV6dXGKJrweaRVeQolJ2Z0uY cBRkT9NL0hZAA8CXH0UIuX+QNvKVwcmk63/uce8US4zjPUQuBdfFfMgaJQyDen1lXCNY4spO 0MCz1UXmq9PSuwbX1HDETl+FDr28iAjAPm4WD0uT15x2Ee5C6OKGIAmd+rLHB6YXlczB39Uh sLLZGAAiYWIt1I0d5uOPD1T10BrVxmbm4cWvNLMZ3JNOboGVPGMiTuM2brKkQY9jaCwm9oBn Jmy8TW2NednUoan6SoCmdNDmRLHPNuU2SG/s8hmbIU2wuCNOkBxSsb5VMQU+/WNPFTYW+p4/ 90hJOai/5EJ0xOZwMW8zWMcBR5Wvxe0eNe1xsKWe7fMiD/61XqLbe8sJ/9AQL8b+iTIofzsG yLVqHC/APYrA14EMwK9GBVDCzCPNpRnNIrN0l9AnO8Z7D0EvQ+iN2YKsDxdRUN4TiDaAve9p eHDZWFjkYpLrJ5iSxmr00D61skJt7XLyzy4atLxVglj3TsLBnEWm8icGkfw2DDbUiM2lA7q4 y1Url+Wen8x5evFKoGSEfRPtjHj83s2NS88xkiTZD5divZF4GbSmdFUEH0/u4IE+SlRVLfSX EREEqhk8IjKEHgSr3PENMT4ANr8bi5GK8e29q+ZaFB34l29FgwvL9OCbTQrPqrUWOAiqQAlV cn3vw7XIoRlt2WjfD7oj5SgzDcwesupPmvVlIZkXMMGTKvUJO5OHfcyNT+nJjBfB2Gs3DF9U YX1b17ryfixhTEaoEpuHbieycW7VpQJoWWZUD1Merszni6a5Tsx1EJAmGMHVDJXaBsvxTRy7 EIr7VpnwG1xv56n7BxWRKpOmsGRDW2xjZzm1YSZ6yKaVsbJK3wAOE2DMuWv7aEyi96Y2qmqt LHc3MOJUAlq3WQZ1EmLrZJdxDm5cObMaGlC06YTd2rPgM5/zdJ955q1rwkfLH4oYQlOvxLDm EodmEDKW8EZTKwHdlkhvJ3ljDs2eDtfac1RF/vUWQJggwy+VD/c1zEJeg2psp30YFgA0euJy fQspnNcRgJ1dbK50OyeykJtrDrUdv8/Dix+bYcZ+b98KD6QetHJRjpW9BN69mFG3vgKTmzJ3 wbVi4ucw50e+kx8wTNuNeJYGXb5JJJW46dvV1E/FMMUqDcF17ZnpXWqXuqSahdiqCGB5NDGC 88ceufgdg/mSMrSbNcK6yryXPX5kxxHevRkniktanRHdZ15fJTnUXzPamVsV65+aTvXwBPxx LvOVV7d4qXmqGddI89/jaZO700uIYsxhGVTrgbw2Fl/RVBylP6PRm5w75VBRSh8HPqg84lGw hHjbd5Bm+B29By8fWVcOAxCt6pJBTdWg6cC3XJQwBLqNW+mV4gdcK4ViX8w1ZllSCQBgObhC +a8JSw/JwsPqMqTRs287dgKUUNMeKJ0ZrrqvuhTVLIEA7huldckkBcbI39gmcgxC6oDn4Udc NWix6c39HtGjgCXRIKimGaCMnJscuP/sQsu70eLi2C9LcFNei50i0DkuNNdWR+eVazUVeuWj yBhskBNm7OeYufufLOYFqIm66L3ZVPC6+mfcEchD54S/14thIWGdAUbue4KdQsjYOyBx4bN1 1j1DcqpGNHjh0bkH5jMHlvh2j3SCDqNiK9bGm3cq9iBNh7/+69Ntbk9MWCS6ytAddPo4Lfow TOB/18/l042WYuX8r/Jh9jJx+iIqGXXgPr9DfSyPHd2j6mXQqZZ0Sv5rYiVEUwBB060PV4gV fijIh+OhiUj/Jt8VqXyoQT7utX7tN0lo/rYXXYMrDFSyHz2bGw7A1a50J62uAMItNScZkW0p M5dDokuZ1uQCeIzQPdVK/gvF8ySqVUfpjSYcgU2kf5VrgJek9XLGxNPUsZx9qKeDDPO0ifi1 f+LoWG2NyDOUoObDp6hg77QdxayDPiN+rG/11AJZuT/VV0CduEi/3l8eqn/asMKgxL/vbLPK G3YIM1DH+uUhxTHkROSMcFQOxbIG7ZEfbq5/jtzyxysFhuQAlmFRaBY98x4UMSFetn0E+AKS Nrv8s8MNVThvoW6NkWdBexcdGApfi6mXuA/co4+2xGBQCpAtXM6xdNOp6GhjrQLvOxjrgdv9 NbmfXhKuUBlstECm8j6E3AxVfcXm2tLqtpg5SAe2R+ZH74RjYTqmWv4/en3HR2DCWJRHAJQB GM+BwuL9sSW4OFIvu4ufvdr15+WQNy+5RNKU8lQhKc8xDNafB2KRN/iNWbx2KTLSgPUOvuxa STZZxjdXrdPC8NJRHoPXA5e5RV4M1rBx0i4Y2f2pQslPSvid7doZSx5dIPOapgfCC4OtxsFe 23pdgpXFMVYHgjydV3XihoUcskSCwv2t7nusqVrhwD6ToLVki1U6eIoTu8c1Y2Eu96/PZpwO +UR0f7BMzBrDAwUXkqMpK2nUKsiap8gE6mSRdNC6cMk9NkazFg0rsbuXZYmgOaZr3BC7L4v3 2gi2KV5WdY3aq7wYRWBgJKF9Hgtm6hxuwg1HveP3FdxEG8ldKSWmpAfdZi4DXqX+KtMVONaU 43JXTAYlAT7MsiwHkb7MbRke9X7yst0vx70b5gzcQxiTaV6uiHtLln+iayMPLUrW9o07GX3e zG8GSUvPEYFKOdhSqTa4l80uY1PmHAUQXft8pb65y7RQX7t5HVBe20cX7uSgy5cV8/bqBDhA VaRKt2CtkIxY/fgfF5etqJtaq/kJNAOdcdNV1Is6ajaqzewn8oiyqkVVa1VuLe9bJOzpjL/8 WLDJ2meRDI6AaWS/AU4sqZvut1J1iPcLxqNATgysgG7+1T1yH3YT9WAWeWU/7O+nxCXKjEih 4S2bl9ou99YudnvYvy6gzYp7fnHWWCv1cN82N7I0PDCjPh6GmuPKIGr5QKPIwcDZkAEBRPO/ 4TUg4+OMf5rVWRX1sfhaduKTBkG958nZFtcouLlGqU1pv1ddEXAuyr24JHS6pXxz81FEPrHC rTRjr+olvSJcmZqLQdlVYqDArq8R5xQRAi5GQ5rkQM5rQpV/B1RNKGSQQ03qLGkIxHdhYDAa 4j8Kx5NQLeYfaantK2qcgEqb5kU7XvAI/NYw4t/CcYl84nGDDoKImYxTH6nn38L/YUJSoKKH UYtOMikh/j0XBY+YsN+2LRkgAIGhDuKn2+EvVk5lGnvqAebnSsn+W7WKK3eS2060dZh/5OIj lCQgYiJGkLMvDsBe2zd6U+t5Q1sPFwDgY6C9y/0wOg0FO/qhOev1f9zrs4kHGeOjGIgdlVcD mOA0bK7XSbg51P4tew3fUrzYFSXHOYkRk75/cd48VE0ZKDXj/7kBIV45iTpV2MHAGFWEWV3w T+swxAOFkOGiXkktxrm09t7LTw6sPLOoXA016Udms2Zeq1yrt9AFkSZSNLi8FitNjAmuQ84x FB2OKRNYtY7yhbJ6ugOaGE1VGzT6OxgIlKdeWxniLrtU3kSyLU39rtJ1S1H413Uc6RQ87d2D t524+Rq8lTE9JfKjYk8sJ+nrptbSJ4bAK9iCrF7cAduWU2pvmBxHRemS37+sXwZfvsYcQckg QgM4593pgmRzWqOaCX9fs+difAAcPhVU/IgRJK9BFiPtoxpb1KguLAYww40uHUdaMGPgisg3 h+jb+ZXGUXYsRDsp47Ipn9B/+aYmC7sL7lAP0o9YbEg6RNo4mCEBrBx1gWirhCL+IZhaLurQ 9Dm04Nd6RM3y3GjptFNRKZo5qsPPAsVpOiy9bNI104QQq4wpWnbhmcyvPnbafBZR0ChKL+bg jIKEZtVYEnVlPMPpoViDIyZB0/TBu8H+s4rO6/12vy+dj2TP2GQMfpwsf1bMMMqWy3SkORGN 6rvNH2t+HDxhJxNzg/HmL1HvFqsHhYoOTfrsX8ugO5AHydlZnYz+qKmKzi++GeSN5xognKqM eTWLHsSfTXlk5LJcYr5Jt7/+4Hc1F+7XvvI1WdXeTfn70qVDRU1sfy1TJYSRNp7UryzdFT6H Y7sBnxfF+i1Am9fFvYv3Ea0m991P2/nN3q4U/yXwNAqeWjwbqFvSHyCUXwTSl5x8gFGx9dKJ XC7OlEUD+wz2Q5R+7w7yvOuMQlI1p1+bS48hw0xGhgObyNP0Rg0oQTYDZpqEZdatS978xmcv zfI1LP17BzvYe3PGrEHGPgpH+u6mfc1IzGAt3YyeTMftgdYfu0SQdH95F7B84AapUjBhfvjC QtTPgkHK3R15Q0x0tq79xaSL4Vesurswm804iSoxKYXyy26Ortd4/u1duPPN2TYl6a7qvrtl 594jkeDL0cVMMUhPekHxosAkaGbHZ3WFHnpB5ZMpDsHIslejL13WsmGZWSoNTfdppZNsN3Go H+m/vG/nT4zHktNLR+57aVyZXrjWrxai7AWqLtvcnlJI/chr1QyOZnVn7wXnKPzoMWE67XWh QIcfD92a+Fc1thlyV8hGk1s3OUM6zkpVmPUqsLbIUHxZpLRna8lZC0ngYID70kZmtyv0rg3f Xnl9K86TCyGeM9xp2GfmzLFq2dggg29BNI0ohDfxwnBWhT524QMF6qKcIC8f5haYoJM0NPKL x/yiO9JD4o+SMWENzr+vlqpvBtcqXFqpnBXhxQFEHjrY2OAeZFW77Q17OgJ8MMfjJKoflxf0 gtWhl6cYMozY0W0DGg5rRPYzU+5mVcvkBJK6RVdIE55bIRkdOJT0dvsEpmUC4Q/j8mx+GzTq G3a5LHXQ68yfS1tnP+kggxzXxiQ0cyuqtvShttLAOFd8vh2MOQPMayeij6Y7AHv3CDuksxKP qHTA6WE5qPbvlHmsXIvSqCe52U8LSSLvYN6HvRn0Sg1hxXQDzCk+CAzaPp4o9JS6QXpIrG5v XGgR4ts758lD0ci/+mdLtEk5vMkWTEUW0n9P3cusES/2yngr8IBboT5t1HPRXXvOniXgQ7R8 c/ITpicCfMAwnGWkOe4Eq4PMaX7/SYHimW6jZpoB6ABIMnfJbzOHg2Clu9RiRwhyE1rOn71J DU4EcZkFrK/REXq82UQBxDY9+TqKlJ1C0660k5boqlomDThLjVOKqrVVzM6EXQfRn/KR9AWL BPlH7QEE3hSJqtLITY1pC+jDDIiYpXfmTvDtueJibKGh3McScaxZk9eLI8QsUfGSFm7tgu47 COHsfd03UBOKU5V2584qD6M2/rHKDhkMi4GXnL4XQwrt1Lf4ABkclyc+mVU3zB++vcjxlkfi STa7uB4El/5nNvMzlVJa+A7wXAds7Zs6gjcM9lqyv5IqdJQYuthV3q2lmbqXnw2lwVZlb2el IsXv1OYL59nyqKeTYn4XYxBhhDU93i5HHyZvodfoRhPELo96yX3EijAsqMOLIFb/M3eJip/5 DePifVoYSaRp8EcgaGj873RgMPV6/t5Yw5XUSVSVemzAy8JHzzTyP4xfraJ8rz4cB2/yI4yX Dzo1hQQe58vHGK2hdHlCI95WX1e5UIrl+Lt7aPDYaCC4rNhV4KUzb0PwDEbc/Zswj7mfoJLc m5QYB5/w2pPS+2C+HcRmY+Y7pzq+dKlbcyaOE/y8YdjG6QEwOw60NXRylirJUofPF964gtQc Bu1z4h7rJgn/z3HXnWOAdgaIkXJNSKwvsQmDjVDjAinPvemVkRCobT9hCgKC/3GJJOpq3Bm7 F4WQ3+Hsl/DnB5lsUU7usSL7cpUyy1mRnoBzqF/drho5yshyYX2L2Q2E0IEa2HZKBsxYEOum InCHwcyim2J0h4lpEJr6B95vbeyV4PnyLSbt7DL2t3SR7ryL44WttUbsQnHrCVhCghptoEpz r9idLrEJVig+WP52iWcViORlcEwjfx8I1ibpvyhPkxoHE+Pa91YdvgfDTW22rFzrDlT0SEMi 1UVuALWfwa0Jrvpl6hxKyTrwr4Lqqd4Dhc0HAflS5Xi0qzIesiqeVO/omzV25uticPPjnMjO B+SHDr3/lnjhBeBobRLBHv/e6fYoqiQYNa/+UItf50JgqnCE7g+rK2dya2HPxvTPb2VTYs0W bVmJvjluujdr3AZhqBA2A+6Tiu2rZr4DKm4s3r6tbVcOFgymJvqa8UqjIz21OniaQJs94wzh 15H6kHrkA6TQymM6pkzvA0/SlTWfTf4mPRRvxjhnsiXgmnUtyfuPxF+m5ZpfTEDfFzfJoVnB hCvYrzEAFhVALMTr/OQZoGJZqRDqzXo/gg2pidMFHBqKf6Gg6pccnfWMFXttO423gv3Ndnkr OfMjPJuTficWVVY6YkXtTPlU5aOPT8/kEhsG3OFrikQNY1DR1aiWlAUSrBVmUrgsOdKQp7KV QjsXThn/6eG50jx2yN2MDW2uCBDtkD/emOH+uAwj4tLLHfBue+Kl+303RImtGplYkZ3hJR57 1Y2tMitj2/hlWhFo83UFCz80bf/1RHHO5A7OtX369vhvOg8gL5J0g/lc5ZGg23uw5y9C6EI4 gI0+P3RwFM0a66JflsQLVWcoeUIPdYWB9bB1KunS45ga3k9Fx3JK4E73uEU9uP22F35wML7M I8B+hGNdoUZo57cLczKVt7XF7FqL3AzqQhflHz3CEgXGC2hVlHjx1OOi3QQRRdPaXWCm0Ph4 3TCypkQgO+yFPiTRmSiJ3LvY1TKGEUq4FtE2Ne8magvsMspq0mhhE/hHTND0Z905lxuLel7x r0AsDmXpS0glBHI1XvA5nkBYIl/P5M32Xsy+14BGHe9XaDlmCHk2HWMCoOLGWD+AQEMUeX1w TTzcJF5SRoH40ZxAC9qfoeGNDYkumVNgZWYoHCPfyo6P5uMXV1BY6mD1pafJASniktNIXedh shc0yQFMSyVRMEUTAl+eZMgmzDRVqw+2AeNm8L+Cze1MR/l5Imr5I1kAKuR7SmD3OecBXFNI /2rKjRnYc5U0Pn1lHmT+483BHVAXzVSycQfqXhhFgaPlyagCiZGaEQo0xptWUSpCSxZy5nLW J/coS881LDLqlautCdD/Ic11Cbq+O4pFkDY1WeIxVfFqmvzZOPE41sJX/X+UiwkLvS0kfxgN YYBTay6x+gvk/H5+HaOzy4GW2Tgqdv5fmfjwpV4bBs3kGVvznprW/gE8ewozID6j82Yx0Fw6 L9HGoq9GQy9+Z/Mowwz3a4ZSmE70WdqbxNc/nzXFKBHhDeJqAnRbyKgc01iQf+gWuxBjI7en QVsaiAC+RNYV6jXhLFMrrHcCwHChEwO24bITET5l9bGeS1jDqLLBNP8KPMid9k1vAT8VqWFI QX/8F2sZWauPGhoF+Q0ryGzwS7kSW+9bUIgFVYRAL94UXoqL4Yko9MPf6ZrQRaSrcZiZdIc3 IXlzrXijTeOBfiZa/6HewQNi6ruWJTWeCGhCyYH4V75aLnP+Ev68kYACjmAeCojxQRG4vZAg HHWB8pBa4ai+ETD5c54RwkbdtJALmEGnlyxPTZWwvLNZrX986qWGoSq6hufWxE/lE3bHbkt4 W7/CjFUqE48AvGq/mWM1MCMPdkZ9Bwv4TNKXj5e7xSaeivmGIv7q2dX8ock4qbIWfZCyGBKt W3g8rc/8G30kzOgORn4A37fWBAdHuiYhCnXUSIXMogqD9TKxRCGXS8pNDTAfmpipDl/nIaOa PdKpDvVKa9OCUTj+qsEIM2N1EQLfKKcu5FgHJIxDRuWX5FIPV+d3MluwXdddLrOiHaojetYZ p+K57+x3pctpOyRgNZq1vf/TF1SgjoxrX6NYrPBlqg0jpP6v04Zo0ftHbzUzzyeZNV98rhwf MWZufd1Jw8z4Ci2QG+Wm3zGwWg1aB0ab7N13X2qip2q6aQkuwEglovM5y32xXUiOyfiZlIQU EIshg5n/Utz6EBkjYqoEIw1spkjHGwRRDIC9a61oEuPwnDZlE5fewx8YcWD2f9T5lNDMVPO8 tOAl1WJ0+KkRDmB4yVq1PMySKy+EZAbuXFSCZf+fKBFdpjc7+abaMA66DoRQfmGBNzFCnUXh SvFaSQMtXmrNpgm3PQ47x9YsNT8sAuhsWrdRU/fztL9KgXAXZc1nXt6w1gyPhSBA+q5gnG6R tvpz/n1+wHCr/Y7YgSvxagcAb+Ifdreeh729cYp5ySmLC/nMiTJLLecneYNUQlePuGhWDHde vPclEoUCPSmJeGADzjh0Rx/YiqX/02G1SAS101QZRfnZqiYZ7pj8XVW/xob1EGu7HIVTcAPH cb2kTNKw3hrmlC5gyJmsQaGaIfvaRLFzIctDL83/tHtZrNrqyBdAJEuPz8tHz2TAOUp8NNkZ 16jJsiHvaE3iwncvP1wCOTwCgOPxen/V/ZeQD/hGhKxH1GFH1BaegE5jxB0B6+I+0Kq3tW/4 IwRAXJ9/tSq3iW4HXWfVPGVDlx4hc1HUgL6BpDmhm2zO+XJi2kExUMtjVihtmJxWcOMlz5LX zndUEee2qGqLpg95vWe1m+B7epsJK2vPUqjmmJoRJwo2ezkXHRw24kY/Eq0S6msfFF0q3SRw 6eY+eEjnLIwdubxZs3CMajn4glSMbUVFzbBqO6FtCty4FojkWDVe5MdjSZbPhtrWiVDcIGFs ibTS7E6uK/Jv8RPiBNAkgc0Xft2LDJ4HSfys+GGGB5KB+uXogBDBWoKTkpp2hmfxptG43V5D 53mIt5/fSrvhQoUaQL3HxizTakNQhvMZWfmz311zTzP3YdY5A2s9tVjTD+4pnEm3+tFamm5a NKvrnF0ha8KRgBfbwNnb6I3KfyVBnGvSjNgSnJd2l9veQWviUrR9KeO6SEdyLLEdo11JDlJ9 YDersaSJu8p3D25D0eaJn9OTwOXrVHZ40slSulKt5hNYfyhMgmUqSY3zg65h20bxNMW4tLXB hUT88DqXWTGk4rdsSrGaW4EAa5uVEHYebnhL9479jEUaTVVE/1Dc2VzPnhvPwL+IfBPvR42L Rjc+1JJMmF6IxhF/pFzGKZDtLcJIj1w0PLlf0W6gaRE+dxI7Lhv0fyOyJYwUVOeeOWd9eV+A MwfpeGB1TODeG+tLO/xJyheuppFHUuv9aFRZRNIjEh6FvNx19keB889VTCTcl/VUMRgg/L97 aS121FXgBoUYt0MEGLhYt5fHqJDwf7eNqpjPRKCK1AvI/B/gsnFetgMT+3F2qSOUGHC7mAyH i4cK4izufA/riaymrDAC4jhP1L25JxTNO4m3BPzldyWQUKi+0Zu8kSP12zapXID/UlXU0hL1 6jAIHaJkQ5lSVRjKEbg2s/nKMJtb+VnGNTJIFeWtkbNVzVMyFRgkIu4Y3qfPzRmbrCojz1Ub d3cLl7xfWBMexX4Oc5kNDklY/y3PL+DRU9JI3y5NSaXXFnN0AZC7+rVGEqwc4EMVUiKvwHHY so4l8fI7UdBc7vhMd7Xeq9JOXmo+g79N1jsEC3dethBhdg2PG8+A5/nHdMK7vZcHjEXGs6i1 uLT7eOWD2k4Fwl6DzuysjxYAjKqpKAM6TRfRKXrZrgfEY7i/JVibirp33jhoQ15j8V9RJUfW X3eMcuBJf4Vr4NrXpRoXJMJ6MgXSP9y2vbg2Vmc0PEpcyra/8iPtZyeoMGoqpAwptpwz8Yqm rlkdlAlgmh9JjTXOFVdO0Ms6Sq/RDLufXpF2WsE5Wl3iqzwD3yMNse8BKQE9qlaMimlaIc2Q 0mC5gLUExb+189FbRVV3zlMNL0YJBLmeI1cW/6pniKj9AKOI9N+LUdPCt8Tvn13wxyZuJR1g yX7dTweFy019DZ7WbAypq7xA2HVNT1Hi4qA/1C6CUYoya4uhBr7nrNI2p741+k8qwEvYYK2a B+4ksEo9Avh6jf6Bloq+MQFVZghfWKRQdIGbq0rbShsh4n2qQledMSYuPLh6D5wlpkQmlhkK deJPAjFRoJ9Cjx5N72wl0oaPzptUt5psQwf5HbIuecROCVTPrnwd++hhph/hIna+qAZ7PIAG KojLuEzcZXrxByfFZLXsJMV8HkIrDRdnA5ygjIVWP3uYflPJadQQkTTeWrp7spGFmhlTX1l6 jmWSnbgxpadanN/10fPD6aYwhx4pmB86eh+/FJPEnJuzW7mWC+kW2uS6K1CU2z/B736XNgCC 1OJa26qKHxvCrHL87Ggiun+UUGrQCaEYlm/eKgtx1kfGZsUxgv86aN58HhPb1ks7i5s3Qc6K +v1ul1G+S4VHmWvBD5w8IZKl1LK1s6ePaDbecDNLBPCg0s5bypXLpd+ffMT2u2Pcg9RykHOA by4xgqFPmRV/UJHAYi9BzGId8ZDk2sXK0yqLN3H47MEmt57p95QmRY2M1g5pBqcQFFcB1QfE VmHo3FTTIUVqjkg1iBVyUmm20/pNS+URP33PM5iY0ciJ8sPif19bH0zEklbF+Sl3nSHAZsfs 0NlcnJUptNrfTMBGo5v7GHXiTPevMWvVwSTdJKDgYMMFyfFEtOprx2Zs3yWnDtkuU8WilQAs sDsYCDTJ3UGBwrV+A4j1ulSbtO5RXutffbYROY7D4u8k9bBRsK19hrE+mybqaGstnDskAQ72 5eKavLv1d1QCB6N2IwQNNAa1fmy7Feas4TRkfcnH5VbQdJSajdeu+2RUE4XA6a8QaUCUmNv4 80JkOFqMJcrpXRTFDBlnyn8KLmPvVaAGZ8DvGqzRqlNK2wGH5syQyPqpbSFKwWhpJKsLdi/o TdeVsvkcZKxND7/mQFzQgle+2Aps7yC9sk51BhPTU2G8ccT2nGGWdKgmn0BKtO/fjUV6pt2r HACAIsBXAZf+PAl/EJgjHb1ZoqkQrZyv7KnWs0TKp01IwlGvnXgCySdQiDU9det28I66rsUj TuzhBvehKSaKozq2yGVnQcp+gJbMYqWwRE0A24y8tlw2FtZkNzOnvdqg8wxxz5PiZN8BKATX jgcN/3SREKmxNyWR0UoZ4aZ2FwMYWb71yOhDMtoA5jCxUUUvbj8i5PoUGb1Op4enxthsD7HG R7vd/lbK3EbrGpURtWIViOgLrcipeIcVheCrovvxSNc3EMdeu0+PwI9BSR425kq54H+PlJoO pscK0pO47HhWpQvvmGiDdJj/bTwQBKRAr3s7JsKL/lXeLsaKOV+Kd3qcXloUkwSNwwj1KwJz SlKymDFB+4n7OfY0EEtRUidlwSBn9mBSwsnMOq2Ov/Xf3CtzvSEnXwanqKzkwJ7ozyd41Wm/ MG33ecIBKSIBXZgUqkpkFK+fOGw/hYu7juMeR3DJRaK7V9JkrXb6GIHwUuyurEBwGGRgbzbq hwe9VZCoYv42IDqjAPdWeuy7qay8mRV39SnLcQnpodPtWtpniiVHYiXIiDKkAQQ492OLZBZm 6OaIEhvY+MzWDQs26gx1947F73i++LYxw87jaEXRXzOKyUrituQud3eOOvof2Mp4RYr8/zNh u7UaxGRJwPLzEdRgLN+8dcYntkWnB18iUE2oIaZ2tK5SSbrQrRJSgqhR8dYzKo5Y5cNGfJtH jgQiCs3WIB0f6IgwiBt+pgUZE/zs5iyCm0exkFsdCVmoD/HtxbHzBV5tdxSm1R36KERVnNPd 8F+fZo5VjndhquiQNKaJBjNA4+a0QUvLX+HM7IVmBbKvzjN739A+MnnN1S1cFxWqGqgayMTJ u2cGSQhmBFkvxi5MkKC2f2JA5QE0O8GBy+EtnyAZadG+JgrVNbFTMGggijI4CTLy4arTxGn2 cgELBC/WnEJCAnhL4/Lgd9NBnKioTACEuEwI+scNsRwBHtdPL7ZEFMHNV3DY4mb1UHC0Cffu 5S59LEgVsY/+pgSqn+rKDvBjKU/tqsUaqslYjuIWeHa03JiCN3AJjqU8SR5emmR5H+vM8ebT Lz3hCsjb86GB08ssm4rKJho+tg1e/JL3WvsBG7rm+k6ru7vmbSW9C5tr9N2o1G4DZqPto4GR BxyWz+0TLGuG9v3SM6K8TOJgOfz97NuWQk/fgty/7s5Pe0so5QrQrvqY++NhhtyzGqxkUYKt vhPO5T8PMYgQXJ4GAdWwfjcEGorFdwBNYVvLBWHo4ANBrluFXVvFUGtnziACDGvDqh2pQdUD bziR7dYzzzK/haIDQ+AhpLzRmR/Fwju48kXLWGBteayO0YGUlodI3WWZUMqW1I9BzYQ5H1go Y2Lue6EELYYjAmEOWps0RPZI9hhhIgQIDKc6MLWDvEW+pyd1MR9dHYfr7gqSZQ4WGCXSedHg jTws7AdIUWKy7FYMTsa7G78Ikpze7PofcNeS0dreyMnn01xbK/OLNmQRM22iFA1fp5Jg+bTQ MCrI0VE7+HZbJ8f7amJgSToUjRBvpC2M5eSef4LZtlABnO8xm/yoQ1CKJKwtfYGkYaP/ClIf ghAvUbqRiF3COiaD6ccoddGe38tw7x7aiq74TpH8wPVsSNODBQm9yX2cZKpNSccKYtJYpu2n NbK/h9ofn2PgTasvr8eIlT4IAhWr471qyJr3nGPuzS+5a3KNgmbDg2KhAoMLsesKrqwfzV7r G2u3fP58SlMyyvEPZQ9UtuAqv51pYRIqctP8kIC0VAductgE2HIrnivUBlVpNKJHqC6eMWBu tAnWX1vo3OhG6hFOTp/6ASBX0r6Ih6xpFA5PFotXAREK4bxhNTGhH8ibt6l5VFkN9Z0zk/JM JlOVDEMnbWjplD8US3LfRW6rbQplHtkKZttDImx5pfpQmEAvBG8AlpW//IqC6wA8s4ykucwH QG9XthtrLAOtPKj/jN+IyXFU1H/2L32wE/56nt3pCAs5+WQWiLQtONxRSXhSEpkKz91Z8YWM w9AFHmErC7V9nStgUDDFqt9gJkFU1g8uN4WBA2VRF97oFvSS0sbOzMeC1UbS4Gxbhpoz30N8 /o1fC4UCDfWTSyKG2SyOTa7hnwt8lQBJj4XYm0WKW/3bA29SOjh2/8+7tVDDW1KkLaVi0F2P 6+gppqFg6wuORjuIv3gXHsGnlf63R00e5TJTdvUygGtw5ZdGmz/cKQRiHanEYgxiOPWpIG2f WtDUrl9NHEgC38K8CBL58lcsI8i+Icp72/Q1e65FkaMMPeAcq0H8JG2B7HOsoMVRpfErWlJV Oqh7eO/TkuhKOHeCI/SQ7p6Udb+2S/UyemF83a74pWw5ybYEcixO+kb5u8WYnWbURQRBKZqi uP38DLzN8RBTzc6nxu/TAxCK1isPDWZBJLhkF6XPU5k2pFQFTzpLCvq4Xxxj17f30LI0HTpC +IJ7Pwkb+Fu6hhX+vz/1Zj6KWfhCzzaAwfDuup/THvIzB96nNsLI6bXLtjfiUJTarD9wJg/4 7iR1sUYbK7rglW1Vtf0Ux9sV+u+yO9ZKuMwqJ5KaHG04OQuj9McHfDl+90v9ce0EOFpEFxH1 yNoCxyx9QjlCbSMYKUp9CEzCxGBOvLm1bpJmtgLy7YCi7mbjRUODoiQaH/Q7UCk1xgpc3Dsv QB5PSQ4DPkB+Bf/O08LySi4iUZzqqF0nh4TJqKhbnxyQfgr/3qMKkACaLCFHjXK/MGBO6L/S INeyin4dItkUN/niVAy0DnQeKwUrMiieuxSCEgokDrtQL834m6Q2yutWt5b7UDTmW41WG2F/ srC0Z30sAtojTp8xzUPcZ4APFp5HaRe3xfrq/OS0bziNx6xn/0aXtqlkFVGhkyuKOxRkNvMR 1qnkegyMlRRoqQpjP39rIkeAi3vuvOFED9bJD5MnJ9aNWu84BjTUJBIOG1Xyzi+gUagdPtxA nfuNCsa/nCU2h8nM/hmjuyN5aXQl9knfzw677ldkJGjfQ1akZQU06Q/9XIzPgk4U+EnGyC6Z gZV1o/7quB8PIH+8frgh5ZHRF3fG+skZ4SomWNBXtebp63T+u6A6wnueVD1PIb7ljcdBvG9p 9NgJaWC3+6IYVNxuIqIO8hAiOZk8TKO+rTHQwwKZY6DfnoRAcbkkOZ9L57F7sBLkGWT4a9AR Vz25EU3AkBw+xhxb/KrNSUtpQipXyfRe6nMmPjt6nA640o6ZM4yyDduZyT7hZJS+W9ippq5M Vk7MZ3P4sin97TeemxO1gEtbQuVW4jj3joARPuKlE6/z1DcrLcREaa5UmuQPmp2YdwJcHOrm Wq6vJ//0LGW60AURjoRrvNoskKN5vO9jeReQsyNBJu4apox2CmyX/EKdTP+sN4DtdLHlFdXQ JXXBObw/uqOncTYdNNLFDhUrw/diooJ22xqvnHQANFh460fq67UBecBr5YEddYLPWQYmOJBQ KWThQComdS8nvHdi58NFU4YgOmtX759CWdCh5ChfQM8ZyOUU14gp4q9zK+yExSsU9PoPd9Kq t5gOYTZhTil62cfAOFT7D9Lut17c9o98UMdrPGxQJuTx1E5TZ7Ii6ZYi+sr+RUtLVvGnTgg3 Xn4MWe1yfTHlKkX3zGGMSYT/Q9gKFoA5/5r/iqcM52knKQjrtBBlva3zHEIQQf0uTBxBLgBu UFBiV3wGYeSz5AHAZ4SwTxDNKRyyxcqaylntlxTEf6bz3gF2JVVsr8BVKImMJ/imMYinyNDN MXBxy6c60C7MT2qxgFrguk1fHhPpKG/Txkbablw6vQGaSdKEGP5cimu695UgfkoYkofpx4HN g0KMlCGctHFsoSFZEaLTesPQjhpJYu0rPWch2L9YGW0E+8lnc+q8vCB3PwpAEVnF6lsp2WXZ SdbdK00ax4rCsMRY6doKK3TXR5c2LEpfKmA4+YWpd+NEgLH3FGsfYH1BxQjNspALFA6nVwHS f97TbNfcbTJg3UKCIz+1mI9+QPmnJBg1fOCxSvef8P3mROfLWBapKILE60EPdcjJnEnbM1Ba AES5Y6eSG54eP8SgtxHLvzuxxVM9s8jAwrNnD7NspRWeYKTyxp7ixNBtGeH9MBrzuyYzsxCY PfCg4yq6EvjTXXTCdLgjwNSSZij1SM/IXkx8KLYAn/CIcPmlaw9V7UjzhtN4r4ft7ysCcE3e QJcyXk1Sg+H5rtWewTf1ND87UArtL8rd2SvInlPhdR+aze0qZheXlK3Ye36uFPhoXuXVTiBR XCUsZ3DmTDJEnM0ahnq0TER8onl5Z3aJUHVZp+NUDSFk2T9V16BTE/ykD5QZO6vtUqU6GY2H eY0KF7ozxECi+jmpaGdDC2kFTA15uzCqosSKytZW5O2bLjpUvRvmz2cGQgAaOt1+l9v4vkYX BPfHMOzxwfUKn7FiYcn60jBkirk5OSuFEzmqRuZMU1AtGP6hBFuLkeW3PaMeWXrsdJFoQmCV 0zXiGZ1ASc/QAKZQAjG0Ai6zCURlyXO+65odsZc+DlGnCeFSIMPssvz2V9UNTECy+tjIpT/E ifUxiYvBgVTLCI2Enolxh++nSwxZxdadG6PgoaswCw//jg4/tChsh7WrVrV5/YKU2ZiopdLG xeA25u8OBGqeicC1FFGK4ko77DUYlljdrDWtn/+ics83+Ro2wEqYeMZpwVJ2VMiKK7Vf8tSr rdpxYHjc643sDlOLffg808ox3nXhIC4dcgnYZ9qSU/ax1JosaDnlp1eYd0eDdGLtNM4KXMK+ M97fVPiHMJAlmXH9zjcUtftV9j0348Ok6ssTdsFbD6VStw37yGDlus+FvYxQb5Veh5MGfSsz l8KXHOO0Gg3+h8IuUgFqhGP6NJb0qUGbfJ/U0q9en3X65xfmsXF4LyahFxoky0QQq9BepH/T 54dTI4WiTk0ASJJ/LkAtLR3NRz9BgCmkitHrd3xYnjvBlKkME/voF+zZ1VgwsTELdFTyAzQU lqe2xu+8otwuzLdAlUae4RxPAiKeUQhvOYO3KFjqzoE5lSL2+2na16fLZwOGpSTd0J6YnClN wp79OMcW9OIUPmIKKAyGfHUGuSM3JdX4ddnwIC/yoo7jKH2XVZFNRs9xreavOgdKGVqw7WAH MeZD40uFvVxgBUO+e1W2SutSB6rNbgC6VKiCE3A4K6j0FnVVod4INqmwtFepZtpWrHsecsFL 74/Ly3vEN6MazI6Wl5qckXbtTDlcRALtFC9DAMCq5E2jgjdEdH3ZbnechYPyyb5oe6X6aIVv IHbdTS99UxHnPGWzyqURzbRbuq8V+LiDUT5LtsVbEMJCu/8srMdcmluTL6ClO5PIDj3/Q+HE bXF2bqE2ozix6ttFpwGFOMDaTLovnb/HIUeEyIdPMTF/yr/cfHJjL0ZE6Yap6ClVqnPeHScZ vf0Ix034aEya4+AMHsMABhy5FKIXWMasHDluHMIs1qyTY+BdnTvVF3ezuhRUYyTgIQdP48vP b3tHZg0UU5O4gdFbHmiKCPbwockjEJEpmfrxiW5rRnakuhS/T8m1bk0DSf2sGg3NPI0C6hli vDOfo5dvZqaAuyBJjVVz4rxe5O9qotVbz8oZxLoDf/TM6Vux+zb4aO0pGrOmN0O1twgbAnPY lMXCB8qipS32wKy0avXruqLJzYjJXMuAcGrongeg0MCeDnK+dsViUVu1MsgaVxpNmUlzRoCi pBHvJlhMCE99i/vtAYTm2Ws5lrUk+EFskKPxPmOWP03ilUuPq0VDiroUTnGbIJ0Js4gwU9as 1p9xSEGNqOmZbE/vf5Hq1pNGig42Trw+iS7sMKWPvgOSRtsWfSrqme1SR0+5AIjNgxB0iTI4 6eK6ru5K0c/I1IAZ87mO2XFB+3KO7UEYdJFC5k+3X5aC0T0rGgB00cOleuSW7dwTFuOWniS0 DzH55V1AhgoqZicRrZON19nhiWHfU+yit+6AJRCml+UsnCR5zNnGAD3H0BN+Uk/9LkOraFIk 8iKOWWDKGVo+kmlmJKudO1JCfkp/GdEFJ/+j9qe0al5s61byVqjnQuMNk2Cx/epYOK6FdxrX /NjoJFRpzArfYJDUPRbwnBl6/vqPcE1RLGp5xGnNxVIBKRCdFt24axSEDjzxdvzKfKsfiT8o OfdfU82+kQdxIAZXv2ISDdvOVJQfuI/PuiN4Kj4lQs205TTmi6YFWvVo461zfKQguuXMdos1 so2+RzIGdph+fidOrrT0eFviYITag9WzliUKRWHWoAMDc4M1mS0Me3hspY3l/crSpZZyH8P8 8chGv53PLPxVMppJ9h0O1qoPVl44ZKv/ENw+OzX4X83G7QcXQDvGG3ghoUp5JRXK3JyoR4eM AqFgcLmBQSMy+4vWDuKlFBdtH++taL2WDcYSnt4f/HF46P6aOO3YMDJxAMtrIBrnlVeyHMrr kgwUXpvi7CiIl1LcGxyIHZC30YRgNOFVUBe1qmO3zSOUPXMl1omco4xppW+U7EajD1uyu8aK v5i7JCFthnj8jhHkaFS40QHeqZ6ufX0PhFnKFrbeRRdtNrXI62nb1irRIgiGuFHx64VAkxJ5 3Ys1klsE88D4AO0Gw9zXZeWuTipibLeTe39BBO6SuiTN6QuNnL4ZoFf4tMGy+XNhnBMnF4Bh 8OSkpiD/8MeHoQD4Od5oELAgnnRnj1iTS3yTvKjtp3RNCeHhPrZtGRkFi3+LKazHLXKvSRf4 ilWVDOIvozh4yLH/g62fUk3ILadGmI4cYKADh4RpNpBaUKFE8sTSHKOhSDYHztaD3H/fqR8g iVnZt7clXmLWDNNvzhjRIJKi1mvtFROpXbGN2wastIARf8Far9khFREGhTEdxGyFZq5yHucq qqLHW1bHRXgeluZdk1IGh2rJ4AaEznLXv28ytXoX+3EMUNyIR7PZc05vR88qg7PsJzRIRvqA 2LUgcAFRg2iNGz6ws92lYfiU9xyeo7B6mMC7TdH9dqn3E35OkECtURbovHRu3Z1agNoFnADb rIxloYDOATa0xXyFvzUXgCypHW7tRSH9EOQ5Ma3gm5gUZhvPUecC0qN4kqnuYAYEwVeT7Bbg Mk8zEj3h9TJyUrbKxCJZ4Ty4iCNm2II1qiXMHcWckEgxTcJDeqy+dd67kXp502+pkIf6PZct z5PVFGk2AgX55tEGMOXxPmtAFliTbWmdYBB/ZKcbvv5wxHIAeJkYnAi9vH9Iyuu/DOlIiGCf RXGJIMe0Y3HYzTNq2wn9C1fZDSsWw5lXrsy4KYJ2jtJcLmpa9ojR6T3s9NAMAmGYNbcSE9Id FVqqU6wDzzuPD/mfowqb5cWbqsUZes/u56V3SykWAp1bOk0GAoyEFIC+y6199hD1linYH5aJ f7n/+qRHASG/CVQyiWy0vICAB1GTQS/8Rmb+YEVlasmOjEkccdgC+iVXIkSmpZDS4x27bO36 TU+sO5El84M+XXBsXl6V1zeHqHGRAA55tE8efQSOwF1MyAc4dyNm1n9oGFRi800aDu2HCBnM +GIDSbEmoP+AsvBN+dShAvY2ZGhba+KR5UyGWvpjv8j9KNlCYWPItLjmUi0OPTczDljGr4eX /ZEGMjSem9vn7K++9W6OQ+WYWovsl03y5j9OUlXJJJ29S61jb3ZHQuyDkPYNYDgt7lTrc/HS Xw1G0mabr8tNb8Ui/JKFsj4iKIlIGgMsrbH2tpAhHQrn/JaACJU7+5pMtUhNfFRZQvgpL3To uIv/xE20wt0DPBOTDrFni/U89fApzur4G+S0m7K3KANzmOnSm8rHBAzTK6KS2JXwqf8OzQ1u 0LEcc1Lz1Q9CWBof9NwxsX+f7Avp9KE5CYQe24chbgAkO+KV6M/44Bxz8uZ2qfi72s7CRnNu 92pIkL5pYbFy3CmYotRkuLqXj8nu/UNB4mVTPEHjfik2QapmY95tDYqkce0xx6FjbhaaLSX6 Jeks2OCGLjwdrwhgl8WLXFJjMSC2Bj0Z83NlRYku59+kcR73dSiFM7fkQkXN3svS3GvwKAqu YZCr1D1tNw/IEzAd4T6NsGJYETE4PK446RBYqmyt56M26wby4g2vgBQeqJLwCCfiThPevtwZ o6VWn10OL37Hnb0yF6AYB07eApwBjoNG+tVQMPfGhj6yxl0gVwbXP3cK0+RpX8NPBOcCRd7J BRojYDTNmWt8XtV1gDEaPj+UIihx6duZVSugliZbsY6MYwP0IUQpH3mm1Zo4ZqG15a+OCRO2 JF9Hit6W+djn/EiO2ew9I1pylfFyYvlB6+YF5K9ppp4GO60KZtd3c/fJWvhc22a8GVpV2Whn es8GhnacnlGDJ24S3iLfd/iiyqgIV88ErZAhp3xFiqVraCtb/xyHvPffddyy1ZDeMfhQotWj 3d3l7udWhEz8qtHuBY77Bx/X+HsoI9E1wMQIuHql3qC6zAFweGhAoxSPaQWZTv+2o87HQzjt BxbU1T5a153H3meT6B22Qdeq/jAlCBX1NewQ6mlBBeJLQ3noQJcZe2lRadL4vkZR4P07QuXM a/8e8YmUp4U28rpE3t16a9M5IyEjWDN1HL4HRJfa5R4ZwfjaWTfLelF6oOS2QDyCtgACqjJf ibjittsSgKqMT9ADl6R1UgSodBUXMlSC9XamIn1fwHEaB+9wxEvsF1dEbvGvJc0rrHsDzNh+ ihEPkIvl7BvSzHT7t8b823vve0lPzP2IL5uUxe5p24XMRmlXm2USomLHnnBPFLzZdzHVpv7W uccUmnmsY+id3ih9m+KkCO+X86AGLusNwEh9tD6OW3zUVUy6Mx6+dqb2NqJO1JMH87DpS1v9 MgssfY9KFWe+UPhRA1DQEiIMX69DCcKPnW7UGLM0z6NaxaMcPHSkKHC7M3acCfxY9ucLvQ7x 1wbbW9dP8PvasJOafiBLGylcjV+I8uD800srE5uu6J+lsMBEi/4afapwLkzP7fLm/QMU2Kxv eW6mr28EpN0fT6qxUpauLo+/QiC4pLnhQ3o9XjYbfYsm3r8TTcTQWyZMZd/s6ESP6Ak7gGZv DmT5utyQMz89vaOILg28kvKekyhBa3xxZwuyOA2MaRIOqHWcZJCjXw8uPY0ZKBAYlJV+LsFz u1XIh3Nnyp9OktkzDmDXwUbrKbujjGGnhOvVL/tWxx1PMOsm2M9P4m+7R1qv8iESCxwymwPs 9jU9aVMt+z/xKHP/xIae2B1/0GMnJas7SOhrTv6jIRVzCO4Lc90pzDVFbCI0TP+hQlnIspTj WJFBUEjWjW6ByGsrklXFVUIDVvZg9CKKneA2giAAa1EDt+NYpiVL5/I8hCoXq3vAK0YVBxMW Y6F+zvSSnifyTnZ9NpzbqjiXijN9z95iJ2qNFjniUotVFotGqGjpelSCLChHamlL14buFOhC fg5lqXPhPr3vSTM43OU7jNhlWFyVLK3COoXGZt4sINqaDgFkgcrOXKSY+nJb1lZUn1i2oee/ z+EtIDN9ghDQdy2JVU/RhJfxO+28iCKxpwNU3LdE1kyW875dm/vSOyvnUBreXsJpgxhdHxZR WVauJBq/fPX56TMSG96B5ZW/wUvOy5D/qZWTmjN/thwACIYZSIWojKp82hbGJsOB5upaihJo mSjaMU4kjI+FqipyW2uEgZxu7n+5t254a/h01/fJx3z0BTbECFEdJjxg5/mUtAndG7cAzYQk o+LzpZv0UQexO0nF2dMifPvTyjiZAp4eoK0HyPCBfKKgPw7zsVfSl7I7nWnuc1qguq0v19UR 3xGlxQN9+NXwKX7YRRpTI5R8XRpWqV/wPyX63oG2zZAtBinacYfw4PpZ9YNZfYBN8N63dp8Z wuBWrmT7SwaD+rPOxvt6i6OjCUNYWDsoxvNvxZkWFRSOPUUR0ex7goUFc0FoiXzjKEXIRDK1 q9IpaZIycT9SIJwl8vwkw7WMdp0WDEbuOr2Lo5XJT1RZUc7gSd1Y/ifFE3eJCb2+HRHx32Ve ryMTTR7Nm6OfHmT9Vo0lgxgTokOmE0xM14caDFAOX6vwmP75epZZSyFKRyQyEW5gm/1mYuTH dD9ZxNwhweiy472qXwCAkZO7D28iGFireeWyzGdyqO5U5dm5HGy0rshdbYFY5S4eMHAzOVUd shYR0WPll1GglFUdOSYPJcWvlB/qfG+eYo0BUV53sAQFQAU7UYzlR8asf7BAfB9Q4i1WUZKU 5jmh2zJF7qbJVfh9KreZ66446UW+UzVQNzKDT11MafMsFj+F6YuebUKdB5RoxI+tuRxz1q51 8Xl7vyCpmtqWXU/KAfnkKlaDSlufAmOo+rwwIErVS17+4jnx4B+YGTW1Xo+Rm+gd+VYtrin8 MxzHLsiX6L3QXU+2808uIPGDKTOaAl0ujLnL+e81W+SQNPaGQ3TUidVG1DNNOxa2yJB7Zcb1 iTx0kCKmpFoRngxXq9sKg4rWHqlcGT38Ll62JJ7XqNHhurYsvPzfPVCf1divgL+LZWbbTymz MjF6a82hHKQ1uwokOmPu4JBrltgdL0W8oMaTBkLbZACuq0zdo1MkugTlAFz+7EebEqf+Jh0L 0Cb3ftoXvlUitjotM0rA6GCv8qk5zgsmZv7kzb+8NVVMvdN+DapfPkzHr8kYRKiDXJAiYzEN t2KmpWHTXIRoZPBFA/yrnomLHawIEKadxeG3ydNpV84GF07ZwOQu7h/nOpgLH8nxL7Fxmyv9 x1N6eCd0cPEDKnqiat+xNvW5jKcA+gQm2jPd7xqeDhCT5eXcvbMEt7yniOE1SqQj0T7F3X+J zNoajihFrhOQXxHCNFRCRGNmluY+WX47SljfNVk+Ru2AMmYYkUnN4dvSxJTZiQA/MuyFvCgd 8o+6OOucj/zKd4zjb1Yxiu32N9WJK56j/svQmmZVWiPw4e9S8BV4QiwsqvcisA5x1eAAWFjd dCLXCMhHpPR3vdIrU9aMNPQMY8zL6RIAYeMonKsWx8YKXWu2x+Hno2JPKqstzfRXpDJNg7lp PFJpPZnPJ8ItPYi+bq6MctW7x32Diic+6YJ99CD63U8dg4sBDcOgIX5tX/Ink4aPyujgISDZ vR0tW+DSGMenp6tqlvHm2hrPCQ1hNzCcwXSiPYYpDfHDHAVF0Mw1MrYaFhK+w8Tt6PLovJ6f MKUtnb+8TlSqDKOVI9udNKreCnt8myvS52NTdFBPDMEqPw1CtG+hIcwPCY1sjjmeHpKLwHKi yTUaTA6BjpDDzaVkT2r++FRzttNy067HF6PNXEM8Q+1STw3C9i/7NDAsFSnwYa90GTBPbUPE goHaPRJvLB6Lpvcool6LAwwhMKmFX1rClVf1q5GhZSFkGZdWSlkna8k4BPlj29i4c7HO6xOQ dvIbkQp6lo19IgKOHGI1jVPtqyhx/sMX66GT5eDNfR8MstwzZn+7zte4z0R8FuMvknEJX8XL UYiBXHU0FBov7d1PQOUBwMwFsM2wHnu3bA+KLHYSK9oM6R6iW9Jg8uV0bo9f0dwa/sySufKp OAbaOJT8m0sZ9HoAHLVYIVt422GgFN7qJ1N9T1MnMGd0h2McdHTedJ9X0s04IZBEfsr13dsL rm2rz6w0lm0sJZHrzgi6ahVd/Hzq6x4nfwPWIr5M+26ghjjj9hocDqgsc4KPS2sB/Y62unQ6 HQqjZNkXAHyIKPKwRMeRm9D8yqphl1jqtJfKFQTpsHugx4KjkJurg3QqeKZFIMTBxdlh5uHh LUQJmHIP1vqF0R4g+DKZQe6ry0KN7C6j5WfhD7ymWAHiabZyastTV7M4d67y7twjMfEfpbzn vfn22F2kmoRrsYV9r/EROw4YNd8sYC6n+JCy5zecMSZNL/uvtBhExs0lFXDhFMUxLo/VEWN9 Mx7gxSbrVBU5qc/sjqgw2RwQfuk+DtKdowuenDoh7gwWuK5VZfyp9eXqqJy34iyex7CexsgB s/bpYioLj+lpgbeKvxwC92invBWDKgpukcKjv/ClIDdOVuwtKt+BsgBryLh6Yxajy3ePOsEB iCA4MdBRqa0005U+lxvhKnQ+R3BWZxDQQEdLEJHCxBzpks9VJWhPYzpgiOx+yVBBCFe/O7x6 zkwmKw7fF1HQYloxfr1dHTZeXp3YmLn9NfBqzmOlvAmXw80VbdmTEKDDnMR2sdQZi4snV9oW grMNYXITLpVb/wwL5kR2gWmbTHmrwXow7UO2J/qEMlqZxLB9DO/qJ98so2EHWOUl+zNVXmNE p7nYi2aW+Sl2ehKcJBt098hRYLKr2zi2kGA27sols3eyaVq+i83NX35bQmXbD6PxpFvxM63+ AFwM4kOWEXuQD96mq3shsKGHu23ULfaL44CMkS8QsY2z6088biKO3EnTXx2umNZ5mzM+TfJF AKzhQDvCiaFcYzKx722cu5Gy+Fjs5MyZfBQHdZ0EGhyuKfzfTssZrs/gBu0YBfFD5vSM10Ih dnc0QIahMONa4puX4HkBQ3mRKMS5q4iEGIj7y6wL7owBzqFkyv9J8yrKA5wYyyfMdNNg5dAP Pbnf2V6V2Jh0LJAnOQ1BLUxf6ekMqnE2hKD8lqHcBzm0LoSpiWfkne94nJe47WjlqbSnryJd v2B9khhHsDIdqneE1tBAvn3RqqSN9JRRwd546tM7kBhuh1wkuyErOSfwWkX4ajc9l2fB/woN k1RSyBCfZJ5zfJj34Qw1A53+Rfx/lwRimPvCk9o91xN3EWJquZy5MqrjZE/U7Aw4xbBrZIcb okw/rJFghtW5v6hVlPqanyyvCMoR/tWPhIcaYto2p0RLrw93kZyd7h2w9u83T6X3WD+0MQ4o iMpJ59uF8lMtGj7lQ7hN3ZtrSt03EuDGB8okBGiLRtH9XO2wnETDUQIEdMCQQhdGTiRjdQhL 746sukuXRCnuABm56g3UEwa0/4qPospzKwaQjJoYi7mRIYV2lAyZuIzFlrE3ZzihkYOfW+NE coZ8ArGDseuy1/sEWdkX5g9/9I54alHA94Hj0noiPCPQSdvmOXKX4t632rrg06v6qp2FLYM3 O6twiJtkZW88Uhkre93sODyS2OaIMxxNG6uBCQ1N6bpDngd2Obi+K3zcOsHg/0jMQUNZDQH0 jGQ+h11DSxrSJ+R+P14uxRdhCPDFO1u/bt3G7Le+Sn3ElgHw4ltcRaimXSYjtfyOFnIvXjqz beOgzvjXa6qqxldlELxOWGEFhEae0Z8N8n9/n2QDuhuuwwsnFOdI7+hDflShO6Sv4tfztsvi mI5HC/W4Y+m108pjY/z1BkKohAAzufjDEduw5MbxHsi8hKkxQOJ/To+f57L5jzABIPF624Zo jQ2N+OmiTSNEl4VZCuZPPr2tG+9Y8Hg13rs9R92Dp5YggJrCly2X2MqJjwnBvoqVVjXgU1mm V7CtACt9428OqrY6jk9/TY+3vs9rsw6+Dl1zGjFqDQ+WIuh/IpsBGRNIxVYdf1jcXejo+0Mt qGJu5WHKO2qm0MfaGyTaCMPxOZMtdiw83yAClTKgxYejjK6SodOuEgxI0xNtdrvgFyr66iMM b+hfT8U8O4frvQdbM5JF8iDZvE6retFI5sCJqs8evwhTGWrnFjqnRcLvpSBzYRm88XyHg3Gd IJgUW4Ls2DGe+VULHJDlw+E1Q27VyaHnZu42cGMMnTTyeMmDriFZfkp4/5yADA3ASTJtVOte j34s+J6ThlfuY1xHhpruNHs3L8qqfthF9Nz83Fi1C1TvL7r/LD+1PcI5y+80xROjQ9ugEvF1 0FH0r5/U/w2YtuGp6kae0JaVsmO5SkXrw3QCiRQtnvNZBPAFMg3uUIjseN8ObxlFmMcf6tdy wdVm3KVoDrOIcezNu4F0Kb/ow91iTQC3OmeCZLT8+5dLuWQpfsZzpfmP+SjP2Nz3EhK0FTFh OZr3VfHcImagwEPPTSAwI5EwkkfkA+LSQJwlP0ElQXjSjqwRlJtG16J0byS6fGA5KnXWHU9a rpVY2akm5tL+QzVywomHOGwU7i5lUGR4DLcj3ounn+PSDarRyqNZW1IDhM0Nki/zSiYZgLf1 98mRlRDa5PfZmRbQb8P0UjU2dzQNHxiQAKAt/OSRyZ8rZsB8hFRTqmit/oC/eCQuVD5c2G5q Ph5pkOzVUuS+CNoQ2mgUv5u8daBGBnYzjKEMyrmYcptBi980Gf45PYRCt+39fIo393ZFaXY1 jq5PKAs0CHgMkEXmYyIv//VIAEID2FvrTFTtAWNa4j6zH8U87QySQ1V95o9A6hd0/BX/aND8 rfQwwE+JzCT5XxQi3sA+6oNIqwFs20CRYqA0m0xiQy/qy9l34CdXRYabPV2zbTAca8WvRUKW cQ1mivVEDyTEtdh2wiDESBfhEycJ4GaTAQaVQuFKI+WM3HS1QyD5rrOQWt06xm/fXkR0zQSi muCyT3alw1WqDATEf5EspvvO5MqZQhrmjs12VLvkxuFUIq7wCvv99Lfd8YoVxAaHUJToxBLZ G+eHvsjg7mFzKEn1UGHT5/7JMiYEzW6P7dBis0VSGbdzSDRu8C9XmWDh6VhlfiQSMyuFPjev Rq6HhbamTeBbBNI5iw4PXN0ktjsIbQ1B+eh5lFvWDMocu/XWVgZd41VeSXSsvexeF1dfbF9q /7sgxn82HnS71SbhBUuD0GuM5GjcYsy+f+uvggud4dkRmVFTdt7m5UjeggsmPQDkgIcAiAEz Mzq1HJw80P0FgaFgfwfMV/ZE+XJYAWZD6M3wG12UnhGcVxLXvXrROB+xnFh098TfwWjzmisv QDZIj9kgIkNUA6EZ+lsr0AwWz+OfevkXek75/ETLICHlR36h9E6GdEANx1iQjbLaBehYAnkv E9t6Uuy+MrfaGJUxuHO3hasnp6NKytEn9kBm3KNPiWHwpVo74KX2mEPVte7o/9tIgcdnf94C 0Ch/Eb87ZiOyXby6NfsfkGKnr174blM8//Ox0DS7ogr1WHHjMpyVKqxc9cW0kzs3s2zvwNII toNB4ildQNeJYBVvMLlEvxmZ0LRyHFixr9dgg0VaixHI/asaW1/u2KAaqBCBppYzcnS4DYEm YNWNssgwzwCoiPQVXklr0rLfrlgxP2pPAcn1dcbKesuZp4t2cqH0hj8E1rsLh+craHFCucmn xYWXYhTPxYz8f7ESEa8/05Y6O+oEv2skyKGziXQ2HsCWiShk2Cc5pDT3Pei5zR4VVtLfaDYD ckYKmriwsvpEhclqwK6HT0o5LqP1NsZfe9ejAS8oH7xByqnlR0XToqMhjNqDopKKUkLnEjX9 ie4YlBfD72QPKi3wCB2WH7HZUvNidVHn8194vtPKWy5e4Q9wJKsRs1boak9E2/0AW5RETuVY mU8KobomABne2Y5O42naOOzpe0bXbHmyERs/fL66n7SgA9Q093LER/PFaEodBE9FseGQ452A XYHNKlF1N+OexetAgUhw6wZO8mVuQtDFFiGHZBJTIf9rVERkaSFzfsTNOknLWcSzE32q+tr4 pJnh7iEEZe6Wk1CwC3z1Z87UGIieZrV7cdEXx8YYx1pIijMPRcIFKUoW8namJBvslZYbbylS fRgtXGfoAlEj4lEVFqOv9G5P9MKVKy/9DLXe9ufVSRcsUFRBMBUE+OxGlKT9If41CdOXptC6 O1owjFrgouPZrsFai/1hbdFUFqA+1KzjgDMRnW1njuSdWwEIRm+V3KBEDqxKLDJF6FTvbXbi kB+Ct65tTSc7wZAJA0vaY8yLE5nEPLAZcISGj2gV1KRtmShOjoXnPFFMiNSdCHLLUFqYe0V3 KHia0hfKfhTqfcgJHY9GRMSTajXzbKFm20R8tQ38iZtkWj5mlga5//yUO1u2zX9v2LnFMsNZ eyi2T39yorvszNqzWoMxanbBMed5MI6OJ9OhFnkWSfnWZ83VSFb4W/78u8yUTdRB0sGCenB3 mSLFPkPewilimPOGzUqpsQc4WdOmKMLmn/cjUWtljxRSU+PrazSM3CgvUWF1F0MCARwhQX1v N3JV5utSSj+jS2yuIBz0mrK1334cwH303GffSE23o7+akkVbdFpoypm4R8U5ynExdF/6UqPC fH6Bj0CC2NgT1r7A2MSTdZ2xvgcCC6brBbHaTduuN4VVraMKmfQRz4f3FYy4Cq758u/LOUsI sCD62q5PKIR7xFmTFGGE8M9RU9sXLFZP4IZQBpJcWdLnRdyFUMNdOdu9gjdnwpTojCyoDLkM 9wbEaB2u97kbUuthpJQ1yZOUjDb4kM7IhMjIWWg34SzMTe5a1p5GNEZK4tHKywHpisI8OfQy r453C/ugx8VA0VJs8LNf+Bx4UF/uzNSceUcgVV/cVGTeuM8Eo7Pq1dwD6urGq/LpST5U5bS1 eYRbzEtDfb6KKDvafuHGjZtimGAnlolfentcyq07ktxNv3qsWn3PYSucE1PWeoxhWqSrmOmO 3Ggrx/qQ33HXuOlQowTPjBZFxp2C4RHouLI+FG7laKIMI+80gbWmYbpMzjT/7rwTSOYpVCcX yh2qRi5r3/+MudDBoaTnyfjHy6nsOQoGTLECdGW9jTxhB0I5YjjbxHbAObxJiJemLa+B3oB3 UWNZpZsy20YrhzPbnFbDOQstnAUdSp8YReizMMKf5w2Qy6It3LPZmWVPEt1PedojX7hrGuR0 7HH59qusLEhcf/hr+FYOtQoq2pJay+w0HWyZI46lB3cdXNJHQSn1em0t9VToUfA6FD5sWmuF zHwig/+e9wBOq0uNy9PF/k0605AFORk0Qe752cLP87i1qVLonmgDGF49v1T5ei+lGIG9fkF6 B8Jb5h5x7VBPWoGVm9IV+iS/Bf3+zhTTr8l0H+UuOQp3OG6f2fN/LmP0IFzqep/VvL9De/ee 9WDnMZfWl1jhbCOuPE7QRK9DOiw+UjgyvFbtiDOOw1/xI/I+tkm4vnQPmrp2SurGqEAQElpv nrdPWwqUJubAjdW5ZsTezFRDW9CTQ2KViG7rFKPxSc/5+dgu22gT1LW72DEgwcHTczkHKPlv Lu+QWkKvtlRWYMmIaqD6FUpuJLbN3l9rbqcSmGLtHQS0DUWvz7t0bZZs7x33KxNfFRgo4sCe d3ws3i3lVQig510QL9T7R+2GvoaFb9wFK2lDgVcuk6Z2PGOFjoGBAMbfwvATPgDVFZWPETUF s6kM/8WUiJumAU+J/eINpstLLvZ+L9XMPKYxQJFPa3ExeJlj8Ti0Ew6Q2W+VjTG2Y4323Fr4 FamWSZ10jVXcGhGzLOifhWvmfaONTgksOMsYuhuAxA+OYOTu81Q1BOAi4dOIhQ6HUfjtzhCN GBPw8tYKDrkTJda+2njwerDdvWGFHGcjJEZyjUN7SBR/4TTK6KdiygT86bnrjwwXd/DId+wk aoq7JPdw53OYfudg+86kmT+2PItkbo+OQ3xh4HMt+ytnH0PYuwk5JjAYkdhXSWM+pB1xhouJ 1dG/4YtP/IxKs6UOUXfFMxfFTn1/Ie61qQtwhFSUTxvC6ieimrDsllWfaxRP3zPeIy9+NRLS 0hh2LY/zD4JQDzFcn1SrCIe+E70Kv+/e/TmbH5mJ9SfTI1OTJP6+eQooj0bN48p78rdJ2duT FwcpvSsNqwJuWRJVDuuArpC/opMpY3zuTHRpGGjOTkMaIDN5rcn+Ng2kxeYOo+VrRggorFQR ALp0164wh+cF2SIsz63/4FoMT9LWrq2Dh65DRJNFwYUb3/ZOKv0un8Op4ZnBkK3AbKTjo+ux 3wHqfz90hpI2z10sjTeWTeqsuMKceVJOl4oUT04eI4jX13VVDD/9oxIB4itd6WBW735vKDTy je/1BR6yW61MKDUzRsdnQtrIzMKS1x8EXfYlIcj+EEoA3dcOigLAN2a4FORJR03X9q1gnEUL MkZnWMbkokgwZ1lyTVnoLaALUAfdkehMQWwwnu2HuQJe2dM0/MKp2yV7YwMuVCXiBrOX0705 a/tNRPWNjQBk1vTUldpMe6arrJkOOiTPbak3LzbcCyjvzidsemDHPmg8k1hhORvN84VLkIlu l+GFm1y72mraZoLdu35ovwqhYGjWO3Djs6KmnN7i/PaygXny5l0BvBKSKE/g7FRgKzrRdVRF X+fZvXavOT4oFy8oFtR3V4rg2JBCrvAboAMRk0IS/BE2ukKmpeLOac8Ps2zU48lAYV5xB/af 53VaWaSTn5d0+KG4Tp3xkWezziuvpntjr2zh8T6UJAFWSzKhktePx6t99DurrKAx1/jNPLXH klXZp4zEi9A77+rR8HOoVuhMXkWJjPPfW9sUN0ujo9cywnwrM0LzwQ8b7h5j4W/2/VSOgHHw 2oipkiyRgF9VD0BxhGeRsGnhtisQYJto2taYx2QFeQFf5ARFof7qdYaBICtlr143tzsuSsuw 4Hxld+ffisaOmxetAW4uR0UmhAio2Yrb9vEZ39/bRkpHwJS2oFtWMUvHWHzYZTdjAlwvtS2x 3cxBORL9d5L2klJzK/z98Ml6UaOnp2hxmr51xo2u/Ix6ywAsGcGZmylD309K8zWz5HWNjaQn yx+gYv2xQ474ZfNLEvcNcOiFH3ZWTuQ8C2OfRn5kLQ90ZO/1aWkepNu3VCPNXet49U/B9w3G fjthD5UQFWmLCKlc2U8Af6GGi909GO1IxEU7JodK4trSJNmNX67olFl/jXSWuCb+wox/IPxb kRfsGXLadKcSFZBrLsPqo3v8So9PqbtcnWYqBbFUY0xyJliv0/n1H08b0M8it7Zzr1eCvukp ld4/kTDAQb10Vh09yuuo2lxMKHdb2pIW8F1yhN4qk5wPUO/6vSzr5WAp4zJRnUwNzXnPesyf LOmxVV+7EdnUwS1xL00EaLCIrTF/9SSyUJUeEPEerNJe6TaAKwCnrgdKjiejVQpUtw2B80zL jjc9atRVGLK/cCWKFtm/0OZ1UZJSs/MdZLTbvG46m/fLazN6bJNmeb3BuvSVNkF7dVFEC+XU NgElg9IgTbklg7d5stqJsXCRqmiNvotwWEIFIxeBNx9ZoSMSdoATa62vn35Enzl/IpRm9KXY 1xGjOcTdeLknQhOkSA8ZudEUPZeOPqs3UVxfLAp4H6/JOSuio2GKLq3ghjfv1omSLx2Hqil5 J4yZ/xSMqYbQx2ZTNBYkZhXWPpk/maZBRFLDMhugtZKrJq2thCXBc6l3VAci2u1RWmYbGu46 iHnAv0P08nEQQfJzHK/z/wUtYIMLHjcQwQx3Wfpvy/5rVsoNUfXZ+26UVCU7gt4z/1Yd4pfI 9r6Dw6rIES/vEyc++XAfxA8Ob2BiWu6aIg160PmwmyVNxaH8YpGt7SFIc8nplDAehHEVULFa abBHCp1C15kyDL6OmWXr1pQGdIvZFQdCZeu0L/87x0rCL/AJSoBcu1lHnoEHe510VehRqVV7 n84ggmHhWxmw7zhVR9hZ37CWEfxJwb6mXJWfJ4J/hoSnjEDt4JIjb98rNcEoKsLtXxT3SRhq FyiJVQtdguoZrCTr3GKicFbYqwB/+1YM72V3LWBH15JWtAAo1C1nA0KYk1U7YP0sMUNMmSsv UP+HmYgIL5uM70PGBSBUvHoMcBkfX/M+BHM5egHBmX7ofETS0bpMSaEgSo4rqEtPr+2Ar/3D 5ecJNN9J8k3f5BRvV7EfNcqfEdDREIQah7OLGwUcuyV6AlbGFGLm/4nadysS/XmvRD9xVapr UvvFx/GM9H9K2IEFIlKDqdxu3iEweQ/vsh9JDx5xRmpvlwWIjXWIoxotB/gyuIVV5iYhojze 9giXAtvUFSjsBusemnWHZl/hmhWaIT1BFCxmLlIB5+Kb6twSpRyONVEZ5Q2vhnYm42EzybSq wVYIcqa6IJVHJgAtaguTI/z9xMf3WFgItnHYtR0vIquiC88J4429lFG+uM0psfUBbedhgsKx BBTnnhMyLLrkkWMJu0GbFy01VyPH+k0rG19FOykCg4cQF5UHGqVmqSyni9hyN/TdwDfEpRRQ m3Fz4vMVWzDV+Kr/BcAo/f4ynr/6smFxSNSmzyf1AYhzZcrk+ze0+Zc6zIxq5eB1d4p4270Q vO5xrVEtRaR7yfN62lsSWO/gt+I4muchs5p5P8EL5rnoBtKJlU+sZCh7rss5cZGgtytiugpq hSYDGFr3bWBZegtjqu2MYN73xosWTseuYUbkzEqIBTFBLFUbT3uJ5hFGMxnA0oa3IuxHF/52 s3URw2qLREtVla5WTY2CpdHo8okEHNwwCBo9z86femhVew836r0fhnSgmxyqaP7NYKvwks84 mxesEKAjx8U3hQbTrK1r2zYMa0Cb8L8BfKC1yhBN23NiXnIzkpCvYZE8tZrT8Z/rQdizbpn1 3D12Z4LUeTvfTJO2PV+9V7x0EocvOCUMhkJSd4RjKlyCE166LWBUHfV35cFUTNgpWMYi1iOu xHDVGXz3J9sFD12nOKjBa1U8N7PX6UXMVil09vzJkVm00je5Vys0amo56s+GD3OkiWY/lsvh I95oD3ErYEA0xNqej/YMy1XwCD3Nj1k68bBRPa/Bi5F/ia6rmvipLV9CnJ1icIw3QwD3h+ko CoiPJEAbE9jOzA2GEX0cMvl/hxzXvCrrsQhCE/6Ni7GUEVO4+eigTNN9tu8mW2qsArKIiPGy vV2VITsR3rWs8mmHK0B6s8wGeiUT0CU8eFwmNIW9J8cdxorwNSqqkzGeT9jWKI18PskaAM6d 7PNbvFYqiFSHZbywq7IROIE7xpFatnoVfkHZcKfYew709pSDIvlBSy1w0dTNfZyzmSwplpEa 6cTDhdi2TI2BHP3d637YM3yX3uTujc52Vmthhp/f3TmZhMvoxUXMl4Bv+haNcRQHQC1tXtOB vJsSX8BLsuMd790EsPPe/JbcFxlmzXKnEsD7rqyPgJjym6aPkT/VYb8QNYhLw2dv/CP+9Kit +40a87jy7yRKSumH0/i+IVjh1hnOIOIq9Db330jG7E4CLoZ2ZV0gmnpIT9LuSj3inTeMrTwn VYl2PuUZQax0j2I4qK1AJj9YMAxRrYg6fkLTj7RhFBP8ObmPfOGmxIWlS1DydFJzU+JASRRi 7rNNdqKEeZ/uqD9wK4me+DxQco4rUyNk0Q09wDSv/30Lho6Vm9mcrstzCmW1T0Hpf5NTISsi t4lU3A8AbTbaWYwBPa405H++nxIy6EjfDobDMV/5PRiYaEIosVeFg4boT2GqJ/apUNOMwmid 6YIvNUOLqhk367xYmzadbI5OF6Rsnqaaib4cYC5He5lWnvOeszxCiwwkGHOgjsb39Tm+jhG9 6IZnjeEFheT0EEL7zAOxcGeSebxEvmI2hGP5dDBoBYcII+LYlQniIj+t6cfau+E9QzNQm1s7 u138EdXD9YWlgmSLggYEkT9eOXqEraGLVN+3Oo5RQm/d94ovNGluU6UgKrz1mdAwxkVOARLG 4DL6ggSuUf2iutWPIfE2ptkeeQSyoIP67jFAa5yPmngJi8+pgh068GFNzHKEmNqAY62byzW/ yudsAPe830BTIkrjj9sKoWAVCQkwv/90UKF4CbX8CAZizyK9lgBGvPvBnpzcT7ZRxk2E51av CwQCOSfXVfpXiJ+7cRajGbkViE9iAYQ1J9mPIEeQWqCfFI9TV+RuiNSAZx1GeS3ANyG21AX+ TnJ8F8iwoggXMHQo7fr/QTlfiXNfVU3v/DpAzgN5CXZQqOzApnCeN/fMz1wusGchyT+SrPNx TfSjsud4Pk+uVR8HWUDaqYg9BZc3pQktYeYS5OvYb88+zjRXtVRPmpCwSeDWjAEuqKBybCHy vo2M0Qz80jCdnt1OTGpfGyYpVfi0aghTm9MwuUEUL6V5NERw1NaLhoF9nvVAVzusLrdP/I7S v9xBN6/SKXUcxLLszFi3E84oxWTFO/smvQ777H5DY/f9JClequT6fCmxEPtxzsqX1HeFIthJ RU/5emzSSFr1cKIlj4rDG/RAI4iR5Y8RZu8g/0NBMnpdxLqq6dkKhXSuVjV9p+s2SqW8fwA6 5+8EJAzCLVFXv8C3aL+RQPhA+vLvSlWCu5C7EflWDpOo2bIhIJ+VTlxj4lSv57og/5O+yTNM RUfyyreqFgKNyChiis2Ft7xAZBHn2FPw2uQbLTgMaSAnM9iBS7MvOqV1V53WW5Im+aIWMqve E5UVx1QhrfvK1wddeav1c5TZPIvM8DQyYyvc0AXHaeHHNS6mkikTSHF4cF8ui01kwpUTN6kq +My9nTqv89ffQwwb9KJcqh9kNk2YIjWYvS1ZumbKtSUuuQ6lf61AD0+6z74AE2NM4wsxIv4/ fexrdqj323tLwnrQzaFL2OxrSRDYXFdt1bilIYzCMj8U2QFhKWx6StnkiHUsrkOWpl2SRnnF PynM1glVZP8AWXlZhxYx2aeORN4aCZMnBvmIQevquQJxRgpC4OXroBfmalKs54SFSIIdRkzt dQU+CNEr9qlAo9Glo8sb5HWjWkLs0skObFOYJ1HIyo6nlTzRS1woSia+cwTgJcxh6Ipr9bHX s7BkuR7lZ97vZpB80xUs4PS6rKZmqWGLMMeyA+p8s30sBM4NeM9GNvJxxUcuetFDp575em4W WciDNlgSoUL0AzKExmRd4V4VtkIwLQHo+uruWI4qE67qtfGscwyUDU2E0pZDt0bTCLqph1o6 UCQrmnyYQusWAkcqH8+gjy8On8hsfFcIypjLOLnsbtzn7913GUOR4QyTSmIcyJcQ8O1vw86E zNlt7l0aAKTwLHrXKZ1d2JhNgvvywJiKkzQg6ecFh4G2Ha89yqShhGkkCRdoORBBV2dP6e4h o+aCv0HRfZTyTKaTsHA3dMDUVoCFxBlzEby9JcnmAFhfzrztlLlj5X30bJVFX1JjAGansuOB WZ5yuFuU+dSptpdtQLsrtX8xZpEl4VONUMFjWIKShNiMURHCT8eH/g7eJsxDAdliXC2ybaSa 5Jy0Rz+Wq0W3vf7z2N5J2MBS8CAC1TVeoJAOwGGYb941YzjMkuYiHU0t7+7LrRFkw8OxakvM ERuWqML+hvXrqKGdp+INy+5K3GbwBrkQI0ZTZlxQ5zz12TzXDa+G5QDFMtdIOTSlcc/Rud+z 2TPs1b4cYAi7fAv2MQn4qdBtBB1pVBnlFJOT4oOUngzjH/SosahnOiZ9OKBrL5sXmSaK0UMF aA+1iZYYqnyJ6YL4CyKdwzIlvI4kyPrBBVGw+rYCCcLjzGuqu6hkMZl7StAkJA/REJXL9B+K 2DI3puCNIVpeKN1dsCxtFi4BKmjWnc9p6RJsDVquiGErKay3XnIrcAgWRc549WsZvNAfyJNF Q4j4iis3KDGgJslFmLgVt7UNO1MbrLdmcRCsqBUcvN99cLIxi+IUXxvrczk7PQhqAx4nhRys FEPwuGu7x9equ3TVMSTvZikPYKw9Itex76X+7FEYzkxL0kDotzWmsmpDQxRQaT6/Ufkmto4+ Ql1MNk1Sfy+IyBhzqyjHU17qwN3c4INf3ddvHR9jztej6YZiUw3SL1CPB2P5GaT1LwiTrJYz AF/fV6tQWihqM2BMgD6HXQpdW75gUO+K6D441uw+szYn5KoflnOjw862Iou3aSHFLljS3ZPy I15Odao/XPPGm7XygieptPxqKqx+el1/vMuteyHUDsLFbVbBrlNVhqMiZM+YacVbVIaAL5YS L1T7rjrwhEDD4e0FOfLWs6cUWwKGGX7BINatrptrNEJGv9Tyc7PplJAHMwyqDA2TgB48BI2F AnAw6KmyVu5UT/KFIxQEPsLtT0tN25PmEsCrEHnIh4qtn1QSLhoFXA3xz0A16rtDuUDKfC+5 oFNfLhnJxu22zimVNnI8RxyqLxthXYW8Kg2pU8v0puok7EVUJzszIC/Gul84xg2hcVZ9pYW8 2SX1wxMivrkjc88QLF026eKMwwGAvhp2Nen/kOTGiXnMhJtOLWa1I81sRHWzQ8wBm0B68jMt gzCFxsPgC9RjzIXh7GFziYXCI7nxRj92U12t7YknCN64t6KJ8EjeicuoJ/YVc6VErqYyMfaq 3nF4RoN3YF+Ynf3WdVNoTHrZpxNxQLcJpigrTTni3BPBMIJZL3Gu6CVKQSC3PedxiGJdw0uk 1t2QPEbv9P9v/GsxAI0GmtMFR3jBanGo3ioidFsnUfccivtIkzCVesv0WMSiOJGK5MZCaORu OyuenvtNOnvbzwQErMvSuDqYzBG2t5olfxy96JfNrkhBvUuIjoHicW98IMgbrF1/XHOJlJdR 6vb/isdjtFVyTerc4vy6SxlDCIou7pCEpiciOwe+adOL/S7l0uoEf44CAGPL3utwyyTVqryM tqrj7rwJvvO4/8rwGF+pBIjCWB8eeezb9T95yyMJORJVGR2tWTCLILb9emTLqdcYEb1mN6kL 6u+DZKWVKAccQu/JvD3G1cYCHviRIPqUKHq2Tzpvu+aD71LbcgrzmFEGtHcfJOFsIYotu1xB UczGd3X0gJcvxyvb7wPaJQuGhsDhKFlyVdkzRs1QKWn9YeN2z9tYfD+yCgEeylChdgfP5BHv 9V6fbCeUWirn6caw31NcSpF2BXEYp7mCvO22IUACU1USsKGxN4iTQk96/SIZ33YBcB+0kpjL QvPCioNVXmqddjaX+9L1zXvR07qNpQ7cvNqnpc48XOM3/f2/35BDmD6xEpAfXdC4qjPXP2dg Oz4jaaNZkSF9U1RYJ1ibGEAIGYFIWw174LjMb7+AA8Vd/IrQ/kaITc7dvFI5rhWYzBj7kMTo Wd2VPrZARCIw1827bykDYgzjBtEhYJta7B7D0qr/LjmvRpxvBGZyM9gQKhSfzdK64TcpioSc 0So5rJ7wX5gNlNwWE1m8AYz1LNN51n3Noq6KKnrHCOg59WxsOXNrN4uC7s1++GQUJzl+VDWB +3TcF3gdKNiErNNfNGKCJZdlD4+eEi1wmqx2ZUNhzENdjC3LFiEr1Jt/P8CuOtvdYV2LZvz5 /hTDG1IfsdnYZ97hkJq8v2ffWS9KRAwp6WeHYNHRmVwn1lNjEQ9WAKPJh6PPj7dAp9qE0qbX 0P9tkJon21vmQk5l4ACsXrk5mdmN/5LTevWC6gt9zaSvPL+fKgPzorqILdho8VvTiuq+GjS5 uNRjRHPReLE8rxQ/F1FuobcvLJ+m5y0nL+ja2wkUqfl8LySDHrsM+pYhWCe6ocDf+4mzQ6h3 yELiBpJnxUxqS7HLWNhClhBxspUKsM9MnUvadLXJURhtakhmYhgdr8YwMN1D+tyY23LwGBFC BXSUxfzJnlPzNf3AR6LzjZutMuVTsydJrmDhj9HrQCruSXJKxlukx/rE1YLfVcxurpHFcZMn HduMKtfeNx/qzYFeiqjc9IkfU9mX7gCDbgiNMmXvxaefpG0yT9GMHqnMza8g+9MU4Qd2mc9x 772WEiPj9wBbWBOj/olDjADNzqh8F82vfn3emU3lCgWbN+jWK1iUGxOqU/If5BS4SskkjDDd OAKHERuodRsvf1eQnDeYMwGNJ1JoMDMcMJGA1taBQkiKk5eC1ajGj4S7gjuY/0vdW0rGmWcg 6lnSDEWJsgrJM3pZSt74X+kINXQKnskmAh7OHphHypSrxaYztIPLKk7xf9/jnAllFh0s8Fao 6+YIHxpb+Q6vvMFNQr9A3OcrGjhVvg/YDOxDyVrA8TOXlt1c2O3aQEZJiEqaASByyLg8SJDT PO7WxsxeqLy6xX8F/gKagPvn8AwtHstNZl8zrbjzP8ZZWQ21dKD2WQrRm9rvCMfqOMAO1JP8 gZb/07w2ySTQ94NZp4oiVUrfrfB2x+MqnN9xE5s/G70I2Baz6LU10wSZ+Xe81Rd6WJpANDdC XvslOWQkPcVijmGWDvn+uwmSwQIP3vSpZOUxulT/Q1qhGqP4incZCiA9i90+saDdGBs0Ny3Y Uluescos96ovK2BytkKgl6COqwgs69bdInZuA7dM9UYcdcha9sP6gVbKlxi6HTor8TPlf9ub 0V+MsNLCNkkisnPkY1Yc7TQzIteMKxSTaIcERuncvTNWLrOe7SoZLHVpZmoeVW2H0ZPA+tze 9fQI6r9QQSRy3Lx4TXXJ4s23TveIGj7ssSICPIRgffwvdsUFT+8N4g+uvBrwY9XOmhBbyajq d18sIGRpLemSxn/I9+AUV4bEv7OaPvfJJn6vchnaRfergKFR0KOMZk4AdyT4ChmgHQ4gBUaQ KOyf8bpMYK81H5G9zTIRANbaBF+4X8tvBOdxV6+VOFIcv30k0JRTFMPKuF7gt8/zdC0j0txP Q/F8qm/lWnFddpAjoqgxFF6dpbE55GOGbGwk2TAjZ0CGuXN5ZVwhaAIlwV8GW1o7Hon9XWap zogWrftFAGDMr+6NaE1m8I8CwKJKUw80w9Uy7167Dkc2IN6xt9GZE2oArHN4FeNsDHrux/uz z8JDTqfY/qR5LebUD3vmuHuwAGDxVkzIKdNHYZbTKX2uEeX7LZLnivnQRvyJMBEfHrz3CY88 h/OJHgAr6n2PPRJDEmURqow4hxNlnoNefWIq8+aCo1gTIpoh6cefVDXeRU8csu4F9VpVDQ5m r44pj67a/8f6jTffw3Gp75JF/CUJYjvBPu+YRl3DHBtePdy1VAA3yrXoILZoCqmm0D8LwDeb z4/bFEeGE6oUPKxCHt9cFevLocB4M8Qop2yiNo2IcIgYTdPb8SHBMpYgJ5yYOIYaEC9RN2Iy 6RfavwfKEFP96DqnEW2Hg9NHHWxXBFF2HXGljr7/z68cp9icZ+cVpw4A3enhPNuJKOfcQ+z7 5Fg/c7L4wixxzsNznnHoNUONollVSTv8e1CCUIvWgBLuZFmMiup77AE5t6+UCK335NKkRAVd 7tQJZXBlJYG7i4dOPVPLC9PhhxuU/4C4eg6vW3WykC5cfXf2Z/UrGr+FKkpH8aYvJ1uFwfOq hzF09DdeBz//1yurxFro8N25Q7z8GpH3apAoOsVUf4NyUyytIJmhYIjO2eTqVsT6HYj4WTPC fWbj60I7xqlfLm6EtAhtCfPiG4GW9pIMA/GZMANo7zIGydfTq0eDErGQ39y8FbNhvQDPeTH9 Z5+OEq7+vALGrdDPci9kXHaqOgPXttPgPWhDND2x7+OMTWWGaBnJTX34129z1D5UioZ0Em4d gKd7R7T8iz5gfQhzM3mAuKnVnUi1RbFrYuMBDnzA/Bd5dS3DVOkI1LfJBGDT7Y5hsRAjIQrd i23cFzR+jUsIRgfYOfT7SkR/wghDcxaIvwW++nd7rwfI1LFV1YgxxcQGxEMaR9MnkQdVreNf EqzCTFVisiR41S2dF1zrjfMcBVr664fZ3tdrDZqDxNl123Xi+matoUdU56gMyhsvqdmRiXAw iOR0S0doY215lrLKvRE0IuebU0pR/jw4aAOVY2HMGEl7w/xp0nXojf8lhomYQwsgVkmPeaxj IWVLms7hOW+zHpURCxkQ+LYBrcWHZM94fXW3+NNH1E+pCEE8rZUVtpDnsRdlvKucVWbFzDCz TLE/hWs/+MN6k8M+tFVcG1qoQhhpLLys8rrFGcHT1JWpHYJkC/5ude5hYcNzXzEfb8whpLwS MBHZM79Ppt5T2ZfDsm/kOGw4uf4sTVIDCka5ZGgy66qiFKqRAdrmUriDtlaUamJ9NAdP7gyX AGU2uB09ymyNELKskQRYCjSA3cA1Fv4csSr3Y4WMcWxgE47TDpDGJXEEpbf2m1L2Ne7YzF9F eo7StLv6MfsWDpWHP7rbMpCk3rc/QzTK8U/GafE2t6vMYP8eUtcE3qu3h9qftlH4AG3hsK5v /RxQN7zgOi5hpizrewKEuaXRtWLuUo6TxfOTX1DZ1aPmaa8nhffpWIGtdt2Xgkfoq5nOqgnn ehghqK7vd8wyWH3fXxMsgwhXE1/UesiKeP8+dJbQxRyixoh7phqloA6yLHS5yGtFiKlFCl5t 0RAOYK/BrxHDSNGuiji6mpL7wp50yzeeWd+hm4EClsJxCETcvuWQLpMYmLOSmPGd1ZMBn1sd qKe5cgCP6JBxEoMD6kUOvVXkXU2VDvN5Tr5i5Nan558O2dZL9Dd3we1qFY3G7+YfLHbVASgk yd6hsK2lcWI63KbHhh3AAVY3wnQ1o2QIC8HvkKr/wJ9Zfco+f/VRDYsnOnL/JAR33/uuCLxh jr41IJNKhNtlVonGfZdBhQnihBK7OflzTR3Nz9DfL4HHqKE0YFsYakLS45PgCHsrFz/xMN9m /rx94Z+0847A3GQnosFZUYQTJKDPkM9hp99GlkvOoEk+HOuYed/FvZlE4iShBixNpe+gdsJh bqVVIhu2Lswzo9g041Nz8H8Ni6AKOLQel/jUgFfXDK48qxDdyhQwAjsTKhOJWR9+rinE69N2 P5rZjfB7U5mz7HHH/7Kk7hPIXsnPrMxRnZx7Z2NgOoOyeCFSLO25QoOCYReIHUsIdF9Mhug8 5U+GZTn1C15j8UzmXL5qL6EXFSIkP16mXulu+WVcNFIuj3CRlIxoLbk1GAd/vZ0qHx3rK4iw mmbRAKiSixe7X0SS5R6EG7Dj6drH0vQyAmFXtyGGvyUgSIJusTQ6xgikJnUp4ECre6q9/CJw 9x42YtbgzCexmpbTmG6uNwYT1MZxBMpBq2zipSAJ3neZjHTcVlGUn+XkulkO33+agCbNVlu2 qyXtYVxDGtr6YdMqyAbQUvriys6mejVjQDZDOYL+dPa8Rl/Qkqox+oskbWKsNv0jouUYqGtO /07YOqCEiigVm7Ns/pB1EqRlUdIKoFI+QYAM7gkWS7gBHN8xYt+11oujrlxtFkp0Vo9IhsWF AdbvzoPGrV7XMzjydWxLRLSOLeqzO4b79BEBXFsSsyATlbc5GLJ2Qe3XGmDaimFH6R2x3qvi 4zLtJx/YzEUgyw8TSVI510mg5GizVccUywKuW5gew9QVJlfEd3NJqbq3hYTRhONkbjqxGbC0 Ui1emmWYZCfNvJaN2lGFesOdQDU9CFzZMl4KAaEHiPfEwGkCqWQRx+US5p851zzXG7bEpMuE UF5n/J7h9DNYZKYqPtat+97kUgauedfHEBhjjMe+OhqUjkoubfcTK1fTsifMq/7fQSqrakXa I6Ec9FHsQG3ZUxNnHvHuYN3En0IE7HutN3fY0m8tQulJnuiR22B9Z/XFrFe7j6zi0PV5K1IM IiebdaTUs6EF/0SucpEdsAsXON4xmGI7OXJ6mwd93AqucrWdxBuVRCdPjS1knPSL5WutIAmO AxR2nTbNvrywG842WStJTi5djbEQsFqGn+iltDEXb+UO/fErgBQ+Z2K4QkxA83qxwZDIJ4WY WndwceowrHu7wDabDWuHB1fnp0tV581qZHAmam/W6ykSjN++BvU7PYvMB01h401GsQPK3Mga lwqxRwm1qQRJf5FO8XGewDP+2HHWHeeIgPuszqz9deqBrb+NlbazoRtF6KAbXlkoZvTYDZBl 0X1h6Whul65BstHlWrYAf9KN0ZCnYyi1wHvlH05DIzuCiTGeWvjVhFcp3zHR5aAjfy6gVcvr V6Go+sFru6aBl2+SQVe08zu/6F+CTwvVr4Wpgxy9is0BKcBxQBeOCsh24ecuXxlXXEzlfStE nEKxtxAPZUqfymNReauWTGioPHBCAEiZUBIutFUekFPIKI2BiKL/mG9xq1I95UdTmVo9TNGI i6bdRt187eU9iY8swAYto9OvMx6+GWFRMCR/BvSgwTUkO4dheRmU6OBryQbV4iK2Kad2xgiJ UVacicEpvqi1LXChMvv+/T4ZFaEJ++ZjbtdHl/OqgV8qTm/ni5giqF01qWzzwctHa9kQ6v3Y LKwOmPra2Xw0PyZxJGkabvfdOArBW0JBIH1KiY1OulqVUgL1bpBqmBSAek9ojUID7wlPgSpM LFy8imnrx2xZbXxEjgxVheO7XSI5Jy16HEN/XCLIGVHMULBKkADAz/GrAWrrsxIPl4VC57mD BMdAqL2taIXEtUHe2TptcwQAV1K+tqwpWDVajfHREiBbsNxD/rBXxw/ARXb5GFM/hc8BvDJu GVuvSUwTWWho3wvP/tCpzai4+veAChfw/M75O5SnXJ1fdj/ucT9Wx+ulWs37m4LXvngK+bnT B/tG0xAUtEmM6KJ8x+tXZnew6vu+VQHPFvuey22IJYKRzqfjw2ajDV4s/qq8y5G26K/8hs6l PxArdIZ45ofWhc1b7xmoX2IaItKklT6ze3sDm0C5xVTLqPkGtn9x2SQhvNcJRv+9tukSYMo3 /8/0k7x7XS54xV2Zl2A39SOizxf/tZvNrbEpNqF67RjmVoXqoVItBYL2gwxJLHvcc6IRhFdh 5+V+ZUjsrSlJf6MCN6SnDmUlwPllnizV4L7B8Nf3V8jIQEvFZ0SQd6EXfy6JN0gwbnL63A/C IdIVNRZknAR2UDyhTrvbW+1xxgq5k4sOvxKau2ACjfMwn/fLXIiSDeFbw3YGtmeJ2oWXuPqE AVil8a5yZ1OhzKZLX3SoghuttaepM0Rf9HcBNLnRfSaQqp3VCpOxqNbmmrMHlP+lYsWjtWv7 zxVWWgkopZ+E2H3zQPu5LkfSpinVLZzOZCEV9lFYb1qQgG2mcqRHusEQkeTRvkznUWV/0Ol1 lGMUuEKjKZDeE63DwJZu84G98qe9z2jrJvkkFiyZo9BKEjBInIXqlVqoV8N+SKjSAV9ogx+6 1OcdlzcQboi8isJ1RjE0Msu4IwA3IWAPeDi5sOcQAdkd+N5zh/69xipxgSirwhECQ2BKXfl4 qgiti8O1a9OVvxMSy+ss0RsryavJrN6cDp+RUlmLsT2I3g3iUP+dIPXb/cmQBg6Lz+imzHCl 7WOqNSTboMpF3SFh1ZUFONT5oIsFw0K1YXIUaOxMuERJ/dvX1wceqTRBJiFUt3R5Eu88st/c SubPqL+UJLFTm0u5Dk5/SKRTB9DvRClCyymf9iSW8y8hk2RYsRkAKaOSEMX1bbZmQD8qJL+3 iMQi4puSVxN8xJ6WUKxOjC33AZ+QHnkWcTq3RzYZOb4ZiFWfVANPZlEuBrybv++Bcc1mqjQ5 IkaWo/SdhEbttMuB9922b0IqakLhrLvcEhS3ZuwLqah7+tjqfLuYodHSkNLUPm5dih/aZFij Te1B9u8dNzQv7XwjZrc+SPoLcSP20Hs8u0BSp6I38W3t8oBAThI8K0l34cK3dxXqJt4CoCRQ RIV5ofULd2aYJEnaqzmiSOJlm0WjTN9xqBklM3/AQ2rNS9FNMfPNVuxFzWRYrrFPrRMS9bON j4TGYl4KyBEagYz1riuiN4Po8IFzKykcZYI8Q4Kpj5uARcbhzn8soT3pOHHzj3+dFX4s4tGr B7so15bLRO5pnCUMKZEQkDZEeR2TwzUqsDbDxdPXOrApbIZPdlu7nImd0z2MFIis3/x+X2K3 o6rMQxBH6fZuf/p2u4eDa1UwRUUWVCpuhcZqjb2MCif+UjHzwylTFJyZp6i1QvNA2UMwL5zu GsCqDALhsRXSxC1upxMwZmtyez7ym04ykR5yV5U1BOlVAreOAGyGMVg6DR56UtQHLXvNH4xi cOdgens9D8+tFnKrLZaBenW3f5QDTX7a10wJU6bS9VyvZTTH0ooLOd6nyMlVGKUtN/nNY6/o nf+SE0fBxaqIeTf1sui/5m7DgzlRiCOOMXHNwx0xA5+g35h4rYYjcddrkxdExSHlJJQLb+Em QDwGKH09M06x6v1uNjyEN6Dy6L3Tal/jw1NCfNslMROhskRynCSujsYo4KevUOFDcP6PSwan 8UHrbXzJaz1JggTlel6O+RlQyjXtWH4GPbfdvIryuuRIhnirXIiJhGrCJaxVcpsuqVz32QHL g1RzFUEF/1MC9SVY19BldkRATJOP96boZ4gcftdXfsTVG8rd8zgKPMNRw/NPOBBeL78OivM1 uB3mDFKIVZGJLFtL4ImySH4+fLtNZSl1fwElI2VHBYa+B4htuhWooyvvvkoZTXumZiKIQOeI lvLXWm3R2quGJw4L3SVg1qg7aKX0BqbwwsyM7Z4ACUKHDgnV/ghdVq0cRXBYAkDIFKUKYbRB bRJG78gZoipCJ5PXj1h4fz81j7IpPqLv6yAb0h5SyK50pidWXQXrdqEZeYH9npey5foxIvG/ DvWa21ukWhzvsTBYhYJ3hYK3R+o+eksqPAHZI6dwhQ91U3ztkRztpg7MD9Mce6iBd2OnKzhH 7kQZI7X20xq9FRzdSN8S+srReHXKKerrIL0KRrBGYDalEd4OyeBX+K9TulFqC/dzAuziRuB3 zMFWpXuvJ9lAeM6lDO66VTqntBc6lZOlp+qXcVUAvHzMXxhRQpffmuS8U/G/rd6ULYelEktj E46Od3wF0X+4f6GEMK+ckrSulH70vE/yb+0TCA8QHKJC7FlNsa37uUUpca/p84wsJP/KcPz0 yAoTt00N5cxyO4omsulXWSodXdpn7qM8PTf+CTMKx1WY2ioc7IB09B9EDFyNwtxoGq3wn+8W zzlh9yfp6RXCakeMMeeudlG7HgE3omXtXVmWB/0tazEE9BXi6ntRzVkUdrFxJnij80vZznm9 yHriTkMpTcKif9CDZg4PbA3pJovsenV1XvxOXqWqX3Fn30d0n2vcTUgpaj7dXt5FdXOkhU2d xfriOwdJNJo+EZCghV9JkVry5JlWmmuy9MBgamerugHpBp9t/lSNcp7RiGSpwam24Vte/7or 0LrTR0GGcHr0EapYcJqqq8NZ9ELqsBedc9KLmfw2kSyn3qmq1euZYOHZsIXgcUasPTgQ5LMi EYkg4P1x8u/PRjivOM/AiJcGT51d6Nqq4sJkaEhrd/wxv3dSD0w35pYLzmPjLdK3/G5C3uS4 Nhd4CVKfg29JnibJHbgATG6M0fkpy7GVPIOMT6E5Bb6kHnDjOVM3QCuoiC+dMwK7G3du8CW3 Wx0Mq8yXs3NglSZGHiObtkGhkhHTLySYPV1LQu2hdGsXU5C02MI0O9f0jTKOlqgh3YGOcAGe KtqO7qVZBSOAqiddBDvc2bagon4LDdlQGMatF8cNWUpMgDJ9z/5L8sGHXb4+xE5W89pdvM/y hyz/Uren0xDDBMeLbjmlsl30aXY/aTR7TeiQMSvA0l8XUha0eWD+InHM7V15zkBChoYu29/r WmgkCfY44+TZueTdw1F39QiFKP94UHd2IlWWDMVlizPMa2e6C5uT5XMwoNl7CNLR+MzoR2JM TS/bwljjCdYd4UKk6tPX1JHsdSQXywRqqe0lGqO6oSL1qiPImvygXT32C7AwA3elB6lwr6qT sqlTdwePGeUPqASt+h1wOQS9Or9kUEn/W43qr+tqd8Dv4rdYIt735UlZaHN+sj+0AqTSj8Dv +tNoNFZ1uKFEyEw2tAul+ARwnvOIHA8K+ThaF0y1Wu939XObfbOJqeKYrylZDKzzZGvQgDY7 LnccDp6ppFzJzv6d2NdjxL/B7c9GtfWoCjnRkWd9aIxMlKJfg1st+7ZiSWTBKaFozJw3vHWn Bkm4LL/6jN8pQVSgQO47psVgpeQ5myXWt69I4j1TPnUBJXO5r4fao1TyAIP8fiJLx8mKMxTi GOseCLT/hHHNst0JuzW6z9YEvUMobgJrqTWh70QIari2CKRENqHaMcU1GXgSY6RLrGF+AXTg WzF97sKW86/6XcjbEbCjMZAr90k+mGJlO3kbkiOvKV84isJeAvW0BCd7jk276d8AH82NuR65 F1cYntow+PDXltsiLHZLUJe9lOMeghvm+pkeiYVGWiqJte+ScbToFbU+i6HAAi50Wb+JRCsf ZKs/q5jxDoKOZjkTRO3CLqglRFE9AfDnLtIMwRq7XdcfPIK+nhMqwzlWz7fY/3qSfxRrR950 TvP+pjmX6eszV/dFYeYSO/n9Gl6opjlV36uk9YQUla9RgBrOqAIaBVjoPkRWhHzOTR/QL9O4 KbAKuxqp9zzeKcmB4enLTMRp5+iTmLBLwb8CDsYP97Hz3TzQugve+ijk7vdYQbboesX4g4+G 7LcykDrmHyh8YC4nV2y9gQ38TwiQfSuHlEhl5Yzftf5znRlwFMjw4IwhaopcMd4IbQnaUOoq GZveZPhjIvWu7KIYrZBKlWnm+f2qedPzBgfDSIeWGS+pMRu8Wt47BpioP7d7kwRb7AcbfLOp IgrRxMLhtwZOuKUJDSEzejBlPv9DjTrbWeDE1+57Do5yi0bNrTrhRNJQXIkWiC75Wb0B54pm a172+nFQD8Zm3xaJTlSm9sq7cPTY9w+Km4JekN7DdYp7ws402HAvs+59u+0rwBUiTCgwsNRH NnNi20xWi9R0qWv6XkRBBBqNWRgfgtpT8B3d/JZQx6u0bKJGG1a964GKvSIiCQMqFHGd0Nhm f3W0HSLhhaVo/MjLK5UePL9wvS8qgYl0TK3CMdHb56hUCHNWTt4aAdjj/m1nqkdh+QbaNOod b9vxIcoJ0RwqwwLstZglWue8Yd8NQv7AhZ3l9rV06B85PxJqm+QhF6WmOaEFdhlYmMOUSi4c Ncop/RYv8eKjmS/mbuiZ5HL9tLs6cjrMp1ouIX5PvKvcSxgavQPzA5cQeGpNHo0x/uvlu54u eoCHhIVYtQJsW1/SriijVJyN3Btug9D6m/Su44YVvJYkd8XaqAdvyfSfVyJ5+4J4zAO9RfgC tW3hnXAGvV5tll/nNZ32qxpOXja9LqQ6Ccr7/dPnLAHm348JKOfabwF+Z/ZqytjBzKUqcVy+ bzOgxrDDhdXEtyWFBtmVpiLSXyn6IKGLKPdAuyFQ0kfiXqrRzG71i/LP88g7sJ2xhoOO1F0z RVz37vkq8N7BWSVcAswr4UpTpevUot5IENpb1vJBQN09DdZOlYY+XDsyhDIcYLmt+jrGH4/w prW8MrjnWDd1Yu/ypB/R1JOZ9jwwiwCoSeiGRS+KBZbQMcsQaQ+vCOyIk0Gs9SLijrloWyEC 9DOMNLhW/o1yPFCngrfpKgdzFPggnYUJRFLWXkEp7elmlZZB8QYnTWcN8EnO1g1HkoKy7Diu 9ULUaWDq7kID4Bo86c4GZvVYAYx5qFE1+CeNyHY2rLcIj2yRfQoOJ8z3a4xZHzyogUB0mMbL QhVjRtpz7SqgfZ/RzWq9Aidx2EKUDK7bd/SVYlwfqbH2t+TuD8vnQhOapOtYGQT8k8JsC09g LyEDFpP2Smp5QIOez0X2RNQ2CGccEtPH/ix/DIM+OW89dGlbQRGuU+yXajniuTeyLEuyIPT4 dbEoR0WDs5UttFC0XYZcQBE5FWcOEwr6LSEca05SdVeWjDoBNfQcEdneUci2HbKFLXSuToOP ruWQkqAw15h2QLe6nr/Y9wbG/M0yrW0srV8BnFy5EF5ayNPw3LfZG1uaCvX2WT5RL2gnJbQ9 fOLpo2qS/gHWney4JCb2FwnMhnmBzmmbN5WW6uS4cUucQ1KHpthoz24Ro9Gvh68kCRi4xQ8w JtvEFxaAfYrPpIoHpXVa5iNSoZNu8qHnUn+Fmj5dyNoNnLF70Uq8C3ErO0LRYZmhg2rfLjDr 7E9/xFzGEdfpviqfn6rzqX/XIjwS7AVX7w8swdW5eG3OzvCqhlzvfhVC1bygUviBlmYmi1Vf 6INMp8y4T8BHb04ZeCgZ6xwhe4TS1CVQgkUC1sjYcVgZUITsPrGptz33qjZgd0I6oGpslFog MhwnWBewS8w5nZbIsQYTE+RtrN9AstpbbptwwKpcS6bZoWs8JHOBDxeNfRcGaBxyyrRj+x4x PqbaZqCz00EnnI3CHTaZYnZcAL/U2qqaCGepIcdFBxklLZdIiDVxKQESCrfss5RipTO8V1WL 0yXuZLu+Ba/c8I5fb+FJ4Xp5g2BCcibcdQL2y/vOMWAcBL1ZvujRj9MBq+vFwhN6j805m4hU 3fwFUqxwhqKI6SedPbB3OsZ9WaKAaJJ2O4OQl59etpfpWs5fSX8q89Fm0gTYnzJSmRXu6Vtj umM/4r6kyzTITlENiQLcs87uSQN27LoYrE65oR2+M6cA/8OImAr1xcG4CV/V4i1qt+PU5Tdi cmlI/ysQoAy7mP9vw9A+uzdDpKl+sRvEBThIhdiXRQnS21fR5dbFEmoZ+DVGfjsfaAHRdSwK sIK7LX/Nilyr2a0afHcbuMGaQpuavp0f2RhlQh07LQERDeB7YAVDXVwumf2AVP4BvOVabo5U gJAJobRDe7a5ntun50GInpk8v7b3MxHBRKV0K6MRniSflnNuvS5srVs2zkFhR6Z+n6lYgCiI 0flIumER1QUYfVRSeA0L8yWtf08HPH/xnfmwvJWtL6kOOBdg1mYO3i1Yc36HPGcbHzaQPfIm PR0GU+zh72PElt6wyEaXGmJxm1wp8JC+iYTkEh62Q9EOXw4BSXkgooRr/gnP8TK8TX1xMvmH unXKfotKQ8wJ0RDlDmaQ82DI1/7WHLckxNcn0848dTw0MbfGKCDk6/XCsxIGhEUMG9URiOHf chnYcm6Xo3Iioe/9EPMPJNwFf+5qEgf+2W5gXtQOBc9crfZspPSgBFGrjKHmH1fBe/FW6wM1 IyQFf99/CO/gj/5p7mE4LNajs4tVhmpAs/edYJp3e4rHeS6fM50O3xak4me+yj6vUp2q3gFa r0GMhPJzeDWyuiC6ER03MlSGezauhnHRW4UNF1lTXyZvpILMTcTjJ2xHittwBH/iDEG4x1sJ zAGkXVY5Mn0MqAP5okLZc+/KudTn9lH3fth2D80DkUD+BKp/4o95gJDsW7t95MBB9b8M6HGh uf7b6/uJlOWkHNQLMh4uTCw47Zn7ElyDXOonmGQncf2mUkUVzQu+fes7Qqf5yaekpkuab9+T c+odIOxYTVQ74hkthXnhcV+FanFtQmFSrtIkY/bUJ2YOfiK2N83UBDPJ0K4qQ3yuliSrtBN8 WHtcJukhqXfMP6QLdSJ73kcF+TixjYQp+umXt5Db4q+NnCjm4wgc21i9AWVI7nx1JO3p7txl zuj/KQ302aov5p8cT5iCq81l6LugWIlnU2PjRpmu/ZYhEO5r4/Nr58CM9UJ69cRub9ZDHYPK sBHiYE54qIM1+VkQlPlu2cz8GlVnP6SDP6F+M0yGn6bKfxsy+TtQq/hQS39OBXXEAlgC9r4H S5YIrubWufoXnKcWi7m7hjKXnEaz3FGHtLZwcOA0sXJXGSsF2Chf8f+tBzcLFIqlCC/pRRuT Ex99S68U2lNJ2pSdZi8JeLr9/PhrS2cTP6WU0tfoPZrv0MrRwCykW2+qmThBuKOjnRP/JDWz deaReEoTswTjCQrrQqlE2RFHog7Y7Te8qY5a38UcUNoPbvx1EiB47e2REwXdW3MItUmknLaf GDd2NokTInu/ka1NgOU/BmbbsSwacMcSGre3JSo1qkPxLeQsOt/4bIBnIYtBp+KZwIWuttzn uulCsPme44rh147EyyagLWRLDhn0bZSb4Hwv27Xp6/y2fg7ia1m5DS5p/aY5b4FHFuFwwoNm m/ohxdt5lIpIpfDIxskhFHuwwa85z0SzWkGG6liHTTux/7LfClgm01z992qrcJYSQuDR751Y vdsAm0/h01Z1CjgUvObqdvZ0RISE53XB6PrzA3BJpqbpjBh835YVw+MPgFiGbk6G7NxhF57H kb4lpNxGb+i06gDpWSd3woewvBDCStsd1vqf/4JKY0gbRzPUcjw99nfBdyFTzhyVszn0ZiYG +FvrVDxlZJXUT9Dug7qmyNFW+Z0QMR4WszRJpeu8oxCpTvphWl4h9Oh1PAOYsl5FAqvNbKTg FLJeuSfHhWX+484orwzBdylTp5MwoSr2pLkfq7TzlZZGdjlIG8pcnYaM6l7Bb1dAKC0JpFCk Wy/FYV6d1eHnpePEIhzrWKNIewVwWsayz+9yHLWBreYGlQVW7rpt1SQ5c2CoEBd1b4p+v4Tx uClIGXRY+fRTL+gDATUNPAtBoJel8eR0hRGy+tPZeGK+BwDpxGkQdgMlAx5au0S0KE5HoFnM XG8/rkUl/pnojizHb5mIgn6qWRj3oHuFAOl/4DeiL/CZk/WLxWUPN/d+ZS1TUtxA2c5qF9pU YTx+hMMJ9RlxBKpb60D5/ULHhTMYVhdjfFswiVRN0l7ZnfcLknSDgWi00j9hMTtii9JRB7HF 4UqgXUFUhv/5I81uma5ZLuC0efGPTibQiUwFU8VrLqYJ30wZ94A1lOjDVbkG11tY3p6CWrr6 /l5SOTFDd7ryHFxwutZFazY3YePheF6Bud/iDBc959KvIh8DIxhcAy9RaBVmv2nRhUGFmLAB erxfqbakKckRfYyrzvocT3HdH2A/eaGN48ccM1yxqugt4X630cEj+rJ+SrG7D4xOnQHud5k3 CohdTQKT/2Qethc16sc4wLuHFW1oDFrjP0kneW5YsGz6FUllicfxXDX7ekHZnLZnxzPd3Ywg qPppDw3zLTE+WoNDakwjyeRWvUoAz1a7H4ZPmoLSDm3BkTWkhFwRN63+i+pZxKzB+CysTHrj xxLO3M+QLb8WI8a1emON4x5p6sNFuqUn0g2rUKjGQCNfA9aqVxUWpgVWXxr5xMJpfTFaoRSr CJBjVzAT+l2sEDpDiy1vfqIucPK4+Y+cs54sAjIRTP01j3rNuPO+GtnUbbRob4C1y4dMGoCP yumJ8vg/wGSinMpYdXpy3YItLl6OiuXsoOWBxgEJ1nu1TgrJ5+/Tb1mrqmaMu1UF1dISZU8N ZJG4WAq01gYBPkIsnhUDd9wg+T1cFiyJCfIQu+dxIO8IXAHPv56rs2TSpGhbB5whD4BThBUB 9y7ngaRw6xHZPdgoiJZPYCaS3sqqghJe4uEoHnPca9y1BW5kpSzBMyMEWup2TuypFSGvp48z h7wM07w8m9aigmA8qdopi5Y1VjqoYh2WAsESEAuKRtInctIopjkvnIX9nWqCX6ygSzKzxsJV uln8e9AtW6XQRBR9GXoGgK3JZK45XhkR7kukrntf1biNLEh3x6EAW0j2MduOdiqGONbvXADc F1RPbCLQufhgF3c1jX9nVB0fT1/DEbSv3v6VNOv5tMgWWDAxXPfRzUg8ys1jNAaPG4XoysGO +EKUAy1Ka8EEVqe1tw3k2zVDkBR7dHbj7EbLyOHJ4I6lQee0XMLLp9Fx9bsTvCVSghsCu9sd pYPHZfbRvGfD7vmyQENkNziI9QFRiirwiaa8wfsZKrEne8xlWDsljhJBo1XefY3p5VeUVefn 21G6BBH+Re1uUGdbPE6zfsIVqqW9+/8BQ7SaJxFal2lN4cKUEQTPsgdTQh7suS9blHy4Ne0K QupOcA220STBGRo20MlhXlt0Ii0YL1rbT5FBK7rDapXlUE8VKd1H1Zn9pjQ5XbHZ+qxVN9BR yRfA7sufMHVn2R5Uf1a0yROooboVn41QgENyrc0859bUKBFljAYqOvJzEvQyGeWyjHijCXoA 8/RZ0OJu6XHTCIW6Ffq7n0bTS1gUOgGlw6yan3nRn7moN2uP/bL6SWpF15jq5RPcFQyChgbu MqfPtKZbq/SP97+urXlUhUOfxpSv0kMCam9o+BHqA/NMRMRUI6bz5v1N57leJj12CP8VuvDj yqgiWEmMyKgwav6LxD1XsGX928CTKGzXrUjLngSC+TPCab/0AceBQvEzL34HXdLDf62T/UBl T9yKBHSduz3DEO2oS7IHu2T1YljOj0q/oqsgis8tsKPJHE+QY0JaF10B6HDcqyZk2nvOnFDy nWxJyOeIO/rBwzkiLSWunTwqx2s087he2bpMpkI1fvN8+eA9mq0ZNgk4VCFhiGYIKnNV32Ax NcXr2oLsUyt3qYD7RSub8/KVlcn74xxcLjOl2bAwsHb+f+tPv4bV+d1WpektQs2tCtbYhmcb FW8LPxnGJIzZ7iIyDjk623q2/t8NZX9PFshW9FAVZ3b+Sit5rxFbPNK50Db9yRAu5Box2EF5 a+DbT1Miw0v2e3GgyIZUt9KjSWisYrBYVjmDHaGYbhyp136u7mPxLmnZ4f1NR1yNucZyUX3h rlDuu6Pf4ItTuhHMLJAYalt0i7VwK+her5Rb0LZwq5+ocQXfl164gGVA4JoMtlSKQZJjSVex plPfcEPcyEb94OPG81OvGymMty7edM0r+59/PgJL2yBR7CnNvmag1kPg1/TKFB2s/UmMX2fF I9BlBIuKYSBiDPGHoamsJXIf3svTpg4xEiqmZfc3JbcK9/fTDzbeHbWZlEF9bbHkeS6ezF52 83FbOvJ2m77Nk/erQKl1fGx6153+cfOP6s7y2oBb1KD9hUVbRtdaZ3IK6PJ3ek8rBZSJ+BEY Ks8+BXtPwkiH0hgvDs8p39Hq6Uir+sG+6P0uKdAqW6jsPt6wRuuLsbHll5pYsFdvuqXeUWxW oRBT6DW1BUnjge/Gcbco++1lCI7/90TRWlqj7DFoxCZlz5BEKxBN6ZASgI0XJmVzA1E1OsB4 bQUlsjY7vDKluSdSlrIzs1fNykAiPixxUkJ0rDDAzLdTAlngYot6TF99Elsjpi6C2Qk7BHtt NVmQc4/gK9Ke9LVSzx5A3U4X4L8Cdftn7qKqQV7c6L8fiu5z9l2HEpZcftkQp/0+QvVAC3Hh PzqeOM17SacYh99w6kJ8xXa0h/s1Af63Wn+RL4ofPFph4NNpppEddzGsTYbU4GcLSFv1oevB QixHmHKCCnClT2/JFwRKghY12PEqiz2HNuRgn+v1iVxW56t5ylZu+eP5eCHzDw7SUbsCAYEr HueaUSLxVu8I7w9zKxYqwBnbSX5Yw4IQnkAg7pQsQVqqqDUWKHi62pBwqx1AYnCGUXbFZtgS G9hL+Im67sLDJgj28pv323z6xcaowGt3EanQ6NwCK9ot6o4D/xI5TzN0DJkifmTNo0lssbUA js2v1zSei7IdfnmghZTYjEdA7NI0ccvWvf5v0kn0Iw6vq1lKc9WROwpZMuQ4UYx/Tk6f6j5H MY9k3y7at3o2VSwKBEUhP2dx2cCb7gtadnD6S7XZ4C4cPTkKExyImBYfRtedvJpXwJmOwamW 3RY8kdZ4JzjVKf0xk00dOLQR+t5Ywb6Fgy1YIt6a4XOIxYJrBvpGpDdgx6wJl30M8lOWtfu7 CgekYxGfKrBx0mrvHKAg2AR8Cnv54oFgbPbZVaLk54rQBbduJYIx1K8zE8fSeQ7sXIgxZ6Zy 7UzbryXK3cY6jkVY0WAkttzd9uYA5wQZxJ8dQKj0yYTjWs+r/VnWEDSCEQGslI43AphNrlvD tm4FPO7fOtjdGJPILm3wcjZVPX+DT0EfynM24aw5ix1pXIiA2JYzK5I/CWrGs+FZK1HJWGEI TDkbMmyZB1X/zMk9aQmEukKPbz6CfM6ibSSzWm2Rvri10KfxznwofUdmu3ul/uNLe7OECJ8p TozN4dioFQh2cHhke69pijcsRaizF3Ms3HO5AkgmPDQjaidIClf1Gx3tOeKnd6rMW8TJc4CO ZsOY+3ImptjnaNPNVAmXp1bS2gIghEIY2XPqQUuEAiDdu2/dBZMgEewQbk01aUkfN2YnQj4v lDoBes44TRA7ZlLEBbsBhRhNUCsGda+5gzfXroUfv9qH1+eADXXbJGJesByYdcmxooMI3z5f y5/LBGUo/IIUl66mMQzGP8KATV+xrZ5CqsdfQNOrKz0qR5PlkiiH1adgM/fbgNo7z+7hzhsJ Hgz+t2R6PaLW4Z//QHDtVo736vIPOJ+6o+YNXQ01hDelGGcnMK7VLVnlMvEwTmOH3k6wxKd2 9yXNeDwZuENsBZJTgtfLBlqLNXcoFfyFmWSqqgVmF+wN9WDqhBC4Rpe+MVoJHHHInlbtTjIC akwaQtl4o1TD8imaB0ZSJqPu58znc25XCmNk0HjtkA3nOnDGG7hzK3ZCgE1L2F07LkciWoZk 4UdSD/Zv4/115P2Zz5U8f5Ucne88NIRWreJ7bhT076iiDnW26pyboZ9iJ6GSrVCAssL2c84E R6JeqsBbSNglj4AitKPMtT4TYib9b/qre1TilF+w9AOK7Bl1Yy0ubrATz3nKpItX9Q4SKBJJ QI5gKmft0E/wFuUbm5P4fZ1sL4KSZBElzM9QFGlS1FmKSAGBu3k/LlZIQth7gkJcT9o9X7G2 eLhKMaAjbrOoh0/gw9niveI5wefIWNPPrdYN283JC2TI9q0lkjFU86HDbx1yF3rU1pabwc0M c7AJh9j3pPZX1PHGcEUb5T3Zjfsjf0EWKfhX0DB+7FZ+in8i5OOg2sJBoPET8JVhLZ4iXmPg htcYaLZqTspmMU7I25yXn6xc9Xg4G07DbeOg2pH0K/1/jjFuZVkcHLIHMu1LQj/OyQoSV1xH N2Mlr+r5FHDuPMvM2eJ1k89RuAlOyeNfWqoMDurHSWMldg+dln8VwdwmkjgooeSKX/XmoZPe ZcuNDZ/UwqDuemDflguqojgNkUGZYx+BA+6zXFJsM8je4tPPPMNOUC+z+hLZglX+RkGK1dEO whRpL2rCFWqfn/vQB+a+d0ZzxcAsR7cWxobgCZ9p/NGfvzg35BTMhl/hlaN1q/qlt3cpEX3f +UBDqxeJrAqFPKxhH1OCsE1Fb+gB/XO5Q8beK4FEWCz52tBdsXtrLugYlN6G9mUuDIYEB/+T N87LJIlu2v5p6HX2xh4tJO75HNMbYzAa06pgJ0WvU3gdtutLIvF3/6ygDJV2zYIO6siO2soo nd4GjYoXsL6OHleAskXvDOr2DyCaH5o0UrIel1Juhe+pVqYTQlsJaCpvBEAdT9uI7SxMzU0U wy0MOmZx5EVuI7Wi3XePQ/7AenbRvBo7yfJ1LUcbdeKk/TOYHNMHF6RYYsehwAvu8ZXfq0xJ V6CjUURlG8w9kLt9VQ0z2BU8ZPECEKx51yk3kL5niwrCQA+ywIzwQsnoCiTWVoIbuRC3nFpo FgUdHF9dK88M+0CINDXPyRy2oxHDZbREbzGoSK1yFDo01XeMpfmLt9wZB2tQXvcBIdIpxgtu +EJEnTq+IzZJBJ2Ne822ob4LR0El/gAByhTy7IXIDO0YpNuprufKZDKWndfcFy3/Lm51+WXZ 6KG6c5hx23WujMBjQOArU7l0Pq7HvhTPTXSL6RS3XyMq4KlABBlULqpwIYKUPf4L2fEps/Dy l2SzcjsO4RmA5ztWrrVeSjx7jgIr5tBuw3Lim9mvIYCokNEEPfFGicm49Npn0caGrCZqIjYv 9QC6dRGchtj084uLUUKGHQORwfCuqm2EvKic+t3sPIKMeoDJkHjAvEj3mGROfMqigA27BwDA sdi7LRlkg/nz79of0JdDSdM8cThfsQ3vuzOYO5BHwXsvHwfH8zCYUevKyEZ+0jtOGaZ2WI+4 7rzngsdQDK4/CPIqXOCXuviQG6DdUI0jOA/2M6cwqgV3n9KXVaJwIor0iMeCoTJw8Zao8bZq 1YoQHWbORfNMC0846x3UOoplP9jY1SgLD3EfsW9HBMeiTfT9DjoGqPbkRlvhszpyJrH3X+aZ n0S19Jvdt4usuDHD1XYpZjEUUEr2FTc+ndQ/g1OlkPNaU2DB+Io5HKLzOvsmZISxUOL8IqF3 zKmfjrBt06Tai1VvN44hEVyGn9VPBTJ1ir9YKaYoaUE/4cc4+aiBIkjM6RigKJwuNNZuG28p mUJ4TxUkUb/nR/4J8M4pa4OxrVT5bhCLlDqLSFM8QD7khYsqMEQi654qr6UpGi5BXzAlaBuY 4P1Ltqm4hqMKzghtFPJx1H5/MXrz9+2c1BMQWMRAkZF+d2AMYt0p/uJE0p4HB7EZ6RlR+3e2 E2f3oWdh77QpT84M44wkZRrj9aREpAQArLBce05lu+oAJTDSoiLTiADKT35N2YBH6JoDUloU ITylx8zFFlSkF2x10Ll/r4jHR0AvmcsAhowX0lhwC7jcEea89pgaK/1yLcFsOIKGmZZfS2Gh 2XG8gISyDWbqMsmQg4haLiSNf5GdyxdnEbAyjjIt+6HDBRI4BKSB4szUetAq87IanWDlLK6c Z2DIk5PLvcVRzpVfuC8qGhzP0nlW5/nANWqRKj8a4xtTWew5cvo08LEKuoLIZgVRBPQ3bYbQ +K341APn4Goh07Vc8cHichHaX1lgkqg3S3FU10nZRxc5e2owOBxNP2QZoz875SvE1IVZ+54/ hc7egxg5+gJK/qK9xQlH5bBrwDIuYA2wTU+MAo3zf4WgvPXIrtGwp54HA1sgqMgnxwaRuoCG dSNwvDQtcLaHBm5QxXt0yLB99ukV+9lBx51i2hXgpCvTKKPa0+jbKZmDHR7F7KW+x2JXoaJx 79XOOL6pjOedX9NjgpGUgnWE4VMJr3CcS0AEdFKa1IhQTKtBg1XYwflTpaHHVxMvFHmTH8mB 0T3g6A+U6gNhnv3mW12nIceCYPAxdj2UTEG8HRM/KHSR+w9Lq6xsvTRGvO34EbXQxkufBBB/ DOyors8l2kOEf9pmedjW5/A2qn1Ba1Rz7F3aSmfjm6rCZoGUILgVp7nZZonQZpGGaLe62nD5 y2mZ6h4MqQsqXsDu55eoT89oEnx23F0o644oxhFjNhmHd1QfhOfDMc5Ouqrnp6QF1MO5yA4x PGOerUvpYX/f60BOk+Nmyj2AgOElZi2w4/5hmHYfSX/qVEXrzZhD80l8HmZiHnSmdcA2yjrw 7NdBJzhd+j5nwVPdSsCZZ/MgOwAmwyVrxw9lsojLS/JDXSuRuAgAFghDKLGbzC/zNByg55jX L23osGB9l9fgtI+7XUcxpM2vaau+p4j/4BoMU7tFlg/XzHTi9n9J7/+MfqLNl+GconZdBun4 Z4z0qXth7P42c7mxUhw1TcWZDKMHzpzw/mYmM3pdzC8Y+14anJoxgi0lyxBWRXAfQy2M5/uH E1w7kMHH/zRzfpx5Iic0A+9nM2d5OwoRtZUmw93S/Z9JlMlpxXxMh9HC7LLdsgwz+ydJJt8j oBy3tEriwoUs1SrtHpeX0Qwkh2e9zjUS0+YxcGTgV89BRaqFSpBLoAPfG7tKl92aDUmrF5+t 8EemqP6wTv9U1J6gwBjS8LxeDIvGM0p2hcptiZIEDlRkBFsJo2cIDYo+5RjRhXM+jKaQRUlt uwh+CBxUuKyn4LzqwJ6mf0eilPlQap+zctJWmwjIQCGxMpwyPMFzNws0Pzu3uDcUrIP072E7 ESQEsNkh6BMBJgBwxsN88zS19OnyUhZGIe+8heUCCOs3yIP6zOLZjyCyJQP0ab18AgWnQtDv aTSfUTCtgXngHNIyVTGMFIIjWonMwQmh1vCPw/zzPGpzkIEGMF3+U6pVX+vmQJF3qQyDyoPO 0OvHXFW2jKdFCc11ozwUJuXy8YzELVJqOekedTk8G5VXY4Y+B+w+nJ0EspPPljEyzMAPKO75 XbOkRSe+PfuQV0T0fQFRSS8+bd47QVrSGgEDPyHPq1QVK4mG6mq83GWMoPAH/VSlzsE2RBIE w19ec3h5tD5BIxrcb1Rbqmtvs0aGuGt6g3tPU0zS+v8Dd8zvc5Go02HXN7GhvBAmmhlJsE+k gvdmZRmUbwy89aKK2EwSmJc0MD6QfK7MixG2c57ytwQZtYA525FvjTprtPHs5EjeyOWCeugu 5ip4hUvhZf4Txenh9dP5eytK8Ue1vzTjTEFTYRrmkAbKGzg4Stu8x/ZqVnbvOnMHevf+KvWY lPEK2dHQTWXpOGwSfvI+r6PqPnoPviMe+5A9dQJLpdOk9E7OrX9hASXUWBug+HZXNXaGMVqg OQOON0bZUnIpG5TjL9dkjGtoymmj4wQA4jOk016usqWFFEvPDcRhPeACJpN3xTv+RvdTcMf+ 2kLm4ILXstS3v7Wc040DQFlaZj92rtO5UlcYT1lu1u0P9NOvCNyoEVOM6uSiJKMbPxkj3XR/ xFn8l8/U3MUOxFGkAlbw8ZA/tQsGqjFUH3ixDvSj+RM+jmCkN8AkOe/6HjnlJuYr40D8Zmx5 gtsMG7GyuAzZs7Y46FRfdXZ/zu02nHmWAaShV58mVaLs4mYarGw168T+8LtJGom5x69xAuN0 xGLtkg9j2JHcqBxN0VqK5jGjlyjavZYXljxryLXaq5G/Oggmb+u00aJnP+CMQNFqUQ6Qpg10 Y3GnFASQkHliTW4uEetWDKQJTYogsu0yyofqijqfCcSCPTxxX6nmTSXNER8joesL1pZvOEap Ldv5LK9CnloeJ5dN9GpTitn7B3ZMa2vBX/BFdGeif8BUAoG/EGXa7VXjA6bO08myJ8XF79IN bIXqsskPjih7aiNAueJu7tgeDPZk3g+XUrhK7SkfzBmpLa/ltu1AZfZCi7BzK8gFzVqVI+9V oEUQCoS3QIpEaODmWtR6GVoZmnSDH7X7Jcv6osc8qC2qZGXFOv4jCFJt3AN8qbR+WRziJaXn fkJtNy0W6ldcY3FOqmivCpfq2Vqj5p7Of+M4Fs7lKD4rC61zeE5cfQENnjFqf6uvqzTvGe2O VKX/4nIgPDZRgndhAw34QpoUb2OUPJZvRCIXnO/TFWNTeCDxPLHYHKjf64JmP+Zxe0Wpx+rl 3toWc7+htsHuOsjTZ7CHUi8P55cvMrGr/bw1vL0vM1Z+feM/xJmPKXAqr5VPm4LhA/VaZbBL +xyhTuRZfySDU/S6T4qhArknFoWK1pYR/slFWis89KGAZcvZBmw4nJwAntUFwkN1Ed+6izGv 3rGImt6OG0uFv1bnNtmjMj7zjK3T0Cv7+UgH+GcMt3t8kLDKhoiyoJ/gJUcLNhsZy+WT3V9Q UrgkfxKjuLlhfVvVslp3veY4tdP3BR684JRVjTHBUDFcc2QoDVLxsoJvyO9yUYgtHuN06T9n fmQpoQHtoLu0NLGP5dnysdPnM1Uvb9sITtYSIKBC4SGjiGinbVpCy3DzVeQ+9OLo/sdJo7n/ QXuc7qd1X0fkZE3YzFx3piYgit8I8R8oAhymYPkAtug1L6BsY9Gd9rhjxZVjSa/UYJDdlDrK Ufe+GMZ6ImdMVQIHAtKRn2QibDqSpMzYMHfjpolfUFBjQ4tUpR6wGDS/i42gguUirI4FA79T qnJLreZNDa43YfmfXvcHaUm6dWaLaYKUp9Bw8awRxXE69ghCT2rSgEQcQduDiHmYCPMCm3lw 5QDtivPodToZw+5rXIDG+27HlTHRw6fvJqCt449LeCmwwo+ngzV5WZ8cmfeybh1ZDuQUh+C2 hS5VapJ7OXcnBOMXMUwNfxS2Vo8wBKd99cD85KsGZzKJz20NQV1nJfFCaiJ7d3Vkr3ieF3bH lbK7BpULa3h64+2tcxD9VVkmPYDkzC2YTuHatWb8OwG+hOATeoHKgPgltvRwVxuH4zj9pysb jZ2eUdRlm2XnVQjkz7hLB7p3yY29mS/dcuJle7IAQfeecHafjQy8o/ol4EH6Gqj+L5mKlUKR AotsG08uqsO2Up39MsBXarlI7pjTTLR8bWgDB8lcxBEEIKbx2y5k5RMmlQxUt0HPsZaGz7cJ 5Xu0rB5WY1nc25ZcgzSaIqZnVic75G2NDsAv8p7DYYdxuNOa6XH1dEkG+PWU0wa42aSUGIAY 5Vpeyc077hnWqZdhtFinCm+4RXyFCdL+nMnjUM2rEAqderWN9uMRJoKS6RwvEskd9Dp9iwvX 3PhOaCyiC/iIe6nmTwfFF1DhOEHg53petYa6g1OJBM/SvaFuZAELB1nAsrAJKMHpqT3YMwCn tOUzvMa4iG1L3GgHwoArBgXrF4eAUKDBkmAdeRN26mf8Tk4BeQfOHyUC0bWq555HEX8ng2vn MwUbokGi//OnOS1adHCgoO3WN12OfvpADinQeispnOyUDk0LC2FBzbuRjf8mEeM2Xcf5oWMV 5Urpk0H3+m8JCuCGVXlaBjHG6qgW1cokz/Oz4qZqxYkxhz8Q3KkuDyhlo7T6agzuFgkycH8w z3yx59v2EM4AlqQuCPDpG0v0oHtcQSL8umpPAqQ3TeDrKGjOeHK5a0SapjwMlo5ekgIuS9Bq OtAIIS/Ao6n54CyTQak+Kme+SA6L9FufSLOvPBV6AfpXX6tR9wml3+MarQGIml7nA+L3ws0h rZ2RBGQsgMUt5PHzWRmdjEcr/ecW+IvZdyssAzwhdi3AWDQvaFL5IXYH5ux8+zVpZ1AE/pQX 3BI2jmgXIt9ckKnKPrJJamI23kOCgw1mw+Stb+sQRNOne1rpNhiVw9zYIWyJ0mvKm/72nXzn YNS4BQdxlrXM14snGmHePLkVY7LOgKTj8dyVH1mcJa7vxXWTQsB0RbW3uwKRvlkytm8jdjYp hK+UgaXq+5Y0JHFEG3oERIHcY2UGf8CkHmDNK1UD64+IhEL8Jc/Qv8w0H2fL08Vd/bFLC/sb zK4pe3yTeK+js2k1l/b8peaPCwajqkCUU9rv33d6CxDG27ih+TRCZ5P21pShBbXeN2g86Zpg P9+uSMl/hWlrgWEhjA+e74ft2FouvdmXM8n0Q6l+0IXDe398WVVoM0os+SfJWBjGqskV66LV smKIYItB8biowioJ8HUoqV5Qe7hqMFlYno6rf4VkMAyZBXISFv4VErtdSQn1seitiE+ZO1z6 sDBYhWh4gsJt7G+hkzmBwtBwPsz9pTBF9D/ECPU2IfR1Mh3LMh7QMZEB+yi5FNefxb5hzjFE lHSTN+86a/ek0pPEoVJI2IpttUPnRQDVqDa88X27edzkJzV6jkgUImVH8FM7qxuKpQdTeGhn h/YviUG8YLe4ZwRxgk0wGmLyLd7SIaW8ZTJ/2OtHt6I3B6daErfxYVE2RMizLb4XsU0BsLKI gEmT26FTsNu10gh1lKiCXraBgzznWs4/ZS5x4EOQKbXDdH2/6a6yLWP1fXbL/tgaUrKPLQsQ u+VcWaY7EnxVNAuSZ+sx4/tqWdRDpYzsKYAvTv09KucgO8+zN/fuoK9odOp323b8NRKYmTlY 970hTxO/h9by9PVPqZYUM6FeyqROsuSCrh/7p9X3pGhqFqN7FS3dSLcUuDqGZnRYKjW1krL2 Nn+aurLejTJuY/79GfO6EM95rGlzh1lsYG7BnnpzcOvPAp9UmqEgYE+J+b8pF52WfiNSzT1w Zgv/xKXGHzHxp97etXUssCzzzgscdvCwMjCrC3qUWa+3ROqVx1qxGkeF5WkgwUR7yAJtShGC IJRoaR11r8a6+HFJGFLr6eoIo7uDUx4LsC3y44zaWnNd37SpESXfVqW66wxs5uPg9wxDJ9ms 80L6xWo77/ZFtaYtK7ui47Vk+SnEx3gV5jmb9jhJdRUF0HRgWdpOtU0T/ixLe2GLTz3CE1Hg GluPZ9wHlmwheAAo3lft4O3BgiXDEI4KI+HX8oY8jV++5HhWSdv4s0qKBw2+JwubeKoeTyWQ KNr10mBu+0K1e8iPYMDbx89I6SJNM7m6UWHjKV3DOiyBq9VI8XRmjKmS0lk6RUcmgpv/5DwU P0BA4iluXyvc1qzqNH6di7n69lLqI0Kb2KnD/O3FHayOnfj9h83K+3sGNnKD4ZHIbYZdzYVu 5ydTQkSadMAW66ZMEOCnFNSJ7m+irvfz+IFW6RgCFOh6BrdcQYYlfWlVjUbNF0xkUif0MLbv j8QS5YTBk1KsF3KuZeBatX1BicSiZIymwWseGA+2Aof0/N2aV68MIPH1ifK9f5SToGYqbCNc TfzqtYexTqP3WRuZVS6MRk7CEwnzXJPwQKpsPPmip2wOijyeBLfpW3lRBE/sv/QjAyhrf+M4 IEiofgyPeFAH5eXvYnz2dSwV33IXCBiFSW7nuSYIFvfQSxaNgf/h9ZGKJRriblqC1uAjzoGt Jyb5spJiL0x/L+MpuOkxmpT6wKDh8dV8lp1Y0Rbq0GO6vatfUoeBJgwpTicdhpxHRri16Ejf OjBVxzrgvnZLllPGbhwY3MnT9D9D+8MYSoYeV0G5jP7hymgUuIHtbZHqVCkmpvLb6twf5YEV srAvVLfqKn8tLYpMarTN2Bog1XF7gegjvIkODFG0iCkgsC4cEEQF5wfJBFH9CofgAp07HHRd KdcNe4XV4c4ajvjh3kDAYjJjuOjpDD652oHJ/zNzXL5azBpypf6KOpjn+74jI1ZRX8DOieYC v0xixkP7Nhb0k15Aqq9860GSAOfJnbhEVuRJfrn44j3Sx4Jr7bZH7kwCpo2n6T9gCL4M8yt7 a2V9u7ZhZ2njFYGX/2rgDOoQwUn8siivG5r7ADv77YJMVQTTr2iV+wY4+t8VWJMZE25cUX5n 4L0I41cKtqYtAEcdJEI0t0K3pAoiPv+pmmpiWjWuUPety7feB6TihelHiaN7njNxsLt7C8Oc 2dC2OYzfU+EnVTpytf3kzW2ccZoviE5CgANySq+uLtnYX/fObh1BPbCeITUbtzF4tKk9lIxp ihZIfoNL62JGUj6K9wbNSCmrXgv9Hh/rMRpMSxFXeriqPcZjNaza2lx6mJkDO6TsYabUOS99 fapyooO5zVWrt2UvQrvS/HPZEL1Sne1rNjlDYKoZ9XKzfRSWz2XKn9Z3gtGyvppAwkXEEwpj xgiGPtfvcyq+VmVUJQDCJDatS3XjfrPJRugEt4D0WGMR/MqxCfYqtgMnD0Z1L+07AWTeuUdT AFRLEMC/5Bf3+84GpcT3suaucnZD09xcO6jzdmr/j47kRNIVqGjspl0ui7xpQBN2IcVdTKna /aafEZEApS/Dj81TO6Ji/He9ABGFrFvXzbXdBBJDpLQu9jeS6Y6cE6KqpTJlCKENQgfF+D2w W7TmHrxUXnuM89fOhZ4Z9okc+CNnabICfeqSKK+V0wjCf96kwARYr9eYjH6xCKewRf11krLY DTlNgnRDAYhFf0X3WhDPcTM/yDXAUImyOfwh3B3CjF2hjt348aL6wrBCiELwuIAIe1LaK+EK as4K2Va4IMNn5qcFCsr6BcBqkSQB4USTB2UcFeW8oXCwvXo+i4eROiTaLpCeT7f90IDYsE+9 c5qfNHP/w+csrahSQtcRgyVLJ/pEZamj5x7sy7QZMo3dYhTrdTs+wiNJkf8uiul41izdM9zB IaRoLvAAr+WRnLelWanb3S9ytbND6GC3Ls1Q257s6l8zvJYonYyE+jG0oFi54zBPUR4XCQg0 vGA7m19P9RudpL+9KLgsQ5qWPgv7a3g8zSICuRVBCxuMf5dsJkzFiywijI4f0Yrxq87V/lz1 hYOu2JNOd+VJz7kepQmCPYy9ZUr9QKaXeoL+2r73AzJfntUyeBw3wHK3RlGWpzde3lV+bj+L fiEXU3yH7+OHyh2s0BryzH1DcLhF1gEOUlTBg4Sub+BpcSDywWJij3V4Ogf/YpEudUujLqpg KDhxqPe6LY7I4Ubz7+QQlCAfIwGBMccFst89oRJTZO/6wBYddlqnm+ILs2ImwkHC0KiU+CYN 0II0awEz0SMrfWEth5uiahx7jZmOunxncILQ9ft6cZzoTWcpFQzA28bEjVEqFjEPDjFkUXUB q7nrzTv9uvr0RKGMDmcB19zrqFfCiQKKEns5ToI3H/9mqvioqMC8DypV7T+qTeHleCLOVP0J mvevOPHWB+Kf+6l6fF2+mm53Pabx2xpMsw3edf4UEIUQ6mnJyfyOYGSxrMKKf6O0dFhUDxs4 hz+hLT2YajEbGFD83sA7Q1WyrJ0xuLf8nVTXhAyIwfWgA08ZytTBIl3isR4hmbLEdQfxVZ6s yXKJrMUAlj1mekP8kAPW3WXVCOe4s+I0yT4mdEH3lTCgWkIrVHdJQs5SVj0Sdve4EhOeSiDv hmdLbRbnftM3naYXaKf8HeEvlU19ALtzDHc7JT8yavTLEVD1J6rId4GmK5ox3Fvy58OFH2Ia b0v6kRgHGAh9MiqTWAv7V4UpFxTTWFsWyMjxTGQQfaLbcfUF1dmFW5JOGXe81AMhyY8ISH+x 4fdrPy3nIjx4uqqWa31G4bl9xOseiUjvKRlebNmP5AsQ31Yap2KiQVSzOP+mcdIYmyf2k5H2 olhouPnOAAcHJC9QMbVfR19JmbBVSPWnbqiaBpCiGMJ5xC6KHzHuv097pqVge6MCCcqY5VrI UycaXsGgLOepIVENhYXcIKe1hJmoo6MtRxZQ7PEbQ+QI6KPI4YFE+3eDQNTqpFkhvGgwViEm saTwURtoFNo8VXeaPW0uM/w4P/MD2q+uA86fPgE3Sy8QfjlZDBkLwhV5hejn8nZOvSz8/nPa R06DMFGla/VfdN0P6qxACGBukqiVyqah1ZuDt+KmC+Rt/AdjDzV8YrSOM33U8kEVayem8aFs UEmxIatT1gy1z73Q0974N7D4Blh/Sh8OunyfS88g8IB0FQvccHOErcYQpExc6Vt99cj6FI4R QTi0LZOGiyCiBJ/qZ4BP20nPCfQPH+NYIUfs5N3KmDhvSuasMaFwgKGcW7d2UnypcW4Jy9Yi ux6mOjmYbDPmpFEfmWU1Cv9xOBmdNQrk0Ukp8T7C6uZmxvKFbGr10EKsFyViXHlfMgmkZB8M riTw8HEVP7MDtZxcZhjvFajQP309PeIjO1ZUMXp9m0Y+BH4oIwoWy/K7A/1TtWCBra93T1ma ocyB9cA6LzjAVhn+BBuE13ViRolhKcDvEq1VwSl5k/AWPnh+t/Xas3i1QOwMKN72923U1/Nc c5zchFS9xX4nGgzF8pSmaszVWO7mwBkV5SV2YuLA8xXKUJ1YIVj3jDXwN92NAt7gsYY7wQuM lavqPOdRfUBecFVUg/qD4e7n2QcFk1n2+QrI7XzV5P3ngXFnIST8zYrhmb+vv2lbejC9i5ga JhbTGLdNkWAeLRzbVfX/ISELbQvjfvV5WLbrvhQU4pBMKmocW5gtzRWA04v+OGRb7Ih4YfRm g/fdsQtdlGQfxcnG8MagZya71SmpZijti4/fgjadyDzxCrJvDsLdejKhlvncQ08ACFEWdzGr 3zC92MEVyUQUaiHbX9tytIwqk95XnONTdjiksRCqOgV9hf4Eo95ENq4ZE0ylX4zb0omhzQWg JqgKjOpO98mMfvNq1m/1mAVP2R4V06LtTSvHJdJ6mkPtP7hdlrlTYFi+y3WjxpJVU3P6ZR9s IYwMy7zzkuanOs1y0Lm3JXiC61xBGQL1GW+9jkZnxpR2qlwrqNEmx1CsdJcW8k2cgqBzn7TZ Hg12/Zn9eK8VPasEAB44BejrfbgH60tgR02GYSaOsQzcP3o4BhtSDvC81N/Xpy2ikbCmlP3G XQwp5k5adBsYUruJ5t7P8U5ut4yjiu7VoBn7hc0IOrxlBj6l1tZj/wTDpMu2ypUm2hJvWbpP dTxu+NQyNd3IExkV+s8bEsYPhEAf5pYmjPj84lTXKHru0TUgA88ACyDUAwQPeh5wcz3XT8YX fBRL+Z6GBGCTHnEi5P8vEXHGqPjUQxiGqrXVgiDR3977Fv5pI6Eh2iSeg6gOWoNoInBpVunt X3BGDY1AI2UdoB4h54TWT4DjdHea9DmtnbllansGvGnoPL+Phmmg8FG11miTyR6ig43e+kQA XiPc3smFFL4TAXiFkf0QgbMTBshOCGstgFkoOfF+VZasyqc02onzjiB8koO70/xY6GnBTwwy sf3LKJ0p+Af9LGWkBqb/f39ZTh1OaJlWtfLIvRLN+rsMRidaUSTp6MbGzyUQLO2eK3dDB6xi v9o7PvF1l1pFWuxGVr2TLJUjuK4rxPF1yP9IHa2+0Z2unGurzPZvjAxhIyKpz1e2Dz6DvpLZ 3k0jkWBFpSxxZvmHykA5dQesBAl7+qGNDV6eiaPMswx3QjrgF91Q5+L6l+++WaMdDRelpy/d kYg1qlgfuLs8/UBrcMQ+hXZDnLn0SzWUIhB6jeVXXxbhsH6lx0lJIXrMMDPmugjefp4nevNM yI6YuEwVq2ufR050/lmruy/MK5GTaoJRzClC0AIusl8rbLnF0vzD8GI7I3kn+sJJwjkoEj1H aVdZUmS+5ro0yDshcRa45bJ4ncJVfYllqF7gnXuv/4zpBfneAR9m7XKO6sRaf+4hzWD1SZFm eUzUevgbYeHZTKxCbGEQ7H5reWdjhpnZYdYUQ6/E0YPpneQyPZv7PRAk7gd0u86d31mXRvc5 Wrg2IXcqZqxO+NJRKZNUD/HMowjdrONOLnLgvgqbSpNupj8mifNvEvRDrHWIlEQEloQfRzBc nxMNLPj70Q0EjHawj/FzP+FJDohhSKzeO7tFPqaNqPT5PIX35OElTEyfllA8cCYE/hjvLGql PKbZuy5oC3HgfnDYOkBxZf/Am1zr0nQcZkxAOczlGooJ2DtX0uUPJvmAUjTfP5SRLoJTNL9e uUWyNce5fkZdhOhK5IoeGkFlEx2G3W+VFffD/nxYH8uTwY2CzRF03+LEfERqR9P0SvNMxhZL qWKEBs5gF6qpU4Jl+y4AzM195zd22jPbJI0ZtSvGb9tiKU9EUgrenNLTqiAGvNz06qjsFxSC UWFES/pu32ORYIGq9uw3vozC/A4fwzysjg2Er5J73JVXhoh5A7DTyZQV7kRheXPa6bjUtQKK 2S60lEU0s7zK27QdeFYZJVii1JhBG1kjsgarYhpkhE9pk91er8npAmRbdhf+GGSOgleBrjUu 17CLjD4BAQMiHZcsT7KXeJZ2st+8eyAaPx58XRXjMFlNd/2AGOZaeyV86XPQpDpKOsJeITD8 yfP6UUnJLsAvgiA6YnsKXhfyePTIZSFxG4AYc6ggbtHAZKSJoSRQuPLYVWdq0LNxqwCzLruX GV8ZcBAT02SjX3ZexwwjhJoJ/DbdyluPVINwu8GfDg6ugCp4qY4cd2/BnUP8JzZlvKA8PenE StZnQqywQ+YQy0X3htYWolU9bt4FwLMB/wgtcT0TM5t72pEvBYYqtx+MbxRdvYjVnQHbg7pH 9H6SXM25Fl7IwojPkPa9dlkkJXHpPH80fenUOQ8j6779XG0P9KIiz1FD3DxtJzRhK0UJ9vNC 66/bv8YHVqEIuepRcM/2KlYCI3R0MapHNN0VslG2yeBBTfl64Ng/WwD6ruDFxmWS0SFYEuVr MPWSPBefK7/70/VLnKntmvZ2ScMRbkkaM0XFRJ9Y9w9dDqRCPNXleVhFH1OWNce8+8rm/4KS FNscrB7vi+HHPERVOr02NhFoy4EW3jZuQBBrX9IjeeQV3crGksxD5Th1C9rordHxe3RS5BSO YcxWJyHgjCEhV2qMIRKhS5nn3klixPjgr/ouNOiw4YBRB5lmaY9mV1IP7C30zKos/AWyTf9s 1IPa2sY+aD5uDWCQvGa9O25qKFpY168N7T7G7GrQSx/uLSTfbRYM7VqBovmwmFC+ei0zCcx0 xttrHNeK92nB5kwpC3upo0RXifCHQsppd7yxTd0PHm/BwaWnerbo5JNyfId4Hk8xWq03J4s5 CeAYSLN5qyhX8R3OgLdUWXix6hUwgU53YDPm4HPIhkbXE5mW+7oWdi+H9HTynQgYs86jQV+0 DKrfZoFlFPby8R8CFoXIKwedNpYIcoadsACRvG9sFHqLbieSrjKy6M+mIJOyL0cUL9tpyvrd 2iz6AoA8yO3TAbNVJ1UTz8Qy8BCizJE2bKTRfSw5ll+AJgir9l8q7JAY95NYbK27TkjPKz4w KG9G0rxS8y2SeM7iuAZGxp1qen1b+HfRfTZVQK7DQashGZmPvHwgUJCQYQn3XFjq0ToUmV2Q 4FZT1bBEfPbEc6+my2+2e8Frt5TI4t7AuvfkIV9FgPXi7O8+8smk8hfwTjOmikEkxkAlct3r L502poC53G9oCpZ6GSUfVxlmXIvKUkoRcDEiNMPMv6Y/E5r80e4xJW6UdVTzc/thFTRNbZkC LEOIBhI+dEgEbndmHr3+nN0JHQ9vK7jRua/VL1luxJhSkg0lQBSsmvEJIVRuf91sfNNL9oP1 vlhQvp4ZxR6VWSgZkgDBAd9pl/SrGcWRXwO+xC7dIsFwN9BPOm1LiTxDHUA+pkMJHZUFLIrg +M9Nsaqmw6nAbkv80JllCp+OeHJEoa1Kyl7ngkwyhsFecxpRQOyQ2vRuDNflDjvkmnzplvik wrtRbuDimOYRUhtebCeHhOZ1hBU/l11RhHZJMDl1sdmgWWJKhNAjv+jUnqULNUPv44pUxgAv qHj0zpoXwS7fG/ek/JmK8Lv1FXWdCS/iQVUAgStDfC9i1CMFF1u5vIv6ouwIaECH1mMtnDD4 z1MVUCu7nGrL8QrFGCOTPeaaTqqRmo/qAzdOxfArtWPflfxvdL8Y9UvORGs9ohhJHAEF2NZh szLRjL89SXtOj349C8WvifxddxDcasMrsHylYCXyBPMAeq6ipthaiVlCCFVZ2hNiD5ES09EZ kiCwmrnLZD6KyY8bprvwLVD2oJbRADaIA6PLXY+3cdCsP0y1K2/jIyr3qyJ3WDI8Uw8kH+Wa ON6bXHb1yIlp4xYqzhQwjBCcGOaYf+K0rAGfvVEe9MTNmshcCLorSEmw7JFKMXMsII5LkY1+ LlXGjNSL7dgyqFQPcw7b+1NvAP4dZDv1KIesPJZulPmOLCSs7meXtC1d+5jSgWXp9Ddys0Um q+MfJxFFy8WKW0n3rxqvCUtPvCPmKT2QScAy9Y2RnR+M/FrsWUgmFPH91kAGhoOISfvZLF6u 64rfQqKPTiDYnNg3+pT/SVBTu3mHhSZS6qP4ozw/D5OzIA2iwH3j4B9YqKESFN/XKY3Or5LD nAPmqXArHHKNTBaucsDdk2ZacdtdDeYOOQgHkYBTnj32Evi+2Y0lkV4pRkZO2efz5YiOsRWk Zv2AAsavFGghl+K5pGx+dp/QPksHZAFDhcFq1bd0d4H9TU4+wLQCQIOrGLeu/nlvXfJv50uv U7xvruTBte8Gk8UgykIEfQTUXjZZjdDc3r03DcIv68k9BSphwRmGuYcYxKy+k62wECyQpEoM VBcVltA5H44Bh4CYAy2Zid5U5mnjEu06y9ks1pgHHhpSkmv4ISF1rmNWP6g4RMhCkAZex+or NQxbMk9x7Z76aTp9Z0mkeGV3mYGKzqMxXneW94bI50Zck7e/1aRo8l1onSYbMs7av+ncr+mr 8iMfEeZZbEou4mrP6LyKPS3dmNY2Ppcl88vd3aer+N3cR4iCTqYUWtEwqthc1tejjNf1pWRg Idc+lMdyG7QImOB7tI1b76co1MxCi9z+rDijM2AFQKzRk25+QcFCmtWs/o7lbmO7iQKfF6hY kBVGF574d8etxX/FPe6q9lTkq5LTLtRGSEy5TtUPOHnoCAd5Oq0DGf9RiH9+nd2/EUdNAVgd X54NNeXJ/yc70lTdJDoinUgFDB8/xrNLWw4465FhUU+VxYgaMAnANUwZ4G6WRkbBsLPl5TdX 11Mb9BggM4laQiRSh0lZHbkndvqhII4+6FXYGbMiXOSibtBXqvJzayuLuL9JIAJTCY2BRHA0 HHQQTQtJGA+eh1FPELLJpUv0lxUGUz3C3MDjckcGv745EYhbD9kcwPr2TwtiEjnDgtrhtTxa xPrww8GKuaGQVymKkiM2tUL5dRLu3f2Mu99H8Qfh7M2Py3z/HyYriMsPfS5A1LQOTITB/GZl v53Lwqa7oSxne6+OzshaPnRdCwOlY7oDilwe3wBmuzFg77C58ZESKW8Fr2PQUHUCPueeyKE7 Tb/1j4IInqTRfMTux7QBBVniaAm58x3lwAPL85bYxJUhGEO63JvaSTn8E4f3uxnywOaAom6L OwRvk5qOliP6ipkPpp+YKUkdhD5NTPW8SWDkfEUAHVUyFG8iLal0SNVI8rQ/D29BOhuwlEGC ExOZIJbrra78mlt+ZWbzKTv4iXsNW8GIjQpYzRhii/5NrIXQgWjLswOPVqC0fJPKD3+/ltkZ shrttwpAFNh4WYzS+U5gUWj/pMXqYb/SeXbWDphiCksTJGO95DjDGCGBuZ5N/lyBpph55Uqf R18Pyd82qyXxQ1YGro0GAuxOiYnUMJdbm5Cpr8TQlX9hdqzp96TpFiDyhibiC6FFPH46Vkvw QEHy5GZplcbQUIooGvCuA7RM0m4TCSiqYUT1BDRh55e4yToUo1G7z8fOvnyOC56IAqSdGKW/ vP+b4BdG9H+ZvWn8RVYfD1jhpiktsNLdNlKz8er3qMhyo5HejxrIGAvQ5yHU1rC5dB2/cQpf P2pLNYkexsosxZ3ONuUDjiDhfxDWMR8IQqzUsNx6+PLXnzWhZ2UFcmW/+C8ElUoCAwhVQjs9 QHL6s/G0qz85GF+SxcVB+oll7f6m5JBAP/kXV2a12jdppd0lOt3uAAJgMQ6Ndx8fFxAnAQaW NCcf7/+acAANguCZPZ8MxnJF7jk2tPFv/T7IC/nfvcCXWmAaaaEZR91uSoREWSMYBPmHs4Se GY0h7cMSv4jwlJXLZ3dgGTq50vX1D6N66DbMNirb+l1X70jCgFxIPn4FpXpZN7yId9ckwAlu xIk7eXp8a8wCoUiJi6WGWcn5ZzM+i9jmllgg51vznj80YMZIz/vzPUWv/iKdJLYVNxBVjeut 8MQ1+BpQbHNtTsiGkJBrGYx/+o/txk+5XuPwm6iOYRwAnWbLA07T656aian8oipZZ++tbes6 2QAmDLHTxWySIk2R5y+gmnDTfUYCroFRFaoQOPzn7y+H4SKT1heA+15hJzGVf3DICQW12ep/ g8DtIGckXND2FZLyICQgl4Z1jQIagnbKA2f8e59IAQ5W4PaOim9QlfqEWaKSzwNAP8skS7Jc mbi+b5nFUL3kbSkirPf3kVyWM65t3Iwp0dkbTYLIWfVzLaQG1zPJHXJs2/Ntourqo6vbFydH gbUzT15VZPvhKn954Cbybzx9Sp8cgR/nOUU+wtJ1KWzfS2snobV/7UbxCuDgO15CwM3dJg0f URRbZx+pHm6Tu1TdZm3aqACMyM2huCs2gwaco/fk6EzP36dKX13H4CeRwIbFEdiwx9GQEI9E nF6VnQT/OWqEzcu1WVhfy6J6414FRBMQHigrEDcujqyYLgv522iZA+ANsaRPgBgHABMyKxY0 cCX4xUZ6UFGWywo3LCVQvQeEqS/dZMq/EhbnamQTDtjy44jwYn0+CZvMIrE6RO2P72zVmFWj AKs+sivt86CJVuO7mRCjeF9Fe8kGVffdGTtCtk38ShhYvWtID20GMyJmtbOpgwdWpwTB2FcG PA2bJ4ClSXaeHVEIOY+oXMf/scNYs82yAHCFuFTADRzAZFioE6JXP0GBs6QghioGSqpjDqqn FJamgyyTbyCOhkelCC4SRFClnJlXSBfCRTSLsEo7eGnswYCllbZBpyGkfktEKOKt3VfwCbz3 oSBC11CCEM15FjSGnT0ozl4+0BlURLUIsqUdwwjKCrZJhehF+DIIN4dG1mz+Wzn2g1EY8jtD RejaadsMSMaAnnqbt9MSkz9JEKPI2Z+IRuMVKK8hsXmvzchBj77R8d55g20ZPyQva2LBSBH/ f/Q6Km61ungmGjFwjy7wl7bLbtmArIjgMe5S6westDYngbD6S90JwtiDkQynRxbq7yctMwDi VJxcZigfmfrHIOsFkXeT4fDZ9QfkStbcRqOnhhynKt11EGI+2mhNkPTVwXJBK7kFH/jwBioV viGUIJjXavRWkXDHltsSLBZKadM9+ZIEb1DInrjx+3WTycKOhIxTEoq2sgnvcDn+bqogHODj pDjlH63p22OpiXf0ZJhgDJYEzS2n/5ZKIjcYMAaUDyM8Yqm5XrLVkflh4cnlHFT2FVbcwQM2 xoLIM0srcZffo/U/WtDDwsgjibe4W+1WuYsvWRI+T++ONAZ+U2+oHPM4HmQSocWlqdOQued9 rwVhTBj2ZV5avQSFrEtmT14RciCeKj7pFfCvq0/u2k6+tWtj7YL9huOmsDrwbkn9O8rjYWzP iIn+0t3IgaeB0h4Mst4raLb0uy6+BRlER/Bc4KuYSrkt1nzODKzEGsqVrJ7CTpykdid6p2dG StGbhMs62k38T2OHqatNJwW+Ok7bW96WH4q6fwYnN51hKQUxjPIKt/mC1QSV7+ShYQBZEomB SqdN5qOaTtyoVqOF9l6BJbFWia4OtkoIlFCLTYcNM7JhBtHHQWRSjHADh7GCfcnr4zEU0rd1 4MI4g/SkgRiktNHWtpKhKsJnj5L1DxUwJDblwXpSXkPFbca1z2gDIeWyoOGcl+Hx1XfrMpXi 9c8Prp0J+lbQsUKhxAlziwVjJLsNYMTOBFs/BPK0KdxBetC5KyMtbjMsZ9VPBWdqwRcPZsv0 duPOxqMeVihv/NUMbFWFy53n1EMs3OATRPgWCyiP6V2a9kehgXY+bQZVGdhFSfEN+Y7ETKVq PEK/R+Kr50Ke2IF+5c8MhY2U9gNBBOpSvhDXBvVgyI94nIBpQ8Rowm8WBqWSk4xrK6oQNxmo zAb1JldbZ7LTvz97Wph54hdQMF2ceFwj65uupo+jc8tXjZQZaQxR/UqOZVRsj0bXH917QMIo sMP3xxXVm4QZQC/+jv+TR8q2Fy7TSxpQCCqX0glhoYiiHh2+QS2DFLw85CVMPClJNY7jaP0c NjUD0nq8827Q8YCgOXNCHlHO2UoQzN2XXt3CVSv678D2XiSPc7nmjA7osZAG4ZJDxX6jRayl 9C9mmbANVRMjEDHtupdna4P6/mNg+49IP4ZElz+0IRHOuO8rsJHAKXvj3q8wWmRkeWhHGKCO 5/XW1xz7fCsynwZ8U5YFQxdP80/rbeuhzXocpRfJDXe+ks3BGDajKPDGVq2M34lxo4IcPPg/ wyJJ6WRhGGt13lJ40aQIrzuWHB+/evnjMHG5DjxLaXv/4XSJT9q+CjRwWQaNWw+ZvSGFevvW DbYMnryvPsCkQ3iZiQaj81c9npAVW29MCOOHfCUj9vMp9pF/RoZKawchaV28SVTU/SOyJrFj h7UhRJU5j6claImRLjA+WgSJRlBIbQ2QcFIA1wK/fY8stv1+vQX5JNs0fUXO+cqHEgwr3z4J vxkt/os9dSMKAYSgtFlevqKlbvLp1Y/cXTsbWk1Av/X9ZMk/oWPNN8sgFJpZo6qx7F5LjX9F 3iH63hVB795auEe6rKxSUyuHfR5EBe5mvnu0BWY2Ps/tQ0UM9A+l4qFW0DwZ9vcNuRcGPuQn 8KfD42+AbU87+VtdGvsaDrRK0BjAGqKz4dLyyJLGQLNX1jORzlvgpT7P/kn0iKNmIMvcSl9x VT7d1suBAxyKpjpd6kMgVj8Kk+cl95yyfaeQwLMeo7X5+X41nfuvBwkzh+cf3GO1NmwrBAzr 3XujzNf0mHQng9ZmGV6iS4PjcqMzr/Tv9cGNsA3FosLSbZsvPGxHrScOIEveOBjp+2px3ejA CKMr/VV6k8hm9zux35AUkd3wUwjLhS+vcwdae/7JWi0KjYgwrEU5Ar9h7nhLJzpMaZ+NzUOL jCoKL0Si6PlzCIflMvyzPA8A2CJLg92UQT8LVEd0yG4Peeb033oWDBtS2MXgjCyWNlVjEINX SXes9xi7pVwGzbveEHEsbP7iHAAyut7g/gH07IgLqxuEYY5gk0rzuRu8FF7D356e8ax/TFqq UJSLtLxHrJG5jYk2go4FHuoXeosO4MnENRitPjVU3/j4MXd2jdzi4HR8KBUAcSKFAFtY6VFC OlA5F721I946Wfn8IHxSuE0SGNodZxmbSFgxRFCDP4dQAEUfNqicdJstT+YqqaPawxIQzngU u5mpGKWOzPJcyiFSHN9vgiVwKAmm9yF/DnFH/1ve0tnRxN5sC6J+eiowf3P3QPQHM9KjXtaa v3SpQcQBfJh+qVBWFHyyoDMpYVy1G9+X1B4XnOm7peXnv7xXqa+3lNZlQLhYpLPM88iGHoSa bSOREFFlzcDqB9GM12WMvZElRtKjtkN/2PU1RrBqBEwpK4PEgm8e655XU1oc6Xc8uXjsYgTx gamOof3WiOP6GaEyrZfFo2dgyMA52FA3s8sW/XAB2pae2XfitGTSF0z0HNxQXQssKUiX/PtR E1tXvGXX21T9nWgXQLdtbcNg30g686/kL2jQvSE/k7dcN6Ym8nq+ZhygHaX+GYXAckYpKyJa AZ/oh2qGqSmh2kYuUUqk7YchODgK2vNqVjS7rYiQQzwrCD3ZK6ciXH9lIEw9DGoI7kUaelTP LHSrHmk4gpYfHJK3itrt50BeYkMJY3A3pAuke168SKg2wLQPOJzb9Gcje64ovzwphhj2iTfy wTZSI3sod5N8WAILnjeA7nQKm4q7jvenqlRGf5hN/+AedSZpEqZAojYQMIx/eOnlQo7C2tBn Vjeh9p+7Nj8gzDki2CV6oJJOiq3mUoTy4sccq3PSY0V8pcU74JYbcNiBe6VP/GB0oGrQSJfQ eYxCsFw0jPhWhRk6BQ3/tD2mgVmCH6X1Wm6Sp/KcBrNS/gRXcMDolfYIgSE+RpOPw5CERl9m frRxvNYlvYMZ9theubDrAAobBEM4+jNakIGXdRNiDPXZ5iPqHcnkhxjFwsi3joyFJGP8oBGa SV7hUkcuy2TntYAMyTsvcQrzoAhw7Qto44JptAzt+fjjoS2B3ystNLKfcs4nl9TeOETeFHvy z1ritwBQLMr5wLqe5aZUczfYKl6kng4R9zsc3pNKwngJyXyPqsHoIK8rE+H9I2i+3WdRQADF 6KIDxz2dsSFQ4iXsIe/c9nmt8cV5zUm7xKfR+Di7dA/E92ybUpe2PmoulQLbZMvOAwnVUjhd yEegNM8ehZeDyb4lg65NqaS1ioQXYUiSNChpV1h+D2uMogGuK/wCgWMjTce8rfCvpzzpf3H3 vnpeZaAnqeZ/iA78b1G2tbfdDcHyWg44SwyzN5ZORlJ042CYif4WBRG0FY7lXdLda4bfJl6C +Jw0VMBJ463ZWRUseeQRThbw3lLRQhV5jlZU8oC8droDS2UqXvF2MkOU4fIM70I1Mp83jezH +2ecHZgYCCruE5VYp04smsBa3DBI+e8Ctfybc19VPHcXx/4sxriVUtlihrqhmXBI6Z65m21b YaaVi1I0CKWKpOYeVCGdOolgPO7wfmHzL52pwrRMABSN7yR41oYOupj58O5hJHGuHsUaSg0o 9w8PxOLbmFZu/CTEcTDd08Y4n7JaHm3RTjieLI3zW84S0rDQHNDakeF+HtbKITpIxydfPlRf LEYWnHSmob+qgm3EHrdL/M4wqeJFvN0Gw9XnLMAepra3WmTHL5raxW0SgvdBNRmR7fI8/4LI jXHCvvdpWUAIW3dPCDKIeziLBl8i4ylCy/OCiAptYd0ietUVLTYInZ7NehfiKHyaAUJ+cHcR 5EdxH0zeWQ23vfP/EgMvu67zgs8QkJIaPMuz7k+uf8YvWLkPpak9PKEgDB8lWx8mNBz0D3X/ 0Hwc5+TPjNGsQtA580r0MQ8E/SI8m+WebKyJ9ivvUT5nfq0Jk2voJim1gmETJhTfJ7fnaV3H 1frD5CNneyWbEjyK5DqJMTVK5PF0deIh+kvts7LSFVQEHD047Ir5DQ9XxHD/4JH5jR5sMhB4 fMgYVpdnsNa9WDG+WnPJCy0/HcjM6URMx19+4I5qiqRI5SamUUzL1OnAigAjNp/nqCtQAbIM 0UGxnZelWd7lHzIDqDN0HQkiXdTl8h9ymO/7K0mgnapwO6JbPAio5QsFWB8gxf3b0CEUOQLg WOwLc2uVVkksVSmWHJxrzVH7DOK7F6JGJjivhLf6RzkmSAWppXJxSlTpbHL+C/4tFgb0G20r uU3X6O+MqEr7qndUr8z7KXAOEEHptwkSlWrB4LNteByIORd8tbB7rYbYv0akj703CsEAOrie KcJ1Jk5K+1sSPCrSvSVBSkzQuBlCtAfUbnRikdc46F5bi8mWqIlwzbtqR1TeRVaMOkfOJ5OZ v9BoteI72ROJwa4j/2ZJ6lzebjfhgT5j7JuoirNoNK6DFlXup7WMRZ+XawJQTD6kGgmjK8Rp Fw++DPDUjMxKZpaT2r9KntiNDx+RqGNQlB6btWb6oLrvhk7swny/43J0tcDcDTuXhM+8LYUd NMRa/qaPX2Ni/CrMTzRo0xRg1UISjk7V04DWjVrUQlORjDyqHhRQD0Em7GuNUDtAfl12u+C8 KkiY/XVT+rpAw6sqE0YKSB1NN2vkQHDn12y/oiNs06urYodeLS4S/LduMIJOU1Cz9OkVlaE5 gmRxTIoWPNzr43blHRkcuHlG+/r16BgK3BRdQNX4bsYS7ZRoINc9qgg6VZFd6MqKc6qfkGsg 9FKCbLaUHNzhsF9k9LrkZrV4qDjl1BdabTiM44F5R6LXFiycaabE9lmgR4YfLaJb0a83MltP 5a9UuxPzEoDTsuaHe31LTQJBoN060zjncr7XTQb6CkI0FzrpHGoWIMhhAVOMI8pAwT0QzLht FqNMBQgf2PE1idolUNfmz3el8mwW4VmQS9X9DpCBx8yZSGQACMm0Q1VT8Whd1hlpGxak9FlF CteTpsaTW347BeZATjC/pcDtjOZd/p3uST5F/biVaWPNYzfkU73lKU8nLHFJwYu4RO8/2fHN z2LX88mIlbweihGA5GqTgi303KGB5AZJ2J/D6CWuguIsJulZS1+XOIUbdbnTVgGJw1tq58mS Ga+2b4MnMsZCTQiDCrm3Hu/yzP/Jft+b4SczLq9yGCIMqK5vys/l7RLRieZcq4sj21Vp2n4n GdOBRyHoZWxuO5KF9nfDMkBDGJTPq2NP6JbhUb27Z0fcNLUxPPNymScPti3SW98e0F6F8aOm c7gK18u19zBj0Sk+M6qFtgw5jnUgHiZwU517YV69OQEZFQf2ZYnnaJGYTYavAXvyT87phBZT JEkCvFBbiQmlT4sbQKuwILFbKWSE6i2OLzJpMdwFMTIc+/CypxjUFRxhkdvWF5ACaAYLMJEV OfghKY7FnDLf62b1TifV7QwIzghRdv1VRxt0e12pDH32P0m8jcvHAvunwfBaKMXrTvqE/yDW MKZvob8SRQKhCsb+Wora6KLmx5vXVK4BEAf92wNEJUWcUwE7Bj0sG3AJ/Rx8vsGVzElx89bX e5CPs26pOGrpKHWygwZmcY5AJdxQ/Ps/qmNOhhcibvBmF6Yd5rrydfEyDhEjaopc2yijrVFh IQzVFqheQWtF4gcK8ih22gxBZyxRhXjham4kSI4YD09vL+W/HBLUFBKvNnIuiE10vrqApg2x mH3Ud+21wqDaXa/C35lJkj1PHGi/TagUmxzzNGB2rt0OAPlA2blkEPGZu3SP5doOQOmDkPS5 0s6Q0vdFTdMBVTjpQBlS/U7mJCihXGtLOaQPlnbGofyfKDCjqCjSrWZTk/Fp/8Wgciyr/sIM wjy3tCnBEZg8gUuoo99BypXRA01m3DU5TanNT80Spigp44XKRX3YgRRH9t9eSW00GBqRZMHb lVBRiJH58IpGQyQSIWhz/DqcBqvQcr3KVT9KaM5mb5B0uNOj4v1BNqBSNiIlDqK6+CY3tWi7 ZvHtze/NTyy/0d2+QW1U1aGTA7//PVSt/aq2Ii1YNXxV7ud3M/BgeqXOMZGrAGxaYQrF/QEx DKGM/sDEvifXmyvFYN7QT9JnO0g9uU9Y0/e+4Z6ua7brNtjzgI5lp7u16k8J3piQe3c/O3OP rS+O5MEvUhNgQqxcuchwGEgaBuqsbTEeIe83oOpzV+gUIUp+KS/wvIDPwwFQlG3iPgW4RX1w pSloyF8IvwlL7Cz/TRb+f8w9vFOcLgLsRX4xF0zPF9OHI7H3HZXS9Dn64cFB+Oi+bLf5H0YF WEpgUHNwCXysLl6Dmqd6AY211kn3HZyMoOG/4INCRqajhyNwAbfE+Pp8qBdD2LIvfmLtkGnW kkQFh0O3Rqt3NxgdNwzBxMogGgYUi9c6E2ZAsnL/fdi4r3wz85tJAwV6MTapE+0ydWW597xm 1QQa/yeMMceP8nerPguO77WM3NPTaErsaEP+Oyi8Qks/5IPyY6dTTMLBXLHSohlqHg5obuMF OOVhZnlDr2f2z47iRmHbvHEZLnL7lqSpS12JWImP6xNZ+9HZBPDXmrV3Fjqa4QOkn4/gbEjj 0aiDPARXbPxWl8m/ZyP5gd5i+HIpuEicKTknlRpMCQC0ljYWsg43Z4bl68fLWY6k+szL1qjs K+6tOc9hvxHTaY+Q4Rl5OfayKBc3ioZ4rfilbKhs0V3s2P91xZFhr6Yr45uoUHl5MctTfMUx I/4Vj/do3eHPWmVDGel5zJO4nvVOGguLIFaCUlEZw5MOpWKBZv31g8i1E96UvRMXbLd9sEoQ mQvhjzPxZce3zRjBGzao92lFK3xReiESA1+9pIbwipu0eHBg88ByeMr1vxTy3cH3t8imt4bD ioth51Bj9gfyX2zrB0+iTFyFuUYKWCXPzzn44iyWaP9sDuytUHbpnO0sBgve6U2fIbYi/y8v 3W/pR0r5GTJvdXmHyLdIkfnDV5jVm63xtsH8baDYtTqeZoySbO45X38TKyFhluX17a1A0YHM S9x8vzplkzD57IqqyKjQ3qPP1D3IMA+iaI89d344DYmfakx5VhBD+ctwfi/g3eHX5S1ZImlk GPCsygdAU42Mshntjw2e/hK2YcAAiujjtZdAmbQoIwFy6cJir/QdQ0DRP7TA45CTylN5Ni9j L2l9/PmgjSq6PdmfTcUFcp1/AcMNWfnSeAx7msLsClquPS+7ifCjpEOb5MMewZyJ7uvzgzok jVxxA/9eaT8skSf7d7VL5y7fBGqIcFDqzdyKY+8A40i4/xJUrQQcoZdEWfqPxFHkAfbkxZT/ EsNV50PE6aSz4QlVe1s+7p4NEpnPpOK21qERQvxF+jvc0CHOIvIOcM/LNbj+1Rvjc6mBx/y0 sPIOr9VluXWRdy6kn21lO1oe7h2QfzWMyXaJkGt5Z1Y6agPUOxFnjQM1WPlYBbysc1kBD+fS MAGiK8QntYj2GA7TlDQw7RsC6/BySnRjNfUrptw8xkeD+7KPM0S5ht+khbITbJU/ab6a/N6R UuJOFcmUgwMQGtDCtmQsexCnluXiSctSrrhAZ0no6MwpHiWCsfIaXCxEU9J5coGaWyy4b6Wd DjIllEL1YuxfDE7BH86O4GahP9oDrLZjomP02UOaF0jAQ+Q+nFZ4NX/ZYGQmIbU5mvXyMekY PYr6mi385B25yGEb8Z4Q1aLWESOSU7B1CoXX4fMB9l+1T0t8suYDoBVgddVt+5wOOFf32Aoy ZfuuBjbeGj2p1ceKTo2K97B3EhMuZDcMZvsyC7+j7s+Nux46vw1FSBwpsDvyaBumOQMOQ0cF mQ7RAr3xD7hsQQ2WI3VwvJpD8/SnQ/Too4N0jcUFbmPfpEB3XXqWsXM1ice4K9Uts4D6rkv1 yrMe5pnDWLuUVyhWsoNPFtzIOmbHBbfSgdl32esbFXG4Aakg9rToeCcGNtMr4ug2Pw7f91vX wTQL9FMfeZbcigEB+jcX7A3OzERIQfFRvYWUPPLkRN6OmYMPMQgFNI+nhGqVDyeAmSID2qwJ 27LIkWgzSJVoHtQb5c+zOdxxU/9FGXKDZtTKilNHCVle4SXEr8gjLdlqrokKM62Of0tiUknx UZlPY7T9irjlsGOHFgvrmymGh62m1P6sFKduxRbkJfFYcNVmWgBTUY6MEXdAqoEdFub4HcRm PlrV6LBTpgPvukwLJD7ixPvpGzXu1xdN18lv+1o5nv4qkRZ8DzOVrlAT12gwxo1gqHGZrOeQ mgf9pMgqXHnpedx4wvO8B/OvfxpfVO65wIHsNemmdtrhGaR0FeTPvma/ZMoHew6GWC7azQMv tvvdtC556weeUuOD6/H57w+m4/8C0c9BtlY59+j+uQRbF1SemIJZXoeYpVHiD0wZCchSdxYr pbwDvXiCcwN8yF4dii5gKwJGCJPNfHeivo7cU6bQs5EJviSKTiHlANz466O6BEyKKpun1/FT mTV9mWbgluZFFWl6J0BVFa56vqxuKRm8mrUcsjZ0H1IZT3gCwgVz0QRpEZfQ+WbRsprXdMf0 hOJ4R+Kk2gLKI/VJ6NLwkmhG6SM1sD7F0c3+v58c1hE0fTS5bDvQSzowvYa3bCf6u3iq7ThE RzV5eg31EmrQFg6XqCkEqZ1msPMWCL7McLEqjzlMX1RXxbjRIFeDqwWuzLABIAjf+kx8hiFw UnSOt6YhUQiHqaB2yKLipfM+e6ZDnP7lRjFnjP/AZK+yjdx8g2fHK+hJvPTzu+e8PJjCSwzk 8wgJiQbRId4ylc+4t2Kq3IKd59OHeW3TH2Osp/5ICwBkFV3tXuDjZu3Ep8a7aJxGQwGYE0Ny 4MEmOBEWXQ3Ee00eGub4t2JQ9B7Y3oy4hs8jyMLQxjnDrI1Y5qr4uwF7NENObcehZ7a2a86e ecDg+PBELuFjUWFCOtLRHabi1747eWeIAXYZyeKZLAPzaDAjEoP99JfjJVBDwsYO7kT1P4Y+ qQBgIheaHn2K8zihSwRrJ+jyZI4ocsZdFXJBG/5gTrs+1JgaNWuFvPN8gqqs2pr9Ggv23Eeh dVDzN+1d/WuybzmYjDm0bu7V6o/9ksBYyHxaCaQUH6++R+JGU0OxcgbQV9QHfG67w40BDh6V M0S05PaR51UjakfDMzPeDY8iM1BivPPbq23/3uiS2gcisjfoo2KBAiYkJ7oHVBITrIUQzclm X1EuA1pkRdWzBrB7ygqjpql804K/cxRyiQEWIZjbXZtOw+QxQvcDd8zp+5/MOQxm10dbboHP OFhphCmrEebD1Cxmyd+2vUSBLg8AVUzKNnWp+6lQZ2yRJcfehCkUAOB/V3fKHYjrE4ty4in3 wA1piMARc0CO3a5OZAt5IYiJcWaqLclWgGgTltqKWUtfBJI3dfzG3+8SJC0m7xprVinAtYk2 0RXoBthCqJho1tHdh+OCm9nLed7JR7AjqASJNGeKEb6G638kwtndI8OsxgGpU58pA3pQLVtB JHxf1J+97eYnlyIjnDjWx37bIGXck/Hzbsw8WIlRRZPE0xYHc+bn8k8dkmVQR0zAukBRRVHl PUX0jB6FYd9Dbmh4LSR/eiifJCmqBYaVx+Kyo1xp5itvUFMWX1wkLl3wG4YdMzUOZBCWBOtH YrMtrF8cbjNE4MmFH7d9PwY1hciFJIJ7RN+i+LzFCMEZDfPm9Yr4VB84X5Lti2LYc3wtVe9z 8uaax7CXiWa6Orcywfnvjdnur33qmUiNpdKUe3sJaVL06B4yYmXNzZPoj0SnnYVGuVZikZRF hFAlR0/pHaCeBayaD0jnqI571vl7k4p/pnA+lxzMP1aUtmkf5KfJYkWeHAQPM+7plIjD1Axd UcbVEgUN03YC0WdcZJhLmd2vMW9yzWHeA1+yqvhmTc9XLjDc+lofKII5aVlPTlUccIl4NC9O IA4FU4/okQBoJCaEWu4oIObn4cQNPmcaT5Kbvd+IRvQWww9+LQVyqQ8f0dJK94EXins/19jw v8OmD90XD02tRE0eqX16yevWDFxRfyCrjJfVvCvTXFvbwuW4VRoDn1uB5DV4IvLwrX4421Dz 3IOEGmK07fqmgt8flgLGLikyjRsR7U6wRWOALvYzcQeWQIy07/z/5vFWLTTcAXe9Ki9N16OW TLR67Fm9Z4t6fXXG/kmCBp4o1tUtTegD82fIZ1WISUQlSAEdn0tzLCRzL7ITqZziZt79BB2c JHcw/7mueIVl74tJmn6p2MvwRc4lI/gwCUbNQY/lP7XeQQxKWSFhS8Bo+btJFAIbUMGxrX7N CVsWcr6kHhMGIKTUrlj/MV0OS86Wytsog/dgu/6ThZxSPUluXpa4ioErw37UZMLAI0nrqE6I JIjnMDaORFI+lkas40wNssoie+lmwSETC6BHghF9U732YacaWQLWFkDS3pzK/+AsYuwHFuuS 8crJDBtPghJLPoTRSlhuItOB1e+8O1IudnZIxTkscnONYj0LsMeGd626/n2NkY8Tq1Q9Sp4o 3NmCwTpZexobFdofpJ1wswDD3FzIN1m91eA9EbUcp9yBGKrkv1iSLd4n+zNlRb6CbDwDaz3u IwRnXQKwmtleyBOx0qa/rU/WuxKvOcZh7M2oR6lDGcqJYGzQVzuonWOEw8i4GxO77khd/J/P lVMkaJ69W4A9gqI2WSdcJdGAxOU7M3Wg4cbSIEmxnyhJvtDOIArZODq4bJeuVmp6w6I6yZ6N IFrTWNOQxKhPjWvjLjNa2HYKCSfip5mnPbdXW4XUu2lltuhBH/zwoC2uRaudtdJHYefl4YQ6 2MTJVGMlgJKdwuaYV4s8nkDZix2c/1WTrPGJNa0kxrLaQNswm6XAPTU+2Qne/LocQFNKjMv6 izJVKUJkpalhfyuRcoEmSJ7IoFSNeGq+cLQafXU+b7CH8HgEhcbID+Ez8hOql1kzQXZlMy41 tpkTRwztZFo0shk1M/nbIYmlGX3rSP/R7PdP4CpYZkryZdJmz+aVGLaC+cgi9DWzfWzvD8XR uxq3ySQ6qkb23t1rpGbTwgNcKgI3ESPPLnu6et6Ru5CUubMe4JtpfRna6ni80/oWZBwl1e+q GQTaYGCwevlXDZcKkuUVHneax4fCqYB6b4ShQNC6zFG85FNfAS/9FJ5nxquIlGRhzBYWIrAH 8UsScwmoO7WHYXb4D2fYlvwS1dz8WjiAFpHoVxacleUERjZqmLYfv3CQMhpAEJCQW/rUPjgc sNXvvN2ZYQ4YOpWw7cv2DKL9DpTLR6NUL84j6dr3wi78dMxegCdsCWaHnXKd3bzW2EsX7PZy UCUOij62UBL1m5HM+RXefbQFg2LbPUQEbqxy1sC8XEKQX7vo3xei6KZooblSj3CkL4B+MNkd oGlDqh9omtRCDEC3vB0Ydwe4CKmvccvhm0iF4T5uJveEf5OelvAuIFsMXBULIsX4P8amjef/ JuaKKzBtFqxcDg/4dkXhyT40vNfzvRRk0O2FxaNgeMPSVgXaN8ADKbsFmjwnsEddTj4hNYz2 7DuIBIG0blphc26jxBKT/M9zqRQbmLsTq2xtApFmYqDtq4aCFGwaOb8k/bOj3byX10cR1nJQ 98BKaJo70Ue04+d8qb37ROLGNVfNXyOLKWhAwDX+pB+6cZesb+stf8sk/09Lb1muy9t1xP8L sIX99orpZl1LNlKacpBcI0EbH0xbRvYFQoFnns1mme+sVJrU0647dhTvIwpAwbiC93eQn/dy sPuPd68gqncx+Ib7E1wn9nB9kfm4FBeH3O39kMmiS4OYE0l3AI4+6htbGKEDhAsTNY79yi9Z pmRSw5i5/Vc3SgZZST5kKdxZRm5tM3XzZEHweqb2TniuapK8gMLXHXKW7PCA/XS9gZpxVY60 xm8hSTXU3TkWqTRxJ8eV2PVClXxIrRH/n4ykBDsfjpWjzERt2XfbqedpUB5Tj9io3xHPUFhn 5KdOOa9TozAXuMxOwvfNW4akQW+AqNRATXLIVKmDM2uFTRsk/hPyLHhUaI0IClaHyMFnPc1z Ff+hQzgqiPD42tPbdyGo9JHURvILT24Q5iQzxlBafxk21lOhYlb8QPSAMy0O/EERyZRmx3Xr 1QEKWYZY44PXDFDH4GGC2sj8WvLiQKjc7HIVKNf9dd2J7qNPigzHmKZnsJxku4GpbjaRU2I9 0G2dowdSBrSpx77w7mTXMr1zFcsk7VYNHlG0ZONAacv3DnjXZ4CJhWKdQJkkOf345+VxDHg5 ViYRU8hA5mG+HX2NAAa7EmK4RRNmLvf1zAYD+T7bbXqaRRqZksTsvivyNOfmWYg/doK5U9m+ KpKLvdQjP36JJx1y9pmqkeUmChie9gI+TOPUdm2XenhHMW/8bs7JzJiL9KwX+n4uUFmATexl f7il5Wau5dlr0KXhtZ9QiGnVvSIIoP6hQIxs1MxrLtA0A5+YPo9KhEcrOf2jOjdnpwsA++pK kwdBC1s+wsDjGYzix0ijAA09Z4uIHDI+3pHbK3PeSyfsIxD/0u890zYkjcwTseJpVYI2v+u4 hvFfmqBykhVDho1gzygG2P/SBEbretYMjvm5Kjp5d0HoiV4EqLUwYESnlsDXaBPa78uZ0JXr /8UZHgdnHi14pGU3J1TvUH4TCZ+9IRKqwWiM0Jo7RJtm1bypKajN8iFZteVv/B86dbWxtqxA jKnvzRlrGu5yBxfKOOeLsp53whZqhX6YJ3RW5W9EF2rl7XnBYg4/9HGSvQmad4U/8MvuzTfg RHgP10uN7XrKMqSYRY0TDQIPKoVjusbOsFIIq+hLxlC+SH2hQzb3IfXEgZ40Q9oVcSQGd+Uc obWrGjAD5PuTxq0Fs1Y7SJuvEYDloAeoG0zuxu6mrnwys8oPBn/l/zMNJ9MzckpvNwvn6jOn L/w6FvZSYOq04KohJy1aMa0mr3BakwTsd6nWG49UO96XE9RCDgerCygj3skNd1FMtpp9ah9D zmuSd6rj7zVrJ6/rZFX37agTvt50bLnWJqNv6xEOSj0gz+TgT1v6atpYlkvGi0Y6iFMGQRPQ qxAvKp11apwCtkhZqZLgKgLShRQEdSYr//62ESuHecPcaXC0iJ4w8lJy8n1Rbxv54Nb/32jL d2SvVnmk2An4rGsgvebCXsORNJY5BSydFZth+Bz6Q+gg8PGO6UpffUpA7YY0xBhbn5Gj4YPT xoFe0SuoCIo0kjwFImDAwc90tJ1kD670zXpat8ZF+YK46/31DcQw9V+LUJP7yfoEE4dwAqkm rmxyarENHb8Jpa5fAB0iI4Aj/NsjVFEyI+q5tur/8a03DyaJ0DiFDR2iAPRcBgUBzxh0XhJZ eRKj1n/WLngZPughYvLQBy4V82HczjgilZatcyZ4ncj0Dm4dWlpP77gc5LShIgggci+4lkQT XA3K24eNEr4/8QMe5lyoSewuNWGI1CYlCJ9DPi1M48PZiNF0OpXAl8lHUQH214p2BliZmNU9 J3ahmAFTB5F8FTWGFGpIc5lP3QghYRjpzG/cOJ7iL5Bc4k9CpnI9A1jAQHqAmH9GEptEjWUN QZR7hADUm+2k2hkFnK/MRD0muFra8/ojA7v5aWpCnwdFG9ZyAw3zlJg2p3cBtUV4f68KiySG v9M53RJN16GHqhy5qoyDWzZ9AUJfovXrdCReGGViYStJp2J18xNqSe7B3sQ4gf0BLVE6U9xu syIewkZYep3bkAHQPvZL6+FjMSx5CC2X/OUKeq3KZEs5fy7wdIJTUzHjxPK19+YHkx6tYbY+ 4a7d/TAE029mNmOYaljSIF7HQEY84ZMrlmMxD0qfmsufbe95gMnfpxb6DJrKe7viCunf29WS IEeP4xjhEU1vy4QSALur6QVmN7HZu/wTFQkxfyk3RrmtMf2fU12BoXkNzG3VOrVMoBJUk3bX JdFo1r0IXD333kzMSWkJkzpZJpvPkuXbiaTrE9amAxh1/h69v9Ht1jHnpf7A8Fk1jWvbXCCE Lp+w1utWlPkbFyHoQIyQ/mNvELDNrFKnek5jFxWJ76NB/AU0L4lKEaWGcO4RwAiEePKba6Lw Qdd9SvTDSfyX8KjLzQ17SLdy0muNPKsZv6Mrx+fEYjnZsqbVw43eBE03LnuMM1PlNZc6UVvU MdKC10rX1FWR5bDcbWhY3fA0IJDghA9M444/glwwdYw7qvP/96/BF6a3PI7pMhH0xl/roLhc feANYGDsoP2AlYNMWJuabhEfvpVWQ0hjb0jq8wuEu88fDz4owX3Wi0bCdh0G/PcALVERvVlU Tny2elD1WXxRJzTZ9v21KyMATuwoK9TKOXWjsJFc+DvAlc2hK21dhe6capilDMf6Ykm0twKX jTTGZPJ0RZs60Pv4rZeWo8X82lSntx2Tg+GEVWO8Y0la5t4B1B+YqSNrrVKpgxxMCBpPwPkL Bgf6GC3XuL1Pw4SZtUGBRVVm1uGXj2E5nFSU+j5SOAHpeXbq2khfrfBzU+4Jsn3tWljyhT+W k4CRu5TMSinHfUMwLlHHcwDCvpbc/065OhkEtM3MsgiOqIFCXUZvB6oEGFcxT3P5+RnATjSx jF4+fEUrN6QYssEmHkiwFswslzS1Lurkpr7CNsJOKeZIRVXrCFg2T1Yj4ceS3E+O9hvRz7nw TQ9o5aND8tz6ot3ph/xZEN07iNm+QXAQSKk4ByL9mlRB3+vvaI0JlAbvJ/LlwsQeN0o/SmDI Zev6DYh/qagW8Lrk48vUD8vTdRKPQM1fXGahNHeUsj8DR4HsUlFnKNULmC7OcJyCoi9sLXUJ oeh6EOL6GckhCvwQM+izdI7AMWRmaS1iahJ5JP+JLGPX7MaV7cpKi7xKh+pdlCmeMzsGgoj0 iW2St8WpSBlC8Su7REzaGiQhCwZemN94tiY+1ly0Lb9wUW8Gkjlg83dCrzIpi+ELl/66yIPG PrgXtc+Wxv+rRdvD38I29WqjNQNNI/w50E4+2RddhL9iMeIdIo1AMSafGD8xvFpLYgH+DNkx 31dL9ueka4zMFtLZ52I8fKHDplyHGOaw6EUgoS53dUCFf9wmHwJaMfIVkQHOX7sJTGc6J23b xss/ifvw73g5QAy89WxcbXvLMV8gQFI7VZi8O2sONaZ383FmW3kBcYtxZe4Rpp8gEo/j7eQB jSC2esAbVCudQgHoy3nALrscoUfj0Z99gLarVBg4UoXJgSovQSaGgNrAGg886EybYXCTQsAD rrprAmlkrkMpwrbWmi+Wod6grH4PZg+aGZk0y2wsOqlZCZhr/ZgrPaBSNkPmK21se9Pw1tb2 u6l0AGMxAUNohj3qbBKQ+znCjWVp2jMIRQgXveWy7nFDiIdPR7kVJmPvHXoKeoBwgnGMSZoN h9ZaZtnXeNJRHcaJ0hjl//eV/dTOHQuKEEaxwPjeyPCHVnjHFp4A7ZbYrqBWjv7EpX/zNRgh ZhMJlJImsVyDjJKHdFMkqP1OuY6X3NEZ2+EIHTPqxYccyFfNKpqdqzlK4eKe6vn8HVTjR6qR PLhXQP3phBZxEznG+niZjf1wgmN+hnS5Je4fYZ90/hASF5yc6XqkQ4uLWVCZ2BV8cjm+4s4K HjUTn6IQc8tdNBRyCbSPI7lAF33VL29dKOgEWaM+q17aQ5Eq7tH6cNMBcRWp+RgZIeuDg2Gi opyiJ7j/58k5/Z68jtap2Bhf8zJRSdguUhKzcHXZn0PMzUMbJOZzmdR1a4h8RjPSl44K4y77 HTxh2tC47hYNGhnW6x62pS/NsZMbwtAMKDEqmwGeI14LPHXnwGb8tG6ujeH4RlWOVd3JlZIh os+RB/KTBVcMLgzDrtwA+E6gN1933LZZ68J3p3CfutW9sbeO+GdkdI4tky7P0WX9bLlrbiy1 N4rBnWWHuLMLQVVQIpXCGaukrPIbLqkQQBbDN3+3Ig46wfLwiaRvE8YtMcIg9varJySsUzSS TUNLlF1Rn2NTd7napiF9y0MicPY4VKwhEj1eVcJ8/3T5l9UDaRzxde9/vzBR1oumpWoHz7kM TqggnaSLxLlePp/aEwL7/wANBxTbgTlQgAIN9CDU2i5Ht05wvzh+xJ/icxZRFCZRhzvagwv3 uYfXXzLtHs+1YK2YBsgI6bQQod/Ju5rFp8ZLE7qmFxz47TGCl7Oy9SOMj8s549wyAWxcLyX8 HhvaUcQ7/PDE7FfQowNvFP4to6t30S3kLK1VcAcxyO8buAwj2vMm7Bq0wznzBQ84+VXV33LV j37+CWozD/4CtV4bCwfucvXh8pJh8bdIlD6Nq7uwEDmaKWQk6XMormdTe1RZpMWTBW4KzXpy tK2NpsJh84M4eO/+YfxviOf9K4j2jaq2UPBRcXWJmwnxdWJeNc8hFbavS34vQPTlKdhiLbbZ 1OhMR6ASU3j4Y0Ui0+5jQDyIYsC/BM2B5Br11qFiZU1k1JxDGpwmAuCbeyEWKhUyO2WDh05d B0FI+wmDr6s1NNc91YlKcvHIq1549G4FR5v8KvkmLq8s+JtlWu28oZDfVEKtYydAtiswVG1n F1oQBAJnPCjxZfALcxhbN3l76q89bI/+t/skIUwKdto72LaoZ4KBAxw5lnzGXAb+uDNHuNH1 PxmsqZowzZPuY1cDu3ja5JHnyc6P9ELQVToGBE6tuD8brq0NSuvcbOFN8lpfFoVL9dP2IaZr keaJ0jDTuBiOQzh7+JkOB9MSRw4Vgp/kfgOj65U0lczZsQh6bvkrDzngp9n4R/fcFBb0CFET a+7z91eyIbUEZJY4c+IU1nGtTGwBfzVnomvdGubMjxBNKxWoMuIvAUMsWDsMgQ7CjeBPNBoz idxigiqGM416IKW6TMAtyNGxLlv0R5g+EmcOwyfX43e+mhDfu6p+YrSGV+x0ybGwzoq932iF QEUz5C3qAFOBDbjQ+YoDvfftsgkwPuL3/sqWtKwTWVSXsaTam0ll/LDDb1vHSyaMUorENSMg S4YT+OO4HNPte4htdGK557+wdQf6bx9JfnJmYqI73NaFlw2fazeM8svK8P3hWWHbNU+nYQja o64aJnasMvIbaQUTe+9aq5HFxI0O12YM2mvsg+DaL+BscJB/3cSNYeL5orWjVXmcUwz4WXBc svJcyDmaoaNM2u3sqOTK7JvzwTsqhtxXIHXfEMHSHzOYBjo+CoOFrRJTjS9lanum5M08EU24 rv58jFmS9WkRuvqrvlZHN1PHM30g0X6VBtyDwb2kHjg7PAF5wuaRrzE+SPqYBMbnZ+QwXRN7 td66Gm3OqIba9X27KoUiL7trpDAE5P8Q2ux8PL091eUyaMNnk1akTNl86KdUrmoUUwWfoLfC CCkYQenbqXV6WDv1gOmJ+GcAGOY7giSSd5L8eACHRBx9o+kGvkvCzeZ3H3NZRZnwuIRuLMYb KOrMHw7m33+TaZsroy3GYByTQ49XoSzKlSpFc27eiZ6u1Av5GOuHCFtByz9nWQuzMwGkGFH9 nx/FMXs+yLD8eM1X4T5aV6+OqLzNXqAE7TYbglqljm0FjLQd2ZDrnUZP4BHKme+nz3Qfu8R0 DcO8Q+Rkpjxkk2lGEBmZkojfDOmZXbs6teeMLc2OjDBZsRFsPHnLpLgon9noewWstbmm/WI4 Qo+msKSmmXAm8q8OzrHaOnaHcfh3ZxaOIP9bDr327Ex4VLNYgoPjSnGUR6FjylFz/JunR9E8 mNUVLc0BwQV7CgekA+Aqb+fmin6b7QXOry4JapnxmaYIDKx0HcmjMd9wCba9JFDs3HWWYzgV CpToULrj5ScvlZ7ySkUYKeKk1JggOvrgGWmvcKPPedBd917aDfVAwtqrFR1VimOu9xulsF83 LYRc8KuYZ72qegCLDoIfQCMNs3el9/xfX64qNKKligFGbDphUGn6h6nXBOVXrUng0jAU0YsP 72nxjeMgYWdGtU+qU7T47YNx9FlklRD+KRvnFztCL98YaJk522mi3onYN0cI4NqmMZ2rL+hm DXXkZzKpIqLjlYlwSuz9QpV/Txfvn7EGlsfNqZ/+5lko99lvrnIUhswcICk3x1WcLztWn7dB n/xsaDGDjRSt304k/T351opl8Iwk3igeYLU7fSVP5yAE8DdusN06kzB/2NjWVlTsn2ZlVxv5 EnDkOdTEp6lBU4Y8Sie1BkMf92WrBbEC/4Gg6V9D5mq3Rj6Obx4QmJ1FsQKOQYx/CHPSdGTk XDQ960TmIukvl+SyJP1ktUdvOLM6hPve3gbW2YH8LwNj8bs5k71iqmHuwr4R8j2LuEtaodj6 cKFE8AzqSP0nE9mwG9RYKNyw4ElTeRJmqmlyF1HTsV3s639aEWeasly+ChV+kSyOkm+T76ig kojvqxitun1WJBu2z5wH2eU9TNzztP8QhA3zYdlDhU7Koah6aTCyoVRKGImcbkvFTsHH6QVX CYwo0tyFVUlpeeR21L8gP1BkmahdIwBSVVGGyp3gMz9IsXnGJhJOsEquXYfLeV3io3NdBJxB 9FqaWTdk96dCB6WwgwAniB31b0XdVzGR0F0RWjo59JDj2EIZTxqn54wLngfLTWoGyF/yJTwn rwB7k+LjKiVk1z/UAeSYiUZKOoVbZsyKxixuQwrzdtHDSrdI63tJBekzJLV6lg/lKe8qpvGL RzAULsbaWziOn5hxkhH8DAGT8s3cQVjMkTDD3n5UnUvjd4lIIHEAibsNBzMjHcdTKZ9A2vSQ 6gkapUTwqJUgpkLD8k7cPCIch/jKlqSZtHMC/ot2IhXtBh5p/dvS0MciW10uk5pfRGXi8Sfu zW/AxEoI74ZcqU4fo6Nj+kXtHcLh2viDGR9tKxAVSYFhebpXCE/PStibvBrWg1P8Uh86uBTH h4qQNNJLYBbb0G9jaN8fLw6/LbEyQhaJlpxOhEpdGdRYmBcVM+zQ+/6KkKx1NeaWMcFStoal dVBKhIZ9Im6L2Iy7bIhyqNVPtJmMBNFmqzWiUL0RNg00EfQWtNWBosFXj/RzequnR2vCxVs1 iuQ9MuWQLjWTNq5ZjeW4KWzLlk2vXBDi8CR+fbks2p3i8TgvqX/ND3GWFTToUQp9A6BvANO5 VJ/pDcZRutS1uNuyGXscIAG69wI+VtgjSoAqmoUm1VUwlwO3Ts1EoZXfI3UXFEHZIC69UlZu iOXvvpnlTZ5WflYEMfAlMj1/QPWd1dItF7HVKnNDTbK7IKzqnID35h75TQgsd+c8oNIzalW4 qcCrL87VwLZ9S+hnhISEfwKeQPtNPZlDd5hpq7gSsKZdInk0+ZI4DQ9LBPLIDxp0dw70Jc0y 24hycxVC3UnXatkd/SEKty/RKfbXVtCBxzAe6cr+/zO5cNUH3Qb9O2YJdsnUHH8GNBwhuxwH YqJjT99c+S9fy2wIT6YgPI+CExxP5+BnDQrssodbSgp8B0XHFrHIjIP4MITw9aV7jekgu9PM Ejzm5p3euyojRd97nRLuvLRxNSVthEk29ZJYcdf0t3x2XBP3qAsdTvqFzVYyVSlBvLbujPqo APmjZJu0vIBAMDEiaJYpzm8IDcOSLnc20BPmmz55hS10arF6iruFOGOJeg/ImyBgkqBOJRwP RZ97jrefFkaSQT/FBgioesCaPewwdNfT55ph+DKs6uzBsZ568VMHBzByLp7ZckIELtMZ8FGq nTGyIUI7JDuWyO5v+dRwr3IAGNXiE5Z4ZW6Yvd1r6Q44Csz8KKQxSp0Q+CNGye6h7FXa8foP If635gPa6ykQ8Y6UoH5koQghKUZvgiP+wMOcenJeukdB7taBVPzHlPPG22p7ifHDaKcfQXbH FTULfsAIRuhKpTFyouMMCGnnrloUClFmDekhXUP95KHVfY4RQ16qohkq+YPJoItps1qF9NPp SN/lMFh7EoERpaeoi9pMZy5ilBrQCRqmMjf845L8nOkdR2HGO5/FHUxP97EnOFjaKiJbIFxM /eiIWHs+m1BoGRglyILwuDoze+TUpCblTAskLnz7irgkEKsnY16O8ob/0dwYdxXntrNkJXi8 yF/JywDpNmHeMe0AwqavxFStpRb5ZauS/td5vdM1oQ8nVgU+t4kAWc7yc10qIrneUlcsq4/w lJx0K3qVjIfZ7s1V5P+GlOwsU06U5efKKFJ5mJKWmEy1wsJquthFIt87AIK3mRXIQw66n+Jx Qx6uROrPlkHhPkx7n0FXBVnCSQzQp0+wgpA107q0mErObhVXdpaxVifTg9pn12igHWy+2c4c otxYD2gjVVANRoh8nGs4c+lIBG4aM9pK5uaNbPtl9rhfaXOQVtNtBkCf/0Dr1sfooGKTSbj0 0dTNyJSDXkQokLFuVXmk3zgnYI2XznnxwF6nXnbOF2sf9Aun9zXgJ85a8vtsYlKxqGxIov43 MvqE6Iuwpmz+VNxQVQQ9zFMjK1c2pbSttSe9Fk9X44g4BxSFGnQQutzx00kkd7AEtbzUEZ0y sT7ZBSp4RKwJB44mGKd0OrUqV06TZje2WWOE38qhOxiWWPbcZSbOhMWM+S3d497VmDCxGNIb LQgqEvW06rZOMQLrEKqNw8BHMk6qdcHUJ/+/HI6GoosivNgrdHahaT9oyBEHg98fcHEl/fHs QxXx1rfWkJUKTXLNVx03+vhva1LIX6U+3rSDM2lVbfMXHFtFKbDwUDZ6ZGuPXKwUAB/mqDEV xPwMcE+HroOeNYnxQJgSDyPa05wmbMJPPpG6N77k2u9ROCMGAKsI/K/0ku5Z9sM0AARegwhu tNTBNfdbNRMQTXdwporIYgSg6sGvlOp7ealElGzuY0T2JKFVfERxYkXCrW/j4UFLmXhnkrYC WCAQ5JrfG7vUQcyThNHAo1EzqHHx8dM+cVqnCgsKE3sF9qyBgXYeyYx4dqZ73GgL2M8s4+wQ +ziJr4e641FpJzO8inlhnWE2JYqBhAMNn8r3erpwBuMrJkZKrlTrvC+6vQpqHOVrqTXRbaqz kgzNWGvY8UbgdWdTr9yxQyfz9/7C9ElHVS0JAcwvl8ku0s8yw7GED9PowhIHKNjgkub5xWX/ USYihsW1EGpZncS0d19sKbxJRc7lxuLSoKgKJI1FX16oSYcg404z/M5OMkcWDX+PO9+yvlRh ZnKOdWSD8146h+BOlN9G33UcBqnrKOUXSpc/cnujcF5UOuf88MkDKCMlqhW9cxorzVLI63px DjQwAOhQc7Nco22Nmxycf7Yt63A+Eq58OkFZsJhhM+gy8Auay0R8iUGeXV+pinjw5TJ7rs86 VSjeQEiZCZXAwOMPnlviFgCCMAK+34VrZk4UeAEm+UDgoYI1MVcmMKWJxqcvmzJ653isLDPs exdXXSieKRgkkvUl7SJpCBGbS8FLnEQ3hCI5RMmO8DgXW/oNA1yGTOfHnhZsrRWzC9Dakzfs f+w1Nspw846qOJBPbmItwg1C8uUyjEQn8npMyaWUmZlTPIBS4jt65V/mnAX4SYK+sAlTPTa3 tDLgnlnsCjOIXEVHcnfNfaDTeLKgFquocuqESn7v5EzV0tFxRZ62WGiIz7kcldEYzg80jBs8 jNsmzxRXMfIkSjoyBJmh5ITLA3jz3l30cpj34Wc0xIFvQTRBlCxMgfgnj8dD9gmuJIOt6wlU cAXqQruebU1qDhRzu3lzXxAk1Jpu5ugA2Nl3mYVY+xLiZZqz//rYYqnW/FxS3hIfOufjVCcc gwJoRslLI4567OPCNxj3vSJY+xu1a/C9y+ej8cHKtxWjUJGLk91P3kb1qFvgr+GriMXcyZYD ZEYJS/mNkiWVXbbk4PFvpAbyxHgXtUya4VnJ8pilcPscmeroZISrt6acFbQI2qzeX8nQIYW4 zJe7IzO+yxDjLefZL/NZ78R68BYij5pxskHssP3MmMN93FKkbY70vskBXJRC2LFXuxUNzkEt d07MaAdvGLGopC+gyJy2LtM5IgeQpizn4RL7mxxjfvFNYmljoeYYNkvVdZkRfLlGv2CFQTCv RszrsqTb0T93OYM3eoS8yqepd627UdB3OcfGJQlzovAUUzuwsTF5xgufvEY2zxdtAkat0IyT PAFCIlS3v5741zAZfnKYMWKidiVgsHZQVpXh5bxllDRsfm9H93qaq3AWK5gX3PRsgDwXD/yq 5cLMK1qSMFA7DGmHJ/wwisOC9BBW39YdMtH2CHB+Yq1kTeMglRyrhpEtM8TK4s+Ih0bep9/T /vCEk7Nl1GOVNFsXvzk7PphIH3Mice39N8aZL66LXZHz+3/OQbWWVzOlnAsTcdaQZQz3EPOx zr5XbqBblM9udRfUo7+hNwMANFU3vIGG/zRSxaU0ErauTguhsVALrbAFk7jhJpT4bLa0nv8V a3YMI6aJeFlpgTUBpRyf8pkfhtScP+eoI3Ogu6MSEJH+xPLOSU6tTE90nHIalwQfpmj/xXyu 1JLHnXW4AkuzKtsSKcx+HAHiIMx45FI5n+3a09jnptE2Tbsp5b0hVpa2hmNOcR/NKtQVri1+ V5Oc9U6QWtCR5p9jZkKVtujjO9fIxWrpH/UCAAg54cs8rH3ABA5v8RSoDVpUKHd0qdutNkGQ GQPnsfxubL0c/O1my8GbSIXbxdNNTNZ9B4NT1noQmOidlAqTAA/2DTxmcSUza2QSLK/nhptY RZiK7zggdwqXYFk8toKQIUPY1P7VhpYRG9eqgJdoaJn9FqCVN+IgHd2MwfeXjmYL9lchMJEd LllXQ97ImOm/1WyenbUeElrbx1tAcrJJTM72TursCnEYRBQxUl41hAspJ1npO8J/s7mPfrlc 0jGXxRr2CYogN+nEM3/H7+mO88euG2Gq8zKgNoj8R5Z61JFY8/XKSacDWgW1lf3J3OrSdmJK 5SeP+g1kFobkw6LviR5Wi7vLlfp3ur+pqoHyoy9HAJN6Hz91RMmOfEPNusN1Ot8R4P4Vckcs h3iHJXs8VHMOyZK1uAEr/PEAe7uDyJBBKcuVwyPlfpl8Dj07fXUoT3+3e2xDN+x0PphkHjeb Nb9947x9x/28Hm6AjyqaKB2o0E8TzUatx4zDVrC/cSi8vEFTV1lH16W/W8ZlnvqdwnfTwM70 evtfVDVGTvQQLM4753w5/jG4g0KH6d9EteCldp2OslH8dpht2YQI2bSwJV3uUFtpZ/E+UcMm d5Rbn+svdDnxt2WTz0i2eF8WfbsSSYiH/lTM97L5VaRfuyCDMs8FBKbDHu8x5Wur5e+aexYy 5pKiwVzDZQi1igv0W+dhmcyr2yC54MvCtMxZCZx1/mlmjZ4ntNO1qGdRHCUSBth6OTETOkTR CMelQIH1wUVxG7+krj4SFJ9iwZbkT0PdmYq399PLRl+dG3PZTsIBb7rkFUeZl5XNeSa/GxBW pcHMq6hRPUKJjSUn82d86RtecpUT1oeDrOj5mXUPZSz1NYmxAhxm/6QSoDyKSMiP5zDJMoOl K8DfWqOMDA0WLLJWNda/93dqGTqvplyaxtjwSlAigiFl7VUqxEyofWQxpoGdUkJ6UBqr0lbD 3eJQRu6kiiiUMMXjUdEJdxbLQBFmN2NIu8mCkXGyRdOTykQt5fpVCjdYQ5fIhCdv10sZgT9k lwx14EaBnHTx/soL/2lxEO5VGOn/x4N+R2YmlnKKFW4HkcgAPuam+6rzqL69bWWKjNEsdOvm vZjA1N2AcACjPULUVluv7OF+JIJ1iK/cQmdkTLpRrMLcUncoeHrI9Gj0BlWvaCkAdHuti6Eu oGAQCCKiajkFlxZISi+wR4YZYBfXxoh1VpRLAKVwKGctYDnp4hSOL2NaMK9n6m6U1LMERRdA RVX3dItd5T1aCiKz+UUAoRhDUULGZrOyq/M6aWCzVSp5iiuUSCw5renTsE4A7gOGmSRZ3kKT +n3zPG52QB9Th8uSElcfixF9YIBL3oFUoIftJOogpxteSqjeznsC91QAqBJqbsZeaL8N0Pkk VEnPVDhOiG/HniDwKGHGs5JluG7J7sWnnAKGLZJVtC8/VlLL1eX3GhnUk9CZMSSLrA4NWDpX Rcj/LyN2kP+zQ0qT3Hn2kD83qpGbEvj+hk8eStKh6ch47bkAzLwjaUEDtsJM/4Wm5/y1UWBF 2cRDSXN2wb7YaXNixW/03jbkg/0gFhSuXFcUl53WOnfPFsWlmv6WY7QxHtAyqCvqkPz2C6k+ 6nbU30FobQD+zRceH9srgGwDbfmUF4HUIz1f3GMNjOjfq1iU0vEQ9p7aXmZy4yCDTB1Tsp8K k48duTY8BTCyyl9ysFNZxTIKiI/kh5dBOKuQd1eZbGeTenfEIi+2cbS8liU8gEuMfYTG9P6F Ey03vxc8PqN0kVy72mEOaTBzIuKTLM94l56AK7OrfgKJWkwl5wm2hkT7ylPjvDouLCbZ1pJl q+isLvS+o6IGYDuMsAiNPC8cSio06V0BpfSgY1IImZrTBuUNm2mNJtRfdnEQKfdhIZ8a7AV+ 2UaMnXzod4yc9TR9mbePsOJk4iiKSjr0SWIH9iOF8bz03e0CbKqpjgY0YXjsBmID/aQNf0uS Fq7ouunvFb2iIgPNvIH7AE91om3WCHCnHfEvV7GYtaVJpLLc0wpDJ4UCS/XyZh4qweM3Hrkr K0+6PDCxzV774xEqrNv576WxBy83KBoLxNY1nUWSi74af/nJiSYnNDYbRrCvHTe01hCzHhgP qkuBL0XtDqmB3r8/1DgilBPAEeCIIJC1nmljKk3axD3RuG8Ggd3jgUrTykjl+yKSFE5WDaxY xq77CeLYSm1prQ/i9lv3mpxrN8ZHSH9KnKvm7pATFM/5x6pF8nbUsx11PIM0eEKW77yIWiI8 lRgMHXGR2L6ZATMEjEFikfmWs4db12FSnGe6uj5ud5EBZa+UmmT1GKcOJCtSFC8cI2YxI7B4 QU7o6QYfhxOLoV3YSNB3FSvtsOwS57YG/aSQIXUYUy8lBk1hptZyim0lUuKRlAZ/iT5e3I3x raf0idJaUHInIPFvMAu+jZPE+RKUUo3UwBGAi3tftnUXSGUN2PovuFg4pptnpj7SFfBolgwf pA9qkbLTngffdL5pAZPnIp/5w26PsJevlm+DDZogZJgXSx2dvh36JgdLYPJyTp8rjme6Ohbk kok7Y8ZgHSvn3LYic0uI+SjvzZfE5DxamjL4T/qhp+AoPLl8sL49QICouiZsSwLeUZtuxuYf HrOYPWZMWh91q9GuZg+LV7jiId8/96TAUYLNxilTZZYGc4rOig+6Ap4v9x9gkbp2IemiH1tA rqVDjaulfWSAyeeVcAPWeO6raln4qJYH4pW7dHX8vlI9J8olL/7fR8BV1z3Q5XWos+hriv1k 4gkqPPKG5xB6Lkou75doMnWTP8ThqRn5TFqJbgtOJUPM2D52ywEeoOQ5B6Mcf4mGubBxysfF x91nHM81gsfkjGM58hs7ErdPS7So6gS3Z2dWK5xA4kjt3nZBWO0+C6v3aWTgWyt/G7w6tFME iVrPC4CEV2sy3LCPiM0jQb0ZBWb19n8WIGpUdoQR4tBwDt7ELPJrvWIeJwns/BCeiOwKqUJg F9tiveYzFXpuM5hF8CO9PhT76yY4Y0dsP8vnjXUAbyK2m/rvECt3IuA3LJEUCGgJIU9N5deq fQzHg4yNRbJCsA/ouk8wieEdPvY8BRPgaFrxHMsUxRoQ59QCHc55Ek7rvZ/WHpdj5TMh0FmN Wz6rHlg3VaApoUY8FAwE4qTPbsSU5zhdakb17V6RytP8ps9AFb9egvgtk1JIOoDNqJ2VQply 7pI3cTtfGyC9wZSFRKYyBxlNO/W+d5ZxlEVXhmyYgy9k5hGmFEm8g8fL0YF9MTLaEk4jVWFN ertHxFSUmDN7/YsbKkSjsebS+U0DHUNzkDKAAL2wjsbncdBkVWg/l+N6J0PY6Fiw/hKNLEd+ J2NYgrONRx400qEdu5GJNIcpeSsxEwDSGWfkrrGs4KL0eVcqzq/5mGsSLLkg7QYnPgx3wRzC T90GeUFJEDWeTBFHTPtmj0ayVwngD6bkFAqcRUWMYeCJ545kfP3deImxb3msdpjZn5puHAwc +TlnMZ6wK7IGFgKnK9TeK5lXS0GLa7Hopgbc2WXuL5xz+XEiH1jxsxXALalK8Kt3aFCzWS5i JIx460gwq3DHGA6GyUELRQAZLm/Ra09wo598Lj5K0aG5MUvFpRS1Tq3IjyBEVgfX17yV2+Ql jkFtDCjGUE5XXsG9RhXHMa8KGy/dOZCkdj4mHGzTo47n0eVpzkBjc9oQn6JCed8eprTFeXHM LVDMcNwZNOqwig0nvNFpvxBOcAddQg50Xg60G+h/ux4rBbG3cto3nQAQBU5Ry1xdijixRdDE fwsGy8D5oOUFd5MNVRnKbz64K2Ue5Ic+URxTPAEykL/yznZ7JaMe+mLZ0risQ1N29eLOTBYW huLHJtMSC9i3cl3ilWrAdY3rjMlv6T2WaKWRG/DoaVF/6i60qGTm4vHfm5sQ2pkmhmjvMt3h YIzfi05YEn+sFIBIJILmD507ESzcU/wMibo+UJdXJoUIVtAFLl6R7UZj67rCCn8rf6CZ1/gE paW3V7jtqhioXP/eKT75mpRCxFLr0ny7WB5tvOUgKl2CpFI/bdfnqFZJS0Bgv2NFW7r5V/Rm ifzh40QxGGlrK27Ywpq0DwwcIOUCHLw3+glwJFJYLgwKtuRg/Bqh8t62dYst/GOzOpg7Kh/M T6AxW2CG0uDermukg8Pi0C8geJHICsDaQc8k2zx0b/kcrORoW/S6TPOFlM2EODsv7ljur1Qi R6t7sT1681Q7FrlTjPocZOLHjAeOTMPP2LOleZ6KpTzpEKCHfo8b8pLq0l9y5maGjEcdheG3 NMn1m2VXT0iTE8syiikC4sxsE7tyl5gkuvWqHVU2+1hOWQ9U6/RYx5Kmw/75Tr5ad+GjccVr m4CLN13mBjTAxoeGXM9VanppOFThtqfW6Pia6oSQY0s2BZeKZbpgM0kqWU4/IZEBbGseM6Mn ZJN3wvEOErbOeMRN8Rc4yUebnKK1IRNGBxvOOa78sy7o9lEQm7wn/6tWUsykJCNWNtsvZTvW x6uVZWaAqW2QlOM5O3iSmyl36lFM0oo+I3FKmzoQ+e4igB3JMZ+CjWVEQ8bYR6yCCe/E+F8U SqOCLHvlk/SwlwiI5Xkrb1znUA4cwPA/tJu4zhOMDUU4LrgulaTYSbGTDwvfJdkXVmqlS+Cg 11FKspAHEQTnjljZcAhBHidLNifpx12KHL31/epbm7PP84tgmBcrFugOtRi5JZsvzrNoGinC sjpHalC9S5G9d59hZZZ6asUFZMZ5zc2HTKhB/qcDGpTp8uHz8ZX7u+yocrnpBI/E2VcCex+e F/9JlqqztcKk8PNhBh54SsE8AIfkCFr/U4htyKZW9vuQM3fQI7rwHzuXaQC1du2rw35hgMJg rzkHxo9sZG4To2IIM2MM/vtSF7MhE7MGengWmHChgSOCLd8FjJp96jLAlfhTpab2fCYfptiA Mwz1u+uyb0ZqS98OZ72MCFsDK2gkOr8QZfCFmG46sMochP3UYFgrccjRWT6xjft8Hd9EB7Yv Dg/pgcBzOEGiYfWadhOsw8/Hs3JDKRpR8wJtlgBQGKAkNJQibTOrZmhcub6vcrY51gqDfS6F jJcyzTz+BI393IsdPN4mcepL9DS/rvEPMVYHSvGsmNPMz23OusflTzraQ28SIKWH3XMGP32O Ak22JNmDoc1u+cDd77OtKCS+zb+REZRkBVE1rE7nSMSM4kfpfwIGB4tG9EWsDDngbL8C4T85 eRtKSAT/hvndrf8r2xaYd2RwS9Z6AawuS13rt5jin/7EVTaobdCR6irlCODbBti/JyydlTST ImXS206jvnAgAPlS5QNcESFWlcO76DFMgQKJg9EcoHRxEzPJ/fUzDC3d3cgYe8i4ddx1Ku3V gvXd876Ce6hAocnK5hhaDuzJ0IJHvGSyIUnH+dcNW3e+2RvNDDY/NzjWu6DHOxpRe8ZFKAMl 8mZbP0IskR+/1GjMViOzGHCutAydbMpsUBSPZz07rQ9GLnN8EJ+vv+knK3L40A6atAmwqhkZ e3nD2uX/s1A4o8bkLoT6JBQVxMR3e1WPx/+CI+0AqbujBIXJQnCkY+xdIvOXxy27p4NCZZBw CxpT7KMz4Tn2pzt1cbI8vebtj5KM6qq48IH8PoT8HGHl5KPSQjJWHOcbkPMxnvzMAo1sjJYY j54Gvaa+q4Mx0u054R3B0tbwO+O+qQsPm2s913pyxIpvInwNqOxrQ4AycTv24hcfz9djORLu BPqiA6QW/kMG3HOW4dbEmlSkouNQT80V5S3o7L6Ug9o70PwWp6MvP43yBLxSGE8x10tlF9JI 47FNkn5na8EmLYAiNsM2ANkfjnY06oqQ6UEWNY+TZzIFKsmCBDcJXRVjylUmnlm2XvFxbNTC 63z77rBiiWYfuoi1HhrcQaw5wD3Y2c0FI/scVZ4QriawAFtpqLC66p32Km7p3f/ascSlQWVt Uc+EKEndY+fVKiIZsIirM9PWL4mtlD4F6smlZnK9Swu4eCln0W67umNKbC23YTuV5LvRV9AH jd7v0d3fFGkYOiAykjiAeMONxNZWDvJrbfoOE5SeaPj8KsiUTwTDXrjvSZDEPQJXg35VcEwo GXBOaKWqUTkarVMnd3w4NlKHpJr5lxlfTtsZ1TEjHr9xNG0aK9XCQqzW8AtmfHa1zqoQnN2x Wa3fqVd+vyQyNC29VcIXhi77HumRIrigTucv2xibOP1Iae4JWvqyQoamma0y1eRAenzYs105 BzXcYKJIeXJdjduly1HytN9l5izknZLsb/GzSLb+L6p5vZmsvM6y6+lrha5Tq5ksmGG2Xvpr /qg7uoUp+l7TtT7VkiBwlB0t1o8keVTBCwZUyqLeZ4ugFxeuQy7TasSSHhU19YilBmDrJXZq fhKuohLhjG7I+Wh6rh9aaGsBGUucmR4oceMzOKkGOs1YZIWjH0LL74JesnLGPcTXHe9YXzqt w/no3PfrPeGFUV7r0x8MmepYds5PmipKoMQtHgbcPK8LO3DXnwKVPrdpJk3a7V0fr14JRZRj kVyDF/QQKJuUHEcO6nmDjvXdxx2sJ2OyTOv9hG9HOtPcpiwiPQDd9AAZh/KN3BwWj2BjASuM kmyjfRHcTZnaoIWNtwqd7D6f3SLfjKRXL1Uh8ixe7VP72G/RJUFhSddewwxn02nDdqifTfD7 gGwxvMrkDRpNo9tmk2oDS9biU6Ay8it8FAIT7JwXTC/816Xqq9fg0hBSlRLGGdstKf6jqAzE D2WzFUBo6Op62EwP/BijUga5XWbYXz8EOFUoaHR1LLNEwBSxCmVUmGZOHoITtfsPPb526KWk CyxFajMMPrykMG0KWfmGO9F6fviuvyCcF1BmETjTtcGUE9S6VoDkfvAjNfJzfzeFTqE5u3CZ 0QYL96j8jLHSe0wgVFiXkg2lkFpAffAZhOYxNL4rQ2obrI6ntuC85rM6j0IfuZxEUeDRkpGB NuLVbXOdiwF/+y/+jTitRJaS7OWXkZ1khc3VfOfSqvzXaAyjSnXGdYPak7l7P9mwS3iarYPW /nYyi09t70LnDn+ifHC5BDQOd1o7/hG7BwbYj3a51lE6aQJd9YyH59E47jTFuA0Cs2+R42pX rIdLKFwTiaNnomrBTp3DNAsCP6G560ATXaAE1OIEwoUlUEmjQwt52nVABgTaOBWY/kFkLjHj 8YVI5j49ljmCNLXlnJhajhFgeINirH6zh049xjD8mi3AUoi3iYqxo0TH7ciGilsmwI8wKtBi 55okPUFcEPXR1DLd2eTpIsY7KwDb28n/vMwq0vjG2g4xyfOG1Vvu5a45BiU+T/FvMUUDW+WE V8O3o9hgBTHRfdtev8eDR2bHrV8xLdVtIZQskarNyS2x9MektKdz3kK5Bt4NTFc820/xmIPB y4/NLu7X1NjpiT7A+VBJGisxiMVF5fDHsJxF5OHQbGqBa2APyIJ18auOowrzPTkOoi8ZvNIq KAWXbFa14wS4vcohk41aBQBoYkdStFlFgo75hp/xJ6dQp0jemsvHMQH+R4MW4JG5hrXg3I91 EUkNeqRATBVineb8fhw80ZNtUHWPU+eS+RRbNKK1Gh/zzRRlEISx8jF0qTJGkfyqh+EkouUT hulhsI5IFofxBTfSGUfxLAqE2aMWTNw6++pGHZzpBHJ2jqUAstKjPu2f0EKC1dKdIIPjEvU/ 4JiR4WH3ou269r77Sz7GQSnDCiTNNR2NU2v52wt65ocRjeYLFpaQx90yBX4hljTNy86h7Ado lVt3OzcqGbhIPHhmjlx7EwlK8xO6ZDUptGSCBDHmjeaTvM2jFY5EUsKI6j/xH2ACKaGoKLfL wtXH2NMNKbWzc8k1bMcOXmcU+4L88uOSy0lLZGCeR2DUfQtos0LZzy5v2L71VL+HRmufo8w1 iLeWFgEuB7ZnbakxG8K4Ww5KwFUs0ZxwbX6IgoH8mGMkvTqU1fngcgOI5VFWnBqkIuP8ehpJ cQGlsuCspiFTEE6y+3MpiWeB6kDJ8cWmCU3P7ukFW2iPEpN3z6JMLCnj22+y9+wmRQaNU0ye KtxefafttbnYg01G9BF/UNmLtGzzqPCOUwkUsXhlKFys2tZT7Z3+FUIVyWikSo6wfpZ+zEqA DryXOHc1FhCTsUBf0mTDNji8uXIeNTdDV6Fi8jT/6k2Of8VU+P9MEju4cC0WI2djBi2fYlgq HgBEYKDGpuR9LWgTP8lRcCT8EpZe3a89/3G9n8Ya03eCU3Krf6sZyRcMWbGkox9YNQlEUfAO 5jpy+LeG5nwnMK7qrz/V2+sMfvmPaS1iPuaQ/Trtmew75GxjGmpXHbNGIzph8NwL3sNm/0U9 v7nKBRtjzdk56Y3fgsjSEAj28arwB9oDYi7hpvrWDPrCzercHV1frsvksut8KDSCNwpZxLh+ fecaRJgRSwrAO+cwkJLq8rCv7RbkEqaS3i2Ez6hRVqgV7OFHB4caTXsmgRUZIrFrdBz7ZgoP jUhrG8Lc2J6o7pgpmrTJKUx1Q/JBrVL4cpczisZNCn70YAi9beQz5wPIBADmtTUdGnCmXldw GhrJ2GRfF1w9jQgfaVaE/NdnmkxlBdk15lUIzFs/+aBraKz9F8noCotYxBGdXuJ+bzqjB/Mi 7BiXE/PrZe8B7Y9GJrdcl80RWZzxn1bNC30UZJQKnICTR9970Z5we2tA5HAA1K6fYMJm5UM+ LBoNCsFgM4GMZomJ/i0kElcXNk3onfaVSgGYKTnH9EVPhrDuD5X//xuwJd5o4RxZxOJupkwq 4g2aCcO2ZrzVkAvQdbVTOCKgn9Z5KYPvXJLn3lJEHdeFxCFR/Ykx9y3gMACowuG1KDV8t/1W 6oX4vGYu3u0kdefqW+h/1vpq7U6a9GPan683s8hI+Y+oMB+wSJUSAaqoA74TeEO2Izhw7pbD jGvI7XVV1jED8+PbLegl6SLd45ZSmD3sj6+qHisYf3xsJ5b9O8iIp2qvz6qi5kn0j2qciCyk dRWb/Ps/fLVQYL/IH/tILMBSwpDx+axMwgRIkMU1xmeMoN/QBRuGvrHCHp5TVRlQNBhDxxFw K+kkTknakamS6r+rHZJzIFkB1Sx/XCMvTj1vDIAd4l26MuXLpb/rhmGjKWX8965/blGJ61rm dqJfHDPmvCqOrhLkqIhcQUYKDOJ53hkB+9cIPRE+OGe+vYNToMMcFdBGCkhBl1YztLGUbyhe D7HvhkNJzCdxaOhyyn/BvGxrHhaJFbEOk3WFZh7Ca5rrQq161CuLMt9M1iDib4Bt3GITGUQ9 PLf1rrknp6npoTZpbHaS4AWEMHDB1PEbKryJOgE2UBFI2S52IsNbMdQnIPgiMu9xEnLhXveK Vy0klXvUWwt89xvnTHa6wRqkuy1b1KuYksUYyEhD0XPEc82M0f/4xgIA6Cre6JlE5sG10zho aGsAW2y+9QsFktXz4xJOE4D1zzp7d1rd9mt3flvOyh5KGeHvyxugPOLUOMarKh+1s8AG9SZH OsekUbgfBdWkPYbcK0pLCSZpNYr/bVqhCHQErqLNaHGvAq36f03sDTgQkO2WrmXDlR7lLwON P2fzFNcO2kQqAsHbYihI2khA7mBV8uYFQgGyDxJdjzqMUQ8Rk5aWM0VX7zRf4fHavL6ViAAM gUVuyshOiInyxK0KqFLeK6lJxpxde+n818QNap1JMLqKOfn5toqKCfJoqRmntCB5J1xjHHo/ EmtHUXsHDaSJ1Km76gjU5ljuS/nG6eyVoCwnE5uV2v9gPKKUdVC4xaxzULErQJQXoinddq24 DfzD663vfNJhahNYR9Ycc1ho917V2LdAK9bxlSjNfhvZN/U4M+tCu2zY9c23pci7UQNDJjRP 34ovJHo5Kh6dXGGMy67/m2H1RzcX9siIzvyIQ8WvXDNNBcL/Jp2HjW0qdIDWMA9NFuGw0Ed6 N6wmW4+/Dk+pPRZzFak0ateW5SXbZm/dt5W60PPconRX+/pxRsitPEESFYtyIyfS431BKq4u VNZ+GWJcTgPs+B1+wICDBj2EgyW/Zq0P2dvwUl2oiKrjvrsf01bdMGsDLolW6EG1OFJC0HYd OCfMRyJ4tyl8SBVLSfWL3h4OR3BScGPMgOG2URRghZDjJNk/zgVmV6yEOl8c/F7s4W+Hh+W7 CY2gPDoZGw0tA+1Kc49NWaH12fQ+iWsgO8oD67G2i0TKZ5+zWNmNTgHcqVmHBwIP86eoBmg8 wBPz3Dx0XAX3WwbCtBmSc3Up5s21jcz6l0/Y9iN4K/H2hYdz+iK3NFELkBjU1t5mWal3uHwK 0jvbgTEyko3I/8UrD2wKer3DydVojrJrqkJaKrPbEJs0SzXUzyzZHaZ5YB9UH8g+CYLw7QYX sfAs48mjNUSUXXneOnDWqAbGkYEXkCkh5OKNXp+sbujYgbMuYVgZjl+L34LZ0hyhFzaTLShW jCpCspUomXXaOdh4V4C9Ho/wb74BdZ5madxPcUByVs+aH7w8m+umldTL8cbkNJIbefLYiX9P BTxzUUc2jBQ5slREWJQxkq44ChZu09DK9SF0LOQvwgflJkJa03Ag+Zr7+xVYURU1XUxkLJbO f548nXv5hf2tCwZ/3s7Osry2qmUgL3O3Sz+A2anqv+CSxQtspXKH1ri9F3IENscBtHIJVDGZ NCkE1PXIijSurKkOzS5XPKbLyIs2MW+/29xhZdyJuk4KZAzIBCvbSLa3e72/SAIJlvuebbpT rXDp+S2lud9RmUlgRYpKksXJ5y42fw5U6v1WWsiwLra/fbCaGAvEhU+DqJ31YkrP8l2cCzpi 1yGKnYuPH/FiIEucNuVxunSmyi4bueHpzdO4kMd/Q4ITc97UJJ2VbOEL26mz7ZqiMUPDRG0m 5qOoC1lJqMQZeyAFtfoUZ2MIiYCvkpNAOEWnKBZznaS+IxbTtvBbUn+jz6Y2bolkM7MDLFQ5 J1xVFNJjx+kE7FgbOu/KgpcjcNBmSpKdoWtmz9+D9QMyfPMfaA16cJtIbwLzzdrC0Mw4znXg Owpw7lYB0FjZPZTtverEfZK81M37FLY5JTn5CarXoprtpfTYs9bluXGEmIAaseMZmjC1v44U WjpO1ih5qdrMDAh/KoOGALOs0Skv1W4JAxygraAaGkQeY3ayikEAn33BT7J9jyFE+4hJadRM ao1mLcertSCADrnuWA7ggWNfjvO/Gs5H67APr4sbGXQTmWGSI2SeyQl3il4Ub46haBJKbxZr u8GYbu7olzhZdWaIczxSPK4GjFZfLBfDxLQ4lr7/LoxV123yc/+f7zI5tWB6HkLo5SNEiaGi IsDrBzizMO4KlmoZ1sJ9G2xulo9EcS3HpObKFztGfRkwLi0rwUX5G7Y60JVSQor/eWQN4sCv 3NyuI+iNOSZmOelmgfrxbfcdLFb3tpQf8RBxJh9rCkpGD5LCjoVRDsT5DIzr25MJ4DOB7SXv X8M5+oA6xfPfAyQHVHzhmCSgMPHmiQtXIvKWeB6yAvVvhVX9Nf3bHt7UnrwVsf3EMuBViFLG 8PWSIx8PiZdCHatYJDxZGeyNEIxRk3RhnNhbJemiefE5qhWcAwI+MJIpggQbjUEhhTRHo4yo RuJIMnZFicvRabzO7iJxJWBbVuTCM+u/9n0NQNbp0vvkbOH6iiwZMk40yGYLc16ofKI7O0WK GtTP8XgaalCpMGi5Yp/eRf0SIsFNxzHNdTIdvS+v0xD7qvWgWtY3JYCYeV7RQzXdtjZPpift ef9eN1z3AtFruHrManQr1E3QNUFVmu+md81yed8oPoFgBHPwMZ0NkdPAa4fW+94ZMdmccylg TPmR6AEKzWFu+OR0tckrM7uuMALu+NJzS1Uw342G42xPtokQP+0PvkDJmNfEmooZmPlXNfQf b9HJR7oGboUCj4iPLiE9equNUwmEe+WABgGRyqii7cTv4dqLv9iUZWW9Yl4R7s/RI0ZsgOpY piLC/UAG6j/ISa4KkUvtr13xsk/v4UZpWjEB4QXTi3K5Jl0HsZ9L6bFetFROtHVtUnIaqSUs WX4qhRnOz7ZcUvTbuu9J+O3JXGE/+zCFrf27MTtvXWRLVfQl0fh8GCrWRhlBWILh/j5XOyv/ 5DCilTI/KE+rRhq47kDXCJvSQPqmK9rHg4Jwg+RFkh5kTLKvziMpvWEl0qLBVGW0Z5xb7Lcd h/dIpqsgVOYG5PJtk10fXgJOXJFBexuGFTDXFnwqj3rELYj3AvGrGwIBafB0SnLlXUFweNr+ kbSjdPPpJ87pIzRai76qdbIrpESg2nJCpmXdpGJfPTHslj0Y9YtfoVIVdzAIk3EGuO3xWe2V dgvRevzN5Fc6URdePbCT92F9ZI1TCHtGBhMPh/6s4I2twc5Jj11nBNCy2qubBCS1RO3KgoIt 3HYMmHYFKMtV2ls0hQr4je5ezg73J41Hjyh1pLFVRk+EdThLY+HpSPibB6oymen7c57cBseK aVrzYIPU0KeX9OQplfrhnr06JnI/1Pi6s2J0rAKIFtBFA+tXiqbu7uwgW/uJ3wGWGrFPZDND L0R2R7pi3vwssJYUCQYAuh5RmF1Fs5wItGrn96Mq6PglTA9Ev3Zbtyomes9ATr0NnW0voDh4 EQOdNPBguYarK9MQeAVsyrkmN3ClAQiRDqIVoVqwv72Z78qskVjMkrvimwAFIhuzWumZUXbS pFWzxkfU+Csch5lO+bIOC1XrBS2ivHqc9/rEiHO7ukQHXhCqEL38uE7gqY1RjaQlyMDfHptA r6KDzOqYX1wC23zHjQPWYbSbPbM79pO8aTWrXSSlqR3cTDQA77i/97+kERnaSzoWjK+CF/pa YFAKzT5J0Fy5RAR4NQ84Tn1IzcQskw7SlsXWrI5K4zg1/xV+h3Oo3kNOoEycdfa+82phBwa0 6y56eKjxeKXSoLmYSJCSYS/J401cdVtF4Brh8kfoKgVFWpNAFe1DGV8CVDtqxv6gK9qYobbv 7fcTMrGPwfOj4PalrWRfF1NLc2NU4J1fp7bcxd77LtMKkKTkOkkzWzUDGYmUMDk4nW+tP/WK 7or612PKmNLNxd+J/dSx79KHDgPG7cO4IQ4fQZFzxDCSpnwOwCYRWYZUPCXZb/IeNcOk3po5 YdMD8Pg6qWo2JYpzZQMlHvfCZP8Pkia8CuH964/fKXwuR3R+/AkcsjXmSUOmTNLKW7BvGXHH X2M7IZ7RWSLw4CIyLSyYGo2TamshW7i2MgjuC4hWfP2V1cEtFxMvQZxvMAt1Zy6c/3Ky7zDm hl4wU87hR1cGkaWej6s3F2QLacp6XIMNrShY/18QrR12QxDS1q7pLBJlgnU/ztGffzIE9Vbj SQftWpw5APlHzJQK0DdH+RZn8epmDFF3xNLUcx6G+yfp08useYh+wS2fzeaWXihU83/My78f Q6pPQMRdKqFRmEa1GFKaLO9B0mO6lDmRt9qATHtspNsspJZwdgSUBrUsEV9yb5W2mzRsi0lC +gnK4vtZ38rREghCfeFG3eQy2JZhSDQo9JQJzZcrSu8VgZn4YXCKIes2A5UFSA8R+upzeGc3 GTHkHrquZ9jysI4QapF4c5za6CADBYexNcBmDYC8egaSkdw5D/I+3tDFZQiozRRiI7oagz63 Oki99Q5kNUnNAniuLkUMhxGLVdY2/GEaMAGLzKojU7z0XMs4/wNWHV+TAkaV3iWYf9ub+lsB 0qU5GyJb3CpGMMQYugq7C/9qdzM/1l27GJR2zmExCJrbsbi4pS/NycW4QyHZnolMGro80ViF jIhBou6cdUcy7+H+LVLAqPqCjycAfbTi/tCjBe2D+dYYWdkNe4Zd+Xwmdseqq0dO4X65b4xo 55pPBYIRDha5Yh0nceWl5VeejDkkhUXTXGdTDJYvC9RP9UiCvlMtOswW+LJY6XhI+tqBqG9W tLcU1pvdWOlEnnfw5tjSnTPYbNI/FOtJNutANZf01oqMCoypO49x/piwNdG6H79gwmA6Fnz3 3QLRDlIEqXWDkEjMX6umuLNFxANBCGZNjV7qRSN8qXgM4GzX8M5VGiLEBT6U1cER+ozHhfGK dERSPM0ZFTWeQcpGYtmEHaeIPLhZ7e0YpW3eerSAkWV/D/dImeXu4qvJj28Ynt9k7lPExmiC 18sdlOakPmkgDQ7wi/JDUAs3Xoi0iWGUbFvlnb2whRPr8/sTib8tAxyoeyvMG87PyejYDx2l kFOI/I15T0i2zcdxxPfzRwUr6ZPiRVrmrRjQqjQpU8XXEg1q+nBckgjbnem/kX0A0OGhGEw8 69WKxI40LSM7n91sPBr9X2rec4MG5TsZ5VKKuBM/EuSGVRzjRadMvnfEdpvP+2/QM4sb0a7c 4uKKv6X1CGZXddIH5ELhDJC75ke/JlCmrGQECmCszqlfulTQXzJARqrRZ7BIQNl4NoTHNgSO Ga94FsdoGWBUQ5HCLE3EOOmO8A9onW3ptDTNv09+QFpC20+FgjEy0CiT1PxBkeI6H9EU74hp pwVEDfhJGZdKaUjzYcyaBzNJYF1C156GNZChnCtuGJ6PvET80YjmRRfXwB2/4A5q5IEIZz2F yk/F5spipJ7WgkiECe2Vlxb3sBqCwH9L7o4QnAECU1AUWe5RhE1CgtDo7S9fshwTGTVz1I2x w1HAaJxCPEnCtVGG6Aooe+/EBEr4PbnwQr+2F0AVTzTB/RArs93ofXChQcGbtspAL0ixY5zT Fn0l44koBec6iMPcJ7OytiDz8JDdjdA8BUQJQBJVTx8rRH32uuWQksZTnrGEt1FmgzZxr8mn nXNla5uDRpc5ZvJijr4Ot+ZS6e9calWdnDemxg3lPPLJAcWRCr/N5seX27sD1yIr3oWDvy0C KQUFloYHyWnJ6ZN19eVPs+dGDhMnWV8KLI7O04+DuUo6cpuIU0EqSl0jKzfHXoNJ3NFQLoEn AZuv7m0JrL1KtWMgY7Prh9rR93CDo2jsxsyryetJ3XiKuabgXsxKhJE5iNQTASguWnPv8jET S3m9P//CdphiiXOpw1o1VpSYT58vJYbRxme2ZWf6/5EdRRy6Meb1sT9jD0uklVcwsvkLW5ld oHpCnhvkW16Ov64S4CPfXBN5pfFfV3e61pCBSMHnc0EY7yYuvyWriLP6fSNWSxNC+3wlrulp ilFiUdqgNiaEfFriYweTEOemX04bemi/jEJdkQEmikh+lo71NajJJZOdF8Q4bZsF18OY2+bQ +kelKh/8hyZsIslEAJdx7J3S5Ovuv5f8oLAPorgfuX+GMmXCDXfcXcFTwuWnZ+hTvjhMciyW 83T1V110olu8jrNIVdmhIVA0i9lgnKrGW2/Q+5SNFcIb0cXtUwq//GfGVNVyZ6roTqZZ1Q8k JAMfozrMFPqTC5dsEbQmB0kuyQFBfxd4x6XAcroJRh6VzVSiiPaK3xKy73rbizGu+v/lhFCU TTOPq9/HDQOyzwlicC34uuRksipkg51bchXUH21/X4mG75iu6Lpm74327iDKVgcwE77MCtty aPetwbuBux1xoJwsRJ5Oq9bRVjVnSeMooaV+sTCipeWGxUAb0DH+nd4tWNRgawesLDcIrqUr eTw7dCOn7zk3pp8x/jRn0VHF2rU82o+YHw7BvIMQ5dg/VOxIH6Dfs1EuFXteLuVvWgxr9paM DsCYgcIDjdwLpiTTQeE03HOOrr4pDwuLbJ+aDn/x+j1xd+coC3TWE4h87bLNyQ8IkWLx9Eba k4AYZ4eSFRVv65Z/EoRajlXGb7QMMPsGLChP4Y7uO9b0S3gZkQXiXPdnAppwsCM7FOl81IkU qRF6nwc3jvayhB7ZQ3N1/pQhIuSBNIvLk0c+TRMKW60sqEPDAeWFxTiUA+TtHmOTtYhN5A0M Qi+gnDxe6ynR7Q3I0jvOEE/XfbUnJCLGEE7C90ud1Y1kxySXr3an44phl+dWeD1M2mGJI5QP fb98oWRze/RrLXpcwoQwGpCB251eug2ALt6lWmlNdKhGf3kM19Pe67LEVDc+JSsALiRbmla3 nRncL713zz5qAJ9saCHFBCFTNcCfT+b1osu6D0XriYkAo8VyN7ctLLjY3Arc6CYURlDJhyDr uj7GZSa9FvhIVtZ4nC5lr4m0Msq/IZX6gCos8oHgkhv6h12h1rgJKQZMMSkXnB1pQHLDbaej 1tZ8ls+Za+ZyG455fnJx9ovIiBfwpaVfWDPh8nJO+NM6vcBIpMqB4NARwGyAFieWbZjNhWIW Rpdg0yMzE9GAQeKIA4fvp2i+yIHmDk14KcEYRLUTEgz0rTdhsm2hOSka1VJLFkuEhnZwaXo/ +57tKznUbnjAPZfn5V9j/YnSgxPJs+gsMCS1sJqbrr7gcu0/PTAHBMMY+d4vUZsA0z4UhV4p 2W643QUNH5oePYPEEOuHQPkkgJojG+3YAVWTRg470uZwnjCE+BwLLOfawiMaSInHww2pKYCg MdNwGP5Y8KwJ4rqszDSaTfXOUxhPAW17e4mJxT5kJ3j1k/P+FDK9GEQ/k65Kvq50MEaFraH9 1Klk5zKz3S2X+kesqIcYyP1YhBSCJdXK9IIlyvoIe4qtyOUoKZo+B2zXrv6IzZCixhIwxjwD hLQOly1BcHfF5gZ6vQh3UJGswKWG/OobWHdU3MEwHWVzjRAixkAvG7qRqnyhPRQ2zUz7UJbq laSJhvdvgg/ys2gYohqz5bb6giemqTzjjCNHUYdGUZN3zn3cJ9cqDp79jJy3ehNsIufMcsj+ NcBfq2DCXi/SZP16WkiK1KDMzz/igyYoE9oGw6EQ+Ybg6FFkFNNOj4aLVgyAy1kO1AaKfBBz PvFU3tfP/HB15ij0yBavIJPLPi8nxErWG4jeTbcF6LHnWuYhQy5g9X9LnpeuVOO5t3pCtmqf 0Jy4p7wqUQHFtKKizWdSbmkv3ILfBWBVCGgn89fBVgjW1z/r3H8q1k+zIMBETcYaeyWzRk+c uuj6TdLfLEYsPjx1oexLYHDuIcTNbic5mVAzJujOSuScFhS/Vf/UgkjrMfrhuVTPjs0Qf8og N6AIcmcgl8LxH14mcyo9N50g6wY4uaCvjMNM3HIPspHfIRJ8r+t7Sx9C3x2Q56FFwMIxUH4Y jpVCfgCrzVgEyzMhgfwgO8V2IkZRPsI6o+C2Dex7L8djLgHGwuVb9eDFAkXktY8BTZu8VWCg 4T2RohFn99PycrAib8tyAoLcdkzGrEFeZaElJs033PHLRfzF/uF+jaX1zA3JE+Rwx7YKteX9 HZDETd64fGQ7zcJfPRS0KzjvGVGRIlEq0TfkGWA3wSfrQwg2jdtsQVQYmN0THQaW4R+D4MHS 2x84hUMZN1+qm3Xvo56LyW1KX2X7QdOcFIzRazpCA9vHcplJ81TUU81FQVKkiMbyLjRjb/bO CIa+FBQoGFTCI1es9FPlD3C1c/vEwvuZm2lBasodHuHZP8GP6VrsV8qFWfX5iDM3PcZyN3MD bqcfrdp2ZtVgDuKCB1JRrk7GtyLjzQF/a8nkN32ztaGRUrdoXt/S5Gnq9RSxsr4akc1sxvPT XawdubFSStZ0JLr4mtPV2lZ4hYU27P9LaUOf4mK+Ou+NC1iMYJhxmSIqqhifKhPeZe/hRLqY NtfgrZH45MusjA32npZJX6XNGqg6Eqp3swsW65mrUDYpywXAB8KYgmdd9F5Qj+MYcV7xpHiT ZXujRD4biOTmrXLLiO88wdMny/HqdbNsXoYsfIOXNUvGoLAREiwqKftm4ws8YBWZB8yBSFpz lsci/lLgK9wh4/HTw9CBUabNsZ0XKRxB87Bqnh5dHvysCJ7kxOnYnDkgCX/TXCwe1k8jYCFE zkaINQd4oaD0YttNKElVG8ss9FZ98sBj4sBD/u0lluvtJUNe5uGc410Gsbgk+uPKp7iyGKPy 12DySfTvVIYVb4dTRQwVFbLlKuMMbocJk3PoMFCW+heeZVv9Y6frC3gD74a5ZEUBu29bi4N3 carCWTBa8xl9+7cJq5eM7NNNb2CDvkvcIZpPzvlVNfAPk5D6w7StMFuvIYdJWX4G0SxKx+F8 nNzY7HbdHABLGMP63dDL+kzYtfsA1um0xL6a0RS3deNDXWQx2Fmv96Mx1mpCVXKES+MLiyqo DJOY/6uirJo0jf+TKW2MVJYhGhcWSHNZ1FI9FPwZZ5MdPOrPMpbjI+z5lOTuzUwBJ4WxqCG6 ieLHke9ru8zurtfxZZGgaAPo0qqsLFPi/SPqIqjTPJIBU66OSkjYIbFJvbefhTK0B12mL3CH 3MG+gayh1jcLzZzxZVJrBZ3GFJdqumziUaEJz0aVPS/TKkhcnkVc2pGqNIttffXNcn8bhTEM oN8s4L9vNHqdZd6fdZYQFkD4iKtHUbgOEp1sMrSgrskphvyfS3e5FY1QcsA17k4TVhUWRF5o M9DOIFD3rXyKEIYEbE3jRov55fbsk6FJNBLDQsyiVuU7pqOaRORqu8XaJuLOnfBZmlov6+br 5dCFmwWjx0PqIW9H0GRqByGYnhPAPJjHT/A9OfoTG2FbLpP2lma3H+J1OzcUGZBlb5nc+fAb CsPP+7jQz+Utm1xOwD8tz06QaQ/DKfS1Rvrt/EPKRp3a+AjiQ/FCrp8MHxWCgQspb1yXMXnX SOCBgvEIb6nF0Mw+bXEmVdNib2QueV9eGE0JwAt4oPMsDoDnESvtTjEn/ktJo4YSoEezE8AC m5w8yWjkqQBYUldWngekr/g7kp1/JNHWFlbqS+b3VUta+8bYevGMY/B7/P/HNz7bNq1Ortx3 K8N8aG56Xq3fwUfJIky3caLUNb5SOzdEDk0amMsl3Z73Kq8rojdtK72LNluTIWODCYRvk/Nf kY178/XRHHUMn7W4cFDyWpHcYvH+XGuXXrmTt/bvq++5upZO5vB1MpO0gOY3l1HVFZM3HoxO 6Z/G7n9FyLs9Rq1JHrqsyYd2NuKRf+bxxUz+nFvNi8nVktkZ3t16fBxKt7YlNidBxTMEARWt nyAzk3nCNWggq7hSqPaBUIAyTLGDyjeXK9YOtXkWVsTbYnTqjGWFZHc2dvH32Ky8k0et2V2j fqjGigekVJIWrihNfowQ8PHTkqkozrQtiVsKYr8KE5v4x/Kg2aPKnAikxFSfCWG9Q53S/as5 MTR0J49fWjQFn3z7bGdAH+Wkm/cUKY1dlDynaLeqNo0bw/RpZZOkHdzYh/veKGpb/bz0jkyi o+nxLqRKU1u/hfqk6EPYzPa75e5TB10dpSyuL3E76mt8T13PekRIT7+L2Iok3L9yanEZgB5B 5y7Yzdx+JcZjDsAMrWzOHsBFlY98TMhIFVtsL+fY0AvnjnsMkZcvt/2dWF4S4NlncoiFm12a MrPP5P6frEWFb3XtDcNyFgqwh6EQMmLrNoVDMU3QUcs+hDqcXZjXWkIHHnagYFVUQZmEJsyx I5IuftlfQWOQfZ2vQWTVCrYsGICWl77se4VA9ZpUIYZCX6QjQgfD/4cUYKXMjIIumAqigem+ 2mIpcGPAnxdr0Nd6g/bb00rusnInCMX4pI5NbBsPWHf0nc44QL4B46s3g5Mpo1yTbLXjJEN8 bwILbVxVhs1GLEnwwjKI9SbFlfsYqIwqhRU2Udb3PzAJxgtKipmDAij1N6/GrtE3xzwERwKd TdD798fAygstPM4pbuIPgQbyKPX+E5ZF6ZzfrnguF5glGZiMOJPpmNMAS12n0N5OW13omILM M5hp9s0t8242RcsQex6kBYultq/DkLddFkfjrey9E2daetTPPVghGgReAmVwgbuvAFJ4UtYf Pr45o6z8eH7vq4SU3NlAfwq+yEqcEPgMIuezRiBWeuoP46j4DsQKJuFbWQSIWWB6a4oTbI5G bFXF0GQzZ2hg0G4PRLcXLlEt+3EPlI5rdNSUb+XHKTqZVG2Wo8gc0ZTmWfN2qTXjZJ2R/QEh T5pWobmS2R9fYrZWaU8QT9yFW+R3z23RmVUnly2/nJZBntvCJWHTSgn9wcYVFbVMUG/ok4KA jVzyfNrj8pCaZfXuhusW2xEg8muaZYYDJ1ofqsdOqLl7QKYm/1Rxht8i2u3JdxL2D5yv4QiN ZBniQvW+ypD+E6iiJdaQMGqi58sI/vSoQY9IIPGtp0AUzBnHA10SLhfPQA/v6oSfKTD/1Apc htEEHDFC9r8Lo7r8mguA2hIj8ImVLYnTbENu1zyyj6jBYDVPCBcH1w8qmxqt1JXF2e29D4OH qYBGRFV8W9s2AfSeS2OX5CYQgErTn31Y4q0Bej7g9mw/Mc+w5k/jJ/2A+w0NKiTPsuB5ZV5z m9CBIzUk5hNhcSPdbn3wbcZGM/LoYL5AfstiPz4XQ2IzJOfKWR+GP2EpnjRl0r8wwbml9Kz1 cmAgr1RrhfKchDVTmBM4H12bAceBU4G7TAcoQEz7W8NVgbjLSobZCrIo9YpJQhWbsQFbi7uu 4Ofrj2ofA8Pq4tgpk5TLES/MU/rYdSCx9Ru4ZuOsdQnntwPrU5eREIvX/FbWFiErxB9iDdYk jnDmrTmXP6+vhKPlhaOjss5fZ6ALor832XddfZrALG85Qo4IaaZXRX0GNi8uyoN7qWJDKXoX 4EBimIkC5BRjtAAawzSrKRsmqvde2aKlGboB+RU3nQVwp0xvwLSE1erPziMoX4W1pmfBWFDI l+O5aNzTV16L/0r57Ezu00VZmsqk4+2LQ5iVXpIyn6UMO2oryVlaiNse7GGVzKl+1JzcyBU9 ajQMFt/nkodWnGChmW0ISIKwcI5QRtG+vBxqJwNS4ZrBeLjY6O/yiUdNIxUFP1F7YVji3lc+ JFZAit+TdPCmXGduVfQjb5ho1YjRvFEAuHMTgOzMuo2T6TsooxVps7k3MHryOWH70VY4wd0p Vo3BRjbn2Ct8/NblQfPe+ml+XyxX6dj5vLYcNgLrBjkxNk3zhEKlSU2MinHd9AQz3M6DZs5A +mxX88go8wyVeBEvwERnox9MJA+eiIbsymi9cstcD0EF7YpHDjx61NcS4zFxNJOV0kOC/8tI JP+y0wE82eBmBTjmhvsJEQpX504N5L2TQ/PF/XXM+Yp29FiAbGPQxEfsYxuGrcUCkbfJ/NZo OlPDUtP5jEo3p6x3rux0gXXbZL2x1beIXjWBhdGVEG1+V7MChvFe9V1yXilH90JBK0jbkyUB nXNTaeN38XN0uUKq8e7mCa3GdWEx6/JnjQCXKKzkuakMNKVTt6I+2Zc+H0z15EHEALLl4/Di aoUUdOk6NM4hDQDU4wXf4f31IMKGF/y8ADhUlVsfWAg2p+6Ziqj9I/E1qiwOh5RikhMVtFn2 Vu5rNGKdsIOuSE1WxsLeIS8WPxw4YWV3ZNbuQOvKC/hcUkwbHnyol7oRBjo4a2A4Ip1Uj54u qU2t6IUYssqIesmR0YufsPv060619+W/hFWk9NSO9N931EnSreMxtdV8B+qV+XaxRln52OIr Z7uEU90cIeHSFZIAyaXSFSR0vfXiRkZ9SV3L+oXKPb8rF0/Huc0xdwgiPV/UG+yw0PNMyBb9 Zvos01hrZFf/3eyIWFxw/apuXmEJkAAJL8XTWJf90KxOVCEceVmOb4W5TppPtUBtb1PP/qcJ BunJPOV6KhxecLqs8NcRIQ4NZwlfwnZU8vEZo+Xu9ff5xD914t3Dk4i41D6KprCUQJGhm35z 3sMonn2Jmlp/on4VPEzFUZ0haOie7H/04+p30QcLlWmYQpkxMek4RQxG69clniQvxPw2j6qa GRIbjK+P94LEVxhQpR8GxEG/CFTAfuZqPsuH9AW4a1TXxwmuziTpqxO21e4efFOIBFqf+or4 WFzJm9QxszcyXGhBcMOPCmfDi+0zoR4d2zCv1OzA9n0AZNZDl6rWQgjSwxbVWCIUim7iR+wc eApS6lEeIgWgYe9Lr+QCj6axuSvfIJQP7htx5OR+zoCCj4HixENqe/IcfMxUL9Aqqg5XfApf Lxj1hpIeC66XozAoxu0D8C/y2VtPmk3YbBz3N5qzc8HnSwWy5wVj6wTSn93cVWoXBdavoFlO 3NgzBTZZFbh27DHLi7k7EcRP19rvGJjW8pat+rc0iTJgz2R8i1+OR08GxP8PtvTvJWOtHQeS KtE0DBHzsxKWRwpPLJTQqMcpzB1gku5PLceiRntWnnUtASm2rLmQt18cgYKDxPJ6gBgeaRpz O2y7R1AYxLEoyPHGhQkztq9sgC97sYfdM7FiVZ8VOULp0Ks2+dxGfgUerJY6cNa9ZqwkvizN w2wlB+5ShCNM1NADggXGZ4xk3xr7YIlQechx6l2HC5GwsYT28gv2e9a5gighktPUKfj8F/ye f1/anbBidv5Gu3LqPeHNhPE5+RuwzPuZKv5fOG/s8qyK0HEoSjjtGVzftYrlk1YuFTwUBs5X r+5+nlrHVnaU/mfZY0vIBlGirkYCdpENSLt5uk602oTRV7YUOWwh57yCaI6TSFqYSXmrf37/ kNoviSmIBcuMt3ap1FrXSLA44mqJRcLtZv5Wc+/5kveWwJs3uvVisjg4QkehOkUbTBF94/2A pAMqVA86Aa9tQNqtIxO/BxsyCtQaOlmWsBqFIZoMGTat74k64TnfIPg3nKeTnLnvxM6UavBm BLzIiwDOlie+6Vbg27Lrs/ygeOMRlsiModz0ZU5GTewDfVhuQs3VFEI9L7C3sbQS6bhrS/LW guGEcXKWTC1ZZWJYH3/3sNc3N9wDDNaFaKg5vrd2vYqaYjmyTMJ/RPtnQ11581LQ0UoTkvn+ r66znv59wu19buyq5zQnZLT/rPYSunWb5qun3B3ix1VMNR2iikBpXp1j0EExb4p2jRNE5jE/ kvAFIYks5HXQlnGmBDgwIQkPEmO3qdjXzvtvQ9g3++yzq9fWob+LqupjnlshBmRgg2+oUSw9 Oz47Z09qWV4f11bXJ9r9GlxPob+KacxK8Imy3iFti4hhUyaCyGZ/RxmeAOv6rS8N0APj3wqc rBsdgmzN3ELKmvI84Qx8zCFH+7R0sqkyz4PgNtkrRQILA7RMcBdgGKfLHmUEvEYdqzSqO7rp aR3txg55w7qufPwIF9ZaMuLqJPuCX9VfOhd7SEddLxg1ZlJEOpjzPe3DmUvVzV7tZ6X7BXJE hToXK5QhmohIk1ok3DLtv9wBuYKc+uFyQXePFhjpTVa/Ck6YKSPrTJ1glJnLCvFqTmj86aEq mhh0dNjCux7CjXLHkQZVvL2tocueEYH1IhzPY4+XnJU4P4JiZg7RH+R3M3c/Y6zjek41K6T1 CPxy5/jHUfXZRroBqJrYm4ZiTA33lsyOtC8Gs4WR8v+sxnwPX0ES3SQGck74bfuYh4XhvnlI 5d0NJGc3gfasZflYGpNE8oj5tLgZYT9TYZgfBvirmVuaaP1w0yBno7z/x/31By7OHEs4y2uO oDw0bUnapUdnGxhBxS6zHgmhdznNQMRFTIr3V0sDlzF+eC50EK09akHbDvBE9TBhKWgMWB1z M28J7KefC6NqjJfLMBk4psFISbMqjIrFCXyDgECgSuFEv7FxF/YpAxx3rDpTIo22j4le98dp 2T+z8nQ+/sz53ZQe+V0bRcxMD6KAV8oMmKeZeS1R5bTEoUF/UnnRvzrz7GW3Md+KlNvlfSdt OJDpux2L2ELsFZJyDwa3t+yNGfNX9qQMXfFkLlX2Ff/IIzODT+CfC7og4J5EISqtH9ui6kCK plGCWTi7GtbDGv76Nl+/3ZrKIwfqgyN3vCfbJ66ylJMTmoefHBi3Lyy7VsSWyjqveXKl55zW 7PDZGUzfGxd7e8hnMcp+6PHblf/pY5+wpKUjxIjrsTg8r9/tXiz3FySa5/IjgbPy/WrmG/+B k1puA+XfVDX6GN9MP3B/iBdHpP3zyfkF4SgVT9QacMxWt5BCJl49aDmzHZZoDLiAxuTHt5WV o0sD3jSfX5fzaUFLq3e/Che5Goai1CUUuHQkQYww8+c6zHO81oCGhKnOe1WN6gFxc1Mrfn1u 7UkiHNnkGrWOXJVifHsqAJtp85nsAQTiJYknqQ+6ul97ycUJ5XM5McMRNpJO7DrfmVw7HMFP aOrSQsINLhsDob3HO1PgpGCepl8i9Sv2p577pAWL//8smG4sNrd0PXsqDp7GRZ1xpbf9eZkQ nP2/crhlDyLrS8DhmJDIzi8L7bB4tKn7GnzqCyIrlw0T2qO3J3F+JBSrx3QNgwKpq7vx9isc 3ZbdRRpEruRDvvxsdIsykcWlKmFCecWS5vtQ5udJ7rWPa2igF3GPKnmGMRIbiZInVvXTyQQp qwWRC4QKgb+ervDOSjmvvprtvKuM+X+EZilJc6Tm1hiWjQzKINYVt4CsQLukjCIJVzp9RSt/ kTjXqT/zkm678Pp/5bE+OW27BUzHbh+p5SjosACygtFxnCt9J1dlr5kHxoHRZWqK9ySF9n8C VZzZpvJRt3eipXo5S/Xkh36ssDL4HKQeiHRnosXBgo7fvcojPoL1ep1ffrOXapuKFKQ7iuhQ BkfXccjvOAhJNP+G7EDdTKGbqtm6FUVVfa3d0oLOonvd2LjnX7B4s5w/0j2zzS3qEHb+Osn/ yILvnZ+w8YgNHbeeFkKZXUnNoLUxGY6hvhflZ258x/YtoLctGZ/nxWsGDoCm0SiMbHciSPa0 EI2EvnXDJFYFNrZttmIBlFhM6ZiyEGdiCkwvyzYS4eSzlor2+zN5g2fhtuPLMFh9idl24BB8 n8V9Z2PlqXR0oIJNzYFaILhVPjkvEIhLrcuPUADqkdySEkPIncYYXdOjsiEsObDlFfqZtVVo Gayz5nSxMRt+VV7NA0f5ytOao6zBXuBgENaF6f7ae3bMbJG/okdsK96+YT1G8pfs6lTlwu+j GwWdTKT1ebEFjwzA/bM0BKiSJ+rFp6AQPN563tBLxw+Tx2dsSsXRC9e1Rme7yiOHVQvTbuK9 bNV8SOWG5yBO4wF4qnlx0w/O4cma/I1l1XeN3HTZOMh8aX+Jn72ssOY5FFPpovbagfTF1f7U d6d6zF5sQJuE1liCZtvWtBfKC1HUpEhRmaZJzhXiHw5vUm8B07v0l4bgIk7Oh6SSwniR96ka kdORPQHWS5AFftqmsEHIjE8JfgrF6YKbbJGT2ECv2Xz7ijVlFoOBIOMcOSZJhMRMUigbuP72 Yu1J/HvgrxijjInTmGnikB++dicrlYdVsm3Mw/XLjyhBMbFnK9KTs8FMriliq+8GecqYusBo 6wcLXKKIttrtFualmuQlWhRapPRVNgyxpP+xHPEStSUhVpVAFi4EVpkwB583La8lIcPxXF/a gyN4g3f3Ft/PCGokGH7abXwywY6Vn3b1Jmt6/8POgg+8QUKNo2p3iolYgRuCe5D7m3/KhZiz Ebuq8rt8tNoEVpjIhmKok7QMw2KIPQ8+3+xJmgwzUP+S8Mh2zYs8rGVCIocxfxGb8GddqDlL n9ZAS3ZTZmVoJugXerVEwOUCZGx5Kpe3O7z17RpKVoimVo4YKv9o7K2uDVire21RcKRSo+KL ovX7CM/NjYkYY/+IQGgvzq8mGHnJFI6sah6GOeaN8B5pKs0peIP6f7qPyggorM7xdcHWHvM8 Wdnr+9AzKZL6mINbb5EdJPSN2nm/mcQqcMBcRGQJ2eO8WlVjLqqJUKRrVlsWmquhI4TEWL0Y 0/Uauss8M41ofwvtVu0Ufh15PUqUr7FJB1vLJjYJDb1os6/vK6YtdabeZ0VBySi2zQd/2qkh ruZXIedvw6AxrVcSIZzCeLV9jL/HPawWoLIJ9rQeB4Dx7lR/zZ83nF8j/vpgaoorGhKTNKzj XjzUOZ8jd2I3rUpq0Xcrx/AXQVf2NY2/djJc6w+j3jqbRwuycAzXMXJi2SVopS9KW2mQf8KL I94k5DEEqctu1fNk2tTe99/icKCBI4c+w1DAjaueT6AUkSeEmZ9JnC8S92Dg3wBAG8IqYI2s WyFmfDVrdEKA+E0Kx5y+P0G36SjKDr+FbHRarPCwYSgC1cdTGUbfMtPsLJDybSCE0PYxPAOn YPkCMtgHClsKn0rXmQOGEGji3ueacDytWoMn3rd3NGAhee84p+4TLrVXCrBFywFypXrNwaQt DzOW+00ZC6VwzLdNJqsJn0m6KuEm1Dz9P/n9XQR0IUwTOXU3z9hmnSZJVkAHzZmyzmVjpFds rUh7LC5+SDD1wOpGCsrg2n91OMPtt0NMRQGRLPIIwg2xjnCALNx/CTkkTiFhAd/gHCrEQlXh IlQ0R8C8plP1ck80r96s/iFGVNKutJVleb+Py7/6C9qqUp4MkQbBtuT8yRa1MhEmo8asLe8U 0V203Fc0ofxF5/mBrfy/GqOXlVf2TfbRDZrhjs/HQYKXsrEwSCrDeplAKmjNfWXQ4pJ8HUYk v0OiwHRR0RYghdfxnC/F2bgXAhT20o8kEPq5/hHA1Ceymse9s7nC0BHTmbFWmF2dhkePAxA/ hAfL7O6Xqp+J3b69avbNJrQtf3iYuZS6KEYfTMeVSVssCRq2fMIBjPrsHrH897vGMBtXy1H4 ctBjUonAH2vkmB+iyqsJJiqkHtZFS1m2JgEKxssZt0sH2qbNsAPiySrMXa/AgGHEuRhAJE6b tbNJj5QPjSuIb/yn+WiTdWnpr4UrzfyGomBzdr6fumojzBGgUWRaA0NnH5Dxxn+iL10Yr67A X6hidd04QfjmZlEjtYMqQphzeYqJNcA0D0U6+nn7cI1+e2ePvkklPIH0FLXqgSIZzrTfcC7y /yMbVf7R2rXC55HZFlFo0L3mcspn1CdxM5MyPsliQZ4KsMrQIY2HkwCEjMN9ZNX8EYS3q2FU CDSg7XgwhABJmlW62IhjS69uUJdFL2iKXTVCLQsDJBpzTzabf6gRxTzPWq9JGXM2OrvcOOKI 95ZEnyAnASne/wgT3CgqWUISVCuGXAsYqDJhOhXcs/nKCrh7Du9V646IIW9MVMIKrg8Zipat 3p4JwUxYQM5HM93frYvWBF3bxa7AWq6UGfW+k2CG3vYT7OzWiRt7pGQXMHUIVLsG9B/DS83i YPeW5I+FjMxS45AmfVARq/jgK7ofkj1F1DbZZmWuxycfDByCOUFOKj4utYdka1VxXRZEy+EA jSpWTJzk3W2F8yrfd4I+l1cBoB8xIjiAVqrBtuteqxTMbD/mBZMfKT7TQWPY+mVDyPn7XoiB kRRISrRCbIbO1Wf2zGPidX+O/Pi8Zur5WNfulIDoGkw+V+KKl9kJOh3MoKJcsHDNTNFShmtr pI4YG6Xvv4hH0OVx6dDiZBUUaf21CoPD+LUikCVNbwHimzSrKsRj4UnFL1ufPp1rUTHuwYx4 rWCIMjGSQknOoKbLu51ExNg1quVzgzFu72wqGM87Y7kTROa/f7EBzqc12w+q8cyEtjbRrVhW IVZrz/MYIXiSVkawzTuGvSCgAUnFqGGKTDAgjxKCEdaBTL2SALQZ4oglIfnn6VqRipfxvgjw hmmJW9z0KoEo7xhg+KBejdD+6IkhoesioLGRaaLpRCCUii/DUWV3K/C9eEZkGQ5TrYISCjkk I8j9SYZxekzQcUleMl58PGB39UhpMIV+vEuzMGoG+xRhUtc3oPngkC9kTQv7R+ojnwlurrla jj284vECjKdC1AjtQdIpjed51uwOwu/Qj6BKALy9A6StrBXeXJI1XwPXqilq9So3SuYFX512 JiyYXMJiORHfgYUsyyErFcuUM1RCDyKxvhzxjJ5dlHzEE7HYoXDsV2Po+Soyl8eovZBaVQyR vP/aJ468W6cWKuY0vUivi0v94tlJbKPEJK2ERGbMEX1pWmU0byz731jae1wRiSrgs2C1I4nN 4QVKt070ETOBbCS8rLf9RPfUMXnJHYK0TaNiX2ofHiHBqEfJHBq5+EME/v2/XNEVV9oOiXRF dfvVrKHz1JSIWjBTpMKJCaKv9uWcCGvzQDO//9ZIJAwGd0wsZA9uVEHgjj9URLpcTNd5ZNW4 iPiPH3lLLp3swRvyDwueChEpF58IuVWZ2of8gv6JzdOYBdtm8odafiP6rjB0o7NepCw3KQRa SJxj0negVgxwdAEPDcwWqDvZssUi9bgm/VyP1qcZ3SJ10U+gHA81vWrgl8QtZclBT3SCooIJ RToKgCxCL7evSiUl0w8ivlyg/H5cDDtSKCQPoTNkuaQxrNRI/XqKoSxuIN0Q9jcXqW+hMMCq nRCmSbBKpq+BmwT2ofJdxfCfT4WQsJd5nzMwtDz2uJZDTB3UFcfVQOXRkunZNFb1aEaJr06E 2AhE4dKSJon0SqVxWNPzNPFivk1PGXmlEbJ6/aAavHgxf9jFR2hYH2/vO85CIs6VUynTaPKS kgiB2yqPU8alhBaiWvebGBIFPzrHw59FFdZPwEtyYE3NKX+WNFVLFabnV4Uc+B4/OHA4iKTQ pY13caAXS+tl3cBv3YFsf+dPrR9ThU2Q1hNpu6pE9jtZ6YzhHzHH7VdbtLXaEnw4TVXl7TRf ekBeEhi06ZyJBYaZOl3aila0ti1Kus5hk+1AKAwn14EqF/IBl4lMFPw59fZWsTWYmLY2+NNC 4ecuUJpkBrui1WQu1D43Ff87IxSkkKghSAuzP2nvIugr1bMFkdhdFA00noHkbiVs99m3nw/Y IbpXRF8+7E7dD2JQefNN0RSgI4dTD7vqgftm0mzN+bWJclzRoHVUBHteioNlAhGQjtWDLC6h LtPpeBzynIxV5qPXasOixsGmMJ9xW3D/taBB6zEuOHgxMN4iloIsF+VMHkgHE5MvNoMzBHC5 fv2EcSRsIt00FqVAH/4TpbnoBVh/pZrjEmBn6Khkx6V5OrcjgNJbjsBWqL6Cgqu4KIlYQMih Bl05XSJIw4HF2pgqorfsGLTzx8C2lPj8QHj6d9li7O57jKqMEo7wrqv9R/vPFETp5IyHk3GW gE9yZa8Mq14zN/IZnvLL95ib48lVejBthPdYNdIcBQN7ThO231zuPHAxGHyPqnxpVylLZ6A8 xdtezx4sH4j078yItYC3fbxTXSnrhcVOyc1SQPLqEE3e+PwozMGoJzd5m/tuiDUuP/RSur2o vp2iUWZG8Gt1opxHRjdfSU+RCdYGxzsSS1kJYwA1nnzB27k3VH7Efpn4JjJGxtXwWBG0b3Cs i23ftb5w/VoIMS+BgPlWgawOpplgaEs++Tk1HjCTpnQOXnlMSR/1Z1Pj2mZUowT7kc7fXxtg g/Febo/zlEifq+XmMZbVH8w2Xb1Vmo41cvhULJZL4zZJu4zTQe7ymXe4FKi4OMuSHSlEntHc bUCLJEDHB6JuCbxsTRm2nDl95bqmmIU+t+vJSF+zSY7anj2incqeUQTjTwlpujBlyVdkioRf bTmEqyiGUGHpdcejuVi8TJ+cS8kIMKYSkWkxFlfgCLkVOA0tk0y5uQdPcGe1Tqe2MK8xzW7l uScpcCiRjkUVfZOvytXyoin+nL9+gniP1zvl0IXbiAMFKatHxuefZZJT7nURIV85RoAbU0Sa ytlDfhv95A5wzGVG8Nmk/WLyNC619SK8+K31BpHjXlHHOgiMzBp3wsu8WR6OR38z+4SSjfK7 txAdG0dZQxkNh0Cyx/hwZgQifNRGbAPb/x9EbJgd7JrTrrLxLGgrBUSExUXjI3OcDsU9bOZM BdeMD13ZXG/wNExRhYfKtnDEnynpFMSURd/JLMBJf3jp1A7e2qwvP22lCGu6zR4wV4BF/wnJ Xy/9JYoNiPy9IT43RlDD6TIHRzyGZkCjZEHRdGXXuK/5uFx/83d1UioNfy9DvBEnec/+Tg0o T2CEmdyKIpG3Ut5KnwbmFnjDtGEzElH9BAoeFCLhr05lE2VsL/d98Npn/moI76y9lr/NXyuM 6wR61Wr559Hnp1HF7fSR9bM1jk6tH2rwsK7hnsFFMG8A/ookiuIO/mg2RSAhqgqxLgGT6qTL S/4ahk2jXwbTB0xJuIDqFQEnpqwsXq5ahZs0HNnzBGEKygsFCWzwM0o8zANHRNOweM45Kfgj 1zbfjGGyWt1RHcuoXIMxyMpTjJlygN+yRiQUCvOC3slFiTtmSw6EkR3lThIA7yrpUzdC2au/ YOk5pRUf3qi8Ig47BvjA18XzgHGzcQzw2mrulziaQtCQU7VE4OJltM/tGoN6SAVzOsVh9SCT pOK7pR4KJjLgY+KigSvRsS1pOxK6u0K3GfDtTogeWLOiJUNJfgMsPjfA5rwOu62q0Ls4ICNQ gcZ7Xf/r8SsF6vpOTD1FAtPVV3YVUd0enfiWehplS8gNrapbW19/krnsrtmruIgVUnfEucgh kYlfS05aKi6XBtbsEFHFjxWtHKhZ8RB0m93GjuHGSXCl0+D2GsSgOc1IE/SW/+hvUljPE2Bz Wd24V5LxBUhVHEqBKFBZiPp1EF8kbi4jQCQEPQqbNznG6R+gIINzBtYt7LAIbD5gRfrery+X wf3q784kHG4djFLRWCorw45r94/dRIOCiUqhZmKOKrBo9W/os59YsptThJ18Dg2eFi0utwTA iELjLJBEeFy19C2TpE9lvssHAcVeqbmtOiU59f23k9vSXCPYOfLs+MnKu3vqYT/uvuBk4g0H BXdZeWVSfvfOPMhczim3O2UozB1GJvx7Ax0aVjnKroXAn03bLb75pbSA6sSdKrNtsja7zyYL pxTHUHGW77E3EXRY4o6j5IH/gdpwQCOLlwtGzQ+cwPSCSj/u60DXl44AilPyjmJicy3qF3HP kJR9b9PyiEVURZpDu6Z8stV+rvSC0BxVQt9m5bebWdl+swdJErT/gEPhuv1ZaOaCalYEnvJg X3B91RdC7cawE5nYd8H+To0ERgfb/yAVkfzVX9fUeMMoOqZoZhWDCegEkSa7qyxcHY09l3LH 2JCULprH3ltCmZD9mBjdBZod2C96/Wftv7gzUXzc94DFu6HC2FeG8NFVH0BPhRZZRKixR1ZN BCcKhrx+xisdPvf8P+p+nt6A+hLuQjqC9CcmRPIqLK2oUg/eyJuOdiWcDdre9l+S8BVT6tix pf3ogkGfeS16+SPbjYqIqm50gX04r0b3Y9/Vx7hI9S78yuRovljUFefuaSCbpvDQMMIHO4Ek xf3d78YCDB8ffGF7RyaiIaXIV8+eKXDjDoVegNVKELvRlHis7x1iPxnU/stbopjBx4WO40u4 MaTQHhc0Y+ZOsGFudWyahT0H4XrqVZOPJVm2qes8Tuoe8lN1vLmC4V1Jpjdw2gW/QOAi4rYE 4cFI1odzQZIM7ds/xkSuYP94lFGx6uHPcGgaFPzwBTeql2v+0Zvqoh5yaNwS4Agg71rUYMlt tDUsQ7R8efiHQjqya6uhR9WrbIKHCbKHgjIjqNzB9c0jngdtkopIpl0HCrrO+oXgRFioZLp7 mBdCVLmw8ET+qD4SZuMq9f6F3h2XGTzrCN0jxC1NeyLjwBUKv6S96eRvPHgsol0MibUeKo5h O9X17r2un12W1/ZeZPcpHmCX31DwB2ReXrYOWc9AFqVOJiyiVJDkH1dxdPRuqmWDU9i7FxoY nHMFMs4TzfG60KRqNgzjOtdxWIgxrz91bkEUjHeumYddoJUcrWuh7A7Wbsq3y3OQMNh05SZk GjURy1iXmrqyUllmzFLU6ZvBgIVBTkPQx4OX8obeAhLZduIj53mKX17xlV8Ccgim2aVN3NjA GS1zFsy2/jYnK62fsYJGQTAOrQVY8LcDzXZfpFS+/MXDJpTu/mnUxJuDLAEZyForiJygE/+J IR6IZNZfXISyV4MdJTKJxqiWZJzSdgY4RLGMsKAeh8iw6TNLOERWTd3hQDRKbcg2DAHDWk/i YXse9NkJJ9L8H9dU9zqjTFm8ryLhgdvK3DdNBCGAxOz+9ITt4NT4it7DYjiXZ7BL/uJs3sQX PePnkWwVZPod7v337Z9/KVx4SlN+fnCRGkOLo09UAXu8MVLOpG/VBQzhHKPNmHuBevK116hn d/uSz7N76XPCYyd18mbvi0PGvsFzy6/Hlr4UgUmpvPEcraF0edWEel7mZqFZtdgRDnlgejAP 8qyRxIADhZ+Xbgjk9EOgydc9DMX5BPFaQSHCzkMuxRfpt2HalqMwB3oJyVOjCxn7ywpBy/qr JSJrtdeIHEePuwnHVXTWNA+CyP0m7jJhAVvT7JF2+C82f3Sn8AKVXF68vG0iQrO88x56VaXr KafZfcsG1+2MjVc4GrjYALsjNNlCleVJKZSqe4X8irOxx4mXvR3L+SZoGkVlPTOqhZTabSVG rnCljBGnrYOwnTyrTWuBrj+Wq6TlVOgkERvsGGO+jsFTfcUg7Axi0qjILAbt69N0XjPoD3QE FfZMHBOrihBpLHLYw/gDn3QqS6bYXkZsBqJzTIIbcG1z5y9MQr55Vrdj8vcAbjRCyRsD/faI dpsDJtFMSCiSc7/D62cqWrLb0pxTD4wHGQTqPCVBx7BXagzF2ESwvAjtrk/md2JtVKz7pdjC Vf6C3Vu5OkXnohqz+mc86ed4VbB8NIL7EoxMFAWDxWoLYAkOaaw2+4sKBG7KXBZnn9+Q+r+w O5ONcM0baf3alHqfWnOQiudiCeqGXHEnyS/HPZK+NbU5ezX+hyZcUad5j4c/Jtx2hc9R1z12 jNXCEcR0y7opjotSZFU5gF16MITkH0O2eu6k35A2oLAuPaaegRKi4MdebV2FJCUhumauAdB8 h6CNga2w0Yf7PD5KtRBk0QLV2j2erKZTEmPH3IFj5oZrNL0fMueotH68xRKGfOat8BGqyrLW /oMiU5VhebYG6LW8Aqj6iMuthVe89HeQIiKxPtcymVCb4yrdmzhlBX2lDd7fkKY77g/AcwDF sc3HHUE+HsLDVzjsjMNopt6R5sO4sKTo3Bt7HxOVRbXxhr0X+MeZLcg2cEzv8PCXoGqC7PEh HHZvu0xreKluF7raFJ40viIrvL8PGMgHXqeodkR17etAb5K8fYw+8Pwgszc4AVZoIrU88iul OZyS43eEUqwQFdzahYRshTzGLRCGz6ROULyh78GMb91QCmCoItaKVA3VJlfIjdffXrgMKBgC pZA9y7RIooCDyVmiLhhL21B2NJoI3mnm+j05kCKlbdaBG+HHrIvTKrn+iHpfR6h79zpRxR1A 5NuAa5W9gwX0ULg2bWb7ecaqNfRIqZcbR815Fn3M6kc3dRy79sxoyL2PuDMUoILkNhP4148b Cc20RqpxWESnWr5g1UQE77F2doa2rAmTAJFuUi8Wnvme+p29aCB4MhyZ3FDr0Ejb3eQ07mJ1 6okqG+mpQww4SLiVqGFRbTas/y56SDf+/i8+4U2H9S+AxJKHFTgZYI5R56a3YOpb7BeK22ge p6xWxjRGwNSJAKN5nE5vRKxG4Ap96N4tECKIrkLew/7QqyKunkmEYZSuyRzMRSc2HuKBpw5R pfFNFGbTsu9UTTHt/yIuOxfMc5DrRMxk3uPcGOykgBOwqYTeqQDyFQBrW/Y8b++hmzKWHdw0 TOUSseoME/LqsFRmS3OKgTYwgEu1+vLY54gBkiz9KAL/+G617ilwqkGTzup2xwDeIlHKHQOk X+Ix/6gjfD+lzKxtDBv9q6DosC59bMl8DCOtyqWbxqKE+UhT1NwDxrfas7mNDKEUmG+3M11h +4ANT0PYHMOKkVKd+r1Ltl8kOeAJECt4WZjVqOrWuJKmWqJ3xt58fMZCpvXoRHPsbZdB+98Z YAT+klL8xsFnkodWEwU0JwxxdfOhz9xyJ8Fl9LMvOUMlyX9N+lqi2u32XKuEiaSE5aVExbgd jXI3QzWAhGVlumbjvA/bNFXYNJP/wBPvl8pJxm9Arvw4jgccNM/4wEM/St4YZ1wl17Y9Mz0h t45zpLIsy86GcAh3lY1TK9BKNFkPhghE6tQrpsHbiV166EHi2Zc+bkGGB8M8wZGxQt/M9gE3 5MLsVe+ctrvRWoH06ObKU3ZW0vdHf+F44f4VkgJ97Nt28ZlWN2Ex9baJUsbpz7ZVKvBio0bI tNq3npzvcYICobxaiJ3ocH+D/Er6UVWCWFFIK4oQLRKuFe3zLCoBLc0x93O8TAm3T9+E2XSt L1/oorMSI809NqRAxvSUn84PDe8qkn6On5X9Pi8ZbD+HKvw5zz+trH1izFfU8tvXaxpl3KTY 66Q0gyUo2pOP8tyn9kHRMHxamnRHDx3hHgqX9MllRtcafCj0vlMg9pXNe+qGJy8cmRUr/mlu jvczGyxvRIbvJVFHc0qaxis33sOSgg8LR7zYiyNcnXlHci2MneATj33KuJJU/VR4clPJCD55 CF1du7Tnjxx2Pjgex4bkmgRkc6HX8ivIb1b8EW2GVQsB8cRicNB3Dtj1YJLm1P1WUqazuc5h FTvVN96hnpLKQ5gyH30mVADfxiWmTSuOY+6Rfj/fjFZAvtEIru3zJomCeJLkiFrn5+Z5lwhC /4AoEwN2s7nNnq1fdZ6cY6N4mMT0C2Nq8/9zDuA3w1tQeYVM4pofncrcudNw6tcVFQhiT+AT 19+jJBjcqAt5eItSgxePaVF/V+iBnbZkV3c0i5yK8ujMRpEcjeZcc/+INNGZoMGOeOBD6w64 71oXZOt1u0+TZJF2GzQLxWELu1RtP67k0sq8ftrffQDI8nnXVafGc/1CuTi2jNHqVORc8iRc lMDbgs8ubXCOdGtpm7KE8qYOuxq9vjgBs6zppWbl6oKdjtg5vsTJURGv/f2+2ZXouGfAlGZi 03U/DydQwD9IxpoiY3I2smP62NN5zld2voj2kKdeJmtdizdRngPFQn0U7ZHR+BK7a21hmxcU Z8DWdBPjLW789uD0muG/jNwSoGX9dTXTLyf4H3ollBeIRSTKRxE5nmOIm5hVDwcxcjvliUQR WaA6ZHaskszCEXJs+x0iLHiIdzTVEB4K15CVnPWgiMZdb/RBQV/Tp+IOcOT7f2Bi6GHMrJbf vZaQU4c37mk+GEz86kBK9lUNH5ED6JMe1e6nnyx3lddKH6TG2KhELV3CpQw/1epQ3af3pXM2 kVQT+cVmuWAiM0SI4e+1PXUI+8kgJB1s1mU5JgcN2tVzrZJo+Po45IGyOigipAd8rPHdiGWJ GG9uP/sF77ugFMV08slH/+PEZ1Q8T0Q3TDMQAeG1kZb1E09XyNkwEEazpqoh0r37BvcRfUpE bfm3AEqiZ+/iHfGPrcMpGii//4EVWxZ8guxx9/+izD1oug8TN3EmHPQ73OvKrpNT7OVxKA65 gH6KvuiOaIOJGXQQNIA6eLhMRuEZOyYc5xlyQenKsny4XBh47PZzxnou8IS5XDHqYeChgTtV nsnGY66b5XcIuGxrVLD6jv9YzhGynbYSJV2PEzyXhrhXZjlKxp0lFUBjvg743A4OPKpiKvYp e/0CFqcb2tMjGpFJM5Mm/MSRDgHQUc/o/YejwdhtZM6tI0Mnhy6UCrwY06Ycikbx1ihfRjQD OU78VI45eQxS727N1D5vL7Fo2nHR9Wo+zcuyQkrydQfxWdp1eSWu8IZCaNTPGHUTQTkgdKZJ FEWVrFj7vwMrkaEgRQ1SHZEIbIk5VGP/Drar8nyn7QZzS2rJ4a2OEeRPlY8lXdb/fKiJ8a0q VAdBwixCvNMzaTEoZmlfDgZX7lJXZhllWB0VQ1C0hrDfhBgEep18ZwHmT5urqbDIkifppCU1 76fD9PHpGpzIsHS3fbAkNXOgzui3tKJJO9K2HlBasRZCv9rvBnH9Cmk4G2QS2bUEsWlW/t/H VeIh79uh3/Pxnw8leZZqeFj2Bpihk9sXBvXRAZtP6meFT7mb5kq8IlutP0cNKpKqleo1YXFs nTQzS/RlEi+uZcfEK0SsR2Pc3cxFsBNC3Rf36jBYMe9ch0hZgRW65mx8XdVXm2urpbVlkEiu b5CloABm3+hnsZjIo0UjHI+gbLKqVEV6HVjWFp7JvIgGnZpjFuuqla2u0fNRO+XETAAPkF0m +hw5Jn90qf+sLL3umwtrG0+gqP2EBIxFbCBAK3INXTqiD2duFtbNA3u1s07oDOHEMNSuTH3l pcMRfEFmI7nomI3+X+FrBFsimBK41hQ4Lts+hA56Ft1TFJ4z7linOiwC/xf0dionyFC5P6Y1 wd+czr2W8NqeckSwSDhlEWRPfmL67W13fcEttfex+OSWcDxv5eaUzCHM2VorWwmc0LopL0i4 eudN/Qw4PwZh5zOwpeoBxbysn6R5M3TAJSTvMadQznJgPP0i7YZHucw4weP+wR+JJTL9OPar PXibh5noNyOPGnLf6tvu4z5e/N3qVypJnvxQafYPgx1mn2IobNQm0TqVOD9wpkUtK5pgh+9e uSrpvutlGylk+Db2X5eRfAT7SBeItxnMsnV0dfQJsJqLh4uUdBOfmbDoHuUew/eW0qKIVMDb NjcdjtAUk9ZoDxCbQJCT8yp302KmHKB7C+dELZeMCT6mtXg1iRpJHj7fLwcrlzH/lx41H/IW a2M+XezjA1PeGLDQJlJaVf86b1nnFc9PP60/jaZduSZhIVLQebCJxY4UgUxMeHnP2BZXbKPd 9RiEVRonsKm/MpLlUi7ewAPhWhARTETnv0slGwPdCFdEtzu/GbMN9zov4NkYmdx86fZIdqPz L+Vmr6T12hRMTiQeCP1H+hJjsStKFZzpT3cC4QhQiTf0NTX7dUaqe8/gMtHRyosfuowzF65O PfluVjwx0+d+CUgdGI+8Y9aiMXvF3Sl42joXipGvjNXW+LMNChphb8+98ABXO7nk0Xjmz2Rt 95ZoCGSu4iU4bpEV1vCUxXjMGi9UcQjo8jDJo4CE5VPeFW2sQFfUfwDhN+r79gkw8q3CP+ob tex6Ve7Qxhwdsv1L9TB14aBeOmJQ2WGhIvFsStdPAaEkWUdKyI2bjW8Il/u3sdFk/zKhzxG1 QtYJ0GT2PfwhrlMBlrrWVPbjsQCQtWs5XWmqnuxWVRI1T9Nmp0Jx8o9c0+w4Zl4OShvu+BFT fPbOfwZi54sX9s7nUjA2n7yI3A0nvVCk23AHGwUaWa9KL7Yf1fEZVKO8MVPA7KONsTxjlOv2 0yLxQeE25iF5o42bAhZURDvqamf6Beq9Ztx8krZGIuiWF4WGrlP9hlwMQCuyOmtitEB885hS Nr+X7blxpjJ32TeXqrSoCQYAtnHPz7eKWdc/xeE8WQdQNqOg1ambATpAb0t9d3O1CUyFAERc gtuMkMcscnF/ethO+xUYyTXXMg9NZsI+gYNyrJrt1/i7beyTRmjJtEX/f/ZoXYHldh8n+ffZ bs7GSZhkVltoGgpB75vd3ZCLOeFDIMUAS2YZ9hkdyichG97yGKEr1ANXnbQrerlUTDGampM5 566tWCu49MC7B6Y4HReZgwCDe61ZZui4E4yeGCMFtClYD9vrgH7WsnxavsPl7QBpsSUGZ1vA FFJkLTIFd5j4yGi4qpU4LQ5O4IGgxLWAxxzYLJL6vRpAsVFlAJBF678JXpQLHwhQ4fvtErZD 6gHWvqT1IBBJK2EeR4GnvB/QrxzSzG0Afdz67BmNaK0HxRgRY5F3e3rpELv9dqBI1uKB7aDi 9VNeQwHN8U/euFV3g3GPRXGLVik3rRnCBBpZ9OWOHh5sPhdpppHLWc+da+cllcG9vhayXqii wKUem/KqLBgvv4OU0Qn5puBRNSyy+Y1tXaiEaw55MM9qhrdFHaWlxMrVrZao+QJc6O2sCqKV B8dSkt51RoMmq8VNg7ocp1za9RbhsmUaXzYB72fc4PcIF/NxKbNspRjXlIC0sG4BOsRgT82y J/ZT3SRSSWbh537RukvDWev4XQcG/KJm7ITLFdvXWFjep0b+DsYP8OemiuGqNUVlIgmQbAkK yhL6nBC9+zOVjTqb9Jc5Df942daz4bZ9//oi2kYowBDYOnMvTCuEv7AdXCs/F2d6B7JKaHhQ Acxb+3HuSx7z7YGHMnT/nfe8a82Xcz8Ih0AdzjT+3csT3UKlRrgotPivxHd50hujT3JiMXyO fjQIMYrNLFX6Kik/R69Nkj+g7r4BSD/P2D+03f5h1yH2KIT8UqFwXsiJL4fgScDMRveD6plu CM+c2Vi+KOs8FPcY10fD+AbPDWov9GVbI74eOJ64GyIfzsw5S/VnWocR7SOVm5YLVR1eNv6E 5GvgQ+CQby0JQYuUUei3QCyP/xBtBaHkJKg9e6PFaogVsPZ1tQyXFVerwiUgQfo3bVVht513 v/A3+jhf43I9m0kHNhIfn1J8Yvfalc/cyZo0lrnyJDzh1j+zywzRKxk/qVKN0ngyPenpGwPA KsG2BUwAkF+eR04OqR3Uf6fZttnqaAHqLYequ3I2pRCIVjMGKCQ+JrHvkDCjtsLXyIHNDAQI 7tlPZIN+Kii2Sj4UasdNAsz/CvtOop3vM9wllpyO11sjpEHPUlow1WGmCHiGkJlUwSs9jMhB A36KHD5Z9ZXYMrZ++hJ4vSTvS2vUKn0APnL22UOreh/ppIwUTmc1oATxTjIJasdZbPWLKRV5 tJMz4Ijd14R0q3HX81jfPgCrm0LEmcYoF+qxG/pkBfh8p4dJjPCybRLprvZp12wRxzLkgPAr /mt7ulLyv/BWT+5sxW8mIG2VG/Ur0Dn1YNoQY/C+roYaEvPSGOBdD3RxOxhlMUHKHDSHmm/t SDN8dBX/fchIHujxsWumObEl0Wgpe5K0J7bwFgIwoi1l9LYC35Q2q61OAerhk2YVAxp70e+z apD7wIrr4ZUZFOYvjEyk3NaRidC6oTQhbLrh6E/8o/xZnKP6tt0Qs+o3xzaTMm7QolRQU2Q1 sL+xeLm5cceTtAgQnhUXd+a4oRhHcWUBCVYjCq4xy1MHka03//TN0mh9XEc2qk+kLK1Yqia+ IAe8KWdd5Vk5pZi7FQoUSmue2NB/5dR0EruShcX3DxnR7G8QbJYWaudcB1Rb1/TkD7Rog8A/ EVNCKBr2f8vmoq7GxEZl3+vQBDYLfwey7IdYV3qNAjQ3oXMsICna8sOTYeDb5WEIXsYUcjZE XK2B3Hs8qXEoTXpzQbsGgkf54T9T5dWHc5LGggQ0w9MbIHcDPZpiNM/tRtkqhtPolEM7Enut 2b5Pfh+OXdioyqo+joadKBNa2O6OXF1Bw2k4WdkJwLvIeQdKsCki/sCfrDnGYf7+qH5UZztg GLLnfPXHU7NZXc7tE6mCAxUK4NaKfGfEPpNVRv/aZty51dVLLxerxo2Gadum3h5nAPx6nh2F 3WWaFp9oEBxeuvF6filBvgUS3AF2HaZG6nKS/+KoCOSsJjsMR2xkAdACFEh6FOmPDpwtnYag hl8y5o2E5NDxlc7Z1DT51FDcCOPjTYukuAEOnUWBCL6ISD0e5E0iq6fg4f6ZgFWZDa8HgvG+ u9NmqcZDup52WkUf2IskKPtZf3FDtD6q4tPeIy9mXpgZG3o6E2MZPbADld/VtUBqR6g3jCqR dxQn1u4PkH+ChZW68BmTYBgCqCzR40K4MoxocAbwmYW9mXvJvAMu0g+9ou1/d++AwsmLZR8+ 3S99fQn78ANsCo0fdz++jU2pu4dHC1nCjeiBHK0SBm3g9XACZgzaAINlzbxoa1M62MOKVo9s zE8quRd9nScjiOKhUeqwH/UI4JYOF/7p7/BulrIoY3no6pkkyK7q+aE86G9R52X6vHhOeAOs fRVYuwMIi7gxphwLhijIBafVeltkwH47W76YYkbBDwS4Rh4gVsFm6HXPF+8MgaOtLP1KDQS2 7Y4m5ihUM2upXMcWqZ0DL0WLW5uCk39zanztt7p2YHBE5uGPaGBCwtOC03mWhhNl3U7lJ/RI vTykuuOqdrS9Yh1d/E2j9L3+LbU1+kOUFYWoxpHCphyP6dWLWI8Ui9RGQky2TbvlhiapNrRm hfUOuzRQeH3RHB42fy7u0qS7rA7VyzJgf0pE+YVHApEFGUpWHp6miws/8GJ+854Oy68EznjO j7q+GXBS8S8Sc5T5Wt1nt6gShfYRML1ziAzzfdjX5krS6jX/jYzP7tJIDihWpZT9Hd1T3wpA n3hzVARgn5IKpLcNF8w9WJ+ONoLIVXRm6Qwa3jB1+TES/IkM8u52OGZKeURBHuJz0fwsEkFK Fs9pqu15aKHcxJmp1XFYG4zMpK34pELt5CngqegT4mYsF9uK7NcjfoLc0nVZM5OPGTLaPSpw zM7cAoPUCukRGUUg8Jxyj7b24egvl5Wlenqot/yH7QMFWBfNjBCK6huGANgKFRql7rA39sZh aPxuStbN6zjTEgB+VNEidVozhM6ZIONOiqxPi6uSf1CRh3JCufxhoPoTlSznwjeey6mSENhO eb6xeVrd95FPjzQ1w93j6nOl+lOkFEr30cLAOMCYvOBKtTh1Rw8Y1NofWhbG1/ht/XjzAHnS FPAubGMHXTO6kfYKRQ/bi+kpwx9atEYdW+BLZKy6mxKra60R9xQVm2NnxQ6ovVxUVIsqLn0m dPFZ65P260d68ZcXUJw3qezLgxJNzDlgCjlCS0PbnIpaH4V1s6ruQkbTb0wp/p1FxQDSd0h1 odZ4e9LaqLbQMKNupu0mDzUrQK3LaQVkNXAxvaH3KEWmpV2w//e3Iv59H7Fzf52Qp4OIxFpY X9bYkLJa4WnheLpPT1GvEONt/4uxlMMbHPW+Vef6Kmt5MgbhT9a4cztEu1o4j64jThpijUrj Ru/ayi9RKfPpm1869tflpVTDs3BkHKZF1IgqXZpaXlW32H7nKSI/iaI42n1rXwZaQBqnUV9t WWLKSov/IENLTP6ZxTN/T3wQEEpAI3YbTrwvH+7FLUWs3169HH7DcZ/gs0apDzwUmiPXbhNd 1taVHnE+/frv4qAY7HTholaeYMNGgRWYFYcFwVQvyEdqu3bVSILC9ZP9TVJawwJLzQS65t+5 C4x9d8Oo14YgYrM90O3hmXp8r3PvAY85q5RhjNIu6eSK3Gem0zMuytQQGbQ9ZlES2iyFwskJ K+R6JzPv0WMTkWMeH5+SNoi6kZErKkR4vPQiFmNbh4obU/tjM//+VmBdu9E1jjcwEF3Ylkdv cwnZ7gFYCoAZxq7FxCjLKhZca+Qf7GC5C4y/vpalJN0r4RuF4RZyvhoOl9zt6pY9gQVvwJMX wiefTxvcDiLIKySMIIZucGMfnLa49alb8hVmgKHZWw66n2wvI2tMYKwD3HcjWlIuNoedATOV s7lH/FOO1USD46/OwyQI+MeCl/2Y/Agp8oKYbaXBNcDQiNUeNkw/tO3wfPQXh8/4nkdlsmGd 6v10gGe5QpQOgZ/aNK2iQh0OtrsrsDxjfnhvGmxDRlx/KLQ8wAdGD4I6giJIu8jg89llQ5LR 6IwBiv8Apa0GyfkwfCt+9ly2cQHh97m9qyO0GpffUs4ukz5HFadJ6R5If4mE7tqdZQ2M71jR cB4e20o1ROs/z+eOIHy+ttEOJhBHFZTWlYtEEaldjK74SXtQjXtZgdMjIYTmyxAGRdrzPI1J Zjfj0l3BHFmfMFXruGB50ixHVeIOLgLI9E7diEHCbFjc0+a7ye5T+K2T+Uh4rY1a7dM5q6/u VOwzgw3DiD9s2z8AsYSg+AALPFPJ9SGFYgPL/ilKXUoiifW8JJxOy3ldMpBQeivqLXVVxIR5 Fawh0U1IT87l8f6XIW9mFQtyj4zqWBr0CLv6kQ6HZrIGQ/WxaV8+EouICUh/C7AvZ4hqqrAy QxDeeWiMansaxkKvggY1F6mhejUVPOY3LGTP/cHJbOtfYL5Xa18vNVZpesKYyAcSnTjaY68N LZ1SgM2h74FKhA723KnalDd7v/BHPbKQQqJbuiPoDvE8hkoIZqPJvo+Z+Rex5MjevJzjVDOH xYh4tOV+IZnbwy4cJ0wU3org51xx54AEToefeuvy0Kg4HsgQcto+SAFiWf+bJE8w4xYN9rbr jQf3a7zcehlrBP7/NFkBrdq+zQD/HQK9Bm2Pxnxc0dVqxKW4vzPTByrE2pZP4YrB9TZ9BuR8 a6lDueLHelfjRigwzzVtxUyht+j1WZOx/bt2C1KWZGr5H1/y7jitUshk00OxyklHjR8GPnT1 z7CB79ObRxZb23UhUUOu+oE42hagEuRelGTtpCH6IWSeE3Pt2XRRRk8hNbay3gsCOf87RyqE 6KC/BQDroKmOyze5Zbdq0Ikky8BMw7HTsKUE1qgKUk9X/lMWSAdxzbZ2cmfznRz2bJa2OmdD pB875JPfgTfqqsEW5HIvFZyeezSVvYrMjetlJ+JPGSyIuAytBVjhGIX70BR1HNttwbCtk5ry tHsy73EiWMIvLMzgAVXgdxfbeIgCq6AxupuJlnr4fXYRNaD3lLxZ+n+I4TU6njL0ElT8eARv H+a/GXb11DXRGxRIyZBDq2g7/R0xuIfzL7Yk8IQWwtmsYtCAsclVzBdqKusLgrD5zEklLAU0 A6om3Tv0H4jSWhf6+ggjZe5LoR/kLnCljrFG9U8yHfk0VDIdQpzTBLldUN0IrSwitHdZ44ms /5Bpe2UQ8WVlCJHett4fBzYsG+sANcqmS1SVmyUbucYgB5EnkglOULaRzIltRxBjGBaf+n8r O0zY+E8L40ADV51W44XS7qXYbs/p1pGGj8oYWbbToVIXr6P1AX0IjfvbH8r6w0a/XPCt/gpu f1WLztBuXQHfE8+jnFB6m3tW1/OmdieZPcywv4HF8ou8veOpKuFIU3t9usjo8/4Qc1y4a1YK /2zVxGcIfNVP6rGkV2ol9PSkKiQQ50lueraABKlwDn6uhWashHdkPRGxc7kvWIaZyV/u3ee3 yigDOideKK1q+rfsY5V9LtIh/cFo7peull2DXnwEratk2cic9AwcRndC+rrhaf/lRJdeZvse okePdpe+kuSwiDtp8t80tLB7IjL2t3iORzoIfgMtDYfAgVxQKVuQSiPvXuVm/N/YsyZv508l JhFKqXa0ZSPt1fw07Mk4cL3t0xyLbAE2F+IS/W87BxhFcF4UU97m2OtugBwiI/4KhNGGDRG2 bXd8undTtfdaxoPqfBs948Dxu+WPKmvHoBIdQts4h0p71aVp9JO02TS/ibcQ5/ix/OrRZvQV Z3i25qaamgt88PWhdKBoQezbxdQ/9c2mgHDYWTsB7gOU2zvTUOt9anvCm4TMZHvJGiulplOq WTAGynRXT13sEAlu0TyMtBbUeH0CLZMnbF2lLrUJka+eLOBk7ilUX647tGiA9qVkLGaA6ZrA oarpNUG3wSLnKcM+Hdu9Z9593iM3hsMZ2QKgNLqDBdIH/NiAEEK726X65ZIlHfARmtsaBCR9 4XwegczlSwMjL3vwpT7Ljstna0UrYFm9Zn0pqzxAj5ZTXpBxZ7pIw1Gpsn1qiPtL83l4Paca /Hb/ClIeVP1cMpJbLSJuiQm38YrIZT5p06TKkuP0+wV5zIm0Zu8PqeGWLDjUWuvSBU2fhfG+ zDc3ZFcV2Um2FpuAlRPt6OYFe765o5STCFG7TmN2IR4eenkuedcVA8vz5T31lkNvXPBq5WCL Xb4u58EjVVOjLgwfBpAhE7bAYAZ6HKpTk9gqhr8Pxj9lIrC1+fox9OzdDsYrR96FSuI3DUXW hdXSRUDkBb7nAaZFmcQiLtBvKgYajkNquQbaVZbvoWo0OT5Bm5QVQ8fY1cBksHE5DbAcmm5v yVJpmB/2tJrRfVBbmZVMRjF8WBh9/9c/Kwm0b6YVgdOozz45/HC5zw//o3HTOTiOYCIy69XN GOBjSCEUR0MFr4Lh4pChjZVX+/+iFLuJDHduFgTmRsfF22HsbxPi4anmic0I6RTotHy6pQVT iZJh6G9Deq6lTkZov1+jcRo7Oxoai5qUPsc4Ethksp3V9CdkIniaOIVS2COu4hMJZtmkE7Na 0x8+IGH8pwPkQDY1eBe/lt660MwhR8G5p9UJimTi5cCfpQdX+63E55qkFAkHh68gBang1yYz 0GJYIVr9dBw3jYVhA+vtAFZcO8OdpNJHIKO/pW9rWA0QUtq3ab6SM9zLW2J3UCU24F8z/t86 blLh8MFZR2WR7YCtops/eWPi/Fnl1pYCYSlt1BvZGXcEOebOaHQ7g3wedkp31HBYi6UKJSEX ReQbi2MMgdpjhHpqEq8UPwJ7t+sMBPJBG9vXS/79r3xfc8c18xr5ryn3NU//t4VAArCd9Gg6 szOGTFE7qdFr1OoG3dbwjfzvwNQn4I0vv6nuJ5cWfA3ZKbXDWPqotgk9sPh6ma0DgXQEn08P HlEjK4sanDYYdnCzGpFeq/24iQXZARgmyePIR+Lt3YVC/2MsbfEIM1UlsaKoU57dzuXBt6dt kPkU2tAJrPbkSnJ6mwxXCb8jOo9q0uqEcZv8I6drMLls9d+cal+q539O2z5N8vK75nVnPVRw Q5+V1Micbh4nZgqNE4u72yH+evjK0Hk1S5IZaJcEemZ8v91BGUKXS309C5GI0tFPG/7prQXl dRlwhfIQUHqrQ2ztHFeE69RcBA2WgHMc16uCaHOnWb1G8B6f492+04FOpVQtTrlfguO893lz mKkqujlxwigvOTXRQPo+1Z8h2G3bQTM7lM4zVkIJKMBhoLrbye4pHLQ+rQMu8mkFt2skqMUX uALYKcDMNGJtt+JBNRLJ8Dt0GvMl1u90uq898y6AAa45V7CkdfeNjX22/ioeQQlst+ryNUoM aTiyM28ltvZNKzeYcWQeg1RSnwJeNsAr5nVhSJ6uhDQhbKUDSPVij9/m6xdlj4YgfnjxiBct f11lZA4PKvUS9rM3XN4A9scOlNs/PdCFNfDbOcfaQxPlKyrhBvGZdN1QmrBrODgF0hcCdWdZ bnW/bCxsTfU01fWhT1WwAeMo401QWZHVkF/+L3r38yOKeLVKjVfDQL7S+M15qJIflsPvF2sf wPy4BSNolx4Dyh5WfFTqeqLHoC6IrC/YbUq6UpsO1cATpagkf+RTeGdnXPuSircAGOKXh/gI NCk8FdIRfUA40Nj5vuDZOO6CHijy2udwfkPBDQuKRnIOfGSKj1plwmhrp6nUIvWc6movd3r7 WcLAhJ1bPtb+g/yK5L71RzLHdq5fmvoK90BLcz2o5eYNfRTurlbuiGuIFSUCDIC0+7w9Ezco gXmTp0FCuUgMjvD2Fbd2YVRSukmdvuoF2d32hyugjCbCbpfMoURMbk2zilLF1QL2asYPWLoA vYlks7GPssxdPUjT9v8piUggYAfdEkN2cg8HsUwmi1GCETdXOgnOyy9vAfNBf5+UDosdq27F SMJSTJYfMhut3UM7uKNP9RwM48pg9zLHmYtzwKYMbbGxu65B6VuE5xh6lhSOAtI1wWEjpMos cxgis4SxU3BYuDE3z/7kt/xWi9fgpW7xol7VqhSZ8jjwp0w4ViAWoT4MbyIDEx6qLvonZxsd QfH0R59oYAB0IFJEFCGM9Of/5MmqtX2ebXx2J6aL7hnJgdLprM/DznjNQlVMGu+a5aDMIgxG Gsk9T11JS1JtxE7VOzcFyX2cNE/B0x9NIEfc8sA8Cl9qPAbf2n3Oa8Bp1U9FHXO6dhH6sdvv YvwEVhrFPVy8MaIM51dedLa8uzOdnZwz+6pIzttkKVE+/UbIIQL/MvXInHejFN3d0rbrQhgG AMigDbPL3e88roa5iXis3lBMaY97nP6wo5JI+gAOC/8qA+3ODJ/xKOljU66S9yVAJJP448/X UNm1W/bepDevZv3jYSNBTp5oLApIIovbJFG++lku+oloivD+DoV8iwA7UzMhAGPK7ygvw3S9 StJQ4xDGqn+w3WtkDTwu5rzez1pg+nab11T9tvSAarg0+a70HOaWit/lpeKI5jK9+c7so4/L CaWGgFwSLAwqjFFO+hIj4oXiv1d8/Dl4WGkJD4YNaPnILWGmqUvn/pzbcN2YwYLa2FH9eNO5 eijE9tzKFRLdjRuDGywPsrvy8A737ItQ8wCUiJRUPonlvFrGldmEgEcr6INvGJNmLJl+jU3t EY0lV1FmbRmCWn4+JPOmc/18+R6qpzta2nen1Uq09wS0PZ/CJhRUDsyiGD6XOBGfQCgIFKyA kfcIvdZKF4Lnwp54YaB0X9kxtOBM0Q8nUCkSOIR1/880JVFuUIYpgVGqfECCVZicqkFPc0UR fLy9yvcYYY8OXCyJ5xoTV0SEEx3Y8A8K5nXyC+8/oPg3F3iYTad9iBpb03mTyWkSlge7O/8R u0hix4/H82tTloL912JovTN370Fktx9Z58WacxtCp3S4fFACEhuHCMIGxxz5SEI360DmnDhT D6d3plRBHQeGOgyPgV+lG2sUBrwN5NWtM00LKgo/GxYbZzPgISurP5Gm6KFfqhOCb6Dhn3dV CwQeRfahQcvLCnmZexbWIHVw+O9eXXY03bo2PUAWL9GaNQGZWNgDtJGT8HkNQJJGNRvX9M59 /zC4UOzjyptoUc4q1pL1MAgpYN2s+D+qZeXSdHBC2GWn9bcMCv6x9vwaeg3ZjGxhukTBJtti Jvs5dduuHc13SlR7Cpcs8ts1X7R45QJbvHrTlqJMnQvNiBjbOLW5oXiUZhxXi/9tUvKM/oVF gjyicWescwdSO7yk6o+MBb+UZzdghgT1MmNiyAAa7LRMqbzxD0s6CGjZtThFt2kzN576FaFI NUMkhuWnqHNdMRlRmwDTQ+KlR15MZChw8KZ6rQvwnVhvkz604Ra96YtRZozpvVkRHb5oTfgC QvsqQaLhlbUXGzz3q6N463WY8tOapk4esji0Y4J1Cg6+ctsF9HTnjJVS4rHr54Z58ks23cY2 4JTY5nTYk+W1JHGz7h5TP0YwKtUhyQ6bJzaMHILuAh+n6B8yyUYTni9uU3YKKyV9ETTSpCZc Ed97EWQyoTtGG9AP1umYI30ysqidoEtKAyFW3+x7XIAkzAiH8F2mEqhym7WwKrKNimn3WLIB 529eaEou+JXHPdXqZhTZHLdZ1Djf7jKSO7kcfinJsZNYg3B/x8nF11no3Jwuf+q1IHLpM0nF g5Uyu42fan18pifZkL9Ncer3fBrpiUIDBoxVG0nRbst+iqRSJaJQQpYH5wj1OGcykbzwTabl alC8JodUGT4oDyyDPqKwwUxrrrCj/edDX9zvkf60FOq71eJ2z2BMxc6Wvx7TBAHxKn9B3EG7 sYCRf712iBs7Puel16Ar0edpZzezQVz7NlpVUhOKWoj5d5CavJdDgcYM4tYRhQUt4BT8rdYX 1qCbQqrMjKlgU+8BOTNxfXlTHsJqVlTRoypSVWFfqeQQAljbyMgAQQ2EUuOc0VgZJzyLfUBI ipeGEWIUBcn1NPDUA+UFbQRDEvNoXzLwKDm+WmUIrtCoqRCX/Hzb2aVrT10RMF1Nkjm1KDoW NBv4vn/HxZEAIZHrykbfs3oHTeDJ6T4NOwQwpLJ4QYDCxWclEqaCbrnJYlb5iJ8ElbJElrHO xdwbVniJ5owFG8sRL3EXfgnBhDvMLgsLuhJa8Bpz7b1YfPm2zX8hGVZwYPMbHX2jW7Xhw1+B aaG3G8XUgC7tF1bx0t6SfjbA9gjo1Uo6vjJR2vp7bBzXaqNvIcR36HKm1XmLH6ZNw35XSpqd T0xOwEg3yUDDjwMZlThLUFcIZRdpU/v9gXCIn9KjSrrFBHcoLdLGWnwsUfFLxTQKEN0l1XNj v8LW31QDRO7ZpqLgAU9osltOFz/mi9ixofTo0NpCCsVkfb1vta6GtYI03rnZqoh7ENqLsaVC +/2JbkTXdVluoAEQ+oLJ9MXWc/SAV0LvoqpQ1iXnIv4peikHZ3hOcEpyUbuJf2hX8K+kE+Nw yu8WApTg2u5IFdKFxjx3Ztb1Yn96LaraM1jKz23Q6G/ZbeKgj5BFOH5LGnLP1K+U1JRg/hf/ SC7fDyse/PlM+W7/09aaQgVlCGIw+MHzmbVzTq8rdkqD39/36brLz1/ZPqeHv4geaAGPNFqR w6oFpTVKFq2AYYzCNmefe4LEuPkitdHBkzFkX6tGH2MoSBbEzeNsCW7fZO5+tesvonZqIk5K tb4kiLShQNSqxtBGI6qg4YzXk/8rX11GsV+BWtEZBgH7jSWdie1KcmYhkVnLUDK5W0R2Ytm8 u9JPcMYgk9anXEXl+602LEmBFUPT/yemgSmHwUbFrddkfev4ulwr3Kq8YcwO19SXroNzK6JR ZVF1tkprDcUDTr+8o6PeXM7O26eWvqJlbKE6v6ACjx2xqSyc/GGT1ij9vZOrc5vpphKaHGfe HqKTJ+0k2e1P8wLDq1ExEgbqxKeuL9oeU8xqAa7jeL557Jf41goxJsFQNo/4Brxg7dEwsvBi wjYrrwnPDpROv9qseMyK/pxfNa1+p1PTSrPGZIufNU8RHF18ScVhmEHSLaCtLtcT6+ZsTHwa mM7ikHLvs22emhRtxX7372phZEpKa9iyOXGbkzXuZEN5Lfg2zt56qAPhS9B5bvVixkkwBuQ6 ErE75M1aWhcNFVXbvJuISPU5x4XzNCXOwSLv3EFBUsCGUHycR5AC/WEGYFoC1jhUjO7SECG5 xaFUTd1JSUC9Kqhe99ALsJmpWWr4G0wNL2tWphG0BcQO4SjMIXeumZpSpSpZEyjKYXKh4cVY 5uJCdXw6vlPdp9birGMUBlFje6Nj4SgKWo+TSCxKLjNK0aP7IQcYg4wV1l3N/6IbKsIL7ZwK YtUnUi6gw4o3GyRB72WZOkJZwbiVA7YPYCYIKAsjC8uiXbORFqGWhFD0bH7TSCqzljVYaIr+ l/I0iyOStawfVjW7MSOWdkitCqBlN0W3dC/YF30XS/FGBEyBkeAIdpp20wXuOoxPtmPhA8KK ZsyXAD7dBFyt3EitcglyHbRrtisesYg7gr+bEYdyFiXGKa1PQ6AWDsUcJVS0omVspis26OSu FdUX7tw9de1GKUSVLQuudPcjb1PKRv9E8PWXBdsbpydl6wEkx/BDl3humVljQIep06pUmPvx wLjoPz/Jrg7ENotr/r3MxE3SxWqu4oXmDyqMhL37OgTGVjkd24I5qtVk///7kon47emqKnuC 7bMekqs6dKMYTSZeCBr0yuh2MiCJqWnXaZm+/UANhlUqDHOeS0TaoQgWUT5DUB6i+jF2krF1 KFB4tCiTimacOoLbWCLjrbUXGDldAeWl68spXPM7zYtXRJljSMGtxKfgJ03fKQC0+mfWmGJU lo4gf7j+GSsqJnbjwNEJULgnBrSoMB4rru23p5IfqLCqSiKsAGYRWd3Yat1Sa05rt9z0GOc6 zEIk7Drm5GsjajeZgtQDfYHFO/S+kHydxnDadoGKHntzzF93aw16uCQL6ueWZx6jtjHfuH6W eJqmONu6GhYL5q88OgErQoIe93+1boio1MVQAb+H4+F7rSfSXKmw9L+ZmZv1DqkKlOUaJPZb +GE64Hhf1Iy3+L539hjkCviluLUEC6ZTcByXk25Pmyct23E8ZD5rZxoMD/Xkj96QyM5yUh+a aGn3vnmjqjNhyHT5Y09jvcKWX2F3A3RBdBo//cVe2FfKesGuPj15JhlZi4MMydx08bR91II1 ham/QurE9tSNkEt3Nhu73/7s0q2i6PBz+coGzH22V2tYeKdZq3l3Wb3H5WAATLq3cAU5XDMm U8WxTqGTVQkKzZFFh8xv8Rv01hsO0P8ThXuQ38Fuato76WiyeZtozLT7reSMqZ2cYAEeOhwe MacWsH2UufRYhiBvPwHcYpC3E4UFwiL9Jun/EWCT3Gq7GMRHgtaL9bmo46L+hAguU7I5Q9Bz v78r/3KL8ZZ4TG5T5Lz73IEKmU8CIPuHW6GHWc4c74TAhwLnje6gwlAYMdqoViffCAwL/3Cb mlexjGB8fnURwW6EspFV/mDv78fJK7TDSg2k62MSenMFkhsCgupfmuk0ErmRV4why553u/LQ EnotCPuqKBGh+gg8EL2dLhOSsnj4YNNYBt3PDtTxlJmmd/m13AnDJBlGt6RPWoHiNTjr+5pI pKFhA/Dwu73Ifi/zV5VLUCqZatCdWD+IrVLR9caAmg3pMgAjPW0zbtlOw1f8I2rUyIpfEvkx CBwpoCtlEsPoXSGoaFVC3b3ys9CD3PRuTT4ms7mOtr829zAVspsuUCFam2CJ0EUnLFgU03x5 Gjr8pGhGfq1cFTHtWDPq4iXrqjWlscrOaZ91ec3i+bRHCepj5aWR4OYZ4fT06rX2vXCR9oJD VnowUgOb9Om/Te9RzQqvxcoPnc8SPfsVuyMKzkLG9P8THDldz7qPhoLS7kFOFsUFPc2jGHdi nEwGDq6AcFs0/5PIjKy5O3mEmEN7aJ8z9QH8eJsSOJHwiNkzPdUms3ExuDeJTJ6nhVM1oaEh YFBNeJ+3lSTIZrftLJvf3TRNHtptKrqLy3C/VsPOu1nupUnaN3Q6a2yGc/Q9vncmut6GqyDY HXCmf5IiUQWdJnivy9Bwh86rs+zDui2nFJHiWNx8N8gG5jxw8jiz30ST4hx2fHOOY6yER5g7 SdkVz40rARkee0L15/0MeYrJzpK9ArptOe4Wj8TQhTLk0Hm5fnj1GZSIirQcR/dPsS04K+Mp AHCqFlhwHyWVkPPRS+9rpm6EBx4KSkjlBT/TVIsU9TVoibItQjGVQVS7u48LWApferJ3xnya sMOKfpHG06WFQKq3JArMLz8HMLH+0CRdGzpkKM3a7ckCIykb+vqDY6P/sk2YmCme0fi9vCSW tE0JF9DUmMmmMlEu2VYHDIpYWDh5zLFH9bu0owKs+FhY0Nal+1DAQOjFLo0UsMUG79Vheq6i GKV8nOiGTCh5mVJiAcyK4G/+7u6BHkPAncw7qeo/vSXTicCXh3LQlVdf2dap7iifK3mn6DN3 6uYTaWcviq6vPF/UmVEVlkG7Rwgbcw0HBf6XlpfYA4e+y5SgBbji4clP4P3+lq2S8AhFd0YD TJeSaL6AjkCR8UVIL4vlagW1xZB2iM0TUUBQltfdKSAMCm3MmCGh3G6oC5UqTnKGoXoGK7Q4 UV2X+xu6Uo2CqprZWrCAtnMtNBF9ryXK8WR21pzJ1DSts8OSx6/81PPCRwxVb9IkRnd4eUNb hGdOxRoP3Ep/SxqL2wY38Ai437atcRCZzJX7e3bd3uoMn1FhCTA7dpvseDxZwZdItHyginzU XDgjBukWjgRboJtGRCIbNzo+viUu88ReWxMGLb6G0MixuoSbImfrSopwwmSCNagWiTRngtFi JctgT6RQUyGNCWbxWkIAQJ5fDkLxtumzmjbpyPGZZpz22owqL4LZYAdRDPwMQ7aevxTunfyZ tLPz0f7WBUGmVEQ2cu+k9cKUngnnG2pIZElKSMzPfijWT8zdGWa8BxBE8mpfRhWRlFMwHwhY OYRbZfSikoxpyagKwlibuzk9bcece5PUW/slhoC5kfGmhgZOCh+94wYBgiTWAkVkuVZ2qY8m UXNb8DBowp9SLhCOSDIqbAcbCTcgkhlVHlNIcUkj4/kWjozYhn4oa2hLiqA86EJ95m13lgdD oNv+GuDm8rptXshyms+gbtEr6JNCIU00xT2ZZvc3ixoOjTVdcHSyIUO/PzfOZB4glrM9nRG1 hHSNntjf9Xuay0CK91BQGGqks4a/T5AQtnKlpD7loAMopSfoUWC6a4iCrAn9t3wix7s3v/Ge huiVf4iskmmBJIdKg45cv4RM90KG1sBBOURe8N8mNRCaNy8ea8l3r084wzoKQtrEAeSbuCbO ocMNjoqVpYFCoxd0sIif7fXmtXiG4WIS3v9vMEBrLpICvATA0ugquA5cFYduBvNL2zHwWnEo rjSGXm5B6A8sXS/ih0TN73JPDQBMv499TA88p7UhJSDvJi3IFXIHPBYgKNX85gz+MBMNs5oz Ik0XdszZMt9/+YaJIVCs7NFHQoNrc9i1aQ6pFNysbwSv0JD9LEVmHcdyAJPjbKhsACAeISoJ hFHlRj66jA8NZmYu8YPUsbe07T5v+sCXvlF1YRBYoUYsPK9xdqCNxSr0bOEAAVN8enXwhiST T0e3sUgmx3f0c4vGDyT/iVrv1oJBCCnhF6VL8F34OuebWrYPHQCFQWnJfg30DxomZcXEepL3 MT7KbZCrYqwK1rNLVC7AzlmPi/1AipyeR2RKz2CiamCubDDrA6sQiYrEzkFRladYfgpi5Ndb NA0kEEqAbLzlhf9KXbGHP4gPETvmXuzSTBwwsMRHJUbVB+se9raXUkCSRdfe7SnIGckyLbJH dHr4ngTnQbPSEHqUJ8djTJGR4Rc7dd55J0n+ZN1Iaw4kfJFDjrkAybeNEUbyGjoMkvOOz2GE cQwG4hxVF8s6ROHrJ9PR4omQeiOtJ/LrVNOlRh3zo90BwXKYhE+XX+9BeoTINgxryP7KOLZG A+5Uji9nK+TW4NhmJeFX76Ye69iz7xk22lUzNnziHgD7L+5HuN9PzgwShjPQSHm7OICitBl6 UBRGEou71+0EjQkCLIuE2sDvyQLSUJNRU0p5W8HODb6PNgIkfkMfsiaWoJnpaOrwZgdZq4bQ o36eiWCHzO29RrUzNq30PQ2ndIN0YVZpARyU1on2riwOkJROX9ERGB7LpRafXZqYqbQG4EAP nYoOS99+EJ8Eq7edV/BEP3jO093ZX4V3MZ+VrRD6tRPZvEAU3TXHzfYy7aTLFaf+i74G3QV6 hpAxatai/DD4A4NfZ6SDRB23zD68xEENQKFpLeYubX/l6m8VeNYSl8egQZR2TOOjLJp/DnPq s151NXsDXLBNA4rcy9njCfoaffBHJjHNy/3ZN4g/vp8tSPshKHDA6+SwNzJwT1ndRmCS1cpB CQTapdFOjVWxhnZ+RJXkc0uzkt1YRZ+efQ0ClT9+HFE70U2SnbE60H6Oi5S09fQC+CGxS/bi sTOzqCXO/utV6GSheIzjtp4wNcJgOM1i9AOfCbSQVYv7Ri0zvsJ3nPHFPpYIQnStjZuOP7Oa xshUIjFgUiMSgpB7U4q0pjjfYE6GKEZ+PALDJ6dtnyNyZI96SzQMY6APHVm7iK9/80sXPg69 g+RLeSLg8ou2F332/ET5Tpmnb2JD/lA3V+EwtlKNMPnBwQuuH5/loKK2h2QzVdaJxQqCg3SU jBE7knbow/FSnpvHGjlXAoVatM/M9fLAl+9vncm5QDHmwUJ5rWnJtUCUHreobXhSNo2To2fw AbmZSyf96CSSU7TIy80Wktc+31z4vM9q7DyKMV5MLzakGuPY4sA4XrmXDcSb3ZkUGYJf1hu0 wM4qE7W4o0hbbGh5jf4gEPE7opGkyBJgtwU0sP8dq++yejNmkMCSOYjGnet2hr0gzND7dVpD 1daVIxxoKscMoT9cR5KFb3NBuob9bxArojyrtngvKzVFDd3v1g+hxmBn6aZK2pHpy/aLQ43u xps5uv0Qj6zgoAoWZ47pNay7eVp53e11KQ8/QhEWALcX8b9aQSOj/he0EPj6r3MKJjOHViO+ m2PPAMm2xkDvl1/+MgZGX3N3qflHJd1qxUXD/QYenn9AH7m070m5TKsj7wGVUBuzABMoJCn0 hTJTh0b+mDicaa19DXgvW6xfFEKrSlaZWAhZZPcfS8mAnz/hij9epRdREXzfbBWE1ycIjxoa Ivl4DczOK/SaP0G7hBzcmbHLchfiVskoknfnRzY9doFcGyH3sU0qVGe1No9Y++ij6CAFqad0 8gArAzurmhtS2g3UQ6ZORAF23LYZv6GK7Zm3MoQKWdz7J2sb1Gl53rH2p1wz9V1D6VzCB7W5 Ky4UFnHKP+X788nlx0f9oh4jCSPQk2AqMU/v5iHIpqf41DO1YjQ6/1beETr3XJAy5pcxFuEX YxyibrAXjGKS327r0QS1YbW9YhpodZMaObTFFOpaybsq5yujl5Hz8PwQUf7awLpFcUi7U+gN vCca3Xw/JbqFArL0Tq4TQOFrsXHzoBeWa4RTEaxu+W6VcCo33Ua+k4vWm4u5lQyzPY6LruQJ H/7k1hJ7kQWTnVICRQIMmeBAYBv/oENjZEmlKfmO3+lBizNQc4EdA/YsmHaOHimPTWDnzg/t 04w+yiYMzoGVfZZt2FCEF/l7k0z5yH8beouAB4eIVsdmIidAS53d31L3CBV5khmuijPAC9ts xte8E1+dPzHKDiFhip/2cijg6Ihbk5Kd4rDERrf/ioL86bZVeI6fofFUC4+y58IKnUTdPtv5 dg1JprV4L01bzFcKZgmdm4y9njbipeOzQBLWrGwF8Q0zR02kgjPvT5D/xlHJpz3QdhHFlkKY hdIuX4X9GSe6uMlfCva+KETjwLfvBwl2fMNy6wx/6IXlq1bl/U3KoL2KwWn6LLdZq2LXSv3l QYmcH6HZBzcK/bLjcWJ/nINzI1H/TURuPgS1Hen8HlF7RCXR19uvHksidPD2CuRiqWJ1L7uk ku/FZgGojx+Ar4tHitJ6l+OCutZnt/wdvIwu19o06kKUyktTMBmhrJlADlRvZDtkHVi6WvCj VNSf6bhYhGf3XjHk+llylxAz2JobRBAabJETB9jV6Ct2LW4AMz9JM3q2TIOvOfFCeRvcCahA m4jWmaN6gFjOnhhxeD5CbfgIXCaO3l0D5y+gbsMzKToiZFbw2hrlu299C5zuFjyMvdPTbfNZ 2yETQisKMXF8XXus3Xjdyovx0C0+gk6sLKZIHlTMCyFRKvSeVeZ2nBeoTHo1Q7Me9urESBON mZDbKyUr5ZTKNpVAc0Yz0zG21OV8bJ5rgYfUasKtE6aVHf5tZBVVlPfE/J4SUkM5oBp6GG2F ujd5k3ufhNVM7wDff2ix9Z4rKzmFllAjFkLpkZF2zz8M0GSxVE9eo1wtRZrkmUXi65lIesYO vdVAsqqca2ZOb7UfZ2QGoxHke1DKAHjCZKlA8eAkoPZTsA7NfaVrqZ9wRQGrfRBvwy+2qz8l bZMZMu5eOQYejYNKcH4p/ipC6oX/eAAx7SG+nywteH4hYc5jnCBHobkFOc1QvNnpKeoTRhCT lGSgHg3/XhJBn9q9EuALmFGT2Uo/dLcmFomwcptVWJO/73dtVBakMpvRsS6nO7ilERDtin0l mn7urBnxVq9U1sxZi1fubxiRlOwLnh7ZOK23vh08w7W5YYrq3O8ZjtLIVYqbCQn8Bt8fM1sj XnJcFIdmL+CsoOsik/vX66mB9NSbj6MPwiu4XMKVfuZH03Hzj5C0BoHW1kghRI2cueykwnU0 k+LXYhY/7GY/lcs+dtF7z4dBivq3cATpuWIN7tpabdDLu1U+TvcT9+2a+Cjl6GIGwcRYTMJc Tx+IrAbw4lXVhqo1md0uiYCjec/BFWnnTb5+yxWkpbJ3gvh5x5lx9a8aeEXuaCGCYZLefzuR euFOXGxRiWgQjWz5YGJg56cBWbkYUrtjGrpqYKX+iDXYVZd0SV1YN9iq5CAet8NCOnN+vDeh EF1Z4ABxLJaoOD94saDetoeUGqRyi3bLUN1t2KhmG9zCpUPUo2tNAKF0gIJpZ1/zE326zoSi GKi22vtKlHOuwLrfwy8q3g/Zv7yzAhvax77v6FpfEtu1LC8ZTcQRfzKUbcJPxvJ9MvcS/Bjq n4/o6+qwIbI5viDZqtwzRBDwyBOzdSlm4TcrCbL9djEQypoLm5mRWQsKqSnjvJOy48MwnmCU s9lJW0Om9mBlDKPDK6zyqJL6fQCogb8gr0kRPABbXnbTeHLoXIq6nMATyviM2vu95hwsSWs8 m3bxIUyM+zKmkuTgbQqjuhtrqseO3kciL5sT46oBZ/2VLEeLHlS0dK14yBvEF43GoC95bxAR +G6q2ATAyVCrTzGBH0qfxxD5T5fDQBg/c2GIGO7uv4zjkonvJR+Ld5vGFCKW2ZEeETlcwCVv Oo4r8sIn6ml2jTp4Vvl1Kik+SvhUApCk2dGSmuWpifB8fU0sxozztdS7KdqI27TZ0hwoyAdH kgoU/o51Cnic/Sa3XkzKBOlRj+Duam+7s2G9dl722AhougTlVByTIOukfqLQyRh7tk/j4Uol 8oXi+ApvdMc0oDsMbceeMwC4DUQ6fOqHDnkWujRpJ1+nlvahVA4Q5LYcuUH8mF81nVb8EpNY B1VQtIBlPUYBJchSk/wJrmJskQM/ANYQNgk+jtuRQGwg4mG3R9/ZlN8JoZmY1CC1vZy68vP4 35pElrbopNr31IPJg+F4L1nh3carKOQdG6i+dcZPfUUAol9rVogkvtcndsDGSbxc2L1yYh9A amNEKuFrTRMiLUQv4QMkHsRT0NGYApqojWCMh3WR/yniueOT07RzWwXjhDRQG6RARko0+rq/ 5T8xY4W3cfJHoQ9/HNlbTaPC0hF5LvRxRGppvxtphvJ5Jd/JcZB7qI4j+dgkuj7xLCwK65wQ dii9dotMQqXUlna07MQvTsSf+mIScth1nS5PmXAer7Ds2jyPF/pQ5Jr1cGx//lRmAKT1Tvu6 OoeAfbE75yyfZRDOVZHqv83UpDtu/XExA+moXw2gTvecxrtjaEqZytoQw6mFFuwfl6i0kl7K xC7m6x9tD7FMG3nh0/9VwxdWaD9/AneQzXd5EWjZDkbi8FM9vnaSqdaeRKnF8vpysut16spc LGuC2Rgdip2wBbltjmYSX4IfgbeIkbbX6cLZn+/k7nSjM3uZpXO1OnNmh094P4YcDBB0WLM4 NRgps7uej/ew/8mhQXqDXZXeXo7OJvsuuNg1/3uFPj/6o6FlXHeFwHnAtrlKpBkC3dISh3Ri zPUfzo9B7hrMupN3EOf11DzK88hGUjMSced8y3KOjWp+Npd+rcdZxS//fyMKiBVwbMA4nVXO ywicMfZy4cDIRDA2pthZx73SC4TuiRDvxUlNprVnvTL5JIfBnjfodDHDTNJyy1VU2l6n4UCy NaaV4UcTcv75UkA/KW7+upMVF9S7ig8nCIcdjAW3a+OUjCsbRz/oq6L97xygjZD7mYiBWwY9 /ayoJ2MnulQ07naCDqNGBYo17kXe68Db1MWaIEtNZc9n5Xi/R9wLyBs1WkJVwYn5flHWbIW1 xOCBA+wkDEn9/fGfQeTWwrU1Ae5arrR9XFvwq8kjgCwJwMFdJrgDX/MIFLBUI/xtOPK1+JHN 1FVp8iFCl1DhgZPPQmGpJkn1RprhGbNRFygPQQAAe2RnRPze0M1J3C7rvNPn+hgxXvGTXDA9 mmmA1r0CxOC6KqyerkARuySVToVZm8tmyfFd8WvBetK1OWgL462ghVFQBJjKC/+IE28qoDpl ODwEP2K6KTnIiYAUGNwzvL6+F6Ijo7g1EPtw4YUMg6mOZA8sGP8IBArmsfJHtRObjebZLm4u UrbfNt0MGQ0EUvboctVVJC+IV8KEqpon4jG7WtRYhkJgGfUHHH/v8iqbpcG+cs0Cp+R43XAr YXQqGrMT6dzM3mNE9znnPM/3waa+pZblDPQGhkZgd2x5ys5E0vNaNL3h0Wyzj5RdwZfy0/sP LE5tS6UfysXtbaWex/XbIL78ttwNqzSsncLxsdbJXq+u5Wz33wz4EHTrj81dfKzeQ711wqfN Lz0Q545GRfDaeRB0VPHVGrdSDuhgYBHDSVdJuPuzRoYyA31YL/eoHGv/f+T8IJ+mx5PKRP1H QIpR01PH2Mq4qMH1F2LrV5j/IzanK9ugSTXei5lT4fOPdmmh8X5EHt5LSUGjIvrzL1qUMlFB ++5MYcxyLMbPUTqNufutw/m/UCqjTSiOLqYofk/VkBbky2GfMM9m+B/n4kgAlj0TiveFPOYQ qE9AAizzGn/MUEVL11iG3vXgbQtunlwPASxtkMv8N1/tb9PSzvEqbXYjYaNyORMXa9jA6pex iwvv90wAmR3flD7zXBB6rQAXEa0WkbQApB26nsV4Hjcaf/HHo/LP7Pa0T72BOFwjQSI/jPuh RCzUUFDUYQ2Zr00/+jr6lgwhb+CUIs8y06BkJi1GmFQ1WZMcfAFJv2cnRFqMVSljW6Dvkubm VKoTVpD3PGp/+vHYn6GJ8aTdpzpWF5uSmUTBzK3UNaLu9m1WaIbsXV6NmmYvrCVN5sxUrc6g 7ompiYrOVb0owwlKg448sDqhKD8HF3BavL07o4U/7TSrArSrNqfAvsTX1fZf/kt1cTJ7inZ+ mJHVl2Xl0vkViO9b6Z8KEHttmGFHTJxNPD9g1125p/z4ipz5DMNUmT6EbysrS4+FxJI8AQWE 3Mo0dO43/3WOiqKGNiCbfK85UZPFmZO0bOKkm+OvNhWeDtWZ5npIJ+1OsW0NYC1WcEK507Vf WZ/yRQbf9senM5Rx1xuXgO8IvzJeR0RkVvRLCECh2hUITZPVePQT53XMaGoWLNYI6rrQVQzM faQk3skmu6D/0RewMETsoVipLpvTMnmfv+6ltsQCWlGbxSRF9AcV/faqyWr/UYwZ+UymtOOC fztUPwTow2ohbyDnpY0Lh7Y+wPBVisBVVpUFNKEAGlhlbMm6RsD70ZPLVcyjvauqxfYwPQg3 O8m2OQVLEbKPZ8dA1rhQyPojsdgP7IeKNJSt7N5HbRsM7mBL4AMaHsoE5hgOoS7YJ2VzGxnr eW6Ha7DZdkTD2EhVkZorDr42XxvWr71g7ygU0aILAK8+IaTVtufNtOTwwTX3v9QFpX35vVvq +hpTO6fXy0IdRbEy8U2kHrmD7rO06lBtodbyrxGJ5cUbcKN5wDMmWnuCLJ90VSJND4dbPa9u MXaUf5HyI1QzMinmk/CM7T/lBmwrppxZ5ALdJhqem0NL+t/5NlmprfgrOc+ovKyoLRtsmQTq i8jU3F4+Y1w2jFXPXBLihoPDU6Ax0pKG5eD1GuF8Lra3SX5pg2hVW57uu9cRNQykHMBC/q/g HKcZu8jCNy3MfDxdDg8ANVNOzYw6SkLDjj7BxqttF+WJDPzzibrpJEO0ZaHHNBhp+i1AkROI oUXFNpFQ58p1pHsnkuiJWNVCNnZ/QTsdaKtpAnWb2XhHZf8WXDxJuAkO5/0/Rya9iIG7HbUR 3QYhKjZ/TVa0UUJZ+HcLGRmXbsD8Xk3qwikQELvrZy6gG34PJIkWJ/UqDIRq3VNsn7BPlFBA 6EUOQAn/fkhAG+hNArmQLouLXEvIic22QRBQlB4EgMPCfvBlO7w9U7DMVOT9ql/xXhXWTDE+ wxzPNmRZaBHBQxeKpbgV5uYnMdpG/uf4F0LWdbCOrwdLzBKr/yK33Nalh+YJZLhkGyr7b2OS I+lyf+cpaaREmkIYGnJcbI0V9pJikVO4OupiJCVq2pcI7hPjX5KWkp+yFQXStmY3n6Y+F5Ra 6QYsvT/nc5oS7hrKrnnbMR3vR4IGWDfVJTrSBSd0ii9gzxY6gsbq6jv5zFJlwnP2maAXMyDm KdZI6jx9aGq9y0M3s42jTPrlohBsjLqdaI3cehdZGMEOKh3DwOb06fFinymPOL4qFKWx7cDq cFxke2w6XI9ulVsfCtvo+9tgB0GshDAUCec5xURmj36BYOX5+5JanRmCIzCtBv5QRh+csMLP zAcxPaSOWe0+/PXjw7s54+UFBpzb6t2CteqtrEdHwitjcUpWCZWNgpQH7W6gi+CUF9Aa4ver 4PeKntiUtWGGU5VFvl9c4zA4oj8q9JPuGC9kL9tsKlqYd6bOFkL2Mz+d0OBrNKZ68+YRuw+e cXMgstGOXfR/iAsVCk60TG/dJpzHlkN1KDs5N9ppVD/2lvvN1GRdwPKhR2NLpD+kgwNPIFqK 90UvkFsPb2m6F6ImgkuSGreTehWdTPpmH6kz4YJLuJosHQNYBpGWp1u8KQyuTmSF7aEuwwJM 9vmWsgYS2KhnWpZazaCJnhjH4FXM03+OQgl1F/c4qpwiV27Cb+cLNGEdJzNqouS/EKKPj8WD awNh1iwk0nYBRjh2/XrPqDo6wp+qqy2Ci1JMiQX3tF5iCSwjn20o/CcyC+7AYCuQl9CI8mcc e0H4cphWRMtjiFumfnHS4lVnP7NKnrCSFc7kEtj9RurebRHK0DQzqYoGC4U1Dy8RWGsIG53I 01jASGmHdrhKyiN2Ck1JBceAUcHWCUeuiO2RDIgbtSPuwx+d8OTomNn+1WQRYVvQ+Ew/x/Rz /yh2BltBnWbNGPTnYOgp9UMIepIAtAtekPERIP+k3SOCtZ6gXVT0ibr/WlnXPH5/RFMXsi0q SPDU7oaFUEEGoJRk4PxL80wi+V4Bts8XwQ+S+YDJUts9U7eewQoWOj60L+ECWfecs3i74OSW i7PmoqcJjTVpUbHqM6MwEX5/xz4akPichu5zaeS4AjdOLjTzZiP/UAHnwBB1wY61geWi5c6J krw7bjmx2N9CAuf8iZ/L1AEzXr83yL4fJCMB2kKdRqZKjs8R1/G4OCzxWPOopBphVBTgHYYK bZYwk414Jc397/hbHYHFlLz4qP4dmMubGCzue+39Xb808YlSSIvZvbyeFg3SKc7EhPratL2+ XKCJUw021OiY1+qCoYFS6JuKuR3fx6BL3y9Jpjf/Xr5OuIxyx3eMElIC7scvA9Vh6DGMsH3/ 0u8eQGtuwxfvGVQc1rMP/5LXCzfq4ZU7phMEPaWkP+D9H1fk2wzDeix6gLJonBXnpEKlMN0b xwNCj2OioaOQjv6YQ78XmEUYtZxJHyIeVuR5rWJXBODfMb4lUMlC+Wi3l6fIGs6+ruVK4DV0 KJ+36yHqZzPAv74hEcqSSmlKXZUq0t+Tutr9qrYclqBPTORktVNpxh8F7ogpntBQjdWcsLUl KRy5m8RmJO3bIJUhd7tPa1ahPWF61zG2dDAbFDBKSRxdq7dVPGOZ4lNUTuYAr5SoSBcTJtdO +7V6VJqJbBjc+aR2KZlchvfn4J70mPBMJvqJeJEc9FySlXr1As0VUcrAeTqy1moeeE9NzVVv l/1TTiPZYc6tNTsyANNiHxhiKrJGLVdLTT38bPFZDzztQHJLTKyXqT8cl5Zw6cDWuqTBx+X0 ZaOFXW6DbwByW2zr610xprzZv2khjsZDkLlH2diMmxkWbx4248mCvNWss+5zn+iBskzIBedx LluuJ+egOsGSGlNN4lCmAV6hLTgTLRg4cEcDvAKUeK6JS3OBo9RNrgoUvVpBKsJmxlFQ7xBd 9wa11ENChg8TcN6KGYkcIOrHzXqOz9Sxu0urgTKj4UWfKz24R9+ZBqkIQxKRGHXQostnMfXM Kp+085K48cNuwfF2WVGKJLipIlmIET/UUtVqh0ZoYRYDPj1CJae+yXfjbB7nnfQY5qRolfXq 54f0XgSxjbsTH80j9wzU/WO6Sd7qkpk7Xxn1KMp6WL0eEwJnB/DwEtFiLk7u5GxbwKsymINU wrX4zN9iizhx+KWmj31ZfT+SAEt3ZFboWd4P/zMSecIe8nGJLDzwzgRhTZsuLaVbtfIzvr7M vRfGbEvdLbG7h22fDg+kqbBOI+hCYquPDGi6Jnw6uXF6FPWyVLXh8Nc+Svxd8PtQLgu4Zi91 8V9RNRmqCcNpQbq+zei8zzUjt/HgpWMuXc3CGyoGFOWwRDJFJGLCzgWUUq6964yG2ZFBWTFe FP21DObB+yGVuKeGomVF7wSox+Bnx+R5k2BoEb+vX5ZPe+umyf8Zfd1arUtnOmeDOUgphDMW F9Kr7tAScq+es35Jwfh9Vv6JU+mZ5EfWoSeSroiU12pB/HC7Pk5DMbKINOI5IdTZp8DYhGnf nZf55Kr8kdPIhHUjViG9macCuQiS3bZ4qQovz48aziYlK0M3HNAkSY0pjAGkSmxBLH4jcDwy au51NYRqR44KWFFdnHH6GEgfaZMYjBQg0lAV0+rXlBt3hXVLiXnHyz8yqrSzGQpLDMdA5n8Q lHNCfH3tHRO5qVxNF0f2G5sU/00u0Mf6G9CGmP0HMmfems3lqaAcpglSnzu7Xil3/raLjerS 5rqfJxIjMlRizI+nVpPOJPf+TmN6yZQFHAV1EkHwFFHdBE6wMF5/33Lst92pW1GbdiT9CUT1 ajrk8vCtOR0XpcTdP3Hd9WdxevOUjZxHm9ZD0AE/Lpr+0R1lmHs8+7PJtlNQHZuPavW8o8vD QgQ9I6DR9aKMQ4PNZxaOnLkacuM4KllnRfHldzpaw0tVDE/bdnIJDCXuuCtrI8I4HtkGByd4 93bJfkF3UqCMCufzmsxUjcZJl/OU5k+lHiLgNZhCJTOpVtPzR7kgJKJi85Z9SUU0ZxrZ+QDd 5HA9/8pta5KdTVhY/hzb21KAUdxUtlV3F9aAM2FpZ7Ex3YAWGU8inG/Ozm6HgI2ZQWbt5cyC 1PKO1dHFx7RCOIVa4mj25KrtTm4dRXfqHaqwJ3sa0TS+SETp9F5pChjAtmteaEJflGuvne+M PqwXgu2v9HCN4E0+QUg0ZK4MNxXnNqZgbQLcCSyqOQ5DSFWZyQ7JoMcBd1Epk8n8TjChAI4y 0KkQgpdyWk37bANMwkDe4rIDzEZ1PcBZyB/VvRL6a4zh4hmJ0kfTmBA+AMXJRyonOyGd5dQN 2nKDlFiHC3GdvFo1qfvrRppYwEHnKrPIDpqLrqB+AUlJqQh28HsOoOGRrfiqxdE2Jqi0sbuK wxk+NhUh5omw1XY8+2ZRy1TbXY/M2QnUMpWBBjJymUkddCXxozAduRbXzk5pthZajBSoiORY yNH1iII0LV0irQZ9IhNarmVmxAqpOAm7fcT9X+k4cTrE7ghMrdV5lGqowbcRTPN3NNtZqpFG esQyYJ8ai1k0Y9YWvTUzkv6aPvXgSK8bqHEphwRJtqLQdWzJmrRYk//XZ0g74Fa6LoXxXz+K Luk3RDKOpB+gaJn45liIvA0ZA7yNMblB5JfIiqQdUgzOFFNSi5tstucX/3Hupg8/Rr2rt+vd b3GsSsa6d0eGnwgGw8K/Ackjx5ptZAE7rwbyqFFSpmpdTf9YZsIxYcwLcL3vH8XqSIhIQ/FM 2Eobjs5PI4TF8SMYxlyrled4budlFEfqaxzsuEG79wTvTZTUE9USpcdRFx5a9ntb5F551iWh 9mYmemcqXCuLaX6S/W9Rljko1rXosMkzTa2X5nS6oEKJzWDa8ymdXSK/QqTNBvKzcEpYD5ap Dk+X+J4574seDBQvIsylzv5EcDq4Neh5OYr6pB46U3enKpZY4CQFRF6RWvvPeSvXmmpy0ajI rqdhllg3imJnHyRlCUuGny8+/8znr2eKMp5Q36iLuTV1XCuOqlAhozEgfcr3v8rvB5fcciP0 hsmV0tbfvvLZpDV0O+dX0r6I8eVvl4TcoydQRSFRytssiKfO+FvV9ZanAKUlP8zIlggnyPgE wY1Bd1PV8m9wCFAw7fYDM/AM8aZvrWmjt2tRpUPeTSo1GTypEOfWX+tROnEtR8W80+s+SD0U gcXtXHteeBms7ibu2CCI1HYdsIq3nk1DGiQDwdW/yLzt6DjnlyYp5QRdcQeVYakTxjuMYWTL 26GhM5+bSAn/f7dHHrBl82aW1MYJo7wl0D33EAxT6ayrtHwKjV/Mnh1NaSbCyecu1jXKv6Kq Fu03oRqORnsTxfuWXy2z5zsDIQWN5Z4ndKsK7YrB2U/jJ1oRjZh8o2o07EzCxvNFfSzbYf+S jmXRG9wRYEHOmmk0gZIUnuXitM5+CP2cx1ieYdJcW2z0hNT3FRgtL1GNB4HvbGH73oAqQOm1 ehUdtF8GAehUkI/vJ2e1ncgqU7pJLadK8e/Fa1k7VldzzgYgOXi+zsD+eT3sOZODcjA6tPdo xOMU+zxpc21iH6KK6wB4jKCmdxy1ATzox0Yx3FYKAU8IgQdjhitVx6pjE2GnGvOcobhJNQwg Z7FK5I0yIxZt4+hjq6+7ZPZzbCnS7XHHCDHQq4CdEIJQx7cOEABtqRoMJEqOGTNlcDBFYpXG h3RdiiJz6i5SxHYDlmTEIYCnrG+DgaBxCudOEjHE31oTHB5SxEzrTNdaUBFZqcMlN6gsnm8b i+f0r4CRDPBbHjya4TaK1UR7fI3YyqQhgeFwgvg2CQVKF+CPcv13tEoGmwLdgtUg06IiqH9d 9gIt5618Ybid+hgY6WGb78p7iQzAHbjSrQZarqsZN96oR68TemCPZaSHXGlroVx8gs3B5WUg 6kLu5RL49HGe+2UUm+xMiaF7ZnjBM9JjghIdKN4t1/WDFp66WX+16RPuDv29WCvLH1myEdNV IP3wdss8IsnjccoPCeFeNT6IHLuv/WtbqtPXq3IxWz5C3sBDOo2mC4d/ijLu5CbLZN5y0vpw imMKsbnZrlKoLxQ/gMF2D4dmIIcIZFHjlelzgY212UcW8Am8KqJPid3LiSCpq48QJX7mtvSi kNul0vFNHmou+3ueS1a1Nuverg2vzmJLXnAoapBMKaAz1PzMXX6neib/OZEw7Yq+ehc5I7Q+ KH6PxZxgfGg0/+Qkndif95oWKEDhL3tR1RFrr5l+AJ7gOGXPWEH8+WCTN9ght7muFQf88Uq0 aM9WlUg88Vn44CG6pyrzOaDfh04k5B1360xs1DQ3Xc26c4VCakgPVJTaORJQGkJ16dZP7OjY dqYjUahEHoxE1ANxiYLinaoHjgx8d+38KHYUEWrtrtqvnLCsB/XbGz5ElZ8h5icVLI7sYCI+ 0tqW50aCzrCxn+VerzGfyczpmYlBL/zYatC3qljQ22Ba5wX22k+5IzGWxElpyg1vBNmkEVZ1 qGcLo2kduezqZFqQ+oWGGid+QnIsU5zwLb2d+/MVwHPYkIkzr8Mfq3a5lu6Ox6WO4xqCBdp8 dBB03Qh7DOFZLU573t1vTtD+QMVQ09l4TGTACKmLkTxzWYbGZaU3M6WA2lsebAKeqldxtjI9 FXTAdyhyUh5RJLYzHS0ejAmTVC401fpIyHH8y5wQ1k3vWORAiU0haevBk1Mc4b1ihgdT48NS NPEupwnu9WTSFJvse5XbmU2OdASCDcQq8nsIP2kPgxn3OErtCV5jw+gS4eY4p4/M10nyGHuJ xUnl2H1torPCLa92mWxzqHiV7N8q5PAsydrMT/km6Pw/oo4eXpVpjBKOqEh/I+E7w5s2/ctw or1vdK2v0nEpWf/wvymINngvLFHqc6m8uONRsAM+iddGFnxO2KUMXMEda5sV6b6ceNjy3Ovz Ima3Pfw0qOECfLLpA0LiLPU+K/7LyU4cJ6sRgTyGyF6/Ormw+PMOen7Se5aTCH6lP1RldMgz RlDs1S2JdP8O1piyQHlqlfKHGe5reiz4KTKMHTiSbgFKiYemrkWur/j/z8+9xZFtTdH7SGEV ekWrcoLNsjZ30sYqSwh9ms5vfJ63bCUPnmXfERcxMTu7CEs0shivN5/9W69981C+k0ZHiQJn dp3LmQZbWiWUyQXfMTM+f0Hd6b3bfLFTr7ySYcR6a7KKj+LIuMeQx6rntfjAvmN1XyHtZN/f 4R941XlWN3GbMUapuab9tb4Y5prvUPsymK/PyZxxamog/sTB/JhM3aFJzRDiRQN3pEzLUSOc LeJQ6AqZKvWHnb4dCHb4r2iPfQYV9jHbxTM36IIinFuH8Rw1YWV8TEgAFK4ZiIN8s7CFMqWr oFfYseOK3ehbZjFPtOZxmmYv/NXlw1wfAvOsaR1nFfUINvcMFJ2kCVmOrMyHPAY3lY4zSA0a 82NxQQjnh8WV2kHs2gPOWttrOJGqLgVOj5JitFKng0kwOySdzkGiWbGq6I6C5mXYNRutD84H NKkHqhhiTR7zOmjfiR5ySQLE58LeIi/4DDfN24bspxrhbPVcekGybaCnU3oeHTTE63byKzD5 osH+i9a2G3GFnfpw+iKSfKtqfthhiARuSrXbx1L04yzOZSdB0uYVWxhSKFMQhMTpA1SZylQ1 iB8lmHbwAELq+czhJQMtaPfcp1qyWpjI2AMUne+dkISJTqk8i4b1tNGobz+Ml4W4eldHMQvJ YRcwlIpGXWqCx2i+tLDIDdgY97GLJNSX9XTOaEEsVRvTxB5ZyZFOfAKNA7IBUhkfGZgYvCMb Jnl3GgxrSYiiyyYSkZ/SFVJUl9N6Sgs2zF0yUHjFum6a981gs6N/7uu3+vsMA++fpGOZb8Ej 6hci4OybCVye6DnM/YHHM5d6lcG63g2Sbqr/ehUjZDelG4FE1beVh73n7sdOxp2VcLIHdS29 De/5GwNphU2I2pxCWxMk7u4Cpckl87s97jbtPB2MahUxiSdxRUt0on8luQd7iV4N+QofSiJF Wjuf3ZwrQTBSf7Rn+WmojQK7SZZogl2yI2fEjuj0B3RwjM0Ui/57Mj/EX2/kagr8/c7ryO4G 1Box2i2tmMVRdRurM5MOrzC2EatamgvJDOX+BO0OP0BO8tHnKpGyeSm3NXlxYTaJmHaAezJw /qqyCkx3rsGPQPNfOeJojoRtaeof9/TBXlTFkKXv8Wo/WjCYp0T9YhUv060tMCgXvTYY9jkG ErJ9OETN6LKYTIKbRqkXcKRU5vvE8c/jQrHpiDIS51bv95yqFHWWvjMQXzsYV/03oOqWRjXD AlgZhtzCpzxV5s6snOq+tRWGjRII784mVttzwMLeE315yfN9bQFkVxTyfgNq5k0OTuQoyltY 9yHBP3jKDynwvlapmErwU0KZeXBx6shNi1e4/zoPzKgVntv6VGQWUKhpsw0lJYKBEQ385rta Qbn5UemQUSy8oVGMIIf3PBPde/NtOGr7XwjElJolkYpAk+TKZKPwsT0BUNG8NskcjoEf+5wR Wo1Sq3GwBbWqzZKSiZok49OyBOUh8tMh0E5zE5RfIi3cMuYq9ImUbA3iyPiAuXXySbA16e30 lFx9ixywnYDkEi1ulVLaMFrqel/kJ/w8nnW9Xu3VVEelLQd1xsHH4TQMA9h5Eom90y5jutMU kBqDtdL1Ju3xw8V4SNwQTjDPAZt3bPzfnaz20yEI3wsluXwhR+NnpEV7XNnptE2uuvasZbmb gmYW6C7/zVgbeCNBhoklmjYza3O8hj/TdlsH90lCYiNsGqriIoCNIyY/gEFHyydcLHJwoEKw HtvMf3VhESIvSjQM+IJ2acBE42LbEPVhXfM85XpvaX/KsV9i5QlT7V64MJ/BrykBzmEpH4XU pTsNmWfSrx1wR9pd//9Rw0qyMBQ+sh8tq228FHcsmOPSsFL4icGciCwXu84QAv5fc7AJGWbS PwPuvMK4iqr8ZGLm9aPV40gVuH2qmd0ESMHC8+9vuDUv+Rh3JIzCnuWDwJ5ZqflFccYSYVjc 1ZbyeNffZNQTTEaSOI1y4tO6N7r5ygZRBVtU/bh27Ow/PJapXPtg0117HrXPlyg7io2pBKE8 i79rdpmqfTDJNvCMTE9aUwb5LBSBwWRioGVKBAXUePu/2Eqw9DcSztMqwNA1ZbuUW/oGGjDx SvbRWsAST9IILhYp+H/VtMetqqp6H4FirL55KNIgJC9lA+jYZHnSUHvpzYqAVcuqUfXtAi1P kU5ks+Zb0aYESMlbAcNpaKcUR/PyxjmaFXRAkHWTYbv10nZSWtYdi/ytRYQc1Vp5LBkzyxHy /FkEh5KNmtg3aQ7Gcg1MAL3WTMLpMmuoSr8eXJQ7qSZ21Z0T4TtHHO8HKeU4HWs/6gzxy2dJ vXL4TtySncmytwrnf6VwyPqwHM1745YftJlvi3QTxaWVVyV8hIX9cUiLe/xQyK55HdXq/SDr 609ihzCSxPCc5nTy6v9m9/i0TUVOA4C6u7Vz0S/Sp0qgemleORBYU8CTVzVETtrXgQodHS5G vSynuzMx9Wi3eellI853LU62JwQ8rUqkEwS5V5lXHPc71jAcx8cW48lEoFC4JFNPKLkalVPW yEOuxhhCeZAbpIIyhvHHC8+NY6hX2hgspnveiTVFS9bMqhvljWjarTRfsKfnFMiQJlbkEZ8L 7m7V54qEjp9w0cKWBsyF2+XHqf8Luc20YDH3EEvP/pTRKmgNx6anA+AqOfy5EQDnnFcWlJ1j OEf/if4RmydsWqJIzrbBqTJjXOK0wbcc0YmdNK+2xnzVwGa6j4S1exN4XrgtW44moCf3tkT3 kof5sPpDvsYSERutCrtaFPKjmyETBanjo+K8RG32KVXNEiE4Z49KzhHVH8AIQ2aWE7X19EbO ozTefp0zu/R7zdeJVz+xhQOg8gvSN64DKbTRuJ9PgLZe8ZsQTA7Loz50otFw1oMtMpiHMpoJ E6jYU7w5tdKvm7IixU3RLEFAMWVW713eV0AnFNpTtJhuOqMrsD57to4h+wfAqzFYE9KqGLEx 7U5WWbPeNmg0zRKVDHC44EouHdibKHRIsA3VOgVJh9ik6f10Q1alz53S29/XjDfrFs0RiATI 1HB6yl9cWrv0D6ygVaunXSeEz8o8Oi5+2jx7PWjAKmzZ0oJ8cB2c+terjj45Ipk9sX64xVVu Wo45Rdsy01jAT2j2E93Vk1TlJ4VLHCbl6puxAsOan8zik0kcycZfMY7YXM+ZxvY2HKp4QlNP z6BZVqjU0esYryk9R+EaiTytGJ73vS4ArFpFgbkcDvCSHEZjGAx53qskkziiS1DLp1MIL+2A 9Bsfbet5GrEpzbMdM6YRu0GxkK2e8vcj3Xjdhri/1JXn+qGeumDH5Lt43DGURIFAojvlNVvv CdhO9kdo3tv3JqpuWJall+BWt3SK2SNPkgf5xr3xgCrFsEiKFFFedeVfb7FBQuF0I0IqyhuG cH6hiYVuUgZ/ksDKiXM80JSgmyOsHedEBjs+MMy4KYA7Snl09wNuAXu7oZp/Q7lTjLuerxL1 eJCpeZJSDJrbxALYFqoAd1f82U8AkwMgziugyJJEyWzoDE9+X6s2TyDScFNg6cVXQiV34pru PxlcIwa+puDcYArNkuI1EIDZF8Pyr8nhslRmwNlk9Nb86L3IJnnj+Rg5Eno8u8hSs+QnZkm1 huQPuM6mOUlyyVs9tWfjpjS8QjQSB48ajk8dxrzLRm35CeqvG561wX4AIYePKs0Zm9VMdZ8K GLtcj0YoBfHlTiRUUzvIpvQTTfVBAxoEWNsV/M994wj+ZPwG2OMpFCamMc5Sr/3OTzG0tSj9 ZWgfVkjJ6AjHstv+ikVM8yFTrDe8B0NSopUQYMyNJB4Vgy/ONlxl2jyWfhDD+huHc+EejfO2 PnxVQss/bwoiEA6Fx3reB2GxHzzJroTop9LVbz1/ORk+kGL/p4hl443FQan3jz5Q38NhosQf 9C+aIWyeA7Xzj+5QYhnOKmkZSJHENtsxeCwyelrC34BDWXkEdIqC/tvNNYh3YQ9hOi5YARsv i6CKF2ccfJ8o6h22Drmf/qq0+Y34+CPsvPB26jsO6nH0Jlfw6bxz/rF3N+CiD1Cn5cujVhqj oexs/K8VRNEvEuncXUe5KI169bhVA0YP5XiC4JacL+tfbb++6hYG2NNLf2IaIkz500H6a80v Gxv/ramisORWhp1i9Yh4iBp8qw+ahdKbmClSNVwpv9E6OGfNd/5i0TehIg9yqU0UiQgAJ2Xy u54lQQ2Y07bcB/wOx13mAex4Ijuebtsc2n9i+V+hytQcuHMeuUF1g6Ka3bKoRmwzzd+xl557 C4EA8zkgZvUJLbtuCVXQGMKOk0iWa8mxUaNtsrf6l+mOKCODzl2n+VMEN9Wi2/0Uq/Ikrwgk PrSby0YLApz02KsQUSMm9BzEqre3wgZ79WsnhiBgoKawis2g+rldPG1/QYd/NVS9sGl+82zW 8zrDKxoQrMYVmgeYiDnfds6raZKZDLhRpFIVHP5tOlAipxb5UuKxX1QXzwQb8UO1kYV/dOXh pqRCohVq1IOTqUkRlOeFB5FHobLIVxp0L0bistNiwfCx3borzs5A7BNFqtC3B/2XCiBFQiHz Qg/KAE+t4LKQJQVTedaLvvL+/c1b7i5yW4engIEDyOz/tifuSYycQ7BRbXDkn3Dy7yxNyUHU tYeNtZTkkHqQEGKwFVVbJJ73CSyhwWFGNF2fM08v6/aLn4Y38kQMqsV/MwNdWYnOcsTqrrEm E48PnJBUjLQVTDfRb1c24pfRlWoVFSPYc72ZTjBjwuHDcbzrMK4C/dgqusthmowVheDL1Fuv Jy+623ntxcN/cB577ZR+daHPoVpEvBZeUTXM9/f4xs3oZ7rU1Jc0ZTDHGbj+0pohnT72cOrm 5a4ddAonG9ijXfvGIDAJryAP9WgUrNOP1oPAuRoIYcoZ9OydiipacLrj5TcKGJ6B/sEUkM+y 9QTVtDMuh9LR4SlVerHtSpsl76XP3wTauWEYNIq0WX9OMQ1WWqrmMJwPaIhYQsBq+7VY9nfG qOda03uv+vXBH07gB6B0eaie8atoZ7Vwt/R+BGCPf+dlF0hm/BTVdhfoYc3dW0m19PFsndoG g8cuXt9OG3+62Nxl4RRFQfonp0t6FIeQZ2lc9tqDvurZRz3Tl3FQ8ygB0rSeO8RvvcFQV689 q0l8TKcxcZ7sS/0nGWuA2fJUzVnTLHVzM+tkC0+PZNYpEVcot+PGkq47Yz3AHKLcTO5GzjSi 4GsmI3IbuQmeeAZFMi/cxRAC2Tv54p2UhIEWSoNh+wJPkHSCNElV3y936yxygLIf2hHhZKxc rfHfrcN+GbVMs0GTrEZ2Aqlt7nTn3TaMvoJaIUF5glGSCFWtHz6eYX7ly05p2KcpLcNQ9vEL 0fklFM6Oo+6l3e8YcMGsiTa4GZtEB5hKPdY69O09NT5egns5wkFpVpbLhpgaLik5jDNr0nfA MYVOvCyHy7buHhNbtT53mxsCL/P5W1KQMmmjfiPia5GoDyEZwAuB8dIq4p5IBri80axtbNvM dZxBYSPZcjzpaZgtiK/toGY/ABxWFpXfme4Yv4AjiRzbmrIQnqPdIOE6hZ3E/rhCYhMTfqSC oz1Jkl0lFIuW/olEMlCKZuv39XnPc2ZhPMAMoTjGT7aWYDd5jgPBqBV62DMcFcygU/CIyUhs wNF0p0Pweg4JgrCMTBa9fq25xvkwd7K07w2RURxWi21PlFTg4plKphjupI04+ajnH5aaJzHB +gS9JSkXWpInUvPWvgDRq2zxboD+Bgbjw24WKF0VMhiLhA3QJtqerOGQiS++TcH8KX98NaLY ulO1nlcma0MPw0UyJ/sihI2vZQTIC+cxWlNxXOvIZJeLdZ2y1u3jPn/JRvQSJzpB+wgHEJqW 09ZimhGxkGFfukJg6pB1xiuvnbuuhkwLRMOhs15YweT582pMBhnZ3wqpYLPgILxRi4dlRURQ OdrtjSpHdVasw3G9s8bsuI48bDpeSaBycR4al7OZ2nsT8CpkUYwRUGQxDQnG8Dtb6nwFhqFb uEpb/vbkiOiOlVNSXdV5Vj9vWzFNmSn/fOfcV6piQlihEB9hN2vTvkGLkF7DBvkFqADiw/lM G/dq3cLTRfHbeEnyIDVslJIVIzlXlhYg5SFu0ZUfRkZbd4XLihU5wG4snT+YRbYTOevdzkQk c3zowV/apsdq+wb8m+dGPCSTaDgFjuRVxDXh7EZc0Edsh9VRi0MIHftDLx6WBj9rphtbH4gC W5bZiW6xpTKZgvUebZ3pwt39B4eg5mBv2edki+6biQZJKH1nHBGCQzGASqQiHbF9WZ6lB5sn RQekBER9XlDYL+HZ30hOGTWhkWsL+jjBBpcqUd9+tvtNE0naN/swTv87hIav6G78IV1qp9pA +LBiAfolEaM/T9Tf2J1BByQsiimbP1Z9fU3iBRlwPCM8B/vJEmUsM/S9oN/LUjgkV/UkclSK ++S0oJ3KlygrODnZddvC7MpUcyZOw1nVTI8r219xIDIWlf8jk4p5t6a9pzM4x4XHDVyDxZOf rQeyyWPRvnytBhYEmod2jIGFO7DIN72Z5O4Z89Zh75nNCnvMOb3Dr9W4HE3HzzV9MMFKzqHn LOzY/KLKeK1RTdQ8LSc5/oA+B1he23JmD6O4jKsiTaUh5O1/U+Ke7B+96q5FfjcsYjVxdwZI E/6el4tafxUZNDqvcYJql8cEcsSI+o8ywZPOCr0HIT9YnWcDeP/U2NEk6YbtwsFcR0idgSHz McaBgOmhWYQ50LeOm4xIt2Wa2bpgFSqqMR5mh1SXlDg0HuC/YgFJCs8IKuEuSjhqjdo4O8lq CBbbmW6v9LP8Y84t59bQtngY2Sazu8FqftsRifQ4UNfhmNwCtfF4bcFnbmgY3d/+QEDE6y78 DZHkNXyLWw7TaJfrXF6CQoitEgdQ9aBcf49Qz6LnHQQ0oo01XcX8bTveA6Rl3nmVh3xgQUkn JoYvH6XYJfVB7LtvISE+wrmkD04mQDS1CVJGWbZJ9+4xZiud15vktY9iuiNvOUsuUB0eNNGB JwtLRfOyFmkaMEncazfDpy09sCm7it4bR3aCCNVq7aMSaY/RCRijezk0qP2kDc68iI8Ocikx gC6DsLQcfe00D42YB8W0vA3of0hIsDpRYoTp2IlGwCwk20ZNYynRpb/qFCDswoUcksqi1JBU sBcuduQ47jvZsZeWHsH4mS7o/aMyq8inSEhb5DA2TmbbweQqhN3k4ifk1Mf1MI93uuNSm4Es b16YTq6HmRKZynwVL+OqkkgsjHtaIttTqdwOU8EZZAr+RQikwTVT6QlQOoEq/jl4i9kWWDc4 a+XerqXpr9oNYmtWW+imbCcIyzhqX9yRvG7Xlfe5g42gpjtL0QxT8TUBKRRWgQimSjGgkI22 7ru0QTmE6aBuxQ0PJ851P1jDkugkWaOxhWQ6+JxIH+r8zbglGXUuz+ySKGsSi4q+0ruOo6ob JP3aSGtR4/3ZckUJsKHz8fB4sIahwsCB/ZwkLBUZnuzaU1Gx2HZ3iMVcTQxRXfwbQM4IDV2S YC5+oOwXM1vdkxcGTPd076VY8tzWGcolBF+a4//ocS4hdRohQevQvSmXaicVYi57N75nUbn1 g3apFn6QiikaqFsiGl81yn/nmE/uP/0PcsSbRBhfZd8haUDu1F8yffUrTlb+1fB6qG0xIp+l ocbXPF6L+ZQaxZca/YoG+7qUFHGQ7b9p8uGLdnSAD20vMsjl0p2PQv3DrCRByspayt0FHJoB EToxdQTDRm/VQUoyLk/X7SBnbNTheakG0+9ij1DsXtGyvrxlU1VrW9ZFp0/AfuCbXMy1v/yl tziZiCP3q91piEGsp14hSeIIwU7g3cfS0vkXi3wi8ZF7IVvlk076+jh9HKA8YjagzcqvVYtf 8lNN9eQZBHhTROzgJn+c5zI1mnQJPK7gL4e+qVs0QC/XTjVt5o19iB5iMtZx++vHnQVkYFd6 5Ln5JfWaXMAsZQVPsf6QRjJt2MwW/bydTIFrjME6YhYwCrwPqcQnoEU/YiBscGavfu+ZpZDY JA2ZYW8Y1gy3kAXFL4SZiPa//lynlAQThwpQ761es5v6yEuen0Qwkk1FMOL7AbV6spQ6srO4 4KsKgkGJxf07q2s4ZYCzq00+ib+1qQ3dDEITMFM0uCTm75yqcbzcKYMip2kb2pnCeimBI0Lm 6QBmh8dRV2Hevxj39SR0Am5fFnshU08HZq3WqBRKjT7hjMz+8FUPbO2PGpjcLvBxO7rDAieX 3DcSRqiQgPfkOpjFFonWlSaMVurNIZa6sTkzIj/UGSB9SrwnnWucYLgbBzND1jc9Z7r1wReJ 5i4AISD2frFEoUVgp8nlQ4grkx3peTdinwJ8AEnTJWtfcd/W3pZ3o0FM+FvOlD/T0ej7T/W6 a8j5uI4E8UA+7uvGa2o3+TlJLQoPTtlfM0J1N9hbxZ053Y4gza1EwrhI2iZX3ZpaY9D+VDWT IEpzCHxgWdUUfMga/rP8hO/HmmBeSE9XJyyIYbwpOQlmOgrxfEKDpvZA2it9K9xRL2fvOYB9 6MJW3i0FXUWbgkxqlZngnA4SlW05CMzsqkJc9h6OH1uuzXWiSbE8fLD3b4it6NRAU4bGATia ILwSpm5yitOCB7/Q7HGg4BaAA94GHOTJfw3a31SjcIrXNEd5IdWVJxUDli++b/VGcrzN/Kj2 wpfk3g4xaJHJfCD8xiqiAnoXaWzPvZDXthtSYGB6K7HSgPMoO/NEZXq8sQtBgwjyzO/x4cS9 fCG+EvlECteiJC0EUAj3ui4O73DEk4bpyPDwjKUvFv2uxwF0nVcLhmmypor4dHokL5/1wAn7 7+VcD8394OH0wKs5v0yboZDF8GHwE27/4pALJUD0tbdyINgtFakPQYM7IJJfkveBnHXaT9Bi HATXQC45ttHJ+V0dIYUa1vIobn5ewtV/gpPSrmpZR6MD7AeMXr0V5sipCjZqX+sSUYFyPai/ sbbsXlO0UyiFmp9dGu7FOvcBIZUWOkty/lIq5eX6psSNlVGcrg3T4aGsDVNpzph6jZe0ayje SDh58OAlOEqYXK6jEYL32pN8jtlpjjWMc0WmnuFmwV5ey70x7Am5WXFi5rNo8F7TQacBUQzJ cuftyVnn2b8oIICNLXa2qpqVz6qF19+8ExIAun63O2L8YBScXAwbN3Wxl1te2g91N96IxVxF sHw8IgxPq3IzYO5OLuMPqHVGvs1w4qszi/ucl4QPdMEyiDVCw8f7EN5AHUPhOc9WhEoO7k+3 V8phn+D4Q7Y8bOTKfY+1uFNpUfqO0lQlHoyfrcN6vXyKZabRBriqt1DAekWN30BUxifAU3NB UvcMU4sN7ReooQNWT7ieZZ+P+Q4Pn8n+3LVsO442jPkq1Ux6kktVdXVEGIq2FRNblpJC6qP1 JHtw0ZuexQ0JsD6boQBbEX3JdmOcUxLeWTleKMl6D3n69JduNM161BHnqvlTYnsMOL7cvtBI nMs9hnXMhnM+x9pcZhuBoVqxcRhoUDjMeUSxzAikxUtE8ahaJWG4gxfU5+Klidp/WCBdsyHO vzvFZIbNzogGvSnzzT3w6ZujWyI/feGNrfr7ZeumfPnbGfNh1PHqXNVFsBsfh2nuhyu2BN2M tqr5ey6ORb8+sPKqWLXkbn3DNQYeoUkt7UuoUos8Eo/b2XFp1vmzTLdE8E/v49UrCN/fK3Nk YVFNa7LEs4i9O4qwiwtNQ5Xob1/z3x/6s0ypPaUoAuY3DsEwONJ2ieK85T1VLIoNNb3qRCEn o5sV24XXsfCd05CatQuUQKZ/PJmvVwi3J7vjlTRauwHjyRzAeMfe19/NtzdwH+jjdUivSmqY 3ZCiFtu66w6KUxV7jhD5ZoyHsOmoc9oDdytUGCLf5waEdHQz0Csbb8tZBQDkGRRzaTRasEad F4kMxO4ZuEKhL6e3U508dD9DmKZhWNXvo5ATf0DEnuKInL9siO9MkJVjb9OZFqgh2OAF2Z+A H+DHl3jdkFjCEKdyU2uc7jjvWjdnQmGKjANacsINBC46PcwG8ZrFjMHBoZ754plpWK07pE8k AgnmjTVWErK10y+4Xrf2zxgCKa1L9zlMShxNCOPhgtCLFsmRyPswqOZqjfriUf4FI1MW3Uo6 OuvmlBpgrawOLTas/TQiIVkHLhEKTbOV8BxIQCbe/uO1vToWwitOGXKfvAeGFj3nCmwWp6PO N+vXAzHY58Ibb5nh9XkFRiuT0pSdtJ2zmQhslYZuvfFJqzHogGyMEDhPU0Yq4pXXfXcsfjhp ZhZYsul+tHrhjNFZOn8n0qVhOWd7TGmDS5WorjWbkgVtxWUAAPa2KFU6pf+hPkXeMadvkY0B KwRM0ZweGBs1jvCtJWsPCJoDKNKOCyUjlim3kHb6ZQ6MxPWIoJCRbBw0heZ3L7vRtaJMjuty JCK5am2tWDrojP7oCQNFjpF3tYkmfBj+sSFuMkG82rCwvsUXwv06/2/zDsTDV+93ZzimzPwd BGBSJqyNIc1ks6GuySPy+Vyn80KSGQtI6OUh7jP7kQjbeYavTat/bKSpOa/2edbt2vzUiQpf owgEL1YkHYTIA66DvzuYhDjpLvBT0BlmPYWSUiRQR2pP8RerMYeg6Tka6gpFy/UP6oFVySku EUIV5II2jPKufPY/+p11fufEiXaONn46ElF1YVpP39Sjdh+r/ru5Kezx7lBLhpf2VXliI1Sp gO/F6oChdeOvgdAph1cvLCpg/TQfHO07TkIg+x+md5cTyRFB+qAa90cUmIwGOh8iAOL/TWx6 FV9qn4YOuuuUW7Dyi1juvsjU5iK8CZ67uQTDdvcrwJlO/1sO8ahtZ7eVmI+hxyI42dI6DZlx FOuudlZLk/lXs9KM2wpVUefWq3c+XaEavJtQieAPf9fdhE8CBblXfqZT+rwkeIYJ+kKyWmwm G3Po0vzMk/P2B/tdkRn6vXTugJ7ZTrt78Mc8WEZZK1ycX5yOoCJmmijlULXlSSta5lSkQQim vLW8W+XWIg64ueGul7pY0WpMtYpCj5VxpshtMiC93llPmVJjskRh10AOvA8AXb80p0z2Efps rtMJmnOOYSyfxA4rRj+8hgkwm1HPjHFXzixxNHIFxl9pShOTlIHm7rioOn72mEZi6Q8RpBsv 7hLK624B1wItZN7WCFGBeHe4/tkHtwLGlzEFid04kSbpfZG0x8bu+/OvNLqFU+3GJldv+hQG do5ONWCOB9NgGpxi8ep/dM+h08c7W26rKr3nIVxGXQ15eLqeq5OfmutrJ+lULdRte/WA2U5j +9ZQDVuXGKrQcH/7d3efObq0u+s6L2FrmAvM2T8qMDfF0AsLyofXrKwyZBR/NWSpuJy08Nh9 +lZn4256z71suij0AJi8YIpy2RSZSx+ylOH60XWv6cTj2NAFX6gXbh67Elk/PPaybYc/RQik +P73U6zwHVcDbe7q2HBKzWEqxmQYRlU0rEXpdomAtwO01hS8meOXxsraPjLISSx9Csbl0CBK e55DEZ3EfLnCX6VUCsW/mBtoEThgMZAIWDoOHt3tQyQJuco4tbVFdPpKLN9oWkp50VsEmCeI 4vO3ItzYqQ45IugPrVTr/xcbhgn3r0u9PclndbiDiS/tzjFOG80d5cMZPI2nZbMPlxgyp4BQ xKfl+tliCz+k3+qhc/JCMTMdnhSFszEfTBZ2pMbOiLrxQvx+Gsl2gdVz6isJBXwXO5EpCxgn AQ7ynP6XHnBr0jv08c3j3eTGvynzYeJLisqwOWGWUPH1JRDYWHPuW+OWTg4gyCOUCOUDhoBo yz/cfQiKclxbwz7jSuW9bKXc8QYAc2PDmnrwV9SLPvk0VUi8ItRdjzJDoYWcoLMmXRPcNfAy YUOmGBMEjxr38kBN2Z0rs2bGs+H9Y07UrTPghoLhZjrVbOHNPn620EdcJbxskWMPySqtxu9Z R7fQuTWK6AMDfPfYciWnEex0SRmO/4Otq/VblyYgmPBB99RRi4qUeeit9Tt7Akw57Rp1XUB2 qAnEnFRS/4VIswJZGazMZvn0QB9mtGmQqY9jXYmXyT5IpZ1kpNhs8r5Vw6hOT+RrACsd13vs lXwdaj+cLdwM9hFfIHf+8XClbvQmrpR6WpsenhyNQxfBGr9mAA0hHvRD4srNWOHRQdmfHgYa 442zLJS15oh2l2+YJ+bpZrQqkSBKYXtPwciBP1Y8EXsKJoCv+agnPUAlmQDoWtnt8xbfv2Pn txVeU3dIEprCpual7yDGQF4CUZdOAjGriCbfmk66Fl++5EYq0ywGccil169v5DLHkdfhSWph lPofHA9g1/MNNfBPF/tKpg1wnuedGPTkrfwFaTYVDAEfPgvwAbfg7+rmddN/g6v5TFG0vIBz Csw2rD4ChapMvuXAhgbuvsNkj+Pldxr6WpAUgmSnnaBR6dS4yEJQUEhcN8dNqCu3/SsoE0R7 XIY/gUDgfbLNfUHwUbIJy665SVYfjwuVlKEi6O53BndjiftsjsZLCt3XYuz27NDfMwfNQL0c gCN9Epv8VUYSaed95x+WPOLKI1HDkaZZY+NfghK52R004uSoSShfJ081hZI3UJknFVI/Bl// dIi3kr3J3BMw5LXAc8RbIG5H9bXHkmyfasa5mun0cVG7RnVcU8LJgkZIDtlhAkQzEFLv+EBn 0bvpPXZ2uU+ouwqPV7cG59boNyja8vcj2epyX+CPabPcxznWsNUO51WgTFlg3yDCKjh9qMgb ggMhpa9SQTQZeCWHzNVaUiU0nH6c74y1y1ZaDnJBVdTRL3XWVp+UTcn/IhO9vYoVXChdWi+S IanDglvpyHtW+WC1UhLGy2JetM+24j+eGoeg5pUIhQOQBVBwz3cKGuHbi6Mzk6MU1BZBgmw6 9DLCcRoMI3V9Iq1VpVKeuoXafxIet9E7+VAAinJIbtj1aVgMSiPIK6F5h0XkAHbZ4o2+9L+F kxKqCA+8B5UNyrZQA1l1MVOJuuWdVoUVHjQtW2WcJxQ5U0LUUazgOf3XdJuuUuICg1aEKBKa 5+zsFRBjdaauU9bo/EgJAqBe2wdyngBy8WPEJbcsSFZ7c5WbXO9YjrzDs9wXxC9noHOiUBJO lg5S02UVIE6htpkvDE9iuC9Q8RddtBvC3GjXEpcZj/o41z0L3u0md/wyWHtAduLO6MHC280P OnT/MhoCTJJ1sCNKfpptxvV/bPCp7YVKnnCf2dmMsrDxwgKcDFODn1wx59z4UbgBTiEVKAux 9NNfb8Z/URkxfuCqARjWvx/G6jVMEUayrduLppLCoWvC84210zqgdx+FHrxLI/u1OWDySaGn qY7QPOV5pVSW4oQwBUntnUkvmNBtIRwLgrc0hJfShMSHHKWF26yk3quX2OWD6WyB0KuFq50A /qJlgsRXMJ6wqn8Dr6HJlcPOpoBE8Z2CHEyc0EaJKRAezQXKSvBB/2FReBZpeC/rj19u5vs3 o3OWUAO5QtUTzhH+838bCGzUJoP76EafuIau1DnYafjzQHElMkmP4UD+9MgsMf4lJM0OiqaB 3R9u4DcvWXYoqZee2O08P+m+uv++sZEq6Zuc6VFE7KNpEFBrLQCpGyKRizbocBIJRZjZJoJy eQJ5fC7BX41uL5himZ374Vu1peHHSDvcRQjxkG/a0R++yp7dznmULUBE3gQbAAyIEscNYf78 S7EZyH9m+54HXNiojS13SBTgH7sYpbQ/trlQeQxAwv6PiY/UPo++QPTj0OKryYP+9PK0RLZR zlwxUiymE6nXe2GMaRBQF+aJWIRfC2u1bm6tx2rnSt6GQt3adPCQlDAUGJJAt6BnGBKrg3/1 Nt+FfktHSGgGEnvP1wa+fvXDolDrrvz6ZUVzlHsxW9TmB/Sy2z88/wev2AzXKPNRv7fPag5j sB0FPEvZFpaxg5ku2Ynt8q2RVjg7XRvB9MSp8O1ieyL3QIZUohkz6kJMuUYRdH2Xf0Aw9lIB MxtpmZ+RJawSrmLoPtfdYKckDdZk1Zssg03s8dYMmnkp7E8QBPvvRDr/x0jLwqQy1kBcn5zP zjy/NsyXYlQ191MIdAMgjlWmD81QEEcdKwr9/vmdRcX8hFtEaWY21oYMsiNYMxoH7s8kxIbj YTMm7UWqju7jKLRKX9tiqdm3ZjElpjqxeuhswuugKeLz7LcSUaV6MULm7IGpUGAsI6JGSZfY yMRW+44ZqTV45CA080njgMcazDPt7VWsIKaq/QwAjaWf0M/F54Wi8W1uEpiXbhT/SsS75ULW wvEQKEOnTFmrgH5rGjHwauEKhjMlvxev4djHcYssXs4A7O8OxtKsxuSfR7zAbH9c8+kZF3mR SA/OCtiPCCnZwXJcRvAgrpiCxWJo3aviB36GMdAd4jAEp8mHl9a9ynd09+U/0hZzlUcr4jqK gPika2cBvEIPmg8Vi0y8vcgRyDG7WtoE6IslpGvutw6T6iTF0v5Kj+Ng5t4PlMwRzD8rKM4G s6cSUSY8AmYCA5UV5NloutSYB4uODmKKqD1WJLEdg6F++gwHshO2KlfG6E90g0CHSuV1ZOmY 9CIs/eCAg8X/BO2M2fjAdPNi0AmWxluzn/2MacfzCH8lx5FfrbmVMGgHjIw3fYyMvqb+2ZbD t/hzatcQTd7tU/7/I7e4Oj3b1R2uGilTxdu/NSPmwRmIbWag9yiEJW7q+wyGzyfyNsNnoozk swCqVYv2rc15v5Jz9rgvT17gGrCFxc8WlwMBHtwOuKvWUhTg3XPEGzr8V8XuAB8FqYQt4lLx VUMz0jLkuxRsf3DMeEyF1vj51vYrpViOVDPae1/Zui6BFs1D+cOQWnYmUuWeuMZrf68Yx5Co tz5IdIc03k3tAliUVC7cdYiU3VV7SwclzhvKGitO/0TCu2JZ9RT97X1FkxHd0zb3lPRl+Ymt roMbl/TJG7qUiYLURu7ocW5xc8jWVT2QbxgmLbYk8yVtD2s5y0gocAEXYndDRKpHG+svSt8w +FvNPxuVzx0VOc+beW7yqPuvZVd+ht0rs38OJqyma6PPLVG9v3DVBjTVy2ZfmMoRM0LK1zYD 1jqqnAdJbH5otqzWJjeuyoT6Mf0hz5+Y03CeNBmNAxveVZE2qdiuUjlwkDxaD3uIBkgOVphh 04v66UfkaAyHD8d5xppJGTCDQPtoiQPHc4Z4wEEp/dOocN6Vih47ReOmXphONG6tZoh6z0uF JwE93+nEMCoilx1yeDjEo3FdxyhT4IshA+2Y3DvBzOApMs4HaqoVOuZo8O4yZ29aOJGfL79x gtPxLS5sdcGpln4AKObI8luF126PHIqL5QXcy7b8OyDfkFpb8JvUMGup1o/FfLGkDclpI3Gs mnlRESFTUjy0QxNBpSLiIzD6aWfQiywkZJ6gjQKp9Jhrn2YiSh+myCcMV1Cc5yhQQFGYfDMf mT4bUBkP5NPcfA+e0w9TIpTWP0x4BexuXWSFf6Waf1BjTMft8xTe3GD8cy8fiZCbedLbtsBp OQTiaz5KGYXIcu3kI08Op524NnJ8rgANVWx4Gesculg4nvP2dkrcHFHB2xm1GPci0azmoatq zmjJ57X9S+HLf4wQ0LpzUMOYg1zPeFB8x4qB+XvVyQfrIs2DcNbteoMxAhvdXANS86/SrZi+ XVm0xZN0rzz8iH0idmL2PEkmG9Nq7JZTXskalT4w1ystud7Gj3otfI+Ol/MZxdswwLiMuaEl sb8hbxNGAOuxIBj/EmjI13dknDCG/qj/4qsiv+bvxhUXV9HkZFS7Ctq05HtPIx56eNypyl7E hKypEtXIYkS8B+tvsaHP0nMjrse3XzcHoQ9kIi0RohPBehBE2tVWl8isRI0Z7OfgPZinCOPO 9HISj0WnXU5TvqqWLBQDxIaoGrmJU2oNjnqSfuQ5oCS8wA9IaEHj5u2qsEA42sUPviBTBfTr bMxJeMEtJNLjCpqqOB3jzuoirsR/3Jr7II9TbwWrpcrAp6xmhSB7U+hINKoT19mBdWlJ/Vh4 AOioDn+Cmels8JPM2tU/2JHFzu/L3lOzQEQFq+oJpRO6ovo3onbvPzHnm6amdEab2LCuJlXH fvDjuSjqdyR0TWGSXKkINwJwtjf2vFJQbAPuh763p8vwphfyoXOfnTSuSsPHb5k1J+uNOiK4 6Rf6+uawN4C6ERJdl9ha0PBsDz7BwDvpvFqqb8FPqtc4Y+skWjw74SBFbI0lwgPk18SrSs9Q PJi3w8vZILw3v1bcy3RRISRWUoU+7WVpaiNZp0XR+GMXs2KBsEYpID/hurY4/mN1QseIRBer mrlumVjYkvekgvDWmomYJSeg1mQrXEz/8UBudK720P2QHvF0i72rGZaaVkeOQwa4L918bHVQ rFCx2TvY3Nzdj0YQGPKFKfM/ZISZGi6ayXfpwJq3jQJUu6Q7ChShGedELCav7dtUSOb46s8b +/8LJVn3tbZxm6jb25m/qsnFIc/grsi+iWa/mFvPv0s+/zwkoXi1lf0uXJjnUwGBIxoVQE3q vcL/syh1oDIEEPHZ3tVLJ2czxsJ+hW77wd4LVtRCi9/+7iBTuzoG+e+PXLX6zhZ33VNN6BSs wxIP4mPTcpbrc+FBVM5D3kDMiMNuTIKXhNwt83lYi0x5fVP7/nW6xsC/o5b7td3/v7tB483V Oy8Wie2ysZjz4vMAXK85ASeeiHZVtFNbWtLD6s/jo700T2By44Og4lxE8XZRDf+fdzbuxc67 XY3+BKM7t4AqQMDSmOAmQ0aBtJ6QOv8ZhqeFVC4ZnjI8EkxKTYllCzdfo4LMX07hRGISYh0a mlCYAus82/MGR/KtK0eogitNovXztROe3G6Odk3kG1PEbIDmC4d3vuow4IZw2vdVYjp1F2NQ ZaDQxffQXOU6B19kGqpuVGKqsbhiueAHxngGbMdB1QbZEu6BtdW2CrqMXgrqNNdhCsedL0rH a6fm2x7UrmByLE35TbG9gUWwi/BmC1coqpi4x+LbSA2QSQaQzOTyVmw4GefX+H505qJNq6ST hxu6gNL3jMvUXtTXlRFOFoufP+whHiVMpcHyYJKV0IlkT5banxBYJ5WFYzj3vMAu1M0eYPMx QkP11dOdc3QVswlIQ5HkAU7UJEGdR+H6FNjQfMT7UCEMh5hlpA89Q6fxy0AxP9NVyR0m3YdO kB5qu8PhFSyA/Sq3AWaDcYERg0FGlgi56mlOKPjbsHuE8i0fsNjlw/+G2BiJqIZgvQSIyE4a csNLOn1r+tlO3LK/9hfyF93fZ9HEYGy6PkltyyqvZ90xvHQRXYgWffG62VYCVOr1s282mDMv nCvddF5jc/dD/OWapPKrjbZiWXOBVGxHO/wXFti0xRSyXrvP7SYiHmHFTUImGBByjd9FHMZu ILNsPtujdBO+3T1dnyZfs4KNb1SvpD6HGCNhgsI3KEEFxDzaSqqn72ZX9rdfcD9wJc+jIMq6 jh2biCwub7zy2CHflyWuNE7KaKR7wkLBheRklhgFUpRgcD6Rkbo6zfS7sxSyRYKYn/lytucb O9QHiaKQ7got3cqt6Wrv28DDEJnHWI4BpORQGZwEHT5N/EgeElV+oeiZ2JHVtYuryColksV3 0Y4DpgUwDTpnd7mP5RoA3HCUwrZ/U6j3K7zg4rOtujQNxhUYPS5qTrHrr2QO15c4qcD/Ce9P CfyWWe/wAGceX2fGFHfKNJGTKmlbvn9PhJ1U6EOOkSRFgX5lPWF8wel/1KrflLfTcZlQm1cx MnVBahqgq1SSQiH5TSWukzapzpcQ0s9mhSkOjici+S1NOzyAQSTag+RtvVl+iJIFB/L+Pb4c Bd12xu7Muh1MmoYzehOp2S561iFfX462ZNZdv3/oHI2112+WbEfir6oonHUH05E/rHMsnrNu 2ol0UtdLa1Txnyi3LXk0+NfE6WkGTDCCRi7wG/N5QidysSSUdqBeErv6PXohzUzt4oP8Xx0u jJIbaVGCbWIwoahI4fxtUn4izcy69gEk3QYQDR4UKLjqjKtkVHUpCRgpQ+qnKxIhhWbVLpty SyzrY/AxO1ET2mRWq/AwRwIt+aaJqq79FxDhFuXeBiFxSBEJsLKtuNLs261F6JRCB3nL/mTI gvFCBkSvc2oUPlMz4UMv1Eu6dr0JAkmwgsEuZPrmr9FT1K2qmh2BlvYCDc49OUN+Ravkyj+L 1v6ZRvW7T4d1wVZ3eYO6/zbbnzwjRyAkU/RSPdaTZ7oVpysQYuK/plKdUBxQr1cbczVqvJg6 4a51Z6s5SnWXC8bWgh3Ep1OT0ZZca+qrST+lv76Cv+z5izZjYnVof4hrlHbsVD4Defy5cdNn WcsqgS518oJWni12CZMEv/jgD62dMpGCLsVr4oV8eAAprgzdXqqhLW3KHbPts2+K4UaFTfP2 Ntu0bKyCY0K/q5n2xMjpFoiQzFpQyna/yM8jK1XrlQlBvciyLPVtPRoGIv3d0dvEKCFb+4fu e/wY6BRT0wWlFQSM6Vg3RMRlBJ2MFbhrlmIiTodSNdL7H82CL/pJvqRVAulEzjxE5JPW8WVT t5C9T5CVk6HdIoE2GfYAvJ6Z0QXKfB6dqDWf5/wltcSGgvS9T/ByEv9ke6mlvkiPTrZ+eQ6d S6zb0y4ygpEM+G4PTnGrMaozFlPnoDHLp9i3o6+gjPOLXgFuKCObzdCJMYcMJmPGnXWDFQ9d IHIdJJezD9EsIHRTjf8HnXSUlLcwtm8H3Q9sscEQeRFQmnrXDyqAC+HLv5pz8kxHWWg4IeJJ 76w3BRRdEkY6AJQya4wUzrY85MlMpj31cG2o0j2Z87T1/zQ4Kr6F6N9Sg4vyhTU94Dh5VxJm 2a8vpzGpDB/q8rlsS3o3VMhDpmMn4CJxnz2kZUO+Izv54f8L8GEacnX3H2Pogzt+5nVhthrF ce+MzTGxWuu4b/teuFHs4aI6dZJyJ+o6yJ9CuuMbbEd9OrWSYyc2RscoNbCHOPybu5sVNp3C 6FfnErgnr97oXkvlCfOweLR6S3iO9Tot1c93nMQJk2jf0dPKCzguZirkGvBoJgSYFB3DdL9V qTcdZhibhkV2la4MOsHlU+M20n02JS6zvj+HJ1m5A/BLyh4N09im1XWSnKIQM2bxbs5fNrki rD76InEdJc+9lJ43mS/FIUU8RW1Ciqv5/bWtlVvx0dsHtkWINo06d/gwUA5wxBFNcBZ7sDrj m5I7EcMr2b5FzaLU38SQNN4K07wZyEH+CTvebbkEpcidX7zn8yQCNG0AJanGwL8QAVVpeXqn WdwhnbUtxFwTS2MZWifSipkGp96MOREtiz/4X+3sodNm/QdRczduErpCiWk/tz1RlxZedh6o S/Yyo2scKHWWD6jabvtMmaCZO1lgLswa1yyT0eiF81jVQh2aMpXJyqWzp46TtK7nEqaYb2TI 5dOay7IHbHub9iU3E6kiJgdD9NZWf3nlTwbNS59ZY4yKH4FmqpnC4DZGsA7Tmd4URg9ukgd5 W39pwRmTfHeyYN0DKYBgixfJSFV6bQnyQumvoODYe0KM1ld2rt2BgvByg8b9B4h9S+w5LEez UVPHUhoLKU9TPsYmHkgWDO2XZ6g/r2n77Vg9RGsyQAipaJvcafzo4sBXBHEGZVYFrpC4mdJX OXCq6bxSjiIWc8ok40+RrwTWBS7Gg8Fbfi7wD0LAuf1QYaFG43F5qdPuJDEHA4d+b+MC/hm0 8iu4e5GqTUlV4GhtxOQMxHBt+/gLfvGY4DDKc/TXAnKENc8qIxGRBFeA1aK9Kl5LgK0D0BFR 4D7Yg6qbrxBTkiTWGBEuVXe+sQ/tzTm+aBfCx9tEllehVecIdcITKG2GHCFNJCryme3gLkUi s3toz7Fl/RZWfhCb0Cr9jCY7NH4X/5dhlkz6le044oh5s6+JBq/qStXUxF133EjVhjYTEuau PXdrYUr5Gm0M0TLMuv6RW/ux/5ttHqshiLXvZlFVvUL3k0y2GuJh2NDwY1t1ZoSLEcXca0k7 xjJsjEp/wSDVIhWnaEqzfQdzHMR6fpfMIm6lJkQ+qJmklLtKpGOQmElHHexT3PhX6PoeSR0u p/UIF1/fMNVZoA1MtjKQ8JxJ8TFfw8JRvkqUBgb/ltATe8XWlD4NazkMQPZnxfM+ykeP5TUM Tx+zhKVL3hcERIZoudWUsRXkN12gQWG7AQxRZmNuB8G6ej4a0cBLNPU9NZmA3ne+oh7a/InM QtzmOqcs/Ec1L13179u6CNHgLTAAcMIz2DJOp8C9Gie3I3/J2nKyVkE1m104hLAm7xtavw06 8HuTT+tqSBveCQiVwTjkwdobIlaZ5efL1ueD/6g+UhobI6jjz4GtXv37Ki0k0fyhDUKvZHOC Rb7RK8cTnH5AFxW9yjdoh7DYFY1Auy6D8GLrMXEICqfQJU+O9iCVr7mfQXuwUDlOP4I23NcV xLqVjwxe9bsy5grbS7nlU9RyzQ8bDQC8zNvY+4JMs39abSsfbfCxUzhrm3ErpK/vhmbeUj+a W+l4+8JKP4LAIvGAWOz5dLGenH9zp4Pe9uDgAd17U3Q+oPUHsdrYm2cvVQjQE+9X4xgE+JKi 1Zb/QJPFQX3L4ikGiJ/349YfyA0pRLKM8ks5T8VNYWfqrRyrAgTv/d6PQKFvcFKsyTnUFsA6 POt7ItJy4gIQUTqpfTgb91SWjeuCqJ31mVbrZoSbYhwTLt5MgD50KoV3VbQEJkXdLdrQbwTd 4PmJkBXVvsNFejKIh0Udvo9jcNaXw9HXsC3Rkox7B49nLZdDiu0ZR5AP37D260CABfGRrwfi zRcsvalQvrBF37jJDXkoMJsvKzLi2CgQtWJYPgdlKUrAN6eV5hyX+ewMam6nGPjTyXmTHEdR yf4He+u2mDWlSZD8XKvxuvnKevjEWpeZTsZxY59M2CtIY4+cj/EDdRe9UBRlZiRYXGURFhXq gLu4pgrnw8THV829i3W+o4Ezj1FuelJa8+hI8gMqu8K76s/TgqGc5JxsnhqoH2L9dVoJAKVB IvK8w3pcG+Jy3b6EVZp6ItXGrad5fyXXCaPV38ewwQFWrGI4xzbGlYHCgUYSMDPuZ50tnoNo 7d/r4MtfTthZkXutlAQAVuyscoa6X+OeDLahSaIqsuOIqir4saArCiKuphYJnAGZ+mWei/Z8 VPWabMyaznvssmurK3w4PVj5WL0fbuAYx5Y9URkaIexxHkhnX2L86buUGy5iaumN4wOUyhdw TG2xwq53PHWSeYlQfzXKRvdLeRQrKxQGfNKuavF4Uh1UwzYeBtyUUbUw4ACLuJLZD+H76ae7 6gTvIRJKYknQqF/BDqsfEmcGOEiSUXvSgga8Ad/LTLCJXn/Y+S+aBiuo9MHBqaeP7/m4V0Xz LzfUHxY7b0S1fCF520hTfsUu7kUcwDbhub1LrDMz3BSz24qfAeoTP9YWhc1Krlnytjr7fM1N jOBaPaPgTNgua9eo/giWI/gkmJ0FuT9h2eyBpEAefWJMTApyNwecR/f1p3yNsRPDjoiGk8sb y01yGAoiuGyEBa9nPky1LtS6r2O2hx3OgOB9cilzdhEKNM3xjdLesNdrd30VXyLPmAZbTw8a LX1dvP3mRPLQpkeuL92SYwHTOmBKM7xvtr3fo92iT+a8uagut4zKQ3Swi/c7IRWFvmDcT7YW 7Wx8FReZlo3WzfyLu9InpnRVHpapBbL1XMdpfROlhpDqXhfdfaw5uEJ7cOKLZdv7mGaNBUEI pCj6D3HQLj6XmEtMdZiknWKwiLpnn3FsYRo6GCDnUHUMdS/21cW3jVDBakxaS7qqQaX6oDkU CxrnPJPSLk+aed/sDyhKRibiOrnKQGLCJQgbjxLsIlWz4uWp/jKOcuMp/Maqg5iVSP0RJAks bDF9Ae7uvjSVKkINisVnkAUyeztLUHPYZouoFY0OMm8cryOsBkFgMAZ0VqSQSlQ/MoY+EhgK mLzXwV5gmQ/IH2z5KGIBV9ixDkIOHm6JBHrSt6TWbJJAGvnMavW5YuixnzQy2S1Ju+jQa53B V8XEqT6sJnP5T7Yl6VkxpJROyeZR8kICmke7l32hJe7QetgRkodlUMLDMABPVgiXQ6s8Oaee Tt60+j14BsxiALtpQMgILisQgcJ8f8rcatMe1pBpumtvGEchj0dLqM3rTgPmwUWV5QGP5TRK rqhH3brYy7JgVKhgAQc3qx+UXlPbU91aWt0pKn9KKn9f3+viUgWhSXHAS9RXOVbMhQOljLkZ PkEPIFJOjPtKK+ia6/aIIct76AVDTbbHL5q3en3q5t0hqMWJMVuwm1S42SU6qvCDJnUO0TTx fT/benFrf2OsXU7IH/joJwe6HeHfTzKpLZJsRGgMXcfLKdKeQrREpbMRt65U8TVeTqitCDTz fF8NRZ0vFXGZq6YzYMZIztjXG3spukfIemTXOq6fClqrmhHGXbzMYryN/CkrQrmNaMGh8FcD TfyXHOALu5RU4OP/vAmQlqjuBZbT4OQsiYdnb78i0MYb+O+F95I1J8M5U9O9B1fsFGcW043I pcs6HsW+F34rX8idTatRUng4VgXB3MVq1gikh79nsTUYCGLWEzOk9T7V2sIm5BlalNFLOKxZ YEy+fkjBBzlSYVV6WNt2wv+Cu1NVj62u3n4jDEOM6QeslsSLVwrJ1QwmpsH+XIdxeX7p8i9x vMpGH8uyzMfZM/VMqcXILv+SbX1OAHLDTQNLlH/M7LRX2z8PXoCFAv8Uyao0oyGnH99D0Lbh Ul1y6g1mIZJ8RN3EigFxaci1hkxSQQ9bpBqnnmuwobPgK2VcKgUs5GgvwJMtBonb0fE5LQlY K8988dCGadlhVmomrbZVNvvpLQPs6J1JHzaPHqu1BwQj28LbVh3ZlKPT61ip+fVWNr/AtSY0 H9tcYmmIQavSO3qKzjvgqZcw9G4uWgthEJFZK6o2mDZTJ7+VOH8KA6cIGmEHtAOrLMvZzZ5H ytQazfOvRN+lSkhplBqBYRtGIlXifBxr70uDvqk2jfat1IjGl8dJLsf0kWJAs7/cWQltOki0 GMMxrmMeEh98L/l4YgQSTDf277JdXuG3jPX4XgaWCjzccAaqeViMqzT1hoqSNOFSS3kVV6tN aVgAOJHLYAhH0L0PD+6dn2BOebLq0wwdtHwGUxFjQw1+JhvtT82b6nmdJOuPeaoP2YpnfbUn fI4XKGzAg7DODOXFhuoUcJqPBNFr4z1muT/de2aSiwUY52WXhmZTFHB1pLQyc6V/2Iv9cbiV pia6vQsCMly+R2/DPt2V7Zpih+lM4ivQUhVa27HXiLliiMa6DwaOrhUBgTEgDrOPkPbgfVqy dAjarOoVJTFNeLFrbOqTKfXfBkhRw2HOeZdzHMFHhLL7xVTRaxlTh5Bfu5fbfevDYv+3YSs/ 8zsxXs8xrA2JkZUG9gdi1SQLzzqN9Gea0b1qbQh/MmZFn9cCGV39ONd7QVYeOJ05CKnMYm6t E71bCCGXpKZscVUfqygwUNEUnvQyly+1MTBcIEa4thwc2qz1AiO3NmZHjeJppO1fKFo5AMQP E+jbSsjSuo4q2VWZKAtVpha9ESQAkmwP5v8YO2BoZY14xt+5VTA7Eex7FugW/zvyJu2AW9sb 0zSFGnbbvwjxwDzDhVrQ5YByNSQZ7zAM8W9iopuR19/SneA8BDlqUJ03w2doE9LK31AQ3EKj 6j0tW/yS6PJjDjVG9Hm0ffKRHgUM2jLhJ3pNiDDT2CMu1jALV0wdJDwJGbRRP5+93OPLa+Xu 1X+kPW8nLur+ciBqs028a9hYp9ywMd/cMkMHGZ+yL8uNFu2t7cffv4Db5XerrtU0ktP+Nlr+ 9VaQEM3nUNyrOXDjFnbBmFqj4sA3eB9D9mB3nCB4wEIK0yLFCQf9oRFheUYRNZZyG6bvh0j0 TDPf8ZLeI7Tpn7fneTkMNRmER5r4YHlyk5LqzNSwQ+HdskbA61bt3o2S01zpzBwU0Nldd8zL +MuqbIMlx0xMaSetC49rAwKD+Qgo1gcdzgGwLmY4k7ax0UrVBor4mmAXf2OqrB7AYtL++Eay Qia3tb5ln/Z6q7n1c6QKzxt3Q+D+jnrC9rI4GEkRjw0pb3sA0p9Vy+3gIKcCkW5XJ6io89A2 cnVKg3vqXDkD3myYsKXsNmvqbWRKqSAkK+rrq32dOt7Hr6dWaEsCL36YWYpguYJmySV0QH2K 8Q6AkLrBZUpk50IwYk59i8WGzC36dQeMc9nw58lKm5jsgLggW1TjzpdLk6mvH9ngWbzaq4l2 oRijxVXrK2lpYNFC0/9ICPJnJg3bKBu09r1hd+ZsASn/D6BqgJsNBKyjDuTLHV0SGPnXDma9 fqRZqTaBhfSaSUhSbNW0aBJ9eAMLal3JviU3qtLNsieP1snWD7/pJKBVbYQzdw/IpcbMagT1 Ll+si19RIhC/nDl1yxGG4pAcrNZ45Czq7db8lavaHVik+e72k9i02rCcvAzZmMH6VdzNIxAr is/rLUX+0R/MRi5N/Lt4EJSUrPaCV6509gdxNaADdb1R1DC+d1AG0KfxDv7d3lYUF2l+WjM7 ICIsKkx5Ec11sTQgR1bSjTys0rq47L58xTDNfi1xjB14KSsVkf3JKHNUE+yFEycDyG71QRMg 1E96w1+YrjDrATFcj8wxJK7gM29AzFa7LEAEUnJ/h6j1n/hL1dHr+REUYQKQZ4errbdTN2Ij I8j2GXLeO1eXmEsnCUxOsB+OvPetuk2cxJDVnwEv393Yp4hbqxMiFDfSrEVc89pP494qQO0B pOGUQp/+Af9H9Hxkh8SNIptx0qNQVIWr+pQco7hVPDS04YkU5zaHGFTQoGqY/NopR8Ltvyy4 wmE3lBx1/DwE4XiZx7TQSEMsiBMISkA/OnNbGUCEUdM49+xNCSgzCXvGHputYekNkibGwHkm OeLylTwH+XXnTDebyPKduVRu4671SFVO1dLRXNg5bV2mwGibw8wXhMx5RQ02467xlkbO6hDV 099Ao0gSb0TMYvG2wYeQHmNHDoBjPyYf2aq+JQ97juMO3ceaMkbgUWFt+mf+Xc6RC5qlrekZ 2QSNPTvxMCkKx6rEsAAW2eLFhhks15J7QhyrLfqTsc6pUsP4YDjrS995O6GD1XrUY4CjQnR6 EJDWSkdavh6jSM0tZvUjRa6anr11IgQ8ZjSoML3ojUoGGXtlDKp6YEBw0z5AC9zOrE3soVNA Ywk5PrKifDWgG+2GVyHIjHK3pF+kIJwk7DKQqT7fjj7BulqZFm1fT688HHvXhDdUbL+9E0tm MjIt4iZoWGG1Gf9skhTr+4/cbfuFdmgcMFy6hLBfdt8qucoPdNmOFxYloj+geC08laAjdCGF yWVrHyPlXG0dMgwjtraw+s1IJBlw3kxocAXpshvGBFz6obWxQMkiqZx1PGXiQtirG8pOAynZ DjkfvV/6BlW+sLo2q8OqNKSFjzsgPSrRfrPnKP5BXNhqweDMT6BdQoNAqatHpwE15dgVvlRP pez/VOY1FwYb/6KgyyurTcztz/F+3Oqi7T3g7RHsxGN50s5hPwkhnU1W+NR/pb4vXCD7xgXP K+FhRsvNS2XMNudyDqcC7Us+e5NnvDoCakQ0FZKGLW4PbfkDKAq3NfJztboa8rMC19TtSBqx M6G1V4R9Nw4rnupgpX3KaO9G7tGl2mUjjAfxq59Tt5HIdtZ7fkwAow3xTPPTshmv4jm4JEQ9 nL6xfEeNwZNx/v5bq9xDBrmHQP9iuTaZBxf5wd1iJhwrqPR1/Tc3mIjrodqfJo3FDxPf0feB dut+EsHfgNFKcZRJeTnpkWMwXzskJ+B5aaxi6ZsC7L7FMhJLyB4XKWPGKm5pWNB6KP5I7PC3 FdQxcH1uyGgcRP6s4bxE0t+qTAZEKwYXiWYimgQSy7uKoh8Cw2MyRxmbLc5XiFybinS41iPj VjcGHScK7BUENWre78OKoBjIrabKiKGOs6bti6OjeGqcCKdNsQm333PH1PMJ938meJhLzAC/ hVc31ObetnMG93bkoafuFlzDBqBcIZRjxjd2LycJwge2HIrM7Cr7JkXqO9KowLWydU2nJtAi iFrvg1/gCOvmNNp65KJIry4wjEsyJXbbIRdQMHUAbRWC/qsT2Hq51flE9Y/1V9PufT2ICOqE 0gCkYGMkRfxLiChitU1kjpu/BFJ9qLTWLm7zve0xFDWHV7DBHiXcD6X7Q2GF3zxmnWKigMmU urgToNAMc+tFu0v7u3KsDvZAyfC3R/HmPY7PyyHx4z7cGVmHAcAim1goc1eUPpE4Wpcmpn+n 4/Dv/cKZ9cJV+CktNgTrQ41+QdJ82Wuw/4Qz1MyOnnRoy7V2CFCVcQvzCC/Z9MX08HaiBilF Db2o9OwrQzOwtGmngNPXiSkmKMIerFc9poVeNmQssvCv/zNph7iwGBB7JCFoTGJpyLtezLEo sD0eFhjir7G+XnCv3bMdFx9/u9kLDA4ew8Wze5WeFVtbz4185g10DfHKhs5O59lZbasyrZu3 nNYUHJ1CcqZ5qvWoh8xYXLB9TMdtLaGY114yAR0dueeSOM5ZpEN8Du7/aYacP83vWLIUWXmp ywozD1J5OV9sagMUageDGWqFnwuwTPPffFPYmTP/a21SPo6a2YJ7AEWP3zullKweP7aK9CXm HmRZGLV70WAokhZ+5HKLSdjDcp6vML84r2tVzcAn8jr0AXg0bO0aYgE60TCqI4lWREI6T1C9 N6Y7TYdNOKpXKZ73eXsUYQ/8w8IIB9f0wwOtjGm9Y/KasGPqbj1Tr6IPM5EVqWOeNFxO0VrQ BCcCup77neQJL9I5750oxRT1MSOLH5Q5U+4+9OaNmtX/usnLTY0NsTcgG5fJwheuT5WypHhT 5NGgXT2qsT2wkuQw5LrgpY2wYi8P7h6BvMOJDF8NM3JeQNG4wDLTAm28tWO4N7xH6lvzr+pa mz8y7KdtyBjGkvhVQ28UEzzt1bLMo5n9D6t7nkHMNZ6gx+eMzmv8MLPVM1ewXnHt2gNeFLfB H/tSs1C/FC0LOovvX9N9I77QRAtvzeTcmEhie5Tn28FlVzY7fXEsRKvh2wPfeGM+AWXm1GLx R50+PtKzF1JiD0mDkxKfRuoIzPi+tjR2SGH5UFt0mBA+kK2tkUJbt6lZvVsBP5o+XxTI8+wt uuJdkmLkmjbGiiMerIZ2XlNN8WpzlEWLQun/mCzrJRpZ2K0CIED5PQYQ3h8kKAVMHVb5kbD4 meKx9N93mlcp7HYbUdBqZAeAr2R3V8dSJJMepqxMcQ/joZtIdjqI2U6QPy8HIbSujetMjlAj OhZrjARHSzAsDRsjez8Mua1cM19Sp9ArnSeNEGqCmpuR1i2OCXdd9FeAYV1Xl71Hr1JB7UG9 YmDybZndAflokcKZRekY6R3Eys9EBLYVF43PSQoqY4Oq2XiwmlzQ/7303ccacnvpsPKmFVtG qpqT0ggveC9CdKTEBjrA3X67JoBaXnoxZIn6gm30GZxoQpsW6JUwU+XxTSsdaV5TncUEzgkp ZXDt0yNVZkyuVla/1HdZQDM7u5Oo93oEhEr1YDj1PJOJoUa1AGZDpWe03Iy6kTBIPDD2EfxE v9Gf+/tG3qiN0oLH21DSB1N+tqsfztSFFPmLaqJW0MkfBCmKc3lHBaym5xlK1Xw+833FkqqT hEDpTyLWCbBMAfW3VV0EUGYEMsYvX3VauskQiDN4q1QsKzsdJmnaqpoQs8/S+63FzlO7OwgX Dzar8v8xGd0Iug2MbFVL6c2cgbWDF4r1fGP4GLL7giry+u1kaK6n+3ZboT2Q39oKGKVS74Ns HR4HpO9NtvLgTaoNr9otTFT4rRpSRBXIiB80PLOxhjaPxT8NylggepDqY+4wLbjjevCzkrAO qClFQ/IrY67+ipUT1OppJDWD9k/DFAtNTauM4qK++/Wd2+kC4w5IAde/D+NG1bAMQEumZ2RB 6REYRfLl7qhTkDDkAZP7eAdKL72V5kJVIhlkkKBTNLTQ1Dff62b+edSsY1d6SdGnhzmfJO3G uyey60qve3RwsGl/wwnux6dTYI2qYX5kU78+08gCdKbFY2aYtY5tsLXRo/RP4uoCGi1C9hm5 e8PGNS2PEBu1/e17TvPMhy24xBSSEMRlLDUUnXZ70s24PTS7DT0BmPd9A2bBwj2n81SexZv8 uvTQCeo8XC3U7lE9WO9HkzJwJ17YvCO1T6JRhz8FWQtsPk1Ck+qCwxL+Tbm2mP1yWDEDdgLQ 2HF5plTE0YTtHy9Ovuy3/rBy5iNDe7ML+MoAhThIm+Xt2gsl3fJy7z4cdJNUmkHhTCXZbile 4pchLG38arR9IjENb1S7vYtgrMW5wRw7l3PPd01KRaFiNECl7pZFy7OigoV9ZuGkOHmUPYCk Erplfx8Qnw32DbzTeIw7RvmL1+YBEttJGDEclKGQdDkkJoCMskc8VUjsbZvYJMJ6izqdBA7Y T520LUh63Sb+L5+OLr1eNSHvD45/Ncnmvs5JCFsgZAEoRktmZ7X8Oy5VTfrpR9VvctU7yGS9 3MAi+LR5DOimv7aG4FWlVBCPqH489B5eh7nj1mlqmQq+svoySHQLYuLsSGgO29EWYpOwkQKd 4ynoNbUVJMBwvqeHUlIUp5Rd2jP14Z07w/GMocOIrOOuXfS//ejJ3Na0Bjtfa+3MzF+HfZk7 nbNQPVlrLpTXnYh3u0eV3KXhuNgge4SqpTgvwNoUqlLB7HNWov1QxQ34QtWnfO8LVXW8rUB2 HJuWy+hkvcvFOQTAJv8Hdi3Hxac/7HgUw5AFIMGesJpLvSjagGv05KXBVfuRL0vEsbj/dQ2R coiMbM+UrrLVi4G8oTQpSkto89U8nzmzTuDYDVY2a9V0WFPNJ95kiOpZa0xHlEiXxp+qSbI6 8nMCgHIcxLVuQmF+s9kXfdS7g9G0HP2z4K7vB/7tVfpLKSJU5Sdm9xW9tCsI8D8jbe2cllb7 cpecYuV1hIqHKK6tioRsZmrJPV2p+7cP5BDauzwvZB+jTaImWOhHklZ3PehRm5XBVsrShT8b pp7LLllQ2jPtywQKr+WEmRSeU53WSYdb0jvGm9svtRNIAY/phJTSa3gOsB8jffIK73ZECASf luSv4NKqD9jXybEHQhm3qjrdidVSTBJ81ljWXOaYVpTpvR17xROlPcfdmoO5RXplK55O35Ew 7lP/nQeKOkaYNZp6dgY33J0Yek0PdlryROROh9Mxp9Yo8RXnzIyfl6a7r5MOHx674ryMxIRj QbBUnO+4Ys4Y7HOtSEbvzEL8FM/FrtEPd0YTb8wHRrSJ3tBRSQrASdKSvGj4qgSchLbWiWQ0 xWun54PUztbIcd6Jh1wZY5PnqeHCXojay3iKZHyZnopFE9VpiPHOCgxDMDtNecBxJDwlSA7O C2etkPdgt/scj0kA/+Due4cwRdMkAV11IR0u8LAEjW0Ajrf7Jte/dTq+Qxvrno539xZuAgF2 I3nnmGNDJ/1AG5hsgwpUAkdSIea0yY3dwXV0IWi/Gcif6Wx+sO8hkG04nMAoJye4F69xWIYS xRJaLh/wEvV5usCVzJClpuEkPyV4wKNv1Y6PWG5ChZ0MpBZrxUPLZKc3z9ySywV7dRFibIEd vWA4q8S/4qy3EHlNOuiHCgV5qZJ6v6Wa+OMMny2DNGQg6KADxMT0Qo9kXkY9DHJijs1coufN tW2hO/XWX7LSXXH94NmkzI4WcaFG8eJRnp7q+Kk/nvZWq6ahQFbTHoR/lVTcv9/gtkbKJFES ghF2JpEY5BsJlDosP+vQemwaArm41BgolXIvNx94QNkgsKTaxirrOWcSsChZC86cTKBzyjvc BZ9OsR9iuMXhEWsVxbwgPXOl1zxhaY/tjCx530dM0qxR54kFZnHIyKgOZ/FhL+zx3daG6LFo oKiuyKTBPt476/HcMjJED1jWltf5oYei580/j5NA4NIt/W7OC7+AE1+TY1bCbvBQyLpCnNUw EBj5CQY8qtmpd1Qua6zjJVjjMTKqaLW+YlyDMevV7/yqdLAaTStZOFBdNhUJ8jvn0eJ+DFdM RkwhKUSQhfEkQbpHw0Fs1yK5bG9jUHJ7zcpAvI/meKRO+7DNFJpcz61nCiiq3FPfcYL3d9ip eT20tzJ4tf+TixQ/mTKk9GfaKo2C+gmHeEaHDSDfNqYo5/vh+iERMRpnCua/pH6JhGku3Acl BItfo30yVf1m2xKgH/pEg7yPZG6LjGleQKJ9KeqCoKT066Iw07VtmUgxuJ8VCHHV1m+exI8B Q1KmtrN/sSIjCcCw6YxHFq4xwPWU2a3Q6dYdqH4/stVi9BNYlmSLWpB5CVaIPfiOGla22m7K jNmn6+SpYzbkBaRdwqUOngM9b0Y9XPOb2mkHyDJaUr0G699HQerAnvZlM04RKZ2pSbwGWv3n lVrTeeKea0MUdZAgvUOnmoO8U0NQR+Lu2JlHHbk35pfPRkRJbwTv4+u5ind86Y+TsORI6fvY ZnGp4kI7Qt964e5y9VgXw/8PNXYP9Jlq/CsUhpIowTy3txkYMhN0oakYBGS5Z52E6x775Z6T QqI6KjAlVxwhGi2EFpqgGIWyUKrBuGu5pPzv4rnHzAHPZnF9OYgZGZrA0SCVedJXsAp9UTji EtnDVjfF2cNvSn2QF8z8FsPnj7xN62YrzpTehNnxKRrkIv7R6SW5O2ZnjLDOgQb+gHOdElfS zqVnBd/XqOVEfzp++vDfjoAj+YTJsVPnvvPxgap6C0TcopWis/y6kawOP8vVpH3/9taofOxL XI3KrUR655Wn47f7Ulumt4BgDFKPGpvoFoF/tAklVkudewmL2zAZgMxXDgK+z8L8VUKotm20 t5FauHlCtOezY/Q0fRERrWgxzNWZYLrc5ake+lsHFDrichakdggtmsL4fC/XwEw7Y4PKAyaf zQ/k1JQ+sPGIWqeDZTdmwZ+nbPvKTeoiLDqkYn/+UKtRvt+oUWCuyUqRGayqQYAjFGDlC7tw kuS6Sxp7tqsyUw+Fz0+ENtMXDzTLlYhz4JiduLCKSpR5x7QRMKmm9cf7n9Z31ihcwNYs9/dp QfldPj5ZaWjlt09mUuILttHt5jeEOsNurZ0ZmplztREOcFD5t1eH0btxgQsMbStGTCtmb2zk YxKE3m1wtwDKjepSdM8SD/2Hiwsy1Cy9pMwVhDDKSC4uFOw0ZduuEN7cg042pYuYbUPmXyx2 9TdonHpeGEcHERtWMwwDXXU5b6/kC7xMKezxXLEvHvMhLN8eyliJLmHJqVbGja5UizYVI3bm pq+/h0AqdRDmdtszXQCvWVsYHgVy5/lz8qEtrKka7ssYJVGeAw1TBE1VocIJ9/ESaKuy/kl1 4vDZhBqb3HKN8RuXuLvt9qk6f2Bs+8SnCS9S5O8mHMZG+1Ge/IGxi5GwjRIt3DfSBrDlqpru JqIA6EO8GRUzJ0W1G2A9VK1AeEzAyx9+WYNhzEyCJnrJjIKBq05yUvsizsLjZYbZ35aDAvzd KrIf4DCRiiJDJjjdYen4YODbo2hW18TRiYljp/OgKG3/L7AokBhasEjoR5QTcjy/equsdOmB 2ib3kLkH0eiTLmEfRr+pJxyjpDZXdvYUhDM7F379fxGr/qNH3yrj+bIR/Gfk3jcjeI/m9HVf brgnPI+ZLf8wcYjeSZshU+vi0T8V56tefQm4Lh9xT9NHcfSNggHd4kSIVPcTntdLbWRygEF2 ywReDQQjW/Dyy8KWXjNWoCTXdiM8TotadZyhT0reI6Fh+zTjpLl7nb7PFYLyY0ZFPhJdaCtP aH85NvsuV9Lll35O2bEY5KclvZA9X8C9KiTDIqpeTyDFo0K9JBkF1fobNZa61xqxgbzUmpCq YkaoBP7wqYRG0ilDLXTkE0/gzZoJSlhe46AMrW0v25O+678+ZnRZ5VROlhiH3FvYdtGndZiU BOUHKeMjPyJ9O1Td4bqgcKBn2cGX3g/L9P4PqA6Qy+yDkNv6C0U5e/d/39oikchMOeVvOAm9 u0TjlF/OgKLJ8H67BFcxdgCopoxdLBNOoiqMNQdLRQzuZj/+/xPmA/B5WBR10IiAe3tSWdzW rrBt3Dx7kCnVlyMr7SgMYtDNecC892C5iUJCtpKs3zEEVfE8/6JhT2Y0vrFzPBjk8Hh4SiR3 vhn+x1faBcYcQ+Tx0njCTCasobEYCa6AOUm2pf5N5Jt1GAY0l7Xt2C0+YpD4g1piZDYP1ft1 rGMogPj+GCSX+ieCXM6PQ9aMzolgVvyk+FDaBgcjMlMBRXS77Tapa0hLOLODhT+aMc42gs9C V8KhvhEtTve7zxlXgIwNb0OAMeoAOg2MwkG2x0g1QuYhWAsYEVlxCn3a9R6RXjexPyXWK0ft dVajCsgN/+TfFV0gzRBVAABTcDMwby9mJkTXA9pHdO0vwic6PKOnto/tZW6OC71Nkc4X+A+/ X8l9pmrllMkOpDgEmYVfx3bKVyngiMN/lOBta1IA4EaiCMlxc6VS0brBDjFpqqbISLGAqhZw XwCtVVf8vtBl7TSowR7GlrEVdBafBdeB2HVtVn7FBcf7Mx86MdjTY0IY2OcQ/ANuYAtHWDy/ L8nNTm7AeqxPEgau5+O4Mp8tw4DKOK91B0pHRkiYANnaoZJbizNQJIVuOrm10iE1LSNhpqfO U59g+gNCO8RPrVF3BgZgT5BVZ+FZuJ506Q3BkaXhCRQ8ry29B+g9FRi3ARXocGCJ4QBSmFjr nGgkXKuqS9XzEDqvM/dga/FbEK4CPNjC9WOOGU21dX8x/6RmmiJ4zhG5UJOCrgHY+TydLIPu 6EP4Dn9/lUD5PBf3o7nX4lmM4pt51NRwbgAAouI9ZDZIXpWaQWkYwfmZ3AwNlDDuKMqv4ep7 qoGSzVFlPT7b2bDYPk+R+41LnJgs8Z1gOB+Mop5y0p4NN0AkAE4R/gWyaYM4o4YHl+KKKvSg 0RqGJu4He+6cqHs336E4sfi7Q1EMBNC87ErOEdhoduyq/Ydbf1+HD9gbQx9yVrb2NSdQjcIX MxuP4NYgno5aZ+Ye16+fr3zRRdKqFiC0fDL8DKl0QNwr/awg/VQI9UFRR5TDgkQCHav4OihO 9lvBDI5OUDm69q+7OCnNNem7abILYvBVCHLX0BgbmzBqhN/gdftg/D93I7+7mmqYIaDko9Gm DaxCy6H31Ryd/SbCwOlzWpYVaanfVwobSXDUjb1Fr9+SmJrXPBgCVBMYLf1rfoIWhxhrlngf 82KsBoNDJ1WkW5NrZcim+JOJz1h6NDkMinznSaSMWEiods8wmBlaYx0v1J6fsmqTnuqvL0W3 fyqj+rCO+vybkYIZSbf/8Uudtnx07S5vqvvGrdK1uoebywT42WuLZ/H2irrOWy9ivv/5Ixeb 4i3GLkoAN2UksSXtPeIjmW8yw9mzB+3mOKG4uKpYF89RlSlN795IDUr8B8alcWFpFbA7xqHY WnotJyf7WkD95TZfuB9lKgsgdfNcmOtRvhQpZvWVs9BCHFjJNjHbrtYCVpLRsopoqRP/QvVa srdD+e7Lka/8M0oI9o8lrAE+G/zRLKFF3MOTXjnSd/OKBBF1QjSgQsX1PUmmdSAbLaf7PMSo 7eDKjwtm7+Zj8XyYmAHDGRxTFE84BZkEcq4oi5RUw2DNTbMDV4H4WjJhJrTVhGsUTpKGdmoO aXrWzigcIObCUWT3b9buyTP81oDUA0K+Pc20QVfygSBQImkuOuMWYgLN/lrnbxKJu3dEncij eLkv5Y+2em3M9qw0L8wuEF07up+9p2JouH/rPE8bNdZWt8wSCkjgcihH0X3eBIw7Z/8Gxc1p obIC3RSbhfFI2mGpgF0loQOyIhYSz/a44uOF2JXxjQDPK2B228XbfxXQIBfwm2EWJ1QtaMtz EZqH1uZcHRbNr8eOuYtmJ4vBtOiy4RNXQQlM24xusXpXR6/WMgEuOlQLUyFo30/Qz1rEzbDR zxcl/RspIgc6AFaAAkFlnsr1Z3ZixeiiLhnuJRxA/do/kXhRIF/ObmIWpYp9fS9Bxu17VcB1 laWBeWQw0uPxAWz0h12d+h+vQ4+XP48l6PHD6Bd7+CS7a6q8yS0RYGOTnF3golOaDBwskGG8 BHtdi3NYfjoGRfaYaehJYzmwcx5BfXEnOZ8SteODyK90KSM9gZuXJ7gR7k4YomLCNUunz483 owNXzTXFyqm5q9XxO3Y2GZ11F0bsc922D/4P6tjK0SwW9ZBchMTdshwkT6/TEHYl33cv41sm Y30dVDR2NPgdMO+thEaMA3kbIrd25tLiiBzAd1cwkJNaif39KU6EoX/Y8atVb4lZOzNgMWKX ZbewpZzZxAskWQsqcH3iXT9Vv7ymJlKN6tIGS//TLksybaPD+ctI17KlBLrwK5rxnohKBIXb 6vEozp3pOiyA59Wrnt1gu2svQz3iTKir8gYbhVx6ADFrG7sH5RhL/WpKWn6F2aX9uUfUFqGm 7ScY3XJovozvqfY+dVlZry3fD/ygF2Tw4kd6G2jiZw+YoGmKKk/G9T4wsyzbusA9XpkdoTus Wrqd0exZUtF756Ubly+tFQSos/n2upIgJw6gS2h2LSVBNJBHUhi1cMIO9T4dcMAKMz/JQly/ VkCZe0/MXmu+EVBOIB2yOOp29en9HBT0J+mefZfD7xFNiiPuFH38QQCc1mLcKJhYQuL27gee njRtvefGlX9TPdoff9dSRy/yKhs43ODuEyDVvJqp2b8OpaZ/1EU5OjsuNCoZX3bGwtdJ0mx6 hsE2s2u3I81a2t8sCpvSpIHC8MnV/OE4tzqGDrAk/RhBygvLsvLvVLK/UEWBIbH7+7MEAs5Y 2O2umg5JjG1akudwoKE5dXy9YLG6L1aPFU7XJ+n9VQEZWpJ3PJp6d7UZN0EcFiHzck196q3v 4N+SV3H+XlDMRMpR5VJZpiHKVjjb7EMVhHIX351PQYsJJ9Y549nLsCt/2KSZkbRRa9Z5VQ+v zAF8nt9cBIGDN6a3q+LuX8xJxTAJsgyTCJW0t4a+RwwOMy4hTgo4eKKOl1+KGQxrWQ/ZNwlt s4Bb/Pax+Wi3nzBcaTMHywf/XjcORqdbGFJYF3MAFmCYWeaz7YypRayTc6p180VUHsig8qLd /9ab7J64nbFpeqGWa27e13FeekPkU9fmffvC8MKmxnaMfOZG08jTxAz5+7FI9kIkzjUCYXge 53O8lcxMD4iohK9XnaPKX2UlJ/3VcO9amY/VOt3g4z+3Pl2r1OASE2lgNXKkWWf9K/NqyBTN v86l9CkFvNNuPqR58Rcm6LPN+IlAqxvMkqGpfryvb78dInCStmLdqadC+kUiXPioEV9A4uer uAYQ1P16RxSoQDU45eOIqNkhN9HcmG/niad9hqSldkyqpuQlmtctNJ/h5qL0lufioBw2abSH bHwXUyyxhuS4jwx/ycvjgSFCMZXilG7FLJa8ccnaJ78RMeBbPGovEwN3ZIADOvy0wrwvj273 ZY0eLpjT0N1T6nv+V+v1Dt+4xc8WKBLhGq8pPFzeDKW+U+yR8cbbz6VYdDZ4yFr+yqdV3yBa KI09syk2jnLYHi5G9pxRLEVGzPikUqpTnQBuPrSHI3O4gIoYTyDf7PljaviPJynXd10+Mjh3 aksVef3OUVgp3IGPgXLuHGOINCFFJI471OBlZqdN9fFqFVhNlNxyWCtLxBdoK0VqWdeDrhXR UqhfNgDtXy/Se749b2zMggLTRlIbzdDx1EOFngHW4eA+JRh2jiG933HGH3CIPMal/IWQor3d kQ1nr7RR02Bl1Ecmr2hsXwv9n2vJFd2YtIyLvUciLsD5o5W9yNM3mefrk0dvm7YUuqGa8nJ9 iTxVz8BvloMhD+8OVZ1bPwG3wCSc1dotDSgdcKr80/qS8GaFKdT5PcsvxDOpjnU04rg6zQwo iq7JyG+Y6p6jbtwBOoPknXNn2RxxWAtDz1NXnhhYRVFNArqCOhKGc8opyvi8K1F2xQOb+PBR 6tzV+URmrRi5mrhwalBTSYnvRgBKGd13izajDuenOGzRtA//ihUxv1/7/7fx4ZQ+Q+doSKo+ Uq4RkCFbGFSjVauW43HBJa1GYSMu3zgiPUO2p6iGaO43zw45bxnvq2YYk6+W899dyYuecmAX Dh365jH2BFCsOQQx8TlXQnXT6dqFjTrfQiBkXaY25Z4NfZUAzJefxV4Hl0M6CM1nmiJEIw8K ZLpLbkVYfHWrn2XR6PSt4Pnoxa+YosRu0HrTE37e8lSSgCXgX9qGy6LaQb5/WJK2XRmZK2yW dFYZ/MxveLs7YKR7QxvWGp8hYVete7eOcyvBkVMd4yENLV83jFBB5obrqWD5vwnEg66abmXC Av1f3vhlVUgXKIjOnvYykvA/CGEwcrnSlWgCauGRmTohCP2imau+kTfaDflrQQdvEJ2jV5HA N6wbS8FkWf/lC/P3J4fZu7Y2N+U/vQZ20DWz3AOGGxp97CXYKOwbJRtt/MiZ+EmJeFnKLPU8 k239EacZeHuktFAqkJvk4t+2d6p+9rCzIJRQ9IIf2sed+iM/sLKDLSccHiZU8TVadzEmTYCY T4vuYdAxG+emRqnuBin/c+Zlwqo9ktJDagPBxaaHM95NwIIfXb73ros8oAWP9cpEbApISLQi bTNGQgwWct21ZY82FILb9sLmX/PE4j1b9LWbyYmppgeZktKz033yPw+CPYTmc0ay02/E467k PMoPV4GD7iZ0jPmehsD6KWDyWA0hQPOTGlD4xyBiZnICW4jdMixqeHE2qUvRGP/xLnx3cpXF WlLsQymz17plL+Nxo4jb2V6zLN9OKWHb9++CQ6KXVxFiOHC2j1O+/EGayPM9Oe/pqw/YHyNI Iridxz7trSk8Txd+bHqZ+y9aOiC2MHNNkp3sRxB09TWpaI3Vr4eviWjOFmZdaV8pPX/hE8Fv UcYrkGtWVso/OtdMJ1Skq5gOhb30h2EkXDul7Y69j0d9JFuqArK/trxltosepaS1g8diarR+ 3xWWGyxV/1WFOHc5q/gYRknsZzWb6uzMXMdywt0jOL1SkH1tENasjOCqxNedva/w7Q7tH7rT clOu2iobIsVoIWsgO2OYCzw7Pok4KbBe/9I7XG6yFB9+8BEeLUmQEkE5RkNjIkrZu8Q4Wkwm fHM7xtX2Jm345CYk0Pbreyv7pkiQ5VvE7OTWHpXzVcG02tVc6hKdLiQwlod/GUer0U0uwD0g dhUYKRyCURxNqGfX/oMa9MeorrpVmaVpsggksnKYbDpAOB3li66COQ0ha877+Mf9qY4Pd1/h XIUtZQLkd0irYu/HVYG+lS2M4oPCbm69MjGRGqdS6TaWlsiP3CNoQZeXiYdaHzqF0S1va+fE OuT85PQW/7/lZ2g0Vu4dKzmjp5GVrnaJctSCsMnpofMjHwD4ROf9bZpd2HbwHVPAiZ38VGnv dfMQpSsgUmjOSaWYRpkL/+KJZPCoYMFakonA58FbEvK635xH7y4KOzdzAYb8+7SBwO4lOiIv Cp2FmyMxU0GUmux/5iRTTPDzHFJU1gZuH+6GcBK+hAJ1Jr9OVYmcsCHCFgqnrA1fHK7DD9XI VBOGhrgghJ5X8VzFW3rmojn8iFJwrz0LqxIO3P8NH664ZJOjZk05vTfRBryjudGMD/QMwYGV SNB0LEfOQWd/kdUc+8w1z66BkjEkZJtPrzHzpzLNXmUQxqO4zgDdldgj5HFaqnoJMG4pRks8 S1hWJUCiUAqYf445cZKTugxg/1MKb9HWjJ+yyr1woyYsBq6t54ACBNEqUMPwS0bpVvYNSvj+ hnos+/8bjhvU2yXBT+A1pCSjOOPei9tUVLzg6HB0Z/BO8KvGO0oEGpBqETZDKSEDI4aWTgFC vIjwrvR3TJ/SbUEF2AhiFyHvax98SyRiBXESpyPVLlU/ge4CL85JHNqz+pVcIlWeythPMB78 kfhgciKencOzg0m9zlGeB0yYgt+q1j2CSENQ5aE+EqMm26D3kp8ZTiMooca8crLs2lUfXHag xcDQ7HsPgFDxTj0O5aezYBoJXaM12NJNR3T51Qr/65PrLO8OEJAsWBB2YY7PjqhXFf+t9kUv kua9i/xFKnuJO/ooGOz+GNWzG0HHvgsO9+EplaT+kdS2b5Tr1YkjAUdpJ/r8QIekLVU/zGC/ hWyXX3KXVGoRRFT43LMXKlx1uqcQ6M4Nhibz9bT4VQzOfUqSw78CLMEzPqlssNW7A5wtzx5M 7vowRKBblK4cMSM9d3BskNI+OThUk89cu5wgLUUEunDlpRDag7mKXrrQh2iE7xGGXhDI9L/Y 9+ABP5sk0+mRZEf4qR6ik97J/YZEjYIFeeHhNhRooIbLxISPsa9/d5whpKno42+eKOLp9EI7 UKzirSo8Xpc8ii1KnihbTPZhLrR6kys+GCqc8IIvZCv+rDbVyJQ9JkkN53Qsn+GrHmGHRTIQ /cyMHjJSuL4rsyRYuSKMx6FWZFEpLpcm+01NdhLuxbMGW2pa4PysjeA/iAM+uw+L5nzjWxqU JGT0BEEAwDBwVTeYcB5VN0yyIM0sqKWxzzxxdgygzTYfM+uReI+LkE3S1vwp8Jg/uGg85JaI gBUAhWELZAGnowMmdT23QLw+SeG1B+BXT7ZMlN5z6mwwRnQuEzf8JazgGvnq1s7zq7i+uP2V SX+dpstRBI9lg4n6+cEVdiTXpbJmuML7q74GoLJB+CIARy4EeD9nV31uqpSqFyPHwcNbHUqK lzI6pQrCQ4bKSAAj2YwDNbPjDLy1C28FkIhszIUq6amlRx0DzIxyTyR+2eX4jzLG7oRJcywU 7egEvVbNBREnJ3TfAzVIDPEhkw/vTTDCGFkMPtQbGkfyPL8N7luQA+lmlC67Dxwnl0aPMIe6 1EZxdOEc9J3hQsiMNhuQSE12GStNTjy9c0Ei2/iz52uHrGebKJHAGLoC27zhuARRK5MwzFlk ecdNFz4NFP0WFw2J+i7mjxIw9wmD8cJtVAWV1HTU3ptj6O5S82jRyKpD5Gx2n5owGq1TeRVY p9my5ZyZytUnnRjxt5VtiF6BEgRL5P0lz/UkcxIV2Ibswnfm79NYCAzcoq1Rb2bzrOMnQghQ MHz7k3diy5gdyjfkTFGMU7etndYEC6fokI+30W8JypiinLE3v3XPy8nZ0aP8DRliPyuNCD2o x9yu6h8hiLwMtKG9Ocwn96qygn9OwbSweu0VqJ7TP6MW/7v+L+3yysf0Q2JFPLihTtlgI+iT hSrDW5EyFplyFP0upQbGLFbU25GUvyWETHIFqt8OEgDMzid3B24Y1l4sWLrefs+I4/E6fpaR mix/RRXrNHn7b7zPNrrxpaUx+NUAlg2i/Mt7XKM6ZKShHexTIe2M6j5lnnhi5TDw3rFUB9Pb dGLwFy/5Yn8CvfQBWZk2LcgTaJrPsdxNnn+m2hsBQuVwUElSNOWNz+ENyHhLRpClkYHTr8BD vzohfvH5r7jPeIDrECh2wCOIdbq/M/l4yWCe75/txzzM0VWfrRNnwbQn/NvPtY1mJLhTHak3 r6fH7xH5RCyVlr73slbXXkRjpTpe2ayA8bDuctA9qz4WlJNTcJQ70bnz3d/SuWvhSixdGN6W xc/eVTYRuT7khfuyHk42+0z2Ip8i50Ls0I2Q/eOiC4lV4LCw3tT/bP37C30cj/e6n9SFihKl /iHcMUJAa1zpNAPT+hVhxf0xLxmo8LsvudhV2CtFYPpMOZNKANqbBhYEQ6wRJrQts/7V6hBs VDN6YYM+6FomC1791yRhVwtqNZuEYfvG6SbrFsIg+UmiQ8EOQH0kzenlBSHirO7UQx1l1kHU lyQ+Kz0ljTUtQgUGOt+JbM815Gt66Dk6nordxsA4eOJr1I70aIC98I83mlUPb3RzV64IzTFQ 5sdnzyZm68H4G7KfP6JavDBlsWiYcM4w8eWEWnsKlFsawEpSIM46EMEK6DLLfJZIZwqdzw2K cDV6/GDMA3iSEkV4hdZluQEWC2SD+yUDl9+RjVyJa+3QUZccvHKPY7fdU5pL8NFLwlv8ee0j K5q3VCU8qARRwxlv8O7qqjYky/GWk801iuPJ+58VxhmLeGNDCDqKJVgloMNqibYgGd0PchTp JJaJ3wcizI6+Uy2mrSj03gCsPp8uPRjH2YSJM33pQJWWY9BP9h5ZmvC2w7knAIZiRyxeusuQ e5XRk/7HoNH5XjT+PpZiCUzArytsq5SNNDZB9B3ee5XbbvMH4UNb4LgYUoJa9hakMP3S9AZK vTmmX2IqS6N8pQMVNoEn14SU1Sga1kg+lZlwphwvbe4sTqJCZmXSWQEQ8KEH6qIJn+0l+x0X 53sp9k6+bv1hZURxx78hwaJ/iSFdP4ECx9Vjs7KORByR/195sP54KZE2uk/UzyQrZMvnKY3t 6qODYQYB1o3ik/C+UDCpRU30e50Nd7bJDolwmMiN/prRgLDwI7OuPCHbueUJ0f+BAhRcj8EQ 0TpKppjFwdOnDrk/iyx0BTcUROuZHL7CExwWZfQ+AaFeWh3kd3doHPREHASwLn9s2LE6qRYU DIZUFQN/JvvAoiO9BiEmc8Ohqwbng8/r6JEOdGO/QV1BB+1PnmPQZ5Vl268aSNVTHQz5YLeI pfv63N8CHPj5ki5lk5K9lK9W0CqyKTiwfVr6XL7Ic3r63Ra4j8k8uGJ8FMXxPf6GrhWW8mdt MLRV1ZkMEroeP9U7++ctjdWAZNunyh2Gks2ffZeDmYqh+qfyQIiOc7SvzZyaBqDB1QLMaz52 hyODISQ7gA7pcpLLUjMCNeelbfGE7lKpUsFch1/dT+S+RySmaA3CWjIb1HwYUoHAPsWE/MfV tWE1SUXdyyRbNQ/DGNkkvNdZcXwjoIuyXWDh7S9K8uihqXghaCIKZAb5VV6hqn3xdPpZNnVf 8jXxRUiPU0mX7SXVhGsFn6MwgAy8GFZ3EuagXdwXdd2z+0Dka5vbeEweSvf7K4h3EvVIuhk7 YVFOBc9L7IqhSMfiCS5DZxYvzkmtPWW7s6WIn91TZ7bIXQGdr1r3s3KZo/3aEo32vYPf4ZnO D2hnAYX+KLba5kUQ9iWlAng5hcaNAU5oPlUH/1PAPYSbyZiYgKp0NOZP8HbYrPXTNpiDcjAU 6NpWq/JY9podf49dYrthaEao0kur5kBXyagn9LFFRO3+Ry8oHp3DOuef00t5ZAEY6YTE/tWi mRGAz+FCT072gfAiP/UynB2y9JRS8uPwhk0DirkOqtOgQi0OYK2cJKihMXHUyoWfkHOFwOCT O6KSiOPrqtrqHK7i/EvaLDYKvVngclHvwKsjYezJTMe1WqQUZvnSmSRPbCOeOlzXecipyMWX a8SzwK1KQ1Zw39seaQWSurl5U3KAl+f2RCyR/8u9ffPCLf8Ie8fZUkwnp/FqVkO/zWXyHEcq uGzcmZpaDPgTLB4s6vh3g6CTu+83n4LKbmG/qS6Qf7Bi49isLVW561V/VFKkKIjI/7G7b/M2 Xndaxb0yppRovhJZtfUJbga/c6VdyHO4L2hfYSaBRgBlm1l38jebnO7l00bZ0jIl7GXHwqKw Y3qk+OYQUsHWM7BJ7vOxJ4GfgwX7V6Lq/oPebCHkKP0uFjBpVQd0kSN/jAizLPzfDv5eEako FbaYDwNgAaPgWmBl8ygr0EgXEj+aLwxKfrM6VevJ48QLVRT6UDn1IOv1OimkroJWcmAVkext kq+d/7cHQ0voqmbN5dgUVCweeS7D4oxQLnJFv9oPKPqXaBvHIccFHhC+6QVlWi7ILSZCFcLg L6u7NEV9LA4lwn4vLItN0pVcwi9EJbavgzUqP3obo2UDSl/ueIB2/1GMqybSSiRuaLF6/amI l4ACgKM9EsKPRDtQN3cS2V+MJ3aJOl9/XirTnyHIbLSN18S1zbQ4xLbJYs7J4lz+ixYYVlq6 7GOkUwl7yCNazdpKzo63dNVnHrxqmsTvWXEz+RC1gQLy+/2IhbOEduWW67jA1dqz4z/dFoew jpYWB+jjKViQfi/mbj9+zml5v104yj4+uJ9lBqm+roD8E3fQd3lo6revhy6cORm6bVOJbbAx SZifdU25LgTHN2BK3VsLJ8v8ar4RVtrvB91jh2qDpHjmxJgYtXnU5f3Lc5rqrlM4A9ovGd3x jmpaALOyfZWjglKeDxAk8SpJZN3QRnbikksV3n7xrsLPJNx6uOycxPaOepLnDYFDDX8eY5Ll Lv2aDuUpuHTbqoWX+xfT/QnWg2pp+mkiEVKVGj2x7HOMYWCiyx0NcKLC6qSNyQC6zLX3fu2Y TZjghkE7lOJE2sy1jyJ6jhCsmkoD46HX1OMZpSNcz8JwuL7vWLNf/eJvSJXS4AthS02qR7Fa mZb3NtiiJGxAV4NHaDoSkL/HIp5kXzegOdt03gEkaQFwKxIAzD5pqCMx50tdwGG2G7/ava5o DRIptNpg9SVPe26591HmnDlDklCFBFEpDIAvG7Wz0JydmkF1E3Ywf8qfncpIaBXRAsBIVjbU ACeV+9wVpAJEMz+pwCw8c15Y9e8FlFvSfVsMOQFBzJCDuihPO/c/e7kGfnWyWeP90StOXNI2 kl1hgPXJWkMj2tjiVyN1CRqm9ys4Akyjb0RW4kxE4ZyUyatSVgsiR4AARVrwJS0wK0kVaEPi Daq7yHjESSt6NhVC/WiBGLUwEVS0SCXtcIj7V47pB0K1QjN1CCgCJJnWoyDBm5LAvXBKqaxf LxVOpJSb7IM8BsV4psmr6oroYkNxH1vX7oPENjXqG13HLdtezbWzfIf9dSctCJcxPYJdFw0t zaj1nz9vl80m2rWgImMz+XOkeFLdgzE/2hDp1bLB0GK9dPuuWbPwCYfPuTWuAlIfKW2J0fyq kN81u8QwPbwa8nJyDNgr6ugI3O30PJUEn0ucNK4FS9nJDo6P+JJJw9/X+e8tY7uJ0GGKd89f GXQZHmH6fh4A3Qqygi9TZle2Mv+Y5VCYHJ2s2BMV2JS7pywFF55cTlw6tbLvtz1jpe9ccIbn XhpP9yQ1VnoaiYsPaGuHhPZFeFvFulxoBTv4caXy+Ox9XFvoHeHG/PZ+WChpHAu1/0pDCGGG NSowL0gTNS4wImcmsFS2VsB9ZgGvDX9z9Qu5TTb3HXb97AaKDtZgpk5wQOYASfrpRtNpvvtI bp1LZddFl7eRhIPGKCI4fDhygxRpFU/sSIhA55I4+LCDkv8CB45i+5XHauDirhGw6BMrQpGO 7iZfCVvUIq6cO02HVvnrx6sEyx4HLXHrS1yQUyNoglDKp8/LS0FkJT1mZOvVeyumtH7A0c/6 tLVcFpjE0/uWHcohFGTZp0x6VukVmXLqTbxp9QktD7qjOxv8CfM83ZFxtj18Bu+p2gjXeIw2 t0Sx/Q+BRz3RQjHfbKXHOZHRGOEizYTqpmzM/XKhzmv8XZC73KyXwKe6PCrIZ84KsxEyA//V Nf0rz0rSHxp51ndFqUkJnf8Q3ydrCzu4ffSO0LXBFvw8Nq6e+F7Ehx5veIegnc3KK4W2BHJQ DHvD7y5NhPw+dCJVE626Rg9fI1hHb6qTc3Qr7XG0DJysemWle9yOyVbS2gmMRP0wQYKMLQ3O cL7opeRhJM5+vDZNJvInZPjTVGtXhldfn2ULUhnnASpf2CMjj/QS8bOT5IQOOGy9MgT2oesi 3ZCodLtrxg8EjEE8jbhSoZC/ykQpyUmB0DLXEw5B1dzeG25pTqzimjQC+im42QcKWHR0hdaJ pl8eFRAz4sB+LTanZIkUZhF0jj7XwEK2cR6F5EbTF2k6g/7QHj+B+80EyMZnzl7Y9yipFLHU 81apFV/V5qw6hnvwYxi0tYIOGsR94esoxu3/1rvyILyUX6OqvrkIMep6roCaiQfisQh+GlKD 1pI3t6wotOAtQ2/uxsVl2AOBmxlBTX61oeH4Y/EqoLqNrlimGp357mXrRP4wNiFXy5r3Cg1r df10xKRS6y+HocoA1IwuxrGhjRGO7oakkxVZqOs3V0lAK28ARqG2osd2ZOvFjAPQg9gzRcze KPNstwCML4dx0gHB/CJK4WJK58rDwOJSuGGCEFrtb21K9mqW+HGGN0bDaDhpBkSpzdaz5N9D iA65lJEoQ7gRkmyuW1DPfDHQq8DoekeFR00HH6gU1Ikqw8LsJioqbpDc8jRSGsS4fJ3I3RO+ i9sNcvyoCQrNT0XLyrLIdv3lEKFkBXmDCjCnl+W1A0hqVYuLVD6zgXjbarxNXHDf2hqLYSkX HYsN2FyEDxb5WoiNr7QqnCE2fz3S5PtkrkgyMttAZZXv+NbCrMv+RRQDG1ivEVJUU7qTxvya ahwk8bXO/TK5fP2PdV7BQPHcKwFd7bSQ+CUf26U45fE0xRpoRQfTYlPsE9HQkyL5/GS+GpKj wskxHeddLeFq8ua68fM9R9vWJF6iCOoy5uR1XYDoNRirJ8uYX5WWy7QE5TreKWp9Z1rXqu3g EAcQaO962Vcg1C5kHt22VNe62vm5qHyIQCwBPc7gjFKWQ0XTjsJ5pPHFA94X4H1k3sJG9slR oSPn73+Q88jo97KjqUB7L9DiVHZP/tONSQuzflkKmhq/aO7VDQC/RFfyPA/SX0FAVmXLwhPP a8DVWb008b60WilDFs/HN+HtQAvtYRrfsI/JxywkQaMxbSqYvwnQ0QErl6dDc1Tu1cROqFNh A+MRJEr0TFySQLZseSZ1QBiI0FOWm0HvTiMKjlMm9AhUhJ7ght8OqzQABKu6ZnzLx7DTU8A7 b55CSGFIG1l5i8R/nm5ALYQmkmqcyRuY6qpJFlId8EUBt31b1yrAi+7u+eyDFKV6YTXru6ZI RknkJH9K0U/DAuSXuAd6AM/ZJJtFQFScDjzCyxH1CHAv9M8duLMEYDBXOCE2kaFnLHvk5PKq 29c4QHjRJUkhvlJlikPpVTu5MTSnqiGYke63Aal2Off3SWBy4eFzBJXSRwnDpEO91LY+I3/f 4riyO8z5sH/2NdXdwrU9NOtI09xS5lGxqZdnKzLMwq9H/PXwE+fq7D7BDzfuVD5SfVloPgfZ mx1DecASkl18c7fEWxNxzdVslu+fqb3pNwT5UOMwZuB/Tjw37qk2rXzOdJZrGPPkfQZLcggh 1mXA8GsKfi0S16MUr8QBMquqciGC0pcwEggg7A1JUAfsyV46YV46pG+KnDCzPbPRhNHWrI6V vQGsU4xrZ5BpFJsZk8/A7i69IWBdDSvqR0Rd/y+Shwo3GK3+taQCrstlx9PiVh5KJwslIM+x rGTxtHRQHmhbd3IcGtiNH6CNOVAVAbPVdla+kFA3QGrw3LfuI7kXEeZ9Yeyqsv2J5f9HNyfQ 9M39b+d89BmPSKyuirhBRmsIX3qYEKNDUliBXxo1H3SpalxA3RqKvPttmYeic/UEFWWSentT fxGHvxO9GmUZXTMWe2PJ9815YqwTsIH6juBEI+L6mbYVdsLHje5ZOy03HSH7qzrwjz/Xr9Mt wx3uCnxZvS4QFbbEspPZz+wDkfFg+WWEa2tOUxjFEwSwTCnibAu1KBzEXkEIYC6kczKEghWE CMBgyKx29+O9vHusI0a9cutMi7953ZtLdFbAuxqdf6VQOp1cPRnNPI3i81WPy3kUzohGdHEZ pISY1XHRkmjf+Oakm2s/uZU4pz3+TUo4qHfmRDS4lEx8zkQrAkpfRajTMC+V9VnuCkBW1OKb WmpVF0cw0Tv5QnFB343jO4XjALfk9lMDd08kIsDEDRPgmyvi5K6exUMzcKqEqcnWFtZoqTH5 PaufAu7JNCP7+9ujmTiYb5gy9suSowmsnVlgC/NGYwh3EqC8Gj+S8o7s2M3rYz4qBKzaEn8H B61S/8bU2ua9hD66rFoh5EOhbBz6WTid84OLYBj2Nnmz5ax0+U4cnkUYUlitDEto1AmDBKvs ToEdqvtBSgxVHLVo/Wa0v1lVaTM5TO8jflvyTNExmTkvlO/9JzP5yyjbdEh1CYwnppq4dMl2 ZGzHkJ+x2MRT/NXMoF8nTgrPXMgsN8KYuSnEjuduXxt3KHcEiE20B0sZgSwHABQllijXQZ0Z 4EOUioV1xujDbhX6WQjXOPL7XaCN3KadeFS9OCfbZOn6qHd1hyQF/8BviFTBKBAoKRWk4Zbc D9V7aik0XnkmmkS264UkL5VL5gFxlO/iCUnWtS/YgzqhnH+NKUjvyBeJ52wi6a9RWbWxQOiS 2Cx2P8ltA0mOh16tGnzmDRc3HejZooSseIWdJ0c/TT1qvlkVaEg8gv1p4RLPP7TeSwpJedHC AxoptKDMDl5ettX+qUROPDDnNYe3emr01lJNABDm3GLhXU1zyjgIy58LtokdF01w+tXNiSQ5 3Jy/I6jufIKQmWTg89PfKOAvL31eIB4+lw9IWZkCh5fN3FqmagKYYmT2WiJ763KCIOxZcU+a HUOigsEVayvZvwqPQobc26eJ7dINlrgu1IStjA/+L3X6NMCA+I94/s4NqhQloJw7twKEb5oI IaiOOkwD1934akkSTWD26g4w6ssBpM9kh4JNJJD4s/Hiq4KU2FU0yxXd0NwgoXcjAXEx5L7R 3JFuojaXxAy1XQ5mwNAHsALN7KF1m6rgsGVnPSYgI+LTL3+P5L90PuV5FcbiCDg+jZ5G2gMy rL3Vb05NwGgyxt5HADB0e2HYpbmZZQQtdB3xBbpaPvtAhOVJ+tipBl41ym4iE8bqe+AROAXW DI8pjiw7TvWcmjm/QGo9lm4ogKfMBGgBIcNMopR18DPkLEbCmFCU9DuBestod464C1+FRa2x Grwu5iZ3pbdEQ59bX8gjSM6bgh/MCWx03DFHOOn81z6GZHp34qJY/DRi2paYvejlUhDTQl3m O2Z44b5YhZcU+ZaTRArYOs1gUv3cXUrjnauLsKULTJh/Pdld6WVWliC9cNFjbRJIFiNqEFQs OWNwvSUeDQ4ZaIH9EpopvNoDizbFYES08AHK5hSG/KZWKmxyfCzx5h3e/OFDqRQGZqi6p8y8 gmMEW/EAke1JWDZ0JrFofWVhhG+SsUHqxRb4AnzQjbG/Ibd/noxQ4EYg30wPkCTydMOb4UQs L2otu8IkXFy1IJE96bjfUKvGXWyHizhBnOt9oUPZmHn6B7D9JAG9Uc3gIkk2MFGPFL4Do7qL DknFgXoRog7Y3/C/bcCHp8yr67hjFvB5Zt3H4HidPOMZkYvwe9K64Y1TX9FHrjb4raYm5RPW vC0fD7ksZCOUmBmnznfnqRebOkYHUBPY5kbjTT2zK5Osfa2cojlMcPYgxT/+/zaLzy4baWpY TdZu1Oc0b7JHIgiBDrqJNYZTxiwkSllVxK42GFPKNhdj/c3csU/o0DEBG28WIWiSKAUD3ID+ d0hsx649EY1IrHD9VE5NUPjAW+ve+lp2ayIaSb0XsgZMGQw5EMZe6MUDZ1U2By5lIjvgvISr 8stU/Gaj/+pr8EiOJ67Vp2rIUxzRiM2zRjlkDXDJQXcc5ZM20CEUm4Ac+ArgN2r6c5mjejE8 98gCXwfgsLvtdGDg5xZCIIrrWZzBWBzP31RQsMfZo0heYXzuad+ucnwX37sbBU8BoNUZC/Bs Z1Q9NCvMrlptYMVz1PqjCS/hV1LcojsmB68Dkuzqb6685WF/SjGFA73GjmpfsFDSvDfG7ZbU zHHFRhe6GN1BImW5SClcqQDzyDKxGOpvy6b68HpdGARh6sMqYytZX+jHTzWvm46e1CkDX9SS W1a1x4Q6jFfZxDgbJMq/hHSJEavYpAJqhXoUNOMiw9kSQGBl1an/jgVOWE14f20cJjyziB52 XVsspgu4X3CCsMLv393zPBPDbQFc7G8VnOgDVYSZwpvD8TbQVsLiG/bJXwZXPvmCaIhrXvdH urvxYaeA4C02R3kZZ4/8ymAXC7byhfvOM0Lx9eiC6ogtENV64igV6gU19cF9jNCkJCfvOHzx UT3hlcufqFgLop0bR1V4QcVZvCLXr0DVH9ua1uonJjXpBsQWx68AvmtAyAtCh4R0IkhtNQHY vaSlRWTGJIpV6QKhNJ5Kgj6YgO7Jj+rw94xujx/4CXCvUW8FCNndnwANE8mYcETNjGnrEsMv J+XxABWTZpri2WOs8HbCYYvlAb7pSni1GQPkh9OK8uTsjLCpMyFaoEXGgjoZuT5e7+sJiEtQ dKUiPaAUFNcnlRxc5/qV4q+Ep1H+/Wh6pJIJHP56IvwEaXRLYdc9pZ1PmYjW6Sv/LWdUNhJv BpPJHcOBdkk9CxJjw2jRNsKp/JCKRms1cyvrvXsW1flKcu3VPFOLECs6IsM5gcW8jFt+iCNR HJC7zbY7I6OjK6Rp/Kij61O7psBLs5iaFlLn+mFOG69fDhHhHt3yLFFwQroKWqQndwIaaLne +oHX03ka1dBkN4KL8bKBmiLYCc7RhAv5kkKhqn2GEEHjojs46doG3//zL7cWFVavgy72N5PI krZXfH0IME3IYxujp9y2k6xokJiXBycThwp+K92aXwqaqBP8KDZ1YJa1HWnNmJwo90VFI3X1 82FATbJ7YiB2z+9zqnOJZE5mYeReodS7+PNIDeeP35tAk6CEqyhweXxjrv4RoI3Z/m5cSymA K2jPfXMp4K8cB6WnWf3vo/lKuMwsw6Sfo+/s5bbV6XdbKH3bFBQN2EJsNIBYLta44w44pbAC nIh66G+LRJj178tL+sarmIKmKJ+A2EPmLZ1hBcIxIJcodNdLdJnPXnXhs3rShj81OrOSl5pI s5JL84ZriaLKjAQzyUTed0ICMYKVpIpOkpRtBlV4Vn+toLfU8gH2V68dAcA8u2EZ8R6wz/aM xO7NrniN/cc8TZHhy7u3yNou9I/89Ff4wELjfwdAOgPgxsTkCnNVW5ZT0Jfx7Y5npSqB1p/D srD7aR4v7evkugoDibJQMhRS4ntCJEsF+Mai1A6QF6H1dc3o+LwwDsH6cd7UzNEWrd+8hqZS 8fjOnYzSMDos3zOpoXVI4nmIw9P9weOdn+YNem50pg8WSGEYzUc8ADgORKBg/KvwLeloIRvv yXdOK4T5FQSNEq9i6hk0Oamen9jDDl3589iSG9r5x2sEy8ssgWAoJvJKlLxlldfbxlbrjNXR KvupUUjCQ/Wrg7bm6Q4tun2ta3nnXUvFAYdVSXo3JTpppKPhOuqDhfNW8HcjHG/PBPGU6BsX oSfRpLYy2AQrWlP6QqE5LA7WUY75JoWqXkDb2njHOS74OuUQtFCrjheQ9ISmT2PRqFgBn7Pc RrWhGg+lsaqmxlweKhRDaIv9+PfdJSScPYs2n5LAMBCbxoiIRqxe4KKDi2pt+hXEyBbeLcMw dgVNMidCjHPgtd4e6UtrgOCawgCbriIIv5OigP11bQPnEnS1Nv03U++RsWdpT5J2yc1a6IWG BFqemZwjUMljvhTr0eio+Dr5Vj6B+koX/fZREBOR8w3xsFgCVGzDDGAr4T+f2GpgIN9LZ6f3 c0VZdzO3fasXOa1NTG1TitlO+EeaTUXQwVi7PqO5qnzO6fxzFW33DN4ZN91ZYYyDLfJ+yGtE E2yotYkUacM1G74Ghptq0tQtHnitoSvKjdZaNYCsgRe4hoy4CXBhiNQ+K5pLaGQvtboM4Biv bcii0wOTDCuuiljPHCDp1gKVnn/r/M5C/nTs5sQEEkS8Q7qOnlkpRN0I36r5WHvczXdovfDS Zz3HsvS6jbUToFrZMGmOx/ZzUaEWktBrBMQJCQyZQgqGTtmk8IxRq1FThEpWJxBPhCkBV0tk G/O3OL2lFOhPHass5PWakXuL90HqhmF3I2h87PJs1+SpQT6V/IVI9h1Tkg+/2sQD0Kr7BrOi SFog+gxNyLcANOxdFky+320lOeQX4NAOvKywDmBpdYxQVt3HL24gVmuh5zRgbq5BT1OLiaw+ BHj1QFG4bgDKi9LhvuSuwIJOTFM8ZXWiPpDT0vMueh0oeRO9oD2f8yI/nvJctUGwlp3RTejn +xh9o7khvrBfLqqfw60L/2GFIcl+yYj03dW8iVnp2wyq7KR04SBE/sAjWnfJE2GrpBck5Biq a9kMu3lMYA9IsBhn4IkKdlzOBcL2OvSgzALtuolvozgjTBzz68rTxTGRdNU+yw+mI6d+QhuB dOGYFHr7lmfVi2QmI/0R1CkMtqPoWH3FzH+lH2EecRykNQBxvPJN3LydS2zsLwSUu9wMu7qh kPjl+j8+dh5tVvdHvYwxBX+b3U1eD6O3QimC9C8lO2VVYVrrkHR2IzM5m4aX0zJfA1EkmRq4 Wqxa4/zrsym2DOGOVDC9RvVUeeoEGJMRr05z48Or9vHmu+QCGSrHZORkfA2QiPf+xdaaPaHO mOeH9HdM/7Dcs67DIH0EobxjMQuF9OvxtA1X+Pjc2dmwawcgtwNVeTMqyDQ8nm953Q8HAcOv Ue+HtEMSO+JaqHIMnp7obw+74ELbGecqGB/8NWhsiF5X8x9oAitjDbrzd4vaN/X8C7UXRaiq VRND4eD1XtdBwJ9XV3SqeyurD20emdtf/11McGLBkuLp846EMQKDBp+ysvR5rQz8wC70+6GI jpDxE0GkkIM1mr95RXWNtyLKD6UtvM3lyN8eqxkCD12tA2Q99Mpu5kp9BvYyUAz4dJykrZBI bmtK03JvIl7y2G8oDj8bHrZKGuMzA+WNzUC15Dg7LM89MhuezceAT9tYYcIfGfJOzFISlAIG XOUwH1KmTSdr8MSHC3ycxAiIA1M4bzGz4cA7RQu6zJwS/8kEIwbLBzeL5gdqbUnfebvmsTzc Ndxl8+XC+I9LefVf2y0+pzuG/lp5mm/oy3OqtqNo9yyjDUjfPgci2MDq6JBBqHyOtuZhbwWG l7aZumkZM4hmgzuXgr9KTkPGYwJ1GoB6VuhM4nh4KDVXfgHktkpCAunkAGAyuLqGcuQ5Gapq zS1BI/W1aslHAzE2lkNhEofN2SyuS3nU28+es4GHTkP6T394PxjR/Zjz5RnLwch9mEANdg0u bQPY+EiQW6Wklu7Fri0wlA/h9QQtSV83ovlq2bJ3VfXLua+HsIlJwqhaSZ4cvvnTjFyvknJ2 /TojG9yBFkyFKUZa8SR311LUU4gqc5WKmiemwwE/YTyTIVhhzrzS51J1TPuoOL4oGBvCcZhG G3uLxiZL6Wkn+2k5A2XCOnZyVYLJoG01AwKIaP0ONNkXTBSI4WbW4ViPTwcRCI/lPiCOcBsd bCXVcKqFmxawA0IHWcYQ6gLh45HwdfK1jU9G3OvY+Fo3p1oMFMZpWJVvT1ap4lEV3395gx65 D22hgS7KyrfMZqhxBizo9/LN+EJFwhJRVEVtLVQq4LCXHIY9GpH+t6lyuvzbC+ZX+CZx4dz0 UnLjgnRNbfZIBWq7lzMzvrg+cPt6I5sMaqfweh5VwmNpXG2k4VsOrKKIbAMosd/IvxM136vY QZDGsLG8uOIbRcPx9G3yHo+GjDTnRoj+g5k+VUJU1xGNLOjp4GT+oDopC7WewjE8BrAaQi8d +lVK1rFI+IUFF4ntKRTZtkZ8/peBXpQgYIVURBA27rV3T/gxwaRHW+Mef5mF1nrYzElDd8i7 bFD6XorXKIEf9qvtpEHQ8K9LXg482x7ENDVi044xEghbzNQUXzqF1I8rjFzR0xWCocjsCNiQ 6EkolCxujV0YcKZyL7atKgcIc0kREvFhxDoDV+HrUUTBrObbAPJ19kZWoNKV4HNGeHL86vWN wozKx/1wJvt2r50DzwJGEDroJ+Qb3QtMfLs5sYcrl1l4F6ykCQqo+nwtIAC16UF5taE3eoOm Y3Jvn5nPyJorUM4wwH9srXV9MbanzY7B3MUlpp1qRJbxNRN9A9m1R4V9v2SgOcE0c4zf4+ZO aF4rXF2RRbloTU/s7BdksWORbbnup2/2En/m+wlcdl2OW+FFGs16jEdRErxMbokH1sbJ52EI s20g61m2PpYyg70+9KWUDtqx2vhRSHV6C5Vwu1rLUxgUihynoS9w0o8BcdjXTEISfKrdklkD jPFNqWr6NlYhhxSmb1jkTP9YLoiWqXd5RnKWXBZAyQstdctv83kN6CLErJitjDgW1KDSUlkL +a3VCLn6LLXmZIpyuC7BSVAqfOWTEcmIYmndnAehuXF+APvL7L4aoYgP7xzqQ2OY0ZcjZI7X 76lMuT9qYdy6jf1S4h22ZeuihyOkx8Ik3yJ7zKLf8qGpCR7wG1NwuE3nmefywpQsFUV6YCbq uI4MEguEPbr04RLnO38gpWpX3ukWenPfmX9N00KuXy8Qz0yqvemsK7KSp4G0cA9L7DinLXMg acSaGpHHfRzMetQW0xy97TDvnx6LBLicw+dALqL9JWDQ8QVc30QqTXn537gbZjZZ80CeAfZF KN5MA26aL15vJbSxfJFnDw8/Ew3RAJb5enUnzkw/6GCUL+cUKJyUY4JOSgg9Tu1XodqIP6MW rDsk3z8fiNBXL6iubtW0S7Dc8FPpnhRRNE5ounwv/H0/T8VZFv55N82X1Sj6Y6vYfhgm7o1u 62q4k+B0IrKae0o63hHk/jWUtrehJP1ccpBOxY++6QHg0gDyA7G6UTP+yrXj7HeE2AR62pS6 YJhiO+tQ14dmHst5i//D2rjq5gjc4wA5b+FUKIgJIZ0AWyi4NebWSkXQnZuhBeZhtaIC4Cwo y7+ipZbxK6gEPmhioldlMotO9YFq2w1PqeS30CWdaBfDAuT+7y20zu2dZLNsj1Jno8v2xMHU 2BKSbkRooaqc5Oh/syfUviwySRn5bvwayznT7/QsvmTLiUkEugyNlDaszt2prf7MVNZZ1cgw JxU2zp8xlrXbqigwWL+ha1jDGe43buPW+PUGeoSM3RgxB/vaPmpeooe+g5VTZuhepj/auYND gmV4vx99DomyxkpyWDQHk+JxUVaGyhHs7K5K/ErJUK8dQjXJQsgVGVcYxjeacem5/QYckCpQ kkfNP/VoJr2u5GjLVojbk+FHW3FFwPwDbrQJ4Gmd1rhDBpuqtUwRANKQyyMadrxWEZ5hA4Rx RJyEF+9f5zkTm9zYORNaRkcfLFKfq35T5ukAkzINtb0YV9PhG7wQB24mNfpB/ei8OB4U3GED /WcVJYPKdR3pvqu2h2eFc/EDN0wTWOSZudIyDE/G1c5JQ7mR3QZmG9K/72PV7MXynH3sM3Pu 0kYui3yU1DiBgxjV4xhQEf01dpxdCiU3TojTENhKuMkRvqAx5cgR+ZhcaEVYPBS53sUf2IEF BgyPnSnTAdTkDaIVqq9IXBThYcpi2TFcOJBHGEP4o7X6T4bTcM04VKUCLnb3wbYvSAbRBEr3 wr/UAyLFZKyqFbXU06azmwQ0lo2Y/wCjxAVdD0Z/b3ssLtjwR84inxGEpxlxpeo9y+fcYWSG Y3Hm8Z+Aj8MiRjBRsY9GWkJn8V4wm+vM0GvWCti41uRh6nT3potlQkMZZVE/VHFxWYZNkdeM JbdqEoKwQscR+QNfPvWTn9yDLx1nbxst1ijhXSuhfMQ3F9G1Ix/9ZdRC6KP7Db/+1Sf0aDvN f9ZQ4EqBJkHNtv23IXunw79ZtO4DPEmtBanEF9VzS/Xjn1OgWHgVg/ylokbTbntpWlEI0Ea2 XUqf0IKnhHu1/zA8e5zi2MW1XA5fqepHKCpc+0iTHWi+damMS7wpdg9ZmW/VzocCP3RCgMOt V9oj0Du5ZQHBitvOAaNNNoKMaCItqblyDVLVpB9I7G2hDjqtkQJPCJDd3sEeK7DYSq2DKZ/h aw+EqxU6IOP9+66kYLdcoy4cjIU/aF71QTnD/ZhrByMIBWTkI4cyxajH+ucEExxmVYHxrz/+ nuOJEiwpbCdHiuqJWec+twYw2jxzrZJegJswWm8GqpdVENwtYOkt88eKh/3nXEtsDW6m2Jvt wystIQmI0nITdvDhHUapmMs7C0eu9PuxJbwZaBV46KHgj+CgWqUPH4UKyHp7Er34sGGoczH3 WGP83sG5fxHAV1wRkP0K6Lf2Ph4denPPUsz9+ITs/++VzCN6XSCjPYB8/pT6AgeBFtimEQIn gAa4nkSNFIxoF4kGoLs3WhD8PuDnzg5Onnj82eaXKPanElNMmbPaQA/OWdzmV/h8h8nKuoSN tobXZSR3sDfefIDDE4SoxQPVqzvpiA9H3MauL/rtXfOqBi/9S9KM3mWzWmVne8LFXHVBiyja aLp1VLvvFgEuS6T0zvh6aPQ+PoPTQ1cjFWFVXOMb1MLOirKCzqnBFu0J+4Y/lFHvKY1PgESj mG/zzU8pOJDNP2ekPBo7Qm7Opw1wGTU2+RMLIdWz7UACChSlDHuS5irtA7Un0IrREJSorDXb F/mruMNH83LQ8iBzHO30ZrfOaGBVPgWxAexSZClc/NwF0pUIRtyotER5P3afx7vWr1ryAxWT TmIqu7er2XjvVgL1jW1ngT78Zl56WQnItMyYciOXOBLc0YGcsoAUxjisiB1NgY6B9mxxzDg3 icXJo3S4rKivSyx64uWcGZaxrVOQpiuei0esoFpHL3zdtWpoFbeLGziuZFJcH+5qddyKP5+d qbw7j22KTZ3EU67CEhwwTFNp4RIGw4yvk8Ohu5OZ8uj1dQamHK4n2C19hJIVoxbu5xqk0qge +/nlDGVGfeUgHgPCreJobF0WP9kS5b+LIg0jWsbGRXlD/61rShw9JBh0pkN4R6VwA0RKcrtb h4HEbXjs3KgM+qs4JhGhWqY5aPCqiEUetHhN57u9K1axzfpq97pbCwkP+PKZHyv5Nac8pJZR GP7GoRzlknim71zNsTsu9pepRc1A7/7c4SDfMDVPVljhLWFKuLB9ww0uCi+HxVulLdPr1H0s yusBjK0MPrPThZjjcdblZF2IDANCYSr5hXTPaSLeVf11cytVKlGnHikibCUewSxfmUk/S8PZ R0U0MD9YGzJJjFpwvfZGnigpIdd8a9Y6QIWndnCpO2A/mNQL5i6uo2j8kBRufc490tGCYULR wie2X3XiMk8EvUaNGEWxF0kqIM0cC8M7FEQIOXJY2sa9LBQmeayYZrlD71H49RBB8EagK2sD GblhS5VqVdL6vizbrA01hPt9eqLN/MZB49kGeENMervEopYTzu5Y//WYtT+cok5WkAbQl5/8 S9O7wCKGVzAYMdl5wJa3aC4sh+IB5TpCHPh+wWECWAu9Y9vAb05i6FSfk3v9NHkUpkxcis7D /x02vPDkDnrU/IiNE0L+N0aQqV5VTCjG4AX1kq60TLOAoGNb1szrlNXtjPUkp0XtP3KHjGQ/ 3rTZuVlXz956DxKZXgyILzpliiNIHA/gcbOD3h9+ISOHtclspJCtKnWL+E6+CroDKU4N0s/d BKHfp2A1NS/kl9PPGgue+iPBUlOLhC2ujdycGUD2d3Wwvv0hR2ygzc/fExEe4yJASQG8ihSJ Rdw3r8pOOS/+/nliMuseomGkXcPSHBjunWeGYgH6uj0zVwialfb/jOSE5BlNTXrTRS8hxDHr Tdylo5ZoSd8Kq5h8OwQQ4srYyGTQm61Sz00UjojoEwKW3ebDFCxJ7OeSaz9rg6LivkM9GS4n R8KfQezPo6PhGpw6Y10Obbi+t07DCrgAEsqDeZfpUhIBZi/aRJXDZVNGYsCCxdCEgrczbPRh Nf/zg2rYFNsG7Nx9QLAMbO9mJ18tsle1MqSaNxBEZ5CETvRHfwwI3G1bt0Y5ODaKlg6HQjev EmLsT/9Tdn9PWUtpz80EmCtP9/XF4ndhBKMKjOexKnUhLqxKtbS9r7giXWqP+C4VoL0oVUaj B6mS8QV+CGjjPRO+JTQv/kx5HP+S+NcH5wmliKFmRrxYTj3vka1NFEobglGsaz+t5Tno1vQg YenAu1UTG/lvB2lKZ6wDwohbztpiz8vA/e3ee+QTGb6Dgml1ExUHSexZCBfDQZ/MdgQs9Vxz 0+9AvsEtyeC9rSA8xgy7iz5YmWymmaSmEoOMqDbzPnM6JlFBLzjrubU3aiGYLGd6bpbQ7mMv YeLWLckKmmjXitbtYP27yksHewOJR8dX1PYEqKbfIJppGSf+n5FLCKC/S92ZkO0gQUupcp7x eZS16c5PYf15Zrd2zS1BQGDUvUn2eBJr/LgeTxpKjAFg5kt6ZFsW4FWUcwzGRTgUYjLlpTEG Abizk9/nLkJ4M7uSWou4ob3+fdCGS22/XKV0M4VqajnThHujC8lxApkh5Y1Z0XkG+Du87w7J u9zzUEDlzVB9PII+nVs0aRM+0BfCi5PWr/uFFqhuhedsZ776yWchwMofcon/u5Bhdnq/TLXl PJa/m9ju4OyP4Ik3bS05MLscHFHIz9F2wfYDJVjvTgIJToh1HEwWgA+9fVAxeaYcvC2Poh3D 8LTX4Giw6QPPse4CXhgREVYyKcCPFm4M9eV4NRWYAT4TUfHd9JcFvVXGv9qJawGRTIqvyouS +XtGzCD1Kkq+YB1oVENy1NRFUZktYrw70bsLFkti8TulkWcWrNs/3ktTY9EG4ZYZzl02r9Jo zSBzmaVqh7yGh2EmT++J/yhes0V7io4umVKKoCBOBsLNgUObZYPvaulymQu7VqdWU0HOkehI Fb0XhBU2J+nKby5CCtC7d4ujKvpztForur+nL3BY1VSeKtKVIpzYPbKl6tWzIyJqybWMA+RL aisYcSiG2qiZmlyrUATVJfy3n5+GrzApg7t0scaiLbgAR2JA22yuJg3zo9a4i1hSBGlAAwy0 faE+6niahd1OYOjhcBu+iJTcbPNXa1NSkUaAooRWytaZ6513DtTIUGocVRvtgILXi7/vTaL4 a0a2oupqu0KAeiN6B38tyovzyZQHEo2JGZaFCVzUpLgor6Bku2cQFKtV2tj+vXFOpABJNdan 87ZWnNJ0Tn9vI/gs0v040ulAEPKqZwr+xmYaXbdXweV2iab4IVHQxctClhQ5Y6/Eu44wFa8O VV6puYP1ZIzZgyx+tfLGF7K44cDoHgbriJHTkt942iTRL520tjsN8rHuzPkxvc46y+RnZ0t5 twe/sQTR7YzJIDX3yh0ZhFkmFPQGga6xmnG3fbqRteAduMGCRZICD8I7e1URbAsiEs3aEAnx um9SvB7XQ7RiJwbjre7rdlK04ZdELKbaCrhEUu4CEaA1JKdOllGCLjnMwq6KWfXTXKvMdVOw yQCwOEQen/v6gL4M133dGS5sWbTYkUR5+MDvGul+KH7rf2VHV0R8rzFD6zXZBW07PUCBEJMm IydpI9HMhdACEmxIb8R4ieftvAI0/tdDk05UK2NUHTeiLXE6AtN/wp/D+TBAa2T5tZBbyUl9 tRs+zsfiMxZGR72FNwzdo6FIsEA6j3daj9vGorCSis3z4fOODgRmCDZb+JUpG/CLdcIYkP5C KR7KzHbadHuHq7l1o/750PWzBP6AoUf+1jnp42F4Y6RIw79hjad586vI2GujBJE+UvR61WzF oJPHnOcsj+k107ZXxoUYG9a5a1ULLgi2bFZCZWQH9o62przBV3lrZSoMyfDrWrIbRU5Cm65b n2OkJtjZp/BL/q4BCuC52v56rHuso7hpPDrzHNlpFo4deJmOe79pDTy/6aIGJI2nMiHBna16 /6aSJjxMMWfu3ArsCiFuT8/jlAIUSendn4PYDh3LEdmEzkK7wSf+fVayDMqUBoeMdJJ1kB7T xh61nU3jASHM7LQ/quddrYT+aNzj1/GaLncEFIaaI/4W9AapEK89JtybGtGiHdGULkB+adiN LvV9vQltArJah545CmusuGx2z3PhkJc5Zf9StfFj+Q+c0sLP21OT4Z1znGvhVcLQdXvSP+zg H1gjbrPSP84XDCbDZWlKzqsHZ65v1v6hzXNIgbpRHk0peGsf1pH8wtrENhzt+PHhIUIZR81L CZ5JXQ39Xu3zzz5JO29MeLph7N5aG7UZmMl463UP6GhHD1trbxggDLu30Ft3dPrZfsESZROP euSPHYskWHkNtgQosaC36dRozamX8EXhoujDgxfGB0HQ0D63o+1o/zrVboQqJoDvOT4F5yZb GTq7QIqxnAxKjCVOWTLmyOo/TgjiksozUCRDLKWAvUK69hVNVScgPjvlz2H2tmSpaeExjWYm t13C40F9TvfEbMAPrScQ56yK/Y5Emsk9d5IeUIJ21FTvC2HspCJYtLOY3LS+VQLlPYsiP4Ca HEHYHMIljNTTzQw5ZJXoPFCsrUzGyfSsyfZ7AL1l7JnxuCLQYt54TFfLWSnVt1IcduDEndaf 7I4rCdsw8UekjJf8/3lIzJm8nfQbLK8v61p6iDE9LuSOuzhFlgjsydp/YHNJCFix58/JDW15 IqNuZue8jt3c1zeCViYPQzgiyDBhPyXjcnhRSmMQpuKnTu8DfbRYpDD52PVwYRGLO/MGlePP vREfR37xYXlEatRwkFMILb3nYL5/RV0Fz5AzhIA6APgeS+pp3ar7EpEG0Y57T+voelD50M36 uU9hF8rs2mz3xM1hpW6W8CSNWMF5bDgqOF1CLJnxrt/d/SLEHpft7nCcLodwq2Qx2QIzkhQM ZifYN59JqPhAp3QX8S25czhvRvL6jVCocwVRD+k3teHJT6gZ3NIxD2RNcSVnoCWZP0gLG+K0 et0l+wbGCnSEas6xHXlUunOhqjQeN6lxt5ZsxdFoS/bHDdludjIrbwuoo93T497Z7a9l0Anl DzOOZIWWn4Wt8GihvcOneXlGgFHE9Wl+B6FldcpRCFRpkyMpe5h3N7xIM4KyfeQxHBYyV+6d tt1GlOJBDjeepoWjCOdYoPdujre5QPjh9ABLTMXockolwKZ3IvGqEa1/70FaKv5X/CgyDdRP xGZtDK6D6d/8mNBGhW3GKloFi9fsOzul89DfePkY3NkHgNPExiTHTw18HDnX2IOJ5ap2Urca JuHEcpnmleLLGwVbVq68GScGvBDsR6MU5hUmzQEO2it3uXr0iAn/JhFyhdMQPJh8m+VY7VbL 2Luhd708287K9xpg4ISgRaNbQ9DLKAJxvZ1AFp4WyKtXBtiFXGVGuZRXSeL4i9RiGp10ANeE UO55Nq1KcjzCj+lPx91JfG5tnyrFJgwzwH5sU5OLrBFdofRzCJYW0oQklT910CTN33F/wYaL TTnVQwKlF/qSoh2BP84+663rsfvo2n2zhGkTunBaGEV8gQb3TOCsAUeUA9r6RmO9EKaBM3y9 XtAPunOg6wvofFS9c0pGXSphkFmZ074qvrr5oxWSwiygniaZ+PIqmSt4Y8eLhpa3z4NqRFr1 ZogIrZmU3bbvscp8qd+TX3Vjzc1nJHO5SwmCPHKNswFtm39ZNpexVcGvjCVUUW4Wv5gZ4qxo bFEUtd73PVxwRfSgEYKfCdaYRfNZk0waALEQAft22GcYbYpIlEUYPIN9MEr7ETv76gp6NMUQ UPEmWuTdFaIrg+A47v6YgnXgbXfQ13dLnQgbZaMHiIqACwuYTojtmUeqkAj75AUi3sLljc1y oSdtQxtikdV6cAP5f3SblihMahbyCqXaTb8a49Ygk+OEVyVEzNgOh/nRQllU0/s20taTxitH PCHP7pDT9xto/K7Ddv2pDEA9fuixqiKvuXdrDNupbd3yWvLwYjFykR2+u1Gspi9TGs4jXD0+ zt2cAVWXRI5D17TN5d4kVjcguo3y8PAtRB6B1HxQEtaoqm6NZdoBvIwSs6ArpS6upGh7uWIX Z9X+SevWH1hVTYsuxq8eBsThO1Xdm9WaS/NgPKzVs9eLh2bzzg2SLR6qdwQ10gDLXenFnEGK 7IX27KXV0PY2okNXv8oFn6JqIRgifbhZtd/88nseSWYRaaWZ2zLpTTRZtlnCqIXVHColkwVq Gwo26HxDUwFGizZ7pNgOya4w83vSoz0BUWJ2t8qQqdQFjQsp6Kq+ofb7nFaQdSxl47zq41bJ sx7WtSxQ6+jv5WxwWwQr1qqUmyZHA+uTlaWS7xp+dVJGE62I8UDiJ72m77wkjsO0bMDDwRwj Ih7pT/x+izsP3J5tIdW1c1c7vgA5mB310zdBdCanWs+m5DZs1YKgd8E1kxU4u42CARZFX3i5 UqMSR3IzJ/j5r3QztLBtohRzgTucc34oxVWSN1yCnZg4sGaPk6K856/MMTvNsAvh88BL+tp6 GM5NjOp9mSo44r/L3w9b2m1GAjRDWUZQpmy05tViikr9QSHaktXuBD4yAO1H74ca0Ns/bxG0 XxgTmZK7WshXhzdjYCr2/sVMROsGhxBhWMSc2oTFZyx2DU1nir2IKqykPc9gjtg/gqZCpxYx 1wHTVWy9i7L1mJncf28U/klJ0zOjnWVPYNTvLHFvxnqb8sjsz5aZx5YO8XjX13nT7ub58A86 VF7xFnN9RAE96PVYk68mkUBDxekBO45XhSLu9caebKWM78JywypbEKuNkzWQmc/j/QQwGUJi B3p3d2nG8zmmBk6m7R2cJc7scSuhgF3ck3sDwwvfzUfVPFxEd5jGL5dcFf1PBpifwxnuChij vrbIIAHADJoxiN0eUXTqEDO0s/BzCcMmCf8UJsa0zBLouewC/w6j75dCsrFGcm2hcdL81t2j 9FIjhhiUBmfNhj/JsvkDSSjXj2kRIqXqhCn/9GDse6gAeFg7kSgAPXNaNcuXl8VofhhCnyOk Nxm/BUsmyH8pIQN/HWp6QNeei4Q2/iWwuF6SKPb9JNhGiF95mnbNoDvtXD5TNd17S8DOqcy5 Uce5MFFiEnMTuLNSQQOW1pVt9qIo2YgZp7ZAaqCKt+N24wyHYO7VlS8zLQLokABPZMB4aig6 KPJ+kP5frPrJjFuiZp1r9/MILUf7NeihagQ2f8PB51GQUr4Id8UrOwH/izJOVLHQpm3T9S2I Hjtq204H1L/ADIerraRm3495o2j5zZ/sLaZEfnje+wPlkLbZijkYi9lehozj1NF3l5iCH2Rn p2HGPGwS+pyh8I8F87FFI05frGMyZbrmCge5AbszNeK0w7/Zd8Xe7rkdOPoLuzZHItKlBme9 iZm6QKhodShANOunILDbWmDotQNbUYPpmk8m4kV359lFqy2rT8J8ucvppH+TTi+JvpdrQapm m6tHXapPi3+FqXR3odwW4hGLFqmSH7zv+ZObomAiK2QNwM3klB+1qyjWOt8ustpf/r3PydRU YWecdz/v9NgzJ14rtL6COPW4cWriScy3/5BrOzuW/I8CgbvEfhE41E1qV1mBpeBnLUSGE/f5 nzGFWSGZB1S8GJ/k/veRD+F4OKYTrt5uf30gL3v8MqmgnfSkieULaOUX5rjFuoZQWNhbWohP yXkE1xiFAbvposEC8bhsHaKRVjNB4SdMkrDyCrgKw67vXRF0JR5+Jx92eZ4d47VMdkJrYzKQ zmfLfJf4cB9fKjead6IWpuVYwrGUBAQS4vYvzoeev3kfTymIqMUqKZVicJrHkKGyTmaYr2Ej yMlj5BNWuEAlox6DsZJ0SYtzrveiYzT1SmUDjFb4O8seBL+qGZdwBUHsLCQPgbdIrRwCZEcu /LZJHRTxErSvxbsvykGDUJVXnadPaXNzWLfMa+O/xAHIQNfqd2CXGe4T2yjqW7gzQZcKW6v6 rWqdvmyjrowZE6LP78a1rcQmZTCQXGwCAX8/9VYvli2m0R57pLZfpwicy9mEE1nDkmstJRyK cxFbAHHr7jVdY147CTiPb8JYucNkvgn/YdXuWZr6q0A+ft8+aTHr00ZQfMIrAEOGEEwytJ1q 7XWCTrblBBgTQU6nU9ONk0B1yJcJtXl+nYlCrroGrK27tHiz5g37rk+P6vOgvXO71lGQ5sho qfuawUK+JW7cM3X+B67G16fXw/pTvhRbUYg4FQj9shDpDqrPHNJhQa5xXhXEYlxuBZnD7c+V aG+ZRMK8HBBPg0lwCLfP1m1paIvqmHfe8whH2eipMAJ82I6BD/KRWz7lNgOc16ermWW942V4 0WNoevnabtMMWsBcGqKNcIKnrOq+IxZUCaEYtFfPVOPb78HbOw9+rxIcaRUgztkVEGW+8QQK acuKzpUnJWMwHWX99ZQI55aeXziQSbTD0Tn/S1/PyajeE26sucXQfUXmBjoYEEFzIPnBDAEd Ud4fSbFcMyxw5Z2XZcVGMsW4dL7ngyXj3KFJbqSYu/dy4MMtAEdOTDdNVj339pSrUTK7YE0G 2ZSGt4FKa381jXB2uCAyGRgzDhoa2c2vH0ZoRPJylR4QkG8fpKNnOI5dD4CQ/KyLkAvrJJWT rHJ01Q4+As1AMq5u3Le2DqM2H6s5PypRPHC4bm3tr9sXvMrHsNXXq9HwWZcqXoFz/oLUDUp1 Tl8YqsGE7Ien/aiiLa84ZP7qd1LQWdL5QS/P6HSvcsh0AoVtwZdCWq5VDmtABBORn9OTP1yb nDqHKK3+N46AFAP+DDDkr5IOycm//3Hw5vSkSvhHO4Iycl7ZJDjzKv5Koku/lZV6uPU6BDZB geYz2gHPzlQi9kfVEWnR2ya1A6gfNKeYw1zogMqsLX4lKOw8VkaU8FGltSnHthTa1KUJQ8PN c5Dp3KYQFPij3XR2F+i+YB2fRXCrgKfnFbfVJz0s92TUrcgA00BJppeLrODighnPBVhMpedC XI/UQei3+f6icGaMaFlVbgl+QIToNtnZDay8cWbRDVIU+esLBIakPDeuQ5eZwslI7jWe/rfI dOqiTkmMHJu2P8zzfhrW5WF6MoBr4lDUGtq6ewIYL4tRKd97hsNN8lmBKdPlAVZOfJNSSgLr yL6zvhE6JIO3dIpeGm57kzx9S5LzaYhxMroUtRJ+hBd4vGIE7IkPR2F+wUXWmcoHLH9ucaXo 4BVspEwPIRr7tOhX+aOET9DzvmfqDPYPhd0briGZ2qz6Vu3MnlB989RyWaxr4OFcNHzYPrYv RKRVTeys+2bTiweuDx4te7rW09knVQ51DeBDZB5Z+eqBo5dUgz0nb6p9NuTvVFckBZROocD6 vZ5NtqMz/l3XrGdI3Wigvytt02o+bMAr5636Uw8RvMil7gj8o+6fpgscls15FLZJDoV6Rz77 1u/rANRYqc6G2tEaZaCkjHBucihhMZaK8Ylbbj+oecvzoORpe+RwZ8qld1NubwpT4UpA9GkO J/DHi5hTIEkPKUHUaWSJtCjw62QWlWK79+MltKqvmXgcDejWea4aXsG1bxZPXa9GqToqbJ1V lnMFKwuJilz7OoA7XGgUnrH80g6odq1zLgOGp6OF2Rdt3Ul4Nui//orY6l5NS0OrKuLVGf+V DPTc62e9YTXIGYMgkPelNUsiyLxK9gF+QJTeJAKPCVAGIg3J+l6PUWM87wA2mJYAVnyqxyaU DGKVc/UG6Ug1LDHmmAZ1H0nxzZWPhb4pgolDqlq/EHcFF/2VfBmWt478nZ1SlLWGbk2scSbe c8sQ2B+cNfFeW2GuqaTnIPAeZV42qwiNuF0WxsFu9GlNTarclklYCt9FgN1JnK+sRFLsz7gm +0YZFjouqKTtJMlaO8uJyiNpHk2ZHzfX0/XdAb7Nf7YFmSQcE20penBjPiu8y/mNALP4KNCc S+xm3Lru/8g0v/XU34TB72gkw8Xl2Ad4c8cP/Zw51xTGifxRQDv0BqZQZQ4kQ1rebXgvFBz9 d2Hc6wfEK8KtVZZUYs/Nz5vi8/hJmnBl87WLAG1vUFp6meX82B6QPYPHk9FftB1c/AN+SXl2 FfxmpXh4wDYzc4iuKmIY5/a/mT6QIFPwBpi0SODdwR1Mu5JMUQk3kplr8JqcEkQYiYMs8Vyb SiVkCbBfxjub2/auD2cJfAqv47JGfx8Rx//n0hj1IvzSYUraCBZV/V3xuaP/jKIEmfmphYEp G+jKFdoHRHwR4BTmGZ/GJFsSTe+NAlgySOXs5mQKGUzPPTCYZLlSMrfDa4ObWUF6zkcYtzp9 RkX/btKBusBUCncJGecp+rgBqKo4dlvsoigKORWyCW0v/WesUu2ijFtNs1wGvoXNwt9pOjII fbUp6QUT4hLGU6JQDJY2CbTvFrCMvq+6ZqV3s75aGKsGVqlgLIZrb+NrM5nOtodKNxrLUjrH hPKzUHc1pdOQC/0jBKlypAFWf8arLcSUmXBfLyIzjgUCQVReoYDaBRpXGLC5JpkDX5lb2DNf ndV4FufxWCEE0OUfx418/9ipdY5C2TYWiLXY0s0XWEXbKPOa6xx9+4IQ8R2s3jRN6Qa9h+Xv o30ildgcteBJ5Aq82zmgO5yDFXPwYEQbTHbK/oxLipTBbYGP5m7b4ZfknichFsOnNknMfjAz EY5bXKmkhxXMqQhJPQMnnOcFiAlHi0HBv9S5ziTXHrWSGlpLBv97GHKn1bZ6wGQrpkWRlE9c jtmHAXs29vkVwF/oUDh43BTIYFCMmAW+XTGezN2+HN3LOo1Om8+eTGZOJ0AxmibXVuNCihHb 9MNPmGTPOALxfb8RqumY4L5kdTjic1M1BDIpowRixFA1rMDc0Y5Ck9vYnVKjqBbfgWgRjHSb nyGqXu+46Fum/GcM84DGd+ROLoJ07fesLjOEdWw9YzRftWMxEfKX2HD1YMOVGmHB4ritDJAZ wc6lGQBsfH9dNB11r4wPb7S5vj9FGjdZainzomyEo2oafsoPlrfv96wsGI5wWCBtRr10G5Xc Co/tn4TKs2TXEPnS/7ingg1oWjNglZ2EjjQzRCfo9q5pY67qvBEtVvGQysRGQi/Fka54nYCC Hdxp0E9NZW1Zl8C0iGG0g2ByM+y9nwwI0x1/Cg/WrBLD4QRNqWO+K9MTRSLYdovFz+NJtR3A O2Y3dd9JctCH7D4xEeinBU/4WZIhxlR2uo4cnupHtbwShOcZkMSPtAtvPVzRcnEC6+/8NsOK 65LP3gULqs5jJVMdDTD+l7GPMWAL2pa+F9dm1KZubhHczmRPeiaT3dByhPFVDXlGYoDK3Lhb zHnNPGR6pbU3ED92xRGuIrv7Lfqb/R7ObSMyNQ+peoQaGHILxR/uPJxg+2Nx3TUZhoZ297Ep 2mXQfd/EYe/t5ey29daOPEqoB4E+kCpy0VHB8cOusRWI219HMonMqtmZ9DTBm1DF3QDrD1Gv lXCV9Rlbj8bIDO+dWLB982ynRte9Al2knMyviptZh8LzGvIfR62JfN5JHzmtifJQCoXbza6R YnQjuXFJLiACMOrDJ/QAHHYq0LkbJYIIySozzuxahmn4j7fmLHoZY8ze8X7n5L3aJAdFLwB7 cXh6uFSWn1fV4cOTHT6h/nNJk9lskfY64LCttjnB1ZnHuh/wCxyT5xqp2VVGgMZO0QCZvM1f 2EUsQX6QZGtD35w9UmTeiou7fhr61qMH5Uo1l+M7QTrLYN1BCFj/RaFBjpDVSKk7E51JrLXi eKqCVo3WZyNUDfjmbNI+AK+vTcik3grnhVhOi4awYSlW5nXoJqS35Nxx741X5yjZI8WW8pSf 14nsBVwO1jr/GnaUIiFlN8u/byZFOF82GopBvZSGZ3R4EdUncgpp4Nme+tX57lXGRpsB4OUi 52Ca/j4rQKVdLR/kqaS8uvV9KIv7M99xiwOvYgDRcM2jRbX3VhuB0SCSmJ39xJRV2hTt+Yt2 khmb//t/KoKUjN0RMSdSP0YnFyqI6UnthB1Zu6pd4GLdbq1w6DSQx7wDKoHbEnvDdC6CiXBt Sc3fmD5nE/uvqN32P6L92Hl0OPPXzA9M42kj9uwjculWiwwXNKhY1CTN5HA3ZBeMuhlj8Rgf P/DT8MVq+NdBLz/uwYv7g5LhcyeTySIHSwSX+ZO59ad7kMVyrKf3wiig8kbkyMOKmnbC3qA2 J8NSSf4Od6DvHiveeo7x3UE+385lNr04U6gWANpFWVwnO8L+OjgcDkwSt8wWTxuVtTQP0DwA LUDdn8bSTalbZH8TtWc4tQkCnGe2x+wIzfUTpC7x7XBZym6BtZG1B/koBgojqVhOGSAgytYn +E3BqMZ4YcyJT1u/A+69rXAZ/SEFRVVCqJY0druy6OYEP8DcYH8HJBpudF1Fc5rfCaRJ5IOj 8kC0VcRj+zKBIuO86fzd4MGbYd//1QivWwEmG9mwAh2AcvPeOL8xOhekHFyTI85eb6Ajqj4o dovHrLT7o105GYwW29wc4lVmLdMHj4clLde7vsfDrAK54I4pHkKvWWTLSpOFtG4gGLHFy1em J+vD9NGqHwGojwIgvzC+TJnrb3JXCdEdAHQVqbm+BSkNYNfXMBQhF+/N1BG8d1r5W+DVdgRT CclG/FM95gMEAUka2SD1ga4fJ9SYD90X6V2EJaS5vTU7485dsBHNqKu4q9jVSZt3nbzqHC8F +i2O2IrvdDR54rGpy9uWurADBhqa20C5JHRFPvu1jgxIaLis4OO7jwF91SRaiFQwSmUed76Y c7ZRbqQ8+GRTnomwMRp8Ojf/jLOmjpMF0XcfGXI56+xkgOfKO1jYgW1YJiY5rVFMCIrdnRRX denxc5SoksygIXeaEAqLVXEo1BNEL/Ds9XTcPgeDugSY67VQdjoqhpI2WSv0G3WtGRSn59Lu VrTIF//gK0iGITuFyzpah8ILCHdkdEoyXJ9A3itOwKmoisG3lkl06McTt6DLyiY7AuLIqKlC 9nDn5wv1xDLZDvfGbgp3lQCXnH+fvQx30fBeVV756/cRA+RyPkL9L3Qu877EE+AKevJZ6fc3 MNhFO3gy/5cBlwTyCXYZr1mu5k2pqv5Kfw0JmpsY0TegHGiKpSfmIoIy97HS9Wpv59HmvzYx vWVqsfLDhysu4IFrHqrN3L0jX9jlLJt2SuZAz1ipk0DHfV1UdaXiGx5KxKXzlg34F8tknTLc Q3VUxeokvuzAv2gteYINKDah6SGDwOL7vCxxBDzoaQ4Qtc1pr1rsV9n+f7/mft1BTHQXZOof WO9exO/BF9DUTecDSjuh5rbVyntSZuU8+vak9alsMfE9J6rRrBW2JeWMmOSj6pIiNEy2lZTA 6AQVhA35f1DeqgQpurv03WgFuunNOWmbRYZGEkcyhi519UTlkGrf1t1siK4nBiHS65aJy4r9 dUfKrKZEBQ19AeM91ePi5kWKNmMDSjtnX+Hag+b8IBtcTj2E0oMEhAUAhw2ja5XGHOntWVt+ N6bNBYFm0NrvLJOF1N4564FdRz3dEbp63wXmGPiGW91ptpYPIU36y2yx4OjWHrf7+AjA7HhW hT9TAe/aSjjxii5Ts2IsacY7a88QjUPnJ45hTk/+w7Vfyd+/gQsVDNJ3BVSmHJeyWx8ZyX3Z GIOJu9d+kYZTSxRz57PItmJfe1RwNZGeSAw6CHAz32YKLXy85BpefOJIM8IIQgWrz4UPQMUR jsxrrYk57xoTCPNtA52ev77YbBp+gG6k9gQRSSY1BGCe7yhUMZK024sqA8JwZXhdyfHdEQpq dcsHgWGbUjNokDoY43GQyK9MqxIpBJ+7zqi6SzXaAERJvcXtX10E6stuHNPTNH+3W6bIZgNl Nx/Xu4miMEVkiCjHBkpEQws78OHjRn7YEtVcNM/MQBR8xTbgZcaR75joAQFOXIquKeLfYYGW yOfbGilouDqUZJnqNqEso/f+70567mzzmOK9sn6+I19qYdtPW9NNhYxJl4XoOGxmLhszWCgn hWtKyoBIOp0lnF9WfoGiaXYTEjsJJysKxw0eUPzQUSnOn1hL84fv93dOJlDm7STgaAq4JhSY ePGZK5HObEA9WB+OlOOuo9zvTaB34BZtizUUic4dRU/aJvrI9C87RC5GgQhLbyCtsUBoXiRK NJrBX9aHX8JA2SfqNjucD40NaCcjmbYL8+ky3yoSq4bPq09XjC00jdMd+3dzOpmo0AlNfMWI TZttu5Jsik9m9vC+ImsR48y6cqbPxBiL9nl0L3a+voYFb2W7GZeFkn+mLlkIRaMxrgF8TsNo D2JviyOei3aY7ZLBQ8Z6pw4JwQPO2tNdKdIq8opiVdM/RDR3qI+yHA8j3LAnGJ+DlnA95E46 B2u22xVtcLjd7ouxWnUwRtu6TPEUk/ASWFWjp2auDNlvJzn84jY4AO4ijGorvb3+IHAVITpL eLtq1QKRcGS1UKgXJ4dRpK8W0G1Km7wLwFYOymstN5KKxsGEoW10GAiLleWNcenQYxfukzfx 3olUR2dOD+GcpayNkORL7FKXQHLSUBtDoJ0mNecK9ToZRM+FXGbQkVZB00nSOUCkKPAo70gB 52P5g752vNbpUiSgqDw2XTbnUmAh9C7kPgsWBzFuGUdnrZp/BhrPuXzc9K2f470VqqOhB9Gn gjJoHfTY3LsVaCWEL/Dyc4fs62aXBVhXI5oA9aGESGmfc1nwQ44K1MyRwGCyglMr7d+YHe9M FEH8NYKGTklio9ZtGSiX8XkxZgZmwV8eS1P6TC9wdWb8ciAVEdLfSFK0gfkHQkfIp4x4BpgA I0LjwcSkTBJbm6g4dsp9SE81q5rujX0ZbCU71Tfp2boSQTaKFbzZBov20YZKVk7tsbfzVVd7 xyOycDMq1TrMcqnzYcslIt8aeRAgXCgPdG8jXOlL22rLnwd4H0n0ua84/838j3bp+HuOo0AC bwuNCJtir2/jioFXRWVNKRI2ALzmUEqq7lTs7yy0H4tWVRfClKNkmD3/kSTDjpxF3zYvKoE8 6fMF6BYWyMde8GXtzyGCMaugV5DM0YFYzYvPsqFyAtquXP8phZnM7GArlK7VgbumquiCreVW 0DWbpeKd7Yb2Rncnju5CYieehyf5fy9RSiHZBl72Zfv9C29KC8H/y7aLSAcF2VNtSj42K4oT 0XkY6QkfkDMMHwkiVebPj/juW7uN5xNrRMyTpGmF8znxs4hA3gYjKSOVqiaFlHvfCAARSOu4 RUnZFdo+mNOIHfjbxLw8ReyTLdK5Rva1eC43UHYvRvT/asfjmglWRnRHki770EM5XtW9LO5z 5yr67+LOyCJXJxNwnbl2yEejjzMwydQol5GXZYOo9ICHNGwzLtcn4lnCf8nHicp8S5WkDVWa E2NK80UDqM6yrm+gHs/uMxRGLpD8SBAQeelgZYSGCNtb7p3f8e8kc21cwEENQVeA9m07ERSJ WysIl8GkDnQExKneVI1XTFfT7Tm96+2pWGqufbugTTr80O1XdBmmMAuaY8GptPSuCmANbP6/ oP/HykyxFG3VRyaaGHK1CgJCNlG90z2Po6ZHi9aARjZueFgvaLwsQdLkbnuVkYkz2bNeCQVz BucYaRKoPQw3862PcOxXh/qYzLSBbkaMDuK9uMiXZO3sT03rOEYOdrQOJdFjf+uur98SIMDH kNv6i94h9fKoOzKGDElN02w/9rcQum+u0shkWVXvKRRcE6MhZKnB72McRAmRGyBDnqqkEZVO t8oFVRj2AM0wCZOTJi40M8G2dsIADVF0L7scfLRy7wEle8K58bVzoi6l4zEpzwgBWcpU2MnN owkacUykSpd3JYNGuA/sTMjhNlMDAwlXftZlKTWAyHCb2rU7od9vzCD7Z4BAuwNF0moACDo+ AJCR8zhN4xO0s8p/0LlKwDQ4FqUgXyyRDTddbsWIKk2XGMbjRnr+4gqYau2V6yzJ7vrEmlyy KcssFNrJa187SKiwQp+8JTrk/r1MOfRQ0Yixn7Wn3bCV65I3gpZAtR7f4zhwUK9pPBvCfaC8 Yavgm+KUFBX7Mx+DEsO6oDiecKn23Yg/etsAAdlp0aqbu9Kpa12q0KUUu6AJk6vqzg/HC4Om bJcTVfZufGu146+LakbRabteqCjoN8HSHcDXcLF+uXVb7faPnIIV6FUClxO44rHsk41QDqzT +NzzuBYiv/Bu9YjBCxXyvG2c4RXjEkhkYjyDaEHD88HxHpMQu3PA4UWFH+XxtiUn8AWt2KIY DSwy1rx6pLo8Nj0whEAv80HxTye/LaT2cjw+t2iZcImji6qGDp2+BzXD8YHu+nI6yA8rtXTZ RNX0oO0nGXz0iaEYiskcK82RFXp7HVAZjcDnos+V7H2uBvE99vU/LDRGYLVTZX4d58b0xsLK FjKFOvpiRgY6P9SN6acPxfkrBEzJQj+dn9Fr3eAWgm3KuS6hXOh6iE+0vWNoNWPbygoAuZaf uvW+exmx+3MTCgpFrLZw9jSkOZ5GbzzmqkduMfaz99I6rH0h5Z9wlgdQ4N1rdkLeKn6xBPGK rBLb5tRD6kp09l2lIF4/C65RNRSnjk6WFHCaVl7QG5TDM2d9/DWvSZWCl1EFErEnSXY/Jxu9 s7LwrO9WxLbM4hQltJiQncIGhNI1CnmYdt1WZJbmmS5KNGTC1u5y1x8sybnjXMWMBQbrbbeF X6lZa0e0SceL5FLvf3QRkzb2ONLq0QtruwU8iVRNbWMG3eHpn0y8sKGsnK+H8okyBlb61wbB EsjIsK0DkfhUdaUVWVmLBQmA6NE2UdNaCUNZK55+G5OgI8+E3F8x/fYXAwM1yUO27R/TANIy j2LRH9fA1YGAw5JbiX6IM4mP3eY47h+TsqFWkB8GqCIS06+DGFQHBoiqiMV4hfvneH7vvbtg jL4uxKMXWCfF5qJRyb0DJg9ePzT72ejcRiTdq/LJYoZZErnbZr2SYwqMaHFLGUX2lbe7t1rX JLERmpGRNIjYlq7T0NELkwPQQwtDHENhLHcA1NDvuGH8MldRPCrQSqrMYswHFiPVegmRhm7P 0DtnQwM2yNvkRQapBZEE4ya2Hf7xo6xGB8Db2kjdgl4w2YG68qPGKwvUbKUy3aLU/b5zgbyw C7Ckus9w0PkMTHd2dJ5q4BZqOLOji1C0MVNZWmvYLxzpDxPkmbCqm9OsNI96IatodIf40LOO 4vtUPFOfyY4kdkfP1f4ELJCpRbPau9ju1GtX/XQHawyvaVyXBH8y6Vk39ThiiQLs5BT+5JAM AZO/bvA9Rbn5uvlYDQ0GwNWFH5hYwQisr7UBGbxLS167xKNxGh7gdczkedTc6T43yvaQKqTY 3gXGlN6djTs8fpQ/XYYicTHIyJsMWlqOCxShHvNE0CdpmC3vdH3O8FMMinWcMq82urm7NuU2 LOdHkGmCz34XWgcm1Zf2DHikNocUDDjdkuqC+7OMFku5xGpWPZIYmaCrhAVja11hnhFGZdmT br3nyyGmB/HyeQ+lPywnDtD5MI13iJHwXtPq2GndBocUV7KuZ37ZM6FUct8R/SqSlpuJ0VXL ze2+zDhS4YkfYtsqWs0UVZMAK6689xJXX0rQ+QSPUfoCtt5JL879Aln79kjDsExEWnZOwrBi hut9sRosZkgs8N6UPxlv/d1I3GiSgHNEf3gm9ZAA/tJX7xIQ1EYwE4oAcDDSpC7nIblVkm+t 1qhHdTIv58xx+oJv6mr7HkBYiBvMRnlQ5IINXMvi+mFXeJdzM6hBQWcb0ywfdwz+6mRliVoQ 8JeLC19SLL9ejaxxzVGoRiJkXJ3qfp1yxsh2m6j+N60nmjFZLHC+HdZ+9WuFWpnrKprMaCwa rRWPNqN1oHL7MCH3HLxbNF6NMHE/63QQ5Dw82hLQJKb7+I8KfPx6benVpaAvDARk26iIhLVY W0soieV5JqWmBH2et1uwXCWUF27tbWo/HxnRpCRBAiV+XcaM+uDOVBWYru5QGYW4pfrdleE6 3/EjgGc1MqXhZ2mjFlyS+S+DqxdUaS2KLhd1ticL5xNAcvpNrqktPvq0UmXVTOzgw+xAq2DS yF0K+WsnwcfM6CC1dM6SwOFvbXcyAZrVH774EWwdXO3cPh4EkgMVDxWKL8b3gouOd1EHXSiz ZfvnSFPOiXmAUZzly2V+JyzZCfILTigdRcdhyKFJW+btiT1yjdp1xmcTzWmwF9NKczb4TppB gHD+fQdoil2Qyza5pVF77C9EVPxWjCpF7wXIqKidGgDUzKL1jqQy3noHZVCYeDouRtHsWxCD C8UiDNoNjq1q2VshCgk8foQs5rY677+N5PDufj9YPyHDDm/VryjEFQ6Uwc4INxbs6MHfBSCF nW/o04Dfz/c0RFMlteHmqMcNzo2qiQLoKH8SybJN0Qlg68sP7jRY4WIVIM0IK3onkzlgb5+R ttjqDYtKkzUaTYuq32cRvLALKScp/1uO2q9PxhgpZY2ry6++vcb6Hp+2grV4X46lJK0NIuqV 0asNq37ukZVuW9VlpskvTdyAkR1+Mk1fYMyoNTT1wrp/RRo8zLOZVe7BDtaJrf/WP4ZDyviE N1qVY+iqkxpFmpPzpUvVDTD4SZZ6UzDq1meVMKinCRG2WazCdwJ/Wf+FdyCWjutuvt+MEBEx XevxVF6E6hXsagOjE7HOfkt2KSDXwl5VnQqdV02h3s8CsAKPWpoPQHSMKY+HF6Jb41g4Vlkd tjb+q5g+N4Smxf5s1HZ6HNIFPEJbvjvPu6BaVdCXySL9SS1lBtaCZOPR7lhLBPsb8WwnvcTR 3znQvAYKOTC44Ye5GKE0rVn3ULc/7K8eycgJgp+Uw8hPM+nU4UWVbXpPECU0SPzyniCD/xZA PE5nLiO3sxs1og7uLxPGFsLGut+Rjq7lkSlEOKCJ9MCrJEN0l9zAtPGjiqxRQoP4xwXUsVwo KFAcrUhB4Of7KsUVVO10sBwDsWmuX9MFYZX0YmUCQZad1dvgy0as0C0v865XUHg3nl37U9jW QjzBMeV5svgLp7zIsXR7vArGXBtZ0Lh2XC/hd3OIbeuEdEdAR9kWWXBnSCoD/06eYI8L5ZAk jZKtFwRLWVCHqQzOwk2urWlLQK8YRkzoM6BSSlEYvBJQpPMgZI6FlIuEtIhw4+ksK+MR/BTb lTzIzJ15aOf2A12S703n6ONwZ6vwiunqrWwgw2CywwUqOeIfOpu/WBwh2o+XvjydqRvVpVbC HqdBU5kCB1vHtfd2P0+lS+UAdXygWfy18S21nd0XVHhBbjqcZ8wuX2bPMGkkzmSUiTJIWMC8 jGeCClbd7qb8S0fNSRpPZElM4ulW8GAnSmHOg+iP9fFrb8B2zEIef9ERGWtmiIvNmuo+b0D+ kzIhI4QAWDnJ1jT7JMfQekcrw4kHsv6nfaYwLXpbBCm2JVNd2KSJDeM+7ag25g7DT/7U1+Ym 6vrOeRH6p/kAYWahojRQU74FqSHfyXlbCPIc8w+iA36HtGjhYqfBo/QkUyUmGMvEwJFiDfcE yVyv00KUrg75KjIyMPTAtlfAb0PoTZvMmgotAsTqGdp1LCjhQAzaaAiSgno02vMETOozH/89 ieFsWxogfmeFKpTkIn2tJq04G4eYB42bnbYW7SnyuJ8pGl4WLff9PkvssBcxSCg6OUnr9TCQ CStnmG57LRf7/eim4qxKKLWH1hiVC6W8ryCc68UOJIJkVseYmds3AS48PsIR6OvgReQpB7uT PTTQv53rDypFIQtcCT9/Nol+xcog6MK+GvqoKLpIenKUUetzkHUvGucja0Nbc+LW4Fisl21T gain/L4vE73PlYUNliE0h1oHnPL1dITDdDDzqLONkTptzuZvVor7LYOBc/t5GOQ9azjBN5Gw u+uHLVU7PoHU7IE+KGK2RZ8nBKK6jpxV5fdiGy4+W3tRNRTH2La4i9X/aAd0y+hw30oU2sVq l7mizcxqf4f04pssoEt7pr1/iDalcetTV19ObZzGyDr/iJCekP4lkA9MRFL1+xH/hwh0ROwh H8aJI8W2dT9fB1vF2kYkYPCPdRqjcg5CUoAATfj7HiQzS6sGgc5KojaTO0Keu3alLlgQoYb2 hZaXZHRz0oHNB47WlOmGqk1SRJl75KmmFENf5OcR8gHzPNPjktFaHiq6W6GoLDjKBPvTRZkK CCEsp/pdYRLiqvISwIlfV38ThvnW/9u3AqDFNIjvUGk2nxDhghobMPIS9Bu3ySiczHD8M3Bw 8ybE69Tt5sImxuYBpUA1/HXc5BqtSYdqkfeTZwLMLNEbULy2tCPMNFTTP2blaf0WRYSb/2Fe nneeHvd6UaCbChiy6ldN7v2uS0hhZeSdvodlB4rn5/E1n3ZOd1xgTnU2eoy1f73i3R4L4lnI mVUZxrbU5ahLdNTqTSGcJbgfOj6OHntHLeePD2I7ZT8i0J/KWs/6DHrUn1K1zU+0gWsgyG8n seXDi7hLmrxVPHLuQDe8Q4LdHXxXbYkW4mgQMdSCuyCmSNGIefzOdrxbNHtt03vPTLMIoBiK xm639KabVejdjGe9zcIjCOUmPlSfMo841n44EddfbLSuD4d0QwkkoCveLfPNaFzyaeY5Qwjn 0uxGHJ7pTReBFk86Qc+g4+OZLq7vMuY5trmjeQPYsX7sNnjUi2+JnB+cFHTmM8NzMBtPkjhM l2AgucDt/Mm1H4rIfIdoUlHUWBCFYGgrY80i8FBHiD5/XE6aiK/vJRVBpvftIDtmOomLYov6 KXhvPxfFrXgzLtOqf89zaLzAQyj+p5XblwkgcCPQBt8VrQ+Tf5/55c9Mt0JysaAMT/QmKemt tcZVxyAQ+8VV/FM6yX0cLNSM3fNGeazgx0NH5PgjGuM8x2yBOk4DRvYgJ5bDn2sr+P0Gdoo/ iZ48wT2xXJQqZyw2LclDocvLauUVsS0mu4lsB/kAekVTe10FBhgD0+0YlccM0ob6KTNVoqJl AFGA/s4eSo1SQoFw6pC0BfSqjAiUSlDApzjMXO8JKvkcyganJmvXhWYGEd6B84c+GZ0BPV3+ pvSkJ8Tf+be8vnd1e02PVLjBcCbUwAVCeEGJl3OdRMnOyguGErWmbWB7OpqUTlopHak7E47h eCbw7tZQxst/X7HccyFHdXOJ4BlHkDIq9yfqgO9hVIcV5ZO5hdXcxvlDhhwRZ4VH1XR7VhPc H++gWN/p1VpAyBxWfO5d3Z+yWOedW6bYDdvvmn1G/ymS4+4CQxxoX0EXRgDJjT46Wy3d73wG XV4OzF/rskHjR6Mp3tILKVXP3SM0rpJLgVpjOcl8Z0zE06PChjm4UkmtspEjNFp9M1jIeF0p q+ocWyjusInhUSNHPVtj0hYx/qHOv5yZf9DlwK50fJFfmpelG1K6zW8zhn6wjzbGhwnN98Hv CHDiNPgbgqmjzUC6YDCEt0RociC8Et30uR7/Y4ARztNMIIZtjwqvh0oWHrZoXgovF0zWWiRC Aujn5S3PXNjWFvK8fhNjsnyVh6aTOleYAXSSSyFqrPuuXASqokhE8Lmny3F72dORWCkhIxcl w+GCoVw9VjAUuuzRqefh4qX5oyxTt5ikIlHcgLtWDGiGYE6v2X8F+t5JdDA2D6hVkUbLXBNW AROPh92XSDhSTg0HxjvOdVSF+Lw0O7+/FtFKOrYEsQpmViuQONwG4ILDJFfaRkXdAiYIdcME xVaJNMDIQUXzziSjHzf5CCuI62HnSxVA3smSb7ixCOHKOsfi95oaP4YM0isTt6EwUOh+a3kJ cWBf7HPh2/nAjq53z47N4/vrOsiSdpAKltvqGwY1pBkVS7Inz47wgV1VZz1CFpRRCKpI6QNJ /zSC3u52IW0ijGVetxjvddKeCiI6ou4l6eaLAhWqY8uf1HBh2g03iJJcoKEnF6UIzLfbETjy A6rqGvwc9S+tD5aXdd7sOCIVSxAxQO6GHwdHcQxCnQkQxG6E0NipbCuBPtEWC93ICYXymtZP 1S0spYhefZNCuenQiw35WshJVLHz/jqVkaZr9wUGF1/rLVL44R0pdD4ezv2TA3VRUEQ+OLPZ 03KrAxWUxROlwLFqxMktSG5EEpaN0r9KWcfR5bFy/Pz7/6PR2gY14fUACb6flq6C/2wY6fl/ MKzA2h/RSSF6ZOXsgKpUO+Dkb4CaIXHirRmJbjw8Iw4HTP1eY7Pe3CF8LXOkYh7xaHTvQGj1 aQ6ShCZDYVaQcf7x/Dnrrxvev/v39RYmbs/Bor7zHhFwz61UY0baj2G0JJr6KUPhiUubmNe7 YN+NlWo60CcRjvEePyewoZLhbMusU7TH65qyXgqyAKV7FFDqOTO19f5o7Fbooc3OlWyNzBcj eUDDGnc1FLz53+Kv2zWHp7RytK+HOaH1/YTw0HhBWHMe3l5QjBhuZLvzd1DRaS4wwmtGyQtE yjdi1tXuR74T8Yhg90MyVAX+sD3vXHxJFXYmtHu8ilmdEENEIt2B3iVsRAl3zOPJBDRRu1LX 81gBJncCefrgjpAbcwRiECYqCPtSdrIIZlDSD4CN7wI4W0WMhGLGgDwRu1wl9+TWIxdSZrby 1bzocdkj7b6vUBPMw5cdo+Zk18jhmGAAStR3GeBS8NTyBhJPL4FUdVZLYYFFBhqXygjOkGCd FiecW5AhQHGfAvJxvxU+wmV/lrmKzQCrhfFcRLKorGo7iXwGybNk13U//Go5YURhB5fpyDu+ WMXekTe41dpIiBzjbE3ef5Xi0trFe+Uo/yubAbkDxQMIy4ZIE8mI4vJ8eaJBA2pgu/PAmKXL 7oreIE9Ghr1JVJzv+xOjBp43wVRbZT6Kxi+FTT5Fbv2wU1DzSV1mBp4pxiXjcEoqMVAlQHNQ K+1a2/9UwD2ctu13U84xvRvvFkZflSxGS1LwwXDTeRyYP0aMqdU5vGWPVpkGvUtKLNeRn9jy 2VeNYHVB7jRa1dUlSezopU5cB6FelSWAY7mzTktj7eyz09TPQ71RZKdTOLRliygQv4hqG6J+ xYUDW0DAnv6dTiDiSKbC5HhWwVxlCSJiE2nDgbYcmpziyyW4Eoo/bc5bkA7SZqI3+yppvNAS iATNVYDCHNQ8PKLefVsxfwN0tSBmjphxywM8Ev0Ti93O/gq+m6SoAAun5q950uf2jfP6kmu/ 5MuHQ8lTef9NSxIzM4+HFbpOY94q06m3WnI0Cg0b49pqUUc0IilRCwM+TJudErpRKnHiEkvh WnWriVZbqWBMDDrFO9F86H2AitiSlyYFxT8+fKeuG6BoNua74k8nebqAb/4nQJdKB9EUQjgh bHFaQY0bvmj33E6VjhTzfUuV5+lKDj/2kxnL2SeNxyTioYU7VSUQGCyQ0EFsobWarMuVA2SF VRmt36oQoXd4Uxfj9xlPIoP8n+pJVWYpFbvnE3wCMA9EiOZLndWffa+PuuhmILM2nTLmPuPx hG1Ne46qWB/f1qNi/IFSJRcfYgzxzh9t4QU3lEX9Bp/bO63FxDhJgizIJxp6cES8FXgZphP9 xnKL9Cx+z4FlWsnIsqTF2MCNDvrcArrreBeXyAEnSllPsSZy7A1/obbBfeAgfx0zw1RDIxwQ wYkVnH5uvEdfg0+Wi3eVw0jiJm7DXqYzB/AlvlrS/vDMb+eNTRYYbQZ4VJbksGStO4Rgmd5W YCTmeGzKfU66/jUj3uKjstvK8ur8pH8oWHoNBWK6rgCboUrE4kal0p0tPAbH/G+xXj86mWJy 59Hry3yNEa4QPAB1K3Mhelkub1MCw+HTKHBdqjD+lkgdUR9Y5c9gmwzZJ5yNyQd0fyQZvxJw 44juo5AVrxbfCDsfImgcPZ2nv8gO5AQS9QBRuUQ8A0LePgvCqNPN2RwPohbVXnjHU5NM0bBS VBl5p7to5KK59ikwRUbAsXxYHyOSq77Ga1feg9cBAq/VO6gDw+MApFqAvzyaq7VOqGRf++5M oPWsYnQRzdtc7bWVJUecTmnVfCozHTIg9bazho97iwJO6JGvYpsZfn+2/EkbbRlQlReNv3XC Tyb62tKbOL8fUa7iHACl2JB6zgRjC3Eq6QZzvaquwfw2Fn1GZZOPWalvCF4rNri481m/BctD CZxRzzK5Aj80tlpodnxr4dWsJnX0WURTbvSGb0vqEhPDQ+RLOtkcg80G4Q7X2EJSubPwT2vC jfwoPCROQKklz3DCuHsSIiDcUGwbmjPz6EX3B/P696MJCRIM3FgL6gl1W/Hkmn/lnijmshEg W1cAXNybqoGfornlx7aCo1EHRxoB1A8KtX3sibr9mSW0O8kFN41oRbFuZTNUrB0etbnhlMir FKna1p2aOsOhdpIM+YzmXSkykZH/XO2QUuDbf0F0lMYFB5XEMoojk/dmhsenA4UDAT6zupj0 ScgMkJSwG0NUx8kgAKg7R/f2sXRMLm7XN/csAz7x9fB3wB/r+wV2j422o0G6Z8FvGWWNdCA6 bKd4e7QVm4kt2GvABfQrAy8mYQAMaiBe1euq2T12haZszSt/JHUtSTlz/rIS0n+XnSHxNTg4 z7QELkTC+wtwyS1QaSVOgmJiVDAQ3p6Df4nIA1uT6eFIQWqu80GsY5MBaua3yRXd1OXnxarS M+ZMmfbqdND0fyfN0KS74rqKgkzzDhjimyGTDMsXnSkNIFejrTFp/fkAHbr94hOI1yIkEUz6 F/g/Uik/n0/PnAz8g98eeAUuUxVM/kVbxsBsD6RHXUIqu6cwGdFbCLZxLqAR/GHYKK+xRuz8 rjMjfn5hRjHnkHQhcjpNuiwiMIwBilzclXL8AC5eYAHJmk6tKel0z0tF8NcM+KrZ2fkY67Jh fFpEPia9wp1t22O3J7D97cKGhYfpCN7bx+qdWm73pJI/hVNLxWyCe5nBmOwC+u5ubE6e2uOS qR5g7Cs2oYBVi60NY7XFlJ4n0Ilh0ROwuPjcdGDflSRsMBiFnwDdagtt/a8C5NoLEf1SKmTs /gfhfoYEsJSwE9GA7MG7JUCsKcjti0XB7Ebs9EGLcXxRqvVTdmIfo9a2+DSQ7bk0pUb/ZCX+ epBX46rJ0fjT7dtoI5mBP5EKQLLME9m+rdMStVFA+XXjYKu7qqe6FJkMdXeXBptt1jN+JMng EOV761NkGuhci1M4UYFqkBfQ6pw1FKnSmO3+p7qiEnxPFAaR/YrIF9ltm0t3A9qrrVWyeLiD zdPYE9Q4viLcx7R+h1jND0I7nKAmqpPaCEOaeZosB3Emqj8ZqwXXR/xYYCPZ8HkbjtDo2+02 v0sCRUtYDh0KAboHuYMYkWYSlCuGTlFTZ+6GC1OoZS1WhdqNBLGHOOtz/n6FqhbVZfZjJMrU ZGvp+urQ7MKQOKJh9051pJ2WWO728MZnJD5u+oZBJcerAQuSFtW4ahEm+1r7x82S6LFXLAdi FPlzRFiS5NLsCTIn8LaYvLERUqjE8w77b13tU1gjFkU1pVpG1nzLpwQ10zwbovSDlHc0OpN2 qgStShhm3KFxn13S//7b+a45Vwdn3CfEfeUuncfcEHfz9wp0rvOovvqktHBHWRc1JZGhfV20 WoHxcg27LId1vPt7o5ddMKoFWBb2XTJiIAFac11fv+Z6i6eNtLxwbv6c7n2EhvQaXLrxQoTx p5GuTY0Cfa3PebLVbLf5gxSLNXh/FJMRM1HIOqCIN8q+ckUJqwfv7vg1kg6FCJClX4o/T99j 39Thf9dOI4qWDvp5tludkUyaym4w5LTixXuG8SfHWiLcgow7l6iHhcZB/ca+2Yh9voAAxdXt qVapM4u4jZZEKIxeWuz91n49dpAg/4FD6+Twi+MQDXmXfLdMHvV1ryIfxtsc29xCs4/aDdss vkdSg6cIPLZKArSJP8aJYrG0pF9m91YGY2R032ku2q1hhJCxvp2ImA6M51tQ9wYbEsbF1I2X aI6BtxbSx49lu8f0V2BOB/t1gj8NL2vcNGmqKtAOkJIxo1ZgyAWDRdwUx9MzxoqnDmjTsRRW x9kGUtXKqxIHsZlJuk4RjQ/MJ3zF8pLd/JuD/SjCbV3065KhVQXyHS7Ra8V2xoABQfApJUh4 iLbDFeQYvcDx8Z+bYcA1XZuNYl2QuDF8FWanmhFgMvdkEk8NC1GmPG/FoVEsT0i8D0Qj/sON BZQRs9zNxs7ptrK+VmAlFqROEir6aQ45hQSAo9teGkXk+cDtW/U5O5/OxC8Mc6qQScJmHf2Q 4eF5WT+f916/n5yS0gf+EXF8pbw+smsZ+R4bg+/VDGtv9lWxIMOme8qsXDk4g62NFKi+fpNG xJjbm4Ae98R2IAwlonsbmDqSlAcM+fw4la3wISvGGYYSo+2382Z4YTLK8oen+o9dNv7n6M8X r+nLbDBPhe1WcaNNZ7/Rf9LMYf/2WD/gmGgJoh3GnmuIOHSo08W4g4J1qQNjIpv6ePhjhe6Y jnZ5/nZNexZ//Q9imyE40AoYAEOFe63OLPxxc0pEIXYXr86+WmbBWjshf/S8MEZnfZlm9Ni+ 7+Vauqg90QaRmvwYmiszOoxhCye5Hk2W/l8kjo1rXdBgR9kW3GHoTHNCVMvajl/oP4Re4XAl d3xLPzBTdT6u14A2yyKoM0LTY8XlggurClVSkExRfWufjUA0JIbGClJ5A9AJTIIEQiCZ/nZO vu76rfQLqBeA8nrO57bWa+N9iJPJfrQGYZUTQQB7WjgkwWl+32JTQbuaQFDEqdYWxXcPGaPW GN3HdmKtxBjnN/q3moA77I3GEvSzHPDOKj2K+0qY4rEF6xt46GhhvfAxETwHkliib5fJT7iL 2sroVN7rir3/7p+8K7gns17T03rR0odAK37ODSQ8M7ZjXgUWPZ2l19Q9arETmMFpSOjqNrie vAXpea22geFSRLNvq/XSqVHlppPVSOj3KEXwlf4Rm+BaswWTqzHZvEw7FgvsF4xwkKxG9msK d3XBVampHrc1K/OA8alHAAJn5wFuXtkE/tYnzk3QbKhsggME7BUuWEeFbiSqfxjxKzbCf/Ur dksNYxfOztnDMGpGTvkUmnZlsEwXA/0o8K7yxzOpECOe/CGmW9Rg3T4CAtSqhntT9/ZqxLFD gHJdj9XozejAuLKiXHkdUObmlo+J/TxbphAH6J9XFw+CTt8Pqpb+g49X0yJ74ggGPNUg2c0L HznIz2btiZdGvgRJ89V3BT7rKbonVVLqj75kN0Cj7iL3O4xLYJzq/XdE35lRejWn6XF8lWy/ +i/G+o2uzuMePYiT6zMF/H3SeF+Qut/CSkE8wraWBAQHmVAEM3G/JwaoFGbXr7qImCvRfZWo /9t+K5bV7oj0MKh1BtNZAzJTiphHCFXnDaBfVrsFD2tLl0TWXNUulhHQEFEsrwoP6aMHUR0z Npl0XxTvz/85bxUKq3gF16bZfd+XV7d7LWYw1OAT+RCKTm5zFWTd3D4chUPUY/3BZaXgDyH5 sonKAZna6hz5xjjOxlr+DuhbOMxRHDzHfHxNGJVqnBuImzuxamhn65AHrTLqExt5bvGJh3vu cXceYjkkHigrNhpBTX945F6X6+zKxNLSb1vxgmydVpPq4Bcl5hSlbkCXrgRuQE2fvfi6pk+J lekSugdv4ftabJ3ZBZ6QAVxqDYmUiKrbt2e0ODvmPFYNvu1I9xFFSFDPCuzRcx0CPO7/owL9 /aTnys60Pta2DCdfqoHBvLRMzbACQF5bkH3uanzLfEoeoYrXzJ6B+/E1Zl1TVGa/vI0yCU8B 2RkN3lzRdgk6BNQluZT/XvIGZVLKIpuEJIRtXQIL1oXaPwv3koHpJ3QkotftYiufSkL9HQ/h TpxgxreqkVOLPDQJ8EuoOKoUyOth3rkmAK27GISP6NHHcH5RHbmRkWT3LUCdo5WMN/+hnmdn w6iXVFA65SXbxX5XE6b3NoeBuZ5lm5rHU9Iftam/DwoVsfPeJ2iultEZqSqZLZVxiKE8G16M Gm7vesKgsFr+lz5wFHAiaWjl6PjCUEBw3cCr0dYnPkPXuk1nDf1SCfjaurMg6VIBT/i2tgzp eXu0Knq24DfX4sNIL75Gtg+HHSLlzqF9sqhi4j0Aga31NKpdbY+/HoNp0t9LM1zF6Hapn4yD KkkB7CLLpfihxI73Ay/FnrrzGcuYf603DGXLL19YGIeGE5K7cdAZVB0FSQeiIdUoLnf5AEbI 4umgbU0rHkDUVcrnyLsFOHQ5BNOiCa9FMpHVmttjLLzWD6hMYY44NBWr1/xRbMHI3vMW8Taz 9MA44C6fg0J4J34p44Terf1RecMkZHX1cAQVUnm8E7Pw9M4gSFFXACCwuoozrXrG0Rf281cM aCnqiBVWsPNFUOCguvF/AysN7HsXYUlyf4bkDiRazsCuA5gdCtjiFa0qNVKReiQ/SUtBV6Fo PyXW2qJRywnmeNh/EHmkkkg3rFeJjoWpMeM0Oxzqka2lezoeAcLgZfdICxnpAaHeWSZQmLht D4dmJyhj/JXSkrhDeTaObDoe+bUnzYlHi/qpZen4JAwC85FANHTo/6FYjhL8NKVkniovYA5C 3EEks0hVKNAZ69yvcH+zOrQhH5LnWjVObL8T8qiqKeNWV4MDCaKhdniS5lihcgegSWvsKXC/ 5RJ0MP5f1HkV1bY6fzhf3Q1xtfetgfDshxROwWrQCOaPK9yVG/pHVoNsVwd542FvMbCoi5I+ jwvqGPDaiqko7R0u7fpTvjCqXeNZL0sWx47lvuuAOy8ztQL4E8DwB+FEvOKcLqYwRPLwjbc4 yPsb1jdzKgLmMn7fxBCM1YqLXjsxAGNJH01MSvw11AkXV9NbsmUm2GBNft8Waz7k3yK+9v+w BN98uF/sOfUIohqc7LlbaMrDcLWqut4jEDtS5vvUUmtMuPRaan4Zpp1ZedKuCCWJk1ZDs6GT rUcOyVtZG0DlbupB4mwoxZojRY3jhIHxxt0QfwZljap/bdJaUfuMFWSvxLhbxelC3394WdXK EKKExwd9mdIXUWhg1FrwDaS/T7ClcBwkot1gMdMTofAcXTNee/iRbFLDqYoqvW7Dw+QfzHgR ecUfdyY8roD/DSIhmPtXmKPjRnrMjvC4jlqQYsiDAbtcHKvT7A2pp4MYTZ56q9sUfRDor06x 4gsbZdMPqUcHme5r2A/dvJJ35lbHb2TYXuiCDmMYRK9Tn1sccCQjtM3krzSkuqrgdy7/FP88 hgLdsWPrEQY+Pqf1Ray939nFzZE8Mke1vzRiMr9kUjNW7DecvX5L/u1Fz7FIa+SBHTRAAQKG XLXdmzBlWChJ76hRhjxnxBQlPTN04vujoQsJdKvJL0nbFTKAs7SxzLJefN5iU2bKYAVNzHjY gbNzb7+hnsYrpC7BRoz804wVyHO4kUPP/NnFdpNtOxsnJ4svUNPVsWdeAwrLUMqAALW4IFpp ZTC5vxQhWZ2XL5mPXn//ANasGUcGo6Hz7HvVInGx5bZiT5HWMEdTiw/Nq1UtYH4+BhIgRwea arAt3ZJpOOsyvrMQVoT2RP4G76dvuD8hy1llsj9WBCpXrVISZ17643iiaaS2VFg+qLvmDYH5 VGcS5VScmc2or06vGNPkgBbf4Hd/cLEB9ESGwJDOX6QXRIQZSlLB+l47FkOoEalECsV6Q3xv xrzRKPFXth+cFZ03ZOWQzSX1+lQL9VyGLEFKYLKxa9dYxrUtMHdcKjdKM1GQJRRghtYpZFr7 PZmMZ//QbTJqLUH4SgzdwjjM+eBHFNP5U3a97iYBoSGOMOFdGMMG94ar+h+cvleoBmZC9uWT pc3Fwv3s3n+R/aahFSn349v/emFrwxLZzomB6PdfeNzFsHydIE+6wzx/ifLF/zICRpSkQnkN OW12LCIL96/YHFTI7kWo1dSVuhbVuoDnKJYiFfxdMEubx6YcXxu+2XAQtvZrmZ5m3rmBB1HY kcoOaMi60Wrqa/0H/erLiflpBsEzW+Wmi+6ZNmnOVOjHUaGhQDiLwn5Gn0VVluFwvGoAUyR9 qIXbNsUxqpyvRzOXy7mmeBlGAbKf2j82Wn51ZBzdo30yhTFfFfiFjKyz0jPUnvW4E9fgNpNi QdLKJy8d1uZ7QW2bwnewDS5AhpnrwISWLf1P8NuLQr9FYZyA5ytuyDgAfYF5djyHcsCuCWLm +M6NSV5RWhdxY6zwKsacZrfyNdQYKblCnspoQ85KGXrpkrCXNSMxlKN6dpQZ5ENszZTsdSmb GA7Zv+Lk6MkWIeDzHeoBX1qJx+4BfW83H//hcwiZZlAR77cgVXZCLCQYZwds0wypVkyi+JoB YZxxCGEPzUv4JE/dExBpyqHfc1YXV0rEsj7Lvefz1IJn8ppa25D8/MqZKPiDJ8fP3TWTLUy/ aWbwXULgC/+es+R+AiC1Ygv1LdWNJ9cScNaCe+sxLqmUythYHpKugCNlvwpsL7i5HhYtFDi4 RkEV3imNzvy6MCdjLaMLaw4ZG8G7uIPI6aDBryzoSIOfNykyxsbCCTsR6SY4dSVNyJcpJFuE xxxRZIA93VI741MuzLT6tYnSBRma+D9vEISoEQgI0G2ZeOUiQP6c2kz96npcaQpGMoGOUlfs bvfa8gbzxbG9KOH6kyghb+1y1CMpdLrnD5NfwUXRCFC8tjoQkR1lWswvnOkBerlDQ+08rgM5 14SWIyQJice3IzMWZFYvQnX1Jpvwiqeu/1sv8X8nPYu5JRw0jlOVmlPyQdKEvxV4CaPbii0L S2uQgP+P6rQyVhKK6DqF4ncVCdGrE9kRROtGyqdbq1fdosQ4ksP7xLPA3PBAthZaY4DIvIjX Wlm3mnwVeorUXFMzLF070fSnPaFllQlddniAd6NWrao9AEg99pVUEyO9lccVnzfdj2Lz77yv XbjvMTUbVVffTyxo1rXhsehbSlhY4srNBFJszyYPP/4/7yVm+HdJvnpV1v2rNAIvwf1fQNaF V8weeZQcYYorcEbdDXUQcgf3uN00dvsWgIKCH9IeyiGTsCmhY/H0+F7epY7OQg3/c4jEtuAI Y5EzTXeMroPqCz4RoATNx0dsv1S14TuKYInhjT7Fha2ZHejIQAi+IImZyKepecPhzVkMd+OM ZFcOJqdvs9Digb2dCLcsp04ip60EY8ZeOO5rmt74scDmt5H0vQz1I773HuCGWc0AVaTFV2M7 E0gHs0MR+R1+jfJEItNGFyS0t7N3BbLxhtVlCU2Y5pmReQCW9evLmE/XLl0Ym6s5qtpZIiIx 4QgO1SVrfCa1dNLGu4H4poYJCI3MAwfK3s/N1EwSI0QOT1JhnKbphwocABBSCzmwm/N3wKNa 8ntWL1EM5hRvFPfqwuEEbpDx9eXmVnOA4SCmvmNvTz+afVruz/Yw3ICCxvw7f+1NT5i8rOOB m3jbQvBV4/m5VMhkFw3yb8gUHt3eaPJZ/168Zkm8pZiDHm4aKJJ9UCYfx3sWIHcL2dipPEVg 5rD2AQXXX+qIAUZDrye0PDiwCU5bb+qUHuFxZe+leTj368oEt8DbvgSxB9R2WkXl5fPBKsim lF2oSlqRddVvc28ccSRxPDLbg8JCyPbgzcGKPJQutUmGLuhuPA34xZOlDF9os4+Lg2roFqz1 8xI9Clpfg+7pitvE7WwuI+xToU/6yJ9/me2DJP/18DMP1RzkRiFUrUsVQSyR9nQh4JZrjI84 399X2ukEnwwLFOJQGpZfhg7rpWuORe2aRWrg1IssS72MSMtu4s5RWw3Y/MfMvAxBqtgFC3E0 UR8Kh6oIaW9qjeDeN1PQ0hqghzdhLsH4bHUkicmI9LFGdBAWfsBZFK1/WXm0IBlcsQFFNmJk n6zd20GEResA2Wc0Qg4b+Irjt1CLCEjzOb6z5BJS1j3VEU0tSjz0csiQy1kE2MBA2z6gl+W+ VjJ8YHj2SrYKcdzLlp/uQyuM2BRGUwP9E1zFr7d8dUOgxl6D0cs1KL+8wPZtone5N/hVccsG YB7J1fKbm8jUbViPeO6ayTjKRYN08qkvbIY1kY5iASBBw1nJC+6ODdkpXXPOqPTF+X0vpDI0 ECKUR1AOHQpOK5lTY6W2PU2Eik+Gis3wBHKA9T5ZNL9dPbBNnX1l5+PtuJ6haaAWg99H57zn ehY31RNfeLrySrx1rR59r2L3uh29G2Xy1dSQHSqeO75l4nXisI9ewCDkTf5FJ1piQLAKDy3R FrDCeN5xwyDAxmjr0Fl8YnZ5XlIzeuLzXq0xVLiqhBnHBoz2IVvxLayJ9tiLS85FhkbbS+IY Ykp3UImh+Ule/CQf1H8AZ9wDFCNnkawc7Ou8R1K9IJuP9soB7j6q+c9U9cPT0RsfyZAFhqx+ +sF174uLkUoD4Xrx1hV/aYNlhEOZ6f7fFOdX9UCrWPitMSL/S6Xx5khFDEP5YS4bTH0DV8kJ 0Ac4vDvowo/CzpVA58jqobpy/D1+hPqyYpJ7k9yEgSlG2jmFhEHOo7YCxA4676dNk3Y1rMxs EFEIYo2FjKiYVOnN/i4lp4+3XAw+W0tWvCdlpaRF/Z8RCD+H0SvpCwZ92dWTfP79gzQBfRkv ScNrpHGIp8+IANGpg9wjeIvShc+tkObtiIdRq0E4AitE4CMu+gbvK0KCUKQChLp/p7eNw0SX QXKDRZ79mYP0cEjxwveOUGK8+pW2mywklLKa9wF1DI8kg4jtU4owm9fucTH7bJSKXOoxBz9v dqBjDyDaPPU1z+2DGsUS+6bVgwFzqNKVPIehMR5wDIqVxlmJyS9BV97fAubwiZ1wZvuedi2V Kr61pdWBrjc1PpA6TmeoLv/++Ks9AuB+Enacm1PQwp0kx+QpZOhZGIXMjnrijfPTUeZrr6xh VFcRAn5TL2kaVTKhMu0CJfRzBgz05oVQWlQHWB+/SoCl4emzW1UFyhIfDIuyEP99ohqTBR5e guOVgZmGOfTQxJk+1uo4B7jWr1OpXjFf3egmO1TziBrVZjxATVyNVXVR60HnkicTdNzj2RdT Qv+HbIwI/tlGb7FN8vP/LRos8goXewpnhWKJ7AcuerTEnwy9mhhoMH3/XyWCB/xjV6HSW/3U I5NV8UDoe7uDuaHEjMz05IceIJcMHEAI5r7okEu80TVbdPsTdkzEEMOyBtd0KtmvybXEnsA3 1skEC0Ncw0VxEIWF77HTiWetPLcETZH9jq9QZOJBextp3WkaoZG/IPcL0tszklXvnydS/mEm 2F4InKTed36gWlw89UonEVpZV3Kq4/Zm9QbGJTHTLaqZfl6KpHQdFetaiDau7oo3MCcOF3UR l/Bp354hrbaeR1KU5zyztRszbRogeV6nAgQBxIT1kS2ENeO1yNgfCQXTekQVN6MVLx/KjSE0 cwiZasVzVxJ2HMVRa0x8B2sT0V6FKEytJmKMnAlphOmrifFfzcIer+VOuOdKIzd8E62qEvq9 HGKhY9kl7263uY2HC15I9jDiw2pcFvcfgWWfROappu0Y68eBG6E5NPufbdDiPw2q8XPjtZux 4dzqCGQqXprayJQIsh6uu5dX2pvhYHZXGC+vyeaG6FI4OatjnIXAiZ4U4a9474d0NUokCxOx H04M7sq1k7/b9fec5ev3WhK3ZIu9Np9RGof1XKstkAufwDLt9StnPBJIHFtOvfcR1dnmXlGd YazInPr6TETLDVzKp8GG6QIYAi8qq+FqORZU7vSARxv4Nx2XcVr688Cj7aImouIm7t/NAWcx LWUPgcKvH839RNPz1UgVGqcGmH4vFtjbOU6DP3aLFrv44vYeHIu65PQ1ING3kAeSRoCD40bq l//lUBmR3jQUVhgSFOyWwMCgVIz9EZCWew3hOZcL7NwLdxGz7KAtWpVUc+DJymzxg5t0aO5s MMJWuPao7xgmuazD6rptQcKs0HY48l3tKIeyu240Lz5N6rmlXbju92okxu3M+5ZQmfnfoU+A 5vhAyimKyXbihJwX+w79sGwJUzP+albBsLsciKvkVYmUMa5Xndg8zg45HMZWGWosgzUnh5Wu Fg+x5un7mDXMlDh9ekQz6JI/dxn6A2Hvxcl1n5KxiNmbYDjb//WzOOwhbVHj/UUzKJJYNdhS GPy61lGybxUo9fxZF2eHyCpAwuKU9Sxi3pGW+2+kdVTiP+Mc60nlZpDohK4ZxC+Qj0PCLksA RtDrAv6OwUVSzY9HK509m7HC7SFkGV3jrP2ZzLxWGAE6xCy6lrFGPr8Cd8WVNbrBYub0C4Hg mIoj4FymRELpWV8jD0vW48MMh/m5KlHtI9twKdCnwggNf1t/gFa2g+U9RE+uH2FWfZgprGuI SywIYpdB9z1R1IQU+DtoQebnC1SVL8gf/m31JtoWqmtQzJ45oFkf8PBXBXYGQsVGde5444FW 734uCOB/rqbqgjmCX1YCNAeUcW8LPgnQuoRz8KfO7DLYEKZLoy/vhrgUOmi55mrOA4D7byd5 v4ygLeLRCaK2Ezhw3klceNxVs0uZjGIrfEkE0sNPLc3PBiySEUk+myl0vFWuCLBwCDXWYLQo 3aeFNqAkDr2jKE+PVi5Ca6UONo2uUkCdRHDrv6G3hvJ/lkEq8SkmKvda/QQA7cl1dgBImS/E dobUSCoU5joODkx8E1hIzFx/a30KRadTNQ7IAGBZtkdPKlMCvaMBZ+qoPCMcOBTRlaNLd01F ujVPKbbAjYJOlnP3LwWZ1bjOr1T3sLlHolpTe+gtYv8iVtnd3XlNCxz2fQzEtNw1cEfhs4uZ z8W9goYm8xyGi60tw6UR4ctVMgLQuAt5eSn6oYoZd5smq4torsbqFKccOyZD3DTyHlC7fpRC w14Uwwbt7oxs5EYHpdIe21oRjdYlviXZvV6qGPCMyak3TKuWyDEwfbTZ3MZ5KtJbI5zrm6UX DS7OmLtvZw3PYZfYKqgrjelSfeJGPG5RFIV8qszu9WA1afmoBxe/UUhzL0paEBMxKkghQsbA fYnMwvcmv0NXBsrkItKrP562orPiW1w0O+TPoVBEeoy4Habz2S3TGsGf3q9X8hIkFmJDQVYo hDNoA8qwsWyspHAQje8kllAybUXXkixgsk/2yjbCWKyCFM6/3ORNkKu6eflsi5rubjjpQEvr UA/kDrdNOYEOQuJkevHIsuA/rQzVp+mQB+j7o48pXASsjj4S4N98pf1aKcWMbjUktA2k0rba BaRmlvFfdav/GPbRdciqrIM9hKEAAcou4I3x2uOk4GizY2ByVJr/FhXkAcwitL3QMfGiwpo2 LzRanKmjqtKYa3w3NCYxrE3jgSIaDjECcsUJrprAIkaUPbFmhlnnxKyzvWxoUS7pZEjmKpl4 QC511TxyVjmHisviHoyugqKXCWoLWrpuTZc9Ns8garX0vV3snzJaa3LyPP3GUImjjR1qql3G 8dngGQ8jaIgM9CtsTHFi2SX0RP61Dj6+n/hFhxb+CPQPePQrB8d4PvC40rlNHIBeg3lKMjBW BspwCHnU7umCzAnBD7qFOMOL8836DjKXw+BvuJ9riWGQyziamOE1Yvii7zvQPqYw2JOxDCGG RCFEiHFi0J0NVablqa1YnkzdIFj7pYYbQbP1rMlcLU4Qn1iNf7thNgpK4JIZ0nuNqXsnBffd TqdLPL9a01jwCQ7cVIpwbXMc7/6M40HiF6dCVVEV2QNTwiPsZTBrDUKEuRwc/OHXG67pjbXX 7JFdcDKeu5hbzX3m2IvY7Sfx/Mdu4EBd5HS7CNRkDKUWyfp0ELPqcLOTwyUT6LrcZtVF7Ikv cG6PF5wS2fmUq4BAqWSycegkXtsz794ThlsVBzZ3sHhKIpi4tB0gFOgDM7O6vrgEtIg/2k1o IkMAkXVuKy33LNXjmx+41NVNq60jkXNkHFnlb4PmpfLTVLEOFMHVSzKsEKiCmH1GiJDDhWsB 7EHzOik0gl+6ncaxyCTh65HnTdP1XpvVPeBSrpLfy2tDuq5M+D2R4nCU/IIgqTCM3S/tsVK0 EC7sc0zaRFADC3kBoZK/Owj8CnLmo7QlrYqFqoR2mRGMd5Ia/6wQfzKZ8wvM2MIxBGCD0ipA IDUk/hxfR6fJsqhZ3UoLB2bETQj23YcCBUXKbdX2UFsHBimjjCT57pFOq/AlaGyYb198ty4E pJJpTyrd+4mZB1ZMS+yZ15t8TMomZtDVMxkFZ7zz9a6RvtJ752L/t9HWni9PsyUgc3u/g9VL rix/DDkFrh6FRXwKcS4rDAEj6HxeyHH7OUaOKxr9eiRKBPyxw7RgMJxL4rt4y5nBjeU81dHn Qsn28eaj9IXEsB1aqTnFRxxo0Aj1B6DoU/YJ5Kt5xiXL+HRmrdFWOZvq8wOXfZiItYqCTNV1 6Nsur+IhweWNdqxglLqepp9meHXtrqP8bIogJDGqwNYz+FuQzoBb6RXorzFUpGmqW0duk/yw empW0poHJnmZ39CHdW1HSj69CaD6YHI42Q+62/T0rkx/cEy0ACYQnthtyKdE78t3NZoRXAGg fTqSXzQ5VWYDG3450LeLiAnuuZAVUOvD9EfX7VctQsIf+uuk5p4lOkiLagMrTBK5ZOZk6H3b TBBx0DONUj++Ml/7sOn1KnMugdGJE3bJAJ7wcc6REa2rHKOXr2lF/m6FrlB/Z9c9oVXa+HZ9 n9SIDcnSFAWOmcvWpmhjZ2PyoFVBDKddxthzCLgj8jK4saKaHPZWdkoRqV9a4s2snl9ht4kV yEfBD8s9+JWAUEmeBZjMRXdBxCuS8T6tQm8xxJz9Pdn+670vXS2d0I99joaG3sH7uOn+SBGG 1M23ASX62cqy5A218mK7ZEjvcVkgYEJKIExuocKr5G8WSdiRV+rIvRoIlBPXyjmPE6Tg6u4y JfkQAOi37PKQHYnRlWsujFCKD92lp7oOsiBTnjSUujNAd0zNQf0LoPlPFt1y4V4uNORd0ZIV YHzaR+sJIJRLGfKMk38/ANbkSHW5s2g5+K4M2LWxf+NvbJ2OY6wP5RPH2ExK6igWU5/X3+qw e2/vn6qsorNfHFwpOWWum1bHDelKX6W3U2aswhPx7NruUKbWeFbhKJ8yZo4n5E54WYlNf4zH bDFfTmpLq9AJ7lwIJ2FfLz599fOeaEcsw/8+rulQ7Dc4nP+Ulo0UbnzG/7mVjaciqMzKRJ20 TrWQFbCWNWqY1HuK7KdXFZffacR4Xnn20Q+uYNeaB3ulHrEQZdaxnN/+pZl6nezWo9SDaF6n EujSr5JjddIHbIqggJ46hLxNlXaR1xMRB8eaNKyPq8wJnvUrB29IK6ZguEtqRkZyZjsB7cSG WuGeKz8BKS9JDDWUOVXLRdZQzHAkWh2draJU0l1uoYuEpAEHvGu2Fwbwy6NnOy3xa77qSRL0 UvMo7f8kxHLPWUrf0ANiSEs1MssmBFanHeia5JmkKz6B+7ZXoqeVPS0jnhZuof6taoV2PyZE qfuoUiGRbaSlALb+ARr9KNo/wYGWzRMxHp5mTGjhxcLrO1yobG4N58iaEEjpNs6ah/zM6ZJy wNAeUMel7+C+rXqObGA9qZcYRb09CoE8kCN3IHr7Lde79BPA7u2zDBEj/E78XIUuc3Jsa6u2 HzUbQ3nca5LMl+JlRsxx94Xa8C88HUoX4YGaGtnF/CwY3sdphPeZT4y5LuTdKFnHnzK9OWkx mq8uDnkSkld5zCBh3pCjEkwJoedyE2R1PJdJ1wL2g4q4bKRKbrzCABrQpFYz8OaCynuIEKxW PsoDoTkJTxTATI6rCRxOEIZMsOCzx5564WOa7enVIrlAGtMRfSbBzrO57XQpL4IkLp7uiBzz ZdKOdbyJLevRhDBWumWOk6ikaksDqIxHQ1/MlHIMWmk03p0YIllHgirc8jBUbWbK5hKoh1MB Kha1tY5K/GiaDrboYYWyZWAM/WowUmqGOBzgPS6kE/SupFiDwqSr9Yi56rbKeq5LI0m3OZPY UgnY2B0gqHNvQ9RTWzEc6oHK+vl0BAhp4x0tXOmrCnIsxmjLAfeZbwSaJuxUcahXvAdhAyGM DnAdXb0pO45MS/BhBjnA5dsPKmyaZ3ITQIQGVthyy2OflqE+oFU4bykX66Rajy9A0FmzV+gE YrWPBKQ51VtiDKoqFYEGLf37hd3dluuIdoc3dL4L3jKESs4OJ9YNkHeOqpFW/SWl3cZOcRsL Jtgpe+BADO2JWZav1oT0Rq7l7mY5Qoxa4FCZIYX7JJlG0BxSteGtewjDa21uHDXn33xle6r8 YCAIWarVzB/j4DPRKdqc7ICSmF/Urxt7ashvvxiQtQWwXp/6rGzkdAECNbt2YmJWC8U6SIFq VCMr2MbgnOfwapBHrH5QlSFSgJoxqO/QDMZH6KNyhDFGFPXBnhmjvEOjF8S01NP0GFMBGW4V UTD/NuLEL+z/RZoTFGQ/ucx+qELO+38XEpIypImMDldZamacJHeDf5lgL/z7uvXcuS+TQPfA 6AcXpt7+jC6Pr3l1wkcSnpflJza9jkdtsb/TVGF+rlQAn0rJacxFgCYCQUZ5k2LpnX1IoSxk /kQXKrqMQl1aUULZN2rWpbmU6xCd0nXYRPLCL6foj8JWYYDkOQdVEh9SOHQh+bBDhQFgFJU0 qjW1y0L42ZRuagW7LqB6cJa2a1cg/lfXkFGq2xTERwQqNj8EQVzKF2Kwbktu/Hq4Bnepqs7o mS8j7aJv5g11DSXRA8YcBD7SksAOtW7Z5XZnRI6zpFkrTI9ul2Pqh+++O3buscwo9W2/VLR+ FxMJhh94ekDxTCsTawYnCZwTsVFA3GlwG9QIBLZ/8erWd8UKOAh1gxfnuTSD48z/8w30aJoz FBL3MqQdEl6QBbrEwkQLTwXEY3fEv++7o+27HTV7qMEijIE6tK5sCf4EC/6Bqgztnl3A0AGW JaRJtDBfzh1b8tdB8Zj4VcUM+oT/AzOzy3N/ioQDr8NkaTERMxa7xJKPzUI/IhbsbEbtlMG8 mNbiXloo/rtynQs0H99vTxzRcXYJvUOY48MsIJl8VyS3vdnw2hclrjwRWBOskBPit1pmJo1A e9i+r6aFWwtKVS198lZx2vnj69ddtz6CZW/A+288WpVtU4SOWa1B7eFLu5qvjI/jxi77ULYC jF849xl6QetGIRRebAaac8cYU4HK0Kqv9SmPPLb/6lkKUQMSB/mCQ8mP6/8j9RJek1h3VJeB dm0WclrqdWL5HAWoi11MZd86sjwfVmmcGwpaCLuAFzUXn+cVADo2zluACO4v8W7E0j9iNO2S ewN9lyoZZjQ/29YjAB85gn951uY9IYUFMFjL5Y1PhZE4Sknc+zKyfAwAEQxUHj1Ek7/Cmf9d /PjS7SqWtVZAW41Xk9GSmB5vz0pHvfSa72nVgHFDKRttgSvBnxng1jN+FX2+T0HQmupNMrAS +StPZ0Ff96LgMG8XzAHJLm6ea2iggKAzkkQnuL4UPlkrTQbixFAvh5l0TICGiisLD//pmez8 iy6+JBBo5VIeou9uVm8OFxM4y8Nvh7DKNn7jPzRWk5wqDv66GZjn9fZS138q4ZN2TqTmHXDb 6Grb0r1bsZHUnSO+hsiD48rUIyEZrsEU5Lui5YfGQFFhyr7nOXV+cpKlrbJall1xEn8m+2JU YYlqks/uNE88AtaJa8PVbrNNqHJeqC3oSx/b1J96ORmE4UOOSIsbEbJ7lwQhi+cJ7UHwjUuG ef3xjjL7RH7sNYLUsdveC7LlU1hQ0ulMNk/mEJGuOh59eO/HpR3htmSaNMNDk5C+QLgsUWIA ZorDKUsa90PNvN6hr3t3EEw7rXgEWgCKOHOYipz3yXM8GhGL0DAWajapbQJ7bQ/FdKxkOYJZ F/EuQ8OvXIMIleit4puAsN4bhj8Hb/3VNoIYkmeKl7HGibq687mGHi1pAglpJaDaH4/bQmIW 6hMrGbYrLnPkzskfxZO2+ByS7gHV2ZPKKO/A+dNmFJNZUeSMt4QtOgjUeAG2RbcD8pdiCiX8 BtEtUs9Yojg7Z2ji3OAmAZqVPpTh1l2P0WtZwCT8WdcOp+nny1HDITawnj8HDdoKwcRAuT2Z du7Y8ilYse30Nf1z+wyrEucGeHF18VSRt0Ec5qvqrFzbMOhsCuZoIAR9HevytnU4F6tALoLm sGJUiREuUsKG973uVwb4c7nnj+0O5zZePjA95lrGXe9bEm8fei2DhY2UnUcId5DEgCf6BpUg Lsy4vTtDylCmA9MocLoFr2hdJcdb1a+W3raTfeuPj8Z/qWlMPOtKSGXCjb6/msReDfbng1+w nHBA1VI7OzxH+XGCV9KeEFnYjtLCMYpLp5kTwQQvUQI1t4d14hMDacR/+H4DNU8fHNM+3SwW k2yWeOrpZPYOAwStBwYdG3vbhN2HMiqgMBn0uYPd01PfTL+46A0zidiM+0yOETsd0D19YImq zV/0QJVI4wagNoroWgmKK38T1EejgLAGuUMojymvAU3dviaNN05aRbnzSYd7nVhh//6kWh42 SKI/cH6LetFpp/p2WIfZL/ww1v3vvobVmS4AKZk9CutwfWATbe1JPU1iYCRSAvzmY+uEAoR5 cpeIztBl83BV1c3QY27bK/jHKPEHdKqcZ5+iVacQGefWGRK7dYHpNfp06xype98YSR6F0glI MVS9pkrX+qJ+GVicBehGJC9ubz97eykXxM7I6M6BSHvLi2nZsg2+Uju4SG2iekQir8CdeZmX P77270dV6zOS9FqV+wAwYq0ovU0QOIepfJkxw22jl2Eua0dZ2QcjRYXRNRwV3jxrdW3tBccI fVJJrBJY7Ws27uWgRU8/mc+ThUHaP9vdyMgZLRZcxXfAfSVJNWS81Y36C6SYumzZx83CMTGO mxyg3k02auvghm/z4qFfZMtplyqUDcwy7dAXF9Apvd99MXkY4V4l3yC2JyPrtQqBaLhPriL2 Pn3lof+13GO0hEMFw6Wz0uMA8MSq9JPjHGwQkVssuTH4uzmbE3SfrnvNA7V+Rv66tDQI0tZC Rh8ksPfzX6S/ilQjd5utqOdoVwWCltxkPaRjGx6SggdDohT27kMDbkfrWIfkq7DvZmJ7Jwgz TKmnFLVMcyljM1nPVVpthTLaa6OBzC1zEJ1TTKoFB0XFYrkEdhPoELWjuKOefoOEcWpXf3hx qkemmxN5Ixb+yPgYGIUccuc7rX7F4sMblzsYmO+adKig/Unt0v02oU5XZC3AafOzAMUGv/zV +XRI/F3p+w3BwHZIyke3zqzoJubPAIAViHfX3kE3zusuxC4NcVXtGkuLh0f7mXACwan7MVpI mHw9G3zerv6PZjqM8fdv6v15RPgVogRZQhjFfFfLSx3Zbyxz0+zzRnTTOdjKIAjhYLBf/a5x vdjCOMe+lrr1Ew+LEKVLa54ocWC0dVMPVPVKFkJILqt2yVEo4kTzCW0Oq/u7qRjPzSj3cYvA 7Tjmxf7xGbblIx8z9AWKBuI1tOQ4GlpqHN8izaj+skkVnTzsHGXBnxv4QUf7pnk+/Ov5vxc1 w7iNdmyF6zzaMD5XPBSUGPHrFqXsC8y99wNG6rSpzLoWVrpnjd2PXZwjx6J2bVFFr4qPS17Z oc1Eju3CJG0LLrzY54nfP1elgQel2lQKOvWfnmcj6Vv42xCQtv5j/PYHbzDgn/ncDZZEED3r U+QOzjFrIXuaHMWSUm/KO/qvryFCSF08QJy8qThJPyjZDv35r2V64+zkaA08tgH4aB13zlGV /seFWlwQRHPNVaeh8qI1nlvutclRe83MgsDRM+lg7t6kzRyUDxeWfKoX3rtMjliC48Y0yP/Y 7MF8wTOPXqixAHgBtqVWPpuOHdEZmoqTsf3IGAfhG9JMo96II9LQKMjNaR9klZAVqZekIvml 8Uq0yAZYQDdGSCNDDgdoS1Lg5OFlEL1VcDQSCKGGH0wqw2+bu4U+s8WoFoMfWlIe5psOz5ET omafad5QChzgJQ8cuRy8UpKNUgIj0Zc5ELN2y0wkHYB5sb9B5d67wwDB5rU+NfFGlQhT7twB XaeT9t6MWHbZhliZbnTi4ciCsSRBQ9KfnXaMnhEUBfsIoTm46mTe0iG2U/e/rT0/xj1OVDVR jPHXnUpUh56am3i7pGPUF7xrJJ1C+u3jJ51VrfMPRjlH7wXzGrLWOgMvMBa/g94Dstsk/Tqy 3GtP5UF4IbBzzfilAeB91pF/V7Ybw3QkpfYsiNTb2UY4FUCYd12BOtX2ZvRJkKiiKP5KxLMy C4RcypYUNOwFMMEzz8VRgeP97tk9fZhBMJ0gHAr3ZtjPknU4x+YUtG89/kkPdjolHAvJfhmH ZEAkhPhkQGx/57UWLGgxg56WFk8O99gg2cy3zIG9SyE0joMUV/MYVWg6m1YMSFZzqtkT0//v oOcCzzlZ3FcFEq+wVeTiu8zHbOgV629+Bvgldm5rxnkv3oJKIjS9To/267klCnX/5ZzPBCGP lfVAJllWgYBgDRf39BNDvxdhtDWn8Jl5oyEyUt4G46dIVJ/EKMUc0faHjbWqZFavcAjKmA8q rA6k09jAZB4Ss6yVUZIOZXqpBjTwr8RKE5XflTp7eVA7UTp2QK78RJViyr9dz81hlHDc+Hex U3if2YsIuAJcI53tVOBiO3iKbc3ZphDvJoKatzGG4sHIJgmNFcAwE74BecLYQfHEAIZBGNyE e9k+zNphlkgY7r97SgMPlKxA2a5o1vPpJ7nCxk+++2sNw+qh7XN8Tu+xoIzeJrqlBVFrT1ak lU2joVre/YUD6vrURSW0c+36jg7iZ71iFHK77vSbHO3XgADBcXHOtnAIozXkAW5/Kcaz5all W6uaTrlaYT44iFBTawLTlkGPn1zTngovTMPi+DfSdr3jhuIxkhpA3VcObZ2G2mbc7ctO65QC artm4UOpectYsejsRslVW4BYT69Ni4GCs5MogwuStFDDbqXKHmeCdq1PcuhPLrJ2t8hqIdZn ua3EtyQY2IeDJpQpWdW3kG7zjKVqQ67Q4+G5gdRvqu2oZvhSmUKUNIhqLaJSgZSmoldRF5a7 Ltee1RUQ0Oq/c3Ut7LzB7IRM920v47h3Vbi4+WkwTBfiXbtEH2gKAPD36qbvTlgoU/6lpH3V Dsh1MlozGZVthXj/KB0nPr7cOy+59MnRTWa6zo1JH0svahdo0MLStXJH47LLGimQr737V+WL RMB4mD/yQejhczoalT9hir7rA3l5fHYQFeMfDNHLuOPXnC4i9OijTvR+bTIHhy4boihYbpFu Lve2nqTjIXsGrNjTKj4Ayw9ypCbr2XKq76pUNheF1s4hMe8WXE1rGgFWDd8SQAwYYyRb+OGb eb8XeJMS0Yoyr2HNOUb3GYgb7c5UOjbWIwdFDZJz6lEnjKMpDT5Z7xzlzmLr0Clr2kst+Pz+ /YavTMsBVBRMOdKdRFHYrL2BfAqAz0HfnDpBRXB/fOcGsb4eIRFZ36bqNGXedyqk9baw54S5 qzqRF7O1Vn0jmQM5l13N67GoB4U8BwGUDrmT5EhB0rWaFa3PhhK+yvGDxSk/6SEGFal/tV6J FOpbdem7dEMRN1Mt5VBQP1WM3QY3KOiJM7+QqrmUHK2uvbzNr6tF2x2duWgXECuM4ZQq/+Uu W+/QI4EZDcp+i7pN4ICWhakqI4ff8D+JkeKWh+sQFaOyN1an0ACBWtdvTOcj6CmYT9Az2DXm Xr/SMtfra+YO0mUMMTr4bpjULNk1TJfkOfRGcqHM2HgvDwXMGBM6ISSeYZCItkEjYo4odhZ6 IOJPi78iShTv3DFAQpXwY8O5bwPwUONwxXvH1bsTN4sx/VTSqJYLd195+4MWX4yhMt34tpKi 5igeokzKwA/ERscEwqBK2KDdKOY/dTDQe9H0nq7af4d/1mQ/RJkFcx+1R1ROj5IRD0k/t4Bp zg4ETKdgDqponbcXERiubtmouOoQnngGXpvjJKc+0CpnxxfO3T7cpVs+cFVPR0g4Cztq2sCG 9hM28HmjuVbUz+7LowDidrqwd1BQVHCdQtXRmvzQRtesUtTCAJP7nKt83cG6ykMzmHZT6zFi C/l07TfGrJBPv/m91JSgSM5pPB15mSCfreR+ioPUGJidnbGVkH7VvN8fmn45aomqHV4Opgez z6MvFKTQVzZDM1vXAo2oz9nZXg1zW5aBxgtAlcTKd5+QYjRpgHNwtRzQssZ4O3zx7/UIpSDl Q3sN9I/jwNDXcSZ8jzwQ2HjGw9iMDw8AIC4tq3ehhMt1LVtf6F9gunN84mq+C0Q9hw1sB1Gz Bw2tGn/9ToW3+53U63+cWV6wJaWTqGx/DDgzoqn5m9o9HMEt/z5ba8e2yJxsYtr9V009fVny M9Oy9khZ25oX1Lr670/AWJQU2ju4JPZvrw+JoIvO/+bY8OBwsj8CkZPPuLlDCpiv5UrS15Ro RRR/7aXKB/XqcB4cZP/8skLwke6JA16HMjuHm1Z4oEBOIbE+0acaBmLs68drWPjszcigeLyZ CwhxT3TrvPVzeVtlq1BukjAO6Wusi6WsHVvPw+KhK0g6PGNfpjWCrjgR5F0nwn+OEnixsaJV Hk2gkszztxS1V3Mbdlap4qbLFd7egD9kGhFmgnFJp3SbK+aGOck5TtVqH1snd4eLLtVQoa6F J/ae1UGW2HDMFzXSusjsSHd/d99BSHcaH/4lHDdm4/gn8SROg27R7cWzmvQ18UkBOFBdY+Of bRmqDq8ABE7ubDGhrpVKPVJgUJamykqMD1q1kreH3mYx9lmojyeoxTCyirixtBti5c5O+XMl aLaDPtQtosCs9VYI677TFbPoMHfZQgY/z2KfKm+KIkdodayy6YstGmHJLO08g6JsjcUtEDbd hwh/ThhNWoXwOx4ovmLLm9hLRL4uPjl4sfk6GCtPoCefEPAE+GTcvbe8d2zh0+NE+GQNM90W 32QeTqe9BcQC/A588Hz4mq0wQV+7xpYCmnJ8Mn9ufL1Mmj1fhY4+b4iyKk1ua/ef1oCGFTSb nyRZ6VVyna9pa4QWR0BetT68/vT+Dq0RIkD4E0esBGoH3P54arAQQSwszfthTT4vF0/2iQMP 7C5DfWpoyVVif4/Ndo/pAGi0uKbJg//VRYtlaathtGH3jNgM2TluQI3U+7IX7Apz2rEAlJpc hYFTIOqFBFovkON9HEdM5pupCqTB4c+py+PTZNLJR+x0UjL8FgUzPfbX76RBlaTdz+HFIPSJ 6Hvs4Qh7/tWedxnXtV6OZPhK2XgFi+qf2zQYKZzhYcp1e4Bo9VWgAZC9xqONBriwNCfSjXhF 2cLRmgWzQZH/8f9ANTGy+YdpWEbz6BA/FihX/cuaAeh7/4OPabwfbZ/Utkhv/3HgNnU4OOfh OU509eOQsDR6Cw5SkZeeMyUGP192iBtKS8kv2kMfAxgNBmJqgzhuraMkbU9EDL27rZzlCB/h bozsTwtMFQwjAoCT1tJmFDo9Dlsp03Y2354Vxx0aWaOEj9KIRYTS1fnPh8OwOuYwxS0URYCh NDxCVxpfFnhhpEraLkShLWJryQXF9PGyhQ9Lk1Fk1wCtMUN10hUtAXb/ht4Gafyl8UP7SneU b79+YwkN8SPGLjX006t4aIC/Mx1OCfhKJS5TI0zVkC99ElqiA2UYAxKfRJG18uTBbOgzX6Gh DCxUxRLkD6vPpJoQQXCN3F1eIBshL4eeOeVnBVTwpZGzY89+90ODmfyhnyEOMv8g52xyedX1 x25PyMS8lGnGXRyPaz+8lr2djvEIyfuOxr5dUH+ZR/T9X31/L8gtfrhfmHMfZxR82dH8So4s 0wN/41WnfyyxE1Jq88LnSgSnacuSI92mT2TR2O7A10Yonf1Ny3NVwNVA+rZ88ud1lQtL8ffI 0HlNpB+FT7M86daxN+Fmm1RveJwK22uSWZNKFZ3L06nLFqbma3iDx8Oa9mRk6WNQBXUJwtIf mcS0WRBmhAM6ZlpeYT2Vz/+UIeW4GN+wVr1tFTb1ZNa1ybuHafNuhuCHX1zKSdalKFkNJBW3 hhph87xVoMe3b3RHfKVkh/Vic2heDRbFJIMKKkwRFbQIzEmHYw0zbjhVC+3f0JTWkQuTe5G3 pc96Dakp4Vxaz9TPwti+7o+B5Cq/Ctw/tpmdktbUtuBaKBeV8CSMkgQRo2HdFpu08tJ3Fhv9 h0WTe90lj0cOndprkOXsrDLTPDZGYlCo8g9GekfLYVLzz/C8VEUxXaa/AvHAnNO7clZGmOKm sufM3kk4bLfvWCOtcTc+9sVxqwIvjN9EB3vQhCkJgtLW6UYc1CaKwFjDcWtqVGsq3J1poStz qtLO5xx0wx87yAlsucFsCnPY74ETKqTTQ6RjRe4y1OqkwKU+Nqno+c/X2Ujbp3TyX1cGjkME RpVXaRl1WN4nTGoSCTCu6zUNdsry2GhM4TVMzbk1IvPVdOwbwwQwvl51KS6haVvZ3+Em6rM0 JTPzJQnCr8GyKQywROXv0AeaAzO0H62PTz6VfiQvLQ6sSHPgP9QWOyN0xHtrITWzKAQc2N5W Ss5NUgppvmxfl5VYastPBjbTYYvn+GOdBSyM0E3eaMG0ZqeZihR2tonKMrpmgyYpyCD4cYes r7dP7CeFxcEO+dAsy7M7hkdaZo/XVLC9RnnKZgQpSpcVosdY/vP4eqwdesnGabDpVNJWHh/q weInTiRhLZ2sYUYhBAc3qAZ+3emzQBUuN4mCi+uh+s+m0jQ2jqLway84SpG9ZPKptftOkCho FZzn5FF1tmvbAwsy9RZBAL8meTqFdEZTurNYKMYAhfxFl0emfOHwN8dBOv7N7WG0eoresysx pzjCnPnL6sb+pE06p2WwgtzhRLtdtGZ6QALCVZ/W800VFEwXV6pQqxJ5ov/orXGXAZjhg5RU 8WMUAPCn5bwTkKulxLRFGU4QCdEhLQLVORlhMOp5mrKrYrFOX6hvvqaKsjdV5Tz6Y5okFo/z 4BgIMiR4Hw9oANnlh4GwhsNOrQOFY3nvJ1I23z0cMG7RsnRVlZNzclM78UzBNzvH23xfDbaO D4cVMuKbu/4rXF10b5Pr6GX0lV5JUa6iJ3CnBB4eyT56TXtJTpUiRk052/TryLYD6BQ7S/RB UZqQD+euhuHLnzcj9TBMa6fSOOo3ehN7Ot/4VV27F6ROstGefvwRB80zckmWt6qM5Ec25O90 i7A3465Mylze1p+cwhmImEs04/N18MihRP0aAPoR0KgL+hiah9QubJGi765TIylQfwaFXb+F EUSZVKt8J3F/rgw2N+Gv2swkSHdQnkJN9CRka5+NK0PzcyoZLCKXB180AATACLRI3hmbnORy UaXDwmEE0rEN8vfhYjPZ/5a8VMz5HwqKL0s9yTLdmd6Wl6jUdQHpU0egvdH14Navzlf2PZ4Q ufFO/NY546MEpgiWVy8LiRo5dVE/WZMIZxoxkiKjdJmxVmErvdTOMrJTADJLj0jCJ3O/MC4K RdIqnAPWWWDiP9NOVYi5GzYl2bClu0qWDj8C3bi22kajSkGTAYElGUVGj4VVL+GLM8Ej/VcT RUyQSOmzud1ePdhmB1fWp7PpyaJjgxhlsPFDm94T4GAAjudeAy6MulmDH59B5AIdIY/XP7Fw +qflmtniwIVozlvDByx335skM/q5cGX3FCYkosCJa83I8yae8gocZ20jRnd/nmHN/jvaEpFX 8ry8xX+/zsLZXXB9bFe4hUav3VEicGl+AWkeB3a3gF6LaYvqlNGjgdHnLrmJ/COOsXxwLe2w x+f6Tre91WLEf5R/B701p1BjVait4c/LwXt4eY1yCgbKKZZorjFb4Ub1PsWoAlYUc4hZC3Em g+akvkLCatgCYG/n3aa9ka87S7A68SUUy1GbQ1WD+X2J6vYxDnwSLXMFA35rhU4ilTTKot2i 1dzW9ai0VQBzaJJhYNUZrpq5LnNhmIpFI5q5gvUS01s1xvcRP+8IzNSrAkuWs7YD5pEzNh6X 1xrYmUZHqVon2iY2Zc2FNB5RFgsYRjk8hJNnCkraqFprZLfFqpNJpIifiQHs0Hr+ZZLn9wuh qVDJkUa3DcxR4oklxb8YICpJm9WpRVwtk/Y3z6H0+wVhkUuQiuHFIGrByuycKTuEoC11s6q7 +Vxm9kW9QwxzP23kjZAsWBpQpDRdrTvAt5viAxmspPC6w2CngHWd/QSh6sRTx3ZPf5sG079S 3ojiF2IFw94+ES2rAM7PlfAaD8tZ4JWCwpCuZ7/1Oq5RPmXSb53gfOc3TD4QpQtnfresYPjU xgzc7X+EGYzbR6VH5d0qMtwdF2hPpymHPtiOthnIl9zMjENoFAv6WFtvfIP4firkA/GyIUYV q9ygICiPr/pJslmxC001wqhLkL9UWoUPEYyq2XdTQdyBaTbA43jIBXTZkqT4xmOuVjq3RSR/ GoDjYpsCdeIQ/vXtgAB8wiuJNGFGG75dw4NlMJ2z9ga1VuiqI/oIEPz2shX45ni6YWhpB1KH JuqazE1C8ljdu3j1cw5fd5UreCBET/EB4exVYuLsGAr5dOLd/zs9vcPcbJ3rU5cdt4PPfBrZ LQRGCBsmTlio1mCSk8mTeJHoEbZlC5VU49LSiGJfMCnLIh1EoVfYFq0hw/lHJ0KORzD+sjI4 0tnhpiS2dGjFDlAtahNZODuTpTLs9QC5ujYU/AcgcPGY49hsjf5ThkVrGnQWmMh81a34CRM0 Z5hmSmYVo/MO83/Y4xk+a+sinY98JzvPKo220FJmLS6YE46VGrrZsAM1wIm/c6B7K64Pj7Yy ryRXVtYPhtGRbhGTeyAZwG3JgqlXrnXFtRyCyz6pqadFaF2JEEPefPQ52o9zDUgbf6McgBmD 6yKW1cM+2T6Nktj7T2kk7kOeb/0QlP4rd1vH+m2WKnIVGLI5/M6WxcOHg31cPsqTK5YKtPva LI3jd8neL0LgfRePXtcUHemqV0LHmXbt3g5qcNfDRRtZmDgVxbiGf11876dC2bdLC86B+2IH LV+J0J8XKj7JeZCx1exnHvbWrfUzBVUblihxm4f4Il6iqJOTzu9S2B3DiCZz27ayoN2Mm7mN H1wUSKPBQIYhY/lzTZmp73qMkupz/xRvp01AAAUZEWaU4NVyZUUmxLwAQGq0A528d6uM+GyA pPLXxYiwb2jBzhGp2xFtgXAaiK6aRrCAcQo9EOPBmVb91JNFDQQf3IrPf1iB4Kh1wCmpqN+u liU+h2bvYMJIxgOrLb4mNJgWme0vJ+fpsHXY7p4nuJ5By63kZeQxo2e+69nCOMNg2sWIipLL ixa2z4p0Y9DnwYvI/v9gV+G9WTFHopYiDsST6ZY2aFgA0xhXI7+z1JkTcPjozX9v3+kj1Klt Pu+bDZbvWWHg167V5pPO8SZuu15Dc/tMbuGTYxDGQl+HwP4WfSdPwCId0EM9PPKt7L+JGXsd HbRrjyXmPc9Fp9DpLiBRyF3UyBNw5e+3LXwjtZP/f0B1nR9x2XaQSiy7RWWRgZ4Ous4n0x2b 3B2BYQg8NSl2lNBRLjB1K36KrG8tiiKREeb0P8gy9PIWQACNoAydrGkA1PYaBrTAEgjp3B9H euI0NUZkgf30/LZG25W7K6iRGrE+IqapgirGcHf4+7g5JBh/ffvalzGHqsYFQDe7W6a186I4 ZsWMjO0swCtOw3oOTqfy1TFjgD5GRmT1/torsSC1VF0JJqLFxwNNSb+1IFiyh4gE9uqfF6IG IlOr9wnaRkeG9ZvAbrTSoo+xbLmjB6PZcd9e1eZ+nZmkiWKxiRcdJtQ+9hRzJZZv7eJ1+JpT ll+fHb3KNPX3YAU+hsoG6zRU0bhnMqi2zUIM/qrAjWqOwB4C9o60OtQiq3tMy6Bn0AlAfAh7 ylpyGR8/Ol3HuHpxRg28luYjryA5A05MYF6QQJBvF/W2+bEWTjTc0XTM2O5KbzQ1fqfTIf7M sNploH3We2kk11ytRpDNov25nUIvfdqCHUbp6DvBp0Du5/Zpf1oj7cnTnJ0H2Hit5uKWhAA2 xbCcwKULUD5c5+z973OwRwpN/ft23/JqN0W8x+JftrJ2J7sViADcZHiWCUnEF+xYBLnAjj0g eNyC20PR5ewzkXyiBOQTKCmAWmQU0e3pHBNmryApDT3Odmh6Vf2EaasuXFKaT/nYAdN/xYZg cynMbScd9QzQnEyFxMJlTGnOKqvo63a/x0o5rD0W2hNYX64ig2AmADCT3hD5o15ZUpONFL8D LqbdrvVecjXe+X9v6XE+XQJ2H/b0wkZsWznVtgvbYRqRT5vHW4hLMbNadWkfrmG95gm1kVSv mbg9oOFXca/qT+SvQVi77FJGr3Bz29d4/tvwgreYCCd6y7FsUnl4prwv/w7Hq5/o8OvkZUST E8phrYyfIEsuVDgWWzm9VYixzLnXrnzmbUNbJHla+Hl4TCoRH+lgfbZ+7kTGQrauhjCUdYnZ BWmMulsI0M+BbGc5dVJ5RXMVpOBG+1jpKysR21pa/nxRPrd2t67tPR37wZK2TSdHgqEqII3p i41Nta+m8NoBwBqT+Wp2+Cdue4+b7N9OygmVLGkwMUslWxy9yB1+rw4x8HJ7rcmhWxoJK9fF 6KyuUDvbjEs4Zkd4KqMBAwnawjlCnqIOMbqVkIskWblwXB0rd7G/QDPapxBFvnOcv2AqPiqq fLb4ZDh8tfgSG57JYRsdXRHl8qqfZKsD6K5hNaS/7clIyFv+Hf/6G2YidYUqcQrwO2aMc88q /zuVhHxwF8IT1aglZl7xXE7dlF+swIVK6uVZdnBSKHBO4ryK82JynbuEwTroDePGswxvUpu1 K0m2akncie0WlO6n87ZOetzdMs/y/BIVVx5AqcEigI7vuSEnWkfcRe3t/fKzPlgIuyHTULvQ w+n6bLqP43NwnmzvFEZruqU1Mqnj4aqGdMNXgO6TtwuTO+tgyOUFyFoA3m75GJYnspZ5xLaL wEsMrC72tLwKBmTGuasO9KLdazAlQaKoGJUe0EDL24brLVBZUIvAZKZxM2PgK7fT0b07L9k9 nKhrFlF3/VXw2H9JkBHH+5BAsByxRr8kvhgRF6gePfP/4mOEsAVGjkU7DwXZHKh5OMbJngTz baXJzr+QGV0eXuT+OqzXxwybvs6id8fhZ1pOrsyiUKdocoAZhfjtETb+2Mmk/oLOnhXYRpSt bw0JdbtgRLCdH7Z2zuKSJKpbVpB3dQPq/5bidDvil4jbF7iJ9k933YVi2tV324JcHdnrldHA zQsVPR6keG/AjjcCFa25H7piPTkwjGWJ5H/5ZbB2+3zj4gEgfEXMWbsf+SqGYj9xN6U0n9xH nTDW3I3Iwaz1zEutmG7f0TRoUC/08otnUVV5T4AgY8cM3jrw3hrEXSEZ1sr2GlvmVyDyyxhx j+SGr0Mo97xT5Xxg1cmEWys5cAVT6VpWkWbjwrONQUuJluVfhIeLbgif+ifnrVcQKeDxDp80 v0ue8LSl6s0QjcU1apBsXSSiC4HSp7ZiuycxVbUWINBFWF3nGuK/keF5sGfczV73fhjvm+GJ 5nLHdIatmUSWk7gCXi5PcclNfopqdq4uKFOD8+gOYaz6fdE1EkabrYr/XiAJ/RWSeIMDVcmz FTDeiMiotUPmyCQL3s35F0UMVcgYS54sZvvS8ADiHvaDZn6Xj8bEhLj0DO7B8spx10ZRVIg2 g705j0ZZQXwvHkPI/+Qa9zHN0MrHckxGFVZWWuUzAcIBDmzBFQzksiDpgz+p/iVIFdrHKU6T bFvRSsdhRrvctiQ+3RxJed5Eg8SO8cutVxNIWxoAeOSsEnS95CPJYVBBVcX9Z6y1XQciXLU8 IdYkNxN7oPI8qsbCUPEL1Pqn3nZgzAXs0u04U8wnIAHw5GjGo1i4gLLwm2PLFo+4/Pm9xb9e 9eXj3Sf5pawpbJm9nDLRcyuzkEsCZ9UuSmgjaDIlvsJJG2+28Zer62UowbuYu2CHfexUhI+9 38ddt66EPjr1P2261mnS2IDzIr5BJFteKJD5l0EKor3UbIyBMaTGbc1yDBXJhsrfJC0JBSmD UllIOE0Bf2dBPy5i8u4PG4KebzASoV//Afkux0ym3kmD1898yBT4Tw9enh5nk00v+nPgbp89 5JY9Q4gQ3n87bJGTpYJTbCOjwg0ebtv8jmeocTbtYLPQZ5m3zT5vSNKJHC4KujswTXZVK7tc cEtuoYJDXrFJL4AMzPKk+9Lz5MdKC7anYy6DvGGgG4b1fkRrvcs/RaDQuwiM++PnVz21uMbe qm81CsWkRyP+TsCwV3HrnbluJXRDhs1vs0uGAYsC1ZgQeOc2vbrYRL1TEXAsHdtTO7OPdNtg T7hVKELcC7/vXZpAAhFr25OZ91EZpFkmn6wpsKrtz3qdL74lUyPaMrgRzS23gvsiBLY3LTFU XKLBqz1ftyHm+aV1mw/SZb4tf+z0RmkYWuDR8+Tg5lmTmDCZrG2mLdDJsc+XkYqOxkBVCT0t EmMZgdUKPqzjDlEoWxHzcAUXxVSgd5+uuu9+4QqUzRWBh0RuzJl+XOyKuoXv9I6es/d84Eps z1/dcbcKNJ7zcjbDJtZQYRw9VI0eHijltcAd1QD5YgcQyfTxV9fsXex1cXwMcDJV63Bjw9g2 G5K0chwkEE1LpatgBVTHnIShIenGEMRIcviGvl1MLyibj3eeUL56LjrVm9Tcv9wssU7nvXiK 6uk7PF7e6ZE5R/2gUf8mHPIsxRAwUfXiUMVykQv/ZEFPH4ADPpkpr4pA/+9IQP7j9+ISYgrH 42iAx4MxDAVGF5KBNpnLtvUER1veQAeAdaMnPtrmMlJ17HgYNQmttBJlt2TDEwwrABZWYJJD ZxoovF4N6RigMfCOuOLXsHu9Um9HNPoDBxoVPjNfJ0C811DMym2s9w20E9B4ANp3DRWT0DEB 5oPRMV/s0peEkKDLW9mCExq8HtFcV4dulrWG8Ykf6dxpQx4LGPAwBRkT+gyqpdoRoxAHDPCv E32uxb8ubAiJtEYyw8XD+IR3fhJ5MgWFjKtIkT0FbCdotb2sPOg96BRdEv2Z+rEpcNtDOU7G vmjmVytlYYTlzrgtjguh0IXgK/Fk6BiyqgKdkaVRZzLa5Mf7ppP4W0DtwIf8yj361euSZbvG XJK/CtKVqsxToCSKcfTSsuZb0L7pVkc0JVaF3V1gAGFe91lINd3ijZodI4dssqVxPhUR7gu+ dRBweS7/r1qLjsxxxVne6+0T5Gn1E8yc/TPycykW0x/H269d/tTGjae1iA209iO0yltutZat qEwAguYWj8NsTeaUAV+npdZ0Tm61G2jtFTSpa5J931rCVY7JAW0Q5bka1+JguTM7Jbn2uiE5 a1fUFX0sfj3hxRB6I3bo5drV2uEGhJyV0RIe45k9KU7XE92avAszWQh0SG0N9PdzwIDGysyj WgMGLtZnAiEm21A5B1Xti2QkmzGfbQnrM/XALxU6qqvyA6ex4JoOJeBnvO2SGFyKwMFsNVOB qnaSta7VTB9HRjXjjqsq8a8a1abcAqoeX9bm0EYHb1L0B4cXKa3JuqqZh5Q8Ar9io7TrBI4k luO1bidrJoQxaDrJ5pgGr3ieR/KzTZKJPoLd1Zq+abUvNQiUb8xDdRu7B8Gjw1ermbhMQhEe O0jQlwh+PzQvof06EHDEN4AbKTf2OTWiIvXXXMhUQgp1lcfWovCmcf/J5BWBsYlTGtRXwZdx tcoCjiGFMGRZIxvm22DdgBx+OMg/NDuvM5y4Qg/H0vfw93t2+hi+RSBl0s3z3hndDRNKJzPe tjtIUOsEuP391uw/K5yKYVgkba9TnAG9CUgVtaQ0ya6howLe7Apa9GJUrxyp0dapPbJCStvs wicl2uCBIdO5/wsfgthVfTlq4X7y4OTjXx6OwPEO6sE39VOMYI4LMlBmWAW6nxG8D/vR2tEV 8vK2B07R/d33hgum31vFizMfeB8jukvEVTBbCWuiKJrrM8N2N11tQGAenHJQnKyJzTer2Zmw LNo4xQAIBVpROCU1DdcpYvaZ2ivOxfOikyplqBG+S6kc9Ez7FTST0a8MjVFfTmpEjpr/CbGE 6UJAxxeK3oY+LWayjh3CAPY8a0/I1y3Tag90VWqgPVcjWWpq3bm+wuHumFk/piIac8681EVa HNik8mgD+/PnTzy5C9nzQkZyDJTuleuYTGF4fMwr681Jno3zJuCBZA1jpqhyz1/cdx9LdwB7 7eyBmudKrrKVlDN3GQ1zf2D1ugCo4y0ZuV4GDVdu7x4jGDNre4SuJayofnaW1mqF4YWcucHE W2JzxzcOFbEuSv9vW5OQ0gqgEkNeH69ZX5sqJck+udD7tjev3BMiAVFZVCLYtWHLjlBuKGrc 5xS18H1+dTBu2W5Kz7TDyPvFMoNCji9Yc8V1SrqECC0BwLI3atmA/VH/iekbEiAJS5GPHsOO nsoDyhYBsMMoXz+y8bf/DFPtzoxt5X62M5lsRj6b2L1eJBvC9Xrg+ugWwHDRq1aKlb6O5WBK aYOl6r6XQ1WYHt1SPy851zzrtEQaK2ecwYbO7ljgXSclFzW6ARenf6wfYdqFds6tY+6RyA9Z ymLOlD+ZnB4oDkXoTAs6tLfLmyI0r9/6HoqUfx+Qr1fJ+vdq2F/Q89r/BxNDkVkzF2Lagi5N /OI1tNtXPUuhc9gIdyJcBqus3YH6SY3v+Hsw0dBqkOty2/r7zP05PuSp6sjQ5qGZpyT4ihe+ wKk4bB1FOhMowMJ55CWv8ZgMudT4xXPSAGHcgzhZCn5dLkgEb/m/CvipfHqT+KhFzpPBxWg7 8Pu11cL8DJYssYyVZH8V10ZTsFxZlAceKP/VgPtyLKhV365JSWkBlTRagNgYgN1rCztqqJZo oZw1NDLfmyrWXTA7NHiJXvDccAsRxBGCipu8rgJX7MYSAULVNRGT9tKJJtikqEUrUSjeeXKW I8tCcMmTlz2IMs1QCjgPCyhTQZdx6JmJRCWSlzXlCoezpVY2myv4eXXyVejkFYH1xEZWuQMV pGp/QgyB3nfEXntlZHbbErnZMpWzqIo+PI03JSBWZTAirbRA654f1K1Gi+7GcFkS2dC4vAsJ gqb0bdgAgOHQrd6AsuCiNud+isMaWiRjeKYRaiiuXpngMhIG0Yg4HQkEtn71mTU20rW7HX9C BW/CYYZXPaeBMs65VcAXwm9iHZGqTmUhfxPKj+g0YpLo615l0vJVTcgAaDGaFOsj1iOMHkkB 6RPBrtXNf1iBx6pxRtExxW730HI2ZD5032DT4rVzh/nUBQ3iHEq0mD3SE4mHNVdak1dbjqfp QMQFPjic8wecHc2+MZQFrQ5zdKbB84YlFaj6d5S+ArIO1UTheANBGXGaKttRLdwDsZBN6Mai DX17h/0qEFSj6n/wxVa111NWPfbGIDoim7z3r9pe8DwC4RZi2LI/HEFb6QpfDfNtHZCahqk8 Z7N9a4kkHp2BDzaRpdQgkqBjX9ejhHucsrlwfUmDNbfnwf6qqWbAzfR3oyln7S7rObeENtCk lp1pE14bIxz2lbczoN9u8QbwwBAIMEevy74o89ResCKONuD1jhAWWFmrBGm3uH0XL36LyOzk K89p90v7uzoe+TETc4bM7Wbbkbxdra7OjFdbh6k6VKVx4WiwGrsz5Gq5FmB4Tx3/h5tMkyY/ WLXOBV4DCrJ70lFQwRk10jkENulRZpm1c7xgLWX0BW1zdB+/lqanWqbG8WsI56Kidf/+MDgO SLL36C7iGNiDh0Lghj3QnKaFEbi+p9ykg20KoqxTkm+1B98GQ5BDhLJuU8vgH2N/OZd74+1r ZXWQ9pVwShBoicNGTKEXbPqpjKwNKFkTKyijN4eOUMnrdQnSrOaXcDzXhL9WiVhTrqc6Nhuk NBOyfkVeXc2sAnVdYHbOFxB3TWXBC83UWD8OSOwPAB6SrV7oKdTPyF9qkZ9biHO034U/roko 2nEiKiG4LQmG/cSTsjR3zPQ7OUTL4gM/4Fo4PDKkkzD1/MNBeAZ+2jBLgS1du18OFicQO5uC Ki8raIBtq8jdQviygxsjPafu8rByP/j+lefXjSM+iMtRgFO0m2a+VDRnxkmGfZ9tbHI2JoTv dhi7d38+PL1l6CAELh83UmaGXredLf6vzb2DehfTyL/nYO25o5FRWpyrAPF/eJTYqFFzOOnV b8bNH4j43c9+KdU7n1X3JnpMR4UDw+FAs2bZzjUxyPTG18YV/Wd+OvsUzji9Eox2I+Z4ms9V MW/kCh5jl6+Jl/vyArtGh2il4031OKEud9uWUiw5T7fzxFqTnnCyHY407bgM6I11FkpatEZ2 S/pEQqxe9W3ZDAzDIEzmdmGemGbCR0s/Qp1wLlYnH7xnixfTcxZqSX3qSCxaCA6MunoxEvy+ onHF2z/5NQ1teenDZnWJmjnXdk2xhfDR9uLquqmxo4kvqbQrRq7nRKCNRus/yeNgA2bi92H6 txEJnMPVw9Iti3UQILifJh4E02XHHKQxUk4bMqODBDAtCQ22eey5ZglenruJySVg0Ez731WL Lcp2wujakPyrgbRQCuuZPPFiwvO67RuqgMPT3uK4XbLSwuFti45lhJAoaLOnFrAgMSxH19ah GWR6hy0cEoZdfXbem/fNwH+Db2KQyqXW9ZBC6nKIbM/p40VvqM1eC+UGFTF2izjQKt9ihI/U l4pBxUEOwZ356O/GkWXI1GO4gb4uZdxmCR92+/pD88eHn/aNIrOGqJyNbVgWYx1BnPr9CmOk tJVTz4zymqjEd6JET8hmLs8Bijx/9X4LHKI+hS3w9C25ORtyd8T8PxGko9sY7jYMjhoNk1fC OgwNg72GKgmRw5Vn5ScilzQAznOtAMOeiBIbhpe4Ic0Yp0O2ZOWVyoo6tqdy+IiVQZxbXMer pjw3XncaaUMe1TiNH1XKqeBTWE+mouF7PezIa+G/vs3ZgBZsBa5GkiwbFhvwgs9t4Gn5dhgy Ozs30HoF3Urgxz0mNKi8qxRykelXHTzdpxPdv2MpMxImfPFPJzwFmuU7UjNP6fAkZF1+e0nk jvRGen/vAbcrZb0su5qMLIf8qvKfTOK4WYoIyVgFIz9TAfIPBWTZCaAHHF5lxKt+8KrGslCH k/dbiMDi5vDo7p2KLz3PAPHlL9fdmrvIKL5GDFOHnl4/0Ks6jSmamscU+71OumcKlsFH/I03 5dvX6pGWc7vPhlc3Epq7mzohZSkFMxE9P7NQWuTadpuwBpkl5O4kbs5HKECrD6tK4oPEx9wp gUpsCgnymAKeyDkoLSdtpJMDhGv34bV1MrlGO3n4n5I1YxKgp2xR84N/vobHE7b7ttFN1VCq kkwhzQO2M2VNOhAzyBwxG1ZnjFaskCEhICk6Mx6UrsKweuIZkfrX2cDl7Mp4iQaPN6ZwCPkl EOMtyMQWoJk6LQX0uDB2PFiwmWL8UbhpFmeP7jdEgCT3QQYws0uthEw5NE0PxcbqHZe0TFza OcHILBfOO3iYj0/L/LwYIWI+Dyfq+jmsxrCd68EZGp0XwOAAjl4DtIzNdVMP10rIf+QprsY4 AxEn9K5gYjz2lcDYxvFjM1sbK+ssCvT86pKQMuAduOys97+osPOsswqdVnvKsttRYhxydAWm nLmF8UXh+p5xR0YrLUkKa/7TfN5EaMjkTfpWpTwv8ci9KM86b9eyLjF49m1+3fkO+7115YPC cnkPN94x5pG2XO5W1D8tyhFKUS1gnGValcHQx4c/Idd8RbjXBgRmT/MK22FVxxcPbJzvVlj7 W6i0ty9iSvUsKhODTisfaMSWJyDQir+QUcBkNjSzASlIxgQtijGbpgwwJ7qXlkWIZjw7zQ5l qKB30zrOTbe+xcfhcfxg1PHYHdXdyWLuEm9kzWWYaRrtu8mK9fpRicqjtCRj2YgaN11yGXRh LWWwB9LeytkCZYmwnrUq3tuMUhIcYDTFUZM4Pi3tvpbXmvhJcTiIt0DgDb3fZ7OXKBqGzwBB Lzc9TTjomFrdsM7MGlMlln1CbE2thEL/vQDF3Nt3Tl1BKFzVy3A/MCeH5YwIGcKtJ4UUmEGS ARjJ9H3ow/IRi7f25xSZIA3zmWsG//wNhQHqau3ZVy9mJ/+ZE00VuX0jqUgCo32lDRNYDUGu cGQajK00WVcipgkq0SSB6tCUXF0F6fWLTIr9AQTjXcSXShI5l+0f5HR7W7e5HlhQ2U7JY0Kb sRiBYJK4ojGD2U9saIkI/Ol4h9TCi2li4nO6bdhRb97gSo+j/FrFm5ard+wiE5VRUck8jE6N Vz48SKqABFKfihC2wIjNNAf/f28ctC53ys8yPjXMTYcLAuFEMGQVDnjrmPCsMF2alU9lVZsM aaHkuI5l3myhBox+duad3QKPJ2Hi115JXbxGPmmF+zB9bIYjIKXUazowIfjwuV5qaB9lKjU+ tooavrMAd/tSyYtsBcRcU0uwVKhKw02KLBGy1o03Igpk4UEUcLFLV0wMOkljXHbhmZF+7LfA /6uPqAHwfW5cofRfrZ2bETJf5pTfdMOZjnORZFBba9WrRjAmve8UYtK25hVvQsYMr1zv63xI RyKgHlLhPW4qeAo3Lzlxqsm0xsnWTLSTrpiudDrsWhDDYu5kAaYTp3X1zAAD3TKOD58hzarH /G8AUVM8yGRsva4ifZ4TgCjDtTf08QrlwL7o47HoSMlMr7rflI4czFokrjKu2fuR5DfAZRTT lXf+e6GFaPWtsIF7MDVtgEyiehQ1z4iw2fSYlIT9TIzj3Kp93eSneOkwe+y+aCeyWi2D0Ami 3w7VePjlZPLtFhNbh2uKg0ccFhuix5T0ygnJMZyuIZ0zEe/8ipDC4LtUUwYyp7oBIigQuXQv 2c2H8jZH//U73DFhCNTCOAc8yJKUXYX0xXDg+usOZyOGRW9NlnTBu4e2B7qYPPZGPr5ay/uq /KQ7WLVagMyBK1cy7FNEnqiuG4yUZxgzcI3Kjh3P1O5KFXtbodgoEkEZLXblw/bY2WSU/r1R tXwVUr3Lq3bYjxnCTtHflt691fcX7+CI5/rlSsF5kf5x37f6k28+LXqXs0DZ76VdNBPo/9+6 fo1/MEIdgo4WUG6Hm2EcN/5rGUgPxqDIefieCSiZH3D9Hper5fbFpwEzu5DZexNYX7I9LcLa JAtkqyrxqvjjTW3AYylBimgyfA8KQ3fGQwYCpXh18HzlSHDT0TcqyyX4Fqi5FjsrqURXari5 7eP6q+lZjRnT/mGQnHyHACXG7HnkxKu7SEHKC4A0JdoRSKreha3MKGk/CBOxqTNfp7sPVDUX uLxSm0d7DEmQMZBLPbdn7DXudHPQpOA/Kif6omMLIA3iIu59U0TEWk2x6BS+s/m4nbL43e1Q VhXR92tJpURaMFJ7187yJz3oeFgsEhroUBBAHDRMfIOlKAR2BCWLNoCjLihBq9IkKYnCuUpV c5hZvNO3UnwEEPkYdKoh2oD7OzKYXVKwwMMnV/KKivuNzNwjGwN5JuOGe9Jf0dQqQb2ZhPS3 jlGyCi7kgFNhOXZJLlXMXSKYQK3Fwr5ZH2DyJFZhJyqI8i8B4csOae/1sXSurOCYRH2zt7Gj RUSzjv4qe0oE2YwXtUD+eelCDV12LcsMHh9G4oNZGY0hly51F86TUMAs8cA0KwSZq0BWSHlF u87PH+Z09BoEk41Ly9rlHp//vtk4VPUJUxwFYBNjBYs1ckMadlvP65GnJm8f8V367FKl9WgK rGVlg/KHRcKbxlasCXq76dxFQcXfSE9snz13NV0HiZJCJuO8U1cZv8ZPhXLBpkZaAAvu6RYa 2kryLybPAdb5lWo6OpFw0zLRoNE4N2N+oINZXzeE58oavjTKNANuD7MKKRT5L93YvZkTlz9A z89VdnLxNPdqDEP2gtAuM+4fzsvUupEy8g94HWX97PF8FeyYtLE+zNZaVRY1B2+TV2qwYXeJ iQ2PJeL4Ms0ySHirM7hzGQQn1y5lQHAxnM2vFOKcInpANb1NYRFcHUpJqaqB5rQDfUT+XMBx vKw56Wh7oeNnhdbWP6Fzw4MQ4bff1ivpLecZ2IAJbM7tEqLPDDGyeC42PaUOSMI0GHSxiYyK oq5j8zajHHI/7f3je/WPsDq50yQ2xsndgth65g72Pd6qmUapgj24jyf6z5g997tmqqqXPgej 3fi2LpxvnDSXsOGpPWHhFumyjlsj5DWJldlIqEXgA2GDLbCTov8snBwPJUimgwcvuNJ1IxTF t8H7J0UWSeb9jS6JnGQwU1UD0b8Nyd7zAElEgMkSBhmMrUa7k/K8ak+UOad53yvNVRvXjAjw KF1CU3CgljoqfBF41eAScBy7VLE1EMExleLeAgGYkiXBsqKDiUCXULLzC8yL3PIw6KBQyFGG hV5pDr6GCjX93w7/sgynoKx4QntGvO+lGax8KwU95dNGF0RAMB03NtLHrKNBkLfWZQ5LOmLl sZtvobvWuOo3/WLq8JuMlfaIR8b+XmBEE3HjyPA4LxLUbSMqQ5MH9XljDKzGB/tWG52AeoyV cdGgt0MTIpXWDKY53wyYM4FJWXj4AO77owvz9ajHSkGqu4bM+exJMO9S4peNnj8D7mt/LJAe 7L3l8/gA53NGjXtxBcsE+2Pvh0nDnfVAXEEWuVivVHCuYw3Hn2C/LyZuhrLOSDX0Wc2/7Q/T Ih6X4xvDrWnwNf+JNGg5ez4iZYDeWQydCefK0DEiPykqrIAKZ92W2uUX5vpkT4a92InKmc/X u7Ielb5Vs2+oNVp1/k+RUnU7Mq4WzKBUO3xK7+AA4EJ036ymjP+UD7xbVBN47O2ZXXD1lIw/ fCgy/ulF89NOoiplMpB6mq9SFqkFysJvlyezrkZSM//9WoFD+77iUflaP0fV7W3DMFEZtpdH BZsAWAoxMdiibatcRf521kWj1YfMjBu2n+F/rJjqq2+KMTixEUPMZ9lUumxNtQ/DZHVPyCSp JBGb978t55d8EbAd0ejMXXc7/IA84opL27vW2diTpj1rDxmj0jFxoYA2wPwO2WaaRDZajwcv blaQgy4p3ElToA9R1X5k8iipO/HfHCClPZ7klLo7sclgcAr4RIB6qbxtOg/6ghx8rGjCUEKN NjUBLsPtACnzgKqVhhc9JXDhxYiP28mW+hfYnc42erSjGggYyjXbEoQWa9GIE5UG88wl0sau y0mEbGO9FrXosGB/PwBJZRvnrF4VGRylQ4aEbT/85m9v7IX+nLq87thivxx4x5E77Mxtwcuz asuM18fKz6KEYGl+RxNY1mnncaq8gqNeHtWMTM9Xp6dzxoybxoscXHGJu4YWzfkjUOzFAQtC 0gZQDL6jGRvzCKSAI4zz54fQJzj5wxLmaf4VNv+TmvDkhJ6Ko0qGaFSolimKW8WNyKnVL2ec XwpN+mwMmHjVJzuA/uyC8aKTd7LjJVFzXhZIaRfatcpubYMN3o5MNuUcM/jDmK5hdgeeAQ/H gzpg8SA9lL5scOzc7+qSpbCPc/LIjXrZ0jXV6SY14it45j3nGLpHG1Tfzzh43Sto29gvEi0G cEEnH9iHPB9T1Pja1Oz6yN1HFWJnpvgCHbqz2RsneEUTuqBxDGK/eFRGwAvfu+zrsjpFzFpj juN/kzhtT4vcqBOLM7baCv3EXzY9t9ROMUWtFWpUHwI/2I/pC/9JAT1YW/Ea4BUoqkpEkWEY T6840Dykmu4056bUlY6JfJcHKg2yxghNKErLjTo9uD0cwc4hAgKchHlTiHtkUJratbxAOBzh SVunel6DcFzNL007c2yrzDxyz3ofZqCs32hrzfjM71Qk8zSQph5hRtV0/zeW8pPDeeCBTa+e rPPtmIM061org7obwkxrwptljnuMxd+l9kcK395ZFvUEp+t7kE+weMT8uwWW5bS6pf5QeTEf o+Yc37N0jqcF2jWko6LZ1kTj2yH/Af0SNRSTa3uFXLZfHbuoGywWtmGG4MH9vF4zWFkG//rS hqHHjOlVvlj9g0gHCCSUT/GpunDCpzxyvtMa9o/JVwvJEKdKfGU7vImI3DkrWXZ9ymfdNyzu F5UBk6DPUEm3X/AM3KvprEX07koCOqFwLe6gYk80zL+nC+GNGVTkHVaZqWHAbULObRjxZnGa xKUPk8rZIAGGraGHq9v801Mem+7ZEgKLo2JaxG98SqfzTiHh91F4sKAAv2duk+6fSnX8Tmhy lqzx9zL5Ip5Oze3/tNGCN32fX3HdmkHNLogWzlAgaEiNOl9u8n2K6QPSEhB4EA7xFiS/aEM9 Rt6noCiep7KT8sWZMVUu5Sg7CznrzVr687zJinrYNmMcq9N7Nz6ICyct97k+KkEylEzB3ltb Oi1Ueu0cXv7uqO6m2xBzo6uOhB5hucQP3krl/LwaCdtbrT5e6sbnC5HWohMMnt9gZQqvCRNE 6QfQoHzkfJSsFfcJ1IKwYy7wX9Lh8J9vtzWm3ROMZsslf5NSrjD7YUwUdt1tqfUjqfZIcdYM zCDFlAGhmqHZ6sYhMIdQLVLC1N3CFJm3UcunPa5CyJz7KUr5Bii7SIR9YboYiW1Sr2K1HM4h qdE2kb2+BABzjUokejp7Pca11hgbn5BnvTZu8DcJ62jRvVZR8QEzkP6RyPxMlGQ/x5Mk5sdR HRkLIKjRJICZiAJ+ZQjedJMrSzpa5SzJkh/H+cwgUE7ZRW6BKP6m3USL3oax2qzDCnJ3/sy/ C6DuZNIVp/6Agc2zQVLdo6RIA14Bk648mQxheL0o5LUpv3I8Yq0KsmFexiA6g0uImJMK8TIv lzSWOjyi1wT4iM6TZXY7t6336sobL0+YnLeBJ4cTY3pkjPzb4Cb8oywG98BJZtCB0PKdNetl onuyESHZB1qlL/s6B/w5RQyWXCZQmMM0v4JelzsPe8eJ5asrrLr66LVd2cVBjlSm+wkXS2Ll 0uBvO9GyrOOzSgS2YivM4wsHEZlqfHympCoYbq0c7J0DLo28PP/d+CmdlAZMd/1AJEa2A6jG IZHb0n0tBiEhMRVA5I3eehxP3eK4c1bPbsZkW3o3/81+rb2NpRomXkKSeN3G2XS9qyaseCAY 5ZbV8hPwScMq7VQch1oH0Q7C7/lMMtw4DEFz579DpHG5WdO5ewmmpGh3DtVCkMkBR2k6hOrA qGNT/yC40Jkwn5m9ojK58Vv3cz0AouALqmT3pKf5cLSONp+Xb5nSWkMrvqUecfYLx1cRBCOE AvIm98f/OzrC2D6aC/FxTbCkQgT5GW2q78572Rzo8WtF6J+a88JSbvVZwVz5wOEJuF7nluVL q0Gm/zrjAwAMEdiksI3dGtcbdmEvOVw76CYpEMPaavBx+ZAziQ82VO66wcv4VHNrpNEWYKnz 8b015BKJxErHCLdC6ck2hEcDEWcI/DgibnktBGIFq8zKyWL0tyfwp7qyqa5rHzP6/ko9T8Dt YJn7VZG2uQ7aZzxp/3DjX6SSv+cDet6UDq71ecOwS78Ls9AyXf0SRuvn010Vw0n8AGdEV/A0 tGfhMpuMHPLeOu/nD9fh0qgbsi7VlCee2UTce1CwkVP98Aawme0D0pgn9tZtukpjco2vPate rX5olzlR0PaVDamOoqm6dXdSl2wYc4f3JKW6wUAA0L35SHCkfHTJ6rRDhjkHhtRbv9N1Ol2/ 34nlk3Kejx4VQmxr9I85Eirqib0TcA6aVInI/BaS/wPMoAaQbpfa4buruL+0lMeZpdcSDjVo P5ZiJ1Y8cPYddE17GJwWZ4tAL+2oW3VdzSNJwIQdq+0EgJ0/qv8yrAL3LrFpIG02bsoLk9e3 vNSti1AquaN3rWV2uLmgSkOQOb+rQOpkkkj0xoC4xbxhuY2jl2ah3HzsihiKk67l3lt5Ucxt eSdiFmtLX8YNiNfKsE+xGj11SpbiLZObFRQvzzay+5Kn5Cb5cL/IsW/ENszsnf/zVZf96Srn RXoAv8a8HKWvLXnKdxwBqkJH41vQrxEfQ7SPkzxLNYs6/G1moBOyOiYXVrbzwg3EHkc0/qYK LbZ34bnn3H0clPN8FvRT3VZHA74jxSGXCaMdOrDx3C4dN1JO6bKOqM4tUmFS2gE4IT0z7Qt+ fTK59jmZDEZBmeV02E/+Ff8VPDcQCztmSC82evWBZWULWcXrZjEvZA5zdFCkX81bsOAwF9kq hpNnFSL2uMmUgd0gg7+jzs2lEQ7w+19nou07R7nifTKQmxdBeAtm1Jk9FJowmJfavImlKewK hfXuQ3g56BJ7oR6216ZzG0HNWWXeX+hqj5S8SKTHS3Mz/GxnaJI8xzjSiftqmvn9h6nzDY9f aFv/tfLURfvkzjJy66rD3RJW4UVQ8UiTEGwA7g5X98bvQMGO4jMPIedEBV6AF0ZG54kbbTQm lDNepyNUDsR5W5SqHqrV40CoDvSnNF57GX4YLavQvJrQmDwcyAm2ObcZ4pt7DVp270jAOe6W zCjKhR3D8R5B4IxHwMdRzIrz51+9JMcoFmI2nkTXMsVTGG67OiJcNq2NeyGSu3rBachQ+IIZ DUSP/IQebrPPcQ5aLJ8Rkk841LHRoyZwAo8k8Jzhnj2bBTuxpBl3qnk27Dph3CgnpdSJH1cZ Ms8r5vGx7trMqUd/mhfwKenMxNxfHqhKE8h/Y74K1E7y4XVH0Fyne0QYYSuVUvBUtQ4SVw/j veu5tj5pQ1/oM95U6vQD66hAnWqEFlKRiw+x+O+f7c0S8WPTf8t/yTPRcEwgZs1tC+ibpmb/ KXK023tmyk8jnJWpTp9/zfTHTcCVVpSA440QuMaHYvf8JWAw08FNHNSezkcejdUlVU4ET50m Gmk8oWOCWksV6QnQ7BwyPxQXnNm/VPXlOU+zmZ1dyN5fiPR64Bikdzg/6GTMW+XWnPblqqBO aQNItKnC5mWs+8fPYX5koY4eCezXK8r0TiaX2nnkqn2XEKFIcW5+im7dA+MiAPCpXJNpHIMP UcGyosTzjXBU1/SikiNRxIAvm6VrVmr7g0yLSePg8cNNfwZ1MCk03HlCerm/dWyLC33m/akl RHk3E2lUGl+50jnWo4vxnBCMPQMu3IZ7lal9zHWObcOSBldu9DM5SHKsHR7Imo2ZnERsXjSM +00VbgCe3LO990mom6uLia6nVR+SKle148FvX/1u+ZcV/oA1FEhr6Xwi4Y6pJL/wWyQWf/jV R/aoZSwLbbaUpZpF3KUEbc0zu6Y7enHDn+c/Az2uWfuV146w2LH/2LjqQnr4awfsRUw8KD14 zGoW2Qa38vBhHkAyhX7wyfTAnmieFn6oDszp4WL1Vdy7FIb1snWTEir1/yaWIjsf7hnK/r+d FBKhf5U//KH4C12lNBgFI8qlRg1AWsjOma8oqGfPjRHHSI1eATsAePuOF6fOtoOCxOZIC26/ R49il7ac+IHkIbUnwiji+Wq8zC35WaRtcNe+r2XzklQoGjpSDskzcZPD5n9XwyTN+20I8+O+ LrKLotDMa9s8uphZ4qLGIeE3r5LRC7y+xmRLuKn3kUXNhoHiPj3weneIjEZsfSnGijTp+YgB o3B2bE4zNnkUDFbWFxywypiC63agnIuOE7RCA0TdzuYnyAaPbYMGukExU88MTPCh7KCxksP/ b5bIuOGijWAMV46+5eu33Z4hkXnR4NVF4LUZq7ug3DUuIV/K6XhzAmWRREcsARlD0S6U7eDs TqXxDQ9g8VTUQXccJElHm9pjpEsRWTyYMvybujACu+Ud0fRRFPePt5+pUWJiLWTVfJVmqOMI Z4P8VZwnjriw6MppRGyEec/4U7HAwARpm/Kh9aTNBKcubKf3wbRB5B8K1MfgZKdOQ35xQh2y AZggRu9dg4sEXqm/Am/ESj0KLYCWpb6lpuLeJSqOMYP86erP4ggQyWLLF4B1FvA3Sd0GZvH1 HnCLs2uggrP1E0c1qZcAq1nXt62jwvWzObWHJc1UWHbcTySX0JaXfPY6zRDsjz0ZXM5GdLlA S98fTWlOh4HzgWfaBt2fRylvXdqO27lzk8fwfEwElQtA8yqiEKHUvKFskziYcBrEDdRixHxX mdFC2i1wgRoR2Z5/57r8jiJJ9k/wyY0r3InDfMomi4QKSVmRMNVxQcI4ayD4Q2wGY2NjKVkw R43slOqgz8CnIteNpVWwwCMcoP/8T8wJLmqbei1v8Pb89wgfXo9L0pM/MXYxn8VeaylnC4b6 LiyShvToxXOXfiU2HbB1jQ/2JnwDjHNqALrTHEXNImW43531iQtGiTTiHf3cPK/6msRwmwph 7gSVfiKjbhUMb+2XdlekLl3klxBMD4JtDPxPTmbrzOQYivKyfieWwZGoNDT0CsyL2wGbkRUF pSFvkRrYjYxVO4/h4hyhakXQFP8q4xMarvzKpKaPOHGTrA0a46RnRUMoYBOcbs3KmMMTDvk4 TlCRrfabIjZ/Ent2oyZkF7/3X8zjTvayJBjAmcIdl6ih3Qton4neVCQtOerUWRJGX3FcJv5U 9bp6935HxOTnKEhq3A8ndIg6yct4ZW3FPYNoJ31DX5CHocqAC+4SnkSGApENSJF/EEp13dT8 z5UGcgdvqqYT4HaeZUPpVlDhMTHKu29a3AoT01bXM5D0XFiYgZt68esdX7dp69CJff3VdGV4 HRbPuCu58LVyNmc/dnQz6Do2rLCJ3jKHCBOUYT55lV4UlmXbW01xqIqbQ2WSYYDDPh7Xmk4a fwmoe+1ofULUMJpuUAIGcpkA6Wsqx+ZeUx4dzLhzIf/nXFCulPYQGUWkb+hGh1GBOftTL+Ma u5b0Gf2lAIHMe+XMgR89p+JGV6ww+S1P6q1EuqHy8UdVboOAKvf8r8cEcxRu6YoI0D2rsgyk 8EQRFqwg4qMmoNZ4WC/YWdx/kbt0ujb4+kSeO5OGbinpr1aUtgZOISS+vjoCPNKlbc2/FYvP rxEKQunm+aEEKuqRi3n+mMOsMf2mEsV7SFBotb+j9WtIPeE99MobngfI34yBbfGB9Ew2Fm4e T/Ueli3JYGFHj5/DiQ54c2LRyw8G+NN74in16WUdNmOIT30Ng1rTqCqXIsP9bO/7Qf5+UxeB CB1cfooCfZ8CcoVjfjAJvknaWbFfA69j/5kpbu5BRdkYxrt11l8i+qrUOdD/+1BTmY8jJXor FYMufyWS6AypJdfAYzxE0oaJA3LkByBhPA7Y/fzOdsY/QlupehLzqllgF5RsbHUm7Knnl4mf mcur7BTm+4P5RaZJ0IN2wZI9JmK4o34iFtKXeNr4FgQYwstP6muUHamZpv4VMOeFKnOIZvp0 SbRTOW/hDuIMIArnfmzD3P419Ote0tzw/KLIJ7uj54fenLR5H21b7BBJyA078bYFjWQhu/6m F6qM147Ah8UL8Kz7/g35xbkd2NiwcZFZ4GndtuXwxBKYd78ndnHsMiHUL5RoQpE22cEsTV59 SZHPJLyZBcHbM5/csptNObP+evjegdamgIYQPFZGbMAmnA/qfa9OCY4Bcag2TSjStSbQOUtn voWpZai44aDLubDqJV5Lh5XtSdxx/Bhyhf3vLhjDm8YfBHcsbwxjR6JSrJqjUWRHIQ/+5eRL fXbg5HcrfrY3A6DlE5FjIE2I49kYV72D5NjckOiFG5MX/GH8RU/52d9FOjmY+LhMGfpD+Nvz n+y58+aBPO+8MhWsVz/nke5H9/lx18wRiXUvgp/1sOELNBnS9NDaN3Ozpo1HNJAAa8TWB4TN 8tK1WujU7ntSxo+X9S3f3X2Kv0OvlX6Y8M/WExca1X3GvgtTIm3w42aQqA3C3F27P0lGzFpF N67hDCYAs/4z43kZoeZSRqpTn6te0ItUIg1LwuAEfvnphf9RnyPvbyXJAkAHGVwaJ4oxBjxx w+zfTm2+vA0q4dBjR0C0HJJxAX6cnIPqJZqL3ue8YUf2KhyfTmAHwhKpYC5bcY39/uROVcMN zejyYBbNv8u4OO4yAoawGghkw/ZMoI3DVu3Y3tv9lDiE6uL1mfbqrx3cR6YeWsst7oYysV0T jQcFKNz5vCA8+NidbNKOFOd2Mz0gbQEFOSZSpl/UGCty2mz1z8eMnf6xQiLT74m+5x6nw85h cLWZ/tjJNRmueTx0u03Pwo2w3Bpl9TBRimN4D1ifAPL9Mut0L3/O1j3ExCtxTq3WgvHheKwl mzCBjtli7GgZoLGz3PU/ziuVzOMj6tWW5/neaVhdq4ljkTNlJi2yb0HxCK9W/bq9xep4gvSP T0khpAUJGJpqLrCWakhmCZuY2SxaX1YR8GpmQ67tm+LK2xRuTNh0RG7PyrXL6D37gUJWmqHh pRhfCOAIbsScY1xK43MezmJ54at4fGh0OZvjQhOC19+GZbsnXQbdw7UA3pL7e8G7hoM7mS4E kve+aeUoPH6yIdiRvbyPpFv5er/WLLVyo22+B48J1iwhlJ5S5QudJglHj+F4vl10S0yauAXY BubG4KhOi25SR81T9fgS600FqPE5MqIR+gzsKhxw4V7exjhtSkosZ2vwvOfOGUmmQysbu128 J1hp0jQZtkv06EAOj8UkCyFjUqI4RIunlb1ns/BZwWg1FT1+iIl4278OsTy4kvEVDn0Jt6BE B+z8odFCWq/rgKol6ZvFOZBzznjw7iGbX7glHHSakuid+aORDhlXrXBBrt7Uebz+JET40o4a V2ldfCClXzc+Y16uk1azzLYW+dXtiVCLnGo6snUoSifbzKm4Vi9WGsvP7hjvFIoUB91/9jhv lGWk2IIzfI49d/E9bVKPmq4YcglLhFNp3o6eClqdjEGscuTOdS7XzpbZW7jfbSBPV6PgO7KI k5qtg+RjhZLjNjhKkAaX8JRxJkrXKfku/J2/86wnRiHpICmSAeu88XeucNfZlCoxJycBMpRf dqMNOuuMwaQ3QYUE+RDEfhtthr7BtdaxfTKj9wNZHxtHLGsgfBKq6Cqf4pN6tQA7JHXNiODv MfOHoDboGHDEoZJp6hxUPAYjz35VKxeI391geAAVcqYj08PdzFDsEbPOEPfhrkC+gq/jKVNY MAfj+yXw9YFn5/tBSPdY6PVj9wvHLQcepvAd/hI31xLdqQuI1IukRBmend+yAR3RCbNU+sce kpnRtq3TlhyivCLwEeG/tQIgqblMM3ezx7iTA5YvtXVJEqjfPHYdcclTcMpaMn0K4etoE5Er Xy6RuOfC6ovlIjTUhbMShapp9ommHML7kkeJTJtWFUc4ndifQNr84PIihPnJWiTtBhmHPGtG aAlYNfU1YCUoxiHWaq+gYYG8yoXNXU6Z4VkKxIfzo93lMlP8HkL1qWQQmKdii2JqthFQAzVZ RloGFXro8aDi2Oig2P+bPQDohG9r++4A+GmPQ3ZTlJiKhYTE+yjEKIwBDNZVDA+4clFrpn0B Edr0WLd8S43oM8yWRBbR1TdoVE6cm3X6VYn7qz5fkQoyikL5zGU5Duu1xFI4QYzmVp+UTje5 aY2WeBZnkugrF1ybvwJdkNj+DZTmpDP965E/2xVoQYWvbvWe1La3yOPE3Hx7T7FeJGWN4vBP SoS/W6OgGjK9BGGx6q+zQDqrhaWbNomPSQvsOGhd35dcfdboBel3NoQ5NEP6jkKkUo8J1NkW BBZ571B7DezoNtB/bS+BGQmRyPMROaKQVWSTT9/SbDjAGRdKBA9zZZBkPNihhaI4QJWCix3j 6Ua+MPBmdh3TTfVMYrTr0tslrLYvRIlRNEivpMIIloamyzLpq0xim6Sc8Eol1bsut9y7byUj 4tdpSw38uwKqPtMqQd9z68AlbwJIqCPFqkPO2pa8kwWNWQtxU0oU25Kf1s68nfDq00tY/Qir xs5Un/QYm3kgRHus/dQznuUjvbAA/xyk4g5zA/+820Ccb3bMH7nCbrFTAFOq9J5ySuqb4A34 yXLjWW9OXrSMT0xpX1apvbUGGwUB5a7oWlDcuWmhwchRAn66YeZ64nzV7odLNCuWrJ75qHcP pAXgrbtFSgdKDNhV3qxzzMZp1W7jfRcFy9Wfr+G7XgQyQFLRwaxNdhsxtX/oPG6FcPof2hsh Czu32h6p0NLpsg97cIgUJfIky+0ziPBrDMBJU65aoCX/yE/dgDYNl0icr9hvQoiPu72GuJ0v WSA879QL9rwf1CcGFUl7Kev231mdCBA38Pm4dpsBlEtwRvbgm2CPNKEmwm5a8PPSyC/Q0CFC sJewC/dDONgliwwTxxQr/2iTkHrBSX9Yr1AaMYNq/IjQE7Pocwzi+mPeAF2L6JaXZnk1COyV TJav8btqbzhQTbM7LwE/yDzyVZ8/l7omnY1v2TiZZwvtD4ISy9CbFi5U639R9nqReYSxlwf/ /i0cxg/2FiqWGRVwl2YoB8JIRlDv5bC84vI3kN6+y31D8t7cl3QOMtzohzUZ0OHoCCDJC8BF /EgasNidRQHIorVZ9BBXmsdyqJkrDOLLNLkHFBpgF1OE9tHdVxdtEn6lsa+MBzgzGwXoGk05 YdBkwTTe6DB+LJiLVlEPPqWYA+AnUKzQgfwlTtvFl83yuqNFmJpNX8i7CQAAYYSN79pLNO85 9xlX3Jdlezwnhf/9BSz45/dAOwmGsLP1SOsme+2Xo5OKiDHOCQ0ymN8SMEvwvHGiRremJZ3G afS5lJLtLaCl6FIMKfqGw6uHBMeoBlzD5hlmL8PTMMoNkUoqOhXT/KmIEmdy9joDuYev+eb9 NNy8oKNZAFiOI0cRB1ZqgmVmkdBSDsNLq1g3w0WG1Wc4USfrVSceOOF8RY9RWUaCtaelZPdz vVUiG6ePZFsRGHVcUg9UdZGBAs6Q6ojTsSBgL1/3cMvrnJprpYOs27VCCwZtOJ2+vCMbB0o9 20/BtNhybIKbTEyjASSvLZf1H5UySJfuezAtzvgcceGxxmsjgVDWY3L2VXpnid/QPWikveXq JwsNz8i6akDBteYwtCgmwZAT2eqrYa0RXEXksoYhOrnyXE1CyGPyqMYiK1P/GVuXDTeTp405 exsMiqNCstkAu/8jdKOiwmbFALSWIWy0PQm4NRHq2e47X6xP0Q97BchDPETrWfjNjcvtgwIL XWRZGVlMDTo+hbkm/2HP/JgydKJN9WZp/eUPU7Fw/4wf8CWe+3ijVC6pjVGw/FdegJybDnZg E5WuDJ8zgeq8OPPUYp0b0LsLaKU1XfWT3jxEIcBSsWSHwzISrs09KLJtUZJNIxrj8s+WigCh G4oYAIRQv1Z/ye8CAEI/js8q+nXTq+ZnvB6mqqdAviRuRwOEHVOzT/eLaF+ixjlH6RuvPeza 9NYXHRE7Va3NPa7gIBjY3/s44DM043445dK9SVmborYMLm+yWcKkaiW17VUxmbGXhYK+jaGl 43HZG9vtg0DTrKpSOVYWwwwKhjkD2GLKsCdDwfmhrxf85g6SgrE370jnBUBeOup36dGjThYN zuQ+o0GGqRUryiNQ2NfJrlOoV39UfNSKu2Fo5hrrBE8xLpG6wTONOKdKQyGe5xnHqDUwBGdq HdzXoUAM9WNbvwmeyWvfS9WG/GiMAZdd7aXOCm84iEmEq5UMHaSxYhuFcKwzvRj8o5P6p8Ko gXgkIHLJFEWqMmj/UwQxjcXyP3D5pwOCxjOnGOXzZ6OokMEyo3Z7smnl/Sm2+vd8j0oF7QBM V6N360umIukkDbnf1MYc7XbjVWoa7eNbkEArUP4uXZQV2YTtYSahArv62tUKE7zSSH0/KjIZ xWLiZwT/t02Qaq4+POzH9OB1zrWFBbj0bchaOEeQSwcxauxIjv7YEw2APe8REDoWlc5f2gzk OJxh5XnaE5P4Vwq8C+yA+VisceufSnYiOEUv3COKzLt2o8mhrZdTdkA9tZni8mo7BynXUmW1 Ktf8DQIFWcgY5VqZwpkn8B77lnKigTslfGGuf7t094wDpUtp8ilKceUl7+cRYuGvKRiSP4hI PCkbzimA/EakKFdvaYigFmI4lPBG83mzzRcFt37KSlnfJw9ugsV3tReEzBVRuulyK9y516b5 3JREExZ6GXlPyD5L6T3lsvVcmY+xCOYsinFUEXQZE/3V/SB8Vd1bxXF2omd9LQGZ5hUQ4KC6 /zyUu/r6LLun70VwtWh/8leXqmkB3mmytupfrVRNyyXcVORnrCiXtPxvAkJpgcaoj+SGBl6r LKtdBNsbUby7y0yp0dmLH4IaoOXgTZioZL1+hgtniPFAa+eiItgQ7Z6LuUk6jiPTiCliDmPJ Vax4CLYin++pP9HS3+r24n0rtoK2NCxKf3QqQXAJKc2ZTDu2FBxF+QFdDR9AsEKEsniIb8w+ 4aphW+1NxK93bkDLwEzyR2sffe7T0ksRnpzEQAH6SQZzMLXUGOo+Y3FIQv1orpi60JAbTRrL KB2SdHvs4e08j1jF7Z3D1lIFrw6JsbeEWd0pjsMA02nv2g5fVflMwGg/uWg7mG6YgpTrT8kX A99QFUDlXzVqqeFImTeub+/M0BVGyOfp/frOgYtK4OykbDEalhaXzA7UgGJmSRcn+Sn08G2a APZ1yMeaxbUEYHGyfbyLy4d/2cgAj9STqctc4usQfT4Q2CbP7ugMjisp6ozEVO0i4K29mYMr UgOVX/HHyv4Cp1cddGmRgue25Mpdxb03JDo0pyS5kxxLAQ+AAmgcDMNuyo+jn/1v2EKjXzZP CJ2RLYyVEytsOuyjzjkZiJJWc+zem1EVxdVeTuQqSBkPj1bXY2F6s5s4jSJGC6R35BFiPOAb zbH+fAt6Vc1BBIsBVYayT8s+QDnDaYkXRIJNi3pLPr+a17l6cUS8tAT1/DtXlNZ5LaXnesn7 1kGrSp5JaPumNsT2k7AAQsyzPyrgfrkfIbTBN7YDNiyp5dyvELo72lQJULPwvEpLg4M4dX3R Bcc3CFJbUpRHfK0MLwS9jBiVLkZ9ihqtnn1/GTMyODJtP4Chd1RwQ1AC7BW4UjEenBfAuP4a HrIIPWw1qY9KUOhfxPqTtmcWLg9ngDcveuH7Lja5WAGKYVCoXARrj6oooHsK/7bRNpeIg+Fq xpl3e6zvvzr+/s5jGhOor9bYwxNIOIUeFYXnF5ku/m8a2Mcsk26i/0a+BP17MwNpcO8yh/WJ Tl2LbsurvoE6RCO7ivH000WkDf7/GLMw395Tab+Newk9LUbv/9ho6PFRAjHUfNJW6uGGpvSR CXjGKSamoVVQDYPxrTS1OFsbByACp5RG1XBLs76q9ZS39HvUfhmgc2jrQEghBOMDa+fC+Vw5 KWTXNiqIrV0frmjvQl1pAKPcsodnYfHfqxjDswxpYF9Y1j74M8vPBX/2x+fHYR1UH7xUojZZ +ZTDexV7VFxZgPZutErENX7uP/HSZramAB/a1dfnUlhzNK1BSjesjCCX3fT5gACtKaZXfZYs dJHsQ/CAXXHchTlQ/FY6/A4e8xI1nIhF4B9WB0/k2Rs3Js6kdXZVKqCJ9QwoXI1c1EOesExl /K6VxS3bwaQ3ulu0vhoUuuwdA++ExUK0vLIQ8qJnjC3PnUg3koBJz86P0iJtsXcG3w6xS/H+ zYXJ2jZkQBzpiX+axF6Ze0INC04MypT3XDbnulsf+RBA2RMYBokHbIDxjcXM6aa+9A375lWq zeztCezb5E/GipDo6JoO1MBXWUeNIT7qT9S1h1yEXZp5XH9BdCyJTjlpa4JJHepExCTcdOAx gJvntsvI7/6WspB50jQoyPwtiD+kYHX5Y8Y6Ak2OY73teIQXzrMMNCyrkIchsvdsXF+FJkyJ pWxiL1eSeL/utVaiMgrPFySOv5o36cYNcKgdmwRq085zcCrT6wy51O3BZNhh0LP9t0Z+ysiq bHmtAJoSfY2/C3AdYOC+QnkzmIBmbrB3f+XtYl2Y1pUQEkGTLVe28DKy22+sRNF8TmBKmDDA RTrz749BPkgxWKb+ovxzm4H2P2wHVhezxCBAwxVwBUlqnFormxLwTeOvznXQPzSBSBXb/pHl RVOruKxxt0ggeZwz5OnKa/VypIxlKKs2idiY1hlbTsgsPh3g+0gh5zymlMlOA/VV5RsS+UTq /SFeWXrhm+FdlIaNJRDPL42Bg+PlhJAn27cTCr4mvSXRkcbVg66DCOqg156OgnUGDfYZ8nDd 151umInxFMBdpuuPOVRcw2rvEqfRbOMH66G7tS8A3Eh+kfUeK7BlYtxC5YKK1zwggpVMB7Fi zZVkS9AjC2Q7DwQ9Em+e6yg6KUUZYQU/MooypUPX2j6Q4WGObCAzsNk/7FDCtNBZ871Dc7/R 49eYnmgqnNUv6acyThcyp7zTjt71F3PpNiXvXUvfC6gi4LgcFiKdJR/7qhs/qu/ohYkgLg0W cZpNrTsigpq4GyhB3Kc4gR/lMCQanqYues7PCNrVt8C9lrooOHpGNIaj4ocU08SxxFEvL0k4 wEmJoWPnmw0rDlqTUYful5w/Jo3VSzkBl1lU4vsBxXlOSjJjH0UXdg5c47UKCI/1Ba4P2tG0 MOb7HMXyU3BLUPmQx4E20E5U0Ec32dBVAs01MW41fW+FAkyIAFU7akZkwTT13aHXfbjrARj9 9ED8Ld9yT38pmvydAcHyyTDcnIKz4mWk+GoGGgy3f2w4tP+CS+0vJvp+PzTfAQvrarIBeEM0 HNLW+XxZ7kUfSTw1DuETV6PqQ5AITVuA4xiM3DJ2FqIfc89cEUVigqkyYfwWXY21X+dIcZrT EvJOTXKYrQ+abQoLt8Opg1OtB5VjKGPi+YJ3x6ZnIEaYau/xyhwFWliBOFrjpMHfqRittgZW xCrQPXABHnLjY9K6pCL9+AlJJwIsOoUTrFABWN3VXu24vPynUDQ2dCJ61Tk4CG5PXL8vTeBp 86ORpBLEij47T44RtE1annPpyuXEpSSG5Ky4mUxE64AKRrWK4oN34DsAe9PONFRqlIIdBIV7 nj18+HXDEgBmqNz1reNmPOqa0E4iShXM5P7/+yVbe5hLOpFxGoLBARVfIX8CHldtpAXyVJaB IBLkWr7laDL9tSJpf1IjgpLJ2DsomgZuBglsDFDKy76LGSimD+a3SRyiTYxhacBPTrpUOcUH OqADrjZK0n7cRfrPkPYnj1x7VcVmRq/4DVeR/4HxlB74tBhWKxqJHe4wx7t0q2DBCwQxPPSu 2bVW5F9zQi7OOQjfLrS8cZ+bXt8CSR6gNCIx7cKL8CFJKZD+q18Vy6/zzsH+hItnsllhxAZG ezq/3c4HnL84S0nA3czdsOms3Hmh8Sxmy519CSY/XsXA5up1fzLS51HHErZaYbHUHvTAarSw ojQmJRLWjK6x2YcnmJoDFVna8uY6Ev9Wk89LbFMT50+ICqHvu0DKX7kqxVz851/1rli/MFJ4 PK0KIIt35qB308mH0xysEYlZj1jrmr24PGxS4jzsKjN04ulF9KMekxnlpt4TU5AA4wmVVSc9 RB5NFyD6+T5j5EjvjpRkX60/NrK/FatCHOx3w1SoDbkI+wm670Oi5Exy36qNPpswl/y90MpC wRLcVMg6ql+UArLGRxIVm4w1p4K91gz4BTOBnpjJeLj2R6i3V2YSb1aw3poFH81ewjqvzpLI JF7gM0rguCyqG4lu5wrViRb9LntFqtJ8PJLnR/ybq1m8StTImSXR4CS84F3fLlD+mUSIxCHD +zdAkY40gS4SPfLFdoQd1ER0KxZHM76XI/XvmdF8NFVJuS1uGAp5m1vADy83VVAkr0d/v7RM RqgQYMTWsdSeOO4NDETkuYG/zyZniHGZeHUk9jQSNx/PRrBG4Ye69go/nr/TWGs2wHjH6+zo m2fGOqkfpLGOuk8LBvCOVZZEximmjDUHM8aDH7yA0LCPfaA15HYdiu1aEI0CTtXNBVIeo043 b86joVUFxTEntd5eIISjCwtSBFIPU+g+nsLUeNqrI/52cFBtNaglclQ8GN8NvO9ZzpEQKwgi boM+ZZr+/f3aFn+mlbHjy30PmrzqjdT0TIdHUZA/kdYEBQnR8gEjVweb27HhHmYw2iu0lpdo pDaMj8WoED46NO3+w9YxEzsGH9yIGZbk5kkaBAi5RyP78OslGdB5MhA/K68gMcqCMu0HJEz1 XSqEwk2i0KfDIpTMPUNT6dykkI8sdU3YMjPz6tPo6V2u+IcIwAC+Y6LgoInJkuzAHtmywJKG +ON0xXAJy/vkvUeJiixRjGkPQFuMaKqHXybUf9mVucubScH5Q6U9vqOohVR1acf3r+zP4REC 5V3ufpNmqF2q2w2wRFW27xRQiY6rkqNelCZticc792wmPuU+04lORMx9w19LFXOZbxKvH5Z5 q8rXZui3kRRDK0obifoSAhrr4LSws3AdpOeJ6PdGkhpqeT9AS1uPjDXLKnKPxoCmYU0prRi3 zBm+3oVoYoENWs1oAbVl82axOvEfYDuBcfCL8pIKerCVgsKTcY8BOscMpMtFudorO+satXHi WOdmgGXQhQSd68MjTT96lFKqC1fDSwarJouORO1kJrOj2RIy+p2VHd39hcphcQTzMhXqKqdi R3wXj62eGdbC8wSMsT5wXi3TAyeQjqZO7wQltaaJmrYQmb9WT7jKnE2LVfz0qv0uPmY08+in gXyWVRfbPqJRFTsa000xaxZEa8bWgBn/ALZDr8rDbkyym85OmZEv5hoWuWj+a4c+FUsYYMf8 KX8LLubAFWzYoXZE1fRyDMmL9zZ42g/Ilz9owg9KyvLJl0oOuZQ4/kkRkqTbhco9/J71F75N f7KiKMY5LJ/gpVLb8GJI7UHRFLakXFr5BKFhgaRz5FC3Kb3Hv9gTdinYGNj/9fUwDsvZcF45 XtVU4/jmpW3RbYzV8NvG+HB50/vyEWwlD6T79R4MUFDm5Vvy3kI0DAXNR5hGYzTNtfkmz8Ju vgNlKMw0YndzCfLaYFRdUcx0PVUH/RG84az+wKzVFXoXx/XYwSehp3u7XgqV3nL46+/ES8gK NMwCpJkj4378cTlein8oDoAO+L3JDAxpcjwJLuxQ3np85dr54TNq5TK1TaTI/ir4Z7IzNk4T HZN2nB2eOokHd33x8axtBHDc3cT0g02KOQJjOl6VQmZLDn6WcVSi7Hax+whvl6bG/yKO1Bft QlU+4Fs/9RGKUuPnGRZPZA+94o/Ad4LhrYVueVyC7Jn/de1/MohZEtffcM4oiKSTZmQQSwRj QBzSD4Pz8gEexdTzYxAc7+bNzXBZytrWQuO06hy5F8SDpS13QD7dfvzkczZaBCT4ZycxzUgF FTNAG5UesSSy7U5g+eNTgfpJhB9RLL8BaHUrmxDifNCJTRxM1Hy1YjhSCeaR+RtRFxDkQIN5 bx17Xogim5wMf8g/G/9Gx8FMqvmBgfXMqUMDtwyJsi6PZVCtDNr5HhXlpYMw9tGYhxMo7IJV yIJ2+nNgv/wRw+dhz5wiUQwamonVXn5bC5kf1MRNd+9L2NxU2nwVrc6eN694DkwEF+Q7qKG0 AAQTsEt7Aj56Puy+eNBstG8j4o1qmcepRHY3DDD0c5X3zm7ukJP+5anS5+XPBYOUJ8BD0zTD fnUbw86L7UhiDzfDZZoJOAawzopyaRpZof29RPHwa3lUclXfII+u529qWGOgoOnzs4Xyje/3 3sHxovUAvAFl3gsuw+rsGK/RzgWdDiyopibfMzqZ86KnKUSS5rgbXeLtIP7YRAehiMOUi8EO 1JdT/X1ogD4zysf4VjS+89RqplLKY7mGhNRz2YnxkgFnmapcuhhnqevU1ivnv5fmACbzdn1y 6fVBq6cURtES/k7M7yTWs8opwG/culy8sf9bbJivG77p7nDQnn2jKUMHV0Fky55xr2XJp9Kb wofCkr0KiQf1N42YFuPWO2gTZQ9kIpfLNk+0mUqSR7xU1zEDkbJvnO0GowV5GptyCNO4BB0t qNXaRKcFPPyBvO6H6jg3q1VBGc4b/TIAyYfH/vVla8WWKsqraO3lqCK/S/YVatE86FIubEtT A+TKSDs8pvgE8nLD1ukvlZNax3/Y085gRsWpcAe+pe0HeiuH0NNHm2VqB+YPCznZif+d1UCb 2kmevlhmdIcuIa25YVHexHeDd65rbkjQRnmY/3Z1wU/66qHz93qbf1V8jf5dzi+xbI6OxFNQ J6ZXzlfPmFZZ6coY1HvAoQZxKoMhEE1PmoRDiZ2sNIPpFvf9QrGmZYleqFpIcZrmtVWlTWsW qeItmnU1GNSwrarM7PQTQpatRysymPMZoEUNhkCi8ZTDMfGHYHiise7vY4Pz/xWRiP9GfxoC b5fZy/+uq1+nprbMZJaSTgYVc2MQDKHbJCh9WyxAHUcaTSId5hbbPqC6iiSfVbW4lvQGSGKW dgmHeIYOFlmnZd9xFTZX5/B+MwMzMnWO30Rgtn44WSufONFa66HBT31PGARmdvjdQ8GBsU14 nZBIz6VYw5hkaaPSp5ZikD1dyWodNKKgge1MYzq8dSBbq+WHJFaO5U+3FQxnm8qaaBMEsiQA fe4Tt0i+srXjp02gpmXPqlZkqXk2RyfEBbYBToPmvEDeSYZFihyeor6S47aTLys+DIIY10pU 5XZJf3+Mkdu9F/K7xwtTzt6xzeoIjoz3T5B95Memr+oUz78DQa/K4zmMQ/tch/J5uwBMYKmv y5w8IqBGPOw5PTFms6yyzBBPKEgGCNYcPJxk8rztUdw4AHVfYUg1Vmjln0/Iq+GoZTwZSYtb RYvXl1r3TfCqCgB1acaw3lhQnJVljreQtMdKfbAEbOmrxUn+mqFtyyty4+Dvjm3V1EKhIYWP wrJelgRVAQLIkU+mhJuK1Cd4KnOTUjT3LjPoAlMNZttUzKtvtgZVhwjBN/yCMM9869P9+bE7 V547J4rphVU5bpxWjQyUdJFiKDgdb6OuCR/LkQpha14EAkNO9WjoDKb5+y6AESktRjV44Fpj kVgnm6zuJoamAFMmxiiXB6QczTz7K5ogFJTW8TENSEIqS7uljRx5Mt/ntYukCfWMw+Mdsg7R 1rNJU+4p8H645zPaH3kGpOr1ZxEGBJ5X+YnFAFBDv9L7C9+mEdCoY8P5HfVLzlBb/Gj8uChw 25UAwlI6/BqkmJ94AJrISloO90xPK0aEMCV/CJ7aNT4j3HPc2ZhIB/7j3xG62ZX96Qx4R8wE E08xmE16cf/YVYe00nJdytfbSCr9H8BGOINT6ay4dB0r1nNpMbdEH3WV7dLwvIrCgcnFB8Z6 DjSF1q/F3zPL4Ts1dfcP2OeSGZrGicJdmgopx8/WGARn7lIeqzsdLqkM/8HoI3r4PQDtEQH7 wnMGw2O+fzHO2utrc/KyEP+vZJti2D8U8j1/kiyxtuNUZwdH8qyEBULBknY970s79X0bJU08 4ud9NiB+WDL16rljqI87U90oZKPHO1HOsQ21mEnJ7OoGs42xIFQBPU4E1ww4b11RtsGUh8tt Jh8ZIzevU/5PrxAZHHC1fQXGD/E53ewf3tHGKhgF2CLIFAenHGa1Wz5qEOJEEmFIOfHyxmAw EDAsRiWENkLy4ItnFBiLfveoeRrnwUjNCZInfOqeskjRBnMqWwKHA7qOcJEUqDdQ/VQyNYmU xdYZku/vMsw9FiICQD7j/jij6mvGBk3ywvqvLzCXYoQjfCBCZh0r/s/s59TrMAApYqhHQhkw tOrkIaMdL7R37XgDRBURRsk4rWbjZqyYHQpS1vlR4SGpxl6xfiavB0tjVSh7uk5CiidsAvwX 3zcFUBrxehs6eVTj1L8ruLyU8T2V/cfwqAduzfUVvRHr+HQWdezvUiwLeWABHxNa/3O8Xaio IlYUW5l58A8NyS/9v7XTnPIRujn7Q4EN73dDgpnhT+PmRhxmmX11vrPy2Qypoa6UkuATlqEP thbmU+1QiM4r9BAUQ0jCBqXjAqgwiwpmfqCZ7o3KAz3q7Xhj7D6z2OihH5+RmDYLSLe15HhG bt/+iieVqH416qCTnpEcYI8+cCu3WCIflrEzKNQFJLx8yGYMv+His/KmyTl7Jn3WKwgs+CDo on1ZWyh/77lYXzylLCIZKDfrOEWUMYIqnB852vrUT9ZIgAq8cG0sowI30L51CYG/5AJ/aXns Qxx8Q3KPinqX9KZwRM5nyiU0Esw6GtsUiqM5NbBE5/KhNJ7acLEIfWUFSvdgwEFsGL4UbKWB xKAIqdOTsUMF5+KiernSE3sSoT0VIemAcGv6gPH3rYkX1rXM2mM7BXeJD1o0EkuA6yvzs7sy dRUO0GuBuXol6S0+1xuh9qltLcTrfDzkIOmChJr7gZhvcSU+4kxQyZXk1CAXcX92p/pWtYBU +ASRCC/7lPZBatsDyKyC7dbm74VznIsgmi5ibB7zW5oVpxNJzX0not/4xKV5EWGAaecgT45z BV1ZqMKdhcWHtaBNzX3H5EvpHWSANnTyTqZv6QQugJTjfeIRD54K8U3uuUHzkKLhr2szfLev 2OS59IyDamgcQC0X9SJYr3SrPqMrFV+60/Y7OMPqvyEQpRBjzmnakhcNMx+DK464o0/0MYOq ivSkC1xrysCSXBNdLoJlODkVjVsMi4Xk518Uf0nGCaqO1s39UqXsJSkMP8XtCCIYPIEzJfaJ nBBzfpy6/EB85ha/6zcUD0FP18Hsi1017Yo7/Otya/RpmIsuY94U0oqDbp6HxNgC/158gF7l y6ROPu9Nzmebo3u0iV9IjQFJzZTPa2qBNpXE+GFxcaMuuGtWzaoBLeNNim96vGqQE1M7b4wl w/FZZRkQLvSTA4H7ZYifGaAEYy9DMP4xJ7ZWCWkkz3MPWfHX6eSs4go2AlJtD4O3dEfudClg X7FrFf5HcnlxcH73zliRVDrCIlO9sf+0v5kq26pLgM+9Os1GH5gtwqAR/KgJEFgQxlpo7Vb9 SUTS03wce/A7k4pCIi7NOXYCVCxUv/+DAR3gzf9PPDy7HCdnwb8uNjxWLB0Axx+ugnAZoBl8 UKlYD+/GP1JbBEK7kfukmlNz7wzXYwzJTCEB+QDWx7kqrG3o9/VcvlFCHD8zNds/1isGlaem WXctL7GhhZEH4mZizTwrV+vIOaOAZLoQ3bBZ7AGAPUozGUsQA5cnRFL+/lxKYj30hKotW/c0 ezrKZ/4ahG+S4MBqPLzPSpjaezVVJAGepo3RwyQHErPqL19jCQT68nJ9xcDJuz7jYBZ4LQoh qCZe+MXL/X8JPjmcBrnm9kmIQJmcgVEl+iSGyL4/0yAOz9HWdKeUFwWS+V/1cfWcn1I+hIPa THiH/87/b37COOue9UNXEeQL4rwcCLYn9sf/Vh28keZWgyzFpOVi+K9sANPaH9IGBuE9tvox iWcZp/Abs61Nwk34joFhzLsABstvptyKM5x12Eqn0xywgvkKwdqZfYLDcKrewSCuwYi9HmHj U7YP9iS+SohfYZV7oDT1YxbflUKSg59y37VArv5WdKyWiIn3t5ITHx5toSGbw/05eckSQ5iX m3ALwAw9h5lRbnGj6a/a6ve0fqxH5t3monyJXfmtELk1zL8zOSBToFe1MSct+QpBEhsywUwf REXZiO6NvXSPSPmrMOLegRnv+/zI1g6I5A+MXmwRK9RjDll9AiQmJiGzlzzG9FAxEyGgU/Z9 fpcyu+NKpTDrWggoKVP0Yb6qvCp9nS5CfibLGU/X0NpnMRlxx9rkb31LQCfhu5zxI32ehRD3 ONVJekSAtopDtQ+nRAPo35Yu6SBGfq/dAT2QdzJp7UtT3M9NM8LlYv1an+RJrI1iseyRH/ao TtzXhLGHmfnEQFl48CUXbVzkFxIN5MToohmt1v2sv1Vrsj3IP/RPhAdn75Fd8A5Ujmj1Qsn2 8aOTLrBYpnhp9LEw64Sfvnue+Vs59HTUldIJEqfJS3yKNsNvcmlRNL7RonIZY5VgM/f2rEbT IRULNCcm3u7ZjwHyJRR/ltuz5v39DWuWseVohh1CXpgQYpMGAO7Uorm5FOwHwAiGTGKIy+zh /r8tTOdtFhovcjtuwvtdGNy/ETo+LhtyhWPX/cJCLDZVPIrDisSEsoWiF1jQqFHxUFJrqufA E+x7jwyw+g6ER5f/Zes2Jdm9W+te44oDGhUNtds1TXrSxhiGEzZTbCCpFJ9wefJC44VZ2XjU C3pzY2+emL4CU9VqR/CYznBXDzxqkSQXvik6FM8uHBuepvxKJvY5SXqsgwgs+hoOiYuBMtKc moPKk1irKbYuWMhZAAEn7+aThAr7tlZGZNH7nTNbgTcrf5b7thEJWQgnTsAnGGaLY0/m1xpJ y4Je32zPX1QzKnNjSCJOGcJxnuadlpfz1jUZ085ZkckFQmITrVRKi0ZIqerbgIKcLounlLAb SEeUsPnMjAdVoRfmiidBDrTEfIQdrOlPBADzqxpxHU8G/XFbL+GYft3SowTEpxfj4pWAVP+L /rZESC/S/V/xSh2q/zzm8DvwQ0IJRda1CM2dbMJR7SUVHIobXX4x2Phx1Bu5WOGKHEBGxeNs Neo/XLZhKWI0NbssxtaMOgt1t1ej9F9N50rObVqgyQBBf/K484w3eVBeMdr4DlzV8VUbk8aY XWT+fEtOV3Vm6RXpNg6248+vs2wtPRUDttj0EHAvN3OaKV+RX3Z82mFP+hJocijYZgOS4HWD JFQuKIVK6KqyJZP/8E8UxZNY0Q7wNeGRk4qC1qOSGKte1iFkKi/YSNaCzeQvxEDYqZHIe8Ca OCa3gNtn/nXY3yHq/mEESxk6VSNe0Ijw3DsxWLRi7Vwle1Vps3KkNewnDKFp1rOVPjDHr2U3 iL6L2Yy1KJfMVgHvDjBhXJ6xMonJWpj3661hcUIVPyi4q9mj5SmzFdHSfOonCM6dtBGkgTKZ lsq2VqsEgZDA8CkhLx2IUGgMmQLorOPRzUccSIwmvO0zUryMyEeKNRVtRBfUVKXcH66wyNXs 7xdCUB4phumAdfnykgsTNJqlibJw8MBMVs8xBgXQuR1u5TEZOAKtXmxwxxdEYzOCgkNddIyM DVZBw8mpm2toMKL+PBQ93Co5WXOnVYaABogUGu8L+/HxGKNaLpQnRmER5Ee/BNSVxRiETsto Z73CYlgOYYb4DJuegNxQxEz28b0S1lJ3rgXnA/S535MrLZ/bi8Jzp5s9pdekgBy/yUnJZWHF 6TdEFxmPF/3PSylpNn54VFFk1lyNUZvwP0GkWBKnbcPyYXQy/XnVNmm3qu8+HrCj/gwBg4cA MOT02Mc5M95cdASH6Jm5/zixkIHMR/z6bbavmuKY2j3B6mRVTAGzcqQZvf58uyXT5Qfz9rDD TEVAhQYSkVY6wPsnmhuX5HgDQPSsSy7et0NsA4rTo1PCIztFbuSFqjovCI24uMBp8eoGS9q7 OrF+hCSlfaipY19DS48j+qaOYesKKj/brU5cyL5TuUYynmua5Mbdg6rjigVnsI0N/cZPiJvo R6d3mXM2Ho5OPFogD1fj794axZ1ZAM4BX3NcnPYYq7VYDnWg28Y1TTE6fJ8B2pvZH129pyKk NdNs7iW9vYZTFueBJmk4vDFzcmHpCyV5h14yZKgnz2iwcdE+go4WCmOUmNS4d+6AJ5REuMEV Vb53IOphL+EniljgS36/x4UKsM7ma7A8pGe4UVmm0m35HAFrDeo1jtCFtkSXcZ7hsTgGUv3M YdO2QQkUa0jlR4telfDmXseMpGNZnyJ4wVORaFa3bAFgJKTMdAsOkQKFp3eCHsbvCwWQjII0 KOmjL2J+/Eb/oKULzxsBSlrvNThCZwjnIU6NCbYoSlj5ult4WhrcVAfaRLIuqQYZkrm3eHxb h3W2KUHCRYA5QoG/Pil2pGfnX7FONyzpiSQmp8QQ9gx2xFIOrL+/KKWTowEu0hrxGxVce9NY MAoGAsftxA8tYsLylqYEfiIuqTyl02LKf4fY5fe/ta0MftpuEO70C4NPhaD+E3jXy+/wk6Te k9Xci2K+tBcvZlI5qG9/UjrUEqz9o7ytaZb0a9EEz/ZrIMzoIODuZUun0JaPBX1u2crpohhV Q5zTyc4aXN/EOAe54JZahqpCUDKq/yKZ1vzXs23XLyNhGG1N4jXdbCeSva5lZ/ZtDZBitbMG xwwzkUZ84pdh6y8OTl8VQYY8FVAE/e1P5v9br7kd5HtjZupF6O21Pwmg2MHMkMB4A2krOQGh q/Aim9DRBCYCRvtfnjan4muiyvdGj65e0t7QPouSiG4ihOUhye4VZvJ0/2i6P9Lt30BifWgo HTvh3YAmoXo1jDd6hW/6mNgjDVugiF+5mI4anDuhLQ2ZMUvdpTv8vUTA/IVyHRMMObBPvLTM 6iXbkWy71wgGfAASDJ9e+DrXZUmK+FboYHuNKr88q7ki6UxhuryZP3nDFTzWcCDZOVMK+5Dm BnYzTLh3IGlQASqnSil9irN6wgZNqcoPSMRzdIzb2S5R/pVRr3L0O3/q+TiWOIaWr+0KSgQO iqJqrG24Z2RoB3EAAFsY5V9o/k4zS9Nm67TJG3xRT4IXgNfMAR9TN7IBAK88HdeVgdjlxxRq wAWLHrNnvdg0vdVtnwb+Q9JsLuuzVIMkasAyfj8FqdRYw1CJ6jNpABCJLGN+lQo/FSRqnuRg xsXEEQYKCwBoYxowjqZI1/AjDzw8+E9/mqfKLTygpOOIF5afbjjudiQ7B+kZLe+PT9pU/7xX wn71y2A7RJeH27R8FDeuejT60aucqqEkE53j5dFyytKoWcPqvGvAyGNEEt+OfZSyCOcDeCYm f2IeyD4OtcEDGkeshfGfoOyUL95ki4qX+mpobrDBLR0RA0pGUUu0shsbKXC8fRt5hX9xKDLC wxu4hFJNW7UomoGkPDyV6BiHU6DtWG/K78JRz73mYugUsflh/gLRG/iN6nK9wF6XQfTBn98I nt/Fe0eQ59cFlT2xHxwrTHTDkqOgtyqljDiWVIOR3AEXoONulAjQSh3qZ5sA96m0Tmk2tNuw cSV7mD7r7+bTItqbBLu5/usKyqWZqBe9XmcoU7sWotLEbo+Gr1DNSgoeWTvLyIlzL4DZAEDE RoVSI95gZkLugwwHiiP9jkdIdOH0+olMW4AvQ3ktF9RQ2KrDfXflAdD62BuKkZidHoBgI0+A PJgICkk4aZoDm8FobTz1Wm4RgQPmLduStwUdIvtMw+OkKmRjCHAD5xE+PHWNNQ2JO1LcOLmk Fjp0tXggsoFzI2zWn0qrGp/Wx1c0+1evetvYdST6qqa1pOr1Hi/oGGCQwUZa61TbxrDXz19d C2fMdhbrAt9P7GqbqJkHwOZPkwnxfKjzflTBoFzH1DbxvwOVLzLWa4O4jKHH5JFW82KUvVQo H+ZQ1I8PwdCDKXuyjpIqtbSbCOlINjdcR5t0G33JDijt4Ted5BUHp6N1PgGAnEu2DKht80bh G8VQtCYfbCVJmoC/pCpM6Y2kHrEvXm+RJkrYCHFY+WqGsHn7kHhdpJ8MQpeHFQWZ+zQPO8Qi pdycpWCvv5SYHmrxPfv+K5xhE5A+UbRJWvLR2pg5LZJ/Vv3ubBpWidKaCwcE7flNM9grCK0h nW/sFp313KeTlgE1hhzJgdsswHWQnDORp34ppCo2aceIHIyagpWSLzdefO8ok1HjqS9YG0i0 DJPHl5Epz1TLbDYLO/XyesMrf6I/Bq6NaZbYGw+S6nG8zWB8CuriYhgK5yutFs7/uLSrcgb1 d/bkkDBbpxzAiZyqjpNibucXDgT2Gi8rNwaUhI3tq9S1rrRfiWo8phPoRDX474ldIu/fQ4/s Mh+pko8s4anA0dxWMxg7gIb5ZzxJ/R9YU1ZbVjKU6G04DwhRoSt8UGjRhym/pcGHCh1P/XQt vqxmWR5L9k+YMtVqKaG8MTFgSlO0MKSLxuqByXLh2LdDu2dsoA+n36jbzwFcJf0daOX3W72H ETqKnsY/DZrHGQRhDvFMOeqLNpuzxoyrQacXdDfd50Dke+s/5OA2SsBk8RbHR4Rj31O11vnZ EPvhcKeA/kBzpZ/jkX1ovMYzKELdF4LegSAbOUc5Stt6b5AR6WGJJ8djEFalfCyxbipE3MTp ypGA9yFZaSFciiWIDHgcgGru8D4ijau/nrQ46c6kTmhnfBm2uFCkHdeMxoP49h3t5rUxq+gc qyih0lcVPXfGn8u5V2nHpXgd/Gn4K9VjpGlIb8mppyDj4OBoCdF1Zh+8tUeeerBPoJKJ6Y0m 1h4ZBF8IkRwUrUK9SR1HPWO/+g4TzrkEQSbULaGFt+0zZMqr4NflJRbiO22n0+JYpy7MBwvK BMc4XiKRfdIq7yHdc3k9fGs5vA0114QeyXEHknE6ufi8vR6BZelFpmhNMa7L6oWbiT2BcK4a yR7atGDAIsgtHjH/uXTfmyjHxnCdAwKAHfSkFq5O66htmMC7tMAI7R7h3Uazul1BmjVlviVJ 05+obajKhI6UDgrpR89kbgYQYjNzSXJuXVR1uT9TyZAjACXIkTp76Ja4XWpqY5fpicWFg7V+ GauITExCfodmjCHuONF1Zau+5nto6pi0btfNBwi3S73bDNcA/yN0A6xbCgkGN0JWBW14UMyu M9hJJuCR3KFnkTi53CeWodNQ1N/Pzov8ciozemVp1gVwmc1+CivxbMaIuRU5Cgl7qlrtGZ8b 3YrAvXXHRbPWhix2PjJAj4B6d9fQD+Ahfi5hw0KqZMQvhvd3uWLT6B68LlmhBOrgvaWfqRy8 UW+uprYH4cXydKQNZRofz+M9GRNravtoORLN1szkDV17HqgsWi5wZqNyizHT/tuLnmqKoDPs 70b0u5Lm4qn1NdT63OZPZ1zznhE82ln2P+Z0PzWKXTyUGjU1G8273/n47IJpbnSQdf8niXuJ ztvOxJdmcubyifCxgEZkkWA+8RCrWxHKNsd+BNYNcPJroa1Bbo2IS+0AJwTnesGqVdcxE8kV gu2cRlM5yIv2InJMmB7fQEH794kGJMCXpokPsrEALNpmJ4eZnJvgWeU6Xcvw1rDXqkw01KJC YWxoUnEJIpf27ggPEjR8R6nbHYJLKwF0zGT+iAc6NYn+yQkS8x2ofqf3vXxr+QTtzF3t8tXI uN46tBDWM+Ri3r+sRPQyLTDIMfXdqcVTJKUgGphgcCROc0/qSmZpNe4pDHI+eZeQusq3s8H0 US3MHTjd3IHeY2DhGxexjZhTTBndhhL00oF9j770Nk+6J4yjdg9p+o3AMS7iK1tB8bRpJK1l jycVLD82hR07nKpQlkv34kttIvDWDgDuMCjsSuMMWWWRW5AjqCt54+PVkl//ujGI7i+9xXlB qKYKv6KlgfggW0r9w91rZtkORdSCoGggd4WzvAseBK9N+bhOY5ArUQ6DEXPNcfrMl+UMTqRi 69HPDKRBwvkiN/73YzxBLmzNkElQSMl6m9hN///uu+xcMGdxkLT40mKCzT8vXhDdjd8nEwdL T+vDC1lv798yFs/ojt8lhuDRJDbLWZXmYyvFNOfhpqhNXFTnq+KO8fkdsTWzafCkYORDYFla 26IR3LiZi68FhIUnyTOB1McyOnD2IEvaheENmOupzb5LcwDdd+zGFrYijKg0sIEztg6r9UGY 7xNeCcADk15qHo6x0J/zy+R5SHrMnNBytFXuJbun40WYyP7OHHYzzJalgQTgQBcWCoLgxTJN fpvrwNZXlXcw166dE+XDn9NNKzNVRICdspZiIaYE8p1IcUit2HomTztKxYirC7cf+i62ePxM oVNFPFpPRoj3yN03D38ZWaDMgfnVZttWY8VpaeR9hYKXRprAYp59NrAEhPoG+KXVg+4T/kPB QxVCoKWlA7NCP96mj6W/oWPFa8Poo9FrA1ZeVZXcqU2ul7bRFl6fY617qM9nRtQ5Mg+27XZK pPWbRoK7n7VQUfobazmf3tebMkUjzSeS8CrUBLF38sfuG043CpaSHF+Mvuf/gmljMm2QrmYZ 87ZH5YSDoZYvZ8hRer2WvbWtd01sGjPksa0dr1YzWtEQQfUoBT3LHDTMvUbIOrqgaYszBXrj F6TulrQvLuMYmkq6ns8eRD+DgK9qn9E6IyHWzl3gcg70pfqMk3IQCfBIjFMCgi4S05BUvrtG frYYzZRuP3TU/M5M8P2hbqtl8hoGcJN7gyeQ1/9k312zX76RQHooMqVY2R/3PC7zo6VvFfJ6 cFsveEWNiaKHa3GoVhcmnRwmGmv3K9dqc8uwF7bxNoxrN1X+5F6yHbt7cPvcAIY376pOeSYn EVN+Dry3E3JbHngfx2LR9KuoHj8pzAQAe630vSMkNBRtpaiLpcPiWZXl4wrvQ+BHtTYC8EMu 1tFP589Vnf0Y3q7fJToEATAE9GSDdlqz3q+FdYvvpcduPFGVsJgC/Xg5TqLzNrvsFd+nOebn NlZhzMHzXdlnAc75IOYv4Uv12Dk2V/dsZzi0Y8aQoFFn26ZTHgAYWJhnnBFFTlOlTOnxXaSu LJqIuKBhUv26kH8BXUMfJOTr/2wQSBbjR1Tn35ClXuD5ByPtFOuerxi9zaQQHnHzDwZtO8hT XIj/hXDO0Kx6ToT5BXwsYFysxfBlKcLGkCeX8JwbfV1nOXggOjsknYuAo0LE9K7MJaM4CEKo NrDRdq/uF3DdjR4WjJUnDEiEGi+A1m+jdQCxWB0CK9UwNPR1kZk6aK3jQMpd+IE/SqaaYGBt se8YgoyeUnuMNuG+8HpFjUsQxuAuBz6HqzGfHNzvf9b4A4iybuv4VSEc3pisrjBaYV4YjpAW 6fpfpvw1yIXFH5/tQ5j5p024J9PLj2b/pED4Saj7PYfH06AXEGQB+y0AjI8YwAd1IYhHoOFB qyOYMJDiRrUnCgGVZb7jR/hs9YQ9pks3mPxReZqm0vAm+p7bUPkO3CPXhYE34yuwNNcqt/6d C6Az+Mi5T9iRchgygIHdFmAmHi3SydDjvhBhfRfqYD24Yeww3FQHnRCN2oelCM6Ky8kB1PZf +ZnuR5/JRoWJoCV8m6GJx4TiLF4VyTcQloc6m2OtBpIZogStm9tMvL80HUE4i8PjgpfU/pI0 7xZeCnejZ7wb2mWAglqnQhgRgc9ikH/W8Ov+Nt6cdRDviptQxBedCoLcxaEnr+sFvTbCsyVJ r5B/jOW1fmnZKvZBlxCRDmweETEEBC7yX1wvbl3yOjfAaIcCbZBjdr9o1kde6qPgRzZm3IMT 23dbGGUutYukpntwIME2JZB66FEKhH0phpoxNHYz3+NF0bA4kjDbOZb97yp0i5KZviT9HEw3 edJTJkJhxdtK405a3uLkvLti8ZjORRiYmHKRLpMhI0Be8lftltbUbJNNYf1pLb6RJ6RV4ztD 6h6GpqxOROd9frCe9tCgg1HdMrYz6FXb6dY/Vz8ukC/gxaDb4M9gLPcuL06vrEp6XQeJ39hk tyz6IkckNUTOc6mJe9jEyvQdwJX9Zycr0RY3Lbrzsr9YQpIpnfSzzJwjy3I1aW/Deq8Sgt9B buUku/wH2EosaokDa3f5Wfg+rufZRYL7vbOH4WT/FaoC/adUN5dAZa5mVw4Hn5BDIvLmRGMb Npu0Jup/Q9/Iz1/yJ1popVdchNvAn5p6ye7m+2bYCrY26mxBYCQ+E/q2r+43RLiawgm02vHO 6n0xY1hdx3J/4DF+qoo4aoaA/UlqmxVddxh259zp+UlL/PmzP0Kl/AtZiVNoUDY5gRHmmttN Donb2IseQX8CYeHssFPmMqt7FG9bJB9erXoPXq0WCMiKGnVwX9IEG4cCz65UnlRuoPe1vt0O xuHoVwuBVzAN1VkAjYjO7TCxwXg34pULMoyRp7kw4f6pR68Zqwss0qV1nO/2eKDLtx3rmlc8 ROcD6baB4h0V96ZmuXis+gRy5m29wm5klp4EdKzmAUotRsXdA2GpZznYV5wIJP9E1wv1tkEC unu+DL90lQ9l8qBVrzuKr+V+KTDeMbQzf+7P0urUgioiUQqSTtMmNx7g1bdPJ7HX5T2TZFkH QFbw8mkx6CYBuGfJlZqUGZ/YmwRHtVVfeXcsxWsMHebzz0qwCAWM5yCRfE30vK4CSPehnJl2 xlqZ6KEOnssrO3Cx0ceh+V2ThoMA1gxnYUhHtimY/WTofO2Y7K8YXfcjw9FWmBtlMD0NgWTc hIunlcly17NljA49RPnSit1h7MH5Bu0WmiXk6KMWoDe5oGO74ATlBudLcOpbddfZZo/heacN 0I472e3Pi9rjDzU5dEOCSlLujdoLR7TCwcScgDstoOiL4RfogI9o7t8qarWqiHL/r4WMs9Xx puaQcIxUSPeFYCCsv97aRU3UgdB/r2WrGGJN5k2KWoOovVF+Z1E1KpemZU00qibqNj47/VMF J+MdNdJ2giELDfMK0eZvIc3Kfvi8gnOymom8Dq6OFEtZp1PFWEtjVESBQlOh4G61OJXQhkBJ oI5d/2djf+YeQRO2FfTpO6qALpUhAvdUfa4/bprd6d9OEjEDV7Nhx3/iFiSHHfGPmKSV0jBe Vc/OJWQBb0K4DAxTO3B8prIi8zg5HNz0zfL9D5kohsGxLsieFQJtuGHf30MoZKzCfJkkts4A mHIdyGcV6DPk56Ax/6DpuiKG1ire21R/PPrhBRO0jI+revJLJJSycFdMFaLBvddc9RdsH92r jm6GHpIUWYKi6dDn0AzoVUygO2uizBmCjtPB6wFNQsEdiK2z+zdUkN4s/wm1wq3akbV481zh H9FsQ/BTV4raNIKPYQEC8cHAT1eyVeUonX0XpHuIUc2mgWrsVqciXfraEbjS1SuT/94Ln8S2 AmRlX8MJ43ULmQi55Aq8YWMqYTzMHbLqRu+2PlakjPRKkJ4Re9ACZzTzR403y7gENKxE/re4 7p3GEn+p4+xvBIKZdM5fkRvoSY/cMlIQ/n0sC+SET7fbHxW6RNVdT5zSWmoGcaWM3DprvMgC dndI10C0J9FVTBurIcRIJhI2n2mvAkVl68ob4S5EBnL+8R87Ca1a1MSxcu+TZ/LEJIhxL89v sb+zT40YAO8mU9AG9D2ReQ9kI9nEEC6MHXNmG0lFjqFi6vBCFuH9oo7Cce28qHtqnztYItUe uoCPvcw9acHh4oyHGBh2FCrsgodfmTLcITxZ3Oto2qepiLHfw9vmAwWrfGhR+GFvO/Ai/+28 Khr8y3NLott0wNcUAt5OWHCwVtzYpI6QqBwEsh0sucVA3H4dxx3FW65RrYo2mXA8ZGMQtHhi RpgHsRPQeG8kPvVC8WNOAN+QNylcdbkcI0R0EmOm+Ohqk3N0c81GCt+6dzGirWAZtO90bAp6 c7akMOQdCfCQRDeaS/bFdb4APnETDUm56EKlkwsy2gIp+j4SqlnQIgzCbqVlasfP1yULj/9Y 7nEt24W6LnL4QgVQHKrgVvOB0UL4Gj3PZ2o6D9EMIhA+NjF9tloO87P2bwzuHEdRuOB5m1H2 jAkyEIdPCrD/NJBnLqzsvhdF3Vm1Ce0KbHMb3/2hIQexq5sIrN3gEtDwot2hOA9FT8FeAwrW yfo/sS1/+UlWTqRXHw33xxeAzYVAhj0l/Rr6hPRxNdkQvlUQ6OFVPjGtJzsKNPJLtBSeu69B QvgDtj7Op9J9sI0jrBpTKgAtXNQhYIPvnJIOGdW80u+GDMvzERlsBP2nHdzrzPyGKWZc/ZRo jGWQbeoeDZXiaToExwCE71y05RNqn87tsJw8zilR10Sx3/Xo2czEflWtH+F9HJn/jBKZcWd4 hbc2+h0lEr0i3yJ3+5JYv4G9OXra+86p5aexBqSPNJlUBQJ4aVYL6IsydQDvRVu7Gi/Nzdpc pTIfeb2GlK/NEkyyoX4Ak7mt60MyOdFufpG4LWWMP9+0KDuigLl2XmDrUYnPCEhHxbq5xfHB x/jpXJt+k6aMLwxP2skX7jRXCubzjla9gtJ+8uqBdvwyGEZj+YG+WhOvov0qEXDyBJ6YSzty 9sHNFGEDl/uMeGOc/W+T0uksmmkpM2mTR5xdfutCtY20KNdcNbF2nzUksEx6BT762feYjzlK zh6vLYwa6lj3ToBY4dkSrkOqh6/YSMiWEqCoUnaiwoyKf61cCLgBr0WqakqiwQGP5LgKEFaw G+0UQTaCept/bwT2kM6lxvzpw4xeFCojtcNUlua+ZhLowki8cIWceSRaVmJI/fbN9OkBYSDX d7VqHFeCTu+W1iAXa5zyBmiu8ETfej1Jli+uEKg5eeEUJRJU6RF08u31PEAlTkZQEnl35ZiT m8bFkfvsNmqtwEKzn8kwmg5hqCaUTxKALyd82LzXx/2VSJfUDLc5fiiFKubUQYyDpiZf0nM9 e1kLK3teWbgvi09ui8peEHecmRFIN/LZWgflK7XkeDLzEI7+nGOnAzCUQRdH2BsLrxWdn10R eTfG6jHSO7N29tAM3K9/XeTEs0q6hWZszQZdn32UOTNlJpWntgQbJAsT+0KIqR7K7IcifgiR +0ircWhog7mewEVCzF1zDGxCyamZuby5KF5XIwDxsJF+dccHVTL0gmaVtCLSaaZAqAMPXXvu 8+FXqndSFzpKm0iEwwXqcCoaGkwb+Bo/RRvOiSB3YJwuqu2z3V6b5PshLyllubkE0tAoq4t4 Upy6EyQhZH3bvi4112KrUEXwCFHJL6Z9uZss8Uwxp8mOawDw9rBkRqjX+NXxthebVpfFLWEB oF4rJtv5devz2xSaHrTnyxexibUqZZedmT0YME8B/i16ihaK70hqKgmJLHhFikccpgVRU2aY jFYIwREShBYTVA1S1t/Y+lPCRYsEfYGv60pMSF+OPkRlf9cPFvAWZQzddoTGyaKPZTttuFnZ /XTa8pmZgxClvabDXVICc/4LimLsJ+uk0Ldtqg7n9fb9AGddyRFup/GW8Qxnizu3TNoZjynv vtvlvRWWzkdL27NA1dyWSxB42j3jfDHgZHr1B7x3hBHBRbf2JBMmvLvE/Cxawn1nh8Ar73Im 1bm3n21KutDGS5JGzIUO1sF8ZUsH1wBOCLORbDUgCxjVha0qhS/ZBXrKe7PPJEl87RM65ruE YhlH9nRx02vbUxVH2d1vZQ/rAVqqiVdvNvrzyFaFar6Koxl/KVZmdgp8uVvESbXCoiG1XL1N zvrYaHsOyGG/UKMpQIMXF2yRpqLROi3quZweaSalX4xMqoVWdaO8vr2whvSRd8SORM++yjC3 5LmYs2BqoRySfc9YERBfqz7QA4EoVkbkWiYHbOsgC57vhXBUV15vy05L0F4zPibnC+yoil2m tXr2dQramjYEJ4LKjUUv8WljOO3d4pMzGeY0nTkqZlJjSHPolE48xBLzX3Sk7FPnx4Hz8Dcp EZp5nua1n8RvrJpxGB9pvt1e+qvWWob3JP6b9mJQCUOozdZCtOv1RBh9S4q+ugha+Y///jq0 U4MB1qbjXDDN4RoZ4EaSZUrBmV7+ws8ugUEJoqj7gbgmZfwPdQDToX6nTgn2NpwWwm9CReWv RVhoxFLjdGBtolXTe+yI2SKvc8LQD8OCWCmr5LgOer2l4sRmdgo1bwfT+6mIJPwjs9CvxeVD QJgkQ0EVPffCDjwC4UtatGH1/Bco1W4vU6MGXDd68Q7RUMvMoXc6Yao6BIXNk2DUGDF6wVao JXmYjWJVW5JVbtwW/6nL329eCr9yiis4wI6hMt8ftjbZSJ7Sn71EN6Y5//D6u7DY6Df6Bov0 HBJqcZ8XXxIpR70/JHHj6enXaGfoT1//wfQEBkeD3y53VHGqMZJiwSDrs7FSvmn/f9vxRLmz EDVlP7XfQ/gn0laTyoh43y3qS9R2bVsHJ3FwvEn18Kssnrezldwue5mG6Qk7cHBTr28YpXxf e4rAiECsVwHWlUkYHiHGU39wyijJX+7qWzvMSi3AMWDH7VZN/6bJS9BUaxKeCqNCXumkB5Wi YDe9ViJJvFq5WCUmjSP3cngOF3I12NbywVpxs91dfgT54FmXugxQK0eYy4IMDnRvdkBFb+Uj EKjGMXrkAFrBIGyBr3uXX87W1EzudptUSPq7oqasIIb20TzvtUd44EuQaCjmwotAhIQ2ExaP v7M3AU4llU9CwIS+QTFjgPOVRSFgOLY6B18BmSS9gT9VjuF3WgyCgE8/I7cjcFCol8GVOhZN u/lv189qDP7OldrPw6XYdympKQIgLLKT0CtVcUh/GWoKNdYz3iEwFcAh6oKEnbLxBP/Bh9mL LqLf97TvO/AmyBA++fbYp3vOZnqHH/bh/isOgcgNf5qsVdyx/PvLjDgoEiOSR+qXILkQL2xN rDT6LpnK1NAFq4WLLs0rZBb0JtVRPbjde4UXEsP9bmfnLXSBME6eMxjaV4edwiYgvJI50XaI 50cDmEvqLI1zPOIEyXutO+rZI5KAyhEGuSagBonxV/ItsPVstrrx8XWOdrAwglZIsD5ViWcb k2yTPTc8Gtd2cHao5VfBsoCBnwIL1imOFyI99G4DjJAbPhNd3dYpRR189m65PdHq/pJ/uUnI 7FkOFGTVCkK/v5jILUDnlEzeVuZV9cJJfVb2qc23D9uIlBPNBTvy873AKZd9QELBoyY9aJ2+ 4BmLBz7XGnBu3Wkr3IcR6lWebL3f4WgDwWkiX9CJAEUzYrPdRJuGGE3IbjG8fcowAbbeqPyS 5l+Ag5UC6EtIC12gULX2awxz47gMqyWvV892QTrNuQD9+nimcNpzvMWL3uDjU+ZIf0RvoKR1 r/eh5BboYo96Sz+Y50aMrayvWW+0Gqzd+w8UfcbRSuGw4wG5E86Y5Cc8w3kx+AccTG0eYlQd 0Rzp14yH2hyDdikyYnoFNWKNvL+M7+zp1wcaAB64y8OQNLe5RcxSOufxR41phZm49lo8/b5q k5DbY2jcwHN315gsqXwDj5f/QgWQxugLWo9bpfVT8F1iyxX+D5xhmd25EqRtiqXeJxDRbcd+ G9T2xWaq7vYXkWS7N/qJ+kWdFJzUr4t4wP37bhyQOba0mtiNgOj2WJkL8SgXRyitx5rIlmjM R+O2IeIaJ5c/MPRwSqHwyBvfd+ONMx2dYPxgJupD3pX/l4HYxCDVf99pgWdeZJMVfn3IhRQe vDVmDgmAu1nvFgTvzt3e3SpdTizVU9xiA6uThzO5tFCvtkiIRvhv8bnzSbclWxpzEdFF14GB fMuYH5YI2lf8NEe0zLgmUBgN5FRp3sXjbpLIihPtnYHKmk+rBBsmT37zK8fhCk3nq1xrwgVW IdozuKMct7qfWQ+xokth51e3u+mi3kVD/QhJwje3vcpPLwrH8EoH3UFuiS7WeqcathP5R2tA jD21wsPBvbS9PsOzpRJ0XhDjY3WnY16i1kRElJcO9BdGG4Jwwb5iOIdzCBecNVO7AObwImzn TtFkDbEhOK2GcuTYre/czNA/hKc8gfUoS95etMiT3oNi+cT/+FJuhpPk+Jv+BFHnXwdOFSDv bnAHbfiPtGBoLjWMBKehzJ6P0azs04xTW1Plb2qUGYzy9AhQ3znrhtlPoUXzIT4e+ginN7x2 Q1zXLdHp50tUWNtQdMCh0UdElzOjjQJcvx//FHKDOMT77LkvKYdhuejDs1PmoXfn5NIkKsFy mRMpwHIlK0+ewkNoiUUMaeyfEa0RP+rKnRCMbBYGneC32RlgbZFEdn2UA/03B4tThOQIwNA4 9OXSWptWHL5X1qvPRCopOfRkDV+PZB2hRSkuDpI5Gvsx+wdydiX11vtKNM1H67nldV/VDCum 5RRy7ZCIyT1+m3+LuGbj4tDK7NzJo9q3bUtBJbycdrokhx93iMi6ywMBpC9sZIYPTrail5cn 1eFy8BroLLEptX6OA1/6vxheLE3QWvKELE+NFkiBBI8To9UHBE9Z4aSfxoNUCas8YAZ6B8Iv WLLKFrIIPR4bxm3K1Hgu87c9MuYjE+4OtDaaWc440CEeKAdpjharDkk5tRuQ2SFxNYSkNXpp 1Rm2p7itgO3bYsnOEjUjhBRjyN50A/AH6AquWGIsAm1Ghl5m3ZjXh7AXBvAgLcOWcEzs+NUT 8HfaOfgPy7sHde2GWiA5lSzKT8P+ZmL8AtYgcV2uYnCJrPgNvqBJ8WVkubvFeMES8AuIcbb+ sEXIBuIKF8Wo3gmjbnSfbKIxzHLIl/LWcHtuzgdwMUeo6/IYmh5VCPWbpPDJBtGZiPNzXXTC vydC85K3/7sDPe38upcIGVwIb1r/pysNX0+ySQbUM7GmzK+fznilIDhBjfmYinWivvuHRWoU zC5a3LDLVLM8ms2gIzgCfkOdzcDz6QAsZhvWwMEsmYZAjviNCMt2McgBapDi1tqdAXnwheeX aaX0NCbISh92fuTq+J/A2QxcBUaLhmFuLnaAqFc+qk8SuOcspJI0W64+I7XNKt4NuJWT95wY OmFWrGM5tmyjIls6MK1z/37nYi/onTqcHHp3aO2J00lBljMk6eqtzepBXZs6i/Cb6Az052bn CCHtU5qgJlw6fD/7PaV5sG5EigpP7uonut5+QJSl/9uATdy11LOFLX24o14DPECNlPtMx/jP 8gRO2CEqXheniUh7OWSbosHTWv1X4HuftkCK3OiNmSbVYi+tftDUI7hit2+aYRUjO4cj6umH iS0jVAxHUqkiHqoohQ1zyyarkoLesZ0MkCS/HO0Tcn8zm+JptGXMXTm3FLHYG/RluuTeinPg UgVc4ExAtleaDzVVABqCiYvJelQMCVtl+ILg27RasZtPh8NOt0G7Jxo9Pos4jPmOW9vBB480 2fmCRHXOk5y/tw+9C6zju6Ifxab1SP9cVeEfm6bb1OjYdiARpuTOnU2JXqWwJB6IyrC3vaNH mkFinI9K6rppqH/A6ad+XQ1dg2tSun+hUqr5ML+NBerNpXtzJzkp7VWl29SAdokmi/g7PB8v 1boKVewYLHgi7Wed7IHs982+PHemnrLKr8YhTP7meIug6nPcL8sxIHRezyxAnmbnLJFWw5va a4DkC5oPkOxjgT38DD4fsuNO6+qAgDGbFvK7h8TN5BLYFYthfP0BT4Rm7YFx98juxxFUHlhz oh9WIwQ5iysmTmpUJPIOT1AnTBjdpyNP2V1FM5lbLgD6xR8NFtkCVdVr6Peg1eXkpE+/pGuE EbNeFakBNTFTOl8syaDp+omEAsveOmnDYpDXePf33GHwTS0YMNgIqVQC3byFIzSeuELVcOuH RANvSiPUgyxGHdxTR+cK+DXSNylLfjZHX/5R3rN4WtOPiy3T1Yp5NKb1JlrPoJSzwklSfj26 ogjBtE2lRSZT2gmAuvjytH/czSD+sj4QkF0eVvKBGZp5eRMUG5BAM8+TPdaAXJXsYlEfQJ2K jHdK8bvcoBbPbUed1iDbwPYhe6E851BLVmW/8/UjGn8ecUleMG63id9Dmi2Y+YmekCyf+dwv Dr1ZZwgSjyBMAYDEekYWbeIHft5iAUh8tlGcwbCEdpnFHAulKFv9Z3M+dnA9HiMcGSvI00a/ Q2aJsQHVk/zw4NGwrY0K5ibl1Vj3EyU2Pb0Yiz9iYIhfsF8qrWM8i6iFiX+pUwFKs2T45xxH QRY3R3JJ6W8zRNLSIWM1igndpDItcfZyO/ZHNhnQECLqzG2KZyjW+tfbAKSQIyK72jrCM1uQ kMPKLvvU2P/KnUeOecDOqzTNNJUYY9nmRQFr9SVpH9/2cu1TxhmOZmQrXV/ZTPvwZounXhoB arkMSraRaiX5O33Po3hYEcYCRP8Sx7Wzn4Qu6lHSdDtlAVXMgErZnXHqVkfri3mjoAyBnBAe CP1MyNJgmYXLzdQ4Agcr4Iobd4U5xxRW3KrjoUMnDZXdKt21ywN4mUmVX9bnykDSCy8XKM5O 3i4q4HB0nKzOZUbsBVhp5Xm8I5zBfwBNtVJ+7NC+ycbaPvkUVSoUbCcRz13x/90MbUwRSm8+ e4/EUTjAROzkHFk0FXpmGzJrQX3Do8SSq6lOB41JETQ277cmgUCBWXs2wnd3ucz42bEnGvKV RIlvyzejAkWN6yj+K2Jj4+CchsUxRziQohFjYvmaj7qCc1urfUVP8UZmB13coVrykfNSmmhL 9gBfjDk5fAixi0ut64xs/EiyJadYkdpSJSEQu0tV1QUbo6TaPk4fp4FZ+sAcQk1hTg85Xf9p a7ZLtogdA5giuh8G/p7PEWa+UpJH2qzOGlgsIUTjus71ueyKGH+VCLiZW3/Ac4d3jfpKnkqC rAiAeieNVZATpffLTRTZCDrwK8ztH5rNwv7LRxAvkKnoJskUBklRxGaGbzlE1/ro6uzpgni0 HimMchnHCmQ0me2uvC1ovB0syIyY7MtGDUmJ92BUaRjlk/llAGJY/BN18fTRBzem6C9IglKt 4vOe0OmuxzMvHnJcThoKos+FkSpL06rWMBJjy2PoCdNzOwkPxPyJ7OmpU4wimMGdWyRQXvd3 YXW/wWxA/CdhQkVNyWyFZ7q594QS3Em03xvpyiEKDRRxZBBygjTmD7KHUC0rZh/o20bTiZ29 zmhCWSDlncBcl6HEmkATHcEtK/R4uypQgNyor69Kw3+9Z7Bs1+dhqXrjqyiJJTarYcu8Rr/R Hf+UxHTfF4CgUQzSMTMBVD0LVpDnDm1Nf1B3sJOxeXNPAVYJZxQGmsrG49t/XDYP3cA16eOz rn+oa0VVHpBCYYqPJ92QJsDFMccZyEPBzTXFiycRjVUV7+XwLs3rZpgGTFU2yL8iwofgsBm3 LNC2iYeZi+VgByeY8g6aH3O6U9qoKsAVwb/m2I4yu39CcplS3XhIsSQNV+UQRto10oa+e2ys ic05YF0BOE+ScajDZJ7hcxgorq2ik9zSnmN5EuHuZunxRLeS7NO2YJsbTkj7T3kd7RPTcWIU VLqUjaPOw/k8SbbMFmB1LDwnftO1b6oQq/FE5oDf6laju1vslgwsia1/+XfJveaVZck9ABNM b6IccZa/h6GsPeF+kF3rXjLaWCH3326aUy5R2/ORgpYTESl+sTMUhAUBDmG8XRrvRJmhrGup En3i6y3G+CTsxZ46v07LvxahCkgQV9MXcoYrM1WqrAu3jtUV5GjDlZ4FHpMe96s51zJQnzqW oenEWi66jbXxEySjXoURVX6vu9tDr1T+KTCMukDPCKkr51vjgXhbJ0nh188nw2srSpLBj2WV heed0NeKD/OkMwt+qZWASJNTaGKAAH6wdAlU/qdsXKVt7Rvp6wZETDDLPlAqa6qMZ93xCI0j HfeIs7hcN/AYi4rUiVXL6amk9Ffip3TKaNdtM3adYJ8Onx9CwTAo8mulfPOepch1I+zuSraG fl7KMLYJvOVVJe8pkblhKCowcojsrj1gX2dgGH4vqmisaPl+b8oSQTYMRFOcEGo6UA1pGFiL KiLe1Pch0M7GiWz+g6facngTkm/V/9a+b7Q1nJopxenjU08mYY73BbBc1z2u3Bp7vl/mE7Pp mLB3NZLOufKc2ISb2WyI9CF4u3h98UhuB/fnV0hDn7tBqKxUxOfWJeyaB2y9h6z9t1y0BZOb gIbTqhSOACYyUPDpnjr2hI+BQGbLO4Nz1/f7QL5rT9QVIuIgY+zg8BHuuGDLNe5AX1jmjCwf 8GH1IYbKX255FDxtoErgp0xlXB98wzIPwqqCWikKlbDt1EXbczntSZpsAjR0OUW6Jb3pZV54 ri9ZGnByA3w9C0/AmuOl5rwx63g3YVhhFvnP1Qq0ww7gY8gweiceG65ZbkvwCwxCear0bDBM XM1+SBIfCa1Ye/QjME58IEJpZRSGRxCGJgBS4rmszybpe/eIaooSHXp8R5G8ueak7f0KTNFx eB7Sz8m1aCJaWPbO7VXZS5oLEKUoFWNYZIa4Adj7iqOTO0gkQRZSRcIzb82OvuT7xYDTfgMi fIn2gVwkKP9MWgaMYAkWtQMyC1p47RmAniass4k6TJkn3osoKsTZQAe0Bi5cpv3qW/bQwiUf +i/tz0qTvtWfD6qZmPYxkG/Iwnzo4ryf4GUI2Gh/Y6nq+Ts+gZmNOyZgZbw0Q0jtHVkLFJ4+ 7eIoVGvJHlU8CKNl73bV3+a86/JBHEEtmdPSfMhi7YhEfiyKhsp5TmrErHyBpmKU+Zf0lNiV AZtZHMPyEDi1keinNno/Kb/5zf/c8S17uidU/Ey/MouJ44sJ6WYbYj5GieLTqmpB0DWgJVGl 93IOzkW5yMXxt01aFgKwLkqQ1I+aOijOk15+bVL4rzqyf1o8A66L1Y56Azd5BiEUuWRzAV3x ZFgbqQ8vXEnIeRFCIENN6L/J3n4zR0RElbUMzzKlRN3nK+0YVO5iVyuKDOHaSgXbitITO3+y Yi2czJ6MLizcMRFQCMwe92wqhGrjEvVSqHzivnk/4dojROK4lLso43TqFLAuuX6IGS1Wnd9h ZF/OeRSC7TDtVxLMADCK7gXF/IZwcT3Ebet5Qq4xBeeXAlcvBrH0TRl8HCuvTg17Vnva6Uud bVChxvQxCbj+KCGYwdvLdcTYAzd087XZwcJFQPKLeQ7Mv/VnpKWrsEpaCEmPt8wI1nF5Wvgu YdblkV5xii82hMAh/0H4dCYKwme3nppSCW2xWE8CvAwQcrvi2oHBmUO+TY6WCl4RYuGiGOog 8RfPCYuqTCWs3b3uSJXowJ+qA+74bwyTzx0SYZHBJRn/aISC6J51yXwHMmcDFCg1pXl12bcL K6nYc16EyRJI9KcylwEZulbKE3+PX3EWxRDhStiOztIoIkLtqKaccr2XfWj3PwRyKkwu89ch dqgqBRGCeRr+HC0UGz3jYM8myka3xUAeylNToZOl6KwLQt9AQrsjObUBbPn1g+bwG2bLgmzF NT0G02L3KguhrUlz5nWrptfktHBv2g2SiDV4fHLUE+F86M3LXdVH7Zd1/mLalQJezB7+eFn7 uwqvt8CeDy8UTnTo57FL4t+J+aGqYVVBvayN6DRt7OY5/tyTDY9qA87RZq6K/TwzPEmLFGT5 XIG5eb+AAyOvviAZUzH/slw0zetZt3xs98UUPmxQXotdJOmi4QlP7bQoOIq6WpLi5Dw2CYqd Ri7o1vOcG78Rc36wzNf8fw+tGd60W5LKI+fdAeFlkgu1jOk2mw/b52YeMslRVmlJzduhtXgr +NNEf32R7rp2kTsbXAvSZu/+ql+cF1rAQCWGgeS5Otgc4THMNcPifPMErE3GFNjwYBxetqT9 PLLM8qO+rChKNtImdlVlq2X8dPyrY1sUXl7fR3DyNL1mzBPyIVLenIXvxwHVab9cQkGq6KaX lui0S2wsYR+hkkj/hLHZhgueRLfsTuV52r4DDweOOkJcmqeg5+QZ3TIZStecO0UxPw6uPx4y c+06OvVprncVhdZnC2iHMXkr1Ivce8+oD2EZD9QQVxb3eCzGTd4Ft5UhohVErpaQWC2BFWxz dnrZ4fwQ5QVbmO1GuISz1Qsc9eexyHiJ2dBb0oTp3dO9lB6C2olLg5Yw0hih8UA4vNwiHsBw gNaphtNl+DMlAVFDlx9UES4qt4oZqHwwaZaiVPEl/aBt+RkdwUPfVH9XxFFCHVnAOTs8tEYO 8z95lxUjXdjAFHfZ9wF9WW9aUMREU6kBwOlxplx/gfikQ01999qSSy70xWWODeJt1geA4ijS tJ437rMPbTlCDhB5PckXQddbcSe7Hnmo8HfuxAV+d6CNCDFlH5zK9zLV4KOiA8ectqr3Fxk/ CKqm1mwHwCnDe3mpvw+qI6bro55cq9/CfyRsfROwZZ7zk+JuR5e7FuSwmWLHiGPD3tzhWOZN OdjYOomOPA7xEIYALlwfkNpgmUf4hKr2OBD7Bfe3uyVSAC1gI1c678REe/crq+rvg7zz+sGb 5C6QsAZFRGPg9FDhR3dyzhJr1YHJMGfk5bl5eqaVQsuFjhi3UpRPCSGi8ezLUmQPReKFqtiH St4lNKiJfrsg7Tg3KA3I6okCQyPJwieKenoUrNrvO+03IgcR9v2hNxJy8LgoL6DQ3GF52KvZ oiXgp47Tk44C1z6Kb8r7TGIPxsakmTAsaH4t7cN93JEnWaVzw2Rd5Ib5b+Q28DouXwNPsyay D0O3Lsb9psk39Gr5X91G64re19CzTvVBB2x/gw7UElL97lxRh+ZQAtqwPCqiwtr5fWvigH8h 2+DlgDXS8k7wn7lUivBibvEAep05upoDW+mHQdrdKW5e1TtO8gCRj+2bryOWK6eqx3pWV7AZ dNlCijGnOfB0bHWf/h0ovtEK7IMpATqo1sDcTf/1zKoNQgtcgh0RzyZ7BKqeM7dhz0hf/RzN R3LGtkmLObtuTOuctz2wwkZ1tIF516uK85M5KrKhP6Mm/Fkco/WEjwG5V7GJnW18KYqnpMBU zJLvbfVMEL40ey8dCO2D3+IiUj3TyI+62I5Pss0GDmLq5kxcey4JkiJXGQKVv9Oansad/CpF 2DOoz3mCp2cPd8OoqYlRYubJebVt1hn5UGB+eRTDE2cC006nHxiFGTRGd3kiyC+9IBRQatVU dq5A4DdElrYv5nJP12gG+12ew3dfXTR1jFWExSaeTYGI0xP4eUjTbsnzVCFuta8dVAUlAbZ1 WhXoc5VUUgHSZxk4ppgrrS1HDEp59jW52F4O4drOqrhJUj7nkz4w1cFz8KCfaIeG/EmyAbQk T0IS6HhJetSAE2L5QuPmWevJpwYVrw7whkG9+9b1bjpItFQzpw7lH/Tt/InjwGUw1JjZ0LL1 cEraKThjD7OoCR1FhEOIINleFCnwRPHPNPrlV9JgOOzQsVIf8rGNgrDpFPBRgw7sU3Be6Xc9 oLcyaDsmSjetv7emLCyY3WTxG8hDIItTNsaa5KR7gfxTWKqYSD5BN+jH4nDDLvbZNicWTYAn DI0v1aj4nvjW2HRuW6YMG+wsm0LkF8/zRGOurH+4UdBndjNI7WIVChxwI05ZNB11LA/diFNn VEvD4ZkTU8LWNVeEbE4GGW5JAwxwDD1hQX6tS2pYy2LxOOJTj9ZyTu8u/JDoDkIy5pJZPxJk 4GRa/tkFymuiYqeZE9dgOZqaxukmPSuC1B//IYUHJJ5maONiTF0Ff/26cvCFTZpw6LpskoOf U+Gh2p0eZB38uq57toxo/L4z1PHDB+iWoU/WX45q90csTX0VLPDnwQFu60GUwHAZ5jFHUl2+ FxBfcKqGTCQuz/9hFINAJKrDoRj9scUJ6wZIo1fFgsiXq0TRYQiXSuAXdyyS95O1yJLaowrA k+E793PGEqnomdff2XSGw845jWRWVmF6Xxmfdkkgtp9QYL4jiRNgPhT72eT2dd+GSoqQjjou Mylk2IEmSxD2Pc+ETw1m5emKodbo3Av5FM26xA3NH9PWdOuJOWMv9ZxvN/lHtkBgbfyPz3y+ 6JYndidAwMi9TLc0QvG/FQ/l+31xj5piJaGHCztIFqSdTn2/avz8GzUGk4lT/GMbbz6F9jKW NDIvaA9eCsVEmn7VVMGVw+iul7u1iQ983QIMb2NkSiz/NYrrY+PzD3X3582PVsRoLkTvADsm lSUEwR1WsGJNK202GFMvXKlkLtLXo7lKfbEONIhAvkLeDEZns9cyNmZtLs7UnJrKb8NrG+W3 6V4HgR9D2gK9eGpFdhM0CRAwcxsyzxB4aP0nm5KongP9IdFQz3uLLE88JYWtoCNwaIQEeZ3x JgY369j0LnFzjJp+ZQKcYRQAwTPBPKsodxGlSNQuvZGwu+PujFTLFAS7QccGufsqPsPgjRR7 rtdcVhzk5lXD7l9e3SO9p3ORiaKqVeL8YBx1rUddiUBs8HO63xNJSZKuXKPbCi5+4MV3jTQL OlRoMVX9+lj7oX8zgj+OYJdfIadFSN1cQTZYgRPJHZAHtLSiAKi07BFuk/NHMKsU5f03k9l6 OjyBcrPjwsFNmwCKEUMK4zOu0Ix3eHb/cQQPIRqEa/41BMJCv37qbPbxNadbrt/Ue7EWK60R IXgiz0o9nUn7by37f7ftqoqQ64cVDczbQU5Ve8eIyOOM/hvAswBrazhTBP21Wl1ye1wAQdMJ 4YfAtlLRO0ep/ePJKFYF6MFRZTyEPngOwOE1N/JqdqEX9VAyVWtCJp3YvijB8e11shP5bFrJ zf9KhG+aeAuHjbpD2gQkELjuhg/xday2T9gqFUGUrwGz9VxLEe6OFLYgLKn1XE0sTxrcwQ1E 4a+Bw3/JIp5bToaTjyDxyLEi7wOyLyeLvDEX/X2167vs2kn+SNXKfcz7iJdZmMKS4WV1UdQh 3+N2p1ias/+lOfaR9RSdlk4/mf01zb+kzoFljdsWFTC8fr5xarevJI78WLYXWU99xskaNCO7 gxczE6t+dTuIKMgnAOeMe8AAcWVKMTNwxx6a6Rq8s7Cje2LPiZnkCO7YVe9VTjr3RiOOxf6g e91u5aWju/9HEpS+mQjj3DANNRzFkSp109PUJydAhov1bF2TYK586kP+wUyI5NhY7KyiSA7m X6ixs8LZ+slx5K+WPIIt9G9DompDFgkr/2UZHE8wcA/ib+N/uML75FXf1Vb44goc+FdGl8X1 C2pelD7rLamQTpz8SVsqdBRYgybY16FjluWZUN5oP2D4KYvJ1p1tm0vzMKIOZ2ILRBwqQWkY GfKSUhFjsfiXlTaMawUpSsyk+b55V/aBlayToaiWROhhWAAi2BAmZ3G9Tk1Dmo91coN4lwuE ngkugNoxYxkHR6vX7OfSlg9Bq/6rgXUT1Ism2cEFu77gt+DAU8Mjhd3pGZsB+F2CZANpC1b4 Orn2rLz4QpGc8TqtRj5pJlBFiewx+xV/r6S2jwP22uv1fm1yApp0uFsZ2SoP70q1u/3GTOxo 2noVPdW9q+z1lpWvxu+dhaE5ROILemjkBXHiIPNhEnNIvhh5mOq0u6bB090HHWUcqHG6okjl YTgak7RhU2EG8/ZHVtVTQM5OJSNhtspZCREJn308+agG+bp2lOaqJLMjyT6foXucb5Al+CgP vvF6mVFfj4tL/+c4FBULzQH+a/ktyiV8TFjiU5Q4dFmQr/aiZJI0gz6ti79RVVz6shpItHbB D+e9j/W/8KMdq7ORI5y4dojnr2X9Q6tnGtBcyqxHC2nqWcPNS5hTsRQ8O+rUvNdZOiRT95UJ A260N8z0nEDsfKoB6g5VE8Eo7iScImboEeM66lATtY+/DxvdxJwFv8tjiFHvUxsD40B0RGWp Lpi/7tNMRYHJc5+e8ZBgxpp1eslmcO7nu66QX6u0XuMQB15CzFMEsWU2BWinsSQHT8wEBq7E NlluDiz4h7bUceEorH3ChJzkMCd0Q+/FnqF2+cWIISFIDqn/eIirwSnEWGNB5bjEgxG8Vq4J VHpXpvJM4GNdWLZIIHyb/h9fjYSN4A9/wnbu1fZ+vXyPqzoTLQ0DuXtP31f8NFGemeMudFx4 krAkc+IY5AY3MlJuN/Ro0JGqgLcXISDEXeGNTfTJAEQrZJ7mCFXGHwMDkkXEYMFYLvPaZHpe E1CR7E33GLXwF+CFCswOngIqWSNETyxnQ04b4o3kt0YafPW4U/8pNhZ3xH+WIlhaI/sy1dOi JwcXd9P/1YpbFF6tE5MaKy5w7eLycvIMmX6p0tGQCgGGnFc2gqLT/JOYbiczfZ6hZB7ZnJ5Z bPH5hEYP9zqbmjOj7a0sdfBkwKpB6Wi3B4MmwUatF94+1iWde6tQrOx6IiwVBemsS31UJDd1 MvAgMvMYIScIuqKyMFL8DA+aAUPy11HtJGNJGxv9m73vRNlEYm7mq7LrUtrKHqUdd4u9NkMg y35a8yZdFkpeo7UsOOpozKM5HbUDaGDc00B8L2XrGDqhtY3ODm8OvRKl1vyqiZjyESyTDR2e 0jptkVjeuzuXzUyp4Xk9o7M1gjuzdF/eeH6oUBk6eU0e6TU0qqynwsx37ldURoLpjhcPjJJH JS9YOYzO4Z4iGpovE/L/P7m8ldGKnJ1MwWag1amIAa0mnrb9jUCDm0HveJrVQBy61N6D7PGw bsMh0zpITOtmcrCAbhWFtlXXc6Jr9ootJXLSZm7ruLqL0X9rBr5ujIHQAb4PYohjjR1qYI1H vs4th+ylHYhAtKl1hdXKajZEsetWo9v0X15R1Hjb7+bDH7yv7qz55NJ0h6AWzlp+byO78jjW zxUo5fWh5axsqDrlEDZuvVLoBLlbxZIJ9WWmhydBwROxoUv4gf+0Jw6fswWqyjF8wfIVwJr9 xqAxKAk1Qra08E+3eaH5+cIvFXNkEOv/9Q3TH96jcTkCMFNDZS3JRh+AMQLViL8h/cP9o0zt HNrdZ9e5qX2OczqoTNyZvTp5TWsq3Kxkygsrb0TiyGAfRQlTJXTmmKeo5/lVZVREGx4RsSxa 9fxYcg2jaTWRGJsR7Gv0eHxydQzJqckQCKN5421QZ3MpjppJiJYTy46o1DXPoMjCt/LP2EVj G4RkgJJL+SW5pNOr8LH4jdCqJReXYITyCHQbmRu390+M+vkgB9tK8aeo1yC+6YFEO7kkSEkC vbVgflobHr0zCGuiFA1Vlzrz0MADh+f/C0OZ8Ejf6uNWDT6KjRPy3gMmbVvtmm3upCjyZAME +avRAHLjcWiXghU6oPA2/G7j0aOy7RT0J7vTeTzXQXBws8BqvCQ4MejfkKrXY/qDv2YrsezH VkFXOuC7lgh/4pxMAuu1Mceaf8P4ks15WtXOMlMEcabFWTYfajFP3B4yjQC1Mob2Ap7yF3W8 B1LKB3nD+vje06jiIYBUW/Mf75ip+V1oKWrAVJaasIrcIX4lRakh8BVFzrnUThlog+SlUjsj jruTgNDHyAVx5jCCUq29IKUPr9AAB/x7A2+NifcD4xyjUOnrnovKbTZxBv41WhWCMk9SB32v rPJmo29aV+BDjYqntfTcTKy0YODK/sBVlFnshg+j3mJXpXQHng3y6PN69SZJMWMvPvrG1Ike KXfhBbVhTmjRH8tEb6ppTyMQggOVEurjTdiMp2neX8PD1odjaAgdk6/+6+RLa0ye2QkkbRND 7gufjny4gzHm7vjXgnxZEimeYpzQLnYn9N4hoHHwYBkdbJmHBl5oakUYNeMYmF3aNyYXQLUG DsbNwDG/e/ZLrG/ypfIXaG0sMpv6xShq004385doXEEmVPEaqtLDNOZ5UO/KgNQO5j970C9U ZnclNgtTH4BB83FyUFiYmun1xKWkEVB+jLJiK93vJ8uIv+pq7JuWMpskEV+5W7twheCLDjlq 0+w7tTc9akOnOzHwgpOPz/ezYYo47LL6KPRmuMiDkPqdxpwJ6Ptw7VPVdtAQP9aMKy/+bC4Y MYUD8v648bsHhugrZP0W0lG7ZRf0tlL884i/4eUWWvzwu8Y4eMz7KY/oZXX5z0hRdDIraIdq CsDgXsrGSxXIacwuUSokQMD5O9ysvdIBfkmq3aMRQv0NsONjUEP091F7W1C5cCTTFTfAiNMI 3bn8B+CVRWBX0oKYQ3ZVdTowEi1ndBHg48ucEtzx+FfXklvUuxV4es2WP5CYCTLQ9BsNkCtq JobtpVFejyvWcqs1g3QDU+38aOGZci72uYnmTGMmLUy76bU38EO/GsSMVzt0LPkJidjke2ba MlKtkrLLbGII4kC/nmEoRHveK9gvZMOlz2TWR+hWec+fDXIuUoXT5GAtXlyXDKHYsoVOD/ra V+i5GyFGK0ygzhKS8NURI5yAVQEQ54/B5GTjTVGcdD0Tq8D9EVxItrzIMfVhAu+5H5pTeErK DF6BgmQeFWjBeH4VArUv/iyRRcLXRxbz5uq12KjZz89PPUkH+i9NWGmllc/eeJhzizPdNK6L niNMmEn1PgNqHjl0T3qQiy1VLFtXJrFk9oQELNgqeN+RA8odrrzUj+ZCPUOkdDXSP5IfG1jn ZN1BWdanob5mYoaJ7QOF1rl8nbJhx0Q3izTFcGiqW0b9+jGVINnSlH689l1zEW37P4VmpNTw LcvfZgAWm4QtLQ6wVlW5QNt8F0GXkm+KdZ52iSbswLWyoIpYE4sO5EUbXcHO2A1G+Sq9dnf3 lJ1BCwRCaPjTsG8/HNn0xfKtCcZC2pa6G8GZTNCoJ1abr8JqC/8lPCtSQ+OfzDukdB4/LUOV HhfaILgwjh4dR9l3KLv84Xkb9EBqr84WO+wyQdQU5PPFRg2CTnWm4i9giHGSRkpUgew0liXR 4yg9xsG6ulpJV0KGg1zZxXyIaVSbzK+kOWQckpW13oblELG5jlXHOoyzjQCZc+pzBzTOnprU oMhJnSPb1WIeSHHgBMb5adwppdJtfNPIIHw+k8iBCna2EawScd52zAzRtqB+tbmjPSAK9IKc vGOoSf+MG0+30/Jw/tDHQOAj1RSDWjKiKbfeS5Mo7fdoSeRjCaX/wkHvH9KudPhP0EAD/jai 6m8Y70ljQlgICGzC1bS5w2573u7uDLEIFXoq6A0OmxqD+UDmFqR0xCvzbjQ9ZcK7F20MU1RS zqPz1AW0mKUDaSwySiYhObPK2Apm6tevOsYju2i2ivtVn/iuT7I6A/PoMDhLmnevtpYum48+ 65wGn5ML2Z5Tvhiee+hHdY7sfcsrxkIajWPhg1MzBUUcJPhcPHp71W98as0oZMwl2fhHL/n6 TQm2vZLT5iOl6N9hKK2PyldwiE6gtNxvjV6cABHLd96Nkt5lEJxIMNIev3OQqWZBAm5nAH1I 1Qk3XM4+M3f2EGXIx0FvjoajRm5h6MAQXqSzUiAbLHMzrJz78YSRnXjVFgjxrtapDx+IbYSt pgNG7B0KEiGkt5rn5Ynfq5I97AtsnqTvzj66BdsZf8UeJz/IZDhCzYnRfJ6jzJM36jJZ0KWF u7TQuR28OHf6smdNo3GsC3SG8TxwGxrCy5nZbX0iWihNy3YSV+t/AzgXoNW3ZYeJVmnfcDcX PxGhunkfkWfuelkmoOnJkQ+Wbs9zo0YpxNm9EB6LMePoTK/xKKzeMnY0RVVJhznUYJTHdZY1 mZiXxR/sYfI80UJ2F89YSoVlpserPmBCHqTHNLjN8d75U3o9sPTi9xIXc34Ab82ObjUQ+ifI rY4x43MfB7iHPBQnCVJ+VkwmflpAtGwRic5mC8UhRnIYoVYgpT4jmDdbtIoAPskk5DGQYMna ysk4S6ebhtbNoc2YrF3k6rI1TlU+59n2jbmCVPrqG2Pnn6CTCwQT2iEFTn31VGgwIaEFholP ZLoFUw21fOYhtyEs7eNM2aSvTWIb5XebkW3NbNQBtJWkzyanXcCi4lfxAMJoh35ETT/SpwqQ QoNRTQvI0N8t8zD787cESUNTwnqgWD6LTbVoB9b1Op5sdjwoqBRrJM+2+Kk1Ki6iPFnuvc5K H9+eGZYL3i84wvwLjrFajpdcVxBTUfmnxcbDJdQ//8O5YphWXOUbGqNiHW5LzPkD4KDTR0Yh +QLyj99qrhki/rEZRJruaBv2PqCm/1hVefukk8Y04bujCbkU81cyKw/tyjQxgfEWzR32BGXu oj4iXWojtnLv/nrLXc2kric/WWTe+zWMs17XF3USz7yZNSwhWns8UWW1pxYw7Az9aIkv3GAQ 3PjAX8mFJoVwtPNYYy2QFlnfTgyugBuRiigZkZC6m1SI7viDYJZjf5lHmruSOGX5LbAE3TyE q/yeiovBY3ElXErEbrtyQlDrEXXjvDE57By9VN7pZAvMT99MrlZfpWDqgaBSTA6Rzu/jUCR8 vtbEuR/9kUatyAh0ume7EJhDGb0CR5pg+EPQWX70Fjz8XqPKEG6MR8N5s4ouDUOj/gS/W2FA YtN6EE2DG/XVVFY9HyOEgsT8WPRqSlAkNIaVTgtJ0F+YQCkTU/Pq6bxF87rr2P3NVc9grxqg K9FJnx3Ean+yFWHboa4yE7G2jId3p+fwDCGJBwLVa11EMtJlCUV4ZQSkOz/UnqKojBjv/Ure AqOAvWeA5M7uFc0PLanwkr3qjesxeumG0xZqHgeaENdKfVdpT7j/UZ2x9boc+2vF571iT5I9 8r5ZumrgVrb5h/vkqqU5EPLNMoaVR9o+kwicWDscLuciUsFjUgoLhyU+kt2mZQOLe7HDSFri 61O1ieXFBP+YqK8O1KS0v+Wxr2tLcd6MNeXimF+d1gDCvD5pra4lOYsn6QuJjWiHg2mz/s9C YkugT5tT0XwiWwLaRI0ddYIGv1d4YNr5jA9wzi4aTY8p+HUdnP8hLyVdGApZaSb6pqD2tOut bpwlWAh1Apymka7jkWZIERUUg4oMDsUySLmZPn6QSmLOqn0FoXpgKluYhmTd56DCxjWFpYVe iSAEZjjcv0oSVxj5HjagESSVZZsIkavdQzKm712AUznsyawho3ZHUn3vRVWZ9UUbiayKFIdY EVSGJrJOOgdFhJhcsO/jKvaEHl7ICojTETucl8nT/F8L+iqptJyKR/j0gFQNBmp2ciInMxIf +u3UPpBd5eJneYQ3XZCtT/GsR719qDp1t2VpBXklFx0CNLzWagQbcJ0/Cc9e+N3Gf8sMe9d8 QRzV/SfVayzRKv9Mj7AFu1NMvAMBt6U1B9cI10yiWZ7pKF9XywIGYS84oEWP1PrMcGcyR/qv gqN7Bq8nmSHes++50Brd6BZW4akbNQV3pIUx8523i3uEGM+jat4Sv0QLLHgjNfhNXq5BGoKi EeEJ1zYov0+aOpQPlJlb/SjscQSYuORwV+OhB41k+j+8oqjf9KHWLOpYpx2z/wSvkEjpVBg4 WKrXTyuRdQdbpthoZv7Lh7y6uxxcuYUpcBrTN7mthTSEOEXOpMYLkedP28KkbNEG77MyK8B6 qsTuW2K8txZ8HmT0IyKot4ZuBrLFtm0HNDHVt8Xdhi5w6AdeGOHN9MWmN106Yf3UXUxdCZqn zVwHQl4aFA49Oj6Fw/oql0A38uTcdIgFkbKpOFiPfSBeuZAcAQ4A+87Jdep+rvNtNyjKmerF FIl5K7sMFnzfXXcbbkCIehrw1DaIlHpvvZbjB/dwfMiQ/tTSFDS5iaRyoQ97MjmxYVEVdDTo +IMCSbXpRy10X620IsycdCkQMMrKE8WaoOLR0dgFs118AzpDaURFoz2u7vEmnT96Td1K6Dxx vf0VNo6MHqDCqzyT+S9GWS34qfZiwULkJgJ7QLvZqjaHE7/vlyuppr+uDnX+Zwai+2+0YZGY fSlX8WSQSKW7rYEX+kqwWyu9r+T6n0comQTJpKym0JWWvAH2fwVGrwalNk6OUXq0QgOT0KqF eqqCeZy7ewiBwLy9z9ytE/N1vln5hCLjlQK3vsvntMVnHjMkEamtU3b8J/VP2pRNyPSxovVp v+xkilpMhrCOlimT2HlixHxVotqVPrymDKbvabaOKxCc/HWJ2o93KSU7+9xYvAZz09NphS+O mgifkX4AMnvKCFEJJw76fXv5x/RFj2WC6v0Fs5fRA1fX17pVy2bLZN3l1xKg8RDhHInzGJR4 PSlDmAr08koLeTJXwq4dP0M64FMSUaa+3GEFVOuQUmcEVfOVR4GgCAZv/klHaZNHDEogsFcU ECObTWRYofQPzW4fTiFbv9p5UALf+ySn2E2CuaJ47jpBnQwxHpsPBXgDC4Zsn9kk8w6XTqXU oBGoe/zwOvEcYfcqUec5GK5KfCoRz54VKt2MQf7EJt9+b2FWhiViXkoPB81tY5mGTGn+AymG xgISSj/ijLELyRkpm++r7Wv7Dd86is1VypKaUEj+e/jpP9Qrq7uShLvjq9GRpqCalhCS4iSa NIE902f3KLvwQAn3cek+doFy3QCqf7T6S8z4/WF/glvB2JEHtm/yuR9iLH1kvvgS5UVXzS1n 0q22ZBJEqmajrWjtTOu/X8ne533jwrj2HiYlsowFDNdz4MEitq6Qcl1W++q66vAL1MckKA35 2JTkiWvAJKP3SXs3p89ipWvK9CkB2uITpkXMzJpev3RtJGPs82F9U2A+x1MlOt45Fb3JLRNe O5fnd9sCjDSeJqduOKk0hXdJm/mjjPeD0B/q1zPgm9N6KUvwsgIwGlTkhFFdrhhmUtRrQW84 t4+vMszjRR4gYv6zLKoNnXMMoUlUB+phRnQVMJI2BgzG4EIR6my2zLT/Z4Q3NzPmh+tPAixz WJpAF71xe1U1lz9uk0fPCi4JHyqrwXeBvWQQzWqDSjYDlZDWSsrqeH4yAqtqJCoRVYWFeP44 n8lwWtyd0BCjX1zdgUNp4g81SZT2KWMWsYY1rk5NNAZUd6NamDtGZSMmshtpKLA26qxmfdHW dcAH2djr2w4G3umafjeka2E0nK62FPbn/piDosPz2SGhimC2kRrsOjkTwwpjsAQJNq+MuR9u y9H1gS4mZHzklvKy1vg1TME4sxH+qBZ7rN8ibZ5CuROhk2IFVIvRtDWYrYG6DZAnAIePxz81 bLcTuscoTXvUYh8jUiPPRHj/zB2HfqJw+Z0+iP0mBwO/RrnR76xXlqpO/W0OJPD5RjTV52kl QOz7rLqFGlkcn6X3j4fJ3jhM4Sdz6rPYbSu0GjdLmAWhHV1Dz18ge+RCzR43uoJ7/50cuR/m xYB3y5yqBLadM/WMm4VsUYzbRPh+wD7DKRsBBYIOm+ZTImEbvXurG5G84Ktb1PsXWPMjMze0 3yjZBqpmErBJFqfwg5QWmnXQK4Br6ijAk9HGVmvg1PTsOdunphH0LwlQmS6CaKSdls+XWbrP MZvjm1s0sbA8DIiv3SD0Yckl3QShkPjCLuiXFmRTVJacX9phMBrGxce9UNHex0mmTIxSawNd 1CUuR1JHTcK1HAC6wB0F9aTy8HamhXCl9ZQKyEEm11T9H8iCWOFcwvyEIkiKCMVERC5Z2652 ewpqg1MPBHdiYm/jZvo1S0hcA6MUmvLOCMr4d9SNP8JlV1vE/bbzHXEdTYH4E4tL08zP1H7n Rn1mO7uVp5wJLB0TqTPM174GtJinkxWwhQZRlqGp4AkiALh5c0tjoKG2TcLhu4BtlcEdlv6T OINLSJl66dodoCaacTA9uD1smsC60F7PaWa7L499JOc2i4QORcsN55ArxDP1OGdvbttJdgGJ +yfzFlTDapA5kertuJ5+XjlRFQNx/sXe5FUHrKLCkSsSbb2J4m9vWXHPTn5t16AinFZAwmfa prrBa1sIVYChjcaIMM0dOV1IyTomlhzeFoVpTJ+4DPSYPDbmSRfNIh0SEHHVMu3JSUrd55mi cJJjWgRbWjINbYwvP+3Pf1RJaAOpkGX/SfqqeP7snVk2FeqxmpBXSQnGpTgHLX7yW9CJZVU/ Jo9FzA5hNqaFviJnulLZ5EUQhlMTv7bTnujpyisotTVQo2hgwZD+CTXTPQgc3gSuBjODE0M9 8ckK8ukhm8FS+Hqcn8bpANzdnCoW73ntN5vYygWefabcjsZnCzixdeTGH7QpfjEWDohXN3wl 7g8DnIgZaVaJ/Q7uUH9C8RJsPk9MBcuGzNaW5Cgxay7jNSmo+VXsjSoxDTmh+qbUYZyOPMag WjSt3iFB5L8k3DdsDRdDJmYyumE28XltsCgZg4yxPF3ATIg3v9AbAU4D9QHH+ylrN/Wdh7Nl cby1111eX9XOIlx6qs7O/TQgU6jANJ5SuX9aM5Mfg4s6F7XDmi2E/ZoY3sImq+IyYm2BDi5T kobcOJVpZxrnLQol/I81xw7IrJHB6KRDvdWc913qG5ZCaBUpOPnfvGGozn3t+LlyUt+34MqE ShziYBI6ApLAFBOcx0n8FYHAnN3bXJFaJYtWDCcXGkNyEwJh1d3Rfw93qJnhfWlhMAlsmllW WzaLiaFolUmWg+mvDR/nyXEfnJ2A+p5CZtXipBxhxkztTR1nxrnbGES4SsbT+aWXnxxeFcSt eq+9hdPGmFljsWzp6Tkbsi07HxEw4Kd6PbSNaK+gcE1i0OFe/3heZM4L+PWASyKdde46lDWR CmsCzGTfijBhB64CpglQCJ5uEzfiI6A7kJNVZiWN8dxrvA1aH8IaM8Y0WfVoiU5WIS9F04a7 vc4BMgMk2zMMZy/x1rD6+2Pe/rr+/+GOn/mT+skIKokF4nCUer5lYykWzBJRbTVnSegceVne jXZB4ZQk8HMqLwwQrksn+PzTzz5r/jSx/64Eur+Fpr8T1+BG3i9NbzRJo8ywNsL+k+gujSCL /aQ+p75WlgLqCxg2LxyUaVL51o2u0Kf3dxVXnooSNvEqoAjhvAPaxENJQMSjfj+QV/05clCD mcJBtPCM5m4iRILQPyS6vrtorZ5iuDJhQEgTwbXpI1NV7Id5+dG583Oq+kXBjf72e3sm1RIV qJG4uBad1lFV1SypKwBZvKKbrxj75A3PFYKxI4krPA6VGd4qywWL1bt4QLg4uJfF3G9DehnY sPcLW01SAqM25IUTMhaZ9SoAuqqWAeTIUO5/YTKLFcqByc3VFdOMfuQg14JDUZQqJ1fz9TsF +GhPioxAfh++aDYoJh4VuGzxPiRH9K3zAnYR2BMQI++9Tn7kkLALiet/3NlFoWZO/TcKA8ax mqufU3LdPe1d2cJQsw63JoMgz5M40Eg8AbM3jjScAEd87MQLkL/WsSO1xCdTucRgud01Kcxu yjbMxbuP9aUdyJLHg5cnpUpKxp+esVkqeMuBAiRO3llec7HVwl8AUpal+Ji3ni/nnyhoCQpt YDf0RHVrBWu73TnYUA2J0+xkwtpeq7+nnsFwfxrtU5OrF1IVIRBrHQZHOhpUX6sV/wiUh02t +u4LC/22v/Lqxd1HF3HNRakFuNiUaT4UJa2VOudCO/qFDxGFqQCncaG9t079MZDAem/tsAmo 1u4POz5MbCJYJ+fF4LGsnGfiod2YuJtw9l8Hc4BKzslJjlqoQ1y2wOHqJh04tihBiMCF3uLs qDEW1PhScdrqQ5kgtW8675mH7fZ8qF5ttaXvGP+V4SkqgiTxRwavPEX3TXbctOCAzpPr8un2 TYPWp11QeBIM451CABk9rZfCDDx5Nz8jq5FxfA1xEtn8ldYimneJ3GATcadcxCoHezDo2yFx m87LMSigyod6fwdsm+KC4TEsy6BtgrOBApQrwY92u6W5/49K0JEXU08aozV7Cbg3JcpHgMOk sbuZTeLG2WXU/VotVRsIWh9cYIXRvH40ziCO3s+o93oLMeonhtiMiG5yLLjjUcl3CIpWTKkM 5F4ln33ykrP0fp814EwrITHDnC0fgdcQcSQPpk3AnB+lrxq+WaofOFbhVLJ4XKSXCZDMr6JD 8nsWjioDWe1odlHrSm65EcoQRtbbABfnOVOg7rUWTNIf/1hd/IhasEiXAbqdjv6/+HtJFEcl Ise7wBFxcX/kvhsgWIG7MGJEVR4t1kyy6Y0hyfYsA+nJtZRKP92s705WK/JM8xgcYPOVb2kC LweKzSYdIoITpF99uB2lgP/Xi5NVRBsOYQ4QeTiy1otWbER1qglbZYoTldAwrsDu++XUrKoi SHLmHeIVdjd72GyYJTf0AAv8HLHpdbbBb7kNd6UjNO294XT4HED2/+Igi0J/ksMmaUv3XdT6 mlOHqz36SU7lFnoNSfznNReFtirD/8Au/ze+bSCDgrdKoy7ibyRy4bh1TZnK+Yy/FGTxXQEH RQGVTBZkhlKYvtb8L3/cZ+IMQlNyXYal4BgBqT+QCFPaFqfa69S6ve1Wy95dtAmEpvcyz7YY x3TwW/U2kbd0T7gnfDOyvkeCkyBk0exXMClfHhYda85+peT3KSAjzGOzz6JxG0OjCr+aoYp7 1686k2F+1jf9tqi4cYM1xdW0rf5MW5O2viS1VkeOzluRSuYYZ86pI41gXuIWve+RdDVD/Mjl dMa8/nwKUYzhkSwXR7CqTLgF3XpNJlda4wb22KJZVs6cc514TBhLeubV0GTB+oH5xJ41eqGr 3KS1OJezomAX/ylXu3co5plb0apCDBBH0ET4X80EDXOomdNVCVVIWmyVH1tgWDQJgiAYNbD4 m9Ec3xle5lyM1uS+Pqkg+PXgqWH018Hyx5D9vhzyVyFXUrIdNyrwzZCNnH1MNtE78Kie5vGe nMg1A6LueVJptMWH20ubGOFoK2hVcLthdXtQNl7ijmthrchplCv3WVJZfDRoWBu+7ZUNtWu1 uM3fZB2Vo2g0VAj+ASq0PXlnA9Bu6ZLZVxEojN4+Y2ByyuJp+yCC8Q6knb2sK5lB0dFin7zF 3rJp+3LY7peM4Jvj1kHsFVlNJDb1x/oBms+RkxTmzxIVC55W5UXZkiYyfGm2DKaAVMf0DhT4 geM0PJtN1u+MRupGUjNMuKYQD5anXC3epLQcBWqfWAM0T7gUpocZkn+tk+z2hDpQqNPVC2iZ RHTBa2J2Gh/QakKUNj+ypWkEVIESh795MR2596knj5/A1Y20PkL2fCvkvhDJiPPrOBll9tws wafXIC63znSIXu5blq02KkPWSnC/+bCGVbLNkMDzFxjQE2lDYBR6UuuSvnbTDyeXiOJL8Cgz +uLT1Ol7nBkg5337Wt81c1C3Xp1dJ7YlUPFn61KOHoTHvahFmoaqeFPq/pmG4ccAt+GUA/Ii EiC9AYT/eKsMgaroYT7O7CQ3nxZcBVb/QqUcQn/OC4Op7IOsEoqtC1xzyBo+HNGbiMek+lCZ l8p6LpWy8tB+gTZ1vM7JU6RYPTwx4uuXgC96i/fpl8s+hDhX7Au4S3KDYsK6vFVoosTs3EyJ 6+5wprFgx6LMXe/ehEb/WPfzdCB2k2YfOgihnjfax/oiewyhHWjWlBUSlHXlgsZNZ9V8lOGi 3TJloIygBhfNVkLaDRFkQcv/T9/wMaoTclZYWDMSFoDrL+cAihFFD1T9LxZYif0brO5KQdRL rXznu0uJGg10rU2cGKMYRJOUSBhEB3sk5pdcjA60uAc9Jg8A+bAVqzbBB9ynBUM7h8Ns2Iv3 yxJ5PYpTvW4iMWsAxot2eVpS5oo9lw77oK1HPeOEfZHuI6aJmmaY4y0nC45NTpgAXBBWa+jN gPGRnz1Llty+z4UukkI1IQIWfuUHnDXaX6MVGsMrb54TpjsSaUWFBFuf12jhOXVtWiYMdCbH hhBRKYQ2Tuoa66+fP35mi3mUxtAHOFRXId+P4Wg9XBAhtxoWA8wvsKsBM3wJN4SiOvqdKGSf ot0o2RmPqnH4hNHzk6RwcsTWMoMeMl0Axz3CDO33LeAY/5CjBv8GxCTYZus0y6FFRC2ijd7W 2fDLAA/IO5asIXL2eLrl7Q6IcoTCuxmuYICD8ISXrVlJplGv9Dkq7tp2DQcbMJ5uW82HcvIi ++6ynWyLbPQ6iOVRMAaDL0ScLbFHF/ssxAUifB5oZRnOqNwa2/r4oR0jOuQbgywAxeQrwDRw Lxu9gXe99glKfhNi293CYqtDzBWXTNowrlRyoFqkgmtC8vEru66v/zzP8ODWvTvrS9biuWtZ 42+vrGpwAqMsbqXyKkr4Nv3YcOSAPFXyTYYbUx1JAr9Ep1U1HsV49R4o5B3fgQxrXjW5hnpU teAlPan2RHU8qGXfjtw/XOf/OX+XW28mR9HwBFHfCty9b0yeu6HDTXES0fzkeRNmBj0u99/n dyHV5zpQ4qOsNcaH1OVD8gGLSRPFYxNaJweA+kzN/rz+gHVwixJgZsB1Iwey9wTrlI+9NYxo NPhoRT8wWPxAAFDgmceWq1JYNE4DaWWJtJkbpFMsv8WYnCaTCf9GKWCQ1uJ030JjIGg1K70F S3X3zr4+AcrLk2nrRJlzoj4uUgXFBDk3oImogYk5JFChUXCKEwUG6GQntenx2UT1Q1WAKOxw dGsMpETriag06RbySkxN9bMR+ai8jZQB5uF8H15CFUvHlXFjhl0FL4IQVvsMvcEHddV24s2B N6dyo2L+9+Z0j0rM97c+P98/OIbpLcZ5MdOkj73btlsj/h/iIBeEmXr36GA+39WEN0wHyrQt BAQ2vkuH2sw2wilH2XsKYIC34FVeyZq1vABLIP2PgUVlymwa6dZAiQdyADWGxOc7aAugo5mq rzKzMNeTUHBaYHK/n8+HvPAtl5D6I125QZAg18OeW7BErG1sxlXpHGRDKg9eRzkDfE3z8cyW HBn1qQCbRpjDiu1NpRNCJ0ALLIPOCIwaDRce+3EJchibVNp1XE/h0545job3BX3C2MPNIlHV FROjD9frww+mzzjS1IDNDDpioPLgK+HVzNWu2zlWiDKI8SaNOomduSarxKkH2VP+9s31OXDt AZedmYmeF+uN9zi3/qkEwIvnJfIDZznsXr+L8Dx/fmnaP4xLOprlfgTMQYNDzzR4G3CNy+Qq eHA7vwu8a51XFXEX626tITcL4Rzc8TbylCNFXWr47D0siISFgG9/IH0qI6ymZOYoyLdldGuA 1qqnY1KTmWGshHmsbxt3zj2fdeKy8Leic43d8rhpwTvT4u4pZQ9GCXdJ1dpDwpUS56h8zeSO uiS27+17XKRgZhj8fEcstm+N75SE4yBYs6MrFJCafCTRHLmXN/4v+rjlleXtD4bf+qj6c+Y9 CpdTcxkBiuNRcERZHKP1cl0FhIN6ZKN2ueeNcJarAfEZqzPYN7wWpJ4l9qCvy6f/ksu2l8sx JWIfn/MPwqlmGvb37/DGYNNRbmwF4LOw//1/n+znlQr+4n+d0cIjxvicjHyf0LmAl33kcr0P Kbzppu0QsWdncUwIKvq36UXWHT4HSZXua3phORhixqA/j3J5aB7yDK0M15o5IZ+xHSj7g0MJ AwRS5a/c3PFJggOwHk1/lCrzaLWijmBCdShTv/Omj144894P/mXZCAAY6EM0VorVv8DTbYs7 HJk7BzlxfST+dZTCobbUgeiqgIySjmWhdZTwlaehB3eM3AI3fReYvi+dSUBmNDyLw53gF6a2 L04pM1n4X/gBeOYzKk3glYMY4EwSACqPtRLPC3TKOaEEzeE/12+a3OGNVh8oXlAb3aSPaXUu /ZEQW034A3cdrQhnmMwMBz4HPrCF6RJc5BQfpKVxmBSPsjnKtLLTILOKEup3TgSl5/0d3HfY gUY/uWfI1U6rCv0DK4HZyF/nREAOkrInLoq4X90apR3ScjhoLm7dzq3jKOMFj6rcE7QEnm5C VuZTgZzUjzyQeJ51F/EajHOzk8DuS5z7EJRSDbYzDsSjqCYbUSrimrsIvbYdbfVQUbvEh2U4 j3BOB2Y/9pMIHu2fh1v0lVMh1rdSVUUCZ9IaPLhZfylz2kU28eYCvyvrKSBfqKssVxi+oZKG 9AD0FRAVM+qJKEX4vCWeesODgnaAvStvSbwjhdQ2pwSpBx1MsYcdsD3eVcxIHdwXZz/c136S QBH0ZHYl/BEdjyTtCBEK17MoJQ8JjJnOjuWVYpPAtfqysMhkscIOi0XiN7Ncrr843z3u7PuK 78VAbHe2EESYIAZ+7VycW7t04PgvtAFNPV6f3LnpPToVlRDGhoe1BHRUsM6qC2MMp/aoGabG VA/zu0cylo3OQRZD7Iveef5gIkS7okF/dTMpvsFcdF07nFD9BLO/NNeuMwUNISgRjWzv7ruI XV+mvERzJloQ+RmwkfaBvgDQEtxCRsyfsDTK/+lg7k7/BTm0Zw2m+3hKewz1lQ54UQXYqerg FwbQ23f6zPlOZ75h3L2Be/SIRDZe3FsZfbFTglkpOnLz91UIGFANmPBC2YKPaGOFlqdAxuMv jJVFaGAYLiEqIG83Pys+PNzLPkRHkj4J7eHc1I4lKr1yByjCQp11AcHA1h3zGIoWpUpkS/xr RaK0niPCGHZH47WcSEImcEB8rjFwOpKxTaarafeOwP2z1cLLR+l72coWrPZL76kDKvF+dHz7 Eq9prB7UV8x6rL4xauEx9JKxOs0pHhKZGpG1FrUfywMA2kz/HJBUtRm45aXUO4gM3Aga3Jr8 dY45hOOfM3stW+0Evzyz9MOSdGi/uLs4FisIajCYBIvvdRarWJoT45LQheTwYsfB3dptrbKk HdKOYwD7m6wGepME3nqU3V7/5iy7OTABrs1kdpVbWQfMDJGcqezdGYOCe3OHM/xZF9uBq8jQ Fh6IJX5MFQVekSrzUEhKAgTyrpbwYEG8R/qaPd0IHtKdLWbP72uZQwlO5TNzgk0vfAHMdzM6 28OWX+/sAOkwO3iXjzYLkEa4+f6bXHszlt+lvD18wlFFE4vBcUS/kzHqt5ao6ytmB/t1tg1/ FtinCd73Qc6InO2wheyrpJB7flR1W5aOCcN/sLZibgB+hbJg4J5PqPIlMwYW6NywxXVaGSVj 5JsVcGytjIlmr4Q0ydjrNBEvTIPnJLDH46hGAJ1DAwiHVsetXX77ngUI9v+lRe//wyKOja6B 7GUF9mcbbyL+imwl5jwb4mU809et3CYlBcH0QCkdMVFG10FAYjKT3SRGG6Pytq5OG5J3dbTh 2HEKYSZ8FhoxkcThycWnit3Y61UyHxBSRASlU1Mm0YU7ulJxsXC5l1g5PMrdOgq7W6uDTnVZ pcIm2y3/rdFQ/O3nDVogAqqK8dDCSXpDHSTyANVG4Xt4Xzf+RRrAFnQK0bSG0v7lOGn6URdz RtayUo7GxkjTZfkzO83pIxlWkXkL6fBve1xI2JLd59ysTZ9ScO3ZHfsb6GuuFaYb8ukv1o0+ eMnEZwfui78U6vkXHyW+0RzLTXOMTHC0jW7XP+RSYtfBdMRH89Dkbn9wM3/dExd0B0dSm68R vzm30r62Zgs8k+oK889H8pQYh90RYe8YddrkH9VZhWNidYq3PYMekKl3lte6J4t4UZ9ZRkWx +Rt+cGtKEhpRWMTZKSZZtw6fgpWOQhiuiJCnopKo9n8yJNEqBQyjQAadtP44rNhJ2ohP2eCp wlIx+rbGHKioQPZTFaisBYOxesT96WsemxPqAODtICLquCnwEj59j3oEmK6UGEL2sHwHoTG+ DSqF6DPywqjG40wUzeAKFc+q/9RMn+BtNHVTw8ZLLouGOvIcbY7xYsPDr+pS7flGnnMO9TzO g5xCclNel6PMIDTz4KWT7vEBr1QCId7AlHszw4ZdFw/XihrGHBoo8UcEA1YcsuXONxM0aSx/ yU1PdGm6jsieV2/iXQXlJpHeeMzuc3OcjE9yeo7k6UPAcZD3PwpKFmKWEAl9ophG0B5VDJuf UgJecTJMbtgO/qTiDqFmFN80giCipK3HHcBGIdFJHu8AQuteZCaS7/+ICTswEO1GcDRbrmEY 9eHpr2UbwcjpnqZoxbPmXdOFuyIX6bSpc+hNJ2dI92CwHc8IYJTJz053RdR3ObuC4cXpR1lM oUXX6MjGQF1+LfkhCEkzRP5pzKgl+kCszfdNYrQYGXBQ8ouP5Y/n0RGoX7+4tRZ7+DfAR9aL LLyFG4LRLBdTA341lqSumqWc3+kZ6DLUm1vHBnkmFSWjbJM59gV+aXniBKiZOPen0+g/2YoC Hmxko+AaDMLkXLjis+9fKS/JzMUfxIzP1wQVjGGAnKyJp8btTkMySz7Hu3DIGeg+/MIwcaLP HW3hwOulUtJzLPuGAceMq9OXSZNLboMJzZ9kWUo+26Ay4/7bVCSSJo8hk8aaMNkzVJGG8tPB en1dGTrglLLemsis2yiJ1+Urn3OJBsEDhnCu9lZZ+veHme5UQmATvk3u/GqBu6LuChKYKpKJ aaC+rCKitY9PFI4AgYTjetr6wAT2uxaGeFQFrVMjP3hDtzqsyyCTUh757VZw8gu2O4rINUs4 M/HbbIISyqF4nnVCIZ4LTF3DZ7lj9cHAT2QDpwrS5NPjKskOO906bYGKwCMkqJQuJH+X3EPe BkzON+09dRVLts49ofxEKNsh7P378cu/YRylBZHYTNAEPN/15japhJYEAQcMCDxiqOHN6biU BzR1VMfI5SL649H6iyGpQMsV0FyoQM+WQPpi156cedGSvc1jL8iFBADzn1OegpSiTfOr9BjQ bKiq6UJqVsYsjW3eKui1ROAzmFarmgbo7ddCth6GC76QIpKIeuvEoc7OhQkFaPrnm8n6Gmqy 2kQyBECjdMDiuJt/cCOGiJd+cHwzMI7fdHJWkjCdw3L9B/u3jwsm6PkHGKZuozpZa6WeEOK5 bcoSbnFiSPmT7VKucFfNrP4Y+fE2w/jGr1XLxdwr0HgT5p7Bw5lzuYCanblCPcR7JWy9a2yX +is6LFgiF39dTySPLuOXeCpbtRkvs1W542Ef4RyF3jNT001AAjVQoZQCORicz4yju15PsgZo p7quoPgVS9C1K9P6IqSuCXc0bemDUkAHrVjt6aDBvPbr8N5Jhm9vCwjEzJSD+Enqkh3+Qh60 Hnru7DAlwZuavznCDlr9pLTenwQUgCmeWqWQ6d2a8SrlOPWRPOFjMS3vc9Zf6xt/YofL2e/q eQbXsaMj1m6+8YomtW+0XArEhNMw287og64lno7vpQaXR6hOkuJ+MxH67D7T7mgq4ieuaytf 68ikjdANO5bc/YQx13LVDTEyT5l+TI2NOc/YykYAY9n+VEtqkRy39ijHwvvNwlQqoPwto/nj 1sSgrrIh2QhxVd35q4l1ZfBFyJ/zXZHQ0lE0qscCXz3PMJFEoyH1BHdqPiiRRfK+6fbIlmCH hVcvx8ud56dCRkz9cQOLy+vtLb+iXG6wBMTfh5vlQvZG6NTTBwq9BBWYmGvmJHJjfAH2Hjv8 SjRG9RDsZh8kDkQ+PO9bNy3y28j5gG6gbcLdUAa52AScgPTfYJ2ewZ/03ofROd6GovPtKYe5 hW7u8GsmmWzg4YIkUWagBFhNoqdOrBnB89J3iPtiEfoHpolW5foCxOlZuBO4MMs7EWppsjG/ s3WHltN4wDl+F+Sdvq0P1NESZ5KFHw7xO0rlaNwtAhAs39YcKAbFGUm7zHBa5al53WI1C6Ck HPE/v3E9QkysW63EHvMsJXmczbZyw9kMhg5uNtXwl6YVonu41xuy0VMBtkawz7oC/1szBsTB 41NR/xkWGpjAfUNRCpYhWWdwYGC/i6UR6y2WZHTJ/fiUZRlFFHTxUcqKUUq6L0VWUDQ2R5wt x4vMx/M3FvfUNvyz+4Txqu+XF4qoQfU84JYnWu9kaCgmSZOmRnWS58xgdegdB7oedlAD0Xaa g2BV8xe5ckSz2pr8tPdXEHzZ7ipKknBrn6FdHgT4Iv+ZCGBNV3X0asN/pQzO0eMlO1wHPQHR Jy+4X+si2NDyhr6Kt/M3khA3LZDJ1sE2woznmaPCjhFivPnvN42hzV6XPO30aPTVYcwECTC9 d1BiaQG/JXai2Jj/rQAzGeOnIsMXbaiNjvwqvQDUA+hpIGtzImGjZHbz5+7PnVyu3P6gHBnp 6fvBciHkhrUBGa9RQLra1gEgAcjVwp9G4VGO6xYkA3TC8DHj4itnrp17qksj4pUywUsdR4UL 10EfPNUUId6oxGZME4JwpFDaMnPqz6hXCuO8qMc6opfvblC4/0seMl0SA3dDAleGW1JMl4eC Q6/fZvXgB57eYhqJ2oXvG/zaTE+RYw5Qn4Ep0sv1IW6D/GU6n0flz0KUK3aAugB4hb169l7w 6aNXNnFsQNWaPHmRp2DAuma1VBpvkrnuDOcddhjBAfl5PFTgIcc0R2q55zOHT1YZPBvPVZ88 nrubagxobQuhUwNIXGaRtrCCn4wwZ6zInWMlGQ/986UcO/WqvHCyj3y/7tgSXOnBAl+69Pva n1ftTeRF0opg+QqknOu1HLNSN4sk0vvDy/s0/MQEFtkhE1x10BFb/8o87X9lbQZBO4kRkmlE tU88ER9vY7FV2lUnnDMditjf7uoeM/OVksfYRzRFgzcmpELaoyip0aGq1+tXza7O8Os2j2Xn 4Zyxop2h+x4qkRS33fOJ3cP8g+LK3TCJ1d/3BASESaOFud9ODD9+Qwa4lIHr+DBgCNJSJdWg D4pcbGe+dU2AEXZ5fABgwSSCegrZyxRSggdHiW2AKCEreVo1r/sNjpn8UOWA5c9/UQC7rhpN b0dop2mdfzrw35cUl66hmjAxoI7nguQaBs2EHdkM2as1WCqBLPjDY2aDoRFN8EYSjtVQcz/m itRJ2U2CgrTKHcmnrPK3CVV4Q0Jix8UtohQNUoSDTq6WVBBIIe8PvRd2GkLcb06pJ1A5DoQA pv0d+XwP/R2ZDeHL99zTMd+HWvvPFwgNYkFUQGqG5D9PUqcjuBw0SnFhg8cnDtUYCbElMRUH UfNZapDghzv3iKgBDId2jXAWg9BVbo507hC0FFh94WX9JdA03brRPwzcSPDOdKGCZVngkXJv bE8j/LuliZgd78+8pL1QwpqRtdYNGL0Wwle7xnx0Ca+vWMyBIB+44G1wB1MBnsAj6MHlSUu3 zB6083Ja9DWJFYAjw4GIFgfSXoIu88PwZPkY6kl7eva4/HDYG6LAxB8ymvwuMSay0Gb94WdP iCr+uCToFTDjkeKSC+cEjePIpewnyVjI7vETUhThn7XIPB3qgVCKtHMU6NVcx7aMjM+JkEyv 4nnqn7RYVr9CGxyDN9J/Hdy6ieWrHc18DXBQj6vlEQueEpjxk2yvtqGVPSJCrVh1TLmA6s1i bjBkq6iVSe6r8B8uaeub9+8sr5i2YKIBDHNAxx8z6q7kxzFqP0WKMsYnOLzxINIOdwiig/k0 IbXeIAU3cUV2/F6910FXP0qX2RxKhNDh/ZFCQS39ULbWFzLZYAnNcwMaKxZvG3KWMk8Dvhpr pGR3qmJYJyEiAtEYj0Y9oylZ073ULXWBGshDexasfRQPhIWvn9zKtqVgb6WB7PcwgnttqVpG +NLgowuFevatkJlFM8UnfgzX/mVlVCwFtj3EadKESAHz6FXUSBWgWc3liMQIPyLTjmVXr0OL YQ1DItjlc+Hi9BjQyTFikBElkseIVuyj804oLVGSGysalGaKvwlZ/RnvPX80S9newPU5kUWZ gbDoymGCtyZr1jXnw6IOjPJRpp7k+d2Itz+GoSulh8br2dOyIK/ZDp8CWAHTRMTDGCgSMTV3 PRJ2RN13H9PSYtUn/UQ1VQoXEqMzZzDAGqaCNcgSfqoKqlj2SDnRIZVN+NMuIjIn1tUyxxpc LzTyvo5qiFykTQXhqDVYNGJmxYvIboD2QlbM3Al6O19FDE0rzL5AqC95x3Evbxt983CuS83u w8lFZGQg4xlnFAUv26PphmciwFeM0T2QMKwdCyTJ+A/heta6FW0hOT6tZQFviWqiTY89gnRk K/IysM4w0hxMzWYi6/kVflt1H1dJVSQTrAnF6mIN7k7yFar8mEY9SpM89teK3tdv0TXZm9dz 1qZufyUAaGaSRHQoWANO6b3yzik5Sp23KTQksNaGjelgEHZbm5HY0HybS8HJYn2xBDIfQbrV 8aFAN8wiGNlnK+Vn1dtQ94TS8nenbmOMVuMvSPoFdNRun86Kq/ZhrfE66p9uZEivG3WH4IQX 5cmVv2WNqSwMG2RuKes79iRkNuP80NnQdDiaVE3tdG+rgDX47QPEpw6Q6oF9nmO6mDI6NtvV n+M9D/K7VHiD8+oLnamOYJkiRSwZHumw0vsRP4+viUv2Y9H/q7eE8hol1f1cLfvJvHmai5Om FIMPOuW/KsG4hUR15g1n/e0eLltr/0C9014OMn07PFEQXTO9Rj0XTHpdmXuoFzDqqQwKdCa7 7GhgKoDH3Lv5XbPs/lE9pg5iOcwEDGFntaAN42cmkVwsXLT8e0z35t40Amc4uVIZwgDxFHwE qPehREvN/Qb8XPicweREtcYESuDORWsUOtihudWa55lnwemRliEh9VtWv2KX7ifpuKRfqZXl tq6NCcAeTBOzUA0uX8+fNaIE++zOEvIpSWnPV74oEB8U75eWuwAVyERvcKCSpQhyP0r6ypq1 S9hrEuj8FmvXvOPKnCpF7/zmeN0iNmguZo+1nanbbTZKknksGEpsmlpDA8ekAI0/BEWHVPVk pHCEp3btmfgEnxfFRRtJvHkJvXpVSaXE5fYCP+CJtsKlizjb03Grw2tGlLcxd4ZXvpwczatG GUF76Sr30RROPOqbTsXJ4guOTS7KB9JHe141q1x0r3NzmcT60d1C7/tCJMi/CW+EZ+Ml68NO 984Zw3jR4GxX+p7qYM3URsQMgPehry2lGocBUnjRx0NRfxN6kjPdWRqu2yVyZu5LsXgfJluR GFHgX+wINT+qhKEMRG5PpvKa2JEOuzxc7gbYW/I/5V5OdgwvBb//sfguYn5m59n9HqoI0P7N mYXOhLhRba/qEmEUvy4kO04qTn4gdJghh6DNSEbxOaQ0JBNSDXB8umt7hHUd43cES/wZ5Oq9 mM2DlPtFw55UzrppzLUe4FVfDkLB3o+lqVqipxK3SyA/fHs/OLu2RrOzByMwBGHV3cUiSjE3 mBRAP/Vawe6KDbQqL1JgiAkRjrpS5OuQjOJJtar/md+Be2WcGDPQn5391tF0HJcTQ1Yi0Yq7 /urVuTrApXGfvDqk4YmSysnrzhbqVCPi/H7ZddZWD+wtTjEy5srLYpnSoYJjX6IR26SsK1EQ edKWniqDOadzIkeJqAwft2kWDQcWZIV3HOxaH40AmedDXUM+P1qkLCKAzAq+2W7rQVSP2zvb o8Be4RLDpmM2dAoSIxxuhtjaA1Vc0KtfbeflqE7AhIG0GBeeGNPhoyvVx2hO+U2g64tWs0DK +fm2C8bf5UMYuqg33uA8m/ab7hNUA0SKyxOa4jD7l502d26oAR+WBfnOlOpE7trTwRtbvUai WTMmQwGoL1jnx5DjC8ZUzSmffAC+Rrcl7zjaxQKX3B2y6ruEtdKaoKHDG2CHB06/mfwRLsyQ lNAsnHUvRZXO4VDGRJN2VA68pDak/NDngekI25LeNLtmW1fKnPwc3yE5IKt5ZdoiUuYqcJtS hOWX+FUSUdH8kxyU8JETUv+2b8MFKWvJ/bT2tp9LYufjl7OC5wnm/PYEy/uETAckK6BAoxPB wP8SyUeJnlah+Qwt+kX+m7vZtWGmtDuqhsY5Mr95kKtkq+uP3fGYfx5SktpGpCwF7uS7AVrx fVqGGxALI7CGB0jk4RXr55BbiJhSlEPN3OxCvanYDuElQeqRsXR0vkLNj9M0QTIJG69wXNED JpTQU4udSyaNhapzRBZ3HlEZIUjoRrq5FACHy2bvGE5EjT7g9nLfp87rGVkn0TP4yJ79X3wM NV2l5c74b67mAnzBwMr2/p2/P+XARyS1HfUFthTbbh7ATHLTDumvVFkttLx+sgVkmQ9qFxAW X4LXdEOTUENCnYcIfuop5gn29t73Om5j/wRPGGMw/L6bv0qFFdTiPbGjpU+hj6BUmxmiKk9W OBLBmzmGeFNZumH6LhQshAR1H+Fc8US7Rn8mq3DyZCE3s4TCDmKqWAw62DDvnLa+K0jY8zzT Y7qRatfD9CD4+E+06Jqt3exRCIEvxTGziiUVx3X+eIaZRO1lRryt63Dqwaf+e6jZPI0u6osH bkajv2UdzYZuY8hA7AsOdwIfaobET9ygh0cxA8vmeDG0RowCvjt50589tUc0aKKAAlXebDYa ai2ZMgiq7QPjAAjbHurY0PFKMx0UeGfU5/ORAmEM+Nd+Yh/+5mKt4hhGS2PUBbQ07ipASncl MO8E4nh7qOG4ehMXcVBSuaubrd95/9Hty3GIGPrcAKd/vJrgW/eLwBMkkTh6kniwy/l7DhIG WbtoeF8vl+J5Z5YEyLVNFJjhKA5xeiR/9mur28fOaGC+e1e6xux0R0/1C6mYzTl01VDpNKIi 1u3bcSjuFK8rIzV0Mlkdkpx+E59P5dgNtvUI3vKcXJfwzQqbTO7RSkgBHvpRGTaqCl9RuUrL ucIeZaW4ldUcIV+Rrzef2HlFndPHp0IvbcrmXLOrOgWzX9ReCiu+JjeLjhz4c08jHxBxpOvX HtjEdlqhqnwPWwn+GdY/6Kwhm4VHS1hFbIDKlZc53uBV48nAXOELF3nCpzW5ygyyv2ZoIRIX 07qKhN9ysn8gMwe4786c0tVHoih/REH9slk0SgPmJXPAReoPHM4Dv77WFJ079+gqIRcmi9+O bzrnrnkUBnqhMsMNOdZEJSVyBmMdkCcn/OxESE1DHJ0AzBfuxmE8BKcQZKh+rm3Hthaqw2Pt K0s46FlwtqXP6BDB+1gcu0oVW7AreehENpU2yRS0Gs+yT9W2q0DLnkTtB3fpFhD+l0TMFHGn MBHANC4/PWZh3d+pGo/SSzx+OQRMIX/FgGYo4XHP2uDzIqtn3gLkcXtww8nti90MIZKl+k5M jo5PVxGJsCNec1zYenXiP8Q9JC8I9A2EeGIweA/IA2QSLx6L2W1/OBKRvUxpSCRn1WnxRFPV ObB9vdxsC9kdOZRWGnZMvzjaS0IjRHPFK7K4K4wCxffBmgx5h0jHZAyWjJ7N/8r2g3eX/OSO 9Ee856dEM7UgFz9PwU8ay0xDQbMqPhSfhwbtx22yN977RR3tzyWD82VyWwUlEUwaZoWGfQNV GuE+d9lJyVEPRESpW0n9VTOaYVx+Yc4HcIcxzQ4fvLwXSVoj0y0TFWjXcRPLnMQeRoVm8hBx WkU9oRG//1Y7ja57BjYFyp90HnCaaIhUpbcpaXDjh0zpgREo3z9QRRD4ysUBer5/M4hiR9+k nLxSH5Lj/Qtw+wOTfvhvNrKoW5F7px8ibZZEJJHzcBRyCVzZ0MIBGoaKHTV+fw+GipGCkWXv DK42vQpLfYG5Hron4gh61pcYFoWDZtORoDFroLGzhlQ6QpJM4m6RUgK3U46swgJQW0RLbi4E nLXVPp54o5l6Yo5OoDiA8YUa+e754wr4yJ+b9EE18IU/E0bKdK5Le+cYdg303VB39kUbeOPf /XkGqYtooK4+em11zjPsGTNI4Dk1zp2Q0xwmT+ZfU3q0XjM9GYf3kviSKz6AVT2rbQ+8FtzM D8tiACDIg5vwpsSDOxDxfh5w7ui9W8OQ+3BX7Jgq3LnfjUXHB6Bmh25yh2ykCxXWNwvkgcM3 HXMxrCorAhtmHrwiAukXDhxUCLdflKmgTRtk7rHvIE3VvCnrMBzvcbI3IzjlnehrKs5ahgzx o8z03z/i8okxaYQ3RfzP0WH2QTRWx6k4AdycdJlS5dW6UtjFIWY0IB/l8TYSX3hBVbUPTod+ ReVhUvIKUxCEKE+NVZZag6x80DiTvQKAde4XvU7wNEhTZ0aCXHJz/MZVChOOs5I2aYmlHwru JguVtXgodB9cYaTd1SZaYWsZMsSofNsWVbXJioRrjQrxwxQFNjMgUYFy7zCnIO27SlP98Xj7 d1MsCjXdTuH2n70RhXVLpVr0SRzMc7xo+8zajoZoYSXjnUIY6xGs7+HVnLoHy5Lynj388vYy rCJkZztamz6XYiCwXNa8EJWldtQdsawD6F6g4EU0V05BMfzet1B5otO2p74CkNhhG3ikg0NM KtuPIhuDSABNTdfNUwBQTK4X+etqBtnFu4ggbuXfuiWTdeFrBip3KWHccZnHFhByVsAkdznp jyVSFGmuDZqOrc297Vl3B8MCd07dc8n2TYP1g/Yzy+opCH47QsPM3H0m9uwaU7rVRPWsAwjH HYZCTO0WA7DjMyJYEQQipbmYsq+0UuKghY2rqosq1qE8HnH4RKunuu7pOH1PoHVLWss3PZFF mi6+NDpCTisbpS36T40CuniHaeoK03wBqMuAHHKxCv+Nfa5BAkCyFuIkCd9+3fUotb9kV8NV MrMcCNqEzDaoodZxTWa0J9aPaslTdvdSZqSOdgkGVMWZvPmAi9indHcTRLtnY593kxqGGJPc SMyPQR4Et7gJzC90MbKou9GjB2ZqxRWznwcQ1FT9gHfIFm6t6rQgoYB3wlgeXilPVP6W9zCF VAxrMm/NtaZrnA9mavshikNWS4kV4baiojhA4aP+CZLXO/WeIX7o9IAxq73UEJKXClrbI6D2 J8EAqoaJFgB3v8Ek0Aw6NkJ+GT7+1PuKvi/uuk2m9vEl9oaz8eQUcxXwZR836i5JKaV9NvaR L7hCvcC3aGLMYBiySGxpsZZV3w6ZIEWfoB0j+2+ErWpqH3ChsXVAjkoBNF5AHtqSwgG4Ray/ DTq28s0MLO1ztRlWDhUskd3spZSk5vO3PWICThfTbyTtd2t1POz//GKl9RaOPCFTuVl2yMiA B0mF/GSwi16Nsj10RLPdpBjGdpI584aUqC2tNfPh766I2udrXOaQts7Yzja54edxAUSE+QDl swMYeSl66oeqBlzLKIZC38iW/zUIE8MzCu4czObnGIOoqJ+U0T4y36e3PwNoPRBTzrV7/L4d z/n8T/fxIhCfLVvZotKjmyiO9Od5ONJ2Fe4GLYrpqA9jcDBbTiHwO2WAnJcB8b1cbZzdoyqN DxakOzdvXoMH53w1VpbMGNCaybhhOFyNXRRmPL7iXiOVaEzSZFg1yCy3gozVT3NRzpfSxX7F pRzq9suzMnC9/qAzqRekYTSu6l/FJoR4m7OcrxaZV8UXOvMroEiFAcq7rxVsqKD1xYK9tJYZ hagyR6Vt9DpSW8tuAmGCr5tRM8hIJxl3Zfw7kIUcDCpLf24W8Hpe6NsKVj+tb6RpJgtXxRMv aiiemocos1lLJu7bnj2RNVDMcpn9p18S9pptSWWVDY3U+3cW5KRVeKEUjNGZB9bbuWUS2KOs teiZgAGiNIckSoTSIQx6X+hPxM7UJkqlP6pTe1VhOl5ZmIT7ACTPYzJr0nkcQusTMJg9ssXt df+w9Y+uM0V6vy98Ygik2Ds1kgNDviwWT7G5TrC6ZeDisBXGE73/w1VeIypAejpPoCRT/Dhy 8rpLQlH2SRQOkUWeYVxRBOb3vSpAYs3HIQxwGdnlSMGlZJIuxQQA8UwM2hF9jLZPzlAKU2iW prcAPoo6aqKGVjucT9D70CztPs2a7uPWvTEL49a/wGkufOmno406m9XCPWlpHE2Ao2y8ynGe FqcZM0f0ijSWCj3tQmgt+HnF7NSdPJdIstn98ITStF0I5LvbWxQH3zmIjEHOEoLhMrMioafb wp6iT2zHC2y03MoOfQkEqbmJPKyyStpt35aPPB5N3J7gJxhxO6zdjhpeEQKvvKDti79hsKQI EmuwCWR2RJYQU4Fd1LX0svsdKbOKCNTZXKPY/oNO3yU+iifA4j9g/czdJYoYRrR8crad5S+u aI6fvpJXoUXXn3nsEn+ZFITE+o7Y1mL8HpNkkP4u9WANWfCZn4B2kWIqyWm39hesHIXJhGyd fQSlkcgcka2b27/zthEwdT3wXSBPeeoD0afNiWvA5A6A7+efMWDzroLe/5SQ5c9bePE/mMi1 /XL6KGbq2xBbRRa7+gVJQe4ShQBiah2CQUu0UKgmKdRiR9i0v97QO/LyKpZYzKAgZ2FNk8Py DCfyiN4LX4OZKu/ZjsujIqKODvPHI0lgQggwuwvwfp5y61eiYtift4l7+taIubVUhAst/181 moy3GHUTyIAwwTNmKDzUDKnLGegbSNLlIOdSrgPIxt3SNd147IAJl+8jusXMznktoa6uaPQH Br6XieS3u4lw2TjL8cYlzHY/MdZePMHWkpjFKKf6hwC9fCAo+OqWAfHu8C8eGvB18CsdB0Y3 mxfcGbD5yBEEZdHSFHmZvrUIJ3CW18+ABp7OACVFlfph1fNs6UrLJMA4+RF8uDc3C7gJwGai s+7TEvgcJo5KOI2NMNzPH4K67IzyXQCxsrVkN+/N4ksnICeqwsmVDn1WrB9J3rZfz6+ClvUR IUfASpbN2v4ard/WN4Alkc4THAC7a49zQKsd+O55KOHEvFBgQbmVJbSgyoRlM+DQuYMV84nl 3quVeeJSc0fCLWY9EfLObLEyY1iI4RbLPSTcigD4n9klHPASb8WVgOcKHX7R7F29pU+oLN94 7WRfPa3FGdqI9UP6mDmVlcGJzQsN3CYxBAghyZKcyOvUHzzN/F/XMtXUuAlNE6HQsjvLK0+e 2v3fGFv6n1jmB9GcmQCam0cZ4rDrWHAUez6W3C1ZFVSBLi8mnFjBHXzz9wdP+f6ontGsQ06j Dp4veOvWkXOjMv4xpxABdnv0Kd/0nImHXQ/gnzv1xGs5rWClJseHcDMmwX44Zcr1MYUfSVwi AXEsTha9uKoSp6+7SfptKcsBaOQy2SeJtaz0vmPKMVXnMr2BMhsxBMIX4j1bDVorqPqzICK6 nBSMiGA0cGKJK8A7N19BHS6F1RukH5j1KFAnB7paS0x5HGZSP/ZqVHzYc80/rip+aYQejeEI lL1dNM47iyY7lQT+hwUDqE9SCCg+HZqr2alUoxOHVVqgKBOv/2sMms919YGblVLps9SVBCNO hiE9muzSrz8SneXM3qlqIYTMQ1fW3ky8t5L8wiwsjJX0jqj8diJilYfKUdO4yWeCfUi+tnNo cSM0LWGXjTpT1yWYzqu6Nkwulo4/g7fvB06tdLdjZZBx2jvjuhpUDHv/rDyf6wAuNsGr89Oq ad/vYSTO3PL9hzLjOvLtPuBmA5O6/zAzaWAZp5ip61LZzvxCySygb7Mq9Sc/7Zl/7Kez8Kjg gRuca2sllShsYYts4q2QulW7L4BJv2zs5EosGXvi6NF4T6pWUri2wKWr3HZ3jDx3/iWQkOeY 0ontEI2YwYhRA0ocUtFaqVwWKs91hA9QAHPOfLUQtiwdcqH6NpMtFn2bxR+TBhLRl2Kv+9De JSu2Suy2qi3DxiRG5UIZ9VpyJaGBBKxOVatngbltZXIQLkvZXc0WcRWeajpMsJrNYbz3ZQA3 aNrCy77qolqzfv6rzybSsCgA7W9bZPrQAYOuXJGKEM2Muy4Xzoy15KQs+nXuwmfwTFIYaedZ 4tl8KJOrxseZZXveNtCprJeODOKuu4OJ3GCA23xlWihsWrtbyZ6jZgitOnyrkq0jyDjnCK9a BW/79PGkIGTCpgTwBhlBaOWSh09leHVlKlB5jGe8lmFQ4G/RV2F2GsGXTH2rKFDKF4onOkUW wKEBK9aE6FbIlYc/M6w/eCfTUPRMUtL1FbcHH46nBQj6ZuAEGXLvVgwBYLCaBtpkVtTBaSZ5 PT16CZaoOJtg+fJBGYkHzglCZqlOqw7axkj+azrkhV+nUpWJ+jspyHm4XgztQC0L71w1mq9k HbNFHw3d3gqt5VOV6NiB8/QxQg7JN7b3DBm0+eysePU/ZB04eOnHBxUEPvmyyIYYpNCOE2Kw rIQko9yCImmYqUjgwvJh/6Vbr4hyc4LKnCCPtewKjaL9ByBrWJdzqLMxTwNjjljj33Bu6J68 HBHpbeHxglwek8nu43XZON1O5Rf1WMC2cgmtdDvaxxg2E9NvSLsOLPmM1hJPdpxV3ibi9wou iOUPxAmUPHL+CInP9f00qWCgIh6e28AWsU7rOZeAyJ03JGG/wOP2oEAFDyAHhFc4Dgk3ur92 nWZ4OJLg7o2x0rDsO4YFsmoB3IJNv8JSmUa5bQuxWEQ0PxXEzmQjWuV/e/5gVEmGrzrP1GOZ qTvctecmjuSugqbzWjroGWJTS+UZEvQJByctvhqQOg6WvnhG9aW1kU2le+dl5kZPMFVMTyPF KhkJ87m1ILxHqGLjWfPm9aG4KjGtL1RB+q4wQUEB3L5m5kLkqgdFr8wFu7EvT1JLn1QiCnEe QRHeV7N8fwFLPF8zqs8YEiUdCOsi9/6YsZWCSTpq0qruzrDCjWVa+bEmTVFhfHCibo6t0p6u PpWEKL7RN6nsR2AVcSIxjA/V1zZgZv4Ah9edpnuL8PTiegeEBHeN+aYQJOTSceHyNp1k7TF8 a1m+j+r/E+6rDZtDkLZqVpFKAerHGjFPwOcecJVpltMVz7uG8mZzA8ZPsQDSVEpM4t6Ug+wN GxlSbwK78D9oJAbwEC59cEgGLQC+vyu02IcWFpYP5jUPZhX6wGhn+8w50Mh204VwvPU6+EPy ipPg9HItVk9SxLZ58QSEKJP3hqpoY9KaKF6wvo07p1R4ZuwsYL3T/RPbfuh1tGGj+4y3Ryzt 9ggPo9Nc52Lkp342LIoYl3ESX0XfRowcWCVlJktDbZIx98hEjYT8lGLtSPGHSkDSfp0++/0x m8GwsyeC+t9hpzworpoDN444EoTel8A7DPj6TPLI9z2rJ6qweP/kqXn6Yr6CiXX3GAf+azwq 4BEy3twsavJObURkMm6SS/MspbQ9KdDumCWPGGENC+sAP5qqZoMjzqeWVjL93++EgALh/Ux8 7tSlZmqIomWIY8//23p4DKX3NpTMoLdtATw7rtgVbpF7PfsyE7tlBGPVpdCXfiAjkgor7yng 09fvV9Jrt9Fypdk/MolXd+1XSkW/9oPjA8CrgVH3m++ALyFduEdXGaehI3Rr8SYX5kNyxJRy sMwNQiRMqqpOP78bM6cvsgPfZ4t+GmWJz6drfMHrFPV0jN2OnQblkNi3uUbU1uXglA/GqnhK J/4pZP91t4e7pezxGNUNI9PGmjkYMi5wBTrU1nKvrKfKHTMHtY4fywoq/c6FrcxmVWvFfa2q HSMXpXaRbiHSvpWND+//h7eJOsqFgoJTzc6U4wnmcWn6Ff8wGyKNgde4h2lcMahR7LdrbJDS 6JRC/NV5V2t87Xu5kf2+zgT9uQjSmhM6+Xcug+enc4r3fOuxv+Px0iK/AmcTo+dzN3GH7YhE EKRedHkSLrsLz7RuIy8i/vwthpmZC8i4LfEZQbjKTgz5lrvSuzjqlD64SjSlYxlwkl9nSE19 Bnz2ErO5usZE2lVHzC6yfxPwJRCFMqpcqhZqnmdwEAxtPLGTC/2tHT0exixLpQ+daP7Kcg4L K/yYjTnUC/mieFzkW6PNGK2NufEIRAguE2N8IcsnVW6U3AKL6uOlJoBM/m60mra25/cYlDDa Xq35bkNnNnlvAnJV72oAsp1YLXr72OYyfBd/Fp5GZ5n1I/pC2qSWgOgruYy7rNfBUUSeLLCD by+ttxTPC/cxF3JvKnZ4itFwMGjoLgiD972an0zoIx2xYi1uUuLj+oMZSwvSl4WXQx4NWk5L jeNd3lrZb4m9Sx+PbX1giY1MhO0bRa4czpHaQsvOiNj8mjMpvOPvfBrO7IHSfw0VrgIIMeFB RujZttiFl0rg2VKJXbS5pxr7OS/53TsCU6IzLX4iWfw/oqNw1Z1eIw2r4dcOiNBx7ZoiFFqM 3MwBlKuMQX+uy7PAGqxRfKRp5W6M1yJ4Qlulr3+uhxaY+8bfblmJWH0n4YCK44O6/c+OK8TL SbFz6rczDbUBypsL0NFTiHOO6YFhdaYq4fhST+y1110cFjanS039nr0iKkgr4+2AH7ywRDw3 u+ZyyfpoSEtyF3Q9ziECcN3mzugxWB4V+QSL2Nn4FXRIfBDbtbj6ZVOUa3I65LTUg+oyC4Xl /anmGjBm2VB/B+J6PRIeBxmUFnsvFrlGA9NWBX9hp2hOW8uvDf4TSTkIfIL8X+CveAIj3xy+ eUAsetu85x0Bq7j8DzIApsfJj+vmV2A/8yqVTrbGiOqCRstSdydTQPC6cMAKe/02vr56DjSR KOv/ffO98cGNOHJ9OBi/HtIF5TMsz2CUIRWfYxoOgOsGSXXMysG8wXrDz9QgyoaAOUBfLe6B 8nsIauRdQV1fko2jWJ1d0z55rwRdNvPhB6CiOdHSC3+Od7h70X1Y+0uS4CnlK05LnIj6HnlQ uoOkokMvYkTRGuHfHqME6ZjHscWLs9/RgTRoOORejLAVqG415Bw4/AtTeVgHa15v+K81RnbM Af2Ozkt1yz0MG90H8sjd1iHiDH5yf442biqFhCNpBq+nnqJO5Z+KyDptDMu5wtqu5s37jYNg s6YR7ytWBDM+u4m6E0pWHkCrtpYsSvad3nm5RVIwrA0jOhJj5OSNK1S9jCk9cU3EyI5byO6N HaIkMsScZ9l+NErvVe3Z46am5YzPVfSZClftV9SPDzlzArHYTzOfsS/zwLf0uVOv9RHmjqBg cwM6wV6qb4iy47zI7oLVpyoaoafOTvMQcVnWR9VW9PuN/Uh4lB/iN+4niWqfpd2aosSSnYJV qD6/F3JfiuyuLdOC7pSqHWsUGwzLAxhlnIKxtHHULIVDl1tX2Svxl/u5ZyjIj0Ynn1CYNfN6 4+bFaydJG99Dt6Igoj+jM4nT3dT2R/dpOQuY/6QvtaoWo8lMsBvIZ43x1qCNgBsLvUF68NMw aphb2Y02XAodhk/FGBSOhFR8QZ7b6OPcl/sfkuUA0EkLJRDaRT0agRus//IzvEWcmiFhwOR3 G3qXOT0szBDTXKYdq//wYuaDB8PaRo44KP7OOMRn3MKYmnqHDjbdzj4yaAZhMCSu3lHjgz0d opI8pWbSaf5/YK1iYzZlXmJJmjprA2M2S1IeBAoVlHygH3K52nDlXyzuTtWN/Kl00cHJIE1V BFHpx61GXh1L7aWsDxJYDRSd/FMfdjlwn+YjlY83XMAnnhDPsjiWMCGtjNktYC9Kghfvq/Ec CNKYR4Zhc5ISCl9tMrixlKdGXdwaIOdUWCpqqS1Gur2cd+DRiQv3OdPtFAx2auG4SbhAO2G5 xEXFTdnaW+XNdDqfvTVaIPrXOfJrul3c+swBhQKx7t1hs/zWNmA46A2yQkq1+5E17gwmvPhl FPGQv0NJDMQgVTY9iwn5yr3u1Y+rORI7mec3D6IkNczDZWiZbE2kpZGhtwSb1vX8LNgc4xpa 5VRUN+Bi0zXsZ/2ew3Rb/NgG5IyJUEKF7THmOL4KN4CQBC4oRh7qvNEdF3zQGP+cnGGLc7S0 xV8d/nJQUftiqxGNst11g6OSVG684EWGo+grz0mnOV4gtft94ytAN22GI9l6sMC/Etpce39A EX8ZaClgMS643tdvsaPkZR9tJG0l4d+3ljXHmaw/XoD1YvARbO1GPpdG4U/gfMQUoD26oA/L T2Ckr7JgV3PIfKa1teMGW2/Ulb0JyUUDSf66FEwzazcX907NgKMLLqQGmPzSn2X8s5+hYGJc PZq6/HgkiKS63JfLnh9MN5ZhnyWmsdYfFE6qWNczKvlK+6qUv0qRxCz2g3Q2GC3FW7wsjyq1 CTnpGQ3iOlKwBQlPrzfRcUNCCQLBQCMGRGZrOw7ugRpJQTje9V69XkybnSmvMPOvtbQpp0x6 9DB941r7Wo3MXZuuab5w4Hvb+DV3nIp3aZKdf6N9yYfBHGJy7yU0KoLCN+DIh0pKjeevd43t zDloajZ+ptrHci9Wo/ZBIAZTv8urlbU2cdhOCcq+/bItdj/CB91goGnng5xogxynXso9LyOx 2fluO+LkrYXkEhWeNb/1TivRpGOexg33hrAtckJekzY7tENn0D6FFtvN0m3gaTELqzc+H8bZ jzrLoXVuqUu3pQNvwbWF6dynoBKqY5sLVnwsClDULZdpU9Ntqqp102BgHLmQ5EQ/IiIgEP9c u6Vu90GnlhwK5v+dCK8zP3OlR6Uod/APGKkLhmWEUhPmJHh5pxNkFuxGihyGQVmWz2HVNRQ1 eanCiAGf9GqS0/yIWAzkXHG3O9CeasVLYIxgILMMru5ZJ/H0xcMUn1/zusi0NoeqTh5hPwLH 9Npbv4Glm7tToqw1c/Q9SdJ5h7azpxO28RF13B7i0YizBUzf36I3/BlsPs/4n/LZoUAflgIL zdaH82MnjL5ja8LcNIjqA1Jd9nq8nZ22/HdU0S4+z7RSPhw5OIrEQBstZOXjSWoLOy17ELpL wJr0Xo/lUViCO/cqzXbREdgB6O9g5y1DeOPPiXLg63BHAQe07FNyfyFmUymyv5s2B1e1N7ov ny6BCLLiCFSFiTk5nmAi/G++gbUMXEdgCTgq8WK5vlTxkG+Pl+IEmwKaFx22iuSVRV5ceVrm WQyG6UTVVJqu8jG6QNHX6N/aikZgap5FVrB0m/DHVHudW8qxd9271ikETtQTCNmAS6HJsTH0 2FFFs8b/B5ttVw84qzRMAYTpzgHNUt/eaHsLUAqyz/F/37y73drap0HcKZ6hIgTWgXzT5koh IdgnMHOmNXGZqGd4IdPXrgF52lQQudLyKYpJQR34GwtN522IKXWufSQDjQhdSPLlUxCVx4Gc q8zScqxBj3bR+VP/YcFZT8r4RdVSACwix2h0pGW7lKqmjMBxjU2Yuxk+1xEPApV9GsCjPudr cnbV1Ze41/lOqz8ulGJWXNi33/iAT5LQaS0oafkl21uHKatr5vW04poNO3c7s32Oye4MwHcg aJ8ZiVLG0MzLnhzB9/Owx351uDIXq95GjfvbqI8hlvZFPfMXAxv+fRj+8j7Th2gNzSP6jNWL ZhztDwZ4tQiMF1ydEyWCfPpYzn8YaUppsuNIuIqAlMV60wa3iJLJAO0yWv4TDmTexw4AmE70 BvHgvlbMP+LSQHVpvduMAc8x+jSrVHAqRrQrl41nQsA8QilpeX5YE9O5d7bXLlClxkI2mwLI cCQvoW9eBVSoH3maaFwWwDc8xMvZKLDD5bwQeJ3QG3tVUcaWvtwxYX4vl+1D5xpvX+BZHMoh ZWukVqIUs7lACwHdJ7EpWkEbmIZkIHoU/9cdA4VT4EZUaG2Q81GTLEO/7DLRERWnY7eC32Kd Pkrh7tLaCM+SrQU50TJiV1Xj0N8hqMcVeer6nmsd5EWqZYfLTszeyJrZycrdVR63EkC+S4FB ucm0Vuq5R8XrBX6gVHYT16JqIK93npEOrsIjUJaZUmh3SMBEp6MzSlh5a2xmvu0KhIreqBfc uKUNApNYMO3KnNPO3RsZP9t5uRWxzXaMvno/NQBi5vdMOBjs8go31wD7EtKCtO7/GdEXB13p cw4H1OoIWoRdquEGKm+wv+cxRpC6a0Qen5F3n/ncUwA8qe+ViPYskWTq24kyWSAJLhnECARd BOSYYik30Dd+xo82/eaDfrWipsc5a3P8d2cYQ+5DFIhPyH+cECCe6BqBA4n91mfSmLxWf0Oj WOIsOMRhpMHIJvgMd/h2M4JSFoNVXFIR5MXNqDdjC6qMKbdV+vY2UWpZ8B9GCccipYS5mrPI Rt8h1fCCnhUoJi1YZi8CHpyqyTiF83h/htNI1Av+BvjRhwBZArSS2XNp5cnx1pBiSLBmkXUe 9dK3a5jR/O3DYKEXnZpyy9zy0VoowEyLVvEYfXUpmbI+l8rSSWNCIVZwSACczfnjNMqmjejd hVSf4AYZgZNMU8dSSYSQNLSeHLgylWJ0TQ/KsG/qj/9MdQXklFB0cvIYZeNgbTffA7CNNxDd MR2yVTbCilVc50lE0ZH2T7Ay9DsD0h1voL1dJylJiRO6ufyiej+pf0uZix6ljAxJPDQjkYGa oxCcEXB/YLnS4ju8dFhvl0Tx6hpzKGaDxyI74YVkxDjdyQA0eLdHFus8FngN6yGvOgseio7P lR3KTIqRmdJQYyiRDlDGyQdqg9gSOjO1LHFqu+ob7AYCiF0YboiKuSJNrYfWKh7r2C2liQf2 DZ7oAOU9jOyF532+spW61+uzvrOON7SBC1v8X08v5/qJGQNouEFSuz7WxQiXns3sBKqzGTEM gc4sTBLry0kuQPYJS5p6G7pTIYrGpmpzBUWvf48I0t+e0gH+xR4Xe1iP9gdfhmeIOsEp/zRK 7U87fCYy8g7ZDV7TVt6ET1HBSZV3pKHdHF0wTqAkm/YwDN5GNJBS5cOEal9HVaV7ATLUR9v+ Ofe+asI11js/xkDZypwIueQ+4e6X9kj1LAPamdvs+bRaC4249/gEOVNgMynMINUrPiyEnrmb uiGj8+2WLonAF1qRDnn2dFjMi00Eyjr2voMPXldufmQqCaRWWJg24b/h9sIyNqEW886iuRzE pGhk6ByKmai8Hv8jR/i1YYfXaM5t+ckKtfqeumZiXf/HCFKIjUsB5io/xtCYOuWD2pfVZw8c PRKZw/aa67RMopvBLk0jKAMDqGwqTAKioydSiew5gc8/Hoajg062xTV0VegJGW3JY3107XSa 6oq6QzNEmbhc4V0AuDFzK8kQk38wIzWhYwxwIkLCdRLI2MerTXNJs7rhbB2OU5sVCpBXCrUU mH6ND1HkIWAq4GaYLRDBtvL234DhHDyLClj4cSRLTiV+PVPFzYNFxkK3WxMTb6nKLbJcAZ9U JLGTa3L0j/lEgm33DpVAn/GXFJGnpL7jykofupBLzlygToXTRXSW2+wWQwMoutX7FqeDak62 NMO6nbmUdQZMs1ZiDcEjiCU5dGCQDzbZr6Z5oo0qT87rZK6svl354NgUBbdarNU5gaJ3q3rX yPEOaAOvd+SW4pcMWuMsNFzcPiTaoB7vjFQdJ7jdt4JH+yXG1TgLkGqvHlg1a4Ms4ZtwdecW 8ZXsSkPPzMdcORExR+zXDSqfZWztpbhOwjUO7flWGOCTIPMESkWJSrAgK70r2vpc+/YRmNPj xivy+tWZDvoJp7orhV8gkLINK7stha/Jsrejtkfgiu93RZGusM4Ix2wDAQJZcYhD55rUWWFn WmcZQf/tP5HZ2pWH5CgqzfO8muNNVAhHgXMXRNRolwi52W4WGXOQClnx1anKvL0i107BiVw2 EXXibvPP+nDvKCe8xMq5xJ4wcrhOtWY/8Az8TP45n2SzLLWHVNDRaTQq4DTC+jMEVNrrG+eL 2I8ck3X4Vhwa9TnxrmQiNdXuj9DONcn3N99yeMg6tqLLW78LLBM5V5+ZBQ5WVxDr3WYnh6cI 3OBhyeYkbkIttJCPUso2EVgHkMZ5Tz94jwNwhU6FU1w5MTQ9GZawdQEWzeakzIQKnWki3Jqm GTmF/enXe+nQdCJlBOHYYdBs7alUIu2P+BJ1Jba/lrmIbgu/eR86VvG6/Iz2weJ7iUgeYZPV bzsQD8Hc9guc8pPoy2eO5aG+mF5lnM2VUS8e58ElwvAf6OZXNdVYH7OvWp2kT7RGhcgTee1y Daa6eiD+YkEHxHMJw0Oe8QUXG7agg0vPVsl68QP7KkuHdHHGyRMQwsOBDlsouqnV9KqPbb25 9ky2hPupslConbBx6noDNycnliSi5KVTkIX2DQKKXIOuZI5jX3xlhlgHV+Fd3Zhy+/GM6MNY ynREB2ldctGj/0aTGunXe58RvuMqtQG167KkhmFPEFOpguySA2B04UN+iRbUCI+4LwPgH2uQ ef16QBI1RH+EuCkPUslfESssDMhtTsP3XqRZjtSrnlw9U9SQHm901ivKJkGMHpA9deKOz3rH l86Z7S35c9+0tvbXNyRUGLYdtcxh4o7r73i34gJJU5tYYTMRNUGlMULrvG+J2X4U/T0vPI9W O4fU/4yH2Rx4OQRdwsFGk4rdXNW/6DfaZKAEWs8K/MOT0VvonNDANRTxerLuCarHeOieSaWy DtBReYQA3+teS94go/AIrM5+8KuABUVD/BYoK6VX9YAa1UiG+Gi4ONdwa1Q0JI2yJbLL0Wne FYg0MyhnsyJzbvPn6fKlFki6nx/c1pCAItT3/FISUaddtKhbdDCKshDPe+mVJKI5Kw6mid3/ 83diSyyIsb2Us1knn0cdXcP2KfAVF/UPbdezTVEUlLrXYgZjya72h9tcFmDbyDaEJ+rxu28y OxY5P2FEWkd1+Mt6FBgP6tgdW03M6pCdfUKH8gGOmQsU0iZ/xJ3x6w9Y58/QsGMhS8y62ttq d+k1aZ2sYLftjoPY9U2mkIzFGOmi4FFisBVnbOukN1E0mW+kThLO91nTu7FIjcdxqfN4aTMG 8xY9HHln0ueR3D0HiQiKSpoVodiTAMcyx3hLJ5WrKRGAMwAwF5fX7m713MDB4S/C08QWGeUv C8G3Y/T8+HaTRvwifkWgxfLE8kjWX0dvA+wAQXyNR81AL++6jxCy+tvVUCaeo6cGqgbYzCG0 Y8aISaiDWEaBIX+6+E2ahzpTmMRZ1z0GvIEaE1IEp0lVEIFW5uTkRAn/yJuLCyuAWaLZFl+w kjltgRFwXaVZBC+koCJpbkEII23G/NLLvqYKj/mJz1vN64mOcsElqktsdkgwFuTbomPztW3S Tq5MFzovIQC1AdRlpd9x3Pr8tXNusE1+obinziuGIGomULmz/NhUSD89c9xNlG6d/XTgsssB /V51JJBaOy/Lbj9o0Tu3SYHUEZnX6lW/wRVX+Y2v+Kb/DMcxjIXa9t+B2ounXE1d0AR2ZlTf pIUlAz2fp6jYGRBd3qRzwZ3je1GQpijAL3TPlmcfUMsyh0w3ttYE4eBpAaKaseJqvX6Q45oW HqjkSrKwfw6iJdRwbDFhoGH/e4ptoFg0JNeAzVP0yvDxXXCJitD8yUKvs/urcKcduOapvOML 1k3RHGC21LRnmBI3Lmn1trCBZv7/wN0JvpCb/ngZO1ipsVt62AutpESRZY9Zu5SV5LyX6672 3cV97cEfYrsK1DxFL8EOPhMgzYyxhEdnpqZcLP7XqgqC8zbxsj+T8/opU8JJnMHnzvsUnMPl /p/7EGWlQ/qz9a57jlnxH/DJpYMee9VbNh7w+T2l3o2Y1kxLUOVmwpdO4BsCUmfH5N4L67sB rq/fQ24vCzy9/GQq4kwBZ32h/WPeIOyRtKO+T54jxhLUOIE6ZBT4/xmYDqSVF5e5cDhEUbu0 92V1THKx+fxgxb1gYwOTuTSJNzuCCApWMj9VBqb8JT1uKLYtVMkYNPSX6HLKVQtBbyF09es1 IlWx0TiI72QjpD43LpXp3jAy1BwnDBzuIINqEVVtlNI/PYFxYmbs1RWE8eVC9YbjaRYGHPm6 HT1mTLik9RZaHEyb6n41lZHLFiSXgfEHRc3I96OYNRyzXXVyExSCVnLB46SrI+mud0flxrgf u+oiUoAGwqU9X4ElbqsARKuX21pQRroeCvgIbbZGyCmWrR03uGp8ftWf8SGprag/FQx8mC93 NoVWzJSeAsrZHK/kY7XLfa0fmWyenmGAi0mIZmLpdQN0WP+HE9+LrVcF8DmDFnpQicMM3EFb Y0SwfICkXENBPAc5E6BFsHPwpaQUqmgVTxD1xmd8vlcFrchQPTiwmamSKZmPJf1VUQ7tcHKx RERE4Hibd6E/KSQAxUL6hl/hhHr6FfzSm7MjOAoxqxHeQOer5qBE4nq17kO2S4lk+OV7LNSP dygZiTLV4WEBzD6uJoLPFPpDjAXF659FdPam4QLx/wwxmoeXUan6SZiC3LIYBB05l8A+FjQ0 4Lf6lAH8MOM2Ot7FQesrXsR1o9GOIext5zl77ZGuy2tjH5y6O91vE5RTGlJp/HJbPiit8AlD V4uw0TvTT/fQayA7GkN4iLmrTfybT1CcEF5hk/Bfnzamrbf3U9QIoV91kbLvQ9/mMh1Dcacy rjfZpq4Lm/i5MGUi3KzlU3jtb3qMhPxILFXT1ZbtCqlsogucGQ8m5TUC4kCvdSWooD9nxLS6 sbveqQ6oF/PwnYFFXrIniGTncGJdyPfZ+E+oUOnWm9SmjbERiH0g3xhd9NiubMUfTmIhGN77 rsJ7R+PDcUye5OR7dzM98Cqkc0bc890GLK4v3n9q2v1yK4fJgN68GDTyzlYzZtPh4/INZXMV 1ivdASwbXPVA+hVTIompCfwUTno4/HMCIkS85vP3M3kD7AFRCUbVwRG6j1qgx0eoRLvfp5uC +1vpWpoVhwAxmwvR/kvuHJ4VFmiuWcbFm5j35+ZQyBH9pbBUVRaP3IeigKG8cIIiWj2FcOXV 3u92uDd8d1nNjw1WOrb+Z8LDkTDGNaGnT8dV02VfYILcpPAphXncMRyBowGTXYx2toETGtVQ uTttD4RgwSzzgH+E8MebIzaF7g+qNDvUYL36B3JdbGSxh2Jvsa+27V5yrXw+MO+DbW0glVJh hgEBsSH4K4k0DoEnsbptk6SCujpiBT9kXP+8deqY+8j7HZzUosOAMzf9Sfu7aODbqoC5607u Z/ZpuWe5qRuVVL/jUFaNopRnhsIm/icEJBrLkTuB1Bf5XDcZ0zoyTrTrBrlaBLoWsDVRYhw4 26GQaEw7KbP7fgpBSJ6oU+aF9l4qyVQZICeb1eZMkZA0ZEaLFn3eAKWFA3nlc1IN1KSHu1yu 6q0WnLr1uz3zlUy0n9R9si6ZWrBq2EHTM0f+NuVLFNmuWvkQoAFpvLNn9moA7pFTynzAXLil 1Y2IbSD/PcJxwKMyFo+4tAWAXFY+/9Ea6G0jNDTT6hYK8r8/qckdvmPkCCBrDGrEs0OxhFzz 1aUlpg8QbEBR9IXu0an4Qjjmn4H7T/nDcfsp3m9gS+LZ1pa0e0PJ0+RsPgbUpXvZi/XCaK3j LdrJ3sypRGJeMQRJCq44jYd7QR4cZKOsBSYOsQ/HDmwvVvoS7EWuuy6Ze7Ef+N41Pz35Gy+a 8QrPZR1G+zqzvtzygJaRYJ/ZDZgmXKHSxfOVCXmo+Dw+oxJ+TjUYQChvvIcg4+iohbhtk/14 2+MjYsQA0VMZxJYr7T40tAgamu/QJTpDrFrqDdB/bSs1oXNPz0YfpsIu538lOYSSUAnu+PlE oDY2HfApwLXShx09W8t5ZY4YmvC6XulfRmkFRJoYagj01WqsqiZ2tbqyFAW6zAc7R8JIya/j pvuOingftjadDLZQgdXBk8iPuyOLqWxZZScuswDPecxzHMrP3+HctcT6w5W8etBk89RR6V04 5PiRhFQLbG6J3G9umY2+GP1WKdTB5+Cb1l4C8RoDLb7r7LP4wpuOE+aUjU5Vl2GOxuN2gPv9 ljfRaLp41aSr2QG4UENgXJKXWgur99J39/lto2lSP5VK2+GpT7achXWy+FvcqzkYkgiYO6GK CrYlYihfsA64VA7Gj8T5mkDqo0UkBVnOBESwvgtjMFnLDuS1TEJqTXXS1tfioPqq6XScd9Jv x0E2e7MzPli8C1WcsaQsw9AtRKtFneWzh3UTzMXpYhnWBApxr/gdmYttfmZZAX2MZqhT3dsq kzdrg/Vkk3D8ljEtVsZFtR9Ld//hWxI4Ke7fuvet+s1J/zs1cqJ9SfzymZfPvT73yMbmv6Us auI+u9d9+iyVZPinWOj0vNOcbSrWVC6qzBwXWg0MI6nRLfWlTUnmfHeLJkmIA9x+Np5XYaSR UW88tIWQTMRBqWIPLxD5irFozkqzih1WCvYs5+e4iGK5ql8Rqq7z6/ewnzTb6aInCLgDAQ9P zRrD/HufR7VFaXlmFu7HCK9ztQYnRZQNYL99WX5FOkJIegf+3GwTeKG4qmltwDlSpMy5i+EX 6BeoUO7h/qJuQltIqgOI7+O1hcs/9qGdBJt0t4eR/+w3guj/Wu5QDsPw46yMMgxohAQ+Rf5G ZJ4v8nfKV86E45PZG+zxROLMdT58da+A39GL+aGraWf+NHba50aoO0YnIOWSgShS+ODO4X2C y80ktEq4KJQbC6GiM/qRLVTQG6rY4Zwf2itRZWPKB3LwXI8uTZM8WZNmqYN+v0MBxXpaUYox Dmsk1OMq8pkDXmtafsmP2RITXQWa4J6v4yhLYCM3QmmkPSYxDI/isVxziTv/Y4NtZc0t4rJ2 f4TY/IVdXavIqO3+DlGSEwwrJkVyu5Y80T7zXgV/Jp9ls2dLZxvTaf8YLVs3DjTcoFJ2uZWA oOwBSMXCnvRxLB4AV/RoTfjq/t5Uvx7Pzb0BsXfNtTrK4LAMhdv22xFnsS08ySnn9O6Or6j9 DJZmkcJfmyMoNgJJm1tDX70vKq5boeqsgnOTft8XuPDAI6EeXzucvavEHDxHVNuEdS9xhIoZ eEk2klpmDZi4KxJ0JqSxOgD+JmTVlGN/I8cxlltND1jz4F25Vl76ZBj3wRQ+D7axn5ykzr4M u8qO8irqQbCGdKJl3HdoOeSxrzH34+BP9O7lkF9whqVmRU6niTpDL/u2x+nOeHy4OzEaZTHU xtT7920zC9visi+Yl5vU01XlgZ0orIUl5zvnRMDXpbpgkqFEybd+oCldqaYslJQo/WS4KjlB w6Pl15RaLsfYONxX6FuwGh+bvvs9iTv//DIe/u/psGg+tJ3pa560yU2R/2qVT29jTegA7uiE K2Yerm+OWvEbXAfXLprg0XhNQbNpir1Ydnq3Uf2UBhnSE0VCxA7NZkpvxeBArTlPGWn4FOkl 4Zp3nZLlqGmLlyhkDWfvrm4nPio2zJ0u/+HVC4UTea7QkHKgbtq5U5mVqIlZNWiY6tI40HUk wseH4xZ80K7luIj+2IXfVYA1FOHBS4SRwFDP3q31B1LmY+/exUUhzGjcIfpOuE9mJyoeZOBj JZAgbLWvT3VMyon9xYaaH/ojGCRzcIKSsvefnpX0+ZChS1gJ0fk1DI+QlQn9nhFNSai1r+8P xiFRk+POnDfv6XfnRLE4W13pd9ZaFb9FoBz2i/eNHGeYHmCRzF4Go+TJTWL2exsC1kX7bcl1 YHKRWaAQb6hPiq/u5OpoVyH4huZVYrt+eOxqGitGCwLCUDgsYAnN89qTTLfap9Aq9wj7sGHG 1kZIs81f/lQUhOpTcWN+F94OCORxzCE5KeoH+ze6/UOLiZ35U3jtNSGJuFVgV3EkPgdO3BXs 1Qx2BrKkz3NPHlkE2xMPhBZci6Uq1hc5+sBZpJPXMY+r2/9ZexJYxmb9rr4mpbm3NOWwqajG zHYlLEOYFCzTwCZUUdS+GqqKyjBcUjqqMvxn3VNiEjQk7uTl6Hsx8sNtUitjjcpx+Exgn410 8Ek6S4HzaNhB3wc7fBcKJDqLsMJiNw2m0qCQzbEj7mGm+1h+hQUuipTHXPgu2iaLAwrt0/XJ Gv2ADFEBGQrdOk7ID/H6FEK932z5CUQY2BLzS7B1csY4F0mjYPfAhoDeyBfrndFcFITx85K3 NsUf5fJqOKjk0Rvnb0aof3C8s5SfZmF7Ih68y2+4HgWJmJAInXMQBEHRIIw+ZFAzzF0k8Uhs uyE73ZYuCgkhJ6nFthyOlfbcAuOOaNHKtjQNZxaKELoYEnBt3GWUQzRQvqSYqKmDNC+iQb51 oVsdS7H9LXC6cz0dgpJ6rESnzwUxw0ERsArAIkaAnAZKIXYkb/erkuKzaa6GSOyCus0zCVnE REnSc37QhIV9BtmepS0UEwUB4SjZthHyrsuJYGwIGn7N49/hkJYI+hzwmHq/HgAVNXqPdzyX 9arLQUP3L9BHIWYn2mfzMjCs8ouLm+LJO44t77ZinhvD/BXysARl155MYQ3n+1h1Yd8+HIC7 BzIlkijDLwQfReP/D1ZOUEgSYDik6nt3CzHdYe+xAb5QJ2Y1QfYbP2T2MwnsZu3oUlfdsa87 ecwDBLmQ69tuDQb08EVIJthAcZ3WR851KTX/xaOUdcWrB3LTNTtGY0v5nY7mbN4j3FmLiqy8 XiyX2Mt7cDA1FF5zVDDMghlSUotJNlekwtuguAlenKt9NWjtEJTNlU84QjivWwgpl9WwJrEL HM+5t5X+K5xfwu63yfrd1RhFjO57NtCLj5YHavlwbVwuSJUDehaoZSEAHMIDroktivm2EP7G sVCw7r/Hgw9l5GcCftTWUBjpOa88BO0QYf4F4Xfxa68rYSXVlpylS6FJuCl7qa8HinK1qIB3 J6LHA6yMHH5DtcQBXnvN64PbVQFUCA4S78swbLZ7Ds5dEx9aK4RRgkSe8c3Tyir6uQehfJHX iqyECYO0lP5WdVSjjzFwZuWOxD9GdngUVtdj0kw2WCtGv0AFT+C9k9z7Fz5Cr97EXTkPzXqC MIsPqivwQ2sPOHK9eUAlyS7g/QeaKqEnO6ZIXCDTQRJEK0Gn/vf+hhCV7EUdmPhhVCZ4dZh5 epHxvoR8JPi973SVWuOE0cSCksXnO2Y6E+8vC/Dpap7e9ntJ8vKV4Qa0ZluR05hsIU4x74vR rsUWXIMfi8th4Jez26Hyn/bXySRgaMgsahpcKFPpa1fU9ue+3ZJt0SKQcFovjBzBoNsWI6rK ZPeQdfeZV4bzRuIqv0ip/80r9/aUcWjtTLzLXtjFzRa44YNs2ktCMvTzXLRxyd3jgcCvyUy4 K3e+9hO+gVXXqD2VOr1IGD+0L98W8/yh717TPx7yWHiAX8JLfxM6vhZuMfx4vv4D2WdWn6ar yq7YSxTefl98mSQ9Tbr3RUs2Ph3rYno+uHS5T1L9ANQXJXw71CJJt/OrGnc0K6OqKx4PTdWu vYpk1yU8ypmySjHvRvSqDU5HpF7PdQCNkh/l1vw0ucqaBpm5UwoATk1XSVlAngXTibxAH0ah ZZIh/ZjSbkQs15pv+Z68yeMk3mbZaVuGoNIPrhzz95Pww+LbapiVagjNPMwNWZsYlH/o/i7J 0msLqpysfbvguf23YD94Ri1YaOu7ddT6mgrMvJRrqLPe9wU55qeSFvB+FwJ6J1FAIm9N2EuB 7TkdAlpXG2O1eT2+4VQkkpz8SGy2xI68fMJ/NSPDAGZk7hbwcbKH1Hvv3nvBQP/J5KQ3DrAa 2kwuMPgw/Sxtv4TBeJERKJr0g1khjyW+SuAmB0v35zES5A81IwQJVNkenfwmKvNSRmMhUOPJ r2Dp7/GwvQmCivf8SbcmQrSV5wYyPcFIVqCoKGBQwUdG+3PXK4vHK3dIuXCGbMJt1odBJeWZ ovVfmudKnFGg5XR5WM1HYO6NZu5UAx3RZ1tl3xDdj7O8dd0TZIC+3+TFEVB6oID8uK0B19qD My1+lhqBZaHOHlbZ5EaU6HOSKH/m5FI0i/eBx6U6Roo2lZJW3WsKpZb5NrqD8foB1H2GeTGp rXeW8ImtYQaZleoY1O3/jAr4rSrgzk5ALR9qSU1PIP8Jj5cYm/VsXtZBPo6XuuvVre8pOLsC UcSVoaAQOulwQ4j4bNNcpG+PoAldvjVq3zZ4ZsZn5MEejv84Baqk711Vmux2cZWpX3hG5dJ7 btgz9dL95IaNEvJgJdbhzT7521GXzeBmrGZ8X0PAgHQ98z60vTOWlnqIqjR4EHqEGMwwVI/v 9T7nL1vOlggiaH8u/yTC859hi4Ik0mbnY2w6beTCr7rRp8S7bZuLUz2LFsq+R4AF0htlL9T9 ESwiqv96kWIf7na3cXW6cJI1GFRW6iAQ7mrHX2attecKUNUyZwPjpAq5P+PFsiiKa+uzMw+5 D/VFqLPOefsRxrdY8qmaWumPmZSMjJok4BY4jCbKnuGpqpozT/XYpmK3HYABB/e9Zvz9K7Po Mcc5nV+W2VQRB2HIyK2cb9Lij4PTdd/HwvVymA77eZBPhyKWF5WQLTNyQMNW/Oy4C+ykWz4V UX+o+Xa9GS5OCSfFSPRV37rqm4DzaFqJJddw6sDs7QxsVdwNebGm484e7VjMLyVWUUAiZEAW PiXT8NnsUtnTqrAsWxEHPkLDb7OpCDithMcM0v/K6qHQO0TxplJGYPmrSReskMZwomwt7Shf JTiR+mGMIyIyJY5AMf6ubXZFdTFCzkPcW15F2hFMmc7I4T+4LWjCg0jwW+QZuh8k9dSmW1yA Gx3QkZtAQkXrJk7XiMvWlfnJsTrGTfBtFyjzHE49n3g6WKAwEw0NinKOQqvOeim9rcrwAvwF lqyjBId0zUCpxDgTj19J0rTAPIsdk9yq3ZErRiRl+pOJFcBUAw9DbyikjnTQutMzsNKCuPJh Ak1E9YNzHb8VM9dasSsrpMqnhM+q+Uo24sujkvHvCTgO3LbmhFm1mgZeW8aPK2UmEII+8V/4 7Z9tvgC9592v62e9CAbyo2a4hGzqHx9/VowR1XjiPFl7Auu5hSD9dqExq+rHxcRO4/XGLSBZ CU3yD4/MWzPqIuy2aVHu0zIzJFBcRkNM+SkfKE0ZYWMV+PkCDq1YRliIoa7pTe4VlV42ty6u D/PcES0GDkOgRFrLxcUgKmzGAASD+OJZcXym5V8bra9ByoB+6SETkwnfRY9l/AJ1NcAS6bLf R+y4ge3gmd3eJu8NFlcD4xOIDoX2huDW/ot8V9cxCvf+72KVVICw865/Z8xKtQ03c1Q6yA6/ m/vNJHl05K6K6ma0yzDZHfoVUr+unosywfA2uSVV6c8le69QTCUDuljVtsDdZ0zpxVQzqj5f QcslgEwDfseREm7zBEMfnJTH47cD79EkWbUqjI5eYltlmKVilJ8j4i/qJbkGSfDrkG6+AUD9 BNJz8APZ81cvLA4oNLD/QZJER2KIICngjKLC30wx7fVaG+NUffA16L3FjPtcP7iN/pDvomjJ J4lB0ICY73f089fioUc3lQG4b/CWxzhASn78/j3Tfh6bL6oygWNmb4KPapSPrz17m4hLa1U1 IvKGu1pXbAWClk33PHgx4a2yAn21WZMj97X+rKShyZcf18RO+fOORB5rKBkViBIxCP4ezQTc NjTagjkVDnQjPM8uXXSFb+BR4iMedr6ewEF24XfLOu9fBfiFxj9/1rDlsmunXNEk+urMFWBm WwZEf01fgiThj57HtB6oPUqMLaCYLUFKB8GcF3OtfdNKvpRsXlBT0LoWbPXYzctxgGhBiT5u aTPIaZSHzYfQgLXkB78+N+NwHL94cGncBADuPQ+wgy/kqIOPhn8IAR4jb6FLzcTnszK3jGgM cHbW/lC8wfM8J3t71cPdG8yUWwG1CHOnOcQqLAS2ep4gMOA24VwEwffPuMQlAcLL4pfYLE4a ViVEBTk2AQzjsh7GgwEoD9cy0r7euHmaO77By2kVNFURt4lB9CuYDSTo2tu34c+6vu6h2j2A jpn5LKbCMgYMd72N4NALLkPSeSzxWtnET2J1/rkg6Wq5ZBc3ixli5DV4WQj7xtHSImePq/nA CT64oYd3H9oe+5YrB3tw0UvrqLFcRN8Nqt+CrSG4UGUnlaxn6iAElpqrctnFLjkQur8u/SwO u4LSA/s2OChxzr9MDX1uUK+FKHhWG9xUo+F/ogwYXCjbgfFT0k42P2ACPwUwIPn+Tkw5qhXn hKeljpK/9qQ6Qnlu1wbvrtiewnQ0KRfNQ8wq+MIfb0sx64D5qDDqUTVczdgG+5b+7RNGOkL2 BsCnPclfVOjZOiKoqVkykLZ20dfc6qYAjrFr5BNOoDVUSn0RtbMqsYKnHKmAZSAz+sbhONxs z4FQ/X2zoyohNFJRUgtY6FrptUxr7uiNRIceJJNNtSp6eEUxI4cVCozEDWgEFl9MJX9KcBFU uZSzFa+HcD5VcQe+g4fJTw2LWNDLIzgSlkVNU/XNurkPQ7Xfl+972bT9x3ZFBVL8ocL3Kn/8 3e9/I0auWsZLb/lY1+HcvhtPPuxZbe6Y7M9bTfAYEyPC1lqBdxE63Cy/Bid9b7XxYviEYZVE 6wsUdxQ7WFLmK7OF89ismdpfAlMjdi8n1K/glVK1pIOyVeOMinxMMXDHtF+ACni9ngrjDzBF Q+d2Ejdt1ONF8vd+7QNA03/HLQH6BRQMSRTih2XN1kInoqlSJNcBU8Vy+ncpafwOrak8h26k ZwdE09RKTAlJ2QPJE9RaeVhMgoEZFfitSvBdo6GLav4RW5YAVoti57sdJaE30ESMqjTgWISp e6o1XSCPaYm/TR+ewzKJf12J7n25aZX//aqBbRGG691iIwvM9eTQlgM9E5f72F9Efj19nehK oS7c+ofXHo1O0jWdQZKpUCyj6GQK6/xlBZBuIm+G9PhcfD1cHIqDZ8QkobJktC/etdDrxpgb JhVcGwco3k3kFOwyeYoMPN47DRxqllEznD48qWkavjm0uou4VOId2FKzcYcCtxAWdzKoYV36 PCQgn6XUxlGC+AFw5ojJs4xcEz8RAV1Uq2ZADie7j46SEjgAi91cPfOyknNNFyZzK/a4UYHs pEGPcOMgxHxou0qCUedAwS4LKPbBspe8D46i60ah+gJbbvEVrr5vSdmR3TMTGjEZR1mzZdzf LLCcwbd21KpLpe3GA6TGIW14p4Vu7NLk4QXJlbv6HzrhaRWaviLS2aSSUNO7qFD0avhCB4dg PvSCif71ji6rrdaW+y1DH8Lpv6bakhwWd284kBqekL2pkM4cKXEphdZqk13ikXz89UdQAERV YUxJCy1oHVzSM15GU6sbjd0//BzML5weOcV7cs0FztguQnHcuKFeq9j+HLqO590WK0tw0Eif 8paUiBqwZFK6eviIHDt4P/lrTED10m02QP25Gf0ksDq3sXfeI/IjqLUY+L30ZI1fHrgR0f1J 3j75Iiy53Q5U/bcK5Bs86QUN+lrweqgCN3BiGQsNtPaVnSTQLVAf4YJk2cID3t63de0rnq9u IICfpzgXzxHgqXrppHEuC8y4AMbPJ732jPsy3TcibQiBUwQvfNzF/WVbzyBQ0YI2mdh7cU4w 8EfYu8CTAQoGGJ/n6AOxe3Q6eOM1KHfyva81XL6i4KbRPSdxNCfBvkaf1jMp1lh9IA6h0kIL Un4Gsnt0KLEiWynIaJLv1ExCsiFCxO64IbRSNpibWBuwAN0dCIObgbPYZps9qC6eD4oKNSE0 TCbk0DIdCw0jvu6GXPetyjdpPK3yKRPEoTkChMSSK7g7Rronsc7aa8Y3tT8kGGHnIqWjsO+/ KVUlokFZ1Gt2Z5slvmbnFCocAECK3Sn3w9ldSNGx6tOpm2LwneRAkTYFctnctd6S5GtzhITd FG6rpnEsrY6X3i9QsDoS5fthcg2UhVsbLv2W8e1QEJgw0uOYX/wKpuNaLwrJrDanYe0BlxOD fj/uaHFOq7J0S1/udN61vGf7Yj8HGq6TSp/fo1VYoYJibZ+1/Flou5E61TEuKeY++Cr63eGA HcGhTnOvCSiA51nIFuV4Plsg6SD23xDDjvcYsqbpPHAxYtMMJY18tLuUQGOpTX6ggNkibkpD c6l3p72rngjJ8XMFgSnGwCVR/lP2FHGR56QGpUFwkHw22KKS8Uq/H7TFkoXpMr4DoTn2NnwJ M02z36CmVv7a00eOloOTkNlJZi/rmws6TcHF/n8jVGp0hWBvhPl5PyQ7j+rd8UWPfRz/skdd JK3wrl0L7rHho+wAkKR8LOguyXqREWgvjyL8hjM12QL+JAIIytOUwvApsn+QUwJUhdZPGLK2 4LMS8DyVGi1GwbPW1EA1GCddNiVOB9fppfVm12E0PliTjzJRBvS/ZdE7uLrBLzuRWbmBz0kW 6BGSf0uwoNm1ViQQ3Scq5dqtOasjKoT22O3kRqYsBLue1U2fX2ZNk0aAVPoxWjSBwp5xAnIx GAGt961BQ4kSGJwEwySXvpqQOYPMvNk0vsjTG5HEgVJOA062NltDRe18V/MqHCRbSX7nsrHE LhpedIMSastr1y0Aljm8oQQiqP6RbLYSIPxfaVBTgmndlhIbu5FoPSEKWkRZQHqYWoESq0ht pWQ1sM/SHLPgoMtL2wXqlXptV2hBmoQtXKa5Yjc1/rqSCoLb/qV6cc3un5XMUKzoufNSFauo HqYWovonqzwg5gxZHsTCeVbXIEqmDPzW2gCJiTF7ycPv4vxfsw2nt3Ym7rqgrjYXH5UeVSfX 8GrHLh7ZIJPi9Pn53snPt/x+0eiSzzmQD0HJL6AjR0QbetRoG9dFZqc5P1kSA6WUhgTKSFHF 663j//JdRmEqvm4vXK+gRqj8bfSTdatUA5K/c2Oi8WLgz1nS1fx4i+h5HUlpe+G1RUC1IhbP uRyq1ea/bF7P3BJNA39yF/k1hChSlp+N0lVUgYyr8VHnUPHIepKeWlXlkc1MKb7npO7/L+ey lZ+E1ffm8POMSivXbI8aYHHIs1IbyAgSnxR+f3ahEfiY0Ju53Jn+PDHIVjd3YWoWEIb40T1C ILJXEDeqM+RQ1TfLxkUgUbwUqlvSNqeAdAYbvM3Ddp5fzhfD6Y7lzhbqI85pT81lrNFvjiC2 2y8hqOk2TeX4ybHlaodLRscF1jdcq6aTM8qVsUv4OtR/m10lgPl11ns3ELFiBUgoUpCfhadD Rq/f+LthDGwISATwpbW0cElanSeRjlxCzCCir/W+SYi5+die0uc1S0NXJeApH8MfrgX25y5F +9P6lQNcSRTVTBNWyoFyk4Li1MuKq9XbR9cD5/AAQXSSNPPtEhqkprmlc7MAYaPP1LQErP9Q lpCXBPnC8zfbmapUzNDoNCnA0RJJIdxUwOporwTDlZwfoeOukT0TOcglGULAbK01UWZryPJR /visnFU58h5H3sitBwMZXrp2Gv6MBiiWkJZuumc906UHk2Gw/q0rAaCNd9HUYqEqMmCa+0ao QbfjvTR5AasVzQIY6lCdyLURyrTCtQ8az0tH3RMLxdYleaCMXKsxfhmAWaJ9q/L/QMTgOGDg sMSrgJZ+x4Wity57E6uia4Q2AW85fZTm+VizaKbwDjjzixMGIXuNu+rltFIF52IYAX3WRcyi quay/jmcVuc9RKnUDczkPoAl9JKGf2HqiwSZfTved7Dc9GjwkEr/xERLvRaQyDAqEbimpv04 MoCxi9XDx+kr1Jr9SJtjgUgWuMVf0TzasojT8eQP94ff5llpMo3WvR0wt+cB0qB62TtmcF1y NOOvNW0z7J3amZQfhKgGAjoedng0T409RLMd4/EX1+D79jIbJFNAANi+JY9uQG+qqGwnCkZX JUMJhchZlm9VzJBI19EKSfwtVvM6aSK4s1qnTXtboc15g3brzqib3VUiu6jYfu2+C5g73pU0 pGapZHJfMMIGbDR1oEM9DVJFgV9eAXMCe7ATMjX8bBI1zProdD0PvWPIQhp3aWClYmw+N7MA 5mgE4VPNCGGjfaFwZSZHGeEyH/B80ArmFNEc+/RM/z0R9/ckR217T+t3/u7jydNqw50kMBXR F/uv6ML3jZ0Wg5/y5/PrYST8qKf0jdJUMUCXhq2zmt1Mp5uKoQC9OgfnneHvcuZ8CBAB6N1u dkuQGoM5uPciAUhOO4ioy9jaZosbMSHOolBnXmllWfByPetcNgNcjMSBNBnwCnFm465MR1xj Hylr5OP/cpoOZvdFwbGZ++LWD1/cdVHNwEPsnvknUnjKUxHpcm1lbMx7ISH71uG4XjuK/o6r Ou3uzYQs9Nf3FwPVM491oE0zhIBEnD2cC6NLhX5AaRdJ1rIB46+ZCsIpqvKVrGcXgQZd+zr0 kWvR0Eu9M93xvuesN6Texcf4nSch/KuibgGp6GuCdM9cLoqkb+GTK2qWrIyNA6WYLqyH+sTW I0qBE1NXQRjcf+o+r4YpK659VnmBOiCVPdKdTVLQPgz5P/OgDjRAtTq1uF8SPPalgHTcFYtr u0z+vMLUXd921NUtTDfo7K6PMpb2NPewjWlXaMhDI8MdVzj/K5TDrmwiX8ql+ZCZqiZwuK23 pFOOA4PFjuYELQDp313SFy2lVRnOPjzvOSTxwczWXpWu/M1qrfXXdRh6VoY3wNvft4LEwDNV WVsQ+1XV5GMiSi8cxKvr+cKSrMwAgfw4mrS9SrPejw05bcqGlXy3/M6wrn/b36M2DPjdBLy2 oXPVI6earAOpqJ635cpvnhQXeHa7FeE5i+sL7EYvAq/ic5sVEISv8gRIHOER6w3cO2r6EHNS DUDIZ82+GXhUdNb+sYw6wf72lkvxCK3HS5EUk4TvDwajYp4pWEB46SejE/EOws8Sjt+ZvSbu NgRtWDs7qGqSXNTtX3h2YQvg24JfPe8338INudFlruLWQftjM3odtKzAp2LZ4TkeHKho1a/+ 0EOO7x4MDm5l3lAlzf36QW7Iys5f1/nHmsbxMefjxL+4nSSvq2nHfLuaEnXdG9uVuEcNX4wy d22HtnuuYo2sPlf4LMkdvn/9K2Bs9L2BYubX+xk7NFaFQztpZNs3HFnWozKYumt964oNy57J 2EuL/KC3DvToA9KQQgDb6DkxT6c94PSR48pr8gQ1H2u7XD9VPoR9EWFiHM+q3Er75VJSRtSv 2au5OX4Eva6X5B5Ji68pqz/9lU6eR+9Mdm9ofnwCQ/fv1Fp9wxBqa5x4b3axRgtI8iLGcU1u zXZ1ijyXT/Hq0EhLYYpdM/JHYDtUidw0RQVYjsxwj2xzG1RsarcKs1Ij+XhnESyRRV7tzRan YfToFmfRop6HZMNGIserrL/DgF/x0mmOQfOXF9RmlYf7l7hjXHk7EPs2cBcDkienMtkWS5IK I7hjoyDkviR607hrTiyeOi8zNdFavxZqeRSCeEBI0LnoON3Xz2BntqfCwnJT//K0fOSuMi5S DdPez2TnSdh5fynRJYgBKp3i1yvJL0t7WZvDlxAJv+7Aq++7PsAV5DYEvYECy3JOrDsOo3Gq 3vrsfk77k/gFegr20oHWCnG/N7FFuKCX0QHyXWQMsTzADT4F/jD+ZrINnGZIEmqysxpb99Ww r6tziYvFmTqJslk9pKX5xUJh/kgTcljAKZgXqfIl9Y6ZZXsRHnApTEiSV6u97gfOUpIQqYpS /UnEkAFpBbMyA+vTBoP4eusj6liYZVJtLNit9pwqD90ZheWQm06haqOBrGEby1DvzGVwF8Ip NZQOENvuHnxDTRPYMJQV2UQix5y8nnuY/HbBNgK6ZhjYew0FAH+QMdDcH+St/HzCFSyE3rY3 sMI3w3lwHiLUNM6gdRlY+Dw/ZWid3s9rxZ+bRzFYrEVsfhh/DWZg6byfvawvWyEg7lunlM70 Vq/UZaI7Rrsz1sJ++XVCZqMJ5AyWZXuh/HapU4QHHxZ7tlEG30OXDqPWUZDKizt52rumahyJ Nbma9j10pK1XH24OP0/rqmDRdMZWZurHmGWDk3xpzVI+hI+H9iHfMMeRW3vYCcnCs0y8/0FX +Dp31N1fJ0W/JX+igrh1CNnM8GHLMdDaRGKD7NwlSMIOQFZmXFlKEHDcy40eA/CTKJ+8x4Ui p0mZECUTTis+P0UMpTN80CTJCjPYXpnJVecYTG68pH+NqubDDI5PIhK+OiDQwt9z7kOQhWcI PK04FRgp6Zx5QtT0c8QImcuFPesp42ZTn5kJ5M4azO5XKDtwa2TzIu0byy6e/8vWKwObJQm+ 8Ic6NnlU/2rp+Tm44KPwwxkCO+Mkh+oO++bzoBhDwh1odu/PdhhjbsI6qbG4ZBVdn8qSF5Jp ig707FlL6O0jlOrbHOD+qRy7bjzhfW4TKP138ngPQc6MyxH9eGWlbKem19FOxcyBdiwz5ghS KDlVTkoGdpnq7kKLmXtOkgSvDElaW74lFYLKOk3Dxu+sp8Wq2vx63SuWdKUb0sO0qTH2Ksll 058+6CjMExmtIbu6CsWJ8yeR2pQWVwreX7VfZHltWYlybxiQdx06Nz/YGaPilR0zVi08TTMT 6SBIvItUyj5vdxy1jOnLLcN7L7R3EeaXsNSgvHXMOW2GbK+tkFoEHzDrvl7wD3YiOiPQ4lsw /aLuyMvOIDvD6MkNSGBGtSn2Xb1E2QWNzOfteXCR3u7Sku5y+kSZPVui0hMDBzHGEP66wwyP FVIvRmuZVWkE6XWoiO8495uOVLfb3fVBAJSMcGcRAALY/Q41lLqBLJZ3+5WbcU5J/VfuJBr2 aA/Q/GCqwbLPIqa3QJt+asgbmm+eqTmH+CTJ2IEJjp23YSAJVKp43XahQSZ1Y1R5Ua+AWNwh erwh7VpxrOxEowLVmy614Mf/ORqd2PDTzhfG5SuXPByf+6ld7zCRLcZvpCTvxXxZzZobLb2s wNycOFL16td37Wl/Dxd/laFjlOTU2XwmOAv4p5POMIEVwv8vDP9Q8J+KMyHkFSsA4oodmH2N 7gMtm/5jzbgOz2SG5WqMDbpHFaUTBFQ9rvqSk/MsF/0ztG5t5fqzQZ/5KSF9dVCZxIRn9Iwj bvEr6TDAr+oiWUTPFl0mBtFfFc5TI6zUG6+ULFU/ou4bVG1f5jQiMs5VaAiTzf3u9MYQ7ZsP SdgmSFMMCR3AOJHX3OTTqR2pRihna1JyECJJ4ny3aMIWKvJOz9L4iyUHNQhCiVJvoJhQ4fft YM3Qfv2pA5eb2wEB+P1MkNljjrsO+XjtWhzOp7c2E2aOBQFdUXmwhxLBMCHMvTqO+j1f1rFj xKEUtuBB3p6rzfEOWtMi1tzE8wz/aq3MbysdvpFZEU1gt9tmtKM27JXZX4R+O+kUm6v8Xw9p ZpTwWPkUtfUn4P7QH70YXkhi49iZKW9yxfU9VedDcdfblcAkmQjHyUSqkFftWTDYq3nk8ILa 4TGJrycOUbeBTUr3qMdbIAnPXD35CqMx8P6PUJPdHnfZR0qJ2/2M/C3tR3zoDzVlK8S5wYL0 LCzQ4WZayj06kLe6nTaVvtdhwoWOpzcgnXDLjF6paaFz7zb1wlro4AGF/i80aETuPjRszYH5 Uxwx9I4Uewbwdmg9gjkrDitXKs3+hqLmYFS9oihQvuIZfDWlzNEaGULxxjAGPXS3V1aIZ9L0 PO/TdYMeRSVMXWlWs9N+xpdbYg/Id5rJotghwv8vcqNibwi/xrEOqUPGqOkskF5aXX4YaIo3 w05r830Tao0Ut8tHYn++3rKiKAT9ubC5FEJkLURALxK3kg6Hd3d2X3oVBNKi2yBYdhP8dKX8 GjAETQ2NhA8W9d2K58IVnTIMiithHnoiTXY0TTJ3lUl2N77GjRJaZmQ8VrmkEnwOdCaogkKf nUxp+kHxkbjMREwoBTk/H+W/AtUx3saeu51RD+RUWjTWnK9uZSsK6rne/sUoEp7CreMqalKI NHDgyp5lz8TRHbmxRuElCfk7uFwB1CJHmfmA3CQL/1ePocXMEJLlJzxTm5q00UwT0VEdk99g muAuGEfnroFgCA3jnXcz+DHDmFj4VjeXZ1pVnwzI6TMHb6Npa7DCnfYL+gas9xjOgVF6/F26 aSKuZF74cK9/BIPuvbORnQ7QZrt8RG2sQPBWg7JNG+ImX44maaFrJP6BC96BdmGX7GiSKU4E PL4iaP0cc89EDc717BIfKty097STLtPnLyNBsCZK5Gfk+ImUJWIY8G29K8LVRIZ2YqLCbNOa PGFcv+bjwpJcPvJMrdrV2N7icRzfnJt1JuorfkEQ/KowctbdR+iIutwwxpe6Q/KT45GciOr1 MhhYoQ5RG6MHw40152if+JlHk79MTVk+jSmCuMWDDM/g8s1588G6wFUbaodljbSS7KfyhRgv yd3Bl66inIX/Y/3PEyloRSqudRg1Z4jJJPxJLqPbWJdUkLnwy/kgZ+QeAPG5/wRl98SuK/m5 1PVjj8PbYKzenLBkCXCMhI8terRRUBMn8GdEluf7lK/tbJhs3ykKYbJi6SJZpDNHgC2G5Nd2 l2+SsPQx6I/bc5ng9z7UEOTJVkxE5YDwZs/mk/N07Cg2cWIfqbWtuxQZpZt61RKpvWOPmyqH 1tVXeXpTFWHXmVIdwFGY7rMdnqZkeMlzzGVHufIaezbZ6MlbeBRTha1W8JIIDoSyK4eZw7Bu c5YVUugE8jBHxiPP6xrA+dUDqz8AhTvxJzaMtUPs5c6bsFsLoiAer8MH39RsyFGbhKxcIBeU YNYTlkOrbaBxKRR+DLnTNHhEofiwIuNEI/JscAoi2Agp7IS3K+qdd+u7vEhH0tT6O/TAbhlJ c/re3PRfVbpSVZNmEcpWvpA9sV6JnFUCrPAnqCrjdG5dtE1RnSu69ojkopsJ6KOtxVci8Y3v 4V+/UyJFbWYcs8WIzkAzsjRHySIxg10VnY8PKO+TBbYasoKU/RmOFArUk5kFO0obBRD2aeOC 1aWJkWBOa1ydwLirzcg+b1yBL3wLYdXjnyCupB4EOlHyd+OoNOLS7/Hd5LxEM3owPBLF4A34 xXhVIbbr7GAo1lvIzQShJJoefTN/pMUVzOfELDV+fkBufYjvBsuamqf9ZbKy+1FTfVnOGolT DE5goHvBNq/s7IHZiGvh+/1RAZSuNph+JP9eM1VgxZ0zYPS4kZaoD5yWF2eo5jtpb0SekMFg ZBHXrnu6gi9QcLnHRZveSI+wxTQxiK76g1zw509vOrxECCQGa7cIzgAFx70tfq7bm1GLpDub aPY5Tx9gL9XsMGJLkz3Shm8FWZZGnVxAkO4AH0I/YQoSyVx46CItozr4WMB+Mbh6DObt5h83 zv+VFV0tzNDaMR6fsP86RQh1ePCyNqzyS1Hved7sVnr8432aHJMgcHiBDfMSRuMs9xNfQ59z v+2hnfnsggrzcj0z/4yScyhJEqqEuWGxrDnwSRMwNmSzckxA8gY7h0PBnn8hI1b25sKZ2s08 rbBK6QawSjRqi3vNx58BrBrd0qv9zbjhkAlr25AF6Gt5Z5jAmMIxVT7VLHUXqkZna1GYt1tk 5hBzi0BsJUx8AzLxSbnjlXVbvNK5xkp6lSmYwk8KUoXSi66uaO+NjzZxLQQPX/ubPsbe2BQd MKr+Qh3RklxakoXTzgEw1ziowFOYDQCx82Ar5AUJ23qRZouKyC+7d6o+JSH7/zEuRtbB2bMK 44nO2f/ESqyL9wTyLJewyA6RWQd2DvjowVk6Bf56VRCEyhvGxL7Cq+VSQzsussc3y11yt7HF zyfw7WIumn2lI3SMv/Ke1Yg+K07AmQhLgA3OepIF0yEcF+pZLzNThrRZnBB4TKim6wxERV7t gcGoOxaEEM8DxJyfeB1lK3ShhCcRWG6ppwNi25rp6Z3TGEPRegXq7Kvhc1QS+IWhvyE0Q83P K/whSrZY/4Ps50QwjHbXPk74xux+vSg7PfhrPdvbdjY7ZrmJqqZSa9YcSBadb5dkWOJvb6hD +8jm/IJ2fALD57ai/oqOUlMEm2cTVG0a/EvZHRphnaSWt+1ynJN6e9lJMlf/PZAjPMKmWCmp RZppLfErawherMXi9amv+rh5CnGB+6bYFepEwTqAEmi4gnuT6vKJiyzyRP7HZ8OIeCE4LqL/ glQe2LbhwMdNYcyGK8qoe1aGOlIOUQaDwwd0MbfJqNb4EasEgA+YmnQeCcLboiU5G2LuWPk3 fP7op61U7797Av+DAUUxijt/ypXvz0jsw2wk9sgLJBznKcBk+dwTsL6euOWtryhIw7lTft// /yjK6jKagNVdvfuHw5dRP87nqUJ+Kcb2sCx86nJIRW3GpS+jAGPz+uAv0UNvqIqsaPa1+4KV jO6RLO9/MEHwcBvHtcxz/xfMsV/uMqL9CXlDVxfR16DrGMFadK2lZLIwlYH6jBrxfvCMEmIf gywPlrBZ/uggabaA/gwPi+XTy5pyWyRtxNfBc/135RGY0HZJuIl0snhP5BGBDkv5ukcPXJNY hLCykISjI2nAQJBWWx+Y2tjZ5GaSKt0b+LpHbDnqtXeSXH3pDaHlufwH9fAHBvfzzxgcpqxG lLdByi74K5kTw8A+JLNThP2CcZPID75uw99F9ddEXy1aFMxIbz0OzEa3P/yG4DbXmKfWdk0B pjgPeO4nR9H5ON4y19ZAbe8SWjWNAHCLG5iEhV6T31KwPBt9bdh5D74GGUguV8X+HxYW5bOW Do3wOay6x4oM9c7drMfAPFpNikWvRt861vvgKIWQdaDIkTq4n447DHcoVU7VjbCvVEhXjotp Fk1sF9WKCUKWa3QvaF0hU/SwixtcU2pb4hFo6ybGBxlVdIzj4isyOfqmrTB9qvxzbaj4bmXl F1xBl8JDb6msvszR1Q+GvyMV4QBeMCes+h92I5cJ22zF5nd1DRdhKAZA8OsbYT7R5jP88fD6 Ezkija5lV5e8ZOZXeN6dzbZ3PBhMX8c8Oj377/BjCc/bUqkM2p5gfzGeeyAeEi4A4Z63IPP8 1tRCBEJmnb5X8e9/40cdcG1O2a+Q0Tz28yWYPqEELd+aPtQ6l3xGtuC85LClKlQg/6gUesQd VQFAPUp7kl+FNkRepPpDv3ATFqCwhUPLEJKkx239dV7rOeWxmw+XyL/NWFT/errM2gYRKs/S fQ3VcN2h0IUtaQW79a55IQCwg+0GyH3O7rxQSR9mPtU+pUx5U5FatG7p4aclT6DShwWcWxh3 Q5cOVCZ8GWl8SvS7TJcWEc2OsLmGqdiFXhq5CmTz21sgE1Dr77ewSAcFrNuqJbtBYUhGNKrj w78Nm9nqI6xYxp0RUigUHSsNml4+XvIQGuaGpE1/EZdS2ZnxC9J206ilg4HOTfKJo3LSoecl zvndF+t0gGWuvjUzcq2ymj2sd5cvToh+3CZEKYCFzhnCs0ZHpf2yFPygVguXll69WSyoA4i0 +8MHT5zNnKwjzUBWFa6DvCnpigdXrHn6VODgJYz0Rvx1gTMFjHArC0sFL1LZl9erbBYRgigP +8B1s/Zrub8rwMuv2bSXXHeJk6kaVjuNaEkyfP8QOV//Qt88mu8WChldOuLl46la38jC5oqI BWeGGqiCpTE0gGxE3zHIo9BnQR+I4l1tTKAS1/MWYOzFZ3NAs7D+wejwIQ9l4P+RROkzBjdo EONwgRBBQOneEkAn9L+JB8NpFjNwlUvPeXY/vXW044l/uJ1dFTYkz1XrOiJH6FKuGGuU/O8z 1Pg4Du7jor1Orz00St1PTR+uZpiAYVDOkGM/MDAythGm1fDkVv7V4ibOhpZxPRIEpbhCWDx5 hadWgB827VQUlBR7GGlT5E+m3T2oFG3GdWUfYrikv8aDWs+b+y5OZGFh6bPGsQ63qRiw6ZoE /9gdST3HozhF8kAgi7sOh3x7Rgj3f/JO0wW4S7ZSR2R5r056zl6y+x1pi8LlJvDqvnxRPxxy Z17gjOgJL/XXICPFKgXAfeSb1iijmZ7GCsszz43JnRW4u48oF1stU1yJJMWAQy2ey1/cq+pl jZWCDR5J6FFllfkKUaS9v0vZ18FAj68/u7MWikJmT+xApr3zg4qDgJ+EXaJC8nbp5/EcaGVC TvY5WElxYPUWpTzULkjXV7QEjiPzBEQMHqy/mK6BKdZsZTTGVcQFJuct+H2rFW+iS9kjVagq seLozD8bD7sRg3qfTDRcWv8n95m6WMlvGtTwtChMez5P+vCMl9SK4I2/Dz25/m5iJsgA+ygp mx4DiN8TjxwiaN6BJ6PLksfGd6IhtXWaYrhIkjCSE2J0Nf9KYwbfWdTfGw05wDKpUdXxUprQ n85XnmNEm3QWkAgSOhG+3QZCGHabjavkh/Uyy+MUtMTQqwtF7FD1RsLW38YnzEJ40VRlssID gkT2MZJR/t+VT9URQvjbZhTk61V8i3QAg65upuz7iTC0+X4gLRv3VQ18BEDgC1vPw9P061KI 3xx/2X7AJEpwywRaxZ48YZPNI/C8fZUQxDld6/UK6NYOLWQYR4MkxtpDCLnEGJi3BPtIkl55 vdCb+03EDfYPn47c+dfio5g7t6Vb6hPBp/Ox+Zmr03dybfeUmkXhcfo5WpSIqayKq67n3XDT 4esviPssRHNvpq1M+CPfOunN6gQCWcqETdfjccQcOHAE4grbOcP0oZk6+5IrTa1bvZgAI9sy ocEeq9svivybnmbVCCtHSoqAlTFCB7iCxsXSNXDUXZrD+cf1bGdjWaXA/qgSKdcqpiZWHGaz 2G3rtAIQmi+6T2tmIprMh4wNyg21BR34x/k6QLlPzTHksdBgL7QIdG0ldk6lKi07GJL9CiyG o4oIeIofgfCFblkTMgDle4CctiVqYzTiijcScbrLLO0LS2honbfkXJJGIi+FOVff9drdY+lA GujgmQ76sJkpIuHQ7tQE/C3OTxtqQZr0VdKNDOQoOhfshRCouddIMTNjDC7DUfRcEC8lR8dc onzqctPZvTyYb0Qwbl0jBh3Cy3OSn3fHZiD1eILY4os0B9tqUZd/Bm50jw63dr6RT7MrPUWo 4YJDcett8WTd8bxBJdqUmlUYpiCTvSa0rphaXSCzdRenbygwrbaYQKV53fBMRa9Xeaj/gNNs kAn7UkEhgskLjQAGaPO4DyXb8u/4oQGb/vf4YIkqtVPpmH+opKiN302R+oC9uBDgMTYHmyg2 ytpamUFrAjpoJQJyykMrALh1MZAwgg8jYKDgDE7l6UXAyVUuIFG2vVU8T7LEnlRl+F0FCECA ceifTP0hJNy1nkWLi/u1+fmyGLOCvzLxzDb4X+IZ+IWqHxJYRB6sySD5w3CipEc+JikADghO 8m1RTVLxSrE+nvx1yTKiDpLhFWY6KNOK3GKgCl0mWB+yFZfUtgEFPD3F7dPILg94hWc2nxX3 XOIVuagjcwif9iM9BOufTnU10sVrk4KTAO7JgmMUk71hX1Um/gNS+jSdVFYWFra59FRvqz0l vxdfkSOCM6/x1zsex+bwbjFv2OHtgK1PhZfMGPRKUkAg794ED8NQT4XA20/rrNUp0Jw2ZYJh oe87FOwrg96i8RRTURC/tMnEa+0HvsraG83JP/ySL3WMl6QjSkIj5myyptKa9PqezVAHcyKL 5MkOY+6OSgBHa2zhqSg3bdRmqwiMk10QqK5Hz2w6DFnpczy1Ujhx93J/1NVuXh6WJDOrcZrP cExq9Gjzc0gssxDv0t/CM1F+rKA+4ftWMtTkRNOr7wU7Cz0GLh2667QxeRR5DiplHwWEQYq/ LyJ//RqLnnAwJMd7SsPv9o0M9xCMBCwKkpTI4SK6kjlOx68C7cxDt21RoVnaT5xzLH7cy8CQ LjJ70STwjtNaCxqsQDNUQpSHaTozzrkDRlqPej98p3g3FmkRrBWSi3AsPw7XVqxaHy3NWWuU IMe99PCdM9S0bhrYiHzHzi4OpDTfp3PDBkdXSK5Npx08/A/RQIiY/45QA/UiTUwood4GCimY QvtUBJI7rgoSkeROmhTm7r0UxCAknTMLLTbWAAeIcdjMD2X53Gb4pTGTsmV4/8n76w5WTKSi 5rhhDxg8J6eKJJkdKR5BdVB7Rhc17DFm6JC7G+zBjLqfmCLSLKMkB5RVqHyzYVakdKxTyehj 3SYTTDO/41GSFZffyz0HEYOrL1jtdiCBNiooXw7Zec5cw5Ya/+ylcZ1137hzuaI/KKAD6yNq VZxY5+kPyqha/tbDQKoxXPjJIVZJGoXqMW4HzMyKinDhgOqQdAVof+fF7GVupR1ROkNyxsUA 2TdORr4n2+saNHA8bUGQd5q7kGJM9s1O4TnI1hGrmrN1Pa3wj2Arqwv/LGwsdtw6FTfsaRLx KAZwMmyk7FYwBlSDo7UMIZ1bCsyvGvqblqAtupnNONf8XwbItkPenaHgRkXoEw5oGDtW8Z+j o44s4RH5qlWsQKsOEd213cJ8PTvhXALuAcSPlGQ7/KYzAGyF7dYBfRadaoenDcvT+q/+SRJM oRUyl7VbFu1VSCnMn+njAN7HWUMyppuDUK1GguKEr99FhrlrEUL59lWi1C3WR58OURXlvHhN kfA2XjSpHsI0qz7b7BPRAohp7Kh2f6OVCOQSzRFRMEHyahrB/4UCSFoXyXFFe2IIwaFwI8cG PSRAIMGuPPxPdlaHi8bQICmTz/pmzWzhlFP3B3C0MqSYDmXOtqLCz2imLS7AdEdnZ5gs/R9j 7Mw0+XdCIoHn0sKJ2UIr8T4o5ZxVCqOXTIgE1EEh+gNojvx77LVH9aYomCgKbiSLJahJ6VKY Wzg0GnL0TdWzPRmT7XnUfZGrXONavIt77a1X+dYYsAxBjULCcW+Hz7hJTaNksS/WjlBY4HRf 6kcb8MKzsOzSKKjSXScYwdhZgXVFnLzjwokU6yO3TCgMfhNIP8FyWRfSoN1LK0u5Pq8DKF5y p6+s9S4wlpSj17kOjd8vFBELL7kssXZYTcYBEkF3QCyHav8wpuMSSx3jcivCZ5RXBwxbYKVy mTmpfaWbhk7dn8/cYRA4EFXAsSTWz1N7VSUxMYaaEtWMCaKBMmMJSMJEYtsTdfhQGDKjDH8p 62lhSrm7o/Vvx1OYeBIq28FpENVLX4ZFQKmRjBUHi5dU/Hqs8EYi03FdwFA2UaNSf6H/Ke8J 6mKlJkkokW6WosXHreospK3thCAalgwhea09t8yzA7OP0a244q48Q7n+poqpFUJwukVi0GwE +gZLe+tSSYSF22XpKmGEAApWJGgQbPupossibqs83uChUB+wFM5DwSG0+g1LaiRxc+JspW5D Iw1WNJOxGCAQixgHd2TpvAdWh3nNHJeFrGA0NVVilwFDXkAO+4ulVyvXCOhircwMNaEY3Xd8 i6ch238IB1bUI72x37V1guHXvrpJxUpFhOAAcM9hC88I1vS6etghGSwa2/Ust2fIgjTeHqvn Hd4mJp09XopBqer7fdyomwcAIRR5yLF9fW0SpZwtWEc/XOCfWqAj1rZQdcsjsGTmpSQtLV+R bJJRRpkvhrVgkHF8OI4nQglUJgcJL4Fhr/wXdPaA2S7+FbCMfVHCW3qIijMnId0lQi03WLuM RR8iGA7ln1v2y6tS1roPfRLHLx0J9BQUnBgOs/maqNOlC0s5v3ZNHfRle9yB3QAJcRXCJqHF bJJBebRRGPERkVy/cCkLQ5HaF2v46GzetMmzcwG8Xq+K8qm8SvxGL6nGqS//PIC7QnfLpNJg jQ7KVt/FzKhfMumhwGQtpaQGG8bfoPLfgl0cKZUC12I53+ofEQmK7OZs2BxC+01xJr0JZhv7 HU3IUToFm4z+iUb3g8FoHxTd7sBBR2u8J3sfBA9oc8PMWc9x5j8I3oD2jvkt2cXqdXU/geU+ 7bul+PPCLtpfOuWWyZmEINfeZPTC8kKtc0w5nxYmxGOAf2QwaiHJDxmb7CmB8mqI+RncpYGX P1C9OydgtwlVYQw3nYDWnQRxuN8G+2VJr84c/zUQSCFGHIT5gf9vBTCZusRpyWtntiGocmYL Y6i1eH1mYHAJllH9bL1dIe7w/SzSE1kgPH8CZte0CRm0uF48k5/kLJbOzBcAX5vXJiJRgeSr LmI+dKUzVXACJ0mKa/PqGyFfqZawc7QPUbeMkwyoDyP5uUjHGKBKvIhOYEX3OMlizDG55jhj qVc6oMnuF18VJqBU2NS8KNanyEsSHOBfhEZQEtrGnXb5y/Rx5OS/SuRW3jnnx+qtq3dSu+HJ D8KWRGZSSMnYPm6VfN8BQmyyQv2IrJAl7bAlsaAWIy5BHpLkogitFSe4ws+KIQeDih9BA97L aRa3yzea1DqMokJc5lbfs+i9HjlqjvqzG4L3vCGiaWYOcVttrrOG3+QqHzKeA6IrvhT38vls iDXXCDGTz7J/rBH2n4ccec4CQbAoO+uh3EhDtRcpZpMiJOnTtFzGboZB4xg6e86hq6JJjKwN cIf4yDWbQQGixhEe5YQEMxWY5JYEp8sUqitFuhoPXo9tkqKTnzTpSOkvCYuzHcjbidkmsPc9 gDM/a3hqWq4y2ek+x7pYoooajPQFi4QCPG/P52d+zpCbaCRheMahk5OOs3fM7626eGL9uMZj SA+MLm3p0rXBWXTaAdesTwJSDbubJJRSZO77S2bi5XG+GZGJb0f/BToOwqm+rlLB+wNx/sW1 MQokZXUFln5P9c2Db8VMSbzwUUkSNaQCCvzBC657HAWXVvN+Y6D8/0SLIQgojIV+bnsLHpGB 6bjZX0rtfq0xaObg5g2V0eEv7nPXC1bPIvNTLE8TiAQUzwKDNaMnYi5x9g1T43LKgrLnr6EV mvzfauwNcLKyX7u7KPH8RqGgjk8hx4JXworH0mQYCLvW7UMnSrOzE1clb55M0rQK4j44WZkE qhLjvhin8jkVGEr7r8C3hqNn5HAhQqXZ6Qmlvxj22gmEKZuaJr57AWRlow58fGO8Zl4IedZX uhqdCOpgBpGHAriSvSoHnbcc/OtWmcbUQBbnGlbcdMKiRIyrJrbZwN/VSpmybjWbQVNQNReh c6XDs4x+KSfpZMCqsgtfsLEn6HWomFKGWCwhg1kkDwFK+CrFztkQvDfWjVigyzPGE9Y6VYBq YLi9R+Jtk2/geDAhYaeaM9yiLy1E1qWZZVNbqKizlAozvtzh+gAwz9/db7P9/73n5/MxdpHY uR04syfFt4tkhVIRpMQ+jKcFrQPjlAx+W4DWixgwD74wd9rfQYHoyUc75Fmr+/zNBic72GKB 67B26PWpRjj249TlZMw1B4W4OHO1avtftMz7U4oKrpBs3IUb8XSUJ5w9bo1jcz/jnrfI3vib czKzYP/1bThf9evIzMnZUwhh6QrANjBHrw5CI/WYvG41bjzR+YW6rz+2o6oPa7Bt0A6POI9p 7d2hTEVEFeX+40ZBaiUSFGO92x7/wppDQnr598utTcSO83FAT/lbZVM4ispYA0CzVm5iw+oH 5BGDjuLzdosHhHWAacyqzRYxhbKzqO1a+CNOCxV12Ma++7SBOc/K2xzRNlU2Gl80kP/UbYkw 5WA8nDio3e5dfReLyxRUJM/w1zmbF+qna00crznwcM9g58vEZR7LGKOy6sBeAhqdsGCY+ZqN RWYjJ8MjKvOKp+RFhJnOhBE2VQCo702EssIT6LwoPYZmW/Toc5Sd1Vv1t3mLmi5epPS5xYr1 I+cVd1a0tf1rPAx6Mvuog4Xg4fuiidiJ/bpyMtDbl7w5R1jOf5HqjJpv3v0Od26j263Cyug8 HROF3onjn1ia9DJKWHLuKvCr0DerAE//fhfkvx8w9yPs+/XPi5dSVvPouTqDQrtU/x91mV49 b61JVNZ3fhHfU059DS0H40wH7S2oWqZc0fkj4JLNLyrTyqOAgy7xmPYMPnOXHdWjoBBgsV/1 BjLV4OuRMW6nNGw3HPmQOct/yfvbdoh/EmMFBhPSyvKb/WT7IooNbDNZUaS/sgV8QxSeTd2s nDrGA5+OF1uRVsnJXcTX3y38qEdcSbZrl7YAtCRSCGLc7fjziCfTqa9+Oea9eRlZR8sISGa2 UVjvnh9HFcit+PR4qmCuKAb9mh81iYzrCq68UhfYl20DNgK2puOb3s61NydxH447/G+Yq0n6 v5yf+suHzwvX70TGcxt2zVvh41AfEVO146L76epASmGLQCAbbDMYYD/sMS2JpK4t4alxROfb lS5Wx5bkOTLm5oGY6EEbJVX5TF+SL5bl8MyYIy9IWi/6Z0dY+OhS6CO+4xpnb1R0K8+MdObr bDL3LA5yCVpRG2EBhqLQ5FUihIc517cIPI03kM8mJTLC9BgCYWMxhq7LarPKMKYtBEUsbctu MVmDJoAiLJUTYPsLssWxPJvYlPEpoVdP0YDYVPL0RqEHkYMAY0BzeQVtTLWXoqOwK/LDii9i Kd1rEzekCnIv7i1MugI7HTXdUAJFRVAyS/oaaXpedB/8DF/EbzdA/3W4WQDmYoeNJOYEYKL9 HUochGddlMv7AI5uJ7XO2J1b/kiE1SFoH90hQGe6TFvLZ/UsDbiV2vWvm7pgHT19BRVd/gUA ZuaHfgu4zG9SVhHAU/9QfHZbNL3XggwmKQn1tahMUuSUdzaaAVFxDnjBivPj+bI7UuFQ7zdV cMHEpdROBkgkFlEdZBwLTZvRYg6EITcA1ujC+x6TtJ/Pne87OTSEHF5iP7/8ZyrSDpODbK1P vMl1CJUjNNE/K4V58ltdVIeav2wOZ4Sp0b/FGYhmwSnTB3ZuPCoyOsueGv6TktKbYygK6Quv 5XlzhUV/NRiqBWwOcTI6Fx3M1fVebJjwm2TFIxziV/IrvZ8EGuRhgeqXYLEMryl6eLGjd1m0 LUa2kUqDBwnKN3vKytI7Ca5iUsdrgMox64eYbjFL4qPVRyPIrEccI9aPArt3XktyqoVIIFKw ubu8XQ1PzBk7OFI4pakJ5nEqj/cGgfYv9Ajg4TloMwDeSMAk+Fag+GmE+/4ngNlw0mm9t8+4 DkRr6d8d44KI+LBvgeDPtVXL27rT61OY3No/f40ZQVMcSRdnTkZQe/bx0kg/JxnQZHE1b9jB rtmKidah/kC+QuWliALQLMvR14tJvz87qDJ5NtCbUqTnBTOH2HKjvq1oHlDM63CX4JHJBhNa YevPSn4Z74cEEiROKJu94ZpYigiwN1yoj7jPvxkwemn3pdMzfsuvcPheTDgtPD0jOAfgSbBY 6WPMZlrjqWOkHk50whJ/Dvl1tUg3mOfVSoLNip798vAz7RB7Sl+c2GU14z4Qu3N+pQ1axaNF gL7+yrtG+YIkm7Eo3dkjtmYyc7XIxSQYNWf8w2AVV3zDTqzUJuaKRO2WGFWAKHCanQ7T1hD3 2NasPzXiXJWlxQlANMzGx5YKeAO5jnwgf3XM9BHesCjY/Huu2cDxjXKJHsCPSMDcGV1CkyNk INGk/SfgLCuVplHBusHggjaIczplT41X8xPOrnYcpDYwnE5Zgt4wqChpbqY/OlT8iha60PVK JNfKxn6SJLocXqJ/EQ0lcloDzjXjXwET/l5be1lk3bGHFUFOzF29OsZXtOiEsgmML05Hcejk oV3xYkrXYJ2NZavcc9GzsdyrtffF+VTmuEdsEdJaMSOyetxgBdNSxHPZB3jYqeeCWPwJ0JUL oPfET2h7I1DTpvGeseVO8CvxAXwZgGKUvHgHIAiRLfPJdnDPBUeCnPKWOq7c/SfxZjmx6iYW ixyeZAf28Y7H2lr+/gWPHirgh/sBLbdwJxqxftPAC0hTuC+I+DbxrayHarXpy1sOne7P2woD z6JwHF2rpfNH7P0J5yTnCnCaXR6GfRtcmh6mCWUkPD6XncLjt6mdgACpHsq/NQv3kChMsjb0 DcNvAZ7LZ2Po4Ag+sJH69o81BkLQrcXLIsQzKXIkDxVb5LfWH5N0y/19OUlaQzVFGSB7skkh tFVPmCHHgPbvmaRb6+EItLCCVF0TZM5Td8KgOaUT4SknEbbaWf9ANE23Kh04lPluasqRUD3z lAmNU40klxGgOCzxrw8ztc2QDKBMO5WppLhSYjvRK+yf11hvGxdCGXoQrHmRr2sjOypQYOlq LUnK1qGM1gLDqaQSQzu8EFqSkVYu8cyPSH442gPGAPhGxsQFsthSqGahF3/5mMtNP6PmdRZT PW2xN4WL/8mcNDpUR9p4u5VR16TmPkgNmk4iqO9AA07WDr48Jt1C+zUMr+73Xp2vKPPB2L91 zRcIkeZlXhaBGxRVlK22mZJotA/EKPtk1q3JF3JJnhMWL4+dlfKM+h1ChCNRDPRHADtPYwz1 V11SsfEi+3G1LN6HMIElPV2NqwWAMB4imeDcO/Wwb2EJ9QBGJ9mXFnREMCPn0uLjuLh3HmgK fCHGMku3yIj3w6dKxFRd5PN+JIE+UyHQyegEjXQAmTpkiYNZ+2DfSph9WlqwdSqkxNek6Kux H7NbeK+SuBv6O/30C4NZwWWC30f53FogF9LpaUxFROFW+VRbZw2a/pzdj8EjfNFaw35ZZ9Ri CjLgWhEUMB23pSMyoRxhJbqsJhkn/n17YpuFuUZwEWZBDbV6wKToDU+Om5Llio43DgcYdiYd rNZ6wiFCL+t2h+eMlKDgUEwNVb5guasfwj/jdWPEZ5TN2gSaOh+rfEWeopx7KSuXQ5TbaWpW GFtSTREBbO7XjN3YBx5RvXXDEMERHQxD4zR6HwWNUHg4vd/A3OcjF+09VdK7WbX2Z8K4HjhO kadcN7ieeq+tsBlqZHSelwVr3DNC+bw5k8mBENVQD7koGLGlZVcNPdEa1yn9N0v5SA9t4td9 LxJBS3tRTBv+y05GeoJmOkO97pLM7lvk2FDUrEpC5VrDemrIwpmHt0AMUDFqD7CW3Nkn7Bl2 euAakEugy33wJmWet3tBLdJeBjWG4JUuw8qX5hVzu8AKSn+Px7Ztx1A76vA54FOsBiJwGq67 w84H0Yg4Yt2Sec9Q64+kzLCTyYMd8kJjxtHgNtwBYB38nieZryFDvtoSdama6p/Of2dYxJEE wnIMAEtrcT2pcRMUE/j/RxbwyCa79Ube+/8uN4rIvVTZQQsqMALml1a4Z91uC37sdvvJ2oQo SPCOCQXSKeXuykAJxeN4UBJ4ThOSrES/6OvcsxSDmadOrkSBnouRMN2tonN8KQxqwBfyLPnT +WzzhaFqaGQhjFajyKlEFw5mtbxEgFPsFvygyqZ1p24pQG60jllgg38dlbfSLFNiDpgO7Kx3 g93oqsnjuX6pJbOwArZ16SgxFAOgu3NgLyKV/2znW6/1hnF6AtbxxXAOZEmCdFZ6MQjMcubQ /TKFYecSRRhXY1V0KBCc6Ls+P/3cTligpcRjHfPTZEFCFlRr98qrdq17j4mPlLwZOyW+zFCq 3/P2CCYpwjrrF6WXkVxkf9/8TO+h68bMOwuUTULHMUDjI3r07b295S+yTGkjuMJDebPEXvvb 51XBVB++OQrp6JqrgtMOLQ6vc1f7pqEOvkwcpLC/A5KQNBY7hjMPOtG7ImdsgzJYZhX8Zwd7 Uuwx9cQVBkJD642/3eIwfLQEwrGs+GDBktZ9PBXOUnqn7vF+XUpsUbCIAOZbqC10WGwaBlh5 GJWh/HAj3cPqKWk6hBkRKjnMZPCD1iVnEU5HyFE6zGdS5BAPFpQA82NeZ+abhQqLXBP5Tsab epERtYB9Y6gJC9sRhLWDNDqV+BVYlwY0nGSqSR1qFZbGKXdZLBpdnbKRFhtuCSP29AHrkQqC /cGa6OI6uc/8NDBKDmN1BwHZ6pGCdR4JgIUWGV6ke6tArpP0OFtqWtL7XCTPx82zLnWAE9yL uHCzc4vEqbLmMWRQgWQqhV/jzxO9WNbh2Z8MlpZN4LDfh40/nVqWlGbQcYmYQ4Faxx2MnFsr xa29rMnExHWy9++Qs3iSWMnsL/IXc/Omh8tsJoTPva5QF0PpWZQ9awQJ4bdE8AVZwIwQJxVD f/4lmRmzgMvMJB5449BXlI2RBKMAOVUjOQswdB638HF9tnSwbsXQXTPE2Ek3s0k4EPwE5+bZ Jq8uqdi3iOHh7vtHbI/8JkzJl4UDtJz8DokqSOnrflkKHEjWHiMDIvPQZxA3mD90a9VEhKDu WAVoREUPQHsOnQg8cVM21mqTI3IgMa9Af60/x95YqP9w2oCTUbOjxe+Y5OYn/bRzGldJPsvw psNDv+N0UeFqi6uJgWqfw7YCzqTeqvCfUxBDXrx8/7sqYhSgNmwOyRYuT0HUZd+uiP0zlAsz rSQVaoFZnLmOj4cOVNpgNuuI+n9atKTzn6jBXB5ogq3SMKmtmD2dyxuUQ53mvukb7D07i5bR 3FVeyroMAHPEqk23QLnS1EnB7TceTRZOAwfVzXUv/js3TE7HEbuDDnpc1L9VhmI3ofiN3yvt hPV2gUZjw1qKGZAIcTxRfMHbbw1+7nX/12wOloF3L+ks2qKEOLJ38FGXmRQy1JuQEHCNfP37 MEeVEjJ7AffOY/ePy1vf4wZt+sY0yWUvs9Mfv6oigcPgPb0tWfOs/PFZIESiqwNWx7WrF6rR ZOql0qcy9/ZiO7TNSDQXeWV9J1zWu6qiqegIBFddhb25PgbItrToFExAvZ1IcywTEbBIQhxU GTLGSRbiTi0k/klDEbhy6E6Xc18E9QjDAXGkxFkiejBTI6kZbVhayReyvOQlwcFdcu2jp68P Y6LopbSs2tdleON8s6Hb4p/CfLOLAjK1AKAgOxYo4E8nM1lYSqRFOOOQ3TENt8UFGZgmGiMO iXJeNf/KNQAyn5nkWNXyjFhbi2qUWEreW0wPHPk4nDgh8DK5wZ0NVamjh7/qutkAiOOCsu74 hMDTCojaEf8YRtNwLRnKC6AC/QsqRVxXqj4Q42x9db+iRpmhmpG4fnVF9dAE4zSRsksXwg5C BTTDlsv80iWmxHb4GWYBQ0qAWu2juQzKLdJTC8nYGGIM5mZUcKZ3NSBd37vsEuY+4/5Qjmfo PWtIE3LVSZLbmlyI0jYynUChKPW506AFMsQ/cHzHv/LIFKqTyjoso90S+s4ZwbBYfPPtI5O+ 5Vp8O675ukM4B7ZrhP1WKei1bHmVaXOxS8FGBvbmGl2lftJvaBVI4zV9b1CKbGBejvx2faoA 4fS4NaM9oKrmNiNKtaWyaAcEXdQ+IT1BNaD0pMTGr2XZ43GsnfIuW87FshB76z7+3m60DXk4 vQBCqX7dsiYlgh/zzVOjwgHdTU5Kwxjqzav1yvfuSoPJ4JWyH24KRStj032cwc/0Sq9JfKcq B/MB6EYHIuD5mdFovXmdc63l7tjS/9eEjrxq5cgwHSi8QWN5F94fPPMUcow2I2aCgIyjX5/C LleXYF9TuBachQIRcfnijT1SP1c/nhV0kyoWW8JsBTJ8WnvKBKxvXF0Rzh/BCE+wy0LBaPp2 qs3uSde5BflTlqAU4VJ9+9jy6esK1Q2P618M9Q/lj3gTE3nm/KR5YfNXFKlekDTzSkNfn8kM lHQTD3Ity5MvUjc89czxhRz0+04YQ9xDoNd4ZTaFW20CgXgj4MYUHK6TvT+2Aj0+Mbk6lkA0 sbfjbBHWLBTjb1jjA5QNjCfBHhBFeMfStGgLNdMY0hDnpCMVAFXBx3av9Ymt7vUh6Fj6ROBr sEmWh2WFolYgUkxejM7euaU4S11966/QMr5uVeDLe75JZQEybEWxbFC765P/pgLQzsgAxiKn JgZEO85QN9CyUQz3utYo0vUhUpHgSr79l0+20ttaSdzd7Ds22xk9LtRrSJaD2MnlWULsfx3c rLKmUDPl9a3XeC795PxZJQBamIjKMtyz1pVbGPR/+TMn7a97ruy7lSg2onx0HA4oKsXIRQ42 hJuZWzhdx+EcqVMhr/vRhJWReoG35FaLMvv7IOYDcVD9IH7WQHyRzqSaTbspTvQI3pP+9yC1 xUVKro1TaP9TmjLObfI+w6Grm68dCwIhwwQlYIS6Y5sQ3fSl8TiXVJj8UYhn6UuBSQ/UgvbY jqeSskQiQ+pqNTXgGORTb/kRekFOqPtiL5PO8CQF4XM7+0JoA4BtAejG7/HFmiDb7Rocwel8 +YO3WiBDUhQg+31GJEa7GjLwsNynJYNuwZpxQY0r1KqQle7A+o72o3L37bnisycFd/OWCDo+ iWWjMv6iY7qGwzW8O7yeiYR0UdxHnyRB/dOha7sCH8RYtZAuW/gSb7iXgG2eZF1ThV42VUaN Y4z+rXXzJuqmUNk+/Kbl8WSLwptHJo+xGUNGIsxhFDzww84aFegB7uTD/715Z6/p1VTqB/Bm psyS2kB+htoZ5lnFIxyhKEWD3wWAkVBHcvnjpGFQfwJaYZyRwv91iNUYtiK03zYFfzYy2/cG CvpWoiyLCfr3WKkYEOOoqN+Pr3vgqWVQY0ygtFVcNZ4bbYmvZxCEoHPk0MufD8sr2iu9/IpE 0MDjP0Z7jF9FHBludihlpWSqW0w9pVpJSAJqv8euPKSGDgMXly4nAAw5NOn2y3Krb7NibER0 QEhJi7U1wVnssfPFYvPwbhUHKlI+HKqLLRiFmf1x7xUCfvngLXTPfwFxA21eQ2a4wuNdf2OE mWgw7s04GWQbtYgvjpjKbJbYOfR9/CJElVqsOn2TsbUFlEOjxgLS+Dvi3cwisWnx73iRVEck Juk0tH/UCYEeQyP5ITc30RQ64jf/xpZR7P1qTeo3iGXploAdWXX09laZq2+hfv1HgTqDFp18 XPc6Rauci3Hcs+IAbobRdDFRJsPQm/QtyxAf5qXY2VRmaajGbgVxdPozmbsybhEGDa4we/AH oIxe34CxmYmcAoIEBgTUnurAcrSmkvylwNylOQo3CcucIo8eGLFPIFGo0j5gziXQOeFX3DyG WpcNJRIceS1K5XRuZVt2PPLE7/WTXH9lYbjz8+jyXvi/q9GW1ugH/r7Twoq8fq7erB9sGKS4 7RVjERFPVf99Igiq+6Y57rV54TFGEhJFv4wFIsNb72vcwXJdqkOBeWlrO0MMmyt2rbKtJqYM aHUzlSaDOKdLHaEkBXYEQ+Gj2ItO+I12eUOwGAwB1o1zzEyzNQ4JDCUiI4tnOzlqXDlJT8kA 90PS1RlTBQJcHeH3+NKwMqaFHVjNYlIUCGL9fW9F5jb4cOiv3gXV38GsgvA3BAe4k7ZYzkQg 4qpP78h+vhc2km0EmCkpvuMeVC4Z9TTVHweW0GFM/JMguKWUnsO62QY8OxOBNX72IsKm/Stx e2b3yA6NBylAINO6RxJwSzHMcSO6YnZgsGhfFI3tNM70PYMC+hzw2CLRf6Eaa0dqYB7brud6 xeRCEZqR8LftIW2LQwpu/slmZ+SX8hRzpCR+YlxhOsU+3p8csdFZ0ONWpJFhgcfuytyXltjY IBjQF9HbRJ3QR9XxA2x4aCXJEist1pmJbWVfcZY8ueRB4LdfuY+2pyeakL9lAPGDWeBLnYxg 8xaO6UERKFsQW2lweYo/PY77htfj5UqCLktuhlPNbF8V6pjmv6Lppz50Foo2lWxD2A8ZZZOg ie20LMY0Rew8igTUxL9gknJX4c4biV2BfiQE2xqV8xCyB8mpypeBMROHa9Q0sxZo2YkKjo5D oJONX1mCdmSD5vnZddgB2dD3CodxVFVp6HShL6cLMyyurlLKTPcMdBE47cIZW6l6dOC+wYSa CMwIMK1w9jm2dUqMuLITsxqqEHeo09tWoNp47upjpzg1of2jMA7Ih+6xmsjjX8s0qZ+c/l4D kCOWNwG8lEpnfS2UFgrsSg18PDVC6fqVXO3oy40BuJeg/Pst/+DIhDXbV0RWEVOMJE7M63BU 48Y67icYZSNSAchwd3p1pnV5q8RRA7sypv6bynLFkErBqnzJn/07UQFkP5V4c7gXYAPOOC35 LZr5AmCMN9KIwE37ODL7UcuNTx4Z6B3/ARMBnuYLYaLO7Kr8SmOlJQx+BYG5fBcDBWGeMX0i Df8gF2WptBPISeWz6fZ2a6LnAj2GdgoT1D0s0VTQp0Gjr3CnKsCHtrpKTaR8XdRw6roe8WW2 xfZvwoK6ADU47MehtZmEXCnaJ80kHVK9J+E5iRrn75U6A1no/smtP53vvsgfurLTbxE2TKfp xwdAsNweyQn36EwKyAogksNSyi6q6D6wlAxSCG8EibsTY5puE3uoOJF8eFvGhLvOooNEZYX7 6A80B3wPGgx2KM5YPetp2n9zPIry59TOQ+F+F0vcyojyvHYORe/tYRB1MVmiCDCz58+bF7og crBqf9LOS7Y3eNB+TNfK9ZPvXy2Hn8v/2MRcd3PiNjZIVC0v5Az4TShUkIS+0oLf3Gb9usXT RXxXr2yzNNLpTiHTJUwhLk/ZR34moYtSEujACzwKOd0O0U+UhhSV8nOG4wbVn7tz1OLxQfXa wMTd+bfX+9g8tCXJhlLdSH/q4dSCJubi6nz9qbjj6AsJAOWmyW9v7y8yDUU3sFj5TVWF76e2 KJJtG5Mdp92H3qqukaq/ecrZfoX+bHLXE6EvNyJKSRSBICEKiDAscQVL03Svikn9g65olD+K 5aBWsb3M1w+tXaXx6lNEagPd+OUgzAvVOsJsBXntl2zGPlM3ViFI1xvt+YM2cuYNGhIgnahN JrfQSMHGZve6Zg8FE+MbGFdCWCZJnPbp03qL5OD/v9bHcRllFPZoL0rKAyTJSucBn8BAphWW oCJxqLuckGODcPGp3YV2yMDEccHeANZHE3Zd00jXyLKgcO83+Ewm/1uRrH7w1MKI21d3xGV4 mU0qBzGRCqgx0hK52YjVf43D0dF7+D9GSHFV9+CJT7+h0S6lagzoIfcchWR28ojDtZdreAt5 NVDkjREYX3FK+lVoQw1UAjkr+vJNTo4hZS3FPK0z1ImWcE3EsR+Q1KveZ74SSkEzw69ZLoj3 Fc4wHyQkGsOZNUFNtKBrQqcbkjjM88J3dSH/JabE5uO9FqdW4sWktR594YwL2pEVTuxYIeyc 74EAIXSOsjg8qhxdNBgQREgtrbessLgJzoOibDIF4gW1wkVu001Bfut2Th1oKeTA+GqLUsLs V20QCqMMnau23S+N1kNf4gYfR4xRccGMro+smjM+iaIq2SbP/25HTaYjoM8oFt6RIeoe5lDl bCvZxGfI5lvx5JVywgeQA8qL4iedcHjEmgrc6CJzXYaDmFy200LZhmRSIJSWaNa7nfdOvJKc 8Gj+OUxkmavJZn/zzU23Z+cfbJPvb0Go/Xe5Lk2w8d9+GeVlEsUwNe2pO6R6uwOSRaeFb5ER 6yeXhJf0s5aMKuS/nMDLhdDWhY9cnw5zSjrXB58YFJxBKbDRoWQwHiDQYeTBQq4rOuiHaWc1 OGCRYd3JkXj/ilwhTqWMtZZMqa1yCmQ07lJMf5aCLPLi9rZh2KjhtuxYpgt+WURWXvzTJgYB SAf9lFlRhIuoi/LJ+LmKLBlsKkYXVJFZMTt5jF/maOtQ+m9g+HzkhyTHGgzX2/6/J4JkVpjK okQI90Qf+i4GIeuJOTEyrZWWD9vBns1WBPW9/lbOmtSTEYD8j5G7dnirttSDLGIurGHTYz4x Th+G0OI/4TIXTCoJKJlOuCm37CuSmUGC4q6AiIplMy5s7Y3L2/CJUp08KxrHsrBk501ZDT3p s3NjVrFQ9UrrZve4TBMn8Pn98lhtUju0rFrd4MycWnlJ2vadx9MT9Qm5/pDIayF/XrZwQf0l b4fvq2hPtEE9gh5RtB16y6czxUaNcNcZbEdqWlPF9VDzHvYX6w6GjfWbfNGZwpNvvFkpW2WB avwLRtqn5BuRDxqGdciflrL0J6mDshPaj9VO6K/pGNZae/DiIV09kL97uxTorv2e1NsztCpR pON/c7vLXK7Kssekh2la1Elfq5/KnhO8j1Jo+LGILKTGWhczsDgI8BfnLrKxtbJIY073dnPN mpk7PKXLYEMc6/1TCcLS7yur4M0WjBLxO+9H7z+SzSSzRUlNz0UnqtnUxtBoQQ4bSFza1gvO RLwtz8QJud3AstjNFdM+NWOruif7HjFS6YT2mK9/jEzMJKLjP1ESoqz/dEcacsRzv0b/cl7n 6UnVVH9jtWrQyCNTuzXQNbMFCHb6Z92kyjwzlrQ7AsDBoL9DDWNTCU+TrBjmwxAUABaFwZqX OZE2DlrPHyDhBU6KUJ2Vd7tCoNPVuHYvtfe8WF7OHBQqdLKn6CnGV6fBdLUFXaQxbGqK2ck5 4IACepu48oedbbZlvyu2vJOVGQDOxMP4PP53E0O6Mi3GEn9XeDtarZJ8SudAxpzfgGJKgsyI OVCBe/W6qzhKvsOW7aQ2H5UF1BCKGy7XjOdNzlkFsjrpS8uCqSU6U607fOdWT7JHGlQkIZjd i9yG1cZNi253DQK4vNSFoctWDCIXSUCZ2LcB0MJUxDT8HarC7IsCftmrG/wN8EQPQSlcy/uk 4BB0D7r1AUT2IgyugtjQZvQUq6OnamTrUM8nTAXFFDzy7iO1eW28+qLfEj46NzC4yEL7qMS3 7I7EWkaBk8izb7rr5pBN26NkfiekWOuSE8x8ZVr6xXPW9pf2RODjaijVnrjYh2J4j/MB+D2P f6lKG+Mx9JadeHwBEQiO9B3l+dztwP7wf10QmfrePRQefTIk/djlaUZEETTLDwuxjwy6wSGW ONySrVil7svN0EPe0oqQNJF6Cwmp+bXCL2MHVX0sHlTnlqEmh610hg/uYV7L5HXs6oFBQDNt nG0xLz6E1bM96W6nieBevfcHGB86d+ijlNE8FeZgos/pEaua04g1w7+JfGie6qXEElO12CcO 3T3GkHx54dSEgt5Eql3spw2RDUl3iS5w6pzF78dGpc+yA9di6v4eMBa6bmv6DHhvRGGFNvyQ 6kOVkJQS80STluh/o3P/cOdZ2puuIdtS05cU7DoHI06xgqUiz2Y5oZ69iTu2CjPizEPYEism 6DXFmZcK+EcZbdXdPPnEZ1oyHIm1HrruZDc1vp5lWDWAyfGLHGUQCPbIcakHmT+GvdYrK8cK LovsnaPFeHlPY0vjH/QgyocjIH+Q9TdC/1OeNUlR4ldrq2xLvWKtOUujnsbE+OrvkfvZU4FL zKpG1RDBp73JbQo7hBaI9BD2Oyb2qZCuYsms2qTNwYKQg/AedCALQkJZsVhtC9quWut2EvGf pLPEd8ZzZXm2tLatj3XV8DYmVEEiH+dG49YX76ONJdgGQntozVwnWK6fMnlJeBD2kp9xh777 sYqrBA7Xlc/iymr6jT0gARD4hLc8Wb7pON0qImw1m7SkxuXYWcmEYTkxinXGMZ4pfwfM5pXA /qncjV9Gjpd7yN3PFhsjN8Z8pWeGG7WcA8EfxMGH3iIe8MjH9U16tPjLupiumhtWqz0nvgXt fG+mi7SxOXWHURcXRoTTaARDnBvPI5wyNK/Vzss1jptcycnlxlOH9sLTKu0uud7ofjql6azG gCsyo0YEK3bxbHwDzZA96OQYXaaClanx8B1TUWxpqwF+SjEPtY4M7/yjxsD95R7xCLoIafLj nOQsOkucLgN1XSx3oNkwnr7puEjgV4ZyElV+QULMVBw/GLHxtMMlutC6OIqnFbMt1rxpDMMi lLSTVAGNdFRd1Qss0doIvwVwfrBHbnOEM24sIjQMlaC9M7RrMP5GihXOu0qIix5h8PInS79g 0+81GD5TiDf6puUpy4mVM288jv13pOcR7BSXvi/gp+HQcJnYmZtyX8Baaers1C2KrBu9oLJI opSa5DuRKvZ9tWl9hlarBzLSaVdLUP3YR14vf81r3SLxMSQcmjIm++xQsTZ8/zpYO2OMo8E9 /Y41hvWXiKrzdVFpA6Ggsb5ecc0XO8pp49cJyHodrW6x1YrmttkWuErRDPFpyGUX/GUbZ2nh TAPvQhqiVmigmEQoo5PhBJ2M3T8u5JulMcyglzAWcLgc3se4BlTBVZllVslvfurk/7CczUno Io2DZjrajUmPptq8YYGLPIcZUUjBBjIa2CVF242n/HyeX6euXPrbL2y8r+JUCSP62Xxq+2uH cJZem4gDgTCE0dx2jOVRPTSuNh3r4BVYjhl562gKlNe0r81HKSCsIIqBLR4so8s5kJn/HG0E scY1pTtphl48vEBUuI6XjzCAfcb2TkV3UfLBud+G9jqEvtTQLHtwBB7Nfz8ZlyqBUbmM4lGx SRO2dyT0TAHhhAGbBtn3dagTRt8mwwvTmr2AiduYwDqwd6hAWqGk9vFsF+z22nXpCFtXPM5y p2rBPVmLJQOLehtQKgseBM6F+SORl8wf8ck+d3kX/odkR29Jk9yLNWRK8JdJiox/KwctaWfe k6i04Pp8U1GfWP5fIlVuXcducSkOtrEXMK9cNPVpr1oeYSxLLbvH2qXudWxG/ypc1LQvOTsK yNmBuajbg3BAUhJ97RnJHkBu5sEB8WfYSntyTkHZ5SLTeQxKr7VLsAivmCBk/r1pbL/C8RKX i/f/EdNVhAtaL9u7sLHbGCohzZ36VSip0lJlc0Wh1iLlPx7443yo6DD12TZKkt7pBTwT3e5K VmNzW1yZxDwSfBalgw/tmKVXg3VhQLgYZ1R8mB6jLSkMpfNtMzqaSIcqMTSb8DwRbRiJZPg4 yQg3gj97JWFL4CgOn/qi2pMMQoEuoYmm19tPFsjP7LxhO0wW6qyu7TP9a7IyqGiCK/HF8rwR L6Rywe3j0QUUBdBKFmohX9jFVktRJDdrHqcDKtB6F39Su2xZwA8IVUD5C1pPFhr5WDeEOZqB /08a+121BVsMk2hA3JmF6Z6bl//u4zdmoztmmaaC75rZjZVBc+A6XfWVpDV2IIrx65gjpKF1 C6lYbsGRFsxr13TL3WSOeXrlV6qny8naqF9gNKu9oPYphHyiGsavygRp10UlmInaSkRuZzF8 A8EZ3aje4/gEfRVqa80zhUq9Fw1E9OGy0Bh58WuAJ/0p/+zaxoUvXhZKuTaO7SBbSbn5grZM sjq+cHlO8cAdlSGm9ioW2B6LXrGuZpLzjdLp/Vl66OQy2/gwjAtPh8L3QzgijeX7LOW2LXtZ sR0FPVKHerabIcHFx051l+ysseq9ML9aiWmg/LBprO0TMc//3mkV70aurjMwCPmr3QydeQVz aWCk0mdq9VNJEdPMMAEbxeVGf8RI6mMKhSnjg1OhgteAzl2FoNB1OIWzfW0mPjm+VIorWCGq lZEI13yHpcmWC3W/RzwchqQRBBRnqh3nlcxx7O17JGGek2EMePCWZDdpMZh69tdtfvcMPc50 7aR+2IZnT+QxKbke8VSjasoWENhuN+53Pl0VEK3/srzX7OC2oWs8PLVW7Jzau0FkmA9zqAU0 EEpoMQMMxgDwW86O/aDrmbX/8KyY1HMSDzC42q3Vh5sV6jtboUu/Ag36U4YVaOce4lDionC1 varyEqWx6lh9EKXcuHvT7JltrD6yAXQC8Dx228oOVLfvp66OkU/dYQLR5ne658tPqdvwLmTz wsGoQzfLiJ/O4GxB5W5QdBKPbpBlTqx/3/ng1o632COfEcSAHf2DQjza+ydesydbtyN/Sonc sivempMTmWjdZmo5oH4/YcdNqSkHrw62GZy6yyexBDGCqzlMn6ib3CNNKzyZIOukLNKtMh/v m3ROXmT9Ox1gG7m6jEOtJk4Fqf7KJ6b3aZ0bASXSSUisOYF5o0PVZNROpJqiswBpM6Zs2id1 cnay6QRwkUAdVY4epdU8eENCiFhekz5v9kM0ijR84sboZ0EUt+Bj7jFMYWzNXOftjUTFWrA5 zbypdsWjKGuYBEIPBoR16C7FtUCVtE/gLxmDouDgJJgAVoyHyd22obQngVrTnTewlXZTOVO3 Pm+Ekxb3Sywd6FoCpDFiGJycPUtXrtX3ucD6jLdTBTQUv7ogLKlRjgbX+zEQ471KILj96O09 SttClSSS3fHhMfIRfmbLSUhoxy8WYuLN+YgLAfJT6bhszneyp/nJ80HPeMz70I5piYvFaDDo gKGbSdxSmdfvXAzj4c7vxbrm80GWkfw77ZxC9OBVN8WYHIlzWYfROzPt7TAVhRXDFINfuvEX AABajqXWXTnVXSRJFw9euB7cghlVZPRnBTI8mrmqQ7qQ7Lu1uMvC0cuzfZYKoxd9DtgPnG+a Y10TT2tQsuRUlBbfhKpybazGsmPsbIs7Hce6SxQ7D2fMHDl//Z2DvpKfz90fOMmFpJZUgwBk 62laTY8iKDLJDshINCDWSXYl028hbXSkEz3F90Iyf43b4qeSe9ecZJr3CaBZnoPXtiuL3lzB 51VSlJHcICAxBgk3A1xNeW+Gys1tNPzxIS1Y+hDvzybQdXQdcSqDb0nQdyDz/lXz2lFnywvG yo57S5sDu3yZ5w/VT//hEWd5LpAfKPEo5jGNZFGkO1J3R9oHunUOdBImCpOL1dFEwAv/lPCM 9AJAsuPTBA9zV/MFPjBQnZbg6sAE5SZtpA6yz2SYBftxCyZEwTyrSW70ppG77EBcV5WN7xwt TCV7Fgs7eQyNyyp8P4xrPHjg1Wij9VUFgf+KdnmMQ7yxxwOPEJ+bvoYsOJ8iOQUb7iV4CO7U vxVhNJqah9uxlya7TlIVjG/Z+HgnVnbDtXeilQ3dTQVCkc/cAR3hEuZogAondiskWsQOLXnM gFWeO8r46sAxAxR17LY4w1eIwdwoiqeMgVkg37MKXZeEwNPErjY8pXHZKXtSEiXmQkuI554o Z+Od9wrQ1ZfE0ZTpLslFd3R7iiSelRVXxy+w5a7iJRwrdpE1XmxEB2MucWtM81HMl7diBnjp p6l2XUnizcDCiud/xJ+NFuJb1wDiMIMJmWaR8HqnWYfALjEf/w5S/RM3N7rdn3BCxiNHz4Gc ltSIyWtzqDgK3v0rxKJMbxNQLEzd1YETPjOIN87xbdScd+5dUuQTEfX7X/LV4zFjG90th0/F eyDb/7rqIbjIion7MJK5s0P2j6l1sCcqa90PvLvzKwyRY3CRLkUeDCZUQqLAEUd9JmXwS++1 B8A5QgIAeZg2OvaiLHrO4jzSmzBFjP4hmNZJJ+x7phmk8JEzY7glBc+NTeGyCmhHWZdNwS1S jY7SXwkrWyJc5isV3X2pYrg3vf00h/PIqm2A5DluvI+yNmRjajFdCtvnQo4F0//BnXgBlyAe jcL4kW5iQu7jXqBkA98t1HkyZpHvp/FfSG88kjqloLaasfd7LvRwqZhD1KtZZE+pjWq6uxSu pLqQPbSrRKJI4tkUu9X1mRCsfPuFMGFJZKL+oOnYbDIuj2tCRn623uKSDpnIZ72vCCbP5Xfi StaOUNc4VKpoE055k3AHbpVCKPeNj/YWpwdoN/pJxeafInxQO7uLmL0l9jJjGaTjE6IZi+29 +p1Xp92V+NdCUzYlYNErSxWFGRU2l3yvfzEpKpsI7qrygt8rEilU7k1ZJGmJ9RcP3L7HXXiP fIQAajbOpaJWKT/1+yGm0Tzc4itJynmVil3uSxIvFoKrULgPG7BWEGsUqvS4YfY2c/5L/953 ZEsWF3IpIcuTtW0BSxMyj1gkpHR8pQcyCZWqavt8Two7bRludZ3mIv+8aqq0JBcv2LNB5RW9 EczJHrqeG8cZSUPnmY9ZY4RBrY9ovioRKxq1xWKjxKJzDp17zXJJiwoJ2OSDuCWdVTiK2dVw z+goclDxqJ07sVU0VPpb0wLe0Qt3ooqtccxW2uUSxAHRVf4LmLl+2tGGc4KA1nqVuFfgzszK qxFr2wNSNEnS3D7Lxtt+pE2/1IXRjvkxryx43aoat7UbF4mNbyLTEeok/dd9YwYbQuXOKGzo EJJDvdieqoy3iJQoC4etnZQLVevU64igFMuEGYg3XG+aMrrMF+xl++GpK4uzy3lftuhPbUIp BqOp2j4b5aSo7dQD3FfVxecIfZodY8wBgqXACrM65yyb/F8bjlT6ik6aHazSFWqcpxB+o1Xd T1wc3g2pc7B5uU1wgMrpHwSomH8EOsESa5+9epe25qFi1ExgK9HCVi5XiDbWsl+Pvyr+AyU3 Zg0VF83dxRO78QoIldIQdkcdGptRrzLUL7RO0e/PTGucbqUqcOhI/GqC4gAPR5/U7A95otk5 yNPDtGS0PzVaSfOvZxuMjQ2NSjV9O/txTHzwFKrg+h5SewzDd+L924AyGsEMkWxtHpEZo0YX pfgdOUJKQeH/ZPnfY3r6NRval8NBupNizPzycb93i32k1ltqp3KPWi7uughBOssd4pYiEqrv cVy5ZX/qDtl2Xrieku2F5dREm8Uu78GNsasBBH50E5UFpZp4Z54Twp+oMhaZuOnym+eSoKDB uhRuiz2YkTJ+S65XoK8Jt7aRJkirZD0CreqXpjT8AadNukieiPCMXIDHln0FQrwIW/9UWyCw +x7xJACxU3nhxoNdIyI/utCe8pevfeIEvE0hkeBEHMLVclaqPlmWxzRB5qAwzP9mlx3rwlBE VKhVSzTDc2oVT2LK1Lf9mx9pH6k1FE3AqBisBxs/yzqPEfL/ad6nbNdwT1UWGCVVRE27KaHv sPJer8TsSi1LXIH8xUl6p3xlQBOVlab6D9VxGVb6XsCtecQUTAGZElKK4jddxrdFSr+NIyOJ o0nF9HbUjP1D+ALtwS7hjrn0xNPYIYFe6xNA/Q2i/Sp4S5uMTk1Ts/ZwDIvrANoIsHzNNcXh Aug4RBb6S3Mg7xYCcpNKNovgtyyUaR7W4tuqty+l6eB0Hs+cbPchNIk+2X/N94WNYcl9qJ4d MVCrp8aDreVBzg0agrfyJxD7ERTJ5YcUimeUkJzfi7ZLCrSmU5ABrboYvf9sj+7/KTAeUBFz I5MmVm5wiSJ47cRObz06S62bx7+78bzW1c1/EGSVk6wj4KQ40vhNRUCTvRBQhNeIboCj1Ls1 rYA5TXt+B/9GYA1xW0DL2RDQ2hXrzXmee9H6WK+wbYP5g5ux3jFotiPsLeuYoB6uTnHL2mSY Ecq4LlwGoe9RMvKSwd0mtn6Lu5Mrt9Jp7JQ9PahPDJEM99IoppwrM66rBhLsVkonv0nFLY28 TEhyt3Afd39jGc0usVKpfExmRge4aFPr3UwCCZPcutvPD2y7TsWjh2XyBhqixVqh5/Zo/4N0 2TKdRIjnPDN9WI0sxLQbs/1YV5uE/AbLTcxRW37SZL3I+TtvUndhEd16Mn1SoQwiBKHdrYgv yds7iIfBVmiESxC0moE3W/ZCLX/WDP832BBAdcGJ7WjIMhr/YnF4GTzakzV1xVmLTe0sRdxW hwoLkzq0fg7SurRImeKbyYbDtXwmHjhaao3010I69stPmp+8SEhS+X7T8wEDprp4aUjXb4xo 6kLPmq+YpsZZvCwaT077XsvR/ktoD0wSn6jVRG1BcLJpbOKeT8Qdy0GKUgLlcY0t5Fbw5ih+ 2DbYb2Irhye48tj0e/d/mrFntDmJ4NuxY9kB+AtF7pwGH+HpmHQfoSVGhzYG4kFiw4u2DTJJ lmDcZeypHXNT+S+pfzfeDdMk9aT0pvEuAUHWUADUiQTLs9O+yeswcrPW2saLx/Rd1NcXL7VL EwNQ88GhgWhb5q1iKrKA+ynxdlgn/zn/eiaCr6ZQAG9piAwb7zpqBENAB1lDrJWegn3sZEug udIJfgdeqWyTNLVqKOBEQctbzMCKIcqRsyouYOUKnLCA1e1Wz/48At/5sRSZjkeYhlsMT8GT qSKVlm22DYOzKIZl/G0yWfxR7/mDHF6jHNyErJlJ5nDsb6N+4yMLMvdFVmm3RbIX2bZtSeuZ pgUaG4ZAi9MbanrIel5gSgP2Ku6UJMGWClM60uK6EOvayxr5QqrFj7ri4H1fS/NSc4zIYVwN eANFeF6h5ZCcbfm+TA/cshY1f2M3lWnD0yVQi5+yUbhWq92bvMA7B7eCB1GhLODiJk1X6LQ7 C45ItZ+QSiLuNDbbGRTIGn1zaRwRCjsNB/v+WIIQLzL3mC14p+F4U6NqDUgnvrZvZU+dkmWG OxJKZguhRThwLBcAhVvyf26Kdi5rWG7uOv43qWo3lTfzjQx7qV7H43z2zeqI36k1/9T5qlH8 JPKDNqGplENgYiqCvGntAuIYdvfbqn+hWO393TRN3Vr/hYffr7aRx9aF6JUZmqXRSf8H8b9I bQuU77ojE4n8+PKD56mRz00puzQSjqI/PlceHzygUDdvFC7UVr5pcGcAaR6iJ50yh+6DR03H imGRGCNLFx6sZQx2p8A7/+PR+lEO8lDLrwEUDVSLRN2GZE4kktt+lWHAHgN2rGtKyDMBM1ul bdlzQVR7ZAfm5hCbF25L5rx3NSuoCWTLl0lgqKBeW9p+lncgfpJopTJxY9dbKitFV/wexvnL pKhV/H+KOGTXOPkFH/XkWAb1AK+bUotDwG9j68zB0hwRFCGWkZGPVBdQYd395wmE5GFHkbit jR/GrX0tEwHull9eLyYJILpkZ1YLsB93DbZRnTNAD4IMpdai58mgvCy3xiOQ3y18skuHCtcQ /xZ39W0Y5Awhp4w7p1qkkgfDpWvLgQ0TRqCHgx5xxb1RzP2LbLIxl1160zim9g0KS6lStyYH UzgNsed9dUZDgKqGPYHrxTr/Vw7xFE6NXwnPxnCi4mD9M0MSgOPET5Eg9ciMn70Iz11wjoGl tgd8CuJ1MmWgVLV75a8TAWH69jAYBo1mmNjnnatsEplkTjGVclSnd/WNj8x7D21i47EG6OVy rAoAqwxzAyNRJexmrCM3+zzbXvOND/8Pr0gfnkYwr4rgXLqU3S/m4FtSSJNXPXCjLYelxh80 2o2cpUviO0LQGQP/emmyZnWPz934mIQc5FLeCZ3282tLp9hEhAkknE+W/Yb2MJtVQ67nEOR9 C89uFbtPv9wEy6csN3jr/T5oJ9l5TTNk6zgkXGkq3l1k8Zo8MHsgV9U9zdqNTRbW0yeR3JZp KzxPub4AoVhC8sxYowsGj1/25BNPBxuB68BmjF/ysysOaC2FV8OIcfkvuNjGl3sDXoJ2r4EZ dDaLAzAjah/PPGDJnwk1o/O6/CAxfAwLKIkNhNNzss3hOp7NQQosBFs1Tfki47gBJYUVbGnF MBZgSXlR8WU1zH7oDwSwM+USh4UHGAdOu/Q5Hw28J56dLblDvD0T7rHLS7Pc5UCuNEZ3VQYi jnBoZZQ3umAvJsG/ol7PWQg60NxFTUKKphK5OxMLEvaxf786usa+S2L2OsWiVRHp4zJC89fe vJgthEuw8OcmDE48LLfuCe6Ytk+qjCr0VHcdMyxmQQbs6a88LJ+J7vMKWpe9Y6LbjWuOzHlRhKw/ dPOZecYohZA9vTJqAUWQWbCuuJ+19+T3AKbhSQjIJoNIGo50OefYai9eyS+Ae0NGu9eLQysR vIiS9Cfb1Yd6M1m0QO8zKdGc8iA6omwNNKdxjRbuS/SdaLYmaCPkL9wY4AwTp2aLWHHuZ83G JvehjhchIsaL8tyNpWp+DdQdhhjwyiZlqK9YWHG9P4j1yeJ0YgXzXfAraHOY+FAhHTpZuQe1 f0a90jC+6qVpa/KM3ekVZv3J7ydmIoko78DGBi4ReIcsO4oglFlx7XB6JspDlR08pJ9OUxgx kBuWCNCHXLB8haf9Ic57bmN9kGVEae/Dlw8URXqpEZkNs6jJDwFWVghoG8j057X+7vuXJsqS /0+pIQuFXPjaGZppUCRHnr5wNoicWIG0IL5LPs1y1w/bRVRx3d/iczlZu7wksxs4Sxc3Z12v DXK22lU8OLzBWB4gH11gHqIjPAUemOgO8V043wxy5dXyGEkNt39AFe5K/a1p3DO6jzx/4mss 0ovkKvcRHOxNETv/IHPT8IDkoa7hU7wnBEugrSpoj3iHSC+jwbBJFenVJNbeV5FKwugE5SOB eg12sJHxzzVCUQWQXiMvzzNcePrxcciXwAVOrWBtEkMNAZfatqXS95+VBnUYdCOBnTx1wn8L FiI3yYW6W2rXwZGMixACYqCr527ZzEXc9CLqdNuHa88zXYgx4GvjBr+EPhB/7jTJsaAvL9Tn IT5+GMiKLqLmrRUGgpxOb+54nQ80vbZCXFmS/ItdIuiylTLJQ3a/Z5dE3GUOleCHwMhidiku iUvY+lSKKi74Fp3fajua/8tQHdPquIiZd7fmd4cP4hHeaZ4/jQtrMzEI6shP58Nii/6L1uHs t3OkwEYuOqGLdyvF1Kiyw2jKYE/jf2s2p6XwqdaSb6qXIcZCroi/z7lRAXQ/ExGZXXw7AQcU g8zDiMAwTxxdY52iHX5S4MSIfayflfeGBBXO+DV8HEY6BW2rMX2njJQi120DoApjf2dwI/vF mTNFPhDJuGGuALkh+/Au8v+jYaJsQ0e5ERzVQcRX+RGApL8EUBNKXAayHwJYgCxbB2pc7/yY OTDhJchs22Oud0ox3kv9UubBrl0dH0KuewscElFE6BiHOAwpqiJ2sFrygComuzUP+LN5Tz+U B8NT8BJGKFTWeARAB992plWIPZM1Qt0ecIpX550yNXWLM4+6TenUMgjsZhcGHvsqO1X4Hl1r MGwVVGdAVBJIw/5+Wscj3cVolkP6oS7mcZ5AhaTY85SQ2zosb8fBEmFkDYcUlnIasdn4117V DTGkE9ST397qw5pjMki+Iu5bMs0eYGDxyZwxVwvS0IsPt1XKOHJrPoWz/Y7V01NLmPn9F/q7 MojiOQ09kMFpD7X3OdH61rMIZ707e/qEJfPUPFzB75WYmeywHRtN85Zdg0yP30bLaxTjC4oV v3ZK1SbwJ8stu6CrP99wyaYA2bk+ta5XLidbfZR9caItUVtVbddqeZJImYgd2n4Wo4wwSWHQ iEGQYMBjfjigJXyiFpzu9OhCPP/7nTiEXaBsyLYClMSM83espxyTGWjMydlPl5HeEde+gvIR CNYlKb/eRp+zpdFMcWs14lGGQejuodXxINzGC9I6FGfM7hek34KQX5rgVNqhN5jHFYUx7rsw J6jcYumubLSWWExO7JvxCbVe71g0pjdRzO/NosVyirBQRiHI6WchxttNpKA3ET0/r9Q7whba LE2F5NiEJhBC5dbSPG7q+Wm1Qy2fm1EIveRc5Ew4uoj5h/aSRUBX6Oek83C6KINW7we086Rt enWIcsFsB5qDciFsiQqprRvqOLrk4tTnHAGvkTEl8uKDfZJxc8FW6269xOMX+5CVOteY1dqi 3dU8tblCPlYVbv75T5y0zcmGxEiqN7CHuRzXJZ/gFmHXKKCO1Rz1qkdllGM5Wa8E1hsBKuYJ f6Tk8vl4s51CfTDEfWliCaoFIaHTQbx9L64hhFr53YjvgUk9QE7yYsSUJj9Hmp0LviW5haJJ chxHtAFQ4xBa4JrLB9RvQM+tcbMmKjuBOs5M5V1b4Mkq/9p/kCLil/vTEsBl5S6iRauqoswn 5rrtuvgKxHUuEo9yiOlUId0kQAWx8sFVP6rLZry3sLUkxo7hhlShXVPFWoBUVeQzgARhaMns fV1Bj4ycuvc80QnABNrNylw6vVaJPPYVLtY51gsE6JEu6GpRO1qvgaz/fct3FJQyCZWsi/Nj mFbKaFJ1LXeonVkvsOmpsdH4oWo99IjsCAWai/SDxpl61bLGiRw9zR45MItXyvy0K3KR7NNK 9hZnKgNMpIo9+NeqpGMtuVirhCvcyKjL+upE8l1P/rS5sJ4DSqKFKwdngp+IwtUsiGWO0MQm x+NVPg2l6t/n2Z880FUuXbTzgJD3HLNyEbX0ddxqXxIuv87ZyikKjuc4wSyFJ3VwVy7iEBWX aXeUseJ+I0WX5WHleuvTX1Voxz1tlxhayMFJ++ggoKC+uC+aKPinBF+asSxFlJ/W3K8PK3gR 859O7CynXQ+qfPQf/7azbGN6OFe07p0SoeqsDImLxsX37VlG6H4vbOK+kXXvLVqNSMF6ARDw qS4xygbKKh2XI7VoUImLoDROj5unzi5BQLt2kQIQUdQCrQRQdWmPfoVcpAu9PRTHEzHpNZzH kCQIi+NuU3y9UewIiSA7IEZI7x0it/NueUD9mx6KseXyxXQ+0FKsy+1B901qU7mam8b95Xra eoaODxNS3TTjvoadI8nCw+LRV3imqaaX5sGu0YyFLaVidIoHegd/0cNCv2IrNAT3UV8VxcqE mxbTwchdsgznafOM5Qd4iNgTkIPvrzgAdVvySiSl1jwFP23Ligh6s+YC88Vz5I8KSVoBQ317 E0oyWTpTP6rxPt7DzIIH0LbIzPprr4A4vNBNJN4sPudsvBqj2YJWWg/D1hohfJIRIGy9Ds1h tOITR9/Fgus98F/T0X53XkueZYvWcV21KXPUZzyP3gjOheuYnl7x6/9T5qldU4rnL5Npvdwb NUCUESXyyvIEC2wV/2p1/spLQQr5j8LHv4iNYQHvSHTdd9PjkJxxvvNaHHNJuG/G1y6aUNEG 02+6QRoo1ZFE39v2COA+cVaDKW3APsf6Yeo4wF0EPXd50hvkrmMve57D98Q2wgAQtZ4vsSiB FkslAvQKhmCYju+hWfdLzFEecvUszDB4JpW4iYcX5hDh2jjkaumaRxUORoPMxueZVuEAwe61 x5XNIKOofxAE4bya6rdAGDzRnQOtlzt2Yz9+eY5dEE1FLI0LG2lVk2JcLXd1Pueuo42GiSsR AasiaMpgUrm2iRp5KHnB8A74poLhwi4a6tOeL2gk4niWZ8PKHc6+HoRPdHUP7ho22EGI7+vd qjztaPlqlGfHcMP+Csb1Wn+NcSqtS5xh4xqt2TvRcsHP0GcCZbvLRS2eTR1d8HY9VaKtGoOM 1lKEgW3JgUZHbslAKSsCm3PWbB3dXVB7EiF4//MfJc2bqllYHNB9HyvPvYhVuzWrEbJ7YxY1 TkLtgQp13vUtroJK3QNzLKqvQnbV8bTa0T3Bmscj+qYVxLQcQiiZfpOvgU42ZG0KlJoMCBoV h8fUtZt7zmIE8pntgwE2KYiJRHdP5iFgVn84y/cMi2kVFkQ+F6eiIhD6tHOXCieVqEq2iCuZ jkTkuqjNXXtLl/OEFQt99C7+Vs3LIKKnAYWAm5QDHOy34IQ/VPwogFpB9ItH/A4p/aZ9KzhX pM232BruJN41cL8cAYprUqPnP9sFRHRb5Uh2QBMGJwRW/vSK+2tJ6RZ1gfp/DhcAQ53dKk7A suqHgKZ3Yoc16l9bFOjJDzu+3TW1X2FpkFDoULLw1R23gEm5ZzcDH6Vz9cSinpVrshYQNzmJ huzo2K/xmcsyQY5QAR2rOm2du2ybdOvXBmoGRl8QNFR22Gh14BFjmJGormDCT1mSrzj6giX9 Yb1QtPzzcHULL/CPUWlHO5A9anh4ietbtsN7Ni1rgj3Ssa8D4NWdMSQ6lZUDljU7zR6sjo+U ntC0ZIToeaLjWNya8oajo8+Vtm4dCFQVeQlwNgXBqQz81YOcTTViIZqBhQsdKY7Ygf4YzZ3H QT1azYshldTcXZJ9q+PHOKNv579gWtSZWL/K1D9vvBRKugHIhAETXMeKkZq9dBfs0UtaUM/q O+ib9OaGYjvVST7lLguwypbwqAOJHORvB+ycjGeEav06jd/vj1FvHtPP/pQTfb2mvDhBSiI1 W1y481lq9FhCgx4DohRlwXRkJV1trcaSUFRhTjSS8iW+YjdJdYZQ5wrIhTSZSR8MFG+u5Cxq 34+3lCNz2PaRBEmfOfz2kppzxGR4VHiXy5Drt1EPfs5ChYkRXVs+A8v5DSvyMVxqAMvSGRpJ k1wWUjz8wK6/fPh0k/yewkFFKVg3Dz7dJbnpRNX/kuChwdRs6UTxuFInRRpA2bdH/rkSQpbb sp8BUBgk+3SBlp5GL8y+Yo8aJU8TiqpAoy02hI2hSebxjqm1OTppzQU1kLgQhT/LKEO42eWM Nky81tI8zq5N0GDWUz0Hq6K9+MCXKXEZki1NwFf5TwbVB2gnZNW+ZvL8C75ycKKlvkDjhi0z TOi2+UJTVUlbK9JQLFS2zgZy0R5djUuBnXjJpTh6aTr19VfDSsAVurWY85W0FT6AhVyInCo5 5eFQxxmjr+ZPzJj/szmez/WYRl2oMaCOJXx8OlJmpPXEq4I3X7Zzim0MBs8a5wjLBv9Xy1bg FttYl12hC5WBD2Rihy6fbe3ZYFbZPft3UQeg5zlExd2dx/YS3sezUJyyMHNvRZInlkqPI/58 3uHzpE2whKpxxMcsZUUQ9HxcXQbOBmcCoUXeGD5bbQn9eKLrXAcOqXvAFe7AvO8ATDX9tWG9 ppfNKiKrLZX0b4ND/WopRHhBS5dyhdjiPvVP1Pp4c6PiatImKUH9GUt/wQ4QKEbHfJSI5/8E PIsKJyW9T4sz5g5kxdx0+ZjkAcjxGB7b9Eiue44st45XpjbmDwrUPDofouQnCxUZ0NhK+O3q e6zFlFWuu1vKPJ8PjR/p4BWAKDxSkPqX5Nt1U1XX3gZRIb7a0I11QaE+f2Gp+avK2Z30FlrH msb4+2wtG5bril4XzYCIQef/+XlEXOPmwIlExy6fTQ/WsPJLga+oIOAkmW7OWtfLThnFiEbg 40Z2YixSY/dISQUTJy87uM00PVF2Xv27tnDgPLC3KYXvtaojFy0NAbXkiAcBsXO4muzzOxSO kHmtR+s7dqDmAS+k6PEIjq4vKE8JgI6/8UN6ggZwYVO8qUGApjcOQE5PhqeggzXwq1S/uxwy dTWL53zLUHIuCGUEIcEEYLcqwv5Xxe3mLZd+IMMda5sN2MeNfmB8edH1J4pFFw0QuxJRxDqJ ikgJvv07WId/8dbg0HFm1x8tPUEVrdjvqLgEy5SvpgKa1rRL29hn3zE65xBIZp+xfxIDke1w EQVRSAJVOAOGr2qkTkCfrSp/4AV5mbbTMFNiXLxMpmQp3xhlGR02Q7nGfJb/Fbw4WY6OOgwC groMpXugI2V0nyQwU3Ns+AZ6Xut2fxO/DEhAqgq4m3ngrG8p6C+wSO2KdWu7tEc0rFarzVHX kc4RW+idYIs6reexdSi3tXGaWfhr2cI9tBCyPpK0PBL/Arl9AkinofHnD3gYuxehXhLBssf1 40fxmTqYCHPZlP7HMj3xjEuZ0Per2Hv9rw9hZt4PNxXRMUh7kiEee1za9DsCwxDURSQQYJ68 wFH9xGDZqSXaHi9Xy8hLFfOnq3uNvvK5KlJHb8P81FVzqjrzeYYsJ2Qcy7gcVOa4JzkvbT7x i2IC4HNeGHgBReMMfbpyq3OfPQ55WCj4JG2Arvtg+I5C9gPhxZxUqGU1MV80LQQd7k5dSX2t lnDhuPjr3svucupjuS6SRM3ObyN4VM64u3AmiSO3tuFp0VpfUDvwxvIgTuAoWBPSzSuxOxel lIAJzcTyzX+OLZ0sxNMnrghxUs0NK7ciO7k16lD12xQ2emCWsGLg+geK4LrCeLGXVKMlQYee vZvdA5fCyUNjViTPwmnmWqIgQ+A+hwRezcFDju7fAEEz+mJXopW3vsbYIJwHXjLi4CIA4m60 n3wL+xr1PpNuLAKH5BkF6hJ1SzJQwnpwR7s3Jh+14/2V0NsSZwwaqtU2GpZV+5pBBCgWu14I Yz25fBL11Qfs8VMkmVWnlMCqnW1pTfntI/QC+hBq1HfpnOX4qFzPdBkHhZ6PamAvspqi02DA gnYWjIZE4zO77++ExAn/sQ3kAlyhzopNf1O1unb57O/MKoHMdE0/UCMcbyJs6J+/a3+L3ny6 G/3zMIe/i8NJcHaCO9r+itN+dHknHjGNbwS5WlSfm537cY1RCTDK4Zc0hf1V2aBFCvjw5xix LSx8L1TsyDgDSpyYyqjQInGkeqEdhcIu7dX4c8BZnMVjJd4kYvewvbWDt2+7nL/PVNc3Wyff BmN0sUH9GoQtkhJAPZv7AvVNBwsJK0b00bfRCQ/yGISiOQqVJ9jd4A4GOYClllC5RX4jiRny R5U+XZDsCeS9zFJj/B2zQXWX2ugJ/NS1eCdpXHz1A0Fx3IUWL5mywCN4hHK3aBqg+8JYjqPB 2qUdgHnQvrLC8Hf7wjMLcmnaTrIB5oYUIbcfoc39sh5V+ftPemwlzVeVD/MN+zzuITpvjE5A 30Py7heieZd79jyz50oAQ5cKPDrAWrYbG0z1RetrXTQEX7x6ejkjPUL/DIwl3AZodSJuL3mo 2NH9MtcKfX2l0c2k3lTl4R+JOwiYNlg//1WFD9bfVLmSvETdtZKyJO3f0o4tZWhOzG7fY2or v7xy5RT9Fd4mqim8VgKZd1Hb6gHFYryh4R7BBfpQTdQGUKH86w2CwIDoo8MXjaZ8God6wyia v06DgxISZVmQBsZbJ0N5DUDlqA+E831Mo7KWJwLEgL30TNk/MvXv1+HopJswX7jZlBi0pcVf CrTQYNeJz0WKwEMskve+Gant7grMW7T7bcHcUd2NSo/DT4qOZdXiYW0H3v5Z9+n/ve1o7JjE lb677FEHD2EGT3UIq5xqC+FcLiB9LKKj0Mr7UNbrGruH2VNvY1eOLMtI7qA2BDnwvKf7TXoN CcdPLFUp61rSV4ZKqLE98daXlxDjO4tDEAC99Mjqb13O6Vg60XcS/km7o/v0J4jstGlbzw7+ oV1s6bhhOjXfnHXfc61X8ZSlL8C1yAT7jvMmH1Fbku6i/M9lvOlVSwfh6xiUmzwIqBbP9jDj vQ/WQYfG5enQwUYx/ct68JQKfdWHd58+QcclIWdi5siVM04exSGQAwbFDJHOGMDpUbE8uQpc b9CNOlyhdvKrwxwocFNbpREVJIaavBjs+IMMNZpVlAJdK/GuJqcTTR7oSZCEP+ghp5gEMmXI R3tWH3tJGAaNJ1U9YCWSEZnCriUF9T59DDCcQtTekhjnVdUons+6MhrYknLeeFwq/4aM8iKA M6GF7Ef9KG0/pVum9utzPG50NFOg6oSHG7NqIrSooxbKZ0WJXjOOTYtZmpVNzLMxNLVTLzLL MGBeaz0LzY9tj+yN9FIc0LJnVwWuFn/HClzg7pmQtJfRREhqyIGrwzHZFPAg9Ye3LNwulePC iRwfT3HKa2KnhNgdSYo4TKTQIEOpLc0lDTWrFl7Eqroqnb1C50yIMUoQfiHOmAZOjHu/9FbF SVtcP4l3rFpyPcocz9Sul1dyXyCPxXf6t5BYNmFFf8YjcF0g/BMX9kjOiqQvnD2kkTPxja9w Apz+P8rL3kSTVTCdv4i2RkyFAK9SvCqqXyTbw4BV1leeMnXxlaXIKLHR8m9sXnwgWNTDSs9Y rfjRpn1AJ095pKhRcPLMI4cwqRmsYHWZHvUjYlRgcViDsKK5yelaw/zr3YjmDuEc5Lm7ZB9G IGk6u2BjmLukYxwGJOzwd3xi8omwjVe3TI4WIspVgW/Us4G4vh3281AZPGl4CRGGZEID3nyQ V165D1pQGraLhK7aPy63wkBUHozXjXoxif0cQ0IuVTK3rsFHQbnM8agbDcLcdBaV1LZZslKe qcmGkPoWU6QniDksNE8qLCyfHT4i+B5PBSzdOAa+MFnj4JN4e9kjZDe6yXFXLBN7el/4InTp wIumHGXVfJlVjqucK0TZcV47fZnEnMxhQdHbmM6chaJSedj57F2mqWFo5Piak9SYQLWToDCI /X9cm2vpnsEKoljj5jJTTZZwP2aexFjevPI0hybPjr7STx48YgEtLIfWt70SH3290l/voCVP cQk901uAcK5HVtx0TK13gICwoFa5BlxJlJECo671/tnpL/wGlaHUai93y8DffI7SCYyM8GBY YEdfd4FW4WYzKqQSfXB8C2El9BWTBkL6W1B+ZHFUe9kpZYdOON6Qi3cC3TbrWAbd34il0I8z +KV2g1DV+GefXv0PwxHFxrr9TuFSkCB+ochb4IZryplpsB0ljowpfJ8E9EmCuhPOfjrSSnWP f2mj9c5B0uSU03re+48RQNTZXOstY8y0Wwnl0+xKNSvbdP1DBsw0tZK6V2teBLXcQNCFA6jX 9JaRXM6fsTS9bHqKPAgjC5Di6NouHtDd7C58DRy5hGLfN5+hU7m2sFPNlUmqyix0ah243mgl NJObFHsFwxw174yIDUYdZfv/vMOBnarjZITy0XgJZ3yRBqzf8Uo2GNkVNY7eCW1SbTY1x8U2 WpewW2Ob2XgMSLZ4bKo7QJveBHmEsbVTRB35qQBeD2JI2E+Ly/MRyWGcA+DWK8M59BrBx4Wx 09WJ0BvDgGMvkRFpK7MLYxxIDnZvN+6sGCBtr9gZYjvyM4Fd4Dq+v0KA0CEjSdi2f4i1Vtq+ +O4HFEkG2VHt97JKeSuYG2ZbW/EyDqrvIZYghPE2S1vNfXULcJwy/BlKFsMBZcaZHzx624L+ Rv7OrD2P3FydN7B0Q1T9uSvLqEnV1YVTuIXeejfO8hvkyPbmXvSQjzgbVBqRn+zmxN3NwWUZ 1GWLmWaHrA0mogBGdEeDITOJ9hwQCVGZdi6w7BYqDI3CXOu4tZrJngje8LsVKiDNccx1wMbZ TxsVNpfjUHfWRPQHyNhVl838ArkzMFs5ppu0ioZo4Y/NirXn2NsyBm1M6FBQAOxbm6QcRWl6 P4FctY+yqlfbhuRaaVMKh3HOysUvXn/NPCsxwz0XbP40CmiX36I17af8WHatbEM+3Ax+Yhvx jSSmganVi1PUL62tPXv5Wx1yKxZK7HTmbPXhqm0cK6PcnQUrsSO4UGvqQbRL94zGpcF2kpAB hGQL+vVLTBv3xq/a4B2BsN0mhdFE2Ef+0RGRzK3z++yrPEDQGAiAoVmmiZ1nd6yOuQcTA2B9 d4BIeSPdCSWBaX4UQIYeIVSHHUAYFmSHyuke9b7oW48BGA5Mkc4zHlXFU+6kQ4X/GEKR1Xuq KYr07vO1kCrJjL5QVdsyPPTdbvlYHPANwBgAcSZ6GfPBlEG4xChrcKtNNHEre/qv2UnQfY27 q5ZQY9l7DQD6THVbJ6+i4xe9zAy8EbBkhd4gI11hOyOUGcC8KRc6ORFWYCEYNULevpKPyUJu sNYKgHZTKCQ81Xq0BX4YFVR07O+7kvcp7hG61Oyg1nPBPEgHyp81wL8bkX1K8f0luorTe00z AjduqgAvneFK45awPfWOK9e5NtkpB1G0EAbYFd3oRp4ZwgE5hK6fLcFpuRBnvx7g7t1zipI4 GKVO/zTK8qJJe6ZocyzfVg/74hTxNle8aK0QtoBdx9msyngZ2GFLAGZxGmdqcE8Q2FJaz0NT MXiBKrryc7lGwxcWxalEK9HVDge93DJ1iJZvpBLNfDlTQ1Jrfmui7/jah6qC3cqf4EDqnS/z 4qYnv2bF8U3f5ZGt33rKHTcN845FdlWC8QZOCP9w1piQbMbDzvDPh+0hqUjop4pBqC7vT+Jn 525rP2V3rGt6ZvrKwfSNXPNQGxE7IwiYTGZpiBo5YcVkjc17mmCUGddaxCbvOYVGKOcBOR4R QFZLgORfbAdog76I099X5dauqMUgH87RjJnUNs2MSUct5wJW1z7cBkdlnSO2HAhxPBkfWbmX VROdkPoR4SQGBWHo8WzkPfPuakugEDl4YNCPrF4KeqF882QIugxwh6vMNYlMbdS1CTZUJOxK HKdz/2IMx0llIKtqkhNtBys1fMr+QlWIlNFUGLFptbKPssKHU5TUhhv7foBe41rzDZiLeNhC xcERZElMZEKgjI03vos/0i1S4GqmG/DTo4AeJ/VabcmhoFR7JZpj3DOzWdpAa3H6jwv2JGZ+ JkIFRdcq4lAf6RYPe16uv8ei2krhXQ3zFZUDVugg4NYncEO6Pf+oBXWTOiJv1uy+mye5C5xK rwtiba/teU6zn1gmO1FUuiHB0FvhmTHoD2G/TLYfKHg/IoZFfa/yiFFzdyMZWXmfVXd8gnj1 4+KS21jgxBmG1kcRnDUAS5VfRMGLPss9Jra7aR6FJtoTNEssb7DBhSU8qBSZYKJ28dX/HFpJ kuzWdyJ5In3TQksRUT5pu+nVn7jS4XQyh4gu0ijxOLu1iQWsWo9JJ15VJ1Dhft8M7mSRHNOm 5xnAG8o8Wj6bO6qP3muPkcAzG1z0PyS4FuJOWyVtHLWcgqj8Lfb2R1vE/IpyfnjYEi1FAT70 QzLqVoL/JClAI15F+81vwO0HT+hh9Za5CBZZc+vmM8Y3b7aUq0WRTnZt8DvhcLsw2kG/H7AK OKJr0KJ0IY66pekYNBBvNpF3zH34tmDvd8iWkz5jTIxGe3UezbDHgO9KYL1vbdwUJwg6doLT nkzaSrk0ljJMDMdXjC6fz21wI9PM00sEo7+h29DtGKHIOANo2R/mitm7mdviTwz2JGCpttWw F8Zkurg3HKjH2wzU4dxASXUawi7wCAak2trExtnZwQxxffOnYt2OHGjOWRJWvXapOnDQlYF8 E2Hg442KQhHuiQRDKwvgLbzbMZywRCnMRDcn17qjBZw98B7gqcM7O+oA3PoMcUASxMzwnzc0 yQUKhi+DVMwd+3wbT4SW7wzokdsMAfAAYDAp8TtPhzHwkBBQm6GTAycmFJ+sZ4Z4ANNquOZg Sm7GLTWD6pjRyI+36TL5NUpFQ0/G49tEu1yYk0nOET9bdOKNiqO1hLqO2Vb/rNeK5LMevUN/ sf3c/Bs2gpCU2An+16bBsQRP/9tTJzlTODC3jZlXaYnVjA9ctvL/48p81bL/ZC1AKMDqRijD xGLyT1aTXfIz32LZQM6wiBY/i6wf8r73Rglpy7vJb8P3T5qEFJyB7Xg9DBsV9AEVOxNSQgEI I2P619dt7iTdDk+w/Lw2c48H29zd166eSGInLsYJdVg9WOD1NdNdUuUfixrY4+lcPxExruwt DlYnJwpgbl+frm91b5t0ZIJlmr/Mc+TtGzV0DiRKh7bKo7NiQQv1NfEwnVtuh2A43Tq4sfb+ djR0uT/58H+ThuytKCR2y7ooOXdr+QNOlGtRJIfCWCu6sPvZRucrsDtgESbljr5SJiVSgYsk EfBnPUPWSGgkznja3CrM2fFyuc16NUm5TYDvqShMsc0l9nS/+Jf05hV37p7IhTGTWYtQT5W1 F6UzxSRYptrVKCs4yTtOhGvdXdhq9Nh79MBuGFhACHn5YDqHYum/3syrAgWPZEhW9BdJlGZc vlhNbX8BnE9LfjJFjcj/DWDkZtaZkLGWirLZFnIRUBH4Cg6GMBOXh5TcNgQe3vuUTeubOrGM CAfXuGM0E7jVOOSe5RQwoqk9EL7c4A7dKAx7rVqibYDII6QqCpJVZOomLjMKUDuHHZkaS6en MvVhg+PQqBjEirdBzKd0lyXGvwDl/JayQxRIv5DP82wX73Org4FJiLZ+AxnsBp+fXwy8Iqsg aJFgOc4Z6B09GejOw8Xcg8o1CWHJz5/lvgxcAEIjqA7u3JhnY3+Wzgw692vKWxHVKomP8A3s pL9RdxqkWX9mwqh0YDhd3fZ5ZCzruLanPy/ItcQ2QhSYhFBpxvzbwIURx9OA+6x7jT74zx50 GXdmGuqmxMjAIHCL4mfLxw4iW06FxNZa2Fgi3JTrLKjd3TQ/7JyA9RvLYg7axjtJJ+NMeglj A1YI5mP8/E3uN1GgvmMxFbeNUS4Xkjx0EhUimnQWMORI4SAujssJsm/FuHYKrEzGgu1zs+UA Vcmb11uZiMIhsdbMlTaj801UeDGl7wtK2C1JNNRjcAL5tfE2sWsQmx6Z6kOqAGz0Kkm87wE1 RsFSd84KcvK8jkr05VBfKB9ASltr4SooeC1DFqVXHblm00vUnv1hk/CowxQlt9qrXui7ku3n XqqyNrjgr7HQHzk3F6Abg06Eg+1fDxupSGGAWesx/YNUN6JELc6aA1FGr1o7fFXf62jq/1da GkzBOzQaNX0vRFESPL88MZnJkSF7ggZE4WOaPoewHjvhaa8x5699OJYPkBiwZR+Kf8PVH2ga KNEla20h5kG8FssciHGzJpPql8O+F0mS4ve3gDYwjBut6On65ZP4rvF8ydxQ18DpHOsZ2lxt EcFcneBNAgC2IeWomciyk8pjjEArEG4C4VnbLERlCqAlPfANBYYruyrfERiIzTzB3DzPhUZt 50rXFqqJfMLYz+sGMAtwqS+LkY4UbASbP+8KogiGnl5Qqtx60koIHPlvCueR+HyXOvQ+CGgT WtrHVbuCRA5FIq6vvD6nxGjpCIa5uXd2JxD99DXE1AH1+z0xEWOzlktFqhCyBQFkkgDccm4L HjYLPOUlKx1m9x0NMhVs2LZBfSMHl4k2/E94HqZ8pSqKgncQ59rr58+jft2VKNdBZEPQZznw hHtOBvmXqKV+PgMOW1ZCDUc1T5V5Ebq543yTEPgm3fcnDR5bXYD3UeouPqILzA9hYdahY+qN bMwrdBzdbtHSfD+KCFAWzud2023fFiF4VDxO1rmC3pbveSJLgJif4LOEKko0U9Sd/gfJObdk bfaTKekfYb2T+yxJthHwUzttvg5Wg0TiYcufdUlyzBpuqsbkZRfkg0oMq2olMlAOX4o/25NK ZagEDjMyBu4FfaZ2MD1lh/yPNp/C8Q6Ni5Py5Pyex8bziTr4PpivM+eIqSVdJ1DSRHQ5+CKN pHdK25vToOZ0o6Hv6ZAHsTFMlN4Y+5rKx86bKMJ+hUEbNWf+esmmLiByOmhwArzK6RFaJ3Tk BpGL4su1HjLX3lj5oIIO01WCGMmUYFyaWrhDPW8e/B3DIJNa+kwNGL/0QSy5DV9JTgy68RLJ G2TG4m9FpN13D49LUtHvbjqW32szbtdOjZBplTWf1nwMm4zFiU6iCSZQDzb+zzzGIT9loIf+ Dc8Z0yni/zrBArlaEKqaX2DkRR0ljxiZuq0CXM2VQdpY8qH44Sti58QoHNkNGuj4o+lQhNN7 5vx3Ih1e1F8Duf4q0FzjQA+zGgjLwyzU7a4d1RMfVo+VV6ktqqgqCTVWy9UkbZBL6JzLCF2g dch41UYIiuaCo1KucbrC+GcdF+AOGexhtaEYmUkbuKMuqr2in/P5rXnXNqyKWCGYQBVNlxzp /ammyjulc45AAvGJ2SmIq0/tkJlYc0a4AJvl0gHKvh8kG0QmbARnvoxwd8Gj2Izx+vgFScr4 VlOtng+Ze8IwAbF2jd2sichFkqVgrYqx1suS0aP6/uDwJY6GaqOvMwh4Zkm/Q1l4vs5ycPUY 7fD94i8KZ+F9h32d/6Kf08tSkSEkp5Z+8G2Msm6z3xCVi6foFa+B4US+MfDUGw1FUaxfqLev HK5AuISy/SXsNuHYsscoalEfZZuTo42WgD5YugdHi/4QHxM8i0yQsbqeXf7HvFWxsnmQwxwL eZfsQKSYyUkv0yCKSLlIVduxK3/vuvmxp8WWzxSpGylUN33Lo65/eafxGHBSQju4ypLWUQa3 9wtwddQ1oAiRTlRO02AUvvUTXuD7c/kwVSfNBP3rj0+syyv8PGY3BPNoxsRDpn2u9pLYmr4U AI3adaU6r5JpRCwP/ITSSkipygHlsAsLZ0bfBw999xVIEu+ApwNGzBT+xaFuBZXs5WiV96IF w6WmL1s/fzHaV2B6RV1AczAB+iKLwkkTZoZO2bqdwnyp2MLZh+PF/ajvHnqgIdfY4jNdzyVt jj0SVQfb+n3pvx7NkLIt6mwR8K14g1LXPWK/kpcYmd0Qxijmp0FPGK2RP6UfIa+KCVncSxkz 25TGKeHTtgi9m3DOunzjN8nvlycTnG1hJ72iNeDyVWXLsvNY+xj6bcthy0c8j5+k//5abmup nDMAlwsPP0cNl3lV7jt+w3F7fNS4x9FJ5vPvk0Do508rs+oW+bZb5acx/9oDVTXg6yxYK5ZU s71kxeDqZvtM4zakE77QlPJNxrrVqGApLNlDsxjoOzSD76Rtsa3anEThzn1MpAkhKUxwU/Wi ph5Piwrv6W1rvRHFWcIbV2U1Bss+lOOBMhH6KvWmhIId3yML3i6AIqHwHxu425WDwPAms4o0 oJGKom47Bd0i9l9OIpH+s8khWezdamN31JhqZBwN1UaSKAcKP6YrXNRdAjwbhPIMg3UfTPux RSJVnU8ohnVD9w4bEUnyily6mb+B2JRKXPyL+cUa1hg6ejcjBFnVkYDfhRpCGUJC+zAUlwzP 2s+scgx5xLAhirX3T+qhYcrJbOIUStl09owNijXKMHKkpKgjM/n7/zzG9ELs2zM7Occyz3kL UuVLsJc/uMk/kM55mnDdwa6tIOn/q/ucSQeW3Rgzgi5GcDz4BPdtE/YObdCSDZ1hekKTB88V rKBTTSf/yHit50F3B0gCylq/nIZa2lJJ8mt0h8jivHQa1xBupPpvw1n8wcMpiTAJn4SWreOo KK+YlzyhRsKemTNQ4IpE8XG2FG3WkKbGTiWzN3/M0dtfopCNip+JtgH5zPxVFHhZMtuq6K5M fq+QSp6kICzjLnbEFbebTxI2PehAQq2DcYSEEW2m0q6v1JZ0w0Gl8XJc3ZMKob5RhILePx5I UI2AMlBB6L9gj3fo8NXl/1l3tQq1fmMdhMJcyFMitFV2lm8npSfU0rE/KDlDl9OplV2A+voS REDW26cyDjADnTR0an4W098nMuYgRjmleuSzzzSD7pOdoKZoLOP5qqRBBWM8QxC9utWR72tB 0pPcZAyZMjPF447uyPRYJxLjorLnqcG7slv3Xl9uVl3dsNSDvH53toBPIt2pDj0VfPICFHh4 zHbJaefJzA25b/J9+1wsyCOrA5ORxrtqsvB+6lxNdkQ1Sbwtgw88yJX17fjAqH7Q7vKHD1Z9 tFmrNxfA/MSQdfpNB02EXdezT8mFeRpGvmv+Q2/XO8kvEXB26sbkljYp9D9ZrUSv5dP0l6T6 qdbEEGRWSD6QOi3RZbIRrgjFyA6cpGMKOPBi3Cv3xjeNgv9686V/JERiMAkWVNb0cY25kO5O nu6dMHg9bI8o7Z164wggPCQWcVviZj1F7euovU5OPS/DNUzOSfY1+84i+zd109NhAGSHRDuq hkK3oKLBfuysVRboIeNzh20UneTNFxrXtHFLLs2YpGkbXU+vtRDD7EuXh2wudSbFokd3KX1G tTpxqHTbQJWPQtoOnbLrGj6giOeA1cVDJb7zIfcOCRDxQpQ0Il6Oypuq+3fyXeO0ZNofAQ4g 8Zx495MQCntCwTWI1b93PPZe2Siq2LdFwx5x5oayBkfEv8OHCGR4ckx6IXo9VJpimA3QaV7y UeIF+xhOwxWuuaPhDMPYHk9ytmpnvxmWfnMBPZyFcbG+8grr0xwSi8/LkuyKGFWc7Q/OhvrB a91XOcAfwLNMbQBp7xuGrBpq77/1qGzrU1mq9Qr+Q+2aRuTy7MqwaNhSyIo+V7nWDBfNsjFu sWFJWJtf4YrMEbW4K1ZNVthhGFA86ACRMBmUVTbe2F8QS5sjrW9FnupDQBaRMTxzKDfL4HYJ TvRtVLuKdXOL6jwrzfPlWN8K7uYJi4vR7Eq8ZIrWn38T0aDtT9eoy1Qu0kgfiyzvUbiRDUtf fpAOgU0/9cWQumHCicmZ1dC3uZwzn4OzyAXfHlkpLxGMgQ6WrbTxK5Ewny8Vh56nFmXNvb9j 9I3TLdmOTApH1scQJsn4QQbu4IiSS11P1jMD979HNmhL303D768qlv+ofHe1A4kMWaxCbkx3 4JiWZcElqFsHN2PPssBLkdKK3SjbZy5Kj3/7/CGr8u5gcJe5qDZXywuwBVeUXnt20ON17tdk kf7M8v+4JqZWNBQ5SfABgiSjeFYgzOd8MhAOx5WeX9PJiiT5s1Wod95eiHO84zhXpkhg489o TXNqsTBR/vlb33SiZ6imdEfs92xNg9IWUsq1lFdbpxG9UQzZ5GLxOWH0hGENirgMThGih1Xg ZSLfzEeFB2xWVS03O2cSFqDrwwdvRjxo7pX+lKpIHkoMeYpBky7CWAR0E3/RE2meFeQ4cI8R OM+RVJ1SD++z7wrZp+W1cwFLsKRo8pKcbDaz0Znmbk0zaIlBUQUmFd6BaQC1AFtm/I/Z5N+0 D6MNK9Dj+TiVdXSduTL+i6vAod69u0t0ECvYpdytPQCE2A53rqN83JySzX8OvUSoA3iXrBG+ dbtD+ep9EY6CqOxHDCR8wZz7vlpjoRAOyRsOF4+Jmv+YspoOLRCEIGOxRdqbqt58+2d6/3Uy jPQIQUJ0P9yFHBqwRNuhSJUf6aX6tglsNdA4RyH32CbcCYUmmVDcvBbRYa9UVfa/5VImHGiR U/B6W9hQLLVgKUJTxwjXl281K6PMXiZ4Nu6hU0rqP8rh8M8Gt0EoS2/TXVSohqhi7+XswdOm DxCA4Yyh3Z9XNR582EhUs+rochIPLOK/c3gJL0ZsFmZ0wZ0utacfC1Z2E+E9++pdunLAHlS+ LwnugZsWlGHWk4u4cnynthHxIAv7LXggepGISvZbkkOpbCDjCh82my89QeyEfUdpdtSXOcFo wMpjBKOB3GVef0zoLvvQLoERYz9WfjaWedfYGK5+SlRNt3KzNX3ZAFORHU41WZ685xoLgKH5 oWitQ00UNuDtIYmMsawEUoSw5DYuv/YCpyDvSOiOjnjWvG2jiTpNaQJH1SutQs5v4jvGlTFX a429A0JLQgWnijpNHNHaKYeMsexNGVdhle46SlP/tQjOmoj6tSJh1X7tgz5jggJ/s8I9xXw3 NlLhFO26NkqV7Z9ErI1CSJ8PesTrp/Y+tpnAUXoKtm5kkM+Y9cksN18GCv8FKNgPeHThtIJo gJFsVQMs8Mee6Xw1axPcufHYVP+Nvh8fSwVfOfRFACsMPbmc4UVS0nu68PR4mOLY73YK3NjM fzoYZu/LIpYarQzY1d4zhfZRYAvp+rPl2LI/oezKlCg2Hli937amh460CDgZj6CEPzBZxJRN G70hv1YWM0abdIA02NUT1vwZbHP+yuW/qVOQc5nN33V7JPTPvDkARuMCZ6R+Qb4r65TpHeFj xONW0MPHqUrj88apzEsbk5JBuDrSpDRUCFOfII60+Qgn5HDQuHRsIpAPhr+qlMSnpBlkC/Hh j89bpq5pJFkQVHw6ftscOGXD9TBURvA11f5qruON5mIYFP8/zFhGsgP2VTPuERez4VgpFkb3 nH9Ink6Wifug8LJfCTRbO+PdiCAa69Jb8SvX3I3laE0vvSZU9/l/uE5V1VCRCU4aNAm+WT11 kJri8hxjTElypPP5RJI1h+r151zZba5oYRJ9QIMcFTlMm5hq5HqElqj9h6XKEhGXFBxdMl6P pLZwosqNDlqkUzgzD4+IRqI+xtmxy0oxyqW0BA9J5NyXWt1ZDylsuJjUXv1NDmNSxC81yVSR 2V44hil1yMP+fnHU2xhw2Z23UOBQY9kN1lthpWPCu3IJeKcJKQ8LHxF6Aiaft2uQQNvogHab VhaW/iHLtd6V2lYM2rkujg+3YjHEpTM/TDE7NemYkb2RNRhneTnYXOL7aqL7B4e4zXneRhMS yEi0rb6ItKtjNZ2YKP21gS5ry7eXnZ7PFKgU5PiCt7OWaHQVO47gF8RimSMDmK+WnKT4deBi 2xKH3kOjL18R0aCFyAUp0+iIwcTJzpf8LG7YaXXyC1+MEyyH/iWl0jx+VZ16V0GGbntOv/wY dfGNNULtuH4s7IZTwFe3QhDJq32TKpWy+NJE4PidGg+xjP1PocN+zNSA0jkQjXu/tN1EAKu4 ZSuaV4SZF2GN619pNa6rDj7vA42Qab9MGJOPGKe8v8Pn6bBXIaYW5kbVwiKWkeR0oWFktv/f W11qEZ2iW5Ey4n2FTL24u3kWsApwhyUqjgVwq7yDeuVmzxZkno3q9V33tUd4DDVjegybcYEN F+n9qI8ri0gh6mB4dRgDrc/A0YbzigFA/7SnYFtBkzOMdkQUbUOXNSpJRK/UNhY1BZ8IjnC9 vl6tgCUB0MwgfI2Hoq6PjPoeNxqi3FiGJlQJD4M8aNq8Oe1d60NHQPNA5F41TrPYQmLC3Soa j0fxqKDxmCMGeQB8x+VYEXrJAoFx/AUIQMXDWxxdaeN8IzRY+p51kXBti6fppq9NN0H3j9/0 cPIB2mfMCYMpcSvcLmsdTJLOtYDE/Y9dgVH15jWCprFYNdkv7DBwzpDvsECgCioezDMqmvMV NhF8iLYQ24oE3JXtr2lqJXqiJAuFW8ycVMDPXQbK1T7ZGF2vI9JPIR0vZhZeLi30pblmJVmz MaToe70Vr3G9UMdHbBIopU3L4GPYSa/irEh8IPiRSOA2+Jp3RyxdGyF2s9BA3etg418CcO4n gKSTgaIeWVDmyvxkNDKRDtE2YnHEgH0V8KOLNUWIY6vcdOa7hRS6hG4sPfoC0xm974uS8F22 HjFuxDxPHUq9nZYM6ecRZQoWT6jWCHifocR3Nwjz0U7Z/VpSOYHn2j2wu7SOEVtTbNQk5L+r d5xWZN4ao2TKWK++pejwHlJQrjyu1Z6qGcH4EBwitgEhNmGetZqnYWuj5IeQO4QXEQ+YdXnb FMIYnmY3DAhhh4aeC8F01uPj7qMABQ7LsQTtgbvtqGvEYVCWdsLv7HCfTzQqG0G+hhh1ld9H zv95IQ5vrHT8BnCzorDxRWxqNw9DbhBRkKBTxlFgat5jS1SLHeh0ZTNJWQKGEPewNCfMDD/L vlYkVJJCCR/FtyWucN5KqSZofCrjWGcJTFCUh289Bl2adtCFwPceNgVZ0G9sey+AacQ6/IMI dQ44kH+EtAOqQRdNUL+xAnNWO6fp6rwtfI7CECnw0iKxOXFiVWHHUbTVXibjvhamhuZPcZS0 FbxTv6cToTfeRfKgSkyOw9Dqm+jy2b9LpVaWiI7qYD0Ki1lWXnd6fELYzoimyH/iVAazOHL5 kFM11rHtANeL6I9HSZl8LZkhBK4I3XMmVfTKrQ5zCUPWCsEsrBcT3/c/kTDxMRhXLPUXP9e8 g6d7lDZjoHDMGcqWrhGkHnZp8fH3fo1dSrXYR5aMzg33E6082JTdOGHQaIATptMfUOPnLlMR JB/2nHwctb/VkQjyv3PjbMjHMRvlFpCSiz1oZa9d7WHwfeI/zxQx54cvN2s44xQkadqD/Q3/ hrmlbdq8h8REUy8xafiqePyyoVKKhZdZa+uFiVLqkYW9HS5C7MplnP8YYEX3froRfH9/07PO 0yLALQkZWJyqXu7Fz6ypa+2FrbhtKx8l+56GVrNzXjXAbM0igdXC9SNF92esZO2d4Vbnq78T fp3YtnWmgSTt0dhUTwRPYCkwZhQB8OBNf5emIZmJmdiAWbqYn/j4jJ5SIYCSVjrJSxWFnM58 7xmfIhf3crUzKFEQ35DeqbhAAPIrps8KczVCu8RxaXSXau349y+uo4tzdWD8mOqdHJ8tjoYZ SYqagCRo2WSSO07uCy6MW42zmMm8Rcbft2IzcM2v8iVIrTDYzVPdjr3ETHEe4AY4kYUcmzAc u3HtyS6U25pvUUzzmSzHqnhWV/ly1yAkJFVPMuzUV3tdMgMOHnqlpFAdNZBAgB4NHyum4kGL 4yvrnwV9RIwift7iXp9oFHq6h+hH+f1/gSqwM2r8fBsDd5TtuT/meMe81Rb07eQwWTKW//fK p3lQuiGyL1AaONLlJEs3iWAlh1zPsyaIaXW1BpQjfzIDqE4e67GaxnUt/BLOqn2qu+AFPwPu ORCr2EDuum78vqzR+2VqNzGQ6q1ux6jqD/FEWkqLyQpsHWskt1lY9+fNOMQZrOGyIGDCZRyc yjFkPgLLFTlKcGkPNnUHVXNpaYkjdHFiXjS8q0Vg2tjdNum/ciquGjNhAlFBKBoawSSrQ2Pa CnvAqrLghjkQ2uzYIju7Ut8DtF0dlKxStfsq3b3yOy9zCiM3MoDixB8JvP9UcyAuweEz/smf mjhwGQjt00jmFpb/x23pTqwYDBgHYeMfFOvJY171nbrn54xhm6LlUfG8RYBCHif+F3Xx/03K X9R2pSlbO+g7yrt/2qECI3QIgPPFSewQSMMTAuA/ITn7KUChWAmt4RTFigA6EDDDm/Qajji5 oCu7baCjU2bux2Umm/NUgiNEFWsQ4mcB6HI8IgT2pBAdKwlZ909f4PDERQ9C+bXtwB7b53O2 fGimML2YiDx8gqpBHgOxoXbGU6+8yniRR4KJiLLgWI+FXuU3TFgSTSB6pJ8MJsvHFDSN1/KU 2Gcaxj2TXjH8MOxMBjyyo1Cvi8HZTpX0oagnHtIqXXjVAo6WfrYvyyI1193QWfzlzgiFV9hI xDvJuHCh7i6G/pbfenPBh/31NPE5Q+N/0mMqDzhnuS8OrE5fuojuXRfIVyjYY8segdx4CCR+ +SpZgtA+54wnyc0VyFLoC9QwijIp4g4Mjif9L2xzZDUNJybqdUfF2udOMPYOMeX50ksIzjpz ZJUynO6oHfBBaSafk31C5pHOOjyH18+emZFbDQw2pj+xf2c3BkiEW7lzyraKNabeV8iNFQn/ Cgqov2eCe6mum5Vyec8Ab3YnjPnmy+oluFLjX5TKEnSepVcXf5zVISbkCNhL1JRltn6kSM7x 5bMmV/98dZIBmIkv/zv0mstx4dixoZACgbYeBnLwlq9w0Ezr3jl+5Zgldydk/Zx/D9zAK19Q uCeChN61H1WKLkHwnU0vEiqqSRjBeGTc6ZPNyW3UY/XolXCpTY9gV8g6B/SNVyo/vMMRl0EX qU+tt171V6+kfgV1/n9bJv1QDu+EUUd3rFZOOTmlfQEsXh3hpzw0l5IlhHdzoSB9hW1fu7oD o9Ta+PDri1rNkdB49K1CfT8eX9JZCUMrjIGfBUE2pys/EJVl4YlWRELXnDU5WV/acGYVKS5z UNlKXJe92eeo8XMkzDX9vYe/rJzvRbOLnLZ9DR9F8Uau260ub0t066Qt6eb3HDNPP1F+gqWC dyJleWIy9cTn/+QijErJxLUl9JO6j4w32euE/Jm0V9DK9VYczEFQHuV56h7vsRiN2b5Riku6 tHkpqxU8f8+BSrBNre6mhP3tf0T3yxGG6ARaasjEG7kFmOnSgR3krlrtk38loyRZ+NyfMvRl 5Qp0ZKg+1PFkj+lAEz6fP+xyxk912CPNqsNuSUeKFQe2I/KbBqqKDA7afbiGfijHrVyGNjeS lbHF+jK9dfe/9eRPFbp5LNrmt/9iHRkCl0dZbODetv2J5YgTmZ54p8WsqHwWf5+PGk2zN6Q/ aYsWDUr2xKdMvRbsTricDecpYYCuvLATLLskng3ySkqNktyLG1MyyjRMF1iljAMGPd7tykFb C5Yf93waDMrMiaK40DCXGPzJeTyArCd5jlobSnH1L4TOUrI7F72uGxDEZrBIX0HVWwIhZ9sG 5uOPjJujSNcjuKa1/e+DmrnhFVLNQQnZlrqPqYTfzMxKHSHikZ2+L39+spUir2kUFrvGitmj p9XQwEov+vaB4RFHwOYLgJalGdXBbjIDEh2ZTfbJHR9TqvosocFiBN8sA4JpyTyBXYNS7ICH q6g9znJwgjb6fUgXlrK7+uiPtVwSZ+yD9YGT2ciGi0oC9N+KAMQMnaf085jmzUTCyOFFKMvC MEueTkrNG83MoGF0mnWoe+PgeJaAY1ExB1s8XEycmHD0pwvH+HeMootBgfgKwNtcAPZA7wCD Za4+MOzQy31epAdOLVfYpbFmAKDoOexK/gBe8pxKIZbnEs2dh03CFQ+v1kM2zZvbjyjka2k/ kcuuMNxnj9+V6Q8J1s6WGXQY5JmSaVKDOz7iOHLW93x7mdh5Bsj/8xEXU3nQV0bMALKf1nMu Fi9n8AJM4zfcci0E2T8QliFlrAnULbvXcv/5keS6j/pyZ8BYz1cbj1TdaYlZ6kazJDcrQrsg EdvpI4g/0LzZ/yRJhc9imhaDv7XN64s727YOJ4REBmtluABbIav3QvU3RgiyPEuY9Qd6/ebm Ou9rVhlzbPeFMAaNaeOuN8Lq55yqXB3FdMZbV6uxkmbG8gdnz9a7BJgtW/Iw0uJ9n+pYofp9 kHftpuZQtxGweMhJ8aCsy6Mz0qPVG8K+Ryb4KZGKiZ2tK8YJoswTD6QtlwDQExxciA71ZsQd qEO0/z6cjzX5GRtBiFOrThM3DWbt0+uS7WuGAAlqwD+CpGwiXmwXKeCCGwOKec15/UKuQBPl XmdpXU16QY0FYvQwmm6zwIupgsKJ5uaHG05hn2IbYVPgWoGwhqDvNZIvgm3O5PF2rto6KVpo Idghh5mP07DOh0BIEaAm8pm0nmToY0gu0yppzvY5TL5ltspVUoHMdJ6XpIbo/m+v6hUHXu+Y M0oWsuLFDVZdjat8B/oU94vssONQ8ruuocjmJExxwNzSt5fUWhLQtksv0YrX/WsB/OBW59MF 3RQsMBUBxbWJKHSg7guexC+479bEfyzDj4LTe2UP5Q4u0w9cYikeI8DxZT1MZxTNnOSgowa4 TF0LL3CLKCvvEHgSY+aueQSVxmcrxVehEARxMo2yn4YqlS4iNbVXsrp0/+thqqNaU9tw31R1 dCfAm/kLuYlAjSyrTYG3tpOsZUIUURB8Lw+1y5BWz4Jeo2hvHrZfotpxLyMoqngprhdBq1dl ekUjvgCXgLbhZxOAtsljuiWhl04gBzxQ+0qJHqCPMJcu55PAHbVxfp1AxhB1VwhzUop0YT+9 uwuXEHl4aLktt3JZt7kQztZApu63NYdofZah1TMNPJRLhjtO+Q43JyR0/icvgAiVVGCxq0uv 4f47M82l2z9OUr+1aF0gdHgzrXWZibWUfUqCMdUZOebt2qxfyKX3TqQm7RqbTvy0JG1/JJx/ YJ0pGiNHdo5rpBjZxjQvydE2/PS7LadgXCGdFxqmbOm+e3cLsP7EVybWL3krZOXT752Zz1PV YBzzWYQH3Ff72VhS0AIQp1oD5HeX15YLgLHilGquvm+4N0YLfmRckTaP5Qonx2Zm/Ay64zla x9OBexK4C4KBlQQbGXQ4GWO3XynU5KPbG799sU6FO83I/bYNHozImarCPE1qsU8xvBpxXOgz FqHiv/mTAmszJXwglEJook4fJOgP88Fa2EuZMMMqsKHzfNJumShqBXOYctUWz/k550HrwOLH lB6oqxBAzbOTlsQJp2WG9sqkctYZWFpCEpyeYpb0KqS7bkF9y4EWN3Ra5XzTOLaUtbqX+3e5 vMs/4r0z5PywygSbmvzP1FkHVDHzkx4X3TzZz+7XaEtoyIFcmRiZ7A3n1uqIcujeQhYsr/N8 5FA6KsIfFxCA3dicWRPWdUatnVnCJKYBj9njBJ2OQEEU8uHqfoTW7fxaZVPglPnCPhzxLTqP 16xgAS7zSfehenH4YLlGgJRMdyEHFRcUMQ0IkdlX92VniM+GTt2eCYLm9jOXbXsGB8kwguBI FLEYJOL/z8jf2GuaCAuhl2w50h+fmQ3tDsirR6Mk4UrwvG3wdfA6DbJSG2msJLu+pnNQuuAw KY9Xqvjbb5HshMSUAqDtqM2h2VTZJGweCvGViavwRzNwwb7fdTIg8RNlElthSzftkFJy9gRg SwwBiQ94+fIwpDLIicDcXPIZNBTQwfhykXBwAAZwOSWqTHk3IV8oSb+kqgwjl61RwSr0iL2w tpf6C+hHIz0BDO21tsWQWp2KmipwitICUV4F/dk4ugg9yrmlj865oqMCKQIovskJ7GLbOGWC T5q3dZYdFa6lhBafx+mZcuz/mwBMEJPDuoCPWyQGcnAaZ3x7JLAXahUMEbPRDPS7Ie7bqkd5 7xKOyia72/6ID061V8opiXzE8ea4huwq3gN/p1IK5EVWZWM1U38ljp6MADHGBgbY9Xgw/5re PZ5wM8PQ93EffMtkaXbIkOHTU0qcnoU3ZHGAaIjnhI4PawyXX9BPtZACxU0sw3wy7I3YdPUU et3EFpDXDhPggTgSCb5PsJQgYQN9BJaTn1IF9AO4mLBu7Ad1b3u2yIXTqax9wMM09pfnKQEG TlOjYEb7Qje4KrTTIAa2LhzxZrNgPMSqr25/snYy873X/zIPT9kykoh2EHbr51SwLUp9G05P u1hEma28TBATSx4weJVEjZ/bWaSufok5cvAOa6jzE4U1VgXxcEQ+PQxuH2V88FTMkC5GMJoz WqJUIBTQyPNdmCeoWcEMBFJkdbNK6TY26aK5f/bhHnElwrBvBGt8pyhjP7qgE/M8PH+k/zIf ljlyIB/MdrwEOA0jBdYNmduDjUigfFSPxjb2AhFrXOBqpcbXyUN/0KEb7l1WHMqlcvu5jHGd VyHLlfjDROE8J5I9TA5xX4jL0TU60i3nFNcQLac1TFyFa6qejcoujsxclz9R00mb1UCCD9hY PZOmzKByQlNvSWpuoyAPafyOtUWHZ8vs5feddWz2qvNZmriaxNb4Da2blCSUmdv8X+2ee5zB KwdyM8PqeU3co/rRXNHiAkaCmL98KYU5BEX3TcylWh6Tia51I0d/UraT2RaWtVrw8E9Dsig1 nBKIKiQJPxY0EhaS9LWnF6nS03HTLyXJT2s/EyZ/rMO0kaQAKFI1REnsFvIMbXB3WPFU4imj cO2Fx+/Wk+JPYBsIOJ+dE4YWdegShYSLHmdnG6Q0O0uzq/htoj8PuXsbRlZn5TclH8e1crmc fsmXcq4j4fXn1xFnFwmPj70thBpYeuZj2ah02w1zNACss+q6/uwQam2USKLfqFPhpZSiqgT9 IZB4hnjEZM/F2KSLYbQpEl2GIsGf6LL7ojlbOxs8JlcWjuIM6YoZE9wV2LROJqWZHYWeW1CP r313ZkG544iPS5mLViHGF4ErzPRVnwkev54fgOZwHlhL8c1QZpfGeuh0/dsptiBF2tmpd6tz zFXoJXNbPpKp1oZr1Wow+EL1F8kAVNvRCRDM7aNQ/VXdswGNO/TxapMr6DLL9NjA0FEcL9fh nchI8WNoV/LSGMy0Yb6ayrk7m9pdqepCyyS9r2baLfuMPzE6fYvDQ6vn1Ly49d009U0HdmIQ VRCnEQ7VdXypPQqjbl/au7m0xqxOKu1Tjj/cSVaIzZ257UTLBmXYs2mGVf3vk67JHsBXRW9x KpcUySTHe2nI6fabTRCG9oB/z9theWJGtQeEo47l0851njfpfZvsnA+FK9JO69M4Iwia6rYV A9B/Hz4IvHqPvOWY916PSumDFChFYJC+ieQCcaRtH3C0xWZU1T3TC2/kuhUNHbf6WlcwsZUT Qz5QkmnZj0tANm/nvRnT2O8Izt0vmVI7qz3lIgKyK4BS8KTwPysx8/b0eJLbCfO132v819Ez CmBr0cfnhiyXhT3Nan1bbVlxTUZW6fJ8xzc9CJIOj5/YpDbgOe3vmS1I690uPWAjxTKfnuSx 99x+CKEGVrJilf0TAJ4vHxZ7fnwpHZpL1xvvQb/RtIz6ElDhIZxtA4/mNZoPuJ5NzOEAQrgL xyptQO7awFODDImthJ3BEjSxXU97voEM0CbwVRS3AYNbOIjIZcso9WmoPFeHmff6nXiDadDr EdLft7FNZatxl7T+O50rV8NeYI/jNYuXoHK+0Ankx2h/kmmYunIaC69EFbDjSI332MYRV939 VYR+E+BZD3o1rNMYACqbCCqIbfAjz9FJ5qmxw+1MTNuJOThQ/StaFcIaUcKVJ16rIZenZ0ls 4I9sMCC2JsEZDm0h+T7OW5RzNXGWx+/LBw6QVJ02ywAcbIKifnoF9b6TwZJX/GY7o/u6M3Um 4cg/GgtldhEjsyPF/p8xB9aRPowJCbaa3okUNHcx67OwWxH9wx/JXKZkShAE+E40l3ThWUJf cHc8cA18Qien5L60n/igAbwDXDSTzUjxG39x67afW8c6OA1lCLxDJqlZFMzNLQLHDzJjstkK bEY+VIO2OyhvEEg1tDp1SkWBSk/k1LSnIbgR+DKlzKMJpwetsxbSI9of0mrfCh0dZKJyErfV UpO/br7pqN9UY0QceR40qgCjGD9+WbSR/c414LwD0NxfsFV6sIYaR1W3te8Pt6y+2hbqbeFM orSUmT6r52WWZ0LDeGI3UbHKD9hYv5Dx5oQMCjM17VpNRvDHOL/Sdt0ENsOkym0eBpCUeg5L 8fRUIUjKo1nLj/0Eido+74blJV8Fz0bas8hu4UTYMlWdso3KE5ELGfWoKiKRliqmM1ey1nps Ib/Svk6JTcgC6LbuXy/mm8uR9GcoSlJWGA3hicPto6x0RDucZHrAF63ZJ0ckA0R4MqjDV0m3 AZpu7nuMpt77X6AjDY6DHS432/EBRT69CnFK4kvkkowFe4ec80KndlaBavdWNRRAhPcYJc2r wsuaehCTfttvfFrQZZebbCOS2xfo05ajX17nb0b2kUtejCkR/8qodNjBKINP+c+y4csG+WKA w0jXZBSNKVKbchVkhrdO0+cxQUEG+JI622lvuWJ3gGiX8IbxJJyMbdCtMf4iT+Y+vr3XyjTX nuz7dZDhgOiGTVxHxsyz4nZW/zGx7dOlAaiTtBuCcGNQz1NQpoBQ7cIWOvny/qWJTW33+Akz UgRI2gBAZhRQ+mlxEiPDHB7JOPc/kpcksZYxgF8yeRIXWW09w2OHxcRht6bN63cVTh9cFjy9 p4kr1xHUIBeVQywPQhwNIr47ivBmZYhdHhcJsxtGFUxyzf9o4SGkDbAx506xVtc2xhq4EU8L /jYAN6yebtu0UODfHlx8xE6bXJag4GbqP+TcyoQwYXtvdR1PP+bz2OsUMmy4QbPLTYkHHjUx 5cgcwjWlpWPDOUvuRNGmzX3o6z3usfp8V0FhOQElse15FZx+yV962F2fGi708GKTLvRbko27 E34LnpDfVOAaYcETQARbpr2tk3uoEOcMgsV2whcdqvoVJ8NCFiuBomF4GUMKCtdI6vnRIEkB KK3thNdhy5BZff8HJCTMP7ZPvrjq9pwgNv4wCTxaGE729ftmmBbEhQYiOox7fjot/0RRxO3g 35dQnn/rrRMXLHvuU05QO8VK6Qn0EMklDOhHw+QsGfWAIV3UkXEj0ethpLvYWt/M3XgtyFlo Ek/qSDt71dC8Ef01xDuD+61hV2djt/QrKBCcTEmv63suKf47pJAR3OWhliuyYmJy2uo/ogtJ x/IoN+JgAINwTNWee4oc8qUfm5fCmMFLwYMb5jw/7xZuxhUVKE89x2pm5b+rzrCgLSTkKbbv I/ien7ahiosZe5sW2IKwLUTw05H61Q99ERrLTlzU4B3taT7t8OqbfgFnInNXYY0aNQCMs7H5 gJFvaGyauwvcAI2XLyvXomI4QxjspBeL0ql53f2IBTxecU3Wn5s8jdchaScEvlJJHXJ38Pl4 6hL1Oa5ljko6icXcEq1t177P6Gx0n/5OdEpkQsu1iuCCbEUBCnmzEm8sIArO1pb6klZ/07B3 2S53dtqeCD8jLQfmUH+3QnYqlPc9iHW3+8tSfcMth80kU5clKCmoP0Cx5tzCc1xl7vC2wRjz Yx5bN+nb+Q6J4CaTPGwGaXemy52ED0hoskoPwih3Canlf5z8yFOUz3dPxj0+vWu7fDMILSyJ NqgUr55Y47odgATPFI3FwY6Q67wbuXZhxEbCSaUtYf/GkL8FOPrHU/BmafbNGp+T2tth2lkb DtRILJ4u8k2uqBgWBCMb5Aqs0JgIu/Js0kxahcwnv5stT9Uk/KkD1bvJa2eTUhsr8DL7ZcVg FTL92c8xKaexHb5wgQMDOBhT4jlW8f0G1iysBn2mVPq+lf8CergYEW3BrfTd8AxK60BACPzw Vu1CQppotKul+X/pXRJv2Smketde49qyFQg9hWkyw2z+aKmJnIZH6l18F+Nhute48S47qHOz An4i2pG3UptKpyKzcfbOyJ3OTQoUy4upy+FK6TV1vDA7siBf9MugYbvvrCfbfVeymjYSKgM2 Xwg/QGeKb2Z+t6uA2jMSk6BSbcfmKaes7q0XLWWv9DbPvs3/VaI4VoMdyAKWRR0SqhO8Zv6a Bs9lLFdewMl94lWVj627iCUTQvKrOWPq0ZuvW204nd8yZx1K8GM3XvqmU3H/ZhGDTSdRRHY1 ZQBymPshQF1lw797ihB9K5fFO2EtaaChwHZ30l8xlbbK6Hkc2xp25iCvAO/wXEBj2t74stSG GI3O6kYEi0VYj4KDO8kn7XxcEdFXl3tlBxV8ETxll4BpPVsLVl+CwJnIjmnsxwOTFLg4mf46 03JFz3oNZRDPe0I74cJxOSzuqqvp8AvcyFNeeZrZvQKSYhepySAU6UiuxFGFyWPh0JKtVaXD N7azdRP34MTAsq9v07kU1PoBwpyZroQQgqiD5eNt7Iq9xfHm32WF/+xwSQfgm8c+ECHILsZP UgIzUpGjeFLZBVGTFPd6eM0ApBDv44Kaquav2XJzqkab/uRyuroxI/ukcZrLjs4BWYdNJC0w W+eTOz7lVQHz9B8BNt+scYmTpa5KZTB2wZWhcGKidlVdxnbyQYGlOlorrKcosxevxv7PLTI1 N1jLBIC/GvpTwaRKnUO8J/fgIovvxSFnD43pq8Ioe4rwxUga1vcQFzzRUKteCf6LWOwxjBcz USJJeMzkkah5YCFjYf1ePeGbBFQDpngpdI3EqW7tPHRvsY3ucigMjHCWQrKLXHZWX63OnEy9 dMcXqjfGjj1+qtKZdAalOzaakqK4vQZ+N+OlEpMJzTu+9DBAduNk7WkHy5XdA3ALs5FF1teF 0f60sIj+LsmNkHFHP+Qa9dwgngSPCiksKPXTfXHne5HcWwUNCPoQW2THgKvnw59yDxh0k24P TClF6hFHjigkh12qRtU0UjQ61S1T0lhS5rtmYgbonDUkOKdMlfSozYWuG2a7VMQ6fo4buHP0 KEiehY3vSUZPgnLR4AMjqFBZA6ElYRFUyZHZZzHs17bbmpzKv7hL1rVPYzXEE/WjJoRSoWlS Ocqj5aLrDnnayCtbvCmsUcJ7rQascesI9qwR1zeEpj+qHwZC9wWstPOqOK7ShGE3PKX+td7j +Fs94+VJlhSBcsvzuBF0ukB6XFqBwgrV6Hu2fBMMPXta6h+MFNJQiWhcnJvZds/S6u34AlbM uGjVrQp3KOLCpO/KVWjebhbEk8nb7aUei5rfYQ9vbes3LcqpoeA1w0LOJTB3PH65aAxF0Jup y+MeAIg6KYsEpubD3sFUZ4THeOY3OjHR31/QskHmapAwVip4yfJjVmde+qLTwPYOFFRCCHEG QlWpB8NeNaQwMOxQggBx07L0Dl4UUxzQ0UD6GwsBI1QnlaprC8RQcaJmyexg9vhtNp83qbAx WRdZkdn4nsNKacI3PWpdhBr5/EsPH902542fN6rgbFaDMZpK262mIeDhrouzmmJCTiU3kl6M iv5NRK6F/yzNhCy9lS7qODPXhsuUoJDhbIy4dzksyUXI15Cilch5tFYtMvc+O/rfGjOZXhXX /vkiP6Drk91SQFl71XxNdXQA+K16kWbKh3Z0T/oXAhZ/BuX5vB3h/89SbmPckSs735VnpR1P OMSspXDRZ2TF++zZRgfvw6WIlqR/Doo666sIE5vT32NP0QEspscG2gPrbuDawdzzjEyTGQkI hJGwz6WMq4z5kXqhw+OVFVgHI5tkajX9G+9wje0cRmrO/ngVytCg2dfRU0Rhm4Xaku1sd0lE cR6nNZwnUyXP/dR7mwtA3Es6vnNc1+v2/OfGFqEhum0vSsGPrqXIT85aHsVV7EE5M4vV5uKU GCMtISq4ddPDClpjynxEyYlRYRlUV14y7YUYxjXZE0QuNtlySzaEpGPrkVkU6Pvs8VZPpwm+ +eZLmZ871kMkeXBTMcSw2KRspr7Xt0Xm9JRYQjI/5VF8L8MtpwC6aesGA2iimpNfAVW82BkE uE3AK+9UfUoyGNoROri8iBR4p42NfFcvp1GwyysdpL4BuU6W7CHleWIZd9d3kqefiy4rIysw ymDsAjE2PbkYJScqXKUPV+HbaE7PpbuiHT4w+VvMF+T8CBNVnwIEijK0kWpHnCrK4PpyR6vg M4BPn9aEwQhlGwORKsqYIFGoXzcJWy2KYTCW6HzzQRe0ZPAeuQQntlgKXnxpBKoagspbM62y nn9ORXODUg2CpQW6fgqSuah2b27RyuyU+zGY6lUTF/UIvpFETy32zvPWmy4LEUBQX+5bIm26 mUC5s+ikZkQPMoP5x9g0BNkNuGtW4H+jpIclPTJubd5+if5RfCdSwTn5FmvubOtzuvtdV0w3 mm1Ax2jiLCRsSFZKlT7gBDwxiw7v3DUWewT01SLb6DSbsbpeuwFzpDpaqmTCKK8+8P3v+JDn E2q57MzTD3S+3XV62vDgDkQDU24+Qdyjcd/+nowh4q3QFrN/Jcv2ZyAifpFjw/ada46r5z50 y9hjgjodpIhwD2u6d84Hs8BTwj99N56lbEhc7N6uWoo4GBrXa4YKa3KifvFAgIFkVk1fl2NC 0PoHYPQs6TvGbSuA0sK/oFS/e3wK4O9IkG6XcpbAS1wDbk4hVgDKpaTljdbVES2fU3gefJoW YxSITvqUx53OeUUwn32neIZweuXsZlAg8oJ8fTpSEych30ux3NKUPYtRmTtTDCrljoCY+N/A HarKdWqV33Z6wGRql5zt/2IkXh3zAaKsJZInrB6I9orY+VJC3c7QBvJsYYKA+/x0KxrDt2gF swn7lqR/fFV/K4tDKkJz2R4fgR5sBz0jqaLi19wAmkDxUSmQMZGrU4F9irpKTS3YNzeqwZd8 S8nQtam/Fknz+HOe7xGL4+1pMD+peGNFRavHIev+MJ6LyMYjYOnu6gZCx9DlR9L/lU9ItEcd XAxn23E6dwsEiVn6iGhrpC0599OtmXu7ZltsnLFbj4aJoWymPCnqL5Lr5gcf5fbSnQ3twhIW A0eC8oeXlzV7yi5r/WMG3pjZjk1si3P4+QFt5y2rWIgGCE9fVf8Mqm+KMRIPUcTWK37RnfnR qNGMoY4y4XY++xk4FFFWeqHjnEq5qQg4ME23eke6LXsURnRmGUJ0MMfyz3YL1zAVBPrnczIX W9xoSO6t9wSNfWFPeLVw01IW4V+kXPA5Ql8xMTDEXJ8RzUTQDtcyDSdp6Bwd4Nhz1xmGHb+a Hqd3z5rq2DdK4vhjFznVzbilbIatux1VwDDTJ3y6APjYuUheMMTF4EQY6VC+ZPyk1FNWxsy9 jRJfGfSPtXiNwe618/kQGmmsbruZeC2Jqh8O881LLC2wrqf/PdHF6jwYX2doppCZtnjwhTby CZ+wwzMZRMACWg/4WJ7pH6Gy4RxClLm3tU4rpONXETsL0lyqmy7r6tHfPlxYDppMDfaeQQHd uxozg/6kKklD+kTrMQzmJY02/Naa7S+Fm5UWXOxNaWLfk3A//kirey1rbJ7mXo4sArCo18zW fgmf8NjAa7JHEwYA9hhauarGKx7DdklAwtVIeFY511elLioLfruAEwRehYvNFbwFGfd85/2j 0hZqIL2Xaqtb5o6mfbujuyomJC8PJX3JGDZRYXWaUckdTpZywTOoN2BW1NzHKhB2n8griTbD F+28FAVRn+5Tm0TxnrgoKtac6jRE+jmVMuZfqb+LZ/iPPgUBW95WonrHLNUtp6ShCmtUX4vv Xs59EfpMcZp1rG9cZdF6IBDTtOCtICMVqqqLCdrDbFKLWaR9fH9IzG7PJk/hJWAP43e5m52Q +lt56az+ViWBKC6SYple6+uI8ruq8gPgp1d9tR344Vi0WPMcZC7Cg4o9ME8uC77rLX96+CsL VA5jB6YgZSTB6TrcOk6FFwzG+mA1hFtXSyuan/PcR4dCVqcmooQzTRDIvtTCZojcXsWZ89JA D2CFsXr5LAS/JyK4mUe4I+Pa+xb6o6bhI+laWD8pe4HsA9VvVvC4oupcieOpRbk/4ZC3dUOe QuqG6/B10lppQ1LGHV3LEcFmofz8nCD95JrSPNJtEiqwXOtch67yiz71ntgCtHfL7Fe4zLE+ DHlQ5LjTXZNCD3fI5Zd/DaxGsEHNuKftrNB7oFj2sKandxY1IzfRE3CO1NZsGqJTnKqTbJ9m 5obaVMcI6RVc3OM+fUguQkzUBtkwm18Etahm/9xuQCyztEmIPFUjF5y1AS+5m7IJrMPThj6S zBXeJl8WYbruYp/p3xaMxFkOATnVr3uFERTlGQ7MtXq8rwzZ47Sp5S0k++VyKAUjlxNtLIRl vYkYE0H5xDPKzpZR+1b9KRDuUmm3bhXt2zT3wKyCPETBAoTCGjCuUyV4yJvmp0OZcdUBfZ1o 65teBVhixMVkSPl+UN3/zG++HK9SCC9PkiMyDRDUnSs1/lLV/PGVnztMyCg+me0PD/xKnPlA NyQZ3Q6fWbZxANoPL+xgCGIkFPs5HkGNaqPfOk1vbAPCUL0b2klFiYmp6zOPUSMqIV8pNGcp pAZ98rO+Hr8YoujXI256Wv3N+FMdB3us3RN3k9fP8/X0il7wiO/AuGDcOuzikgKaVhGvMCQ9 zoIE9kzho2pka0nGvFlHA/y0lXa8Dx7przVr3ozb+2o8zhi3Q1Zct6ZFryT54ewtvn6gtfDu t6ES3ouZhbxF1HYnEjMsAirYV4SKynCprOa2sCef7v0cyRPgo8HDhUiY1DmpMugBO7MjYZt7 mtPMIVEFycITZhTGsJ2zx9PTGa4m922qMLIj1VO59QxOWaWcp8vzRvSTQjlV51W7Jr+Q1u90 Bubf57X2AyPhF4cPYbvKMYNi+x70NJm4PQpWT/tJvzj9rAfNTk9/cVE9OCIYIFgfpDpY7CY9 zWuNQfJw+aU+TpCH809tMOHzwLbrCcwjoNywNhQVqg5WgrjO6JhnY7NJ5IcpyLe/P/yMsu7j j3Drko/KllopE/JGF3PVYaptNY/mjTV6l3Ug+DvXycD9zFJV9yq5DXLwsZ1Z9EIrGGqN9lom eKXN6jNL3NVNWxG1uf0t62dqze/QAR55A7jAH3SQzUsCF6z9PhFum6QpHT1CUehGOa+Q/eJB pERcF7Vl3OuUpFDqqJN/X+t10PnLYS2+TcJhifljKe4iDkHRsgWr7wsQjkJ4TnTw9LOSyTZq yqpn++x1k6NHp1LIsu94DfxXP+tF/d7HrMSgJE1mc0B9NW+EM8dVHt6CS6Oe8cTfMg8yentV 4XL2tqtkn93V7Fga0lK66ddPMroAZfbgrJIo87q27GlSzJoPLAaO226+u/4taB1YHQZK17JT aUJHIIUTGhbQKLlLdooC+K5rmh39FeqDJrjOdbT4EUJhcdsnnkwLT3qbTykn6CW7k1cqCI7X egZTnwn78xMh5kdW7qqtVbmGeiQS2hO0YrCv21/pnuZfpt7I7KxdnZiqmxa4CzgAhdS9Im/+ Vi1TqRgPaIhoHwbnMCoACkWUIh3ESSJgpikcJD5HcH8vN+x3CVrRsbTVle+QMy+GhWYEG7Uk VerrpkcGUfg5Fhk/+2+F7L62X5WuhZy3TgTcq96CKSrqF3LtRhSvFGodx+lKSae6SkdiBDtq HHhMwSmusXaAkkdixgPenS+jFL/ABD/0q1t2aQ5gbI5Kbfsd3/ij9tkPd42MtJrMkkI6q7bf 0teT8iJQllhU6jTZ/kz+MniaMjdLPUD9dcr21isZF1fD5RVabvZF5pSxpEdfaZpaWzchUv/2 YkFRe2YFI0b4l3Sw1JcIF2uVqEwuCIfqG2g5Fs+n/v1e6CL4QHA0LpYeAOhqtTjRM+L2EYjs DlBH6JEBD8ThwYj1D/iNM2nz9ssaPKd+MXnlFRzs31L5G3iEYPhX1ZCEjgvD9JlnBwgwWBuB ffWu/i6xtRPuWrEJzAtynNyq2EQ3VUAIf6MeL1JvvsZ3LeEPn19NI0CFw/inpiOXLWPSx/Yk LrzBkHQXz5JKV4DTCNWi5/F8k4xdaute3HNT4QFrrKcSNIEUMPGc7ThCZ83T1PWI+01LRBX9 9/o+TwDOi3XT0NAbFPocpANdn8wgnXZ20heZ0UOzhage9ThDXiWZrfHzWbllcFhXn8C9sgF1 0/tFbM3ypDRIr0Oak9hoJ2ln3nkjh58g3iYcz88gBK2Z6fQ9BhAWE16AQKV2WGH2P0LRRC4Q Yc6bQsD0gNaDvtRIJkwuT9w4xrt55T3RTg5DMdSq8tQColNbvL+yE5s81IZOvIj2iL0At1eO t94TzyGXT+czWYATjK7ya5kHKq29kJlfyvzC/eqqQf5vFBK8NO8L/1MMl2j9ZCZCnk2j0EIB tVc06DwBOgEtN2oHApzKctZ0OwjBU0p3n7+E8UBywtrBoqirvbSt6QhvewVnjpl12WmvPH66 W6/iPmpKkqzgsv/07swh+T0bTU7HfrSRbAk47O40k/fRdZzmc4ECDTPVd0PPXddHz2JiZrSh QSgMn/1xiwBWQ/8QRRsdsYnUsy/LTTs6gEdIBIMRhT1l0xyaoprHhpo5zn48U7F5bxMsdLbg vIz5iOv76f8OOQd5NSOAEO7LMWlWOW5Eq/pc5N7Hg2aJLLmve/WfNCKmbPg6kGtDuB2w/8uB nsZs3ijpkn5GYBcBZ98+Rng4YmwKmC8CKeXfJhPB3ixvsVepU/GEkGI6VTiq4nqQNJ+bskZl wpuHR5psb2+4e3lSD6Q04UKfSzLva83GMbgkbNlDhUnzMC91hX69eIlf60CoK6bY28BBpYkn +TjTrd06UCVG/IRxTyGCKHGoDGUJsiLk65VWO3dSmDn6sqvKvsDpt7oYYAkpcWteB3gyHyC0 XWI/bJJdQ2csrPFgBScs8E2ezOSAE+/f6+/J7k7EP2xtB8TWnIS80mMbGhYcZg8kWQfilmPG RueXZWy9gSziLrmHRw4WRZAEDCFVKtJ8OoPop0+SyqRKBB6gx/3y0xZE15wQNUb2GcIKE9ih R4FyndWS3pUQRTfc8xesXSFNXr333WJ+EE5w0i88kAMVjuC3Dn1JaqYl46jMoMv3lq5o0M7v 9rGlXJBfVLkwvcBtImSWPgNJoRh4PWVqvIlzEC82cdBi8yWXRWIZtzVaH9V9M9on6E6qv/l1 VCYEIt6xZkM4SbOKU0J1GoyWU5Z6Y+Rob9KtKLbbTp4LobfPfbOzCXy9LOSsyAxYyFEfY0zk +S2hir+8Gjyn12AOkqEtvAJwkmURGk6t38MI5SuWLyva/uo9/y4h8+xVH7EQtYCzUK2KtAgk zLxAr4WvsCX6BAoHkP8aukhXkQ11BdgVAq+etjmo2ZvQ+rwoKjKBumMDm38J+TAv4kuSBsIV QETSUlXOCmDysoWoxhHeANF/mz/lhwadFePU0I3cFFhBCR0fYYIbr9MFaair1csPuk5f2cOL 7y9s+wn64n+hBTccndRAeyjBD8/VwlMEDsb5IinlUJQxxF2r5kAmp8auWA1SZqfXie9a/YQS 1wyypizbM4aeGeOjVQs3AdPOQostAJe0hNkeZHN5JD0o06Nj6Y6XB0C9WP3y8BPAgQUUkDEG lpjPDXmS9IBqbw/DWRQZYVVA2eiCM5k57l9opK29f9msVqrmFOU4SzJYLJtyhdbD3RJYn0Zt jJje4HV5Bnd3w17/+bk+hGGWZvwJsV02kLbon7OGWslgN9P99Cmus762o2F8Lia/AfbSkaf5 M/IOMINz5ChxkSmMtcIAFE+IUXtgRvWkscXuEhC/6w+YxIxgnZt2A+qFAzxWVgCZ7G4fF557 lJY8ab8q0Kf7xwJIlqtYM41YqSCNLe6CpjY8d2DMCx1MgI+Bh6GxHA+wA8MgU4DEbbssUJK4 4YiXMoVIJW+SbTp7TM0N4GedcAm0qUtCvgURDrwJYkaFj0HJpVyfD96qNf60ry+yq3PQwbQr Z+DGrk330d/UgVLc0ogApJeSm8i0mUO3Ob3i2Vh7IrKYSTzMqRxiqwtPUjKrEWRfQ37ggoRm zBDr1anVREu6xNdDHB+uR68HAVU2/i+FcvehX/tlPzmWvWfDstxnu2Jsd+khz51HEv/5PHqA nrgapeDhdfpd05UjWEBDIjxhpTMGMofmjHoczQbLWvB0QQVSltIfXW4o9g1+mHaxDNuKJQhZ JeHcpdWCbT6vL//CPZq239X8cNKNOGqaQgbY22+rDyDlLQ+AOofcpBMdcLUhImWrihsoxETZ iIC0mUUt6UMA5aqklwLygRYdRw5xZD2kToNaKFPeafZh7GmVQ059vWTrVgYXTMFJmlLJQ4MK POrkvCDqAcZb6bQRXFyq1+5crcWQ9d8UcNtrTApUW6tjwM35LGXrbh6F0UoDKZ8b5O9VCZnG v36T+3Md7t5JFZDLb+G80cp88ZrJ10OELnfPo+W32hsHTgecZCU6UtNdQFJIDdRd/MhQnAR9 P+jxDjljXm1ZFXxWxwmEDUk61YndQctE1pwYL0N2cf7RilqFI6jSnJxEg/w+ej05SG9Qbzz5 vawvxjfyBntjbC2z9DcvRWDnrJnSJHkLNo65Wf34djcRl1Ucy5EIFaXNlfqfJrhZo4j0Lpfi I7rBLfmv0UVhZoo+K8pNnlGJWizcF7Jb4b+CXXCk3pYkzJswSQXrKEv5bFp2CXzN6Q0E0opX UeFEuidC65dec+lxoaDwaouULC1cEeoSjkDp8ZxzNsrdt0hi2v2ZVKGu99Ff+d0uzpMOxNDo a6bTkyKAhIouzbCTq/IMDraVPETWh4y13/4ndnDrZjS5qafwEjTbM3mpmSCfAQ2qIfYxvaYl Jv3GSSfFUfnXTKmk4Hqwoh53b2MTLhJPr3aZcrezmQy4qedHp/hjgc1kLnQOeK0A17Tg/P9Y 6VI95Mlr22hgsaBj45/TG0mXnbV6SV8YGxI8to93rfrtSMHTTHtd4kAk27EnlU5bDf6/Rb6A bdTCo0D07iM1xT7KqUo28SPcppGNbkGZ0csj+j16rYYoOIqhup7pYpkbmaq5aKZnBjaP2Xv4 eWcmd4uOMTSvLdhxUdFbYwAo5YdK2Spkf695wchY2Uh4H5zvrjzmuo3uvykvNarALMf2EsOO YSRJhPnEHxUSKYSO6PVh2sAhw0eFLN29GSXOtH+7oyYr2o0wk7Ry+nI/BK4mNJGuD7JQDDX6 ExSsW3MXvxH3WZcH2cca2GHmBT6PkSQfMhetT7COZtIH35+AmMMvEqMp8N476wVH9OQUI22g BOgAkU9sVA7+LcFJvdmNCcCB6k9WDbro8RPcK9BrEgl2V7n1sfwf37GRTVaW5oGrDrcro0kp 7C6b0drcDU2qIg73WrMvULjpluIBAW56enPt4HWMch2ckXE+n2/5Br1VpUHt4uYoLsAI1Zs9 pjS7MBwzoXeyCk5AqTH9Gi7R2uGACSrU30CNx+vPUtDRPGEKAdncGLkUVWUFcoYKgZXwz9/h lxSOeaZ8jhRqkqFy4EeTOTfd93hO8j3IlnonSTpHF8vDv/AAM61p0rPI6ok5EQ8T+okedVrC 2LOpG/TJWyCkspVeA8ZYgXTuhYRP2ocWmxNEyYsSiqlzjN2IYqyiFoijDMNVzIC++MyAqvgj gKmqNRVMdhvgv7NSMhy6gjm0pkO0gI/giGOC9dTTe0j6zl3p3tmcPSEDlTmir92YDCaU6khf rbTQs3B/V01j66fmql/ff7a39XjkTeRopMa5VvctW2zmOa4qTr097f3h+YUnKQtvkivQxU1t LpWkhtC4GRuzEiQ8/H4bE1IBZ6zbXC9j2F+5uuC/xuNRnVggsA5EaI2YiISnD7zsf4RTgjtt lZBwPkVICxixkOOV0QB05jM5IsQj3dzoXstvGLtwL58PwbuE97qVVl0Kw3qpCc6YMzKYWecS fssIfnt0wfr5EWyIwM8DgkPGD6FMMz/cfFZA2tZsXrTDi87DPnUne5FC3THfe5XNEje8Lwqp lho+Bbs8jcjo9ZBeBLqlyVkXxPdFMTd2lj5KqkCwRgbXZYgczgliHr5/YliS6Mt2JxWOthiA x6FgnAiPpaDx3U5sUrx3gthqzyd4GUO9c2xQ3hGbThywGC+FxLXgQkYtDpA0lVd5V7CbHylr KdKUKCUQQLVONhHcI6R1ptLOjkrPGTdjkeFJCgaGo36vnpUyyqBcPLuPVSgnNINUDTTQzTK8 7dDnd47ZOTRrmrD0qyvu94CYHS1XAPvlKEDdY9w/m6ZuxeMhFFOkLDJZr+Cztp6vEcswdZZ4 ACmyVvjQKj8LmaVpZL/cG24V1zVIsgmOHPnOF98TtS2VTZofqu+kOTdoCw0OBVvJuGRQu1qs xADIGeKgtWgW2taE8wgg1W26Ghqt4/xAIjP5IpC00VqzhAv0Ysv2V3uDjEwWjyNezQPpnOJA dmu5ttN4Jb/BmwQqK/b7N/wH+MUNzA+686ADAbUHF8B3Jt12BIU/GUmT0k1Ii1WcmxaqlmSP o9I9X8HIv0goQ84iaTw+Z8Jn5Y17ejX6lbq3/lzAGuSDVWLVpo941Sfd+tdS+N5+XKvsl1Al wU4P96NomzCiWXk9ds9ddWZcRrjDUv0rcd6vN0zOCypkBj2IZdGGomK5p4ZjdeMw9uTmjYqp robAJZ8jsxgHMEHTRXKZYtHIBuo9fK7i/925m14Jxiz4C1rNnTXO6i9y3oI9aJcDb6Ao+GBH tilp1H4onisnpRpqWa75M1MyPaUsnOPkAcwb3pH1TcKdj7iXn3JnzBm1X+XlM+kA24GwpEnz uTfSbjA+u9M7yE4ynaVFSsb/qiEU7zJit6BQJKG4j9QAib6hroJYS57vIJgww+ydD7Aj1rbG w+uJ7IJD0XsQ0fD7fhlJMus82OPRWdKoOdIlFesfpLXu5Ssu4G564/pUtS1SK74kQJI7F4Q7 unQtV2RXTpmoyJRfyP896TmJ/2IAnqUlFkfNAETL1WztNlPK0f5x+pnrKsBvL8k8ye/7oBtK l5wTcDCBNXIbrwU5L451CV/+3phLVwPTI8T1r2LWd0Jzc8XBKdD5uSWZ8i4KLIzvAEjnJ3T1 lvYzG9p67RDkkdOwxqZwGACbBzizSBUWTaSCayA/w/pJj6ui7vL+y6jTdkG6fdXcQaZ6EXI0 18hsNcTc9W5PdyYiiCpAqRKKYFjME6Ikk6Anxqcb+Rl5CfCpApM0TCbzbfvVzWLkZwH41wuT W0/7OAe2fLDs0eZG7YwQKxdTsTGzQc4tW/wY05w351lJbJhZ1VDBC/TCOf5yH294DDkE5KV/ UWZcQsqq8Uepiz+wbhOggnSugDiBt2tdJiUacNk9FhhhpER+/hQq4wAKiE+XMl62vWa63PvO TpPKuyzbqopOwSoi/nRrkiRagchk8PEeQ7+JLjjhjpMKOE7ig8r+RgPXStdtH/BYmJk/mtft De14Y9934QCz/NQ4JciXv91KMWJQg95VtLaVBBK6SvMVHUoq+c5QdrRBLFoAtcFlZWtVzdgY xf4g34+uOPn6/2yYFoEHnJ3x59XGbKGa1NF6tsC7KH1tbGRgPWCQjxfYUnpvT950eEw3nuDU bqvNPDHJYTMnkjG+tgbl11HUgGyaTnPMwfxI4qlFE1QPT4qO4nMvwNOv8L1D9BCpjnctO1mn svtdn3f7J6+E/G28Svbffk9zLKSPuywvPu3I8HcMjDAQyc8w+0QhW0x+CK3VOa7WY0uMemnm zu0sxbED7jFNiAFM0Oi/ry8oJAf3d732qKsEFjePyu1ifb7zLvIL8OPdOWIQWWwzzpwvGBUs EgUstMZaaE8d+oS3H8wVLDUXEeoB8qoFqah6qlcDiB+pUp6GnNeCxdgnHneZ5WjLb362YL1V LXoZq2q3pdJTD+XFIjo5DkwtaOByfRZSosLRMKX7Lpj7qT9FwkaZuAxe5xIAtE7EpuixvaBv 46M/VJ/0/ana+Yd7P88TlxJ41q39cRKm0iK6asmOpPdp5tUVcKQcsr8q9hzUxBEIuXmWs9fZ x2DSmQHjHVLyeLsu2xcdnn/Sv1JjmxDV/sMXoJABm6dM0uUILgiw6lFXiKOY17npKLn/WqD1 A9MrehBs+3a3k/kXcSfjBQOqhpfV9YhGoSJhFqb+2/DprJ8aJ/0P6hh02kWsKW+xb4xkDyJX eqn5IpxFpIWRNODUhXqFjLNHPMuwvoYhriL88qWQ8qb+aawEU2EsrQqvqG+PwRWPg7P8gAyG +VN0NsddNO4SJRU4e45ROJcaF7AqbtDlgdNgYevGZzoxuf3NUrWVnxGGGmoJbrQZWVJavGfB 1kyRT0f4fl6wBDbTOBNH1O2Ru5sEuOmeQojiXkg6F+L7Ejzt6W7iEWf639DZZz8WEBhB3vYM lQJ1mZXW+ler7uzL+QgBDAt6QebLwRE+hMuqWS8cQ/qCA9Dat+xMKy7cbHCJWOqiOj2P7XHg BLbB76UzQrEHAmBwGHNDetwIyPqe6sg1dFTNMzLUebD7VMDgaOyqgXnGsQPpH5h1rMT6ZC5f iV2wWsaasjKMKzLTR/C7LLFmIOD2nejv3d0ngr+DFruxvV3z0kxrQHT1Ba3Zrc3bME5GROuv ws21Hy1MtWi0eFe+kmSVBM6D0KhjPUCViiE46gPmifuDu+1ByWBgc2XoSPOPAe6PK+tLYZGV bedCjnkTOsrvOyqa7YFWO1qEeiSM0BRRyU522CCGSj/dlRCHneOVAgqxaoa9EMhcuDMHrhzT IWo1hl0rrJy4kjqWfgViYLNs0l2fh9vJ4nyO5t27lcfYAcRbcddyS+SZbc/y0Hv3uVIX2+Tq PSPRaBMvqcU1FxIg1obJsEz5anpZ1SfvUwcgXPsCYrAh1ZqtEk7k+ouvoKDCFge2A2x9qtvZ Fl2IbMObvcx8UZN8Iyq2rdO4MD3RTH+uZ4U01WrxWcGZgJp5q0zvva0YeJ5erxdB3V39uRP1 AxqTmhNgC2ADei+rvWlEX9VBOkwMuIkaECCyNoGbMUbP1LlS7UdqWeYKgPmE/qjqe7RaGAR/ axLgnZL7tPtHUx56pXLA4OuAitDBY4mthRIffJ0B5EU4ne0RPOXMGoaxI2eg/QR7WunaK8SL /vJ4t6LXtkaCY2ajFKqTo4gFudeBwqrlb15uGRqJM0ajmK2i+QSSh77TuCm4Tyx9vc6+9wez MMprMr41Wl+cbWJZDxJcHT7ddxcNeie8ELkMdyvIk4Cr80q22Nj7VHis1YFKxEUFZESfuHas gh5p0Xp17KJof4zFXN74w+PjdcM5p2bZu8U5n/nWZbhoYZHUOruzo64xtlpeWxrGbQknfMZP p05GJev6Xt2Hb0GYK1AeZb5wY8Vou27pN/incDsQc8LBZluYZ25vcFhV/ukGnE4h2CWmDKlH o5IwynDoI8cyo86NiztrqKtGFcJfBkXew4BsaCIC/H8mAFbN8VXSzLOz5u8cLyLcR/Bw4sPQ mo+VhOr1P/VbnpMXGLpcBjlpf6rUMNqw4J//gfYVrZTblhTH8uV2wASGQe3x02Hcc/l9TQpR rpMfzY5z0Z4Z+ioakt1EMfWqW36rFBxXC97b47HmQWEd33bNfDn0nokrA2A/0hdw0rmsqVxr gM2tHnObwU1ge/+sGcr/1Tq+Wts210uGhVyzXL0n5MyFSee7z/DG/gaGzWyNCz4+uLij+LvV a/E4UMuCDLoMOiWSE4d9+PWLh442m2O2uZhb7k06iwM4N9TDOpx1lpDwLRYA7M1MPyZHswVJ AhU5sdT0eRRvCU4KzD3Z6MRqv7dEOj9nES4IMqRhgXG6RKQrPWDu9gSBpXs+HxeBt9B6MUPz JK/KFVEfYEopKdEnahoCD9lDlBDSF52e3yyYtjseAlAyV7+wTrh9gP9Xyz/aTfYYQ+Jn8Tqg 7hjtxsxXDetELdhGLKq8nhpvr8VXK44nRLRrYE69876x4rnI8asFl8uHkGblmQ/ZsGnEzbmd lil+opQweKQ1OYBK3w3R25tZ3Squczqip3AXUpFwWq1nJUWXMz4Nl30kV2y3F6godwH3ZiPp okpTEEnfNMjQehtVOZnF6yv6F0rTi+AHOSjDORvENTTDhJdZZhQcRtUKmUM9g3QS7RhchoV9 VwFf3wzWpTx/PEeKXJj86UWLuU4MWvtCF6Ltdw2wPzyJ3fpdjtLD+IXwpUQfQDJ/3Rmo95Ga BW6PRFkYJa4nEv/M3GQL7LSpe7n59eFjSOd5X44k4c9ZbAEzpUoUvMMi8oXyqRxkZPVpVicS /bK7PwkdD/4NoY4Ao1gg8F7Wr9ciNKNt23rqdPrPS5GJeMz6DFmdtQb5oLP4HYXD28wsabwu yB0omDGVelYFkOrYR+jiRHOs2+dxVx7ErJMms2cBY8nteg9Ny7LSqpJP2X3kcDdj93uiQXC+ 6nHTcpQV+Sa8EoNI/cEPbJeUb9wZeKskWff0alTM7pCM8E1560nQpTNVGNtAV7H8RlnSb3qj VFkHOGhCfXkIUBNZfZP9bbOilEzfL1+8X8ZupAtUrsykQfPKfmlIj/2YSOE2ieosejqERq3s PdbClWEElwYkmLXoU7p/SMcZcHg8VlKaKbswp/+vbABRDk/vs+ywkkS/tDPAeEEoZltiQVDC bYtyOq5kTlcxjbC0MFSq29wj9iDHIWixb4k9lpAsnrWe1I1DeqiO5Vknuwi3czLxhH9yCBjL n133maAEKeTZdR4tE72jOrZwfQYKZDjvO7/chEfFpJiBPkBQvT+l4mRjC32TBaLMDxJENEOM t15CI9lB21AyWzbMloWpTit/otZ3K2l+Hgv02zgItqLqMHRdJmhfWGVSeu01wS/YSmzOozk3 l6U8FszU/pfDyZTGurQm+fccHTLshOq98WVVVnUgKaeHWpq36yFzy2mG0SABKVSR5yMKD3EP H6OYVl3QTepRSYj1fbThxX/ghUV6ellM4EeLtCU/eYuGA2P8kUnA9O/Ocx2me4ZT8z7H/W7C 6/bQ/B7yJynMqlEJ4fC7azJjlqZVV0xu6DdTIeoZFH5gvJcB9hEMO2nLfmKrAGolXH7Lh0iy ys6u3qNx/IEcxfadOfX6ZMppvHpmWwAY19ZeUKEfRTquOi8IGkAhTFdgNS3vMmLMiJNfDvbZ GTEddinUItg+/KfHOf6KDHHdGmoInsXagxd8U0n1BCahizTh+nUeBqEWip6V61R40WG939bl WRNgOi0cGE8q06Ey5eecCBHL/o53Ee4JL9TppcF22ABUaTqQmmbs2WIaPCqA/zz1ZHiQEZfY S89WVGjV/ghYZiyULwziLE06pfvD2vGxAR2Z+yAGya98XX5Gkb6ys9JbVRFNHXlF18fO5qGD HysmWPqR7X1nQBiHH7z62Y76/iB3DiRWR/j4u7IEtSwBrkQUwI/NySZ8S4A/QLZldWC3zU6L UKaAjpddWYufcpo7dfrtgervchE5ojiNp60KkhkBy/mw2ATjBszooq47I+Xax54tQCthYR5q RzE20LtstEVyZGy8/xYNlb7W9P/PUYYsmwTN4E+8HfVApzaXZC8k8w1bIiNHmac2w8W8QjdP Z3VQ65TrxZJeEK0h40ZJZcwQXupggDUJ50ugTRX6K0uyjGzw5rap8PND6u8ienn4hUcc5WcJ iXvvtnDDo7p+4nUhF8yv6hxhhYfGd/rIu97PmxjLfmN96Kyx6zHrSHL7Uct4VJah9r3UqnN9 DqHHtta10T1nSYY7gGVSIM69+WoxBrdxOoQ1IxWq8oCyQKQ3u4MB9bWV1Brgruk1HwJpFnKo B6A24WGbqcE7z3GeBD+DpJDm1IwpvqtzPua63vm20VFWrhYHpQaBoOMVQ092hq2xpUCedg4e k7obRfS/Sbd/BB0Cj8Wpc9xC3bABckFeRyoCxWT5fMd9b7KWI/+wvA+4wZPUHvyQXEyd0Zl4 6XHTD+CpJaIJ6cACdQuMJWXHrdrPzT2lIWRpt34HgzGqs/y1tGRfAZRf7caXmw3X4Es2U0hS TKLN7r1yXtl6O4dhBPUJtTGYx15izKku1UZvyzqRxv3W+cfb21635HEY6LD+8g3zNIxafrF1 FXcpI/o3fc6WhV65bg6gTzUxNj3Pvrs5hn449t9f1GESA6k0mKCsR41zPrRtSbrxPVvIA2jK sqxNbvyNI0qmcQRx1G6KOZCcrJprRgV1sHa4mZTMqUbgUqrHT+GAek8t6XlZW8+zK3ayQoMU AsoVtRBJ2DId8IxQMZKAu4T2fylBpuXyREayxs+kD0lCTZUG3Vrc7KMDvBzpqkb0R38/dpA/ ANyl+c5n+Y+P8zkrGAWe3t0zvLyGv93LQcB0waWnQvX/4Qqdo+IiMdMhkfCJUadC87j/KKCD GP3n/zlpx8+piPFrUtGuHsqVN4VoMcmvPovxR8ElVgb9Kf1O2fW2+pxC9CIK0hAgH9+RtSgy 51/BdZxZloaljpcwvtpvJ0qetR74Vh0J+7Y62EkZni3pnGiIkVklZpRom0PJA0lnymc76CY+ XmFDoj7CsDeZihHx6FhWfN2RSybi5oNEqUX8nvn2Av8y+vSFIERU7WmwFSUjsG7YAFiW4W/f vhfr+LqJIjYjScaQAVDZIm7fxWxDWK0iMcIl0fJeoNs8+9PgCivpl027RyPexLkobqTKU5Kn YsxABgOZSg5rIo8V5CLoT77BZN+JxAFcHkS0DWCpLXXw1CPUnEgn4U0YF4M8V5OMZHVPVDFp 7eCt6eRXSJ63baJyauZMviZWxXZPWyc/ljFxHBm8e97ReCc18ZVmCJmi+PBufVJkNmzH6HtN XtuznQgAn3DDn++kCHx/sW5QFg2mL6M3jMLpcB05jFoRCknUhV2Y8ZHRqpNwjBnxWt23Nyih 9shAuu6yIBnAmz7b/DuXXNH48sUEzdRXYA4g7f1ROZ1WSTUD370sdERpM1CU8KIUek6NPNpc S60uMRJULXTY+Km3QCA9EsdTjrNC1PUcuEUcXT4KjF2KMh0GTrS1mj//89cxAv7HYCFtjiGX g/KAUuQ5jZSa3OlcTC5xFQ0TU/4cUlgx5gjmKv6419X9UURFaG7OEemTJPOpCPHXjzuw8ODX I31852NoC2fiy6iKIB+0d43iiHyZhHB/DcDTLJNfCmfjvHT93WPSOWGm/Ndrs0+gQsSDNMrT Wi4IABi3Fmvq1/lhQPhzlKDJVhn0Th4t9xNMN0u0zGXkNoE9A7pyMAKYaTpWmjPStMPG58CK lBvR38OtfTyOY3IGyezaSCpcUP80nnD5MfCiPWU1eLzRQWRcAo085THYb1hsUH/tgr0zfP7n dE3hEWN+rc/RO5ldrgRaLT+TYSn607Hi/rEQmaQMNPL02MRDpLSRYglW1WCcziImjcDr7/oY fz4FKPan5kq7EgwoTy7HSNgabV1Ml+nwDmqWbuPOflBnsJ3FNk3iXbxon9fF/Bck0r7d4dJn GeQ8CWtmPhyT9/gIAEhpWtm+l+ksF8M5eMBeYUQiiJRevB1nEhl80pIngLP5qjTf1U8kXuOh wiBb7397DO5HZfSJ6ai20/ZceHjdbOZio9L5HGFmdElj45n0eKroJTt8JJW54JEzk7Ye7zmZ WuhTYCak+YXsq5755O9y01O8VY2ZazfXr3yv+sl9BnQ0zXsQN5JRfl2HnuM/CoYQFoPRbe9G fCkJP3hIVw4M4+IC3pzZ26sx6r6fIc17LKESnxafu1vCc7bT6xYYaWttBnULIjo8KACogl10 SSG+KFXjvgl43KJMTVvc/3RWuGkE0m9PVtLmAleTWD3X8ucXUuhnvEXSTq+Qy4evS57K6Itl ZKVtaju3GQ5V45Hx2vCw5ClOnO08RbiSegKCMe+OShI6BgvxIG1l0o1DjyBY7E46Cx7e8LlN PRWPNKB/xAuZsiMwGqbeR537rboRyZ72P0W5P1XMZHfaiy8gEJhkhXd+vr26fiVO9mQyzH7b n7NWMArPznH6THQiOTMwya7qE8YHVxd3sVB2I1cl6JZw7F//7aJ0K3/HF9hSj0MNpcWfZsTb 9D3EcCx1KNszxQnhc7sTTvJxpwNX5tC15fzOCqL2VWi4r4j+lulzF2+Z8tsfYrv9Y9/VLiUg 8gchwLeSnOgClrJN7JEovMrmNaCxub7BnwwRP5heOAX2rLRUDkNigZQUcS76YycIzA2cTNA8 xENRbZsxzwhUm/jZZHk5PyTN5BHIdOITfF8bCE9A9i+SsuIBCLM628pjbf9j2+kIDzmRvVB9 MY7sLgF2dxDXctZqRN4IBlIfbdz7iRnjK972YGNB3wncutwPoXgDhIwVtR+zui2GaOxSh3KJ oT5WGMfgTtDhE2oUA0FC7h5M4fCnuiwz2luxsSHFcVPAMC6HvLMmDYY3J3K5A+bQsyVmx6an +ZCi2n37FLJgMu3cIPelXA9ZNejTNHnqiV6DmjmW4O724tWpaOv5DWP+JOXe3PssVLU6yAfj 49aSmbe17NfB64Mfnh8wmzydhNuVP16efF/Fm7Ul8q8mcsEhb/P3paaXgL9V36ztutaI5JiU MGJ3Lhqnbho33Qkvol73OEC1aasPIDOHQmL1XtFXt+EIz7vMn5qxEQVTzO9DA5UGT5wSOyon mccoD4M88rHnFHMGPe2uM9Fn0HoNE/LPg/ABmPq3pt7KNw/vKc4MbL08LySSBb86NrImLsUH KlPzUsxovevpk6DcXv+jMi0hgjNZt/JgWL8KsbXjyt+ECdu5IN1mKYNIC9O9dwtr7mprwL81 vJpgMRiktrPHvQFGn23NhFb3f6EaSqs9IjJFkXVTAvoFC3xlD/RXTA/ok6vXem7m5qpheg7E BaGrBtcgpsQWfk9qIwtJPWVmzbVjpnzfKy/qBXXGWSeHrIhFP4HCCbV3Zt75KMIdPqJoo/pG Gb0VYOrY1HrtSIU6VQA+wGPRfAjtWV2hY3JZ8WyEQIZ/0pn72/yWWEVrWnzBY+yZiBU/6R8t xeqnIRLeVAhEojcUd6K8dZ6cSuX0fH1Hwb2M8W6gHYpeXYibLH5rvfBNOwErgUGCIeXVkIXp 7tbOqWuPYsA32ZyGt4Cgo/C8jsSNz2P8ftW8zibWnW0vU4H19iPSE4ZJj3fu+JZbQ3vkxNu0 cdB5PtRTrG/3BzOCpq4SzBX35VQy2vqJoY5PhZBUmOVpB4GRbFGJ9XI6rxW6BdFcL9pUrLkc JfbOL2oUQIElaYUv/W21rM2cJ+W3fIFRY1cQZfuEd2YzbrJiDWy6kdPeho0nR8qwQhM9N/Ft 1pGDe6UooCzHXox4ukN0db1jIPXTh0Xm2JS6cD+SPyDzOYo9MnJsiv/uUb8BLgoqPAXPy1NO b+mH3hgCSuuIerXuuG2OQPnidot2hc9icAYJH2vS6ro6TivqpQ7TkkaBsxBEQ9phKZs95aMw 7om4aeDVGue+aoyIfgZBqVtoOpF0tkY2T4IqG6ZJHTUvy6Ag99U4aX3X1EYS0Lc4L9Kstk/u MncYgR3LqLXV3Jx0SM730RJHx8JPc+TzxiuCZPneBPWy+ZX9npSxc7fZhKbrCJeHc+zc1v9w RCJENlCHFiMZ5+7LoTLYFiYOH0ee3xQaIag07peba0xJigB7QCaTutE05O1zY8bOJw88sYMV +ZXMMD32Hg9lgYZkzDA/wGMoFAIB7MYNTMmqHE6Lq9pHbaPcpWyma24g6jCYx/5xGt7QRLQx 2uLFJQgECQ85JOzKQ3el5JXyl6m8HI/UM6GZCFU8ZXyodWCNllvQi/2HKsw5xhoi3iavbmrw lG0EMexQAFp9HogpzPzzfxQr8LTxivGDic/xfzwYIzCK0W6UEaaD48lfyPnQGwECgYVbLmFK MKmqV8+q+WpdVWvDFbLsTtPlmNdmCalneTsFLTHMh3/cIM4BXvLd+8uUrsc4wrkQYYqIoBep ZgBX92ZEnBN2AmRorYcmlU26moa+GQJZHme8OYPGrRl1oMgf2ucAjgYbWqR4C9tJeeO7eEb2 jWClHmTgjbHe/mKwMQILMGGaCNVxq/fB87PO60BST1g+/dsvZPc62mKYBAtf1a3Kt+o7Yit7 TGRb9Hs/Cq+y8nMrTAqYN9rC6nb0lSAOyLYIHRp3lpbhMajCuapYTZffn/yuvSZ4w9t6wHJ0 TMOFYKrfyaJEX+5McflKA+pARmYVS9FumUS8Ogjkwh15snWE9gBDzsU9CYkhQ6FnraNWIfuj IYdIOgNCY0/tn2qBtAGtfP3SZf3IWz3o/YbC2b0mpnEv+OdFHMn7BNhq3N4CFKBUXNxmHBBe iA06y5zBuC0otv1vkW9FDSgJqHwTamgM4663ihCbMj1LFXxq5u0GdKGhC/VzvBdKdmp3hdB0 D/YfCIKcz507XocKUOYptHG8ySzSw1CeHvzMqH6s9RJdUr/U94YQW/WLVt5R2IMQ9hIha7m6 xg52tladwBoGL5l67KKI9UIBrpvPbd4F6qMNBsd6gIE1Y54CtGRNI9t67JwXzCRNM+qlaiMM aNpcT1TQfcREbaMkcbUTxLUplp1nzeNn4FGIWAoIUnAOyvK69xzraYCt0Ss4CAH6FTxpqBpf CYN2AhxzbL3PpKVrxt2KBigLDiIP9Kc65EcQmUKUrQdhAYIjQCKmLoZoRNUiGIBqDTNbR4Hi vW99Hx87DeuTqL7G6lQoqaQlc68v55uD/2JuBCUIH9kuFS0hifqORcTtGZa6/q+kEw5Qgqg9 UemtmXSbzY2AK1LbFVl7ux8Vm0cj9FXQjoG174zgNxbS/kAjsDnFsgfoKFvYUqEaiGLEBpU6 cDXX8ezhfs5YksJePsAqTkTYZZypPWmOCZYkqOUn4uR1ftdojhS2JA8dH+pnV2AtcQ29NU+V UF1jExgPxTjGNiiJ8p3hfw9TDk6xHQKtjZcYOlYw73b3fuyiTH3fmpaFfYan1OdPRyE5YlC4 T2O83dX/Q8OWZfPfgRSkOSz7NTEHjtn17ZR/ZOUZNqYRGc8fiOM+F62BpESEnUDbGb7ginoN V3wiwrqAOjRtWCKVgQJEirJU20aYRJRxzNhJP8LQAP1CtS97lY8lWi6T16qA/tPcuQVRG5a1 Qa/RhJnXqY3KdfFsWn4sW1Q1FWT/TAmn3ss4IeEYtB4JxQ1ztqRevTQb8H0lP8xUUgpsUT3V +SJvXrbF1E9HLDCar5s4U6mJrOXjDXsHQDzHv10WJ0nlrMWL4nCWPglgC6iS2D51jKKOo8Fp Cm/Z+2y6FWtG4QorhKt6Z8HO/zvBStgv5h6966lvPSr7fHzEH4e77vVlpqtmRpNVEzEABugJ FqPpuX4B9QWdwOJGCkTgMmrMKzeeyUtHLt3yYglYTaY46ZKLNiNxIdL/iSgdq8o8SBy0ZWyT Qx6LOcVQumOqLnqEzi/WcIuvN79flTu1qExZtybjt2EPwq4jbufk687+G3CkfY0kscr0VJPw Hl1s9VYbeiSLHTvuCNU+/aWBDsKCII185clRqnWKWI2rQ2D/J4Pz06Cfp1w3mzon8VKCgwVh LatEWA6SJUxQmkS+W/Hf7FSyUAiffpQLl4krf5eackDbolFiAEyPVCCS6g4VQ4IVl8biKVk5 30VsTWCo/dDqCU+tkoDCNNnOaWw3iYp/oMxEAkh3yWyO1LyUdiDhh87CYZ8+jEt6vbgbIeHO h2WIsR1VDaeC8vcAe+jO7hAyWmKEx2BVkzWuXDaw1GxIZeiDxsdq94KWb1WaV/M5zlr4h8+I AOP1qVUwDQ+gzerNtehwCFfHeMmn6OxzVfJZyr4s80oEZf/GEEWFj2c+zG3EyMlX8yWF1nEr 5UjuAMY2dPkJNd5vFVuvwVhdjFKWYs++bbS3TpBr9jKP7rrGxGPmc9u7l0lC5L5WB95bz6Nb r6C10f7tx+aAbOvwYlOZT84EP7C8aHXQbE2EH4HkMzV7QZvapcS6qRiXkIe9NOjVxvAroF2m w+6KDVckT0yvbq/eKdAp+nRdOA0cOqSfvhP//kmUOE1muLjlWE2i02+v9B0uhs1Xghp1w8/y uj5r8IfGZG6K3wcjslMmqbr4JVItxVMhCNaT0NWh3mArtKxakwzJIh65WGOaJevVwHfZketR 7DRKoyCvR9ZvxMPLXr+nlRwJK35JemIHbG5pYwP74WCWJxAkkCZtMCBFuH5ITG2XnmFE+cz1 xXaG7+v2rqcK8Wp5fUcPidXxMkSiXhrLKMpjX02KLFSKt8iYLrfZOuPp8N53W8ptPJRL8kj2 Pn76OkWNyGt4kY1+QuPuR5groKTSzj0e5M4eMabYHBu/rmjzNoWyocTHKOwOkkkyvvwn10Tb GzI5ktx+rPzbR4ziIzF7gD6VKXjl7ok12p0aW5GqE0u3Ka4aFcABesJhPGn/+d49/uitTJIZ 1Yvy+6u1I+mI2mZtozuPz6h1Nklp6S7cIqSJSfo5Cezg8Yhsfp2rjzTYUGuLf0v6+fpz8ojM 2Wss2gpUAa9qMnrJc0zYEu924aia5o7nl74dxSaa6VBbnTiABWRJ99ivtpsrwDR4gdO6PZ/D al5+mKAE2iZpibTWD1xlA/cxMj2DhzGy4s17F+G/yRT4oJ3sxHiEFWieA8GbwxERD2W3korS W5ezSKKJTVIqXB+9UR+3zY97TIb8k0iKx8Eki0tBcj6Hgeb3O0lkrS0RN9c+63KmdKdF2d99 CcO5uXhou3wmtdrBVsrAaQXzPkIdldju2bGZOkRBaTz/SuZTbUWJB4/3Cswd61w6bkaaztGc Tl2B/wm+mpC8JiEMsqZ54KvYTnviTfLnCqFftnWjNge3K53L/qRKP02Dik1WtBEkEdhkVgkA +99YX9wkIlyeSe6/DWXLeLwFUJ7zUBq+EFhYuyHVwoo3VowMMD/3IZoH+WgPPyTQ/Ksqu7MU jzH4N4uYUPui0XLqjcYL6fhtPisrpfPYvqLW6TmCUYv+tYWHwC0UTteo4wEgqkoiZD9DVNik Vxh6QJkVTRnQ2MnP0gUwTqdMGGFNqgdySr3ZOUs0hCg3UpdWIpQFbvzzTHWQG0cqhT20NH9S 8q7DEdtSr4nxKZ3mhzYCBy2JMbds76e/BAesZaoWPnTS5BZ9dFlmDKxW8pCaI4bIn0LCp6dp EtxfK1mhhFbzkFBIH02xAX+pWFj+HQvR3InQnavt99N5BqPSGLZB+9gWHr/4oCRi/83inSO1 2FNpZmQBvNzkHnXlmlP576qKBAjwwN8Gj4yQcAiM5DGoRg9pVQcOjNPWTfFxYyY5sBKARQFe zZJmg7vLcesfsx4OP29hu1lYgtPyBh/6cZW17DNyII2wMWKdmzZkw+QxertT8LqjPV9uTCoN tag6ATwLFwUqCfIcYMZi/URfon94baafP7dlHp8uyY8cV6c+doIiNLtawQpxW+9gmLGqH44V vNnDlUv2NzfaVvbYJXNlnbg5hy7YpsHzqebgSetrujYVJDaAA2tgJvJZWn4RQx2e6K30DPy8 aBNwYUZY4gRicx+5w1V/ecCNsMUKvWJR8hRIlZsA2vVod6QPFTayLYIuRj0oluFCMY1QSIIK fvSM2IK7d+u9KTooxce6RwIafUIyOOTLdugyWtUfCeld7kkY/0FyHOlFvNRp+ntl6LLK13md KKur89jvBA8EPfMZyaYbqgQKqqBWYwuUJg05fNm9wSFConq14IFRgxqWkf7qeXU1ErFbdfJf fEV1mL6D68OGQeNm6R/rMhuF9pT9Pu54r38CHOJAhcFhUg8vmtmh9lrS5Qynzp4BcFqUJ5i4 9GBE5GCVsUpyX27y49SZZZwQej72SzIUxhqbHtY+B47k+PZ0ttRPsKbMJCf5aX1Gz3u66w67 bE69CX9cgtiSbVyXB0YRf4aeleidAb7v0X0h/CnQXjm2Y6pH/g5mVorH/K18f7WsccxuSNwm +xne7hrrRVdsm2kfEwIZnYdg2mpfEyWDk9JXFqTa4wxPa8WUW0/MkkLzuSTdYpyTNTIQl6Lz PiJbtQNvt1tkKzV/my/9M3vDMuBpF3rIAJZT005JY8uQF+GiH0Yyqjrkfs3mWF9Obct8uphF /m+ZKR7ZuSCX7EU6YJf57rfclG23gkp5iSGPZvnjJEcnh84UYAQkzVsGJbw8G57mVGvk9xTF RQXauLIBIIpPtjUsMCF3BxmDoUmjBiZwUQvr3K42tYQ4lt3hLpuuMtT3o1iGRjq9646wWZOa lBg9NN9NP230CUeVQT/nCDO8MWESIwWH4zjYGYRwc22pXjCXLOcQfku7pgmD/slqIjCULCcG CZcB85g7fVaJNV50XVJn8eOMGoBLa4i7mdRwnm33Er3ZXtsnWf3u3JWGTalvGADxCl6H/zl2 i1T8eFiUZz8AsZ2ZMadvJeygbPomqX/z2HZtoxsP5lgIxpsjAjZrBlpBRBl+1Y3U/V+8XVlu QnDcBygXzTh4VelYVR9AQVRb4wnCGaOI5eMaiWJrxLweP7482Kr0nqt5KL9gJQVGUEVRYFPH VNPxZhl2Hd+/6jH+g+E2dSuwF1mv2nBrRSWmTbZQC/dN6zB4/e2BaRz4tL6gRSVdzXN1PSZC VSXVwG1qLe4WqAQekucDUZCC7Yjj8cVYx2z/fBDPLcMxntOCOYqyL9qV4zRD5U2P3Rpe8jBt gx4411G6Io3eSO9e2fniQIKSodCVAWzlszF2DLU1HzregHRWw6RrvU0T2+TwvN9XgkJi1Wa6 DMu3H0YO+TsXEeamG4J4+k+ww8UMgUc52mf9gxnOuJchLQelOV3CMRO7ehKXMBrEFPG/fXg7 culpixLw83eCUI/MyUGykccD+9lZHtCDufXqAQChQEr3a8uoNJwvA3FYcNi8J0yoES/B/kUC 7ZSzcQYrlAdv3dD21l37Fj1m4ZiHGyIBt6yBgcJtU2U9P9jG4vgiO2X/HDpjzN+5HIq2of2b ccMMRs9R0ZE/q4tc7E5phTDQfTu3KE8xXiWH70fRj7kR4jyp1YByJNr04zh0gSFoxfm7YOgw OnRy3cAWMAtVZUCJBm+BxYraYT2tcOnr7N2wvcUGOvZpbrg+pY0AH+VWI0IvGonspuB+TxRp 7y+xhdRRz5RZ1o7mPmu2VVNJysl54d9SZqk02QMe/e+Ii58HivVVKlI1R5qgHS3VWkeQPTmf t1XFMVXPZ2lID8n2z2rjMPPE5NQQw1ZMOd3Wo9JYhVg87cfbFHQf0YZ93V227txxqnHqhsBH TVY63MtyB6rZ/G3q8XOEnrz0B8jElDCxOl1c+bl6E9Zswc7yVm77+8ZGTQ/EzgNZwAuGQ5gM LWpW7pSI4wx4T7xKLP0tTCmNG8TGw7Kv8iFU1xspeF81yW4fFfwNtVYo5p9c4CmXE3jBjWHS nKlk4EmmZePWVY2OrtuJ7rlnqDxJd7sz60eogbPmILNJaQ0emxXJ81cByZS9YiyU3FDnz9Yd VAVPq4wJ62jT2fGFg2qMuP4b3o/J+4nCV3JwGhNGs3hv9mS+ZKB8BbzgtfAsLTEM2j/zxBrq lx7bWSHJaVu+YLUasfdKb2k41KvCiMayVhoj4zQhQVpw1GPd2K7l8qyA23bWwIvFDi12zfRt wNvFILSMqyiJSHNdmIpdG3Bp4rxRdkLsIgBb/fq1nARkRFenTYFLLqA/Yek/aGFAme86rDiv NmB2wofa30EBjyhAmFYJk1s8smIjZr6ricXgVPQuY6Kk2rf+tbSBFjgMScHu6aicvSg2RBeM odaHIQnsN+ugYG1GPs2zjECICPJwq2Kr+qOSLXkEm4hlNmpB3KCa16MhnYqtjelE9IyoccVB w2YYU7jUP8CMsW7Dbk2RrniOF2+4lb/Lo5b3e1yULqbRkW5aQXT7wMz6RH73SoUri2ZA1DLb w+yBJBRJSSkYYMdUHtAI1MsVF9CW5HyDIEqbHc6B0aRmTteyuD4t6Mwc53EYQtely/6ZqsKO x6hYsjr6azGJ4yCTObp1N0NbwmU6uaIZ/FzYgeqHpT75bHAwMLTnj+0diHLZ+ln6Wpn26jej yddjxEIsDD0z/6iELIme3Yw8maQxpG6viF5W4PcAtf0cFUYgnMzvWuOGnt7Ll9LF4nPeDkFh +8RPz9LyV/xqU6F4vwc7m8i+qzZEf2qOpkeFF/yUHxz4Zb0aDIP5X7P0VJUu1P1JqYdZ/I91 jKQHK5mSuh5ISPZIb399YrJqo+tSgphjiDEEDuFukeHvQqpCjLbtpab1UZ3GWIPIieS3Z7Rn hDiq37kyj4NnflqYX+rqq0wL+POFk3ppQkTqR8TQmAI6roVEyCX7js7iF6fFI8rzMF0F/LBT kWYXygIBWquWRw6SJqdPUAOQSH5PRRhxdNK1EK81+FWjU0oKDswr4JHqFG6SA/EAzuvUjMHU IZzcPaWfk51iSts8E11rfSqzy6hCT0zakMx+nsWVEMZN6XNZlcpFfG67+p0IkUSF2NLd2YP8 xivZmeEvy7pDuynQ+dkG1J/uIKqoaYPyBdZmhrvnsBiks83Weg269quYWzatG+0cEbkEIjF8 eB/MK4N1qItIT6P9ALFjvWYqhoNuiB0HM9azccIwzvXoWad+peQsLNi4J3QXdHjVpgTr2MYa rr+Gm7BCDad9PYZjscpVty1tLBKZjwesELMQTgKA4EormuQfS7l910dccT6Fo3MuL5xH4T8J GCSYHm8bihBraTmMYIFyDLJg+B5qkQDmvIdyMFLCc1PrvGqURTLj41cVAJBdcW718/MNdF/l SAB+zUeUmzayl18TG+AJZzOzWU2kAKpfdcoqyIcMqECCMrgW4fjZ+c+MvlTG8iZU8pUb44Mr KOMq/RLTvVTBmVPl90anhAk+aN+KY+ugpX1ZZdLFHqg0mLQIlQlQyrJhH9/e/RCEKRrKwaf5 CIUb45n+FopS6sVvMrNyrlKfIoPk4Z6jDG6LwyQ7l4HX8qWSWeRwSRgIXzNiFRHjRvIwhTHo l9SeN4x4QEdJtbT3nV8iF3Hm10+SfPxCuH+4hIvCtowH5B2PLhUd2AsA6zw5zqTyeVzdpzXU jmcLyW87lgx5jMrC5EXO5rWel0RLMgTrIbwDjJcmVakLGRk9oul/lsggaVYTIrxjLg+fvVok rfOuWxmZdGPxo+m9pEL5S8pEH5ymhp1k77jp2gofoOsTGmyAOSLvO2N7J3F7yYgTtAHER/sr l2fuc0Oe1M7zErvzHuzB+E0G2X1x+plQifCU4ukUGrnSCqvypWCW2vWnHy4Sia1ng7E26bnl /4WCryv3Exq19Utl0e30eTc6buQKU6x8I3ffi/nq6Q989XsS05gabWyEWTD9rOQ8kV7ZGD7S xVg5brNEDA5wDchShpYg4D5BC6qxvNdcYek9090GSoibgHLKaQbDudBSJNOvB6yqG79zeM52 UVUmjPqF5yD5wwWXY/xunbn/5oO0/5l8FuDgzq6qq2z+UmHMOBeypfKif7s05MEEHV7Ocq93 oeKO+4sxTtxDAm/7nRlrzIeQJlPNKaGpuxCF26yEi6S1dzXALA9ESmKs46/25oz7lHnZ0IKW y2xE16c5vnSrgD/4NuYClICDCpiGKqTG2QoBq93kzfBCf9OlWEE3Y1lHuFk9y7e2nJm9YXFY wugOX9Uxr+4oeTQ0Kd+bwbks0j9V5g9RZ0JPmZyNG0Z7ELv296Uj0RO8GdaARdEwXWYc1X1u V9AZgskIwgtgub4N17WNbXuW1xAolbLN3Zstpojva8zEdob1G2RBm7RO8eQe2MULjXkKjLJY Fg/KdR+OmBXah0UvpGONS1Q0uHfxVsZPKcsL7vASq374od8wH6knVW7JTv8PMqCqMLROAFpB yaSSUjRJ9elx4uUIGTLiKB4RAgiUVAYUzP/eKuVVZp8raQJQOHEPFF6Rtv2DEZwhvz7Jsjza fGh159i3HbkBMCCdyFXK903KC3YyCVki5zhVE/s144SHXhTD2kttxj/OPgb68z9RkyGuC5Ax JgeC9oxZvgoVJFMavpQXrJ2ggVccOzvp5dZRNaoVqubuKmOuQ98Q9KDXbqHiqi6r+gf28b92 Fr4UgTx7lQHMnHDk2AM3WtJ3nB7tJeJm7mzgLTCAJNaIXyGT5DKqmE6wemdj8AmWYVK5H+fU lw4pXUOgx0/Q6uwP4jDPDN6rRd7M8YK/CW39j3qoYzFXcbsWov6SKexJH+kk2zvKGgR43eNS 2spEazDRf7fehB/zkFAdhMdWd37IzDjEtZ6w/qvxPVNM7bB4qN0aClS/rmgqd+hExwdqgMLw 9e3vUxXroP25viRIhEavyh0H/rYDHH7xVhXEwxqM2pmyHXJvW2vDf3a0N3T31AhV+B6M7vET GPzglhtbwjEe9TPxJT0mqrGp6AObXXspxZ8k1CfeVyEGKYhX74HgTmfwAjhV2klQlSplOOF8 3soxxAG5bcGQEfs7x7I/gpRxTkjcP4RLw09ZD6MkU6rWGx+PNXRADxR9P0MrpiZg5VMlfBkt dDFggdEhsgpnV/rrruiBSeCqmPRukEntiz91s4o3qHqBthsTaYca8gT8TtKGwSHFsrTVlKyx 74hcGuhW+fZf5W9HO+Gd57AHxXxOEEtEFcp08XAGAiQs6/dbAL078s9rYq/bThPm9sD8irCv fLP82+MU93Ddqu/sxHD6dNeYPaNvbarRPTIqij12H71TyubjwSYt7yQXOK8jufYRSKoHSXW7 DV90H4w2tN+UpdWe3pzHYpesCBDQ9Qd2NpnTOwQxMgfY+xQ3UcvQyABngJgE1BwyRA0B3qrt rV/bE1u4GHjI0BmgP2v22vKVgD3cbHiGRD2mHHmW5NadrV4qkA50HCyoBwq/ybz/9+IYybeJ 3OsvRQsnSH6wU/NpYbACGZAH0muiL0lNJQ1a6zM1Y+zdgIjedevgCKZOeSR7AjIh4GXeo0wQ RC6UfIYJsebm3J+rnJJLaJpsK7geLRGFwCbY5X8gqzPZO//yLV/LwBYJyWpAOATYbTpKy22u MxB2ZB20c2IUiFpYkgaPryTPCBiBbebw+h+YRRSSQAIAcUZG/J0xGAjAEgOa1u8Mz0GIinLQ uBmTYIAxYGDbtVJUuMIOwPcN+TtBToHAOyOOIoCwd1pERMk0+gEJJAjTGNOOFaQamwMFx3+1 eLlasox877w3IElbAAc3JuOI2+zM6TRx0K+EvoozGf1tIcB02U1oucB8kRJCxzr7hRvTHMgb /kQ0tjlYY0PjN9Td1hccRd8fBX7cJWUTx83uNTBlQjcFsDOoTBmU84LSjBYv0Ut/WkKxYTTF bq3ccC8EvsOpCMlg3ZNtvXM+rc5qi6kWNcm0F6o13icAYGBKcG0x9NVAijRpkgagYRWkcopB NQlSVF944HzFfqBkP42E4SAHCEbntkfhIIXviQrf5NFbFbV4Yz2SNHDMhYCqnVSaqWqJLrw1 Z/z0vmNJIe7eUU73p3xuaDKt+EtAGwea517EWlVVfB44m//cbEQL4+1HNzsNuUImxhDCtu7k qcVpsRB5ilL++b4BuP5cl1tiKFOzznlmliDK62/tNvAtVmvSqQ9OK5eOdZUZw6wNeIKNeTNK 9uyO4kPBd6AR/gJkY/po+A90Y4VsPZf3aYFQMeB5DRdEjtS3LSLSYrsIqFuHhFDEnzZVro3Q SP3Qr8hZr+q9a0vMXMn14uJFGYx3zBB+Gea/q+akW/GEu0mFGAgKDoL/Cb6ZPaAyRaQaUEFi T9oyumYzmJMT6sjYvT+lNRPeAs3d8BFHCNLcuF0i4xhifuFnm4iJx2ckGzLnjjsUSAHMy+4A mex52AdRnoAjuQzq622Y0gWXuNozN1K5LBHd9D4fartOsWFa3nHCVrJFo0kIU9CmWySOFyNu CxOvLY+py9yBi4MVf9n5RvgR1a5NmHFBWtvaG1uLXJGDCtuSXK1DSJ9dm3qmAS3HHZJiyXH+ bCt77I7HGz4/CSgYI3AqVsZVgmbjJRbJWBk/dsvZc+7fUMHWq0cCcgB2MJKqI7uKHyfPmSyV GWr1jHHmA9DXxZNfUisHlTLyoW5dwbZRanv+vJXN/zjWAPWmB3F/Bipzg2i2H0+M0cD22CT/ rQrgGS9aoAVZOG8QaQyIktz29OGONv+wcGRP0K9nWSK7fUN4FIo4t803KCm970sDj6Svjxyf dn1lSymRBTVlcfJUWeLEcBsFzDNVO6B+31UoFSwUbeRVtit9MGttfuWuzURU0HtuDWuidIwT yvMPpLkEF6lMNQU2GAxSLmtNCCJKeEXh+jTVXPHXjFsxJVLtJkyPlG2JK4W1si/u+ytQXOld Cfc7+YNOusHWW+6XYRHLpS98YE9MMbnV94rrLgV1S8Nh8EMXzLBOAJCtelAQV88kN8paxYhl iPkG+qi6NAcxtpqEJhqiHXhWssA8xfAXnsl1gPiM9+72vUwR+biMFhQ1aLTOthBqQtd0AXGB RtjJCIah8SVO4TQifZ11aLvV5G/YN8g4j/LV6hxXrF6Vi7WbHXuX3BoXHB8dmzHIy3I47EB5 m1Tv1aOpAHGG5LW8qZxE22L9r+Rs/L6r5jWqHK/QV46tsMeiTu9CoKqi/CpsRobmuAyEsxjn fyWHNw2e4GgMcrzjy6ScciVqEJlpmzyDQYVmHNUxiirogZLGFQMz9No+PJT1X1YB0RXTN9L1 /g97OkYU8S9Ot3YmJw5fUxthLDE+a1Ixb2asbs4sT7ia07SUCzosMmR1z0iPPjuHABxpFGwj cpBc99KVZ+qgHfKuq6W8xCpyImrIU7h7t/mZPXs23I+0Grjz39jec7hxFrmeyE2lkh35I8Jd LECv1jrdqOhSnAmHQjJjzzgWg0u3MFGdGeWVtHbY8YR4aW2xzEi0yB4iwiFPp0InxpUPYGm0 HlvOV9muhZH610IlKwDv1TGJEVZ4bDEuKkqPNFMiolLKEGRLtCbetSWNQBA3+VxaxwDiz9yE V851IOYcRHsa5Zsxg8n03b0MOIfFgwjp1IBH2JLrFIHKXkXYbmb8e81pi3XIOv7gApawg655 B3GcWQ1a/ByM0TxPqFoKuFIY8PIf8yuqB2vitXK4FHeP1Po/Zuzhx4vYsjVD9fRUcXikPlMr 2l0aQirJB0YOjV1qJktAu/p5NccLTh8zOObUqVnu09HG20FXehjcPPjmVGoEBylN+x46jCBB gKbu/aKZsjtje678RbTdsuo/Pu7oZyVV5dxf25IvyCRLuJdH2YzHl+J0K0r9ZCrF5Z3R0T5p cK2NsSR2uTYD81m8Jb6uY2nR6vPMlLdX86rsVGagJACxgI1w7g+b/kuWp/eowsoat3jk7meI nWXoB9uFOZhYxhtb2LqJtr+u2zgXoKxLvrvPbzY1qnpH6b9x/yMgfoBCwXxIPlnBc39qqltF GQif8L7teM/dB5CpsYo7n7+I/fDQmGewxOqWUSyAHQ+ctuGFZU431uwG7ycFFMz4v4PRwg1z DbKeKPAQwI/UpJJV/jO8DjsIdKYFR8C6zMBX0vVwBdLXhSblV4l2KTBP43eIrNqHhL9Rafil Yo99oCFmG16hf8cO0r9WN1Xipn4YwURw8k8bodX/skIBYlPBzSNrBtoqf14jxkKlCbQ5LvW2 GfNXixEeQOzws8mhIls+ODldRPeIr6hmOG6VoesQX2wpywZWkFVj/UthbaFDJpg6W02TZa9G 4JN06o7ypTmwYR66dKb6txBcrOZxe2lITVKoAquq+u1gPNXq/CKhoT5hX6lP8TokH+oKNL/+ zD0gr6gnejMHZ6ixp3hW5oI3g+t2DhBBpvWP6UtLiiyG1Nw22i/12isin9oTQW4Kp2QQGErf 0Zsj8b+8XP/L3CVOQyB1XHk3v2/5ij/hAPH7hMA/EADmO4Bk/5vDI5QuobM9S9mQC/SdRLHH MV5ZYWFX+31/frvSaEL1cCZZyvjL/v/kF3fwyyr600tMgg/0u1NZoFj+itHN9t8bEROPsUTD Apfr4UYwt+d5+jrFT+XL4gY0kI9FRcotJZvPS+7fTSD8OYHMhNB7WtGn6TIgpCAB6HwwpCMW qdr6k4xPB+0TBwJXV31r92eb8ZKC/2czvaf+P+5VtEJZTUcjBzmhEQxU+91LWfOFP4QNVEpq q1qf7FfTI5tL8GinuS5Rx6cXkc3ZBPdfGOVGWo4IJWBfDF4WkFIZ0ouu6vdwOg7fy0Q78VRt Ah34heb+IwuJHyhYkRzPeM7R4b7JBlsM5NfSAWSdmwbtGGtARhWM1faEyCSmqITFqbqa18wJ /UUdQ5B8PzRsLESERnzs44WAas5iPKDXiecH4Mkc9rHSqp32u/9+1BAAvWAliiQHDWE2vPS0 Yetkq3jam8isc98fDMko94+S9glQDgzFB/XyfdcSur39ivM/i8Nb+jl8H5Dehd0JNO1833eZ QmeLw6xyxuCe5Dpx1hZ4XJxuoBwpRPaaQMSBllU+ees40pEw00IHvjbTtO3KraVQJ7f0nX1o DF5M6AELhD2OBCvsigZ89nP7LW2cD25fpVr+xoXr9XPkam+xX9vioGQALN4MCM81Zd5ef+K7 H0UHS8t1S8iOzlga9mCoU29n2F/kpftEosRIdBMUr6OzDPBZsgYU0q4HH0e7nuRY6HyV14IX QpJUrKKN45dM8jJOb9A/o+8S1FsweHBj9Lv+XG1p7+TpdqlbGUzDRqA72Y6aoitjvViidXot wAKQfZKAcRDhhKC2vmkfz/Gq19AOgHXNAQ/HvKHY+ljSn8+3XZ3buCrihdVdbNkacnjs6bp6 Cp7kqyDM8M9Tv2fbksu6ZClvDmP/mfh2dOBtt0vl3iBZWT72rSZzZ0sqOxV+yn9gmIB0kGHy BzhxNkl4YfdvDgwLgKOEKsYrtUfyJtN67xj27xWwyI6csCkpnHm9KnskB5ZkNvQW9/Ix1BFN nx221KSG4bnRC6WTsRKz7GuaNywN7yh2Hn7t6tcuXLKrNsw+CH1kvdZY1jv9h0J4RSWRRoN7 4aGYOBidEvsmlJUdtNA7FLldQElnbb8Acy9Xy2ySaPn48b4WizJLq/XYlH/2txohjMJA5N1S 5CxoHUyzFRdSIJIR3t3XYVc9C7fhW5MV+ijLwLZFpWNe9oZ+D/29UpFgbcvjGZexMI4OcGhE cSofE2dhUsq4/RzS+nFFLHynDfCFw7og0/9R62sW0n8S4IsQV9iLelemwuzaRzl12tfWuE5a vDGJNWN9ikS9QfZ2dmP33v0qunGzQACDy27NRL35wHsHlX9KFWgmFFldWgF0FsPpolTFsgF5 kG6NmgWUiKNnbm1fQGlL4G7vmtHInHGPaWnfHmCerQP1lPBILA3yRYuv6WG/a1wnL8CiC/9d XyX1gKHr0AnhNgkpsVIHTEphpi4mjlegjNXGl9vOwUznpfOJrDIp2LAW+sCxAzdwvMgHnBIw s2/hBxJHr/OCS/0B4TNJBnJpsJo/jlx3PsGHqQurMqDCm6VChpxLFvZqZpqnH9zUeVWroPyd jLd2YXbXvxM8VWSL+fmuVZu6+HvADMxVDOaCXaM7PKnAyQgzQ8AuOH8Y7Kg99KmpSlXT9vmf bCL1wxbiJGtGLh859WCeQN3zkvwAm+lQ1OWI4XlUie8cAPSbh0TWDS/H2PxB/b+BwSB+cyyl qFQK0X4RdbS9XhYlrDHsBAklW7mgDYWOlJhtQEj4WOETjJ9F6k85Y3sJvxQfZAaNFIeZSsvA nnQ7J7gr4qr4edFpM+kJO6sxEN7aoqVc7j2KyMvf1zDdJRKz7vE1zBawNvCj1SeWT+cAa8Yj 8SgvBsT5gaBQPeK02P/zpggZj0YZwh1fBNqcDrYb3KtXaGTa7HpEMBxjuL5NPNfFIDaCoBe+ Hp319jhywJ6bK5Lsi7rlCrhr7Z5Cj3nOJ1HHPVKeiWRh1ERMPB2ZL3+rKpJuNzMt8wrsmGBY FBkIPUOINrzhgFQBKwPLTDVd5gOjwJF8naPkozdi3lDRwBKfhS7JiRiSeXiShxQUXwHcyWLh r0DkEbTKQ8KyBqQGRP05/E9vczy9US8kKTVuvqT7i3gklPJT7HYtca56vAADMOJjXE9M2+wV k9SBpXxY8Q1pvZXKYL9mSyF9GyfY4Ikmurqy4lU31nrvFcvJ3cChKsJHmRiM9MyItsha7eLy W6OQm7Z7rv2kHbtI1b1a0S9qZTrESiSU5oWGgL0YHblL1tT788iy9b6+kYoebEhT01J8MVdh oJtVzoC3KnwGoH4ksTbwIcR6Vq2Gh11a8SLkq37Z0tGGyZpfG6MYkPOAuh+CgPBajEKJn7Ei k1xNuBrWudsJz3AtCpps3JByGrMZQ9QvLi+BngUa47LGd1wCTsJDNjirZNPBaBIsC9yqwfYi JdS9NHRZEXB26EOw2wp5M/t/qUTmT14/bGsGzewHXUIGDMffZrXDZYBj1NDRYd2p0XaJbPl4 KC8ceU8JI5WdUF13kDhyctZ/A79ZgSWJFGy3lepf4Rxdn2wiTaE7KbhgIJ953Qap3jxxjm7B V1MnNx6sNFR2WlAzSC20JHGEmCkZdG6NOE5c4jUksX9uWoWmk1Rsh4ZIPDHJyEq+gzLPWa2F GepuQ1LxRwDzC6tYm0YdKIFMI0eFncyi/Udeo/PFj4HsUqijwsMvcyxoxeS82cqbYvU5VhZQ PTInf1/0LdXY0fzwccQlDWG+FimpfRLQNqaf6h4WqHRhphEaepZmkLHtKjpbgOpZzH0YrN8X G6pDJ1GYVt+J9ccA5pFqIRp1ZoSCLxKLxtddx3FjjTNh+QpuFrD2Z+qWMd/XyvyFRNjo8dnV A5OwoFgNlvBxxdF7O7ad+CCtirm5YqefvjYl2X8PynjbfArmxz903j84mD9FLLmSxbi2zVRj FEq5z/iALlHXzNKlvFNZJEotg/SJAOAMR7G2zlz+IsEg6lCbkh/VuobrjxxuzY8xcq2/R04c 7b1RSskbQHjoF7vX+KxqVhZV+AaX3iVwlf500RPmyRY4pKH2XpiN5531fNna9QcPqTvuL+va fUBHzosLvP+X9WZgMqvF0gNE9nMr5Fpm/X6Mzv3TqOuHB9UBF7GlXWvt4tQJEdFpBjVcDfpN 5hy4kjinbsZWwjBhaBPS7Rdo26FYP2AUpAP8n3IBJvxN+/4T3+N4MUkoB+CaM6iIRKGzyCFG CgDNPtTRfCZQQT59tAGNLMCHRDrebX7apO3c3N5JmGAvQ5B+NvR1JZCuLyc21q4XDbUmNvDA 5yR05a1xsd0DdWrG5FxVJOTwiiniaBquN9D5c0n6Wze+CNseP+3mCF3g0WOViopH+FQsMiU6 G7uw/YJbcgsRdq4zbtQjg0lQaYGSXcPRtqM0Ux7BxXVFinkvxEoc9TrOWDoTfnv0JZtcEPY+ lwhUwzhlR0HpzuJQlsMoiC3Z5I+WePjf3BzO730LhiQ3AAnZzEauHTQULWNCaHC7alP2nyxv NYDKXtsgQuso0Q1xex36NCceaHSwKBu4U345Cz58bAWo8KYVNWOHkRYHxE+ThYSG2DPR1oUl 44K1+bIHHu1BsSiTchhmpT/kUVAGnQaAhleDJyyz0bxL8ETLSD+kSmvakZTgsbIwOE5AQkrA sj7rdF8Bzt2no0yZBOmZsfDMEDSjg0r6cqgE6NhAz8lPdKTPVM4xHfOPMQXPwyyqig8KFsZj TIelG6Kc6EtEwrECZSInROIy2DEhqV7CgpWJh/Ae12xaybbRFyGyAzYWq8HxILsCE5ey35W0 TmplZKlTSP9Gw5PRIQzwuFowQ+wnoUbZXUHBWb68D3WYZYtlPWKgcyEw6w+wLPeKZFDmBQyA C9W6IbigsdrQ9YE3gKIqTadliPWWO3aiXylqOo7Pd0zLT0tIxNTFIcSHwh6XCb23xdNUSEDi k0xQv8LpHg2iLY2z2hsHUeoznvBmQuep5RKqMtudMhZJy0R7BT5FHqJJ1aOmpWP/puGqCNii /y3mAYuBw5nCDODkhwoSfV4aIB0nfjXLSmjvZ6Ur/gqRfPOf//9uyr3CyqPAbWFrQIN3WlXf Dz6ibzUt7i1U3Xxndc4ft05YF8gX0SqWRZqATRv2PsmCuMPo2OzWmF1q8lnSqgvvRj+WtNSN ML+NgN0MkMUh6GuMC4tvz1dwQclmcOSN9VYl3Qi748q7WjUwv0XbdQ3251puIT0lpCZIV1N8 rYLLs5i4dkjvOA69Ft8dTEl0+9mXBp+VI+m11OkdmHZw/J4WWdCpAncQdSzv+zXuZTNk/PQ3 Q7QQe5TVsIuwmEh1L67Qj0xMNbRAeQNqS0thuX72Yt8T7Xw8x+f7qlDLXpshq9Ykqc8FNoTQ DyGN2CMa0JCFwveZNAre0Jua+u6LjknjCnJdBnmbfWMynJKsr8W/0PS7pM2NDysRPB4rGzYn T6JJxEM89MnfMCy2sZSq6+I0loAqotEO0nHvQkV/KbbSrhis/AR8NgxQWBHkGxyQjZ47yYgt xtmoo0eSUMwLyNTW9csXCFPde5xdWPTNuSD+9ps35mI+HYVE3+RJXNIXWtjJR8bTXRXQiLTm S3RBcQ4Lu8Gf2rPbuuWbP/UIfyCSJX5eegX8q20N7ERuS/EQ9IJtgM1Zyhm/6RwTMrJ/h0me 8n0A3oKrw6gfcEJB/m6eJ0q1T846aI/bl9qNKvckoZKcdc1eOHHd2VvV0neKNH7bNC29Ysvn H3aO9+zOHK1hensDoj/zytnkhShVp81F1BQMRkQ4lhQ3W3AfG8m772+cNPmCHMr4hM5kbvtL wt+2+oi7cZH0M5iB6xP1a9muSsYpSNdpMqU/CO8OSm0LiFuSIOHqOyAziL6Yqyzt+09fr7aB he+B5bcRo2C7VxkBXe6mNXJmTsC/Xg3JoAAF3Vw6dH5tx9rKUUU+Ye/S5x8xra9Uyq8JEAmH hyNSRM9FhagnOeINQdff2FMN9JGIOASRV7p5oEesK2E5qe/34bL0roZSlc0bemEqXbZ6z6Za /arLILKSXzPTtjjtHRksMrbtFE/37ogo2PTqyt74XHk/IMBN0BIyK+YUvdWUkKZ+tga3BJOu 4utqVcBVpYKmaJ0HW852ARRT7Zy5H1vwWM3lUZh7CzrTMsR4mfmdHa+3xBu5SsPp8WKj2r0m i628svof2VVgEzz01qX8T7HT+NQDILxnAVP1U1CT7pXmWPH36+R4msRfIzHdSonvHBKBSGVR NyLz/OWBpSins/6dDoGEF0fTH9Fkj7yvbj2WmBVtAxJfEM7fk3Py+p9KXJ+LrAO3o0j5iZxO hUzA7ZTOJHRCLQ7pC7OdpzjOrC0lTfi7b5/KQGJHts2/3lcmPKYD0aCauYIHIvdVMZpz54oI PcOFTCdcLTYQBM8N8ZmLveiYuoW4HZIX1LKQ6wGp3VqKHhuk1hKVfn1BG5ZEDl2XtNS9exIu IFb54HkL75PTeT60SLfA0OwSjrBjULjZuy5MlJemcWNG7XjpXwriSW8zXQaXdDANk22vpZGf Cark6Nk5KE9tU2SEP0QGnbEA2CRTVhXJdgDhc7M1ZO3eLCl9ig7h/zeCeKT6/MVAbgReqnCp qx24nxcdRih1Bz8EUFusgkJfa6yZyJUWK5j744Jq5U907MT6Au7arP89ZDB8+aVQnMlhnts4 tMtqyWRtxzJAyvcR/EdXZcaH50EqTMaPdfiVhOHdu1qxOqcD684JOI9Oz/rVT5ThCmJlk+7V Xg7AJTctbyt5K6lUytlkJ6OpxQg9u0Ct6W1x4o9oBwzfqvX/Q3DCz89NFT6XloMhgjSo71ya ObnUXMIgUVRzTLUyoX0O4ehskpeniV64n+ZOAg6QzCXaN2NKueuTY03mAZlY5YrWo4nSDoqF /d3QiBGbfmWWVbBVjkrVS2OYqBBKNhLfA6hbduD5d/i+tcGX/wLkDh+wgmN9sRT6mubOuqFE up5onDCByG2JpOlTzfBaXUwY8wcEezfWYTkSDLWFoQ9BoSfpXRy5XiiTUwmY6a4gPxDzlf32 7qzLiAZtOfDy8wm9Y5ulkFrxFa+s/6R9of3Em4RkaoHg4OAacM9/QChjeWS2BAB97f/xNvrd S26FTYFOTEHsUm/sUbcx7BrQP22DyibfEk/n6MXkOmkFJrU9l6XCef/pk91YCQ0nZC0v5ep5 rH1Ef3qAAzZbUiNwhuiM7lsrwMueFCgWeufa+zLDF88ARS5v/c9GT1hfDwlue6NDjS4POdqO Hsd2fWB52AEQHgW8WX/kpG2Fcm8M45lWrk2jsWN62u719zyYYu6keDvVxTpRNI90N10jyPNd rGrdn9nOG7zdAEsdQTutmvdLHF1O5QcCup9y24zL1DKRekcAvLTn8JJHt0nit1xIWg+fQ1A9 k1dHxHGHdc/c5jHqhP+mS2js5q+1NwmseZb+Xm0e6u8T0yUjyllhhxKODdx/jwbb81rzwuJK YIYurqUSa8XuIxqdA5LpMAq1s9MHKfhwSbxz1nU1KReXd0i/tWlW9bfuiEz+gRtAyDk8MgtM ZmchQMRbYHly7FcHHMPKpUOldTfuILQ31zfl1Qie4BAyZIbWDlEhqQgRIAuLix1KsTQ0Q23I SE/W0Ltf0Q9379W4ZOXEjrGIDZ/9dBmBySUIhin+EwrFlizddtiWm/mcxmXkAsd5nk5s+xeU XQvOf2BImnMiRxQ+/CUKTz7KHxeDLTTmMtE1PEdmGNvYRz0LpSzRbQ6FxHPD0IpfW4ySFn0T kS1QcVuGP/3pWBwOq/mKsGAvGE2N5GZoL40fEKBiWM2sfxer+gMWD7DfeZRv3SVCJU4DQLSE GhMMjywS+LzNotdMWbNSs/dX86k47Sc8LKNo9MaMhwmFBpcpdw+MkXaUZEklqCvjyKWjrBLR mwQf438V2h76vKIAZSfeNsfRBNDb8un3oIHN0Zh6q1TO4POzbtJoS4/o/1HQl9PwEYhD9WG0 B/xMGxcXw1TUcmeztT1dC2hJrMRhEqXh+pwurv3YXXjCsQi1Y5aXB4++9dQbKvHjXXM4USjd 35UfDGfkT4rRaTeHgIJoeGb6Efl/nIEsxWprFAQ/VqRxptQCFW0EakAYBqDTPWMGbzbtajgU 46EvHuSMvkMj1xTW6CNOFJUKpifofI1CPclgUTSxEyd/R4dPKlgnpWwKr9p0zP0sOm4BnBWT XTzqJZfoxVxyX7TOMsp4/WYmCyHDrufc642OCMzDaVlApA5KDM0qm7HNUh4TsmySaeP5DOYp vx8RBIWDtxwRk9+IT1zUxR7NmQ4kTSo/0u2TdIZ4/ZVSJdSyECzrns6gTJ7UNddxVHeSet5p t/A3VhQopIXDUMEdzlKG3Ay0d5IhdXTieZNGjJjQGyIofctctMikzfbQ9SAll6i4XtcXklr2 OF13Kf8zd/4JU4k7ZiH2u5DBBK2O+hu67EZuC7OOesa1/1oJCKWtIzV9EeE0w1AJgP+l9x+c W9Pbgn49KjYZZCjMiJgfVXxfVuWwcfuVFPOdXdsKPlX3Okgs5f18ZNE5709YuKwY3Nn951Uq 3FPuLH5C6C3mQHGUSHoKguhCHhuv0f9hGbvmZMIbZG2jQIRlGkhY7ScltNmpSYu2eSMcb7RQ a1dVY0REsCrUedEtn7qkwl0BSPBo2a/7dYWwi49jKZdADqtyMEgScDOiP4/BQBEUUK68Sr0T dov3DgbgWzEWD/CS1/C/pDjB7wZA6pEqsgxauxZ1JNv6isCDrAp2/pio8FUOsSHqiKLkO3nl tU9OtpgzKKJUr74OG1KTTrebfu9ocHa7vIdxouYOMAM7kY3UFfducxehzxkbUN7f9sn0+rIV wb/FJmRzrkQgKV/ujNQQfYvgQSahUfrfKQao/qBWAMrjXYHfPU7hJZc1wggLKBAlOed6In0V IcoetoR5Y4AIHm1rtQSmC+6gNp7b1CsEsqHxuIACmIoyvvFuKdwPKXvT3EWuxd7EIZffuRoJ d7apXUT5jo4mqvasTiv5DMxraqt+QbzGqXGf48uO0CzobsnkVdzMJQkdH5x5Ix6hJAS0AEF4 1tRhOeVf3dhFkWTTdmYJJWldRPG8zm6ZgCxsTgnDsweni1iyEjdlPh8Sx1bvQNXOdaxRK7BK cDwqEgg2SrbdKZiTkn+5NMRkD5do+bpAhtRBnHD5XaiymSRdK/8MiaT555EQhMgU84no04u/ mv2LNz6QbktB+y8der8Q69hdxtlOul6A2PqzsA7W8pKDH2bnTOEBCSdbWoqsLVUpu8TCfAJl LxA24z4P0IzPVFM/n/YOlTGsUk5SVLzIXuJsl/TvpPyIvJnw9r+vBPdSO+kyEE8NO3lBLzkN S4Vyv74q7BgPveGppqynNcEJ4lIpgtjXT3D4EsBsIte9Oy9Pq282UUDvvy1NV6JbhDYMOeHW YXNNY6FNYCIvxj/1dlDMxLqBAn92y57Cp8Hj0Cf2zDC9SIxac6VA8VSAWyv4LSo9KvoZ6Q2Q 8M4D8APwn5fL8ihQzKry8XW2SGUlIhoZD192yt69M5UQiakGI7rfAsxq9jwwS0vtnC0yuK7P YJ+hLoPAP5IRU4b0fTjKTg4/qylHo5CEaPeq28gf8Nlf2NjEMQR/PGCpACa2BYLLAcp8lF74 cssrnC+kBg9TX8+00IwtyafnyCPaavX/6oBwB3lNVvvvBIuCkko9q9xiMV4ocI3vVQCMzVtq IsMIsNZKmakeZLg9KBVUl0bWhUuZf3jg4ZELdwO8iraB9D0Nkyca+Qrk2Z2OSapJohEUi2y2 15MtYuNoQt3dwBv141ihXsmmbAMmONTfrIwA1XrnAdq7yEx3ge38j08NAbDdWd7ijbVir5BH Wc18E29MbTueMggwMYOETA5xbDM+kR+YVSi/La3T54sFV2e9v372hcRrjHVpD6Hf4lelNHXV AardeEBzeuwl2G6UO6sYSbaZE1l6ixjd+JFhH9QWLzrtANe1ZZm5l+FnjjKGI4NUwar1xv66 gpdjv3sZjv1ahyVhfmjUIdgpSTUIxxjszuVjWW724aaKvMnNr5SX5/BEJrTM2pGMHnsb2/+0 eWCcOR6QcDn05mbVSlvFDzyp9mIcuzYifVLup87aIH15h29z6haNH5+zI55JMdf53/Skcjt6 BD/Ds7cXSQW4/kAqTQWYV1j41dtyUFkIpc2Q8YdslquwxcLhRFUEZzjprdxlpVt+yLEDJ1Ez +miHpPjVypA5GFiF+p/yPm5MubMtAdlSEX5/wv/X+jERXQREdN+2H5TW7vrvQZiFPZWxRgql vnOncpa/tpp4/7M1gj0B43pmMG/udPJQ4L1k4GJvZ6qhZKwhcdYl5IdZJWRTaoHCedrVLZdn zfVWNM9WzbZCEdp8uuypRBu4lwTuktXZ4zlIeoKTw0y2hW8x+/++JZOEcKL4TXGvaaj7ElxK lFEo+qbkG3zbDWMvfchuYcEJgwA8VNBDyzO0zjwGGOqbHNGrJR3es2A13GaiOVi+t7imASvF Qkit1LJriqPWS2V6JjQymeKm2WBz3odPL1AdvqZQtOT3mBQLFY/e9B1UNAc44ufmzvAV+v7a sIuCLz+oCzLd7cB6zhggxVdMqjdaajIRKnaDDjna5MI6Qe8v+/0nYCvCA6WPZBucO3WmYDT1 e3z0OW7Af1mGIMTmNMyHJtfObmcj7gbgY/umG2sS0SqeTkccQQTZS6/r6fhw/2+zfrIuzCQV 5I0yPePoyuN3x0EK8542r0Gse7lH5Ahb8a2/sb0GVn29t7ka3l1C4fDZJUVx6j1bxBs2fFC4 8B6eU5VsV5OtE2grpquowYHMAFAfLNSO0zqKMgiwAf+3datBmmB3OyHPrAkMG6eg2ZJafZS3 2PRnnuH1ialdXXetVYRPhN0IZi0MoPmvsm+MckobMRxCYEkCb3SfD9l0oiMwZA5aW65Fa7Ea V28+K2/L5GSSA+HtSHL9+FnEDHv3Mhycb10NsPz8/zpTFO75h+5YRYrVFg+kVEWbbevT6Vke 2BJA0Sf2GwPxNvXxhU82PW3+pDDpqKQzceRgJzBUgUZ65l7AYlaDZMjU4IOWiKtKxgNlOu/d MMILHW9DNMEwF/bNYvbJBDFGgFiKsWr5rSmdprV7MVbR+irx1hgxWFQoL80gLX7DcPyyJAbh q/eCXAnzCS3zlgk8adTCTTlomKcQcHzwUx5wV/aOafIR2PLAAxux2bW9OzgPI58oUAWTk7le bRyZDHjGRa6HXwQ3+m7hhxTtYMRNsVVd8hqWMpwww0e7YO/0w8AHoF9ahIRZNCJsEW16pBoM M4iBMrjSSCdLPrwNv5rk63etO6lBrGPTuBLJzABrN79SnOqL03efOP+X8M7zb0ulW62lpml4 LVvIR19tyCC2dEl04hZ13bwR3+zgz+wS7+3673EbmnfFpsDmgog9qoGq7Sb746hAwFtryh8g PT9jGVSddsRy2M1lBNi54ckX3iEOSz0t56FfUlZxQE4JDnYmp/uflGcsD5WewGo9v4vwQ1e0 fkvqRxWQuwCVJvm1aexAFkYSf3hoMDyTLCW5l3/lloB4L3Q9EivU8YulcaDKFd2A3WiFJ/ll AerACYWFBsm5bq9VvvnT7BCCX9n16MYG3fDgFzfNxT1F5/yesUfV6qwtL9WhAjEbhhCI9tJy xqavi8cq1377ok/+luZQzRbUlll3+oOufTL2zk7N50Eietcv/T0d90wwZ4d9IWeDGp/4pSa2 +HpPHh6eb828Hk8E/PspJsgZU/S+7PBzFzaiNVEFFduaXgWAL2NiwoBpH5ukCfXYzoktNn/N HefuinmjYGKatT7eozjCEeQ+WEx1SRCFfamOIHaGOHnsQAOzB1nqJtUWRgage/NmxL95BcVk sZcWFrYpNDK6wpYmvKt4DbAXTO1sEdEZ4xeqRbV1FDq1KdcECazOSdZ/i5Z0HhxUuTXMnjFh DdVhhpPtM8T2Tt0IIB916LzjhGFzPejtpPGN+XC8A7y+qnRmYRx6UmImvWlVNVMWlocqBAI3 m3SP2226w/xoDVpKsL4pwhD/aORS4NupLdU+5f5+HXnPbWCVB2upHS4VE9thcSdu2Su+6VMg TYzQDnVFLkjIOz6lEcKx26OedZoj7s2MEonCfbbt04BSI/7UzCCvX5rRZsbzgvnotarr4ga3 fSB4AKcUDwlfBtpTKmfdC8uvIvlUKZk03+okPfGKa/Hcz4lgyEuO+679FskvAT6BQ5qEYg2v SDm9fjWr8RC72qiS3/5lm1N6Q/Ar+eCpFAid6IhqBduIb7az4zxyfcuVbf/CWbgJfmsnm2Wy znbGw2eU72a3wRbTQfiQmatE6oFRWR7clk8PdoFfelYj2RA5j/AKy+d8jx7+b7BE+fPK0/ir 31T+fCO3vXMBKOuz/eE1sMzDPxcnIIJSmp+zFXQJxYODNIsd1+/jAaalKMjAEFQMgVOHVW6j 1zCRpP5UU1uZ0Uh4HbQraquTf9jv4qGCiXbr0j6t5pkmIJBIbXIID+OK8bXu4O1knN9RvnXL wWrQmopelz6E0Q+/UI2oVg9WMCwN7vkVpG778JXKehjfMbtICU9yYJcFYNc4wx7uTXmoqCqD XjdzCPgYnKb1wr/DAi25h+VZ2D7d2stnQK/ke3O/0EfrHkgLBu6jYsb/kcIX0efTAKAbcqNh MLc/63pDjeyQ4c68lURDG93CeijhZUgkxxwhVZOWqYtOFLQww6sz+smWW1hR6wMF+ckwnukj 86X816LJbOaLlNS9rQ0P1TY/b0bhvIrv0gqPfes0LkIqtx26INv/2/+CO10moOL1eVkvGCwQ sXxKROZW0qK3oEh47x/4pCWgIl5u0aj1H0LIqIzR9OKMSXTyoYl9sJ3NSWhAH4o/gsDxs3eS NG1oYU+TWk6QHOi+NZF7vSVkbfzNJa5qG4pjoetGDUfrthpCDFU6wULoielN/JJRmIX2WbWM dlINa94IpPDZAuq35ycjCjhEuG/hXoAg9wcdk6wpopgzmjlSy56tigWIOhnWkv49VNWGYqMm 2ZC4OYNn1IMztBEEj4oFOeVPwb8V52S+dtYYlVd3OmxPHTehVOwN0zccrOhabbqBIRBwpG3g J9iVKgdFIIXtj7b2tXExwtnY4Pk/9Cs55DooPztv/pLOZdEjXPAB68z0q/2OzvDrfSsxaFgT /XAHkx1GgaAmKZfO7EygTODYHDEAP3jbjXRyVqSaR2ww1JVqo+kfN/CstLUuN3dd4dhQWQ8S B4C4AAOEUfn0ZMkh5eYPdpmDIsRIGPwlHo7CT1ZS2ZTo187IFoXWikXWoQrJfXdSoZpNaD/a fu0bfFUyNeNNn9QalquUlkb4W4GbBxFjBE1q41gajPhmMBstr0X8o+vSL9oeWxE4DfMT56u8 4T/FQg/7NnIP9rtTYqPeQtkiefoCPuKoAEuafb5QZdTQnQFW48CPD+psJEF9KudTzEMnu/1D AnzYQac7ifPfnwh9VkM5n5mwI0stS8b6M8i/ZMhMDC8zef48OX9HvbjSCbPdbUvcZm0VShg5 8X40MZ8yQDRqHbzGgpBlPftnbNOJC8JQYQ7rYNja4pJzyWEt5wkOE+Ho6fuxeH33nmscYACO Et3lw0gFQZRmj4XIagUoUtEx+6nMtdVfZVEx9yNtKpU5aBl3HEZB8RYrVqKlQlhqajJ5RReQ 3e9bMFw/rg5OaYVGF+0Dw+wdvpQpO/1x0A4EkarRrT1FeOqKz7D+gaJLv3D9dBDz5TGdV/H0 M8c4dsl8tncsjACSn3aH6CRCMluCGDgaEQvIvq2V7jaKHWRNbz4BtFplVP0W1npAk/u0Rr5M FDkIrYurfBS2Khx4NfddaTcx+thN30oGVM/aygEigxqe+s0iLc9ipZkhd7lJmSsN9hpy4tAr P3x7fkCRZtU6F/F6ZxkHKi06ZovRFwahH2gFikl66puYxtuPEOV+jljpfbucewBrFVhs8hgS RQDvSvm810/jD7Bnw4SDa15CaEapFwEx0kixIeOqumL9VDkkijyZjS5e/4DRdGTElxaVCJZs G3N0p2zf2W/GqOuRkhKoZ/OZv2FDHfB+nLBe11FAk0HJAKCQ4Jd+NBRNtKdBsARAfcs+X2G8 hbTS57htcQxiZiMKSfAmdG/8ml4aq15kaNjAjp1l/KL94xgZoFgrU6+5nootJ/nHK6L1yaJB JNqbacCy2Ue3QCP8fpJ0MdN1hpOAmtWD923uOv96E+oAzK4amqQGLJiAktdPJuu9zIdUlb44 h4HtwynOocsONJ1in51i0Ld5z+n5Dzs53WvZ2kdZJMEAys/SM1vAQn52IWCBl2N1lgt5YpMX OpN06+0bLXkguOBSC7WT/3AMKjWdFisblqcqhHmSIPv/0OJiW3TJiikYMXWMmHqQva5+Y6of 2xPuL4XkfQeLUkiYpzK5XleIToDMTJgFFjsfK6SB/6WC7Q5Uw8q36IsNBTad4I2GFxWON3/y dUCYUuC6PeskUxqjT7DiD2BBxu890OO9Qppxa4O3TM9QnzhzXbYMZLR50gz+KuooqEewRQKN f4ELv0oIjjhvjpXnggSdIuLKmDPbew/wbVHufFJcJYHXEoss9Qhi/mkKQQS/iAohAMl/OGUI ZBZF5fP8mA0ojRWf7O1AO1mEzI3eTJJTG7nzZl8cQP7wJtadtDGhk0EALlQ8y/0Fc9WrzGzz iLOl3w/8UsZiGOBt8SlWeo28yY3yBoXNMkgh1E0yKjCtH+5tq2O3CNtQROYBbUroyPylaSHy biE18LwdY2MppcqlZkCOS3Q48VjZsGW7rXMOC3xKfHIv9t7NqaQg9wGITi5x8dKIy0BzwAZd J39t47qZGaGYrCjivZrqGaDMMdb6BEaBzAEN3qRHxfZfQO1He6kFGY3AbOH43v2D+OhZutBx L8AvJMRTIxq6n2tHlOnEbrMFOnk6x774lVNMDCgpzgnV0diwDP1UsjgYnNZ2mQClgYM1eiDM F5PygpPuJWG9pp5fmwF/Sb0dDST6kfDgltPfprXYtkq9t1dPnTHxANtZK+ssBWd4Q8M1wBz5 3e9vRT5op6eTJ3Fk+/WlmBQc9IuwQa5A6wWqGp+Hya0IsMjRnwRkyOQEp6/mXJjkDopVrtUp AOqEjFy2m41apsdBE5aBNfWlPecTTv0992EklipF846/00poQLPvjl3MND7zKLlA0aZRVPVT LjXP2eP+8zTnmiaO48O2bzI0bWi+ymUGckKIID9vI6aAI9L8n2acd1i3f3/XjQq7hkxzE6TN Qnw8l90e1WxN4jGpb9V23mb2MFkS8LxC50G2o8+Mvs0N5lmo4viQ9U/Y6AXkHv8Cn3v7qGsu ZXc46/UdhIQHxT1SRzL6lO0zFqypxvRN7gHV4Z3mhbhNqUulJVQBkbM4ocss1b+nKEP4ir8F +ohrz+QpkXbakCxQFRA+C9AaSEsp69i3eJ4echFja2s3whpENAD6FMwU8pKa8UWOZdjnh3cG wWa6RgqE+2Ke9qzgUwvlLHoZYnNl6jh+WmAMB9wwNVA1YU0d3tFDFESn3oee6JT+Zp2k+ehA utfu5HBjasdFE6FVcjrv2+0StqvP19ig9mSNWeI7krmaOg2Us/LdTaAcUx0rTq2oK4VeOX3J d54WzmMynCKF23fTA6sjoXBe0MFcuxf1CVLXk1M2DdUrf0TJjPE2Y+hUnrjQn+d5uRgKb+12 VkJ0vMBU62OJMfiJziBAB7kYS2fIM52jI0ZlA6V3XrXMX1mRsPvGVZ2Wi1QZ19OH6ZnNLdZY ZqERudOX05/Vm0C+MS2q6UA3wbK2hVGSh3nVmTHZ6Z/zQGZ+AarwrI8oOcoez+QOBpxJ81yC ZsIPLCzaSwUGXv4TKmnYIHj0KSgPVOSkN4SjosZ8sXEMR9olsL0W/H66k2z+x0WaRoRGHnAM 03I7OkYps8xwB5hqLexPhyoo53twTrmn24a+BclY3EK91PT2/Lb+XIwB8eo1jniZDqn3L4pX xiVjzRUKCaXrZE0thTlyjgXOHBw4NNWSg2f+JTo6vC5TvsJvDLf3R1tWa1hdxgOfee8kqpPu HqLqGuU3VqyubrOoIF9zO4BFJiWMC+EgTyLPlpoYol0PcUUQNDuD+EjSrK7p5m1O/M/n8VMl 20ONvTraP2WIQr9iu2kz9Zhg/wpUlQL+vBcWAogwx8ZZeH93cD4lIrT9Pkr8q2XEm1OCWL4P uC/yJhcrrXs4wyEpKRecam0x5KHEwt+o2w3bXLMrCv+aW60VGcIFp+rXKP+y9A0+8jzjNr0T iLNdaXHJOmwPJ954fcdI2xragiHuO42laTUh/tFZ+PEAd3qCG39+hq/7WkIeHdx4iepyxVTF PWO9oBMkN+5VNIi+cNaKwQjTmWaPz3JJk5kqvdMQpaR+/uJvWn2CcqSqfYSQmv7izLJTpWHy y0XYO3PuLkiJA6NlmJ6llEgbyxGfSPcnZ8G5LEGlyH0LfGgFcAgcXeZDgyRpFMJMmT3loxyX 4zSoCqbvAr9/5xr7iMcu+rliR/+9NiQ1uVFrRH7nvpMvyK5/yjpTwQWJAnF90pqdxfgc+2+e ZcHKPr8WfXYwNM7yI8p9MUwYbFZ8WoWxXavb327PSnxxpmyzKUp6V+1JvJFQ92EsyQ+Vg7q4 thvUHd80VOENlxW8oqUABPA6SsjtQtUGoGctHTtFalCq5uqMWx+bcet7Em4twyFixfmHPtVS Rojj7ttk9zJQOEvCVRMttdEwf3Aelju5mtyb9CVbWYy3dhaeSj0QgCAhiRU85dPRqd33dEeW CgXKLziuvinEm/KjQCD1cL/BUqxbJ9up+T2x0urnCwVoOlhxQ1z+J44WDLOeMSf4mPOKHLgT rR8ooscESXU2lYXfBuywljymkhcLDNBJWKz289sLxqrj7GNJUlnNRi1HibAC2lbtvOpWkXpE B7Ov/svyRHHal/EtPPwDX9SF+Ejufh8qCxmtTJdb5CbWs3HxzouhOrLjLaGX6NDk74Ju2FBm KtrGMl/z/+Fc88fkIKyLj1eFFLqf6slHRqcWPt8EkrikIMqoXHswEUUEMv5u3xRVRjtd7Fnd 34R2hs+327RZZVLT9jgKQf3AZCCIxzzz3QTAtcW8hkG1v5ctpLFK+aLTM5k2G2xRHVRrSJQo ZWPZJnS579drihMIlRMWx8ntInUgPPi/nl0QIXuXylUYrqshC4sCoKP3scW7/yH1bcYVXSPy KBrezroQyCgHSpc93Njjc8CY2VLcMA9hmfLQvfok3qfJahnPJJBOS/ll9UScKpwHjRxaPjnb eo39ECCd6aGUjqWWncBFRBKkf9brk2uf6mYuVW/+5Z07Bb8EdGDnsKICu4Wb9dRGpJPg1ofS jeosZZSXLWt1veHghbzyDKKsKrrUBarGUPnOj10hc0iDDSw7u8sa3iEGTeRMKdl6gVUu9U13 ics0h0CtMzZFhYManGtaURXIhF8ldSNb4rTRUptKi58x/swc39MMwpMcpTt/mHmMcbTsKj/P p35+MmdiFX5WP/2HjCkdR/DL4sORqTAuJn8y5b+xMYR60JIp55oB3DKQ92PWOZdDYI4HMS0N zjdmLAL61AVfS/+NVQB30YDzHWoZI19lpLNz+zWZz+zr4BErVcq3Wye4P2XmnU1zC8nlQd/m no18i6gVXRRdJw3/OxQm4mU6+Onfywr1VfoW1eBDbj/ogZAX5PvXffB39eMQioDG7vakIV0c bjFFIKTfJXWBKRQxcaN8HqyupxJ+VXLkxATqejQnDCJuOMIDqKJ+FPaZgDfwMdwKDK3+/h9G AROZAyGEdsYWcygkMBx0ugYfSpAZVIuXVnWMV/+XWQRew0XCUuYJP84wir15/eMRrOqdDXEF dp6JdfgXz2omdBe6sNjx0dpXQFpB/mrSCtsDqYH0ayS5FQ6fv+bCoxChtr8u9AuTrU4Wzj0I BiBJjRKdF7V4NFZn683FnACBwbp5b7ZmdOLrNS+RyeNSaOOjCoWKyCijRKeSRdOKpKLktYx4 UBVQyVHBc8WWoTQzHcWBo+VdeoKMPZTAAB67YdzttSfwhW24eK/C+AxhYOYitiCSquZ7brjf ddXYX4v1ZxOa+DEEqF9zLoMFGDWtUPqO/Z60evYLjaI1cbvjXzyhgGpc4721O8K6WsZ97/Uj wjv+/oKms8RGved0QhOCvvNJHtR/hfPbwZVEQ17TM8u6r/HvGAuSY5p6P0b5e5tHUecNLs9l TrOw1I58LJUJfIuxEJ+pggEuD2VnhZCuk6n9+QbUqLPuVF6vZRD1UDT7UAR8nJzj9pM6tbF6 FrVgkV+W0ErYZp5RutFsW9A43keMvfqQNn7ZGOPukBMd1Oazph44FayW2aHb3/fRe4FL8e+E UFK/1/oH8pw3uXxxgZRKuKHB08o9tv2O8rY+khGDpT9fTzZT57DrQDCGSLx3OYZvYIV5zVGt ZC50HQY3rp+3LwcC9hgQX8RtdnBtuzdtv9I0r/V/r/GjR8b9g1qJKSu8q8nC658gKvwhCdbG t5y0bBBB8APt/pVKFOBYRLgmkky3VkYsKMyiuEzsLMq4YeCf5SgO1IHz9KnrC6CiCXNozDHf c/oWm8dSZk/05cLtvr+nslLAdQQVjtwDT4l0PtKibyrVDVVXJbvx0TwAqYI2kUexHMFKoEB3 J2ncUsM2bntCyWfiW6IocMRYj7Cf7m7Z4NmRq2XsusfbO0bJSWnekuJgZBH3l8FlIVvOiZFn u87IQYNuKdTfgjbhFuC83jvlmXG+/Wii5pMwnaTYcfutgRrAKF19FKno/ThD5Umu9vP9NJXJ fukTLgGTRzi/6KmQT+0uS1nY3rwq6GwbV05D8mYitHXJ4q0pPzq5Mt8ykGvygM/EFr1tikBL fLpWSkuHvGBzMeV9weZ3iPlN8gU3W1ur7fvMrfVBGsOgHBjYU5lIHjIOQVH0zUjshMuf4twk 4CettaKXpV6vrvo53D2O1JueeA9OdarCiYm2JEQmCSGlnfvjD8aP7PqkqYhsPnx6R5RXK1vO ATXdzql4xt8JczHsIHiUwHr/ICw+dV38ylMkAAZsljafh0E3mKyU+eUFjqbP1IqONU0fp313 MtR0FI+LklncdD87JYdEybVXpbV6S9Tp6w8UuzBlSvJka8VjsSmD/nnfQ7n2Pqw8YNiBFG9F DAkOZr3/vFHYlOs1rVsYCqqmUJfajUZkVYT2E5KIWpbUsJA/V/xhlAvRbhjcpX4EEIYfl6TB jSXjNScYyvQTQQ20YSxlOj2uQTpeDezqqTEJTrtZtx/gp1Hv1sfQt09zZvd7ERL6vA1bfaix 22mm54n/Ls3ahw/NZd+qnmSWM+6Me83Z9beFIYflIcUnEnQmUKm13uly7vKsPHecz6QZulDc FDAeWrLPHrU+jnqNA0IWXgEUl1NFGBnNHnYz/62kTjRkLVdeO8Dvlvzrpkh9OWoa8rWROF3a R6bImfZaSCiO1po/o8/Tb2gxC2Snd0jzPfhNaNx/izT7JgNclOAC2MOgSio9uy3Bzwo4i/0m oJFHdhSnA1D2usU9YJdRBPc/KEssvakuv5w7Tx+4416wljMT/60C2P1otWXAImW1Xe0fEYc5 3CHgP0H07OLTHR/F3EiDQBGxFZU08e8iU0t7bSp0KjISeAN0rFPiLujllhKo97Iv8VMYGT71 wQ9nji7jg+u0kqegdyyUGhvnz1yVco/C23l8XfmzpPdBY+XnUIW4Xf7VTx5/jhmztRvLQ8TU LVmbpTsan7tYhyTHtSQnCNAlOJfhyvr/5SraRoSJxkPCSt5XwkEhDcq1XWiye5LvXC51exde Sre9ct5r/uSmJB5mcrAec5DIhJaXiswsB4xAH5PXhzYhWrBEh4zL/b/wBM0soXDgT3E9B19L PosJelVzPKsD4/MIiZ3scpIFYeIoTaQQveBFDdDKpQVfW+WuNvtU0uBhVhNS3jXqo70RrWYw Yh3llOLenTwcqEwqYqDs3bROhzvm9i6xkEpOAIwm1/OCuu6YURR8Lqu7xzKMmIStXKac7xfk cIAQJulEQPS0ODH26L4y3jxRPhb71hfVcdgqFh3k4gFkbtP+pSTZeX6dvgHiDWOIHzVXGjnJ uUJVDb7rZQbQ5T3jMNUwTEYFs8HiCBICT/wJCC+5rjNY4FlGWlzTEs5eXm1OKCk4XNACJvhI xUxhRtwxRIxr/XTramMOa/yZP87vsNTB3CCxxJadq3/QGRIotv0aCxnJky+lke/hRJMzxio9 30pOV2I79Lfezc7B7404quFYguc5OQb3yBkPHzi9N0OxRPApPQ2pOT0S0Bw0lmC0TL88PgWO 3cuByXzI5EC2mGgtmeEiNZmAJGazqYGI/ZpcB9yPutWZ5Iz2idg48/Dh77/BXfHdXw9BQM4l aR7Uwkvl87NbooNN6JBwxvI4lP7ytKc3KPt1mS5IPjwtY418obywMs+3fAwTp1xWo+UxtrPm lvqq7VsgrFwrcLXE6PjM3lC/T4RfThCn468g7ijgq+ZCtI19lcaQ9h7r16TvLt4rAZRZNQFi rt7FXwAZRztZOmTID91AVH+Xon3jNg55+2i5HczaLjxlPSt6XwjJr/+41mfE3Isg8FKhoIgo u3m518sbSz5Es7aJywBSeVBy0roYteG6tgI/NIfh8CpmQ8LD8OyvswzCCZKQTr/OVWCFOtXG MYonT0jhCta9WiOsruaUw0i7Gt3cZyakcaLUSm4KDhAkcvcToHR1+bGKZT8MfZzTqrUlsauE sCN7TdxHDaDo1eXLYHnXAeAi37WxPkgtWfCAS3wdqOPdyGXQ98D31EfJV8Z8/UKBuZ3+VEf8 olDMnbCOMnq4wYNXq7cIVMwiOcjsCeqb5oLLlfECD/hcKOK1FZHAYLsFermdycifU0Si++Sl OkELVnrwFEIuTPh8DP8f25nFCzzPNqvgD8srnDBGfx1frqe6/HVvJafFB0/tCrWCHTHrEnYd 3+8kSgifWEqi+pS9fAiGS1JoHhL40oEYMHwJXGjyqJgl3p5do8ErZ9STtMedvlp/FIX8q/YR uxfPxsZEFg12aAkVqrsNN2KzAouXokbFiESr8F+4gPH62qgQsRxQuQAi5b/8gZxlIc7TFiBH DsIgUgs3GMBZQmFHVLztWYpzyP5eVBn/0K3L9jjhXGU+mJQtBR0oC8oI1vCox80U2iHNT4m8 zOD9mS52LxXN1SliAx2KQviU66FcecTONymHz26x7xanX3vtRRf8HJWlCNy4/Y+a4V8zSLWe MDJYdo8V0a48R8Z0S9BfHYzE2QBWVLMzDvRYUIYrgGw1c8r1e7Kc3Ut/nDQVG1YpRnDEBJmx WE+b47ZKT0cDFtJ5y3JbdX+cycnUeOwWmMGQ6B6cG6zF+hTUB+mnbbVhXbqY33kpoa99DxsI VxAu25rjNRqpyRP+O0plIewQ3PfWouxQSAawIYRg8ilLI973U0TRXKqencnuxTNqd53i/YPM tfb0hH6IvbTnPTDcSrCp2X90Gg3cBC+ciorg/U3++PP6KIp/zd7v2O+sw+0l9JJ4fmHtu4w+ r+I+TQHzYzOGrnHBMp6nLXwC4EqQjZdiI8LIEH+P0wtEg/u5gUdeyau/crq+PmdWKbhlmis7 ITVN+SMX4wcr/TVgCVyONdqfvg/VKErRYeFjxfnxZ0lXbLhqH82g/9kiRRD2BAA50IowL3u2 wMHP0pN/IQX+Da0jFZsFQYkp25/0Y5QJ6aFkiVNPgggM05ulFvHd8d61WEXCXBUF8mVb3fjS aOfNvcE1sdK3xU3g+8fx1imz4FW0V7RGMY5gxVSlGb2R3MCng9w422kol74Jf4hYtqDToVuS Tv2ny/d/qXRrrInif4MS4d6BAAZiW5WXwhxZ1+Tt7fvUSCHCZ+QtrnHq7CwsUBT5Ysqz+wCG wBl/9dqe/tSzBamcqg9HhMlMWWW1AlhD5/nph8TNg8v8xO+RDPWaK8KIZ2LDhO1WHnq9uJZ2 BTFGV8XyA4FfWqVKoRSL48Mm9RguJU8SO+A2JzKnSACAEm2wh8HvzPp1hMgDlDB0U0arhbUg COIbS6vVDmrsHPiXuaoED/aOGmo0kCvH6ssiiJbt33SxxOjmdcVmK/ArP5yCJpecHoN/UFZQ 52GpYkjHV/1Xix96/sHr05UFtUdQ2wt9nYVuAhjhRZXs99m61ueDfz59Urb1Fa526lQIkFyS wXyXsr9VZlf87M4VFnfazePMUWrqlI7kKEJtEcQU/z6/alcnrh5R/DqdGvVKSJoZcandvssV Lihq5AZ1162BTFc3KpXYVd8tqe6CcJCIa8RKYTdEKJE2rfmEqBNBDsoIyvN8b6Rl6J6+j/ZW hTYi7IDWPF1EqhNNstZXtN6ww9Ru7E8dLcnLBYu7fCoceDu1UM/XX2WnFhHXw0IeTscynavA 1jSzX0Jn7uXk/msoO2sjfVfE7UMl7PlYo/aoMJwdERwONXnTMfuFjTBI+n1OeizbUGxDIqX2 bIBUG7MBaPOWbi3cbYn7tTv+FGxhYxeMq7TuCAlb1LDpBbf9specAIi5X83vxq0l9tGdtEvF MYhVdok2qWMFFKklOdsudZunBqhUdGDbmoeW1t+gb3vAia1RkUrANMCCEBBvfERt4YkhRHzJ S/JhcJS4AMI6brhmO+YzWmeLJrST08FWt9P5YQ0lNG4qEjPr0mQCmTamt2FYPNLL6pH2iiwJ NXQwLlEEdkSsleVtjDV/J7uBp+KHSsy0ZrkieZN33ta2LRLhHRjAD4MQTZSWpEibZIvSUeIe e9LQ66Sw15EEmNkjfXU5NIpMPCxvynDk36lrUplgCBAr2/gI4uHu2AnSM/35FYOVtGkH9q71 KA9F1FL5o0bYiEHKn31jFdRwbZ9u9PuWu3saFFRo130AhTHARpAQs41wXEfJsxH+WtiylYlB 9gkr9WJoNty0anDxBhuzaVZeX6gd+VoqGRcX2l1+ioDcjdHLjjX+7yn3O4VT/8XNgQ6v0Me7 C+A5g71SJrEyttKxD5LxTJIHK9yEC3eih8hgRiX8W3ORem9+UCdGvaaJSFekRTMcIE1rNCov Inx0hQOyCsakq/Ewkl3Utqhca7BgXo7ZU/rTD8PAMEp3BUv8anWZoNrvlQik9bmopuOZu+Rc TSru7jb455NRfu7R+fOr+kB5NQ+PMAnBrbH7kjajKrWPZe75vfdMBOoAolcSuD+dcLCGU/mC /xcqROe/c4JF2DsIuB0+kHQUn4YMfkWXFXdvluP6uIyUhQNdt7GHNH3XPn+JbiH8IQc+v2La UXQbYg+J1ktFScDBxEEmoxZsqDRANNt/1wYbAyX6xzfQQgh0n66K8fNqIMPLvF1Twoyp3bS8 M7srtgcHHLPE/9t8B6WWkUHjlzVnDl0kJs9CrRtRhvuesdTcIdWoQcVL4XqSUbdfAObq0tmZ R/2VNPv4Z3XcliF9QFErUwayzomdFxEtWyXyHKS/TQBzLkq4QIY+jEYsN4HD60wvdrAbcRH7 49BczSJqBVs6dJzXnJfIiBtFyS7i80vkFgnUoEqINjIvErVWRy/w+Lv7rja9V0gH0odZz/ey yBa/khLPU9hBw65C7zSGN3RwNvO7WQjZFuqv7t2oECD8URvshZ+REpIyGIhYyOpT14HsXo7r /r9pe9h2qqglu5ENucGMePhrnvcPEw+tW+MsGt1+io/shnxipSK2DW1ID2/Om0oo6ofQqS2E JbeSJeyo1IVgXOJIz7NOVXUCPkrOw8ZgvjQ8lxZ6/Avxv9UgpT15L04pge61RsfF+fCG2XTB +WpQI3wGVrZOJkvJ5PaWmx5mDFta41D72wS5Dt4HTChQe3BYaJdNS2oRaoFU8xJa8rIwOdhG xawheVUDB5vaH795KlgMrlwJToWRTfZM7HbbW2pLMWdnZctMoXTKz3FqWRJp4lOzMu4JIDCa Y+VyQ/wCRWhqjg5trkkeTHeC5LlFh8OjBbMEaOmz3IoJIVsJWVhnyFlN5V6Ew6Fcha9e1fmk ysZV60mJbwox4YxdIiSxF413UvJtD85fTc1Oy3Pe+52WxLM8d+Hr0IGy+0uUHEVjEhQT4ZSH 5FG8EyLPubyGoafjAwNGGhENSHLfFFycr6H5r961+eYASUaSfgNefNCdTRqfWGG9IysxQooa vQiUA4BZdtyFFeFfFBg9BLbYROD6WFG3QYYsFGhWmq04SenwDR2IyJR2g508+zNVpoZ6s0n8 3JWYepYMjU9ZNI1MatYKkySxzJKe5n+VSWICCmnFDp4m+8fIqiMC2xmw6jn7iHbXsjE8i7H/ +WmVWi2LL1q0oQHvfiNPkX1mBKo3QZBsiGGZGXALlj+ur09cuyrVBYmdSoyIVkozKSG5UDdW P3D/5CK6SNfZ86HDvH8fqZJXBZmv+K2f9AdO4TdGaG+CR3KQLkhSd2jupMpiFlmGnjEZLbUo w+6Te85/EXPx0diZ+j6EzKBkpAno8Ew5k544xu6XNmOoivZ+ZaTj2leRDPUvJP3WBTwdoIMg hFMkWc7NsDtjvdjPc8XtwNl2CK5he1Kemwsy136peTSftC6WZT0JhaLAKOlZx/ZzKswF8bcb PqQZ7+FfaASLb+DMY5/gA3aYnPXun0hqltKu/yr1ar12LA2mgktYRY5FrGVEBOWuLbOpcrYi BGq31vx8UC4emq8MHJdXuMkoiylJEk7lgJF+XvzKswBsvzExIUVcqtEaThPBLplDE21n3EEe tHG3lHayhwX2V+uQH7w8KXSwP9Z92PSjAjMde4P0B0gfbcisE9vVgC3Lun3veQ+IzP4/8tiN gOrtLMxlWwwGL1EQa2EwfXbMm9rahbpJPwFtAJkEME7xQswaJCq39Cs5FXZdwI9/tbz7qiuC Gwbry+m+78kj6dO8M1cfneI1In5a6dG992XYXFdSKMM4AlxCBNbx3dZZlD3Ummb3WQ8Dr+De n4y348tBl+heF3lG6bdvJTIYV4FAG//xor8r+YFZlzkvN7iSL0xtIwAcDwoVElP3s6NPRy+v nGowIZA3zRXpwES/5NY7fy8N+Ru91dzGQOA49+u8vPIw/xedV2bDLRPYGjYkBaFa/+OJBALb XDMFnXga0FoxIj6WnwkLrWd8mqMQXy0mTfG8GYavv8BthHKDF3MoUXaSGNz/XivAtzTtKO+8 qa+pOJrPhdZ4C4o4UkE0wYRYnNaWnfbLLVbfVr98qcqd/cCkH9ItA9gzRywEQQNTXbEkWP4b uB682OPsXn/8DoJlH67j/uxIeqKeEh7VDO5uIiVUllZL87fUg+BdXAnj8VtgYEFEGqS5F1nn 3aBbAGzZFZU3qYnAikMM5hhoxR+/846RLOkF5vMwrKfx0vMZa6GsG7pLFBAtz1Zf9Nh8Hcg6 xunh9xrj2H0FbyUEk4PWGP2ceZHd1qwuhXtLrqG2GuVofhllvB32eeNueSa6op2RQI1+HHiV ZnG5cqlSDCL5rRwWAEFrm06/bDUv2XOawqYny+x/OZWwuafupf181pdIju8H4isiRoitHc6L zcMu+mdGbE/lNyDi0NxppTMHbxqZClNO5/lmpmMOkQJCjSYDXpVSXFh4hD0HPUbLz0tEiom5 9RlqeHcoJxkmw68YNptUUWPpw/pRUTZqwTprHp+0UOsKI4KHJexcCReuHm7WKE/hkXBbV7V7 EU8s5BD154HB7XVLA9G7VRQ9jcxJn3C4SDJVEjy0DWUOoKTIDdcybIpqsqmsjUqlEV1bxFZb j0pDu4xkw2mF32GN6TxIKfyOAPGXXSmUuJcjYnPckwu8AjBeVqeLO1JQH3EwnesOghyU+t9f C9wila4JUNG46CTwYP+8uQ0QkxhQgC8qEEpl25KbbslHiXsGymdI010xM9rigwu7l2rBizgx ee+eFy0U0TVyv4o732RBs7b0/Eqk1tP7YA2RO6HD1zXFrzu5k3QRjAGc5wwP/3d8LpEtCDAX AGiJ5MhU+JEbLG1q7Fuh6Mhf/va8TxI/SGMExE91pXsyoVVfNVqbNdq4DpJq2lEmxaoyJJzi Ayexja2BtF0bRz6kQaXeuqFMTYKEZ1XGSro0IS2wDh0D88ym93gxF1ZIBKOwl1EBBzjbc1NE xpgrA7jQ3V67P9NBIBTSwbVMhl8e5bAaSVkaK4BlzkyX4MS5n2CSknt5zbPAjvjHc7mgil8x svY4W+myZ1jVLbvNwIwwdZGNt0XRzJD5XmEDxAoD4BtjWPz/34iRIR8tVeWO1E3kovG9rPE1 RtpeGV/wIwG6Ux3DJoesOOyxW+WpjLc6Fj/Drw7GF8LN4pMGikZBhoTtd9ur6iQ7ApqRIGGh 7hIighR5jCtuq/yMsH1o40/k4v/ghwSF2fgb1/jOW71k4vsUzEH9uls6swwxg57QFhVSAuwU 5nufORGRQoF4yr8UuZwcGEmzjnbqIy+1qQn1SLqfzThypa/koefpzCHvA5rq6jHth5tlQ3mN c8OyGrZ8evB98AO91uyRs71CVDuPnaRI3A9byfw1kNPZ70KO3zvo3PQZ4ZsBf6e7CwXOWH6D nUYKpf9zp69WkmwgZodffYDaNyycIhD1Tr5pxwW3v/M+y33DeMeb422zvHD+D+8vVCkvP5/s j5HTwIPQY+i1aiA++Y/QcmWK3PvVNvEveEoPgWgGIxYJ5OjNpAyAWiS4HAvf2a7N3PxrXgBC aBjx30J3JYcQOWTr7GgMBLmBntuBYOs5vTHonmZPpA717NtL6dbCSKPhrW1iu+n1f99oVi14 QsvdV4sig1ySyqcBBb/Dfg7ZWIHOfsPkEY2Pud5k9Btx7p56isAGoqjWc1eOo0/Ve3PLTpPE IpW12SQNBJ/gCFhJg0NuCKGUto9zHJZZW6sfg542zn4qjrTkX/SqQm8C4Gmp69A8mRsptVoX WzBcC6LxbcF2FqhxEvXw4cDicQR+598ynm91TqCORYXUmUBr7hBEgant1yiSNbkjzQc4dyhc 0hJEruqWwZYNgGt9glZG2ZQNTlXvnGO+WCMI2WCEA+cB00iaPw0GB7+UKQ2dkqhHzjVnbSc8 QptB8aUls2XqOYmlDDd9BlqFJ8NrzWTvV9OsA/hrRguuZS0E3Am0gtZir9Ah/rP82BLWNqlt 5pOT9i526KDNRCGT2+D4tXNeJ2fwhmUon4r/5+BFFFAX5sXg4YD7fPtd/qHYIHa1ks83QQ6u OiYJfSWDeHh5YrQNMy/VJC/J+liYRL9xC0fptMR458Zzuj6/3KfX4S4LO1no3cEXBcazJ0Jk UB9f6fNd41/4FBMzv475+huY5A1UMLy5s6221c50flfwWZZEKjhKsd7qrLHWk70HCsqqHzkS 5358wAOFN4D6Cj7nlYhpWPTa+8AIbVKcdz7MYTQxA+N4GJmHPFeKRTZq7OBYY8ws0baZZ2hn 4yPXUXAtsB9DpnD3g+iQ7A+pRHpG2TEAIZjcDj22kjjoSeolF6r+BbcBoe1zYKj2ADzdAdER A73dYe44FKuZjcPKiOwDQP0hSFOf7p+4qF8SXh7vbHpwiIcKspzZsvYhyjsEbWh4lT6q+rB+ UFmgWOpvqS7bHhfLte0PXQ8poyQL1ZBwMXYHT3bh8fjxlje1VSOfK5ehMb/KA2ukwsNgU3xW NKTDul6h8IFMufRq26hw4Crh2EBEqushaQ9NDeY6QV6C/kYuzxwFLWVPlJsMaf42JEFQp1Pk bWQRsYcY2VIrufnbKUQvLv8LXB+4mFpsgeNn78HkQxe9bFJnXlIk3oWTXrndiKvIzKl8AXKV XghnrpDDojTt/zqW0EToTYkGGp0QdtI7eQ3/Zl+XScG6fyfcuc7T0g86YnSNBZos3QKWe+Cl TXlM8V2ecrfVxfp30WgZYvP5ScfL7su7+G8VF27k2SSAQTbtsv80eCS1jiyz3LqxTdaGEnUa ZBefQG96RlMbyfXZR1NKFWpClkAHTzr6RZRaPHrPeNGMjhplRC1xS01KwF2ri8w+HrbNT2Ml 5ayvihWXr9o0u0ccZz1c/0t4vPWk1L5WddTD3oC9537QyqhkAonCSCyccbkcnOH+ZWSDtVJ7 3UwvP8V/jMwioA6RtOBBVhaVToz4u3Mxm2cIbKYDgJH+gpMCWk+O7cv/V/JTM0oP3b7pElsB 4YW0ZT+DpNi+izDZoQpYcfphwO3D55Lt6vHuzxi+IDkNbhfJKbIyG1giH3F0FMMhJGWB20Yr 6Iob9XV/Cm0ERaLYAVFb0sdAVYjNi7x5H9Qp+aTAD8iqYJHKNolK1qDKqUljlR2n1gTqP7EF PEw2el/PRGRwojvB6DxQAlBZDmxgVcLaS7KyFfZgG1p1WhwRHEmF38YE6ExQ3CXB2GmxbxAl 262IJd3cklg1vNJQrU6gE1w72NbW7TZN9Ic01AKPxgs0/0QXqd7ZhwGVgp0sQWFEUwBvm3jC cybx4T/60VDnLBXCoGL9N+rxgO/EVgZsL7UmElOeTzkf23iP6hqx+BTnM5HIB+h9bvGhs+oM nyztQg/GovrvUuw/WRtTuDzlhkF2ebi+c9cFS3hIwjp6n/gU9toDAVyl5KioKWTNcIbMbPbt HuDezX5ihuyOjhyPdNbmtjw7wdDO6ArjmCVJpE/F1vIpPitp39vB5SHZGOJ04NziExDa577u XrWtTLo3bXU3csbKoBBgPuEACFvC3IH6FnDyTUVUKhkFJ8xMNAIxn36NQdwQ5VB/rTfrZYUa abpvArfdLSrL7YpiunBLM5QidlE93RIn13lAUAkzUjzmSoOJcMz7OBkc10OKbWVAxCYcaLXn mSrrNjheB0BnH+x3vo7VRFQMKgYUzjCKeUZ0HyiBVnnKdhxcqeaX2d3HP1Mtw7uS26P9GGPQ WE3gcZXPQBgv8KNnsw/tbGlg8XpBr5xQ3/SpW4iJFm2Rp8VDL7VhmTA5bbM+/Wh60D2najTj V+OGZ9/j6/6CQJEuKR1Yq8lrfPDDsQv9R2Yxe2k89g2v+olzE7J7TeYAqzxWqxPqa7i6ElIs bSzCkmjKQsB3ZZcW7W3NTMHqfnIssA1sjT4E4b1Iy4NyUydPemlIUrnDTYSC/+rVJ1HaKrBW sVIk1H9+QhChjeI7+Mg5GahtCfHSYH2lxhSq/IKtIZM6K6NpqASxze5wkStTtskFPUKxms0j Gq0rTkJFTGvAfXzJoUY9hW+/0bDHMTPsUQfSrHHHGwNmsHRR3qyGiq8IBIT46bGCOHPZzt1S FL8ROxcZ2Y9bvGzrt0ufXI2Y/88jzjham1akJukxmknFc98sFGdf+N5zU8j32WYifV24xxOI CHDCn5abhtYd5nwBfInGUC0UXaA46nedfmV+IOq28bcM89rA/Xf7gA253ekGlTVQh4qq4lNm PWY/HQN0BZtowBJ6RIQaItA1M/uZLQJf/U4z1ZVsFCclAG6TLmoi2DED7+IU7OaCL+F7W5J0 rjI2HNMKS2cHPJ4D4gDLmXXq8OXuCIHOv/fmYwyetaeM9il+X3I2TwI3IVTZVuIBm92iZwe0 BMdjMiGjfqCKYxpQL7NJGfveQyjtfeUVONwGLGzvrxg0wQ8QUIVsYxRmtPhYRg9nqQxMKMKO uu3oDE/AhnZ7Vh9CdbLsOOp7tU0TyhoGYm/JycQT1RJ87b1PAB7DQLqz+1Uy6/pDZhwd4XXl n3HZAYjYpBPJrVNxtki4qR1nwJMyguTR7FNsRJcx5i4Jnlb8CK3fsRhY0gvS4urQyNrhZYKz dFQ7DLeYzCBj3U7clXyxbZLhxtxrQZkS3BAI0w/Lc4V/cqq9v+XrZKsiF23Cv4f4v6DBf4HL +7KpkYnvzGhLUNQSwUmXfV517x7UeQgos1y6sdJEWTdKUx/ItGf0ftqNi6zquDcDutABakTQ VDWjS3ywCiZT/PqUnDyk54Ny7mNDYRLBSnsCPEyI1XNYimomCyggcLYe5otmOdPjuS1OlY49 XwvMLQjQk7djdFKBA8+WCz/CoQBF6sA2ClGyrICW5HlAyH+nHp/aOcsbFbkii8G3dQ+Pn+i/ KZcTNDpwrFhEa05byoKXwDfRYgRfEwZGUq0eOZxhYpInXvfCHcSO3h+YyuzMlDxe1ZJdHA87 c+mc0RzH2UzkjrjeZnDRO80IakUVkTVYjdwIeoialbK25UvQtoF55qCTQxO7q09SaqNWSGIk 68NcWjQkDKTWemKFjCo/HyXDZyDf5hr/sOjJ7ns3UH0wgm3mOJPWQGA+x4cAK2jUyuiWBbkb z3FagNRfAaxT6/ziLQGnPG+NWXXMllledAZzxDkjy701+fOXG6dKB5uEWnlq5O+LV8uJC+YF KtBvWD+r3PUKPpgxgah9ZoWMg5X0BOSHU7paknDS4JOVagxmD8htaCzenMWT6YJf51BvDBMD p8z2nxMSeg0CyVh+Yz4tEUTJ/OOwZVIHP+xtfCtIIQP4G2xrXow6P9b/I8TUWGoEMHXmFpiI 7aA1CL6xp9oZOtZSB7p78MhFKbSVPUqaJNctG3wnGrUUheDjTgWK1PWhNjURT/tHPsM2lOTV kofTPqCxplSvHZbVefLaDvrXXcQwdNFN8MViiRmhxWmb8MNk2DNIenjbHgwQ5cWLNpTW9INM jlssCQveJdlgyGP7wfNnrgutrNSkeNvESisl1WMuO2GiBAmwrehmkljJT7NK2UJ+pAnN1l4j AwNY0Wb+YiSwin8a9iMFoGO0JMtYeh/KmsRr6qrGjvbwKtBJp5RLLaTtfaDObZBe1u3cLxYl lTXBRN4pwr136Mjgr45C2NfIrLBggl2XjSjAfkk513eS5CE+z46NFL9W6ctP3jtOZ62cByVW AQfHUcVvPMc2tP5yvXAZskRMw6ubwPCma9QCEONADYccukT2RnZ5or2TxKn3W7zRc15SE+Jx PVkcN9H+Q1mt3UDNUGCOA4FrysIrIfQwOpndMpAv+cmHOXDSfH7kwi6Py4Jk5y6FcybeZdYa mDMgNdfKVDisuZiMFqr8Zy0LejGLOxfxulfRzfb3zfMUCJRXvWbEkceihwRa00upEwC678E+ AFXvXP/UvvagU0WSmkCGw5Roz70+LSf0LpIDqtqKdjLrIULkz+gOUMOC0USUSi/ep+mhf0Y7 DNlC5EFVBpEcsoZG9jxuuTvihqzZCTBv/YxBXXP18mlx/wVtbpUgBpZTFMAKYg5BvLJtldvr xB9maVtsxdyGPYCweAHGuV7CZypQrCosX/SJAALD0ucfqxt5nhxllPnaQBLWcVjAdIwCr9Tw Xpu+V1EWPDHLPaHR8KlkOllszABwc7D3W8VF9ceRdo1R9JzhGaW9/QGF8wm03KGc3QEFtyew n58WeTfUsX5bvVV8558ImuFoMycKAOANKzG6im9Tf0yRJERJJEpduaIeC5duYf46xJDAq0Vz sJOevd2RRbNWd0cPv/Ap6gI1QPfSz2dw3RUa5rBZ5HZ6+thi6ToqxJntLGkW3DfDX6N3pxSj 1eKhR8kYfx/LUbHUKWYAc0xJLInl+T/0/zLT1OBQImMssdxeGYQtVHoP81Hfhg3W/RMYvQM5 1cpY1QrGEzWNS7fZEdxWmstMDsdHY5/u8uvcE+45mfLzIUxhWymEsJ8eEK0sJ1HSZx9KSQOP 5JJf2W6IbNpRkyOqfZKSkpwMmzgfrCKt9K+Ji5nENRFJtRl5DpU4Vjn/rWlpGoI8xf9nO3QR Ht2fayQ1BHXsko1IgGUxrSBkMqqnyfRv+tU4qv2YQsPJiml9ZlXv+lvgiHfJd3rlZO3mWjj0 ggjEL5vFTSJc+GZiX6lMlFJtJCVmQA88tQtaIGmVMXKgusJCEQP5a2FkTICTYvHo5muatxoC z5Bu24isEslM0dS6sGw3imUFya7B22PLCCYM0Vhrmv08TodZHDUNCAAplXkC54LKlJ96d7qf rID6lhiov0ToL4J0CLZfiHJ2v6V555kR4NfY9fCL0pOzNUcSANS9Gj6gnQwaWHG7k647DX8W l9FaVganRxJlTCHI1NEnZOSxwylQnC2sfe7ur5eV9BJ0lMYAxASDGnQ2GZ7c1prPpj+MqIk4 ra9XfH3VWIuxdOV1vMViWL6r9o5pff5V4xRUjJ6AQ6XOlgy1rSeXJ+L3OL6kFt5F2kGL9Szg SKlMfsBFFYQJSCuZQ55Mv1oMJynEsqYUFm5mGDmRBj81wsi1gk2exNU4L8lcdTLVIlJ2EQfR jLcwuNMtDMARW6mbZDxqWkcn3K47MKUEj64isJbjjOryXaQqvookt0eTtrO/0zT8sLquC8He RHCxYhZuYVqacpegSp9YUtBXDuHMSML/n+f/5OFtfKFu1S9KLMR3zOaxpGpCxdXWML4jYzz3 7yw467JIcT6kvE8/Sfq8NGelbCygDPAuCUWJQh5yH5iqcO1FOv259t1DTYhnD2yYm+RZzbRN dV6b9IF9rtZC82JNmcYcqtYdpuAKBXxF8VHIaBt6CZIsvSyWYGbOkzbdngQzWHzUSR70UuGe OC7rrfXv1hAEFnzoLgZ4ULqlUacO/DZIa+snIe4Urtq6NM+2FNazOkjXVZXIwkGLdTKIjeep pRfEonDHrjp9sOoRr27Gh3TZIicskkj1ivX3p93/zErFOpr6it6TS4yP+a02yIkwsD6oHDZt nvKKzn6g4TIr39ohDnAvJp0uRqqEH81zGwD/wgkbzycnO9WnOnkXv5YF9433F5BAkcRA5q9j o5gCU0VFDZPpzNEE7bqLH1zqe6haiThL4x5tRfDdjEyBPnBoOJHV9NcojBJk8QiBu672XeHX IOKYeCYoN6rH6BwMpHBp4GRilKO1lYmR8bx1D9f/OzJ0xxYVey10msUZ57YXOFQwgCnFzJ5v fACA78DSieJ29ik7IVOOhJwJkdQwjV+1oY9O+uJTGYz8WQAgCLvAhXXFxPUVeQpcng6lZ1rB vHaw/tM/6GXOcDOwU40PhsW+3s3fOpSq9849+DoGUudSvlZJyoO6KJV8KOCHHBUGDLaxNL/C vWUQ3Y6f419LonaX3NXDeTOYliMAxlu7f3wmsM9TcUE2SBfCbSeklnud3mJmMHrrw5Veao6R FVXkDmz2BAUByldPgZNGiVFf44ghEtXMucMuE9fInvxVmwrzr/xLYpK6DBkwHNI+PngHu52j zOmwlzSG1jgZzgdTnxITzDVl+ClSZRGYBZ+i2ytNCR0BY1kqMUhaOgzUXvjxu2j7CKmNC4mD JLd0+11lAMfhgAXnh/VA8vw4hefiAhANcDI7m8vZS0qu4vjUlaEWqbZua0Q5pMQHIdEiFirP iG280juLWegcrVopXQkVfxn6eOg8a9+UsJEArw1z8DZqtqx//uWID2lA5rvONOfCsX99b+ZQ AqZWFfgV0WDndos0DJwQVTdm5cXh2ZvC/PBnl3LakgZfE+SLFed5FC/GB2pi0x9Mf7BejUey r4GWc3mStkz8QyBasxlDJ4OJBITS3T5b/BRw9HNpFhc8W1WDDCjRUD0iu3tD6s5sRlXwK8o6 zcLOdRszLpC5ubjH1SYU20rgILq4/hjYRB+xP3Q3LPXr+nS8GpOhe1/CFNnLPXOKNUX1K+ef kpbh4uznvlEEwjX8Fsie1Z2ZeQmWfelSCz2KN2UVEguVOkhi1L+lBuIZWPvu202AL4BxzS6A dYbO7ap26Na31cNb4VX4ffWAcX29RBjbZ0GeGnRU4tFfFrakgHo3lY0mAkjXyX2Ed4OeU7kZ I6FV/HS/X9diUIT+H4zxGYVFLRqDy0chMWxMtQHzBTDyVevnDtXOxyKrTWeMEhgUAiljy+H8 TeYF5JTw6DMRZPGu2NUhwDKBkfAKcBqr1JA3y5bv2je9JuHBr6gwKkgZ9PIrSPM2ajS+O+lk gjs4uWHx2AFlhgM00h2EVxHHpXhmPlbol8Lwh3L75+v4UXvu3slMOaiTZsDh0mAZFPstAa2y WyZWAbrCVXPar6gBYFDb/cv3LMaJulAPXxRHwTexRDEUlUUaXN/nq1XnCZaVj1BMUwBQ+jWX owf0sMR2sE479fGjOhncDW5l9NpGcMmlHItANl3MRTJROL+Nb0jVQyARk+Aqmg3t7lZdaauQ 8EAawZWfx795qWnkdhoThniMUJgi0ImENhU5Qzv/mBJ7GRy6yJ0EMSP8bqozboqIgpjVTVCb ZtRR//6ltDxod+2q2as8cqBZQV17f+kRO2iu2ZLyOkR6L71HU33hwRFY682B9PokTmG6DkGx lWOQDOTpyOiBANvchfPfbtxUnBlOguLZ7CGvekPUTQ4tOepG5Da+9qgYwVCRQPwVQ09rozBC 27yr5zH5MiiS57R4ra2S3yntPCc5jpGcoogWLQAY6SBVWRxmQjnWUYqrZ/3mj21E8s3v1/jK 5BUYS+T2TPKTyaLmuYTJZ+fztLiF+pfDeI37/m3ZdqsvHmKNYD1v3QXchbPhDtFuHaPpy952 2xre63wO5ty/GRSrGvKuIwY29s1Pvc8Wp0NRbYe/BsAachzf0WhBVPA3MD6Ooy8L8Cv1rbF2 2HdDyKPGE5I0+6EIZnCfjre2736BrqjXWTuDw00Zc3ZEIz4lQtYIoUDKiaIEzpq1REnsMh2x 2O30TWyAsLbsZTniqBSRVBltSDeMArI4ZXCPHlIL4EQbWtfifXaYocjdhTNhRVka/6GyVQEO 9YNSSCByG59TPZlOpbd79v7kWS1VVTaCch+qFXxXLJeQukdnLONhoYm7AkSg1JbD+pkWHam7 5p/Y1v3wtqeX2QCOeMcQV8+E7XQZikqg226olAUoBBx805ruCH41kgt4TkAcgfLokol7jraC wxFXsFYE7kf2eezj1mZt+0KeyDQkSCj5mku7oFCctB1xNMKimpqzNbOgSKIV1TJk2ZCm/2a0 QLy4kGvXdRPan1gZHLjDT6zUd1jrpycLntgk8MEFfVeFHF7oFrMbbcWC6SWJrg2ai6h5fy9u lfX1PeVDP+QFI6IXwax1ZIkGBqHVxLAFRxl5O4Q6Nt/fiUubfcoc+mBy61TCMmULrdL1tkxA jfBmQQ7mUgyY17NPzH7lzTb4HVCsyI9aTGRL4E7gTQ1DNyTMkcMK0WP454Vf9nkpMFEqIwSO Ti/Px6+3MnZg7P3eH/R1Rednf9XqtSHnmNWJQqFsCrntwODzfN9Ijo9NHN+ZjpXTZPUyl/mm Y240E0D3AkIJ1BkrMKafVvr2h+GD+hpTI52EYk4mzgcdrinPqaFubp6CUEJPu0+q5b929M0y 8AzIzgG88TMKnS1cATnwfqJIaJ2ePVBOzh/s2WecIuYSMWd2DYNKSZWys18Wu7GFZGFBl+nK lrit7hyIxp2qao/wCyYOE9KtFUSqPaA2HhhQx13zvbYj46INHY+dCcXiFKc8KlsxWH6/al4F F8eDiaIKsrxTd6m3GAzAaKrnhZS7wWhC4/LceosQoWDvzqGsChk/Di11lp6wSX1Y9uGnzO7l 7xAIBwNDQqe6dCcQwRJNX1xikP2RQcEAVT0yRXqmHRBpbxHwBS3E2SVKk/h8s1x/FK/HwWta 9z5cGVjvP7ePEplCEbd/4Ss9G54e5NXxgnLC1yZ58JdbJVuEZc1o3wHjLk3BKREQTy87Fv67 e2Zv7415tEImrF84KYE3G4R7b1fKjyQlJVcmPnxJ0gXbNMKK/aAFW6OC11P8Q38OAyqCnPXH loe8czUzGx5T0vXqqU4H2mpWn393cQxLDg8VAXzpJboi5T6GDjKnLJewaDvjtZ8fclms5nYD DfiQtVoRWEAHpcAM1GEZ4a2hkVIM72Vz2ehujP+2qFFb4nV5HeIUpxJ/R6KnjDr0NbD7Tf7F Cwv3YEC4elxkp67LNYaJyP5Go4q4NAGc4l/tcfHVnUqRHP4GNoeznqVFCltzHmJ3/1H6kqSz mMGTOPNDtqzMBT2z0RrT0JlFuw+2aNZ2x8VzaZiY4UOXbJaHPqG0fLoQN3R0o1OHdcofCN2C CWbyfMx0+wjYYDIhLSwAFc/XVKbGBCEyKwqphdEJVAhSQuT16cISmORn+L11dpw7VeoJiFm4 +WYIP7RO0QNC2MT03KmGvQp1xGsMR1mkWVZTC/EfzPBMR0MWWCYlW2stMBZfAyh9t7czGPkG K+vPvWggKcWWHKaTmHr0d9TyJPgTyemv7PLaGw/6pGJn/ytAHbAHGhhwAQuqiSi2262V3SBV M7yejdPxdVqzPTKDkxFMAZJezSY6PMMhGXUtFnvifQBdCmtcJKd6MmyrJQG8bH7fE6o2NDp/ BW+9EwsFIJTvqnryYKk+rn0EaWyuIyyG9XnTeuRi3xqDRUGHqbwbpmgX+J3DvyRf/+++pHoz P36SUJzCfckWGrpzbo8NYNDBOv5lSmv/yzCt8hXwTREzxY2/sb3kc4rdqk3NjUUmo8vwePKo /kfec7e2JwS367q6rK5EIMBMyGkrdBTwzYWasRAZPwyzTaBw/CqpNzALMTH2VmadCFSXi45J jnUTL5WBRpNULPaYQsGqTEWLaxJ9w0n7R2Do2W8ZKMg4zc1ntVxHR83rtlIdNRSitCGXamHk dyaQFosKuTFUsMCqLPnIsjP+j4Lpl0J3++mgDbDnUzmG/BklPMU90FpLHAvM1lR7WdraqLbf 44KU1btSBGqpdhd3duafICiPqkrFookqVBsyk2WyzCAQG6fIYtoTXz7xPt9Y4Q2MzOH2iacN mlETnV5gqRjQ5tOWLkl4zUyJFVcVg9UTvZ6ICykU5oy8TcItPc8GdfrFWLPTuj/4kpr02xoG AObjBB4lrg8A5IpplnilvU/dnqYXD8XSLTKl4L6CyhnhyZogXML+k5GcPGhMrxe/nokIVyxE bZY2zCoKl6gc1XRwiQvYTG2eY8KFykUfRHKdqMjigCHzmyUghKZfWWDFPV/kzZ0ioHu69h5t UP/kNTgSRKNSbdoFEh6OY624icDc+eeXsfDBev06IigsKzeIFAv0viWBNg68DBLlBMTjLcsv zKD0xQNJyfocHNeL5B5LN8LuATqOBLi9hXRvr7MWHxEdqhS+D6pYCfsDw2L0bIkgU9THkosV 9ss/5B/zBFo8JSbeAO63Zp4G2CmTXhJ6EvcBqf/ygFf19avsCXaEC5mEaSQov+yg27yp4fNv Xn8BVNcY7pAxGsPfby62CCPdy5pxI0vavRKvEQnDXAl94qFQJuqzX715Rx2Ec3g6jtdyoDCx YG33LaJcX7uMH5IKsiX/DuoTpkMGN6gw3PYAui24mbYRHQ6PvSnrJisjN5FRz4RjIuP1YocH nDfdOUBLlCbK2E4SAwNtUEn3+P3SDl+3w6GnD/HonsjnFBFl/gIeSaNsjo9DY0YCRa47ZNJ/ XwQqZSBba4oJCfkil3f72hvW4+8jxwOuczz9tuUey5PtzsFOiooYMWzdOnuHPVi2GGf7Q3fq Vrbq/CSWVttTeOFqfhFGG0JIlTu1ZwEhhs2eaob4PqP0h7rvc63qGRZCTqGMLxICD0y7xDgp PVq8hC6jaUrdCHjHQFqNedHZl2MvECJgdHm1NExiOmwa83klI3zd56foZUvdZVVVgVI/KGbc 5YBcqxlgjzNly9xQn2442pwm/Qyjxd10xvyVcZr2ZxUc6qtmfbHBrw6Pe55XJjFvQUAmcWvn ZppTUvIIW47fP2uHyBNgxz9bK8XXvvsUS5wRhMakwXvNe0fHFj/CQdulJaR0yEPXxQVsN6NA hm0RK5ywd15SvjBWzmxOytTF7TWPQBulo6hDas2YAYPa7DFxyFqSH26dHB7hpLIl/0HyJiut cKQnByc86yzP/QJJFTY9wd4jEVZfDIvuYqAoQwHy2s05jpsOfTJNfNpNnB4qmQLbKtsUihbP B7LhMCJcTC804lWedOsb+++4JDkkvrAZU3Jqxga0MfUohx4pLLjlnsQGd5gCEdqnjiAz0LSc LZmZ8IvSi0ZT8FBfzshFchy3VuUvdvEZWuhHMWFt02IabC/PW33vMLMibREiSn8kF4XN/fh/ WNDOVDI45dnOUhMvfknmsbk6rY7COdQ+m4ZecYznyrafGkr1e/Vh6iHiN/AmAe3nzmFaZx5X m04lF7QwQaIpqf07lsN/tDGNWttTYRbo63EZ4l+WkC6ArZ940OCywpIYECjozumoJiTMGiHA +DzETT0WdaoxR5u+vbkLJ3Ukg9+5Z347xCy3n9JYzmCHktNrPKTgMAAt6pODNypkXM9gUccK YvZzfTCq6sKnqFt0vjzYgoGbCYaivW+F1E0r4uyYaNylAwP/f+JdXfvE1Wm22LYa0xiX6x0b 1+rtdg80y/BKl5xHoLfSFGA0KziZNALZhJOmj1k3oODHjfxlhTzAO3H5TOnQZhO/G7893Cgh R4N8OEkssqFk1y+PK3d7RDkUQgXJc/27YxOSbF23On66KlXh8AtiGq2OAmmcL7OZqp6upuAk Q5CbvjANZMgNiqRO21hAisXnEQvhUsB5SuAy8LGPZ3f899WHL2DZ/j/helN5H4iE59jutY62 dy0F6NlLYHS1inww0obDqGI+Mk2agHrDRybRNrYjS1lbazUWAUSvk9CMPhq7GeY/MhkFuTrg HFL5jHa06+z23EGtO/X1DOZk3hS91m1/PWU09Y2IWPJNfsntT4lfSm5AjvXlDWdb1uG1X67q 4XZAIFblzya+SxA6lsyhOrZxWzkwsxt229ybsPN8okB1nQYhuUQ20MXuHMHIxWFDVRYPybUQ oHLqhxYIQmyR5sN5qfhaMVeCQ2UpY02q0MjDdw6eAMPck2Xb9RmwY7Cvpx37kShm1z05+AWe iZVwvH6Kn5dJ2E3jcXRu+ryj2hU3BHih6JAPFxT2oKpjnsGdVfPGqka639BRMzUzhejUkt8E SOrJWtpLeqJTzl32GV3F1V2pk3fcqpaEKOA5o0/lVbQqDb6/KrP9syXd8Fn/GjVUDEQDsvto BAMPU+rKGC36t8E6rYAnS4GY5BtR1fwhneXwbS7zxtPdHfEj1pbFbbCjGLSI44RmVf4ZzVQa YOSfQGtSDXpdbOLsJp9w33kZQ/JdD5zOT96pcSK75tCX/+wl34mit1JTgX5mZ+pT4xG3fAVo X5leP2z7fzcFGsX1W4LoKuqVp0iQXUWosdyeAF09MF3GLcShCaQS9rknRJckaVCUM0zsZDtw tnQhdn+XwNgIbvo8/3PicuP8t/L7jxWOZB2UXgiJ5F/wXCXkUZJkKCEbYxZ1XLq3N+nuk9iV eF3VJIoap8Ij5u90QD2zuHJLq8hrGIZFkAd2pddmQohF3iUDXgiu9/4yMVpyJB3pckfXgSy1 8l0yHPSofCeoxQWmtTPTeCy0Ge28H+NU+qeK2eYPZux940aSlpQ6QTp2Vnr5+gN7H5tdPNSy J5ApsTl6Izf/tqvW07PxotfAx2JyOk2Yh2/iSxVcMiRyxPEdGkZaQGnf8yvQuou5iG9ZIBnO fTan5dcgHcADKQ/CIYwerD/rHLnbBQuhnbTKMW96DPg11WODVPbNayw1YOV3JagYao+jyec6 nSE99rsXcEAIB4g8deO3VUaGRl3UBBFZYeWyRvW2EWt05PmzB3JDSdr8EpQOK5MfcfNk5ZWN UmklkHN4ev/Xh25L7NqzTtiHcRpSRZvvBqqfkUkOOfkrhVcCl5vO8wrRmnJ2+mqsxooRTOrh xZ5ujZpNd5qn5sFHIPdbkTcqd/b9e55r9GLz80WiYxdFEoY5Qvr7o83V8LlYS98nyDSpk3IV cfs6O70Vj2g1M/yPABXonczhMAC9BdJ5Senj2XqkJefdQsxO4IEQVtjnirJ0NA/JpwHACPm4 pjhaORWPpYpkwbq14dJHPlqsjVA2LfFTK9YXmFhD+A3X4XnGG+6Peg/GMp04RiJErkAI+GCA b2HwjGPzohyIlg19U+NNSNP7gdnfm6rtVxkPYloDeToJjhq/ILqXqyOEGH5qBnZRDCEZfn5G aq7oObi/oyWHPmM03htu/MtTZZEAL5B2jvfdIhlnUv5ktLn3N/OgItwRXSj1weQYdhR6atgm pJjxY0Vr7ztUWqRDScqZzHFSp+t3Lut3wpqQu/uOfQQV7uMbeI3Mi0+62ORqnSB9W1T9pg5v zu6bOAh4DLIybA3zyH8wZXjh6USV+y4526eaJB1324CgM9WRooOAV2/obOcH0gkU9ydTQnMz 4QCcLfoq30i8fOf51j83GK0nJhXpLiNog9Ou8agKrtCuhJV8Dmu+A7FBt3UQKh7Gp3Y1FFeT tKoL3JU+tSx/olvgKi9hOr0meTTZlIE7klc0DgbyFDSaYLcS6rrwDED2LkumdXk1R7dO72/C mZofjvBkvMGpQZ96JkATI9mSPmhdYC8qi6zM53EI+rRfwBkqicmgfU9E1uEafzO/1b4UstCw mji08/CWvRNPKgFrDNN7ZWwDThj8H+oUgDGZU29cWmFAndOPCXYpxB30Up7ddGOiRi2f5gqh bgI8dgJJxE/VJS+zkCTc4UiLXlOZFN2GUmk1T5qpvUqd/RPZQZXCZ0bVP75QrcdQAevl7SRU hNXd0u6aiQVElVjVfkvVtsRLagc/+/c6DRLzUqW6SUEZc8SHTJTpC4aYNcXdKPMiQqYKhPnS RozI2Q49QNvOE6yfMuwArKJMb6Es/qcx87m4sNxCZWkBXIgNSzzZk2AiiUr2F/Uuesh18c5V IgYCi02Dxqf1GFApiMgUssLIIkS/vWKFlcBQkKIoanLHEK8uwF/yF1Ysi50uuSYEHUltmBKV beUPq9NRCGbP73SntCJCw2BHWDkI2nRxeh5vxwS8Kp6cOhLTC4CfJEmtgBWkDF4GxmZMlWU+ Ey7COQkjj5XMapCh+pc4u37e28gkk1EbtFCqbnCTNSMmlzc1slbX9DL5UGCIfBvVI+UZ1YIx 9X2hxwZSE9ho+2P8oKVmxJyFjcgxSRTbY1Liek+iJ1PyuKHaPUKFI4dihmARWq4ZG/aaluZ+ /VlJILTmzbRR4ZUEMMx1fk+d1G/W1fS3JJec88rLtJNlJmKJyAhGBz2EGEO8iwZ2v3/N4OAK cLw9TQvhHzfBuOWAXYkaifDtOVvqajwybCfoIJRYbkWUTYe4DVGe4rriZc872tau+Dxg3pa0 EJar/saKDpO2UbJgpdqFQ3MUj9GPGPrjcaRDuOb/Hpf+GimP/NqCahslckg6sXUjeTJyCVU6 TT/0Iy3PTQoiURf7Lf+JGaTk9k8f/QLN0YTrUckKFbenyV7STolMUMnia/UePeGBrrn9OKkQ Nxy23sstl3l9qFd6bFK/T0hyoy5k5QrbFapgtgdNm15SfW1aM+HFYJu9D6XCzfsPcmyU4o8K /jJp8sN+vnW4dRf/BEudVHX91AiEpCN0/L38GSjKqJLP3Ao3txNNKFj/jTu2X9+I2sby0K7R AAI1Eh2+IOAmeSlNltjqaznF4abrsU19F5ZuiD2RlLj8UQvv6V6fCgO8ZlK17oUxBkEL/y02 Xfzf971cYUCrGo2x+sY9Pv314sDzGgD/C+nNUToSaLxrpqdImQ34t/c8f2/DLgIFtJzocFqk jOG8P+HGHYuLouS/71XVAh2TPe1P2ZI12Dm3VK1Mvi2R0njzyEdctEPOa0GyyyeoECdm9vIy ZDPODNG2ORn43Ss1Yt/gROLQaQyaoona5lPqYc8IqTM8fYvoibWuaco3d82XpxQLBxlTHAvf 7e4VTYZNSK5JDdCkSV81EIB4zZ7rHkSPW4TD3hO8r53/NBozsTG9YFOcrgM/YcSM1SbbQuGA lly2kYYp0H4vKNpsOlgHmE6HLVvJpY2k9GWqG5k8Fz3eURhXGJzHeYqv40lCuGSPLAyf288E xqUYZhnngzgDeBybCdby60FjGml1XW3iWuYZzQCq9OrEL4pUB2g71jfqpFDoKvhq5Nd2g1Hx q7D0etZVC4Pm2imQRyVcSKK3WlCfycUNrnBOoXO3PSa7C4IqHfEdIvTUvHtRzZzp97y7E9wU 1Ixc2K0vAfMELsO/ei9UfBodCZlieA38UC2JWqSjBu0I+4s+mNMUC+UO1ParLVgMaQAXhqIA 2oCFL0ZUPx5Pqpxrc5/S8oy+GuQB19wnPlf0y/V3mLTrjU3CjD9Bh+iqWRUexLk5xBapcusX jhA+z9qOsV1mC7uYELNQ87MiTuT99deHxYiqADa3evaRISFKn1aoL/M4MOugZg2axg8ki3xt rIatc64PD18jBeskFQcSkn1JoMCqVsNIBwJtZs7OEBA9Q6E6sMNuM+506jMZD6Eca9L0I6Nb tL53H1xghozqCivJf2+kt8JNEQlrWFyxvC2CReNqPtrxzRdvVz7Dr2ArFhSCeCVsXqHebH/T 5ItVXWl8DEbDw+UXX7PfOkzRmQz/gMrJAp+6yrtZyQRliNs251ow98fRNjO0QQdsvaXQf/IW edkp0aAaVvnNTg5n7Zi8hUFsw5Dxnx1zRgDBbce3uoqNIfBQghEkr1mPzw9FiKLE4PwMtPQH 68Lxl05NrAoyolHVAWd9yW7Cw/8hThEuio1KjhUFswQu69DqzWiHJNkK3C3qp7Chj3w4WVae T7nEb7yT0FOxlmP2C0wo7QCW2wUpxmQMeWexD8CbiG1dqqo0lfA+JBVs/6dyIBIi9Y5NMNFw vM4hghRiEiuw1+Em7BRWBcE7eqDu75hOBzK5hLkdcWARvRGF9L2oCbFIPlH6Mg4q5x9+/mum drPTNmzMjuQAfBpqXa6rwe9a4FqF9uLSUTC5cgFLgWDkjuESE7O5GcIGmSvV6587/gNHaTSy XCpUy6Xui2kEzK+HT8ZsitUpSovYQEazPcbSReHeYUSL+ESWyeKxq1Aeeq7c6fETUojul0FP Jqov5yACb98M8ugFKF7Bgsw8d4FCfJkZEybfilnMkB07Ewt5YHGCtVN7desfrvQrk5DVrp15 EvY8lkLRCC0zddeZbCVxOQa8kSHJPSkmR7z3ppG7L20+8UOeee+vfgPemd1UvL01kCtckLem 4EQq5R5FcrpHKwlTw0cgPNVopilroO9rY2+6t3CY0bV2TgAV1Z1kmqH5RMviBUw8dtyI+bYl rZfVVE/iTqx4Z040Exe/qb4naGUAcd68vm59r0fNm5bF8Oru95iNYLQEO2xZIli/tB7L9uJG B4yMQMpE4A0VSmaF8DOpMziWSuIbP7jnTVpgIaKjR1x40Jr9kdMZeXiKer1T8RdEvSDNomH1 JUDOVYE4veawk+CuJs08PPp0Y7IeY0W+LucOXLLIGGZj/N8R64TxrKGSQD1tBZ20c/GNk6NR DM4LWS1uTurF6i8y8zgMkYCDIsCeCyRHfyezw0JuEX/FVfhTewv8KQYM7W9QLXT12kLFtMrW mM+sXDVgaY7IEtS2hMoYT6Q165yuq/JzgIyBelK6x/WbmkDvI7uCFlSPaGRmpOUIcWVXnp+B oKqHZsgKGp7T3BBID7Ntc01hNxCgPwPBZ04WxRWudF0sNPd0ynYsTn0PKJI3Wp3MOen1VWoQ vgxi2FNm69BqI/ZVSoe0eUdPeTHQLljuc0BHbf7+uPSxIlPUItk3gDxzrr9eeSG2Ne0jatFG hPb+Y6SN/QsC9+22QIDOjKqq8Bjym34LjT0DytAhRlbJKm6qYRjEgw+1AxweO0oeXzhceB6p MPPR5yDI4OHkuQwQNIKmTLVxg65XMAdLmzvDz+6VoYxPrf8vxqfBqRMQVvzcha7vOkUcEHwh NZdz7SozuvypM4pIaAkn8oCKzTLtruOafYvRGePRuiAs+d9TmNx2cRcFX8XylfK8yvsdzp1p 4uGSvgGsEJl9Dw6z3rCw4ekyZ/GtLeuDdVELkKXI6+mn7LB11mTX3Knxz63s4W/HOP0nbxZx pg1c7iTYI5w816rgragTLuQAp/dRk+YTbGtX6wUsswV2QKCb1cmrK7q4raGjYUPhTUVonW4c IuiZGE7N5j68RBKIUCWBmOTqvm/hTozrrEvPBiCPiUUvgeoxRLXjr4hzlS2Fh1aGMRi3hjIO ZMcs6FUyuiA+2P27iyM/vpTjVEz9KGiIkj5RfbhwdTpsP/Wdal5tVlcTGAXt94dUACJSn0Uj cTsJI7dr+/b9SIJ8W1dr+ddqIVRN6h3YiWiZTSswfHlRp/9eT8GnYrSNszXQ8vlqdjN1+W/V HzMVatKN3+x2Apxk8TDFrWPvXqMH38uYD+LwQU+WLmKI0ffRUxAvNroJGnRgtGrOBfyjBbul K97s4BfNHCg2NWiRm2WxlbjfPVJN/Yo5soBMTPsAAbwSz3sLzNVZmnrC6tE3HjzJQY9sQy6i Hwsj1PwYkF8lpW/jhpxfAupFyjbrT63hcNk25NBQP6O/y1CSha1w6rZ8FHbJ+HiVQ+DYT9kt ztIe6FvWIyZoOWnUt2fGyRqi8TG+zRpAIvbDXDRGQ41fUC5vkLIsWlDa8Ms3khhMxl0pQkud 1X6S3GWLXewEMGkTvovEZ5/8PbZBxf/Tem+2KEtjn1EpCSMSHnq5eMZVFtVidvpT08v0lPYG G+z2DZsIELuZgZKUKkZEmnYVELfx95VAAZKObhEiWdjM/36H/95GzswyqmW18CFFS8yBdQ4O vrdycXhqzcfPtNjfZdJktZprZGULpDARTm3x95WjBg9/wamBeavtry0q30xgelD5wsihe58g qWkOJ4VfTG1n/r/dDNEhAssAomQc2U3S4ZVxlS7K/XOiqmkgBHDFmot7dQgllH1elTxn4NNs rL/FiHA6GM7gm+srtMjLxy1evbpK/FKJiAuCcCzjfqbNltCjZvUGYHa3yVETr+slSfPtTINo 7lBXlLoDtnTLcSpqzPj7IpkcMkDwqcXc2aIH2VXqxK0fcSA4AjEwrER1ATs7bTzzYPUP3jF4 xTp+rcpmE80dXYBp19dapMRpSR4hqECU0b1ywPbEwMDQhRF5m0XPLOeRkjUmY+4qW+zKp2Yr QARd00EQpQ3fFst8EDYHB0CTV2W8rVX90afoLnuZvFaIGh/GfPS10PXPX+M1JsECiEPCRPkL MMGXjFUNgeBSOGoZV37jM4Y65evmCd8nVeUpv1Op7j5lxtnt2X/Urfb5LtigXmanQYFRJJSz CjZ5XXLei7CGDH1mDzudLHVB+nI6BG6ylqSlIR0nl5HMfhRRINQR6/Z3WU30ePN7Esql02Vb Kt5FVUdfOY6K1rAhaxta5rzoVdRV8jnkFXjZFcClcjLnZ1/Sxrled+VVhjjOGO/eAlAPz6cG 7MnmJhOTV3PaHZA0Aw1bwHe0P8djyt2lrmDVygBGNJ+cEDn/uwDPQ2lB0neyl+6L8e8tIXMD IKc4lEhA1qNCbQLuTZRwlT0YvfsFIvaHcW8lDPV60HxTfUYPOHhxDb1AX3yg1olJ2l7wtx29 rTzepsWZeGRoqEOuluB3QNWPjPf+Q/5igjmqh2p0MEN3X7ZeU1didtmfNBpHamj742CxMGuI VMVPV7iUEBfK+Z2gKhj344LHkyK3mCNsb30QYjwexl0YMe/ld316xLxQmfrkAEauvqtpofg2 LCsv34YKUvEAHjQuK0DMYYbA60JliHN1Cz1VNWukdLfVqkQnpf1KZ7s+mCy2Jzg21j27PZQ7 0EMVK9jW7TN1Bp7hj6rRAKG09XtxnmNzDxxaTLd2XGyfQ2tfnMBP6ksapUKK28PpBi22PTw+ m2/qpO3GrNyBgKej0vJAMtrAciLCcpJZc3yc28ZDwGgGbvNMKD+4uOaBx04JZBDE46Uryno1 j6pTjVtQOPf/GQAj0dTWnIyB72FIKksggcTKxFeE36kAsIZmo6FoT/l1ZrDsJjcgKPzMSB2Q oDURIvFH9pdFIMU+lgFzwK/96Tg3xV+uyv1PDjUMRzPRYh6wq7eBA3UOj5wUGvNYV8LPYqH5 2Hq/v9EKyug1kXCVMoZ20kkkDDdJIdHV0ZFPIpX8DBBfjR7BnmNHC1pGpbFeX6mScquKvbAX oiCK7zoLMjk7iwUEiwpe+xW/EAckESn24OCx/AUqOa9g2UBsUwjyrfmit8XR5Iruxa0It/X3 lCm+vhZrpzXAYown/vgjr3W22QC7B8pDxuC3C5WmFpiCwWwNUBfa2IYFx22lBnh2R/qQPxq7 jOpCiwUZ13j1JlHDkSBFu8Kae9TlKVkmsr5N4oBu2RQjyV78AurV9ziH1NSi9fF3IO8jsS6O hevMPESxGLWIXM+Dd89DXIdT7L3cOFU6/DUE5ox0fN2MMTQNUWloIJyBffr3Cw8UQH4O7IQs vv99Efe2qVi55xxbo37K/m6m5fzF6L1pOvf4Sln8OEntarjsNXq+72yCtH6qO568+rNSz3j4 Hm82tzTw7JuAAbgKdCFePL0+N8upIRbLtj3NiMixXUzulcB3fh8+Ufo7vzjpSOmmZRGJNV2G HtvEOTAOy1VSCiTP811NBiJ9E5Fpvgi+O+8N1r+Pu1YzrfwYOyGOjh6dXNrGDEhyPdt8BreC X3TJ5X3xA2FRY8kDXy0ivV9yzuF7dqaEeNXN/FM8891bnfrq5kONCFnq9rjrxE4L4hPleDzw XUfU9f+y4GPg9I4PsMzz624dFIYpHvonQA9BWPFLYQSEzJx+3sQoSffa54OpUfJY5JVosc1X QsXxeSwUbdeBA1pm5qbchhZ363IVD/KaT89mWy2PBsP4CXzWM3j/kJf4mBU09wU0yQLzHdP9 pIq8XEww9CCWPyU9k98Uio8x5T/9C8uCs6oc2ZIsHDiDfpW+6kLiJWSnuvxqm7TZyHpyVITS VQJpIe2MLMQ9gYzU4zHfvG+kSD0BKNcXk3Fby3KIyBIayr01h0YwcMp/8TrP0qrk65k5A1wI AsbTRb6s48PMXq16GFYCWtSMtf+w8PyodFtuLjWyryM4NwKDY5EHHyfXxhzSq3cWXb49OpcB NGsBZ5Yogo4TiaaYS4z8amfvi2j6VEg5wiFRvVTE+KFhkAolm8FZUQYZ54ksEwEObYJZiCIV 21mQehudGOzZAF+yBG2FzriwaedXzG+cqD812MzH3smLN39c+wZQokMJCM+0V1BXgLqkVvv1 ARXYa/hE8vTSO8Uie78qEO8o0L9Z3QHyQ1nn7KItHKsKnlc+c05jIR3/StOI2PockvSF72nC Ij4ZGIa4abQld8nqCRQpjsL7A5JYzMy5xq1Us6ZW94jU9a6a3/YCCgihjLvgOyaKyxeBbUpc phDGPTNtVz9dlb6dq/OVXxQa63fkYX3m9VkBMalxFZQA1PTinbOR3udvlCIgT9kJSqv6TLIG iHHGW/SJoj8eTLHdFOrVJaAaLFjucdIjrd00HsIBjxkVwQLDgVBF41hxL8jeV+8XffpHUwJ9 LblmQljopCu7mW9Yo3S6kmG10vl36J+8b30MRAcZLnX0GgFFFgkJTZ/tPl1xUMRnzH9yVR1I h9R9u4iBbOcMqYZcq875Oxp874h6viqGqAhqxwcHKBAOFwWpZR370y7xHKFyibY2gSP5xtLQ dcvMHdcq6t0rWKV4r189vBYWYNJNHWRO9XQt7IGh1vITLi8DPjxyYb5LE46tnDX5pfGG3isW nBzt0v4WGk4kzlf9KHCMGrLdq0jH7yZJudhR8KFVgA9ZICDDqgzKd1NYld/RJ/eVcAbxOFrw prWkEsZeB29VwraAdG+tkHKI6jWocbX7OdcKlw0HwEbazkkOWbaeb9rDcQrs5Jjg33loTdXP BQNHaEcNwr8HDzXrwLfgLxZgJQ2Lnxv4UjP68liJ0r6DgyiQGglX5PTbrjOD21Yk5Zvwq8/Z eIdJ9S+fDAPdwN1CaPW3wG5R7AVx04Olu8VWV7LPEA5XgRh/ty9FUNdsiSKD1LVFPkCzvot9 3v9g57fRF0mbbheS9DtdNEHN0fLMkrgaaosicoLNzEFHYpyeIMDjT//1PvhhsXODgjUY5tuX QcK8BNHaEKObJQQprNKs1BhP+v4XeT+kwGg/FbuBN73xTMDHS8aF0IDOJbj1Zg6SOYX4T+5I b7CQaJpTC+4VfMKanM4FzEoG2ZJcAN4C5Vw8UBcryLqrNmSE8I0mt6RR6g9Y6sKMxVbizVcz VE1X3u8vIKhgF+aG/PxbmYzy/QfBuI6lfvYvAKyM74jmThtYbbLoyZAek1YhyltgbVawe99f alo/BW1GuJO4ABGLSbZYrvCksWjvO0zeYUtlaUIIs8vJ3vb24qQ/yjYFY+Lx3vbxd5UY4h3W hLQ/Sve1exXxy9Fhw8i9nqgI+YNhdtMmcmCe2D+ySL7T+GD0eshqOtX7phSTUSXzOGWDmBzW 7eNLRaAtrVDfda9mciRuC7fyLfwSGT9mzkpK4f0/UNkjr0Z8pbnxZE6DyeUlUNsadI8bKt9s 5VAAhp7nTGJ8ef/IIdiQYqbroHj8WHPdazzJIXnEw++LlKvtyOukHoCAD+tDoLJuxOo757Lt i3rJwCqXoBH0YlXxg2/BMfTzpV4hTxA8WuQSOaAUEr7lTmXda1fwlM2tthWWnqG2FbuM0EOo UVRQGHbi8ETuXWvYnDEJZsUi7AZvExb+E2vterQRASmVrL3gG8fg/KQ1p8WtG+nLVl2aweBe BmoVM4DDpkx9QXzDyr3H0wZ3pOj5k7bi+3+0BujiAW0ZHAsbkzuYqoZmR6a841SP36N3RFrg JvgpawVOijZOUAn3YiEi0zk5PAmWKCwU8OQZEt51AHGd9c3q1xv/swcIncjcXNTSLyn1caNa MAZjZrviyDI9L5ZXeBlaxu2nWhzJX65UmgOSWqx+EzVdZee9YnCou5zUhmbifnu5FNax9ZT1 MK5AkBbMvmEajzXAU2lhRNkARntDY7P7IecCKy3Kv4W5zW+tbq08rBT/O3kOikWrljf33eQY +SU9befdrAJlHp9DkBro2u9U7MMK1Elc6EWjt1u79uW0zhpxwFqSDR/JDYDfKxkvbRsAo/l+ t+riD1YlhRAIw0zElU30JQpik8ES/b86I/H4GttSsv0EcAvho7iW2BRlVwtBSrWZEbHGu5RL K+FoJjfiGaFQB2Yyq8PBsgvQpBOnngLHDurmI3lHSO1FJU/Gk7HZ3fIpW+LfjVCpcfNFQWXw 5DuqwEfSmVa+NCExqxQ7KApz4n1yFnnFvt9RE2e2LiBHHBzOyPWzGVHQTeCHDiyh8NHVAqRx maMzJcHWrGlUzfztMchE/IDmPxinQKt7K2urz1zJ/ZvnUGKC5Dot5z2DW9jRuWsDZk9flN9j 2GI/omuk8+0u6CUFlLpMXEeI++Lrxp8AZpzcQxzlE2gdOgsHKWNHomuGIsu2GkSyCaQCrGz9 E+0hUGqLV0zw3u32n1a0HmiMyN3o5z6K8KGnDx3yrKWwn24z9YOCaDi0KVLvO/AjQk6SIDuP jF26rTSBWvtNC6F3znqKhMl4tYTTmi/BDMAeFeSQBxS0pkUHzV4Sp7O3NrvmDooebsjLvlaq P+0yL/9Z8jyNbHGqPTyAt1tMKRmpz1fxoXVHHPIToI7X4pgME1llD2GkOBoa0PcjjmVmiajS 92UIq97nV0k2yXkrDvPTVGn0ckFxmlRt8n81CXGYHddLfuTSTFr9lSRzOJA3InlBKRTBIdwa gWAFZMCxzQ7w72z4XZ4enPqgiyXXC+o2pzsVANnrcBagcNeSlBuo2Cu7HT3XC7nbWGhXdDR1 6akn/y4FBdxnHnJScA6TEzfyxOKdyBpt7dWqCNp3Fnu2PSd8TLYXe3kOYTqCyLwFpm+Ai9c7 yqJD5BHRU36rxdWmHG1Mgk98IMquLBqvfpuryoySnbtLtHUMot1UvkSG736MYtr9LKiLIsxG BI03nsrTQHWtZCSpsWDF+gkBrBqASrqc/C/JgLSrIFeFkVsUXJYfrG66HZESH09QDNyB61Ik 1GrCKFVMq6xfYXeLYQjCnt78Hul2SyVs0c4mw2Yh7Qe0UyBaNQ/KQysThVShxRoppEshBTZC Pk1pUSmSE/dlydaqcdtiay+Ayd+60PSpVsnAJjBKGMq4uuIRCSK58gKCwAPJt9WR8AWgZvuI OOfcuGuYohdZyuMCOO+IB6Z1VBbAjugiRauLHIAOnIOnEXLKcOUeFaJ/EnXWkDDaqI0L01SC pKWK30lTXRem9tUx6f5MbQO3SJtZHuy7XL/FEAZlAtLbxxGETcsMQOaTd7wtWqiJuB1qVIld SFboMvS7bRCsmF9McLUB4p30jG78pauYQL1qeKSavB6mGd7dSWrjLpmn7vtpmHA4GCQjg3Lo WQlRb9b4G5ECXHMUMuJQmpRMFE328mMv3XfHFfysmlTe8hZhHpxIlGcBPNXM99k6Z9c7LPFg TvFct3GsQ8u80nDR5NeVscUgKDCRYIQj1Pl/b9icpP6tJ2AFwEcrId3Irw8EZIEX9U32I7B5 JMsTtIhU0Bz6XqhxM3HEu1527NMJhBwsJzBd7/cNgVBohHcD4qnI8g9nexx+SrZY1d/WsSbv WndmGgmU5EsPOKnz8lX7gIF2zrYtKVcFg4P4l7wpCmvHxOe4FfvBYV2dcXIczmLIVI3TPjmn qVkePVxOpO1rstx4/HvD40KQG58Dr1+GMIazO/94KbR7ZI2BMnLSsROMLc1wlhtb4t7soQ/c 4Yxrbiu3I9r20AI5vU/VdU47bEU0w4VYY9EJ/+EqKWKTGMp0c92WHGg7/sPXJMNJO9etPufJ 17LjMHg7RqvzTGVtgYj7NryQvZQeh+8/v+iY8HGXeYWtpUtLEO1CmkE4q7MxNbHsuGzJZCRK s7Ngz1M11dw9POAA23bTcjqRj6M/JKSK4rFmomoQPIa/WXYKCbyOB9qkqgiGDt/COhTs7h2O EMKeQ9y51XX2ya+KTaFLE1Cw8EnMT0fPqmXc1uT/xyznBNU7CSCojg+ULfpBeqFB1H3pl89x Erxq8PvYCuDttRKWgrjRmnuVMW2jXotAsid7Vbgn41/ko/mlok0Ofkm4LpAKdlebSMGktCZZ 21dcSk4Mo97RXl1+8OpQvd7D0wHNG8jTb2gZOryx5lAni+1A7SIDX4Qy8+0Ov+Bdb2CLLBTr mlSoJEFEpnjUCFh2cx9qI0u9TwJh842XB3vlSrbFHrsC+bf26i2qsYrPFiFfO9bCJI0e1uI9 f40O2+guLXBtxjKjw209ZnyHt3gDkDOVFkvMCy2YnvarsN4B1ZbBF9fnqrd29fbW47cHKiPk CUMsRf1Kzew1Wd1uKNZwugnmFvO6qfroGjvS0JJOjvk/M+KGHfgaKsKxRIcvl15V668SFKaM tJV946FMW0o+o1iNbBbsw/B4ThZB2XQDI8GNiVuf2JqOkuSoYQQ6Lus7iPE/SZ9wUQWDAO0Q SusaygianHPovQKu+tkCc+xDsOatQ2yjvRa08LvoJknvSuLq89KEvuvtfTf20eHA3NdNlIk7 eunwrmjLxVc/m4Q8uY8KGatcHkIf9FDHpzVrMcCc8LXn1zPYSJlBhSOo1INsuqNbpsuht66X LKQCmrMCsXTEcYT+myx444aBzjvfW8zq8Zo9lV/8cscf5xel60vemNBbE+Xi7F5LtSFf5248 QlEBY77D4OXmJJI2Oq1QIP449YXWL4SgD6rWtcP0yugk8tTAxJ8RVK4DKByQ/sXTOKO3FhxC M5NUEhJA7tjIiRcJl+yrLkRglxzjD3E7Vr1FpbdZbi5EGIjgIXNp74/KagB5/MijCMYNF654 V+Psv8XI55Psr/IOuSZJFUu06q2jXeeo/nh6KfmVp6BAb3UUgZHV9t0KrcUQjZ9p3J81OiYl p8VNkvcmOl7kJbeDIbOatKSuhuqCgYqQFEDL6m+hqbMFNxvynIsDbbmouYU7dKAywQNKrWuj BBSzMI1SZKhUfq/FU4AcQuC91osn0QqLuNcr3FzFevGCgZRkUrTWIrmOrlmHr40qaPoTHnQ2 G1z17LzfTvj7XN5CvexAneXIeho59e8JxKHAvkChwh71/tnEif7iJ7zSJ04UwXvQ4Zje6vQZ XJ5QkdFDOCh+uTxfuubgaG7vAJ7Lw8Rfb/+Ozq/8sieVRC46d+4Ua47dTvLXETnGCDzjKD4v ZncAXZpfWbl5gju6s/Wcl1a4kVvnLNUgHYH2YVn5p1FR1Z+rIYYSIB5T2f+vVuI/4rvC3h+7 6lOLuQXo3tZW9/7g3v9qsxCKT2dbrDMUMgoyd//SENTAyqfN/hNfrtUr10qKLJyzewHouMeU +vdc0e/Ut25BnpAC4ETA2VobCSNsrwqXY1tADbxfwIk+FYLGplLj6hYs/AbfCwV6pAkiv4fa +UMAeFQYbQ3en9Kstc5J0iBL4r9awuy8MD1QmDWWPxBFqXUjvkE0Nyfk9MO3qyuhtTH1soz6 JVYB1XBVz8KqPhz0KPgZUSAh3UQGcfyAVw1HNc+DwMDUaAh8rnKyVZVwQ0hcG8Uhc6TQ8QDe wl51dNfMqLqRimS//U5pMM/GfpEi73tquQYy5y4INCYqX6ZeFmzkslK7qkntkVTK2tN8BeTT r0rdVX0GUTJxL0hzba1TKoUCuqbqPzo4iEzUlLMeoJ87wcFSeCxIh7mj0Mm/Sgp8KYh/mYzN lyd1MSDA4nPklGI7aPdS7wef6WLYrXdv7hEtrzKyAh1vBs5wzVozQsyth83DWyXjYUQg102B MI0GiPl2pFlRDcf4hky0CqhrutukObryvA1pUDZbYaKvY0ABnffxcqvJf4p9MAbxajrNnl3J eTu+OBDsc8XKiGDlCA9iVxNGTjxGWs0HWm7e6yr95QV9gs1jhEM2PXRp+HlgV4DTTTeRMACD qA4AyrilTbrCFIJx44OckRFwnZlaKX/AP7gSdtypycdAe/K69xJIbMOU2O2xXUqGrhpp+se6 fksK0KlrfKLczkasvPJhXaYBhTdfGhiYS1Rgn+0JghKjGUUJrfpoEEiS2pKUt7upTaCxXPnM yQXGj1XTsf81LlMVhOi4qhknIzRsGEgX6D39WSoCcu8SnMOkKnST+eDCAag5ugQ/AdRhf7Kq Bb1wapvOUEZih8PrKjxrsV59BzsUnhsR94VMnTl8PZ5vUgaxGW8gpMRUP8U+2UNCGJ8qTaMW 6UcUYZNscOfNbeShm1c1pmxirl62fSV0fwObEd5rvcyeCLHypNeajUYstmQQopHYL4rSOZ8G UEmESqH0iWQvuE9R4cz+7zu78egwy6KFMX6Bnu5X3NG8ZBfMbNZLB8bt0Z82nDRAQQxX2rxA wPnSZm1cN78mCx3etMfLZKGIkpTMj1fUaudy1kEJiFX/jc2o11TXCOjWNM4YVh03tTiJ6/oc LZUonhh9G8yXD2HKkEox0UWIhLhTMn3UQyZpzvAYjwn1lzV56N7n2hSHaCxAcjkWuvcK7Wsf VjxpnIaH6bELyqaPJVgvalp0yy1yN0evY3Dr7baF9d3S/IE3y8LWrnmTJ3mgobP5NMeEGCUO lJZvU+r9g/r8Jq/k9zGuiPwivhfYl+xzuwFHm/fzoy+41vBkAUTRkDRnv7T3xxujXlvesSHd LRJ3DIBG9XkISKs8yEL92kyHlPosuSrqUWwHoHKgFcRZpj3c41q11YVV/yEtltuj/dGBbBc0 HezWAt7h/A/8HQuL/d/HBXen2qgZn5HjiRuptcRyxpNxLv5IdKuwmQrJZe0zYh8ZLXv0EgT7 d4sDsxyEj8SVG8/+Qk0jJux9Z+Te3TpdT7CmgOutuEvAPiEO6Mg1z+NAj4MselTF05I2yuZn c/h2dLZ8pk7f0Fnp59hZNyRaqHhZHTHCg/8ZaFCQCp12dsOfYc60ZlpHYcvZ7IZKi8EQKYZI WMMuyB1FUJnJ/ZtBl250yrBtDTPN+rnstzT4L3UHYT4XSe7VKgOnX5IZOhzgYxc9283eQR96 YFzaQWU1v4/QNALFv5ysQEaWNV/Z9pcRTYX1eJ0XJE0twTX2BVxflpPInz+h8vHsK2SYRIYR 8z+H/5aIdb4nMh01jZTiTPBi6/JpAz+9S5P/KfDxYMSm6Ot3t4FEr7cRw1uPSR+vqdcfDfYi Vmw+5MkMF6HxCSiRNOwJRekRjMkZDT1v2D51y4px7vYBUsA4SxkAqbI42CRR/GOrG35dsgdn PqEMzXdevmkhS/Owv3gdVw/wWaXYncVfFZ5qxvyIW9B9BtZgTxVEJ9/9nSper6wgMUQbVp/q vsv7nNdjGnEijFQu9Zwz7HSRFNR9fSw8wxUml9wfAtliiBU+ayOlD0/DQhd+EiQAwQbkjy7Z y9J4wS/1zs9hqqFdCH0lVpLC6pDuWqq6a61RWgywvK12Ow27TN1UgQcQv7PxGQSAEXqsqJhR W5ghnzICG+Byjdc6sN0L3BYLFfb39bn8aPoodwsDLD54qGjuS8tONpN9a1NpaqHENW8j4BGg wWifRtKddBAXJIeIigAta1VWnob5m577GD9dDTRHE9TcEKs/ZeMrDHqM3ZsdhVzOszGdSv7z qgWfhwapYPqakVaGER2CcIc+VX786Y+anzbQ1KWWRe8IFF6td5D+QSJY0xzy65v1TQzdljC2 rM+cMcfbZSCICD4Qi79O0jI/ByTu2D3VU8HQlnS21UOEUMaj3RzrGnq/Z3JLNq5DnpUJzbFZ TIundadg77VwQt7BOKAf/8HhENVaUsrladLwLDB8Xam+4A/vJdlDk3VR2LcpyzXO5j3ZyaKj PDhGdTQtbKKUHabg2B7VFzU6A/YAAQqQBlRmmcMSkoa0T53QHe3AhVY3HP1i0sj+Bqz5nOyN UgAbyMI5FXT2dwp9X/TD9FXV/rWzlHcrrry0wPTo0wig5e0t+YQwVwFE5iIvGiyKgeEEehKn TsAm55KZAFULiEsgfD+CW8r/bMEACn8+iw0YycVWgkov0Z+YUS9j3/c6hGbr2Bc0diMc2Wbu FaMR2CBluFq4fyTDscFUmnqS2nA6uj5xng7O508s+FGvGMlmG03n9Zva4h0rbTAoSkyUeTAS +nN0XKsMQDGkTUQXYh60keMzq3S+fVzzWRYnp/mCkuW4I64oqA8iweCp7izRGhL9qqZmHvf8 D03PYM5AvwWpdwxBO+93Cv0BWSwH8Lu+oSml6CHFQtlo8mP1eRsclXo4q9aUcol3CZVb7WIC uwlqkGKMboW5cGIFKfMGX7i8neNtxIUAn8XxfVgrgHs7/6PbremyN+VCkM5st9rdyCBanc5q SSgo3IBjhA/xGA1TcduUsryMufXRVNUALkP0U2gqChHS1ZXedtyOaG1BmwOVMcTyDVrV0Rfv 4b2ObSLp1b2VJog6rHZxB/AH3SnlchVGlc3csVtuQWmW1AXhVSskLY7YQdEEhhFWnqk4XosJ t7tuQ8x44vVv2JwjCNr5rLvXhojmwpPOIAV07wvS66C0UkqodDENoIvDpnXwreA1kxnuLYN/ Ya7S5myowHpO7rtRwE96OBaBc8ig/kneQ7voRq9KgkyOAX68yZrgl8lSZrF0FxSjThArz735 BJH44qtwjLpU9/llspLc6BhEu6Y62bl79gEtX/MRCCqq+w0+t9mKuNNMwIwY9ChRNEyhWg1s bjw7gmOMr811GjZJCsb/PjXlTQVMBbsvr9dK09+rdm9MPWMuG7G4KmeCyOZZlFdtMFM4aZzU jN3zenk/MmOj8GmW0gf3Q6PazvOZ75fDhMoQ17IUDdF3BbKcLmECWsLXFiVA7uss1GkTxNho em5yaQFiqGIAhaTLrEn/7plHM2nATbnj3B6J2AgMN8DjX2D7/fF/5x4U3ntdKAh+b7oAS1JA uLgkh5MOLPqduFYmL139qs6bhMUclwyhtFureCiN96KaqbqXETtzqMBe7KDRYvtgJqx/kbPO HNaR6Bvvq5m0qZNwJiJIfqECoD8K2L+Io3FpaqsJ3+CXwSb9nMjRbzilKaPLuBy0bDc53XKs qe8XQN9g99hj7JMhQ+1Kg8vHTFtna5WJp0HE2RQNduKc/113iMs/UsXC8QbjlteyngSClhFL Q5MYhNTU+Ov4B5KltDQxce646Zz8/w0Liv9gJ0FarE7HuiS2ZoiH75EhTd0OpIm1VMXX5BhB /PQGdhYGhDpOEmWJewS5jaQr213zXx8AMb1kO94L2fe7XdSKYsA70LVkxqMlovgzf72sAwpj P6A9Ml/QcU92rKuv5Gn2qBgP1qumy1uiiQvy6gzGC/KCJVqyD+C52LPaxd207uNK2iuCqCg1 792/b0arnsS3BCUxX3c56zqlHD3LWpyQqwAjOqtfImo0fe172JXBGBooYzYGGCWHRGSMnhno gue3iNlcoGFUKHH0GsIxbWj60ODmtOfnl+3wQ8lloo862QOnt9ME8FU8ZoEB9p8n1LobUu0S VaNhYrTkYzxu5keX1Om8aEygJsvbBNUoecwijzn/bX+CLkrUtoT3EeSkOpm4jc/FTrMbPIUH eyXLUy5VNqTCJ/X3nz4OTF8FFPX9fWhotvjWvR/hjgvqu0EGwXMhtQeyVdJSsZqlj22qgYhc LZt3ZgxNfw1PKBaxoEtuf5LdMxWm/hMwxV+YZ4NjvzoaoHHzNk1ytAvQcQn5JZLUi3w0K+7s oLMV4nUvloshFfob+JtlwJv1+eYK+fh5s3RprisItKMJkh/TlSYM+XkxJ/hGJhT22Z4mK2Wo RqfjJOrMR4KeJnEh0U28TcYlmPJ2NnD05ss5SA5pxeUcECTEhDuTrbGlY2TkVHmwMgy5d1X2 5d5VozCSPIKWdRgsMsCKsl8XeEXSKh1NOcl3vlRyduuHwEpWt8PKiA87EL26qYL/mi17eUXA LehgrZG6zRcPdVylPguiiPZpmGsjC4qjZPCePP6yK8jyUFLhETUVa6tYsORozFKgu9jk8xVD +JJkYs1W3VXxYKZtF8U3Qj3RVIIQVVnX48eAe2Z4XZ7LUFqXClbduM+yWKrjyGhKN3iy4QBS eet9bfa4Dod37p4uq5LTNO+1WjTL0zktknrBwvNUOw5faOi+d57qkL5ymgoAAq2eOK8rjP/W mFyxqYG9TldfUVumEK9l6E053GRBilfrsqnOJxCLSZrDaS3iXeEG/L0pb6Awz2sfxCU0/gjJ dAji3MC/12v55H2gRbstz+m4q3ELVpTyJ+NsiJsmWUWWffR75uwjkm050G8Kf4go3c7CWgO4 JgOwJDr/C2VLcP9D77KwJsaPVlYumDfdT7BgzIxKEP5YkXulLiOXdaBRGrui0B37PWXpLBrY vTMGMrsHMJAcB69TVCpbXczSY87tRzl1W9CJHB48s+2KVPkP6vsEa5/rgCrRZAnO0Hh3ziQH cgHt7bTkikgyljwtjMJKt6+FuKiCVt0qEqdz03ZYC4q0P9ERODC/hV0cgGsySIYC7ZCivNJ8 HyxVDU5vZi0n61SWON02RHrNfvwEGksHRTYuUiytuf/qheu7WEkPecthzbCcK06pkepxP+Z0 Df6HA/RegHOm6s2EhE2wwkjEwR5nHO0Y26r0OP0kUWbvQhc8Y4Gf51/DQoQ8prQZkBZLZzrJ DnYKZ/k4mpDaQo8PEk96VjLOsXCAJK/8XZFpA9M5OF7mSCtd7nPv4foR398yee9tJbRnx4un j/baGy9X2d5kVIQtbhxsdmZpy3GyKI+vgpElLMnp01S1wRk99f9DRAO05VA4J3tuF8jxLUcv pRgJJ7N9NUAGAkg9i/Tq2Edzk+RFl4CdD2NNOdRPgI+Hck3kCenKDp2IdlbD/TgtWHvIn8d9 QaFwJIfLLxRj8EfLWIJcStI8GxQo0TDBcFzN/NX3+41ycUYjuJsIXNDMFmXkCcV1wYuvKuvN I6Ps59M0FNFwZt+Q/mG7/goFTQofvCsRA8kTfxFg14so7XxWmowlEvBVTOBRNVdc/rvttdzZ LCz+hfhQem0x9wRQthk0a9H5Iw/J050AOi5+Ab4fmfBB1EKYwo6Lox8oTObiGh2h9IXlRQ9C udD8HYFN7Y4WDFoH7GJnoBHTMuP+SalBT0YuASnMEpIIhlhIBtU/SzCH5u6r52ORfP9kDaBM aRrd7Uh2nEwjdTuRz1OZlfc2nQ1o9uu9UhhCsB5sksMdJUyyCngLmsjEf0wg57WWuaFSom7d wr34z6Fi7xBWcxD8aj0O/JF2WW+Fx+OtiKzz9hSS/HU9GQuuCn9rWoWqDEaaVXs3N8c0AKVi HfrARyiTRDlo0mQxWnFBh9mszGNL9gt6Xu4LnFDEwOvqhUxfWOUDr+FEnyBThEWn62hikYcv bZgut40Htoz2y7iqCB3NEjD/MfjkDbWTR8WxXn5031y/nGZcaCpuEku3HPbnZTbdBBi9Izlm s+IQ4v5lpEdYFYezank2Tsii2y0zbsG0I98qSWxsPU6ZLr7nMklQfVCD2GqSp9PmTmkVQfk4 djQZ4Vp75tXL5/3Hsj6FDUmF/lZg/LXUn6E4OglgNEPwfNgEzQiI+6XCoODoNRNiGYkmBOVC wV/aGsIc+g7UqVdeMsUQX8Q2DhHM7gOn/rav/nX7ezWvVaQHCvc2Zw8jRiLs0foGq+X3UP6X 3OJPcKsxe5C8jBQt0XwfSC3aPAf+tYsebaAViRHMfHpTPjkdw4jOEXWa+KZI2A4/lFUVlaNq aL9PUBASckeYuREYbN6vplmE2l/RTweNWq5q9QOKaO+NDpiZnA5Yaq/IX5LOL3YzjiGe3g3p CJCkFEuIhRxQbrLODGMDRmJtvczTDxdXSKWV8GPoyQuo3LPdE5pqSUtMTJgBOJngU1HrOA6p mAO1tiEtltjXndqlLIIgi7ZvHVbC4HP9a8AozivFzA4FZ6Qkdgu04JZE8H7R9pnwqDbLnOgv aw0m8X9XPFD0KPhMdyzLeSxPNsrgZBMFe7HFPqKsnQblPJ+z2P/209e0ElRhDWRlm6z1rot2 fIgZ2UxjoAVad0oLTqkuzh2BXJu6+7QR4uFPkJ/zmUdSeOJKeRLKU8aPc6ohoSxqs0UDlcNy /Fj4qxGMYpB7q/6DjKPFeJAhoBUFgPxSDPShATJHNhmN1Ruv7S5bbmLGqgDm1Uq6N1ovsIKp RJyC1qdsM/aqKrmA6Xwqaro9y4IF8qYtAdzmB1eR4QMju/Yy4rSM4f7C988LAEeQDTsLTWfZ lPCoalpnNybQcDOTu/iSLlL1f8ez6XGaVnk2WznPN5ec4jYC2VxB+n+eIEm//ziq0t3SX1MV Hc0L1AFerfBYdVmQt0qBe8AzEafaLeyR4jmxFbUKukURLT540qWkkBAZ6uALGGrLvh8a3Rxi z9e13U5+KDCfIN0pI8PXlp+sRcY2wXmD1COwSFN2R2umi2seqEnnGpqP0K3/s+nk02/76qER 3AqD2eYpr20a+JP49LpASnr3d/4rtQVX4y5bBga4uScmR76ltona68WCDZLMgbCsBdx16E8T ujR/2fbnOUQTh//4lcURoS/mCKKn9AoOen6Mc/tEtL9h8MXv3YEkKZ1oDT4NL/fMPwcBj9KP DPA3d1tyaVvw6OBroJJwtFC8SvVt+W51DSkPy4NfK2GJ7Kc+Tb/R3LtHmD3F6BzQbU2ayhCG tdNPhifaIolQZKT78h6l6Pwu8nlIT1njV1RmjiezRDcvfUbZ9swBPgmSoGenmUsfIMY0AwVl DH4wWoSC1z9e7bfrpngxKqg31+ss6I1cQlf3lmvga+wYXAvXET/YXHi7dYptPGjeEah1O0KX O6HzY2/ExDc52Fu3901tzCSqLTZXxzrpsZd/tJVAcMPtb3RQvcczcmqtfy5FfgUXR+LddO4N zj2sR1aPR+5aV3QqqJP1NQ4OWB7HsbtHdPqRb0bdwJs1f01Etru1V6UEpINHhMAE43QJEIKh V7kVUBGBHx0brDAMvkCvODMYio3+H7QOQP1Gvh6rDtXUZh98KOtL5aUDbAJnquZ9/G8k4hhC dvRthtb79Lc1trw3SqQcfK1PiBRcpiDGGHf73YMCHKkPARZSU7ekUiYy3dRe5nBvAp3ENPa2 eMtbeuAExNuTwFdZz8xE6aUmHIwkhBuc2hRKn0hHKAdZLYQb7HNFxieC20hVn2emJ9t9RV4J iChAXSTeIT5jSgv+ko4SNzhPvqyXK5LgR2bmr+d6RWuBBuJUDWGVKquCpgdwxVoSswvFTJpu VZGPjI3utTeD7VLWfl4R8LWwjere7FRYrb63IyU4wCZDzmIJ6M41KLuHsHVMIff31QBRgRrI zbvmvqEzjZCnWptWhgQvECg7bQSAzRXBmAIFe/s6lYfUuvvTrUETYKzYk0jVI3WCNz6K6jDB DwUt+A8uAh64gN+vpmjp+V/VadLcwM4/PynRL7V2OyHw7br4VDfz18tmRUPVfsqHbF8LlFpx OBxM9DStclix02W6jLAGIME2x1T4sw93R4efrgD0ZX07fCJfiFmFZ9js6w8sKxZHnSqrQ/62 kTDUR0VmHC0d1toYnFDREfTaUXdNGz3fpaReQ/PaIwTnkNfX8RhTwgwhAlqFHsAX1nnrWMdY O0G3VZEE2H6vdI2Ggazpcd+6Uiw5mbMTO5NKTWM237c5LzUcEEodNW/eu+DPNbjx1dAtAxja oQh+A0AhKAPGX2U1an1LsDIrop7v3OUJDuhhvsSfoXy+RbDrKvrDcPY2hFuxQ1TiZxNI+Upm ZsopgvB0m6XgQAueJUE922eFJdpslDuDJQVi1Si/zdXogSPIMuirQiaQFtQMfFjZNBUuHpKQ 2mVV0MogEVhC+e8PMnkshS+NKbSSDpLE9LVY1P0SGJCZiVfvZUOYXOt+0ibrtC+NbL8wVq6r qagYWRgSTAqoUwhNxw6XJBSwLwqVaalw8GbFQmMdoXcGQJGGfL7yY2lHR7QjCbFy/dQ6Vw9C x7+nD1EVI+rxqGv9Y0VLAHL/+ihoSGnq174DgXeVPeQfPm95ZHyB4WvfT7gmfrDkfFmfMUaQ eOhH1N0j1IC7JFCsMqlpvYZA6N64rn6wtcVRJbtr+x3nyYdjQOU1Xid2IyUokccpuda4t1ZM kgE7Vrn9ZLzcHPGn2AzwuqvfSFNOEgu6GAMAgzBEHavsjtjOg5Pn+EIc0VfOr86J+ZduTPg3 Mo4Rs9q9VwM+s8nXGJRWKsFm/0Fz9Ujop/qXBjfDJP2YRE0U6Z4V+QBuvkBWeTM6EgsLA/A/ R2ejrHrJB167UmE4ku2sHnHKShOLRnT9sl9J1/K9U69bbw9bcidgekNEh9BuvB7iAqRMf3sG Z5ubEvBGi8v+nRU16L+xZP6kQLdB+TNu7AWGXpcaqNb8RHyGh0QQ2UtO/cUOZvRWUc+pibAN M8s8dZRAmu+LbBktAI1jYZA8eqzUXG/i9Il06oJqkBRoIvElluumW8w+hTxI2NKfolLFR2VF OeZpmcHcmPVNdwfHlXyzBYA6mD8NDP3vzLqCsIMicgFDsAxAZN86utHafVFMa+dZh+JEfC1u gZTySq7RDG4xAGM9DntviHdw1SW+NwKEwKb6djek6ymKjUTrtNyNLqXdPm5wbRQIBEPI9EXz uMYxdKx3EvaFOclB8A9naNNAQjNeaKk4GDXuZr9E2bk/fiVs3AWhSjtMLdcyzArRysr9+bYz 7W2Y+fuwYueG73rsFafgtUDujeBuztaXJdwU9XOygldgLoy1OwGyjPObPZPwKAER3sqsCcyf xJj46Kkau23UEVko01gWjMbWnVQrbbCCIA5yEfMNwCXmerJImvp4i6IJKBa5utivQ2L7Y+IP eR0uyEcXL/OS8A3VJdlNjJIW9ymetM1h+EjxXcpIut0PDP2IwvfwRwzab3P3dd+k8IPQNWaL qnlcUB9xQop6vEyGYMrCNv+7soW2D7Pel2+saouEC/bM+8BGLm2Jjnc6Ke4pqciDA9UZR2pM o7INGvFZqMTYn0u/ywUzApk77NQdC7qJt+Y/H3izKTuBXMuCU733aUCwhpJHls2qIU2dlheJ VQ5oY21eHaKCdU0TmYr43dt5hGgjPnE8rn/xuh4mCcSLJN4eIW0AifKFW8GoDhCoQPz+UTo6 4WbH5sJ7/frn24Zs12/RTrYM/49tnCUFHNPCKiyfcu0RpntbVKaUYg8iuhoz8rT6xvnRg4cb M+e8VJU6ppvOXWb4yTP7cQ47udOfaPFiloRqj1cpLaoE/zUYFxgqHlwiEPtC7l63phsM+dWu F3Xz2pKYxWxVMOV1RKup9ew/Af/b5oJ1YjxE8dkTuiyShD58hcyILzE7AlOrIL94zT5tTUx+ 9pgxafcRReGdh5yS03Bic9kocPs74IY0P2vhR9wXOg+hlhX2CTMH+J6UsVYwQwCOHZizi98n ImY1tACP94c0IgdKOWMl1qyQt6Uq/Z3urGv0JvRGAtBQkL0Jwsu6AY5R63eTv0WVL4XKWASm kjsUvh2a3nAnFqsWyg1p9r7RR79NT4VPm2LjOvvkHW9dB1ZxTBSPZBolLvR3huj/6uxtO+06 ucDrZ3J1/mTbUyuZ/GJQF5/AuhxUWJs3lfhS4uwlFAwfszu8Zmf58sPoxrHbTwajWG3xSlag tP1ssLWx42aMrBgvtzQ4fFo8nkcN5ay3X2oqydXLXZ7a1Ht4PHFnMvZQYrYzk9+hBUQlRLTY JlVU/7pH/lI4pslqhZVnasSeYYPmzihCiv2EZPu9xAj7B6IAyTvcZ2BJEJO/GhKifVeb2h8c 1iTHhJqZb+LjIdrdbsFqNVUriXJxJolY4/AaT2SC4vXSZex6A9Iw8drzenacugprwmcGMXz9 3Dm1cfhOXY/jHuQ0PkdxBpR6h/JANEVVdvQAYi2SCCEBmIWutaWwPuV0ioqkJE4fj2Mq3Uiq t+IRZASa0En1oiex4mHMqdzZwJ1ZxfIMHM/U7agKB2ukDrmZc7VqcH4OoW6Fiws8c2nKnRW2 dbjBKJ3Z8bxjQmBV5qnghbhC9eX8iLf0681BJOVGa4fMnoZgHRxNNauGLj5V4/rVehzfPQ1B 4a8R6AQ7ShlxbMJ+vUjDZy9aiRq8UBvj/1JSsDrQTGucv3nu1wojFRjZIJP/5zsCu3P5sjrY mU5m3Lp1NdzK92dQkXsNJd7Y/0Ts1XQhhCie7kBvtSu+41h6+esCo/Hd5h7GSWJRSr9KF4oP 9tyyq+oR/0UE571H3HHeyDyirCZjD3XPDuCRE+d8GHTXINBsigoleFJceeo4yNXaCjLah7E3 R9YqLDepmrOf8aSzl9Ks9uT53WC3hr2FQm3rNwBHr1E4Zq9eOasuIU7Q+kjD+54a0WPUBy0e EeQ1NCU10+mvsLI/o2Hb0FizvZsy2apxb2VOzq0sAryeT8BfNeu6PKmZin66YX1WnuabOGoF LU3T/7etYm+yYYeqQw2wqHieWww4wJ8FWNUZFJK3IR6XRw2mVxJZeNTXVrjNZzgDo/sLpNO7 zD8qkUCG2rKpoDXvtDxpLs1E+IVHr0AoC+nrkvwB2oJQVouo3KXTzuCrY7fkd8UFPJGSyfih BDKRfhvc/DeXlZFW1iVgvyf5CTXhGwL2sbqvBHJuwcHlVt8srNRhzT9EDl3UDe6Qg5nNf8Lv DOlzq0a+We161S5Oph8/reCT1iKGeHtDvgAdcjCW1yAvePIUF3ROx01IyttJvHRx1SAQaMMA KO2VnleoBHU8JWY6oE6dyBKQOYJ4D3jC/52jufnBsOumf5LIe4xZk6TevQDIhEwzyLj5nw/g piVHmKX+xZ36maPOZeriSzyIVWB0xlr0811OTRyilqGO4Hzj8WJh/q1H/o11ixK0jrV7zhu3 ARtPazoK4PWREsYEg3czBN2lAdSUAAmvEdYao/OKyJ5wTfw1cTTKOGq0P7HpDNSHjzQJ9JJ9 Q3vZbyRU6fzZ6eYKizqzcCSuwpgpyIgSK3sytW36tu9NarVTvB2lBpjXZ88+sOV87n1xrRRH UlHTmrZp1ATrl5pYuoi+cXlFp17hAWV6FC8PJqcoTA7ovxAFom4ry8Zu5XqVDvGMGoNaNo/h FA11VD9GQf5Roj80Pu3FzS/YSLfUBx7J4/oXYVxc6VzbWgOb2SwEIOpWFcXIbWi/xlkDKrTy gB9p9jJNqf2xL8aEkemeDG1RALNMQO23+bGbcdbaOigY8YbaxXVVJ0PhWXKOudseYjh8fTqN ruMQ60kWavleXaRzWnt5khi0w1PjdRUMf5RSRpOoDjQhDmvVpTiliabCYdaZQWhkpEsTLdvN 9RwRCJ6GpHeTvEtT2cBXOb7jyP7wx2qDZ1L8HplStBzkBD9iDRQWfWcZAVln57o6ZlCchwYh Kr13iXxlPoN7qqHuiViuPF0Y0FOndTbXUGEyLLljGwQ2kMfzZ7RLjQBHQOriXgvnzfCNMy9z ldgk9pLhpXWhAJ3XYZYVJbOGFHhO+9Wlox4QY7XuAfYu7VWzW2AE9Mtnj1vHy9N5soHBOe7h /YYI8xfw/mmdIZ0INQZhJ1WefMg1N72EWIhrrSHEznYIhAmfdRoyO4aS8EF1+LCW90JrwZ5j HcKH6f6MiO+IEnQmgeJ2PQ6W6/SfmTm4FVdnpslfPBGm5l5ZnxeWb/rJVg5slISfKaG8HvGU WMYSrdkk8N85uXqNkWfneBWu2am1dDspx/nMNuzHjkiLeKT694VdqjQpJqam/bXiT7gF6YJZ mPJu6zPMgo46v8ZNEGfI8zqVFuliP7kloyIvTSWO8P/QZQmbyc8fbxstkMPgH4tEJhG0qGC9 yC7CMhZDhrj+764zJagqdK+40y/VwNaKuNHIA+xlPd8NPtnXEB5EMMp0Y30USOCxxBHWb6J7 kMrEO1PJNrV67Ira8LgZeGsHoBo3VFxk12avBdZNspxy1F3OauULSJCeHaHRrgfH9UXbJ4kX 4Q2VeOWOQXRIBvXd9RSUXb76BO0qIUbI1dv53tKxdudlRuEvDEOJJrh3TprlVwZL8yGbM/vf /+7nI7PK1q0DhN1dLxmXsH3S7jh9OVhSmrpUzdW3NSNsd3FJH1ySxxAGap+xnKnAagh30WdH HZAbMtr3go+EC/1YJFeN4Q1HX0mBVfxUlLOydgGKHVMGQw/NjdhLYpsGZR0sz2x/rdwvmKJU nYq5VMUEvKRPgFqgalBVcvK4QudKA/IcyJaqO10IycCrkS/7i8l+seZtw/9KbGnR5mZvWvaS UYK7I+r0elCbkKl7NGOwnJ2Los4d7AivY9LVex0Sf+O5JYtDO5hXh5Cxn/6N4+d1rWh/6jVz 5K0dHdGZ0OmhRvsDwPR40tK6gG8Yior0q086fl25QZwlxPFwhhsMtckc15YvbglBaN7VtZaa WTwzOxbs2Gr64ls9Wf/0e17JjoRLHf7zZ4+SGQqf7o/e3Mt9vWkoR9y3UBacM3fVz6qML72j QSNFyeNd8tVs+OAIMbabcriGs5aDSoYyEsMm1XfdcZG1P9T5afMgEMY6QWZQbhXSAXOLfuzG QZ7P9HAJwh4kUOzWSCzcRsZu47GI9QJV9DxXp9e/1vSXSHc397PtbivqaHtIBZJmB92pnMjr Ws+KlEaAy1sqIihufmTFeFacIaQbyoVBejoFWpjDvq+3gHJZ/+ZduOpkRsFdmEM/a8rZHcrY JJwQskqRBGUF1LcrjEmflOxFA3Vfdwb3BwSwxPAycmyVb6+0ETkw2HNjobWKpSC3ecF4ESHd EkQe0V9K9GAoxMXj7+/FoIxjriXR40foOut8FmFOO4E1rB1nDvV9wsYhPoFWS4gkoT7jJoPR GFb5vpaz7UVtkft8Bq3HmiloUUAS6lZCMLjgBehNA7oTHG1PAABsIx3TsJMBM+kOG5jc1Jo2 JJrWM3pIF8xMe0SYCxvJzP3VNvofX1jxfRzJWVg3aZ7T8wXtd02fQI9ptpvjWt5BnLVyAP34 BAaNrhJl4mQ3n8OHIlYXRrlE1G0n9hFI2cyw0WDGNaZeVQOL8/PVNyygM0TELOX4CQN0e0+O Ty+ZIzKo29LJHkxAe9v+qlt0g6AqC5j45Pb7oxqSBL+2RBQZzW5kGHJRtgIPhgDQ7BErQvJc 0+NgVvl8rKeL/LlTJqdKZL/n5BMtH1rApAj5Zg3lv+GQdSuHYwbSgbNZrNAMMFtEjBzSzqyh 4kP0SqEnEKiUWuhkcpBeZiPB4XdhXHkdVu+UcshSNhJZOy6WXt1hN4H7C155qjf/3DsFrZnj 6jccbcEaHTjU83ky/D8qdTkHtDqbIcOxluUX+1MKd9WBammiP6/p8QDkQKFT0V/PAQnH3GUd vgcTE65QJq4Ht0Dc1tEq6X7haVMEDDmk/a2+LT2xppFD3UTIjVSefe1FImCf2UD1Y/gB3u1R baKlwGHqcLjCfiTbSeMS8JodWVKztLWdbFVxzsmyl4vDgpcrpksoczgC4/V+qG4LEKhT9ydA EgUw8SVZhtHFO8RH9o3T+Q5mP5q/xtoRgPDo2ADwZuj9QlkxCBvfpCo+k2FQOwuFQ12qcMqg BaFfE4wmTVd9C3GVr3miW+mHzvagufSWt65QqJQeqORHbliYvDd1JtOkEwUypkwuu1SOJ6wY pOrs7AnToJRBRNemhTWGG9x+HpEhYsFyOl/7ZCHY22GOVF9Zu2efddwj+M6z7PcoZwSnpZmu r74UkgbvYH3AwAXL/AFE4zKCJD7QmtukrzUAje4itQ6bxnngFl4hdWs+VgwUpVrmsUG0BtkJ 2db5/5u2n4xknY9KhZQHaXl87oo6O41pn//O1dlDI7byq+TPD/deeJh+yiptUZKlYg5/Vj2O ybQDXQHZJG2EjDtUjMlrF4scfqMp5MoV1qLsiyOpZ8Nq4XEcj+byJwhZk7kJ4pNx86YKwfVO Cgw3Wx2WV9tBC+m1FYVVp6TSICLM93Io9caulNiKc2tkBLMJZtWO5Cw+ZIFurwDU1XkTGCdH DpTpgDG36+AUr0u4QibyQ61WZG6H3uxUK5exYXN9ZPRpfalo+VLcNbM3HKa8iw+aN+cFt2wP OnqjuqPqQ3a43sxwZuQE9gK3iConj1C9+1chRwAsyUoFN6o5HiV02f2kdbv15JkaS0yCIMQB /Bi1UuWY/ZbTwkXGjlTpc+Folr9HzpH3APGUTfbrjS78pCI+701ydIB5uc7Pl8GcFuQMbwvT 8pvGwf1vDGjxS8mtZJKSVGS3b/EM327q1h09ofsQANwh78O4S2TguElMmLeT3jrIxHVQ3urk SNiFW6bDOh/xZIm1NfZjgCRredRcx6rwz5Q29mLa443IwI6agRXCyEQcEyIzFB7aiefmkR7L skiGbhZ7ad0zcH1W10/3p7ShCObFqdrRvpz9ytW7jp9yiZisRE4GaivTo9+7gPUEmTtANUqR v6dxH6rFSZys9ChVhlwry6SnogLbc+N131Hu/wGt7LKsrnGeOqiIvNdGVcOruRhqpSp2i48w +nUI0OmgASUBcXA6Fb25fvRRjg0TJy754WBK+GJ/rVWkusGz93/uflKPyMSWX9g4EGvXAC3x 2ai7D5S1IpP61cyHmlD/bdUaD8kH3K51AqMC1JDigQURnK1szrMjHeGXvETOPKg0BVtvoQPL 95Aqz5/79D8U4SRlr+MtkJ/6Zc2EDl6LpFZa3gZNPNHdUJjN7Zx7t0mzjGbofO/TbnspcX84 SSS8PuAYwovSrGc2Oly8XSAMHHuBliHK7CUaQNslpdp+c7VWIuodxMLS4hXIFREvSNGXukJ7 EOQuRDktXagNhbx2wicUFX6C3ay/IeKU02R64BZ173+atYONdphfMSuvPJEQgqhYnCMvqCqq 7HQJK4Cu4ECz9Jc4iThEIVCS6tt2TMma8EEqEWyUv5iSMx4kMeTTDxbiN+RtecFzN7E2qDm/ wO1pjagsWHaWuwJq8ZR5gwGpQIDukgBwZFs/4NIACjQ6Qfdt9LEryUSNVLkXPJTwHRKi/qwd b9vvAohL+vdHUQ7nunQy9HdNO9Ct5wIQDwYhKWLrUGJCgiXytpLHvNx4w13CoINP/DufrQWo 22nd8jge7xg/FZPP1/jWidv6Ngl13Vlk8r0snXRxfbPmzZgs2J8XTHBs76EuMFopVvPHwv8B G7w1kmTgfFYeaqklyJYbi6WehnT1PKDZ4zbK8+ckU3V0Uum46pcca0h8Y0hLXk4jutmy70Fj 2YtpC8sbe4FSrvi6+rF08R0yDShoRGDdojGQJ4MGfLd2wh00RAF4Fm8JbHypqDfxQIOivIBN bqAmB57ecXLOvOBywVrF8VhRxqIdJYDoejAGHlhjOEly2+dgiagg1UB1cSseGkB6/i9XRPwH dZUKcTZcaAYjT7XevEnezPH7NlLUfaSurvscA7E76ks9VcCSIYoKQDqvpCA0YqQz0GsF5c9Y T4zZYxWg1CrzdIB6xZJMpgWOHULjxEtQz2lP0rshwhpHKU59xRH6gL2aS0pl73NHTaYwT4pp C0ITTbK/zez3VQRHURS6V7uLxTSFKRypaQP06uu03HQCJAbx6YzlgFQ26iebVxsPetrKClDU jLPCXk9FqURZJw+YUGwaTk3oQinnKV3PjqwLQr9odxbwQkvk7sPMAW7unRCCMpOhc00bQHAS 7DHm138ltnN7cBACLyycg7d2UBcjMzoPWQSxL1Odaq0v6sdkAxVP4bjooOeBxng6m/S0d/Lp b1qn+JSW5ij+iJHu4CrPXlyuTUloFGwLq1sWQB8krQoINUELtx82ZcV/ZpLpj326XjOECX1k HdSm7/vO9E4cJPtSFUVyQrwbeF6mAxZ1Oj/MM+Gd7hKz9qFnb4IPIffLVYGFMzSLUu8IK/bs GUlpZq6rT5KM36JyeXUQ4pS1TorR1qtSeNnPNSa9BdAl4YVq0kgVJGw9SDxxyxns6bMP2rCa u8EI4+WZZpE3nW5XakWvAXEmEEys8+N0ciktjYuOVVxCW4pEo+DWa0CA6BqVrF9Wj/LhS+Bl DVIly7PWdvpfETIkTSHaig1/X7p8gKgfn4z/pP1+YZE+Yq5UfzKfzprTIBA6b4137/e/FPBY zOITAbHxuy33ImRtdpzuVY1WNXBuD9t/BuIBouayfEYOzzP1F/Sm6YQl17waWenHxUAfTQ0m JfqL2/9wzuNXvdnzyBncz1Jpd3rsrjtD4wMO4O8Jw2u2AVsC5tNm1muhisgdd5XPrpZw9Z7Y GVSXVxlGg6U2KdQU1ZYKARsKVKROwDE6Uqb87Pmfi4qrCvdttM6qzfdGHtUpGy9OW2fhqelp S9cSiFDheEnSbNOOixzGzS7JbILBDC+z1u2ZNhZXtUkwYi0Pbk8phqniiAIQ70vpebdzn4fq z446x2qpSBdrH0Tp1yfkZxi0Gmk+GHiQtBbsj2ZLkoKRCDBGti9s7qWo4b/A+oT1UivsBVje 9cyaTjHpsgu0O24pqQC9QfscEpsrmuI4QacqkH0jHBqdYbUa51iAlH6z/iEWQMXKilAWocsz b5npizIsiD/Kx5+KeRfb1OtxWqI85cTFUnXNjMqW8u+z77VvDrfcA/FrMEN4BjTA99DOcJ5T jv0JwiZE0yF1QAvu7kW9yZVcY+Sb8vsU/nvvYpuBTzJ8PrPUFtlYhF13n9zDPda1tFTFcF7E 9FCtr1dunztKMIYOqc9B97y3gfqElNxKrDZTJ6adsZx9X2oq0wODdbJSPI3iYNHPteQvnPz/ J/Q1Cqt4FF4SKYGsnWSiBnB/Wawf5r+rwvJBibeHD5RllvKp6FYMEcbl9zM614HhHVfQDNzg BCz27tbgMgGWN6mKkg5qL0w8zEkoiEOHTcQWpRoRMsnIc8UAIvrHL0pmzV1Y4c5s3aHNc/Fi cp01JC+dJZoMUp2LqkPmhXxNCL7sCbwKtcFs23/8A0xcYMK6ia7t5Slb76xvEtfnRZMNFd4c v8DOmxvjjHRn/cUhIirHwjxunk2YI4/s1HLh1STzFgbs24qx6LEVj5o5mvErdKP6BwZwP3oE +gtO8Ez0SE4GFKkMEb23m4WJBi/PCjUqt7gB7XLbxdmDpxX2nH9253hDt4QPFQApsqMGDQy8 1L1svai3zzSdVYR9Km5DaGjn3i/ih/4PCzmMLzJPCL5kHn2JMndMU4w2K5F1muer5Sij3iSn QFxmkXtpby27boFmpuNsphnc+VEkkn0P/vgGjtr26F9dvrtl287CoWqPq2NVWqy7YnbA6Fvc YmI87OgWzq6ZNWkY19a5/iPmJlp2shql//otzNgYMmMVd8Nbxm62V7Kt+vTHOJHTeyV6l/bV bU5eCLVnsAl5MOkGupSxSjlr4Kv5wv04fH7fsFB4b9L7czBiJh9QgSQo/wC1pKInCI4e/cft rxP0K7+A8JiDyl/W+5GMj4XEtOVq24kNc2Mon+XQRRcVCKWS8xBxyU/vy6ZQvfSmwpUPtfgN sJUWwGOElejhA1ghImcc55mZ41y9Cs+jUOJl1KdpJpqciOa4JNzzttgHbvO1DP7ho4jDUCla MV9N5XO6EsocHzRA/FF9vysivvnVQrWJNOfhgDrrhk0Uq2XB4r8LSU+f/K193Nlayob7FDyh xxeAf3SBHLu0V2lMzvaMFo/igdPSh1fU50fnFeurYnjNWvGsqGc3TbzeuastavBHO+bbGOYg DVTVmZlGmGBQLd6RTVj4XRuaBzVnO188AeDe9jfX1NdtLVC2G9uJr2brPnVEZEWEBVClvp5O kAQPcExC4+z6peTDZ1+unnKjOOtKFWHLaz1wZXPsxMuMyl0EFQub36BMVCWah2PNPONpNJqi +h4w7FY/rJI1sLlBxZFfq07vL0T4RkwH1dgyEvVl2kIdGDAyaB1DdsUSsIk41tBlYBZuVbj/ E/uvf/68EkCMJwgFbfrxdg2JBM4Q0nog+MqxfT41/k27AMK2SwVaBQGAxINiAQWbXyHp6YVa ezgZBgDDKdq455Gn+bv+AX6tygCHgo1QTAUBtprU2d4aNZ4o7ZJZnZLJQVzHf7FniX6HhMel B6Ryt48b0kdNZmHAhNuiCRT3UxbD/3MC17XJJrY+yjHKJjupw9gWFbr4A4XtUF+aEU2l40cs /JlGPcSFT+4Uxa4EYev/FtluQrUt5wRM3sK3ExxpzKBg/xCB6fyNde+9yuTjaEoehc/WmOsQ c7TbqcLQNqcx4L5OgYs2U4KgBdR7njYV2RSW0QLYN5EfH4Tgsk2XJJg0MJDJs1Yh00ddj4kk pxhjvkjUflSZbhburKG0pjQKf1bkPG1+wM/hpHrHc06BQ09Q901tB+aS7PkO8/y2wvEtWhlO oEtv5QCW5yAMFOFfzSegb7twT6wo5Au+THV3WGX/xkJmWSqSEZINSY8LPfSrr/Fd70duBbnk Sg4Y18hIsMg+OpE7VajIl3sUmjV5Fz+gMh9Tc5Z0lZwD2IryIDe18U96vQL+9hHJ8CSvy7SN pJA4pseLlQ9Tmgt8G1fzivI7op4Zo24anKKjsr5TDwR31omY8n4BOQLWmjx4IvRLHMij+Pvy L63ds17iQhkvSWUmHLnhmKsE+ijc9pAwWvBQEuRrenlJCrbFMOFi3P1StSNsVbySEaRim0Pl Jwj1Xdw44lb8DRB268L0X5J7EPo863cE2RDWOuQnhl7ZuJ4KiZOsJsYInH4k/0PVRmsWDPNI nzrdYBCEhSA8gJyYaAFk6ZHY5bU/zgAfBbHzJEX64mUkSDuMif+j+T0/4aBHLsgSTXFm8008 5b0mBCCPNL5MbVgEnILQizcYJ82oUmdPZgLZ79YrXb1aPqEYfGyxzujjf0LauPtAKKzAs/lX 3Fu9JCuVHk4T6FU1YlmzgUSTkKksKKEpu47ke7q2ikJ6S2dzGNjAkEkybhAwKY8PFe9fCF17 p9q4xN7PzqbEiaLcpQiDG5VoFi9sAEoj5IlNZIiICNb/tNN9HPEmskpUe7IzI3Wh7XRTYwKh gRCn/F/ZlJzV73laPZ0wBwN8hfCjS9FDl6W6BEFsjNvxPLk7yzHqJbbjvhTdUdnIzNWnpm0n pdrKRNnhNLX5xNbBNi65j2ySa8+urfDcwf6cTUVfqkMfVdQe9+ATzSZZJGjb/G9sqhepH95p MfjCKROan2o2bG8tjDq5qRzeDzZHyTGmyjjxLeKwQRfwYDM84Vdm7bxfRLqHXoRibg/ank2E +8Q2129R/gw/967CguAwcvvjAfX/ZSrcWOQFaFR6mczPF0kVqrjpQdcrmq9Hfl6uk/mtCLJT O8m0aUFxyxuDdj75rVsIvhQzVg/Vcmt6X/PHkUHNvMrVhjI18VzfN4BNbVk/yH/DpEePzkmu Z7BF6PoG6SZZ9BKaQ1i1yugbwIaVILe7AabsffQCap0H4cG5nsav6AB4VgN5d3DdNR9Nify6 Dy6MCYZrLDAY89YkRDkW6FkWxQpc6hyt0aKQ796YGatYAVvTgk3ers4pOiyt8m/Rd2yzkE85 FB+kyWSvsLFklpr9RebrhpERU0nGJVVyrR/GpG//Hrju4rZ7iFp9P5zIIl5/E238pedN6F0d BkaK/0Kez4b0I+CmMBmFt+KyM6nfrthYao2dKQAT0Bi8t1JBNXLoCx9kecWYXphl8T4r63rv QiV9GkDXbWjOIfrmU+seXlMYubRUdVh3oDSfW9A5LvhspFicyNL9HZgeeMIUlB4jdYN2Nq6i D9wXk5CCxS+3LjSz6culAsnjguBBQNN8bDmUwfCT57ON5MlvDOj6hQqtfvin0bv6aYngl5X+ VfdksJblbg7GE+OI+NrxNNlSYoQ2+5VDFYWmpBjG46yaJjhU/kd4TEKPe0eE3KWY/Ao2J287 JbLK0m2aM2wuCOAGdes4wNlA2aeuQBBVB7K3rJAOFhOIuElLcBi6UQkP9h1tv8R9LAVx053m ikFwG0QSFMhKtrUe9GwwUf3bNhL/MweBtnQ9AR+0jP3NJY4SoJav8Rjm3S7OiyX8oGvZjcI6 8qp+DPaO71djbLisVzh4gEGoUX4I+lQGMdlqAHpl8IVMnVHWao4YQlKBeh4luXHeNPNHlNW+ 1Pwj4nM+2dgVWL2xd0pcoPxjG/gdEykFll/OiwhjzP1yEGXcwa1kL15vLSBwysqN8BfAA3vC iPiDnXLKpYA1lNR2DPnX5FILUUQOIYHp30r8FIXEtFYiJxw4wLOj+4oP8iR0gzUz6so74GcB 9gF33DQDE0B4yAoShvaUzy9hWEuo092y9n//PNNBXBR9VZDbVTCF1OOLP7V2zZ7+kZuc/MxL ohhEQNPzkhG8MGUeqXlG9fQWgRZNAUaKgwzDIbmwOF4sN9u4hpiMyIN3hZTVIZSVyPLEJ2OX OmZXqkOsRmEeCfa1Xddx3w15/yD6y+SryM9kuSnnQbxPpQB2ziTcglrOc/1/yr+X8L4VUEEL 1Bivi91oBX7wS4LgDMOzO1tRokqnOn9Gtuv4X0Ty1bzJ9XnA7+HEwkOqaMZ/3QRBippKcUqC WTl28T4w7wJmPru9HqBlzCth2OjA0w/KWgcWlwut/NwVlPpYJAz4dGWkbM+TuEA9ibZ4yXaJ 64HLtX9TdRnO/yW2Emxp3Ht/F2d/RAV/q3BReNP87VWediJ56OeWD+APabRbT92PSkkJz18q +tOao1aZu/Bd5RljpaoRIDFntaGuO/CUG4gk6ljGOFC/EEgUjkEjkH6FwvmDFxs97jp6GXSX I2mbL1EEnbYXAfP8osZiilOWiBPvSwDZp2Qib2Djk/yvwtj3Kf0MHERtnsEnxXgDbsJWIXVl 8SWLgykEDajr2iKEpfvyxxpgDaia3vWhMzQp6K/2RjApwgR3THugea4NwJKRgz8SOlRanM9i 2Lrq0S+TLcqna+Rpe6p1PXsArEF/LIARQo2yfY8y1JjcshWDJ/Dt8z19tD6MbBk74uVOXob+ UU9nTDWPpfoHV12lCv8qhR8xO1RDwQMdPYQJxIhp4E+y6RgJ6bDzOkKNs5FmbOgisCeZG3PC UTkYAOvUMQGMKlt3fJxsgQP8Kd/Ccbe9suodzAoOGNe1+jRtxIkZrztrEBOfZKgTgNKqztxu ypHIQsdg4dzJaNou7zcdIvIbV+/e1DcxTBsZS/X0SaRukGZxwyVbrk4UtaZCvvOi8T9/+srt p8+XHYTuBBkp8ffwtPge9jmqQEX/5hkwUyohE4x4kxL+xcBBQAFoxmxkkDW8B65TlcQR3Cqe ag+3HqX3TRcPaAOMMpYnrVeMuL67Xe/SY65FJv6bCfAKZuJ34bTRIOQQ77mlXmhxA13CRIHi g4kxe2XQNQtmqq12EfDBx8WDnC5KXNbRzOopavJ+bf6BABIG2b3xTVM7NscDNsnDbdZnD73q zVj2X1b9zI/GGODuy/aNHmQxf6J+LlY0pZMsICRnJqYtR6aczQ5X9c+E1weyS8YdwTAKBQsK v5Ji3LEtwOkOI7ARo7472kns9yMmorLTI81G54p7XpSJT3yQv7b997rMZyXrhNthys+b/Xk5 dq3JHINvmErmBydq4q4UJisraacj7CXe5WFOcu5Jn3bb5OZ8yl9xHaHfrRpjHAlzeZXq8Ox+ NyVaztE71z/U8eCVVCu1e4vOljAo9DzH6/XShvwOyHGwdoFu3s3+bkmdUBmdvS0/g5mLS8oK nxKajA0ft4Fl9Nev5YRmx2OTqwMq2INWIQGow37/p8aGsxDcvtRXLboqYLwRqgMWSfzJrzO5 w4w0Q4+mOK7U8lofdNwwR5w4WIE19cH+LfOoDKr2EszUtdtP/MtS9RIL1QAf72OYVycpQjNv l/iKn7xLG2oo87ofdkWJekuMxqjsuiKfJ34memiCsjyNhcMEJy8jtc649+ejeiNpsH+os+nA 6cV7G5rbnSKeaIaSp3VHGdZm3E/Thbhri5A79Gt4o/eTzr8+xGMDHXKSSgyzaG1pbTM4oOnh ueGgLpKnGi/309dG3tEJGtiULIi0HCiSIG+jjD93TppOmZnnEwRTH0YOCqFXkXo2nVbtsLi+ vzhDkFEAffTnet82ANUK3guj5RJ/tuoXL4TDYxTnWZgKKdbCLPYBmOjJFk2JzTbUSY8FMJCI EU1YApY8sMwVb9cvlEfEVOjQN52pfRDMaiRlUedwllgDuMEwMDAVtTal4xbFiMhHtuLIffvX 1Y0Y8pV/SBwzy5jfbDyRUALPCm62cfTcV44RliowqUHAmzBkQMqsi7rQQMI1k3G9+ggFQv6a GKjqkp8WxlWvAq9REmqON5VvVuLqoxXzZbnc3ia2NN44tBnbcJpmmVt8ljWu2UYnm6wRYLZD hUkPSZ0CRdE1+FI2FBTzkckXMnNFEKO0mgyS/5XF1RhRA5mM//wrc4GIpN67RPPusyTehJ3y 86q7dNehIYQkn7RP5mAVKGmytzNTNneajTf6ari8kEUTbMkVpx7eCwLE5ISx3R2yo9O05Tlr vQd0McxrXvv/6qZGmtZE+hCaajU/f66AWc5ybdY8pK1uRvjefHxkn79dKflnjYbV9APwxZM2 +5Wg2THLBTDP5fEY95l+Mdde+M50U165j+xbEZ4lvOAgTyydi569gi4zOwhrcKU7i4TxNlzd MXuT3a0p33jGxmEi28srl6PWubEXJEQUVdoQU8C6X+LCSAYM0eNM9w4F0tOVsfCzkS836Fpe hKj0msVy3MUKmb8tbJUmm3VjzimuJOxcM87mG8REKw3LcZIbcsssl9tc4decarPpnDibHJ+K nYA6/EXXlXlfzjTQ0hwmo+xJwIhxtgV9y5WceU6QvVEva8g2UxHOpUytcPYKv8ohxOK0TatO FPJl8FkdnkNfBzGdtX9vqxZ9WFPRMsBfG6LlIZQlBI8Pc+wI50BS+bw4kOW3riDyED2ks5Aj TO0wCMN4FUgcaigyTCzp7Mt6QjN9x8l28TuPdvJ5Dbow6shgiyePyV71bwrExzXh3g40C/3N UbANtoA2fLldRFFLqcKuvRBt4rIVfV2R/C+PK6M7IJkmyxiVvna+IUHxIsK+bbvz8F2WwFFU OWwIlR7EWE2Gqs7T88JEvdXjNI1Ml/lUBrSjzKmjIAtZeToEDfAaGteK/dQelpzdxarDTfFr UwV3t3saRXRwDlXL22POE05M8D4HgnPAO1uZ9Stc2IMy7zAIX/efca4DbqXL2moHdEXLcVnM OMPHLwHpxduIAbqHcaxrmYefXYeABJlWltp1sTS/IpuzyUH++4nHjTeHvxj2VJO6/P1Ysuoy LzJ93ZOX+IELH6rKookOkST2LFIhcVEc0eOcnWpQG9JnJkByhABPSng/473bEbTU1YdSqIPS MiwEOY5XX1TlaGyyMIZZ7WmqY2CsaFT7MODSIf6q/fS4/PdYlD4XL+atbIaKrgHFZmORMMug 5Wz2ECfHrUV5cSdIhBdMGdrQxiS7cjFGFQQFa8hGdTCEa8y0a6lZeg3OB4nzIijBs0j/SLXk ekkiMSKrZoxGjgkGDtZ9pb06eYrQ0EyB5GUiUhGySkNDYY7eFmwRn+yWmZX9fqXNd9QJZ+CS wCUaTmleabcCy7KJqTrqwv97wdbMzzJIoKwQa0eglSYuG9GsDajJZpJLF8rHYe5PKSFI7295 25d73lxoIR5zK99IVcZlhgMtInnKhs4Jqo2Xgo91EuWy+gr6DJHNaIEaj90eG1K8uYyXC6ty m2uVyFvT6cqaZHGeHwGKTs2rAN2Bf1bWYmlViypq+Ccq0sonNUfb87bSOHDEJeAjPFDQ70OT yHl18Xj7SVWdNULyt7Kc9F/dC/Kz7gDiibBnsztMTj0/JEwHod67igpg3KnEbWaT2X5WU4eo reAuyxKJbWYFG/rGuCgG7iiMq73vP0I8Ric8aO5rwZWwemrnW4PW3furYzT8UtIACUKV7Jun bLhhp2sGagjDWhOFsGfR2GwWf8dQ/8VfuzNxnWkya64zcBM7uoFGLv2a4j/1qOBpeKTw3LwA XulI5rrUiMD/oTrm4OMCivwEU53lQArCgBxwh0k459Srv3j/GEmeFqU/AEaNSoiF4BjyuOxC ASlfft35JwLyzZifFSz8zMsp7NTAqO16lyWaW6hSQCs8hyWdnk20fQnkK25NQZ1Sl+4U9xY4 JsU5NMQzfJ7oFaDi3sB3JHRMORH/bSxmOeA1DQB/Wia9tTFDPMY+gwo6W/NpMKxdQebS1/Bz ZOhImYKlh/LpiOGvqDZeQovjE6EZmHxcUC04nJLToZo/UJzFNl3NhC1CfMfQF+t7hdLuTfQz qshmV2Mqrv/loyDgKX2KIlqmtxVl6Bzp+AI+442vQDFtkLW0Xa1eGbWSU2mC4pqSowUCYV7R L9LmUNn2zGxweN7ezG6bKFmrhdxPT+9PxDkxe1T8tX4M677XNfQRieCxE5GD6xBZ2KKFCbPo Bd9+SfkvZNO6WItfX9ImXsS0jen5KpotchS2E+X0PQx5JyB8c00F6B/tIKoEawdGLIiRdglS d0q/QEqBsoB3jSFl6Oy0Fae+bD1wi934XojlHJ8rJwU7Bqa2ZfdUZRZkNdYBJ8Ga9ZKymj2U oxeAi2WN7464p001xaLGq3vP8nFDGqReBNVOEF94NAH8IS32pl7vJDSqwppp+QKvHyVQN2RQ QwtYvVelzH/BPFpjzS2lB3m898Q9bPioeOVqfohviZ+EdO10Z+kHhztCvuWp3xFueRTOhl8W 47KR/6RN/1XlW+C4DKgPMPy3iqMqAQ/RiGvMyf09dolCdv7JnguhMi6qDqlGQ2rLCTZGzdav dIumWjtbOQwvP41ZEW955B1XYB3tlLsbZyFfu6FzDRZvdnbyg08Yfuwy3y6PVvQ/NNRWq5eP e4UNvKYL2oKgqfKbfZ6agnfAFjowVVj034lSe68yjpPVwrcjNKNjHV9uzCBEmJSBXRb82yC9 gfqImZQfLl+WkrSxvpastl/5Ig9iJ/Hq3G7XtEmtjJEF1AhBn/c74mgzGpHNHN++nRQnUIDD njYY2Uw+8GDuMO0E6OYf9y1oiIngCoGZkDuSn7OQ+EPp3qzi0QVdT0mG+kNGmft2U0driADu xDboS7mOzWmTpJ3eFTjhARd4d23o2i3k6Ymg7IxMaOqMMKVI8VeQaRhCCpnX1Td0BsEYXwg7 y5nTGctmaCyT4aI29HKGHqSlJJB9oD0d4FGNVj7cAmQJQTCtpDEJHN170Y1Vn7OlZV3yx2yT REMBJ5FsdTBMApAkcfxAMeKfAv5GPwgwvklGRrrDHeW0751vni1u4sufVDb19Q4GKfh4M3qG b7mUJU/ynivt8GgJbcCM6OARPv+eSaOSDlJ3i99GmztZdfE6Q7jw5FhPlYk60tEznKmMphRD h3XUBI3aKpuPgvr2tgBRBqJqbH7EDsNabYhGKI98k/5RjEbV+CpT9S+ooK1yiyeD5Iyv2DCG gYH+5z8Z0xxFCuwzdNwzQkdniSBLz4wCplFljjYC3FxAdoOuUjlEZgdIBxMtQnFHSeeC2Ocu CavBNLUrMpwuJwkNdsF8G4W3qp4+uiFJ3YbDKiROA2CxPmv/GZF01k4JejKNYpBdVMU4tgb6 FdC7NPvUucEupheTTFPnNecr7txul3UfEHtCIU6avD2J6AcJYLOlwCGWQ+CJoFc+R1gl/vKz JlW8WFvL6tRboaWrXyhnyKmCGyYF1N2I2WEKQJzPktPRxZoaSmvqILt83x0IR0aFfd2dQYvc eH5+LLZxVhL5jOniiWA3ZsWyNMBbH8LdWlQ1g7kYSZE89VH00QDcRJaXqrrpyfuw2T30t5rr zvt6unewGodjSO9W+VRVILLC1HIqc59Mo3CCLpihKl09G+Ch1VkdhOnvXnxB5MwSVfDb9rp4 3pDlnk/8pA9gT3r8JGd9w8NBAVv+FbGyjp18MaQOT4rhC3HPjUqL+hbuEr5hICC1mkwvDPHl CjrnoP8CWDFB7ou/yYgrjQtmjQw5ujHpNXQZNUZQjNBdW3U8kvQQ6aeQQWWv0iJU3VgSRLU1 G7podYI5uPdqds6yQPZp607jG092clAp3YdPxV80ib9Y+P0dvtJK/rw5f/MNs2SJwbNKf20H WJrok1ye42x/XypbIrLuw8qClix8bf6gjQHkP05UoWuh7y/1lTt6+m2WFd/cR+afPIKh9uMc 1BCCHoBrl1JEECouccEsaip6ES6YjyaXDluc8w8+RW6H/ZRxFmd/eHoiWLiLDbq1ngQnaeP8 wy8b+90yVFYoW7FRlFgNO8Hq3Ainw1HaaGIoRBjLiipIT3cjkRgZfsptRjaLN826TwYK2sDP /215SnFKVDvL6heD515iBfzzPJb8tH9sea3iufvbr+UM7DxSwAIr1+mgHg23TpYjAUg9VMRp H2PoftEyW4xfrD7O22230KIVFyi6zHOg0djg6zbwvnOBstBzhpXquTxTBXP4QqbxbuIxJSDT WQsYhnlhyhIRppiOTuTKiWG0VlQiUmJcAJtY30p6iad2gCVIIBovZgJD5xjXd6nHV8aJSYTH RTX6scjJrTIuLRFCjw85/PF9yc8W4MZZCeDuZvuHsMuachnzHyoLjBkrdRAAbjmr/1sAjVt0 QaEnowgTA23HlQJsLVR88x4NncfSaNog8oo2cB3Gc6foDuqKCIE9gl8lTLG5eKFtj33a5x+P qbJAFgaWVFch8pduaGXJKQzB59KqgcAmMFHYe0gO6xq0PbkqMEyyh83gSmxLOaoWSJCwPWgk ptbQpLK/J8s0xGBOx1MF+yFZkOoXvv5rQ0QJejD5x4ZJ/18/BjsEuYef0ABeougd4OIhWHmv 2kk8TylPdPhp0AP749HzkwAK8+LVyqN9vzrV4k2Q+OehLvueSyVV5bmyEOL7kTRWwlEi1E6q GbWJsIMurUPTCp5Ixjvmn2JbzwLwm06AYTkTFzkL2kScQQxZsNeMvOKkoZeQ514JZ9UTAOEE 7U6SVMJz/N12gQJTe1WTZeQFeR6uCVwAjjKMi07BRYOYO4ycg72+Hps5SzE/VoX8HuuPMdfC jXDWgLYnjlcEm5EdWg2FE8Zm8CYjXEm/ukqrMTtG1DsI5PamEvECSqwTDddP45vAJIyopt2y ATfjJfWsr8wPdxZMmi7HjD65flJQpBl5/HSygI7a6Ovw5GKrEhvJLu4z+ZGpPXrUtmDo6Uyi 5yjblzPAeVd7bBvw9+sLVzapwymUr7H6gBZwu7sUIvnKM4EDLap172oIBeVGcLa+krhwT0N7 Z5PGD4pF8TgHPj5PkYbqAHkiIWe3tXhWFMLOAJ0cRUzkb15/lOKFp+6FUUhZZk6viQFb36Jm H8BJSzxL06uMRmAZBliMUtTF/f9VRRBeSrdXGiEyxjhIjc8CurXMkB7C6L1C7KrBAWJc+K8n hAilxdlclqfTCvCEp3BbHxcftBW4R8ch+PlgC5iqCip874QxbHtDknYNPB7uqNsAGmVJ5Pqx bfJoS41zXOBL7rC+ZxhQkF7sTcEJHYEoQv55BxzU0tKKLDcZ5m8pOh5c1xkIefqOoCGD25Fl d0H8NxguM+aOi6GUz0CkvtJiofx/tI009HRbKsvDZ007zmsVuNUEGyazstLktFCIUjH7084T BDc23bwE0dPoco9vfH5Hhc7Br1lfCXTK5ZGmZVwd67/BylEmFA1nufOarml87xHdYwkM3pjR S313+7ByZkn19Y+JuJwpbubrSL8ktuB8JKrNlOQYfwnU//f6viB7fEo9mn9jXtZIn5U8W4k4 LR44vI+81M1sTWTcOL3jYgy06t6BO90785yq+UWX6kqs5V9ddVOe3BcVMHWKkoCjZ7Z3K4ab ecTqSGgEvISgXkhPd3Dk6KCRTpqh5t1XqRcfqhgIWMAqQjE9u/v9FdNd0F60cul+uEitfp3m 413UqlaBpaAEp6umbk28TqMsO9hFOTyTWbCSMuzJGl02iL/vjrAmovGtrjiQyAiHXRUrUwSw YwC2qCY5Es4FOuM6cQ/b20TwWp/4/WNoBscciSPLMpO6dJpFKodF7P6gzPThRW3e7+ogSNNP 5uDxJarSPCjtjUAVbFC49cTfPuQrOniporC+wOeyt/gYxb8LX4nRBwGf075fao4MvbFxLeWQ Ll53uevuLBPFX2U46KB7i2LG1cRk2GnCStk/yLJm3QSPLFjNuf2h3GAw/4FwyGPYSfJs0nZo CcwbL7o/kh2zJeAzDO6hwxv3TzsW5LJgs2pfGl932ezCWA5kYaKyTSsVaxrZ3CS059UaHPz9 lylQBsIPYJ03Xnc0aTl1MnQukMHnZQwF3+3rca1gv/pXtwdUIJgC0ogwigEn+MIFO/i5fHJ/ 9oLIKjbJ3BKzyaCY2LQotxlSmL2Wi6gZLqsZSequ3mgEKSk/FgooSVBJzTgtrINoq7XnIxL/ llWwbS0Bz2ZARMheU0exRUHaJPawX6mZ8kyrsH1/AwEnYgl4iTq7IQwLdH3z1QjWGnfkeqcc 2nChk2LPVfmlIS2eU/bRFtcTqePh8GBsWQ8v9HtbCuDaoyygos5TAMHO3BGNs87xsW+uSZKf w0h/B4mp5dPqD+voCG//xeW7wUN35fK6D2w4R1HXomsmmq73H8QGn60xM1Zp/sO6zu9ySa7r cN95glElqfrDoAyVbWLdJNgIZOEqHZN920dzI5Hn9YjdMIaxeRDh3XI7TD3/tRwejouCYqYY NrMPDVED/gx5gjsIXt4AoLYFLWbbqeIbkPCjj8Z99kFt5FcNpB6JWciYeKLAjvc+yvZF2oMK wR0zg6uupySqMMVTOgwk3uQeo86JFhd3PeccvYOZ+xkU99zw/bGbAhil6VvMsUhUu1i7Swje 1Wcil/vBiKPH75+oormFQQI1Lpi/lYglRT40UDWxxCl7gabSQVOJfNd7QSuu7wKmckx4BMv3 3EEOCPc8e58qk6cQY8r44V09owS6HZHEuvtobUe903CaIcOJKBme9YYdDui51IyGNvQZZa5N HUpRb9yzetPwJhvz5f8FK3ljHCD57sW/xtlmTXx1mxZBKYXqq1v445Ii7Yb+eaSqSwdk0jPQ kW40c01TTZNXYqp1C4XRmtl6PSDH/v2uhLRCe5DNOdNrrrmm//MWNqytwB9ooTdoVUxeUNdV jIQRjn83uZXQbz2HBRnUzUNNFWuJocq/f+MUc+H0e86zyJ/iha8KuVBBbYCcVBDtZTaCk/ND 3BLvoiaZvm7Gnf5C8yXXxA2xoSCH++dqiAGINeIaepAHAD/mbjczU+v2BbsfHSK8L30b30e2 O+Ad76sa1SlMOqcQCjZWlmw0YjoxNxP1r5lH6Fx3PiXwSk21TXUR7myHhYV1ZBmT5xvPaRZA Mc4jNeshSR1pZvl/hze3lZqDwIXJvHOLRHQKXSYbVbNtUO9nHiTBjXZJKhYhmf27kRSvKrKU kB6GyZNua7ti866pJ4S9qVlpMT8CryWgA8DEKnNUfnQgpnfzZYH1trERimc/QdUyVOL5SYEC 060oZcdLpw+J6IX4hfV77Us2qK9NbLlB8N6t1S3ClGX9w+iHtqoCXqbbm6WgZUZ52XraKsY4 V/T2uf64FzGMkWyOkOIVfzwmA8bb6zJEtUgqGtn6xht1D8i6h+toNv3o10T7T0ScC6/OBLaO Ogu8YHm5XQGRDGZNa9xEVIlBnEzt89sYrkkk80x8aimvI5F+arlNc+nAe+8K0Vb/zvKaNUHn 2bXQSEY22FhynkqP1rfz6eNlzIMpQGkmUySdhCijy75icUzQ7AdfR/zRXwIDi5rRQr/mKJli DOJBlNkuVKMyWf4SkKTTM1TNQ81l1zaacixqsQUjKV7E1rfcSLK07vIekMBHvL9Mh8kaTFyk FYNB83v+WWRzRHfopycj+z+cJfCU4Zaup6nVbB2ip5juXCWeVOGZBQ3NOhCxW2i3GQZXVSUW YIFphkgLewcEyMiMPYRbOHbuhAYVo7CKDA8SlgfBVmOB2hDsgWO5jPsV5mbb0MBNdM5t7h8U BQgfcgXRVvHSK6rCbcXjEmR3ZsuihN3XOyYoBchsK+SMsJeA7dMLb8tzfbR0ciprgL4mplHn o8ugbrJNZ71Xi2Xfh9iVs2u5FSutHkYv94JclHu2e23L3ru/MRUtKKZxEIIMIHtb2qauYekW 15D0JQEdzYpwNO45r/747pL7PUU9g+MCRishjC0WHr/5NwIJEBYIVdAR5HhR5CDZQCEt+0E5 mtWGoQ20Ma2TGa1S0xyugkMUlgz5tWO7LNWLFIv0ob3DvWvznX22HBBFGsA9KpdlDQy0qrfE krE15vrXac3c+fngimJ166YFs562SC1SGs/fQvWx29sYxltu5k5WrK6jYScAUNDC34V3il7R r6tis7T2jmUYEPFINNRXLNrPl/SSM+8qNWdnSgESFSOauo92oDMyrID2jCoXSexntymtbvxA m50bNtaSiN/amw5GgyAxzvrPmWGLcYK8F5KIOXsGGTKiW8WCXCp+MmCb1lRcQeTVFsnhP1RU 5wV8z9JQP1wUufnYG7AtNbc6sjhYHGDhuz8ub7O50dPPw/QvaccyVC/D/IvagM4kdEd5XTIA Ky04izYVrEUWUr7UDaP8YMRhhwoCnufKceIK7Fqob7mMH7MHzMd6yECuz+94O5dfhsK/1zge 3hCwCBmTiy3ihxWDfrr8arcvB9ThCUT4U9zJ51bXxWon8Xd1btT433ouEgxmg/Bf1a9LkTqg HvGvllzXUM1Ei5oF4Sx4TVyEJGGqUw68m2VvdCg0bxt/GEWhD4fWjVDmtwokuAWTyE19ojg9 p/8dqaZ2rbDMPJ1KMM7pfCLkxn18YSCqYZ3V98s3Hneer7508c3TZI664yVA10Ot3oIPq0Y/ pGlZlvAVjmPSUeVTwUifsrVg4o/eJfjs+vJafzV64irH1b4CrHx/53vmxBigRCbY675vgubA mnv2tpvfkt6w5r6jBPbpl3z0FfSCW96N+Ac1aTPTEdWVMB1ebDOv7tEjABqCG2VN1Je+PI4x 7wt2uWqtnggrITxdbELC/p1XlqXlM9tNwCH4FbOcb6ImWxKLBbhLs6FJ/y2RCf/JDTE/0URD 6r9hVhj9C50WJO18hiPA84V2GAzgL0/cPbwCUgjdlb4eWj61RToJs6k/HrsYIIdW/3cMTP44 Xv7m0qTjHPgW9LnlnDRVHS8G+/6N1505f56C9f5QeHSI65iwOK21yzxXfkYowBHIk/JxrsRl t6feeRVE8qLT6YqZHB7N3b99enZTuwhzNoNathlnlzvbLPkr0b6WgEBzFqdRlnQLTHWGys8x yoy/6a2wJbifY1XseieMccRGCm1Xs2/eyqTdPC1T5OMtw5IPDak1rshCpXB9pvWGfBKQDGf7 T+DiDW2wcRBY0q8MHjs7yQg/uaqXl1NRiVfjiBzZ7zwgiiVEbLq1/AIw2tGcE4mFW6rrW7Gh kxe6e1vZ7H0ukys60RYAy+y4XVqBtlUD8zvVWuWZPkE1bxk7qEXiB07WFhXMJzk1BIi7cqYy JPm38HSCFkQkOSidUCcReOemMsjGGnbzfUT+OIv9FSvmFO8i9nVZh0ADkRMwxz/0S/SYWAA6 quleTIBXNGxcy0WRAMqY5kl8QoC0ffAXV/ZzpkCdeZGHmq3iePrIK7XBjtlxZiu8PMoVhnFV snOh6KFH8t+uZFmpxxnVCJ4kOGUFGwUPDBn6AOuFW4Ds1altD+sV0U6IjTKSyxDo3dIskcli cxodt6OiyoBP9JecIPimKayplbCloK4DVSW1CJov4XRP9vCVSi4ohN3ODRPI+lvC0coimNd+ tkieSc9fpgtnIQOM/KxTNZoiiuYrMwqZ7lK77WO5BoJqdvr68InWo0atbLQrkfWXEHSrCH7e bNPrhf6N50i9D6sb5d51LZ82jOaJWZ4e9C0kjasLxZeKXWc3drkzKfgsBIz7FPUufpvsBa/C PwqdYgyjqLDOM8Pgxhdv+r5aFCc/8s7l8wG3Vkg2MvTRAUeyYNBnZ/RmmNX9kHLf1vJnVdx0 +pZKXbU8em50ZS3lei0CEgXrCeyW7dzuQBupSB2VhRe046EqAqRLImq9lcAlUlPXo2Vz2kcu aEL3RN6Wy8gB7EMuVQnh3bD4k/zkfJcn9opG0g9wgepqMnCf59uNp6BNKPiOsCcTjlIt4xXy 6KWEKvWsqsLj2RIAIuW+9X4R8m0Yz8cp54gIU+BYvkk0raGZlm/ybtnndgQ5TpUJR0I6FPUv KwjSjgnEQeKJhDsD+d4PIvL9+FEepV+DgyT7MuHiEGelc3I24RyStPCcL7uYwdkirhA6TQAX Kbbr6HHoQ0izJspidZM+FCjkBFT89Xzggxq88qvBP0xKOhZtV8vwRY6RWBSJizHh4Envb8l2 rIySZfwlqYazkf/xV/PWFmwoGxdwKxkVGkSEa2Y3OlrBLUlsq87c5U3JQv32zJB1/NwJbEPl Y9yHzM5tXOADSXF8CaLHsYYYIdfX2qkNXax3q782T7PUTg7xyRm6VlJMkbACjt9OPvlR+bEl dLTeK1qxMHVKYj8Mc70A9RizBquHACrvxqQrxWUPTh+Y0yRbVuXP4CqyxerlqselzcR2a+K1 O9fHYo1wiDzheyQJVGOpzXXzaRdJadMk2g2HRgs9Ktgwj50ZmmI0VIINDSwpzo7c/v8ftUgN 1UHJ02w9pvoUuWYCh7XzR3mNC2snGET2pxva8+9pHDPO0qnJqOIu4Cp7MB1CU2iV8Bb55z62 X05X65OcDbxD0Oapyhhh2DpqCl9hrQsF32AHF01xmoNsmykJKo/H+A51uCAaqsiDU/gGdLN6 mmhPRW1AdnIGfbR6K8sUhzRYHUm/C12dY0x9s7+PrISYoWsxfpF1+XPZvzANwZKF9atthw4l tOSXSNsPZUoKq3KhfG73ESqTu88cnlSfvFes7RhZ3it/Uq4jD5ndmNX71GUdjp1IrQfhLqdM VMt5B64Ch7mIpb67ITfwKTpoOe7Cif1HY3M2oDvV5eoSS4RcJPYsKgWXip68D/NiWjSdF97H pdKVB+JHLgvXPCKyvn5ub+gxEArCujpdGXmOi1Z7hTm/nhZr7/EYByterzZ4yfB8X9yYoCBd CQv3nq8nucVy7ETXp3UUcrOKajRWWLe5E4wOQZkvxdR1f3qGuMr+YFByR3VDpXR8NBOzeh9g jClB39XaMPgUC5dvATsqRk6SxWmmt6u1t0YvijE8hH2q6Bl2Nf3RHqo7NODIZRUxtx1mMlbR 9X77sFweJCtSbXJHD9iRzkVpCZym/7TgvdNNyphwYg+Lm51h1KcMqartgzbcBzvpWTyiPQOy 6r6CrVtZMHc1bFsT4Ke1yNRMHvTnfh/rev4BMrK94kSTYTknBekAZFaGvsfHwLLkmzHBDgzc cQ97MvDnv9EqNehPxhTPDhBKeDCD5OGnQguiGD1KMk1DmjefbvtxQiSWJSHUtWiITxbDLxxT XtyyfFF/f/tGpQN383Oy7mXD5X8tbc4D+MackUJ87TePGdkzBmsfgpqP9KtfQvsgOTCJHif0 3DgYAXtyXk2RzyKOTnvAa+cO+fMa7uwpvTiQS4KboqbULOlj1SZzBwzJk1DEc1iysgexOy0F DIWFCG3tP4k0pqoSaj46spQ+cMuiZ4ieOE7JB7e8xUQSRzw07GJYKsisFOFsVzMKPvVEFgem h7/lsK8/M/rSxv+2jmLkDQhPkpnLZCCHfwENKrufBUwxl+EsRkZuDPH4IjkrsOVUz3Y8caeH sWU+fMzlZccZjWvJqYod0ty8lP9xCwKobURETS44UVh31tkv2V5wRA+4ir22nx+L5RvJAXDm sXwG5RdhdzhxAGzBDu35diqo91vlk1xFYq+c8vD3CXAByNQ6Nuq2vXWRzdX3QEnT3v4+5c6X lIxlu8kGbX+E4IC/gmBvCMjNdRTQMs3r9wUPIFhun3OotPU7VpM0RjciC9c6q7xvEL7r+XqJ Oy6DAFhyugHSHBOlGp5yFCRzFiCjFfxRAM+p9+Zg/E0vSm4BZL/4WvE5/POxJIntlgjO6zdy vK9lWVpiRPPu48YaHYyCl/cCkkRvpr8vjVCUkzXrTR92wv3UPVNYu8o6sv43eTZTxHh72AcR tNGVoOJtGHWKMRDQ8py8+w45XGG/X8mfZwtlkG97Nw1tt/PDj3KahIvboQZRa21rR83Tnzud 4BKcWWg8zjntxB+uJlQ4CbgvqxCfPiXFlT5kb5OWKNaG5daAJjGLAFik7ZmeqZqRAsKbzHm1 OHu0fdehIvM4Ofpj0aB6QgPBAZ2t1ypaDsIEjxiqZ51+mY6Tsaq1BrdJFCuvZmrtNJLkGUWL wx0EU8RwZ9Zc0PDStGcDihtIHDM3bkVrua1bSr6IsEWLewp8+QP3l8lZ8ueuGjXRZ/PT5ZY0 6YJquVyf6w5VZjrHLEaVLvQI/lSgUfFx+81C5E9/KgqBu/wq2LbnHpI5HUbT2kzzV6jd+R/z e3bqyVo0PG0QcL7z4yAfRM5k5PrLlMFPMVePbnqyegtVbvCC4Gr6+x139nwlcX2O+oqDhe1C b+L7v/8sh4CXyh1B4rTj3ncmfKzg4zdftz3jLFW9VW0wrbB6mJFkeeFlaeW9z9w62aaYxfRd prTuxQsaLNpYi4S6OIL63TeatS/42+vnitXoo2slkwCOLU/lpSSjgm0OIi2gQn4/2J1/Peob /XgzTLT+O15MUHj8SH66WNLgTkVR0i7ztsw0Vo4WYtPcS47g2DhpDYaCYtm2aB10Bmwjyq86 2/KRcoQovqdVC63ZiIRJ+lYh45rMm7mpX7FP/4Ku+4njJubQRd+ghvckjA1bisoKOJ7LB7qB Ng0T2D5I9xTfkGtd27xKErskEu7FvfdM3J1OOWO+c/eFsqncZgf87iczrrFlsVRswWj6LSZu Rtkb/PCLM2v/MHLwjDglXZVqa/MLfmsVIh2oM99WsWpEducTDsoUJ1qlh6UJ8okNwcdZ/jl+ xhbx23thur2QvNrQn978Y8jOi0RYBM2pRLT3lP0MGJPtQcECvzEm++q6/+Z+hsMTlXZ/sxX3 NKb4Jn77fOvNPz3HhcGU7EayKnoJZb7DdwdorFyv7ErCDNxYYdQjKO4wdckAVnMrsWe71++o cBBUZ7GCnZvsJqTkHXjMQuoZpBTd8jpEczDKGULSJeg+K/2gVChmnT7Ec4A8T5LG3m1EgPid bUZfG3vEH2UMkgDo4dHaProNnJIGaZUPYHxYY0EFUOiRl+sLnFf5cBz5JIFInrkAdZ/9ZuuP MTV2qoJqtwMzbAvS/wXri4DEJinfSvL70bpne8zdtKp++pOcCIIsMxgatwXbgmV6n39QaB/K nzl8QxAHwrJeSPHDnGLNussuC7hbbJgklo4Xxiju4ka8ateiPnYAGwTO1TJ/vDks154c6GxO ZTPdw0N5CU+UhMsAma2VrLNeSaUSAZkmR0S6zO4MkX0UkTQmjpLqegEQzpoWU6lozvnU7FYe PVtY2yUkvKlD4kOCrC0AAgduG34BV6zkbf7OYret1XWtsU3uNdfcHv11zP+rvNMiRYEGECbh Y4ZRMGj7FgeWR+Tsw5t6hM1umIAwWLj0bjkYdhQgU67/H6wqJ5FVZqE2t0SipafDA2+YUbkT FLBqL4drWRxC4DQhREvlHA11aLuAfcEGSYMHfZfA195BWaiwYtyemMaVuIndOUKwigU9lL9H p/Vc6VNY6Kf4lbOBaAZoEgzmCqv7kBkZIoD2U9v0B4OuS7bxw2XTY3Qe3q4kyeD0e6c5pOBP Tc3/9ZO1bbmoUa6opbmvBrvlGTbuLCJLyUBrsy0WQ1c4LChAT5gtsXTCYTd4bGfdlVia7nrZ 4YsjKmfMNwEqpxN4/2kLy3LBd/WgVt9VsL+1k1cZ2kBCRIaoarNzR4Xwt/Bo4VA4G39B/TMN ijRfBbtfwTv6D+Wn9bbvYtanzyDK272MtLfj+KmBc3z4aSBHxRnWxT7CJK4cgHlR7V+ezBL0 ccGgDCWJrWXNeCYKA1sbGG10rS9fkUSFRpOmWN3VnXy5MLAH1d9zAWYUwfmrwsQJS2ZWA95H M5q5c312xpg3jBqybNHfakh5RBhjBD2qJzvhZYy4QvrCBR/uN1bf5bZqHig2V9c0Q0cppsLW 2Zz7R4F4yC4DcO31kwS8G9qGkk7teztsJATojgqE7WuxDy+jcP71LzglJ+eCS/9M6FOcaCBo 0gDgZ98NZlbQuQsAnbWOicimOWRmG2XK9AfkMrlkpOqAINRbL3AIvVLMzLMA+GEKorOE3RhV BW3ArwXXCl/Uk+E1oPDwUXMR+x/UwoTEbDyiBAY8moq7324MJr3hwMtkzu8vtPVbu+SSD0f4 2V/XvYsSx76ykk8qbpenoUC9uPXls+ShY0xYL034eV0OicIRuKEOnmivG6VnDxNyrUK8rnNm bDQUp3jBrbu3QHPbn9h9Cr0gS5FgwkDbYTZOUTSX5ZdveHDBTd2dP13RPRkMV2lF6BBSufXH +4ERfCseYIWmGoX5qnjeJCsWH5Ij7D9VMEj2cmq6USZ+deeczwOORw3OVI8oNiVgq1kWJDVf GXdlwt9V1H2wtVWjxpv+X22ovQDOE/cJ7WZjzvw5sjHvKEPVm1Wu5qbKHoTygFS79OeUNtC+ xDvpti/muqa+mSGmrfeEe0ExzRvOtuvqmzzn52PRZ6foL2JgnZz+OeaQTRARAq7OztV6wwM/ 8bgMTOe0TFQF5aq1ZDtf/APyTNvFjRrS9LgO9qWmVCcQ7xdvgK0DalFrwfzWjmiRW0f50eXN 96+6xJoo5YlTqAgFo3h1GoxKnlAgbDK3XBflZFSCpQcGbtRnRcPQ+2YM4aOv5uUBjy1t8AzJ so6B6D6BUxXsTKmPkZIOnMaNh35vZM2YVHwHNXBtr25vNkUIsmOO9B1tQDMWETUgfF8IGAM+ UqE5DQYHXI6Wpp2zbHf/3k1Zogv9Nww8UFZaFLGeqVNPaRFdesc0PCRKLBL0tsW50TFdCOZx 32TJVNlFSPFgG04/NhIbvwXTkXS4G/h18LyqWQ8DEIQ9eHEckMdEjgOkhD46anDXkn7Ajc0v KLbKRH0kxtjTVbhM8zgBzUoNWuDXIxMRvwyo+FayBwdmQeZzNHvNF7lmO63eNfP4fgSQNrma XtYf/nAqrm4K2K4wYYWdn61hFeEVHkKxWWlaFI18Ktt0SbKRGxYaSsDlnTj6MvcaLpNOad1V Qe7bgX6ksWGio+kdNPI+sX7wNiTQcE3uX6r4xBre2GaikT68/iBWWyB1JnsEivSHauBJLlW1 o9uqLGGkauYCm6QO7ebpcmjsnUICZTIwo7sK3XM2hqdpuGLaHPVBDDikcKQ554xHnT5yY8GS ZgRghkYE05zivuMLFTkOdM8P2eTSL1E6UeNyiV0MQHtNCnhtxJn0s+IumKPQhqjIx/J5X9+X Z+8YIFgopvGzAgLa/rC7y0hgw50Vek3vz4yDU6WAoE9TlCaSxH8U/P2E0YJ8/4hV2+G0d/Bx +typFMPpXAHB5pDZitHjAWy2IQJWW6jyA+QDhLhg9O9TuFutVZZ0wD7irZR2jdWjOf8fVbWU i1cm+YOn4p+TvCO9OuM7qZLtXuiuh8gYmXNUqbNhMAZFXEWrXpmLuygnrpOkxnMNy9pSJRXf 44/JlkFWwnjU2PvJNLGADB0/jKtk6P9HYIDWP8Wejtay7Nkm311EoXxFucJrBAtDZY0Mi+QW ZWE0YzyZPe64Yiw8GXBitE5Gao5DNlKEKe48GTG9UWODbvMJWWj4N31uWbopakkvO0MSJXwY Gyv9MgzYJHzgoegS2NCd/1NBWwW72WObEMhy67Gvp5Yl4HnopPk4Y7wIWEfO0AYFdJBsGTD2 M8XYJ8sb53vNKb3zxWw98jBIjwOjXkKiBEuJTu7cu56tO4uTgK5KThx6Q110jtdA1w6daB7z pCMsmn1VAFkHb1spjqCtTC705A+WryQZQldLs9sJIMEhvbh9zcBq/spKFQPSSIpHEjYSdiz2 DMoRPvs2319Ieb+hBxIyXV0PbuCGSbdoPLTWzSZjpT+UnATmFM9srWc33BKaiYY33gMYkfRa AL8jIwW0aTAkJDa9Gus65oLyvsOfdqYqQc0tb/kY4hKUzcS2ZEvVfrRLL+S4W1dan1yreF1e mDJgGJzGr9+t/Wkdpqbl0bbPlCIluTSaaIGczzROKnfOw/SNKsfF51dFGaTuY50H8XXo5Ao4 tRyhN/78nYOcI9DzfkBTJ7gMgXg4YoiphRJvhzjQijbO6LgzX0V7OuWJakpq5fhaipoRyCxX x4xh3H+kimeGCXVSPYMgP5f89QC7VUuI23CurGg9bX7Ih5Ci6vLMegjC+udxflE9mK2vBHuu rG2Pf8YYhZI1sx2j/P3MhbC913Kr/CPKe7LmKaJukGzJ6Cdt2bMvtOBrgZ4PP+8eCb3WNT6V OfAhoa53qVnSi1ZIWr79ZLGrIFIf0WArqyzqmOkhHoUgTYtnR+jXTFzJOlY4j2yEnnRymxEB gyMLaKN6QBEIzfyzZX3JxtOPthoH6RmvPRWEcRELzn5PALsG6KnWHZWfU/KjPCeMVSTESWdi 4soYz5rWiUYklvbzK8biJKPOc2tA5FdR+hGC6DZ/Pt4NRl6KNIl9qR3hrxVUocsJ/X71vCBM kEGwJeGz7tqiX5gxqKs0rmwdQH7gryqJq8hxRsX2KKauRxoqcU7l37BPtUjaoh9B5l0pklpd k5YBfPr1ELTeoRn2tyUL8ySDLAIWyV/cbbamEwnOag7Kq4BZUpZrY7EGI3wgqlW4Vwjb5B+B pmkinwQxCwa2/gxIBLJXOfHF3f6quIoyjXAS0E7TNPs2LyyCQCdThRf1FRuyAjJKJrfytaJH mWRJd+D/gLTH6ujTQ8JbUi8Fnbe3mEGVTUFO4iWnLzfS9DGLkdzs4rtqBMTJSBfO92su4pEr bw6elWBg7jDaNQ9GtmetWG7eobMe/hs7xfSdo5kgeWmNjHCJvPgaqDkkEuUW2V00BeyWE/20 G9Qhf9/dXNJ6SY2SzAaWT+RHWEYi1hkMthEo0SSkoPbqvTuOuMqcgJDwQ2ElXzrMkBoj5MLt S8/2dcnojmKSkXe/2Scuc3QqcWte9XdDAV8q6ZthYdV77b5Zo6O9vswOvfCuSor4XfrQWd7t JPXH7of6k2/43yjZYpoARahTvWwsHa9IqoVBe3VUW6EkWovmr4L646PCZrGysqph1hoST0a1 CiSN/X9V0V2mrZitQ6NA9/mebpjncCwWMmka2wEXBUvmYXnl9BjoAUN6rTDKqXdfExmj5aYc 8pJa7iTpwIBLGQBWbBkjl0pjGS/3U/e05WdkYtddCWU8rYrOOb3CmJizKnGqFu+6L2q9oUMa +0qLngFecsyQRg1UWxL8IWF8m4iiQw3eBGBCNMuAMsqP6yvqyCzYQHsdLoWw4I3/7ukRUO7p iK3HNBbEM+E9O9Sc5IqxluefiYPIYp2ltEele0SeBHEHlO+8kMcIvx8Sh45ZucXIudxusuqj j7iUpzIHbGsPsHjk6V8R6YcGca1W7bfkBru7JlV4czZLRD9Mwr4SJXB16am3Sj5b7EyyICRV jWPqbxq5VIegC3Gm74rB8s27y2JiBr9Xh0SQVdK//a2mhkxHATIRa3BItxhwFG1MYt+ssrUy 79dZhC3K7b6+z+y2pUgY3JiMvph74oCyqs0ITGwk1upXoX6HwwhnVTYqTh0IXSGjVWFTBiXT eQ8Xa5Yb877L3wCeIzFs4uKNL80PSAqkeGzTklXWOP3eaWNTOIW5s/q+iRPxoDUpRhWoDjBO /TzHklSOMwK6qo+gavmObL+PQYXPNBoXVe1Z3GZd5guvvxyTJiRC4gW0QFw8yOXLV6RoxoaP 8u5qYhjw9WRtlqtidsDMjc9FmidzFtT6/Ap4LYRww/56KuziBZeO2qHRcHDUU7kVONJizfkH JYAIcRk7OYodAlR1Y8Ci0vZsWTTI0S0CqkQLOqZYPQe1pNZ4RtlsSCRBAnWOEPsgVOhx+AnY 4nsBWXN/F1SyfHgxcXzYjXQtJMmL/y7pkJlbPbYleEALxwYBR/04Zn+R5eI8AG4gNonSOHrW PNHDK280+SGcQI+NZJleueHLo4JsfJxDKE6y+2ccx7R/QlW6GZEhjAAekh9XuJAOMEWHpS8L dZz3NxS9b19QiHrfSOX+YiMk0J183tg2MCMr4vzKXbClXtBLdN5zu993JAGxwJ1WdloIG9hB AtTrhLZEoHbU+fN27nbxGAk+4ud8Y4w/vkyEw7tZ2JXoPo3suV5oxRRSOpVCWYKa9P8zxhNL cOIew2AW3rGgpDTQld+3f3ZunDwFXnC2zvBHcbUYiCBQ3cQKDpORGn9Zx6DQR64X5ku7Hb1r 2fMIKUuQD3hrSbxD2/riKAs8nCqT8aH6e0isdoOd9oVfRE1SgjcimCZ0i2nS0vz+0NJKJzEQ yFwcutDYjldk5UpcjSTSoE0iFnxlY5C7aTiaT5/4MAcgd9PsUdX5XtMnz5Ho8YSpdK0Bix+j o6WKTyBbnL9xwXyzb+qh7pPEFaW6fDy6fcFxCSL1i4L/UwR7RwECJlRl4vKp1G+fMDrD9TjZ Wyswpl5E8mhxeHtL1O7uS+//g3iduL4SPC7ty7hY7CWfVpvRZ5iVl9gPCTSxh/+H90iuKpXL 1zSRxj9Ix6j7CIMvO34dwVu+vhq67oRyAmClDvl4nhX9m9yuVjenrMwJu1HHG9epVrFowUb3 ZKf0kzOto9NDI5h6YST0VIYO7NmSusiTQtXCEchIQ+OiyzdpsUafKiVhpnSZF7PMPo6IfVTZ adz4Hz4M6csY3x8VCx5my/y2ynqfBw5q0jOBDiXt4Ezan7CMsxtHKaDXNZCDLU0g3H4SMG5Z IbB7XTthWoZl69WDL9Kjk2Xs4N6PcMcVxih+QekvpAuS37ofGgr7V/B0i6e0d0UamDNsykh2 JWjuJ50KSGCGVws5jR1Dh/WHHBGK2ojM0JMOnFEgYWTn1t4seeiVezV/fmzbuA08H0KJXHJD UnoDwGdSA6qPQIIEhMngeltA0CNdrVhDFOJP9jyufx1pBezdy33aDbOnayfMWHDqsg429fyJ ri/ohlN+MejNJg33ofkG2mXcpFJjXkD80YpPaNiIyq7w7L5ukfSC/pplQ7WwqsSYzhnpl0Vt RKhjKbunj0GnorDU4S6sEUulpAmzpgFG5s+veSO/acua33dSD5voNzUOJO64HoMDmhA5iM9z TyJV2kXOO4sNqJLn4bpL35NAtmo5SDNWHUBn1PlPxXe2zKla7axTDhC1KkMDM241JFB6xRLR AIIp0Y0ppzgP1ZGEB+LxJygJMiaNS5ZPM18x359nhXAkbCKG8TYKkyiuJ2PUIV0sfB6Ve9bu a8QSH/d3tsh37KTa0dzPHCiA/Ardc+sxfjqZuKFRVIhjiP+WhubmCm6tWt3wgQVO9E4BGO2U DSDhrOB+75YMyUXMohcWpZdqyV33W3gDSIR5TL9VeZuAp5kVxZ3RjV6iynLGFr01IeUWaRw4 ebio+hdYxoKkSFbAm3RnVRPASqGcsaxdCtaf/iFEKFT8UG0nlMpXvOcmk7AZ70DGM1vKzvgu Xg7hR+h6HET++Hsq3mfsRNOkQhH0Ewe3ksF6xpj030NbMUHSkeGqSBSx3YYXx1ysIHx19vsR 6vAeG0ey+a6BIGv72CVtejEWO66gNM3BTNY9rxtSD6MzCItKA5pExB3apW2wDwyGLYJ68zEl s3Gb69zRF5K8pKRwaZnfEHbUwbqP0bzusRlvtplAytOhrJMOHNtCHLPm43ujUvoa9VJDU/mN Na5X6z0u1d0lotlp1vLMjgoyyhO/Ngs1YagP3fLVDRG8F9z8BT7T7xFAZZXQ9KMQcsnYQFnw +BEDUXOFnEPkTM6+DaybY4uED5ySpb9QNpuzQE20aQx22Ez4gqXRQi0ohxW0uJRUtBE6jL47 mP4tthrTY7OYlYf9mUHepWbCpWczfczmiuVjTRMnhWbgqr674AESyDLHGsCMVb58vCFZhEQv ahfLkrYFyVHfG3xOkujGPCTgHr+OYRfSseckqyJoy4mwWLHBC7ouiDaU6tGqb5RtBMPfpmb/ g5XOYB35CqhjtZrj4ph2tML4/23K5A28ECfbbTBg3KkAt0tZZrMwtK1+xfBz5/vppdaOpHdS pdPvEG9yGrmjcQca7+0NtE65K5OaBxUhcLRD1z2qeCNjU1TwJT2zjKklu1IRnALcfboUycvF fNQvjg3by4lofjrmZKX7rJ3eYlt69cUgGt7wnVLrD+oac7up/qDm95r6eUKWqVIpUZMMXgm9 kkU1IJyJulbNENWI++lRcX3jmywlKd/AcOsI6fgCm18yyQe3F60aHsfRBhwWcibXtcpyr7y2 RnQgh1+fYnhgVJVOHANNM13TxHdYfNKteVTVSRtDwWL3CmJ6NFtzAizbyzX/9BrrbS3S9Y7R 5bfRUsGqm8KUXpKwuo/rdv8TsHisK0ApdNtsWp8mlBHsr8tyhs2bjGl65bdYzEy+pWVDPtJ0 09HjTReLpDedlc4aaIGwqgfFOFKzASCM8ZfLX62/syNHQvqHLPkL82FEh+9TRL1u376HWpwu 8MjlpMDZ+rPzStwgXYgZmldAl4CBbxOtlwwLqayGkCzIC0sV0eUyvVD3I9arCzfTZ8HsIOyp x7LXS7l90AybVus+g97dYCMfi0FyghFzxRoKQ9qcu2pVeYPTW8qLTaUZNo/5TI+Ka1FpdD+O X67YObGVSkfKfibAYHIqmPiLtGbZpKLYfvRoGLkVobcxRu937MLiGUgxl3iBZjjpiIXF7VwV K+2oyqRqvHOqM9d2F8GrI2G6+iAZTtMqju45LeH4deem5vj7qp6Gupgm20PwJ7mkBQY1dAK+ DKJicq6JDWodyOMTWeJTcrEG9y4gL+mdOrPfLi31TqkrRaIXxfputfNVq6REyJ+I55tantIO wQEYwrjA95BlYAxtTe3ENfV5RwuP3rDn89fZ+D8hglNlP7+3tpaeGkeOyGoU9CN++bN7tjGG zeNFlY6goGdOTekzINdCucqT6nwcQkKiRLEP2KgYj7zRwMELUxhAOnbqk+xyLQMQIXhj0yzV UirBbiNzbDvxVXnGHrdEGbl77apwsBqzhQg4YMHxXiuGmm4hpNQSS45gxPosuK4nVVfiysSf aPCNZGtibz11hIFGhd9F+Yx6yhE8pvKwfjH+BUcvcBPVhW7uKpXXnJlAjDkEUI7uHBlHv5Kx WO2G3WPyYydTAFOb36amiwebOLHYdPIzjenMaRuLHIAR7D5BoysV6QMlaDOJYEAUT+41GpTG JGxWiypXfCAeP9Z6d/UmAoehnxwHlU9xRkEBldstMT19TMLRekEizmR24zyE8N3o7eYtFeO1 886+Vgmh62DGpxzyhaarCGG2XBQzR6CV13ayYfQ3nyJ50ZETr4ii25E1fX06OVK8zKByxtN/ mSn3QkRXjoZ2pdWAJIIf74c/R141qSEcIFDPSAWnfy3GT00jRPwNhOvN9gC0AQQCxVe1uDbL HuWV4aa0lp83tmPhuwyhQD8HCPAw6+I79h/vUW04JOpkLyt8LQ86xbscfvcWXHHXxYqWtbfJ i4TKN7p1R87fQHamlKyinIvILnGdV+DZQezzXOWNU7euATu6VZA6SCu+FhEZBu/CyAeThvhO NVE2nNvXEjK2AkLlLr59Q02NmLSZXFcKY5A1l0XSc9NfCPr7UqmNnyTbxqD+oOJx0hjUg7CY WXYpzD7ms4n0HYEOEfAvWxW5+YdUe5oJFpgEvlhQCEpHKrmz7n3xOXlHjxYf+2/LMxXiyWnU CF8FHg3nyJvLXLae73FYsSJMmjrVVC2rV3Wr54JdWtRj/dHf8Lsfg2YYbnYn+/Ol6oUSIBD+ jSAiNIW7hJydrrQYFMlfd1qmnFNoM0Lqh1i+I/VwRKZOXXFWrGsQmxoAzGkNR61WgWf/WWIU ccoiFr7cDq0pXIZdtmUyMBPDeAY11WxQ9ZdoIU/AmQ2LAAfOtlMNi/TS7M2xvnbYMxQjzosM Y+VLOrNaPjoT06ai4vDQIaaR+rpndB+/6+scO3/G+6XZlpPKyqVItpBhLCvnUDdp27tpYZNV XGVLXZs29mL1128AoFzf0CyyXa7To1DAQgaJCz01rb8/9onYdYz45we5Fb2R7IPBEkwoTFzt m459CXWjCcC499x3k2Dtsf4gp4242Ol1HwgLLqxEUpQwTIjg44INpRC9AN6drUpAsZfHGtP1 96LnJty2xDQIOY/0m14osUaW7qzPPxafa4ZzKuaseej4p4HnQ+oxiwgxT+z+CS+RVyBKhhK2 Z7O+D84jQwSJhfNUx0co3+FaekDP4TBe1eHvzjBEU2gFfn82dBeSi9V1v6cBgFRBJWWo3GqD fd0p+x60KsXw+nE9JKktDpyTRnN+1ULjQrIV5Aswye5ZLqx3Dj9dawJEnixx1O78hqpUmvjs HCvQ5iCqhI3vlKRn2Unide5GaZ8DA07OcIuxVb8KjylCB/hiQ82NQKSLHUD/IPUThGc1DwHb lhR+frKDJS4KXkCtLomVFnHtJTPsIhY3tFwJalhkQyezlz8QrM4L1WiQ5vU6GAUBc5xkJ4fi 6b1NBDFS4aTVCtUaGcikLF4qoWAz96fX1OGKT1ueMZ1XYT4WMs88t7l3lLGQdDHZJblz9Ogl wYCIIMBmkVXlYPVH8LgAnFgVWX2tl172CbIJH6MKOkZrMFoYvfMWVxTAA5TX9Ak7xT12YuA5 T/rI8WjeRHqwOqeXV5M7WOgfwcXbBNSC7gYoO/1FTxSvOvbY0YyHxSJS7LLQL/TVjFliAXsp k4n6QswevaRnr1ilq+YcBNQMB5nSeoZI5gALpvrJ2ND5WxvvhEILuRhdZWUy5HIirkfy2loV pQezDEf2y2nGo1/2bFl23OpfOcKtyBakgq3gyRxe6qjIl71vbHuHQCmlQLFMNHN4zSmxKzCW 8tT7PSf085GzQTDXIsIwllKe9l/3eHmjHEbfKsBp3jhVC1b9eN1GfU4/Mn6T2WY2CMSyn9f5 5v2wKZK7HBj5tthHc+xz9ZI624ZoB4xHMTZZ3vQOuwonQdLQmFi2OH8st4EQcZ48AUCMXGDI 2p3kjX3Ey8t+t46FtANw4HaOhYiYN+Ok4oHaw6l867eGG9XUf1NgjA8k0O1MYhhE02iBVd34 E9EiRfXnw/fA8z6PPbMUs/bUNADmAt4jwnILFsgJxaKAHm85KotnPKga9QX3S3CRPRhnJFdA aqLV9kIbxQXOJPTE2DNewQpsAm+z+BJkG03v91wgzMXTrQqwADuhbqhf5KbdThlSzne1en2O J/tEK33Jix3mVHBHmSetKe93iezmLDDrnWFCUjF8QkO+tggZE8j2X/TeRc4EJM4gUGLz2TMq /fofl24hBjUh5lmJ36ZEt71/KJ5ImFEXeQqTkghTbE5leG6hggcOHNxx+uFY8As1hAsfPBAJ x7k0rPc5PFbDyrgjZ/0Wog3diHITreIx3cJSmbzt23Hcloda6XiGi+E2tyVf4DNLTNSTr1cR Y46D/4a5XpCz2fFYm9UT0kJMR5StUHbejQRi+rTsvnKTDv+qppE0LOOuTP+UvC98N4lIVNnu rGcMrJDwf6hTDLxqZigTK0LGn7rH/YaCy3yT/LZsHtVQVYsmGlbBUIF8VZRO8Bq89tCjODh8 WDtZmrQegqCFNumxAlPwqOPvCv0Dz15ORvdFZ6s1ydmZaR6k4AeQJFSt44c0FS76wuPpzw7n EXvH8dCwthXfJFXtHbAx/D6PKGhpXfc5OjMWCUn0fJscX53W4sUjFRJ+1gtTZHARjMvYKvnr C+M5Yxaf3Ab8lNQ0OPkf5iVEeCZ67K/BhErVLu8ctPzx7epY0y443nv7jUYlv/FN/VJ8ukiD usA7LjqViUzhk7YYxN5dKr3jRY5DXMcGhLkwyxXHFk8Pmi0fdgSiXnC0+Ar2hTz5gDIB52fh m+OAcXwf7cAekrYa/UHDlHFoLyYVMFCuYQLDWHaAlzEA1ZD4DjlT3XlN7AgP6di9qDPiBpM2 Z9q5SRb0JfIhi3yC8CK/LU0M/BVve55Ce7LuRJp1WFtmk76W/eNnOM+goR9H8AUCWRbrngcw cFma9nyWJWErzS0zO427r2WJoTfjMcC5lnkT9Q18DCkHM/FE4uVnzvvV3UpsAbt/Z4YuaMIE Ox/M+yHooxjPdxsm7fM9M8t+hWhLfXL7j1k4cTU4XD3/7qoSfvUm5Nu392ZIk8PGWQm1qLTa A6aCkobfoz6O07Y30mY+6B2XsDuf4m+k4ZEEAkQZN3cGVyCh3qRdn8cl51KjSX/IJlc9jeza Fu02YHng3s4sHxW5VvGJkVlT2hAGwCfWLahUtgyT9s+Tygz6vc+iTN3vM/1qGMuiy8AnaH1i Pb2q7xi/EHuchTNc9YNMBirTEJcVucplq3zyniWZziuUx01RtmqF5dG8XrGNuVj9K6NzFPHC FgpNERVAuMErtlFlDg7zpbXjOOTZarFiwFOPzFiW1cKSxa/G7w+QiUE0JVN/VkX+mP580Lws 2nIyNcELk2zEUkQR3/Ngwk7ING4e6P7xSvz4f8V6S1VDyfwSaNINdJYEiMVWCYno6hPQ74w/ OWO5QQU1WbB90ICFl4t8HmNQqDYMV7AcwU3kt3e6iKWHH9l0eOSQaPhCULJSON/qBsDdVa4w 1kzv/k164X19IsklxSJ/sWSBcOZdIsnw2td77G0Dwx043H4VrurzCsSsEtm1IXxX8oTH6OG6 6cUOQ/Ts6sGU4E+3nsu48j3sU1oZLtAEQLv0nPvtVJlqxgii5FfOdWq5u/nLbMnGHPi6moz+ KvtZO4mHrxEo+SxosK14NF2PpYZ/ojMUx/mDemlEWpYOdqXKdpErZiYWLtRcrMKa89WEXNtX V8f37eSepmBQD4J9whGE0ONKkD2Rf/vRJ3cY6B0PVNRDFoN7iMCLC4FhDpV6lC3a3hHtKFbH fCGEKuLHHxpzmbJDRB5ti6nE65lduQ26iiC9aG+52BiXzVMtEeSeGvUdpdBUVkzS35GByenz AX2xhlr/Yphj9MYpoJydS6uNljScvBU/kXnJNeAqUOpsNyWmzYPdFrsP7al78COJStKidAti lzYm8EOrISQHz8/OrAkl2DnjOAVnSHmQZ9XOYdHGd3eCWqNUveAXxGNEP+MkIsf1KZaMb2EB +atiC5tDYtHoRGWullBea8e8dwrlsJwhAr1g7Oe9s50x4YnZ6xFi631penBkoDQuNrGkAeLi dlzFcH3gls0hoZgu7X8qiXbIF1EoFY79g5jkVtGDpHQ/HQOP8hJYumTG2htmYEQUV0Hd3nfC pq4gkO1IEh29LQ+ALGUdbhuLIQH8w4lsZJ4AHp4jvCLXga8n4lx4siYdL2kYuL45YYqSQHq4 7gkP1T5bm7T6MdR3apLDqxSQK7h1pQOXHBcKNHOR+keK0UyRwC9HYHlAO6tv4kDEK9PibZLY kRbpHATbeAV0muAqxelbXpe2IeWSMmjp2ypnPzqOrcyZNFSBRLLYkzWM7YahZwH68OOjdoT4 4r2wXky6nGbdwDB2z1FkYivSaLSFfPVRmrVWG8NrhqIQ6CoCgc72WyAc9mol0nOoSeuPJMpG XOG5mWhS/F12ndVBzI2H9mAgeu0+kmuH5aE3/Eb6nk9TuloYO6+72Z8KW7uugKS5T1Dk/DUG 8LIZjpXFyx9aNOAIO4dLGlPVaEL/mvHjFcSWpJ/0Us5roplNPMAP1ncLPxB2W7bRMYeuxD4e imq4UBXyZ+/O4cs6UwkfQMBR7Vbjc3mI9RknHrhaENZNepzxxthwqhrfbSkiGS6qCh0LJbd+ mur8RiLisxMYWuQxBtrsmDBxJE0mxMq6WBC5IhvTzztO7ciqYyzeOcLi0tFVa5kyaFOKoUjs CHt9SXfi9+e1mGOE76M0gjAL5HH65XeGyjCNJrfGJoxUiYsLiYR4EhtcucyrO/rullhiZH5X xE4zUW3xh167kXuJRjjPbblLF/vR+qL5/o7rDl2XlB6g5gY+Ezibw+Jv/6uFk1cvS5y6AUl7 AAbkoRCvpsHlRr0mrNa+/0DFz9NsCXso/tJVtF8a9raYIWIUmQm8wDydt5CeQ6jIyns6q9I/ t6CNN1GvDVhuOlEFj8V6n9hV5vO3WxEV8RtdUeMpViPp1SFyM0cUNVMZ6AIjdb+tpYDcXQi6 FCC/mky9ZqDMUWHCwv3T6mxc8ZVrDNhXY2Cv+CueSsNpey42irBR6SpjJ7yUzDJjMK4j9ymi gVvF1I/ZeI/8NgESHVjvfd5cIjf7ebQJ7QSVoqtSZxdCu5vass6PBYp7dJzdj2WMxruPwHjk KA3UugoXvPe7XnO4dphDzPDD/0FDSlZwU6sCvw+0OVnCVkSlwfpYvy64JPVbHR8uLZ/aj6Zg zxR5qJJhNJOfNA9EUTnyiu40x2jiSAdDkD1/pq3tfgY7jFJ6YK8Di3L8P5j8Q/U7VWwX1cta hw63FgtgUZvXYqkms5v4UwtlOCMi53/ZkLzLAbyMs1sVT6wa5h2O4256osMoprwSC1Ei/jtQ 3FGa1AOjflhkaAVgR602I717I/cHFPMi3yRkUrPG1l8UXwJRP/gOwdrdGBCybwoim22uJv+m hCvNm3o42m11WuZSFTIzalAjFidvegp3LY5u3L3OOAd5yiMBuqKLMcppyBmZe79L53RzKX3P pzZzpEI4nev1Ic0LaK6hnmgzew01gW5GJjbZ6GXsTSQxDsr+qu/2exuPTpcg+zjiGmbXZO9d OyFyQdYLf/OYLJecIEftVYt5QysYEPg02B/pARY8dUgV/UrLZSPjRNji3YRro+ijWw5h47ys H6qwai2p5lbhyZmJPiUGxzKOfUVD6H2xS1vsxyE1DrJu847QPd3L3sGnLgvOHTnpyUA113jD 9pykXlLFW0uL/VKB90qbpofhdDtu5y9Ga8+FdgpgfZAoyDeh8MOzc1PVlv28NmgooCxoGbd7 yHDrAfrNApNHgI+rrAAOjC19XqfseFMcyEKiDVI9xP4vaGj9exLUY2ns9Zm3gBmL1cW5peSM Va/am9DqMHrSINXg2CHv8+uVRuebXws34Bnk6wrhNZ8oaYoWJkj4v4uwNJFGqPoNXZV+2+LJ n3TSGhJjNAENi0cLIFDFDZtPxHGMjh3bBQxxcyyG01+mg1Dsa0am9wGz6Z1j1c0cxSfIo7tX QRLCLtfVQKOVNERJal+MGzK0H2G6H0xVEcWCRWNmuvyctXDbdYT7qVD0MWaBQTgBD9tiUe4M 0IPWWYTd5QbNj/XbovYJc9iB/AqmaptziAZmiYzMeZsNX1DJ7d8TAnlSTfkjRPX9qAalzs90 7qoA7bpTwuNLM1u9Q79wMf8WZkA7GaigWVseOUZKV2fnNaKXHqczbWdBJ/fPmCi+1/wGxL+c asun4uMonzFJXsQdedj29LpXuOLmGKXeCTcthywAunOxUX5xu1a912IcyDfCi/EkojuWhaYN fMCQFwCInSgAELuTR6DVBrwP0fYBQ3mDgCn2EuUENXfGaGnxcyeaToj2LoTOSsgGomgjfPFC Q50pmpLW4ehwShkexoi3NjJel3Pl9mjjNTI+tTFauYfmN7XBKBXmOdTsmFoL7g0f/C1LJGcx J7v6cJgGcJNF7x3J6flj6Zz476CFzUOFbuyurZhQa+eigWTcnY3fLmRF5G6q5R9uDVGspEAW 9yt4xEjQvh++6uL7p5O/wJkTe1p3nlE7EmFVkqh6vCcues/bccjn/tJWjir32ETcAIWVX2KA C+mPCpUL9K8gbONlt819UYw2C+/l5WmugenJTM3liDBgCTzHQel/GOsxhJuBGeUbLVTaQO9K QTT6NCOTSRmNwmFbuVbw9gUrN8xqCPq4KsWTkNdaqEKFfhxcNAbuO1Fi8Pe5dUgJ+3BGKWy4 lh+ps82Ha+JaHjkB3FyFB2eY/WjodNymMLL7Fr55CLeOduvSDi9XVi3KKbC7zi/xVYnvV0kj E6ey7YGSewBKXZ1N6xqP1Gs9Wh+J9jIU+rQA2Hpg9upRWLp4GbEhW6+PtwVaFJSgXJHFGBXh yBlTPlZeeOEA0pz9teXDyBd6/rUcslvBZYwUWceJP742LhU8iOiIKH7MO1f1MdH5FM8tDIYv anzoNqgssvizXRI5YsFoBEVZLRItnUgZP55VVyHu3TBJ4vFtN9XBE6PJg7TjTzeic554I6Dg e0JdjSneberWxmWkroPtYiCXW3WEvet+1A36K/e3udGSNYksTDtUwzUzj7Gt7NLWS7zruvG8 TelanzbyklzsJ4qpslx7e0zPnSnYuYQwrUb+6kShqCTY8KIAWrRhWN8I6HqmwKQr/+HZscUt GD9Ak/WjFyO+EP5E1ZqETzwfEN6niwMrb4Kt4JvF9iK3A46h2rpl9gDAEJ866zmbzHCt3kpt XuvSB+5RR3cbuv3lhEz55xq9Dhah7UYpNVQYNJMwwR/ugOybMyQ+ajrrtnqbLgOvSNU824CS xYuQSit+PeV+5QKTw5Hr1jdOn4khhSYMH7GE7sNTdT2cM1PhPco8pw+/Cp1vRgjFZ6BrF4YQ Jl+UmWVFDrpBfZ9kuIkJ6/H8sZzR5Qi6Ee28bHbb3O6wpJOyGPTWE6Se1ptOSFFA5j/pvP91 P/wM6Usxxl+POTVrjpeTK5u/bbrP1tSxMFu7RE/C5uBR187XfE8z/rZ+5CpxxR9kv3P1k7y2 vdn6w2VAJB2oqkeUsHnw5Lha0ug1TKRU7ZurwoFy0RnxmadT5UMxKU00rU1cvTy907MayFuW vmcE0q7/CDJ6QabxfEyrMxYqdokVROBWW0t9yMV95Ot740vjUl29La88oXLm7sDv75HItvGs g7wJfHCwN3Z22y4QuY/Eqm/0uVnKCGyimPzJ2m/wUeK+61/Ie7FzVWZSUegMx3PIHDs3aXhX Sms0gUJi/Uiw6vW30QMuJFcaUeVog2MSo6nUNTzCv/SneG1sUyBjvcvqT6VAYWMYqipPH5c7 lU4qqL02vhx6KjzOa+O8Rv714CYvC23K8fOySK/pyko+epxK8VA3WLbqXuO/jZd1vsuMhbq5 EHaBKuWVnD35tLfmp13l3Q6l2STkj8ie8cTdqKuHifoq7DwsMvKutv7yT9J5/Ozem28eRUhN l0YceFlVHBKcMiggzeX2JDv4toSyOWOq+omKzYaEWS78PkZZweLAM/QY2akNNwnjRUHDJy/9 1aNzdsQ1sVqHpvxhQHMp7YUIj3ndXAp2gsG+Y4Nqpr/hOKjIjY8Y49k5ywseIJ8+tExBlxMY ISqByp+6NMRJMo7Jw4laqwBwXrKGksYPA5jiLQseDywNdcbedodHtze6q2W/XyE1gDPwOkYW 5GeUpecJJFa9VTI58vBPlPwyXyfGmrtsBT9jQFZK9ak2JVLfhUYCXHJ1NDQ/HSP3/kUE1avM aP5SoQZAkaePQtpdzdvHCMZfX123Ux0+kArKcfKwC+tOanRdXBSlGYj++6br01EiNZh17ZCh aZgAJAK2E3W1TiYxH2iTCs2Hqu22KvkuzEqs0I4dYB2PyP09KrOZkIPKCbbB741yGD0mXK9r RvhSk+8TTF1aLkc0J/1IeFj00nRzsvdH68+UdOP4qj6BFXErfrv6S2tvv69NdzDQ193zgbJo WFW2v5PhER2O5NoGHGqasNsaQsAiST2Fd/OKc+8ubqXKVO7fQ/c+RMccMLbWA+kDJ0bUf4Cl 9wBHgoDxMe4vrIFJPSj9QAepj4VBf8Yv38Xngh/Exx+S4aTHEbotR0ACv+cjKQrbQqAKudtX xVPwgUfEOSs+bEzfp3WUVhnUBS2l4EVrvXwkRkVXsnAqNuiTWMtApLBFR24Rz1noOyXzJWlg C4KfmmbmFgHTgUineZH7kztwWSwcZnl3EI6JShNENrO+vSmaLMBJwJAOdz8w7SqLC0qEqhHV 5CrbzHNzehRwx9pCGW7rP7fVolIAIxRZq2CQ1YkXhE3bSHAWRoJ+UXKN7/GaNUBQVDxtInbg BLcceKyLzxANeASEu9j0HhEEP5OPMMR2hOloKCxlYibrSkRe7C/FYsuMd8YqZt1HkxposutL E/YAybUaRY9i2n58nnyJPuN6ADOgTfKq/9Do7MrRfNqXNn2iVXFQTaxAhbP0DU2XQjy2lacu 6uem7ri6OQGmAkAMnF6mw5PCRAwfgmeizbYCC2d8F9kyMVYPdA8xPHZlTnYPJizvYqLEKC0Y bpzNcFfcyyXzqFoegDuA6V9HLvGVlzfDQ6jQfpZWyBolkHp4ThxMqgWZ9sIIj1Ca3cuAINnO BwpTxQMZ8Zb1mpRGLBr9+9pRlRW/ymnsRJUn3L04FVZj2pjU9rA1S/0U3sM67JguNacRm8ea b1M5fCd2gSGxpF1rlUmgtajGIy/Q6pTyKx0fTge1Qvz62XE+9raTswkDFbc9zQEhpsiv0G5y Izq9dtt/wWdDrp9je+GO6ZUnJiQhdh9VkNxb77P7xlcL9dpGwxxDY7yEqL2opOs3de4tIsgM bA35jUKA7NqTmik0Y5s7AvqH1MidYW4kSVOXPXo00oqRfYE6erh31vd03udejP3R5zajb++c IfihCoXaVF79Uu7P5aEhMfa8mKDiX2/9aqSO4ZVjjFz/+oiQ/sOHUqL+lXCXiLo6yjWbXjdi Z8HsGcmLmslWEI20QfCENmq0tUt3sgM3c2FOY6vLuimSuBCkvj5HS5Oe+xQYniWiuXfcnIbT l2e5G1L6F9yLhOGDSbI4et/3jvISpAQbmiVJ2Lr/HaPrZld70RTZknh/Bp3wexd8BZjPB6jw vtC2+pJU+7bkejCYYDBfj566fwVjTlr8u1S2C9+Rdv1Z0p8ZbyveO1rNvjJU1LJb7mth1keN wPXZNODMOPLLJ3PylwezwiR0elqomrFhtBiZbsF4U75cTD6bR5cjAXUvSzU98XwytF9UwH17 +GnEv6pEVs/b2Fi03PIJ6gGzYc7iJidYc9LsNtuzl2avUdTJgUd44nfEJ+5Pj7YkeUIPmj7h m0l8hYcj5K50NT3PUG1EIdekzrfxjo+/tYhAX81pVoNXbqRKydWOmCvqHhNSaiGjZ5vPiv7v 8K+Qo8WRffJUYiK38978NCilL8vJe1sufqbgxQCGjP2vPNY+eLwtHi+VbPvQSVrYnyzQbjW7 +X1dqtVT+1gTfdokexVYNKcD7jsRzlGcjX0UR0RSubnyY5xK3Sbo/AyFY8JJQ/VOnn3k6DOZ oGnGPReAeaBTNz7hPu9nFU5d0kRSfMhHRfUiM+iGZmVp4bAvPJKE/drEFOMXzMAFD8OyN0ZG vUcos7Pgev+gsgQ9jOEDg5vDDOGR1OyrqyV+n9PSDJnReFX5uS9caYqtJEZf2nHPjZTp4NlR Ie0aEd4H2L/Kb92PMBHZaJjGuXAbdAps/0zTAiVNrGu8FthBZOPW+x2UK+KP6GwzUp1tte4B KuNUAuNoI0UZc2GWr9seyDokPA8ChAzLkU9VN0VHlgTAfMe7wzDHuaDUYAPHl0emQZ0ZcBtK jfVk3Hx/X5F9IU3GIaID+/eCM48XXODRvQotW13c9RvvQVclltfjOeQSkc0y6CjrFLZeiBi/ WskbuJCgAYUkPrJjxfCOEN7lUQMQsvQDWJT0H0ZGkthtcJhBMuQc8rEafQ837jUK7HHY1s/s IQRhnHXUkd0/2ccFCO83yNaOvVzT16IASfeh3WefCvFn4Nhd4QOuiFHmktVW8ImbO+RpcNuJ P9AsPcViY7IVQH2OUT+Q/uPRdG6JMDJ1oNrLH8upMx/WK4p9VHqp+PFGoTN3ByYcwrMaFO33 soSXmURZ4ckemHcfPQvJb5rIxybi+R8NLqLs6KBqlhwVODVOpbiFJN/wK6mmk1iiv0IUTd3c serLl9CIp6j3P+u+F1RDeTxwi8rKNHNnNUty8Q4XxBFrnhOBfRL1pnN7RV1fWAmmMfMUl1EH OHAIOuKz74Ga+PLP1ppoSaQxxj8A6DuwzJOEKfGvPEp97dWz5d5GSePwpNvQaj+1Bp8uqfxB tD6ELzAFRQDw2nU/dUviILFlLS+elpXW9NAbJc9HNJZYfz8LbM8tByYokhUnrjllhQjLtkJn 47UCfgNryrmSKU34q1hvCFNL1UDhz63VuzOnzCDEYwGKWJO6StixTS6pWKQC5q0rezisFhAl ++FNak8AB2K1/GXzYai5Idd5Ph89ipR4fS3YqKIMliCBbunbSqbJGRrVapVb6usG+4ctPuGS DYGGvOuCt/qde7oIdScAqZOLRKvMifzxgUKZ31E//6/v4H5VwjSKq9NaE8TfilT39eYQzhMU jFtCEG3tnGPUWgKweLXlz2pjGxfTeKF7oqmKG1kzS3MEHzngq8wZJ+6famgi+DPuw/J7JSkS PN3g7XGwYINx2BVdpzFnp94dPU+afAINuRudxOONpOe187gPbN9BGMNWk3s+aJqihCcu9pRp noOlppWrH9+NxwwesH3YPcvEbiNg8K3I0Wg+NTy5KXxZkUC7NOTypcVtXgn01Q42vM2A26kJ 6/2ai7OppoFPWrR7KYadEnXDhRhALvRfNr8My7znVlwiaVUEZo2RkCS9WIMVhO98zx0kIYrl fwZud4/oFXVpKBbJAPzw6jSKNBSF7u4jvn0sgnI6g1SvrlYq8J1Qj4r+yNyPv3ycwoLAl2Z3 MaYUBq52ySzw/KlbrXPiZuMeXd+ASYW93pSFSaQk7FpDsPPsngqHD+Ro1qQ5skyKhYJNK9bc dgBDt7NKqcXS3me7U3Zb/KR8ub+XUKXAMQx6+Q2Z3OOxdOgzdCz7ytmHGturfeweu1SlVfq1 XwfzN/2eWfbYf0SlWV8OmWjcAGKHGn+TM2T6hrgdA9U8Wrp61Bmw2k76IhsdKDydExlLjY7l 8jQiofEKL0nTxhQzPAb4ffozLdX/0nqZ4FES/YCnmcDVspM16NmkREpcUmRL7g8NhwcX05Dk /WMoTt1TrVCR/SwDGLfGt9qVRz9YQEShflgktt+nc0Tmhps0VQGYQfF6z9BpbKyRu7PY6a7h P1ffgHDWYKu8uXYKeXHIuq77nDhAA6NtPtKCpoS5RBhQjROU1+oAtsqFFmERwXo6e8Y9RILf hZOfI3QSPYrilr2AGqmibWHaeKxKcVqGSSPOKeRDBudxTDZHW2GppnAqpe+goILb+7dcfYjd oLs9HyOuO04X7+PDWVjwIuvM7ZBk+CxxUBX+zLCqgdRQ9PYwqdcsIKwSaJb8jO6nf//A45SG cBaaLI0JBQoT+d7BpICoYx9kxFdtDc9JUurWoNRvEcuR1JDGd8DeK5PfCKrnW6JfPU1D0q5P ZYSdzYAaspEqMGJGFkipAUSeTJYXAiXt586CoN3sSsQaP3yKcbGlJm44MxwLcTtBL8Tr0QhA h8VJp5HBQbo7J18K5YEv51UT/QV1OF/zLuDlh+7xC8R2yfnZRejAI5bLGi4ltlajnP2OekJ8 jWrurDsQOn2kkBLGAzI6lSXBUj5DuDCZ9XH9Xpw2xMX9vp2Pw2cdJRo0Zzw6xm6YZZ8cQTeO A6+w0ihPh5fglUDxnLql7XhhM0BcM03ux0LLK+XcfFcEHderAJzYCZmh3SMhDYPAEv+5/3Pg DktuBrn5DSPTJZKOkBYtRum1F9nfhL2aPDSxMHRH7BhmxwjO9CNRAyh7gWmWioOBBMwGvm39 kZQrG21aeTLLWYBOXi2aPQjcfpCN06IImDEAe7q9+aPdGCPspEcbNuX9R22DmcXgvaFfyScV 79Dt8pVSGyzPs1VFp3S6bMmqN3sR5rdC7jXBhPZ9soMFBMJGFKBVjxGtnjUEYvmVW00tVW4R EVfDM5MGT2WCdLdbltiu5iieRVmNh5NtccdoEBavMYVgI9TVPTBBO+kDivsZKvSeIewBUGs1 ckw4KwJy/XaDzVjGlxMftZY0xLGlETHNygkdrZe0PrcsyNZWPdTYl4bvXfNS41zEviEU4fFd dysnBOSTf2v1xgIZvuOs61qOd3G/GV92cgeAviNE/JT4F62Q0YCTxNu+HYRka3/t+7Qxkijw GEWdIzPxiZRY1jY5HtBzsUUpJ0Fu1brasGUFuJ3CZc3qL7zcK8hL4sw66Lp9TMk9NyhSZqzx iC6eAw8hdXzyZUa+Vc6IC+LtK1s8iH2GDqF/Pwz+LsYzAHthA1M0L3dhyWyuPgdfVlWtElWI tPBljLDn9KwUltgfOdqb+4gePDc/bIskLgGN7UeBAIi28ar9u5Q4QhNT3awLrvCmMprpXcUS 3X1JRvzbfnOdHPKl6JNw1wk6mckNt9teVhTtVXGJHnwnsrwN4ol9guc5xaP2PaVI2KYi1cNP NnwGUvhtMdh9Cj8hiHFLQI4w6HMnCl57LEVgN/x/f+qVXzM3hTcZvZn7eg2qQ0QrumPxnoxf CKLm2CyU77Nq2w/e9XvrWM4O2z4kl8vIQvkf8FjOukIKsLFYoim/k+flqJPBwmhj55BYvUVT H4ox1+fbzP/bWXHzyw5pdztbkWlme82RnQTTT6r5jkscSdt2eCHtvX6M0u3ag4B5pkgH8Pqe VNwvVdVrziw//a/A2GWdBSOjfzlev1WNwKdjEtXvty5Pqbnq5TWqQBO+NGk04fkb9VQzrkXj 09w2gqrKfzLmqDyfLxW7uAJcR0OZMOFqevldMPT+Yfn1vI5RA+B6c7TAyEGdRreCL1Vvpl7I 2fcEN6QZA8DoTEeSoeGDLSNOyNjoCyS8P+6B9Ld+pOL2Qxc/drvmsua5q3iDVj5flhxSaL/7 mXnIap01TNH4ZduSVoLtACqrgvEN9VT5+O+lmvqlZwwqZ5vn7fdWAmymISt7hXaaZerG9zRo ElP6GdvIqzN1W26SNjKbwJCFo9d2bH5bzLjwh9E7NdUq4ABND1rXo8F2lTi63+yKKkJag3Lg P+C5fdojaCx+fhdjUnN7Kf7+03mY8ZBqvx5+Y4te6iMB10n8i2SwzJcwGPGADwZXdOqfMlCl 43LlsPMJREmmjq2GVXPmUJZRUKrJmaMrnr9AIyRe8uR4OHEE/s3hK5fYlN3Y7Y61CuPiVF0d fMCp2pTwjPB/U64E2HiEgyzjBnbsfWe23Zdj35Zby/Mk3QwT0evMpOmrqznRi6H4tVvviwVr Xz5XgaYhlCIHQRRaHipV6dAklgxCwRIxAvje3ETssmLfLPjjqgBIC4IF3R5oMU4XXJnb1PQM N9kTUk/wWk0M2fwI3sPbyC8AycPSosnjLAr78BHG5AmazDD2IJL8LK3xt1DtXxpQZt3zeBJw n/Esc1yfUlUvslcDW468BYJNnb+3LN1vvL+Y5elHVTPG0bK9a3uJqCbV1VLy2c3d6gwjz1Ph X/FUy42FOS/mtsO93IwxHdMsADgPyMz7wKjDGrWqRBPfkGWnO/oH2+7yHDbU0ygfVuHbdz+w W6QEVTkQjHeZSbKwn/VD9R9UIvZONzrpVJELz6B48BzOZR5T1mYRthoQ4sh92oWuRZ8rqogk Ssm7dDh1HmGzpBoqLqEHom7rkbEEbAMDWqy15kQb0psiJggwRdyhebO8jJXOGphSMCLDmy6W OtySABcOdXa0uUuAkxmDX4hI31LhuxefNdMf9ko0ILx6yM6FD5USz37Ef+uQspUPk0s0Uf0f HtwMSY9qRIwvo48UXeR5hWJm4VGV3r/y95w4YofjJSaRylzR8EhRaUMnnYKbpkJ26YQIbtY6 eBVf+1O0UJ0tKvWeFQ9h1Id8CjVoVGn0IJ2T7Gobg04bvfb7vdkvbOg2K01DNH8zcEXd2JWR 1xg9ZjYvXFOWR6vHwoIfLtyfxjuSdH+LDLlsMK18rGGmKRnCeIKafIKSplbvmcL9IYUgYWsb kbTOSQ8CMZWty00h04IFVPIL8Wf3eCHHRO9uVImLbyFX4bsxno+UxjsGDjjdk1ejptPni5Sm LyuwwAkcexb42gofQT1ZEhyF/TiiZkrP4ROUooFOxHmKoyhsbVRHNM5Y7YrCytUu7O9uANsU G8BHdl7ySU2FFjgVo0YOLWnG64/COLOd6wx++D02ueFW5hSIY80WgRd3z6YehkF9xYD/cBKa PDHEc9ofdBaSSXJUCocU7IjdPM0Hx1WwTedxwHarK5ZqU4NP7trrtSZUYdnrf0/B/qgzBu9O zSchryKMGPZqCqP+R/6fpvlMdRdv3duuv/I9K5OAWGHB9M2UrzJlO3hnFw+iN3azahYN14LK DiJLpW0J6HbJl5ZMHqjp8K/45Ld/bQ9mDwmySc3rvZO08HTK2g3MTYxfeS4ebsrVqLScuo/O mMoC2Ovp7rSZQ65nUZCdHQx8B0fG/g9zL6OtnXKmSaep102SPBYbCHyPR8okArI5D/8I0mMp 2xKoYqYmzsc+buW12q2S6IwWQr88qfe+FIB/sIHegh+ndiN9VbU97rh+pUmq03OWKJlwogor yhZAJg7S10CH+tmSEOHWQkgSnQYph2/xmPlRq4lGU8/pcR8DlD92cEclxqCOmiCci4kxm9pU aFEkg4F1xLvj3pYnZfivFcU54Gpf1qeZ9fQutz6yD8lzhSwdTkAlPkI8INYKo7r3hwWiTZCO SuohbOjW09gVDvPcvDumeR3Ogr6c7g8izVvt1yO1vGCOA0JAGVNwxgdK7WewJzKeCBo0uBAT reisWa/3uaGF77ZtT9tdKwnLX3i0yO6SSAq/wIoyCjhNMQiwXsPkl514chHNFzvtd+4GZihQ a1Rmf1yHxK65x6R1ZE7w6J10BEIMFNbAggyXMID1FnpZnElnPMcUgLZwMRZpAMh3Ih6uNNz0 s39MdN4ZYhxbo013B6LPwlBmlSihSxj5JsnELv1yO1eZ6JU62RcrcyiTfRL06pU6wTyo/z30 Ka9xP3ZZdVD6XzDwDC7SY12pGCl93kXBkXK+iAy/a7/4W/cDxLiJD55JK1e6hlIyt/hI9Bxl E0eFm8bjuJ7WMreOoG7VSx8+x1noY8Be8m11iWxGj2BVc0pXxI4h5N2b2I+YHF+EbXw0pFMI X+GprI/wkr5PA88I3uFhJINABb8m+uURkbizFVCFUKD/pEFfXLipfDu5DffOsKHTEkfBhb3A m+QgyiE2SqlUGv6pCD13k5sNZujPUj63QMGPLrOzuhP9TnW/moXU2gsiRVGu0SYEQIiZbJTV IyyxZMmia9xbbjDjYmbkRHXEWGllcFO2bj2naaZWyochQFS9ZpaCP7KZuqmasZVARzPDzmqJ 45zrH52j4fpfBrRGbSr4MG1Yb6V6o1l631WCAZVl1w4lxN6fW7HUTc4ww6X3YSP1lD7Zsqwh mFISgKkIPHBMAqxrNwqss/OvXowHcV5pTzPg/drKRgI7Lufz8GysTm+P/J6wKcvQ5+OV0l1H NMq81D56/pSPgAnlNqq+FYK5iFDdlUcntpJpKgE9qeMkGaAaBdAXpb64ux/lPCcjIOI85PAV 6MzWPj5gkng5TjhACGo5j5waq/W+nnbtx7lKGSF4OknEMxrheKTXEZxVFDRg6x9xz3F9ezoa aK/xCJc0P6SonT7tBC9S8dwBJTpy8xY/7ZGoLGzzTU4ejCqYj64AeRu9Ug66UIMeLr9Lces1 YrxAxJtMv/inShX71oX8fdIQLLR1gXcu6dXoPOZ8geky72MXDSpIPfSf1ZjGiTkFqw+fmph5 FBkZIwQYRVVIwhYT35H3FwAMODX7Szor7b8FKyB08yWsweh/w/d3+pav569frMp0zC5gbuK6 mcoTSfBdLKicCJ86cVyHjHZWMFd7EHnPIq9jO37/jat9zUapOpDRR7qmrqt513Ct0SKC+QIP OjIGykpf3kJL6FIuO+/M6u6wSwQkV0BGaBPuad5g0ITVlOz6R+s332bsUgnP9Cuq+TPBAlCa Yz64+66OIWIyYJJk1VUJ4kWv2cHIrrXYHAAFL7cqt5brP7c7RKUnj2GQApsF/XfmTP8iYE/Q UOuKAJ11wo5e5Qq6J5PqJ++0AksZWHHHbpAL2c5MX+/4iVrb/9BOgZ/qgNSccKJqZ8na2lOf DKv6wiNSOxwsgPwVqEhqLijoCq4Pc4p+J1HROxOyNIaYE5kPpKoWW4WpU/ev8shAlgyAAVgl qO4XjSrBVtdM2KIT7A0Sgi7K9mAC+FuzG0H4mCb5uemaU6uh5QRhqmvDuu70sKWMmRY5Eu61 OW5G7M/IpzB58syTJWaxOPHZosmwJQiFHzpJEmg61s/ZitgEjFtCDvqQpY+IsNQu5Rv7dzeH N2tUZIqxeG4dEffJ7b/8lAzZI+dCGVTjNQ8zW9UHqu9362JmqHBK4jy6hIJt098b44UcdAph esPc5ikx57bHGinSGmThrOz+gZIHSUE7cMowH8iONWMwovucR4KM+NTWUu54CVafQIhiSdwP foFXyD32RjABIlENtR6zTORDK4NwnjePCvi9Elk446ZzynFynjGHoENzHi+7iTFZHkK5LgYM CGfp4Ac/jcpl8HFYRlORyoYbE7xc7jdSnzREm8+IeABuXlaf3JdcC40ESeumnogc+fNbtU+G nY+opwevtkRrOLXVee1QkyJ1NB5j5u/bPvhel297lJW7ZWsXMPw7pjN6pZeOb/2C/V0K4AoU VbyfegMWu3NAHrzW/r5TWDvoQWIvnqmMZWZD0eXIA6fKDbHz1Iv7C/trpqGOvUsjzuwAoggh NUtG6HUE/W7I1JERlWjHdQntpqMsWwl7va/c/96QI6Ph42Co4RliQGWsZmknZfxFi+oiDAEx XC9MsAAWtbfsx37NaCJtGhVJSxakH12jyAiYgZhZ/Bqc29VupB7d+lOiLWsyIvvZB20m4vYp gbXJXYxre43fflMBzQEHAmljeRqsSzCtvS2ibJCTHJ/cepege18YgiafnNx9nu1y9s8QgBMb L6k5MieW6qUj3N62zF1w2s2shbgS1XcDuRmtodzvEV7ZS6gCtIUDvB1NS0/1taAnYTfxgL88 /z1i1+Ncp1Q+OA3mmRG5ueJF8i0iSX9LqvMi7bwcGfpuvmpdkO9fjPiB+hKQhp3NAa3o5S4s NcMcAzPNqmqzFgMyP6vOlY9hfKtmXJCsvZbRNKMZWJdCedwWyk9ZejHtRuvOSSBaM3XX2C8m qquAaecfGR1L7liHYib+yl1kmI+MGBlSZMYiuP0IgvzsrHd4Y9rpSrYYTZaoha4ACUzhLryS 4hxRYmvitXzHK2wN9THd1O90Eg6HI8cyJUQHfBjeYhOelG6saVX/XvV4R/nRfwc7Aj8Zxr2c kOBe77PwrlvKwcKwA6guwSyoy/bF8TNlUr3vAndxhr/5dpsMYYYnKReKjeJpF0Ocwb0i8bWQ AlLuxDcBHgK2Z+SahTA11uOQGLIjtw1T1RMrO+FTxeYmb7OV3DNDaiFIjwT5Jq8nQkKh3euN /NA9hRPbR7l1lbBESvwRBkN8hTfogs04DB9HdYYXjUuqfw245by2Eiga7+RsetwQ0Tqd+HeM ny0RVbYxj2tc76x1K1uG+HhJnCIViKhsWjz36Kd18RnZcNhClN3DM1LZ3PdB5TmXBbgKAsJt CwBWElz7jP4wTm41pHQVjCzH0vBvclFZem8iuDn8qaawoHJ4SenfbjExPf3R1HUszpAj6DVX sS1xE5Sgii+LVr14pKx2lFHbsB0AVpkfa84OWw/SYQsllrlkG5vyaOgvz8GCWNUEe+Clrttl /FzBbqqBQE0C3D6JJRG8zz/loEgyVN9zRrVK3QkAeJKoDF4RyVhphbVBbou6Z00f58imoJO9 CGZC3j8D01mLdJc/3Fc9yA019NlXXwfIJ9aXpus754dXTrVOyNDQwhRNnwI+4OKcryo99FFP SQgBlS7YKtAunRsK0sNZO0Qnwvn34FWjqiTbW9dHWzE8IG1Aq5vwktWjNPZWYWXOMAZSqIS6 YLUqZcLB/zWc5rj7HsDvC78glSdJGIvTzbZB4smcqsWPeK0MayTnrzQ0N3V5h/ufGNfvDkmX h5h0fJb7j6VsBb/NuQCrggB4yrtzMK1BK2N3kMEjQrMgjr/ZFOAk7R/GK8COHVNMNET+w8ZF HuGXOA8O5QSerZ/4H7VwZ6Wx8KnZFov5I7pw2OuilTovuSzUE1JCfGowZKO0SVEe1cJbCJn/ biZGmEnu691zZ3oj/y90S36Yyi9mwza69+1SRtTvkXdgxQKBMkaHop/HSTXc3ZCXYbUAAQ1R UOikjlLD//55e1oE2zbGLqrlztkfGoMvTtRAPVEqIjKjvyYpcmdAlrq020rkzonlXjUdEfV4 RorXW5gfGYqonWSQQsuZmuJsT/YQhOncoTzx6pmwob/syzzlI5b5lGEMMD5HJgpqemIAgizm gf0u7idtkBqmA/l+4C5ejuInDnaJutkE+3D9D2hyEYIx8a42W6nuk1HXiuuY+I3xXCkI6SEG IPD1CjtBGwE9N5lh8Pu10ZSLWmXqbMyb9DvTtY1+ZUizzYkwa5QSl9uDhg/EHuQzolcIx7B8 tunbwy5T1KKpv+bIqveR5pjt+l48Yid12bhguuFW0Md3IMkhqxHYZaSHwZamQY+9Z8AuDGtK hr+/UZuYhkHxCL0KgCkyEHYzhT1sms17oRfumZB8WsMZ/FzyMt2K7JauZF9xxd6TC+vrxepN cHXLhizq6/ikPRdyGUnSpIVVJKIXYYp8RoaOnS5ntvZPaAkM8aOU1DzXeSvFFC8hWslQFhtC TrJBguSNC14BgI3lGho7Kn28ldtlasMd5mwEX2oDs2fQTFxb2t6xevTJnwNJbEQl+8O4eqON ukeypzRv3Knk5ooNfOCIoB/cg/bOo0Rt663NReT2K0bd795yCLajbgWOLzmbRoEcr3/pFVBE bI0pSSKPtmMWa2zj1cJw5oeOCyr9GtyyREo1OSOfzoXmshCGi+I1O64l1kdi7TM1XYyb7xYo uPiYrJC2YS76lsYqNy8BSRZh4yidBn6Xl4YbHNPJQcPz3ChLx4e6Ozfblt4UoTVDH8TDicjq rPAXi3WjKBQofcwjpVwRu4peafchTomI/Bn2y/rxLMFr7RIFRucV4/8Juu++ofdeeO0qziJU yFl1ByDaRycKvLcBh1OvcWSc6VZqJejRnQOLSf+Rq/+/D+6JAk24DKEt6FD2Z5SS2WHeW839 pk6ZNwgENm6ueEpEyDoRZOtVg5jNYf9hBZOvCIANzHzInlR7y21Bwr8qGihHeWuc6S4oH0Io Nik34oXlCE1wX7/CGWlDXxKaeu+Z2X3UiJZ87CG8ABczlCHAi/zTfxvbJq+8Z+5BsyCOzXUo ZBuQ5GFUoDqafSmgaSI6fy/+1sBNTWkU6kjWr9HajiACLJ8j1l8MfKH/9fghnLl6KNXg+Goq lMzKJ1Ux3bMqRwIGyT7zG04NkfGIAmmBEdqhfo+rdzfVY/6yXuvtBkWZhW6YkWFaCJylcy/z XGwWiTR3/NRJbh/3yrSsbbxqvy+yyCEXfeE+YVNq31nvi6v6v+6rPY8pk+0g5RoTF64OhfR7 SHrqnhiZ7GdEY8My8Gxtu+vTbZX9LsFRWGy9aP8HSySFOnlJctp7D2K7gS/LlaGEwlDWm1Ik YmKszHbHwhDRbRXCBDU0WWVVOlha0/e9YNPSoqUw0Tr0Ki+iMPJEoTe4nVUzHApVfcUVD0Re fElv7yPXCgNWKfm/qpyUnltTx+O0BHwyeoJdE/c3alrOLwGna8kYanurAdU6CkUeRTwPEl0c kwbD5fPqpV78TJn1U7d2POvYzI7i9QjO+v93g1u3ltYoFZhKZfl4gcCHHrGOBt/Iovurunnf vt0UP81SjXk6Ziu6jNWGzszHpovlBLtV9uKIgl4zFEs4IUklyWvsMDAdHCpdH6h2YA5snn1r p+GJnJ8HV3C3G1Lw9XHJoPLv0Iq8RPe8awrcDvVpEZNlZ59ITmXQvYNsujhakfS7HBNIoA/Y pVhgpD37bCmMC+YFCC6Ib9eazTbnVoDCU27jAS1zp8TLqFufv8fHHzfAVjlJtzC+ARK6w5ox Xq4Xq7aaoRE7dW62nXbVeBNcfqrYBOE1nGu5WpsZWR662GChb4KHvtvXq7X0jT5Iudbbea/T xwCBEzscV5ZBZnF2TPf7f23Ai0MKtLsnl5JztosriK8lA9NpzUExun74NKckgIdytBlQfbUE Hk6iCunZqTBoZnPqpSu28pE5XvnbUH3cY0MfPa21yvJ0IxIVgtWlDNMMapg4ho1pTll6+vn8 NF88hLUn+UfmCfwWsIWv48m0xjKexcBSDYnPApHa+/kgqI+RseL+/pt1A5W2+qhiOl89f9Ha 1Xtznw3FuCsu6SDrNxfJJAVaiW4rAyHnNSPGyPEmtwKHAQi5JsOZ7AAspfplT5seDWpW/NIe zVAZb+fd0VvTzV3faUUZWemCNrXji0Avzjqf0R9qWdiZ/zUZbVlxdbV7sF0e5kz9z1K2ja3f eoqjXLkpmANjJM4xI9aII4+Aj81oTqERwC1P5rhQM6Ui70hLjrTOi32UpqSTwqo9qDxwFg18 CpLx2T3LAsegj/InmckM4RUEFdH4SKrL1Qnt2DT3vz4AF2M8dOg2472iv1xxLwzHzDtWk7Tt p3q+9OcRTbRQHXdX26kHEw4kqHggZ1xO77Y2ELrFuOXiRqhtaRS7niFYhFk1dFKFtMdAoVdx VSztRMQuLUrNjFKGxxi22k8cUbqVhuX1uQHOoc9CJ0PiXQ3F5hwQDmiIW8cXCMfuPa/df7AP U52WhJsiOJuB76OYFZPUd6JEPvyyK6HFTjcMB/1aKpZAoLc/9PFQyLshCJLlfXXe8YtH4WVt jVnjVf8LU7Eucqc32Fo9pBgM/AFueANTsFxNdFlVso45xJQuopYGNkS/CWWhlqcyI4x8ojak sYKi+8f/UU+4alAu4LQ1Lm9NN1konL23mIVtEkjTMDDG8uVMRMfNznTWNlTc5k4juMWOSgf+ eN5Sa2x0UPy9SYBLhcb7alooRs3fdbM2xsk8XDIsWfyNGVBZWcyKFaBZylZUPjuy6PDxphpt AGS5PWTQzaJBE9+9ue3P4OAXGPLhJ/9aXBRSxXodgc8N2WmXj0bflAMYdYjTCCxMPLGFSqb8 9eDfhXCWlTcn5gkPEKPSvfEg5YnSRLexs560qSlKbA4YW57PGEkWAySqGZYUpNAAS7DbJBx9 di6FkdvXn+MbmqC5kCKDOjorp61pBVaU8xswXf3o09YaKsJ+H0X00WTO5o+u/3C1BrZJ9xj6 lGW08JMBsfrJtwCVQOwsyoufHZPS2FA3X/mTUMjc+g/9T/fQC9e30RAeXZyPJkbxqo9RpC7i mWRNBiVJyb06D9VYyEvKRMziK8M+TGslPhgEUBmKQwI8AQQn4keSdQD8NIHYTtjo+KDKS+Dq WWgsJSrDgGvY2rdB28+pDiX3Wxwju1oX6M4tmVxQAiDR/IlEqLmtvL3U7+zche8eFZVbx2/9 01ZaLHTRZshbtueu7cDTFAsDgB6+Mv1R6uwZYOCmJLt5PjN0haylTd+f9G3htGKA9+pDmahN +MII4ntMoIOOI71ZDjQ/ERVA8M+f54wGXgSgjjQ0E5rTPxhBEAjKRwmhvyCbC77q8UR8YUep Km3mXHYbeUiZi2R6xPJo4g6giwVgOxoeiSUo5seg8SKVRexGzhnHiAmVVddMuQesPVX67d2d 8JpCPjH2bRw+FI2ZezpNHVTC6Wov40CvVySFmthCtBbYKmXZsC/G7LlZOxHnWy3TORIvFSxh 5/loEE3quG2WGDEi9EHXRjDQi5I3gOJ+NTnoUF/cyaK9LaVwpTchBFbAwPbEGeZMtxzlC/H3 l9H6Y6LHk06D4SOCfzBgGCLTwR2sehNL7MZiKGCaBis+2ZQAx46/w3BWBBVR1gzEglIQ3JiW mgCqOfuGvT+AfpCAjy8/i7qc3RLgLMBBNhvydK+afW5pmuing+0XGYmMSqEMGOdWH28IT0Km 5MfECLN5KvYcOvgtYf30AhLsxhclLjHdc+lq+7hXAIpujAi9MDzRyDJHI8CumF80YNpaUK7y lTmA7D9gY0EG13pGBS8C6fTG9xB2FBsjfb22pr6GATJ+zkN8UMZ2BBS2UQ5ogm1bSa8SONjS y2PDTRPfVoVoZHpcDXFYT4F+zkL9m1h8cqD2S/vd7VVVosa39Ofdln5+e4SA9eQkYQANX4aV 0I6eiboVLeZqDp6HpE3NLyWIfxthByHUVymI/osgh43N1WNWYFNCzS5eX5A6sgkg1PyDHpeC YN0wHTszVa9Y00uEH48IORVb+pscJ9ddXwIK2wjB88bHwaJXDrdzjh+nBXBUwmM475A2QNiv a0LM8PaQtOrkCesBbU02SVWFS1lB3LrDwWH5ARM9/NusN/WoyqiynZFILDwroct1FEwUEyb7 ZKfyp3ie5kSai0ClqM6G6+7WZBVwm40jA1oNf4b5l0PatFuMUDHlLYSXQJYM7JNp9bJf3BVk 453BCpQZdbVfHHc7TFk003jsiw5Q+cmBxm2qxlgoy5FiRKP+2eoIQNdxX/JsWPhThOUePw2i 1dJmLx9O8sOgk/R09n0mDY7Xd4sytv8wqnk6YB2b6oPpdOp7OrfZOWQ1sWBjrzeHlk0ydIWJ q6NjhEqYdbrwRtZeISXBG7bFf6ohWdti47i3M09bGCp9g1DOr93JZAR8WufnYoZAV9yloW7s ldK21C8VHSfpE37ejzqb/2M9rOPDbqZ+rErw4RnUbK5KXIxX057qZsiK3ZMXuJi+AklWxoRq KigmFx3X9arpZ+dO7OzxyFbVN9B1xGphQVTiuoGso4KDI4Q4hWTVSJg+lHreNOnJk5gnmY5H E5tIxF6/0U6Lz+5RVnUbOBYl7xydblzH8PyLkTbdKparSDb2S+MdVnL+owPSI7XQ743gW1bN 36GDKb64oU+nyim+rfuJWhdt0xvMU2RNSShHLIAuWYXDml2k8nUs13u1XGqd34YK3br5Xp67 VM9prtEjqMWS5lebdU4DyY6mP7GuBIs8bft4K20YTtUoBV6od3j3I1zjUBC4toKZ/c9xq3FO l9XjFwZe30ytsKAD83RmDpFDX0jeezyr2GDxBjPXbwm39xk3YqDAV0RzZT7nFNgUnq/q1AzK 8fLsKT/KVc7nPV0+nXvTHdxNxgEIGRjkqeVvvQf2eBXEJq1VwxlONJbJNh0vHI3ay4SaDPb8 h2GLS2jtw9Kfk/XIXHIteH622jZN8pWc+GSzLRBBFQ36WBANZlX5O+g8YQvXNxwnkzOKsmgs bSNAtZSUSxG/ubacr3C5firv3cjU7vSEb4Clt9ntrsebVXuqHAJo7m9Sj252WZTyyx4PG40h HKDytnIUUke0kMcyoOyKjDN8ZJeIAE/TNEM7+JSGZY1n+G+PGA7Mx3FRseTyU/9PQ2f0FWbq XKC32d3qaxwHLObp48BUYH4d1gobr/LiZjTVCKY1GGfZVRwf/9Tfsh4YrT9WG1bJFQZ9EJ6k 2M1XrKN2qR8u/icLMCl651y3G2F85RKcznLl2yNwBJgAkfuiuT9G8M7NXSn3R7EK3WYD861I 6RFOPlZhA+2T+Q3Fg0zeM2/xyQcSQan+gATitB9mCWufRpCgMGq6g1xI2UkST3yI7LtKCfO2 pQPDqMy37MteYMDAnY+1/JSJ4v1sZD+leczxtkSsiMkzuT9Z5Av8Az97BnEiFTsIP8Au97j0 CrLjE/ZaeQrLTaSWjHoaAALg3RoFJNgiksnNegcTymhSYn/nO3f91H5GFxxWE/xmHYr+D3Ok rhvOYwiOYu0SRHzhnrb/gAypc8FwzjlX/YihgDW3+LDgUkpYAYskHgw6VMRbqsgxyNFYir+y qc26ojdAYmm1HdS16UD4WGxK+UqOYAZDJ8tXJGwKhBA6ZSBevuB8E0D2vrMTcGkWA5I5jTR4 fPK4sHZo4EdlBSphqnT5cf9GiaFQzz7gxHoJrUD0SnCWJ30Ew0mVp3YtnmPwRACtJDXCUEjD tQLJBFgtpGOktIZ/KfYgDQn0m52iP7v4SDF9T/X2szbgZywSEaDkJSJijOt5NKUbRZr1eop5 Ui5vc3f2TCqLWBIr/spocZmfi5sBFDGtFTlfXzv1FXbVCeRHxgWefLFEsK173ty8Q3f51m9j KqL2dMjJVg/3qKZJgvQu3mATKnoH7b3BpMekLPAoEQFVDTREECyQWcTCl1NOtkneZ0c79S49 q3/uwKd2LympfYKVkLz8BAimS/azpEmp9R+jBNv+pI3jDfjXgjXEGorbSK0d53qzgKyCaQkC boS8zPXt8w/wcZM8mQsZkHa/z2tCvrGpOXbSAJ3UnH9scMmMbfzfWVyTkcQbwAgJMf/6XktV tloc0Wr1QKTWv5/MLKW4SDB4UeQHzIdKUTuJ5Bng60Tl6snm/ta8mimTeIN+kPN/ZrMvioXQ 98vyxs0zyXRnGk3qmx+6vkBdkAMl9KmwABMsCLMkAcF1kHZpXPAPy3QqXidjQXfpQRWXve15 Zp0ry04BPtjVWKsJV4jpAvGpPrAM4+XM+T6f1RkCLLQNzV8mdExnZoLLnsYIFc23NV/FwRDc khgPxLEcsP84Dr47QmsNs6gjDYuPtT8j0prKT5wJuSBzBCTWDTAS9ZFNrIvb6OzatAjv/oA3 4YleCV6nNZ/WgZJvvYQ4i+EQNA+nobssvVaP+LqxgDsxi9fnpMMVmdWUsqEdvqRCYYNCh4T2 6R4btIY3VJsRLyPtbuwaeO37ls3Y/+E24D+g5V2f7gmFne9Vv50cPQnz63IJSQEozXEpRtoS 4/spPecwGWZ6HuESc31F51682mt5sFdxoHfsGVujjiyGH9+cZXTqHIz7xc2Fuj8+pRrlao/u xXkvNd4Nx9dyxXsGJBJ1DpvAgBlG0guMO6QvWj3Kt8y88havRhWAej1FdNQztCVDHGSkcbb7 p8xba4/IPv/dV28shB0xkyR+z3MXQV5HvlS7tJgdgpz7ptDry7anuJNNdmm88bZ9HU8K/2un FDOLvMf+4KUtCbEZA5WHul/Rc0asm6RbnpMYMzjLG/WH2PKDpULwQiaa75la0fP4PVIl3iYC z3kQzPTBdC/+9qR1W8rMIPS+nAuJDfSDdhJhXeMPU2efCRYo0l+UUTQzVX4DuLwCvHu+Q8fk g/hifOBE3S8yv9rds+A3vyUoExL795Er8FL3LVxe7FgbzGJEAkHdnzUFPYFnTm9VF3vdiyGy aGgH57fuQXHlmyDGmbdi5FQ7oU0A1NEhCf/N92CH9qzepifB/xOK9h8Ttdhs9vfQ3Jzc5IFM 1GhSfnEOHm5IxA30KMPB5pkez7iS5BfSle3qAYB81uK/9wNlyZFHmUUyZcHgrg8wdaAU6FpK M1cjPEuKwmBERb3CZbj5hk9/0eD6eE8iBLMVBBo/iZLVh1S9Xaksz52+32nRSztb5LaIskOb TGKbvETYFAL8YzR0VITvofYu+mfzqqUkEYgPZSFqSCeNlLwdAqE2+NWTAkGjLya1hGeFG19i 0f31ItBzv5jdnw5BpvBry0lPbQQm03v1BTxy09oxFwyi9rMMS8zTpcKIf7IhjYY6/+a3uKJd EsMWTiuUbmT+1IuwGUy1Z3ns26e8HLmYEflbmgWGRf3xbRhsC/sFD3SvOb+Sp+no0e6gCorv pcN43Cve9iWghOdvJxCFeq1+33DOZ5w2x4oJxHqbvDXt9I4fUpAF2E+FY6LXtc3T4HEXC9wL cmAFOUUf14rLCegA/bJEtdEYRFEvi3+S0KrwpfCFuI8HAep7tgvXOrwFdz+MLB8O4fH8Nghr hW2blFAwMF9197V+Ox2K3ikG6eIuBoMFkqTMyUkXbX8GidQMJu+DAkJgBExcySV4c+8i7cug WI6UIAnLA7QgllzxGmgb4DAQxHLqlXKTXNEZ57GS3/0u/9gbtVXRLJJEQxrMSMJY5H/NlzR+ M8pFxM3vLPY8j0MBmjAky3Nd+oAbFOIowglv1vKz45vjo9e2pGznQTyqaIrcYEQBINwWrjWb 0Qti8YKPl9rQkt0OIcs8zl2F1WWF+JuleGU9CsTG1ryKtbnUV+TLTX82ZGMWHjYQXav7GV+l HHKEwX7HPyzcAjGmKrPQYAyTcKFIy+4ctyoMFOMkIoXsVTC7mSJ+lcKO3uSvdZUSI48VYeaE +XjbCxu16t6UHZgv8s2Du+JZBZBI9k+p0ZtleULX2/Yop8Xz5WpS2deJp3sfKE3kdhhrS7SR dNr699NtwIxHMlov3dMdeQq97E2QM9jLY1pBO+us9mFNtdKjvOYg7DERd2aOunYCOgaCZhst wW2pwbIj6ZBoI4TPknaUzNg1froN5dO+7HC0cPPzV9eP3bL/1bqQL5Hyoh7HH9czULOlDYaE TOeoEkuej7EHAAcfZGROHBgCns8D/b2wGvxPoOsDw883HjLexJnuKzyeI9kVl5bHhx0Ek/A/ UwjPclaLoFSzdejMx0P7JmaqyWmZ/VTMy0wtlWZ6DLOmxQus8euQHpt16Q2EsEx2oO7150pG nsfU2bG30cCs4upNLA5dtAwsjpx0AMVE4o+i1LMSk1UJTltjVsA1sJ7d7qbRZotl7/9A5DYD lhshJifK3am+iIbogL+GWjHgmcm7Nr/isdzPvGTbWlnpi36e+Ns5ypjTT3L8iYQOofWmmcLl AuarCnz7+qkdvSv/En4ecguZRdB3z89IGhzGcQreGNaqKzcYSKVtAw+y7u69R8Q2ClZin4wL a9Bkd+QxiJMbbr4nKU6/enEUOZjTPpfmIvJ00DA/b9LQurz3tlmT4JFxdC2Jf6zEy3Bk4m4U 5wLhuP1lcRFQ7M2mIbOJkO2DBcDAoglWjEyn4G0GbCrmlm2LsvwXW3zJclDehQQettj1iFHq OOf+UsE0cE+t7yudimjkXMBfz0DCF/VfOjoT6Rbf8Vt6j6OdAUeYH87zbE8DD+cWEqlV+NSS Iujfpj67pJCrqm8hf2Esk3xcIUVR8KcRmwrXYYMFNTY6K+8S/WDTl+DKhPRQtQizCwZAOFZZ ezv4rmM0uAA5447fPy07X/KIWBZgCStXI8zfKgwesjBnjr3Ry/w6aFfnWvtl5KAagbvydurd 3pIqa8EcGYsc6HbxnbQqMgRRx3BLejjd/zRojVqNtbdPyc55sX2z4cgQ09zv1/NaTKRDC391 UwOxlYnz+w5Y3xQfUR4XAqazutcb6qNevrrGMcs+gaRcQK45BvISXG8T0Smj+XeYRIW9SLm2 XvDRBTUXzIEU+++zJMfCc680v5CSKsVULx9ssPmql4hr29cz6GXHlC5gpoacZndP16AHOoJv InUaBikWO4bKoxGz9Y00LAZm66XFEDpqM8jx1SMiNoWO19GJxypZBegEWXiONRAj9/HBXPSS vUOuPVMYyf9BY36MQy+ZKbsD2WnbI4ltogmeNIJpN4OuvRmmVbrlQOxzY+/5tSjXIM97gByi fEWJW/R7JPC/5Tdq/34nox8A19JWQvz5NWEZBn6RC75cPBM8y2u1CYmxrhqdhtydJNuO7AjY 5K7R9+VKO4I+tt9em17UUmKaBo1OT0c43yzOImnOMuluLzmXS7tmtQLxmIbCs21TjoniXAsW 7p8JMCsDhwKMCg6oTJh2V1B2ibDASReAKfNR6IzCQaSm0Pf4hHRZz8yq6UP0G1n5AxgiBt10 vLNOQXAYYKYvXy+qjv6nsruDq/JhvNDxHtMn4MKpfnrBf/ddJz5CMhchIPwuKeVDZ81oGdSC Ws7ZDE6l8vV7r+cIaeYPEd3kBCO2j7ywVtF+85+0XLHffiBQjs7hyMvkcdUTVN0ATHi/8/Fy ojkhaJXkosWp/Q0XOKaX6NkXYYReIjjRrq5OrAO7GCq4GZe0Qhj27dWxi6Qr6jgij8vEyH2I wNz5LhiMwQvuYqrKW9eeRRIZdyRCDCNqohDSZBs6WdGm7ijPZ8CXg0u1VV0c7iygX/bsJAZ5 m7J+D7F/bUGo98GF/Bxq2115EpWXEKe+DwqtXFex/O6j3kC3iYAD3u8ml8BVr48VrRFTaAvc H+iAdPrEKpJTg7ei+d7bgztYBhAizSnxdEb2oSQ55pPJ5a/b/NRbE/+iIXgSHU/iXG1ttWFs 58LhjaDFcdeOSt041VTs0IiLbllslQa/RnENgNH9kzpHxA1kA3QtHPB9EvZswKRHMU/EAaWt 3B1I1dkS5IaoJ9qD4dzcum93eu1yqOXkkLUd5iPGb2XzxItXZspV5tzqled9TlHMlTi2mJvw liGb7G7EQDZJ0WAcxPPMlP1Xo2ZDX0UgFAikauER3Vf9D2fhwlP+IqKIw8W/BjQO2441EWHR SqeZNLU4AMgCFkK88/sZbxcjg85YRgiD3MIy3tPn7iqN3YpHkoxSa6R4s57f4rwa64tJyQqj 5P00sMAqz8lLHZzcdCOs58jSQRDC8s2M0csxojluAdEVlDyjNXmuWfhBtdiuqHpm4JoQ9PuA 7A5LqapqNqMO62UmfqqwTlax2a+RFFl9VWf5kfsSJcNugMZniaO6hZgfR0427WQBS8xxxK1Z QsgnK4XrDmaVtNpbf3Igdu07eXn5q1z2a+Xza7DBIMGaeWy28rms+6AFhuc2MAkuGSufe8o7 uYYUHBUk+YZen/WENCJ3pM6GeDcxOo43ugg8EqGetex4haXq1rGLblEN+QoX2QAI+tWmxuBz Bl9t0nWrLgIFgak+y1yV2pVq7psPY7NgxaH1SFUr+oYHUfeAEafMZxPKAjJTshrtjxxLt3AW cvmWVXhNqEzCDpWLezV6s2skzwx8PDssMhPpUKCFTmsIwxbt3uJdwvlgL0SQZNUonBo9QdHD i4hqRbxjlG1qZqPkXkuvhjQ1QxbwhApeyE3ej5AZf9YhyvCQVGhtPnupSdY9n+e5h24+eJUp q4Mgt+qk3mfPJVq+i0XJzNOV/bXSYcpfC5gfwIqYARE00/T/hpIdI+BfsqrH6SUvHoxStaOJ GLCxEeNZPF7Jpd7y6aJ9NU5eji9Ludf1/zJFYYJ/qlHAGsudyj9eLgLMV/+z15KzvLCOUZMX JhOc0tlJenKbSA7y04Hph3Tdh6Ah589pZOkAjshcd6i5nZoE4HUj6vl5u6Z+gBCsMD5d923u FWc8bQZXmtK0DP6MENMY2AlLvgDNjLnVWWHdWovlWw70i3d5WzbnwNm9foNpiK5k6IjbJ8gK YhWJLp5Zjfp30Mby2ucPGFV1Mzu7tXLA174Wn7JAKksMJ1PBTJQ7xB8134/3Oiyn8sgv7srf 5VgMz5K2Ff59FKQVqn5Hi1ZtImrU6I0BHPBQ8qzDbctCzlpBaq+G/4iaNkdSSqA9/6GMK0QJ 5mpbg423ORWIusIjrO4J1/1i9ngnj9NuGsVDIENzwu+Yfo2OcsSu9Ego+6VzPf2h4Rxe5mB6 1M3TNUD1v3+idnLjS4vevPOMjCoguDkV2rHBvRkEPQuUQSue1WQW6AwUYDtZzMsrCva6rHWW /nTHf8A1vzFlAHVrjmrHcV4+GpvuYM57/MnZpEKMb0eQy4eWvZXbLpO1TIKpa6p1bMkvhLLZ qB6b02eoIykALuAncOzktzLqqb5KMpxRrNi9QU67DB8Y22BAwA/G3LFwwD/aTpOeDbJ+604k MFLeq26z4ovbZXumxZsu+vng+mqcUaQ4QF6gjaTcuiWhMWM/qCOp2GimnDaGx/bCnMkL35Rw 178BJV8uXDoBCIts0JNdtFKGi6ZvkyUw2/4Acg6Rkx4tY9YjC/CQezAhsRxxAR/q28Q5TGd7 Xjk0ILfAuDl1mFw3n98MmgLWxQb9DCAyruWoPzoWY+EXqGsyY1bGb6ULnQhc8tWxqMgrSe3B X4/yG+olit8N51zLzl/o3GURI6gNNUM4s8d5utHPYESv15TaUGM6SUiGeivuvs7J6XZIIVVF sQdA1WXubnWMje1CBOxPgrPWL6J/Cj+1vKqiDvI09Rj+hlqI4CgsjmEsZi8wZvdUHtHKiHYi WVacX65ncI+C6409E9+rcXxvNanlRCwkenEdM1TkyfnXR8I4M2HKINMdKzhsXIGulRZ71Y5m J1Sfbdy9PPjM+UkiZTJfRz46bkjo0Cv8+x6HaE0PAC+TZE+S21W8wPdDX/JGzCcvZ4O/I0ZQ DCBcwSh57ahpXgPqUIkns3ZLww/nCgBYD3zG/ubkx3EEyPRTdp3oKUwDzdcLTZE1e7TrbFU9 Obm9lnxhnGW1Awxx++48mmn2QJg0GlOXVjMMLMlErGjVZZ1BUcAlrIFSmjJAJf5mmfPcXlEF Ydx7ppFogbcadeSz9PP3dRom0rz1Vq/zr4m3yNNxq0Dppfn//FX3PijXDDrke8NxSUn9npz0 fYrFJZIEMamABKbse+QV3zthH/KpsOSwX5EPwn61/c1MyUfa1hPHqeYp2my6PIYCR3pXQ3Fp NawMLFJr9saQ/QqVhgMBtNWRnj7TIB7xU4y6JAqJpUsHQ9oOsdcp+2iP2H5t9RORlukOTGzr Bp6C91zE5OLe7bl8TbAUDWBx/kGMl7eV+jFx0yjQ1VcmdCqGqONoDirGsUisOUFgzaYLtih+ T5FEETXyBUqAdgWwHNSAwA3cUFd89ABLT+vwOgZz8zR6SYLgY09Dn+2oniQa6d/CZ/HLsoKO 2hEwQSWRKoAMPO3tYMzpzZ3X9bEDRwxx9Q7HFrT3Ltq7tRGvpYVUWiyCVtcA1/MN0BAhjRUi InXMnlihywmOMwgA5HEL1qPr5ou+32762Yj9qvbuNUz85WMfCIM1QdBVkWwA/LeyJKkxV/pA PrwrKcxugaw3ecKExC2z+lsPC5tyV5EfAtngkF0LxMCBJC+8uMKA3Gq6BTN22ld6g/lePl2D MkYTfpN0YCiGeujXQgog5iNpYVyD4rwKJmwIff32wfsssofkPuqqW7JPG+9S3D8TRFlOeX6u z6eSXc9prwtLhoMf2CcL5SSecbXx1Upsznz6ttRiU/OP4qvG/ZHCMlHZ9yM1NCW6LzBDqRdN x4n4F5otKYiFl3gPEZ8seeooHJ4JXX2Hk0uSIW7Xv/Vt7xDVyDT/qJ3Q9pA9gG+t0bm6niXO jgc6oLL49M67UodtLnKgj4wz7d3BY/tO9LQsmI+qqJi5JXzAPzp84gdsWEb5BAJRvx3n78dl vRikLR0e2dbyXip1MCb6CEMtgDqplsNHnrW5ACP3PE/qux+cGTHOHlYupD4qETzaGGNvSiGr nZWvrjIsrL5SYFLoMwM6uIai6k5TDUaQainu9RgZMTgo3a8KvHhxt5WW9pvwJm3sd4meBcrk DNHSonLBFvNfhdW+om4vWfKjpeHtySBkBPFflNHM75FB0KIdGVanm/UTe9puqnVxFu4/7SRg ztIH2w8QGgYufZ+mSI18x/uQmjzcSE5ScYP6KhVQXHVc3tRGM55UbvvZ148cNohnAdv/QBBw B40OeTLYppSg3vdwE6crh8A2j41G1Lq4WcPYLIwfqQBUQzKuEV0bS1ZglAJ18nCZNGB0J7lT UuIswBs/bZ4ncJbZdPrIL4WTopWbFuK/MCesQ+AMFSHr9Ib5n+NMC5oi2oWFqcPipGMcnY/E Sk7d/9iLw2NOJohDYZJWzwj2QZH1p/lSUvnUPQZlfM5u2XDvzttnpJvsuKx40QnofZvlZwTF v0r3UL9n/lBwGkhgzu3XACmZKDIKXdzIGIV/dpvBQUBAi9kyRwKTUkCl5+Au3ErRTUWxzqmu Jo9iajEa+q4bCcnz4T8RgBXH1G8MCUgMNm/Ojxo1NrUkECMOZzUc3J8fCBE8SE3GniJgr7l4 wp2f6v9NkU/ns7s/U7/iG+XaagV1R3uvPmDAYPIefvqqXE2PgrWzHrYuEjBsxTHlAprwPOfS ZxVC+r14vbBFXZSUV00cebmcmPWY9rMyeaa9cgyWyPOd0MLKquGSyYJZYNWpkkPJXInIx/YM 3QBrUso77uPSOXnlGJEFU1zKv3CzX+81QsC4+iEQTCqLn06oLj8L6cyJwqKXvd7IEO5qb8id 6s/ijMaQE3mIuGjh6b78ep8fLXAAJBB6AJCg8bFaO+FEcxbaGXMeeWGretVQTLnMPtIGvERt 9XCr1Z2NL9VYiCT6KsBtPtCIkd1OoJ/GuOnNHXf8XQUT12ZneCgikM0CUGEbNlIZK+97yrz1 RiE6oOzn39slc1lwqkecy8sYgXvjGlsukeMGX3WL1wcJyN8PKcDNHsXJmnC0CLJNTeQzWhpQ ITBnKYfY3zhpRKgg3VcfMqy+Yy5i3cq+hnX1QHOba/w5j0BmgXReOv1iZowdrITBqcWgRbd5 ciUQBEQfdRqMTKdKUWBQUmI6KZDXpMUtVZtGl6MYWD/zEYkLkgeGd1ngAv1h/oTqTv2dXuPS BCQt+JVrJEyErSsN9mLkFy+ujw5RvDrvg5tdiojyx+5Ht0Ihkib1TNUqTjfyEJiCG9/pgTIK zaDI+wcIVrTsVmqR9on9A/+szqu/UaiWviJLflYOu4WAlBmvpew9k4bfA8JJkC2OsvtXbv0M syBlj1dZoW1wv0iHh15DI9aoJ0e9roZCvSCNM1pqri1ZTnk81NllwG6zmz1bWYi1nStmVRIc jVoebEAURF1cJ31loJlxAYC7ATSsXzSexfD7amlSEGpzaHKTLDyKN1q4akpcY/egMIKMEzMi kCM3aHhbi6ueWuhCgJffoeB6FU2tksTN0tXtJLvzbOkm7ZSS6/OMvsaQWyBIzDYflyz5Lgsu bm9ZzD60ubtR35DKzyw47/RW1rvvN9BPMpFG+D6LKvVb8L2vE+c+8VwhMKkmPcnWAaESmV/u 1vORfRewoiJaQfWNibLrSDZGAURfQ6HPTF/cK2nvuQ85WT/eJMUuQkvzN0hF/JwwSo3oTrd/ j4KozEUS6q7Te8cYj/1n8hT3vZ35HAoz6Y+oObsxpfhHIRriRThR4yTGavDqvbGtJYQDPToW xvf3g9OlVFHJleSPGJAtrA4ijANfKUMyhpJa27hsPxhexudCuqR1B6f8LS513UBqw56i1GgS Z0VSI40TMrGlQ24FzRwFJwcOX9+Z6QypaAAhJmthcpUrXpp79/2PKvSw53EzAxce8v/lTPRK u8Xfl4nclRKQSqovIlXSC+ziEoZiq4h327Vs6P/jjcuodYG1dLlsIJKrv0GUZNaReqBxgvYB llqKykvtZVNZvW59K/fBxPMI6aMcx7UHgSC0SIJmTqCyIotOSUG4OyaktkTKdJNKatRbGpc3 GQbt0OlAfZEpkyMi/rwtUAnGSoojP+iskbzBkm5u5u7kmfJCyy5jrhkHyuYYlsCOD7PCcZQ1 sGI5yC1zMCyjaEYCH39hSM+OA0nzXXH6nVnEYl//fIAifXSbqAs9DqPZY/5B/jstxIMf9K7h jiZ99imgKT6DmErISG3U9FFSV6LqXIaZFp6pua+jxY3zCSMeWR1kmav9kEyx1MTQfKhyw/Wj 0GXnAA6Ykd4TEFqYJHwlBnPy23NdYGIUR2lOx6fnnms/BhzwNczl56VYkJAZ5gXRwPIrevgV BpWd9g0t+uLykFsibOx8jtYzwbRc+LsgcZcCn8IJ+9kPT1ViXj+HsXGejL0hHo5MyHpY/JJx FskrcP/x3K9tbj5p4DXxNenAvcCCaVgqYQ/W4Jq0kVC4ORYMWbxlgaEFDJ594dhT1j/VY59i zePs/JjG96kakJSwnYn3C4OUETbhA+rzOxJdvbPiRL3tSDoyj3a6YAMdhSJ8nSrlOsp8RfUc Z8kTdB7b7CcPwIKsSdNDKuX/b3EXs5ANeFjBrs0j4hKjmGPKI9KvreNj2cAZkLJL+2KviDGO 6zQMWfJk8myFBDn5ZBZpl+NWSLs6sftdQhy8oXz/bHHz//0/V89Gk5lqkySlkLh4gws7cvJF AEz3ptV0OxbRHcx9eEcbH6ZZNoCvt9sknJ72ldqyt/n9hO58jbX+F3ZFapjwAwUTCA6djO/s wre8QHcMg5+vvjS57EIHwXQPZwpxWFe44Nzrvq9wACraHyH+86uPUVFXM6JTNsFw/7GtGv4N VJtLYa57+0UyQyyZLiA6bn5EbKnNexqiwlpvokeVm3MzK9IuYEapU4195wNtgHpEA7Gc9BER JCND3St2Su96e+zyF77u3G54krhmN3Our0C8TbvKB+ayOzqsxV3m0fug+YWbjA1UAwWfL9TL SybUW81vqcfn88jcry1SiyCN3itLsWzxCdkGrT159fWzrGjODp6JIigL48igdMaR4yruloZd 1ylOLv2zn/0yUUvcdsHuapdWxhP1n8E7mMJkOIoHAZ7Q127/pNoWSThWT7pA668eKpWNRX6p 0IlVpU+FgK489+uarjgcSzgkTVrDQvHv/6BnwfMuMxqEbEkNLHptMC2oyByqdp3q3l11VQhw BDdp93omJ3q8/tPcQF9pGPD5INLaTxDxJVS39EOdwXFTuILGb+i88tK6ewcv55nFqvfim5G3 bW6syJ/uPKrcHlumnKMLnspzNqlxGOs0hzi7YVxgsdFikfcIYkqWj7hlWq2wzxxnW8PcJrIY 9x0LIwuY6eBT5UfcHlSaCk+2cGfk86gtb+f5uhnHqh3h39cDXlXa2bAY3Iqye86TZmcQDMx2 UieOfbryMaD6NsaoqAVVuBgNwn+vklFmEkIx3UmDRTtK1+4sQDrq2Xt0euTWvz5YRViq2NkS Sy0WXwAHlj5TsSd5a4Kuu2F4uXgXOXoB6kDE/MgagNr+BQ5FiIj9uNn1px4IDz+llWmeF0Xg IRG0vedXFR+dllUPr07Mn7iOuezHyR+upQHDUHO2baiZJaMVMoV+DHkKzwbB9Fxlu1mbGcDw NdoLc90BYlVDDz48t7h6/tJD7OztX3KWAB2fa+d9IJBO/dBdzeS7P2rYMdQ7LLki4YHfIb6P yXZZERlTqiZdN7t2c9TJUwcQd0eICBC7V6uCm6nhVD4JU0AIR+ZFWQAeKKNAeYdKQUAOmriJ NSUhX4enW+sxIvM1RQ9QppzR21UlAmFQd/BCdL43VTHHrrQzqgzYE8mHpIdEMcukDBCI7Isc k30aWiEJpmzQld2L1T1wMmLHTkk2N1AYjrjzYVAboNjryy2rXchHtSZl5fYp7n8L98aUoWEX 9CPYDae/rn1j7KkszOtxSi2kvcFtHonXvWvXP5VsEAjYDNbxyYy88usT5EytkS6TGa2qD/jK 4wiBo5vVgoGoYt3rkSfD/0c6LWIx12fxfth5KYdkrxjd8hHgcrGGFM/znf0rqz8F2mU1eJd9 YvsHMQrXBYPw+0b01abGnV3hX6CpIa7QqzKMDTP8Nd7mnyc+hCW0Ue8OqU4L25ajvT+GOQZf UQ0CpFmz1TpabnJWO7GpUDzbcyuE6DpRyX0si/D/NfuRZSnCxzh9YWMVaIlHBJaMQTmS2zlz CfmalqcvwCxzMSB1xAjqLsC1JaIbRRZOfGyi/+7ATG9/616Q136ROC49Vq9m8nLemwI51jDm v+tELMkPy7AHydefXfXhfvZpdxRl/vgqPI+SM33sIZBh5d1cniZhOnYZ2eCuM5TKVwaz7AIv zr98An1l/CoE3iKJob0TCjxxEEIlyLwsXPkkMaUxjuF40+bqJh/x/7L5mGDJAcPYqLoyehhw cBF+fkiVbGvrzor7wmGEB/JOdFWjapIBHkybxXHgrYUDYn8JFVWKRUSvZY97ASQydPUkWdL/ /t2GvbMOZ34JY5l1Y0iqzh/sjxN8CthCSfVQZcxBWCb6Ank0UJ8U6Reot7p56Wwb8yi3rJn6 0NFuyjaRkq7ClSUDpsb3X4S/EgMegd58tYulE6PX8ojvqZDRmnP5ARPIXvRQgMghnkHVksR8 qgtqzFb5LZjsFfbm5XYgQURaHvRQYH2xaXsuDUx9P3pM/82CM3Mzfazzf3Tb4QeZ3m8mE2X8 R9JyNdjkamodRcuh0uxZA9E0xpuyse5uX2JqqKtEwM9nri+NIHoI9d/CCkVw81y+PULAW7LC zWSpb4qlL3MiWS4XKidSMk7HyKlg3CcbQT8atWl91qL5YTlSAJXJWJT+gub8w9T2xB5BQwEi RSMEMTzSDgpf8B1MZUmMh/mIDLsoC0uyi7MOSQlGkEPfmKp9rQJT43R1114CgoKcmzRQ/WA8 J4cOX3XIGXaFWdv+Md6wBamAqt231T1qn/ACHpn2rS/hxNguNJskekeKcRNDb3KyOql+19Lr fm2YI8MBzWa8yUYTmoC3TPNj9dz9RMedyuPUoLHnv2KSlVZ3q6bpQszOFYA1bjYKrvmdgGYW y4qxwDOdl7cscntZ4cEYfRn77TA9FeHe6FH1heAOgxfQLJ6l577AemUxPlO+yxdDejx0QeYO hTtYM6zAwTv6S2k0TsfypR8dtqvtgZzAFjXx5R6hV0xDYXMowML8xiOdvSp5NAGod7rfwaVM HDMmv82Oe1KD9lpBr/leI+r2doXpKBagnPzX/jS0i74F8dN6zAofaD/3Ek9mNxbEEq0S0Kbo 6CgSu1bpzxTOoHJOZPo5YvXBujH5yA6IucUk6TxsFG090zPOCx8MY+wjIDUGdGT3FDsKbZik B0J0QUcc6tzYiq3wZ0bkGKBurS76DoT3XvQSvUk+LFKvwkY9o6WTm5LEbDAlADrM51uUXdxy D6zMbSUN7R338kDMr7NGN+Nh2JV8HnlCuU6PxZNYaVMFRLdMVEBiPE/kMBwAGscAGGgFMm9v 1TA5PHcWu/Fc+wVqnqJ/mMGpHiP0agx1WDw9/a9f/tj1NNH4MMkAE+tDv8h2rP7tm2xtw4L4 XEM2UtNjBwChWLzf3fSh60oSivFsye8XD+y3n4YzUycb+HPRRBvptYx/jWiSSCJcW2Yl9iX/ R/UsDvfunZowN20gb1HLmkXX3V+qcI9O+AbItCRFspvE2WmoHZLw+CO7trLarXdr/k+uZ1jr Mf/xVVm34qqd1++5SKG5fmMOHZieLdG9n2tv9o1cpy+4jC2fPFOibMDQVsTMLQPXAXZWfozo UprN5yOvId+TxpXGyUyrqz/azTOE051kjiH5w+EaIAySFYKyWEb6GmeJHlm86WtZxGsWyQrv OJDi125UhdUguFnVDlDa7ThU8wE2HCNORvB0ECss116ZJgxybMGKX47yMrcTi85UuVXesn02 nNV2050VE9pkQj1KSV7jfnc+f1JxS9vgOVqlIZVCbz5rTmFAMlx/incxg2c+8sYuIGqfGDEk N5S1BYsX5KqMW4O5snFojlCu1mvvus0qvJ0aldkkb8HePv07Kr5t+olfaaaO066ZpQ9RRlZ+ PTKuxJGd7rnpIQj58ZxGK+qEM9saE/Miygcvl5ngKluSbYjl/V+SY0a7MR3PdmkdWkwZvmwr 7564BAjMvzq6mKbsoN7jvP5a36E89kqIsSZb1o+IU/0yVRZp4vYQftchSy1jPIy8NigTWk+q gUWN7EqXmvbtzoLY8jgX8+dDZRyesr9LeSevy1I1cTEaeNwbIpGW/gGS1jwQA1M858LbjmsJ NPWw9GJ6ZH0/9chX9j3IAfOHxY0CIhM60ICPv5ROCcqZy6wGzVo0XaEBEo26nRw4VNWpE6W/ szOr3QNjFdE4XUoz5b/nJSUZ3uWarSmInO/ToqXtCKN9S1Giwa57S1PjaaneRFIAwcUG9B+u bWa6OKpr6Vwo4cN+5qPL0Ih01bjW8BVgDY2hD1LLFHQITLdatkXiq1y1qfLDZNxMYDEyA/O5 8T2JRlKTqmeqC6JlrPPSH+xZvhTaIZf9dq5/DWBJ5v5V5vsZXECFdYfvVha3QOC2W79eMuXn 1pMDyJpfpdEKP4OYehNjbAiOWZdFZab0S13rng4BdvFqLb/IiUF1F0zxlHqanghOK2fFpINd wS3F7AfdEEiH97lnEvKBtSg3/5bTKP7aYtXtY+X2GR6ZnobGlsjvgH2/mOQjhUAMYVDZGwc1 Yi3CMQPL5H5viO7TgtVppMCWiJYX0diFhVJrd8h7RP0VfPPQgXp6GBmxcQAQgqv/uUAkkEwT zKW9/Sl/r+0gscjQRm0tyGDScWZbJKhvsLM6z5py/dzoQkLeWHIm4ekMyWOeRPzrluB9oTKn VKH/0Y6naWJmm2h73oQZlBkwNUk7oboBRP2M4CS7IpbZy3/r+K5GL5j+6WhS17oRJT96Fo2d KSNF7i71XEk5dlBUcT3ZNDKa/FTSpncG90PpnMYjWkvldoiY19KSXRDI9UAofY342q3W/7Ml R1Y1skTQhp5xgVUSAt+NYNYl63Y9D/7Ur2i0m2tAX8X6DHTeUPClu43iSLLj5ZkFW1y3AobP QzpZaPNZf6gkrRvStc5Ira5Yx123NEEs1kXfWRhov+zVAmhEuVP8dWshk3Q2MyhubE7HjGfB UkECgr2YfRD5FljchXylpUc7NlysSrlEXZ4R4pXf4PFNO2raRuSz9qGgzpocSlfr690MavJT vA2F8C2wNmjY/RX5ovstJex1yAciJT3EZ1TzhiefO4Z1sjv67erRI7aU4k32Su+xhBfcd1l0 E/5W6zIVlJMa0dp28XIMuDAYRfOAGQrGnNLrykiBhWXN7Ok57JyZGY3/PKOBIcLqXIolKuTY DuHfTuXNq+fUeIPiFV5q1f45q0w0R0uTORe6zvAs0g1q58+27GEnzWjS4BEmNNfOD+SI6Lpy pL8pvsfWv6yAcVOTq3/UE5FbJFCOIL1HHQC8dRbMEPJtFnGPP8hFNSBk3o4yGfJKWN+EDyA+ zOxh8tduky+G1PJeCfS7cqvrfQrWPOW+4v2QjTrFTdB84bB1YBJdlUSsYEYiwZYszMhZeEl4 q5AFKPpE280o2gwjSbTboGMVSAVXtcE7s2u3A1V/h2ZTsQiXz1ruFpzSMumZDiX5B4N9RxPi 8dKt9e0Z8DJy4ZDI07VH+BmepmTPbERuNqEvfPU8lwVrw50FoyczULy2AuEvFAWdycvR9tYJ R+l7u+qpIXZstxgh6x03yH6IkjsZjwohriW7ZTddqifngeg/IOJ9ZnJO7Qc7KKdThRxMrUHt gQW1p4+oReI6/o59q5tjw5ipvjmoBLywxBZGtYDiSmB0lk33EyRzyc4IDJGH23vQ2BBLFGoT cNpx7kQH7rkteR+5+hz+YoE7b3EVV0O4pSHcbUAwIGU7mqKmJjEWa7d5VNOLT6C6kohR+m2C gegFe6D329QluXEWHcLz4sS9gfv8fk35Z2odK/4i8hbsnNGrk94OcRCLN3u9mcOtdc6p2jmn RUjcrJcIYMuvaUowiY/GHGUpxBEkiRKB56CkYLpAYoaS2Kc1q/7mSsGde2I5JKTkORM6OpLq cQWSMmpKDe6Pb7JoAxxiwOpsRTEiSy3u3vZ6bySCmfc5jks6qidvuoHQBhgPfvDOf09+U19K dmCc3rRYyw1XZZ543UBpigy0I019gjn5+IS8CWaa3yLkEBvXCox7M2KyBG6QwwOfsSFFSnv2 qh03lP3+Dxf5T+bkmpXAXnSxWfTUgy9ij6JbqEcW1GgfyomHHoDYTbjxgFn9tvQM9eNTOsHO v1Oc7jf8z/OpLIJJ3tZi+gHE0fJwP19c8iybm4ndjtChwlDyw5JfojFkfylZ1zQH/JJ1PDJS 5qcEgJ5PFE6Lc7x43xJbC6nK12nr/6Ig/fvMFqGNYRWN8bn8nHFR0KoLtswwt/SeVA0J6IdI TbPdyyvWBPg6t/tiFG/J+d4ecF9m1vhc71Lkk3SJ4SMPDTQ/uKfLa9bvvKaUaOpMROfUFplr HsZjye8dTa7FmEvMHR26o1hrrPJtjrufs8Od0rEj9UkM/OPP14tZcVbiXUm3HKwo1dTKug9k 1FKVxEWo/Q9it0aZf4pjfye8h2LdjkuaCgPtcm/h69hS8QzSBsRh+57jVQgBylkOLw5FafP+ 55tlpBTAdn+Q2l8uW8eFRq0nCl3/HU8TpnE38MFJTwGGDoqA9Exg7TV7NU8T2NORCV0adL50 SQ+9TeXjTxTdqis/HmIc/odO5JMseakQv8urKCD5TrmeN0X9EXej5lTxAi9FatZNmPctsD7F 5FZKXC2NJMSAyx1/NGwIJc7yEwq8LTpwEC2lT9Q+XBKMMXeoUVeQoBGjLOq4KwrUj8PhMlbR Ro+EWMU748414OhghEhDqckjxgVvbOHybPxl24Sx8GSds5J+ouWP9pw9ywVodzOEQEhDbenH SQmjERyz88M/ilw9vCwaLC+d5TpipfP7dpqRG+if2xEnKiHuZWOgeNe7BDTmeo1m3HBzbTCD hVncvTnwMUmL3RnabgLGiy+3pNMYmRvlbuJW07QZj1K1Qd19QoKAI8Z9TAKeV0TT2zWufP/+ np3TERM4ym2VMIRJKE6nTZ50Hrrz6KCxDQfyj4UjcQLpIpsi298GaXfANLDfoI9VZL1wT3VF 35zUZK5DoZzzuyQNNvQ2zLz4RaeCelz7+Q/kqMqC1CFqX1MQIiMa1/PUEf22yWbOIiw58oGa LLKuJQguvmc/MHRbEv5eGyP/zuQdIhEfkxTt/ULHAeGbNvEHktN67pRdB51BKQWpDTtR2S3A OR23idHCt3ECrjygIWL0uYExuFqNtd6/B8GRq3mPt7jkCfG1WJ4LRQPjGH8RsHsIHzpfu86l VbEWZnkZsZhjshpsdykbFXZ8/ZULFGcYrqbGJp/pwOgdFI10btPDeD6yYBc+c14n3XVlcokP Esd5+pmS/7B18OwqHZlxqmL4/Jx+Ef2wxs6W6hqxpzvCrCFw3ZMOkGDKzuw6uewCo9sIWSDu NM/ufO+V2cF+gtSfMeLKiGivKnJllfmACbF4y1hac8bkW3WoVMGRhD4qdsjYrTpPdyZcIKkA YVHB7mqHdGQP714qCvO/W+sZEIxSO6WE3hPAjy3DHEZJjN6R5Oh98fRkdnE/UAgtwvEV4rVh Z8FseNrQD4E+weBXeTSp0wOYx1UcbOIAG35R6gr1AZr4+VDy5ldXrpF35s+87RL535wKcEiq Y9a7lRP/2rAA8znUJmzl5pa8wcrZ8EsXwzpebE4wATsuVbvSivW1dujW9TR0+6u1Sb/HrSRp hxGjALjGOsS+GzZuFbbq0A6PKRf1G/SE/UtdrcrFY3whUiyozLoUoXR2Dxcij9qbwn1IiZR+ Zvw4glE1Uc7sm4LuGlsVg9wbuKXxt8qgJeeScLubGL52Cq5j5b4Og5k03+HWION2GAaQdpIy iVRmLAUU0sW7P5lcwWSh/tlZGJn/dDZWiMDnSlM0NAxHHepAk1GzirWOL4OIcpDI8rZSgd8W /11jaPWsM1/6OhDbZZqpO/aiLB2z/BkkAj/l2guaekL/vjysKIsGsuEs9bkocfq0pl1LHTri JDqQU46pOl3y7WSBH6eTRYuxy9TYeVXexRCbXidC7ZTPesGIAvNyf0rqiGaLywD7X3ms69+8 3HaluaAegb9cezMGQv5nl/HElDkIxoImqP2EycgYxgnpOrmZ7bvWHq6wbNKSZEI8nxZ0MV03 qIvR6GGXw2AEkcvUbv2yGjAg00DtMjOAq/nphnM/uz/GYM0EvBAktY1+YfDGXWgIDjzKivQW /MNe4q3banlUxkJwx2iKTV9jkj7eP/VNBpuhAKGlA6sjhgfzemrpT0dyJCLauCUW39inhEFy Y+rAJuj9TRRCehLHZr3em+2S7A3oYGswWwFEamOXC8BdMGOUmLHP9wH+zI0xywvugfZ6/9oc jOOvl4PsFCHbLRIA8/pNkAt/+2jveY8xJRy5kBcUcdDgSyiVt3VZoWpX2NgxfXqwZjMuKYDe NtBBxgeuTfVtMKg4lwQ4AjwddzhkIoHqEqzWe7qf8eFxt6Aq0a6HMnVfr4lH/ZwsbzQytO99 s90wKLkWiK5fbea5rTA1HWoszIbOnorEoNsr/gvjVQcx/Fu2sooE3nkzaiCssWIi8KRwV9Gp z/7BQYTVOBS27F2MXOdrJQnZdj+oaGoiikDj0Tu0KGlI29gD6GmQIl2XREO+wETQS/XrGKif JU0/cgs5dyo3df8cZJof7nF7R77HNapYmnpqQex9268JpdGWdL3v9952xfZacP0faf0VxqBI eRO5F833tP0HqL8xuTkQVl9AnEnDGr/r3d7eyap4H0gxwNKOHmdToZJifwFp7YtVBXg+NEiv D+UyiKZFwZoWVxH9Jlo/THw3BIMq7rW0JTUqem0QEQ8Xl1KdLGBnQtXMPpy5YF1Hnvg+Kg1K X3yKMsOEkx5/LOdrCrvJRHCQT5XinebPZWX9scCnZ2THMO+chMPfAJ6AX8SrIC5/Dcevk8OG vXbTQZmIADfRYyL4Rp+U/ipLJ1/9X+UR6xZ0q4fBq5LebSmz9qhXgD/Gmg76iPaaVwcyI0jI tdD+w5bZUo2ucb2QEvE3g8WBpxNuTm16/iITz1fKY4W0tMxtzC6fH3ZraTvG90l4BZx9sDPC YaJragfUE0IF9Ke9TSPSYpbJ0YF6x+/lejvKgnMP0lRQEV2jMgFRYp56LQqi9eeZ/vwIEmFM ZeEAGA28AfTQL/DbUWWNgIcxeQkJ14RdTBFhEShsVC0fcx2MW7StgV3kQNfqGlutCYgf24WD Hh5KhsoNadcDrrUot/EMO7kaU2IWNLGKBNWmeqvcZZy5M/fqxzITbzDr9JgJPy0KX2EW0VXl gQlVnv3oilPO7grNa34GwtfsooBSjXN45I7njzXvM6/Qnp6v+KRV/bIEjIhOxhec1CsppaXs qkXc8Fvncuau8o3rkoWA71et1QPtZkpJ+V+buhujJf3eV9AB+tb5lW+EWZy8u6cvbqtKSwz2 pejkQbPkCGqgzIs0W8njusLebb70Oc2Q5pa6z3sEmwGxJddf0U5YMZHAYNoUMV0gwf81gUlB MZnxq2jxe8uZrtk3bFcOAVeBtII6Trj1JjrljIAIeGDsqtP48hKOLfnEM6EaqkMU0y6v1Hx0 dJMJE3Cez3po537SkdbJd1z4XrcJZJUCpnIle+zXF5W6bD02WDQQPa4iMuQy3quIuLyM5YWR R/jd4g6QSz3dlkIpky7QzeTgDkF8YEXG6KIUwpY/YunX3w6udGfbwK6FJjIA3qT8UUWpUooU GPmdfgEUh4Hy/2bSdRcw8Fd0TKiDYrj8Yjppqx64GXWQKCS3+KmCqvzUdjKD67osjjvlrgnv Bu0I0J8d+3s6Pbx7puYS06cZTSxOETDtrskq8rG/qlNCoOQVWBAsCnkQmhPkAQK9nkMnAk1f FYGY4CbQ/opJRYY5GjRx1VAOTAgrJUCLYizbZesFMXF3D8dGCkDAJ1lRtoSudGxjCyV2MpqX 5Mhx2aWdLx/sF6akTDX3qp2E0GKi6Nkq3vqDiOHaffkVHvTjM4A7MJbtgsVsvsP01mfo8wX7 RhXh164wAosYcttVFm0h895SAEoTmKElxHdNq8UOk2uzoWyMNPD2d/6OeE4nolV8ogN+fh0j aNiQ/YC6S5DYOnUWLv2+80/Z2g13quqBtlC7AOsBRUBhxHT/a09dEn4iR9r6pidKFD6a2SNs Fcv5NxXR/hfmDGzBHPUUZod71ERNyZYCGwCfiAnZ3SVQcHVWper6fDjHx5jWVeXgsZGNOdE7 4BbkolJeTEnap/3iBn70ZcUfCSGbiqxIgYMS/XpUMGeyX0lOgA0LvAZ3Z9g6xdXBjfYBno0i uardAkOL1q1I6monabICk0VrwBehovvG9SjfzFuncMsJzGf7DZy2nV2+CB3lfJswCRzrDzKm +92lvSaHV3evyHafcFy5q/WkTKYjO6onhGHtzCDoDuM5oAfxHAzpSd/Fp8/91GPogWXUM3ZR jj4/LbccujBJbGaY43/V+s9VeIrFjLurVA40XjiyWBIvxwDwegSinwDBFsT9JEH3xVf7fz02 t4a5ZpTxsb8aZrZYBztzLl9BjXs//F8KOUAiHt8GJWonn3hGsbMs8pbKnfq0swQcxs1Y/1wZ czlWpZAWXgS7HmnH3wv8j79WmHuyAO47g0VIBaSxOs0lljoZ/C8zQFj43vxhfnuHQM/+1Hvm zczRM/BQ+8FnF8B8NZ6M4JhPiYasB9H92OhZTXgp8Xopq9rkBrBVd/+urBJnd7BgBYKI4f7B acNG86k0mHP8+QvupNskOXBGOLeWuuf7PidVofNDTwsNmy0QYmFcGKpRBSSyE57syveEJ/N2 pgZ7NH9mfJbaumIwoJK0u4rI9vJVT+T+AAgUztU1y+SKvFRHZUB6YRj2eujAVuofBApNgOpg o6UyWA/TVmGusuFOjNi/NZvJUqqMitqHjSYHWwRFR7Wn9YxaW7hIxnlDGlNWWqwkcU4XrLsS WV2glaVY3qI5YtSTJfA+WcYMCcQiqQRZA1q0Ene9spOKC50A7++sWBOTqtA8yPIau8H3Wdsu N5WPNDw4plJo96sCGmbMFDTN0sfhEj5Ze/ToYUNiapS6bOErcpvxjGkthfPCNOfoubnfRyyH i+t1miUOleZdeRCH7T0NG1ov/AjkAdUWoUGWct8iIb+lt4RCHBMssvUtlq8tGfnkrBPWa8Sh 3WbuF6AuMQBujnmFpHJQDckU6Pvoxd/PHICtVrn8mPpubhKou/1hE06QIDTdABCGjIIMtYLI Pf5H8yOBrP4iGwtzWZZLw5zuUlqls9QVmUAMivi5pRHDiwiUitW5D0IR95W+u1SM9N5IrgYy i1MGeunzTWi+xd/LnQ+A5B4qxUNAkyMwMnJzE359X8kA5Jw45PahqH/y3G4NcNqyAvFbXuyt +Ekxx6X33UMHSWksgggR8PrKDm9ZpM4GOpFCW8mMEj5z0GRgc5X3mLEpk5NgtiZwN2Y4tY0E p0RdyaIosXTMPJFRClJVqlwKVQoMrLxd6c9x/8Nz0N4p+h+r9OH7Sg+Q13qcnQJ6HLUr/zZ4 IBPcSggKfLKB6mazdOmvsR11RhqfjqtKgbqY52SJfRcI0NmYJBynGA3BqkyYKbVtz08r7wmP eMfrKlabOccaps90jzu+UKno3y7pLOaxe/YtVbgxnJ0ZBCZNGprdG8xV22fHxd0QajZ/96TU L09tj4kyysgkjyVmZNWvyaSFX8aTgz3JG7u/EjmgX69SvyEMDpTS3asqCwlVat+59DN+UrIJ d+XOz+qOJ0Rt8mEMObFZiVtNTTrulpSFvt8YoD9uA1Ubpow04IaJgunUkkAJSfAOTu/hz0qJ lR81QjYfLFXZ5mQQfE0CRWTX0QrJXFjKCLBVPByuiNTk68fAikw2NcGjxuPD9Z0p8n6CVbUz YOMbUPahreFzzgxU1Y8mLHEA3A0qXX0cIGOUXOzLXCD6s3kfdwpq2Of2k4IDsEYH4HKqjHBm j8ULP3EZebaWJ7mE7bYqVLAor63pOV25OeBUolyt3SManwjnLmnpa/kdgknlk8IDyDesPN+I uR3CSxcVqAZMe6C7TzB+MjuHDn1s3yAgEgP0feCCWxHhpYfOWRtoJR2+p3MleJwyC6OFfBAX p0V6vHkcDLSBYTl16X5/WetlOE3LdfxnKpBNhTDMidL+PXHp1SQzT3VVoqVOYVBPzDaWntkL oMiHDTKpgzI67ww89x2a9HJdW+249fZk/3b9M+iKtjW687GTdjOHb/WcNHmjhsiT08/PVQUM Ae29Zo5Mhwme9Kh9IluIyWxw1r0I3naoOB/QOwN7wb4V6bO/DICnvAhYZ62jY7u7cpa3a+Vt 3E+3runq/SoEOk0ejuiREaWna/xCJ0yrgwnDzX27qPwUQ7KDwGPzcapHlMS/iwhgKICFF6jg AI4t47jn5YFw9gSk3N+yjsCQS81lr5dqr0NglBi0Kld/5OQIlg//A2ecvHjtMMgNkwIFFV+r N5KC9vS6wOGFGwCMQ78EIjkn5uZIqF7foBVW7gD5bIOzsdm/RS7cltza67C/zN1+DQvFNeaK 50odLlRnPN3f59BOiyxjGhGjgbc8mHEFE5oFuppfEjQJZt2fo81gm/hRrX5xzXmBP3nUcp6K m0i9Z6zmiKN9wuboCBrv3IX4/kdHRDzVaSM++TqppRJE5+apUyikQVtC87ZyVCB58Sk/sE/V lTiQlt+I4MhMmb4GFchXhMo+MttoOJG6CZZzs4C2LGU8hNFwcwS12iiXixSoAz+D/1wMhcrf 2cxdwqBBlEc3bn1z9SKFV8DjirLvucVBnaO98VQQ1oDKeeDGpptyf4m4na7huyQN6YdZswrd iVUn1vKpbh6NmbbdRVMsmTtRWYyedqY8+/m9uqkAZb2dIbiMsdgA27z5Kn6FqR975zy1Qrj4 YW+NJek19TRyXE6m+g0jyRXWIUzvCyqkmHWdWqD1ohC/yQRYD6Zf+A2CE5Vt4SG9FjvhaOgS 2PKIF/KvyVOX8M+jzJcKAj6pbnW6WlnFU//YrG/vwgavhhLhq/nVLGRYeKy0vnltVyLQhgnV FmPpzv/jjaWcP+sYFDHBpC8w6kzJ4tJ2LHFdYiYJdYSZEln6uMJsEL5fdVpU8SMpIXv++NIi 1twX6iEBGO9UxuyboQydPbL9psIhyqPJIzXJ91VvH00dzuoQNCG6i6wBh6KQO+S8SlHkveEg mxokRa7fxGlZx2e+WpXwmfxRBsA8HdbscFcLhKEe41PazkIzVabn75viJgio9q2fWfeFDSbx 0FcDyp9/FqcGrU6g43WHdSHp1bWMe3L/yVR3g7ZvK9XW+oDGmgd7zt6pM4nYBWrMg/2bRZZU zfS4poNWP9yDUnT4IuRZaV4XtSUjZt9SSyxiQomxnZsjKoln6cz6TR672oMQ4vWfkV6Q5R6x 0ZKH4xdxjqqFwgU+hRCY+hXo/2mK7cdCf19YzelWI4zNoyEuvpRPHqEiJH6Z1ZDQg63Qlgoe PXVlPqym2GY5A3qspaZCBKMy80Kw53gyQj2K1O48ZbPZ1XULeiAOhzJmKlY1kbFLrEBVDtIn 7nLRERWap42ZgtpJefionMDn6QkPYIuTjYEfHnoAu2J8aVMxRBrux0PIw6zMsqooU87d6QI5 +5MNRf4AXypmwFRye1enaSDZFdO4S7gAvGHZX2HJFdOW5hHgfwo19RKMU3/mthn33ckEeEnF Xlb0FC6Z8wrJU05cB9TgJiW9em3DG3BSz5LTrzfR9l+oQdxmf7/j71l3cv2dYfAsSfGyvURb V+KFA+qD3n/AEMn7VMfSz59fM+7+POGVUAnyhzSRE52gqEX5VHhHERfZDGtJIhWV+Xdsw3tm CdmPxMfvGtajZKXqYuhm2IWj2v0no1vZj8fmgs5h4EAHk4sgG1EHcl9bQ+nu3YmCdUhQFknV 2PR/F4vnOIZT1s9Y9k6JMSZ2/SAzmjH5mpFpFxqZpTPiRg3qItucqKSPNEg8CHp9uoA+qrNO Gje4/e0HzvdkM4ASFVeIPi4Ck3Q2RrQaXqBLIdqaGqMEJkCMYygE+3YHJUmF3/UKbRMXpJ3q 0f54LgHhyAjtYyg+vnPXsgfMI9aeX+pTKbIlmwDLemh8QR35s6mmpL3DeUvBwr/LfEGqE/66 2BKZ9WZvC6SW7M0zFyh4qh4H4yLpNdBG8GBLmo6XinTMBU65+Q3JVyatkrl3ltYF/TW3nuBV c/IeaklJVFKEKUrRfta5MOT4hZK+RpDR/upSqt+svYe7/ngPdMXXlUbdtIJjPY6T54e92U76 SG+sDhVkCp0qB2OmYhZphgfTWP/Opt2INVIxynwZow+I4x7BdGdB7Alb/GkxIcrqAvZ0cyPk b4os5Raet2Fc/4OXZmJYNNVq373pKUu71YfD6Ff6goh3q5TU71FFGi2IYIstV01G4O8ly2MD qN6SIndNp9ExRLqzs9y+zyqXbsXHS86msLK0luDzBxYAMstUukAl+Yld4ry9h8hv6VEaR1Ud 8A6v+knJ042M5Y1VZ2RwgGb0cMEcj/FUe66OoefB0pbJ6bcA6yFpIpqLLrpx8U8LIoX1hv3U 9JRwdniAlXjl36flkkgZ3BtfapTZHTqGAvpwxAMFxAXMICRNV+KGozU8YkHOpglhuV6Wu1yP 2NBOB2R38teyCo6fgiUdBq6B4Cym5GCm1bOTmiCSD2KUNVamDf2S/NhYt69Gf6uk602mqSMj dmTw2VY6aHMW35mdefU871/93nEbXNm6dWD7XR05ljAQBhqNpAssc2vTSbB9R05B+TrkY3qb 5Jrnv4q4NbzUV9Pbd/oLDJmYOwCECTS2VoprPpCsAheXRrc1F6z5qM1f6jHsrrEieq4FPGTe znBPSFKGJ/AYJGn2CKdW4okAQz8Sl5fT8RlqNiL6TUL+Fndk6ujFA215lA49ZAs1cPEgZVip oecqQnz8w33Dcr7z71Qf0uemRiP3VD3nK1VkdC+/MKYI0AW0pzOhEETSFQryqTd+KoEXRpIg AiV/h8tvflTwfjWov6tOKxtHeRFKZhPBaSi5KDDD8wSCtyfXxhmtxSRwtpem3TWUeE208aLR Def4He3VxbGmmceMx1DuEniCMvupB9k5Kq9nM3VH3ZRVFm922dbd4jiNAdJgyRLcq+HDOw5F HASNT4IH9NeoNEDsIZEPBLvilkDfE+dsdySkgbqKRqx1OfZJsb+r2L7IuG4jJCa210LC/+vs EAUVGwn31JP+EeVHr1inON6hllcODasiUdQFGlHIDNMZL/KFGVVaCBbTQjFpYkKakgDxE1Bx RVth7jvYTPGo8muZ10NHJFa1O/naiCboeFI/mvoYWAt3XVTCtaqPkpubxY5PPiVSy6ue4v0w qXhMzNzKyxXmOawp/Ajfz+g+q7eXqq9U6eghWeRxmZZzu1ADjqb1qiEM95ZM9gpIH2TLGLMk z9hUJp1CUTl0H3TQ3xyl5ssrpVGWrJNn7B/BhR3nJ6+AHGoXnJk2W6GaBfyhTuLYC9uCYzO6 07BJ4DPY+4voKlDkvLTKO3AOTIVHLZGDa/++lLMXujxJqoaNAYPn2DJMwhzCH6VXfsQvqStQ 53ap/eAvA8Hyb7oqHGpjVYqX99msqQGUgQkTunVm8Q5JSkOMe7v/m1ruitF46lHmJ6Ntl7nv 3M5DNdSite8NbRMsLYhBK2bKBVecgAF14uqpXiBt3FE7gkOaKY4/OAQzVlFQ/daOI+dInbHc IGfcyjaqEjjju+a3WND7kD+2O4BDtluNoNI7DLQI0w9ACnczSI6Nqgy/P57GX5A18ZUetzGO 6BRyAhoyNO6+i1V+gjFi0FxRD/WXaNb+PCOhUj0mzrcRLkNC/b0EZY0n0FiV6IzacHviMpV8 A/XuNMJQyfIp7ovVHZt/7VrnYwLWB2jFN3FtIajLYCFDpbwqnXkaBkdywYXLlKkY78Ovtkn4 Sy7+5lSq1zZ8H6y8rRjfM2Sll/xaU8VbXgVykhc4Kc3CWUggKKv2qJhxLFiS2Ebhk/3t9+EC cK7Le/vBlmS3BOuuYTP6ViEfxql6Llahmvts/P+ZbEo36gn9sLN23aqDlNTfB1bl3EU2sAgl XkuYRPil+LZSUiRFQ8a0gd0lTi/m+7YpB+RmoAiFwKH8ybCwHtJuAKAU4q206hfyVCjEO6ex ZKvN+yf41wBHvQ1KFasB9trs81rfNPi11p/sINu5uCzT733jK8qgrwHYGKcSLwpfN8oXbXmR 2nITdlaqWEvuqNOhzBy/Eitvait4JwwmHCq0HVtyE3FDpUpEpK+3worWU7cgiiY9u0JGjxRz K61OVaDJ1e2LStyTU99BISP3ekpE3x7f9boxk90+blXaaQ05luqO+8Aidu1LG6fy7pf843pd NlOk9ZqSpKSDsF4PUwaeU5aPIJPwxP/WbvFgsQqc63s3QRA2kK56cJF9fW5mFssCMlU9tgs5 Q+O/z7l5taqeY+J8CSjMOZjPK1cwjIqeD2+AjAaXWQjEHlZsjDEbkNJLPok257YYafy5dEld mp1MW1Km3Ea2f9NkFAq7hmob1HfcOH+Qn4uFRm94lvirL0154rHJhJYEWjeKPTlXWZg27WOx g05LOePwqbAzTg4K8aZZQG6+t8i1eHutFxtEbMApzChe4qz/tyI4pyaXYaW3Mu1X2DlD67Gl d2RnoP7M/ld4US5f42ItgdEX3RbxCMLR9a/e0e6qhXH2Y97ZZqZDFB4xLSG4qhMSe63FQkIA Wz5uvvGsbSBIf/8p7XlEV466thMnHdJR6G7oU0S6Og3nQphGYfuQcb561JZfA7scxEm6FGFG FO902p0+9YGg0068HE97WXgNViAprP8a2U80P5adNzXkYG0UbJNTS1taiCLAhHTChYLyC5B6 NcDIl8ioeIQNfgu01c+7lRhqwlr4LzWhAETu9GHDB03jUQm6HTbNYYYhjhwfkkWcgGW0MJU1 8utqSi1YL5I1hY0sfJ/bGevY+2Bgjr4eDliqkPwR/lflt92gq/A4GqTRZeB8VOnd6EmbeRx3 BH4CuUJamg0CJRBTwzSv+l3/YfS/qDK98elvcLK9a+rURKXsNHqqBGFOPUAmNEw9geX5HsxJ B6VxOTvv4sXCNQqsPJVogwwZEY1tVZWw1sXOytiJ6g1uzhRYjitKrvxIHf+OLn6DiqSt89sO 7g2nnZp6UH1VBHgntE88l1l1oayT6b2RnFxhqMm2/t1PQEOMxcvnzjcPZXmd2GP71go0mBWj eU39d2jptdQMyJ2LMaJ4XfVAyGgs7CxyFnmXNS3FQ+9oZyNfy1NfxL05Ys7hAMAfN01dZGZ0 oD2jiRWqibLETjG6xKnzsMw+f2OqoUaNRyDVqb099smuYHthcR0F7R6MjvbDqKODL3wzZ2Qk CT7TCZH4rcljcG1kaSDOouCO0ijscquelxG0b50blVoehLBK/t/2ptPE9PUMUHTEv8wgS06d Yhj6vL3MfT4OYtg6M+Pif2gcG/p+UcHusUn4yxhkVHe0oLvfgQ8PyPEf+3Tw3hYaBXE4anzj A08gYFiBEBAFAsZ/IukMfxLz4H2Z03bsyp9OrvsHYYEv4sgGFBYRgpY0VUDOixDQ/3YLoJCJ JINyLgMKaV7veRpMauHhviruZLK8ZgHAQmZdXLk2pUtpw4sQW/pzw4r16ggPCPoE23amJuHr IDk0dYsqB/T8FK+TMGyiVGn1wm2saujBVsGUn8H1uAZRupqAAHllkRkMMQyPpjqV6UBj7c/K X2GMzSJ0flxn7dDJa6/ISKnRCmlMM9QQuH/TlgkXjHwIUS5baZ16OBN4IvHZQxuSLffxKile bBnQLnaN+w9E2cB54NtZN2B6PwgazDVgj7lCiuDOlwo6lxwB+eL5ezDm2h3wZziRbkMBj8bO GIs1ZoOwJlnA2vf1tXjZZldcZlYA0ZU7TpsQ9kWDpMlKrXVfdE+wEddUt+l7KLJbX4apM1GA zhpNW8l1uRDJ0zuTYOAo48tCay94CQ5hwjr3o6zstnGgJVvWy7myXNtJRF+CaeSBR3uDsPPE IelswOIOqFYPG2w0Bnf3CjuItfzh/TuV1bK0ioTlbWE7H7obGl8PQtKniTa6FCTi7fVLakyH NY2mwJlGZ2KR8NhK+r2xL0Z9ESKXJCkjy+YZyQ/0fVRDEqRtkxJHPMs6icQPgCKztBfnHZOk o77GBmQPjxsshN8VzvYZGVCxIRyv0/N5hMBpv3zBHbl4DAzZ1XrbPib9Z8BJjsvffQ7daX+l CABKZa+sR1q+ZWiQWYZEZ+DZs5yUAgwLxGLKUT2qYpMSpokwktCDLo3GwWskCXhQ9rOjio3g rVheNgkkkvdo7dmZprTzjxPbgXBZ43XqC7UrzTfT25K5jNDY0Wys5+9logNvz6QzLS6wbPOG J4tYJSBrBB+UXljS8sD2d4F/SHw1ZzW5Bc8OLPuHFJ0R1Vv+Ax1E2khzcY48e3K07OxJ/Uoh a7JQVR5bZft2DlJuH6u+KU0TZh2MVVJZlt3DXGBxA+Wb0TW0sWV9Qf/w+LfWiB+AZF4lvtg6 7OxFYwx4vGJuuTedZVvDT6hyU3LtGOpNeCtf0yUOH7/wy6pJnzUuV7kzRBi7ZXI9ZZbmVxnd v1Je4nMPAfzZrYyEljAEREMh8IKx2xK61nqKai1jm2UOPW2LYAhmslrNST0s/S24Rs0553rk ZV386hW1oI322N4ZdLbIU9DCi7yo6Tmj8tqGLEzqmrUajFUCfQTe52dNuvjln8dHKsR6D7Cx O6VutgUS5ZmOkXHl4oFD+wuNPkNzoZJeyZQttSdgHvTkIgh9dG4UxMLyrW/9reVrBYYzWLDE hr7Ac6jMYGdA6vNSvDjq5cVi/wJWSoPHBCDhL2U0NjGQmMSzJ+VYQFD1+rfFYRxLaiIlT6s+ Gr+vZsW90qRJQ0aVERARgeWBRXb0mHbIutC+giHBlBUJSCsOLi379N58MO1Il3GKwBsleCaT dUk4if6oMeC8lZS5Eh1SJ3exMJRBUxg9phFvvERnRBaeQCn4qNLJYulXNhOdf0m/R5MXcJmy rpYsRdekuZozZgHbZQtvwWwrWbIujxDoyoEE3hvQdADlS+F1RP+8lYsffqSH7CXuTdZNt2hx ImF54+7vT1WbKS0AHZN1IEB7kbaQh5JmWZ+0UjfFF4Q0i4W78IqUCrIpwpN8UtNO9voYOmhS tJ5Ojw6Y5qhRBqAJUMJnFFD3FKCULD4uPlJa4Jc93fKdespTDefcaRq1OA1nFki7+0tUSULm nr8bA31MXOIVibLzfnGnatqx3r6fHeeduNrb2yGQ5yPQNuMx+HN84gqGqc9Y2qqjZ1tbDvdX jx+6WH8oRnygxazb93ZKbZgr4Tlc9GHMHxaWw0TtYUFHiLTaowRL5593urZTcMM6OA6OMnge eyulrPns+j8xHUr1UqstWl3+bFnbogPGRq83zPnnQ3W1UF1lMLdC1mzWaUKTr1Qp6+ntrtZH KXLcp9mnFFOyXH48aU/mPm2x3AXAQ7NB/YI7C0OWeaXmCzWj25/wYVrXo5XHLK400xto5VMM BHeiJfFbd88kAwCda4B1JPTFDS+jcx4rS833PA91pgkgY8I5Hz4GJbilYc2DuFMs2tUIA+qy Lo/rXmsEgMw36MVcJBeRwbXK6iLatZjsLk7WvByJUOOk/B5Uw2LLyFx54g7ZUqRGRvBFsSca yC4EE3xH4KiY2298P86iwm8aUedRR82Gfub3ZhJZ7AYL1FTzHEOAEtvFP4N6DIhOHUDmQgpo WPqh8QlTC5siQ9W+fH26FXHRgGcvxhwILfMFqN/U3No5CPehG2Wxu18su/VqrFKZQwHsqJkY 1Z57pn1VDQvZ4b0IdWZrq/igOqSbu3J1kuo0x2Mumojwzc6QS5pf4uNWkQ6yTgd0mr0MTAzP y5oby7kPjdaWFFWSFhMW6KPkBiPvk2hwjviMeEvhLPzND5F8prZ5N0bgIOZejUxCWnqNQbVU sLkRc/bmyPY04tlhR0LYCfVnPV1Dgtj8TtZnmgpbUSxXf5vTk03WyqifiAVrvOfv6QRros5y 3yrI6psn0UTtRd88KcFu2YEYGenTxs2uI47t6xM+nAH3gpG4dD/5EfEg1NeHfqqf3gOlWiPD pdCqW0oLg8790VIMwLGXGy/B81ihvqT/Ed3Q64orUoKmNlc2Pa97EnFrGzYtusZrKBfxkYJu RJhpKhs5LXRH8T61OOsrYaRYlewGnW5nUPYmIsXxizoWA6RLfAVH9jdPlkOLEOVByb8OJT2q OW99pO51GASJWNEpschUQuBkamNAUkm7vdu7+jOImLuVFV7rjzWE6IVdGgbcdvJZV+8AjrVN Z65h4JxuJRWL69nZUFx2xhoHCbGSHXt9g3V85glnBrNJz/GXBs1PEMynZgeThEz7kXJ9VpAv VSmbLorxLTVXPfi94n44WOL4brsTRLNPaJCY8dsRczmD785fNpsEwu+ng1EiZfHetyxfUnq6 Fw5rC/CERtOtvhWTlugwkQDhCbLuXqj+rVGRUTuB+8UMceCWUVDz7Mn7rebPwdh54uYN6K3r K6YoA2GUOTklyEgP/F3cGIi3jwHOcrBK2cHdrQBUR3uvLGOic0WAGQGlB5TNPYDMU5hr/8oH PFJC6mb8CjlcvwtmN2KwQ8xsfiU/aXccls0qdfiQkMbdUUbLDlxVvJJ3mc2hPhmlT4gAvNvJ q7Bz/kLTRiCkt7u3Zt2hMVNqL7g/aVxU+HPsR5lhplODqOx3Z82T8YLkN+Z+5MhQOWGUrVjg yZXwGQAZIqsfeA/XBIUByhU/x8bI6iWa8RsgJgPRf8fXLOKgB1pSfw869I0VWjMrFQVCr+si d9IDadTkvWKpkkNCHD8Uag3DTC+We4eBbkmhGMXe0dKVPP8dKlP/Uvoh1108i5hKj7w0X52I ESJpJFR6snRmwcFbW+s5T+5fWnf/n1BkOmo4/8athVWc4W8pii9vlntBFFYvofftaRYenrhy pr3vRaUcvvSiLkwwrdX2pAufL6rCDMaZl2Q/RiHIGAVhDjz9YAlanh+tSGUbUNqkvRmrGue0 +rk3I+BeL5ZZGSC664A4NnOO5P3pppwcu5OXxTVU6G8FAHdfpMcD8ACKzGSy/ycEqZvMg+30 E1HHI1rxYqt/PSkqL1qNrw32O/z/3FrcHsADRoy/GZkhwHyt03D7XFgVfRoXwm5dx5fYj/sm CXgeg9Qq5noLhW9gGrSrzCeDIaTqeD2SFEgvVCeWY8TSqXxomSe2wmP+ClD1SsUo/ph5InNm Q/om0IklT79Bhdy3pEdMoDkke6KTlaKXR0nOe9MUR6fOvGXUZoUw2b1W9oYhwqbiA/YNZIHo Zd0Y0qKDECGXs4nYiOn3K+UdfUdSwxmPXfLW1MLzILWkXq4y9V2T1eBlKMdYG/QgmNiUObLV lBPh20KF8A2j8lgc5836+vZts/DF4CMAXDAcFp4NwvjJkXgS6TMRUZFVqkG/ChKoq2f1w73+ Xg3nkD4Ks9p2tIE3W/scziwwpYil84teYAeoWzEUO0qh2Tufj/x5QVMgZ3b4GryuSIoCBtB6 GfPCmnfNKTW/IUwHOnvrTvsaV8bMXINz9yDrDGwZXWMBz1iruuV59RX2++wX96Bs7qlZU/d3 byYFHQweXfvzsXFihJ9OeZ1hdi1hsggiOUSD6iOp3zEWOAibKkYKKsaITP6qQwn1L3UhtUqF 921HxsPl2Fw8NafULadVVR0oc7n7YnZ25Aqi1QD+q41rgkAAqpeeyqaLyyLjy3/jWX066vDX MVTuFGGCJ6jPSMRYf2/dtMtLDh+5ld8x61i0s4KaWPsIYt51a7AK43/cbYwdTf7Xv29rEV6t POYZNyamEIHTe79NVe0xXu3jOqgZUpNJAXccuy9uTGrUDiHZHljc8MfZ5aKMAb10d8JKfW9C pA3JL/asKCXQ8LOFL1vLJrzvr5auzLjqyZpb8IqQHFhwYhAgmFjQkm6rWCK6JmcgLT7QcJYG AFzd/TyvOk5Mr2u4CFZOdQ41oZRgyz90bdgiOJJGNtTuQZcyHjdxhdj9FAUPv8dQ/pDt7ecN 1gZl0BONp587e27bZhqJ07pq5EIW8+tBb8WgDlDCAlV15FqXMOIR0xJ2qQJfLd+yaWiIlBhw B4DuriVueIaNnzeQ1sg5Li40g89WPna1/uGerbHdsax3384SG0Yajs+DK6USZt/LUK4TQof4 t7OzgLsYNgKbXGUFYovX5fdI58a6sR8R5EDZ0qMRqtJjnWAnPOt4RW7aQAM06cueTmyLhpIs 4shARE7RackiInBwaLh2NOw7xoZi+Y5XcHk19raQFtcilSrg4yrAkjKqDeiK815VNsoIeQUg 26CcYiZvfkwlF1UcGo647M0wOclJNt05XrH9kwJh0y+B0ZYpFgmY/EoNepflLOm6euqDvYaH 5JLBAVjswOTIen2nIAqSd1jja+b1ptVxCsImOUyJ3uJ+hzQViTaU9+okr+GTZ7KLr94Aok8q CXmGXppGL8R4gudZAPv0hl6N4GIRG1QyfCeoVelnCR0Kwf+7r9kH1foY2uX5iX/Xti9uKZpN zNnNGP0Nvtm1EZEc2Yaxh5lZfGHzOs5F/ZbYj/QKUeosRQ02q/7R0NQE12yyp1fdKQ0/NJ4n 0M0YJmZ8tN7tKY8mLdrAEVNkUb/ZAhx1EfEpKdjZg67kVRB01PGKHvz+JNI5RC9jVGfMaYM/ RaWA0hlXEksP8O4bg/PQT2evnzK4Mc5ToLnQZfYhnt9zbgjj+JJ43pJtyLGGjckd2dxFjj2l rRHQtEue8RPxYpnGOSKl1TW+icb7X2LMZj0WosIIa0kw+QQOAfAQxi8MsDfStaa0tdqcijdw EadBiqhcCwQxBt0/fJ+xbbjw49m0TmTYHwsl8emP+/OB8ABeTEOdhz31oDVst3Ov+OAcLysc Y964LM3B8i8Jz6OPF7wCeSB4+fcPokyeLbQqJNPoYwrepMZOhPc5HLDNv+PXE2lbRMSdENlf g4duNuKNUtQLb2gx3rjRHaLcw/52HTNrpOu3cxdieHlbJWAw0kV4lXWLDnSI3PtOC8r8XJpF 9D8/PjQO6SIkTPPpiKylZuMkeWlPtxJRvMVDo0oLWFqkJ9kkqRRhWXE7K7ppZTZ1mrQcFAwJ rrgKM3M3xyfp8R5k2i/O1kfKwj1I+ZlZiOcci75/BIzdyfJ/lUqrKvZoGTpAYb7WpQq1ku9e vKh7XkVXRuKKEjLFUOLO3STsiwzRLylFHrG9bN55xNZTh0mHqav04UKyMc/L1ADYmDvNVMnp POO91h/EdsYxwnkGhoCRnnGGF4tcev/3rp5Y0KDwrbdqraUyt6oYgWT9wyXszrzloHLSB75u FNkWCS+rBM5496zPGuhfjXCWRRon8MwWisMwJbTZ9m5ihFgva767mIbH1fE8/Gf5mLaOUetE sr7raA4+OEB5hctqyeUqn2aWbCj4MP/PiCCw4mwuVNQjGBd5G01FnW422FVdLXXOhkrqalhX xVYt3sCipZnnJUK0WaRylf4npOv0S0BptUfwHN4p64U8GkKO9E6yPB8MavjK+zZqauFmZCAb QKsyW+rZ7/sT1baA4yNCFMtFQK7PtP68WXgnLc8YdbcSF1Pio88VY3w7Trcdl/datEyn5T89 FPrYvn2v3mzG8D4TPliKuU8qiYf899cwEh20McptQQnr80i2cpIiMe8ghmkGGfABX/mjTY4H jqqQnK91w/dTup4b/as99cDvZsLt5Ia/dJwhFAMMbtjzqCosFm2hmvNcXQhW6nR/y9hk7WVx 9Q9nIpVTsXP3wsQs7IrJEWzoROEc2v6FynXhc3MvRlbnqoYp2S65/syox4QGEq4UTQABsQ6+ 3dizkGI5c9XrY7xpbNo0Q3edzE0Xh4iz5be1aCnyWM9B1pwSNVbSMhQhldP3s4XoQlQ/L9qb kFp8AgByJpnGCBHxL77lVHhtkRO8PmMQ0eULTce389rSKIThl5c1gjs0TqNOIl26e/dLY2FF E9BusR3u/E8XtQGQP7sjNFynXA/jR0PwRiKMHUWGzoh+BylX8CPzk5DxNb2Tzvugx/YyC8yw aYd91pDTilTmsHXVSB/xzxWuMLtzgbUEZfzmnC3Az7oPk0ZOmEmdvbf1O7gPaqXNBb329SHu PVmJ0DL2jjJx6ptrGKDuwhRCkh+mzbOnmrzba0bIcExhby1VF22PhsQ1OWMv4KirNcEGVxo0 v2JnOxHozvQEE3T/qdNPz6lDuePOIqjxWUxYx6ANa07psvMmpM+IM981g7NhjiCzFwVUtyNA T/M62YmzO3Vnq8Y4W0E6zYV902GfBSOSrXifiXXxD1IKVm5LqzCX4ehE/KRSfZnqnt1xhH/e 0kNFdi/zBsgUkiIe39+dnJa5zrEBpBMK6R1Q0crkz/l6MChs/XwAY6NX8ouj7YKlk8v6X9Yu bypO6s/TDqt3pO451EJYGT9wa0xLoeER/s/LXLEvfgolKjuDOYXw5QhXZWCt+e5Crwm9sce6 nA25Re2sFevUD9JDef92dxvMxrbI8MphYUZWC8COqWbsBS/Q5oWwqhaJMaT6WXqukNHtJTd8 w688G9KSk+WSrLn8/mK41dIPI3ZCBJsvPH/tBCQcvHpsaeU5IcVEKzPoITlz+IUBj3xuig/7 a4230SsygHsXUHhdNdYWFLEo8pTO9s3uxOb9LKWtfMG+FHeYT3jGjqiNleLLbRwgGggOPZif bSZprPhfRPAg3geqIvXl9N6EttPCydXO8mw5+8VwBUTJsRU/sWzY32+g+I4Okd/OxsjMsc7o jiigSoibwDqUCav1vaY8CL5ZhBKgnjI0Z7ynHm6McaXf8gu4YN7pc4dLKSu7bVOZbivFgXTN QJwRvsWYqXhfq76ZvRbo/xhAxonq4LriTCY6nxZJcuYlySlTA6SIpekZvQkRH4IWSfIkqWCO xS51IE2RH+fZwdoZ8MbKunr6ITGiaTZMzqNX4sfv1vfn0mLeLPFFdXI1nlp8K8RImOALrZMa dQQojWKDe45QKAvKtDFrVi33k2rYidocPRoXAb2OXBRr6NjUpIAsPwsAeLSJG83o6S6iPhPG RGeq39eKRHagnHmqcqCPQw3QAzJpjX2ZQQv0jtt2LWBYvJq7Yu2StVVMpDlTtWJEl7WAHkUP SsHzCRJP0D+B/QszoMYxAaTZoi8b5o/QkmIVcJGZQx4JwvfgDGWylGunzvi0TJCoN7JRdF+x z6L3BsrICUtPFXA2ztYX0iX3yQC7JWys/v2RIxgy9h4IzzzaXU3IWr8y1cnh+tdA2NwaY65Z ihy+pk8ojbN/+vBvePd0R46uofo6D7bdAGKdaqieo0Cv4pB69lXhnYym3FTX/P8IAQ2qCUhG 8deFxUO1P+BXRmYA4TJE5leGXlX00YXoeigSW7DefxD+X0nqHkYKUhrM12zvDpGctWJzYk8z gFFShS8DmlQub9hDjRKC+abKpAEzjXSk/diTVp79t0vGufKZa5p07JUMxl/uzu0kQe4vzbiP vxN2RT7BzVO1IlkpYvhQ+2lfGkxkW2sc/HLWoPRfavPW/IBGETRBQ/WPOTb6rZErsfRoPhQr BkDi49ziHXfbbGzlSv6CclQT+oTM3TIxNc7PVcj86fwUKl9cyq9LhfKnrkE/kQWLtjHbsrfT VByWuIfKckcbb4EKNX7bV7FgJPt8reNxR1urcV4AueKAaEgz/b96xYG9s+KkTKAJSmqIQBfe ZkjVHW3nv/ixRjYf+fLR9y5CiMUPY+bMOy8ip03meUN8B2h72SSnczU6Q2Sh5rUYAOI/88+r wMQ6Qba9vy6IFubJ22wmB/gnx0g3N7uvyxuwngH+56EUFjJbyUhQoAUgQYB42s9s7hUgE2dI QYPh9mzFxpYVgdSBTLJMFrGqqzP0TPRmjkycOKip7IH5yxVB89BvQJu1lopsHSZfMnfDkQUk JeELqkhfYpeao4cxLcoQy3rOn5pC/876onYJ3evzUvndt+kG1dS08GQVEnHZb77aOwnnIeBh 1Q+ISwsC1jAm3HqfuHN2RIZXo3ijy/8xX6jZYLVK6Nf59eaN1lwQwzOlXSNaCX7x196Y7VBR HBqGeuoktMSHXUSspEI5gKK+FooUvEv4rYiUt0pxrexkph7QexL7e+KkTUKoYMVChyOWAlFi owbXfnSuHz2QXLYrE9ATLrbiwk/+e7FbuMLV572Ru3UJjqDdEiNNQPyw/fm+YUotg9pIKB+S EShVtmL/pBf4XiQQ9/qlytFSuOMHpCrvetQWri25GXTX3VrDMVYY4+KhQhldX60MmRkfVZ6v kXnOLY6nDvXjUNsUP8UfqxENo22LCp5gyRsAsmmhzcsI1qWlkM4Don6U2EGxJCTsNw4C1tCv oc+90ad591mJLarTucATD4qhfHvY3SNF+Y0Q8+vjpCtxntgXO9FSoxO2rJjTxtUuY81Oar2A lWh+JBTJYsjNK3GdQxuOmRuZYWKfeGuk+aGQuzAkRCaqC/CkpaiFXSNuMe228NutvDWwsFn6 5oL/w7ozEinK4hSqJ11MBi/23yZCWhRinIUvoQ9OFHGUj1qtPmZSN0dONyYLN4ySyqlNbInW N3S4FbR7WscMZquf27zUIMk4948plYJLNvPw3PYbya7H5sNbxZYD/7urtmZbtDFCy+7m6hvM ZuYfuSqh9afb7XGym+yYDAHZnP3sQ+bdPLTQCt75r1uayk4JUvuWEoHuavl5uF+wx2Ap4TWT i36QYGxAmCGHSfKHqDOf3t7ras6EtIb62SMNgMqmVOqnaLuaHCiWqIJ/8gLlDbWYs7uf/srS Y+ci/uykKk3OTyIweJ1MkvPYhcthmh0AlPqNs3UpcaIpfCYlgmu/yUHOR2lokVj30p1e9s3g phUOOemnLMvjDAL0W+If4A8KXptD/CfSR0hrOQ0RA6mhVOsXQyJ+VErAwikELMnjhUMgRsHG IbALf2TJrFUbZ/AhWGt6CuMsWrqMIbcXFViO4cfSYyNmJYFlGyCvDrsn1PdW++GqJsl9Hxrv +NFaW+YhtORPISGzHNhv3jZRfpfCVvugRfebu+6BMREZySTI0fBMZk+IhrqtW5skdU/ZxOMJ f4r7SXTDPOax10qZ+uBfGuutpSY8LBgqG+NkgjrxRgUNbxhoMZkVHEFrU30rewHEGR8JkiE3 Itm/XJvljmdoIzeKUZjQxATDl7rJrxdsK8EQvRn4h+4JIWKKq9/wEuxPQoPMK52hdgGPDGut ySOU6mX222D1jk1taUtuA1ax1DomEs0hlJ9xXfAKfD+rD9fBj2yFAq9voAncFPk0E6NDOiqg z6GTPsTaz4djcphtN1IBRtgE/s1F5F47rOVUhxuNqrBX2q1A8GkO30WDQ0nZm355xWdNb49z hhR/YfwX+kPW9Bg8OtRJpC0ywSjR/W5vvpjh/hzPLg1IRPjZeWCKd99xQ4h+Rg82xoxjGUYD KuWrqiAFUmOUt89PWYvONKkER3N1qKwUHnsjrs89PKezl5TcXnLjWRNRQoqk9ReA1Fe/IXXJ DkfVn1jmraRDeCLdUQR6lzvNQWU22ES/eOTPVtKRhftBepN0aBCAEtnLXncae6TIbWIbDCZX LwfcySJJdi/qHbScLiYumkgJ9HbfSdVjrAee5+NnlnHzYau2nrMCchSQrWusElmfJLSaVFDv eaC73vofqVmdCnWXHKU+Y82EozB07qxFGw52UV00WcVpqmpFO4RWcB4h06pdPs8pbl3GsV2t J/XuNCBPfKc0kFO8/AUQSS4ztT+AxIBI6jj+SGzSshaVDgMIbd3tcDilenT2+0XhV4crkXWR ad22WlTKoNGFXa44SHvOlHuakM5pXH0RYmxgZ2NNVRZ9V1AGQeYndSjL/R8wLVP06iSn6o1E sqndvbedboZwEKC1G1Jn4y8hytItVz7QZh9JkNbhrht5wCDwannXHFxxIuttWQyCDcwDZvL2 ldPnfKXZPfnB0kQQCWZqucsiDYJFEQWmXVsYMonkdVmhC4t/Fb9bXvIhHKfjVFvmLCy9ua0Y i148yDWPsG16OkY/baBeHHrpwBDael9dMnkf2fVoRgaaEBnMArRCrE3Gq9Se5OB/yC1INUZI FxdYs8PPljlKRIaxmjS93OT1aCNyvk/UZ/L6gHvbOdF+HikNIHMQflMC2C6mkM68cfXSH8X+ jqIgAzqp7N7zftvfIE2Uah2vnSuMPV2CbayhwXj3MmKjjyHLY4XXXwEUkB8oaHsLk6QBCt62 kspQzYJ/LremUzRjBVHu+Qss35iM2Pomgxyt5dQb0k3KQvmtPfyCcJyufTtaaP5Qf+HGleaw DEojDeCATwucPnjcS6mYDSkzh5+/AbxgyHSkhlHHGozXjy2XC4Jkr3tlghvPJf/a6mV9WdIn KNQ1DaOPFS7axUOqVD/nxiqX7Wyn37e4/CfWku3WWzIdqNnxibDj/d9H75FALJOOSec+mU+6 2651L69z0sqfThuQldeStr8qFpTkmuGwiqYHGntw6qShNmhJ3mLm+2RLDdXiXODTu/ucdB/m N/DIjJX7cMR6+wfZWphWU5p0RhUopUNGy6w9bqOqjGm3L8UQxqKzWzh6hA6tYi+mGRmy252t UKwqJqAppXSj9KZ6H/8frSbrAQSCgbIEbw9NVi1oahvT7M9WcU1GMsWdyOaGipsNoFe2HEDz 1q3mMeQVkLi3Udog9G/APPMcvuBQDzAMWXxWmjY4JAMur4jPtjrvCew68L6DTQNy5KJ0LHT0 mXpqMI+e5uNZrrh8LVcvn+MRh8BgqrPk7AVDFJZHE/bKvTJm/bY+WkkzmEsRpDBof7uBCIZA q43b8wcEHF5jr8oMLM+AV/859KjIgzi26ZMKanwyxrKn+F/Y4pEXKKT3A91bGSal9wLc8WMI W4g6pEBdZxTB1Ocn5QzMRw5AQ6s5p2A3p4Zcmi6K3XhUCr8ugu6jNOL0I9rxG/HsUxuou0cS 4i8swDosS3TwqSxpqtDVfpqCk8n62eh4dE8r2JFmft1e/QqPI6sQmMg8ArqNAoolDvagMYo4 3CN2UrXHdZnLnROLYhegyKFE3g/q2oHj2U2l7GqqPVcTOwbsVdCenydy2kfCmRpIrTFNivDf hquXi9pTcjOjLqQnUMS29u5TCeiRgQbtKvR/MVSh/ombmG8FmsuWTGYmOEUxQnGBMVpKZcuO luozSC3ALUjfEtVE3wvSNoGMdQxAZiC0y1d71IRw9WB/kYAmpOKiRu+/lxCuzbvAApv+uhqp MfQbDBIL0vnp+Y1Run/n7/ArZRRA/LPuGYXXfmxsrOJUaDnBRM4JcI4J2f4PfiPOkmT1wPm9 vI5NPpjvh+jqDETf+IlrdcKIg2rK9+a+Evc33zvqCp1zEQW80BFWr+o8+v66BgaYvHGRx37v iO1Jys01jI2pCV3faYZtvscqPxBQ9PGy0IOBiKlfGEQJXNRogn/ujLUPP/iJxc7/B56vziYs +JSGatkruDTzBUvL8jHwtbl150VOJifG2lWgXQ29pHY+/0dgmPoAP8Wgg5B605JYi+fJLmi7 1YVZJFH5a/s4gqckWBl79mvgt6nwIHtdYhYptIRw+hxRGGS6l9C5J7viv7q0gYWaQA02/27h KEuTg7y6AK9psgJsyW3k+kkGBKSZBRqw3+G8csLVRrkh7UuL8+8iBXh92IvezVpw8DhAIwN6 2PhzpOQ4NKtjOTaU9gmMV7NGOSSePqpv3z3pnZUkL3D+qfobZgQfC3QyvmskPXVTJg8eHs10 DLKc+rsE0V4kxV9BcbbbO2zOjnR8ereJEUIDk6FyIeeb4P4pLa1AjOEbyYTB2oPSRWKTPVpf lp8Kg4/hZlc+YxVcsNgde8lfNgtpLcOxoN3vUlkHgIIlTlwKZ8aqV0I1YmJAHp8FHZn6dtXP uJZ932sa7sbFQJp9fcBTifvDx0fkiKu96ueiamymPZtVuizpxy74qcewnirWEePHyWaASf0e HJJcl5y02q3kCA56AGWrXNwid+cCi46LdDZH5f9J9Yug14GI5/WKgiud0YwcBEoLQG9XM3nv AaKFXHlZqKMcDMeBsg/7S87wxmMLXagu0evWT5BYXAoDc0348yFFQt5bNTuunJKTQv6Lmx+s i1GgQlyTa4nK5nRZNVM/d4gIQGd6hpTlocYOKKyQdQFsQNISk8+MJ09EvAIf80SzqiT67Jmm 0N/bbeMz9DmPu4TqS5AGtcLuAQqTYLVSwvPh7MxvqoyRFBS/ozWyhHjRZfGFXbRWQ98nnmRQ G+BHvO9B9ySBttkIj1RU11jv/oJ4i5O/4lcVUE45yR4ANjnHjXxVC119W3ddS5S35jLaGAlj K4JD0rElcMhJBuDoEbXrJrcpFOnCal2WUVa3BSyDnb9R3/WPZaoptUE14uvrJLWcdpIYzZfO cEEi/uBCHfBtYufnhg3EWV7eS6uEk/bseFjHn2P3rE9wNc6R7nO07HX1BECjgn8Gzp3BoCxu sFVRkDqRJzE45zhl/kiS2FE9MB13Q9i4+TWHTd2aqfrITeQOmFT0bsgDijTxcIaelz2envRB gN6MFa1Vn18URhJPxKx4vxlcjjzEplMEjUX4u/R5OCPxGHNTh/aeHxMG+qHcwnKwPOKPZXT8 reVgi/RzYx9vUKu0kZuqo4bWZS9t92xsieLqhWTaNBZ1xXHMQUDQGXPjR7qGdiWYFqcYyjv+ jK5rXnknC5ZShJ8G8+tvjkB/seLGyrBZJIbMM+lOj5WAkRcmIvEouJDBpEbKJkM475glKH9d 2P5pToXnwgs0bOP+dsb8xwmGJBHOMU4UVq6iU/amY3EhCPJm2YTvoUMBw5jbajf7Lhtn78at cxStJ8+Vmq4KIV9V26N40w1UyqoaC41vHW6niPNgdUrJA+2TUTkdce+FOcQLmn9+PF9N4Po9 aFPvpytxKcwYgMAsFgDus/rHpgPjPdFWRcng2tXuFL8vQ8AJBYgMc4nbtX03pWmcgsPEfyu9 Sa1Pb4B3uKLlUS+vC8AcgCsMtV4NcqTVWtVKl6P3e+6yl9qV9GVy61Mxk7EahZv9wdZNFxYa qQyEqMh402yXdsNt8m8gQcWm92PbSg8/LevOZ6ZlckWGcvGyCPtGpSVjnP95pHXQujNVD9N+ NzIzVhONoLriBXwRC6vnTPI6C1GRXN3Ro2VP3c7f40hGj6Vggmlre1nc1zhtJEmFs2gOOGVA NjOAn4rYVWNaWb6Wqo1lq6lhAODgF+Mxoy68I4RuBt73QMVk95vyH05nV8T/H0g3Z0u/TYvd CSXixcrmukpKNlE7TTI7SICINhdBHAcWwn9hP72n+VIADGxbKn72CtYcX0DnQ7oB61QzPdxP ahLdXSqKvoTVQlyCrpXMPCs4gofsqpqbFGzwXIOHOcNpg2li4jgT2NAvqceC9hFkKuCUYWmC dtdIcMkTkC9Ex3U6eiF7UAQ/ZkuHynjS4bgPcr9J8muJUF51BXtRugjZW7beczbLq+BaOP8r xR9KFtwM8yBTuQC6zqzfKZOP8+3t8L/gAFPMW08JHeW0zwShuWilymz9p3lGnnKJQAiJfyx+ Ih1DRRrVaqW/WFDWEO/5ieQN7OeXo9LZRJX+5W7jjhpuUqvYtooUxl1ZlAJJLzINVkXvpvmu yYtct2r0CaeyNB10WatX15rss7WtU+Ex1+5bJvjAGdHGo7AwrWbCwdlbEaqkoyUWlt6CHwL+ z/ERibhqQNVxZcPfKMoHlsBzgyspNOkcmFLCdkkPgbIhulekQc+97wrxhwHRrCBUbH1lWiwW no/RS324TmfqDksOuK7C53gIrPU5DLVZGYAqtL11B5TfBZx4TWjNzyqEsii1ajCVg0P/2T3o WqKdPH7p6NPM90tvy2XnFOeeyqsL1Da+eyhk+S8gsnsKHEixxwF5dTjHqppwwfdQd6T/QmRN UuN9iFiBnt/NsPgAF/arTFgGhawOkXRQquiSZj5KaPSK0r4Q+EeP2jE8ABg69u3Dr5hSJPan S3ZnvC1apve+3RteGJLrZ0GN4cZFMArqlYyRfswZD7G7yJi6FGzPZiJzQpnZNmsyHDIdHzTG cnXyDwuUGf0qxPiOecXZVxvtwc8icixCX/3vJv69ygSYT9IsGPHC/WkKFPercgUCSWgPuTI+ Tg0Uik4JqJIgPvSMa5hZmTVYFWJ90pExJw8JFVSaf++XJ+3jwO8Zkn8DCQtu5NY+6gNjAcnn EaZ1ncis4Tphb098i2sIJfqATXv3R+I+MpLDTqJoXTrQj/TDlCgnaoCJiAixTEr/PCeLjUwg dXFAUcU71zNryabJIPZ2jIZFmW+tAlaalt+yJGUZQmCn4bfYOJ4hpbWGm5K1QOWWCOigBXaD ztqjgvPErfH77gQwk0BKFB/lfQ2qPmkc+89T/LIZ2kjddZ/9euukMQiDsDTn1uTEO+GFOR46 fQcUkCj1m1iKFAYiDRodRp4Co2fqbZH5pjGbnH5zxqLLMVPWLb4DxsA1SlgHRyn0cvy/0KQJ I2QXg7c9+giHj4Bb7mx/Sl+8abGSuPR+4a9HYwfdQszx5ZLLISjZnKA9Gg3FR6BvIBqNoCzG 0jb0AedB3Nnk1kG2/9qdxd+ZVb4oCmXdPaEXnLdB7YMjPeu0nZ1JvBvRiul20QSjvLpOyCsZ VAsMOjurvqhx+KrZYLxhbGhB91Yyn83t+8YjyJbtdjObhAXJ7z00b06fa72JfkxN5OQ0xtyF rIrR9IdFhoYL0FAJHCtBy2206AFujgL5B4FLSeL7K3709rORvRcfQlixViDNfGyBEkknfQ/T ch92sBM4gEeplVeQrnRf2vY+k4jet7ls7rhqDxuQN305xy8ht3tjUG2X53szirQzVPkbRAeR JQiJU8BgzU0wG9Aii8SLRiW2tz1+kGPvtVKgceR69AEHhsPJVqeEB+7BTWfgMIlJo+lVBgoS sosE1pP669HLjQcHqw8dl/ly94s7qtQEbV0AdYETsvq12JvPfHPN2Idm63SPrjzOuG0XZwyx E1/9W4+Ava44TFpc3ylO+qDGryzv6MTcANPAA3szGqFOYrO+kzIrIIT+D+3Nxp/k8yiiK+Q9 yFqPHhnDoo5rpXYTT94m/km2RmD8GIQPPdN5Inx4BUyCu2bfENbRcAr7r9SB9DVApJmS/1cr vcXC4sOAQPTXGkkKF9mPcmGiMHavqQ3wHhN87c8TZ5bvoFIDsQFs0t3kiQbCD60YkzJjrwCh 92tSHg8Df32y4rWIP3ZEQgTi4/SLilUKMrXdAufvBXQREME9vgz+9SpiYc5b52CX+ORFIylh /i77gviKt9Jqa3svh8tKNIFv5EMtqDc5HuFUSCPGizc2o98Nfw1hV+QzjiQfu/XXJ2s3HMN4 JNatW+Cjxtm1NcUH2xQkjMhhY3mno4FvJQrTQPj4R9PUN0vgh9qQolu1Pv0/0WKJpUfFFypu IpsHc7G7NPNwJqe7pf3hfB0RVFTcwEmwzzc4a+BRYlXwGR5AeDmnDUx6BSKjGv1tqSzYgKh+ YBlVAx4O918YDJZjBcFcLJgs3ArQi4PfBCkcwf3bmuLWO3YsWfDaOjXDfcJipHDcTmfSyhO0 Se4YNDi4hyGI6CQ5mKvWSLy9z/rvPtln460E1vBxzhxUjhBa9QI+zAB5q2aNTfGjpmM/sTE6 sUhDDUynkHly/QKYCqFWAbcwG1v4rLbOItpnos01w4M0mdgQsqJHHgkomMEKjVSUQUeFgc6g OV2+Qvu8EzuzHMvSmatdykbkkupXyoxH0/YRBeN8g5v7x8REmZnxzLfsHF6lJN6rMdSc548A 1V1aqo5Tg3uyl6+KbrjzAhHe7GXLxk9dWOXehKV7W+jV/pTcAt9jTJZD9fJ9N9YZ+8Hwomkj FoxF+0FjjUuv1M4MbgdzVB2iy8dUJ9lW74YkZCCkhIo/LfLgrddk7t9kiVS4uWVus6kv4IdG D1vQmQSwavsEJm5aP9IUxd7P7bbTzsfH0u1iH3aRa7iyCzMRZNot/PTStEaZDjXjuktgxKG3 9STe6ev36K0jwjd2gehYQqqGY4fPyyjQuul7rkwQSl6WVRrNTX/1dqesMyHk7QskRAwdOaI1 2qPDqLhGcvKsFoYCs746F6C1Pds1SDh+X/c5bVBHZBQYqqjWz/Ld3O39SG/O+7Kno2prVorn KgTE7A03q0PA4V30l8HvBJyTilPblr5sozAdj5RHnjjz52UymXGBr29obUXJj+EWEngRESrW 3n7bQd7KlhF9yKCRlkhJBiU9GTigSXO44L9F1eUP4hHK9TNwoeIJz5REDQOtX5+utqlYqoKI 4vtfPzAtqJhdoUkKvNSZwYGOLHau5vc4gzXlekqZJDLEOSkl9Kra1ocBcttf2RvkVNP3ZqpZ +05F6SULWYIbQWgk2GbeGDwy/y2i5EbNB2IKrcjwOnUUNGffxTI1PWUCqwlTvhysQjQ/hAS5 CXeDUNbxO0Pm0Xz4nTTgFKJ530vl9af9HmXa4hHiLquQH8aO3sT5YKfxP6RceOHn69BHSVQI jnTplUeWxn3uQgBPHHupTIB8TLMoFv2NWnufdMkAdfsfwVtyOqivhxWapIxFXjDW+F6+HMOB NCi28pmU29vSQOF4cMDDSZSPX4D6Jz0Sgx49dTWkSW2eUvdvvdhmVFNOyLj1jw3bvsegZGdP oQ0PAXlBgHpnAO6W0llMjpjpKkUJeAuamDqg1TlEFzXavC+/8A4g5jrcUzjB5sbDBVx6EegH M7liPd3jWHa80GytLzpUlz0/vHNmRl4iZzycZbVL/bBFFrhXPsBHl7P8aITtraKxGgt7mqbe 81ei6rZBc75Q5nn0bVPWthmZQ5J1vikz/sybBjoZG14trr+XrjSjJxzx8Tkm4wANFZUqUqMq hKyxcjRYtAHmEImri07feTZlYi59rF+YgBud2tV3zbXWwz0m4PazDv5pNPhEPaSWpCsc1nD0 EqlpKBkgQdzh1tVj8XnIiT+0WucSv4u4BiO73rG/u0XYDl7sQVB+9XaCP+rg0CQzDUdhN7oX siqB+XAVavK1ZTLUmdK3TyTzPo2HVf2dEZYXXoUpFOIK1v3GvcjyA2wuMUV37OdU+RZWnDfq rG0/1g9+zj2IXwq19zU3vbhahYxTSMULB+qnGMcZtIiXphae2XNpH2UBea3g3tu4Rs/GaR+B qB0W43YS13FUI3sfcMeeGjB1CUKwLGwS8Ql/w3P230akXqLTnStn+Gxxak4emAT+emeHuAP9 P8pF3Nr7RCj6gzGwx4xzSqVVefeo7+TfKvctGuiAZSG8QhCgCCwsd0LSKuIxJcdzd6Ucmf84 snjor0aO2hUr9ejxRSFLQOmeU1PowbyV9O1ByZXTsmAuLPRRqW9rsgpRSyGbe7Z2ttI+VgiS 75HSPBrRtJXsbnjWFuUZhNld4qc5g5hLPeez4iXgP0YjhXQcEekwyeWmIrnv6Ou+z09D3lPX hVT4gSelyP5dmIYMmnylY9Evbn1YteBCvV3+CspSDATAx3bJaN7Izw6r96dGz2kEiJnFEJNU zOqFyUhxCYTk19/stNRgPT4hRZvXuZdeyxfYYdiVUnkxQ+KVITujVBXfsqkB6QzW+Najmmbe wEjsnq112vG8b9TrPsEoSTxcpSs9gCzZqRGxFEMC96k0oH9gdKPnu0zLfZTZRHl3mgWc7Bv9 LfkMVueFGlHw6GgqbYjdKAkei0toGrCP6s6O/c2LqYnD8gYDkVjvTbGTRKHRYPTnnyZezg4m BXNot9OIdF8WijTVsdQ1zvfGC5XSmbyuJWwHzC87Zf46rn/8C99sIme/Ej98a42LMC12GK5M jZtkOFGHOD13H2vPPF8BuEPwJhfHxnkyaRa3bCZeurpKJpGAyNc7hDvjI2UD3FTzpZ8OGnmV yjH4EC9WqTL772GzCOuYkAVHnIKo2V3wupNWwP5TjFCfzsk/FQtjG7kjAx2gNGl1s2uF7PBX o1WbG3Eod3knaP3NEkgfAHV/Il7T77f51mFGYZ0xp6YjBEGXUJfA6UIw5hxr50LhCGfPakli 9S5bDFmNdtyDtomb5hOB2PzVRHfDBP/dvSDZtv7hwFP8jW/PRO/mvJVyc3nx8PURzm2J9LRc Z3WeZHikA+dXaoznWNLSBStRsv2IeSzwAN/1+TQ7j/Lx3y0P5Jh0e+7K2NEHlc+SvpW58+Ga 8Nj7N5bndh9z7MW1foLGZaI4Aoxt6NKd8VsmRgjPi4mVSbOlaGngENEVNlg5V9SbR2u59Lm3 cPky/Eg61YvRyVRrIk61+0LWl9DHNHAOeBbXlhjfpxjxMQuc+DmssFDQ4ggIArlfl3qGz48i zfIQLNPbMzP+2oUERlyAVB/RKW8oI+Orp8WHyf3IDqedbO9pDJBWcS4oEi4tySeXgJPgtPk2 J6Acx+wo1SDuXvZzgUC1fR58P5St8aLQuJaQoJqw4rmk51zyr1cuv2vcq5KHuaoUUtaFiyEv AzoKBDev+bQL0f/rg0E4Pgt2cvq6lA1hrw+nXj/Ffq7W6wJs8M7VkLIXnxpkDo2ZOGiaXgLc cO1Dwd/b35MQgTr0ivUynaA4mov5wrkZ1NSs6ixQxiU0ABUVrZk1jadEfVQBOMefJMitdWEH xggVCNbOleAnry1lzCxfSlf7HrOm4NTWs91XqOVswcneNGttjtHR2aY5n6u4ndLXc/hDs/qy otaaofthtPpDYQtXLcShRyi9+r+4ghp65QxtujS7HwTcVZDBknCJn/GdsEQqlpHEAPhGXuJo Z80KRanWVq1hRbHtf4dpR+3hQOBSt+c8IFHJp8oanlMK+onG21jcHR1zrICgdYQnQfECSeps xreng1MuXhrVb5x3t8IrNmR7LX0InYgZjFHwLz3/CDX4XLYkt+T2eTr02yvXNoLyYiJ8kIyg y7rx/Rha0BplnBlqEt/7zCDGqmdZHjnVLILV/mjF6AhCxFkZ9yFeeogMAvdbWuk8r1vr3rZd pQGACg5NRCBwUTukqdUDc51c+5P2ztd130PMfeNZssKwU27MYZsM14xZlVfgV63Zl71lFvM8 OTaUD2Ytl8RHX4FY/dCYZPaEhW2/gQD6VgAr5awSp0KegrJZsP4HYJj8WAQGMft8qxI9u7V6 bDV0E5Fysylvkg9gjjNZ4gFmfcb7wm4BfGh6NTC25Asd105aexNOEEsK50EN0RQzMlhlPYyq TGUWR+WptOnNGNwNbdTQ2ir89tFRrnaoqtrFOAi9ncmXAb2/p9v7ilrttBevdU81NGI1Mxtw WYiQcq/e/9eognDsJWc8kpBIG//73gNOoV5bgo16tqo/RaejLc1tPFTSR/ZPjsrmiyhoeU6m BQYvK9i9Pn6GQOAZK5Qxv+p5Vyj5H7bnDO2PuihQ7buVkwT3jx5b5h31YkIOeNfvOEC+4tGU 4f5lC3XqoWJsVroGiA353oIj6Ob9qyN805kLkjakcz6BAl3ojjsFrz+MhKAI69fNqTUI+3ZU /3BpzWj5GhdC38V2wx5VsYwu/6efrBlFdvFJM5BC3VH4XOCpFhdQjY1fHo5wKCeiepg/E47i BpN1WW+XmyHtRXVAFxfUbA93wjiYpEdBUEMTvCl5hBFyH+UmDC4rNqa5JJEioCsecui5kGtm iIKW3CXR7YBRAQrq1ropGRteh6SVBdhEDwunJ+RPsx2cd8WDgJOe2EqyIoO/b7sktYHi9bg6 mBf3nunW5SipsgwufZu0TAy6PvuttZB5en/joxqroy4fs2k5YwSAgXedu1xAHDQTdY5E0EY2 qyG8YdGTfzJvmCHFZ5Q56x46+ZhhW5rkvrk7TGxoZFnJznrGNH6mtZ5S+6uEq9zmGuYg+P04 sjMLFCu2UnqEiQR27jMjFZWxLAJynVACOUJr/+LMTBFDnCt9nKbmQr1bNCXJ/T56+HVf2YEH TFUIp8f8CByjjj8YZw+99q5Dj1ZFkJiqZYLswvzBhYdvFnCwTT5+iSjm/kfP2I2mCgrfUAd9 bWImxykL6eojXujdnIMr7ThGl2PBrlETnsrVFizLjRa5HBBUyQoieEk9J9LbFHCHE7Jh59jS 0UHQVW1kj4MnrGvPkAa9ennw3eSJZJD+ZrjXTpInS9+ExEGSaujB8UCLes3mUfkCEWl7XDLE htPlM4/ocePHWFOysvY4ATqVZHKuQttu92/Eue7jlX864kAFhWgKiKA/0WVjja+yQVKQJO+p OEFmONUq9SK3pPlW9if7yzw4HFH85g59/3Jo6/CdZADZRHQTtRX48VgOawhipT+xwNSabojM XlaNOhMbYGyVp/s2y9MsuvBqiMIBPdf2BD372EWVPxlIwaamiQEYfefosJSO5L6G2hvJ4LJp j6PKUsreVbDRNvav1r9v3ik1pbsS/V9vu96YvoOuySDTSOxBVa9LIOPYtBYhKDzbJwuL54gB HIwHv5MWPXgExUDco9cwzHDEzOIOIssfyLgeiqXsOS1nq4UfPexpXNkoFhs2DcvdjtBuFw9M OyIiXo3UTv9LwwZJAfTBrhy/ULpdhGlOpcdc8ncohyy3x2okLukzdY6jDVvuhf+LMK53I1a/ 82UvLitAF0gebemjqyttrOJuSFUsUibM74jJvyWTlZih7aBxxL+kRKWHh20JjeIAvk0ApOTk sRrTTDlnMUlGRLorQkMmB8MQWBSjU8aRH1E/Nk0cQfr+SITKkVUPMi9470CAdbj/9YGaaefq bqQezVt+h5NbqqNWz4VpCaLxI5X/lx7YoqqceeDOUTaHOK6zLU88on/qIPMMYCymSN+//Q1o yLyyM3INB3P807TeYyzcpWbE6MlVPZQiHLfew2MmA8lhMVw33Cev/b4hNm4ug6nrIgaFNLfJ TIP6QvxHrxK177JRz6XbZbHmqUjBbyGN6vOt/QHhaKe8MNcH/GHacVlQuZs77K5tVdSnN/IN kdt1j4YB4+Czodpc+WKEobcpsmU7zeLjdgd32K7nJDykwdEyFs7pP13B3jpH15htKst1Gi4q sg9Kax42fV/eFQEs57M2WhB+BzUcRUn/aRBSF4uaF2Gp+MhlNPSTAzCTAAuhu0AmIKufhB+l lYuiqsssZCP1ycoYNzxlJl1XRtP/nyVB0Ka1hn89CwalXwxsqe+OIyWoYNJXk7tyBq5fgxAd hVnwoY1FDH++BOnhwmFSb/QPOAmZWe/8VbCcCSa4AwWw7cDakNiaMjQfrxEwa566/upuGned pk/uJoDwxLdRsxJdgZSuhB6Xg1GqJewXGzvIKgW+iS9It910mKsDqgohzmmnREZF7tpEuIjq DxYISnWNkDudkQ/asmi4LdUfo5W+jmsvQOn4k5NJb8QOBpACpSZFYyFiImjsNPeanouNZlaA 6H/PdcKpVmovazNLyXVdORY3CFSawEX5u0BawpAwjGa6hzUViSVw4YM5fVyyXcm1bD9yleUR CYPTOsKy8luRsjed50+TTjtxw1c5ivOOeDfJlg0mkZpAISDkuZRD4Bs6J3tdkCvY8v48811M 7q13aUPDda8S5CKpnsrOOgx+s1doqmnAebVLFCreUOGstsV6pXZ30dn7FES7GqvRcVXAxfHy z0ud+T7l4OX9KljTSJzoS2VxjZhyU4NkoXcZqAFTWl+eyqKBfg7oV8Ev8E7EgvaSEjqLdkjm vM2BQPrghZeMLm2n2W7V7zWQ0HS8IzOwSkQy4O81eUQbNku16e/cvJvHpCGc1PtsBmdzbK+3 hOkpeRLxlRjZ2owTajiUJ2spwynSEeNUYmvqYu5a2s5ez66IX0SasRpCir94s4M/NX9FGlNE ZXHVEV2M7PdgfAfBgxZO43kTqdIeNjmVIAsy/knp6dQIdDbZ5aDbiK3Xq0nuGYTO/Ee49XnC WNUIRQ0eCfRIGpX8Vfyt/rnklnsEvQxc5OJHkFJSt3kTy4G1QdGxBK3nfMz8/pBudy3Fb9WB gHPQy1wIfiWpIZ+2ktM4zvhXxg5S2eXfovQsCVlcHO7wEBrTrDE74YFyD2rrgQp44zhgCwHa 2ovJUgjil/oOZRz6oZCp+frfpI4agrMoqggU6FMpvGikSI30RslXQFpPiJ2G7lMXXq44B7rh uU27Y9u/b7KHVfTKStDdUXeZsqEqVAn1Zx+x6c17OTcSDGDy5EfxEn8m8Gh8lb2sczJ7e/5u bwGbOFhBOyUAECfrbGkOORzKxOepN9EV6shR7fuT35y7AVqEiLmr8Gykm1fYrWSvvaNEip9z j04YUzHmM8DIcP/5wuIcPC1AjKL267BDAkQRteRYUpq4/mkRtAU+LUDaXCOSSNWRlSxw0sWo jfWtTmQmKYZ8UITZWkxAReQfRzBnpgB8+h+jlPUg38Ld53Xs0B3Oo/GfElZlrcvilEjaNNa5 s48vmK//V480JI/rh9SY1449BQ8iJEsZRD6/1fVRdVbC0bxNlf2HtPDsuHRBpthy5WemIfkP IqjSP1XFwRVhlP+Egzee9uDWM7vZuUwVkAB9F+8maGcLU1XyCGEpOnCq7mGZsD5XCE33CI2X DYuucvHq2kU5AZX5AFvR7LKmRvarcG44eDrkxNCVqHHLIvGrjhDzgh9TBkCTFDgBy4ErrOFo 2mY2953B8WMZ7h4uyLBTJaqQoZXwC+sFVgAT+2juSfI1UZ0J+xX/Kmia2FlVTDLe5hGgnJZ3 rRqCoSGOPt9E0jOOLEk1dwyFu3aDv0n0oJgzAytCi7O2SkalpQhmv3GBppfPZ4GavI+5WLrL oImivjU2efdGMBOlh57FSeD9y84P86UU0K3jcX5kfH+q9846CiKtFYSuev8NBIRSc25gyFBW s88yyNoziE7PTm1t7u1kYt0O7O/AaVnPrQzHumu2y7rBHqYN+wZtgvkiBJeA4rVsqqOiRdIF 2C9ih1JslOKFoteAojyZTLthV1GsJnPrazkpjYpY2f4Mkxx8VeOR/MRcEH07p+EieZB05ms0 JmWcj32U3awyvgv9yBuqTyPaFhRtEukvmlfQOSTvUShj2oQHvyIADbswUFsPGf+ZROhDvcuc Zzw5zaoDgotrOeGT60VwRDRLXX03VZQynSV2xoKsJsf93VsWRa4Ewf9Wj6dka79HP86GvL1e Lv/Emfj+etpdDnUAH0rkfxodXJk+gaWuuXmrUhHHNBlUCFh/jzJZIDFEKFJrHpetFl0jgdC3 BJQSImC3VrlNbG4IcHK1AC5dWhjHvEGzrfoMpEtwkg69uD3RoPl91CZ7Re3t8+SgLvwkqX/w dAS36y/yR9STG2mrBCtKmeCrVpyVFn3wU3yustIYGqS+CfWy/LtQFwficRGlR60wGV7ScZMT Y4AnG6fxR6WV3HKy0lGUJ1a06yP90pRLFLDSPPt+ZwWzh+jk2q9PK6DN9/2IMhMOo2A9BU5m dx9pXqTqePSScPK7U3rJP3tCCJQgAZM7Nv1Tck5KUxze60/JCj0dPgPk9rG9cIEPmxQUpp7b ufw629vxeV4cEntYr0VHNAXggEpSCQJop2hoVYOfFy1Wx0MPo3IoSWPAfbcc5MVLtbIRfNpA fpERdZAuZ9VcZXNYsVPpwPA+1EiJeUBaDf3WDEUa/WDfVlFh3kB8d1cijIHUHs0lUagaaQqr RwIM9HIjf45VZr7oA52SUdE6BlXAZwIs3NJF3RFfOW3xLzU24LZBGiXYg6hCsaN4TO68praR UBw4QraKGnwI8C0NnGISd2zs8P4ELkeVQqNeBnQVGQW7axDIya6C6N80WHQWJlMp47WOkVeX uyg75lIEPMIHh3ajNYhXEgziCAqkSuKLJGlhGJCEvA9TEZge1zFkmax0vq9V3OMEsYa6Ubsu Ba9xAxygEHkdkaY74AheQlUnCXaz72fIvrIoDl/TiDvmaDwgS/IuhSkeTSokAOLad4hH/OHZ vh2moIopmNMe0dCE7YyANOt6RouCTPH06kmDGQqRclj4Sf5UQREJYoksAx7wxWKToKN+JV6f Qtv+5O7WIW8HGp7BCd2rDzOSOY1V9OgBQ2G2Ce00XFRJ38yiSEnw4qxwHFW3icX6mWTUQx0o GcB6kXhcecOIZneyHx0rBKzT0MZLdggFXdPsJ5PG4MWUTxQMjL20UcgHEvXcAnsAKECg1AlH GlBCT/YtE/3r1QJlP591z9QlOk3oxhfTz9Jh0oPx78jtR7r5ElUbXZWcl7kda5GJqzHeVygl hjUDByMA/9IJz3BwQZRnPcriO00at1jnvCaQa2u9v+HKNuFXcSbNyWD8DtvbzSgHefej8QL6 i3S+qI4Uhtemzcg2a9UR8NbuZ/LVTBAW3R1AeYRCIGYjNVOfUS0QWT7g/Iv8vOOuwUG4Sq/i plJODDuX2w5o59397fKHPb73EM1j9aAaaOp8+bXRz8Qf/EgV2dxu75q4Pj0jWnwVU3WLUxXF yiDMYIijGO5XkhrZXwlCl1ASI3FtpiVqQnXjlkmD0nzprGqTrm5iPqew9f11ILF3pNfrp3b+ /GSPT8dhUifqi+f86X6enzzuXoT051/8NiCzhrYkzrgJsvY8pq9f/4qg0IAeFD0OS8tLwJUa QZ9F/UNaCHEiA6AlBHESCLx45xGvPP2oSNagQ4NHmKxzICfv2KBCJvgST81rS1534CyE5fCQ yFSvDcvz89VtJXhon0JvCeDYKc3LuDOmXKC+z7+5D88Jldgr3gS0n4+fuQuKFcaTkuMTBfHI pm/QCIaMG9LFFo2c/bWcoSRQfiOh51wJf32nmyLvxHldxpbcWC1IjxwgGkfkKzgwaYFSx5b7 a5OOLQ+JxdWmMITx94CepNz+ZHDdYT6zcmKs7br2T16TQy6w6RWLWZNHdHX2jQS+aqhCyE5w j1uqoFyGRZ8wbisH7L4CI5Oq4QJLpLidyoC+uKKPU6f48/MbRdswrN7Xe308mpw8MT//B6cZ YIiovJRhkpnV2UGWWuDfvzVPXLHhrnEqdRz4nHPJgZTggKa+kUBUS5n2WaxGhVV2y3tenNE1 MyFFlHgiLbQS8SJCZ3C1+LrKqhVTRHdh3SOunhGm2DQNDFKBjJhpJ5y+5P6GotaRIsyncZUo VrxV5tO7d0j+Z0pwp7S48bdWwIeQbsWp4a5YKwyYaZYmSe8A7CIZ8Cfn2mTwIA8RXS6AwTIf d4Lx4rqLcVYCmxzGieIa5h4/pb7SPO3mODR00NS6STWH36KDudUK4LLUEHku5aJHzgbgIiWv OmbMkmkGNq5EL1W56klIRenC4xyGiyXinC6zpZt4Wmznfl+Xtfp7JGcj0iIk1L/jV1Or6QGq l4OorpDk/cVXob7wpJtXwo8/NpuHsB0fT6TmRxLV+zpoveij5sv1pjDRkOVNx6YGcOMZNLL7 RB/Sulq8u60xuNdNs+LCCaP0sQemIEv+LgbeR+MoSGq6ZmttdUXdziab/bN0G6Ps5ksCMzrn pqWU4eLlnqsn9xIudq2b9wB4EPSiaZfVuPOewKQthAMrvvF0yQNpaEwiRJGKSaOBUhgcA7ar KqklZ0YaFCqYXjXkB3GSisAjPeiVNrneU6phVQrdRtssc8Czyeiqk4gtNUCXBp9TfzHB9uaV RsJo6WspzuOfP7qL0ShXv7ZW0hV1Nh8t3KynARq/MaKSx3nK+dOW3hCuYpLpwTomxIgZkYtT T3rBLnNufqi0K0rodumrJCOoVk7Hdy36KvTZ/3+/4XcTsGsgkFZoMzBiZomFmWfqg2nuHmhJ A5kpKnbNAcjLsj/5WClCP+OMnv6ZU81fnQCY5k3LXagv3Q2mMsti+OETjTnrNRDfArzZS8ZJ aqE85IXFhv4lDVDLTCYaLXLT/WKxYcKoxkvEIK0RnKX2leRrjJzZ4+PFORQJ1uzu0EiDEkjq K6ZdH1UUBJvkpWFC7ItGOHGZzVBbwA/nSymeGL9Z+sZ2D1llQLfT9bRwurGIdKcwLFMvuQdi gsOJ28+RC1S3VWBGRyyoM16SBSvUeGyexOmZtgEuLjUkrKKOGoQ3S1LmYhwoiK7HB5yJl0s4 LlsEu8H5piHsTg3tpwl5lOwQvXE2qZSxY9Yf1fThW7WByvjH7KWK2+ahNvdpZVU+Hfgp0cW9 HcrBl8VYaWgE2Q6QfcYx/nCEqMEV1XMXniMpYoZR064EFOrEatjKGUVwvjy9VQHjlMCtPt0D eqxdQdVW43eSdfb+Bwbqs4g6ee3/nby1vM+QJJLkn1u5tH5QIurCcfsAVoqCa8I8LR49DZsk 4GZiqoAPxTYbVHeucGETf60l4NhfvgYphlHk5A4kyTRafNNBm/wc6JORtaLesICI05EZt56h DO+YVXqVFfPYQmm2HsrhSVIbCJoyyOkb8srymvvDNSorh2HD4BpsKczSWEVtRXWBB7r1+WeH T45pCKUZu/I3otrb9eQwmdyyEg0h5YwPToVZfbggcDrabYywceHmITrG7aB1yHB2WtD/J77z Set+gUCG5bR1/SSAWZYtDhmgj0vHSiHC0xl7M1Cse69RXWk63iSjEEgfcLzAhBxi+UlyOkWX B8olmVmtX3I/aAyQcbdnhcJvs85+5Fu+tSozF88I1nnxJh8vziw6TWb8WWNUhODoPNz8gYva vXwtJyfcYZgWXDi9edB+ZsK+Vnc6Uq4gl6IPRjuETtGHERDJBVYOLI4sBpuQ12XnW7Dd484a dqkzGv9whQ5Ie8sKrpxwTan7OS9mvJJI8TwlnTYcQAD7s/IAmCHH6yKvkSHwpFGfaq8zypxd n/VzzH3idfEChue8qxr6KuxPVqMtxQKY6FeN2n4EbZ0ym9+petwQMknj1TkuWsZd0T/zf4sC r4JJ+YVHM1jGuCKqyON3juRjMIRa6Xg2hWFEG30qFq6PttCx0KYYxfpYwzo0ywMwOMehwFqt AiUc70ByC79zzQW1NKCnS2ZRnbVMRYgJUNx+WU3mpyhNw9GPVAy9o7RVgWnTFJrxvTW5y7QI rH9FeUms6KptUcijjTmbcsH98SdMAE4vu2KhegDnZjp40Kb5RoRcqo1ZOC+X1kOWSL4eJm39 MA4IIvr+gEsUILi2VpVyAIJmwinGqm0Wju6iDT/nMqPPlikyidMGETpHIlGOWbD4aXyEcNld fIMM6Zn4ZcJ8Agx4x5sBai23Bc63W01X0gphttBv/d5kYU+p95fEbhlDLSS4HFD3QFnSjFJE +vSQNd3svddv5wQZvG/ILlxhrfs1Za0/hhuLWUYbQ2bnS9PyqBV9d8H48aSJQhz+8dPF7Hwv Snkufw/yMZvQYG/weqK8IdPFdqV6I4MkPap5celYrws2hxekrux4V0iYX5XAK8C2IrMFQ4ju lLZHzYYxwq/+w0HOvzVmcrlBR1OSwkoxDTbfVRrvN5kMYRLL3ym4ooStdNbhRAYLG4G0fxYc xmi9CtnWfua59JXum3OjVOqQXoSIUC9+C464uDAyDeaduUoY5Yl+SsoQdGCneV8K9xGx0BS5 QFt5mvYERIMBT9TFY47MAPS2EIpKMokQf+zohiUIm43Vt5eLIsZgYXNDXbaIdOcNpa2RRXHQ qCnFrTakKWUKpvQ+1uIOa0rYsIcu8Se6cWZKljAV7QyJRNxk0wNj6L0aP5BKa3UTG9ylH7U+ q6HU8ySmcKr5n/+VQ0+Ufwgbq6vkFwqH1ZCUXIoOTiut7Kg1OlcEOqlkH5xHj1T97+ulSBn5 8ASEaKptNS71dDk34L8z75n5NjdeJgcFaVG+EM2xMunkeNSigVjacjs2lqKQtaWwlZ8NaE7i monab7cvqzsih5iCzmGQDY+xFQ64QW8+KiVd7mHVhPwa2Lrv1l7Jnw5usH+XlKhGN3GyL37t OtXju7A1NY2yYnFXqa6G2z0vHqqNkCKEqL1lfJtoWyOoIaSb63+uPCAX4EmRVJuw1qoYONHi D+y5Svexubh04AOVWCRz7ZwAjswCu1u7VAPSNZnCz6Zidz0Hvj7Nd5aKX0X6y9uEl1C0pPJx IIypHvb9oJSnXEyt96oSDiMbMNVskmsXrYef0VARpFYKWnbzJP76+T3atmMdR/5EBdGoRH+1 2C+sKMK5W28Ws+/mO+5KGNUd8C/1Fxbg6c7A6pkXH10ao+2ExWToivYbFfH61NoqhlAzb17C 9U9cbwiPWHzeUtpuoBwK2oMMJq+cIguzcxC+H626MNpb9JnmJ1hIy8kcPjK3IbnisOdC+Fie u4Jln8Qe081YwkC80H7m4RLnXBrSkk3uvLMkwqv/Y70UK6CoDGW3QP82fZ5mckSbLR8Tn4qK gF3nmdtXbe/ERWJsspHLbJzX3vzfDQOWnzqHHpZh2s87otew/yLfUrSL2AWLgSftk7YG7t12 mqOccHlJ+11kbIhL4hZZ2mRndqpdsIK1kYFnF5/y2vb+J2tvvwOBFs3jOpVM8OEiL8MZ4ZU3 RcuKtO/NcKpIWZp7uzlGhGy3SBmIAiOp9o2jGyR3/0jm/ZxwmNcJvmaLGSGVbTb4kEXgUrJy Pp8vTcJtcYeU2FljyGvB4A4POtIHJPyBIHxS+0YF3+XzHHqOzqZ7op9P4KrxXmsG3gOfnIme jq5RETFW1k6+233ziWBWvpTMTmfvCwant7H3dwDQh7QTLKk02s6EGhktZSlb1X5bGXL2fGoH cinCCNk6l7kjniiSLebWpkwYAVUWscJEtr2IM9VbIBASzRVUA3b2bfMYofDluKDftMxbKPg+ Ea6/WJIdzUXfKT0eNsCUQIheyh4jD8Otrjqn68HmXNB1cGQJtg1BxFeYwAA18oKrJHfIRddN 2mWwkmG77F93S42Mf58NnQZdbpnQKO2GoKuwTzBWZ+NRhwUkKhJiZW5XV72c8pvJcq6UtmPS tVtA8WaIwzAkfRLyblIkFj5a9VWS6OkQhrJjYTQSxlQ10VXuQuAhgd7Q38tXElTbhUpOrrgt gAimeXH3O9UmGhJBaUi71x8Jw5orwYZTVWApihGnCG0X5dUOWVgOxrFT5GVyou+ftGIYBDdy puSY8Wq2UnfpqBz47NDnU85a2rYj3EUHj6Onr8s3ldxbvB/8tmjoEB0qrkueo+d2cgGXkXtC 5xAFqUmV1/9Bx5dVx9SvRk5/hS+ImTwHx2FeIc2xCPGvPU2NwCYnRHRKFeT7jPpnA/FXBcVv uCFDN3VfH1mZYmsqYG1H6xBjJMEIz3PqzrHDGaZP7dbVfTB3rjmniG2jtyen1bLpFyRkwtSp +6uAZsU/zTj0yXdjOT/cbdFNgxoex98PPPnWK7KAPQno0PE0w02G2wpRfMHxGGH24M/xteA7 CMlFB0tdQS6+qD2tEJnPOkkL/gqHrd/a2tL4I/HK6qM7yA60lFK7S14fbg4whF2NIf02LOpf 8x7sb0QV8uGykROZ4XneHFIlfcnqjLDgzs4hsy/N6QUykD1FUn5JgVlBrr1EkFV1LpqVxsl7 8lUdwDqQMq7f8IdgdB/bLVIA0vf6ZurAs+sqXWk3RXsu6VcuwyBg9zrgudu99Fgo1K9P6Yds I0iaNtSXtCGbb1HjoE+OjvBOamVMnZNCbsZTOutf5hJczEauseAGMy/JDQeNR6pvRW4QiCgV Y8RFYWXKSHRNcFlmqIc4OOGNeO0dqqPeXhCUVB3QCYBwzyL3bLQeMPuaYkgfT02spkwrrPwB 5r5UWBLBVW4qXJ2VR1gKrI9xwr1dG8sjPXnM5lEsIYz/ErkINna0XWYIkbkIy8eghqEXUmpR uGvI8tU9ZC9+aGkqeOw0udgasPhBq42S5l+tcsgAb8zUhLKLtEEAQl/eQGvs1/bsnwFnFPiG LKnu7SIQsieaJfpTTGJj1wMpTtdQvnQSqcHjJpthdDZDn3n1prBMnhLd8WKF6TASL25XhJ0H sz1/Qa2zR1gR1Jk6telBG2OECLC4yTCE0XkSBvs/AwV5pu8RKIkVgSlluJtV9I7Ax3ueVpph KlJ6a5f/yKOsZPsoClMCCt2bnv0/jEx39yU5LPbu8Wjt2clEpVZ6KI/a3cEBCn0XXe8Q1hiO jjd9H8wEwIJH4kd2i6u/UBTY6JCKjxtCEm7uXcFEcTLKVmX9Oy0/n8A5NeHwielfHVMXIqlz shQNdkZy1gIUo7e4+MH6ziwiIZ7getz8STY7apys32N4QsN5BOyLDKY5hctSWXQRyk8iznIf hBQhA3mp6HI0Lxr4uJRwU2Ozbe8Ms3Yholla1t5faN7JlRRUvtdbPPJk9I1MNMzCyov5atnb XQ2N4PVpZF6StE9JWlmskxK3lK30+tR5a8clAKe0Miye97ZbLI1AbxZXqKP09hxF0GbhEuof nMKE4joQ+59d2P2a1K76q6ayz1mr4vbePmRBf6b6tQlixECzPSOSRNMFLrkunWzirEz+Ldnp Q5QScs24zBdGRsbv9HwoGKvKT80HZwzKPJ3SQ2pt15Jg/+hLWqc/InyuuJIPdlaKbnRXb2TV j/nfWZx0GqGMU1dIfd0nkPYwLMb2tdxkV3lmqcpTwyFUYKUbKryz1pl1PbLlMEIPv8JnOJid GmbZk+T/K4DL+LtK21s3oPgEjouxzNAudVUp8H5Kx9bJXw3N0e0/8+5D5u0dxOx7XQyf+y6H BRPMVggOk9MuuhRsTJ5/IjkIOmtLESgHOdz7+o9lvT5mNTOzUQZ+cVniG6MVQOxJk9jQ783B BjZi63x1C2FVWDJ3pqHc+sAizkEBnKwojKgc664mfgxruOnmA/zY0d/gvJN58CSOmQIuCRCr AUK/36zJKhesxC1QXacyYtKn+xmxnuoeagAQV4L920EUdD2V4PA1mhnjq5W8DMXCSzKEsOof qQ7bnxJ/9dOx4juZf04UfJ41Z25YS4XQb/brBc+0ixNviiafnLAMAU0FFnEtRo9I/qd8mKMH CAXxJFXNdg9WRlP0UQKxJJZ0mbRruKgCYb6aS6KWsXOcqv+vm9vk/xH9/7VaCxr/KK/aFvPK vv6HJjPkNdMi9B31sVogJcxKdkaNMzrUqJdlkN2ZI7kxU3xVwwAvykbelzZDagKjLvvpSL/D 4JwGVawXCU9hqHanhn3fpRviQvx2hQKwby0toqerWgoSpSZxk8f7uD0i5QvjhChxS+Rjdhv2 f7Zajf43gyjexBJb+KikaAROMkt6U29vcT6QoruViTCL9qfgcuAxjJOqCYeqF1/CigMibjsB H9idvHRCZPvhUIlIPnhw90w2NA8kBmm4c8cjL66wahGr31PBERBqH734q9GVdVZxxCLQLJik nRenEIMTAzxykUTg+70Lql5QoxX7jCwJ5Zbv3PPTElpo0JpTO7+ZJP0mrhZsoVJ6ts6mW3ea mx/hY7HtwGSfRrc9jYr0aKIn7UlGQ/njQ4e8jcn59sU5iKTPZAUytmkvXenSvkaziRMX71HP fKX69ej2OQVg25zdc4ks9t4ihe0/c2Anb8Ul6Nvc6c5s6LMVHFPDw6pcaD6yB9PicojXEpDK 8G1TXsId5iAn9whEMPlZiAcy7Ud5mbKPpm4byXLy2Ng9jYREy662NJBTltlobTM10i363H53 YNRireT/Xykwis2T0Ly0RPrh9zjmo3CvL2g5+uAPPE0OnyiVeoSuzOq73wR19NWtzDkmvyE6 9Qr76HfXP8z/LWZ2DokQCwB4AUmA4iJMLS7kPRikbUlBeCIBN5y5JyAI2FaNI649yrO2m6YM tDPiQ1mvT5lqyYRcI+XIx0LZv6NX34rGt138O5D5TSpZk9kSY9fZMS5NE1+uCKvamqY0sqyj ICDrfce5pEQy7Cvo7GKvNnTIu0CFxl1jIRPA0W8STFb9TvK5vM9oRlHuDEalR/+eewynuaUg fQscpKJA+s/JWmQFz9+UkMiI63JH0+oUMypHjAWWJeBJOIo5Vc7x0p6ozlmB6ONm37Cpbe9k fXy4GyUSHWuzJZEPtkbaXk1DLxrXBY2CK7ULnB+SYYncd97+t1Iaa01i7eUodVggG9/Wc0TN vavz2x4wgRUWRP+xtjIZAJocIfrKbye75zhcqmw+QzMEBPsKhkTcUmjkRUgG9LYiE2x9R+fK CgOXqB2CnvNeRxD6SNRL9QBFMIywL7lunrrrG69u2OLhN6Oy3Fn8KKX0C3zPmx2IzKOpg9w4 NBJ2Q95z6wQ4kyxVLNPBwXexmAM/iquEYxD7N3uXh3R7ckNor43ePLFyv9jIe2YiOHV88bQv fTZWt7kiGXKTZTYC4OuY7xp0FCibNEjjPLrZ4nPECY3ffBoJA8sp758VoPgwsAZ7nAoRRsn3 t+/GVN3OZxQ73EPtuZaTtRdbfh3lgOol8LkGxbmW8+nsSLBd/YZWvT43AwC6inRU2YwOgXwi i3212rcjjGSRTKGu9dV1uMRnt0wHtNraXixFBTBBIBLgjRbPy0VHm0+F4utLpNwbzI15rT1o 6ZbgZghoAWZVsiJ6rmbzoza95vRCkl6LtklYOmM80AADcVtX5c8T2PdY9MgDHIMmvVBF/M5Y uKX04LBQmvx0AqJ/uYAllxomKTH84xyeupR+DEWY8tQrbrRXHUJKkWZp0c9BjwrtLsYkoC0S A7v+Vmb8YM7PSenjRtJ02UZRrTppgn1vqjrLWCQH05MgbkV4BygBvcbfn/VHByVpAuWY19KA ieWTtDoD9BxpUWiPSEgzTf40YpKnG2b9Cd5SuVauZVjaCMho7j5szeoeGU+zz6/p2lpxbrXq XL/H7lMCm3S03u4AhGdj5oyMg+grbsfZGxQjhEYox6vVMKdEhL4weP4nIu1Q4x/N5ECat4g8 sIR1YKaCFu4aaMfNaheTaZx9FpgFuwr8JN2s6xGuhCB48AsZQH5L8btA8EK5/yYpE4i2MaGA IJkieN6wB/lFpZnZUpxVbYxlftoRMV1CQCBVAhfihLdnbQQHAFOBy3lq7MbBhSqsyC/JSi/O dRYXB/OjPJT8VuGiHNAubhJmYyGwJ+X8ZYdALKB6B0SdvzxDYholRvyQQvexJP+DikD5A5o7 GmgBZdsln+US3S2n6V5HRRWy2Kdmdv28VaKKVxoh4gVTAlEs0i1SwC8pTSVkipJLqMI1k4WW ErU3Z9BhCpRK2cmfFIRj1cfUNw7OgbLmUBQ4SjHvJaUxgQ9TVqBxuFFtHxAley0bI19yHd8L A3Kz8/Uc+c2T+3mRuR1BeTRIP0RX3IAud3wP3cA59SFouJH1ZTOmgBAiDf7H8Rdh3Fn0+bgP TAyoQTyEkE+uB3C8akhCNG28DiMhbb6WkKsqVN89acuTtslLrBVQDoidchneLSMti9E3e7/8 MricOr+I2+UNcNXU/tWqkvLxanZQ6YPdzx7CHT9bbF+q90pcybHPpegtx0Hzu/xEt9kzxejh OLFfN3ZovzkClgumteLbxlO08TwODb7FuDUISVZohvo6qbOD/o1UD7LBnQps9CyhSLEuM0H+ A1nRYpAbH4CHRuS3QW8kg6BcxCHEbuRlBrDSRZxOLE8ape58MIxQyyyrgx8y53S1SjiyKDOE YqO9z9ozTfYTDk958fAADtyY8hp21fAYtHXcMRosObONDDx9QOtHjjxaVEdfS83UUGNvUnKx 53vpxlJI1Gf53vMvus1HtzvQ73FFtEHZnTW0Gg+a2jiAb5f32WIgAqxVWku7CWSIjrGeHP4I STN4g4NLOSa4oqsTF5y5EvJ6EnPXwCBpwCdhUPR4/aWdoinvIGAs6zinoRfR56qTJKc6M1/O RaceeH47E9TmwGAbChpDQ/1tTQ4+DYEcCJIO9gn8fykXAkuq67PbDugfosHbxlKsH2aH2FsZ 3eljWx9c9vSRMr+QWsg1C4r/ULsZ2HkhGhjbFbw2wcehV7zes+1+3NLgKOgWksZydlRweI6E 4Cqbgx95pG4VoOEVwpT4KRnOtX/wNPoULK43kC9UtCMZSMUXUuY9Elpnn4KM0W1yp+8ql6yn eLQaiBeUyqQDuOjqXPiEU03zhhgCG9id48rOkeIRBPV2H5ud7eHHQBg0kLRcSzpKkyOmD+51 gEzQdvdKcxWp9iEssvywkIP2MrYPmbVwkRiknNNSZzXWl2k9bgyKgcCT4/fPTnJ0sm8E0aWL e1Df25BWRxaWRTgvZBg2DK3GTkoYdSU/v4QITiA84cG+ENj59E8EJkIluGSfVGgS/ftuMxB/ GyBIickoCoe2a5kUm53BkbKpJU6bPOMWaDtnvi/t8tatHT2TFmYdysLNCUgEIfGrJX8OmCIr ECNjpdVNcYw72acgnkDU9pNc4FOgfpiKx1liXhshG1ggPe3NyeIPdkxwkJK7gVgaqGYkKmQU 7eVOga6xFiUS9V+5iTJsFQXfYd7/nlzD90NSsx5PvZf0Zw7QToSWeGQ1oONCX1KNEx0T3NoJ z2/eNkQqpNzBgqYoM/k5pzxYASElfYzTrnqLDncPFIURAr/ekr2cdl3DHtReVgh56fYkvtLr 6OdVD5d8ODQDnL43NqrqRnnqjYN+jR1wvPllS5eKlDlw391k3gmynN0kv+sH3JrCLOE/mk+v TGTvuRhPHIYaL5qRy6B5oz2DFSLhoXFNE/Y8Fmfma0otIiZkjcwRl+grxKnR+Fi5VJqHJuTe gkXIofkef3v1QU2o2VPw8XAezbwmVXmKFyMHNENI6IWvquxU0HZiQ9zbfFFt75U2Vnf85bkO xd47CrH28rxBFqYymaY8SDqWQgFtV/IDn7Ex8nM/UK7OJBBTd9hHcj7Bk2mUKrHSreI3DK08 veNN+ZiF+uyI2C8Wn3DvEpH5zLfPix7u/mLsGIz0OA7U2KbbV6ewAx19n2ZNAb3hACo0tsSy wED59JpG0lI2hvUpLKtelUplyPINfx5yDvaIE+dpgvlTOpRoMUiDJupofWQnVWaW3AfNJI34 ncnpFZRbs4sIii6Pk7DLqkk8gzOpWAIpZ8AQ21Z7GBUinM3UIRK69WlZm+4EATkWQM4e6ILu qikBsBeHaNQqRmoAzNigUanvUwbXRv9Pzalq9Vr9oDWCrdNSJ9PE18+nl5mbkgU8Gy8ILHb3 HMwBxswe9BcBbwu+8lDcL9u1Jj7odcvT2xF1jCXbATvHU5Tld5YhzQeKx88awwPk2c6K7GwU ZqDhCWJWSHJhxsBbwWvXru0JdVCzqknanE7deiIDLQsa7mMU1ChiNNIKyUZhBcL9It1HaDMM oRI3SJ7oEt6MYXP0yJ8oXtvFPEN6g2j5NFN08sMxhuB/tRTBIS8s1nssZNtOX/hru+lTeAxP RFYzhrOLwd0P1C8/x8XmH5fUYAlKZxzFHHc4/Kn1ppPDd02RtuRVOnIS+aXHikEi4qgWOA0X QJuPkYmngkiJCqhjkr4+lsHl8Fgk0h9XXJRBwK9DfDNzOb7xDAvylD5ewfF+ZcnLTmXfcjyG O5QaLJUkVBC2hZ3xBp2vs8D8ZZrEuPI8Tfpg+++nDOH5aCfEMz3vhw47DSlGgftjAlxxqODR bItrlz0Saq9wltSihB1a5Jo+Tr36GKYFfpMz9ppsPbPQO1oGqzaQujTbI4JheBWDkDkISvXk /dp3o9XyXGrsuWvn1jjE33J2rroY6X6pz2HeiBZ4lLp6cQrgWKVZOUxEv52nfpoVoqoG128/ vczmfd/swkxo2ZISfjaU0PqVUdZy4aJIBmZOMFMWWhX4DBNQPvjP9t7DDW8lQ+/ontjpmXMC EUHOGTahhE/73q6kkRZQz/aSpSq1PO8lKBotLMjhdl40zBln+fN3HqmbM5F7sZHsjFOKanT2 mjtDH28Q+hODGTdNr9dfIVCVCUlIV4xkqlqeagzes5GiEU+p0wUQSftCM8L7sS/m1sTGGXsA jyxPcVf0Y0LDox7kMwBuV16XnnRKQx4CtJmZCqWR9t0q3eTE3Y5d6T5tADA4qqEgZ7HQyP8R dngjnNp9s3wX2u5wO0XKq0r5hpZuQa9W07MZaluHPamU7pxWg/kedN6KXURxgRZOqrKWGhHw ZxJZtc9DOMpnACUqWQ8DILCE3uRyTeDCtD4CPtLI5dUrJW5Bqlv9cN1Ao/KpGRwKeXPPUhG1 ycOkuJMVTOi0TGPaNQCwmkGQOlkNuEqgnAinv6Zg4BYzJFSJZWUtAMXdKkt9YG0OQfqWb0Jk i03gE7NIjNs0ROOLznWH0trwMWOBwJkh/HRy2TwAF3A2FxhqfXCOsMoYXQty7cI9Xb88wozK 2CuqYSHF1jYRfJLwA+yp7KOFm64iD7IoLwJ/mrx8Lprb68ItAYMBBhopzs/AvUjmGjREL+AV ok43QQlX60R5xSZlPjcBEgITLEnYvO/Trz/8tOZRCVzNq49qdZrAdeEqR+fOCFhI5bWr4eem X6RdcIgwQSK9bXrnr+cmIVLjqfDUvipgFR19X1bKB1TDm4vt6nyPR7rMmY2oPUyrdZ16Kgrd rnmSPScbJm6d+yqAkbx/+PKuEesDns50hrGC4BAUm16HjQgLxqahFSGEiq58foEgQJCzb5JX 3K+bhTSZJcVJLydbRAqzViHuBz0ykMo/rEiv8LQlpwc4JnCyyApv7Cav54uelJFQNoPHpbir A2MmmEBxWm1Ih+i/ANGAk/f58PLSXcOBSrdu/UDmDLhcZnJOks9GRsSDDBEiRN5G4uf6iNIE aT1pDkRG77B3yTkZF34mhOFdPLi96X6Uv2l2OCe9l8OB/sjbfjl7VSRSsXBhitXl/80KdjuX 2mqXJtcGhlP4F5NNgYCr9OhA5RUE22HZexEW+rKwYH0ll3k2Awk3RjTfH7aBHpnB+Q6AKaa5 D7ywseyrP7zUlI8aScTNClOXn6LyEFV1HZKSSGOOHuXaTXiud1jbHIlYrKz/n1P0pmT2zzaG fSqx2xFW8VwGEhrvTFGDteB7AXZKmFyjyfvkbduJMaSwsqxOoEcI2n1r5lgiFMTnj+GGY6qw lLzN3VWZXatZPsb1sh+0SRJeWWiI3Z6QqaRwnO54DjV/WS1a7C6UT/vjjnS5J/os5a076cqr kikQ89s7EJY9iAmXceB+s4sLKYzM0Fp7EbKHfjqVNziT817x7uiIsba+K8tqEi7ulBM5cORu zO1nH5Dm30ClpDpNkxuQG5ngn1AulP1tq29DRbNvBogpdkVFuq1/xpNmfgRVTVGwgpi0vDws EsdvbJejc2GeguSTLZPw3+BbVvBVp62EEDiw70wRtvJ81l36OS2dwsc6hK3mq3G4tGyoBfcQ rRBoYZ+Hn6kDGTJVFc98n94pVezmA3isMxEWnfgVou0Bbn+gWN9IenMdqiAySLvuRbqe3+Sv kwViZ/iuD67e/TEqqiFtN04BLbIqiatxB/1ZyYcArer4S2apRl/u+MQYel3rF3jC5Z8nPekA DzZ8PBmpijlag28quu+syUK59UBX7QwtbKXeHGKiS9v3XWoKpcAlX7apZuW/cRdUM+9SZz+c vERuoyeWiFS2MnS81IuR5g6FS8Yx1eIxzUryuj3iYbMGNki4dEqWd9rtA1UBb4588mLri9y7 T5EfdOjiRHbJq91K0QN/t2RHI8TWbvT8V+QxFXrMBXCkXEkuceNOj1sUM1H9DhJltU1LboNt SSzes7fUZ5Qm6piT+AXTWjIo1bQkE+uktD8omkFWllzWg0DLkmio8MogNPHguwAkxlxa8txo vGVA1pJltP0WOylc3yh7aqMgbyznLy4sFRemO6awVQr6PRJE2F4uvuu3QYRrRTPQXbCWzrEd 3piwK61ZHXqktszt5ytd5080jeRqBE9KI+KquzWHCxIlbY4o3btz0cRQB8WID6HcWWsv01wx hCXJJ1qr3FhQH4QSSvFty2y05MV9LHPYP13phM8PT8y7XPtViD3WNVCXQ1jeEWiDE3mDHm1U +26AH+HCwvxxNAIoCM90Bq0ZwNiG1k3+e7BtgUrEmB7Ugn6dEd3/imrV/kPZX8GWFC/su4eT p9ONDyM7IPk7VQRZXkq7uZvkU2DRvnCuT9KTlxWpj1BooXS+bdXWm3yWyIRFQ0PMjjbN1cmV dk9xFw3j1Khs5k8H7DTvhtgoYWttG05D0nlbgx/Mer5DP3kVwBJGSODk+88H2VmDbGDVxEsr GHNawYkRjMmjnQV7gQWofHM87SG/zXLmT4rSPgj/Ds0Sy8Q/taP1N7195Y+0faoS3//V+owo beU7MSm1LeEOvNDtzaHSmD05fNKnPBpcve//uTKjwvVSeKmepcF8QSaIXKXHnQh2w5gRb+N1 6oOMWN4+YMlywAJauSzw6XQrCixb2lGcFuhK+UqEOmJZ8Qyawf+zMr9gPe+GDfvIXYB7JGSb iloCEgINuWg1XTuo0hyTVvGLS0S4F5JYYa3LQSOUob0pysdhWXVgZhKX3bPddjdFpLWMSS8e Sq8EHPLxb2ni+ejmNBLryDmfZ4RE/Y5qovCFhE1iv87l9Xxnf1sOpgRUMagiioAL12vxxASp ie0jQJTE0gD1pwrTnbpb6phSEseoarWmpYH7VBjGVXL+YcaFiYAkf2hNYqtfp0e76VvY5rU5 aQZpXYdwcS910saYWDYhNsikwGnbYUChWsWrk/iB46TOqBI4PyYi8rK8ywlRBxEfdpfwJnOH BbCumjxsxbQD+2MKIdzJhdy2VOZrXywq+S/nhy/A41Je4VBQzFxc1fc8Uihp5kX5fPqkj2y0 RBAR93rthS5VzK68ZtTaHecfLSump5HSzoWO15xRQm62CNpcTzQkMT3ceJYhGl37v9ABuFO0 jSMfwZCFQuW8BvUf17g9KV9023mMh9LqiDSJQHn3FDh3AppvxOtF6p5SYwByUFtz6lgvfK91 uhvrWwQp2rugWOpU0PdUDjaJAaWrmSI9jNsfH+i5U4DcZzy7ee4IM+r9isfYQyRJENHvwsnR T+F2btqKviZcGxpF8eVK3WHPhavTXHe5qKIw+PuOK/x8ufhOHxNgzupHrMZhLtVLSF3ZkdxK nEnQGMFNquRH4QY+/FlE7+afSsAu4mPlkndqRrZJlwn36R8PYvuPzkb/a0We9DPu8MEOheH8 9ufrFu2a6iIISBfF4cmGLHAdN5+z6bdDQjjBDBehSVd4TX4mRa+nT6h1rAYZi+nJ9fupf5pM P6+qdmAjaFQ6dU8q5Shi9TPLOcd5B9HNbduDC//nJj6bWvwaGvqVBt2o0mZh1ul0Kmaj1s3L eJJQ+bENgV9xoJGquFGuwYpUWrhIsj/dbNmCJNuk3NUNm0wlDC9abiL0sKVZIJ3f8Kq6wRmL ZShhUChwTd6KgLdorZbpCWY7hI8PQfQsTUFCnK/R8qArGYr+dl87opkaec2m+ZKAXJuTIRMS 3Zlx/evonH3DUmVZtBV2b01gfoijgLZdLqsk8IAsiW26cMTlFybyI8VJWbnCOfPOi/mnD7w1 e6Cb3LhsT3+RFRTr+GTlIH2bW1KPEhNbK7legzI2QJHu2a+2CXV8ZtLRPFgfT4ED6xIvsJ3B Nsb+9rwgnTbTz2eBU8/2sVz0anR7S9xKxVzbgK3ymycREEfjwfcE2mejWGyscZZVT5RVn20A 0fuRjiv8Hw8H6Dtu+4v7HbaVp7KqDWVBipIXPam436qpMo2vITlcufe888LJE/ofyADfcuUZ TnTEvVZkQ+KBblj8cYKc3n9I0deF52NYrfOl9wd3hkjlvhMMyanViXGBWoJLZk2+JU84Xap2 HN0v1FLFViWj1SF9Zd86Eg10nmOuzjGtAi83tFP9eV/ofY5k648f8uo5YxTf0R/wdTAX3nKe b8H0DEoMRaOgNebOL+2OejwyRpfqCdliPWnMTJ/KTEWkFWU+zG2MvOqD39oc7crOqK9BC9WD MNv00I0WTxcXlodIZygYvnRjMRhTrKqTTWtLPocsekshgQtYyif8RSPSmX1H5t5aqEZP6EXW g3pgeOhoag4cx+hGi3rCs4t2s4b51epg5OSa3oNu3APSbGosTaHnnqsakthkFtLwISVTh3lD eXnmiyZBVzpiM4eKojSCaTo1aA4l4gpPFDRC5M/HPOs0e9QHwoooWc2RupTTxG4+5gnq3NEn qDnrX+k7udfsI5r2BEDRTt1PkjMKXOXrBCgyR2V72BREZyAFj0yrUbm8LWSJWgQiHGow+vNm Sc83zvxajSepii6Z1MJf3nQ236wyK9DZO3w1VGXyHXBNbdJBIQeqKsSrXi6qD25XwjLaKgDO sl+zyEFdu2NoLUYbcipdlmUP3Hhvu7LPSl0Q2e4i/rBqIR5Lq/5fGBEvPpF4sg3Z5SKc9/22 LpOMaemkF3tKepsN+3NdoS8AiEmeXq0aBX0cOa69/RoO172ZUQFteZ7C0xh3Gs0E/0ZDm8/L LfQJTwhgjFjBQc+dC+i2RPNd8GKQjeE0205Od1mIbS+nDaGT/F0YOwia7un3OiMlHvqtFcnP anpeqSstVY4uYwYkDwqszTqSSutKMLqGM+m/08y3VBbjEtwZQtjZM4qj4+94ASTLTqftG8qc oG1z9Ffznm+MHaHKXKW20vbQ1/eHPivG9X7kAlvB2AqQe7I2yjhyzv38z8knSjed+d/8X9er U6jMH/4Z7gYE3Z7OznrcZRie3SzSWqqMdvj3L6m3tu/hgLnyswR+ZNcVgarW8IGR1CxaqxVe FB1xTXPuNa5AFjdZENLbYdOL7nYSAhO5qOZiF+JEjUbgvp/FVVZvw+M+pWZ4eOjGKM8Ppkrg vM9SAm5LAwJNsFNchoCFR3wi2oWeAcY3a4cpl4JUf5LQi+8K27naWTURguGNwLLxV/TxFYkh ndWZKF83r31lCNluPexpBp8x6Ist/Su7FY91vH9KV79YTexCFpdJT6QEw36oPu3Ptl7BgGKC FZvm7ioE6VhuVEwP/py8BIfpJz1JRcBIlI6GOsThrQz+a5vbvzjZStlOHoKfSYLz6N896MSR Kf4Zco668vKY0biP8sdPVBjX/jGkjZ4R0ACo6qLlU/7f6Fge9p4GV3Lv9yWBYfPhBjdg+1fk gXq6arPdDikfElO5+CDig04DR4w2msH2NRQQQPKw3Pam7EryX4c4HOO0PDrCzLrcevSRZfpl 3zCyMnG7djgIOhRCFWCgSF6ohcxPpaDKRAFHDbZhvYHd30nb0gSSXpWqAofKCEvIIY/8delA rTcdIPmmcexTpMvk/iJE+FEZ2+PJsRkiSos9KnFzseZ4YUHciXdh/q7QNSJ5N++ibNrLG1gM uoSabQFJneFZbm0+JB9EmQ/4jFDuXfruGvTLEe1wE4I65oMBKL58vUZ+2sT1JlFrAMY2bNTw AeFjY7PrP53oLokKAQF7nee+Q0FpoljifM6De5w1gUhL6YBDPpSZ8XrspbOcECJnb1TrlEME K35kFxys807yYNsurUuv2rKLvkB6dRnD9JPNZNmF4R/y/Yxke3ekucgdckM5tp6CfEhoc93Q OTcmpKOwCWX0WoXV4bS3IdE2sGvuSJlPUGDEu+vomhozQdWgmyM7Ihwxdlv2pByCa9+O7czw SZEdUkDAcPet7VYzMDoxSIA+9IAufwV0ll5USL1nqq7USaEt0sKYRvZNVDMIZ+Td7jqTL1lj c23upDYArirBxT31b5JWPQhaJDW2McWG74fz9icJxoCsaUxaz1NuNj+TdVlI6psS874Wjqko d2F0HlrdpwqYZb6bCiFCwIn3W+6z0/b1uWSmGgTXRU5MKA+cngsrnXN2etG48sg35VfwFZgL 5T85erC2i27jHzo4nHckjErZXOuneqznH3iXVa/MnvzQHtPwHAuRPK16ElCC2IVPuj2FFrJZ 6uhq9yRhcoqID19hOoIIhffLroKtL3zCpgUyqogw7RKw8TEST8LJPhSZHOjTvF2o9ew/Qtqb NuDoLeTyNxXWfqk4E/YerTUU33IjwaR8ycUckGV0Gd5y3WakKoaH3W2pJlLTDLveOJ3Xy5IJ CiZpwaUf8b52Atij26+dPRf9D0VcRhwtXtBxR/T2RokTghpFizTum9WcvfNLJjf4Tl+sn8gC 7mtzuFgPz5W+bYMLL+TvWBCZuuJTCb0cHJYMguTafTVxWf3qhJ2ii2mwmQ//+sRoXGnCbyEM u/x+y4yUxvzTz/tJkY5zF+3kkfJmOJVEqwBaoleQfHODFagpv2I1OwM3AIdgwCpQ8UaYSHS2 ExGkiLwlj41Yj0/jWrS2wuIIMoIyj9yu4E8vzsSaHTpj/SqNdsf6m5ZXjGB5k3p8c6jZUOAF Y5LoNm39N9MBTBtIGBUCd27f40bmdb83moiaue3ujfjq2fRaqhzDnq4vbH5ttvjxrsas7UIg dpRVrAjQUCsqya98wUKf/BURDxklo2EMeT1n40OpjS2Esij7ajHv73BNIEGLiUv50LXRder+ ZdSdI7PELM5G4yOxTj2KR750L2Rq5bphJzC8O4JjtHckmzEDtpvMe/7nfj5G91hUIGlrXFuA zrJmmjX8owIMmciMn3WfSfZY7fflJlwyWltj7eMKGYi3AkN1y6P4Ow+3y740mjb+WBt4ZiEU +1c651tdaBPqvssj6yLDV4lP3rKqbiYtoCZ28qLMmJ7y6+nFRw08OK9TWDDJS4rcF1KU22U2 eAjeeSSwwSEvrXykHtxrZXQ9yhfcjCsI1SvZBVOIM1YV7W9W1FWyKz3UKx8+LhRoREvlXke+ x8+bC0mQDap5UkPofJ5Xri9sEcP3jZgsz2bybbhi5b4OP942MGD+bu4FSZpt8jCQKF18Gpgi y+GFBVSyvS/P7yCmnB4Ps7nmFAZ3hpXHvhVqdbVeD1Sq12pmf6dJuJSb1K/Tvaq2+jb5YH80 YIC3OL7PXCPFeJKauTePhnV5D/R+2W10sUXIKk3BMxAMdqiOUOjAizzuyv5AgiYPb8f1ZFOz RlKN0Hdx+Cr9FUkt7Hf1iuQd/LyagV8eU502L26y8rrrF4eGHA4X9s7jDfwuEMDZ1j1igjY6 otABofpIsiBFQHkRIJlnQDJfqNXdoSmCt/CmTtGExLmKy6V5ptGedWk2I8yKPD1hdPLOU8ui RlhD8CFgfg3DvUbQl+XQURN8s+swJOHY6e5N5xvXysE4pXKNlEUTGO/u2HYZERpYKWRaeHYs Bwel+le2U9jBulKvCEzEjPnNDS6padHcMY5pe2y6Y4T9NaX44KmDM4+00dn1M3wbo2hpnfs5 FxK9/XO12DYRQk0lexCVjgDvqOVjLKd/IeguuB+05rm//J6uVXapfhpXjtpRERAYttDIgVIg +CKGUgpwBBRET1qILceIgSiKW9+HliNg5C02lDkmkuv4uIQQmKB3QikbaANMa5ZasASSVCce MbCzStRYeZJxETVvfMkO6mh2+2QMRzkL4O9hlFb+UHdy1ZV1EsroFbwANmH7IgridaKm+IDv Zcux4IZAyMsYsGaPPvdZ74BU5lhcwiwp7U9o4J5YoiYj1hcwU7YsudZRsfCWas0FB8mr5mIY waH1AH5MR//ezP7a6gFSJgCBI+xUCUch8D/TOrjIbUWy9YtFP7eqmT95nDHrk4hDL+86EKaM f0q2WPx7/ktR1YK85oRi8hOdjZrGlDhariFfw6cN7ikOu34tZH4ETaoRhPPSDwRsYr8A6VUL c21LN+/cbdoIBP/G/K2gyrIeHTyCVHG664Fw+4RjWg5WJCIRARBgel0fspTsPPehuPGt3NcS RD+BdUlBYXu/SGmoSP5LhAPKJ3HwaGrEtAP87Wq4m2XbfcaCSEE+SOskliuSSV8yqbIuPC1a oZ/IsKFQ15blZ2iOQtTXJ5t4nHDNAfBzAakLxloR6xnh1633p4m7uPzW7KMYJR92/TFJUarP 582RoVjWN2gAKQKpMNnI+27QVmk8632Ib8HTCktjUISlekDgcJ7QGnX1hDH9ABjJjso9y7B7 Zo6n9CGWG7+Oyx3cDKV4J8BSXBSqanEsU6NZ1i4E6eaeISwLjaGVclEZfDVRDgZLyyej8t3s iAyB/rglNf9NOh0qKsxhCS7Xf6Nr+FM0NhcuTSntTDx33is/pS2c9GbTsM5Bbp4C075ifNQX K6v7kmABj/wlSKfkZuUD+zYd/dmeGaRLjVo7nkejzHZei5tB5dAD3TI4JVyTmsxjbmAIB5GW EGmNc1OViYeW0thaUM5oT7B8hqglpe2UIkcHVDktR1G5XWkVLw4JCGhKAn8ouppgIkonE+sq 5udA0gciKB47fq2N1bb+IK5jQH62wCVAutmMQaj6R9AoereqeygMc2gyGrdn5hg9M3k6m5qv ei9cpbV2Djr3oC8ubWyeirFmG/l0eKeLAaM2ydx23WfBSALCfu7Yh4vIXCrXg1yp6B09V/Ej 7wioRH3LXcV07/kTVhljLbT8NyDorGzOK6BhziOnR0DqBGVQ735iMuMddPZDF3uNoIIJ/z3p 44V/smd4nZIuVu1qfr71dhu5OscwLaCh5LR3vidEi7SjJioxrN3P1gnHzhX1wgotPYjHohGU owFCnh7aByFXTqmqCEUKewQfXIDTWkTZyoPrgb0ysC7SqLfg4dqHQO+3p7Fhu04jt0N+H/LS Slubzuc/dGrDZTmwzO2GSfs8DyC4Fv2AC/hxtfFQLAPfoyr6td5XtzVoDJ8gqtUwkx8ekZgm E1vwF82zXULoz7TNcFLdCSRWCYOAjc4kTWTrKSJnN3mnnd41+0Jd45q4BbKAlaQGGQNkruy3 tlVys+9T6PeDtIClbeDJ95f4EEruTxX6sLBsw70Qr9v7WBswhfPCjfb5layLi9CxaMv94T9L IrXkX9QQ6T9inqTQWYC/BUHbCmHEAT2a6vcshAE54WVsFh3BDxR3emxgO/VmrcxnBS24hoT4 dB0CN9axdQPrQ1WZL3iFdt8rtCOuHaTgQLd15Fluejp63MDYGpbrftSp9tp8iTe4SIKFwxaA 8oJnJREph0A1AYys7v0ecH97AmahFMrBdIQNLeD7HlEAA+BekNUbQMw7K3b3xKTXVno2xQNv CoOwM8mD4Pfce9Qw9FM0BGGJ7P5mRoDEgnhd7cINu2BUjgv3PTVwKeAxPuX+f/+Zf3u7XTmx BHfynIcR3oGHtIwQEJju77gYPIPHQLWe0w40bW+dOO50QWpmP+LhMFjMzBIK01OmUeNLeXkB fUyMe/hf7Vj8SY6rI45sF4iATQ5ZqgPHq7BUhQy1zLI/EHsvjaz7XiccIIs3/evKch+xraKa 85eqSH/wnBp0+a02RIOILnbIdETkO0i4jBhoH+1DKaH7bTrC4z/NyFQtnj25DVdRfxASqmpU h8DmipSoFX2eQGLM/YXh4KTmrbkcb2K2km0mn3aZnHDgHF73noOey3mZ6yCvC0uRZLRL16UE dknTmlNVftnAhVU8MN1VpAfkGHeUFt83J+vOi5d/xUT9s7/9D84nUK8TqaYa1pDm447U4DVF pHcN/LJY4/EV8yuMgb7f94wIe61Utd/xOcujLsbryNfIPSKkG/lZHvHRMSxncpX5yt4u4xQm tIjPoo4SW5ENQ3xYtI20ZFUyaWZC+RJV7JgXFuvByOpOn9+h+C1Z2XM6IIhZoG1fnkl7sjoj 33RWaAZ0aa2FnVV8o0Xl40F/HvUn6cTsrASory1qmji+mqeS+5p+WCHb4t8HmI3+DTomttgt +OPY0D6ih+7ErONPvQ63IQA/L6aB/7ELr4xfIxOioXQxMImRRoZ/+9CeA+tNjwHovlQob8cc EN39h5EvtlX9xWKqygbaKEb170DZAVlwZl/zdpa9vHcGRjLISAW+RANSZ2C7gi24bvL3sg0B s+a+K4fYELAt6yA2XRx9UKLQb9MVMDy/8/vNCwb67ynHGE/U9m/wI6qy1YVrGGq6HZAcUFTh ep4Pyq8/ADmAYQ/sm4IvtNwxJiwdRm1gNeZCglDPg8+VtFB4upH5Gq/+ISzCo2FcJVGCML8R 77kM+R/MArR6hdnATHDHzAotS7J9mi1kfxeE9EGgmRlkJowHJiWRTCkHfDM3BW0FV2JL7Ji2 vkeXZJHhwlbS5vjmJqKgfOPnGhqahUUTByAdpoL5p3AvOBjj7zkvvcq+OPRx0xfCv1o7Wrtp 8sshaYjPmCjmWSWZUbmivB6f7F2fYeWH6PnAqW/97r5yCm76SGWq3bO0JZUZUvDm++etI6kW NWE+MEGt1OhZrkeM8VMxf9rYJ0Cd90cTvuoNfkr4M7xH05HBfh/qP5mWBiLaEypbQG1CHI8q pdPb/Ju852dRU9LfQbw+5OJDPXqoKa+W11D1lPe4PrRDEyIZylPmuATYqX8Tc9J2YuRO9Iva /91KhMOsSE3FoxVnwG5urD47cDskxbLaLjsWUvndeODxKQkjXIljIiLxk7+8tPTaok1M9bz5 cxqF1NtJDgi2HvQPnmG/sBy1vwFBVMTh1KHrEyBsyjV0b5wFlE63ZJ0wY/jBVHUD2kerLrUJ iJYtESxOJO/mGjyUdwWetCBiZL5fSft9+EBwU6cskGhURlNOgW3jhyCR2FI1ZiQrdpOj4IRi WmFYGhuse/rnq0ZgI3f8oWbLoLbAaAFLqHr9LyufnmjzMW5NKJGp1MDXf/GbIePrDP6frm8a 8AeNi+vGEhL+0ARAzS0trZ18sESpGb6jN63r/LQwYsikhIRvyUQeGxPthJFRb5BJbIuiiS7W nwa4I+5h8RUxxRB58WzUOuI0fnSoMm1wMALWEGP4JTTisRQgZvrN0w7Q/tmn7ENbXfeXJ/3/ TzkGin1blSu+4PuMH3uuGeEEtFSYOSzglJdzgmt7qTMqclaQ+FWSM/EiUJkBydAkED4JZun6 V5sXLqH9aIhgew+E9/30Tn0aUsJ/gTKUTWQp12xxtRMjoyjWpvNVuSpw7FYFgbQIs69diPlo LdFcHfIkOdqPeWidJX9gdNKLigOcmDRVys4Nx3S9Gl7okKjohl9pa0uvknG8q1hEJfYuOc3z tgWTqGJ0rCiVgbzIVySYyiHlZQ0qvkx7HGGJPAHNc38M6DRFrSaCohFQK3BGRNQOBXaXcIR5 FjOcIdx+ycDgR0z6BUsIVGum3y9SlWwWBcas6nTdAg02Rl+L4YFefWEY1R1LDnKgKagzP+GS n7OHzFS4mj2Z5y6YbOymtnrje5SoEd1UhfR89auv6i+Cdd6A1s3/0HBUezZhmyPFkWaYm4k1 Ikxe2rAA9ODgsKIzq/D2B63hJ9cYXpnLM+QfW4OB9EnhwqPWalda2BINFkmvkqeYchsYpaHE xi1BH2YBcm9xoWQATUnHyOgeyQWXv4jXcafx8/pWH/MwOUsxHLqp0UfI1JG3wfOnS1MMP2qv Z4fGToGqic1pLoy/KhXrLc5+vfVwUwcvCcEwA92bOplJtm/C3U79qnkYRLsXSh6gD2eW9Bps tqmY+KwBNyNm+SuSvP5H42nNfnaepwnDJDCBI/nu1ITBwXi8DgfmkXemvH5AZFWqSXUeXvMx so4zXUgNWX3SLk2WR2vDB3PVfEoe0sbXMNHVGW9ZTdy3UholKRdtfaWAnFDE6z8OHnHkwfQn YAy/Iim/vy582mQOHnkq+kVI4cQ/zRQ5gM29AQZMeBXwisinA0zWaS0q4ZaogQ/PSS3VPI0X tPKkW/QtJ8LIitrGSaqDtOizbaD9Kv+DPVQF8srldaBJt2kr1hNHelo9X/WysCuDLt0cCPvj OkQLZChelfeqK0vXalwcrNzryF+NxqSyU0hvz9HzW7c6PzPTSXx9jpbxB536fqlrrsR0sTcJ T1Y0BGWAeLfH3akXI1jx3nQDPFG0FXaCuBpUpTTAuWeRmBouJ/JsbmIpm4poBYmalpAO9P+G FpHA0IE6V6njD4J+pSFDcDZWnaZ0Y+GANdIGNN79Mg5ayZr9PyWzUvCgl2xgiR/3xE09dxcj eltQWhTDgCYWskznIrVd0BqxaQIa2gGCr0wwbxxqiImouPvhOZ3Y9K4YVKH2jO1f4gPsVlJV rl04VvkLoRUvdhCAOy5Ndn93qi+kiLLG4JqfEaV3mPXmhPbarB+s4ts86SbiIqQBmFEKrZWN uY3RJtwT9NrSsQb8i6ELh5mrvtjHCyk4MJlwy0wNIuvcE3ulZKcoyNN8aZu8q2VEe4oOrh2f v+l+7Xb1JV9d2Q9co/pzvpG5tgFA/HuaEm+tZiTw/LqcbxzRrHTaWc0qS9tqvha42Uuo9PHi rCmOKxv3TlxTv9phR99UFdOkl24xhFvwSaow/hOso9Y9srx5DcKilDEWB7JUtKT2+iiollzp GSlPYe/SED2renmU5n2L/yErQIifGO8TkX6DvtslippAN1P22Ut0daTnVMohjiYH7koUf/d7 50okYVHE/XyldsyKEzxIylsZxa0EPPnnIZ7wwxqhO1T+OhN7oF6wamH1KjjTb8H0cj/D/+wv n9YAmzQ1FlaHKY+yVpyP0WItFDzzYJIsx27Q4uIH6LEJ+wjrpgXzfUpvnZULtSRpTk/csWWl sB+jM6+GnI3mAPIrZ0tHJYomeuDHpc1iy2JXtTntnMoTKMnHAIj6AUHlndgzv94ZSOwvg/16 UtXQ9UfHAPkn1+j9AjPEFqQKhoBWbjUSoN5GBKryrP/cddVQgTMsWHJ79SKzcQMqMTU/PDlP apN5yEKy5FQx1xFQML0rLOHYA+AnQR16HfhvvCmi1/9zsEuhK5X7xFxOki+WZ9V6fCPkAjf9 lERlfk75ervPVerwkIwiubK2BMryJ5uoEB9wrj6/mGHX6qj4RD+OsxxR1b2Z14axMTEUx8um v+LA36i6FxNVBi7x5Bhl1gj9P7RghAIQPrTyRzLw/BsDrddn0x3RCzmTL73q9d5RhjiBP2Mj syF5bORE/FijqwRKriaiu7EDtV0zu1/xr4JqywvMmI9sjaTa3KtHU+mr7CAERUQpkc6Q9N0f l4bXlcP8aDa+bMFkGW69SeGkVFqq9aAieqoqrJ53RgvzBwtOMjgmZjXE+4CUJvtrv7qj2fYW 94VyCfmD6dyClHfexVwv770LT61eLtFNyulzeinQyTgQ13J8cr9H6Kk1ZaGipBUSwOhZpWzA FV4p5kE8FqhmunVkQZQKlpT4jk4gX/C2jEk9OJRzSecogeolweYvB0jXEHYAPmo1yX/3PJafKl9l OMPoN0CUblkepISYwHhXFYqC1ToHDjhDHeILCC7O3pqTWEbiBJPD5G+YfdVHieuMXEQVHFkh 2qaBwxkpHZZi9qYK436jgciVDqJ+G5VYwoFLwhx7T5Hg116hGzUxCpTdDGsXTdj2U+3xPPWD 6QOzBhgdQI9MWftqqtIh4BcgvwdD2x5KN3IJ4fgS+gys+OUSt6MGlTU6W7haA+qgqC0kAHcA MxPjROri0PqbJx2G/igvkhj2K7tUfByCpTz2uBH5/7x5USMdBAH6LRwytJVA8VYSVZBfp8rp zJG6L3QXgFOIOypxr6S/cFf/mr0buYmbcdr3g4XloVFRZujdR8gWNN1gdx8LURa3lUlZLfcO TWWm6+6pziE3sfEBQ426zAkj7km2xAd8xm+6LNl4+E52RwbsCLlHD3Cm1pNh97LcavXzyDOG 9G7tugemjYxXhMitnn8Veh42cHIkGrhhL411OhU1QObToLwqAPCRlmI/OnuRMjaqy7ETKpQB 0lbTySdwYPGj8Mk+R1eCWOW+l3vq87VoxJPaEylTKR05sTyaYy/AVsXpmt8tcm9jaxZgKuQM kvAY+6VLgqZg0tf6PqaboottTTJzpEe8t6FNcTxl3jjOxN6crtbuFB9D8wQMNYUgToyncjOz NxszVPWBJ+zSTkBSiQvTZ4DMEgo9V4Utp/2X07E5+GGZp1kQcMZrmqDS0yrX5BXQ6KD2pv5S X58m0ak8Yln5cc//WIz6eFhYfT4f/l6D72usikxLSoLGngM4ziB1EIu9+nfq/hUcTupKeFnl 3junRBX/awf/1UbODGJozij5korfmIanw3f5oSeTNEAIGO1gmJkH4eMXLEkIivXQA3H6pKF8 L+K+qzjy8cdWrDJo5sVyk8/gslpJhkiwCkOOi7yYmQW7cbkDVqkhrKKcU0S0KCtQ5sjGGOn0 owDAJci/ykBezMLoWW5+RUQvgdMPWR8iK5umy2AbLy+7ra14wfs5boGAsOXnuznRZ65wJCM4 jR288kCC/lSw4rQy72UYFG+UO0r77VJQQ71jwGqjkwFuCsybSUHd2/+Xpe8fMWscGR9IJVD8 9JkFUvhlVR6RerntjY4J2dSOS5wTlQ0cjfFDpZjg3UoeK6EEaa4nwG1T5MgIXFdPhXHxJfDc oxhI7g6dazfW5cypBW/eSySgDU75rkB0jghYSz7zopvcXS5pGYxZ0ohq3y2tjKrw4f2jFPgw q2MLRO9vjF6sqoRCwJf2jRbNyD2qPSIDS8ZlIkPLRywzWvmdmCICjKThZ5ILFAUMSgGvAo1H 5PaAO1s/knG1t+FirnAMIBVKlMyzwVat3fHVJDwpCzL34bv7tLn5hq0eixmj8k9poPWYvkeP Bzc4yJL2F/idPQYstkF/llVHNGovf9hsNpQu36m7an0RQreDP1mabR+jzdzw4e+jyiVmlEB/ bJNNt7kUCKsqqLkF8e3rkvqpyb4qJGY5TYJXH9DBFvn7OlPAHJ6Ai/aQ3BKFYXGBMoygkub3 r1TdhL7HoxeEHu5I9Ef1QdQ92VTmnwchCLZoldnxoyzcFfF2sExHCi5S0CgMiGwbzXoN+rIf XyZGGupasl9Cw3Qq8O2f2nzOLpFTsl2nNquS/+rCE9SCrzpKMzilIVXGQbHsg24SMnETIEtU mFDzrU0wlb3bpx+oq/mTbDn6GOroOiE6mM+1LLg9ZJrzbv81ZDjqEjHrpGRshePA44tp5g0F sF8B13lA9lmy+3L9uHkUBJZKNxsrFZz3yPlHh5gfYPsExzqJRsrPxKplXdOoit6NBwaZs7AK UB6igdUwYbieEGvAgsM5jGAK9dF7ZsHErjUv/BK/3P6ouFD5hhaQqDRiJtLlSOoWljwd88xp miuGqYq1AU1opnswVE+Y+00dF5eKR219r/GtxmY4yyNQ29nSs+4hPrJYJBuVnm/PzxtFrRXl cHUBqdMcFUKvGE2r5OjIoXsWXL0/ppNc2tFm97asVA60CPuykbxzh3ZipF+UChIpSGskv+GC nhLDyU4i27KXdwYketjXFu+BCzlUvVE8+U1ckDxYaDP+tmQiJgWanyyVieDQZSQ5eXU98vQ9 oi2f/mz0KCdC/sqWptN9iy77kbtx8gCysH4qQgwyiXOOKY2ddgx2nEGrJNynFJ2huXITeAkj WIksQsvMjIf7yo5eiT12Xx/ppagzZG10WdrpnpSY3f2Nt6kazKN8KFEPR2w+nplVADyaZZgB btjfiJEYGH9SQ4yt613oX3LwWzkvzuhAYKzT8Javp3fLD2WYhw7wYZomMzIdCRw0Njqy9Xod 5O4JGpb62443uxcmmmaOHXP6GA+XRXCAnnlvxRqoh8/8XWcMWtwp8sKcKPcdKHtcBNOmX0EK oyfCPOtYRTUvMcQXE7D4LwVh5E14kH9UrqQkRGsr5E2o+n6PaflZRQvNy+Mq9wiQXPQNlvrA 0QO5C3jAaxvxhhQKLKIiNRwcnhO2pJZuIycXjhh3I1f61xFle9m8x4dmFF9cpK53D6pTUT0N q8cG4dGWkKtczxdJtZnNWeXd5MUu66P3O9HN4v7gvDIGhpBzB4MgfyG0dOJ9YfKLDMLPAddR CjoGu2gYUkI0rV4/4tq9P40Nb8WxTu5uC93jzFWUU/hDSvi655QPXOWboALgJ/5dEM8XINBA x8gZPGJVm6o6jbRQSXuTN1+fbtq89kRQ/3oE520cNeQYJLG3Elj79kRChDRPZFLc2lcZCn54 C4k+xniztPR6oGAUcXY7N9BAUzfZ81mBWrFmWhxVk6Ohy3aB7VYwKjpgjkqMa8XHoaiQVKw3 Pf+EjlUzJilrbH1zoq6DJeHllN2CoQ3gabpZO4fTJUvxge5SH50inU2ANndJtmMh3At3j+8b Ibu/mdfVDiBAePy773J7QGu+xIcE1MTPhJWskXjmDR+xizbbysOPWMGH5uyRFYLTt21tYxAx iVnOxHgdC3sLgB41YElaDgxhknryMPbeLrQKT8+Q9M88NglhAXjvUzLd1sOL9MbZXziWltLz K/LfXrPO5/bf4K2FX9buDRNMxLOC23keALSQgCT9Jtuac4ftLza8IqLKBNkNps3ts7TejhdU /sTGOpleNPsZAfIbP0eGhR+ly+B06m3PL3jhbp4pRKYVURGq5ecT+sDu20Hs+X+NMJ1cK9aa 2ypXF0pUlzh3OWZKuDIa8FLcVRgC4mDY5GqrstQAqRIG6IlWh0x+/mu/Pg5HOcC2y6J2+i1d ejiB2lQKZjoRWuA/02MNczN2oo+jLli/M91M40ma7Xrg0fLpMow9Iy//KT/tRz/Pz05nSTxs bhyHa8KquN6cXwVmFSVvo9FZbQe+V8aJQd4VnofuERh3PUP1p3LHLVgJ1U2z3lrgkkQxCr5/ iecspTitCR0+nWs96TOj4EbmH9b4sXIw48VxjzwMzkeF0k38X0v3cMlOYQrcK5Nph1J96XN5 /jHAnouncOr/GXOshdQq9ulQhNs9NahIrMQT72czopt2Wq40T14Oxouwi2HIO/RJ67nx+SUu g7gdwvxl8+yqY5bo1W7BEeKQn66u3ZjtMebh5tVcJ0T4qgjBHFDYkLlPtgu4GI3HH4bG8yp8 T0I71w+kAxv9gRnJWdBPjUtUfDDSNfebv4ogYo9mrq7QyPN/mojya7ie53A5B4jBUKRr9ir+ cua01YA30IdRSkkYTAJdsOyPceOE3iXnEPOl/pk92s1mfIT8eO4H2vrjRxDO6nb6/lQbxPiB JAoIaQqGBsVpA68TIcHwB2Z8JX7GMYFZF9ZC/1ZBrKDp4PQxDmQFQ7/aHXjtNCG1dDm9UAp8 sIGMLyrSPZuk02an40xa0nZtEBXX99zo2No5nbZOHOyYCZHzsVF/dJCz6McPVDxXhbEvgPZS eHUX1Nm/+zfNlp95KRiDb84M6FrETpAkD04aIuIvKeyzAEaIHrYAMJq7UN3iNZTe1xs+yh24 6sSGzv+iMoT+nogu34f1D8c2rxq+xfiZbfOrCZ3T76toyre8B6z7HRPoJ+x0/jM4bLQGriEq QAPEmaX3J4ZZ4iNpn8/0qKFwQ5r44ABfe34KiLhZSpe2O5YXoh6jxAy1IHFsJRS093pn9Drf JenzH3zG61KpGqO6lKcAXNDK2Z3eA1ZArHy0wywDn1OOZ/1W1g7g6Jk2OI1loQUg4mDFK21j oQkGh8+c+5X1dYhQwdvGbZWbBV7FG6p8+5G2IlSvFYC9mzXC9/rZjGj7hy3PBAcdMwFL3x7I pDCWx09VSPEgZQUjF3E/OWqks1JnPp/DPYdIQn/5+N2IqWvY27uVd6NEicv9uVGPmXu/BH97 Pei5WlQpBA9/eUNEIfq+KWrWDIbSsTHyRmxTnj/5CG9pW7eqz20xuXJ+SLDORSx+MEYTo1Ru C5kXPVwEHoA8D497FCHohqrKI27cZIqCRDmGhrwMrqBeuqPEdsudunclUJIe8gSYXpmnaPZs vCEypie4wE49gACrxdesPneDXEirzf2s0H5IyNhY9qjMPBE7R6gdAC57ckQi/XAkKzBLA0Yv hTMgAQwDKmzbCNLxQlde0hiH5ykUMwzLnBOT4b2M4QJD7WQuW0NIWn/XZ93U8LIoiaH96tHl S9r40ufEnIATBz2Koj5UsrnYE7DprF2ut7F1Jjwc+8E+5s8gFqkhGh3tVAXj/NmNhd6buicJ uIibvIXzB5dKOEK1+axWWoxLRS8zKXpZzMhSAhXiuJnsDs14RjGsMBlKDxuOC3HRXW/iXhlq 1LDt/xkOg4NwbqIMLl9Pjf72WtBT/n/ZZOuRwIGJ1LVeHediWHZ97POApeBS4pF2PZyC+GBD jayfm9VyWuHqqy28Q1JZYPcykNDXaKb9bDPFHUAPFIAiZVqhV6J/hDr7BWmbgczzEukzfoWU HToxWia4EjL7aZueTyEHbFwXq3+VDUribCaTJvgcr9k+FyZ7t4bm8TFQ5JzW9Vp9AEThMXCP 2ZtmQ0Ae0A6JbHeWj9kwvG9PYPXzWeZNrWaxnntdOOyzv7vp2VvFZaW1+lP4ScKIirX6dN2q 4lN22USuZuYg7QUs2Df8rLd2oLiXa0tIBE0fkDax/GZk6n2G7RZdAOq12DtC8eRK/clhWf2I Pr4yfWEpQSGORNp/Q97u+X/g+IqxdpsXc8lC1WBsa+u3tW/HwTQn0FuKRb4ntHTiy81G7Zmg Rm2Ple/M3YdA0W23wRc8dkOtDeC6FGQsD+VrLqcWZOk8kzBzHUtv0A6sjiE6twV0D0tNxPhh eNrZOwl9enRAo2CzeSmL3YN1L+REFkb5WOZUQKSDOoiMNx4cht2l8SQo2FhkqZCDPrcPMvTm G0r8exLNy5+v0tMp8HNxsXAFMJ0Rzfpb5lcqr23OGlcEdO9cGBisy7arh5XFq3TC0ZknBW6B /gpTnznOA8laZ4Bm6Cf12svJyMju2dvqz2tTBEWeR7b2hZ8pdsIq9Uxx6dtWDsRp4J7lKGnO wY6taJdtwvAQ0ELXOpHmlmyYm1wNI5lELMHxt7wKzkwHzGNDhOAk/YT+heINzKVaDuuweC+T o/2GA5BouR4K2CrDtOy/TslfMreFVrBR8H0RAReG9HTyTuXQKnVrCHXGBoUFoBzVcZ+diaxN zs3beiLNsrZ4bpunvgMp77My+W8AOkc0tcIMSPMEwHfKfdkNfMIlrI6fndLFt5cXxUKSO7zV 9htC5uZdLrvwfZhJJXEcSKA2es5nVFQbnCL0flzDCQkEfTWlwETkeW5YpbqanjwegCFJ3OE4 BCGDigWqp9ykQmghglWIIe2+VItuML+mD7UfiG3craSPdRt7RuemkDbCpcmWpEGRZvUF9AKp +KLjicxOm9vX1RKvdoIAaAVI+687Mph/GNea/zNV21in3rcqkeU/+U3bIukUi2+dJgIvV2Iz eStFEKvCYJblEkuDEYn1jZ9hnnXP9zvB1Q+EGMTsF6U2kfYqtkcOYyo9C2HMopM3DdCjSnbO wSlqxXNCm1tPFiH1N10juwIxyXZ4Ixy5cn+4KLX/WE6iV+/F+Lyy1PWSn3z0Gmh0mx+bbcTx RTI0CYX3oMUn3tblyDBKa31jNZgopml0b0HuGpSPqiZ+zjWcUfz8NoDSryL3bJb2WZ8lq0yE 4VN/ZFyy3Ul+eauRsnQy2+qw++hRkhcatPEIc+LU7fgzPJ8EcYvWrbQ06rpkpDF9OlXI0wJ8 ezFpqJGIkSyjyRIKpUoSvbGK4IlFURA6ayyHD+ictK1VkeLtq4FEHQlUrZcQ2CPRkpgH9cSp V9UpOZW5OnOBO7LPCvq8jRp+qTeQLpIKMvpCPcxulajRAYpNtEb37DX1EgAK32lWkqoN+VPv d+e0QUzpMOWmTR7W9wILVecD+bxak1TnE5InzIyeSR1sxLr1SLMh9aAE7jcMzLDk1RxSWhT7 KGMV6L9ZeFQpvDOEStCOOgX6MfPPnaTK8hHq2K4vsfCdrVU5m8C/yvuiJ4SKPhThvoVN77cK lcpxci7rVA3HuoL+zV0QspGPj57KwweD0AYavYj1o/jx4E1PkW9PlgJ6tvxgq2gc/A8nyiXf NUoVJgMRr/aoTbZABW0dZu29y4vNLfOTOoChOCAos9EZN+rvahd1oMtQOEoBvXibR7bhC40k JJFbPSlI4oE8Rw8ofujj8WLeSvr7eVMOlvQzUXrGPUt5AsB66w0ER0Lncgrl0ZuYFEPofcAj 0l2tC+73uBWjSqmD7QmHhKk/eMzS/WP4J5a293nL3ZIALRJPXHtubXPvfz9AhycsNWfjRe9R BS1c4dcY9VFbPWEyRKrQhxrUa11LmGwlzxtyXmZZpBJ4aC0Ux3ZO9R9vnqTn+ESM4fM85MiU VpY9QVt3Pou1Yev5L9uwKQBSVvTpgtg8nMKjzYcVCdXKyY4LkyfmrdqnEoDSScZuGlsdXLlY lB/em1z1UUH/DmnblZwRxlMFeKKS8UyJvRG51GNf5rfQz1t1KhY/lD6O6V9/sTFIPH5Mp7vf DMwjRN+9oevHQPccL6WP8kOVENOfCdhulsIZAgXia2aK4XmGQo42NqHIfno4ivqSrQe05ZaK a69h7GiIWDzK8yKnDBIS3vYIKYD8SDluu6DssOIggfYmcFcCvWTig5axU1gTn8cDeU13rnA5 1eow8MvVL6ShEha+g/ky9JTCLJEorJ22tq5WUBZXkf+C4xK9w5FFyRQiLJKGyKJr6EiPzsCQ hWVLoadx9a0wCAvaYKJlyUpk1HIT2eNCQM2ubxwu54QaZV5Kjq2+WMAVnvy5tlYK5C6D6BXW ID0weT1cjCuOPik4jC1I9SkXqHSpEZwiSMZnuotQM0uTrxTLLF91ZVPHMDrAKACgXViKQTIQ 155eQ59V4TXWGqADX24oHUGJYML/i4xB4fepY1IULv7mBIMzBXQLMENv0bJyf9SyDWNOR0rm iIVJd3S9O0lMX8iRkZKEEG6FytvppyvkDIbVAsTMGrRQ7/VXCk9h/fANCGXWm5hBue/5UrlT 263JBqFQu2M/9VaxZQyi10ndlDAC04iOV/77YL9Y/OjDv6nOL7GfRwrnXKKHefWMV7bhK84d XlQfTo9WG+8hRo4nEg+pxvswZhQpykSt1pVe/jkdVUOg3ffWylX9M2nvwQPG0ZwpH7OzL0TR /RNm3kIP+MYnuo1n47uIP0lHDZ9m0Wzp6uZbk3USVmBYJcDPa7NoNeSH3FIvgV6VjZHU7RH8 4xSkcL/KyZwyAnAx9PL/kXeAvMT7B2QHRAredHkYpZaYeAaI85B1ow4sfTjA4u8I7IKTRwtL CnoUTVprBgPxxUPe6MV1G9i5MZVQqaUoU6sn4nPKC2+Zy8L+rIPLQkOImhtvRwcGC/smRm2a bS+mjBfYD+y+csMSeQT5z9SMhdgzqN54+Kxr4ED07LzZ/x8X1NUcsRioiOVzsUFqwWp7GCQA SLt5ioaGT7GtZuwlGgqHrKNPQHivKzFz7hszJk9poWC0FO+1RD2GgJQxYoGR5reEMgB9eW2R weB/AddpF5/Q29vGDemTwdwJ+eZgnBA4rNXAh9Yjyx563yZ5lRThpdmmWjEeOGZJh3jUFHp4 ZsMOBFBGl5e4Chg4gjgO+t4bTBwZcEYml/4rZ6+1hgtVKGKJy3nDj4kMtP34JfkVNqXDJOKg m54IoAQIa9iGLmIDjaCVLRLo710U6a8BTTZ3HYD1IPgvwZKH2R/UMiTiccK2K6xMHckbOkIt IYGRGVnkKDv81Bgk2i56V1sKPUP/yBb8zxXTpSUW4NvqHxvpAC+XS8R/XgrpmOV/SQdj5jyz 1XUW4HEmmIG1uSAomcAMj+w9QHNFhazURjNEWwWUfmajwdu/BpzqJWuqkdDFgkuFwSO1mcue GFisBAxkzQoU+SuErCkTmRmKR3VjuWYxd7saP/BjU5jPQIJeCTHMz41SbUy/ICzfJwSDAoST Mt9EGZkNz+7GjRoRAb/8u9N93LpwEajVsfdgS4dQWyBFw4OkNQrdvJj1PgAWRbnssJKOAftZ ckjV+ltYcOwfUf0eR0tNq7ztR1Hk2hWYwhNKgmr8/fJClqQUUJnFErqhyXCuN5PRXVbyXwJZ oUFn9wOD/G7kxgz+78G6xSVGRI0xjXxMDp29vp3QZnJMEoOviaAK315yk3FkGxkx/4OCViZn abkUgeTZQnoajZiCtfuNlOeRuC+7zI1hFsKo2FGsZn7FmINivYXK9MAj1UYw+f41Uv5I6a79 YTcQ+lDZDkVixI03BwxsXMrGlCULg4RWNiCmW3T04viYmLHCeIjuhWTThhhhG0EXJ8VJIZff gsRkvSP3E85FKvhtDVekoTLng+3I2IDkVplCoq4fm6U0mHlfaGVT5232VdGq+4MS41qK2GQn c7hUh0rmMTptkYjztUg7LUGu+EimFUgRPtDEuI9Am38HcVkYCWjA748RgDScQbHqjel/UsRk V7+Q+TLYs6cLbdfgU8ZYjCm3Tz3vIjPTptmsItSfrUjFvKYN32rGl6IP49z77Vc32Sv5VDO8 r0MJohSqf0Iy4vFrPhN3LSIvGE7PDq5U9Gw75x6tSJTV1NU3bsUs1YaK957sxndxiFtBWmVA tHoKFLue6+brskXKmEvrjFFIMXo9JVUaq9wWi8MD5N8mzntOEL5t4r1rhv6zkzSVy6wSaccz ib1Po8/qN8wWqdbZ4EB5X8668cG8NxMKQ92GYnwFVd7Ujl/t2OTFnS2TjkRkvVJErVJ/9y2Z buYriklt+xgYVjZ+ubj35da6+JHGK+RK0jFvV7gmD0hH9o8ZpI/bqOVDF4+WdbB92Stx4PYU aeN1WAFsMGGRENxdvEmlSWm/bzn2NBxv6jUckXWjCGM0pxd469wmsvsyqOXwTW8q+j6uGaJJ 8EK+8dYX6Js7mIKgoU7dATkuaHcful4o0cT6nhb8ZLsek3zH2QslAvjN5mmdQCjHZOj3I/fn QtTVbf1KJusDl0I+CUPhux4d5sj2Yz7Z9svVE68kogbHKjk7ISAxRgaVJ9UBK8It1WGIh10X DJgOkVgBVvb/bJyFEd0v6kNTdJYliWdBjDYb3mbtVi9LM5FWr0wJWCC69olTfSJnqq0VACYi iLXqBExwIW7k8Kz5DULZfxJLlJB1PkXvrCKiJb4E/gz2NWIUk72DLHxwYNmMDrCDi2qad6ke 1nHMKgEwm99eMsY5+iG88JFeY8HL9t1RqjElC+v7FLmkruI+rMRVaLk53hexQQ9ASDs3+WH/ yXa2zXaHqPQgI5nfHpA8BGRF9BQCYsIf2x3cWH0g1664GFkAY6SgrFfMeDgRqhvQBgVrCp37 HdlHjth4E3o7g8zE15wKygln5n1oZROol7yfbWRsbjsbOajoGSl6MfnzQTRgbVBEycIyNDeN n605tPqzkePrvv8OjLw4xKY3OCKYoPyltG41HwcJ+kf13qCvwN2rrziEuNVzU0LVjjDMWf3g LCbp7S3l26O9fRLntK2CA+sZchtsYxycbpJTMvb6dB7SgjuqJwohusorTojzzKJd7rLcDHky Y6nrEqXhn6S9ZCHU20NmHe6B4AyxNh3W7zuGCBRx6Su69DtfRTxL0JoLUiLmDAjG1d5rFeGh 1chFxWH1W7ZCL1pfaR/zmZhQUeMZw+1/sgL41zbe3GDzX9oLhILx9v31cOu5OdgVuZObrjtU ifhtlurXCTgGiynlP+17Bn7ShsaYcbtSVy3FQ09ayIuSPh9VDkgtZrYaWBiFIaEpP3tQmI1X Q5a5H2C9TNxecB6m0yPH3NT4wBYqc0vY+/Vdm8i9X1jllcHijmn8dHrGD6sgshgESE1CeHGc O/rwa2DAFCN0Vp7Be8UCcEwLjFCm8CJZZB02h3gWo/tz19ppV0fTrdtDv8PYFOnGUdrbM6L9 DWcCNd8odiHmjGVMmvMrMPf4G6nDik5ziCyW+WNBPHpRDa2RRs/V+F8XvYhQG/1o8gH4I4++ 4MW61WhmnU5lxdFa+swj+x9o1tPuM12RnLHTwz1wbztUS8mOAs7O2fssZp21fbieGrV/v+cd YoPhkDjv0+0QXZDgN2nH4REckbgjXS0VF2kGMYhev+/XEGiqa9/cPKK75XxG8ZAX9VfUP5PG ymDH9z9zYnQs0WAjvuJzZw6cVJMzJCIlSRKDj58G4hUAJ+s4AunApy0oenafT7USID/hjaDp UugGTLCX8S7RwY9Tck46Xs8ChOc4jDbqRSgdVIwBqCeFK0O6LYqasPXWGTAHrRordGNauk4N hkcKFUW02v/qddT7ASR97h5iFPlRrkLHwt/FHwYQesTHBnrKknPPFz6fG7BeZLxNbDJnHGup h+iDwEzhqb0pxJVk4OmUhOBNjl5ianwQ9cCAJbJqBdeKelrikCCuHXRSqCs4Gm0vktuwmb/d ZnoUwbpY5NviY1UjzmSt1cC0UONHMYDKPbI07oHLIi/r0hyU4xd9r8Zutv33rdXeXSWbrlVk uGgxewbfFN0mfY7pOYeMJ0Om0nX12On+IbWaIy0j11Id9mwDFYMy/aLqph/xJZiM2Q/Nbi99 Mg89KosdCJE+3jd+2sfMt7tFZprLO7rUCwE8c2lLbFbg9f2mqV6OwjyyNK2ofPrQ0CLK8uQA 3M+wkMa1AIIHuAi00doSyJkxerFdRhH3NxplxediUHA52MSvEiVISGKP1soYvxtt3WmPQ8AX AzrlC80Z052Y8SgkgGfpOOlq4mTHdEvNLXH763DszEDhGbKE5lz22eWclVssrc3waDvNbPNt hFGe/1BNSbk3fjrIOioImt0KyTh+c6B2F/DsjaPn/cCBaeO92HD7QaLeLS+nVhRIKRz/hrAu ac4rrlkbEqHmeyA84mWQBkRxw7poKUFr7kGm1wp/yjD5Zd0um5nM6KyJNJSyqzZ7JTSjvMDL PkAQ6Q0qVNGgCZ2QbIAZLFlN+eAtzLlmsiaSHyFUN493+xxnZBoQCrDhAj1CasqOcCjaZNm6 jqP3p107RhjB5mSAi9HuDoOZhYIG9w+5ta1IExf0+/BdWKfsoVY/dtD4HusuX2IPVznWGndS gggZM6z+Eap8HfDFXCpfAxB/9nev2dAIWFZCVYReqPm6vNrAWjpVElGT3SIVQgPxzo9x3PWj benPN5lV7IwaysXHFh7EIbYbVufuxkJ8Y9f30m8962RgoH07WP+d8x1e4jNVAyZOg4u8VWzu nbLt1gX3KpzLw9c5l6slXMUgrXluEQk0+xBR+pW6Kj0JrC0YA1XgKO0bFTHShnoRyO1e3415 JrCimDT6OQ6CKkM0DDQOeJyqdT43PRiHEHYVMDm36HyK4wcrWOHmnql4463z9wPlNakcBGQv RLXqEWY/LOC/E6hkp9cbbMhQb36RldHEYhA5EUgl7WYJYwXeI+apWz/3wp8Bemh72deZgHpy J48yhvbDhAwU16l6fJDgtI3dXiMzVnbEGo3e6N5VqegUGGCA5Y2tEnVG5o32VPOhfIJtDIRd 2PV567cNE0x0icEn3ETLTpQhkAwTyFbrqKLW8hnb8c5kunmGy/5PK83DHeT1bX2IHeqexEvW dTE0N9E/qF+j2gYob5B5z5OCyjwngMIKJflOZSw9WYHqr9vAU2yuzWBQ+Md70xYC8+XaUMzh Bq+14OQPYwgpIXqiVWD6M2MKkHUNpjen6QBt1DpjEX9dqwPiftuo/8+ADV+yKneiICAVwkb+ VdJZXYr8JCroLQtwynlGPGWp0mUAT2Qmd4TJ2fJ63myju0Y6OimNOySyXSJmRMSYzOkgdUJc 0F4QH9d5tBOUAaGWXt4Ibjf3rg2LXYkq48oEaCPKNuhOBhfDfUfhOxVZ4g2fubV5oBjEfy/B xl3RT21hLkaCORHFoCrTIq7b6roQ41GrrqkzVhXTtgxbvFllqE0kRfp+euc8ljBYEiO04LMZ nNEcOnum0b/I1Ly4V3kcxrfpg3FxRh8WKcOaGVgQNj8tHgga3LyiBO5a849dHWj+lv5JVbdy FbqbfoShqSjTB8F++c7tcZaMgVtHqcPaLdkLrL3lnE+V48cwdq/sI9GxpPIYsiV2FBihxD4b aCwnbKFkNOxzEQXSGURc9Agu74k7cdR0/0sGRU1caQOpbZdp04L06nMTVb7nduGZmcHsvIsN syzvWxo2S13CDvmj/pDZcRwlKsqDW/jhVH2BSygaOmTERl2bn8Rk8aq2i4Q9hQ+HXhkwU1Cz W0BkIp45Bl2wtaoLH9yjALU7KWeW7S+mDAZhnN03VL6f27J6v1+WYwKGgCswen1EXRNjSYGb 44q6YpWg/PxevMfzRp5BR+wie2PO2PeTuOV1tXLrAR9gmkKbdoInCPi3it2yRsjt/4p2icke 0Drlp3UvHSEqwcQJNP1QXtSRto3Ee0sS0Jnn3uKGgdQAFUgYeexGK1xYQAaJhv3GuJgJEuhA Q7/fbPln0Z4Teim0xJ19DpxKe4zzUTz2AkC+k1WnjNZW5FekrqF1FGRclyeReRHeNpR5bjOz sORzrt8OxYoSZ069QN4vkWePZ+0VDrRSFLJkunbtfjnUYHyMg4rynaylr+jJeS9umAkcIiiB MZ4a0HORGsUBsgWKYbCRhJHjcPzJv9WsYntaIH1yq90IfgGZTnCCqt7SgL9sx7qfHqI8vj0A 6ZOn/tMDU2EUSIy04tIpapH5yFKWy56tlFl6g8LeNlW6DEnFvJ+qrFiBlnRPFGb9yc6clTHz n8nE6EHLPKjZief17Wz/ibRhx324vQ20cRq1ewFx+M+/UAsuPymZzBMDds6rbc2A9ai3DmIG 0bX7I6B7SuZvunxa9FwZsc8UajM0mrS8San/ofoSNW4k5Xj8u2BGRjtNGawHqJKSUF6G2i4W zD8tQyIS+Xhs9IALctQcKUslJMxgmLtoeWWVKkFG5iwbT/reLlIhUq7ydLIFzHdfRddoK1gE tlx8+uJ72aF6P/VC/Sf5QIXknUIRyHZxImDOA4IOyQxUqoaHDb5hMdZOj9Eoa8hX+FEdoIv5 2cF8FH7tpYmsGbDOD0yCEeEnd6n7FxWNeLan66JTbrSlmT3dVoh/ofU+haU8A/q1F22VBkH2 x+NwXwo8UeubdwnRvSigQzOvR92tPhqQWvXwLUhdgwEM+HHkWjwK9GNH9A5vXMopQVOM1kDA uVZBM2lr7BR4qQKBjgP5h+n3+gVu+SmAG0SPvGUn6Rqimo7yD1aU0eTKXqIaZM2fsRRTvJ8s 7Z5hPvCpY3OmttMnaAaZIkUzz7BholcWs7KBVouSJouwV+UEQbVxtYTW80BNJPmbEVhf3/gG wQ6QMVR1OXhhGee/WKEeuUIB8VwtOz8i+DB29LlKuKDLXMuZIDwy/hN5QxELe2chw/c+/8db g50jT3rHcaoMK551pjmK93GKWhp1vNRZKHWqFADN+BGLs9rmzFYxT8cZaBLjpqVHqTYLR0Si Orafytyh9UM06PprmnXkxGS/3LD3oKx8nP+/cTNgUIJyEcUnyH3XnlXc6E35uD81w0ke9tZU RL3QMSHclwKB8vxMqrfS5jw62cyuF07qYRPR0iyeswMED+qt6QlgD5Rlyvu5FKaOZpfU+4ZW lVMgbFKfXHpWvGhPJ2sCdCojgfiv/2OzHdirJpfJ92Aqq8F5/P8AmhunUQzZaaZfEfyx6wY+ t6Z2UXYlfsReL+dEQyCzhu6qDHuL43SIwz90D7tPXxwumS3CEXwldDZZ42WK9YYE1p2ESt8O e8iVQWqZAjCsGihIXoMwZCpID259P5v4NN4pvVSlpzoB7aaCdyrqjkZVvJuTrsMBN+fg9M1H Pvoxo/Dvu6V70Ys6ff+ujSBZoo5BBMpBcPigtBEsKO/eyrefh/yr8YY+7hQwXtXqq5C5ntWL HIgVgLny4IqaEOw6XBmxYS9wntNXStW+qeuiJo7iDzYR3BLfqUsHRM6vTOiHl7RC17yiusZY x9+EEtFne6U19Szx8YLGy2NMJ4xsANxJpy9+0XDUZHCx8dO+pXaBSExV/vQQ960b1k8KI5zF v8Chy9YxiASfS1Cszs2xt64QgMLm4uS4OUCelGt17UUZ47UjmcueqB5ILP0921d4Yxz+IfUi Jh4eheVEs/cXvRlUC5ypdegZe47Ifid1ax2fu/A+OeFSvFkDxEwSD9oeHAE7FhLqP2Ecdv2K MV3Zh8cHxM39UYlWJroPn6iTzqDbM1Tbv4nhpu77xI8YCdIKcdFR0JFegwf7+6bAWify/kEo HB/nCuGwoGrDSNWZvZa4G4Tifim8QMUvPluBsnAn9AC0Cc15x/Pn7ppRYpFNNMroRV2rU33y ++R1NiJAbuz3GLiDTm8c8wuA9372Y9Y2kkI10gmHaJLrRPSw6UiZsRctftoxOXpI0Z9NFVw+ SYF+gRyZ0N98H98k0jY0CvUGNptaSWHXEWIAvCqMPaKiZWnz0WhLidYrX+MEknAhoIeMR0cH 71z40VXh4awL+9KuWiwchp9SrhKMZRggikmtrudOEhs/uOTQdhqpdbWWRMiDWbF0a143UDqX 7tlRPL9re7go5ZpwE7qz9W9x6lokNyu7BDlKf4bycB5zoRvw+N9K1S9h2fAr39bad42fC9KT aqrapfUdmm+9HwT8hfHk32XSiqPAUvg/7PNfnbEAdxiyo8laGGik6vqtGkGCmAZsA+0c8Jm6 yh9wXwkbZVJQxCU7BlRVnnFCrz+iUF9dkAB8PAYz4Dgr2HOox/jRJSrhDJDxnnfnfmkPWg81 3aYFlolFANyjQRzGx4D3buUTV4+yIrlG0c+CrX0VLKOZXEjJ8l35wc1b23g6TmJVezkdwKxW hFJ6XZZQSL7wNtVJ0/IfnHow21z69NW5vQn+RU/dyN/ihs0Sx0VPGMkLFR0btNs3DNXyopVd Dd18o/l/YEXA9bLgKw5H0l7tFrHYujNAEyzfRpLkp/cDqYQ6Pz6p60QXfmiX3OP44hUdglWa GHCkOp7xsKt3A8S+M+mhpeUeBe6F6KmtaehYPKx6u+kms2ACJI/w3r/zElYOPW89+fHLrgLx nhWIQSZoEZcKbswuMsLYd+8Bq4DhKFVhqcAUG1jQ24OhFkEMys+0D9imFvEad5gBBaZ+ZP6x 7O8DHMnwY9kx2XAR0lc1aeJG7gg9xshzBAjB8nvTgfvoXclcDAcsUVD0n4wC3oeJnjwTXJZB bL5mUmdYtXlS3ykGCqKtoLTOb0vafURD/0MG8wLZdQxCkHz6LxCX4SyHnnTV7CtwRlnIyB1g +N6xlZecDLN8hW4ocEFZNuBMS/75CqQqrr6f8kh1ZKkTjq6ah/95LqV05gO2jYMARcwSAWbc gz3aa9UTU1lLH/WKgh6jFw0cDUoFVKccp6nXXy9PwQNz8MVPrRpHwmIeg1fUnK0juWZnNlZI 45hEbOiENUTXNUy2Xg29wmG2I7ZzIuIYTkVb8eNDEIUHBkfSC9RyGyPdC98f1XJ/8/2EzrOf 0+EkNuUxCIkcFGfVSkpwo/RECQYgxWUzxdLn86RP/Efg2y+Uu6FDN+Uh9SMvkFjuL4ky5wWB xhbQtR3UUw+kF3j3c5sJ8wVhDVKCTMAPCAmwuC6+jB8dWJz02D3mMKgxdvesCfMdjZFMzvop Ao/ZHoZEmR9JvGT19weOIvZkOhwQ8/stzvV6dtAR3nQ5cNoZbBaFZvbAr1/jflSCrfRzDzUm +8UBmG8/A+xMzWsUBGA2tDI+sD4JWU5f7kQj/TIBRbTeizpWcG1RyKPdxHIvmCHI1rLwLgOS QDQTYoXhhs0DQwHwfRnITUlMNxwjZB0JdM0kbZZjVGMm4RUvBG404pyX8pYVgSxLos+XZuMf MrNcqL9L3oG18z93OsfWROLrjOkgheV9CsrER8KPnEmoB/ahUY+pR+VXnvG9poQaJ+dH0bbA emuBymDytNPtRJsbOAhUJl6Sg88i6Yqku6pNwjhesOc/XJmfzAZKK+pjd9I5NQ5Bqn2zV55P CCZQd1eADrLufeEUTkvKj1gzVaRaDxFB++G7oyLw8vvj+0n8ZTJ/Umyvk6Q/Xv5bxWCGGvGR nLqYz+gejh6scgnMryxCiaCcPw2kU/rpru+fqsEKC3yaxwEWkKQHfeXaAkzuBEMb/qRi5Fbr qgWtFBW9YxSHx9XrNmx/OsR8aEhaSuMgwvxSg18JCVuTxPxqkRoOYcD3vME+tp4RlZvS5mr7 7zFdqQZ9dyTonTjcJdxhpb5LBww8X06cI7hmTjCRAWRK45C0Xa2e8I4EAG1WGR0HMd08myDP DpYzZ2TMTgKKruPkKvOYYn0EYEcIADYP7nWoe1htluEiYugQ2Dxk2eiJdMiV59vsbGCLNm+j eb3bbcE9hyfuxE5H77spEKLyNX6Pg1/9XtVFiCHZb+ENlwltNB5Rwk8EDGCvidp8jLByOpyu pivuzdUv5hfXeFtucxadAOHaqYMcB1MWQ+F7X1ZHIaqejgFYyc+mtiq/bEPyoGocVhZLHKIs qgXooj1HteEmEYPuxK3fnXvkDzQO7legxvmz4oBSIJ/6w8D5Ta64AYfHi9PflZ1pvKs30mfJ b89yi+oTjd1qJTQFljAjC0DOFXKR1ffdRskzdBrAbEIBFz4Wl0wpu2GphZj+/SWrNrQlqj1L zZFQZ3S+c3DtGE6sB762rEJ8J9Yc+IZlIKZRpuXR6V/b5cpKVbJPPNMWuaPv2Qlv9w4U4i01 qeMu0ECuq1nyXNxfbYCXU6qgrOLPR0D/1CkmnSR2GII2eBwZSmUmesyP8EygWNSPDy5Kn/tF MqpmAbHIOEypc485E3xra9Zt5fyKJulbr2P673YpBpFDVyH76O31RXS1xRfT7mxHlJCutIWb GN12b9jcpxnBX2zn5NoPFtmKG1ALZF9Fb5y3ul0pCm3DoX7QoTtKVgeOabEOq0Z4GbWIwu5y +DTgju+im01un1jNJGuguaCGJJhvPyZAAb9tCbqGfVi031hqTnJYOvgLMQVebvCEn8Znq0ia R31F0k95SrK5EFmFvh39pIdkJyrfzj0X0FexKkIajl4aIH17GKTQpm96QvWa/CUQNiC/XXHU 8b8yX9KMsI/RMfNmMZffu7/mgY83EhOg/fA0CnjxOnEEVyRmx1JPiMygLVNg7lPp2cQOTbxd RCNd3FRQJOGCSds0A7y7SDJ+ibQbLN0xu1Y+l0XHMpBYNWZsbdtTlacett15voGwX3YnO6PQ UqDHC7y0jiqc2pZYi5k0WdtAi/+Y9z85bwjDeaNPQu/stzlLz8WMGLbeIvqkQMur3woVpXUs eHbUYE/T42fCoi7OBb/lx1uojyQSJPCrjakLAFAGpbaKnGSaegsd7O/7wRFGz9di44prUKEd ScP9tiowBuRlEzsYWTMUgidPQgN6tA4tQX9F9beqLsrVC3EXj8UqGLalDHzUXAm04zZ6N/9v GWD4ugANQ8QrCc8RQziY7Gk8a8I84A9W0XvcdrG49EAhWPlJJ4rUu1NTeS/6UiGn6+f3rVEG +f/oD/FANkVl+5qKzy+UH3Ecs+kavEmCaXuZRehsQjUPeXoliP/6P/1p/GaJFDqAmzbKPdRP NPKmUI8Suw+wmInkVDbGUiqck+F1MSvzaZR8eX+R6SbXxSYxGNeF4GpOr+oZRZMM9cjMd704 u7MVYSEFlBx6qVSQ9azQUwlrt1j9WFgXh/twX9FytXK2LH6Hp0XonxldRLyy4/7+Ux3JhwKj wGkjpG/tvO6ll5IAKrPkLNIam2K2LpQxdw3nbm6CFpttRWmBPNqFq3f3R3juClMtL5lSiWwT nR16aH4smG1aaR0Vle6YYhJk+F+PAyWS+DNt+ZBommh5JqjWRTyIx6wJ0tl96dy6rHN7XQgp B6EfK9ezmVQRuUl6nu6iPcKfqiCscd4/VGUYJA80QJGqgUpmfcQGByvKkz/k33cc3+8O8GOf EGQ6cPaa1Z9VXtEsG7/KXfMix9kKeNOd4EAoCfT3LjgfvMCibQ0dkQociRkrJyCZnA4P4VNa QI10DlMHQTBWOsbkdmZNBBB98hGuyoPOA4B29ihba8nRnmKPf1kKQn+bICASsQU2lPj0/Ill O+0Y4iehwm+3EMJWw7YOS/TF9NXVK35YgqaQvkyygjUrC5qigifhL/PUSfPK3idHuBCjyDSZ X2QHAT77zIfoDz/d9Fsyl8JVk4Jq90io+l0WFD+7CDkZNOfKWpubUKkN++8S50oViwfOgtjy kz8Pf/a6EnnPYKeUwOpVVBHxJd+dw0MG2SzdEt1opNIfQ54mwn9nLyO4OAsFW6ORrLdgjmdw D4hyHyvR7ItGWewGc1yEUR3pZqzcgarn7FDoQYSZDct4BCs9Xyi749nzjQfj0jRq8ZbLo63e bmNU0mcA0FCrYHvYIuYmmfKWfodmdd6uOEgeIfag5IrTMrmt+nRoaovUzrNSMd8fL78vMSMC 6FHnrsbS8YTopE3ENb/Y6YQvSZ9SB2lNKXTxaYVNFhXYZnAxuGkdGxTLKOg8xHzq4lAV1XaE NXWfHY5Jla9otjhDfB+bccVRRf1hp+dHP+v2ACh4XZBVKDM6mQsmGs/yuXt5WrT1fjuhzOuR mbQJX8waNNsnU8yllj5heAnIjWaPd1uatOKtowpuFnHz6R3VBhhLgRZPSsJAQ6xg6q9ehfVr OjZ8pr91ZsjKFN756Nf97Tp9cF37ZR6u7pW/z0Ep97svDScMFVmTVl9f+yJQCjnbwQv30PoX fgWroq1L2/RPaFuIoMhPvzCoeRjBeDLgkGZ/Sqg6+M6k4LaoATLwaYzuzqRzBr4QnqG5oG5m sDYlGJ+kzGVhJLb6UGFVGx3Lg3phFS96On2C7L3YRs9tuLvtbVk6RaK9ehHhYSMbe0je8eDg AhwWpzEQ62gb+kB/x8tLN5NLGUK5zqjF7nlYyppoM1AzGB9XYCBWpu8ZqW4DFZxx93JLzAJH 3uQ6YU9awiTjdfm5MrXgfic0pzMTAHoDF1c0xpU97+UpGcik6umsqKexE7glHkdVmB6EJZxT a2845PMMTC346Hty65usZ+4OlhPpmZsVrOLyfsHaNxqsqs0VHT2ezhc+x4xRm83yOSh3fzVc ZgsKTWsrXzmsjlnb5pDXuQOkc4gvvGHUC3W5cqY88rjqbI9Wi3ui08oCg6kWyAKCSh6c+Hln 9Wuv+fzAAvV0zRYz04NUwenHJbChaRC2qEOVnMnxZvsVGSISWcEdO7mek+S+/GpNRReWYVAW FH0kHGI3NyQaw1JFokCWXAXGWltTsPiedJHDcxa3PrCHmzwEDTx01pD8olxr6ewpKONo0XPc jj4kl9vPgt2i8cK9mqXY8JPOypsYwHur0afVv92rIIN+SaSGLY6/UKCaogUYTsB1FL1A4hQv syqV6Cvb3imW3Xxi8owrU5YJs1HvtYk2Ae7dIff44eVUv57ratzy+RCp+yHPdkKZ+z1d6dJn UjqKUBVNXwOI9yAQdYxIYvXJ4a7BrEWuPxcfBHragxWIkWlW+ZwFKHnbW7DoCXCC49w4yWqc lBnT6pp5XR8CMI54diM2xZzhxC+GzqEFR5K9MPMrlsBnW5Etw2Ai4paESZhCW+9hO0Cqx2DU g4T9+hIVn5K4gRRyX9Xm/KljkypGM6ruuGyebPCNzM5mC5tGzXQlvC8IkzVYckSLxImHThnl FccJOBXPjj827qCCgk0ixZrYV+O+xZp+htrfp9nyJ8YnjMhV/IWnMBHovQE3qK2b9vC6hBsT cXCCScuroRvlIxy3DDj81c3xO5MPsyn7hT9jHHS8A539AYEXTBkgi3209F1ayIiQjdpW39+v 0zTNg26zaO8A0+Mw4W2uGTszgRVpK4G55I2gFC7OITfd8kYL+WxTetedFhVxxm0X01TqxlMs f9dtNLlnoIOAlFhJe3PknWDXGDQToVz9hMYsNk155R5tonBVjhT+xknfOYPaYVMReuV45ghc pHWtZam2fXdNjGLK9vtSBLwCNvbcV1o6gvxhBqKDWKCVsM/dgs88zrIIwAzuw8eH2I6MISQT y9/39udyvUwd+rre7mml2bsjt+5HfrVliiX/4oQsbG+bI+IYSXs0tCurs2ZsO34g0qz1O88Y 472Es9yTo8x1MDEewKSl6Bc6JhDOrY7nJHjIe5xWS7FKx9gIzrJpxmPpkdsQzCcmAyGo3keC uukYQ4Sf0pfGPXoYlGonRx0VV3aqtWkTKANj9KQfdkqnGivhotjGnllDcstWsvu/F52gy16Z qXzyK1mgfAhEYX02lnCILXKmV/bpM9yDxGTrzsafd8v7sn+Jej2aJcEgJVwktY3FHYRsGBHy iXUbGHQgXYI7g5lLoP1Ij4Yf5BcbEFtD45+mxk/+XzhgPU8o9GamBi5y98K4UorYqUk3GHg1 ctVfq5sVqYZbXTL/ZS3mZ4S0znZIamL9Us0NN7kTEoROd4vpWFaxBS6HuDJiGNRvh7NRI1JR 2ZAXpUG7ksFuuAnd9sbzBciQjQr7FJ4Bc7T/OaBkvdRTEaU0cX9DSoLhvNX/6opgw+uCZ+xI cLkdoAvu03FtAaGt0yZRVXLcQY6V0u/HdOnp6G8h5nz9hxJ4EMJvqRh0jd1kTQll3lu6Z3PD o7pN962QOAdBt1e3XhFmGWKO0mjPKB3vrN3QlWuhLyVHaAFIUxeeJKHlPlF8amL0hDZo/uMO K3I7HVNgLuAk+5jSt4EkzA73EQzg0fdeqG235wSqY4xrzLCqV/Grer+Hi8ItAi8qxA7YwMPl mQZIovIzoXepuurrrXXmfCa27M1C2yrtR9BTBvFyIrXnbM8wxDoTT/jLXLEuSrkhLJVe38E8 ccoQXo5TeD6abrDLxtSSNRTNRHIIasGDl88SRO/QR2LlDdiMA+LaEms7aIsKcsueUuTzDFaQ ZWDAeAkdmee6Gzw6Tn/a6wM0EInKRgeG1LMwW2al6Htd0+mifwenGJtiqtrk7pCPFY9645bg b9IQZDj2hu9lALmsVJGCqE/2Bd7teLvQvoqj3pKGcKbb/qQQ+C/37SqWU/FIpEq53bb+song 2FfR7sYhefekrWwVvcpH+TIdfb2U2/P6ZIfK2QBVd80HiZ5EsswGVcQdOwtOGugrVJEXirJs A/3cH6JlbqqwlBXpprDezmchfeIoIfXnNWj0bvtIjNNt8A2Xhb7089gkhT1sVhtz1Ubx9aUo WrTMtl6GMJ1YxA4M7WBohhmQ1riIAFOroVilIU59BI9tSgnmDh7eqA5Df+nTtLYiKKGsYDF3 bLfL+HsDMD3YOL05HuKwvaD1glUPKMptlBxMUAlTSoS4/ORImb30MD+rSHbpRBu895f5DeCa D5KyQAkWgFoFiEbMtsV33i21JFcKlpOyxvl/E3NsTUDqP3cff0SanO6UqzWKbTObtJwAsmCw KV1zsW2TpRo8kGuF4UNkPs0nzHKO7F4si5dfgj29WqZQs0kIyI/Fkt+Zk84UwhhTTWPI2PUr x0El7F4o7RXuiYuFNB8Hg06bxM7VZw7ddisBFdue3cM5taBoGZDMUG4fKthvv/u0lH3DZtBu 6NaV8SKPAotQUXbldiGcyDlAhGRPL0is0Iq96JVTPxP5rtTla5Kn4YPZSC9AIVg334ZDx6Id ocE0jbWb6rsYcLrk9K1qENg4S8i/Fm8fF70DvSXUdU4sdmNQscAs3YiSipWunflHXV6+YpDO q3kri1PCBelDDa1SArQeMNsz/6BFTAe7AYbkRuJctXRbCuxvJRA2V2/InKi8nrnRGQDIzraT a2WqZSQF4aoVrz7XT2e73K+CCUnsFyPBfg0Qmuxw6sK1d+KHDXeG8oFZ0+B9I2yvej12Bma/ /smH6pN/lNS8tmcqXGJ+ZRCPRNNa4xKGliYEgibry+KJhL3CjDabhiKgcdPvQgWBbf1L0WtQ iCnJcG0P+BVjpwRc05+B6PbDuuHzXT55zEj7LF70cS7YM9dxSW9ivKGIsCizjNX4aUaIA192 LCuUKMFhLQel2WAQnLnMnRSyyIZuCsU4z+JtvaMyEpVRRcsiJFy1egVRh5LrD8KZiuCRjXgX vzG5sW9FF1RHs+85y2D5Kl163VwSeWyFODmab3iubLZhh9NojbSWhWjkZcw+of1KPIpnLr1I u/BdQ8et6Mme0rb5R3Y8qloUt7V8ZPXgvtHImuFosI87iUJ/NHJKID1s9CTBac6WzlE8tSri GrDthyPtD5V8mBwhYg3gLinWfKubyz6kDR5KyygCoKCOQjtC5WzSGt3/XM6RHAzIm8cnItZz 6Snakp5TbmxgkAQCpSBkevDqu4Oquz6lp0gbPK6tYVkGJhPyL4Q59PCTAIg1LZVpbmzDBp/q lelPEoCHR4+EgV6D/XiWSrcoZdwaFk2USv5H0KyEhsIxoKJeT+aNDe9c3W9QfcT+TnMxHFDu ihoMnxpQhZFU5OlF+jDInUzP+FFUwnCvTzC0nf+9uQvtzrYYKP+VOoqOn29HFOVmqtJyd+K/ J+g2TTLgrQUQRf/820Il0XatjemM4vUo2UnXOaGq/6mQOS0LlaFBJCFh64Qh+Jm9VgeXFTcB aFzM2jPjRMShDrN7vZGyXGxQXz3/1BHcBKyRjxtgF3K0++Y/gngnYJ/Sl1aqBA6XlYZvqsMO xnZ1YfScSXzP1OLunXIjQ6H77f+XwGWWc7oTlAh4zYwibpIWZnPa3H8hlA0jRylwL02d43pX /as9wXxH5fSL/R6dS7Wi9ulWOBDSybOBS2huccYn0FcYcSL82AUZmxaSAOZXcQkKa/kbsWbL 75ngr6g8yDzYz/TCJGFP5QLYYg0HmUIwn+DaqQvU/utHWyfriFN9dEohfLCmwGAyzm1ROe7N 80ARReJ2DcVjGTYs3nhBQQjVLgbdr55kC67xJ5brno7X8NWs34IMrPY2Inb0ZsEk/PxDvbTs lGLjVXtqF/rMY6s143MJ113PGksMq2R1tHjdtgkGfaAqIbno74R6DZ3vMU+jIcMC2Cz0s/vX jHnXUZew0SAZTlEU6PFJW31gNYJfYXuevEizBHOqSt+tqzlIeZBgjvrDQzcMZP6nexoB+N2A iRxPcLPRV9d97TW6xuXMrIcGJi7WAawssdaWMJO7OoeagvegSo4XeEB2HYlWL5qQxTDpSR5E Zsi4f8GFlN9SVf+aXyH/0HCh1Lk7kRJWpoCwvzoshN00cD5hVUKo/0ANkPS3839sbFWTOyuM 86Nvw00BHZo00Vr/IKQAWNvaRWUjol8h0SDZwooA8YMprzhTxNkb28i0N1/nVkU4JgjPxrKZ U5yUDOJJboULAESalYx9aafIv+vuROoNE/2hhE9kq42iGXXHZksSp+MM0K3/qruwcHHE0m/A 2r8FSkgKBfv8P3CLYkWQMzHFa2jSH2FiZTWvKxS+MZrfjEMVHkgItt0N2/+qzJkW3RvpDolH Q2o6rnjSZdbTkHyDLY/DhBAXKQn9VEm+ND97sH3AZH/6eQ7xkjaNj7uBlDryPwIOxCQdTrto C1qEwOZ5V9gLUceIVTW1XkDGNJHW+QPCx8yQbwOkvcboo5mJIIyt/xUyV6DNNSx500SOiyAj HJexktCVZSDaAflDHQudcyhKJd/HPZ1pW3Avcj9PQYiC3Rwutx6T/LMQ8wL1FLQG6vrJkiUr RghyKoThHJH3dO3LoOTBC0pJirpXZjYriYyBprkhPfwCPDZLQFXPNJJ0Ed6GCZMJ87dc3E7u /Y27JIYMm+4oKh+upSDtAt3LO2nci/wvW81ok7C0xX/C+VFPK6rbZsaNz6hE/mLmKZMlYaRU yPgw32aanR+gJdRqoqniLrPUNwOxPaQPbTWqYT0wbD7CcPya3RaqnfyKjVlKbBcqL/EA7qR+ 6RODcxpBUG21wk/EuiF9ewIIIWqe8MdMAT0YQF6V0Joi48RkkP3pScARgG7ItgCEUlIKi7YG OFZeGl/ZwfqKYTPZcsma5NvCEm441TNdo7kuVpwBHWFknOFZaxRoM30HS2zmCPyYlFNv4X5z l5hOdpRWeRn3F1GFDHIiuyFV8m0Q55WhUaJ7xAU0JtIVlxW/t5fbdQr7w+/QJCCNc45zsxr0 1emxS82cKS6rt2ZuySvnopAjYTlwi7mq+VoLhNEiOHkqPYlzLAE5jqYHPPDbxHhXZwLaVrCW IFPuwIKMVPlOi22QraUH4SEFksGuLfrAl5OqPMFQsnB15Qlnr4a3GjY9VvNgOS1kv73BIxn9 Hx7kshtWCFkNLHwvBQl1TukrXh9oUDk28ZkV+AWewCoGMhq1RHIbwommL65Xt2HVvpMD0lSC KMr0TqtxipzOGe9M8jFgLFnPdUCb82Y20KWWjpXUjaVpg7vUPy+sSBogEfbWWjdDdah1FiKg EUmveRka+Ko5oIqKl73Mp7rCDoYM3PxCcCVwTw5T9DTnjnkoeHDbxSuPeb5OA40KSyk3/+mV +RglJoCmlomikdOfztZm0X2MC7xCYIjIyUJ6Ce43zWoSl2FCDL0P63yU6ddq9SnJ40+ekWFC CXUNJhfWTpW5v44n9+0iK5i5XSkNH+9SN6Bl1C+x7d6E2bJ0OqmSzXZMJfJ0VuzIqGE8+/wz CUX6R43hx8cfAj3+Hk/57Ot4JDd1D7NyMdDNX+/O2hG1zEkCjoyV3RlVzjpvELKVQzNjd5M/ FVeXF/Fgz2fv2S8GK4d8tWAJanNztfLaQOIiZOwX9nPvdKIRsSVV0xACbHhgdlf00EIInKQx 10cxh2e31/f5h5ik8Di6vug4zYZJ7zDotGAZdGwIpSzLaMnexxNyxqHCO6JSrJor3gaUvR7A vRny0F67yggZrNRwhsjoEINXaoDTG3dOR5GcEX3EjWswGvCHNhtB2FuUZdcDY5aZzTra3vL2 Y81oPQcPe6s7S6oSW57qEd30AaxjR6hQbfx19itnc008OCiBd4/PP902NrOwOYRVtoqch6mD dFAqfvHb5x2IveopaCH9T5GvNPf7f1SQi9EUjL6kBHnXi56JW1qdiKpsCL9xatu6jY6MGU70 7uWgDsHofMvSgXMUyEv0Siq0dvGmpKBnsi+9taOwQJwjCQeXARPGzGgS2hWxhbV4QP915ipV 003mvHBs5t4DAk9Lo/NMohS832OfE+ETTeBmLXGLo/Mu7LUTfrxcjR/mH03FLUsTFq0wuOWl ifVoVnHs8RewO3nL2KxaKMboPnS2KZFDamlpBQNF1XZLxozsHoWLqbPfYMpFB3iuk/XZP7PU 2kXZjPRdAhYr7zfjpWQLpqqPKHF8uvPbiQKFgB5RMy1LWmABcLOD2NjHa/5NQePkZwn+RGcC J8+Hk9xRYcRexWd4vOIAan1ieFqhtAjn/ZkWjtoPDLDJELRlwmAKu4XQdKt2rJIA7f24nAEC BLIDqb8qrZ/x7/FR9vHZXfPsC92bNWtfbek3j4pXJaQiT/V4WELQdRyxH/NsqO+L1au6PT8n CADWvEQ+k8N+5EYD2pem+1in5YGfkRetLcyT/jQz9YSD/5FmjuWULuXcsxTPvlEt4ZKorT+4 8txlDaL6EL6pHPHOYTfpSK9N7DaNz53xo1nmYiYmgx69mqXv4eEfJMdm/r6d85ZQ+trZUk73 U1+XhDByADMgj2xiiAX6S3/7JstQJdiEsKMf95cDpTH76aNtaa0wZRT9jih7OcxZUv2w8hsu Qf7GXCcN51omrA8CzNDa5gns1cNyuW+ehuq02zlFW9TL44V0btUBpvyqyTB2Hrc0I1y/LCmu 5rehaYejLm+Qgd4cvUg7aQvNUyfyO0jMaPLR1Q5ba2tk+S+cdBkdi2bjtOffO2UjZBlfepKx sOw5FZZu3gO7aiHTDK5+e8IcxZbemoLeXkBRZZxFY/llesvwI7eN1y3uv7WNvWl+dkF7SwSK MTa6cHrODuMvRSGUC5kT/DHSmr5SwvHBOWpwYL3wkytikxEZxr+NdoU00M5P4vV252prB6Li tZZLoYbWBAoTJZu1+aYHwqqWj8CPNFXlFMPrRUha1MB744tcPVyujLhql/wNhgQn/VfMpTTH zxdBn7WG1IbftlDeQuHCNJiZyJHQ9mv2/1hmppAEsrfvBI745FnqBYDpkgLEN1lttSD8tcIa 7+fYOoGlRNdyTTnHzgvU/RCL8PHX0fZt3PtBfrqpEuXxZRkKDDrPn9eOiiu5wN2es9O7ChoA KjkB5IGklmcFIF2ZVCGjjv30r+y6stoL1BaQq6HvcROE/tdzdsaxAv6NJwDIT9BPxpNexfKf 1g+uhx2x88KIyLoqd+pzyH8BB05EjJ00QhjbB42sxCemN8FCXhEfhJI+5mV/cTtjd2fxC3KY 5toruEtCoJnt/nMiK79D/kqzaOpRFKcOIfWpnB+PRFCwWtwvv9KcHk4iYhNP1sDRh015bauF 7XR6+ffM1dn8Ku2VC/MTTes+K28p5kX/6HiDOFmPgUAugZONJs/c7A67dITeA40zSz9qzgtK 25MV0NwWGbLugbNzFJ0lkWp/DfMNUwqd89f9VKJE99z9BkUWL28hzTaDUtnjse8hoXOZ23k/ 7r9ZvPc8BjuKU0lptDM0p9uUQSXRdDkAXnI6F0a9RoyVyaGJC8oT9q0G8yPhEgj8bqfxXMD3 szjzHJ3pPqPAryJlTbCxgOgareTm1ZlXAXCt+QS063+4y0bIQ7Pq7S0UU2c0iCa6AZZmgFT9 xCvQ2+89pDFF5sgDauytVJ9s1TKV77tq1Ex5K9XpKykjpBJ7JjPO0FEnk2BOuq+fDCyEzARH xDE12K/Py3GqIsldyxU0J+nl3fu6q5FfefrfZlY3uby6WkLKotG2Z+CS21yHBgXLe2Blonj1 UPjwCERK9urF8mBzd2yQGK20M5z+wnX2tYfFJk897uSn6qWMdpEYo8L9XBUZeHyxiS2n/Aji X/JWdmLBeDndYmDvw4+6YPdao2OQShmKRjIal5aD/oGxu/cENRduotmJ+On81W7EyjdhsMPp banYGsWJg1GwtxM/CD/oyzF4E90s5gy8M8Rz3FvpcNyKoy3BOrLli4GVtlhI8wFIBXF3tlCU 6YEgxsI+fH7mnNXr2xrNnsMsIoqc5cTRUnkloxCgE/zYrEeuxJXG5GjLxBTB+Oc68CHsfVrd HFsK6qbMRfnIYJK3kOGaIqO49GykhFQptKRmG0VlpWBaIk5pZ4Bml/6mDTa2Fed1OVhs56Bp RInrw4lz+rwyDvPwTy8Xo+KhCd+dkfOT5Xt6op8sco5NEqRT91Y6ohmPEYzkBeVjENJXmkoj 75p9W+HZv4eJekSK0QT6uyf4qU/bTTD1MY9ql+htuTJKecBlsjFdu4Emxkp4b5k6c9r6mUaW VuwXijc0Ab/Zkc65gN8Vlp339hgvP+SjpGo4XWAxkgqiCq3ZqEvRmc7ZDi3PhfqKI7r60oQo lCpJpnTwDjCwlGy4/u9fkYROvEhUqDrAQgh1maHROrHouZiq9+PibORt6vV1pjFwieFnhWO1 3vPJhZXii3xNW/znetTzbTHL69uNTJlSHQKXZ9YyEE7mUqrD+O2CylWf3wKpbL56HoWmf+LN MedkfdDRhDC0KtItCboJ2SzPXTC3zteVXwfkqWCUc4MfvyAjuiObNlAIpvTRA/ZwdV5Z+4UN ADoxD06M/sSFBp4Pv5IF/3uzPzgQmlfOXjaeX3fyH1Uwi1m1Tcizslu7FtY6L+JnV5vs3GQA splZLcf/02Tt3Q6vLIQDvHrO7tSvpuwRXz9nZke4DAbnQPmtXn0rXTC/e0N8Mg2F09Fv0VK+ BabcgcLNjjKg/grkonW3s0VD3FZIVSR4em783RFt4MRwJJ34LTDKTMXVO9Apl78KcJ9/LRV/ Vefmt42h7dkhdmIs6hr4TyTYh67BTOgDpbOdR8aLvNMGbFB0SautclCa8vLtkY86fnSe264S WSOelB5OxMvk0OuAVJoblUX6ry6woVLUpPT8dMDgv7aYmtj4z4muBaKrlxbwgs2zTj20BiFd 2d22U4KNZFSw8Q36GDYlU2Y4xegpTyoWjvN/OBWD4/HDALsXM72UyxgXyOR4BGTO4bjR5Uf0 /OfEIpvCP9OnUVQU9rlZDkFoaij1R+tSmG7W5HbcS3XMmhckrxbuFFaoLFLj+3853KSHmiXx kgyMJKFzCFYmapb/k93p4iq9oY7MTL3NIAZeVf2R5RcJmwtK4oUuYZTZglta4xwGSbuwOQtG wO3t86mX24n38D4Hj8mQedVXHVrLtgbO1IeRDLrdVo6LKLpTNZ7VcLGAzLhr+xQpXADJ8uT5 IK2QsIlR/AAftvPkzu2K7yJPS8BzRnQWSalfJGluM0haN2fS7PDC65JJwRfCtZD5f0ibSWk1 a3pC8yK0Erxl3sY+JuzLyxY48E4746hrwmmOq/uuvbAzmWWJYoapODnoXnS00b+XYkW/MmLF lvYlNEhU0OvGZN9kshv/h4T53TC/wfCFYMZ45vL6My8y/mk96qjjSIquovYPm/uqEudqC3d1 Fnw9NLxwY9ShRrtpH5UY4mLOYDTUq5sU1H7R/EYUCr/sKstroLkBQPzQSzpoGSnm4CFfb5tY DR9VVf6hHXzHYY3BR6USeGv9hm1qrxYsd03Oxu9dazO9XLb3Jv7krItgMz3rfEoevbbYt+5X ASPKbIC5BR4FLUzT434IIUdlVlULI4EOJGB81XS7awbo6bycUKID2KytiN8ZuyS+UKv4leJF +OLYGxqpLYkF1FLFuheL0W9BW3/bDvK4Z8083QfL9mqCbsn3tcsz6fnicY07Nf8mc+D6mL0b XzWRRKNFQgTNPvDBBoWoJxJNad0+IiZ3Rkp/9wia3g0Av+S4VMyoRAYohgih446d2hzRCd4u tu8g4wgqc/hxc0gK6+n4sng4JVtrk9Kdc4DkkbCb7eozgmpF0VLLPG/AlycOLZVlhoLussRc Ky2C4DP5HH5X+vztbFnUv5BR3YnT00MqLY0qX6RWWnSEdtEh9Jvq/BCar6olSXpSxNh+9HmD 8sqH9p4wZRaGpq+VqPEZ1+bPu1M3OlPhmU3aJIS41fV9p8b9HDlQqH1pbbhdg6dyctyVLGgR RlyPRkPTEKwwFJs9rRQRjkcnwB4eyhypbciHJgXqkf/Xb1ouGbB7TaZgYzsrsW0WkjXrtZIY g6RILpZifueGeAbcLmyn7ZF4g/e2UEr3xNnbPpr8sHfMfpo3L8Qxjz+IRlQ6MP4gaIyipf3Z hIkFbXMZMdvEEMAYP5LhFQF+1kqcdt/qNjigsTeKvTTVR/X6KURqpScqPXEbGfwRqQ3D2wxu 1R//6h31j0CQCRh9l7/TTdRwWfcH4uu4A88vh1R7w/DjKyvZy5oIx4Mqd0f9nlg7AcHrD6Xc 9GUNTE+COB0eovajbjmifRnVJLcypzbyZDQoBFqkpThAV8sCedY1hgJLYNzorhLzJB0LsnjC 24CbDCGRDhcOGPNqqYmz/l6/IAdIxEEXgAVn/XQwQz9xG8nSwd8/EoSVvpEgY4tXimQfmVcB 0XmrGDIxNC+bAD+i32mwBwa2gMhz0OoearSBmWsU3JNjCVJzXoquOl9ynZ3E+rfjJEqL2Kpl PmttBLEYuOjKCCYr5o/E11mmrHFIr7s1WaykFKHePRLiSJD1C176hOkETJ6RTtpYPra1q5Ga xpCm9Ks1jFY2XI8JVWeJoEAbLTBYDYq4oQpkufth6oTkfPYffsq+JYW5oGMT/2RMkFCNsVkC /Diux8QqEU5Txh5LbVdOyI5WbaknUHU5YeASzzWJ9BZVjI5Y19kRpX7thWDj+oJ/MfycWLJR 1ep+bWbr+OsUPapVDcCuD9rrxjkPp7yHFHZxqgUeYI6aLnUmYWPfOHcYeUFKUiGZzEPH6149 YfxsJV85MXj5lTSoJZqECUSRBQlkqUZct2P+fV7NidOLlj7OWcQCkOoznZ8etg3Y5zCXxs/j AC8nLuOrCyqXzLiDV5B6s2YoxUFxw12bBwFZxOVAC4EUHfZZ2lNvDlm6fV1xFYdkjf779u3o E+eo6UFIEMmNUwGi/SIBU8pKf4KCOAaFxjlF/Nj76Sa7F6YBf7bjbkPL+lguJvuRDgM5BpPg WfUC8I51JX3Dq6YJkdYtBoRXxJopT/y74ez59DZPdShMx3w8nu3ScZcFGp59R0Bik3Qwdw35 VyFA+5HT7M3VfJwG1Tm6c3kXDHPHOfaddLG70n1NMQir73iShQ/GFpiJuNG+24PhCbxynr3D SNga9cMmGzXN5Znas7NpS5xpY44BqCry/5UhECpanKiOzi7KnX7tGUfGyiWLFSloRfjpOf1h 5xKPaV59OwFBlU5VI0ZaxAfA4DLHZp2g2lvvHllyEVFhawZSoS56Ap4pmsjUMyaoTbRRR4g9 KxwA0c+jBbrzkAFHsL0aZ5WEuKNU32iwsFCfbLjpB9l6rAz2pJsEfDgHgl1Q3ONzaZA8fEaT FkU2BbzEPI4IxlG/RjQF6F+rVpB35bNmZ/2+csrbcRh7aCz4iKim7W0G5ENCRNN9ep040fkw 2eZbqr0JKTNKKz9L4LBk7mzVGT7pH6swq/1p8EjwA5QKTnCsa8H61CjBYTy2ufsIpRSG7baf e1eUmmZ1nSsTDeCiistkc5WOVHYi1IdLR/wdVEBk9LzqO2dJZcfeDNuWGzcqIYxP3n3c3LvP tr1F+gSabBXQ42rSKjs6EmuwPnvjSk26tIOxvpTLFLOLrTYs19t1N+j9hL7L/QByxPpm2zsM typfnCF/fcx1i8eM82gnPEebg9ohqEx6oSxF1fQOn8NuyIZl5ReHRI+GlR8sDoCZVeXpgNdY H13xcFtNkAO38HBYtvTaNBB+twRs3ecAdGPcmFS3f4Gr6Dj0hhuFR5bQMsABBMolzh+KapiV paQBUQjxiqbtAjW2wZQ6rkQTTz1h/azfTZlwvqtSaMEGI6rsYQN4EudzdasBrXnnX13MAdbJ Y4owEKbOX/rdgQFC1J4RHFijZUsMpboVXI2SoT1wH2q8AJy6waceAv8gTl96GJWZNVk+YHfU /XZq+/v9H5zxOu4oEAzO/nUjk698oOSrSM52IGL9i9NR3nNvfBHlkTcRQOecFMlWqU5TWW6Z gLK2Suie9F24M4sbFBHTUrz/44Z2CF/C9vERjvk8Yh7ZTvly/lrXU5wrSiM7osD9M1VeTCwM ymo1kUB4A0D1CAnw7d6VDs9XRWzBfFlLee0my8PCuyTg4F5bg131shKbLBmLcg5PyBU2k/wV 4l3HVNPEnpag7tWjgMEjLzvSs2tgmSYmadhaeefhCkfoNFRDve97Uutyb3ecw09w3oPw9aSz I9v/eAVB3l1PVZXD8r8M469lr4dRSL9ejD4kIAxRn04cTlFs33d4EwJVsJvJx6sfF0L58LJF fbA6ho6uf8vL+rzMnBkqk7+feaBOjlHjFEqn4wblHZ5JuMrJVUAGT3fPp5HYfJLYX85tThNt L1hsaYowYnugKeOw7PRdO151qSROTs7LcexlGk8gs7mXbKzZj+PNQXQz1o9ImvJwHC5IGaF5 PJDYYOZxn2d32fOFLkf6mT/pLbcZuIIbSykxQWoRxydqnCynNoZ040u/oh+ghPe3wfamo7na vnDVO3nxyeSQZ85Lw/okSg0ndShCfFT8CIY+fUyIclcsewpiWXj8nJC2Fc6opSaZj2K6YHYV p44CkpAwCsl/pmSjZm3DC47AmjS0KhMKiOu3sF7J8eNRPDfk+8GsSZpP3ZTbsOq1gmIyetd2 iOSLuJzxUN/r4Jo1NaxFYvvQ0HuO595b5kMo3ieFqgezQ9lRWxXc1S10fuH4JgyvBW0VkEWq Wm86lxl5YiAwxnqm11ZsWBwpYcFTkhnxcug8tYI7KF3DHYbBaz3M4gGSMFzbNKEKnOCKmCFW 6Qnz7om05OyiEfoJdM/RWrPm9IVPNJbgKQ5K+mRWvqxAYBWPyFXpC/bxIGi3/4kebaXm+m/0 toOdK34Zczf4TjbNX4psmJe/g4TOcldqCYMrQkuOho44VGDakz13HFPFnkTb1xAN4SqB2+I9 Je/YB3Cq0/ivQl/UKD9LVnKK6ibAJMPmdGRaPwIC0U88hL/6I2iQInhx2ae4KfTKhsEmR7yg Rgv+S+crDh8bZ5mMfyiyeWM+3mjl2d7kHKRYsOr7ADUFrmYlVTTi+BTx7o/uNOuyiR2ia56F Z+ersxkbvbhm1P5R5QQDW+onpUAE8b2OEIU2I6oht0hGZ9oE5OeOapm26fqZAGKvQsldcZtX oebwRCN+3lcRNkUc8IkuK/Iyn3GOBuo0IpmW5TLyBKn211pZXuNLNoHrRgElwdXrcrF8neY1 KJki5CscOe3nJ1Gxnl1X9pJ7JWPXeiWMbL4+x7rqHG2bbWsvEmpCeErf7cu9pTZaJgto9awe HVb8BWJZJx9v4W0LHi6gDwodHKjicvj9CzdclFX85yDdIq5r0+ldwS7rt82vI/cX+0u3sP4/ 2vONvKbSVrz3+T3u5oDe2aDtOCu+LlhuqW3YzyA6/ebGB9Sw977BYhOsQzOmJIIT8OL2ontQ wwLkXM1kYPeeSZiaN9oyjepfkh1cwjU0vtdzlv0Mw+9xMd5fX807JYaIHJhz6Gv3AO1lAnm7 RE2dxnuLw2R8Tq8Nbgb9F/734K7FowZ6I+vcNWeAn0QVsTBb0GSHok3i/zvgqY/jvAErLQLo KhGx0ElcSjKgtcVE5BeM3RHXpkdIo3k3cDXlR44oUg3ytHao4u96lSQxPRJZQeXSove8hbN6 y4+brlFebsByTRwkN9m5X0qCyYHTPTV4fe/rtqKFreSbFZp7IMEAcauQJvMxhINJ9dJoqdqX dRXdWqMl5rdKWQnIk6coOK0u0YF4zFCJxxugD63QCHQLfJ8IG9ZOJGfj7pOw/Tf6+95Y+05Y xSKzmw4Om+KecNqniZ8lag7YRhAqu/vj92OS+vfsUDIou7l1c2/smsdJR5OVDuOfBNMzAp95 GsK3OU/Uz/K8tdyB2wqXOD0BpFWWdI7SmiW0EOefSYo6vIbqzozUm4J5IycsjhtLpAOBExZD vaXQV2RiqIVq6/RICA8L1C46nP/FPeQc6NuKcVxRxdpFpFYh0ZQsV9RWIG23DytM1HoF7whu h2YTjcfPienI7NQZ3bD68QaU8ec3ogtLDMxEVVJoDWh8gds6eA/NIo4zqTrkaSohKZfmEGng LUSehEetkytkFKGsnK5a+2aVu0Qr715lm7SzRsouMUnitYIgBbB18qFVOnDb3szwWw6VoSqZ YFGPSzVBO8rs/YFhsuYIrqX+8iEY5ForfK6MOhUc0hSScRPIZowS0l26aNwwwO0JamxPfsgl tSyXCOykNGeoJK5dFUOSiQrgW0zIGrd8nqluq3MYnuJbv8A8neRz9khLL1Ie1Fsgy6/bXkJb SSfysYlIL+HwFAJW5PTI17CbYCJ812txiSt+Lssw/nNDnmrFZLZiDZZGvrB0zeLQRP30x27A lf8y4p8mybd2cp/sTT17PaRYgHNDsv9PjbShgHmCR+l5blkvrXN/JntVGffiEZkQy52bjXx5 lPu+C/gC6zYBP+Wlcw8kxAj88PJRo7r+tVwX52EohkntmKPCAhWH86QdCpBZ94qt9euh8TLT svgNCeRWIS9AgbcvguR60z3wOJ0xu+FiaQpHjZhcDcAwoJdJqfdrKIJQgwQtW9UGxaRpifcz l8QERwBvbbuLHggnKSOrGYL7q0//hT9hhHXpcMbjLKaHykC1qgYPaTU/bwUDZG8Iu1s5rlNq zhWcD9ODof/IuvJXA8o2HA6UC0Z+mpz/ERTUp91lCYjiBQxKrxXRTP0IZxdsKglKtMDnaJOa SaYBYFle07HhqTJcJs4RRTAO80ZGhQHxTDlWhimEfIqQrvNdfJDl5QYKih3JN7HDh0CUSZQL sdyK8gN88t5VpbN3DcVYvvdmBAAMbSs7Yk80QTVFhypJMB/gtCrJMEPO4gm2IP+HEi9G8m6n Y6y0qe8kFluRuVWJj92rF51mtgyj0JgI6SVkqsYumBG+Qj27noBzKrVKhzPfflz/i8iU32xK kcAvUHSobJb9IiZhqagoUIS1QWsU2gDz/Eb+LxTPDLhuscv8d1M72YaOYY9QOpTm/qGYteIQ vhc2IIt0hl1olnXCWQgnheBsxReu1Gw0l8RrX0ABjC5kcHjLXLB3uCVcB/MhnZBkqJeaxu4v aKZ3xhuXcSkK9vUGB/AcLTb0+d6Q7pWk1IxK5Trc2rYrMntydmzQ0YMBE87fSiznmevECoUm y34RRsUqBmBuz3iaCWQ5n9rHM0/ic8Toojt/1JYgp0xWYSNfb8/eqXnH4RDGZL33XcwBI9+d syY3OLLsHlC6Vba1OlrWVpBatpbw7wMngkmfYsjvtpWtFWAlm4xuqQs8NoyWpqC7OvvdEKjA E9yerN2ApK7LLz/MUK09y47PCvz8o91yGyUPwuMwwkWEaiJTR7gb173U3FoSdXIpt54/NlJ3 InqWW/I7Ph8iWMsLWKvbTbcAY3gCAk9oa8+SLTTDp/Gojdt8TStAkN37FTK+WpXIK59y7+1p g/quJyvwKtAar7RUpRiK8vTyKFNB2epJSc36SHFT+mn3huBr2xTW1vRoIM/S4IGCVVZ/y6jF vlWDpKEl78/jaLGIwYwzWh4hlQ2Qs9JYK8ss4XKzJftz4DB+XI/1qy6jsuHOtklj35clWDmT gsPU2+2z3mhYVdI+PUh5EkvwK6dv5DQakKMfiNtsAxzy2qnMk+P+fs3tAW8JRWBavOuI5DtU q/aQdIlpzTgjliNHS2aBRISqMagcLc0fyZrHrLM/Maj/lUE8lU3SmEHexXOkymwolktYRzlj GcT1RpSd2hOrcgkYeIU2ua8bdY05efZRnSj47zY+xMfzhQftvgqOZ9PTgQcs1zMzMhMv/IuK nHY4Dd5+ZtEN42MhOMnXLh81HNfoHET3ePF72RpUWeESIMP+bs73Lls+sxLOsovvzHgbPLJ9 NPl70x59d9+FCIyTWVyNtdXa1ryDj/f+B5lJraJvU6hckafOUSHUNG6P6B6wVLnceBi9c55X UgQSENlHggPKWQmQjLmtZNRYHFCbj58QXgUCs3jCTM6RqMJnG/KJwTZn7Gu8bVvlJJoOTAHA didEOtdDjvqluq7vHmBHEs6kzCvlOiXVIwUT27NbxAuSjfN/3yfnvtS2W+X96M4oT0MIOKu7 qJTTz8iMtW7/grEl8u44T29qmd1bw1TdO4aaMkVkp+qoHIWu6nXI8P8FA6ddxDTcBGL2l10T mmXokfH9F8w5l5Bn8T1aFZrkcXVmPBYs4W17YJvQ7YUg8fFkehMGyVUey23mF+NMMyVSat9J p/lwvzTsmPWoACetjgU3+iWtCCb9qByxAW/myXmYiraW7cTfjbRUeFtqEo/JJgKpevaxfTu+ oYinix6sFGUNy4KE1sAa44D3orLXE2CGWcOFsDWsMH7O6s7k3SnlG/ioTUYejmvtlyqplyd3 845YVXNYoAxLVnUs5UuGPhhntqhDDNqQt1v/rDqXEaY4CgQTpvxX7SoG8hFxTgmt28Uoa/CX wrYVbZHx1Q8OSpJE61+Y+wMtAiDc1xz2dyBJrChsGha83mnNKuaTxjQEBXDtqBkx6HSfZbTl h+9sfNTRqCoV7l8idUH8gOUgLQv/hcrkmF/aJYers5ADeKbWgSARMCo5nftgQ2i+JVz10X0/ rVtien893GYTwHBDHKs0fNigezKdwmy9S61dvUTpu3BiTm3d2XSCqyuHcOrNe3OX+rCYVr4F PnoQhzBqkRXaBU7/N0Eg1JMWs4NkQ6wjJGvn7kFiiApkeXa08JOlWV2GpxFm4j6nQgTsML0H dMIV3ao/+GkLAsHvXovC0S0kpoLTncLwJh0kAUKv8C2wjUtqHY5db+F76V1QaHS7QDvMQoXO WoIEFaesB+KiF8q1xvTcAfNoiznfn334YxMjK02oXCIXL8zNgLgjNYCGsiDbcgAsPkIZntDp KQxspyyKtJICXLv6HEFYdjQDsrjdkJ92ONYvoJxDNxW3alSJowe2N8FkAOZWdZ/jdOteIJf7 C+VHymMzmxoDELZfQAPT8HiXXewOQxOTkWKrArIk0c91360cP8M4EOwckFIuIwuUQ8x4bVd4 O6r6nGbyhdvvVH72Ts5aWppnzIiImJbivtRUvp3LPoX3e7dypcshoFscz14wBK6jdlO/BH/j 9cdjTU5bgmnSjNwnZqs/kdF9u+uj7R7xf9cDFaAaft0YoQgq+ue6FiZZCL5JQHWo42rPVDnR 5fkLHTsl8tlo2ukEvMqHAgHbg2qozDLRVKjiWEeO739hmp/CiOsJ5HATAT++dpjHzSPYe5ZV xCVEu22lOj+22aPImKTCyP13u2kV99+REApRnXwujZz6bEmFjijnkSAvet0GiyH2byWFI6ii 5BEnRQTzTDvJ6hIkUopgBsLAmvRsjGX5NHKipw/p7YmS11Qpi0IjKDKFc4IZWybx+hlPfpsD Pr0XoC4B1Jy8I9Ml9UyoC4Ol+Kf1+7g0egzDgQAh9eZoCQ/hQOlHfRnUvMeI9I91cEufTITL 5U+wQnTrEp1+/Y1tGs/k5aLBXhMXFonClCqqoSu+EHTB9Li3vMdaUfmgNImWzSKgYRr2rPlK MZ6HOS78pCcf/tjUvV4BrXaWXsjvXImkKt5biMklGqk1QiuukCbPe/vt59f6PSmPxlKFe6XY q7vrRi+tv9dXSK0qXxlbg9bU7Z36usYwCTGHTWuM1pp51l4X9350OwzYRWlvIe6qLeGgwmBr PnfN/h3jnOeB/Wc2p9HZS7vSPpnlgTyPE3T0qPGcsxqq5X9NNVpBv6Mm5mgLRToRWjOVw81T EWGXXHpTbLjXcapkVHPChYgSoYSRthvNtc1ljztD62sugC6H05WO37hT/TUgNomw2Sxp/47/ wwSJ7HQZhq5QxnU60fzIWwx/Pe400QoWY4A2OMXelsEB7XtEABbn/HL3uP65cX4fwQP9mBM3 /Fo/GejEhdtnAMmT+dacyr4ibzufuWTHAre/lZ0q/BOYyMMyF2GBcLt7kVLfp1o4RR3cbhEO Z9JMeRopmBPNxAlAYW7SDhfm0WyI/8lJWvEM2/1PcUSvkmYnBY8ysvlLwUfUqeQ1fLXiCle3 T6tQ8QCH4leccmCDCDDQ0TSMPk8agAylwxew1Dh2bE7xU4gmiRD5OMOD4Ioz8IX92rABu8ld 36+LxnXL8I8rU3gAOSSd6uzjcNSf2xYFAqbOASOOqMZKvGSq/cnh0PgWuZMYmnCL/T2uka2h HCcLsmujXHyQ8/JxGHQDAnbMqLZ8gxOaCFHml+miSO64pcH67LfHmaXgyo7T8EXTtgFZtpJo bfhtzaSDf7F0maooOPfnPgDrlH6xlt0e6bTO+VQKYCisdL43nsXp3AaO3281+69f2+/9Fqb9 qpa7SZLIgo/xR1o373jzY5NpCQPnR1oZeT8ackB7R4AmShrUPTwYxCOMIdPzbh9L31fvCUQE LJMtE6o4wWcfqctqRS934t/x0Bl+CLJKQg9rzfwhrD+idyjKti7w2VDMN9I9y7oaY/Fo+WHQ nWKusPeLXhPi+YD7dl/3y3cjcQfT/39tzQfKub0R9dtZfo8DBos2rkGyov4BU5Wup3TzVEw5 GIxA+KhU+3lhKEM/upJP1Qe+RXvE+Osi+z0ylPKdNjbd/6RT7XjV/+OeYNonOhiA5SKc0a/w lSU6icyDCTz7lp14bScGq/GQeDFb5QaZSVV5bWwnJHsB6EaOU3hVuziqIIiSJBOMoHogb32A 1IxnKAMvcKzPzPgX5IJuwKDuD7UTCAbNBT0Lql4XYRKRpKNgY4Cbhims02gemeTlhAYAgICz W6SqICpgcGbR7qgVzk19bHB1gsi++gAc6voZHMFWGczjq31GNofmbTzVIlu+57WXc4Oah4hX sZ9qPusPeamD4it9XClURdl/2WYGlGMjOTISuqipZQKUkRUZXywptoHv+xhBBSpWnU94bcsX jPNiQhSsB13t5SD8qleQCXZwEwv40TsnykiwknqWc2FI0ihRRULiJjntWHPf2cleUaTbxXjS xlX5gq43RCeNBc4KsUbG1LfEMA/atflunGF+ZD+Q9vu3GwnLvbOBq9Bbh7Z/D0NLNKkSM+CJ I1SO6JrfwGqepV5/ASsQwJsRYN4+u/Qxf1F8lrvrjgYEB7MTWesyS2Egxh/shDxMYG2pRArU a86eKOlYobOurbCCqq5TKHmASPrUd6OCUYoEEraPzg8o91UTkc3tQ6OB78wuV/jx2/kE73uw 29VOUQ/5OOpqJ9bZ28kl3kPV6+WBrGoogq2a4qQmDO9vzuSTuzWHf91S/fm5cN6bon2+BKVs BNc3ei3IQU1cT+wsrW4jtXsltliwlZN5pIp5FrTDE9PYj3T6mtSD5sgq+DFDDZ8PzZxgHwF5 0ztgF9YjvqE/IfcDysLyEJcx/lmTYIp94RxkrJmErduaycdftga4V9QbFF+Xi1AVd8znwKdh OWfYhv16PQLhWb0gowkV0uoXvFv+Q4s3fy5Sdcj5B8a61JHXChBO74walnbOw97i7/HxBErg 5wJIUxRCyEIvA32CZCaj88XH4HDKLSfM/slTyplENf2IbSfp6stNK8/QyshHn7mh1Wpj3rCK oAvSRxijb4a1FTwIKFOK7XYasee+dtzv39GqrPG1wu9jJ7trckjR+uQ3UUPS74X6Dxkp1rQB f712TEa7p9jXx9pkU6we57q6Xd3aPPGUZvpFHguH1oNjM5oz8rHqMSjVeICRHdameXuU0sBi hWPo6Ocuq8GanSkCYj1TUW5wvnZAp1jcATuU6RVPBfWRn6mv8xWw7nYEhcw0IX2PVcn96P6h FyyXELRx6Uhrqt12u9ZYotdryfUA4x+1hRY3HAI0UQV7VAAKYAUC1IJXTaqPL8luJYqUx0s5 AeIH0fhD5FkAjjnM7Ydebs0+YXhs+MlAvfJmbqBAb3zAQb/pmMUn/Z4iuwEwVo6jB8WzC6+L hGL/meTgY0amHL6fADMCNUOvxKMhcGD7eN/k3YOqryhj+GNdKsvehd8qhSBC6usG/dsumIFR zYOiJTLBCIT4nith3XJL5+xoXmXy33euxMWpEj00ZCCHCqST5NQDAgmgaqp40AKtbj+XLJdb +diN3jlzTCQzcvUwqqhhiiaQoilP38YntTZXcbUZ3nJtCk2rUOooaWLRzK9nVpLdJq9kqdYv U7x9WbNosbhuLtc8EUeEMdu/00S4KEPSOAjM/Pji0vooYklQzJbQ94XzBHiSJMLSbJ/8OgFf svB69ccEKWvdc/aKWaqmUIu5u81EXKVlWigXagS7dGC15gtdVFBHr3M5aRjlYepJGe7w77wr QFWXh2cOyYHGDDT0URau7mdGuzneOE7RNV6Nl5ex/t0PFjd7e+++I87oqXZjzccOTbU9dxIY 7dSpzM4Knk+8VRA0FBH9oj1VQlLQ76BklEqqvLM5qcxXvK52w1DVBjRDYmzfa7LZXVxluEWs NF1Uj+BTcUnbw26tYvECi33Oefm93ImZhPRDM2SsojAb8/ApZt8v8id+9tzPvwjrjiTD6CpL FirZJw2Dkzwa5OBh7Eul6KCYlTEyS3wzen1KcEaLJYGvXgaJ58FhYsgyv5iOOIvQHa7wHoZ7 Xa5V8OsOKN6o4pYxsTiFjLc7ZIM90BK9hkPWVZHhC9fYDbWUyQBpF482+LJdJkEt5OF0eMY+ ct8lVAMZTJikT/EULuzOi0aWFeek/EgOqUIKnD4CADqmXfafwkfyItqhLk7PJyBYl5K2oLyi 5lEdSxRX0ttpz+r9uqNqz5iMalx+hegzw/BaZtz/6vMPB+CWxJYVLLkkchejGbAa1fwhBHlO N76N+LFMYQORuhjasgQmXiYMdoCm8pDOGntU5pRvjWd/ZNOjnQYe/gsLr+0Mx3gnA0/ZzbgR YBEYUAS+AlfwgSh683/mGSNddIrr/4gzRfpJEUHGC2S78dh/o6V6RMVg6DNjiqiRyDd3Yx0X vASdddmJMjE6RPaVZ+jmAnt2+iML8SJ3Jbim/9xGddHP+VPm4S0Wu2qgxKeOpWx2a9QrlMwu a4uRs3CNUG3PNgd0VgVtRMTYPWbpEbBN1aqt3hbwEGHj+75lRkZZLNZ8IXB5wrVK271LJ8fc cCFtAnR4eLi1dltZiy8Bi3OmOf6eW8407rfqQgRjWfiQXzYZ2P83OOuRqU1mHzLogGUJlYZH QqnA/DNCWugTEaUXWJg/Q4P+f+JgisOxu4Qz46C8Uf57Oypwx4lziXu41O5W2Cn7z11fjsHr pjWdKVdpR1vb6wEUcv11389SmklOqdj7hoNJUftGalpm1e+DQcKSeMCtAv8Q7rL7UWHwyOo8 I8pZOqh06Sr2JMFvVFrH2wx4/ot2TpAjSq9DxaLtHpnwvdZ4ACASECSCM92Ev/OUcN5iRd4j DH1NNqW6VBXMZettHYvnR03oEPFus+yhfBDbojm3gapuBCvLzY8E1g1+ZUFrNCPt3HDYIT9S RlvuxlCQ5E64vyqQXDxSZo3dCoK7XGjZY9t0jOujR79HKtTiEX/4YzB7CTXXQEe5U0EvdNQ4 3IHlem6U/jx7HLlcJn+5bChUYUL7rcvuI/SxgfGR9lF0qiEnAwZVjza6dzpenmPRXvZXrcy3 AMJk1ybmLHKCdGCGnU1Hmi5oM/1zt5bg17taD/s8n2VZXIA81dHZQbpEkrNt/q84Hz9nXQ+j WGPgmM1Fzgxx6EOScClIBSgHyqDkHRprGohHiBd4jkwHjhwIHnjCpqKFZBKyrmsk090xgOR/ VquQm5DRf/tyFBW3UGqCVCj1puqrjEF7hB2v5XMJUCstA6VlzP7BTqIcJWS6Vt06gcxw+42T iOY1O8VCDjesq7vaGy9sH1QavepMVgotQlG/gofoaBPQ3sPPQpBt1uvVqCGOVgCzJu6TlM/V Pa9Tzs6V5CB5K6OebnKrsohqscsGGNAh6xIz+M622kvD94RMVx+CzwKOq7Mn5F7fRB5TIkhO UjuaKyS5kxUlh+SLhim7hBaDIIoJax4VUIJCGsbRuQF6UZwKnvwN2iY0aGjI5di3li+VDLbh qIIMxxtj7e+Q60MFTTQP1ak6WuCrZt1y34owuRCb+xlYpwbCdRrR70dpFEjx2+RCt4r0zg9A SFxOB6M3FCjMwCnlpYjsyVr1UOnEcg2OKl+imjapJJmKWcjvo6XazOEF9sTKuhf0GkZ51o02 k5A16HAJR2cVuzkkfHfZfMQYNaPmYtAua6WPnMbwlLf+ejpKMxPFIQKzMDhOpWWUj5dUwAe7 Ak9Pgy+dt9O86MCzN/VsjAu9xLUXZsMZZxhFzVtJ2v2gURPMwBKWz3ZFSd22NRHbA/y0rPO4 lnd0nSaZ+HY60QDWw2BXc1tLUjxH75dkMdpeGj9sNHG0Su0k1P2zwSW4Vucs478kGv6Rdvny 3hHAfFjEOEGKwe6w2nAw49EzgJfYpQ8yZx54R8/tIZwTcLret9vSsWkyHMP/4mEgoz6EHT5F GrAyYsMkpquaWHhL7Ew4zCZD8f5JJX5PGN62RHsITRXDm8Nnpt8SM2CVPDdqkY0sZ33qzLoH uNfMF+IDVuYAHKnF0qn5DkJym6i3IslDKGsKxgq415ybx03Q5j+7x4HwbKdWAm8Rqg/ZEe6t DGYOD4MWXbsgCI1qFWV4lfPKa65Cb03tuVnGPfcal5XJkZi9PGccyCGf6yP6a3mCJqo7TTre /NTExTjfvtaW8ra+n0G+vIdX/0E0zVxQaCpVTowxHLK8V4CYF/G+SPsg1AMjQe9kje4wdSac 3GR26L1XUln2Zwi9bpzg4q+7cx0VoNX9w5fLL0wr7qHlYtQPZIRp64T1//qdSVuy6NF0Rf94 M2X5IHbfP5Or5WUQSTlAw7jz971Czyg25hoEcihQr5kzqPI60eHWV3xXSn8Oq2k2p/pX+Gm2 N5q4KE5Q59OMcnh1ZFBQIyRUaigUqUphobhKHlKjVERSu+aV5k/NtUixpVj9Mnukj7oU0JFa gIqnlYQTrGHGCNhLSj2VwxB0Ou5SDlz6ONy067ywn8QqAKGMaCFEZIJIe7iEpZl9jthQKco4 gKDWgrbKgYst891pCB2z2BD6Ub5eQ0pClkO0IgR31NxLE4poIfrzn4mAYLWkKXTTczfFxxf3 1/RIl7fdi1DG5jGSb8/SN2kshEhYW85DtH+9iiWfAawf6CnDV5/87GeaGJc9xXLARn7KHaYi kRJAR8fdmTOGWAUZR+2FNSI3LQzxlNRQvvXX0tx4X4Pv9tOz/feTGZm7pNe0zybMjTowEEHH dmbDM/4QZe9utKMnZ+B3SFQmYvIqs1wKlh090S263X/DHz35m0rQk0KJOyzqRYO4dZ/2GFzL 6rjj7/Pmvv7YIes4DoG0CAeRsvwqrPd4U6yoBivxZ42N/KKEGtejGQ48kQLRW9BGeY+tmsme TgoHd42Jj2XyUEb9ltkjjXtXd53HNyrkUTc+BQK2dXWSUhGhDYAxBFb94lsnp6qZXD6zhNyE woTF8UCNVKNpzrH42f5HhvElS56i5OQ7ba3UQGJQu50eE0Xt+rgQhszUUlrN34EIM9AjYEwt /P0GoCCjwwcKbdk629tWQ5JXc9PwK3QgVA/jOLhiQmKbenvqtQCj3eNc1XUJEi6roDsENRlf 2SuFkeXSWJWNtjjeU7vUenGuFCiQNyGqHytrjWGZuEJ/ZL7hPCX5tJa6YJd0Z5B28ba3N0D/ WCnJDXo2FzqKClLrA5gBTDcacconRFs5N0Zxmy0HLIgiNl1cwWCdIQ2arW6EiDn+FO3wMKIj I04nyNIE+7x5b6weoEl//f/ZEP0lUj2UtEyZx9p6lY2rx4S7ecBP8HX0RkBWkI4/v9cDNUf4 Rs9/oyp/7g/X/XIIShMxEIf4A02qdpGeXLZH7HobMBwS8Ihysc8ojQzl85s6VtU5qqnXp9mW 2yLpxzc18NtLXQdpJSprBWQs6vUbur96bQESm0YaarIgfXUUpYuDicaLiSW16+/BYOPnFlQR S/zz8e36MaZSee3zGwaEW9i0wuAIXMkV4paRz5DOpeKz7KQJXiePbXQjs/hMFmLW9OJNXedA q77uaSX6WV2ZBy7lQXmraQeDDJTkbOkdqtqQPgdBmd5e0mkMeOF8FtTZ97gbG/OR3/eRLIvJ 0IyO8fVZmmzx3c5eg8N2WQYAZ9v/oGMNhOl65TXOSboJ+pkOdr7DM5X7UBb/trzuth4N3n+O skMDj6cHsvhtJ1SDIM+5NGBNkUuCaX9XAcDdEbxQBZ+oATm3Fh8m+f2d5gocWxt1KhmRRb/1 sPB+iEcvTST6wv37wkfJjq2N29hmGjN0jEutENqrcOJez2Nl50S528xa/TmM7e9jh+b+tWmt yBu7QI6Ooh4Dvn+EA/SehDmIkTGtx33BogYzoqL5jIaF/725Tpep4QjYugwX68zvdQaDwRCB +JF8lsLtbJ7mcpj2hpuv/MA5cy6a717TE8szxeLgYTZ3UJM6TTrp2AK2H2t2pfGnq9DHOGPg eI4yK0zPie+MdGV/wkyLoZ+EgD7Z0QDIW4GmqbriadGIm3AsSJh7wTLTbh1dUi1FNjQUlasR 6Mkc/ZsnfFg8MiFgeY9gKX0RRlXm7PKM1yc3jqr8DeSz0nltYnvLWSfjvs8XOx7BgFmzh2PD 9Yybh6u127MDiB/XaawmhFKMfJ3asvwK5fJG1fiCtglds8k5xsCyiVGI/ONAIV1G0oJcGfqt GGvx/ZzoyDC8lNQe9ArhegOVWXmMZ4z8k2mddueyHr5FSwS8UANm9n/gYhKhP1YC6wKAaNA3 7KnusVLDkkBvC+PKWy0VigwN73V1KFl/PueEj9ki5kFNCTYf7XNtFGtLxJ2SLCesX6kI4PGC LCKeUF4xPzeOztDgBJ8IohHR0qJ1LDWjEhgfd0jcWLXY1DyiZnu4mD0Cc/H5jukjkOLQTVvL XDDqRs+Z6zY1KvO6CDWpExCcVydnSyCfhEww9KrZbn3k9fmgjB/tvypyZNfECDJ/fC8BzOAt w4mGu5EIUq2IxIi5EXxydIVSpiMDRVLHVPlj9GypA0lnNIQVSqbdFA+fiHIT5E7Ww2109VlU ci94voj+xo+9gCPiVD2PJOGqFks8nXiazjSQR98SMccqtEimU9FQQU4ITqBMeYmggRtaQYth jJdRYefx0H/qrBVe0/sT3WYQ458Pyfj7YSmXrVqG5/LqcFfGDMCJTz0uSmKGqzIate7t1+dV PdIcKdSnIJMsA8aQ037lrvFpQw4rjkH1IfKmblFZ0HlSBfA3IsEhK+5MXy6+iziFSTxLccsI r7sMpdk5EPS6KVKcR072rj81wk+73SFFx7DzO00LPIDUwesZUmOPWumiqheay1QdrVJZF6Xw 0DT/QE6pzCbGF93AVmX+1ohwKhYdjM59HnJc3VWvdKY5N4ILzmaiSb6NFhuqZsW8Vr7Ciwx0 Y0URLqJlJjEYDkUOst0NTbNGYx6t9RfGIRevnpRZf7KMNMFxnw4j+bOXo434fL5Ul7AaNgpE E/zOBnW2LEH84fXGIFV2+qwM74oCEH6M4F0+IwzRpweoNcJlhHH6RSFZm/dAwboBno0/trFn wVyvryugGMetV+MPG0RSVQxkNGrdn608tqJuq2Ui37sMD/PC1WLTLXpWjR1pNBLFw7t7aCmM nH5l7dlSBgFGZBrhpNcpwrwKTIz6rxFsNOfviXVDg1r69C03qZkfNa+MIST9axbVPRERZMl3 D+xNZPzzMqrFg6vkJFJ4EkdeltnJFftzalXYrPTn0/Vb//B/sEaawxM7xjXhXP+jBBuNYt1Q 3CgICeA6pxxCnJafhQSbcrFYHsO4R6y8lQ7om4XU1GyijNmEdLk1zORweZ8zrJ4KvA7Y8jOQ RuMjqd4NtchLhEnPo9CkJrzsynqwC6UhFH5w+dxE7LpAqnWX1DanRKE9j3u63ogJsEIekqfw PSUmvDJYNRFooXHMtGf60rB8eH9pW71/nPTTlzb6Zb106enLduC0QIgelmF3xDCdTK6Esv0M 4YJ+U8hh/kA9YFNApWLcvnOnJy6RIN+MQ61N9RMA8TUrOii+AhIdZaxCO53nMHtsQ71eNFlQ xk4tmuJUgwOuQ3N6ZxFC5SFqqKft8+P/sAFC6T6tB3tqjYT/aido/pKWySVgx7a0PoOGYaxn 2O/OmnPcKFmWHxIpM6s4pf4AZP1dV9wokzHsabHKze9U+GQ/WFhC6qhC2wNnWqv4utpnqAmn Oixv1JfZKfsZZtfCVqL1IUJp2U7BjJQ9gHXeTA+jX++w4RwtxaoA8syUOeXWjzxrdXLFNfaG lF+QYhUUToe6BtK0zWuliiXSbGuCmD6yqW0aeNsqF3FNc4ztLKx7t9aLZyfTGLCdqAUgg5Zh 6tK0W4ghHVJaf7OvdMm6FWbXspwXdZRySuHUPsg13ZLTvNCz9jj/cGpfFHA5Je6vQdHkeOsC QKtDjfdY26AjCBKCvqSb2id1fMvEJ8eS5pZrzWbMInSwrl0tdMz+5m7V5PS1DlFWuM2s7k2I 4MtZ4mMUUKtUqDdRAybQ5L2CRid8agj+9nl0g2VVPP7YBy3rhmRY/aL9dNoFsSanyNSz4ggt 2VU/H1wDWuZok45m915ZVenEw28TkXAukz5YKHyk3f0TcXRSL4BEpLSghCrq6BjCJzD8RLag VYE7iphu5BFUsZWFAey4B/XmCN6SUPykhoSavUgUSvXR9X3PnsPtNHw+4IZraHlpBxjslTAv 4GWbb9UZQ4RanDKqO6E2nS0JFxsJaVN1YNsoRx3ac21b+Puv/snZG5gXwAEbHX3TGIuHUTxm i3NxOJQ/+vb6uSw25DS5qE6rvfxdO+BZzRVbHs+ltDLmdS3VbfzUEaU6aAM3skkrGn5kbDUn PSBO2BWxMcH/RZ4NWee9dgtA9muw5lwY9i28QcxRNDtWSx4+gp3VGAf5D5QQ41/L9yxJJ8Vr 33Ipsu6eBgRCkssz32OoBFqnN1SqRi299ABSairWH5ONIPM0joO5JzE8NDAWlvt8SAn0/eOr tWUfTxTFovtQV21VZIPkR/TJpCXFXioMj6gp4anOH7ftzriEtI4Un27P5sJQw3G4M438w4p0 wzNn83mLM/W4yAekR9Dnl9DuruzDiUviVDXJpoFRPv7sk1+K4QBZlyp1eX7k14FvGi/T1z6V 80UhPv3nMM1G3a9riOX/QIni8ND3omG1ZjTqOXcua/7MJxo4XaReD4rcmHr/sxULdM0OFGoB dFixM/sG3ho72yA873ZheyGhrZb70wy55SAqWO79SaYb0URFLbN5Oc/smZNaYwF21vSXrjPv 7dVcZlJoLjxQh8RFETclJWFyB7VBjyV3r4d1uKcPUyzXFn0MoklmrPlVvl/1GNQB+33iqm6s 8P+Vc+abTTCm7nBxFx/frgwYx7JCyWuW14jVGh8L2h4Hhy9utvGl33bRMQcGaTZafoXSUeyf aHI1qAzU0Tjccv7LmZksktoHCUQihn8Z+FwCivzzPhZ1NFUxCb3EDQLuUZliQx7tI8dpuITE OS3wxFupG9ptRkrms/VTFn/24jOSlCfYD4Ww6Rhs2F2XtIIX6938RzswghnhcszsdKWCcjaA 4R94VcaOhtzLXEzPcSy0VvDuAyVKRmetgYsnQszPn9xAOlIZJBJeJlzYzxRJKzZP+8KUJJvj bweU/aq49jf13Y4CfwYmEEvvJv0r9UC6COq+h4Gl8cZ2OzCBPnR/IXrOD1v1EqVfgZlT4HzO zrhjf7Sqxgz75n6LqQj4g0C2m6eNhO0WXkWPjLJFg0fPBoaszAlj0J2QrR+CB3l7NCIcBLU+ NwSldXe0IrguqUgL9TY9AkFMS4INCHKJHRAO/EGmQprh+a78tJlWKB8/8FBRtUax4xD9HkDL TmhS7wOGyooiHgkquxWmesRHOSO3lFSpQ2zZUCVbCqjyqwsrTCwbKt8qqTtpQTv7B4ixDMG7 vr2cVlmMNiVHrnyly9ljqvcVe5oyQb1xrFtEMyU4CUIkB96mMPcQC/pGdskG9WIw6HyiUy+5 /wJL9NZ8yU8I2HeWfmm9maUNinELkcVZHPQr8B4SeEoMrwC8ldbpYlZ2ZHzoai4ca2KpZ425 uzeZHxywbjIbQk0Sdz8vYjh12J3tXGMeeLSfyGwDo8xRxxpU/ewllpdMTW4jVUtOMwmGijuD v3vhKDTJ7/2i5sYoPPkOY7RtM9uPecAwoRhQkXPhBXg80huZVRaXvmfs+33fWgUpWQ8Q89EU PmtASPNDnT2KSgMqZNluwwQsqXn5KBsEFRAqtcnDb+cvBs6BLqIX3mn5QNj4GqDjraUxv9wW 06WC3WSK9VG5kzMgpbqERj7cm3TVKb+S+5ctRc1/bD+SFF+GnsIKHEeg48R/KJXINYdzoFMd F51z9qicvMoZeCzCCADQh5duJeif+lv5yj8OG7XrQvjnSS0wI/ivSYeO1DnuGGi+KAl+E6zp 33jmcMPw4Wk2CCunDP8/zs5F4RISjF5EAo7ujCXKlwGDFF3EX97Vcc1x+IY3DGCvmEXUgAcE 88eDCfQ2q1TSjEWKSGtmnpSBlhnnGmHQsM5JiWf+hkK9YGwi7WohpBsOsI7NlYuazr2sJ5JY LEci0A4gB8T0nz4T9SaSU9OdTEtHcGJY9VyoOfPfVsvW/XFRBI8JOhxV+wy/7zBFjENu/9PX 6kIFkjLoFHYEMjtEyfUXEec+XYJrBn+9Sr6LwpUVVf6aZ2HIN4jjaWsYEuu6p9WiUFYIHDdf Ry9JzVAYnp2IHUNlqdwTyQWle+xnyHUoclHoNUgajuNpcD7lgWmA4pqkrq49vNpQQmZIzgF9 GFAka6SKurLW57vnnPgzyrXeQSP7HixZs4D0Kr6sUsFEb+tuc02lsk3Ghx2jZ5LqzcAMrUF4 1UlPxq7IHzriIwImfOgsjKA3tSIY6xkAipY+BLAkDuytxOgFFhvnzXYHNYnnO/qtY9omTT00 FvnOTnHOvuA0gtYv7yhuUVyYBPweE8HzHA1w7S/7RweadtWI8ZJLgHYY7wQMnv+qphdtNUoD CPL2iPbasYejaxg2IliRiRPCUE0KXvLqdtaDK+QvRlM89i2jhjuMCAqASNRMXlMUc755V4j7 bih2JoLHQ+hV7KtG0L3lC6Jxb48CCf3oif/qkWnZChdtoFc3aY99ala+CF4f2xtRd/LFwlxl P99G+4o3Oh86YJ85hCkGMw238PIMrt6zGwvW1g+php1CmCc3OpsxWPvunQcZ0jCgv6l+l4oW FcGMVux5N7iG/kzIJ7XN9XzaU3dzQLJvN7Rbm3T8mgkIxZW9fYzhtbilwJF84mGzDZ3ljuK8 88yD8RFV53oisMe/twwDJdPQIynCBZKmbVnBF8WHxFW5PYR5FjGtFA5YUJAOSSPtQAlcFpdP ZluHYwGG+k81z7d+Li5zGW0aebeEekrmk4YibTTO8Cjd79WiV7Cj3S0bfYtuGzA937l3XMem aJ0Np486EflbCQSmIluWF8c1Zddo7EzApNja6y1PxC742mZKDWiDp7YnXroTXIHU4ZtP4dfA xmoLJrXe1RJtFFG92ZaZheb0r5s9A3gKDZNNS0hmC/2olTncBlqf+Ke3fOwx4AC8o0n5nqWf Lo/CTYaomaqC5sgx5rg5iazqlbuzmFJ3EBv01Zke+E6S83c3lnYvb5/IV0Ui0ttSw07WLmhy xyZpwOG+otHp5uRgUHwqziTzFtUIswl4tj/z5VQ+PY7nbRL0nlv89W31KRngWc3MArRUBypS bmNHUKBZNeKxgArQS4/yUPA5ES44KgLPJpAcu9YITxGbSnkMNW5+ttMDFpLGhCTc66V+Ap3p Yr1VI9bpP7TWBfGNBK86cATr/toSl6+0R0q7OuSx3xcvN3tyVwrQODQ2xZsypuj5h/+nrEH0 v+gpOd3n18QUtN5g8Ujc2TPxBhnCSB9oxhpUOBId+pVjC0qXo4H+H++i9K1WDNinLug9Dj9P MlBguSFv1GjRpNzT5SyI7u8/c7Cv4oXg2UzKlLuqiWVDgfoYFUk+NUQyHSctZwTSGhoY2bwo H/c5gYLdIkIYnCa62TCg1xkMzKZoObVsVa7DMeQz04bDvS3AuzCkpNB1JH3VX26UKPuKgNQs xxjrsjkcL+QepFyn/0kARc3T4euACPC38K8Y5TTPinS2cHFUwikTcadkRSQ2bh2fLoFgspfz OTUJuLUUheCaZJbJ8WVovp9AJKR7psh0pls7aIZ31iFE0eueap8IPFfbZxgU4qw+tBIwZwZd lXZNj8FdslCuFjlsARYRpMZEK5eL7enNoeKPa033VZOWtWcr14iONE3E7hoWRu5Mo/AjSU+O yi+0b2YJ0lqWRpZ+CC4JfuZa3nBOxaviYNw655U0g5Rx8LaxJ/CTghvl5kEejOpD9yUT5BVb VOUF/KwVw32OzaLqXtKgE7SM9/jU0HT321iHXJ3Zef4YgcqxchlYcjQW4/RnZhswucnWB/xG ouKKwnfJXyCZyVG4Aa5ZmTsd6W7pOVi7AEvVipuh0fNoxKZT+PqsNPhMbmNfE7DuBrrgq6dQ XrpcB9IdBONWTH+twP6MGVlj/1XOUuxXQfPHaROQNk7SQZKOEcLQnmUmI+PYwTA3ZT2w+8re rJv6AxQbfF0ZzNfaIfHHJ/7TOgBvFKWRWdVOSvN2qddCxg8uu0BgN1laPYDEZTJv0hthBqtb 7UJzmkAaYzARhNs4YCHsSM0RwI7JW9QCtX/PW61lVLb3lhXINXDiCEoULoJwy/U38EzQwhsr JiIHWgodQN6qpD2pGd9snz5WeJHbvStvjWT/IIVkn+Hws2d1G+XH1yDtj45nUQmcJFKff0BD 0LBziTQPD/BulDSataWibhFcWp5Iai+KLn9I/ngviJZwkCoh9EhIZ4gRLVIdjFkQ/v6kkK3W 0nklEBAFXbSMOkazn7YQpp5IwqSt/VGqyYb3WG5d3LFtYe/5zu1s9l2BxPyqCyNvKZSHbLvE lLL9Z7HjUAJyVkwlAm26OUeJo/K2sleGi+4wfXziAfazENNnUpOlj5jCzgOHXygBEgsR6uYR cMs9CUSIeHb+hbFPelNDHkBSlUolHAMG1Or/j1MS2MeMfApjCpipfbA2vXgtinqIGa6yMbKH hPoijFU/XSvoMsA6sWXLAn4gpKEAbhQYOQZgKFLxoUrNcSPzWCLXoVCSZXVAaY/Rb6+0JmjY NzdggZlZIInjO55aGlN20nspL1VE88BWAnLwfQHjld/QZ/xjdRi5YoVFvT0QeECAvmUF9bnn zwZG1FpbyuAuDioNqxZCw2pHp/LJr1dBcfa5kOS82A4I6mXLDT+NPe0a2oTv2EREM+Xgwblv 3FhPOP8BXG9tIMw7nZxmafFwF6K+aAVa5st5v4yJRP4g+LUQ8yaD+GFDor8fCly+5C9JoBOm lqXIB3ikbCFjuK+VFXEMD4pN62z8ZosbpP+lv0vtNpgqbeNbpd7PM/5jzTsw9lIKB+KCeb58 TiZC7+gpzw1Zn1L/pnE7ZM58m8ppb1Ls5ginham3Ubm/VWk2xEsgp07NYH0r3fJZmkZctaza M70Q+jYIDR5hdOE+qB8jq2y8CrwMtm7+pf9AooMmiWITX48X9cFkiG8xFy3G7qCZi84o8CZe epOJr8HGKYcIk8Xr2l+HmDBecmTH2x7B2ttkc5SolVrKeFRnyfsj9UchrArf8jUFj/Jz49Y3 wqY4bMUFedBmjg5f9ptzD70rU2H7Ys9RpqQTtUlbp/Ne2D3cBm9myxSeO7cQE9fUPySWpSpM fb3g+uNvuRGQYgOxjanBmt9uG3zkOne0cbBAJi1ei5fMryNCac7DDsDcOVL/ht3SGKpsOrH3 55OXvkXvNXT7CJC8zFh3mWaX/OqQ/wiBMuYUn0eq59rg56fd4AluJ02iglFEOIWj8rMB7HiM 5JGUCE+d+EOqFQIRcjwOM0+jwkU5Zokk63eAKgUfvExnheFd/NRqNpFGjh2mHe/0nbRjmf8f JWS7Jxg/psMboIUY3sLkkHN1pUClhEyU4cATFbkt/c7KQ4Ydxc+FsRkWkcZpOIJzwaTBd3V3 IhCXItOhltFiBb5ZubNSalGnNeXCpKYxcIqdP5zYNAZfiR5BDkeQ48fCFz2dhwpx0sPgS6hu MqMCZ7bdm4/AW2DB54QrsCfJPEPzzCGwb4r2cIhLtcDTlnY6zmg9stjdU+QvIEe5lKAlPORU uPj2ox0DiHhBVO1EsvWecSqrmNV5n5ZqF0ijua4cVtXSiCBflouduaRgD8PdT95UV93NdwEo Y+cjNOrAPs3OZDnz2ZNGjMNP1oZE7pVlhkd27D9iCF8LL4W7I42Vov7Q7G7xK8OhoQ8Nr1My 52+Rv6FHEerMrg65o/g2UvY7E1RiUNmCvst/HBkY8pqpRZO5RNy9byIPykVpq+T6E3IL3RrA LDlpQJc+IJxe6C0GS+TvV3mX1TQgoe57jAn3yocvTCU9OagOd5tx2iZUCgFIM9oSXoi6UwBO fZTILdi4jNDwjy7NY3dP7p3lgqHQgs9Hr1yt2IpmwtslZAFfPLcXXSFkbLgBmR8M+BUCSJRW U+G6us0el5E7ulKU3hZbKjhSPhFNwyE+pL+Pf5jyuycn2xWNr1sxIvB2tkfMzkIds3O21aLa MhS8lMe0Zi89efinbTMTDUta18YHzj5Ll0JNOw2Y/sZ2Dav3J0UcauKa4dT8UwKb08/SVWaB WfarfzDBoKj3At4WPbLVPZ7Q/UFsAO1tiRvv1z89KTgVS6AQjZF/xUE2Jzu1WQRuPNgHc2fN 9DULefjX9x+J+Yh3L60LodGT9MealEDlitDIkzobiT1j8hOjJpn4ho4TGD79La6S3QI3CF4z tuy8GSe0zGfo2scoIA4VGN9bfPxIRshpRH8OwVqWYvGVgBSgN+Pk0Nub/+UdRlO2m3/Rp2Cq fm3enSN4EhiTt5nkRBb9eIEU96bA3PuTyDnv2d77rVxHUlzYAtvJdr3wNDlKQsesvjomcJu5 zXWeJ86wMhgoB3byThUW8zvNvwLnUBiYji8gdmRgaIH/BBXjM6sU0173XjHW6V2zl7JsDd21 HmljKDtHZJhu4Hv67jTTfEwbdLMLtaUK4nLvHU7DU8DcGOo3RsvspOcv3Z1ZgXrAaCTbp7Im M9rIBB92VHl+/k9wbhWLvWCiIdRac7PCt6jwHNLOGewprrAwfy+4QwXyUYSuerp01zZgcVAd 6uA2otq0s4HpPXdTnLcU9+7d1cOZnhcbUl78bAewJ+6lS0WhxhIU8B8DVHzjBVRogTVAQWrq BSi1ctG1QFKmSq/BBU+Aue8p5mLJSgGO5IYPNUfDLvoi7h9C7oQOe12PbeBg03d7tO26QFx9 FLvMHcvHvBp8fsM+u40KypZIbs7xDFf0YTIOSb1QFiQPOfpql/4EkChrpM6quK9o1Hi/ipM6 +dki+0qLnTPc62ENfvnBYmdkDYRZzoosqhLpLbM3TSS9Cjb29uNjzKr8dkbSaIclsCwHqUAb jRfQ8KijfKnlvVtmDZDHUvbMN8hJyQNlWG/Ry60N8WEI96rCMD5/UuZHHZOhDe8KPj5r6+ly 3ACLg3ulJT7FJWZMWQx2DBZlLe6Jsop+GpxYeKlofMvvlxPW+Tgh96s7XGB9efU1xzEsCMQv zOlzB2wJrZKM5JFo5WohZ5wuxHCBaJaYTRP0D3To2iKT/E6oRvXxLWdVX0RX2sBKkCrHlBGi YFwklAVyg0pkJkxldhb9ThoA/8IPTbVNWYX8GirM5GXwOsco2SBZNpQRs/pGUlIBEHmcTkWe I5cjbWqj2Eo66HvH8mlc7ngonKpOmZTtkQosvogc2Rhc51XCsohvQE5nLeSHG4x1uloZbywL aYeM5tv9Wbf0M0WfHD1klFDi/bGWBuczj4Rr4LjIl8Ozji4Lm2UBFl4P10+HXgkJeXZaVHPc X4NvjcB+GTj7AOol1bIrjAxfir5KwsV9UbScOzo0z7klZ9V4CMEITmuTdeIjft2jU9fHkRJP f1poqzKhQVUcWSAtJCuvZmzGe69uj/AL3NNJdqQARqCSmTeZYTcia0L9oRU7n6PrToacqcjZ jDYl6LbFMK8HYtyEA/bQWkdqLF0KC6KDJ9u2pyUs0FNcrdsq76QyQE81If7U9w6MjnUljByN fzaSt9eJICN8eM0N/Rfpu1NC934S31JCrA/NKZsuUNUWcZJM6nuCg/T3iS/2dB2TLbK7Mujr 7YgobdDI9/AfIh1Tzr3TmI05MuO9B5eYGPPUi4yBXbIyFHcdWCKiFQPMFrxdAfLuxYWI90Wh Q69haUliSHobQwvP1Kt81bU/OUqzRi4IfOblRhhQRBVQIuA0IHQ6c/BldJFp5zg/kgxnxvpY EWyqSjwXZj9AEf3t2wIMvSgnG40E/Vu7w8LBBlyMd5bnhP6Us20SguZE+Kn/bKM+T2CI/ctm Gn9BBxg8DJggrucPD7OULZR367kx9ySIqvOYMW21aJs2y7h8cMwT4StrYlpbdf0uPiJEJcoe rJMsvLLSeOo8aVArbz8cfvcrQVY7twvh44zUEHXXh/oBfAKmLmZnOj5tLsoVz/4Uozf9817z 5nJ/IVUM50mBXA4A/FD5Wv0TY6QUYY9kNaLpo4V2RNX5h+ZL0VmQQzNKVcO8CUbpCX7lKwf2 tClRpRzkuTwV22/jVeiDKK3s4JmNzhzYm+5wHxJfUUMq/BUuBPY/L1tXOjc9RtNwdc/JboZW SySFJ8/uwuUx0XdO4YeAjFsynAV1Sy6NKuJW83eHTKmWojTDRnnr00PtNHFOXZAaz1fIN60I LW7YlDoRlzaWHoFALMmpCxti1l0C5ZReQinwYaFr98p9VUCj0aFSNCyvJJW3iMbwbdXWxMjz NajkoweJ/8O+IZntd+jE+ZuSfb0VrIz11llE40pzyj/JKpVK1mZSXVIcAceHqV8CBWw5J0NL G1RVwIqNjNVJEhdSpFVcs+x7PCtd95wkCfsjZ/gOPQW7kcEUCU5FK1nK/S0O6n7Cy0v+GRE2 tx2kckxOAb1p1YhQVEAumfsQTc9BKLYjfuck5sR9ksUgsIT05fOWaZ/+3h7mk1EX9gy8eOlY pypAOB7BB/2U+lSZKD48V3uP0AuJPxW5UVO/ta6qzH4EIYuCq6BU1G3Ewtof13aDKw3Rmg1a UMQ+yLFVRNFZPnpmtKuGh2YoNdHlFpwTA+C/eZXfrtCpGlC+rMwPN5Q10tCiwjj88oiJXiF2 hotvcr5wxK4gY1cRcVKZm8Ifs/0SYCEqaYj4E0Pnt5A5ioid+z5LdiFIHtPHEBkZmwMHYLo+ OlCfFel6ZMU6mQvR1tfrR4DbrvTnho1PCd9o5WVX2K2LpVZN/L+q/jiLtpE3Qa6E+7kgNDgT F3ZNNYGY264xbeKzduao9yzGH+/PDQzmG1ReWMcJeTU0NQJm7FRjOcOoh4cF/z+QUAn+nbna yCKYCH18FdWUOx5k3Bfk0EW0+cUz5lIMR8GNzNDf6169LbU4s6fk/i3PUW/Yme7MKf9W7VCM MPQ7e6iCJxvtdLt7bTAz45NQb6c6yQ0DZjF/L8H+OyViYUDH80ob1/ewyhjPdWSSCrL9ieMa 9RJYrcyNSZ0wWmHbjKVEemsc4JcgccTPLdx2beZ6mS8AfJ4vhehJxJQh0gRJq0kvTbsEjN6S /3uEW9WArgzKLZu5BGMuWwZBxJC5nrm4YkCoaFuoxxmav9v3vFoQZw4sXJxrykbsN5I4TzoQ rxUjfaIxS7otSWc56zHNsDNl2nJIGRswvid7+u08vhgf8AMOgQt+aDTQAb/c4Q6IIm1wzrAr U6Nnp4cLjGAuKBFEOikoY3e/E9RYQPJlQmqAR/8ufa7q1mNhEX3u4ekj5YWfHnhWHsKz1RU8 ngbHzd/JcPkfQsk2vr2pz7KWnSN5D03DCzrXkLooysIL6+Yi4BJjXP/VEpQaN8PHbif6Nf3e sDdUE14YrCfW3TKMDIfWdxrxVXBvibIlzu+1FywM7T5dMBjVfJrT+LThG9ZQHzZ6WeeMpTqb qtnYj6Rv7hYnhVdT6n7J0Ml3Gq5MsWJtSoCCcJiLB3t5VNwEcwN0qEKGZkNeKOsYxTetLEB7 /71cx0jNVX3s7B6cSix4raEG8TJELeRDm3NbWlle7Sppl73PwqN13kMuigkQokC8d+/bIJLB ym3TbC1qDhTd+401Rwe7rjKK0QNeMDU9aYONG8U8fefl024E20YKsPYRDnP8ihBrFcCv7c11 U4jlCjvxhYqqa0rM5jhjxcrAAYeD1kRcgVxQP4XcBJFvZO0I0d1EaFaWBcuyxE6uiHVvBokv KpqegeI1F8mWADSuLwOeQtr78VZ9RloM1zM9Qmf7xfFjorUU7r0Llrau5P+or6MlJhgyDMY2 1CPVGMlQUSavdfGADZmRwmHuvFjc7LeWZKngr7Wze+MO7zDocPDj0+POOhrHckV7tAH2X2VD LoIDFiXN+SRX3i7vLuq/FZ7tdub4L5a/TIQeM71UAPSQZiiXCvkiu3UNX8T1TVdOVRrH+GU6 gR3RjIG72Y+PmovQta8pRP1zImTGo5WPLRAJxQUfSz1tIkxVsbkJtpWq13FXPafUxU3mt2Pa Fr10ProhUBaVDhoLUP5f0kRcqeEWQaXFV2SVMbca0i2ZMBHcFMGm73AD6K2RHdsKJr3S1gHk bh7b5ZbesUcNFj3n8k3aURzRHVJHGUowaW0mtJR6TVHBdanJUvShcEpFFWtwAYIsQugDpSZ/ BagF3mRB5uI5SZGlKx9H0ciPjiEWu864x0a9HZBPikiK7PsCrGKxJ5w65L+sZRvTbV6Wuopv 7XkDO5iQFEislo5LsT4GXVBW9LaG2swXTfNbldnCcva0GqeADzut5cX5dAcVAVXeueMpFjYk IO8uq36K4u2JAvMIo3u1Vc0/+CgLq4+sEAmZugdvAdvNZcMgmoXkhKVYyScyfIjsnDazYFJF gYSVZjnBAI86buRrrvgNTlGTmY2VeO7MvICCMKOcz5YAxVpl1ROUtIlMgpqzs7QVCRURGR2q p3cw760l2IRk/isGmfM/ve/2fZY9djIqSoAoYIcDclPT41j4fQnGM5FeVtdpeIzFCYLy3ozz Sq23dYcRVt+DR7Mv2acUDpXIFlRvN2+RleOcafsdPBFTtYIr/gU8aCbvt4qVs8fvnE7G2O2t hEIUNWt/pE53HqbjnmXCcx7waBZmpcWktDGAupH8Z7/yzBWKvbHDCh+cJsJ4whGRAafLN0Oa j4uAZp1x7JMh0MBrWs9kOzs2USuCfX9Nh+r5jM3gtQM6F41WxfvodY6GDwExjki03LJjRFGh flH6ZYaVaK8aQSvkTDP30yqCJqFLDfxGxV0CkCCVnS3ZyiipdkVyOyXPXx4zqCrD2mcIpv6z wbwilTG1yJUT28mYtSnItv6o446qQJpBi4vE1E8ob7F79DoMTjv4Fd+1SEdWNOENUUPIyUPN 3mqWBeDmVeD4D9E/QaKAwHJNwaFMeZ6eNzwyRPyQjQQskBmgr5j1KQyBCoVA2NrQFJmqMhWc QaSRruayPanRItJfoT3jn6Vs5M0DItNYgrT/1ogHJ4De4A0HgxYv3RNPG7Tg8Z6xAX7za5dP HQSgToiJEvFHo86HdzOV7ZWkWVlPuB51sZXvt1JBJmGHoVEg98yibd/WiUtxRy/XH5JfoPaV 09Uil8P/XUL3/9nYcdI+PXgK/BCM/WwVHEnDgO1mva0kSwWsHIjfVPfRP7V8NMO2zkUhbpty FB6I7eU1qiz7I4vL9kJgYVogahF8UwLaYfgHcqoxKz5gmoocBCdDKKn4U52vbPjzSDMRyXF2 ZUphvoLp3Z0JFZoaCZZBcWhMwc++JEasmyij6lA+rNh2yyy6KyAI/DzrCMtqZEuiMvViDauw K+iXENdT7UWJXX9VG5OehCFjeydx1jMsBzmpT9B31H2gqWm5HedRoccrwFVhh107/y0zpPDa ci1wytgpYzu/Qgxlpq0CGULELklTktWS6aDFZD7e2DLGNcUWddWFwe7aU7ieMpBef5ZEN/6K Xtbm/Lvi9nVanTq7xBc0MxLfuz2ydFOiChQU8ypjf1sIB2/vGJo+upreblbWJKqXlMcxxPIf vQCybFpAY7UI9yDOJ0JbY6ffov8Dq1lyKablAmTJCFnhx680FBjyApkmTdn6I1+00QVkqtXG eG6Z+NfaM19bz3j8tqVbh1S5kEe/2P2h/hUcpyOrdp2LMdas8leBmV7754Ts9zwUGhXJBmgZ lTX1NT7bsKBTKunTDggxGhAcwWsD0cyfUygqT+dTzhqxdYHce/NeSTycaoerWLyn0fi2N5QU yT+GWQ22/1KAmc5r/rMdoSLfmdKGj2UoWAJa3SPwPj+LQh7lHwOyisqy5g5Ps32RwuZwJCw5 06lN9+UeCblV7LnqkiyJPM4//LrvIcbNiV3C/Lvpope3oeZ2l33xflQT/hLXSiMJJL8adDCa ZyXiODcP8e9bGtpGGc2IJzZHvKHRSrwMKD/mJDxERA7pMOh2yiZG3u1i47wnF0HrbHYgAO+J jESUKmcLPEJAG6c+g91DnPTYjt5EZ1MohaDidA9Pb1ZphzG6G8CR8t9V1SrkMhb+1QdANp84 G2QhscDMy+e2J8/ME/0OiCUhFQ5RWef0dk/lI753mUOaAluT/YpviucXohAhjjZhnqMLgSRf cdH1quts+QJlleCaQ1QVBdPSeoyn04VhyBMt202m98ZUlcx55l3eV2I2hiOR3mRnhn90u1+V /XJuZzEGPQiMnFlylUQd3fhS4rrc/U888sfcireBNQ7N171fSvLwGoXaLtC9s2y52dtYY5rP kHuE3NNkFeYkB7OVMcBhApBVy/SX2xVggyMEM7ltJOCQZ5Qv39vJowUC/nWXnlQI+/0PsrYN d2ftqKNTlzEYr1G9xSdsEIN5kMV6zgw7YL8+Me7Bp8Y9DOUBz5iu93GEKac/dqsK4sr4Ad66 vJ+Y9ZS5Fd5ZNwPv3siuFrwjh7nwIxzPYue7jeB/7yM/IqHxuxsC9do6P4IiCdW/L3oGKNOJ YQPiKTEslW5lwLkquyCGlARbM+MIhYVYj9uO40n0JPTZrWI/SLIPpJOhwxtd/jleSXtTh+ZB twKItfdaqbGQ3ILfeoIxuYh+ZMVDG6rz4C6Yws6WTqVA4QS+z3eQ/0cdlG6ZIq2KLmGTekMG 5wASvXfJ8ZrFubukhLvDRamBiOBBJxhGm5zKg9v0QqGRuAvReDChwpMI69AX0CXFXES97MOa kdtnkzEhw7YCYFaXcC44ckuYdBtwSKC2laumq7nUH+vECi1c10yd5qmwPyxH0ILimU9TWWTQ KfELP8/K787GMTkcT2xJzZdq5XV2e/FGqyRqOzNUM/Eh7WtJiLE/PLBANGBWPOnvtmGpTppT DrjaNkV2K9RF+8G+WKDlpclSqFlq5faOQJ0Af+xZ4XhGC55OQ550qUBRwen2fr8mtrc+Y5Gw dJzcaSmcrLjnju3s8kqvbvJdhmfSaBFrC8ViLKKhtgKHV9lMSKfXiyaiBIDCxicgVbtP/e7a n2tKbTDD17dHdAScIy6esU6QZSHsUrzoZyLW0q0MEjAQX04RM1dB1sZIRXN0X8XIb0n2f90R lC5BXOUkLa8PX4MXANXm4li3qVZJ9iMSK9GO8JReXEHEBMWrPcEb1r5t5A654q5jqW9Ca9dh BRx3vAlVxys7dp1W20gL4Hyooeq9TrEkhivAv5UzrK4wx97X1DHdibuqkVRnqiI2mxY4J6XP nk2c7Yy+dwFwWY7d85wizkdw9WsqC28LL+NsUsljpkpXctvP1Fdc7XoNh4kAsWha260imzhi fs4YCjG7jciluiwh7+eTEGHDOqMW4Wue/odImRyff9nTlfiZmWvOQz83kwG3F2TD7rPAxc3s uyTLf5wsX4v92XLontYTW0ZqzauLh13yEZlnJGwNMnSDz9khgc5LaOV7bBSDeW1E2l4XgkVi CafKpyDLGJuyS576ABnWJr3yr/Ekor7d2xylOJkhwTTa8MjF074O5vqize4a5LlXF901zBNi pZoTKe7o6/F53XerF745Q1jfXXyN8wz/kFWRSk7zPDIKe12/h2aa7UXtQkdz8ADBqXrF2MOc aX9MU2WgwIyfkCDpIUEwBZjNAmNymrij3fupCe9IPOqtZ0ofR6B2ajwdaiB/BEqvgG90Qc7p E7oNVf81sWUXHWRJcvoopGAkDJe7HcYSelynDq0I4oIlbRhho3SVn24k70Ob0Yivdnm/F6zk kcAaKDzdDBtHvwryRHtId2DHVy7ixJ6bw/RKZ9tfmUdyvTv5KuuCSWAdz05pEx9VN4t6jpGA /m9pZMdl65crhKwaKl8EDVZbmehCGIEPSAEjCHG1uWEf6WSnprecAEOZgdVOHvxtuh82G6QB J2gUjc4Y8pNerxIccWfoE9gsu3lY7qzwXukfS2515MEiCV2Rvyuvilkttrg0sUg+qizzfH9O ZA0os7OsYr8jiFLvwpMaxmLWvAdTK83Or50SwQiquNUsOdXupacW/hj+a33FUdTw7sZGcik5 eJPRewUjQRtCIsKBLidPgFH2SEVZGTdy6+y//kMgMgukcmyBNuvqAuSMgwtyUoGvna3w3RnK 5MIdPjAZN7IhYWqgS73RLTbPD+Czm6zvA3OGBW6F21cSA+IpND9agxnqrlgEf08sLcXZPlo0 4Txa5LOgou/DrT8d6rPP7utONJIkRhKee7c4HMBtUSg3Wrj0/GggfEqM0mTEjLfdmWlJgLBh XcDe3ZzRJmDI3W0mA3PCwp658TI2GTfPPGJHt4N2lLg4l2JJ9u2jeKRxRvwbxKy4rnXB1VP2 7bek162WRJp8w4YVuJzGwnoZOgnSiEjMgH8ZxJxm5w0axCqr8I30SmtJThoiuSbyoRhB/Zeg 12XcDZnuWoukHPyaq0V4Ta8MbPIFnBhw9LM4vu0qf1SbbMQ16iaykyj93WwVq9uDRDIPs1Se kilvtXZ2hZ7G/EeFWCVSZI3og3XydGnCrV7RDEIaDSJx8Exa/yuZ3S8cWFtxlRfp1yNqh+n2 U73SK0zYcWBXOamz5mBsmgwCYMtK9xVwLMEjnMXsiMWzoMtbR48SXdUOm7FVX7iZZ819aIiq uvdfBFEwazGCmU90LTwSqzzuFWzsBmcMExtuIVcbC8/ONShLE6awyqJsXZtA7HLzSouGvjsO zTG6HIAenfOJkaHCNq/p8eLyD6rXm6HGU3COI/Haa5lenPJromY8ItIXPwZ3+71x2bmGs7Ry 4raggEW3uBaStSx9LNwRD9/ay5k3h9MmIVlscogMNIuNFE2xYzJ9dJ4CC/wqGP+o1EgPg0Wx MStnG2tuCQGZW1q7mSUcRrbqo6Ou3gldLRy4Yc6LRJJv1b2krq7oksekSOznPMkg/zZIT97G S4lFTpj5gN7O48N9Q7y8Gb2SvWCQ76vA4s1iPwQRT01PbK/ioKJDDLqzVGwVBfoTA8qzYecM 3246KzhMruwkdkHOhAcGb9ryvPAM4DfjSFMcuQWZs32KtFeHus10M0PuRDWLZ7JMnHeOw/yH NEf0+VipkZZHQIRIVHyYHyMyoUxl52Z/9LRvym42iK0Ka+z2DVm4rMvPb+Szk9nLjfop0IHI zLHiqy7msJPOpO5NvhVFOV9StFxfQqosayHNf09j6haHNJDN+aUhvsjAwlDYrSZupv1x7l6p C+EsbCGKHkAl15nsrfWInsVgCTAMxGM4+X/YeBCamQS2whGcLDDfDJ0J9TpUOC8vOeV0bJo6 nZLs6kccIV1EaY3hJcRnQd99Q7qyuBMEcV63kcB9+fZ/IZoJGsv5DG+a06PDu3p2BCWsXpVx ec5V6an7MdJw/Yb0ime0CXe62yxD8aLMQJVReVkrDtGVEj7aSzEmO9AzrVyXdPDPFgoH53Xz 9V2DogVclyK+ftosf1CI5zgs+R+Xy882rHclXlCNBI8+RU3CNsnIXqhIViNCYRAMQxE/fQtF dp/Ss5W38NAPkdsOMa0i1Q6jFi7Yy6Dj8WDKQIade8PNMS7lGVWl4fC7uI6q4P8NrMUOECGz vpv1J2OhLol/YJ2MKgau91oJoL7XlxPCtMKzDS//EMPBjxz4TAKQhuoemcP0bUdjP1Oh9kC1 /Qc6Kuw3L7h82yLwU/KfqOZ7iIpw1upfjv4JU3+cDjo1JmGzLfJdqwZYm5x1TovLYaBYbMiC cW6N1liCkXouGmm1fLL4KNcxRB0Nd4i6suo7PIj5tGUc9LLB2Szg79jLI/vwRnd3gzRsxMGL lunV7tpoOSBtqYT7JrfF5ugC35uzrEorghDk57YF4Nu1Lb84Yzr6T7GacbmEzPyYzkPMUmaN QGU+QzgwT1eS/Ne/zlu5oo+EDU9d3q4iuQ/1PKv0cPwon0H5kL/kIrfyhskS/syQXt2B10a+ 0YGWBgD7f/PcqKrXIvYQ71tg5RweP/ilbnl8XkOmwpog8MtrC1AMEuNpsTgKBIyM0bamwp8A aj/Zz7zzZNhdyV3R9nou05+RufaOhSQb18/W2u3yyhygFjD2BlJNRF+1DsaQnkgN38LTj0nh TruFma+sJMVX3cl1NlBBadwrPuTEq11B/QJxo7XJHt/BR5fbjHN4A7PIcNqVeUB7w7Jxr0hO SdV1rhK5doqyoTnkeziejOJiShj8DxksTYlvpltrRkXz6wxGKzCNITr2hGCZ3KXCOvk5v/rG WcBokUdA5LEv7mLfBSvCoFrYe0ipxeAKbqiqJTbuebdldbwCBBHIOUGbgy+g+2ftEKmqeZCE J988FXSKuCoYZf/Sv2vTS3s88O2qNRInwGiR0jX6srFKncPXK5AopaYlClYSSmew99SfGFmQ 18qXOuTDlYqz/a59tsAEItmkqnZszx4iRSONeTgDcztDdPNvHZI73ChY93ipsvnU9bgMdoeC JwWvmJVMywzZPjRIUvjO5M7HceUaimrWTjOTcXgDkfSkL/wjZcjpZ1uJn1Ed3l0v1Q+lAuNr OiCa3qY/7RMVhuYQ1dA4Vo60UpxobnPkzbm6iaYkvJX972Sx+IV3qy/ssxyai7hwzC76yfHD /J+VbDmt3CcIA07nZN+45n0QpZfMJ014WGp6isN6FtNQfXsRWQNWACdIMJVpCQ/8FNuPHgQK Uphovf7E6Am8GHDdhjoXlK6p8NvflCBZvHjMCn1tKSGoCfq3ntdFB3VFPRYygE8VbjG62TN+ Ltz7LwlmDzc2Lj5Zu5m5KlwoS/v9mURaUVvdyIc6xdqW9EOIfUCrPkOqgGQK1kNZLFwQrmxQ oKJStDxaMH83An96u68QseBwAlmcQMiJq1/qfWekupnpW69YgsQZ2ciHurUs0od4wK2xsHZa UnAcJ1ahoURSprnMydRDXUacP6GKgI7W9oznjZ3S45Z2+x5diIhCdTC5GBAnRBuUIn4XVRIc AdeQ1EqAcwJEfPOCOeEB/11zUlzg7OrwYRmoIKIm6DuxzruCO8aI/1l3yLCZvrNs6CYXDPIi JNRJmbHSch2U8BTHoFue5Npp5uYLDTkRzsp2pBSkN6hhf3bYiX3ub0e+LwyFFM5AGyBX46Hj gLZeqlFqrpm9zDn8ZEeHNxAXmzmJlePynY/rVPbf8Zh9aH39KpchFjX7+uOkvmhu2A4i0WG5 SiKmdvJnhBYmngAqpW+rViFR77ghSK9FJVRk4IVqEAU0V5UWw05CIz1DGg4zziuJWbjutLRy aOBnxP6AWgHw3VqdxXJYIDT8GO/ltP6AwKEMnQMo8qg3lUbELCiYW+yQlE3Uv+b0+Z2VRiaS I5Gjs1+rG9vogznrMvW3iCnzl1QwMXciVGkJtv4CfmyPDZ8Fcp1X2O+rsvB+DkVLYC2uI9se 1j3L0YjxCjlTaInEuSzSgU12+BuFvqkoDJhuqbA7jtf3M+LXBm59BllF9eFl0s2hAtgi8zAk hLdzz+iCRHZZEQ14L/S/Djssmf2Rxc/1FM1QaAinlkmKf6W5trA6Bq3L6sdoy2bXQ8iaBEk6 2YLJ14jbsZcPHRiPpQLquI8QgtHY6qwRUrqpEBqS/yJR/O2QcKAnYnIWSj/8m8QiycSqQpM+ 6UL4bA9NOCJe2w98L0IoXycQlBTnCQLcDVZ8mH2XHao3B2dFMcRyBmwzoNqdaZE+ea+WFrV4 LpQZluQ1QA1AJkTimFHpALya8XYgYnegvy05hUl7aScaAQGOrDyd3TD3CYBPC7G2kvKVN69r SPnr5ZRhxXQpI2G2dBxrz7rB1cRZOB7KeavoHGoYBfFnRcLZUvfBaVWX6qrFt4uRwjIaP6Eu j87CVZyBoegvpSd77tUGUaSPc59uuiiUkZv4eZWqkIAhA++RYhLlInbefHbJd5YCGSkUeEM2 GEMuxMij2cCUu+1NdT+Yy+8Ld8XWGwDj80Pm9UMtCY1taaZbQLX6Hkf1Kb7Zcg0A2Bgk/Vhi rOG7Lh16qRkqALWS0YF5XTOPrU4bbxKT+02jd+IAWr+INiGObNhbxspwbyRn3BN+dynZcuxL sOpfWDALUpTrUdU6y+ZQGfQjJngabKkDhOcwwk5/eCYplLxmR95juJg0/j35yzQVlMnxIrCJ 2sPZ5Ga00Edo+2BXODEAE8bthtTduKRChNeSEJqCFDLa0gD2/cvbie29gan0b1LX3eNhXi+z Lsu7k7ZHdnzgA9mogCZYre86svlo3OqRe5DekzBxORjpzfL0tfmV8KI/RHyw/+B6bPeVSWo+ dCPlD/tWFsCCdBv2jsTJseCH7kU0nm7IUgTsuL2vroIFOTZALZN6VJi595NUZByF3qrrpbhJ PX5Ot+8mJ3a7Hu5jsBMwHMPNVL+SykEjQjGdvibYnpvhgz3Wx19kE0EfSk7r0VBW14lgzL+4 tfC2mdH3YMLNQelcMtLPAf36Ug8ZnLw8QlvBup1sPCROP0ANl4JviRV0ZtR3CSyohtlhW+66 81eEGU5R7HEOvebbyPzTX4hbgaoI6GyNb0e+cqXaVdWvyGaY8uUj7rPcyVbm2wBjXKJRUD/e 9XCwdkVBkhAiHdZVmpQb/nINSJmVlLcHzrpDHunE+8Jw9+1ZFQTPdNz8L71pRB5Z+HQKsnHw km0O4nzn80CdXsNEKyZOtRR/LpqCu0J0vtE66a9qtbS/tdppTk5eEjdH7RdwkKC6zeK7uoEG Cz4fOMM3rERv8Z/hkw9oHrtSIzyWKBYl/TwH0RfnGDVVCgT2gbDGHDnPsjt9EYT443lnl9cK a8BBGlv/vi/JhSgVPijZqrh534UV/4uNT5z6MWpVTa5MSdXQWlhJldOZtEcI/mBSKedF32BY pPz6W3jpSRVbVyowdfVVXfX8jbqIE9yijNCLbZ5PdUlv2c2sxayfoXVbc0nKEwlwtX2Jiejd IH+4SiwJyZD8gqDrEngfy+/rJZN8jj+67IbENrzZajG4ZOyjJNRC8rwZASvLVBTrPbLo8fDl KVUlD6WwxbxDLOeiUnfk1eVfu7HgX2dlg0TQdLUT5A11hrKwgVV77ziDjr8IlGOnixK09SdV 6dzqfnCU07/QbFzjadkgKXsFxZZTK7/pzjdmXGIQ7UvCTFHdvjmLSMIuFHLoVSxZHnyJX5sS Qs3oSvEfgpXYZExWOhPpkvhIBgoxUYsQ4g71nvGrmGohKGJd1NigLRIsv03gJNvTWIEjLpB2 HWREQ9MN6fRjXh7Hij94qW4QpG3WRGGJXXgsYieORjmo95QZppgKn9LzJB+WOGgcJUT1AAh7 eYnuvtwUh/SsXj8FQoRDXNwqNkCeFoWcYMvPzNV0p88N90pwaJ1gnUwEM2O01nKgxIpLcrr+ /JUormaLiOnt6FoY3Z4wswipF6aXEAf3jYjrEGP1kRWVK4VfFVwq80e/snYkO3yCZ/cZdn0/ 96xzYqr+EDcoGzb85dXojx+n4a8L+xbmp+5pRhP4hOgg3YEK24tPsE/ho0zMZhLK6mfqYlIu cIAtwCBMOhXG2eUEYR4IN0vpZpl8ZyDqNSlOuwpuAm2ocXYxYQfpg8iRAu9ZJFMtHUE9VK52 +rJTFmvdsYO18f+WSgwe5HNCcJmlyV4BsvZ9TQkndYnG/dE7tQ+FpNcQxhzEb9ZpySem0bjU J0sngxzH8pLKTp7JU68wuIcffGrwC6P0/T4R44WzdW+f7xT3isfOu2I0+Yo2Ik19yTFAdwdx gteD5DR7YAOqTBhReLNYbvileZ7BlBT42ibR3n4ZQvWzSOsVowp+Qx3sjGy8O68y557FQp80 OoWkKIPw/sRzWbkqulnKC3jjEC4FHy13rTugKAA+v22nkRSnmdr/aJIs9qwFCJ8iusI3eGkC F50zvLs/6aU4KPlHR/+/8INV74J4zzu4ncmDWeNM+TA3TQ35QRppCG5JbMivt9STJR+hVghN X2WFewkj39PXmhQLHdrmv73huyi66SB2791UDq/Fy2O9VQkwqEbyVM+x50QOEiiEBAwEoX0t OGYBWafeodtFzDSvuL3LcniEM7vjSaDw1pFthMNu1xKA5P5SNtOLDBcdkp5p6TCEV2J1FqF4 eM2ukGam0Y7rf+eLGLnj+gcMQ4uEnIm6pH8nsdzrLwBiFWxLtOQhTGN3TBiJYjeMwugLGkyT gZ4WfqIZtM9dLXXnfyM27pdru58s1RDgxxHC4FdE4oUieFxN0DHacbs6H5llGPwE1pNSsLCt XdWQun7uspfJ1G/JbBbU1FSC6vmUWg+TRsNOU06AlVvTGQpKjxRlwwflDuIK03wIh9KWu6NF Ug4fpkMfnhL5Bpms0VTIvLOuVsEYdCnCi4/N0JQjTps0tgTLi05MKUTYvU645KTNGvQXmoMU /LMNf8AlS79jE0DZCWSzcwE2SgZLqh+b6muu9iB/KYegcWo2g+PLJuBl62jlQBi8qHjoL4H2 UiXVxvTC7L76Fig/Z58Mc1lgCq2U12uIPrY4KAr0mPl41cMhQBxUojrdstU+69wLYAqKneB3 cKlqCcJIaBOlLyAvEEAkMTcOrXSd11ADVDgnMVICGNQEpCaQnlcyj7u9vhx8RpBeufZ5mW8M pchKmF+OZRuZhV1ADF8z29uGnC8FYr8k2pKi65rBLzbofI2R2X9F/MdDPmlMMySL2EL16hgI t8dQn1G9Vv9Zbj2chFIqYhQshNgS7rmcySgyiKcqHcOY1k7UnN6Y77OP4rMPgKmvH7Huj+UI mdBKp/TjKsmFBamQlHdtd4csIg05XC3HKgQmIimc2WGHFgAH51vCrNnv+kn4HVj9+hRsQ0tF lOpZ7T4xLcd7su6xD/DtiQuzpMD+qkl3pNWs4K1q/w+Ms1OmTGJwgKwsbBSG0SRuymYy0sSA QP6oTrVahkNysKpH71gZ9a4+HtqxpuOb4qEgAKjmqmx57h6EiIbJNrJ81DiH+uS7T5UrdHv2 XcC/5aEsctbHqPlsUxn7zqDhd97owCsoa7IZD8t2SF1Vsu9fwhO/B+C1a/oRgEL9kWJlf5RK GmK8CKhAYIzILLtRqecE8gRTyjA/krX7pM06tGCU1/Vmd/d4MKJ39R5/q9BcAoBthtfXs9yk xg1sGwphmXv5JByZrxCCQjMp7iw0vu66Lkj5DzLzRN8QrYtmmb8LzzPZ44iiYHcqcnFcFIYi fEts7n+fRgOIULa9lAJMdIGQZXPHXiFe07uSLITgDquWsD/IwptGNODjEA7bCJx6N7IWVTHW RZF8s5NOJXmFIBRM1w+3lQ+xWSzrEtSYwYuHTSpm0QTW/ZvoO5xCBY97Uzly640OCvBRBQkS 34dkFXHAqIqMYZO+Nuidt4/XXvg3JqiqtqBWz/jRMM8f0pS8gsJnf9Vm9FheAxistPozLOSF 5vjWyr0iJ8BmD+Axi/O14n+GbYePAq7WLGXDx3uzxB4BAu9rBt4H3b2DblxmFWBVX2VGLzLS GE8ubXsGSHxMpDUYXIHYQSqmWzapwrt/41upL+WRqNDg+G0vTY+QlpV9YDqM0vLWF3P89o2f lXIXcWJkIXbUwm25ic0akbZlSbo88MnSdUdg554y+zgxFqAo12g/VaGDVl0c/3hvWXadatZF 1QsKHRtrGzf+GBt2IXT5TD+RXjLWjW80udxGxM7Exx8QRw9ERD6q0s9ZiGxDvDWjqvScVjCN fBbcylYX78Kq2ewdCnIlaC3YKk3A5uIqAgwH+gw9JJX3IwrTEz3oBXPIklcyNhlRpd2ZwQj5 GMh6lVEHdoF2kJMRHCsVG+khDmkJbqKUK8cjxDKLZdtbKRrwtEQv5a5+9W7C20Gu1dLT2Ucl RG1rgjKQH+4JLyWHFe6I4zomNI8hPOJ1qzaLgZXnKdsp/zjfWY5Pq72ep/HY8IjkkSmV8edF RYDNcouvZ3mQj7If5Pfz+xjE2r9rx7YJR1e4ARlfh4xQO3Bn6VxKoN5dz28bE+gz9mA8W1c+ Zezzt3fJZanOpqg1IDFGavC1bW9nlMtVSI2y3yhblQ2mcNLnl+KRoJlFEoGXgMczKnILEDoq LXTOiwOx7qO5Z6WlRVe3fZ2U3ii5sQnjl3xOJlCE2AIOLk/ZyYGxvcVVqd1DjICq3XkgZcjM 0S3yOlvNobjN1cx6WlaUpKcqLv0vJJu2ijDKQi/CGK/vzSmddjwMPkYA73BxIX7sYxbiha0x nA7185re25D1yp7Zt81xvk3j7c8A0+PpC6EdpS8nmFbWWkPdWPpTmcH4LDX0khb5anP9IW36 WPERU05uuuQKprF6X+7kRnBjZ7pBgXLm+dJQL/u6hdNyzb4qNVB9cz4oeiZZwZpS5GKkkuSa JEwzOFnsZhsVQ4WnbyNymN6dvplL7hmHtCKRxDFBOq7IIAfm8l2cYFvT1zJcan4eFZ6L2rQk gcEbjzTWlqcZ3fXfqILk54It8sD9PZ4HYIOGKOid0Pbz67WKlcxxQOf0mVr5KVT0sB1MvjEk fAQQ8prOjgbxcfiuJ+OV5573sSe1kh+j4CTztsXYhvrkTxyBH9BrpbEhZqUfG9Rvl/0TRnZw eLjfxGYRsl0gqsZrV7abP9y6W+thVqFsVyhUNviAzmBSMopwo8otbZan73RhD0IkIbR0p/KV N+ejIfHRiMw0oQzezmKmAVejj0S3xbNeFAzXgkcrDpQE3Ds6O5yRMnba+0qTxG9G+TBb1d/k R/ungfCGnRaYp5+KEHF9IkdVieinxUuYcFh3YL5bjWuL/53AzJ468a2eR8aoMisMYwVfZsvt P9crc7yrhHkcXhzbmx84iS/MH0PRsK3e0TY+jBKPi1O/mNzAeIcTmxgJKDjyeajqRF//BoY3 ivkN7LYj4P9JjE7XX8NL/fpWwjhu7UuZrKvfmcZpX/jm0fVmkUaoqHnxJwyhGUVLqdfSspAC bAkA5eFGgQJ1+XsX1lBKfozVi4WWUMyK0aELC8zRB6rx+rQpw7RD5ZmMowi1eTYd0Qi4MbqR 5S+hRYbnnRQvrvr8hyYPqGOFJBVhfVsm+6ZbhlvlrYNqkVU+muIc/gC2+Qct30p1skwRBUb7 +gVtuL5RVgnPFiS75sXapMIZM1ETDs+N+zdaPIpTWsHqzLCnI6JkUiTBx+QXaNbj+Z3HbZHx Y/FrPCJqFGup56IeQ0iRu2/PsF39CmX5zclbvqEZt5P1PDwuA3klwUn8L/9PlhD3BHqAanmg qOa3WDzW6JdrZDsaVpgPOJP0Z3T+j72bEP+aP5PMEilt4QgVLmSZjsvPe8i2hnKrKs6VEt1N Sra3pCRiGfgjTwDOtm/wa/q36kKbwxuD2HN0bCXCdyvE7Nufy0WSA4dxI3WMENRMP22e6Byk ERDcz3fVkKX7VW3zWlhQDRg4Td++lcR/SzN8+o1amjgxnkwE/GkUr7EtMABvhWyD/c3FItBA alSH/eWvCLsVGMxbQgPqNc4XrQzLeMH/TFUJ3jKxQciYleuf1SV0BQu8rmmCjGUWM0S1/jwU qmgK3ThF/ACJLnYE3NIuoXDjtKzymOZifSqn0ZzhVSwGp+/u9J+WYgTnPzLMCsPZz+/uCO+k rMjUEPDHu4PRMJpNQhdwaVud9m3yofPFurc/AB3CK2oFdh8Izc6zTleJYbFGph71OD3ulNmJ D6HPh2troq7mEXBRzOyvutzOhY5GHHW1c/JSM+JX6rd1/SZniyS/klUS98UFtSWQayY+ocsa sEoYgiFI9qw+2RsQPzueM3VDil+hH11+dnulF5+h14OeQPA5uuz35rW/b7QGkGo0VN1ZUInH yfBpMbIfgDeWaepha41s4zKtgAhm0HmKzP/Ef7jlHXG6+wyL+fE8SnIPiKN+KR8w8KRMvHaI hhX/iPBzKBmVccyhULgMVgmp0jaWXigKOPhjdw72aXnIeBy4H5dzT3N8qXyGFNm2QE+WS4d/ xK8JdzMJuZJa7a8gw5BgDoST5BLW5WuxIElYtt7xLY0RrZii7NbwmFOLCRs8sNpLEc31Eycw 4gqrCBtAvMVUPMpSfrCzp5ixCAATby9mt+ckwb2qt2cxohWWGVdovYpklC65UdjFAQJTmzYg GtG3vfqcntNFLg19gIY6Wejdd6M8FDQg6+616bRksE+GLc+kUFXqSPm/qYbsWG3WmGai9tTm n2fy3bOTLOxutyUSvBB+fPE5q3XUKFaZSDBpLFVFRUn+Z/y/OPA9pg7tFstHRBgFhBshnS3u iHhlV3+zGIluKSzySuecUweYFnuiBPhnyP8ehRSiPJzvBJECKu9lLV/I6MHPjxho+g/60RTs S4CMcef1NR12QswElneS35ASXgNpMmqbMMKwUx4b++IdFrU9AAd752H0W+5IVMSgvFZxHLQN F3cM6W5BVkaY9ZPFzpkmMGOllziS0d9FoUX2CjOMPpxg24x8hjwfPNUHLnp0BGmaArkyggQf 2RKHQrpAZg/LExlKb31RvFi4Z75W00djiiLUP1CXCYj/s9pvzEmK6HFm4YrfwSuiV0IPOiWu 2RnwXsJjRFlOHYl/L494qSCtBCfGV7V0nzauHoWurE0GgStZ+oE0m7mt6eSGxkPwSXHoaPNs KDXGI0sxVpe+q0xA99ytgCIKCAXPFXJm/NS2mpko7tZ1qLijacAyVfWmKJR0ILWwjWOEk6cY z/vYHcC+hG8azFo1iFkFK7wbuRiRJivQRXAmm4+t35LWAinB+c8Y31xNXI8sAtmVaLqlmWN1 OSMpycPH7TBT3Kb71reofrYFPlSP09gTNjW8qUDfnxBo0V4FsVTVHZSSk92wu28BCa6GJesX KgahKBTKCzpIL9GArmLWOPsIjcLxktAB66Lduf9TPnfJ3vA58Fl+8ZUJo49/5z7aIdbEbUOm CKWCs9xi+oRjZkJpS8oBlwm5vuU7W4XGTjGvGqslG/hhlFvZsfUGAskxnSL4YMJDw3CHxQ3t 1rwFIc+bOSLdnq+N9gmfRAEMRs73TZyHowNvQRFfucMtlBY8rXVFyte6TNNrs3H2aJXeroe5 9/csbsinIg9kRf/c2jVJFU/KVmm8RtEuz7n6I+6WKZnlki3EYz9yLzdw72Im0lcWgjqALBno OwnkwcKBtFYdOS8EakNLCjJoTX+keLOouGMc8OHqnfTbYmiSW6UtBcLjtZ1ECG+qInnZv8Au R43uPDQf8Nas6PFkntK8FYIXfhrjqEMpM+i6DQxbLAtaU0CM+J6mHW52yuFXMh+OfpJo5vkG TLUvvdFql5mAcV/x5wKyi/hxc0m3OWV9Ce1nJfc0KWqFCxHMhImWmHhfqGJCnOarRkJOTSMY AD4XghyD2uKy+HRNbyIaX3PGUTtlBb6skzB+aibT+9vF4v6ihqrWQHD4zbuvjBJJab/aj+hi 8pLggF1zxEPx3CBG/LszIkq+4SO9Ik2V46BP17GBSExJ51pt1bTVQMUO1PesM1jJRN/F9yS5 G4AM6vKj8urKmNCuqmAZE7+s+yWM8M368Xkq29uB6Z1zMpmKfXSeFEKFG53+t9euqudzgkdR 3up6W7m/b1IJZiqe4UooOfk5dQsNJYIS7ajW+9SPgjWcGWznrQug8eICfG+Tz/CfpKy1qdBE WRbuB6f2E8kJgbo8dcwmFdoyswDUk5wTI/XZ8J9hGUwh/1GTUowqmP2feNSQfd6EvYOpyG9I GdhN+ObroqKWr0GW21YPHyu6odAhslrrst2oembK5qpp/3I55UVbTXxamjC1oLQ+znyaXQto pbT5IDKWLfWguJ7qW/1Uz7u4NNbzQ5AXcrX6LfS14brOWu3/Hmh97bypWQI1W4W5Nk2WZWTA uW9qsDEsapz4RQ07MhSZjZ615fYgmZdMSaEX7w3k9WTBwpJtxI1S2AHofy7KaJFTmgIRcfAQ WFlmyIJzyGtRC0LlSYdJ3OREjRCwdD6ClrfgJ5fbvszgJ+IO+1e5OyFZObCgR4WtUx+vevNQ iBX+PP42xItZ6/VsbjRk6gzZkVso8ztXIFJXg1ypaB/XaVf8ksTE2aEzJNBQMzEPMKu9mw+M qoavA3r9jKU5J6Fb3wpACZnuoSFIyrb0CxDJ2PHL+cybyatfqWMsC6Qu5eOtUAHlVeieGfxj OqJhJerOm6XsWYzRMF3Wgqk2fVJf0mdarkR500ycb6CuiOi31agQagXEW+WV3QuDOP3YTD5C Ubil+3rieT3sSNjisH1d/iKBs2GFunhmldxCB3uWIriF1C8+aFjKOJFhsFS+qb03dD0Svahl jMM2YjAHrBDZiwhqJaI34TtogOOnF011oiE8ML2tl3jdjDN0Q9WiEPon21x41xcQeNatft7V biGaGp7bL2wYbzK171jN5DFDV9L1jH86u59vYNA8LlinCTmfi2nb1JybUbHh01w2phodyrYF kOfDIMLzvznFyiagRVle0EjtM4tjMStgz0u1v17kFALDom4qRBWuyzuYu+iLB4Zn/yAYR458 +5R6zwuU5NtMAafy6PJ0EbHQXiisotbLR1rbY4hsjDuiRGtuAxGvYANnww5eyEYgEAK+TQpv cBLnTpBz63j/k159ePBw8W8QT4H4mje1AA6Wudcg9dOrUyMunUFhW57ul9XyRo/tFPfM8EIJ M7N3/XaZpj73IAHakt0gPeqCqd4zTtS2K5aM91ivVFU6cXMeUDh0Uhli3gpJBDw7oG+yHM7+ mJfxDLF0xO+2fvOU90TW+GG2K6Y2psikJ15wTiJNr+4WgONJNz95ejF8RI3Kfj6yiDQmzfqx WffL5iL7lDNSsd0TCi4h5tK+tTKoA0GN1TpUZvVT51U/WgFbNW9/PfHcV2O/bxiLuWeIv+ZX tyjWa41TGNRioqaCcYJasb88nCxJQP3oX1EPQVf2vlePCxGnQf12469gJX5J3xJltFEG7SFy c9MprUdy/ZE70XIdpp/xL8rNLgEVz6Sr7Yho0zSfG4z47Q4NPbAiOVvewGUviMRr7zdxhQ0y BxBWEsmcwFwSc6Ginv5/LdGXrBctNqezMr3NpA+Xlh++tgMlbUIoKHHWjxMA3ubWhKI4XwK6 dtF/y9S1Nfn0m8+s7a9mM5yptAvToIUnJ+Ztjv7yVKzHjlVwkJ2c/QjrHF5UKfx0eY6Wsxw+ m/vcmeW+SRb8PuAcV1dnkth27kv1WrrWUZK6sDMF8V0QZbh5PbL36WmAe+Pr9MO9Ni0qYrE/ vVIst3azTvt8GPLqOg3L5QqihjmQqRFaIKPO/ylBvZ8wis95B3pc1Tp+ytuxLe3x0KarBdUj EzjQ9WB9mNnh7d4OPwgNYosPOMs0po5mELY7rolA71LizGVDpfdgiWVHdL77Uvr5tHVssnuK vNlLtxclwM0NfWNc9a9TyLo2q6N3uY9Ef4JoplrpDV8a3GMjD2DRZLVummm/n90eOCNGXLF5 oX++Ak7csVfbak7etqqb9I2IGaXB2gOsUEe1W5oZ9sM9vBns4hk7pNxccJZ4OHsZU1Is9YZ2 CMoqlwSoK8C0PCQWg5bxPQ1uTeTAohy7LWtq/Fzy/dUDLcOue8ZmNic+G17ufDxCVePsz6IH ah5UwXtnzhiKbPaKmg3dKyhpPQ5hlnXW5URBeuurSBqVSeOU0SJcSCSnf+mOYnYSU2lXMlRs 91oy8CGZTXtpAFG7tbftSwxMmCddmNfcKVSBmf4L6uwH4sqWCvTow5buKX0R/MHwHMbG7QXR 7APxsqXRzk2+/isnm98W891U3yoY3LRJV4828D+pM86PpN6GSvbn2lYOBaD6BkO38+L6Ls2H MX1+QPxXhVlMck2VfeLjxn40zEptTjIcVD5noZ62wYBe1degqAm0IL1BiVgE70R8TMjWwTUL E2UT1Y0OPuWu8HCa+WJ7tQW2EmyKGuRihoaF1idUNOe2iqw1CAjvCHx4HWI3Mq4q5kM6TyMP tH70G/qeCmpzc8IiW2HbpRUJHDPOF8/Dwyfmv3DiYdKbE298fOdKPOzjlawxzDOZ2AIxWhHF dfsHrDpBxv3EiPtMvCsIdhKrUkxxGk3ZzaCrPxWABy1wixi7P9QHPW+rqMfCxuKSXg0bG6MB MGYadQDvIx/51B7gikhsj+rM4IrW0eWadYIy6Oj9RZMlaRzp1aX2OSqIKYz6ZmeAjSlPCFoC SuqS+M0H2pCICla3OE5s9mCjAO5HwQW17JUEFEUT+TPDy50QbWpzV1Qe9QCx8lfeU5WTz5jn u5teGpGqQpmThihfgqDm5hbg+6kZRu0KJ/YCgQwljWIH6QfSCpLOu48IQqDa3/AQfqtEEjx2 xsCQGi2iLacKBB/9br9DmjzAv5gj2D6kv4s/xpvD1J5XWLQkAcfD5E6tOrRJFMJeyxR8MqRA oHHphT19Pegop8uvUxTCq4KPXz+tbwUKBs9AxmEMHBSonS/JngbrU6X5EKGUnYWDflB3gMvR IgEzJt+fFM+nMd2rtKOMuik7QUUoACIizSlLeGKK8G5Hl90yNNla5GdpmR+f7jjwjmaZcYPc 0bDqya+P8hhjm5XAwKRr3Bj5AGovH3eg2C6k1dSQNkwrf5n8ZPFCg8qkIYhiPxI2nChHYEPU c77AQT90wpDR6gMW9SA7BVTLXPUFGL38HuEeozOYbWex/0/Cj7KUOtdxe26F4E/h5fbprSJ9 4tXYOucBGJV+zo8YzomiJQ9DLFUZ0sfEU6OQVu2hK4ATzewKXQlpdbk4ZBXbCN5LKIVSB/bi CQCYVmqbHfsBhGKFwSE1f7lSeDTegYDrEhp6rRH2Qi1+vP4bxHrr/tTIEEWp7aiO0mFPiIxl QZ+BdV5UEiZF3wV5jMsf3bpc+GMjnLcoKEgg/5iPs3kQjcDkrcWGEcPyV7DUPtWf9A60hAhz APW82QOTvEtiP63UWtEyh9P7F4AQ/0YEoD7rvPUdIsWXMmKWJINjzoRgg8i0nsZL+z+TcFt/ IVUir0Wb+vJjTT+K4o9C/67vTqZIlkdF6Ej4VwNADPFdO0lsrQtlDutKLfhaXd/XR7Vwhu6K vWtD7ooUuy5J/WkuRfI7nEC33m2iaysxFOH2a71fWQCx7EI45/cn65y/m0JmKpGl9RM7+weE lBOGi10B6jVgQ1OhNO7jagFUwDk5qTwU9wzQh7OcmbVAup55q92IuGgF1UTI+ejtbDop8P46 WJdDsB+VvLGmgap8DEyxuF5/sk70iun4452HkT2jKShmyFigKrijJk0U6qbfCj577jndzjLy RpLK9LZpiQDxS3YY7fRRWITtQTMpqfeR1wmeTE5htRG48uYSpx0VWbijI6VoZI9hevE4lwdj wf0TLnLgYBe2AXIgJclmTzhgQHY21Uwztx3CfJeS3EmuDyqwYv3ajlzmeDOCgGGBPXFusfaS UU6YquqNcyzKjuwFQCE4//NFkKRifXmZ4RvDCpynU/gusgyf+x9Cq1yYFf7LokhTqmytRJAX bv+Z4+V/QX7YSgwK11o+NWUMLmPcyJ5my7tzBi1VOiLarQDTNRxqVKYkW06fJermig+LdJxG G4/4V5DLArhTplgIw28W9qmZsbMzf2pJUMrspxHEMPPZ6f8fBaQftYWKAEa9d13FGeulUw+B MORgERmD+hQSvvz52wViiGZvttW7uLebvsx5unti9HQDMwSUK44Znwre54EeCUE6JYOFGEdT nEkAVwJzY/iPKdCAzm6CtFij+cxO/2mytXKGSITu0qDnEC/Xb1CZqM/k/bdihsFRMsCrCAcm HrE2+lYduWTcM/dCr9akxKo6XbQY0P6aMTjovrZP8foYc1WBOuR56RUnEupVDoFz4R3KxByS U2MHenBrSd3ohjluHPEn26cHMCcLiiN61oRm+9sXLbDw5hbbgusPX6qVhZ84gm+piblDWfTo gae+Obc6h2dP3NqbdTKFUIXKuIE4DFCclELXoyh5NKTYla3VRtoAg0X8WgFBQhgjYzAyYLLn N+HmGEHeJCiAxDkGAHUm8Gmvs7klkNnjcE2Lg0CdhqKxFwZ5NWpIex0fX8IzfYfupSlF84zN YUBE3WxbhTH7Tfq4CGM7Sm3h4OC7N6dnLiP+G1R/f3b+tTFlGO9b01V1+3OrAmNzk+U17ILa SEr01FcdJBMFeOpZoJP1hLH0VEauWB/21+OCZqtoS5a3apv1yL6z8roqskNy9+d+fQ9zLZ3c fktvuxltvwVg7lQ8eZeXL3/iepcY1Zhm2ENHycStj6uv60966zctSXQSli578YnI4rzyVevf ppAhmRx5FTpb/2ykPndnvs4g1BSG2eM4hepkcQoYcOgU0OPBqeCmhDd+Nvz9LPdgc8H7jdg2 E1Wsu3GooZJ31mIVS8kgknyNlssYfohAvl2ao7IbpjTQyhpXvz4o6qWq3VeXparnAqz18MEw DLi3+W6lK2X4t4t0iepoRXnCjgFqdt3AQds+mrxHyhY6wj7c+S82mJZ1iSLqYno/pBjq/0CJ mcCv84wOwWn7dgZMmsE/NFhduN2yq1S8h4ysYIDUdiMN+zFkim1vLn94RYlSF4EkxH6J2a8m qAXm/JSNkB/62VjPq6QNQVynmnWQAWTPtLlMLcHawGld2Dv8wbuftFdyAE3L8OjKReQWMANw e/AFxnTIE2gB7bkvB9qhhWDXHtLAlqEL9y+m8ru1N7LsLbHg2isE87gbnDr4XEHH6vhhrL4H Zg/MsADx0ipsOxsGZlXDKcAT8uT1V3bkKjFbTmQhvKxMHUG5pPy1398LU94urhGVrVaxW6jL xakdgyuXf44TLa/tu1rNnREC2vamBli7rw6otgz6g4Jaxv/16MxqNX6v2FcHZebfC8Vohusj aVnLgU79eRMMDhd9bktiiJ61RNkraUSDFV3KBiR/nYyi2q2Bd51RTgp0fzYBpMI9bdWITmvS 2LoPlfRAnq40wL4y3iesYoyLGt3gzDM6F1tKPpwtIsO5EgbaqntU1wEJH+qTswWMJRN+8yGp wcWm48LYxOR1XVmVG8rM2FplZ36lnfuwyXkf8pFWJk/E629gonQxUHc486l+gyz/a6+5D7Wa ypGXeDn/tDY+po5L1BTTnPnTIa7BbJCjwk8HSa3g9i7AfUh6PODsBjiOyx+wJfDeosCN+ih7 yABf5r2exHoO59d9QVAHyOKRu8vaXDmO8YBF8zJDMxvXzU7BN9KSfr8qZYPW183AbNC++6lb G8iJsSxcMPApOn/XJxBLua3i5MAaVFWNRpWdXq3mjkq7unVMebJuqZcVJvXvSLrIBgha4MXZ dz4emrJ0DjYuJRsSMnVUYLqYllXvXxNs5HdWM1y+SnieX4KWVNQeDEJ9oYirixsCLl6VX4Gu Pv9LOgLc5PO+kD12Q2Wv8LTsZN3sCsgopGNhJt1L1Q5UTaqpey+uf7OajNmkai0xogGNrPqs P4zcRFeS31HOL5NAYoLsg5bX/5Hf4Nuu9O+KazmizKDiCEihSrgQzJGOQmrhW0Jn2243rqsx ubfIv3Wt0qEz10ZcS/Cymso7Eqj7NATlH+DOhjR/YgomROL3g73p0xJIk+Bt4fTjjPWEsnmU Z76vJ3x3L+YhNQkSm+U8mxqc9y+CSRU3+JDo0pRYtaXdXgalceZpuhiEvDecQYnvWrRZSmh9 q4Lp0JXGkOcnjN9ovzNnCyT67OgHIXPBb82S1AoG2kgfGBKZc2sD8teiKoBGtAB68PhcfSq0 8gbMHWEqarymDFLjmDsZX3fQ2GvJM7Hi9r888QNjP1SLCz77KKvG7CWqKP+Tqr56gqU/fmJx M7zFsk6E0ZRgDFYre7sXL6yWNpVVhTPZmhAC+GnUx4t0vP5p5KJiIf5DLNXYkcCkvtYFwiTj /3OH+elTtXRKlgXN/bNGTnFrmpKqEld4sJtd2GM5ogNCNG2o/UFgy5CL5AsuyIcIWs/BPGhN ypBb5t+QOqjgu0b9Gczvb+uNrGwykpRc1ISn615oaKDXOwi62yWTZ7C/2POPZwFv62qd8UUF BwDabKklDPxH08ypfWPKpLG+/M26hbMCka9czhoX9+Y94lb1uoAuA22ha5I3AiUexGSbV3jB AM0qiKsIu4DAuoJ+bAEdRq+cD2BN4Ic2q4ziRK2daKzDVfAionnT/yDWuuUHcgSl1ik4DDqJ erqTBxGYC2NCIf99cBXoBcwdW0+r6Eh6Ev2Ol+qXdbsw2zg6cEtmMYO85WlckzaAZFRrx/Ll zv8n53YkNke7kAK0DS/2h9vtu8oEP6avwkItaaOYin4BRQ3xjvpH9Bsi9Tfq2XLgsRLJWk/0 HVvab7Wq9vYTE+nNQ3v4nIjM2w5Rk/pFQ4eIUXR9ImsskhrpeK4m3dINkB/eFHK8u1qkcp+N B04iULEzmm0rqQ2qlB7iN4k3vN1PnMfk2F+2sEixrMt1Oi88uj0UCr+fj20/kxx84RzniReP GHRdtIHiuGKtg2F6TZG0b5scj12Vo7c8w5BB5035MeF8qskPq9DT11CvI5PbKvNLjQrfQE1I 3uTN1gEpk96QZW6dmJE6ACO8jPO/FB59RtvrOAdLOwRAuajlYtNbIJ4Wpe64tJ2CWNmI4B2S e42tdTR7tXhFQviutKESR+F6LtjQOmZ2/RSTxXpvGG/FmQlXDvJVpkwmZvTyEMgMe6XBequF FS9KdvgT9pOIRGxqKHQsIb1iC3PA4jMvQWMw90qhFruJpTAf3DbS7G7Z7V9bDHXFdQ+7KXv+ vliaso+jlyC6k7ElQXySHvg90DqlwdyGOMX8CUBa0KgWnWLrm6AUHplwy9YwngAAPmIlcDvn a3LecKPZSgfG/Ys5ymvG3NfR3AYVaJkU1reERFLskgbGSy9yI3CUBt6ICF+NJerxDyrAceDh er/mF1nbix+IJW3ojvUb4ZmzIvidRHUPtmSaJ+J00cX1lA9LvAMACgoCeBwx41hatUVQ8WLX CLBa2jXcw6aK1glxKPC5zrYMw5nepdBPylZIjKWgho+Tsk3sVKVbxI7zg7lhZjLwKo7Tkd+h co0wgpBZ3q3X1/AEuS4A92q0uZZyq0axOaq9MofStF2/yB3zfKige2mr6mVM2CeZTCuRuW2q JMPXM2JdGIpZcIw13iYjA7l2F44YfWoR2DQDTaJPJW/7mucW+kIg/0ZTSzFSMwlPZgcz0UVt evOpFH/rrrCv3yn4SLH2AEh82gYZJxwql+Klkc+1K9ztCyFoOUcocHuqMoFxM9iCvNUB/Rhv McQbf3qF4fLCkX/fFkxx0wMYt8sfAhEigvSrsGnuA8RIzyDR/i97JJ4idrm4MdTTFBWEL9n5 42wB+9FRAYL254NSKcf1IpSd3T2RQeQhozDbT14R6hcQsb+aFG6NDZwBVz262yGzEpRV/3h/ fACk4FLOtMG0s56eNNpW2ugHNVPsZVL0EEUk0dblwvm82XoO9OmiRaoTjuaq1dMDCHfu3vd8 bYWvWdNzoJlHkFSfAxXeNwRTz50gu+r09k4ej5pIltys7vhRvKQt2VVHW7T57M0EcPXx1rGx OzW8nzHhBMWHzr6fRs8J31un+etMsbn9EVnPwJRHDIeWcBWsL2PYvqUNyZYEmUtISS/Vv6j/ 1WtvWAMo4Z4WuxBBaEr+VdV1TF5h8PT0oXOpIRiQ6goNaoTCz9t1jxZCHS0LFPVf7yB3/Ml3 OqvDE/CPYrvBEWAyBjp4twb2X584JpRJlgWvsOczRjhz1n+e90hi2GXbJ3TyiL5z8OF02CBi czWGGbOu++jdd/9FatHZFpZ3M1wjtxPYo2JrlaxjDaC22WH714G/z7Geh9TKh1Zm3Xq1CTTL aV34IXXk849RWa9esvVz5pSb/RVRp95bNXP3+FunjieuzM3ogugG0iKoAOS8ibH77od4vY9t t5GW6zoUBhyw5HI3o0g8FKXBoZ7hA+zF4poxnwszOrPMnzwXlfpgI96LbQWzNCPB/kdYgj1K zK4PbpP4L3I3YmkoWkBaoPxoxv924L8/phsu8DuwBwE4oyBwjgVrpG2RHZJcySXxnDPjZwMC jCR65fsnw0WW8N9cCY7wWsvO9vSo+w9txWyNnbb+LnrztTW8osyQUz/41u6BS5Lt1hKnNdZc mws94ANrmYtIR4mUNKXOZtaq67tpDELp7TBc2XUDAAp4WP/AbEharSv5Cyavr7gi0boFO0dg Zny1yFDMAnWagh3EHL5piKZ5gHJpUKF6D+yaZmuTvAR4uVNUYCK6uHWJQfTH15JWk0xnR8bg svx+hLLfg2n8Kv6T/lN7GoCLDTsBolg/MCKtye5x+EQUyhpIu2xsn6OAH1WLAvi1OvMTLquG qIQx4A0LqxK74x6PaJE4L8goKxdZ8ADmSZLlmAEaH63IL3I+qCXvdcxlpgQ1tsPS/r0t/v49 Pdmr0pzLcxQV4HcKGTQmLNGFjBxlQdVgEh9WVWIt7WmAR5FRFAVT3FgX6OJrIJoXotUV3I4H TurZJAiLyEzGhk0Zat5XgVKjarOH7Yh9N8NsYBiWEx/PDxophAS94L3Ezhhan75u+kCEXtTT jg4O4jtSl4Z4nzHlHOch/weF+YN/MuTXdf9oSOSDxcBLFKYm83Tiyv2HzBL8DI8KiJMknyV0 /eVNNcciYKoev4NYCiYnDbQe6b69ZobCC6pfxnVwGPy61obW+D2Fg9URaoDLSL+ZMFhpe7nb /qXJXFF8jzViM+zGL1S91qvffWug9jEcujjdeoJSn4mFNLSzc80MPj36Af3EjqOdUMhdXOaL hVQP9Iu7N6XvZaarmUjlKwcz1CYgpwUJuPcbwwWNciShTEjLFiTtExOTZvk73TZ+MIFqu/Qx x9zaUL+c3gwIavc84bPi/qJn+t0QIJkm6owCvzDQZx35zmTTGWfkanY269rgCkUVagoPxC1q 4emnGyQP0u3HZN0JwejavrgDTHGwYqd4PjAzNoRBw9ucHu81Flf+yNFwrR+Jt/PWkxXb+BAX sW7Z3VtFwALQ1MMLaAjYDsrCMoDtrFksy1yM9SYYwngxHlBl9S5g/W1gAZdB4d6M5NcAVmtH uKmIJGFlgvz11xa6du9jmP/c4ds= bouncycastle-1.49.orig/test/data/org/bouncycastle/mail/smime/test/validator.longValidity.eml0000644000175000017500000000612610503212005031737 0ustar ebourgebourgFrom: "Armin Häberling" To: testmail@bouncycastle.org Subject: Validator Test LongValidity Message-ID: <27789929.11157112083150.JavaMail.armin@lappi> MIME-Version: 1.0 Content-Type: multipart/signed; protocol="application/pkcs7-signature"; micalg=sha1; boundary="----=_Part_0_10440721.1157112083112" ------=_Part_0_10440721.1157112083112 Content-Type: text/plain; charset=us-ascii Content-Transfer-Encoding: 7bit This is a Test Mail! ------=_Part_0_10440721.1157112083112 Content-Type: application/pkcs7-signature; name=smime.p7s; smime-type=signed-data Content-Transfer-Encoding: base64 Content-Disposition: attachment; filename="smime.p7s" Content-Description: S/MIME Cryptographic Signature MIAGCSqGSIb3DQEHAqCAMIACAQExCzAJBgUrDgMCGgUAMIAGCSqGSIb3DQEHAQAAoIIFNzCCAoAw ggHpoAMCAQICAQEwDQYJKoZIhvcNAQEFBQAwNDELMAkGA1UEBhMCQ0gxJTAjBgNVBAMTHFNpZ25l ZE1haWxWYWxpZGF0b3JUZXN0IFJvb3QwHhcNMDYwODI2MTI1NzUyWhcNMTYwODIzMTI1NzUyWjA0 MQswCQYDVQQGEwJDSDElMCMGA1UEAxMcU2lnbmVkTWFpbFZhbGlkYXRvclRlc3QgUm9vdDCBnzAN BgkqhkiG9w0BAQEFAAOBjQAwgYkCgYEA4s2LugTz/byjUAsZAGe0T1U3GTYzYckXSn2N75agogy3 eqWD7DC3CdiaCYj1qkogZXTiGlyziBa3oYqhy9wN9bFSobLlOJlNFvl2hdBS769nMfvCdoNWNc5R 8qI4BZBFJgm2OtnlQC8r0Kc2iUFqx/HSoN4svXfkYEIjXR5cJhcCAwEAAaOBoTCBnjAPBgNVHRMB Af8EBTADAQH/MB0GA1UdDgQWBBQ6maBDgpnIH6sSFWsCM6w1aLo+ljBcBgNVHSMEVTBTgBQ6maBD gpnIH6sSFWsCM6w1aLo+lqE4pDYwNDELMAkGA1UEBhMCQ0gxJTAjBgNVBAMTHFNpZ25lZE1haWxW YWxpZGF0b3JUZXN0IFJvb3SCAQEwDgYDVR0PAQH/BAQDAgEGMA0GCSqGSIb3DQEBBQUAA4GBAFcv F59aBSc8Hmxgtd05PdiOpHTEUaaQ8LdK9jdOBDtoHozNwHXoQLQZJN55Nowvori5s7yt25fjvB6h 5flkdnisqEU01I4+L/cySWPQQJFWOc+4D/BgfLGQUKK4Zenm3ky6UrywtXDvB7Af5CzZopf13i2k d6l1vZ/mXGe9/easMIICrzCCAhigAwIBAgIBFDANBgkqhkiG9w0BAQQFADA0MQswCQYDVQQGEwJD SDElMCMGA1UEAxMcU2lnbmVkTWFpbFZhbGlkYXRvclRlc3QgUm9vdDAgFw0wNjA5MDExMTAwMDBa GA8yMTA2MDgwODExMDAwMFowZDELMAkGA1UEBhMCQ0gxJjAkBgkqhkiG9w0BCQEWF2FybWluaGFA c3R1ZGVudC5ldGh6LmNoMS0wKwYDVQQDEyRTaWduZWRNYWlsVmFsaWRhdG9yVGVzdCBMb25nVmFs aWRpdHkwgZ8wDQYJKoZIhvcNAQEBBQADgY0AMIGJAoGBALVpQlq5az05GA6c+huKS5fDvc+3UqE/ WDwEf8pJumJQGWfpi8O6Xs4IZrUfSSDqPTV7j5A/8j/f2AoCfd/7w2IeQ3C0HiYJIsD851fpQfcL vlb4/fMWZije0gR64SZ6lVhSZIPOqMmIlyNOTJUyYurusMbjc96pJlC22gKFIuJ3AgMBAAGjgZ4w gZswDAYDVR0TAQH/BAIwADAOBgNVHQ8BAf8EBAMCB4AwHQYDVR0OBBYEFI1j+O4aW9406QoSu1lr K31q5iMEMFwGA1UdIwRVMFOAFDqZoEOCmcgfqxIVawIzrDVouj6WoTikNjA0MQswCQYDVQQGEwJD SDElMCMGA1UEAxMcU2lnbmVkTWFpbFZhbGlkYXRvclRlc3QgUm9vdIIBATANBgkqhkiG9w0BAQQF AAOBgQB0Lt0+td1mbBtP0R1QrCnAKwqpSOL99iAfBb1tg56LJE04upuF6zy0umlEzJ6UvkWafWJs 6A2UBh+yQk5CY1g8tKhV+GLrg/zfaCx8/qq17qpooHJbcu7mdojrElaBBj285ngyPxqoQdn10hJp /0uSrY3T6ZMKwyVGEWwwm5i6ATGCAXUwggFxAgEBMDkwNDELMAkGA1UEBhMCQ0gxJTAjBgNVBAMT HFNpZ25lZE1haWxWYWxpZGF0b3JUZXN0IFJvb3QCARQwCQYFKw4DAhoFAKCBkzAYBgkqhkiG9w0B CQMxCwYJKoZIhvcNAQcBMBwGCSqGSIb3DQEJBTEPFw0wNjA5MDExMjAxMjNaMCMGCSqGSIb3DQEJ BDEWBBTnzDDJJYvkUebVJIdBB7ziFjdxbTA0BgkqhkiG9w0BCQ8xJzAlMAoGCCqGSIb3DQMHMA4G CCqGSIb3DQMCAgIAgDAHBgUrDgMCBzANBgkqhkiG9w0BAQEFAASBgDFNkMbiOzdhwsxDjEDjJYQd X6t3B9MRCd+Pft9luGy9veG1LXWstqCEhHg1qe7LI2Av+/uACjdWzR2IpvSZnzll/rwI5LPLU8Pc qE5NPJHG7AOCneNvC4o156GolOCuAS5aBVaY0vZsPcN3ICC7A6Vm+mkPw3N8LZxutUCQSlAhAAAA AAAA ------=_Part_0_10440721.1157112083112-- bouncycastle-1.49.orig/test/data/org/bouncycastle/mail/smime/test/validator.extKeyUsage.eml0000644000175000017500000000616410503212005031532 0ustar ebourgebourgFrom: "Armin Häberling" To: testmail@bouncycastle.org Message-ID: <27789929.11156777297553.JavaMail.armin@lappi> Subject: Validator Test Extended Key Usage MIME-Version: 1.0 Content-Type: multipart/signed; protocol="application/pkcs7-signature"; micalg=sha1; boundary="----=_Part_0_10440721.1156777297487" ------=_Part_0_10440721.1156777297487 Content-Type: text/plain; charset=us-ascii Content-Transfer-Encoding: 7bit This is a Test Mail! ------=_Part_0_10440721.1156777297487 Content-Type: application/pkcs7-signature; name=smime.p7s; smime-type=signed-data Content-Transfer-Encoding: base64 Content-Disposition: attachment; filename="smime.p7s" Content-Description: S/MIME Cryptographic Signature MIAGCSqGSIb3DQEHAqCAMIACAQExCzAJBgUrDgMCGgUAMIAGCSqGSIb3DQEHAQAAoIIFSTCCAoAw ggHpoAMCAQICAQEwDQYJKoZIhvcNAQEFBQAwNDELMAkGA1UEBhMCQ0gxJTAjBgNVBAMTHFNpZ25l ZE1haWxWYWxpZGF0b3JUZXN0IFJvb3QwHhcNMDYwODI2MTI1NzUyWhcNMTYwODIzMTI1NzUyWjA0 MQswCQYDVQQGEwJDSDElMCMGA1UEAxMcU2lnbmVkTWFpbFZhbGlkYXRvclRlc3QgUm9vdDCBnzAN BgkqhkiG9w0BAQEFAAOBjQAwgYkCgYEA4s2LugTz/byjUAsZAGe0T1U3GTYzYckXSn2N75agogy3 eqWD7DC3CdiaCYj1qkogZXTiGlyziBa3oYqhy9wN9bFSobLlOJlNFvl2hdBS769nMfvCdoNWNc5R 8qI4BZBFJgm2OtnlQC8r0Kc2iUFqx/HSoN4svXfkYEIjXR5cJhcCAwEAAaOBoTCBnjAPBgNVHRMB Af8EBTADAQH/MB0GA1UdDgQWBBQ6maBDgpnIH6sSFWsCM6w1aLo+ljBcBgNVHSMEVTBTgBQ6maBD gpnIH6sSFWsCM6w1aLo+lqE4pDYwNDELMAkGA1UEBhMCQ0gxJTAjBgNVBAMTHFNpZ25lZE1haWxW YWxpZGF0b3JUZXN0IFJvb3SCAQEwDgYDVR0PAQH/BAQDAgEGMA0GCSqGSIb3DQEBBQUAA4GBAFcv F59aBSc8Hmxgtd05PdiOpHTEUaaQ8LdK9jdOBDtoHozNwHXoQLQZJN55Nowvori5s7yt25fjvB6h 5flkdnisqEU01I4+L/cySWPQQJFWOc+4D/BgfLGQUKK4Zenm3ky6UrywtXDvB7Af5CzZopf13i2k d6l1vZ/mXGe9/easMIICwTCCAiqgAwIBAgIBDjANBgkqhkiG9w0BAQQFADA0MQswCQYDVQQGEwJD SDElMCMGA1UEAxMcU2lnbmVkTWFpbFZhbGlkYXRvclRlc3QgUm9vdDAeFw0wNjA4MjgxNDIwMzVa Fw0wNzA4MjgxNDIwMzVaMGMxCzAJBgNVBAYTAkNIMSYwJAYJKoZIhvcNAQkBFhdhcm1pbmhhQHN0 dWRlbnQuZXRoei5jaDEsMCoGA1UEAxMjU2lnbmVkTWFpbFZhbGlkYXRvclRlc3QgRXh0S2V5VXNh Z2UwgZ8wDQYJKoZIhvcNAQEBBQADgY0AMIGJAoGBANI+H1cJFFbL9i89eSEpsqngQysvRVmJc9zM u+hDRUTcVxD2yvbzVK+6GKTUPObP679KrpfB55U/l9+OAMrTfDs43u6yahMMqxT1aHpsH2y7djso 8xkLKvx2M06kVoobxPZff/ApbAv+mWqzWmRis6DvAWd1eW8k+1vswE33V6OtAgMBAAGjgbMwgbAw DAYDVR0TAQH/BAIwADAdBgNVHQ4EFgQUYUF/LLxg5q1bayoD2ggruf3QGF8wXAYDVR0jBFUwU4AU OpmgQ4KZyB+rEhVrAjOsNWi6PpahOKQ2MDQxCzAJBgNVBAYTAkNIMSUwIwYDVQQDExxTaWduZWRN YWlsVmFsaWRhdG9yVGVzdCBSb290ggEBMA4GA1UdDwEB/wQEAwIHgDATBgNVHSUEDDAKBggrBgEF BQcDCDANBgkqhkiG9w0BAQQFAAOBgQCsshhqSn+pThjrRMvmaMoPs4ZUQYZA1/F4xF8H7JRPGJb8 zIIlKpQSuLV+b3vTpYKqjwSeauFhT+buUvmzrAkjBI3OkFHeNbETkOJU8EDG2Bb2IvlyZiaXY6wZ hJT9RkSFDhv1Swd67CY97UBtW3KKnFgp4Rs2DSdiylvTwxYU8TGCAXUwggFxAgEBMDkwNDELMAkG A1UEBhMCQ0gxJTAjBgNVBAMTHFNpZ25lZE1haWxWYWxpZGF0b3JUZXN0IFJvb3QCAQ4wCQYFKw4D AhoFAKCBkzAYBgkqhkiG9w0BCQMxCwYJKoZIhvcNAQcBMBwGCSqGSIb3DQEJBTEPFw0wNjA4Mjgx NTAxMzdaMCMGCSqGSIb3DQEJBDEWBBTnzDDJJYvkUebVJIdBB7ziFjdxbTA0BgkqhkiG9w0BCQ8x JzAlMAoGCCqGSIb3DQMHMA4GCCqGSIb3DQMCAgIAgDAHBgUrDgMCBzANBgkqhkiG9w0BAQEFAASB gEwdu6LKpc0BJ6zBA96xHDpF8zy90hNTQfoj+J145zy+2kuO2QdyElwxcsuGjjWiT+VzBNhDw4/R k2TVu+i5BcubxxrHyM5kZ5Z9t+FdC6kikMStMmWQeC7VtatufkIA4h5DQ+v3/7nAdDxBEQpNB+Vc nTNBWNohT0BqIdr4KJK6AAAAAAAA ------=_Part_0_10440721.1156777297487-- bouncycastle-1.49.orig/test/data/org/bouncycastle/mail/smime/test/dotnet_enc_cert.pem0000644000175000017500000000406611604226442030467 0ustar ebourgebourg-----BEGIN CERTIFICATE----- MIIFyjCCBLKgAwIBAgIKEhRhbQAAAAADWjANBgkqhkiG9w0BAQUFADBTMRMwEQYK CZImiZPyLGQBGRYDY29tMRgwFgYKCZImiZPyLGQBGRYIbWVkaWNpdHkxFjAUBgoJ kiaJk/IsZAEZFgZtZWRzbGMxCjAIBgNVBAMMASowHhcNMTEwNjI4MTU0NTUxWhcN MTIwMjE2MTc1MzU5WjCBsTETMBEGCgmSJomT8ixkARkWA2NvbTEYMBYGCgmSJomT 8ixkARkWCG1lZGljaXR5MRYwFAYKCZImiZPyLGQBGRYGbWVkc2xjMRcwFQYDVQQL Ew5NZWRpY2l0eSBVc2VyczEUMBIGA1UECxMLRGV2ZWxvcG1lbnQxFDASBgNVBAMT C01hcmsgUGFya2VyMSMwIQYJKoZIhvcNAQkBFhRtcGFya2VyQG1lZGljaXR5LmNv bTCBnzANBgkqhkiG9w0BAQEFAAOBjQAwgYkCgYEA08LXWOeJfgeDg32drx2pyJjq YcGWjPSPGg18VGeZZgss0gFGfgcAXInY+uZnVjG4GsPMbpDL6bFjrXs1JjdtraOs Yw9qk7BHG6dHNK1ADK+NPwDY80xAK+Z8Ztg0YUMrjeUlYHpvNpxr8kVsFqW/35iL nHz8mm0/1dlr3zfO1bUCAwEAAaOCAsMwggK/MBcGCSsGAQQBgjcUAgQKHggAVQBz AGUAcjApBgNVHSUEIjAgBgorBgEEAYI3CgMEBggrBgEFBQcDBAYIKwYBBQUHAwIw CwYDVR0PBAQDAgWgMEQGCSqGSIb3DQEJDwQ3MDUwDgYIKoZIhvcNAwICAgCAMA4G CCqGSIb3DQMEAgIAgDAHBgUrDgMCBzAKBggqhkiG9w0DBzAdBgNVHQ4EFgQUiO27 fGR7QWNICiRAKzzQeHI8MLMwHwYDVR0jBBgwFoAUIai0WOwGVg5JWe3fQyn+0jaK f5EwgdIGA1UdHwSByjCBxzCBxKCBwaCBvoaBu2xkYXA6Ly8vQ049ITAwMmEsQ049 U0xDLU1FRC1EQzEsQ049Q0RQLENOPVB1YmxpYyUyMEtleSUyMFNlcnZpY2VzLENO PVNlcnZpY2VzLENOPUNvbmZpZ3VyYXRpb24sREM9bWVkc2xjLERDPW1lZGljaXR5 LERDPWNvbT9jZXJ0aWZpY2F0ZVJldm9jYXRpb25MaXN0P2Jhc2U/b2JqZWN0Q2xh c3M9Y1JMRGlzdHJpYnV0aW9uUG9pbnQwgcIGCCsGAQUFBwEBBIG1MIGyMIGvBggr BgEFBQcwAoaBomxkYXA6Ly8vQ049ITAwMmEsQ049QUlBLENOPVB1YmxpYyUyMEtl eSUyMFNlcnZpY2VzLENOPVNlcnZpY2VzLENOPUNvbmZpZ3VyYXRpb24sREM9bWVk c2xjLERDPW1lZGljaXR5LERDPWNvbT9jQUNlcnRpZmljYXRlP2Jhc2U/b2JqZWN0 Q2xhc3M9Y2VydGlmaWNhdGlvbkF1dGhvcml0eTBMBgNVHREERTBDoCsGCisGAQQB gjcUAgOgHQwbbXBhcmtlckBtZWRzbGMubWVkaWNpdHkuY29tgRRtcGFya2VyQG1l ZGljaXR5LmNvbTANBgkqhkiG9w0BAQUFAAOCAQEAAUPwYfpibwKPWZZc+lCabaHZ l5pL8hWaZH2WTV7/CsuGbdZw+cS0dsbb08XIXFKhF2lKGbWGHqgQmgmOuDZUBE1z lw94AI5t9tQzbCKbgdiCiQpxjJ9xNyIbCO4/2wAQfM5gl7hc9M6FVa0Pk6OIJQs7 kdNYQgSvP7TpJuEMZ8Sag/MRjCOnYEfyPzntIKM545WBxGlit8x8ND5jZArDg4Cj iIx02LCjuQyWywCLiEVvndycIja7J4Fpf0NuUIojsOpi30lHTmbDjs3CnbP3edOI Giaqtmtz08oWSkylStTJInC25gKepyBts38GOodtJ9oRpW1xVlp7kEaUEgcGfA== -----END CERTIFICATE----- bouncycastle-1.49.orig/test/data/org/bouncycastle/mail/smime/test/validator.expired.eml0000644000175000017500000000611010503212005030723 0ustar ebourgebourgFrom: "Armin Häberling" To: testmail@bouncycastle.org Subject: Validator Test Expired Message-ID: <27789929.11157101715132.JavaMail.armin@lappi> MIME-Version: 1.0 Content-Type: multipart/signed; protocol="application/pkcs7-signature"; micalg=sha1; boundary="----=_Part_0_10440721.1157101715093" ------=_Part_0_10440721.1157101715093 Content-Type: text/plain; charset=us-ascii Content-Transfer-Encoding: 7bit This is a Test Mail! ------=_Part_0_10440721.1157101715093 Content-Type: application/pkcs7-signature; name=smime.p7s; smime-type=signed-data Content-Transfer-Encoding: base64 Content-Disposition: attachment; filename="smime.p7s" Content-Description: S/MIME Cryptographic Signature MIAGCSqGSIb3DQEHAqCAMIACAQExCzAJBgUrDgMCGgUAMIAGCSqGSIb3DQEHAQAAoIIFMDCCAoAw ggHpoAMCAQICAQEwDQYJKoZIhvcNAQEFBQAwNDELMAkGA1UEBhMCQ0gxJTAjBgNVBAMTHFNpZ25l ZE1haWxWYWxpZGF0b3JUZXN0IFJvb3QwHhcNMDYwODI2MTI1NzUyWhcNMTYwODIzMTI1NzUyWjA0 MQswCQYDVQQGEwJDSDElMCMGA1UEAxMcU2lnbmVkTWFpbFZhbGlkYXRvclRlc3QgUm9vdDCBnzAN BgkqhkiG9w0BAQEFAAOBjQAwgYkCgYEA4s2LugTz/byjUAsZAGe0T1U3GTYzYckXSn2N75agogy3 eqWD7DC3CdiaCYj1qkogZXTiGlyziBa3oYqhy9wN9bFSobLlOJlNFvl2hdBS769nMfvCdoNWNc5R 8qI4BZBFJgm2OtnlQC8r0Kc2iUFqx/HSoN4svXfkYEIjXR5cJhcCAwEAAaOBoTCBnjAPBgNVHRMB Af8EBTADAQH/MB0GA1UdDgQWBBQ6maBDgpnIH6sSFWsCM6w1aLo+ljBcBgNVHSMEVTBTgBQ6maBD gpnIH6sSFWsCM6w1aLo+lqE4pDYwNDELMAkGA1UEBhMCQ0gxJTAjBgNVBAMTHFNpZ25lZE1haWxW YWxpZGF0b3JUZXN0IFJvb3SCAQEwDgYDVR0PAQH/BAQDAgEGMA0GCSqGSIb3DQEBBQUAA4GBAFcv F59aBSc8Hmxgtd05PdiOpHTEUaaQ8LdK9jdOBDtoHozNwHXoQLQZJN55Nowvori5s7yt25fjvB6h 5flkdnisqEU01I4+L/cySWPQQJFWOc+4D/BgfLGQUKK4Zenm3ky6UrywtXDvB7Af5CzZopf13i2k d6l1vZ/mXGe9/easMIICqDCCAhGgAwIBAgIBEDANBgkqhkiG9w0BAQQFADA0MQswCQYDVQQGEwJD SDElMCMGA1UEAxMcU2lnbmVkTWFpbFZhbGlkYXRvclRlc3QgUm9vdDAeFw0wNjA4MjYxMjU3NTJa Fw0wNjA5MDEwODM5MjBaMF8xCzAJBgNVBAYTAkNIMSYwJAYJKoZIhvcNAQkBFhdhcm1pbmhhQHN0 dWRlbnQuZXRoei5jaDEoMCYGA1UEAxMfU2lnbmVkTWFpbFZhbGlkYXRvclRlc3QgRXhwaXJlZDCB nzANBgkqhkiG9w0BAQEFAAOBjQAwgYkCgYEAwvaClfyxSvpK4A74gRYTGBqErtDe6bTOfzRtuuth WXIJPWYxAjBCTBO8huqojDnsy6Gy10P3o2E4Labuw6ae9ayeyBTgwaTzGBsAg1kFD2Sd/RWogkru aY1q3fmHGIMapfX7LwRxeWIqjNv9hvogzT73CWeOn1IiF2JpOuCqDWMCAwEAAaOBnjCBmzAMBgNV HRMBAf8EAjAAMB0GA1UdDgQWBBSb+XFbXFWFQtmYtpRr3JXvnCmSFTBcBgNVHSMEVTBTgBQ6maBD gpnIH6sSFWsCM6w1aLo+lqE4pDYwNDELMAkGA1UEBhMCQ0gxJTAjBgNVBAMTHFNpZ25lZE1haWxW YWxpZGF0b3JUZXN0IFJvb3SCAQEwDgYDVR0PAQH/BAQDAgeAMA0GCSqGSIb3DQEBBAUAA4GBAKiY QC6Cyr4IXHMw2AcL1jo5thNcoSVX1tK8xFC/jCzHgvy0CGkeFA/ilsn1rn9orLX0ypx85P0dI7MZ vmYiGnTPuuvua9GDyW3z0ypur3YEHt2tcsvm4iiHZeRgyooNhItihomc4YNBE0rFMM5ewaMw5CLf ZmXzxz8SGxhFiwj5MYIBdTCCAXECAQEwOTA0MQswCQYDVQQGEwJDSDElMCMGA1UEAxMcU2lnbmVk TWFpbFZhbGlkYXRvclRlc3QgUm9vdAIBEDAJBgUrDgMCGgUAoIGTMBgGCSqGSIb3DQEJAzELBgkq hkiG9w0BBwEwHAYJKoZIhvcNAQkFMQ8XDTA2MDkwMTA5MDgzNVowIwYJKoZIhvcNAQkEMRYEFOfM MMkli+RR5tUkh0EHvOIWN3FtMDQGCSqGSIb3DQEJDzEnMCUwCgYIKoZIhvcNAwcwDgYIKoZIhvcN AwICAgCAMAcGBSsOAwIHMA0GCSqGSIb3DQEBAQUABIGAKp/WFAgXSoqWggroUrX858toEWdAPfOg Bu602NOZKxmd3nRt9pHs+Wi3c5vrMHwYZE/3EVenjkz1VUHBU62bLvJi1RQ3Vso7BbTcU1PEy6dZ JLaEpI/1XAIQzrMyeRTS4W8RFNO7vqnpzaq8WyrHOy1l2gxWmqsxwx+0Uj3NMWMAAAAAAAA= ------=_Part_0_10440721.1157101715093-- bouncycastle-1.49.orig/test/data/org/bouncycastle/mail/smime/test/basicAS2.message0000644000175000017500000000701710555315542027565 0ustar ebourgebourgPOST / HTTP/1.1 Host: 216.18.74.3:21050 Cache-Control: no-cache User-Agent: bTrade, Inc. TDServer AS2 Service From: parcuri@btrade.com Reply-To: parcuri@btrade.com To: http://216.18.74.3:21050/ AS2-From: b*Trade AS2-To: 0010-450014-900 AS2-Version: 1.1 Date: Mon, 17 Feb 2003 21:01:00 GMT Subject: Test B Message-Id: <20030217210100_E02431B950@bTrade> Disposition-Notification-To: parcuri@btrade.com Disposition-Notification-Options: signed-receipt-protocol=optional, pkcs7-signature; signed-receipt-micalg=optional, sha1 Content-Type: multipart/signed; protocol="application/pkcs7-signature"; micAlg=sha1; boundary="--=_SIGNED-MSG.922A545DEC" Content-length: 2915 ----=_SIGNED-MSG.922A545DEC Content-Type: application/edifact; charset="us-ascii"; name="edifact.edi" Content-Disposition: attachment; filename="edifact.edi" UNA:+.? 'UNB+UNOA:1+TESTER1:ZZ+TESTER2:ZZ+961007:2013+000000003+AAA:AA+1A+1++123456789+1'UNH+000050001+ORDERS:00D:94B:UN+23X232323232EC+1:C'BGM+105:161:136:PURCHASE ORDER+1A+9+NA'DTM+11:071096:2'PAI+2:44:11:107:11:5'ALI+UK+8+21+22+11'IMD+B+3+123-ABC:35'LIN+1+18+1:CV:110:108+1+67+I'LIN+2+18+1:CV:110:108+1+67+I'LIN+3+18+1:CV:110:108+1+67+I'LIN+4+18+1:CV:110:108+1+67+I'LIN+5+18+1:CV:110:108+1+67+I'LIN+6+18+1:CV:110:108+1+67+I'LIN+7+18+1:CV:110:108+1+67+I'LIN+8+18+1:CV:110:108+1+67+I'LIN+9+18+1:CV:110:108+1+67+I'LIN+10+18+1:CV:110:108+1+67+I'LIN+11+18+1:CV:110:108+1+67+I'LIN+12+18+1:CV:110:108+1+67+I'LIN+13+18+1:CV:110:108+1+67+I'LIN+14+18+1:CV:110:108+1+67+I'LIN+15+18+1:CV:110:108+1+67+I'LIN+16+18+1:CV:110:108+1+67+I'LIN+17+18+1:CV:110:108+1+67+I'LIN+18+18+1:CV:110:108+1+67+I'LIN+19+18+1:CV:110:108+1+67+I'LIN+20+18+1:CV:110:108+1+67+I'LIN+21+18+1:CV:110:108+1+67+I'LIN+22+18+1:CV:110:108+1+67+I'LIN+23+18+1:CV:110:108+1+67+I'LIN+24+18+1:CV:110:108+1+67+I'LIN+25+18+1:CV:110:108+1+67+I'PIA+2+123-EFG:CV:190:104'MEA+AAJ+CHN:7:8:JJHJHGJG+THG:2323.90:1122:767756+RR'QTY+164:4243234242:232'ALI+JA+8+20'UNS+S'MOA+109:23321:UK:6:2'UNT+38+000050001'UNZ+1+000000003' ----=_SIGNED-MSG.922A545DEC Content-type: application/pkcs7-signature; name="smime.p7s" Content-Disposition: attachment; filename="smime.p7s" 0€ *†H†÷  €0€1 0 +0€ *†H†÷  €0‚Ë0‚³ 0  *†H†÷ 0Â1 0 UUS10 UTEXAS10 UIRVING10U  BTRADE, INC.10U QUALITY ASSURANCE10 USECOFR1!0U INTEROP SECURITY OFFICER10U 2324 GATEWAY DRIVE10 U750630 030109194843Z 050109194843Z0Æ1 0 UUS10 UTEXAS10 UIRVING10U  BTRADE, INC.10U  DEVELOPMENT10U BTRADE AS21'0%U BTRADE AS2 INTEROP PARTICIPANT10U 2324 GATEWAY DRIVE10 U750630Ÿ0  *†H†÷ 0‰µyüù;Rm.ׂ\ÉK§' '/…’è0ðËÛÔ@·‚gÛå.åþZëÜÃ_㢪) ß‘!Ì$f¶a8þiYe…[P”h¢\ÒHJx¤XnÛê [ù(x[v¢8O·JVø‚Ëõî<=á!!sD—½!b®Y ïò’ýéãJ0H0Uÿð0UsÐ,¼¯?J·—ßK Ýt0U#0€†‘«K+˜®[:ž[:/"0  *†H†÷ ‚¹{&ÿ¸RØŒ]¬IÕú_ªßò#›Œw¿ò~à*)ŸƒEÝÁšè“ÓW*è‡ñ/9ôÅQÉ™ƒý±×f¹Ÿ 0/‰¥ãú”Xᢡâ=¨£%}ò;×­Ñ…™¶Ô®[ÇHâ ¶x½‡êîŒi‚LW{ÓúQÜà1‰·18q 4eQg—”Ç¿‚*CÕ•çˆÒr¾ôÅÚ‹/31>p¹n˜íO›€’R£}'< ÑÛ3Ô/û¹´zÓטÜíAÂ{_b»s'T›QO<éR˜ÜÉ‹Hi‘w{ZÙ_åZÄš·1˜UŸ²9,’r^W]'€…ÝÄf®)ŸòrNÆÀÓ3òUÆ1€0‚k0È0Â1 0 UUS10 UTEXAS10 UIRVING10U  BTRADE, INC.10U QUALITY ASSURANCE10 USECOFR1!0U INTEROP SECURITY OFFICER10U 2324 GATEWAY DRIVE10 U750630 +0  *†H†÷ €M->iojã°B!åôÁdP ‹âW ߟçz,íRKY1šj/CB¢%?wMÞÙÙâ6ù¦ÂSתÜÓ•‰×eôÅÏØy0ÒÆv‚ͱEñ\>“SÆäÞ€¬S ÿ0ŵ4À‰U-’usiŠºš ø¢ì †0¹‘åØâˆ}* ----=_SIGNED-MSG.922A545DEC-- bouncycastle-1.49.orig/test/data/org/bouncycastle/cms/0000755000175000017500000000000012152033550022361 5ustar ebourgebourgbouncycastle-1.49.orig/test/data/org/bouncycastle/cms/test/0000755000175000017500000000000012152033550023340 5ustar ebourgebourgbouncycastle-1.49.orig/test/data/org/bouncycastle/cms/test/PSSSignDataSHA512.sig0000644000175000017500000000657211252340215026721 0ustar ebourgebourg0‚ v *†H†÷  ‚ g0‚ c10  `†He0  *†H†÷  ‚ ý0‚X0‚@ °-0  *†H†÷ 0>1 0 UBE10UFake Smals Citizen CA10 U2009020 090810090503Z 100810090503Z0+1 0 UBE1 0 U00710 Uuser10‚"0  *†H†÷ ‚0‚ ‚¾§CM[hÁ¡d3DM®‰iq@ÕÖ!¤ŠÃçMCp—¤Y0óúöµbp´ Š0Ù i£•Sƒ0“â/ùí³Ÿ†•ám69nt Ï$W51!|D D˧hµÕJl-a^†±b¢F@ à%X-„Œ9É2¸šûUQ<€Ó¾k)‡%<üÃbø%ÛDÂñ¦]û|>3–(ƒ¿û:buþ$Îõ“·–[e $û¹ùí 3KäUà´E?žfâ’L%xPE;Ħ)»j[ûv­ÍB<3qœÂ]µQaú¬íã}UäϽÜKëà >®5Œ@í Ì]TÐZ?mNŒgòÅŸX³£e0c0 U00 U°0Uæ£}2*ˆfONÜ$áðQŠƒhf“0U#0€s9¡5“D(2¦ _«ê”Zf"\0 U00  *†H†÷ ‚¤zÜý Ùˆ¿±Š·hð`²9ó>Wlžãé‰÷p0ÁÊzTÔ.Ÿ&*zˆ@éýöí½ÍËûK¤@dIw`\3µTŸØMrä0¾ ¦ ù. Þë/š·Ob/x–/=¤Â&z4ÿˆ¦v•ªcë" ûs¦ch_óñ1ûGÇLx·-íbé¶ÃUŒ'‡¼}ÃJÂýdO¹]‰ L¹)œùG #Uš[4Ýæ˜+Ž""qOk›­x_»“ú)Óê 3+Ñçn¼À=ÚÑgXºÄ×îã£òÛÌÐ7 ÿÚÖ¼$üèÕhÊç~1÷1Ý-™B Jµ÷ã—*~ j¾0‚0‚í  ×Ö5ào>Å0  *†H†÷ 0*1 0 UBE10UFake Smals Root CA0 090330125856Z 100330125856Z0>1 0 UBE10UFake Smals Citizen CA10 U2009020‚"0  *†H†÷ ‚0‚ ‚½¢OZÓ›šž$H\½]^á˜0ç¡Z!>¤síA3f¯‹\ndñ”ÐVÏÊÀÁ÷… Ù¯u&;ã´½†ÒH[úsF$ ¶R—ržz¬´ç¾ "Àäzhaõé]îüE®}žéÇ"A .Qøÿ¦™xP[ä`=ß«ñ@4{<NJð¡ÇpJ-”oç7¨<)Ls ØáxÇù€ÿY-‡µWFá ctr–BПœWT—UÊa_ŒÕÔNyx ÁžS©ÒÚT[Dgî¥M F›üѤ+Ø&~S]j›ãS°~Â%Ñ÷Ên·h5OR¿u—üå¬ö!ö”m £‚0‚0Us9¡5“D(2¦ _«ê”Zf"\0U#0€þ;LÐÔˆòódR¾ŠéyKÍ–0Uÿ0ÿ0Uÿ0U%0++0 `†H†øB0FU ?0=0;`8010/+#http://repository.fake-eid.smals.be07U00.0, * (†&http://crl.fake-eid.smals.be/smals.crl0  *†H†÷ ‚M‡(©žÅOPrû"·ŒºòpÓä?]T“Ä>W‘Öv^¢Ô¸o†À$bh@OÃ0  *†H†÷ 0*1 0 UBE10UFake Smals Root CA0 090330123606Z 100330123606Z0*1 0 UBE10UFake Smals Root CA0‚"0  *†H†÷ ‚0‚ ‚Ëå!³¨Žzç4Sí$¾›úÛ·DÆ£œëç•Aiò™Þ»ð¢üγ”ל/ ÎdT Az”› nßëÇ'øB1ùÎ@áÃU¡°´à G£ÍÁ1¿’*Q©d^Æ.EV#‰‰òïßnï ¿«¶À›!ôד_©îÔx󳨣pxЯgq›§¶}rK«îmŽ8ñêÈ-{r¸ÓGZ¶Ô^jD:íæä-('—[HBs‚düîw’6ßÝóÂm šš²¿@”úSðÖÀ³f^¢Ž`UfyıâMkšC¿AÔð_l÷€ãü÷õ)Ñ’«`ø¢«”Rÿ룼0¹0Uþ;LÐÔˆòódR¾ŠéyKÍ–0Uÿ0ÿ0Uÿ0U%0++0 `†H†øB0EU >0<0:`8010/+#http://repository.fake-eid.smals.be0  *†H†÷ ‚‚"ñt›K^âŠÁ«éEð»LN‘ôù—=^@¸Wͺ“ç"£"O C®e±xþ0ÉÌúò€èÓ—­Nè›Ú¨u‡°c}#Õÿ‘¤LR U¾<«m·—ðð>!!ÂýÓe$ ͇‡zD„b.x4æê…·=€îfÀåбÇډϠ¸K’ªƒ³pNÏûˆl¯±Ëò–þ·Ó±<š´L'ño2½Ý6ÕÊB<ý!Æ€TTúàóo&Á7°kà…¼BJ+d}½Ñö*'NV×jKŠo1\ÊŸ{X]›X$q@ ý+WàxDÆ"×S"Ø„4[&1‚=0‚90R0>1 0 UBE10UFake Smals Citizen CA10 U200902°-0  `†He ‰0 *†H†÷  1  *†H†÷ 0 *†H†÷  1 090909145658Z0O *†H†÷  1B@:¹Òœm2æ‹Ôn¼ã &•…Å[*!IìÊc)´ÀÆÜЛ_Ù€òê:‹i²\òϲ掾Höâ´úM”üÐ0A *†H†÷  04 0  `†He¡0 *†H†÷ 0  `†He¢@‚7îÀ€)uó·î$¢v¼¼ úGB°.Wÿ=@%TâÉúï^þǵ©0Ì$²¥Æ×UˆÓ Õ›o†JºuÛ²üøÓ#ü¯¥FZ}~ÓlNG/5ïsåT´¬§/Å倉æÒÚTT7×¶qÈFyoÀ*Ÿ}˜­ìa‰°Àv]X‹¾<5¯”Sq¦Óó_g}»+á&>¯}ñâm99˜ùoGî“z”ÈÌŒ¯:™×€å—!‘¾ã̉?±K›9&ÆŸp) —¬lð÷BfŒ|G©¢Vžž¼Ok‡œÎmú»xí«+íÍPÝÓ ã> MÂdm¦À¼bouncycastle-1.49.orig/test/data/org/bouncycastle/cms/test/PSSSignDataSHA512Enc.sig0000644000175000017500000000662411252340215027345 0ustar ebourgebourg0‚  *†H†÷  ‚ 0‚ }10  `†He0% *†H†÷  This is a test message ‚ ý0‚X0‚@ °-0  *†H†÷ 0>1 0 UBE10UFake Smals Citizen CA10 U2009020 090810090503Z 100810090503Z0+1 0 UBE1 0 U00710 Uuser10‚"0  *†H†÷ ‚0‚ ‚¾§CM[hÁ¡d3DM®‰iq@ÕÖ!¤ŠÃçMCp—¤Y0óúöµbp´ Š0Ù i£•Sƒ0“â/ùí³Ÿ†•ám69nt Ï$W51!|D D˧hµÕJl-a^†±b¢F@ à%X-„Œ9É2¸šûUQ<€Ó¾k)‡%<üÃbø%ÛDÂñ¦]û|>3–(ƒ¿û:buþ$Îõ“·–[e $û¹ùí 3KäUà´E?žfâ’L%xPE;Ħ)»j[ûv­ÍB<3qœÂ]µQaú¬íã}UäϽÜKëà >®5Œ@í Ì]TÐZ?mNŒgòÅŸX³£e0c0 U00 U°0Uæ£}2*ˆfONÜ$áðQŠƒhf“0U#0€s9¡5“D(2¦ _«ê”Zf"\0 U00  *†H†÷ ‚¤zÜý Ùˆ¿±Š·hð`²9ó>Wlžãé‰÷p0ÁÊzTÔ.Ÿ&*zˆ@éýöí½ÍËûK¤@dIw`\3µTŸØMrä0¾ ¦ ù. Þë/š·Ob/x–/=¤Â&z4ÿˆ¦v•ªcë" ûs¦ch_óñ1ûGÇLx·-íbé¶ÃUŒ'‡¼}ÃJÂýdO¹]‰ L¹)œùG #Uš[4Ýæ˜+Ž""qOk›­x_»“ú)Óê 3+Ñçn¼À=ÚÑgXºÄ×îã£òÛÌÐ7 ÿÚÖ¼$üèÕhÊç~1÷1Ý-™B Jµ÷ã—*~ j¾0‚0‚í  ×Ö5ào>Å0  *†H†÷ 0*1 0 UBE10UFake Smals Root CA0 090330125856Z 100330125856Z0>1 0 UBE10UFake Smals Citizen CA10 U2009020‚"0  *†H†÷ ‚0‚ ‚½¢OZÓ›šž$H\½]^á˜0ç¡Z!>¤síA3f¯‹\ndñ”ÐVÏÊÀÁ÷… Ù¯u&;ã´½†ÒH[úsF$ ¶R—ržz¬´ç¾ "Àäzhaõé]îüE®}žéÇ"A .Qøÿ¦™xP[ä`=ß«ñ@4{<NJð¡ÇpJ-”oç7¨<)Ls ØáxÇù€ÿY-‡µWFá ctr–BПœWT—UÊa_ŒÕÔNyx ÁžS©ÒÚT[Dgî¥M F›üѤ+Ø&~S]j›ãS°~Â%Ñ÷Ên·h5OR¿u—üå¬ö!ö”m £‚0‚0Us9¡5“D(2¦ _«ê”Zf"\0U#0€þ;LÐÔˆòódR¾ŠéyKÍ–0Uÿ0ÿ0Uÿ0U%0++0 `†H†øB0FU ?0=0;`8010/+#http://repository.fake-eid.smals.be07U00.0, * (†&http://crl.fake-eid.smals.be/smals.crl0  *†H†÷ ‚M‡(©žÅOPrû"·ŒºòpÓä?]T“Ä>W‘Öv^¢Ô¸o†À$bh@OÃ0  *†H†÷ 0*1 0 UBE10UFake Smals Root CA0 090330123606Z 100330123606Z0*1 0 UBE10UFake Smals Root CA0‚"0  *†H†÷ ‚0‚ ‚Ëå!³¨Žzç4Sí$¾›úÛ·DÆ£œëç•Aiò™Þ»ð¢üγ”ל/ ÎdT Az”› nßëÇ'øB1ùÎ@áÃU¡°´à G£ÍÁ1¿’*Q©d^Æ.EV#‰‰òïßnï ¿«¶À›!ôד_©îÔx󳨣pxЯgq›§¶}rK«îmŽ8ñêÈ-{r¸ÓGZ¶Ô^jD:íæä-('—[HBs‚düîw’6ßÝóÂm šš²¿@”úSðÖÀ³f^¢Ž`UfyıâMkšC¿AÔð_l÷€ãü÷õ)Ñ’«`ø¢«”Rÿ룼0¹0Uþ;LÐÔˆòódR¾ŠéyKÍ–0Uÿ0ÿ0Uÿ0U%0++0 `†H†øB0EU >0<0:`8010/+#http://repository.fake-eid.smals.be0  *†H†÷ ‚‚"ñt›K^âŠÁ«éEð»LN‘ôù—=^@¸Wͺ“ç"£"O C®e±xþ0ÉÌúò€èÓ—­Nè›Ú¨u‡°c}#Õÿ‘¤LR U¾<«m·—ðð>!!ÂýÓe$ ͇‡zD„b.x4æê…·=€îfÀåбÇډϠ¸K’ªƒ³pNÏûˆl¯±Ëò–þ·Ó±<š´L'ño2½Ý6ÕÊB<ý!Æ€TTúàóo&Á7°kà…¼BJ+d}½Ñö*'NV×jKŠo1\ÊŸ{X]›X$q@ ý+WàxDÆ"×S"Ø„4[&1‚=0‚90R0>1 0 UBE10UFake Smals Citizen CA10 U200902°-0  `†He ‰0 *†H†÷  1  *†H†÷ 0 *†H†÷  1 090909145658Z0O *†H†÷  1B@:¹Òœm2æ‹Ôn¼ã &•…Å[*!IìÊc)´ÀÆÜЛ_Ù€òê:‹i²\òϲ掾Höâ´úM”üÐ0A *†H†÷  04 0  `†He¡0 *†H†÷ 0  `†He¢@‚4ͳæ>é  B~¹›óþEÉõÉóßå0ÉP/¹ðÒá5æ_wX¢hª¬óWÆOftZ>Ð@Íz‡|7ÿ“ž²W1…ªßûظÔÃZgN?Çš‹;à ´jä5ôÔB [ÿvÀÔ'êÈÙ­Ëv2¯!åþ3÷`eÏM«%Âç:šÅi¿ á^d°F¾ðô«äßþÉA§a‡—Ÿò;ÎfO.ô¨ÿЈañídý™æÐ$±‹œŸ10š–Çn7GV-„{d邃x³.Ú ¹É,ÞX öìJ{ÎTä;ò‚Í8.ó×]4_ûYÅ8E ÌF.×r(ÄÜYä¬:$&‚ïbouncycastle-1.49.orig/test/data/org/bouncycastle/cms/test/PSSSignDataSHA1Enc.sig0000644000175000017500000000645311252340215027176 0ustar ebourgebourg0‚ ' *†H†÷  ‚ 0‚ 1 0 +0% *†H†÷  This is a test message ‚ ý0‚X0‚@ °-0  *†H†÷ 0>1 0 UBE10UFake Smals Citizen CA10 U2009020 090810090503Z 100810090503Z0+1 0 UBE1 0 U00710 Uuser10‚"0  *†H†÷ ‚0‚ ‚¾§CM[hÁ¡d3DM®‰iq@ÕÖ!¤ŠÃçMCp—¤Y0óúöµbp´ Š0Ù i£•Sƒ0“â/ùí³Ÿ†•ám69nt Ï$W51!|D D˧hµÕJl-a^†±b¢F@ à%X-„Œ9É2¸šûUQ<€Ó¾k)‡%<üÃbø%ÛDÂñ¦]û|>3–(ƒ¿û:buþ$Îõ“·–[e $û¹ùí 3KäUà´E?žfâ’L%xPE;Ħ)»j[ûv­ÍB<3qœÂ]µQaú¬íã}UäϽÜKëà >®5Œ@í Ì]TÐZ?mNŒgòÅŸX³£e0c0 U00 U°0Uæ£}2*ˆfONÜ$áðQŠƒhf“0U#0€s9¡5“D(2¦ _«ê”Zf"\0 U00  *†H†÷ ‚¤zÜý Ùˆ¿±Š·hð`²9ó>Wlžãé‰÷p0ÁÊzTÔ.Ÿ&*zˆ@éýöí½ÍËûK¤@dIw`\3µTŸØMrä0¾ ¦ ù. Þë/š·Ob/x–/=¤Â&z4ÿˆ¦v•ªcë" ûs¦ch_óñ1ûGÇLx·-íbé¶ÃUŒ'‡¼}ÃJÂýdO¹]‰ L¹)œùG #Uš[4Ýæ˜+Ž""qOk›­x_»“ú)Óê 3+Ñçn¼À=ÚÑgXºÄ×îã£òÛÌÐ7 ÿÚÖ¼$üèÕhÊç~1÷1Ý-™B Jµ÷ã—*~ j¾0‚0‚í  ×Ö5ào>Å0  *†H†÷ 0*1 0 UBE10UFake Smals Root CA0 090330125856Z 100330125856Z0>1 0 UBE10UFake Smals Citizen CA10 U2009020‚"0  *†H†÷ ‚0‚ ‚½¢OZÓ›šž$H\½]^á˜0ç¡Z!>¤síA3f¯‹\ndñ”ÐVÏÊÀÁ÷… Ù¯u&;ã´½†ÒH[úsF$ ¶R—ržz¬´ç¾ "Àäzhaõé]îüE®}žéÇ"A .Qøÿ¦™xP[ä`=ß«ñ@4{<NJð¡ÇpJ-”oç7¨<)Ls ØáxÇù€ÿY-‡µWFá ctr–BПœWT—UÊa_ŒÕÔNyx ÁžS©ÒÚT[Dgî¥M F›üѤ+Ø&~S]j›ãS°~Â%Ñ÷Ên·h5OR¿u—üå¬ö!ö”m £‚0‚0Us9¡5“D(2¦ _«ê”Zf"\0U#0€þ;LÐÔˆòódR¾ŠéyKÍ–0Uÿ0ÿ0Uÿ0U%0++0 `†H†øB0FU ?0=0;`8010/+#http://repository.fake-eid.smals.be07U00.0, * (†&http://crl.fake-eid.smals.be/smals.crl0  *†H†÷ ‚M‡(©žÅOPrû"·ŒºòpÓä?]T“Ä>W‘Öv^¢Ô¸o†À$bh@OÃ0  *†H†÷ 0*1 0 UBE10UFake Smals Root CA0 090330123606Z 100330123606Z0*1 0 UBE10UFake Smals Root CA0‚"0  *†H†÷ ‚0‚ ‚Ëå!³¨Žzç4Sí$¾›úÛ·DÆ£œëç•Aiò™Þ»ð¢üγ”ל/ ÎdT Az”› nßëÇ'øB1ùÎ@áÃU¡°´à G£ÍÁ1¿’*Q©d^Æ.EV#‰‰òïßnï ¿«¶À›!ôד_©îÔx󳨣pxЯgq›§¶}rK«îmŽ8ñêÈ-{r¸ÓGZ¶Ô^jD:íæä-('—[HBs‚düîw’6ßÝóÂm šš²¿@”úSðÖÀ³f^¢Ž`UfyıâMkšC¿AÔð_l÷€ãü÷õ)Ñ’«`ø¢«”Rÿ룼0¹0Uþ;LÐÔˆòódR¾ŠéyKÍ–0Uÿ0ÿ0Uÿ0U%0++0 `†H†øB0EU >0<0:`8010/+#http://repository.fake-eid.smals.be0  *†H†÷ ‚‚"ñt›K^âŠÁ«éEð»LN‘ôù—=^@¸Wͺ“ç"£"O C®e±xþ0ÉÌúò€èÓ—­Nè›Ú¨u‡°c}#Õÿ‘¤LR U¾<«m·—ðð>!!ÂýÓe$ ͇‡zD„b.x4æê…·=€îfÀåбÇډϠ¸K’ªƒ³pNÏûˆl¯±Ëò–þ·Ó±<š´L'ño2½Ý6ÕÊB<ý!Æ€TTúàóo&Á7°kà…¼BJ+d}½Ñö*'NV×jKŠo1\ÊŸ{X]›X$q@ ý+WàxDÆ"×S"Ø„4[&1‚Ø0‚Ô0R0>1 0 UBE10UFake Smals Citizen CA10 U200902°-0 + ]0 *†H†÷  1  *†H†÷ 0 *†H†÷  1 090909145658Z0# *†H†÷  1{œy¥lÞ îÅ‘ÚNY¦³0  *†H†÷  0‚˜¯¶:«p"+Åu°þ-LÙ_³Nä‚slËÑj øÂ_˜:†c7ÄôM ͺàÚæ=±1îT”œa=*ÿ™>l0%ö㽕S0\ô‚CF…L&vÏ)Fó, ñõža¥Þ ãlîD>ÃeÇ ðR->jNTºj˦Ý"âlUÛ‰¡yNDâþ–5’x$‡hˆÊ,™ÍOßÛJI5v]~ÏæxM‹…¥±³•cô›’Qn‹± ü8ÐA¤‰Dqûbküø.ùÞïh |]zà˜dñõ‰(ê7ØZ•,(ïŸóo•*Üß΃ÎÙçáu66[æâùåì5bouncycastle-1.49.orig/test/data/org/bouncycastle/cms/test/PSSSignDataSHA1.sig0000644000175000017500000000642111252340215026543 0ustar ebourgebourg0‚  *†H†÷  ‚ þ0‚ ú1 0 +0  *†H†÷  ‚ ý0‚X0‚@ °-0  *†H†÷ 0>1 0 UBE10UFake Smals Citizen CA10 U2009020 090810090503Z 100810090503Z0+1 0 UBE1 0 U00710 Uuser10‚"0  *†H†÷ ‚0‚ ‚¾§CM[hÁ¡d3DM®‰iq@ÕÖ!¤ŠÃçMCp—¤Y0óúöµbp´ Š0Ù i£•Sƒ0“â/ùí³Ÿ†•ám69nt Ï$W51!|D D˧hµÕJl-a^†±b¢F@ à%X-„Œ9É2¸šûUQ<€Ó¾k)‡%<üÃbø%ÛDÂñ¦]û|>3–(ƒ¿û:buþ$Îõ“·–[e $û¹ùí 3KäUà´E?žfâ’L%xPE;Ħ)»j[ûv­ÍB<3qœÂ]µQaú¬íã}UäϽÜKëà >®5Œ@í Ì]TÐZ?mNŒgòÅŸX³£e0c0 U00 U°0Uæ£}2*ˆfONÜ$áðQŠƒhf“0U#0€s9¡5“D(2¦ _«ê”Zf"\0 U00  *†H†÷ ‚¤zÜý Ùˆ¿±Š·hð`²9ó>Wlžãé‰÷p0ÁÊzTÔ.Ÿ&*zˆ@éýöí½ÍËûK¤@dIw`\3µTŸØMrä0¾ ¦ ù. Þë/š·Ob/x–/=¤Â&z4ÿˆ¦v•ªcë" ûs¦ch_óñ1ûGÇLx·-íbé¶ÃUŒ'‡¼}ÃJÂýdO¹]‰ L¹)œùG #Uš[4Ýæ˜+Ž""qOk›­x_»“ú)Óê 3+Ñçn¼À=ÚÑgXºÄ×îã£òÛÌÐ7 ÿÚÖ¼$üèÕhÊç~1÷1Ý-™B Jµ÷ã—*~ j¾0‚0‚í  ×Ö5ào>Å0  *†H†÷ 0*1 0 UBE10UFake Smals Root CA0 090330125856Z 100330125856Z0>1 0 UBE10UFake Smals Citizen CA10 U2009020‚"0  *†H†÷ ‚0‚ ‚½¢OZÓ›šž$H\½]^á˜0ç¡Z!>¤síA3f¯‹\ndñ”ÐVÏÊÀÁ÷… Ù¯u&;ã´½†ÒH[úsF$ ¶R—ržz¬´ç¾ "Àäzhaõé]îüE®}žéÇ"A .Qøÿ¦™xP[ä`=ß«ñ@4{<NJð¡ÇpJ-”oç7¨<)Ls ØáxÇù€ÿY-‡µWFá ctr–BПœWT—UÊa_ŒÕÔNyx ÁžS©ÒÚT[Dgî¥M F›üѤ+Ø&~S]j›ãS°~Â%Ñ÷Ên·h5OR¿u—üå¬ö!ö”m £‚0‚0Us9¡5“D(2¦ _«ê”Zf"\0U#0€þ;LÐÔˆòódR¾ŠéyKÍ–0Uÿ0ÿ0Uÿ0U%0++0 `†H†øB0FU ?0=0;`8010/+#http://repository.fake-eid.smals.be07U00.0, * (†&http://crl.fake-eid.smals.be/smals.crl0  *†H†÷ ‚M‡(©žÅOPrû"·ŒºòpÓä?]T“Ä>W‘Öv^¢Ô¸o†À$bh@OÃ0  *†H†÷ 0*1 0 UBE10UFake Smals Root CA0 090330123606Z 100330123606Z0*1 0 UBE10UFake Smals Root CA0‚"0  *†H†÷ ‚0‚ ‚Ëå!³¨Žzç4Sí$¾›úÛ·DÆ£œëç•Aiò™Þ»ð¢üγ”ל/ ÎdT Az”› nßëÇ'øB1ùÎ@áÃU¡°´à G£ÍÁ1¿’*Q©d^Æ.EV#‰‰òïßnï ¿«¶À›!ôד_©îÔx󳨣pxЯgq›§¶}rK«îmŽ8ñêÈ-{r¸ÓGZ¶Ô^jD:íæä-('—[HBs‚düîw’6ßÝóÂm šš²¿@”úSðÖÀ³f^¢Ž`UfyıâMkšC¿AÔð_l÷€ãü÷õ)Ñ’«`ø¢«”Rÿ룼0¹0Uþ;LÐÔˆòódR¾ŠéyKÍ–0Uÿ0ÿ0Uÿ0U%0++0 `†H†øB0EU >0<0:`8010/+#http://repository.fake-eid.smals.be0  *†H†÷ ‚‚"ñt›K^âŠÁ«éEð»LN‘ôù—=^@¸Wͺ“ç"£"O C®e±xþ0ÉÌúò€èÓ—­Nè›Ú¨u‡°c}#Õÿ‘¤LR U¾<«m·—ðð>!!ÂýÓe$ ͇‡zD„b.x4æê…·=€îfÀåбÇډϠ¸K’ªƒ³pNÏûˆl¯±Ëò–þ·Ó±<š´L'ño2½Ý6ÕÊB<ý!Æ€TTúàóo&Á7°kà…¼BJ+d}½Ñö*'NV×jKŠo1\ÊŸ{X]›X$q@ ý+WàxDÆ"×S"Ø„4[&1‚Ø0‚Ô0R0>1 0 UBE10UFake Smals Citizen CA10 U200902°-0 + ]0 *†H†÷  1  *†H†÷ 0 *†H†÷  1 090909145657Z0# *†H†÷  1{œy¥lÞ îÅ‘ÚNY¦³0  *†H†÷  0‚n¥¥þÕsÅ'O²_*”ª…*ºkðç]¶ñâÑ[Í×Ì>Q}Ôþv•S`$߆R€@Èÿ!ÑAQåÓŠL{´"y[u°¡~²äÏ2`çi–ÇnYÃÐXðÓ[f³%¨’\ÿÎ4EOwp…ÿåÿ[“1¥zÓ"‡PW¬z"¥ ˆ4ñŽ×߈Øí¸FzØqì¼JãDk4)"0a·SõdIŠ ¹cv¾ÚîqøX)‡»r2 +ØŽifçÞýŒÆøñôb­ðYæúί”©ÈéÞʼnØ2txÇóSbŽ0þëGáŒÅ"Pgüq8\ê4æ‡obouncycastle-1.49.orig/test/data/org/bouncycastle/cms/test/PSSSignData.data0000644000175000017500000000002611252340215026250 0ustar ebourgebourgThis is a test messagebouncycastle-1.49.orig/test/data/org/bouncycastle/cms/test/PSSSignDataSHA256Enc.sig0000644000175000017500000000656311252340215027354 0ustar ebourgebourg0‚ o *†H†÷  ‚ `0‚ \10  `†He0% *†H†÷  This is a test message ‚ ý0‚X0‚@ °-0  *†H†÷ 0>1 0 UBE10UFake Smals Citizen CA10 U2009020 090810090503Z 100810090503Z0+1 0 UBE1 0 U00710 Uuser10‚"0  *†H†÷ ‚0‚ ‚¾§CM[hÁ¡d3DM®‰iq@ÕÖ!¤ŠÃçMCp—¤Y0óúöµbp´ Š0Ù i£•Sƒ0“â/ùí³Ÿ†•ám69nt Ï$W51!|D D˧hµÕJl-a^†±b¢F@ à%X-„Œ9É2¸šûUQ<€Ó¾k)‡%<üÃbø%ÛDÂñ¦]û|>3–(ƒ¿û:buþ$Îõ“·–[e $û¹ùí 3KäUà´E?žfâ’L%xPE;Ħ)»j[ûv­ÍB<3qœÂ]µQaú¬íã}UäϽÜKëà >®5Œ@í Ì]TÐZ?mNŒgòÅŸX³£e0c0 U00 U°0Uæ£}2*ˆfONÜ$áðQŠƒhf“0U#0€s9¡5“D(2¦ _«ê”Zf"\0 U00  *†H†÷ ‚¤zÜý Ùˆ¿±Š·hð`²9ó>Wlžãé‰÷p0ÁÊzTÔ.Ÿ&*zˆ@éýöí½ÍËûK¤@dIw`\3µTŸØMrä0¾ ¦ ù. Þë/š·Ob/x–/=¤Â&z4ÿˆ¦v•ªcë" ûs¦ch_óñ1ûGÇLx·-íbé¶ÃUŒ'‡¼}ÃJÂýdO¹]‰ L¹)œùG #Uš[4Ýæ˜+Ž""qOk›­x_»“ú)Óê 3+Ñçn¼À=ÚÑgXºÄ×îã£òÛÌÐ7 ÿÚÖ¼$üèÕhÊç~1÷1Ý-™B Jµ÷ã—*~ j¾0‚0‚í  ×Ö5ào>Å0  *†H†÷ 0*1 0 UBE10UFake Smals Root CA0 090330125856Z 100330125856Z0>1 0 UBE10UFake Smals Citizen CA10 U2009020‚"0  *†H†÷ ‚0‚ ‚½¢OZÓ›šž$H\½]^á˜0ç¡Z!>¤síA3f¯‹\ndñ”ÐVÏÊÀÁ÷… Ù¯u&;ã´½†ÒH[úsF$ ¶R—ržz¬´ç¾ "Àäzhaõé]îüE®}žéÇ"A .Qøÿ¦™xP[ä`=ß«ñ@4{<NJð¡ÇpJ-”oç7¨<)Ls ØáxÇù€ÿY-‡µWFá ctr–BПœWT—UÊa_ŒÕÔNyx ÁžS©ÒÚT[Dgî¥M F›üѤ+Ø&~S]j›ãS°~Â%Ñ÷Ên·h5OR¿u—üå¬ö!ö”m £‚0‚0Us9¡5“D(2¦ _«ê”Zf"\0U#0€þ;LÐÔˆòódR¾ŠéyKÍ–0Uÿ0ÿ0Uÿ0U%0++0 `†H†øB0FU ?0=0;`8010/+#http://repository.fake-eid.smals.be07U00.0, * (†&http://crl.fake-eid.smals.be/smals.crl0  *†H†÷ ‚M‡(©žÅOPrû"·ŒºòpÓä?]T“Ä>W‘Öv^¢Ô¸o†À$bh@OÃ0  *†H†÷ 0*1 0 UBE10UFake Smals Root CA0 090330123606Z 100330123606Z0*1 0 UBE10UFake Smals Root CA0‚"0  *†H†÷ ‚0‚ ‚Ëå!³¨Žzç4Sí$¾›úÛ·DÆ£œëç•Aiò™Þ»ð¢üγ”ל/ ÎdT Az”› nßëÇ'øB1ùÎ@áÃU¡°´à G£ÍÁ1¿’*Q©d^Æ.EV#‰‰òïßnï ¿«¶À›!ôד_©îÔx󳨣pxЯgq›§¶}rK«îmŽ8ñêÈ-{r¸ÓGZ¶Ô^jD:íæä-('—[HBs‚düîw’6ßÝóÂm šš²¿@”úSðÖÀ³f^¢Ž`UfyıâMkšC¿AÔð_l÷€ãü÷õ)Ñ’«`ø¢«”Rÿ룼0¹0Uþ;LÐÔˆòódR¾ŠéyKÍ–0Uÿ0ÿ0Uÿ0U%0++0 `†H†øB0EU >0<0:`8010/+#http://repository.fake-eid.smals.be0  *†H†÷ ‚‚"ñt›K^âŠÁ«éEð»LN‘ôù—=^@¸Wͺ“ç"£"O C®e±xþ0ÉÌúò€èÓ—­Nè›Ú¨u‡°c}#Õÿ‘¤LR U¾<«m·—ðð>!!ÂýÓe$ ͇‡zD„b.x4æê…·=€îfÀåбÇډϠ¸K’ªƒ³pNÏûˆl¯±Ëò–þ·Ó±<š´L'ño2½Ý6ÕÊB<ý!Æ€TTúàóo&Á7°kà…¼BJ+d}½Ñö*'NV×jKŠo1\ÊŸ{X]›X$q@ ý+WàxDÆ"×S"Ø„4[&1‚0‚0R0>1 0 UBE10UFake Smals Citizen CA10 U200902°-0  `†He i0 *†H†÷  1  *†H†÷ 0 *†H†÷  1 090909145658Z0/ *†H†÷  1" o48)© [7’‹ó‹òn9å|n•V‚‹í¾ù0A *†H†÷  04 0  `†He¡0 *†H†÷ 0  `†He¢ ‚”O¹L[²ë‰õ·ÏãÌäšEC.ø¸[Ç}n>têFRryh9G;FâYÏ 0Cû +õï©c‡Žn¬Á“sޝø*Ãg6hÃAv:úQ]Îqwb{Ú “4O©Û¶‚óGU+UËê¬uѱ?a5ÅCq\`Mÿ°`Ú™áÓ¶o†a§qΪQW Ì Pôà Œõ½ñ}Öñ@\½ó ÖXªâè1Üz„= Ioå`÷„†Rmo‘ùŠ×8Gµ{ ä³Ã÷òîçÅØØ4½ÂìuçÓex´‡‚C{ê¡-/“¥%'³<¦,~Þ a€ê`ÁâmCÑ1AGbouncycastle-1.49.orig/test/data/org/bouncycastle/cms/test/PSSSignDataSHA256.sig0000644000175000017500000000653111252340215026721 0ustar ebourgebourg0‚ U *†H†÷  ‚ F0‚ B10  `†He0  *†H†÷  ‚ ý0‚X0‚@ °-0  *†H†÷ 0>1 0 UBE10UFake Smals Citizen CA10 U2009020 090810090503Z 100810090503Z0+1 0 UBE1 0 U00710 Uuser10‚"0  *†H†÷ ‚0‚ ‚¾§CM[hÁ¡d3DM®‰iq@ÕÖ!¤ŠÃçMCp—¤Y0óúöµbp´ Š0Ù i£•Sƒ0“â/ùí³Ÿ†•ám69nt Ï$W51!|D D˧hµÕJl-a^†±b¢F@ à%X-„Œ9É2¸šûUQ<€Ó¾k)‡%<üÃbø%ÛDÂñ¦]û|>3–(ƒ¿û:buþ$Îõ“·–[e $û¹ùí 3KäUà´E?žfâ’L%xPE;Ħ)»j[ûv­ÍB<3qœÂ]µQaú¬íã}UäϽÜKëà >®5Œ@í Ì]TÐZ?mNŒgòÅŸX³£e0c0 U00 U°0Uæ£}2*ˆfONÜ$áðQŠƒhf“0U#0€s9¡5“D(2¦ _«ê”Zf"\0 U00  *†H†÷ ‚¤zÜý Ùˆ¿±Š·hð`²9ó>Wlžãé‰÷p0ÁÊzTÔ.Ÿ&*zˆ@éýöí½ÍËûK¤@dIw`\3µTŸØMrä0¾ ¦ ù. Þë/š·Ob/x–/=¤Â&z4ÿˆ¦v•ªcë" ûs¦ch_óñ1ûGÇLx·-íbé¶ÃUŒ'‡¼}ÃJÂýdO¹]‰ L¹)œùG #Uš[4Ýæ˜+Ž""qOk›­x_»“ú)Óê 3+Ñçn¼À=ÚÑgXºÄ×îã£òÛÌÐ7 ÿÚÖ¼$üèÕhÊç~1÷1Ý-™B Jµ÷ã—*~ j¾0‚0‚í  ×Ö5ào>Å0  *†H†÷ 0*1 0 UBE10UFake Smals Root CA0 090330125856Z 100330125856Z0>1 0 UBE10UFake Smals Citizen CA10 U2009020‚"0  *†H†÷ ‚0‚ ‚½¢OZÓ›šž$H\½]^á˜0ç¡Z!>¤síA3f¯‹\ndñ”ÐVÏÊÀÁ÷… Ù¯u&;ã´½†ÒH[úsF$ ¶R—ržz¬´ç¾ "Àäzhaõé]îüE®}žéÇ"A .Qøÿ¦™xP[ä`=ß«ñ@4{<NJð¡ÇpJ-”oç7¨<)Ls ØáxÇù€ÿY-‡µWFá ctr–BПœWT—UÊa_ŒÕÔNyx ÁžS©ÒÚT[Dgî¥M F›üѤ+Ø&~S]j›ãS°~Â%Ñ÷Ên·h5OR¿u—üå¬ö!ö”m £‚0‚0Us9¡5“D(2¦ _«ê”Zf"\0U#0€þ;LÐÔˆòódR¾ŠéyKÍ–0Uÿ0ÿ0Uÿ0U%0++0 `†H†øB0FU ?0=0;`8010/+#http://repository.fake-eid.smals.be07U00.0, * (†&http://crl.fake-eid.smals.be/smals.crl0  *†H†÷ ‚M‡(©žÅOPrû"·ŒºòpÓä?]T“Ä>W‘Öv^¢Ô¸o†À$bh@OÃ0  *†H†÷ 0*1 0 UBE10UFake Smals Root CA0 090330123606Z 100330123606Z0*1 0 UBE10UFake Smals Root CA0‚"0  *†H†÷ ‚0‚ ‚Ëå!³¨Žzç4Sí$¾›úÛ·DÆ£œëç•Aiò™Þ»ð¢üγ”ל/ ÎdT Az”› nßëÇ'øB1ùÎ@áÃU¡°´à G£ÍÁ1¿’*Q©d^Æ.EV#‰‰òïßnï ¿«¶À›!ôד_©îÔx󳨣pxЯgq›§¶}rK«îmŽ8ñêÈ-{r¸ÓGZ¶Ô^jD:íæä-('—[HBs‚düîw’6ßÝóÂm šš²¿@”úSðÖÀ³f^¢Ž`UfyıâMkšC¿AÔð_l÷€ãü÷õ)Ñ’«`ø¢«”Rÿ룼0¹0Uþ;LÐÔˆòódR¾ŠéyKÍ–0Uÿ0ÿ0Uÿ0U%0++0 `†H†øB0EU >0<0:`8010/+#http://repository.fake-eid.smals.be0  *†H†÷ ‚‚"ñt›K^âŠÁ«éEð»LN‘ôù—=^@¸Wͺ“ç"£"O C®e±xþ0ÉÌúò€èÓ—­Nè›Ú¨u‡°c}#Õÿ‘¤LR U¾<«m·—ðð>!!ÂýÓe$ ͇‡zD„b.x4æê…·=€îfÀåбÇډϠ¸K’ªƒ³pNÏûˆl¯±Ëò–þ·Ó±<š´L'ño2½Ý6ÕÊB<ý!Æ€TTúàóo&Á7°kà…¼BJ+d}½Ñö*'NV×jKŠo1\ÊŸ{X]›X$q@ ý+WàxDÆ"×S"Ø„4[&1‚0‚0R0>1 0 UBE10UFake Smals Citizen CA10 U200902°-0  `†He i0 *†H†÷  1  *†H†÷ 0 *†H†÷  1 090909145658Z0/ *†H†÷  1" o48)© [7’‹ó‹òn9å|n•V‚‹í¾ù0A *†H†÷  04 0  `†He¡0 *†H†÷ 0  `†He¢ ‚‘ PÇÁ™PÕ†ë_ërjK‰9´þ u†¹fš¸ÒY³J¼!GôôXá:ÏÄ0vVl>oùë> ²`ëî‰ê±P7‡7`-d5d+ç „”¦¬8jÜšÇ+‰Ðª‰Á4æäŽ7{ãÉ®/ÍÆþÌÖ¥ÑtÔE6ŽÁŠ5½Þ~è”Ä£lqJSJb3^3ePb¦…Y£”kÖHÙ_ËÊ!–g÷*ÕN~îØ?zI9>ñiëáÐ jC$âòZ yEÕ)ãÉŽh`§¢§P²¯À gÆìçjhNB*šï%<LàÇ6_áÊSˆ °vz õöÄN6w–ƒ3Àœûk†bouncycastle-1.49.orig/test/data/org/bouncycastle/cms/test/counterSig.p7m0000644000175000017500000001301711331466466026127 0ustar ebourgebourg0€ *†H†÷  €0€1 0+0€ *†H†÷  €aaa ‚90‚0‚ "0  *†H†÷ 0\1 0 UJP1 0U 00-ECOM-TEST-ROOTCA-SIG1+0)U "EST-COUNTER-SIGNATURE1-OK-SIGSUBCA0 010101000000Z 351231235959Z0ƒ1 0 UJP1 0U 00-ECOM-TEST-ROOTCA-SIG1+0)U "EST-COUNTER-SIGNATURE1-OK-SIGSUBCA1%0#UEST-COUNTER-SIGNATURE1-OK-EE0Ÿ0  *†H†÷ 0‰Ö ¾¼DáL¹¯ŠPêÃ…Ê4Ãaès×peõާAêÎù¹DU÷;0P?e¹á\+ò| JkŒ ºC™Öù•Â%èE^zD…‡5‘-ý:Ë¢¥ÎHez .H}²ŒÌ#ê ‚`1jôáiWß[Ä‘'Ÿ0V[:£½0º0U#0€7*ÝzרLgè§½QÍ4‡0 U00]UV0T0R P N†Lhttp://ecom-es-test.ath.cx/repository/EST-COUNTER-SIGNATURE1-OK-SIGSUBCA.crl0UÿÀ0UªBjgF¦Í,;j.kVJ-k0  *†H†÷ £ n£ÒR*éA:„à6ê‹iÃ3é˜æõºQeÁ6aƒ:RíØô âðè f€x"†ÕÄ!ó °UŸS~D‚æM²g 2Pxz'}Hvˆù¢æl- =…—ˆ±){$xòV«ªËRªeÕº]YõůƒC¿é•<ˆÙÓC†3û0‚0‚‚ "0  *†H†÷ 0\1 0 UJP1 0U 00-ECOM-TEST-ROOTCA-SIG1+0)U "EST-COUNTER-SIGNATURE1-OK-SIGSUBCA0 010101000000Z 351231235959Z0„1 0 UJP1 0U 00-ECOM-TEST-ROOTCA-SIG1+0)U "EST-COUNTER-SIGNATURE1-OK-SIGSUBCA1&0$UEST-COUNTER-SIGNATURE1-OK-EE20Ÿ0  *†H†÷ 0‰§p5¨üÈl÷zc ®õ9‚΂+=ÂÛÓ’Û;§©®º§‚[zz â*™©J?PdM¥àWcܸÀïrK¿tô¬%n—šË÷œ—·gô[ŽÈ†Ë¢±6£j8ýë7À†‚©DìEA…P²\ƒ{Ôåoß² “PÙœøñ+£½0º0U#0€7*ÝzרLgè§½QÍ4‡0 U00]UV0T0R P N†Lhttp://ecom-es-test.ath.cx/repository/EST-COUNTER-SIGNATURE1-OK-SIGSUBCA.crl0UÿÀ0UN©V¢uãY(îµãˆ ÅsÉqõ0  *†H†÷ ˆThv´©ÛÙ…€#Qdg›I­Gâd2&y#Ì·ŠWZžò¦)%¥Å¦Uûň¼†?½‰!¯L¼ø›dºé( ´RÄP£Î•¤8ß^OŒ°?­—_Ðérº½q,©·‚J±ÛðzÔ° òØi‘„ûœF€­õ¶¦u–Ý·´ËÓòŽÌ1‚‘0‚€ªBjgF¦Í,;j.kVJ-k0+ Ü0 *†H†÷  1  *†H†÷ 0# *†H†÷  1~$ çO±íúÓ€cö¦©b¨0š *†H†÷   1Š0‡0„0¬T=fÁ:öËuúþ܈­30i0`¤^0\1 0 UJP1 0U 00-ECOM-TEST-ROOTCA-SIG1+0)U "EST-COUNTER-SIGNATURE1-OK-SIGSUBCA"0  *†H†÷ €–:û¦½ö%']èõ‚®ø³Û!ùœ“™†¼ñÚIhÉn-úp¼K‹Y1^r…CÚàoñ>†LÌ_ Ý3Éwwò|hHKãÕL¸iØ-Fïâ…m¥Æâ³%f}Vë¶› '.uJcBÑ¢…ôÝœ?q‹`Ûãð¥E±Ãçÿ5€ÖŽ¡‚ ö0‚- *†H†÷  1‚0‚ *†H†÷  ‚ 0‚10  `†He0‚ *†H†÷   ÷ô0ñ010  `†He `Uc᥵Ç'\MxרSxø ÚO'&Æ^Ÿïò(*©.p"20010101120000Z0€ôÿ4Vx ‰¤†0ƒ1 0 UJP1 0U 00-ECOM-TEST-ROOTCA-TSA1+0)U "EST-COUNTER-SIGNATURE1-OK-TSASUBCA1%0#UEST-COUNTER-SIGNATURE1-OK-EE ‚40‚00‚™ "0  *†H†÷ 0\1 0 UJP1 0U 00-ECOM-TEST-ROOTCA-TSA1+0)U "EST-COUNTER-SIGNATURE1-OK-TSASUBCA0 010101000000Z 351231235959Z0ƒ1 0 UJP1 0U 00-ECOM-TEST-ROOTCA-TSA1+0)U "EST-COUNTER-SIGNATURE1-OK-TSASUBCA1%0#UEST-COUNTER-SIGNATURE1-OK-EE0Ÿ0  *†H†÷ 0‰Ù·ìúʪ ‰C3pý•Ýöès Šbå¬R^;¹v ŠêL“@©SºÒ²z9YÖ° ª¿2‡}Á5ÒE3õ-¤øÔµ‡…å.ÍÝs»…½P¹^‡ñ"ÂBM%] ¯«ÄÈ@mªqéN¥Vcéó„uãÕ0Ò0U#0€Tè…£;ó S;ÖlM\—fUDßø`0 U00]UV0T0R P N†Lhttp://ecom-es-test.ath.cx/repository/EST-COUNTER-SIGNATURE1-OK-TSASUBCA.crl0U%ÿ 0 +0UÿÀ0U­븞¿æIߌЛiÉ/VGçL0  *†H†÷ Ç*˜ü* æ?My¯øý,‹MÉd$ŒN…®‰=Zµ@ýápÜxzVh]sh°¿}N„?(.4õ–W&,ÏœH@äéÝ%qiôFîÚÓ­‹N ÈWÒ™ÙÉiÄv[„"äâN{Úú†Ôí«ÿ—wgä¬\îÿÐÔ&#+ q $™E¤Õ1‚ª0‚¦0e0\1 0 UJP1 0U 00-ECOM-TEST-ROOTCA-TSA1+0)U "EST-COUNTER-SIGNATURE1-OK-TSASUBCA"0  `†He ˜0 *†H†÷  1  *†H†÷  0 *†H†÷  1 070308062840Z0+ *†H†÷   1000Ë/92;4°fw(èNfµüšã70/ *†H†÷  1" æ "üÏú ÂšÄqçÕ_BOv Ñ>!’¦b¬û‚o z0  *†H†÷ €'hÉtÍqX|z20† àgÙD´½øâ9™ÎgªŠG~çx¤À v8¾ &R”6~,8%Ÿ}äßm ÍävòÀÊàÉÐs9r­ÍÞ¨{qJLŽ{ã‚àP2ž£])AÂMó+êˆÇ›Ü.÷ ¾]’ÏÑ?­0‚Á *†H†÷  1‚²0‚®€N©V¢uãY(îµãˆ ÅsÉqõ0+ Â0# *†H†÷  1ÞÿY™8Gèñ‡XIÓ9 M0š *†H†÷   1Š0‡0„0hCEÑwÊ÷êáȇ‘ŠÿÉØð0i0`¤^0\1 0 UJP1 0U 00-ECOM-TEST-ROOTCA-SIG1+0)U "EST-COUNTER-SIGNATURE1-OK-SIGSUBCA"0  *†H†÷ €T#¬N};h',·+œT+Vá¿ÞuÐ:–¼—å{Ù3q·­ÊcšÔÅæâ°S5啾öTA®\´tˆwÝ,Õ_M]DÕ34vÜ'7tH÷Æëò®Ö´Ï• %j´t÷gïxd ÒŽR¡vÝYRK+YK–HŒÛ3½¡‚10‚- *†H†÷  1‚0‚ *†H†÷  ‚ 0‚10  `†He0‚ *†H†÷   ÷ô0ñ010  `†He ÃS„[áuµé|Dâ?½`Õ$!Š8@›·µ#~~c%"20010101130000Z0€ôÿ4Vx ‰¤†0ƒ1 0 UJP1 0U 00-ECOM-TEST-ROOTCA-TSA1+0)U "EST-COUNTER-SIGNATURE1-OK-TSASUBCA1%0#UEST-COUNTER-SIGNATURE1-OK-EE ‚40‚00‚™ "0  *†H†÷ 0\1 0 UJP1 0U 00-ECOM-TEST-ROOTCA-TSA1+0)U "EST-COUNTER-SIGNATURE1-OK-TSASUBCA0 010101000000Z 351231235959Z0ƒ1 0 UJP1 0U 00-ECOM-TEST-ROOTCA-TSA1+0)U "EST-COUNTER-SIGNATURE1-OK-TSASUBCA1%0#UEST-COUNTER-SIGNATURE1-OK-EE0Ÿ0  *†H†÷ 0‰Ù·ìúʪ ‰C3pý•Ýöès Šbå¬R^;¹v ŠêL“@©SºÒ²z9YÖ° ª¿2‡}Á5ÒE3õ-¤øÔµ‡…å.ÍÝs»…½P¹^‡ñ"ÂBM%] ¯«ÄÈ@mªqéN¥Vcéó„uãÕ0Ò0U#0€Tè…£;ó S;ÖlM\—fUDßø`0 U00]UV0T0R P N†Lhttp://ecom-es-test.ath.cx/repository/EST-COUNTER-SIGNATURE1-OK-TSASUBCA.crl0U%ÿ 0 +0UÿÀ0U­븞¿æIߌЛiÉ/VGçL0  *†H†÷ Ç*˜ü* æ?My¯øý,‹MÉd$ŒN…®‰=Zµ@ýápÜxzVh]sh°¿}N„?(.4õ–W&,ÏœH@äéÝ%qiôFîÚÓ­‹N ÈWÒ™ÙÉiÄv[„"äâN{Úú†Ôí«ÿ—wgä¬\îÿÐÔ&#+ q $™E¤Õ1‚ª0‚¦0e0\1 0 UJP1 0U 00-ECOM-TEST-ROOTCA-TSA1+0)U "EST-COUNTER-SIGNATURE1-OK-TSASUBCA"0  `†He ˜0 *†H†÷  1  *†H†÷  0 *†H†÷  1 070308062914Z0+ *†H†÷   1000Ë/92;4°fw(èNfµüšã70/ *†H†÷  1" È…C¿y!RùQ´Z‰!VeJÒÎU…s7‚ÄÀh ­0  *†H†÷ €¡iÍ^ ™)¢ ;[®÷_"»nŸðÕ¹Tú”·5$0ñ4^r*”OÕ•ƒ± ­‡â¶|v÷ÙÊÝ?sð¿Èƒ¹- wÀt ßóøl“j@çI"o¿*Ñ;ÃIÇ´'ï5’ôÇXÖ½DÖŸý^ÿ4»Æo!YR¥²D7ȸbouncycastle-1.49.orig/test/data/org/bouncycastle/tsp/0000755000175000017500000000000012152033550022405 5ustar ebourgebourgbouncycastle-1.49.orig/test/data/org/bouncycastle/tsp/test/0000755000175000017500000000000012152033550023364 5ustar ebourgebourgbouncycastle-1.49.orig/test/data/org/bouncycastle/tsp/test/FileDaFirmare.txt.tsd.der0000644000175000017500000001407711522717574030151 0ustar ebourgebourg0‚; *†H†÷   ‚*0‚&0"ÿ FileDaFirmare.txt text/plainåINIZIOINIZIOINIZIOINIZIOINIZIOINIZIOINIZIOINIZIOINIZIOINIZIOINIZIOINIZIOINI dati da firmaredati da firmaredati da firmaredati da firmaredati da firmare FINEFINEFINEFINEFINEFINEFINEFINEFINEFINEFINEFINEFINEFINEFINEFINEFINEFINEFIN ‚0‚­0‚© *†H†÷  ‚š0‚–10  `†He0É *†H†÷   ¹¶0³+L$010  `†He ÎŽÓìgçL¼ë»¿£8q?WæYÞˆatÄe¢27ÊT7a“·20110204164058Z0-ñŒBþ O¤M0K1 0 UIT10U InfoCert SpA1 0 U TSA10U ICEDTS01201101 ‚}0‚y0‚a ]¾0  *†H†÷  0s1 0 UIT10U INFOCERT SPA10U 079452110061 0 U TSA1)0'U InfoCert Time Stamping Authority0 110119143356Z 150119143356Z0K1 0 UIT10U InfoCert SpA1 0 U TSA10U ICEDTS012011010Ÿ0  *†H†÷ 0‰ûuU4„FÚH`Ò׫¯â¢Í†4"å0S¯½¸"¬Ù×=œy¿ËÉ«ÊÜ@ÞLÞªâx®iyA|nω›h= šîpýþ™v÷ÊŽ|²êN+LfãGzK?:²ä«Ë|@œXÃÒ( fƒÛôŸ™VÌálÀbÖÚ¸Ù£‚Á0‚½0ZU S0Q0O+L$0E0C+7http://www.firma.infocert.it/documentazione/manuali.php0Uÿ€0U%ÿ 0 +0%U0firma.digitale@infocert.it0U#0€¡çKì X•Rm$-o i0ÏUÇ0Ä06 4 2†0http://www.carm.infocert.it/InfoCert/TSS/CRL.crl0‰ † ƒ†€ldap://ldap.infocert.it/cn%3dInfoCert%20Time%20Stamping%20Authority,ou%3dTSA,o%3dINFOCERT%20SPA,c%3dIT?certificateRevocationList0Ulª0–í¤Ò¶Ã÷ÝeÓtô¨Ÿë0  *†H†÷  ‚xí#î.(Ò>.œ<¦Í=‰“ȪÛ÷9ês‚2)¼×¨ùï!z˜æhD"÷ÐJ²TÌ™¦æ’Xø00‡ô<Æ? ‹W·cÿ¡ï*«ò+n]CåMyê¸Píév ô Ö6A):õyÍv£ž@ÿ£¨¯­ )NL€uÐ|0ć(]edzuÖ6,~46^B&æ–œp„ ÚU9˹Ú¸…ÀÜ 9pâÿ6[>6bíP(.žuÞ‚pó  ~ VÈ/+¸:jFÙgzÂäóHØ~‡®gä¸Fä²)UuùYÈI¸•؉¸z°0ˆÄê8™dËL“È™pFß ª-÷Ÿn:1‚10‚-0y0s1 0 UIT10U INFOCERT SPA10U 079452110061 0 U TSA1)0'U InfoCert Time Stamping Authority]¾0  `†He ‚ 0 *†H†÷  1  *†H†÷  0/ *†H†÷  1" 3@ÏXÎ ò!¡ ö#©0¿ûJ‹ßŸ/©7ü;{!²0º *†H†÷  /1ª0§0¤0¡ q€x_è ï²×O¨œR äùÊ:ׯßâÇx¥¢ONò0}0w¤u0s1 0 UIT10U INFOCERT SPA10U 079452110061 0 U TSA1)0'U InfoCert Time Stamping Authority]¾0  *†H†÷ €œ”Õ!SX^},{kuL‰3+Až»BÆž~ìOŽa“º20110204164059Z0-ñŒJK O¤M0K1 0 UIT10U InfoCert SpA1 0 U TSA10U ICEDTS01201101 ‚}0‚y0‚a ]¾0  *†H†÷  0s1 0 UIT10U INFOCERT SPA10U 079452110061 0 U TSA1)0'U InfoCert Time Stamping Authority0 110119143356Z 150119143356Z0K1 0 UIT10U InfoCert SpA1 0 U TSA10U ICEDTS012011010Ÿ0  *†H†÷ 0‰ûuU4„FÚH`Ò׫¯â¢Í†4"å0S¯½¸"¬Ù×=œy¿ËÉ«ÊÜ@ÞLÞªâx®iyA|nω›h= šîpýþ™v÷ÊŽ|²êN+LfãGzK?:²ä«Ë|@œXÃÒ( fƒÛôŸ™VÌálÀbÖÚ¸Ù£‚Á0‚½0ZU S0Q0O+L$0E0C+7http://www.firma.infocert.it/documentazione/manuali.php0Uÿ€0U%ÿ 0 +0%U0firma.digitale@infocert.it0U#0€¡çKì X•Rm$-o i0ÏUÇ0Ä06 4 2†0http://www.carm.infocert.it/InfoCert/TSS/CRL.crl0‰ † ƒ†€ldap://ldap.infocert.it/cn%3dInfoCert%20Time%20Stamping%20Authority,ou%3dTSA,o%3dINFOCERT%20SPA,c%3dIT?certificateRevocationList0Ulª0–í¤Ò¶Ã÷ÝeÓtô¨Ÿë0  *†H†÷  ‚xí#î.(Ò>.œ<¦Í=‰“ȪÛ÷9ês‚2)¼×¨ùï!z˜æhD"÷ÐJ²TÌ™¦æ’Xø00‡ô<Æ? ‹W·cÿ¡ï*«ò+n]CåMyê¸Píév ô Ö6A):õyÍv£ž@ÿ£¨¯­ )NL€uÐ|0ć(]edzuÖ6,~46^B&æ–œp„ ÚU9˹Ú¸…ÀÜ 9pâÿ6[>6bíP(.žuÞ‚pó  ~ VÈ/+¸:jFÙgzÂäóHØ~‡®gä¸Fä²)UuùYÈI¸•؉¸z°0ˆÄê8™dËL“È™pFß ª-÷Ÿn:1‚10‚-0y0s1 0 UIT10U INFOCERT SPA10U 079452110061 0 U TSA1)0'U InfoCert Time Stamping Authority]¾0  `†He ‚ 0 *†H†÷  1  *†H†÷  0/ *†H†÷  1" ìos¿ePjœqÔ¶xè1+ Ôç‚\)“ u[ɪø 50º *†H†÷  /1ª0§0¤0¡ q€x_è ï²×O¨œR äùÊ:ׯßâÇx¥¢ONò0}0w¤u0s1 0 UIT10U INFOCERT SPA10U 079452110061 0 U TSA1)0'U InfoCert Time Stamping Authority]¾0  *†H†÷ €ùrÈÄœ³gÍ`l¼ƒ¶‡^ÞmNƒˆÞ\Ýí÷ò-¢o›vkÀÈ÷ÙMš$\L¡›C|ôOI2§f~ÉKÖn}|9\^ߢ:Þ÷ŸÒ[éîµñÌÃÆ0®õ×4½kéø€‹ê„@ÒQóë¾KH}ú"Tpç+ì®Æ´ëWÞ$C¼ß¸Ò0‚­0‚© *†H†÷  ‚š0‚–10  `†He0É *†H†÷   ¹¶0³+L$010  `†He Dº´Ô|ר>ô½£o±ÃYBYP²ýËw‘,Ÿ•°ˆîT˜Ø20110204164059Z0-ñŒL O¤M0K1 0 UIT10U InfoCert SpA1 0 U TSA10U ICEDTS02201101 ‚}0‚y0‚a ]À0  *†H†÷  0s1 0 UIT10U INFOCERT SPA10U 079452110061 0 U TSA1)0'U InfoCert Time Stamping Authority0 110119144209Z 150119144209Z0K1 0 UIT10U InfoCert SpA1 0 U TSA10U ICEDTS022011010Ÿ0  *†H†÷ 0‰Α<â·BE8º|«+,¼„æÀÓQ—Û‘ž0\ÃEæ*ÓМ&ß7SZ}"¨”@Ãa•êôÛƒë¥ä‘í ¬Ó¹³I@É¿¹—3öüh´:cíÉÎâ3Å!Çnã! ·ù"þÍ»<Ÿ.%í€ÎƒIñ…foqŽJ054`Áîsí£‚Á0‚½0ZU S0Q0O+L$0E0C+7http://www.firma.infocert.it/documentazione/manuali.php0Uÿ€0U%ÿ 0 +0%U0firma.digitale@infocert.it0U#0€¡çKì X•Rm$-o i0ÏUÇ0Ä06 4 2†0http://www.carm.infocert.it/InfoCert/TSS/CRL.crl0‰ † ƒ†€ldap://ldap.infocert.it/cn%3dInfoCert%20Time%20Stamping%20Authority,ou%3dTSA,o%3dINFOCERT%20SPA,c%3dIT?certificateRevocationList0Uµ‡T^ÿQ¯ÊvŒýr“­[g0  *†H†÷  ‚© 1J†¨Ä2h¬îæع°kmG ìéCn7ªÚ«Ó«>ÁéÆ+éCß®Cxç‹X ÀÔÃîTÿÝè" = ðŽ/ôäË ð#‘Eœ†4JÓÆá #/ïÃùSA:Uðk0á·Ž—˜˜`¼yû+YŒ›@:Ð2 z4µ¾Ð±õÊxFxôóÍz1µ Ô@¬Î5ç§EXç´Ç•ºJ8Ã\§ev+ßªŠ­ÜE ;*›‹ú™T5®Ÿ·a¤Î4ÚÅQ™¼>¾  îdê4…¾¼Yͪ\œ÷IØ=e2I;©ŠK¨ç«E)ÎTc©¼=ö¼< å ß×N’x(ìÆt× {bouncycastle-1.49.orig/test/data/org/bouncycastle/tsp/test/FileDaFirmare.data0000644000175000017500000000034511527072347026667 0ustar ebourgebourgINIZIOINIZIOINIZIOINIZIOINIZIOINIZIOINIZIOINIZIOINIZIOINIZIOINIZIOINIZIOINI dati da firmaredati da firmaredati da firmaredati da firmaredati da firmare FINEFINEFINEFINEFINEFINEFINEFINEFINEFINEFINEFINEFINEFINEFINEFINEFINEFINEFINbouncycastle-1.49.orig/test/data/org/bouncycastle/eac/0000755000175000017500000000000012152033550022327 5ustar ebourgebourgbouncycastle-1.49.orig/test/data/org/bouncycastle/eac/test/0000755000175000017500000000000012152033550023306 5ustar ebourgebourgbouncycastle-1.49.orig/test/data/org/bouncycastle/eac/test/REQ_18102010.csr0000644000175000017500000000053211642462503025431 0ustar ebourgebourg!‚UN‚_)Iÿ ×Á4ª&Cf†*0%uÑׇ°ŸW—Ú‰õ~ÈÀÿ‚h¥æ,©Îl)˜¦ÁS QN*ذ*YÊÒŸCƒ%€ö<ÏäA8‡±©#iã>!5ÒfÛ³r8l@ „9 )­,~\ô4#²¨}ÆŒžLãLnýîÀ}XªV÷rÀro$ƸžNͬ$5Kž™Ê£öÓvÍ…×Á4ª&Cf†*0%uÐû˜Ñ¼KmÞ¼£¥§“Ÿ†9À¦$·ºòÞ=^*Xž«q/žOeÞ ä.šAGòbßöÓ•|vsÁSvöH¯ðB"B… E.“%P-‡_ BETEST00001_78JЋ³~.À² Ârë-fwW¼cWÇ’3^[±Ä35¶â½ÔvûÎrÖ ŒìˆDJË†’Ž(Êbouncycastle-1.49.orig/test/data/org/bouncycastle/eac/test/dv_cer_BEDVBUZABE006_7816.cvcert0000644000175000017500000000034111642462503030371 0ustar ebourgebourg!ÝN–_)B BECVCA00001IO †A¨Šy¸õò5àH+_XÚoïiYM “¦v…µò'ƒPV†WVP6óv"L¾Xe".½ !ÊÍ9=º+Óõ•_ BEDVBUZABE006L S_%_$_7@ë»(ÌÉÊgê´Îxmr ­ÊØxNG‚}ê,**-­É]â>µÚyý±*åö2¥d²gJdœMºê"Xebouncycastle-1.49.orig/test/data/org/bouncycastle/eac/test/Belgique CVCA-02032010.7816.cvcert0000644000175000017500000000066111642462503030253 0ustar ebourgebourg!‚¬N‚d_)B BECVCA00001I‚  ÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿ‚ ÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿüƒ ZÆ5ت:“ç³ë½Uv˜†¼e°ÌS°ö;Î<>'Ò`K„AkÑòá,BGø¼æåc¤@òw}-ë3 ô¡9Eؘ–OãBâþ›ŽçëJ|ž+Î3Wk1^Î˶@h7¿Qõ… ÿÿÿÿÿÿÿÿÿÿÿÿ¼æú­§ž„ó¹ÊÂüc%Q†A-ãÁ"Ïbþ†¡#ð³b² “šøÛi‹4!GÁHœ=÷Ú$BR$Ú•±I]a­Zï>«ý-àr¤û¤ »Lܘ‡_ BECVCA00001L SÁ_%_$_7@‘úÄË%¾GM}ZíZ1kb¼Z·oÛP•›1WyãèÞÔ÷± ,¡œÛ«Îžù?·Ú)Å$L¢zÊd—çxý¬bouncycastle-1.49.orig/test/data/org/bouncycastle/eac/test/at_cert_19a.cvcert0000644000175000017500000000055311642462503026623 0ustar ebourgebourg!‚fNÞ_)B DETESTDVDE019I †3…´„èé”É?U­ô©É-£Àc¬}tN…ÓŽàp¿oø×«¢Þh‡$²}k®+ŠàtÀ›¸€ŒÈ06°i(˜q?oÃ!8FáK1T„P„ß¼· â½êŽëÖyjϤÅoWÎZnþ &nCÃ÷~ì`åÆð… ÄÓE_S(,Ÿ¼¨]ÉGÑ;î_ DETESTATDE019L S_% _$_7€4»Œ( zY<÷Çéóuÿÿ¿Ù,N?aˆ¤H$!^ïGÐ4(ÏÉ6¢`œt.ù,Yh¼æ[¤*íz­p·²£Ü,ì“ }yT¿¾!­Ò¬ªl4šl/¸e¹ð=ú¹˜qûÙÝ„Óí¢ˆ>½ ”@}¿ánZ¶Cî|/ÀÕ×{®6f¯bouncycastle-1.49.orig/test/data/org/bouncycastle/jce/0000755000175000017500000000000012152033550022340 5ustar ebourgebourgbouncycastle-1.49.orig/test/data/org/bouncycastle/jce/provider/0000755000175000017500000000000012152033550024172 5ustar ebourgebourgbouncycastle-1.49.orig/test/data/org/bouncycastle/jce/provider/test/0000755000175000017500000000000012152033550025151 5ustar ebourgebourgbouncycastle-1.49.orig/test/data/org/bouncycastle/jce/provider/test/rsa3/0000755000175000017500000000000012152033550026021 5ustar ebourgebourgbouncycastle-1.49.orig/test/data/org/bouncycastle/jce/provider/test/rsa3/self-testcase-B.pem0000644000175000017500000000613410503212005031441 0ustar ebourgebourg-----BEGIN CERTIFICATE----- MIIEHTCCAwWgAwIBAgIBADANBgkqhkiG9w0BAQQFADBsMQswCQYDVQQGEwJHQjES MBAGA1UECBMJQmVya3NoaXJlMRAwDgYDVQQHEwdOZXdidXJ5MRcwFQYDVQQKEw5N eSBDb21wYW55IEx0ZDEKMAgGA1UECxMBYTESMBAGA1UEAxMJbG9jYWxob3N0MB4X DTA2MDkxMzE4MjYzMloXDTA3MDkxMzE4MjYzMlowbDELMAkGA1UEBhMCR0IxEjAQ BgNVBAgTCUJlcmtzaGlyZTEQMA4GA1UEBxMHTmV3YnVyeTEXMBUGA1UEChMOTXkg Q29tcGFueSBMdGQxCjAIBgNVBAsTAWExEjAQBgNVBAMTCWxvY2FsaG9zdDCCASIw DQYJKoZIhvcNAQEBBQADggEPADCCAQoCggEBAKtexL4ZP1CWMsVedm+pD2xPG+md VbRqkVSDQYxrHUyRVKletjluY95908bsAlJR9oK/YehXe9W7r+LnotaR+yy1P45g hSWa6TNl1sz3NGIZwdU9WdqdNNs9YyDgzFezxzZffrh9xFTSF0CR66Tm1VasKa20 69RTx4fE5n4kZx+DKfBGCX3PBprvIANZp0nrfuhf21ij9lORI9OkITwqR72PrybB 9QDZB+7og1jGLAGbRBNR61mLVfKrg2yJVhpk1dHPsUzeVr3BB5XK8i7DvflWw5di PeyU4S7qm7WLZ9Wdg1XOchkQWmzqEUPG71dGzG6joPhdp56LFg2Yg58myRcCAwEA AaOByTCBxjAdBgNVHQ4EFgQUPd6mAcGQZ8iNGajt0kffN4AeDZswgZYGA1UdIwSB jjCBi4AUPd6mAcGQZ8iNGajt0kffN4AeDZuhcKRuMGwxCzAJBgNVBAYTAkdCMRIw EAYDVQQIEwlCZXJrc2hpcmUxEDAOBgNVBAcTB05ld2J1cnkxFzAVBgNVBAoTDk15 IENvbXBhbnkgTHRkMQowCAYDVQQLEwFhMRIwEAYDVQQDEwlsb2NhbGhvc3SCAQAw DAYDVR0TBAUwAwEB/zANBgkqhkiG9w0BAQQFAAOCAQEAIYpxwPMRRjPuRBsWKhB0 ACZHEaO6RtSwu28sHO2TF1o0kHONAnqR37OhMuPR70qBynd5dVDkjpxXUfxhLDPh jdaxXuj2vMrbAvDJFsIsKDatlc632IsicSR4DVEnpJmUtLBQFC2VylHMxkGoo5eJ dsf5ZY/QqUXf+VReLWfyQXEaSGe8nI7fP61xqTsgzcN4ziqkKSKGvsEtPU/oo23Y xZDJpRMPdzu7TqkP3PnzRFy6HUamM2Xpyl2qeYELtGu7nuoSaF/1AX21bPtU9N9N +wbxlGuq7NVIKdlIaoQ3FfgCVZGrVwjr7uxow7Gob+pWJJKjOS+IlSRL0MqH1t/U yQ== -----END CERTIFICATE----- -----BEGIN RSA PRIVATE KEY----- MIIEogIBAAKCAQEAq17Evhk/UJYyxV52b6kPbE8b6Z1VtGqRVINBjGsdTJFUqV62 OW5j3n3TxuwCUlH2gr9h6Fd71buv4uei1pH7LLU/jmCFJZrpM2XWzPc0YhnB1T1Z 2p002z1jIODMV7PHNl9+uH3EVNIXQJHrpObVVqwprbTr1FPHh8TmfiRnH4Mp8EYJ fc8Gmu8gA1mnSet+6F/bWKP2U5Ej06QhPCpHvY+vJsH1ANkH7uiDWMYsAZtEE1Hr WYtV8quDbIlWGmTV0c+xTN5WvcEHlcryLsO9+VbDl2I97JThLuqbtYtn1Z2DVc5y GRBabOoRQ8bvV0bMbqOg+F2nnosWDZiDnybJFwIDAQABAoIBAGA8GNn0DaUwo5RI htQPqVSWXENlklJ9od1G1FGJeWudFWEDietYfYbdPEcyE9+snXUxCkdSkX0mKBCR KdW7JsUlh2pp83t5scmmP+jcTbNlaX9ZM5Nbwun3YCp/cuExWQbEu8HZBp7nWB1v lFgHNPi2N7WPqvuSjLNGtHVT9gEwWGUl1zfbuZp8pNT4r1l7nwj+S9pGF3v5RXDt qZWSbfPF3ESPkMOpXxGk5uDLx3aoeHBQALVjeNdVlkyxjrG75Pv7ZnrmXjXzcuVv aVACiCPWxzaRFR9cRCx/Z34KrJorLglrfIPIrRMKJY33QO2gpYYEpFkLsLth/Ip4 NMSJ3KkCgYEA36skUOFK0iQcdEaUXR2zcvQd3P3ctxe0JqD7dHFWnY2ndA5+VvAP vUjemZgw+tNt1qjLCAwxMi4cEOEICG6zSlMBRcVbqkKPS3gd3fGvD/lfQZ02EePz 6KYVC7xz1WXIcId/HvkBNmbPEyOLqi9fIJQoYrM3LnB3AFIUqQ4K3UMCgYEAxCRT Z6yLGFb6Evkvvc6usqDhpAjWaaTSxlsSf9IGsKXW90OronB1IiTaWgJze1PrwWy4 z4YOSI8oEEpF7LdwI9hztg9wFGht8lahGkfHtgR7V/QzyLMYfcU/57STI9vvsw2S FNqIdeP1Bd/CE8iI6o6HOAadsWlTBBUBUtnZnZ0CgYA/ecthpL5eKt9kZE9gqbgu rHb5K5aC45g9yjvyjOO+7N+UATT7qT9eQZrizh1AYdZvMBIGo6cmjY1rgOGNuxTo x+u5iEv+YstV6K3ZOeiryOKutVYN97pV0SRx4zagXjVnMhzyhkpAzSaBUPom/zCp B0L618+WP1aWYbT5UUHmDwKBgA3Ju+86yuBgJN42lCuUnuVBt/rvABuXEZYOCuPf YMcEMXNaV3No0mMfEhZnu7R8tsL3IJq+Ar0JCzjx765vSrvKWIAA39EfcjMp8dNG HnzmHcGWEhnWtS8KMa7ZG8rWiCgfGRjML/GRn8TU8PCxFSbf9BN1K5qwG7zauSgY 1lplAoGAfl1Qw77H27TYGMVBgco/2g05MaKb8TZ4PKn1znlPnNcqFEBi779W0/dD Zgb1mjnRQkw68Jj5XA2zv/06yjvTS+nHVEDCdgIrZI2p1IrI3F4tihSoWgYtoe+8 5OVDiHQ73d6lxVLqIRoRic8ZtWR02PbrK5SmoPsFdeTcmtzqo6c= -----END RSA PRIVATE KEY----- bouncycastle-1.49.orig/test/data/org/bouncycastle/jce/provider/test/rsa3/self-testcase-E.p120000644000175000017500000000526610503212005031272 0ustar ebourgebourg0‚ ²0‚ x *†H†÷  ‚ i‚ e0‚ a0‚ï *†H†÷  ‚à0‚Ü0‚Õ *†H†÷ 0 *†H†÷  0¥Ø¿‘(vu€‚¨míÒþ…½Yº;¥qf@ÒÖ uzdrwuh:/ I}¬ÕWlÕ¹ñupHÛ£$W¹;po#Xª«ÁÂ-mîc¢Eº`s¯> YqòX8عA[³-þz† 0]–dç^½›ÞK}Ùëusα=J‹æKÙèv6•=nk”_ôtíÂVÁE5€‘PèêÜõñ˜‡HyM€UöýŤß&l§sa›ÞÈ«Æ^åŠ0åÈÚ©‡ô†ÂÅÐ×S¤{öcŠÛ.ÈÞÀñ…@ø¯öÖú³× º3yÓ»ÈuY’ ³I&3Dq!úGOB@gWñ¥Q™WKv †M½¡â&Ô dÙÅx«ô\î3Í5r;YÔÛYGLNH³f:Ø«v|‡íJW^sØô¼À9Cg«­þâ]Ì’Ga¸^Wö¯x”ŠþôP ÕL$2¯ú·lÍ~o’v¶+%'÷@“Qä:dñx†HÚëõ[a8¡Ãuw5Y4Þ uˆ6ÍíVÀBïªlÆç½LŽ†Ù¸9DšaŽï!»lÝh"Ô£§\ÈÑ”66“ƒ¬@ŒÈúÒlºœbã¼JÌEtšWV0Lmóu¹ôÁ+ÂÒcÓt&4ˆT•Eätõ[Q¾&zSzî§8Ûp£–-i@íŸ6–¢z»YËü­Ý~aÛcÕÆYf_¬k©Ge@1ŠÃÔˆù\{`)£k“»Haq¶(n®×k¶³XÐ Ðm’`5³ú+k÷J¨%ì„r[ªÏÈ=o˜;7x8Y¼xºÁÁŠ×ˆ ð-‹7Ÿ½2诫`ÂÅü_t¦ùÌÀ•ìåw~´,_8Ñ´«Ò]©.ÂЬ¥îg#ˆÊ¼àì K\RV›c½û覾´PMJÔkø•‹Å«væ!è‘ÿct(uL³N02œ›±¢|a~æ‡r„lÀ{BØÅ[d³OÛˆ ~ÿeùZŠçXKÄÍûM)ÌÍm@²úbðé²Ýû: ç¦]¦Bææ7Žw‰}ßî°ë™R™¥‚ǨøÕ?o†Q•8ôÞzà`!T0JÀ8øþøe;=Z Fà561rÿê6z ÚÓDãÝö&*ÌebœìÊe›EäùZwÚÑ9ElEÍmÔËÓ~ìnÖþà¥Íéì…4+ªLŒîöRï_À¡ù©[êç±[Mh8T%ŠX‡V*°²òØN# ].õZ`|׸w Ô¹±y-ֆ𥗕ػ^òcï{éRŽ!CX8„š¦h1¸c}aS˜æé¿º`LŽC÷×ý—Â2æ)Ê#ÚVø î?E‹W9ÝP¿”$DMvØ)Œ’ÚÜ•/ðûcïÚz³°¡pÝÜ`ŠË:F˜Mǘ_%<ÖŽœ áÛ´+›}ø¢uÜJR°W‚}@ذ"˜Æ1å…|`¬aÜÎBÜ›v›±8¨X^Ô³ï)g¾è˜×mXèÍïÍzûsÂS,&9†ûóa{`tjª™f•†}'$Ž^)8e{´„ŽÅoN`õqµó«tŒÞ—¨¶f0‚j *†H†÷  ‚[‚W0‚S0‚O *†H†÷   ‚î0‚ê0 *†H†÷  0`Ï"f@èn‚È{gX?<Ê}-—òØÝNEv`/5DLïf|›¨¼ CN"fRÂY#s@W3ÔÖŽju›,$v˜›~Çéñ#‹(ÕzÓ‰K;°R'*OG}õ3W,žÃ$Ç΋í†$AúÚ¾Kª¼Ûû)üèzšÖ¦$óŒ|Œ÷.¤M+Ëxð^Úäá(½=Mݽûj|B‰‘çÈheí[Šå[¦æó-ªfY]c† ·Z-óó€Z“´s‘å&;M¾= ðIÞ$luP¦_!B}ÇáÑêW-šÝš`pºÄZÉD ¶í³Ñxãöé™o%pŒ¹¥û-/s¤3‚yª<ÔæúÐî~²êUYkt¨e‡!´íN¥L+îï‚ FŸ#Ãç•íQ7ƒéù…'”‰ØÉ«ÀLµ1~ŸñÇ+ù üŸ+¬õ.œ,¥Q= {¸ÄÛô¤äò6ä·˜R˜û¿éüÛæÙí€× áF/¼ÕîOúF t-zèÕ¯FS¦ì–.9`ÍÝXœ‚¥2ãûýØ=˽é/²yú7Eø©§Ì–ÀA·5‹“ÑEÎóÙsC¸ŸÐ¤†£ =›2Ƀ–’UÑeßö¡¤vä»hóD¥š%-U§-ýA„xòœ3D%MW™ñ;F»…ÂÄ«ME¨ê\{k&¼W;fåÁ„^rÛúažàkàÄb†SëðíP-JM¿¾9ÖSÙ½£M£5™ B,•„¼ä±Î„¥‰Åv·— K°[=mÐBózËEy¦ùŸRn\Û9B—’ß1&às¨9WúzlDºvµ4ÇR Fù•†›jHpQå“¶-¬a”¦’+B•±’áÓ¯ñÓë„QP¤ÝZûÇä˜f°­åå¹BI¥¿¾|oÃ'úÀæ9:ê"ª¿–¿Ç"pYG¬DYê.´Ôø*¡°Ò›³î”–² "v/l;þL”z|çšÄÌßuU‘ÈbPâE.7½3NpªÕǸ)åmÀÙGÇ3>Y{6  íëB³>©Íüã)¸¼åuÓÓâ¹{8mp½Õþ1c‰¿Á˦u@¨\hÆòPvâÁ[²âÝÉâ!ݾJ®7«ú P ÅÈN’ê€Ï»ûk‡Ñã$×+½ oË}Glg–c}¥™yŸðß“É*·«ŸßÔO„{–,aÝãü·^r0Àw»(ÉÏÑçmÚw>Ý‘@øøàyïwé˜O¿{ÓP,份°›„CÃg+vÌnzǾ•SZ"ù*YW’×–'ΙرõÅpbk.[‚®? 6{ègh‚jgVÄõÍ š-ìÒSiQÅ{UU#·¿‘Ô,xت(x©Bý}uM e1Ý[+§9II¹Ùd›I÷âO&9ÒÃv÷‚ôFæ CŒM¨'Õ5Ô¼€¾ØEv:uß(bvt14ì~@ÇM¨S+uq1•ÔVÃÂ5:<ÊØ£±?äŸK1ê½l‚£7}`S7@­¿ÌRÃV›—†´·¬ v•Ž~:on<—M s?Ðû"©ûÇtmUA‡ÚÉló±´’ àƒ7¤¥"q×/2èÃË8÷k·ÐqèV<”]57¡BÃÒkéƒPdàeOô(#ÿÅê,ÏUm1N0# *†H†÷  1U9HZˆ,ÅðUê½¢“9`×H0' *†H†÷  1"testcase-E"010!0 +•0I÷ûδ†Qž=àŠlÎx<¦p~¼vÖ>bouncycastle-1.49.orig/test/data/org/bouncycastle/jce/provider/test/rsa3/self-testcase-E.pem0000644000175000017500000000613410503212005031444 0ustar ebourgebourg-----BEGIN CERTIFICATE----- MIIEHTCCAwWgAwIBAgIBADANBgkqhkiG9w0BAQQFADBsMQswCQYDVQQGEwJHQjES MBAGA1UECBMJQmVya3NoaXJlMRAwDgYDVQQHEwdOZXdidXJ5MRcwFQYDVQQKEw5N eSBDb21wYW55IEx0ZDEKMAgGA1UECxMBYTESMBAGA1UEAxMJbG9jYWxob3N0MB4X DTA2MDkxMzE4MjYzMloXDTA3MDkxMzE4MjYzMlowbDELMAkGA1UEBhMCR0IxEjAQ BgNVBAgTCUJlcmtzaGlyZTEQMA4GA1UEBxMHTmV3YnVyeTEXMBUGA1UEChMOTXkg Q29tcGFueSBMdGQxCjAIBgNVBAsTAWExEjAQBgNVBAMTCWxvY2FsaG9zdDCCASIw DQYJKoZIhvcNAQEBBQADggEPADCCAQoCggEBAKtexL4ZP1CWMsVedm+pD2xPG+md VbRqkVSDQYxrHUyRVKletjluY95908bsAlJR9oK/YehXe9W7r+LnotaR+yy1P45g hSWa6TNl1sz3NGIZwdU9WdqdNNs9YyDgzFezxzZffrh9xFTSF0CR66Tm1VasKa20 69RTx4fE5n4kZx+DKfBGCX3PBprvIANZp0nrfuhf21ij9lORI9OkITwqR72PrybB 9QDZB+7og1jGLAGbRBNR61mLVfKrg2yJVhpk1dHPsUzeVr3BB5XK8i7DvflWw5di PeyU4S7qm7WLZ9Wdg1XOchkQWmzqEUPG71dGzG6joPhdp56LFg2Yg58myRcCAwEA AaOByTCBxjAdBgNVHQ4EFgQUPd6mAcGQZ8iNGajt0kffN4AeDZswgZYGA1UdIwSB jjCBi4AUPd6mAcGQZ8iNGajt0kffN4AeDZuhcKRuMGwxCzAJBgNVBAYTAkdCMRIw EAYDVQQIEwlCZXJrc2hpcmUxEDAOBgNVBAcTB05ld2J1cnkxFzAVBgNVBAoTDk15 IENvbXBhbnkgTHRkMQowCAYDVQQLEwFhMRIwEAYDVQQDEwlsb2NhbGhvc3SCAQAw DAYDVR0TBAUwAwEB/zANBgkqhkiG9w0BAQQFAAOCAQEAkFwewElSyXCGG2ygI3I4 iYLtjAJAy002ES4JGHvr39dNhYoZ1poop18AU52mrx+SKX5vc/hAipisVa0rK9Jl 91GF5NQdhU0KWxNCBHZAy3dUf1M63jvTC3eiG8LVV+C77Cx936i8qO5f3qWCN40z 4W8eMwkCoVtpfzuuHk1by0VwCgU5IYuNIrwxR1bjudOctyhXNJjgr3SIsjDrqpTA nS4AauNFVqFfSyyaw5AX+7eA/WrMOGdJBJT1bEhHqrWxLtQzwSzKBKu7FpuF3mVX SHcSW4AzA6Yzq2Hcedo+SJt96IDr5xT17ncPMBzdq9pdoHlyJVq9+3O5JQOTx1WD 6g== -----END CERTIFICATE----- -----BEGIN RSA PRIVATE KEY----- MIIEogIBAAKCAQEAq17Evhk/UJYyxV52b6kPbE8b6Z1VtGqRVINBjGsdTJFUqV62 OW5j3n3TxuwCUlH2gr9h6Fd71buv4uei1pH7LLU/jmCFJZrpM2XWzPc0YhnB1T1Z 2p002z1jIODMV7PHNl9+uH3EVNIXQJHrpObVVqwprbTr1FPHh8TmfiRnH4Mp8EYJ fc8Gmu8gA1mnSet+6F/bWKP2U5Ej06QhPCpHvY+vJsH1ANkH7uiDWMYsAZtEE1Hr WYtV8quDbIlWGmTV0c+xTN5WvcEHlcryLsO9+VbDl2I97JThLuqbtYtn1Z2DVc5y GRBabOoRQ8bvV0bMbqOg+F2nnosWDZiDnybJFwIDAQABAoIBAGA8GNn0DaUwo5RI htQPqVSWXENlklJ9od1G1FGJeWudFWEDietYfYbdPEcyE9+snXUxCkdSkX0mKBCR KdW7JsUlh2pp83t5scmmP+jcTbNlaX9ZM5Nbwun3YCp/cuExWQbEu8HZBp7nWB1v lFgHNPi2N7WPqvuSjLNGtHVT9gEwWGUl1zfbuZp8pNT4r1l7nwj+S9pGF3v5RXDt qZWSbfPF3ESPkMOpXxGk5uDLx3aoeHBQALVjeNdVlkyxjrG75Pv7ZnrmXjXzcuVv aVACiCPWxzaRFR9cRCx/Z34KrJorLglrfIPIrRMKJY33QO2gpYYEpFkLsLth/Ip4 NMSJ3KkCgYEA36skUOFK0iQcdEaUXR2zcvQd3P3ctxe0JqD7dHFWnY2ndA5+VvAP vUjemZgw+tNt1qjLCAwxMi4cEOEICG6zSlMBRcVbqkKPS3gd3fGvD/lfQZ02EePz 6KYVC7xz1WXIcId/HvkBNmbPEyOLqi9fIJQoYrM3LnB3AFIUqQ4K3UMCgYEAxCRT Z6yLGFb6Evkvvc6usqDhpAjWaaTSxlsSf9IGsKXW90OronB1IiTaWgJze1PrwWy4 z4YOSI8oEEpF7LdwI9hztg9wFGht8lahGkfHtgR7V/QzyLMYfcU/57STI9vvsw2S FNqIdeP1Bd/CE8iI6o6HOAadsWlTBBUBUtnZnZ0CgYA/ecthpL5eKt9kZE9gqbgu rHb5K5aC45g9yjvyjOO+7N+UATT7qT9eQZrizh1AYdZvMBIGo6cmjY1rgOGNuxTo x+u5iEv+YstV6K3ZOeiryOKutVYN97pV0SRx4zagXjVnMhzyhkpAzSaBUPom/zCp B0L618+WP1aWYbT5UUHmDwKBgA3Ju+86yuBgJN42lCuUnuVBt/rvABuXEZYOCuPf YMcEMXNaV3No0mMfEhZnu7R8tsL3IJq+Ar0JCzjx765vSrvKWIAA39EfcjMp8dNG HnzmHcGWEhnWtS8KMa7ZG8rWiCgfGRjML/GRn8TU8PCxFSbf9BN1K5qwG7zauSgY 1lplAoGAfl1Qw77H27TYGMVBgco/2g05MaKb8TZ4PKn1znlPnNcqFEBi779W0/dD Zgb1mjnRQkw68Jj5XA2zv/06yjvTS+nHVEDCdgIrZI2p1IrI3F4tihSoWgYtoe+8 5OVDiHQ73d6lxVLqIRoRic8ZtWR02PbrK5SmoPsFdeTcmtzqo6c= -----END RSA PRIVATE KEY----- bouncycastle-1.49.orig/test/data/org/bouncycastle/jce/provider/test/rsa3/self-testcase-C.p120000644000175000017500000000526610503212005031270 0ustar ebourgebourg0‚ ²0‚ x *†H†÷  ‚ i‚ e0‚ a0‚ï *†H†÷  ‚à0‚Ü0‚Õ *†H†÷ 0 *†H†÷  0ý„ÒÃÇÃIR€‚¨Æ×$‹N zŸ³š@>ÏC•Ù»ü%U߃á¢Õ¶Ýý?ã%!¨˜}"S§Ë¹¦…AηlïlÍ:#ôq±ã"ô8ÉpÉB‘s+¦Ï¡ÎPäYÛƒRb”oHÒÚ^4àÁ:c„óÖ±f®‘|©º+A<äfJ˜wêPÔ9À• T'¶ŠÀÆ:,ÿuœÇØ ëBÖɧPÄÑ%G]¾öJ}ÒÛ½¯?™ëþœ”UY`LW$5vxsWáëÉŸ“õÖßÄä°eò鯾§Tt? S1Pòùü+‡‚Ë“cQ2_U8rœUaòZ«¾d-m²3'H¯g·<^œ“¦òI”¹=.ÏÄ Êj×õy\fJóˆIÅÈ"(¢ô2†ÅÄ`ÁÐȲd¡D#(@˜÷@R‚ °ñcã+±Ùå¼õLc"”"d~è)ÀíαZ2käÈX²Ÿ&9Ì»ÖÔê«(àLZªîOÚ°E=Gd¼»dKÉqxSÎÒ]ˆGñ-¹»¡º–JH6Úq vˆŸ²f·UAñšPÕc*¿ "±/~u%–"‹¬"&ìdIî*¶)ØX©L1RCv:u¢ä›WG¦L ,íM¸N/¨Òå»<©ÔO~÷‡¢SósC¦xÃÜWeýq×`Xý7¬¹(ëìh.–’@Cs9¦m‹½(Sý0‚j *†H†÷  ‚[‚W0‚S0‚O *†H†÷   ‚î0‚ê0 *†H†÷  0Ï4ÓÀhׂÈti¹­äió¯/$è?hvCñÕ„ n² UÙS¯R\ }Ñ•Eµ€D ¼Pk-TEQá>'»É•E×fSyA„„)sª›À&ÏÐbrqK`[,Gâ§(°ºQçÕˆÝjçºx[£¿ä§i؃hí*"KVRÄuÜvÆ÷=ÚÞtáq„z™úÛaÑrvM„÷ªf¼Ÿ“>mýÂÖ_j@ŽZ‹JÄÒ€vmaSûFu–Ú ÿÏmÌ1gºÛºË>Ê{ž¾Þ+ó«k¤ Ú¢óÇèrN‡>ù¤øçznÓ2%üY4è„V0·„m}ÍRº=9‰[aF玿`‰Ì«•5Hs&ž”neAÞ~À¼‰ågdX]ÛxØýZƒî·l%sH*"h.S¯}FqÉ’vïíÓEzíî/É…$ší?⡯Wg«žäR“åEŒ%Š{ Ü x^ïI×­bË3—àˆ&’îdTÒl a¸ËŒRYn„ê™#µDí·€#ýµ£ºJ9¡ÊÐXkd«54—§ ì'­üòBÿƒHFb›‹Àã]>JbPKäÿ~ ÄOͶ×N×H¬6ˆŸL¬À]T%Ìåú[l û¿ì^ø÷a§ôçc³ÂñÚÛBE®Ô§±£Óá–¢¬¿›i¶Êʲ3EËFŸïÒ\¡¬iWÌ ¿Wª Ç•Pnw{UÃ×^ùSÄ4\CD¤°£0-ͱ'úôO¬A¤0» ç PSâ=söŸº4„Ûmd† W¤o¶É»»¶ 4ŒÝר$'n¥±_^D½·ª7Ò»a+{ôu®]é>ëÛnM·¥!$ªç`;ñíwA¬™=!~â]ªr{î@C#¡ÓÛIÐå²·<Õ}23;õÁ¥ô-XpÆ6ÓèX ¨òWlB^ÅB?õðûÁï€ÿíÍ#Í¢n¢Ï;u Ÿùa9åùïY½©âçvKÅSd]]ñ_á0óÚj“~‘Ñ•=’ŸdÚ\y‡ò€]¨Æ2]%ØÖ“ß’§1N0# *†H†÷  1ÆÓ5E*IO#®ÓxÓ~è§ 10' *†H†÷  1"testcase-C"010!0 +†¿pO±Â[™åïNB1íS¦¥\¯°Ë+·—bouncycastle-1.49.orig/test/data/org/bouncycastle/jce/provider/test/rsa3/self-testcase-H.p120000644000175000017500000000526610503212005031275 0ustar ebourgebourg0‚ ²0‚ x *†H†÷  ‚ i‚ e0‚ a0‚ï *†H†÷  ‚à0‚Ü0‚Õ *†H†÷ 0 *†H†÷  0Р͋Шn€‚¨¼e2ÿM²Y<ëÏD‘ˆÊ¡ýƒ¦A > Ò^ùrnßH^Òg]÷ä•ðÅOÎÎÁ¿7SN!Ü¥÷8'®ÆB%Å}ýñ¥üY¿Þ Ú+Ý8 ‡Ú9›W çzó*ŽJ_¨oJ^ ý(µ ÷ß[Rós7ÉïгªLâð—/¹’£ëê[M¿D$2Âlò5 ÛP²'B3ÎûãÿwÉ5€‚6¢<{{?Òþlä][<­Ö!CmM¡žž’º©xŒE|ñÌÌA©V¸ay‹Eær1x[â咽Ôgéjy¶Tù*æËŽ /ZW—E#šŸÓ^ÉÉ~ˆ~«vWé—‡Õm„T·ÍúiÞ-݉8éG&ï=ü»·ØûyÞCu‰l,õONÕßÐà*Ò¦”Ò=×ԇgè”lëðO•K 3È+~üž=áÓv©ÀGN6ñ©+ òÕ°C¤Ö×Û‹á4¯šAXñ}¯¤¨E,t`ˆõEwüÝ„6DN¬ßK‰‚KÌ¢K-‚þóÑŠ€ÃüBQVyð~=K±b°9áüØ·<[Ì‚½ë{SßÙ§çOjS2!˜1󣸽âis”Z¤§—ã…ã¡Q¦®AòûØEÑÜÞ3,¦e(²Q_0äøÌrZãEêç<Ùiv€ÂôVϳÓI|Ÿò_¢(ÁÁ ×;Ól Á"àÕ¢WÌ Ž4±U'hÀIš&!]‰bóÊØçȯ³xÄ…Ìâ6wä œ1M{îŠ÷ˆû ÁUên—¨Ù ¨vÝp‰|Ú“Eª˜dGqªÓÖ0ž‰Ì—ËrQ©ÎkvÜ@ ÑÖÞÚ»ÍýkI˜g1+ÀMµ3zâ6Æ€^G‹å×·oµMÕ’º1P4·=Jþ¿Â/OÎq®ì||ËBx¯Íf/J ú¡À»‚þãåÈØD‰¯ËVö6“c m5>o•eT¥Þ‚{÷9Ãë69i%ú[+%zç×Yq]Ńd¬½ÀŽ*û@À¦uô|{4o›¯PÏ{Acò!U ²Œ±gE˜Ášá"žºD·2“¡ÞJ9Ù/µ²Û7ܾ¢FmÏI(/×õ£ª”T©\•à¿?·³Wk¢âŒ˜K7^&] [øf"[蔼QfÄø§©£¹ZÊ¿r¥ßUæ^OB»ü s€RÙÙ¼Ò¹qÙ ‰ Ê:ÑñÊËê‹•@ªÞU=øŠ—|³„&¦Ð·"‹¤ŸóÊfůƒ tQ*$9ú1ÀGÐMtzziEÍXcJæN¾Ÿ“^ý%¾4(Yé«KüøÔ+ê*ÓwN†ï7mËrpÆk@5PÀØÇ匽z ¿XH´¯qNœ^üzáÌÓþíç‹Vèrî#›aΦ6ê¾$l,±áOæÙ„6b·è u"¦IW»ÑIÆncú;µnü¹*ØÔ%QÀþ«Ròý‹5Yjd»œ\ øÝ­GÜŠT[¡IÞâjáÚÇD€ly˜‘N¨´KNÖž´®3sÇ„•'XDH´É`±¨¬Ý æDÖ"Ý´Á²13îP6/SXOû?}Kf°b:0‚j *†H†÷  ‚[‚W0‚S0‚O *†H†÷   ‚î0‚ê0 *†H†÷  0¬×íË»‚ÈÎ]Ó÷hJ«ƒÓž¼_ÜS‘ »×-M« &+ õƒŠU#k Ã×á­ï‡yÎú¥tîz® »ì€âkK`tÅ'Ä@\ zwXßéÑ)Ì>ât‰xÁ|„°Âäjî–Ì6çÚ©üG(P^qФ¡­Œµ­DÎÿ§-Ä(¾M[Œgã\¡à‡¥¸ÑqržÂWDq‰‹æ©< ÉÑò‚žt7¹ªÙ•Ú¢Ñ xA†ÏRjØÏCƒ¯†p0*·"aN©‡zïEé—‡yÚkèÈx%tUIÛcgýC˱ÿ¹Ûþ¹­IÓᛂÅt Ï…!dêù¡‚|jØ„:˜> ‡»—øèCÍ“ÛS>Jd\FÎq ]”«uâ 8±¨Ð/t™'{Þ¿7Ö}D +T#S,N­KX§öšŒ`:¥•Г6ŠÌo‡Ã"´×ˆPÃ5†æãü\žŒ6û;6þŽ:s‚|]zJ©lz-â„…»É':Rk À>öuÃUÓ®ÿk3‚ïPÇ‹#ûà‡¹Y7ÂUµrÜ"ŠÉƒ?èÍ"ku/Gςߛ)T=B* Ü^÷´æIÓŒ¢­ ×)ø‹NXÑÀg|ü.P[¹7q´ÐNˆõí6M¤xC ODÒ’pƒ3în"®k|Åmå:†>›Øa·QŒY¯ÌŽ>G1”äÙˆ$ÔŒ€ŸTNÕ®œƒ>–²áÝ5¯ëU¤qj>1®õf6ã<}±o¥› jÉTt‡©Œ÷Ö(©E¼¼òm«sä[¤€±Às¡Ë®©)š‹L"¥Är›&À‰¨0Zñ=L) ºª!íªkEA€àÜ—2àhÅ9Œ@{ê¹ò\ibŒ:‚Bâ×ýç,—{Ê~«9[å0[ÒhU˜Ä„>qpi…äõ–|rס”ñeõÕš?³b’²_£èZºBÕïðEŽÚ¸4®WŸ,€ˆÃ–Ò4­5d'/ŽK6´Ž àDJêÿÆ)_í´ÜIi/šÙ¸ë{èB}ß8­´¢}żܮ„È(a£ŠBÔÁÆT³måMSþ‰>`ÙP5tÉÊ‚§ ^ãÀ8ßU¡„“ŠPi}£›úLœù±Éì|¶LÂÃ?$|ú-¶uÒ1)нWDj-z~Cƒa?söµ„‘Ew YuÕAƤ=ЍÿgýxKúÌUº/3"ºX¡rZjŽ[_óûøÎnî·Cà“iþÅë¡¿/à@_ÙQ)°èê)•¾«„ ÜnÊghЕYbˆ¡VagnÕ™Þ7²f–ÜÓxmåú Í;­N.Ã;PûÛÀRèÿoÊ/X,K½µ"4õ„§±¸ß䷕щ±ègÃ|+þ-‘v‘é5û’ä€nøtiêQWçÖ’µó9uj.gPwcnÞLà øNL°ààªÿo,Œ2\öæ NÆÍG¦ñ=1 ìÿõeñÛâ±÷9U†·ÄXš††Õ}°I9MéŠ;¬œ`*Ôä¨Y´zÓð$“ÛCõðg‹zÚ@Õ˜HÿÏÍÖlàMâä¿?RÍQ;ÚÄ‚¢P=Úl4t4%°¥k¤UÖƒl¢:PéÞ¸’÷v£¹æ{0¶¬¨¾êœgj Ë2äÁ ¿)çú_Å1N0# *†H†÷  1zÔáüV²PÝØÚíÛg,å0' *†H†÷  1"testcase-H"010!0 + ò “…(i/»v¬6ƒ¾uÞ°å2=¿—nIbouncycastle-1.49.orig/test/data/org/bouncycastle/jce/provider/test/rsa3/self-testcase-C.pem0000644000175000017500000000613410503212005031442 0ustar ebourgebourg-----BEGIN CERTIFICATE----- MIIEHTCCAwWgAwIBAgIBADANBgkqhkiG9w0BAQQFADBsMQswCQYDVQQGEwJHQjES MBAGA1UECBMJQmVya3NoaXJlMRAwDgYDVQQHEwdOZXdidXJ5MRcwFQYDVQQKEw5N eSBDb21wYW55IEx0ZDEKMAgGA1UECxMBYTESMBAGA1UEAxMJbG9jYWxob3N0MB4X DTA2MDkxMzE4MjYzMloXDTA3MDkxMzE4MjYzMlowbDELMAkGA1UEBhMCR0IxEjAQ BgNVBAgTCUJlcmtzaGlyZTEQMA4GA1UEBxMHTmV3YnVyeTEXMBUGA1UEChMOTXkg Q29tcGFueSBMdGQxCjAIBgNVBAsTAWExEjAQBgNVBAMTCWxvY2FsaG9zdDCCASIw DQYJKoZIhvcNAQEBBQADggEPADCCAQoCggEBAKtexL4ZP1CWMsVedm+pD2xPG+md VbRqkVSDQYxrHUyRVKletjluY95908bsAlJR9oK/YehXe9W7r+LnotaR+yy1P45g hSWa6TNl1sz3NGIZwdU9WdqdNNs9YyDgzFezxzZffrh9xFTSF0CR66Tm1VasKa20 69RTx4fE5n4kZx+DKfBGCX3PBprvIANZp0nrfuhf21ij9lORI9OkITwqR72PrybB 9QDZB+7og1jGLAGbRBNR61mLVfKrg2yJVhpk1dHPsUzeVr3BB5XK8i7DvflWw5di PeyU4S7qm7WLZ9Wdg1XOchkQWmzqEUPG71dGzG6joPhdp56LFg2Yg58myRcCAwEA AaOByTCBxjAdBgNVHQ4EFgQUPd6mAcGQZ8iNGajt0kffN4AeDZswgZYGA1UdIwSB jjCBi4AUPd6mAcGQZ8iNGajt0kffN4AeDZuhcKRuMGwxCzAJBgNVBAYTAkdCMRIw EAYDVQQIEwlCZXJrc2hpcmUxEDAOBgNVBAcTB05ld2J1cnkxFzAVBgNVBAoTDk15 IENvbXBhbnkgTHRkMQowCAYDVQQLEwFhMRIwEAYDVQQDEwlsb2NhbGhvc3SCAQAw DAYDVR0TBAUwAwEB/zANBgkqhkiG9w0BAQQFAAOCAQEAkWkqxLQH4vvX5e2oiydv VN8Et+ZznJ78yifF7Tctjm9+EfEBRupHwXHlAZd2n2CsZfhVTqk/Rnffb078X3g5 9jx9ka0/hhkYyG6XqLybS3yXVpC/mvaeQMRu0Ubi0uSOkcf6rYiaqGjcG5DRaSAz SNNrDTEDYNxsuaPJoxZtQ+o1VaB3ksJ2UanzAHy45IJKXlSWS4l0Xsu6NZJxeMLB 0iL0j5+TcaK37dkNpDi4dhFbeOi30Q8rvC5BDorFMM8GEl+GevH6Rpk0P67WlnOY qeDoKjzKi1w0ZDBS8XI95DLsmnHXcg2Iu8Dx1iBJMFST6mLtsMdVQAD+y2NTkbpM xA== -----END CERTIFICATE----- -----BEGIN RSA PRIVATE KEY----- MIIEogIBAAKCAQEAq17Evhk/UJYyxV52b6kPbE8b6Z1VtGqRVINBjGsdTJFUqV62 OW5j3n3TxuwCUlH2gr9h6Fd71buv4uei1pH7LLU/jmCFJZrpM2XWzPc0YhnB1T1Z 2p002z1jIODMV7PHNl9+uH3EVNIXQJHrpObVVqwprbTr1FPHh8TmfiRnH4Mp8EYJ fc8Gmu8gA1mnSet+6F/bWKP2U5Ej06QhPCpHvY+vJsH1ANkH7uiDWMYsAZtEE1Hr WYtV8quDbIlWGmTV0c+xTN5WvcEHlcryLsO9+VbDl2I97JThLuqbtYtn1Z2DVc5y GRBabOoRQ8bvV0bMbqOg+F2nnosWDZiDnybJFwIDAQABAoIBAGA8GNn0DaUwo5RI htQPqVSWXENlklJ9od1G1FGJeWudFWEDietYfYbdPEcyE9+snXUxCkdSkX0mKBCR KdW7JsUlh2pp83t5scmmP+jcTbNlaX9ZM5Nbwun3YCp/cuExWQbEu8HZBp7nWB1v lFgHNPi2N7WPqvuSjLNGtHVT9gEwWGUl1zfbuZp8pNT4r1l7nwj+S9pGF3v5RXDt qZWSbfPF3ESPkMOpXxGk5uDLx3aoeHBQALVjeNdVlkyxjrG75Pv7ZnrmXjXzcuVv aVACiCPWxzaRFR9cRCx/Z34KrJorLglrfIPIrRMKJY33QO2gpYYEpFkLsLth/Ip4 NMSJ3KkCgYEA36skUOFK0iQcdEaUXR2zcvQd3P3ctxe0JqD7dHFWnY2ndA5+VvAP vUjemZgw+tNt1qjLCAwxMi4cEOEICG6zSlMBRcVbqkKPS3gd3fGvD/lfQZ02EePz 6KYVC7xz1WXIcId/HvkBNmbPEyOLqi9fIJQoYrM3LnB3AFIUqQ4K3UMCgYEAxCRT Z6yLGFb6Evkvvc6usqDhpAjWaaTSxlsSf9IGsKXW90OronB1IiTaWgJze1PrwWy4 z4YOSI8oEEpF7LdwI9hztg9wFGht8lahGkfHtgR7V/QzyLMYfcU/57STI9vvsw2S FNqIdeP1Bd/CE8iI6o6HOAadsWlTBBUBUtnZnZ0CgYA/ecthpL5eKt9kZE9gqbgu rHb5K5aC45g9yjvyjOO+7N+UATT7qT9eQZrizh1AYdZvMBIGo6cmjY1rgOGNuxTo x+u5iEv+YstV6K3ZOeiryOKutVYN97pV0SRx4zagXjVnMhzyhkpAzSaBUPom/zCp B0L618+WP1aWYbT5UUHmDwKBgA3Ju+86yuBgJN42lCuUnuVBt/rvABuXEZYOCuPf YMcEMXNaV3No0mMfEhZnu7R8tsL3IJq+Ar0JCzjx765vSrvKWIAA39EfcjMp8dNG HnzmHcGWEhnWtS8KMa7ZG8rWiCgfGRjML/GRn8TU8PCxFSbf9BN1K5qwG7zauSgY 1lplAoGAfl1Qw77H27TYGMVBgco/2g05MaKb8TZ4PKn1znlPnNcqFEBi779W0/dD Zgb1mjnRQkw68Jj5XA2zv/06yjvTS+nHVEDCdgIrZI2p1IrI3F4tihSoWgYtoe+8 5OVDiHQ73d6lxVLqIRoRic8ZtWR02PbrK5SmoPsFdeTcmtzqo6c= -----END RSA PRIVATE KEY----- bouncycastle-1.49.orig/test/data/org/bouncycastle/jce/provider/test/rsa3/self-testcase-L.pem0000644000175000017500000000613410503212005031453 0ustar ebourgebourg-----BEGIN CERTIFICATE----- MIIEHTCCAwWgAwIBAgIBADANBgkqhkiG9w0BAQQFADBsMQswCQYDVQQGEwJHQjES MBAGA1UECBMJQmVya3NoaXJlMRAwDgYDVQQHEwdOZXdidXJ5MRcwFQYDVQQKEw5N eSBDb21wYW55IEx0ZDEKMAgGA1UECxMBYTESMBAGA1UEAxMJbG9jYWxob3N0MB4X DTA2MDkxMzE4MjYzMloXDTA3MDkxMzE4MjYzMlowbDELMAkGA1UEBhMCR0IxEjAQ BgNVBAgTCUJlcmtzaGlyZTEQMA4GA1UEBxMHTmV3YnVyeTEXMBUGA1UEChMOTXkg Q29tcGFueSBMdGQxCjAIBgNVBAsTAWExEjAQBgNVBAMTCWxvY2FsaG9zdDCCASIw DQYJKoZIhvcNAQEBBQADggEPADCCAQoCggEBAKtexL4ZP1CWMsVedm+pD2xPG+md VbRqkVSDQYxrHUyRVKletjluY95908bsAlJR9oK/YehXe9W7r+LnotaR+yy1P45g hSWa6TNl1sz3NGIZwdU9WdqdNNs9YyDgzFezxzZffrh9xFTSF0CR66Tm1VasKa20 69RTx4fE5n4kZx+DKfBGCX3PBprvIANZp0nrfuhf21ij9lORI9OkITwqR72PrybB 9QDZB+7og1jGLAGbRBNR61mLVfKrg2yJVhpk1dHPsUzeVr3BB5XK8i7DvflWw5di PeyU4S7qm7WLZ9Wdg1XOchkQWmzqEUPG71dGzG6joPhdp56LFg2Yg58myRcCAwEA AaOByTCBxjAdBgNVHQ4EFgQUPd6mAcGQZ8iNGajt0kffN4AeDZswgZYGA1UdIwSB jjCBi4AUPd6mAcGQZ8iNGajt0kffN4AeDZuhcKRuMGwxCzAJBgNVBAYTAkdCMRIw EAYDVQQIEwlCZXJrc2hpcmUxEDAOBgNVBAcTB05ld2J1cnkxFzAVBgNVBAoTDk15 IENvbXBhbnkgTHRkMQowCAYDVQQLEwFhMRIwEAYDVQQDEwlsb2NhbGhvc3SCAQAw DAYDVR0TBAUwAwEB/zANBgkqhkiG9w0BAQQFAAOCAQEAoArZH56QUnasmPqCd68C kcG6hw5S6p7wloY9jz+iwh9b2tF3k1SPCeE7rBV7cevr1ruv/wWttBFiGfJK/hlL 8C/MMPj1X5JuLY3JgNmNDSK9MLr5Ejvps0AQ+kA4CCSxxpTLWeUlqNnGk/Zcfoqa Gyk37PDlHMQC3QWLgAX+wG/rg8WvrAP1ZjM6t25yb6hIPZgCWZbq+j8X5kS3Qxz0 buc9HMi9oeuejeP7zWRJHhnCcDuClmpI6pk9nkjmunYtF2rMWi7f2eJ0Qjbo1wnn rUU5sCGLZ6i3ux/HvMgynho7RVqV+bqV+G9wZem3crNbtLhUSB2SAgYZnMqrLcW9 jQ== -----END CERTIFICATE----- -----BEGIN RSA PRIVATE KEY----- MIIEogIBAAKCAQEAq17Evhk/UJYyxV52b6kPbE8b6Z1VtGqRVINBjGsdTJFUqV62 OW5j3n3TxuwCUlH2gr9h6Fd71buv4uei1pH7LLU/jmCFJZrpM2XWzPc0YhnB1T1Z 2p002z1jIODMV7PHNl9+uH3EVNIXQJHrpObVVqwprbTr1FPHh8TmfiRnH4Mp8EYJ fc8Gmu8gA1mnSet+6F/bWKP2U5Ej06QhPCpHvY+vJsH1ANkH7uiDWMYsAZtEE1Hr WYtV8quDbIlWGmTV0c+xTN5WvcEHlcryLsO9+VbDl2I97JThLuqbtYtn1Z2DVc5y GRBabOoRQ8bvV0bMbqOg+F2nnosWDZiDnybJFwIDAQABAoIBAGA8GNn0DaUwo5RI htQPqVSWXENlklJ9od1G1FGJeWudFWEDietYfYbdPEcyE9+snXUxCkdSkX0mKBCR KdW7JsUlh2pp83t5scmmP+jcTbNlaX9ZM5Nbwun3YCp/cuExWQbEu8HZBp7nWB1v lFgHNPi2N7WPqvuSjLNGtHVT9gEwWGUl1zfbuZp8pNT4r1l7nwj+S9pGF3v5RXDt qZWSbfPF3ESPkMOpXxGk5uDLx3aoeHBQALVjeNdVlkyxjrG75Pv7ZnrmXjXzcuVv aVACiCPWxzaRFR9cRCx/Z34KrJorLglrfIPIrRMKJY33QO2gpYYEpFkLsLth/Ip4 NMSJ3KkCgYEA36skUOFK0iQcdEaUXR2zcvQd3P3ctxe0JqD7dHFWnY2ndA5+VvAP vUjemZgw+tNt1qjLCAwxMi4cEOEICG6zSlMBRcVbqkKPS3gd3fGvD/lfQZ02EePz 6KYVC7xz1WXIcId/HvkBNmbPEyOLqi9fIJQoYrM3LnB3AFIUqQ4K3UMCgYEAxCRT Z6yLGFb6Evkvvc6usqDhpAjWaaTSxlsSf9IGsKXW90OronB1IiTaWgJze1PrwWy4 z4YOSI8oEEpF7LdwI9hztg9wFGht8lahGkfHtgR7V/QzyLMYfcU/57STI9vvsw2S FNqIdeP1Bd/CE8iI6o6HOAadsWlTBBUBUtnZnZ0CgYA/ecthpL5eKt9kZE9gqbgu rHb5K5aC45g9yjvyjOO+7N+UATT7qT9eQZrizh1AYdZvMBIGo6cmjY1rgOGNuxTo x+u5iEv+YstV6K3ZOeiryOKutVYN97pV0SRx4zagXjVnMhzyhkpAzSaBUPom/zCp B0L618+WP1aWYbT5UUHmDwKBgA3Ju+86yuBgJN42lCuUnuVBt/rvABuXEZYOCuPf YMcEMXNaV3No0mMfEhZnu7R8tsL3IJq+Ar0JCzjx765vSrvKWIAA39EfcjMp8dNG HnzmHcGWEhnWtS8KMa7ZG8rWiCgfGRjML/GRn8TU8PCxFSbf9BN1K5qwG7zauSgY 1lplAoGAfl1Qw77H27TYGMVBgco/2g05MaKb8TZ4PKn1znlPnNcqFEBi779W0/dD Zgb1mjnRQkw68Jj5XA2zv/06yjvTS+nHVEDCdgIrZI2p1IrI3F4tihSoWgYtoe+8 5OVDiHQ73d6lxVLqIRoRic8ZtWR02PbrK5SmoPsFdeTcmtzqo6c= -----END RSA PRIVATE KEY----- bouncycastle-1.49.orig/test/data/org/bouncycastle/jce/provider/test/rsa3/self-testcase-J.pem0000644000175000017500000000613410503212005031451 0ustar ebourgebourg-----BEGIN CERTIFICATE----- MIIEHTCCAwWgAwIBAgIBADANBgkqhkiG9w0BAQQFADBsMQswCQYDVQQGEwJHQjES MBAGA1UECBMJQmVya3NoaXJlMRAwDgYDVQQHEwdOZXdidXJ5MRcwFQYDVQQKEw5N eSBDb21wYW55IEx0ZDEKMAgGA1UECxMBYTESMBAGA1UEAxMJbG9jYWxob3N0MB4X DTA2MDkxMzE4MjYzMloXDTA3MDkxMzE4MjYzMlowbDELMAkGA1UEBhMCR0IxEjAQ BgNVBAgTCUJlcmtzaGlyZTEQMA4GA1UEBxMHTmV3YnVyeTEXMBUGA1UEChMOTXkg Q29tcGFueSBMdGQxCjAIBgNVBAsTAWExEjAQBgNVBAMTCWxvY2FsaG9zdDCCASIw DQYJKoZIhvcNAQEBBQADggEPADCCAQoCggEBAKtexL4ZP1CWMsVedm+pD2xPG+md VbRqkVSDQYxrHUyRVKletjluY95908bsAlJR9oK/YehXe9W7r+LnotaR+yy1P45g hSWa6TNl1sz3NGIZwdU9WdqdNNs9YyDgzFezxzZffrh9xFTSF0CR66Tm1VasKa20 69RTx4fE5n4kZx+DKfBGCX3PBprvIANZp0nrfuhf21ij9lORI9OkITwqR72PrybB 9QDZB+7og1jGLAGbRBNR61mLVfKrg2yJVhpk1dHPsUzeVr3BB5XK8i7DvflWw5di PeyU4S7qm7WLZ9Wdg1XOchkQWmzqEUPG71dGzG6joPhdp56LFg2Yg58myRcCAwEA AaOByTCBxjAdBgNVHQ4EFgQUPd6mAcGQZ8iNGajt0kffN4AeDZswgZYGA1UdIwSB jjCBi4AUPd6mAcGQZ8iNGajt0kffN4AeDZuhcKRuMGwxCzAJBgNVBAYTAkdCMRIw EAYDVQQIEwlCZXJrc2hpcmUxEDAOBgNVBAcTB05ld2J1cnkxFzAVBgNVBAoTDk15 IENvbXBhbnkgTHRkMQowCAYDVQQLEwFhMRIwEAYDVQQDEwlsb2NhbGhvc3SCAQAw DAYDVR0TBAUwAwEB/zANBgkqhkiG9w0BAQQFAAOCAQEADFGQ9QEI1TU+qRg2QFLZ OhYryOaAXNOaEBR+f0LCG5My9j0vI3/1BKHwq6kVPVDkfSPrrX1ZNUPOAI+PLrwI RGsJw6ST8dyWXeY4LEarHOPLvSTD2u+WaPcRMJSsSTFnsscKgrAeu4VfZixOTpBp tI3bfqTPkY9Fra8R1M9PbNsPik0WI34nPS0T9XqF+s/FhHCcL/mX/Hj5aD0qEZWd wCSJGDyoZRQeMc7LowMGHpu1eqcqfSLt2TCPeXebVB031AioCe1iJUddb9WxHixH GyNlzJl7YwztT9Z3yRqHKde6Dun128N2YThQ/7/Dn54hXcWQCK4gFCTz2deD5S9Z TQ== -----END CERTIFICATE----- -----BEGIN RSA PRIVATE KEY----- MIIEogIBAAKCAQEAq17Evhk/UJYyxV52b6kPbE8b6Z1VtGqRVINBjGsdTJFUqV62 OW5j3n3TxuwCUlH2gr9h6Fd71buv4uei1pH7LLU/jmCFJZrpM2XWzPc0YhnB1T1Z 2p002z1jIODMV7PHNl9+uH3EVNIXQJHrpObVVqwprbTr1FPHh8TmfiRnH4Mp8EYJ fc8Gmu8gA1mnSet+6F/bWKP2U5Ej06QhPCpHvY+vJsH1ANkH7uiDWMYsAZtEE1Hr WYtV8quDbIlWGmTV0c+xTN5WvcEHlcryLsO9+VbDl2I97JThLuqbtYtn1Z2DVc5y GRBabOoRQ8bvV0bMbqOg+F2nnosWDZiDnybJFwIDAQABAoIBAGA8GNn0DaUwo5RI htQPqVSWXENlklJ9od1G1FGJeWudFWEDietYfYbdPEcyE9+snXUxCkdSkX0mKBCR KdW7JsUlh2pp83t5scmmP+jcTbNlaX9ZM5Nbwun3YCp/cuExWQbEu8HZBp7nWB1v lFgHNPi2N7WPqvuSjLNGtHVT9gEwWGUl1zfbuZp8pNT4r1l7nwj+S9pGF3v5RXDt qZWSbfPF3ESPkMOpXxGk5uDLx3aoeHBQALVjeNdVlkyxjrG75Pv7ZnrmXjXzcuVv aVACiCPWxzaRFR9cRCx/Z34KrJorLglrfIPIrRMKJY33QO2gpYYEpFkLsLth/Ip4 NMSJ3KkCgYEA36skUOFK0iQcdEaUXR2zcvQd3P3ctxe0JqD7dHFWnY2ndA5+VvAP vUjemZgw+tNt1qjLCAwxMi4cEOEICG6zSlMBRcVbqkKPS3gd3fGvD/lfQZ02EePz 6KYVC7xz1WXIcId/HvkBNmbPEyOLqi9fIJQoYrM3LnB3AFIUqQ4K3UMCgYEAxCRT Z6yLGFb6Evkvvc6usqDhpAjWaaTSxlsSf9IGsKXW90OronB1IiTaWgJze1PrwWy4 z4YOSI8oEEpF7LdwI9hztg9wFGht8lahGkfHtgR7V/QzyLMYfcU/57STI9vvsw2S FNqIdeP1Bd/CE8iI6o6HOAadsWlTBBUBUtnZnZ0CgYA/ecthpL5eKt9kZE9gqbgu rHb5K5aC45g9yjvyjOO+7N+UATT7qT9eQZrizh1AYdZvMBIGo6cmjY1rgOGNuxTo x+u5iEv+YstV6K3ZOeiryOKutVYN97pV0SRx4zagXjVnMhzyhkpAzSaBUPom/zCp B0L618+WP1aWYbT5UUHmDwKBgA3Ju+86yuBgJN42lCuUnuVBt/rvABuXEZYOCuPf YMcEMXNaV3No0mMfEhZnu7R8tsL3IJq+Ar0JCzjx765vSrvKWIAA39EfcjMp8dNG HnzmHcGWEhnWtS8KMa7ZG8rWiCgfGRjML/GRn8TU8PCxFSbf9BN1K5qwG7zauSgY 1lplAoGAfl1Qw77H27TYGMVBgco/2g05MaKb8TZ4PKn1znlPnNcqFEBi779W0/dD Zgb1mjnRQkw68Jj5XA2zv/06yjvTS+nHVEDCdgIrZI2p1IrI3F4tihSoWgYtoe+8 5OVDiHQ73d6lxVLqIRoRic8ZtWR02PbrK5SmoPsFdeTcmtzqo6c= -----END RSA PRIVATE KEY----- bouncycastle-1.49.orig/test/data/org/bouncycastle/jce/provider/test/rsa3/self-testcase-L.p120000644000175000017500000000526610503212005031301 0ustar ebourgebourg0‚ ²0‚ x *†H†÷  ‚ i‚ e0‚ a0‚ï *†H†÷  ‚à0‚Ü0‚Õ *†H†÷ 0 *†H†÷  0fž2=;¸Å€‚¨Þ€%àOŽUÈívw#™p|pÿÕ þƒc³µ¨c …ƾƒ8̱U—ÿJ»¨€ó~Æ›+šÑuU¥®À6¬62ÕD© §&EÁç^—l©‰/³­­ÈŽ–U¢€AȬȷËE˜ò|ZÝ­_ ’-FæIØ’Œ ã @<ìWӤѩÒÌ Øß"b¶ý˜i;Íz:®tVì(’r¦Ì';+‚½þœÌ‰ rÜ[Ò yRF«ðpéZA§bb¤=oh;«zcbrnF ¨+• D›fõ2ÚhÒ·68H<«|ÛH…m%× ]lX­ï'fß&?û“aÿ(ÞWlù‰„J`åÜ÷m½³Båâ.™¦Å§Gxö‘Mbõ5)+‘k’¼ˆ­‚lîZm' -öÁêZ"ˇ'•ZäÃH-ä¢oçÆ`ÁõÒèZós÷¼¢2¡ÄX½T!έñæ5yÆ;_Åoì9¸T&Él7“­Õݤc`u µßáô#Ô Sâ,«ôC¶ãNvÒSJÕû^å]frñ/…ššh¸kFëÔ'¾Ìn¨AÖËšE*8Šœ5]Ù–®Í5|ã]¼~tnªèEúc…‚°Šï .»ô¨{ÈÜþø¼0$øÙMf`¸ý†ìÉÒÑâ–|ÏÛxMÒ¤tv±¡ Âéþ3“2:ÔóÎø¨Ãh~0Í €ÉÕsA‘êð„¿7\—Ü­]÷½q>8]4ÁG¨ÍÛç¨cÁT«1gMßNŽDTa|u¥ü>Ÿ#[cg¦$5à.ñšÄ~-ï„~ž’úvûCB#Ôbq®}1ÇV1êØWC.Åk~ÅØê’p¤Ñ8–CƒÙ¦Õt?‚Œ'Ú ûBùÔl³kNóhd F¡æàÐQÞ7¬ö¨on-ípº.È]þ†w¯Q„ÒÀjc§a=îi_h5çâĵÌqÆÿã\óäPB¤ŠÃHò„³"²…ê<é?É¢Á–Ü;«äÐ]ÔD/DU¯·]×.QŒ\F†GÞzO0‚j *†H†÷  ‚[‚W0‚S0‚O *†H†÷   ‚î0‚ê0 *†H†÷  0jH g¯#1ÿ‚Ȫºg¡R”4.ÞV!—B5£–moÆ…I"š«ñÚùýXêAÝ3‡üÅyG ô®žºEp`X´/–]ìD¬m§6éXU¨'^ÁÆýÈK,èb÷B¶@l³¾¢µ ÌáàmEDhÉø¶Yþ×Ô]КÛæ4ɸSÑ*÷ÇÖ„¨e_àJiÄ¢2ùµ@V,UÈ‚å꓊hÈh­õ…«ŸO‡£ÕÅ Â×L±zZ«ªxT°íM~”¹~A­÷þÑÇa´DɉÐï8qÐé«tâ)r£^*Û}—‘F(PÆ„u>…pv†³UÞüå¾5†œ½Ë6—ó°.y††ñ¬ÉÊGÿg]Ml²öª 9D|³†¦>­?;mj¥T¾ µoè)ko—ìXi— ­…Ú<ŽïñƬ-v"Žî€ò3Q6ƒ¤}Äü¦NŒ®!7$h3¬æªÎŸ¹Qü ¸îÿ:6…òoz1íC»²“šÆû/*ÎLV;‚¬±_jØ‘áþÓuÒ ¸_#´x¢ú†+JLñ¥„Çá ,ñ¶Å혛†âQs7PanûåÒºïÖ³‚‰*Íûª>ì: —tÃÃç³ûñÄ`P„¹ïO•±>xeu­_c@²+ÝŽ”N˜bëïcO”6š¹—–v%B­R̼Øp®8J*Hû4$Ã6 ¹ày¢¿éT|RÊ]iˆÐšŒaŒÏ˜Ä•tmgGº¡a(ÖqÈ0UÔ`ÊÛ™þ¥²‚!6»äu¸b ‰0‡«šÅÞq^‰¬Ù?À1"Ÿ pÑX«ÁŽçƒ5”wÃ"â¼Î_2‡ QñƒJ´éÔ¦ÐÃNÁLZ„ˆð(6S‡Ý¢óšUÀ<ÉAÍkßÒb :ò9êf˜_ úwÕ›øÛ`ßÎ6¹ å ¦ R"‘•î%æZ¹/Nø˜·ÃÄèVùá8K÷Î1ØÖœšäßHE´CH=ŒÍ=t<¸h>zXy;ÅZ® ¼L¤¹ïW1N0# *†H†÷  1Nªw•m¸ðß1„D¸&Ý6ТE0' *†H†÷  1"testcase-L"010!0 +wÈè²è=’:ÃhÖL*1aS“îè¯À³{÷Obouncycastle-1.49.orig/test/data/org/bouncycastle/jce/provider/test/rsa3/self-testcase-A.pem0000644000175000017500000000613410503212005031440 0ustar ebourgebourg-----BEGIN CERTIFICATE----- MIIEHTCCAwWgAwIBAgIBADANBgkqhkiG9w0BAQQFADBsMQswCQYDVQQGEwJHQjES MBAGA1UECBMJQmVya3NoaXJlMRAwDgYDVQQHEwdOZXdidXJ5MRcwFQYDVQQKEw5N eSBDb21wYW55IEx0ZDEKMAgGA1UECxMBYTESMBAGA1UEAxMJbG9jYWxob3N0MB4X DTA2MDkxMzE4MjYzMloXDTA3MDkxMzE4MjYzMlowbDELMAkGA1UEBhMCR0IxEjAQ BgNVBAgTCUJlcmtzaGlyZTEQMA4GA1UEBxMHTmV3YnVyeTEXMBUGA1UEChMOTXkg Q29tcGFueSBMdGQxCjAIBgNVBAsTAWExEjAQBgNVBAMTCWxvY2FsaG9zdDCCASIw DQYJKoZIhvcNAQEBBQADggEPADCCAQoCggEBAKtexL4ZP1CWMsVedm+pD2xPG+md VbRqkVSDQYxrHUyRVKletjluY95908bsAlJR9oK/YehXe9W7r+LnotaR+yy1P45g hSWa6TNl1sz3NGIZwdU9WdqdNNs9YyDgzFezxzZffrh9xFTSF0CR66Tm1VasKa20 69RTx4fE5n4kZx+DKfBGCX3PBprvIANZp0nrfuhf21ij9lORI9OkITwqR72PrybB 9QDZB+7og1jGLAGbRBNR61mLVfKrg2yJVhpk1dHPsUzeVr3BB5XK8i7DvflWw5di PeyU4S7qm7WLZ9Wdg1XOchkQWmzqEUPG71dGzG6joPhdp56LFg2Yg58myRcCAwEA AaOByTCBxjAdBgNVHQ4EFgQUPd6mAcGQZ8iNGajt0kffN4AeDZswgZYGA1UdIwSB jjCBi4AUPd6mAcGQZ8iNGajt0kffN4AeDZuhcKRuMGwxCzAJBgNVBAYTAkdCMRIw EAYDVQQIEwlCZXJrc2hpcmUxEDAOBgNVBAcTB05ld2J1cnkxFzAVBgNVBAoTDk15 IENvbXBhbnkgTHRkMQowCAYDVQQLEwFhMRIwEAYDVQQDEwlsb2NhbGhvc3SCAQAw DAYDVR0TBAUwAwEB/zANBgkqhkiG9w0BAQQFAAOCAQEAC0dXvAI0/fhu22j15YEo F8M3OYM8fwlvxs2/qtwELR3hVckpRIJmfGpUutb6/TBPgTS8a/fmzcrxLsL/aGSD jH4/TmTHrRmhlT/einuudpAXPxaS27Yz7duxRPmyXeyHy3P0ulXDEzOaZdV8kxQs J/v+z0knwdAh91omHRfJuNxDQtLfjp1Qtz+jrBCI6s864UblKXG/AwjWOLFQ1E0N A2bDo72tr3aw01gryggFkyNrB9K5/15+jJLVLFjuJfP7m3FUjPfGQB9+eZMBWpNH hGcSsPibqWVTDMjN0Z/mTGMzZDsEXX0Ao1K21q5vK1sfFYEahv/PCwkcW1dOeTGF pQ== -----END CERTIFICATE----- -----BEGIN RSA PRIVATE KEY----- MIIEogIBAAKCAQEAq17Evhk/UJYyxV52b6kPbE8b6Z1VtGqRVINBjGsdTJFUqV62 OW5j3n3TxuwCUlH2gr9h6Fd71buv4uei1pH7LLU/jmCFJZrpM2XWzPc0YhnB1T1Z 2p002z1jIODMV7PHNl9+uH3EVNIXQJHrpObVVqwprbTr1FPHh8TmfiRnH4Mp8EYJ fc8Gmu8gA1mnSet+6F/bWKP2U5Ej06QhPCpHvY+vJsH1ANkH7uiDWMYsAZtEE1Hr WYtV8quDbIlWGmTV0c+xTN5WvcEHlcryLsO9+VbDl2I97JThLuqbtYtn1Z2DVc5y GRBabOoRQ8bvV0bMbqOg+F2nnosWDZiDnybJFwIDAQABAoIBAGA8GNn0DaUwo5RI htQPqVSWXENlklJ9od1G1FGJeWudFWEDietYfYbdPEcyE9+snXUxCkdSkX0mKBCR KdW7JsUlh2pp83t5scmmP+jcTbNlaX9ZM5Nbwun3YCp/cuExWQbEu8HZBp7nWB1v lFgHNPi2N7WPqvuSjLNGtHVT9gEwWGUl1zfbuZp8pNT4r1l7nwj+S9pGF3v5RXDt qZWSbfPF3ESPkMOpXxGk5uDLx3aoeHBQALVjeNdVlkyxjrG75Pv7ZnrmXjXzcuVv aVACiCPWxzaRFR9cRCx/Z34KrJorLglrfIPIrRMKJY33QO2gpYYEpFkLsLth/Ip4 NMSJ3KkCgYEA36skUOFK0iQcdEaUXR2zcvQd3P3ctxe0JqD7dHFWnY2ndA5+VvAP vUjemZgw+tNt1qjLCAwxMi4cEOEICG6zSlMBRcVbqkKPS3gd3fGvD/lfQZ02EePz 6KYVC7xz1WXIcId/HvkBNmbPEyOLqi9fIJQoYrM3LnB3AFIUqQ4K3UMCgYEAxCRT Z6yLGFb6Evkvvc6usqDhpAjWaaTSxlsSf9IGsKXW90OronB1IiTaWgJze1PrwWy4 z4YOSI8oEEpF7LdwI9hztg9wFGht8lahGkfHtgR7V/QzyLMYfcU/57STI9vvsw2S FNqIdeP1Bd/CE8iI6o6HOAadsWlTBBUBUtnZnZ0CgYA/ecthpL5eKt9kZE9gqbgu rHb5K5aC45g9yjvyjOO+7N+UATT7qT9eQZrizh1AYdZvMBIGo6cmjY1rgOGNuxTo x+u5iEv+YstV6K3ZOeiryOKutVYN97pV0SRx4zagXjVnMhzyhkpAzSaBUPom/zCp B0L618+WP1aWYbT5UUHmDwKBgA3Ju+86yuBgJN42lCuUnuVBt/rvABuXEZYOCuPf YMcEMXNaV3No0mMfEhZnu7R8tsL3IJq+Ar0JCzjx765vSrvKWIAA39EfcjMp8dNG HnzmHcGWEhnWtS8KMa7ZG8rWiCgfGRjML/GRn8TU8PCxFSbf9BN1K5qwG7zauSgY 1lplAoGAfl1Qw77H27TYGMVBgco/2g05MaKb8TZ4PKn1znlPnNcqFEBi779W0/dD Zgb1mjnRQkw68Jj5XA2zv/06yjvTS+nHVEDCdgIrZI2p1IrI3F4tihSoWgYtoe+8 5OVDiHQ73d6lxVLqIRoRic8ZtWR02PbrK5SmoPsFdeTcmtzqo6c= -----END RSA PRIVATE KEY----- bouncycastle-1.49.orig/test/data/org/bouncycastle/jce/provider/test/rsa3/self-testcase-F.p120000644000175000017500000000526610503212005031273 0ustar ebourgebourg0‚ ²0‚ x *†H†÷  ‚ i‚ e0‚ a0‚ï *†H†÷  ‚à0‚Ü0‚Õ *†H†÷ 0 *†H†÷  0$e`DI;€‚¨äL˜’)•¨¼-[²ø ß¹j ŸÑ¹R© ôÐÖsV]r,,z1$Õ}þîtPb‘m¨)ŒÉ.§TåZÔj&ܤ©³ÜºGÊ_3`á”Âu¦œ=5Wm°¼7¡^Æ}l‹sÏæì¼Q ÙL-ìäÑ^CEÐÀCÔÖ@ßd›mLÊ&ÿÊ‹ ‚f žø(^ޏŽ:tå.Ãçi¿+ átaܼÖo©ÆØ Q[|·o¥¼Úe;VhR0Ì¢]Ìdý‰Ð+•ÔjëhFÌò!nq)Ø 5˜8h¼X˜%o¼ìöó3¨­øËXWƒœøI“¾’7ü4¤QÇãr`‰7µ~Q3h÷©Ü<Ùeä0”„ñ• üXªþV9áSVæ#ðGwLÑì0w´¸Ž3]Eiˆ œ/¼ud7›@ÿíÇ8;Ô êZâþ7¥ÞÇr Qé³{—€w³EàùöFš¾ŠSxCH\‡l+Û°!™t÷âéKÙ–4+â/Ä2ÈÅ%@ðd7{¾‡^D23…[×ÂN0Cùõ¯-ÛÊþ»pYNšÃ¨M”I9 “ß$³þ‚6}„Ñ?)cÛ½¡÷ØÛX6ì ßÕ1óhÖN³V1¸©È—ò’СäÉn.*PbÿZu ±‰:Cn…`Yü!IzMóGØ/YÄÁ&n/Xx¦r?£à&µ’>Èg‡ø4ºôÍ´z²ÀªM{ÂÉ-2,~¨$P“±ÿDÒû+%î©*'$êÂÓ¾EÿsÓL¹xVŠíáyÅØfè&à¤<“Ë!…Ëç¼E(¾H§ ŒLï¯Ñÿˆ GëåÈ1HHðéÇo¡>/W,:ÚÄ'-ÞÒ‹­ðý"Ñ5Ê£ØOj'ÅöîrgAÄó/ê ] O, Cñ‹NBS+U)ØP/´/gD|Î’£²#xÌÆ4“5REÆÞor9b­JcÆ Ä\HTuœÇ‘ÏÎÎë(h¦%Uëâò<]Ücí¿tJPíË^ ÅÚwyÅ:9°«XÙÒIóQ¾€ý‰02ˆåµB‡ ˜¼eŒ}xL‚ùE>°ìDZ4 \åð5$õþ²¶+A|ßÏ߀2\¥#C‘á7mޱ…éˆÏu`ø 1ä[¤4:´¤NÅöOÜþº ÃÂ9—¡óëÏ•ÂVÃ!dŸ¶}rƒŽ)-¾~ SA¿=VCN¿CV­B…V™ëÏô¾Š7‚\á;óM†IJ+Ï‚,í9‰ÊÔS¿ŒKJBÓ+lijØôMZDo½Øa™&¤ W}ÞQîqÖ?Ïž ñ£ú宅ëÿì\jŽì5F–%Š#ìCl^??­bœûàÙ\ÅÕ{ÐàzyÕ—‹Ù7ШSã0‚j *†H†÷  ‚[‚W0‚S0‚O *†H†÷   ‚î0‚ê0 *†H†÷  0€oÙm9ëC‚‚È/ûoNã0Uk-S°œ¥‘v÷)g«O3ëh•ë–K2àXûîKÆD^Wvÿ\®f¸â²Ò +üƒ+zXu6!(”/­Õõý˜².6|«‡k܃šfðåçäÝE©%.¥×ñ:¸~œ·‹Ý {ž-î6Û4Ž £*¡(ƒ;j2ÝëG -ï{ó! ˆXéPQÑå)‚¿ÒMФã`ïÔI÷qÉ#D· P²ÚØ©dÒ[”kîé)vh ®Kû†±Œ´p)ä! 5ÿ-ðš&Іí\ÊÐ7ù1ü¡å}œ­Ñ› NîUŽŒï`Ô(©I&Y‘©S>;ñ„Ÿdô¡¼‡Ò™¬Ø ¼g%m|$n|«ø`÷.å)ùÅ´"“ê|Åïñ8G½¬°´Æ\ÃÍÀË&tŒ™<óoóû©’y1*KÓø¦÷¸ ´éúGyU†Éûm’˜ðÕ8ŒDw“ ^ò²™‰Ð z¡!ßRidôØ F»:õ´GŸ‚´Ü_“§>³²0«$E¦™{ò5¡µ0—"Ü£Ÿ\ŠL(JåJ¶Xî`å0í«ÖÌŽÉVùS¯Ï—­w²Îýèî4ƒ0&äôá\Ò~dI\‰¤éUóRóØßÍ—!WëÇÊÊê§#‡”ô£åëF¶0Ë—Í™MÑ:q?Õ¬."ª3"iè‚7ø$k½Ó.¡åÜ2‘©É ¡› ÊþgB,?8—ÂUk‡”5«½ðëÂw„›]! Ðû¯Å¯W8¼Çròù@š£~½æ@·ŠxëγŸÕƒ. Žµä´Êw@¡Î°&ç !œDÇö·Ùèë|°mIÍlT0;ÂhÁkwÛŽÕtYš“<ó2L6k³Y$qЏ8ä§!4ëzv’{üUÝ£u¤tMðåÕžÚúî“ñ…ÓKâ¼qzcXÓ÷i*ŸÖ<ØFQ,/ÛÜiÝV$9¹J„¤'7Û´{[ œª›Àsês» ®ÑüÅÐ¥EŠ@Œ0ÒB ™ïÍ=ùM~úÛµµä‹·ÝLîW- Uì]Ì¡f¯ôà(ZÙc’•ƒ>{3y©8 ¤ž i×( ŸUŠXj•&‹ëRYå!÷ú½_ÄÌK^ Ú7±“Eeƒ9å߆]n>—ÙÐWBü °=ÍôÂÖŸ@ä¹ù¸¹D·çìKGT¨¬Ðš ûtCÔ“©½”]‰ÅkKÇBèû¬c) gÿ-È6åŒ 3Ï[CæŸÏùÚAŒæðz·ö¢ò•ÿšÉ5¸a@¥õ²òlÿ»·‡øk°Ù–'zn¥sÓ0å'z“H;æÔªú¾Îu}û8:Tð{k%d1“g:x»ÿ17ª\,‰Æ¯ª!M9Ò¥KI ŒÁbܱÅÀ^ ±¦¯P//6t˜±|ÀoÕX Š[;³IØ21‹ÿÓÓ¥ÖŸÍ¥¥Mn‰ x»g«ó…›èmÜèO&±Æ CËdØv¸Û1N0# *†H†÷  13‚%T·§‚·eƒ¢Ë=VtrÝ0' *†H†÷  1"testcase-F"010!0 +¼TÕ'´Ü‰Ñ±[6Ô2Ë*ôI©áZ€‚¨*R»ò}"Í'ï,mÔ­Šßeê0)³$•ÓÓFáÄjÛߎ/ÅiÏYÖÄf{'ŒŽ,!ó.p!}AÊÞÝu‡0d mkÖð‚†"x{/WWÝyL+4„Ž+r]ñçÏDfÿbKŒ Eª(j¶©Ï´9hpò½77~ð•3£ñÅÂ67î†a~)¦KY%~ž3d¤B²4t€mÔ"Ï„HÌ&l¼Ë‚¿¡›hÇÐ+¤ñ\Jzeÿ'&[ßM®Î‰!“¡ðdtÐbSŽeUOÑ/ãl³°Ù(èÅ£ûE0¹³{¦VG›?¯ú Ÿ_-Í­ ø…ãþ†‚nGGU¤ÑkΆ}|b\ÙQÄ`‹ºµDCÞÔbä;»@¾“X.©‚ɘ!þN.i½ûWpîÑÉ*Ò#ÚÏßCyÂþìé_‚xW)e‰Îß6˜ùá’Gˆë´Á®Ü(.–Á>7è,Ü>æ`n¸ÒõýaöP'9³Iÿ²…VûŸoï¡Ê ¶š ¶ßM"ž+—L_èQªb¼éêtW0d¡W,ÃÉ VSëpðh¬¶~2M˜Ó1ÓšÚÚ¿J°¦2Hw´Ú™MÄ4ýÕŠþ\§˜ŒÃ9˜<þÕ\­èœ\)Íô›ïH†HÄÕLLQ袊éµ=@¯]BÝ ðLA:y>gž§¶2”gÔÖ0ä;ÈŒAt¶pz<Ƥ^a[¼/O*§DrŸýCï9'Mò,|’ò#<’ŽC£  r½`¡ã*1…RhMñ•+ËÁ ‚ ÆðHÃtLxûÏsò®b›Ä¯N¶¯ÛI;KwT«ê U+#©£¯&~dö¹¢áÂÇFDàËBØÆLªG`÷~µJ®ïLÒþâ7#¨u”|àÆ%ü„€å|ûîm¡&ÙªCWÇža$ÍÔîV?^R¿H¢e^¸WmW“±;`{3^Œ\áài¯‚öZ^Ý/$ߤԭ´Ð~CJéË.u—àƒFçò>K“¢3ßÄÑ•œ HY V4KId0Ÿü¡÷}eÚPí´Ñ)> 7ÍV{¬ÛѳKÅ5É!ÃÊ€^:ùa™Ù´œ”æ?”ä'éùÊ‚å²W—Y1ºÕY:VÜc_ÆI²Óa/¢昲ÙÎ Žl28ò.©Nͧ û;¯ÃX¯]í:C¦Ÿ¾!ªÌÙë$è7…ÜÇ0øs-=T( ²);V]s§GK§_³øüJxVMaÏ=î»` z)Iõ(q ¿?u+éGD¤+ Ê@À‘¸@“_¯Ów–ÚjUVAå¡Bm@Pr“8öé[ð ¾ðrî¿‚îƒ1YÖ((!o‘RмhLcIu„ wš/˜d$¨¿¾{§à{AÓ0H'%Âx§ ËzG• =kÒåƒHèHá;æ[ÂǾQ‹:kìÞ Fúç ÏQj<š÷tJ°ù:­“F´‹²ÜG;–>p”sÝ>VÄ?èI vð½|ÚŸÖþ0îm´HdzÜØ»cƒX$(-´i<ަ´*Eå(* ¿øÀ˜kÖJ—{©Lá#0‚j *†H†÷  ‚[‚W0‚S0‚O *†H†÷   ‚î0‚ê0 *†H†÷  0]‹-h„þ Â‚ÈÓÑŒuGj"[Ö\Þ–3QÙIn[Uoþ»Œ¿ËMfyÜÂòkMÀA‹/ŒÀ Ã?©º‘ ¼¦(cé"õ°˜žOíìà ˆ$KŠÌ¿#Rju±"4¨J9TC ‚¶œqÈO™ŒAÎD› "÷’,6õÝÜx ~¢4ô %Jjô÷®?;¼óö\·uß’§Pÿ]Qñ{ûÝŽüÕAt¾òòñË– `×7§+ÉaÆÃiØ.âÀ£­uyÄ„¬%|$!¼©¾›Â¾æ{/®a\ø@‹hy¢}ƒ½Ñx.k÷o‘Ù9óþ•’µýúïƒçÙú¥-Öf\ý“hµriošZ¬‰×A¹u¸’4©û•ÌQ®KcÇç²Vaú!#ûRZ É›$a‚Ñ”¬ôp}бÛíz ™Ý€Z•Bçt †ã÷J»!úâ&þáµqäU¾I#B½ÏžòGÛ/`ÂD^ÉÕ8QltõŸREW…à4^ûN§Î8hfI·/x Ë),æØ÷DdðzùREJ”³¦‰nÿH²=|Á2Bïö±_¡ð­=ýC¡â/ éìÔê~uÝ`㟉W4*²‹Ýd{U^驚IKUlž3ó oóK‡ú3SQwox¥­°æçÕû@p–|ðmvL‘ Íáÿ7H¶0 K9™2']“Yª‘7- À»6•ƒ%l‹ìõÚ¦CÍÙdÆo”ø÷f¯_Ò]¹ºˆYÄn#˜zÄ8¬%LR[×4VÖ1ƒSÕoŠ<]…ÕŠ²^òßßì Ç<ñ]µU<¯GÁDü4åñËÒó·êói€Ðüõ–A‚÷2“žn°ßíãä‹¢‘c[ëË‘»TÄäåb äH~uˆ¨à —%e¥0¥7)Ð1N0# *†H†÷  1m©ôŒà{þûC* Az!€bj0' *†H†÷  1"testcase-J"010!0 +þbª¼4‡2*?íò{møÂå|Ëk·bouncycastle-1.49.orig/test/data/org/bouncycastle/jce/provider/test/rsa3/self-testcase-I.p120000644000175000017500000000526610503212005031276 0ustar ebourgebourg0‚ ²0‚ x *†H†÷  ‚ i‚ e0‚ a0‚ï *†H†÷  ‚à0‚Ü0‚Õ *†H†÷ 0 *†H†÷  0¨R³¯åÍ€‚¨qÊBòÚq“²M¼»×¾¦\ÖPQ­£¢Z;[g::fþD—Ê|MúÈg×cî¢s3`ìßÛçÄôÜÊš:rÀ'O.¬n½„­f–¹.z0©g Äã£øc´6ȈÌÉKt´‰®[ÙøÓ¶ÒxõÍÉA`;ÉU…ˆ@×ÞÏ å›5™Ãc"¸ŒËW€nFr³£_ï/òoí_ZžÌº2ÝdE ÅKIú,3\1¢‚@Ô%T¨äpºÁÌ”-˜ÄY WW+dm;OJ­Ê%¥ÃÁóhLHbû€lõßvA:ʼñG ‰"$ó¼”gfñ^m”©@zjb#7²­u˜4ײò $½„þ†»Yt¡“-¼´çÕÒœeÏÂdžzʳ!Ù°›9Uu^t税ÚMÿQ ®{8‚Ú£ú˜1ÇX`ëÏ ‰Ðrºk…gó‰ÚáõÊRAñWîa3‡ß3™tÈ\Ý …Õ/’e”QßÍRïTù,Þ;¤ó‰­(¦Œ—0 ¤É.®¸„-h¡òT[OŸnÑ"vK¶Î4ÀÈÎæsæÿ-ÞŽ@3eÞåõàcÞ‹m—·ü²±yºßP¼jyWÛߦ9eà˜‰]Y *ï7Z põ¬øª÷¼½ÁøÀ~×ÊÝ$ƒù~abr‘ÊAw£BÎOk+«Ÿ ”ï=g»ƒãNbõûÏ„:à­×RñËÅ9‘(†Ç5Á#ä‚XÀ‹¼ j AKƒýœm áD!» €à—j—~F¯(i³3t2ƒ»ñ69nÚ·×yï³ <ëøÜ Ùeî¥î@¿ ‘nš{å:Dw#0kªØ%D9 cfŽˆ|U#ÙkS× ËÏ¡GQ53òÙUO"Bª¸&‡þË2;xuE¹fûÅðârŒËátìi 7ðÍk5[Ë[ËTl6JŒ+ ûw€6•\ Ê0L¶öÃÛHÒ Œv'èŒû~]£¹ŸjË”x…c<è€Ø¦X§wèCŒ®L¿à‡ÔÓñExÛlïu‰ætñÝ[AûãÒ"›'\ß¾­§"8gäaï³×ó*ƒFsZj¼Ã|ó>ø0a…‰Ðh„¼wÓ ;øšñ<×í)þ6T² Ěˈª/´~V;†=„JSŽ*0/%ôÑDïwäê¯ ¡ ߟ`¢-OA¤—”›Whm`D®“`gdx }^ÔÁ<:‘é,‘È4^è]:.š°{¶%q—Å…cÆ oÙÞTêŽT]CìÇÿ·‘ÉbÖ9ùRà È?‘^üÔò :ˆž£ÖþÔGá-ëe˜ ”²†àãfIó­Ãve\¼ aš‡‘×®óÞ•–¢Y 4–A·¢Œ ~íÿQijŠDcÌCiÈ­û±!ägIµ˜÷0‚j *†H†÷  ‚[‚W0‚S0‚O *†H†÷   ‚î0‚ê0 *†H†÷  0"±Òp©GÝ‚Èoa5‹“”“¹ª ѽNâ÷%¾§=­R´YœPà«û7IT—)çËøL] ènâ… yVÏ…Æ»¥«+(þ’‘‹!ÎïÝsVU)^x›`Å^ª £¤®¼~&Iú^³©rb¸]_­5 /EO¿Ï·ÛÒ@OM|^ÆTšm©’^bÎ| ˆV_ÙŒc \e^oÏõ—¶nâk)…[®4ýp$eBüÑ7w‡Û‹êÍ?iÏg“½DK·ü±ïh…)”WyX7¬«`çù;àWWµ2=T¬$^Ú}Þ^ƒ…W½:`B ‡5Stg'‚„07å4leu‡9Sêlù ’ÒÙâàab°´©¾ ‚þÀ™YŠqR™­y®srê,Tžš\Ë0”‰*S¯KaÑQCXuJô×›æºE<¶­Ë)޳'“OHt<‹ Ñi„x‚5²Õ8ÊñÚtdXÿ^&\Ü»º‚ưèÿrÂ_K”’Ü?>p—E¸?EâÁÖ“oÇ™w ÈœÀ‚Yíøãœ÷;TÑ+qÐ3ҕΊ?샓–M˜qÿΔ‰ç–Ô9/²ÐÜEÞêsì ;ÑÍ4—¹ÙÏLÈé)‘Yæ 4Ù¦3üZ©œ¨Mòb@-mܨ¹'Çä ‘ÿVêO)EúVí_tÛ-y‹7&‘íæz,qïãö–Jqò %èåÈ…]˜ÿ^ƒ²/k™¸°ˆ…üƒ”Ç‚ír.¸žóNMO1ÊXDÞ|‘½ i)XkäŽqJ#x!5K±:~Œ‹v ¬#jÄò%Þ(™“RsLzBàc‹8W­Í€@ø ÜŒø¶> s–m®íÔ”/QÝžê@’ûã´·ñÅ›#f'^‰æTÏ@­-Ñ‚âŸAK\;I?=9qXÜË|­´•Û‹‘Ý~³ ¿Írà DT}KEMRï©&ŽP û¤JƒPú¾žÞt•Ú\®ç‘œû¾;?c”¼‹£­>2_ÀKiºtÃ|˜ÂYa}½&ùQÙH$| v£EòVŒKÍÃ6†?PˆدÙü)rFvóuŒÇ\d«f““¤%­`Mzi¢xzYçÒÞ” Ÿ™ðºÞ~ÍRpê8«¾,ôÛØ+¼0®ù[þ Jµ<ºXý§Õt=¹ƒhäåÍoôÇ0Á…ܲªˆsó¡ÖÖÇ>[ý_’Eh8UUǘ±Ú%v¾lQ³K¨vÐÝH¬`Lé8ë{0?î¿‚¥,~ˆêh…\ÇI1Q %ƦÇ6­‰ Gã>\öµï±3¨ )¸Úð‘¥·!+-AfWEµêx)€áý‹.nœ‡«×mr0ñüpÊrôƒ’¥Æ”˜)þùf©‹vržI²ì£J\|1N0# *†H†÷  1mÁntÐ7é"Û•¦!g)ƒ10' *†H†÷  1"testcase-I"010!0 +7 à©§BÀöù„›ðf “óõs[ãˆ=ˆ1žbouncycastle-1.49.orig/test/data/org/bouncycastle/jce/provider/test/rsa3/self-testcase-I.pem0000644000175000017500000000613410503212005031450 0ustar ebourgebourg-----BEGIN CERTIFICATE----- MIIEHTCCAwWgAwIBAgIBADANBgkqhkiG9w0BAQQFADBsMQswCQYDVQQGEwJHQjES MBAGA1UECBMJQmVya3NoaXJlMRAwDgYDVQQHEwdOZXdidXJ5MRcwFQYDVQQKEw5N eSBDb21wYW55IEx0ZDEKMAgGA1UECxMBYTESMBAGA1UEAxMJbG9jYWxob3N0MB4X DTA2MDkxMzE4MjYzMloXDTA3MDkxMzE4MjYzMlowbDELMAkGA1UEBhMCR0IxEjAQ BgNVBAgTCUJlcmtzaGlyZTEQMA4GA1UEBxMHTmV3YnVyeTEXMBUGA1UEChMOTXkg Q29tcGFueSBMdGQxCjAIBgNVBAsTAWExEjAQBgNVBAMTCWxvY2FsaG9zdDCCASIw DQYJKoZIhvcNAQEBBQADggEPADCCAQoCggEBAKtexL4ZP1CWMsVedm+pD2xPG+md VbRqkVSDQYxrHUyRVKletjluY95908bsAlJR9oK/YehXe9W7r+LnotaR+yy1P45g hSWa6TNl1sz3NGIZwdU9WdqdNNs9YyDgzFezxzZffrh9xFTSF0CR66Tm1VasKa20 69RTx4fE5n4kZx+DKfBGCX3PBprvIANZp0nrfuhf21ij9lORI9OkITwqR72PrybB 9QDZB+7og1jGLAGbRBNR61mLVfKrg2yJVhpk1dHPsUzeVr3BB5XK8i7DvflWw5di PeyU4S7qm7WLZ9Wdg1XOchkQWmzqEUPG71dGzG6joPhdp56LFg2Yg58myRcCAwEA AaOByTCBxjAdBgNVHQ4EFgQUPd6mAcGQZ8iNGajt0kffN4AeDZswgZYGA1UdIwSB jjCBi4AUPd6mAcGQZ8iNGajt0kffN4AeDZuhcKRuMGwxCzAJBgNVBAYTAkdCMRIw EAYDVQQIEwlCZXJrc2hpcmUxEDAOBgNVBAcTB05ld2J1cnkxFzAVBgNVBAoTDk15 IENvbXBhbnkgTHRkMQowCAYDVQQLEwFhMRIwEAYDVQQDEwlsb2NhbGhvc3SCAQAw DAYDVR0TBAUwAwEB/zANBgkqhkiG9w0BAQQFAAOCAQEAJanu4ytjXr/ppQEiEsJ3 1TqGBIoASHHWZsjd4DZmigBgERJqtXK/AsTsljFrSo1lhP3Q9TFqOeikvJ5T3y4q 8yYY5qaEICsjUuySTIT3r7O00O5mtpdnpsRkBceqvBDDqfWefau00SVoBaqmt2P+ Bq3x4l7MYqJNI8fPNVHqhSBlnWfxgYO/GZd4ZshhOZgrb96B98XpRlD5uYSlTpJt cYvSb2s+BX4RCZIGSpoQJ0dgz3uU5H5i949fbuTbyGLVka0t8gvWN0IPoSPEp3Zj mEw5Oz2UV0/R0qF2/yeKKNH3aFMEAzYUAmVqA5OdWiiZgLYcIm6pQvT0iAtgnT9x rQ== -----END CERTIFICATE----- -----BEGIN RSA PRIVATE KEY----- MIIEogIBAAKCAQEAq17Evhk/UJYyxV52b6kPbE8b6Z1VtGqRVINBjGsdTJFUqV62 OW5j3n3TxuwCUlH2gr9h6Fd71buv4uei1pH7LLU/jmCFJZrpM2XWzPc0YhnB1T1Z 2p002z1jIODMV7PHNl9+uH3EVNIXQJHrpObVVqwprbTr1FPHh8TmfiRnH4Mp8EYJ fc8Gmu8gA1mnSet+6F/bWKP2U5Ej06QhPCpHvY+vJsH1ANkH7uiDWMYsAZtEE1Hr WYtV8quDbIlWGmTV0c+xTN5WvcEHlcryLsO9+VbDl2I97JThLuqbtYtn1Z2DVc5y GRBabOoRQ8bvV0bMbqOg+F2nnosWDZiDnybJFwIDAQABAoIBAGA8GNn0DaUwo5RI htQPqVSWXENlklJ9od1G1FGJeWudFWEDietYfYbdPEcyE9+snXUxCkdSkX0mKBCR KdW7JsUlh2pp83t5scmmP+jcTbNlaX9ZM5Nbwun3YCp/cuExWQbEu8HZBp7nWB1v lFgHNPi2N7WPqvuSjLNGtHVT9gEwWGUl1zfbuZp8pNT4r1l7nwj+S9pGF3v5RXDt qZWSbfPF3ESPkMOpXxGk5uDLx3aoeHBQALVjeNdVlkyxjrG75Pv7ZnrmXjXzcuVv aVACiCPWxzaRFR9cRCx/Z34KrJorLglrfIPIrRMKJY33QO2gpYYEpFkLsLth/Ip4 NMSJ3KkCgYEA36skUOFK0iQcdEaUXR2zcvQd3P3ctxe0JqD7dHFWnY2ndA5+VvAP vUjemZgw+tNt1qjLCAwxMi4cEOEICG6zSlMBRcVbqkKPS3gd3fGvD/lfQZ02EePz 6KYVC7xz1WXIcId/HvkBNmbPEyOLqi9fIJQoYrM3LnB3AFIUqQ4K3UMCgYEAxCRT Z6yLGFb6Evkvvc6usqDhpAjWaaTSxlsSf9IGsKXW90OronB1IiTaWgJze1PrwWy4 z4YOSI8oEEpF7LdwI9hztg9wFGht8lahGkfHtgR7V/QzyLMYfcU/57STI9vvsw2S FNqIdeP1Bd/CE8iI6o6HOAadsWlTBBUBUtnZnZ0CgYA/ecthpL5eKt9kZE9gqbgu rHb5K5aC45g9yjvyjOO+7N+UATT7qT9eQZrizh1AYdZvMBIGo6cmjY1rgOGNuxTo x+u5iEv+YstV6K3ZOeiryOKutVYN97pV0SRx4zagXjVnMhzyhkpAzSaBUPom/zCp B0L618+WP1aWYbT5UUHmDwKBgA3Ju+86yuBgJN42lCuUnuVBt/rvABuXEZYOCuPf YMcEMXNaV3No0mMfEhZnu7R8tsL3IJq+Ar0JCzjx765vSrvKWIAA39EfcjMp8dNG HnzmHcGWEhnWtS8KMa7ZG8rWiCgfGRjML/GRn8TU8PCxFSbf9BN1K5qwG7zauSgY 1lplAoGAfl1Qw77H27TYGMVBgco/2g05MaKb8TZ4PKn1znlPnNcqFEBi779W0/dD Zgb1mjnRQkw68Jj5XA2zv/06yjvTS+nHVEDCdgIrZI2p1IrI3F4tihSoWgYtoe+8 5OVDiHQ73d6lxVLqIRoRic8ZtWR02PbrK5SmoPsFdeTcmtzqo6c= -----END RSA PRIVATE KEY----- bouncycastle-1.49.orig/test/data/org/bouncycastle/jce/provider/test/rsa3/self-testcase-G.p120000644000175000017500000000526610503212005031274 0ustar ebourgebourg0‚ ²0‚ x *†H†÷  ‚ i‚ e0‚ a0‚ï *†H†÷  ‚à0‚Ü0‚Õ *†H†÷ 0 *†H†÷  0,s’ ±%9Ì€‚¨µªÑ‰Ý½ŠBþÏÜ>åÅ´Ä[º)Çœ4¥¸ a:‘™.»®.U„w—:«Bƒðj²‘XªHÊÀ«·Ì(‘M1#â»è:pÇéªÀ›étBaÂSÒq±ô~KE¡EÝMr´”'(éaùýhEÄÓžÒRÔÝéî‰ý³ÄW+f@½Cd¨<™ûש#ûTõ ®á oå:_.wÔ*”ÜÒ"ÿ 'ö¡ðn~¿j4ŽÁ/Ÿàæòl^…¹ý¯*-ÂXÍšÀ~˜‚r²Ûv7Ô¢3„“ÆŽ¬þÍ]A­;n±ºÐ{* ˜†æœ®¦ŠT½[wn?tOê»N7'GÁ²°˜¼r…Øì°«?Üþ !#%à~q¬Ô7•ã烰žÓ–[HâÖJ–#\ˆÖ:‹ÐØË>Äœ³½=OðìÁ£íÓ·å.‚m°¡Ò _5b¦ñl§Í §!~)”ùyDº’× È¶pÆÌZ1—4 %Ä2ŽýD P`rí'~?­ËFö.;ÀŸ€Þ´ `JÆ¢¢ O+Ò„T{.ÑÒÓªÔƒ)c“L›5ßµ']Ÿ+8¦)ó8™ôC×!×Ý çå(\ZÇæM×õ¯~ò­†·³`i‹ƒ˜³Ô5´3²æ>•yºýU gÌ¡(ãN²º\¶_Ýø_é±Uº*zã\kî+Mt¦ ¹­›¯›U‰€XªŸ=^û eSb[ªLEÀifÝQõØ%‚Ï)¡ÆüBŒlvuÛ¨û@ñ³rW– Ÿ}Ít€k*vÇÒáíNîSúcòA\0i›¬~Nðx¾²h‹”ñ‚[[*™ÌŒ#iœðú½¸¡Yÿüú?r–{þ¿ß$›Àk@¶W« Ô sn(` ©±Û©Á%|zFó*´€(#FèӜѹ93üÙãÝbË»íµÓÌCö*oÝô7†5uIJm)Ùœ<=ƒØwÒ°,…ƒ¸dÈ•jI¢¾à»mDÛ bÌÛg^dø¡3G/^µðNÆrö¢ÆNÁŠ]½VdåxmB,4liÅ®0•h¯mê¯'Å­üoŸG+bÈÈIUa³ö­øæÒRDqÌ×6Oƒf -,K¯L1¶àOÏ!þú1K¼RŸÁã†eî/±‡:× ô>`È}ëqÑlö±±åS Š{Ö=ôÃZÜÜÜ/H¿"“.uGŸs›ÎI¼ 8m¡{¬‡/ÉgÔ‡[ø3žË@K&€Xa•(„€Î)6¸·;´Oy4Ñý¡ñÀš¥¸WøÏ<ƒ[àŸ‘HT´ÒMŠÿòÕ3|2ámË¢ÁvÁ.y†Ÿd»‹ã¦±!ß•û>û¼ÿYDåÕˆùXƒ±¤fýð&nÄwc7áàtG?GŠ\Éýú~±¦Ó…>Äã’ñI‡Ñô=,tª´D{RÜ’”f‹EQ&0 7ÓØ¥~,ËýjÕra.…!pÿçU¥Œ§ÒÔ.›÷±ø¬[§ñmF£JðÀõ‡¾`Êy§JIƒAZ™S2ĵb'Fõ´@^»ÞÁAEµC÷ž0‚j *†H†÷  ‚[‚W0‚S0‚O *†H†÷   ‚î0‚ê0 *†H†÷  0Àú³ûå‚ÈÜäê` [_utÜCÁ& ÞÝ‹àù Þ?ˆwì´FÅbÍ ”`ÝYõÌïõò¨þ¸øM¥)ˆ¡0Ð "E{®`ºšQŽSêÝO¦gIIßH¼¤ n­w‰§u Gõçc:#ô¨W,¼‰%šKî#}¡Œ Eÿþ?°6ç}“!‚8 T?òv¢[AÐ!Z6'À7k‰ìs&eˆÁ.ûü ƒòzòt(*úªPé? Ê7²îÃñÞ6™GF- øÒ½*/ ð"se?|½Æ•ëµ–Wé>·tªä9%ÄàgØmÌþ&’úÀv > ¶ºKàNmð2€?óM[F:W#¾tï;V¢:«òÂé3¦_À‰jÐ%¹’.ê¤ ^"R 1ô½CAC¤ÇgÄt,)ÜI9ið ^-ɨu=l…0;½…It”&iþ ³`uóã_ŽèáÐIÈoýqv ÎË­ˆ%ŠšKlþͺL'Ü Žš”-ÙíæWX,w†apTÒÄ\Ì :MÁúN øðú»3¾ÜŃ?Ä/9+ÙB͸Ö{8ÀÈZ8opá°¶ö5ÆþÒ­ŠõMhQÿÚd”q\W«ñã_Hõè´›fWž–²°¤$Þ#W`jÒäz0kßp`¥Ï²¿n Œš€F¨ðÂîG™”Ϭ×s=qD•¦9’<§žáÊ$«¿£ašÕ#[­CòL{W¶¢Cx5n1Ùk‚´U7Ks‚‰"1|V…”ä(®ÕÖŒr–<,«KØà‹(­WAfÑ^dÃëj(G6?§–=°TD>Ž|2aJ"óÌõ¶ÔméïG‰™â],9ì.í䘞ѣ1éœÁééÿ•Pdƒ–/‰ê‡1tf#eÛ¾¹·™°dÕ¨­9Ò—¶'ý3R1›ÔöõöG˜•<¯œé$µÑD¶ì´bîØ èaõ2Vµ×³¡)ûRî/`“|oÙÆˆ¸Èywv#צÏßèñŒññ»ÉÅåèÇ}­nQ5‡¡væ_6Ò%М¶Ó›ÈWt“ñ•³3a@2E»…EŒŸdEý׬q k¾$” 5‘TÉeëÚmµyNþŒû;»¹ îx¢è`—yÞSæˆfåÛ@ªKO} äÔ|¿ ò&ýoÅa˜ø'7Ë©&Y³,Ž[µ*Þy\u8®0 š«#Lˆ¯É”Ð%K¬y/Ûă2ÝP³mŒZ6S5Þ!=ÌJÇxÑû?É™ÿ´e­1N0# *†H†÷  1p4¡ãðßšÃc Ãߎ8àã0' *†H†÷  1"testcase-G"010!0 +{kŒÅÎàÄÚÇúüåÔ \/À3{ZBó¬D4Ñbouncycastle-1.49.orig/test/data/org/bouncycastle/jce/provider/test/rsa3/self-testcase-H.pem0000644000175000017500000000613410503212005031447 0ustar ebourgebourg-----BEGIN CERTIFICATE----- MIIEHTCCAwWgAwIBAgIBADANBgkqhkiG9w0BAQQFADBsMQswCQYDVQQGEwJHQjES MBAGA1UECBMJQmVya3NoaXJlMRAwDgYDVQQHEwdOZXdidXJ5MRcwFQYDVQQKEw5N eSBDb21wYW55IEx0ZDEKMAgGA1UECxMBYTESMBAGA1UEAxMJbG9jYWxob3N0MB4X DTA2MDkxMzE4MjYzMloXDTA3MDkxMzE4MjYzMlowbDELMAkGA1UEBhMCR0IxEjAQ BgNVBAgTCUJlcmtzaGlyZTEQMA4GA1UEBxMHTmV3YnVyeTEXMBUGA1UEChMOTXkg Q29tcGFueSBMdGQxCjAIBgNVBAsTAWExEjAQBgNVBAMTCWxvY2FsaG9zdDCCASIw DQYJKoZIhvcNAQEBBQADggEPADCCAQoCggEBAKtexL4ZP1CWMsVedm+pD2xPG+md VbRqkVSDQYxrHUyRVKletjluY95908bsAlJR9oK/YehXe9W7r+LnotaR+yy1P45g hSWa6TNl1sz3NGIZwdU9WdqdNNs9YyDgzFezxzZffrh9xFTSF0CR66Tm1VasKa20 69RTx4fE5n4kZx+DKfBGCX3PBprvIANZp0nrfuhf21ij9lORI9OkITwqR72PrybB 9QDZB+7og1jGLAGbRBNR61mLVfKrg2yJVhpk1dHPsUzeVr3BB5XK8i7DvflWw5di PeyU4S7qm7WLZ9Wdg1XOchkQWmzqEUPG71dGzG6joPhdp56LFg2Yg58myRcCAwEA AaOByTCBxjAdBgNVHQ4EFgQUPd6mAcGQZ8iNGajt0kffN4AeDZswgZYGA1UdIwSB jjCBi4AUPd6mAcGQZ8iNGajt0kffN4AeDZuhcKRuMGwxCzAJBgNVBAYTAkdCMRIw EAYDVQQIEwlCZXJrc2hpcmUxEDAOBgNVBAcTB05ld2J1cnkxFzAVBgNVBAoTDk15 IENvbXBhbnkgTHRkMQowCAYDVQQLEwFhMRIwEAYDVQQDEwlsb2NhbGhvc3SCAQAw DAYDVR0TBAUwAwEB/zANBgkqhkiG9w0BAQQFAAOCAQEAPaezAGexMlsmptKQBlrV iTDBKfTs555wM05d0CRzd6dq9GHYNk/BMPy0mPmpxLwuyQqjB3rw9+mlGre1jcLf Kthaz+Vna1yIGqg5dqqdu7NUX6/8x51hKQ+8B3rmlqx3wjt+bWgo2Qgl8otrHXKY EWrKfmTNd3z0+nklqaLFvxmQwQ33CKciw6k9A2O3DaOdf1smCfFyjF/hi4I0pJaX vFB/CbCAF/zVmQW+uXMNooZmd+DcKsK5ZN6LzxDXC6iqqaN0WS1kmctjYQ4pOomg 5pdKfv+gUwUqUTbtL2/WeyuOcHY9XLluYk+nwtdFS25uQpmHZcQ4baeKB5N9IJy8 jg== -----END CERTIFICATE----- -----BEGIN RSA PRIVATE KEY----- MIIEogIBAAKCAQEAq17Evhk/UJYyxV52b6kPbE8b6Z1VtGqRVINBjGsdTJFUqV62 OW5j3n3TxuwCUlH2gr9h6Fd71buv4uei1pH7LLU/jmCFJZrpM2XWzPc0YhnB1T1Z 2p002z1jIODMV7PHNl9+uH3EVNIXQJHrpObVVqwprbTr1FPHh8TmfiRnH4Mp8EYJ fc8Gmu8gA1mnSet+6F/bWKP2U5Ej06QhPCpHvY+vJsH1ANkH7uiDWMYsAZtEE1Hr WYtV8quDbIlWGmTV0c+xTN5WvcEHlcryLsO9+VbDl2I97JThLuqbtYtn1Z2DVc5y GRBabOoRQ8bvV0bMbqOg+F2nnosWDZiDnybJFwIDAQABAoIBAGA8GNn0DaUwo5RI htQPqVSWXENlklJ9od1G1FGJeWudFWEDietYfYbdPEcyE9+snXUxCkdSkX0mKBCR KdW7JsUlh2pp83t5scmmP+jcTbNlaX9ZM5Nbwun3YCp/cuExWQbEu8HZBp7nWB1v lFgHNPi2N7WPqvuSjLNGtHVT9gEwWGUl1zfbuZp8pNT4r1l7nwj+S9pGF3v5RXDt qZWSbfPF3ESPkMOpXxGk5uDLx3aoeHBQALVjeNdVlkyxjrG75Pv7ZnrmXjXzcuVv aVACiCPWxzaRFR9cRCx/Z34KrJorLglrfIPIrRMKJY33QO2gpYYEpFkLsLth/Ip4 NMSJ3KkCgYEA36skUOFK0iQcdEaUXR2zcvQd3P3ctxe0JqD7dHFWnY2ndA5+VvAP vUjemZgw+tNt1qjLCAwxMi4cEOEICG6zSlMBRcVbqkKPS3gd3fGvD/lfQZ02EePz 6KYVC7xz1WXIcId/HvkBNmbPEyOLqi9fIJQoYrM3LnB3AFIUqQ4K3UMCgYEAxCRT Z6yLGFb6Evkvvc6usqDhpAjWaaTSxlsSf9IGsKXW90OronB1IiTaWgJze1PrwWy4 z4YOSI8oEEpF7LdwI9hztg9wFGht8lahGkfHtgR7V/QzyLMYfcU/57STI9vvsw2S FNqIdeP1Bd/CE8iI6o6HOAadsWlTBBUBUtnZnZ0CgYA/ecthpL5eKt9kZE9gqbgu rHb5K5aC45g9yjvyjOO+7N+UATT7qT9eQZrizh1AYdZvMBIGo6cmjY1rgOGNuxTo x+u5iEv+YstV6K3ZOeiryOKutVYN97pV0SRx4zagXjVnMhzyhkpAzSaBUPom/zCp B0L618+WP1aWYbT5UUHmDwKBgA3Ju+86yuBgJN42lCuUnuVBt/rvABuXEZYOCuPf YMcEMXNaV3No0mMfEhZnu7R8tsL3IJq+Ar0JCzjx765vSrvKWIAA39EfcjMp8dNG HnzmHcGWEhnWtS8KMa7ZG8rWiCgfGRjML/GRn8TU8PCxFSbf9BN1K5qwG7zauSgY 1lplAoGAfl1Qw77H27TYGMVBgco/2g05MaKb8TZ4PKn1znlPnNcqFEBi779W0/dD Zgb1mjnRQkw68Jj5XA2zv/06yjvTS+nHVEDCdgIrZI2p1IrI3F4tihSoWgYtoe+8 5OVDiHQ73d6lxVLqIRoRic8ZtWR02PbrK5SmoPsFdeTcmtzqo6c= -----END RSA PRIVATE KEY----- bouncycastle-1.49.orig/test/data/org/bouncycastle/jce/provider/test/rsa3/self-testcase-D.p120000644000175000017500000000526610503212005031271 0ustar ebourgebourg0‚ ²0‚ x *†H†÷  ‚ i‚ e0‚ a0‚ï *†H†÷  ‚à0‚Ü0‚Õ *†H†÷ 0 *†H†÷  0uðBrÍ’^G€‚¨è°†õþžFTëÝb ‰>sg™вfFÓ&rç3è¥ÐÉpâЙiÁê?™Ú’Þ[@w‚GN‡:ÒÑ»6']-‰¼°•¢.ÌY[JjË%ãµ?ŒÒ($¼ë å5 ª1iºZŠ2âÌh˜ã.Ö½Åü¤VòZ=ü  ÌlvVÏpžó8™ž“ªì=©Ç ¦Ý§ˆÅ-—>'ÏCVvÙÆ‡8/¯®Á›<¤véUò€é­‡Îj‚ x KÒ»¤rI½1¤~LV+ÑöFHƒM͇35cï).äÝË7"hbk÷º ‚Ä´viTÝ)Q£>µ&­½Ñaˆ·?ÑH±:¯ yÛ Fñ¹ó{¬K«ÿYŸ{PMl¦¦ !ƒù‚c ´šlè!aYÈ%…­JÓj#gá™ÉÓ/J?Ù9’³Þ·ôŸÿL:%?ôN³E¶h-\<eϹb4_Üá#±æ4¨›Ñ&µmçk[דß 6e¿±TdJm}ú”ßÑ^’Ҕʕ³ÉwzÈW/wJZæÙXОMòdÒÛê» ÑãrË+¡t¦(ÄW"8/]lo:`táQ,sÔ°Xs+Θ%“­Qqcü𻼙:KÂÆœ0Ѧíá ¢x⳸A‡H.£ÎÏׄ›zÏѺŽí5Ë ·:êÍj€ ]ɇÁ¯áÄ@‰”ÖÁ™+ú,[Ÿü…]^ÕñÿÃ'ÿɱ1…ªÜl,.á˜ïµBÄ—)W\rˆM±«­J7~å°»í-UõµÝt²ÓºêD}ù ’ØáÍWXÂïÒšïPNŒêïƒl¨£:Š(‹Y¦ZϯÖKht»!ŽzîŸoAwpÖƒù%Ã@†fœÅAöŒÏO:Ô­ÏÔ;œ"Þó;÷xÔÏ9ÎLHsÞOb< ›’y©Èé}ÊOØaXjŸòÑtòœšoQå–çA¡áæëz7¼EH¹/<ŒúÈÏ›©D¤*Æ•r@Ï ;ŸÓÈJÝÏòÚçjTè¦ÊÍÝ¥ rC1Ö%ø.eOȕג,¤œå¦ä›AÔ ¢‚Ž)w8è—€µùCë(Ÿwr„Á4°É ‰±kË/Ÿ›ìà|âË–@_Ö%êÉ´×íZ9ÛÍf‡ Å ø¦jXdËj*œ¨5Ä'oál…´žßÅLI\ŒÝÃðc4Ž”Q˽ºFÂ|j‚!„úãÔR‚¿ŠåÞT…¦^iœ°B~Ò-˜¥\ÎÀËØ’XY×+Ô2é@~“J‹Q°ÃîzœqôÜ?ç·,ÆvÞyð\åcUOWÇ7…i<ÿ¹d ¯ZAiÁnê¡W0–Q¾X´f6èãÎy5J_DÃD2Älª½P ²•õóæÉ ÇT ”TÑõ›ˆÈ3-#Av¢&}[Ò$V”¦ÃÒßLüÐj0‚j *†H†÷  ‚[‚W0‚S0‚O *†H†÷   ‚î0‚ê0 *†H†÷  0xµkÔñ‚ÈÆ6ÚWõ*üB^«N¢|á½Za ÷žZ0Aî7±±ï ùÒÚ½[t× ¹–gø­s°ã%˜Š  Ç¤\owoºƒ¥fRjÅÜ?¸‡!Àññv W%@xQÿ5YÁD [;&ïLù°T rm¯¼éž õBc°ËiŽJÊ<}7§‘ˆ›*ìå¢q*ôç¹5ªÂ™j!aµ'ý嘸±? FÛ6qêó™D½û_¶çãÒb»Þ$æS‘ñ'7†»muåjÿ~Sb€àyq£ÁµÒ;‘%[̼ڢñË®¦òc»8– ‡ ¦^¼\™ª6,EòIv"ø‡=ð,™ƒ’õPfzyœÓ–>®¹¡ˆà/ä¬ëØ«þGi™„E„/6Ñ´N f¡~|"<ìú/ O²xZmç^n‘‘$òØ**|M]j…=Ñ'÷«–@s¥aZ÷ID:cÐ2:Lj†[ÈñÞмPQÅ´-Mi‰*Ôþ“jÄõNtiúÚy²kžƒ\3~¾›E Ô6¢)=Þ]x3C\`ÿT©6€+Zê—+¢ƒÒ¯É|*)P#ã_±Õ¤¦™«f<5â”@­5ׇ µyv’@#ôìq‘{]Å"¡Î¾?öÏúl7^Õœ(@‚-Ž÷{‘Þ©iÀB7ŒÅ>€ðX*rÑWGÿã™AâÿÌÿ 0¼wê„«²Ð5Ï æfOr5?˜‘AÀ6oòF“Řӷ²½+S€A?ž=¥‚޾Ús>¶p!h­˜#-B0ñWv-¯€wÈv[fá¶ŽÈň,iø>I( ·Û%}+ú*Ù{Šž¢O‡ åÚl&¬Ê›Âc}EµTdJ¹6á­ “7À²´mû[ºÛSK…L7ž©«à åRÙ€Ú3Þ£ ¼j2oé³qÕ`{ÆÛC^þ¸LñPi$Ý–®£8p-òQÒÓËR³¯ ü÷"²„“h©3ùb}ý3Áõ¥Ì=K+g)ŸI‹dìDµÎ€··îMr$ì׈§à¬}ã‹Ôv7€Ï¿ö'b¥~£ÿ=Âp”vÿF@%õ˜Äjnû‡ó%ìƒËB3‰0ÿy¦;tuX ÙÂAºÝÒ÷Œaš(gu¼u\–÷ñ<û~>ÂuÕ0k<ÙY†›åÒÚÒ× l'Ø„ÅÏmPÕ^€tÎiÿ}ûxÿZÅÝBÉn&ììÚn ¯{ûd{è‚£Øö lÉ›®«úÌMîê«\?(p'ÃÓp³6‚®ñ ò‘¾€‘¥ÝÏ3EßÝæ®Úà¢dZX«ã±»WÊÁà zsü0¢Aácä˜}Òuâî¹;Úðy2³¶Ù„ÎÀ¼³[¡>œ‘˜Hκ¸ —wžd˜sÙ–lœä¥4ŸÌQß/~‘§@ªS½áIYbÐåÈuíT)Ëi¶]tÕë|ú‹H^Ç'©„k"?¿Ãï!¿/ÈæÖÔêë`féà辑Ù>UéŸoöÑÅ ”;L4WÉÊgŒ´øB)þÁ£-ýËåy!ûƒ•ÎQ t¶²Bé;öÃ1Úeî¹ã$îG¹aç!…F¼´Ö>$í´ù¦R1ÑR+Þí1N0# *†H†÷  1[4r½?ãé?‰í¡Pï´2È0' *†H†÷  1"testcase-D"010!0 +þyc+>P¬Àƒ ÷œ3Ì=r(DK½usbouncycastle-1.49.orig/test/data/org/bouncycastle/jce/provider/test/rsa3/self-testcase-F.pem0000644000175000017500000000613410503212005031445 0ustar ebourgebourg-----BEGIN CERTIFICATE----- MIIEHTCCAwWgAwIBAgIBADANBgkqhkiG9w0BAQQFADBsMQswCQYDVQQGEwJHQjES MBAGA1UECBMJQmVya3NoaXJlMRAwDgYDVQQHEwdOZXdidXJ5MRcwFQYDVQQKEw5N eSBDb21wYW55IEx0ZDEKMAgGA1UECxMBYTESMBAGA1UEAxMJbG9jYWxob3N0MB4X DTA2MDkxMzE4MjYzMloXDTA3MDkxMzE4MjYzMlowbDELMAkGA1UEBhMCR0IxEjAQ BgNVBAgTCUJlcmtzaGlyZTEQMA4GA1UEBxMHTmV3YnVyeTEXMBUGA1UEChMOTXkg Q29tcGFueSBMdGQxCjAIBgNVBAsTAWExEjAQBgNVBAMTCWxvY2FsaG9zdDCCASIw DQYJKoZIhvcNAQEBBQADggEPADCCAQoCggEBAKtexL4ZP1CWMsVedm+pD2xPG+md VbRqkVSDQYxrHUyRVKletjluY95908bsAlJR9oK/YehXe9W7r+LnotaR+yy1P45g hSWa6TNl1sz3NGIZwdU9WdqdNNs9YyDgzFezxzZffrh9xFTSF0CR66Tm1VasKa20 69RTx4fE5n4kZx+DKfBGCX3PBprvIANZp0nrfuhf21ij9lORI9OkITwqR72PrybB 9QDZB+7og1jGLAGbRBNR61mLVfKrg2yJVhpk1dHPsUzeVr3BB5XK8i7DvflWw5di PeyU4S7qm7WLZ9Wdg1XOchkQWmzqEUPG71dGzG6joPhdp56LFg2Yg58myRcCAwEA AaOByTCBxjAdBgNVHQ4EFgQUPd6mAcGQZ8iNGajt0kffN4AeDZswgZYGA1UdIwSB jjCBi4AUPd6mAcGQZ8iNGajt0kffN4AeDZuhcKRuMGwxCzAJBgNVBAYTAkdCMRIw EAYDVQQIEwlCZXJrc2hpcmUxEDAOBgNVBAcTB05ld2J1cnkxFzAVBgNVBAoTDk15 IENvbXBhbnkgTHRkMQowCAYDVQQLEwFhMRIwEAYDVQQDEwlsb2NhbGhvc3SCAQAw DAYDVR0TBAUwAwEB/zANBgkqhkiG9w0BAQQFAAOCAQEAaiR5Rnhj/vUqDgVqHaJk 0VcMuvDzkQVmUlAZlsDa3uH3CW43yAXXM6ahacYnOgpLB96aq6cI8E74hHzO6PU6 M50LLdp+KWu5InQv7+6fgSpShRxnHBKigCuoLy6oKFkCTTnnK002Mplr8+eHZHbi clm+k9rQejNalv+P9GSE5JcIEkTSXUDbfe81/ej9DCOcGbFPuL5hFQ8GNIuf+uv2 OKXQtdpuayFZnD3hoWYE1LMT5W1lK1Jewx03phYeCMAY+MibRhzXWLDMBiwXpvW8 cgCv777p+tRedunb5eLF+FT+/r617rskD9i9mJjqvoxQaXaYe++UX5mt9xpXZ9oM 1g== -----END CERTIFICATE----- -----BEGIN RSA PRIVATE KEY----- MIIEogIBAAKCAQEAq17Evhk/UJYyxV52b6kPbE8b6Z1VtGqRVINBjGsdTJFUqV62 OW5j3n3TxuwCUlH2gr9h6Fd71buv4uei1pH7LLU/jmCFJZrpM2XWzPc0YhnB1T1Z 2p002z1jIODMV7PHNl9+uH3EVNIXQJHrpObVVqwprbTr1FPHh8TmfiRnH4Mp8EYJ fc8Gmu8gA1mnSet+6F/bWKP2U5Ej06QhPCpHvY+vJsH1ANkH7uiDWMYsAZtEE1Hr WYtV8quDbIlWGmTV0c+xTN5WvcEHlcryLsO9+VbDl2I97JThLuqbtYtn1Z2DVc5y GRBabOoRQ8bvV0bMbqOg+F2nnosWDZiDnybJFwIDAQABAoIBAGA8GNn0DaUwo5RI htQPqVSWXENlklJ9od1G1FGJeWudFWEDietYfYbdPEcyE9+snXUxCkdSkX0mKBCR KdW7JsUlh2pp83t5scmmP+jcTbNlaX9ZM5Nbwun3YCp/cuExWQbEu8HZBp7nWB1v lFgHNPi2N7WPqvuSjLNGtHVT9gEwWGUl1zfbuZp8pNT4r1l7nwj+S9pGF3v5RXDt qZWSbfPF3ESPkMOpXxGk5uDLx3aoeHBQALVjeNdVlkyxjrG75Pv7ZnrmXjXzcuVv aVACiCPWxzaRFR9cRCx/Z34KrJorLglrfIPIrRMKJY33QO2gpYYEpFkLsLth/Ip4 NMSJ3KkCgYEA36skUOFK0iQcdEaUXR2zcvQd3P3ctxe0JqD7dHFWnY2ndA5+VvAP vUjemZgw+tNt1qjLCAwxMi4cEOEICG6zSlMBRcVbqkKPS3gd3fGvD/lfQZ02EePz 6KYVC7xz1WXIcId/HvkBNmbPEyOLqi9fIJQoYrM3LnB3AFIUqQ4K3UMCgYEAxCRT Z6yLGFb6Evkvvc6usqDhpAjWaaTSxlsSf9IGsKXW90OronB1IiTaWgJze1PrwWy4 z4YOSI8oEEpF7LdwI9hztg9wFGht8lahGkfHtgR7V/QzyLMYfcU/57STI9vvsw2S FNqIdeP1Bd/CE8iI6o6HOAadsWlTBBUBUtnZnZ0CgYA/ecthpL5eKt9kZE9gqbgu rHb5K5aC45g9yjvyjOO+7N+UATT7qT9eQZrizh1AYdZvMBIGo6cmjY1rgOGNuxTo x+u5iEv+YstV6K3ZOeiryOKutVYN97pV0SRx4zagXjVnMhzyhkpAzSaBUPom/zCp B0L618+WP1aWYbT5UUHmDwKBgA3Ju+86yuBgJN42lCuUnuVBt/rvABuXEZYOCuPf YMcEMXNaV3No0mMfEhZnu7R8tsL3IJq+Ar0JCzjx765vSrvKWIAA39EfcjMp8dNG HnzmHcGWEhnWtS8KMa7ZG8rWiCgfGRjML/GRn8TU8PCxFSbf9BN1K5qwG7zauSgY 1lplAoGAfl1Qw77H27TYGMVBgco/2g05MaKb8TZ4PKn1znlPnNcqFEBi779W0/dD Zgb1mjnRQkw68Jj5XA2zv/06yjvTS+nHVEDCdgIrZI2p1IrI3F4tihSoWgYtoe+8 5OVDiHQ73d6lxVLqIRoRic8ZtWR02PbrK5SmoPsFdeTcmtzqo6c= -----END RSA PRIVATE KEY----- bouncycastle-1.49.orig/test/data/org/bouncycastle/jce/provider/test/rsa3/self-testcase-B.p120000644000175000017500000000526610503212005031267 0ustar ebourgebourg0‚ ²0‚ x *†H†÷  ‚ i‚ e0‚ a0‚ï *†H†÷  ‚à0‚Ü0‚Õ *†H†÷ 0 *†H†÷  0žIþ±Rw t€‚¨“Î-ŽäÎþÖûÖ.­©µ ­Û:¦ ¼)«y©3G4íÌ.ëq)bfd×Ò1˜êQšâqA—]‰1m‘Vç= Ðöiô¬ßχóŽs©h”–ÂëîR",W›-Ã'jF3%Ø5‡òUá*”oASôŽ_ûJ 6ðT{…÷aÓïVÚûëÉê]âl4Aï•ît%U‰îKû-ýÇ^ñŸsŽ(y^[!£è{>Jù5ZðBJžøSêgnw÷þà߸L˜ÊR]k¨ò¦žÂÛá Ϻô¸Ëh÷Ã*bÛÿêX‡fkÛ°6ÿ csÛl¿Ê¬qì¶æA‡''æ¢qEÙ~dy0wO:A²^Õ8Åo}@²Ñ¬YÏo'NBâÞ™ê<'ÂãvÛ¥[£aÖIJïԨܭ—w5î ›±òS ‰~!í7 >ì£M«f°;z"m³ƒTÞÛ—{mÒ9å–g! Ö€§Õ_B†»‘Ô"ÜCØ~zñ₃¥”]»Ú€rP&ýxÝÍÊœÄʧ%“×[û™õ Ñ3àxí¡±1¼÷ÛÑ S×V"ßoía2;ƒº«;sQÖѧÌ#ˆFÜ¥ÇÞ©› ¾ÖµÌ>dÙÓÕ_0T*ÙP~Ã™Ž¾rF÷pØÒ¼'š¥‹Ç„{YibûòÒÒ…þ#ž … ¯Ü] X2Œ5ÀâhùÑärö@‘–öã¹·Y@^$ØîMÐÔà3ú¾yÊv¹u×K»Sa­·«üxïî !&göäJWê ¾@nÊç„ËÖBw;(:¥YÌ@-àç$Œ¯LéòÈ×UÏ¢–z¼1xCW7Æîò…’(¹Îki¾Iò}®iK{Í O·:Æ}„“72½|Äy€]nˆ8Ô´ÜApm6XëÖðÞd.ìİ|éXƒ³H½†Íé÷xs¥kY0´¡¾ˆlW–+c¥´È\šÓ[-Db@À4Óødór„óY¬4ny(2¢+d¿³Œ°AzMºiXúzŒËv„+ooƒzö‰“ßF}àLýWÒùÖ+Vü¦– NM,c2­ ¢J‡Œ ¶-Ô}]Žs~̱̺{p óÐS†ì2w««ëšÂ2ù‰OˆxÛ‹6ìnÅÄ-Pï’v½ÒèùÃþ9[åÖñóT ê…iÂ=_fïÀjÐ2»(5?¿Ké—¥2’CêM\jªŠ‘˜‹„™nž¡k_¹zÒR”Š2Jamfµ‚¬1Î ’ßów8d‰i¯y?ø·ÿq*}mÙ3¨Ðl©'·~ñk 4ÓÜ¥µYƒQ.Gª@Éå²ß‹êP •ßIbŒ@ ‘î8îòpÄÕ¯ÿ°ŸcIÙzký&eÉ6L»¯¯ãú—ΨY©Üô8ã½£šªlóH<üá§æ 1ª‚äz» ½Ã¬¦!t‰iØùiæ­©{•­%á±Ý ]ô¶´ò… f=ØB“ ÿÌnÐ] “<=#€¢RYú˜.–xÝË5Á¥3ëDÌ0àg´#p„ï炳â®ïÞWZÑ)Á ¬œá:r÷/ ¥~˜« ­¯Èç܃°ç‚¦»2\h¤Ýÿ2è.k(”ü kx}6`%v£àû#ìpð®1J….ÿeMÙkŽ÷s5v;JFõË7þ}Áý²yy'»©3ܘ­Åšd¯9‘B/jÑG^Òw9]&A~~<Æ\E¤ì~ü±æ¯ÄÃä?ê2¡ò]Å\á…“P±Û7!<µ²(O3辇;n[] .šõk.žNeÕ?мúøÙøÆªDÏQ»éSQ ^a3 €ñÜ4ùØ™ t¾G+êŽú$q9.Þ-ê…Nzœ;kÐ<#=À“ا “mnÊÓû‹éÆ8ÏKTEõÔãØï¿EB[ª!•]eU¿jMf—.óŸÕHì¡3?YlõmŠêUÿcß‚‘ã‘@æröÖ¸o%Ú4ìd—èO:( àTc‹ø¹ÁL@rx;&ίuîð³XÈSþä˜Ð8”œ2õ– å¾l¡TJMØìºµÏæàÝažáRVE—º1KDµ%•ê§ÉBý‹6×(}/´ ÒåS#ï…Vþ×f)·àEé)^E$l¢¶À—œ‰eŒÉ5]UÝÑÃ]$í¼~ÆÇ”ü)j¾x>óóòF KZ.SQËä¹(ÏÜìãƒ?¶G† ™®~Öáo:W~Awû.úÜò¡û5k¼·ŸŠtÀ{¥8ÎÄz-åÇY¦AD6%ù¶ÿkh»WŠKl6éõº÷Aõ±i‰2MºßÐÑÔº¶Îy|{î{©®Ùk àSÝä&îÒß_*ѾEH%?Ð0º—31N0# *†H†÷  1Î骻HÎùÔÊ.%/âò¿XF0' *†H†÷  1"testcase-B"010!0 +_¥™[]³lŠÔa‰¨ÿ<¿›$<‡žòo"”5¾DWž|ƒ^Ê\‘âÉ „Š;ÿß­â|2…”ßÿ·å;,Íë@ÔðÈ“_rJs d]ŸðW fOiÑ_ÁtG›Ôƒ/ŒSøä¦S¹÷ˆ/£ J( ½,Ÿ7ª•ßo¼-uŽÆ™ð[*ê!MŽ…IÞ»ãÛ'’+-ÑÞÙŠ9ïÁ”o]ƒg~cCRuU–¦0ôw?>¼iiìl<â Nkf\/^œ¬a/»­,§Iż;ý2ð´Þ陥æU8í·Cõ=rá,òÕ}y¥Ä~YL „ÅÇÊòÕèC{þ\åOX(%IÓì»áXH‚œRc$nÛ{¯þw©ÙŽ@ðòðôÏzÕQÁ•bÔ†jG‡#U®ÆèÂŽ£dð‹¼VFùY^Vʵ8tF=‰ÝQ~‡Aý)†]Á~‚EŽåÀ)¬¦v7hÉÓ›.‰Ìó©9õ’ÏØöžaãÏ}Å:s€¥ZÇñêìæOET ™ÍîúÛUõRìt ¯Î|Ì»ÊÙAn(œ®P{ŠŽñG#‘®¡pHQ)‹i³¾Ræó‚«ye!©›<¼hÿ«ü“›w<yÎÑ)¥äKÏx“èv~þyŸôßÊ CBÁl…¿€îjËë®í_¹Ÿþy;£¿ 1KЕ=¬ É]úu‡\ùÈÕ8æÆà_Þ ôÒJÄaÿóA6²Mm~¾÷œ~›*Ó—4±{,[‡í°Ò´¢'ƒáWå»wõ'2«®Nœ_OÆýç+3R‹çdÏ9r3sµ:@s.ë¬,ÕÑÆÂÈl¼°X9Ä>>“—d 3L{uaç/@ùƒÅ= Û°èÖ­©s© }ÊIT%cIìÊ%uåïŸ \5ÚÔÑ,ñ4¨lô@®Û ²Ñ ’0/‹ªP™ÔЇ\^˜òÅ$û=\_EÐt—w˼4¯›ý–EÖk¹hr>§ÂœIO_檶?]úW]—W¤ž·ë …ï1Ò9¥+Cqq »oÖr*ë9Ž×5¥gÕ×—oºá,d’7šGOˆ H†õLð`•ž£ó×SrT5p›‡¦’¬yôþŠoÓ*DÊQÖ5š¤cŸÚVM«A œ9½¶SP¥ŽïºÁqÒ±Ö16 4d©8•ÝÀç-Û)3¯Fl‘LN¤Ç#æÇ¯=¤E{4},ßK0èüL#•?¬Ø.^àÍ()D¯«fÓSæš)þ­[$~ÑŒÊMèyù*¡rHXbsëk®ÅßLÑ[F•ç–ƒ`:ÝRàg™X온¥ºøËOH\[ûÒëød§}© á¦ÊcQ>0‚j *†H†÷  ‚[‚W0‚S0‚O *†H†÷   ‚î0‚ê0 *†H†÷  0úö™,  ¥‚ÈËŽÏðû»¾nˆ{šú¾¦YlW"JEpNz€«–3ä¨äê£-à ¶ËñM,8¤NcÁQGK|ÿ^±¡~9öJB¦l.ÚŠ>ü09™óä7û…CdA²É¬¼©È?™ÀôËgÊdŸö=Ù‘ Nâtãv3í÷/ådKÅœ$‘ei¬BÏM ÀÓ-Qv-i¦’:HJËžM÷®¼VìÌB„iæ§hí½(8…{Ôç±L!Í3´®&+bÔèpÞ!'d”â¤% 4± …a2½\l1УOÕ¦©î"lÒf‰ÅÌh´zØ< ‘Òp+y¡,ãçÊ—qö>åÖxc2¤Î?ÁF5Öv(}ŒF³~…³SAÇ^šç…¦‘²µ©àDæ}%$:ûÁ%€àüw·q*¤ΓJ*T6nüj.ÇÇ?Έ•JÔ%ŸMËoâ4 ¡'xüC(º™¿¢]áã±ÈiÝ™án=Û.êÇ'Aʸ;EgªÓèrA¸½;eÔ’íÈ$¥-hbÛ!ì‚_±‰ÖÄԞųíjl•ÑnÅæ ƒÎ|0ÌÜt•“Ø€¦SîèP{HwÈ 4xQPÜNÌÚÈB .ïÿ£h^Ê"YãÿkŒÀÉ®'öÙ–’…üÕ;$ºÒÀž(MÖmÒ ¬ÀÑ®z\˜)ºÓdF¤Vp9¶bíã†3ªŒXíÚÉ?ÌvÂŽ‡z‚á¡ÚIjÚjÔgfÎ.¬þçÝ•VaþY=0p‹XÊ Ù²H6I²FŸ֘Zï|Ög5ßãŸ~;ßKð›È9¦¡Àƒâ‡'IË}¾s+fl,Bçb©>†4Ïàª-˜µ’Ù¶JH^!QÁlì{º5ÊäÂìVÚ»(ƒxeû«wê¸ÖEö¸0]B…›—o 3‡Ñ~Fƒv¹]µU2–oVr€XC8>!¬·0%4˜N©‡ºJ½‹“ŸaÏÂý–ßõ&ýú缩ˆ:ùþÁTåcƭοœeÃ%eí 3GoÄ~EÈš£y¹÷KIS¿¢ãÈa {$µA”ôùxõ…ˆñ·/÷MâŽhÖ§wî6›h‘ß·Î6ñžÝ”8˜£%Ê•„_yÉ”nv ëG®¿ržJj³ô½+Í^ (‘‹ßXA»ûa.zhÖŒC •ò"tö´Y>>·«Ýõ—W{ÊH Rã’‹ý>††ü'ܸß×ÉÀÄyø>)a@n6¼‹¢¡%Å+i¤Ü,©ÃS)L7¬e|_寣™Yr¬¦;!=в¡CMöIÙ¸;ž¼²Ð ¬G~¢†ýˆ jÿ媟“• ÊH"7tªºÛPî’½YXÏ™ôQÁ`A…hPé#ãßþíú±9¿º"îjìîN('V€$xÉ`ºü ×,çÁã̯Ίžwëäß×͵ã=u·ç’ÐK?ßû)…Rü‹à/#«êºÎÿd¢N{5øÒ„€Ix·q(Ô¬d='´ °¯Î& K1N­÷y™«”(G-jGܶ½·¬'†D暑k.¶®‰’µÞ|B÷Â5à˜ÇýÒèÙ¶þTƒ°™—=„>1N0# *†H†÷  1ºÃ<áYM­XË1*'êwo$h0' *†H†÷  1"testcase-A"010!0 +YÚ»u=Ýûý y…E2ŸûkVÆ9rbouncycastle-1.49.orig/test/data/org/bouncycastle/jce/provider/test/rsa3/self-testcase-D.pem0000644000175000017500000000613410503212005031443 0ustar ebourgebourg-----BEGIN CERTIFICATE----- MIIEHTCCAwWgAwIBAgIBADANBgkqhkiG9w0BAQQFADBsMQswCQYDVQQGEwJHQjES MBAGA1UECBMJQmVya3NoaXJlMRAwDgYDVQQHEwdOZXdidXJ5MRcwFQYDVQQKEw5N eSBDb21wYW55IEx0ZDEKMAgGA1UECxMBYTESMBAGA1UEAxMJbG9jYWxob3N0MB4X DTA2MDkxMzE4MjYzMloXDTA3MDkxMzE4MjYzMlowbDELMAkGA1UEBhMCR0IxEjAQ BgNVBAgTCUJlcmtzaGlyZTEQMA4GA1UEBxMHTmV3YnVyeTEXMBUGA1UEChMOTXkg Q29tcGFueSBMdGQxCjAIBgNVBAsTAWExEjAQBgNVBAMTCWxvY2FsaG9zdDCCASIw DQYJKoZIhvcNAQEBBQADggEPADCCAQoCggEBAKtexL4ZP1CWMsVedm+pD2xPG+md VbRqkVSDQYxrHUyRVKletjluY95908bsAlJR9oK/YehXe9W7r+LnotaR+yy1P45g hSWa6TNl1sz3NGIZwdU9WdqdNNs9YyDgzFezxzZffrh9xFTSF0CR66Tm1VasKa20 69RTx4fE5n4kZx+DKfBGCX3PBprvIANZp0nrfuhf21ij9lORI9OkITwqR72PrybB 9QDZB+7og1jGLAGbRBNR61mLVfKrg2yJVhpk1dHPsUzeVr3BB5XK8i7DvflWw5di PeyU4S7qm7WLZ9Wdg1XOchkQWmzqEUPG71dGzG6joPhdp56LFg2Yg58myRcCAwEA AaOByTCBxjAdBgNVHQ4EFgQUPd6mAcGQZ8iNGajt0kffN4AeDZswgZYGA1UdIwSB jjCBi4AUPd6mAcGQZ8iNGajt0kffN4AeDZuhcKRuMGwxCzAJBgNVBAYTAkdCMRIw EAYDVQQIEwlCZXJrc2hpcmUxEDAOBgNVBAcTB05ld2J1cnkxFzAVBgNVBAoTDk15 IENvbXBhbnkgTHRkMQowCAYDVQQLEwFhMRIwEAYDVQQDEwlsb2NhbGhvc3SCAQAw DAYDVR0TBAUwAwEB/zANBgkqhkiG9w0BAQQFAAOCAQEAkSFw/c7vnAAs4wKzS24X oyJrIiazcZD4A2ioqWMQD+QxFJlplJsyE5vcyVxv5Pww5Od1aPJCsSEd/C7h12eA 576kkQcbv5KQ8LUlpj6eRjzI4E97yc9Yi9C3YibniGCv5mxLpw2bOxix9l8EBj6h vTfDMdoQVXkGyI2TCbYppkffJgxrL/wj82XbYeIHL27REf4+bNVRYD3LMXl7koPc 4vUC6lyxYUELfv6UnAzppqDl+LSUkKvQEe26syIUAE3ArGvy/aYjIYBCwQQu4r9H WnXdIvcTdZqi3x9z/aN8Or9/IYIXpk3td6lLqI/DUwkPRS6zcthDo3x/1IFhUCB3 KQ== -----END CERTIFICATE----- -----BEGIN RSA PRIVATE KEY----- MIIEogIBAAKCAQEAq17Evhk/UJYyxV52b6kPbE8b6Z1VtGqRVINBjGsdTJFUqV62 OW5j3n3TxuwCUlH2gr9h6Fd71buv4uei1pH7LLU/jmCFJZrpM2XWzPc0YhnB1T1Z 2p002z1jIODMV7PHNl9+uH3EVNIXQJHrpObVVqwprbTr1FPHh8TmfiRnH4Mp8EYJ fc8Gmu8gA1mnSet+6F/bWKP2U5Ej06QhPCpHvY+vJsH1ANkH7uiDWMYsAZtEE1Hr WYtV8quDbIlWGmTV0c+xTN5WvcEHlcryLsO9+VbDl2I97JThLuqbtYtn1Z2DVc5y GRBabOoRQ8bvV0bMbqOg+F2nnosWDZiDnybJFwIDAQABAoIBAGA8GNn0DaUwo5RI htQPqVSWXENlklJ9od1G1FGJeWudFWEDietYfYbdPEcyE9+snXUxCkdSkX0mKBCR KdW7JsUlh2pp83t5scmmP+jcTbNlaX9ZM5Nbwun3YCp/cuExWQbEu8HZBp7nWB1v lFgHNPi2N7WPqvuSjLNGtHVT9gEwWGUl1zfbuZp8pNT4r1l7nwj+S9pGF3v5RXDt qZWSbfPF3ESPkMOpXxGk5uDLx3aoeHBQALVjeNdVlkyxjrG75Pv7ZnrmXjXzcuVv aVACiCPWxzaRFR9cRCx/Z34KrJorLglrfIPIrRMKJY33QO2gpYYEpFkLsLth/Ip4 NMSJ3KkCgYEA36skUOFK0iQcdEaUXR2zcvQd3P3ctxe0JqD7dHFWnY2ndA5+VvAP vUjemZgw+tNt1qjLCAwxMi4cEOEICG6zSlMBRcVbqkKPS3gd3fGvD/lfQZ02EePz 6KYVC7xz1WXIcId/HvkBNmbPEyOLqi9fIJQoYrM3LnB3AFIUqQ4K3UMCgYEAxCRT Z6yLGFb6Evkvvc6usqDhpAjWaaTSxlsSf9IGsKXW90OronB1IiTaWgJze1PrwWy4 z4YOSI8oEEpF7LdwI9hztg9wFGht8lahGkfHtgR7V/QzyLMYfcU/57STI9vvsw2S FNqIdeP1Bd/CE8iI6o6HOAadsWlTBBUBUtnZnZ0CgYA/ecthpL5eKt9kZE9gqbgu rHb5K5aC45g9yjvyjOO+7N+UATT7qT9eQZrizh1AYdZvMBIGo6cmjY1rgOGNuxTo x+u5iEv+YstV6K3ZOeiryOKutVYN97pV0SRx4zagXjVnMhzyhkpAzSaBUPom/zCp B0L618+WP1aWYbT5UUHmDwKBgA3Ju+86yuBgJN42lCuUnuVBt/rvABuXEZYOCuPf YMcEMXNaV3No0mMfEhZnu7R8tsL3IJq+Ar0JCzjx765vSrvKWIAA39EfcjMp8dNG HnzmHcGWEhnWtS8KMa7ZG8rWiCgfGRjML/GRn8TU8PCxFSbf9BN1K5qwG7zauSgY 1lplAoGAfl1Qw77H27TYGMVBgco/2g05MaKb8TZ4PKn1znlPnNcqFEBi779W0/dD Zgb1mjnRQkw68Jj5XA2zv/06yjvTS+nHVEDCdgIrZI2p1IrI3F4tihSoWgYtoe+8 5OVDiHQ73d6lxVLqIRoRic8ZtWR02PbrK5SmoPsFdeTcmtzqo6c= -----END RSA PRIVATE KEY----- bouncycastle-1.49.orig/test/data/org/bouncycastle/jce/provider/test/rsa3/self-testcase-G.pem0000644000175000017500000000613410503212005031446 0ustar ebourgebourg-----BEGIN CERTIFICATE----- MIIEHTCCAwWgAwIBAgIBADANBgkqhkiG9w0BAQQFADBsMQswCQYDVQQGEwJHQjES MBAGA1UECBMJQmVya3NoaXJlMRAwDgYDVQQHEwdOZXdidXJ5MRcwFQYDVQQKEw5N eSBDb21wYW55IEx0ZDEKMAgGA1UECxMBYTESMBAGA1UEAxMJbG9jYWxob3N0MB4X DTA2MDkxMzE4MjYzMloXDTA3MDkxMzE4MjYzMlowbDELMAkGA1UEBhMCR0IxEjAQ BgNVBAgTCUJlcmtzaGlyZTEQMA4GA1UEBxMHTmV3YnVyeTEXMBUGA1UEChMOTXkg Q29tcGFueSBMdGQxCjAIBgNVBAsTAWExEjAQBgNVBAMTCWxvY2FsaG9zdDCCASIw DQYJKoZIhvcNAQEBBQADggEPADCCAQoCggEBAKtexL4ZP1CWMsVedm+pD2xPG+md VbRqkVSDQYxrHUyRVKletjluY95908bsAlJR9oK/YehXe9W7r+LnotaR+yy1P45g hSWa6TNl1sz3NGIZwdU9WdqdNNs9YyDgzFezxzZffrh9xFTSF0CR66Tm1VasKa20 69RTx4fE5n4kZx+DKfBGCX3PBprvIANZp0nrfuhf21ij9lORI9OkITwqR72PrybB 9QDZB+7og1jGLAGbRBNR61mLVfKrg2yJVhpk1dHPsUzeVr3BB5XK8i7DvflWw5di PeyU4S7qm7WLZ9Wdg1XOchkQWmzqEUPG71dGzG6joPhdp56LFg2Yg58myRcCAwEA AaOByTCBxjAdBgNVHQ4EFgQUPd6mAcGQZ8iNGajt0kffN4AeDZswgZYGA1UdIwSB jjCBi4AUPd6mAcGQZ8iNGajt0kffN4AeDZuhcKRuMGwxCzAJBgNVBAYTAkdCMRIw EAYDVQQIEwlCZXJrc2hpcmUxEDAOBgNVBAcTB05ld2J1cnkxFzAVBgNVBAoTDk15 IENvbXBhbnkgTHRkMQowCAYDVQQLEwFhMRIwEAYDVQQDEwlsb2NhbGhvc3SCAQAw DAYDVR0TBAUwAwEB/zANBgkqhkiG9w0BAQQFAAOCAQEAoLujmlhRD05T4G8CQa+g kIW/l43pazV1+iWaPnADd3/ywX7BNrVkGDaJHPci1BBq8lsiIA9nu7Gfxjl9TsZe wwLzZ/LxI9tTR+ikYxy0MID+x45rk1dF0nnya9S3wQAXDhP8ZKN0d8ezvbQ2N2LG 74YPAtQZngMLMvYlG6MgoDNYOHHDkYZ6uL8PEwU9DtlZ+JPwxI7o7/E/T3XdDpvI UcI15axKbD5QMqGQxZwgQYFVMDvKou1upkLQ6ymHYgEzSqNNSzTYVdhVrGgTX+xl VZQFdJqR/gkloXbzxC/WqFTGrX1WN6kMvL+ZnVEh7DWELPmLFMfoWYCd4Q2hIjdx MQ== -----END CERTIFICATE----- -----BEGIN RSA PRIVATE KEY----- MIIEogIBAAKCAQEAq17Evhk/UJYyxV52b6kPbE8b6Z1VtGqRVINBjGsdTJFUqV62 OW5j3n3TxuwCUlH2gr9h6Fd71buv4uei1pH7LLU/jmCFJZrpM2XWzPc0YhnB1T1Z 2p002z1jIODMV7PHNl9+uH3EVNIXQJHrpObVVqwprbTr1FPHh8TmfiRnH4Mp8EYJ fc8Gmu8gA1mnSet+6F/bWKP2U5Ej06QhPCpHvY+vJsH1ANkH7uiDWMYsAZtEE1Hr WYtV8quDbIlWGmTV0c+xTN5WvcEHlcryLsO9+VbDl2I97JThLuqbtYtn1Z2DVc5y GRBabOoRQ8bvV0bMbqOg+F2nnosWDZiDnybJFwIDAQABAoIBAGA8GNn0DaUwo5RI htQPqVSWXENlklJ9od1G1FGJeWudFWEDietYfYbdPEcyE9+snXUxCkdSkX0mKBCR KdW7JsUlh2pp83t5scmmP+jcTbNlaX9ZM5Nbwun3YCp/cuExWQbEu8HZBp7nWB1v lFgHNPi2N7WPqvuSjLNGtHVT9gEwWGUl1zfbuZp8pNT4r1l7nwj+S9pGF3v5RXDt qZWSbfPF3ESPkMOpXxGk5uDLx3aoeHBQALVjeNdVlkyxjrG75Pv7ZnrmXjXzcuVv aVACiCPWxzaRFR9cRCx/Z34KrJorLglrfIPIrRMKJY33QO2gpYYEpFkLsLth/Ip4 NMSJ3KkCgYEA36skUOFK0iQcdEaUXR2zcvQd3P3ctxe0JqD7dHFWnY2ndA5+VvAP vUjemZgw+tNt1qjLCAwxMi4cEOEICG6zSlMBRcVbqkKPS3gd3fGvD/lfQZ02EePz 6KYVC7xz1WXIcId/HvkBNmbPEyOLqi9fIJQoYrM3LnB3AFIUqQ4K3UMCgYEAxCRT Z6yLGFb6Evkvvc6usqDhpAjWaaTSxlsSf9IGsKXW90OronB1IiTaWgJze1PrwWy4 z4YOSI8oEEpF7LdwI9hztg9wFGht8lahGkfHtgR7V/QzyLMYfcU/57STI9vvsw2S FNqIdeP1Bd/CE8iI6o6HOAadsWlTBBUBUtnZnZ0CgYA/ecthpL5eKt9kZE9gqbgu rHb5K5aC45g9yjvyjOO+7N+UATT7qT9eQZrizh1AYdZvMBIGo6cmjY1rgOGNuxTo x+u5iEv+YstV6K3ZOeiryOKutVYN97pV0SRx4zagXjVnMhzyhkpAzSaBUPom/zCp B0L618+WP1aWYbT5UUHmDwKBgA3Ju+86yuBgJN42lCuUnuVBt/rvABuXEZYOCuPf YMcEMXNaV3No0mMfEhZnu7R8tsL3IJq+Ar0JCzjx765vSrvKWIAA39EfcjMp8dNG HnzmHcGWEhnWtS8KMa7ZG8rWiCgfGRjML/GRn8TU8PCxFSbf9BN1K5qwG7zauSgY 1lplAoGAfl1Qw77H27TYGMVBgco/2g05MaKb8TZ4PKn1znlPnNcqFEBi779W0/dD Zgb1mjnRQkw68Jj5XA2zv/06yjvTS+nHVEDCdgIrZI2p1IrI3F4tihSoWgYtoe+8 5OVDiHQ73d6lxVLqIRoRic8ZtWR02PbrK5SmoPsFdeTcmtzqo6c= -----END RSA PRIVATE KEY----- bouncycastle-1.49.orig/test/data/org/bouncycastle/jce/provider/test/rsa3/testcases.README0000644000175000017500000003402010503212005030665 0ustar ebourgebourgPKCS1 tricks by Marius Schilder This package contains 11 self-signed certificates. The signatures have faulty pkcs15 padding but might fool some verification implementations. Although these are self-signed certificates and use a key with public exponent 65537, each of these flavors of faulty padding can be constructed without knowledge of the private parts for sufficiently long keys that use exponent 3. Use your favorite search engine to locate background information. Search for "Bleichenbacher RSA signature forgery". Each of the self-signed certs comes in two forms: .p12 for pkcs12 form, empty/no password .pem for pem format For example, unpatched openssl gets fooled by A,B and J: `openssl verify self-testcase-A.pem` This suite of tests is not complete and passing does not equate safety. Consider a different approach than DER parsing of the provided signature; for instance construct the expected image and compare. Exponent 3 trips up sloppy verification implementations; avoid and do not certify such keys either. --- testcase-A: Properly padded but short and followed by garbage 1ffffffffffffffff003020300c06082a864886f70d020505000410e6bd45f3fca2e3abb5b36cdd134c450300000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000 (([06:2A864886F70D0205],[05:null]),[04:E6BD45F3FCA2E3ABB5B36CDD134C4503]), 0:d=0 hl=2 l= 32 cons: SEQUENCE 2:d=1 hl=2 l= 12 cons: SEQUENCE 4:d=2 hl=2 l= 8 prim: OBJECT :md5 14:d=2 hl=2 l= 0 prim: NULL 16:d=1 hl=2 l= 16 prim: OCTET STRING 34:d=0 hl=2 l= 0 prim: EOC --- testcase-B: Garbage blob argument to algorithm 1ffffffffffffffff003081f23081dd06082a864886f70d02050481d0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000410e6bd45f3fca2e3abb5b36cdd134c4503 (([06:2A864886F70D0205],[04:00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000]),[04:E6BD45F3FCA2E3ABB5B36CDD134C4503]) 0:d=0 hl=3 l= 242 cons: SEQUENCE 3:d=1 hl=3 l= 221 cons: SEQUENCE 6:d=2 hl=2 l= 8 prim: OBJECT :md5 16:d=2 hl=3 l= 208 prim: OCTET STRING 227:d=1 hl=2 l= 16 prim: OCTET STRING --- testcase-C: Garbage appended to algo specifier 1ffffffffffffffff003081f23081dd0681d82a864886f70d02050581d00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000005000410e6bd45f3fca2e3abb5b36cdd134c4503 (([06:2A864886F70D02050581D000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000],[05:null]),[04:E6BD45F3FCA2E3ABB5B36CDD134C4503]) 0:d=0 hl=3 l= 242 cons: SEQUENCE 3:d=1 hl=3 l= 221 cons: SEQUENCE 6:d=2 hl=3 l= 216 prim: OBJECT :1.2.840.113549.2.5.5.26624.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0. 225:d=2 hl=2 l= 0 prim: NULL 227:d=1 hl=2 l= 16 prim: OCTET STRING --- testcase-D: Garbage in null parameter 1ffffffffffffffff003081f23081dd06082a864886f70d02050581d0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000410e6bd45f3fca2e3abb5b36cdd134c4503 (([06:2A864886F70D0205],[05:00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000]),[04:E6BD45F3FCA2E3ABB5B36CDD134C4503]) 0:d=0 hl=3 l= 242 cons: SEQUENCE 3:d=1 hl=3 l= 221 cons: SEQUENCE 6:d=2 hl=2 l= 8 prim: OBJECT :md5 16:d=2 hl=3 l= 208 prim: NULL 227:d=1 hl=2 l= 16 prim: OCTET STRING --- testcase-E: Garbage within sequence, within algo sequence 1ffffffffffffffff003081f23081dd06082a864886f70d020505003081ce0481cb00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000410e6bd45f3fca2e3abb5b36cdd134c4503 (([06:2A864886F70D0205],[05:null],([04:0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000])),[04:E6BD45F3FCA2E3ABB5B36CDD134C4503]) 0:d=0 hl=3 l= 242 cons: SEQUENCE 3:d=1 hl=3 l= 221 cons: SEQUENCE 6:d=2 hl=2 l= 8 prim: OBJECT :md5 16:d=2 hl=2 l= 0 prim: NULL 18:d=2 hl=3 l= 206 cons: SEQUENCE 21:d=3 hl=3 l= 203 prim: OCTET STRING 227:d=1 hl=2 l= 16 prim: OCTET STRING --- testcase-F: Garbage in middle of expanded hash field 1ffffffffffffffff003081f2300c06082a864886f70d020505000481e1e6bd45f3fca2e3abb5b36cdd134c450300000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000008000e6bd45f3fca2e3abb5b36cdd134c4503 (([06:2A864886F70D0205],[05:null]),[04:E6BD45F3FCA2E3ABB5B36CDD134C450300000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000008000E6BD45F3FCA2E3ABB5B36CDD134C4503]) 0:d=0 hl=3 l= 242 cons: SEQUENCE 3:d=1 hl=2 l= 12 cons: SEQUENCE 5:d=2 hl=2 l= 8 prim: OBJECT :md5 15:d=2 hl=2 l= 0 prim: NULL 17:d=1 hl=3 l= 225 prim: OCTET STRING --- testcase-G: Garbage blob next to hash, with hash replicated in least significant bits 1ffffffffffffffff003081f2300c06082a864886f70d020505000410e6bd45f3fca2e3abb5b36cdd134c45030481cf0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000008000e6bd45f3fca2e3abb5b36cdd134c4503 (([06:2A864886F70D0205],[05:null]),[04:E6BD45F3FCA2E3ABB5B36CDD134C4503],[04:0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000008000E6BD45F3FCA2E3ABB5B36CDD134C4503]) 0:d=0 hl=3 l= 242 cons: SEQUENCE 3:d=1 hl=2 l= 12 cons: SEQUENCE 5:d=2 hl=2 l= 8 prim: OBJECT :md5 15:d=2 hl=2 l= 0 prim: NULL 17:d=1 hl=2 l= 16 prim: OCTET STRING 35:d=1 hl=3 l= 207 prim: OCTET STRING --- testcase-H: Garbage blob parameter to algo sequence after null parameter 1ffffffffffffffff003081f23081dd06082a864886f70d020505000481ce00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000410e6bd45f3fca2e3abb5b36cdd134c4503 (([06:2A864886F70D0205],[05:null],[04:0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000]),[04:E6BD45F3FCA2E3ABB5B36CDD134C4503]) 0:d=0 hl=3 l= 242 cons: SEQUENCE 3:d=1 hl=3 l= 221 cons: SEQUENCE 6:d=2 hl=2 l= 8 prim: OBJECT :md5 16:d=2 hl=2 l= 0 prim: NULL 18:d=2 hl=3 l= 206 prim: OCTET STRING 227:d=1 hl=2 l= 16 prim: OCTET STRING --- testcase-I: Garbage within 2nd algo specifier within algo sequence 1ffffffffffffffff003081f23081dd06082a864886f70d020505000681ce00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000410e6bd45f3fca2e3abb5b36cdd134c4503 (([06:2A864886F70D0205],[05:null],[06:0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000]),[04:E6BD45F3FCA2E3ABB5B36CDD134C4503]) 0:d=0 hl=3 l= 242 cons: SEQUENCE 3:d=1 hl=3 l= 221 cons: SEQUENCE 6:d=2 hl=2 l= 8 prim: OBJECT :md5 16:d=2 hl=2 l= 0 prim: NULL 18:d=2 hl=3 l= 206 prim: OBJECT :0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.40.90 227:d=1 hl=2 l= 16 prim: OCTET STRING --- testcase-J: Minimal legal sequence without null parameter followed by garbage 1ffffffffffffffff00301e300a06082a864886f70d02050410e6bd45f3fca2e3abb5b36cdd134c4503000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000 (([06:2A864886F70D0205]),[04:E6BD45F3FCA2E3ABB5B36CDD134C4503]), 0:d=0 hl=2 l= 30 cons: SEQUENCE 2:d=1 hl=2 l= 10 cons: SEQUENCE 4:d=2 hl=2 l= 8 prim: OBJECT :md5 14:d=1 hl=2 l= 16 prim: OCTET STRING 32:d=0 hl=2 l= 0 prim: EOC --- testcase-L: Garbage in the padding 1ffffffffffffffff00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000001003020300c06082a864886f70d020505000410e6bd45f3fca2e3abb5b36cdd134c4503 0:d=0 hl=2 l= 0 prim: EOC bouncycastle-1.49.orig/test/data/org/bouncycastle/jce/provider/test/ThawteSGCCA.crl0000644000175000017500000015354311724567057027705 0ustar ebourgebourg0‚×_0‚ÖÈ0  *†H†÷ 0L1 0 UZA1%0#U Thawte Consulting (Pty) Ltd.10U Thawte SGC CA 071127212500Z 071211212500Z0‚ÖI0!KLÜøôÕŒ‰Ë^É"Vt@ 061103170711Z0!KPb5ö^ù6èdÓ cú 060822174027Z0!KU°¯©—VeÑd)äì 070711150255Z0!KŒ0ÀÈ—Ý'ÙqÜû2 070802120354Z0!Kæ„°"òNo YzvS 070508202243Z0!Kµb!»ÃJ¾SÁTuƒ5ª 061019151850Z0!KºN6ôz–¢eþ.ùÇ› 070313144349Z0!KѬ*>m)½1”“VÚ@› 070304114851Z0!KâqÜH’±$å…¸®H\q 060126100251Z0!Kë°½FØñî{.£Ä œ[ 070830101758Z0!KûRÞí©C"óð öRÿ´ 070921141813Z0!LªPSQõe4w 6ÃY 061026065416Z0!LCCä—ø0ùLÇ€ðJƒÓ 070707055934Z0!¡‘St–Ûµ°¦öÅ´¦ 070625115741Z0!Lvç;té¾+­›]ÏÏ% 070416105926Z0!L~áD}ciÿmÁUoëÅ” 071105170817Z0!L’wÅã‘ë_Ì<ìØ‡€ 070906234656Z0!¨Ëéqì˜"Ò»ÞüÚ  070420220802Z0!L˜—¥N¦àŽ­Ð•ƒ·£. 071029143322Z0!L±·úfØu¡f[Fªž 070619092741Z0!LѯüݘˆLK¬PàçÂÐ 071004075252Z0!Lî\ãŠD]¥NºØÙл Ù 060602152937Z0!LñjHrêsæøA±¼4* 070814141617Z0!Lÿ鸧ùtP}†÷‡ÃÎ 060322221826Z0!Mê>xÅ‘ŸØ$Ht 051215135207Z0!MŽV2ó|Q”ÔBs#Î 070511204154Z0!MR1ºOÛ¿YT™p¹ 070913150706Z0!M2¯¢ÔÎ"à~5(¡îæÆ‰ 070711151546Z0!M=OßE„•ü®qÉ‘ÿ1¤W 060927192242Z0!¼©¸Û³•¿™c *˜ 070227125327Z0!MmXr8sgôÄÀ¡`Ù©J 070711152647Z0!¾MÑã„å)° -$¡V 060104142641Z0!Mpå]Ã[ÄW‰IëÐ 071002133321Z0!Ms£4$ü\vx6²®dÙ 070629140515Z0!¿‚¶#,¯SŠÝ‹î‚Ñ 070222145639Z0!M‡#ƒ‚‘ÁÁ°ÆþÝqÓ: 071102124343Z0!MŒœèF;1ˆ)jfŒ‘ 071108154714Z0!MŒZ4ßXvÓ•ü’J  070215210247Z0!MŽæ”Q}Õxù¾ËVêµ 071012225500Z0!œXð%jÍßI!ºcï 071025182615Z0!MÍEð?¦k 5ªà‘mÎ 070314202330Z0!MÎZ¿~÷’„ 2HW„ 070810171939Z0!Má~™›©sþô9š¹|߃© 061120070546Z0!M㡊g‚‡ëGRʧÖÁ 070911005348Z0!Mð¹ô™­inÈD@JŒr 060127153911Z0!Ë|e¦\™ ò²Çöôö 061023231755Z0!N¾4ÚpâžÌèÒ ü& 070629143938Z0!N5 ÛÚj>¥ò.¹¤ 070518164102Z0!ÏM%+«Ý®÷wÔœ 060822150923Z0!N)áÕ I>áÊ•ÏÞëU” 061108112131Z0!N*015+<¸ó;4~Í9 070531132059Z0!NnÌvÂ@Y¢^Ãé©Ù 070219160517Z0!Ns#¸@Ö“øbYF+æÿ¤ 070828070934Z0!N](k1·\ÜìX[ 070404122505Z0!Ù­uíÓl$'â8µ… Íò 071001145625Z0!N…§‘Šy|•{ÒôN 060622125618Z0!N…¯þÒ‘,·øÈÔ竤P 070921173707Z0!Ü6!p¼pèÓXlJó¢ 070525172845Z0!Nª0à—ÌþÇG®—— 070620230614Z0!ß?)À¹ ¨»º'd3øç 071121040234Z0!N¿ÀzÌñr€´FÎS. 070516205607Z0!NÃæ,‘lƒoI²YS0{ 070425225411Z0!NÍô¤ÑžqÀ®&´–õ1$ 071012080818Z0!Nüjnº* M~aÍ^Œ<ð 061218140851Z0!O,°yüPNÝ!õ6Âq 070619151333Z0!OÚ2cvG3_Búôƒ 060303145617Z0!OËøŠÊYÛú Wˆ 061120185644Z0!O7œ…D—èvãѬ¶¢ 071004194934Z0!OFò[õeÀÒi–µ?õ’Ž 061106201845Z0!OLô5d0¼$7ÖäFät` 060831114017Z0!OwgšªG$^˜hX¤r 070220154005Z0!OGšq~lÂ;ÖCµRxU 070916025925Z0!Ì#ë_<…4†íÙMàÆ6 070726180122Z0!OЉ ¾Ð|¡ NZB 060505025335Z0!OÖ»ÈyUú)jB‘÷jý 060324120505Z0!OÚx‚Fù8)×ê[¨AF 071005144427Z0!Oèä~dö¢ßåáaà.ô 060807132558Z0!Oó¿ß-y¥ï„Àâd 060608130217Z0!Oýlç¤_3ô©‹nEŸáB 070209213507Z0!PÆZø—z˜3Öo( 060921083526Z0!P$‚!ÚÔ†O æ9<"™‡ 070702093156Z0!P(¾úH³±P«‚Á ei 070725121253Z0!P*íɸn+Tç Ê`3 060601111729Z0!\ÞZ×@cièà”³U> 060320133855Z0!PPœøO‹LŽûÄÖWñ· 071029160056Z0!P“ËSOÖcÅ+*Ç©7 070106005213Z0!P–@07Æk'HCoö6 070315140724Z0!P–Ì™õóœ»ßy(u + 060220165430Z0!P¡ÿœùþ¿×šŒìS 070208182013Z0!P¼H¿7Ë mÍ[ýï 070330101546Z0!PàË–-èÞ–,ñÛÔ‘‘“G 070531053424Z0!Pü‹‡…:UµÔßæ’[©ž| 061221142604Z0!н ,> ÷>ï 071119161453Z0!Qæ4ìs+&+À°;@,Ò 070910211230Z0!Q* (¼{ô©_¼~@ 070711150953Z0!Q8ûÀ’›ÖEþ k·aÁÉ 070404122627Z0!Q]…àÎH+îaÊ0ìâ˧u 070827080905Z0!Q{.Ñ©ŠM~ìq¡ØY¯ 070711151953Z0!Q–ð㔹y`‹NžoÕߨ 071016104653Z0!Qœ„ö|ÉÏE`’›Í^Õ 060202213118Z0!Q·Z £X`La®W 060516180743Z0!Q¸HþVûÖð‚ó 070529195112Z0!Q»{¿Jµ;!cÀ¼ç“• 070707005848Z0!QÀã0¨³ªØäèú¤ø¯®7 070228185726Z0!QÕËòéÃÕ¢ô`6˜íÛ 070821142304Z0!/¬âH,ÊÆ„£vó(7ñÆ 060929103011Z0!QݩΠ: ÷Ê®Tã 070412001955Z0!QïöŸèŠ}©(nƒ‚ 070726164558Z0!Qõ´‘è‘Ë›×Z‘(r 070711151510Z0!R ¾‰»uõVyW~ô¸•Ó 061123105115Z0!Rîê¡ÂNT+eÞÊâ› 070201215129Z0!R?iw…3µˆŠZ¨#Pýe 070302055815Z0!Rd"ï‰Ú, "ø<~Æà 070711151641Z0!Aä4. °$@¬´øzsr 060803162213Z0!E\äWq¯²-Ô\xn > 071116192321Z0!EÃðô“géÒ£ s“è 070418191805Z0!FaËIÏB…ë¡AéºæDî 070118165713Z0!R ™ÈY\°ÂHs&ÃLš 070924140055Z0!S59ƷŽè°*Xâc 070614085409Z0!S¾ãÞÕñMí™RåU„Äÿ 070720124722Z0!S91W·÷ã%#Œ~xv 060623122941Z0!Sj5ÀyQÊLÕép”P¥ 051219194859Z0!STZé8ئzµ²TÁ 060320125930Z0!Sguö³bɰòñH¨ÈK 070719141054Z0!SlnDcžÃˆO„ênW ¤s 061103220300Z0!Sˆú‚ç€|Тްžž]'É 060731183910Z0!Sp“$« ºü?lF¨”™ 070711152356Z0!S—ºÔýÚ N‰‰)÷65 070614180327Z0!S³}º+äïÌújÅÁ 060228101800Z0!SÛp‡Ý |’¦¢ûx 060802120812Z0!Séf¿|!2¤BtQLJy 070531071957Z0!SëþI3ÊK’/ +Áôâü 070709101448Z0!Sù1¬/è ÜP¥Ðe@ 070217202435Z0!TIÉÜ™2ï]‡$SÔÁ 070404134801Z0!TaÝòÌÞ·Û:3q á 060510083237Z0!T}ÄDN´óQ|2¤ÈVjõ 060710233902Z0!T•(ç2=)0ž_XÆØ#\ 060706184742Z0!T©`äO±¦ 8ž‰œ‡ 060123215226Z0!TÂéT‘êÏ)Z˜WÂ? 070213143314Z0!Tܺr«Å§U1=ŒAš 070711151451Z0!|·›ÞDè´­›¦Ï8 071120120317Z0!Už˜ÜÜ@¤ùaUFÓio 051220004753Z0!U;ÄâUÖä±€é>{äÐéÿ 070711152231Z0!U?£˜IG?´Ö(šL‚{ 061115212752Z0!UX×Ô~Àlýq¨‹'ïYp 070112164441Z0!UfØd¸»•¦ÃÚ{ðè© 060928100051Z0!UyuÀ¥#u6"b™(Fb=6 070731083830Z0!UÂåÌÆÐ8LÛ¬Cô 060819061309Z0!Uß©»¿Gíl /h~£•* 070614180603Z0!Uï‡Á4¦GHÔ ±™Çc 070517193255Z0!VsR å8ùq°ÿbš…! 060713172845Z0!V z¸™æw• î^†  071105163042Z0!V?n ˆš<Κy 070912082120Z0! sѸÙA%ìÈ%) 070331022025Z0!VZa"Ÿê¼d a»Å¤Fc 070730093208Z0!¤ŽÌ%£BÐH¶È51à^u 051223161642Z0!VÖv¼ïC¨®RåJºÙ‘ 070220100101Z0!V䄤öo'<^W>ÏŒ%g 070717200231Z0!Væ#R÷þÑaRhàý ³ 070201143930Z0!W#˜°B[(RÁÊg¥ìí – 070718010637Z0!WVƒê–S‘’sukX 061205150931Z0!W~¸àw%n^úèwXNU 061204051741Z0!Wˆ‘AþiE$Ò1Ú-6EÑ 071001161444Z0!W“pMõß‚ CSñƒÀÑ 070821180223Z0!W”4vÛ­JfÇ'Zsp%  071029174021Z0!W¤4^õÅ`.xÎH'Äí 061206153302Z0!W±Y“£•ŒðT­Šì— 070711151126Z0!WÔþ+ •ÜÂóÊÜôKžÏ 070614180011Z0!WëWS -“Ѭ øØO›Â 060913095653Z0!X"´Âh{ 070611105732Z0!XwÇ’ñ.7åÄE5£9!( 061018200029Z0!Xy<D½gj­9ã¯ÃѦØ 070418092148Z0!X…Oß‚E@h›A 070614175624Z0!X’ˆ›á.p½ âƳW, 070711145955Z0!ÛîÃQ!©›*°2›ÀYX 070921192313Z0!XÈõy±ó"©øCŸáî"x 070412140006Z0!XÑÌÍfŽôáô§ÌíÈ 061114181331Z0!XÖ 071013171234Z0!Zù•NïÞ(¦Jï_®íÝÏ 070517083936Z0!Zü°/š|ÞœKñJ;0Ÿ 070711151432Z0![#ýýÖ!çÑvI{ ´ä 060224024425Z0![;ÃÀÈà6?–e§B 060707161254Z0![T¹Â×èi N2? 070202074357Z0![e¯D)DÈ­Ÿ¬ º2.d 070828180113Z0![x¶B4¥ÓγwÔiÁµâ 071011083454Z0![‰GÎ eLs½&%ù 070628143601Z0![/†ÿMÃ%ÎOÝÎåÊ 071002133034Z0![¢…ùõ–žf³éã* 070522095717Z0![¨RôÍ\÷¥ùl9šdà} 070903202019Z0![º¼ôgÉÂøGJèôKÑ€ 060512151840Z0![Áµ%à]LÄU Í™V 060206103339Z0![ÚMFõ¸¯¨>7€ÀN% 070816185423Z0![á§ŒçDu–{ÞLýa-‹™ 060512095735Z0![ðÐL8]ÿÔpƒ~5V1 070525132958Z0![õ/UˆœIŸˆ-§¬Ý& 060303074916Z0!\rP<]¤ÒñÎQzƨh… 070906114105Z0!\0gR/¨'³–ÖeÐ@"G 060719100350Z0!\@/HUº}Y'Ÿˆ$:[ 061210192927Z0!\R݃2ðõ¬UA°´l 060831164753Z0!\€ê§gïˆiŸÉ‹YZu 060514055630Z0!\‹ŽÌH'oæp°ïaER· 070329205819Z0!\Ÿ~—µúðH¨æâŒLé 070627180304Z0!][€TV¡Cüö\úÑ¡è3 060711145758Z0!]}J›Ž„»¯c6½{ 060601110841Z0!]0&­ñ¿zÞ0Ÿ-­, 060523102212Z0! R+G»{)g†¯ª_q© 070712010840Z0!]EškÿnXèÅÙ€j| 070327233139Z0!]‹?XÇRCœ2Žh‰©\c 071109110442Z0! _#kDIy[]?2Úœû/ 061127083956Z0!]ÑO£ÃQž õ.Jz^à 071027012541Z0!^´ó#A#™ ûYPP  070418172748Z0!^%Oo%7£~ߤGðbh« 070529183313Z0!^)>ÒG1¼Âw’ÿu¾Ù¢ 061220030436Z0!^*禾)‘›¥b‘Ú9 071030230506Z0!^; y ¶–߬5œ¦ö<к 060608135253Z0!^;¦ÇaÌ*.Ïá`6 © 070824181624Z0!^MºdrŒw—vç‚¶·_ 070430155304Z0!^|$•“Õôø‹Tõ`è 070227211952Z0!^ƒË×#o0°þ…˜€õ\ 071023184502Z0!^‡õÞÊ'J÷I*mvæÄ 070220134852Z0!^•Cܶö¡~-£²ñ*ìø 070622070912Z0!^£ [•ÄP[Œ€K½£–Ml 071115121149Z0!^ÐÛ½, ÌÅ@ÐYÂöÀ0 070711145627Z0!^Õþ€ôttæó/‡%¶Œ• 070710163158Z0!^ÞºJ |u9οF¬oH¶ô 070925092937Z0!^ñŒý ’€y2æºÇ £× 070301115342Z0!^ôÌ ö‡‡J7&"`Á¬*Ç 071102170516Z0!^õŽžÜyúc똕·­íý 061117073223Z0!_Üd¡A*£n±î„s 070612085047Z0!ó‹:m‹(ì?±÷£Ì¯Ø 070920212404Z0!_~H$Ÿ%uÊ“©­ä§N3 070809152618Z0!_¨Û"rûá'˜$Äæ 071101153655Z0!_ª$O“¯7%Æ%_·% 060113152000Z0!_¿«þ.(N[` ÞÑZcÚ 061005191049Z0!_æ’eühKªBMH /» 070611150305Z0!_ê/U¶%'>€{E Ô· 070403093315Z0!_ý”“‹e–eÏ»ƒæž† 070618132450Z0!`'tgÆS|Ÿ´¡sÅnfK 070816190611Z0!`)QÁ¸cj<.¨DV‚e 060919135817Z0!`6O‹pÀ¨Zès©© 070613092642Z0!`8¬Å (8›?Åp7 060421205001Z0!`A‰ýf$ ±ˆW"OÓó1Ì 070221233910Z0!`M˜=ñENÐÎ \¤5 060106091153Z0!`ŸÛ4Ò3à•²Ø®j~¾² 060501100209Z0!`¬PDíòúž’*%ëN+ 070827123214Z0!`¸™2é#©"õ²úåõ 071004152603Z0!`Àº!²'oH¨YãýKÑÞ– 070516160210Z0!`Ö‡^È5Ãú•¾×@{ö© 060322184004Z0!`Î[îÇ@Ç1m/Õµ 060504072347Z0!a·€{ÆRÛñ1œnýã 070905124024Z0!a4»KH½1ˆXi(Œ‹õÝ 070614180715Z0!aZ’ÆNay¦±fij+ Ó™ 070907183248Z0!as “acãÒŠ¶ôŠÉA 070202090344Z0!azhbÖÃ9õK«…¢W¢á 070711152326Z0!aÅçDö­êF!à`Ä. 060419091507Z0! Á9p§Yy\2¹{§?\ 060704070734Z0!aÙ&‡ØîIT CQ=y|q$ 070605150716Z0! ÉÀ!&w¡Û+ë½j 070523053549Z0!aê§AV¡¶óмqU9J 071127134723Z0!aø­oþcüÇ&ðâT­ô 061220130750Z0!b>߫܅&”áó„ç÷Yº 070619151054Z0!b¨ ïÀ‚LwÁ¹» 061024143848Z0!b<ÂÔë!Kš~f 6ýbÒ¼ 060605124204Z0!bV剈p_©ÌÔÏMø“ 071101121349Z0!bböí š§ÄúßäBž 070605150640Z0!bjqÝ$®éö”"ArÑÔ( 071107135013Z0!bpÝjœ¤ÙW( d ݦF 070711152703Z0! ÛÌ;é  ’Šñ³1Bœ 060126095911Z0!b®<¥FÞtY£M‹Ó  070625065457Z0! ßkfÙ;ÉïÀ§oL˜bw 051227120513Z0!b¾l-ÿ½6¨!«¡MÒ 071123052623Z0!b¿LäKŽRš¢Žîœ®˜¿ 070410091933Z0!bÍÂÁ®Ù2FÚ1ã©'V 070612222542Z0!bÝhëž '—Ý|]ázÏ 071115151720Z0!bßDUÄ ¢òã×÷?z‰ 070808142325Z0!bò27EÏÙbE-kÐ{ãý 070711152120Z0!cBj‹Ñr]Çp¤cµCï 070330073544Z0!c'”­^ú¶ê~mø39 070907132830Z0!c(l‰O_ä}_P\¾ 070220112805Z0!cD¯ÓHoß_ã[ÏIýÁ 071126221617Z0! í`?%ykûw]úd>ÆÄÁ 061212154855Z0!cd)ØŸ'©ž,ÿEÝÉêu 070309084050Z0!c}_•ËõŽ?³-…©ÓYìU 070305233838Z0!c £ Ç•ª‡›Ïdª 070524134445Z0!c¤ÌP¸¤FyüLçøÊ 071025165100Z0!cÖÒg’å©D—¿…#e! 070423201745Z0!cÝ·Á3£ÿ ùG)˜ÓÈ 070711152613Z0!cäÎåå€HwRa?Ú~_î4 070215195052Z0!cèeûx¼'>ÉNFíû[ 070425212035Z0!céHuêÖ~é”ê9b 070510155328Z0!d‰«Ì­8,¾I­HÆe 071012214829Z0! £^£÷j©G”ûÙYˆ 071119162948Z0!d¯¡nEtTÍžÃyb^; 060607125715Z0!d2¢k ÿ8‚Þ©ÖŒ¼ 070101045238Z0!d0¯WfÞö3—jrvÚ». 070711150545Z0!dR¨æÀÿ²Ž\Ñ%P"7Ð 060803134722Z0!dZŸ›Ÿ¶_´ˆ(Š[W 070326121943Z0!db­OÞ¥Uü0ç…£jhÇ 070723224806Z0!ddµï.öCçDY ?N 060105082213Z0!d—>ÓÍ!”)j Â "œ 060320162958Z0!d¡ ãÞÝjq؉ÏMuÛ©— 070426172232Z0!d¡àƒ­¿^3ÍVŒ) 061201110640Z0!d¯Yl\sœfz~­_|ü@Ê 070809120059Z0!d·ÀÁŠ2 X&°Éq04Î 070718184448Z0!dÕmß«j$¥:Kb'0Ëü3 070329084703Z0!dÛAÅŸN¨›íD¦È 070619164237Z0!dáCY;(dÕšav1dx 071121094954Z0!dåÁA7ëŒLK1¦ˆþú 071123101348Z0!eçωscÿ¸¸ Î 1 060620193059Z0!e¶ž¿hzRRy{ƒ 071127104204Z0!eC¢2Ì„)*Àe)¾ 060315201935Z0!e+ß°Èu^/ï¨(PÌF 061109235636Z0! n\[ø:Pfk]g‚ 060526151823Z0!e7DŸéR»böcKšA3 070523141333Z0!ec 'úq¸"nýH°ßr 070220095934Z0!e…!é)ÃåøE@+AdÃÐ 070319225732Z0!e±mmÅž8kÁ¿Ü>ò\ƒ 060316161041Z0!e±/IV2•Ó$¾ PV5 061117172257Z0!eµ# ÝŸz¼›Ë|K!“ô© 070516123238Z0!eÄŠÑFaÇö 7.Á.] 071106151458Z0!eÌbX ný|ÚfŒ±¤á³³ 070522213820Z0!eÑ—œEÑ™Lßñ"C„sÀ¶ 070607111202Z0!eÒ âÑÒ0û²Ö_û‘ 070522225306Z0!eÛ™'f›ŸÒw4µàÝ€Ü 060707151353Z0!e߈­=S…ôvÀX\y 070316163447Z0!eâ#­Ë®Œ»£Ð=ž 060620161551Z0!eî;w¸©>'¬2?6Oƒ‰ 071008153626Z0!eôƒ5xWŒXö¡§a‰8¿ù 070827120922Z0!f-³aËM³evEŸ=õ 070613084425Z0! 76oóÃØx¡ûÿ3¹6 070301162812Z0!f* š˜ð™nå.†bš 060415201221Z0!f2ªBO$¸KÛy 2Y 070416113612Z0!f6cS"WÜ|v­ÍVû†ûn 070627105741Z0!fF0úkk!€NèxpÎòf 060829102600Z0!fJåµ\¬UJSáÙ¿Q‹ 070131102210Z0!ffØPå ·â´`š 071023101921Z0!f‰¯ÙOó„ïûrDºvp 070725182811Z0!f|ÔèvT·<ãGH‘à 061120130218Z0!f”²Mn |Y»ç|¤ñ 071114174411Z0!fÇ$[³‹B¸ÏFTÛÇ) 070515194314Z0!fâÁ°0ÚTDïˆéj¤ 061214151904Z0!fââY¬;2e6"ªã™ [ 070817175412Z0!g™5 ¿{èØ!Þº3¼ 060502090848Z0!g2Ý puKý¸arðT:‰ 070924185320Z0!g;€¥ Ž~ø¦=Â⛂ 070315122416Z0!gk’:´‚½gÇ5WÑbO 070925141601Z0!gq,ÞåÉ_=ÔG0ö_ 060928195141Z0! Zr7=¬ç ¡…([³†_ 070404102817Z0!gáo<äÇ?ɬ¶“Láž 071101232243Z0!gìé© ¼Ÿ(Îʪþ 070517193554Z0!gó2;¹Ûš‘Do¿gÓ 060213115325Z0!g÷ò²ˆåH0E"YY2 070529192353Z0!gø  ä £}PfP#ÖE 060316133435Z0!hâºlýÉ ? wîI‰~ 060531210757Z0!h·igÉ'àg—.ñ~¿Ÿ| 071012081858Z0!h/21O\к‚Z­Ÿ›H 070220141006Z0!h6„§‡õäü÷ëx2#´& 071107094610Z0!htÏù$ÄØèvžãv[ 070620163621Z0!h~ ¶‡áF“·êFuë´ 070406040429Z0!h„솅ѻÚu0Ô¨-¦ 060510120521Z0!h•Ïõ‰c˜ípÙo`@÷ 060810223413Z0!h™„G_]C •‘•NÉ/ 070328204800Z0! vz´”o‡¶}zYɈW»„ 070309121846Z0!h¸$H¤«kùT¤r]õ\wÿ 070215152602Z0! {*ÝbøZsÒ-üÍ$Jó 070222181710Z0!há¾ 7mr1)»g óÉö 070823204613Z0!hú>oÙRE`¼¡ú¶s» 060926153610Z0!i'­€ 070514195022Z0!j§ÊÁmK}À^ÉpÇäˆ 070725083514Z0!jÝYhªÊݳP¡‚oÎØ 071004144531Z0!j/ þá8JŽKï,-Z? 070509012231Z0!j9Ñâ;U–$`zàs‹U 061113092347Z0!  çî&ªÎYRáG¥j 070515132547Z0!jR—4ü7Ea§Lã™rò 070220160631Z0!j_ï&jƒë/Í6¢¤, 071016164427Z0!jcsPQà°¶Òxo· 060626164327Z0!jsÀ«@¬e/ëLãíª? 071108175953Z0!j­eŒw¨øˆÃŒ±~Ö“¹ 060713081853Z0!j°ŽîS” ºð ° ã 060721102746Z0!j±¥ç¾“ µ²¯]6IL 070108221410Z0!jÛÎñ”¢Êm3ч, 070829081732Z0!jôqff°HXúIw7h¬ù 070411162805Z0!jþŒJÙÎEÃpÊÖöà” 070824170848Z0!jÿ'šá´I™Ä¡´yuÈ 070502114355Z0!k*IpþJÊ-|©˜úD 070711152340Z0!k §t/ÑF‹â²Ùô«NØ 070213043738Z0!k TÊJ´Ür¬dcg p 060201164353Z0!k8»ŠÂºÀé•ã‚ P•ªÂ 070502133005Z0!k8Ű"x:æ¤ ÉÑÇÃÚ 070711150841Z0!k:†é³óy2¯|øÉUBj 060316161203Z0!kCAÙaQYº±/¶—  070614180740Z0!kT´¦5b¶‘(§á|ûP 070814131034Z0!k`½G×±E§BK®²~…Á 070711152813Z0!ku3i÷wÂ_?¶~Eæ_Œ 061024032212Z0!kv[š›±h@ENL㣥ô 070227165012Z0!kŽó½€‡D¤9ä?ÉA¦ 070402163143Z0!kÍS!-Ã`‡§•%uBŒÊŽ 070711150932Z0!kÙ95Ð k#’ôûöZå 060301201822Z0!kã%ÀªÈ¥´$Ï,oºÃ` 060904134339Z0! ÊZ¾½Øè7‰'ê¶¼$Œ 060601140007Z0! ËR.e-¥EÙÚ\V½3ºA 071115154539Z0!l0𡙣¾¨N¡’öÔ+ 060620200219Z0!l0üý²Kyf„kÒ²¾$© 061007162814Z0!l:Ô×ÊŽT©¡=}Ø 070316152838Z0!lC¼ñÖÃѾ•Róî 071127174952Z0!ljˆ/ÉY[‡\¶n°\j‘ 071003185633Z0!l’óGBŽÜi·ƒ4©Z‘Œ 070808174944Z0!l›‰ 2Óë¢ÀÊi½šÖLv 070818140822Z0! ÝŒÇ0"4èU•ÝŸz 070415155027Z0!lÉÀ¼qY-7M – ¯& 070417220450Z0!lÝæ¸­oJÔ ˆ,<ß› 060206203907Z0! ä” ŸE¿6i¨|xØŽG 061113085831Z0!lý$ºä“À ž¸™ß£0K 070313140547Z0! æ1žÈHŒ™»Éž˜ 070710164138Z0!ms¯åÚi~Œ÷øw¹Pè 070711152445Z0!m#[Óf2#áˆÛÞÑ™† 070219040010Z0!m#³<\ü¿7Bv/ÕíËB 060328100401Z0!m%œM©…ÚÌ ›ÞÎ÷ÞU 070713003404Z0!m(íŠ é!7+óhµ*] 070711151620Z0!m/!`^æØKHYc¥« 070605130920Z0!m<ù ¬È¤¢€&2ßk‹ë 070713141132Z0!m_)Ì/ßèïÆÊô!#/ 070906135208Z0!miBïÉ õ¨i“yŒo 060824182207Z0!mußCE(è!–3¥Eé§þ 061214020720Z0!m†AÍÏqÍíìxp^L 070326204951Z0! ô`aèOKÓªª€H 061230080408Z0!mq0îÊêTÌ •¥“šP' 071112223330Z0!m›‡Ä7dó:ÿÝ„µþ‡ 070529151009Z0!m¢/5ïFîjâÊÝYìÒ 070509183437Z0!m¨-d}‹ ÅyÃvŠà˜ 070220022911Z0!m³Ž*kÒð” @™ÕZ— 070427135009Z0!m»t WO¶r÷/(ìaªj 071102151941Z0!mÀ}¡ñå9l™m$ëR 070618075122Z0!mÊGCXÍ‘¼´à²‡À 070711151247Z0! ûãA¦ÉÍCy ˆN7÷Å 071002154721Z0!mØ¥Ó#º+ ž2vµPDÖ 071113174315Z0!mâž—Ô{sy =Ý«)‚ 051208215848Z0!môà Éžc»ÿC<ÿƒt 070222173736Z0!nW¤‰¶6ln*•¼.£ 060609060349Z0!ncÑŽa*­Œ.…£(§°d] 070815171047Z0!n‡Nöš°è6›ßd;+Ÿ 070821230837Z0!n‘Á!¹±îOѤ—ÏÜ £ 070509135947Z0!n¶iM¾ëL‘ðåçñ„¸K¿ 051221004503Z0!n¹ç º{êí³>œŒY Ó· 061009052143Z0!n¿h2ík¾¥íÅí4û‰1b 071127142322Z0!nÎøoqy§Ç&П§Îíê 070915193923Z0!nä´â-$Úç6 b£>o 070711151658Z0!næ=sÄD$@²CD{…D 060713091852Z0!  ³&avï/ï—'ÙO± 070228101547Z0!o®¨ÊEù!s5¼ÓíÇ 070502152934Z0!o&q@ŸbqÅ©¯_u"™ 070615070920Z0!o5,>Eó ÓÑѧ¤€¢ 070330115844Z0!o8Jè™Ã<ÝnÞͬŠé‹ 060827094739Z0!oPXq#]@Ù׿‹$qåN´ 071108090825Z0!oX1Ýí‘¿ ¯â{©P&0 060712095244Z0!oz×5Iͱ™ÆÝUÄ\µ% 070711152055Z0!o~€xñ;W+™½×I¸ 070417182229Z0!o2gr‹Ö7«âgرK[ 051227191213Z0!oŠqïë'ìs5"ŒÑ MÚ 070711150237Z0!o‘E2lU ±Ò¿öF’P 061228235104Z0!oœ€‹æˆˆ2á£Qå'_] 070605142715Z0!oÅé:J-=«’í™q>>_ 070629055725Z0!oÌš¨ º2ó$Ð>ݯ\‘ 070312175733Z0!oíkÐ¥¯‰*L‘ëæ 070203055124Z0! 1èÏÏÌû^2¯¬}8` 071115151624Z0!p fJ¥3äw·,œ—6ûN 070418141518Z0!p2zæÔuÑ:fäN â ż 070201093540Z0!p30”…( þó(Ïuú‚£ 070409195115Z0!pt‡cèL›K;×–‚÷¥ 071010131431Z0!pv©`^GÎfaSû&žÕn¤ 071017181455Z0!p{bWiHÞí| ŽÔ’¯ 070711152556Z0!p}ä"æ‡úe™ªùtQ¦„ 070306002152Z0!p‘s«ŽVäØÁ~ºG³ 061229152308Z0!p7VšÂA„#AK¸jƒgh 070711150822Z0!pµ…úŽÈ ½†6²¢²¦u 070112151157Z0!p½ÖC¬Yø¢˜ÜæW 061203103658Z0!p¿TV¯ÐÛ}À)û%­> 070924114309Z0!pïù¨ä ìÍÀÑN° 060320083211Z0!q ±~«Rk]ìÙ³i-Œ 060922091813Z0!ql ¶Æ_“Ó 070705172435Z0!qR‚ -v q¨Àu½Ç› 060704063812Z0!qV&îíÍdh޺ಔ 061113044427Z0!q?Ùvn‚ê±úô¾éXƒ 060222211946Z0!qA)áI+¦­¿ÿÐe •÷é 070627161850Z0!q]±#Ö´ûßÒ©JýÕ 070420132001Z0!qfõ+|Yj‚5HìjÁÏÄ 070618223834Z0!qyıÀ‡—–ì!G®Êb£  060215111546Z0!q¬,ÀÅ}©—.¶ÂCG 070604152742Z0! ^æ*óœ5lo¦"Ub 060921150614Z0!qÅþÆ-éó/Hˆ‰ 070517185917Z0!qÇ‹0e1~Ad)ÖFHÁÒ 071113152543Z0!qÊïúâÿ o7Ì•,_ 070619145339Z0!qÐØV#—+Íl:’ŰžM 070314090850Z0!qÕ è^ž¢¬Òí*Î`Ÿ• 070906103726Z0!qã97iµ'9V®~©2é 070906164452Z0!qé§3Üç«îœá'måàÔ 070827074637Z0!që<K>Ô+õ«=¶Š 070911172313Z0!qúBÅ™3€;¾á›†ûª 070123103356Z0!rŽ2( [ÑZ70j÷Nä 070614180512Z0!r Vã„sÐç½ñí% 060823090833Z0! i`2oäÚÆ¼ðx™/W*å 071023200623Z0!r6}èùÄÂ|(¹QŽÛ 070327120549Z0!r„Û%"¦üvÌ'K¥ 070129152055Z0!r‹¡L¬Ý—9 Ë«W« 070430115645Z0!r³žö ¯ßA檈fÏ2 070913081834Z0!r¼õ†Ú[ùŒ2ØH"3» 070509112116Z0!rï@qô|íÀ¶rBét6‰ 070322143815Z0!ròùÛùÇG¤O©I‹®ñ¬8 060417125430Z0!röÉ5Œ:Z¡ŒÒZ*¦¶ 060823222739Z0!s ho÷)¯úÁý³Îúëû 071127072154Z0!s€­ÁR]Œ¿Å/q¼œ– 061019201223Z0!s"˜½§þOr?›¸aãë™í 060315214657Z0!s%Õ›Íþ6‚h°^7Êϰ- 070913103250Z0!sZÚó …à ­È©± Ç­ 070319111852Z0!sc@Â*=ÐdÒ§Eúü° 070628130100Z0!sjq[Rà£7É5e…ÿ› 070223071748Z0!ssÿ¯u õ-wG_èŸ0 060330063844Z0!sl/ 2bĸWKÏè 070920151209Z0!(£ñpÁÑ/|ôb|ç^Q 061019182347Z0!t5›a6ñ¬Bµn^° 060308181843Z0! ¤wõcνåèlýrÖE 071017073517Z0!tmiȯsúø¢´m|Eg¸ 060105231127Z0!tz;äV‘–QŽ&eÓ 071008153705Z0!t„Þâ`ƒ®N{ÎäþONw 070629014748Z0!t‡…÷FiVã‚@„Ò(ö 070702071711Z0! ª䊕lŒw–(«=d©æ 060320223719Z0!tÖ=>“òû2ÛÁ³BL\X‚ 071012190831Z0!u­±y 0‚KM8x)š 070918121241Z0!uM,ÊßFƒî€$ùº8Å 061113123939Z0! ¶Ø¯s*wÂ3kˆïùÊL 070503104401Z0!u'iÏx³Ñ†û_ õÓ=½ 070302105234Z0!u- Ã2™‰“Ç~` 2o]# 071005174746Z0!u2¸ðÞòÁ›â6Éõç7£ 070905044926Z0!uV\ï'â—÷G3ŒYf¯ 060518142500Z0!uVã1*‡â›¤ðÆàN! 061222190153Z0!u[¾v¡ ä\ÙÛ+“(V½ 060725223301Z0!uqÊ·Ót?Ñ9ZhN-¦’ 061018173031Z0!uyš´ µGl”H j´ 060612162931Z0!u™2(o?ß&¶5^2Q 070131162420Z0!u³r›rgÁ03GÏKü¾K 070604193026Z0!uÒ]ÜÞL2‡úXÖà›2] 071029112908Z0!uÓ¬$@­Öqž 2nUBÅ 070725135759Z0!uÞ€À,F¤pöÇ]~h! 070319230400Z0!uæ:æ4w€Ô/7·¤0jK 071017102239Z0!uñJq­Q‹î¤$B$¡ 070711150449Z0! Íš¾gS«éO|áÜÁ܉© 070206191544Z0!v‹8m  .`Ɉ.Èb 071031190602Z0!v )ÇùV” F6º8 070212181123Z0!v ‰;Ë?é^'9šâÞž 070726160228Z0!v(Mts%Å:Ų Ê.ÂÚ 060604095151Z0!v)/rÏëËz1ËaYÖ:2 070810063926Z0! ÑD(ÒR>ƒìoð 071025222224Z0!vv¢­â=¡ÆÆ IOj/ 070528121815Z0!v}f+bnî…vÝ~üò5 070611142426Z0!v^a¥ºùâÑ/ͦª¼ 061118001404Z0!všçª¬r ¿oû‰‚Òî 070809172713Z0!v£ÒH/,ÐyðÐêÔ,ô´ 070301014410Z0!vÌÜ&g1·ø.ahÖù‰ 060526171246Z0! áu¤&ðŽì][.€é 071112173334Z0! âÔÔ,Ùbn¨"Ó:6 070518120359Z0!váLP®]™qÓÙRêU 060531071119Z0!vïAê3’Ør+oÝ×W1 060203200010Z0!vÿÒsø§"à<E*ç 060920235646Z0!wËF£sytU‚š§>‹£ 070323103214Z0!w Ðd”‡öƒv¸âR–äî 071012175258Z0!wÿ)G‹è†7_K>•  060802162507Z0!we4^uãŸ0Ù€[t¢T 060710163606Z0!wqn­cW;?1iFâ®Í1 070126144757Z0! ôÞ[† ?­9É5ŶŒ  071101133759Z0!w«_ÒB¥ûžT03Çœ 060515100434Z0!wÐk»#óH”@7ר7#ò 070810054505Z0!wЦ·?Lv­Èû8¿cp 070625115123Z0!x ¡ôœ³ìÄFŠ)Ào€ó 070312161301Z0! {Í’(/÷6Ez‘RBæ 060628164332Z0!x$nz6t±œB¦ÍÔS¼$ 060824111608Z0!x,ñÌe:µEÝÔ7×þ 051220124305Z0!x‹åàÕóŒ—fþŽ·A 070917124553Z0! ·L•FGV]¡4'ßÎê£ 070108081202Z0!x´á1­æÚméNb„êã 070201102019Z0!xºÏý$åÑIXÐó:¸nÆ 061214222644Z0!xÝÙ=¥ ½éË–ÁF\T 071120024540Z0!y ¥yfb¨·|бÒUt 060810223443Z0!yQî³½ž.?XœºˆeÇ 070809070125Z0!y™›ÕXàûW¨‚¢X  070816220201Z0!y§Ísü¬éëyÓ¨Õ 070531142828Z0!yïÍ6„hÊ•8© y´ß× 070116075335Z0!yüÉB¦ÐÃÈ·Ê1†5/ 071114202220Z0!z 82‡à>÷GÓt< 070604142254Z0!z cA›?!çóæþGïô 070806101405Z0!z9}Zpza¦_Ϙ?º’ 070907132456Z0!zYŽˆ ¿üGðV» sÀ 070517130808Z0!zbØI([ø/¿¥ ㉠071018205507Z0!zcüï·}òžô@¨È¨Üµ 071017091052Z0!zä~丨·Ñ¡6È‘<Æg 070420092106Z0!z›9›dTö‚ŠÙ˜ó9 Æ 070509215027Z0!z¦ÔžN:ÄR'º,Öa` 061015065142Z0!z´ÏX"WéñºÔ7„a44 070320202035Z0!z¹oy^`v«);¹pÖ  060820095831Z0!zÅðª >BOÛâiÙ11R 070619151509Z0!zÛXÌ«ðòSŽÄ;ÇÑY3¢ 070129022059Z0!zÞÔ$ï4b•à08@úÐ:” 071018105516Z0! Kd¯Z±ô¨=½KQ 060222165302Z0!zÿÚ¨Åõ«w\»ŒPmš&´ 070315162243Z0!{-hqR¶3[âa ÒvED 060925174459Z0!{E‘áÏ7áèo¤Ô|‚v 070711150800Z0!{JpÄ{â`ÍíÄ9Ûë¬ 071123102007Z0!{Ow^)pª¾LÓlšv8 070926230226Z0!{k³Ζ;ºæ±În‡ÁX 060915162445Z0!{};>2 5Bä°¥Ù$ 070223183657Z0!{€’ÉE›ÀüSLiQ{à 070301081714Z0!{“¨ùIpü0¬ÎXõÕVà 070709195821Z0! ]!v ŸN/V=¢s¡ 070321224343Z0!{Ö¹BtèGÔ¯Ê_’òã 061015054703Z0!{ã’>Z¨TC‰Ý–'æ$Êc 070711150329Z0!{êP’o³UGÂYw1i‰ 070416203943Z0!{ëÏäh±&⮺#½àÉo¦ 071107234230Z0!{ûbV‡ ‰]Þ4Ç4ZRB 070307194613Z0!{ÿÜ]£¢(ô¦ß)¤¤ô# 070711151033Z0!| ‰ºçÂêðj¥ã&ç…¯Ì 070928152057Z0!|±·cøùEöiõÆéá 070329120848Z0!|ƒÓŠc¾CˆiáÝ[S 070409112619Z0!|#°ãµü‚tÒ’e4ðÒ 061214113344Z0!|Fc$á6ÙÝ~4¿œ~åž 060328071134Z0!|G3™%v¯Šú™ÝgÀ?± 070124100230Z0!|P×.ÉXÜ…]%y°Ì 070507184155Z0!|^†VƸaÑ#2á 061222084505Z0!|bžœ 7ŒöøbD#®g 070711145722Z0!|zŹY%ï /Ñl­ 060303175107Z0!|Ž“åvsŒN¾cˆâÄþ 070423173957Z0!|² iHC3]U"( 070221174546Z0!|¡J—Ô@Ú]t£Ù 071116163432Z0! {n 3¹TV” 虼ã 060712142748Z0!|ö «©ÍÌ”a`¾W3k 071023174153Z0!} &%:­”B½óŸ ó 060831135327Z0!} ÅV¬‘6ÔÉ{üVõìÍÒ 070820085514Z0!}8Q^H×Zvž¦—nšlÝ¢ 070711021911Z0!}UÄ–˜^Ëðä“Û|1½ªˆ 071031155322Z0!}f.æOÚ¤<±¹÷mÿÓ 070205105550Z0!}uÒB¸Cî ¼'—€wÙ7 070813134812Z0!}{bT5ôEj|ù Ð=_° 070613092820Z0! ŽÊþM«…€á4cb$û 061031165420Z0!}¥ïÊêjo†úœ<)† 060102141356Z0!}®Î˜jÌÄ=“ð‚-¹V 070507155511Z0!~w«ë¦ÜÑ”×Öж 070723152436Z0!~D_|’Öy:íçšû 070614180538Z0!~ ¬B Ýu×Y?… qXÓ 070913070644Z0!~2éjl•”Ö§9é¥x¾É 070226154407Z0!~F0XÏݲª½dÎÄYü&µ 060414214005Z0!~UYV×ÊHã„Ëe–X’Q 070516140255Z0!~k2Õ I±Üò}]Ò@“c 061128223130Z0!~§ tòšâE(çÞú 070614175823Z0!~¶+õbµ*Òé…À 071106133714Z0!~»[µUWJ/4Ø÷–  051215054419Z0!~ÌĨšÚ1)=ƒ4âr 070711151212Z0!~Íf‰â=ýñ[†¥X) 070330140329Z0!~Õ;ÎFÎ&óÜ…Nkùéá 060411231127Z0!~ØÂxt9I?ÎÁ\FŠUëì 060404123651Z0!~îÔ†^‡ÓóÂu¹4ž 070510014046Z0!¯÷|› e’Št¥Gë 070515083820Z0!RÄ̶;àš›L®jÈí 061130205634Z0!1Ë¡²¥€¬Á¯R9|Ž 060510093709Z0!!ïKUff5 =¤$' 060831203303Z0! ¶u(£‚ýD†ÜTahJD 061118001419Z0!.e#ðy¡É,r8JÞ 060619180639Z0!5/¹lÁ©ô Š•C 070903135357Z0!ŽLv†… ºU…k—f1 070403092000Z0!œô\…X‡ñ¥[ÉÒ× 070508091728Z0!·f½} ëo*(R¤ï 061108165035Z0!¸ MÅÄßsA·Õ“ýôV 060316150524Z0!áĬlì—„!­\–ô  070216232234Z0!äewb –µBqÕªf³ 070824135750Z0!ìÒ#™k/§îîÂ&QS  070613105446Z0!í¢öõd% ›ÿ:(r¸± 070327223553Z0! Þ®"£éþD²37NX® 070711151905Z0! ãp÷7¥ðÂ÷ßUÔNý‡ 061114182333Z0! õî~Ó{ŸÉXªÏßi 070919200900Z0! öfkjÖ¥ã/ZÅÃy 060908173108Z0! *Ø@/^·`[P{qŸ°4 060524155854Z0! +toþ4®²H4i!D"®Y 070311183921Z0! Wø‚å—íøœf‘¾ 071108230659Z0! }ä 4«6)”×bûPrØ 070313104952Z0! àjÒ«¨ÔU­­´Ób 070618140828Z0!Z>Òî$úqëÙñY¢’­ 060919114044Z0! – k\c[¹ÓôjÐÖr 070521225952Z0! ÚÒkî»1ïÞŸ¦=ÓÉî 071126153409Z0! ös »¾"î`ég5ÉP 070629190837Z0!qru!ö/'—­¹kí 070621144247Z0! á¹ó´–­ÞÒÛõi' 070131105520Z0!$|‘Ôj‰æ—"ŠÅË6 060602135943Z0!OЫ‹¢ÙËEy%žO9 070924210454Z0!r)nÐt'Ra+ïÁ’åå 070314161330Z0!‹¢³=väÇyžæ¦\Ú@ 071004131603Z0!–Æ<ÜRÎâwV˜ª²õ²¥ 070605160607Z0!šñ¿Š¬¤¬#ô¡xÿ`„ 060727062213Z0!ŸEÓORöM^+„ 070309215851Z0!Ÿ‘pÁE`ª¥4• .›À 070327181221Z0!Ôûtb³„C)|€Æù 060823000005Z0!ôÈ'ÝIˤ$9(1” 060828043653Z0!-k0ö/»hâØImƒÙ 070508020622Z0!/}ØtõÕ°9Ö¶  070924025049Z0!V‘`ørJuæëˆer 060210152848Z0!lŒò!±N•s[ÔÜn 070108194208Z0!mî|6K®ýÁJª/€+ 070208230027Z0!y\G!·üõM>š‹ŒY 070412123959Z0!—vÔ¥x95ÎýÆš˜£ 060216103025Z0!Ø %z9ÂÕäz‰R 070416093144Z0!Ü›’o  hjÿ“ñ4 Å 070604104316Z0!á_«Ç~±Ð¢Ð«Ï:ºð 070308062425Z0!ö*¥ÙeÄŸÐÑÆ Þ•B 070727095810Z0!ùëçi°nV/.yó«: 060926064120Z0!—¾ît»/ìškÇ3cS› 070705172134Z0! ³B^n¿Áá/CÁ)µ 070426182038Z0!Δ6|¶»§TØ´úw 060510065223Z0!9ÒèFGýL{Sr 070103232802Z0!.«ìE³Ö‹/ìø’>Å|N 070327090052Z0!?‘øiû^^éÑ<ÍD 070727153809Z0!lyÓnúÅ—»°ãb?, 070330112749Z0!m­7VßW@×&øb$Yi 060627073612Z0!nXÏÐ:ÏÐ${ÏÌßSç 061205161203Z0!sSy`™G/ dFSPkL¦ 071105133045Z0!tIH/ën7.Û,ÆP 071127121803Z0!~}^Š%ÓC­¬¤bªA 070711152140Z0!¦Î§ÑýÇ ¨ûTÜhc 071109210618Z0!Œ£ãê á'Cêi/ØíÚ 070524095830Z0"ð 060517113159Z0"– 051208181918Z0!ÔÉÿP4ÒÜq ÚRެ 070822232528Z0"%W 051214020048Z0",8 051130160119Z0!¯s¢›ÕÚ1tç×”‹ 070504220409Z0"0ÿ 060809171134Z0!ÞóM%…¾®÷R ‰µÖ 070523220051Z0!é6ìzˆØï–àà×O ÷ 070509211108Z0!óëo³A!Ð$Á:Õ÷Ñ¿ 070806152253Z0!õ@‹êŽõíäŒpj„é 071115214830Z0!)®³ÊªŒ§lª˜1¨ƒ 070228140358Z0!é›!)ãâÝü÷N>øœ® 070316102046Z0!RÔŠ~~—¤æspˆn¯ 070711150155Z0!5Ì×!{\[˜µ‰ 061204193343Z0!!koçsLzê5lavr 060301193412Z0!$ËÚ©}aMiÑ ÿÑ 070507053811Z0!'X\²Rž£ºc鈯eàÎ 070925080019Z0!wå1ËÚ'#SÕÏÜïm 070430090321Z0!{\E„ð›ûþ/ïco–ª- 070403145148Z0!ƒâ‡¶âª›9 ŽõzZ 070507183726Z0!Šfu ¥iƒj©QlÓØDŠ 070412090451Z0!’hÆ ùù—Î?gª4 071106080047Z0!–ïu…É ²L¯}oÝ 060711062645Z0!­.ï``€fzDK´~u 070924052033Z0!ш/ž±ù¦)¥Ó×Q¬B 060411124702Z0!ìT¹å¶„¨¿‡êÆ£˜ 070825060018Z0!Í@®€>^*Õ`€–E½ 070426153855Z0!V­Ò£õ˶òZ¸Ë 070213200334Z0!Ý— ù˹œþ×0Þ£ 060516102434Z0!‹»ž†Ù¸"†\!([: 071017163946Z0!!öñÃFúÈ~nv»óÕ 070410131546Z0!,Þô…¤A±üµ€ÜÁƒ 070614180814Z0!Aм7A;@êètØq÷QÍ 070412090739Z0!aý»€lÕn!¯&è“K5 070626165549Z0!b·s 060523165148Z0!¬˜òF*Ÿ-_Ûe¯ 060517104829Z0!ìdš<éëhºË@ÿ 061115063113Z0!þõN/œ.²? µÎ¶×¡g 061205154418Z0!ЙÃ7в À‘\r“T” 070621131104Z0!g5¾£íW¯PôC@à 061005154817Z0!3š:Óì`9È a±Vi 070125091019Z0!G AŽo€EôøwŒ”€Õ 070601104555Z0!Hm#\v9Eh¨ô |Ÿ 070424094417Z0!Q…œuÿ¶ý<‡EÆZ 070430191431Z0!^¢ïXID?ÕŠ–J¨Ü 070820101627Z0!` âö3‚oI«œ¹ ­ 071024230953Z0!X¸Î‹B0W³¤'ÃQá 070403063043Z0!{vÉÆH³À†¢0µÊ 070919100308Z0!~j38ð<#é)nä 060213152153Z0!‰:èÑ?}ƒZÂÊ… 070125095759Z0!ŽìdÈñmE‚ Å+uÊm 070503232002Z0!™:IdºéÌ/j³ñ·  070412085211Z0!¡ˆ’‚kzˆsŸE—6Í9 060614174745Z0!̇'´«JÒø=}(ƒ}Ú@ 071001084047Z0!Ñ6å¡8[ìM¶ØË’7G 060822145503Z0!öŒ8‹¢tQè ;øPÿ 060905161056Z0!ù"ö u ÊRL³!ód 070815145259Z0!ñšñdþ¯û8z& 070405164559Z0!ÛšØlf§^òŠ´Ë¢¹ 060424092554Z0!ÞÞr ÂÀ ×°Í 071106033937Z0!»7ÖÂE #} Z 070725081658Z0!56f ¸½úiÉ•„ 070411155304Z0!`ײïÍ3'¡5÷–V )ƒ 070312180403Z0!lÚ†‰ï.Œ˜¦ß (ï 070712172732Z0!{ø¡ã]^wu¸ÇRMõç 070315142147Z0!Žø„fº¬JÙ/‘ón`Æ® 070625151609Z0!·ÇbPÙJÛ®fèGåZ\ 070928083554Z0!Í¥ýT>‡X1—§ìòˆî 060329205537Z0!{ßý™c¢&”LâL\fSž 060328181138Z0!Ýñ7KÙròF"àRÁY 070322101431Z0!öq½,á$ꆤçXÂ)ó 070203053946Z0!9ŒÌÝ>ÞÏ|“ 061208022838Z0!‚ÇIšÈ-TTóä{ 061123194443Z0!*Σí]¶ÀoYТ¥w 061201112855Z0!>´¾·¼QšÏåÿ„³ŸYˆ 071109202103Z0!B'»Y ¥¿ŠxåLîg 070531180934Z0!\y§e{3äqÁ=ÅÂ¥/ 060919141339Z0!zV“9›Oöj‚<{µGÄ 070611194343Z0!ŒÂ÷¾¯&" Œ’yÆÂ 070213231728Z0!Ÿ\ýræÁ#otYå-¬± 070727135507Z0 Bº´FÒWLÇ7<’TÇ— 061219202516Z0!×sؤÒÊΡ» 070322144938Z0! NâfbA§ËýŽéhÛÓK 070619141650Z0! §åCâ[ kõfq  060907165301Z0!+Šr0¡ˆ8€ù ðÅÜ 070611231351Z0!39Áä™ ž…Õa“•‡ƒë 070911192100Z0!žÜ[NÀ‡¬(/ Kxd  070525083044Z0!JŠLI·|$:¶âC 070816150836Z0!gFÐ ÑT]Añ‡ÿ 070208223813Z0!ƒfU(3ÅÜÆóì›ð 060419111941Z0!¸©ø>'ZOoê§ÖÁí 071004072110Z0!¤b°©Û,Åçhéš… 1 070711152523Z0!¬Ü)5X½ ô³Öj ‹Ü 070108204556Z0!#™Œ>›“·Ën÷1ì› 070810130620Z0!;u*šæ2$µ–(0àÍ 071019200512Z0!_ ÔÂTÿ;+G} ¶ 061213195730Z0!_¸ 3O-³<ž½Ï]© 070621153947Z0!’à U¨h*…¶qoYŒ¶  070811201023Z0!“I'“;Å •±¿“Ä04 060618193552Z0!¦3ˆiCUp(ÄšI 060919205054Z0!¾Sß ¯O:ÑpS{`E›[ 070109024651Z0!Ö‰/©Ø÷pïž?#I 070212162206Z0!ȨºÉpŒxìfÁ@¸Ïü 070214125643Z0!ç;zÂWà‚b¥í¾ck 070618165602Z0!è†Ù0/—ðÌ÷IcVú 070420011102Z0!ëÁSÔ^`|J'Yµ2:F 060328151446Z0!úi'1ž½ 9Õüùž†æ 071122102624Z0!9»h¼+Àá¶@Üö)uÑ 060825004833Z0!:Ê,¶z$M¯ð©.Xù×Ñ 060124012357Z0!Q¬muÇÉÞ¡ôò9É &º 070126152026Z0!Øt<æÕ)+ØýÞçÎ[í 070807211257Z0!x®»÷„¢?:<\PEq 070312085636Z0!p\fñÅÏYi’J2RÁ 070625115148Z0!$Õ`7nLi%Õ½'4ùL 061030215920Z0!2daÿ•6ˆß”t¬½ 061228024210Z0!HÆÛS¤ß•…;g~h[@ 071102160215Z0!Mf€ÆËô2¦¢ÆÔdŠ 060523081943Z0!`[9±+{Fˆõ„·‰™ 060124160636Z0!igÁIhùq·y¶µ 060710182805Z0!j°ê2 —ŽÏûb¦ÅÁ¨› 070502140447Z0!kÑPPõ~FN s…o 060519201038Z0!u3ú\Ãè¶7—' ?f 070917121816Z0!Š„Ù ˆ‘Àí¬Î¬S‘q 070817141926Z0!ôÜHb¡.¦à‘Â{ 070711150524Z0!³9_bº^\oæ\zEcB 061130125354Z0!¼ÌUnïNmôCß_»ô 070614124012Z0!Æe @»Q_áÁ+숙 070316173309Z0!È“Ëåû0á#5™ƒ=ÕZ§ 061016114340Z0!ç™^¹mÐ9—¨h„<â 070213101512Z0! 7ýÒ6}¸óÙ 070328005050Z0!Žg ÇSlÒ±ËÍ J 070210014355Z0!…Òô.=¤ñ}Ÿ 070424100046Z0!$—Æm½Æ=Œù"¡¹?hb rQí 070504082210Z0@,> 060128203424Z0@8W 061010054901Z0!¯áµ›¶óÀöj›äÅÚ 060614171655Z0@Eù 051222195511Z0@HÛ 060307152544Z0@I 051206100221Z0@L 051130172552Z0@La 051206012504Z0@M' 051201205349Z0@O' 051205111927Z0@OF 060125100819Z0!·qŒ© ÇQØOÿ ²fG 071019004008Z0!¾ŸžÀ´É©ºàeR¸ 070613141544Z0!ÉûK (Á‰¶´ã„pYß 070824125811Z0!ÌWî´ˆbæäú!F£÷ñ 070711150413Z0!Ï.`ôXÿüêQ{š4•b 070227120230Z0!ã-’›?Ç™ëv¢d8ÅÐ} 060707090350Z0!ùû²Ú±ŠÏ‹gõ 070731205225Z0! ~ÓP¾nsB|/L¾ 070622091758Z0! çÈ‚ÔùscÆÇg5Õ 060516131449Z0! ö'Õ¾¯ëÆg<÷[–·r 070824160455Z0!4üŒ}³ã8ܸMpã¸< 071031184539Z0! #¾Ô61|jðD‡IlÚ± 070606162545Z0! R»·t&‰Óâî†áæbe 060315113140Z0! ]ý;¦€ú¥ÈfS7»_Þm 060919185938Z0! bDÞ‹À )òxÚÍÔ¾^• 070604121941Z0! ]ñ Ìûgß\©Wî*du 060710232720Z0! ŽmßeÔ¡s1Üží/Þ 071003131908Z0! ¡0Lň)ú)#÷Fré] 070604145528Z0! ¡^„6AÃ;–|kƒ}X 060517212537Z0! Ö㌦ЖNö×Í8v.ô¨ 070731205249Z0! á샱Ã4€ùe‰—[ 070301080156Z0!!ñ#X£›_Îcº”q 060921103145Z0!!Ùj¤d1Âàql¦:ÉY“ 070110192322Z0!!>-ªx'W{r¿–ñ©£i 070209121025Z0!!4-àˆæå#‘ (êçÏJª 070302115021Z0!!I&À7èCÌHøÖ 070511113150Z0!!K¤µÙf°ØõŒæêše: 060515075924Z0!!dü&qCÃÝc8±8õ 070731143145Z0!!qàÞÎó÷‹‡mݯ¬ 070411123723Z0!!u P.2¦ËšÑ.†— 060706215225Z0!!‚AÙÇì´<ܺ|'èIÍ 071029174058Z0!!ÌÁ ø3⩜† 5‚Jw 070711150431Z0!!Ѧ,’B D7›ózЬ 060209082411Z0!!Ò†¸w±¥ð‚T¾áD‡¸ 061108000453Z0!!Òïb»¤¹Ôã¡üÔ 070711151333Z0!c6 z‰WuO j8¹– 060126155951Z0!!ú ÍÆ2þÉÔ$V.0¸ 070614175745Z0!" "ÅáÕ%Tfý`r ¯N 071121154756Z0!"%sŽ»5…‡è, Š1ç 070305130450Z0!"@†‹×R¼©Rðµ`PA 070711150134Z0!"L¼I öÈðæÙŠÄ‘îŠ 070827104151Z0!"Y#t\;ÈŠ”Kï”âãæ 070717171435Z0!"eò/n #Ã|1ñq‰ 070108223133Z0!"y ~œEº9n‰" 8$ 071116163305Z0!"0»3ošÆãíV´Hfš 070301103724Z0!"ˆ+çý?“ø!¸Áç7g 061218100222Z0!"œr`{¯ENÂö1{E&  060724151259Z0!w¶DÈùBÌ›ØWv&9Òï 060828104634Z0!"·rXÌ>’/&P<FS 060705063531Z0!"ÏLÝ÷ˆ‡“ƒ=:MÉœ’ 070302222822Z0!"ð@ƒðªhHìª&?6ì 070807140409Z0!#¾`³Âßl¼uœ4¤À¤, 070906172905Z0!# Qä­Ô)¥»_ŠOÄ>=à 070102200127Z0!#C Îb)µ˜Ñ µ 071120193927Z0!#_7Qlç—$‰ëljW©V 070118055638Z0!#cUýÞ1® Ę»f›ˆ´ 070906235828Z0!#m\~ŠÄžÎý¿eå¬üŠ 060719105315Z0!¹lÞVqûÀÔƒ{hǸ 071112173051Z0!#’¸çuwOÅy)9ämù• 060109080014Z0!#›•2 Sõj7¦ñ_Y! 060803155417Z0!#Æþy3’¨nÅ™ 060919110837Z0!$ô'p À4uSµòæGoj 061118001233Z0!›&‹JöÉNx÷• 070502102117Z0!$+ZšÅ}sÍ ÆK¥á+ 070119150537Z0!$0¿ ‰Z‘â‡ê7C”‹ 060629081535Z0 \üTð’}‹-¿¹Ú} 070405074128Z0!$f`ä¼x {U±·ÚQ€Š 071003200259Z0!$l×SÉî9æ&Çï*¸â¸ 070928083716Z0!$nˆ>KéåfÑ“øÙø„[ 070206171657Z0!$uÛ¾'<ÃH»Lt½‚8 060405203645Z0!${…ôU 060213224348Z0!&ÄAkŸ«ÒÏ_¦Ö˜ž 070907220235Z0!&^¤¨™ÿÜwzØj¿þ 071009063008Z0!&o¹ëŸG$*Ž•+»Ç 060106065517Z0!&yÁ{1„½›Ù7¸àÙ]¼ 070709073959Z0!&wRZrÀ|¦ÅÉ*)´ 070711150015Z0!&•¼^¢5yÏYß6§jª 061016121447Z0!Þ¾Uø!z›‰sTýx‘µ 070711152628Z0!&Ï¡'ÏIØÑ6s0ÔR 071003120756Z0!&ÚuZjÁ¸eýçM—[€~ 060516190900Z0!&ìöX9©»| "¸w¥A 070723124253Z0!&ùi} “ùÞÀ ­ 070710081047Z0!'KÐ’Þjb~žôÏÀ×_ 071112223007Z0!'Ú÷‡O'É´–ì•&K¹†Y 060428115730Z0!'Þa'è H‘š¸¼ž;} 071024125122Z0!(/BmÒŠ0iàhå§Å 061212181946Z0!(9 ¤fL´æëþCÝÂà¼} 071025022348Z0!(HcO÷°;è ì¹r¿ 061214185800Z0!(€ËºÀœâö ufÇ/B& 070216235606Z0!(•Å~ŸÖ@ûÏqß®ô¨ 060728163256Z0!(–ˆKÁ÷ ¢Øë: 060222173812Z0!(—Ϯ«’Okðÿz滞 070524122044Z0!(Ÿ3é _’„µ@vÿ\…Ÿ 060922202233Z0!(©>ÛC%‚RâP¼;ÝÞQ 071026131226Z0!(Ó‡û¾¨h¬3¨Â¢Ÿ¾+ 070927071910Z0!(à*êKO?—‚ç£èWx 060516220634Z0!(몔øÇ·³N\Aq{™Ý 060328153915Z0!(ì(þ$5z#Üiõ·Ùº 070723110854Z0!(ñ¨šZÄ cÕ©$¶› 070702103001Z0!(ø,F#)ç´¡OÀÖ¦¤ 070522155535Z0!),ŒLkªÎñ„o—ˆ 060802150446Z0!)6¦vWÑî|_^ÏÿÀ4ZÍ 071116173530Z0!¶ƒš_úçó·Zèá‡bY 070228151023Z0!)Z @Ó¥ê+¯²lZôM 070614172602Z0!)_Bõj.Üèž/ ))‡ 071127145059Z0!)bºØ¦˜Xƒ*\UÇ2É  070709140311Z0!)xÙ¯?ÜÎþ•ŸôŠôˆ‘µ 070711151145Z0!)zR“ÂX(ý§¢ 070629002500Z0!+4§ZþþNòƒ §íµú 070316202028Z0!+ŠœÉÒC} щsœü¶ 070214201429Z0!+‹xä°oÒ›™ù*G 060718092249Z0!+™%kÂȱPñë-+Pq 061114072322Z0!+µ¿yW=¶ß¤=×FŒvK 070703200434Z0!+Õ¦+_MçSí«ZŠÂ׊T 070703200714Z0!+Úý¼N+ª†ý5/°Mé? 070529214352Z0!,ï1ïCÔu`Rùž¿å 071029184640Z0!,Ñì²Á|r·)hÁ8 070126034152Z0!,>ÂT n'+Žô§-†JB 070517204716Z0!,@·Ðl]Þ¸Yà '½ÂÒÁ 070803181429Z0!,dz5¯IKc-K/ 061124131910Z0!,{)·³A‚ù6º,Aäå 070313201635Z0!,›g݋厠Ñ[£ƒ‹lñ 070912204452Z0!,¡ÂK[Ê»–”rdxº‡ñ 071107201220Z0!,®B 6@øR‚kÌö 070621162025Z0!,¼`Ú[MEº*+VN”/M 070827141500Z0!,¾No^Ì ?R’¢þ€ 070212200432Z0!,Ë”Øå ~ØÅ vÏ[ã 070628132009Z0!,Ù¯òªZe0Õªz§}E 071115181659Z0!|Ð\…hÜ/eô;Ä  071030142828Z0!,᜵.KX0÷Æ+4˜(© 070711151313Z0!-¶ÏÞCëÅè ‰~¨H3Z 070405220129Z0!-#äãÿ¡þÛO-*0©[« 071016100019Z0!-%dH 9)ŒpâJ§HEƒ 070808152304Z0!-(%ÇÌô–Qð#’ò>ìl 070614180036Z0!-( {Û¿™„ïÐPþE—¿ 061204151054Z0!„²"h.Ï9ƒß"·Wˆ 070321133009Z0!-Nœ©ÕÑÀÄMöøs;ÅW 070822201402Z0!-SJ5£G ÇÅ»*BšÑ-0 070724175814Z0!‰±¯šîW.n‘’&õmé 060308223343Z0!-pþg$'+gÔ‰`Þ¾¯ 070711150859Z0!-xm¼óߪæˆa’yš± 070124143213Z0!-ƒ¿`U_­O÷<ˆè屨 061114212641Z0!-˜í—dÀ¯º÷ÕòRX  060803131847Z0!-£*7 ý °.6h.3 060123122318Z0!-±Ñ ‘ª_PÎi±µ;gÍ 071001132304Z0!-¸x¥IJl6ÃÜ 5à'´ 061110124601Z0!”ˆ±„„¤ ÷ÁŸÄ• 060213105857Z0!-Óš ܦe$é Kaé; 071127144118Z0!-ò"NðŸ—I7p>‚ªw¡L 070504180838Z0!.)›¥¸ŒßÑc»2ê !ø 070329110738Z0!.R=»I‚ÍÆ!r¹·ª—Ÿ 070306192243Z0!.SöNŠ´9YÍ0Wç3`ã 070517193045Z0!.Yzûö •÷|-³2PÇ; 070607014218Z0!.\$ëvÅHÅ[[ 051208102758Z0!.dfJiæz{úyÐ@„Á 070625142745Z0!.˜©žtÿyÌJ⮘ۘð 070521210118Z0!.™m7[âN‘³'UŸ6pµD 070711152011Z0!.Ÿ²=¸Í ÓF1³æ 070803192205Z0!.¸ªŠGž-€8_þýz 070813181348Z0!.Ç!%AVi?¼Q×›bq 071105061116Z0!/Ûøª£ÉW \,Œg 070416184959Z0!/) ÝxÑΠ©%hP 070430230111Z0!/#×uT¿úfôo>ã§^z 070511204212Z0!/3 škñ:ƒåi[’’ù 070323133848Z0!/:îµÕ>®Ñ‹íçå;‚k 071002074538Z0!/k¼Ù¨€Ô+¬½…š 070306171547Z0!/uþ¼¤ ®8^êßLùU 070906201011Z0!/vEUÞlèŽBh[X 061221172725Z0!/ 2*û1e $ô­¼J 061130130312Z0!/¡âjM©Ž4C€ò¸ôJôÇ 061011203641Z0!/²‘SÎ~â|×ÑjZEY¹ 060119173043Z0!/¿!ì Ÿ©S“@}º 070523143149Z0!/ßG¹–ŠÇ‰ƒnÓüèCß 060810093209Z0!/òâ°sè‚ô(+e' 070607160511Z0!/ûbíütô¾‰ ÍSl›âf 070205102851Z0!0Áˆ5…«{6o¼ÈÊÂÖ 071001153838Z0!0¼û¯fžÒè“ ƒª 060415183730Z0!ÔïÔIõ Bm"Lþ 070921234327Z0!0H§£ž‰4ÑÕ 1vóO 070604185827Z0!0Y&“%W™.Èœí2 060414181252Z0!0\^ö?­™%Cü`ê©õúG 070711145749Z0!0b¹‘Z YÉXʼn6` 060720142813Z0!0Œ?ÔQ¶`è€üs"ß 071102201846Z0!0¼„Ñ[­ÿ*¾òÎk½;U¬ 061114181039Z0!0Ê’žK¹®É£U@8–+ 071018230323Z0!0ÿËsQÁD‰qTkv 061206134404Z0!1šF ¢ñbäôÝõšR; 070924180213Z0!1"b)Ê_ä0¸ý|‰½æ. 060823080959Z0!1_²B,sÝUÄe¥kõ 060505084942Z0!1(í¼Ó9r>ãm[dE 070125205741Z0!1Q§©¹\QC;6º (>j 071018004715Z0!1V³YB Ð? uN-q\ 061214215210Z0!1cäw»BסřùÉÎâä* 060929071147Z0!1mâ öî㬷˨ìÉè 061128085806Z0!1uµRƒ”6‰×eʤ9y 060524190103Z0!1zÇ…¸Ê½C$Æ à›æä 070914124957Z0!1¸lÅM±ÍΞ…¾¢þ 060405100135Z0!1î=…´VI´5û#r*I 070711145825Z0!2œÍí„¶ž±új˜ 070621164346Z0!2 œ¹!œôÔ÷É7ò¹Ð;é 070226154013Z0!2}ùr*(µ†’iÔ 070509162918Z0!2@ °Šsù§Dd ˆéãž 070711030546Z0!2cÃ&£È^÷ '[Ôª„ 070104055912Z0!2q‹Ð‰éGÜÞ÷óR$ 060125064109Z0!2…¦ÔŸ3FÄCGÊ|—}B4 070108220424Z0!2­ê)%oÜÄ3‰Ï5)Ïø 071108194012Z0!5L¦š¢?Øú%IÐ g¹7 070323072506Z0!5OÍÄk¡0èidS‡ïÁ… 070302060454Z0!5Z½¹27í9ºX«³` 070510072005Z0!W€®yÒVYp’$.’œïA 070711152542Z0!W„eêª-CLÅŠí^!Bl 070927050455Z0!50Ò&—¬ZBªÝVô 060523093609Z0!5ŸròÂ¥À{MfUJ\ › 070509223919Z0!5¯®N'ªý ó}(Ç%‘î 061019195732Z0!5¸0Ñ]˜ ZòÑ oZ 070214141135Z0!5êå}ƘÊKUÅŽMÔ¢1 071018164944Z0!6Gºž§ª-«xi,?*{ 070711151529Z0!6)`„ë¤)ßùÕ´÷ 070308185238Z0!6Aj¡['[»‘~\ #eÐ 071003205727Z0!6QÂ?(qáp”R¯ 070313154730Z0!6Y{TàÈÓ`ÖA Þ#z 070516185527Z0!6Z:gÀ»=:;9Q‰6òzè 060217145250Z0!6wMœ‚€ï^07æ\rÀ 070816133427Z0!6œ‹aèÊéL¬1d©ÔÉÚ 071025121730Z0!6ÖG›Z϶GKIX 070404152923Z0!6ô-KÕ€¬ÀWŠšôf 070120213636Z0!7 ¸y 9õåç­S¨…ŸÜŠ 070410195103Z0!7 úŒæxeâ«0ÇòK[ 070430235540Z0!7!íÑfà•`²šæÞ‘ 070516135225Z0!7%´ú¹ÃNA\"d§­ 070529212029Z0!72ùJ~ejÊ:½ÐýÌçj 070309194737Z0!7F¸õšC(ýܘãSJ‚ 070108100857Z0!7Tïï]ÉÓXRú¡ 070320081133Z0!7Yù§_×ÝÔ—oA 071004131235Z0!7rŒÌg_'Ùå+ÛF÷Í; 071025160346Z0!7‡HãlÈÌ=a;w77D 061218131755Z0!7¤[“ldñ‚¾b±—yÔS 071010131402Z0!7Ü…ƒ-Ãî´÷ž(á¨èºI 070131101747Z0!7íí |òF—lMHÒÉ0‘  070604191232Z0!7þ1¹‹6–zÙËZçàa 070626121954Z0!8a¿mÚF$ÇWTVÁ¦ 070520182659Z0!8 8d (ï†SBϤ 060406084155Z0!8FÔAõ+äc'¯ô}çÄ 070205200746Z0!8_^-ÎÇènicç¿’… 060525131158Z0!8x„2™ŠIâU UF« 061110155032Z0!8~§(<OÊŽjã]÷Æz¬ 060614062927Z0!8ˆ»Õ§ësl€œANÉ 070831171929Z0!8’3ô$íꨙÙí‡r 070719015155Z0!8§Ç?"•Ø´k䣱Ü 070202090246Z0!8¼×€ÿƒ€­^Ô˜Ó€Ýj 060516060422Z0!8Ñky D2þ$ÓbàÚ¥[ 061229161352Z0!8ýviUåz”cVöR|ä> 071024125946Z0!9äýËÈîíWewk‰´! 071102225701Z0!9Ýã õ³Ç Á¡ók™œ_ 070125225827Z0!9 …à÷cvÂëgý'Œ 070227131709Z0!9 ,PˆÁűÙÃŽ‰£ò,` 070306132702Z0!9V‰»ƒv@è)‚˜5ab 070924105624Z0!9[Qg)\jÞ»/ ¬¤º 070711152250Z0!9igª¥Øî(XÊ̱/y 070915182618Z0!9r}(ŽúüÑ~õ7äÍ“Š 060714164432Z0!9~‰‚¾ŽTÃÒ•`‘¯+ 061211145647Z0!9 ®7Èþa4`¥bf 070716222829Z0!9’ö(µ—[=ÖT-ÄÑî 070801003122Z0!9œ¨L>sÉë·u3Hi%ÕJ 060316150738Z0!9ª‚:ŽÄ7&øZ…S†æ 070314144417Z0!9ºü»Ä3çt,%zÒÜ£ 070515085145Z0!9ÅK{º[_ñRM¸v 071114173235Z0!9Ô/)¢axW¿Ä‰%>˜w 070711151731Z0!9æzb#T€1)RÞâBÚy 071115230557Z0!9ë[ÛX»âkÃK4¹¯¿Ý 070208144803Z0!:Ý4éÖ>ìÞva”]…úT 061113140116Z0!: Ìæn!Š25NPf\« 060918123026Z0!:(V„7“•'<D¾«°Š 070926152244Z0!:+öœÆÅÛrB¿FË”ežb 060531075659Z0!:=™Áp5W&×+dëë„ 060320092952Z0!:N·”×QôU¨ê@,8U 070927143623Z0!:kÁLk†päïÇß Sq¾© 070301080019Z0!:nA­4HTæ,P§{© 070501092122Z0!:xŸåF®/¸æ5Ëô&£ 070711151822Z0!:5÷lkWò”Y“»Uzÿ 070424143831Z0!ÛB¹/« û(cæE³— 070711152305Z0!:ÂÑî Ísn£.u 070803110703Z0!áGÒÆí·Ç¾È»Ë~aÜ 071114170217Z0!:ãr{"d×Ãш·ú Øú 070912064151Z0!:ím™ýœÝñ™©§S 070629101224Z0!; O± ¦ –§dâ¥6 070706180053Z0!;”RÅÓ± ·Ö–z âQ 070621154616Z0!;+06’æI©Y´N U¶B 070726180411Z0!;Eü*¯ åüšòg?žÊ9 060404111404Z0!;e[Ô,V”8{}SrÕ{£ 070711151840Z0!;<©­?µkªûƒÿA‡±÷ 070711145936Z0!;ð$¹ F~¨ñÖ»“4. 070411162923Z0!;û^'vã¡R:¶¤` 060214144212Z0!ÿ×5±¥¯3ç1îèq 060120151308Z0!<£Ó2¬'Ã)ü¼ª2( 070130112152Z0!<Ž¾Ê à…ï(Aµº=< 070404112850Z0!C— 060802090452Z0!<ïJ.ÏÈMF.ÏÜ\Çòé 071031203829Z0!<ó™¯Û!Å"Ùi âM¶åJzY 070822142831Z0!>&zl F“•úDa…£e 070620123640Z0!>;Å ¦¯-ôª´„kg 070314185841Z0!>@½ U±†*Ö? žèŠå 070207175231Z0!>B¤‘BLΓ”*4!¯ 070726073217Z0!>Q‚üé¶=3PÜÓæû 070331202936Z0!>jÅìx¾?‰÷Ø1×mxK 070906051121Z0!>lï‹¢£LeT 2Z2õ 070201182853Z0!>†ቩÇE‘¶8. 070214214122Z0!>™H¤r®ÆyÌ#+x¤ÇÛ 070928094055Z0!>šå–Wóê½®†‡‘&HgW 061116182559Z0!>¶)á 0?q{”‚9 071012215351Z0!>Ë-ÐM£YÚWå!ª+ 061219193831Z0!>î°ø»x†þÍ8ì# 070402055413Z0!?°rÞÒ¨h šÎÓŸ·' 070309084344Z0!?ª·ðÏFÐËå¾uæ^  070516160655Z0!?5¯ ã@eäøÖc@¶ 070418105327Z0!TIÁ]¿è–>hQï9ž 071006054914Z0!?OefÕ#ø¹Æ‘@bN 070524194742Z0!?P1P¾Z€uñ£ßí]aO 070405173549Z0!YuÑle_þ!K}Ù e˜^ 070227151145Z0!?½Mdm}Bhl]CVwè 060517113328Z0!?Íò‡ž|Ué3†x 060524045228Z0!?ûÃ/F!«³~üˆ=WB 061123091343Z0!@á*tã.O]Ü!/ȸë 070813155118Z0!jQ×FîT1úè&ÿ¥Ôj 071121154731Z0!@YLg~¹Ÿ%@6šy5IÏ 070525170246Z0!@c70áöضç&;¯ÊY1Þ 070402145748Z0!@f-"°ÀwÐPÊOOÚ?[ 071018004127Z0!qG´›óA$‘ªä£œ 070823123127Z0!@nÑ­ÀÑ$ëßêz}Rg 070122215647Z0!rGÇ=¬AàÖ¦¡5 aä 070518200806Z0!@}_oN‹¨|²aHlG5´ 060428084819Z0!@¡ /îÂô¤#5QøÛF 070129222244Z0!@³Cªñ$9\]Ý0a  060908161555Z0!@¿™ ”,|\1ìÜ»òr… 060807232125Z0!@Äv ÌZ†óY9…¹ƒÆ 070326111853Z0!{õµ·á‹;¢ðpCm-Š 070301091153Z0!~}cxNQMS¢ óÊü 070709101418Z0!@øâðž|VÄP¿ZAå 061212040353Z0!@ûZhöá§7 ŽÑ_"- 070706085307Z0!@ÿäé²ÏY97þµ" 060510143848Z0!A¡žÉÙÆ<¶ [_b3”š 070725121224Z0!A}êç&syXö]ÙSû 070319142107Z0!ADCî.ÊPñ»×R 071106133600Z0!A)“@Ç©4¹#èç ²º4¥ 071109000250Z0!§÷Œ#Ú¢õµ•µ–ˆ« 070822014658Z0!AIuù4¥ËpЂ@,’{8 061010185512Z0!AXd¨«ÏõÚܺ`ƒSÙ 070911175550Z0!AdÕüù13ÈÊ›……<"õ 051213011307Z0!Asÿ#«E1R³\|(‚Í 060720135819Z0!AyŸ¦ä¡´ÿŽê|Ai[Ê 070309084241Z0!A©lÿqV%Ô½Æ.Új¹” 060920091940Z0!A¯ÊïsלšïEÀyŸÒ 071115202543Z0!A¼x‹ŠÃY{=/Ô¬‡™qø 070125140056Z0!AÅ7ë _zBd"èm[ 071015201953Z0!AÊ>^¡÷™ItAŸ?Lœ 070326105640Z0!AߎïcHs6b3ÇØMí 060421084852Z0!Ðßì`¯­{LŽý‰R“2 060201161738Z0!B5ûD¡2zlS½}ÞåÞ~h 070626183246Z0!BpÙFØÐÎx#ƒî"– 071022081808Z0!B„Ÿ–MT ™ÌΊ'Í 070621145229Z0!B޼xøóÍ-¨'ÍÕÇŒ# 070810172133Z0!B™¯:á˜pR¾°ñKÁfí‰ 070314180257Z0!CM󷻆_jj›e32L 071121035721Z0!C Zpj®z[hœw‘1ì 071010131915Z0!C+ìÈ›Ìì ¡Þ2å5 070329100219Z0!CQLSÄÚ¬ª(Æø—±¶ 071114195954Z0!CµRï0nîð½ëC“ÿhž 070619133801Z0!Åëµ²¿¦€ ë>Õɯ» 070314144552Z0!CÇö$)Œgò+Ñö“2 070108161318Z0!Cÿ§Z¸‚/T¢Î 071101061638Z0!D†@ßê8'ôk¿7S% 070124224117Z0!D Þ!·1a9åïÆ,¤¾ù  070604123338Z0!D!õ¹ws)¾9éfâi  070403092803Z0!D7–×6x)2£ùÜ' oD 070711151048Z0!D;£W¦MgTv›€qFÿ§ 061208021922Z0!DP¯kMö…•\EøQA 070711152025Z0!DwÆå™( ]³7w’ 070614180414Z0!D„ê¦Ëi’È^Š·S‰ 070613034047Z0!D¢¶ªžèpäâ(yΪ 060112162000Z0!D¤ºU̘µy~‚Âc0²ï 060523210500Z0!ݱ×å¼& (ú"ß 070711153800Z0!D¿7²«Ë™^bmô€ 070413060559Z0!DÙzCÅ|SEî\ýxu  060206123021Z0!E8M¾_À=wýðE 070614175719Z0!E–ëí®ˆ‚hËz 8{t 061025181803Z0!E"œëV;!Ô×taRöBQŠ 070614180446Z0!E+Õæ¹Lø‰é+wû Ó 070309213822Z0!EJ Âdq00i©+öpQÞò 070605222040Z0!EP”¡+|ĺÔ4k‡ø+ 070614180639Z0!EWÀCëa‡T+½úFÇç 061011135932Z0!EjÉodf-ÊîÃýÛì›) 070307180559Z0!EqÙÆ©÷õF{·mÙž 070127223336Z0!E|Ïi9òOÔšj -T 070711145918Z0!EÅæüÅV-Ô]ùÂú 061110164734Z0!E¨ê¡´´Q[ªD¤¶ë· 061018190541Z0!Eª­ûB«\ \GÙã Ô„ 070515234957Z0!E¹¿õÑ:©Es:p‚‚ 071123230751Z0!E½Sè¯èã*¿UÃ0N×Wm 060425113543Z0!²Á¯Ñ²@¦ŽôFÍpz 070423192717Z0!Eï.˜´Î–RGK;‹¢È 071120234727Z0!³ëñÄÁ¦e+sœzùÉ 070302021543Z0!F'ëX–œfX 粩%Å\ 070720170316Z0!FÜ.Ø£^#=ÒÔ´Ú 070209104442Z0!F2St«sÁPlµ3|Ã[Þ 071112112338Z0!F=ÖC,éð”§3ŽûŽ 070126213626Z0!F?Áæ5c¨ÿ à CºkÛ 070921024519Z0!FKžä>ºÈëÊî‚ 071116045517Z0!Fi™ö¯-{ñS1ßã?ù 070711151714Z0! ©Ihp`“ª°\ŸÍ 071121035656Z0!F‚UjŠEº½¿˜ÿî3 070621183036Z0!FÉñ[ØSfðÝŽÒÈ)€ 071102200255Z0!Fà}}àõ-â)ˆìv8 070426123520Z0!G›Å r²oeá }  061214181003Z0!G ¡ÎĬ™Ï”àdæ±î 070220074232Z0!G êV,bXÿ}…kÈË* 070824112900Z0!G(e%5eL ªiš/u)/ 070511175735Z0!G)¹o‚|L,‰/%ò 070711150114Z0!G_9qT–n†~ZÄÓ° 061122143059Z0!GŒrX{¹dlÁÏ9€-‘ 070606124126Z0!Gj\ïU¶a6´`Û¤ø. 070920222854Z0!GœéSSÓCkkÊA!$e¨ 060320114843Z0!G©›,€¾ãSÚàuØÿõM 060614062729Z0!G®m ÐU¨ZòTCM&îÅr 071030102452Z0!Gß÷Bؾ÷X@P|­ÏàXµ 070711151111Z0!Gë˜@¡ Þ] ‹½Òò 070531144510Z0!Gï~ ÄÜvBP:D²®ÁÛ 070607185009Z0!Gø¸Á³@X`§=HE–Í 070611232548Z0!Gûã\(«â•?Jqú§ 070228184744Z0!HsoÑΤ< î ‘# 070316132427Z0!H*EÈpãq_uðïzø…Ú 070212171818Z0!H„:Þ+ÍøÑå&»Ð“Võ 070323130632Z0!H‡¥åëUàb¯±È¤ºka 070329084158Z0!HŒ¿À/« F9)Ââî© 060516091307Z0!Hª='ÌLLì­^sôCã 060802195152Z0!HÉ Rê ‹kTMYÕý“| 060124094211Z0!HéD=žŠâvU˜Ý7éà 071116215450Z0!HïÌ pÁ³YžˆÀ7Ln‚ 070711151604Z0!Hù³í'{F»BaåÿÜw 060629080652Z0!J`VZÕˆ21{1/@D›«± 070517184050Z0!t)Šë´™´*‘›ÓQ¬E¡ 070907194603Z0!J’Ð( ÚYhðÀøx® ³‚ 051212131127Z0!J¥©Eldr³‹øñ½a±Êñ 070727152644Z0!J¥°vKѼÄZ(Ó³Ñ[ 070629202622Z0!Jù¸CgB?í÷XÔ9Ýe° 070601220033Z0!K.$߯‚ãrÛÁT´¸Y 070316125334Z0  *†H†÷ Íb¸ýÎE‚ÿÜmî8ÊÙ«x³º«c½¬ ÷K’Bùß=U EǧpSÄ—µ _FLS•½gu <-þ €Y稬/r#0œè¦ÂÛäzºÛY" Hi´¡qÜçx;eUØþ…,P÷ûA\>1óåºq²z?9©l›¯€bouncycastle-1.49.orig/test/data/org/bouncycastle/jce/provider/test/ThawteSGCCA.cer0000644000175000017500000000144711724567057027671 0ustar ebourgebourg0‚#0‚Œ 00  *†H†÷ 0_1 0 UUS10U VeriSign, Inc.1705U .Class 3 Public Primary Certification Authority0 040513000000Z 140512235959Z0L1 0 UZA1%0#U Thawte Consulting (Pty) Ltd.10U Thawte SGC CA0Ÿ0  *†H†÷ 0‰ÔÓgЮÍ1þ}‘¡? q<¬ÌÈdûcü2K”½o€º/á“À3ü 3#é t+qÄÆÒÍâ/õ cÍÿH¥¿àçóˆ·-2Þ˜6æ ­{ÄdJ;„uòp’}bõ!«i6„1uø¿Çlˆ•|Éå¨Þu¡,zhßÕʇX`£þ0û0Uÿ0ÿ0 U0 `†H†øB0(U!0¤010UPrivateLabel3-1501U*0(0& $ "† http://crl.verisign.com/pca3.crl02+&0$0"+0†http://ocsp.thawte.com04U%-0+++ `†H†øB `†H†øE0  *†H†÷ U¬cêÞ¡ÝÒ_Ÿ Îv¾Q“Ù+ÈwK­iP¡îÞÜýÛéè9”Ü«ry/¿«pĨíêS4íïSÙÇV+Ñ\ôÑŠŽ´+±7HB%Å>ŠËëoÑmÅt¢÷¢|{`v»A˜”³oÜ$È®¼8“Åïbouncycastle-1.49.orig/test/data/PKITS/crls/BasicSelfIssuedNewKeyCACRL.crl0000644000175000017500000000056110350736725025572 0ustar ebourgebourg0‚m0×0  *†H†÷ 0P1 0 UUS10U Test Certificates1%0#UBasic Self-Issued New Key CA 010419145720Z 110419145720Z0"0  010419145720Z0 0 U  /0-0U#0€¯¹ùÂE̸!â§G¼I½µx(0 U0  *†H†÷ sþÅÛ†îkøh…Ò ÁDÑ3]šB§© ½80Áñ>Á¸ÙLºý=|©f_”úFè#”N Ek!εÏ?æ3Ь¦êÅù2nu1ykŽP†‰ùóégç“·Ó°Ÿ,—œ·~~Æ^ørMk0òißh]ª „ñhý“ö¡ùÎbouncycastle-1.49.orig/test/data/PKITS/crls/nameConstraintsRFC822CA1CRL.crl0000644000175000017500000000051310350736725025454 0ustar ebourgebourg0‚G0±0  *†H†÷ 0N1 0 UUS10U Test Certificates1#0!UnameConstraints RFC822 CA1 010419145720Z 110419145720Z /0-0U#0€ã…zŽ¢;žî¸yªÄ½.Y­0 U0  *†H†÷ ´ws÷ç× š½á¨±jzeŽVÉÊ83~Õ7AÁ畤«›@1ªlùä?…k$ÿÖ¿Ëý'©e5\·k‚‡·áÂM4ÊB\FfEÒÀHŒ°§Xfc® h [[îþ“wn¤2.VVÏ…¸•R÷sx^Ðf,ŒÊx6ÚCbouncycastle-1.49.orig/test/data/PKITS/crls/onlySomeReasonsCA3compromiseCRL.crl0000644000175000017500000000066610350736725026766 0ustar ebourgebourg0‚²0‚0  *†H†÷ 0G1 0 UUS10U Test Certificates10U onlySomeReasons CA3 010419145720Z 110419145720Z Ÿ0œ0U#0€I{ëOiû~£ßÛ#‘÷ZVjù¶00 U0mUÿc0a [ Y¤W0U1 0 UUS10U Test Certificates10U onlySomeReasons CA31 0 UCRLƒ`0  *†H†÷ ®À^9²àJ^úÖ2yyñQYsñ³.ýCD$œ=þ7Eî˜nÓúÄš±=âm;Œ—DŸPÆÙ5QrËÔ^éwÊ1-«aqk¨Êró*, •eógSÁÑ=þ/?ºj‚£ß7ƈÁ¡],šKÒ¿‘z”˜ð"AHòáãÉû%bouncycastle-1.49.orig/test/data/PKITS/crls/requireExplicitPolicy5subsubCACRL.crl0000644000175000017500000000052010350736725027301 0ustar ebourgebourg0‚L0¶0  *†H†÷ 0S1 0 UUS10U Test Certificates1(0&UrequireExplicitPolicy5 subsubCA 010419145720Z 110419145720Z /0-0U#0€ çb¨O/·¸?'È£©_{Fk§0 U0  *†H†÷ >GÍ®²K‹0ÔîÄ*Õ„¼Ê±+©Ó7¾öÑ`ArßÊÕ tZè§½2%ËèämǾ%ÃcœCfJ÷êფ¿^p{£·É6ü™…XfÒ An¨.÷E6þq>Äzˆâ ÂÉÝ0¹DH*ZÌáIš¦[Äl*ð?;ê]«pbouncycastle-1.49.orig/test/data/PKITS/crls/inhibitPolicyMapping5subsubCACRL.crl0000644000175000017500000000051710350736725027073 0ustar ebourgebourg0‚K0µ0  *†H†÷ 0R1 0 UUS10U Test Certificates1'0%UinhibitPolicyMapping5 subsubCA 010419145720Z 110419145720Z /0-0U#0€ßjkGÚKwºöT´R”&Ê0 U0  *†H†÷ 9/ðÔÊ:p—RF°íŽ::’ã^õ3Ls ¨I®ÊØoáì#6Ÿ•è©Ò±l-™”!òk˜Èôçð¨&äXæ¡ôhÜ3¡ÆÅ§¦}NÏn·rq¢jÒååá¸×ˆ:¨Ò罤ÎÿÊõ~}ý,L/–‡ØKº5£câ‡Í•.É4—œþ0bouncycastle-1.49.orig/test/data/PKITS/crls/P1Mapping1to234CACRL.crl0000644000175000017500000000050510350736725024106 0ustar ebourgebourg0‚A0«0  *†H†÷ 0H1 0 UUS10U Test Certificates10UP1 Mapping 1to234 CA 010419145720Z 110419145720Z /0-0U#0€̧ÑÒ†ï!c˜ïÍÊÿàD³Ô0 U0  *†H†÷ E tp¶ØfŠpЩ!à µqE§ýßPîÖ8Nê먄ky dm Mà6 kìÆF™!çD`Þ´õê~pK·¸J]›³ÏäTZ¡Œk­ýQó –Ȧzƒò¡Ü:©„öŽ?‘î®ã…œD·’‰wó³Üü~‡àÖU–îƒbouncycastle-1.49.orig/test/data/PKITS/crls/inhibitAnyPolicy5subsubCACRL.crl0000644000175000017500000000051310350736725026223 0ustar ebourgebourg0‚G0±0  *†H†÷ 0N1 0 UUS10U Test Certificates1#0!UinhibitAnyPolicy5 subsubCA 010419145720Z 110419145720Z /0-0U#0€sù ôdœ²ñï·Uª¤¢¯0 U0  *†H†÷ ÇŠ ‘Ô~µ);ÛràaïšÑ²Ì»»ªÝkªvŠDõW´Ò®µ(){ë¦ÉÞ aÕômßvîŸÔk)-æËRKH8L±íNP`h’…†µû˜ÕµRº¡~Ø"þ´ñ¶‹mÌ_Ý%¢¦Bð`Þ¿.ûÖ8Ýíìê|Ý]ð§JÃbouncycastle-1.49.orig/test/data/PKITS/crls/PoliciesP123subsubCAP12P1CRL.crl0000644000175000017500000000051410350736725025462 0ustar ebourgebourg0‚H0²0  *†H†÷ 0O1 0 UUS10U Test Certificates1$0"UPolicies P123 subsubCAP12P1 010419145720Z 110419145720Z /0-0U#0€#‰œø#aBè–›5j¼0½^Š‚0 U0  *†H†÷ 8SrÀËãù„}IXÄs–a?}xG‚ú¾+šU™Ôs­I£<^™f ôßÙÃÓau öĸ)çãé7ó àt ïŽŸú ¢Š:»ræ O*+"]VèûvýbDƒ¨~SMjJ ”d…Ó(WŸçWe™7™ôR®Þ^O\éòÌbouncycastle-1.49.orig/test/data/PKITS/crls/requireExplicitPolicy7CACRL.crl0000644000175000017500000000051210350736725026060 0ustar ebourgebourg0‚F0°0  *†H†÷ 0M1 0 UUS10U Test Certificates1"0 UrequireExplicitPolicy7 CA 010419145720Z 110419145720Z /0-0U#0€"çÛpˆNòb/p˵ÁÍNM0 U0  *†H†÷ •[Ò‚€:ô_Š:c¶~FæI_Ñê‚$Ï€K7½òä·(Të`Ø;å¾ >8pªÐ{˜™Uš 0.†Îe¡]`Ué´¯Á¢ßËcÇ£E‚…‡N,z;Rç?7 ŠAò¨èÙÛ*©åèPJ¼õQ²GýŒsWÏ—5Ý£Çˬ*ËS ßEbouncycastle-1.49.orig/test/data/PKITS/crls/pathLenConstraint6subCA1CRL.crl0000644000175000017500000000051210350736725025754 0ustar ebourgebourg0‚F0°0  *†H†÷ 0M1 0 UUS10U Test Certificates1"0 UpathLenConstraint6 subCA1 010419145720Z 110419145720Z /0-0U#0€D4áP&ÿ<# ­¿½NÆ{à HŠª0 U0  *†H†÷ #ƒi=驹 Ÿýd4—±ãÆ%bÄÕËÖ–~–;"|?çöø¥Ô¢†,Ö¶¦Ú*>~pñÑæ nUhOeÒQ× k×ßÛ~.ö^d^jÊH+Œð…7ópgÉDÄ­““æÙÀ~‚⹦(;é ÐêÖ#¡Ä¥bouncycastle-1.49.orig/test/data/PKITS/crls/pathLenConstraint6CACRL.crl0000644000175000017500000000050610350736725025164 0ustar ebourgebourg0‚B0¬0  *†H†÷ 0I1 0 UUS10U Test Certificates10UpathLenConstraint6 CA 010419145720Z 110419145720Z /0-0U#0€´¤·¢®¹vµËd¥z…J0 U0  *†H†÷  ñ=TÈ"ƒÔiÒã‚ ~¶À¯ôA›QÅÔÅÊQs\ÅÅÖÐl@ÎIç€I©5”„µ»R7bÃ^HWD±Í—¢DïŸuDžXÿÛŽÕüdÃyM¯Ýˆ7¾Ì€zËýç\S±ò%ôêPŒÿXé/þäuÙgxúzbouncycastle-1.49.orig/test/data/PKITS/crls/P12Mapping1to3CACRL.crl0000644000175000017500000000050410350736725024021 0ustar ebourgebourg0‚@0ª0  *†H†÷ 0G1 0 UUS10U Test Certificates10UP12 Mapping 1to3 CA 010419145720Z 110419145720Z /0-0U#0€­â ­Rm%¬Í©˜¢ h­r®²0 U0  *†H†÷ ”4bº4Q´­Ý@þ=ë¼l|‰Ëð~å8P“[hºÑÊ9쨜7$ÃëgŒü7»E¹O_V­ó…#¨½“ÊèµÈ`•¿Z²<<'i¿—À·Jz9^,gZ OopNâµ1s*¿[¯[Nàs[ñ-ͼuDBÔÚ;bouncycastle-1.49.orig/test/data/PKITS/crls/inhibitPolicyMapping1P12CACRL.crl0000644000175000017500000000051510350736725026124 0ustar ebourgebourg0‚I0³0  *†H†÷ 0P1 0 UUS10U Test Certificates1%0#UinhibitPolicyMapping1 P12 CA 010419145720Z 110419145720Z /0-0U#0€v0ƒ_£…K{7 &f0 U0  *†H†÷  ¶Ÿöh "_$sÀ¬¼‹†X{—­8Žpa|8! rµA<¶š“woãætg±•Vò¾R!jÞ÷¿Ù,ÜùºFù’$u¢‹:yÚÊÅr¤{á¢÷’ë¦t¼ºbQÖŸi¯ 4=CçÚuy·n®•Ë}à:P~Á~bouncycastle-1.49.orig/test/data/PKITS/crls/requireExplicitPolicy0subCACRL.crl0000644000175000017500000000051510350736725026566 0ustar ebourgebourg0‚I0³0  *†H†÷ 0P1 0 UUS10U Test Certificates1%0#UrequireExplicitPolicy0 subCA 010419145720Z 110419145720Z /0-0U#0€ðpGbŠ–Ñ‰ªT‰øœm)0 U0  *†H†÷ }¥ßøpÇœÙòNÉBcḢ)û™À*‹ÎÎE1XA29ÿS¼Ü$ßšµƒ‹£ªÍ:#’§ÃVƒÁíØ­ÀVyýÀk½é»Væ(‘wòDQaê’¦‰„Ï6Éäòn¨‚–ú”ü׿‹À½‡0Œ„ë„:å!BÑ`‚‚E+bouncycastle-1.49.orig/test/data/PKITS/crls/inhibitPolicyMapping5subsubsubCACRL.crl0000644000175000017500000000052210350736725027601 0ustar ebourgebourg0‚N0¸0  *†H†÷ 0U1 0 UUS10U Test Certificates1*0(U!inhibitPolicyMapping5 subsubsubCA 010419145720Z 110419145720Z /0-0U#0€$¶q­WÀ÷„š¯V·âHlóý®10 U0  *†H†÷ 5ÕÎÌì.÷ÿ½~FÂêøy±6Ht(éjhYð 2ÅŸdôZ¼\*»b/sf§ÏÞ·w&Èz•j/æ>Û;þ¿á_?)k§„ Fofóq„A—–9«êÃÉ!™o“]Kß•Y` q+©æ¡¼àäü^´¦,™ *vÍÔbouncycastle-1.49.orig/test/data/PKITS/crls/UnknownCRLExtensionCACRL.crl0000644000175000017500000000060210350736725025330 0ustar ebourgebourg0‚~0è0  *†H†÷ 0L1 0 UUS10U Test Certificates1!0UUnknown CRL Extension CA 010419145720Z 110419145720Z0"0  010419145720Z0 0 U  D0B0U#0€jÿ˜ô7ýLô'Ýnèa¡U´«0 U0 `†He ÿ0  *†H†÷ ‡ƒ4¥„ËZê•ßÏÀªJ2Zç)‚’¯@ðÁ[øOź¯¿…²ÙßÕóZÚ½ŠìÓ¡¯ç€HT"ŠtžÁÈ[3¤j0C‘5 ‡ÅZ°´0lô÷"{q¶ÿ~?®Úª·ÒJ§|p·j…ÑŸÑ]¼6D02l¼¦Ž$–bÖhÀ$U:bouncycastle-1.49.orig/test/data/PKITS/crls/UTF8StringCaseInsensitiveMatchCACRL.crl0000644000175000017500000000052510350736725027346 0ustar ebourgebourg0‚Q0»0  *†H†÷ 0X1 0 UUS10U Test Certificates1-0+U $UTF8String Case Insensitive Match CA 010419145720Z 110419145720Z /0-0U#0€6b)|¥ÂЄÇ^£'ß©Db0 U0  *†H†÷ 2õFÀZ‡†•ßi×È™L„_÷èÇf'As¤rö f©÷Íb"‡Ý$”wÁ8ãœÌpd)·Ùv”Y×&C†5ck ¤ÔO}‡j¶¼h4›­Ð4;r|%²¡$îïÓ<¦!ÍypÔm]Æg9â#0v[÷µNÎí>W.XÌìíµRbouncycastle-1.49.orig/test/data/PKITS/crls/GoodsubCAPanyPolicyMapping1to2CACRL.crl0000644000175000017500000000052310350736725027275 0ustar ebourgebourg0‚O0¹0  *†H†÷ 0V1 0 UUS10U Test Certificates1+0)U"Good subCA PanyPolicy Mapping 1to2 010419145720Z 110419145720Z /0-0U#0€‘×ᵤ–‘ñ¢q/fÙ'{J‚“š0 U0  *†H†÷ —ç·ãFÏYIrÒÞöÃÊ4YPñ-û1÷»²÷Ýû½kzçݾl{6IP8Ù…g—¥„IÞŠÕ Ð6ülJ‚˃sí¯1Üoëig·û¨¥6„ÝrRñQá“jÿ/’kzÁg fñƒ"ÙR^÷X]\zi„‘Ú±Âbouncycastle-1.49.orig/test/data/PKITS/crls/NoissuingDistributionPointCACRL.crl0000644000175000017500000000051710350736725027030 0ustar ebourgebourg0‚K0µ0  *†H†÷ 0R1 0 UUS10U Test Certificates1'0%U No issuingDistributionPoint CA 010419145720Z 110419145720Z /0-0U#0€,Å'#ÑÑAßßa„¹Oñ2ì10 U0  *†H†÷  ާÝ©¦Â ºîÌæzYݱ›òp"~Ä:뜕 c 9ßg¸^|¸ƒuØÞ5ý¼+‡‰®‚…Þ5&«ù@®lžš°µ—_È~~Þ–y }ß\¥™úµ¼­ø¯|uÞps®á{6‹#!™¼‹l-ÞóÅßÁi‰¥µ !€Äbouncycastle-1.49.orig/test/data/PKITS/crls/P1anyPolicyMapping1to2CACRL.crl0000644000175000017500000000051410350736725025627 0ustar ebourgebourg0‚H0²0  *†H†÷ 0O1 0 UUS10U Test Certificates1$0"UP1anyPolicy Mapping 1to2 CA 010419145720Z 110419145720Z /0-0U#0€-7Ò?žYÙæ¾W¢÷k‚¦­î0 U0  *†H†÷ VR„\Ægáõp”ů¸Þ8ܰeŠi€µšù/lŽƒZ[3Ò©ÆÇ ’ÍŸ¼ô0Ø¿ŽÀ˜Ôܾµ1€v0ø5HE¥%*’ß®Lˆ^4Õê9ŒòäÇäÁ5E;ooóã/C­®ã˜:~HQ̨8Î81œ6^ ëõéC©_w¤¼DÄ bouncycastle-1.49.orig/test/data/PKITS/crls/pathLenConstraint6subsubCA00CRL.crl0000644000175000017500000000051610350736725026551 0ustar ebourgebourg0‚J0´0  *†H†÷ 0Q1 0 UUS10U Test Certificates1&0$UpathLenConstraint6 subsubCA00 010419145720Z 110419145720Z /0-0U#0€jæÅAm­>‚ܰ]­òñPÎ 0 U0  *†H†÷ B[q¾Öð´€ö3<Í™ &ópBDøùar³‘ UgÐ#ðvIÆ‚#pÚ:•€ªûN[›f8!Áeqå¶®²zs„š<ò/e ´R¡7¦$¨^r勉1¬Ü :Òõ—ó‚Öýtµ’ÕÓ¥t£bÄbouncycastle-1.49.orig/test/data/PKITS/crls/distributionPoint1CACRL.crl0000644000175000017500000000076510350736725025257 0ustar ebourgebourg0‚ñ0‚Z0  *†H†÷ 0I1 0 UUS10U Test Certificates10U distributionPoint1 CA 010419145720Z 110419145720Z0"0  010419145720Z0 0 U  ¸0µ0U#0€žPWj…oøæA^ëzº0~ºô0 U0…Uÿ{0y w u¤s0q1 0 UUS10U Test Certificates10U distributionPoint1 CA1&0$UCRL1 of distributionPoint1 CA0  *†H†÷ »6W‡9?IPB_¤+>²R©Ü^‹ÁlGƒ_Ú®¿ºW§ðA¿Ñ@ãø¿€¬-—ˆl‘9‡= Ey£¸A¢¶£$Í©{òùWµ˜ §+>Z*Ø[„}%u%QŸXoêù:bYæT×v‘-¹õ*Î Fäݱ<#’¨gÒ9jIbouncycastle-1.49.orig/test/data/PKITS/crls/pathLenConstraint0CACRL.crl0000644000175000017500000000050610350736725025156 0ustar ebourgebourg0‚B0¬0  *†H†÷ 0I1 0 UUS10U Test Certificates10UpathLenConstraint0 CA 010419145720Z 110419145720Z /0-0U#0€! µvvÓ³*¬&üª¦OòÖ¡oK0 U0  *†H†÷ V{¥åd‹1dúŸ£%«‹Éº˹ã_=é¹ôôôØLÌžZ6³ÓSªÕº­”¥!Äœ¬=<ã/Si—l.傘1èGùÜ«âì¹?²a ­"$öÿJ’8›€?òØ{ýÔ ‚,Høž~‘U !èÝ•¬Çׯ„ô#»ÚÍ¢bouncycastle-1.49.orig/test/data/PKITS/crls/inhibitPolicyMapping1P12subsubCAIPM5CRL.crl0000644000175000017500000000052710350736725030006 0ustar ebourgebourg0‚S0½0  *†H†÷ 0Z1 0 UUS10U Test Certificates1/0-U&inhibitPolicyMapping1 P12 subsubCAIPM5 010419145720Z 110419145720Z /0-0U#0€$«U•‹•×DÇÝÿ~ýö‘± 0 U0  *†H†÷ Ü 3÷±éøG†.V¼ äFH Í7cqûi4á Ъä÷agF§¸ºg0ë…á ›æýûPêÉóäs…kÌÃðJ+¼u~´Ñd9¶89Ü0w3‘¸wR¶pí$³4z¸ïF“x÷~mj®.È ×v¬FGÿúQ›GËÃÆ…Lžbouncycastle-1.49.orig/test/data/PKITS/crls/PoliciesP12subsubCAP1P2CRL.crl0000644000175000017500000000051210350736725025314 0ustar ebourgebourg0‚F0°0  *†H†÷ 0M1 0 UUS10U Test Certificates1"0 UPolicies P12 subsubCAP1P2 010419145720Z 110419145720Z /0-0U#0€gå Œl*»Um-è"ªKs+ˆ*0 U0  *†H†÷ %¢âuÛÿðœâY|ùÆŽcÌÔÑ~Ô— ê Yˆ´ìùX}ý‡N…âäTÃìþ¿ó«Y¯Iä—ºÂßnEéOéJA…Žõ|ÚÇ!s37ÿáàü®˜)ö-ÑKT¤ûî®Ms¹ÿÊnmVÃ'ØÒ´ÕœÆ=@Hù7/"»UO„ebouncycastle-1.49.orig/test/data/PKITS/crls/onlyContainsCACertsCACRL.crl0000644000175000017500000000053010350736725025320 0ustar ebourgebourg0‚T0¾0  *†H†÷ 0J1 0 UUS10U Test Certificates10UonlyContainsCACerts CA 010419145720Z 110419145720Z @0>0U#0€ó¡Fg{éY«ëU†“ȬäU·0 U0Uÿ0‚ÿ0  *†H†÷ T'¬üµz““çòéc÷R­ LRbæöqrô¿ÛRÖO‹†hJÊJý¹~]zßHg6›1Ý)²Ž¶ºÄ 1WO~ÆÑ< å ÂÆ [wÊ•71}¨M®`O<´ï’ñ_¡-ÿæ.ˆN,ˆT¸á¾Nl"7 ²a!F6)bouncycastle-1.49.orig/test/data/PKITS/crls/onlySomeReasonsCA4compromiseCRL.crl0000644000175000017500000000073310350736725026762 0ustar ebourgebourg0‚×0‚@0  *†H†÷ 0G1 0 UUS10U Test Certificates10U onlySomeReasons CA4 010419145720Z 110419145720Z0"0  010419145720Z0 0 U   00U#0€?¾@ñ÷kû°YäZà—Té0 U0nUÿd0b \ Z¤X0V1 0 UUS10U Test Certificates10U onlySomeReasons CA41 0 UCRL1ƒ`0  *†H†÷  ÉÏ®kQ:ØîO…;§0lÍYPýuIDš¯q¥tÊ%áþ ôÛ ŒÊ›ÞÍ¿->©J›©duÜ&²ö«/Ò{=öûd¤ÈSe²€Z"ç;œ’– tƒÒræ4ËT¼uÄ4ÁN@.á(×êmÁšK€Ü-||¥§(ubouncycastle-1.49.orig/test/data/PKITS/crls/requireExplicitPolicy10subsubCACRL.crl0000644000175000017500000000052110350736725027356 0ustar ebourgebourg0‚M0·0  *†H†÷ 0T1 0 UUS10U Test Certificates1)0'U requireExplicitPolicy10 subsubCA 010419145720Z 110419145720Z /0-0U#0€mh1ýù_Rùû.ÚDÂÏ{6™Øÿ)0 U0  *†H†÷ XËÍ~êU[…}±{® p‚ª_ä[™rŒ"¼*®?ה̶Ãé«Â‹ÁhÊð|1!}8^,Ÿ¯‰Há*æ*¶Y˜Ýк±É…¸uø©Úé%läœj’)×Yûñ€ÄLCöy[`§6Ìd"_÷ØŽº£YÒþ\@ -îMbouncycastle-1.49.orig/test/data/PKITS/crls/requireExplicitPolicy5subsubsubCACRL.crl0000644000175000017500000000052310350736725030016 0ustar ebourgebourg0‚O0¹0  *†H†÷ 0V1 0 UUS10U Test Certificates1+0)U"requireExplicitPolicy5 subsubsubCA 010419145720Z 110419145720Z /0-0U#0€>©0f/§´%ˆ„gÉ­˜“ø–ÎÅ0 U0  *†H†÷  ×f-.I5™TvîP€â7ÃÕjdò²Ö—Œ¥uਫ਼;FÊÎ1¹Sþû™›{5h\š` Ú©-ظ‰a‰ä@vú¹bÏþ‡l•žÚÛL½>ñ%W;Ó«”{ÞZÿUcþI­;E’úIyE‰=pu©S•ÖÂFCvAÀI#Ðï¼bouncycastle-1.49.orig/test/data/PKITS/crls/NoPoliciesCACRL.crl0000644000175000017500000000047710350736725023511 0ustar ebourgebourg0‚;0¥0  *†H†÷ 0B1 0 UUS10U Test Certificates10UNo Policies CA 010419145720Z 110419145720Z /0-0U#0€SÁ%}å[>W‘ø–ž]Æ%¨º0 U0  *†H†÷ 2¤šÊ_Qž‘ÛûŠ …›dÇïÕC4{­SMÑCùGˆÞóxg*:K\¥î¹ïùë?ñ9,1«å§Š‡qÆx¡uß„ª:h7Šºey1“ŒNjñ;ûhy4U[BUó-ŸöGdj„ —ª,Æ–í³±¡b´s@ƒ–ìÒÿbouncycastle-1.49.orig/test/data/PKITS/crls/nameConstraintsDNS2CACRL.crl0000644000175000017500000000051010350736725025230 0ustar ebourgebourg0‚D0®0  *†H†÷ 0K1 0 UUS10U Test Certificates1 0UnameConstraints DNS2 CA 010419145720Z 110419145720Z /0-0U#0€~Ü;êޜқBDï{Ín’à´0 U0  *†H†÷ ñ<œ%Øåó™—rGÑ”¡ð ïŸLÆ>“#v’÷h÷Ы}s ºøêYÃ6p³á€?8eBwx•ym©ˆÇTY²RÚZX¡sxgAž‚´«óÑtÎúx‹ÅÿÊ@ʈ¬txAK`…?C1~`»=‘ ßój@bouncycastle-1.49.orig/test/data/PKITS/crls/deltaCRLCA3deltaCRL.crl0000644000175000017500000000051410350736725024164 0ustar ebourgebourg0‚H0²0  *†H†÷ 0@1 0 UUS10U Test Certificates10U deltaCRL CA3 030101120000Z 110419145720Z >0<0U#0€âO¿Þ@Öÿ3]"V‰Ü÷Îp½0 U0 Uÿ0  *†H†÷ Ž iÐûüÁàQ¯²œ±ÖÚJñ”¢#>oÉœMÖ°n®Ç#üli>fîú-´vçE|k|µÊÝógÇxÐ TR©Ž6\>›·µñ©aZ•L?©ÒvÃqÝ*šx'M>è“@!B¨ †ô'SŒ<«Ôp).BkÛZ-Tébouncycastle-1.49.orig/test/data/PKITS/crls/NegativeSerialNumberCACRL.crl0000644000175000017500000000055610350736725025516 0ustar ebourgebourg0‚j0Ô0  *†H†÷ 0M1 0 UUS10U Test Certificates1"0 UNegative Serial Number CA 010419145720Z 110419145720Z0"0 ÿ 010419145720Z0 0 U  /0-0U#0€Œ§#MK÷ꡲ‡¹ÀÓ3XË‚0 U0  *†H†÷ }UwÞtø®%5­St’o‰ùí³L¿§p± Jé™[Z gßÍtÖ€-Ê÷À¾žh5Óy‰E§nòu†å(Ð,––ëuÐú§xøPçpkÌŠ0Å]"©ïÝH…‡Ö/Ð,¿úÆÎID7óóy±a«Çù!)?OË6Àbouncycastle-1.49.orig/test/data/PKITS/crls/TrustAnchorRootCRL.crl0000644000175000017500000000054110350736725024351 0ustar ebourgebourg0‚]0Ç0  *†H†÷ 0@1 0 UUS10U Test Certificates10U Trust Anchor 010419145720Z 110419145720Z0"0 h 010419145720Z0 0 U  /0-0U#0€ûlÔ-žÊ'zž °<êš¼‡ÿIê0 U0  *†H†÷ ’Ä4´’«ºqkt1Îí%ÖKúø ×0í÷‹]d›Ý1@äU _‚icv¥ÏžÄ_òS››}õitW8påû[vXÉì1Ü”î3œ8K)á )‹nÇ¿ è@4ƒÏÿŸÍµ÷ÙM§Ÿ.¿D˜kòÓþ¨ 1Á3v·eM¹9bouncycastle-1.49.orig/test/data/PKITS/crls/nameConstraintsRFC822CA3CRL.crl0000644000175000017500000000051310350736725025456 0ustar ebourgebourg0‚G0±0  *†H†÷ 0N1 0 UUS10U Test Certificates1#0!UnameConstraints RFC822 CA3 010419145720Z 110419145720Z /0-0U#0€ê·nš+ €6giµÚ5¥†=)x0 U0  *†H†÷ Œm Äg‘¯Þ]‰ŸüßâzzR>MìP¹Fƒ:}-›]„‹mº¿KAtã;Ás¢ƒO丹zp{ ¼Y÷Ûƒ“‡˜SC¢qÕ/Ðþ/ÂFUÕdTrO¢7݈¸;c$ßÓí~mÚ/W›Ì×–gH~¥°mËÉ^éxXƾð̱ãJWE†bouncycastle-1.49.orig/test/data/PKITS/crls/onlySomeReasonsCA1otherreasonsCRL.crl0000644000175000017500000000057310350736725027320 0ustar ebourgebourg0‚w0á0  *†H†÷ 0G1 0 UUS10U Test Certificates10UonlySomeReasons CA1 010419145720Z 110419145720Z0"0  010419145720Z0 0 U  B0@0U#0€àbšßP½[Iþ¾pÌÜ9n0 U0Uÿ0ƒŸ€0  *†H†÷ ZšpYOkB'Ø*pž‘¿õ À,Ž!]jvpaîø ÃÏ{@xÅ%]ÏÇta)@“‘ÁRhLã·Â ã&«ú/âp`Ùí4ìrK˜WŒZÝPÒlDîK‰ÖùÔydŸçòOé ‹Äïä-øŠÆ”šY$ùÔnLMíO?è±)ön. Ñïbouncycastle-1.49.orig/test/data/PKITS/crls/onlyContainsUserCertsCACRL.crl0000644000175000017500000000053210350736725025755 0ustar ebourgebourg0‚V0À0  *†H†÷ 0L1 0 UUS10U Test Certificates1!0UonlyContainsUserCerts CA 010419145720Z 110419145720Z @0>0U#0€ZË7ÒF˜\•øß¸:ÿ@­ò0 U0Uÿ0ÿ0  *†H†÷ Rc@U‘Jˆ# d„´>P¢ º0²†/ε·àÂÕc‚ˆ«Ö¤ß"–ó~ÍÎ ‡T ?`Çk¦š%Q¯²ÄÚùÕcWò¸øÑ¿ £w§æã‡ —]JA¹6˜½T“•2Ù|ƒå×Tw¾äëáúçƒýxEK B‡RÁO9ó bouncycastle-1.49.orig/test/data/PKITS/crls/RevokedsubCACRL.crl0000644000175000017500000000047610350736725023555 0ustar ebourgebourg0‚:0¤0  *†H†÷ 0A1 0 UUS10U Test Certificates10U Revoked subCA 010419145720Z 110419145720Z /0-0U#0€xõ½K–³-æ@P2븴GT òH0 U0  *†H†÷ 8‹!êÄ.6;Ñ#Ъè‡bKch’±Z":™^r§’A¶°…ðÿHêÚXÒw&ÂáVRiEÊ8˜õ«Lþš0dXdãh÷¥?†ÿ:‚½V§£¢[û÷!˜ ;¼ =”ŒßOkµh<ÏçiqL ±zS$\Iúšbouncycastle-1.49.orig/test/data/PKITS/crls/BasicSelfIssuedOldKeySelfIssuedCertCRL.crl0000644000175000017500000000071610350736725030162 0ustar ebourgebourg0‚Ê0‚30  *†H†÷ 0P1 0 UUS10U Test Certificates1%0#UBasic Self-Issued Old Key CA 010419145720Z 110419145720Z ®0«0U#0€ú¢j¹îúOÅruÓKzmŒä\9$0 U0|Uÿr0p n l¤j0h1 0 UUS10U Test Certificates1=0;U4Self-Issued Cert DP for Basic Self-Issued Old Key CA0  *†H†÷ Œkì[=1þÆ@ÊãÅR0 šUîøÃ½Í±EÐDöB¹ßM% º[½ hÂΰÄç¾ÞsU\kÖ=åâ1×_nK 1ÍDþ)Õ'wõƒ¼î?F1ÕfZ¡›Ќ﮻6u¤³b¾ÍÞ¸½_&§ØYÎ'¯î«ÞfïžIËbouncycastle-1.49.orig/test/data/PKITS/crls/keyUsageCriticalcRLSignFalseCACRL.crl0000644000175000017500000000052310350736725027062 0ustar ebourgebourg0‚O0¹0  *†H†÷ 0V1 0 UUS10U Test Certificates1+0)U"keyUsage Critical cRLSign False CA 010419145720Z 110419145720Z /0-0U#0€”éÄPö p&”<ïß0.Þ?tÍ0 U0  *†H†÷ ßlq™½T5.ç»T`r ûÙu™Êå* æÈ'tGÜ ÔŸ¼Ÿ²b%´m[å è*Žë>kÅšÒý‰[ÿwg 3E¼lí¯„0Yû|q•c`1›› êwñpñ¹.Ñ©Bf”¹THÛDVVWZ|M×À\oõ£WˆjšqÍծñ(bouncycastle-1.49.orig/test/data/PKITS/crls/nameConstraintsDN1subCA1CRL.crl0000644000175000017500000000054710350736725025711 0ustar ebourgebourg0‚c0Í0  *†H†÷ 0j1 0 UUS10U Test Certificates10U permittedSubtree11#0!UnameConstraints DN1 subCA1 010419145720Z 110419145720Z /0-0U#0€î¹ÏÖ/ŽÈ…“þî£PXþB00 U0  *†H†÷ 1u§%äK Ð)jh 0<0U#0€‹Öÿž)é,PÑ#y]eÛ`pôÓ0 U0 Uÿ0  *†H†÷ s„àÐ]»¤°I-œ˜/Å9ª J[Y Mò¶Gˆ3û¨QÙ±Dqf}HÄþîý+«€ ­AÖQˆÈŽ™ n³ereX;ñ¹¯Ìu«¬|Y2YŽÊÙÍPòùÖNA^b*â:˜ØÿËniMÖtϵ-Ç-<`¦0•4Lbouncycastle-1.49.orig/test/data/PKITS/crls/SeparateCertificateandCRLKeysCRL.crl0000644000175000017500000000057210350736725027024 0ustar ebourgebourg0‚v0à0  *†H†÷ 0Y1 0 UUS10U Test Certificates1.0,U%Separate Certificate and CRL Keys CA1 010419145720Z 110419145720Z0"0  010419145720Z0 0 U  /0-0U#0€ŠýB){YxRJ÷Hq·ÄqЦWÛ0 U0  *†H†÷ ŽyüW4ž¼<(ß»Çôj¡•QñÒ´:dA5¶Bb·ç¿ íkÊöLɧH«Bžž µñ†™±~nÝÖ¦³±?üyj¿ð9?¬iµ/Zd‹éFŸ‚ ò ‘´ýV¡«y 3&ÆIj–ÙB‹D¥í­i‚cxŽç–-bouncycastle-1.49.orig/test/data/PKITS/crls/WrongCRLCACRL.crl0000644000175000017500000000054110350736725023072 0ustar ebourgebourg0‚]0Ç0  *†H†÷ 0@1 0 UUS10U Test Certificates10U Trust Anchor 010419145720Z 110419145720Z0"0 h 010419145720Z0 0 U  /0-0U#0€ûlÔ-žÊ'zž °<êš¼‡ÿIê0 U0  *†H†÷ ’Ä4´’«ºqkt1Îí%ÖKúø ×0í÷‹]d›Ý1@äU _‚icv¥ÏžÄ_òS››}õitW8påû[vXÉì1Ü”î3œ8K)á )‹nÇ¿ è@4ƒÏÿŸÍµ÷ÙM§Ÿ.¿D˜kòÓþ¨ 1Á3v·eM¹9bouncycastle-1.49.orig/test/data/PKITS/crls/PoliciesP12subCAP1CRL.crl0000644000175000017500000000050510350736725024402 0ustar ebourgebourg0‚A0«0  *†H†÷ 0H1 0 UUS10U Test Certificates10UPolicies P12 subCAP1 010419145720Z 110419145720Z /0-0U#0€BˆÁx·CÚ¯½ÞºC§åµaÿò0 U0  *†H†÷ 8…ûƒìôÕäB'hÓÖ_ÉÕ`Jü39”ÎÙ(qNþªæakB–V@äHæ–e!òæŽiPoD3£Œ(éõ…ÖÞU»0ë¼Ip;»ÆðŒŽÖ_?0ªX©jN>F¡övç¨}(èØD2Xvˆð_7'(ೈÃuAPÂþ"¾êJ+ü¡bouncycastle-1.49.orig/test/data/PKITS/crls/pathLenConstraint6subsubCA11CRL.crl0000644000175000017500000000051610350736725026553 0ustar ebourgebourg0‚J0´0  *†H†÷ 0Q1 0 UUS10U Test Certificates1&0$UpathLenConstraint6 subsubCA11 010419145720Z 110419145720Z /0-0U#0€³À÷Qö\šN,‡PQå‘ÓX[+0 U0  *†H†÷ _=¥î “ØOÏ(;‡Ž‹~-6ÂðÍT”T/æœõþ’~?¼”Õý‚À‡Ü“2È«Y;jߎ¯Ë÷÷9PÚŒ¬|—$'Ω›8rn2Ä¡ ó4]bøê!¼"˜o€%\Äþ{ÿœJƒì)Û nËž˜‰3¾%Œ-Hp=bouncycastle-1.49.orig/test/data/PKITS/crls/requireExplicitPolicy4subsubCACRL.crl0000644000175000017500000000052010350736725027300 0ustar ebourgebourg0‚L0¶0  *†H†÷ 0S1 0 UUS10U Test Certificates1(0&UrequireExplicitPolicy4 subsubCA 010419145720Z 110419145720Z /0-0U#0€¾l¬ LS”¸ä‘#¥«c0 U0  *†H†÷ „ú þ„Ð&†\7k,1ªz"„ì°ß™™ð·éÖüpšOPÕ$( y…i£VÊy^wÓzbŸXŠÕ}Þâo¤Ñ.'ì%‚¢‘g D9̲å!I¬%,‘ß3•n«‹ü*Y{]Âh§&àÍ@nó77aöjP¡Ý’Sþbouncycastle-1.49.orig/test/data/PKITS/crls/MappingToanyPolicyCACRL.crl0000644000175000017500000000051010350736725025217 0ustar ebourgebourg0‚D0®0  *†H†÷ 0K1 0 UUS10U Test Certificates1 0UMapping To anyPolicy CA 010419145720Z 110419145720Z /0-0U#0€º€Ìz,§cZ«N?„ÄSU iú0 U0  *†H†÷ ’Ú *HZ{¦t¼2pJ0‹ñ&´Ï œ‰„˜qHO“ YÀäe¿ÊI=6ó1ƒ>4³šßÓ¤ö}Ëî[Ïàp%”Tœ2JPAê¿ôWÓS|ǼÔ©Ÿ6Q&o7bŠê÷{/Ñ$SÞÛáΉ>q#s²Ú¯y÷J+¤*»bouncycastle-1.49.orig/test/data/PKITS/crls/nameConstraintsDN3subCA2CRL.crl0000644000175000017500000000051310350736725025705 0ustar ebourgebourg0‚G0±0  *†H†÷ 0N1 0 UUS10U Test Certificates1#0!UnameConstraints DN3 subCA2 010419145720Z 110419145720Z /0-0U#0€ H¾(qjH$ <âJÔ*â×5ï0 U0  *†H†÷ À §(€ ,qfMg‚ìÇ0OH)þÔ ‚ò\æï$‹Ÿò¸Å;à†SôµügÛ²EwŠxGëc»C¸ÀÿÊ{Õúßçz¥9çíJÙmýÑx¡Dðqô‰LRÕï™\Yë€Ä]íH+ZU ÑßJ¥Iiñg¢ªÎ™›tìÚ`Ù>E£l[GúÐbouncycastle-1.49.orig/test/data/PKITS/crls/GoodsubCACRL.crl0000644000175000017500000000047310350736725023043 0ustar ebourgebourg0‚70¡0  *†H†÷ 0>1 0 UUS10U Test Certificates10U Good subCA 010419145720Z 110419145720Z /0-0U#0€|\i|ÈU±")CûÄ{êê¸}0 U0  *†H†÷ ¡5XAXJ“êŠçÌÁ¾"Œš!2Ö©¿ß}`ŒºòŒ©8¤”ŠmiFå¬cHåÉÀÞßsÆì?·ía¢lBØÏzÿ;5AŠÈþ…7¸}Ü 5ºà»9Ⱦ*yW‚ÛñÚ!àÆT+7*á ‚ª/G«ü0ÝRº“ϼF9§”)}à*\ÔÎbouncycastle-1.49.orig/test/data/PKITS/crls/indirectCRLCA3cRLIssuerCRL.crl0000644000175000017500000000074110350736725025460 0ustar ebourgebourg0‚Ý0‚F0  *†H†÷ 0M1 0 UUS10U Test Certificates1"0 U indirectCRL CA3 cRLIssuer 010419145720Z 110419145720Z Ä0Á0U#0€±!K²’¨ 3N+‰gO¡OŸ0 U0‘Uÿ†0ƒ ~ |¤z0x1 0 UUS10U Test Certificates1"0 U indirectCRL CA3 cRLIssuer1)0'U indirect CRL for indirectCRL CA3„ÿ0  *†H†÷ h4‡dUe©‡GTÂ-H‘îYõíÙmx¹ÿŒ\õµ"uòcbx%Ml/£XâW+?I ½…Ŭ­8 F,4ò›å"õUÌcûÂi”×åxON˜eÏr 2x"¯",!Å|ÛŒ1¾­YÄ$äìà @L+•˜Ýôbouncycastle-1.49.orig/test/data/PKITS/crls/PanyPolicyMapping1to2CACRL.crl0000644000175000017500000000051310350736725025545 0ustar ebourgebourg0‚G0±0  *†H†÷ 0N1 0 UUS10U Test Certificates1#0!UPanyPolicy Mapping 1to2 CA 010419145720Z 110419145720Z /0-0U#0€ÒºO>h8æøÁê%®Ú’¯C6n0 U0  *†H†÷ õùչ̃5ë=˜R‰cy— šõ 5rD«+—… Á?&äxˆY-M+J‹ZXä,‚v°ÃEÆF4Ì83Úk yâe*:TiTnw2ÁEŽcÞ ô>Ÿ¥7%’@ñªWòaiã=ä…”ì)QÝ…leÃzÄù7~À  l†+G{bouncycastle-1.49.orig/test/data/PKITS/crls/BadSignedCACRL.crl0000644000175000017500000000047610350736725023264 0ustar ebourgebourg0‚:0¤0  *†H†÷ 0A1 0 UUS10U Test Certificates10U Bad Signed CA 010419145720Z 110419145720Z /0-0U#0€Bo— #yÁWž:¦ œˆØ0 U0  *†H†÷ ‘}¥N§ñb”ú— FA–1•Iy©åñ„ªÈÜÈ’äüf–›.Žsª­pý޾òt?yZæ*g´F׊ÞÈзÌö…Û¦Fœ­# GªðDEcõ@Ýüu¿K…/út ø)—’®4\nkk@tQX&ß•·r=±vš C71bouncycastle-1.49.orig/test/data/PKITS/crls/PoliciesP123subsubsubCAP12P2P1CRL.crl0000644000175000017500000000052110350736725026374 0ustar ebourgebourg0‚M0·0  *†H†÷ 0T1 0 UUS10U Test Certificates1)0'U Policies P123 subsubsubCAP12P2P1 010419145720Z 110419145720Z /0-0U#0€Ó*»ðµWA•RÝϨ»’œàns¼0 U0  *†H†÷ 7ÏŽp ÆÏî(ÍãøŒk ý×1Ã,wõ>ÿn·# M3?¡ô7M„m*%ß@ø%–@zûY)N™Èc{#¶ÈërpŽóÊZ*6»Æš€EcIÉŸh2„ä¦Ê"RÙ™ú4“8ìºù &¹[; Î…C޽GÊÞPKBè—‘t¬Zbouncycastle-1.49.orig/test/data/PKITS/crls/BadCRLSignatureCACRL.crl0000644000175000017500000000050510350736725024346 0ustar ebourgebourg0‚A0«0  *†H†÷ 0H1 0 UUS10U Test Certificates10UBad CRL Signature CA 010419145720Z 110419145720Z /0-0U#0€û ýº{æ8H™Z`UP—ª6lC0 U0  *†H†÷ h}ï›,'‚Â.”)"¸ôñÇD…^„Šn7\„^pµõމ ¶HQœ”!ñ!æ8P¤Ã…L„éëö·j¤Ì¥B¯šÙÀL˜Ã.÷„Øú$Kh< Æ|`xÖF7h(OÁ·20bouncycastle-1.49.orig/test/data/PKITS/crls/GoodCACRL.crl0000644000175000017500000000057610350736725022335 0ustar ebourgebourg0‚z0ä0  *†H†÷ 0;1 0 UUS10U Test Certificates10UGood CA 010419145720Z 110419145720Z0D0  010419145720Z0 0 U 0  010419145720Z0 0 U  /0-0U#0€·.¦‚ËÂȼ¨{'D×53ßš”Ç0 U0  *†H†÷ “Âì q-×¢³ðíMnfr©Â0sñr¿§Q•Ä1?yAíí«Ð–2GLÄ÷âeosUÁY Vò`y'.”@Ý~±’¿¸WåLÅ8—u*¡¢% ì·•@,ß¹úÿ¾žJò7O%ËÈmïä ¹6ÁÙùO^€…’Íbouncycastle-1.49.orig/test/data/PKITS/crls/requireExplicitPolicy10CACRL.crl0000644000175000017500000000051310350736725026133 0ustar ebourgebourg0‚G0±0  *†H†÷ 0N1 0 UUS10U Test Certificates1#0!UrequireExplicitPolicy10 CA 010419145720Z 110419145720Z /0-0U#0€óé&™–†ÄÕ¢{ì¹°¥n6 E0 U0  *†H†÷  ‚sá™]Ÿœ'WCöt´váÖ¿šÞ„›¦ºš˜úÿÂ¥¤Í_¹Kágæ³ã.[êäÙœBÀ–@â™2$Â{ÑG-2BÉ|Í ªÈ¼¤ØþmŒRyÕp‰x±.iE(UfCa@üxê#˜DfߎÑÕù‚zÒ.­6ŠÿŽ bouncycastle-1.49.orig/test/data/PKITS/crls/UnknownCRLEntryExtensionCACRL.crl0000644000175000017500000000061010350736725026351 0ustar ebourgebourg0‚„0î0  *†H†÷ 0R1 0 UUS10U Test Certificates1'0%UUnknown CRL Entry Extension CA 010419145720Z 110419145720Z0705 010419145720Z0!0 U 0 `†He ÿ /0-0U#0€õ[ëÚÊå愈ŸÙl¿[ΓiM€0 U0  *†H†÷ F‰vѨë}Þ¿¨†HŠÙx®!!b‘=ºy°ÔÊA®ÓCLw-ž™e“YÜrÜÔäóìíc½ Y<¨ ®úïs²¤šçnÂþñõXx•Ò$-LK~{ñŽŸÎ‚v¾¥^wâ3¥Ñ**Èâõ mâçÇœÌ[0¨0  *†H†÷ 0E1 0 UUS10U Test Certificates10UPolicies P1234 CA 010419145720Z 110419145720Z /0-0U#0€0»yOo²ƒzhC«÷L¡@q 0 U0  *†H†÷ »².†cPz`uãï–â!Îaþ*Ñ7Y°=þÃ빇a:zôï=FÎïä§Þ¦ÿ%x½ßM‹–p¬GŒäwò”?»6!5 Ùi¹€BÐ~UßoüP²œ²S µ liU· e„zŸtRIX.l½·¶4ëÓÌ©?iuæbouncycastle-1.49.orig/test/data/PKITS/crls/pathLenConstraint0subCACRL.crl0000644000175000017500000000051110350736725025664 0ustar ebourgebourg0‚E0¯0  *†H†÷ 0L1 0 UUS10U Test Certificates1!0UpathLenConstraint0 subCA 010419145720Z 110419145720Z /0-0U#0€Ž«FœKnçåWˆ '“þ'Öç0 U0  *†H†÷ ‹-Îh…`dê^­“eœ“ž§ Iɼ7A¶»n¹ŽÆ [Øk¥v÷Ñ@ðs×h¤°h­cð±µ R¸öìUt"7¥/À¯©i¸Tã <#< { èm­œ6³ÓTœoMÂæ5àk ;¨:†xv¶ìÚ¡<í§ãAÏEÍÒ³µƒbouncycastle-1.49.orig/test/data/PKITS/crls/Mapping1to2CACRL.crl0000644000175000017500000000050010350736725023531 0ustar ebourgebourg0‚<0¦0  *†H†÷ 0C1 0 UUS10U Test Certificates10UMapping 1to2 CA 010419145720Z 110419145720Z /0-0U#0€7;Š¡º§t›ÀëÖ9Ë! £V}0 U0  *†H†÷ )cŒW¤5»,. ~Áâ9,ƒÖ_):pcªBèý?dö‹­†'æ]Hïm¼¾z$©m°NMXORÈ¿Üp|ê^TÛ]bÅc.´ÒúQlÚ?A6ÎcµFæ}ÛPi‚j4E 8^òÕ‹wäêjšútí´ZºhòhÄÒUžbouncycastle-1.49.orig/test/data/PKITS/crls/deltaCRLCA1CRL.crl0000644000175000017500000000077510350736725023161 0ustar ebourgebourg0‚ù0‚b0  *†H†÷ 0@1 0 UUS10U Test Certificates10U deltaCRL CA1 010419145720Z 110419145720Z0f0  010419145720Z0 0 U 0  010419145720Z0 0 U 0  010419145720Z0 0 U  …0‚0U#0€“M¼ò× ® H¬º2 ×è Í0 U0SU.L0J0H F D¤B0@1 0 UUS10U Test Certificates10U deltaCRL CA10  *†H†÷ H2Ú:Âq7ê$Z/¸ž–³á*míµ{ë0¬‡ÀŠmÊ$ôsݽ·øÌU1óÙâ¢\|Q`m ÛCRœ”ú†2æ¦~ÎæÁ.þ3"³_féÓÞÄ”½ +.†è&õô89b~è»ÍÈ»‚’q–Šs×ïú¥Â”Sé,4§P}ëNbouncycastle-1.49.orig/test/data/PKITS/crls/deltaCRLCA1deltaCRL.crl0000644000175000017500000000073010350736725024162 0ustar ebourgebourg0‚Ô0‚=0  *†H†÷ 0@1 0 UUS10U Test Certificates10U deltaCRL CA1 030101120000Z 110419145720Z0ˆ0  010419145720Z0 0 U 0  010419145720Z0 0 U 0  010419145720Z0 0 U 0  010419145720Z0 0 U  >0<0U#0€“M¼ò× ® H¬º2 ×è Í0 U0 Uÿ0  *†H†÷ cækéÏD)ȋ区«&W¥O¨¶ã5ÿs‹@àyz×iŠÅ£Ù…)ÿïäzKõ6Q4yš…ˬHž-·¶ž‚W± ·I¨ËÃq,qX}áh"j=æ¬*XØ—;F˜Ðõò……µÇW¤äüÈÍ~°,-†0p63àiG`˜[õ“5zbouncycastle-1.49.orig/test/data/PKITS/crls/requireExplicitPolicy7subsubCARE2RE4CRL.crl0000644000175000017500000000052610350736725030135 0ustar ebourgebourg0‚R0¼0  *†H†÷ 0Y1 0 UUS10U Test Certificates1.0,U%requireExplicitPolicy7 subsubCARE2RE4 010419145720Z 110419145720Z /0-0U#0€Ë »Š£‘ç2DýPP`5 jE&0 U0  *†H†÷ ¦PZJ¸´…§b°¿gÖ7ŸV7ÿQžŽñz'â+düÛ(vic,6cHC?{)‡Ï-zŸ‹?¾ýçû\ûÁ5±'Ý´pð’y3 ‰‹Á–.rÎÛç öiäÇJºçÿšðo˜ùéªßÔÄ{Ö§ƒH3¨bouncycastle-1.49.orig/test/data/PKITS/crls/BadCRLIssuerNameCACRL.crl0000644000175000017500000000051210350736725024456 0ustar ebourgebourg0‚F0°0  *†H†÷ 0M1 0 UUS10U Test Certificates1"0 UIncorrect CRL Issuer Name 010419145720Z 110419145720Z /0-0U#0€È4ÛàµcQÑP¤2ÒÅYøCŒàg0 U0  *†H†÷ *•–¼¡¼é‹Û :Àö³¼ ï—lŃkæîËúTdž{ºèsÀÖåtLŒq¿Îç6ß•JØjqæj «›{ÞëÆì.ƒé aObß;_(˜[×ùcƒb/Þ Ÿ¨ZÔ‹‘[”Ï¿DØq‰ý™É’z kí]7‘ýbouncycastle-1.49.orig/test/data/PKITS/crls/indirectCRLCA4cRLIssuerCRL.crl0000644000175000017500000000074110350736725025461 0ustar ebourgebourg0‚Ý0‚F0  *†H†÷ 0M1 0 UUS10U Test Certificates1"0 U indirectCRL CA4 cRLIssuer 010419145720Z 110419145720Z Ä0Á0U#0€ßœj.YµvÆxõ9 Ûþ…Zc0 U0‘Uÿ†0ƒ ~ |¤z0x1 0 UUS10U Test Certificates1"0 U indirectCRL CA4 cRLIssuer1)0'U indirect CRL for indirectCRL CA4„ÿ0  *†H†÷ ~§!{ŽpÓ#¨×Õ·4Dà­â‰ö~[*·¯W¿•¿^kù@w‡êë±­ áU‚“ð»öåL3iåAÁÉn®´˜8 8á „Ù-Ÿ/~0|¡Å Ã9ª—µ0oÙéÝxÔùIi“Úé0.Î[‰Í[ÇH1i¼šjÌ/½[x´Ä­‹ïbouncycastle-1.49.orig/test/data/PKITS/crls/UTF8StringEncodedNamesCACRL.crl0000644000175000017500000000047610350736725025627 0ustar ebourgebourg0‚:0¤0  *†H†÷ 0A1 0 UUS10U Test Certificates10U UTF8String CA 010419145720Z 110419145720Z /0-0U#0€Ó(Ad \~“ V0¨ö(eÊû0 U0  *†H†÷ —šËÝèšó–5S)ti„ÉGõqŠð2Bd®šìñ*áJp×ü¸ò›k8Ö7[t×¼xÇœ±4Áv‡O1C%ΕR#ÍÐ8Åð&±ÑÊ+ñáßáç>j>ÙQ`_jx²PE9•@=-9{¯—ã2_øªp¬ImD¬,Òû¤\Õñ×#_bouncycastle-1.49.orig/test/data/PKITS/crls/requireExplicitPolicy0CACRL.crl0000644000175000017500000000051210350736725026051 0ustar ebourgebourg0‚F0°0  *†H†÷ 0M1 0 UUS10U Test Certificates1"0 UrequireExplicitPolicy0 CA 010419145720Z 110419145720Z /0-0U#0€wj³dõ±ìQz-e†ÿ~ JŽ'0 U0  *†H†÷ x”—ù­¶ŽeÝmìe»s7šfQ×—¶1ûb¤J!; —zMªÎÒ•÷6ewQèÕ ·b¯v8·wr, Š|1XÏÆÚ$eï~×!–¡òbÜ]ú7™{4¨ÍG¤Ë^ÿ´Xip÷;.|w´3‚}TÚó]Ü_¡–öÙ Ê› bouncycastle-1.49.orig/test/data/PKITS/crls/anyPolicyCACRL.crl0000644000175000017500000000047510350736725023412 0ustar ebourgebourg0‚90£0  *†H†÷ 0@1 0 UUS10U Test Certificates10U anyPolicy CA 010419145720Z 110419145720Z /0-0U#0€>³ž¢äC…ûg@1†›Æaí†Õâ0 U0  *†H†÷ *Ã-çó‘Ög{fˆù"èdÉ€¢ˆ»× „£u«Õ¯rÐúíNB)b#2%YM£EÁ¼®7ȲÐy–„ }¢ðX×Ä™dÌN‹_ˆöoÏî9T4Œ{çC &ØnÄøj퀚GÓ8»‚›þ¿knÉç>̱J£ß†:-ÊblÝ'¨Q´?źlbouncycastle-1.49.orig/test/data/PKITS/crls/NameOrderCACRL.crl0000644000175000017500000000061410350736725023312 0ustar ebourgebourg0‚ˆ0ò0  *†H†÷ 0Ž1 0 UUS10U Test Certificates1#0!U Organizational Unit Name 11#0!U Organizational Unit Name 210UName Ordering CA 010419145720Z 110419145720Z /0-0U#0€ÿø&Dô.ˆèø×¨K„‘¢ÈhbZa0 U0  *†H†÷ ´ÄVðã¤'¼ Ô™nj”\ ^3  lß=¥èÚÍSà&‚Ô‚4.ub𥰺wå²ÊÔqx,û<ËQXO¸"~`Á`dX`=¨6Ä7n´Á( M‰^1K}M35 ’8òpáôÆ~ý;œÂ×ÚÎm6;Î^(ûbouncycastle-1.49.orig/test/data/PKITS/crls/PoliciesP12CACRL.crl0000644000175000017500000000050010350736725023462 0ustar ebourgebourg0‚<0¦0  *†H†÷ 0C1 0 UUS10U Test Certificates10UPolicies P12 CA 010419145720Z 110419145720Z /0-0U#0€ãeéÔ†¹Ççó39^L¥ù0 U0  *†H†÷ ¢!æk ™fy-†§›Í7›Msß‘cÄÞUS°2¬È<½–ª®ÉO²|@×ô]™Žú+D-uï8†ÈY®äb䃴s4ÑR¼=»w~|ÉA LO©ÙÙ¼Fp/f Ô €ìƒN•­†w誦H)£Ÿ6Ãìšõ¤š õrbouncycastle-1.49.orig/test/data/PKITS/crls/PoliciesP2subCA2CRL.crl0000644000175000017500000000050310350736725024200 0ustar ebourgebourg0‚?0©0  *†H†÷ 0F1 0 UUS10U Test Certificates10UPolicies P2 subCA2 010419145720Z 110419145720Z /0-0U#0€që/íQ¥ÿ…IŒ|öK¦›¤”0 U0  *†H†÷ Éa+ØÛbR6g…Ò¿yNDL;.¡XG»-²?bÕœ}Ú½4†]DòìBØË7‡×s;Ñ‚ãé,ÖÛoõóÛÔ¿¿ªzQvÖVåö'TT‡èZá[dSÞ1iÂk¥þwŒ¼òBÖ­„jõ»”Àd¯J.hd/õ\±ÅÏbouncycastle-1.49.orig/test/data/PKITS/crls/PoliciesP1234subsubCAP123P12CRL.crl0000644000175000017500000000051710350736725025716 0ustar ebourgebourg0‚K0µ0  *†H†÷ 0R1 0 UUS10U Test Certificates1'0%UPolicies P1234 subsubCAP123P12 010419145720Z 110419145720Z /0-0U#0€Ì´ç\ùÕ7ÔPU²1–.䑤Äh0 U0  *†H†÷ ^‰bÅ;àø"ÍýâDsÀ#˜g‰)g®9;SL$…j7 Èú® 'í<âí5S£ô£ÎmcÙ†3,•ÎG•-Zð hyZ¨ª]y¹J»¢Z…¯9ª¶ Ú9ö ñ.ûbo-Ù·Ú¥’ý`s}Hóšs*ex*|ˆZbouncycastle-1.49.orig/test/data/PKITS/crls/nameConstraintsRFC822CA2CRL.crl0000644000175000017500000000051310350736725025455 0ustar ebourgebourg0‚G0±0  *†H†÷ 0N1 0 UUS10U Test Certificates1#0!UnameConstraints RFC822 CA2 010419145720Z 110419145720Z /0-0U#0€+6ftK“«1U‡¤1«6co5É0 U0  *†H†÷ G“ÍÖ›1°ÝjØÄâ^:sÍ+i\GuVkV¤/ÂfLk¤š†Sû&9>aÒ…œð¬ÈÁs¥Ã)Æ!LJZÖ!Në}¤¨.é1ï9Îøn+× Á­¾jÃØF$•êÏ,Æ„P¿x1‘y5ŒGÑ ªU4"ÖÔ¢¬¾¸`<bouncycastle-1.49.orig/test/data/PKITS/crls/BasicSelfIssuedCRLSigningKeyCRLCertCRL.crl0000644000175000017500000000073710350736725027760 0ustar ebourgebourg0‚Û0‚D0  *†H†÷ 0X1 0 UUS10U Test Certificates1-0+U$Basic Self-Issued CRL Signing Key CA 010419145720Z 110419145720Z ·0´0U#0€IÉü·Õ¤r¯瞃铦’£H9`' nuOà„‰> …ø¬2µvv« d•Nï/4iN=S–{^É´„b¢½_noȾŽÑO3r^Œá.óû#z:4>i?jDá¥þÌ]`#•£H—¿rÝ/«ýY\ÒÁLá÷­Ùbouncycastle-1.49.orig/test/data/PKITS/crls/PoliciesP2subCACRL.crl0000644000175000017500000000050210350736725024115 0ustar ebourgebourg0‚>0¨0  *†H†÷ 0E1 0 UUS10U Test Certificates10UPolicies P2 subCA 010419145720Z 110419145720Z /0-0U#0€äXJªØò‘õhž…#n 4ëÍ0 U0  *†H†÷ Ãký±ÉIþ§v3‡$÷ßA1¸7ò<®ŽÇ¡0ê¦S™J‹¡|®ÁNXOeâ ë Ì-õ¢ºîd:±Ÿ+Ò@'io2•ú…÷Èv‹Kz|úT„×ÿr#cFU äÒ8ƒ,W»`!ÜD j•­ðµW‚hô 7ô×F“ÍÄÆýÁbouncycastle-1.49.orig/test/data/PKITS/crls/requireExplicitPolicy10subCACRL.crl0000644000175000017500000000051610350736725026650 0ustar ebourgebourg0‚J0´0  *†H†÷ 0Q1 0 UUS10U Test Certificates1&0$UrequireExplicitPolicy10 subCA 010419145720Z 110419145720Z /0-0U#0€£Ca¾zó®eÑt¼Àó0üÖ:”0 U0  *†H†÷ åxßG¶àBxoõ87¦ûé‹4þÚ®pL¶²=S|ïX$¸‡¥ÀÊ|ýªº.výÀšó¹p¨CA"Qÿ 2®«mDì¸}NKÕ†ƒê˜dÏÜõ-Rî ˜©I­¶9LÕ”¥"N­µ­dIånªc›6(Ÿ_ÜÁ~~ÂîHczôbouncycastle-1.49.orig/test/data/PKITS/crls/inhibitPolicyMapping1P1CACRL.crl0000644000175000017500000000051410350736725026041 0ustar ebourgebourg0‚H0²0  *†H†÷ 0O1 0 UUS10U Test Certificates1$0"UinhibitPolicyMapping1 P1 CA 010419145720Z 110419145720Z /0-0U#0€ªidµRå¢c  ój? ²Ô´0 U0  *†H†÷ …™·[c[ Þ%5x%PVxë¬4ÇÍ­K€Ÿ² sÐÉÝ¢[åž0­ ­ŒV{9vª¦!+hÄ“ó9û|z÷-äÓ¬\¦8žõ·ÂTlçv›.t^̓%ÀÖM¯«)Gݰ‡y†óM‰€,!hìMÍgЈ”cÑÛ÷¤bouncycastle-1.49.orig/test/data/PKITS/crls/PoliciesP3CACRL.crl0000644000175000017500000000047710350736725023417 0ustar ebourgebourg0‚;0¥0  *†H†÷ 0B1 0 UUS10U Test Certificates10UPolicies P3 CA 010419145720Z 110419145720Z /0-0U#0€޽fŽUeÏQäY¦É*b¿÷¥¼0 U0  *†H†÷ p¡ À€ ¹Ë–½0YIWÓ›âñA?õñ×g«Û/¶m´åEº”U%œáq£Üímë‘3}@.„ÂEŠ&í ¥oP™ý{Ñ:Ï Ú ðzšNµñû›«TWU«·Ã¦Ä'éÈkƒ(hÌž ð™~ õòÊ5({xY|ˆbouncycastle-1.49.orig/test/data/PKITS/crls/nameConstraintsURI1CACRL.crl0000644000175000017500000000051010350736725025242 0ustar ebourgebourg0‚D0®0  *†H†÷ 0K1 0 UUS10U Test Certificates1 0UnameConstraints URI1 CA 010419145720Z 110419145720Z /0-0U#0€¬ºK _â¼a®áÙdZy¾EÖ0 U0  *†H†÷ Hbþ×LóšxMà–ÖK³“#–m¶k5%ã” þÈË=\{èóÏÃÛ–ÓbN·[“ÃA”èuÒŠg¿ó°%"™£LŸ‡± ¦·Èò+å²M´á¼Ã…·T)è~SíÒ̧•?q2]: ¡þ¯ºEAgûFjûx&qbouncycastle-1.49.orig/test/data/PKITS/crls/LongSerialNumberCACRL.crl0000644000175000017500000000057510350736725024654 0ustar ebourgebourg0‚y0ã0  *†H†÷ 0I1 0 UUS10U Test Certificates10ULong Serial Number CA 010419145720Z 110419145720Z0503  010419145720Z0 0 U  /0-0U#0€ß=Hûã2ç¹&R‹Úìø O³Çߦ0 U0  *†H†÷ z cžUÑë?7—Eal£!Ÿƒ½ÎcH|¨Ê6;Qfà#ßÞê†ræ’šcÇ10îbƒ># )#ìª.öº”Eç¯^D <+kŒ|zm¢÷µžêÖùM1‘êM·ï_Z.cü7ZÛ¦>Þk§„ƒÒ§[â…Ÿ ð3Së£ÑÔbouncycastle-1.49.orig/test/data/PKITS/crls/inhibitPolicyMapping1P1subCACRL.crl0000644000175000017500000000051710350736725026556 0ustar ebourgebourg0‚K0µ0  *†H†÷ 0R1 0 UUS10U Test Certificates1'0%UinhibitPolicyMapping1 P1 subCA 010419145720Z 110419145720Z /0-0U#0€¶¦ÁêÀRS߆ýfIä´F¾c3 0 U0  *†H†÷ ªüjéªmFŸeì»JãÞüîKja{Oʰ†ù>îBp¿pQ «ðµQOxòY[oy¶ÙÂ8ƒ"´®dcZ¯Xl¡â?dÎò$ ¤wRáÌ#?_§‰ …ûÍøÁ ˜»bÃb u8°“Ö¿"ÐÿR%r¼ÉÔåwú¶„»ÙE bouncycastle-1.49.orig/test/data/PKITS/crls/BadnotAfterDateCACRL.crl0000644000175000017500000000050510350736725024424 0ustar ebourgebourg0‚A0«0  *†H†÷ 0H1 0 UUS10U Test Certificates10UBad notAfter Date CA 010419145720Z 110419145720Z /0-0U#0€- &>a#.7§Êé2©Qàµ20 U0  *†H†÷ ¦ÝÙ½‡ •¥’éݼß´]1ÙvoÏÚ nø½AÖO£ôx¨g–ïŠÁw貃^ÐóS6¨x9ÒÏë·Wæ¬3‡œd£]qy·ˆ“D¥2y…üú¥¥Ö™`.¥..j`A)p*'·›Ruýžâ€ön9už¨p³Ê×bouncycastle-1.49.orig/test/data/PKITS/crls/indirectCRLCA3CRL.crl0000644000175000017500000000065310350736725023666 0ustar ebourgebourg0‚§0‚0  *†H†÷ 0C1 0 UUS10U Test Certificates10U indirectCRL CA3 010419145720Z 110419145720Z ˜0•0U#0€–(¼)¦­XŸg.ÇÂÁ—:ßîˆë(0 U0fUÿ\0Z X V¤T0R1 0 UUS10U Test Certificates10U indirectCRL CA31 0 UCRL10  *†H†÷ e»ˆòýŒvm’®õտȺ»Ô˜Þƒ¥ázé’–÷ÂÎ Þ{ 2Ȥ¦æQ±²å’bïFÓ|_7VG]<”¦>Yk,ž¬ð#„±ÍIÿŽgb52hí$¢v“\²€]¼&«Àô¡Þ:m ®fûnrIYþñ/‡Ò¼˜>3=Õbouncycastle-1.49.orig/test/data/PKITS/crls/indirectCRLCA1CRL.crl0000644000175000017500000000056510350736725023666 0ustar ebourgebourg0‚q0Û0  *†H†÷ 0C1 0 UUS10U Test Certificates10UindirectCRL CA1 010419145720Z 110419145720Z0"0  010419145720Z0 0 U  @0>0U#0€lÁ_ا-à†“\ ðI¹%[è0 U0Uÿ0„ÿ0  *†H†÷ l«‘K8bŽòH†¦¸¹ÃÂ(åÁØ;ÅŒobD7ö/Ô¾ÿ»(¤›!ÄïI›*èZï9‚îÚ—_w‰¦>B&w²—ÄÛîÊŒ­ÒÏ>‡èbouncycastle-1.49.orig/test/data/PKITS/crls/nameConstraintsDN3subCA1CRL.crl0000644000175000017500000000051310350736725025704 0ustar ebourgebourg0‚G0±0  *†H†÷ 0N1 0 UUS10U Test Certificates1#0!UnameConstraints DN3 subCA1 010419145720Z 110419145720Z /0-0U#0€­’.+ÑøŠ±·!.~Ži<4u0 U0  *†H†÷ .Ü<ýÌÂP JÓÞ`“uï(¯‡5ÇG^òÀs5\GJ½T„ù0L¡2'…ËÊržwp¬ r©ÒoP²®´)þÄ’–h³ÒÝ`AÕîÕfÛ´ðÔ_ l“Ø>ç¢Y¯Ÿ"°ñg+…ëÜ£­t‰ÝÛ*q¨"Ž/øÊ{óÏ2bouncycastle-1.49.orig/test/data/PKITS/crls/inhibitAnyPolicy1subsubCA2CRL.crl0000644000175000017500000000051410350736725026302 0ustar ebourgebourg0‚H0²0  *†H†÷ 0O1 0 UUS10U Test Certificates1$0"UinhibitAnyPolicy1 subsubCA2 010419145720Z 110419145720Z /0-0U#0€"ÉÕ1ÝÂvçÃÜ’üÀ…“ªæÍÎ0 U0  *†H†÷ ˆÀµhøÅ5 fÒT‚Íûä{ýàÿ 3ä´‚Ž@ŽF6\Œr¼¹ƒP+ÉÕ#@É£GÊÏA†¨þP©ìuxÉÑo”†Ã=ä9¯´ žˆ$þfù{õ•|ÜÅÊäLÓ‚»lÞŠòqÿ‹Ò •-Äâ7¿Ìé»uÞŸ†2bouncycastle-1.49.orig/test/data/PKITS/crls/onlySomeReasonsCA3otherreasonsCRL.crl0000644000175000017500000000066710350736725027326 0ustar ebourgebourg0‚³0‚0  *†H†÷ 0G1 0 UUS10U Test Certificates10U onlySomeReasons CA3 010419145720Z 110419145720Z  00U#0€I{ëOiû~£ßÛ#‘÷ZVjù¶00 U0nUÿd0b [ Y¤W0U1 0 UUS10U Test Certificates10U onlySomeReasons CA31 0 UCRLƒŸ€0  *†H†÷ Í(ff’¥’ü‘ûÆ}Íð ÕK@øý 9ô ¬N¯0 ÌëÌï|=@þÿûK`ÞŠ§~l™‚7BëðI‡#ôš²ßš Q)ªÄ¸˜=É)­ˆà ›“­ Šô¢ò15F8ð’$} ›m fÒˆo PNÉ™w6J‘MiF ûwJ=Þbouncycastle-1.49.orig/test/data/PKITS/crls/TwoCRLsCAGoodCRL.crl0000644000175000017500000000047410350736725023550 0ustar ebourgebourg0‚80¢0  *†H†÷ 0?1 0 UUS10U Test Certificates10U Two CRLs CA 010419145720Z 110419145720Z /0-0U#0€0ÈéJÞC&A#ŒSSŒ³GŽÊ0 U0  *†H†÷ ¯—ö8‘;ryþþŒ>eÜa¨rïŸs.ÜÛ’>*ܺ2ù— kR2 |‹‰¢‚òo0Ý_éì&Æ5Áú”yìLšš‚«?¾*>¯ØäŽÃÁÅ%ǃ˜nB‰^oÖÇøÒ9c4"•Vò$¡b¶žÿÔ0á·,pQ¿t<Ü©(U˜Õbouncycastle-1.49.orig/test/data/PKITS/crls/pathLenConstraint1CACRL.crl0000644000175000017500000000050610350736725025157 0ustar ebourgebourg0‚B0¬0  *†H†÷ 0I1 0 UUS10U Test Certificates10UpathLenConstraint1 CA 010419145720Z 110419145720Z /0-0U#0€Ús“àðe™}ÿ°&ö-15Y0 U0  *†H†÷ ´Œ Š÷4 ‘ò)šæoÜæ¢=1–[S +ÍQäÙܸòJ²è^“`…SHï™õ 4„•ˆß0”äçqúòëøäPlû|ã·)æ‘·^põÀ)íPlM ·yä¥cì׬ŸJLÙD>óúZö/µòQó²‚ÇJ“‹'z¨¡¨&:ëïMbouncycastle-1.49.orig/test/data/PKITS/crls/nameConstraintsURI2CACRL.crl0000644000175000017500000000051010350736725025243 0ustar ebourgebourg0‚D0®0  *†H†÷ 0K1 0 UUS10U Test Certificates1 0UnameConstraints URI2 CA 010419145720Z 110419145720Z /0-0U#0€†¤UcñŒ #§§¼ËlªmÐZÆZ0 U0  *†H†÷ sî­!$ˆÇp'‚ÏhúaÚ,©ž ´~ã¬Iü‚vÐl€³°6LDÚ骚ßf €ôð „/WG–á÷®æ¾…žSà—šh~ò2Œ×‰cÝ?G0DãBî0ÂÖÎ:FOlŒâCÃ~ZQÎ^szí÷Z¨ òðg¯á¸ëŸÍ+$bbouncycastle-1.49.orig/test/data/PKITS/crls/BadnotBeforeDateCACRL.crl0000644000175000017500000000050610350736725024566 0ustar ebourgebourg0‚B0¬0  *†H†÷ 0I1 0 UUS10U Test Certificates10UBad notBefore Date CA 010419145720Z 110419145720Z /0-0U#0€z3ø#Šœ*lO8"ÕËý}X0 U0  *†H†÷ ŠK\à3;^Y¥-~\-"ü´ªœQó8…£„3>håz ÙáÇjùHÌðî È´A·¦ *hŽtݶîë®úMPÄ€çzj ëdÊ¥¦d䘖uñPŸÃ¦È¶Õ·d{ŽÎ@ò¼RJå‹"®šY©ã§D ’¶vÌ%óǤðbouncycastle-1.49.orig/test/data/PKITS/crls/nameConstraintsDN4CACRL.crl0000644000175000017500000000050710350736725025115 0ustar ebourgebourg0‚C0­0  *†H†÷ 0J1 0 UUS10U Test Certificates10UnameConstraints DN4 CA 010419145720Z 110419145720Z /0-0U#0€3)茀L¦­'ƒ%gÅå¶vÌ0 U0  *†H†÷ }W=Å…[ ÑËfaºœ­Ñ|(/.RSc¬Áý0Òñ½ú‰—Ä/s©Ç6¿]æ*!òÙ®óGŒìü€ÉÅ=7ËZåŒV×¾çí÷!ÖlãøÍÜÆ½p¶0½ÑvGb3º¿—A¡Ïb!LÐI¨·Pù£c@^ù [¬Þ~ô'bouncycastle-1.49.orig/test/data/PKITS/crls/pathLenConstraint1subCACRL.crl0000644000175000017500000000051110350736725025665 0ustar ebourgebourg0‚E0¯0  *†H†÷ 0L1 0 UUS10U Test Certificates1!0UpathLenConstraint1 subCA 010419145720Z 110419145720Z /0-0U#0€asÛ b5j[¸bH#çø+ÞcúÃò½d9EuìL_…8Êœ™•›JÑ“b(½©y'1ØA8zÈ®ZB%èF„1Ïè8­ó¤>¨MqÌ7‰Z[> ­o•}4;oÿ¤£X×ÇXâÓ¿3=½Yó{cüW«bó'r§œm´7 Š;àG;# n:bouncycastle-1.49.orig/test/data/PKITS/crls/inhibitPolicyMapping5subCACRL.crl0000644000175000017500000000051410350736725026356 0ustar ebourgebourg0‚H0²0  *†H†÷ 0O1 0 UUS10U Test Certificates1$0"UinhibitPolicyMapping5 subCA 010419145720Z 110419145720Z /0-0U#0€ït]½'!\mwD&mÜ¿û¾ck 0 U0  *†H†÷ 3à#U5úŒè5!ø5(¦/W[kß>—vrs\Ú{†c€3^Èö;¡3àíŽïŠÌž3"µ”2˜eqÄ®è6Óž$QwêÑ©¡æÅb»‚*ª:Y¦rH•‘º4 &©Ôïk WŽd)pw4’ã낚Á2bouncycastle-1.49.orig/test/data/PKITS/crls/requireExplicitPolicy0subsubsubCACRL.crl0000644000175000017500000000052310350736725030011 0ustar ebourgebourg0‚O0¹0  *†H†÷ 0V1 0 UUS10U Test Certificates1+0)U"requireExplicitPolicy0 subsubsubCA 010419145720Z 110419145720Z /0-0U#0€Y×èân×yp‚aˆÏRä·I*0 U0  *†H†÷ °#ÂìâéÀ‡éuÓî¤Å;œ'Ä«²gtyø[ÍK î2Ž‹Òçg_Úƒ§1 ¸d*–xÛ¯w&:á˜×A¹å†œ±6¨’¿oÏb3>yå¦iû†¹gÏnÆØ»/ †ÝfÈ q¥hû‘žõÊX€~'àN:4E#ÌÁbouncycastle-1.49.orig/test/data/PKITS/crls/onlySomeReasonsCA1compromiseCRL.crl0000644000175000017500000000057210350736725026760 0ustar ebourgebourg0‚v0à0  *†H†÷ 0G1 0 UUS10U Test Certificates10UonlySomeReasons CA1 010419145720Z 110419145720Z0"0  010419145720Z0 0 U  A0?0U#0€àbšßP½[Iþ¾pÌÜ9n0 U0Uÿ0ƒ`0  *†H†÷ ™øá ¨]ÔM©\‘œ,¢Q|Ýa½J8 \ˆFVU)pÌÏDÙš¹”‚SHµM‰BÀÿ}Bà9˜Co@óé^ŽþV?ôL`")Ã}-êÒ–ñ=Î5Ô0rò›ü†Dû·:Ò¼•èÓ+¡dÉ%?nŠ¥›™äô¬ùêrœˆ¸¬ébouncycastle-1.49.orig/test/data/PKITS/crls/inhibitPolicyMapping1P12subsubCACRL.crl0000644000175000017500000000052310350736725027347 0ustar ebourgebourg0‚O0¹0  *†H†÷ 0V1 0 UUS10U Test Certificates1+0)U"inhibitPolicyMapping1 P12 subsubCA 010419145720Z 110419145720Z /0-0U#0€Z“Kï–ž®>C&¤y‹¢æ›!0 U0  *†H†÷ d€3zãèäf NM®Ëôõ²êMH$¾9žÁÚlú ¥¾G„'À>«xq“çnÈêò½Ã{üR¾ü²"€5³«W{#Ê9fíGÍ,«J(]#«${ãQ»xy %ÿOÅÑ,ág³ä)5+^ªªI»fR£| õWbouncycastle-1.49.orig/test/data/PKITS/crls/requireExplicitPolicy2CACRL.crl0000644000175000017500000000051210350736725026053 0ustar ebourgebourg0‚F0°0  *†H†÷ 0M1 0 UUS10U Test Certificates1"0 UrequireExplicitPolicy2 CA 010419145720Z 110419145720Z /0-0U#0€q¶ï´ï…|•›úÝÀ¿|þáÙü*z/ýH XimZè7&0gƒƒL±žkÐ`Bˆ%‘®B$êaº]4j|"k¾Ï,àg6Û(\¾½zu=¬Ï<šDŽÊ0zé—bouncycastle-1.49.orig/test/data/PKITS/crls/OldCRLnextUpdateCACRL.crl0000644000175000017500000000050610350736725024557 0ustar ebourgebourg0‚B0¬0  *†H†÷ 0I1 0 UUS10U Test Certificates10UOld CRL nextUpdate CA 010419145720Z 020101120100Z /0-0U#0€Àjóÿ#ŽÐGDPCQÂ|^1‰Ì0 U0  *†H†÷  Ü´P)–‡¡à¸.9nn•|¢E¨$]ÎÚjoŒzw^ØÖÿc¥hÅ>â‡W˜×+&.=V9œ“ŒÄí¯7Nœ.JT…‹T/²¥ÉÊZœÒ§vÅ’ÀË>icLù@þ@×ú®²_âô‹±/¼~Š´—!Š„f”ì_úM(bouncycastle-1.49.orig/test/data/PKITS/crls/inhibitAnyPolicy1CACRL.crl0000644000175000017500000000050510350736725024774 0ustar ebourgebourg0‚A0«0  *†H†÷ 0H1 0 UUS10U Test Certificates10UinhibitAnyPolicy1 CA 010419145720Z 110419145720Z /0-0U#0€fÛµ”Çij>+‘¹ßȨÐM+4D0 U0  *†H†÷ ¦"KÀC íåŽÑ‹ Ò̶‹›!èü/„¡Í< ¿s¾šò´å 1‡+aðÍ>­ÛØ-‘Ûº\ý•Y6 º ñy©h–¡.Ì jC“ €q·>Ž:Út1\삹<ˆÿoQõøØGŸ=<\˜¾ðÞØ¦VéSbÍ V‘ÇêÈ».¦8µbouncycastle-1.49.orig/test/data/PKITS/crls/requireExplicitPolicy10subsubsubCACRL.crl0000644000175000017500000000052410350736725030073 0ustar ebourgebourg0‚P0º0  *†H†÷ 0W1 0 UUS10U Test Certificates1,0*U#requireExplicitPolicy10 subsubsubCA 010419145720Z 110419145720Z /0-0U#0€”×wÅq*ÔÓoôQ ¶Ú¬2ã¯0 U0  *†H†÷ ŽB"¨Ç”ZÓrL˜ëX0XcAÏÚùžõo;N0’‹¨0¼Ë¬-”±bï¹i>0Ô2ÿô†Å]AF9R ßtå5ÄæX”ºÑ~äfáe#<æÞaNq^]$½Rÿ…©êzc7åÀæxJqE2Ç}+»ù5Í¢«ÃŽÉÛn~b”k­bouncycastle-1.49.orig/test/data/PKITS/crls/DSAParametersInheritedCACRL.crl0000644000175000017500000000036110350736725025724 0ustar ebourgebourg0î0®0 *†HÎ80O1 0 UUS10U Test Certificates1$0"UDSA Parameters Inherited CA 010419145720Z 110419145720Z /0-0U#0€]$îŠUòÆÉ²Â¿Šð²IO:³0 U0 *†HÎ800-‰3Äšg¶ÑÒúÆÛ ©ðœËÛZù“¼,û¾Kñ¢û“ܘô«bouncycastle-1.49.orig/test/data/PKITS/crls/RFC3280MandatoryAttributeTypesCACRL.crl0000644000175000017500000000061410350736725027155 0ustar ebourgebourg0‚ˆ0ò0  *†H†÷ 0Ž1 0 UUS10U Test Certificates10 ’&‰“ò,dgov1 0 ’&‰“ò,dtestcertificates10UMaryland1 0 U3451 0 U.CA 010419145720Z 110419145720Z /0-0U#0€ - \¨‚b*6¢MRÈå,P}+0 U0  *†H†÷ RÑŠË2fχ>©ê¢5BtOžC]ls NìEh¿=×åƒfà*„—ŽÒ)*ÆòAèüc<ŠZŒ@ëÃï^p©¯Ù܉(vÿ¶Ë^à‚÷­2<`X<þ$=Ÿhy˜ä €÷cë[ÍÊi€“Š&U㬹~ƒdÔ;&¿ýß_?@0bouncycastle-1.49.orig/test/data/PKITS/crls/inhibitPolicyMapping1P12subCACRL.crl0000644000175000017500000000052010350736725026632 0ustar ebourgebourg0‚L0¶0  *†H†÷ 0S1 0 UUS10U Test Certificates1(0&UinhibitPolicyMapping1 P12 subCA 010419145720Z 110419145720Z /0-0U#0€zŠ0öê\6@ ®ØŸ¿¹½‚ÌR0 U0  *†H†÷ sÔ$è:ymœ¤–tý`úe‚Æ &œdÖøÅŽÎp²¤ Aߢ6O-Voïâûç„Óª DgWˆ‹4±tŒW–›â·Ü.Ô£A»$ú¾,¤Ï¾ ªdÿoîá$ÈŽûýþ’ÖU„®qX,jeS49 C[ Al\%°?óbouncycastle-1.49.orig/test/data/PKITS/crls/pathLenConstraint6subsubsubCA41XCRL.crl0000644000175000017500000000052210350736725027415 0ustar ebourgebourg0‚N0¸0  *†H†÷ 0U1 0 UUS10U Test Certificates1*0(U!pathLenConstraint6 subsubsubCA41X 010419145720Z 110419145720Z /0-0U#0€•犖tù<ô›©IóÁš?Îp0 U0  *†H†÷ ¯?€h$îÀ?3[bIÏî‡÷’I3¢±°lç#J*é1üIvòö’Ò³2pPqŸ«l-§ïû>? ¸ßèN(É]ú£ïdÛ¹Ëf¢µºób\Œ[uö~Tª0Y PÁ#É‘I¿#ÞˆÆz9nÌDD@.‚eèt`bouncycastle-1.49.orig/test/data/PKITS/crls/inhibitAnyPolicy0CACRL.crl0000644000175000017500000000050510350736725024773 0ustar ebourgebourg0‚A0«0  *†H†÷ 0H1 0 UUS10U Test Certificates10UinhibitAnyPolicy0 CA 010419145720Z 110419145720Z /0-0U#0€@˜`æÈý\ÑØ/ êìEÏ0 U0  *†H†÷ `«¢Šã"Ë•JÅÊhFp Ð1°˜Ì­K#Œ>ü´Çz“ j1hÄÿ07{\Hmá…÷ЛsSÊb6\)ȯ¦@bÕõ¯2©J¶¢§ Ë»r.> wd-Y/üÏ/¦wƒš|h°öZcgt²:út¸Ó©p懼LyïÈ´1p®óï®z;bouncycastle-1.49.orig/test/data/PKITS/crls/pathLenConstraint6subCA0CRL.crl0000644000175000017500000000051210350736725025753 0ustar ebourgebourg0‚F0°0  *†H†÷ 0M1 0 UUS10U Test Certificates1"0 UpathLenConstraint6 subCA0 010419145720Z 110419145720Z /0-0U#0€Hx¹ÌQ1t9*7ÂD“~˜i€0 U0  *†H†÷ D4öÅÀ÷$B3¨äÊtq”v“çK|£‹¬®«F”ö ˆ¶à–«j’·mKªj°XX§~ÞÁ&Ô à{©äÝsÚ°Ì a«ÄÇËÂáfùò*ÂÉY_Ætø½»’$w4#}•™¿5àoÏ*¶)žYÒ /D%fjéZí™3µ>eiW•bouncycastle-1.49.orig/test/data/PKITS/crls/nameConstraintsDN1subCA2CRL.crl0000644000175000017500000000054710350736725025712 0ustar ebourgebourg0‚c0Í0  *†H†÷ 0j1 0 UUS10U Test Certificates10U permittedSubtree11#0!UnameConstraints DN1 subCA2 010419145720Z 110419145720Z /0-0U#0€Õ¯k( ­Hl ‚*ÿÒh /mW0 U0  *†H†÷ ¯õsG +ÎÁ\‚zíÍÎU…4~Fà”~Œ'œõR‰U[üé2³TuÀ­Š·ãú^s_&Ênâhä™L8;V%΂¥z?Ťx‹Òü¦OòmÖ_i˜¸Â OžGýf>¬äûUóK¿BTÎF¢\ýÄ_ØaZa›¡,¯ ¢.bouncycastle-1.49.orig/test/data/PKITS/crls/RFC3280OptionalAttributeTypesCACRL.crl0000644000175000017500000000063010350736725027002 0ustar ebourgebourg0‚”0þ0  *†H†÷ 0š1 0 UUS10U Test Certificates10U Gaithersburg1 0 U*John1 0U+Q10UA Fictitious1 0 UCA1 0 U,III1 0 U M.D. 010419145720Z 110419145720Z /0-0U#0€¯ŸÌ,¤cBWW×Wc_sÑ0 U0  *†H†÷ ’-ˆ0ë’tc2 ·™Rxƒï¨3‰¸WÿøðA w¾©˜〻°HÒW“¾;¸döš‘ßÔ—j¡Ç)Óæ«cƒ™ÁX‡Žî×…÷Ñ/4ĨwÃ]ÿ+ÅGøôÀ¡:„ ¤—øÊRþB)ÿâšà¬OáGlqÙÚÜbouncycastle-1.49.orig/test/data/PKITS/crls/indirectCRLCA5CRL.crl0000644000175000017500000000260010350736725023662 0ustar ebourgebourg0‚|0‚å0  *†H†÷ 0C1 0 UUS10U Test Certificates10U indirectCRL CA5 010419145720Z 110419145720Z0‚Ê0  010419145720Z0 0 U 0u 010419145720Z0a0 U 0SUÿI0G¤E0C1 0 UUS10U Test Certificates10UindirectCRL CA60  010419145720Z0 0 U 0  010419145720Z0 0 U 0u 010419145720Z0a0 U 0SUÿI0G¤E0C1 0 UUS10U Test Certificates10UindirectCRL CA70  010419145720Z0 0 U 0  010419145720Z0 0 U 0u 010419145720Z0a0 U 0SUÿI0G¤E0C1 0 UUS10U Test Certificates10UindirectCRL CA60   010419145720Z0 0 U 0u  010419145720Z0a0 U 0SUÿI0G¤E0C1 0 UUS10U Test Certificates10U indirectCRL CA50   010419145720Z0 0 U  ‚ž0‚š0U#0€”­Ñá~û7KA=mY€?DWm0 U0‚iUÿ‚]0‚Y ‚R ‚N¤p0n1 0 UUS10U Test Certificates10U indirectCRL CA51)0'U indirect CRL for indirectCRL CA6¤p0n1 0 UUS10U Test Certificates10U indirectCRL CA51)0'U indirect CRL for indirectCRL CA7¤h0f1 0 UUS10U Test Certificates10U indirectCRL CA51!0UCRL1 for indirectCRL CA5„ÿ0  *†H†÷ IG¡tû5çcÃ?ÿ4[ºÓ\¥?.ÑþÙ‘‹%©±âBœðù˜Â®”ÚÚ¸8QkBÁnÅžD¼:´6WøV¡®Lʶg.ÚÎQ³·ž¯T7ˆÒXŸÁ¦SyȪE²ÿacé^,{Ln¨q«{ªÄ½EΚ Õ÷¬ ƒ|b<ǯbouncycastle-1.49.orig/test/data/PKITS/crls/inhibitAnyPolicy5CACRL.crl0000644000175000017500000000050510350736725025000 0ustar ebourgebourg0‚A0«0  *†H†÷ 0H1 0 UUS10U Test Certificates10UinhibitAnyPolicy5 CA 010419145720Z 110419145720Z /0-0U#0€ÆŒq¦™b¦ÒToònÊ0µ:¿0 U0  *†H†÷ NÇ )xêïC£Þøo¥¶ò¬Ž“{ÎùOãHõõG±9 ´Î3ê¼rÁ «uYhhÝÈ–sú9*ˆÎSÐ=s'ÓaoÓuò/øËÔcqë „Ù¬Hmw:#6šc˜Mš½½wKY˜!Ò‰ýõðp†@žY_Þ¨ûòbouncycastle-1.49.orig/test/data/PKITS/crls/onlySomeReasonsCA4otherreasonsCRL.crl0000644000175000017500000000073410350736725027322 0ustar ebourgebourg0‚Ø0‚A0  *†H†÷ 0G1 0 UUS10U Test Certificates10U onlySomeReasons CA4 010419145720Z 110419145720Z0"0  010419145720Z0 0 U  ¡0ž0U#0€?¾@ñ÷kû°YäZà—Té0 U0oUÿe0c \ Z¤X0V1 0 UUS10U Test Certificates10U onlySomeReasons CA41 0 UCRL2ƒŸ€0  *†H†÷ =ÙµJ˜.ö„ìå×Õ E^‰'Ãüzê§>=¼ÿ&ñis¡/Ö‚6÷˜}&/†X´_΄mïJQè@JQ²WF¶vḈrÈttv8D‡ˆÂ¥Î4Ë©¿¡oé–ã§«?¾¥`²Kâ»ø„Nëi®òZéx¬8EMbouncycastle-1.49.orig/test/data/PKITS/crls/keyUsageNotCriticalCACRL.crl0000644000175000017500000000051110350736725025343 0ustar ebourgebourg0‚E0¯0  *†H†÷ 0L1 0 UUS10U Test Certificates1!0UkeyUsage Not Critical CA 010419145720Z 110419145720Z /0-0U#0€Ï*¡¥ýBâ3¼3*M˜s³ØûU¼Ø0 U0  *†H†÷ :MË<~ìOrG˜þº,yM/]èqú5Ó&µ'#ÀÅœ÷á–qÕ|jä@í}F(¡‘™«u+a¥ÅKÑc»•»Lî ŠŽÖe<†ò‹ Mj=á©æ(i‡ëäžÑE\Ý+/nUrâi͈„±Å^†DOΫ¤³íÇX„„Ìbouncycastle-1.49.orig/test/data/PKITS/crls/PoliciesP1234subCAP123CRL.crl0000644000175000017500000000051110350736725024713 0ustar ebourgebourg0‚E0¯0  *†H†÷ 0L1 0 UUS10U Test Certificates1!0UPolicies P1234 subCAP123 010419145720Z 110419145720Z /0-0U#0€¶{ƒˆI CÎò‚LóF†(„Ù0 U0  *†H†÷ EÔÞ4QHjÑKà×-URâå¥î¼¡ÆD ·aË¢X¡ÍŽåœ(LÄ ®£±ÈªŽŠYAW¶üÛ4¨æÉË\(oµ:pš©¬5ƒGz$iF&c) ÅQÃ’ÆÂmÏ^¸%ëÕ¶Ñb‡;›$j±ž3¢–»t!­·˜«²j%+ íbouncycastle-1.49.orig/test/data/PKITS/crls/requireExplicitPolicy2subCACRL.crl0000644000175000017500000000051510350736725026570 0ustar ebourgebourg0‚I0³0  *†H†÷ 0P1 0 UUS10U Test Certificates1%0#UrequireExplicitPolicy2 subCA 010419145720Z 110419145720Z /0-0U#0€Þ)ÖæãO—¨:¦êMäF_‚00 U0  *†H†÷ …_ù„ ã„ðêkNxȘéV›í™/Õ”‰` ‚@à” 6vžˆâ»âAÍ÷fä…ç­c×àz›NT'vIÄ0ÆÎjä·Ùõ”ç‘Z»ï#Šf 'Ì4÷?àðWCrO/¬uH¦«t•¡¢8[;mgKikÊ–°vƒ*µÃþbouncycastle-1.49.orig/test/data/PKITS/crls/deltaCRLCA3CRL.crl0000644000175000017500000000062410350736725023154 0ustar ebourgebourg0‚0ú0  *†H†÷ 0@1 0 UUS10U Test Certificates10U deltaCRL CA3 010419145720Z 030101120000Z …0‚0U#0€âO¿Þ@Öÿ3]"V‰Ü÷Îp½0 U0SU.L0J0H F D¤B0@1 0 UUS10U Test Certificates10U deltaCRL CA30  *†H†÷ ‡ùdéhà¨;*Šòt£&Š+~l³O®pÑã­9µºp%41›n²Yð¨V$gÉüvTtO(l}Q ×Riág+:ÑpÖŠåÅ’a)åUÆT»Š©´·ö;î±c£9,)°ó.ôÝvF@1 ~)«û5®¨sŽÊ¡#ŽPbouncycastle-1.49.orig/test/data/PKITS/crls/keyUsageNotCriticalcRLSignFalseCACRL.crl0000644000175000017500000000052710350736725027547 0ustar ebourgebourg0‚S0½0  *†H†÷ 0Z1 0 UUS10U Test Certificates1/0-U&keyUsage Not Critical cRLSign False CA 010419145720Z 110419145720Z /0-0U#0€›¤[ä"XµVÿ.²‚¿"èöø0 U0  *†H†÷  ПCê‹–¼Q§&â­¡Ù…ÔÄTgr;'¹QtÊ¥r¢ˆ!-ðF!Ê^6_»œ¤„cdŠRZ¸Õ_?Õs8ðõ~ãY€ïp‰Ú7Ô±1J”êÉq˜ªÄ®âŒ«}©zü#Wî)KÆx/eM8ßùntqW¡ªJŠ©«‡îbouncycastle-1.49.orig/test/data/PKITS/crls/nameConstraintsDN1subCA3CRL.crl0000644000175000017500000000054710350736725025713 0ustar ebourgebourg0‚c0Í0  *†H†÷ 0j1 0 UUS10U Test Certificates10U permittedSubtree11#0!UnameConstraints DN1 subCA3 010419145720Z 110419145720Z /0-0U#0€W«øœ'ÈÒôæÏoª 5gƒ$k0 U0  *†H†÷ šÿ¢ZJÙÑ}@¢¼ëoüMX;²wy`™^÷õ°9bg­·¦,ïÞv;&y·|<%·½‚x!“[fâãÙwæ¡mÜFˆù(^•{¦ÚJÃDŽôP¦ R†Í@Tf’0 d dA3]õ«Øa^¢`V§Õbouncycastle-1.49.orig/test/data/PKITS/crls/requireExplicitPolicy7subsubsubCARE2RE4CRL.crl0000644000175000017500000000053110350736725030643 0ustar ebourgebourg0‚U0¿0  *†H†÷ 0\1 0 UUS10U Test Certificates110/U(requireExplicitPolicy7 subsubsubCARE2RE4 010419145720Z 110419145720Z /0-0U#0€ç«Î(åhéji>)¥6cp¡š0 U0  *†H†÷ .ÑÑF`%oœ[ÉOnâþö:ŒëMPÍ6ÙªÏÎ0~Š $mgcȇi¤͆ªÒ;@8ÉùÿG#ñ>ÜøŸÑ¯0¥GYÏŠÂ*ŒœÙxc]ŒÏyú>ðŽ—Üg(¯_m‡åà&‹‘õiö 0ø^Ðyâ†Q62Hbouncycastle-1.49.orig/test/data/PKITS/crls/keyUsageNotCriticalkeyCertSignFalseCACRL.crl0000644000175000017500000000053310350736725030472 0ustar ebourgebourg0‚W0Á0  *†H†÷ 0^1 0 UUS10U Test Certificates1301U*keyUsage Not Critical keyCertSign False CA 010419145720Z 110419145720Z /0-0U#0€ß ¹4‰uxÒ#’ð!ßÂve´0 U0  *†H†÷ ž²ÛÛûB »Ö¯µ*çˆuðæ©R ­£M¦dãS´9ÛO–]êÚ» ÑÖ2S‘bí3é ‡lù JÅééoÕÑ"š×|‚ÒH Ã*ÂÙå÷wRçœ,}_1£ª2Êž­Bï³›ÍÚ6|Ë…HuY~lš pãÔÁÝÅz;bouncycastle-1.49.orig/test/data/PKITS/crls/onlySomeReasonsCA2CRL1.crl0000644000175000017500000000052610350736725024743 0ustar ebourgebourg0‚R0¼0  *†H†÷ 0G1 0 UUS10U Test Certificates10UonlySomeReasons CA2 010419145720Z 110419145720Z A0?0U#0€ª¡ïØ\Ø8²3‡ç“EAЊ{0 U0Uÿ0ƒ0  *†H†÷ ¨•˜¡4äý´¿”HÕB¥Ìá…UeÂçË3¡ýØÍ’PË¿êl⮼UHÏJ)akBL5öI0ç7”§8¼»<ŒÃê󽟠2¢¹ŠÏlëu×]_ñþ—÷Ø3èž!¶Žº*cÁ Wdݘ4OÛ¡Ñw‡ô°aÁ6Èbouncycastle-1.49.orig/test/data/PKITS/crls/BasicSelfIssuedCRLSigningKeyCACRL.crl0000644000175000017500000000057110350736725027001 0ustar ebourgebourg0‚u0ß0  *†H†÷ 0X1 0 UUS10U Test Certificates1-0+U$Basic Self-Issued CRL Signing Key CA 010419145720Z 110419145720Z0"0  010419145720Z0 0 U  /0-0U#0€rÊ3C©ÄQ«cÚD‡a¤ô¾G0 U0  *†H†÷ \Í£=žd÷dsœ,9âç׸>›ܘŽZåG1ý~§ÕŸR1È÷Т„?wÇñº~$b­®{ÿðâÎUõ'ÓÌ$Ȧ¸ÎBáì‡LÕixYÒ3”;'h€=o=¦ÇŸ+9Ÿ×Ãëw½Ì–³­$h™Ñ¿Œ>*øbouncycastle-1.49.orig/test/data/PKITS/crls/pre2000CRLnextUpdateCACRL.crl0000644000175000017500000000051210350736725025126 0ustar ebourgebourg0‚F0°0  *†H†÷ 0M1 0 UUS10U Test Certificates1"0 Upre2000 CRL nextUpdate CA 980101120100Z 990101120100Z /0-0U#0€½z6Õ] •¿]®«ì¤Q`&¯V0 U0  *†H†÷ ?AK[µGw~*‡cež÷–ŒAAæšOE‘íÝŒ±ÖãAqpí˜Q5â$»Í&ŠÉCñLXC*1^”¥^ “Ý ùÐÇýÖ‹MLo<×Ck¹‡ÀýöZ§Kðt#üa$û=2^÷ý†ÞR? .²ùµ™¢-–ƒ.¹©™XúÀå[‹üÐS2bouncycastle-1.49.orig/test/data/PKITS/crls/inhibitPolicyMapping0subCACRL.crl0000644000175000017500000000051410350736725026351 0ustar ebourgebourg0‚H0²0  *†H†÷ 0O1 0 UUS10U Test Certificates1$0"UinhibitPolicyMapping0 subCA 010419145720Z 110419145720Z /0-0U#0€0±¯Ü®Õ0ò 9¦ã,!8¯¢‹Ð0 U0  *†H†÷ ÎÕ‘R[ð!¹žÑ;\Ó©ñ·pQ«d¬Ó=Kæ½ëhû E~EK&µýÊf9›B-¼V’e9*(kÓj~jëÆ,?)sužÝ)åÔ\ýØÎ5÷ŒEd5yâË<8Vc8ÆÄ'aû¨±0<0U#0€£“«Wf&mr:l¼ƒe£šüŽ C 0 U0 Uÿ0  *†H†÷ %àæ eð+ñíGŒ¤Ýy&x"„–5`Þ{ìpîP=¬Ôš"þãšw¤û»†˜!€>Ó …W².½SÔz¬–>ggm“Ëü¶ñÂ# âÞÂZp45ŠrŒËx­b–†P]lº»å¸è_¶|3‹ªÆ±x§äVv zÛ®õÿbouncycastle-1.49.orig/test/data/PKITS/crls/requireExplicitPolicy5subCACRL.crl0000644000175000017500000000051510350736725026573 0ustar ebourgebourg0‚I0³0  *†H†÷ 0P1 0 UUS10U Test Certificates1%0#UrequireExplicitPolicy5 subCA 010419145720Z 110419145720Z /0-0U#0€•†‹‘6»zoâ„ïEŽ'k¸0 U0  *†H†÷ s„Täw¥}=|Цêkp‚š…Œ®=Š£+̧w ¾z¼/ÿƒæöz™¡¯ÅÎóvw¼ïï¢Ë–6;ý°Î\®0¯Ÿºçèòft‚nu‘±Y©ž‹A7B¨Ns1á±SûŠ=îÓäw¨øêê!õžµãy'ÞÃÕE°‡$bouncycastle-1.49.orig/test/data/PKITS/crls/inhibitPolicyMapping1P12subCAIPM5CRL.crl0000644000175000017500000000052410350736725027271 0ustar ebourgebourg0‚P0º0  *†H†÷ 0W1 0 UUS10U Test Certificates1,0*U#inhibitPolicyMapping1 P12 subCAIPM5 010419145720Z 110419145720Z /0-0U#0€æÞŽV°ó–ÊĪN’º 𔩔p>0 U0  *†H†÷ Ÿ§­ne¡›ÌIc®vT&_‹£ô˜ÛG€O8¿À öØß´~j®òœjœju™ß6îÓÞY‘2“Ã1l±ÍBËrt'If3àŠ™2{fk‹H!#mÄ´@Övœn¡¿•^¸éÇ¡ñ¼\(|sr…Úñ¦S\bouncycastle-1.49.orig/test/data/PKITS/crls/inhibitAnyPolicy5subCACRL.crl0000644000175000017500000000051010350736725025506 0ustar ebourgebourg0‚D0®0  *†H†÷ 0K1 0 UUS10U Test Certificates1 0UinhibitAnyPolicy5 subCA 010419145720Z 110419145720Z /0-0U#0€JwbX#¢Ã¹îÇnß퉈M—o0 U0  *†H†÷ †ª | r—G4ml—X-Ùj ÅŒß19÷"Ϩ ?q‘{rÌ®½µÆ!ì•©|•ŠM°õ«ÿ¿\$ýöÒaïЊn„)Ïl2½y¶»áËqÉïëýʇMÉT[Gîù9ÄœÂýd+f ¨lƒ›äú]Š4‘™éš 4`| ºDbouncycastle-1.49.orig/test/data/PKITS/crls/RolloverfromPrintableStringtoUTF8StringCACRL.crl0000644000175000017500000000053710350736725031363 0ustar ebourgebourg0‚[0Å0  *†H†÷ 0b1 0 UUS10U Test Certificates1705U .Rollover from PrintableString to UTF8String CA 010419145720Z 110419145720Z /0-0U#0€7—¤Û4U5É´MÆ~K褉<0 U0  *†H†÷ *r’Í2ÐÄ™cG ›•('ŽI8¼T§Ú÷+X4ؼ­>¤ú…„ûI•? Ãû”*©fDáUOݺl½øù¾ Þ(TýÍôP¬Lžæ’¿Ͷi]ó=%ù-Ô^Nž´ò”0 'M/mAN1® *Ø42’Ö±!™W.cbouncycastle-1.49.orig/test/data/PKITS/crls/inhibitPolicyMapping0CACRL.crl0000644000175000017500000000051110350736725025634 0ustar ebourgebourg0‚E0¯0  *†H†÷ 0L1 0 UUS10U Test Certificates1!0UinhibitPolicyMapping0 CA 010419145720Z 110419145720Z /0-0U#0€léÇ B@AõópŽîáÑR^×7Z0 U0  *†H†÷ ̘êëzð.f:.kýÄ*‰FdZÊÒU>½¼Îôv~h¿òsËÒ´ä´!kàNêÅa =¸ÛaâÕ'HeËGÑf;)©Çfö ,HšÃ7©°t‘³Ôê,¯¨JjNû@°è^XöË‚SGCyï‰k^陃]@íòbouncycastle-1.49.orig/test/data/PKITS/crls/requireExplicitPolicy4subsubsubCACRL.crl0000644000175000017500000000052310350736725030015 0ustar ebourgebourg0‚O0¹0  *†H†÷ 0V1 0 UUS10U Test Certificates1+0)U"requireExplicitPolicy4 subsubsubCA 010419145720Z 110419145720Z /0-0U#0€÷„+ݱû•ºzZbàs1²*Èy0 U0  *†H†÷ àðèu]ÖOÜ)êÛ"¶»rñÿµà1œdÙ;+Mx÷^« å‚~a•yB»VxÝš’^ èúx³³âJž×Ñ0`}1äa Þ¬é —ª@VÞ6¨âEörÂNÓ-U%ž ÝÚ@‚ØuDu5’’üy»Ø±TƒÿÚßêbouncycastle-1.49.orig/test/data/PKITS/crls/requireExplicitPolicy4subCACRL.crl0000644000175000017500000000051510350736725026572 0ustar ebourgebourg0‚I0³0  *†H†÷ 0P1 0 UUS10U Test Certificates1%0#UrequireExplicitPolicy4 subCA 010419145720Z 110419145720Z /0-0U#0€#a8q, a¾¢¼×Õ‰ÖØP>½ëÅ0 U0  *†H†÷ £œgDW ÒxFûçv»fÌ`,z~Öì¤ÂM,QŠ—âÂzç{MyIÂl¢·¥átdšõz]Ì.%Ý¢ý„®ØÏêúYwž";~—õt4qÁjKn’ЩmÍÊ_iȰµ—x_±4Ó0 6ó.ÝR3a,ÏtqGžôfbouncycastle-1.49.orig/test/data/PKITS/crls/P12Mapping1to3subsubCACRL.crl0000644000175000017500000000051210350736725025244 0ustar ebourgebourg0‚F0°0  *†H†÷ 0M1 0 UUS10U Test Certificates1"0 UP12 Mapping 1to3 subsubCA 010419145720Z 110419145720Z /0-0U#0€ö,±·)µ®•°ø9AS-.ãÇ0 U0  *†H†÷ o³)65vÇbné)惋^¿%êMqVP%’h¨¢éM £t6â›ÁR݇ d˜XÚj–æÄØÍLqL˜»Ô}tù4?˜÷Š^ë¿|*{Äó)Ì¡—Η„éyrÁ¡Lz³x™—ͤí0,ß6dFÿÁ a&‰Ç@²bouncycastle-1.49.orig/test/data/PKITS/crls/inhibitAnyPolicy1subCAIAP5CRL.crl0000644000175000017500000000051410350736725026125 0ustar ebourgebourg0‚H0²0  *†H†÷ 0O1 0 UUS10U Test Certificates1$0"UinhibitAnyPolicy1 subCAIAP5 010419145720Z 110419145720Z /0-0U#0€)cÞæÂ‚={_t s¨°oh0 U0  *†H†÷ Ï©ÒnY"%k*ß&¬îdÏ-e­C"ý{ì„ÀN±Ü®ÓEº‘-¶|¾¥€\Ö≀þTŽøÝä ÆÂ$na”DjþMD¬¾ûFLÇ;$6ÁÕœ‰>¦øó~ yeh Å0LÓäÁÈ~-še¶à„,²Xâü–•Ëáåúè›bouncycastle-1.49.orig/test/data/PKITS/crls/SeparateCertificateandCRLKeysCA2CRL.crl0000644000175000017500000000052610350736725027311 0ustar ebourgebourg0‚R0¼0  *†H†÷ 0Y1 0 UUS10U Test Certificates1.0,U%Separate Certificate and CRL Keys CA2 010419145720Z 110419145720Z /0-0U#0€UüÒÚ«dòa7)žÓ(Ïa*§0 U0  *†H†÷ s%â‚ÊFZˆ ¤»—†2Ø ÇŽmóCÕ¥ã‡öoZVI‡Áø&gâì(Ãá?«ªí?@š à"Gº:´ÿê]€‚ßh ­°½<V‡.ÔèÏS¬ÀAú]"S<õn%äCYÈ"OÚ8UÝ’Ó°#'ŽÅ…5(â§kyù%Cîbouncycastle-1.49.orig/test/data/PKITS/crls/inhibitAnyPolicy1subCA2CRL.crl0000644000175000017500000000051110350736725025565 0ustar ebourgebourg0‚E0¯0  *†H†÷ 0L1 0 UUS10U Test Certificates1!0UinhibitAnyPolicy1 subCA2 010419145720Z 110419145720Z /0-0U#0€«ÈA&ÐÕLæ+Vgìï‚ÄÂÝòU0 U0  *†H†÷ …ëh»‘]š *÷\sèK#’ÃÖ³‹ºÒ¹Ü¡äH)¨˜ÏYÛ+ÞÎÛÍZÝÞõ󑜦ÈLÑî$|•ß íMù¥C‰¯ö$°pœb†ø áaÖ™í{ˆXŸyÖ:ºªR—^}ΚÒ4Ÿ ¼ ø-ÅÒ×ë©Y%Ebouncycastle-1.49.orig/test/data/PKITS/crls/requireExplicitPolicy5CACRL.crl0000644000175000017500000000051210350736725026056 0ustar ebourgebourg0‚F0°0  *†H†÷ 0M1 0 UUS10U Test Certificates1"0 UrequireExplicitPolicy5 CA 010419145720Z 110419145720Z /0-0U#0€Õâ†-ñ+hœ^¿+¸f™žCº0 U0  *†H†÷ 2•nI-~ŸŸ}Ö<°sM*؆÷/aõ9€Ç´æ;Œlý›ÃR¹ª.»Ž%¹öu·,üETöIiâxï%ÒË~ø{–Ù7ºôfáçV–ïv½L”ý¨5Ñ*i()–‹¥¯¼ÙBÿê25›=WÚž¡Õä>äOKZHGs8]bouncycastle-1.49.orig/test/data/PKITS/crls/BasicSelfIssuedOldKeyCACRL.crl0000644000175000017500000000056110350736725025557 0ustar ebourgebourg0‚m0×0  *†H†÷ 0P1 0 UUS10U Test Certificates1%0#UBasic Self-Issued Old Key CA 010419145720Z 110419145720Z0"0  010419145720Z0 0 U  /0-0U#0€ºŒ!‡s˜úë¹ÙoA¤EÕ†ê0 U0  *†H†÷ bÞ“Œ6ݲqV»Nä27QÞnÝ>%ŒÔ~üfTt 20ÒIÜ­j´üìæVþæìSžAf1,î:¾½t4›qÁg;(¹…årÍð+§ÙÕãC%JR.y$RÏuá<5‚Ñ]ö‹E$g턟ÇÀU^Rv>/ô¯®Ø$£h]µEtbouncycastle-1.49.orig/test/data/PKITS/crls/P12Mapping1to3subCACRL.crl0000644000175000017500000000050710350736725024536 0ustar ebourgebourg0‚C0­0  *†H†÷ 0J1 0 UUS10U Test Certificates10UP12 Mapping 1to3 subCA 010419145720Z 110419145720Z /0-0U#0€]ĺxy4&ÃrWÑYô£âT§(qÑ0 U0  *†H†÷ »"ž_®}&v[o‹¤7ú‡ƒa#pÊò½º®r> !pN—LãÐïÙ1Po[ÿQ@s‚ò»ø“h¹ ²Ã[VsRÓu/Q[@?‹qBT3¯U Èÿ¿ÿhCx“Uû~MÛ¨W64ߢu»ú#óŸÞäM’0eŒòdàbouncycastle-1.49.orig/test/data/PKITS/crls/inhibitAnyPolicy1subCA1CRL.crl0000644000175000017500000000051110350736725025564 0ustar ebourgebourg0‚E0¯0  *†H†÷ 0L1 0 UUS10U Test Certificates1!0UinhibitAnyPolicy1 subCA1 010419145720Z 110419145720Z /0-0U#0€) x”Ž„)BK|«ƒ*¾5[<0 U0  *†H†÷ u;BDÅú«²Äc¬‰„àP2K–€H¸ImBÃL´½ )àVß’' ·óz22-Íî)8ÐuŽŒQ’¦¯ï#޼²¦G6ÑœæÝKUVG@gK½´ÐtZ—ƒ ÕN§Ò»­R¥¬Dü•Ùpú¢ûsâa¬bouncycastle-1.49.orig/test/data/PKITS/crls/pathLenConstraint6subCA4CRL.crl0000644000175000017500000000051210350736725025757 0ustar ebourgebourg0‚F0°0  *†H†÷ 0M1 0 UUS10U Test Certificates1"0 UpathLenConstraint6 subCA4 010419145720Z 110419145720Z /0-0U#0€H4T¦ìOÙ˜!ìÔc±#oíy>0 U0  *†H†÷ z^äâ¯\H:Â6Ñ—f°Œ7‹–²Á¼µ:µDÛ„*…Á|–ý³lGicæ¢Õk)vâráKjÔ"€ËX 9ªGE „ÐÔåqï»;'°å“ϲ‡C¼¥zP"CHßšçÌŒ>Tý…>é¢GOø®”…2Jˆ”·Äbl¸bouncycastle-1.49.orig/test/data/PKITS/crls/inhibitPolicyMapping1P1subsubCACRL.crl0000644000175000017500000000052210350736725027264 0ustar ebourgebourg0‚N0¸0  *†H†÷ 0U1 0 UUS10U Test Certificates1*0(U!inhibitPolicyMapping1 P1 subsubCA 010419145720Z 110419145720Z /0-0U#0€~—C¤}Þe‘;7}'½¤óУ0 U0  *†H†÷ Ìò±ô‰ðASÈfÇMoˆ¡cE(ÿQÀµ§›³wÙíñn€fô Ï5«gýà| PDúN½ëi´å€V¢!²Œ 6m¬´†»iÿfÄ¢¿ãp_*ÝÁxϨÏÓ3K²gm–#;hãÀqˆ8~ýû÷Zywölõbouncycastle-1.49.orig/test/data/PKITS/crls/MappingFromanyPolicyCACRL.crl0000644000175000017500000000051210350736725025542 0ustar ebourgebourg0‚F0°0  *†H†÷ 0M1 0 UUS10U Test Certificates1"0 UMapping From anyPolicy CA 010419145720Z 110419145720Z /0-0U#0€÷Á«5Ø/†Z67YoÁÁ¤m¤¤H0 U0  *†H†÷ °ÒhÉ \Ýèàáí•5ÍpÖ$ˆ×7ÓY8ÃQdʪÄ1€Åך8_gÇÝ ˜q¡³eÝ Ë‡ÅŠâ¿&' V ÃF±uOó[=ì„ùáÇé"o)²kdäª{^½„þ¯©%˜}{¸ðï?ßù&¦„Ðn¹-½•Gz¨((bouncycastle-1.49.orig/test/data/PKITS/crls/MissingbasicConstraintsCACRL.crl0000644000175000017500000000051410350736725026300 0ustar ebourgebourg0‚H0²0  *†H†÷ 0O1 0 UUS10U Test Certificates1$0"UMissing basicConstraints CA 010419145720Z 110419145720Z /0-0U#0€F ]7Ò©“E¬í\1çÍö0 U0  *†H†÷ ”IG›Þfß@5•ƒõ’Ú 3x™Íœ42ê†H:žºÆZÞ[h œõ¶ãGþ)EªÄQ!¶pí(ÍÁòCçHx{n(_qùV*":|‹‹|Šô,#gǶ´…™ÙH)Èl­¾$§:ŽVê’K䨛÷³éµ‡úbouncycastle-1.49.orig/test/data/PKITS/crls/TwoCRLsCABadCRL.crl0000644000175000017500000000055410350736725023345 0ustar ebourgebourg0‚h0Ò0  *†H†÷ 0K1 0 UUS10U Test Certificates1 0UBad CRL for Two CRLs CA 010419145720Z 110419145720Z0"0  010419145720Z0 0 U  /0-0U#0€0ÈéJÞC&A#ŒSSŒ³GŽÊ0 U0  *†H†÷ û¨i ªŒMòôjk8®Ú¸À‹Ò#–:ýÔ‚ÅÞVºÂYž—gÑKÖ$@˜K±Â…<¾ã¾(š>V˜Lh6¨ëæÕRÞ0Iàv ¿¾>š²øÞQðôÚYHÅŸG!2)Ùðu¦oÑT§œWO'ôÜ%]bouncycastle-1.49.orig/test/data/PKITS/crls/pathLenConstraint6subsubsubCA11XCRL.crl0000644000175000017500000000052210350736725027412 0ustar ebourgebourg0‚N0¸0  *†H†÷ 0U1 0 UUS10U Test Certificates1*0(U!pathLenConstraint6 subsubsubCA11X 010419145720Z 110419145720Z /0-0U#0€j6ðWu?BPµé(7Å­â¼0 U0  *†H†÷ “ÁÔŸSô†UfFº/‚ßíR•ËðÀ%ʲú€Ç´P£•pê±0þÉÚ ´û¦ŸUì?ß7»DÏj\}ú4“|_ðÖüÜŸ-¼?€YÞ1ºÈè©<ç(èË÷Mâö&ÍE/Ôpwh®]UÆûô]d<à0§-:íN{¡âpÚ0äbouncycastle-1.49.orig/test/data/PKITS/crls/P1Mapping1to234subCACRL.crl0000644000175000017500000000051010350736725024614 0ustar ebourgebourg0‚D0®0  *†H†÷ 0K1 0 UUS10U Test Certificates1 0UP1 Mapping 1to234 subCA 010419145720Z 110419145720Z /0-0U#0€­ïW}ºƒïÿ‡hsÒ¦—0 U0  *†H†÷ 3S,­néID}Þ\ÜKW55òÙK”Æ8N3§~l´·ÒrF(KÕÊ3ì¿Ïé¤JÅᦠ·M†î“îÚ­Ú×ÍjÚ•ëb0õ3"ú{*øÊg$NöN¾ª1#Bë v›ðd$•ô¸b{^$ýolŽ‚³`©Àbouncycastle-1.49.orig/test/data/PKITS/crls/basicConstraintsNotCriticalCACRL.crl0000644000175000017500000000052110350736725027100 0ustar ebourgebourg0‚M0·0  *†H†÷ 0T1 0 UUS10U Test Certificates1)0'U basicConstraints Not Critical CA 010419145720Z 110419145720Z /0-0U#0€ظß+ü ®×VË\>zŒÏ‘0 U0  *†H†÷ ÜŽE~mVë½\Ç! ®i·5¢µ14…ð ’} 6.2ܹŒË­9—5:œÑh7ðš­ÚBg’0‚¸RÛÅÕ9Ô/Í{ìCVm×/1œYHú¯ùý:·à²K |é{uX¢p»0»â!4têãAåÐÀ´}QRöQ¾x–%¥Šbouncycastle-1.49.orig/test/data/PKITS/crls/onlyContainsAttributeCertsCACRL.crl0000644000175000017500000000053710350736725027007 0ustar ebourgebourg0‚[0Å0  *†H†÷ 0Q1 0 UUS10U Test Certificates1&0$UonlyContainsAttributeCerts CA 010419145720Z 110419145720Z @0>0U#0€Å(•›Ã£Ù¸û¶ßmãS­¹"0 U0Uÿ0…ÿ0  *†H†÷ MÐñ§76äWÒå»Àh5‘ „SUž/¿KÔ~UOêlqôT¥·8P¬CÇ…¹ˆO6\5\ƒVIêÐ4οÖ!@øJbîĈt÷ÌFÓŽ_.ïCÏÚ„Ô'±"Ƶ­ƒÍª‹Ï×v7¦)Ž:ç?X+wX±ë5m–töHbouncycastle-1.49.orig/test/data/PKITS/crls/PoliciesP123subCAP12CRL.crl0000644000175000017500000000050710350736725024551 0ustar ebourgebourg0‚C0­0  *†H†÷ 0J1 0 UUS10U Test Certificates10UPolicies P123 subCAP12 010419145720Z 110419145720Z /0-0U#0€Z‡!ûÜ“mš |Çj±hKßU×0 U0  *†H†÷ g¸µó‰• R›#í‚3„™Õù*ºzýa.2›¿PÐ̸^ ù}k×Î)}Íš JÉï8.¦F¥JºXq!jRå/ÈXºÝ»µ> [”:–ÐGú¤„7ÀäZB1ÆÌB2…ªäp#âÏëþóþàƒ¼Ä¸ÀÙWÒbouncycastle-1.49.orig/test/data/PKITS/crls/onlySomeReasonsCA2CRL2.crl0000644000175000017500000000052610350736725024744 0ustar ebourgebourg0‚R0¼0  *†H†÷ 0G1 0 UUS10U Test Certificates10UonlySomeReasons CA2 010419145720Z 110419145720Z A0?0U#0€ª¡ïØ\Ø8²3‡ç“EAЊ{0 U0Uÿ0ƒ0  *†H†÷ 8|:Gú×zù <øÛ”ç úGk®hôø´L{p¥ _’Œ¸Ã2éU48SaºÙ=Ü9EÜQ\«{g€G¸`lˆKŠWýsi ÿ-Ã#Šbê1ÃJ;‹‰¦ÝNè‹™gqb’Û@¯à´á bBi¶EdØ”O0@Cé8:Y)mr Œbouncycastle-1.49.orig/test/data/PKITS/crls/nameConstraintsDN3CACRL.crl0000644000175000017500000000050710350736725025114 0ustar ebourgebourg0‚C0­0  *†H†÷ 0J1 0 UUS10U Test Certificates10UnameConstraints DN3 CA 010419145720Z 110419145720Z /0-0U#0€‹ã¸XVŸjß=Ø;³6á˶Ê0 U0  *†H†÷ ©>ùÃ\°ë…YÛÉr>´+0m"ÜœŸüŠ­›H°ŸG>ÒDl=Äl»‚l&…ëœH“ œf%…±^þq£Ö-MÀË?Fþê1ŠÛÒõ³H­ H ´ÍéÅ]j?ø¼™9[)ˆ-}´¾”採~1*Fù<ÑÂiþbô»°k¢bouncycastle-1.49.orig/test/data/PKITS/crls/UIDCACRL.crl0000644000175000017500000000046710350736725022065 0ustar ebourgebourg0‚300  *†H†÷ 0:1 0 UUS10U Test Certificates10 UUID CA 010419145720Z 110419145720Z /0-0U#0€Òe|ÂÙAˆìÕXDšâÌx0 U0  *†H†÷ i»»'x“pp¼[ëÐ:žx:ãÜŠw“ájɃõdø _' ©ƒ£Äó‡ê$øyA¤DV“x½åƒÙ`/.Ð’A* Ÿ_ˆ˜´kËx˜Ú0Ò7ÒDÇÓüže‰.ôw}õŸK÷r?2ÙØR ÜÎQ!õ%Y4R$­ i/-bouncycastle-1.49.orig/test/data/PKITS/crls/DSACACRL.crl0000644000175000017500000000033310350736725022043 0ustar ebourgebourg0Ø0™0 *†HÎ80:1 0 UUS10U Test Certificates10 UDSA CA 010419145720Z 110419145720Z /0-0U#0€tÕ$½^eˆá‹ ~êHNa0 U0 *†HÎ8/0,F ÒKùÍ‘ éqj¿Ò>ˆ]ÐGîª%®ÓjÊ?¤TAÙ£Wt³H«ÅŸùbouncycastle-1.49.orig/test/data/PKITS/crls/pathLenConstraint6subsubCA41CRL.crl0000644000175000017500000000051610350736725026556 0ustar ebourgebourg0‚J0´0  *†H†÷ 0Q1 0 UUS10U Test Certificates1&0$UpathLenConstraint6 subsubCA41 010419145720Z 110419145720Z /0-0U#0€ÆÅÝ=×ûtC@ÉÐªå¡ Ö4Š0 U0  *†H†÷ q›ö­9nؾø²‡…uK5<çRH¯ã±{m.YY¯Ìˆ7;xøMzæn#PL€òéÕÏyÎèžøÄ‚+oJ«)½[4W_1];¦µÚWKâ_ãñ°%’òÆW&šN6ÙÉk7ó}¶-l÷Çv×>)g‹.šø,SÚ¦Çl¶V ûßbouncycastle-1.49.orig/test/data/PKITS/crls/PoliciesP123subsubCAP2P2CRL.crl0000644000175000017500000000051410350736725025402 0ustar ebourgebourg0‚H0²0  *†H†÷ 0O1 0 UUS10U Test Certificates1$0"UPolicies P123 subsubCAP12P2 010419145720Z 110419145720Z /0-0U#0€‹ì9ó£®n9pdh+MT,ŽÀ0 U0  *†H†÷ š|8Œ• âŽÆûLCõOÆKì.»¡‹gw?UŠí*ðN |èØÁ&7G(ºåGÞyt0´¡f½Ž}šO7Rq­ÆP±ûÎë ðXT¨"QŸÕÓ’ 5öâKލø8£QûÍ’K-@/ù¹ÿ%Mð} ãë”$þíâ³~üûÁNÏ0bouncycastle-1.49.orig/test/data/PKITS/README0000644000175000017500000000016710355160030020070 0ustar ebourgebourgPKITS test data from http://csrc.nist.gov/pki/testing/x509paths.html For more details please check the website above. bouncycastle-1.49.orig/test/data/PKITS/certs/0000755000175000017500000000000012152033550020327 5ustar ebourgebourgbouncycastle-1.49.orig/test/data/PKITS/certs/InvalidpathLenConstraintTest11EE.crt0000644000175000017500000000123510350736724027240 0ustar ebourgebourg0‚™0‚ 0  *†H†÷ 0U1 0 UUS10U Test Certificates1*0(U!pathLenConstraint6 subsubsubCA11X0 010419145720Z 110419145720Z0c1 0 UUS10U Test Certificates1806U/Invalid pathLenConstraint EE Certificate Test110Ÿ0  *†H†÷ 0‰¯ÊϦ¹F¹ËWí=Ÿæ0ö,XFÈ–+σÛ1yµ*‹˜í[¤òáJS7\¶47am’}»ª¸S eÌ bÛ+ že‹Kñnê À“ˆ€î±ÿ¿Šß;u¬ôVË6ºfП|ß|âDäíuF.(mÆCÞVt`%4c˜Á£k0i0U#0€j6ðWu?BPµé(7Å­â¼0U¦³K•j6‚+”?†öâ÷˜ã“f0Uÿð0U 00  `†He00  *†H†÷ eA‹ DºÎœÑâóK‚F Ú핈ãnùJWåIŒ„PdGv ‰2b¬6±F¶à© Ó;"xÅ´0xpN Ü0çìuÏNj§¶¨qx¬TBäÁÏÜVªŸ§ìüÙªCsz˜™tp¬MØ²Š {/ý-Z;ç¾o~àtÈ“iF¹3bouncycastle-1.49.orig/test/data/PKITS/certs/DifferentPoliciesTest3EE.crt0000644000175000017500000000120510350736725025606 0ustar ebourgebourg0‚0‚ê 0  *†H†÷ 0E1 0 UUS10U Test Certificates10UPolicies P2 subCA0 010419145720Z 110419145720Z0[1 0 UUS10U Test Certificates100.U'Different Policies EE Certificate Test30Ÿ0  *†H†÷ 0‰×4ÝtýŇs–#üßg•V0¸».VǼüKñ çpÿ“Ž üM$’~kôV²-÷cxÆÕ6HÓø½á(#µŽvÈ=“‚ÈÞ!õÎ#™Ô劌« #m9lø”ní´báÙÕ`p}éiÆ[§Ür¡-áQ†0¤!W`µ³£k0i0U#0€äXJªØò‘õhž…#n 4ëÍ0Ur:{Ïw1FÕ¦´–B"¥~j>0Uÿð0U 00  `†He00  *†H†÷ %Ÿ€4Þ ‹‚šeDì‚1þÁZý &=±Á~j‡êø@ÉZ½„:„Ã)f~½+©¼< $ô zCkHwúþÿ 7.\|Q×i9@Ûiáš‚FõŽ"9ØÝÎ/Ÿÿrc$¬i0r‡r‚tÕâ¯F'§PÐ&žƒ¨bouncycastle-1.49.orig/test/data/PKITS/certs/InvalidRFC822nameConstraintsTest22EE.crt0000644000175000017500000000130710350736724027541 0ustar ebourgebourg0‚Ã0‚, 0  *†H†÷ 0N1 0 UUS10U Test Certificates1#0!UnameConstraints RFC822 CA10 010419145720Z 110419145720Z0h1 0 UUS10U Test Certificates1=0;U4Invalid RFC822 nameConstraints EE Certificate Test220Ÿ0  *†H†÷ 0‰ÙÝL·?B– »^øNƒƒ€BAM»o[ì^zð†­5]›y†ûRènžø¬„R¥¡D#~–Óg˜C‡<‡‰bå}Ú•÷Á_ٳݘ Î|›ö¥AÃ+"Éõõôð^ ËŸãº)ËåõwÔ»qÝ\Ä(”=N­ÄÍin/D®NHoÓ¤Hù£–0“0U#0€ã…zŽ¢;žî¸yªÄ½.Y­0UøÚsT&8Z0Uÿð0U 00  `†He00  *†H†÷ f<¡»ol²z7Ѝ1šn ú•-í€K*“›1 s¹Æ_ÿø†—ÓËÌ6ãý%þÙ§˜YÀ-…ÜB¹dxÊB3¤–pù›2OàpÄUŽe²óòT¦*’Î%FFÉ8ÅÕÔoŸÚƒWŽq7¥ˆpS®ƒPÀrW4Õp¯bouncycastle-1.49.orig/test/data/PKITS/certs/pathLenConstraint1SelfIssuedCACert.crt0000644000175000017500000000121010350736725027601 0ustar ebourgebourg0‚„0‚í 0  *†H†÷ 0I1 0 UUS10U Test Certificates10UpathLenConstraint1 CA0 010419145720Z 110419145720Z0I1 0 UUS10U Test Certificates10UpathLenConstraint1 CA0Ÿ0  *†H†÷ 0‰IJ )y`¹_yjÀrtö^Ÿv_"Ë+ñ–<²ì¢½¿ÍÑÕ¹m¨6Ì÷ëš®C š°7ÝîÖÑu ªâí ga—G‰:eÛ²æß¥Á)Ø/,›Z¡9Óµ›°B‡¿Ñﮉ6òÛ$*”¸:Ú-èçÊž)AåŸa1ðn0£|0z0U#0€Ús“àðe™}ÿ°&ö-15Y0U ×MÅvzþð5Å5Šf2.Ö7Hj0Uÿ0U 00  `†He00Uÿ0ÿ0  *†H†÷ <ëa²ÿµEÀ7`Š'Z„ä®r”õ¦˜—ùKÜ­™ÎœOzaYXþÃ¥ù)5ð¢^{`ƒ¾Ï§à_aï[‡ÍÉhÇh‚“r_F½ÆéöÌ¡¦Ú=Mq¿ÃÚa= ¦š}'ÔlD’8;¦À”Æ]…ÂäÓ™}R«ŒÆ8<bouncycastle-1.49.orig/test/data/PKITS/certs/AllCertificatesNoPoliciesTest2EE.crt0000644000175000017500000000116310350736724027234 0ustar ebourgebourg0‚o0‚Ø 0  *†H†÷ 0B1 0 UUS10U Test Certificates10UNo Policies CA0 010419145720Z 110419145720Z0e1 0 UUS10U Test Certificates1:08U1All Certificates No Policies EE Certificate Test20Ÿ0  *†H†÷ 0‰›rD^Kñ¼V•q¿û}#{¶.eè!„ybYAõÖJÂr_*2ø¸º'Ç/&‹P)òü·§=ožB›1jÓBjŽƒ[¦I ½†$—Ìc]iëaøºØ¬°;¢6Ë’[O@™ØöÐ;IE]‚i1C+8ö^1¦›å‘D±£R0P0U#0€SÁ%}å[>W‘ø–ž]Æ%¨º0UËägkÚíšø¥í%‘G!ò¢‘0Uÿð0  *†H†÷ i6—M³=çŠåwíL¬œyœ]<Œ ÙÃ¥ª(™Rd¯î¥yÈ»ø¸%xñ„/Ú‘C³Wèño»ÏÀjê› þ«ë/qqÍiæ§Oâ%s·½¿Øh wn)åzHéùVºR=„_r?‹½'äÃÜ@¼Öv_ŽOÎ/d÷ Uòðbouncycastle-1.49.orig/test/data/PKITS/certs/UserNoticeQualifierTest18EE.crt0000644000175000017500000000171110350736724026221 0ustar ebourgebourg0‚Å0‚. 0  *†H†÷ 0C1 0 UUS10U Test Certificates10UPolicies P12 CA0 010419145720Z 110419145720Z0_1 0 UUS10U Test Certificates1402U+User Notice Qualifier EE Certificate Test180Ÿ0  *†H†÷ 0‰ÆCwŠÑ±ÅJŸo¨üWÚ ºêä­©ÆSÑu6WáÏ¿õdQ룂 0‚0U#0€­â ­Rm%¬Í©˜¢ h­r®²0UäÂ˜ÂØÚ~‰ŸñŽ›è4ò¬ºï¯0Uÿð0‚³U ‚ª0‚¦0Ø `†He00É0Æ+0¹¶q7: This is the user notice from qualifier 7 associated with NIST-test-policy-3. This user notice should be displayed when NIST-test-policy-1 is in the user-constrained-policy-set0ÈU 0¿0¼+0¯¬q8: This is the user notice from qualifier 8 associated with anyPolicy. This user notice should be displayed when NIST-test-policy-2 is in the user-constrained-policy-set0  *†H†÷ ,âÓG9#¼óBk’çð¦*€;l[¢aÒ=Í‹fÙmn³™u·”°NnÊ %Rp%Ú†Š¶,åê1–ÿRï¢ÎbAŸªqçÈš—Ĥ1ñLû#Z"4þ¦Ò$Ñ ÍÁ…­4õ¼¨\5ï ¥£¿I?¹>¬*ƒË Þˆ>bouncycastle-1.49.orig/test/data/PKITS/certs/InvalidEEnotBeforeDateTest2EE.crt0000644000175000017500000000120210350736724026445 0ustar ebourgebourg0‚~0‚ç 0  *†H†÷ 0;1 0 UUS10U Test Certificates10UGood CA0 470101120100Z 490101120100Z0b1 0 UUS10U Test Certificates1705U.Invalid EE notBefore Date EE Certificate Test20Ÿ0  *†H†÷ 0‰ί»Ýúi½MÝîvó2v¯$Öö«‰‡Ž`MâÀ~ÝXF,f“¹·Õ"eé£ï†PzxG™È@ܹñ—8+óÆsLžõ» Ós~“g7o«˜_\+I~`Ëd= a‚‹drСIñ&";Š(ÔPNÚž}ªŸHuµãŠü…Û*5£k0i0U#0€·.¦‚ËÂȼ¨{'D×53ßš”Ç0U¡O÷u>q'Úøx›An+ÃÇvv0Uÿð0U 00  `†He00  *†H†÷ f2&r.Åö‡ÀŒ¢:rÜOr·Œ¬ŒŠjåˆ`õts¨Ì0Uÿ0%U 00  `†He00  `†He00Uÿ0ÿ0U$ÿ00  *†H†÷ H ™ ë‡,º¬q9³àÖÑÁ{ÖZ׬3ÉU-J¥iÆnœîGx{RÌxÍï#ÃëpËÞ`Ùœ¯ª·+ê]¢·¹TŒƒÐŒÁ‚©qƒE¹¦—IÛŹ 4b˜Ù W9ˆGÙÙ½ýp* 4è,ÖáO4‚p¾¡|®¨yÆ5ž©¬bouncycastle-1.49.orig/test/data/PKITS/certs/ValidSelfIssuedrequireExplicitPolicyTest6EE.crt0000644000175000017500000000121110350736724031514 0ustar ebourgebourg0‚…0‚î 0  *†H†÷ 0M1 0 UUS10U Test Certificates1"0 UrequireExplicitPolicy2 CA0 010419145720Z 110419145720Z0p1 0 UUS10U Test Certificates1E0CU‚ÈU¤²«Ÿÿˆœoð/Šñ„,MÖóNJ!þ"³ Y„é’‘ˆËÛ¾~!ô˜·8¦ÃS´ô×: ÒZƒ\°QÀÕBLGÿºë£DÊ—˜›&…0÷nªgî±í6Y¡–Ö6ûN¬Ñ(!Xí_£k0i0U#0€ÔmãŸÖ}÷šÝ\ Ñ'ðKTiw¨0UÈOb6žD¾’½Ð=s¥o}™0Uÿð0U 00  `†He00  *†H†÷ £=^ÆzH4V\y5Ÿ lko"Û1´íAÑ™ÊàèŠ_8ø5âçfD%cÎÙÝ@¥ø_\UŠ’+"¶Þy£¾ þ´ÚùDhÑó/N‘ð«#HX'. €Sàšß è…ñ¶Û=sB”RÛÁp.¼7%ý]E“μl¨UNœÁ$µ•&bouncycastle-1.49.orig/test/data/PKITS/certs/AllCertificatesSamePoliciesTest10EE.crt0000644000175000017500000000123610350736724027625 0ustar ebourgebourg0‚š0‚ 0  *†H†÷ 0C1 0 UUS10U Test Certificates10UPolicies P12 CA0 010419145720Z 110419145720Z0h1 0 UUS10U Test Certificates1=0;U4All Certificates Same Policies EE Certificate Test100Ÿ0  *†H†÷ 0‰š·LÐ4Ýup¡k¯T­ô ›+zc¹ë>Å­žû«)Ñïï7¹4H€iµ5(ž°r(/¸+zƆCZfNÓ…BÕc´|Iƒ²øÖ¥ñ³`Oz(5]}õ£ˆ¤Þ4ùµOöΙ†D•ä <_Ç‚5ˆâɯ\ê3£y0w0U#0€ãeéÔ†¹Ççó39^L¥ù0UÆö7nSÑFŸ˜ÿ?\µïôpÚ0Uÿð0%U 00  `†He00  `†He00  *†H†÷ Lûsr0r R–oÓ Ì ÑTæ‚hN…)­Ýú¡¨ö­Æe޾9i ê› I¿IE1Ï—[¨ýn]#ƒ•"êc±Ëx9³ÖÇ\§ÛÕLßIri€Ñˆ`Œêy¶‰Â‹EnÞé2{â?  §P- ô“É»wö®ôGU)rЦÐ.Jbouncycastle-1.49.orig/test/data/PKITS/certs/InvalidUnknownCriticalCertificateExtensionTest2EE.crt0000644000175000017500000000125310350736724032672 0ustar ebourgebourg0‚§0‚ _0  *†H†÷ 0@1 0 UUS10U Test Certificates10U Trust Anchor0 010419145720Z 110419145720Z0p1 0 UUS10U Test Certificates1E0CUeû„r“ž©;_$­yê^%WGhÉm¿çÿs—Ibouncycastle-1.49.orig/test/data/PKITS/certs/ValiddistributionPointTest4EE.crt0000644000175000017500000000130710350736724026724 0ustar ebourgebourg0‚Ã0‚, 0  *†H†÷ 0I1 0 UUS10U Test Certificates10U distributionPoint1 CA0 010419145720Z 110419145720Z0`1 0 UUS10U Test Certificates1503U,Valid distributionPoint EE Certificate Test40Ÿ0  *†H†÷ 0‰ÒHçYG|Q9yæ#<ÈsççGPмü®Œ :&þ‰÷ÜNÔÑÐÇqü´¥¬©§Õ{}#Nj”Ué«,ÞÁ6o't6µ<éÛ©Ü]í½UÍ;c׋íé \]ÓA<Üq³š›öm¸ a 5 îÜ-2#ÀsЏ–ߣ£0 0U#0€žPWj…oøæA^ëzº0~ºô0UÖêº8ßúæ,ÇßF¿)ùvY$Ó0Uÿð0U 00  `†He005U.0,0* (¡&0$UCRL1 of distributionPoint1 CA0  *†H†÷ ¬Ö ±JèXj–³R˾ê‘}Ýx :pQoÐü#y îîXj˜Þ̆K=xÈem÷Í"#D˜Ã¾}ëAÚåÁÓWFʼn¯I’{aß]|@>°0—€¹0E¦SBöa½ªmOz³Ø þ¯ŒuçFEkRûíôbouncycastle-1.49.orig/test/data/PKITS/certs/inhibitPolicyMapping5subsubsubCACert.crt0000644000175000017500000000130710350736724030244 0ustar ebourgebourg0‚Ã0‚, 0  *†H†÷ 0R1 0 UUS10U Test Certificates1'0%UinhibitPolicyMapping5 subsubCA0 010419145720Z 110419145720Z0U1 0 UUS10U Test Certificates1*0(U!inhibitPolicyMapping5 subsubsubCA0Ÿ0  *†H†÷ 0‰Óö;©‚º4vìB8¯:1èöG=«\£k½dùNCU-¸&™“¤tKHÇ8W­ŒµYzšïÙ£÷‡¬¯–QÙ ‡ëwÄTRÜY`Ñ7£…Ã1ã zDÕª‡Á.Ö!9åëa|ef¤SÀÏW›Û|¸ÿ;©KzÖÕϾͮÁ£¥0¢0U#0€ßjkGÚKwºöT´R”&Ê0U$¶q­WÀ÷„š¯V·âHlóý®10Uÿ0U 00  `†He00&U!ÿ00 `†He0 `†He00Uÿ0ÿ0  *†H†÷ |'Ü=tH9ÞÓw¶×õÌtÑ>cDú0’Ý-v‚ÐmáÚܬj²i®Á/j >| Ð>"Ô+ƒ=¬ åWônÀevã§«Ò”*ŸN@£¡m7È ´–DbNÔ÷‰Uœài;ê— _…©¿yA²®¿+[:¿m7¶¹=X<§¿bouncycastle-1.49.orig/test/data/PKITS/certs/ValidDSASignaturesTest4EE.crt0000644000175000017500000000147210350736724025652 0ustar ebourgebourg0‚60‚õ 0 *†HÎ80:1 0 UUS10U Test Certificates10 UDSA CA0 010419145720Z 110419145720Z0]1 0 UUS10U Test Certificates1200U)Valid DSA Signatures EE Certificate Test40‚¶0‚+*†HÎ80‚䋯@Œ×=|î–hÁ èÊžteKšT—*x3Ú¥Årê4³”hBÕýwð¨Bžd“¶Â1Fzi̘-V^#_(¿­Ði•b\*^ŒsI~ý"ŽUåVé®r)–‡'×wCð†¸ ¥ææEyMéúS_Á ½~ÅÀ?äüóLå>Ë *TlÐgl ;€fÔŠ ­þÑ2Ÿ¥§³Ðêw?ël¢ä)ØØ¼!Ýš÷Ìå´wMßìÚ¢ŒœuZþfÓÂï„C쩈nLºL?5–Çgü™½™)‘NØ®þk¯PVª/µ*Èî"G%xk!Ý?Îð÷–œA»^D’].ƸÍiÈ?;>ÐO¢ÎÙ„€S(¬8/=óaAÃ=§Öz÷ö2Ó!qÕÃ>M뢌¯ž=A ÿÌ¢G‚zV¡£ý첋·9µÊ …‚›–h¨»kº¤á­e¶D1Ò"/SAOúœø/è,C$~+Ød÷dúðyH¹m6Ìë6ò9«}'ì÷GoÝ3Ä~Mî$W£k0i0U³3×Q¢ Dû@ñbq°Söi 0U#0€tÕ$½^eˆá‹ ~êHNa0U 00  `†He00UÿÀ0 *†HÎ800-Œ§ÈÒ™Ô@›ù!’hó'& s¢YLþ€»0€×ØpÆNv Ù´ö@êbouncycastle-1.49.orig/test/data/PKITS/certs/BasicSelfIssuedOldKeyNewWithOldCACert.crt0000644000175000017500000000142510350736725030166 0ustar ebourgebourg0‚0‚z 0  *†H†÷ 0P1 0 UUS10U Test Certificates1%0#UBasic Self-Issued Old Key CA0 010419145720Z 110419145720Z0P1 0 UUS10U Test Certificates1%0#UBasic Self-Issued Old Key CA0Ÿ0  *†H†÷ 0‰´8k­B÷ nåm'8Ù¾@³DJfÇ´¼2ãß%:‡•'K­Qü» ²/Þ± uÛ#9Å?BäÛA#\æb "Drüß  ….°ZMÅ ›_‘á.rJú¥Â`øe«Kî€êW’!”„´JŽàù N e§sl}åè>çAtƒ£ú0÷0U#0€ú¢j¹îúOÅruÓKzmŒä\9$0UºŒ!‡s˜úë¹ÙoA¤EÕ†ê0Uÿ0U 00  `†He00Uÿ0ÿ0{Ut0r0p n l¤j0h1 0 UUS10U Test Certificates1=0;U4Self-Issued Cert DP for Basic Self-Issued Old Key CA0  *†H†÷ pÕ‚×(ßÿ2íp”¼ ·ÐòŸÃ•vtŸÑ&uts uÑx5ž9ª"MGÔsIp³áˆŽËmL@F~Æh:ü5F{ úÊfƒÊCý[ùµM}ÙT¹±÷¬ãߨ‘SÜλòD9ÍXè.^FäPá…÷6é¬5Ý–¤v7à­µ ßÊ'’‰bouncycastle-1.49.orig/test/data/PKITS/certs/indirectCRLCA1Cert.crt0000644000175000017500000000117110350736724024321 0ustar ebourgebourg0‚u0‚Þ T0  *†H†÷ 0@1 0 UUS10U Test Certificates10U Trust Anchor0 010419145720Z 110419145720Z0C1 0 UUS10U Test Certificates10UindirectCRL CA10Ÿ0  *†H†÷ 0‰ÊœÛÊ FÎ’¾&4úÕ¡ÒõšJ>Ã13. àÞsO¥äØ!hŠÍútÅv-(€cE¯Þˆœs®­½¨;ÈÊ{#.õ |ÂJ¼>`^¨å~’¸ÞhÒ ÿŸÂ¹ ¯’— w =ªx~ÿÄA°e³0ù Ýsé§°öü‹` =£|0z0U#0€ûlÔ-žÊ'zž °<êš¼‡ÿIê0UlÁ_ا-à†“\ ðI¹%[è0Uÿ0U 00  `†He00Uÿ0ÿ0  *†H†÷ 6£M¹®fÉV,ÝÉÊþ­³j³3ó²¢@˜¦pèÊq”Ò˜8€Ä “c0EYåYš•mn“†eùžF˜Ž,÷¼° t0Ô¯¬Àµ‰°ý¨¶£¥)œÍîW €Â­ì yìS÷Tt´)m-Êi8òaÎc1Þöâ4Ü\rñL¨Çô‹bouncycastle-1.49.orig/test/data/PKITS/certs/NameOrderingCACert.crt0000644000175000017500000000130510350736724024447 0ustar ebourgebourg0‚Á0‚* 0  *†H†÷ 0@1 0 UUS10U Test Certificates10U Trust Anchor0 010419145720Z 110419145720Z0Ž1 0 UUS10U Test Certificates1#0!U Organizational Unit Name 11#0!U Organizational Unit Name 210UName Ordering CA0Ÿ0  *†H†÷ 0‰Ï$éìv_â÷ü|®§ã3yy ´ÚWÓ lù…ëbc‹|ÐÛÊs|Z³rÆ^cÕ«îŽÍÞˆÐЩ"A:™‘bouncycastle-1.49.orig/test/data/PKITS/certs/InvalidDNSnameConstraintsTest33EE.crt0000644000175000017500000000127310350736724027323 0ustar ebourgebourg0‚·0‚  0  *†H†÷ 0K1 0 UUS10U Test Certificates1 0UnameConstraints DNS2 CA0 010419145720Z 110419145720Z0e1 0 UUS10U Test Certificates1:08U1Invalid DNS nameConstraints EE Certificate Test330Ÿ0  *†H†÷ 0‰±/ó[|¦-·åb Ó Fü=ÿ¼ƒÞÂ^I¸*ÿ½øJNXxp’ð T˜¬(eNàÚÔnìF†† €ÿ¢ƒ˜,¸p s-üÐo•×£?Õk‘„ÆÄ©èöèˆwÎýT=ÃÊAÔ§"bouncycastle-1.49.orig/test/data/PKITS/certs/InvalidCASignatureTest2EE.crt0000644000175000017500000000116410350736724025666 0ustar ebourgebourg0‚p0‚Ù 0  *†H†÷ 0A1 0 UUS10U Test Certificates10U Bad Signed CA0 010419145720Z 110419145720Z0N1 0 UUS10U Test Certificates1#0!UInvalid CA Signature Test20Ÿ0  *†H†÷ 0‰°@u´èP Ï\aÍÈ€?Ã%Öá€Ç]$Èo¾ÖôàóRÞÙW&8™©QK˜·ÁÙõp>÷4¬ØÊÝR™ðU›g•`µ¹çÃä´TÀ = •ïsîF#w,h!Ø E“ÃÜŠçïi&`G(åßÏF¿t€â„­¤ B?5£k0i0U#0€Bo— #yÁWž:¦ œˆØ0U|‡\Á¿â0+ä}ë¤3¹^0Uÿð0U 00  `†He00  *†H†÷ `’>ˆö·aB¦kóÂN%>´Ã¹âú‹gž‰¾+;-f㇠)+¨{ÁÎÆ›‰;‡Œ;ÜدjûUãr2 ò­¨ç´ÚìâSÁ&Z÷^ôçæ¥e²kš”­¼bÉãGÿ-NQ&oÑj„ŽËGß®äi/“×È[áŸÜ÷ÐÛ98bouncycastle-1.49.orig/test/data/PKITS/certs/InvaliddeltaCRLTest9EE.crt0000644000175000017500000000145410350736724025164 0ustar ebourgebourg0‚(0‚‘ 0  *†H†÷ 0@1 0 UUS10U Test Certificates10U deltaCRL CA20 010419145720Z 110419145720Z0Y1 0 UUS10U Test Certificates1.0,U%Invalid deltaCRL EE Certificate Test90Ÿ0  *†H†÷ 0‰¸˜‡o1ûå Ô¾¼YãŠ@ßu]j†¶f¸t ÀE‹ðp8ÚS_/•¥â=€¨ƒ#4›4%®5Q›y¨•HÚÕîs,¹"]8¢K¤|Ê´RpGumª’¿4S<ø ÝjI6 ]w„aÝ*ÁÙØ5@Ùo›öð"n¥¡œ†îÇ  磂0‚0U#0€£“«Wf&mr:l¼ƒe£šüŽ C 0UI)¦ß³-Ábûœ±3CÊÇk0Uÿð0U 00  `†He00SUL0J0H F D¤B0@1 0 UUS10U Test Certificates10U deltaCRL CA20SU.L0J0H F D¤B0@1 0 UUS10U Test Certificates10U deltaCRL CA20  *†H†÷ cI-”,.ö=XFô ýç@DÎó51*hÇô-x͹ xw‹ÉÎèz T16OucÒ½mê ùl+}MjjâVÜ·…àl‰LÓî)†­ì9 MÜ~Ã/'M™òz[m§}t$Ú>öE@iR¬ö;~/ã>Ù$Ebouncycastle-1.49.orig/test/data/PKITS/certs/Invalidpre2000CRLnextUpdateTest12EE.crt0000644000175000017500000000123210350736724027271 0ustar ebourgebourg0‚–0‚ÿ 0  *†H†÷ 0M1 0 UUS10U Test Certificates1"0 Upre2000 CRL nextUpdate CA0 010419145720Z 110419145720Z0h1 0 UUS10U Test Certificates1=0;U4Invalid pre2000 CRL nextUpdate EE Certificate Test120Ÿ0  *†H†÷ 0‰Ðhq„×#Rm˜”­ÁýGÆÁÑÆDGÌ:èrñ¿û ’&n¯¹Í»ƇÈo¼þ»7µõÃ4D @y¨#íþ£×*:tÈ%e×?*¹«O2Nµ-Ö\ÅÊ· À`{?$EÖŒbouncycastle-1.49.orig/test/data/PKITS/certs/ValidPolicyMappingTest13EE.crt0000644000175000017500000000122210350736725026023 0ustar ebourgebourg0‚Ž0‚÷ 0  *†H†÷ 0O1 0 UUS10U Test Certificates1$0"UP1anyPolicy Mapping 1to2 CA0 010419145720Z 110419145720Z0^1 0 UUS10U Test Certificates1301U*Valid Policy Mapping EE Certificate Test130Ÿ0  *†H†÷ 0‰«åÁ¸Ê `^2’ÞÝÿÌ×"¥Aæm7Ö£Ÿh/cþïYšêÇ3_ ß%&»ˆ]/Á-9q-^¸y6=òÅœ’Zš„éhŠÆ:²ë¦dÇÕÉÄÛ¡È ÍiÒWŽñfÁ_Ç,šns#û!^ š®H¹,¸>Ç£k0i0U#0€-7Ò?žYÙæ¾W¢÷k‚¦­î0UÝšê¢Qbk4kº”Q®•â™0Uÿð0U 00  `†He00  *†H†÷ à7¦aººƒ—+tÄG{ĺôó—R8B™u¶9E?®b¾¥¹}¡Šó*Q»§è:ójf ¯ïŸŽ£iBÚÔê^²é¥†0{ø0™uo¿É!©ÔÄZ1¹YíE SÀ72iˆQ B³d åš“šÆ.©}¢žQ­ËÓ­bouncycastle-1.49.orig/test/data/PKITS/certs/ValidPolicyMappingTest6EE.crt0000644000175000017500000000121510350736724025746 0ustar ebourgebourg0‚‰0‚ò 0  *†H†÷ 0K1 0 UUS10U Test Certificates1 0UP1 Mapping 1to234 subCA0 010419145720Z 110419145720Z0]1 0 UUS10U Test Certificates1200U)Valid Policy Mapping EE Certificate Test60Ÿ0  *†H†÷ 0‰ƒøã±ÕFÞ«àˆ­€dWz­T2ÔâÐ)ékÞR× –׳µØ¡LyÜùsTƒu&šEûá+#%înwm£·Ý¿Œà|Uõ‡·ú'ߊ´kr ¯Èmüë¯ ªÍ+ÿ·³`ÏVù®²š<¸ŠØÍÊW22B՘ޯƉ‰|¬Ì¿nÏ£k0i0U#0€­ïW}ºƒïÿ‡hsÒ¦—0Uáþ-¢ò‰–Ó“ž” ˜ÿÞÍbí`0Uÿð0U 00  `†He00  *†H†÷ e+EËôMTOD•ð(º|¥Ñ?s‚ý®ç28ô¯ÿœáî>(ßÛp¼hã0}󈆮&›Œ¬&ü«íìÛis>¿"òDЗ3³1ä!– 'GªyýB“×]máÁdx¨ågcX6–^Ì!8²¼9¯îf_y¦%Æðq!yÁPbouncycastle-1.49.orig/test/data/PKITS/certs/inhibitAnyPolicy1SelfIssuedCACert.crt0000644000175000017500000000120610350736724027423 0ustar ebourgebourg0‚‚0‚ë 0  *†H†÷ 0H1 0 UUS10U Test Certificates10UinhibitAnyPolicy1 CA0 010419145720Z 110419145720Z0H1 0 UUS10U Test Certificates10UinhibitAnyPolicy1 CA0Ÿ0  *†H†÷ 0‰½ÌsÑÑë”âø6’ïÌöcC½óGÓ*:â@¯[¨ÿýÙ¼Æeû ÁÀ¨9Èm/†ôp»,åj£žñ‰­¾ðì§-«üj™1ÄO_½®AtÁ1òå}V†0‘A*6±Ù/£{6º8âè¦.œ9p`z¬$ÍÊ]‹@·º£|0z0U#0€fÛµ”Çij>+‘¹ßȨÐM+4D0U§…,ànçT#jw¢¯ûã0Uÿ0U 00  `†He00Uÿ0ÿ0  *†H†÷ ƹi.°_;.ŠcŽ…i3'Y‰#l£ Ù >º½îtµèÜñŸ¹C»¾X?Ÿÿø’ -}S.¹–y5ÒzR¦ª¼ÙCnMÛ˧݊§+µ¥jíPcb-ï`õ$› ¾èòoX—ž­w£¦@â„<0 F P EŽ_ˆÌ{fybouncycastle-1.49.orig/test/data/PKITS/certs/InvalidMissingbasicConstraintsTest1EE.crt0000644000175000017500000000123510350736724030362 0ustar ebourgebourg0‚™0‚ 0  *†H†÷ 0O1 0 UUS10U Test Certificates1$0"UMissing basicConstraints CA0 010419145720Z 110419145720Z0i1 0 UUS10U Test Certificates1>0<U5Invalid Missing basicConstraints EE Certificate Test10Ÿ0  *†H†÷ 0‰‹¿slL¡]ÜÜ.Ž ç½Ç1¾`…]uåÉý²b¨ô€ˆz×›Zyp¸¶XÁ¾ë±åC+˜c¢ëó(h•/ÅrV¿;ϯGÇ€ÊR<&¯ 9 ä§$—#BŠª//â¾_â}ËÔÞÔ6¢SªâøØFênð×f¥Žf^”A'äþ¥£k0i0U#0€F ]7Ò©“E¬í\1çÍö0Uû–ðÄ7Uðε¦âñÿ™®nX0Uÿð0U 00  `†He00  *†H†÷ º¡Wzbƒ²âÖÃ1~«,¶ãc±±bŸÄ´@åŽí,Míã·½®¶Ÿ·çf¦|),‘ )»z÷¨‹ÇdÕú-õŠs?«ÔÛ*ÁÕfôu"Ø$©aG.3²¢5„ O«`Ú·½VT¢d¢|ßG~wÞj¨2t=Ó8º ýbouncycastle-1.49.orig/test/data/PKITS/certs/requireExplicitPolicy0subCACert.crt0000644000175000017500000000122310350736724027224 0ustar ebourgebourg0‚0‚ø 0  *†H†÷ 0M1 0 UUS10U Test Certificates1"0 UrequireExplicitPolicy0 CA0 010419145720Z 110419145720Z0P1 0 UUS10U Test Certificates1%0#UrequireExplicitPolicy0 subCA0Ÿ0  *†H†÷ 0‰º·ªUà„PTžSWßF8h·ÊmÓ ò”K:U†KÐ>»ï*†7 —nÒ)Fñ$5\/šÖø3”6ægV-r ù5&”ÒVàËëvÆ )ÊošVø|fñå ‹ºÕÞ`Ãqhùy- ¥ÕÆÉ2"çí7Vy!ja„ðù¬!£|0z0U#0€wj³dõ±ìQz-e†ÿ~ JŽ'0UðpGbŠ–Ñ‰ªT‰øœm)0Uÿ0U 00  `†He00Uÿ0ÿ0  *†H†÷ ÷ýÔ •ià»Ø”l‹½l)g÷½M„Rg*Kñ´|„”9‡í5MÖ·lÑ”N¨º×FÅ(^A×t€M2¢¤ÝqÏeÞJôdÈ`|Î&Dö /©&kv³O¿:£ JçŽ3®áœ.nÌ.Ë«oû60 æ­ß~ä«·0,vbouncycastle-1.49.orig/test/data/PKITS/certs/nameConstraintsDN3subCA1Cert.crt0000644000175000017500000000135210350736724026347 0ustar ebourgebourg0‚æ0‚O 0  *†H†÷ 0J1 0 UUS10U Test Certificates10UnameConstraints DN3 CA0 010419145720Z 110419145720Z0N1 0 UUS10U Test Certificates1#0!UnameConstraints DN3 subCA10Ÿ0  *†H†÷ 0‰¦‡ÜÞ3Ð^ȩ݂´E`Ügïêƒ € UÑf¦ý\Š©dÝÓB½Ýa†©à…h¶_1Ùë¹ö³ÂÐeM[ДàÓ­©2Œu{<•±žŽµÔ+É IÖHÔ‡‘NŠž´‚á¡Ôæ4•ñ=®ÔlGLóH~ê¾]Ì…Þ¿#VÆé©£×0Ô0U#0€‹ã¸XVŸjß=Ø;³6á˶Ê0U­’.+ÑøŠ±·!.~Ži<4u0Uÿ0U 00  `†He00Uÿ0ÿ0XUÿN0L¡J0H¤F0D1 0 UUS10U Test Certificates10U excludedSubtree20  *†H†÷ Míi0Ù´íí¸2Ï¥zÁi* ãµ…€¹%¨iÁïýûŒxHg¡F*ÖKýÍýE¶ÿ®jt^›F+ŽQ/­ª¸b0ö&[úås)=ü Invalid Basic Self-Issued CRL Signing Key EE Certificate Test80Ÿ0  *†H†÷ 0‰«á"Â{º,j-ÊéJjH¬Ðý‚{"c«9˜¡ÅéѸG3¡¡§Ñзj4ž_{ Ù(™þ L:sp6³ ü$ç…L'3™ü\úC£‘$úæq\@¤¹#Å8/ßû?¿Ò%·ñ›t‡ uïÞůêÎ90•Þ ã¿£k0i0U#0€rÊ3C©ÄQ«cÚD‡a¤ô¾G0UqÒì÷ÿ˜¼ÊF—YûÅë<™-ò›0Uÿð0U 00  `†He00  *†H†÷ åàhW#î£7iêÚA[MõkÒB=zmèºÉP NÀz2 ªXXß¡ BH!trÖ…xyôŸîÔmŽ ÞS2)0¨  ¹åÜ gŠ—»ºøâI|t›ÀŸ=@aÑ!ÉOâ…GÌ-c‡€ƒ%peXE Òź—é8IçMbouncycastle-1.49.orig/test/data/PKITS/certs/NegativeSerialNumberCACert.crt0000644000175000017500000000120310350736724026145 0ustar ebourgebourg0‚0‚è 0  *†H†÷ 0@1 0 UUS10U Test Certificates10U Trust Anchor0 010419145720Z 110419145720Z0M1 0 UUS10U Test Certificates1"0 UNegative Serial Number CA0Ÿ0  *†H†÷ 0‰܃­YÝÕDN¤«(¥W½u€ž—9+•áêhGü¿bšF(ÔÃüþžy˜èéÌ%P!@”Vž&¬€àç4|ïw¹õ;³0Iû7,¼D;Íbý¤âqEÄ­Bž@S tqJòƒ·/À$k5@ó±Ð‚œœC$ª ¹¤”sj’w£|0z0U#0€ûlÔ-žÊ'zž °<êš¼‡ÿIê0UŒ§#MK÷ꡲ‡¹ÀÓ3XË‚0Uÿ0U 00  `†He00Uÿ0ÿ0  *†H†÷ XÏÜW>ž :[DFÐ}%¸I&šrÁºÅffÅb·S59w?Ì1€?ø¤Ý¹^vrþ·ìt—5ªfá¸(]-x–º cÙUœ ©$2¦Eku=XcfÒªÈq–Ò‹•kýi¢ÙÄeÕiݔ˸Žõ¤yy±™übouncycastle-1.49.orig/test/data/PKITS/certs/InvalidIDPwithindirectCRLTest23EE.crt0000644000175000017500000000121610350736724027175 0ustar ebourgebourg0‚Š0‚ó 0  *†H†÷ 0C1 0 UUS10U Test Certificates10UindirectCRL CA10 010419145720Z 110419145720Z0f1 0 UUS10U Test Certificates1;09U2Invalid IDP with indirectCRL EE Certificate Test230Ÿ0  *†H†÷ 0‰”u: ·Ý¹ÖvsOÄû»ŠlH¼+êd ÀÑ5dóÈß ë¯ó$Œ<¯ NÉ…ŸPU¢¯ÝŒœ¼ôÓ†/ú´¶7‘þrôË¡åéÒlˆ0FÈXÐh8°‰÷)"¤~tk’jAƒíÑÆøÐ¥ ¨Õ&Ÿ&Ñ3Åo8n2ov€Ë£k0i0U#0€lÁ_ا-à†“\ ðI¹%[è0UÛFƒíÌ:VHº¹:˜7â#Ç0Uÿð0U 00  `†He00  *†H†÷ lpå!ž’ò¤e@á•q°XSåŽñi£xm`5\rRVA&ç5þÕ_ÄNp"q áêKN»0S³†å8怢œ.rî²'vA™ÿyhÜ2rtÕ‚ÕRÎEX îZ2"‘NL¦`[GÀ˜{‰]&kÉù6«{ÐažÄ.X‡Òí…×bouncycastle-1.49.orig/test/data/PKITS/certs/ValidSelfIssuedinhibitAnyPolicyTest7EE.crt0000644000175000017500000000123410350736724030442 0ustar ebourgebourg0‚˜0‚ 0  *†H†÷ 0L1 0 UUS10U Test Certificates1!0UinhibitAnyPolicy1 subCA20 010419145720Z 110419145720Z0k1 0 UUS10U Test Certificates1@0>U7Valid Self-Issued inhibitAnyPolicy EE Certificate Test70Ÿ0  *†H†÷ 0‰è0C„8|¯eZÓžœ)ËW•Òç`“]£j˯ßűææÒÍ©Ø=¯TÞ;ª§öŒW0Ê!WSü$…FÝ{ÝÆžs VSÙ©;Ú÷*äèÚÖ;¯ôøÿÝI_æ\›&!¼m¯çઠ¬£]òyA|öŒEV(€H…³?"ïxèW£k0i0U#0€«ÈA&ÐÕLæ+Vgìï‚ÄÂÝòU0Uéj[mƒòŸ|j7nÓóHÙŒ.0Uÿð0U 00  `†He00  *†H†÷ i¤¿$`S|1ÌÃqÛθ°wº1x#'}Ã-÷Œæ*(=v#º­ΈúŽyÅ%õplµÆGk- ,ö÷dù Já š òxIû#cÎÈÁÚJoÌšÃÀÁ/æXT+[±SL lï®’I›™UUΔežefµ¬_Ÿþ•ørµbouncycastle-1.49.orig/test/data/PKITS/certs/InvalidcRLIssuerTest27EE.crt0000644000175000017500000000132310350736724025460 0ustar ebourgebourg0‚Ï0‚8 0  *†H†÷ 0C1 0 UUS10U Test Certificates10UindirectCRL CA20 010419145720Z 110419145720Z0[1 0 UUS10U Test Certificates100.U'Invalid cRLIssuer EE Certificate Test270Ÿ0  *†H†÷ 0‰ÁxõëynÓ ýSß.äˆä¡J_ü$D.àÖàE‹K"o¹ ž:yv)DI“_Ùï. "g¿DQ5Ž!+ £Gu~ý¾>ÉîSñ‹ŒÜÉ ZRmŽ©W¤oË—‡ÃN£%¼ FM®Ñw%Nè'QIy³(õ$GÀ€P¾ü',‰ö©£º0·0U#0€Á¯‚ÕÓOð1b¼ÈI€ÁUbƒŸ™@w‡'N̶¾@‹ÛNKÝø–=Ä¿×9üu¿ª0Ÿ •9žK["Ù‰ØN ¼ßmð>7œœOI¦¶¤t–º«ž ±¶QWìbouncycastle-1.49.orig/test/data/PKITS/certs/Validpre2000UTCnotBeforeDateTest3EE.crt0000644000175000017500000000121110350736724027272 0ustar ebourgebourg0‚…0‚î 0  *†H†÷ 0;1 0 UUS10U Test Certificates10UGood CA0 500101120100Z 110419145720Z0i1 0 UUS10U Test Certificates1>0<U5Valid pre2000 UTC notBefore Date EE Certificate Test30Ÿ0  *†H†÷ 0‰µ»; NÈæ]Þ÷@F ÖP „ª:_aAdil (šüB¯4~x˜õ«ÄÞ ÝЦFÍ5`–Dvå«ÒÛªHi£*»;àçAL׫ƒ×câøðWOÐaÖïȵ\(ýˆ±40"^H·±ã¶½‰\æÒ\Äßï€W5“»ˆ÷£k0i0U#0€·.¦‚ËÂȼ¨{'D×53ßš”Ç0UôK2„ §, ú‹ $›è€JŠtÊ0Uÿð0U 00  `†He00  *†H†÷ “->Ñ€SÞû«{Š ñ˜I axëK¶ý[-¯SO‰£_5PÁ3§d»J¨¦ºzÚ1'½+…ó¹Çk‚¼ò"E+¸ò¨Æ ÿIÜ‘ÎLL¬ã›8²XøžþT»ç»ÖÚð5íI¥Ù›*¶‘ú`}òn³LfaØ%jbouncycastle-1.49.orig/test/data/PKITS/certs/InvalidDNandRFC822nameConstraintsTest29EE.crt0000644000175000017500000000141410350736724030454 0ustar ebourgebourg0‚0‚q 0  *†H†÷ 0j1 0 UUS10U Test Certificates10U permittedSubtree11#0!UnameConstraints DN1 subCA30 010419145720Z 110419145720Z0¼1 0 UUS10U Test Certificates10U permittedSubtree11D0BU;Invalid DN and RFC822 nameConstraints EE Certificate Test291/0- *†H†÷   Test29EE@invalidcertificates.gov0Ÿ0  *†H†÷ 0‰Ñi¶Æ¢º¡¹ñ'’nuLLÚû\mäo:ÂÛ :&9pFGþ:½7‘»€† «›»âP~$‚ÈVÍÛ;M¦à~RNœ”±ãoX¨»ÇÑD|\y3'VM˜6Iˆ@ šÚn¢VàNŠ/Ñ'®-‡CE< –Bé)èC"24nÍ.ï¯W£k0i0U#0€W«øœ'ÈÒôæÏoª 5gƒ$k0U&å0ÖÜ4Îäµþ¯ä®öª|270Uÿð0U 00  `†He00  *†H†÷ x"8 ß«”ý®€cquƒA¨½UÇÊ]“8ÍÐUÝ9¤²‹‘”ò†>uEú:'ñ}ÒPÙaÔªDiÆå[§£_à6%u®c{¡gv[HÁÈ´´¥ø5oØ™´Z»üV6>rš ¢`,mÖ3F騲§ÙÜâr¹IòIJ¸YM±bouncycastle-1.49.orig/test/data/PKITS/certs/ValidNegativeSerialNumberTest14EE.crt0000644000175000017500000000123110350736725027324 0ustar ebourgebourg0‚•0‚þ ÿ0  *†H†÷ 0M1 0 UUS10U Test Certificates1"0 UNegative Serial Number CA0 010419145720Z 110419145720Z0f1 0 UUS10U Test Certificates1;09U2Valid Negative Serial Number EE Certificate Test140Ÿ0  *†H†÷ 0‰É««l‘ýeM©uçiaÄ'´æUƅꦀµÔEÌ(<»U}k¨ Uje£˜žLö…}Z¢`>„dúÙC¡P’Ë(í ÀU°»³O˜‰i¶‚®àVÏóêvõ¤IlܬÇîË&ÏÈ¥ò7L¥TÕÙ½LR×ðRwQáImÓæ$õ£k0i0U#0€Œ§#MK÷ꡲ‡¹ÀÓ3XË‚0U¼aê™ ûlÛµbÏ’ÜžÛ%€80Uÿð0U 00  `†He00  *†H†÷ %䡯­·´¸m=¾v”½ZDÅõùì‘OkvA\úÎÑ2ß G’yM7wj-ùü1ÆúæQÁ½¡ù þ½µ5 9´‘·õHÊ2‡n¯¯6*±É|w—ÈÚÿÇ+ÿŽ @˜xŠã mhPŸ¶B#J‰Oûxxp#BXyý"bouncycastle-1.49.orig/test/data/PKITS/certs/ValidBasicSelfIssuedCRLSigningKeyTest6EE.crt0000644000175000017500000000125510350736724030540 0ustar ebourgebourg0‚©0‚ 0  *†H†÷ 0X1 0 UUS10U Test Certificates1-0+U$Basic Self-Issued CRL Signing Key CA0 010419145720Z 110419145720Z0p1 0 UUS10U Test Certificates1E0CUÙù5?Á¹};¡ CmeúxÐþuÅ\£Ú-m˜‘«Ãó‡Q”èÂåþÉæ&IJÓ5úX†'LæG|æåSÅ0Kìd’÷€R}qg4ã’Y´SʈeRp(ÄEùÒ|_24HlQŽ™®ª=àbouncycastle-1.49.orig/test/data/PKITS/certs/InvalidDNnameConstraintsTest12EE.crt0000644000175000017500000000132010350736724027166 0ustar ebourgebourg0‚Ì0‚5 0  *†H†÷ 0j1 0 UUS10U Test Certificates10U permittedSubtree11#0!UnameConstraints DN1 subCA10 010419145720Z 110419145720Z0€1 0 UUS10U Test Certificates10U permittedSubtree11907U0Invalid DN nameConstraints EE Certificate Test120Ÿ0  *†H†÷ 0‰­Ä$ò¦D;õDK’L×Fb/Æk/DJ™Ï`AÃiôZ¨…õ"Å4K‘}6{M *†ƒøWlZaGšJ °d×u˜5çÜ_ò=‘Íî(0i‘§‹Ûr=D¿œ…^Õ,ùá§—„ó±»Þ™0çËðÏìÅ$k#LÔ(E1¼ÊØM ¯ôA£k0i0U#0€î¹ÏÖ/ŽÈ…“þî£PXþB00UeYF%ïE‹ãá…¾z ÅÃù(ê›0Uÿð0U 00  `†He00  *†H†÷ ©Æ¯â*ª°7k{iïPDyíG§è póÌcº€Fp _ TÌùfJ¯€( Þ”ë1ËŽOŠo´m•-Ϋ_…b®–Gà¥.\töf6=«RBÞ^xãN0ææÏ± /‡-´(÷8V‡˜DÈd•¢‘­¼™uv—HÅLmUÅÀÙØUbouncycastle-1.49.orig/test/data/PKITS/certs/GoodCACert.crt0000644000175000017500000000116110350736725022766 0ustar ebourgebourg0‚m0‚Ö 0  *†H†÷ 0@1 0 UUS10U Test Certificates10U Trust Anchor0 010419145720Z 110419145720Z0;1 0 UUS10U Test Certificates10UGood CA0Ÿ0  *†H†÷ 0‰®Â5• —+±JC•E£ð–¶ t§±Óⲋª#}-ÂósŠÂöèýï a÷É$­£1Þ½0–YXI‚§Ù‚Û¿ ö6!¶BÈo¢£€7Rmêý¯ly\–jÉoHô1·£Ï„Oé\ºHl\jJ “)-!i?ü–Ìèžz£|0z0U#0€ûlÔ-žÊ'zž °<êš¼‡ÿIê0U·.¦‚ËÂȼ¨{'D×53ßš”Ç0Uÿ0U 00  `†He00Uÿ0ÿ0  *†H†÷ Ž–Ï~ÒAK½pøª…ù-Ð ÕÔ˜`•drõÎÌšpóÿCÂ,ÛðçÙ¦4rèmœ{v¸7tÿ6 Fh¼œÇ›ð9ùƒ7]æ0kç ÞÆ4 © *ô·}j—h®…&‚‹ÏÒ%žÖÅáÎ~¬ñ@¯:Œè;× ‘j¬bouncycastle-1.49.orig/test/data/PKITS/certs/ValidDNnameConstraintsTest4EE.crt0000644000175000017500000000135010350736724026563 0ustar ebourgebourg0‚ä0‚M 0  *†H†÷ 0J1 0 UUS10U Test Certificates10UnameConstraints DN1 CA0 010419145720Z 110419145720Z0}1 0 UUS10U Test Certificates10U permittedSubtree11604U-Valid DN nameConstraints EE Certificate Test40Ÿ0  *†H†÷ 0‰¸Yw6Qý,¹Ë+lC½–"Ôp¿bfÅN:\Ûƒ'Êì\jâd:,ƒjyqƒëà8óÞT9Ø&ŽŒïþRt(sñpœgÞÖ ¤"`úpüi2½A:,NGá>˜¨OÀèëš—“­v§*Üz/g*®CD>¯›£¦0£0U#0€N.£çÙÝ‹§‚;AJÞ|Y#WNS0Uñ¸×ÝB4 ÀÛ +!ÊÐ> Ô0Uÿð0U 00  `†He008U10/-DNnameConstraintsTest4EE@testcertificates.gov0  *†H†÷ ]×ÌýźG’¹`L½æ^:àÍÂ=q81ÈCBj)Æk¤¥ûyΑ²ƒ^N¬´®Š5FjýßÑð—ßæh‹[xsçKÓÏ5¶Ç Ûêf…þQýí¬¼†7uªª]øDr?þ°m"kœ¤‚%sE /?­ìEìÕ’ú‰ðbouncycastle-1.49.orig/test/data/PKITS/certs/ValidDNnameConstraintsTest11EE.crt0000644000175000017500000000131210350736724026637 0ustar ebourgebourg0‚Æ0‚/ 0  *†H†÷ 0J1 0 UUS10U Test Certificates10UnameConstraints DN5 CA0 010419145720Z 110419145720Z0š1 0 UUS10U Test Certificates10U permittedSubtree110U permittedSubtree21705U.Valid DN nameConstraints EE Certificate Test110Ÿ0  *†H†÷ 0‰™_Çxlj Á ^ã” ªûcÛ <ò›óâ®n´]ž5̵rɉV‹˜àëzǵ gð‹þ`Ó¸Ä÷5ÕN“Å~o¶nïþ{Ä&¹MªEâ@8z2cÏÉΑ-2òÖÖíÆPµá^ØnyZ eœÉð+|¶˜E£k0i0U#0€5Ÿ¬Á¹¡ã:þñ/ºw²NMYí0Ub,2Û×¥‘zç&Sâ¶<ÿ‚>0Uÿð0U 00  `†He00  *†H†÷ ?8¸£ñ¦ÿ&÷ô–‹µ¼“)TMˆPšR”âù¥»C£/Ýôáª` îÌ9'š[gs? N]HTEŒ r#©Å Ë…Î/ iÕ–rõsËPáÒ9íRŒ^T`•I7y }CZ¬ßAïýäˆñ¡¡ÙB­ntÁd,+¥xÁbouncycastle-1.49.orig/test/data/PKITS/certs/requireExplicitPolicy2SelfIssuedCACert.crt0000644000175000017500000000122010350736724030500 0ustar ebourgebourg0‚Œ0‚õ 0  *†H†÷ 0M1 0 UUS10U Test Certificates1"0 UrequireExplicitPolicy2 CA0 010419145720Z 110419145720Z0M1 0 UUS10U Test Certificates1"0 UrequireExplicitPolicy2 CA0Ÿ0  *†H†÷ 0‰¹ñ¯ÖÀÒ¥j(aˆôtwÁËÖ¢÷ÑzÃσ´Æ”[Iáe7ø¡~ÕF¦^•˾»¨Yé ÁXcP|¨êÁmå'Û 2Dš5±#V§N±€Áú¤nóft‰§¼‘Q; ÁŽƒ ¾V5Dy0ñlÿQ¶x@b!̾(ðâÙ۸б€Y£|0z0U#0€qÂÑÚäóÆJ’@bG.)UËÕš™‡À>Uéïk3`Ñz%wYjTÍÐ ÜZk,½Ü]‚0»ÁEDiò_ÒbóóÑ” û>íÅ;ò‚Ö+L3ˆIs£|0z0U#0€ûlÔ-žÊ'zž °<êš¼‡ÿIê0Uû ýº{æ8H™Z`UP—ª6lC0Uÿ0U 00  `†He00Uÿ0ÿ0  *†H†÷ ™Ÿ>ìyözPg¼ÔD‹h!­Ï<á\ñÄ«¦£ H`xšG(×ÞžÊ×ïzß÷¨AeÄTžór‹ Mý’•HQ 5Óƒßg$›d’ á‰ùæåÅ÷ bÅ·ÐÈïöÿœå5 üzœ‰öãýl ‰V™U˜0¹Æ ˜/bouncycastle-1.49.orig/test/data/PKITS/certs/BadCRLIssuerNameCACert.crt0000644000175000017500000000120010350736724025112 0ustar ebourgebourg0‚|0‚å  0  *†H†÷ 0@1 0 UUS10U Test Certificates10U Trust Anchor0 010419145720Z 110419145720Z0J1 0 UUS10U Test Certificates10UBad CRL Issuer Name CA0Ÿ0  *†H†÷ 0‰ñTÙÆq ¥^´üMÅÙQôÝ€ðñ—UÙÑ¢§)™»è­ÑF‘3Þj6ŠââïúE¾‘#¢r¾]=¢nKˆhV˜g¨¸Ì0_¡¸1zÖ‹øö÷´Ê=CÍ%ˆ ƒB৯çäí÷";ò¼i n¼ÜÎÉY‡Rº®ZT½ ïÞ1£|0z0U#0€ûlÔ-žÊ'zž °<êš¼‡ÿIê0UÈ4ÛàµcQÑP¤2ÒÅYøCŒàg0Uÿ0U 00  `†He00Uÿ0ÿ0  *†H†÷ ˜ƒé~!}úö9–Hãa°¶æ§rlÄÊV/ËX8v-ìTÓNM’O¨FèÍ“%IšùÁŒ µ™î™ZDtýE|­m‹+Ü‘¹¥áPkÄBÿi†¶øÎÿÛëÐJº±@8/OHcšbÚ  ‰ooh‰tZ8\Ù6×¹Oͽ%Ù»n,UËA´T £k0i0U#0€që/íQ¥ÿ…IŒ|öK¦›¤”0UÐÑLÈm}Cè'õ¤§¿âÜ0Uÿð0U 00  `†He00  *†H†÷ 0g(@´rD­'d5¸ÖcÌmÖìmˆ,—M9×Ä/âD¶l‹&0àxW©%ãÊ–b*—g`R¦ôB À$QfÃ"Öw%2ÔØ/Ô~-Oh½†ÔÐn؇µôêX'ê +žãÜ’RÂŽyö7e‹² §bí²±P¸£@0>ê´úF;Åùbouncycastle-1.49.orig/test/data/PKITS/certs/ValidUTF8StringCaseInsensitiveMatchTest11EE.crt0000644000175000017500000000126310350736724031161 0ustar ebourgebourg0‚¯0‚ 0  *†H†÷ 0]1 0 UUS10U  test certificates 1.0,U %utf8string case insensitive match CA0 010419145720Z 110419145720Z0q1 0 UUS10U Test Certificates1F0DU =Valid UTF8String Case Insensitive Match EE Certificate Test110Ÿ0  *†H†÷ 0‰ì¢^›6ƒg”Ð2ÚY±ÕLÓgÃTošÕL݃‰wØÄ€6ÓöŠÎ–K»¡?Küßš™ŽgP R›ÛuMœŒS0‚Ø}Þ z ñ¶¶‰X 'F¡Å®UÏ£ $[i%L÷{S°³-ÔÓvªõ+a¿ÁQN´ú™yî6M£k0i0U#0€6b)|¥ÂЄÇ^£'ß©Db0UÄÁô¢ïŸß¹Æ Ýú´K§0Uÿð0U 00  `†He00  *†H†÷ ‹d´ÑWeÆÁÍyïëМkfžÃ!p.B .Âä^‰sÜ]>Nœ ùݘ “‚‰A‹à'uåðzNËý®«­ÒV£ÿ®ës*1hgªKY©º0f¦èPÀKŠt²2¯Ü¢©Æn#c+â»Åz‘nŠì@)Š«ì·ZçØ³Í)ò‘bouncycastle-1.49.orig/test/data/PKITS/certs/InvalidSelfIssuedpathLenConstraintTest16EE.crt0000644000175000017500000000124110350736725031232 0ustar ebourgebourg0‚0‚ 0  *†H†÷ 0M1 0 UUS10U Test Certificates1"0 UpathLenConstraint0 subCA20 010419145720Z 110419145720Z0o1 0 UUS10U Test Certificates1D0BU;Invalid Self-Issued pathLenConstraint EE Certificate Test160Ÿ0  *†H†÷ 0‰ßœF æÕ|ŠK †ƒdGóË44­|=—« !~›áûúCxÝÿ=Iêq½s™mì)=ø&H¿!³GqtMŽÿÀŽôÅË(ÈÖ®pUÝþ¥Œ{ ®¸Ã&Ú?…Z}™*Ÿ#:F/(¸jT.Z"I7ý¹Òx#ºçì‡GžTé£k0i0U#0€RzkBN°ãÍ‚¥cÏn#”‰50UDéf//ÅDl좟ÝOA"Û1H0Uÿð0U 00  `†He00  *†H†÷ 0x>•Ъý>0(TT®[‘kƒâ|jžƒSj ¤-(ðw1WÜREëd5ãÕÅ$’ÈÒþU­¦ÞwåÚ?¼o{c [À[še8Š&»Œ$gz¦ÙPI¼J¢.ÿd‹Äîá:xiˆ¯ºRÇ­S~E×ÑO|eiQbouncycastle-1.49.orig/test/data/PKITS/certs/RevokedsubCACert.crt0000644000175000017500000000116210350736724024207 0ustar ebourgebourg0‚n0‚× 0  *†H†÷ 0;1 0 UUS10U Test Certificates10UGood CA0 010419145720Z 110419145720Z0A1 0 UUS10U Test Certificates10U Revoked subCA0Ÿ0  *†H†÷ 0‰ã¦×Q±…5+5<Ȱböâ¤\4˜~ëžê"§åôźÅlàªDpK¹SôžN/ââÒ„ß«q'õ,ê=iLnç#K\ª×.K={Ñ9·c‰#ÉJ÷;)gƒ €Òò_òª†ó¥â$½‚º‡F,vÏö4ÍFØrª£|0z0U#0€·.¦‚ËÂȼ¨{'D×53ßš”Ç0Uxõ½K–³-æ@P2븴GT òH0Uÿ0U 00  `†He00Uÿ0ÿ0  *†H†÷ PhràµçŸ0nù¥O].ogf&˜ï_`1˜“9pÙ²¢Äžg¤æ/2d>o†*9šúJm´ €BÊzH^gMØýF~ô®¤Ò·MönçVQD¾˜Êih–&èË)²†TJ+Sï#-ÅÂ(q_UÑ \T…ÃXº[Ç9Œbouncycastle-1.49.orig/test/data/PKITS/certs/ValidonlySomeReasonsTest19EE.crt0000644000175000017500000000154610350736724026426 0ustar ebourgebourg0‚b0‚Ë 0  *†H†÷ 0G1 0 UUS10U Test Certificates10U onlySomeReasons CA40 010419145720Z 110419145720Z0_1 0 UUS10U Test Certificates1402U+Valid onlySomeReasons EE Certificate Test190Ÿ0  *†H†÷ 0‰ÖÞ0ÂÇøˆM*‘4[™©MXœeÙŒE4^Õ„ÅG¬†;áÕv¼ñ/€¨¢qxÒjMeвT ýœ¡Øuu(ŽCg#ŒêRú~¥ÕçlÜÇ ­óÖLÏnʤ‘1þ…Ù¤yû‚Ä Y>˜Ù\ÏÔ éFQÈY)‘ø[Êú …g Ù£‚D0‚@0U#0€?¾@ñ÷kû°YäZà—Té0UßYôýªS¶K¥ýàÓ}›h´žë0Uÿð0U 00  `†He00ÔUÌ0É0b \ Z¤X0V1 0 UUS10U Test Certificates10U onlySomeReasons CA41 0 UCRL1`0c \ Z¤X0V1 0 UUS10U Test Certificates10U onlySomeReasons CA41 0 UCRL2Ÿ€0  *†H†÷ "™'n–“¥}‰~¿¤`fòe˜[rçï6ƒµߊTQÃe™|¶, ò:qAËÒɺ_ʦÚe‚ò²”¬yšØM÷Da[kV/)ˆ*žË6œø=G¯»‘Z_'ueB–…Ð4ùEÙž4îÃ×ì»æ¨ÍºÚ*+×­è/]ûØÇbouncycastle-1.49.orig/test/data/PKITS/certs/ValidkeyUsageNotCriticalTest3EE.crt0000644000175000017500000000122510350736724027102 0ustar ebourgebourg0‚‘0‚ú 0  *†H†÷ 0L1 0 UUS10U Test Certificates1!0UkeyUsage Not Critical CA0 010419145720Z 110419145720Z0d1 0 UUS10U Test Certificates1907U0Valid keyUsage Not Critical EE Certificate Test30Ÿ0  *†H†÷ 0‰‰ùì§Î˜‚×,Ö^H‘ÃÕ€ÈàXØj†ðæõ!8X÷ñ%Å Az‘Ã9ÿÔÕãÑö˜)å@æ>•g‚?°ó¦BxlcÁu”Ñvv¦aÛ¯,JÅ·f'¬5°ÜÚÆ ZòüŠ¢€ÊãV§b¸ƒ_ÃuæNp 4”ûŠŠ©I—£k0i0U#0€Ï*¡¥ýBâ3¼3*M˜s³ØûU¼Ø0U±|ÔbÒ>c§oU$%Kî9Rå0Uÿð0U 00  `†He00  *†H†÷ ·†UvQÝÜfᡆ®ù­v@äý´£îùþ<ÌË;¦¸«AR„Ûj/M…L½²üõ‚¤ jL ìúÑ®ëy6$¥-À šáR_ó¨2ÜÊ*¾šÈ¡b£g9Á/B ]ÝFêyÉ*ºvðês=Y(ç÷0ƒ?ÝZ=…KfVbouncycastle-1.49.orig/test/data/PKITS/certs/AllCertificatesanyPolicyTest11EE.crt0000644000175000017500000000120310350736724027212 0ustar ebourgebourg0‚0‚è 0  *†H†÷ 0@1 0 UUS10U Test Certificates10U anyPolicy CA0 010419145720Z 110419145720Z0d1 0 UUS10U Test Certificates1907U0All Certificates anyPolicy EE Certificate Test110Ÿ0  *†H†÷ 0‰×#ÃC NgˆtýD¥ˆ<©‡M‘j×#P`ÁÇõ³ž¢äC…ûg@1†›Æaí†Õâ0U ÂÅË'·¶ÛãkjÀ`ÔZµÐ–0Uÿð0U  00U 0  *†H†÷ &#I4ɾåwÔ`OÈ"N𯯼*È[#2…Ëû‚‹1+aO¼ 5©’3ôÍ.6¬JaÊ£üÍ@Á©BUöìœyi5å_”¨*ÑEjaê*s柦ø {í¨ØW¼ÕLöµ‹P m?vyž&ëBÂí™=á¿deZžoÖi†ãbouncycastle-1.49.orig/test/data/PKITS/certs/InvalidSeparateCertificateandCRLKeysTest21EE.crt0000644000175000017500000000126110350736724031367 0ustar ebourgebourg0‚­0‚ 0  *†H†÷ 0Y1 0 UUS10U Test Certificates1.0,U%Separate Certificate and CRL Keys CA20 010419145720Z 110419145720Z0s1 0 UUS10U Test Certificates1H0FU?Invalid Separate Certificate and CRL Keys EE Certificate Test210Ÿ0  *†H†÷ 0‰Ï’Õ ^ !S€Y Ú:÷tÇQÞèY¡s¼ ‹¶2›ZrÓÍNm2¼ ÌrõÍ÷-¥"GêñŽ®]CY3þàúP‡2¿Ï{ãófÔ ç¿Û-ÌædôÉU”R‚¹ðÜd“Õ³±Ÿ.œ´7:æp÷J<ðå竵ÝiQR³{£k0i0U#0€¸˜|Éx4´$¾˜ýå£ÎÞZ¾0U„Si]¥?žhR·.ŠeUq£”A´0Uÿð0U 00  `†He00  *†H†÷ _Á”œ«²õŠÕȦ!Z#X]sG¿|\ŠûŽû)àRQÓP•}ìÂãA €F4‡/Ò®éÏá7üoVm­røíÓtîÛ¶Œ4s\nwÉd¾éË]p¶]¯%ÅmžY ¥Güˆ`¶°3‡>è d¥Ç˜ý!õ [ ,XÙ`Ibouncycastle-1.49.orig/test/data/PKITS/certs/InvalidonlyContainsAttributeCertsTest14EE.crt0000644000175000017500000000124210350736725031147 0ustar ebourgebourg0‚ž0‚ 0  *†H†÷ 0Q1 0 UUS10U Test Certificates1&0$UonlyContainsAttributeCerts CA0 010419145720Z 110419145720Z0l1 0 UUS10U Test Certificates1A0?U8Invalid onlyContainsAttirubteCerts EE Certificate Test140Ÿ0  *†H†÷ 0‰n®M~&{QØUŽË wý‹+²øÊ³BSìâ 8÷˜£hàw c8B~»<uÁ¦Jf"ÏÍÃ0×[õ‹æ-»¨­ø^ꊛf1E˜T…UЍÁê’áø7óäÞ?Ôäÿd§.VÞD¼ÐÅ»¶B“e(3 Vd;Q£k0i0U#0€Å(•›Ã£Ù¸û¶ßmãS­¹"0U~ù*e3gôõ•Y1ôO{¶U»Îÿu0Uÿð0U 00  `†He00  *†H†÷ r{"hú­}¹¯Ö[» ô­oä9oÄ—ì¿vçC 81[‘­¬5ûÀ#ãå׉,¬}B[š*ªøR ß=ÑÕšn1Y|Ï$õæ:ùzA“^Åç:ÆÎð!¾0/ƒÌßEYV¹¦Äkäò¬8·LAÐb*ºÕAèüØ´žbouncycastle-1.49.orig/test/data/PKITS/certs/UnknownCRLEntryExtensionCACert.crt0000644000175000017500000000121010350736725027010 0ustar ebourgebourg0‚„0‚í  0  *†H†÷ 0@1 0 UUS10U Test Certificates10U Trust Anchor0 010419145720Z 110419145720Z0R1 0 UUS10U Test Certificates1'0%UUnknown CRL Entry Extension CA0Ÿ0  *†H†÷ 0‰¸7wïïT ÷°œ´  vpØt±¼=ÃnŠA£ClRA:êgfÎuë¯UjÇ뼓Ä+ßÈ Øn Åñ¯CôŠð+W œ›×è¼€{ÅNaÍRN*±šœb–´w˜O׈ɴRjŠ­ (P®FÏ(îŸ Yl\ ìBsù£|0z0U#0€ûlÔ-žÊ'zž °<êš¼‡ÿIê0Uõ[ëÚÊå愈ŸÙl¿[ΓiM€0Uÿ0U 00  `†He00Uÿ0ÿ0  *†H†÷ ÇÐý€”‹€Ý ›y=å3Š-æ«zößPÆ ¢ýùù¤†ZúÐÀß2­'KT¦ÞYoí€ïXRÞË"I’ºÓÂS~;JwjÕÆóá.[Âèû~ñÃ¥8ñOÏå«W±Mû¶LÃþÜ^¨D“¢S6}r–¿{xÑ¡PÃʯbouncycastle-1.49.orig/test/data/PKITS/certs/P12Mapping1to3subCACert.crt0000644000175000017500000000133110350736724025173 0ustar ebourgebourg0‚Õ0‚> 0  *†H†÷ 0G1 0 UUS10U Test Certificates10UP12 Mapping 1to3 CA0 010419145720Z 110419145720Z0J1 0 UUS10U Test Certificates10UP12 Mapping 1to3 subCA0Ÿ0  *†H†÷ 0‰Ë ¬è'ÇcþP¾dyËɇ8’vOÅcíÿ ûùxÁ~«]n¯ÂjÞh7mrZAs–CdÄË«j¥îñBvÂr;¦]çXq=ˆñ^ìÂÄ3QšÖ.[Y®F×KÏ™œ9—´0©?Ãè™vØ\h—P¬ýÍëú˜’ÍžÿPhE¨"–}ÏËzcì™\´Ñ䋞Ì:ABÐÂŽg´ý!ïg¥îXóo‰Àòõ&—jB©£|0z0U#0€ûlÔ-žÊ'zž °<êš¼‡ÿIê0U£“«Wf&mr:l¼ƒe£šüŽ C 0Uÿ0U 00  `†He00Uÿ0ÿ0  *†H†÷ YÊl$’:Ú ¢d©7t¿PÍÍڻܱßš¬$ nb(˜ì±Ëq²ß¦;…î5=œ¦äÚ&8†¹ÿù` e¢Ne%»Æó2zbg,ÈŽ:ïÄrº{B1vÙÍË;ºk)ó¥ xøÃ ¿;›™ï?d/î$ô6†bouncycastle-1.49.orig/test/data/PKITS/certs/UserNoticeQualifierTest19EE.crt0000644000175000017500000000174010350736724026224 0ustar ebourgebourg0‚Ü0‚E )0  *†H†÷ 0@1 0 UUS10U Test Certificates10U Trust Anchor0 010419145720Z 110419145720Z0_1 0 UUS10U Test Certificates1402U+User Notice Qualifier EE Certificate Test190Ÿ0  *†H†÷ 0‰šJÉt•z*F)ÿ½v49ɼ–¬£P ›Ó‹å¸N–›Hß \®‰wñ&‘$ 3Ÿ¢Wò†¢ÍìýpNþl±`²¸Y¢ýäuÌ%¡9ŒûåÿèøÅ0U…ná\[¯ô{»HÞÌ]‚Üö“ÂC¿ Ùè!÷¾»ñ—ë”Ã.àÄÃ[£‚Å0‚Á0U#0€ûlÔ-žÊ'zž °<êš¼‡ÿIê0Uv£†èÔõ¼œ4ïæ0% ÷àµ0Uÿð0‚mU ‚d0‚`0‚\ `†He00‚L0‚H+0‚:‚6q6: Section 4.2.1.5 of RFC 3280 states the maximum size of explicitText is 200 characters, but warns that some non-conforming CAs exceed this limit. Thus RFC 3280 states that certificate users SHOULD gracefully handle explicitText with more than 200 characters. This explicitText is over 200 characters long0  *†H†÷ 'Â}ä'4‚¼!qru„1vãRB£§€@+D~e•ö#9ù*e1JNóùšãyãþÁ{?tWýpG6y¡]íÖG´ô3€á¿¿¶OŠM¼Žñ×O¦ãßßïZLåíM„0{K~ññè†`à˜ž‰èœp™tjábouncycastle-1.49.orig/test/data/PKITS/certs/ValidNameUIDsTest6EE.crt0000644000175000017500000000116610350736724024605 0ustar ebourgebourg0‚r0‚Û 0  *†H†÷ 0:1 0 UUS10U Test Certificates10 UUID CA0 010419145720Z 110419145720Z0S1 0 UUS10U Test Certificates1(0&UValid UIDs EE Certificate Test60Ÿ0  *†H†÷ 0‰ë\øíÈXEšöáûþ> u) +Ÿ”l˰ݵ¦kY¹íÛî E!pžcùÁKtáÎçÓˆ+wÁÃÄ&#tF¿¼‰l0þ¡ìq4Ž5=£²îªè\í1ïe-ì’%[ôÛu'_ÊHó7¢[SÑ2ŽâÚ]²=\†þ £k0i0U#0€Òe|ÂÙAˆìÕXDšâÌx0UL•µefujPÄ'¼ÍÏo§ø0Uÿð0U 00  `†He00  *†H†÷ µÊ…bI |-¢=1[Íž[ý¸piué†Ñ2Šx­‹g.y}Ûj×†Ðøy˾·Ý!@4ÐVKç§Ô.ÜÛbñºçg!XŒßÿËÀ6;§ZIÿ=T+#¨×9Å4oˆköÚ6é+(ȵ­`ïÔ]Ú¢ï=5ê:¯Ínºw®Õbouncycastle-1.49.orig/test/data/PKITS/certs/InvalidCAnotBeforeDateTest1EE.crt0000644000175000017500000000122010350736724026436 0ustar ebourgebourg0‚Œ0‚õ 0  *†H†÷ 0I1 0 UUS10U Test Certificates10UBad notBefore Date CA0 010419145720Z 110419145720Z0b1 0 UUS10U Test Certificates1705U.Invalid CA notBefore Date EE Certificate Test10Ÿ0  *†H†÷ 0‰¹?ÏãH߉µÕ`»YÈ’UáÜ;éúaiU}„°lÕ’´Œ~ûúÆ—:æ dÓæM±Á‡;Ý’N`êû‘œ¬¶ÐÃ.‰Mø ä\|IDþ¶.âÚ†ÂZC˜óÚ‚4ÄÑëù¸‚u–Hܧò¸ý[±~J[ÍíÊ‘nk£k0i0U#0€z3ø#Šœ*lO8"ÕËý}X0UiY=³egfÃ[~Àu7SYå°0Uÿð0U 00  `†He00  *†H†÷ mý÷"¢3Ow³Â ¬:„\¸Ñhë 3ÔóLtñ4ÚO™óý2ùœÎ©¸=|§F̤f¹÷òØ AýˆVÏêûR ±”¾ÜUšø®pííÀÕª>)Ohù¨¹hÝ„¬eŸ 0i"QaÀW]= ,¦bouncycastle-1.49.orig/test/data/PKITS/certs/MappingFromanyPolicyCACert.crt0000644000175000017500000000126210350736724026206 0ustar ebourgebourg0‚®0‚ 30  *†H†÷ 0@1 0 UUS10U Test Certificates10U Trust Anchor0 010419145720Z 110419145720Z0M1 0 UUS10U Test Certificates1"0 UMapping From anyPolicy CA0Ÿ0  *†H†÷ 0‰˜ÂLü¯ºÕÑNºã.µGj@Ü_wÎ׋9òŠk€ro<;5ø|®­ºÖ¾ëÉ'à̆a&6úeš•â¬ÙüIËUOŸÅ‡>&r¿x´4õàŒÑKöSg½,Žm=ߥù߈Êäɧr) þ8rÛüéÓóhëÃõ£ª0§0U#0€ûlÔ-žÊ'zž °<êš¼‡ÿIê0U÷Á«5Ø/†Z67YoÁÁ¤m¤¤H0Uÿ0U  00U 0 U!ÿ00U  `†He00Uÿ0ÿ0U$ÿ0€0  *†H†÷ ‰“–˜Ú_€¤ëe›‹"Þú a{™ Jq”pÔ6âæ&F ~y{ªŠ½ƒ”},÷оôôàâX±øfnrïÜl²²XÍ/¬ ðǘÓ#*Ôô8øS¾–~g¼<õ»?N QwŒ‘G·áùÌÉ.ß ì•S9Ƚ!"Ëhbouncycastle-1.49.orig/test/data/PKITS/certs/BadSignedCACert.crt0000644000175000017500000000116710350736724023723 0ustar ebourgebourg0‚s0‚Ü 0  *†H†÷ 0@1 0 UUS10U Test Certificates10U Trust Anchor0 010419145720Z 110419145720Z0A1 0 UUS10U Test Certificates10U Bad Signed CA0Ÿ0  *†H†÷ 0‰× Ž  Ϥ¥*¹!ï‚»XLPk1-ë¾D3²øBR„ëƒÀiãxKq=\ î嘊»»d̓âN ¬Ò‘ݱôî´NòdvmñgvºÎ?­MϬþáXƒXŽ*-úì Þ¾#›–2è…Ž—rÙƒz9+2Šþ‘£|0z0U#0€ûlÔ-žÊ'zž °<êš¼‡ÿIê0UBo— #yÁWž:¦ œˆØ0Uÿ0U 00  `†He00Uÿ0ÿ0  *†H†÷ k ¾55†›.ìqóÿ.þeøK³UüÀñÁK=}ñöñ7a>Pþ}küǯ;M*«‹µ¨LL¿òÒˆzÝ@8ÓIsKꆉÃ%ëÚDÚ`+­Âþ+2¤ ï 6 Ý ™i“¯¸•ö.!@ÛCDUc4y0bouncycastle-1.49.orig/test/data/PKITS/certs/onlySomeReasonsCA1Cert.crt0000644000175000017500000000117510350736724025323 0ustar ebourgebourg0‚y0‚â P0  *†H†÷ 0@1 0 UUS10U Test Certificates10U Trust Anchor0 010419145720Z 110419145720Z0G1 0 UUS10U Test Certificates10UonlySomeReasons CA10Ÿ0  *†H†÷ 0‰©ŽXzgƒ  ¡téQdTâžÔ懙€~«Ú2OŠèW‡}Odð_ÖˆA§œ«‡¹™°B¿ )À~úYëmN£²×°Ô´`Ø®~ïwO§°“YCÖWXGŽ‹x`i8ï »H¥güË(’Q"Šoù‚Um‹)Àj,fêM£|0z0U#0€ûlÔ-žÊ'zž °<êš¼‡ÿIê0UàbšßP½[Iþ¾pÌÜ9n0Uÿ0U 00  `†He00Uÿ0ÿ0  *†H†÷ ›žAs -rSé ®ôõ›R¹ÐeNúw‘W êf´8à‘O»L˜&PÔ¶ju.Ä^u¶G˜¼Éj4û*(ë7úÆJ*YÉTvÍ”iw[|‡îë9Nå^ RvÔB ægÝ?¶-Ÿ€‚§ùÀ51'¶f´bqÔ›’‚ØH9WÛxÅ bouncycastle-1.49.orig/test/data/PKITS/certs/InvalidkeyUsageCriticalkeyCertSignFalseTest1EE.crt0000644000175000017500000000126310350736724032073 0ustar ebourgebourg0‚¯0‚ 0  *†H†÷ 0Z1 0 UUS10U Test Certificates1/0-U&keyUsage Critical keyCertSign False CA0 010419145720Z 110419145720Z0t1 0 UUS10U Test Certificates1I0GU@Invalid keyUsage Critical keyCertSign False EE Certificate Test10Ÿ0  *†H†÷ 0‰ UúÕj²+°`Ïæ¤×sI®G,¥Á [#¬ësþµõçŽL6¥«¸²²’qLHgîQ»«õÍ„§©A»WÕGEñâÖë·"ÁóC ËLíŒð Ý?Á]có[h(?LUß”«CM£qU“:eŒÀŽ¡g $C°¬mç´ÙÌë à-£k0i0U#0€”¼øœ|?è’¶MÉ´Ór1N:70UöiÎÍŒ©J.a\3eì ,‹éo0Uÿð0U 00  `†He00  *†H†÷ x©s‘ÕˇÒ3jøHƒØsØ4!½aûV!…Œ¢º‘o|éyo‚×Ãh{¿‰Í©ÐÑ(Çþ·ãÚ|8 '© å÷&H¼æ¹üÞÅ×uu/¢ØHõæ)ûê5ùqÄ/ DBP=ƒùþ¦‚"‰ßŠv‹exÜ’U‰º\ÌØXbouncycastle-1.49.orig/test/data/PKITS/certs/ValidpathLenConstraintTest13EE.crt0000644000175000017500000000123310350736724026711 0ustar ebourgebourg0‚—0‚ 0  *†H†÷ 0U1 0 UUS10U Test Certificates1*0(U!pathLenConstraint6 subsubsubCA41X0 010419145720Z 110419145720Z0a1 0 UUS10U Test Certificates1604U-Valid pathLenConstraint EE Certificate Test130Ÿ0  *†H†÷ 0‰­ú WÁå,Þ3ƒaõ«ÜSKHìQ·@Y”ÈXp”ôîöͽl“–xʱn´ˆ†ÔmÜ«•3qQ÷áÄvuY‹í¸Lp(#ß%Þ@•’å]¿­q"¶æ¿Ö7Ùx!¶ò(èZ:3$f5Ò1uCkíøKͳ‘/™‘5ã£k0i0U#0€•犖tù<ô›©IóÁš?Îp0U*!Þúoå—†ŠR¾殆q"$&A0Uÿð0U 00  `†He00  *†H†÷ `×¶ެ„¶*EOÇÅP0¡ÐÂ(Pt4GäHj²¸0æÝá±N>2™î§@8å‰F<k0&Ìö ùtbÜ«,@¼’iœ®n[ŸßZ»8ç[ªæ‚çÄF‰»ó̸yûYpšÐ¿äOA;ü´ôØY©øîPòHbouncycastle-1.49.orig/test/data/PKITS/certs/InvalidinhibitAnyPolicyTest1EE.crt0000644000175000017500000000121010350736724026766 0ustar ebourgebourg0‚„0‚í 0  *†H†÷ 0H1 0 UUS10U Test Certificates10UinhibitAnyPolicy0 CA0 010419145720Z 110419145720Z0a1 0 UUS10U Test Certificates1604U-Invalid inhibitAnyPolicy EE Certificate Test10Ÿ0  *†H†÷ 0‰µ;ççìªJ Ö¸ý¬³ò³Óí_ß}Så~ïSxÐ&“ž¬H•Ž>S ?·Š£SA×2j7ì·8‘/>ò27Jockˆ‘ÿ‹d‚/Nb½>Í qªR(DöëÈÚñ$‡{à1hPø05óÃÐ,Ø’m[c\0|Ñ&QÌdó$ãe0c0U#0€@˜`æÈý\ÑØ/ êìEÏ0U`%ô/ËÎ@Tõ¥ ÉßWÖ"–0Uÿð0U  00U 0  *†H†÷ [‡±âàòéíÅ0>…C ‰]ä)Ó=¾… ¾Q´/M‡ˆ ¢)øÙ+öµpõŸgÇ5S&ˆs³“‚À7‹ÆÝb ˆïÞ[‚ÏPZ9ÜÑVšë­¯ üÌïÓ ó+õõ S ÁþàWv‚´ cGx4Tâ ùéÔbouncycastle-1.49.orig/test/data/PKITS/certs/ValidBasicSelfIssuedOldWithNewTest1EE.crt0000644000175000017500000000124210350736724030143 0ustar ebourgebourg0‚ž0‚ 0  *†H†÷ 0P1 0 UUS10U Test Certificates1%0#UBasic Self-Issued New Key CA0 010419145720Z 110419145720Z0m1 0 UUS10U Test Certificates1B0@U9Valid Basic Self-Issued Old With New EE Certificate Test10Ÿ0  *†H†÷ 0‰¬‰œaþìéæ´ùÚ³Xð dO¶%„ÿzà6¹êÙ5ÒÊ‹T¡Â+Ñb ¦¾ˆß´±Îáf…óŸ leìw‹ð/Ÿ*V\3C5|%;šüœb6m1#›…5š¿ÌFƒ»Sk(z½ŽLu&Ù!˜ÖˆŠ‘üN1§:gÚç¢.‘£k0i0U#0€É[ÓÑ¿ñÁy\»s LFË-Ù0U²‡!™ –tÕM’K:Ø%œ®î0Uÿð0U 00  `†He00  *†H†÷ fí­ïO¨\™!Øç§hÿ~ãÎqšèBÙC”»+vXX ;æ©{<‰ƒ7k04º?5öTÅqê(bæÔ'33Ü`˜½bÇI –Þý´.QßßÕÔìrc}yùQ#ð¨ÛëÅ€D_/]2Ò÷¾»fD…½¿òvTúßΦø bouncycastle-1.49.orig/test/data/PKITS/certs/NoissuingDistributionPointCACert.crt0000644000175000017500000000121010350736724027460 0ustar ebourgebourg0‚„0‚í L0  *†H†÷ 0@1 0 UUS10U Test Certificates10U Trust Anchor0 010419145720Z 110419145720Z0R1 0 UUS10U Test Certificates1'0%U No issuingDistributionPoint CA0Ÿ0  *†H†÷ 0‰¾ï#C¢¼\UZHÀÔ™DmY{oe]³÷Úøl6«`½È‘Û ­qPž3l ò–éüÏ¿¤Ä¹‡VKÎßoé»÷á3—ƒ;Å{Äiºø¦ô«(iGs¹OÀNfžæÆ˜Üœ•”ÝÔèØ»’ýôrÏ‹ÐMÖ”Oºç£|0z0U#0€ûlÔ-žÊ'zž °<êš¼‡ÿIê0U,Å'#ÑÑAßßa„¹Oñ2ì10Uÿ0U 00  `†He00Uÿ0ÿ0  *†H†÷ ‹oÖërîÞ” ºÉe†Š_‰2×+¨LGcüÕ¸.à*µ%;·¸-ŒìöiQˆÒHø¤Fvi–ܺš¯ÒKÿžÁ€ü„À‰iõÌÇ`,x3K^Àeèä™áÊèï½`”¾@–sÿß òWéêaî†bwSRÓbouncycastle-1.49.orig/test/data/PKITS/certs/nameConstraintsDN1CACert.crt0000644000175000017500000000133510350736724025553 0ustar ebourgebourg0‚Ù0‚B >0  *†H†÷ 0@1 0 UUS10U Test Certificates10U Trust Anchor0 010419145720Z 110419145720Z0J1 0 UUS10U Test Certificates10UnameConstraints DN1 CA0Ÿ0  *†H†÷ 0‰œ½¯Í2¾YÁ‘Ú¹¥{7TMD$|‹óq5‘!U¶Çàq@úÏ~‚êš–j¾,cÃCÒ]éAgÁ˜‰¦ÚñÔ.¥1dŽG÷Lß ¬´åÝØ’UÆü?¿†£`e<×+¿ÂòÇÕSgZªV'Ë÷óºã^èc+5P£mž§èue± ½£Ø0Õ0U#0€ûlÔ-žÊ'zž °<êš¼‡ÿIê0UN.£çÙÝ‹§‚;AJÞ|Y#WNS0Uÿ0U 00  `†He00Uÿ0ÿ0YUÿO0M K0I¤G0E1 0 UUS10U Test Certificates10U permittedSubtree10  *†H†÷ ½Êš¡e`¦¬„‘•¯ÆŸï²¬Q2Ôžìðkåß·`ïF’}?éwŸò.oÜÄBj¾¥3Ì~r€L®5UA½ƒ¥VØ0(mÚŒ£ãËÍÐgxuL/°`&™[ˆÀ}ÿíˆÊtÓ~5~˜ÈJ̧1 \UíØèogÌœDÑìbouncycastle-1.49.orig/test/data/PKITS/certs/BasicSelfIssuedCRLSigningKeyCRLCert.crt0000644000175000017500000000143510350736725027600 0ustar ebourgebourg0‚0‚‚ 0  *†H†÷ 0X1 0 UUS10U Test Certificates1-0+U$Basic Self-Issued CRL Signing Key CA0 010419145720Z 110419145720Z0X1 0 UUS10U Test Certificates1-0+U$Basic Self-Issued CRL Signing Key CA0Ÿ0  *†H†÷ 0‰—*ËG@oˆ¯üÔ/Bþ(÷8~óO€³Ûµ:‚X'˜‰® ÿ®XípCDµL–Ð-Úñ·m¼ô·?Ï~=ocƒi˜WþÌ€¶µFŽsª‚µ£Nîï€gC¼™«IRßIv¯¥åÎûÌ:+4‡pÏÀg¬î­éøN3£ò0ï0U#0€IÉü·áa[!š¹ÿ¢ƒÒÔ4W®ÌIµ”¢˜Àe!EŸXÌVì‰ÂõIqhfëFÞ¨BXS ýË @VcÍÒ.à:Í^p“ p™G—]‘8«Xɬžø}í®æãauÚ;ÓüŠh1¹9¾(# f#{ýþ³é$$j晣0}0U#0€H4T¦ìOÙ˜!ìÔc±#oíy>0UÆÅÝ=×ûtC@ÉÐªå¡ Ö4Š0Uÿ0U 00  `†He00Uÿ0ÿ0  *†H†÷ uäHWØÇw‚„²Þ¿cG›>ZBOï0¶0<Šn¬¨¯DÑ|»¸éHÎÀŠxÔÓN`Ó¾u¥â:SZÓº´q¹•NÒœõþú5¦à°†\ Žb†c´²r ±›Öm#Ik2UTÆöM<Òƒ`B“þ®0®ò\™)áÛßó^¸U#¤bouncycastle-1.49.orig/test/data/PKITS/certs/PoliciesP123CACert.crt0000644000175000017500000000124610350736724024216 0ustar ebourgebourg0‚¢0‚  $0  *†H†÷ 0@1 0 UUS10U Test Certificates10U Trust Anchor0 010419145720Z 110419145720Z0D1 0 UUS10U Test Certificates10UPolicies P123 CA0Ÿ0  *†H†÷ 0‰¸kUºµ¢ÕD¸ßìÅWHáW2&³Qb¦³¸Q˜]@Û+9‚`.˜Ê–Äœãö&’Ð8ü}Z‹/ÁUï’£áæ+nQÑ¢½…PõôSÚ8o“Qqa@¡€@aŽj^÷E>X£Äüjùjî„‚ÔI²óÃx†Ju~>(ï#£§0¤0U#0€ûlÔ-žÊ'zž °<êš¼‡ÿIê0Uп͛ßñ‘ý‚‡Zϯ‹¼òÅÌ0Uÿ03U ,0*0  `†He00  `†He00  `†He00Uÿ0ÿ0 U$0€0  *†H†÷ wT!y°ù½¥ys!ïY%y ñ‘ÌVü¢bÅTMæÎxãRSG.>lè˜I)/&ÏÇ®ˆqJd*-\åìmp5ÄÖÔÅhÙï9éu-ß•r_cKúA!ê¡h°›è©M›~£©JävØ’J5KVbouncycastle-1.49.orig/test/data/PKITS/certs/requireExplicitPolicy2SelfIssuedsubCACert.crt0000644000175000017500000000122610350736724031220 0ustar ebourgebourg0‚’0‚û 0  *†H†÷ 0P1 0 UUS10U Test Certificates1%0#UrequireExplicitPolicy2 subCA0 010419145720Z 110419145720Z0P1 0 UUS10U Test Certificates1%0#UrequireExplicitPolicy2 subCA0Ÿ0  *†H†÷ 0‰Ò*Q\/öÓ¼«ÚÚ'ªvzÛkiKsÖ|¿ÏÏó´à5yeQº„¥áëׯå8Þ¥ivä´ÍJÿ«ã3Ui§Æi@p¯nw¨šI좜M˜ ìjư<𸥇¹;(_<Ìë¶­äö·¬‰”k°k¸ÎTCMôX“øë£|0z0U#0€Þ)ÖæãO—¨:¦êMäF_‚00UÓ ðibŸ–6g‡«¸†00Uÿ0U 00  `†He00Uÿ0ÿ0  *†H†÷ }5{­v„NÏvJwrâX«cMÍͤiñ^zý»8âŽê‰ÁÝô`Þ/ïˆÖˆbÈx'åUñ,¬ci‘GPÍŸ¥ðî"4|çжçÅ1•]yÁ¡;¿7 î¥±'pû8îëjÇ—³µë»HŽGD9|Fµ°¤´†~µbouncycastle-1.49.orig/test/data/PKITS/certs/ValiddistributionPointTest5EE.crt0000644000175000017500000000130710350736724026725 0ustar ebourgebourg0‚Ã0‚, 0  *†H†÷ 0I1 0 UUS10U Test Certificates10U distributionPoint2 CA0 010419145720Z 110419145720Z0`1 0 UUS10U Test Certificates1503U,Valid distributionPoint EE Certificate Test50Ÿ0  *†H†÷ 0‰²&˜ÏŠNp‚hž6ˆ»‰Å§Ø•ÀlLÊU‡O…ˆ—» NA‘xy‰#*óV϶‹ZÅæ~ZÏæ_&FbÜF¿–Ž›Dò)\µ—OÖĦ˜—qa,B359ŸŠ ,>¡ËA‰±Ý MÓ8þY ¥tœhüP~rÕÖÅ óT­í´é££0 0U#0€:4‹ãvXXć˜}~Œ¬]¹N0U÷ ä%‹®ÿtøÇ™ÜõÒ¸·0Uÿð0U 00  `†He005U.0,0* (¡&0$UCRL1 of distributionPoint2 CA0  *†H†÷ šs|8÷–r0>ƒ-,™ ãñÏçâªA K ó½–Pšøç 1äGü?ÂÈ¥;¯¾»gV°ôѶï!ÊÆPðv@È;»xˆœCÙRåÖëY(F ‚iZ>Ak|±s娆Å0*uÒ‘¬|Šmµ½ ¨…`R×Wbouncycastle-1.49.orig/test/data/PKITS/certs/onlyContainsUserCertsCACert.crt0000644000175000017500000000120210350736724026411 0ustar ebourgebourg0‚~0‚ç M0  *†H†÷ 0@1 0 UUS10U Test Certificates10U Trust Anchor0 010419145720Z 110419145720Z0L1 0 UUS10U Test Certificates1!0UonlyContainsUserCerts CA0Ÿ0  *†H†÷ 0‰½¹‹.ç{¶ø2:`™Õ!µvâ|›N½ww@ZÒѶI×÷#mGmºtü0ÿtÈŽ»‘‡ªI# Œ8Ѽ'×ÌÕPP¾µ´â´QÙÂGêúh&!îGÔ#–2á¡`0æ/§õ!ªÕÃÌHmÓ#®oÅ4nëÓjg :÷î¨yÀ³p £|0z0U#0€ûlÔ-žÊ'zž °<êš¼‡ÿIê0UZË7ÒF˜\•øß¸:ÿ@­ò0Uÿ0U 00  `†He00Uÿ0ÿ0  *†H†÷ )÷‡, ÔÀáåŒÄ€ê{§ÈhÐøÖ%tG+“Ê‚@›w.£%Θ¾˜ÊÆv¦]û³ «ÝWµˆ¨õÏv@|QÈÓ±“îs’÷$Ç?0[QZÆŒœ‡›“š%IÙOrèY3Áàüím”KqÕpgþí¸¹xÇibouncycastle-1.49.orig/test/data/PKITS/certs/pathLenConstraint0subCACert.crt0000644000175000017500000000121310350736725026326 0ustar ebourgebourg0‚‡0‚ð 0  *†H†÷ 0I1 0 UUS10U Test Certificates10UpathLenConstraint0 CA0 010419145720Z 110419145720Z0L1 0 UUS10U Test Certificates1!0UpathLenConstraint0 subCA0Ÿ0  *†H†÷ 0‰½Ê«³LRç´'ÖH›±´‘.‰@Òr!5 _ê˜õ‰‡Ù¹YR;̈ ãflÖú„ÇPÊžM(v[`èyÝXVÎÁ“{Þ1›ì!:+b)é&N×êµ®ÅaŽí’Þ|<·"F©zn¡½¤ùµ/µ rÃò¬:é£|0z0U#0€! µvvÓ³*¬&üª¦OòÖ¡oK0UŽ«FœKnçåWˆ '“þ'Öç0Uÿ0U 00  `†He00Uÿ0ÿ0  *†H†÷ 5µ¬ƒvÓÝÙC~ðü¬6­| ]"î«1ô–Êí%0­ãSºrÃÕ!ìqXÌœ[гÞ+hŠ¡´»B¸Ì´âŒ$·‹½±R•…¯þA<ºcÅr2æ®%ømø˜R5É>©¦dQ13{Î\Ì®›L2]Ñúî=~é`QyÏ•÷Å•obouncycastle-1.49.orig/test/data/PKITS/certs/MappingToanyPolicyCACert.crt0000644000175000017500000000126610350736724025671 0ustar ebourgebourg0‚²0‚ 40  *†H†÷ 0@1 0 UUS10U Test Certificates10U Trust Anchor0 010419145720Z 110419145720Z0K1 0 UUS10U Test Certificates1 0UMapping To anyPolicy CA0Ÿ0  *†H†÷ 0‰šèfQ˜ª³Óó)lJøÝ,xbI{uå<¿YɪØO ÝÙœb3R0jÉ"Ófúþ÷P¦OÐ%¼\¦»ÒÚ<×Ú'ª=½C&;ˤ2ÙW¸²4¥ucÈÞ[ÇÚ9!Aü÷¿í…ÄÛf×äêeCZ<§ »a—£}ÖY´>£°0­0U#0€ûlÔ-žÊ'zž °<êš¼‡ÿIê0Uº€Ìz,§cZ«N?„ÄSU iú0Uÿ0U 00  `†He00 U!ÿ00 `†He0U 0Uÿ0ÿ0U$ÿ0€0  *†H†÷ ¸ÌÊWL~²™vÀ+Á)ÿ€¬(’ IG2©që'¼ÈYjS½ëf3‰@á²tŒ`@~r@Ðó9lk)GL„cg[º ŸaúB»dx{'êöcX:öyäüð¬Ä'¡âm'Ûè„"¯ Sç{±—X¿ŠAeD:¼(L¨Qbouncycastle-1.49.orig/test/data/PKITS/certs/ValidcRLIssuerTest30EE.crt0000644000175000017500000000155110350736724025126 0ustar ebourgebourg0‚e0‚Π0  *†H†÷ 0C1 0 UUS10U Test Certificates10U indirectCRL CA40 010419145720Z 110419145720Z0Y1 0 UUS10U Test Certificates1.0,U%Valid cRLIssuer EE Certificate Test300Ÿ0  *†H†÷ 0‰¬(»£í("œo¤õ ðmX³NÚH=S%uÅ4´ÏЈÝbkð íWO])ÈY _ˆðÿŒ¶èu¾ dßW{‹lVðSÎCˆ¹ ™<¯èÙ2]íVÏ`Ò:ã +ž‘AöÇ|Þl™c£|0z0U]$îŠUòÆÉ²Â¿Šð²IO:³0U#0€tÕ$½^eˆá‹ ~êHNa0U 00  `†He00Uÿ0Uÿ0ÿ0 *†HÎ800-¨Yo1w¶ ì6›ëKa ¯Dírº)m"á½M'ö.;×ÖY^Ë%†"Øbouncycastle-1.49.orig/test/data/PKITS/certs/InvalidonlySomeReasonsTest20EE.crt0000644000175000017500000000155010350736724026740 0ustar ebourgebourg0‚d0‚Í 0  *†H†÷ 0G1 0 UUS10U Test Certificates10U onlySomeReasons CA40 010419145720Z 110419145720Z0a1 0 UUS10U Test Certificates1604U-Invalid onlySomeReasons EE Certificate Test200Ÿ0  *†H†÷ 0‰£ýyiö?[^™,­§×ч{~Q’)ëi9ˆ×µD¢ÇÏOÅ$̬÷‚DÙÉžh¥²é@K“Ìe¹Ö^!ņȻALÞpã¬dÓˆ!Ôü|go¿štÿž³Âƒ/)—õv 5ü†p3G¡|ÂT{ˆÁÞÇ/aDüÈzç\‡ÎÄHD¦µ£‚D0‚@0U#0€?¾@ñ÷kû°YäZà—Té0Uý/‡gÓ¤«èË“t×3¸_’2«0Uÿð0U 00  `†He00ÔUÌ0É0b \ Z¤X0V1 0 UUS10U Test Certificates10U onlySomeReasons CA41 0 UCRL1`0c \ Z¤X0V1 0 UUS10U Test Certificates10U onlySomeReasons CA41 0 UCRL2Ÿ€0  *†H†÷ "ÌjšGdnÍhtÈ%œË)s@=(wPbp‹‚D—ánY«;¦vذ†µŽÒ_£ÔòW+ cRR”›6OûGôò›Nå®=¦7˜žÆŒõ<ßüÿ~•9p%h¶¦óÞYí¯&ì&6Zij¢4˜ý´Yµäb9 Ú¬ÏŽŒ£1^¶e¾bouncycastle-1.49.orig/test/data/PKITS/certs/basicConstraintsNotCriticalcAFalseCACert.crt0000644000175000017500000000121510350736724030761 0ustar ebourgebourg0‚‰0‚ò 0  *†H†÷ 0@1 0 UUS10U Test Certificates10U Trust Anchor0 010419145720Z 110419145720Z0]1 0 UUS10U Test Certificates1200U)basicConstraints Not Critical cA False CA0Ÿ0  *†H†÷ 0‰·›*칕½ä àÆt§]”ǪW%Ío‚ìÛh¿ÞžŒÀr!ý´áðŒ×—ßg Çïú–u8|… ~±èCUó±=$àpÕ0Jàuþç×ȯÄSmÕ-dõSȲÏ<JHë͈ÐkÍç£ëž|óóÿ8Ó™–êqjߣv0t0U#0€ûlÔ-žÊ'zž °<êš¼‡ÿIê0UÄ•âºvlÝã»KhýBEøTì[Í0Uÿ0U 00  `†He00 U00  *†H†÷ †8+¯‰Î·*“¯¹œ\ÍcЯÿ¸À­SW]Èßõ¦â¼ŠkìˆçaT4pDG[IJêa«uće1=æèÛ‰gÉϨM”7¶Ƌ“Ëqw øf>ÏP0ÈÚª×ç42JÍL¼¬QRg>n'Þy$?D<æCJ¿bouncycastle-1.49.orig/test/data/PKITS/certs/InvalidBasicSelfIssuedOldWithNewTest2EE.crt0000644000175000017500000000124410350736724030475 0ustar ebourgebourg0‚ 0‚  0  *†H†÷ 0P1 0 UUS10U Test Certificates1%0#UBasic Self-Issued New Key CA0 010419145720Z 110419145720Z0o1 0 UUS10U Test Certificates1D0BU;Invalid Basic Self-Issued Old With New EE Certificate Test20Ÿ0  *†H†÷ 0‰¯oeãñ»Dd,<ÎæUZìœãzËt4Ú{3Ä3AŸ]÷]žVAÎFJÞŸC"LGBêðx^ü¼Ä€…`.qw ŸM5 ÄÈš"w”+iJ mÚ~i‹5wœxå6Hö ßÁ½I¨Üúv–æu65XWïAÛžz&Jl yvŠüù£k0i0U#0€É[ÓÑ¿ñÁy\»s LFË-Ù0U&å Ï)‹:‚Ⓢóâ1’æ‚0Uÿð0U 00  `†He00  *†H†÷ Æ!PeõËW  ՜¶Aˆœÿ9€bôdœ hhÇ´,Š{KòÜóqücƒžQ¢V¬a‹ØyMÞB…ö»o{"ÎÂÛ­–SI2üåžû†êã@}®%û_ò”Þ‹‰¡UB‹Ð® H…n„ƒ­ R*em÷&¾„¼X0Ò­bouncycastle-1.49.orig/test/data/PKITS/certs/InvaliddeltaCRLIndicatorNoBaseTest1EE.crt0000644000175000017500000000123710350736724030100 0ustar ebourgebourg0‚›0‚ 0  *†H†÷ 0P1 0 UUS10U Test Certificates1%0#UdeltaCRLIndicator No Base CA0 010419145720Z 110419145720Z0j1 0 UUS10U Test Certificates1?0=U6Invalid deltaCRLIndicator No Base EE Certificate Test10Ÿ0  *†H†÷ 0‰®ñ©qm°@@ß¿{\&,BAôª<«LÚX-û©0Å]Õ^k´¬F#vµmA‹¶e°«Ê(Ô¸í¤SyÈÒH–ÿµ½ÄcG#I:gÇû"ÿ0é=ÄÍ^ÑRPd3?fÓ+Ðis§ÇOk# ‚†5-¢þ=lAÂ-õ3£k0i0U#0€‹Öÿž)é,PÑ#y]eÛ`pôÓ0Ug?ªwýl”S¸tÒ^AäS¦0Uÿð0U 00  `†He00  *†H†÷ à¿à[œ¼¦'ýƒ*QËØ$LìŠ>+‘i¾!—œúfµTô鯔€• Ì>l8Xo’¸UdÕ,±¿ 2h(¯%ÇOWqÖS»É¨v/ÈüDn¨Ç”ëß´Õñµ¶-Ì¢—è— %÷Õø±±€™‘Êc0Ž$n5æŒcž«µ¾vÁ™Æù$‰G ÛkHDZ ã4á‹q‹UçŠ<ŽU€ä¸Êa ·À}¸×£k0i0U#0€·.¦‚ËÂȼ¨{'D×53ßš”Ç0U:Ì”e …©<Áà¯Q3*Hž‘[0Uÿð0U 00  `†He00  *†H†÷ ¤hg©ˆ´ëÍgô8­ß©`ÝOý6h6£Ìh‹Qw ¼ñÇc"xSȧ!c'[WÁÃóÓv<Ø«²v(ÏÙã²@²=RˆÃdm†^Þ¶Y:Wk3ȲB9ÿ/RU‘ÝûˆWdèvK^¶öÂåÈßnÄáÅÀé"÷¥à¹Ÿ|LKðõÒkž5Q fbÑ7É”¬ÝDÜKâgÿçÃ$‘ÕCK+údg±ýuˆÓbouncycastle-1.49.orig/test/data/PKITS/certs/ValidpathLenConstraintTest14EE.crt0000644000175000017500000000125410350736724026715 0ustar ebourgebourg0‚¨0‚ 0  *†H†÷ 0U1 0 UUS10U Test Certificates1*0(U!pathLenConstraint6 subsubsubCA41X0 010419145720Z 110419145720Z0a1 0 UUS10U Test Certificates1604U-Valid pathLenConstraint EE Certificate Test140Ÿ0  *†H†÷ 0‰“s,±•ä±_Õ=h•¹ÆïH­Ð\ü?™3¶ 8‰ œÌ©@sCſ׻ÊxGÝ«¸œ\=ž H<]!ƒÒÊ$Qat#Ýã`¦qµ>ZnIE='¢-uäå²€=áVpÙ³¯ùIÈâìæX*ÐYºkÐùŒ[db¢õ£|0z0U#0€•犖tù<ô›©IóÁš?Îp0UI®o ö š1Ë'M1„¶Ó¡µ}0Uÿö0U 00  `†He00Uÿ0ÿ0  *†H†÷ _¹7ùŶ‘3¶›ëÿ¬ :F‰zÿ¿[à[–‰Q›-”kûš«Ç? ¢áÎc*ð‡â‚d?~0I¸EæGqüƒâN‰‹gVÆ¢Ú¡ÄDã™ö¯©!BëyÍöC6{¹@—WíþÇ06h 0¯*éÝòØøÒeÉãæê½Lbouncycastle-1.49.orig/test/data/PKITS/certs/PoliciesP1234CACert.crt0000644000175000017500000000126510350736724024303 0ustar ebourgebourg0‚±0‚ #0  *†H†÷ 0@1 0 UUS10U Test Certificates10U Trust Anchor0 010419145720Z 110419145720Z0E1 0 UUS10U Test Certificates10UPolicies P1234 CA0Ÿ0  *†H†÷ 0‰Å2Û «V}š(,a厸f!ü9:µßƒsKò]&©À4Ö¡!,&¬Ä}òÇyÄ£í4DÒC}ýÝfkø‚Šxl*>Xo‘Â)C.’Ý0þ×Àvír*Þ*š£ÛߺÍŒ}9hSY®ë +ŸûÒ:€äÖµCÙ9î0Å£µ0²0U#0€ûlÔ-žÊ'zž °<êš¼‡ÿIê0U0»yOo²ƒzhC«÷L¡@q 0Uÿ0AU :080  `†He00  `†He00  `†He00  `†He00Uÿ0ÿ0 U$0€0  *†H†÷ Ê#óu1¬ÿ¬kIy¼ý­ÇÝ—ª²cíFÁÇq:Lz Þ?¦ÜÅà (fº¯žµÒ*= (ÐÃñ>¸q]äAþ&Î4@®óS¹‡â:à©|OÌk¦'”¸¦ ‡óÆ­Óe/10ãั×ÚŒ³gCa¶2a1ó̈—~bouncycastle-1.49.orig/test/data/PKITS/certs/InvaliddeltaCRLTest10EE.crt0000644000175000017500000000145510350736724025235 0ustar ebourgebourg0‚)0‚’ 0  *†H†÷ 0@1 0 UUS10U Test Certificates10U deltaCRL CA30 010419145720Z 110419145720Z0Z1 0 UUS10U Test Certificates1/0-U&Invalid deltaCRL EE Certificate Test100Ÿ0  *†H†÷ 0‰ø>P¸ büR’ô°s-ÚðKä§Á¬³{Á!Zˆá Ð¥‰[òÃáàæ„Éýӫ9A ƒü£˜¬¡ªTf3œñ×fo¤·¯q_5Fó_{SD*€«JVϹ’×ë’qŒV BݳÕb´1P¥ZòKzGMí›Â4:úô ˜—£‚0‚0U#0€âO¿Þ@Öÿ3]"V‰Ü÷Îp½0U×@²*,Ýãÿ/äÃûžèÈï_0Uÿð0U 00  `†He00SUL0J0H F D¤B0@1 0 UUS10U Test Certificates10U deltaCRL CA30SU.L0J0H F D¤B0@1 0 UUS10U Test Certificates10U deltaCRL CA30  *†H†÷ (5¹,ä7}³ˆ÷ùVÊ ´N•wý”i¹{×LÙ5ˆàþ1bS‹\ÛŽ[©øÞ ÕDÆŠŽŠ§6ì ú¥s–& G%ú5вßÇ„1åÿN톾Ð0!cå[jÝ °%Ф¹î¶•ïÊ) ÅAè`i­DIŽtS~bouncycastle-1.49.orig/test/data/PKITS/certs/BadnotAfterDateCACert.crt0000644000175000017500000000117610350736724025072 0ustar ebourgebourg0‚z0‚ã 0  *†H†÷ 0@1 0 UUS10U Test Certificates10U Trust Anchor0 010419145720Z 020101120100Z0H1 0 UUS10U Test Certificates10UBad notAfter Date CA0Ÿ0  *†H†÷ 0‰ï-è]` (ƒxtq?TF[Q¾ÌÍÓ™'Šnm.aøHš{»#¦øÂÓDVS«`Á¹¦·vº7?¦™[t«l³’—ÛcD˧¿½ØÅö+l³lšŽk;¨±=¸ ¥Ö”®2ÿQ"£O§RXºu”)>ÿW›R“Ä·Îø~”Ÿ££|0z0U#0€ûlÔ-žÊ'zž °<êš¼‡ÿIê0U- &>a#.7§Êé2©Qàµ20Uÿ0U 00  `†He00Uÿ0ÿ0  *†H†÷ 09mkX†+W3醯tÁi8 "YÌ-C,«ÐD;~!.Õl8?ŒÄJx×£¦pUòdì@Î^>Tå3iÖos¬p~}Ï{\™Hi UŒž6™—Þ“;”ÛðRy»zIóÚo…öå~«7íœPoF6)HÅ­=ëLbouncycastle-1.49.orig/test/data/PKITS/certs/InvalidRevokedEETest3EE.crt0000644000175000017500000000117010350736724025330 0ustar ebourgebourg0‚t0‚Ý 0  *†H†÷ 0;1 0 UUS10U Test Certificates10UGood CA0 010419145720Z 110419145720Z0X1 0 UUS10U Test Certificates1-0+U$Invalid Revoked EE Certificate Test30Ÿ0  *†H†÷ 0‰­Bà56²w »ÚB–žr )›*º7Fæ†1"Á‚˜=ÖRC 9´sv_HM`aB û[ã•‚çÓuô¡Ñ5â±"Ç ZCk^H–ѲÝÞ&˜ïFÓZ´ü¿¦*P±ÜéC¬Mψ7v3dmø“i Åôì#Íþz¼(‰AFä £k0i0U#0€·.¦‚ËÂȼ¨{'D×53ßš”Ç0Uœˆ&¾«Šd ¨ìÑë‘Yβur[0Uÿð0U 00  `†He00  *†H†÷ ±t_F¦áY7\àžŽŒ@b90aôÛa–*Â]%ø•9 Õâ8ç[9Æ4\ÚO#Uð7Qí"âŒciÐòäï!1j"i¥©0¼WŸÝŒºIÖêÑ®Ýu¯ûb?4¡†È‚ŸX )=–íÜGQž2†…øV,G†YéQbouncycastle-1.49.orig/test/data/PKITS/certs/InvalidpathLenConstraintTest9EE.crt0000644000175000017500000000123010350736724027162 0ustar ebourgebourg0‚”0‚ý 0  *†H†÷ 0Q1 0 UUS10U Test Certificates1&0$UpathLenConstraint6 subsubCA000 010419145720Z 110419145720Z0b1 0 UUS10U Test Certificates1705U.Invalid pathLenConstraint EE Certificate Test90Ÿ0  *†H†÷ 0‰±:i9™•ª«J–s3z~c¨¹]!ÍÌæ.í½:È.P‡VßÞ·žHØjàÿÙ»ƒläFñ½ ùž­Å‹›=Òj½J€üjL$9^$ÙÒß¶Òïè`C>Ñ©âs„J‰m¸_Q£…<ßVÃÉcÈAXÛždXýT¸|DIþu£k0i0U#0€jæÅAm­>‚ܰ]­òñPÎ 0UÔ>0„ÎÕwìóÿu§•…0Uÿð0U 00  `†He00  *†H†÷ –oòY¤Ø¾2àªU’Òn„T3Ò°@±íy¯}Ôy¿¡§]‹`˜IOÚeQ~6ó ú_›ÔžƒÏ"X–²0èEßÿVmýÎc['ºèo2#ÇO·üAÅxævµôi¢zúÛ²œ.ç®Hm‚ÿ¨üru›(š@Ï:#Èd”ƒ¾gQ[bouncycastle-1.49.orig/test/data/PKITS/certs/ValiddeltaCRLTest8EE.crt0000644000175000017500000000145210350736724024632 0ustar ebourgebourg0‚&0‚ 0  *†H†÷ 0@1 0 UUS10U Test Certificates10U deltaCRL CA20 010419145720Z 110419145720Z0W1 0 UUS10U Test Certificates1,0*U#Valid deltaCRL EE Certificate Test80Ÿ0  *†H†÷ 0‰ÓWAkÿ³um•¨Ûàh–~µª0݆' ÂóöÕԨĎ8©è}yÏÀÕ{sM³+ªãéÀ¼u¾‹©æØ9Bu’eÞݨ}¹™Qbb"Æyìë,Ø€›kÅth8!õŽO²)€q¸æCÑóËÅøÛo8>­-Ùjs;'C£‚0‚0U#0€£“«Wf&mr:l¼ƒe£šüŽ C 0U¬6H ‘¥zˆcL;›3טÛV·0Uÿð0U 00  `†He00SUL0J0H F D¤B0@1 0 UUS10U Test Certificates10U deltaCRL CA20SU.L0J0H F D¤B0@1 0 UUS10U Test Certificates10U deltaCRL CA20  *†H†÷ (½|#VΖá~FÈl%VCSÛ´ápÀ˜š3·ÿsˆµr­`\ìzOmDk×’­­ûºóÝDœÐ77’VR÷ªTêý(fÕåÓ·ZÑòb‘šƒêµW-£–*9ßÒL½ž€R³5X_G•£\2r†ÔÜVm˜\«ô1H¦ÿ˜[tbouncycastle-1.49.orig/test/data/PKITS/certs/inhibitPolicyMapping0CACert.crt0000644000175000017500000000123010350736724026274 0ustar ebourgebourg0‚”0‚ý 70  *†H†÷ 0@1 0 UUS10U Test Certificates10U Trust Anchor0 010419145720Z 110419145720Z0L1 0 UUS10U Test Certificates1!0UinhibitPolicyMapping0 CA0Ÿ0  *†H†÷ 0‰Ð#<|ìŸ1ô9:åoÞJ:ßp“Û,+g·þ |Ú%Óé<ò}ù™¨^þX)ºüº;=¦Â/€UȲ¨-dU¸äUúÆ6ú}Âóy±x3©…q’©IörË FÂ*ÕNcGÈÃfœÀo6m2ÓE£¢áè]øjù£‘0Ž0U#0€ûlÔ-žÊ'zž °<êš¼‡ÿIê0UléÇ B@AõópŽîáÑR^×7Z0Uÿ0U 00  `†He00Uÿ0ÿ0U$ÿ0€0  *†H†÷ Ñò‰¸Û,~7ã;Åý‰w.nÑfb"DÚj˜’ñ}e¸µ¤@ ›~Ͼúw›\±—v¶Ìôü3“¾{Y…GW湯7Œt‹rT]¿[8ó³h‰³š¢*M)=À•ÔÂÃòÞ[FjTó^ìâèüMí}ù2;';[·—Ìv,•¼bouncycastle-1.49.orig/test/data/PKITS/certs/ValidDNnameConstraintsTest5EE.crt0000644000175000017500000000147510350736724026574 0ustar ebourgebourg0‚90‚¢ 0  *†H†÷ 0J1 0 UUS10U Test Certificates10UnameConstraints DN2 CA0 010419145720Z 110419145720Z0}1 0 UUS10U Test Certificates10U permittedSubtree11604U-Valid DN nameConstraints EE Certificate Test50Ÿ0  *†H†÷ 0‰Ãl«»…ûª.´Š;µ-´;D€(#J[bî ­âa”L=Øì¦×=½jAÚg—í/?ÖI¹¦îVH8qFZ ‘-BR.DÂ_,ͦÎUÖ›¡qÞlR&/XVæÂ¼xÅ–ÞI§!‡-ŠÇ±†¶Ð²zì÷|·£¯£û0ø0U#0€¡|ÄÒ{ &ŽQö ¬ÛvñÑb­0UÄCÝÖ1çà௄Ÿ½ªä²c®—0Uÿð0U 00  `†He00ŒU„0¤0}1 0 UUS10U Test Certificates10U permittedSubtree21604U-Valid DN nameConstraints EE Certificate Test50  *†H†÷ ŸVæ*v²>[‚‹—}+!{ós¢&”'Ñ&6È×uÝË ±üå£JìŒ|‘>? å¹É¦àîâ[]¶t?~îç§#špÁ¸º”º¤%Ìwé?l%è˜HÝu±*5|wž(Éà•ÝËŸô6Z¥ÎÊ.§h¡ªoM›Ê¬Ybouncycastle-1.49.orig/test/data/PKITS/certs/nameConstraintsDN1subCA1Cert.crt0000644000175000017500000000144310350736724026346 0ustar ebourgebourg0‚0‚ˆ 0  *†H†÷ 0J1 0 UUS10U Test Certificates10UnameConstraints DN1 CA0 010419145720Z 110419145720Z0j1 0 UUS10U Test Certificates10U permittedSubtree11#0!UnameConstraints DN1 subCA10Ÿ0  *†H†÷ 0‰¶QiÞÄ  ÂоëD(œêМRwTîåþªˆˆßHJ…ËÕ§€3—6*lËæ·VÝel5ØÚ棚‘ã|i’q Z SûÈÖÈÛÓÈ”Ý!ð}¨àޝï0µä§c-ª@ä4µú}µD5®ßxw1ñËÆímU6-)TTÿÛÐ0……íÒ70t†Æ|`°U}pÜ¡y“YØ¿ÄQ0\ÙLøBª¨·5h^{ñô‘1ëÈØÐh—B©rbouncycastle-1.49.orig/test/data/PKITS/certs/InvalidUnknownCRLEntryExtensionTest8EE.crt0000644000175000017500000000124310350736724030444 0ustar ebourgebourg0‚Ÿ0‚ 0  *†H†÷ 0R1 0 UUS10U Test Certificates1'0%UUnknown CRL Entry Extension CA0 010419145720Z 110419145720Z0l1 0 UUS10U Test Certificates1A0?U8Invalid Unknown CRL Entry Extension EE Certificate Test80Ÿ0  *†H†÷ 0‰ò'÷—¸ ƒêõËé(ÍK…ÔOÕðUY¡:pbº“m†Ùš}ä W2ÍLm¦§†º€æ‹¦³hÒø¼ HÌ$?@ʪÑÝï3ô&3õ™àºá¸Æ„…¨¶j Õvõ£k0i0U#0€õ[ëÚÊå愈ŸÙl¿[ΓiM€0U({ŸÍ¹äFñÒ TØ7s¼û`^OV0Uÿð0U 00  `†He00  *†H†÷ 8ò€Íp\i½ãÄ@NÖ·°!CzäFYf=EÎs$O­TåÍ áHû‚$ô ;ž=äñÿ¾ÀYQYm2¸N¦4‰¼è· Á¬cäi›ò³Uý£ð$Wñú˲XiÃä(ÿmÓ¥"ÐQÝÑZºükÀ¼õ E%¶—ý · ?|N}£¥0¢0U#0€ûlÔ-žÊ'zž °<êš¼‡ÿIê0Uê·nš+ €6giµÚ5¥†=)x0Uÿ0U 00  `†He00Uÿ0ÿ0&Uÿ0¡0testcertificates.gov0  *†H†÷ s vGHx™zïRaCJúrcʼn¡µÒKù ŎZ!?ö¹¼{B‰êÇ+Ï´hŸËùÉÍ@p§†$ÏU7²# ÓÅ]’(…yµ–òw…üà‡>M­]›ØJMêbYXß-*2‡Šw«‹éÉ:.ÃŽL=(ƒ1=)¸ÃÜ9bouncycastle-1.49.orig/test/data/PKITS/certs/InvaliddistributionPointTest3EE.crt0000644000175000017500000000143110350736725027251 0ustar ebourgebourg0‚0‚~ 0  *†H†÷ 0I1 0 UUS10U Test Certificates10U distributionPoint1 CA0 010419145720Z 110419145720Z0b1 0 UUS10U Test Certificates1705U.Invalid distributionPoint EE Certificate Test30Ÿ0  *†H†÷ 0‰¹.K½èúéxÅK€x3D¿Lx¼u*r‡O4;çB< ÿ¸v Õ•hàªiòäN${u¹Üô”q2Êc(YËÃd#Ñ£Ö¬­#>ýlX)á×֙ΕÛ°m(Ûýa·,‰è›}]ç4ÜXj´Å¤E›ÆßqÞr(ó!A£ó0ð0U#0€žPWj…oøæA^ëzº0~ºô0UÅá´ŠÖƒ†"2/ݘŽb60Uÿð0U 00  `†He00„U}0{0y w u¤s0q1 0 UUS10U Test Certificates10U distributionPoint1 CA1&0$UCRLx of distributionPoint1 CA0  *†H†÷ çcå|FA°úJHa´ÃR_þÓ’NDµ‰]y6Õ¨zW³ª(–å°†Hâ‰k®iàb‹­ÿ®6õ¹ã“E·E¤šã²Ró¶|]'V^๓-§ß)è¦UàHÍ® ©3·r÷‚éÎÍɵ³pæ6Àœ@[îᬠ9÷ĉÆtäbouncycastle-1.49.orig/test/data/PKITS/certs/P1Mapping1to234CACert.crt0000644000175000017500000000135210350736725024551 0ustar ebourgebourg0‚æ0‚O 20  *†H†÷ 0@1 0 UUS10U Test Certificates10U Trust Anchor0 010419145720Z 110419145720Z0H1 0 UUS10U Test Certificates10UP1 Mapping 1to234 CA0Ÿ0  *†H†÷ 0‰¹i )'ôgÄoû…÷íCûHœ$Víé óÄÜUœ,_íæ²øâ»&µr7@oB:Eî– @Òp6ûÈééSÙJò­X3=¿Ý]æÒË—¼iðÔ³Ä*D]¿æÐBúÝ› h“g`žÉ¾ ÚSh¦à)h¿Ž9kð~A£ç0ä0U#0€ûlÔ-žÊ'zž °<êš¼‡ÿIê0U̧ÑÒ†ï!c˜ïÍÊÿàD³Ô0Uÿ0U 00  `†He00ZU!ÿP0N0 `†He0 `†He00 `†He0 `†He00 `†He0 `†He00Uÿ0ÿ0 U$0€0  *†H†÷ ^Í=¯€Ç»™Ñôfìe‘®OÙe¹S£F%6…óÇ´wbÍwJʆ9âERꥑI¾&ÝðõìA‡‰·\Ohþ„+˜cý¤Ô ¡òªÈ°ê¹WR“”°%YÆü;‹GC·TcȪD7…Ü/y5…ɼ5° ÖÁ:¼´bouncycastle-1.49.orig/test/data/PKITS/certs/ValidNoissuingDistributionPointTest10EE.crt0000644000175000017500000000143110350736725030637 0ustar ebourgebourg0‚0‚~ 0  *†H†÷ 0R1 0 UUS10U Test Certificates1'0%U No issuingDistributionPoint CA0 010419145720Z 110419145720Z0k1 0 UUS10U Test Certificates1@0>U7Valid No issuingDistributionPoint EE Certificate Test100Ÿ0  *†H†÷ 0‰¹ƒã¤3§é+ŒM8ôl–/öS”ó/3%59·£ZéJî1¥V6-â­U_¿&£Æ€Ù-4ªÇ´vE"LiT8ÔìÈÝ¡Ãæ´t3ù-`ØS¢ÜËKE%§Âæô};#³ÒežŒR1 æØ‡gG?”&>ÁM޵¹XîLì83éy£á0Þ0U#0€,Å'#ÑÑAßßa„¹Oñ2ì10U¦ÿZYàbU¨ÑàYJ¿…ž´ù†h0Uÿð0U 00  `†He00sUl0j0h f d¤b0`1 0 UUS10U Test Certificates1'0%U No issuingDistributionPoint CA1 0 UCRL0  *†H†÷ 'ÊŸ;k§k‘¾þ ŒBêEîò#ßë?¦å]#Œüúî©î]‰¢ÄcM=¢‡–ˆyt„.CXÑy¹Ñ,ƀƫi Í<¶¬Æ´­ðŒe[D¤UƒKO‚]1.í’Gà/5o•OºÐI¦H7NÀÓx©„•°úbouncycastle-1.49.orig/test/data/PKITS/certs/ValidbasicConstraintsNotCriticalTest4EE.crt0000644000175000017500000000124510350736724030641 0ustar ebourgebourg0‚¡0‚  0  *†H†÷ 0T1 0 UUS10U Test Certificates1)0'U basicConstraints Not Critical CA0 010419145720Z 110419145720Z0l1 0 UUS10U Test Certificates1A0?U8Valid basicConstraints Not Critical EE Certificate Test40Ÿ0  *†H†÷ 0‰ÎÜ3‚£ .²»t¦¢N í¸BA ¡Ëo…”ì^I¶YᇹÔy7)h¹K »ÂZ\ªøHYy”¬þÇJݾÁÈß|\Μ_\%2bf?†Þ|ZHQJêýŸuÔJÜTçµÆ…Ø#\zä½í;î¤@ ©+å/úY¦âòchÅáÇ£k0i0U#0€ظß+ü ®×VË\>zŒÏ‘0Uý4N»ð8#ÿê˜+)ˆ¥¥ª:©"@Ûȱ¥®y°ÜE…;qÜhŒ%*X½˜Ç Ö^)›ßç.?Á€dY;ç¥>¹%AšábsIøsXÄ=9dùt[ —ؘG‹$i«Ø8¶[¡]ðüzebouncycastle-1.49.orig/test/data/PKITS/certs/InvalidpathLenConstraintTest5EE.crt0000644000175000017500000000122310350736725027161 0ustar ebourgebourg0‚0‚ø 0  *†H†÷ 0L1 0 UUS10U Test Certificates1!0UpathLenConstraint0 subCA0 010419145720Z 110419145720Z0b1 0 UUS10U Test Certificates1705U.Invalid pathLenConstraint EE Certificate Test50Ÿ0  *†H†÷ 0‰±•žo<ž¤—ßиÀî7~÷UžeSòa ¯³ ÁK×ý/ÓE«SK¿¢«D&•kœÞ uD0ó”2]‰jº1 ‡m¡ì%³ýº·ÿ™è/‘nOü¹sm9¾2“•b6¿»¼`‚àAñoÛÛD¬Üœ¥?ÿ^¦¯ß£k0i0U#0€Ž«FœKnçåWˆ '“þ'Öç0U;ì‰[_R„_ô ƒÝ¢ ?ÊG0Uÿð0U 00  `†He00  *†H†÷ zäÀlû˜D„c ×Ì ™ ¡¯,„»š4:V߉–ð€äš4„’y¿þÖìU0vúÌÚÚ¸(kψS Ìšáñâ%‡FÌÿÕÓ¦”`ýc+çÕ2ñ¯¾øºm78RLãî}¦hÙ6ˆ*K7†Q±ýÖhÄêùö’bouncycastle-1.49.orig/test/data/PKITS/certs/nameConstraintsURI2CACert.crt0000644000175000017500000000125610350736724025714 0ustar ebourgebourg0‚ª0‚ I0  *†H†÷ 0@1 0 UUS10U Test Certificates10U Trust Anchor0 010419145720Z 110419145720Z0K1 0 UUS10U Test Certificates1 0UnameConstraints URI2 CA0Ÿ0  *†H†÷ 0‰ЮþÕR\“Qs8mM¥C± ½ Æ3.=M)Ç”ŒUŸT6öÒð¡œ,O ¥¢UijvªôzùKÅÒÏźÄ{•ŽKàW˜éÀôºƒíE½ÿœ0ú]$"½â´(M#f›8߇¢úŽt)¬‘ÉÑðÓ— ¥¶«%£y0w0U#0€ûlÔ-žÊ'zž °<êš¼‡ÿIê0Uß ¹4‰uxÒ#’ð!ßÂve´0 U0U 00  `†He00Uÿ0ÿ0  *†H†÷ VŽòf÷â3·³³Œ$º4)áP¾g—G¸2ó?¯þÒŽݤ ˆþüïüß8cÉbÓ-òª%9&ûÇìù2Å®ùVͬÝÓÄ-rK¼\ @V‰$)WŽ­„>Í/;áÛ´Ýbõ'%ï-°1Û‹Ú û_…óÿ'kè÷%¼†š­././@LongLink0000000000000000000000000000015200000000000011563 Lustar rootrootbouncycastle-1.49.orig/test/data/PKITS/certs/SeparateCertificateandCRLKeysCA2CertificateSigningCACert.crtbouncycastle-1.49.orig/test/data/PKITS/certs/SeparateCertificateandCRLKeysCA2CertificateSigningCACer0000644000175000017500000000121710350736724032663 0ustar ebourgebourg0‚‹0‚ô g0  *†H†÷ 0@1 0 UUS10U Test Certificates10U Trust Anchor0 010419145720Z 110419145720Z0Y1 0 UUS10U Test Certificates1.0,U%Separate Certificate and CRL Keys CA20Ÿ0  *†H†÷ 0‰ܦ ŒÐ9îX`‘?¯.q®Sšr2ç3ìâKØž-Bˆ %Z!÷âšP°&Û¥À¯QEÎ^âZ|Ðt¸ ¢Œ“9TrB&áK 6ëaÑÍ+Í.OËw7ÙØéƒâŠú:BQÇt‰'ö|°BåÌê-ò6õ.jM[èý ©’R¯£|0z0U#0€ûlÔ-žÊ'zž °<êš¼‡ÿIê0U¸˜|Éx4´$¾˜ýå£ÎÞZ¾0Uÿ0U 00  `†He00Uÿ0ÿ0  *†H†÷ ­ÃÍ @Ê( ®q»Ñã:Gqï®ç’ÎÓËñËí'£p+Ô”;@í@÷à‹z#†Òµ|éïú#A~öù)Œ7ÿ¬âÍßÎ(•V2÷$Û(®w¾´êæòcšJئÏî9Ùo¦æ½`æàì*V‰Hz•‹k7Õ!"äü=ĸbouncycastle-1.49.orig/test/data/PKITS/certs/pathLenConstraint0CACert.crt0000644000175000017500000000120210350736724025611 0ustar ebourgebourg0‚~0‚ç 0  *†H†÷ 0@1 0 UUS10U Test Certificates10U Trust Anchor0 010419145720Z 110419145720Z0I1 0 UUS10U Test Certificates10UpathLenConstraint0 CA0Ÿ0  *†H†÷ 0‰Â]uÏlÙä1MðÆ8ð Ð?>?¥Â@äñd±(gN­ÃÌœYë Õ'J¡Krºý>ÉE ¯éwFÞ°,k@xP, „Ž?"TsèŸ7(””>9ÚªéÌI¢LS¿SÇeMí³uDžÅ­j/ïð°ì·Îþ5S¢~çôá£0}0U#0€ûlÔ-žÊ'zž °<êš¼‡ÿIê0U! µvvÓ³*¬&üª¦OòÖ¡oK0Uÿ0U 00  `†He00Uÿ0ÿ0  *†H†÷ •ó|ëJ<_hlu0­"5™7³µ"…ÄŒëYäñp´$p1·Z Ô| ÄÈÚÞ¼aÎÁPilÝ‹x±¾q«5¸Ëd~Ä=`OI ¶­0¼¼Õ³`.>Àd¿² ÆÇL–m-µÃ8†­Y?¶àëŠÁ<ÄéÆÜIîók>jvˆòÐöt±Âbouncycastle-1.49.orig/test/data/PKITS/certs/inhibitAnyPolicy1subsubCA2Cert.crt0000644000175000017500000000121310350736724026740 0ustar ebourgebourg0‚‡0‚ð 0  *†H†÷ 0L1 0 UUS10U Test Certificates1!0UinhibitAnyPolicy1 subCA20 010419145720Z 110419145720Z0O1 0 UUS10U Test Certificates1$0"UinhibitAnyPolicy1 subsubCA20Ÿ0  *†H†÷ 0‰’ZŽþÙßZTBÔlLL0\ê3MýÃ-ë`nÚ‡Ñæÿ¯™/sqTãZ·eÕDß6ôY#¤^ižü•ê½ma9‹=‚†¦]¹2.*£QMŒ¢Î¦Ÿ¨cƒì4dœä#s{dwŠ{ÈÙ+yÀàng¿Oʲ8›¯P(Žîã£v0t0U#0€«ÈA&ÐÕLæ+Vgìï‚ÄÂÝòU0U"ÉÕ1ÝÂvçÃÜ’üÀ…“ªæÍÎ0Uÿ0U  00U 0Uÿ0ÿ0  *†H†÷ 7ûظ)®¤Þ¦l¶u'¾êÖPlâþ`7Ó{'Zí›ü3§déö0™¦7cˆjí¾ìMÔ%I¯½€_{g-ì"é&Û,‰ëmÓ/kä—Š4ƒüì!—+”ò§¿ì–ð.’o]HH«Í¿¼ñ¾$]ÊìºáŽu¢èàò‰%‰°™³oS‚bouncycastle-1.49.orig/test/data/PKITS/certs/InvalidRFC822nameConstraintsTest26EE.crt0000644000175000017500000000130710350736724027545 0ustar ebourgebourg0‚Ã0‚, 0  *†H†÷ 0N1 0 UUS10U Test Certificates1#0!UnameConstraints RFC822 CA30 010419145720Z 110419145720Z0h1 0 UUS10U Test Certificates1=0;U4Invalid RFC822 nameConstraints EE Certificate Test260Ÿ0  *†H†÷ 0‰»ŒÛ]̘0Š”É9Çî١׿ÿâæ ÅsKÂì$ÅBbž`)>GÖU褶mêÑÊþ"àÑTÀ”Šœ%ÖtT‚x~ås–Àß7îUßý :x(iÎS‡D¾n#M 6„É# ‘ž#ÍB?·¤r"B±Z¥[#&³3œK£–0“0U#0€ê·nš+ €6giµÚ5¥†=)x0U”¼èêì°ëAh8ÉÈ™šæFg*0Uÿð0U 00  `†He00(U!0Test26EE@testcertificates.gov0  *†H†÷ ÃM '=§†ßëŠz³\qÝ—)‰Ü4„ÎPÞ+=’©w<(¦B1çGÆÓÔûô°ã¿ šÕ&"Z̲Ÿ|MÌ×¥Y“!È2Q–:A¾EÐJ}y‹/Hb ³®›XÔïN'2,§%ø[޳~¸yëeIkÌ4ŠZbouncycastle-1.49.orig/test/data/PKITS/certs/requireExplicitPolicy5subsubCACert.crt0000644000175000017500000000123110350736724027742 0ustar ebourgebourg0‚•0‚þ 0  *†H†÷ 0P1 0 UUS10U Test Certificates1%0#UrequireExplicitPolicy5 subCA0 010419145720Z 110419145720Z0S1 0 UUS10U Test Certificates1(0&UrequireExplicitPolicy5 subsubCA0Ÿ0  *†H†÷ 0‰Ð Î’:U¾`¬ú¢J¼Ü:³_=žim°¸Ž;<÷:5Eœ0´·œíN(N ÙeïŠ@4¢jU«†î§®ý´Èr™·z0… :OÕ&@•g+ýµÒó•j"[g¥#K‰àì[ÊâÄñ—BR[/Ô äÞ]6,þ/¹á?SÁé£|0z0U#0€•†‹‘6»zoâ„ïEŽ'k¸0U çb¨O/·¸?'È£©_{Fk§0Uÿ0U 00  `†He00Uÿ0ÿ0  *†H†÷ ™¸'Ï®·Uþ3nÌ_Y+ì{ô9©L0/×`œÔ½’|E4ʼnK ðt†l©IòhJÊÒbKLt ª çVP}áß‹UºG6ƒoÅ ~Ò£L¸~€î$ŠÐæöž’Ý r‹¦½ÖS¼ÜÚ¬Êâ{2t6è[½ÿJ¸ qÏN½ïbouncycastle-1.49.orig/test/data/PKITS/certs/Invalidpre2000UTCEEnotAfterDateTest7EE.crt0000644000175000017500000000121710350736724027704 0ustar ebourgebourg0‚‹0‚ô 0  *†H†÷ 0;1 0 UUS10U Test Certificates10UGood CA0 19970101120100Z 990101120100Z0m1 0 UUS10U Test Certificates1B0@U9Invalid pre2000 UTC EE notAfter Date EE Certificate Test70Ÿ0  *†H†÷ 0‰»vXSšs¯7ÃÑ?‹Þ«!m¯CŽEÔ¾¢rÄcÿ‡; ÑÚëˆb‚{+bS(MǺ †µ9 @ë«a>ÜSPRÅîú†9£|0z0U#0€Ë »Š£‘ç2DýPP`5 jE&0Uç«Î(åhéji>)¥6cp¡š0Uÿ0U 00  `†He00Uÿ0ÿ0  *†H†÷ G® r]ÂFtrrÕÀ¿¯™ª“ƒ‹=¥½8>áÛÓ q^~”€K •:bêã­³cª<"éÿ 8%Q±×¾Dp…$rW@ƒ_~Þ]MW‡àì{Á¡Ö‰WÈÍ-£0}0U#0€´¤·¢®¹vµËd¥z…J0UD4áP&ÿ<# ­¿½NÆ{à HŠª0Uÿ0U 00  `†He00Uÿ0ÿ0  *†H†÷ Š.«dIW„â¬ìÙóI>ÂEÌ*Ï TÀ}’çsÜü¹pލÉ/"Ò¹=Æ6*_ ´…H}׎‘#HE%Ýu aôù‡vÅ'CWïÓW^Œ±±öODKàžÿ“?¢}UÊ—À¸ øü΋ޞã2%FqtADw”bouncycastle-1.49.orig/test/data/PKITS/certs/InvalidIDPwithindirectCRLTest26EE.crt0000644000175000017500000000134710350736724027205 0ustar ebourgebourg0‚ã0‚L 0  *†H†÷ 0C1 0 UUS10U Test Certificates10UindirectCRL CA20 010419145720Z 110419145720Z0f1 0 UUS10U Test Certificates1;09U2Invalid IDP with indirectCRL EE Certificate Test260Ÿ0  *†H†÷ 0‰•†Ñ@¼¿±5Ø"!mµ§Kiw\‘–-ÑnZõÊ MŒ§:ünÇË#ó© WB¾„¸ÿlBڕémMJ7ãXÄ•#Upuœ/Ïïm_]^¡ùgoC˜´Ú¹ˆbF¢±Þ‰v¥6çlNÓ«iRxVl'Úc_]Ù±/£Ã0À0U#0€Á¯‚ÕÓOð1bÙ*ÁàNv\Û·Ëjè‘3„s Ÿ²Ý•GÆí5ѱׂ„ço•7‰eòïè<»>®Ÿ…§…Þös#ÒÇÎ7ÌLLÝU¶•hC5&žS$Q'|À0=ÞÇWmAŠâŽ2¥œ¦Gbouncycastle-1.49.orig/test/data/PKITS/certs/InvalidDNnameConstraintsTest3EE.crt0000644000175000017500000000150110350736725027110 0ustar ebourgebourg0‚=0‚¦ 0  *†H†÷ 0J1 0 UUS10U Test Certificates10UnameConstraints DN1 CA0 010419145720Z 110419145720Z01 0 UUS10U Test Certificates10U permittedSubtree11806U/Invalid DN nameConstraints EE Certificate Test30Ÿ0  *†H†÷ 0‰ÉEUGYè‹wÞÔ6O±ò9$²2BŒlAˆ‚Fõo¹ ¬®–€ã•SÏ<ø¤î?- œf OëTl3Û¼”òÄu©SÇÄop…õøíaw1DŽö²Š¡(® ·C®ˆ7:Ê c¾7½àÀýþÙö¡q—‰•ßÛnT<“€ƒþØ!£ý0ú0U#0€N.£çÙÝ‹§‚;AJÞ|Y#WNS0U\ÖiØ]ƒJX’DÄ@ÿæ>^DN0Uÿð0U 00  `†He00ŽU†0ƒ¤€0~1 0 UUS10U Test Certificates10U excludedSubtree11806U/Invalid DN nameConstraints EE Certificate Test30  *†H†÷ F-lB{R¸†09_³,n9D·¯å×Ây-B—é'oΈÕen°JwâŠxÄIR K¿§¾™OSPùË AÌ£vq»¿ ¿kð'zMB8É}žö¯âœ®W¾ ÙŠÞ}ªÇ1ŸéÛ‘‚ˆÜõ¢)éM!ãàˆ"-rߟMÁelbouncycastle-1.49.orig/test/data/PKITS/certs/ValidURInameConstraintsTest36EE.crt0000644000175000017500000000132610350736724027011 0ustar ebourgebourg0‚Ò0‚; 0  *†H†÷ 0K1 0 UUS10U Test Certificates1 0UnameConstraints URI2 CA0 010419145720Z 110419145720Z0c1 0 UUS10U Test Certificates1806U/Valid URI nameConstraints EE Certificate Test360Ÿ0  *†H†÷ 0‰¼NÆ*/\«bèG‰Ã+jê˜B2Âw›¡XÅ„bu½ ±8ä릫›$Dh¡Y[µäº$Žæ¾Ýªí{)ü1»ƒéE)Á?…KÎ>HV€ä£` ›)¡>þR YDBðO“+ÛÏG•PÉ4'só=>GÂæ»ÕY·-`¯Ç'úúòy†£­0ª0U#0€†¤UcñŒ #§§¼ËlªmÐZÆZ0UÙ~˜è*n—Q4ÄñXmZy0Uÿð0U 00  `†He00?U806†4http://testserver.invalidcertificates.gov/index.html0  *†H†÷ mÞÖNÄaØXG÷€ÄÙ•z¶9¢…Š­‘?2H¤Õ>]h Káä}ÛÉV-aæåoK%[Äu_WªY3ÕÚ–pZÙHÃuƒÿzŠH¥X¿€nË8äÛM@Þ¾b0q@/—ßЉŠ^ÄœžBÖ']à‡›ð‘ø†r…—?q”bouncycastle-1.49.orig/test/data/PKITS/certs/OldCRLnextUpdateCACert.crt0000644000175000017500000000117710350736724025225 0ustar ebourgebourg0‚{0‚ä 0  *†H†÷ 0@1 0 UUS10U Test Certificates10U Trust Anchor0 010419145720Z 110419145720Z0I1 0 UUS10U Test Certificates10UOld CRL nextUpdate CA0Ÿ0  *†H†÷ 0‰·™kïa.@°SGÜöñq!mQ÷O5¥;ŒºÀƒG7¦)“Ó¤§î,¦D57Hm™HFAr‡0q:ÛâùAà¬ò–°}}áÆ$£Ž¸5 ™4¾ÎÏó8(óO{£¤Cù¯°Í˜çƒÉÊA÷'ª.¸{}$ñÑI«ÂBBÐKy³£|0z0U#0€ûlÔ-žÊ'zž °<êš¼‡ÿIê0UÀjóÿ#ŽÐGDPCQÂ|^1‰Ì0Uÿ0U 00  `†He00Uÿ0ÿ0  *†H†÷ 3’‚ñ…N¸&ßvÓ9è<‰f[Õ¶¨>ãˆ`‘Ê/DÇzT×PD_ítð¡¶T_ôbŒe1ÈcÎê,9 *Í-ÀÄh&iÛ¾ ¨n´¢Ìt¬SÜU(©xûø áEÜ ©÷(ïa¥¸R »ŽïÖ¸„"cfÒÙ#ìbouncycastle-1.49.orig/test/data/PKITS/certs/ValidURInameConstraintsTest34EE.crt0000644000175000017500000000132310350736724027004 0ustar ebourgebourg0‚Ï0‚8 0  *†H†÷ 0K1 0 UUS10U Test Certificates1 0UnameConstraints URI1 CA0 010419145720Z 110419145720Z0c1 0 UUS10U Test Certificates1806U/Valid URI nameConstraints EE Certificate Test340Ÿ0  *†H†÷ 0‰èQ¥§¥ãÎLî¢$Ž–‰[øž8…\—”'ø"hÚ»¡´BÊ‚ë©?åÊ´ N'Û§oZYä¶ÑNžóGaí¡ ¥Æxq´‡uûpIëžà1ÿ#z˰µ¼«¬á1:•ˆA\–mL^e\ç¡0æhïnøŒvý8”~hMДx„uÊû£ª0§0U#0€¬ºK _â¼a®áÙdZy¾EÖ0Uœm(û1=¿&±>”·' m*0Uÿð0U 00  `†He00<U503†1http://testserver.testcertificates.gov/index.html0  *†H†÷ '‹rѼ>ÛAWŽÂ(¯¢>9 Õ^®YÅnÂÙ’‚ÕLÀkœ¡¢þ|>ìO°&Ík² žL¥YTÌâÄ]Rk¤XŽj:Ö.}®«9\”ÛÄýµÐ‡¦¡Ðxÿ³ ®õµÑŸ¬à=Çþ÷$°Ÿ°5‹Þ³övÌ\dLÊRùl6j ô3bouncycastle-1.49.orig/test/data/PKITS/certs/InvalidMappingToanyPolicyTest8EE.crt0000644000175000017500000000121710350736724027314 0ustar ebourgebourg0‚‹0‚ô 0  *†H†÷ 0K1 0 UUS10U Test Certificates1 0UMapping To anyPolicy CA0 010419145720Z 110419145720Z0e1 0 UUS10U Test Certificates1:08U1Invalid Mapping To anyPolicy EE Certificate Test80Ÿ0  *†H†÷ 0‰µn_àN¥[‹¬•´œg_qW¤MÀ±>g0 ÎǤÖΖò½Œ`¡wÍ þÛŽÖ›³ò ÷ä†Õ„)¨íýAH˜ÂØ7ÑÂÝž0IáÓÛ6ŒÓÙª½u¹ø†ýô=ƒ4¨å< [ož5iÍ9èÉþdCÀÇÃ÷A+}J¨q£e0c0U#0€º€Ìz,§cZ«N?„ÄSU iú0U›á µwþ Cæ–àðkV“{0Uÿð0U  00U 0  *†H†÷ ݤHp½a•;µ¥%EZÝá$ƒ¾ù$Ê,ȃÔ<Í´ÿÁS¿ú{÷×jÔ–¼Ú–gß^¨ïóèóžJÕÌÑ]àp¾Î MC¬[I'hªB‘Eͦê}ðóŸˆ J¼¸1~sDeð#q˜‰}Nsn¶>‡B_S¯x¨–Cî~bouncycastle-1.49.orig/test/data/PKITS/certs/TwoCRLsCACert.crt0000644000175000017500000000116510350736724023376 0ustar ebourgebourg0‚q0‚Ú  0  *†H†÷ 0@1 0 UUS10U Test Certificates10U Trust Anchor0 010419145720Z 110419145720Z0?1 0 UUS10U Test Certificates10U Two CRLs CA0Ÿ0  *†H†÷ 0‰ÑutʸºVfmKÜ©A3Ü"k‡®îÀ«Ës¶Ó<Ö ÛG¡µ[Õ.ª¢¿ÇO"¯söœNwjÖ³ôw¬DÂF·®R2…­}$ ãÏ–êìÓØlûò Qé™ &‰6ÀCM‡L]±XU–iÕ§Úê"=¶]ÒÛÔ§Ž1£|0z0U#0€ûlÔ-žÊ'zž °<êš¼‡ÿIê0U0ÈéJÞC&A#ŒSSŒ³GŽÊ0Uÿ0U 00  `†He00Uÿ0ÿ0  *†H†÷ [ÂN6737…vÆ›ˆ³N¸5™ý‘*ÂãÃyÚmµÊïî|ì˜WÌc7ýˆ5HüdVQ.˜Ñ»ážSE#(ƒ4=ð¤¢H”õà ñq#Úh‡æ¬V9à+ÒÛÉ]}_ÂòÁØA3€÷›qSåÒ‡Ýõt—NÖú°3\eÝ2²Çšbouncycastle-1.49.orig/test/data/PKITS/certs/ValidIDPwithindirectCRLTest24EE.crt0000644000175000017500000000134410350736725026652 0ustar ebourgebourg0‚à0‚I 0  *†H†÷ 0C1 0 UUS10U Test Certificates10UindirectCRL CA20 010419145720Z 110419145720Z0d1 0 UUS10U Test Certificates1907U0Valid IDP with indirectCRL EE Certificate Test240Ÿ0  *†H†÷ 0‰ß>6¦:£'’6¤Ez²fäžDzXÐ!€Ú-ò£1¬¾êûƒ1~ñÙ˜{ø”\‚ÝëzÖ^%e‹j¹Õ£}­Ñ)üßü ˯$—ÃÚôÍ‘665Ò(5vÖ1¦«Î£ÿ ‚/¯2…êDã†Ù鸀 -ôOÛã)ìÚoe ãÂ0¿0U#0€Á¯‚ÕÓOð1bÜ;ÜíÌ ÚßG@úþd¹Î†bouncycastle-1.49.orig/test/data/PKITS/certs/InvalidSelfIssuedinhibitAnyPolicyTest10EE.crt0000644000175000017500000000121010350736725031036 0ustar ebourgebourg0‚„0‚í 0  *†H†÷ 0L1 0 UUS10U Test Certificates1!0UinhibitAnyPolicy1 subCA20 010419145720Z 110419145720Z0L1 0 UUS10U Test Certificates1!0UinhibitAnyPolicy1 subCA20Ÿ0  *†H†÷ 0‰ÿ®èŽ6͉öXV­–]kAÇoª–ŒñƒýKÑ:ë ˆ$à«ëKž†bùÿñ9” S3Y!úðiv>~"{Éyó…ÙOwB”þØóëø·Ž§éJæ>j]÷y<à­<ã—1,N䤤X³(Wx$F À¦‰ùœûP ×i#ëV,íq—âS!Æ I£k0i0U#0€ß=Hûã2ç¹&R‹Úìø O³Çߦ0Uɺy)þf8C4z³®^×R/†0Uÿð0U 00  `†He00  *†H†÷ CD—‚<š /I9ç§³/ TôÕ®¶m¢2ØE1„Ê oB™Šl1¥ëÏm#!9"N羜¤+ΠäV~óÍ¥h2£Mæy¯Ô«‰ aœ±ê&I½å+Ù†Áùf²ät’Ҭ組b5zÄ€:ô·ð‹Ñ´Í†eïbÉñÃbbouncycastle-1.49.orig/test/data/PKITS/certs/ValidNameChainingWhitespaceTest3EE.crt0000644000175000017500000000121410350736725027526 0ustar ebourgebourg0‚ˆ0‚ñ  0  *†H†÷ 0@1 0 UUS10U Test Certificates10U Good CA0 010419145720Z 110419145720Z0g1 0 UUS10U Test Certificates1<0:U3Valid Name Chaining Whitespace EE Certificate Test30Ÿ0  *†H†÷ 0‰§©:ºæR5ëJû„Ò¿‚£æ„ÀïØi U£Sè¿™rºiEð C4€\Ï9™4œ“Pm+ŽÌö7ÀZ=畈íAöãðqN¡Bpúøw9óèDü;ÞùJ€'²„,š"7×B™‡^yù“g=©×üÙÃÈ,å£k0i0U#0€·.¦‚ËÂȼ¨{'D×53ßš”Ç0UíØ"ZÒlÀM¢Ã!;d ‰PRda0Uÿð0U 00  `†He00  *†H†÷ Xþ ônÕj ÀâsH)„‘+QT-.Uáq)ná×k861.”ZñŸÖJÁ&Ä—«ô& âe±nû3|cNæÿê]ƒÁ?©Ÿ,˜>uÃ|Þ9ÜÍ'c´uî¡SOB:¾ÿesoÝPAç]`Ù»“ѸõáBJ® sB&@lÄqå¿,bouncycastle-1.49.orig/test/data/PKITS/certs/InvalidcRLIssuerTest35EE.crt0000644000175000017500000000151710350736724025464 0ustar ebourgebourg0‚K0‚´  0  *†H†÷ 0C1 0 UUS10U Test Certificates10U indirectCRL CA50 010419145720Z 110419145720Z0[1 0 UUS10U Test Certificates100.U'Invalid cRLIssuer EE Certificate Test350Ÿ0  *†H†÷ 0‰ÜiÝ»1ªMÅ’šò|¬Æß°'íÁcûªºÇR´Ó3ŒónséâoQƒ.DF‹vYÈx0`bH¤Ño¥­a¹ÐÕ€ûÍ€¤ŸéT®å»£‚50‚10U#0€”­Ñá~û7KA=mY€?DWm0Uq…ǨRÅпwv€²T¸ôÚŒ0Uÿð0U 00  `†He00ÅU½0º0· l j¤h0f1 0 UUS10U Test Certificates10U indirectCRL CA51!0UCRL1 for indirectCRL CA5¢G¤E0C1 0 UUS10U Test Certificates10UindirectCRL CA60  *†H†÷ Ú”WêíOšÝösÔôŽY¶Kð@aLÌ9¶ß‹ÏÂ`Ÿ‚~×-ûç@Á ú†ÙLØÝé ×ÏGa 2MGXžKÞBŠNʬµ¸3êÊpÀúa–ÄÈZ»—º ]Ò>aұܵvÑTBË­â…øŽƒ œbouncycastle-1.49.orig/test/data/PKITS/certs/nameConstraintsURI1CACert.crt0000644000175000017500000000125410350736724025711 0ustar ebourgebourg0‚¨0‚ H0  *†H†÷ 0@1 0 UUS10U Test Certificates10U Trust Anchor0 010419145720Z 110419145720Z0K1 0 UUS10U Test Certificates1 0UnameConstraints URI1 CA0Ÿ0  *†H†÷ 0‰¬Kö „ÙfÊ SäoŠç±#ž t¡\\‹°Ñi6d1 Ð„σP|°ÀŠ=ÍJKUá¢Ån×í[C„³Tú“»ÜÆq<åûÅÌÃNä}¿ÚŒj±·ÿ4šoq:”ªÿ5‘ü ì½#ùhÜËéós=¾&H“N|d`JZJ‹„|MÿT¼u2[ß“^eÂ5`пw€í»Ÿ9S¾à¨ÄDeÄÄbSÄ‘’,?|H^¶9‰¦GpkÇ N©bouncycastle-1.49.orig/test/data/PKITS/certs/ValidcRLIssuerTest28EE.crt0000644000175000017500000000155110350736724025135 0ustar ebourgebourg0‚e0‚Π0  *†H†÷ 0C1 0 UUS10U Test Certificates10U indirectCRL CA30 010419145720Z 110419145720Z0Y1 0 UUS10U Test Certificates1.0,U%Valid cRLIssuer EE Certificate Test280Ÿ0  *†H†÷ 0‰»Œj ŠêbÝsª+‡·!›ÉŒFÄuœU”ÛÃ’™ HNʘCêk>Èÿ ŒKO®ïLƒ®$|}D²9±ïû+ êx Ù1­ÿ.,ƒ£@úÜØÀܘÎt¼Ý„VO¸]ÃÛŒ{ãΡ —Ãí—ç±ÄV€ÐžèQ3-wÔÉ£‚Q0‚M0U#0€–(¼)¦­XŸg.ÇÂÁ—:ßîˆë(0Uúc)wWþÖ­é†ÀÙj¬# &0Uÿð0U 00  `†He00áUÙ0Ö0Ó ~ |¤z0x1 0 UUS10U Test Certificates1"0 U indirectCRL CA3 cRLIssuer1)0'U indirect CRL for indirectCRL CA3¢Q¤O0M1 0 UUS10U Test Certificates1"0 U indirectCRL CA3 cRLIssuer0  *†H†÷ ‰9›+äaïÈã¡ß(yléÏf•ê¢0 ü¤¼à&,?·úà?Sñ÷$ZÓ\N¡—¦ªÕå¼ëÉ—‚‡PY<H½Š/8½Štìú”Cm<5¡ëÊÜ`#7^ue€Œ‰¯Çtä©éј ‹FaÐ]ݶ\î£=/’<ú bouncycastle-1.49.orig/test/data/PKITS/certs/ValidPolicyMappingTest3EE.crt0000644000175000017500000000121710350736724025745 0ustar ebourgebourg0‚‹0‚ô 0  *†H†÷ 0M1 0 UUS10U Test Certificates1"0 UP12 Mapping 1to3 subsubCA0 010419145720Z 110419145720Z0]1 0 UUS10U Test Certificates1200U)Valid Policy Mapping EE Certificate Test30Ÿ0  *†H†÷ 0‰‹¥`s@®Y¬ØÅjLq?ùªÄ¸ZcûE,ãâÅ:Žbh}íÉ*1Ò#X}Ê$Ó‹*ÃU pÏ`º<ÎKû‰²W™+ ë€ÛR8«ŒcÿDä÷±Ýû¤à—dD·ÖñgPQ|!À’:C¨xù)ì ´écaÌߟqYãk0i0U#0€ö,±·)µ®•°ø9AS-.ãÇ0UÇmf#f•d–֢Ɩ6«×î‹ì•0Uÿð0U 00  `†He00  *†H†÷  ccšÿоá±%B¾uÌ™¨Î€´Çp‰`´Ü9ADHo$3ú‘ ¥\µWú˜;Ê-/mý§ƒÇ÷ôŽtê²v²×ñý*й›B¾kÑ•Úh´†âÅ/Þ”í¾¸±tÏ~õ[ó’vê¨É˜kÌÓJãhŠ©¥U|gä×T©Ôu÷bouncycastle-1.49.orig/test/data/PKITS/certs/InvalidonlyContainsUserCertsTest11EE.crt0000644000175000017500000000125110350736724030116 0ustar ebourgebourg0‚¥0‚ 0  *†H†÷ 0L1 0 UUS10U Test Certificates1!0UonlyContainsUserCerts CA0 010419145720Z 110419145720Z0g1 0 UUS10U Test Certificates1<0:U3Invalid onlyContainsUserCerts EE Certificate Test110Ÿ0  *†H†÷ 0‰à¾ÛÇ)ÇÚ$–úÁ‚ƒÿ‰×® NáaÅv$Ë%]°Á$U(Ü+¹s Qø'²Kù:šÛ‚‰Xiž8r÷ ­éˆ—&^ÍùJä‘m-äyúC[Qæ¾FT'ìD§èè¹.ˆ\ Hùµôˆ‰¤¼¬;pMÜ“kS¿»Þ’À¬„kÝÌA£|0z0U#0€ZË7ÒF˜\•øß¸:ÿ@­ò0UoOõ]#™õ‹Ç˜në¼ÏÀ`80Uÿö0U 00  `†He00Uÿ0ÿ0  *†H†÷ œ›ÉýnÄ„(ùPožÉP]ÕŸ@g¨ÔÕr ß;]"Qï_yÈ{ª%áF¶Ï¹–¬‚ ¥¾^ßCEˆôÊëëeá~Í¥ý«0>t‹•¯þÍ>¹ZM)‰‚V—æ}ÚÝb[%EÞä¾E:‘7º¯Â§ÍÌ ÌÌ‚$>h±õ'J]²7œG¤…î϶„ Ϲ^°¤xàé}Çìëmd6)[Éï5Æ££l¦[ìîò½2¨;ýÎXâ\8ü=½çôYç¶°Z Ö“(«—xµ¬“´Oú› ©[€Bq­†m<^£b"bouncycastle-1.49.orig/test/data/PKITS/certs/InvalidDNSnameConstraintsTest38EE.crt0000644000175000017500000000127210350736725027330 0ustar ebourgebourg0‚¶0‚ 0  *†H†÷ 0K1 0 UUS10U Test Certificates1 0UnameConstraints DNS1 CA0 010419145720Z 110419145720Z0e1 0 UUS10U Test Certificates1:08U1Invalid DNS nameConstraints EE Certificate Test380Ÿ0  *†H†÷ 0‰‹ÎÔŠ±f>K†a˜Ø}öÛƈ^°Ò`Ъ€s ã _s„Ÿ`Ë6§PµÃ!•Â’Oá[pSTε²J0ËRjMë9’ Ó,ˆx‡öþ¿n°©]LÅC-Çê9Cœ­½gÙ¿éH®ÉÊ͉ªÝ8#âVWÎY5P²Nî)ǘ˜Jd}¹sÿâÕ¾·ÆÒ¬àPW--{V\GObouncycastle-1.49.orig/test/data/PKITS/certs/InvalidSelfIssuedinhibitPolicyMappingTest10EE.crt0000644000175000017500000000125110350736724031706 0ustar ebourgebourg0‚¥0‚ 0  *†H†÷ 0R1 0 UUS10U Test Certificates1'0%UinhibitPolicyMapping1 P1 subCA0 010419145720Z 110419145720Z0r1 0 UUS10U Test Certificates1G0EU>Invalid Self-Issued inhibitPolicyMapping EE Certificate Test100Ÿ0  *†H†÷ 0‰´®­Ž®›‹úüöe™GE¥Dá"õœbO@6ïfq”psšGâÏÝêеkßg,´ç3[g×upÛãpYÕ§`RjyÈ¥I£4ܹiûm}VÌÞ&ë˜Nv*ÃtÞ÷QM©Éd†”IõìyÚÍç¡ðE vPUs¡ãª{û_£k0i0U#0€A¦$çKFÊN½bý• EDEÖƒ0UáC¾ý(~ˆn3ó[wÊÃé7F0Uÿð0U 00  `†He00  *†H†÷ {to}]’0„3@º¾x r«fL ¹Œ­Ü©çS6¹6 D)GÞ´‹OÀQX7òÔÅ'oDí+ þZ¡^0ŽLƒ,äº!¼oÅ¢ð×Úøcþe¥±õm!# o‹e¡ŠÿÀîk rK™—bʵ ”A›ÿµK+–e™ Ý.°bP<`bouncycastle-1.49.orig/test/data/PKITS/certs/ValidPolicyMappingTest5EE.crt0000644000175000017500000000121510350736724025745 0ustar ebourgebourg0‚‰0‚ò 0  *†H†÷ 0K1 0 UUS10U Test Certificates1 0UP1 Mapping 1to234 subCA0 010419145720Z 110419145720Z0]1 0 UUS10U Test Certificates1200U)Valid Policy Mapping EE Certificate Test50Ÿ0  *†H†÷ 0‰»»@ÒoDâü[ãSpõbP–WúÈäÅæ¦äÕyfkäBå âÙõ[Ä¥—øY…ùÃ|žú&#â€øïÓXOCézŸ—\¼$|‘e4ñClä6ä³pmY¤~¬]Ù¯àÏ× éßßYøòíŸÂÞC=p¾ ó ð¡¡£k0i0U#0€­ïW}ºƒïÿ‡hsÒ¦—0UŸ÷léxdQئ<Ý™¦Úœ0Uÿð0U 00  `†He00  *†H†÷ š:„¢“ü/zf䆴P¿4ã÷Ê/qèð˜þœÚ¿Ö*Y]á ¿å%O3ù—s©ø@):ý¥µb.å—œ\û¡Ôª;ìÓŽã*åï>f"³úEâÌm”bÒ(vòÚ˜)…eï÷uÞÑò)‡’Zª ¼½Ä7<Ùbouncycastle-1.49.orig/test/data/PKITS/certs/pathLenConstraint6subCA4Cert.crt0000644000175000017500000000121710350736724026423 0ustar ebourgebourg0‚‹0‚ô 0  *†H†÷ 0I1 0 UUS10U Test Certificates10UpathLenConstraint6 CA0 010419145720Z 110419145720Z0M1 0 UUS10U Test Certificates1"0 UpathLenConstraint6 subCA40Ÿ0  *†H†÷ 0‰½øŸ*nj魒,;©ý*hYq÷“º©52àkqzwHëri×/øªí2ÖÌ«˜)N*S‹Ï)ƒÓÙ& ¹XÖÍðõ® VkŠîõ»ú§8¼ "Ìu ~¢øÏîÄ ±Úÿ·ä×XvQ¡rsL»ã`e8h‰Aç8]˜š™þü?£0}0U#0€´¤·¢®¹vµËd¥z…J0UH4T¦ìOÙ˜!ìÔc±#oíy>0Uÿ0U 00  `†He00Uÿ0ÿ0  *†H†÷ GÙøì©¨»öÛà2jb´­Œµð»ŸóÕr}¡œ.´qç˜I¢•“¢_ûTÑÊü÷q†QúÑÇ£üYòfû¾Ì%;€—¢3£ciMÒ;ÖoÒe¤Ñ£'j”×ñáT*40Y£X¡]¨RXû<ÅĘI ±•Æ)¹:Äʰ<°bouncycastle-1.49.orig/test/data/PKITS/certs/RFC3280MandatoryAttributeTypesCACert.crt0000644000175000017500000000130510350736724027614 0ustar ebourgebourg0‚Á0‚* `0  *†H†÷ 0@1 0 UUS10U Test Certificates10U Trust Anchor0 010419145720Z 110419145720Z0Ž1 0 UUS10U Test Certificates10 ’&‰“ò,dgov1 0 ’&‰“ò,dtestcertificates10UMaryland1 0 U3451 0 U.CA0Ÿ0  *†H†÷ 0‰˜ù¯¼Û‹¥âÝÆC;ëjÙ§«V¡Ôÿû´’~9v»=p°±ÈíxÎë–¬OMÒƒA¬fIˆzZ¶&=\wËÜáSÊkñä5„z£ÂlTîûô~ºÑì`‘γŽPJŠ’!Í„w‹*دœìÌ”`D<Õ˜"{´p³,¿£|0z0U#0€ûlÔ-žÊ'zž °<êš¼‡ÿIê0U - \¨‚b*6¢MRÈå,P}+0Uÿ0U 00  `†He00Uÿ0ÿ0  *†H†÷ —¡pˆ”î ÿ8uS°y#9Öù32“¹Ó°ç™”íXÌÉ;¿4ã ãôîÈ34‹ú$ŒÝ‚nÌì1Ç™@ŽÏîhFD`U’C„šÅ÷/n¦¤*‚c+æ úÌü¥Ú©~½t02!ÆMh½/õ„¾fœÃ@'%Ÿ‘wN£«bouncycastle-1.49.orig/test/data/PKITS/certs/inhibitPolicyMapping1P1subCACert.crt0000644000175000017500000000130110350736724027207 0ustar ebourgebourg0‚½0‚& 0  *†H†÷ 0O1 0 UUS10U Test Certificates1$0"UinhibitPolicyMapping1 P1 CA0 010419145720Z 110419145720Z0R1 0 UUS10U Test Certificates1'0%UinhibitPolicyMapping1 P1 subCA0Ÿ0  *†H†÷ 0‰åÔP¨¹³Õ&˜;ýæÌFu4ùÐ]ÔÙM t3Di«xœ|šæÍ5Lʤ£!¬€ª€à‰òÃx,èÃqq-p¦ÿa&G;êO¸kL«èd5Eù_Ûù«„¢ø=Ê¢†!=jÐ|½HFtVæªR‹»"ò¤a­‰£¥0¢0U#0€l\â¥l[`¥ÞwSZã55¯­0U¶¦ÁêÀRS߆ýfIä´F¾c3 0Uÿ0U 00  `†He00&U!ÿ00 `†He0 `†He00Uÿ0ÿ0  *†H†÷ êÏš®ß+~UíÎJ|¤ônR2ÌFÐÿÃnä–7‘F‹ÕþF2êxÃê§ÓOœ}.Óµ³Œ Í:΀v²IEž†'V“{`BR·ƒ’CwÇ4í%€v‚Z{ÕñÆw$±^Ì¿¸d<×P–(Æa‚êÅMò,ÎŒ¯ëºbouncycastle-1.49.orig/test/data/PKITS/certs/nameConstraintsDN3subCA2Cert.crt0000644000175000017500000000131710350736724026351 0ustar ebourgebourg0‚Ë0‚4 0  *†H†÷ 0J1 0 UUS10U Test Certificates10UnameConstraints DN3 CA0 010419145720Z 110419145720Z0N1 0 UUS10U Test Certificates1#0!UnameConstraints DN3 subCA20Ÿ0  *†H†÷ 0‰Âs– Ï•é52Œ7pè8Âþ­öú'×Ùt1È\¨',<¨]³ÅÉxjKÅô…¥ÿ{m)¼Íåù6ü tƒ=Uϲ¦[̰i°ú Mß‘¶?7„}Ö· ¹ŒjN=4¹ÏcØay. `)¡"yéó’þDê¦Ó­üWWÕÍ{ Q¾G!¥Þ#KøXR«Í¸,B3±ë¯KšÁúë‰äèÔ¶ý8.51kï6Ù¬bouncycastle-1.49.orig/test/data/PKITS/certs/InvalidSelfIssuedinhibitPolicyMappingTest8EE.crt0000644000175000017500000000125310350736724031637 0ustar ebourgebourg0‚§0‚ 0  *†H†÷ 0U1 0 UUS10U Test Certificates1*0(U!inhibitPolicyMapping1 P1 subsubCA0 010419145720Z 110419145720Z0q1 0 UUS10U Test Certificates1F0DU=Invalid Self-Issued inhibitPolicyMapping EE Certificate Test80Ÿ0  *†H†÷ 0‰Ù™ÊÛRÝ ÐÂ//þìL!`F{M{B[¯Éþ™Wkÿ"Ú^QÝïÞ¼7ƒv~¥q€€´Þ zFònêF¡nšµ„ù!­ê{£‚0‚0U#0€“M¼ò× ® H¬º2 ×è Í0U‹€=²¤`ÒF¢TÒžm)}†‘0Uÿð0U 00  `†He00SUL0J0H F D¤B0@1 0 UUS10U Test Certificates10U deltaCRL CA10SU.L0J0H F D¤B0@1 0 UUS10U Test Certificates10U deltaCRL CA10  *†H†÷ kºÖRW·íngÁh#Ý)áïOÆ (ìlÛBñ¬ãn¢‘#>ÄNÇÐöv±ãmßEaç¦ÇÍ%nâõ‹ñ ÍÑ?Y¼Ûxî÷Jwj”Œ;Ëu —«ø$lP$”„¾‡î$(Æ¡•ÃÍÑ›CîÓc6gù« ¼5Y“ òr¯+bouncycastle-1.49.orig/test/data/PKITS/certs/requireExplicitPolicy5subCACert.crt0000644000175000017500000000122310350736724027231 0ustar ebourgebourg0‚0‚ø 0  *†H†÷ 0M1 0 UUS10U Test Certificates1"0 UrequireExplicitPolicy5 CA0 010419145720Z 110419145720Z0P1 0 UUS10U Test Certificates1%0#UrequireExplicitPolicy5 subCA0Ÿ0  *†H†÷ 0‰¬ÃaÞ)Ì•e”ME†| \Jr*;›†OÜÀéEoXE„¬[S¶M‡—ë}È…Rò» [m˜Îž-7Ó:qzLpvú|µK’z-õp.ûiõCåÍ'Õ¹ ¶ÝjíQqK%bÃB9»¯ÎEÏÃôââï­ÇQუ|0z0U#0€Õâ†-ñ+hœ^¿+¸f™žCº0U•†‹‘6»zoâ„ïEŽ'k¸0Uÿ0U 00  `†He00Uÿ0ÿ0  *†H†÷ ó¯yñD’/U¸«zï4¸ï=yó\<¨ª]ëbØk2mÉ!B韜ÚF¬(„üºî42‡ji}ÑÐÔsnjÀ€¾Ú¦´œj!¤uâ—ÿ7äÉΦ‡¹›¹U8†iU¦?çJ®»ºª"G†Üb¶ø½št`®—/P#bouncycastle-1.49.orig/test/data/PKITS/certs/ValidSeparateCertificateandCRLKeysTest19EE.crt0000644000175000017500000000125710350736724031054 0ustar ebourgebourg0‚«0‚ 0  *†H†÷ 0Y1 0 UUS10U Test Certificates1.0,U%Separate Certificate and CRL Keys CA10 010419145720Z 110419145720Z0q1 0 UUS10U Test Certificates1F0DU=Valid Separate Certificate and CRL Keys EE Certificate Test190Ÿ0  *†H†÷ 0‰¨õ Õ?^èÃ\X ¯bø>¾NxZáy³`ñi­%}Ç%«6¡È·Í*¢Â§HÂ'+ÀÛr`»#ãøvøð[Ù*ÑpûEmì²#É)W!ÎnÈMê"È…ó‰˜àhŸðïéxc« É„¢§(!ݵô«?*6ü¨vðòGTsªëÅ£k0i0U#0€›\Q¼"'1"@” %ÿσy­£0U®‡qâ_§¿ÎÿÀžØWh4»‡0Uÿð0U 00  `†He00  *†H†÷ RüsÍBä þ.HÁš«n1ÕY‘JðiqZÑjwÆÍžÕèÃj!ß(Y­Ü[œ&¤êêÞ-ÊÏ·hÔ–ïßqD’"XÏS&–±91àÿNaãÄ ô-Î0Dù*k9èµYk¹k:]”¤ï’[¨8È…v›’`A#n–¦i‡bouncycastle-1.49.orig/test/data/PKITS/certs/basicConstraintsNotCriticalCACert.crt0000644000175000017500000000120710350736724027543 0ustar ebourgebourg0‚ƒ0‚ì 0  *†H†÷ 0@1 0 UUS10U Test Certificates10U Trust Anchor0 010419145720Z 110419145720Z0T1 0 UUS10U Test Certificates1)0'U basicConstraints Not Critical CA0Ÿ0  *†H†÷ 0‰ÒáC€÷_§ÞPïñÓÞÏ•icNRÚX)k4Ô5cá¹Mß =w.6SùÚóœËܳØpã…I*¢çëÊÕ¿*ZuŠPÕzŒÏ‘0Uÿ0U 00  `†He00 U0ÿ0  *†H†÷  ¤iƒ‚¡d¬©óöÝ”ÚUTÿÐ šMÉÍ KN,^«0ô e*¥½VöH«¨,øþ7uàîäν˜V‘G´jBnÿí•Àˆž.Ì Écùyˆ6Ü쇨ûÚ+¾«{#àuïàzª.?ô^²I‰V¾"× `»P<¶­lbouncycastle-1.49.orig/test/data/PKITS/certs/inhibitAnyPolicy1subCAIAP5Cert.crt0000644000175000017500000000123610350736724026570 0ustar ebourgebourg0‚š0‚ 0  *†H†÷ 0H1 0 UUS10U Test Certificates10UinhibitAnyPolicy1 CA0 010419145720Z 110419145720Z0O1 0 UUS10U Test Certificates1$0"UinhibitAnyPolicy1 subCAIAP50Ÿ0  *†H†÷ 0‰Õ½_‚Þí\‹Ø‡º=®Ð\^ØKnµAüÍ“ºéÍË(0[t‡P´ëï)û¢KࢻcÕÛ8ÜØ åMqö>¡¢%ìÖÕ¦e°UèlÖ,ÿ¨i<¼£>½Ôƒ_VèSÓ9Ú‹$Zñþ']QeÝ3ÈÓta’öV¥^|n±!7£Œ0‰0U#0€fÛµ”Çij>+‘¹ßȨÐM+4D0U)cÞæÂ‚={_t s¨°oh0Uÿ0U 00  `†He00Uÿ0ÿ0 U6ÿ0  *†H†÷ ³|æœïů#zU$¶mö%p]/*A&èh;«º´·VôdcÔ•H‡ù¾ÉÖó…Ÿ ÈÜ;{µ#âhÆ»!sÎy@űÈí LöáS ­'t+BV†ì{¢ÑKžhY‹sS×kиa$JžÊ³:ã3è9=’Êè ({:»yD’Žbouncycastle-1.49.orig/test/data/PKITS/certs/ValidinhibitAnyPolicyTest2EE.crt0000644000175000017500000000122410350736725026446 0ustar ebourgebourg0‚0‚ù 0  *†H†÷ 0H1 0 UUS10U Test Certificates10UinhibitAnyPolicy0 CA0 010419145720Z 110419145720Z0_1 0 UUS10U Test Certificates1402U+Valid inhibitAnyPolicy EE Certificate Test20Ÿ0  *†H†÷ 0‰¼+SZë‚€Ý!‡WŽP]ûYü™Œ„žÇf‹bÌS,wK=;×À„—µ¥Ð–L?<4EécÐÜ,ΪÍa$A5[%¶àQlŸcÅÑŠ0l8nÚËZÙ^¢gëͤó{£Â`WAéÙZ2Š_€˜¯¹ÿ c@k£s0q0U#0€@˜`æÈý\ÑØ/ êìEÏ0UºÖ>_´äSás-©k†‹÷®*&0Uÿð0U 00U 0  `†He00  *†H†÷ ­¦(ÝŠN: $v Nçu¤Þâùâ6DaõŒ¸¼x>óÄåù½œY££©~p&†t¶»SCÎöämÂJºf•ß[/ §„p0lž¹^[£k0i0U#0€·.¦‚ËÂȼ¨{'D×53ßš”Ç0UÑB_ Ÿ¹…%(^Þ†"ö0Uÿð0U 00  `†He00  *†H†÷ |r‰¡·&é“SN}!ê=­lÞ G¡òK´¼í›§HrU§Oð¯]E•fzX£γø¹€q-`}p°Î’cŽ(ÆÓªbô¬˜ªxÍ¡Ì žÈæl"BŠè—Ý3[zÃYæT%H­Òf•xÁ21êš*ÎVÉÇn2iÞë>”Æbouncycastle-1.49.orig/test/data/PKITS/certs/keyUsageCriticalcRLSignFalseCACert.crt0000644000175000017500000000121410350736725027522 0ustar ebourgebourg0‚ˆ0‚ñ  0  *†H†÷ 0@1 0 UUS10U Test Certificates10U Trust Anchor0 010419145720Z 110419145720Z0V1 0 UUS10U Test Certificates1+0)U"keyUsage Critical cRLSign False CA0Ÿ0  *†H†÷ 0‰â,ö»xx•ÔÃ/”LÚÔ®ààXf@Â09 qƒÈ V£}E7—x«ØO öA׿Ë@4çì/Ù¸¥5{£u”ã tVÞz°ãsû@6‚ùøUÀà·Ïº½dãhS…70L†ç©J¡žc`‡’ˆü€²`ÏëU£|0z0U#0€ûlÔ-žÊ'zž °<êš¼‡ÿIê0U”éÄPö p&”<ïß0.Þ?tÍ0Uÿ0U 00  `†He00Uÿ0ÿ0  *†H†÷ oQÞ‹:„ Ã4ª•±XØ–äa±bà­=Åë‘+lÂ#æ4"§Ó-ÿ N¶Ïv± Wd\ƒ7™ôQcô,èJ 6ü´©ðº— šQ›#Xé>ùך6öÞÂö{pE®¡—rñk]=1–Þ¯«²„vÃÜ„pPÉ4_gƒ:«UÊbouncycastle-1.49.orig/test/data/PKITS/certs/requireExplicitPolicy5subsubsubCACert.crt0000644000175000017500000000123710350736724030462 0ustar ebourgebourg0‚›0‚ 0  *†H†÷ 0S1 0 UUS10U Test Certificates1(0&UrequireExplicitPolicy5 subsubCA0 010419145720Z 110419145720Z0V1 0 UUS10U Test Certificates1+0)U"requireExplicitPolicy5 subsubsubCA0Ÿ0  *†H†÷ 0‰¼;& {•–S©Ÿºš,ø•íâÁ úqK»ž~ZÜï\Tèˆól…J¬ …ó4tìèÒáp¦,Q0ÃÀúîA€ê•VÀò»hÁÌt7‚.‘JrÔ5QÜ£œî¹ÕgkF(Â1<ÅÁ‚I´€'UxûyÑKôK}£|0z0U#0€ çb¨O/·¸?'È£©_{Fk§0U>©0f/§´%ˆ„gÉ­˜“ø–ÎÅ0Uÿ0U 00  `†He00Uÿ0ÿ0  *†H†÷ ®šâ À¬åE‡áî¼pˆ¡`Q¹®/’j*ãkpmFø«DRL½6X§Õ˜§´ŠPSý–9])|ol§ê5^j—ˆa¢³öaõ‹óä¼Ð†èU:<«w7€ÆÎWzÁcÐà$ö=F`à%Åêo¢>Ôý¾Üb1:Eþ3bouncycastle-1.49.orig/test/data/PKITS/certs/inhibitAnyPolicy1CACert.crt0000644000175000017500000000123510350736724025436 0ustar ebourgebourg0‚™0‚ <0  *†H†÷ 0@1 0 UUS10U Test Certificates10U Trust Anchor0 010419145720Z 110419145720Z0H1 0 UUS10U Test Certificates10UinhibitAnyPolicy1 CA0Ÿ0  *†H†÷ 0‰Ï{X\˜»ÉH$ §""Ûó§ü™>!Z à"!Q5Ý–ªÌ—û爆/ E…¦èÖsãnƕڱªôœ¨9οí”2ß¼?rž„•ʻ쥠·vÍıNµÜ¶×¡©<·sÒ;šÄ[¦ÛÏ1®©´ñhA/Z›R—¸V:—£š0—0U#0€ûlÔ-žÊ'zž °<êš¼‡ÿIê0UfÛµ”Çij>+‘¹ßȨÐM+4D0Uÿ0U 00  `†He00Uÿ0ÿ0 U$0€0 U6ÿ0  *†H†÷ ”ê–µ-Ûÿ,5Z²:”ˆ í…§ËžOwl¦ÿ÷KúìE,˜:©•bxÊ,1˜GJÑõa²ÂZˆÏwߨ®œ«³CÚâæð-i¯?{9ë.Õ Š+0`F)Z>« Ã]¬a£g€šc(¿ŠnɵÕHëŧÿÀX)ˆ>ìÇbouncycastle-1.49.orig/test/data/PKITS/certs/DifferentPoliciesTest12EE.crt0000644000175000017500000000120310350736724025663 0ustar ebourgebourg0‚0‚è 0  *†H†÷ 0B1 0 UUS10U Test Certificates10UPolicies P3 CA0 010419145720Z 110419145720Z0\1 0 UUS10U Test Certificates110/U(Different Policies EE Certificate Test120Ÿ0  *†H†÷ 0‰² 7Sï@<úû ¡Xªñ5ˆbĵ®‚/X€kˆOøÇžÂ¾øVΰoF#KbY®¹J‡–JRÿ¢½/mÊ}¢4ØÐà¶– ø/#^8ã«pdœÈ_~eCƒóNq-ŽÚô}JùˆÖm šSQ$ Æö_¿,ðu²#Ú€µ}OÎÝ£k0i0U#0€޽fŽUeÏQäY¦É*b¿÷¥¼0U‡e* –f̧æqœ%q±TPÃ>0Uÿð0U 00  `†He00  *†H†÷ >°«šç¨ê¥dÃÓé.ß1÷ìÿÂxܧ­‰E´P?ÝY5'RÙ€6Ÿâa() çªqD~¼–a°…ÓûLá$»ú·°p.d™íÞ^Œ ZgçØÁ%c² hûÓÎ4XßåÈy7Ì+Ë‚Qy±ûR·AHËîÐI˜À¢ߑ݊bouncycastle-1.49.orig/test/data/PKITS/certs/inhibitAnyPolicy1SelfIssuedsubCA2Cert.crt0000644000175000017500000000121010350736724030212 0ustar ebourgebourg0‚„0‚í 0  *†H†÷ 0L1 0 UUS10U Test Certificates1!0UinhibitAnyPolicy1 subCA20 010419145720Z 110419145720Z0L1 0 UUS10U Test Certificates1!0UinhibitAnyPolicy1 subCA20Ÿ0  *†H†÷ 0‰œÙWâ]¢§ Ð“#ëe_ˆýñvÓÙî9éÃ-™æ¯S•ˆEÒÁpÊ!M!0°# øšÜGñm8ÁSˆi%ÓR¢Iô¥æWeãú^>IßâòrE•rî„àh#Á>ž-;¸½Ì_“Êk4’má5qG!Ó"µ®Ç£v0t0U#0€«ÈA&ÐÕLæ+Vgìï‚ÄÂÝòU0U݉f¹âwލΤ‚² ¤Æ¦z0Uÿ0U  00U 0Uÿ0ÿ0  *†H†÷ Ïðœoeê:~V!á~¸¹|©Û؇ÖÚÑÍ•dFÛZØ{såÁ2ø7ÐÕ²­·Ží×ÉËÃŒPJÝqW>J«n–¯oaoޱvÓGپ̟Óf‡S¯r¡$[Jæ2«kÿì÷m5þ©è´ž¾9e±RËþ´²ŠsýÖ»òb{Á¾ˆ£bouncycastle-1.49.orig/test/data/PKITS/certs/ValidLongSerialNumberTest17EE.crt0000644000175000017500000000124310350736725026467 0ustar ebourgebourg0‚Ÿ0‚ ~ 0  *†H†÷ 0I1 0 UUS10U Test Certificates10ULong Serial Number CA0 010419145720Z 110419145720Z0b1 0 UUS10U Test Certificates1705U.Valid Long Serial Number EE Certificate Test170Ÿ0  *†H†÷ 0‰É„#;D°X+4jS(öÓ6C%Mä€Ð݃n^† £tWßf5óâðu§ ÅEÅb Ï^š?üSúæ ýþtù¢ÉÓq²Zš¾Cæ±6ä¨r>á ,hø=Ô,UNBáÅOQ M[.E`‚t'æªÒÈ{ðÞ8ù]ÏÊÙ¾×Q£k0i0U#0€ß=Hûã2ç¹&R‹Úìø O³Çߦ0U{Ű5Eú(„=á¯Bãåeøóº„0Uÿð0U 00  `†He00  *†H†÷ aªÖj”"¡¡ûŒG\,1nòvµ#"ƒcªñ¢Íg? œj­g!Ã7Ì]3ž Õ(bØ€1"žå|[‡¥ü£ÿÎ;1÷÷ºêN°½5K‰Q±×uü>Š’ä—ÇÃ-ôï&ßÏ‹ :|O,û˜¢_ š‰(3ÑJ–­îebouncycastle-1.49.orig/test/data/PKITS/certs/requireExplicitPolicy4subCACert.crt0000644000175000017500000000122310350736724027230 0ustar ebourgebourg0‚0‚ø 0  *†H†÷ 0M1 0 UUS10U Test Certificates1"0 UrequireExplicitPolicy4 CA0 010419145720Z 110419145720Z0P1 0 UUS10U Test Certificates1%0#UrequireExplicitPolicy4 subCA0Ÿ0  *†H†÷ 0‰¦¹åOêwI¾RÛ±”Ól'½•˜mˆ…ÎÂæÉrçmTÔ@ch¸^ÏNmxwÙ¡IÞFP¸üVDjBýÌ(cÀYS·DXïN@Wü5_‘MbéÎà6«š´·CRdïK^¿mÚdZö0ÀC‰Ð}óŸýÌtèfï8|ÑÙÍœÏ^÷¹£|0z0U#0€%~´ вóÁGðAyï²Bæ5û0U#a8q, a¾¢¼×Õ‰ÖØP>½ëÅ0Uÿ0U 00  `†He00Uÿ0ÿ0  *†H†÷ Í\xÌ§àØæOƒ‚†u5IK6¯SÐîÔÈ×MH¼3[*ç6HI©šéwÜüxϘ (&l"›_7ø®n¤»|ôúUÜíRáÈŠò²æ øˆtí€æPÖY~_:úí §eÑCJÉ ±uEMUfQÊÿ V2cA«VƒzZâÑcbouncycastle-1.49.orig/test/data/PKITS/certs/indirectCRLCA4cRLIssuerCert.crt0000644000175000017500000000153510350736724026124 0ustar ebourgebourg0‚Y0‚ 0  *†H†÷ 0C1 0 UUS10U Test Certificates10U indirectCRL CA40 010419145720Z 110419145720Z0M1 0 UUS10U Test Certificates1"0 U indirectCRL CA4 cRLIssuer0Ÿ0  *†H†÷ 0‰½T3:ÛqzRDVå¦2,q“èßbBf-±#ÅC®ÜEý&ÊAN<%@nFa>ñN†EÒ$x½æZB±kwÔí¥æ‚!*ìêNªó¦&“}ª oÂÖ‡QÑI×çœûÅiCAÙy^/ÛO­1/TÁg49]®Ó{…ÿ£‚Q0‚M0U#0€­²CT¾—xP—Å ò4“ÅÈ@°¹'0Ußœj.YµvÆxõ9 Ûþ…Zc0Uÿ0U 00  `†He00áUÙ0Ö0Ó ~ |¤z0x1 0 UUS10U Test Certificates1"0 U indirectCRL CA4 cRLIssuer1)0'U indirect CRL for indirectCRL CA4¢Q¤O0M1 0 UUS10U Test Certificates1"0 U indirectCRL CA4 cRLIssuer0  *†H†÷ R»œ¨BÚ°ãÿ  µ2ºòQ´ü‚n§ç5@ì~^Îc·jœJ G¯ÄÃ`«9öÀÁò=S«¡ŒŸ°¾®Ý(ÍöÀ ÝîN{ ‹Oñùé7WÓºåDY(t“˜š< A.a}àDbouncycastle-1.49.orig/test/data/PKITS/certs/InvalidinhibitAnyPolicyTest6EE.crt0000644000175000017500000000121710350736724027002 0ustar ebourgebourg0‚‹0‚ô 0  *†H†÷ 0O1 0 UUS10U Test Certificates1$0"UinhibitAnyPolicy1 subCAIAP50 010419145720Z 110419145720Z0a1 0 UUS10U Test Certificates1604U-Invalid inhibitAnyPolicy EE Certificate Test60Ÿ0  *†H†÷ 0‰æ¢û–ôo7³¹)úý¢ÖÜÍ0,Ìã mÂ?A#0`é?™ÒÚ1žÐ4WkiðØùlµÛë (¶^eƬlH*à&fæ'ÙÞàú÷<ܳóÓ ¬}>WÀ —ôÞ lÇЕÍÖ'¾;ii¿ž›£e0c0U#0€)cÞæÂ‚={_t s¨°oh0U³ ä®®`aÇ9ìeŒ=ª7¡ía0Uÿð0U  00U 0  *†H†÷ e5Øõ™(自ÛM ÿŽ«HÈÂr„=ØSÊ îa ÜÊ& dÊŠ@ŠNq „¶Òñ:GhBBXdWiÑ`Ú.ö óË›kGbMÛ_ëqn"u 6S×ôÿ:W„%KÅÏzÙûJfwšd_@ÍŒjNñ’×#°U{Ž)³ƒ†]H¥œQ~8úbouncycastle-1.49.orig/test/data/PKITS/certs/pre2000CRLnextUpdateCACert.crt0000644000175000017500000000120310350736725025566 0ustar ebourgebourg0‚0‚è 0  *†H†÷ 0@1 0 UUS10U Test Certificates10U Trust Anchor0 010419145720Z 110419145720Z0M1 0 UUS10U Test Certificates1"0 Upre2000 CRL nextUpdate CA0Ÿ0  *†H†÷ 0‰”ÆP½ñ›éwbšžÄÆMÊ÷© ñÊo¥&3„¾½eˆAÆOŸN.[‹›h£¡R¬ñm[Xé{˜ ƒ¡‡\‡%7š3¯ñ%Ú ìý Àwð‹àÉtÓBýä¹Ü‡Ò+Ä~ìù¡cE³zc蹈1ÛÞ>ßÞ¿Õ×øG£|0z0U#0€ûlÔ-žÊ'zž °<êš¼‡ÿIê0U½z6Õ] •¿]®«ì¤Q`&¯V0Uÿ0U 00  `†He00Uÿ0ÿ0  *†H†÷ }þ7¦“”»m…žd.o<Í#}嬞q"?Ü8†øÂÍä¤jˆ·‡‹¶ßÓç½cèÚBï83ÉÁ»ÌÐp»ˆŒ™æžS‘ŒûÚUO Lê Ù“ÆGf'Ö[BþKÁ³Äúl¬=¡,3ù“—— 8ÀtÉCƒçøèÿ¾ˆ&3-¿bouncycastle-1.49.orig/test/data/PKITS/certs/nameConstraintsDNS1CACert.crt0000644000175000017500000000125310350736724025675 0ustar ebourgebourg0‚§0‚ F0  *†H†÷ 0@1 0 UUS10U Test Certificates10U Trust Anchor0 010419145720Z 110419145720Z0K1 0 UUS10U Test Certificates1 0UnameConstraints DNS1 CA0Ÿ0  *†H†÷ 0‰¡xpexŽ!¤ùfOõ{o–§ c_Ö oCÁ”|}ö> ­¾¯ž1[_^b[k¿g½-xÙýáy\~›?é/^ôCÞ‚jÀ,=M®@.´ØäQ'…m*íIv5 X¨ºÖÉÎÞ1u~ú)ªaÈ¡­IÃà®ã*÷Å«£¥0¢0U#0€ûlÔ-žÊ'zž °<êš¼‡ÿIê0UuçgG «ñˆˆÛžÕRŽüsx0Uÿ0U 00  `†He00Uÿ0ÿ0&Uÿ0 0‚testcertificates.gov0  *†H†÷ ÍEyjz"8?0A Þ´\ƒœ œÙktø±Z7¸«bPpùêfMÓ[Ó´;VfpV„·>,P”“Çdkä–$Ê3ÛÎí¯ ØPåý‘Q6¹¶¬qcg “åÂ?’#€ŽòI­Ië/WEb[MÉó•þy¯:²ê‘Npƒ¥¬vÿcö®å@,)bouncycastle-1.49.orig/test/data/PKITS/certs/requireExplicitPolicy5CACert.crt0000644000175000017500000000122610350736724026522 0ustar ebourgebourg0‚’0‚û +0  *†H†÷ 0@1 0 UUS10U Test Certificates10U Trust Anchor0 010419145720Z 110419145720Z0M1 0 UUS10U Test Certificates1"0 UrequireExplicitPolicy5 CA0Ÿ0  *†H†÷ 0‰•M{›fÿ¦ÓÉ[%O*ÔZ®2½HiiZ¿„!×õÜF'e›Ð5:qMÉõŽf’ÌJoiRfæljˆ6æHÁgšÌ—Æv˜t˜iÑ噽žš\îÔ87—§Š½£aêÚEÃKô¾ÖŽ•f¹gL"%–¬EHñ€/eEi壎0‹0U#0€ûlÔ-žÊ'zž °<êš¼‡ÿIê0UÕâ†-ñ+hœ^¿+¸f™žCº0Uÿ0U 00  `†He00Uÿ0ÿ0U$ÿ0€0  *†H†÷ Ž1¥Ôׂ.#ôÁMûf í^„yù øM"PjgštIvhìjîIºgEüO°±-BÑY¢». ¦—iÊŒ˜¶\þTËGÖÒ²'˜+3d"e»rRˆfMßÚ !º¡Q9·OÞ¾þËŠƒ÷‰.oÝU×Á€,bouncycastle-1.49.orig/test/data/PKITS/certs/InvalidonlyContainsCACertsTest12EE.crt0000644000175000017500000000122410350736724027464 0ustar ebourgebourg0‚0‚ù 0  *†H†÷ 0J1 0 UUS10U Test Certificates10UonlyContainsCACerts CA0 010419145720Z 110419145720Z0e1 0 UUS10U Test Certificates1:08U1Invalid onlyContainsCACerts EE Certificate Test120Ÿ0  *†H†÷ 0‰Ñf£.,o¿…,´_AS&Aà5 Ë¥Š—¨êbE2²‰ÄmŽFYõ¯œþIJx½h00A4‚v´¸R€ ¬`¯¨zkÆ ¦pìÝø{wº^­!ø·´‹nWöR_@àïßå ,ÊØµà|8\vµ¶^9”ëç×.1߭߯£k0i0U#0€ó¡Fg{éY«ëU†“ȬäU·0U¬Vy«_Ó©}¢ê¼[Äà\´¨˜¬0Uÿð0U 00  `†He00  *†H†÷ Z¯óÇ\žºí}-3‡Pä …ƒ$ˆ¨¹Þæ#D—p7¡ÐÇ¿'\&¨9¥Kº#ÞõS«§¿A#ŽÑ,šúAê`‰,‹Ñlºçm{ÁoAÚ$LúŸ0iM賈m+Ÿd¦'K Íï°(_À ª€ãßÓOô0šŠ®ß;uËØH´0^.ýXbouncycastle-1.49.orig/test/data/PKITS/certs/deltaCRLCA3Cert.crt0000644000175000017500000000116610350736724023617 0ustar ebourgebourg0‚r0‚Û ]0  *†H†÷ 0@1 0 UUS10U Test Certificates10U Trust Anchor0 010419145720Z 110419145720Z0@1 0 UUS10U Test Certificates10U deltaCRL CA30Ÿ0  *†H†÷ 0‰²¿c܇¤éËTŒ)³¶s‚¯˜—Âb„ “ì¢Q転Ý@¦¢7Dž/=<¦é,¶Û¾èÓ^iHTæêóxÓ`Œi„ä“}Íï<>h3-oͺÉåÕ(bKŸ¢KÀŒ€2 ªõûSZÝ-,ôÈ©aà¶B*¤h{£|0z0U#0€ûlÔ-žÊ'zž °<êš¼‡ÿIê0UâO¿Þ@Öÿ3]"V‰Ü÷Îp½0Uÿ0U 00  `†He00Uÿ0ÿ0  *†H†÷ ÅÚOåßGtf£>§Ý¢Dä`Ey“ªÂí ÜÐ|Gk Sæ®to ‘Œ)=lÀ% †{µÓÊmç7eÛÌZ~±ÁµPTÖà(÷£ñªA noîH -IpÃà°2Ð~–r”(Y4ÜYH®4‰.#:Sy%¨ÅÖ"Áø$Ƭ-H(Ìœbouncycastle-1.49.orig/test/data/PKITS/certs/ValidTwoCRLsTest7EE.crt0000644000175000017500000000117310350736724024474 0ustar ebourgebourg0‚w0‚à 0  *†H†÷ 0?1 0 UUS10U Test Certificates10U Two CRLs CA0 010419145720Z 110419145720Z0W1 0 UUS10U Test Certificates1,0*U#Valid Two CRLs EE Certificate Test70Ÿ0  *†H†÷ 0‰‰dÚ꾜ØlŸxÅ#Båæ›çY· ¯ÄÛiÙìãf-‹väéËwÞ½MúwÒnÆ%X ÿ†/)EÕ‰šÀ·öBòó+€ Fý“C¥M¬[˽JÄɉò¶†ôoÿgF1îž9¦IäÿÀ‡RÉ%7Á'°²Š$¿m€qÛ£k0i0U#0€0ÈéJÞC&A#ŒSSŒ³GŽÊ0Ur´œdOjF *°€gmE¯ HO0Uÿð0U 00  `†He00  *†H†÷ oymòY/^ŠUÛ­L1áp;%—­“ ›S ÃÝ[Òž‚H¿! ƾÆòhP‚´'ÏÁ ðùFø¼ãe®~òá„qá+ˈ-5< ñMè•è@·¤¦‡¶„p`iuã$I&a Œ{Aš#0ž ¡ ´n]ß,ƒPß‘”A—ÒÑbouncycastle-1.49.orig/test/data/PKITS/certs/ValidIDPwithindirectCRLTest22EE.crt0000644000175000017500000000121410350736724026643 0ustar ebourgebourg0‚ˆ0‚ñ 0  *†H†÷ 0C1 0 UUS10U Test Certificates10UindirectCRL CA10 010419145720Z 110419145720Z0d1 0 UUS10U Test Certificates1907U0Valid IDP with indirectCRL EE Certificate Test220Ÿ0  *†H†÷ 0‰¶Ÿ(8?1+®Ú+qä Ï qäÒSì·_uh“Þå)þ‡‹4ZÙyÄ{´m"mÈ­Vª½´¡72ëR\Мgà«>=þœíŽQ@•uŽ”ÂJ=ëUP¤¿As­ŸjÁUZˆÝƒ÷ ¨.9UœQ`Ý3Ë!¦§>-7ªrO£k0i0U#0€lÁ_ا-à†“\ ðI¹%[è0Uî¹fʆ2‚¯]ùœºCÈ yÇ-0Uÿð0U 00  `†He00  *†H†÷ j*ê³ã c@Ÿ—Úå›ä2¸r{»½39} ³ò·Q.fÇÀùèº>¶þ»±jÅLšùlé x;­¹%cÛ%ÞÁø{ ?ßX[ؾ8ë¹ 9­ ŽsU.[ŠWNhOñO ³²Ô-ELí‰VÖ+ð€ù8!¦v•oˆø—bouncycastle-1.49.orig/test/data/PKITS/certs/PanyPolicyMapping1to2CACert.crt0000644000175000017500000000126610350736724026214 0ustar ebourgebourg0‚²0‚ 50  *†H†÷ 0@1 0 UUS10U Test Certificates10U Trust Anchor0 010419145720Z 110419145720Z0N1 0 UUS10U Test Certificates1#0!UPanyPolicy Mapping 1to2 CA0Ÿ0  *†H†÷ 0‰ó°èV ßÉ Ø,%®Ÿ÷†÷ƒüD†Yé@L¥øí¶CÉêÒŸŸýùݬ ÈÚ±ç‘Ó‹i°’úŽ›Q4òõnFê DüÇ'KºÕbK`Õ½{žÜ‘€+wx¼ç þÊ*!¤â ²á—¾L@ÿ°ša:|j ®À4åãEF©û5£­0ª0U#0€ûlÔ-žÊ'zž °<êš¼‡ÿIê0UÒºO>h8æøÁê%®Ú’¯C6n0Uÿ0U  00U 0&U!ÿ00 `†He0 `†He00Uÿ0ÿ0 U$0€0  *†H†÷ Kën»1tò˜µÊÞ-ÏÅÏK–g¶ÜÜyTÚ­5…»úÀŽØ÷ø˜—Ig••U&8–ôÝ›(éM‡H˜xqF‘pB®§Žíaß2ø?ÂÐv ˜ûKq:í” /b¯«€¾ÊŒH®Çø$j¤€» ­µÑ ¤[Þ¯œJä:ìbouncycastle-1.49.orig/test/data/PKITS/certs/PoliciesP123subsubsubCAP12P2P1Cert.crt0000644000175000017500000000123110350736725027035 0ustar ebourgebourg0‚•0‚þ 0  *†H†÷ 0O1 0 UUS10U Test Certificates1$0"UPolicies P123 subsubCAP12P20 010419145720Z 110419145720Z0T1 0 UUS10U Test Certificates1)0'U Policies P123 subsubsubCAP12P2P10Ÿ0  *†H†÷ 0‰ƽ ÍÌ[ª&«õ9иSíc‚êqω%g¢"®„Íþ™[éõ æoÒ·Òfwÿ©ØRJ,’©ÑÇEåZÛ• ¯Ç»Áê]vjßY²IøÀ©Þ·Ò%EC²Znæc«uV»9'òÁC›·SV:·§%¨H¤ÈCL'xç`Dkÿ}£|0z0U#0€‹ì9ó£®n9pdh+MT,ŽÀ0UÓ*»ðµWA•RÝϨ»’œàns¼0Uÿ0U 00  `†He00Uÿ0ÿ0  *†H†÷ ‚OÃüA›üˆ‹Ä$Ô„«x<û:©z*Ê´öê·ÿ×ÎY«’Ü^ ¶Ä&º rÑÁÅcë¡2i¥ë6'\Vjé^‚JVÏÝkœës"ö×Çù{$ lݵðgÈåa'w>§© +l1??«ÅÉ݂˷áê EhAÎTbouncycastle-1.49.orig/test/data/PKITS/certs/ValidcRLIssuerTest29EE.crt0000644000175000017500000000142410350736725025136 0ustar ebourgebourg0‚0‚y 0  *†H†÷ 0C1 0 UUS10U Test Certificates10U indirectCRL CA30 010419145720Z 110419145720Z0Y1 0 UUS10U Test Certificates1.0,U%Valid cRLIssuer EE Certificate Test290Ÿ0  *†H†÷ 0‰Þ'¨Ðæ²)šý6ÌRëãyô`¼Íõ÷gvÛþH©ƒ‘®­,Ît^ÌleVFõ!÷½õŒ’è3TRåbÀ,§–c¢}þdÎíü›Y'J`é|ê°GÙüP®ÇQuÒ³"ÆÍÂísP-Õ¥¨j¥8ÉÜš›ùÌá-íÿûXj†cùceU£ý0ú0U#0€–(¼)¦­XŸg.ÇÂÁ—:ßîˆë(0Uݘm5b5©ÕŸعX« -1rS0Uÿð0U 00  `†He00ŽU†0ƒ0€ +¡)0'U indirect CRL for indirectCRL CA3¢Q¤O0M1 0 UUS10U Test Certificates1"0 U indirectCRL CA3 cRLIssuer0  *†H†÷ Ÿ»B°ìV¾/Å“€„ùqSZ]ß:‡d ”J%éâ¶9Cå°JÌOÜ\@w !Í·JEÖ±3‰Ðçø •yrs?ÑU3Aä‰áEjÊýÞBu^åµø3]ß‚0ëþ‡Üz—k7 ÞË>ùHk°‹Q®_å1€ÊüŠ×u±bouncycastle-1.49.orig/test/data/PKITS/certs/InvalidEEnotAfterDateTest6EE.crt0000644000175000017500000000120110350736724026307 0ustar ebourgebourg0‚}0‚æ 0  *†H†÷ 0;1 0 UUS10U Test Certificates10UGood CA0 010419145720Z 020101120100Z0a1 0 UUS10U Test Certificates1604U-Invalid EE notAfter Date EE Certificate Test60Ÿ0  *†H†÷ 0‰È#ž †¦—´Ž/í±õEœÂ§ !ZÒñ¥?Àèó´ÍœþÂ"ÙÒsTÇçAdöðMû/k\v†T3´–ñÙo|ÇÓ(Š)åÔˆ>EûkYXøþÏH¥¿áði}“A°Rh=€ÝË÷QÃlö m?¬l4–}¼U¾£”…ß8¯¾>ÍGÛ£k0i0U#0€·.¦‚ËÂȼ¨{'D×53ßš”Ç0Uþ"¤›k@"–k•jÛ 6úOœ™Æ0Uÿð0U 00  `†He00  *†H†÷  Ðl(pãŒ{¯Q°6Ô³GÿP›=ƒ…ß]ÖËAºnÒˆ>‘rZhô‚&>͹ pN£/²ÆÀælªt-ÌÉ„õÕË•ËÁÿ©r 1UsN?¨B.fÛ˜’n–ÐN¤¤ë°¬éiQN’D|KOyÕ!F‚°:½é‚‡?bouncycastle-1.49.orig/test/data/PKITS/certs/UserNoticeQualifierTest15EE.crt0000644000175000017500000000136310350736724026221 0ustar ebourgebourg0‚ï0‚X (0  *†H†÷ 0@1 0 UUS10U Test Certificates10U Trust Anchor0 010419145720Z 110419145720Z0_1 0 UUS10U Test Certificates1402U+User Notice Qualifier EE Certificate Test150Ÿ0  *†H†÷ 0‰Ò è_s¹·†þmrW£ƒA A ü@U eIÄºÑØ@äkí‘·P‘¼ž<‹¸Ÿ8ö,)ŒõLù NX±Bο³-}ÀоÖpEÉLÁ‚L>«V½ …ßj­öÊ}¶·sºÍÝ©Iº/¹'PÌ4¶Ç=„µY.Ç»ýÝ/–hG}£Ù0Ö0U#0€ûlÔ-žÊ'zž °<êš¼‡ÿIê0Uа1òŠ’ ‡ý†€ˆäR‡J0Uÿð0ƒU |0z0x `†He00j0h+0\Zq1: This is the user notice from qualifier 1. This certificate is for test purposes only0  *†H†÷ Il%µ‡5hg‡-Œ’lî 5RZÙwÀ¡¯ôDy‹Ñë|¢RW·WLʶÿªÈ‚&Ãy5Cc~ç=·@Ýá o’Ë?k ãúm̶÷,¿,—®¶ƒSag°×çE¯ /£lÊ—i{nšõÄØ+  yJqö(8èRÌÊ~âtή¶bouncycastle-1.49.orig/test/data/PKITS/certs/InvalidOldCRLnextUpdateTest11EE.crt0000644000175000017500000000122210350736724026715 0ustar ebourgebourg0‚Ž0‚÷ 0  *†H†÷ 0I1 0 UUS10U Test Certificates10UOld CRL nextUpdate CA0 010419145720Z 110419145720Z0d1 0 UUS10U Test Certificates1907U0Invalid Old CRL nextUpdate EE Certificate Test110Ÿ0  *†H†÷ 0‰¯HpðÄvÅ®31“Éû…‚¶žG"zÇ­ëGç_b¤.©DjF²;üß@¥‹:·ü^½Lbù=«5ÙÂúÇp!àYÄé'gø)HÝÝ»ŠIã< >ïÎL$Ô¾mÑS4:mãC°‰vÏ1;šõ¨Ú×jåuâ·÷޵£k0i0U#0€Àjóÿ#ŽÐGDPCQÂ|^1‰Ì0Uþš–>$1]OÕƒßØÒ˜öE‘0Uÿð0U 00  `†He00  *†H†÷ ¶„8™¤Èž+gt“4¦g.¦‚g12{!¢C`|\†écÇͽ5=ÿL0KÏkíNì@ÓÚÐJg)•„ÄæªNxþv;v'¢¶RßƘÇ=ÂsËj)sÚŠOnnýá#ûçYv …–p=Ú œÇÞŸ: ©Z'VJíìbouncycastle-1.49.orig/test/data/PKITS/certs/InvalidcAFalseTest3EE.crt0000644000175000017500000000123310350736724025015 0ustar ebourgebourg0‚—0‚ 0  *†H†÷ 0]1 0 UUS10U Test Certificates1200U)basicConstraints Not Critical cA False CA0 010419145720Z 110419145720Z0Y1 0 UUS10U Test Certificates1.0,U%Invalid cA False EE Certificate Test30Ÿ0  *†H†÷ 0‰¹$JOPHQ÷ˆCáøžî­¸ŒþÅ/M÷ï9üÝIûS\ä?â‘îdõÊ>Ò¬Î`)‘dÅå Fg€þóõÒµzލËÙ#¾FŒq˜¯t·[ž¯¼,_·ô¿ñÝIa|ª„Î}ë0³ ¥'7ž“*1Y×"ú èæ±08÷ÒöµÛ£k0i0U#0€Ä•âºvlÝã»KhýBEøTì[Í0UÄ-³¢Ê8G!:6NyžcX]Û0Uÿð0U 00  `†He00  *†H†÷ 'ŸXñ÷Jx Üv‡W± ³ßM¦´ XápNÔð­7^pžlóDì4A»ü¥¡, Á°ÐpH@3Ãëi•‘)X“ãç¸ŠÇø-ÆßPQnH®mÂl ¬Î9О ÕɼeÀ'_,»ÃþâÊÎuÚиƒjG-˜€1¹FF¶X ØÚbouncycastle-1.49.orig/test/data/PKITS/certs/InvalidUnknownCRLExtensionTest10EE.crt0000644000175000017500000000123010350736725027470 0ustar ebourgebourg0‚”0‚ý 0  *†H†÷ 0L1 0 UUS10U Test Certificates1!0UUnknown CRL Extension CA0 010419145720Z 110419145720Z0g1 0 UUS10U Test Certificates1<0:U3Invalid Unknown CRL Extension EE Certificate Test100Ÿ0  *†H†÷ 0‰¢ëø™y"m•ˆ€T¥Uì›·‰9é*oÎóà$ü¨ÆG¡}¥B6–PöçrÙjˆ3“Rló•æã·0¥küI«€TÐÈ­æ3Á Çê“®â‹Åõû‹éÁ °bKí¯ù *žÚ$“ƒ( § vª4tÅlSi’œŽß(V' ;£k0i0U#0€jÿ˜ô7ýLô'Ýnèa¡U´«0U’m³H€ô—·á Û¾À~;ÓÑÙ0Uÿð0U 00  `†He00  *†H†÷ Œa¨¢"i:0#kyÇM¬}+4˜y×»º)Ž W¸>†p©Ð´èMÿ“×g_“)ù‡ ¡g\Vcµ/Ÿ’ma¦64Jœ†˳.Ûàì59Ÿ\±f–¨š{É>´Ð+¸é±»­8ý»E#bwhÐ5ùò†,Ÿk‚—¬ÞŸV¨ bouncycastle-1.49.orig/test/data/PKITS/certs/nameConstraintsDN1subCA3Cert.crt0000644000175000017500000000132410350736724026346 0ustar ebourgebourg0‚Ð0‚9  0  *†H†÷ 0J1 0 UUS10U Test Certificates10UnameConstraints DN1 CA0 010419145720Z 110419145720Z0j1 0 UUS10U Test Certificates10U permittedSubtree11#0!UnameConstraints DN1 subCA30Ÿ0  *†H†÷ 0‰ß¶ˆ‘^ìc- œ„: ·¯„ù~ÅïS¤³;_>»Mš¼óˆ±ú÷Ì<@À$Žæe4ÎtöÎb›“÷"ŠÐR8ÅÀÆù3™€dÜ'í­ðJŽ*Z)˜%öÎ+v“Tù{ècœÎðÅqNwÅ‹‘¾Ë`–e1´ˆ…˜/Eêƒv•^]ârØ*Ô ]zlŽKjGWI ›»Ï`,~×±ÌPi…BV$…¿Žgríg bouncycastle-1.49.orig/test/data/PKITS/certs/ValidRFC3280OptionalAttributeTypesTest8EE.crt0000644000175000017500000000135710350736724030552 0ustar ebourgebourg0‚ë0‚T 0  *†H†÷ 0š1 0 UUS10U Test Certificates10U Gaithersburg1 0 U*John1 0U+Q10UA Fictitious1 0 UCA1 0 U,III1 0 U M.D.0 010419145720Z 110419145720Z0o1 0 UUS10U Test Certificates1D0BU;Valid RFC3280 Optional Attribute Types EE Certificate Test80Ÿ0  *†H†÷ 0‰Á‹&r|È© ˆóŠ“øV:B–mÃûë[N£d/uvÜörÕÃì5‚OK?±IÚ þñ1E¦×Ù h^ÁñFz»"Ç0àÚèu--?“N(ùŒleŽG{âÛ›õ½E~ŒÎ«B »IiϽª(ngÀwP–üšþ%½ £k0i0U#0€¯ŸÌ,¤cBWW×Wc_sÑ0UÔsn¥†½q¨ÏÜRÊpÍ …Ô0Uÿð0U 00  `†He00  *†H†÷ ¦çpš©vb¼._ÒC8¨„†‚€B;>†ˆtO×Ó(DzÍû„i¨ãâƒí…b=ÞYI¶ÓË 4ÃLýOˆ·û¶-Ólìǘð“öÜHÌgï =Cò•á+ÍŽ– ñn˜>~«Y#ù[™Ê“¥oûÖÄè<þH!ø¾¥cºP4µÊåbouncycastle-1.49.orig/test/data/PKITS/certs/pathLenConstraint6subsubsubCA11XCert.crt0000644000175000017500000000123410350736724030054 0ustar ebourgebourg0‚˜0‚ 0  *†H†÷ 0Q1 0 UUS10U Test Certificates1&0$UpathLenConstraint6 subsubCA110 010419145720Z 110419145720Z0U1 0 UUS10U Test Certificates1*0(U!pathLenConstraint6 subsubsubCA11X0Ÿ0  *†H†÷ 0‰µÍ¶Cˆö Õ]Dr-{6¢üɧ8o!Vü=æ²àkϘ9)Ï àJ¶S ù0&2l÷ÐVx^Ñ IËñ÷)e1 ó’ÝÊôÌd> Ë¼–“à’"¦/oÃÉRÑúF°Ð˜««NûqäLþV”5RŸÿ e…›m«¿ ?E¼õ£|0z0U#0€³À÷Qö\šN,‡PQå‘ÓX[+0Uj6ðWu?BPµé(7Å­â¼0Uÿ0U 00  `†He00Uÿ0ÿ0  *†H†÷ ^V˜!= 1t` ð~5†õ$¢ü·ï"í€Ö¡õA…Û~¬G‚¿KoQÇ>îcÒx¹~V`&v×3»ÀÙK†ÛN¥°L¨¾½lˆrúà^mê™z0@]Zå¿ZYG€lÐòÒEœ—fïS@ærº`«+[æ"ja¤TtáýÆãî¿bouncycastle-1.49.orig/test/data/PKITS/certs/requireExplicitPolicy7subsubCARE2RE4Cert.crt0000644000175000017500000000126510350736724030577 0ustar ebourgebourg0‚±0‚ 0  *†H†÷ 0S1 0 UUS10U Test Certificates1(0&UrequireExplicitPolicy7 subCARE20 010419145720Z 110419145720Z0Y1 0 UUS10U Test Certificates1.0,U%requireExplicitPolicy7 subsubCARE2RE40Ÿ0  *†H†÷ 0‰´yÃŽíu®¦@²lŠä±¿:B@^[g~FHÚl¶ŒÈS«÷&xuD¢°¨—âóúEïñ$½ôÕ ú5s¿/F”ú»¸æa‰z̸(²œá?yÁü¯ú¨Ôá-häfii¿^º/×eîhÏÅà[e˜à9mê½£Ž0‹0U#0€ëh Æå/Ãó QK³Xsœ9?K0UË »Š£‘ç2DýPP`5 jE&0Uÿ0U 00  `†He00Uÿ0ÿ0U$ÿ0€0  *†H†÷ , xc¹å‚Í[g}ÖÆd5íî”U$\'Õ·ÎìZî ¿ÜJŽqŽyÿ¡œÁ^.>KáKNQ礦x©›þu¦-?ýVü-é‹Yç»~yÙî8ó‘BËáý&JŽÆO‘ú ¼àOÉhX€¶ì `”ÖÃÏ.}iÁ¬ô5Éy{-“Íbouncycastle-1.49.orig/test/data/PKITS/certs/InvaliddistributionPointTest6EE.crt0000644000175000017500000000131110350736724027250 0ustar ebourgebourg0‚Å0‚. 0  *†H†÷ 0I1 0 UUS10U Test Certificates10U distributionPoint2 CA0 010419145720Z 110419145720Z0b1 0 UUS10U Test Certificates1705U.Invalid distributionPoint EE Certificate Test60Ÿ0  *†H†÷ 0‰Á¹ÃË ½–ö³x¡'Ë>Ðh2¯ çÁ·u(Ñ&=€ï6æ"ñô,ªúöÒ,ÀψÄlTµpÀ^æšê‰‰ÔòVŸ¸t9§¤€{!™ºÏi°C_ñ§Sl{[Û×XYKº¬ ©~Ž9Ç–,Ð`åÄ›N~éç—\£ À/HMÒ`†cÁ ïn¬ýÙо3«‡±•«Rm°„ /W'Œ˜uIÒ\{iŸbouncycastle-1.49.orig/test/data/PKITS/certs/InvalidNameChainingOrderTest2EE.crt0000644000175000017500000000133010350736724027031 0ustar ebourgebourg0‚Ô0‚= 0  *†H†÷ 0Ž1 0 UUS10U Test Certificates1#0!U Organizational Unit Name 21#0!U Organizational Unit Name 110UName Ordering CA0 010419145720Z 110419145720Z0d1 0 UUS10U Test Certificates1907U0Invalid Name Chaining Order EE Certificate Test20Ÿ0  *†H†÷ 0‰”…":»# 0|8pð_yÏ‹g nó%dԿדt都mV€ˆ H^‘«Ïì FŸ†. $‘ÝoPœÙlÇȳãÌ,¦‰)?4N`™Ë¦Übouncycastle-1.49.orig/test/data/PKITS/certs/nameConstraintsDN1SelfIssuedCACert.crt0000644000175000017500000000121210350736724027534 0ustar ebourgebourg0‚†0‚ï 0  *†H†÷ 0J1 0 UUS10U Test Certificates10UnameConstraints DN1 CA0 010419145720Z 110419145720Z0J1 0 UUS10U Test Certificates10UnameConstraints DN1 CA0Ÿ0  *†H†÷ 0‰Ê„¶Ì6é]A*a×è`IMUî2ë8—ž¨Kã v¶¿«+9Ói·"Ïl(óTÉ`3=@Bj=ûùÀ¿–z#%:YÃIr|䞨0mÀÌÎýSk£ºãWÆMâ …£¬â!ªl˜¶Ö!!Å|bošð ½Cóp!0ï£|0z0U#0€N.£çÙÝ‹§‚;AJÞ|Y#WNS0U·¬ ògÒ9qbÛ­53‘ü”óóÚ0Uÿ0U 00  `†He00Uÿ0ÿ0  *†H†÷ ,NØéO|u‰bn¹ü;%HÊ€ÊH0á²úÁ8ÕØ]÷ÑXìWu¡Y> ø&¿ ]¥wŸP™uh}2ô{•ž$‘¡bóð>h‘“×Ô|š­sRCcfÿuÎÍÿÆ.ü JÎ}n_œNmÄ ÑŒsû>³oø¶0¶§Ú •ºúºbouncycastle-1.49.orig/test/data/PKITS/certs/InvalidrequireExplicitPolicyTest5EE.crt0000644000175000017500000000121610350736724030060 0ustar ebourgebourg0‚Š0‚ó 0  *†H†÷ 0\1 0 UUS10U Test Certificates110/U(requireExplicitPolicy7 subsubsubCARE2RE40 010419145720Z 110419145720Z0f1 0 UUS10U Test Certificates1;09U2Invalid requireExplicitPolicy EE Certificate Test50Ÿ0  *†H†÷ 0‰ ÒYà¦QÐJ‰±W³¿Ê÷ß3¥µƒáõÜ[Ćjä¡4ÚÕVLû½p+ÚÏc²Õ¡’@ƒ™¨zÛ1ˆÎþ{pjþïÔ^±UÙâépò¬BZÀÿPmË©&Êô"É×?¾2í‘ýxÇk‚jÃf.Ø(Ý+n¢Ÿ¶r‚Ï –õ£R0P0U#0€ç«Î(åhéji>)¥6cp¡š0UR?ê* ÖºzJm°:Ç Â0Uÿð0  *†H†÷ N­5ÓVÁha+8~5`n#è}e!V\lÞh0‭ª¨kl0C>› ÿÝD<àÑ E*­–òRÐY«7캃^1›Û¯_Fwçmbšp–[ǂ٫6“ñ4Mr•²æRÚ÷nä-7µ¼é:Vï?ÎNhxË#Úx½¨'+Ãh-×bouncycastle-1.49.orig/test/data/PKITS/certs/InvalidSelfIssuedrequireExplicitPolicyTest8EE.crt0000644000175000017500000000121610350736724032052 0ustar ebourgebourg0‚Š0‚ó 0  *†H†÷ 0P1 0 UUS10U Test Certificates1%0#UrequireExplicitPolicy2 subCA0 010419145720Z 110419145720Z0r1 0 UUS10U Test Certificates1G0EU>Invalid Self-Issued requireExplicitPolicy EE Certificate Test80Ÿ0  *†H†÷ 0‰ɰÄ[Š n=ªõdVÄꦭ̺[GzÈ7Șv¥Ê³SÍ•­­Ìü’<ÙfÃ6Î$‚(eš¶Y{†<ÜtÌ?úm9§êïË¿ÿÌÖ ‘­¨˜tÒGªìÆÿ±ÒþŸ‹¡P éŒá?³-OéÁTHQêRÓÈ\ÅelЦ‡îßw£R0P0U#0€Ó ðibŸ–6g‡«¸†00UŽáè8:ƒ%*2ïoVŒª«ªDÖ0Uÿð0  *†H†÷ «ç ˜Ÿaä'¿¾¼„™ !×auÊN»šù™|èxe–;üÒeÞ|½"kÒA= }ø¤^›¸ã»—"«ÈÀ ß”¯;±Ñœ¤*ú8lag¯|ñ5’!!çòÝߥp¤-jc,7ú‰í¡4ïâLoâeÌÌH3¹Ü$‚bouncycastle-1.49.orig/test/data/PKITS/certs/InvalidUnknownCRLExtensionTest9EE.crt0000644000175000017500000000122710350736725027426 0ustar ebourgebourg0‚“0‚ü 0  *†H†÷ 0L1 0 UUS10U Test Certificates1!0UUnknown CRL Extension CA0 010419145720Z 110419145720Z0f1 0 UUS10U Test Certificates1;09U2Invalid Unknown CRL Extension EE Certificate Test90Ÿ0  *†H†÷ 0‰ÞaƱݺñ˜ êŒ“Ÿ_ÿ sò·îGL4ÿ¨Ã>[lC(ˆþ'_¬ùu®Æà›y .²ü7‘€åöO¦ÖãàÜX©2×FíÀzª{¶tã?ƨGÈ>4Uº‰y˜—Þ´¹êI.ÅP!9Róph.XGÛùX6Öf4W¦=P=£k0i0U#0€jÿ˜ô7ýLô'Ýnèa¡U´«0U?•ß2…k'^§š¨\3Äñ ¯gî0Uÿð0U 00  `†He00  *†H†÷ 1a¦W V·ûé <0hômîQ2SÒ‡î”X¦<“’uò{(H7DÔG°Ñ^ÿצQAÖ½>Éh£=VõA{>xJ ÄŠ»ò¿ãÒÿù¨ÐÓy¢ƒY¿,Z£ Ýá(ÝulÐXõ™‡>ñNaë´5NàÊÿJ|Š4ПÔîQù~øbouncycastle-1.49.orig/test/data/PKITS/certs/ValidGeneralizedTimeCRLnextUpdateTest13EE.crt0000644000175000017500000000124610350736724030730 0ustar ebourgebourg0‚¢0‚  0  *†H†÷ 0S1 0 UUS10U Test Certificates1(0&UGenerizedTime CRL nextUpdate CA0 010419145720Z 110419145720Z0n1 0 UUS10U Test Certificates1C0AU:Valid GeneralizedTime CRL nextUpdate EE Certificate Test130Ÿ0  *†H†÷ 0‰ŸÁ[äa߯„$ráÈ]«Á×-¯ÿñLÁ¸©¢"RÌW8‚NdÆÔxÃ\ì‘ñÝÂÖ ˆêKùSÖ¹›Tµ<XÓYEI¥Ï§˜æ˜7ˆ.ˆ†h{ÿ‰8-~ÓSeI0ƒ²ÆeD΃ͧ%œøÒSxtf\!W…(ðzq„%£k0i0U#0€†.`b´¤ˆ㊫x¢îÑ00U@\¨=€³ÖÍ¥ïT÷¿Eø4¼/0Uÿð0U 00  `†He00  *†H†÷ “ƒr‰L¬¤’a… ò- «ÞÄòC¥þSõ”~ÐáS(>(»³hTØÁãuc?óA§ ³K˜Ú–j²š~–F/Ê÷ JÅëí »dÞÓ<ªpÜx¶ns… ÊóZÅþqèp¹¥Æl§zöÜ}¶azmŠ\Vë èÖT|íM3®bouncycastle-1.49.orig/test/data/PKITS/certs/inhibitPolicyMapping5subsubCACert.crt0000644000175000017500000000122710350736725027534 0ustar ebourgebourg0‚“0‚ü 0  *†H†÷ 0O1 0 UUS10U Test Certificates1$0"UinhibitPolicyMapping5 subCA0 010419145720Z 110419145720Z0R1 0 UUS10U Test Certificates1'0%UinhibitPolicyMapping5 subsubCA0Ÿ0  *†H†÷ 0‰³€ûôC,y6Ÿ*€²š™ UrÓj;”¢¤žÚòíìø£Yªš÷R`Ý'”…YÞ¿4G„â ˆJ(&´”Òœ|éy'4˜VèãÈŒ3²ßB³œ7qˆì;çáWθ­«>£Ikˆ†`Xq´gq#œ»bcQòßï£|0z0U#0€ït]½'!\mwD&mÜ¿û¾ck 0UßjkGÚKwºöT´R”&Ê0Uÿ0U 00  `†He00Uÿ0ÿ0  *†H†÷ º9Wƒð¨÷×&Ç¿iíÇ¿pªËغޔ¶ÃxtT;M¶8R»ºÿAœ•›ÎÏ UÊöø+‚ùŽRF"‘둌sy „¸ã xËêD3ÖË{÷xwY¤À…85!ä’ÐQVôƒZÂ+vºº%=š¯8ãÚZ‰’û r#abouncycastle-1.49.orig/test/data/PKITS/certs/pathLenConstraint0SelfIssuedCACert.crt0000644000175000017500000000121010350736724027577 0ustar ebourgebourg0‚„0‚í 0  *†H†÷ 0I1 0 UUS10U Test Certificates10UpathLenConstraint0 CA0 010419145720Z 110419145720Z0I1 0 UUS10U Test Certificates10UpathLenConstraint0 CA0Ÿ0  *†H†÷ 0‰èÀª µ1/p Ìa¹'Í$Ø.DJï‚£‰÷WsnÙ,³qò„OL1å ñbnUo;'µþˆ¹Òi}x3Är0'ˆ¹¿æsÃXŠ©‚6æÁQÎÐ$Ö»GÄbo­› o«ð\)ò›T0IC0 ÿl¤ƒû³ Û‡e¦VÆ4× Q£|0z0U#0€! µvvÓ³*¬&üª¦OòÖ¡oK0U8­%ÈBZ× éJôæ,¥S¤PôL0Uÿ0U 00  `†He00Uÿ0ÿ0  *†H†÷ MÀ×]Áxy0ebbÚ0-p©nÈlSÍ'?íM”“J½¥í-ò •ƹ¥àû˜ ÙyªŒÀ[¢‘ãZ5Kúšy¾ÒšVz$ç"~Nß²2pöÀ)VQ…«ŸÞŸÜNFzEÌ'”>|ÄɱËÒ^Ó!Sä7>žOå^5ÌSibouncycastle-1.49.orig/test/data/PKITS/certs/AllCertificatesSamePoliciesTest13EE.crt0000644000175000017500000000125710350736725027634 0ustar ebourgebourg0‚«0‚ 0  *†H†÷ 0D1 0 UUS10U Test Certificates10UPolicies P123 CA0 010419145720Z 110419145720Z0h1 0 UUS10U Test Certificates1=0;U4All Certificates Same Policies EE Certificate Test130Ÿ0  *†H†÷ 0‰ž‘ ÷¸—´P‹í=È'J*ô¶ŽÅ.áãnÍ8Q ¥´qe·7âdÖ¹*¦žmZ^¶ýràÅ8Õ‘/Eö –³o˜àU÷¡´¡«,$ÉÛ3îðh‹‘]¯è*ÒïÈyÍÒ ôt°—–")P–L ›øÜ5? îÝâô,êmŸ£ˆ0…0U#0€п͛ßñ‘ý‚‡Zϯ‹¼òÅÌ0Uj”m­C) \ëK z¢À«#‘ÿm›0Uÿð03U ,0*0  `†He00  `†He00  `†He00  *†H†÷ uv"†¸è3µ¾›Df)nëÈIóÃ…hë,ì-"Sy~/ÆCrtEÎú•®`ÉFÑÁ}sM’‡,q6„Þ-’°%G¬QP”\oT ²j3;©í›…?ØwúÜbïQ·Ýó´,J®¢B-<ȘUÆÅµ¦é&nŽì‰bouncycastle-1.49.orig/test/data/PKITS/certs/InvalidonlySomeReasonsTest15EE.crt0000644000175000017500000000121510350736724026742 0ustar ebourgebourg0‚‰0‚ò 0  *†H†÷ 0G1 0 UUS10U Test Certificates10UonlySomeReasons CA10 010419145720Z 110419145720Z0a1 0 UUS10U Test Certificates1604U-Invalid onlySomeReasons EE Certificate Test150Ÿ0  *†H†÷ 0‰–̧bõò¾_ªíãgCZGE<ØGxзI(ÔÕ@°ÇGŠ`¢Ån¬‘n­Ž Ž­Üq“þ <#ËOçK†ü"Åæ!‚k7›ôÉúi×yºùlr7>1zÔ,?˜—¸äþj°ñvé§¼”mÙCÀêÃõ±Áõ’Ög¦Ó¤´ Å£k0i0U#0€àbšßP½[Iþ¾pÌÜ9n0Uª„1¹›‰ÓaÌø¨zïm‘µ#}90Uÿð0U 00  `†He00  *†H†÷  ŠŽ œ0/àvŒ8=;ù?Æç>@6: 7í8.›=ƒÁUÃ!>ÔAVy‡6^^y–¬¼x° “aŒÈ^™y,¿ŠëZK뗦⻠B± •Íóæc.ÉSwÎ_ä˜6ÃG[ѽ_Dkù"!;ÊznO®ùÞoâbouncycastle-1.49.orig/test/data/PKITS/certs/ValidPolicyMappingTest14EE.crt0000644000175000017500000000122210350736724026023 0ustar ebourgebourg0‚Ž0‚÷ 0  *†H†÷ 0O1 0 UUS10U Test Certificates1$0"UP1anyPolicy Mapping 1to2 CA0 010419145720Z 110419145720Z0^1 0 UUS10U Test Certificates1301U*Valid Policy Mapping EE Certificate Test140Ÿ0  *†H†÷ 0‰°Ò-LÆ©!1ÆÎDQ.æN˜á å:Òtÿ”+l~NdËž8E-4ÏÍõU®{£`òÐüØ–m> <ôû‡r2-‡ÝïÿnÙëA“G“Vûì ð2‘©mOYÆG_zɦ=c6$zÙ¿Ã?¶„8 •È“³çõl_ä”q£k0i0U#0€-7Ò?žYÙæ¾W¢÷k‚¦­î0U„‚üN9À‹ñö"’&u¤öh0Uÿð0U 00  `†He00  *†H†÷  öÔ}Œ¿Þ»ý#~0±†}Θ áT¨¼¸iIň'5Œüü®<¸²bR“­5lYù|í‹)$¨pqý{5Óû¨ïhÙMwl\“ÝK*xDxß=ͯEn±Ò Ä0 7iŠôIÎõÛbouncycastle-1.49.orig/test/data/PKITS/certs/PoliciesP123subCAP12Cert.crt0000644000175000017500000000122410350736724025207 0ustar ebourgebourg0‚0‚ù 0  *†H†÷ 0D1 0 UUS10U Test Certificates10UPolicies P123 CA0 010419145720Z 110419145720Z0J1 0 UUS10U Test Certificates10UPolicies P123 subCAP120Ÿ0  *†H†÷ 0‰ée'mVºP÷ìÉõ­]µ8‡§îs&nÝÚ"•M9ÔÆÒëq' ˜çRmé®P&$ð¶¶àuîšI>6Y HîÇ+bÉ®àÃ9á¥UµYHh“kã•<àùƃp K5ƒ`Ë4Ø x6¶Å85ÄÈ ‰î»O'/BŠÍn³PÑ£‹0ˆ0U#0€п͛ßñ‘ý‚‡Zϯ‹¼òÅÌ0UZ‡!ûÜ“mš |Çj±hKßU×0Uÿ0%U 00  `†He00  `†He00Uÿ0ÿ0  *†H†÷ ?@‰26Ö•9E£øõ®Xu8rA#/áハ¸q¶àíÓw©¸Ø$Ô®äÖÉœ¥*«Kz·­Im÷Ó¾ô‘je%ü,%Q2 2Y)pÊg^cƹ´÷ÖEêý¿‹HÙ4¯[š_óò# wç“ðgq ~&€;îö$p-´¹Í.bouncycastle-1.49.orig/test/data/PKITS/certs/BasicSelfIssuedCRLSigningKeyCACert.crt0000644000175000017500000000121610350736724027437 0ustar ebourgebourg0‚Š0‚ó 0  *†H†÷ 0@1 0 UUS10U Test Certificates10U Trust Anchor0 010419145720Z 110419145720Z0X1 0 UUS10U Test Certificates1-0+U$Basic Self-Issued CRL Signing Key CA0Ÿ0  *†H†÷ 0‰ŸŽ\ !i¾M¬§¿íüýXhC<Äù¥ËbTZxW í;+ühSe©ó»‡Âz&: Yµ7+v!ÛDç×ÍäÇ(eŽéI.ï;€å-è¹S0Ey¥!4ÜoÂœÅæä;Å…1;^$ÆßèÉèI/SÙãv9R‹r×ü_B5£|0z0U#0€ûlÔ-žÊ'zž °<êš¼‡ÿIê0UIÉü·jc_`›WòÛ/-¯ÁГ_`Îð#b˜å*C2É ÏÝÝlŒËy €ªtÕJ¸$>Oòvìo=H›¬e$Ivd¢â]aÒ9{@vx!Äqè4–…êKGj¹a0È¢! ßèuŽ¢6pbkÓj<Ü'^R)£¥0¢0U#0€léÇ B@AõópŽîáÑR^×7Z0U0±¯Ü®Õ0ò 9¦ã,!8¯¢‹Ð0Uÿ0U 00  `†He00&U!ÿ00 `†He0 `†He00Uÿ0ÿ0  *†H†÷ ©ãN§/r É~Z #°YcÝ“®4‹4€³çÎ,<×bA[ > ‚ŒÎüÈËúEhéÑ—_u k!»ù”N§QYS$×#äʺèÓ,uQlÏšeDe áŠD÷Ò°ŽJ(üÎú¬1ÕT^Uó\ÁÈ%È¥È HÇLÃ,A‡bouncycastle-1.49.orig/test/data/PKITS/certs/InvalidcAFalseTest2EE.crt0000644000175000017500000000122710350736724025017 0ustar ebourgebourg0‚“0‚ü 0  *†H†÷ 0Y1 0 UUS10U Test Certificates1.0,U%basicConstraints Critical cA False CA0 010419145720Z 110419145720Z0Y1 0 UUS10U Test Certificates1.0,U%Invalid cA False EE Certificate Test20Ÿ0  *†H†÷ 0‰¥€¾r *§/Å]M#U˜8ˆ )šŠôxòh‘PdñwnÜ…/Í®+ù¹œ'Þ«F"Ò”-‘*yœu²¦Ú€Ë!b±Ã’{gE(eÖ[‡ãFÿEÕ§Ñ)äYÆ"æS™ÅM^-Ðé yLÐ2Ó#-;ê-ÉÊkdG£²z5d3£k0i0U#0€ÇGOt"‚š”˜E³µCÃu6Î0UÐÞ7*7@°äN¢äÏ䤠j4ÖÌCѪxlhÏ|ºÒò‰•­Âˆ8là¨EM=ñ&·öYÇ„…‘«ŸíÞͰÞ5ÉšZ¢f²K8¡[¯:EÊKî[’.¹WUtõ‡gV#O¤5 ¯>/÷£|0z0U#0€ûlÔ-žÊ'zž °<êš¼‡ÿIê0U7—¤Û4U5É´MÆ~K褉<0Uÿ0U 00  `†He00Uÿ0ÿ0  *†H†÷ Å_xý2tíõaÏŸðèþ¡+h8Î3TöÏÁ’±Íá`ѨäGZ~T±³ ϧ٤bouncycastle-1.49.orig/test/data/PKITS/certs/requireExplicitPolicy4subsubsubCACert.crt0000644000175000017500000000123710350736724030461 0ustar ebourgebourg0‚›0‚ 0  *†H†÷ 0S1 0 UUS10U Test Certificates1(0&UrequireExplicitPolicy4 subsubCA0 010419145720Z 110419145720Z0V1 0 UUS10U Test Certificates1+0)U"requireExplicitPolicy4 subsubsubCA0Ÿ0  *†H†÷ 0‰¸Ø«$Ýã€ZýA䟟á1sž§T™ wWŒå*xE%ßq“w±QÂÙw9ìC7…`å›Z[˜‘¥Ü6©rªL–íBj:u“ÎA‹lš„MpZf5äÔ£;=ÓAedÐø1¾ˆitóü,°°ÜÐRTç¤nÃ,Î}ýÑp‹£|0z0U#0€¾l¬ LS”¸ä‘#¥«c0U÷„+ݱû•ºzZbàs1²*Èy0Uÿ0U 00  `†He00Uÿ0ÿ0  *†H†÷ ';ñ1Y—’Ê“;`ØŒqj¤ìjL¹èÍL¨E ¼p³}Û$fNù–{ŽÅ¶DYÏýü€ßOù4Õ¸=‘óäê%¡vò8:u?ê¤Ü3›1t‡èœD«z 5õ”C\ïúq~ì¿ÈêØ§ÿí¶¶eë(Ÿ÷ ¥­„±Ma$}»bouncycastle-1.49.orig/test/data/PKITS/certs/ValiddistributionPointTest1EE.crt0000644000175000017500000000142710350736724026724 0ustar ebourgebourg0‚0‚| 0  *†H†÷ 0I1 0 UUS10U Test Certificates10U distributionPoint1 CA0 010419145720Z 110419145720Z0`1 0 UUS10U Test Certificates1503U,Valid distributionPoint EE Certificate Test10Ÿ0  *†H†÷ 0‰Þ »;M >õ&ËWÀwŒê-3Æ|u“±e7±“iB¨‹á8@±#Ámü`™o‡ý§)ÞË)'¥ŠÑ>Ýõ–þ¢Œgý¹Zî=¢Yûàš$6P™­ºÊ:î[ ù_U`¢èqƒŽÙI¬q›¾»ø]r/_b’²žÝ¸Ô5Ú7'£ó0ð0U#0€žPWj…oøæA^ëzº0~ºô0UjàI… »¼bä‘KŒò•Çùñˆ0Uÿð0U 00  `†He00„U}0{0y w u¤s0q1 0 UUS10U Test Certificates10U distributionPoint1 CA1&0$UCRL1 of distributionPoint1 CA0  *†H†÷ hÚ'¯ÏM”#Ÿ€ ð2øþŽÿjd(žg†*À»õ¹¡›§WH–/&£Í RV)š²š -€,1‹¥Ô[.ÚF¦ÒD ™lÇ5*Æ ÌŽÖ÷èÐvN÷‚ÅRTŠ°Þ”·Wq\Ø^o³ `X([#ÍÏJÜoè²éøèËü~9Ôbouncycastle-1.49.orig/test/data/PKITS/certs/MissingbasicConstraintsCACert.crt0000644000175000017500000000116410350736724026743 0ustar ebourgebourg0‚p0‚Ù 0  *†H†÷ 0@1 0 UUS10U Test Certificates10U Trust Anchor0 010419145720Z 110419145720Z0O1 0 UUS10U Test Certificates1$0"UMissing basicConstraints CA0Ÿ0  *†H†÷ 0‰Î÷"® ëºvÝ íE`Îö·½d‚g«¤¡罸Lusož<É͆ b‡ I–x—|„Àp‡­e¦H ³š$°‚·ØÍ+[˜=ÉÏ­Ú‘|aæ\À¿ ÿýj4ƒ9ê¾}`ˆ‚·r ï@Y,]#¬"ÞJ¤j§;i£k0i0U#0€ûlÔ-žÊ'zž °<êš¼‡ÿIê0UF ]7Ò©“E¬í\1çÍö0Uÿ0U 00  `†He00  *†H†÷ ˆ¼‹ó˜Â0'ÆâñOÓÍvrßɲªÝ}¶Ñ©¤p¨¯* /Ç‘Ђ?©FåôÑ,Ï /{®é}d<'¿ó™©¾[žÀ¯u¡±&@îú-Ù÷f¬#{þ¸|é[jHÞk„‹˜ÔŒ²5ÅÌd…OkV'UÍ|PôF Iæ‹bouncycastle-1.49.orig/test/data/PKITS/certs/ValidBasicSelfIssuedNewWithOldTest4EE.crt0000644000175000017500000000124210350736724030146 0ustar ebourgebourg0‚ž0‚ 0  *†H†÷ 0P1 0 UUS10U Test Certificates1%0#UBasic Self-Issued Old Key CA0 010419145720Z 110419145720Z0m1 0 UUS10U Test Certificates1B0@U9Valid Basic Self-Issued New With Old EE Certificate Test40Ÿ0  *†H†÷ 0‰¢A|¬R¿ÊLP:ÔÛÉæ'\ÚC‹RZö7,uX­ÊM40!*B蕯彨‰ "ûÿx5 y<'E–“°†Ñ>²u;Ý1$6 µø×>ÄZ8ãtbouncycastle-1.49.orig/test/data/PKITS/certs/ValidDSAParameterInheritanceTest5EE.crt0000644000175000017500000000106610350736724027620 0ustar ebourgebourg0‚20‚ñ 0 *†HÎ80O1 0 UUS10U Test Certificates1$0"UDSA Parameters Inherited CA0 010419145720Z 110419145720Z0h1 0 UUS10U Test Certificates1=0;U4Valid DSA Parameter Inheritance EE Certificate Test50“0 *†HÎ8…΋6Ø\DAÇêš°Ø”9E³I´lf½Ö°ë‰¾~[ÐÛ3!ƒJ’j×vÒ£ÈKÇ›•|Kä×4šÖ±ýß´Å*Ôm›È¬g+æØ%²a^ëï|KP%uh5ÞàþQ~l¨ÚÑ?4ÃÉ_ö+KÉ1\Ææ[8øXnX•×_únüO£k0i0UxB2Rd€ë&º)íe•¿*0U#0€]$îŠUòÆÉ²Â¿Šð²IO:³0U 00  `†He00UÿÀ0 *†HÎ800- |ˆ«›) ©6ß ¾‰öË졺`ΉÞg©‰¸¡5ûv''Žý€ôÅëbouncycastle-1.49.orig/test/data/PKITS/certs/SeparateCertificateandCRLKeysCA2CRLSigningCert.crt0000644000175000017500000000117610350736724031634 0ustar ebourgebourg0‚z0‚ã h0  *†H†÷ 0@1 0 UUS10U Test Certificates10U Trust Anchor0 010419145720Z 110419145720Z0Y1 0 UUS10U Test Certificates1.0,U%Separate Certificate and CRL Keys CA20Ÿ0  *†H†÷ 0‰OÀn‡ü¯cŸC+îèyÏO&Ù‹î?å5UÙ‘³“àí¸[bŸ86™EºË…Á|jÕ"—…c´îåDþí%M~ÂØ}x†|øÌôÿ^n¥˜7RÏÛ-*·2` e‡”˜ÿóêwéþPâÆgœÆ»¤VÓ} JÔšN¬(–[âׇ(A£k0i0U#0€ûlÔ-žÊ'zž °<êš¼‡ÿIê0UUüÒÚ«dòa7)žÓ(Ïa*§0Uÿ0U 00  `†He00  *†H†÷ @@ùW‘º¸qã9²ÄÞ-°Í—»ªûlö¦¥NÇI§Ãkn.‡!„¤ž¤É!'Ùµ©§w¶¹Ê‡¯bþ Ý©~n^&Èái_Q}ò€V¿£.•ÉfL‡Ôœ]ލ Ê'i&„i.19›ÙÌÔöÑÂës_¦ÍAKà e°te¼ßßbouncycastle-1.49.orig/test/data/PKITS/certs/inhibitPolicyMapping1P12subsubCACert.crt0000644000175000017500000000132710350736724030013 0ustar ebourgebourg0‚Ó0‚< 0  *†H†÷ 0S1 0 UUS10U Test Certificates1(0&UinhibitPolicyMapping1 P12 subCA0 010419145720Z 110419145720Z0V1 0 UUS10U Test Certificates1+0)U"inhibitPolicyMapping1 P12 subsubCA0Ÿ0  *†H†÷ 0‰˜‘´å\>Ó¯}ëÆä3WË„ôEÀ´Ÿ¥qVúÅ! ©•"•ÊØ-7ò/÷M®¾zˆ‚v4ú’ô0°Ïn0g»ž?0ó¦D„sá§£npû¢Ï¬aA'BÍ£¬—¾Åw TÂ"4?·~èlòtäüßS¨RœÈã¶2¹„æ¹£³0°0U#0€zŠ0öê\6@ ®ØŸ¿¹½‚ÌR0UZ“Kï–ž®>C&¤y‹¢æ›!0Uÿ0%U 00  `†He00  `†He00&U!ÿ00 `†He0 `†He00Uÿ0ÿ0  *†H†÷ ¡ý“;›bô;ÅéñyU!cœeN4NÐqÓ§Cž±&Ž QùL£¯ÓôëzíYÛöh3Ád„\ Ù¶ÿpÕGZ+wõ dRžÃ‰elÉðE.^ß8ê,k yi6eÜ£ =¯˜¨…%þ®Qïh¹>çGκ”Õ©c8{³ö(§Ybouncycastle-1.49.orig/test/data/PKITS/certs/ValidRFC822nameConstraintsTest21EE.crt0000644000175000017500000000132010350736724027204 0ustar ebourgebourg0‚Ì0‚5 0  *†H†÷ 0N1 0 UUS10U Test Certificates1#0!UnameConstraints RFC822 CA10 010419145720Z 110419145720Z0f1 0 UUS10U Test Certificates1;09U2Valid RFC822 nameConstraints EE Certificate Test210Ÿ0  *†H†÷ 0‰šåNÃú‚W¶¹§ 2O}ýž¨7Um î©’ ¨Ësm÷>Ê6š„M~¸²œ!Ï÷›Ü„V’R¶ê£ù›qÿÆØ½þÎLv·¹-<µ×š·Ó„»(®„¯Úz~zȪÇ:å/ú©ŽIŠjd¬"eºˆº¿ÆÔ}ŒzÍ£<Þ}T£¡0ž0U#0€ã…zŽ¢;žî¸yªÄ½.Y­0U´ BÍ•ê‡ÔcÕOÖÑå·;û0Uÿð0U 00  `†He003U,0*(Test21EE@mailserver.testcertificates.gov0  *†H†÷ jC=Ì©ª"Ù >ê+§N².Ê Ó÷_ç8ÊnÉ?MøÚF!'´¨dY…l„Aë>;Ø¥›%Í{ ÏK+¡Ž·OB… 5¥šîxC¬+üZdwìQðnC\Fˆ•ßÿòƒþnuãbãÜïR¦å2ý­önË©£L¤XêÃ5žÙ¢bouncycastle-1.49.orig/test/data/PKITS/certs/inhibitPolicyMapping5subCACert.crt0000644000175000017500000000124410350736724027020 0ustar ebourgebourg0‚ 0‚  0  *†H†÷ 0L1 0 UUS10U Test Certificates1!0UinhibitPolicyMapping5 CA0 010419145720Z 110419145720Z0O1 0 UUS10U Test Certificates1$0"UinhibitPolicyMapping5 subCA0Ÿ0  *†H†÷ 0‰ÜÉkm )Ž¡‹SMÒ¬\ÜAœ­ÎÄÔäº&X lñv¢k±Têxv#<çA|¬V•¦¡é8Ž„•g5+ƒØTß §ûå^®œTt‹ľ›M–·ñ»G‘ʆ0WñÃ÷ù×o€]·O]k¬FÙAJÆ{› ±Pñ1ôWa «lº·£Ž0‹0U#0€@¿p.8ø¶¯§ZÙ²CY˜õL0Uït]½'!\mwD&mÜ¿û¾ck 0Uÿ0U 00  `†He00Uÿ0ÿ0U$ÿ00  *†H†÷ Mg‡U–‹£ßC¶|=ã_%Ë5Nó–êßÖ-nŒëãBÿCÃÈR\y•À톲›å.`¶aõÙ)”¹ª³‘“äI|Ð ´‚Ê‘¶ÒÐì4Þÿ¶#Ö¼¼v7»Bö¦ìÉCYuEx‚¤€€KöaWokH$«»çk·bouncycastle-1.49.orig/test/data/PKITS/certs/nameConstraintsDNS2CACert.crt0000644000175000017500000000125610350736725025702 0ustar ebourgebourg0‚ª0‚ G0  *†H†÷ 0@1 0 UUS10U Test Certificates10U Trust Anchor0 010419145720Z 110419145720Z0K1 0 UUS10U Test Certificates1 0UnameConstraints DNS2 CA0Ÿ0  *†H†÷ 0‰Ùž|TEH+jLȇ󉻒׿V…ï®dsôNÇ€PbàTeèchÝáïӮ洉nz2.—oÑuo¡‹ò¾ö"­éc…Ì̤Û{Àv­€‰—ýœÿ)žÎS™$ir?k{û3@*Mi¸SÛ•Œâbç3Õ9÷~ƒ±£¨0¥0U#0€ûlÔ-žÊ'zž °<êš¼‡ÿIê0U~Ü;êޜқBDï{Ín’à´0Uÿ0U 00  `†He00Uÿ0ÿ0)Uÿ0¡0‚invalidcertificates.gov0  *†H†÷ zL)µç›q1ÉÝÓ¨Ù•0i&¶2ÐehåMÉh¿BÈ2ü³¹Yï@†J¹éYJ…“X!Av¶Ûž$Ô:`ã@ñ€Cb˪ôª*¬œ³æ¥7‚N8ËJ6æÓœªHXÖ¦Á¬I¹}éiåÚÛ'+=î`—nn×6¨ÙÛÅA·“tì¬S˜ÔºêËq¡ÏÎ]«r8+Žâ»ÞwÛs­ ݦwzf«§÷û¼¯="œÅ2Þž«GÑbouncycastle-1.49.orig/test/data/PKITS/certs/InvalidpathLenConstraintTest10EE.crt0000644000175000017500000000125210350736724027236 0ustar ebourgebourg0‚¦0‚ 0  *†H†÷ 0Q1 0 UUS10U Test Certificates1&0$UpathLenConstraint6 subsubCA000 010419145720Z 110419145720Z0c1 0 UUS10U Test Certificates1806U/Invalid pathLenConstraint EE Certificate Test100Ÿ0  *†H†÷ 0‰¯DŸ€ýâDJD¦ŒKߌ@èòq29ÀÏØõ…ÐèMºgtK|ƒ- ·ì;ýgÑ¢úïN’ksjV€~Ø{RT)à |;txh›ÛÖF樘èòmràžB©wðï;«@ßéÔ|ÓˆZꇖ)ALû£µ×àív[™£|0z0U#0€jæÅAm­>‚ܰ]­òñPÎ 0U» K;üuø`'s1Em;[L ©0Uÿö0U 00  `†He00Uÿ0ÿ0  *†H†÷ 8ƒ^ˆÂ-4t /ãz³ ·xè;¹¦ƒíø V~ѬF$ÉÍegõ?žˆ]ïZLÎ5yY¢Ôü›–Ftiqý{´¡håµÔ™8:’)ÇëÑìzm2¨…ÄKz[¥fÛ¨#Õ`î«J¦Í>“/—ÅYBOߘ.OT¦ ¢åýGlbouncycastle-1.49.orig/test/data/PKITS/certs/onlyContainsAttributeCertsCACert.crt0000644000175000017500000000120710350736724027443 0ustar ebourgebourg0‚ƒ0‚ì O0  *†H†÷ 0@1 0 UUS10U Test Certificates10U Trust Anchor0 010419145720Z 110419145720Z0Q1 0 UUS10U Test Certificates1&0$UonlyContainsAttributeCerts CA0Ÿ0  *†H†÷ 0‰´‚'³'A$Ÿ©ýܬ…P”Jè%z1"ÚÚßIš ¦î¬AŸ>ˆ/ ¯uƒöïO9ÛîÙ팟•D¥Ú T%ä´©Ó%­ ‹3ò. Í2¶ÆêxÇ=WjÖ}ÛÇ©ÂðÕÙè[wW*»ØuoìN…Ñ£¸×mz8Uó£|0z0U#0€ûlÔ-žÊ'zž °<êš¼‡ÿIê0UÅ(•›Ã£Ù¸û¶ßmãS­¹"0Uÿ0U 00  `†He00Uÿ0ÿ0  *†H†÷ #ªÙ™Å¿lçU?:\ögƒ¬’†³yãU'B×½LÅÚö3¨W±âÔwßzÀ9¯Ak(s;|zӹ̗Hþ%í ­VÊ©’’HKè ÿÅaXBP1¾>êÉå5"TU3‘¿œM°If ¢&^ð9 È¿O«1¶^4·kÀ¥ˆ²bouncycastle-1.49.orig/test/data/PKITS/certs/InvaliddistributionPointTest2EE.crt0000644000175000017500000000143110350736724027247 0ustar ebourgebourg0‚0‚~ 0  *†H†÷ 0I1 0 UUS10U Test Certificates10U distributionPoint1 CA0 010419145720Z 110419145720Z0b1 0 UUS10U Test Certificates1705U.Invalid distributionPoint EE Certificate Test20Ÿ0  *†H†÷ 0‰ï~Ô;ãų[}mXˆ=WBú#ä([J7¨È²MÀ†ã1âŒÒIÌ<êL¨¡ëÃö¤—…¸xMmÙ–“3âL”¹5‡—]YOFš¸õ›×’¤=b²`g00úá×Q×·]ehC&È/¶¶‹¶—-8®™Ê(²ëMg|•²ôs&LpÝ¥£ó0ð0U#0€žPWj…oøæA^ëzº0~ºô0U ¼¶¹phCfªQíçÏ­UÒ›¥0Uÿð0U 00  `†He00„U}0{0y w u¤s0q1 0 UUS10U Test Certificates10U distributionPoint1 CA1&0$UCRL1 of distributionPoint1 CA0  *†H†÷ ÜCé× ûY%Û¶z¯ãÊWðN#T˜¶È„t-Ó‰ @ã^uð° x,×%¹/ϳÆž¼j‘r(³Ž6^áã[‘š-€ìöÄÝe÷¸û“µ&.ÂnãWnÔ€Xxd–3d–.w|Èhuó€´G´0„{WäŽmD“Ò8bouncycastle-1.49.orig/test/data/PKITS/certs/PoliciesP12CACert.crt0000644000175000017500000000122710350736725024133 0ustar ebourgebourg0‚“0‚ü %0  *†H†÷ 0@1 0 UUS10U Test Certificates10U Trust Anchor0 010419145720Z 110419145720Z0C1 0 UUS10U Test Certificates10UPolicies P12 CA0Ÿ0  *†H†÷ 0‰¹ºpŒ¸ß¹QVn¬Nÿ ÈBÇ">!(Ôj Z3:úFý—xzÁl–c ¬·g5çÊœ$¶=?”2wô˜Ñ;}ZQ×UÁ<¬ÊHi…Åò·ÝJ^ Ú°ÏÛ =%°fJ±ÚR?ÒŒÐ^ØoB}üJ ÃS´ kuOBL‹…1{Îÿ2Zs±£™0–0U#0€ûlÔ-žÊ'zž °<êš¼‡ÿIê0UãeéÔ†¹Ççó39^L¥ù0Uÿ0%U 00  `†He00  `†He00Uÿ0ÿ0 U$0€0  *†H†÷ ýÌ€ ÝÀo¦saé çØÂî" sý»®ÕÜD†ª ©ÄyòHJnÑòÇÆ+°œ©CRá{;rE¹“eMß]@¡sK¤ê¼$¿ë×üÉ‹ÂÈß÷pXän"b£ñoµ©*ª=í_¸ÞÓ±:‰4¡û¥µâùO矄§’%Åæbouncycastle-1.49.orig/test/data/PKITS/certs/anyPolicyCACert.crt0000644000175000017500000000120010350736725024037 0ustar ebourgebourg0‚|0‚å &0  *†H†÷ 0@1 0 UUS10U Test Certificates10U Trust Anchor0 010419145720Z 110419145720Z0@1 0 UUS10U Test Certificates10U anyPolicy CA0Ÿ0  *†H†÷ 0‰Æ8f íïuŒÊ£Cg¤õÍ6à…ß ¡º¢ ®.ý~•e› Àì¨b_°¹ú Y'•a=4—ЧÁŸ//d1·W¨BŒ–9]ÒÍû{?ˆã+‘ßrY§i*¦[gÊvNuƒp¼ YBx³Q (%áʼnÂâwÒ†åáý£…0‚0U#0€ûlÔ-žÊ'zž °<êš¼‡ÿIê0U>³ž¢äC…ûg@1†›Æaí†Õâ0Uÿ0U  00U 0Uÿ0ÿ0 U$0€0  *†H†÷ <'3ùšœæ…Ç*ß/©¶ã bG§Ã£™¡`C£fáÃY×£I›ÍµºO|ÙʘΖþ¢9îAPâ—ÓÿÄ¢ÁƒÉ¼©t¡ú'žOwëŒ>D6?6²sW ®àqäíÿzéÔH…èËÜ®Ò{ Ói_ˆYÑÕ0¤DŒåí©()bouncycastle-1.49.orig/test/data/PKITS/certs/indirectCRLCA3cRLIssuerCert.crt0000644000175000017500000000133610350736724026122 0ustar ebourgebourg0‚Ú0‚C 0  *†H†÷ 0C1 0 UUS10U Test Certificates10U indirectCRL CA30 010419145720Z 110419145720Z0M1 0 UUS10U Test Certificates1"0 U indirectCRL CA3 cRLIssuer0Ÿ0  *†H†÷ 0‰˜wDNDÜG;BD|åI’`á§Ë€ãóýÊ™@‚(Šâ'ùOM-ÞGù™t??`GÁˆÔ““e¨:–dÛËt…vZs°ZÿêäŠî ÍØ¯§àJH“+2$õã9(Ûþ®•s-×)cÛÏú1çㄾ}…GÕY7¿E²qÔÚ´2ü›‡g£Ó0Ð0U#0€–(¼)¦­XŸg.ÇÂÁ—:ßîˆë(0U±!K²’¨ 3N+‰gO¡OŸ0Uÿ0U 00  `†He00eU^0\0Z X V¤T0R1 0 UUS10U Test Certificates10U indirectCRL CA31 0 UCRL10  *†H†÷ ln¥ U˜ë†Ì«j+^t¼Gû ªsù—~éó·DLmÄF äÞœ4…gg¥ÏT´ áî¤wÆq=øÞiMk–{‘²M;°ñM£9¢ñ‹/Ñ¥ÿ›Ú°i®ýtAï>Zô›çTÑñOý—¨Lœ+ê&3œ¤õ'?­8­g«bouncycastle-1.49.orig/test/data/PKITS/certs/GoodsubCAPanyPolicyMapping1to2CACert.crt0000644000175000017500000000127110350736724027737 0ustar ebourgebourg0‚µ0‚ 0  *†H†÷ 0;1 0 UUS10U Test Certificates10UGood CA0 010419145720Z 110419145720Z0V1 0 UUS10U Test Certificates1+0)U"Good subCA PanyPolicy Mapping 1to20Ÿ0  *†H†÷ 0‰јéJ•'ÚÜ©ÞÖ‰„·¼V„ŽÂVçߟ¡TïÛü¿È°OÓ/ ÀkbæF¨oày“´üª3N·™%¾½P5°0êÿ4®i‘-J5þÂ%•ºýÓ¡¬ŠòŽ‘ .uwÆ0 †a͸EÒḓ••Qrj,ú¶È¼$öu£­0ª0U#0€·.¦‚ËÂȼ¨{'D×53ßš”Ç0U‘×ᵤ–‘ñ¢q/fÙ'{J‚“š0Uÿ0U  00U 0&U!ÿ00 `†He0 `†He00Uÿ0ÿ0 U$0€0  *†H†÷ M¹v ¾§Áìý'ò¸e˜V¤Ãèÿ´,£dº ‡´O)‰+úœ9ÏÁëH¥´$lKjù]ôd¨êÿ´r{SüŽÜ›ÒJ9s*}ùàóK˹P”ÃÁg?—”€ÒÇIÓOÒÉjfÂË?¦ OäúþsÕiŒÕchWÊŸ!$ûƒÂbouncycastle-1.49.orig/test/data/PKITS/certs/NoCRLCACert.crt0000644000175000017500000000116310350736724023014 0ustar ebourgebourg0‚o0‚Ø 0  *†H†÷ 0@1 0 UUS10U Test Certificates10U Trust Anchor0 010419145720Z 110419145720Z0=1 0 UUS10U Test Certificates10U No CRL CA0Ÿ0  *†H†÷ 0‰¯Ž¾üÌoÆ¡¶g)¦âþÈ®% »êN@<'AÞ Ò'<åaâ¼$ û¸µ¤A`¢Ë=18!îœ.DyÖT5A},\ k)‡‚¨´¿³O¬hät?bÚ »¿¬ ìÙzí+Ãx¨˜:-ÖZHÔyóPÎé‰T>œ7¸&fæï£|0z0U#0€ûlÔ-žÊ'zž °<êš¼‡ÿIê0U¨óœNh–E̘}Èx?õ$0Uÿ0U 00  `†He00Uÿ0ÿ0  *†H†÷ ƒŒ…*ý^²Öž/Äï€×f˜Ïë$ox}‹«`Œ; © TØ~éªE°›u’]Ý•¾8Q8 œ»«…¹‚fH [Ô[Õi”‰·k¢:vb9êvy¬/‚d¬Í÷C£È0ŒŸ¯Àü#RÙ$nÙCYû>™¼uoÛKï$jtŽbouncycastle-1.49.orig/test/data/PKITS/certs/ValidSelfIssuedpathLenConstraintTest17EE.crt0000644000175000017500000000123610350736724030707 0ustar ebourgebourg0‚š0‚ 0  *†H†÷ 0L1 0 UUS10U Test Certificates1!0UpathLenConstraint1 subCA0 010419145720Z 110419145720Z0m1 0 UUS10U Test Certificates1B0@U9Valid Self-Issued pathLenConstraint EE Certificate Test170Ÿ0  *†H†÷ 0‰ÍÂ×ó»U¥ Ë·CAµãœÛÑmÂöm¿Î§ ÙI÷X TÔ«XÊvEœQòX~aí|„A4€äÎþÙ`K4ÊZpáÒ¡Ëô–ÞàÍÒר}â“ÞòÓùk%ê¸EÓª,|ÛWzÉ£NpmÞ(­_Pä? 㸙ç(í£k0i0U#0€UQÆd^ õ%ÆÍ’·š·™±80U:Z#ñäø$gÝØaÌ7Ä_]ë»0Uÿð0U 00  `†He00  *†H†÷ <‡\€‚d (ÓÃÔÊ5@_ÛÃqvAù´ÁÞ9Û q9Í(éµÚ>k K¦t0ÝÚì5ÔÜ€S„²UöŸ‰Ì?Y#§ ÏHÖv?­Å¿?ŽT„¦SŒÖ/ò×¥õŒ¿8b2ó…¯Îaƒª$+ý3…8Nbouncycastle-1.49.orig/test/data/PKITS/certs/InvalidEESignatureTest3EE.crt0000644000175000017500000000115610350736724025676 0ustar ebourgebourg0‚j0‚Ó 0  *†H†÷ 0;1 0 UUS10U Test Certificates10UGood CA0 010419145720Z 110419145720Z0N1 0 UUS10U Test Certificates1#0!UInvalid EE Signature Test30Ÿ0  *†H†÷ 0‰˜¸J,dÉhárç,\ôp(R–‹"B”ôgJwÒÜÛB ß7K¹¼Ys†äA¡Ú Äœñ4Ÿ–³~΃ãã —#Ü'Qk;´ˆsõJ-Z½‡#T2ºäß ²&¬÷°Ñœþj<ç·Øƒ)µòn:uüÇn‰©s£k0i0U#0€·.¦‚ËÂȼ¨{'D×53ßš”Ç0USûšpËrOyíSñû‡ÿ?ËLy·0Uÿð0U 00  `†He00  *†H†÷ Gcgó&¶SF:j<¼sS¶@ä½;ý5e6?öæ%КɱóxZ\Z`ËREÄÉqä½ü«iù5Ç~xˆ‘~5»\‚QõF–Dªäõ>©oý¯¥(ê‚Wø&àµWݪ?`Ê*a›ãýðû¶ÕÏÕ«ÜJܘ÷ñ”Hà¦<ˆoTm40bouncycastle-1.49.orig/test/data/PKITS/certs/InvalidcRLIssuerTest31EE.crt0000644000175000017500000000152710350736725025462 0ustar ebourgebourg0‚S0‚¼ 0  *†H†÷ 0C1 0 UUS10U Test Certificates10UindirectCRL CA60 010419145720Z 110419145720Z0[1 0 UUS10U Test Certificates100.U'Invalid cRLIssuer EE Certificate Test310Ÿ0  *†H†÷ 0‰Åëo›™j¬ îd?;½@³€/´;i_TÔ2ñH‘ ìûpPýÕˆ²¿rñ ’«’úê›I9!-$C¥w½VÃØŠá€¢ÄÑÕâx ¢ø31b£1Á7O¼ÂÖsÚljCâ_ ¼.5±Ã…ô%}1 £‚=0‚90U#0€Â>ªNÁ3ŠªYI±f¢ð}0U4I\ç¾.Q±íñXI&R!uO0Uÿð0U 00  `†He00ÍUÅ0Â0¿ t r¤p0n1 0 UUS10U Test Certificates10U indirectCRL CA51)0'U indirect CRL for indirectCRL CA6¢G¤E0C1 0 UUS10U Test Certificates10U indirectCRL CA50  *†H†÷ ƒÓõ -ÌùÝPœâ.K ¶ðÙHRN¨¼:3=e-nò‘ª¦¼’Ѥ[ßýË ƒmɲ˜PF•€ìœ3/×äv8ùyL¸²Á) €ì+"g6ö5=Z•ܧ‡ «!ÂàYÕ4®aÈOÙ¾ÿ"ÊvMõ?ÀwX©zœÑ-%Wµ†\žGÁlbouncycastle-1.49.orig/test/data/PKITS/certs/ValidinhibitPolicyMappingTest4EE.crt0000644000175000017500000000123610350736724027316 0ustar ebourgebourg0‚š0‚ 0  *†H†÷ 0V1 0 UUS10U Test Certificates1+0)U"inhibitPolicyMapping1 P12 subsubCA0 010419145720Z 110419145720Z0c1 0 UUS10U Test Certificates1806U/Valid inhibitPolicyMapping EE Certificate Test40Ÿ0  *†H†÷ 0‰Ì3Ftt¾wž&ž)ætëêmdÔømã=¶x¸• š½ªtš¼E"Yó kzq`+oÞ¤€£¸[Ig!-ýÀðöw v ‘kû²·%Õ%¢Ó›º\œ 1ÁŸÒ×#è¿ õ ñI•Ùf‘±«-P†Ú9>ÜUf¸!»“ÑÙ£k0i0U#0€Z“Kï–ž®>C&¤y‹¢æ›!0U gÓØ„4ØY‰“ª-Yá- ö0Uÿð0U 00  `†He00  *†H†÷ ‚?ªpÊE³$Þ0&Eáœ܈·EÔËjý#¼jë´™žš úʇ¢KæK!̦Ù´XªB"uVãb/áëwȸVfô•¡‰ø@ ÑÓ,÷ð+Ã`µ¦¤\å­¦‚-F×Í“Z!ö³öt?…¯6Tç–˵)mô¿(÷/oϯc+-bouncycastle-1.49.orig/test/data/PKITS/certs/InvaliddeltaCRLTest4EE.crt0000644000175000017500000000145410350736724025157 0ustar ebourgebourg0‚(0‚‘ 0  *†H†÷ 0@1 0 UUS10U Test Certificates10U deltaCRL CA10 010419145720Z 110419145720Z0Y1 0 UUS10U Test Certificates1.0,U%Invalid deltaCRL EE Certificate Test40Ÿ0  *†H†÷ 0‰¦]ùÁå6ýlN”DŠDYCu™ Â!Ý0O}VÊOb I$!Ø2‚&€À •ÇÇ:%Z8 —S‰W¸i©ÃÌúàak6Ò‘!%æQÞt–“¬méÂË|D†€ôÄæª¶r?½"z·"÷äφØT®hä;Çðf‘¹£ö—£‚0‚0U#0€“M¼ò× ® H¬º2 ×è Í0U™ÄtŠ‹%׿&Upáêòaè´a0Uÿð0U 00  `†He00SUL0J0H F D¤B0@1 0 UUS10U Test Certificates10U deltaCRL CA10SU.L0J0H F D¤B0@1 0 UUS10U Test Certificates10U deltaCRL CA10  *†H†÷ Uç2üÿP*®5‚üÏÂ6ÿÓ_ˆˆöùæ2Hæøz ­U‚¨ Ýaåß(áð+hK«>KìZb‘,r_yŽÕ0c¦¼ V•âËIïV„T `ÚáàoÔÓêØÉPŸ’ûZÆ$Yɬ¼~ÏÙVñX4£â Ž´uY='ÅÍ ^¾ïbouncycastle-1.49.orig/test/data/PKITS/certs/PoliciesP12subCAP1Cert.crt0000644000175000017500000000120110350736725025036 0ustar ebourgebourg0‚}0‚æ 0  *†H†÷ 0C1 0 UUS10U Test Certificates10UPolicies P12 CA0 010419145720Z 110419145720Z0H1 0 UUS10U Test Certificates10UPolicies P12 subCAP10Ÿ0  *†H†÷ 0‰©âèVßá”× J7Ôñ9æRâ‚ó;¾o»Uß ÛLSÍòßt^üÒö>fúª¢Ìƒ¢·˜xž/ Ûq©¯ QéOŒƒbŒtqnôéó&ºõ—FÍÏ´‰ÔâD{Q‰ÉvO9Ã1ÚÎ7Ö>Ù§;A#2H˜½ÔÛŠ@(:·£|0z0U#0€ãeéÔ†¹Ççó39^L¥ù0UBˆÁx·CÚ¯½ÞºC§åµaÿò0Uÿ0U 00  `†He00Uÿ0ÿ0  *†H†÷ `¥YS]†êW“‘bS ºcxÆÜ­p7¹ÐŽ –œ.û©€S~å°Hk]”«7yCTÔCök½Îâ|À¢Œè¶ µÿñDê¦âÙKÑú|F†ˆLÖ|Óo¿ÙkL,Y<Ìõ¸æxh´93´ }gók„j´Éâ:+Qbouncycastle-1.49.orig/test/data/PKITS/certs/InvalidDNnameConstraintsTest9EE.crt0000644000175000017500000000125510350736724027123 0ustar ebourgebourg0‚©0‚ 0  *†H†÷ 0J1 0 UUS10U Test Certificates10UnameConstraints DN4 CA0 010419145720Z 110419145720Z0~1 0 UUS10U Test Certificates10U excludedSubtree21806U/Invalid DN nameConstraints EE Certificate Test90Ÿ0  *†H†÷ 0‰¡ßäQ… ‘ج¸);rÂSQqŠ™ïýäëï¶ô,1T“FV#I){Z'ÖÍ"ó4Ž·£¡øÀ¥fªT^ðÀœÅªà/± âx¸½ª+WÔ¹ÿ¯€©yæ[îúLÿ\äßY ä1ÚÁœåg†ÊÉÒ&˜\z­QÌäC£k0i0U#0€3)茀L¦­'ƒ%gÅå¶vÌ0UYôWnc ¿¸1úC«PÅuÖµ™0Uÿð0U 00  `†He00  *†H†÷ j¦/.šÎfN Åû㺠t Ô¼7â'Û€½$rL·$t‚¯nú Ÿ\Jà±Jx}ñÕ«ãÄh±‡<ÂJ#L§+…‡Ëi Ê«ZN·^JÁp›ºËšƒ sö¹-DÑLÅ`öʾ×"IbQ‡_K¹9çý—¼+PÁh ˾$-½bouncycastle-1.49.orig/test/data/PKITS/certs/InvalidBadCRLSignatureTest4EE.crt0000644000175000017500000000121710350736724026433 0ustar ebourgebourg0‚‹0‚ô 0  *†H†÷ 0H1 0 UUS10U Test Certificates10UBad CRL Signature CA0 010419145720Z 110419145720Z0b1 0 UUS10U Test Certificates1705U.Invalid Bad CRL Signature EE Certificate Test40Ÿ0  *†H†÷ 0‰ ´»¹…Óý×rŸjƒƒ:9X’@ßýk\(€üèÁ0åó°8ˆc¦gâÄ“ Kj¶òasdT‰I }Ê•3¸äÖhËaU“àUž`WGAºoeY\uI€Ê&¸!/›²úKý«:«øÔ¬AÜžðSCèˆòk­wüü ô2õ£k0i0U#0€û ýº{æ8H™Z`UP—ª6lC0U+RúÛV “eë^v•doO þµ™&0Uÿð0U 00  `†He00  *†H†÷ 9*+4µ%¹Kç?Ïæ*¨z 4Q!)6žŠy”%غaw._v_óøKCŽÀ å”ÓCUîíø°Á‡ý¢³*caa­ÑN g%;Y‚¥2„G¸VŠúߵػzG„Ù¡)e§[ Ôþ«:gþ…+Ü7¯ˆ_úÊ­üAèøbouncycastle-1.49.orig/test/data/PKITS/certs/InvalidcRLIssuerTest32EE.crt0000644000175000017500000000152710350736724025462 0ustar ebourgebourg0‚S0‚¼  0  *†H†÷ 0C1 0 UUS10U Test Certificates10UindirectCRL CA60 010419145720Z 110419145720Z0[1 0 UUS10U Test Certificates100.U'Invalid cRLIssuer EE Certificate Test320Ÿ0  *†H†÷ 0‰Æ4­Xùã˜Fnt‹²®‚jê@Ë|ó”Ô‡IsÿkÁzv:k "§îL²!ðmþg‡· ô›òéìN¯É–ß¾²¸å>DÏh fea„°Rßw?/‹u'ЄùnI<Ð8a´,;øƒ.©ÌCrÏE%« E”èÔiPÞ‘©Ïÿ£‚=0‚90U#0€Â>ªNÁ3ŠªYI±f¢ð}0U!D¥3ERf ·n+˜g­Ûx0Uÿð0U 00  `†He00ÍUÅ0Â0¿ t r¤p0n1 0 UUS10U Test Certificates10U indirectCRL CA51)0'U indirect CRL for indirectCRL CA6¢G¤E0C1 0 UUS10U Test Certificates10U indirectCRL CA50  *†H†÷ ¦uêx³·hBVJßùgÉW[~´Wõn΋Œ!B¡ý@6œF}-W†œ …ítZv5­p6$rŠ8÷`0hSŒZÚxÝoßd áÑQÓÉ.Ihï (¢H}»*CüéV¦\¿îµá‚×Q‹.Äš¹mySÖR"P†ùëzbouncycastle-1.49.orig/test/data/PKITS/certs/indirectCRLCA5Cert.crt0000644000175000017500000000117110350736724024325 0ustar ebourgebourg0‚u0‚Þ X0  *†H†÷ 0@1 0 UUS10U Test Certificates10U Trust Anchor0 010419145720Z 110419145720Z0C1 0 UUS10U Test Certificates10U indirectCRL CA50Ÿ0  *†H†÷ 0‰±ë¿Y_ò6%ˆ‰£&²·+/Z­ƒnꀌîAB‚OOI„‡îTѲ¿+C¾> ƒ )߆€ÃÑ´z$’mÕÛÿ„·z©—Îþ\t>¹òÄmš¬Õ•ÒQú“$Ri ¸¨ºŒKÈ™Æ(Ñ ÌéÄmW 2S «;˜¶^üƒ£|0z0U#0€ûlÔ-žÊ'zž °<êš¼‡ÿIê0U”­Ñá~û7KA=mY€?DWm0Uÿ0U 00  `†He00Uÿ0ÿ0  *†H†÷ °!GíÇPóõ’³6Q2?í­·gë4šBù›õ°;Í.dšyt¿Ûм°w¨Zf Ñ›€#Ü3w•3mÚ’ˆæ8kõþÉì5[àdÄv`TkÅü Uy-ZP ¨Æ2o‘3Çõç/ÉÁ‡Þ¢ÙÀ=ǰ߰-)Mëbouncycastle-1.49.orig/test/data/PKITS/certs/AnyPolicyTest14EE.crt0000644000175000017500000000117010350736724024201 0ustar ebourgebourg0‚t0‚Ý 0  *†H†÷ 0@1 0 UUS10U Test Certificates10U anyPolicy CA0 010419145720Z 110419145720Z0S1 0 UUS10U Test Certificates1(0&UanyPolicy EE Certificate Test140Ÿ0  *†H†÷ 0‰¢ÂfqðÆo./¥ÊÙ³¿Ëx'êžðß^Z’„hœ±à¹Óð,¯7÷À´¬ 1Áƒf¶? Û½ÇhcêÄxñV™n¿•ٽ͹ÚŸŽq&zœ¦1Æh-?ÓkM†l1Z<¸ŸÝ÷0׿Ç~VåÚ#­Àw¸ •¥Z@ožex†]£k0i0U#0€>³ž¢äC…ûg@1†›Æaí†Õâ0U@÷}ï5\å2xÅQH(Øöà ‡0Uÿð0U 00  `†He00  *†H†÷ -±Ü¢eŸØy>fïzáÇÿ9¢bH²Hý6”¸ÈBà{o„|Å.a¾¥\-|uÍ;社» PV¡¬»Ôû7—å{œÿîTå“2.*0?á‚:Œ9•zVz:Í„!û†ÝŠg…¯Ö] ÊÃä¥9€:¸¯Ænh1€-·ç¨ˆ‘bouncycastle-1.49.orig/test/data/PKITS/certs/nameConstraintsDN1subCA2Cert.crt0000644000175000017500000000140710350736724026347 0ustar ebourgebourg0‚0‚l 0  *†H†÷ 0J1 0 UUS10U Test Certificates10UnameConstraints DN1 CA0 010419145720Z 110419145720Z0j1 0 UUS10U Test Certificates10U permittedSubtree11#0!UnameConstraints DN1 subCA20Ÿ0  *†H†÷ 0‰µä` ¢œ!à‡™ƒÇ,æ3çÂnŒI~8T=Cµ ÖXDîhh’Æ4ä­5ð ]‰ < ´.…¢©ï!$ M”Í(ˆ¸QÄÏEpШÃuJãŸ#´ú3¬ˆÿ³À?áW²£Úœ=ƒEˆøsX ))xSùz$ãû%zkDø ´%&K£Ø0Õ0U#0€N.£çÙÝ‹§‚;AJÞ|Y#WNS0UÕ¯k( ­Hl ‚*ÿÒh /mW0Uÿ0U 00  `†He00Uÿ0ÿ0YUÿO0M K0I¤G0E1 0 UUS10U Test Certificates10U permittedSubtree20  *†H†÷  7–-®¥ÅY÷i+_jcêççG}‡Khå9u"ªiÁç  wVBÔ1xCßq`qlMú—np_ˆ‰Çÿœ‹G-õÆ[´t CÈf¾ßÊQé ž'íTNèNüõ~þ@<€ é~>¼c/ëÖ#SÖ¯aäµ£åÖ–$_É{¾bouncycastle-1.49.orig/test/data/PKITS/certs/InvalidNegativeSerialNumberTest15EE.crt0000644000175000017500000000123210350736725027655 0ustar ebourgebourg0‚–0‚ÿ ÿ0  *†H†÷ 0M1 0 UUS10U Test Certificates1"0 UNegative Serial Number CA0 010419145720Z 110419145720Z0h1 0 UUS10U Test Certificates1=0;U4Invalid Negative Serial Number EE Certificate Test150Ÿ0  *†H†÷ 0‰Ҝ̾?7ˆëž,#êÓ»µ¼Þ¥koµ rµ‹ã e.NÚ©)¤fCí×kŽzh^OD™¡-B3šÉpó¨ï«‰÷‰Rô[è-†µ„;„PLŸŠŠmÉ]’þ]3,Ç:äg¿IzŸLQÖh™«Á4˜1 0 UUS10U Test Certificates10U Good subCA0 010419145720Z 110419145720Z0[1 0 UUS10U Test Certificates100.U'Different Policies EE Certificate Test40Ÿ0  *†H†÷ 0‰£Þëõ9ÍèÇûIzî!ñ–Hæ„âÕwýΧCߓ̛µ¼þg°ÁL1p­Ÿ©ÁòãÝ‹óNÊb½•$e€âŽëØ<$VK—¯¤oÚ}΄ùBÂXÛLqo”·Àã‰çqG' ÷G_QñÝÁÐ*q+ÊÖ…ÐTã®ÒÝÔ*,Å%©£k0i0U#0€|\i|ÈU±")CûÄ{êê¸}0Uâ2ZÂþpr„Þïœål“D‘”·0Uÿð0U 00  `†He00  *†H†÷ V€V0íc`·lÒ—=ÐЪøše()®ßºKBS ISüÊËæHQªB˜‹ ϶öÔÒ…7|7ÿC.W`1Œ@:DæW0 ¬žÄBD2gtvÜ)½ìx0ç-{ÍÅ5îu®ùå-êeFá4¤Yœ»õˆ<Ç(Þ“˜Š·÷$yyM Úbouncycastle-1.49.orig/test/data/PKITS/certs/ValidGeneralizedTimenotAfterDateTest8EE.crt0000644000175000017500000000121610350736725030550 0ustar ebourgebourg0‚Š0‚ó 0  *†H†÷ 0;1 0 UUS10U Test Certificates10UGood CA0  010419145720Z20500101120100Z0l1 0 UUS10U Test Certificates1A0?U8Valid GeneralizedTime notAfter Date EE Certificate Test80Ÿ0  *†H†÷ 0‰»ßKq6¦Á*àÿ±Ã¨[èví5_þ} Žœ¡_t+væYáTYÌ9d×糨ã5‘ìV’$÷\æÔ4(mûŸîäŽ>C™<7Õ”lfR¢?y% à®>YúíðÍoÌ·#ý4mº-c§ —(?ÙŽÛ2{xü1¬· Af×£k0i0U#0€·.¦‚ËÂȼ¨{'D×53ßš”Ç0U¢M²€àõÑ•7¼lZy<€ü“0Uÿð0U 00  `†He00  *†H†÷ ·ï·{\Í¢ooÑ¥P)0å šõ2ñ¿@ž&ßèê*;,¿ö´eÚˆg+ë§ž[´S2€áÀÀ¥$(É$ &úêA^|×VO&¸$>:íÆCj 4Òø÷áÏÛ$æidùz$ăΠŠÚs×DÖàO_„ÏaÞ#ŠNbouncycastle-1.49.orig/test/data/PKITS/certs/keyUsageCriticalkeyCertSignFalseCACert.crt0000644000175000017500000000122010350736724030444 0ustar ebourgebourg0‚Œ0‚õ 0  *†H†÷ 0@1 0 UUS10U Test Certificates10U Trust Anchor0 010419145720Z 110419145720Z0Z1 0 UUS10U Test Certificates1/0-U&keyUsage Critical keyCertSign False CA0Ÿ0  *†H†÷ 0‰¹¾/U ‘¾šø®ãt°w%ë˜oÚxOÁß3ÚŽ*SFðޝK=êÄg|ŠÇ ÅöH ›U]´Ú³‘2üÔô»1u E7|²‰Ó†Y¿˜ªJ¾6q¿P?‘bPKF±î7…µÌœð“¶ð·‚v-ÙIþ'U¼’zX” }£|0z0U#0€ûlÔ-žÊ'zž °<êš¼‡ÿIê0U”¼øœ|?è’¶MÉ´Ór1N:70Uÿ0U 00  `†He00Uÿ0ÿ0  *†H†÷ ‰ò\bB–£\"‘õÓË=°Žßœ1mŠŸo¶æ|(Ñšå'2WÈ«LBçÿî–­`xn²ÂਲÅP½8&Ä#lsÓ1ß— _b\Ž[Ø'þ–mõÇ¢¢ÏV=êߨ¿$ wž.²Ë•†ky©Süa×Åÿð½´Ðpkbouncycastle-1.49.orig/test/data/PKITS/certs/InvalidSelfIssuedrequireExplicitPolicyTest7EE.crt0000644000175000017500000000121610350736724032051 0ustar ebourgebourg0‚Š0‚ó 0  *†H†÷ 0P1 0 UUS10U Test Certificates1%0#UrequireExplicitPolicy2 subCA0 010419145720Z 110419145720Z0r1 0 UUS10U Test Certificates1G0EU>Invalid Self-Issued requireExplicitPolicy EE Certificate Test70Ÿ0  *†H†÷ 0‰׉͸éx¥]tð È(gutj ªûA~ðQ»]y"%÷ÛЃC&ÖžÓ.àD5ˆ—¸yY ˆ9 ¢F2èZS‰ØïK]%`'ÎÌð/ÛüÞb‚% ¯Í U°®aVØ·« †Š™HþNÀ[à ùÏ6„Èë Ý#£R0P0U#0€Þ)ÖæãO—¨:¦êMäF_‚00U«ù2 ñoÐÚÊ̪쟿žŸ0Uÿð0  *†H†÷ 7R¨F5 ýºL4ýʼÀé=^ÞÇÑçÑ•dæÑÿÎ0â?u ÷åãÈ¢B€‰Ë´¨ýî”s¢ï¡7ÚÌxÝÜK!‡¥xùÃJHߺܠ›nÚU¦Ó£²°•%‹à¥Y’L44µ_®<鳌—g¡|Ie·ú(õ£òj'êbouncycastle-1.49.orig/test/data/PKITS/certs/InvalidpathLenConstraintTest12EE.crt0000644000175000017500000000125610350736724027244 0ustar ebourgebourg0‚ª0‚ 0  *†H†÷ 0U1 0 UUS10U Test Certificates1*0(U!pathLenConstraint6 subsubsubCA11X0 010419145720Z 110419145720Z0c1 0 UUS10U Test Certificates1806U/Invalid pathLenConstraint EE Certificate Test120Ÿ0  *†H†÷ 0‰¦<÷;¦ÈΖƒêt VŒ5ú1K|š ±è'îö‘²Úã(™ªmÞÔOªwèÉ•Jßåcänà Z}vûFÇ…3NçW¿3 étqEåô 6Ò0Þ]Rt%Uy»1›Eg1€¾EïÒL253bIÏlü?Ö"ÆÑ£|0z0U#0€j6ðWu?BPµé(7Å­â¼0U ‚æ³–¤©,“ž™ øm´.Éï0Uÿö0U 00  `†He00Uÿ0ÿ0  *†H†÷ âÁÍ¢t|/€U)_hvX¸j7 ÿ˜[¾WÜÛ †wÔÆÇ%ð‚ÊGˆ‚µ'ÉÀhTƒ¹ 1C¯ÇÛ¿t!ÔèuhžÉIÿ±Õ=YeQ^${w“6IRÁ×:69¬IX:›ï–÷Õ/æs¡0 Q1+w&G©9O·çÆbouncycastle-1.49.orig/test/data/PKITS/certs/ValidPolicyMappingTest1EE.crt0000644000175000017500000000120510350736724025740 0ustar ebourgebourg0‚0‚ê 0  *†H†÷ 0C1 0 UUS10U Test Certificates10UMapping 1to2 CA0 010419145720Z 110419145720Z0]1 0 UUS10U Test Certificates1200U)Valid Policy Mapping EE Certificate Test10Ÿ0  *†H†÷ 0‰¸—üݦŠz¤R òˆ¸ò/Hæj•_ן7Õ¤ð ÒrßWAžØü´íßc9"Øí`á¬Ù!ÛÖýTÍ<ç| ¡UȽ:ŽÖþ[äÃ#ù‡³ž"á!.Â…¢Ë!wìySÇÜ®5ûø_o#Ì‹dx¬ MYÆœa«v)ÔÂÑ£k0i0U#0€7;Š¡º§t›ÀëÖ9Ë! £V}0UxG°!ZL…!š×ŘÆén$Å17b0Uÿð0U 00  `†He00  *†H†÷  °`’Ô`×/x†áÑžÕ¿ý–Ž'$ÆÂÑZ^¨v²9yÌz@&óìáºOLÒDà;ÖPÜòGj3#•aHgDÞ…•RH±‚_à×È)ÙŒb2ð«ˆTûÛzµËM”ÕÕ%8:)4ûpœí^,¾b‡Ã€ðøeŒýkŒJbouncycastle-1.49.orig/test/data/PKITS/certs/PoliciesP1234subCAP123Cert.crt0000644000175000017500000000124510350736724025361 0ustar ebourgebourg0‚¡0‚  0  *†H†÷ 0E1 0 UUS10U Test Certificates10UPolicies P1234 CA0 010419145720Z 110419145720Z0L1 0 UUS10U Test Certificates1!0UPolicies P1234 subCAP1230Ÿ0  *†H†÷ 0‰»?NIqtj”ÔiÖô¹(E¦œ\*QŒ¼µŠSQµ!Îwy~HÎ[òsÑÊì5¬ò­jh ÔЧªK`¸Ð€ 2…ysòZÔ.`¤AæŽFÕeÜ«.)`­‚{2i®¡ϤSV?ÝW¸z_E…'’E•¤DDÖ -¼ÃN1º*Ó8Ê1ߣ™0–0U#0€0»yOo²ƒzhC«÷L¡@q 0U¶{ƒˆI CÎò‚LóF†(„Ù0Uÿ03U ,0*0  `†He00  `†He00  `†He00Uÿ0ÿ0  *†H†÷ 3<3ިȄò=o&ª.`äÃ{@ælZ{óý7¥˜c¾m Ê5ìõ$ÜG_þ×I`Ôœ9xÊ¥Íáž°O}k(BØ,çi­Äk¤t’1(ä ¹Â2—±³yÇ®“È.lÄ‘”‡{#"Ø:4ÌÀ£³ÿœÍMÒº¨;š‚bouncycastle-1.49.orig/test/data/PKITS/certs/InvalidBasicSelfIssuedCRLSigningKeyTest7EE.crt0000644000175000017500000000125710350736724031072 0ustar ebourgebourg0‚«0‚ 0  *†H†÷ 0X1 0 UUS10U Test Certificates1-0+U$Basic Self-Issued CRL Signing Key CA0 010419145720Z 110419145720Z0r1 0 UUS10U Test Certificates1G0EU>Invalid Basic Self-Issued CRL Signing Key EE Certificate Test70Ÿ0  *†H†÷ 0‰סµ–`OŠ”QGKHÆåxS~‡ÔP?’CO¿Cµ6ÊiS‘h‹}¬¤¦Ýi•öhÁ}dáÊ*Åå _j§Ïð%†Äê;9cFNÇâÝGϳ^/ Y”âËúˆ0£2ä] ám'SeÁãs¤ØËZ"ä5aÖW£k0i0U#0€IÉü·«áfÐÒ¶ÿBw£ÈnyÌy£k0i0U#0€Ó(Ad \~“ V0¨ö(eÊû0USoì—¶£ˆÿóÜÒÒÜ?°3‡Y0Uÿð0U 00  `†He00  *†H†÷ OcVBµóƒ/kEFœ°—³#UQ…}ÿ§ÅYܘÂû_õåOw83¶cJ‚ÿ'èUÉ«ÔûZMHŸü™©•k Nc2ù°\¾˜ >6LA™ùÜ%K!ؤ/a»ÌR‹,á!£³¬¾´éHX¢u²à-ºãŠñŸÃÀge½úÍ././@LongLink0000000000000000000000000000014700000000000011567 Lustar rootrootbouncycastle-1.49.orig/test/data/PKITS/certs/SeparateCertificateandCRLKeysCertificateSigningCACert.crtbouncycastle-1.49.orig/test/data/PKITS/certs/SeparateCertificateandCRLKeysCertificateSigningCACert.c0000644000175000017500000000121710350736724033002 0ustar ebourgebourg0‚‹0‚ô e0  *†H†÷ 0@1 0 UUS10U Test Certificates10U Trust Anchor0 010419145720Z 110419145720Z0Y1 0 UUS10U Test Certificates1.0,U%Separate Certificate and CRL Keys CA10Ÿ0  *†H†÷ 0‰´Žºé ñlç:ˆàyaÕg¶Þ)Ÿtg¶$p<@žü°ô/éYjÕPæûAûßQšwc[ƒi™XeĈJ: »ùºÅÛóü¿’ðï¬H>ìÎÍfQTÝŸæ1£î,{‚̬ÛDÅèÚ'ÆW!°®š@©I”@+£|0z0U#0€ûlÔ-žÊ'zž °<êš¼‡ÿIê0U›\Q¼"'1"@” %ÿσy­£0Uÿ0U 00  `†He00Uÿ0ÿ0  *†H†÷ l›1E¦dÖ¬wm©Dê©•eÞã ½çøŽP}t{å’.³íè`/ˆòÂò|6wƒŽ­Š%¦|œyÒÒײg¿€ÿ 3ú; æO¯ô^÷謠Ж`$ê* 0Ø`–?_# Q-õÝIô—aW$_$ÐjoVjcœ˜­ûbouncycastle-1.49.orig/test/data/PKITS/certs/PoliciesP3CACert.crt0000644000175000017500000000121010350736725024043 0ustar ebourgebourg0‚„0‚í '0  *†H†÷ 0@1 0 UUS10U Test Certificates10U Trust Anchor0 010419145720Z 110419145720Z0B1 0 UUS10U Test Certificates10UPolicies P3 CA0Ÿ0  *†H†÷ 0‰¬ÁâÙrš"Õ[ƺ>Í2¦ŠÕᜠEŽŽÛZ£:ó+¡'8õ£ šÃLäzµs~ÄMDàSÓ®RßrA>|Cî »}&jÂÝÊ›´{µŒ]R³¬êוäk…­°Êí÷vìÂõzæ²ñ,•+=xݶØÃóHgJoh t`Ãå˜e£‹0ˆ0U#0€ûlÔ-žÊ'zž °<êš¼‡ÿIê0U޽fŽUeÏQäY¦É*b¿÷¥¼0Uÿ0U 00  `†He00Uÿ0ÿ0 U$0€0  *†H†÷ b±e|JsßržYD+¹mx¸8Ñ¥Ó; éKðXÕÉ’jV0bãüþßRºÓÆýW‡Ð~”íU¤ÜBþÿСYp¯Ô”¸ær ½Ó„`?eÿDΉ̅TOÐaSñ¤è)Àœ<f„€4<š‚„ÃYjxº+Y)r¢ð_%=x8W¶Æ³–/?RÊ'ñ»¾IÜet F—Ó£e0c0U#0€) x”Ž„)BK|«ƒ*¾5[<0U…I ž¤ƒ%×µ5.=ø)@aãöK0Uÿð0U  00U 0  *†H†÷ Êà:$K XYšÁæ‰< ýf)?ÿ¹A˜Ï›tét{ô¸€÷ u_“îÔ·²•oöŸb¥S³ž:NñmI½DV"‡Œ‘–³6¥yB/g+bI0wÿÿ#Dý/0A)A•€6âêF%‚¢ÂCö—<5€ÒaÊÂaÃÜWQ¡bouncycastle-1.49.orig/test/data/PKITS/certs/onlySomeReasonsCA3Cert.crt0000644000175000017500000000117510350736724025325 0ustar ebourgebourg0‚y0‚â R0  *†H†÷ 0@1 0 UUS10U Test Certificates10U Trust Anchor0 010419145720Z 110419145720Z0G1 0 UUS10U Test Certificates10U onlySomeReasons CA30Ÿ0  *†H†÷ 0‰×3í|3°Xo šíÍk›Z;!Œ—X´ç V˜ C|½ž‹ÜTk•’¡ µ§Må‹t SBÙ:P·DL×Ð=ýÚίZŠzÅ,ï!5¬a ס(C7HëøÒÒøt,¡ ­¥òÉþðÄ Y¾{Í¡&D¥ÓÝê¾36„jD:K¬£|0z0U#0€ûlÔ-žÊ'zž °<êš¼‡ÿIê0UI{ëOiû~£ßÛ#‘÷ZVjù¶00Uÿ0U 00  `†He00Uÿ0ÿ0  *†H†÷ 7±šÉ¼©Š7"0Þä|$E«ÜBlÜeÚ}Éï’oU˜’ÐIÃßÒ3,:#ÏÅþ):ëÀ¤ƒ–‹ƒs‚}#µÆ„+®BV²ÃÜT\>"KO³VUÒ(?p¸òç…_4\)&qàCû{ò'(Bï,ÝÇ¥m0ýÖL¬„uP.²Â¸­bouncycastle-1.49.orig/test/data/PKITS/certs/PoliciesP1234subsubCAP123P12Cert.crt0000644000175000017500000000124410350736724026355 0ustar ebourgebourg0‚ 0‚  0  *†H†÷ 0L1 0 UUS10U Test Certificates1!0UPolicies P1234 subCAP1230 010419145720Z 110419145720Z0R1 0 UUS10U Test Certificates1'0%UPolicies P1234 subsubCAP123P120Ÿ0  *†H†÷ 0‰Ò¥ ƒòt³L ÌÀ4q‚‹’Wú~Ë }Ø=Ü˃¨| èó'yšËÒI¡£7³dž"»k~þ‚;ÉܔÙý @ÈÓ5'­§ÛÕõùörô•U+e¾ç'‘ f‚rù4'p¦ÞÐtÕFu /Ï I{f2çIåÞJ;=ƒ¬¹H@ÿ¦¾€o@‡Izk†ë“Ì|­Ï¢‹ƒÝÄ'qT³ã‰õWh~¿ †¤;wë”ckª8võ ³¶ªb¢JÛÖ šâ“bouncycastle-1.49.orig/test/data/PKITS/certs/ValidPolicyMappingTest11EE.crt0000644000175000017500000000123110350736724026020 0ustar ebourgebourg0‚•0‚þ 0  *†H†÷ 0V1 0 UUS10U Test Certificates1+0)U"Good subCA PanyPolicy Mapping 1to20 010419145720Z 110419145720Z0^1 0 UUS10U Test Certificates1301U*Valid Policy Mapping EE Certificate Test110Ÿ0  *†H†÷ 0‰ªˆ¿êu7½Š÷¯ÇûÒ¾¶YuE¤Þp“S#q_iþ=‚SBšžt?zˆ@‹i½/–(ñ¬)½RÜš¼A>ÇHU‚åH‘½?W©oâ'УAó3~Q›ýf¶¡‹ðÝ!RÖ¥ M^2,?Wiõ¯v&#±¯ˆ~f«:_Ý%Hxšk£k0i0U#0€‘×ᵤ–‘ñ¢q/fÙ'{J‚“š0U?˜û-osKRýâ’ CmPm@»0Uÿð0U 00  `†He00  *†H†÷ #^ígK™ÒÛ·˜EÈÉG©¸kjŽ‚'ç°ìwïYõQ||è7ªTPç§Ù‚¿ÅJÃ@¡W‹OÙ0ùÇ’²á!ïÅ–à„Pºbq¹bhý_üã—ƒBº0 û2-TeŠò)žþ¨àæñ*¼¸œ‹ÒRö‹ÌÊ{¹âìãl«û%Ïbouncycastle-1.49.orig/test/data/PKITS/certs/requireExplicitPolicy10subCACert.crt0000644000175000017500000000122510350736724027307 0ustar ebourgebourg0‚‘0‚ú 0  *†H†÷ 0N1 0 UUS10U Test Certificates1#0!UrequireExplicitPolicy10 CA0 010419145720Z 110419145720Z0Q1 0 UUS10U Test Certificates1&0$UrequireExplicitPolicy10 subCA0Ÿ0  *†H†÷ 0‰½gÛ È6-Óçþ‡ðš6÷ñº] ÂBoÌ<ƒn¹ÀQ(À<©¢v Ä cÿû*V=¡BX%ñN ÃJï"ixa¦fGtQyv;@WŠ!P_D"lžÍE£Ü‚¸4àY~[_p“d6¨`ksZÌ4†ís«I²Âi‚Fø)è¿E¡£|0z0U#0€óé&™–†ÄÕ¢{ì¹°¥n6 E0U£Ca¾zó®eÑt¼Àó0üÖ:”0Uÿ0U 00  `†He00Uÿ0ÿ0  *†H†÷ —æ÷ö~¦à°à…£ùiÅ,*$¢¸ýõ:?ÅËW´cRÁ¦Ù·S’¦F!B5ŠhÛO® -kíØÃ&}áΔE?}$qzøQOì‘RgÚ&ì=4©+Z1¥IæÛ¹r¾Ä["LOüïße  ·é]rñƒªê°ÍKɼ€µuèë»üE1ubouncycastle-1.49.orig/test/data/PKITS/certs/P1anyPolicyMapping1to2CACert.crt0000644000175000017500000000204210350736724026266 0ustar ebourgebourg0‚0‚‡ 60  *†H†÷ 0@1 0 UUS10U Test Certificates10U Trust Anchor0 010419145720Z 110419145720Z0O1 0 UUS10U Test Certificates1$0"UP1anyPolicy Mapping 1to2 CA0Ÿ0  *†H†÷ 0‰ìª$P§ÆTÖEŽKûo´ð%?]ý{ºÇšœØ±Ú|0Q°åU•/¤0‹ÿ.yĂܰ]­òñPÎ 0Uÿ0U 00  `†He00Uÿ0ÿ0  *†H†÷ 9Á‰ÚDÍ«n²ÚžE &ž‹:3»gFÃ¥»4ÙÊe ûÈ•Êô›%ŠžR».A®ì3{ÚžkÛ8‰§šdÖö)䀿%B¨'…&íêþ̃î•x›²ã… †;\Bùõ饨OËæ«Æ»38»\ªæË¾i5°üÚó+=bouncycastle-1.49.orig/test/data/PKITS/certs/ValidDNandRFC822nameConstraintsTest27EE.crt0000644000175000017500000000140510350736724030123 0ustar ebourgebourg0‚0‚j 0  *†H†÷ 0j1 0 UUS10U Test Certificates10U permittedSubtree11#0!UnameConstraints DN1 subCA30 010419145720Z 110419145720Z0‰1 0 UUS10U Test Certificates10U permittedSubtree11B0@U9Valid DN and RFC822 nameConstraints EE Certificate Test270Ÿ0  *†H†÷ 0‰½·Ã"l&ûNGã,ëÅtP§ôk|pu¶1[<…3¯¨Qí?±60¾ÜÏ+cÿô°èààð.JÛ„9yL¯jAK¢Üì¬Ý‘·ï¸ Œ{sQ‡ò‹4Õó¢¯&ØtëcËç8¯SC}øQ?*ÿ¦y{t¾ý '»>Ágh/£–0“0U#0€W«øœ'ÈÒôæÏoª 5gƒ$k0UÝó™Ò FTI&ÿZ4OóEn÷éû0Uÿð0U 00  `†He00(U!0Test27EE@testcertificates.gov0  *†H†÷ %ÏùEÁ¡Æg”ê 5×MyüV"³÷7ëÖ)‘že©’S»dåIÉ’7‹Äƒ¯¾×´½\b>, BJÇïÉQ51ùèÄ݃ű å‚\Øk…o¯™‘"•X1ºQ¹3Úfúú9Πŵ+iA—XÇŠþµ†ƒq{¥k5¾"›WXˆTbouncycastle-1.49.orig/test/data/PKITS/certs/InvalidPolicyMappingTest10EE.crt0000644000175000017500000000123310350736725026351 0ustar ebourgebourg0‚—0‚ 0  *†H†÷ 0V1 0 UUS10U Test Certificates1+0)U"Good subCA PanyPolicy Mapping 1to20 010419145720Z 110419145720Z0`1 0 UUS10U Test Certificates1503U,Invalid Policy Mapping EE Certificate Test100Ÿ0  *†H†÷ 0‰¡דbZY—RQñ:Û£Äv 晊,¯ 8 Ĺú¤<ì8l$ÊŽÌè ò…³ýæ‚™õ‹ª²@¥nÚÉõëj{*[å7'u%€ ãdkÅ_ ojÜßåD¬,J?Æd‡¤ÿÈ’[ò‚ÖªHfì±ÊèYü½Ä8.Rº +£k0i0U#0€‘×ᵤ–‘ñ¢q/fÙ'{J‚“š0U¨ZSü½8“ޑ蟹uÝñƒzªƒ0Uÿð0U 00  `†He00  *†H†÷  ϸÑ#Ö¿0Yq4õÝðP¼brY×…@4Û4¤ß—"ÉÂâÃËb×kI v¼$.Œ²ÙA“ÂXe_³qd|ŸÅ£DÝE)dz¦¥ ÏÌëMêgN¯]çŠÇˆrÀ#Ÿß€œÙFî[9@b \VîÉ:Ÿø%Y¼Zbouncycastle-1.49.orig/test/data/PKITS/certs/keyUsageNotCriticalCACert.crt0000644000175000017500000000117710350736724026015 0ustar ebourgebourg0‚{0‚ä 0  *†H†÷ 0@1 0 UUS10U Test Certificates10U Trust Anchor0 010419145720Z 110419145720Z0L1 0 UUS10U Test Certificates1!0UkeyUsage Not Critical CA0Ÿ0  *†H†÷ 0‰˜”rž{ËŸh%>0¤ªu³/ÛÅ?ò¦‡–ÞÊ_¿8¾ °3çlÒõf‹€ž›;$ú_áQéfô†à .¯9Ô?«FþoKÛÚªúäZüÊR0uæTŸBHÎ’1éÖ;Ø'‹eG;ZkB7nV©‘sj¿¯vÙ™ 5£y0w0U#0€ûlÔ-žÊ'zž °<êš¼‡ÿIê0UÏ*¡¥ýBâ3¼3*M˜s³ØûU¼Ø0 U0U 00  `†He00Uÿ0ÿ0  *†H†÷ ¤¸ ¡9¿øgž;7—«b¶ä•;å ÆQ˜ïì–_'e%[¯"i¶¼Æÿ¯‡=•€Ô›“ü)ñL>­­Þª©jB5EBé!Ð^(ÀZˆVuA ²È¥á*ÐùûÑAõFÌ[S÷Ò¦—dOtçI¸î¢³­¿¦“ßTiM¿†bouncycastle-1.49.orig/test/data/PKITS/certs/PoliciesP12subsubCAP1P2Cert.crt0000644000175000017500000000121310350736724025754 0ustar ebourgebourg0‚‡0‚ð 0  *†H†÷ 0H1 0 UUS10U Test Certificates10UPolicies P12 subCAP10 010419145720Z 110419145720Z0M1 0 UUS10U Test Certificates1"0 UPolicies P12 subsubCAP1P20Ÿ0  *†H†÷ 0‰ Ï-”ΛÄ+ÂRc\ Dƨb/̸ÿ‡’kpz¹¼ò[Yí;Tùæ{±Žž½#Ù˜›ì$Ð<ï öŸ£¤™þ¡E[zç ”°¹1,ìr´aš¾G&ÍÊíž3T b>¼øôÖïM/EÁd²{ƒ˜zïß1„’~›ù9ë’â{£|0z0U#0€BˆÁx·CÚ¯½ÞºC§åµaÿò0Ugå Œl*»Um-è"ªKs+ˆ*0Uÿ0U 00  `†He00Uÿ0ÿ0  *†H†÷ Dªû` ¿,$wê²è —²¿ø¼³LšuJÿCðÙ(ð ”ôZUnÆÌ¢{h!°×b2iåYR4tÉzÕÝ6ŸŽ•gž°ô8ä´k(JLüaŸ,-ÁS¤> qäOê'Á£zíÆ”¾…‹RÛ¸yFÞõw!¼fM Žbouncycastle-1.49.orig/test/data/PKITS/certs/ValidcRLIssuerTest33EE.crt0000644000175000017500000000152510350736724025132 0ustar ebourgebourg0‚Q0‚º 0  *†H†÷ 0C1 0 UUS10U Test Certificates10UindirectCRL CA60 010419145720Z 110419145720Z0Y1 0 UUS10U Test Certificates1.0,U%Valid cRLIssuer EE Certificate Test330Ÿ0  *†H†÷ 0‰ÓX`'&ºâ…ðÆ¡b•³Ž)—“–[BÏA }gÿ:A~l'{6š—ª™£ÐO±qþÎ:|z'úCÙIsw’`à ‡`~€¾Ä¼ª—=X¡Nbž¯LÑImmz9s¨[Æ]¶®dé©6ž†(÷‡nŽ«>^`ß~+vÓÔØ‡£‚=0‚90U#0€Â>ªNÁ3ŠªYI±f¢ð}0U|AzÁ<Õ Ì# Ïsï;8÷«G0Uÿð0U 00  `†He00ÍUÅ0Â0¿ t r¤p0n1 0 UUS10U Test Certificates10U indirectCRL CA51)0'U indirect CRL for indirectCRL CA6¢G¤E0C1 0 UUS10U Test Certificates10U indirectCRL CA50  *†H†÷ “ª§g|Vmå¥C¹¶jN´Î`áY¡#%œw|9£j<ô‹èßM…t []ìĹƒ[öl!…õ8Õ*Ì‚Rjt@„Q°×lźßRqP[Õϼ„ÝB9eÐJŒâqy2Z7>’R×&Êd¨¥ÔXí–¶¬/Hbouncycastle-1.49.orig/test/data/PKITS/certs/requireExplicitPolicy0subsubCACert.crt0000644000175000017500000000123110350736725027736 0ustar ebourgebourg0‚•0‚þ 0  *†H†÷ 0P1 0 UUS10U Test Certificates1%0#UrequireExplicitPolicy0 subCA0 010419145720Z 110419145720Z0S1 0 UUS10U Test Certificates1(0&UrequireExplicitPolicy0 subsubCA0Ÿ0  *†H†÷ 0‰ÂN<0nÜŠ¦jþŽ$ó ¨ºa]èq±o öì—¨Ùn¹jðT¶ê‚å$«ÎÉf;‚,QØ(Hâv`ywðsºxjÜáNòý+ÒE7IÏ3»éˆöÝã›–{ìdù^áPô¤zÅ£u @*‡O¼,¯Yƒ¾ÖpµœL7£|0z0U#0€ðpGbŠ–Ñ‰ªT‰øœm)0U°BI3hó*ÍT!]æbápÎ¥#@0Uÿ0U 00  `†He00Uÿ0ÿ0  *†H†÷  z Ï“¼qJ³œøìè¾fJ% ~¼‡Hë¸AIHf ˆYÆÜ#¸=¡´Hˆ9vaÂ÷9|wƒ™¢ü΋؅µÙ\O_ÒG°„©ð}UÆXMù–Õ>=f¹Âº æuIÃ,­KÓ L”ï2ÿ+e\6HVâ -Qñ±Sƒ¨Íþbouncycastle-1.49.orig/test/data/PKITS/certs/requireExplicitPolicy7CACert.crt0000644000175000017500000000122610350736724026524 0ustar ebourgebourg0‚’0‚û .0  *†H†÷ 0@1 0 UUS10U Test Certificates10U Trust Anchor0 010419145720Z 110419145720Z0M1 0 UUS10U Test Certificates1"0 UrequireExplicitPolicy7 CA0Ÿ0  *†H†÷ 0‰ ßRÄ“R5I¬q¡F¢èßI uÍþ÷ë.§“@Z?(É”"¯Å–¶²&X'5rçÀ‡·vì¬2(}yOiÆú[×SÅÙaÜlàbXö ß¹Wä¾i…rSÂ~¶cêX2??°tÞs!@ÓB…AHràJh ÃG ˆ gy#·£Ž0‹0U#0€ûlÔ-žÊ'zž °<êš¼‡ÿIê0U"çÛpˆNòb/p˵ÁÍNM0Uÿ0U 00  `†He00Uÿ0ÿ0U$ÿ0€0  *†H†÷ /àa-&ê;ÍžK ÕïÛ_%ÌšMM¹j5¸Žø¸tÞ#ÀCà¨'ëCUr•ýX03)‡:œ†gMõYŽ¥=Îñc›þñÕ¢Vú ÞL„&ci‚EÐìu·œ$¹‘knÔÈÍæ0*ïH³´Qu†œbouncycastle-1.49.orig/test/data/PKITS/certs/onlySomeReasonsCA2Cert.crt0000644000175000017500000000117510350736724025324 0ustar ebourgebourg0‚y0‚â Q0  *†H†÷ 0@1 0 UUS10U Test Certificates10U Trust Anchor0 010419145720Z 110419145720Z0G1 0 UUS10U Test Certificates10UonlySomeReasons CA20Ÿ0  *†H†÷ 0‰Æ;¬æk™œ’¾½´âJ¾åûY’nÇ”ðä]¡,lŒ FÁodÕ==£ì·Gúý gËa|BˆO:Á$¦±°—5¾zЀ¥ìÖŒWíÃpüÙ‡‚Š«Tj™e±Á[þëYÈ÷F.‡>£¦RšÒü]Ê„þ’IZ¹þÓ|½€;v«£|0z0U#0€ûlÔ-žÊ'zž °<êš¼‡ÿIê0Uª¡ïØ\Ø8²3‡ç“EAЊ{0Uÿ0U 00  `†He00Uÿ0ÿ0  *†H†÷ 'ßæ*ÔDÇ!‡vÔîÌ'e¨T-7^…·=“ ¢Y¡ÿm‹¢ô ÏÇ…ìµ¶ 8–ã¤síUçýb=Qßðç¬VZΛ"i‚t˜b%£Q®¨ º/qn²‹³»Ú Ÿ½ô´Š Ž_pD—€˜±°é3þZ }PS·§Ê—bouncycastle-1.49.orig/test/data/PKITS/certs/inhibitPolicyMapping1P1SelfIssuedsubCACert.crt0000644000175000017500000000130410350736724031201 0ustar ebourgebourg0‚À0‚) 0  *†H†÷ 0R1 0 UUS10U Test Certificates1'0%UinhibitPolicyMapping1 P1 subCA0 010419145720Z 110419145720Z0R1 0 UUS10U Test Certificates1'0%UinhibitPolicyMapping1 P1 subCA0Ÿ0  *†H†÷ 0‰¼žùvˇÈÕ?¶†æó«(ø·wµtÖGDlÏ(V&OŽVp}º¹!@Ã~0HÛÇÿçaŽÀÛƒ.´!/§ IZ= æàöG¢êõcÙ¦tOê4aP¨‹„Ò$…Þ\¬¿Yq„̦G—¿Ð†2,£ŸÞE¨T^¦j'±£¥0¢0U#0€¶¦ÁêÀRS߆ýfIä´F¾c3 0UA¦$çKFÊN½bý• EDEÖƒ0Uÿ0U 00  `†He00&U!ÿ00 `†He0 `†He00Uÿ0ÿ0  *†H†÷ ¢Ÿœ•`5P ”FªOŒ¡_ÐK$G¯i ¦” (  ‡h½d1÷û1‹ÆøºSáÉ26?å ó"G>k.r¹CÁ\ É1=X+UNWðÕ¨lïÚTëi•TadH&×@zµ‡N褅zp¶¡ú_Mñ)É?oòHBbouncycastle-1.49.orig/test/data/PKITS/certs/requireExplicitPolicy10subsubCACert.crt0000644000175000017500000000123310350736725030021 0ustar ebourgebourg0‚—0‚ 0  *†H†÷ 0Q1 0 UUS10U Test Certificates1&0$UrequireExplicitPolicy10 subCA0 010419145720Z 110419145720Z0T1 0 UUS10U Test Certificates1)0'U requireExplicitPolicy10 subsubCA0Ÿ0  *†H†÷ 0‰« - L«gt¿T<p—érBYÞ„ë3BM”Ó7Ç]–»rí.Ó""±þ)‰ˆ¬>:² Gš³Dô¿õ ÷½­¿’»Yéjí9ô€Á)É,­»ÜÓlbEÕ†ÙOw£|0z0U#0€£Ca¾zó®eÑt¼Àó0üÖ:”0Umh1ýù_Rùû.ÚDÂÏ{6™Øÿ)0Uÿ0U 00  `†He00Uÿ0ÿ0  *†H†÷ 8´ÑsPÄ èŽZ,l‘®hâ|Òl¦"·åXr]޳ýÚÈ«.R¼A >õY ±ùÜŒ,W²zCw5¬óB½Þ•ð3ËÐßp»ûÙ»l¤ÁàK’¿má0|ã Ùïþ!”Ÿ9+,gÌ<ö%Û|޶òIMeap>˜ bouncycastle-1.49.orig/test/data/PKITS/certs/indirectCRLCA3Cert.crt0000644000175000017500000000117110350736724024323 0ustar ebourgebourg0‚u0‚Þ V0  *†H†÷ 0@1 0 UUS10U Test Certificates10U Trust Anchor0 010419145720Z 110419145720Z0C1 0 UUS10U Test Certificates10U indirectCRL CA30Ÿ0  *†H†÷ 0‰›Ù¬g4ŽzZ{Æz‡)jÒ°Ãã¸URäíÉ}ÊUOõSä“ü›oÒîV>ž"ŠÐ3ý×EŠ cáÌ ¯ØYaݵL¼`ñHÉVžyªaŒÀØËQª‹qêø¼2~îìÓÁ»N¡?uÚL\‚,m'—ŠŽ7ð]â܃Fw£|0z0U#0€ûlÔ-žÊ'zž °<êš¼‡ÿIê0U–(¼)¦­XŸg.ÇÂÁ—:ßîˆë(0Uÿ0U 00  `†He00Uÿ0ÿ0  *†H†÷ ÏàkOwŠd{²4åŸþÙý€U÷Aü˜¿ŸÐ£;õô´ét ® ›™ïtÐÑd|Ž&âHÚ`ÿYØýÝËWÎHöâL*dTœÇóÍqŠÇèáûüdÁˆ¹‘Û‰Ù_IªÃ’ßÃ…_w£ì´MrÞ‡ªz÷iGâéP机übouncycastle-1.49.orig/test/data/PKITS/certs/InvalidpathLenConstraintTest6EE.crt0000644000175000017500000000124410350736724027164 0ustar ebourgebourg0‚ 0‚  0  *†H†÷ 0L1 0 UUS10U Test Certificates1!0UpathLenConstraint0 subCA0 010419145720Z 110419145720Z0b1 0 UUS10U Test Certificates1705U.Invalid pathLenConstraint EE Certificate Test60Ÿ0  *†H†÷ 0‰©Ê{ƕՑhú•ÆßÙÝ®—"C[Çž,ñéc÷ºTúºyøÃ•!\#ûKØ~L¤-è¡pdÕÚ¢ýTÄ€{y\ºðª:á Òjh€GÔ¿ÕK£~sä€F‘id3™ª<éš Z#]£|0z0U#0€Ž«FœKnçåWˆ '“þ'Öç0U,<¼+´ÒP¸(\ˆðƒõñó½0Uÿö0U 00  `†He00Uÿ0ÿ0  *†H†÷ [} A©¤K[˜ññ`hç@´„WmTb´Í–s^Ê Á=\!Ä9[Ö;OPríU?¸pÂv„ªZ]h¡H¡ßzeJÙü;s-Ä:Ÿ¾=µèH&dƒn-Ê3 ¬¢kWdŸrDs´¹Þæã8–Zª¯ß0ý6œ“§&’­G—bouncycastle-1.49.orig/test/data/PKITS/certs/InvalidDNnameConstraintsTest7EE.crt0000644000175000017500000000125510350736724027121 0ustar ebourgebourg0‚©0‚ 0  *†H†÷ 0J1 0 UUS10U Test Certificates10UnameConstraints DN3 CA0 010419145720Z 110419145720Z0~1 0 UUS10U Test Certificates10U excludedSubtree11806U/Invalid DN nameConstraints EE Certificate Test70Ÿ0  *†H†÷ 0‰“/QÁ·ãzêÒʘU½ñ♉þò°:¡Õu÷ó;M#r¡@÷-Ôd$UÂø’Àü?QÑ{;j 5ûvB‡k;í]¼}XOÂýe ü²”Ý )­«™¢é3Éç¥ÑãLrBú©þ¥Ú£^U;¶Õ”A€ñ "¨¤e‚ã—W?£k0i0U#0€‹ã¸XVŸjß=Ø;³6á˶Ê0UòsQtoû ¬ÙÇì…Úô:A…0Uÿð0U 00  `†He00  *†H†÷ 8.>óë°ú‰4ò·ÒòSè<΃3›—Ÿ[‹ø›UŒ3ŠØto~•.—ùv4ÂUp*½Èj6ŽÏ¤[Tc—×xý›P+ñZ᥎ý#Iþe¿¿‚h[’§5MÁN“É&ÍÓ±b³ÜÕnYQ+Ç£Fs ²Ô±Óû¶Ä^SK,bouncycastle-1.49.orig/test/data/PKITS/certs/pathLenConstraint1subCACert.crt0000644000175000017500000000121310350736724026326 0ustar ebourgebourg0‚‡0‚ð 0  *†H†÷ 0I1 0 UUS10U Test Certificates10UpathLenConstraint1 CA0 010419145720Z 110419145720Z0L1 0 UUS10U Test Certificates1!0UpathLenConstraint1 subCA0Ÿ0  *†H†÷ 0‰©Õ1G3gQúvÄlöüȰì»ì@Öô†úñàCä~Hs"ØþìÝ6‚ÛšÉíaIwÇœMäÖP­ ˜œpiªeNÞsbeøÐìF_B!A.ÄKå¶Ö,p¶ÜrØŸôxÙ05–L)ÜuàÛ¸yA) WéÄ4‡¦ë!£|0z0U#0€ ×MÅvzþð5Å5Šf2.Ö7Hj0UasÛ b5j[¸bH#çø+ÞP]07~?6è8< x¿ä –CC¹ª*!ŽS1J·ºùEg¦ËˆJzvÆ TÉhÑ)Óë°êèqRpbouncycastle-1.49.orig/test/data/PKITS/certs/InvalidDNnameConstraintsTest2EE.crt0000644000175000017500000000125510350736724027114 0ustar ebourgebourg0‚©0‚ 0  *†H†÷ 0J1 0 UUS10U Test Certificates10UnameConstraints DN1 CA0 010419145720Z 110419145720Z0~1 0 UUS10U Test Certificates10U excludedSubtree11806U/Invalid DN nameConstraints EE Certificate Test20Ÿ0  *†H†÷ 0‰›½Y•bouncycastle-1.49.orig/test/data/PKITS/certs/requireExplicitPolicy2subCACert.crt0000644000175000017500000000122310350736725027227 0ustar ebourgebourg0‚0‚ø 0  *†H†÷ 0M1 0 UUS10U Test Certificates1"0 UrequireExplicitPolicy2 CA0 010419145720Z 110419145720Z0P1 0 UUS10U Test Certificates1%0#UrequireExplicitPolicy2 subCA0Ÿ0  *†H†÷ 0‰±Þñ«“Á:6¢XÁpÂ… 6‘\%Q¹g?“­Š—žèíl¤ãÆ+¿°ìÙﮘ€>ôjÆBÈ×`lÇKΗÊÜ‚™7ßç·ö-„‹Ä§Üþ«Ü2ø“¤™ˆki‘ƒ¯”¹u¯Z”1çm<­½÷m#K)æÌr€6‹èø ¾Ú£|0z0U#0€æŒÁ+gKLz¶À!Z$™P„0UÞ)ÖæãO—¨:¦êMäF_‚00Uÿ0U 00  `†He00Uÿ0ÿ0  *†H†÷ Gä+˜žX[J{¨?íÃw¸ÒûÏja#.7§Êé2©Qàµ20Ul[„¾²ì…v¦?ÉWØÙO¶0Uÿð0U 00  `†He00  *†H†÷ ÒVÔöJÎöÄP-:á¦äJ§»OßdˆÚ,‹™âÑ‹¶"ýäUJësŸ3OzcÈ«ñî§¶;÷õ,²ÉÞndê,”1 å‡[;t–ÈáOFd‘t¼GªMOé°¸kꟶÑ>‘^g–&2Dg´ZiÝ·‘‰ïƒÁbµ#G™­ˆá*èbouncycastle-1.49.orig/test/data/PKITS/certs/inhibitPolicyMapping1P1SelfIssuedCACert.crt0000644000175000017500000000122410350736724030470 0ustar ebourgebourg0‚0‚ù 0  *†H†÷ 0O1 0 UUS10U Test Certificates1$0"UinhibitPolicyMapping1 P1 CA0 010419145720Z 110419145720Z0O1 0 UUS10U Test Certificates1$0"UinhibitPolicyMapping1 P1 CA0Ÿ0  *†H†÷ 0‰—Ý­¼T\! .‰?¾µT‹'7@Éú6¾UË~vƒƒµAD÷Ö]b´þ¨CÆH¨Ä„–Å zŽ[ÿN:ŵzDIˆÉ>¤‡MüÝè:ÒóôÞrzc¸6¯¿p:vdÞ©_Á¾&+"öôW-àLÿÞ" <¾±:“Ëà(‚S£|0z0U#0€ªidµRå¢c  ój? ²Ô´0Ul\â¥l[`¥ÞwSZã55¯­0Uÿ0U 00  `†He00Uÿ0ÿ0  *†H†÷ ‰¨O㦦;2D=NQ•¹ËUõê(ÆÙëYq³µögjí ¦\Ÿ1Kîbiê¥ÉŒ¼ s¨Ús“pÈv‰Ðóîèp-I½ÆxDÌkP Úx< óêÐC8wÍ Þ¸nòç)•›Ý²Ä=ùÙ¥“iÇž°îþ4ø>Ìš)bouncycastle-1.49.orig/test/data/PKITS/certs/ValidpathLenConstraintTest7EE.crt0000644000175000017500000000121610350736724026635 0ustar ebourgebourg0‚Š0‚ó 0  *†H†÷ 0I1 0 UUS10U Test Certificates10UpathLenConstraint0 CA0 010419145720Z 110419145720Z0`1 0 UUS10U Test Certificates1503U,Valid pathLenConstraint EE Certificate Test70Ÿ0  *†H†÷ 0‰ÐèÆ|RŠì‰ú㋤r±Áä2¨ÝdXKMN$@Ìßï›#›¦/߯ÀH æÄP y#• -£ÚC¼zѽœ7,¯iö↭é} Ì£š9qÐÞDñ:{-í׆TÝ*To|ËUB—E²á+Þ£¨åuæèy9ëC{Ÿ£k0i0U#0€! µvvÓ³*¬&üª¦OòÖ¡oK0Ulr’8F÷¾Cðîk`û/¡‰ÍiØ0Uÿð0U 00  `†He00  *†H†÷ '¨P2W¹íjG¼C,ïžBÆó%ì˜Ò>·aò«à€G*S"îz…‡}íGÈû:±+ÝM°i–| ð’Y2H‹à>I£ÿ´r€=„ü&Êz'õšæs¦-ìudh7s²~1P Ö¬{Ð[xXI¿`V «Ó De{/ƒ•¨sÅr‚bouncycastle-1.49.orig/test/data/PKITS/certs/inhibitAnyPolicy0CACert.crt0000644000175000017500000000123510350736724025435 0ustar ebourgebourg0‚™0‚ ;0  *†H†÷ 0@1 0 UUS10U Test Certificates10U Trust Anchor0 010419145720Z 110419145720Z0H1 0 UUS10U Test Certificates10UinhibitAnyPolicy0 CA0Ÿ0  *†H†÷ 0‰µÂΆ—FצMÒ í§Î»~#_ °Ž%ƒý(.4€ûÒz|,á‡3:7P_&ÚUÐÂsá>øØ¾zÅYð8xÅsqQÒfŸ¼·Õû]"¹15&ÛæÌ[ònhé0<åvdlXÖøÐߣX pÖ˜7­O¿CìGövÍ £š0—0U#0€ûlÔ-žÊ'zž °<êš¼‡ÿIê0U@˜`æÈý\ÑØ/ êìEÏ0Uÿ0U 00  `†He00Uÿ0ÿ0 U$0€0 U6ÿ0  *†H†÷ ¸aP6ýV‰H3fÊ¥ºZ·‡MŒjä:eSü{Æ_…—k³#p¸Ýl gØ"—y{_ì îS=̪W–5yXÚWûŸrT6®Ø“ŠœcKiüîÛ¢š.·ôg„›®k¨i\JM ]÷#mœ$éaíLßÜçÆÚV+X`¼_±/·;jK¤È0P™¸â@MðR[¢ùÕm=6ˆjnãŠi¬å¦Ø­’¹Ÿíx‰þ²#« i-A/bouncycastle-1.49.orig/test/data/PKITS/certs/ValidpathLenConstraintTest8EE.crt0000644000175000017500000000123710350736724026641 0ustar ebourgebourg0‚›0‚ 0  *†H†÷ 0I1 0 UUS10U Test Certificates10UpathLenConstraint0 CA0 010419145720Z 110419145720Z0`1 0 UUS10U Test Certificates1503U,Valid pathLenConstraint EE Certificate Test80Ÿ0  *†H†÷ 0‰ŸÙÔ6o.1Ý/\ú¨€l‹™ËÇÈO›¶¨½¦µÛ!á¨ÈÏ’×ï|í·e”ºæum[¹é¦O‚i“"yyCâÑîÄݧڛÛE5 Za »P‹á—a ¥™&¼îÔØwÞ)«à£³ø™˜¯†¡ƒí€ÖUð€÷`{ !êߣs9£|0z0U#0€! µvvÓ³*¬&üª¦OòÖ¡oK0UT)p¢M¸±nCqgÿißAÛœðÝ0Uÿö0U 00  `†He00Uÿ0ÿ0  *†H†÷ #.<6ÐøÛ=4fX‰ù†WPE?®:iQ }Ò²ä@°PóeÿeO€Þ7w—š8ÞáŒEoÐñØËÇMMšd•¢4­²QEÇh¢ñ‘ƒ[äŠ}–!‚;&œM£³0°0U#0€ûlÔ-žÊ'zž °<êš¼‡ÿIê0U7;Š¡º§t›ÀëÖ9Ë! £V}0Uÿ0U 00  `†He00&U!ÿ00 `†He0 `†He00Uÿ0ÿ0 U$0€0  *†H†÷ ¦ ‘r%ã ­kÑÔfæÞ̶‘Ét!¥&N[î…J¤|a¶ÇR¡¤«²F `k—ýÞ¨TûË[Y6ëýésx\ëFÊgšÞ¢7Nh-e…Þç[¨0îàŸ\×׋=î¢íº¤ÊáËbö¸é$Ÿ÷¦"z“8±{o8Z1ÑÝvbouncycastle-1.49.orig/test/data/PKITS/certs/InvalidRevokedCATest2EE.crt0000644000175000017500000000117610350736724025327 0ustar ebourgebourg0‚z0‚ã 0  *†H†÷ 0A1 0 UUS10U Test Certificates10U Revoked subCA0 010419145720Z 110419145720Z0X1 0 UUS10U Test Certificates1-0+U$Invalid Revoked CA Certificate Test20Ÿ0  *†H†÷ 0‰Ù©-Bå*búÒ¾äÑŽo»õöõT !6AÝ­ý5^n!•ïZÈ=PHf¶í̤ƒ32Àzä ³×:»ŠõÁÕÆ#\;¶Ç;ÿQfn¡ÚÈ<óTènAí^LÂîR‚ ´l„ô œ©àÅÙ¨ 4• ù3Ø T…±fA’*…QÄéCÂV%£k0i0U#0€ÒºO>h8æøÁê%®Ú’¯C6n0UHJšM6°‘G÷!WMr±ª‡Q¡h0Uÿð0U 00  `†He00  *†H†÷ >·õ ëç¼µÁé îO™&èC•éŒf;‚ ÙqªÆ/âìF©.~˜$.—¢ì,õÝ»€/ó*W\ì~ÝøjÛƒÀ{cW}Éå$“ /IþêI½ÚÃ×’©‹XNÅ…/ô!äb=„–.…̼aÔ)åÓóÜðú‚Ö™ƒ±ö…y¥S$bouncycastle-1.49.orig/test/data/PKITS/certs/InvalidSelfIssuedinhibitPolicyMappingTest11EE.crt0000644000175000017500000000125110350736724031707 0ustar ebourgebourg0‚¥0‚ 0  *†H†÷ 0R1 0 UUS10U Test Certificates1'0%UinhibitPolicyMapping1 P1 subCA0 010419145720Z 110419145720Z0r1 0 UUS10U Test Certificates1G0EU>Invalid Self-Issued inhibitPolicyMapping EE Certificate Test110Ÿ0  *†H†÷ 0‰°8)c>Ïߘ[ÌF™‹R!?´é%ù¡íςȮÔ9—Æl¯3¥6ÄúWɤ»?6$Äåz×µó~,vOÚÈÑT–‡²_4ÐàÔš³ ªÜ<ê|mlUË·ÁËnjjï²¾²ì[ÉVôÐÁƒƒ‚ãøÿÛèZ7.'xÜŠ!Oƒ¸?3¯j\½Ž H•!Øvp±ø»w[œ&@}6)«^-¬ OGвýDÕÌ;ÃKÓVìQ2MkeU´ÄS‹¦â»Ôû±ä™Ž ¡nªÝÄ_†Ž AïÐM0aÅbouncycastle-1.49.orig/test/data/PKITS/certs/distributionPoint1CACert.crt0000644000175000017500000000117710350736724025716 0ustar ebourgebourg0‚{0‚ä J0  *†H†÷ 0@1 0 UUS10U Test Certificates10U Trust Anchor0 010419145720Z 110419145720Z0I1 0 UUS10U Test Certificates10U distributionPoint1 CA0Ÿ0  *†H†÷ 0‰èT€å_ÅŽ›SÇ)×ßij¾‹î³vúsve¥hý.N%F:ž`L–( ËÂ8[UÂm}â‡Võà"Yõœ{‹ŒHÊŠÙÁþ]>¡ÙTç/ôÍãDö?Ù¸ï­Þœð:~Qà}¿,ø ÏqçdÍ6 ¶\ÇOË£|0z0U#0€ûlÔ-žÊ'zž °<êš¼‡ÿIê0UžPWj…oøæA^ëzº0~ºô0Uÿ0U 00  `†He00Uÿ0ÿ0  *†H†÷ Ã:óVì{<Ïñ;S“VüÍXy=•Æ«Ùj¯‡¨¯ÆŸ%F¥=FË“®…Ýu9Be?ÅëùÈE|Q V>θžzW=µQ,ÂHñ—=¬Þ ÐPK(µqÛ)[Z˜˜2£¦¸ùÅE³»ˆœÎñ,‘JÑÙ¾o¯8èDnb<ŒÚîbouncycastle-1.49.orig/test/data/PKITS/certs/pathLenConstraint6subsubCA11Cert.crt0000644000175000017500000000122710350736725027215 0ustar ebourgebourg0‚“0‚ü 0  *†H†÷ 0M1 0 UUS10U Test Certificates1"0 UpathLenConstraint6 subCA10 010419145720Z 110419145720Z0Q1 0 UUS10U Test Certificates1&0$UpathLenConstraint6 subsubCA110Ÿ0  *†H†÷ 0‰Ò]`»/E‹7f^H)††—hŽ3€¯Ì*IYòÌc ³ƒÞ/4=v™]j!æ„G²ÅÒçHnҫ椒Wâ+uŸF,pÖ¶SªöîüÚ˜ýç䟾p.(;Í“áT-P™Ô8‡õh€Æë:¨Ú„U6ëÜ'ã£0}0U#0€D4áP&ÿ<# ­¿½NÆ{à HŠª0U³À÷Qö\šN,‡PQå‘ÓX[+0Uÿ0U 00  `†He00Uÿ0ÿ0  *†H†÷ 6º #Ãró!¥Ê¹ŸcG4Eä?È9‰¶šó£µ#ÿÍA6U ÐQé‰3 X•ˆ×"÷1¨™8åïú6‰ ÀÌëW5ÕkŠ`?Qú0˜œégG‰GÔ†í—v8¿»«•z3#ºèŠå%%R9_¦1e Üoð #jbouncycastle-1.49.orig/test/data/PKITS/certs/InvalidPolicyMappingTest4EE.crt0000644000175000017500000000122110350736725026271 0ustar ebourgebourg0‚0‚ö 0  *†H†÷ 0M1 0 UUS10U Test Certificates1"0 UP12 Mapping 1to3 subsubCA0 010419145720Z 110419145720Z0_1 0 UUS10U Test Certificates1402U+Invalid Policy Mapping EE Certificate Test40Ÿ0  *†H†÷ 0‰šk*‚a&L/ö MÔ†-1]îD>l¸zÆ*)\ ¾¦ ¨·näå)^L‘uF~#:Š8‚ÃRO\ªiæóÍò Bå—¢“O¹Ég@­£€¢0Bs³¥nõ¨ì£PþÜé IïÆø²S;ÔU/KîÑ›;Ü0úó'áƒpÀ„ÂM£k0i0U#0€ö,±·)µ®•°ø9AS-.ãÇ0U„cñ 2¿[i*8æ»Fsïv0Uÿð0U 00  `†He00  *†H†÷ º´¥gùé;jPJ¶¼ß,™¸ùK@86~kš”ü›sj;רzé8+ãEÍð‡s­ÏÎC_…z, Å×™y<˜ÐcèÊ$…mÙÉÏçOܪÏÞ®|ÙHªFÔ8¶wÖå–IÂ(8¤Íe3¢ áÜÚ~ò™ì[‚v'Po/ ¬bouncycastle-1.49.orig/test/data/PKITS/certs/nameConstraintsDN5CACert.crt0000644000175000017500000000151210350736725025555 0ustar ebourgebourg0‚F0‚¯ B0  *†H†÷ 0@1 0 UUS10U Test Certificates10U Trust Anchor0 010419145720Z 110419145720Z0J1 0 UUS10U Test Certificates10UnameConstraints DN5 CA0Ÿ0  *†H†÷ 0‰Æc2í|Ã{¦QQeÁw‘±* ‹øÒ~;õój×á¡Â[M*<éK‡Ò";7®°`Š4 <èS礈„ÿ%Ž~äxíë+ÖEì^÷~Öê~¬³ª…uû¾ˆ‰86L±èŒÁ ŒwÀœxûò.œ­öÝ;¬F§lM_­ÕšC£‚D0‚@0U#0€ûlÔ-žÊ'zž °<êš¼‡ÿIê0U5Ÿ¬Á¹¡ã:þñ/ºw²NMYí0Uÿ0U 00  `†He00Uÿ0ÿ0ÃUÿ¸0µ K0I¤G0E1 0 UUS10U Test Certificates10U permittedSubtree1¡f0d¤b0`1 0 UUS10U Test Certificates10U permittedSubtree110U excludedSubtree10  *†H†÷ §}£ãz[ cûeuâL¯š©Gý¨5ÍþÖ‡¢øÇ^ò¼t‚êw×$ }¯ê¶| ï!N N¸¬p!ªö:«7wT„9Ã&Ÿ/õ!ºÚ Y{yõÈ3~Ó½<9á ÄâkðRðÃTlöHœ.jbõùÌ„(1ôœTBô ¢íbouncycastle-1.49.orig/test/data/PKITS/certs/UserNoticeQualifierTest17EE.crt0000644000175000017500000000134710350736724026225 0ustar ebourgebourg0‚ã0‚L 0  *†H†÷ 0;1 0 UUS10U Test Certificates10UGood CA0 010419145720Z 110419145720Z0_1 0 UUS10U Test Certificates1402U+User Notice Qualifier EE Certificate Test170Ÿ0  *†H†÷ 0‰±¹A¹+Qü:hªú ’Œƒ-Ÿ•'Á¸‹UìTà6âa|ü‹ž'†(6wëiÙ¢Gpß1»æÙ‚·ðª·.ÅS¹>ä/'Å£Óíï3Bœm BÊ?²ÂÛíÞc^ÑÕ Гàá,FéWgumYˆÐ 0,8Ó™ëQ£Ò0Ï0U#0€·.¦‚ËÂȼ¨{'D×53ßš”Ç0UÎíòYåR0ËßsmâðYpÀ0Uÿð0}U v0t0rU 0j0h+0\Zq3: This is the user notice from qualifier 3. This certificate is for test purposes only0  *†H†÷ >+¦ò¢ýÀΗ»ÍZ… híŸWÇ2{åÙ7Äf›ÿ>(k[Wî¾!¡ *¦~×.'PC¥ç·°ö¼ª>*‚àÜnßÚͽð›XjGÿÿFïãìs[GÒùUÑÚD‡)uÑÞAç»ù^p#nÂRó#ÆuLj9 >¼àv¿ý­©[ÿ…¯¯aûŠ÷¿®ä«}ü'9ÐïA2Œ#5h³á·Òµ £éE6ÕyGÁÔÙ“"dÄOe"T*t§ðÌžo_Wj2!𕨄ªÀ£k0i0U#0€N.£çÙÝ‹§‚;AJÞ|Y#WNS0UšþEˆ>xáè¯$™™g4V¬H0Uÿð0U 00  `†He00  *†H†÷ iià}:IÃäñóÏý§¿ÓÁµ\PRÂC8At-w2_a//ùd±VŽ\g0 ®/NUm¹¡ÊiK›Â âÝÊÃsƒ½§½–Å…È®Ïb›iÐ8¦Ýd“AÑ}Z)c‘–£ë(ŠãÅŒE2v¢¦Í0qðÜ| É–¶ÞTg'®öY/bouncycastle-1.49.orig/test/data/PKITS/certs/UTF8StringEncodedNamesCACert.crt0000644000175000017500000000116710350736724026266 0ustar ebourgebourg0‚s0‚Ü b0  *†H†÷ 0@1 0 UUS10U Test Certificates10U Trust Anchor0 010419145720Z 110419145720Z0A1 0 UUS10U Test Certificates10U UTF8String CA0Ÿ0  *†H†÷ 0‰ÀܦR5Ó<¶Bmlo'üA ñ²«+û)ÚÒ-Qz;.ïù¾ß糖ÊjùØF/¸U0Ò‚‚\‚r¨qgèlR¢bïÛ£Ô8F‚§’_à›'nm¯lçx'ªÍ…[³ÔOÝ_˜.óQ¢ðB?ô/‡1*Ïèb€]Vײu¢"i‹+BR‰Ì{,öc!晃I×_yõU¥i ù£0}0U#0€ûlÔ-žÊ'zž °<êš¼‡ÿIê0U´¤·¢®¹vµËd¥z…J0Uÿ0U 00  `†He00Uÿ0ÿ0  *†H†÷ ¢ef¤H-¤6tÓ¬“šôEM­¶lõáHFGJ8èÒe53S| .³íg¡„Ô Ó#-ì˜sÆoS¸ŽØvöV£G B%z8q!4¶°AO’ù¾‡jäû¹ª„Ö=”»Ê]©Ý›*J¯¸æ)é î¬ÙàoÓàÞ‰´ƒ½ìBäãbouncycastle-1.49.orig/test/data/PKITS/certs/distributionPoint2CACert.crt0000644000175000017500000000117710350736724025717 0ustar ebourgebourg0‚{0‚ä K0  *†H†÷ 0@1 0 UUS10U Test Certificates10U Trust Anchor0 010419145720Z 110419145720Z0I1 0 UUS10U Test Certificates10U distributionPoint2 CA0Ÿ0  *†H†÷ 0‰¬Ö0ýPÿY\UÎö•åÁªÞ uqq 9Cså¶Få"•ÑŒè[·ÚA¨ÌìHRãRŒ·|!)ÚH y ;æ¶³áyzˆ³ÁŸNæûHÃ¥ÀíÞDÀZösÏH6b ŽB¶^?Jí⊻ÞkPXÉ3ºŸfç“$|þªÔE!«îൣ|0z0U#0€ûlÔ-žÊ'zž °<êš¼‡ÿIê0U:4‹ãvXXć˜}~Œ¬]¹N0Uÿ0U 00  `†He00Uÿ0ÿ0  *†H†÷ Æ j½þSôå® ò àÎ"ðc¤m³H: Œuo_ÂÿC¼‚r ïë¹Ê’]cÚ,T‘ò•OÖ¡+‡è{çHÀ§\‘U·(G×ëèÕ¥§ Šè t,‚{‰(¹÷ͬºìyq£DN¾rEž À®£‘[˜ÿGÕabouncycastle-1.49.orig/test/data/PKITS/certs/requireExplicitPolicy7subCARE2Cert.crt0000644000175000017500000000125110350736724027545 0ustar ebourgebourg0‚¥0‚ 0  *†H†÷ 0M1 0 UUS10U Test Certificates1"0 UrequireExplicitPolicy7 CA0 010419145720Z 110419145720Z0S1 0 UUS10U Test Certificates1(0&UrequireExplicitPolicy7 subCARE20Ÿ0  *†H†÷ 0‰ß.û? |=pÆã*ó—ÙHH+ÇINñÜÆHwÁáý£ýþRR£ÒÑ;yBYãuŠWI,žÈë1wÑ׎ÍFÌ$ÕÚ\&-oñ1cÆdï¶tÆNÉ3äêÆ ïr£¯+?æL¼.úžžÚs³úÖÔ½Ò Ø÷É_t½£Ž0‹0U#0€"çÛpˆNòb/p˵ÁÍNM0Uëh Æå/Ãó QK³Xsœ9?K0Uÿ0U 00  `†He00Uÿ0ÿ0U$ÿ0€0  *†H†÷ !G~Ÿç¹}Ó;\[ãCùú"„øOEÛ€~Òh`«Þ~FãÆYŒ…!G'µRÀʉ•nýîoòø/… ù*µ°T8òpk€˜XËŸEI€…ò>Ö`úwŒ ³¾HMØŠ$2líÜ‚T² Ë^×(„ÎÂã-$”šG~{B0ùXbqŠbouncycastle-1.49.orig/test/data/PKITS/certs/nameConstraintsDN3CACert.crt0000644000175000017500000000133410350736724025554 0ustar ebourgebourg0‚Ø0‚A @0  *†H†÷ 0@1 0 UUS10U Test Certificates10U Trust Anchor0 010419145720Z 110419145720Z0J1 0 UUS10U Test Certificates10UnameConstraints DN3 CA0Ÿ0  *†H†÷ 0‰¶.Nuú7¥'ú§È†ŒÓÁ)J£:rÈÆ×K#¦ ﹚e–h˪…ÞêØ–‰çµ÷¥ËÃ'oåà÷: Y5—~iÔH”úÅPò˜9ÕK¿4 Ž$Ñ? ÏÂÂg‹0ý(·+Чþ{Ñ¢,pe©“8×ý(%nùcœÍ6!aã§Ñ£×0Ô0U#0€ûlÔ-žÊ'zž °<êš¼‡ÿIê0U‹ã¸XVŸjß=Ø;³6á˶Ê0Uÿ0U 00  `†He00Uÿ0ÿ0XUÿN0L¡J0H¤F0D1 0 UUS10U Test Certificates10U excludedSubtree10  *†H†÷ ¹.‘nIo±tF ìLjWÙ_ÇçáIaþ^® R¢ùg#b(‹‘t±„+®ÈÁ˜?Š÷é&ÜK‡[Œ©÷ËÌ@ñYŠ>™­T•øz¨¯ð.„€lÅk;EkfÃ6Ä©R×*ù±ŒkP×Þn~¡Z‡ðÝP\š ¢YÀbouncycastle-1.49.orig/test/data/PKITS/certs/InvalidDNnameConstraintsTest15EE.crt0000644000175000017500000000126210350736724027176 0ustar ebourgebourg0‚®0‚ 0  *†H†÷ 0N1 0 UUS10U Test Certificates1#0!UnameConstraints DN3 subCA10 010419145720Z 110419145720Z01 0 UUS10U Test Certificates10U excludedSubtree11907U0Invalid DN nameConstraints EE Certificate Test150Ÿ0  *†H†÷ 0‰²Ð??>Ø–ºúÂJIÿ)A/NµZÕ’îòJü´M,Wý3&V5䜤õœåiøbœ(—‚±»í‡òec¹,5ì-ø1†¦xu)ïƒóEؾ5Ô—†5NÌ~úî”Ò"’I¯4ô¥LšÏY  øúc¾äù§åÑ_»ðFâƒJÀ£k0i0U#0€­’.+ÑøŠ±·!.~Ži<4u0U©“gÏ ‰ÔÆXz$ÃÈŽkÅéè0Uÿð0U 00  `†He00  *†H†÷ 'ØŸ>ׯͲµÇ%î¯ûZïêÿJ/ݺ™÷”,SЈÏ§iåy&­‡“|¤P&*óY}´A“¿ÍÁ3ÐÆïmK ñY¸PuîÇôÜ3 |8!,·nÏ·#ÎÇÀ|³ˆ/N¶¼–%Ÿgi@JCWu6æÎB­¾©¸5Ž9,ªbouncycastle-1.49.orig/test/data/PKITS/certs/requireExplicitPolicy4CACert.crt0000644000175000017500000000122610350736724026521 0ustar ebourgebourg0‚’0‚û ,0  *†H†÷ 0@1 0 UUS10U Test Certificates10U Trust Anchor0 010419145720Z 110419145720Z0M1 0 UUS10U Test Certificates1"0 UrequireExplicitPolicy4 CA0Ÿ0  *†H†÷ 0‰ä¶½|á>);6y]f`QMÈÓŠ÷æRŸâÝÁŒÚ–ÀìXY0™P•ƒHçAn"¹=ìkyjô“¸eCz0pðNÐ —Ê´èè8×.Òÿ=ŠrÜ·õª¾s´íLJÁ0Î –5Ö– 1êÎ6  Áà2«"£¯RßšbPªg£Ž0‹0U#0€ûlÔ-žÊ'zž °<êš¼‡ÿIê0U%~´ вóÁGðAyï²Bæ5û0Uÿ0U 00  `†He00Uÿ0ÿ0U$ÿ0€0  *†H†÷ =CF1½>ræÓ@À?xÖÞiO—†µÎ£ ·¿Úßß@.óÁ—äm…%:¥üŽðU 1Èqwe§}AüßëçNÒ?Q†Q*€)9øZ…±ºCÑ<®Ð«º‹ÃF  ™±"ÑîäP8$РΨÝT¦# +sÔírk˵–Ä•bouncycastle-1.49.orig/test/data/PKITS/certs/DSACACert.crt0000644000175000017500000000161210350736724022505 0ustar ebourgebourg0‚†0‚ï Ñ0  *†H†÷ 0@1 0 UUS10U Test Certificates10U Trust Anchor0 010419145720Z 110419145720Z0:1 0 UUS10U Test Certificates10 UDSA CA0‚·0‚,*†HÎ80‚ßå>Úé¶nÖêâ:°G½DÇVÈÌnÐ3„VG5=öTÈã­»ºuó/3 ¦ù1ìgãå™mü)nªWˆr4âŽà£¬dŽÀö<´ÈJH0^ªœv& Ûs3ƒ—Àųæ7õ>ÿ Ô¡.º1ø«‡Ø Ìw˜Bn¬“˜Â½.{4 ÏØÿ‹ëéö\–sý–e:/Ìá|°Î’_cì8»DºÝ’4¶^¾e{Øqwìf|;ζóRþ’UïN«]š./nVópìjí›"¸¨Ë œêÁ Ž!&D¥ ù ìbàp1Ìhõ …¤JnyôÁù6Z8oNï„SßgýÌ÷YbœœÍ\¤œ·ì`ó¾¯~9˜„€ò¹Ø¾B+Å„¾‘üŒ2r‹¨l!׈Šº0euÀ=‚ie§¬z…{åSÂ`ü±Ïg¯Áò.2j8Ç‘N;¼< Ðùqmß'ItؽFÐÛQ¥Sº‡óú]%ƒO uå©ã‰§Awc@_+,„ÒÁqx ÛkWáç žÄö29£|0z0UtÕ$½^eˆá‹ ~êHNa0U#0€ûlÔ-žÊ'zž °<êš¼‡ÿIê0U 00  `†He00Uÿ0Uÿ0ÿ0  *†H†÷ :;rw,ºÜìõ[EÎ?¤?ä²ÁúŸØ \˜âî~c:ÒȰâ¼ÀÖË(!0vFÍÓ=ˆœÌtR««ËPûÄÜ¥r}3„•}°Cô¼ a ê$§T–Á¶ÆE] ¦«ù¬(ß%Ã~!ÞŠC%õ§>žeBR©~`ÈŠb6bouncycastle-1.49.orig/test/data/PKITS/certs/requireExplicitPolicy10subsubsubCACert.crt0000644000175000017500000000124110350736724030531 0ustar ebourgebourg0‚0‚ 0  *†H†÷ 0T1 0 UUS10U Test Certificates1)0'U requireExplicitPolicy10 subsubCA0 010419145720Z 110419145720Z0W1 0 UUS10U Test Certificates1,0*U#requireExplicitPolicy10 subsubsubCA0Ÿ0  *†H†÷ 0‰º=ÂPyF_òX£„,vfóžÍ}ØìD -Zñ‡;}ü‡’µ¿A1B#ƒ2!èêÎÎ'FCª˜èîÑUØ…û¾ÓXø-2©Ú, •âÛ!îBgóÖjÈý‹_Yã××ìÌÒ¯¶pfŸêÂ"¨¦8©Š>Å È$ ‰ŠSv^5Ày£|0z0U#0€mh1ýù_Rùû.ÚDÂÏ{6™Øÿ)0U”×wÅq*ÔÓoôQ ¶Ú¬2ã¯0Uÿ0U 00  `†He00Uÿ0ÿ0  *†H†÷ '€¨Ç{& ¯¹z1…ëTY þ’?ä[Y[ûãÆÄS+|MHi¡ÇdΟqD±|öEÃðÀVò³ŠÄ4Z¿V“ó Zˆ[ŸcÕ»ÒC8ÍfiÔËZBèRÜðs‡_ _õ£4VG#¥>çö&v$Æ ¢Òšk…0ÂÆ¡X•«Kè›bouncycastle-1.49.orig/test/data/PKITS/certs/inhibitAnyPolicy5subCACert.crt0000644000175000017500000000123210350736725026152 0ustar ebourgebourg0‚–0‚ÿ 0  *†H†÷ 0H1 0 UUS10U Test Certificates10UinhibitAnyPolicy5 CA0 010419145720Z 110419145720Z0K1 0 UUS10U Test Certificates1 0UinhibitAnyPolicy5 subCA0Ÿ0  *†H†÷ 0‰«5#x>S$¾Ó´üQ]M'1ÉÁi[" ZM»tïÑ|ŸHåjÿb×>ÀÉ tÎÔO*Ó~2\Í¿‡Gí¿E‹r-5TH8´H¶ØËÂZ]Nl½0¼4…” üÏ0è`ödLM…õ¨¼çyäßÞ à ¯Ä5FzBV±Ñ£Œ0‰0U#0€ÆŒq¦™b¦ÒToònÊ0µ:¿0UJwbX#¢Ã¹îÇnß퉈M—o0Uÿ0U 00  `†He00Uÿ0ÿ0 U6ÿ0  *†H†÷ ³•ð|BoÇ_¡[n1°MÑ~bœ¯o¨¥x«ôÿ¼ˆÍX+˜‡Úðàí9«|4}Q'•P¿bÙŸ ÷ǬJX&M$,ÊÄÕϽ,ƒÐûg4ÉãšÈ†qt–ý†'Tìø«¡]lWœQHe.EÉ#¨wňÖ6ÈsDeâÚbouncycastle-1.49.orig/test/data/PKITS/certs/CPSPointerQualifierTest20EE.crt0000644000175000017500000000127510350736724026125 0ustar ebourgebourg0‚¹0‚" 0  *†H†÷ 0;1 0 UUS10U Test Certificates10UGood CA0 010419145720Z 110419145720Z0_1 0 UUS10U Test Certificates1402U+CPS Pointer Qualifier EE Certificate Test200Ÿ0  *†H†÷ 0‰Ê h¿Û„膈º`ïÛ^¾ LÔŸ» íÅcFGQ'gÓï¦ Ro)óQ¢|bò§A‹Qb³‘UM8}cXŸºä #ÞT@âžâôŠëÖ¦ã[ˆx|¤©Îà>Eô×%G¡αá­qB HzãV®õí£¨0¥0U#0€·.¦‚ËÂȼ¨{'D×53ßš”Ç0UÂÜš\"pÓ H…ž¯ÈØ”¨ ês0Uÿð0SU L0J0H `†He00:08+,http://csrc.nist.gov/csor/pkireg.htm#pkitest0  *†H†÷ |:=]‹ã)Îí7Ó½LÖ‡#}8œ5aO’?lä>àÝà|l#QJÓŠµ5²'äÎUù7G´Ò–zUÖk‚\©ŸƒTqÍ*ŽÚЇL9ÅpÂ2#•=*AѼxÂÈ©ÓÔ¤0ÚK\%eý³°Ù,þZ»wo»¹Ü CÎbouncycastle-1.49.orig/test/data/PKITS/certs/InvalidDNnameConstraintsTest16EE.crt0000644000175000017500000000126210350736724027177 0ustar ebourgebourg0‚®0‚ 0  *†H†÷ 0N1 0 UUS10U Test Certificates1#0!UnameConstraints DN3 subCA10 010419145720Z 110419145720Z01 0 UUS10U Test Certificates10U excludedSubtree21907U0Invalid DN nameConstraints EE Certificate Test160Ÿ0  *†H†÷ 0‰áçUÚJ‘ ¥Íí=Âg"ú]pÕvZ—š1{ÞoEcÊ%A2N N¼È'þå/Ò©ÎÍp+Öí@çx²bˆá =tsè ô·3òµ¹QeÑCÈO ±ÏaI­ûï— ÿ(ñuØÀRÇ[- n­BÚj9ZE£k0i0U#0€­’.+ÑøŠ±·!.~Ži<4u0U÷Kf]‘4Ó¿4Øñ¨ i?0Uÿð0U 00  `†He00  *†H†÷ ›XuùG,EP V«Û¹D­§¬‹­W¦€9k#¶è߸֘òæÛÏ¿Ìn ëæ+OÊ2pÜ!y-EƒuûA?Îl ÖÅ£Ò5“h ‡4pêR}€ò‘;«v§Q °‚­ke XÖÇ…6Œr–ÎLÄQvèkžbouncycastle-1.49.orig/test/data/PKITS/certs/inhibitAnyPolicy5CACert.crt0000644000175000017500000000123510350736725025443 0ustar ebourgebourg0‚™0‚ =0  *†H†÷ 0@1 0 UUS10U Test Certificates10U Trust Anchor0 010419145720Z 110419145720Z0H1 0 UUS10U Test Certificates10UinhibitAnyPolicy5 CA0Ÿ0  *†H†÷ 0‰óìæ|»~ †2:p6’¿,£!cÏWNmó峘‹9>7â ù‡îÉ}{˜âgÃïù¬è©«Q H˜5¦]QVšjÛbÈŸ#¢Î6U)ÍS¦¶¾²¢Ûc@â kJ˜xà= P*.¡þ¸Jku¾Â Ý*¢ZJ‚ƒEÅ­zS,õ£š0—0U#0€ûlÔ-žÊ'zž °<êš¼‡ÿIê0UÆŒq¦™b¦ÒToònÊ0µ:¿0Uÿ0U 00  `†He00Uÿ0ÿ0 U$0€0 U6ÿ0  *†H†÷ k~3ãÈ1Ö¶ Ÿ%êð£ƒàÑEèËZ1œ¤ùÑ ƒøŠxΧüà…oti SªçÚ¥'9Ž$ñq×Xä“JÒÿ©‹¸/°ðÙ«üÃ9Ñ+½ùj+‚ì ©.íCŸH½ïLðóι•wp *ôáoþŒûw(=Üzbouncycastle-1.49.orig/test/data/PKITS/certs/ValidinhibitPolicyMappingTest2EE.crt0000644000175000017500000000123310350736725027312 0ustar ebourgebourg0‚—0‚ 0  *†H†÷ 0S1 0 UUS10U Test Certificates1(0&UinhibitPolicyMapping1 P12 subCA0 010419145720Z 110419145720Z0c1 0 UUS10U Test Certificates1806U/Valid inhibitPolicyMapping EE Certificate Test20Ÿ0  *†H†÷ 0‰ÙÁä¡ÁXìÖ©ž£Æ@âÆ•ËPÝ5àËù±0Ñyˆ+G;EÔ –Ôå=*ZÞ¾¾9ø3q“~~PU¤Þ(Î27ÜM6÷щBw—å`f ±´„ØzxÇ º„nRj—GûÂF“›žÃÎhèúÅ™L –åða³_ºšHvšœòq£k0i0U#0€zŠ0öê\6@ ®ØŸ¿¹½‚ÌR0U¯—htp[¯ožnX46âUÑ>0Uÿð0U 00  `†He00  *†H†÷ ­¤~3dŠŸ®…ø¯ws¥øŸ”“›B0±+Æ“‡_kc,ª«Xk«lü^ò øÂP:4áÛF&I…õ¢ÙL42®ÞôL1íVN±K’à@ë\DY»ÐvJ‡•>hé—ó$“øuˆmn—€¤&z¢;‚ì&f0|Çbouncycastle-1.49.orig/test/data/PKITS/certs/DifferentPoliciesTest8EE.crt0000644000175000017500000000123610350736724025616 0ustar ebourgebourg0‚š0‚ 0  *†H†÷ 0M1 0 UUS10U Test Certificates1"0 UPolicies P12 subsubCAP1P20 010419145720Z 110419145720Z0[1 0 UUS10U Test Certificates100.U'Different Policies EE Certificate Test80Ÿ0  *†H†÷ 0‰ÄšÌc¢nùX__[ÚZ'_ˆõ å Ë™EîÍ••í«ôSCËזּŒò¬²¦÷\‚ùRÑ•.F2ŸâÞ•€»Dú ›âg¸‡U(Ì ´:ØóE0¾2È"’¾uЉí¢}š’BFœ:ô8Ï» ^²Š§MkÛV§£ä6ü$ô§£|0z0U#0€gå Œl*»Um-è"ªKs+ˆ*0UáïûIˆþwüóÓ2+°ûQ ‡r‘0Uÿö0U 00  `†He00Uÿ0ÿ0  *†H†÷ $W³'ò_Þ{ý*ì>WĹu{ǼÀ)E}ÿžc@úEå~õ svLèuˆ< mV‘«à!/hò Éox[”´ÝŠžßô×Aˆ#-4ÚÁJ˜p'™fRãî—…á«ÕWƒâÆ«pûgVÊbQÎeäÇX`KõÈ4U7Valid Name Chaining Capitalization EE Certificate Test50Ÿ0  *†H†÷ 0‰¢£6$eSöÿÒCx*ªŒð`œýs¨«²«ÒÕ+Ÿ ¬§HKÑòoÄ`2½Š[#ÍOç`¤]:óRÎMaÇÕHA'ÑŒ~ŽY$Nóm^—áK¾.RNù’ÔRÔ#§:å´€"7틯 ‚ïUÐÉ`8ÿ¦h,ØX;|êº3 þ×ENkŸ£k0i0U#0€·.¦‚ËÂȼ¨{'D×53ßš”Ç0ULîðùoÈ÷€„ÅËd:xýøQð0Uÿð0U 00  `†He00  *†H†÷ UÕ¸2KÛ ¨[l{d‘±@†¼VâBtëò‚LÔ:åÕƒ¼X¹ÍNØí iã{Ôïl‘|° õ§#bm vÚïݰӘ¢ØáÏÕá¥-Ãa¥]C°€éÄ ‚oŸcÈÒÖn·SfíÐ[8çÏ¿dX'‹\à«íì3ebouncycastle-1.49.orig/test/data/PKITS/certs/keyUsageNotCriticalcRLSignFalseCACert.crt0000644000175000017500000000121510350736725030204 0ustar ebourgebourg0‚‰0‚ò !0  *†H†÷ 0@1 0 UUS10U Test Certificates10U Trust Anchor0 010419145720Z 110419145720Z0Z1 0 UUS10U Test Certificates1/0-U&keyUsage Not Critical cRLSign False CA0Ÿ0  *†H†÷ 0‰ÂΛÀŒfátžÀå3KÆ*(;þ±+ØnïÍÓ!Œ=nÕª2ø`Q\†s  nô„”ÁÓ¹GÝÝ£¨þ)ïOv>ç¢Z£p胡¿Á[}¯ép5­.Òý€k·˜>i„ãm¿½y; ÓÕLë&в¾‘‡’ës£y0w0U#0€ûlÔ-žÊ'zž °<êš¼‡ÿIê0U›¤[ä"XµVÿ.²‚¿"èöø0 U0U 00  `†He00Uÿ0ÿ0  *†H†÷ ]¬³D`oFÙÉÝ–>Ý¢ŽÀvÑI»Ö(GºÙÝ„òfä’NM»è„2‚.[êÍ™“D7<4Ô†Õy5¨§Å »*šðx^BÊ×ÊwÙÃt†<5!OŠ¥Â\ƒ©rø²=wÄ'üιJB%öê%[‡óŸŠ(ùoËbouncycastle-1.49.orig/test/data/PKITS/certs/requireExplicitPolicy0CACert.crt0000644000175000017500000000122610350736724026515 0ustar ebourgebourg0‚’0‚û -0  *†H†÷ 0@1 0 UUS10U Test Certificates10U Trust Anchor0 010419145720Z 110419145720Z0M1 0 UUS10U Test Certificates1"0 UrequireExplicitPolicy0 CA0Ÿ0  *†H†÷ 0‰¼El,Â÷N„Ï}(Š tO|ø¼Ð‘ýpC:ˆê¥¥ðoº—‚–g!o„ÅÉxwšHSü;•iRp¡¥Ô¨ª+%È­¾qЛ1ÊXM…H'ìïóSµ²¸`Äá%4@ÔvOð´˜á_VGN†rfÌ FQŽó™ôá¶OØ'ãØó£Ž0‹0U#0€ûlÔ-žÊ'zž °<êš¼‡ÿIê0Uwj³dõ±ìQz-e†ÿ~ JŽ'0Uÿ0U 00  `†He00Uÿ0ÿ0U$ÿ0€0  *†H†÷ Z€[žb¯tŸboH—k8»Âiï´öq'lKõ¿ÚÌU0¡C?"I¼ê,#ÄØ6à°Âx·f´0 ö ´ÛyEéÐï:˜²¸ëõ„¶œneÕÀœ½åenkTuñAgšOÇqkÅþí%öUbÂ$&›ÀæÅöŽƒ&¸ý/mbouncycastle-1.49.orig/test/data/PKITS/certs/PoliciesP2subCA2Cert.crt0000644000175000017500000000120710350736724024643 0ustar ebourgebourg0‚ƒ0‚ì 0  *†H†÷ 0;1 0 UUS10U Test Certificates10UGood CA0 010419145720Z 110419145720Z0F1 0 UUS10U Test Certificates10UPolicies P2 subCA20Ÿ0  *†H†÷ 0‰´´Îë"ˆ]ÝXù¯t–8L—™9þdˆJ*fï‡ì4ûÂ$àtòZí›&}¦]——kœNPñ½c7**#ñ/¨}»‹xпŽÉªNd¨˜ÊEâö0®ŠR»y&öµ4Œ_áN{Yå®_3š§ˆÄ'ù(w—¡‹uÀJÁÙ»×£‹0ˆ0U#0€·.¦‚ËÂȼ¨{'D×53ßš”Ç0Uqë/íQ¥ÿ…IŒ|öK¦›¤”0Uÿ0U 00  `†He00Uÿ0ÿ0 U$0€0  *†H†÷ ¦ümGä+šE}»âPï~1x~Ôݦ›ö™Ðö©1ÚãÆ‹0ßãîm>co`¡Ý€l ®iRõYņàðÑ),â‡àŒå‚¬í +];`̓0ÅÆìjªÈ=-"E–yÁêõ£=mÓü¼çudÁ¹•*×{XÿÂJÈNÞbouncycastle-1.49.orig/test/data/PKITS/certs/basicConstraintsCriticalcAFalseCACert.crt0000644000175000017500000000121410350736724030277 0ustar ebourgebourg0‚ˆ0‚ñ 0  *†H†÷ 0@1 0 UUS10U Test Certificates10U Trust Anchor0 010419145720Z 110419145720Z0Y1 0 UUS10U Test Certificates1.0,U%basicConstraints Critical cA False CA0Ÿ0  *†H†÷ 0‰²j¼{H‡-:Æ”ñ)ý'eÈ=%Ñ£èËÿˆ«¥±´èÙ‚™¡}bÄX(¥ߗÈbR%{@ÖÍtZ~8ý.œG6‚E§DYåFiFÃíc¡P®þºXÜ ‘4©|æoCï¿>匼0Ìï}„ðŸ"íN·ß¥/Aá_£y0w0U#0€ûlÔ-žÊ'zž °<êš¼‡ÿIê0UÇGOt"‚š”˜E³µCÃu6Î0Uÿ0U 00  `†He00 Uÿ00  *†H†÷ ˜˜’¶äã[oŠ XÓ"†½ CÁ<‰à"f°aˆþ»RŽ÷ÅŠ¡Ïš­œý¦ú(ʤ„eÍ5O*o).ªÅl Ö]!¹9åªç rC^Õé÷V æ –\«Îž7$¬?úé>øs¾¨úN_Ç:4iHÝ\ÒƒÍãÒbouncycastle-1.49.orig/test/data/PKITS/certs/inhibitPolicyMapping1P12subsubCAIPM5Cert.crt0000644000175000017500000000133710350736724030447 0ustar ebourgebourg0‚Û0‚D 0  *†H†÷ 0W1 0 UUS10U Test Certificates1,0*U#inhibitPolicyMapping1 P12 subCAIPM50 010419145720Z 110419145720Z0Z1 0 UUS10U Test Certificates1/0-U&inhibitPolicyMapping1 P12 subsubCAIPM50Ÿ0  *†H†÷ 0‰¡kCKµ'U–z4¢ý†’žå >ËZÅ׎ݷº<žßd¶óªŒúr¸á:=ãîîB^ú4×>æ"÷ñ¿¬÷qòà¦_˜güÊ/­A=8ù°¸—“DB‚” öl¡äÃM|ƒÜpÖ09I‰õÊ€6)iª8ç!CðÝ ÷|¥Ç£³0°0U#0€æÞŽV°ó–ÊĪN’º 𔩔p>0U$«U•‹•×DÇÝÿ~ýö‘± 0Uÿ0%U 00  `†He00  `†He00&U!ÿ00 `†He0 `†He00Uÿ0ÿ0  *†H†÷ ‰šÌ9«Ó½‚êCò€ŽÍ‚¸ê Цné&o4ŸÖÁŽ6h‹+Ž$ÊH Ó6Xãä¡uNB#kž Ü”×_e­>kßÇÛÕNT¨-°Hq7¡`Êq©­¢8ìišsôE§*RDd‚–Z›Ííœ1s§‡L,A`9“Lû…{‡âbouncycastle-1.49.orig/test/data/PKITS/certs/ValidDNnameConstraintsTest14EE.crt0000644000175000017500000000122410350736724026644 0ustar ebourgebourg0‚0‚ù 0  *†H†÷ 0j1 0 UUS10U Test Certificates10U permittedSubtree11#0!UnameConstraints DN1 subCA20 010419145720Z 110419145720Z00Ÿ0  *†H†÷ 0‰®g×Q,%÷÷Ö'.€îùc±ÐùD~«ý§G)Øð‹î\i¤êgý˜1¦aÜ;(}ý+$=|»¬Åê=Ä ™í™ˆîÞ¸z¦~•Me‚qèIVÔÊømï¦Ò,Èñluf.²6‘Ñ'Š¡/ÓêÈñ—OÙgþ™ù£¯0¬0U#0€Õ¯k( ­Hl ‚*ÿÒh /mW0U;ôÏô1¨$¥¦bçJlîd«“(0Uÿð0U 00  `†He00AUÿ7053ValidDNnameConstraintsTest14EE@testcertificates.gov0  *†H†÷ Gã²úÕÊpíEk„Q«] ²ªë·54ø…G@vÊXª ¼ÔP qÑ6fjÀ¹ËXN¹=:Ø*óRC¼Pcm9ˆC>¼õ/ g¤ÐùX `—¾Æêö}"–Ί¯~ÓÅhçßÝ`T%¶ÓžÉ‹$ÃsZ¤Ç_ÞŸ=¡3 AüVbouncycastle-1.49.orig/test/data/PKITS/certs/inhibitAnyPolicyTest3EE.crt0000644000175000017500000000121210350736724025463 0ustar ebourgebourg0‚†0‚ï 0  *†H†÷ 0L1 0 UUS10U Test Certificates1!0UinhibitAnyPolicy1 subCA10 010419145720Z 110419145720Z0Y1 0 UUS10U Test Certificates1.0,U%inhibitAnyPolicy EE Certificate Test30Ÿ0  *†H†÷ 0‰æ–“ãÞ›¡6v¡/•Zf)cÞ”xÛº ’EÊů×ÃZ=:Æ÷T8Œ2D ©¬<Ø’Ö=M 棜´^;ë£k0i0U#0€) x”Ž„)BK|«ƒ*¾5[<0UUè©dÛ“’¿oA›Ç1° —ä±0Uÿð0U 00  `†He00  *†H†÷ F¡@ó:Ùý>Sâ e³%U¯iÔ‚Ò]+ “â¥Áà%5—u·†è×Õ„© 6ú ®>óqø:Í›®0&ß|¹ÊÂgŠ!¸C×Ôjå1)ùJ€¨Ì{{¨éSH~^ràòýn=#k£"› ‰´lÒܦÒçÿâÚßîš§¸âúsbouncycastle-1.49.orig/test/data/PKITS/certs/InvalidDSASignatureTest6EE.crt0000644000175000017500000000147310350736724026021 0ustar ebourgebourg0‚70‚ö 0 *†HÎ80:1 0 UUS10U Test Certificates10 UDSA CA0 010419145720Z 110419145720Z0^1 0 UUS10U Test Certificates1301U*Invalid DSA Signature EE Certificate Test60‚¶0‚+*†HÎ80‚½°z<´I}æÉ‘Íc*ÏEhey%©e¹P˯j²ýÁsÞ™¬eÎ'óî> 1êØ¿{¶(ÿeFåÍ¥)ø/Á€uppA'6[:¡{K²¡VýªðÎBå6ï4Tw)š®cªI÷>®áÂùö‰2ÿ™h{ùÎ4]ñ|)d{4d­—c BÊŸ¸ ~:å3¤.[À`_mCF<‚ð~ŠÂF½:@ë§n-Õ„fxí0¬®M×hñ ønöó:¥•Ù)¼‘A¶n•õ¡;ò¦‘$Ttƒf NþKâ€"õÚ’¹ÉÍÜŠøû}©¬•øÉÌn"X±µ9,÷ljÂS÷hñŒ¸!ÌI“7ä/ó·XMJ„€-i¯Ý0+[C»`^ƒ ÐÎL9êö†'èìÿ“tʳ¦¨Ý‚áÒFŠºŸ'?ßwg€ N*ɘ¸)há_oæÄ5¬ökƒíô2õÓš»{™PM*¢QÎ…WR”A2µé$Îl`Q-zÝ  Š¶Bùœl|w9•ëM.Ù‚ò‚7E Уk0i0UÜfi9r§°:ß}Ó0¿N´~ ñ0U#0€tÕ$½^eˆá‹ ~êHNa0U 00  `†He00UÿÀ0 *†HÎ800-¼n£&ÒÅ9VÿÞ|QÞ³ ÂÔ^ KìçMêÊãù!çv9ÕÜlbouncycastle-1.49.orig/test/data/PKITS/certs/ValidSelfIssuedinhibitAnyPolicyTest9EE.crt0000644000175000017500000000123410350736725030445 0ustar ebourgebourg0‚˜0‚ 0  *†H†÷ 0L1 0 UUS10U Test Certificates1!0UinhibitAnyPolicy1 subCA20 010419145720Z 110419145720Z0k1 0 UUS10U Test Certificates1@0>U7Valid Self-Issued inhibitAnyPolicy EE Certificate Test90Ÿ0  *†H†÷ 0‰ªIWëX«ÚÄ.¹9;FY£h;ò•·MÔ7ýü[;õ:•‚årtΦceOGTa/ºpýeÖN)(€;„dù'ß»é)áGP ?#@ФÈöåÈ\2{k_RnÈl9(Þ÷U‡Ê M>Ø`AìÌ@Du)ežäø\‰£k0i0U#0€݉f¹âwލΤ‚² ¤Æ¦z0U—ø‹ë—A|ÿ8Qê2SŒû{Ô0Uÿð0U 00  `†He00  *†H†÷ ƒÛ¾œÄKRÙA\p-œgïPÅ*vüÕÔ$‚ÊZí¯ŸML˜ ³+â¦}γ$0Ë“¼kÛÒÁ’f|´™`a` “dTÞæž‚y “ GÅ—ãø%+æˆ{giAΚêÊŸøªw.¾‚)iaû~ùé;"œª»ChT†°bouncycastle-1.49.orig/test/data/PKITS/certs/InvalidBasicSelfIssuedNewWithOldTest5EE.crt0000644000175000017500000000124410350736725030501 0ustar ebourgebourg0‚ 0‚  0  *†H†÷ 0P1 0 UUS10U Test Certificates1%0#UBasic Self-Issued Old Key CA0 010419145720Z 110419145720Z0o1 0 UUS10U Test Certificates1D0BU;Invalid Basic Self-Issued New With Old EE Certificate Test50Ÿ0  *†H†÷ 0‰“Žt.YHÇ3гŸÉ>)ûµ©Db°0ª|ŽVáK»š&²£ýûžB±5ÎRSúiþÇkÛ¼ çë,nVÀù§ÕØ ¢±GDм±£L`¡JVfhú òÓ6PœÀ!-¡î„ ë` ?ÕŒ^ÊßrÔSqÈÈil&yÓ8%«£k0i0U#0€ú¢j¹îúOÅruÓKzmŒä\9$0USC”z£å÷«ÂÎÛ]Ùc£8·0Uÿð0U 00  `†He00  *†H†÷ 3ÌõÑ*æÐ€ §{¿‘ª2ûÁ3‹t;ûW Œ‚ÕÁT§X ©·z ÷WÓøk eŽˆféñù!|_ “õR¦¡qÄÓþm8óh#‚¡±x0¿r®ª–"0q2ÊÄoÝu#ÚeT”´ n9 §9z Ë´3bíòo2¦_b áDbouncycastle-1.49.orig/test/data/PKITS/certs/inhibitAnyPolicy1subCA1Cert.crt0000644000175000017500000000120410350736725026226 0ustar ebourgebourg0‚€0‚é 0  *†H†÷ 0H1 0 UUS10U Test Certificates10UinhibitAnyPolicy1 CA0 010419145720Z 110419145720Z0L1 0 UUS10U Test Certificates1!0UinhibitAnyPolicy1 subCA10Ÿ0  *†H†÷ 0‰Ëî3šëènŸ™ÁVÂÍ»^U¤ÀÌŒ[œ›ôÆ•okÞB#uàˆt‘üMEëÇÝSá4á+A  Ñ½~ -üû /ÈØ÷ ¨êÇäH:ÿ”ö$mHó}ó±ÿ‘îìz¨{q%NEú à«©tA7‹h18ÑåM?û]]壥£v0t0U#0€fÛµ”Çij>+‘¹ßȨÐM+4D0U) x”Ž„)BK|«ƒ*¾5[<0Uÿ0U  00U 0Uÿ0ÿ0  *†H†÷ ¸¦TÊ ½Ooše?¿ruÔPsÖv¯Á@÷a$»«j皦6¹É‡_Áõ&áAJ¯,¿5|Š€‘cÀ4 +ƒTý”¤’;_MÂræ†,UxóÐÌ‹(ì+·£ðÂÙ±E¿L‡ù{žä=³‘ ´P„JþÈÀÓè7"ˆ|š£!Ât';ubouncycastle-1.49.orig/test/data/PKITS/certs/ValidBasicSelfIssuedNewWithOldTest3EE.crt0000644000175000017500000000124210350736724030145 0ustar ebourgebourg0‚ž0‚ 0  *†H†÷ 0P1 0 UUS10U Test Certificates1%0#UBasic Self-Issued Old Key CA0 010419145720Z 110419145720Z0m1 0 UUS10U Test Certificates1B0@U9Valid Basic Self-Issued New With Old EE Certificate Test30Ÿ0  *†H†÷ 0‰–~oRý£» äÌM‘ÜXcêRŸÍ3G0¬žéB¤Ïó9f>ö„”yÜß‘6Øqio ^cxYQoÉy|y¥eóå9qìÔ¯æÿ£ª †z’ø×º$(¶ã/ºm°±åZ2ÏÅÇ.'ÑÁ˜Óg·[ÌZŒãê%ê‹` AAçoY£k0i0U#0€ºŒ!‡s˜úë¹ÙoA¤EÕ†ê0U¥@Š¯ã§” áx Ñ/„8¦•ÐÐB0Uÿð0U 00  `†He00  *†H†÷ "…ÀšÞ7„«QzÿèXÅÑV òW{ì'¥ rÀ§i`jòFçÓ’dAÂRÇCD]§ÞFB /ˆnþ¢(އ!Œýzëø®†’©û8€?¶2t,M7ƒ‡:âè9¨¶‡aþ[Øö(y¤YÔHìœ#@ø —È·õbbouncycastle-1.49.orig/test/data/PKITS/certs/onlySomeReasonsCA4Cert.crt0000644000175000017500000000117510350736724025326 0ustar ebourgebourg0‚y0‚â S0  *†H†÷ 0@1 0 UUS10U Test Certificates10U Trust Anchor0 010419145720Z 110419145720Z0G1 0 UUS10U Test Certificates10U onlySomeReasons CA40Ÿ0  *†H†÷ 0‰¥¬1ñ„L>SÓn+K{%wÝ ê÷ž‰¢ C¢Çh»&­Õw4|êªÒ¨ãˆ ŠâJV¼„p€ÌRáìvÂ5ìDT¾Á´ô÷ÉJ'CK±‰WR…@ð,J!G÷|¾ú  eÖ8ˆÆˆ,0xE÷Ýî+¸wÂJC ÌáêÜ&K£|0z0U#0€ûlÔ-žÊ'zž °<êš¼‡ÿIê0U?¾@ñ÷kû°YäZà—Té0Uÿ0U 00  `†He00Uÿ0ÿ0  *†H†÷ 3šÊ“ ª¬ÊIê€ÑØn>޵„¤Ä‘”i1%Œœ %aJáüêt/P°ö·æ6W{G \ èОoÝ> p¸³ÔkyT¦›‚°¾æKl›DÐloââêhPšPSdö%ôhuB”?gŠpûß5©Íþ÷Œr$°C³x*îÙbouncycastle-1.49.orig/test/data/PKITS/certs/inhibitPolicyMapping5CACert.crt0000644000175000017500000000123010350736725026302 0ustar ebourgebourg0‚”0‚ý 90  *†H†÷ 0@1 0 UUS10U Test Certificates10U Trust Anchor0 010419145720Z 110419145720Z0L1 0 UUS10U Test Certificates1!0UinhibitPolicyMapping5 CA0Ÿ0  *†H†÷ 0‰¦¾3”¬Ý¸íш±½…‡µJÏ´TÔs°·(Æ—Ø»vë`un_C–­œäS4Ñc]BˆHºŽÖi¼I9ÄŠöZåxL9ñ¶cÃ\çú<ÆÜ\ä™Î¿ ~ä!±“IÎÍâØ\ŸoÊ?çeÎbÒN‡ìÕ>q׿³›dœ ç¶ißÝ£‘0Ž0U#0€ûlÔ-žÊ'zž °<êš¼‡ÿIê0U@¿p.8ø¶¯§ZÙ²CY˜õL0Uÿ0U 00  `†He00Uÿ0ÿ0U$ÿ0€0  *†H†÷ - æoþfÇã"ÓœÒ% ˆO߯€2¶Í*eås).Bºà¬yUëĉœ#xbÞ…p’övÞf™£Þª9‰¼CEÒ¼ sŽþ.ZdúƒÖ^mžäÉ ¶¨ñRí†z0Uÿð0U 00  `†He00  *†H†÷ 9(N§ÆÄa<äl¢QsìÑö@C1[€*MݤËeYnVȸ”ÎN¿R,ˆCaM ®w eˆ®{ Zýeƒºs°Ç²ð>×$°ê73sfD©2€- ò‰xý_zÞÖI:@³åöŽ‚t«å4èf/m{}wfò{Á4«ä3Y9@þbouncycastle-1.49.orig/test/data/PKITS/certs/ValidDNSnameConstraintsTest32EE.crt0000644000175000017500000000130110350736724026763 0ustar ebourgebourg0‚½0‚& 0  *†H†÷ 0K1 0 UUS10U Test Certificates1 0UnameConstraints DNS2 CA0 010419145720Z 110419145720Z0c1 0 UUS10U Test Certificates1806U/Valid DNS nameConstraints EE Certificate Test320Ÿ0  *†H†÷ 0‰ß¾(ì WþÎsT|j ; [ןÜíº›¡ÏH1Ž´îEµh=Ù÷ȤT¿,m4UÕ£²öùB8=5µ§3–Ò^-­å÷2Uƒñ><á®] [ðßQƒ¸S¢Çµ:ˆà…×]Ýysÿ¥—·è,Bã;ªË͸Úg²9È£˜0•0U#0€~Ü;êޜқBDï{Ín’à´0U¥9*ËÞ‘ûݹ×gÏ÷%™ãÙg0Uÿð0U 00  `†He00*U#0!‚testserver.testcertificates.gov0  *†H†÷ Kcog•8“±À>ŠH.hU~×Ý9§8‚XPu“!̰œ:¨wÙOÁ)šõ«Z2ôRž§çL{Q j5õ.jOD#V5_bÀß_ÄËhÉé²=K›çá²ÎØu Œ³šlô¹—!æ×GÝ7è9õR‡ÀJš@džä…Z•,ìKbouncycastle-1.49.orig/test/data/PKITS/certs/OverlappingPoliciesTest6EE.crt0000644000175000017500000000124510350736724026174 0ustar ebourgebourg0‚¡0‚  0  *†H†÷ 0R1 0 UUS10U Test Certificates1'0%UPolicies P1234 subsubCAP123P120 010419145720Z 110419145720Z0]1 0 UUS10U Test Certificates1200U)Overlapping Policies EE Certificate Test60Ÿ0  *†H†÷ 0‰´ø$”뉓¼ûÙ¾+nfk<Ë‚f3‚ðIóò/̶—°+û³ÌØ5? # ü¼ƒÕÜ„/PšÀ#®LºùiÆ´j–Uã"Hœ<È ^1wX(½Qñi+3ø:ÌØ>t¢¼Åέ9º|Ãi„K q¾J¤Pê‚€ídî5±£|0z0U#0€Ì´ç\ùÕ7ÔPU²1–.䑤Äh0U ‡1µT<×l€Iֹؒ¹þ‰'ë 0Uÿö0U 00  `†He00Uÿ0ÿ0  *†H†÷  ëšpk1ÃÄjè|çO÷oÎÌ=Üà6çI—¢ñR[ÈÜ9Ç­~Òñ-”RÖ !ðމÝàP¼1MÖ¿¦ O…`«¾¥ä…²¼Š,¸µé$ç1{9AžÄI ÔPã“Éê. »LxÂÓG·4¤)¶6 oï!Κ Ís¬Ibouncycastle-1.49.orig/test/data/PKITS/certs/ValidSelfIssuedpathLenConstraintTest15EE.crt0000644000175000017500000000123310350736724030702 0ustar ebourgebourg0‚—0‚ 0  *†H†÷ 0I1 0 UUS10U Test Certificates10UpathLenConstraint0 CA0 010419145720Z 110419145720Z0m1 0 UUS10U Test Certificates1B0@U9Valid Self-Issued pathLenConstraint EE Certificate Test150Ÿ0  *†H†÷ 0‰›ëRÓ»5—œ‰AWÍuÿbö\­ h>0Z:¾}ØNBßP'Øý?-KIBi—r&OLE=ˆ¦˜±_¿fÜ“þŸ+ýAߣÍZE?]#< âÁŠ+ïJXX¿¬ø‘C¹ ׉ü‘“ ø^XuEÖ®Ú™Tß»uØPWu¶Ö­lJš£k0i0U#0€8­%ÈBZ× éJôæ,¥S¤PôL0UK‹£Œa£ãá@7ô‘>[I&ÊÆ 0Uÿð0U 00  `†He00  *†H†÷ aÞ ËrƲÑNÅ+Ir~é:ü+> .‚Gö)à×aÊÈrB—ŸÿÜV^}*ܯD˧¼ž‹Ù¶lKIëJWçgÿlÔ°¾¯}-ö³Îû)¬‚‡mÂRœÇ6owA„ªõ9îŒYiÕìçST'ãAwƒr w17Õ:žtbouncycastle-1.49.orig/test/data/PKITS/certs/InvalidinhibitPolicyMappingTest3EE.crt0000644000175000017500000000124010350736724027637 0ustar ebourgebourg0‚œ0‚ 0  *†H†÷ 0V1 0 UUS10U Test Certificates1+0)U"inhibitPolicyMapping1 P12 subsubCA0 010419145720Z 110419145720Z0e1 0 UUS10U Test Certificates1:08U1Invalid inhibitPolicyMapping EE Certificate Test30Ÿ0  *†H†÷ 0‰¦ûµ½¿ŠLŽìŠÊ,ÜX¡Uw¯o¦âe2Äê5HSB¯»nˆîȉ¤¿O·Œ\ú•DwM[T€ÃÊužÔk—…4Ò)߯ÆcÔM:³§ñB ‘ÇP†§‡UWZ=1ì&fêÅ=.Ûû_ê ñhpMQK©sµr£k0i0U#0€Z“Kï–ž®>C&¤y‹¢æ›!0U»ZßXjÙª*èÇD;ÉdK”•>÷0Uÿð0U 00  `†He00  *†H†÷ 3•~LˆÃºÂIÅå1zþn2e¼øœT1ïö™@Gr~óÔ ýJZ°:cÏCƒÿP ™Øò_J2™eAõ²C+ïš)ûµ6Jm uÄ©‘¢ iŸ+û{wÒ_ɪãiõè§»€#ñ©>iãØSY­‡V -XWÛbouncycastle-1.49.orig/test/data/PKITS/certs/DifferentPoliciesTest7EE.crt0000644000175000017500000000124010350736724025610 0ustar ebourgebourg0‚œ0‚ 0  *†H†÷ 0O1 0 UUS10U Test Certificates1$0"UPolicies P123 subsubCAP12P10 010419145720Z 110419145720Z0[1 0 UUS10U Test Certificates100.U'Different Policies EE Certificate Test70Ÿ0  *†H†÷ 0‰ªìØAIäšV‹ûyg‡Â@*,Æê¥ªÃ·“šs¦d,ÆFlëõ»?ÚG×B ¤Y'æðfRCè 9lÎ|l.=Ô_nª–æÄ›‰ÊKG·¾I+qRûÚ)ãý3Õ¾xˆ•€ê¨ïì"#þÙ@\lAc¶™)Om£|0z0U#0€#‰œø#aBè–›5j¼0½^Š‚0UòCžÓ½ãj÷qü‹6îý D0Uÿö0U 00  `†He00Uÿ0ÿ0  *†H†÷ É(®ý“žyîÓ·›†z û ÚõˆÇv!˜ZÏÐ&ÆÉÒ¬éõ凉®ƒ×%õsà³VE¤5T?a$M“¹{„(+m¬ËÔí­OQ®IC»ž?·&GÜ+Lç—çq”HuüáwEÐ„Ãø`%#6TÑžhÑ*J¢óW;–̦|Úbouncycastle-1.49.orig/test/data/PKITS/certs/ValidRFC822nameConstraintsTest23EE.crt0000644000175000017500000000130510350736724027211 0ustar ebourgebourg0‚Á0‚* 0  *†H†÷ 0N1 0 UUS10U Test Certificates1#0!UnameConstraints RFC822 CA20 010419145720Z 110419145720Z0f1 0 UUS10U Test Certificates1;09U2Valid RFC822 nameConstraints EE Certificate Test230Ÿ0  *†H†÷ 0‰£çÊ®‹BT£—R‡æì§Tï¬9ï¾²^^CLïŸ$k!f(MI;™ v&ççPÍ"Çe8}vyæoYH¡Ÿ™¹Ò ÛÆ¹Nè£×*« êõú1J2k2 oß·i“^“¼Ãh_Òçil6ïë¹±Ê*i›àF¨T––C£–0“0U#0€+6ftK“«1U‡¤1«6co5É0U Fl´H$\$úæ½Þ¤œÝ£=ò0Uÿð0U 00  `†He00(U!0Test23EE@testcertificates.gov0  *†H†÷ x5šBý ¢C—›xà´4r‹$ãü=ñiƒ EÅíq„QL™Ç$”CÐ p¿|g…oÊ‚¬p’òb«€õå&ôELkZð勤%[¾7É{6k…â¦2=Ÿ "ëp'ªNcx#%BDÜuñ-nÒøC÷{߬ 3W.Y >ðbouncycastle-1.49.orig/test/data/PKITS/certs/InvalidRFC822nameConstraintsTest24EE.crt0000644000175000017500000000132210350736725027541 0ustar ebourgebourg0‚Î0‚7 0  *†H†÷ 0N1 0 UUS10U Test Certificates1#0!UnameConstraints RFC822 CA20 010419145720Z 110419145720Z0h1 0 UUS10U Test Certificates1=0;U4Invalid RFC822 nameConstraints EE Certificate Test240Ÿ0  *†H†÷ 0‰ª=n›½0là·ïšhfÒf`=ã/Êm Ï<Ù HÛ×xfã¾µ§å {˜ŠÀ…£~<†½¯zQ”lWä}gŒÅ/ý¿ºA”2ŸmMUˆÏd”âýM ÕHßi²q¡r› ÛEœn±‰µKï(X^‹×¥´i݉‰­£¡0ž0U#0€+6ftK“«1U‡¤1«6co5É0Uò¼¼ª1šP(3‰–mô9xꉖx0Uÿð0U 00  `†He003U,0*(Test24EE@mailserver.testcertificates.gov0  *†H†÷ ®±i#â¢ËÖCÄ=ZÕx±?ŸâqK¿~ObÆÙõ=Íh´Ý ý>Eª(îãñÙ›Z©{«<¬¼o¼æÌï,ü’›¥ñ)‡˜¥õ׿ôfz.o¿!¦åÎÑYø·úet ¼®å[e×ßÊ-Ö9›Èbouncycastle-1.49.orig/test/data/PKITS/certs/ValidonlySomeReasonsTest18EE.crt0000644000175000017500000000136710350736724026426 0ustar ebourgebourg0‚ó0‚\ 0  *†H†÷ 0G1 0 UUS10U Test Certificates10U onlySomeReasons CA30 010419145720Z 110419145720Z0_1 0 UUS10U Test Certificates1402U+Valid onlySomeReasons EE Certificate Test180Ÿ0  *†H†÷ 0‰çÌþÐUÜ·C(Òã> ™Óý~i®TMj‘ŸP(®w¼¯Êý(<’ýÛáEEÍÄâp›AfÅä–¢éF·òéK”œ*S° a…ºR{Ê€1ë §›’yÜ2µ]6!0\¥Ì¥á¸²¸„Q3~h8ŽÔ:k2Um>ƒñ¸º l³`Së\Ñ£Ö0Ó0U#0€I{ëOiû~£ßÛ#‘÷ZVjù¶00Uíù«dÆðìöÝ$±ËdâbŸ’ùÑ0Uÿð0U 00  `†He00hUa0_0] [ Y¤W0U1 0 UUS10U Test Certificates10U onlySomeReasons CA31 0 UCRL0  *†H†÷ @Ùк±whJ[É—–¬©X[lå6Ãe)†©¥Á·‘¦«½Wb2ÂË `(¾%c)1 ˆÜ|ü×…îíh kk#€ö¥y)sÙŽ÷˜a½Ôˆè`Ú¶þpÜö2+"‡“õSN>éh1­J–~-è„8>zb KjM‹™ä¦ bouncycastle-1.49.orig/test/data/PKITS/certs/InvalidSeparateCertificateandCRLKeysTest20EE.crt0000644000175000017500000000126110350736724031366 0ustar ebourgebourg0‚­0‚ 0  *†H†÷ 0Y1 0 UUS10U Test Certificates1.0,U%Separate Certificate and CRL Keys CA10 010419145720Z 110419145720Z0s1 0 UUS10U Test Certificates1H0FU?Invalid Separate Certificate and CRL Keys EE Certificate Test200Ÿ0  *†H†÷ 0‰×Ú›5¬¡ûwô•\N"§ØäÊ™¡¬À”¦-edfƒ»Æ*½‰R­± ãW½Ã„ÇA……œJyöÏÌj|›Z—çW^ÆÕ$¿t,^’øÁT\àCA¦…³¾ èÄÛÆ@>—ÿé¤ ø}Φ¶ÜGÞ ã¹±„Ê;ƒ!¨·3¯·£k0i0U#0€›\Q¼"'1"@” %ÿσy­£0U7©í·th;|{Æ)$¶!½]Š0Uÿð0U 00  `†He00  *†H†÷ Ä®ü•¦aÕÞ­ßÅBwìÆÞOM4¢¬-‡0óT2×§òغ-"‘ÅÁ¨´ïæG<™U+º“&¿[üÔ=´¤.@‚®^U@ÔŒ)îVHÎÁ ó¨· ¼r­‡”‚lTJ]¿;k[¢ræÚîèŽIÜJTä¤Ôݰˆzrbouncycastle-1.49.orig/test/data/PKITS/certs/nameConstraintsDN2CACert.crt0000644000175000017500000000145610350736725025561 0ustar ebourgebourg0‚*0‚“ ?0  *†H†÷ 0@1 0 UUS10U Test Certificates10U Trust Anchor0 010419145720Z 110419145720Z0J1 0 UUS10U Test Certificates10UnameConstraints DN2 CA0Ÿ0  *†H†÷ 0‰´^B¹µËî2â ¸»°oD-Y÷¾Ý¡q>Óv<…n+%7žS Údœ“lzW)_–;]R<Ø™eä\6Â&MÀ˜’ö48ÛIñ+ÞÞÉþ}+~ŠÑ’Ê“¬È¨¥G¡&ÐŒôè¦<j(ü0å<˰\X»ür#×Ëbouncycastle-1.49.orig/test/data/PKITS/certs/InvalidMappingFromanyPolicyTest7EE.crt0000644000175000017500000000123110350736725027631 0ustar ebourgebourg0‚•0‚þ 0  *†H†÷ 0M1 0 UUS10U Test Certificates1"0 UMapping From anyPolicy CA0 010419145720Z 110419145720Z0g1 0 UUS10U Test Certificates1<0:U3Invalid Mapping From anyPolicy EE Certificate Test70Ÿ0  *†H†÷ 0‰µø6M¢ï/Öâ9%´ûª·WgOwëüø‡¶¯fÊËhš±yb”é]_˜ÜË Ú§ I¨x­žªÌý÷Ã+†]àHI'”Iv †0i|£F½É”"Ta¨ (•ÇÜÉ #} Y_¨rn“<ÏÁ[»ó§0†¨¬÷Yl¶%£k0i0U#0€÷Á«5Ø/†Z67YoÁÁ¤m¤¤H0UÛ¢}²ä(ï–´öMœ£9ò_×Á@ú0Uÿð0U 00  `†He00  *†H†÷ ]Ÿ¢ü7xw]q¦â‹OÝ8€ÿm§YrÈà²v…1¸&ëz“È^ÝËäPZª5IûÂЮ¿yì|H1žK•¹Ÿ”Ëa³ºü €¨£pò£ì¿¬â©{|êØ(:Îbuͪ»PýõÙüã$ëe;ZÚBá ësdsÇJbouncycastle-1.49.orig/test/data/PKITS/certs/InvaliddeltaCRLTest6EE.crt0000644000175000017500000000145410350736724025161 0ustar ebourgebourg0‚(0‚‘ 0  *†H†÷ 0@1 0 UUS10U Test Certificates10U deltaCRL CA10 010419145720Z 110419145720Z0Y1 0 UUS10U Test Certificates1.0,U%Invalid deltaCRL EE Certificate Test60Ÿ0  *†H†÷ 0‰±ÊÍ?u†Ñd!âEò;=ÿT­òr@õÒI¼šºÒJ;µ[Ê^Ÿxèr* ±œ1“|iéå"+¼µÜ'ؘæ{D*Ü÷•WV`ÃYs!x¢!Ïaì!q™ÀͧÒlž‡ÕKYQ$ÍßZk”ý‰lÛŠú=hQ ©ê9£‚0‚0U#0€“M¼ò× ® H¬º2 ×è Í0Ur%ÉÎ6ÒQ·!XJ_üB¢¦0Uÿð0U 00  `†He00SUL0J0H F D¤B0@1 0 UUS10U Test Certificates10U deltaCRL CA10SU.L0J0H F D¤B0@1 0 UUS10U Test Certificates10U deltaCRL CA10  *†H†÷ Pf`¡5¸vyS¯‹¼ù+lÂ$ƒcGB)¥£”r‡™s9-³¨kMtC;fbŠ5* ªø^ádN §6SÙ*Ó"ße|lDyjÛ¬Ó<ôñ6¥„½åÚR÷¾y{çðŒå<Ú£L¤–LTˆAdV<-†ðýuåY⥛q™bouncycastle-1.49.orig/test/data/PKITS/certs/RFC3280OptionalAttributeTypesCACert.crt0000644000175000017500000000132110350736725027442 0ustar ebourgebourg0‚Í0‚6 a0  *†H†÷ 0@1 0 UUS10U Test Certificates10U Trust Anchor0 010419145720Z 110419145720Z0š1 0 UUS10U Test Certificates10U Gaithersburg1 0 U*John1 0U+Q10UA Fictitious1 0 UCA1 0 U,III1 0 U M.D.0Ÿ0  *†H†÷ 0‰Ö¶lE‹æ€¼2 S‡k J ÒÀI¼%63duðÂzÒŸÄ·n% ˜Oœ~!ªšÐ”‡`!cŠ–s‰:Ó\LØÀ€÷¿<ƒ‰xŽcÑÈïÜ ¾=ì¢Öå² ·6ÛG°øSتm¨ñ¿‡±€€¨¡¨‹3Ë-Ó}»ð*.‹£|0z0U#0€ûlÔ-žÊ'zž °<êš¼‡ÿIê0U¯ŸÌ,¤cBWW×Wc_sÑ0Uÿ0U 00  `†He00Uÿ0ÿ0  *†H†÷ SéÆZ<úÚ<“±¨²‘çBw‡íµ1‚ÿ¹ó#›:þ¸…æ|RF 3è|…¯³7g_×jN¾ž‘@c­»‡?*Ây˜®6v}Ûãã»#øăº¡Lü6Àçš­èå²Á;CÏz‚Ü÷,ø™Úm¢Óô#¿'NÐÆ@Übouncycastle-1.49.orig/test/data/PKITS/certs/inhibitPolicyMapping1P1CACert.crt0000644000175000017500000000123310350736724026501 0ustar ebourgebourg0‚—0‚ :0  *†H†÷ 0@1 0 UUS10U Test Certificates10U Trust Anchor0 010419145720Z 110419145720Z0O1 0 UUS10U Test Certificates1$0"UinhibitPolicyMapping1 P1 CA0Ÿ0  *†H†÷ 0‰ÀëÃwSð%ðU͆µ”EݦÙ"K<»ôÓÉeËSÒéZzàÈlåâ>ñQ沜XZÏæ¥9½¡³Çƒ|r¢²;\*?ò½ð+ÝÛ×Ôf¸?Ù(…å“3âÑ$›M<£Fð¤”Qâ‚Û껞·V˜ ³¤³ÁWPJe£‘0Ž0U#0€ûlÔ-žÊ'zž °<êš¼‡ÿIê0UªidµRå¢c  ój? ²Ô´0Uÿ0U 00  `†He00Uÿ0ÿ0U$ÿ0€0  *†H†÷ 7ûc* J¢Ù¤F `3:m~V¹•ðsÐbòîUŠ ,çºþ°"c;eû¥a ¢Éã~b”: ËqRá ú$@¤×Mt0\œ 6ýªK™_ÔÃà}¥ž^mE'äY‡‰Ešme_'V<ŽÜxŸ‡ôbjï—& Š,O&Êx0bouncycastle-1.49.orig/test/data/PKITS/certs/ValidrequireExplicitPolicyTest1EE.crt0000644000175000017500000000120710350736724027525 0ustar ebourgebourg0‚ƒ0‚ì 0  *†H†÷ 0W1 0 UUS10U Test Certificates1,0*U#requireExplicitPolicy10 subsubsubCA0 010419145720Z 110419145720Z0d1 0 UUS10U Test Certificates1907U0Valid requireExplicitPolicy EE Certificate Test10Ÿ0  *†H†÷ 0‰Ëq}< Я²kR†m8Ø€¢¡d„?,dÚì;)w¶y´è ¦ÓQ]ÆqY3(·4`—YÝ”:U$$ÏÕfÏë¸4Ú}q1dNÀ6Ì‘Õ]¨o˜-â w徨Íâ÷Êö œêq´]ðYãòeǤ…¾ ë º\Ûk2]ö«#£R0P0U#0€”×wÅq*ÔÓoôQ ¶Ú¬2ã¯0UT‹K¶õû>9T–Üѽ ¦hè0Uÿð0  *†H†÷ †d{îÜÒsp~¨É²~¥&[—ŒÄØÇÊhnD<75tæO´P¿üлê±ÃþG NëVëÆHùuª" “¦L]hÓÜÃ0ÌÞÙWRú‚ØÖ­›õÞÃ_‡Ëˆ_Ít iT¹A©*œÐí&-˜y~Ï=hûÖ5”Šã ìçž+(R4bouncycastle-1.49.orig/test/data/PKITS/certs/ValidDNSnameConstraintsTest30EE.crt0000644000175000017500000000130110350736724026761 0ustar ebourgebourg0‚½0‚& 0  *†H†÷ 0K1 0 UUS10U Test Certificates1 0UnameConstraints DNS1 CA0 010419145720Z 110419145720Z0c1 0 UUS10U Test Certificates1806U/Valid DNS nameConstraints EE Certificate Test300Ÿ0  *†H†÷ 0‰ÓÀ¶Ù›L¨9‰B;z…a=¬òW­`|O^¹”H‰9^ š²Uiy=üWSÓÆI)å¥y¼Ã\վؗݲ#1Õ¸Ôˆ¯¨5ð{Z¬ñzø0±s¼g|9_$ 55€!,u/VTFB¨U|3g0†Z¦ˆ— ’ûúäšsdø§l+£˜0•0U#0€uçgG «ñˆˆÛžÕRŽüsx0Ubi^4uK݇a¢ü„M  à0Uÿð0U 00  `†He00*U#0!‚testserver.testcertificates.gov0  *†H†÷ ¯T gafC²jÁ‹‚íîÑ©ç/ æèËÛR»ø¡î]ùµ·/X¹”^ÞÝR WÊ“*?bM³>åv—@)ûRèö¬¦Ø™.Z¡‹vzrçVÙ…·`7ž¢&†`9oa4•¸o1UóA¼äǽïË[Œ•1 ³ HZ˜7AMðŠbouncycastle-1.49.orig/test/data/PKITS/certs/inhibitPolicyMapping1P12subCACert.crt0000644000175000017500000000135310350736724027300 0ustar ebourgebourg0‚ç0‚P 0  *†H†÷ 0P1 0 UUS10U Test Certificates1%0#UinhibitPolicyMapping1 P12 CA0 010419145720Z 110419145720Z0S1 0 UUS10U Test Certificates1(0&UinhibitPolicyMapping1 P12 subCA0Ÿ0  *†H†÷ 0‰Åú.Ìä%Ä«Èeq|Ž€ïß1s´ ú1‡(G<¸ù¥YOJ36-j”:K? Z·âWÚ ¢y;åwü9ìhˤ™ŒçîOÚ¨g„íqÑZ{;Ó³?­ÁÄóÿ³4‹*JKò÷a­Âæ†ï ᯊÈ Ú¢šú ­‚¾.`µ£Í0Ê0U#0€v0ƒ_£…K{7 &f0UzŠ0öê\6@ ®ØŸ¿¹½‚ÌR0Uÿ0%U 00  `†He00  `†He00@U!ÿ6040 `†He0 `†He00 `†He0 `†He00Uÿ0ÿ0  *†H†÷ MÙ~RQé¿ÏÂ*{líY"H²›ï.O9Sæ|w^匡î)Z¨çe¶hh¾qÕ—]ï}Ö3Гôû â.6I–z—úT±ƒŒ‰%:˜kC'ZÏÀËŠ%A•Þâ?’a¨N \I1ÀûMxÈ6uëáØŽVµ}á¥|bouncycastle-1.49.orig/test/data/PKITS/certs/InvaliddeltaCRLTest3EE.crt0000644000175000017500000000145410350736724025156 0ustar ebourgebourg0‚(0‚‘ 0  *†H†÷ 0@1 0 UUS10U Test Certificates10U deltaCRL CA10 010419145720Z 110419145720Z0Y1 0 UUS10U Test Certificates1.0,U%Invalid deltaCRL EE Certificate Test30Ÿ0  *†H†÷ 0‰Ï}í/ H ÷è6€?.\mêãå9f~ŠûúÓ‡ä4˜Êñü¡!}«: ¾ Côca[MÜ¿}VåVh †eë\Þ§TlV—W€UÔ›6ÆÌ£˜fѦ /i\®Ùj¨f–Ô‰šCýÙÎ=^8‰ü£r863>‘M{”rgó£‚0‚0U#0€“M¼ò× ® H¬º2 ×è Í0U±,¼^/ªÛ¢–“í5M1L(Jö-0Uÿð0U 00  `†He00SUL0J0H F D¤B0@1 0 UUS10U Test Certificates10U deltaCRL CA10SU.L0J0H F D¤B0@1 0 UUS10U Test Certificates10U deltaCRL CA10  *†H†÷ ädT˜<«±æOÝ')ðc3ùFòÎC9cõ%°ü¹ziª7 =_c̯«µ ÔeQ]~<°° 9+@‰ÒVm:ƒ²èp놾ÍFl´X¬À£Z‚Ï$°!†½Ia5û³[Í_„nè¹á —ªõœV8u[ø½Hbouncycastle-1.49.orig/test/data/PKITS/certs/indirectCRLCA2Cert.crt0000644000175000017500000000117110350736725024323 0ustar ebourgebourg0‚u0‚Þ U0  *†H†÷ 0@1 0 UUS10U Test Certificates10U Trust Anchor0 010419145720Z 110419145720Z0C1 0 UUS10U Test Certificates10UindirectCRL CA20Ÿ0  *†H†÷ 0‰Û”;GZ„|G»Äü4¸´›Ê‡« ƒO#'<ÂC­YľËçý;’t2Nfmˆæœu<8Ñ%Øy£vVV~ MÀ€¡ c Öý,2t ý>äIû³ÿJꄱý¶<÷BØíûüòã–Ÿ/4ì“,}Þ-}Ù£¦°•žžDÅ£|0z0U#0€ûlÔ-žÊ'zž °<êš¼‡ÿIê0UÁ¯‚ÕÓOð1bëD5è$PôìCíÑ ™1xþuH5öK ûtM˜é¤ÛççŤa+^Þ-µ(,yq2$GêЇ^=ïAÀqÂß²ï#Û[¾óªªÉ×›Yb ÜÃm Áó¿jò Õç܂ܯ£ó0ð0U#0€:4‹ãvXXć˜}~Œ¬]¹N0U‘\;L_É%*ˆ¨ÔÀX»dí50Uÿð0U 00  `†He00„U}0{0y w u¤s0q1 0 UUS10U Test Certificates10U distributionPoint2 CA1&0$UCRL1 of distributionPoint2 CA0  *†H†÷ 8û¿| ],ÿ­H]‰6çä~Ù+Ძn9;áþáAɾfËÆØ‚PÂ@¢uw‘ÿ 5¾¢5c†5h°nJ¤KêǽEŧ^_qÓ®<ö´"«Ÿ«ÿ†¾š_‚UqÕŽŞ̌yå׸+þgX’Þ}´²]í¥RÀ¢¹bouncycastle-1.49.orig/test/data/PKITS/certs/InvalidinhibitPolicyMappingTest5EE.crt0000644000175000017500000000123710350736724027647 0ustar ebourgebourg0‚›0‚ 0  *†H†÷ 0U1 0 UUS10U Test Certificates1*0(U!inhibitPolicyMapping5 subsubsubCA0 010419145720Z 110419145720Z0e1 0 UUS10U Test Certificates1:08U1Invalid inhibitPolicyMapping EE Certificate Test50Ÿ0  *†H†÷ 0‰©M‡c‚y‹„òj !$óè8O±Š“LR¢½â*³ãDéUŒÓj89ß§ÄKãiagn(‘Ðð: —Kþ;GåfwÉžËð`í´¨ËÀzQUÛ¿‚%W‡ üÓI{H¬†Í:=ÔWŒ´ùHMpk›y(ÖcÃÑ/ö¦˜S£k0i0U#0€$¶q­WÀ÷„š¯V·âHlóý®10UJ˜9,_«YèäŒÚ¼)ÚàÁÐî©0Uÿð0U 00  `†He00  *†H†÷ HÉ 5»ý7\ŸbÞBÚ=Ë›.k…ºÓޱŒÐ‰± Oº}ܪ²Bµ~v¤dMyýÒi¸v[ˆÎc¡±??ŽOtü9¸›Pw¶ Þ|r¾°;=©0f/§´%ˆ„gÉ­˜“ø–ÎÅ0U2×]èov;ô„Ò€:¼Ûgµ”e­0Uÿð0  *†H†÷ fnÿ߃ Ý è^™sŸMÞÂß1Äo 9ø;OK!Â.¤œaŽâª5*úˆ L”¿u!9i¢"†RXžÇæáÊ¢òDŸ›þ—OrÏqÄ'ÝdóÉâù7(+J{Cû…€ÏBNÀfyîzñöfŠâ*9õ¯ÕLó:äbouncycastle-1.49.orig/test/data/PKITS/certs/ValidSelfIssuedinhibitPolicyMappingTest7EE.crt0000644000175000017500000000124610350736724031311 0ustar ebourgebourg0‚¢0‚  0  *†H†÷ 0R1 0 UUS10U Test Certificates1'0%UinhibitPolicyMapping1 P1 subCA0 010419145720Z 110419145720Z0o1 0 UUS10U Test Certificates1D0BU;Valid Self-Issued inhibitPolicyMapping EE Certificate Test70Ÿ0  *†H†÷ 0‰°ßÓ—}Iì†V/2Jöe¯R›ÒðiB§¿å>âHèÖ›Ûž€E„è²Å*èí¹‰dÑÂôõ½§EôÎWÆÈº>€ZOohši­€š‘3Ñœf.Áž5M”/Ñúõ kB5_9Zý•üUdÎt–§Q?ÿ=H'È/ô]þ²Ñ£k0i0U#0€¶¦ÁêÀRS߆ýfIä´F¾c3 0UEzÅ™{us"î¼xûX)Ø$a0Uÿð0U 00  `†He00  *†H†÷ MZ ´@±UÉ‘ÃËèßÈtg¾Mœþd†ÆVìi>¤'·ÊBI}•@0•¿VÔšÛ¾?ŠHbjŒó¯i´rI¶Íà]¹Õúã­…¿Ší ¯µzò¨¸„rd pdª«¼:´5“ÐÕêßÔ/Ή|Þóø8oÇN«“¸Ù䆷š’bouncycastle-1.49.orig/test/data/PKITS/certs/InvalidrequireExplicitPolicyTest3EE.crt0000644000175000017500000000121010350736724030050 0ustar ebourgebourg0‚„0‚í 0  *†H†÷ 0V1 0 UUS10U Test Certificates1+0)U"requireExplicitPolicy4 subsubsubCA0 010419145720Z 110419145720Z0f1 0 UUS10U Test Certificates1;09U2Invalid requireExplicitPolicy EE Certificate Test30Ÿ0  *†H†÷ 0‰ÅlÆç@ÄiU’8¤!Œ ›#¨u5ô(TÙmôFÞÎ 0-¹ÔR@ˆ? ‡0ƒl2y¢MxæˆÁ=ßáL?GâÚyd)eð¸÷B×ýÛ·fuüç<Ši‡¤NG<µ.³\I@ïÇËba^üÄáŽ^æÀð ,st&¢a7£R0P0U#0€÷„+ݱû•ºzZbàs1²*Èy0UO‡"ûÃ!KËUáïݼì0Uÿð0  *†H†÷ ™$H@´DÉýÙüŸ­P`ÃÜ‘kÓ|mªÛJ#»—§eöÖ ­ðy<°Ý½¦Ÿq,—ζÅ!²£hqŒßê>pøÀôÒmEµ c¼›t¶¸þ8f-+LÌm†" ìÂù:>¡+µå_:CO4|%¥¡i¯,¼d“6bouncycastle-1.49.orig/test/data/PKITS/certs/nameConstraintsDN4CACert.crt0000644000175000017500000000145410350736724025560 0ustar ebourgebourg0‚(0‚‘ A0  *†H†÷ 0@1 0 UUS10U Test Certificates10U Trust Anchor0 010419145720Z 110419145720Z0J1 0 UUS10U Test Certificates10UnameConstraints DN4 CA0Ÿ0  *†H†÷ 0‰Ë÷úÊé>õ?"ÂB4-êA޼DØ 3„ p °6d‚µæ›"²_w¾[™`-ë³Îñ3Ñ\>mM ø ^3 #ÕrŠ/qpÔ÷)t®…›^ô¢‹ß ŠÂÜ5¬æâs p§*ÓžûcÀ:¸¯J/ÑÈ_gX¼çqEr‰"Ç£‚&0‚"0U#0€ûlÔ-žÊ'zž °<êš¼‡ÿIê0U3)茀L¦­'ƒ%gÅå¶vÌ0Uÿ0U 00  `†He00Uÿ0ÿ0¥Uÿš0—¡”0H¤F0D1 0 UUS10U Test Certificates10U excludedSubtree10H¤F0D1 0 UUS10U Test Certificates10U excludedSubtree20  *†H†÷ ƒÃw4¾Þ°í ÎîÈÙ¡¨m¢}P‹§.ÁÛæÈÈ(a©Šð>ÄüñˆB8·ÌBïè8?Ä,FH²½'¶Žkø%tÙ× ?qv\ЯÈ0¨ÿñèÔ Eœì÷BY"3‰™Þcwr‰<)šÔHVËzÛoüžÞXbØ‹bouncycastle-1.49.orig/test/data/PKITS/certs/ValidUnknownNotCriticalCertificateExtensionTest1EE.crt0000644000175000017500000000125110350736724033021 0ustar ebourgebourg0‚¥0‚ ^0  *†H†÷ 0@1 0 UUS10U Test Certificates10U Trust Anchor0 010419145720Z 110419145720Z0r1 0 UUS10U Test Certificates1G0EU>Valid Unknown Not Critical Certificate Extension EE Cert Test10Ÿ0  *†H†÷ 0‰¨nôȚ̮ eöqŸ¤ µÎöK,Ë#ÈS«špAÊ.š;jäƒïhïº (ÒÎÓ¿”™fºü7¥[×LFP:r5¬£xHCÖ " ð—qI¶¸×²°†Dµ`ð\8Âd¥×ŽÑɯ7õ˜OxSàîm1³‘?óÞŽÇ,Õ£}0{0U#0€ûlÔ-žÊ'zž °<êš¼‡ÿIê0UöQT^Â5¦¤œéoY—läÞitúª0Uÿð0U 00  `†He00 `†He 0  *†H†÷ 7j#Òm¨_Ù]Z@ÛÞ9ž m÷ŸEc’©¿‘˜¹‘ß6î­mC]|îÝt„8w¾NtËàôÂ*Ë5¨D§piâ[Lk•ÄäAgXe+Žæ@âË!¸“bgUüÇ|€ìdRጙäÛçÊ®dÉ ÀúP]§³+„'î bouncycastle-1.49.orig/test/data/PKITS/certs/InvalidDNnameConstraintsTest8EE.crt0000644000175000017500000000125510350736724027122 0ustar ebourgebourg0‚©0‚ 0  *†H†÷ 0J1 0 UUS10U Test Certificates10UnameConstraints DN4 CA0 010419145720Z 110419145720Z0~1 0 UUS10U Test Certificates10U excludedSubtree11806U/Invalid DN nameConstraints EE Certificate Test80Ÿ0  *†H†÷ 0‰Ñ-dÍ,z.ˆ=°7xIÒ7g®>N9sÛï}—ð~ëÎ ÜPš@ <žƒ}bŠ3D&‡Û-l’ß³¨:Í–?.ë5É#OqÜCQ0uCárü̆/uÎyápޝªùƒCÓ×ómŽs!¯1¾ë‘¡ÒÜϱãÅp€Nh²ý‰[«û@½£k0i0U#0€3)茀L¦­'ƒ%gÅå¶vÌ0UÚ-ËXŽLÔ³hg(h€ÒÊ0Uÿð0U 00  `†He00  *†H†÷ …Õ±µþï°@QtFÑ”<Èô1Íxm¹z]TSÙ: ¨E‰4NN¶ Aé3£~ᦩu$ÓÒ£leh¦ÂLè–È}èËw2¸¿³R‡6tl=d{gÙèL6VÙÚ1#Hu™Û¥Çÿ?„÷Ú–WÙÔ XE•êJRmøbouncycastle-1.49.orig/test/data/PKITS/certs/InvalidMissingCRLTest1EE.crt0000644000175000017500000000117610350736725025476 0ustar ebourgebourg0‚z0‚ã 0  *†H†÷ 0=1 0 UUS10U Test Certificates10U No CRL CA0 010419145720Z 110419145720Z0\1 0 UUS10U Test Certificates110/U(Invalid Missing CRL EE Certificate Test10Ÿ0  *†H†÷ 0‰ÏÃ¥ƒZK„—d@°íN~x¨ºå Õ«7;Wköqˆ_UNqœ¼Aô›¶ý^ÁÎÜÄV#}v鍸xäÄzéóL¥<íÊxžF~è‘úŒ•Á¥d¿Z<Š&oœ+àâ7‡…)-ÀÊiLbˆ©‰Ù- ã"`(Ùßc£k0i0U#0€¨óœNh–E̘}Èx?õ$0U– £/Z^Þ$$86> -½6Ð×0Uÿð0U 00  `†He00  *†H†÷ ”ÒK ,«E“Tͯ^/b\éáRn:âF¼ü¯#Cú¹ôv{x…k]P)¦U§W#~oŒæe4âÌâÉñ›4Iø\“G¬ù»ÙÊõ0ÊÆ£óbœ!ÙŽoâkqA:„“ˆh\_‘š#Ölüó˜‚!c ë™@ÐåX†‡^€!A4bouncycastle-1.49.orig/test/data/PKITS/certs/nameConstraintsRFC822CA2Cert.crt0000644000175000017500000000125610350736724026123 0ustar ebourgebourg0‚ª0‚ D0  *†H†÷ 0@1 0 UUS10U Test Certificates10U Trust Anchor0 010419145720Z 110419145720Z0N1 0 UUS10U Test Certificates1#0!UnameConstraints RFC822 CA20Ÿ0  *†H†÷ 0‰ÃÙKϹûý€€mòÛÈ÷Š‚峫5xhѽßJ;ÊãÞ[Pò㢯 :Q€ⱌ©ÅšCø÷W«¤Ì[ÆÖ6æ ,:s©âæì«{–è¾›h$+&Ȫ)â¦ÎC**Ñ€åµÛ>•$N•5þê8Îw \Ž_`”‰£¥0¢0U#0€ûlÔ-žÊ'zž °<êš¼‡ÿIê0U+6ftK“«1U‡¤1«6co5É0Uÿ0U 00  `†He00Uÿ0ÿ0&Uÿ0 0testcertificates.gov0  *†H†÷ °æ1—NqPÑC¼3*}Ï×j‡5nh(Õ:©“äËoÃáŸzÌN§èÂw¸íLJ„y}oh%T¥D[X@-~á7æÉPB¿ÜõØ0 ÉÀ]QSÛ?ûÞpÄ7Þ«P­ÆbÍŽ;ÉTÊ)¾"LG3öÙÈ,¸þ†ØkâÚbouncycastle-1.49.orig/test/data/PKITS/certs/ValidGeneralizedTimenotBeforeDateTest4EE.crt0000644000175000017500000000121710350736724030705 0ustar ebourgebourg0‚‹0‚ô 0  *†H†÷ 0;1 0 UUS10U Test Certificates10UGood CA0 20020101120100Z 110419145720Z0m1 0 UUS10U Test Certificates1B0@U9Valid GeneralizedTime notBefore Date EE Certificate Test40Ÿ0  *†H†÷ 0‰½åáñEzØ?bÁ›`ÎØ¡kÕµZ¶FD‚I®’a%BW>7?Q6’[ƒ¶þÜËú\£+Ò©ÜHiªt°=ÌcÀ9å¢ p„µ>W\º§†¦§Ýz8ç¼Þ W]öàZÅýnŽÉ—Ë >Y­ƒ l­vñ:*ªt1]F¥öu£k0i0U#0€·.¦‚ËÂȼ¨{'D×53ßš”Ç0Ux””Rñ¡É8 yŒß+ôª•l½§0Uÿð0U 00  `†He00  *†H†÷ "Mœ;H ñ·ôÞZ#àÏ^nL#ÜMYs1Ìg„’q¾ý¹âxà²FV;¶  ÓÇ¢@×U'ˆÞa1¹ãOš@Ö°®‹øxH0Ò.Ì|5÷IÊ\Ã’¨ù“‹Û`ü$ßgmF¹õ„…º50NE¹u¡q'nG%UŒBì¨bouncycastle-1.49.orig/test/data/PKITS/certs/requireExplicitPolicy10CACert.crt0000644000175000017500000000122710350736724026577 0ustar ebourgebourg0‚“0‚ü *0  *†H†÷ 0@1 0 UUS10U Test Certificates10U Trust Anchor0 010419145720Z 110419145720Z0N1 0 UUS10U Test Certificates1#0!UrequireExplicitPolicy10 CA0Ÿ0  *†H†÷ 0‰Ì…ý?ì÷‡SrÜQÉ 8c¬þŶLÿÜã*òûqûÈðþ£‘Ð酪¬×Ó\²Êtvoç)è÷ÛlwÔ œl§¹OÂÓ£Æüd/5HBëÔsˆ¼\#$Nçlß:qÊúwU–os1–I­s°!(yŽFŒÿ)ÝØú"ì¿u£¿•£Ž0‹0U#0€ûlÔ-žÊ'zž °<êš¼‡ÿIê0Uóé&™–†ÄÕ¢{ì¹°¥n6 E0Uÿ0U 00  `†He00Uÿ0ÿ0U$ÿ0€ 0  *†H†÷ -¿ö’óýæš~G@;Q;ÔçDüσ8ã9ÏÁ‘㔸v(b·úïŸLÜ ƒœh”à•…&ì#›–Bè –O-p©®}Z‡B²²­Ï}vŠqÕ5ünµbx)Õ:õ~%ãHƒ$ø@IëŠÓ,«é³­1fAê’bouncycastle-1.49.orig/test/data/PKITS/certs/InvalidDNnameConstraintsTest10EE.crt0000644000175000017500000000131310350736725027167 0ustar ebourgebourg0‚Ç0‚0 0  *†H†÷ 0J1 0 UUS10U Test Certificates10UnameConstraints DN5 CA0 010419145720Z 110419145720Z0›1 0 UUS10U Test Certificates10U permittedSubtree110U excludedSubtree11907U0Invalid DN nameConstraints EE Certificate Test100Ÿ0  *†H†÷ 0‰¸ÂÒÆ@šIÜK‚IX9r$ØJàÚHüC(n¿+gJà0FÐ2eþÛ 6«µòo–»8[Î#´B™Èì:Í{=\8 ÞùO*y[Ûg¢hlÚ~ŸËö/ÐÀ\pî­?;"W,Ú±÷¢;Ñ÷¥‚¿Þö.˜“ós…ñÍ ª‹Õ£k0i0U#0€5Ÿ¬Á¹¡ã:þñ/ºw²NMYí0UÁ ˆ˜öÖ¦µ_kehbxߢu0Uÿð0U 00  `†He00  *†H†÷ ,3î+³1zñ¤3)›Yú"î§œnŸU“Ò0½²ø©¼É¸°Õ£Ûo·ÅÅOœŸÎ‹Ž‡ÂMêüØB&áš#±ÙºT”%qÿ¾=¼X¼¨í'24˜"ü幄:=øÏý|,”á˜g}ÄÂhuŨœó—;ò!`EgµQøæ?Ì@bouncycastle-1.49.orig/test/data/PKITS/certs/ValiddeltaCRLTest7EE.crt0000644000175000017500000000145210350736724024631 0ustar ebourgebourg0‚&0‚ 0  *†H†÷ 0@1 0 UUS10U Test Certificates10U deltaCRL CA10 010419145720Z 110419145720Z0W1 0 UUS10U Test Certificates1,0*U#Valid deltaCRL EE Certificate Test70Ÿ0  *†H†÷ 0‰µ<¢‰¹èf%î,ñ`2…—™˜Ìq°Þˆ’t·¢2wœß[¢Ö”KH³KXŒ3¸$̤Ï0«S…%¨?õ^O¹Z!Ã]Q‘kx¸PÜë1-•€óÎð0︟+ Žlé¼GP–ƒeBcÜsj„Gv ¤p®KÎ;q?£Ù£‚0‚0U#0€“M¼ò× ® H¬º2 ×è Í0Uº{x¸õQÒÓàÇë§^tç0Uÿð0U 00  `†He00SUL0J0H F D¤B0@1 0 UUS10U Test Certificates10U deltaCRL CA10SU.L0J0H F D¤B0@1 0 UUS10U Test Certificates10U deltaCRL CA10  *†H†÷ \çžnªÃ@ù›Rñ ÕäQ§˜áa<¦iÃüÉÎÆó±ò¹ï1hÜÀÊ> Ý_¶hçaEFb¸â‰?†½~#¯ðjg*Îåã ³égâŸäUÄ^‡ŒS.Û@eüÂy,÷`‚eÖö×Q&én7I¤û뺃"ŽòLU#µaÉbouncycastle-1.49.orig/test/data/PKITS/certs/InvalidSelfIssuedinhibitPolicyMappingTest9EE.crt0000644000175000017500000000125310350736724031640 0ustar ebourgebourg0‚§0‚ 0  *†H†÷ 0U1 0 UUS10U Test Certificates1*0(U!inhibitPolicyMapping1 P1 subsubCA0 010419145720Z 110419145720Z0q1 0 UUS10U Test Certificates1F0DU=Invalid Self-Issued inhibitPolicyMapping EE Certificate Test90Ÿ0  *†H†÷ 0‰Ê\^B„A>н¬·ë…‡P=¯©*ܘŒJŸÞŸfúåúè;ñþÁÜcÙK½¼xð;þ\õá­1°a¯_AËŽRÿºž¦…9×ñV0˜rmƒk*ÊÖ(nYd? é×òZåŒC’Ô·›ò ½…l)Ãzøþ+ç#J$Q'ü£k0i0U#0€~—C¤}Þe‘;7}'½¤óУ0Uß…îAóÔÅ6?/jÍ)ó™Å50Uÿð0U 00  `†He00  *†H†÷ (àÐL¹¡”ë"ŽR¤M_:!dìã'nëÑê$àSpP+žØc z¹k*¡â(h¿Ì(@7ÜdÁ§DʼC çLoÓÿà†û\DpT3æTø/A‹Ü¨.áϰ{¡ƒ»®(’ºè‡eöÇûrž˜qœ„RèÊ\ÓOõÍø ýbouncycastle-1.49.orig/test/data/PKITS/certs/inhibitPolicyMapping1P1subsubCACert.crt0000644000175000017500000000130710350736724027727 0ustar ebourgebourg0‚Ã0‚, 0  *†H†÷ 0R1 0 UUS10U Test Certificates1'0%UinhibitPolicyMapping1 P1 subCA0 010419145720Z 110419145720Z0U1 0 UUS10U Test Certificates1*0(U!inhibitPolicyMapping1 P1 subsubCA0Ÿ0  *†H†÷ 0‰óK4V¡oNÕ¤+~XE†×†¿R/38(±”8H¿‘Alnוx•£(E€wòå±SïЯûRÅ;'fPd "$Øu†f3ÙŒÿíß¼uÝœ]àg µô„ eCWÅ!C|èe :Å2ÙX*.æºËy5S“Òâµ!_ÉôeÕ£¥0¢0U#0€¶¦ÁêÀRS߆ýfIä´F¾c3 0U~—C¤}Þe‘;7}'½¤óУ0Uÿ0U 00  `†He00&U!ÿ00 `†He0 `†He00Uÿ0ÿ0  *†H†÷ ±ß'©|Vó¾Rº/q¤÷vüåÕ¿‰mP¶*K‹k¨€)§6]Áî1ƒ‡+¾¼W ÀéÛÛª²ièã3ª5¤•ŒFµ³w†Ù þOІ= %‘Ú™¢ÄöQu{qAp"AVÁÁÀŒtÄ…¸~\Ô;¿†…ªW§~“°E` öú~Wbouncycastle-1.49.orig/test/data/PKITS/certs/pathLenConstraint6subsubsubCA41XCert.crt0000644000175000017500000000123410350736724030057 0ustar ebourgebourg0‚˜0‚ 0  *†H†÷ 0Q1 0 UUS10U Test Certificates1&0$UpathLenConstraint6 subsubCA410 010419145720Z 110419145720Z0U1 0 UUS10U Test Certificates1*0(U!pathLenConstraint6 subsubsubCA41X0Ÿ0  *†H†÷ 0‰¹iøYÄÇ¿=#ÝdªŽ)šzª:…P{ )Àò¢õ´Òá^Ò _ûóß«B÷­°£Ì¾Qj”œ@$0.qWý!ÁîŸâN6ˆQÂÁ£\†ß|œy¦“­å )©=¢¼$ÔÓŒ8/Þ ð{YSålç™öð39q‹Š*âá×£|0z0U#0€ÆÅÝ=×ûtC@ÉÐªå¡ Ö4Š0U•犖tù<ô›©IóÁš?Îp0Uÿ0U 00  `†He00Uÿ0ÿ0  *†H†÷ »1Gkd l2½öê˜Ç¾§it3ˆ 0G7¯gj‹æ*îW eŸB]dÝ«ÎVWˆÙl0kÏO̲¶jmQË\;@Îüÿ¨.ÝøÈɇ¯K]Pkt[e YûÅ—*¹ï°+_KíA¬|ÎqMK$2ÐÞêófÆýç·X%bouncycastle-1.49.orig/test/data/PKITS/certs/InvalidURInameConstraintsTest35EE.crt0000644000175000017500000000131410350736724027334 0ustar ebourgebourg0‚È0‚1 0  *†H†÷ 0K1 0 UUS10U Test Certificates1 0UnameConstraints URI1 CA0 010419145720Z 110419145720Z0e1 0 UUS10U Test Certificates1:08U1Invalid URI nameConstraints EE Certificate Test350Ÿ0  *†H†÷ 0‰ªî‘W9çu º p,uDbbѧûÀ;žEÞxÙGòð¯*gm«Aé&É÷ã SãË^‹À"UçXëm¿0/ ËMOñG›-Ð÷žŠEMµâ|¦Ò8O²ž¨ ¾Øx´ÿuh}ƒÈ\¸1:øÂõWY§`¨î _iN=£¡0ž0U#0€¬ºK _â¼a®áÙdZy¾EÖ0UIº27°f¾ÒØVñ*ôš€”‘ôã0Uÿð0U 00  `†He003U,0*†(http://testcertificates.gov/invalid.html0  *†H†÷ 1™(úUºwóTÊ­r?'e—?a̦ÇñÛŽi£¶Lzºùß½ãud«zm*«r@>äȳYU^Ý£™0–0U#0€W«øœ'ÈÒôæÏoª 5gƒ$k0UñÍ ¾'lÚ7€fc”(Ë©ÈT0Uÿð0U 00  `†He00+U$0" Test28EE@invalidcertificates.gov0  *†H†÷ mfGpÃÅ3ÖZž·c:wÐé»xî!>¤*Ì‹&mÚz›GP‚§zØãçkÍy•—30­-íTôÃö½d•¯1òQyÆÆ› dbD¼Ý ºø°Em±ˆÆ¼Â½/3:êLuU[—b´ÎÜTHtÑÉö¤LrI0o-¤”_àB»õÜbouncycastle-1.49.orig/test/data/PKITS/certs/InvalidcRLIssuerTest34EE.crt0000644000175000017500000000140010350736724025452 0ustar ebourgebourg0‚ü0‚e  0  *†H†÷ 0C1 0 UUS10U Test Certificates10U indirectCRL CA50 010419145720Z 110419145720Z0[1 0 UUS10U Test Certificates100.U'Invalid cRLIssuer EE Certificate Test340Ÿ0  *†H†÷ 0‰’hôdyèD”Ù 9?‰•]P¡» l–YóJÑ®–‡ø¾´›Ôš×X²%*MÁA±,=C|Í&²9ÆJ’ ´ÄkžFŽM¥&ÎÌÕ*Ÿq:æy¾ð§&:ˆJ§ž$¿èK)î0ŸŠ½SaÓ¢‡zÓl}xn™ÓÃ)J#ËÙrMï£ç0ä0U#0€”­Ñá~û7KA=mY€?DWm0U8@$¶J1ËBÔw~âðï,•áäð0Uÿð0U 00  `†He00yUr0p0n l j¤h0f1 0 UUS10U Test Certificates10U indirectCRL CA51!0UCRL1 for indirectCRL CA50  *†H†÷  iÔL𑚸ÿwž™Ìç ”Þýn-ýˆZ{fìk‘ÒûeÉÔ›€9ËK¶fŒ°RÓQF!ùè†Ú\rÆŽcAVĶ *Š×;&ê#fÔ:–ÆO”I\å}’î„úø&ï£(í"À‰s†ö\+ËÆEqð,‡é.T2œ¨Wbouncycastle-1.49.orig/test/data/PKITS/certs/pathLenConstraint0subCA2Cert.crt0000644000175000017500000000121410350736725026411 0ustar ebourgebourg0‚ˆ0‚ñ 0  *†H†÷ 0I1 0 UUS10U Test Certificates10UpathLenConstraint0 CA0 010419145720Z 110419145720Z0M1 0 UUS10U Test Certificates1"0 UpathLenConstraint0 subCA20Ÿ0  *†H†÷ 0‰°TXéú%!È "ºPþ#%ʧdô@L ¾¨"DªKîŸýúÍÆÃïòݽ„QøPOñbûÓ 9|tº"SÑÇ­`Dèüx¢«›Û³FÑŸ6³,"ÀHE™áËnð(›I—]k°¯øÏƒž™Â83y§Âˆhºˆ/Õ\xºÎÃõ£|0z0U#0€8­%ÈBZ× éJôæ,¥S¤PôL0URzkBN°ãÍ‚¥cÏn#”‰50Uÿ0U 00  `†He00Uÿ0ÿ0  *†H†÷ …-BÜÛ¡ù0,øª`þÖS­Ü—`Æ3_–û ì‚}éBg¨†#ø€¸ôlÙ²FYPÐ$ë÷-$™jl4,ÈêOYÊâÝÛÌuw³Véx°§TmoÃClòG¼ yjt:éêe]Âï W©gê¦6ý66ºÚÅÀÇRbouncycastle-1.49.orig/test/data/PKITS/certs/PoliciesP123subsubCAP12P2Cert.crt0000644000175000017500000000121710350736725026126 0ustar ebourgebourg0‚‹0‚ô 0  *†H†÷ 0J1 0 UUS10U Test Certificates10UPolicies P123 subCAP120 010419145720Z 110419145720Z0O1 0 UUS10U Test Certificates1$0"UPolicies P123 subsubCAP12P20Ÿ0  *†H†÷ 0‰ý Ò5LYäÖ‰&}©¯¾3å@ôý¡7Z-L Ñ9ÛóŽFà˜y:þnï—_R`&½5n¹af†e­ÜôûV(ê,UjËŒWÿ£„Û:Œã’‡"ÝVP Ùb}ê3©oñÕÞú_kãwC0ÌJEwtXól/ÚdlÖa|½ù£|0z0U#0€Z‡!ûÜ“mš |Çj±hKßU×0U‹ì9ó£®n9pdh+MT,ŽÀ0Uÿ0U 00  `†He00Uÿ0ÿ0  *†H†÷  ¸ÜTãõÔ ÎŽÓàÒ¯®´ìJfàö ï.È tq‡µËÒl ÿÛ %ÆB <ÍZZ“”c˜Œå0¼ ÍÛ·«„ “—fÚá ôÆ„·w¬½™ô1S»·lN\‚ê° ÞÈ"ã[ê ÝH¥£Óájm'ð;û5¼ bouncycastle-1.49.orig/test/data/PKITS/certs/deltaCRLIndicatorNoBaseCACert.crt0000644000175000017500000000120610350736725026455 0ustar ebourgebourg0‚‚0‚ë Z0  *†H†÷ 0@1 0 UUS10U Test Certificates10U Trust Anchor0 010419145720Z 110419145720Z0P1 0 UUS10U Test Certificates1%0#UdeltaCRLIndicator No Base CA0Ÿ0  *†H†÷ 0‰ n„½¨+xºÜü·'‚Ú°ó™¶‹·WcAr@j_à¯T'òÎ~ÉÕù sTÊЋÎ@Wb*#© ·Ë˽ðþ¶FPDuŒ(û+öàsÖ#eu+c°òþ°¬0%Yg”Û%‹w•vrÎìq'Š‘…1‹gƒÒ/,ðÐi%£|0z0U#0€ûlÔ-žÊ'zž °<êš¼‡ÿIê0U‹Öÿž)é,PÑ#y]eÛ`pôÓ0Uÿ0U 00  `†He00Uÿ0ÿ0  *†H†÷ ¥4ÑF8™‚.2|yÜ\¥iY… Ñ›Óþ]Òî7tÜâ·jÅmÏqÃÏ6M·î\¥Í䤨a`Q¢é_½$ÀGÞ°Ç@Û„W-ÓÂ$œ5ëÊ=гÐgi®´„èÄ]R>å‡Z»‰+è“Äæ™ãlÁ¹Î«±,Ì“èI§Pbouncycastle-1.49.orig/test/data/PKITS/certs/InvalidonlySomeReasonsTest16EE.crt0000644000175000017500000000121510350736724026743 0ustar ebourgebourg0‚‰0‚ò 0  *†H†÷ 0G1 0 UUS10U Test Certificates10UonlySomeReasons CA10 010419145720Z 110419145720Z0a1 0 UUS10U Test Certificates1604U-Invalid onlySomeReasons EE Certificate Test160Ÿ0  *†H†÷ 0‰–`+æ—Ýòð?D2R~*<@Àl¼Æ_–ýV`)ÜøbÈ.ûŒÒ¼âŸ¼âÒVêPTPG°C)êÍd ê’*ØÀ¶s¯ïª&t…L©£ .Á¡óÖÏÛU•ãÂ1¢ †å\)0fßs:B3Œ¹ÁKõ AÞŠ é q>«£k0i0U#0€àbšßP½[Iþ¾pÌÜ9n0U—P( l¦¶vÁ »z« –>®Y³0Uÿð0U 00  `†He00  *†H†÷ šŸαo](‚`»Wÿÿײ’n  X\2_8‰dõcãäÁSuQâ7’ÝnW Ç÷€[g‹Nì7‚t´ç$\î[Ãdö÷æš{â ‡÷ Ì¿‡ÂT‰Ì‘jMGgX/Ö`Ÿ Ú¸77™Í5ÿ\qoªíͤ¡¯bouncycastle-1.49.orig/test/data/PKITS/certs/ValidRFC3280MandatoryAttributeTypesTest7EE.crt0000644000175000017500000000134410350736724030716 0ustar ebourgebourg0‚à0‚I 0  *†H†÷ 0Ž1 0 UUS10U Test Certificates10 ’&‰“ò,dgov1 0 ’&‰“ò,dtestcertificates10UMaryland1 0 U3451 0 U.CA0 010419145720Z 110419145720Z0p1 0 UUS10U Test Certificates1E0CUo Ë4iv‰/Í–ó˜¨_Äû†ÁlTž®¯Ù’N8˜m³Šâ9¤‘{€\ø…Äw' ðäzM‡·^ ÿœ÷ý ûæVQZPSÛ}ÊH½x<¢“â§6ìRò~ìS©jTÞD®>½å4:=HEháï{‹œbouncycastle-1.49.orig/test/data/PKITS/certs/indirectCRLCA6Cert.crt0000644000175000017500000000117110350736724024326 0ustar ebourgebourg0‚u0‚Þ Y0  *†H†÷ 0@1 0 UUS10U Test Certificates10U Trust Anchor0 010419145720Z 110419145720Z0C1 0 UUS10U Test Certificates10UindirectCRL CA60Ÿ0  *†H†÷ 0‰¹þ¶–¡åôxªB˜b—m³è3¤® ñ*@k‘sÉÐXp‚ZŒžÌmbåZ5Ÿ7vìM˜AÚVäoÛÒá8¡æ™glåï‘¥‡ø¨„‚áoD8ô•žà•6É )†šfÍx°´g('ÜßßwÂE1LJÒ@Øšç«Æ{ 2 °“¥£|0z0U#0€ûlÔ-žÊ'zž °<êš¼‡ÿIê0UÂ>ªNÁ3ŠªYI±f¢ð}0Uÿ0U 00  `†He00Uÿ0ÿ0  *†H†÷ #.uú&Τöó„Ã@0OÄPjOѱô¡ôÏÿ¥Ž À÷3o€b9-ŒrãJXŠ'ÈË¢r©­ˆþ¼#+’J<œÒK"üõûôÝ5ûÆàÁº¨W:€/xB‡Ûc3×™A¼¸‚ˆxTõ7…=Np”Dd)"8`#Ñbouncycastle-1.49.orig/test/data/PKITS/certs/deltaCRLCA1Cert.crt0000644000175000017500000000116610350736724023615 0ustar ebourgebourg0‚r0‚Û [0  *†H†÷ 0@1 0 UUS10U Test Certificates10U Trust Anchor0 010419145720Z 110419145720Z0@1 0 UUS10U Test Certificates10U deltaCRL CA10Ÿ0  *†H†÷ 0‰–ÓfJ}(„ù{…šÊ)Cb~¬íR²x¤0 wr ½L&™Ã:ŠNûxHÃü:¶ÀxðBp0(¨~‡Å°ͱ‰‰Ô‚’ÅÚ'ÿK ²[5 ¨а}Ïœô4·ÄÿIçRPœyámc;?þÀÇàî…@-Ýgtßúkj£|0z0U#0€ûlÔ-žÊ'zž °<êš¼‡ÿIê0U“M¼ò× ® H¬º2 ×è Í0Uÿ0U 00  `†He00Uÿ0ÿ0  *†H†÷ ˜b‹ð(º‹ òØZ/O™Øb¹  ¯Ã"ƉW9µâäÑç–Ïâ•$0 Úå+‰tî}æ¿•Ù¢d&_™öÍH<¬^åp\fà}Å <'ƒÕB­Uú&¯x¨ëÓ\ëaðhS€P;L/~rÐI‘ýÛŽÞyæbouncycastle-1.49.orig/test/data/PKITS/certs/PoliciesP123subsubCAP12P1Cert.crt0000644000175000017500000000121710350736725026125 0ustar ebourgebourg0‚‹0‚ô 0  *†H†÷ 0J1 0 UUS10U Test Certificates10UPolicies P123 subCAP120 010419145720Z 110419145720Z0O1 0 UUS10U Test Certificates1$0"UPolicies P123 subsubCAP12P10Ÿ0  *†H†÷ 0‰Ü‘ɪ£_F!âÊ‚½|ào$fE eÅU¯—ÂDl'*é­¡?ƒçM©Ñð1Cùnë¿þ[?WûFÀÂK°,ÉÕ—GeF•kÔÜMísÿ·:“7Ëü2p®\¿• gDtb*ÍvÔÑE²(Óö?³öH(¬-zi&ÙV"èw£|0z0U#0€Z‡!ûÜ“mš |Çj±hKßU×0U#‰œø#aBè–›5j¼0½^Š‚0Uÿ0U 00  `†He00Uÿ0ÿ0  *†H†÷ Dñ— ö{ßдýÄ/œcC>»’Ï1ƒq‘çvh…ä}qšÚúœ‹¹T#'’AVI±R @ ß\}%¼ &%/.V_îHŒ|ØJþ!ÐbÄâæÌš Ÿnp"tö•„òÁ *I”ß“}j8G"‚ZÅè¿y(“NÜyæ_7Îbouncycastle-1.49.orig/test/data/PKITS/certs/requireExplicitPolicy4subsubCACert.crt0000644000175000017500000000123110350736724027741 0ustar ebourgebourg0‚•0‚þ 0  *†H†÷ 0P1 0 UUS10U Test Certificates1%0#UrequireExplicitPolicy4 subCA0 010419145720Z 110419145720Z0S1 0 UUS10U Test Certificates1(0&UrequireExplicitPolicy4 subsubCA0Ÿ0  *†H†÷ 0‰Ñw¡µfv_~N>8¸áJL9+tû¿U2ŠÑîÑ„¾ÅìhØËwJŽnôƒ¸P~p­uÈÂmÇÕ­úZŽ5G@ïÄ ÿÊ…^ŒãQÌÁŽuñغþmøwÏ›Â&,ÂõãòØÅzµS§½ëÅ0U¾l¬ LS”¸ä‘#¥«c0Uÿ0U 00  `†He00Uÿ0ÿ0  *†H†÷ _þj5…:툛Û%‚h¸bsçªNhYŠŽ¬èwÈxã„wǾ?yߣ”f^À_•á -uŠñÙåw¹[aœävÔñpå+âOÚR ¥ß$Þo“¼¬Í_+M&¡ \J‚†â²³S <Ï&õò#XËÐ¥?Ô¿IHÌæÀ&G¦ˆ«Dbouncycastle-1.49.orig/test/data/PKITS/certs/InvalidinhibitPolicyMappingTest1EE.crt0000644000175000017500000000124710350736724027644 0ustar ebourgebourg0‚£0‚  0  *†H†÷ 0O1 0 UUS10U Test Certificates1$0"UinhibitPolicyMapping0 subCA0 010419145720Z 110419145720Z0e1 0 UUS10U Test Certificates1:08U1Invalid inhibitPolicyMapping EE Certificate Test10Ÿ0  *†H†÷ 0‰°Ø™¢ݾ·¼Í‘ä‚®p[Hå›3@åã_ȯ†”Ïaꇮ¬Ù’Ý“kŇ$Ÿí…)P^%§Ê/Ž a‡¿íIÉÓ”“ ëJè³[—¯ª›÷sª$C„°=Ÿ¥-仉ð‚Š_‹õ1lîöÏ’ÑèÒ˜s¯<²e£y0w0U#0€0±¯Ü®Õ0ò 9¦ã,!8¯¢‹Ð0U3¿”‡†rÐô6–Î(ql ÆåA0Uÿð0%U 00  `†He00  `†He00  *†H†÷ Š…ßIqyðùopíöþ"„yêT‡b{ËŒ:×_”ñ)&ì¨ y!Ý 4#ʆÉê +åÕÖ=µ˜bµb¥ël¸èùñÛ^¼µý«ÍdÂch 8\@ZEº«)¶(€®© ËfÊ–©·ŠˆP•ÒÀÉò4LÃsŇ„F©Åºn±bouncycastle-1.49.orig/test/data/PKITS/certs/BasicSelfIssuedNewKeyCACert.crt0000644000175000017500000000120610350736725026231 0ustar ebourgebourg0‚‚0‚ë 0  *†H†÷ 0@1 0 UUS10U Test Certificates10U Trust Anchor0 010419145720Z 110419145720Z0P1 0 UUS10U Test Certificates1%0#UBasic Self-Issued New Key CA0Ÿ0  *†H†÷ 0‰´)2‚§ ì·‹Êze]úó›¬ÖS®%8¥C$ÔGþUvÊG¬“âQq µ³µ’×hý)Ò'Ý}ý8(¹•Þ›5|-Að|â I³ þíþKš’IÒGéȳ¨;ÅR$(©ÿË„6D¤¦õþ-©=èⳆܯ‹‚©QÔ  `ë*jA£|0z0U#0€ûlÔ-žÊ'zž °<êš¼‡ÿIê0U¯¹ùÂE̸!â§G¼I½µx(0Uÿ0U 00  `†He00Uÿ0ÿ0  *†H†÷ ®DÃËh>¤eÎû~Ä_ev¸`š£0A²¦nû¢EºÀmà:°Šü5XSO=4Ò¼š’¨Þ Ã\†ÉäÂ|šÉ@5Á³T(ãl% âÌø¢.J_…’­2ë“ãJ ,û¥j9Ùl¹i Ä­ùDUW0Í“ÆyúkZc£k0i0U#0€ H¾(qjH$ <âJÔ*â×5ï0UÎÇÉnT«4´:{ªÜž$Ãs»-„0Uÿð0U 00  `†He00  *†H†÷ · ‡ê¬=ðI·îýv®µÓˆEfO³lýtbiD‘Ã3hZ½­æœpœY/µ²òãQO.¢LÒà ò?‹bZarq¶H·¼òTq1<Ѩ¤G\†Ý;éi‰Hg:ãIbD-硊ë5Ýfó„ )8åyns’øw™60Ù¬z›à¬bouncycastle-1.49.orig/test/data/PKITS/certs/InvalidinhibitAnyPolicyTest5EE.crt0000644000175000017500000000121610350736724027000 0ustar ebourgebourg0‚Š0‚ó 0  *†H†÷ 0N1 0 UUS10U Test Certificates1#0!UinhibitAnyPolicy5 subsubCA0 010419145720Z 110419145720Z0a1 0 UUS10U Test Certificates1604U-Invalid inhibitAnyPolicy EE Certificate Test50Ÿ0  *†H†÷ 0‰²qúÆÉ»»ÈŸ:zÒv¯= ècÆD'ÆÜ£1üŒHLlYØ1s6Ot'ôã}\ÀHð¾(«jAõZƒú —ö×ÕË»¬=ãä)Œãæ"ZÖe¿mGÓƒ (ˆ–f³bߺˮxÓ¾õÞ¶€ûÐæa›ÔG­1bIRwgÔ@´£e0c0U#0€sù ôdœ²ñï·Uª¤¢¯0URç†äzÝ5¥ª¢·öÿT®Q:0Uÿð0U  00U 0  *†H†÷ Jz•C˪¼Ù#—õÝ÷­ñ>èòH‹·ÈÝ>šFç6xm¹¨†Ÿ‰¿×[‡ a³n"YS­cju.N V Ñ;¸6ES·ø3¥¬Ñ_Ñ?@CÍgöbÙzxk˜ÑXÀ*~ö÷½@Ã1éhÛ­]ᵺÝ~0F«’7 ;$©Ç®•¶;Ïbouncycastle-1.49.orig/test/data/PKITS/certs/ValidRFC822nameConstraintsTest25EE.crt0000644000175000017500000000132010350736724027210 0ustar ebourgebourg0‚Ì0‚5 0  *†H†÷ 0N1 0 UUS10U Test Certificates1#0!UnameConstraints RFC822 CA30 010419145720Z 110419145720Z0f1 0 UUS10U Test Certificates1;09U2Valid RFC822 nameConstraints EE Certificate Test250Ÿ0  *†H†÷ 0‰Ž[½h„;pj.ö=‹ý!-3„¾ÇÊîȳ¶£d6Ë’XX+þ“ˆë.¾XæºQ>#¼Ù¯+Ç9)ª¶s<ç”E}}ˆãOt_ð·‚.ù\ ­UBI'o©&!8Ýo$€|ÃúC ì#Ò(XWýÅC3£">Á ÅE+Vùz?Ï£¡0ž0U#0€ê·nš+ €6giµÚ5¥†=)x0Uüñy¨†$ž"hÆ. ÝÞ¸n=Ò70Uÿð0U 00  `†He003U,0*(Test25EE@mailserver.testcertificates.gov0  *†H†÷ L2Á„yoʦßISÐeù‹Á…â|§vHEF@gú !ðaX{wÅÿ]rÌ I=޲'ÒFH¶:¦ÃØ„8dªÌøIƒr9̓ӒHÐ!E*ý-‘8ßÚBXr?¨Zy{I¯@Bm„ËÚ¤a^xƒRYâ„YsKE¯îœåÒ[lþbouncycastle-1.49.orig/test/data/PKITS/certs/P12Mapping1to3CACert.crt0000644000175000017500000000130310350736724024460 0ustar ebourgebourg0‚¿0‚( 10  *†H†÷ 0@1 0 UUS10U Test Certificates10U Trust Anchor0 010419145720Z 110419145720Z0G1 0 UUS10U Test Certificates10UP12 Mapping 1to3 CA0Ÿ0  *†H†÷ 0‰™10,~®êfú’üøºVÁTP¶®–tKö¸ï6-·˜Dv6_±·¨¦,·8±"]«ï{¯V5ôm#‡i6÷«Ÿõ+çc|«yWƒ·4Æ"èjï~møêGn¶2nÃe„³„òb×R ¬¦‡+€Ž´-¹.‘¿@ç÷9Œ¸Ž½‰†Ó£Á0¾0U#0€ûlÔ-žÊ'zž °<êš¼‡ÿIê0U­â ­Rm%¬Í©˜¢ h­r®²0Uÿ0%U 00  `†He00  `†He00&U!ÿ00 `†He0 `†He00Uÿ0ÿ0 U$0€0  *†H†÷ égºH 7f>åƒL Þîð“…éýl @ÂÝò)ÜV$mçû6g,Ó7—ë^/¶›†›à'opû®•} ŸÏjêã*ÊJ·Î÷!ÁÛ¸qMÂ,j×.¹Ž¯É>Ljb&ع¼d/Ì M˜¸»l.$å ²]yaœÞÊí’¥±þuÇ£k0i0U#0€ H¾(qjH$ <âJÔ*â×5ï0UE¬vº6ó|ôW?þî¶Gø)0Uÿð0U 00  `†He00  *†H†÷ CîS™íýI4x(&?2|»C1¼CG{R™³²©ŽLÞž.Ñ1”$’ÜÅá܆<€G÷Þß^A²HcK8%{Q¿ ;CzŽY‘ôédt]ëžÌŸh- ÜÚ÷3ÁiâñAz„-1{3æçjEU©^ý‹ÐAü¦jH‡bouncycastle-1.49.orig/test/data/PKITS/certs/ValidrequireExplicitPolicyTest4EE.crt0000644000175000017500000000123710350736724027533 0ustar ebourgebourg0‚›0‚ 0  *†H†÷ 0V1 0 UUS10U Test Certificates1+0)U"requireExplicitPolicy0 subsubsubCA0 010419145720Z 110419145720Z0d1 0 UUS10U Test Certificates1907U0Valid requireExplicitPolicy EE Certificate Test40Ÿ0  *†H†÷ 0‰¾Î±wbïã½{x%¢J7ÑÕn:¢‚]ô­|8þa ŸâÉcQîíeúž1m]‹È”ñEu„ÃD£j6§úàÇäD“2…eÅsJæ*n5ô‹ŒÊ+ÂÔ®·IZø¿ål«šƒ´r¥iL{APR9Æzþs¥ÕÂc…=Ëf¾î6.8ë£k0i0U#0€Y×èân×yp‚aˆÏRä·I*0UA#¸i¸qÍZÑèÎ-‡ÎJ* ‹0Uÿð0U 00  `†He00  *†H†÷ V—ÊŽÅŠÈ·\9ö«×á#sײLÌ^ÞÅ×Ò©Ùå³ö{FỎF5–õ&ÖñáU½²?ó êðÂlxr`-'&¥'±õouú&ßU3esíAçi"Õ‰¶¥­xßuà<øµý‡å“bouncycastle-1.49.orig/test/data/PKITS/certs/requireExplicitPolicy0subsubsubCACert.crt0000644000175000017500000000123710350736724030455 0ustar ebourgebourg0‚›0‚ 0  *†H†÷ 0S1 0 UUS10U Test Certificates1(0&UrequireExplicitPolicy0 subsubCA0 010419145720Z 110419145720Z0V1 0 UUS10U Test Certificates1+0)U"requireExplicitPolicy0 subsubsubCA0Ÿ0  *†H†÷ 0‰Ù4×b*úƳq“‚¢ Mœ[Ú¶›bS‡°¯È¢ž¾ Ñ¥xš¦ê½-™ZÙ$ ¡;YMç|5#1Zw œ«ñ`Þ°2¯Hœ Ï-òÑï—¸Ë÷BÜ…__æc­”h‚Ï€OW22§UN&AîÒpÀqG‹‚7}Aœa‚OòÕ£|0z0U#0€°BI3hó*ÍT!]æbápÎ¥#@0UY×èân×yp‚aˆÏRä·I*0Uÿ0U 00  `†He00Uÿ0ÿ0  *†H†÷ ­™î¹ì*SB t‘ê‹'ÎË—èN€â( H­YaB¦…ç{'ëS™jôðœÏ¡í)½ÒÛލuŠ}±"ïvEų7³Uú‚Ö•ØgbÖ¥K(u*+Š fœBýL¯?þæR åµ]‰\èÚäÿ%êº42Š‚ú`q“ü9x8bouncycastle-1.49.orig/test/data/PKITS/certs/WrongCRLCACert.crt0000644000175000017500000000116610350736725023540 0ustar ebourgebourg0‚r0‚Û  0  *†H†÷ 0@1 0 UUS10U Test Certificates10U Trust Anchor0 010419145720Z 110419145720Z0@1 0 UUS10U Test Certificates10U Wrong CRL CA0Ÿ0  *†H†÷ 0‰뎙aKMþë‚É¢´$5-'%ñ+Æ/Ôv†™Ïœg]Ä’®×=l¾–‘wé–Žõøó°aì:&7#~l$ttV#h 2)&¸Øm44$t·ã3™GèÆÐ‰¾!úËÇrÙUXc˜Þ_–ŸY)¼aä·¹2rÈVÍ£|0z0U#0€ûlÔ-žÊ'zž °<êš¼‡ÿIê0UÔmãŸÖ}÷šÝ\ Ñ'ðKTiw¨0Uÿ0U 00  `†He00Uÿ0ÿ0  *†H†÷ 8áJàÈcÑÅú·5Þ‚Þ ºÐ4fʰ"0ZòõS•é3o=ß”]bÑi1Ë0‚¨k882J‘»}Ðå€ÄÒ#ôóÐæØnÀ? Çw:™f ôJ‹Æâ iÁŸ¢Ýg+öèˆ8r8Zùqõ†–œ¶%ñµ—5æÈîù4Àœ=V«bouncycastle-1.49.orig/test/data/PKITS/certs/DifferentPoliciesTest9EE.crt0000644000175000017500000000122410350736724025614 0ustar ebourgebourg0‚0‚ù 0  *†H†÷ 0T1 0 UUS10U Test Certificates1)0'U Policies P123 subsubsubCAP12P2P10 010419145720Z 110419145720Z0[1 0 UUS10U Test Certificates100.U'Different Policies EE Certificate Test90Ÿ0  *†H†÷ 0‰¨•#ƒg/#,.ÇUlP€I¼XØ-]Ž^£Ze& Ù†%äÚŸð@%ÿõS_µÑÖ·$³=—¦R•O©NGžeèÍ~‘|ÇêF{ûtÈðê{OŸ—½e#a èbBG}ÚeL[¶’ÛiSåÊÅ˃ºöÆç õq.¤'Œß›÷%a>÷¸+Ýÿ QsWœ?7Xí:¢Yg?ý¾é&ùkÎ#!ÕOýœ$‡÷Û‘ÿhp\±cþú¹¤ %Á!N’#ëÞfHre8`B½;Á!“(€˜íßGxŸ´ÌÖw3ý_P]%7$£¶æ›Š GÓ‡ec—/ºì wɦC£|0z0U#0€ûlÔ-žÊ'zž °<êš¼‡ÿIê0U6b)|¥ÂЄÇ^£'ß©Db0Uÿ0U 00  `†He00Uÿ0ÿ0  *†H†÷ ©çv¾kÛk7ÒJ˦zö¹Íà7l«÷°£&†ŸU;ó¦¤q=Ú¥V¢ÎãSÂØV9Ý>R|[ DnP>̧²½ÞrR/Ì+HoÅ=wçw˜6X¡ÖçØP6yÏš«„}˜u»Rsþå½²+DÆÒûl#øO÷ÉìÂbouncycastle-1.49.orig/test/data/PKITS/certs/GoodsubCACert.crt0000644000175000017500000000117710350736724023506 0ustar ebourgebourg0‚{0‚ä 0  *†H†÷ 0;1 0 UUS10U Test Certificates10UGood CA0 010419145720Z 110419145720Z0>1 0 UUS10U Test Certificates10U Good subCA0Ÿ0  *†H†÷ 0‰óÂü#œh73”O{ájµ}à”°ÍÖþX麀ª§—®bu¶Q“Ž,í'$Ô*ɧ+z¡* í3¼Ïø­££óÑJ;ΆòÁûExªûè­"Št·`ÉC‰!œ Œ€{,šy¢Ö¸Ov²á=·?¯âÜQ6kômeÄ$żç‡q£‹0ˆ0U#0€·.¦‚ËÂȼ¨{'D×53ßš”Ç0U|\i|ÈU±")CûÄ{êê¸}0Uÿ0U 00  `†He00Uÿ0ÿ0 U$0€0  *†H†÷ 2!ˆµöZþ5@±–­Â^JYLµM)¨}UlJ(¶Kô£¶©l]œ ćEŠ(ʦc« äÚ[§ûä¡ñª„8<ª¨e{w+Šã‰ (SíœÈ/¦Äîz8át|/äJCˆè^ù†‡ óÅ$a@Ò ›jLyë¹bouncycastle-1.49.orig/test/data/PKITS/certs/BasicSelfIssuedOldKeyCACert.crt0000644000175000017500000000120610350736724026215 0ustar ebourgebourg0‚‚0‚ë 0  *†H†÷ 0@1 0 UUS10U Test Certificates10U Trust Anchor0 010419145720Z 110419145720Z0P1 0 UUS10U Test Certificates1%0#UBasic Self-Issued Old Key CA0Ÿ0  *†H†÷ 0‰«Á›·N-ÕVÎŒ7–ýÆúSMCø?GóïóÁÄÓó nd3z,|‚øqs)Eï.>‹ÜFYö"µ?!fpÚ¾ <ºø¼wí`hd·ë @zƒ±â)<8pA:}µžÖÅÍVçÝß¡üÕ£§µ‡G Óæìm>§ôß‚èçO£|0z0U#0€ûlÔ-žÊ'zž °<êš¼‡ÿIê0Uú¢j¹îúOÅruÓKzmŒä\9$0Uÿ0U 00  `†He00Uÿ0ÿ0  *†H†÷ sB_¾íÌaßaÜM®ƒC¸?~QÑDàXì åC¼|ü6†hD?,:êî‘Ûµ{S_ðÌ- b[²çMÂJX\½©é‰¸³çH¤{Ìà±Y¯Ö VçÿÐ='Z¯Ž_ÐsîŽN¨°h3QB–ZaùÖ‹»UÐà(šbouncycastle-1.49.orig/test/data/PKITS/certs/ValiddeltaCRLTest2EE.crt0000644000175000017500000000145210350736724024624 0ustar ebourgebourg0‚&0‚ 0  *†H†÷ 0@1 0 UUS10U Test Certificates10U deltaCRL CA10 010419145720Z 110419145720Z0W1 0 UUS10U Test Certificates1,0*U#Valid deltaCRL EE Certificate Test20Ÿ0  *†H†÷ 0‰ÔJW¯WB’lï5;8ÔØÉrÞÉ·ee¶WŸ`ü»î›ÞtÛ^?<žòˆ*-œ%„i@ÉöS¨Wx€Ii•Q ½ùÿ#riìwÙ$ê°Ï+é üʵ±cÖ Ië"nÈ\èTTí èEi±íšÌï]þŸé¿ª¥) £‚0‚0U#0€“M¼ò× ® H¬º2 ×è Í0UÎŽãÞÙcß‹ßr¤,ñí|Ýhç0Uÿð0U 00  `†He00SUL0J0H F D¤B0@1 0 UUS10U Test Certificates10U deltaCRL CA10SU.L0J0H F D¤B0@1 0 UUS10U Test Certificates10U deltaCRL CA10  *†H†÷ b!ÚrsªH†îŒÉøpr‚m.@›ÃAýÈ+(U•Dç§­›u»uÎ…ô¢OJ\¸—n<¿ÐökÖò‡uÁB÷È€6×÷³·óÎ…Ûc^—úжU«~WpÙed"4Òy}‚`_ÝÁÀW}I?ŸêÖ³%æCã ô'xéDtæ36bouncycastle-1.49.orig/test/data/PKITS/certs/InvaliddistributionPointTest9EE.crt0000644000175000017500000000122010350736724027252 0ustar ebourgebourg0‚Œ0‚õ 0  *†H†÷ 0I1 0 UUS10U Test Certificates10U distributionPoint2 CA0 010419145720Z 110419145720Z0b1 0 UUS10U Test Certificates1705U.Invalid distributionPoint EE Certificate Test90Ÿ0  *†H†÷ 0‰Óû.T;ie~tb†¸m pâ‹.$å¬y3aQW™„©H Ùçˆô•ŸôCbeZò2‡L¸Ö?â†W†lŽ½Î‚õ§œü†²+Ißb]C˜)sOÔÙÕ¶ƒRd S&ÝUQ À›õüH’Á:˜ÝÿʯÂÁS(2þðž+*«)£k0i0U#0€:4‹ãvXXć˜}~Œ¬]¹N0U¶ô<—M¾àÕìL8Wz€â-÷¸>0Uÿð0U 00  `†He00  *†H†÷ Ù •”a0qŠ\€&û…‘*ï6t|.!½™õkŒ~‡³^;nEö{)ÞÈVð¸þéÁ„H4m-côUú~ýSaqÁ70Þ–4`>~û-Å­‡ë7I®‡¯” iG¤fêØ›“4‰eü±sï_B–Ì›qÀºžz2œ2¶Q{Ëbouncycastle-1.49.orig/test/data/PKITS/certs/UIDCACert.crt0000644000175000017500000000116510350736724022522 0ustar ebourgebourg0‚q0‚Ú é0  *†H†÷ 0@1 0 UUS10U Test Certificates10U Trust Anchor0 010419145720Z 110419145720Z0:1 0 UUS10U Test Certificates10 UUID CA0Ÿ0  *†H†÷ 0‰ÊÞG7¹Ô°ßôó¬ot°ó ¥x5¤ÖF3Ë0²4ÔLb4ì¦-ýÖ—+â)ܲï9×s¦ñ¨ÌÌ\4Gë«êå¡6o7M5‘³¯l:èƒ2{JN–v>•áz¼™sŒH¢úѬj¶Ü)Éô¾ƒÂ¥Xì,'G‚ £|0z0U#0€ûlÔ-žÊ'zž °<êš¼‡ÿIê0UÒe|ÂÙAˆìÕXDšâÌx0Uÿ0U 00  `†He00Uÿ0ÿ0  *†H†÷ %€à„5b?ð7iø‹P¬"­ä.Ü Ó+Ðóœ03æœ2ÃEnPj‡œD½ÍÕ^1ïì£ÉŽZ´ózfÿæZ›¦Lá dÓ<ŠNnØÜ.g±› ºÜÅUú%lyþ§[v]ýÚ…¶ËBg0†ËxÜפƒóÈYP+E0—8bouncycastle-1.49.orig/test/data/PKITS/certs/onlyContainsCACertsCACert.crt0000644000175000017500000000120010350736724025754 0ustar ebourgebourg0‚|0‚å N0  *†H†÷ 0@1 0 UUS10U Test Certificates10U Trust Anchor0 010419145720Z 110419145720Z0J1 0 UUS10U Test Certificates10UonlyContainsCACerts CA0Ÿ0  *†H†÷ 0‰¨ÿ3Ý/P%W!UÂ¥ºþuÇhdX´Q”¾^û†ª•9¬ôWŸW™“zê ømQ†¾;¥³‡kÿc;õ33ÐÍãÆÝèhÿ ‹³Šs©U™6£—¹¸Ï½„õÑl¤©ö–º+ÜŸ–1l{€q­6À@½M«ùÛ'=mçãÃESºâ £|0z0U#0€ûlÔ-žÊ'zž °<êš¼‡ÿIê0Uó¡Fg{éY«ëU†“ȬäU·0Uÿ0U 00  `†He00Uÿ0ÿ0  *†H†÷ ÆÅ#@Wí£„¥v|”©zvv~$·ë?!3Î#)¬›C§š7‰‹².}´ž#¹fi® æê׋_Iÿð€”©Âî|¤†Ï£t"~õ/E/0˜på˜ÖsüÕúÀœð&Ýyd/ zOžde0AÉ:/Ü-æ-p0\‘À€bouncycastle-1.49.orig/test/data/PKITS/certs/InvalidkeyUsageNotCriticalcRLSignFalseTest5EE.crt0000644000175000017500000000126310350736724031632 0ustar ebourgebourg0‚¯0‚ 0  *†H†÷ 0Z1 0 UUS10U Test Certificates1/0-U&keyUsage Not Critical cRLSign False CA0 010419145720Z 110419145720Z0t1 0 UUS10U Test Certificates1I0GU@Invalid keyUsage Not Critical cRLSign False EE Certificate Test50Ÿ0  *†H†÷ 0‰§‰œw‹—Ž¡‡ÁãàÇÐCY-þ¸£³{11€°%änI?óòÀó‚?A©»vŸ@ÈÎ9 d>Кú¼nLg’êÂsêdH‘ìæ”ägÇX ÈL„*¨§†2·ê)ÒÜH"5òè"+€†`2ìÝã4 úű£k0i0U#0€›¤[ä"XµVÿ.²‚¿"èöø0U;ø~I›ò&á{‹tdHYêùé.·é0Uÿð0U 00  `†He00  *†H†÷ zÞZpêÐåé_}ìb>ož­ &”p8@£µ½ k·ÂhüìZ]Eþ«\¿ÆÁP=f<®w}Y}ŠüfÜ oÕn™#}CÄ}8ÝK?nv­!ó¤~UxµWã*~EMIé[×UÃÝÁ5è‘B4«AËðTc¤´)÷ïêrž€íbouncycastle-1.49.orig/test/data/PKITS/certs/InvalidonlySomeReasonsTest21EE.crt0000644000175000017500000000155010350736724026741 0ustar ebourgebourg0‚d0‚Í 0  *†H†÷ 0G1 0 UUS10U Test Certificates10U onlySomeReasons CA40 010419145720Z 110419145720Z0a1 0 UUS10U Test Certificates1604U-Invalid onlySomeReasons EE Certificate Test210Ÿ0  *†H†÷ 0‰Îyäk¸ …7Šäêc¼QV’K<Õ1sêù‹'¡ 6`äzl/BR)UÀ•›”;bÑÉë^\3HŒHÕü~KH7ÉÊ.¼7p>園0‰£sN 7Wµ 5±Þt=k¯/èΛàh#/uÊ…$ôÊ’žG]ØÅcS£‚D0‚@0U#0€?¾@ñ÷kû°YäZà—Té0UøÕò$¥Öñ“ñ¶ ûŽr;O\0Uÿð0U 00  `†He00ÔUÌ0É0b \ Z¤X0V1 0 UUS10U Test Certificates10U onlySomeReasons CA41 0 UCRL1`0c \ Z¤X0V1 0 UUS10U Test Certificates10U onlySomeReasons CA41 0 UCRL2Ÿ€0  *†H†÷ 6Rjôñ{kãR„îî%7ûóËï‹ß“:#¹n{€{Ýcm|—ˆþt|C‰>uP]•Cð”CEæ»n*ÈÒŸ¦Úx£0Ž@ê8´íƒ›’§ è´?§È)=½+$õî^.ëE2º>£ƒ¼ç'ùûi2”+K­Êm=VaÛV$@bouncycastle-1.49.orig/test/data/PKITS/certs/InvalidDNSnameConstraintsTest31EE.crt0000644000175000017500000000130610350736724027316 0ustar ebourgebourg0‚Â0‚+ 0  *†H†÷ 0K1 0 UUS10U Test Certificates1 0UnameConstraints DNS1 CA0 010419145720Z 110419145720Z0e1 0 UUS10U Test Certificates1:08U1Invalid DNS nameConstraints EE Certificate Test310Ÿ0  *†H†÷ 0‰¼^nIcô‰qI:þÐc>mëX¿ŽVYHuˆÕºÍ·§ï'Çúô=^@‚±‡ýv•ÏT§¬_“³¹u'–±lÐÃR„2”F¿lCöŠ “¸5FÆ oG»‚dz­•+ü°ÜÚ®•8ÓÆ5[kâ!42D‚ ó{!¿7}RŠi£›0˜0U#0€uçgG «ñˆˆÛžÕRŽüsx0U/•¸XâÌ7r!ÄÀ¥ÉèîËÂü0Uÿð0U 00  `†He00-U&0$‚"testserver.invalidcertificates.gov0  *†H†÷ KOíÝ8äV%HuÄzÃx2³HÁêÍsg* èvMÞ°JS‰Y¬ÊüPŸ°6Ã×#c.š‚d£ûXèʦ L(t5ˆn>ñKìÐ|u·-V’˜'Y¦l^ SÎu?b@Gc(ºé€:Drí3/³ yÿéÒg9&bouncycastle-1.49.orig/test/data/PKITS/certs/BasicSelfIssuedNewKeyOldWithNewCACert.crt0000644000175000017500000000122610350736724030177 0ustar ebourgebourg0‚’0‚û 0  *†H†÷ 0P1 0 UUS10U Test Certificates1%0#UBasic Self-Issued New Key CA0 010419145720Z 110419145720Z0P1 0 UUS10U Test Certificates1%0#UBasic Self-Issued New Key CA0Ÿ0  *†H†÷ 0‰Ö»En°åtQ½t¨Œ±Cíbj‰ØÏB$µô¡”êÑ%z5åc9œ­*óŒt&™2ÀáшÌ;^ö.žlåÀd¨¤ÖÕ•T6l¥¡j(V€³VË_è ˆ˜‡BÐmãª{A vX{høié4~ί QìÌ””m1£|0z0U#0€¯¹ùÂE̸!â§G¼I½µx(0UÉ[ÓÑ¿ñÁy\»s LFË-Ù0Uÿ0U 00  `†He00Uÿ0ÿ0  *†H†÷ „†tõjÍ+x×ù¿º2€ÐU__´Î!d™±§„@Ö½ËlÑ„èÎY ¦üï¸ë4XzÚt§¤UZ°²Êí žöÈhF€:[Š]‡”F÷"^‘…tç÷»ŽCa“üÆÀj˜Üä£:É9€h†L:5E ‹Ê‹Ï…6bouncycastle-1.49.orig/test/data/PKITS/certs/NoPoliciesCACert.crt0000644000175000017500000000113710350736724024144 0ustar ebourgebourg0‚[0‚Ä "0  *†H†÷ 0@1 0 UUS10U Test Certificates10U Trust Anchor0 010419145720Z 110419145720Z0B1 0 UUS10U Test Certificates10UNo Policies CA0Ÿ0  *†H†÷ 0‰¥‡þ’lØ@,£q¼:NÎiÍé3 @ŒøÉjð:rúHˆ ±Tùòé×eeŽnïÉ(¯†“p¢øà­I„ó¬ÛßóŽk~5¶æÄ”Ž˜ômXÖÙó<"¾†-oޱÀ½F•ÿ:}Š:TJ5γi\öÚç;;Kòµ£c0a0U#0€ûlÔ-žÊ'zž °<êš¼‡ÿIê0USÁ%}å[>W‘ø–ž]Æ%¨º0Uÿ0Uÿ0ÿ0  *†H†÷ kV² ™µUÜ€ª-I»·¦Ðqß"5/¾yxõ ã*F£UëÔBE8e$üžíMS| ’–qþ)¸è圂Fþ¾.BÑ#Ë<ܦ×ÄUÌ£Pµ<”Êó[Çð©­%û ®Î…ÉhU+Vµ)ÄãWƒ‡çÛðfwHžbouncycastle-1.49.orig/test/data/PKITS/certs/InvalidBadCRLIssuerNameTest5EE.crt0000644000175000017500000000122310350736724026543 0ustar ebourgebourg0‚0‚ø 0  *†H†÷ 0J1 0 UUS10U Test Certificates10UBad CRL Issuer Name CA0 010419145720Z 110419145720Z0d1 0 UUS10U Test Certificates1907U0Invalid Bad CRL Issuer Name EE Certificate Test50Ÿ0  *†H†÷ 0‰™l# ½Å±ùè)×”—ÁQÁ)A`»/–ŸK°b­ÂºÓ=œTߤŽ0}j!ó?+m̳2Tý¿t^y%å%-îP¼î·®Î5Ž7ÔNgKKv™Mà>@œ'‘ ’„Iˆ™K²!!V²É¯{h„Úyâ'2µ†“ˆn¸Ec£k0i0U#0€È4ÛàµcQÑP¤2ÒÅYøCŒàg0U²(ãó‹ Pó93–˜.Ñgß0Uÿð0U 00  `†He00  *†H†÷ aëÑwWk{/{É+‚ï,'ðã÷OË%ìOƒ‰V,ŽïÞ¹´ýì#TƒµCÄŸnÖx¾UÃJ»)þöÈÍ›ðÃV'ŠawãÉ2Dú*l/*>³oë(öê5ÀѨ¼ÿj0pVœîÌmNÙç1SS Q]íc„1cZ Fã.œúbouncycastle-1.49.orig/test/data/PKITS/certs/ValidIDPwithindirectCRLTest25EE.crt0000644000175000017500000000134410350736725026653 0ustar ebourgebourg0‚à0‚I 0  *†H†÷ 0C1 0 UUS10U Test Certificates10UindirectCRL CA20 010419145720Z 110419145720Z0d1 0 UUS10U Test Certificates1907U0Valid IDP with indirectCRL EE Certificate Test250Ÿ0  *†H†÷ 0‰ßЋ% ÍCM“×0&ÚoˆS¸'IÈE»œ;¥, ˆ×¡ ÜI8ç!?6c=÷v¿¢¶z³'jº$kǬ wv4¡\©«èSz¼)æoe¨×îʧ’”0ˆMMÆü´c#†wL„G@ÿ.,F©®$C™SÂUÕ{£Â0¿0U#0€Á¯‚ÕÓOð1bq—îV%y’D9á'‰²¾ðHF¥g˜‹ñdž™&¼½5eDNAµVÙ&y47PÙkãXÑ[£@MŠÝBµ(3Ï6Âbouncycastle-1.49.orig/test/data/PKITS/certs/ValidonlyContainsCACertsTest13EE.crt0000644000175000017500000000124310350736724027137 0ustar ebourgebourg0‚Ÿ0‚ 0  *†H†÷ 0J1 0 UUS10U Test Certificates10UonlyContainsCACerts CA0 010419145720Z 110419145720Z0c1 0 UUS10U Test Certificates1806U/Valid onlyContainsCACerts EE Certificate Test130Ÿ0  *†H†÷ 0‰¥yœÇPÖŽÔ#«r|ÒJýɱÄÚl¹G]RÛ^>{;4ÿõ{•T¹{¦A÷ŸÂï3öØvÙ‰ SÝ.Éî6’#UÌ4½•Û.‘\ááÒü,Rce‚5´T‚ ¨æ»Iç“{ŸîœÉ`¡ýÂÓA\ c‹G”-c‹³Ïð×£|0z0U#0€ó¡Fg{éY«ëU†“ȬäU·0UB±=$ÞÌ¥G§EXK¿v ˆÄã0Uÿö0U 00  `†He00Uÿ0ÿ0  *†H†÷ ŽÝâ,Úé{Ù}ëÑ€ü¶<— ÿâsº>²]ù¹M(œ'ýêŒ%פ‰5£—a><¤¸œIá^¡º¹ÐüÞ¿"); count = 0; while (rIt.hasNext()) { count++; rIt.next(); } if (count != 1) { fail("wrong number of public keyrings on exact match"); } // // partial match 1 expected // rIt = pubRings.getKeyRings("test", true); count = 0; while (rIt.hasNext()) { count++; rIt.next(); } if (count != 1) { fail("wrong number of public keyrings on partial match 1"); } // // partial match 0 expected // rIt = pubRings.getKeyRings("XXX", true); count = 0; while (rIt.hasNext()) { count++; rIt.next(); } if (count != 0) { fail("wrong number of public keyrings on partial match 0"); } // // case-insensitive partial match // rIt = pubRings.getKeyRings("TEST@ubicall.com", true, true); count = 0; while (rIt.hasNext()) { count++; rIt.next(); } if (count != 1) { fail("wrong number of public keyrings on case-insensitive partial match"); } PGPSecretKeyRingCollection secretRings = new PGPSecretKeyRingCollection(sec1); rIt = secretRings.getKeyRings(); count = 0; while (rIt.hasNext()) { PGPSecretKeyRing pgpSec = (PGPSecretKeyRing)rIt.next(); count++; int keyCount = 0; byte[] bytes = pgpSec.getEncoded(); pgpSec = new PGPSecretKeyRing(bytes, new JcaKeyFingerprintCalculator()); Iterator it = pgpSec.getSecretKeys(); while (it.hasNext()) { keyCount++; PGPSecretKey k = (PGPSecretKey)it.next(); PGPPublicKey pk = k.getPublicKey(); pk.getSignatures(); byte[] pkBytes = pk.getEncoded(); PGPPublicKeyRing pkR = new PGPPublicKeyRing(pkBytes); } if (keyCount != 2) { fail("wrong number of secret keys"); } } if (count != 1) { fail("wrong number of secret keyrings"); } // // exact match // rIt = secretRings.getKeyRings("test (Test key) "); count = 0; while (rIt.hasNext()) { count++; rIt.next(); } if (count != 1) { fail("wrong number of secret keyrings on exact match"); } // // partial match 1 expected // rIt = secretRings.getKeyRings("test", true); count = 0; while (rIt.hasNext()) { count++; rIt.next(); } if (count != 1) { fail("wrong number of secret keyrings on partial match 1"); } // // exact match 0 expected // rIt = secretRings.getKeyRings("test", false); count = 0; while (rIt.hasNext()) { count++; rIt.next(); } if (count != 0) { fail("wrong number of secret keyrings on partial match 0"); } // // case-insensitive partial match // rIt = secretRings.getKeyRings("TEST@ubicall.com", true, true); count = 0; while (rIt.hasNext()) { count++; rIt.next(); } if (count != 1) { fail("wrong number of secret keyrings on case-insensitive partial match"); } } public void test2() throws Exception { PGPPublicKeyRingCollection pubRings = new PGPPublicKeyRingCollection(pub2); int count = 0; byte[] encRing = pubRings.getEncoded(); pubRings = new PGPPublicKeyRingCollection(encRing); Iterator rIt = pubRings.getKeyRings(); while (rIt.hasNext()) { PGPPublicKeyRing pgpPub = (PGPPublicKeyRing)rIt.next(); count++; int keyCount = 0; byte[] bytes = pgpPub.getEncoded(); pgpPub = new PGPPublicKeyRing(bytes); Iterator it = pgpPub.getPublicKeys(); while (it.hasNext()) { PGPPublicKey pk = (PGPPublicKey)it.next(); byte[] pkBytes = pk.getEncoded(); PGPPublicKeyRing pkR = new PGPPublicKeyRing(pkBytes); keyCount++; } if (keyCount != 2) { fail("wrong number of public keys"); } } if (count != 2) { fail("wrong number of public keyrings"); } PGPSecretKeyRingCollection secretRings = new PGPSecretKeyRingCollection(sec2); rIt = secretRings.getKeyRings(); count = 0; encRing = secretRings.getEncoded(); secretRings = new PGPSecretKeyRingCollection(encRing); while (rIt.hasNext()) { PGPSecretKeyRing pgpSec = (PGPSecretKeyRing)rIt.next(); count++; int keyCount = 0; byte[] bytes = pgpSec.getEncoded(); pgpSec = new PGPSecretKeyRing(bytes, new JcaKeyFingerprintCalculator()); Iterator it = pgpSec.getSecretKeys(); while (it.hasNext()) { keyCount++; PGPSecretKey k = (PGPSecretKey)it.next(); PGPPublicKey pk = k.getPublicKey(); if (pk.getKeyID() == -1413891222336124627L) { int sCount = 0; Iterator sIt = pk.getSignaturesOfType(PGPSignature.SUBKEY_BINDING); while (sIt.hasNext()) { int type = ((PGPSignature)sIt.next()).getSignatureType(); if (type != PGPSignature.SUBKEY_BINDING) { fail("failed to return correct signature type"); } sCount++; } if (sCount != 1) { fail("failed to find binding signature"); } } pk.getSignatures(); if (k.getKeyID() == -4049084404703773049L || k.getKeyID() == -1413891222336124627L) { k.extractPrivateKey(new JcePBESecretKeyDecryptorBuilder().setProvider("BC").build(sec2pass1)); } else if (k.getKeyID() == -6498553574938125416L || k.getKeyID() == 59034765524361024L) { k.extractPrivateKey(new JcePBESecretKeyDecryptorBuilder().setProvider("BC").build(sec2pass2)); } } if (keyCount != 2) { fail("wrong number of secret keys"); } } if (count != 2) { fail("wrong number of secret keyrings"); } } public void test3() throws Exception { PGPPublicKeyRingCollection pubRings = new PGPPublicKeyRingCollection(pub3); int count = 0; byte[] encRing = pubRings.getEncoded(); pubRings = new PGPPublicKeyRingCollection(encRing); Iterator rIt = pubRings.getKeyRings(); while (rIt.hasNext()) { PGPPublicKeyRing pgpPub = (PGPPublicKeyRing)rIt.next(); count++; int keyCount = 0; byte[] bytes = pgpPub.getEncoded(); pgpPub = new PGPPublicKeyRing(bytes); Iterator it = pgpPub.getPublicKeys(); while (it.hasNext()) { keyCount++; PGPPublicKey pubK = (PGPPublicKey)it.next(); pubK.getSignatures(); } if (keyCount != 2) { fail("wrong number of public keys"); } } if (count != 1) { fail("wrong number of public keyrings"); } PGPSecretKeyRingCollection secretRings = new PGPSecretKeyRingCollection(sec3); rIt = secretRings.getKeyRings(); count = 0; encRing = secretRings.getEncoded(); secretRings = new PGPSecretKeyRingCollection(encRing); while (rIt.hasNext()) { PGPSecretKeyRing pgpSec = (PGPSecretKeyRing)rIt.next(); count++; int keyCount = 0; byte[] bytes = pgpSec.getEncoded(); pgpSec = new PGPSecretKeyRing(bytes, new JcaKeyFingerprintCalculator()); Iterator it = pgpSec.getSecretKeys(); while (it.hasNext()) { keyCount++; PGPSecretKey k = (PGPSecretKey)it.next(); k.extractPrivateKey(sec3pass1, "BC"); } if (keyCount != 2) { fail("wrong number of secret keys"); } } if (count != 1) { fail("wrong number of secret keyrings"); } } public void test4() throws Exception { PGPSecretKeyRingCollection secretRings = new PGPSecretKeyRingCollection(sec4); Iterator rIt = secretRings.getKeyRings(); int count = 0; byte[] encRing = secretRings.getEncoded(); secretRings = new PGPSecretKeyRingCollection(encRing); while (rIt.hasNext()) { PGPSecretKeyRing pgpSec = (PGPSecretKeyRing)rIt.next(); count++; int keyCount = 0; byte[] bytes = pgpSec.getEncoded(); pgpSec = new PGPSecretKeyRing(bytes, new JcaKeyFingerprintCalculator()); Iterator it = pgpSec.getSecretKeys(); while (it.hasNext()) { keyCount++; PGPSecretKey k = (PGPSecretKey)it.next(); k.extractPrivateKey(sec3pass1, "BC"); } if (keyCount != 2) { fail("test4 - wrong number of secret keys"); } keyCount = 0; it = pgpSec.getPublicKeys(); while (it.hasNext()) { keyCount++; PGPPublicKey k = (PGPPublicKey)it.next(); // make sure it's what we think it is! } if (keyCount != 2) { fail("test4 - wrong number of public keys"); } } if (count != 1) { fail("wrong number of secret keyrings"); } } public void test5() throws Exception { PGPPublicKeyRingCollection pubRings = new PGPPublicKeyRingCollection(pub5); int count = 0; byte[] encRing = pubRings.getEncoded(); pubRings = new PGPPublicKeyRingCollection(encRing); Iterator rIt = pubRings.getKeyRings(); while (rIt.hasNext()) { PGPPublicKeyRing pgpPub = (PGPPublicKeyRing)rIt.next(); count++; int keyCount = 0; byte[] bytes = pgpPub.getEncoded(); pgpPub = new PGPPublicKeyRing(bytes); Iterator it = pgpPub.getPublicKeys(); while (it.hasNext()) { keyCount++; it.next(); } if (keyCount != 2) { fail("wrong number of public keys"); } } if (count != 1) { fail("wrong number of public keyrings"); } if (noIDEA()) { return; } PGPSecretKeyRingCollection secretRings = new PGPSecretKeyRingCollection(sec5); rIt = secretRings.getKeyRings(); count = 0; encRing = secretRings.getEncoded(); secretRings = new PGPSecretKeyRingCollection(encRing); while (rIt.hasNext()) { PGPSecretKeyRing pgpSec = (PGPSecretKeyRing)rIt.next(); count++; int keyCount = 0; byte[] bytes = pgpSec.getEncoded(); pgpSec = new PGPSecretKeyRing(bytes, new JcaKeyFingerprintCalculator()); Iterator it = pgpSec.getSecretKeys(); while (it.hasNext()) { keyCount++; PGPSecretKey k = (PGPSecretKey)it.next(); k.extractPrivateKey(new JcePBESecretKeyDecryptorBuilder().setProvider("BC").build(sec5pass1)); } if (keyCount != 2) { fail("wrong number of secret keys"); } } if (count != 1) { fail("wrong number of secret keyrings"); } } private boolean noIDEA() { try { Cipher.getInstance("IDEA", "BC"); return false; } catch (Exception e) { return true; } } public void test6() throws Exception { PGPPublicKeyRingCollection pubRings = new PGPPublicKeyRingCollection(pub6); Iterator rIt = pubRings.getKeyRings(); while (rIt.hasNext()) { PGPPublicKeyRing pgpPub = (PGPPublicKeyRing)rIt.next(); Iterator it = pgpPub.getPublicKeys(); while (it.hasNext()) { PGPPublicKey k = (PGPPublicKey)it.next(); if (k.getKeyID() == 0x5ce086b5b5a18ff4L) { int count = 0; Iterator sIt = k.getSignaturesOfType(PGPSignature.SUBKEY_REVOCATION); while (sIt.hasNext()) { PGPSignature sig = (PGPSignature)sIt.next(); count++; } if (count != 1) { fail("wrong number of revocations in test6."); } } } } byte[] encRing = pubRings.getEncoded(); } public void test7() throws Exception { PGPPublicKeyRing pgpPub = new PGPPublicKeyRing(pub7); Iterator it = pgpPub.getPublicKeys(); PGPPublicKey masterKey = null; while (it.hasNext()) { PGPPublicKey k = (PGPPublicKey)it.next(); if (k.isMasterKey()) { masterKey = k; continue; } int count = 0; PGPSignature sig = null; Iterator sIt = k.getSignaturesOfType(PGPSignature.SUBKEY_REVOCATION); while (sIt.hasNext()) { sig = (PGPSignature)sIt.next(); count++; } if (count != 1) { fail("wrong number of revocations in test7."); } sig.initVerify(masterKey, "BC"); if (!sig.verifyCertification(k)) { fail("failed to verify revocation certification"); } } } public void test8() throws Exception { PGPPublicKeyRingCollection pubRings = new PGPPublicKeyRingCollection(pub8); int count = 0; byte[] encRing = pubRings.getEncoded(); pubRings = new PGPPublicKeyRingCollection(encRing); Iterator rIt = pubRings.getKeyRings(); while (rIt.hasNext()) { PGPPublicKeyRing pgpPub = (PGPPublicKeyRing)rIt.next(); count++; int keyCount = 0; byte[] bytes = pgpPub.getEncoded(); pgpPub = new PGPPublicKeyRing(bytes); Iterator it = pgpPub.getPublicKeys(); while (it.hasNext()) { keyCount++; it.next(); } if (keyCount != 2) { fail("wrong number of public keys"); } } if (count != 2) { fail("wrong number of public keyrings"); } PGPSecretKeyRingCollection secretRings = new PGPSecretKeyRingCollection(sec8); rIt = secretRings.getKeyRings(); count = 0; encRing = secretRings.getEncoded(); secretRings = new PGPSecretKeyRingCollection(encRing); while (rIt.hasNext()) { PGPSecretKeyRing pgpSec = (PGPSecretKeyRing)rIt.next(); count++; int keyCount = 0; byte[] bytes = pgpSec.getEncoded(); pgpSec = new PGPSecretKeyRing(bytes, new JcaKeyFingerprintCalculator()); Iterator it = pgpSec.getSecretKeys(); while (it.hasNext()) { keyCount++; PGPSecretKey k = (PGPSecretKey)it.next(); k.extractPrivateKey(new JcePBESecretKeyDecryptorBuilder().setProvider("BC").build(sec8pass)); } if (keyCount != 2) { fail("wrong number of secret keys"); } } if (count != 1) { fail("wrong number of secret keyrings"); } } public void test9() throws Exception { PGPSecretKeyRingCollection secretRings = new PGPSecretKeyRingCollection(sec9); Iterator rIt = secretRings.getKeyRings(); int count = 0; byte[] encRing = secretRings.getEncoded(); secretRings = new PGPSecretKeyRingCollection(encRing); while (rIt.hasNext()) { PGPSecretKeyRing pgpSec = (PGPSecretKeyRing)rIt.next(); count++; int keyCount = 0; byte[] bytes = pgpSec.getEncoded(); pgpSec = new PGPSecretKeyRing(bytes, new JcaKeyFingerprintCalculator()); Iterator it = pgpSec.getSecretKeys(); while (it.hasNext()) { keyCount++; PGPSecretKey k = (PGPSecretKey)it.next(); PGPPrivateKey pKey = k.extractPrivateKey(new JcePBESecretKeyDecryptorBuilder().setProvider("BC").build(sec9pass)); if (keyCount == 1 && pKey != null) { fail("primary secret key found, null expected"); } } if (keyCount != 3) { fail("wrong number of secret keys"); } } if (count != 1) { fail("wrong number of secret keyrings"); } } public void test10() throws Exception { PGPSecretKeyRing secretRing = new PGPSecretKeyRing(sec10, new JcaKeyFingerprintCalculator()); Iterator secretKeys = secretRing.getSecretKeys(); while (secretKeys.hasNext()) { PGPPublicKey pubKey = ((PGPSecretKey)secretKeys.next()).getPublicKey(); if (pubKey.getValidDays() != 28) { fail("days wrong on secret key ring"); } if (pubKey.getValidSeconds() != 28 * 24 * 60 * 60) { fail("seconds wrong on secret key ring"); } } PGPPublicKeyRing publicRing = new PGPPublicKeyRing(pub10); Iterator publicKeys = publicRing.getPublicKeys(); while (publicKeys.hasNext()) { PGPPublicKey pubKey = (PGPPublicKey)publicKeys.next(); if (pubKey.getValidDays() != 28) { fail("days wrong on public key ring"); } if (pubKey.getValidSeconds() != 28 * 24 * 60 * 60) { fail("seconds wrong on public key ring"); } } } public void generateTest() throws Exception { char[] passPhrase = "hello".toCharArray(); KeyPairGenerator dsaKpg = KeyPairGenerator.getInstance("DSA", "BC"); dsaKpg.initialize(512); // // this takes a while as the key generator has to generate some DSA params // before it generates the key. // KeyPair dsaKp = dsaKpg.generateKeyPair(); KeyPairGenerator elgKpg = KeyPairGenerator.getInstance("ELGAMAL", "BC"); BigInteger g = new BigInteger("153d5d6172adb43045b68ae8e1de1070b6137005686d29d3d73a7749199681ee5b212c9b96bfdcfa5b20cd5e3fd2044895d609cf9b410b7a0f12ca1cb9a428cc", 16); BigInteger p = new BigInteger("9494fec095f3b85ee286542b3836fc81a5dd0a0349b4c239dd38744d488cf8e31db8bcb7d33b41abb9e5a33cca9144b1cef332c94bf0573bf047a3aca98cdf3b", 16); ElGamalParameterSpec elParams = new ElGamalParameterSpec(p, g); elgKpg.initialize(elParams); // // this is quicker because we are using pregenerated parameters. // KeyPair elgKp = elgKpg.generateKeyPair(); PGPKeyPair dsaKeyPair = new PGPKeyPair(PGPPublicKey.DSA, dsaKp, new Date()); PGPKeyPair elgKeyPair = new PGPKeyPair(PGPPublicKey.ELGAMAL_ENCRYPT, elgKp, new Date()); PGPKeyRingGenerator keyRingGen = new PGPKeyRingGenerator(PGPSignature.POSITIVE_CERTIFICATION, dsaKeyPair, "test", PGPEncryptedData.AES_256, passPhrase, null, null, new SecureRandom(), "BC"); keyRingGen.addSubKey(elgKeyPair); PGPSecretKeyRing keyRing = keyRingGen.generateSecretKeyRing(); keyRing.getSecretKey().extractPrivateKey(new JcePBESecretKeyDecryptorBuilder().setProvider("BC").build(passPhrase)); PGPPublicKeyRing pubRing = keyRingGen.generatePublicKeyRing(); PGPPublicKey vKey = null; PGPPublicKey sKey = null; Iterator it = pubRing.getPublicKeys(); while (it.hasNext()) { PGPPublicKey pk = (PGPPublicKey)it.next(); if (pk.isMasterKey()) { vKey = pk; } else { sKey = pk; } } Iterator sIt = sKey.getSignatures(); while (sIt.hasNext()) { PGPSignature sig = (PGPSignature)sIt.next(); if (sig.getKeyID() == vKey.getKeyID() && sig.getSignatureType() == PGPSignature.SUBKEY_BINDING) { sig.initVerify(vKey, "BC"); if (!sig.verifyCertification(vKey, sKey)) { fail("failed to verify sub-key signature."); } } } } private void insertMasterTest() throws Exception { char[] passPhrase = "hello".toCharArray(); KeyPairGenerator rsaKpg = KeyPairGenerator.getInstance("RSA", "BC"); rsaKpg.initialize(512); // // this is quicker because we are using pregenerated parameters. // KeyPair rsaKp = rsaKpg.generateKeyPair(); PGPKeyPair rsaKeyPair1 = new PGPKeyPair(PGPPublicKey.RSA_GENERAL, rsaKp, new Date()); rsaKp = rsaKpg.generateKeyPair(); PGPKeyPair rsaKeyPair2 = new PGPKeyPair(PGPPublicKey.RSA_GENERAL, rsaKp, new Date()); PGPKeyRingGenerator keyRingGen = new PGPKeyRingGenerator(PGPSignature.POSITIVE_CERTIFICATION, rsaKeyPair1, "test", PGPEncryptedData.AES_256, passPhrase, null, null, new SecureRandom(), "BC"); PGPSecretKeyRing secRing1 = keyRingGen.generateSecretKeyRing(); PGPPublicKeyRing pubRing1 = keyRingGen.generatePublicKeyRing(); keyRingGen = new PGPKeyRingGenerator(PGPSignature.POSITIVE_CERTIFICATION, rsaKeyPair2, "test", PGPEncryptedData.AES_256, passPhrase, null, null, new SecureRandom(), "BC"); PGPSecretKeyRing secRing2 = keyRingGen.generateSecretKeyRing(); PGPPublicKeyRing pubRing2 = keyRingGen.generatePublicKeyRing(); try { PGPPublicKeyRing.insertPublicKey(pubRing1, pubRing2.getPublicKey()); fail("adding second master key (public) should throw an IllegalArgumentException"); } catch (IllegalArgumentException e) { if (!e.getMessage().equals("cannot add a master key to a ring that already has one")) { fail("wrong message in public test"); } } try { PGPSecretKeyRing.insertSecretKey(secRing1, secRing2.getSecretKey()); fail("adding second master key (secret) should throw an IllegalArgumentException"); } catch (IllegalArgumentException e) { if (!e.getMessage().equals("cannot add a master key to a ring that already has one")) { fail("wrong message in secret test"); } } } public void generateSha1Test() throws Exception { char[] passPhrase = "hello".toCharArray(); KeyPairGenerator dsaKpg = KeyPairGenerator.getInstance("DSA", "BC"); dsaKpg.initialize(512); // // this takes a while as the key generator has to generate some DSA params // before it generates the key. // KeyPair dsaKp = dsaKpg.generateKeyPair(); KeyPairGenerator elgKpg = KeyPairGenerator.getInstance("ELGAMAL", "BC"); BigInteger g = new BigInteger("153d5d6172adb43045b68ae8e1de1070b6137005686d29d3d73a7749199681ee5b212c9b96bfdcfa5b20cd5e3fd2044895d609cf9b410b7a0f12ca1cb9a428cc", 16); BigInteger p = new BigInteger("9494fec095f3b85ee286542b3836fc81a5dd0a0349b4c239dd38744d488cf8e31db8bcb7d33b41abb9e5a33cca9144b1cef332c94bf0573bf047a3aca98cdf3b", 16); ElGamalParameterSpec elParams = new ElGamalParameterSpec(p, g); elgKpg.initialize(elParams); // // this is quicker because we are using pregenerated parameters. // KeyPair elgKp = elgKpg.generateKeyPair(); PGPKeyPair dsaKeyPair = new PGPKeyPair(PGPPublicKey.DSA, dsaKp, new Date()); PGPKeyPair elgKeyPair = new PGPKeyPair(PGPPublicKey.ELGAMAL_ENCRYPT, elgKp, new Date()); PGPKeyRingGenerator keyRingGen = new PGPKeyRingGenerator(PGPSignature.POSITIVE_CERTIFICATION, dsaKeyPair, "test", PGPEncryptedData.AES_256, passPhrase, true, null, null, new SecureRandom(), "BC"); keyRingGen.addSubKey(elgKeyPair); PGPSecretKeyRing keyRing = keyRingGen.generateSecretKeyRing(); keyRing.getSecretKey().extractPrivateKey(new JcePBESecretKeyDecryptorBuilder().setProvider("BC").build(passPhrase)); if (!keyRing.getSecretKey().getPublicKey().equals(keyRing.getPublicKey())) { fail("secret key public key mismatch"); } PGPPublicKeyRing pubRing = keyRingGen.generatePublicKeyRing(); PGPPublicKey vKey = null; PGPPublicKey sKey = null; Iterator it = pubRing.getPublicKeys(); while (it.hasNext()) { PGPPublicKey pk = (PGPPublicKey)it.next(); if (pk.isMasterKey()) { vKey = pk; } else { sKey = pk; } } // check key id fetch if (keyRing.getPublicKey(vKey.getKeyID()).getKeyID() != vKey.getKeyID()) { fail("secret key public key mismatch - vKey"); } if (keyRing.getPublicKey(sKey.getKeyID()).getKeyID() != sKey.getKeyID()) { fail("secret key public key mismatch - sKey"); } Iterator sIt = sKey.getSignatures(); while (sIt.hasNext()) { PGPSignature sig = (PGPSignature)sIt.next(); if (sig.getKeyID() == vKey.getKeyID() && sig.getSignatureType() == PGPSignature.SUBKEY_BINDING) { sig.initVerify(vKey, "BC"); if (!sig.verifyCertification(vKey, sKey)) { fail("failed to verify sub-key signature."); } } } } private void test11() throws Exception { PGPPublicKeyRing pubRing = new PGPPublicKeyRing(subKeyBindingKey); Iterator it = pubRing.getPublicKeys(); while (it.hasNext()) { PGPPublicKey key = (PGPPublicKey)it.next(); if (key.getValidSeconds() != 0) { fail("expiration time non-zero"); } } } private void rewrapTest() throws Exception { // Read the secret key rings PGPSecretKeyRingCollection privRings = new PGPSecretKeyRingCollection( new ByteArrayInputStream(rewrapKey)); char[] newPass = "fred".toCharArray(); Iterator rIt = privRings.getKeyRings(); if (rIt.hasNext()) { PGPSecretKeyRing pgpPriv= (PGPSecretKeyRing)rIt.next(); Iterator it = pgpPriv.getSecretKeys(); while (it.hasNext()) { PGPSecretKey pgpKey = (PGPSecretKey)it.next(); long oldKeyID = pgpKey.getKeyID(); // re-encrypt the key with an empty password pgpPriv = PGPSecretKeyRing.removeSecretKey(pgpPriv, pgpKey); pgpKey = PGPSecretKey.copyWithNewPassword( pgpKey, new JcePBESecretKeyDecryptorBuilder(new JcaPGPDigestCalculatorProviderBuilder().setProvider("BC").build()).setProvider("BC").build(rewrapPass), null); pgpPriv = PGPSecretKeyRing.insertSecretKey(pgpPriv, pgpKey); // this should succeed PGPPrivateKey privTmp = pgpKey.extractPrivateKey(null); if (pgpKey.getKeyID() != oldKeyID) { fail("key ID mismatch"); } } it = pgpPriv.getSecretKeys(); while (it.hasNext()) { PGPSecretKey pgpKey = (PGPSecretKey)it.next(); long oldKeyID = pgpKey.getKeyID(); // re-encrypt the key with an empty password pgpPriv = PGPSecretKeyRing.removeSecretKey(pgpPriv, pgpKey); pgpKey = PGPSecretKey.copyWithNewPassword( pgpKey, null, new JcePBESecretKeyEncryptorBuilder(SymmetricKeyAlgorithmTags.CAST5).setProvider("BC").build(newPass)); pgpPriv = PGPSecretKeyRing.insertSecretKey(pgpPriv, pgpKey); // this should succeed PGPPrivateKey privTmp = pgpKey.extractPrivateKey(new JcePBESecretKeyDecryptorBuilder(new JcaPGPDigestCalculatorProviderBuilder().setProvider("BC").build()).setProvider("BC").build(newPass)); if (pgpKey.getKeyID() != oldKeyID) { fail("key ID mismatch"); } } } } private void rewrapTestV3() throws Exception { // Read the secret key rings PGPSecretKeyRingCollection privRings = new PGPSecretKeyRingCollection( new ByteArrayInputStream(privv3)); char[] newPass = "fred".toCharArray(); Iterator rIt = privRings.getKeyRings(); if (rIt.hasNext()) { PGPSecretKeyRing pgpPriv = (PGPSecretKeyRing)rIt.next(); Iterator it = pgpPriv.getSecretKeys(); while (it.hasNext()) { PGPSecretKey pgpKey = (PGPSecretKey)it.next(); long oldKeyID = pgpKey.getKeyID(); // re-encrypt the key with an empty password pgpPriv = PGPSecretKeyRing.removeSecretKey(pgpPriv, pgpKey); pgpKey = PGPSecretKey.copyWithNewPassword( pgpKey, new JcePBESecretKeyDecryptorBuilder(new JcaPGPDigestCalculatorProviderBuilder().setProvider("BC").build()).setProvider("BC").build(v3KeyPass), null); pgpPriv = PGPSecretKeyRing.insertSecretKey(pgpPriv, pgpKey); // this should succeed PGPPrivateKey privTmp = pgpKey.extractPrivateKey(null); if (pgpKey.getKeyID() != oldKeyID) { fail("key ID mismatch"); } } it = pgpPriv.getSecretKeys(); while (it.hasNext()) { PGPSecretKey pgpKey = (PGPSecretKey)it.next(); long oldKeyID = pgpKey.getKeyID(); // re-encrypt the key with an empty password pgpPriv = PGPSecretKeyRing.removeSecretKey(pgpPriv, pgpKey); pgpKey = PGPSecretKey.copyWithNewPassword( pgpKey, null, new JcePBESecretKeyEncryptorBuilder(SymmetricKeyAlgorithmTags.CAST5, new JcaPGPDigestCalculatorProviderBuilder().setProvider("BC").build().get(HashAlgorithmTags.MD5)).setProvider("BC").build(newPass)); pgpPriv = PGPSecretKeyRing.insertSecretKey(pgpPriv, pgpKey); // this should succeed PGPPrivateKey privTmp = pgpKey.extractPrivateKey(new JcePBESecretKeyDecryptorBuilder(new JcaPGPDigestCalculatorProviderBuilder().setProvider("BC").build()).setProvider("BC").build(newPass)); if (pgpKey.getKeyID() != oldKeyID) { fail("key ID mismatch"); } } } } private void rewrapTestMD5() throws Exception { // Read the secret key rings PGPSecretKeyRingCollection privRings = new PGPSecretKeyRingCollection( new ByteArrayInputStream(rewrapKey)); char[] newPass = "fred".toCharArray(); Iterator rIt = privRings.getKeyRings(); if (rIt.hasNext()) { PGPSecretKeyRing pgpPriv= (PGPSecretKeyRing)rIt.next(); Iterator it = pgpPriv.getSecretKeys(); PGPDigestCalculatorProvider calcProvider = new JcaPGPDigestCalculatorProviderBuilder().setProvider("BC").build(); while (it.hasNext()) { PGPSecretKey pgpKey = (PGPSecretKey)it.next(); long oldKeyID = pgpKey.getKeyID(); // re-encrypt the key with an empty password pgpPriv = PGPSecretKeyRing.removeSecretKey(pgpPriv, pgpKey); pgpKey = PGPSecretKey.copyWithNewPassword( pgpKey, new JcePBESecretKeyDecryptorBuilder(calcProvider).setProvider("BC").build(rewrapPass), null); pgpPriv = PGPSecretKeyRing.insertSecretKey(pgpPriv, pgpKey); // this should succeed PGPPrivateKey privTmp = pgpKey.extractPrivateKey(null); if (pgpKey.getKeyID() != oldKeyID) { fail("key ID mismatch"); } } it = pgpPriv.getSecretKeys(); while (it.hasNext()) { PGPSecretKey pgpKey = (PGPSecretKey)it.next(); long oldKeyID = pgpKey.getKeyID(); // re-encrypt the key with an empty password pgpPriv = PGPSecretKeyRing.removeSecretKey(pgpPriv, pgpKey); pgpKey = PGPSecretKey.copyWithNewPassword( pgpKey, null, new JcePBESecretKeyEncryptorBuilder(SymmetricKeyAlgorithmTags.CAST5, calcProvider.get(HashAlgorithmTags.MD5)).setProvider("BC").build(newPass)); pgpPriv = PGPSecretKeyRing.insertSecretKey(pgpPriv, pgpKey); // this should succeed PGPPrivateKey privTmp = pgpKey.extractPrivateKey(new JcePBESecretKeyDecryptorBuilder(calcProvider).setProvider("BC").build(newPass)); if (pgpKey.getKeyID() != oldKeyID) { fail("key ID mismatch"); } } } } private void testPublicKeyRingWithX509() throws Exception { checkPublicKeyRingWithX509(pubWithX509); PGPPublicKeyRing pubRing = new PGPPublicKeyRing(pubWithX509); checkPublicKeyRingWithX509(pubRing.getEncoded()); } private void testSecretKeyRingWithPersonalCertificate() throws Exception { checkSecretKeyRingWithPersonalCertificate(secWithPersonalCertificate); PGPSecretKeyRingCollection secRing = new PGPSecretKeyRingCollection(secWithPersonalCertificate); checkSecretKeyRingWithPersonalCertificate(secRing.getEncoded()); } private void testUmlaut() throws Exception { PGPPublicKeyRing pubRing = new PGPPublicKeyRing(umlautKeySig); PGPPublicKey pub = pubRing.getPublicKey(); String userID = (String)pub.getUserIDs().next(); for (Iterator it = pub.getSignatures(); it.hasNext();) { PGPSignature sig = (PGPSignature)it.next(); if (sig.getSignatureType() == PGPSignature.POSITIVE_CERTIFICATION) { sig.initVerify(pub, "BC"); if (!sig.verifyCertification(userID, pub)) { fail("failed UTF8 userID test"); } } } // // this is quicker because we are using pregenerated parameters. // KeyPairGenerator rsaKpg = KeyPairGenerator.getInstance("RSA", "BC"); KeyPair rsaKp = rsaKpg.generateKeyPair(); PGPKeyPair rsaKeyPair1 = new PGPKeyPair(PGPPublicKey.RSA_GENERAL, rsaKp, new Date()); rsaKp = rsaKpg.generateKeyPair(); PGPKeyPair rsaKeyPair2 = new PGPKeyPair(PGPPublicKey.RSA_GENERAL, rsaKp, new Date()); char[] passPhrase = "passwd".toCharArray(); PGPKeyRingGenerator keyRingGen = new PGPKeyRingGenerator(PGPSignature.POSITIVE_CERTIFICATION, rsaKeyPair1, userID, PGPEncryptedData.AES_256, passPhrase, null, null, new SecureRandom(), "BC"); PGPPublicKeyRing pubRing1 = keyRingGen.generatePublicKeyRing(); pub = pubRing1.getPublicKey(); for (Iterator it = pub.getSignatures(); it.hasNext();) { PGPSignature sig = (PGPSignature)it.next(); if (sig.getSignatureType() == PGPSignature.POSITIVE_CERTIFICATION) { sig.initVerify(pub, "BC"); if (!sig.verifyCertification(userID, pub)) { fail("failed UTF8 userID creation test"); } } } } private void checkSecretKeyRingWithPersonalCertificate(byte[] keyRing) throws Exception { PGPSecretKeyRingCollection secCol = new PGPSecretKeyRingCollection(keyRing); int count = 0; for (Iterator rIt = secCol.getKeyRings(); rIt.hasNext();) { PGPSecretKeyRing ring = (PGPSecretKeyRing)rIt.next(); for (Iterator it = ring.getExtraPublicKeys(); it.hasNext();) { it.next(); count++; } } if (count != 1) { fail("personal certificate data subkey not found - count = " + count); } } private void checkPublicKeyRingWithX509(byte[] keyRing) throws Exception { PGPPublicKeyRing pubRing = new PGPPublicKeyRing(keyRing); Iterator it = pubRing.getPublicKeys(); if (it.hasNext()) { PGPPublicKey key = (PGPPublicKey)it.next(); Iterator sIt = key.getSignatures(); if (sIt.hasNext()) { PGPSignature sig = (PGPSignature)sIt.next(); if (sig.getKeyAlgorithm() != 100) { fail("experimental signature not found"); } if (!areEqual(sig.getSignature(), Hex.decode("000101"))) { fail("experimental encoding check failed"); } } else { fail("no signature found"); } } else { fail("no key found"); } } public void performTest() throws Exception { try { test1(); test2(); test3(); test4(); test5(); test6(); // test7(); test8(); test9(); test10(); test11(); generateTest(); generateSha1Test(); rewrapTest(); rewrapTestV3(); rewrapTestMD5(); testPublicKeyRingWithX509(); testSecretKeyRingWithPersonalCertificate(); insertMasterTest(); testUmlaut(); } catch (PGPException e) { if (((PGPException)e).getUnderlyingException() != null) { Exception ex = ((PGPException)e).getUnderlyingException(); fail("exception: " + ex, ex); } else { fail("exception: " + e, e); } } } public String getName() { return "PGPKeyRingTest"; } public static void main( String[] args) { Security.addProvider(new BouncyCastleProvider()); runTest(new PGPKeyRingTest()); } } bouncycastle-1.49.orig/test/src/org/bouncycastle/openpgp/test/BcPGPDSAElGamalTest.java0000644000175000017500000005374011601026206030264 0ustar ebourgebourgpackage org.bouncycastle.openpgp.test; import java.io.ByteArrayInputStream; import java.io.ByteArrayOutputStream; import java.io.InputStream; import java.io.OutputStream; import java.math.BigInteger; import java.security.AlgorithmParameterGenerator; import java.security.AlgorithmParameters; import java.security.KeyPair; import java.security.KeyPairGenerator; import java.security.SecureRandom; import java.security.Security; import java.util.Date; import java.util.Iterator; import javax.crypto.spec.DHParameterSpec; import org.bouncycastle.bcpg.BCPGOutputStream; import org.bouncycastle.bcpg.PublicKeyAlgorithmTags; import org.bouncycastle.bcpg.SymmetricKeyAlgorithmTags; import org.bouncycastle.crypto.AsymmetricBlockCipher; import org.bouncycastle.crypto.encodings.PKCS1Encoding; import org.bouncycastle.crypto.engines.ElGamalEngine; import org.bouncycastle.crypto.params.AsymmetricKeyParameter; import org.bouncycastle.jce.provider.BouncyCastleProvider; import org.bouncycastle.jce.spec.ElGamalParameterSpec; import org.bouncycastle.openpgp.PGPCompressedData; import org.bouncycastle.openpgp.PGPCompressedDataGenerator; import org.bouncycastle.openpgp.PGPEncryptedDataGenerator; import org.bouncycastle.openpgp.PGPEncryptedDataList; import org.bouncycastle.openpgp.PGPException; import org.bouncycastle.openpgp.PGPKeyPair; import org.bouncycastle.openpgp.PGPLiteralData; import org.bouncycastle.openpgp.PGPLiteralDataGenerator; import org.bouncycastle.openpgp.PGPObjectFactory; import org.bouncycastle.openpgp.PGPOnePassSignature; import org.bouncycastle.openpgp.PGPOnePassSignatureList; import org.bouncycastle.openpgp.PGPPrivateKey; import org.bouncycastle.openpgp.PGPPublicKey; import org.bouncycastle.openpgp.PGPPublicKeyEncryptedData; import org.bouncycastle.openpgp.PGPPublicKeyRing; import org.bouncycastle.openpgp.PGPSecretKeyRing; import org.bouncycastle.openpgp.PGPSignature; import org.bouncycastle.openpgp.PGPSignatureGenerator; import org.bouncycastle.openpgp.PGPSignatureList; import org.bouncycastle.openpgp.PGPUtil; import org.bouncycastle.openpgp.operator.bc.BcKeyFingerprintCalculator; import org.bouncycastle.openpgp.operator.bc.BcPBESecretKeyDecryptorBuilder; import org.bouncycastle.openpgp.operator.bc.BcPGPContentSignerBuilder; import org.bouncycastle.openpgp.operator.bc.BcPGPContentVerifierBuilderProvider; import org.bouncycastle.openpgp.operator.bc.BcPGPDataEncryptorBuilder; import org.bouncycastle.openpgp.operator.bc.BcPGPDigestCalculatorProvider; import org.bouncycastle.openpgp.operator.bc.BcPGPKeyConverter; import org.bouncycastle.openpgp.operator.bc.BcPublicKeyDataDecryptorFactory; import org.bouncycastle.openpgp.operator.bc.BcPublicKeyKeyEncryptionMethodGenerator; import org.bouncycastle.util.encoders.Base64; import org.bouncycastle.util.test.SimpleTest; import org.bouncycastle.util.test.UncloseableOutputStream; public class BcPGPDSAElGamalTest extends SimpleTest { byte[] testPubKeyRing = Base64.decode( "mQGiBEAR8jYRBADNifuSopd20JOQ5x30ljIaY0M6927+vo09NeNxS3KqItba" + "nz9o5e2aqdT0W1xgdHYZmdElOHTTsugZxdXTEhghyxoo3KhVcNnTABQyrrvX" + "qouvmP2fEDEw0Vpyk+90BpyY9YlgeX/dEA8OfooRLCJde/iDTl7r9FT+mts8" + "g3azjwCgx+pOLD9LPBF5E4FhUOdXISJ0f4EEAKXSOi9nZzajpdhe8W2ZL9gc" + "BpzZi6AcrRZBHOEMqd69gtUxA4eD8xycUQ42yH89imEcwLz8XdJ98uHUxGJi" + "qp6hq4oakmw8GQfiL7yQIFgaM0dOAI9Afe3m84cEYZsoAFYpB4/s9pVMpPRH" + "NsVspU0qd3NHnSZ0QXs8L8DXGO1uBACjDUj+8GsfDCIP2QF3JC+nPUNa0Y5t" + "wKPKl+T8hX/0FBD7fnNeC6c9j5Ir/Fp/QtdaDAOoBKiyNLh1JaB1NY6US5zc" + "qFks2seZPjXEiE6OIDXYra494mjNKGUobA4hqT2peKWXt/uBcuL1mjKOy8Qf" + "JxgEd0MOcGJO+1PFFZWGzLQ3RXJpYyBILiBFY2hpZG5hICh0ZXN0IGtleSBv" + "bmx5KSA8ZXJpY0Bib3VuY3ljYXN0bGUub3JnPohZBBMRAgAZBQJAEfI2BAsH" + "AwIDFQIDAxYCAQIeAQIXgAAKCRAOtk6iUOgnkDdnAKC/CfLWikSBdbngY6OK" + "5UN3+o7q1ACcDRqjT3yjBU3WmRUNlxBg3tSuljmwAgAAuQENBEAR8jgQBAC2" + "kr57iuOaV7Ga1xcU14MNbKcA0PVembRCjcVjei/3yVfT/fuCVtGHOmYLEBqH" + "bn5aaJ0P/6vMbLCHKuN61NZlts+LEctfwoya43RtcubqMc7eKw4k0JnnoYgB" + "ocLXOtloCb7jfubOsnfORvrUkK0+Ne6anRhFBYfaBmGU75cQgwADBQP/XxR2" + "qGHiwn+0YiMioRDRiIAxp6UiC/JQIri2AKSqAi0zeAMdrRsBN7kyzYVVpWwN" + "5u13gPdQ2HnJ7d4wLWAuizUdKIQxBG8VoCxkbipnwh2RR4xCXFDhJrJFQUm+" + "4nKx9JvAmZTBIlI5Wsi5qxst/9p5MgP3flXsNi1tRbTmRhqIRgQYEQIABgUC" + "QBHyOAAKCRAOtk6iUOgnkBStAJoCZBVM61B1LG2xip294MZecMtCwQCbBbsk" + "JVCXP0/Szm05GB+WN+MOCT2wAgAA"); byte[] testPrivKeyRing = Base64.decode( "lQHhBEAR8jYRBADNifuSopd20JOQ5x30ljIaY0M6927+vo09NeNxS3KqItba" + "nz9o5e2aqdT0W1xgdHYZmdElOHTTsugZxdXTEhghyxoo3KhVcNnTABQyrrvX" + "qouvmP2fEDEw0Vpyk+90BpyY9YlgeX/dEA8OfooRLCJde/iDTl7r9FT+mts8" + "g3azjwCgx+pOLD9LPBF5E4FhUOdXISJ0f4EEAKXSOi9nZzajpdhe8W2ZL9gc" + "BpzZi6AcrRZBHOEMqd69gtUxA4eD8xycUQ42yH89imEcwLz8XdJ98uHUxGJi" + "qp6hq4oakmw8GQfiL7yQIFgaM0dOAI9Afe3m84cEYZsoAFYpB4/s9pVMpPRH" + "NsVspU0qd3NHnSZ0QXs8L8DXGO1uBACjDUj+8GsfDCIP2QF3JC+nPUNa0Y5t" + "wKPKl+T8hX/0FBD7fnNeC6c9j5Ir/Fp/QtdaDAOoBKiyNLh1JaB1NY6US5zc" + "qFks2seZPjXEiE6OIDXYra494mjNKGUobA4hqT2peKWXt/uBcuL1mjKOy8Qf" + "JxgEd0MOcGJO+1PFFZWGzP4DAwLeUcsVxIC2s2Bb9ab2XD860TQ2BI2rMD/r" + "7/psx9WQ+Vz/aFAT3rXkEJ97nFeqEACgKmUCAEk9939EwLQ3RXJpYyBILiBF" + "Y2hpZG5hICh0ZXN0IGtleSBvbmx5KSA8ZXJpY0Bib3VuY3ljYXN0bGUub3Jn" + "PohZBBMRAgAZBQJAEfI2BAsHAwIDFQIDAxYCAQIeAQIXgAAKCRAOtk6iUOgn" + "kDdnAJ9Ala3OcwEV1DbK906CheYWo4zIQwCfUqUOLMp/zj6QAk02bbJAhV1r" + "sAewAgAAnQFYBEAR8jgQBAC2kr57iuOaV7Ga1xcU14MNbKcA0PVembRCjcVj" + "ei/3yVfT/fuCVtGHOmYLEBqHbn5aaJ0P/6vMbLCHKuN61NZlts+LEctfwoya" + "43RtcubqMc7eKw4k0JnnoYgBocLXOtloCb7jfubOsnfORvrUkK0+Ne6anRhF" + "BYfaBmGU75cQgwADBQP/XxR2qGHiwn+0YiMioRDRiIAxp6UiC/JQIri2AKSq" + "Ai0zeAMdrRsBN7kyzYVVpWwN5u13gPdQ2HnJ7d4wLWAuizUdKIQxBG8VoCxk" + "bipnwh2RR4xCXFDhJrJFQUm+4nKx9JvAmZTBIlI5Wsi5qxst/9p5MgP3flXs" + "Ni1tRbTmRhr+AwMC3lHLFcSAtrNg/EiWFLAnKNXH27zjwuhje8u2r+9iMTYs" + "GjbRxaxRY0GKRhttCwqe2BC0lHhzifdlEcc9yjIjuKfepG2fnnSIRgQYEQIA" + "BgUCQBHyOAAKCRAOtk6iUOgnkBStAJ9HFejVtVJ/A9LM/mDPe0ExhEXt/QCg" + "m/KM7hJ/JrfnLQl7IaZsdg1F6vCwAgAA"); byte[] encMessage = Base64.decode( "hQEOAynbo4lhNjcHEAP/dgCkMtPB6mIgjFvNiotjaoh4sAXf4vFNkSeehQ2c" + "r+IMt9CgIYodJI3FoJXxOuTcwesqTp5hRzgUBJS0adLDJwcNubFMy0M2tp5o" + "KTWpXulIiqyO6f5jI/oEDHPzFoYgBmR4x72l/YpMy8UoYGtNxNvR7LVOfqJv" + "uDY/71KMtPQEAIadOWpf1P5Td+61Zqn2VH2UV7H8eI6hGa6Lsy4sb9iZNE7f" + "c+spGJlgkiOt8TrQoq3iOK9UN9nHZLiCSIEGCzsEn3uNuorD++Qs065ij+Oy" + "36TKeuJ+38CfT7u47dEshHCPqWhBKEYrxZWHUJU/izw2Q1Yxd2XRxN+nafTL" + "X1fQ0lABQUASa18s0BkkEERIdcKQXVLEswWcGqWNv1ZghC7xO2VDBX4HrPjp" + "drjL63p2UHzJ7/4gPWGGtnqq1Xita/1mrImn7pzLThDWiT55vjw6Hw=="); byte[] signedAndEncMessage = Base64.decode( "hQEOAynbo4lhNjcHEAP+K20MVhzdX57hf/cU8TH0prP0VePr9mmeBedzqqMn" + "fp2p8Zb68zmcMlI/WiL5XMNLYRmCgEcXyWbKdP/XV9m9LDBe1CMAGrkCeGBy" + "je69IQQ5LS9vDPyEMF4iAAv/EqACjqHkizdY/a/FRx/t2ioXYdEC2jA6kS9C" + "McpsNz16DE8EAIk3uKn4bGo/+15TXkyFYzW5Cf71SfRoHNmU2zAI93zhjN+T" + "B7mGJwWXzsMkIO6FkMU5TCSrwZS3DBWCIaJ6SYoaawE/C/2j9D7bX1Jv8kum" + "4cq+eZM7z6JYs6xend+WAwittpUxbEiyC2AJb3fBSXPAbLqWd6J6xbZZ7GDK" + "r2Ca0pwBxwGhbMDyi2zpHLzw95H7Ah2wMcGU6kMLB+hzBSZ6mSTGFehqFQE3" + "2BnAj7MtnbghiefogacJ891jj8Y2ggJeKDuRz8j2iICaTOy+Y2rXnnJwfYzm" + "BMWcd2h1C5+UeBJ9CrrLniCCI8s5u8z36Rno3sfhBnXdRmWSxExXtocbg1Ht" + "dyiThf6TK3W29Yy/T6x45Ws5zOasaJdsFKM="); char[] pass = { 'h', 'e', 'l', 'l', 'o', ' ', 'w', 'o', 'r', 'l', 'd' }; public void performTest() throws Exception { try { PGPPublicKey pubKey; PGPUtil.setDefaultProvider("BC"); // // Read the public key // PGPObjectFactory pgpFact = new PGPObjectFactory(testPubKeyRing); PGPPublicKeyRing pgpPub = (PGPPublicKeyRing)pgpFact.nextObject(); pubKey = pgpPub.getPublicKey(); if (pubKey.getBitStrength() != 1024) { fail("failed - key strength reported incorrectly."); } // // Read the private key // PGPSecretKeyRing sKey = new PGPSecretKeyRing(testPrivKeyRing, new BcKeyFingerprintCalculator()); PGPPrivateKey pgpPrivKey = sKey.getSecretKey().extractPrivateKey(new BcPBESecretKeyDecryptorBuilder(new BcPGPDigestCalculatorProvider()).build(pass)); // // signature generation // String data = "hello world!"; ByteArrayOutputStream bOut = new ByteArrayOutputStream(); ByteArrayInputStream testIn = new ByteArrayInputStream(data.getBytes()); PGPSignatureGenerator sGen = new PGPSignatureGenerator(new BcPGPContentSignerBuilder(PGPPublicKey.DSA, PGPUtil.SHA1)); sGen.init(PGPSignature.BINARY_DOCUMENT, pgpPrivKey); PGPCompressedDataGenerator cGen = new PGPCompressedDataGenerator( PGPCompressedData.ZIP); BCPGOutputStream bcOut = new BCPGOutputStream( cGen.open(new UncloseableOutputStream(bOut))); sGen.generateOnePassVersion(false).encode(bcOut); PGPLiteralDataGenerator lGen = new PGPLiteralDataGenerator(); Date testDate = new Date((System.currentTimeMillis() / 1000) * 1000); OutputStream lOut = lGen.open( new UncloseableOutputStream(bcOut), PGPLiteralData.BINARY, "_CONSOLE", data.getBytes().length, testDate); int ch; while ((ch = testIn.read()) >= 0) { lOut.write(ch); sGen.update((byte)ch); } lGen.close(); sGen.generate().encode(bcOut); cGen.close(); // // verify generated signature // pgpFact = new PGPObjectFactory(bOut.toByteArray()); PGPCompressedData c1 = (PGPCompressedData)pgpFact.nextObject(); pgpFact = new PGPObjectFactory(c1.getDataStream()); PGPOnePassSignatureList p1 = (PGPOnePassSignatureList)pgpFact.nextObject(); PGPOnePassSignature ops = p1.get(0); PGPLiteralData p2 = (PGPLiteralData)pgpFact.nextObject(); if (!p2.getModificationTime().equals(testDate)) { fail("Modification time not preserved"); } InputStream dIn = p2.getInputStream(); ops.init(new BcPGPContentVerifierBuilderProvider(), pubKey); while ((ch = dIn.read()) >= 0) { ops.update((byte)ch); } PGPSignatureList p3 = (PGPSignatureList)pgpFact.nextObject(); if (!ops.verify(p3.get(0))) { fail("Failed generated signature check"); } // // test encryption // // // find a key suitable for encryption // long pgpKeyID = 0; AsymmetricKeyParameter pKey = null; BcPGPKeyConverter keyConverter = new BcPGPKeyConverter(); Iterator it = pgpPub.getPublicKeys(); while (it.hasNext()) { PGPPublicKey pgpKey = (PGPPublicKey)it.next(); if (pgpKey.getAlgorithm() == PGPPublicKey.ELGAMAL_ENCRYPT || pgpKey.getAlgorithm() == PGPPublicKey.ELGAMAL_GENERAL) { pKey = keyConverter.getPublicKey(pgpKey); pgpKeyID = pgpKey.getKeyID(); if (pgpKey.getBitStrength() != 1024) { fail("failed - key strength reported incorrectly."); } // // verify the key // } } AsymmetricBlockCipher c = new PKCS1Encoding(new ElGamalEngine()); c.init(true, pKey); byte[] in = "hello world".getBytes(); byte[] out = c.processBlock(in, 0, in.length); pgpPrivKey = sKey.getSecretKey(pgpKeyID).extractPrivateKey(new BcPBESecretKeyDecryptorBuilder(new BcPGPDigestCalculatorProvider()).build(pass)); c.init(false, keyConverter.getPrivateKey(pgpPrivKey)); out = c.processBlock(out, 0, out.length); if (!areEqual(in, out)) { fail("decryption failed."); } // // encrypted message // byte[] text = { (byte)'h', (byte)'e', (byte)'l', (byte)'l', (byte)'o', (byte)' ', (byte)'w', (byte)'o', (byte)'r', (byte)'l', (byte)'d', (byte)'!', (byte)'\n' }; PGPObjectFactory pgpF = new PGPObjectFactory(encMessage); PGPEncryptedDataList encList = (PGPEncryptedDataList)pgpF.nextObject(); PGPPublicKeyEncryptedData encP = (PGPPublicKeyEncryptedData)encList.get(0); InputStream clear = encP.getDataStream(new BcPublicKeyDataDecryptorFactory(pgpPrivKey)); pgpFact = new PGPObjectFactory(clear); c1 = (PGPCompressedData)pgpFact.nextObject(); pgpFact = new PGPObjectFactory(c1.getDataStream()); PGPLiteralData ld = (PGPLiteralData)pgpFact.nextObject(); bOut = new ByteArrayOutputStream(); if (!ld.getFileName().equals("test.txt")) { throw new RuntimeException("wrong filename in packet"); } InputStream inLd = ld.getDataStream(); while ((ch = inLd.read()) >= 0) { bOut.write(ch); } if (!areEqual(bOut.toByteArray(), text)) { fail("wrong plain text in decrypted packet"); } // // signed and encrypted message // pgpF = new PGPObjectFactory(signedAndEncMessage); encList = (PGPEncryptedDataList)pgpF.nextObject(); encP = (PGPPublicKeyEncryptedData)encList.get(0); clear = encP.getDataStream(new BcPublicKeyDataDecryptorFactory(pgpPrivKey)); pgpFact = new PGPObjectFactory(clear); c1 = (PGPCompressedData)pgpFact.nextObject(); pgpFact = new PGPObjectFactory(c1.getDataStream()); p1 = (PGPOnePassSignatureList)pgpFact.nextObject(); ops = p1.get(0); ld = (PGPLiteralData)pgpFact.nextObject(); bOut = new ByteArrayOutputStream(); if (!ld.getFileName().equals("test.txt")) { throw new RuntimeException("wrong filename in packet"); } inLd = ld.getDataStream(); // // note: we use the DSA public key here. // ops.init(new BcPGPContentVerifierBuilderProvider(), pgpPub.getPublicKey()); while ((ch = inLd.read()) >= 0) { ops.update((byte)ch); bOut.write(ch); } p3 = (PGPSignatureList)pgpFact.nextObject(); if (!ops.verify(p3.get(0))) { fail("Failed signature check"); } if (!areEqual(bOut.toByteArray(), text)) { fail("wrong plain text in decrypted packet"); } // // encrypt // ByteArrayOutputStream cbOut = new ByteArrayOutputStream(); PGPEncryptedDataGenerator cPk = new PGPEncryptedDataGenerator(new BcPGPDataEncryptorBuilder(SymmetricKeyAlgorithmTags.TRIPLE_DES).setSecureRandom(new SecureRandom())); PGPPublicKey puK = sKey.getSecretKey(pgpKeyID).getPublicKey(); cPk.addMethod(new BcPublicKeyKeyEncryptionMethodGenerator(puK)); OutputStream cOut = cPk.open(new UncloseableOutputStream(cbOut), bOut.toByteArray().length); cOut.write(text); cOut.close(); pgpF = new PGPObjectFactory(cbOut.toByteArray()); encList = (PGPEncryptedDataList)pgpF.nextObject(); encP = (PGPPublicKeyEncryptedData)encList.get(0); pgpPrivKey = sKey.getSecretKey(pgpKeyID).extractPrivateKey(new BcPBESecretKeyDecryptorBuilder(new BcPGPDigestCalculatorProvider()).build(pass)); clear = encP.getDataStream(new BcPublicKeyDataDecryptorFactory(pgpPrivKey)); bOut.reset(); while ((ch = clear.read()) >= 0) { bOut.write(ch); } out = bOut.toByteArray(); if (!areEqual(out, text)) { fail("wrong plain text in generated packet"); } // // use of PGPKeyPair // BigInteger g = new BigInteger("153d5d6172adb43045b68ae8e1de1070b6137005686d29d3d73a7749199681ee5b212c9b96bfdcfa5b20cd5e3fd2044895d609cf9b410b7a0f12ca1cb9a428cc", 16); BigInteger p = new BigInteger("9494fec095f3b85ee286542b3836fc81a5dd0a0349b4c239dd38744d488cf8e31db8bcb7d33b41abb9e5a33cca9144b1cef332c94bf0573bf047a3aca98cdf3b", 16); KeyPairGenerator kpg = KeyPairGenerator.getInstance("ElGamal", "BC"); ElGamalParameterSpec elParams = new ElGamalParameterSpec(p, g); kpg.initialize(elParams); KeyPair kp = kpg.generateKeyPair(); PGPKeyPair pgpKp = new PGPKeyPair(PGPPublicKey.ELGAMAL_GENERAL , kp.getPublic(), kp.getPrivate(), new Date()); PGPPublicKey k1 = pgpKp.getPublicKey(); PGPPrivateKey k2 = pgpKp.getPrivateKey(); // Test bug with ElGamal P size != 0 mod 8 (don't use these sizes at home!) SecureRandom random = new SecureRandom(); for (int pSize = 257; pSize < 264; ++pSize) { // Generate some parameters of the given size AlgorithmParameterGenerator a = AlgorithmParameterGenerator.getInstance("ElGamal", "BC"); a.init(pSize, new SecureRandom()); AlgorithmParameters params = a.generateParameters(); DHParameterSpec elP = (DHParameterSpec)params.getParameterSpec(DHParameterSpec.class); KeyPairGenerator keyGen = KeyPairGenerator.getInstance("ElGamal", "BC"); keyGen.initialize(elP); // Run a short encrypt/decrypt test with random key for the given parameters kp = keyGen.generateKeyPair(); PGPKeyPair elGamalKeyPair = new PGPKeyPair( PublicKeyAlgorithmTags.ELGAMAL_GENERAL, kp, new Date()); cPk = new PGPEncryptedDataGenerator(new BcPGPDataEncryptorBuilder(SymmetricKeyAlgorithmTags.CAST5).setSecureRandom(random)); puK = elGamalKeyPair.getPublicKey(); cPk.addMethod(new BcPublicKeyKeyEncryptionMethodGenerator(puK)); cbOut = new ByteArrayOutputStream(); cOut = cPk.open(cbOut, text.length); cOut.write(text); cOut.close(); pgpF = new PGPObjectFactory(cbOut.toByteArray()); encList = (PGPEncryptedDataList)pgpF.nextObject(); encP = (PGPPublicKeyEncryptedData)encList.get(0); pgpPrivKey = elGamalKeyPair.getPrivateKey(); // Note: This is where an exception would be expected if the P size causes problems clear = encP.getDataStream(new BcPublicKeyDataDecryptorFactory(pgpPrivKey)); ByteArrayOutputStream dec = new ByteArrayOutputStream(); int b; while ((b = clear.read()) >= 0) { dec.write(b); } byte[] decText = dec.toByteArray(); if (!areEqual(text, decText)) { fail("decrypted message incorrect"); } } // check sub key encoding it = pgpPub.getPublicKeys(); while (it.hasNext()) { PGPPublicKey pgpKey = (PGPPublicKey)it.next(); if (!pgpKey.isMasterKey()) { byte[] kEnc = pgpKey.getEncoded(); PGPObjectFactory objF = new PGPObjectFactory(kEnc); PGPPublicKey k = (PGPPublicKey)objF.nextObject(); pKey = keyConverter.getPublicKey(k); pgpKeyID = k.getKeyID(); if (k.getBitStrength() != 1024) { fail("failed - key strength reported incorrectly."); } if (objF.nextObject() != null) { fail("failed - stream not fully parsed."); } } } } catch (PGPException e) { fail("exception: " + e.getMessage(), e.getUnderlyingException()); } } public String getName() { return "PGPDSAElGamalTest"; } public static void main( String[] args) { Security.addProvider(new BouncyCastleProvider()); runTest(new BcPGPDSAElGamalTest()); } } bouncycastle-1.49.orig/test/src/org/bouncycastle/openpgp/test/BcPGPRSATest.java0000644000175000017500000016453211732262004027064 0ustar ebourgebourgpackage org.bouncycastle.openpgp.test; import java.io.ByteArrayInputStream; import java.io.ByteArrayOutputStream; import java.io.IOException; import java.io.InputStream; import java.io.OutputStream; import java.math.BigInteger; import java.security.PublicKey; import java.security.SecureRandom; import java.security.Security; import java.util.Date; import java.util.Iterator; import javax.crypto.Cipher; import org.bouncycastle.bcpg.BCPGOutputStream; import org.bouncycastle.bcpg.CompressionAlgorithmTags; import org.bouncycastle.bcpg.HashAlgorithmTags; import org.bouncycastle.bcpg.PublicKeyAlgorithmTags; import org.bouncycastle.bcpg.SymmetricKeyAlgorithmTags; import org.bouncycastle.bcpg.attr.ImageAttribute; import org.bouncycastle.bcpg.sig.Features; import org.bouncycastle.bcpg.sig.KeyFlags; import org.bouncycastle.crypto.AsymmetricCipherKeyPair; import org.bouncycastle.crypto.generators.RSAKeyPairGenerator; import org.bouncycastle.crypto.params.RSAKeyGenerationParameters; import org.bouncycastle.jce.provider.BouncyCastleProvider; import org.bouncycastle.openpgp.PGPCompressedData; import org.bouncycastle.openpgp.PGPCompressedDataGenerator; import org.bouncycastle.openpgp.PGPEncryptedData; import org.bouncycastle.openpgp.PGPEncryptedDataGenerator; import org.bouncycastle.openpgp.PGPEncryptedDataList; import org.bouncycastle.openpgp.PGPKeyPair; import org.bouncycastle.openpgp.PGPKeyRingGenerator; import org.bouncycastle.openpgp.PGPLiteralData; import org.bouncycastle.openpgp.PGPLiteralDataGenerator; import org.bouncycastle.openpgp.PGPObjectFactory; import org.bouncycastle.openpgp.PGPOnePassSignature; import org.bouncycastle.openpgp.PGPOnePassSignatureList; import org.bouncycastle.openpgp.PGPPBEEncryptedData; import org.bouncycastle.openpgp.PGPPrivateKey; import org.bouncycastle.openpgp.PGPPublicKey; import org.bouncycastle.openpgp.PGPPublicKeyEncryptedData; import org.bouncycastle.openpgp.PGPPublicKeyRing; import org.bouncycastle.openpgp.PGPSecretKey; import org.bouncycastle.openpgp.PGPSecretKeyRing; import org.bouncycastle.openpgp.PGPSignature; import org.bouncycastle.openpgp.PGPSignatureGenerator; import org.bouncycastle.openpgp.PGPSignatureList; import org.bouncycastle.openpgp.PGPSignatureSubpacketGenerator; import org.bouncycastle.openpgp.PGPSignatureSubpacketVector; import org.bouncycastle.openpgp.PGPUserAttributeSubpacketVector; import org.bouncycastle.openpgp.PGPUserAttributeSubpacketVectorGenerator; import org.bouncycastle.openpgp.PGPUtil; import org.bouncycastle.openpgp.PGPV3SignatureGenerator; import org.bouncycastle.openpgp.operator.PublicKeyDataDecryptorFactory; import org.bouncycastle.openpgp.operator.bc.BcKeyFingerprintCalculator; import org.bouncycastle.openpgp.operator.bc.BcPBEDataDecryptorFactory; import org.bouncycastle.openpgp.operator.bc.BcPBEKeyEncryptionMethodGenerator; import org.bouncycastle.openpgp.operator.bc.BcPBESecretKeyDecryptorBuilder; import org.bouncycastle.openpgp.operator.bc.BcPBESecretKeyEncryptorBuilder; import org.bouncycastle.openpgp.operator.bc.BcPGPContentSignerBuilder; import org.bouncycastle.openpgp.operator.bc.BcPGPContentVerifierBuilderProvider; import org.bouncycastle.openpgp.operator.bc.BcPGPDataEncryptorBuilder; import org.bouncycastle.openpgp.operator.bc.BcPGPDigestCalculatorProvider; import org.bouncycastle.openpgp.operator.bc.BcPGPKeyPair; import org.bouncycastle.openpgp.operator.bc.BcPublicKeyDataDecryptorFactory; import org.bouncycastle.openpgp.operator.bc.BcPublicKeyKeyEncryptionMethodGenerator; import org.bouncycastle.util.Arrays; import org.bouncycastle.util.encoders.Base64; import org.bouncycastle.util.encoders.Hex; import org.bouncycastle.util.test.SimpleTest; import org.bouncycastle.util.test.UncloseableOutputStream; public class BcPGPRSATest extends SimpleTest { byte[] testPubKey = Base64.decode( "mIsEPz2nJAEEAOTVqWMvqYE693qTgzKv/TJpIj3hI8LlYPC6m1dk0z3bDLwVVk9F" + "FAB+CWS8RdFOWt/FG3tEv2nzcoNdRvjv9WALyIGNawtae4Ml6oAT06/511yUzXHO" + "k+9xK3wkXN5jdzUhf4cA2oGpLSV/pZlocsIDL+jCUQtumUPwFodmSHhzAAYptC9F" + "cmljIEVjaGlkbmEgKHRlc3Qga2V5KSA8ZXJpY0Bib3VuY3ljYXN0bGUub3JnPoi4" + "BBMBAgAiBQI/PackAhsDBQkAg9YABAsHAwIDFQIDAxYCAQIeAQIXgAAKCRA1WGFG" + "/fPzc8WMA/9BbjuB8E48QAlxoiVf9U8SfNelrz/ONJA/bMvWr/JnOGA9PPmFD5Uc" + "+kV/q+i94dEMjsC5CQ1moUHWSP2xlQhbOzBP2+oPXw3z2fBs9XJgnTH6QWMAAvLs" + "3ug9po0loNHLobT/D/XdXvcrb3wvwvPT2FptZqrtonH/OdzT9JdfrA=="); byte[] testPrivKey = Base64.decode( "lQH8BD89pyQBBADk1aljL6mBOvd6k4Myr/0yaSI94SPC5WDwuptXZNM92wy8FVZP" + "RRQAfglkvEXRTlrfxRt7RL9p83KDXUb47/VgC8iBjWsLWnuDJeqAE9Ov+ddclM1x" + "zpPvcSt8JFzeY3c1IX+HANqBqS0lf6WZaHLCAy/owlELbplD8BaHZkh4cwAGKf4D" + "AwKbLeIOVYTEdWD5v/YgW8ERs0pDsSIfBTvsJp2qA798KeFuED6jGsHUzdi1M990" + "6PRtplQgnoYmYQrzEc6DXAiAtBR4Kuxi4XHx0ZR2wpVlVxm2Ypgz7pbBNWcWqzvw" + "33inl7tR4IDsRdJOY8cFlN+1tSCf16sDidtKXUVjRjZNYJytH18VfSPlGXMeYgtw" + "3cSGNTERwKaq5E/SozT2MKTiORO0g0Mtyz+9MEB6XVXFavMun/mXURqbZN/k9BFb" + "z+TadpkihrLD1xw3Hp+tpe4CwPQ2GdWKI9KNo5gEnbkJgLrSMGgWalPhknlNHRyY" + "bSq6lbIMJEE3LoOwvYWwweR1+GrV9farJESdunl1mDr5/d6rKru+FFDwZM3na1IF" + "4Ei4FpqhivZ4zG6pN5XqLy+AK85EiW4XH0yAKX1O4YlbmDU4BjxhiwTdwuVMCjLO" + "5++jkz5BBQWdFX8CCMA4FJl36G70IbGzuFfOj07ly7QvRXJpYyBFY2hpZG5hICh0" + "ZXN0IGtleSkgPGVyaWNAYm91bmN5Y2FzdGxlLm9yZz6IuAQTAQIAIgUCPz2nJAIb" + "AwUJAIPWAAQLBwMCAxUCAwMWAgECHgECF4AACgkQNVhhRv3z83PFjAP/QW47gfBO" + "PEAJcaIlX/VPEnzXpa8/zjSQP2zL1q/yZzhgPTz5hQ+VHPpFf6voveHRDI7AuQkN" + "ZqFB1kj9sZUIWzswT9vqD18N89nwbPVyYJ0x+kFjAALy7N7oPaaNJaDRy6G0/w/1" + "3V73K298L8Lz09habWaq7aJx/znc0/SXX6w="); byte[] testPubKeyV3 = Base64.decode( "mQCNAz+zvlEAAAEEAMS22jgXbOZ/D3xWgM2kauSdzrwlU7Ms5hDW05ObqQyO" + "FfQoKKMhfupyoa7J3x04VVBKu6Eomvr1es+VImH0esoeWFFahNOYq/I+jRRB" + "woOhAGZ5UB2/hRd7rFmxqp6sCXi8wmLO2tAorlTzAiNNvl7xF4cQZpc0z56F" + "wdi2fBUJAAURtApGSVhDSVRZX1FBiQCVAwUQP7O+UZ6Fwdi2fBUJAQFMwwQA" + "qRnFsdg4xQnB8Y5d4cOpXkIn9AZgYS3cxtuSJB84vG2CgC39nfv4c+nlLkWP" + "4puG+mZuJNgVoE84cuAF4I//1anKjlU7q1M6rFQnt5S4uxPyG3dFXmgyU1b4" + "PBOnA0tIxjPzlIhJAMsPCGGA5+5M2JP0ad6RnzqzE3EENMX+GqY="); byte[] testPrivKeyV3 = Base64.decode( "lQHfAz+zvlEAAAEEAMS22jgXbOZ/D3xWgM2kauSdzrwlU7Ms5hDW05ObqQyO" + "FfQoKKMhfupyoa7J3x04VVBKu6Eomvr1es+VImH0esoeWFFahNOYq/I+jRRB" + "woOhAGZ5UB2/hRd7rFmxqp6sCXi8wmLO2tAorlTzAiNNvl7xF4cQZpc0z56F" + "wdi2fBUJAAURAXWwRBZQHNikA/f0ScLLjrXi4s0hgQecg+dkpDow94eu5+AR" + "0DzZnfurpgfUJCNiDi5W/5c3Zj/xyrfMAgkbCgJ1m6FZqAQh7Mq73l7Kfu4/" + "XIkyDF3tDgRuZNezB+JuElX10tV03xumHepp6M6CfhXqNJ15F33F99TA5hXY" + "CPYD7SiSOpIhQkCOAgDAA63imxbpuKE2W7Y4I1BUHB7WQi8ZdkZd04njNTv+" + "rFUuOPapQVfbWG0Vq8ld3YmJB4QWsa2mmqn+qToXbwufAgBpXkjvqK5yPiHF" + "Px2QbFc1VqoCJB6PO5JRIqEiUZBFGdDlLxt3VSyqz7IZ/zEnxZq+tPCGGGSm" + "/sAGiMvENcHVAfy0kTXU42TxEAYJyyNyqjXOobDJpEV1mKhFskRXt7tbMfOS" + "Yf91oX8f6xw6O2Nal+hU8dS0Bmfmk5/enHmvRLHQocO0CkZJWENJVFlfUUE="); byte[] sig1 = Base64.decode( "owGbwMvMwMRoGpHo9vfz52LGNTJJnBmpOTn5eiUVJfb23JvAHIXy/KKcFEWuToap" + "zKwMIGG4Bqav0SwMy3yParsEKi2LMGI9xhh65sBxb05n5++ZLcWNJ/eLFKdWbm95" + "tHbDV7GMwj/tUctUpFUXWPYFCLdNsDiVNuXbQvZtdXV/5xzY+9w1nCnijH9JoNiJ" + "22n2jo0zo30/TZLo+jDl2vTzIvPeLEsPM3ZUE/1Ytqs4SG2TxIQbH7xf3uzcYXq2" + "5Fw9AA=="); byte[] sig1crc = Base64.decode("+3i0"); byte[] subKey = Base64.decode( "lQH8BD89pyQBBADk1aljL6mBOvd6k4Myr/0yaSI94SPC5WDwuptXZNM92wy8FVZP" + "RRQAfglkvEXRTlrfxRt7RL9p83KDXUb47/VgC8iBjWsLWnuDJeqAE9Ov+ddclM1x" + "zpPvcSt8JFzeY3c1IX+HANqBqS0lf6WZaHLCAy/owlELbplD8BaHZkh4cwAGKf4D" + "AwKt6ZC7iqsQHGDNn2ZAuhS+ZwiFC+BToW9Vq6rwggWjgM/SThv55rfDk7keiXUT" + "MyUcZVeYBe4Jttb4fAAm83hNztFu6Jvm9ITcm7YvnasBtVQjppaB+oYZgsTtwK99" + "LGC3mdexnriCLxPN6tDFkGhzdOcYZfK6py4Ska8Dmq9nOZU9Qtv7Pm3qa5tuBvYw" + "myTxeaJYifZTu/sky3Gj+REb8WonbgAJX/sLNBPUt+vYko+lxU8uqZpVEMU//hGG" + "Rns2gIHdbSbIe1vGgIRUEd7Z0b7jfVQLUwqHDyfh5DGvAUhvtJogjUyFIXZzpU+E" + "9ES9t7LZKdwNZSIdNUjM2eaf4g8BpuQobBVkj/GUcotKyeBjwvKxHlRefL4CCw28" + "DO3SnLRKxd7uBSqeOGUKxqasgdekM/xIFOrJ85k7p89n6ncLQLHCPGVkzmVeRZro" + "/T7zE91J57qBGZOUAP1vllcYLty1cs9PCc5oWnj3XbQvRXJpYyBFY2hpZG5hICh0" + "ZXN0IGtleSkgPGVyaWNAYm91bmN5Y2FzdGxlLm9yZz6IuAQTAQIAIgUCPz2nJAIb" + "AwUJAIPWAAQLBwMCAxUCAwMWAgECHgECF4AACgkQNVhhRv3z83PFjAP/QW47gfBO" + "PEAJcaIlX/VPEnzXpa8/zjSQP2zL1q/yZzhgPTz5hQ+VHPpFf6voveHRDI7AuQkN" + "ZqFB1kj9sZUIWzswT9vqD18N89nwbPVyYJ0x+kFjAALy7N7oPaaNJaDRy6G0/w/1" + "3V73K298L8Lz09habWaq7aJx/znc0/SXX6y0JEVyaWMgRWNoaWRuYSA8ZXJpY0Bi" + "b3VuY3ljYXN0bGUub3JnPoi4BBMBAgAiBQI/RxQNAhsDBQkAg9YABAsHAwIDFQID" + "AxYCAQIeAQIXgAAKCRA1WGFG/fPzc3O6A/49tXFCiiP8vg77OXvnmbnzPBA1G6jC" + "RZNP1yIXusOjpHqyLN5K9hw6lq/o4pNiCuiq32osqGRX3lv/nDduJU1kn2Ow+I2V" + "ci+ojMXdCGdEqPwZfv47jHLwRrIUJ22OOoWsORtgvSeRUd4Izg8jruaFM7ufr5hr" + "jEl1cuLW1Hr8Lp0B/AQ/RxxQAQQA0J2BIdqb8JtDGKjvYxrju0urJVVzyI1CnCjA" + "p7CtLoHQJUQU7PajnV4Jd12ukfcoK7MRraYydQEjxh2MqPpuQgJS3dgQVrxOParD" + "QYBFrZNd2tZxOjYakhErvUmRo6yWFaxChwqMgl8XWugBNg1Dva+/YcoGQ+ly+Jg4" + "RWZoH88ABin+AwMCldD/2v8TyT1ghK70IuFs4MZBhdm6VgyGR8DQ/Ago6IAjA4BY" + "Sol3lJb7+IIGsZaXwEuMRUvn6dWfa3r2I0p1t75vZb1Ng1YK32RZ5DNzl4Xb3L8V" + "D+1Fiz9mHO8wiplAwDudB+RmQMlth3DNi/UsjeCTdEJAT+TTC7D40DiHDb1bR86Y" + "2O5Y7MQ3SZs3/x0D/Ob6PStjfQ1kiqbruAMROKoavG0zVgxvspkoKN7h7BapnwJM" + "6yf4qN/aByhAx9sFvADxu6z3SVcxiFw3IgAmabyWYb85LP8AsTYAG/HBoC6yob47" + "Mt+GEDeyPifzzGXBWYIH4heZbSQivvA0eRwY5VZsMsBkbY5VR0FLVWgplbuO21bS" + "rPS1T0crC+Zfj7FQBAkTfsg8RZQ8MPaHng01+gnFd243DDFvTAHygvm6a2X2fiRw" + "5epAST4wWfY/BZNOxmfSKH6QS0oQMRscw79He6vGTB7vunLrKQYD4veInwQYAQIA" + "CQUCP0ccUAIbDAAKCRA1WGFG/fPzczmFA/wMg5HhN5NkqmjnHUFfeXNXdHzmekyw" + "38RnuCMKmfc43AiDs+FtJ62gpQ6PEsZF4o9S5fxcjVk3VSg00XMDtQ/0BsKBc5Gx" + "hJTq7G+/SoeM433WG19uoS0+5Lf/31wNoTnpv6npOaYpcTQ7L9LCnzwAF4H0hJPE" + "6bhmW2CMcsE/IZUB4QQ/Rwc1EQQAs5MUQlRiYOfi3fQ1OF6Z3eCwioDKu2DmOxot" + "BICvdoG2muvs0KEBas9bbd0FJqc92FZJv8yxEgQbQtQAiFxoIFHRTFK+SPO/tQm+" + "r83nwLRrfDeVVdRfzF79YCc+Abuh8sS/53H3u9Y7DYWr9IuMgI39nrVhY+d8yukf" + "jo4OR+sAoKS/f7V1Xxj/Eqhb8qzf+N+zJRUlBACDd1eo/zFJZcq2YJa7a9vkViME" + "axvwApqxeoU7oDpeHEMWg2DXJ7V24ZU5SbPTMY0x98cc8pcoqwsqux8xicWc0reh" + "U3odQxWM4Se0LmEdca0nQOmNJlL9IsQ+QOJzx47qUOUAqhxnkXxQ/6B8w+M6gZya" + "fwSdy70OumxESZipeQP+Lo9x6FcaW9L78hDX0aijJhgSEsnGODKB+bln29txX37E" + "/a/Si+pyeLMi82kUdIL3G3I5HPWd3qSO4K94062+HfFj8bA20/1tbb/WxvxB2sKJ" + "i3IobblFOvFHo+v8GaLdVyartp0JZLue/jP1dl9ctulSrIqaJT342uLsgTjsr2z+" + "AwMCAyAU8Vo5AhhgFkDto8vQk7yxyRKEzu5qB66dRcTlaUPIiR8kamcy5ZTtujs4" + "KIW4j2M/LvagrpWfV5+0M0VyaWMgRWNoaWRuYSAoRFNBIFRlc3QgS2V5KSA8ZXJp" + "Y0Bib3VuY3ljYXN0bGUub3JnPohZBBMRAgAZBQI/Rwc1BAsHAwIDFQIDAxYCAQIe" + "AQIXgAAKCRDNI/XpxMo0QwJcAJ40447eezSiIMspuzkwsMyFN8YBaQCdFTuZuT30" + "CphiUYWnsC0mQ+J15B4="); byte[] enc1 = Base64.decode( "hIwDKwfQexPJboABA/4/7prhYYMORTiQ5avQKx0XYpCLujzGefYjnyuWZnx3Iev8" + "Pmsguumm+OLLvtXhhkXQmkJRXbIg6Otj2ubPYWflRPgpJSgOrNOreOl5jeABOrtw" + "bV6TJb9OTtZuB7cTQSCq2gmYiSZkluIiDjNs3R3mEanILbYzOQ3zKSggKpzlv9JQ" + "AZUqTyDyJ6/OUbJF5fI5uiv76DCsw1zyMWotUIu5/X01q+AVP5Ly3STzI7xkWg/J" + "APz4zUHism7kSYz2viAQaJx9/bNnH3AM6qm1Fuyikl4="); byte[] enc1crc = Base64.decode("lv4o"); byte[] enc2 = Base64.decode( "hIwDKwfQexPJboABBAC62jcJH8xKnKb1neDVmiovYON04+7VQ2v4BmeHwJrdag1g" + "Ya++6PeBlQ2Q9lSGBwLobVuJmQ7cOnPUJP727JeSGWlMyFtMbBSHekOaTenT5lj7" + "Zk7oRHxMp/hByzlMacIDzOn8LPSh515RHM57eDLCOwqnAxGQwk67GRl8f5dFH9JQ" + "Aa7xx8rjCqPbiIQW6t5LqCNvPZOiSCmftll6+se1XJhFEuq8WS4nXtPfTiJ3vib4" + "3soJdHzGB6AOs+BQ6aKmmNTVAxa5owhtSt1Z/6dfSSk="); byte[] subPubKey = Base64.decode( "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"); byte[] subPubCrc = Base64.decode("rikt"); byte[] pgp8Key = Base64.decode( "lQIEBEBXUNMBBADScQczBibewnbCzCswc/9ut8R0fwlltBRxMW0NMdKJY2LF" + "7k2COeLOCIU95loJGV6ulbpDCXEO2Jyq8/qGw1qD3SCZNXxKs3GS8Iyh9Uwd" + "VL07nMMYl5NiQRsFB7wOb86+94tYWgvikVA5BRP5y3+O3GItnXnpWSJyREUy" + "6WI2QQAGKf4JAwIVmnRs4jtTX2DD05zy2mepEQ8bsqVAKIx7lEwvMVNcvg4Y" + "8vFLh9Mf/uNciwL4Se/ehfKQ/AT0JmBZduYMqRU2zhiBmxj4cXUQ0s36ysj7" + "fyDngGocDnM3cwPxaTF1ZRBQHSLewP7dqE7M73usFSz8vwD/0xNOHFRLKbsO" + "RqDlLA1Cg2Yd0wWPS0o7+qqk9ndqrjjSwMM8ftnzFGjShAdg4Ca7fFkcNePP" + "/rrwIH472FuRb7RbWzwXA4+4ZBdl8D4An0dwtfvAO+jCZSrLjmSpxEOveJxY" + "GduyR4IA4lemvAG51YHTHd4NXheuEqsIkn1yarwaaj47lFPnxNOElOREMdZb" + "nkWQb1jfgqO24imEZgrLMkK9bJfoDnlF4k6r6hZOp5FSFvc5kJB4cVo1QJl4" + "pwCSdoU6luwCggrlZhDnkGCSuQUUW45NE7Br22NGqn4/gHs0KCsWbAezApGj" + "qYUCfX1bcpPzUMzUlBaD5rz2vPeO58CDtBJ0ZXN0ZXIgPHRlc3RAdGVzdD6I" + "sgQTAQIAHAUCQFdQ0wIbAwQLBwMCAxUCAwMWAgECHgECF4AACgkQs8JyyQfH" + "97I1QgP8Cd+35maM2cbWV9iVRO+c5456KDi3oIUSNdPf1NQrCAtJqEUhmMSt" + "QbdiaFEkPrORISI/2htXruYn0aIpkCfbUheHOu0sef7s6pHmI2kOQPzR+C/j" + "8D9QvWsPOOso81KU2axUY8zIer64Uzqc4szMIlLw06c8vea27RfgjBpSCryw" + "AgAA"); char[] pgp8Pass = "2002 Buffalo Sabres".toCharArray(); char[] pass = { 'h', 'e', 'l', 'l', 'o', ' ', 'w', 'o', 'r', 'l', 'd' }; byte[] fingerprintKey = Base64.decode( "mQEPA0CiJdUAAAEIAMI+znDlPd2kQoEcnxqxLcRz56Z7ttFKHpnYp0UkljZdquVc" + "By1jMfXGVV64xN1IvMcyenLXUE0IUeUBCQs6tHunFRAPSeCxJ3FdFe1B5MpqQG8A" + "BnEpAds/hAUfRDZD5y/lolk1hjvFMrRh6WXckaA/QQ2t00NmTrJ1pYUpkw9tnVQb" + "LUjWJhfZDBBcN0ADtATzgkugxMtcDxR6I5x8Ndn+IilqIm23kxGIcmMd/BHOec4c" + "jRwJXXDb7u8tl+2knAf9cwhPHp3+Zy4uGSQPdzQnXOhBlA+4WDa0RROOevWgq8uq" + "8/9Xp/OlTVL+OoIzjsI6mJP1Joa4qmqAnaHAmXcAEQEAAbQoQk9BM1JTS1kgPEJP" + "QSBNb25pdG9yaW5nIEAgODg4LTI2OS01MjY2PokBFQMFEECiJdWqaoCdocCZdwEB" + "0RsH/3HPxoUZ3G3K7T3jgOnJUckTSHWU3XspHzMVgqOxjTrcexi5IsAM5M+BulfW" + "T2aO+Kqf5w8cKTKgW02DNpHUiPjHx0nzDE+Do95zbIErGeK+Twkc4O/aVsvU9GGO" + "81VFI6WMvDQ4CUAUnAdk03MRrzI2nAuhn4NJ5LQS+uJrnqUJ4HmFAz6CQZQKd/kS" + "Xgq+A6i7aI1LG80YxWa9ooQgaCrb9dwY/kPQ+yC22zQ3FExtv+Fv3VtAKTilO3vn" + "BA4Y9uTHuObHfI+1yxUS2PrlRUX0m48ZjpIX+cEN3QblGBJudI/A1QSd6P0LZeBr" + "7F1Z1aF7ZDo0KzgiAIBvgXkeTpw="); byte[] fingerprintCheck = Base64.decode("CTv2"); byte[] expiry60and30daysSig13Key = Base64.decode( "mQGiBENZt/URBAC5JccXiwe4g6MuviEC8NI/x0NaVkGFAOY04d5E4jeIycBP" + "SrpOPrjETuigqhrj8oqed2+2yUqfnK4nhTsTAjyeJ3PpWC1pGAKzJgYmJk+K" + "9aTLq0BQWiXDdv5RG6fDmeq1umvOfcXBqGFAguLPZC+U872bSLnfe3lqGNA8" + "jvmY7wCgjhzVQVm10NN5ST8nemPEcSjnBrED/R494gHL6+r5OgUgXnNCDejA" + "4InoDImQCF+g7epp5E1MB6CMYSg2WSY2jHFuHpwnUb7AiOO0ZZ3UBqM9rYnK" + "kDvxkFCxba7Ms+aFj9blRNmy3vG4FewDcTdxzCtjUk6dRfu6UoARpqlTE/q7" + "Xo6EQP1ncwJ+UTlcHkTBvg/usI/yBACGjBqX8glb5VfNaZgNHMeS/UIiUiuV" + "SVFojiSDOHcnCe/6y4M2gVm38zz1W9qhoLfLpiAOFeL0yj6wzXvsjjXQiKQ8" + "nBE4Mf+oeH2qiQ/LfzQrGpI5eNcMXrzK9nigmz2htYO2GjQfupEnu1RHBTH8" + "NjofD2AShL9IO73plRuExrQgVGVzdCBLZXkgPHRlc3RAYm91bmN5Y2FzdGxl" + "Lm9yZz6IZAQTEQIAJAIbAwYLCQgHAwIDFQIDAxYCAQIeAQIXgAUCQ1m4DgUJ" + "AE8aGQAKCRD8QP1QuU7Kqw+eAJ0dZ3ZAqr73X61VmCkbyPoszLQMAQCfdFs2" + "YMDeUvX34Q/8Ba0KgO5f3RSwAgADuM0EQ1m39hADAIHpVGcLqS9UkmQaWBvH" + "WP6TnN7Y1Ha0TJOuxpbFjBW+CmVh/FjcsnavFXDXpo2zc742WT+vrHBSa/0D" + "1QEBsnCaX5SRRVp7Mqs8q+aDhjcHMIP8Sdxf7GozXDORkrRaJwADBQL9HLYm" + "7Rr5iYWDcvs+Pi6O1zUyb1tjkxEGaV/rcozl2MMmr2mzJ6x/Bz8SuhZEJS0m" + "bB2CvAA39aQi9jHlV7q0SV73NOkd2L/Vt2UZhzlUdvrJ37PgYDv+Wd9Ufz6g" + "MzLSiE8EGBECAA8FAkNZt/YCGwwFCQAnjQAACgkQ/ED9ULlOyqsTqQCcDnAZ" + "7YymCfhm1yJiuFQg3qiX6Z4An19OSEgeSKugVcH49g1sxUB0zNdIsAIAAw=="); byte[] jpegImage = Base64.decode( "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"); byte[] embeddedJPEGKey = Base64.decode( "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" + "Qvmtc8X7lqK/zLRVkSSBItik2IIhsAIAAw=="); private void fingerPrintTest() throws Exception { // // version 3 // PGPPublicKeyRing pgpPub = new PGPPublicKeyRing(fingerprintKey, new BcKeyFingerprintCalculator()); PGPPublicKey pubKey = pgpPub.getPublicKey(); if (!areEqual(pubKey.getFingerprint(), Hex.decode("4FFB9F0884266C715D1CEAC804A3BBFA"))) { fail("version 3 fingerprint test failed"); } // // version 4 // pgpPub = new PGPPublicKeyRing(testPubKey, new BcKeyFingerprintCalculator()); pubKey = pgpPub.getPublicKey(); if (!areEqual(pubKey.getFingerprint(), Hex.decode("3062363c1046a01a751946bb35586146fdf3f373"))) { fail("version 4 fingerprint test failed"); } } private void mixedTest(PGPPrivateKey pgpPrivKey, PGPPublicKey pgpPubKey) throws Exception { byte[] text = { (byte)'h', (byte)'e', (byte)'l', (byte)'l', (byte)'o', (byte)' ', (byte)'w', (byte)'o', (byte)'r', (byte)'l', (byte)'d', (byte)'!', (byte)'\n' }; // // literal data // ByteArrayOutputStream bOut = new ByteArrayOutputStream(); PGPLiteralDataGenerator lGen = new PGPLiteralDataGenerator(); OutputStream lOut = lGen.open(bOut, PGPLiteralData.BINARY, PGPLiteralData.CONSOLE, text.length, new Date()); lOut.write(text); lGen.close(); byte[] bytes = bOut.toByteArray(); PGPObjectFactory f = new PGPObjectFactory(bytes); checkLiteralData((PGPLiteralData)f.nextObject(), text); ByteArrayOutputStream bcOut = new ByteArrayOutputStream(); PGPEncryptedDataGenerator encGen = new PGPEncryptedDataGenerator(new BcPGPDataEncryptorBuilder(SymmetricKeyAlgorithmTags.AES_128).setWithIntegrityPacket(true).setSecureRandom(new SecureRandom())); encGen.addMethod(new BcPublicKeyKeyEncryptionMethodGenerator(pgpPubKey)); encGen.addMethod(new BcPBEKeyEncryptionMethodGenerator("password".toCharArray())); OutputStream cOut = encGen.open(bcOut, bytes.length); cOut.write(bytes); cOut.close(); byte[] encData = bcOut.toByteArray(); // // asymmetric // PGPObjectFactory pgpF = new PGPObjectFactory(encData); PGPEncryptedDataList encList = (PGPEncryptedDataList)pgpF.nextObject(); PGPPublicKeyEncryptedData encP = (PGPPublicKeyEncryptedData)encList.get(0); InputStream clear = encP.getDataStream(new BcPublicKeyDataDecryptorFactory(pgpPrivKey)); PGPObjectFactory pgpFact = new PGPObjectFactory(clear); checkLiteralData((PGPLiteralData)pgpFact.nextObject(), text); // // PBE // pgpF = new PGPObjectFactory(encData); encList = (PGPEncryptedDataList)pgpF.nextObject(); PGPPBEEncryptedData encPbe = (PGPPBEEncryptedData)encList.get(1); clear = encPbe.getDataStream(new BcPBEDataDecryptorFactory("password".toCharArray(), new BcPGPDigestCalculatorProvider())); pgpF = new PGPObjectFactory(clear); checkLiteralData((PGPLiteralData)pgpF.nextObject(), text); } private void checkLiteralData(PGPLiteralData ld, byte[] data) throws IOException { ByteArrayOutputStream bOut = new ByteArrayOutputStream(); if (!ld.getFileName().equals(PGPLiteralData.CONSOLE)) { throw new RuntimeException("wrong filename in packet"); } InputStream inLd = ld.getDataStream(); int ch; while ((ch = inLd.read()) >= 0) { bOut.write(ch); } if (!areEqual(bOut.toByteArray(), data)) { fail("wrong plain text in decrypted packet"); } } private void existingEmbeddedJpegTest() throws Exception { PGPPublicKeyRing pgpPub = new PGPPublicKeyRing(embeddedJPEGKey, new BcKeyFingerprintCalculator()); PGPPublicKey pubKey = pgpPub.getPublicKey(); Iterator it = pubKey.getUserAttributes(); int count = 0; while (it.hasNext()) { PGPUserAttributeSubpacketVector attributes = (PGPUserAttributeSubpacketVector)it.next(); Iterator sigs = pubKey.getSignaturesForUserAttribute(attributes); int sigCount = 0; while (sigs.hasNext()) { PGPSignature sig = (PGPSignature)sigs.next(); sig.init(new BcPGPContentVerifierBuilderProvider(), pubKey); if (!sig.verifyCertification(attributes, pubKey)) { fail("signature failed verification"); } sigCount++; } if (sigCount != 1) { fail("Failed user attributes signature check"); } count++; } if (count != 1) { fail("didn't find user attributes"); } } private void embeddedJpegTest() throws Exception { PGPPublicKeyRing pgpPub = new PGPPublicKeyRing(testPubKey, new BcKeyFingerprintCalculator()); PGPSecretKeyRing pgpSec = new PGPSecretKeyRing(testPrivKey, new BcKeyFingerprintCalculator()); PGPPublicKey pubKey = pgpPub.getPublicKey(); PGPUserAttributeSubpacketVectorGenerator vGen = new PGPUserAttributeSubpacketVectorGenerator(); vGen.setImageAttribute(ImageAttribute.JPEG, jpegImage); PGPUserAttributeSubpacketVector uVec = vGen.generate(); PGPSignatureGenerator sGen = new PGPSignatureGenerator(new BcPGPContentSignerBuilder(PublicKeyAlgorithmTags.RSA_GENERAL, HashAlgorithmTags.SHA1)); sGen.init(PGPSignature.POSITIVE_CERTIFICATION, pgpSec.getSecretKey().extractPrivateKey(new BcPBESecretKeyDecryptorBuilder(new BcPGPDigestCalculatorProvider()).build(pass))); PGPSignature sig = sGen.generateCertification(uVec, pubKey); PGPPublicKey nKey = PGPPublicKey.addCertification(pubKey, uVec, sig); Iterator it = nKey.getUserAttributes(); int count = 0; while (it.hasNext()) { PGPUserAttributeSubpacketVector attributes = (PGPUserAttributeSubpacketVector)it.next(); Iterator sigs = nKey.getSignaturesForUserAttribute(attributes); int sigCount = 0; while (sigs.hasNext()) { PGPSignature s = (PGPSignature)sigs.next(); s.init(new BcPGPContentVerifierBuilderProvider(), pubKey); if (!s.verifyCertification(attributes, pubKey)) { fail("added signature failed verification"); } sigCount++; } if (sigCount != 1) { fail("Failed added user attributes signature check"); } count++; } if (count != 1) { fail("didn't find added user attributes"); } nKey = PGPPublicKey.removeCertification(nKey, uVec); count = 0; for (it = nKey.getUserAttributes(); it.hasNext();) { count++; } if (count != 0) { fail("found attributes where none expected"); } } private void sigsubpacketTest() throws Exception { char[] passPhrase = "test".toCharArray(); String identity = "TEST "; Date date = new Date(); RSAKeyPairGenerator kpg = new RSAKeyPairGenerator(); kpg.init(new RSAKeyGenerationParameters(BigInteger.valueOf(0x11), new SecureRandom(), 2048, 25)); AsymmetricCipherKeyPair kpSgn = kpg.generateKeyPair(); AsymmetricCipherKeyPair kpEnc = kpg.generateKeyPair(); PGPKeyPair sgnKeyPair = new BcPGPKeyPair(PGPPublicKey.RSA_SIGN, kpSgn, date); PGPKeyPair encKeyPair = new BcPGPKeyPair(PGPPublicKey.RSA_GENERAL, kpEnc, date); PGPSignatureSubpacketVector unhashedPcks = null; PGPSignatureSubpacketGenerator svg = new PGPSignatureSubpacketGenerator(); svg.setKeyExpirationTime(true, 86400L * 366 * 2); svg.setPrimaryUserID(true, true); int[] encAlgs = {SymmetricKeyAlgorithmTags.AES_256, SymmetricKeyAlgorithmTags.AES_192, SymmetricKeyAlgorithmTags.TRIPLE_DES}; svg.setPreferredSymmetricAlgorithms(true, encAlgs); int[] hashAlgs = {HashAlgorithmTags.SHA1, HashAlgorithmTags.SHA512, HashAlgorithmTags.SHA384, HashAlgorithmTags.SHA256, HashAlgorithmTags.RIPEMD160}; svg.setPreferredHashAlgorithms(true, hashAlgs); int[] comprAlgs = {CompressionAlgorithmTags.ZLIB, CompressionAlgorithmTags.BZIP2, CompressionAlgorithmTags.ZIP}; svg.setPreferredCompressionAlgorithms(true, comprAlgs); svg.setFeature(true, Features.FEATURE_MODIFICATION_DETECTION); svg.setKeyFlags(true, KeyFlags.CERTIFY_OTHER + KeyFlags.SIGN_DATA); PGPSignatureSubpacketVector hashedPcks = svg.generate(); PGPKeyRingGenerator keyRingGen = new PGPKeyRingGenerator(PGPSignature.POSITIVE_CERTIFICATION, sgnKeyPair, identity, new BcPGPDigestCalculatorProvider().get(HashAlgorithmTags.SHA1), hashedPcks, unhashedPcks, new BcPGPContentSignerBuilder(PGPPublicKey.RSA_GENERAL, HashAlgorithmTags.SHA1), new BcPBESecretKeyEncryptorBuilder(PGPEncryptedData.AES_256).build(passPhrase)); svg = new PGPSignatureSubpacketGenerator(); svg.setKeyExpirationTime(true, 86400L * 366 * 2); svg.setKeyFlags(true, KeyFlags.ENCRYPT_COMMS + KeyFlags.ENCRYPT_STORAGE); svg.setPrimaryUserID(true, false); svg.setFeature(true, Features.FEATURE_MODIFICATION_DETECTION); hashedPcks = svg.generate(); keyRingGen.addSubKey(encKeyPair, hashedPcks, unhashedPcks); byte[] encodedKeyRing = keyRingGen.generatePublicKeyRing().getEncoded(); PGPPublicKeyRing keyRing = new PGPPublicKeyRing(encodedKeyRing, new BcKeyFingerprintCalculator()); for (Iterator it = keyRing.getPublicKeys(); it.hasNext();) { PGPPublicKey pKey = (PGPPublicKey)it.next(); if (pKey.isEncryptionKey()) { for (Iterator sit = pKey.getSignatures(); sit.hasNext();) { PGPSignature sig = (PGPSignature)sit.next(); PGPSignatureSubpacketVector v = sig.getHashedSubPackets(); if (v.getKeyExpirationTime() != 86400L * 366 * 2) { fail("key expiration time wrong"); } if (!v.getFeatures().supportsFeature(Features.FEATURE_MODIFICATION_DETECTION)) { fail("features wrong"); } if (v.isPrimaryUserID()) { fail("primary userID flag wrong"); } if (v.getKeyFlags() != KeyFlags.ENCRYPT_COMMS + KeyFlags.ENCRYPT_STORAGE) { fail("keyFlags wrong"); } } } else { for (Iterator sit = pKey.getSignatures(); sit.hasNext();) { PGPSignature sig = (PGPSignature)sit.next(); PGPSignatureSubpacketVector v = sig.getHashedSubPackets(); if (!Arrays.areEqual(v.getPreferredSymmetricAlgorithms(), encAlgs)) { fail("preferred encryption algs don't match"); } if (!Arrays.areEqual(v.getPreferredHashAlgorithms(), hashAlgs)) { fail("preferred hash algs don't match"); } if (!Arrays.areEqual(v.getPreferredCompressionAlgorithms(), comprAlgs)) { fail("preferred compression algs don't match"); } if (!v.getFeatures().supportsFeature(Features.FEATURE_MODIFICATION_DETECTION)) { fail("features wrong"); } if (v.getKeyFlags() != KeyFlags.CERTIFY_OTHER + KeyFlags.SIGN_DATA) { fail("keyFlags wrong"); } } } } } public void performTest() throws Exception { PublicKey pubKey = null; // // Read the public key // PGPPublicKeyRing pgpPub = new PGPPublicKeyRing(testPubKey, new BcKeyFingerprintCalculator()); pubKey = pgpPub.getPublicKey().getKey("BC"); Iterator it = pgpPub.getPublicKey().getUserIDs(); String uid = (String)it.next(); it = pgpPub.getPublicKey().getSignaturesForID(uid); PGPSignature sig = (PGPSignature)it.next(); sig.init(new BcPGPContentVerifierBuilderProvider(), pgpPub.getPublicKey()); if (!sig.verifyCertification(uid, pgpPub.getPublicKey())) { fail("failed to verify certification"); } // // write a public key // ByteArrayOutputStream bOut = new ByteArrayOutputStream(); BCPGOutputStream pOut = new BCPGOutputStream(bOut); pgpPub.encode(pOut); if (!areEqual(bOut.toByteArray(), testPubKey)) { fail("public key rewrite failed"); } // // Read the public key // PGPPublicKeyRing pgpPubV3 = new PGPPublicKeyRing(testPubKeyV3, new BcKeyFingerprintCalculator()); PublicKey pubKeyV3 = pgpPub.getPublicKey().getKey("BC"); // // write a V3 public key // bOut = new ByteArrayOutputStream(); pOut = new BCPGOutputStream(bOut); pgpPubV3.encode(pOut); // // Read a v3 private key // char[] passP = "FIXCITY_QA".toCharArray(); if (!noIDEA()) { PGPSecretKeyRing pgpPriv = new PGPSecretKeyRing(testPrivKeyV3, new BcKeyFingerprintCalculator()); PGPPrivateKey pgpPrivKey = pgpPriv.getSecretKey().extractPrivateKey(new BcPBESecretKeyDecryptorBuilder(new BcPGPDigestCalculatorProvider()).build(passP)); // // write a v3 private key // bOut = new ByteArrayOutputStream(); pOut = new BCPGOutputStream(bOut); pgpPriv.encode(pOut); if (!areEqual(bOut.toByteArray(), testPrivKeyV3)) { fail("private key V3 rewrite failed"); } } // // Read the private key // PGPSecretKeyRing pgpPriv = new PGPSecretKeyRing(testPrivKey, new BcKeyFingerprintCalculator()); PGPPrivateKey pgpPrivKey = pgpPriv.getSecretKey().extractPrivateKey(new BcPBESecretKeyDecryptorBuilder(new BcPGPDigestCalculatorProvider()).build(pass)); // // write a private key // bOut = new ByteArrayOutputStream(); pOut = new BCPGOutputStream(bOut); pgpPriv.encode(pOut); if (!areEqual(bOut.toByteArray(), testPrivKey)) { fail("private key rewrite failed"); } // // test encryption // Cipher c = Cipher.getInstance("RSA", "BC"); c.init(Cipher.ENCRYPT_MODE, pubKey); byte[] in = "hello world".getBytes(); byte[] out = c.doFinal(in); c.init(Cipher.DECRYPT_MODE, pgpPrivKey.getKey()); out = c.doFinal(out); if (!areEqual(in, out)) { fail("decryption failed."); } // // test signature message // PGPObjectFactory pgpFact = new PGPObjectFactory(sig1, new BcKeyFingerprintCalculator()); PGPCompressedData c1 = (PGPCompressedData)pgpFact.nextObject(); pgpFact = new PGPObjectFactory(c1.getDataStream(), new BcKeyFingerprintCalculator()); PGPOnePassSignatureList p1 = (PGPOnePassSignatureList)pgpFact.nextObject(); PGPOnePassSignature ops = p1.get(0); PGPLiteralData p2 = (PGPLiteralData)pgpFact.nextObject(); InputStream dIn = p2.getInputStream(); int ch; ops.init(new BcPGPContentVerifierBuilderProvider(), pgpPub.getPublicKey(ops.getKeyID())); while ((ch = dIn.read()) >= 0) { ops.update((byte)ch); } PGPSignatureList p3 = (PGPSignatureList)pgpFact.nextObject(); if (!ops.verify(p3.get(0))) { fail("Failed signature check"); } // // encrypted message - read subkey // pgpPriv = new PGPSecretKeyRing(subKey, new BcKeyFingerprintCalculator()); // // encrypted message // byte[] text = { (byte)'h', (byte)'e', (byte)'l', (byte)'l', (byte)'o', (byte)' ', (byte)'w', (byte)'o', (byte)'r', (byte)'l', (byte)'d', (byte)'!', (byte)'\n' }; PGPObjectFactory pgpF = new PGPObjectFactory(enc1, new BcKeyFingerprintCalculator()); PGPEncryptedDataList encList = (PGPEncryptedDataList)pgpF.nextObject(); PGPPublicKeyEncryptedData encP = (PGPPublicKeyEncryptedData)encList.get(0); pgpPrivKey = pgpPriv.getSecretKey(encP.getKeyID()).extractPrivateKey(new BcPBESecretKeyDecryptorBuilder(new BcPGPDigestCalculatorProvider()).build(pass)); InputStream clear = encP.getDataStream(new BcPublicKeyDataDecryptorFactory(pgpPrivKey)); pgpFact = new PGPObjectFactory(clear, new BcKeyFingerprintCalculator()); c1 = (PGPCompressedData)pgpFact.nextObject(); pgpFact = new PGPObjectFactory(c1.getDataStream(), new BcKeyFingerprintCalculator()); PGPLiteralData ld = (PGPLiteralData)pgpFact.nextObject(); bOut = new ByteArrayOutputStream(); if (!ld.getFileName().equals("test.txt")) { throw new RuntimeException("wrong filename in packet"); } InputStream inLd = ld.getDataStream(); while ((ch = inLd.read()) >= 0) { bOut.write(ch); } if (!areEqual(bOut.toByteArray(), text)) { fail("wrong plain text in decrypted packet"); } // // encrypt - short message // byte[] shortText = { (byte)'h', (byte)'e', (byte)'l', (byte)'l', (byte)'o' }; ByteArrayOutputStream cbOut = new ByteArrayOutputStream(); PGPEncryptedDataGenerator cPk = new PGPEncryptedDataGenerator(new BcPGPDataEncryptorBuilder(SymmetricKeyAlgorithmTags.CAST5).setSecureRandom(new SecureRandom())); PGPPublicKey puK = pgpPriv.getSecretKey(encP.getKeyID()).getPublicKey(); cPk.addMethod(new BcPublicKeyKeyEncryptionMethodGenerator(puK)); OutputStream cOut = cPk.open(new UncloseableOutputStream(cbOut), shortText.length); cOut.write(shortText); cOut.close(); pgpF = new PGPObjectFactory(cbOut.toByteArray(), new BcKeyFingerprintCalculator()); encList = (PGPEncryptedDataList)pgpF.nextObject(); encP = (PGPPublicKeyEncryptedData)encList.get(0); pgpPrivKey = pgpPriv.getSecretKey(encP.getKeyID()).extractPrivateKey(new BcPBESecretKeyDecryptorBuilder(new BcPGPDigestCalculatorProvider()).build(pass)); PublicKeyDataDecryptorFactory dataDecryptorFactory = new BcPublicKeyDataDecryptorFactory(pgpPrivKey); if (encP.getSymmetricAlgorithm(dataDecryptorFactory) != SymmetricKeyAlgorithmTags.CAST5) { fail("symmetric algorithm mismatch"); } clear = encP.getDataStream(dataDecryptorFactory); bOut.reset(); while ((ch = clear.read()) >= 0) { bOut.write(ch); } out = bOut.toByteArray(); if (!areEqual(out, shortText)) { fail("wrong plain text in generated short text packet"); } // // encrypt // cbOut = new ByteArrayOutputStream(); cPk = new PGPEncryptedDataGenerator(new BcPGPDataEncryptorBuilder(SymmetricKeyAlgorithmTags.CAST5).setSecureRandom(new SecureRandom())); puK = pgpPriv.getSecretKey(encP.getKeyID()).getPublicKey(); cPk.addMethod(new BcPublicKeyKeyEncryptionMethodGenerator(puK)); cOut = cPk.open(new UncloseableOutputStream(cbOut), text.length); cOut.write(text); cOut.close(); pgpF = new PGPObjectFactory(cbOut.toByteArray()); encList = (PGPEncryptedDataList)pgpF.nextObject(); encP = (PGPPublicKeyEncryptedData)encList.get(0); pgpPrivKey = pgpPriv.getSecretKey(encP.getKeyID()).extractPrivateKey(new BcPBESecretKeyDecryptorBuilder(new BcPGPDigestCalculatorProvider()).build(pass)); clear = encP.getDataStream(new BcPublicKeyDataDecryptorFactory(pgpPrivKey)); bOut.reset(); while ((ch = clear.read()) >= 0) { bOut.write(ch); } out = bOut.toByteArray(); if (!areEqual(out, text)) { fail("wrong plain text in generated packet"); } // // read public key with sub key. // pgpF = new PGPObjectFactory(subPubKey, new BcKeyFingerprintCalculator()); Object o; while ((o = pgpFact.nextObject()) != null) { // System.out.println(o); } // // key pair generation - CAST5 encryption // char[] passPhrase = "hello".toCharArray(); RSAKeyPairGenerator kpg = new RSAKeyPairGenerator(); kpg.init(new RSAKeyGenerationParameters(BigInteger.valueOf(0x11), new SecureRandom(), 1024, 25)); AsymmetricCipherKeyPair kp = kpg.generateKeyPair(); PGPSecretKey secretKey = new PGPSecretKey(PGPSignature.DEFAULT_CERTIFICATION, new BcPGPKeyPair(PublicKeyAlgorithmTags.RSA_GENERAL, kp, new Date()), "fred", null, null, new BcPGPContentSignerBuilder(PublicKeyAlgorithmTags.RSA_GENERAL, HashAlgorithmTags.SHA1), new BcPBESecretKeyEncryptorBuilder(SymmetricKeyAlgorithmTags.CAST5).build(passPhrase)); PGPPublicKey key = secretKey.getPublicKey(); it = key.getUserIDs(); uid = (String)it.next(); it = key.getSignaturesForID(uid); sig = (PGPSignature)it.next(); sig.init(new BcPGPContentVerifierBuilderProvider(), key); if (!sig.verifyCertification(uid, key)) { fail("failed to verify certification"); } pgpPrivKey = secretKey.extractPrivateKey(new BcPBESecretKeyDecryptorBuilder(new BcPGPDigestCalculatorProvider()).build(passPhrase)); key = PGPPublicKey.removeCertification(key, uid, sig); if (key == null) { fail("failed certification removal"); } byte[] keyEnc = key.getEncoded(); key = PGPPublicKey.addCertification(key, uid, sig); keyEnc = key.getEncoded(); PGPSignatureGenerator sGen = new PGPSignatureGenerator(new BcPGPContentSignerBuilder(PublicKeyAlgorithmTags.RSA_GENERAL, HashAlgorithmTags.SHA1)); sGen.init(PGPSignature.KEY_REVOCATION, secretKey.extractPrivateKey(new BcPBESecretKeyDecryptorBuilder(new BcPGPDigestCalculatorProvider()).build(passPhrase))); sig = sGen.generateCertification(key); key = PGPPublicKey.addCertification(key, sig); keyEnc = key.getEncoded(); PGPPublicKeyRing tmpRing = new PGPPublicKeyRing(keyEnc, new BcKeyFingerprintCalculator()); key = tmpRing.getPublicKey(); Iterator sgIt = key.getSignaturesOfType(PGPSignature.KEY_REVOCATION); sig = (PGPSignature)sgIt.next(); sig.init(new BcPGPContentVerifierBuilderProvider(), key); if (!sig.verifyCertification(key)) { fail("failed to verify revocation certification"); } // // use of PGPKeyPair // PGPKeyPair pgpKp = new BcPGPKeyPair(PGPPublicKey.RSA_GENERAL , kp, new Date()); PGPPublicKey k1 = pgpKp.getPublicKey(); PGPPrivateKey k2 = pgpKp.getPrivateKey(); k1.getEncoded(); mixedTest(k2, k1); // // key pair generation - AES_256 encryption. // kp = kpg.generateKeyPair(); secretKey = new PGPSecretKey(PGPSignature.DEFAULT_CERTIFICATION, new BcPGPKeyPair(PublicKeyAlgorithmTags.RSA_GENERAL, kp, new Date()), "fred", null, null, new BcPGPContentSignerBuilder(PublicKeyAlgorithmTags.RSA_GENERAL, HashAlgorithmTags.SHA1), new BcPBESecretKeyEncryptorBuilder(SymmetricKeyAlgorithmTags.AES_256).build(passPhrase)); secretKey.extractPrivateKey(new BcPBESecretKeyDecryptorBuilder(new BcPGPDigestCalculatorProvider()).build(passPhrase)); secretKey.encode(new ByteArrayOutputStream()); // // secret key password changing. // String newPass = "newPass"; secretKey = PGPSecretKey.copyWithNewPassword(secretKey, new BcPBESecretKeyDecryptorBuilder(new BcPGPDigestCalculatorProvider()).build(passPhrase), new BcPBESecretKeyEncryptorBuilder(secretKey.getKeyEncryptionAlgorithm()).build(newPass.toCharArray())); secretKey.extractPrivateKey(new BcPBESecretKeyDecryptorBuilder(new BcPGPDigestCalculatorProvider()).build(newPass.toCharArray())); secretKey.encode(new ByteArrayOutputStream()); key = secretKey.getPublicKey(); key.encode(new ByteArrayOutputStream()); it = key.getUserIDs(); uid = (String)it.next(); it = key.getSignaturesForID(uid); sig = (PGPSignature)it.next(); sig.init(new BcPGPContentVerifierBuilderProvider(), key); if (!sig.verifyCertification(uid, key)) { fail("failed to verify certification"); } pgpPrivKey = secretKey.extractPrivateKey(new BcPBESecretKeyDecryptorBuilder(new BcPGPDigestCalculatorProvider()).build(newPass.toCharArray())); // // signature generation // String data = "hello world!"; bOut = new ByteArrayOutputStream(); ByteArrayInputStream testIn = new ByteArrayInputStream(data.getBytes()); sGen = new PGPSignatureGenerator(new BcPGPContentSignerBuilder(PublicKeyAlgorithmTags.RSA_GENERAL, HashAlgorithmTags.SHA1)); sGen.init(PGPSignature.BINARY_DOCUMENT, pgpPrivKey); PGPCompressedDataGenerator cGen = new PGPCompressedDataGenerator( PGPCompressedData.ZIP); BCPGOutputStream bcOut = new BCPGOutputStream( cGen.open(new UncloseableOutputStream(bOut))); sGen.generateOnePassVersion(false).encode(bcOut); PGPLiteralDataGenerator lGen = new PGPLiteralDataGenerator(); Date testDate = new Date((System.currentTimeMillis() / 1000) * 1000); OutputStream lOut = lGen.open( new UncloseableOutputStream(bcOut), PGPLiteralData.BINARY, "_CONSOLE", data.getBytes().length, testDate); while ((ch = testIn.read()) >= 0) { lOut.write(ch); sGen.update((byte)ch); } lOut.close(); sGen.generate().encode(bcOut); bcOut.close(); // // verify generated signature // pgpFact = new PGPObjectFactory(bOut.toByteArray()); c1 = (PGPCompressedData)pgpFact.nextObject(); pgpFact = new PGPObjectFactory(c1.getDataStream()); p1 = (PGPOnePassSignatureList)pgpFact.nextObject(); ops = p1.get(0); p2 = (PGPLiteralData)pgpFact.nextObject(); if (!p2.getModificationTime().equals(testDate)) { fail("Modification time not preserved: " + p2.getModificationTime() + " " + testDate); } dIn = p2.getInputStream(); ops.init(new BcPGPContentVerifierBuilderProvider(), secretKey.getPublicKey()); while ((ch = dIn.read()) >= 0) { ops.update((byte)ch); } p3 = (PGPSignatureList)pgpFact.nextObject(); if (!ops.verify(p3.get(0))) { fail("Failed generated signature check"); } // // signature generation - version 3 // bOut = new ByteArrayOutputStream(); testIn = new ByteArrayInputStream(data.getBytes()); PGPV3SignatureGenerator sGenV3 = new PGPV3SignatureGenerator(new BcPGPContentSignerBuilder(PGPPublicKey.RSA_GENERAL, PGPUtil.SHA1)); sGen.init(PGPSignature.BINARY_DOCUMENT, pgpPrivKey); cGen = new PGPCompressedDataGenerator( PGPCompressedData.ZIP); bcOut = new BCPGOutputStream(cGen.open(bOut)); sGen.generateOnePassVersion(false).encode(bcOut); lGen = new PGPLiteralDataGenerator(); lOut = lGen.open( new UncloseableOutputStream(bcOut), PGPLiteralData.BINARY, "_CONSOLE", data.getBytes().length, testDate); while ((ch = testIn.read()) >= 0) { lOut.write(ch); sGen.update((byte)ch); } lOut.close(); sGen.generate().encode(bcOut); bcOut.close(); // // verify generated signature // pgpFact = new PGPObjectFactory(bOut.toByteArray()); c1 = (PGPCompressedData)pgpFact.nextObject(); pgpFact = new PGPObjectFactory(c1.getDataStream()); p1 = (PGPOnePassSignatureList)pgpFact.nextObject(); ops = p1.get(0); p2 = (PGPLiteralData)pgpFact.nextObject(); if (!p2.getModificationTime().equals(testDate)) { fail("Modification time not preserved"); } dIn = p2.getInputStream(); ops.init(new BcPGPContentVerifierBuilderProvider(), secretKey.getPublicKey()); while ((ch = dIn.read()) >= 0) { ops.update((byte)ch); } p3 = (PGPSignatureList)pgpFact.nextObject(); if (!ops.verify(p3.get(0))) { fail("Failed v3 generated signature check"); } // // extract PGP 8 private key // pgpPriv = new PGPSecretKeyRing(pgp8Key, new BcKeyFingerprintCalculator()); secretKey = pgpPriv.getSecretKey(); pgpPrivKey = secretKey.extractPrivateKey(new BcPBESecretKeyDecryptorBuilder(new BcPGPDigestCalculatorProvider()).build(pgp8Pass)); // // expiry // testExpiry(expiry60and30daysSig13Key, 60, 30); fingerPrintTest(); existingEmbeddedJpegTest(); embeddedJpegTest(); sigsubpacketTest(); } private void testExpiry( byte[] encodedRing, int masterDays, int subKeyDays) throws Exception { PGPPublicKeyRing pubRing = new PGPPublicKeyRing(encodedRing, new BcKeyFingerprintCalculator()); PGPPublicKey k = pubRing.getPublicKey(); if (k.getValidDays() != masterDays) { fail("mismatch on master valid days."); } Iterator it = pubRing.getPublicKeys(); it.next(); k = (PGPPublicKey)it.next(); if (k.getValidDays() != subKeyDays) { fail("mismatch on subkey valid days."); } } private boolean noIDEA() { return true; } public String getName() { return "BcPGPRSATest"; } public static void main( String[] args) { Security.addProvider(new BouncyCastleProvider()); runTest(new BcPGPRSATest()); } } bouncycastle-1.49.orig/test/src/org/bouncycastle/openpgp/test/PGPNoPrivateKeyTest.java0000644000175000017500000002231212151252353030541 0ustar ebourgebourgpackage org.bouncycastle.openpgp.test; import java.security.Security; import org.bouncycastle.jce.provider.BouncyCastleProvider; import org.bouncycastle.openpgp.PGPException; import org.bouncycastle.openpgp.PGPSecretKey; import org.bouncycastle.openpgp.PGPSecretKeyRing; import org.bouncycastle.openpgp.operator.jcajce.JcaKeyFingerprintCalculator; import org.bouncycastle.openpgp.operator.jcajce.JcaPGPDigestCalculatorProviderBuilder; import org.bouncycastle.openpgp.operator.jcajce.JcePBESecretKeyDecryptorBuilder; import org.bouncycastle.openpgp.operator.jcajce.JcePBESecretKeyEncryptorBuilder; import org.bouncycastle.util.encoders.Base64; import org.bouncycastle.util.test.SimpleTest; public class PGPNoPrivateKeyTest extends SimpleTest { String pgpOldPass = "test"; String pgpNewPass = "newtest"; String BOUNCY_CASTLE_PROVIDER_NAME = "BC"; byte[] pgpPrivateEmpty = Base64.decode( "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" + "+b3JLdM="); byte[] pgpPrivateFull = Base64.decode( "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" + "6zDS8hez1Sb+MAVxLe0/SqfHGGfNEsaXdtdSx844Ij4NZJJCJifSHtamz2Y3Pbco" + "hn+O5tEyDkZyrcDW9mDfrCi6amfonp307L3NLsrlRlvvDwreNPTPUfvtKuurMb29" + "6Cgads7K9wWxmiErODlcWNi/LlN7eY/aYqinVdl04lfTmSftn9WrtbTMITT841Se" + "Bh+d08XsEpLIUSU2bcNqLlCZHQP24s3zTvV2GL1fLFtfwEntXZzrPgDQxs7ps0gN" + "NHVj0r3lEa6BvmbVV1YJGpCSbQ8HQGLrT5EptvHJ7JdTpqwSj6JweTd7g405auer" + "44tXdheboAF00w+T6bYjC9cBAf06rESUV7mOwy8vvIrpDlTsqFcOt1DF9u2FM+tS" + "SWWHAe1NvIDXkcgbJ0xG45r7XqBbGJ2hoDsIHPtWceK0HWRKsWUZn8JolIBxsiPT" + "qb6FWkyLgyKg3dmUVoifBBgBAgAJBQJRkjSeAhsMAAoJENKvoeH226TknLIEAJjM" + "pknwJpbZx0Myq+ZNhr5QKiM5fTKilZvcANAsd4K8Mz2oqpn7KTyLnkPD4XsYsunc" + "Hz68DaCpyThIzOv7DnFhJi4iKGIvv6EI1Nds8KIDn80/9YT6Ruc7PhgRl+LKKwiu" + "utz7qL8AhKDa1pvu5yLX08HZxWrzbo+7OPm9yS3T"); public void performTest() throws Exception { PGPSecretKeyRing pgpSecRing = new PGPSecretKeyRing(pgpPrivateFull, new JcaKeyFingerprintCalculator()); PGPSecretKey pgpSecKey = pgpSecRing.getSecretKey(); boolean isFullEmpty = pgpSecKey.isPrivateKeyEmpty(); pgpSecRing = new PGPSecretKeyRing(pgpPrivateEmpty, new JcaKeyFingerprintCalculator()); pgpSecKey = pgpSecRing.getSecretKey(); boolean isEmptyEmpty = pgpSecKey.isPrivateKeyEmpty(); // // Check isPrivateKeyEmpty() is public // if (isFullEmpty || !isEmptyEmpty) { fail("Empty private keys not detected correctly."); } // // Check copyWithNewPassword doesn't throw an exception for secret // keys without private keys (PGPException: unknown S2K type: 101). // try { PGPSecretKey pgpChangedKey = PGPSecretKey.copyWithNewPassword(pgpSecKey, new JcePBESecretKeyDecryptorBuilder( new JcaPGPDigestCalculatorProviderBuilder().setProvider(BOUNCY_CASTLE_PROVIDER_NAME).build()).setProvider(BOUNCY_CASTLE_PROVIDER_NAME).build(pgpOldPass.toCharArray()), new JcePBESecretKeyEncryptorBuilder(pgpSecKey.getKeyEncryptionAlgorithm()).build(pgpNewPass.toCharArray())); } catch (PGPException e) { if (!e.getMessage().equals("no private key in this SecretKey - public key present only.")) { fail("wrong exception."); } } } public String getName() { return "PGPNoPrivateKeyTest"; } public static void main( String[] args) { Security.addProvider(new BouncyCastleProvider()); runTest(new PGPNoPrivateKeyTest()); } } bouncycastle-1.49.orig/test/src/org/bouncycastle/openpgp/test/PGPDSAElGamalTest.java0000644000175000017500000005066511417250275030034 0ustar ebourgebourgpackage org.bouncycastle.openpgp.test; import java.io.ByteArrayInputStream; import java.io.ByteArrayOutputStream; import java.io.InputStream; import java.io.OutputStream; import java.math.BigInteger; import java.security.AlgorithmParameterGenerator; import java.security.AlgorithmParameters; import java.security.KeyPair; import java.security.KeyPairGenerator; import java.security.PublicKey; import java.security.SecureRandom; import java.security.Security; import java.util.Date; import java.util.Iterator; import javax.crypto.Cipher; import javax.crypto.spec.DHParameterSpec; import org.bouncycastle.bcpg.BCPGOutputStream; import org.bouncycastle.bcpg.PublicKeyAlgorithmTags; import org.bouncycastle.bcpg.SymmetricKeyAlgorithmTags; import org.bouncycastle.jce.provider.BouncyCastleProvider; import org.bouncycastle.jce.spec.ElGamalParameterSpec; import org.bouncycastle.openpgp.PGPCompressedData; import org.bouncycastle.openpgp.PGPCompressedDataGenerator; import org.bouncycastle.openpgp.PGPEncryptedDataGenerator; import org.bouncycastle.openpgp.PGPEncryptedDataList; import org.bouncycastle.openpgp.PGPException; import org.bouncycastle.openpgp.PGPKeyPair; import org.bouncycastle.openpgp.PGPLiteralData; import org.bouncycastle.openpgp.PGPLiteralDataGenerator; import org.bouncycastle.openpgp.PGPObjectFactory; import org.bouncycastle.openpgp.PGPOnePassSignature; import org.bouncycastle.openpgp.PGPOnePassSignatureList; import org.bouncycastle.openpgp.PGPPrivateKey; import org.bouncycastle.openpgp.PGPPublicKey; import org.bouncycastle.openpgp.PGPPublicKeyEncryptedData; import org.bouncycastle.openpgp.PGPPublicKeyRing; import org.bouncycastle.openpgp.PGPSecretKeyRing; import org.bouncycastle.openpgp.PGPSignature; import org.bouncycastle.openpgp.PGPSignatureGenerator; import org.bouncycastle.openpgp.PGPSignatureList; import org.bouncycastle.openpgp.PGPUtil; import org.bouncycastle.util.encoders.Base64; import org.bouncycastle.util.test.SimpleTest; import org.bouncycastle.util.test.UncloseableOutputStream; public class PGPDSAElGamalTest extends SimpleTest { byte[] testPubKeyRing = Base64.decode( "mQGiBEAR8jYRBADNifuSopd20JOQ5x30ljIaY0M6927+vo09NeNxS3KqItba" + "nz9o5e2aqdT0W1xgdHYZmdElOHTTsugZxdXTEhghyxoo3KhVcNnTABQyrrvX" + "qouvmP2fEDEw0Vpyk+90BpyY9YlgeX/dEA8OfooRLCJde/iDTl7r9FT+mts8" + "g3azjwCgx+pOLD9LPBF5E4FhUOdXISJ0f4EEAKXSOi9nZzajpdhe8W2ZL9gc" + "BpzZi6AcrRZBHOEMqd69gtUxA4eD8xycUQ42yH89imEcwLz8XdJ98uHUxGJi" + "qp6hq4oakmw8GQfiL7yQIFgaM0dOAI9Afe3m84cEYZsoAFYpB4/s9pVMpPRH" + "NsVspU0qd3NHnSZ0QXs8L8DXGO1uBACjDUj+8GsfDCIP2QF3JC+nPUNa0Y5t" + "wKPKl+T8hX/0FBD7fnNeC6c9j5Ir/Fp/QtdaDAOoBKiyNLh1JaB1NY6US5zc" + "qFks2seZPjXEiE6OIDXYra494mjNKGUobA4hqT2peKWXt/uBcuL1mjKOy8Qf" + "JxgEd0MOcGJO+1PFFZWGzLQ3RXJpYyBILiBFY2hpZG5hICh0ZXN0IGtleSBv" + "bmx5KSA8ZXJpY0Bib3VuY3ljYXN0bGUub3JnPohZBBMRAgAZBQJAEfI2BAsH" + "AwIDFQIDAxYCAQIeAQIXgAAKCRAOtk6iUOgnkDdnAKC/CfLWikSBdbngY6OK" + "5UN3+o7q1ACcDRqjT3yjBU3WmRUNlxBg3tSuljmwAgAAuQENBEAR8jgQBAC2" + "kr57iuOaV7Ga1xcU14MNbKcA0PVembRCjcVjei/3yVfT/fuCVtGHOmYLEBqH" + "bn5aaJ0P/6vMbLCHKuN61NZlts+LEctfwoya43RtcubqMc7eKw4k0JnnoYgB" + "ocLXOtloCb7jfubOsnfORvrUkK0+Ne6anRhFBYfaBmGU75cQgwADBQP/XxR2" + "qGHiwn+0YiMioRDRiIAxp6UiC/JQIri2AKSqAi0zeAMdrRsBN7kyzYVVpWwN" + "5u13gPdQ2HnJ7d4wLWAuizUdKIQxBG8VoCxkbipnwh2RR4xCXFDhJrJFQUm+" + "4nKx9JvAmZTBIlI5Wsi5qxst/9p5MgP3flXsNi1tRbTmRhqIRgQYEQIABgUC" + "QBHyOAAKCRAOtk6iUOgnkBStAJoCZBVM61B1LG2xip294MZecMtCwQCbBbsk" + "JVCXP0/Szm05GB+WN+MOCT2wAgAA"); byte[] testPrivKeyRing = Base64.decode( "lQHhBEAR8jYRBADNifuSopd20JOQ5x30ljIaY0M6927+vo09NeNxS3KqItba" + "nz9o5e2aqdT0W1xgdHYZmdElOHTTsugZxdXTEhghyxoo3KhVcNnTABQyrrvX" + "qouvmP2fEDEw0Vpyk+90BpyY9YlgeX/dEA8OfooRLCJde/iDTl7r9FT+mts8" + "g3azjwCgx+pOLD9LPBF5E4FhUOdXISJ0f4EEAKXSOi9nZzajpdhe8W2ZL9gc" + "BpzZi6AcrRZBHOEMqd69gtUxA4eD8xycUQ42yH89imEcwLz8XdJ98uHUxGJi" + "qp6hq4oakmw8GQfiL7yQIFgaM0dOAI9Afe3m84cEYZsoAFYpB4/s9pVMpPRH" + "NsVspU0qd3NHnSZ0QXs8L8DXGO1uBACjDUj+8GsfDCIP2QF3JC+nPUNa0Y5t" + "wKPKl+T8hX/0FBD7fnNeC6c9j5Ir/Fp/QtdaDAOoBKiyNLh1JaB1NY6US5zc" + "qFks2seZPjXEiE6OIDXYra494mjNKGUobA4hqT2peKWXt/uBcuL1mjKOy8Qf" + "JxgEd0MOcGJO+1PFFZWGzP4DAwLeUcsVxIC2s2Bb9ab2XD860TQ2BI2rMD/r" + "7/psx9WQ+Vz/aFAT3rXkEJ97nFeqEACgKmUCAEk9939EwLQ3RXJpYyBILiBF" + "Y2hpZG5hICh0ZXN0IGtleSBvbmx5KSA8ZXJpY0Bib3VuY3ljYXN0bGUub3Jn" + "PohZBBMRAgAZBQJAEfI2BAsHAwIDFQIDAxYCAQIeAQIXgAAKCRAOtk6iUOgn" + "kDdnAJ9Ala3OcwEV1DbK906CheYWo4zIQwCfUqUOLMp/zj6QAk02bbJAhV1r" + "sAewAgAAnQFYBEAR8jgQBAC2kr57iuOaV7Ga1xcU14MNbKcA0PVembRCjcVj" + "ei/3yVfT/fuCVtGHOmYLEBqHbn5aaJ0P/6vMbLCHKuN61NZlts+LEctfwoya" + "43RtcubqMc7eKw4k0JnnoYgBocLXOtloCb7jfubOsnfORvrUkK0+Ne6anRhF" + "BYfaBmGU75cQgwADBQP/XxR2qGHiwn+0YiMioRDRiIAxp6UiC/JQIri2AKSq" + "Ai0zeAMdrRsBN7kyzYVVpWwN5u13gPdQ2HnJ7d4wLWAuizUdKIQxBG8VoCxk" + "bipnwh2RR4xCXFDhJrJFQUm+4nKx9JvAmZTBIlI5Wsi5qxst/9p5MgP3flXs" + "Ni1tRbTmRhr+AwMC3lHLFcSAtrNg/EiWFLAnKNXH27zjwuhje8u2r+9iMTYs" + "GjbRxaxRY0GKRhttCwqe2BC0lHhzifdlEcc9yjIjuKfepG2fnnSIRgQYEQIA" + "BgUCQBHyOAAKCRAOtk6iUOgnkBStAJ9HFejVtVJ/A9LM/mDPe0ExhEXt/QCg" + "m/KM7hJ/JrfnLQl7IaZsdg1F6vCwAgAA"); byte[] encMessage = Base64.decode( "hQEOAynbo4lhNjcHEAP/dgCkMtPB6mIgjFvNiotjaoh4sAXf4vFNkSeehQ2c" + "r+IMt9CgIYodJI3FoJXxOuTcwesqTp5hRzgUBJS0adLDJwcNubFMy0M2tp5o" + "KTWpXulIiqyO6f5jI/oEDHPzFoYgBmR4x72l/YpMy8UoYGtNxNvR7LVOfqJv" + "uDY/71KMtPQEAIadOWpf1P5Td+61Zqn2VH2UV7H8eI6hGa6Lsy4sb9iZNE7f" + "c+spGJlgkiOt8TrQoq3iOK9UN9nHZLiCSIEGCzsEn3uNuorD++Qs065ij+Oy" + "36TKeuJ+38CfT7u47dEshHCPqWhBKEYrxZWHUJU/izw2Q1Yxd2XRxN+nafTL" + "X1fQ0lABQUASa18s0BkkEERIdcKQXVLEswWcGqWNv1ZghC7xO2VDBX4HrPjp" + "drjL63p2UHzJ7/4gPWGGtnqq1Xita/1mrImn7pzLThDWiT55vjw6Hw=="); byte[] signedAndEncMessage = Base64.decode( "hQEOAynbo4lhNjcHEAP+K20MVhzdX57hf/cU8TH0prP0VePr9mmeBedzqqMn" + "fp2p8Zb68zmcMlI/WiL5XMNLYRmCgEcXyWbKdP/XV9m9LDBe1CMAGrkCeGBy" + "je69IQQ5LS9vDPyEMF4iAAv/EqACjqHkizdY/a/FRx/t2ioXYdEC2jA6kS9C" + "McpsNz16DE8EAIk3uKn4bGo/+15TXkyFYzW5Cf71SfRoHNmU2zAI93zhjN+T" + "B7mGJwWXzsMkIO6FkMU5TCSrwZS3DBWCIaJ6SYoaawE/C/2j9D7bX1Jv8kum" + "4cq+eZM7z6JYs6xend+WAwittpUxbEiyC2AJb3fBSXPAbLqWd6J6xbZZ7GDK" + "r2Ca0pwBxwGhbMDyi2zpHLzw95H7Ah2wMcGU6kMLB+hzBSZ6mSTGFehqFQE3" + "2BnAj7MtnbghiefogacJ891jj8Y2ggJeKDuRz8j2iICaTOy+Y2rXnnJwfYzm" + "BMWcd2h1C5+UeBJ9CrrLniCCI8s5u8z36Rno3sfhBnXdRmWSxExXtocbg1Ht" + "dyiThf6TK3W29Yy/T6x45Ws5zOasaJdsFKM="); char[] pass = { 'h', 'e', 'l', 'l', 'o', ' ', 'w', 'o', 'r', 'l', 'd' }; public void performTest() throws Exception { try { PGPPublicKey pubKey = null; PGPUtil.setDefaultProvider("BC"); // // Read the public key // PGPObjectFactory pgpFact = new PGPObjectFactory(testPubKeyRing); PGPPublicKeyRing pgpPub = (PGPPublicKeyRing)pgpFact.nextObject(); pubKey = pgpPub.getPublicKey(); if (pubKey.getBitStrength() != 1024) { fail("failed - key strength reported incorrectly."); } // // Read the private key // PGPSecretKeyRing sKey = new PGPSecretKeyRing(testPrivKeyRing); PGPPrivateKey pgpPrivKey = sKey.getSecretKey().extractPrivateKey(pass, "BC"); // // signature generation // String data = "hello world!"; ByteArrayOutputStream bOut = new ByteArrayOutputStream(); ByteArrayInputStream testIn = new ByteArrayInputStream(data.getBytes()); PGPSignatureGenerator sGen = new PGPSignatureGenerator(PGPPublicKey.DSA, PGPUtil.SHA1, "BC"); sGen.initSign(PGPSignature.BINARY_DOCUMENT, pgpPrivKey); PGPCompressedDataGenerator cGen = new PGPCompressedDataGenerator( PGPCompressedData.ZIP); BCPGOutputStream bcOut = new BCPGOutputStream( cGen.open(new UncloseableOutputStream(bOut))); sGen.generateOnePassVersion(false).encode(bcOut); PGPLiteralDataGenerator lGen = new PGPLiteralDataGenerator(); Date testDate = new Date((System.currentTimeMillis() / 1000) * 1000); OutputStream lOut = lGen.open( new UncloseableOutputStream(bcOut), PGPLiteralData.BINARY, "_CONSOLE", data.getBytes().length, testDate); int ch; while ((ch = testIn.read()) >= 0) { lOut.write(ch); sGen.update((byte)ch); } lGen.close(); sGen.generate().encode(bcOut); cGen.close(); // // verify generated signature // pgpFact = new PGPObjectFactory(bOut.toByteArray()); PGPCompressedData c1 = (PGPCompressedData)pgpFact.nextObject(); pgpFact = new PGPObjectFactory(c1.getDataStream()); PGPOnePassSignatureList p1 = (PGPOnePassSignatureList)pgpFact.nextObject(); PGPOnePassSignature ops = p1.get(0); PGPLiteralData p2 = (PGPLiteralData)pgpFact.nextObject(); if (!p2.getModificationTime().equals(testDate)) { fail("Modification time not preserved"); } InputStream dIn = p2.getInputStream(); ops.initVerify(pubKey, "BC"); while ((ch = dIn.read()) >= 0) { ops.update((byte)ch); } PGPSignatureList p3 = (PGPSignatureList)pgpFact.nextObject(); if (!ops.verify(p3.get(0))) { fail("Failed generated signature check"); } // // test encryption // // // find a key suitable for encryption // long pgpKeyID = 0; PublicKey pKey = null; Iterator it = pgpPub.getPublicKeys(); while (it.hasNext()) { PGPPublicKey pgpKey = (PGPPublicKey)it.next(); if (pgpKey.getAlgorithm() == PGPPublicKey.ELGAMAL_ENCRYPT || pgpKey.getAlgorithm() == PGPPublicKey.ELGAMAL_GENERAL) { pKey = pgpKey.getKey("BC"); pgpKeyID = pgpKey.getKeyID(); if (pgpKey.getBitStrength() != 1024) { fail("failed - key strength reported incorrectly."); } // // verify the key // } } Cipher c = Cipher.getInstance("ElGamal/None/PKCS1Padding", "BC"); c.init(Cipher.ENCRYPT_MODE, pKey); byte[] in = "hello world".getBytes(); byte[] out = c.doFinal(in); pgpPrivKey = sKey.getSecretKey(pgpKeyID).extractPrivateKey(pass, "BC"); c.init(Cipher.DECRYPT_MODE, pgpPrivKey.getKey()); out = c.doFinal(out); if (!areEqual(in, out)) { fail("decryption failed."); } // // encrypted message // byte[] text = { (byte)'h', (byte)'e', (byte)'l', (byte)'l', (byte)'o', (byte)' ', (byte)'w', (byte)'o', (byte)'r', (byte)'l', (byte)'d', (byte)'!', (byte)'\n' }; PGPObjectFactory pgpF = new PGPObjectFactory(encMessage); PGPEncryptedDataList encList = (PGPEncryptedDataList)pgpF.nextObject(); PGPPublicKeyEncryptedData encP = (PGPPublicKeyEncryptedData)encList.get(0); InputStream clear = encP.getDataStream(pgpPrivKey, "BC"); pgpFact = new PGPObjectFactory(clear); c1 = (PGPCompressedData)pgpFact.nextObject(); pgpFact = new PGPObjectFactory(c1.getDataStream()); PGPLiteralData ld = (PGPLiteralData)pgpFact.nextObject(); bOut = new ByteArrayOutputStream(); if (!ld.getFileName().equals("test.txt")) { throw new RuntimeException("wrong filename in packet"); } InputStream inLd = ld.getDataStream(); while ((ch = inLd.read()) >= 0) { bOut.write(ch); } if (!areEqual(bOut.toByteArray(), text)) { fail("wrong plain text in decrypted packet"); } // // signed and encrypted message // pgpF = new PGPObjectFactory(signedAndEncMessage); encList = (PGPEncryptedDataList)pgpF.nextObject(); encP = (PGPPublicKeyEncryptedData)encList.get(0); clear = encP.getDataStream(pgpPrivKey, "BC"); pgpFact = new PGPObjectFactory(clear); c1 = (PGPCompressedData)pgpFact.nextObject(); pgpFact = new PGPObjectFactory(c1.getDataStream()); p1 = (PGPOnePassSignatureList)pgpFact.nextObject(); ops = p1.get(0); ld = (PGPLiteralData)pgpFact.nextObject(); bOut = new ByteArrayOutputStream(); if (!ld.getFileName().equals("test.txt")) { throw new RuntimeException("wrong filename in packet"); } inLd = ld.getDataStream(); // // note: we use the DSA public key here. // ops.initVerify(pgpPub.getPublicKey(), "BC"); while ((ch = inLd.read()) >= 0) { ops.update((byte)ch); bOut.write(ch); } p3 = (PGPSignatureList)pgpFact.nextObject(); if (!ops.verify(p3.get(0))) { fail("Failed signature check"); } if (!areEqual(bOut.toByteArray(), text)) { fail("wrong plain text in decrypted packet"); } // // encrypt // ByteArrayOutputStream cbOut = new ByteArrayOutputStream(); PGPEncryptedDataGenerator cPk = new PGPEncryptedDataGenerator(SymmetricKeyAlgorithmTags.TRIPLE_DES, new SecureRandom(), "BC"); PGPPublicKey puK = sKey.getSecretKey(pgpKeyID).getPublicKey(); cPk.addMethod(puK); OutputStream cOut = cPk.open(new UncloseableOutputStream(cbOut), bOut.toByteArray().length); cOut.write(text); cOut.close(); pgpF = new PGPObjectFactory(cbOut.toByteArray()); encList = (PGPEncryptedDataList)pgpF.nextObject(); encP = (PGPPublicKeyEncryptedData)encList.get(0); pgpPrivKey = sKey.getSecretKey(pgpKeyID).extractPrivateKey(pass, "BC"); clear = encP.getDataStream(pgpPrivKey, "BC"); bOut.reset(); while ((ch = clear.read()) >= 0) { bOut.write(ch); } out = bOut.toByteArray(); if (!areEqual(out, text)) { fail("wrong plain text in generated packet"); } // // use of PGPKeyPair // BigInteger g = new BigInteger("153d5d6172adb43045b68ae8e1de1070b6137005686d29d3d73a7749199681ee5b212c9b96bfdcfa5b20cd5e3fd2044895d609cf9b410b7a0f12ca1cb9a428cc", 16); BigInteger p = new BigInteger("9494fec095f3b85ee286542b3836fc81a5dd0a0349b4c239dd38744d488cf8e31db8bcb7d33b41abb9e5a33cca9144b1cef332c94bf0573bf047a3aca98cdf3b", 16); KeyPairGenerator kpg = KeyPairGenerator.getInstance("ElGamal", "BC"); ElGamalParameterSpec elParams = new ElGamalParameterSpec(p, g); kpg.initialize(elParams); KeyPair kp = kpg.generateKeyPair(); PGPKeyPair pgpKp = new PGPKeyPair(PGPPublicKey.ELGAMAL_GENERAL , kp.getPublic(), kp.getPrivate(), new Date()); PGPPublicKey k1 = pgpKp.getPublicKey(); PGPPrivateKey k2 = pgpKp.getPrivateKey(); // Test bug with ElGamal P size != 0 mod 8 (don't use these sizes at home!) SecureRandom random = new SecureRandom(); for (int pSize = 257; pSize < 264; ++pSize) { // Generate some parameters of the given size AlgorithmParameterGenerator a = AlgorithmParameterGenerator.getInstance("ElGamal", "BC"); a.init(pSize, new SecureRandom()); AlgorithmParameters params = a.generateParameters(); DHParameterSpec elP = (DHParameterSpec)params.getParameterSpec(DHParameterSpec.class); KeyPairGenerator keyGen = KeyPairGenerator.getInstance("ElGamal", "BC"); keyGen.initialize(elP); // Run a short encrypt/decrypt test with random key for the given parameters kp = keyGen.generateKeyPair(); PGPKeyPair elGamalKeyPair = new PGPKeyPair( PublicKeyAlgorithmTags.ELGAMAL_GENERAL, kp, new Date()); cPk = new PGPEncryptedDataGenerator(SymmetricKeyAlgorithmTags.CAST5, random, "BC"); puK = elGamalKeyPair.getPublicKey(); cPk.addMethod(puK); cbOut = new ByteArrayOutputStream(); cOut = cPk.open(cbOut, text.length); cOut.write(text); cOut.close(); pgpF = new PGPObjectFactory(cbOut.toByteArray()); encList = (PGPEncryptedDataList)pgpF.nextObject(); encP = (PGPPublicKeyEncryptedData)encList.get(0); pgpPrivKey = elGamalKeyPair.getPrivateKey(); // Note: This is where an exception would be expected if the P size causes problems clear = encP.getDataStream(pgpPrivKey, "BC"); ByteArrayOutputStream dec = new ByteArrayOutputStream(); int b; while ((b = clear.read()) >= 0) { dec.write(b); } byte[] decText = dec.toByteArray(); if (!areEqual(text, decText)) { fail("decrypted message incorrect"); } } // check sub key encoding it = pgpPub.getPublicKeys(); while (it.hasNext()) { PGPPublicKey pgpKey = (PGPPublicKey)it.next(); if (!pgpKey.isMasterKey()) { byte[] kEnc = pgpKey.getEncoded(); PGPObjectFactory objF = new PGPObjectFactory(kEnc); PGPPublicKey k = (PGPPublicKey)objF.nextObject(); pKey = k.getKey("BC"); pgpKeyID = k.getKeyID(); if (k.getBitStrength() != 1024) { fail("failed - key strength reported incorrectly."); } if (objF.nextObject() != null) { fail("failed - stream not fully parsed."); } } } } catch (PGPException e) { fail("exception: " + e.getMessage(), e.getUnderlyingException()); } } public String getName() { return "PGPDSAElGamalTest"; } public static void main( String[] args) { Security.addProvider(new BouncyCastleProvider()); runTest(new PGPDSAElGamalTest()); } } bouncycastle-1.49.orig/test/src/org/bouncycastle/openpgp/test/PGPSignatureTest.java0000644000175000017500000006641511640215110030126 0ustar ebourgebourgpackage org.bouncycastle.openpgp.test; import java.io.ByteArrayInputStream; import java.io.ByteArrayOutputStream; import java.io.IOException; import java.io.InputStream; import java.io.OutputStream; import java.security.NoSuchProviderException; import java.security.Security; import java.security.SignatureException; import java.util.Date; import org.bouncycastle.bcpg.CompressionAlgorithmTags; import org.bouncycastle.bcpg.HashAlgorithmTags; import org.bouncycastle.bcpg.PublicKeyAlgorithmTags; import org.bouncycastle.bcpg.SignatureSubpacketTags; import org.bouncycastle.bcpg.SymmetricKeyAlgorithmTags; import org.bouncycastle.bcpg.sig.KeyFlags; import org.bouncycastle.jce.provider.BouncyCastleProvider; import org.bouncycastle.openpgp.PGPException; import org.bouncycastle.openpgp.PGPLiteralData; import org.bouncycastle.openpgp.PGPLiteralDataGenerator; import org.bouncycastle.openpgp.PGPObjectFactory; import org.bouncycastle.openpgp.PGPOnePassSignature; import org.bouncycastle.openpgp.PGPOnePassSignatureList; import org.bouncycastle.openpgp.PGPPrivateKey; import org.bouncycastle.openpgp.PGPPublicKey; import org.bouncycastle.openpgp.PGPSecretKey; import org.bouncycastle.openpgp.PGPSecretKeyRing; import org.bouncycastle.openpgp.PGPSignature; import org.bouncycastle.openpgp.PGPSignatureGenerator; import org.bouncycastle.openpgp.PGPSignatureList; import org.bouncycastle.openpgp.PGPSignatureSubpacketGenerator; import org.bouncycastle.openpgp.PGPSignatureSubpacketVector; import org.bouncycastle.openpgp.PGPV3SignatureGenerator; import org.bouncycastle.util.encoders.Base64; import org.bouncycastle.util.io.Streams; import org.bouncycastle.util.test.SimpleTest; import org.bouncycastle.util.test.UncloseableOutputStream; public class PGPSignatureTest extends SimpleTest { private static final int[] NO_PREFERENCES = null; private static final int[] PREFERRED_SYMMETRIC_ALGORITHMS = new int[] { SymmetricKeyAlgorithmTags.AES_128, SymmetricKeyAlgorithmTags.TRIPLE_DES }; private static final int[] PREFERRED_HASH_ALGORITHMS = new int[] { HashAlgorithmTags.SHA1, HashAlgorithmTags.SHA256 }; private static final int[] PREFERRED_COMPRESSION_ALGORITHMS = new int[] { CompressionAlgorithmTags.ZLIB }; private static final int TEST_EXPIRATION_TIME = 10000; private static final String TEST_USER_ID = "test user id"; private static final byte[] TEST_DATA = "hello world!\nhello world!\n".getBytes(); private static final byte[] TEST_DATA_WITH_CRLF = "hello world!\r\nhello world!\r\n".getBytes(); byte[] dsaKeyRing = Base64.decode( "lQHhBD9HBzURBACzkxRCVGJg5+Ld9DU4Xpnd4LCKgMq7YOY7Gi0EgK92gbaa6+zQ" + "oQFqz1tt3QUmpz3YVkm/zLESBBtC1ACIXGggUdFMUr5I87+1Cb6vzefAtGt8N5VV" + "1F/MXv1gJz4Bu6HyxL/ncfe71jsNhav0i4yAjf2etWFj53zK6R+Ojg5H6wCgpL9/" + "tXVfGP8SqFvyrN/437MlFSUEAIN3V6j/MUllyrZglrtr2+RWIwRrG/ACmrF6hTug" + "Ol4cQxaDYNcntXbhlTlJs9MxjTH3xxzylyirCyq7HzGJxZzSt6FTeh1DFYzhJ7Qu" + "YR1xrSdA6Y0mUv0ixD5A4nPHjupQ5QCqHGeRfFD/oHzD4zqBnJp/BJ3LvQ66bERJ" + "mKl5A/4uj3HoVxpb0vvyENfRqKMmGBISycY4MoH5uWfb23FffsT9r9KL6nJ4syLz" + "aRR0gvcbcjkc9Z3epI7gr3jTrb4d8WPxsDbT/W1tv9bG/EHawomLcihtuUU68Uej" + "6/wZot1XJqu2nQlku57+M/V2X1y26VKsipolPfja4uyBOOyvbP4DAwIDIBTxWjkC" + "GGAWQO2jy9CTvLHJEoTO7moHrp1FxOVpQ8iJHyRqZzLllO26OzgohbiPYz8u9qCu" + "lZ9Xn7QzRXJpYyBFY2hpZG5hIChEU0EgVGVzdCBLZXkpIDxlcmljQGJvdW5jeWNh" + "c3RsZS5vcmc+iFkEExECABkFAj9HBzUECwcDAgMVAgMDFgIBAh4BAheAAAoJEM0j" + "9enEyjRDAlwAnjTjjt57NKIgyym7OTCwzIU3xgFpAJ0VO5m5PfQKmGJRhaewLSZD" + "4nXkHg=="); char[] dsaPass = "hello world".toCharArray(); byte[] rsaKeyRing = Base64.decode( "lQIEBEBXUNMBBADScQczBibewnbCzCswc/9ut8R0fwlltBRxMW0NMdKJY2LF" + "7k2COeLOCIU95loJGV6ulbpDCXEO2Jyq8/qGw1qD3SCZNXxKs3GS8Iyh9Uwd" + "VL07nMMYl5NiQRsFB7wOb86+94tYWgvikVA5BRP5y3+O3GItnXnpWSJyREUy" + "6WI2QQAGKf4JAwIVmnRs4jtTX2DD05zy2mepEQ8bsqVAKIx7lEwvMVNcvg4Y" + "8vFLh9Mf/uNciwL4Se/ehfKQ/AT0JmBZduYMqRU2zhiBmxj4cXUQ0s36ysj7" + "fyDngGocDnM3cwPxaTF1ZRBQHSLewP7dqE7M73usFSz8vwD/0xNOHFRLKbsO" + "RqDlLA1Cg2Yd0wWPS0o7+qqk9ndqrjjSwMM8ftnzFGjShAdg4Ca7fFkcNePP" + "/rrwIH472FuRb7RbWzwXA4+4ZBdl8D4An0dwtfvAO+jCZSrLjmSpxEOveJxY" + "GduyR4IA4lemvAG51YHTHd4NXheuEqsIkn1yarwaaj47lFPnxNOElOREMdZb" + "nkWQb1jfgqO24imEZgrLMkK9bJfoDnlF4k6r6hZOp5FSFvc5kJB4cVo1QJl4" + "pwCSdoU6luwCggrlZhDnkGCSuQUUW45NE7Br22NGqn4/gHs0KCsWbAezApGj" + "qYUCfX1bcpPzUMzUlBaD5rz2vPeO58CDtBJ0ZXN0ZXIgPHRlc3RAdGVzdD6I" + "sgQTAQIAHAUCQFdQ0wIbAwQLBwMCAxUCAwMWAgECHgECF4AACgkQs8JyyQfH" + "97I1QgP8Cd+35maM2cbWV9iVRO+c5456KDi3oIUSNdPf1NQrCAtJqEUhmMSt" + "QbdiaFEkPrORISI/2htXruYn0aIpkCfbUheHOu0sef7s6pHmI2kOQPzR+C/j" + "8D9QvWsPOOso81KU2axUY8zIer64Uzqc4szMIlLw06c8vea27RfgjBpSCryw" + "AgAA"); char[] rsaPass = "2002 Buffalo Sabres".toCharArray(); byte[] nullPacketsSubKeyBinding = Base64.decode( "iDYEGBECAAAAACp9AJ9PlJCrFpi+INwG7z61eku2Wg1HaQCgl33X5Egj+Kf7F9CXIWj2iFCvQDo="); public void performTest() throws Exception { // // RSA tests // PGPSecretKeyRing pgpPriv = new PGPSecretKeyRing(rsaKeyRing); PGPSecretKey secretKey = pgpPriv.getSecretKey(); PGPPrivateKey pgpPrivKey = secretKey.extractPrivateKey(rsaPass, "BC"); try { testSig(PublicKeyAlgorithmTags.DSA, HashAlgorithmTags.SHA1, secretKey.getPublicKey(), pgpPrivKey); fail("RSA wrong key test failed."); } catch (PGPException e) { // expected } try { testSigV3(PublicKeyAlgorithmTags.DSA, HashAlgorithmTags.SHA1, secretKey.getPublicKey(), pgpPrivKey); fail("RSA V3 wrong key test failed."); } catch (PGPException e) { // expected } // // certifications // PGPSignatureGenerator sGen = new PGPSignatureGenerator(PublicKeyAlgorithmTags.RSA_GENERAL, HashAlgorithmTags.SHA1, "BC"); sGen.initSign(PGPSignature.KEY_REVOCATION, pgpPrivKey); PGPSignature sig = sGen.generateCertification(secretKey.getPublicKey()); sig.initVerify(secretKey.getPublicKey(), "BC"); if (!sig.verifyCertification(secretKey.getPublicKey())) { fail("revocation verification failed."); } PGPSecretKeyRing pgpDSAPriv = new PGPSecretKeyRing(dsaKeyRing); PGPSecretKey secretDSAKey = pgpDSAPriv.getSecretKey(); PGPPrivateKey pgpPrivDSAKey = secretDSAKey.extractPrivateKey(dsaPass, "BC"); sGen = new PGPSignatureGenerator(PublicKeyAlgorithmTags.DSA, HashAlgorithmTags.SHA1, "BC"); sGen.initSign(PGPSignature.SUBKEY_BINDING, pgpPrivDSAKey); PGPSignatureSubpacketGenerator unhashedGen = new PGPSignatureSubpacketGenerator(); PGPSignatureSubpacketGenerator hashedGen = new PGPSignatureSubpacketGenerator(); hashedGen.setSignatureExpirationTime(false, TEST_EXPIRATION_TIME); hashedGen.setSignerUserID(true, TEST_USER_ID); hashedGen.setPreferredCompressionAlgorithms(false, PREFERRED_COMPRESSION_ALGORITHMS); hashedGen.setPreferredHashAlgorithms(false, PREFERRED_HASH_ALGORITHMS); hashedGen.setPreferredSymmetricAlgorithms(false, PREFERRED_SYMMETRIC_ALGORITHMS); sGen.setHashedSubpackets(hashedGen.generate()); sGen.setUnhashedSubpackets(unhashedGen.generate()); sig = sGen.generateCertification(secretDSAKey.getPublicKey(), secretKey.getPublicKey()); byte[] sigBytes = sig.getEncoded(); PGPObjectFactory f = new PGPObjectFactory(sigBytes); sig = ((PGPSignatureList) f.nextObject()).get(0); sig.initVerify(secretDSAKey.getPublicKey(), "BC"); if (!sig.verifyCertification(secretDSAKey.getPublicKey(), secretKey.getPublicKey())) { fail("subkey binding verification failed."); } PGPSignatureSubpacketVector hashedPcks = sig.getHashedSubPackets(); PGPSignatureSubpacketVector unhashedPcks = sig.getUnhashedSubPackets(); if (hashedPcks.size() != 6) { fail("wrong number of hashed packets found."); } if (unhashedPcks.size() != 1) { fail("wrong number of unhashed packets found."); } if (!hashedPcks.getSignerUserID().equals(TEST_USER_ID)) { fail("test userid not matching"); } if (hashedPcks.getSignatureExpirationTime() != TEST_EXPIRATION_TIME) { fail("test signature expiration time not matching"); } if (unhashedPcks.getIssuerKeyID() != secretDSAKey.getKeyID()) { fail("wrong issuer key ID found in certification"); } int[] prefAlgs = hashedPcks.getPreferredCompressionAlgorithms(); preferredAlgorithmCheck("compression", PREFERRED_COMPRESSION_ALGORITHMS, prefAlgs); prefAlgs = hashedPcks.getPreferredHashAlgorithms(); preferredAlgorithmCheck("hash", PREFERRED_HASH_ALGORITHMS, prefAlgs); prefAlgs = hashedPcks.getPreferredSymmetricAlgorithms(); preferredAlgorithmCheck("symmetric", PREFERRED_SYMMETRIC_ALGORITHMS, prefAlgs); int[] criticalHashed = hashedPcks.getCriticalTags(); if (criticalHashed.length != 1) { fail("wrong number of critical packets found."); } if (criticalHashed[0] != SignatureSubpacketTags.SIGNER_USER_ID) { fail("wrong critical packet found in tag list."); } // // no packets passed // sGen = new PGPSignatureGenerator(PublicKeyAlgorithmTags.DSA, HashAlgorithmTags.SHA1, "BC"); sGen.initSign(PGPSignature.SUBKEY_BINDING, pgpPrivDSAKey); sGen.setHashedSubpackets(null); sGen.setUnhashedSubpackets(null); sig = sGen.generateCertification(TEST_USER_ID, secretKey.getPublicKey()); sig.initVerify(secretDSAKey.getPublicKey(), "BC"); if (!sig.verifyCertification(TEST_USER_ID, secretKey.getPublicKey())) { fail("subkey binding verification failed."); } hashedPcks = sig.getHashedSubPackets(); if (hashedPcks.size() != 1) { fail("found wrong number of hashed packets"); } unhashedPcks = sig.getUnhashedSubPackets(); if (unhashedPcks.size() != 1) { fail("found wrong number of unhashed packets"); } try { sig.verifyCertification(secretKey.getPublicKey()); fail("failed to detect non-key signature."); } catch (PGPException e) { // expected } // // override hash packets // sGen = new PGPSignatureGenerator(PublicKeyAlgorithmTags.DSA, HashAlgorithmTags.SHA1, "BC"); sGen.initSign(PGPSignature.SUBKEY_BINDING, pgpPrivDSAKey); hashedGen = new PGPSignatureSubpacketGenerator(); hashedGen.setSignatureCreationTime(false, new Date(0L)); sGen.setHashedSubpackets(hashedGen.generate()); sGen.setUnhashedSubpackets(null); sig = sGen.generateCertification(TEST_USER_ID, secretKey.getPublicKey()); sig.initVerify(secretDSAKey.getPublicKey(), "BC"); if (!sig.verifyCertification(TEST_USER_ID, secretKey.getPublicKey())) { fail("subkey binding verification failed."); } hashedPcks = sig.getHashedSubPackets(); if (hashedPcks.size() != 1) { fail("found wrong number of hashed packets in override test"); } if (!hashedPcks.hasSubpacket(SignatureSubpacketTags.CREATION_TIME)) { fail("hasSubpacket test for creation time failed"); } if (!hashedPcks.getSignatureCreationTime().equals(new Date(0L))) { fail("creation of overriden date failed."); } prefAlgs = hashedPcks.getPreferredCompressionAlgorithms(); preferredAlgorithmCheck("compression", NO_PREFERENCES, prefAlgs); prefAlgs = hashedPcks.getPreferredHashAlgorithms(); preferredAlgorithmCheck("hash", NO_PREFERENCES, prefAlgs); prefAlgs = hashedPcks.getPreferredSymmetricAlgorithms(); preferredAlgorithmCheck("symmetric", NO_PREFERENCES, prefAlgs); if (hashedPcks.getKeyExpirationTime() != 0) { fail("unexpected key expiration time found"); } if (hashedPcks.getSignatureExpirationTime() != 0) { fail("unexpected signature expiration time found"); } if (hashedPcks.getSignerUserID() != null) { fail("unexpected signer user ID found"); } criticalHashed = hashedPcks.getCriticalTags(); if (criticalHashed.length != 0) { fail("critical packets found when none expected"); } unhashedPcks = sig.getUnhashedSubPackets(); if (unhashedPcks.size() != 1) { fail("found wrong number of unhashed packets in override test"); } // // general signatures // testSig(PublicKeyAlgorithmTags.RSA_GENERAL, HashAlgorithmTags.SHA256, secretKey.getPublicKey(), pgpPrivKey); testSig(PublicKeyAlgorithmTags.RSA_GENERAL, HashAlgorithmTags.SHA384, secretKey.getPublicKey(), pgpPrivKey); testSig(PublicKeyAlgorithmTags.RSA_GENERAL, HashAlgorithmTags.SHA512, secretKey.getPublicKey(), pgpPrivKey); testSigV3(PublicKeyAlgorithmTags.RSA_GENERAL, HashAlgorithmTags.SHA1, secretKey.getPublicKey(), pgpPrivKey); testTextSig(PublicKeyAlgorithmTags.RSA_GENERAL, HashAlgorithmTags.SHA1, secretKey.getPublicKey(), pgpPrivKey, TEST_DATA_WITH_CRLF, TEST_DATA_WITH_CRLF); testTextSig(PublicKeyAlgorithmTags.RSA_GENERAL, HashAlgorithmTags.SHA1, secretKey.getPublicKey(), pgpPrivKey, TEST_DATA, TEST_DATA_WITH_CRLF); testTextSigV3(PublicKeyAlgorithmTags.RSA_GENERAL, HashAlgorithmTags.SHA1, secretKey.getPublicKey(), pgpPrivKey, TEST_DATA_WITH_CRLF, TEST_DATA_WITH_CRLF); testTextSigV3(PublicKeyAlgorithmTags.RSA_GENERAL, HashAlgorithmTags.SHA1, secretKey.getPublicKey(), pgpPrivKey, TEST_DATA, TEST_DATA_WITH_CRLF); // // DSA Tests // pgpPriv = new PGPSecretKeyRing(dsaKeyRing); secretKey = pgpPriv.getSecretKey(); pgpPrivKey = secretKey.extractPrivateKey(dsaPass, "BC"); try { testSig(PublicKeyAlgorithmTags.RSA_GENERAL, HashAlgorithmTags.SHA1, secretKey.getPublicKey(), pgpPrivKey); fail("DSA wrong key test failed."); } catch (PGPException e) { // expected } try { testSigV3(PublicKeyAlgorithmTags.RSA_GENERAL, HashAlgorithmTags.SHA1, secretKey.getPublicKey(), pgpPrivKey); fail("DSA V3 wrong key test failed."); } catch (PGPException e) { // expected } testSig(PublicKeyAlgorithmTags.DSA, HashAlgorithmTags.SHA1, secretKey.getPublicKey(), pgpPrivKey); testSigV3(PublicKeyAlgorithmTags.DSA, HashAlgorithmTags.SHA1, secretKey.getPublicKey(), pgpPrivKey); testTextSig(PublicKeyAlgorithmTags.DSA, HashAlgorithmTags.SHA1, secretKey.getPublicKey(), pgpPrivKey, TEST_DATA_WITH_CRLF, TEST_DATA_WITH_CRLF); testTextSig(PublicKeyAlgorithmTags.DSA, HashAlgorithmTags.SHA1, secretKey.getPublicKey(), pgpPrivKey, TEST_DATA, TEST_DATA_WITH_CRLF); testTextSigV3(PublicKeyAlgorithmTags.DSA, HashAlgorithmTags.SHA1, secretKey.getPublicKey(), pgpPrivKey, TEST_DATA_WITH_CRLF, TEST_DATA_WITH_CRLF); testTextSigV3(PublicKeyAlgorithmTags.DSA, HashAlgorithmTags.SHA1, secretKey.getPublicKey(), pgpPrivKey, TEST_DATA, TEST_DATA_WITH_CRLF); // special cases // testMissingSubpackets(nullPacketsSubKeyBinding); testMissingSubpackets(generateV3BinarySig(pgpPrivKey, PublicKeyAlgorithmTags.DSA, HashAlgorithmTags.SHA1)); // keyflags testKeyFlagsValues(); } private void testKeyFlagsValues() { checkValue(KeyFlags.CERTIFY_OTHER, 0x01); checkValue(KeyFlags.SIGN_DATA, 0x02); checkValue(KeyFlags.ENCRYPT_COMMS, 0x04); checkValue(KeyFlags.ENCRYPT_STORAGE, 0x08); checkValue(KeyFlags.SPLIT, 0x10); checkValue(KeyFlags.AUTHENTICATION, 0x20); checkValue(KeyFlags.SHARED, 0x80); // yes this actually happens checkValue(new byte[] { 4, 0, 0, 0 }, 0x04); checkValue(new byte[] { 4, 0, 0 }, 0x04); checkValue(new byte[] { 4, 0 }, 0x04); checkValue(new byte[] { 4 }, 0x04); } private void checkValue(int flag, int value) { KeyFlags f = new KeyFlags(true, flag); if (f.getFlags() != value) { fail("flag value mismatch"); } } private void checkValue(byte[] flag, int value) { KeyFlags f = new KeyFlags(true, flag); if (f.getFlags() != value) { fail("flag value mismatch"); } } private void testMissingSubpackets(byte[] signature) throws IOException { PGPObjectFactory f = new PGPObjectFactory(signature); Object obj = f.nextObject(); while (!(obj instanceof PGPSignatureList)) { obj = f.nextObject(); if (obj instanceof PGPLiteralData) { InputStream in = ((PGPLiteralData)obj).getDataStream(); Streams.drain(in); } } PGPSignature sig = ((PGPSignatureList)obj).get(0); if (sig.getVersion() > 3) { PGPSignatureSubpacketVector v = sig.getHashedSubPackets(); if (v.getKeyExpirationTime() != 0) { fail("key expiration time not zero for missing subpackets"); } if (!sig.hasSubpackets()) { fail("hasSubpackets() returns false with packets"); } } else { if (sig.getHashedSubPackets() != null) { fail("hashed sub packets found when none expected"); } if (sig.getUnhashedSubPackets() != null) { fail("unhashed sub packets found when none expected"); } if (sig.hasSubpackets()) { fail("hasSubpackets() returns true with no packets"); } } } private void preferredAlgorithmCheck( String type, int[] expected, int[] prefAlgs) { if (expected == null) { if (prefAlgs != null) { fail("preferences for " + type + " found when none expected"); } } else { if (prefAlgs.length != expected.length) { fail("wrong number of preferred " + type + " algorithms found"); } for (int i = 0; i != expected.length; i++) { if (expected[i] != prefAlgs[i]) { fail("wrong algorithm found for " + type + ": expected " + expected[i] + " got " + prefAlgs); } } } } private void testSig( int encAlgorithm, int hashAlgorithm, PGPPublicKey pubKey, PGPPrivateKey privKey) throws Exception { ByteArrayOutputStream bOut = new ByteArrayOutputStream(); ByteArrayInputStream testIn = new ByteArrayInputStream(TEST_DATA); PGPSignatureGenerator sGen = new PGPSignatureGenerator(encAlgorithm, hashAlgorithm, "BC"); sGen.initSign(PGPSignature.BINARY_DOCUMENT, privKey); sGen.generateOnePassVersion(false).encode(bOut); PGPLiteralDataGenerator lGen = new PGPLiteralDataGenerator(); OutputStream lOut = lGen.open( new UncloseableOutputStream(bOut), PGPLiteralData.BINARY, "_CONSOLE", TEST_DATA.length * 2, new Date()); int ch; while ((ch = testIn.read()) >= 0) { lOut.write(ch); sGen.update((byte)ch); } lOut.write(TEST_DATA); sGen.update(TEST_DATA); lGen.close(); sGen.generate().encode(bOut); verifySignature(bOut.toByteArray(), hashAlgorithm, pubKey, TEST_DATA); } private void testTextSig( int encAlgorithm, int hashAlgorithm, PGPPublicKey pubKey, PGPPrivateKey privKey, byte[] data, byte[] canonicalData) throws Exception { PGPSignatureGenerator sGen = new PGPSignatureGenerator(encAlgorithm, HashAlgorithmTags.SHA1, "BC"); ByteArrayOutputStream bOut = new ByteArrayOutputStream(); ByteArrayInputStream testIn = new ByteArrayInputStream(data); Date creationTime = new Date(); sGen.initSign(PGPSignature.CANONICAL_TEXT_DOCUMENT, privKey); sGen.generateOnePassVersion(false).encode(bOut); PGPLiteralDataGenerator lGen = new PGPLiteralDataGenerator(); OutputStream lOut = lGen.open( new UncloseableOutputStream(bOut), PGPLiteralData.TEXT, "_CONSOLE", data.length * 2, creationTime); int ch; while ((ch = testIn.read()) >= 0) { lOut.write(ch); sGen.update((byte)ch); } lOut.write(data); sGen.update(data); lGen.close(); PGPSignature sig = sGen.generate(); if (sig.getCreationTime().getTime() == 0) { fail("creation time not set in v4 signature"); } sig.encode(bOut); verifySignature(bOut.toByteArray(), hashAlgorithm, pubKey, canonicalData); } private void testSigV3( int encAlgorithm, int hashAlgorithm, PGPPublicKey pubKey, PGPPrivateKey privKey) throws Exception { byte[] bytes = generateV3BinarySig(privKey, encAlgorithm, hashAlgorithm); verifySignature(bytes, hashAlgorithm, pubKey, TEST_DATA); } private byte[] generateV3BinarySig(PGPPrivateKey privKey, int encAlgorithm, int hashAlgorithm) throws Exception { ByteArrayOutputStream bOut = new ByteArrayOutputStream(); ByteArrayInputStream testIn = new ByteArrayInputStream(TEST_DATA); PGPV3SignatureGenerator sGen = new PGPV3SignatureGenerator(encAlgorithm, hashAlgorithm, "BC"); sGen.initSign(PGPSignature.BINARY_DOCUMENT, privKey); sGen.generateOnePassVersion(false).encode(bOut); PGPLiteralDataGenerator lGen = new PGPLiteralDataGenerator(); OutputStream lOut = lGen.open( new UncloseableOutputStream(bOut), PGPLiteralData.BINARY, "_CONSOLE", TEST_DATA.length * 2, new Date()); int ch; while ((ch = testIn.read()) >= 0) { lOut.write(ch); sGen.update((byte)ch); } lOut.write(TEST_DATA); sGen.update(TEST_DATA); lGen.close(); sGen.generate().encode(bOut); return bOut.toByteArray(); } private void testTextSigV3( int encAlgorithm, int hashAlgorithm, PGPPublicKey pubKey, PGPPrivateKey privKey, byte[] data, byte[] canonicalData) throws Exception { PGPV3SignatureGenerator sGen = new PGPV3SignatureGenerator(encAlgorithm, HashAlgorithmTags.SHA1, "BC"); ByteArrayOutputStream bOut = new ByteArrayOutputStream(); ByteArrayInputStream testIn = new ByteArrayInputStream(data); sGen.initSign(PGPSignature.CANONICAL_TEXT_DOCUMENT, privKey); sGen.generateOnePassVersion(false).encode(bOut); PGPLiteralDataGenerator lGen = new PGPLiteralDataGenerator(); OutputStream lOut = lGen.open( new UncloseableOutputStream(bOut), PGPLiteralData.TEXT, "_CONSOLE", data.length * 2, new Date()); int ch; while ((ch = testIn.read()) >= 0) { lOut.write(ch); sGen.update((byte)ch); } lOut.write(data); sGen.update(data); lGen.close(); PGPSignature sig = sGen.generate(); if (sig.getCreationTime().getTime() == 0) { fail("creation time not set in v3 signature"); } sig.encode(bOut); verifySignature(bOut.toByteArray(), hashAlgorithm, pubKey, canonicalData); } private void verifySignature( byte[] encodedSig, int hashAlgorithm, PGPPublicKey pubKey, byte[] original) throws IOException, PGPException, NoSuchProviderException, SignatureException { PGPObjectFactory pgpFact = new PGPObjectFactory(encodedSig); PGPOnePassSignatureList p1 = (PGPOnePassSignatureList)pgpFact.nextObject(); PGPOnePassSignature ops = p1.get(0); PGPLiteralData p2 = (PGPLiteralData)pgpFact.nextObject(); InputStream dIn = p2.getInputStream(); ops.initVerify(pubKey, "BC"); int ch; while ((ch = dIn.read()) >= 0) { ops.update((byte)ch); } PGPSignatureList p3 = (PGPSignatureList)pgpFact.nextObject(); PGPSignature sig = p3.get(0); Date creationTime = sig.getCreationTime(); Date now = new Date(); // Check creationTime is recent if (creationTime.after(now) || creationTime.before(new Date(now.getTime() - 10 * 60 * 1000))) { fail("bad creation time in signature: " + creationTime); } if (sig.getKeyID() != pubKey.getKeyID()) { fail("key id mismatch in signature"); } if (!ops.verify(sig)) { fail("Failed generated signature check - " + hashAlgorithm); } sig.initVerify(pubKey, "BC"); for (int i = 0; i != original.length; i++) { sig.update(original[i]); } sig.update(original); if (!sig.verify()) { fail("Failed generated signature check against original data"); } } public String getName() { return "PGPSignatureTest"; } public static void main( String[] args) { Security.addProvider(new BouncyCastleProvider()); runTest(new PGPSignatureTest()); } } bouncycastle-1.49.orig/test/src/org/bouncycastle/openpgp/test/PGPArmoredTest.java0000644000175000017500000001600210707053207027553 0ustar ebourgebourgpackage org.bouncycastle.openpgp.test; import java.io.ByteArrayOutputStream; import java.io.ByteArrayInputStream; import org.bouncycastle.bcpg.ArmoredOutputStream; import org.bouncycastle.bcpg.ArmoredInputStream; import org.bouncycastle.util.Arrays; import org.bouncycastle.util.Strings; import org.bouncycastle.util.encoders.Base64; import org.bouncycastle.util.encoders.Hex; import org.bouncycastle.util.test.SimpleTest; import org.bouncycastle.openpgp.PGPObjectFactory; public class PGPArmoredTest extends SimpleTest { byte[] sample = Base64.decode( "mQGiBEA83v0RBADzKVLVCnpWQxX0LCsevw/3OLs0H7MOcLBQ4wMO9sYmzGYn" + "xpVj+4e4PiCP7QBayWyy4lugL6Lnw7tESvq3A4v3fefcxaCTkJrryiKn4+Cg" + "y5rIBbrSKNtCEhVi7xjtdnDjP5kFKgHYjVOeIKn4Cz/yzPG3qz75kDknldLf" + "yHxp2wCgwW1vAE5EnZU4/UmY7l8kTNkMltMEAJP4/uY4zcRwLI9Q2raPqAOJ" + "TYLd7h+3k/BxI0gIw96niQ3KmUZDlobbWBI+VHM6H99vcttKU3BgevNf8M9G" + "x/AbtW3SS4De64wNSU3189XDG8vXf0vuyW/K6Pcrb8exJWY0E1zZQ1WXT0gZ" + "W0kH3g5ro//Tusuil9q2lVLF2ovJA/0W+57bPzi318dWeNs0tTq6Njbc/GTG" + "FUAVJ8Ss5v2u6h7gyJ1DB334ExF/UdqZGldp0ugkEXaSwBa2R7d3HBgaYcoP" + "Ck1TrovZzEY8gm7JNVy7GW6mdOZuDOHTxyADEEP2JPxh6eRcZbzhGuJuYIif" + "IIeLOTI5Dc4XKeV32a+bWrQidGVzdCAoVGVzdCBrZXkpIDx0ZXN0QHViaWNh" + "bGwuY29tPohkBBMRAgAkBQJAPN79AhsDBQkB4TOABgsJCAcDAgMVAgMDFgIB" + "Ah4BAheAAAoJEJh8Njfhe8KmGDcAoJWr8xgPr75y/Cp1kKn12oCCOb8zAJ4p" + "xSvk4K6tB2jYbdeSrmoWBZLdMLACAAC5AQ0EQDzfARAEAJeUAPvUzJJbKcc5" + "5Iyb13+Gfb8xBWE3HinQzhGr1v6A1aIZbRj47UPAD/tQxwz8VAwJySx82ggN" + "LxCk4jW9YtTL3uZqfczsJngV25GoIN10f4/j2BVqZAaX3q79a3eMiql1T0oE" + "AGmD7tO1LkTvWfm3VvA0+t8/6ZeRLEiIqAOHAAQNBACD0mVMlAUgd7REYy/1" + "mL99Zlu9XU0uKyUex99sJNrcx1aj8rIiZtWaHz6CN1XptdwpDeSYEOFZ0PSu" + "qH9ByM3OfjU/ya0//xdvhwYXupn6P1Kep85efMBA9jUv/DeBOzRWMFG6sC6y" + "k8NGG7Swea7EHKeQI40G3jgO/+xANtMyTIhPBBgRAgAPBQJAPN8BAhsMBQkB" + "4TOAAAoJEJh8Njfhe8KmG7kAn00mTPGJCWqmskmzgdzeky5fWd7rAKCNCp3u" + "ZJhfg0htdgAfIy8ppm05vLACAAA="); byte[] marker = Hex.decode("2d2d2d2d2d454e4420504750205055424c4943204b455920424c4f434b2d2d2d2d2d"); // Contains "Hello World!" as an armored message // The 'blank line' after the headers contains (legal) whitespace - see RFC2440 6.2 private static final String blankLineData = "-----BEGIN PGP MESSAGE-----\n" + "Version: BCPG v1.32\n" + "Comment: A dummy message\n" + " \t \t\n" + "SGVsbG8gV29ybGQh\n" + "=d9Xi\n" + "-----END PGP MESSAGE-----\n"; private int markerCount( byte[] data) { int ind = 0; int matches = 0; while (ind < data.length) { if (data[ind] == 0x2d) { int count = 0; while (count < marker.length) { if (data[ind + count] != marker[count]) { break; } count++; } if (count == marker.length) { matches++; } ind += count; } else { ind++; } } return matches; } private void blankLineTest() throws Exception { byte[] blankLineBytes = Strings.toByteArray(blankLineData); ByteArrayInputStream bIn = new ByteArrayInputStream(blankLineBytes); ArmoredInputStream aIn = new ArmoredInputStream(bIn, true); ByteArrayOutputStream bOut = new ByteArrayOutputStream(); int c; while ((c = aIn.read()) >= 0) { bOut.write(c); } byte[] expected = Strings.toByteArray("Hello World!"); if (!Arrays.areEqual(expected, bOut.toByteArray())) { fail("Incorrect message retrieved in blank line test."); } } public void performTest() throws Exception { // // test immediate close // ByteArrayOutputStream bOut = new ByteArrayOutputStream(); ArmoredOutputStream aOut = new ArmoredOutputStream(bOut); aOut.close(); byte[] data = bOut.toByteArray(); if (data.length != 0) { fail("No data should have been written"); } // // multiple close // bOut = new ByteArrayOutputStream(); aOut = new ArmoredOutputStream(bOut); aOut.write(sample); aOut.close(); aOut.close(); int mc = markerCount(bOut.toByteArray()); if (mc < 1) { fail("No end marker found"); } if (mc > 1) { fail("More than one end marker found"); } // // writing and reading single objects // bOut = new ByteArrayOutputStream(); aOut = new ArmoredOutputStream(bOut); aOut.write(sample); aOut.close(); ArmoredInputStream aIn = new ArmoredInputStream(new ByteArrayInputStream(bOut.toByteArray())); PGPObjectFactory fact = new PGPObjectFactory(aIn); int count = 0; while (fact.nextObject() != null) { count++; } if (count != 1) { fail("wrong number of objects found: " + count); } // // writing and reading multiple objects - in single block // bOut = new ByteArrayOutputStream(); aOut = new ArmoredOutputStream(bOut); aOut.write(sample); aOut.write(sample); aOut.close(); aIn = new ArmoredInputStream(new ByteArrayInputStream(bOut.toByteArray())); fact = new PGPObjectFactory(aIn); count = 0; while (fact.nextObject() != null) { count++; } if (count != 2) { fail("wrong number of objects found: " + count); } // // writing and reading multiple objects - in single block // bOut = new ByteArrayOutputStream(); aOut = new ArmoredOutputStream(bOut); aOut.write(sample); aOut.close(); // does not close underlying stream aOut = new ArmoredOutputStream(bOut); aOut.write(sample); aOut.close(); aIn = new ArmoredInputStream(new ByteArrayInputStream(bOut.toByteArray())); count = 0; boolean atLeastOne; do { atLeastOne = false; fact = new PGPObjectFactory(aIn); while (fact.nextObject() != null) { atLeastOne = true; count++; } } while (atLeastOne); if (count != 2) { fail("wrong number of objects found: " + count); } blankLineTest(); } public String getName() { return "PGPArmoredTest"; } public static void main( String[] args) { runTest(new PGPArmoredTest()); } } bouncycastle-1.49.orig/test/src/org/bouncycastle/openpgp/test/PGPMarkerTest.java0000644000175000017500000001026710330633061027404 0ustar ebourgebourgpackage org.bouncycastle.openpgp.test; import org.bouncycastle.openpgp.PGPEncryptedDataList; import org.bouncycastle.openpgp.PGPMarker; import org.bouncycastle.openpgp.PGPObjectFactory; import org.bouncycastle.util.encoders.Base64; import org.bouncycastle.util.test.SimpleTestResult; import org.bouncycastle.util.test.Test; import org.bouncycastle.util.test.TestResult; public class PGPMarkerTest implements Test { private byte[] message1 = Base64.decode( "qANQR1DBwU4DdrlXatQSHgoQCADWlhY3bWWaOTm4t2espRWPFQmETeinnieHce64" + "lmEIFzaryEWeSdQc8XGfDzcb7sxq7b5b9Hm6OrACcCbSp2KGEJNG5kJmo2A16UPq" + "JdK4xNelpJRh3KcJPv+N/9VJrMdj4C+DRnGNFg1hTQf3RKsX+ms2V0OBC5vGlOZY" + "zX+XZz/7hl1PXVLN23u4npZI/1xETI2VtRoM76S6oykGXxMtT3+sGU1fAVEKVS45" + "pyQHWbBqApkWrURq0xBqpVfDwOgGw09dJxt2igW9hjvNAd9tJiMGrMF5o2OLlub7" + "c7FiK+dWLLcw+nx7Hl6FQmo9E8qyW8x1Cb78HjR/JXMgH/ngB/4gba6xX+s5TJkW" + "H2Wpp5ePTw39EqHosUMrm05R+C0ha3EyyaJIvKj2WWmImKu5PWo1t37Pi6KHFNC3" + "wsYJMRKnnNtd34luMTOgLpDcdgClzfp2p6EqHMoB7Uj3etlLmbN+vpGgz9qkLBRV" + "7MpR1yE9qrZNeGgbkry6N31w5E7HoAHu5JNcwxgzbJoj2lI8uvs6Gf7fEoQOuAPE" + "W/SGlfR2BdBPiJ1yErMElc2O8LVS0wTwwifHpEsMV+1ntl1EC5d052lo+6q7zNqD" + "uYt1/2if6h9W9fe+S9mzr0ZAtxIN2ZGOFJJRnqzjDQ4siB9nnwr6YgvUVRSr/lQB" + "hDTd0bmjyWacCt0PPMJWchO6A5tzqKUpTWSYibpdks80kLQogQHsJTZd/kpS0I6f" + "gD0HYYlMssZwhg2J2TWwXDpDTgQ6mzFKbGSdOSk/deTJj2+EubzxaZcxZEocCJA8" + "bppCj4kLBnCj1LjYx7A="); private byte[] message2 = Base64.decode( "qANQR1DBwU4DZlTzKj+E4aMQCADruFAojUIlHGcnswLIekvhbVnaHnbCt6Kp" + "IL2zppmEIYJ9n1xCO1k+3Y5j9vNATbqCVWs1HD0aAL3PRI1eZ1l8GkIBCd2z" + "tcZpSI/uyI/JCzVW2stCH0gpP2V7zcjk8HaIuBz4ZsyU9m7v6LwCDPB4CTrb" + "Z5nn5Jm3eowonQsRL/3TpJtG+IjTaw29NbCBNNX8quM5LwfIsfWovqNv28r1" + "aX8FsqoTRsWEfQ7dMV/swVGqv0PgKxqErdnZVJ2yOJqjLk+lBJT6zhqPijGV" + "10pc68hdZxxLU1KZq25DAjS12xcAgagjRkOmYE/H1oEjGZlXfS4y/xQ7skHa" + "HI+b04vECACTpQPwCXhxYiNWnf4XhJPONIGyrsXVtsTNwzOShFPmeUvpipP4" + "HknakBkBuUY49xcffQogW/NlGCZnQOulDLE6fCH/krkSmI8WVP5Vhf6bM1Qm" + "92dHZFoTrrcQ9NVGaCNHHWf7KXkNfKdTkE23LdggoVrVAzO4WcdqVc6s/or7" + "jQYP9zXLeu8+GGFMxe/9FCtoIWbujGQHsdDEkCK4h+D44EVDPzbvWj39ZB4w" + "hHoab8RLHd7njcrPeoCPdYkFVCKOSuLdxxYZDbbmgpISaafrafwefkkESeGu" + "JzbNhmyS8zfOiejWzndaLYWUSE/sqISK9Pg+xKundnFPk04+AhIRyYEoUjG3" + "LgGVyM49mrM8E7QwAGU0m/VCJLoOu+N74Z1rp1wFdA5yCllFlONNM4Czhd1D" + "ZMyLFqGXiKlyVCPlUTN2uVisYQGr6iNGYSPxpKjwiAzdeeQBPOETG0vd3nTO" + "MN4BMKcG+kRJd5FU72SRfmbGwPPjd1gts9xFvtj4Tvpkam8="); public TestResult perform() { try { // // test encrypted message // PGPObjectFactory pgpFact = new PGPObjectFactory(message1); Object o; if (pgpFact.nextObject() instanceof PGPMarker) { if (pgpFact.nextObject() instanceof PGPEncryptedDataList) { return new SimpleTestResult(true, getName() + ": Okay"); } else { return new SimpleTestResult(false, getName() + ": error processing after marker."); } } pgpFact = new PGPObjectFactory(message2); if (pgpFact.nextObject() instanceof PGPMarker) { if (pgpFact.nextObject() instanceof PGPEncryptedDataList) { return new SimpleTestResult(true, getName() + ": Okay"); } else { return new SimpleTestResult(false, getName() + ": error processing after marker."); } } return new SimpleTestResult(false, getName() + ": marker not found"); } catch (Exception e) { return new SimpleTestResult(false, getName() + ": exception - " + e.toString()); } } public String getName() { return "PGPMarkerTest"; } public static void main( String[] args) { Test test = new PGPMarkerTest(); TestResult result = test.perform(); System.out.println(result.toString()); } } bouncycastle-1.49.orig/test/src/org/bouncycastle/openpgp/test/BcPGPDSATest.java0000644000175000017500000007322411732235214027046 0ustar ebourgebourgpackage org.bouncycastle.openpgp.test; import java.io.ByteArrayInputStream; import java.io.ByteArrayOutputStream; import java.io.InputStream; import java.io.OutputStream; import java.security.KeyFactory; import java.security.KeyPair; import java.security.KeyPairGenerator; import java.security.PrivateKey; import java.security.Security; import java.util.Date; import java.util.Iterator; import org.bouncycastle.bcpg.BCPGOutputStream; import org.bouncycastle.bcpg.HashAlgorithmTags; import org.bouncycastle.bcpg.PublicKeyAlgorithmTags; import org.bouncycastle.jce.provider.BouncyCastleProvider; import org.bouncycastle.openpgp.PGPCompressedData; import org.bouncycastle.openpgp.PGPCompressedDataGenerator; import org.bouncycastle.openpgp.PGPKeyPair; import org.bouncycastle.openpgp.PGPLiteralData; import org.bouncycastle.openpgp.PGPLiteralDataGenerator; import org.bouncycastle.openpgp.PGPObjectFactory; import org.bouncycastle.openpgp.PGPOnePassSignature; import org.bouncycastle.openpgp.PGPOnePassSignatureList; import org.bouncycastle.openpgp.PGPPrivateKey; import org.bouncycastle.openpgp.PGPPublicKey; import org.bouncycastle.openpgp.PGPPublicKeyRing; import org.bouncycastle.openpgp.PGPSecretKeyRing; import org.bouncycastle.openpgp.PGPSignature; import org.bouncycastle.openpgp.PGPSignatureGenerator; import org.bouncycastle.openpgp.PGPSignatureList; import org.bouncycastle.openpgp.PGPSignatureSubpacketGenerator; import org.bouncycastle.openpgp.PGPUserAttributeSubpacketVector; import org.bouncycastle.openpgp.PGPUtil; import org.bouncycastle.openpgp.operator.bc.BcKeyFingerprintCalculator; import org.bouncycastle.openpgp.operator.bc.BcPBESecretKeyDecryptorBuilder; import org.bouncycastle.openpgp.operator.bc.BcPGPContentSignerBuilder; import org.bouncycastle.openpgp.operator.bc.BcPGPContentVerifierBuilderProvider; import org.bouncycastle.openpgp.operator.bc.BcPGPDigestCalculatorProvider; import org.bouncycastle.util.encoders.Base64; import org.bouncycastle.util.test.SimpleTest; import org.bouncycastle.util.test.UncloseableOutputStream; public class BcPGPDSATest extends SimpleTest { byte[] testPubKey = Base64.decode( "mQGiBD9HBzURBACzkxRCVGJg5+Ld9DU4Xpnd4LCKgMq7YOY7Gi0EgK92gbaa6+zQ" + "oQFqz1tt3QUmpz3YVkm/zLESBBtC1ACIXGggUdFMUr5I87+1Cb6vzefAtGt8N5VV" + "1F/MXv1gJz4Bu6HyxL/ncfe71jsNhav0i4yAjf2etWFj53zK6R+Ojg5H6wCgpL9/" + "tXVfGP8SqFvyrN/437MlFSUEAIN3V6j/MUllyrZglrtr2+RWIwRrG/ACmrF6hTug" + "Ol4cQxaDYNcntXbhlTlJs9MxjTH3xxzylyirCyq7HzGJxZzSt6FTeh1DFYzhJ7Qu" + "YR1xrSdA6Y0mUv0ixD5A4nPHjupQ5QCqHGeRfFD/oHzD4zqBnJp/BJ3LvQ66bERJ" + "mKl5A/4uj3HoVxpb0vvyENfRqKMmGBISycY4MoH5uWfb23FffsT9r9KL6nJ4syLz" + "aRR0gvcbcjkc9Z3epI7gr3jTrb4d8WPxsDbT/W1tv9bG/EHawomLcihtuUU68Uej" + "6/wZot1XJqu2nQlku57+M/V2X1y26VKsipolPfja4uyBOOyvbLQzRXJpYyBFY2hp" + "ZG5hIChEU0EgVGVzdCBLZXkpIDxlcmljQGJvdW5jeWNhc3RsZS5vcmc+iFkEExEC" + "ABkFAj9HBzUECwcDAgMVAgMDFgIBAh4BAheAAAoJEM0j9enEyjRDAlwAn2rrom0s" + "MhufWK5vIRwg7gj5qsLEAJ4vnT5dPBVblofsG+pDoCVeJXGGng=="); byte[] testPrivKey = Base64.decode( "lQHhBD9HBzURBACzkxRCVGJg5+Ld9DU4Xpnd4LCKgMq7YOY7Gi0EgK92gbaa6+zQ" + "oQFqz1tt3QUmpz3YVkm/zLESBBtC1ACIXGggUdFMUr5I87+1Cb6vzefAtGt8N5VV" + "1F/MXv1gJz4Bu6HyxL/ncfe71jsNhav0i4yAjf2etWFj53zK6R+Ojg5H6wCgpL9/" + "tXVfGP8SqFvyrN/437MlFSUEAIN3V6j/MUllyrZglrtr2+RWIwRrG/ACmrF6hTug" + "Ol4cQxaDYNcntXbhlTlJs9MxjTH3xxzylyirCyq7HzGJxZzSt6FTeh1DFYzhJ7Qu" + "YR1xrSdA6Y0mUv0ixD5A4nPHjupQ5QCqHGeRfFD/oHzD4zqBnJp/BJ3LvQ66bERJ" + "mKl5A/4uj3HoVxpb0vvyENfRqKMmGBISycY4MoH5uWfb23FffsT9r9KL6nJ4syLz" + "aRR0gvcbcjkc9Z3epI7gr3jTrb4d8WPxsDbT/W1tv9bG/EHawomLcihtuUU68Uej" + "6/wZot1XJqu2nQlku57+M/V2X1y26VKsipolPfja4uyBOOyvbP4DAwIDIBTxWjkC" + "GGAWQO2jy9CTvLHJEoTO7moHrp1FxOVpQ8iJHyRqZzLllO26OzgohbiPYz8u9qCu" + "lZ9Xn7QzRXJpYyBFY2hpZG5hIChEU0EgVGVzdCBLZXkpIDxlcmljQGJvdW5jeWNh" + "c3RsZS5vcmc+iFkEExECABkFAj9HBzUECwcDAgMVAgMDFgIBAh4BAheAAAoJEM0j" + "9enEyjRDAlwAnjTjjt57NKIgyym7OTCwzIU3xgFpAJ0VO5m5PfQKmGJRhaewLSZD" + "4nXkHg=="); byte[] testPrivKey2 = Base64.decode( "lQHhBEAnoewRBADRvKgDhbV6pMzqYfUgBsLxSHzmycpuxGbjMrpyKHDOEemj" + "iQb6TyyBKUoR28/pfshFP9R5urtKIT7wjVrDuOkxYkgRhNm+xmPXW2Lw3D++" + "MQrC5VWe8ywBltz6T9msmChsaKo2hDhIiRI/mg9Q6rH9pJKtVGi4R7CgGxM2" + "STQ5fwCgub38qGS1W2O4hUsa+3gva5gaNZUEAItegda4/H4t88XdWxW3D8pv" + "RnFz26/ADdImVaQlBoumD15VmcgYoT1Djizey7X8vfV+pntudESzLbn3GHlI" + "6C09seH4e8eYP63t7KU/qbUCDomlSswd1OgQ/RxfN86q765K2t3K1i3wDSxe" + "EgSRyGKee0VNvOBFOFhuWt+patXaBADE1riNkUxg2P4lBNWwu8tEZRmsl/Ys" + "DBIzXBshoMzZCvS5PnNXMW4G3SAaC9OC9jvKSx9IEWhKjfjs3QcWzXR28mcm" + "5na0bTxeOMlaPPhBdkTCmFl0IITWlH/pFlR2ah9WYoWYhZEL2tqB82wByzxH" + "SkSeD9V5oeSCdCcqiqkEmv4DAwLeNsQ2XGJVRmA4lld+CR5vRxpT/+/2xklp" + "lxVf/nx0+thrHDpro3u/nINIIObk0gh59+zaEEe3APlHqbQVYWFhIGJiYiA8" + "Y2NjQGRkZC5lZWU+iFoEExECABoFAkAnoewFCwcDAgEDFQIDAxYCAQIeAQIX" + "gAAKCRA5nBpCS63az85BAKCbPfU8ATrFvkXhzGNGlc1BJo6DWQCgnK125xVK" + "lWLpt6ZJJ7TXcx3nkm6wAgAAnQFXBEAnoe0QBACsQxPvaeBcv2TkbgU/5Wc/" + "tO222dPE1mxFbXjGTKfb+6ge96iyD8kTRLrKCkEEeVBa8AZqMSoXUVN6tV8j" + "/zD8Bc76o5iJ6wgpg3Mmy2GxInVfsfZN6/G3Y2ukmouz+CDNvQdUw8cTguIb" + "QoV3XhQ03MLbfVmNcHsku9F4CuKNWwADBQP0DSSe8v5PXF9CSCXOIxBDcQ5x" + "RKjyYOveqoH/4lbOV0YNUbIDZq4RaUdotpADuPREFmWf0zTB6KV/WIiag8XU" + "WU9zdDvLKR483Bo6Do5pDBcN+NqfQ+ntGY9WJ7BSFnhQ3+07i1K+NsfFTRfv" + "hf9X3MP75rCf7MxAIWHTabEmUf4DAwLeNsQ2XGJVRmA8DssBUCghogG9n8T3" + "qfBeKsplGyCcF+JjPeQXkKQaoYGJ0aJz36qFP9d8DuWtT9soQcqIxVf6mTa8" + "kN1594hGBBgRAgAGBQJAJ6HtAAoJEDmcGkJLrdrPpMkAnRyjQSKugz0YJqOB" + "yGasMLQLxd2OAKCEIlhtCarlufVQNGZsuWxHVbU8crACAAA="); byte[] sig1 = Base64.decode( "owGbwMvMwCR4VvnryyOnTJwZ10gncZSkFpfolVSU2Ltz78hIzcnJVyjPL8pJUeTq" + "sGdmZQCJwpQLMq3ayTA/0Fj3xf4jbwPfK/H3zj55Z9L1n2k/GOapKJrvMZ4tLiCW" + "GtP/XeDqX4fORDUA"); byte[] sig1crc = Base64.decode("OZa/"); byte[] testPubWithUserAttr = Base64.decode( "mQGiBD2Rqv0RBADqKCkhVEtB/lEEr/9CubuHEy2oN/yU5j+2GXSdcNdVnRI/rwFy" + "fHEQIk3uU7zHSUKFrC59yDm0sODYyjEdE3BVb0xvEJ5LE/OdndcIMXT1DungZ1vB" + "zIK/3lr33W/PHixYxv9jduH3WrTehBpiKkgMZp8XloSFj2Cnw9LDyfqB7QCg/8K1" + "o2k75NkOd9ZjnA9ye7Ri3bEEAKyr61Mo7viPWBK1joWAEsxG0OBWM+iSlG7kwh31" + "8efgC/7Os6x4Y0jzs8mpcbBjeZtZjS9lRbfp7RinhF269xL0TZ3JxIdtaAV/6yDQ" + "9NXfZY9dskN++HIR/5GCEEgq/qTJZt6ti5k7aV19ZFfO6wiK3NUy08wOrVsdOkVE" + "w9IcBADaplhpcel3201uU3OCboogJtw81R5MJMZ4Y9cKL/ca2jGISn0nA7KrAw9v" + "ShheSixGO4BV9JECkLEbtg7i+W/j/De6S+x2GLNcphuTP3UmgtKbhs0ItRqzW561" + "s6gLkqi6aWmgaFLd8E1pMJcd9DSY95P13EYB9VJIUxFNUopzo7QcUmFsZiBIYXVz" + "ZXIgPGhhdXNlckBhY20ub3JnPokAWAQQEQIAGAUCPZGq/QgLAwkIBwIBCgIZAQUb" + "AwAAAAAKCRAqIBiOh4JvOKg4AJ9j14yygOqqzqiLKeaasIzqT8LCIgCggx14WuLO" + "wOUTUswTaVKMFnU7tseJAJwEEAECAAYFAj2Rqx8ACgkQ9aWTKMpUDFV+9QP/RiWT" + "5FAF5Rgb7beaApsgXsME+Pw7HEYFtqGa6VcXEpbcUXO6rjaXsgMgY90klWlWCF1T" + "HOyKITvj2FdhE+0j8NQn4vaGpiTwORW/zMf/BZ0abdSWQybp10Yjs8gXw30UheO+" + "F1E524MC+s2AeUi2hwHMiS+AVYd4WhxWHmWuBpTRypP/AAALTgEQAAEBAAAAAQAA" + "AAABAAAA/9j/4AAQSkZJRgABAQAAAQABAAD/2wBDAAoHBwgHBgoICAgLCgoLDhgQ" + "Dg0NDh0VFhEYIx8lJCIfIiEmKzcvJik0KSEiMEExNDk7Pj4+JS5ESUM8SDc9Pjv/" + "2wBDAQoLCw4NDhwQEBw7KCIoOzs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7" + "Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozv/wAARCABqAF0DASIAAhEBAxEB/8QAHwAAAQUB" + "AQEBAQEAAAAAAAAAAAECAwQFBgcICQoL/8QAtRAAAgEDAwIEAwUFBAQAAAF9AQID" + "AAQRBRIhMUEGE1FhByJxFDKBkaEII0KxwRVS0fAkM2JyggkKFhcYGRolJicoKSo0" + "NTY3ODk6Q0RFRkdISUpTVFVWV1hZWmNkZWZnaGlqc3R1dnd4eXqDhIWGh4iJipKT" + "lJWWl5iZmqKjpKWmp6ipqrKztLW2t7i5usLDxMXGx8jJytLT1NXW19jZ2uHi4+Tl" + "5ufo6erx8vP09fb3+Pn6/8QAHwEAAwEBAQEBAQEBAQAAAAAAAAECAwQFBgcICQoL" + "/8QAtREAAgECBAQDBAcFBAQAAQJ3AAECAxEEBSExBhJBUQdhcRMiMoEIFEKRobHB" + "CSMzUvAVYnLRChYkNOEl8RcYGRomJygpKjU2Nzg5OkNERUZHSElKU1RVVldYWVpj" + "ZGVmZ2hpanN0dXZ3eHl6goOEhYaHiImKkpOUlZaXmJmaoqOkpaanqKmqsrO0tba3" + "uLm6wsPExcbHyMnK0tPU1dbX2Nna4uPk5ebn6Onq8vP09fb3+Pn6/9oADAMBAAIR" + "AxEAPwD2aiiq9xcxWsRllcKqjOT06E/0oAsVm6jrmm6VGXvLuOPGflz8x+grzXxV" + "8U51u5LXRgBGowZHXknnkc9OQcV51caneXdw9xPOXlckl2AJHY4J6cD1oA9J1z4p" + "TRkrYQhRyQ0hIY5/2QRx7k9ulczN8SvEEshdZkX0UorDrznI759a5Mksckkknqec" + "mkoA7WD4oavEoEttbTepYEZ+mCMVv6H8SLTULhbe/gFozAYkD5Unp3Ax/kV5XRQB" + "9EAhgCDkHkEcgilryTwd4zn0m4WzvpTJZSMBuY5MfbueletKyugZWDKwyCOc/j3o" + "AduyWLDeWB5Ynj8jSUUUAdFXn/xU15dO0RbGGYC5uWwUB6L1Jx+n413F1cJa2stz" + "J92JC5+gGa+bdfvp9S1q4urmRneQg5Yk4HGAPYZoAzySxySSSep5yaSvQvAPhOHU" + "rB7u5iLGUlIwQRx7HPr/AJ9LGsfC+dJGngc+X12gc8nvx1/rQB5rRXS3Xg28t9ye" + "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" + "qkEsPXn6/pXo/ilVzbttG7DDOOeornqAONbRpI4v3pKOQcAqQD+Y/P6j052NK0p5" + "HWHy3IBPyqrfN6gZz+P4/hpXoGzOOiP/ACNdH4XRftsp2jIBxx70AX9E0pdMtvMm" + "VRNt5xyEGOgPf3NeDeLdVOs+J768zlGkKx+yjgfy/WvoPXeNEvMcfujXzJQAUUUU" + "Af/ZiQBGBBARAgAGBQI9katEAAoJECogGI6Hgm84xz8AoNGz1fJrVPxqkBrUDmWA" + "GsP6qVGYAJ0ZOftw/GfQHzdGR8pOK85DLUPEErQkUmFsZiBIYXVzZXIgPGhhdXNl" + "ckBwcml2YXNwaGVyZS5jb20+iQBGBBARAgAGBQI9katmAAoJECogGI6Hgm84m0oA" + "oJS3CTrgpqRZfhgPtHGtUVjRCJbbAJ9stJgPcbqA2xXEg9yl2TQToWdWxbQkUmFs" + "ZiBIYXVzZXIgPGhhdXNlckBwcml2YXNwaGVyZS5vcmc+iQBGBBARAgAGBQI9kauJ" + "AAoJECogGI6Hgm84GfAAnRswktLMzDfIjv6ni76Qp5B850byAJ90I0LEHOLhda7r" + "kqTwZ8rguNssUrQkUmFsZiBIYXVzZXIgPGhhdXNlckBwcml2YXNwaGVyZS5uZXQ+" + "iQBGBBARAgAGBQI9kaubAAoJECogGI6Hgm84zi0An16C4s/B9Z0/AtfoN4ealMh3" + "i3/7AJ9Jg4GOUqGCGRRKUA9Gs5pk8yM8GbQmUmFsZiBDLiBIYXVzZXIgPHJhbGZo" + "YXVzZXJAYmx1ZXdpbi5jaD6JAEYEEBECAAYFAj2Rq8oACgkQKiAYjoeCbzhPOACg" + "iiTohKuIa66FNiI24mQ+XR9nTisAoLmh3lJf16/06qLPsRd9shTkLfmHtB9SYWxm" + "IEhhdXNlciA8cmFsZmhhdXNlckBnbXguY2g+iQBGBBARAgAGBQI9kavvAAoJECog" + "GI6Hgm84ZE8An0RlgL8mPBa/P08S5e/lD35MlDdgAJ99pjCeY46S9+nVyx7ACyKO" + "SZ4OcLQmUmFsZiBIYXVzZXIgPGhhdXNlci5yYWxmQG15c3VucmlzZS5jaD6JAEYE" + "EBECAAYFAj2RrEEACgkQKiAYjoeCbzjz0wCg+q801XrXk+Rf+koSI50MW5OaaKYA" + "oKOVA8SLxE29qSR/bJeuW0ryzRLqtCVSYWxmIEhhdXNlciA8aGF1c2VyLnJhbGZA" + "ZnJlZXN1cmYuY2g+iQBGBBARAgAGBQI9kaxXAAoJECogGI6Hgm848zoAnRBtWH6e" + "fTb3is63s8J2zTfpsyS0AKDxTjl+ZZV0COHLrSCaNLZVcpImFrkEDQQ9kar+EBAA" + "+RigfloGYXpDkJXcBWyHhuxh7M1FHw7Y4KN5xsncegus5D/jRpS2MEpT13wCFkiA" + "tRXlKZmpnwd00//jocWWIE6YZbjYDe4QXau2FxxR2FDKIldDKb6V6FYrOHhcC9v4" + "TE3V46pGzPvOF+gqnRRh44SpT9GDhKh5tu+Pp0NGCMbMHXdXJDhK4sTw6I4TZ5dO" + "khNh9tvrJQ4X/faY98h8ebByHTh1+/bBc8SDESYrQ2DD4+jWCv2hKCYLrqmus2UP" + "ogBTAaB81qujEh76DyrOH3SET8rzF/OkQOnX0ne2Qi0CNsEmy2henXyYCQqNfi3t" + "5F159dSST5sYjvwqp0t8MvZCV7cIfwgXcqK61qlC8wXo+VMROU+28W65Szgg2gGn" + "VqMU6Y9AVfPQB8bLQ6mUrfdMZIZJ+AyDvWXpF9Sh01D49Vlf3HZSTz09jdvOmeFX" + "klnN/biudE/F/Ha8g8VHMGHOfMlm/xX5u/2RXscBqtNbno2gpXI61Brwv0YAWCvl" + "9Ij9WE5J280gtJ3kkQc2azNsOA1FHQ98iLMcfFstjvbzySPAQ/ClWxiNjrtVjLhd" + "ONM0/XwXV0OjHRhs3jMhLLUq/zzhsSlAGBGNfISnCnLWhsQDGcgHKXrKlQzZlp+r" + "0ApQmwJG0wg9ZqRdQZ+cfL2JSyIZJrqrol7DVes91hcAAgIQAKD9MGkS8SUD2irI" + "AiwVHU0WXLBnk2CvvueSmT9YtC34UKkIkDPZ7VoeuXDfqTOlbiE6T16zPvArZfbl" + "JGdrU7HhsTdu+ADxRt1dPur0G0ICJ3pBD3ydGWpdLI/94x1BvTY4rsR5mS4YWmpf" + "e2kWc7ZqezhP7Xt9q7m4EK456ddeUZWtkwGU+PKyRAZ+CK82Uhouw+4aW0NjiqmX" + "hfH9/BUhI1P/8R9VkTfAFGPmZzqoHr4AuO5tLRLD2RFSmQCP8nZTiP9nP+wBBvn7" + "vuqKRQsj9PwwPD4V5SM+kpW+rUIWr9TZYl3UqSnlXlpEZFd2Bfl6NloeH0cfU69E" + "gtjcWGvGxYKPS0cg5yhVb4okka6RqIPQiYl6eJgv4tRTKoPRX29o0aUVdqVvDr5u" + "tnFzcINq7jTo8GiO8Ia3cIFWfo0LyQBd1cf1U+eEOz+DleEFqyljaz9VCbDPE4GP" + "o+ALESBlOwn5daUSaah9iU8aVPaSjn45hoQqxOKPwJxnCKKQ01iy0Gir+CDU8JJB" + "7bmbvQN4bke30EGAeED3oi+3VaBHrhjYLv7SHIxP5jtCJKWMJuLRV709HsWJi3kn" + "fGHwH+yCDF8+PDeROAzpXBaD2EFhKgeUTjP5Rgn6ltRf8TQnfbW4qlwyiXMhPOfC" + "x6qNmwaFPKQJpIkVq5VGfRXAERfkiQBMBBgRAgAMBQI9kar+BRsMAAAAAAoJECog" + "GI6Hgm84CDMAoNrNeP4c8XqFJnsLLPcjk5YGLaVIAKCrL5KFuLQVIp7d0Fkscx3/" + "7DGrzw=="); byte[] aesSecretKey = Base64.decode( "lQHpBEBSdIYRBADpd7MeIxRk4RsvyMnJNIYe4FiVv6i7I7+LPRvnIjDct0bN" + "1gCV48QFej7g/PsvXRjYSowV3VIvchWX8OERd/5i10cLbcs7X52EP1vwYaLj" + "uRfNUBg8Q51RQsKR+/rBmnVsi68rjU4yTH6wpo6FOO4pz4wFV+tWwGOwOitA" + "K31L4wCgqh59eFFBrOlRFAbDvaL7emoCIR8EAOLxDKiLQJYQrKZfXdZnifeo" + "dhEP0uuV4O5TG6nrqkhWffzC9cSoFD0BhMl979d8IB2Uft4FNvQc2u8hbJL5" + "7OCGDCUAidlB9jSdu0/J+kfRaTGhYDjBgw7AA42576BBSMNouJg/aOOQENEN" + "Nn4n7NxR3viBzIsL/OIeU8HSkBgaA/41PsvcgZ3kwpdltJ/FVRWhmMmv/q/X" + "qp1YOnF8xPU9bv2ofELrxJfRsbS4GW1etzD+nXs/woW4Vfixs01x+cutR4iF" + "3hw+eU+yLToMPmmo8D2LUvX1SRODJpx5yBBeRIYv6nz9H3sQRDx3kaLASxDV" + "jTxKmrLYnZz5w5qyVpvRyv4JAwKyWlhdblPudWBFXNkW5ydKn0AV2f51wEtj" + "Zy0aLIeutVMSJf1ytLqjFqrnFe6pdJrHO3G00TE8OuFhftWosLGLbEGytDtF" + "cmljIEguIEVjaGlkbmEgKHRlc3Qga2V5IC0gQUVTMjU2KSA8ZXJpY0Bib3Vu" + "Y3ljYXN0bGUub3JnPohZBBMRAgAZBQJAUnSGBAsHAwIDFQIDAxYCAQIeAQIX" + "gAAKCRBYt1NnUiCgeFKaAKCiqtOO+NQES1gJW6XuOGmSkXt8bQCfcuW7SXZH" + "zxK1FfdcG2HEDs3YEVawAgAA"); byte[] aesPublicKey = Base64.decode( "mQGiBEBSdIYRBADpd7MeIxRk4RsvyMnJNIYe4FiVv6i7I7+LPRvnIjDct0bN" + "1gCV48QFej7g/PsvXRjYSowV3VIvchWX8OERd/5i10cLbcs7X52EP1vwYaLj" + "uRfNUBg8Q51RQsKR+/rBmnVsi68rjU4yTH6wpo6FOO4pz4wFV+tWwGOwOitA" + "K31L4wCgqh59eFFBrOlRFAbDvaL7emoCIR8EAOLxDKiLQJYQrKZfXdZnifeo" + "dhEP0uuV4O5TG6nrqkhWffzC9cSoFD0BhMl979d8IB2Uft4FNvQc2u8hbJL5" + "7OCGDCUAidlB9jSdu0/J+kfRaTGhYDjBgw7AA42576BBSMNouJg/aOOQENEN" + "Nn4n7NxR3viBzIsL/OIeU8HSkBgaA/41PsvcgZ3kwpdltJ/FVRWhmMmv/q/X" + "qp1YOnF8xPU9bv2ofELrxJfRsbS4GW1etzD+nXs/woW4Vfixs01x+cutR4iF" + "3hw+eU+yLToMPmmo8D2LUvX1SRODJpx5yBBeRIYv6nz9H3sQRDx3kaLASxDV" + "jTxKmrLYnZz5w5qyVpvRyrQ7RXJpYyBILiBFY2hpZG5hICh0ZXN0IGtleSAt" + "IEFFUzI1NikgPGVyaWNAYm91bmN5Y2FzdGxlLm9yZz6IWQQTEQIAGQUCQFJ0" + "hgQLBwMCAxUCAwMWAgECHgECF4AACgkQWLdTZ1IgoHhSmgCfU83BLBF2nCua" + "zk2dXB9zO1l6XS8AnA07U4cq5W0GrKM6/kP9HWtPhgOFsAIAAA=="); byte[] twofishSecretKey = Base64.decode( "lQHpBEBSdtIRBACf7WfrqTl8F051+EbaljPf/8/ajFpAfMq/7p3Hri8OCsuc" + "fJJIufEEOV1/Lt/wkN67MmSyrU0fUCsRbEckRiB4EJ0zGHVFfAnku2lzdgc8" + "AVounqcHOmqA/gliFDEnhYOx3bOIAOav+yiOqfKVBhWRCpFdOTE+w/XoDM+p" + "p8bH5wCgmP2FuWpzfSut7GVKp51xNEBRNuED/3t2Q+Mq834FVynmLKEmeXB/" + "qtIz5reHEQR8eMogsOoJS3bXs6v3Oblj4in1gLyTVfcID5tku6kLP20xMRM2" + "zx2oRbz7TyOCrs15IpRXyqqJxUWD8ipgJPkPXE7hK8dh4YSTUi4i5a1ug8xG" + "314twlPzrchpWZiutDvZ+ks1rzOtBACHrEFG2frUu+qVkL43tySE0cV2bnuK" + "LVhXbpzF3Qdkfxou2nuzsCbl6m87OWocJX8uYcQGlHLKv8Q2cfxZyieLFg6v" + "06LSFdE9drGBWz7mbrT4OJjxPyvnkffPfLOOqae3PMYIIuscvswuhm4X5aoj" + "KJs01YT3L6f0iIj03hCeV/4KAwLcGrxT3X0qR2CZyZYSVBdjXeNYKXuGBtOf" + "ood26WOtwLw4+l9sHVoiXNv0LomkO58ndJRPGCeZWZEDMVrfkS7rcOlktDxF" + "cmljIEguIEVjaGlkbmEgKHRlc3Qga2V5IC0gdHdvZmlzaCkgPGVyaWNAYm91" + "bmN5Y2FzdGxlLm9yZz6IWQQTEQIAGQUCQFJ20gQLBwMCAxUCAwMWAgECHgEC" + "F4AACgkQaCCMaHh9zR2+RQCghcQwlt4B4YmNxp2b3v6rP3E8M0kAn2Gspi4u" + "A/ynoqnC1O8HNlbjPdlVsAIAAA=="); byte[] twofishPublicKey = Base64.decode( "mQGiBEBSdtIRBACf7WfrqTl8F051+EbaljPf/8/ajFpAfMq/7p3Hri8OCsuc" + "fJJIufEEOV1/Lt/wkN67MmSyrU0fUCsRbEckRiB4EJ0zGHVFfAnku2lzdgc8" + "AVounqcHOmqA/gliFDEnhYOx3bOIAOav+yiOqfKVBhWRCpFdOTE+w/XoDM+p" + "p8bH5wCgmP2FuWpzfSut7GVKp51xNEBRNuED/3t2Q+Mq834FVynmLKEmeXB/" + "qtIz5reHEQR8eMogsOoJS3bXs6v3Oblj4in1gLyTVfcID5tku6kLP20xMRM2" + "zx2oRbz7TyOCrs15IpRXyqqJxUWD8ipgJPkPXE7hK8dh4YSTUi4i5a1ug8xG" + "314twlPzrchpWZiutDvZ+ks1rzOtBACHrEFG2frUu+qVkL43tySE0cV2bnuK" + "LVhXbpzF3Qdkfxou2nuzsCbl6m87OWocJX8uYcQGlHLKv8Q2cfxZyieLFg6v" + "06LSFdE9drGBWz7mbrT4OJjxPyvnkffPfLOOqae3PMYIIuscvswuhm4X5aoj" + "KJs01YT3L6f0iIj03hCeV7Q8RXJpYyBILiBFY2hpZG5hICh0ZXN0IGtleSAt" + "IHR3b2Zpc2gpIDxlcmljQGJvdW5jeWNhc3RsZS5vcmc+iFkEExECABkFAkBS" + "dtIECwcDAgMVAgMDFgIBAh4BAheAAAoJEGggjGh4fc0dvkUAn2QGdNk8Wrrd" + "+DvKECrO5+yoPRx3AJ91DhCMme6uMrQorKSDYxHlgc7iT7ACAAA="); char[] pass = { 'h', 'e', 'l', 'l', 'o', ' ', 'w', 'o', 'r', 'l', 'd' }; /** * Generated signature test * * @param sKey * @param pgpPrivKey */ public void generateTest( PGPSecretKeyRing sKey, PGPPublicKey pgpPubKey, PGPPrivateKey pgpPrivKey) throws Exception { String data = "hello world!"; ByteArrayOutputStream bOut = new ByteArrayOutputStream(); ByteArrayInputStream testIn = new ByteArrayInputStream(data.getBytes()); PGPSignatureGenerator sGen = new PGPSignatureGenerator(new BcPGPContentSignerBuilder(PublicKeyAlgorithmTags.DSA, HashAlgorithmTags.SHA1)); sGen.init(PGPSignature.BINARY_DOCUMENT, pgpPrivKey); PGPSignatureSubpacketGenerator spGen = new PGPSignatureSubpacketGenerator(); Iterator it = sKey.getSecretKey().getPublicKey().getUserIDs(); String primaryUserID = (String)it.next(); spGen.setSignerUserID(true, primaryUserID); sGen.setHashedSubpackets(spGen.generate()); PGPCompressedDataGenerator cGen = new PGPCompressedDataGenerator( PGPCompressedData.ZIP); BCPGOutputStream bcOut = new BCPGOutputStream( cGen.open(new UncloseableOutputStream(bOut))); sGen.generateOnePassVersion(false).encode(bcOut); PGPLiteralDataGenerator lGen = new PGPLiteralDataGenerator(); Date testDate = new Date((System.currentTimeMillis() / 1000) * 1000); OutputStream lOut = lGen.open( new UncloseableOutputStream(bcOut), PGPLiteralData.BINARY, "_CONSOLE", data.getBytes().length, testDate); int ch; while ((ch = testIn.read()) >= 0) { lOut.write(ch); sGen.update((byte)ch); } lGen.close(); sGen.generate().encode(bcOut); cGen.close(); PGPObjectFactory pgpFact = new PGPObjectFactory(bOut.toByteArray()); PGPCompressedData c1 = (PGPCompressedData)pgpFact.nextObject(); pgpFact = new PGPObjectFactory(c1.getDataStream()); PGPOnePassSignatureList p1 = (PGPOnePassSignatureList)pgpFact.nextObject(); PGPOnePassSignature ops = p1.get(0); PGPLiteralData p2 = (PGPLiteralData)pgpFact.nextObject(); if (!p2.getModificationTime().equals(testDate)) { fail("Modification time not preserved"); } InputStream dIn = p2.getInputStream(); ops.init(new BcPGPContentVerifierBuilderProvider(), pgpPubKey); while ((ch = dIn.read()) >= 0) { ops.update((byte)ch); } PGPSignatureList p3 = (PGPSignatureList)pgpFact.nextObject(); if (!ops.verify(p3.get(0))) { fail("Failed generated signature check"); } } public void performTest() throws Exception { String file = null; KeyFactory fact = KeyFactory.getInstance("DSA", "BC"); PGPPublicKey pubKey = null; PrivateKey privKey = null; PGPUtil.setDefaultProvider("BC"); // // Read the public key // PGPPublicKeyRing pgpPub = new PGPPublicKeyRing(testPubKey, new BcKeyFingerprintCalculator()); pubKey = pgpPub.getPublicKey(); // // Read the private key // PGPSecretKeyRing sKey = new PGPSecretKeyRing(testPrivKey, new BcKeyFingerprintCalculator()); PGPPrivateKey pgpPrivKey = sKey.getSecretKey().extractPrivateKey(new BcPBESecretKeyDecryptorBuilder(new BcPGPDigestCalculatorProvider()).build(pass)); // // test signature message // PGPObjectFactory pgpFact = new PGPObjectFactory(sig1); PGPCompressedData c1 = (PGPCompressedData)pgpFact.nextObject(); pgpFact = new PGPObjectFactory(c1.getDataStream()); PGPOnePassSignatureList p1 = (PGPOnePassSignatureList)pgpFact.nextObject(); PGPOnePassSignature ops = p1.get(0); PGPLiteralData p2 = (PGPLiteralData)pgpFact.nextObject(); InputStream dIn = p2.getInputStream(); int ch; ops.init(new BcPGPContentVerifierBuilderProvider(), pubKey); while ((ch = dIn.read()) >= 0) { ops.update((byte)ch); } PGPSignatureList p3 = (PGPSignatureList)pgpFact.nextObject(); if (!ops.verify(p3.get(0))) { fail("Failed signature check"); } // // signature generation // generateTest(sKey, pubKey, pgpPrivKey); // // signature generation - canonical text // String data = "hello world!"; ByteArrayOutputStream bOut = new ByteArrayOutputStream(); ByteArrayInputStream testIn = new ByteArrayInputStream(data.getBytes()); PGPSignatureGenerator sGen = new PGPSignatureGenerator(new BcPGPContentSignerBuilder(PGPPublicKey.DSA, PGPUtil.SHA1)); sGen.init(PGPSignature.CANONICAL_TEXT_DOCUMENT, pgpPrivKey); PGPCompressedDataGenerator cGen = new PGPCompressedDataGenerator( PGPCompressedData.ZIP); BCPGOutputStream bcOut = new BCPGOutputStream( cGen.open(new UncloseableOutputStream(bOut))); sGen.generateOnePassVersion(false).encode(bcOut); PGPLiteralDataGenerator lGen = new PGPLiteralDataGenerator(); Date testDate = new Date((System.currentTimeMillis() / 1000) * 1000); OutputStream lOut = lGen.open( new UncloseableOutputStream(bcOut), PGPLiteralData.TEXT, "_CONSOLE", data.getBytes().length, testDate); while ((ch = testIn.read()) >= 0) { lOut.write(ch); sGen.update((byte)ch); } lGen.close(); sGen.generate().encode(bcOut); cGen.close(); // // verify generated signature - canconical text // pgpFact = new PGPObjectFactory(bOut.toByteArray()); c1 = (PGPCompressedData)pgpFact.nextObject(); pgpFact = new PGPObjectFactory(c1.getDataStream()); p1 = (PGPOnePassSignatureList)pgpFact.nextObject(); ops = p1.get(0); p2 = (PGPLiteralData)pgpFact.nextObject(); if (!p2.getModificationTime().equals(testDate)) { fail("Modification time not preserved"); } dIn = p2.getInputStream(); ops.init(new BcPGPContentVerifierBuilderProvider(), pubKey); while ((ch = dIn.read()) >= 0) { ops.update((byte)ch); } p3 = (PGPSignatureList)pgpFact.nextObject(); if (!ops.verify(p3.get(0))) { fail("Failed generated signature check"); } // // Read the public key with user attributes // pgpPub = new PGPPublicKeyRing(testPubWithUserAttr, new BcKeyFingerprintCalculator()); pubKey = pgpPub.getPublicKey(); Iterator it = pubKey.getUserAttributes(); int count = 0; while (it.hasNext()) { PGPUserAttributeSubpacketVector attributes = (PGPUserAttributeSubpacketVector)it.next(); Iterator sigs = pubKey.getSignaturesForUserAttribute(attributes); int sigCount = 0; while (sigs.hasNext()) { sigs.next(); sigCount++; } if (sigCount != 1) { fail("Failed user attributes signature check"); } count++; } if (count != 1) { fail("Failed user attributes check"); } byte[] pgpPubBytes = pgpPub.getEncoded(); pgpPub = new PGPPublicKeyRing(pgpPubBytes, new BcKeyFingerprintCalculator()); pubKey = pgpPub.getPublicKey(); it = pubKey.getUserAttributes(); count = 0; while (it.hasNext()) { it.next(); count++; } if (count != 1) { fail("Failed user attributes reread"); } // // reading test extra data - key with edge condition for DSA key password. // char [] passPhrase = { '0', '1', '2', '3', '4', '5', '6', '7', '8', '9' }; sKey = new PGPSecretKeyRing(testPrivKey2, new BcKeyFingerprintCalculator()); pgpPrivKey = sKey.getSecretKey().extractPrivateKey(passPhrase, "BC"); byte[] bytes = pgpPrivKey.getKey().getEncoded(); // // reading test - aes256 encrypted passphrase. // sKey = new PGPSecretKeyRing(aesSecretKey, new BcKeyFingerprintCalculator()); pgpPrivKey = sKey.getSecretKey().extractPrivateKey(new BcPBESecretKeyDecryptorBuilder(new BcPGPDigestCalculatorProvider()).build(pass)); bytes = pgpPrivKey.getKey().getEncoded(); // // reading test - twofish encrypted passphrase. // sKey = new PGPSecretKeyRing(twofishSecretKey, new BcKeyFingerprintCalculator()); pgpPrivKey = sKey.getSecretKey().extractPrivateKey(new BcPBESecretKeyDecryptorBuilder(new BcPGPDigestCalculatorProvider()).build(pass)); bytes = pgpPrivKey.getKey().getEncoded(); // // use of PGPKeyPair // KeyPairGenerator kpg = KeyPairGenerator.getInstance("DSA", "BC"); kpg.initialize(512); KeyPair kp = kpg.generateKeyPair(); PGPKeyPair pgpKp = new PGPKeyPair(PGPPublicKey.DSA , kp.getPublic(), kp.getPrivate(), new Date()); PGPPublicKey k1 = pgpKp.getPublicKey(); PGPPrivateKey k2 = pgpKp.getPrivateKey(); } public String getName() { return "BcPGPDSATest"; } public static void main( String[] args) { Security.addProvider(new BouncyCastleProvider()); runTest(new BcPGPDSATest()); } } bouncycastle-1.49.orig/test/src/org/bouncycastle/openpgp/test/PGPCompressionTest.java0000644000175000017500000000742310527510470030472 0ustar ebourgebourgpackage org.bouncycastle.openpgp.test; import org.bouncycastle.jce.provider.BouncyCastleProvider; import org.bouncycastle.openpgp.PGPCompressedData; import org.bouncycastle.openpgp.PGPCompressedDataGenerator; import org.bouncycastle.openpgp.PGPException; import org.bouncycastle.openpgp.PGPObjectFactory; import org.bouncycastle.util.test.SimpleTest; import org.bouncycastle.util.test.UncloseableOutputStream; import java.io.ByteArrayOutputStream; import java.io.IOException; import java.io.InputStream; import java.io.OutputStream; import java.security.Security; public class PGPCompressionTest extends SimpleTest { public void performTest() throws Exception { testCompression(PGPCompressedData.UNCOMPRESSED); testCompression(PGPCompressedData.ZIP); testCompression(PGPCompressedData.ZLIB); testCompression(PGPCompressedData.BZIP2); // // new style - using stream close // ByteArrayOutputStream bOut = new ByteArrayOutputStream(); PGPCompressedDataGenerator cPacket = new PGPCompressedDataGenerator( PGPCompressedData.ZIP); OutputStream out = cPacket.open(new UncloseableOutputStream(bOut), new byte[4]); out.write("hello world! !dlrow olleh".getBytes()); out.close(); validateData(bOut.toByteArray()); try { out.close(); cPacket.close(); } catch (Exception e) { fail("Redundant close() should be ignored"); } // // new style - using generator close // bOut = new ByteArrayOutputStream(); cPacket = new PGPCompressedDataGenerator( PGPCompressedData.ZIP); out = cPacket.open(new UncloseableOutputStream(bOut), new byte[4]); out.write("hello world! !dlrow olleh".getBytes()); cPacket.close(); validateData(bOut.toByteArray()); try { out.close(); cPacket.close(); } catch (Exception e) { fail("Redundant close() should be ignored"); } } private void validateData(byte[] data) throws IOException, PGPException { PGPObjectFactory pgpFact = new PGPObjectFactory(data); PGPCompressedData c1 = (PGPCompressedData)pgpFact.nextObject(); InputStream pIn = c1.getDataStream(); ByteArrayOutputStream bOut = new ByteArrayOutputStream(); int ch; while ((ch = pIn.read()) >= 0) { bOut.write(ch); } if (!areEqual(bOut.toByteArray(), "hello world! !dlrow olleh".getBytes())) { fail("compression test failed"); } } private void testCompression( int type) throws IOException, PGPException { ByteArrayOutputStream bOut = new ByteArrayOutputStream(); PGPCompressedDataGenerator cPacket = new PGPCompressedDataGenerator(type); OutputStream out = cPacket.open(new UncloseableOutputStream(bOut)); out.write("hello world!".getBytes()); out.close(); PGPObjectFactory pgpFact = new PGPObjectFactory(bOut.toByteArray()); PGPCompressedData c1 = (PGPCompressedData)pgpFact.nextObject(); InputStream pIn = c1.getDataStream(); bOut.reset(); int ch; while ((ch = pIn.read()) >= 0) { bOut.write(ch); } if (!areEqual(bOut.toByteArray(), "hello world!".getBytes())) { fail("compression test failed"); } } public String getName() { return "PGPCompressionTest"; } public static void main( String[] args) { Security.addProvider(new BouncyCastleProvider()); runTest(new PGPCompressionTest()); } } bouncycastle-1.49.orig/test/src/org/bouncycastle/openpgp/test/PGPDSATest.java0000644000175000017500000007131511222021300026557 0ustar ebourgebourgpackage org.bouncycastle.openpgp.test; import org.bouncycastle.bcpg.BCPGOutputStream; import org.bouncycastle.bcpg.HashAlgorithmTags; import org.bouncycastle.bcpg.PublicKeyAlgorithmTags; import org.bouncycastle.jce.provider.BouncyCastleProvider; import org.bouncycastle.openpgp.PGPCompressedData; import org.bouncycastle.openpgp.PGPCompressedDataGenerator; import org.bouncycastle.openpgp.PGPKeyPair; import org.bouncycastle.openpgp.PGPLiteralData; import org.bouncycastle.openpgp.PGPLiteralDataGenerator; import org.bouncycastle.openpgp.PGPObjectFactory; import org.bouncycastle.openpgp.PGPOnePassSignature; import org.bouncycastle.openpgp.PGPOnePassSignatureList; import org.bouncycastle.openpgp.PGPPrivateKey; import org.bouncycastle.openpgp.PGPPublicKey; import org.bouncycastle.openpgp.PGPPublicKeyRing; import org.bouncycastle.openpgp.PGPSecretKeyRing; import org.bouncycastle.openpgp.PGPSignature; import org.bouncycastle.openpgp.PGPSignatureGenerator; import org.bouncycastle.openpgp.PGPSignatureList; import org.bouncycastle.openpgp.PGPSignatureSubpacketGenerator; import org.bouncycastle.openpgp.PGPUserAttributeSubpacketVector; import org.bouncycastle.openpgp.PGPUtil; import org.bouncycastle.util.encoders.Base64; import org.bouncycastle.util.test.SimpleTest; import org.bouncycastle.util.test.UncloseableOutputStream; import java.io.ByteArrayInputStream; import java.io.ByteArrayOutputStream; import java.io.InputStream; import java.io.OutputStream; import java.security.KeyFactory; import java.security.KeyPair; import java.security.KeyPairGenerator; import java.security.PrivateKey; import java.security.Security; import java.util.Date; import java.util.Iterator; public class PGPDSATest extends SimpleTest { byte[] testPubKey = Base64.decode( "mQGiBD9HBzURBACzkxRCVGJg5+Ld9DU4Xpnd4LCKgMq7YOY7Gi0EgK92gbaa6+zQ" + "oQFqz1tt3QUmpz3YVkm/zLESBBtC1ACIXGggUdFMUr5I87+1Cb6vzefAtGt8N5VV" + "1F/MXv1gJz4Bu6HyxL/ncfe71jsNhav0i4yAjf2etWFj53zK6R+Ojg5H6wCgpL9/" + "tXVfGP8SqFvyrN/437MlFSUEAIN3V6j/MUllyrZglrtr2+RWIwRrG/ACmrF6hTug" + "Ol4cQxaDYNcntXbhlTlJs9MxjTH3xxzylyirCyq7HzGJxZzSt6FTeh1DFYzhJ7Qu" + "YR1xrSdA6Y0mUv0ixD5A4nPHjupQ5QCqHGeRfFD/oHzD4zqBnJp/BJ3LvQ66bERJ" + "mKl5A/4uj3HoVxpb0vvyENfRqKMmGBISycY4MoH5uWfb23FffsT9r9KL6nJ4syLz" + "aRR0gvcbcjkc9Z3epI7gr3jTrb4d8WPxsDbT/W1tv9bG/EHawomLcihtuUU68Uej" + "6/wZot1XJqu2nQlku57+M/V2X1y26VKsipolPfja4uyBOOyvbLQzRXJpYyBFY2hp" + "ZG5hIChEU0EgVGVzdCBLZXkpIDxlcmljQGJvdW5jeWNhc3RsZS5vcmc+iFkEExEC" + "ABkFAj9HBzUECwcDAgMVAgMDFgIBAh4BAheAAAoJEM0j9enEyjRDAlwAn2rrom0s" + "MhufWK5vIRwg7gj5qsLEAJ4vnT5dPBVblofsG+pDoCVeJXGGng=="); byte[] testPrivKey = Base64.decode( "lQHhBD9HBzURBACzkxRCVGJg5+Ld9DU4Xpnd4LCKgMq7YOY7Gi0EgK92gbaa6+zQ" + "oQFqz1tt3QUmpz3YVkm/zLESBBtC1ACIXGggUdFMUr5I87+1Cb6vzefAtGt8N5VV" + "1F/MXv1gJz4Bu6HyxL/ncfe71jsNhav0i4yAjf2etWFj53zK6R+Ojg5H6wCgpL9/" + "tXVfGP8SqFvyrN/437MlFSUEAIN3V6j/MUllyrZglrtr2+RWIwRrG/ACmrF6hTug" + "Ol4cQxaDYNcntXbhlTlJs9MxjTH3xxzylyirCyq7HzGJxZzSt6FTeh1DFYzhJ7Qu" + "YR1xrSdA6Y0mUv0ixD5A4nPHjupQ5QCqHGeRfFD/oHzD4zqBnJp/BJ3LvQ66bERJ" + "mKl5A/4uj3HoVxpb0vvyENfRqKMmGBISycY4MoH5uWfb23FffsT9r9KL6nJ4syLz" + "aRR0gvcbcjkc9Z3epI7gr3jTrb4d8WPxsDbT/W1tv9bG/EHawomLcihtuUU68Uej" + "6/wZot1XJqu2nQlku57+M/V2X1y26VKsipolPfja4uyBOOyvbP4DAwIDIBTxWjkC" + "GGAWQO2jy9CTvLHJEoTO7moHrp1FxOVpQ8iJHyRqZzLllO26OzgohbiPYz8u9qCu" + "lZ9Xn7QzRXJpYyBFY2hpZG5hIChEU0EgVGVzdCBLZXkpIDxlcmljQGJvdW5jeWNh" + "c3RsZS5vcmc+iFkEExECABkFAj9HBzUECwcDAgMVAgMDFgIBAh4BAheAAAoJEM0j" + "9enEyjRDAlwAnjTjjt57NKIgyym7OTCwzIU3xgFpAJ0VO5m5PfQKmGJRhaewLSZD" + "4nXkHg=="); byte[] testPrivKey2 = Base64.decode( "lQHhBEAnoewRBADRvKgDhbV6pMzqYfUgBsLxSHzmycpuxGbjMrpyKHDOEemj" + "iQb6TyyBKUoR28/pfshFP9R5urtKIT7wjVrDuOkxYkgRhNm+xmPXW2Lw3D++" + "MQrC5VWe8ywBltz6T9msmChsaKo2hDhIiRI/mg9Q6rH9pJKtVGi4R7CgGxM2" + "STQ5fwCgub38qGS1W2O4hUsa+3gva5gaNZUEAItegda4/H4t88XdWxW3D8pv" + "RnFz26/ADdImVaQlBoumD15VmcgYoT1Djizey7X8vfV+pntudESzLbn3GHlI" + "6C09seH4e8eYP63t7KU/qbUCDomlSswd1OgQ/RxfN86q765K2t3K1i3wDSxe" + "EgSRyGKee0VNvOBFOFhuWt+patXaBADE1riNkUxg2P4lBNWwu8tEZRmsl/Ys" + "DBIzXBshoMzZCvS5PnNXMW4G3SAaC9OC9jvKSx9IEWhKjfjs3QcWzXR28mcm" + "5na0bTxeOMlaPPhBdkTCmFl0IITWlH/pFlR2ah9WYoWYhZEL2tqB82wByzxH" + "SkSeD9V5oeSCdCcqiqkEmv4DAwLeNsQ2XGJVRmA4lld+CR5vRxpT/+/2xklp" + "lxVf/nx0+thrHDpro3u/nINIIObk0gh59+zaEEe3APlHqbQVYWFhIGJiYiA8" + "Y2NjQGRkZC5lZWU+iFoEExECABoFAkAnoewFCwcDAgEDFQIDAxYCAQIeAQIX" + "gAAKCRA5nBpCS63az85BAKCbPfU8ATrFvkXhzGNGlc1BJo6DWQCgnK125xVK" + "lWLpt6ZJJ7TXcx3nkm6wAgAAnQFXBEAnoe0QBACsQxPvaeBcv2TkbgU/5Wc/" + "tO222dPE1mxFbXjGTKfb+6ge96iyD8kTRLrKCkEEeVBa8AZqMSoXUVN6tV8j" + "/zD8Bc76o5iJ6wgpg3Mmy2GxInVfsfZN6/G3Y2ukmouz+CDNvQdUw8cTguIb" + "QoV3XhQ03MLbfVmNcHsku9F4CuKNWwADBQP0DSSe8v5PXF9CSCXOIxBDcQ5x" + "RKjyYOveqoH/4lbOV0YNUbIDZq4RaUdotpADuPREFmWf0zTB6KV/WIiag8XU" + "WU9zdDvLKR483Bo6Do5pDBcN+NqfQ+ntGY9WJ7BSFnhQ3+07i1K+NsfFTRfv" + "hf9X3MP75rCf7MxAIWHTabEmUf4DAwLeNsQ2XGJVRmA8DssBUCghogG9n8T3" + "qfBeKsplGyCcF+JjPeQXkKQaoYGJ0aJz36qFP9d8DuWtT9soQcqIxVf6mTa8" + "kN1594hGBBgRAgAGBQJAJ6HtAAoJEDmcGkJLrdrPpMkAnRyjQSKugz0YJqOB" + "yGasMLQLxd2OAKCEIlhtCarlufVQNGZsuWxHVbU8crACAAA="); byte[] sig1 = Base64.decode( "owGbwMvMwCR4VvnryyOnTJwZ10gncZSkFpfolVSU2Ltz78hIzcnJVyjPL8pJUeTq" + "sGdmZQCJwpQLMq3ayTA/0Fj3xf4jbwPfK/H3zj55Z9L1n2k/GOapKJrvMZ4tLiCW" + "GtP/XeDqX4fORDUA"); byte[] sig1crc = Base64.decode("OZa/"); byte[] testPubWithUserAttr = Base64.decode( "mQGiBD2Rqv0RBADqKCkhVEtB/lEEr/9CubuHEy2oN/yU5j+2GXSdcNdVnRI/rwFy" + "fHEQIk3uU7zHSUKFrC59yDm0sODYyjEdE3BVb0xvEJ5LE/OdndcIMXT1DungZ1vB" + "zIK/3lr33W/PHixYxv9jduH3WrTehBpiKkgMZp8XloSFj2Cnw9LDyfqB7QCg/8K1" + "o2k75NkOd9ZjnA9ye7Ri3bEEAKyr61Mo7viPWBK1joWAEsxG0OBWM+iSlG7kwh31" + "8efgC/7Os6x4Y0jzs8mpcbBjeZtZjS9lRbfp7RinhF269xL0TZ3JxIdtaAV/6yDQ" + "9NXfZY9dskN++HIR/5GCEEgq/qTJZt6ti5k7aV19ZFfO6wiK3NUy08wOrVsdOkVE" + "w9IcBADaplhpcel3201uU3OCboogJtw81R5MJMZ4Y9cKL/ca2jGISn0nA7KrAw9v" + "ShheSixGO4BV9JECkLEbtg7i+W/j/De6S+x2GLNcphuTP3UmgtKbhs0ItRqzW561" + "s6gLkqi6aWmgaFLd8E1pMJcd9DSY95P13EYB9VJIUxFNUopzo7QcUmFsZiBIYXVz" + "ZXIgPGhhdXNlckBhY20ub3JnPokAWAQQEQIAGAUCPZGq/QgLAwkIBwIBCgIZAQUb" + "AwAAAAAKCRAqIBiOh4JvOKg4AJ9j14yygOqqzqiLKeaasIzqT8LCIgCggx14WuLO" + "wOUTUswTaVKMFnU7tseJAJwEEAECAAYFAj2Rqx8ACgkQ9aWTKMpUDFV+9QP/RiWT" + "5FAF5Rgb7beaApsgXsME+Pw7HEYFtqGa6VcXEpbcUXO6rjaXsgMgY90klWlWCF1T" + "HOyKITvj2FdhE+0j8NQn4vaGpiTwORW/zMf/BZ0abdSWQybp10Yjs8gXw30UheO+" + "F1E524MC+s2AeUi2hwHMiS+AVYd4WhxWHmWuBpTRypP/AAALTgEQAAEBAAAAAQAA" + "AAABAAAA/9j/4AAQSkZJRgABAQAAAQABAAD/2wBDAAoHBwgHBgoICAgLCgoLDhgQ" + "Dg0NDh0VFhEYIx8lJCIfIiEmKzcvJik0KSEiMEExNDk7Pj4+JS5ESUM8SDc9Pjv/" + "2wBDAQoLCw4NDhwQEBw7KCIoOzs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7" + "Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozv/wAARCABqAF0DASIAAhEBAxEB/8QAHwAAAQUB" + "AQEBAQEAAAAAAAAAAAECAwQFBgcICQoL/8QAtRAAAgEDAwIEAwUFBAQAAAF9AQID" + "AAQRBRIhMUEGE1FhByJxFDKBkaEII0KxwRVS0fAkM2JyggkKFhcYGRolJicoKSo0" + "NTY3ODk6Q0RFRkdISUpTVFVWV1hZWmNkZWZnaGlqc3R1dnd4eXqDhIWGh4iJipKT" + "lJWWl5iZmqKjpKWmp6ipqrKztLW2t7i5usLDxMXGx8jJytLT1NXW19jZ2uHi4+Tl" + "5ufo6erx8vP09fb3+Pn6/8QAHwEAAwEBAQEBAQEBAQAAAAAAAAECAwQFBgcICQoL" + "/8QAtREAAgECBAQDBAcFBAQAAQJ3AAECAxEEBSExBhJBUQdhcRMiMoEIFEKRobHB" + "CSMzUvAVYnLRChYkNOEl8RcYGRomJygpKjU2Nzg5OkNERUZHSElKU1RVVldYWVpj" + "ZGVmZ2hpanN0dXZ3eHl6goOEhYaHiImKkpOUlZaXmJmaoqOkpaanqKmqsrO0tba3" + "uLm6wsPExcbHyMnK0tPU1dbX2Nna4uPk5ebn6Onq8vP09fb3+Pn6/9oADAMBAAIR" + "AxEAPwD2aiiq9xcxWsRllcKqjOT06E/0oAsVm6jrmm6VGXvLuOPGflz8x+grzXxV" + "8U51u5LXRgBGowZHXknnkc9OQcV51caneXdw9xPOXlckl2AJHY4J6cD1oA9J1z4p" + "TRkrYQhRyQ0hIY5/2QRx7k9ulczN8SvEEshdZkX0UorDrznI759a5Mksckkknqec" + "mkoA7WD4oavEoEttbTepYEZ+mCMVv6H8SLTULhbe/gFozAYkD5Unp3Ax/kV5XRQB" + "9EAhgCDkHkEcgilryTwd4zn0m4WzvpTJZSMBuY5MfbueletKyugZWDKwyCOc/j3o" + "AduyWLDeWB5Ynj8jSUUUAdFXn/xU15dO0RbGGYC5uWwUB6L1Jx+n413F1cJa2stz" + "J92JC5+gGa+bdfvp9S1q4urmRneQg5Yk4HGAPYZoAzySxySSSep5yaSvQvAPhOHU" + "rB7u5iLGUlIwQRx7HPr/AJ9LGsfC+dJGngc+X12gc8nvx1/rQB5rRXS3Xg28t9ye" + "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" + "qkEsPXn6/pXo/ilVzbttG7DDOOeornqAONbRpI4v3pKOQcAqQD+Y/P6j052NK0p5" + "HWHy3IBPyqrfN6gZz+P4/hpXoGzOOiP/ACNdH4XRftsp2jIBxx70AX9E0pdMtvMm" + "VRNt5xyEGOgPf3NeDeLdVOs+J768zlGkKx+yjgfy/WvoPXeNEvMcfujXzJQAUUUU" + "Af/ZiQBGBBARAgAGBQI9katEAAoJECogGI6Hgm84xz8AoNGz1fJrVPxqkBrUDmWA" + "GsP6qVGYAJ0ZOftw/GfQHzdGR8pOK85DLUPEErQkUmFsZiBIYXVzZXIgPGhhdXNl" + "ckBwcml2YXNwaGVyZS5jb20+iQBGBBARAgAGBQI9katmAAoJECogGI6Hgm84m0oA" + "oJS3CTrgpqRZfhgPtHGtUVjRCJbbAJ9stJgPcbqA2xXEg9yl2TQToWdWxbQkUmFs" + "ZiBIYXVzZXIgPGhhdXNlckBwcml2YXNwaGVyZS5vcmc+iQBGBBARAgAGBQI9kauJ" + "AAoJECogGI6Hgm84GfAAnRswktLMzDfIjv6ni76Qp5B850byAJ90I0LEHOLhda7r" + "kqTwZ8rguNssUrQkUmFsZiBIYXVzZXIgPGhhdXNlckBwcml2YXNwaGVyZS5uZXQ+" + "iQBGBBARAgAGBQI9kaubAAoJECogGI6Hgm84zi0An16C4s/B9Z0/AtfoN4ealMh3" + "i3/7AJ9Jg4GOUqGCGRRKUA9Gs5pk8yM8GbQmUmFsZiBDLiBIYXVzZXIgPHJhbGZo" + "YXVzZXJAYmx1ZXdpbi5jaD6JAEYEEBECAAYFAj2Rq8oACgkQKiAYjoeCbzhPOACg" + "iiTohKuIa66FNiI24mQ+XR9nTisAoLmh3lJf16/06qLPsRd9shTkLfmHtB9SYWxm" + "IEhhdXNlciA8cmFsZmhhdXNlckBnbXguY2g+iQBGBBARAgAGBQI9kavvAAoJECog" + "GI6Hgm84ZE8An0RlgL8mPBa/P08S5e/lD35MlDdgAJ99pjCeY46S9+nVyx7ACyKO" + "SZ4OcLQmUmFsZiBIYXVzZXIgPGhhdXNlci5yYWxmQG15c3VucmlzZS5jaD6JAEYE" + "EBECAAYFAj2RrEEACgkQKiAYjoeCbzjz0wCg+q801XrXk+Rf+koSI50MW5OaaKYA" + "oKOVA8SLxE29qSR/bJeuW0ryzRLqtCVSYWxmIEhhdXNlciA8aGF1c2VyLnJhbGZA" + "ZnJlZXN1cmYuY2g+iQBGBBARAgAGBQI9kaxXAAoJECogGI6Hgm848zoAnRBtWH6e" + "fTb3is63s8J2zTfpsyS0AKDxTjl+ZZV0COHLrSCaNLZVcpImFrkEDQQ9kar+EBAA" + "+RigfloGYXpDkJXcBWyHhuxh7M1FHw7Y4KN5xsncegus5D/jRpS2MEpT13wCFkiA" + "tRXlKZmpnwd00//jocWWIE6YZbjYDe4QXau2FxxR2FDKIldDKb6V6FYrOHhcC9v4" + "TE3V46pGzPvOF+gqnRRh44SpT9GDhKh5tu+Pp0NGCMbMHXdXJDhK4sTw6I4TZ5dO" + "khNh9tvrJQ4X/faY98h8ebByHTh1+/bBc8SDESYrQ2DD4+jWCv2hKCYLrqmus2UP" + "ogBTAaB81qujEh76DyrOH3SET8rzF/OkQOnX0ne2Qi0CNsEmy2henXyYCQqNfi3t" + "5F159dSST5sYjvwqp0t8MvZCV7cIfwgXcqK61qlC8wXo+VMROU+28W65Szgg2gGn" + "VqMU6Y9AVfPQB8bLQ6mUrfdMZIZJ+AyDvWXpF9Sh01D49Vlf3HZSTz09jdvOmeFX" + "klnN/biudE/F/Ha8g8VHMGHOfMlm/xX5u/2RXscBqtNbno2gpXI61Brwv0YAWCvl" + "9Ij9WE5J280gtJ3kkQc2azNsOA1FHQ98iLMcfFstjvbzySPAQ/ClWxiNjrtVjLhd" + "ONM0/XwXV0OjHRhs3jMhLLUq/zzhsSlAGBGNfISnCnLWhsQDGcgHKXrKlQzZlp+r" + "0ApQmwJG0wg9ZqRdQZ+cfL2JSyIZJrqrol7DVes91hcAAgIQAKD9MGkS8SUD2irI" + "AiwVHU0WXLBnk2CvvueSmT9YtC34UKkIkDPZ7VoeuXDfqTOlbiE6T16zPvArZfbl" + "JGdrU7HhsTdu+ADxRt1dPur0G0ICJ3pBD3ydGWpdLI/94x1BvTY4rsR5mS4YWmpf" + "e2kWc7ZqezhP7Xt9q7m4EK456ddeUZWtkwGU+PKyRAZ+CK82Uhouw+4aW0NjiqmX" + "hfH9/BUhI1P/8R9VkTfAFGPmZzqoHr4AuO5tLRLD2RFSmQCP8nZTiP9nP+wBBvn7" + "vuqKRQsj9PwwPD4V5SM+kpW+rUIWr9TZYl3UqSnlXlpEZFd2Bfl6NloeH0cfU69E" + "gtjcWGvGxYKPS0cg5yhVb4okka6RqIPQiYl6eJgv4tRTKoPRX29o0aUVdqVvDr5u" + "tnFzcINq7jTo8GiO8Ia3cIFWfo0LyQBd1cf1U+eEOz+DleEFqyljaz9VCbDPE4GP" + "o+ALESBlOwn5daUSaah9iU8aVPaSjn45hoQqxOKPwJxnCKKQ01iy0Gir+CDU8JJB" + "7bmbvQN4bke30EGAeED3oi+3VaBHrhjYLv7SHIxP5jtCJKWMJuLRV709HsWJi3kn" + "fGHwH+yCDF8+PDeROAzpXBaD2EFhKgeUTjP5Rgn6ltRf8TQnfbW4qlwyiXMhPOfC" + "x6qNmwaFPKQJpIkVq5VGfRXAERfkiQBMBBgRAgAMBQI9kar+BRsMAAAAAAoJECog" + "GI6Hgm84CDMAoNrNeP4c8XqFJnsLLPcjk5YGLaVIAKCrL5KFuLQVIp7d0Fkscx3/" + "7DGrzw=="); byte[] aesSecretKey = Base64.decode( "lQHpBEBSdIYRBADpd7MeIxRk4RsvyMnJNIYe4FiVv6i7I7+LPRvnIjDct0bN" + "1gCV48QFej7g/PsvXRjYSowV3VIvchWX8OERd/5i10cLbcs7X52EP1vwYaLj" + "uRfNUBg8Q51RQsKR+/rBmnVsi68rjU4yTH6wpo6FOO4pz4wFV+tWwGOwOitA" + "K31L4wCgqh59eFFBrOlRFAbDvaL7emoCIR8EAOLxDKiLQJYQrKZfXdZnifeo" + "dhEP0uuV4O5TG6nrqkhWffzC9cSoFD0BhMl979d8IB2Uft4FNvQc2u8hbJL5" + "7OCGDCUAidlB9jSdu0/J+kfRaTGhYDjBgw7AA42576BBSMNouJg/aOOQENEN" + "Nn4n7NxR3viBzIsL/OIeU8HSkBgaA/41PsvcgZ3kwpdltJ/FVRWhmMmv/q/X" + "qp1YOnF8xPU9bv2ofELrxJfRsbS4GW1etzD+nXs/woW4Vfixs01x+cutR4iF" + "3hw+eU+yLToMPmmo8D2LUvX1SRODJpx5yBBeRIYv6nz9H3sQRDx3kaLASxDV" + "jTxKmrLYnZz5w5qyVpvRyv4JAwKyWlhdblPudWBFXNkW5ydKn0AV2f51wEtj" + "Zy0aLIeutVMSJf1ytLqjFqrnFe6pdJrHO3G00TE8OuFhftWosLGLbEGytDtF" + "cmljIEguIEVjaGlkbmEgKHRlc3Qga2V5IC0gQUVTMjU2KSA8ZXJpY0Bib3Vu" + "Y3ljYXN0bGUub3JnPohZBBMRAgAZBQJAUnSGBAsHAwIDFQIDAxYCAQIeAQIX" + "gAAKCRBYt1NnUiCgeFKaAKCiqtOO+NQES1gJW6XuOGmSkXt8bQCfcuW7SXZH" + "zxK1FfdcG2HEDs3YEVawAgAA"); byte[] aesPublicKey = Base64.decode( "mQGiBEBSdIYRBADpd7MeIxRk4RsvyMnJNIYe4FiVv6i7I7+LPRvnIjDct0bN" + "1gCV48QFej7g/PsvXRjYSowV3VIvchWX8OERd/5i10cLbcs7X52EP1vwYaLj" + "uRfNUBg8Q51RQsKR+/rBmnVsi68rjU4yTH6wpo6FOO4pz4wFV+tWwGOwOitA" + "K31L4wCgqh59eFFBrOlRFAbDvaL7emoCIR8EAOLxDKiLQJYQrKZfXdZnifeo" + "dhEP0uuV4O5TG6nrqkhWffzC9cSoFD0BhMl979d8IB2Uft4FNvQc2u8hbJL5" + "7OCGDCUAidlB9jSdu0/J+kfRaTGhYDjBgw7AA42576BBSMNouJg/aOOQENEN" + "Nn4n7NxR3viBzIsL/OIeU8HSkBgaA/41PsvcgZ3kwpdltJ/FVRWhmMmv/q/X" + "qp1YOnF8xPU9bv2ofELrxJfRsbS4GW1etzD+nXs/woW4Vfixs01x+cutR4iF" + "3hw+eU+yLToMPmmo8D2LUvX1SRODJpx5yBBeRIYv6nz9H3sQRDx3kaLASxDV" + "jTxKmrLYnZz5w5qyVpvRyrQ7RXJpYyBILiBFY2hpZG5hICh0ZXN0IGtleSAt" + "IEFFUzI1NikgPGVyaWNAYm91bmN5Y2FzdGxlLm9yZz6IWQQTEQIAGQUCQFJ0" + "hgQLBwMCAxUCAwMWAgECHgECF4AACgkQWLdTZ1IgoHhSmgCfU83BLBF2nCua" + "zk2dXB9zO1l6XS8AnA07U4cq5W0GrKM6/kP9HWtPhgOFsAIAAA=="); byte[] twofishSecretKey = Base64.decode( "lQHpBEBSdtIRBACf7WfrqTl8F051+EbaljPf/8/ajFpAfMq/7p3Hri8OCsuc" + "fJJIufEEOV1/Lt/wkN67MmSyrU0fUCsRbEckRiB4EJ0zGHVFfAnku2lzdgc8" + "AVounqcHOmqA/gliFDEnhYOx3bOIAOav+yiOqfKVBhWRCpFdOTE+w/XoDM+p" + "p8bH5wCgmP2FuWpzfSut7GVKp51xNEBRNuED/3t2Q+Mq834FVynmLKEmeXB/" + "qtIz5reHEQR8eMogsOoJS3bXs6v3Oblj4in1gLyTVfcID5tku6kLP20xMRM2" + "zx2oRbz7TyOCrs15IpRXyqqJxUWD8ipgJPkPXE7hK8dh4YSTUi4i5a1ug8xG" + "314twlPzrchpWZiutDvZ+ks1rzOtBACHrEFG2frUu+qVkL43tySE0cV2bnuK" + "LVhXbpzF3Qdkfxou2nuzsCbl6m87OWocJX8uYcQGlHLKv8Q2cfxZyieLFg6v" + "06LSFdE9drGBWz7mbrT4OJjxPyvnkffPfLOOqae3PMYIIuscvswuhm4X5aoj" + "KJs01YT3L6f0iIj03hCeV/4KAwLcGrxT3X0qR2CZyZYSVBdjXeNYKXuGBtOf" + "ood26WOtwLw4+l9sHVoiXNv0LomkO58ndJRPGCeZWZEDMVrfkS7rcOlktDxF" + "cmljIEguIEVjaGlkbmEgKHRlc3Qga2V5IC0gdHdvZmlzaCkgPGVyaWNAYm91" + "bmN5Y2FzdGxlLm9yZz6IWQQTEQIAGQUCQFJ20gQLBwMCAxUCAwMWAgECHgEC" + "F4AACgkQaCCMaHh9zR2+RQCghcQwlt4B4YmNxp2b3v6rP3E8M0kAn2Gspi4u" + "A/ynoqnC1O8HNlbjPdlVsAIAAA=="); byte[] twofishPublicKey = Base64.decode( "mQGiBEBSdtIRBACf7WfrqTl8F051+EbaljPf/8/ajFpAfMq/7p3Hri8OCsuc" + "fJJIufEEOV1/Lt/wkN67MmSyrU0fUCsRbEckRiB4EJ0zGHVFfAnku2lzdgc8" + "AVounqcHOmqA/gliFDEnhYOx3bOIAOav+yiOqfKVBhWRCpFdOTE+w/XoDM+p" + "p8bH5wCgmP2FuWpzfSut7GVKp51xNEBRNuED/3t2Q+Mq834FVynmLKEmeXB/" + "qtIz5reHEQR8eMogsOoJS3bXs6v3Oblj4in1gLyTVfcID5tku6kLP20xMRM2" + "zx2oRbz7TyOCrs15IpRXyqqJxUWD8ipgJPkPXE7hK8dh4YSTUi4i5a1ug8xG" + "314twlPzrchpWZiutDvZ+ks1rzOtBACHrEFG2frUu+qVkL43tySE0cV2bnuK" + "LVhXbpzF3Qdkfxou2nuzsCbl6m87OWocJX8uYcQGlHLKv8Q2cfxZyieLFg6v" + "06LSFdE9drGBWz7mbrT4OJjxPyvnkffPfLOOqae3PMYIIuscvswuhm4X5aoj" + "KJs01YT3L6f0iIj03hCeV7Q8RXJpYyBILiBFY2hpZG5hICh0ZXN0IGtleSAt" + "IHR3b2Zpc2gpIDxlcmljQGJvdW5jeWNhc3RsZS5vcmc+iFkEExECABkFAkBS" + "dtIECwcDAgMVAgMDFgIBAh4BAheAAAoJEGggjGh4fc0dvkUAn2QGdNk8Wrrd" + "+DvKECrO5+yoPRx3AJ91DhCMme6uMrQorKSDYxHlgc7iT7ACAAA="); char[] pass = { 'h', 'e', 'l', 'l', 'o', ' ', 'w', 'o', 'r', 'l', 'd' }; /** * Generated signature test * * @param sKey * @param pgpPrivKey */ public void generateTest( PGPSecretKeyRing sKey, PGPPublicKey pgpPubKey, PGPPrivateKey pgpPrivKey) throws Exception { String data = "hello world!"; ByteArrayOutputStream bOut = new ByteArrayOutputStream(); ByteArrayInputStream testIn = new ByteArrayInputStream(data.getBytes()); PGPSignatureGenerator sGen = new PGPSignatureGenerator(PublicKeyAlgorithmTags.DSA, HashAlgorithmTags.SHA1, "BC"); sGen.initSign(PGPSignature.BINARY_DOCUMENT, pgpPrivKey); PGPSignatureSubpacketGenerator spGen = new PGPSignatureSubpacketGenerator(); Iterator it = sKey.getSecretKey().getPublicKey().getUserIDs(); String primaryUserID = (String)it.next(); spGen.setSignerUserID(true, primaryUserID); sGen.setHashedSubpackets(spGen.generate()); PGPCompressedDataGenerator cGen = new PGPCompressedDataGenerator( PGPCompressedData.ZIP); BCPGOutputStream bcOut = new BCPGOutputStream( cGen.open(new UncloseableOutputStream(bOut))); sGen.generateOnePassVersion(false).encode(bcOut); PGPLiteralDataGenerator lGen = new PGPLiteralDataGenerator(); Date testDate = new Date((System.currentTimeMillis() / 1000) * 1000); OutputStream lOut = lGen.open( new UncloseableOutputStream(bcOut), PGPLiteralData.BINARY, "_CONSOLE", data.getBytes().length, testDate); int ch; while ((ch = testIn.read()) >= 0) { lOut.write(ch); sGen.update((byte)ch); } lGen.close(); sGen.generate().encode(bcOut); cGen.close(); PGPObjectFactory pgpFact = new PGPObjectFactory(bOut.toByteArray()); PGPCompressedData c1 = (PGPCompressedData)pgpFact.nextObject(); pgpFact = new PGPObjectFactory(c1.getDataStream()); PGPOnePassSignatureList p1 = (PGPOnePassSignatureList)pgpFact.nextObject(); PGPOnePassSignature ops = p1.get(0); PGPLiteralData p2 = (PGPLiteralData)pgpFact.nextObject(); if (!p2.getModificationTime().equals(testDate)) { fail("Modification time not preserved"); } InputStream dIn = p2.getInputStream(); ops.initVerify(pgpPubKey, "BC"); while ((ch = dIn.read()) >= 0) { ops.update((byte)ch); } PGPSignatureList p3 = (PGPSignatureList)pgpFact.nextObject(); if (!ops.verify(p3.get(0))) { fail("Failed generated signature check"); } } public void performTest() throws Exception { String file = null; KeyFactory fact = KeyFactory.getInstance("DSA", "BC"); PGPPublicKey pubKey = null; PrivateKey privKey = null; PGPUtil.setDefaultProvider("BC"); // // Read the public key // PGPPublicKeyRing pgpPub = new PGPPublicKeyRing(testPubKey); pubKey = pgpPub.getPublicKey(); // // Read the private key // PGPSecretKeyRing sKey = new PGPSecretKeyRing(testPrivKey); PGPPrivateKey pgpPrivKey = sKey.getSecretKey().extractPrivateKey(pass, "BC"); // // test signature message // PGPObjectFactory pgpFact = new PGPObjectFactory(sig1); PGPCompressedData c1 = (PGPCompressedData)pgpFact.nextObject(); pgpFact = new PGPObjectFactory(c1.getDataStream()); PGPOnePassSignatureList p1 = (PGPOnePassSignatureList)pgpFact.nextObject(); PGPOnePassSignature ops = p1.get(0); PGPLiteralData p2 = (PGPLiteralData)pgpFact.nextObject(); InputStream dIn = p2.getInputStream(); int ch; ops.initVerify(pubKey, "BC"); while ((ch = dIn.read()) >= 0) { ops.update((byte)ch); } PGPSignatureList p3 = (PGPSignatureList)pgpFact.nextObject(); if (!ops.verify(p3.get(0))) { fail("Failed signature check"); } // // signature generation // generateTest(sKey, pubKey, pgpPrivKey); // // signature generation - canonical text // String data = "hello world!"; ByteArrayOutputStream bOut = new ByteArrayOutputStream(); ByteArrayInputStream testIn = new ByteArrayInputStream(data.getBytes()); PGPSignatureGenerator sGen = new PGPSignatureGenerator(PGPPublicKey.DSA, PGPUtil.SHA1, "BC"); sGen.initSign(PGPSignature.CANONICAL_TEXT_DOCUMENT, pgpPrivKey); PGPCompressedDataGenerator cGen = new PGPCompressedDataGenerator( PGPCompressedData.ZIP); BCPGOutputStream bcOut = new BCPGOutputStream( cGen.open(new UncloseableOutputStream(bOut))); sGen.generateOnePassVersion(false).encode(bcOut); PGPLiteralDataGenerator lGen = new PGPLiteralDataGenerator(); Date testDate = new Date((System.currentTimeMillis() / 1000) * 1000); OutputStream lOut = lGen.open( new UncloseableOutputStream(bcOut), PGPLiteralData.TEXT, "_CONSOLE", data.getBytes().length, testDate); while ((ch = testIn.read()) >= 0) { lOut.write(ch); sGen.update((byte)ch); } lGen.close(); sGen.generate().encode(bcOut); cGen.close(); // // verify generated signature - canconical text // pgpFact = new PGPObjectFactory(bOut.toByteArray()); c1 = (PGPCompressedData)pgpFact.nextObject(); pgpFact = new PGPObjectFactory(c1.getDataStream()); p1 = (PGPOnePassSignatureList)pgpFact.nextObject(); ops = p1.get(0); p2 = (PGPLiteralData)pgpFact.nextObject(); if (!p2.getModificationTime().equals(testDate)) { fail("Modification time not preserved"); } dIn = p2.getInputStream(); ops.initVerify(pubKey, "BC"); while ((ch = dIn.read()) >= 0) { ops.update((byte)ch); } p3 = (PGPSignatureList)pgpFact.nextObject(); if (!ops.verify(p3.get(0))) { fail("Failed generated signature check"); } // // Read the public key with user attributes // pgpPub = new PGPPublicKeyRing(testPubWithUserAttr); pubKey = pgpPub.getPublicKey(); Iterator it = pubKey.getUserAttributes(); int count = 0; while (it.hasNext()) { PGPUserAttributeSubpacketVector attributes = (PGPUserAttributeSubpacketVector)it.next(); Iterator sigs = pubKey.getSignaturesForUserAttribute(attributes); int sigCount = 0; while (sigs.hasNext()) { sigs.next(); sigCount++; } if (sigCount != 1) { fail("Failed user attributes signature check"); } count++; } if (count != 1) { fail("Failed user attributes check"); } byte[] pgpPubBytes = pgpPub.getEncoded(); pgpPub = new PGPPublicKeyRing(pgpPubBytes); pubKey = pgpPub.getPublicKey(); it = pubKey.getUserAttributes(); count = 0; while (it.hasNext()) { it.next(); count++; } if (count != 1) { fail("Failed user attributes reread"); } // // reading test extra data - key with edge condition for DSA key password. // char [] passPhrase = { '0', '1', '2', '3', '4', '5', '6', '7', '8', '9' }; sKey = new PGPSecretKeyRing(testPrivKey2); pgpPrivKey = sKey.getSecretKey().extractPrivateKey(passPhrase, "BC"); byte[] bytes = pgpPrivKey.getKey().getEncoded(); // // reading test - aes256 encrypted passphrase. // sKey = new PGPSecretKeyRing(aesSecretKey); pgpPrivKey = sKey.getSecretKey().extractPrivateKey(pass, "BC"); bytes = pgpPrivKey.getKey().getEncoded(); // // reading test - twofish encrypted passphrase. // sKey = new PGPSecretKeyRing(twofishSecretKey); pgpPrivKey = sKey.getSecretKey().extractPrivateKey(pass, "BC"); bytes = pgpPrivKey.getKey().getEncoded(); // // use of PGPKeyPair // KeyPairGenerator kpg = KeyPairGenerator.getInstance("DSA", "BC"); kpg.initialize(512); KeyPair kp = kpg.generateKeyPair(); PGPKeyPair pgpKp = new PGPKeyPair(PGPPublicKey.DSA , kp.getPublic(), kp.getPrivate(), new Date()); PGPPublicKey k1 = pgpKp.getPublicKey(); PGPPrivateKey k2 = pgpKp.getPrivateKey(); } public String getName() { return "PGPDSATest"; } public static void main( String[] args) { Security.addProvider(new BouncyCastleProvider()); runTest(new PGPSignatureTest()); } } bouncycastle-1.49.orig/test/src/org/bouncycastle/openpgp/test/AllTests.java0000644000175000017500000000221612032226267026511 0ustar ebourgebourgpackage org.bouncycastle.openpgp.test; import java.security.Security; import junit.framework.Test; import junit.framework.TestCase; import junit.framework.TestSuite; import org.bouncycastle.jce.provider.BouncyCastleProvider; import org.bouncycastle.util.test.SimpleTestResult; public class AllTests extends TestCase { public void testPGP() { Security.addProvider(new BouncyCastleProvider()); org.bouncycastle.util.test.Test[] tests = RegressionTest.tests; for (int i = 0; i != tests.length; i++) { SimpleTestResult result = (SimpleTestResult)tests[i].perform(); if (!result.isSuccessful()) { fail(result.toString()); } } } public static void main (String[] args) { junit.textui.TestRunner.run(suite()); } public static Test suite() { TestSuite suite = new TestSuite("OpenPGP Tests"); suite.addTestSuite(AllTests.class); suite.addTestSuite(DSA2Test.class); suite.addTestSuite(PGPUnicodeTest.class); return suite; } } bouncycastle-1.49.orig/test/src/org/bouncycastle/openpgp/test/PGPUnicodeTest.java0000644000175000017500000001246412151252353027556 0ustar ebourgebourgpackage org.bouncycastle.openpgp.test; import java.io.BufferedReader; import java.io.FileInputStream; import java.io.InputStreamReader; import java.io.Reader; import java.math.BigInteger; import java.nio.charset.Charset; import java.security.Security; import junit.framework.Test; import junit.framework.TestCase; import junit.framework.TestSuite; import org.bouncycastle.jce.provider.BouncyCastleProvider; import org.bouncycastle.openpgp.PGPException; import org.bouncycastle.openpgp.PGPPrivateKey; import org.bouncycastle.openpgp.PGPSecretKey; import org.bouncycastle.openpgp.PGPSecretKeyRing; import org.bouncycastle.openpgp.PGPSecretKeyRingCollection; import org.bouncycastle.openpgp.operator.PBESecretKeyDecryptor; import org.bouncycastle.openpgp.operator.PGPDigestCalculatorProvider; import org.bouncycastle.openpgp.operator.jcajce.JcaPGPDigestCalculatorProviderBuilder; import org.bouncycastle.openpgp.operator.jcajce.JcePBESecretKeyDecryptorBuilder; public class PGPUnicodeTest extends TestCase { private static final String TEST_DATA_HOME = "bc.test.data.home"; public void setUp() { if (Security.getProvider("BC") == null) { Security.addProvider(new org.bouncycastle.jce.provider.BouncyCastleProvider()); } } public void test_key(BigInteger keyId, String passphrase) throws Exception { PGPSecretKeyRingCollection secretKeyRing = loadSecretKeyCollection("secring.gpg"); PGPSecretKeyRing secretKey = secretKeyRing.getSecretKeyRing(keyId.longValue()); assertNotNull("Could not locate secret keyring with Id=" + keyId.toString(16), secretKey); PGPSecretKey key = secretKey.getSecretKey(); assertNotNull("Could not locate secret key!", key); try { PGPDigestCalculatorProvider calcProvider = new JcaPGPDigestCalculatorProviderBuilder() .setProvider(BouncyCastleProvider.PROVIDER_NAME).build(); PBESecretKeyDecryptor decryptor = new JcePBESecretKeyDecryptorBuilder(calcProvider) .setProvider(BouncyCastleProvider.PROVIDER_NAME).build(passphrase.toCharArray()); PGPPrivateKey privateKey = key.extractPrivateKey(decryptor); assertTrue(privateKey.getKeyID() == keyId.longValue()); } catch (PGPException e) { throw new PGPException("Password incorrect!", e); } // all fine! } public void test_UmlautPassphrase() { try { BigInteger keyId = new BigInteger("362961283C48132B9F14C5C3EC87272EFCB986D2", 16); String passphrase = new String("Händle".getBytes("UTF-16"), "UTF-16"); // FileInputStream passwordFile = new FileInputStream("testdata/passphrase_for_test.txt"); // byte[] password = new byte[passwordFile.available()]; // passwordFile.read(password); // passwordFile.close(); // String passphrase = new String(password); test_key(keyId, passphrase); // all fine! } catch (Exception e) { e.printStackTrace(); fail(e.getMessage()); } } public void test_ASCIIPassphrase() { try { BigInteger keyId = new BigInteger("A392B7310C64026022405257AA2AAAC7CB417459", 16); String passphrase = "Admin123"; test_key(keyId, passphrase); // all fine! } catch (Exception e) { e.printStackTrace(); fail(e.getMessage()); } } public void test_CyrillicPassphrase() { try { BigInteger keyId = new BigInteger("B7773AF32BE4EC1806B1BACC4680E7F3960C44E7", 16); // XXX The password text file must not have the UTF-8 BOM ! // Ref: http://stackoverflow.com/questions/2223882/whats-different-between-utf-8-and-utf-8-without-bom FileInputStream passwordFile = new FileInputStream(getDataHome() + "passphrase_cyr.txt"); Reader reader = new InputStreamReader(passwordFile, Charset.forName("UTF-8")); BufferedReader in = new BufferedReader(reader); String passphrase = in.readLine(); in.close(); passwordFile.close(); test_key(keyId, passphrase); // all fine! } catch (Exception e) { e.printStackTrace(); fail(e.getMessage()); } } private PGPSecretKeyRingCollection loadSecretKeyCollection( String keyName) throws Exception { FileInputStream fIn = new FileInputStream(getDataHome() + keyName); return new PGPSecretKeyRingCollection(fIn); } private String getDataHome() { String dataHome = System.getProperty(TEST_DATA_HOME); if (dataHome == null) { throw new IllegalStateException(TEST_DATA_HOME + " property not set"); } return dataHome + "/openpgp/unicode/"; } public static void main (String[] args) throws Exception { junit.textui.TestRunner.run(suite()); } public static Test suite() throws Exception { TestSuite suite = new TestSuite("Unicode Password tests"); suite.addTestSuite(PGPUnicodeTest.class); return suite; } } bouncycastle-1.49.orig/test/src/org/bouncycastle/openpgp/test/DSA2Test.java0000644000175000017500000002024210550364567026317 0ustar ebourgebourgpackage org.bouncycastle.openpgp.test; import junit.framework.Test; import junit.framework.TestCase; import junit.framework.TestSuite; import org.bouncycastle.bcpg.BCPGOutputStream; import org.bouncycastle.bcpg.PublicKeyAlgorithmTags; import org.bouncycastle.openpgp.PGPCompressedData; import org.bouncycastle.openpgp.PGPLiteralData; import org.bouncycastle.openpgp.PGPLiteralDataGenerator; import org.bouncycastle.openpgp.PGPObjectFactory; import org.bouncycastle.openpgp.PGPOnePassSignature; import org.bouncycastle.openpgp.PGPOnePassSignatureList; import org.bouncycastle.openpgp.PGPPublicKeyRing; import org.bouncycastle.openpgp.PGPSecretKeyRing; import org.bouncycastle.openpgp.PGPSignature; import org.bouncycastle.openpgp.PGPSignatureGenerator; import org.bouncycastle.openpgp.PGPSignatureList; import org.bouncycastle.openpgp.PGPUtil; import org.bouncycastle.util.test.UncloseableOutputStream; import java.io.ByteArrayInputStream; import java.io.ByteArrayOutputStream; import java.io.FileInputStream; import java.io.InputStream; import java.io.OutputStream; import java.security.Security; import java.util.Date; /** * GPG compatability test vectors */ public class DSA2Test extends TestCase { private static final String TEST_DATA_HOME = "bc.test.data.home"; public void setUp() { if (Security.getProvider("BC") == null) { Security.addProvider(new org.bouncycastle.jce.provider.BouncyCastleProvider()); } } public void testK1024H160() throws Exception { doSigVerifyTest("DSA-1024-160.pub", "dsa-1024-160-sign.gpg"); } public void testK1024H224() throws Exception { doSigVerifyTest("DSA-1024-160.pub", "dsa-1024-224-sign.gpg"); } public void testK1024H256() throws Exception { doSigVerifyTest("DSA-1024-160.pub", "dsa-1024-256-sign.gpg"); } public void testK1024H384() throws Exception { doSigVerifyTest("DSA-1024-160.pub", "dsa-1024-384-sign.gpg"); } public void testK1024H512() throws Exception { doSigVerifyTest("DSA-1024-160.pub", "dsa-1024-512-sign.gpg"); } public void testK2048H224() throws Exception { doSigVerifyTest("DSA-2048-224.pub", "dsa-2048-224-sign.gpg"); } public void testK3072H256() throws Exception { doSigVerifyTest("DSA-3072-256.pub", "dsa-3072-256-sign.gpg"); } public void testK7680H384() throws Exception { doSigVerifyTest("DSA-7680-384.pub", "dsa-7680-384-sign.gpg"); } public void testK15360H512() throws Exception { doSigVerifyTest("DSA-15360-512.pub", "dsa-15360-512-sign.gpg"); } public void testGenerateK1024H224() throws Exception { doSigGenerateTest("DSA-1024-160.sec", "DSA-1024-160.pub", PGPUtil.SHA224); } public void testGenerateK1024H256() throws Exception { doSigGenerateTest("DSA-1024-160.sec", "DSA-1024-160.pub", PGPUtil.SHA256); } public void testGenerateK1024H384() throws Exception { doSigGenerateTest("DSA-1024-160.sec", "DSA-1024-160.pub", PGPUtil.SHA384); } public void testGenerateK1024H512() throws Exception { doSigGenerateTest("DSA-1024-160.sec", "DSA-1024-160.pub", PGPUtil.SHA512); } public void testGenerateK2048H256() throws Exception { doSigGenerateTest("DSA-2048-224.sec", "DSA-2048-224.pub", PGPUtil.SHA256); } public void testGenerateK2048H512() throws Exception { doSigGenerateTest("DSA-2048-224.sec", "DSA-2048-224.pub", PGPUtil.SHA512); } private void doSigGenerateTest(String privateKeyFile, String publicKeyFile, int digest) throws Exception { PGPSecretKeyRing secRing = loadSecretKey(privateKeyFile); PGPPublicKeyRing pubRing = loadPublicKey(publicKeyFile); String data = "hello world!"; ByteArrayOutputStream bOut = new ByteArrayOutputStream(); ByteArrayInputStream testIn = new ByteArrayInputStream(data.getBytes()); PGPSignatureGenerator sGen = new PGPSignatureGenerator(PublicKeyAlgorithmTags.DSA, digest, "BC"); sGen.initSign(PGPSignature.BINARY_DOCUMENT, secRing.getSecretKey().extractPrivateKey("test".toCharArray(), "BC")); BCPGOutputStream bcOut = new BCPGOutputStream(bOut); sGen.generateOnePassVersion(false).encode(bcOut); PGPLiteralDataGenerator lGen = new PGPLiteralDataGenerator(); Date testDate = new Date((System.currentTimeMillis() / 1000) * 1000); OutputStream lOut = lGen.open( new UncloseableOutputStream(bcOut), PGPLiteralData.BINARY, "_CONSOLE", data.getBytes().length, testDate); int ch; while ((ch = testIn.read()) >= 0) { lOut.write(ch); sGen.update((byte)ch); } lGen.close(); sGen.generate().encode(bcOut); PGPObjectFactory pgpFact = new PGPObjectFactory(bOut.toByteArray()); PGPOnePassSignatureList p1 = (PGPOnePassSignatureList)pgpFact.nextObject(); PGPOnePassSignature ops = p1.get(0); assertEquals(digest, ops.getHashAlgorithm()); assertEquals(PublicKeyAlgorithmTags.DSA, ops.getKeyAlgorithm()); PGPLiteralData p2 = (PGPLiteralData)pgpFact.nextObject(); if (!p2.getModificationTime().equals(testDate)) { fail("Modification time not preserved"); } InputStream dIn = p2.getInputStream(); ops.initVerify(pubRing.getPublicKey(), "BC"); while ((ch = dIn.read()) >= 0) { ops.update((byte)ch); } PGPSignatureList p3 = (PGPSignatureList)pgpFact.nextObject(); PGPSignature sig = p3.get(0); assertEquals(digest, sig.getHashAlgorithm()); assertEquals(PublicKeyAlgorithmTags.DSA, sig.getKeyAlgorithm()); assertTrue(ops.verify(sig)); } private void doSigVerifyTest( String publicKeyFile, String sigFile) throws Exception { PGPPublicKeyRing publicKey = loadPublicKey(publicKeyFile); PGPObjectFactory pgpFact = loadSig(sigFile); PGPCompressedData c1 = (PGPCompressedData)pgpFact.nextObject(); pgpFact = new PGPObjectFactory(c1.getDataStream()); PGPOnePassSignatureList p1 = (PGPOnePassSignatureList)pgpFact.nextObject(); PGPOnePassSignature ops = p1.get(0); PGPLiteralData p2 = (PGPLiteralData)pgpFact.nextObject(); InputStream dIn = p2.getInputStream(); ops.initVerify(publicKey.getPublicKey(), "BC"); int ch; while ((ch = dIn.read()) >= 0) { ops.update((byte)ch); } PGPSignatureList p3 = (PGPSignatureList)pgpFact.nextObject(); assertTrue(ops.verify(p3.get(0))); } private PGPObjectFactory loadSig( String sigName) throws Exception { FileInputStream fIn = new FileInputStream(getDataHome() + "/sigs/" + sigName); return new PGPObjectFactory(fIn); } private PGPPublicKeyRing loadPublicKey( String keyName) throws Exception { FileInputStream fIn = new FileInputStream(getDataHome() + "/keys/" + keyName); return new PGPPublicKeyRing(fIn); } private PGPSecretKeyRing loadSecretKey( String keyName) throws Exception { FileInputStream fIn = new FileInputStream(getDataHome() + "/keys/" + keyName); return new PGPSecretKeyRing(fIn); } private String getDataHome() { String dataHome = System.getProperty(TEST_DATA_HOME); if (dataHome == null) { throw new IllegalStateException(TEST_DATA_HOME + " property not set"); } return dataHome + "/openpgp/dsa"; } public static void main (String[] args) throws Exception { junit.textui.TestRunner.run(suite()); } public static Test suite() throws Exception { TestSuite suite = new TestSuite("GPG DSA2 tests"); suite.addTestSuite(DSA2Test.class); return suite; } } bouncycastle-1.49.orig/test/src/org/bouncycastle/openpgp/test/PGPClearSignedSignatureTest.java0000644000175000017500000003627510603373224032241 0ustar ebourgebourgpackage org.bouncycastle.openpgp.test; import org.bouncycastle.bcpg.ArmoredInputStream; import org.bouncycastle.bcpg.ArmoredOutputStream; import org.bouncycastle.bcpg.BCPGOutputStream; import org.bouncycastle.openpgp.PGPException; import org.bouncycastle.openpgp.PGPObjectFactory; import org.bouncycastle.openpgp.PGPPrivateKey; import org.bouncycastle.openpgp.PGPPublicKeyRingCollection; import org.bouncycastle.openpgp.PGPSecretKey; import org.bouncycastle.openpgp.PGPSecretKeyRing; import org.bouncycastle.openpgp.PGPSecretKeyRingCollection; import org.bouncycastle.openpgp.PGPSignature; import org.bouncycastle.openpgp.PGPSignatureGenerator; import org.bouncycastle.openpgp.PGPSignatureList; import org.bouncycastle.openpgp.PGPSignatureSubpacketGenerator; import org.bouncycastle.openpgp.PGPUtil; import org.bouncycastle.util.encoders.Base64; import org.bouncycastle.util.test.SimpleTest; import java.io.ByteArrayInputStream; import java.io.ByteArrayOutputStream; import java.io.IOException; import java.io.InputStream; import java.io.OutputStream; import java.security.SignatureException; import java.util.Iterator; public class PGPClearSignedSignatureTest extends SimpleTest { byte[] publicKey = Base64.decode( "mQELBEQh2+wBCAD26kte0hO6flr7Y2aetpPYutHY4qsmDPy+GwmmqVeCDkX+" + "r1g7DuFbMhVeu0NkKDnVl7GsJ9VarYsFYyqu0NzLa9XS2qlTIkmJV+2/xKa1" + "tzjn18fT/cnAWL88ZLCOWUr241aPVhLuIc6vpHnySpEMkCh4rvMaimnTrKwO" + "42kgeDGd5cXfs4J4ovRcTbc4hmU2BRVsRjiYMZWWx0kkyL2zDVyaJSs4yVX7" + "Jm4/LSR1uC/wDT0IJJuZT/gQPCMJNMEsVCziRgYkAxQK3OWojPSuv4rXpyd4" + "Gvo6IbvyTgIskfpSkCnQtORNLIudQSuK7pW+LkL62N+ohuKdMvdxauOnAAYp" + "tBNnZ2dnZ2dnZyA8Z2dnQGdnZ2c+iQE2BBMBAgAgBQJEIdvsAhsDBgsJCAcD" + "AgQVAggDBBYCAwECHgECF4AACgkQ4M/Ier3f9xagdAf/fbKWBjLQM8xR7JkR" + "P4ri8YKOQPhK+VrddGUD59/wzVnvaGyl9MZE7TXFUeniQq5iXKnm22EQbYch" + "v2Jcxyt2H9yptpzyh4tP6tEHl1C887p2J4qe7F2ATua9CzVGwXQSUbKtj2fg" + "UZP5SsNp25guhPiZdtkf2sHMeiotmykFErzqGMrvOAUThrO63GiYsRk4hF6r" + "cQ01d+EUVpY/sBcCxgNyOiB7a84sDtrxnX5BTEZDTEj8LvuEyEV3TMUuAjx1" + "7Eyd+9JtKzwV4v3hlTaWOvGro9nPS7YaPuG+RtufzXCUJPbPfTjTvtGOqvEz" + "oztls8tuWA0OGHba9XfX9rfgorACAAM="); byte[] secretKey = Base64.decode( "lQOWBEQh2+wBCAD26kte0hO6flr7Y2aetpPYutHY4qsmDPy+GwmmqVeCDkX+" + "r1g7DuFbMhVeu0NkKDnVl7GsJ9VarYsFYyqu0NzLa9XS2qlTIkmJV+2/xKa1" + "tzjn18fT/cnAWL88ZLCOWUr241aPVhLuIc6vpHnySpEMkCh4rvMaimnTrKwO" + "42kgeDGd5cXfs4J4ovRcTbc4hmU2BRVsRjiYMZWWx0kkyL2zDVyaJSs4yVX7" + "Jm4/LSR1uC/wDT0IJJuZT/gQPCMJNMEsVCziRgYkAxQK3OWojPSuv4rXpyd4" + "Gvo6IbvyTgIskfpSkCnQtORNLIudQSuK7pW+LkL62N+ohuKdMvdxauOnAAYp" + "AAf+JCJJeAXEcrTVHotsrRR5idzmg6RK/1MSQUijwPmP7ZGy1BmpAmYUfbxn" + "B56GvXyFV3Pbj9PgyJZGS7cY+l0BF4ZqN9USiQtC9OEpCVT5LVMCFXC/lahC" + "/O3EkjQy0CYK+GwyIXa+Flxcr460L/Hvw2ZEXJZ6/aPdiR+DU1l5h99Zw8V1" + "Y625MpfwN6ufJfqE0HLoqIjlqCfi1iwcKAK2oVx2SwnT1W0NwUUXjagGhD2s" + "VzJVpLqhlwmS0A+RE9Niqrf80/zwE7QNDF2DtHxmMHJ3RY/pfu5u1rrFg9YE" + "lmS60mzOe31CaD8Li0k5YCJBPnmvM9mN3/DWWprSZZKtmQQA96C2/VJF5EWm" + "+/Yxi5J06dG6Bkz311Ui4p2zHm9/4GvTPCIKNpGx9Zn47YFD3tIg3fIBVPOE" + "ktG38pEPx++dSSFF9Ep5UgmYFNOKNUVq3yGpatBtCQBXb1LQLAMBJCJ5TQmk" + "68hMOEaqjMHSOa18cS63INgA6okb/ueAKIHxYQcEAP9DaXu5n9dZQw7pshbN" + "Nu/T5IP0/D/wqM+W5r+j4P1N7PgiAnfKA4JjKrUgl8PGnI2qM/Qu+g3qK++c" + "F1ESHasnJPjvNvY+cfti06xnJVtCB/EBOA2UZkAr//Tqa76xEwYAWRBnO2Y+" + "KIVOT+nMiBFkjPTrNAD6fSr1O4aOueBhBAC6aA35IfjC2h5MYk8+Z+S4io2o" + "mRxUZ/dUuS+kITvWph2e4DT28Xpycpl2n1Pa5dCDO1lRqe/5JnaDYDKqxfmF" + "5tTG8GR4d4nVawwLlifXH5Ll7t5NcukGNMCsGuQAHMy0QHuAaOvMdLs5kGHn" + "8VxfKEVKhVrXsvJSwyXXSBtMtUcRtBNnZ2dnZ2dnZyA8Z2dnQGdnZ2c+iQE2" + "BBMBAgAgBQJEIdvsAhsDBgsJCAcDAgQVAggDBBYCAwECHgECF4AACgkQ4M/I" + "er3f9xagdAf/fbKWBjLQM8xR7JkRP4ri8YKOQPhK+VrddGUD59/wzVnvaGyl" + "9MZE7TXFUeniQq5iXKnm22EQbYchv2Jcxyt2H9yptpzyh4tP6tEHl1C887p2" + "J4qe7F2ATua9CzVGwXQSUbKtj2fgUZP5SsNp25guhPiZdtkf2sHMeiotmykF" + "ErzqGMrvOAUThrO63GiYsRk4hF6rcQ01d+EUVpY/sBcCxgNyOiB7a84sDtrx" + "nX5BTEZDTEj8LvuEyEV3TMUuAjx17Eyd+9JtKzwV4v3hlTaWOvGro9nPS7Ya" + "PuG+RtufzXCUJPbPfTjTvtGOqvEzoztls8tuWA0OGHba9XfX9rfgorACAAA="); String crOnlyMessage = "\r" + " hello world!\r" + "\r" + "- dash\r"; String nlOnlyMessage = "\n" + " hello world!\n" + "\n" + "- dash\n"; String crNlMessage = "\r\n" + " hello world!\r\n" + "\r\n" + "- dash\r\n"; String crOnlySignedMessage = "-----BEGIN PGP SIGNED MESSAGE-----\r" + "Hash: SHA256\r" + "\r" + "\r" + " hello world!\r" + "\r" + "- - dash\r" + "-----BEGIN PGP SIGNATURE-----\r" + "Version: GnuPG v1.4.2.1 (GNU/Linux)\r" + "\r" + "iQEVAwUBRCNS8+DPyHq93/cWAQi6SwgAj3ItmSLr/sd/ixAQLW7/12jzEjfNmFDt\r" + "WOZpJFmXj0fnMzTrOILVnbxHv2Ru+U8Y1K6nhzFSR7d28n31/XGgFtdohDEaFJpx\r" + "Fl+KvASKIonnpEDjFJsPIvT1/G/eCPalwO9IuxaIthmKj0z44SO1VQtmNKxdLAfK\r" + "+xTnXGawXS1WUE4CQGPM45mIGSqXcYrLtJkAg3jtRa8YRUn2d7b2BtmWH+jVaVuC\r" + "hNrXYv7iHFOu25yRWhUQJisvdC13D/gKIPRvARXPgPhAC2kovIy6VS8tDoyG6Hm5\r" + "dMgLEGhmqsgaetVq1ZIuBZj5S4j2apBJCDpF6GBfpBOfwIZs0Tpmlw==\r" + "=84Nd\r" + "-----END PGP SIGNATURE-----\r"; String nlOnlySignedMessage = "-----BEGIN PGP SIGNED MESSAGE-----\n" + "Hash: SHA256\n" + "\n" + "\n" + " hello world!\n" + "\n" + "- - dash\n" + "-----BEGIN PGP SIGNATURE-----\n" + "Version: GnuPG v1.4.2.1 (GNU/Linux)\n" + "\n" + "iQEVAwUBRCNS8+DPyHq93/cWAQi6SwgAj3ItmSLr/sd/ixAQLW7/12jzEjfNmFDt\n" + "WOZpJFmXj0fnMzTrOILVnbxHv2Ru+U8Y1K6nhzFSR7d28n31/XGgFtdohDEaFJpx\n" + "Fl+KvASKIonnpEDjFJsPIvT1/G/eCPalwO9IuxaIthmKj0z44SO1VQtmNKxdLAfK\n" + "+xTnXGawXS1WUE4CQGPM45mIGSqXcYrLtJkAg3jtRa8YRUn2d7b2BtmWH+jVaVuC\n" + "hNrXYv7iHFOu25yRWhUQJisvdC13D/gKIPRvARXPgPhAC2kovIy6VS8tDoyG6Hm5\n" + "dMgLEGhmqsgaetVq1ZIuBZj5S4j2apBJCDpF6GBfpBOfwIZs0Tpmlw==\n" + "=84Nd\n" + "-----END PGP SIGNATURE-----\n"; String crNlSignedMessage = "-----BEGIN PGP SIGNED MESSAGE-----\r\n" + "Hash: SHA256\r\n" + "\r\n" + "\r\n" + " hello world!\r\n" + "\r\n" + "- - dash\r\n" + "-----BEGIN PGP SIGNATURE-----\r\n" + "Version: GnuPG v1.4.2.1 (GNU/Linux)\r\n" + "\r\n" + "iQEVAwUBRCNS8+DPyHq93/cWAQi6SwgAj3ItmSLr/sd/ixAQLW7/12jzEjfNmFDt\r\n" + "WOZpJFmXj0fnMzTrOILVnbxHv2Ru+U8Y1K6nhzFSR7d28n31/XGgFtdohDEaFJpx\r\n" + "Fl+KvASKIonnpEDjFJsPIvT1/G/eCPalwO9IuxaIthmKj0z44SO1VQtmNKxdLAfK\r\n" + "+xTnXGawXS1WUE4CQGPM45mIGSqXcYrLtJkAg3jtRa8YRUn2d7b2BtmWH+jVaVuC\r\n" + "hNrXYv7iHFOu25yRWhUQJisvdC13D/gKIPRvARXPgPhAC2kovIy6VS8tDoyG6Hm5\r\n" + "dMgLEGhmqsgaetVq1ZIuBZj5S4j2apBJCDpF6GBfpBOfwIZs0Tpmlw==\r\n" + "=84Nd\r" + "-----END PGP SIGNATURE-----\r\n"; String crNlSignedMessageTrailingWhiteSpace = "-----BEGIN PGP SIGNED MESSAGE-----\r\n" + "Hash: SHA256\r\n" + "\r\n" + "\r\n" + " hello world! \t\r\n" + "\r\n" + "- - dash\r\n" + "-----BEGIN PGP SIGNATURE-----\r\n" + "Version: GnuPG v1.4.2.1 (GNU/Linux)\r\n" + "\r\n" + "iQEVAwUBRCNS8+DPyHq93/cWAQi6SwgAj3ItmSLr/sd/ixAQLW7/12jzEjfNmFDt\r\n" + "WOZpJFmXj0fnMzTrOILVnbxHv2Ru+U8Y1K6nhzFSR7d28n31/XGgFtdohDEaFJpx\r\n" + "Fl+KvASKIonnpEDjFJsPIvT1/G/eCPalwO9IuxaIthmKj0z44SO1VQtmNKxdLAfK\r\n" + "+xTnXGawXS1WUE4CQGPM45mIGSqXcYrLtJkAg3jtRa8YRUn2d7b2BtmWH+jVaVuC\r\n" + "hNrXYv7iHFOu25yRWhUQJisvdC13D/gKIPRvARXPgPhAC2kovIy6VS8tDoyG6Hm5\r\n" + "dMgLEGhmqsgaetVq1ZIuBZj5S4j2apBJCDpF6GBfpBOfwIZs0Tpmlw==\r\n" + "=84Nd\r" + "-----END PGP SIGNATURE-----\r\n"; public String getName() { return "PGPClearSignedSignature"; } private void messageTest( String message, String type) throws Exception { ArmoredInputStream aIn = new ArmoredInputStream(new ByteArrayInputStream(message.getBytes())); String[] headers = aIn.getArmorHeaders(); if (headers == null || headers.length != 1) { fail("wrong number of headers found"); } if (!"Hash: SHA256".equals(headers[0])) { fail("header value wrong: " + headers[0]); } // // read the input, making sure we ingore the last newline. // ByteArrayOutputStream bOut = new ByteArrayOutputStream(); int ch; while ((ch = aIn.read()) >= 0 && aIn.isClearText()) { bOut.write((byte)ch); } PGPPublicKeyRingCollection pgpRings = new PGPPublicKeyRingCollection(publicKey); PGPObjectFactory pgpFact = new PGPObjectFactory(aIn); PGPSignatureList p3 = (PGPSignatureList)pgpFact.nextObject(); PGPSignature sig = p3.get(0); sig.initVerify(pgpRings.getPublicKey(sig.getKeyID()), "BC"); ByteArrayOutputStream lineOut = new ByteArrayOutputStream(); InputStream sigIn = new ByteArrayInputStream(bOut.toByteArray()); int lookAhead = readInputLine(lineOut, sigIn); processLine(sig, lineOut.toByteArray()); if (lookAhead != -1) { do { lookAhead = readInputLine(lineOut, lookAhead, sigIn); sig.update((byte)'\r'); sig.update((byte)'\n'); processLine(sig, lineOut.toByteArray()); } while (lookAhead != -1); } if (!sig.verify()) { fail("signature failed to verify in " + type); } } private PGPSecretKey readSecretKey( InputStream in) throws IOException, PGPException { PGPSecretKeyRingCollection pgpSec = new PGPSecretKeyRingCollection(in); PGPSecretKey key = null; // // iterate through the key rings. // Iterator rIt = pgpSec.getKeyRings(); while (key == null && rIt.hasNext()) { PGPSecretKeyRing kRing = (PGPSecretKeyRing)rIt.next(); Iterator kIt = kRing.getSecretKeys(); while (key == null && kIt.hasNext()) { PGPSecretKey k = (PGPSecretKey)kIt.next(); if (k.isSigningKey()) { key = k; } } } if (key == null) { throw new IllegalArgumentException("Can't find signing key in key ring."); } return key; } private void generateTest( String message, String type) throws Exception { PGPSecretKey pgpSecKey = readSecretKey(new ByteArrayInputStream(secretKey)); PGPPrivateKey pgpPrivKey = pgpSecKey.extractPrivateKey("".toCharArray(), "BC"); PGPSignatureGenerator sGen = new PGPSignatureGenerator(pgpSecKey.getPublicKey().getAlgorithm(), PGPUtil.SHA256, "BC"); PGPSignatureSubpacketGenerator spGen = new PGPSignatureSubpacketGenerator(); sGen.initSign(PGPSignature.CANONICAL_TEXT_DOCUMENT, pgpPrivKey); Iterator it = pgpSecKey.getPublicKey().getUserIDs(); if (it.hasNext()) { spGen.setSignerUserID(false, (String)it.next()); sGen.setHashedSubpackets(spGen.generate()); } ByteArrayOutputStream bOut = new ByteArrayOutputStream(); ArmoredOutputStream aOut = new ArmoredOutputStream(bOut); ByteArrayInputStream bIn = new ByteArrayInputStream(message.getBytes()); aOut.beginClearText(PGPUtil.SHA256); // // note the last \n in the file is ignored // ByteArrayOutputStream lineOut = new ByteArrayOutputStream(); int lookAhead = readInputLine(lineOut, bIn); processLine(aOut, sGen, lineOut.toByteArray()); if (lookAhead != -1) { do { lookAhead = readInputLine(lineOut, lookAhead, bIn); sGen.update((byte)'\r'); sGen.update((byte)'\n'); processLine(aOut, sGen, lineOut.toByteArray()); } while (lookAhead != -1); } aOut.endClearText(); BCPGOutputStream bcpgOut = new BCPGOutputStream(aOut); sGen.generate().encode(bcpgOut); aOut.close(); messageTest(new String(bOut.toByteArray()), type); } private static int readInputLine(ByteArrayOutputStream bOut, InputStream fIn) throws IOException { bOut.reset(); int lookAhead = -1; int ch; while ((ch = fIn.read()) >= 0) { bOut.write(ch); if (ch == '\r' || ch == '\n') { lookAhead = readPassedEOL(bOut, ch, fIn); break; } } return lookAhead; } private static int readInputLine(ByteArrayOutputStream bOut, int lookAhead, InputStream fIn) throws IOException { bOut.reset(); int ch = lookAhead; do { bOut.write(ch); if (ch == '\r' || ch == '\n') { lookAhead = readPassedEOL(bOut, ch, fIn); break; } } while ((ch = fIn.read()) >= 0); return lookAhead; } private static int readPassedEOL(ByteArrayOutputStream bOut, int lastCh, InputStream fIn) throws IOException { int lookAhead = fIn.read(); if (lastCh == '\r' && lookAhead == '\n') { bOut.write(lookAhead); lookAhead = fIn.read(); } return lookAhead; } private static void processLine(PGPSignature sig, byte[] line) throws SignatureException, IOException { int length = getLengthWithoutWhiteSpace(line); if (length > 0) { sig.update(line, 0, length); } } private static void processLine(OutputStream aOut, PGPSignatureGenerator sGen, byte[] line) throws SignatureException, IOException { int length = getLengthWithoutWhiteSpace(line); if (length > 0) { sGen.update(line, 0, length); } aOut.write(line, 0, line.length); } private static int getLengthWithoutWhiteSpace(byte[] line) { int end = line.length - 1; while (end >= 0 && isWhiteSpace(line[end])) { end--; } return end + 1; } private static boolean isWhiteSpace(byte b) { return b == '\r' || b == '\n' || b == '\t' || b == ' '; } public void performTest() throws Exception { messageTest(crOnlySignedMessage, "\\r"); messageTest(nlOnlySignedMessage, "\\n"); messageTest(crNlSignedMessage, "\\r\\n"); messageTest(crNlSignedMessageTrailingWhiteSpace, "\\r\\n"); generateTest(nlOnlyMessage, "\\r"); generateTest(crOnlyMessage, "\\n"); generateTest(crNlMessage, "\\r\\n"); } public static void main( String[] args) { runTest(new PGPClearSignedSignatureTest()); } } bouncycastle-1.49.orig/test/src/org/bouncycastle/openpgp/test/BcPGPPBETest.java0000644000175000017500000003257011576323542027054 0ustar ebourgebourgpackage org.bouncycastle.openpgp.test; import java.io.ByteArrayOutputStream; import java.io.InputStream; import java.io.OutputStream; import java.security.SecureRandom; import java.security.Security; import java.util.Date; import org.bouncycastle.jce.provider.BouncyCastleProvider; import org.bouncycastle.openpgp.PGPCompressedData; import org.bouncycastle.openpgp.PGPCompressedDataGenerator; import org.bouncycastle.openpgp.PGPEncryptedData; import org.bouncycastle.openpgp.PGPEncryptedDataGenerator; import org.bouncycastle.openpgp.PGPEncryptedDataList; import org.bouncycastle.openpgp.PGPLiteralData; import org.bouncycastle.openpgp.PGPLiteralDataGenerator; import org.bouncycastle.openpgp.PGPObjectFactory; import org.bouncycastle.openpgp.PGPPBEEncryptedData; import org.bouncycastle.openpgp.operator.bc.BcPBEDataDecryptorFactory; import org.bouncycastle.openpgp.operator.bc.BcPBEKeyEncryptionMethodGenerator; import org.bouncycastle.openpgp.operator.bc.BcPGPDataEncryptorBuilder; import org.bouncycastle.openpgp.operator.bc.BcPGPDigestCalculatorProvider; import org.bouncycastle.util.encoders.Base64; import org.bouncycastle.util.encoders.Hex; import org.bouncycastle.util.test.SimpleTest; import org.bouncycastle.util.test.UncloseableOutputStream; public class BcPGPPBETest extends SimpleTest { private static final Date TEST_DATE = new Date(1062200111000L); byte[] enc1 = Base64.decode( "jA0EAwMC5M5wWBP2HBZgySvUwWFAmMRLn7dWiZN6AkQMvpE3b6qwN3SSun7zInw2" + "hxxdgFzVGfbjuB8w"); byte[] enc1crc = Base64.decode("H66L"); char[] pass = { 'h', 'e', 'l', 'l', 'o', ' ', 'w', 'o', 'r', 'l', 'd' }; /** * Message with both PBE and symmetric */ byte[] testPBEAsym = Base64.decode( "hQIOA/ZlQEFWB5vuEAf/covEUaBve7NlWWdiO5NZubdtTHGElEXzG9hyBycp9At8" + "nZGi27xOZtEGFQo7pfz4JySRc3O0s6w7PpjJSonFJyNSxuze2LuqRwFWBYYcbS8/" + "7YcjB6PqutrT939OWsozfNqivI9/QyZCjBvFU89pp7dtUngiZ6MVv81ds2I+vcvk" + "GlIFcxcE1XoCIB3EvbqWNaoOotgEPT60unnB2BeDV1KD3lDRouMIYHfZ3SzBwOOI" + "6aK39sWnY5sAK7JjFvnDAMBdueOiI0Fy+gxbFD/zFDt4cWAVSAGTC4w371iqppmT" + "25TM7zAtCgpiq5IsELPlUZZnXKmnYQ7OCeysF0eeVwf+OFB9fyvCEv/zVQocJCg8" + "fWxfCBlIVFNeNQpeGygn/ZmRaILvB7IXDWP0oOw7/F2Ym66IdYYIp2HeEZv+jFwa" + "l41w5W4BH/gtbwGjFQ6CvF/m+lfUv6ZZdzsMIeEOwhP5g7rXBxrbcnGBaU+PXbho" + "gjDqaYzAWGlrmAd6aPSj51AGeYXkb2T1T/yoJ++M3GvhH4C4hvitamDkksh/qRnM" + "M/s8Nku6z1+RXO3M6p5QC1nlAVqieU8esT43945eSoC77K8WyujDNbysDyUCUTzt" + "p/aoQwe/HgkeOTJNelKR9y2W3xinZLFzep0SqpNI/e468yB/2/LGsykIyQa7JX6r" + "BYwuBAIDAkOKfv5rK8v0YDfnN+eFqwhTcrfBj5rDH7hER6nW3lNWcMataUiHEaMg" + "o6Q0OO1vptIGxW8jClTD4N1sCNwNu9vKny8dKYDDHbCjE06DNTv7XYVW3+JqTL5E" + "BnidvGgOmA=="); /** * decrypt the passed in message stream */ private byte[] decryptMessage( byte[] message, Date date) throws Exception { PGPObjectFactory pgpF = new PGPObjectFactory(message); PGPEncryptedDataList enc = (PGPEncryptedDataList)pgpF.nextObject(); PGPPBEEncryptedData pbe = (PGPPBEEncryptedData)enc.get(0); InputStream clear = pbe.getDataStream(new BcPBEDataDecryptorFactory(pass, new BcPGPDigestCalculatorProvider())); PGPObjectFactory pgpFact = new PGPObjectFactory(clear); PGPCompressedData cData = (PGPCompressedData)pgpFact.nextObject(); pgpFact = new PGPObjectFactory(cData.getDataStream()); PGPLiteralData ld = (PGPLiteralData)pgpFact.nextObject(); ByteArrayOutputStream bOut = new ByteArrayOutputStream(); if (!ld.getFileName().equals("test.txt") && !ld.getFileName().equals("_CONSOLE")) { fail("wrong filename in packet"); } if (!ld.getModificationTime().equals(date)) { fail("wrong modification time in packet: " + ld.getModificationTime().getTime() + " " + date.getTime()); } InputStream unc = ld.getInputStream(); int ch; while ((ch = unc.read()) >= 0) { bOut.write(ch); } if (pbe.isIntegrityProtected() && !pbe.verify()) { fail("integrity check failed"); } return bOut.toByteArray(); } private byte[] decryptMessageBuffered( byte[] message, Date date) throws Exception { PGPObjectFactory pgpF = new PGPObjectFactory(message); PGPEncryptedDataList enc = (PGPEncryptedDataList)pgpF.nextObject(); PGPPBEEncryptedData pbe = (PGPPBEEncryptedData)enc.get(0); InputStream clear = pbe.getDataStream(new BcPBEDataDecryptorFactory(pass, new BcPGPDigestCalculatorProvider())); PGPObjectFactory pgpFact = new PGPObjectFactory(clear); PGPCompressedData cData = (PGPCompressedData)pgpFact.nextObject(); pgpFact = new PGPObjectFactory(cData.getDataStream()); PGPLiteralData ld = (PGPLiteralData)pgpFact.nextObject(); ByteArrayOutputStream bOut = new ByteArrayOutputStream(); if (!ld.getFileName().equals("test.txt") && !ld.getFileName().equals("_CONSOLE")) { fail("wrong filename in packet"); } if (!ld.getModificationTime().equals(date)) { fail("wrong modification time in packet: " + ld.getModificationTime().getTime() + " " + date.getTime()); } InputStream unc = ld.getInputStream(); byte[] buf = new byte[1024]; int len; while ((len = unc.read(buf)) >= 0) { bOut.write(buf, 0, len); } if (pbe.isIntegrityProtected() && !pbe.verify()) { fail("integrity check failed"); } return bOut.toByteArray(); } public void performTest() throws Exception { byte[] out = decryptMessage(enc1, TEST_DATE); if (out[0] != 'h' || out[1] != 'e' || out[2] != 'l') { fail("wrong plain text in packet"); } // // create a PBE encrypted message and read it back. // byte[] text = { (byte)'h', (byte)'e', (byte)'l', (byte)'l', (byte)'o', (byte)' ', (byte)'w', (byte)'o', (byte)'r', (byte)'l', (byte)'d', (byte)'!', (byte)'\n' }; // // encryption step - convert to literal data, compress, encode. // ByteArrayOutputStream bOut = new ByteArrayOutputStream(); PGPCompressedDataGenerator comData = new PGPCompressedDataGenerator( PGPCompressedData.ZIP); Date cDate = new Date((System.currentTimeMillis() / 1000) * 1000); PGPLiteralDataGenerator lData = new PGPLiteralDataGenerator(); OutputStream comOut = comData.open(new UncloseableOutputStream(bOut)); OutputStream ldOut = lData.open( new UncloseableOutputStream(comOut), PGPLiteralData.BINARY, PGPLiteralData.CONSOLE, text.length, cDate); ldOut.write(text); ldOut.close(); comOut.close(); // // encrypt - with stream close // ByteArrayOutputStream cbOut = new ByteArrayOutputStream(); PGPEncryptedDataGenerator cPk = new PGPEncryptedDataGenerator(new BcPGPDataEncryptorBuilder(PGPEncryptedData.CAST5).setSecureRandom(new SecureRandom())); cPk.addMethod(new BcPBEKeyEncryptionMethodGenerator(pass)); OutputStream cOut = cPk.open(new UncloseableOutputStream(cbOut), bOut.toByteArray().length); cOut.write(bOut.toByteArray()); cOut.close(); out = decryptMessage(cbOut.toByteArray(), cDate); if (!areEqual(out, text)) { fail("wrong plain text in generated packet"); } // // encrypt - with generator close // cbOut = new ByteArrayOutputStream(); cPk = new PGPEncryptedDataGenerator(new BcPGPDataEncryptorBuilder(PGPEncryptedData.CAST5).setSecureRandom(new SecureRandom())); cPk.addMethod(new BcPBEKeyEncryptionMethodGenerator(pass)); cOut = cPk.open(new UncloseableOutputStream(cbOut), bOut.toByteArray().length); cOut.write(bOut.toByteArray()); cPk.close(); out = decryptMessage(cbOut.toByteArray(), cDate); if (!areEqual(out, text)) { fail("wrong plain text in generated packet"); } // // encrypt - partial packet style. // SecureRandom rand = new SecureRandom(); byte[] test = new byte[1233]; rand.nextBytes(test); bOut = new ByteArrayOutputStream(); comData = new PGPCompressedDataGenerator( PGPCompressedData.ZIP); comOut = comData.open(bOut); lData = new PGPLiteralDataGenerator(); ldOut = lData.open(new UncloseableOutputStream(comOut), PGPLiteralData.BINARY, PGPLiteralData.CONSOLE, TEST_DATE, new byte[16]); ldOut.write(test); ldOut.close(); comOut.close(); cbOut = new ByteArrayOutputStream(); cPk = new PGPEncryptedDataGenerator(new BcPGPDataEncryptorBuilder(PGPEncryptedData.CAST5).setSecureRandom(rand)); cPk.addMethod(new BcPBEKeyEncryptionMethodGenerator(pass)); cOut = cPk.open(new UncloseableOutputStream(cbOut), new byte[16]); cOut.write(bOut.toByteArray()); cOut.close(); out = decryptMessage(cbOut.toByteArray(), TEST_DATE); if (!areEqual(out, test)) { fail("wrong plain text in generated packet"); } // // with integrity packet // cbOut = new ByteArrayOutputStream(); cPk = new PGPEncryptedDataGenerator(new BcPGPDataEncryptorBuilder(PGPEncryptedData.CAST5).setWithIntegrityPacket(true).setSecureRandom(rand)); cPk.addMethod(new BcPBEKeyEncryptionMethodGenerator(pass)); cOut = cPk.open(new UncloseableOutputStream(cbOut), new byte[16]); cOut.write(bOut.toByteArray()); cOut.close(); out = decryptMessage(cbOut.toByteArray(), TEST_DATE); if (!areEqual(out, test)) { fail("wrong plain text in generated packet"); } // // decrypt with buffering // out = decryptMessageBuffered(cbOut.toByteArray(), TEST_DATE); if (!areEqual(out, test)) { fail("wrong plain text in buffer generated packet"); } // // sample message // PGPObjectFactory pgpFact = new PGPObjectFactory(testPBEAsym); PGPEncryptedDataList enc = (PGPEncryptedDataList)pgpFact.nextObject(); PGPPBEEncryptedData pbe = (PGPPBEEncryptedData)enc.get(1); InputStream clear = pbe.getDataStream(new BcPBEDataDecryptorFactory("password".toCharArray(), new BcPGPDigestCalculatorProvider())); pgpFact = new PGPObjectFactory(clear); PGPLiteralData ld = (PGPLiteralData)pgpFact.nextObject(); bOut = new ByteArrayOutputStream(); InputStream unc = ld.getInputStream(); int ch; while ((ch = unc.read()) >= 0) { bOut.write(ch); } if (!areEqual(bOut.toByteArray(), Hex.decode("5361742031302e30322e30370d0a"))) { fail("data mismatch on combined PBE"); } // // with integrity packet - one byte message // byte[] msg = new byte[1]; bOut = new ByteArrayOutputStream(); comData = new PGPCompressedDataGenerator( PGPCompressedData.ZIP); lData = new PGPLiteralDataGenerator(); comOut = comData.open(new UncloseableOutputStream(bOut)); ldOut = lData.open( new UncloseableOutputStream(comOut), PGPLiteralData.BINARY, PGPLiteralData.CONSOLE, msg.length, cDate); ldOut.write(msg); ldOut.close(); comOut.close(); cbOut = new ByteArrayOutputStream(); cPk = new PGPEncryptedDataGenerator(new BcPGPDataEncryptorBuilder(PGPEncryptedData.CAST5).setWithIntegrityPacket(true).setSecureRandom(rand)); cPk.addMethod(new BcPBEKeyEncryptionMethodGenerator(pass)); cOut = cPk.open(new UncloseableOutputStream(cbOut), new byte[16]); cOut.write(bOut.toByteArray()); cOut.close(); out = decryptMessage(cbOut.toByteArray(), cDate); if (!areEqual(out, msg)) { fail("wrong plain text in generated packet"); } // // decrypt with buffering // out = decryptMessageBuffered(cbOut.toByteArray(), cDate); if (!areEqual(out, msg)) { fail("wrong plain text in buffer generated packet"); } } public String getName() { return "BcPGPPBETest"; } public static void main( String[] args) { Security.addProvider(new BouncyCastleProvider()); runTest(new BcPGPPBETest()); } } bouncycastle-1.49.orig/test/src/org/bouncycastle/openpgp/test/BcPGPKeyRingTest.java0000644000175000017500000034132112104711535030002 0ustar ebourgebourgpackage org.bouncycastle.openpgp.test; import java.io.ByteArrayInputStream; import java.math.BigInteger; import java.security.KeyPair; import java.security.KeyPairGenerator; import java.security.SecureRandom; import java.security.Security; import java.util.Date; import java.util.Iterator; import org.bouncycastle.jce.provider.BouncyCastleProvider; import org.bouncycastle.jce.spec.ElGamalParameterSpec; import org.bouncycastle.openpgp.PGPEncryptedData; import org.bouncycastle.openpgp.PGPException; import org.bouncycastle.openpgp.PGPKeyPair; import org.bouncycastle.openpgp.PGPKeyRingGenerator; import org.bouncycastle.openpgp.PGPPrivateKey; import org.bouncycastle.openpgp.PGPPublicKey; import org.bouncycastle.openpgp.PGPPublicKeyRing; import org.bouncycastle.openpgp.PGPPublicKeyRingCollection; import org.bouncycastle.openpgp.PGPSecretKey; import org.bouncycastle.openpgp.PGPSecretKeyRing; import org.bouncycastle.openpgp.PGPSecretKeyRingCollection; import org.bouncycastle.openpgp.PGPSignature; import org.bouncycastle.openpgp.operator.bc.BcKeyFingerprintCalculator; import org.bouncycastle.openpgp.operator.bc.BcPBESecretKeyDecryptorBuilder; import org.bouncycastle.openpgp.operator.bc.BcPGPContentVerifierBuilderProvider; import org.bouncycastle.openpgp.operator.bc.BcPGPDigestCalculatorProvider; import org.bouncycastle.util.encoders.Base64; import org.bouncycastle.util.encoders.Hex; import org.bouncycastle.util.test.SimpleTest; public class BcPGPKeyRingTest extends SimpleTest { byte[] pub1 = Base64.decode( "mQGiBEA83v0RBADzKVLVCnpWQxX0LCsevw/3OLs0H7MOcLBQ4wMO9sYmzGYn" + "xpVj+4e4PiCP7QBayWyy4lugL6Lnw7tESvq3A4v3fefcxaCTkJrryiKn4+Cg" + "y5rIBbrSKNtCEhVi7xjtdnDjP5kFKgHYjVOeIKn4Cz/yzPG3qz75kDknldLf" + "yHxp2wCgwW1vAE5EnZU4/UmY7l8kTNkMltMEAJP4/uY4zcRwLI9Q2raPqAOJ" + "TYLd7h+3k/BxI0gIw96niQ3KmUZDlobbWBI+VHM6H99vcttKU3BgevNf8M9G" + "x/AbtW3SS4De64wNSU3189XDG8vXf0vuyW/K6Pcrb8exJWY0E1zZQ1WXT0gZ" + "W0kH3g5ro//Tusuil9q2lVLF2ovJA/0W+57bPzi318dWeNs0tTq6Njbc/GTG" + "FUAVJ8Ss5v2u6h7gyJ1DB334ExF/UdqZGldp0ugkEXaSwBa2R7d3HBgaYcoP" + "Ck1TrovZzEY8gm7JNVy7GW6mdOZuDOHTxyADEEP2JPxh6eRcZbzhGuJuYIif" + "IIeLOTI5Dc4XKeV32a+bWrQidGVzdCAoVGVzdCBrZXkpIDx0ZXN0QHViaWNh" + "bGwuY29tPohkBBMRAgAkBQJAPN79AhsDBQkB4TOABgsJCAcDAgMVAgMDFgIB" + "Ah4BAheAAAoJEJh8Njfhe8KmGDcAoJWr8xgPr75y/Cp1kKn12oCCOb8zAJ4p" + "xSvk4K6tB2jYbdeSrmoWBZLdMLACAAC5AQ0EQDzfARAEAJeUAPvUzJJbKcc5" + "5Iyb13+Gfb8xBWE3HinQzhGr1v6A1aIZbRj47UPAD/tQxwz8VAwJySx82ggN" + "LxCk4jW9YtTL3uZqfczsJngV25GoIN10f4/j2BVqZAaX3q79a3eMiql1T0oE" + "AGmD7tO1LkTvWfm3VvA0+t8/6ZeRLEiIqAOHAAQNBACD0mVMlAUgd7REYy/1" + "mL99Zlu9XU0uKyUex99sJNrcx1aj8rIiZtWaHz6CN1XptdwpDeSYEOFZ0PSu" + "qH9ByM3OfjU/ya0//xdvhwYXupn6P1Kep85efMBA9jUv/DeBOzRWMFG6sC6y" + "k8NGG7Swea7EHKeQI40G3jgO/+xANtMyTIhPBBgRAgAPBQJAPN8BAhsMBQkB" + "4TOAAAoJEJh8Njfhe8KmG7kAn00mTPGJCWqmskmzgdzeky5fWd7rAKCNCp3u" + "ZJhfg0htdgAfIy8ppm05vLACAAA="); byte[] sec1 = Base64.decode( "lQHhBEA83v0RBADzKVLVCnpWQxX0LCsevw/3OLs0H7MOcLBQ4wMO9sYmzGYn" + "xpVj+4e4PiCP7QBayWyy4lugL6Lnw7tESvq3A4v3fefcxaCTkJrryiKn4+Cg" + "y5rIBbrSKNtCEhVi7xjtdnDjP5kFKgHYjVOeIKn4Cz/yzPG3qz75kDknldLf" + "yHxp2wCgwW1vAE5EnZU4/UmY7l8kTNkMltMEAJP4/uY4zcRwLI9Q2raPqAOJ" + "TYLd7h+3k/BxI0gIw96niQ3KmUZDlobbWBI+VHM6H99vcttKU3BgevNf8M9G" + "x/AbtW3SS4De64wNSU3189XDG8vXf0vuyW/K6Pcrb8exJWY0E1zZQ1WXT0gZ" + "W0kH3g5ro//Tusuil9q2lVLF2ovJA/0W+57bPzi318dWeNs0tTq6Njbc/GTG" + "FUAVJ8Ss5v2u6h7gyJ1DB334ExF/UdqZGldp0ugkEXaSwBa2R7d3HBgaYcoP" + "Ck1TrovZzEY8gm7JNVy7GW6mdOZuDOHTxyADEEP2JPxh6eRcZbzhGuJuYIif" + "IIeLOTI5Dc4XKeV32a+bWv4CAwJ5KgazImo+sGBfMhDiBcBTqyDGhKHNgHic" + "0Pky9FeRvfXTc2AO+jGmFPjcs8BnTWuDD0/jkQnRZpp1TrQidGVzdCAoVGVz" + "dCBrZXkpIDx0ZXN0QHViaWNhbGwuY29tPohkBBMRAgAkBQJAPN79AhsDBQkB" + "4TOABgsJCAcDAgMVAgMDFgIBAh4BAheAAAoJEJh8Njfhe8KmGDcAn3XeXDMg" + "BZgrZzFWU2IKtA/5LG2TAJ0Vf/jjyq0jZNZfGfoqGTvD2MAl0rACAACdAVgE" + "QDzfARAEAJeUAPvUzJJbKcc55Iyb13+Gfb8xBWE3HinQzhGr1v6A1aIZbRj4" + "7UPAD/tQxwz8VAwJySx82ggNLxCk4jW9YtTL3uZqfczsJngV25GoIN10f4/j" + "2BVqZAaX3q79a3eMiql1T0oEAGmD7tO1LkTvWfm3VvA0+t8/6ZeRLEiIqAOH" + "AAQNBACD0mVMlAUgd7REYy/1mL99Zlu9XU0uKyUex99sJNrcx1aj8rIiZtWa" + "Hz6CN1XptdwpDeSYEOFZ0PSuqH9ByM3OfjU/ya0//xdvhwYXupn6P1Kep85e" + "fMBA9jUv/DeBOzRWMFG6sC6yk8NGG7Swea7EHKeQI40G3jgO/+xANtMyTP4C" + "AwJ5KgazImo+sGBl2C7CFuI+5KM4ZhbtVie7l+OiTpr5JW2z5VgnV3EX9p04" + "LcGKfQvD65+ELwli6yh8B2zGcipqTaYk3QoYNIhPBBgRAgAPBQJAPN8BAhsM" + "BQkB4TOAAAoJEJh8Njfhe8KmG7kAniuRkaFFv1pdCBN8JJXpcorHmyouAJ9L" + "xxmusffR6OI7WgD3XZ0AL8zUC7ACAAA="); char[] pass1 = "qwertzuiop".toCharArray(); byte[] pub2 = Base64.decode( "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"); byte[] sec2 = Base64.decode( "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" + "Nifs+ljmsAFn"); char[] sec2pass1 = "sandhya".toCharArray(); char[] sec2pass2 = "psai".toCharArray(); byte[] pub3 = Base64.decode( "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" + "n3FaE6UZE9GMDmCIAjhI+0X9aH6CsAIAAw=="); byte[] sec3 = Base64.decode( "lQHhBEB9BH0RBACtYQtE7tna6hgGyGLpq+ds3r2cLC0ISn5dNw7tm9vwiNVF" + "JA2N37RRrifw4PvgelRSvLaX3M3ZBqC9s1Metg3v4FSlIRtSLWCNpHSvNw7i" + "X8C2Xy9Hdlbh6Y/50o+iscojLRE14upfR1bIkcCZQGSyvGV52V2wBImUUZjV" + "s2ZngwCg7mu852vK7+euz4WaL7ERVYtq9CMEAJ5swrljerDpz/RQ4Lhp6KER" + "KyuI0PUttO57xINGshEINgYlZdGaZHRueHe7uKfI19mb0T4N3NJWaZ0wF+Cn" + "rixsq0VrTUfiwfZeGluNG73aTCeY45fVXMGTTSYXzS8T0LW100Xn/0g9HRyA" + "xUpuWo8IazxkMqHJis2uwriYKpAfA/9anvj5BS9p5pfPjp9dGM7GTMIYl5f2" + "fcP57f+AW1TVR6IZiMJAvAdeWuLtwLnJiFpGlnFz273pfl+sAuqm1yNceImR" + "2SDDP4+vtyycWy8nZhgEuhZx3W3cWMQz5WyNJSY1JJHh9TCQkCoN8E7XpVP4" + "zEPboB2GzD93mfD8JLHP+/4DAwIvYrn+YqRaaGAu19XUj895g/GROyP8WEaU" + "Bd/JNqWc4kE/0guetGnPzq7G3bLVwiKfFd4X7BrgHAo3mrQtVGVzdCBLZXkg" + "KG5vIGNvbW1lbnQpIDx0ZXN0QGJvdW5jeWNhc3RsZS5vcmc+iFkEExECABkF" + "AkB9BH0ECwcDAgMVAgMDFgIBAh4BAheAAAoJEKnMV8vjZQOpSRQAoKZy6YS1" + "irF5/Q3JlWiwbkN6dEuLAJ9lldRLOlXsuQ5JW1+SLEc6K9ho4rACAADRwXPB" + "cQEQAAEBAAAAAAAAAAAAAAAA/9j/4AAQSkZJRgABAQEASABIAAD//gAXQ3Jl" + "YXRlZCB3aXRoIFRoZSBHSU1Q/9sAQwAIBgYHBgUIBwcHCQkICgwUDQwLCwwZ" + "EhMPFB0aHx4dGhwcICQuJyAiLCMcHCg3KSwwMTQ0NB8nOT04MjwuMzQy/9sA" + "QwEJCQkMCwwYDQ0YMiEcITIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIy" + "MjIyMjIyMjIyMjIyMjIyMjIyMjIy/8AAEQgAFAAUAwEiAAIRAQMRAf/EABoA" + "AQACAwEAAAAAAAAAAAAAAAAEBQIDBgf/xAAoEAABAgUDBAEFAAAAAAAAAAAB" + "AgMABBEhMQUSQQYTIiNhFFGBkcH/xAAXAQEAAwAAAAAAAAAAAAAAAAAEAgMF" + "/8QAJBEAAQQAAwkAAAAAAAAAAAAAAQACERIEIfATMTJBUZGx0fH/2gAMAwEA" + "AhEDEQA/APMuotJlJVxstqaPo22NlAUp+YsNO0qSUtBcMu6n6EtOHcfPAHHF" + "I16++oajQtTA3DapK02HFR8UpE9pTbQWtKm2WG2rlxVyQTcfGbn7Qm0OIjL7" + "7Wrs2NNm9lzTmmSxQ0PX4opSprk5tmESF6syggzGwOLG6gXgHFbZhBixk8Xl" + "IDcOQLRKt+rX+3qC5ZLTQblpQlvwvxn9CMpZturVGkJHapQJphRH8hCLXbzr" + "qpYsCx1zC5rtpJNuYQhASc0UAQv/2YhcBBMRAgAcBQJAfQV+AhsDBAsHAwID" + "FQIDAxYCAQIeAQIXgAAKCRCpzFfL42UDqfa2AJ9hjtEeDTbTEAuuSbzhYFxN" + "/qc0FACgsmzysdbBpuN65yK01tbEaeIMtqCwAgAAnQEUBEB9BH4QAwCqRuWO" + "rxm5v/8WWBtPEUZnYuu3WYxefRKn6ON5ka5Ymp4AfKpKqKqn982tjlG13GVE" + "P2ow11L4yQKGNm+VyVEapm7SpMD0SHg9vsJygAWrfMJnBYWSgE19W6o3ckUR" + "sWsAAwYDAKDCSiSxC3Z5/POaCehw5iHs/vmVk5Wn831LSZEEwkSohNDbIEry" + "ia/9tFXSt11AP4stJtZ0MH87/6JBbiIRD4JXcx+zfzchL7Teczr/06QMphSn" + "sAENupbhLupfpR+BbP4DAwIvYrn+YqRaaGBjvFK1fbxCt7ZM4I2W/3BC0lCX" + "m/NypKNspGflec8u96uUlA0fNCnxm6f9nbB0jpvoKi0g4iqAf+P2iEYEGBEC" + "AAYFAkB9BH4ACgkQqcxXy+NlA6mtMgCgvccZA/Sg7BXVpxli47SYhxSHoM4A" + "oNCOMplSnYTuh5ikKeBWtz36gC1psAIAAA=="); char[] sec3pass1 = "123456".toCharArray(); // // GPG comment packets. // byte[] sec4 = Base64.decode( "lQG7BD0PbK8RBAC0cW4Y2MZXmAmqYp5Txyw0kSQsFvwZKHNMFRv996IsN57URVF5" + "BGMVPRBi9dNucWbjiSYpiYN13wE9IuLZsvVaQojV4XWGRDc+Rxz9ElsXnsYQ3mZU" + "7H1bNQEofstChk4z+dlvPBN4GFahrIzn/CeVUn6Ut7dVdYbiTqviANqNXwCglfVA" + "2OEePvqFnGxs1jhJyPSOnTED/RwRvsLH/k43mk6UEvOyN1RIpBXN+Ieqs7h1gFrQ" + "kB+WMgeP5ZUsotTffVDSUS9UMxRQggVUW1Xml0geGwQsNfkr/ztWMs/T4xp1v5j+" + "QyJx6OqNlkGdqOsoqkzJx0SQ1zBxdinFyyC4H95SDAb/RQOu5LQmxFG7quexztMs" + "infEA/9cVc9+qCo92yRAaXRqKNVVQIQuPxeUsGMyVeJQvJBD4An8KTMCdjpF10Cp" + "qA3t+n1S0zKr5WRUtvS6y60MOONO+EJWVWBNkx8HJDaIMNkfoqQoz3Krn7w6FE/v" + "/5uwMd6jY3N3yJZn5nDZT9Yzv9Nx3j+BrY+henRlSU0c6xDc9QAAnjJYg0Z83VJG" + "6HrBcgc4+4K6lHulCqH9JiM6RFNBX2ZhY3RvcjoAAK9hV206agp99GI6x5qE9+pU" + "vs6O+Ich/SYjOkRTQV9mYWN0b3I6AACvYAfGn2FGrpBYbjnpTuFOHJMS/T5xg/0m" + "IzpEU0FfZmFjdG9yOgAAr0dAQz6XxMwxWIn8xIZR/v2iN2L9C6O0EkZvbyBCYXIg" + "PGJhekBxdXV4PohXBBMRAgAXBQI9D2yvBQsHCgMEAxUDAgMWAgECF4AACgkQUGLI" + "YCIktfoGogCfZiXMJUKrScqozv5tMwzTTk2AaT8AniM5iRr0Du/Y08SL/NMhtF6H" + "hJ89nO4EPQ9ssRADAI6Ggxj6ZBfoavuXd/ye99osW8HsNlbqhXObu5mCMNySX2wa" + "HoWyRUEaUkI9eQw+MlHzIwzA32E7y2mU3OQBKdgLcBg4jxtcWVEg8ESKF9MpFXxl" + "pExxWrr4DFBfCRcsTwAFEQL9G3OvwJuEZXgx2JSS41D3pG4/qiHYICVa0u3p/14i" + "cq0kXajIk5ZJ6frCIAHIzuQ3n7jjzr05yR8s/qCrNbBA+nlkVNa/samk+jCzxxxa" + "cR/Dbh2wkvTFuDFFETwQYLuZAADcDck4YGQAmHivVT2NNDCf/aTz0+CJWl+xRc2l" + "Qw7D/SQjOkVMR19mYWN0b3I6AACbBnv9m5/bb/pjYAm2PtDp0CysQ9X9JCM6RUxH" + "X2ZhY3RvcjoAAJsFyHnSmaWguTFf6lJ/j39LtUNtmf0kIzpFTEdfZmFjdG9yOgAA" + "mwfwMD3LxmWtuCWBE9BptWMNH07Z/SQjOkVMR19mYWN0b3I6AACbBdhBrbSiM4UN" + "y7khDW2Sk0e4v9mIRgQYEQIABgUCPQ9ssQAKCRBQYshgIiS1+jCMAJ9txwHnb1Kl" + "6i/fSoDs8SkdM7w48wCdFvPEV0sSxE73073YhBgPZtMWbBo="); // // PGP freeware version 7 // byte[] pub5 = Base64.decode( "mQENBEBrBE4BCACjXVcNIFDQSofaIyZnALb2CRg+WY9uUqgHEEAOlPe03Cs5STM5" + "HDlNmrh4TdFceJ46rxk1mQOjULES1YfHay8lCIzrD7FX4oj0r4DC14Fs1vXaSar2" + "1szIpttOw3obL4A1e0p6N4jjsoG7N/pA0fEL0lSw92SoBrMbAheXRg4qNTZvdjOR" + "grcuOuwgJRvPLtRXlhyLBoyhkd5mmrIDGv8QHJ/UjpeIcRXY9kn9oGXnEYcRbMaU" + "VwXB4pLzWqz3ZejFI3lOxRWjm760puPOnGYlzSVBxlt2LgzUgSj1Mn+lIpWmAzsa" + "xEiU4xUwEomQns72yYRZ6D3euNCibcte4SeXABEBAAG0KXBhbGFzaCBrYXNvZGhh" + "biA8cGthc29kaGFuQHRpYWEtY3JlZi5vcmc+iQEuBBABAgAYBQJAawROCAsBAwkI" + "BwIKAhkBBRsDAAAAAAoJEOfelumuiOrYqPEH+wYrdP5Tq5j+E5yN1pyCg1rwbSOt" + "Dka0y0p7Oq/VIGLk692IWPItLEunnBXQtGBcWqklrvogvlhxtf16FgoyScfLJx1e" + "1cJa+QQnVuH+VOESN6iS9Gp9lUfVOHv74mEMXw0l2Djfy/lnrkAMBatggyGnF9xF" + "VXOLk1J2WVFm9KUE23o6qdB7RGkf31pN2eA7SWmkdJSkUH7o/QSFBI+UTRZ/IY5P" + "ZIJpsdiIOqd9YMG/4RoSZuPqNRR6x7BSs8nQVR9bYs4PPlp4GfdRnOcRonoTeJCZ" + "83RnsraWJnJTg34gRLBcqumhTuFKc8nuCNK98D6zkQESdcHLLTquCOaF5L+5AQ0E" + "QGsETwEIAOVwNCTaDZvW4dowPbET1bI5UeYY8rAGLYsWSUfgaFv2srMiApyBVltf" + "i6OLcPjcUCHDBjCv4pwx/C4qcHWb8av4xQIpqQXOpO9NxYE1eZnel/QB7DtH12ZO" + "nrDNmHtaXlulcKNGe1i1utlFhgzfFx6rWkRL0ENmkTkaQmPY4gTGymJTUhBbsSRq" + "2ivWqQA1TPwBuda73UgslIAHRd/SUaxjXoLpMbGOTeqzcKGjr5XMPTs7/YgBpWPP" + "UxMlEQIiU3ia1bxpEhx05k97ceK6TSH2oCPQA7gumjxOSjKT+jEm+8jACVzymEmc" + "XRy4D5Ztqkw/Z16pvNcu1DI5m6xHwr8AEQEAAYkBIgQYAQIADAUCQGsETwUbDAAA" + "AAAKCRDn3pbprojq2EynB/4/cEOtKbI5UisUd3vkTzvWOcqWUqGqi5wjjioNtIM5" + "pur2nFvhQE7SZ+PbAa87HRJU/4WcWMcoLkHD48JrQwHCHOLHSV5muYowb78X4Yh9" + "epYtSJ0uUahcn4Gp48p4BkhgsPYXkxEImSYzAOWStv21/7WEMqItMYl89BV6Upm8" + "HyTJx5MPTDbMR7X51hRg3OeQs6po3WTCWRzFIMyGm1rd/VK1L5ZDFPqO3S6YUJ0z" + "cxecYruvfK0Wp7q834wE8Zkl/PQ3NhfEPL1ZiLr/L00Ty+77/FZqt8SHRCICzOfP" + "OawcVGI+xHVXW6lijMpB5VaVIH8i2KdBMHXHtduIkPr9"); byte[] sec5 = Base64.decode( "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"); char[] sec5pass1 = "12345678".toCharArray(); // // Werner Koch "odd keys" // byte[] pub6 = Base64.decode( "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" + "L4Kb7TWkd/OHQScVBO8sTUz0+2g="); byte[] pub6check = Base64.decode("62O9"); // // revoked sub key // byte[] pub7 = Base64.decode( "mQGiBEFOsIwRBADcjRx7nAs4RaWsQU6p8/ECLZD9sSeYc6CN6UDI96RKj0/hCzMs" + "qlA0+9fzGZ7ZEJ34nuvDKlhKGC7co5eOiE0a9EijxgcrZU/LClZWa4YfyNg/ri6I" + "yTyfOfrPQ33GNQt2iImDf3FKp7XKuY9nIxicGQEaW0kkuAmbV3oh0+9q8QCg/+fS" + "epDEqEE/+nKONULGizKUjMED/RtL6RThRftZ9DOSdBytGYd48z35pca/qZ6HA36K" + "PVQwi7V77VKQyKFLTOXPLnVyO85hyYB/Nv4DFHN+vcC7/49lfoyYMZlN+LarckHi" + "NL154wmmzygB/KKysvWBLgkErEBCD0xBDd89iTQNlDtVQAWGORVffl6WWjOAkliG" + "3dL6A/9A288HfFRnywqi3xddriV6wCPmStC3dkCS4vHk2ofS8uw4ZNoRlp1iEPna" + "ai2Xa9DX1tkhaGk2k96MqqbBdGpbW8sMA9otJ9xdMjWEm/CgJUFUFQf3zaVy3mkM" + "S2Lvb6P4Wc2l/diEEIyK8+PqJItSh0OVU3K9oM7ngHwVcalKILQVUkV2b2tlZCA8" + "UmV2b2tlZEB0ZWQ+iQBOBBARAgAOBQJBTrCMBAsDAgECGQEACgkQvglkcFA/c63+" + "QgCguh8rsJbPTtbhZcrqBi5Mo1bntLEAoPZQ0Kjmu2knRUpHBeUemHDB6zQeuQIN" + "BEFOsIwQCAD2Qle3CH8IF3KiutapQvMF6PlTETlPtvFuuUs4INoBp1ajFOmPQFXz" + "0AfGy0OplK33TGSGSfgMg71l6RfUodNQ+PVZX9x2Uk89PY3bzpnhV5JZzf24rnRP" + "xfx2vIPFRzBhznzJZv8V+bv9kV7HAarTW56NoKVyOtQa8L9GAFgr5fSI/VhOSdvN" + "ILSd5JEHNmszbDgNRR0PfIizHHxbLY7288kjwEPwpVsYjY67VYy4XTjTNP18F1dD" + "ox0YbN4zISy1Kv884bEpQBgRjXyEpwpy1obEAxnIByl6ypUM2Zafq9AKUJsCRtMI" + "PWakXUGfnHy9iUsiGSa6q6Jew1XpMgs7AAICB/93zriSvSHqsi1FeEmUBo431Jkh" + "VerIzb6Plb1j6FIq+s3vyvx9K+dMvjotZqylWZj4GXpH+2xLJTjWkrGSfUZVI2Nk" + "nyOFxUCKLLqaqVBFAQIjULfvQfGEWiGQKk9aRLkdG+D+8Y2N9zYoBXoQ9arvvS/t" + "4mlOsiuaTe+BZ4x+BXTpF4b9sKZl7V8QP/TkoJWUdydkvxciHdWp7ssqyiKOFRhG" + "818knDfFQ3cn2w/RnOb+7AF9wDncXDPYLfpPv9b2qZoLrXcyvlLffGDUdWs553ut" + "1F5AprMURs8BGmY9BnjggfVubHdhTUoA4gVvrdaf+D9NwZAl0xK/5Y/oPuMZiQBG" + "BBgRAgAGBQJBTrCMAAoJEL4JZHBQP3Ot09gAoMmLKloVDP+WhDXnsM5VikxysZ4+" + "AKCrJAUO+lYAyPYwEwgK+bKmUGeKrIkARgQoEQIABgUCQU6wpQAKCRC+CWRwUD9z" + "rQK4AJ98kKFxGU6yhHPr6jYBJPWemTNOXgCfeGB3ox4PXeS4DJDuLy9yllytOjo="); byte[] pub7check = Base64.decode("f/YQ"); byte[] pub8 = Base64.decode( "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" + "9Uqz3fUvGoewAWA="); byte[] sec8 = Base64.decode( "lQHpBEEcraYRBADFYj+uFOhHz5SdECvJ3Z03P47gzmWLQ5HH8fPYC9rrv7AgqFFX" + "aWlJJVMLua9e6xoCiDWJs/n4BbZ/weL/11ELg6XqUnzFhYyz0H2KFsPgQ/b9lWLY" + "MtcPMFy5jE33hv/ixHgYLFqoNaAIbg0lzYEW/otQ9IhRl16fO1Q/CQZZrQCg/9M2" + "V2BTmm9RYog86CXJtjawRBcD/RIqU0zulxZ2Zt4javKVxrGIwW3iBU935ebmJEIK" + "Y5EVkGKBOCvsApZ+RGzpYeR2uMsTnQi8RJgiAnjaoVPCdsVJE7uQ0h8XuJ5n5mJ2" + "kLCFlF2hj5ViicZzse+crC12CGtgRe8z23ubLRcd6IUGhVutK8/b5knZ22vE14JD" + "ykKdA/96ObzJQdiuuPsEWN799nUUCaYWPAoLAmiXuICSP4GEnxLbYHWo8zhMrVMT" + "9Q5x3h8cszUz7Acu2BXjP1m96msUNoxPOZtt88NlaFz1Q/JSbQTsVOMd9b/IRN6S" + "A/uU0BiKEMHXuT8HUHVPK49oCKhZrGFP3RT8HZxDKLmR/qrgZ/4JAwLXyWhb4pf4" + "nmCmD0lDwoYvatLiR7UQVM2MamxClIiT0lCPN9C2AYIFgRWAJNS215Tjx7P/dh7e" + "8sYfh5XEHErT3dMbsAGHtCFKaWEgWWl5dSA8eXlqaWFAbm93bWVkaWF0ZWNoLmNv" + "bT6wAwP//4kAXQQQEQIAHQUCQRytpgcLCQgHAwIKAhkBBRsDAAAABR4BAAAAAAoJ" + "EPT+Vvgr/2IUmWEAoJEyJ9B7CJfmjwVTT30UbdCctVRmAJ9akw6we6UYd82vF0FK" + "QTlSuqHXKbABZ50CawRBHK2mEAgA9kJXtwh/CBdyorrWqULzBej5UxE5T7bxbrlL" + "OCDaAadWoxTpj0BV89AHxstDqZSt90xkhkn4DIO9ZekX1KHTUPj1WV/cdlJPPT2N" + "286Z4VeSWc39uK50T8X8dryDxUcwYc58yWb/Ffm7/ZFexwGq01uejaClcjrUGvC/" + "RgBYK+X0iP1YTknbzSC0neSRBzZrM2w4DUUdD3yIsxx8Wy2O9vPJI8BD8KVbGI2O" + "u1WMuF040zT9fBdXQ6MdGGzeMyEstSr/POGxKUAYEY18hKcKctaGxAMZyAcpesqV" + "DNmWn6vQClCbAkbTCD1mpF1Bn5x8vYlLIhkmuquiXsNV6TILOwACAgf/crbApFLO" + "QikN9lHbn62dDxuu/dNigNmjf/A3cX+vo8aPHTXnRDyDwQALRuqbitdbM6p1LFjG" + "8g84Aabk/jL7zzjJLqPe8pxeK1Pu+P44NzalXAYMsOOsxGuixIrz3Jw8IrpH/mkP" + "tG/iX0NaLZ+Au9eokdLb+6NR/a51r2qL3E0ycFciJ61HzZKKHi6d0VQ7CHozCz+j" + "d5530Mh1qq/ZjYDDjfP+snpyNIZXcLtGR/3HzkBqNgDcvClLx3322AWKDa7pX8DX" + "qiLr8znWhPRpH9kCTnSpRzhYGT25FRcvdj4/q/oUIET/Tp+BWW3BxAc7WgpgqEfn" + "fa0Mv72Zbn91gf4JAwITijME9IlFBGAwH6YmBtWIlnDiRbsq/Pxozuhbnes831il" + "KmdpUKXkiIfHY0MqrEWl3Dfn6PMJGTnhgqXMrDxx3uHrq0Jl2swRnAWIIO8gID7j" + "uPetUqEviPiwAYeJAEwEGBECAAwFAkEcraYFGwwAAAAACgkQ9P5W+Cv/YhShrgCg" + "+JW8m5nF3R/oZGuG87bXQBszkjMAoLhGPncuGKowJXMRVc70/8qwXQJLsAFn"); char[] sec8pass = "qwertyui".toCharArray(); byte[] sec9 = Base64.decode( "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" + "6neEEX/i1Q=="); public char[] sec9pass = "foo".toCharArray(); // version 4 keys with expiry dates byte[] pub10 = Base64.decode( "mQGiBEKqia0RBACc3hkufmscRSC4UvPZqMDsHm4+d/GXIr+3iNMSSEySJu8yk+k0" + "Xs11C/K+n+v1rnn2jGGknv+1lDY6w75TIcTE6o6HGKeIDxsAm8P3MhoGU1GNPamA" + "eTDeNybtrN/g6C65fCY9uI11hsUboYgQZ8ND22PB0VtvdOgq9D85qNUzxwCg1BbJ" + "ycAKd4VqEvQ2Zglp3dCSrFMD/Ambq1kZqYa69sp3b9BPKuAgUgUPoytOArEej3Bk" + "easAgAxNhWJy4GxigES3vk50rVi7w8XBuqbD1mQCzldF0HX0/A7PxLBv6od5uqqF" + "HFxIyxg/KBZLd9ZOrsSaoUWH58jZq98X/sFtJtRi5VuJagMxCIJD4mLgtMv7Unlb" + "/GrsA/9DEnObA/fNTgK70T+ZmPIS5tSt+bio30Aw4YGpPCGqpnm1u73b5kqX3U3B" + "P+vGDvFuqZYpqQA8byAueH0MbaDHI4CFugvShXvgysJxN7ov7/8qsZZUMfK1t2Nr" + "SAsPuKRbcY4gNKXIElKeXbyaET7vX7uAEKuxEwdYGFp/lNTkHLQgdGVzdCBrZXkg" + "KHRlc3QpIDx0ZXN0QHRlc3QudGVzdD6IZAQTEQIAJAUCQqqJrQIbAwUJACTqAAYL" + "CQgHAwIDFQIDAxYCAQIeAQIXgAAKCRDjDROQZRqIzDzLAJ42AeCRIBBjv8r8qw9y" + "laNj2GZ1sACgiWYHVXMA6B1H9I1kS3YsCd3Oq7qwAgAAuM0EQqqJrhADAKWkix8l" + "pJN7MMTXob4xFF1TvGll0UD1bDGOMMbes6aeXSbT9QXee/fH3GnijLY7wB+qTPv9" + "ohubrSpnv3yen3CEBW6Q2YK+NlCskma42Py8YMV2idmYjtJi1ckvHFWt5wADBQL/" + "fkB5Q5xSGgspMaTZmtmX3zG7ZDeZ0avP8e8mRL8UszCTpqs6vMZrXwyQLZPbtMYv" + "PQpuRGEeKj0ysimwYRA5rrLQjnRER3nyuuEUUgc4j+aeRxPf9WVsJ/a1FCHtaAP1" + "iE8EGBECAA8FAkKqia4CGwwFCQAk6gAACgkQ4w0TkGUaiMzdqgCfd66H7DL7kFGd" + "IoS+NIp8JO+noxAAn25si4QAF7og8+4T5YQUuhIhx/NesAIAAA=="); byte[] sec10 = Base64.decode( "lQHhBEKqia0RBACc3hkufmscRSC4UvPZqMDsHm4+d/GXIr+3iNMSSEySJu8yk+k0" + "Xs11C/K+n+v1rnn2jGGknv+1lDY6w75TIcTE6o6HGKeIDxsAm8P3MhoGU1GNPamA" + "eTDeNybtrN/g6C65fCY9uI11hsUboYgQZ8ND22PB0VtvdOgq9D85qNUzxwCg1BbJ" + "ycAKd4VqEvQ2Zglp3dCSrFMD/Ambq1kZqYa69sp3b9BPKuAgUgUPoytOArEej3Bk" + "easAgAxNhWJy4GxigES3vk50rVi7w8XBuqbD1mQCzldF0HX0/A7PxLBv6od5uqqF" + "HFxIyxg/KBZLd9ZOrsSaoUWH58jZq98X/sFtJtRi5VuJagMxCIJD4mLgtMv7Unlb" + "/GrsA/9DEnObA/fNTgK70T+ZmPIS5tSt+bio30Aw4YGpPCGqpnm1u73b5kqX3U3B" + "P+vGDvFuqZYpqQA8byAueH0MbaDHI4CFugvShXvgysJxN7ov7/8qsZZUMfK1t2Nr" + "SAsPuKRbcY4gNKXIElKeXbyaET7vX7uAEKuxEwdYGFp/lNTkHP4DAwLssmOjVC+d" + "mWB783Lpzjb9evKzsxisTdx8/jHpUSS+r//6/Guyx3aA/zUw5bbftItW57mhuNNb" + "JTu7WrQgdGVzdCBrZXkgKHRlc3QpIDx0ZXN0QHRlc3QudGVzdD6IZAQTEQIAJAUC" + "QqqJrQIbAwUJACTqAAYLCQgHAwIDFQIDAxYCAQIeAQIXgAAKCRDjDROQZRqIzDzL" + "AJ0cYPwKeoSReY14LqJtAjnkX7URHACgsRZWfpbalrSyDnq3TtZeGPUqGX+wAgAA" + "nQEUBEKqia4QAwClpIsfJaSTezDE16G+MRRdU7xpZdFA9WwxjjDG3rOmnl0m0/UF" + "3nv3x9xp4oy2O8Afqkz7/aIbm60qZ798np9whAVukNmCvjZQrJJmuNj8vGDFdonZ" + "mI7SYtXJLxxVrecAAwUC/35AeUOcUhoLKTGk2ZrZl98xu2Q3mdGrz/HvJkS/FLMw" + "k6arOrzGa18MkC2T27TGLz0KbkRhHio9MrIpsGEQOa6y0I50REd58rrhFFIHOI/m" + "nkcT3/VlbCf2tRQh7WgD9f4DAwLssmOjVC+dmWDXVLRopzxbBGOvodp/LZoSDb56" + "gNJjDMJ1aXqWW9qTAg1CFjBq73J3oFpVzInXZ8+Q8inxv7bnWiHbiE8EGBECAA8F" + "AkKqia4CGwwFCQAk6gAACgkQ4w0TkGUaiMzdqgCgl2jw5hfk/JsyjulQqe1Nps1q" + "Lx0AoMdnFMZmTMLHn8scUW2j9XO312tmsAIAAA=="); public char[] sec10pass = "test".toCharArray(); public byte[] subKeyBindingKey = Base64.decode( "mQGiBDWagYwRBAD7UcH4TAIp7tmUoHBNxVxCVz2ZrNo79M6fV63riOiH2uDxfIpr" + "IrL0cM4ehEKoqlhngjDhX60eJrOw1nC5BpYZRnDnyDYT4wTWRguxObzGq9pqA1dM" + "oPTJhkFZVIBgFY99/ULRqaUYIhFGgBtnwS70J8/L/PGVc3DmWRLMkTDjSQCg/5Nh" + "MCjMK++MdYMcMl/ziaKRT6EEAOtw6PnU9afdohbpx9CK4UvCCEagfbnUtkSCQKSk" + "6cUp6VsqyzY0pai/BwJ3h4apFMMMpVrtBAtchVgqo4xTr0Sve2j0k+ase6FSImiB" + "g+AR7hvTUTcBjwtIExBc8TuCTqmn4GG8F7UMdl5Z0AZYj/FfAQYaRVZYP/pRVFNx" + "Lw65BAC/Fi3qgiGCJFvXnHIckTfcAmZnKSEXWY9NJ4YQb4+/nH7Vsw0wR/ZObUHR" + "bWgTc9Vw1uZIMe0XVj6Yk1dhGRehUnrm3mE7UJxu7pgkBCbFECFSlSSqP4MEJwZV" + "09YP/msu50kjoxyoTpt+16uX/8B4at24GF1aTHBxwDLd8X0QWrQsTWVycmlsbCBM" + "eW5jaCBDTEVBUiBzeXN0ZW0gREggPGNsZWFyQG1sLmNvbT6JAEsEEBECAAsFAjWa" + "gYwECwMBAgAKCRDyAGjiP47/XanfAKCs6BPURWVQlGh635VgL+pdkUVNUwCdFcNa" + "1isw+eAcopXPMj6ACOapepu5Ag0ENZqBlBAIAPZCV7cIfwgXcqK61qlC8wXo+VMR" + "OU+28W65Szgg2gGnVqMU6Y9AVfPQB8bLQ6mUrfdMZIZJ+AyDvWXpF9Sh01D49Vlf" + "3HZSTz09jdvOmeFXklnN/biudE/F/Ha8g8VHMGHOfMlm/xX5u/2RXscBqtNbno2g" + "pXI61Brwv0YAWCvl9Ij9WE5J280gtJ3kkQc2azNsOA1FHQ98iLMcfFstjvbzySPA" + "Q/ClWxiNjrtVjLhdONM0/XwXV0OjHRhs3jMhLLUq/zzhsSlAGBGNfISnCnLWhsQD" + "GcgHKXrKlQzZlp+r0ApQmwJG0wg9ZqRdQZ+cfL2JSyIZJrqrol7DVekyCzsAAgIH" + "/RYtVo+HROZ6jrNjrATEwQm1fUQrk6n5+2dniN881lF0CNkB4NkHw1Xxz4Ejnu/0" + "iLg8fkOAsmanOsKpOkRtqUnVpsVL5mLJpFEyCY5jbcfj+KY9/25bs0ga7kLHNZia" + "zbCxJdF+W179z3nudQxRaXG/0XISIH7ziZbSVni69sKc1osk1+OoOMbSuZ86z535" + "Pln4fXclkFE927HxfbWoO+60hkOLKh7x+8fC82b3x9vCETujEaxrscO2xS7/MYXP" + "8t1ffriTDmhuIuQS2q4fLgeWdqrODrMhrD8Dq7e558gzp30ZCqpiS7EmKGczL7B8" + "gXxbBCVSTxYMJheXt2xMXsuJAD8DBRg1moGU8gBo4j+O/10RAgWdAKCPhaFIXuC8" + "/cdiNMxTDw9ug3De5QCfYXmDzRSFUu/nrCi8yz/l09wsnxo="); public byte[] subKeyBindingCheckSum = Base64.decode("3HU+"); // // PGP8 with SHA1 checksum. // public byte[] rewrapKey = Base64.decode( "lQOWBEUPOQgBCADdjPTtl8oOwqJFA5WU8p7oDK5KRWfmXeXUZr+ZJipemY5RSvAM" + "rxqsM47LKYbmXOJznXCQ8+PPa+VxXAsI1CXFHIFqrXSwvB/DUmb4Ec9EuvNd18Zl" + "hJAybzmV2KMkaUp9oG/DUvxZJqkpUddNfwqZu0KKKZWF5gwW5Oy05VCpaJxQVXFS" + "whdbRfwEENJiNx4RB3OlWhIjY2p+TgZfgQjiGB9i15R+37sV7TqzBUZF4WWcnIRQ" + "DnpUfxHgxQ0wO/h/aooyRHSpIx5i4oNpMYq9FNIyakEx/Bomdbs5hW9dFxhrE8Es" + "UViAYITgTsyROxmgGatGG09dcmVDJVYF4i7JAAYpAAf/VnVyUDs8HrxYTOIt4rYY" + "jIHToBsV0IiLpA8fEA7k078L1MwSwERVVe6oHVTjeR4A9OxE52Vroh2eOLnF3ftf" + "6QThVVZr+gr5qeG3yvQ36N7PXNEVOlkyBzGmFQNe4oCA+NR2iqnAIspnekVmwJV6" + "xVvPCjWw/A7ZArDARpfthspwNcJAp4SWfoa2eKzvUTznTyqFu2PSS5fwQZUgOB0P" + "Y2FNaKeqV8vEZu4SUWwLOqXBQIZXiaLvdKNgwFvUe3kSHdCNsrVzW7SYxFwaEog2" + "o6YLKPVPqjlGX1cMOponGp+7n9nDYkQjtEsGSSMQkQRDAcBdSVJmLO07kFOQSOhL" + "WQQA49BcgTZyhyH6TnDBMBHsGCYj43FnBigypGT9FrQHoWybfX47yZaZFROAaaMa" + "U6man50YcYZPwzDzXHrK2MoGALY+DzB3mGeXVB45D/KYtlMHPLgntV9T5b14Scbc" + "w1ES2OUtsSIUs0zelkoXqjLuKnSIYK3mMb67Au7AEp6LXM8EAPj2NypvC86VEnn+" + "FH0QHvUwBpmDw0EZe25xQs0brvAG00uIbiZnTH66qsIfRhXV/gbKK9J5DTGIqQ15" + "DuPpz7lcxg/n2+SmjQLNfXCnG8hmtBjhTe+udXAUrmIcfafXyu68SAtebgm1ga56" + "zUfqsgN3FFuMUffLl3myjyGsg5DnA/oCFWL4WCNClOgL6A5VkNIUait8QtSdCACT" + "Y7jdSOguSNXfln0QT5lTv+q1AjU7zjRl/LsFNmIJ5g2qdDyK937FOXM44FEEjZty" + "/4P2dzYpThUI4QUohIj8Qi9f2pZQueC5ztH6rpqANv9geZKcciAeAbZ8Md0K2TEU" + "RD3Lh+RSBzILtBtUZXN0IEtleSA8dGVzdEBleGFtcGxlLmNvbT6JATYEEwECACAF" + "AkUPOQgCGwMGCwkIBwMCBBUCCAMEFgIDAQIeAQIXgAAKCRDYpknHeQaskD9NB/9W" + "EbFuLaqZAl3yjLU5+vb75BdvcfL1lUs44LZVwobNp3/0XbZdY76xVPNZURtU4u3L" + "sJfGlaF+EqZDE0Mqc+vs5SIb0OnCzNJ00KaUFraUtkByRV32T5ECHK0gMBjCs5RT" + "I0vVv+Qmzl4+X1Y2bJ2mlpBejHIrOzrBD5NTJimTAzyfnNfipmbqL8p/cxXKKzS+" + "OM++ZFNACj6lRM1W9GioXnivBRC88gFSQ4/GXc8yjcrMlKA27JxV+SZ9kRWwKH2f" + "6o6mojUQxnHr+ZFKUpo6ocvTgBDlC57d8IpwJeZ2TvqD6EdA8rZ0YriVjxGMDrX1" + "8esfw+iLchfEwXtBIRwS"); char[] rewrapPass = "voltage123".toCharArray(); byte[] pubWithX509 = Base64.decode( "mQENBERabjABCACtmfyo6Nph9MQjv4nmCWjZrRYnhXbivomAdIwYkLZUj1bjqE+j"+ "uaLzjZV8xSI59odZvrmOiqlzOc4txitQ1OX7nRgbOJ7qku0dvwjtIn46+HQ+cAFn"+ "2mTi81RyXEpO2uiZXfsNTxUtMi+ZuFLufiMc2kdk27GZYWEuasdAPOaPJnA+wW6i"+ "ZHlt0NfXIGNz864gRwhD07fmBIr1dMFfATWxCbgMd/rH7Z/j4rvceHD2n9yrhPze"+ "YN7W4Nuhsr2w/Ft5Cm9xO7vXT/cpto45uxn8f7jERep6bnUwNOhH8G+6xLQgTLD0"+ "qFBGVSIneK3lobs6+xn6VaGN8W0tH3UOaxA1ABEBAAG0D0NOPXFhLWRlZXBzaWdo"+ "dIkFDgQQZAIFAQUCRFpuMAUDCWdU0gMF/3gCGwPELGQBAQQwggTkMIIDzKADAgEC"+ "AhBVUMV/M6rIiE+IzmnPheQWMA0GCSqGSIb3DQEBBQUAMG4xEzARBgoJkiaJk/Is"+ "ZAEZFgNjb20xEjAQBgoJkiaJk/IsZAEZFgJxYTEVMBMGCgmSJomT8ixkARkWBXRt"+ "czAxMRUwEwYKCZImiZPyLGQBGRYFV2ViZmUxFTATBgNVBAMTDHFhLWRlZXBzaWdo"+ "dDAeFw0wNjA1MDQyMTEyMTZaFw0xMTA1MDQyMTIwMDJaMG4xEzARBgoJkiaJk/Is"+ "ZAEZFgNjb20xEjAQBgoJkiaJk/IsZAEZFgJxYTEVMBMGCgmSJomT8ixkARkWBXRt"+ "czAxMRUwEwYKCZImiZPyLGQBGRYFV2ViZmUxFTATBgNVBAMTDHFhLWRlZXBzaWdo"+ "dDCCASIwDQYJKoZIhvcNAQEBBQADggEPADCCAQoCggEBAK2Z/Kjo2mH0xCO/ieYJ"+ "aNmtFieFduK+iYB0jBiQtlSPVuOoT6O5ovONlXzFIjn2h1m+uY6KqXM5zi3GK1DU"+ "5fudGBs4nuqS7R2/CO0ifjr4dD5wAWfaZOLzVHJcSk7a6Jld+w1PFS0yL5m4Uu5+"+ "IxzaR2TbsZlhYS5qx0A85o8mcD7BbqJkeW3Q19cgY3PzriBHCEPTt+YEivV0wV8B"+ "NbEJuAx3+sftn+Piu9x4cPaf3KuE/N5g3tbg26GyvbD8W3kKb3E7u9dP9ym2jjm7"+ "Gfx/uMRF6npudTA06Efwb7rEtCBMsPSoUEZVIid4reWhuzr7GfpVoY3xbS0fdQ5r"+ "EDUCAwEAAaOCAXwwggF4MAsGA1UdDwQEAwIBhjAPBgNVHRMBAf8EBTADAQH/MB0G"+ "A1UdDgQWBBSmFTRv5y65DHtTYae48zl0ExNWZzCCASUGA1UdHwSCARwwggEYMIIB"+ "FKCCARCgggEMhoHFbGRhcDovLy9DTj1xYS1kZWVwc2lnaHQsQ049cWEtd3VtYW4x"+ "LWRjLENOPUNEUCxDTj1QdWJsaWMlMjBLZXklMjBTZXJ2aWNlcyxDTj1TZXJ2aWNl"+ "cyxDTj1Db25maWd1cmF0aW9uLERDPVdlYmZlLERDPXRtczAxLERDPXFhLERDPWNv"+ "bT9jZXJ0aWZpY2F0ZVJldm9jYXRpb25MaXN0P2Jhc2U/b2JqZWN0Q2xhc3M9Y1JM"+ "RGlzdHJpYnV0aW9uUG9pbnSGQmh0dHA6Ly9xYS13dW1hbjEtZGMud2ViZmUudG1z"+ "MDEucWEuY29tL0NlcnRFbnJvbGwvcWEtZGVlcHNpZ2h0LmNybDAQBgkrBgEEAYI3"+ "FQEEAwIBADANBgkqhkiG9w0BAQUFAAOCAQEAfuZCW3XlB7Eok35zQbvYt9rhAndT"+ "DNw3wPNI4ZzD1nXoYWnwhNNvWRpsOt4ExOSNdaHErfgDXAMyyg66Sro0TkAx8eAj"+ "fPQsyRAh0nm0glzFmJN6TdOZbj7hqGZjc4opQ6nZo8h/ULnaEwMIUW4gcSkZt0ww"+ "CuErl5NUrN3DpkREeCG/fVvQZ8ays3ibQ5ZCZnYBkLYq/i0r3NLW34WfYhjDY48J"+ "oQWtvFSAxvRfz2NGmqnrCHPQZxqlfdta97kDa4VQ0zSeBaC70gZkLmD1GJMxWoXW"+ "6tmEcgPY5SghInUf+L2u52V55MjyAFzVp7kTK2KY+p7qw35vzckrWkwu8AAAAAAA"+ "AQE="); private static byte[] secWithPersonalCertificate = Base64.decode( "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" + "cGdwbWltZQULBwgJAgIZAQUbAQAAAAUeAQAAAAIVAgAKCRDlTa3BE84gWVKW" + "BACcoCFKvph9r9QiHT1Z3N4wZH36Uxqu/059EFALnBkEdVudX/p6S9mynGRk" + "EfhmWFC1O6dMpnt+ZBEed/4XyFWVSLPwirML+6dxfXogdUsdFF1NCRHc3QGc" + "txnNUT/zcZ9IRIQjUhp6RkIvJPHcyfTXKSbLviI+PxzHU2Padq8pV7ABZ7kA" + "jQRIfg8tAQQAutJR/aRnfZYwlVv+KlUDYjG8YQUfHpTxpnmVu7W6N0tNg/Xr" + "5dg50wq3I4HOamRxUwHpdPkXyNF1szpDSRZmlM+VmiIvJDBnyH5YVlxT6+zO" + "8LUJ2VTbfPxoLFp539SQ0oJOm7IGMAGO7c0n/QV0N3hKUfWgCyJ+sENDa0Ft" + "JycAEQEAAbABj4kEzQQYAQIENwUCSMYtnAUJAeEzgMLFFAAAAAAAFwNleDUw" + "OWNlcnRpZmljYXRlQHBncC5jb20wggNhMIICyqADAgECAgkA1AoCoRKJCgsw" + "DQYJKoZIhvcNAQEFBQAwgakxCzAJBgNVBAYTAkNaMRcwFQYDVQQIEw5DemVj" + "aCBSZXB1YmxpYzESMBAGA1UEChQJQSYmTCBzb2Z0MSAwHgYDVQQLExdJbnRl" + "cm5hbCBEZXZlbG9wbWVudCBDQTEqMCgGA1UEAxQhQSYmTCBzb2Z0IEludGVy" + "bmFsIERldmVsb3BtZW50IENBMR8wHQYJKoZIhvcNAQkBFhBrYWRsZWNAYWxz" + "b2Z0LmN6MB4XDTA4MDcxNjE1MDkzM1oXDTA5MDcxNjE1MDkzM1owaTELMAkG" + "A1UEBhMCQ1oxFzAVBgNVBAgTDkN6ZWNoIFJlcHVibGljMRIwEAYDVQQKFAlB" + "JiZMIHNvZnQxFDASBgNVBAsTC0RldmVsb3BtZW50MRcwFQYDVQQDEw5IeW5l" + "ay1JbnRyYW5ldDCBnzANBgkqhkiG9w0BAQEFAAOBjQAwgYkCgYEAutJR/aRn" + "fZYwlVv+KlUDYjG8YQUfHpTxpnmVu7W6N0tNg/Xr5dg50wq3I4HOamRxUwHp" + "dPkXyNF1szpDSRZmlM+VmiIvJDBnyH5YVlxT6+zO8LUJ2VTbfPxoLFp539SQ" + "0oJOm7IGMAGO7c0n/QV0N3hKUfWgCyJ+sENDa0FtJycCAwEAAaOBzzCBzDAJ" + "BgNVHRMEAjAAMCwGCWCGSAGG+EIBDQQfFh1PcGVuU1NMIEdlbmVyYXRlZCBD" + "ZXJ0aWZpY2F0ZTAdBgNVHQ4EFgQUNaw7A6r10PtYZzAvr9CrSKeRYJgwHwYD" + "VR0jBBgwFoAUmqSRM8rN3+T1+tkGiqef8S5suYgwGgYDVR0RBBMwEYEPaHlu" + "ZWtAYWxzb2Z0LmN6MCgGA1UdHwQhMB8wHaAboBmGF2h0dHA6Ly9wZXRyazIv" + "Y2EvY2EuY3JsMAsGA1UdDwQEAwIF4DANBgkqhkiG9w0BAQUFAAOBgQCUdOWd" + "7mBLWj1/GSiYgfwgdTrgk/VZOJvMKBiiFyy1iFEzldz6Xx+mAexnFJKfZXZb" + "EMEGWHfWPmgJzAtuTT0Jz6tUwDmeLH3MP4m8uOZtmyUJ2aq41kciV3rGxF0G" + "BVlZ/bWTaOzHdm6cjylt6xxLt6MJzpPBA/9ZfybSBh1DaAUbDgAAAJ0gBBkB" + "AgAGBQJIxi2bAAoJEAdYkEWLb2R2fJED/RK+JErZ98uGo3Z81cHkdP3rk8is" + "DUL/PR3odBPFH2SIA5wrzklteLK/ZXmBUzcvxqHEgI1F7goXbsBgeTuGgZdx" + "pINErxkNpcMl9FTldWKGiapKrhkZ+G8knDizF/Y7Lg6uGd2nKVxzutLXdHJZ" + "pU89Q5nzq6aJFAZo5TBIcchQAAoJEOVNrcETziBZXvQD/1mvFqBfWqwXxoj3" + "8fHUuFrE2pcp32y3ciO2i+uNVEkNDoaVVNw5eHQaXXWpllI/Pe6LnBl4vkyc" + "n3pjONa4PKrePkEsCUhRbIySqXIHuNwZumDOlKzZHDpCUw72LaC6S6zwuoEf" + "ucOcxTeGIUViANWXyTIKkHfo7HfigixJIL8nsAFn"); private static final byte[] umlautKeySig = Base64.decode( "mI0ETdvOgQEEALoI2a39TRk1HReEB6DP9Bu3ShZUce+/Oeg9RIL9aUFuCsNdhu02" + "REEHjO29Jz8daPgrnJDfFepNLD6iKKru2m9P30qnhsHMIAshO2Ozfh6wKwuHRqR3" + "L4gBDu7cCB6SLwPoD8AYG0yQSM+Do10Td87RlStxCgxpMK6R3TsRkxcFABEBAAG0" + "OlVNTEFVVFNUQVJUOsOEw6TDlsO2w5zDvMOfOlVNTEFURU5ERSA8YXNkbGFrc2Rs" + "QGFrc2RqLmNvbT6IuAQTAQIAIgUCTdvOgQIbAwYLCQgHAwIGFQgCCQoLBBYCAwEC" + "HgECF4AACgkQP8kDwm8AOFiArAP/ZXrlZJB1jFEjyBb04ckpE6F/aJuSYIXf0Yx5" + "T2eS+lA69vYuqKRC1qNROBrAn/WGNOQBFNEgGoy3F3gV5NgpIphnyIEZdZWGY2rv" + "yjunKWlioZjWc/xbSbvpvJ3Q8RyfDXBOkDEB6uF1ksimw2eJSOUTkF9AQfS5f4rT" + "5gs013G4jQRN286BAQQApVbjd8UhsQLB4TpeKn9+dDXAfikGgxDOb19XisjRiWxA" + "+bKFxu5tRt6fxXl6BGSGT7DhoVbNkcJGVQFYcbR31UGKCVYcWSL3yfz+PiVuf1UB" + "Rp44cXxxqxrLqKp1rk3dGvV4Ayy8lkk3ncDGPez6lIKvj3832yVtAzUOX1QOg9EA" + "EQEAAYifBBgBAgAJBQJN286BAhsMAAoJED/JA8JvADhYQ80D/R3TX0FBMHs/xqEh" + "tiS86XP/8pW6eMm2eaAYINxoDY3jmDMv2HFQ+YgrYXgqGr6eVGqDMNPj4W8VBoOt" + "iYW7+SWY76AAl+gmWIMm2jbN8bZXFk4jmIxpycHCrtoXX8rUk/0+se8NvbmAdMGK" + "POOoD7oxdRmJSU5hSspOCHrCwCa3"); public void test1() throws Exception { PGPPublicKeyRingCollection pubRings = new PGPPublicKeyRingCollection(pub1); int count = 0; Iterator rIt = pubRings.getKeyRings(); while (rIt.hasNext()) { PGPPublicKeyRing pgpPub = (PGPPublicKeyRing)rIt.next(); count++; int keyCount = 0; byte[] bytes = pgpPub.getEncoded(); pgpPub = new PGPPublicKeyRing(bytes, new BcKeyFingerprintCalculator()); Iterator it = pgpPub.getPublicKeys(); while (it.hasNext()) { keyCount++; PGPPublicKey pubKey = (PGPPublicKey)it.next(); Iterator sIt = pubKey.getSignatures(); while (sIt.hasNext()) { ((PGPSignature)sIt.next()).getSignatureType(); } } if (keyCount != 2) { fail("wrong number of public keys"); } } if (count != 1) { fail("wrong number of public keyrings"); } // // exact match // rIt = pubRings.getKeyRings("test (Test key) "); count = 0; while (rIt.hasNext()) { count++; rIt.next(); } if (count != 1) { fail("wrong number of public keyrings on exact match"); } // // partial match 1 expected // rIt = pubRings.getKeyRings("test", true); count = 0; while (rIt.hasNext()) { count++; rIt.next(); } if (count != 1) { fail("wrong number of public keyrings on partial match 1"); } // // partial match 0 expected // rIt = pubRings.getKeyRings("XXX", true); count = 0; while (rIt.hasNext()) { count++; rIt.next(); } if (count != 0) { fail("wrong number of public keyrings on partial match 0"); } // // case-insensitive partial match // rIt = pubRings.getKeyRings("TEST@ubicall.com", true, true); count = 0; while (rIt.hasNext()) { count++; rIt.next(); } if (count != 1) { fail("wrong number of public keyrings on case-insensitive partial match"); } PGPSecretKeyRingCollection secretRings = new PGPSecretKeyRingCollection(sec1); rIt = secretRings.getKeyRings(); count = 0; while (rIt.hasNext()) { PGPSecretKeyRing pgpSec = (PGPSecretKeyRing)rIt.next(); count++; int keyCount = 0; byte[] bytes = pgpSec.getEncoded(); pgpSec = new PGPSecretKeyRing(bytes); Iterator it = pgpSec.getSecretKeys(); while (it.hasNext()) { keyCount++; PGPSecretKey k = (PGPSecretKey)it.next(); PGPPublicKey pk = k.getPublicKey(); pk.getSignatures(); byte[] pkBytes = pk.getEncoded(); PGPPublicKeyRing pkR = new PGPPublicKeyRing(pkBytes, new BcKeyFingerprintCalculator()); } if (keyCount != 2) { fail("wrong number of secret keys"); } } if (count != 1) { fail("wrong number of secret keyrings"); } // // exact match // rIt = secretRings.getKeyRings("test (Test key) "); count = 0; while (rIt.hasNext()) { count++; rIt.next(); } if (count != 1) { fail("wrong number of secret keyrings on exact match"); } // // partial match 1 expected // rIt = secretRings.getKeyRings("test", true); count = 0; while (rIt.hasNext()) { count++; rIt.next(); } if (count != 1) { fail("wrong number of secret keyrings on partial match 1"); } // // exact match 0 expected // rIt = secretRings.getKeyRings("test", false); count = 0; while (rIt.hasNext()) { count++; rIt.next(); } if (count != 0) { fail("wrong number of secret keyrings on partial match 0"); } // // case-insensitive partial match // rIt = secretRings.getKeyRings("TEST@ubicall.com", true, true); count = 0; while (rIt.hasNext()) { count++; rIt.next(); } if (count != 1) { fail("wrong number of secret keyrings on case-insensitive partial match"); } } public void test2() throws Exception { PGPPublicKeyRingCollection pubRings = new PGPPublicKeyRingCollection(pub2); int count = 0; byte[] encRing = pubRings.getEncoded(); pubRings = new PGPPublicKeyRingCollection(encRing); Iterator rIt = pubRings.getKeyRings(); while (rIt.hasNext()) { PGPPublicKeyRing pgpPub = (PGPPublicKeyRing)rIt.next(); count++; int keyCount = 0; byte[] bytes = pgpPub.getEncoded(); pgpPub = new PGPPublicKeyRing(bytes); Iterator it = pgpPub.getPublicKeys(); while (it.hasNext()) { PGPPublicKey pk = (PGPPublicKey)it.next(); byte[] pkBytes = pk.getEncoded(); PGPPublicKeyRing pkR = new PGPPublicKeyRing(pkBytes, new BcKeyFingerprintCalculator()); keyCount++; } if (keyCount != 2) { fail("wrong number of public keys"); } } if (count != 2) { fail("wrong number of public keyrings"); } PGPSecretKeyRingCollection secretRings = new PGPSecretKeyRingCollection(sec2); rIt = secretRings.getKeyRings(); count = 0; encRing = secretRings.getEncoded(); secretRings = new PGPSecretKeyRingCollection(encRing); while (rIt.hasNext()) { PGPSecretKeyRing pgpSec = (PGPSecretKeyRing)rIt.next(); count++; int keyCount = 0; byte[] bytes = pgpSec.getEncoded(); pgpSec = new PGPSecretKeyRing(bytes, new BcKeyFingerprintCalculator()); Iterator it = pgpSec.getSecretKeys(); while (it.hasNext()) { keyCount++; PGPSecretKey k = (PGPSecretKey)it.next(); PGPPublicKey pk = k.getPublicKey(); if (pk.getKeyID() == -1413891222336124627L) { int sCount = 0; Iterator sIt = pk.getSignaturesOfType(PGPSignature.SUBKEY_BINDING); while (sIt.hasNext()) { int type = ((PGPSignature)sIt.next()).getSignatureType(); if (type != PGPSignature.SUBKEY_BINDING) { fail("failed to return correct signature type"); } sCount++; } if (sCount != 1) { fail("failed to find binding signature"); } } pk.getSignatures(); if (k.getKeyID() == -4049084404703773049L || k.getKeyID() == -1413891222336124627L) { k.extractPrivateKey(new BcPBESecretKeyDecryptorBuilder(new BcPGPDigestCalculatorProvider()).build(sec2pass1)); } else if (k.getKeyID() == -6498553574938125416L || k.getKeyID() == 59034765524361024L) { k.extractPrivateKey(new BcPBESecretKeyDecryptorBuilder(new BcPGPDigestCalculatorProvider()).build(sec2pass2)); } } if (keyCount != 2) { fail("wrong number of secret keys"); } } if (count != 2) { fail("wrong number of secret keyrings"); } } public void test3() throws Exception { PGPPublicKeyRingCollection pubRings = new PGPPublicKeyRingCollection(pub3); int count = 0; byte[] encRing = pubRings.getEncoded(); pubRings = new PGPPublicKeyRingCollection(encRing); Iterator rIt = pubRings.getKeyRings(); while (rIt.hasNext()) { PGPPublicKeyRing pgpPub = (PGPPublicKeyRing)rIt.next(); count++; int keyCount = 0; byte[] bytes = pgpPub.getEncoded(); pgpPub = new PGPPublicKeyRing(bytes, new BcKeyFingerprintCalculator()); Iterator it = pgpPub.getPublicKeys(); while (it.hasNext()) { keyCount++; PGPPublicKey pubK = (PGPPublicKey)it.next(); pubK.getSignatures(); } if (keyCount != 2) { fail("wrong number of public keys"); } } if (count != 1) { fail("wrong number of public keyrings"); } PGPSecretKeyRingCollection secretRings = new PGPSecretKeyRingCollection(sec3); rIt = secretRings.getKeyRings(); count = 0; encRing = secretRings.getEncoded(); secretRings = new PGPSecretKeyRingCollection(encRing); while (rIt.hasNext()) { PGPSecretKeyRing pgpSec = (PGPSecretKeyRing)rIt.next(); count++; int keyCount = 0; byte[] bytes = pgpSec.getEncoded(); pgpSec = new PGPSecretKeyRing(bytes); Iterator it = pgpSec.getSecretKeys(); while (it.hasNext()) { keyCount++; PGPSecretKey k = (PGPSecretKey)it.next(); k.extractPrivateKey(new BcPBESecretKeyDecryptorBuilder(new BcPGPDigestCalculatorProvider()).build(sec3pass1)); } if (keyCount != 2) { fail("wrong number of secret keys"); } } if (count != 1) { fail("wrong number of secret keyrings"); } } public void test4() throws Exception { PGPSecretKeyRingCollection secretRings = new PGPSecretKeyRingCollection(sec4); Iterator rIt = secretRings.getKeyRings(); int count = 0; byte[] encRing = secretRings.getEncoded(); secretRings = new PGPSecretKeyRingCollection(encRing); while (rIt.hasNext()) { PGPSecretKeyRing pgpSec = (PGPSecretKeyRing)rIt.next(); count++; int keyCount = 0; byte[] bytes = pgpSec.getEncoded(); pgpSec = new PGPSecretKeyRing(bytes, new BcKeyFingerprintCalculator()); Iterator it = pgpSec.getSecretKeys(); while (it.hasNext()) { keyCount++; PGPSecretKey k = (PGPSecretKey)it.next(); k.extractPrivateKey(new BcPBESecretKeyDecryptorBuilder(new BcPGPDigestCalculatorProvider()).build(sec3pass1)); } if (keyCount != 2) { fail("wrong number of secret keys"); } } if (count != 1) { fail("wrong number of secret keyrings"); } } public void test5() throws Exception { PGPPublicKeyRingCollection pubRings = new PGPPublicKeyRingCollection(pub5); int count = 0; byte[] encRing = pubRings.getEncoded(); pubRings = new PGPPublicKeyRingCollection(encRing); Iterator rIt = pubRings.getKeyRings(); while (rIt.hasNext()) { PGPPublicKeyRing pgpPub = (PGPPublicKeyRing)rIt.next(); count++; int keyCount = 0; byte[] bytes = pgpPub.getEncoded(); pgpPub = new PGPPublicKeyRing(bytes, new BcKeyFingerprintCalculator()); Iterator it = pgpPub.getPublicKeys(); while (it.hasNext()) { keyCount++; it.next(); } if (keyCount != 2) { fail("wrong number of public keys"); } } if (count != 1) { fail("wrong number of public keyrings"); } if (noIDEA()) { return; } PGPSecretKeyRingCollection secretRings = new PGPSecretKeyRingCollection(sec5); rIt = secretRings.getKeyRings(); count = 0; encRing = secretRings.getEncoded(); secretRings = new PGPSecretKeyRingCollection(encRing); while (rIt.hasNext()) { PGPSecretKeyRing pgpSec = (PGPSecretKeyRing)rIt.next(); count++; int keyCount = 0; byte[] bytes = pgpSec.getEncoded(); pgpSec = new PGPSecretKeyRing(bytes, new BcKeyFingerprintCalculator()); Iterator it = pgpSec.getSecretKeys(); while (it.hasNext()) { keyCount++; PGPSecretKey k = (PGPSecretKey)it.next(); k.extractPrivateKey(new BcPBESecretKeyDecryptorBuilder(new BcPGPDigestCalculatorProvider()).build(sec5pass1)); } if (keyCount != 2) { fail("wrong number of secret keys"); } } if (count != 1) { fail("wrong number of secret keyrings"); } } private boolean noIDEA() { return true; } public void test6() throws Exception { PGPPublicKeyRingCollection pubRings = new PGPPublicKeyRingCollection(pub6); Iterator rIt = pubRings.getKeyRings(); while (rIt.hasNext()) { PGPPublicKeyRing pgpPub = (PGPPublicKeyRing)rIt.next(); Iterator it = pgpPub.getPublicKeys(); while (it.hasNext()) { PGPPublicKey k = (PGPPublicKey)it.next(); if (k.getKeyID() == 0x5ce086b5b5a18ff4L) { int count = 0; Iterator sIt = k.getSignaturesOfType(PGPSignature.SUBKEY_REVOCATION); while (sIt.hasNext()) { PGPSignature sig = (PGPSignature)sIt.next(); count++; } if (count != 1) { fail("wrong number of revocations in test6."); } } } } byte[] encRing = pubRings.getEncoded(); } public void test7() throws Exception { PGPPublicKeyRing pgpPub = new PGPPublicKeyRing(pub7, new BcKeyFingerprintCalculator()); Iterator it = pgpPub.getPublicKeys(); PGPPublicKey masterKey = null; while (it.hasNext()) { PGPPublicKey k = (PGPPublicKey)it.next(); if (k.isMasterKey()) { masterKey = k; continue; } int count = 0; PGPSignature sig = null; Iterator sIt = k.getSignaturesOfType(PGPSignature.SUBKEY_REVOCATION); while (sIt.hasNext()) { sig = (PGPSignature)sIt.next(); count++; } if (count != 1) { fail("wrong number of revocations in test7."); } sig.init(new BcPGPContentVerifierBuilderProvider(), masterKey); if (!sig.verifyCertification(k)) { fail("failed to verify revocation certification"); } } } public void test8() throws Exception { PGPPublicKeyRingCollection pubRings = new PGPPublicKeyRingCollection(pub8); int count = 0; byte[] encRing = pubRings.getEncoded(); pubRings = new PGPPublicKeyRingCollection(encRing); Iterator rIt = pubRings.getKeyRings(); while (rIt.hasNext()) { PGPPublicKeyRing pgpPub = (PGPPublicKeyRing)rIt.next(); count++; int keyCount = 0; byte[] bytes = pgpPub.getEncoded(); pgpPub = new PGPPublicKeyRing(bytes, new BcKeyFingerprintCalculator()); Iterator it = pgpPub.getPublicKeys(); while (it.hasNext()) { keyCount++; it.next(); } if (keyCount != 2) { fail("wrong number of public keys"); } } if (count != 2) { fail("wrong number of public keyrings"); } PGPSecretKeyRingCollection secretRings = new PGPSecretKeyRingCollection(sec8); rIt = secretRings.getKeyRings(); count = 0; encRing = secretRings.getEncoded(); secretRings = new PGPSecretKeyRingCollection(encRing); while (rIt.hasNext()) { PGPSecretKeyRing pgpSec = (PGPSecretKeyRing)rIt.next(); count++; int keyCount = 0; byte[] bytes = pgpSec.getEncoded(); pgpSec = new PGPSecretKeyRing(bytes, new BcKeyFingerprintCalculator()); Iterator it = pgpSec.getSecretKeys(); while (it.hasNext()) { keyCount++; PGPSecretKey k = (PGPSecretKey)it.next(); k.extractPrivateKey(new BcPBESecretKeyDecryptorBuilder(new BcPGPDigestCalculatorProvider()).build(sec8pass)); } if (keyCount != 2) { fail("wrong number of secret keys"); } } if (count != 1) { fail("wrong number of secret keyrings"); } } public void test9() throws Exception { PGPSecretKeyRingCollection secretRings = new PGPSecretKeyRingCollection(sec9); Iterator rIt = secretRings.getKeyRings(); int count = 0; byte[] encRing = secretRings.getEncoded(); secretRings = new PGPSecretKeyRingCollection(encRing); while (rIt.hasNext()) { PGPSecretKeyRing pgpSec = (PGPSecretKeyRing)rIt.next(); count++; int keyCount = 0; byte[] bytes = pgpSec.getEncoded(); pgpSec = new PGPSecretKeyRing(bytes, new BcKeyFingerprintCalculator()); Iterator it = pgpSec.getSecretKeys(); while (it.hasNext()) { keyCount++; PGPSecretKey k = (PGPSecretKey)it.next(); PGPPrivateKey pKey = k.extractPrivateKey(new BcPBESecretKeyDecryptorBuilder(new BcPGPDigestCalculatorProvider()).build(sec9pass)); if (keyCount == 1 && pKey != null) { fail("primary secret key found, null expected"); } } if (keyCount != 3) { fail("wrong number of secret keys"); } } if (count != 1) { fail("wrong number of secret keyrings"); } } public void test10() throws Exception { PGPSecretKeyRing secretRing = new PGPSecretKeyRing(sec10, new BcKeyFingerprintCalculator()); Iterator secretKeys = secretRing.getSecretKeys(); while (secretKeys.hasNext()) { PGPPublicKey pubKey = ((PGPSecretKey)secretKeys.next()).getPublicKey(); if (pubKey.getValidDays() != 28) { fail("days wrong on secret key ring"); } if (pubKey.getValidSeconds() != 28 * 24 * 60 * 60) { fail("seconds wrong on secret key ring"); } } PGPPublicKeyRing publicRing = new PGPPublicKeyRing(pub10, new BcKeyFingerprintCalculator()); Iterator publicKeys = publicRing.getPublicKeys(); while (publicKeys.hasNext()) { PGPPublicKey pubKey = (PGPPublicKey)publicKeys.next(); if (pubKey.getValidDays() != 28) { fail("days wrong on public key ring"); } if (pubKey.getValidSeconds() != 28 * 24 * 60 * 60) { fail("seconds wrong on public key ring"); } } } public void generateTest() throws Exception { char[] passPhrase = "hello".toCharArray(); KeyPairGenerator dsaKpg = KeyPairGenerator.getInstance("DSA", "BC"); dsaKpg.initialize(512); // // this takes a while as the key generator has to generate some DSA params // before it generates the key. // KeyPair dsaKp = dsaKpg.generateKeyPair(); KeyPairGenerator elgKpg = KeyPairGenerator.getInstance("ELGAMAL", "BC"); BigInteger g = new BigInteger("153d5d6172adb43045b68ae8e1de1070b6137005686d29d3d73a7749199681ee5b212c9b96bfdcfa5b20cd5e3fd2044895d609cf9b410b7a0f12ca1cb9a428cc", 16); BigInteger p = new BigInteger("9494fec095f3b85ee286542b3836fc81a5dd0a0349b4c239dd38744d488cf8e31db8bcb7d33b41abb9e5a33cca9144b1cef332c94bf0573bf047a3aca98cdf3b", 16); ElGamalParameterSpec elParams = new ElGamalParameterSpec(p, g); elgKpg.initialize(elParams); // // this is quicker because we are using pregenerated parameters. // KeyPair elgKp = elgKpg.generateKeyPair(); PGPKeyPair dsaKeyPair = new PGPKeyPair(PGPPublicKey.DSA, dsaKp, new Date()); PGPKeyPair elgKeyPair = new PGPKeyPair(PGPPublicKey.ELGAMAL_ENCRYPT, elgKp, new Date()); PGPKeyRingGenerator keyRingGen = new PGPKeyRingGenerator(PGPSignature.POSITIVE_CERTIFICATION, dsaKeyPair, "test", PGPEncryptedData.AES_256, passPhrase, null, null, new SecureRandom(), "BC"); keyRingGen.addSubKey(elgKeyPair); PGPSecretKeyRing keyRing = keyRingGen.generateSecretKeyRing(); keyRing.getSecretKey().extractPrivateKey(new BcPBESecretKeyDecryptorBuilder(new BcPGPDigestCalculatorProvider()).build(passPhrase)); PGPPublicKeyRing pubRing = keyRingGen.generatePublicKeyRing(); PGPPublicKey vKey = null; PGPPublicKey sKey = null; Iterator it = pubRing.getPublicKeys(); while (it.hasNext()) { PGPPublicKey pk = (PGPPublicKey)it.next(); if (pk.isMasterKey()) { vKey = pk; } else { sKey = pk; } } Iterator sIt = sKey.getSignatures(); while (sIt.hasNext()) { PGPSignature sig = (PGPSignature)sIt.next(); if (sig.getKeyID() == vKey.getKeyID() && sig.getSignatureType() == PGPSignature.SUBKEY_BINDING) { sig.init(new BcPGPContentVerifierBuilderProvider(), vKey); if (!sig.verifyCertification(vKey, sKey)) { fail("failed to verify sub-key signature."); } } } } private void insertMasterTest() throws Exception { char[] passPhrase = "hello".toCharArray(); KeyPairGenerator rsaKpg = KeyPairGenerator.getInstance("RSA", "BC"); rsaKpg.initialize(512); // // this is quicker because we are using pregenerated parameters. // KeyPair rsaKp = rsaKpg.generateKeyPair(); PGPKeyPair rsaKeyPair1 = new PGPKeyPair(PGPPublicKey.RSA_GENERAL, rsaKp, new Date()); rsaKp = rsaKpg.generateKeyPair(); PGPKeyPair rsaKeyPair2 = new PGPKeyPair(PGPPublicKey.RSA_GENERAL, rsaKp, new Date()); PGPKeyRingGenerator keyRingGen = new PGPKeyRingGenerator(PGPSignature.POSITIVE_CERTIFICATION, rsaKeyPair1, "test", PGPEncryptedData.AES_256, passPhrase, null, null, new SecureRandom(), "BC"); PGPSecretKeyRing secRing1 = keyRingGen.generateSecretKeyRing(); PGPPublicKeyRing pubRing1 = keyRingGen.generatePublicKeyRing(); keyRingGen = new PGPKeyRingGenerator(PGPSignature.POSITIVE_CERTIFICATION, rsaKeyPair2, "test", PGPEncryptedData.AES_256, passPhrase, null, null, new SecureRandom(), "BC"); PGPSecretKeyRing secRing2 = keyRingGen.generateSecretKeyRing(); PGPPublicKeyRing pubRing2 = keyRingGen.generatePublicKeyRing(); try { PGPPublicKeyRing.insertPublicKey(pubRing1, pubRing2.getPublicKey()); fail("adding second master key (public) should throw an IllegalArgumentException"); } catch (IllegalArgumentException e) { if (!e.getMessage().equals("cannot add a master key to a ring that already has one")) { fail("wrong message in public test"); } } try { PGPSecretKeyRing.insertSecretKey(secRing1, secRing2.getSecretKey()); fail("adding second master key (secret) should throw an IllegalArgumentException"); } catch (IllegalArgumentException e) { if (!e.getMessage().equals("cannot add a master key to a ring that already has one")) { fail("wrong message in secret test"); } } } public void generateSha1Test() throws Exception { char[] passPhrase = "hello".toCharArray(); KeyPairGenerator dsaKpg = KeyPairGenerator.getInstance("DSA", "BC"); dsaKpg.initialize(512); // // this takes a while as the key generator has to generate some DSA params // before it generates the key. // KeyPair dsaKp = dsaKpg.generateKeyPair(); KeyPairGenerator elgKpg = KeyPairGenerator.getInstance("ELGAMAL", "BC"); BigInteger g = new BigInteger("153d5d6172adb43045b68ae8e1de1070b6137005686d29d3d73a7749199681ee5b212c9b96bfdcfa5b20cd5e3fd2044895d609cf9b410b7a0f12ca1cb9a428cc", 16); BigInteger p = new BigInteger("9494fec095f3b85ee286542b3836fc81a5dd0a0349b4c239dd38744d488cf8e31db8bcb7d33b41abb9e5a33cca9144b1cef332c94bf0573bf047a3aca98cdf3b", 16); ElGamalParameterSpec elParams = new ElGamalParameterSpec(p, g); elgKpg.initialize(elParams); // // this is quicker because we are using pregenerated parameters. // KeyPair elgKp = elgKpg.generateKeyPair(); PGPKeyPair dsaKeyPair = new PGPKeyPair(PGPPublicKey.DSA, dsaKp, new Date()); PGPKeyPair elgKeyPair = new PGPKeyPair(PGPPublicKey.ELGAMAL_ENCRYPT, elgKp, new Date()); PGPKeyRingGenerator keyRingGen = new PGPKeyRingGenerator(PGPSignature.POSITIVE_CERTIFICATION, dsaKeyPair, "test", PGPEncryptedData.AES_256, passPhrase, true, null, null, new SecureRandom(), "BC"); keyRingGen.addSubKey(elgKeyPair); PGPSecretKeyRing keyRing = keyRingGen.generateSecretKeyRing(); keyRing.getSecretKey().extractPrivateKey(new BcPBESecretKeyDecryptorBuilder(new BcPGPDigestCalculatorProvider()).build(passPhrase)); PGPPublicKeyRing pubRing = keyRingGen.generatePublicKeyRing(); PGPPublicKey vKey = null; PGPPublicKey sKey = null; Iterator it = pubRing.getPublicKeys(); while (it.hasNext()) { PGPPublicKey pk = (PGPPublicKey)it.next(); if (pk.isMasterKey()) { vKey = pk; } else { sKey = pk; } } Iterator sIt = sKey.getSignatures(); while (sIt.hasNext()) { PGPSignature sig = (PGPSignature)sIt.next(); if (sig.getKeyID() == vKey.getKeyID() && sig.getSignatureType() == PGPSignature.SUBKEY_BINDING) { sig.init(new BcPGPContentVerifierBuilderProvider(), vKey); if (!sig.verifyCertification(vKey, sKey)) { fail("failed to verify sub-key signature."); } } } } private void test11() throws Exception { PGPPublicKeyRing pubRing = new PGPPublicKeyRing(subKeyBindingKey, new BcKeyFingerprintCalculator()); Iterator it = pubRing.getPublicKeys(); while (it.hasNext()) { PGPPublicKey key = (PGPPublicKey)it.next(); if (key.getValidSeconds() != 0) { fail("expiration time non-zero"); } } } private void rewrapTest() throws Exception { SecureRandom rand = new SecureRandom(); // Read the secret key rings PGPSecretKeyRingCollection privRings = new PGPSecretKeyRingCollection( new ByteArrayInputStream(rewrapKey)); Iterator rIt = privRings.getKeyRings(); if (rIt.hasNext()) { PGPSecretKeyRing pgpPriv = (PGPSecretKeyRing)rIt.next(); Iterator it = pgpPriv.getSecretKeys(); while (it.hasNext()) { PGPSecretKey pgpKey = (PGPSecretKey)it.next(); // re-encrypt the key with an empty password pgpPriv = PGPSecretKeyRing.removeSecretKey(pgpPriv, pgpKey); pgpKey = PGPSecretKey.copyWithNewPassword( pgpKey, new BcPBESecretKeyDecryptorBuilder(new BcPGPDigestCalculatorProvider()).build(rewrapPass), null); pgpPriv = PGPSecretKeyRing.insertSecretKey(pgpPriv, pgpKey); // this should succeed PGPPrivateKey privTmp = pgpKey.extractPrivateKey(null); } } } private void testPublicKeyRingWithX509() throws Exception { checkPublicKeyRingWithX509(pubWithX509); PGPPublicKeyRing pubRing = new PGPPublicKeyRing(pubWithX509, new BcKeyFingerprintCalculator()); checkPublicKeyRingWithX509(pubRing.getEncoded()); } private void testSecretKeyRingWithPersonalCertificate() throws Exception { checkSecretKeyRingWithPersonalCertificate(secWithPersonalCertificate); PGPSecretKeyRingCollection secRing = new PGPSecretKeyRingCollection(secWithPersonalCertificate); checkSecretKeyRingWithPersonalCertificate(secRing.getEncoded()); } private void testUmlaut() throws Exception { PGPPublicKeyRing pubRing = new PGPPublicKeyRing(umlautKeySig, new BcKeyFingerprintCalculator()); PGPPublicKey pub = pubRing.getPublicKey(); String userID = (String)pub.getUserIDs().next(); for (Iterator it = pub.getSignatures(); it.hasNext();) { PGPSignature sig = (PGPSignature)it.next(); if (sig.getSignatureType() == PGPSignature.POSITIVE_CERTIFICATION) { sig.init(new BcPGPContentVerifierBuilderProvider(), pub); if (!sig.verifyCertification(userID, pub)) { fail("failed UTF8 userID test"); } } } // // this is quicker because we are using pregenerated parameters. // KeyPairGenerator rsaKpg = KeyPairGenerator.getInstance("RSA", "BC"); KeyPair rsaKp = rsaKpg.generateKeyPair(); PGPKeyPair rsaKeyPair1 = new PGPKeyPair(PGPPublicKey.RSA_GENERAL, rsaKp, new Date()); rsaKp = rsaKpg.generateKeyPair(); PGPKeyPair rsaKeyPair2 = new PGPKeyPair(PGPPublicKey.RSA_GENERAL, rsaKp, new Date()); char[] passPhrase = "passwd".toCharArray(); PGPKeyRingGenerator keyRingGen = new PGPKeyRingGenerator(PGPSignature.POSITIVE_CERTIFICATION, rsaKeyPair1, userID, PGPEncryptedData.AES_256, passPhrase, null, null, new SecureRandom(), "BC"); PGPPublicKeyRing pubRing1 = keyRingGen.generatePublicKeyRing(); pub = pubRing1.getPublicKey(); for (Iterator it = pub.getSignatures(); it.hasNext();) { PGPSignature sig = (PGPSignature)it.next(); if (sig.getSignatureType() == PGPSignature.POSITIVE_CERTIFICATION) { sig.init(new BcPGPContentVerifierBuilderProvider(), pub); if (!sig.verifyCertification(userID, pub)) { fail("failed UTF8 userID creation test"); } } } } private void checkSecretKeyRingWithPersonalCertificate(byte[] keyRing) throws Exception { PGPSecretKeyRingCollection secCol = new PGPSecretKeyRingCollection(keyRing); int count = 0; for (Iterator rIt = secCol.getKeyRings(); rIt.hasNext();) { PGPSecretKeyRing ring = (PGPSecretKeyRing)rIt.next(); for (Iterator it = ring.getExtraPublicKeys(); it.hasNext();) { it.next(); count++; } } if (count != 1) { fail("personal certificate data subkey not found - count = " + count); } } private void checkPublicKeyRingWithX509(byte[] keyRing) throws Exception { PGPPublicKeyRing pubRing = new PGPPublicKeyRing(keyRing, new BcKeyFingerprintCalculator()); Iterator it = pubRing.getPublicKeys(); if (it.hasNext()) { PGPPublicKey key = (PGPPublicKey)it.next(); Iterator sIt = key.getSignatures(); if (sIt.hasNext()) { PGPSignature sig = (PGPSignature)sIt.next(); if (sig.getKeyAlgorithm() != 100) { fail("experimental signature not found"); } if (!areEqual(sig.getSignature(), Hex.decode("000101"))) { fail("experimental encoding check failed"); } } else { fail("no signature found"); } } else { fail("no key found"); } } public void performTest() throws Exception { try { test1(); test2(); test3(); test4(); test5(); test6(); // test7(); test8(); test9(); test10(); test11(); generateTest(); generateSha1Test(); rewrapTest(); testPublicKeyRingWithX509(); testSecretKeyRingWithPersonalCertificate(); insertMasterTest(); testUmlaut(); } catch (PGPException e) { if (e.getUnderlyingException() != null) { Exception ex = e.getUnderlyingException(); fail("exception: " + ex, ex); } else { fail("exception: " + e, e); } } } public String getName() { return "BcPGPKeyRingTest"; } public static void main( String[] args) { Security.addProvider(new BouncyCastleProvider()); runTest(new BcPGPKeyRingTest()); } } bouncycastle-1.49.orig/test/src/org/bouncycastle/openpgp/test/PGPPacketTest.java0000644000175000017500000000536510527510471027404 0ustar ebourgebourgpackage org.bouncycastle.openpgp.test; import org.bouncycastle.jce.provider.BouncyCastleProvider; import org.bouncycastle.openpgp.PGPLiteralData; import org.bouncycastle.openpgp.PGPLiteralDataGenerator; import org.bouncycastle.openpgp.PGPObjectFactory; import org.bouncycastle.util.test.SimpleTest; import org.bouncycastle.util.test.UncloseableOutputStream; import java.io.ByteArrayOutputStream; import java.io.IOException; import java.io.InputStream; import java.io.OutputStream; import java.security.Security; import java.util.Date; import java.util.Random; public class PGPPacketTest extends SimpleTest { private static int MAX = 32000; private void readBackTest( PGPLiteralDataGenerator generator) throws IOException { Random rand = new Random(); byte[] buf = new byte[MAX]; rand.nextBytes(buf); for (int i = 1; i <= 200; i++) { bufferTest(generator, buf, i); } bufferTest(generator, buf, 8382); bufferTest(generator, buf, 8383); bufferTest(generator, buf, 8384); bufferTest(generator, buf, 8385); for (int i = 200; i < MAX; i += 100) { bufferTest(generator, buf, i); } } private void bufferTest( PGPLiteralDataGenerator generator, byte[] buf, int i) throws IOException { ByteArrayOutputStream bOut = new ByteArrayOutputStream(); OutputStream out = generator.open( new UncloseableOutputStream(bOut), PGPLiteralData.BINARY, PGPLiteralData.CONSOLE, i, new Date()); out.write(buf, 0, i); generator.close(); PGPObjectFactory fact = new PGPObjectFactory(bOut.toByteArray()); PGPLiteralData data = (PGPLiteralData)fact.nextObject(); InputStream in = data.getInputStream(); for (int count = 0; count != i; count++) { if (in.read() != (buf[count] & 0xff)) { fail("failed readback test - length = " + i); } } } public void performTest() throws IOException { PGPLiteralDataGenerator oldGenerator = new PGPLiteralDataGenerator(true); readBackTest(oldGenerator); PGPLiteralDataGenerator newGenerator = new PGPLiteralDataGenerator(false); readBackTest(newGenerator); } public String getName() { return "PGPPacketTest"; } public static void main( String[] args) { Security.addProvider(new BouncyCastleProvider()); runTest(new PGPPacketTest()); } } bouncycastle-1.49.orig/test/src/org/bouncycastle/openpgp/test/PGPRSATest.java0000644000175000017500000016623712145535523026633 0ustar ebourgebourgpackage org.bouncycastle.openpgp.test; import java.io.ByteArrayInputStream; import java.io.ByteArrayOutputStream; import java.io.IOException; import java.io.InputStream; import java.io.OutputStream; import java.security.KeyPair; import java.security.KeyPairGenerator; import java.security.PublicKey; import java.security.SecureRandom; import java.security.Security; import java.util.Date; import java.util.Iterator; import javax.crypto.Cipher; import org.bouncycastle.bcpg.BCPGOutputStream; import org.bouncycastle.bcpg.CompressionAlgorithmTags; import org.bouncycastle.bcpg.HashAlgorithmTags; import org.bouncycastle.bcpg.PublicKeyAlgorithmTags; import org.bouncycastle.bcpg.SymmetricKeyAlgorithmTags; import org.bouncycastle.bcpg.attr.ImageAttribute; import org.bouncycastle.bcpg.sig.Features; import org.bouncycastle.bcpg.sig.KeyFlags; import org.bouncycastle.jce.provider.BouncyCastleProvider; import org.bouncycastle.openpgp.PGPCompressedData; import org.bouncycastle.openpgp.PGPCompressedDataGenerator; import org.bouncycastle.openpgp.PGPEncryptedData; import org.bouncycastle.openpgp.PGPEncryptedDataGenerator; import org.bouncycastle.openpgp.PGPEncryptedDataList; import org.bouncycastle.openpgp.PGPKeyPair; import org.bouncycastle.openpgp.PGPKeyRingGenerator; import org.bouncycastle.openpgp.PGPLiteralData; import org.bouncycastle.openpgp.PGPLiteralDataGenerator; import org.bouncycastle.openpgp.PGPObjectFactory; import org.bouncycastle.openpgp.PGPOnePassSignature; import org.bouncycastle.openpgp.PGPOnePassSignatureList; import org.bouncycastle.openpgp.PGPPBEEncryptedData; import org.bouncycastle.openpgp.PGPPrivateKey; import org.bouncycastle.openpgp.PGPPublicKey; import org.bouncycastle.openpgp.PGPPublicKeyEncryptedData; import org.bouncycastle.openpgp.PGPPublicKeyRing; import org.bouncycastle.openpgp.PGPSecretKey; import org.bouncycastle.openpgp.PGPSecretKeyRing; import org.bouncycastle.openpgp.PGPSignature; import org.bouncycastle.openpgp.PGPSignatureGenerator; import org.bouncycastle.openpgp.PGPSignatureList; import org.bouncycastle.openpgp.PGPSignatureSubpacketGenerator; import org.bouncycastle.openpgp.PGPSignatureSubpacketVector; import org.bouncycastle.openpgp.PGPUserAttributeSubpacketVector; import org.bouncycastle.openpgp.PGPUserAttributeSubpacketVectorGenerator; import org.bouncycastle.openpgp.PGPUtil; import org.bouncycastle.openpgp.PGPV3SignatureGenerator; import org.bouncycastle.openpgp.operator.PGPDigestCalculator; import org.bouncycastle.openpgp.operator.jcajce.JcaKeyFingerprintCalculator; import org.bouncycastle.openpgp.operator.jcajce.JcaPGPContentSignerBuilder; import org.bouncycastle.openpgp.operator.jcajce.JcaPGPDigestCalculatorProviderBuilder; import org.bouncycastle.openpgp.operator.jcajce.JcaPGPKeyPair; import org.bouncycastle.openpgp.operator.jcajce.JcePBESecretKeyEncryptorBuilder; import org.bouncycastle.util.Arrays; import org.bouncycastle.util.encoders.Base64; import org.bouncycastle.util.encoders.Hex; import org.bouncycastle.util.test.SimpleTest; import org.bouncycastle.util.test.UncloseableOutputStream; public class PGPRSATest extends SimpleTest { byte[] testPubKey = Base64.decode( "mIsEPz2nJAEEAOTVqWMvqYE693qTgzKv/TJpIj3hI8LlYPC6m1dk0z3bDLwVVk9F" + "FAB+CWS8RdFOWt/FG3tEv2nzcoNdRvjv9WALyIGNawtae4Ml6oAT06/511yUzXHO" + "k+9xK3wkXN5jdzUhf4cA2oGpLSV/pZlocsIDL+jCUQtumUPwFodmSHhzAAYptC9F" + "cmljIEVjaGlkbmEgKHRlc3Qga2V5KSA8ZXJpY0Bib3VuY3ljYXN0bGUub3JnPoi4" + "BBMBAgAiBQI/PackAhsDBQkAg9YABAsHAwIDFQIDAxYCAQIeAQIXgAAKCRA1WGFG" + "/fPzc8WMA/9BbjuB8E48QAlxoiVf9U8SfNelrz/ONJA/bMvWr/JnOGA9PPmFD5Uc" + "+kV/q+i94dEMjsC5CQ1moUHWSP2xlQhbOzBP2+oPXw3z2fBs9XJgnTH6QWMAAvLs" + "3ug9po0loNHLobT/D/XdXvcrb3wvwvPT2FptZqrtonH/OdzT9JdfrA=="); byte[] testPrivKey = Base64.decode( "lQH8BD89pyQBBADk1aljL6mBOvd6k4Myr/0yaSI94SPC5WDwuptXZNM92wy8FVZP" + "RRQAfglkvEXRTlrfxRt7RL9p83KDXUb47/VgC8iBjWsLWnuDJeqAE9Ov+ddclM1x" + "zpPvcSt8JFzeY3c1IX+HANqBqS0lf6WZaHLCAy/owlELbplD8BaHZkh4cwAGKf4D" + "AwKbLeIOVYTEdWD5v/YgW8ERs0pDsSIfBTvsJp2qA798KeFuED6jGsHUzdi1M990" + "6PRtplQgnoYmYQrzEc6DXAiAtBR4Kuxi4XHx0ZR2wpVlVxm2Ypgz7pbBNWcWqzvw" + "33inl7tR4IDsRdJOY8cFlN+1tSCf16sDidtKXUVjRjZNYJytH18VfSPlGXMeYgtw" + "3cSGNTERwKaq5E/SozT2MKTiORO0g0Mtyz+9MEB6XVXFavMun/mXURqbZN/k9BFb" + "z+TadpkihrLD1xw3Hp+tpe4CwPQ2GdWKI9KNo5gEnbkJgLrSMGgWalPhknlNHRyY" + "bSq6lbIMJEE3LoOwvYWwweR1+GrV9farJESdunl1mDr5/d6rKru+FFDwZM3na1IF" + "4Ei4FpqhivZ4zG6pN5XqLy+AK85EiW4XH0yAKX1O4YlbmDU4BjxhiwTdwuVMCjLO" + "5++jkz5BBQWdFX8CCMA4FJl36G70IbGzuFfOj07ly7QvRXJpYyBFY2hpZG5hICh0" + "ZXN0IGtleSkgPGVyaWNAYm91bmN5Y2FzdGxlLm9yZz6IuAQTAQIAIgUCPz2nJAIb" + "AwUJAIPWAAQLBwMCAxUCAwMWAgECHgECF4AACgkQNVhhRv3z83PFjAP/QW47gfBO" + "PEAJcaIlX/VPEnzXpa8/zjSQP2zL1q/yZzhgPTz5hQ+VHPpFf6voveHRDI7AuQkN" + "ZqFB1kj9sZUIWzswT9vqD18N89nwbPVyYJ0x+kFjAALy7N7oPaaNJaDRy6G0/w/1" + "3V73K298L8Lz09habWaq7aJx/znc0/SXX6w="); byte[] testPubKeyV3 = Base64.decode( "mQCNAz+zvlEAAAEEAMS22jgXbOZ/D3xWgM2kauSdzrwlU7Ms5hDW05ObqQyO" + "FfQoKKMhfupyoa7J3x04VVBKu6Eomvr1es+VImH0esoeWFFahNOYq/I+jRRB" + "woOhAGZ5UB2/hRd7rFmxqp6sCXi8wmLO2tAorlTzAiNNvl7xF4cQZpc0z56F" + "wdi2fBUJAAURtApGSVhDSVRZX1FBiQCVAwUQP7O+UZ6Fwdi2fBUJAQFMwwQA" + "qRnFsdg4xQnB8Y5d4cOpXkIn9AZgYS3cxtuSJB84vG2CgC39nfv4c+nlLkWP" + "4puG+mZuJNgVoE84cuAF4I//1anKjlU7q1M6rFQnt5S4uxPyG3dFXmgyU1b4" + "PBOnA0tIxjPzlIhJAMsPCGGA5+5M2JP0ad6RnzqzE3EENMX+GqY="); byte[] testPrivKeyV3 = Base64.decode( "lQHfAz+zvlEAAAEEAMS22jgXbOZ/D3xWgM2kauSdzrwlU7Ms5hDW05ObqQyO" + "FfQoKKMhfupyoa7J3x04VVBKu6Eomvr1es+VImH0esoeWFFahNOYq/I+jRRB" + "woOhAGZ5UB2/hRd7rFmxqp6sCXi8wmLO2tAorlTzAiNNvl7xF4cQZpc0z56F" + "wdi2fBUJAAURAXWwRBZQHNikA/f0ScLLjrXi4s0hgQecg+dkpDow94eu5+AR" + "0DzZnfurpgfUJCNiDi5W/5c3Zj/xyrfMAgkbCgJ1m6FZqAQh7Mq73l7Kfu4/" + "XIkyDF3tDgRuZNezB+JuElX10tV03xumHepp6M6CfhXqNJ15F33F99TA5hXY" + "CPYD7SiSOpIhQkCOAgDAA63imxbpuKE2W7Y4I1BUHB7WQi8ZdkZd04njNTv+" + "rFUuOPapQVfbWG0Vq8ld3YmJB4QWsa2mmqn+qToXbwufAgBpXkjvqK5yPiHF" + "Px2QbFc1VqoCJB6PO5JRIqEiUZBFGdDlLxt3VSyqz7IZ/zEnxZq+tPCGGGSm" + "/sAGiMvENcHVAfy0kTXU42TxEAYJyyNyqjXOobDJpEV1mKhFskRXt7tbMfOS" + "Yf91oX8f6xw6O2Nal+hU8dS0Bmfmk5/enHmvRLHQocO0CkZJWENJVFlfUUE="); byte[] sig1 = Base64.decode( "owGbwMvMwMRoGpHo9vfz52LGNTJJnBmpOTn5eiUVJfb23JvAHIXy/KKcFEWuToap" + "zKwMIGG4Bqav0SwMy3yParsEKi2LMGI9xhh65sBxb05n5++ZLcWNJ/eLFKdWbm95" + "tHbDV7GMwj/tUctUpFUXWPYFCLdNsDiVNuXbQvZtdXV/5xzY+9w1nCnijH9JoNiJ" + "22n2jo0zo30/TZLo+jDl2vTzIvPeLEsPM3ZUE/1Ytqs4SG2TxIQbH7xf3uzcYXq2" + "5Fw9AA=="); byte[] sig1crc = Base64.decode("+3i0"); byte[] subKey = Base64.decode( "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" + "CphiUYWnsC0mQ+J15B4="); byte[] enc1 = Base64.decode( "hIwDKwfQexPJboABA/4/7prhYYMORTiQ5avQKx0XYpCLujzGefYjnyuWZnx3Iev8" + "Pmsguumm+OLLvtXhhkXQmkJRXbIg6Otj2ubPYWflRPgpJSgOrNOreOl5jeABOrtw" + "bV6TJb9OTtZuB7cTQSCq2gmYiSZkluIiDjNs3R3mEanILbYzOQ3zKSggKpzlv9JQ" + "AZUqTyDyJ6/OUbJF5fI5uiv76DCsw1zyMWotUIu5/X01q+AVP5Ly3STzI7xkWg/J" + "APz4zUHism7kSYz2viAQaJx9/bNnH3AM6qm1Fuyikl4="); byte[] enc1crc = Base64.decode("lv4o"); byte[] enc2 = Base64.decode( "hIwDKwfQexPJboABBAC62jcJH8xKnKb1neDVmiovYON04+7VQ2v4BmeHwJrdag1g" + "Ya++6PeBlQ2Q9lSGBwLobVuJmQ7cOnPUJP727JeSGWlMyFtMbBSHekOaTenT5lj7" + "Zk7oRHxMp/hByzlMacIDzOn8LPSh515RHM57eDLCOwqnAxGQwk67GRl8f5dFH9JQ" + "Aa7xx8rjCqPbiIQW6t5LqCNvPZOiSCmftll6+se1XJhFEuq8WS4nXtPfTiJ3vib4" + "3soJdHzGB6AOs+BQ6aKmmNTVAxa5owhtSt1Z/6dfSSk="); byte[] subPubKey = Base64.decode( "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"); byte[] subPubCrc = Base64.decode("rikt"); byte[] pgp8Key = Base64.decode( "lQIEBEBXUNMBBADScQczBibewnbCzCswc/9ut8R0fwlltBRxMW0NMdKJY2LF" + "7k2COeLOCIU95loJGV6ulbpDCXEO2Jyq8/qGw1qD3SCZNXxKs3GS8Iyh9Uwd" + "VL07nMMYl5NiQRsFB7wOb86+94tYWgvikVA5BRP5y3+O3GItnXnpWSJyREUy" + "6WI2QQAGKf4JAwIVmnRs4jtTX2DD05zy2mepEQ8bsqVAKIx7lEwvMVNcvg4Y" + "8vFLh9Mf/uNciwL4Se/ehfKQ/AT0JmBZduYMqRU2zhiBmxj4cXUQ0s36ysj7" + "fyDngGocDnM3cwPxaTF1ZRBQHSLewP7dqE7M73usFSz8vwD/0xNOHFRLKbsO" + "RqDlLA1Cg2Yd0wWPS0o7+qqk9ndqrjjSwMM8ftnzFGjShAdg4Ca7fFkcNePP" + "/rrwIH472FuRb7RbWzwXA4+4ZBdl8D4An0dwtfvAO+jCZSrLjmSpxEOveJxY" + "GduyR4IA4lemvAG51YHTHd4NXheuEqsIkn1yarwaaj47lFPnxNOElOREMdZb" + "nkWQb1jfgqO24imEZgrLMkK9bJfoDnlF4k6r6hZOp5FSFvc5kJB4cVo1QJl4" + "pwCSdoU6luwCggrlZhDnkGCSuQUUW45NE7Br22NGqn4/gHs0KCsWbAezApGj" + "qYUCfX1bcpPzUMzUlBaD5rz2vPeO58CDtBJ0ZXN0ZXIgPHRlc3RAdGVzdD6I" + "sgQTAQIAHAUCQFdQ0wIbAwQLBwMCAxUCAwMWAgECHgECF4AACgkQs8JyyQfH" + "97I1QgP8Cd+35maM2cbWV9iVRO+c5456KDi3oIUSNdPf1NQrCAtJqEUhmMSt" + "QbdiaFEkPrORISI/2htXruYn0aIpkCfbUheHOu0sef7s6pHmI2kOQPzR+C/j" + "8D9QvWsPOOso81KU2axUY8zIer64Uzqc4szMIlLw06c8vea27RfgjBpSCryw" + "AgAA"); char[] pgp8Pass = "2002 Buffalo Sabres".toCharArray(); char[] pass = { 'h', 'e', 'l', 'l', 'o', ' ', 'w', 'o', 'r', 'l', 'd' }; byte[] fingerprintKey = Base64.decode( "mQEPA0CiJdUAAAEIAMI+znDlPd2kQoEcnxqxLcRz56Z7ttFKHpnYp0UkljZdquVc" + "By1jMfXGVV64xN1IvMcyenLXUE0IUeUBCQs6tHunFRAPSeCxJ3FdFe1B5MpqQG8A" + "BnEpAds/hAUfRDZD5y/lolk1hjvFMrRh6WXckaA/QQ2t00NmTrJ1pYUpkw9tnVQb" + "LUjWJhfZDBBcN0ADtATzgkugxMtcDxR6I5x8Ndn+IilqIm23kxGIcmMd/BHOec4c" + "jRwJXXDb7u8tl+2knAf9cwhPHp3+Zy4uGSQPdzQnXOhBlA+4WDa0RROOevWgq8uq" + "8/9Xp/OlTVL+OoIzjsI6mJP1Joa4qmqAnaHAmXcAEQEAAbQoQk9BM1JTS1kgPEJP" + "QSBNb25pdG9yaW5nIEAgODg4LTI2OS01MjY2PokBFQMFEECiJdWqaoCdocCZdwEB" + "0RsH/3HPxoUZ3G3K7T3jgOnJUckTSHWU3XspHzMVgqOxjTrcexi5IsAM5M+BulfW" + "T2aO+Kqf5w8cKTKgW02DNpHUiPjHx0nzDE+Do95zbIErGeK+Twkc4O/aVsvU9GGO" + "81VFI6WMvDQ4CUAUnAdk03MRrzI2nAuhn4NJ5LQS+uJrnqUJ4HmFAz6CQZQKd/kS" + "Xgq+A6i7aI1LG80YxWa9ooQgaCrb9dwY/kPQ+yC22zQ3FExtv+Fv3VtAKTilO3vn" + "BA4Y9uTHuObHfI+1yxUS2PrlRUX0m48ZjpIX+cEN3QblGBJudI/A1QSd6P0LZeBr" + "7F1Z1aF7ZDo0KzgiAIBvgXkeTpw="); byte[] fingerprintCheck = Base64.decode("CTv2"); byte[] expiry60and30daysSig13Key = Base64.decode( "mQGiBENZt/URBAC5JccXiwe4g6MuviEC8NI/x0NaVkGFAOY04d5E4jeIycBP" + "SrpOPrjETuigqhrj8oqed2+2yUqfnK4nhTsTAjyeJ3PpWC1pGAKzJgYmJk+K" + "9aTLq0BQWiXDdv5RG6fDmeq1umvOfcXBqGFAguLPZC+U872bSLnfe3lqGNA8" + "jvmY7wCgjhzVQVm10NN5ST8nemPEcSjnBrED/R494gHL6+r5OgUgXnNCDejA" + "4InoDImQCF+g7epp5E1MB6CMYSg2WSY2jHFuHpwnUb7AiOO0ZZ3UBqM9rYnK" + "kDvxkFCxba7Ms+aFj9blRNmy3vG4FewDcTdxzCtjUk6dRfu6UoARpqlTE/q7" + "Xo6EQP1ncwJ+UTlcHkTBvg/usI/yBACGjBqX8glb5VfNaZgNHMeS/UIiUiuV" + "SVFojiSDOHcnCe/6y4M2gVm38zz1W9qhoLfLpiAOFeL0yj6wzXvsjjXQiKQ8" + "nBE4Mf+oeH2qiQ/LfzQrGpI5eNcMXrzK9nigmz2htYO2GjQfupEnu1RHBTH8" + "NjofD2AShL9IO73plRuExrQgVGVzdCBLZXkgPHRlc3RAYm91bmN5Y2FzdGxl" + "Lm9yZz6IZAQTEQIAJAIbAwYLCQgHAwIDFQIDAxYCAQIeAQIXgAUCQ1m4DgUJ" + "AE8aGQAKCRD8QP1QuU7Kqw+eAJ0dZ3ZAqr73X61VmCkbyPoszLQMAQCfdFs2" + "YMDeUvX34Q/8Ba0KgO5f3RSwAgADuM0EQ1m39hADAIHpVGcLqS9UkmQaWBvH" + "WP6TnN7Y1Ha0TJOuxpbFjBW+CmVh/FjcsnavFXDXpo2zc742WT+vrHBSa/0D" + "1QEBsnCaX5SRRVp7Mqs8q+aDhjcHMIP8Sdxf7GozXDORkrRaJwADBQL9HLYm" + "7Rr5iYWDcvs+Pi6O1zUyb1tjkxEGaV/rcozl2MMmr2mzJ6x/Bz8SuhZEJS0m" + "bB2CvAA39aQi9jHlV7q0SV73NOkd2L/Vt2UZhzlUdvrJ37PgYDv+Wd9Ufz6g" + "MzLSiE8EGBECAA8FAkNZt/YCGwwFCQAnjQAACgkQ/ED9ULlOyqsTqQCcDnAZ" + "7YymCfhm1yJiuFQg3qiX6Z4An19OSEgeSKugVcH49g1sxUB0zNdIsAIAAw=="); byte[] jpegImage = Base64.decode( "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"); byte[] embeddedJPEGKey = Base64.decode( "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" + "Qvmtc8X7lqK/zLRVkSSBItik2IIhsAIAAw=="); private void fingerPrintTest() throws Exception { // // version 3 // PGPPublicKeyRing pgpPub = new PGPPublicKeyRing(fingerprintKey); PGPPublicKey pubKey = pgpPub.getPublicKey(); if (!areEqual(pubKey.getFingerprint(), Hex.decode("4FFB9F0884266C715D1CEAC804A3BBFA"))) { fail("version 3 fingerprint test failed"); } // // version 4 // pgpPub = new PGPPublicKeyRing(testPubKey); pubKey = pgpPub.getPublicKey(); if (!areEqual(pubKey.getFingerprint(), Hex.decode("3062363c1046a01a751946bb35586146fdf3f373"))) { fail("version 4 fingerprint test failed"); } } private void mixedTest(PGPPrivateKey pgpPrivKey, PGPPublicKey pgpPubKey) throws Exception { byte[] text = { (byte)'h', (byte)'e', (byte)'l', (byte)'l', (byte)'o', (byte)' ', (byte)'w', (byte)'o', (byte)'r', (byte)'l', (byte)'d', (byte)'!', (byte)'\n' }; // // literal data // ByteArrayOutputStream bOut = new ByteArrayOutputStream(); PGPLiteralDataGenerator lGen = new PGPLiteralDataGenerator(); OutputStream lOut = lGen.open(bOut, PGPLiteralData.BINARY, PGPLiteralData.CONSOLE, text.length, new Date()); lOut.write(text); lGen.close(); byte[] bytes = bOut.toByteArray(); PGPObjectFactory f = new PGPObjectFactory(bytes); checkLiteralData((PGPLiteralData)f.nextObject(), text); ByteArrayOutputStream bcOut = new ByteArrayOutputStream(); PGPEncryptedDataGenerator encGen = new PGPEncryptedDataGenerator(SymmetricKeyAlgorithmTags.AES_128, true, new SecureRandom(), "BC"); encGen.addMethod(pgpPubKey); encGen.addMethod("password".toCharArray()); OutputStream cOut = encGen.open(bcOut, bytes.length); cOut.write(bytes); cOut.close(); byte[] encData = bcOut.toByteArray(); // // asymmetric // PGPObjectFactory pgpF = new PGPObjectFactory(encData); PGPEncryptedDataList encList = (PGPEncryptedDataList)pgpF.nextObject(); PGPPublicKeyEncryptedData encP = (PGPPublicKeyEncryptedData)encList.get(0); InputStream clear = encP.getDataStream(pgpPrivKey, "BC"); PGPObjectFactory pgpFact = new PGPObjectFactory(clear); checkLiteralData((PGPLiteralData)pgpFact.nextObject(), text); // // PBE // pgpF = new PGPObjectFactory(encData); encList = (PGPEncryptedDataList)pgpF.nextObject(); PGPPBEEncryptedData encPbe = (PGPPBEEncryptedData)encList.get(1); clear = encPbe.getDataStream("password".toCharArray(), "BC"); pgpF = new PGPObjectFactory(clear); checkLiteralData((PGPLiteralData)pgpF.nextObject(), text); } private void checkLiteralData(PGPLiteralData ld, byte[] data) throws IOException { ByteArrayOutputStream bOut = new ByteArrayOutputStream(); if (!ld.getFileName().equals(PGPLiteralData.CONSOLE)) { throw new RuntimeException("wrong filename in packet"); } InputStream inLd = ld.getDataStream(); int ch; while ((ch = inLd.read()) >= 0) { bOut.write(ch); } if (!areEqual(bOut.toByteArray(), data)) { fail("wrong plain text in decrypted packet"); } } private void existingEmbeddedJpegTest() throws Exception { PGPPublicKeyRing pgpPub = new PGPPublicKeyRing(embeddedJPEGKey); PGPPublicKey pubKey = pgpPub.getPublicKey(); Iterator it = pubKey.getUserAttributes(); int count = 0; while (it.hasNext()) { PGPUserAttributeSubpacketVector attributes = (PGPUserAttributeSubpacketVector)it.next(); Iterator sigs = pubKey.getSignaturesForUserAttribute(attributes); int sigCount = 0; while (sigs.hasNext()) { PGPSignature sig = (PGPSignature)sigs.next(); sig.initVerify(pubKey, "BC"); if (!sig.verifyCertification(attributes, pubKey)) { fail("signature failed verification"); } sigCount++; } if (sigCount != 1) { fail("Failed user attributes signature check"); } count++; } if (count != 1) { fail("didn't find user attributes"); } } private void embeddedJpegTest() throws Exception { PGPPublicKeyRing pgpPub = new PGPPublicKeyRing(testPubKey, new JcaKeyFingerprintCalculator()); PGPSecretKeyRing pgpSec = new PGPSecretKeyRing(testPrivKey, new JcaKeyFingerprintCalculator()); PGPPublicKey pubKey = pgpPub.getPublicKey(); PGPUserAttributeSubpacketVectorGenerator vGen = new PGPUserAttributeSubpacketVectorGenerator(); vGen.setImageAttribute(ImageAttribute.JPEG, jpegImage); PGPUserAttributeSubpacketVector uVec = vGen.generate(); PGPSignatureGenerator sGen = new PGPSignatureGenerator(PublicKeyAlgorithmTags.RSA_GENERAL, HashAlgorithmTags.SHA1, "BC"); sGen.initSign(PGPSignature.POSITIVE_CERTIFICATION, pgpSec.getSecretKey().extractPrivateKey(pass, "BC")); PGPSignature sig = sGen.generateCertification(uVec, pubKey); PGPPublicKey nKey = PGPPublicKey.addCertification(pubKey, uVec, sig); Iterator it = nKey.getUserAttributes(); int count = 0; while (it.hasNext()) { PGPUserAttributeSubpacketVector attributes = (PGPUserAttributeSubpacketVector)it.next(); Iterator sigs = nKey.getSignaturesForUserAttribute(attributes); int sigCount = 0; while (sigs.hasNext()) { PGPSignature s = (PGPSignature)sigs.next(); s.initVerify(pubKey, "BC"); if (!s.verifyCertification(attributes, pubKey)) { fail("added signature failed verification"); } sigCount++; } if (sigCount != 1) { fail("Failed added user attributes signature check"); } count++; } if (count != 1) { fail("didn't find added user attributes"); } nKey = PGPPublicKey.removeCertification(nKey, uVec); count = 0; for (it = nKey.getUserAttributes(); it.hasNext();) { count++; } if (count != 0) { fail("found attributes where none expected"); } } private void sigsubpacketTest() throws Exception { char[] passPhrase = "test".toCharArray(); String identity = "TEST "; Date date = new Date(); Security.addProvider(new BouncyCastleProvider()); KeyPairGenerator kpg = KeyPairGenerator.getInstance("RSA", "BC"); kpg.initialize(2048); KeyPair kpSgn = kpg.generateKeyPair(); KeyPair kpEnc = kpg.generateKeyPair(); PGPKeyPair sgnKeyPair = new JcaPGPKeyPair(PGPPublicKey.RSA_SIGN, kpSgn, date); PGPKeyPair encKeyPair = new JcaPGPKeyPair(PGPPublicKey.RSA_GENERAL, kpEnc, date); PGPSignatureSubpacketVector unhashedPcks = null; PGPSignatureSubpacketGenerator svg = new PGPSignatureSubpacketGenerator(); svg.setKeyExpirationTime(true, 86400L * 366 * 2); svg.setPrimaryUserID(true, true); int[] encAlgs = {SymmetricKeyAlgorithmTags.AES_256, SymmetricKeyAlgorithmTags.AES_192, SymmetricKeyAlgorithmTags.TRIPLE_DES}; svg.setPreferredSymmetricAlgorithms(true, encAlgs); int[] hashAlgs = {HashAlgorithmTags.SHA1, HashAlgorithmTags.SHA512, HashAlgorithmTags.SHA384, HashAlgorithmTags.SHA256, HashAlgorithmTags.RIPEMD160}; svg.setPreferredHashAlgorithms(true, hashAlgs); int[] comprAlgs = {CompressionAlgorithmTags.ZLIB, CompressionAlgorithmTags.BZIP2, CompressionAlgorithmTags.ZIP}; svg.setPreferredCompressionAlgorithms(true, comprAlgs); svg.setFeature(true, Features.FEATURE_MODIFICATION_DETECTION); svg.setKeyFlags(true, KeyFlags.CERTIFY_OTHER + KeyFlags.SIGN_DATA); PGPSignatureSubpacketVector hashedPcks = svg.generate(); PGPKeyRingGenerator keyRingGen = new PGPKeyRingGenerator(PGPSignature.POSITIVE_CERTIFICATION, sgnKeyPair, identity, PGPEncryptedData.AES_256, passPhrase, true, hashedPcks, unhashedPcks, new SecureRandom(), "BC"); svg = new PGPSignatureSubpacketGenerator(); svg.setKeyExpirationTime(true, 86400L * 366 * 2); svg.setKeyFlags(true, KeyFlags.ENCRYPT_COMMS + KeyFlags.ENCRYPT_STORAGE); svg.setPrimaryUserID(true, false); svg.setFeature(true, Features.FEATURE_MODIFICATION_DETECTION); hashedPcks = svg.generate(); keyRingGen.addSubKey(encKeyPair, hashedPcks, unhashedPcks); byte[] encodedKeyRing = keyRingGen.generatePublicKeyRing().getEncoded(); PGPPublicKeyRing keyRing = new PGPPublicKeyRing(encodedKeyRing); for (Iterator it = keyRing.getPublicKeys(); it.hasNext();) { PGPPublicKey pKey = (PGPPublicKey)it.next(); if (pKey.isEncryptionKey()) { for (Iterator sit = pKey.getSignatures(); sit.hasNext();) { PGPSignature sig = (PGPSignature)sit.next(); PGPSignatureSubpacketVector v = sig.getHashedSubPackets(); if (v.getKeyExpirationTime() != 86400L * 366 * 2) { fail("key expiration time wrong"); } if (!v.getFeatures().supportsFeature(Features.FEATURE_MODIFICATION_DETECTION)) { fail("features wrong"); } if (v.isPrimaryUserID()) { fail("primary userID flag wrong"); } if (v.getKeyFlags() != KeyFlags.ENCRYPT_COMMS + KeyFlags.ENCRYPT_STORAGE) { fail("keyFlags wrong"); } } } else { for (Iterator sit = pKey.getSignatures(); sit.hasNext();) { PGPSignature sig = (PGPSignature)sit.next(); PGPSignatureSubpacketVector v = sig.getHashedSubPackets(); if (!Arrays.areEqual(v.getPreferredSymmetricAlgorithms(), encAlgs)) { fail("preferred encryption algs don't match"); } if (!Arrays.areEqual(v.getPreferredHashAlgorithms(), hashAlgs)) { fail("preferred hash algs don't match"); } if (!Arrays.areEqual(v.getPreferredCompressionAlgorithms(), comprAlgs)) { fail("preferred compression algs don't match"); } if (!v.getFeatures().supportsFeature(Features.FEATURE_MODIFICATION_DETECTION)) { fail("features wrong"); } if (v.getKeyFlags() != KeyFlags.CERTIFY_OTHER + KeyFlags.SIGN_DATA) { fail("keyFlags wrong"); } } } } } private void multipleExpiryTest() throws Exception { char[] passPhrase = "test".toCharArray(); String identity = "TEST "; Date date = new Date(); Security.addProvider(new BouncyCastleProvider()); KeyPairGenerator kpg = KeyPairGenerator.getInstance("RSA", "BC"); kpg.initialize(2048); KeyPair kpSgn = kpg.generateKeyPair(); KeyPair kpEnc = kpg.generateKeyPair(); PGPKeyPair sgnKeyPair = new JcaPGPKeyPair(PGPPublicKey.RSA_SIGN, kpSgn, date); PGPKeyPair encKeyPair = new JcaPGPKeyPair(PGPPublicKey.RSA_GENERAL, kpEnc, date); PGPSignatureSubpacketVector unhashedPcks = null; PGPSignatureSubpacketGenerator svg = new PGPSignatureSubpacketGenerator(); svg.setKeyExpirationTime(true, 86400L * 366 * 2); svg.setPrimaryUserID(true, true); int[] encAlgs = {SymmetricKeyAlgorithmTags.AES_256, SymmetricKeyAlgorithmTags.AES_192, SymmetricKeyAlgorithmTags.TRIPLE_DES}; svg.setPreferredSymmetricAlgorithms(true, encAlgs); int[] hashAlgs = {HashAlgorithmTags.SHA1, HashAlgorithmTags.SHA512, HashAlgorithmTags.SHA384, HashAlgorithmTags.SHA256, HashAlgorithmTags.RIPEMD160}; svg.setPreferredHashAlgorithms(true, hashAlgs); int[] comprAlgs = {CompressionAlgorithmTags.ZLIB, CompressionAlgorithmTags.BZIP2, CompressionAlgorithmTags.ZIP}; svg.setPreferredCompressionAlgorithms(true, comprAlgs); svg.setFeature(true, Features.FEATURE_MODIFICATION_DETECTION); svg.setKeyFlags(true, KeyFlags.CERTIFY_OTHER + KeyFlags.SIGN_DATA); PGPSignatureSubpacketVector hashedPcks = svg.generate(); PGPDigestCalculator sha1Calc = new JcaPGPDigestCalculatorProviderBuilder().build().get(HashAlgorithmTags.SHA1); PGPKeyRingGenerator keyRingGen = new PGPKeyRingGenerator(PGPSignature.POSITIVE_CERTIFICATION, sgnKeyPair, identity, sha1Calc, hashedPcks, unhashedPcks, new JcaPGPContentSignerBuilder(sgnKeyPair.getPublicKey().getAlgorithm(), HashAlgorithmTags.SHA1), new JcePBESecretKeyEncryptorBuilder(PGPEncryptedData.AES_256).setProvider("BC").build(passPhrase)); svg = new PGPSignatureSubpacketGenerator(); svg.setKeyExpirationTime(true, 86400L * 366 * 2); svg.setKeyFlags(true, KeyFlags.ENCRYPT_COMMS + KeyFlags.ENCRYPT_STORAGE); svg.setPrimaryUserID(true, false); svg.setFeature(true, Features.FEATURE_MODIFICATION_DETECTION); hashedPcks = svg.generate(); keyRingGen.addSubKey(encKeyPair, hashedPcks, unhashedPcks); byte[] encodedKeyRing = keyRingGen.generatePublicKeyRing().getEncoded(); PGPPublicKeyRing keyRing = new PGPPublicKeyRing(encodedKeyRing, new JcaKeyFingerprintCalculator()); for (Iterator it = keyRing.getPublicKeys(); it.hasNext();) { PGPPublicKey pKey = (PGPPublicKey)it.next(); PGPSignatureGenerator keySigGen = new PGPSignatureGenerator(new JcaPGPContentSignerBuilder(PGPPublicKey.RSA_SIGN, HashAlgorithmTags.SHA1).setProvider("BC")); if (pKey.isMasterKey()) { keySigGen.init(PGPSignature.POSITIVE_CERTIFICATION, sgnKeyPair.getPrivateKey()); } else { keySigGen.init(PGPSignature.SUBKEY_BINDING, sgnKeyPair.getPrivateKey()); } svg = new PGPSignatureSubpacketGenerator(); svg.setKeyExpirationTime(true, 86400L * 366 * 3); keySigGen.setHashedSubpackets(svg.generate()); pKey = PGPPublicKey.addCertification(pKey, keySigGen.generateCertification(pKey)); if (pKey.isEncryptionKey()) { if (pKey.getValidSeconds() != 86400L * 366 * 3) { fail("key expiration time wrong"); } } else { if (pKey.getValidSeconds() != 86400L * 366 * 3) { fail("key expiration time wrong"); } } } } public void performTest() throws Exception { PublicKey pubKey = null; // // Read the public key // PGPPublicKeyRing pgpPub = new PGPPublicKeyRing(testPubKey); pubKey = pgpPub.getPublicKey().getKey("BC"); Iterator it = pgpPub.getPublicKey().getUserIDs(); String uid = (String)it.next(); it = pgpPub.getPublicKey().getSignaturesForID(uid); PGPSignature sig = (PGPSignature)it.next(); sig.initVerify(pgpPub.getPublicKey(), "BC"); if (!sig.verifyCertification(uid, pgpPub.getPublicKey())) { fail("failed to verify certification"); } // // write a public key // ByteArrayOutputStream bOut = new ByteArrayOutputStream(); BCPGOutputStream pOut = new BCPGOutputStream(bOut); pgpPub.encode(pOut); if (!areEqual(bOut.toByteArray(), testPubKey)) { fail("public key rewrite failed"); } // // Read the public key // PGPPublicKeyRing pgpPubV3 = new PGPPublicKeyRing(testPubKeyV3); PublicKey pubKeyV3 = pgpPub.getPublicKey().getKey("BC"); // // write a V3 public key // bOut = new ByteArrayOutputStream(); pOut = new BCPGOutputStream(bOut); pgpPubV3.encode(pOut); // // Read a v3 private key // char[] passP = "FIXCITY_QA".toCharArray(); if (!noIDEA()) { PGPSecretKeyRing pgpPriv = new PGPSecretKeyRing(testPrivKeyV3, new JcaKeyFingerprintCalculator()); PGPPrivateKey pgpPrivKey = pgpPriv.getSecretKey().extractPrivateKey(passP, "BC"); // // write a v3 private key // bOut = new ByteArrayOutputStream(); pOut = new BCPGOutputStream(bOut); pgpPriv.encode(pOut); if (!areEqual(bOut.toByteArray(), testPrivKeyV3)) { fail("private key V3 rewrite failed"); } } // // Read the private key // PGPSecretKeyRing pgpPriv = new PGPSecretKeyRing(testPrivKey, new JcaKeyFingerprintCalculator()); PGPPrivateKey pgpPrivKey = pgpPriv.getSecretKey().extractPrivateKey(pass, "BC"); // // write a private key // bOut = new ByteArrayOutputStream(); pOut = new BCPGOutputStream(bOut); pgpPriv.encode(pOut); if (!areEqual(bOut.toByteArray(), testPrivKey)) { fail("private key rewrite failed"); } // // test encryption // Cipher c = Cipher.getInstance("RSA", "BC"); c.init(Cipher.ENCRYPT_MODE, pubKey); byte[] in = "hello world".getBytes(); byte[] out = c.doFinal(in); c.init(Cipher.DECRYPT_MODE, pgpPrivKey.getKey()); out = c.doFinal(out); if (!areEqual(in, out)) { fail("decryption failed."); } // // test signature message // PGPObjectFactory pgpFact = new PGPObjectFactory(sig1); PGPCompressedData c1 = (PGPCompressedData)pgpFact.nextObject(); pgpFact = new PGPObjectFactory(c1.getDataStream()); PGPOnePassSignatureList p1 = (PGPOnePassSignatureList)pgpFact.nextObject(); PGPOnePassSignature ops = p1.get(0); PGPLiteralData p2 = (PGPLiteralData)pgpFact.nextObject(); InputStream dIn = p2.getInputStream(); int ch; ops.initVerify(pgpPub.getPublicKey(ops.getKeyID()), "BC"); while ((ch = dIn.read()) >= 0) { ops.update((byte)ch); } PGPSignatureList p3 = (PGPSignatureList)pgpFact.nextObject(); if (!ops.verify(p3.get(0))) { fail("Failed signature check"); } // // encrypted message - read subkey // pgpPriv = new PGPSecretKeyRing(subKey, new JcaKeyFingerprintCalculator()); // // encrypted message // byte[] text = { (byte)'h', (byte)'e', (byte)'l', (byte)'l', (byte)'o', (byte)' ', (byte)'w', (byte)'o', (byte)'r', (byte)'l', (byte)'d', (byte)'!', (byte)'\n' }; PGPObjectFactory pgpF = new PGPObjectFactory(enc1); PGPEncryptedDataList encList = (PGPEncryptedDataList)pgpF.nextObject(); PGPPublicKeyEncryptedData encP = (PGPPublicKeyEncryptedData)encList.get(0); pgpPrivKey = pgpPriv.getSecretKey(encP.getKeyID()).extractPrivateKey(pass, "BC"); InputStream clear = encP.getDataStream(pgpPrivKey, "BC"); pgpFact = new PGPObjectFactory(clear); c1 = (PGPCompressedData)pgpFact.nextObject(); pgpFact = new PGPObjectFactory(c1.getDataStream()); PGPLiteralData ld = (PGPLiteralData)pgpFact.nextObject(); bOut = new ByteArrayOutputStream(); if (!ld.getFileName().equals("test.txt")) { throw new RuntimeException("wrong filename in packet"); } InputStream inLd = ld.getDataStream(); while ((ch = inLd.read()) >= 0) { bOut.write(ch); } if (!areEqual(bOut.toByteArray(), text)) { fail("wrong plain text in decrypted packet"); } // // encrypt - short message // byte[] shortText = { (byte)'h', (byte)'e', (byte)'l', (byte)'l', (byte)'o' }; ByteArrayOutputStream cbOut = new ByteArrayOutputStream(); PGPEncryptedDataGenerator cPk = new PGPEncryptedDataGenerator(SymmetricKeyAlgorithmTags.CAST5, new SecureRandom(), "BC"); PGPPublicKey puK = pgpPriv.getSecretKey(encP.getKeyID()).getPublicKey(); cPk.addMethod(puK); OutputStream cOut = cPk.open(new UncloseableOutputStream(cbOut), shortText.length); cOut.write(shortText); cOut.close(); pgpF = new PGPObjectFactory(cbOut.toByteArray()); encList = (PGPEncryptedDataList)pgpF.nextObject(); encP = (PGPPublicKeyEncryptedData)encList.get(0); pgpPrivKey = pgpPriv.getSecretKey(encP.getKeyID()).extractPrivateKey(pass, "BC"); if (encP.getSymmetricAlgorithm(pgpPrivKey, "BC") != SymmetricKeyAlgorithmTags.CAST5) { fail("symmetric algorithm mismatch"); } clear = encP.getDataStream(pgpPrivKey, "BC"); bOut.reset(); while ((ch = clear.read()) >= 0) { bOut.write(ch); } out = bOut.toByteArray(); if (!areEqual(out, shortText)) { fail("wrong plain text in generated short text packet"); } // // encrypt // cbOut = new ByteArrayOutputStream(); cPk = new PGPEncryptedDataGenerator(SymmetricKeyAlgorithmTags.CAST5, new SecureRandom(), "BC"); puK = pgpPriv.getSecretKey(encP.getKeyID()).getPublicKey(); cPk.addMethod(puK); cOut = cPk.open(new UncloseableOutputStream(cbOut), text.length); cOut.write(text); cOut.close(); pgpF = new PGPObjectFactory(cbOut.toByteArray()); encList = (PGPEncryptedDataList)pgpF.nextObject(); encP = (PGPPublicKeyEncryptedData)encList.get(0); pgpPrivKey = pgpPriv.getSecretKey(encP.getKeyID()).extractPrivateKey(pass, "BC"); clear = encP.getDataStream(pgpPrivKey, "BC"); bOut.reset(); while ((ch = clear.read()) >= 0) { bOut.write(ch); } out = bOut.toByteArray(); if (!areEqual(out, text)) { fail("wrong plain text in generated packet"); } // // read public key with sub key. // pgpF = new PGPObjectFactory(subPubKey); Object o; while ((o = pgpFact.nextObject()) != null) { // System.out.println(o); } // // key pair generation - CAST5 encryption // char[] passPhrase = "hello".toCharArray(); KeyPairGenerator kpg = KeyPairGenerator.getInstance("RSA", "BC"); kpg.initialize(1024); KeyPair kp = kpg.generateKeyPair(); PGPSecretKey secretKey = new PGPSecretKey(PGPSignature.DEFAULT_CERTIFICATION, PublicKeyAlgorithmTags.RSA_GENERAL, kp.getPublic(), kp.getPrivate(), new Date(), "fred", SymmetricKeyAlgorithmTags.CAST5, passPhrase, null, null, new SecureRandom(), "BC"); PGPPublicKey key = secretKey.getPublicKey(); it = key.getUserIDs(); uid = (String)it.next(); it = key.getSignaturesForID(uid); sig = (PGPSignature)it.next(); sig.initVerify(key, "BC"); if (!sig.verifyCertification(uid, key)) { fail("failed to verify certification"); } pgpPrivKey = secretKey.extractPrivateKey(passPhrase, "BC"); key = PGPPublicKey.removeCertification(key, uid, sig); if (key == null) { fail("failed certification removal"); } byte[] keyEnc = key.getEncoded(); key = PGPPublicKey.addCertification(key, uid, sig); keyEnc = key.getEncoded(); PGPSignatureGenerator sGen = new PGPSignatureGenerator(PublicKeyAlgorithmTags.RSA_GENERAL, HashAlgorithmTags.SHA1, "BC"); sGen.initSign(PGPSignature.KEY_REVOCATION, secretKey.extractPrivateKey(passPhrase, "BC")); sig = sGen.generateCertification(key); key = PGPPublicKey.addCertification(key, sig); keyEnc = key.getEncoded(); PGPPublicKeyRing tmpRing = new PGPPublicKeyRing(keyEnc); key = tmpRing.getPublicKey(); Iterator sgIt = key.getSignaturesOfType(PGPSignature.KEY_REVOCATION); sig = (PGPSignature)sgIt.next(); sig.initVerify(key, "BC"); if (!sig.verifyCertification(key)) { fail("failed to verify revocation certification"); } // // use of PGPKeyPair // PGPKeyPair pgpKp = new JcaPGPKeyPair(PGPPublicKey.RSA_GENERAL , kp, new Date()); PGPPublicKey k1 = pgpKp.getPublicKey(); PGPPrivateKey k2 = pgpKp.getPrivateKey(); k1.getEncoded(); mixedTest(k2, k1); // // key pair generation - AES_256 encryption. // kp = kpg.generateKeyPair(); secretKey = new PGPSecretKey(PGPSignature.DEFAULT_CERTIFICATION, PublicKeyAlgorithmTags.RSA_GENERAL, kp.getPublic(), kp.getPrivate(), new Date(), "fred", SymmetricKeyAlgorithmTags.AES_256, passPhrase, null, null, new SecureRandom(), "BC"); secretKey.extractPrivateKey(passPhrase, "BC"); secretKey.encode(new ByteArrayOutputStream()); // // secret key password changing. // String newPass = "newPass"; secretKey = PGPSecretKey.copyWithNewPassword(secretKey, passPhrase, newPass.toCharArray(), secretKey.getKeyEncryptionAlgorithm(), new SecureRandom(), "BC"); secretKey.extractPrivateKey(newPass.toCharArray(), "BC"); secretKey.encode(new ByteArrayOutputStream()); key = secretKey.getPublicKey(); key.encode(new ByteArrayOutputStream()); it = key.getUserIDs(); uid = (String)it.next(); it = key.getSignaturesForID(uid); sig = (PGPSignature)it.next(); sig.initVerify(key, "BC"); if (!sig.verifyCertification(uid, key)) { fail("failed to verify certification"); } pgpPrivKey = secretKey.extractPrivateKey(newPass.toCharArray(), "BC"); // // signature generation // String data = "hello world!"; bOut = new ByteArrayOutputStream(); ByteArrayInputStream testIn = new ByteArrayInputStream(data.getBytes()); sGen = new PGPSignatureGenerator(PublicKeyAlgorithmTags.RSA_GENERAL, HashAlgorithmTags.SHA1, "BC"); sGen.initSign(PGPSignature.BINARY_DOCUMENT, pgpPrivKey); PGPCompressedDataGenerator cGen = new PGPCompressedDataGenerator( PGPCompressedData.ZIP); BCPGOutputStream bcOut = new BCPGOutputStream( cGen.open(new UncloseableOutputStream(bOut))); sGen.generateOnePassVersion(false).encode(bcOut); PGPLiteralDataGenerator lGen = new PGPLiteralDataGenerator(); Date testDate = new Date((System.currentTimeMillis() / 1000) * 1000); OutputStream lOut = lGen.open( new UncloseableOutputStream(bcOut), PGPLiteralData.BINARY, "_CONSOLE", data.getBytes().length, testDate); while ((ch = testIn.read()) >= 0) { lOut.write(ch); sGen.update((byte)ch); } lOut.close(); sGen.generate().encode(bcOut); bcOut.close(); // // verify generated signature // pgpFact = new PGPObjectFactory(bOut.toByteArray()); c1 = (PGPCompressedData)pgpFact.nextObject(); pgpFact = new PGPObjectFactory(c1.getDataStream()); p1 = (PGPOnePassSignatureList)pgpFact.nextObject(); ops = p1.get(0); p2 = (PGPLiteralData)pgpFact.nextObject(); if (!p2.getModificationTime().equals(testDate)) { fail("Modification time not preserved: " + p2.getModificationTime() + " " + testDate); } dIn = p2.getInputStream(); ops.initVerify(secretKey.getPublicKey(), "BC"); while ((ch = dIn.read()) >= 0) { ops.update((byte)ch); } p3 = (PGPSignatureList)pgpFact.nextObject(); if (!ops.verify(p3.get(0))) { fail("Failed generated signature check"); } // // signature generation - version 3 // bOut = new ByteArrayOutputStream(); testIn = new ByteArrayInputStream(data.getBytes()); PGPV3SignatureGenerator sGenV3 = new PGPV3SignatureGenerator(PGPPublicKey.RSA_GENERAL, PGPUtil.SHA1, "BC"); sGen.initSign(PGPSignature.BINARY_DOCUMENT, pgpPrivKey); cGen = new PGPCompressedDataGenerator( PGPCompressedData.ZIP); bcOut = new BCPGOutputStream(cGen.open(bOut)); sGen.generateOnePassVersion(false).encode(bcOut); lGen = new PGPLiteralDataGenerator(); lOut = lGen.open( new UncloseableOutputStream(bcOut), PGPLiteralData.BINARY, "_CONSOLE", data.getBytes().length, testDate); while ((ch = testIn.read()) >= 0) { lOut.write(ch); sGen.update((byte)ch); } lOut.close(); sGen.generate().encode(bcOut); bcOut.close(); // // verify generated signature // pgpFact = new PGPObjectFactory(bOut.toByteArray()); c1 = (PGPCompressedData)pgpFact.nextObject(); pgpFact = new PGPObjectFactory(c1.getDataStream()); p1 = (PGPOnePassSignatureList)pgpFact.nextObject(); ops = p1.get(0); p2 = (PGPLiteralData)pgpFact.nextObject(); if (!p2.getModificationTime().equals(testDate)) { fail("Modification time not preserved"); } dIn = p2.getInputStream(); ops.initVerify(secretKey.getPublicKey(), "BC"); while ((ch = dIn.read()) >= 0) { ops.update((byte)ch); } p3 = (PGPSignatureList)pgpFact.nextObject(); if (!ops.verify(p3.get(0))) { fail("Failed v3 generated signature check"); } // // extract PGP 8 private key // pgpPriv = new PGPSecretKeyRing(pgp8Key); secretKey = pgpPriv.getSecretKey(); pgpPrivKey = secretKey.extractPrivateKey(pgp8Pass, "BC"); // // expiry // testExpiry(expiry60and30daysSig13Key, 60, 30); fingerPrintTest(); existingEmbeddedJpegTest(); embeddedJpegTest(); sigsubpacketTest(); multipleExpiryTest(); } private void testExpiry( byte[] encodedRing, int masterDays, int subKeyDays) throws Exception { PGPPublicKeyRing pubRing = new PGPPublicKeyRing(encodedRing); PGPPublicKey k = pubRing.getPublicKey(); if (k.getValidDays() != masterDays) { fail("mismatch on master valid days."); } Iterator it = pubRing.getPublicKeys(); it.next(); k = (PGPPublicKey)it.next(); if (k.getValidDays() != subKeyDays) { fail("mismatch on subkey valid days."); } } private boolean noIDEA() { try { Cipher.getInstance("IDEA", "BC"); return false; } catch (Exception e) { return true; } } public String getName() { return "PGPRSATest"; } public static void main( String[] args) { Security.addProvider(new BouncyCastleProvider()); runTest(new PGPRSATest()); } } bouncycastle-1.49.orig/test/src/org/bouncycastle/openpgp/test/PGPPBETest.java0000644000175000017500000003072210613545326026601 0ustar ebourgebourgpackage org.bouncycastle.openpgp.test; import org.bouncycastle.jce.provider.BouncyCastleProvider; import org.bouncycastle.openpgp.PGPCompressedData; import org.bouncycastle.openpgp.PGPCompressedDataGenerator; import org.bouncycastle.openpgp.PGPEncryptedData; import org.bouncycastle.openpgp.PGPEncryptedDataGenerator; import org.bouncycastle.openpgp.PGPEncryptedDataList; import org.bouncycastle.openpgp.PGPLiteralData; import org.bouncycastle.openpgp.PGPLiteralDataGenerator; import org.bouncycastle.openpgp.PGPObjectFactory; import org.bouncycastle.openpgp.PGPPBEEncryptedData; import org.bouncycastle.util.encoders.Base64; import org.bouncycastle.util.encoders.Hex; import org.bouncycastle.util.test.SimpleTest; import org.bouncycastle.util.test.UncloseableOutputStream; import java.io.ByteArrayOutputStream; import java.io.InputStream; import java.io.OutputStream; import java.security.SecureRandom; import java.security.Security; import java.util.Date; public class PGPPBETest extends SimpleTest { private static final Date TEST_DATE = new Date(1062200111000L); byte[] enc1 = Base64.decode( "jA0EAwMC5M5wWBP2HBZgySvUwWFAmMRLn7dWiZN6AkQMvpE3b6qwN3SSun7zInw2" + "hxxdgFzVGfbjuB8w"); byte[] enc1crc = Base64.decode("H66L"); char[] pass = { 'h', 'e', 'l', 'l', 'o', ' ', 'w', 'o', 'r', 'l', 'd' }; /** * Message with both PBE and symmetric */ byte[] testPBEAsym = Base64.decode( "hQIOA/ZlQEFWB5vuEAf/covEUaBve7NlWWdiO5NZubdtTHGElEXzG9hyBycp9At8" + "nZGi27xOZtEGFQo7pfz4JySRc3O0s6w7PpjJSonFJyNSxuze2LuqRwFWBYYcbS8/" + "7YcjB6PqutrT939OWsozfNqivI9/QyZCjBvFU89pp7dtUngiZ6MVv81ds2I+vcvk" + "GlIFcxcE1XoCIB3EvbqWNaoOotgEPT60unnB2BeDV1KD3lDRouMIYHfZ3SzBwOOI" + "6aK39sWnY5sAK7JjFvnDAMBdueOiI0Fy+gxbFD/zFDt4cWAVSAGTC4w371iqppmT" + "25TM7zAtCgpiq5IsELPlUZZnXKmnYQ7OCeysF0eeVwf+OFB9fyvCEv/zVQocJCg8" + "fWxfCBlIVFNeNQpeGygn/ZmRaILvB7IXDWP0oOw7/F2Ym66IdYYIp2HeEZv+jFwa" + "l41w5W4BH/gtbwGjFQ6CvF/m+lfUv6ZZdzsMIeEOwhP5g7rXBxrbcnGBaU+PXbho" + "gjDqaYzAWGlrmAd6aPSj51AGeYXkb2T1T/yoJ++M3GvhH4C4hvitamDkksh/qRnM" + "M/s8Nku6z1+RXO3M6p5QC1nlAVqieU8esT43945eSoC77K8WyujDNbysDyUCUTzt" + "p/aoQwe/HgkeOTJNelKR9y2W3xinZLFzep0SqpNI/e468yB/2/LGsykIyQa7JX6r" + "BYwuBAIDAkOKfv5rK8v0YDfnN+eFqwhTcrfBj5rDH7hER6nW3lNWcMataUiHEaMg" + "o6Q0OO1vptIGxW8jClTD4N1sCNwNu9vKny8dKYDDHbCjE06DNTv7XYVW3+JqTL5E" + "BnidvGgOmA=="); /** * decrypt the passed in message stream */ private byte[] decryptMessage( byte[] message, Date date) throws Exception { PGPObjectFactory pgpF = new PGPObjectFactory(message); PGPEncryptedDataList enc = (PGPEncryptedDataList)pgpF.nextObject(); PGPPBEEncryptedData pbe = (PGPPBEEncryptedData)enc.get(0); InputStream clear = pbe.getDataStream(pass, "BC"); PGPObjectFactory pgpFact = new PGPObjectFactory(clear); PGPCompressedData cData = (PGPCompressedData)pgpFact.nextObject(); pgpFact = new PGPObjectFactory(cData.getDataStream()); PGPLiteralData ld = (PGPLiteralData)pgpFact.nextObject(); ByteArrayOutputStream bOut = new ByteArrayOutputStream(); if (!ld.getFileName().equals("test.txt") && !ld.getFileName().equals("_CONSOLE")) { fail("wrong filename in packet"); } if (!ld.getModificationTime().equals(date)) { fail("wrong modification time in packet: " + ld.getModificationTime().getTime() + " " + date.getTime()); } InputStream unc = ld.getInputStream(); int ch; while ((ch = unc.read()) >= 0) { bOut.write(ch); } if (pbe.isIntegrityProtected() && !pbe.verify()) { fail("integrity check failed"); } return bOut.toByteArray(); } private byte[] decryptMessageBuffered( byte[] message, Date date) throws Exception { PGPObjectFactory pgpF = new PGPObjectFactory(message); PGPEncryptedDataList enc = (PGPEncryptedDataList)pgpF.nextObject(); PGPPBEEncryptedData pbe = (PGPPBEEncryptedData)enc.get(0); InputStream clear = pbe.getDataStream(pass, "BC"); PGPObjectFactory pgpFact = new PGPObjectFactory(clear); PGPCompressedData cData = (PGPCompressedData)pgpFact.nextObject(); pgpFact = new PGPObjectFactory(cData.getDataStream()); PGPLiteralData ld = (PGPLiteralData)pgpFact.nextObject(); ByteArrayOutputStream bOut = new ByteArrayOutputStream(); if (!ld.getFileName().equals("test.txt") && !ld.getFileName().equals("_CONSOLE")) { fail("wrong filename in packet"); } if (!ld.getModificationTime().equals(date)) { fail("wrong modification time in packet: " + ld.getModificationTime().getTime() + " " + date.getTime()); } InputStream unc = ld.getInputStream(); byte[] buf = new byte[1024]; int len; while ((len = unc.read(buf)) >= 0) { bOut.write(buf, 0, len); } if (pbe.isIntegrityProtected() && !pbe.verify()) { fail("integrity check failed"); } return bOut.toByteArray(); } public void performTest() throws Exception { byte[] out = decryptMessage(enc1, TEST_DATE); if (out[0] != 'h' || out[1] != 'e' || out[2] != 'l') { fail("wrong plain text in packet"); } // // create a PBE encrypted message and read it back. // byte[] text = { (byte)'h', (byte)'e', (byte)'l', (byte)'l', (byte)'o', (byte)' ', (byte)'w', (byte)'o', (byte)'r', (byte)'l', (byte)'d', (byte)'!', (byte)'\n' }; // // encryption step - convert to literal data, compress, encode. // ByteArrayOutputStream bOut = new ByteArrayOutputStream(); PGPCompressedDataGenerator comData = new PGPCompressedDataGenerator( PGPCompressedData.ZIP); Date cDate = new Date((System.currentTimeMillis() / 1000) * 1000); PGPLiteralDataGenerator lData = new PGPLiteralDataGenerator(); OutputStream comOut = comData.open(new UncloseableOutputStream(bOut)); OutputStream ldOut = lData.open( new UncloseableOutputStream(comOut), PGPLiteralData.BINARY, PGPLiteralData.CONSOLE, text.length, cDate); ldOut.write(text); ldOut.close(); comOut.close(); // // encrypt - with stream close // ByteArrayOutputStream cbOut = new ByteArrayOutputStream(); PGPEncryptedDataGenerator cPk = new PGPEncryptedDataGenerator(PGPEncryptedData.CAST5, new SecureRandom(), "BC"); cPk.addMethod(pass); OutputStream cOut = cPk.open(new UncloseableOutputStream(cbOut), bOut.toByteArray().length); cOut.write(bOut.toByteArray()); cOut.close(); out = decryptMessage(cbOut.toByteArray(), cDate); if (!areEqual(out, text)) { fail("wrong plain text in generated packet"); } // // encrypt - with generator close // cbOut = new ByteArrayOutputStream(); cPk = new PGPEncryptedDataGenerator(PGPEncryptedData.CAST5, new SecureRandom(), "BC"); cPk.addMethod(pass); cOut = cPk.open(new UncloseableOutputStream(cbOut), bOut.toByteArray().length); cOut.write(bOut.toByteArray()); cPk.close(); out = decryptMessage(cbOut.toByteArray(), cDate); if (!areEqual(out, text)) { fail("wrong plain text in generated packet"); } // // encrypt - partial packet style. // SecureRandom rand = new SecureRandom(); byte[] test = new byte[1233]; rand.nextBytes(test); bOut = new ByteArrayOutputStream(); comData = new PGPCompressedDataGenerator( PGPCompressedData.ZIP); comOut = comData.open(bOut); lData = new PGPLiteralDataGenerator(); ldOut = lData.open(new UncloseableOutputStream(comOut), PGPLiteralData.BINARY, PGPLiteralData.CONSOLE, TEST_DATE, new byte[16]); ldOut.write(test); ldOut.close(); comOut.close(); cbOut = new ByteArrayOutputStream(); cPk = new PGPEncryptedDataGenerator(PGPEncryptedData.CAST5, rand, "BC"); cPk.addMethod(pass); cOut = cPk.open(new UncloseableOutputStream(cbOut), new byte[16]); cOut.write(bOut.toByteArray()); cOut.close(); out = decryptMessage(cbOut.toByteArray(), TEST_DATE); if (!areEqual(out, test)) { fail("wrong plain text in generated packet"); } // // with integrity packet // cbOut = new ByteArrayOutputStream(); cPk = new PGPEncryptedDataGenerator(PGPEncryptedData.CAST5, true, rand, "BC"); cPk.addMethod(pass); cOut = cPk.open(new UncloseableOutputStream(cbOut), new byte[16]); cOut.write(bOut.toByteArray()); cOut.close(); out = decryptMessage(cbOut.toByteArray(), TEST_DATE); if (!areEqual(out, test)) { fail("wrong plain text in generated packet"); } // // decrypt with buffering // out = decryptMessageBuffered(cbOut.toByteArray(), TEST_DATE); if (!areEqual(out, test)) { fail("wrong plain text in buffer generated packet"); } // // sample message // PGPObjectFactory pgpFact = new PGPObjectFactory(testPBEAsym); PGPEncryptedDataList enc = (PGPEncryptedDataList)pgpFact.nextObject(); PGPPBEEncryptedData pbe = (PGPPBEEncryptedData)enc.get(1); InputStream clear = pbe.getDataStream("password".toCharArray(), "BC"); pgpFact = new PGPObjectFactory(clear); PGPLiteralData ld = (PGPLiteralData)pgpFact.nextObject(); bOut = new ByteArrayOutputStream(); InputStream unc = ld.getInputStream(); int ch; while ((ch = unc.read()) >= 0) { bOut.write(ch); } if (!areEqual(bOut.toByteArray(), Hex.decode("5361742031302e30322e30370d0a"))) { fail("data mismatch on combined PBE"); } // // with integrity packet - one byte message // byte[] msg = new byte[1]; bOut = new ByteArrayOutputStream(); comData = new PGPCompressedDataGenerator( PGPCompressedData.ZIP); lData = new PGPLiteralDataGenerator(); comOut = comData.open(new UncloseableOutputStream(bOut)); ldOut = lData.open( new UncloseableOutputStream(comOut), PGPLiteralData.BINARY, PGPLiteralData.CONSOLE, msg.length, cDate); ldOut.write(msg); ldOut.close(); comOut.close(); cbOut = new ByteArrayOutputStream(); cPk = new PGPEncryptedDataGenerator(PGPEncryptedData.CAST5, true, rand, "BC"); cPk.addMethod(pass); cOut = cPk.open(new UncloseableOutputStream(cbOut), new byte[16]); cOut.write(bOut.toByteArray()); cOut.close(); out = decryptMessage(cbOut.toByteArray(), cDate); if (!areEqual(out, msg)) { fail("wrong plain text in generated packet"); } // // decrypt with buffering // out = decryptMessageBuffered(cbOut.toByteArray(), cDate); if (!areEqual(out, msg)) { fail("wrong plain text in buffer generated packet"); } } public String getName() { return "PGPPBETest"; } public static void main( String[] args) { Security.addProvider(new BouncyCastleProvider()); runTest(new PGPPBETest()); } } bouncycastle-1.49.orig/test/src/org/bouncycastle/openpgp/test/package.html0000644000175000017500000000033710330633061026367 0ustar ebourgebourg Regression tests and further examples of use for the org.bouncycastle.openpgp package.

    Note: The classes in this package are also a useful source of example code. bouncycastle-1.49.orig/test/src/org/bouncycastle/openpgp/test/RegressionTest.java0000644000175000017500000000227212145535513027742 0ustar ebourgebourgpackage org.bouncycastle.openpgp.test; import java.security.Security; import org.bouncycastle.util.test.Test; import org.bouncycastle.util.test.TestResult; public class RegressionTest { public static Test[] tests = { new BcPGPKeyRingTest(), new PGPKeyRingTest(), new BcPGPRSATest(), new PGPRSATest(), new BcPGPDSATest(), new PGPDSATest(), new BcPGPDSAElGamalTest(), new PGPDSAElGamalTest(), new BcPGPPBETest(), new PGPPBETest(), new PGPMarkerTest(), new PGPPacketTest(), new PGPArmoredTest(), new PGPSignatureTest(), new PGPClearSignedSignatureTest(), new PGPCompressionTest(), new PGPNoPrivateKeyTest() }; public static void main( String[] args) { Security.addProvider(new org.bouncycastle.jce.provider.BouncyCastleProvider()); for (int i = 0; i != tests.length; i++) { TestResult result = tests[i].perform(); System.out.println(result); if (result.getException() != null) { result.getException().printStackTrace(); } } } } bouncycastle-1.49.orig/test/src/org/bouncycastle/openpgp/examples/0000755000175000017500000000000012152033550024743 5ustar ebourgebourgbouncycastle-1.49.orig/test/src/org/bouncycastle/openpgp/examples/test/0000755000175000017500000000000012152033550025722 5ustar ebourgebourgbouncycastle-1.49.orig/test/src/org/bouncycastle/openpgp/examples/test/AllTests.java0000644000175000017500000003375711042356631030344 0ustar ebourgebourgpackage org.bouncycastle.openpgp.examples.test; import junit.framework.Test; import junit.framework.TestCase; import junit.framework.TestSuite; import org.bouncycastle.openpgp.examples.ClearSignedFileProcessor; import org.bouncycastle.openpgp.examples.DSAElGamalKeyRingGenerator; import org.bouncycastle.openpgp.examples.KeyBasedFileProcessor; import org.bouncycastle.openpgp.examples.KeyBasedLargeFileProcessor; import org.bouncycastle.openpgp.examples.PBEFileProcessor; import org.bouncycastle.openpgp.examples.RSAKeyPairGenerator; import org.bouncycastle.openpgp.examples.SignedFileProcessor; import org.bouncycastle.util.encoders.Base64; import java.io.BufferedReader; import java.io.BufferedWriter; import java.io.ByteArrayInputStream; import java.io.ByteArrayOutputStream; import java.io.FileOutputStream; import java.io.FileWriter; import java.io.IOException; import java.io.InputStreamReader; import java.io.PrintStream; public class AllTests extends TestCase { byte[] clearSignedPublicKey = Base64.decode( "mQELBEQh2+wBCAD26kte0hO6flr7Y2aetpPYutHY4qsmDPy+GwmmqVeCDkX+" + "r1g7DuFbMhVeu0NkKDnVl7GsJ9VarYsFYyqu0NzLa9XS2qlTIkmJV+2/xKa1" + "tzjn18fT/cnAWL88ZLCOWUr241aPVhLuIc6vpHnySpEMkCh4rvMaimnTrKwO" + "42kgeDGd5cXfs4J4ovRcTbc4hmU2BRVsRjiYMZWWx0kkyL2zDVyaJSs4yVX7" + "Jm4/LSR1uC/wDT0IJJuZT/gQPCMJNMEsVCziRgYkAxQK3OWojPSuv4rXpyd4" + "Gvo6IbvyTgIskfpSkCnQtORNLIudQSuK7pW+LkL62N+ohuKdMvdxauOnAAYp" + "tBNnZ2dnZ2dnZyA8Z2dnQGdnZ2c+iQE2BBMBAgAgBQJEIdvsAhsDBgsJCAcD" + "AgQVAggDBBYCAwECHgECF4AACgkQ4M/Ier3f9xagdAf/fbKWBjLQM8xR7JkR" + "P4ri8YKOQPhK+VrddGUD59/wzVnvaGyl9MZE7TXFUeniQq5iXKnm22EQbYch" + "v2Jcxyt2H9yptpzyh4tP6tEHl1C887p2J4qe7F2ATua9CzVGwXQSUbKtj2fg" + "UZP5SsNp25guhPiZdtkf2sHMeiotmykFErzqGMrvOAUThrO63GiYsRk4hF6r" + "cQ01d+EUVpY/sBcCxgNyOiB7a84sDtrxnX5BTEZDTEj8LvuEyEV3TMUuAjx1" + "7Eyd+9JtKzwV4v3hlTaWOvGro9nPS7YaPuG+RtufzXCUJPbPfTjTvtGOqvEz" + "oztls8tuWA0OGHba9XfX9rfgorACAAM="); String crOnlyMessage = "\r" + " hello world!\r" + "\r" + "- dash\r"; String nlOnlyMessage = "\n" + " hello world!\n" + "\n" + "- dash\n"; String crNlMessage = "\r\n" + " hello world!\r\n" + "\r\n" + "- dash\r\n"; String crNlMessageTrailingWhiteSpace = "\r\n" + " hello world! \t\r\n" + "\r\n" + "\r\n"; String crOnlySignedMessage = "-----BEGIN PGP SIGNED MESSAGE-----\r" + "Hash: SHA256\r" + "\r" + "\r" + " hello world!\r" + "\r" + "- - dash\r" + "-----BEGIN PGP SIGNATURE-----\r" + "Version: GnuPG v1.4.2.1 (GNU/Linux)\r" + "\r" + "iQEVAwUBRCNS8+DPyHq93/cWAQi6SwgAj3ItmSLr/sd/ixAQLW7/12jzEjfNmFDt\r" + "WOZpJFmXj0fnMzTrOILVnbxHv2Ru+U8Y1K6nhzFSR7d28n31/XGgFtdohDEaFJpx\r" + "Fl+KvASKIonnpEDjFJsPIvT1/G/eCPalwO9IuxaIthmKj0z44SO1VQtmNKxdLAfK\r" + "+xTnXGawXS1WUE4CQGPM45mIGSqXcYrLtJkAg3jtRa8YRUn2d7b2BtmWH+jVaVuC\r" + "hNrXYv7iHFOu25yRWhUQJisvdC13D/gKIPRvARXPgPhAC2kovIy6VS8tDoyG6Hm5\r" + "dMgLEGhmqsgaetVq1ZIuBZj5S4j2apBJCDpF6GBfpBOfwIZs0Tpmlw==\r" + "=84Nd\r" + "-----END PGP SIGNATURE-----\r"; String nlOnlySignedMessage = "-----BEGIN PGP SIGNED MESSAGE-----\n" + "Hash: SHA256\n" + "\n" + "\n" + " hello world!\n" + "\n" + "- - dash\n" + "-----BEGIN PGP SIGNATURE-----\n" + "Version: GnuPG v1.4.2.1 (GNU/Linux)\n" + "\n" + "iQEVAwUBRCNS8+DPyHq93/cWAQi6SwgAj3ItmSLr/sd/ixAQLW7/12jzEjfNmFDt\n" + "WOZpJFmXj0fnMzTrOILVnbxHv2Ru+U8Y1K6nhzFSR7d28n31/XGgFtdohDEaFJpx\n" + "Fl+KvASKIonnpEDjFJsPIvT1/G/eCPalwO9IuxaIthmKj0z44SO1VQtmNKxdLAfK\n" + "+xTnXGawXS1WUE4CQGPM45mIGSqXcYrLtJkAg3jtRa8YRUn2d7b2BtmWH+jVaVuC\n" + "hNrXYv7iHFOu25yRWhUQJisvdC13D/gKIPRvARXPgPhAC2kovIy6VS8tDoyG6Hm5\n" + "dMgLEGhmqsgaetVq1ZIuBZj5S4j2apBJCDpF6GBfpBOfwIZs0Tpmlw==\n" + "=84Nd\n" + "-----END PGP SIGNATURE-----\n"; String crNlSignedMessage = "-----BEGIN PGP SIGNED MESSAGE-----\r\n" + "Hash: SHA256\r\n" + "\r\n" + "\r\n" + " hello world!\r\n" + "\r\n" + "- - dash\r\n" + "-----BEGIN PGP SIGNATURE-----\r\n" + "Version: GnuPG v1.4.2.1 (GNU/Linux)\r\n" + "\r\n" + "iQEVAwUBRCNS8+DPyHq93/cWAQi6SwgAj3ItmSLr/sd/ixAQLW7/12jzEjfNmFDt\r\n" + "WOZpJFmXj0fnMzTrOILVnbxHv2Ru+U8Y1K6nhzFSR7d28n31/XGgFtdohDEaFJpx\r\n" + "Fl+KvASKIonnpEDjFJsPIvT1/G/eCPalwO9IuxaIthmKj0z44SO1VQtmNKxdLAfK\r\n" + "+xTnXGawXS1WUE4CQGPM45mIGSqXcYrLtJkAg3jtRa8YRUn2d7b2BtmWH+jVaVuC\r\n" + "hNrXYv7iHFOu25yRWhUQJisvdC13D/gKIPRvARXPgPhAC2kovIy6VS8tDoyG6Hm5\r\n" + "dMgLEGhmqsgaetVq1ZIuBZj5S4j2apBJCDpF6GBfpBOfwIZs0Tpmlw==\r\n" + "=84Nd\r" + "-----END PGP SIGNATURE-----\r\n"; String crNlSignedMessageTrailingWhiteSpace = "-----BEGIN PGP SIGNED MESSAGE-----\r\n" + "Hash: SHA256\r\n" + "\r\n" + "\r\n" + " hello world! \t\r\n" + "\r\n" + "- - dash\r\n" + "-----BEGIN PGP SIGNATURE-----\r\n" + "Version: GnuPG v1.4.2.1 (GNU/Linux)\r\n" + "\r\n" + "iQEVAwUBRCNS8+DPyHq93/cWAQi6SwgAj3ItmSLr/sd/ixAQLW7/12jzEjfNmFDt\r\n" + "WOZpJFmXj0fnMzTrOILVnbxHv2Ru+U8Y1K6nhzFSR7d28n31/XGgFtdohDEaFJpx\r\n" + "Fl+KvASKIonnpEDjFJsPIvT1/G/eCPalwO9IuxaIthmKj0z44SO1VQtmNKxdLAfK\r\n" + "+xTnXGawXS1WUE4CQGPM45mIGSqXcYrLtJkAg3jtRa8YRUn2d7b2BtmWH+jVaVuC\r\n" + "hNrXYv7iHFOu25yRWhUQJisvdC13D/gKIPRvARXPgPhAC2kovIy6VS8tDoyG6Hm5\r\n" + "dMgLEGhmqsgaetVq1ZIuBZj5S4j2apBJCDpF6GBfpBOfwIZs0Tpmlw==\r\n" + "=84Nd\r" + "-----END PGP SIGNATURE-----\r\n"; private PrintStream _oldOut; private PrintStream _oldErr; private ByteArrayOutputStream _currentOut; private ByteArrayOutputStream _currentErr; public void setUp() throws Exception { _oldOut = System.out; _oldErr = System.err; _currentOut = new ByteArrayOutputStream(); _currentErr = new ByteArrayOutputStream(); System.setOut(new PrintStream(_currentOut)); System.setErr(new PrintStream(_currentErr)); } public void tearDown() { System.setOut(_oldOut); System.setErr(_oldErr); } public void testRSAKeyGeneration() throws Exception { RSAKeyPairGenerator.main(new String[] { "test", "password" }); createSmallTestInput(); createLargeTestInput(); checkSigning("bpg"); checkKeyBasedEncryption("bpg"); checkLargeKeyBasedEncryption("bpg"); RSAKeyPairGenerator.main(new String[] { "-a", "test", "password" }); checkSigning("asc"); checkKeyBasedEncryption("asc"); checkLargeKeyBasedEncryption("asc"); } public void testDSAElGamaleKeyGeneration() throws Exception { DSAElGamalKeyRingGenerator.main(new String[] { "test", "password" }); createSmallTestInput(); createLargeTestInput(); checkSigning("bpg"); checkKeyBasedEncryption("bpg"); checkLargeKeyBasedEncryption("bpg"); DSAElGamalKeyRingGenerator.main(new String[] { "-a", "test", "password" }); checkSigning("asc"); checkKeyBasedEncryption("asc"); checkLargeKeyBasedEncryption("asc"); } public void testPBEEncryption() throws Exception { _currentErr.reset(); PBEFileProcessor.main(new String[] { "-e", "test.txt", "password" }); PBEFileProcessor.main(new String[] { "-d", "test.txt.bpg", "password" }); assertEquals("no message integrity check", getLine(_currentErr)); PBEFileProcessor.main(new String[] { "-e", "-i", "test.txt", "password" }); PBEFileProcessor.main(new String[] { "-d", "test.txt.bpg", "password" }); assertEquals("message integrity check passed", getLine(_currentErr)); PBEFileProcessor.main(new String[] { "-e", "-ai", "test.txt", "password" }); PBEFileProcessor.main(new String[] { "-d", "test.txt.asc", "password" }); assertEquals("message integrity check passed", getLine(_currentErr)); } public void testClearSigned() throws Exception { createTestFile(clearSignedPublicKey, "pub.bpg"); checkClearSignedVerify(nlOnlySignedMessage); checkClearSignedVerify(crOnlySignedMessage); checkClearSignedVerify(crNlSignedMessage); checkClearSignedVerify(crNlSignedMessageTrailingWhiteSpace); ClearSignedFileProcessor.main(new String[] { "-v", "test.txt.asc", "pub.bpg" }); RSAKeyPairGenerator.main(new String[] { "test", "password" }); checkClearSigned(crOnlyMessage); checkClearSigned(nlOnlyMessage); checkClearSigned(crNlMessage); checkClearSigned(crNlMessageTrailingWhiteSpace); } public void testClearSignedBogusInput() throws Exception { createTestFile(clearSignedPublicKey, "test.txt"); ClearSignedFileProcessor.main(new String[] { "-s", "test.txt", "secret.bpg", "password" }); } private void checkClearSignedVerify(String message) throws Exception { createTestData(message, "test.txt.asc"); ClearSignedFileProcessor.main(new String[] { "-v", "test.txt.asc", "pub.bpg" }); } private void checkClearSigned(String message) throws Exception { createTestData(message, "test.txt"); ClearSignedFileProcessor.main(new String[] { "-s", "test.txt", "secret.bpg", "password" }); ClearSignedFileProcessor.main(new String[] { "-v", "test.txt.asc", "pub.bpg" }); } private void checkSigning(String type) throws Exception { _currentOut.reset(); SignedFileProcessor.main(new String[] { "-s", "test.txt", "secret." + type, "password" }); SignedFileProcessor.main(new String[] { "-v", "test.txt.bpg", "pub." + type }); assertEquals("signature verified.", getLine(_currentOut)); SignedFileProcessor.main(new String[] { "-s", "-a", "test.txt", "secret." + type, "password" }); SignedFileProcessor.main(new String[] { "-v", "test.txt.asc", "pub." + type }); assertEquals("signature verified.", getLine(_currentOut)); } private void checkKeyBasedEncryption(String type) throws Exception { _currentErr.reset(); KeyBasedFileProcessor.main(new String[] { "-e", "test.txt", "pub." + type }); KeyBasedFileProcessor.main(new String[] { "-d", "test.txt.bpg", "secret." + type, "password" }); assertEquals("no message integrity check", getLine(_currentErr)); KeyBasedFileProcessor.main(new String[] { "-e", "-i", "test.txt", "pub." + type }); KeyBasedFileProcessor.main(new String[] { "-d", "test.txt.bpg", "secret." + type, "password" }); assertEquals("message integrity check passed", getLine(_currentErr)); KeyBasedFileProcessor.main(new String[] { "-e", "-ai", "test.txt", "pub." + type }); KeyBasedFileProcessor.main(new String[] { "-d", "test.txt.asc", "secret." + type, "password" }); assertEquals("message integrity check passed", getLine(_currentErr)); } private void checkLargeKeyBasedEncryption(String type) throws Exception { _currentErr.reset(); KeyBasedLargeFileProcessor.main(new String[] { "-e", "large.txt", "pub." + type }); KeyBasedLargeFileProcessor.main(new String[] { "-d", "large.txt.bpg", "secret." + type, "password" }); assertEquals("no message integrity check", getLine(_currentErr)); KeyBasedLargeFileProcessor.main(new String[] { "-e", "-i", "large.txt", "pub." + type }); KeyBasedLargeFileProcessor.main(new String[] { "-d", "large.txt.bpg", "secret." + type, "password" }); assertEquals("message integrity check passed", getLine(_currentErr)); KeyBasedLargeFileProcessor.main(new String[] { "-e", "-ai", "large.txt", "pub." + type }); KeyBasedLargeFileProcessor.main(new String[] { "-d", "large.txt.asc", "secret." + type, "password" }); assertEquals("message integrity check passed", getLine(_currentErr)); } private void createSmallTestInput() throws IOException { BufferedWriter bfOut = new BufferedWriter(new FileWriter("test.txt")); bfOut.write("hello world!"); bfOut.newLine(); bfOut.close(); } private void createLargeTestInput() throws IOException { BufferedWriter bfOut = new BufferedWriter(new FileWriter("large.txt")); for (int i = 0; i != 2000; i++) { bfOut.write("hello world!"); bfOut.newLine(); } bfOut.close(); } private void createTestData(String testData, String name) throws IOException { BufferedWriter bfOut = new BufferedWriter(new FileWriter(name)); bfOut.write(testData); bfOut.close(); } private void createTestFile(byte[] keyData, String name) throws IOException { FileOutputStream fOut = new FileOutputStream(name); fOut.write(keyData); fOut.close(); } private String getLine( ByteArrayOutputStream out) throws IOException { BufferedReader bRd = new BufferedReader(new InputStreamReader(new ByteArrayInputStream(out.toByteArray()))); out.reset(); return bRd.readLine(); } public static void main (String[] args) { junit.textui.TestRunner.run(suite()); } public static Test suite() { TestSuite suite = new TestSuite("OpenPGP Example Tests"); suite.addTestSuite(AllTests.class); return suite; } } bouncycastle-1.49.orig/test/src/org/bouncycastle/crypto/0000755000175000017500000000000012152033550022775 5ustar ebourgebourgbouncycastle-1.49.orig/test/src/org/bouncycastle/crypto/tls/0000755000175000017500000000000012152033550023577 5ustar ebourgebourgbouncycastle-1.49.orig/test/src/org/bouncycastle/crypto/tls/test/0000755000175000017500000000000012152033550024556 5ustar ebourgebourgbouncycastle-1.49.orig/test/src/org/bouncycastle/crypto/tls/test/UnreliableDatagramTransport.java0000644000175000017500000000510012146536044033066 0ustar ebourgebourgpackage org.bouncycastle.crypto.tls.test; import java.io.IOException; import java.util.Random; import org.bouncycastle.crypto.tls.DatagramTransport; public class UnreliableDatagramTransport implements DatagramTransport { private final DatagramTransport transport; private final Random random; private final int percentPacketLossReceiving, percentPacketLossSending; public UnreliableDatagramTransport(DatagramTransport transport, Random random, int percentPacketLossReceiving, int percentPacketLossSending) { if (percentPacketLossReceiving < 0 || percentPacketLossReceiving > 100) { throw new IllegalArgumentException("'percentPacketLossReceiving' out of range"); } if (percentPacketLossSending < 0 || percentPacketLossSending > 100) { throw new IllegalArgumentException("'percentPacketLossSending' out of range"); } this.transport = transport; this.random = random; this.percentPacketLossReceiving = percentPacketLossReceiving; this.percentPacketLossSending = percentPacketLossSending; } public int getReceiveLimit() throws IOException { return transport.getReceiveLimit(); } public int getSendLimit() throws IOException { return transport.getSendLimit(); } public int receive(byte[] buf, int off, int len, int waitMillis) throws IOException { long endMillis = System.currentTimeMillis() + waitMillis; for (; ; ) { int length = transport.receive(buf, off, len, waitMillis); if (length < 0 || !lostPacket(percentPacketLossReceiving)) { return length; } System.out.println("PACKET LOSS (" + length + " byte packet not received)"); long now = System.currentTimeMillis(); if (now >= endMillis) { return -1; } waitMillis = (int)(endMillis - now); } } public void send(byte[] buf, int off, int len) throws IOException { if (lostPacket(percentPacketLossSending)) { System.out.println("PACKET LOSS (" + len + " byte packet not sent)"); } else { transport.send(buf, off, len); } } public void close() throws IOException { transport.close(); } private boolean lostPacket(int percentPacketLoss) { return random.nextInt(100) < percentPacketLoss; } } bouncycastle-1.49.orig/test/src/org/bouncycastle/crypto/tls/test/KeyStores.java0000644000175000017500000001752012146536044027367 0ustar ebourgebourgpackage org.bouncycastle.crypto.tls.test; import org.bouncycastle.util.encoders.Base64; public class KeyStores { static final byte[] trustStore = Base64.decode( "/u3+7QAAAAIAAAABAAAAAgAGc2VydmVyAAABD34zDJEABVguNTA5AAABrzCC" + "AaswggEUAgEBMA0GCSqGSIb3DQEBBQUAMB4xHDAaBgNVBAMTE1Rlc3QgQ0Eg" + "Q2VydGlmaWNhdGUwHhcNMDYxMjEzMjM0MzI5WhcNMDYxMjIwMjM0MzI5WjAe" + "MRwwGgYDVQQDExNUZXN0IENBIENlcnRpZmljYXRlMIGfMA0GCSqGSIb3DQEB" + "AQUAA4GNADCBiQKBgQCmOumCM46ehsdcrZMw6tj0hMl5D0xf21gcyBj/ByIv" + "pe008ukaN3zCXIUUUlAu0GkbI1sCbTD1V4qVZuaHqtfa/FINJjyZJy5w7KEx" + "93OOF2/gyPlnEPGs6RPdThAPliSBsWKBKqtOdmKpwYn/NKuUNFRkFXVLLUPn" + "jyEKjIcNywIDAQABMA0GCSqGSIb3DQEBBQUAA4GBACi8J7raYqDFjXqAXXPJ" + "ljZHqvzJNVaSWvBtK/oY7g0+sdGIjPR526fhSCxOZRr7G157ERqMnPjuFjcm" + "cRlUOPsQtTl6KbUnxmKxa04UzDuNXzSx2oyGx5GCWx9u62hpO6vSpK69L9gH" + "OUtM5dQXcoK4i3olScKaU8qaYb0mBAy8fnx5pen8B0bIg+pz47l5VxQ5NO8="); static final byte[] server = Base64.decode( "/u3+7QAAAAIAAAABAAAAAQAGc2VydmVyAAABD34zDJIAAAK8MIICuDAOBgor" + "BgEEASoCEQEBBQAEggKk9OXWj3aBr6rV9Grcsm2YL+/2ShVsxbJVGMSWll1f" + "U8z/mjhv5K/skgleTIMoyE5FzDDxJIGEmSMCkcHsnseXzxyhLpKBaz3N1Tk7" + "KVPzXfrNh0FJwzw3lPWyC2ayT+ObQfAtzuI9SUWNLBzzpWeolUJ8gkXnLshX" + "5RqmR735NRZdjgQOtNYBBErX/NOhTyi009/CZDNxgJQzywFmQcXBLhNSA+0i" + "cE+LwZ4sZV0NXshPZiyNnsfqN/XNOyhpKr8a3VyVtee2nhO9+FY5IDEviHmR" + "WDvH5TmB6Os3L6xvwE1ZQCPElk/cK2G1q9+zDBe4JDeo8o7lPhiNpVfcivnr" + "+tyK9m7PqlssR0+ohuZGwrFMyzLugkOWh+qZ3pk8/7AwJosMvvTvIg36nN7R" + "pdnouQNKqTm1Sr/UUnKyWqfG7zqKIuF72IkDwwafwuQ9YRX5PAOuRfo6bCyb" + "D4w1OWdfGFciKMc1BrT+8JzhiTkzNe+jWEA5Tw1zeazPGpp1RHPz2np50G2s" + "v025uiOSUilBe13Qpx0mAyx7z8Gl6eOxai6rQ/eB/Fu++BMx0OX8vO/K4//Q" + "w43IPVPklGlb/3Qt7eoNf4tichuxrYJjHu4XbwnzB29Vmsan0XZFER7epvFj" + "cAZCSG+O6G/f6Ib+7d7xYjLdUaPI60tJ4/C+AuYwZn4jJwTnMnMmwIypz4Z8" + "XPXW5SbHlV5OkkFC+eAuuN4b2YXZmifeWv4fx65Ioir921LMJrorMizH41RJ" + "/rAO5wGSwjeDJ784QhhLGbEUMygraRtdaz6MRx26InnoHY7V58ET3Z5YGV39" + "p+9AtVhYw/QQmTZiF7hqnEMf9AMVFfac9qFF2+IN3g9HAMC6QLxJ1VuPn5oo" + "lS//axPfjckO7iZx9x59/gAAAAEABVguNTA5AAABrzCCAaswggEUAgEBMA0G" + "CSqGSIb3DQEBBQUAMB4xHDAaBgNVBAMTE1Rlc3QgQ0EgQ2VydGlmaWNhdGUw" + "HhcNMDYxMjEzMjM0MzI5WhcNMDYxMjIwMjM0MzI5WjAeMRwwGgYDVQQDExNU" + "ZXN0IENBIENlcnRpZmljYXRlMIGfMA0GCSqGSIb3DQEBAQUAA4GNADCBiQKB" + "gQCmOumCM46ehsdcrZMw6tj0hMl5D0xf21gcyBj/ByIvpe008ukaN3zCXIUU" + "UlAu0GkbI1sCbTD1V4qVZuaHqtfa/FINJjyZJy5w7KEx93OOF2/gyPlnEPGs" + "6RPdThAPliSBsWKBKqtOdmKpwYn/NKuUNFRkFXVLLUPnjyEKjIcNywIDAQAB" + "MA0GCSqGSIb3DQEBBQUAA4GBACi8J7raYqDFjXqAXXPJljZHqvzJNVaSWvBt" + "K/oY7g0+sdGIjPR526fhSCxOZRr7G157ERqMnPjuFjcmcRlUOPsQtTl6KbUn" + "xmKxa04UzDuNXzSx2oyGx5GCWx9u62hpO6vSpK69L9gHOUtM5dQXcoK4i3ol" + "ScKaU8qaYb0mBAy87VQaPfaiQqqxSgqifbSowlg+0fg="); static final byte[] client = Base64.decode( "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"); } bouncycastle-1.49.orig/test/src/org/bouncycastle/crypto/tls/test/MockDTLSServer.java0000644000175000017500000000555512146540541030210 0ustar ebourgebourgpackage org.bouncycastle.crypto.tls.test; import java.io.IOException; import java.io.PrintStream; import org.bouncycastle.asn1.x509.Certificate; import org.bouncycastle.crypto.tls.AlertLevel; import org.bouncycastle.crypto.tls.CertificateRequest; import org.bouncycastle.crypto.tls.ClientCertificateType; import org.bouncycastle.crypto.tls.DefaultTlsServer; import org.bouncycastle.crypto.tls.ProtocolVersion; import org.bouncycastle.crypto.tls.TlsEncryptionCredentials; import org.bouncycastle.crypto.tls.TlsSignerCredentials; public class MockDTLSServer extends DefaultTlsServer { public void notifyAlertRaised(short alertLevel, short alertDescription, String message, Exception cause) { PrintStream out = (alertLevel == AlertLevel.fatal) ? System.err : System.out; out.println("DTLS server raised alert (AlertLevel." + alertLevel + ", AlertDescription." + alertDescription + ")"); if (message != null) { out.println(message); } if (cause != null) { cause.printStackTrace(out); } } public void notifyAlertReceived(short alertLevel, short alertDescription) { PrintStream out = (alertLevel == AlertLevel.fatal) ? System.err : System.out; out.println("DTLS server received alert (AlertLevel." + alertLevel + ", AlertDescription." + alertDescription + ")"); } public CertificateRequest getCertificateRequest() { return new CertificateRequest(new short[]{ClientCertificateType.rsa_sign}, null); } public void notifyClientCertificate(org.bouncycastle.crypto.tls.Certificate clientCertificate) throws IOException { Certificate[] chain = clientCertificate.getCertificateList(); System.out.println("Received client certificate chain of length " + chain.length); for (int i = 0; i != chain.length; i++) { Certificate entry = chain[i]; // TODO Create fingerprint based on certificate signature algorithm digest System.out.println(" fingerprint:SHA-256 " + TlsTestUtils.fingerprint(entry) + " (" + entry.getSubject() + ")"); } } protected ProtocolVersion getMaximumVersion() { return ProtocolVersion.DTLSv10; } protected ProtocolVersion getMinimumVersion() { return ProtocolVersion.DTLSv10; } protected TlsEncryptionCredentials getRSAEncryptionCredentials() throws IOException { return TlsTestUtils.loadEncryptionCredentials(context, new String[]{"x509-server.pem", "x509-ca.pem"}, "x509-server-key.pem"); } protected TlsSignerCredentials getRSASignerCredentials() throws IOException { return TlsTestUtils.loadSignerCredentials(context, new String[]{"x509-server.pem", "x509-ca.pem"}, "x509-server-key.pem"); } } bouncycastle-1.49.orig/test/src/org/bouncycastle/crypto/tls/test/TlsClientTest.java0000644000175000017500000000717012146540623030176 0ustar ebourgebourgpackage org.bouncycastle.crypto.tls.test; import java.io.IOException; import java.io.InputStream; import java.io.OutputStream; import java.io.PrintStream; import java.net.InetAddress; import java.net.Socket; import java.security.SecureRandom; import org.bouncycastle.asn1.x509.Certificate; import org.bouncycastle.crypto.tls.AlertLevel; import org.bouncycastle.crypto.tls.CipherSuite; import org.bouncycastle.crypto.tls.DefaultTlsClient; import org.bouncycastle.crypto.tls.ServerOnlyTlsAuthentication; import org.bouncycastle.crypto.tls.TlsAuthentication; import org.bouncycastle.crypto.tls.TlsClientProtocol; import org.bouncycastle.util.io.Streams; /** * A simple test designed to conduct a TLS handshake with an external TLS server. *

    * Please refer to GnuTLSSetup.txt or OpenSSLSetup.txt, and x509-*.pem files in this package for * help configuring an external TLS server. */ public class TlsClientTest { public static void main(String[] args) throws Exception { Socket socket = new Socket(InetAddress.getLocalHost(), 5556); SecureRandom secureRandom = new SecureRandom(); TlsClientProtocol protocol = new TlsClientProtocol(socket.getInputStream(), socket.getOutputStream(), secureRandom); MyTlsClient client = new MyTlsClient(); protocol.connect(client); OutputStream output = protocol.getOutputStream(); output.write("GET / HTTP/1.1\r\n\r\n".getBytes("UTF-8")); InputStream input = protocol.getInputStream(); byte[] result = Streams.readAll(input); System.out.println(new String(result, "UTF-8")); protocol.close(); socket.close(); } static class MyTlsClient extends DefaultTlsClient { public void notifyAlertRaised(short alertLevel, short alertDescription, String message, Exception cause) { PrintStream out = (alertLevel == AlertLevel.fatal) ? System.err : System.out; out.println("TLS client raised alert (AlertLevel." + alertLevel + ", AlertDescription." + alertDescription + ")"); if (message != null) { out.println(message); } if (cause != null) { cause.printStackTrace(out); } } public void notifyAlertReceived(short alertLevel, short alertDescription) { PrintStream out = (alertLevel == AlertLevel.fatal) ? System.err : System.out; out.println("TLS client received alert (AlertLevel." + alertLevel + ", AlertDescription." + alertDescription + ")"); } public int[] getCipherSuites() { return new int[]{CipherSuite.TLS_RSA_WITH_AES_256_CBC_SHA, CipherSuite.TLS_RSA_WITH_AES_128_CBC_SHA, CipherSuite.TLS_RSA_WITH_3DES_EDE_CBC_SHA,}; } public TlsAuthentication getAuthentication() throws IOException { return new ServerOnlyTlsAuthentication() { public void notifyServerCertificate(org.bouncycastle.crypto.tls.Certificate serverCertificate) throws IOException { Certificate[] chain = serverCertificate.getCertificateList(); System.out.println("Received server certificate chain with " + chain.length + " entries"); for (int i = 0; i != chain.length; i++) { Certificate entry = chain[i]; System.out.println(" " + entry.getSubject()); } } }; } } } bouncycastle-1.49.orig/test/src/org/bouncycastle/crypto/tls/test/BasicTlsTest.java0000644000175000017500000001427512146536044030007 0ustar ebourgebourgpackage org.bouncycastle.crypto.tls.test; import java.io.IOException; import java.io.InputStream; import java.io.OutputStream; import java.io.PrintStream; import java.net.Socket; import junit.framework.TestCase; import junit.framework.TestSuite; import org.bouncycastle.crypto.tls.AlertDescription; import org.bouncycastle.crypto.tls.AlertLevel; import org.bouncycastle.crypto.tls.AlwaysValidVerifyer; import org.bouncycastle.crypto.tls.Certificate; import org.bouncycastle.crypto.tls.CipherSuite; import org.bouncycastle.crypto.tls.DefaultTlsClient; import org.bouncycastle.crypto.tls.LegacyTlsClient; import org.bouncycastle.crypto.tls.TlsAuthentication; import org.bouncycastle.crypto.tls.TlsClient; import org.bouncycastle.crypto.tls.TlsClientProtocol; import org.bouncycastle.crypto.tls.TlsFatalAlert; import org.bouncycastle.crypto.tls.TlsKeyExchange; import org.bouncycastle.util.Arrays; import org.bouncycastle.util.encoders.Hex; public class BasicTlsTest extends TestCase { private static final int PORT_NO = 8003; // private static final String CLIENT = "client"; // private static final char[] CLIENT_PASSWORD = "clientPassword".toCharArray(); // private static final char[] SERVER_PASSWORD = "serverPassword".toCharArray(); // private static final char[] TRUST_STORE_PASSWORD = "trustPassword".toCharArray(); public void testConnection() throws Exception { Thread server = new HTTPSServerThread(); server.start(); Thread.yield(); AlwaysValidVerifyer verifyer = new AlwaysValidVerifyer(); Socket s = null; for (int i = 0; s == null && i != 3; i++) { Thread.sleep(1000); try { s = new Socket("localhost", PORT_NO); } catch (IOException e) { // ignore } } if (s == null) { throw new IOException("unable to connect"); } // long time = System.currentTimeMillis(); TlsClientProtocol protocol = new TlsClientProtocol(s.getInputStream(), s.getOutputStream()); protocol.connect(new LegacyTlsClient(verifyer)); InputStream is = protocol.getInputStream(); OutputStream os = protocol.getOutputStream(); os.write("GET / HTTP/1.1\r\n\r\n".getBytes()); // time = System.currentTimeMillis(); byte[] buf = new byte[4096]; int read = 0; int total = 0; while ((read = is.read(buf, total, buf.length - total)) > 0) { total += read; } is.close(); byte[] expected = Hex.decode("485454502f312e3120323030204f4b0d0a436f6e74656e742d547970653a20746578742f68" + "746d6c0d0a0d0a3c68746d6c3e0d0a3c626f64793e0d0a48656c6c6f20576f726c64210d0a3c2f626f64793e0d0a3c2f" + "68746d6c3e0d0a"); assertEquals(total, expected.length); byte[] tmp = new byte[expected.length]; System.arraycopy(buf, 0, tmp, 0, total); assertTrue(Arrays.areEqual(expected, tmp)); } public void testRSAConnectionClient() throws Exception { MyTlsClient client = new MyTlsClient(null); checkConnectionClient(client, CipherSuite.TLS_RSA_WITH_3DES_EDE_CBC_SHA, TlsTestUtils.rsaCertData); checkConnectionClient(client, CipherSuite.TLS_RSA_WITH_AES_128_CBC_SHA, TlsTestUtils.rsaCertData); checkConnectionClient(client, CipherSuite.TLS_RSA_WITH_AES_256_CBC_SHA, TlsTestUtils.rsaCertData); checkConnectionClient(client, CipherSuite.TLS_RSA_WITH_RC4_128_SHA, TlsTestUtils.rsaCertData); try { checkConnectionClient(client, CipherSuite.TLS_RSA_WITH_3DES_EDE_CBC_SHA, TlsTestUtils.dudRsaCertData); fail("dud certificate not caught"); } catch (TlsFatalAlert e) { assertEquals(AlertDescription.certificate_unknown, e.getAlertDescription()); } try { checkConnectionClient(client, CipherSuite.TLS_DH_anon_EXPORT_WITH_DES40_CBC_SHA, TlsTestUtils.rsaCertData); fail("wrong certificate not caught"); } catch (TlsFatalAlert e) { assertEquals(AlertDescription.internal_error, e.getAlertDescription()); } } private void checkConnectionClient(TlsClient client, int cipherSuite, byte[] encCert) throws Exception { client.notifySelectedCipherSuite(cipherSuite); TlsKeyExchange keyExchange = client.getKeyExchange(); keyExchange .processServerCertificate(new Certificate( new org.bouncycastle.asn1.x509.Certificate[]{org.bouncycastle.asn1.x509.Certificate .getInstance(encCert)})); } public static TestSuite suite() { return new TestSuite(BasicTlsTest.class); } public static void main(String[] args) throws Exception { junit.textui.TestRunner.run(suite()); } static class MyTlsClient extends DefaultTlsClient { public void notifyAlertRaised(short alertLevel, short alertDescription, String message, Exception cause) { PrintStream out = (alertLevel == AlertLevel.fatal) ? System.err : System.out; out.println("TLS client raised alert (AlertLevel." + alertLevel + ", AlertDescription." + alertDescription + ")"); if (message != null) { out.println(message); } if (cause != null) { cause.printStackTrace(out); } } public void notifyAlertReceived(short alertLevel, short alertDescription) { PrintStream out = (alertLevel == AlertLevel.fatal) ? System.err : System.out; out.println("TLS client received alert (AlertLevel." + alertLevel + ", AlertDescription." + alertDescription + ")"); } private final TlsAuthentication authentication; MyTlsClient(TlsAuthentication authentication) { this.authentication = authentication; } public TlsAuthentication getAuthentication() throws IOException { return authentication; } } } bouncycastle-1.49.orig/test/src/org/bouncycastle/crypto/tls/test/DTLSProtocolTest.java0000644000175000017500000000604012146536044030562 0ustar ebourgebourgpackage org.bouncycastle.crypto.tls.test; import java.security.SecureRandom; import junit.framework.TestCase; import org.bouncycastle.crypto.tls.DTLSClientProtocol; import org.bouncycastle.crypto.tls.DTLSServerProtocol; import org.bouncycastle.crypto.tls.DTLSTransport; import org.bouncycastle.crypto.tls.DatagramTransport; import org.bouncycastle.util.Arrays; public class DTLSProtocolTest extends TestCase { public void testClientServer() throws Exception { SecureRandom secureRandom = new SecureRandom(); DTLSClientProtocol clientProtocol = new DTLSClientProtocol(secureRandom); DTLSServerProtocol serverProtocol = new DTLSServerProtocol(secureRandom); MockDatagramAssociation network = new MockDatagramAssociation(1500); ServerThread serverThread = new ServerThread(serverProtocol, network.getServer()); serverThread.start(); DatagramTransport clientTransport = network.getClient(); clientTransport = new UnreliableDatagramTransport(clientTransport, secureRandom, 0, 0); clientTransport = new LoggingDatagramTransport(clientTransport, System.out); MockDTLSClient client = new MockDTLSClient(); DTLSTransport dtlsClient = clientProtocol.connect(client, clientTransport); for (int i = 1; i <= 10; ++i) { byte[] data = new byte[i]; Arrays.fill(data, (byte)i); dtlsClient.send(data, 0, data.length); } byte[] buf = new byte[dtlsClient.getReceiveLimit()]; while (dtlsClient.receive(buf, 0, buf.length, 1000) >= 0) { ; } dtlsClient.close(); serverThread.shutdown(); } static class ServerThread extends Thread { private final DTLSServerProtocol serverProtocol; private final DatagramTransport serverTransport; private volatile boolean isShutdown = false; ServerThread(DTLSServerProtocol serverProtocol, DatagramTransport serverTransport) { this.serverProtocol = serverProtocol; this.serverTransport = serverTransport; } public void run() { try { MockDTLSServer server = new MockDTLSServer(); DTLSTransport dtlsServer = serverProtocol.accept(server, serverTransport); byte[] buf = new byte[dtlsServer.getReceiveLimit()]; while (!isShutdown) { int length = dtlsServer.receive(buf, 0, buf.length, 1000); if (length >= 0) { dtlsServer.send(buf, 0, length); } } dtlsServer.close(); } catch (Exception e) { e.printStackTrace(); } } void shutdown() throws InterruptedException { if (!isShutdown) { isShutdown = true; this.join(); } } } } bouncycastle-1.49.orig/test/src/org/bouncycastle/crypto/tls/test/TlsTestUtils.java0000644000175000017500000001612612146536044030063 0ustar ebourgebourgpackage org.bouncycastle.crypto.tls.test; import java.io.IOException; import java.io.InputStream; import java.io.InputStreamReader; import org.bouncycastle.asn1.pkcs.RSAPrivateKey; import org.bouncycastle.crypto.digests.SHA256Digest; import org.bouncycastle.crypto.params.AsymmetricKeyParameter; import org.bouncycastle.crypto.params.RSAPrivateCrtKeyParameters; import org.bouncycastle.crypto.tls.Certificate; import org.bouncycastle.crypto.tls.DefaultTlsAgreementCredentials; import org.bouncycastle.crypto.tls.DefaultTlsEncryptionCredentials; import org.bouncycastle.crypto.tls.DefaultTlsSignerCredentials; import org.bouncycastle.crypto.tls.TlsAgreementCredentials; import org.bouncycastle.crypto.tls.TlsContext; import org.bouncycastle.crypto.tls.TlsEncryptionCredentials; import org.bouncycastle.crypto.tls.TlsSignerCredentials; import org.bouncycastle.crypto.util.PrivateKeyFactory; import org.bouncycastle.util.encoders.Base64; import org.bouncycastle.util.encoders.Hex; import org.bouncycastle.util.io.pem.PemObject; import org.bouncycastle.util.io.pem.PemReader; public class TlsTestUtils { static final byte[] rsaCertData = Base64 .decode("MIICUzCCAf2gAwIBAgIBATANBgkqhkiG9w0BAQQFADCBjzELMAkGA1UEBhMCQVUxKDAmBgNVBAoMH1RoZSBMZWdpb2" + "4gb2YgdGhlIEJvdW5jeSBDYXN0bGUxEjAQBgNVBAcMCU1lbGJvdXJuZTERMA8GA1UECAwIVmljdG9yaWExLzAtBgkq" + "hkiG9w0BCQEWIGZlZWRiYWNrLWNyeXB0b0Bib3VuY3ljYXN0bGUub3JnMB4XDTEzMDIyNTA2MDIwNVoXDTEzMDIyNT" + "A2MDM0NVowgY8xCzAJBgNVBAYTAkFVMSgwJgYDVQQKDB9UaGUgTGVnaW9uIG9mIHRoZSBCb3VuY3kgQ2FzdGxlMRIw" + "EAYDVQQHDAlNZWxib3VybmUxETAPBgNVBAgMCFZpY3RvcmlhMS8wLQYJKoZIhvcNAQkBFiBmZWVkYmFjay1jcnlwdG" + "9AYm91bmN5Y2FzdGxlLm9yZzBaMA0GCSqGSIb3DQEBAQUAA0kAMEYCQQC0p+RhcFdPFqlwgrIr5YtqKmKXmEGb4Shy" + "pL26Ymz66ZAPdqv7EhOdzl3lZWT6srZUMWWgQMYGiHQg4z2R7X7XAgERo0QwQjAOBgNVHQ8BAf8EBAMCBSAwEgYDVR" + "0lAQH/BAgwBgYEVR0lADAcBgNVHREBAf8EEjAQgQ50ZXN0QHRlc3QudGVzdDANBgkqhkiG9w0BAQQFAANBAHU55Ncz" + "eglREcTg54YLUlGWu2WOYWhit/iM1eeq8Kivro7q98eW52jTuMI3CI5ulqd0hYzshQKQaZ5GDzErMyM="); static final byte[] dudRsaCertData = Base64 .decode("MIICUzCCAf2gAwIBAgIBATANBgkqhkiG9w0BAQQFADCBjzELMAkGA1UEBhMCQVUxKDAmBgNVBAoMH1RoZSBMZWdpb2" + "4gb2YgdGhlIEJvdW5jeSBDYXN0bGUxEjAQBgNVBAcMCU1lbGJvdXJuZTERMA8GA1UECAwIVmljdG9yaWExLzAtBgkq" + "hkiG9w0BCQEWIGZlZWRiYWNrLWNyeXB0b0Bib3VuY3ljYXN0bGUub3JnMB4XDTEzMDIyNTA1NDcyOFoXDTEzMDIyNT" + "A1NDkwOFowgY8xCzAJBgNVBAYTAkFVMSgwJgYDVQQKDB9UaGUgTGVnaW9uIG9mIHRoZSBCb3VuY3kgQ2FzdGxlMRIw" + "EAYDVQQHDAlNZWxib3VybmUxETAPBgNVBAgMCFZpY3RvcmlhMS8wLQYJKoZIhvcNAQkBFiBmZWVkYmFjay1jcnlwdG" + "9AYm91bmN5Y2FzdGxlLm9yZzBaMA0GCSqGSIb3DQEBAQUAA0kAMEYCQQC0p+RhcFdPFqlwgrIr5YtqKmKXmEGb4Shy" + "pL26Ymz66ZAPdqv7EhOdzl3lZWT6srZUMWWgQMYGiHQg4z2R7X7XAgERo0QwQjAOBgNVHQ8BAf8EBAMCAAEwEgYDVR" + "0lAQH/BAgwBgYEVR0lADAcBgNVHREBAf8EEjAQgQ50ZXN0QHRlc3QudGVzdDANBgkqhkiG9w0BAQQFAANBAJg55PBS" + "weg6obRUKF4FF6fCrWFi6oCYSQ99LWcAeupc5BofW5MstFMhCOaEucuGVqunwT5G7/DweazzCIrSzB0="); static String fingerprint(org.bouncycastle.asn1.x509.Certificate c) throws IOException { byte[] der = c.getEncoded(); byte[] sha1 = sha256DigestOf(der); byte[] hexBytes = Hex.encode(sha1); String hex = new String(hexBytes, "ASCII").toUpperCase(); StringBuffer fp = new StringBuffer(); int i = 0; fp.append(hex.substring(i, i + 2)); while ((i += 2) < hex.length()) { fp.append(':'); fp.append(hex.substring(i, i + 2)); } return fp.toString(); } static byte[] sha256DigestOf(byte[] input) { SHA256Digest d = new SHA256Digest(); d.update(input, 0, input.length); byte[] result = new byte[d.getDigestSize()]; d.doFinal(result, 0); return result; } static TlsAgreementCredentials loadAgreementCredentials(TlsContext context, String[] certResources, String keyResource) throws IOException { Certificate certificate = loadCertificateChain(certResources); AsymmetricKeyParameter privateKey = loadPrivateKeyResource(keyResource); return new DefaultTlsAgreementCredentials(certificate, privateKey); } static TlsEncryptionCredentials loadEncryptionCredentials(TlsContext context, String[] certResources, String keyResource) throws IOException { Certificate certificate = loadCertificateChain(certResources); AsymmetricKeyParameter privateKey = loadPrivateKeyResource(keyResource); return new DefaultTlsEncryptionCredentials(context, certificate, privateKey); } static TlsSignerCredentials loadSignerCredentials(TlsContext context, String[] certResources, String keyResource) throws IOException { Certificate certificate = loadCertificateChain(certResources); AsymmetricKeyParameter privateKey = loadPrivateKeyResource(keyResource); return new DefaultTlsSignerCredentials(context, certificate, privateKey); } static Certificate loadCertificateChain(String[] resources) throws IOException { org.bouncycastle.asn1.x509.Certificate[] chain = new org.bouncycastle.asn1.x509.Certificate[resources.length]; for (int i = 0; i < resources.length; ++i) { chain[i] = loadCertificateResource(resources[i]); } return new Certificate(chain); } static org.bouncycastle.asn1.x509.Certificate loadCertificateResource(String resource) throws IOException { PemObject pem = loadPemResource(resource); if (pem.getType().endsWith("CERTIFICATE")) { return org.bouncycastle.asn1.x509.Certificate.getInstance(pem.getContent()); } throw new IllegalArgumentException("'resource' doesn't specify a valid certificate"); } static AsymmetricKeyParameter loadPrivateKeyResource(String resource) throws IOException { PemObject pem = loadPemResource(resource); if (pem.getType().endsWith("RSA PRIVATE KEY")) { RSAPrivateKey rsa = RSAPrivateKey.getInstance(pem.getContent()); return new RSAPrivateCrtKeyParameters(rsa.getModulus(), rsa.getPublicExponent(), rsa.getPrivateExponent(), rsa.getPrime1(), rsa.getPrime2(), rsa.getExponent1(), rsa.getExponent2(), rsa.getCoefficient()); } if (pem.getType().endsWith("PRIVATE KEY")) { return PrivateKeyFactory.createKey(pem.getContent()); } throw new IllegalArgumentException("'resource' doesn't specify a valid private key"); } static PemObject loadPemResource(String resource) throws IOException { InputStream s = TlsTestUtils.class.getResourceAsStream(resource); PemReader p = new PemReader(new InputStreamReader(s)); PemObject o = p.readPemObject(); p.close(); return o; } } bouncycastle-1.49.orig/test/src/org/bouncycastle/crypto/tls/test/DTLSClientTest.java0000644000175000017500000000363512146536044030206 0ustar ebourgebourgpackage org.bouncycastle.crypto.tls.test; import java.net.DatagramSocket; import java.net.InetAddress; import java.security.SecureRandom; import org.bouncycastle.crypto.tls.DTLSClientProtocol; import org.bouncycastle.crypto.tls.DTLSTransport; import org.bouncycastle.crypto.tls.DatagramTransport; import org.bouncycastle.crypto.tls.UDPTransport; /** * A simple test designed to conduct a DTLS handshake with an external DTLS server. *

    * Please refer to GnuTLSSetup.txt or OpenSSLSetup.txt, and x509-*.pem files in this package for * help configuring an external DTLS server. */ public class DTLSClientTest { public static void main(String[] args) throws Exception { SecureRandom secureRandom = new SecureRandom(); DatagramSocket socket = new DatagramSocket(); socket.connect(InetAddress.getLocalHost(), 5556); int mtu = 1500; DatagramTransport transport = new UDPTransport(socket, mtu); transport = new UnreliableDatagramTransport(transport, secureRandom, 0, 0); transport = new LoggingDatagramTransport(transport, System.out); DTLSClientProtocol protocol = new DTLSClientProtocol(secureRandom); MockDTLSClient client = new MockDTLSClient(); DTLSTransport dtlsClient = protocol.connect(client, transport); System.out.println("Receive limit: " + dtlsClient.getReceiveLimit()); System.out.println("Send limit: " + dtlsClient.getSendLimit()); // Send and hopefully receive a packet back byte[] request = "Hello World!\n".getBytes("UTF-8"); dtlsClient.send(request, 0, request.length); byte[] response = new byte[dtlsClient.getReceiveLimit()]; int received = dtlsClient.receive(response, 0, response.length, 30000); if (received >= 0) { System.out.println(new String(response, 0, received, "UTF-8")); } dtlsClient.close(); } } bouncycastle-1.49.orig/test/src/org/bouncycastle/crypto/tls/test/AllTests.java0000644000175000017500000000070312146637300027162 0ustar ebourgebourgpackage org.bouncycastle.crypto.tls.test; import junit.framework.Test; import junit.framework.TestSuite; public class AllTests { public static void main(String[] args) throws Exception { junit.textui.TestRunner.run(suite()); } public static Test suite() throws Exception { TestSuite suite = new TestSuite("TLS tests"); suite.addTest(BasicTlsTest.suite()); return suite; } } bouncycastle-1.49.orig/test/src/org/bouncycastle/crypto/tls/test/HTTPSServerThread.java0000644000175000017500000000626512146536044030664 0ustar ebourgebourgpackage org.bouncycastle.crypto.tls.test; import java.io.ByteArrayInputStream; import java.io.IOException; import java.io.InputStream; import java.io.OutputStream; import java.io.OutputStreamWriter; import java.io.PrintWriter; import java.security.KeyStore; import javax.net.ssl.KeyManagerFactory; import javax.net.ssl.SSLContext; import javax.net.ssl.SSLServerSocket; import javax.net.ssl.SSLServerSocketFactory; import javax.net.ssl.SSLSession; import javax.net.ssl.SSLSocket; import javax.net.ssl.TrustManagerFactory; public class HTTPSServerThread extends Thread { private static final int PORT_NO = 8003; private static final char[] SERVER_PASSWORD = "serverPassword".toCharArray(); private static final char[] TRUST_STORE_PASSWORD = "trustPassword".toCharArray(); /** * Read a HTTP request */ private void readRequest( InputStream in) throws IOException { int ch = 0; int lastCh = 0; while ((ch = in.read()) >= 0 && (ch != '\n' && lastCh != '\n')) { if (ch != '\r') { lastCh = ch; } } } /** * Send a response */ private void sendResponse( OutputStream out) { PrintWriter pWrt = new PrintWriter(new OutputStreamWriter(out)); pWrt.print("HTTP/1.1 200 OK\r\n"); pWrt.print("Content-Type: text/html\r\n"); pWrt.print("\r\n"); pWrt.print("\r\n"); pWrt.print("\r\n"); pWrt.print("Hello World!\r\n"); pWrt.print("\r\n"); pWrt.print("\r\n"); pWrt.flush(); } SSLContext createSSLContext() throws Exception { KeyManagerFactory mgrFact = KeyManagerFactory.getInstance("SunX509"); KeyStore serverStore = KeyStore.getInstance("JKS"); serverStore.load(new ByteArrayInputStream(KeyStores.server), SERVER_PASSWORD); mgrFact.init(serverStore, SERVER_PASSWORD); // set up a trust manager so we can recognize the server TrustManagerFactory trustFact = TrustManagerFactory.getInstance("SunX509"); KeyStore trustStore = KeyStore.getInstance("JKS"); trustStore.load(new ByteArrayInputStream(KeyStores.trustStore), TRUST_STORE_PASSWORD); trustFact.init(trustStore); // create a context and set up a socket factory SSLContext sslContext = SSLContext.getInstance("TLS"); sslContext.init(mgrFact.getKeyManagers(), trustFact.getTrustManagers(), null); return sslContext; } public void run() { try { SSLContext sslContext = createSSLContext(); SSLServerSocketFactory fact = sslContext.getServerSocketFactory(); SSLServerSocket sSock = (SSLServerSocket)fact.createServerSocket(PORT_NO); SSLSocket sslSock = (SSLSocket)sSock.accept(); sslSock.startHandshake(); readRequest(sslSock.getInputStream()); SSLSession session = sslSock.getSession(); sendResponse(sslSock.getOutputStream()); sslSock.close(); } catch (Exception e) { throw new RuntimeException(e); } } } bouncycastle-1.49.orig/test/src/org/bouncycastle/crypto/tls/test/TestTlsClient.java0000644000175000017500000000101312146536044030166 0ustar ebourgebourgpackage org.bouncycastle.crypto.tls.test; import java.io.IOException; import org.bouncycastle.crypto.tls.DefaultTlsClient; import org.bouncycastle.crypto.tls.TlsAuthentication; public class TestTlsClient extends DefaultTlsClient { private final TlsAuthentication authentication; TestTlsClient(TlsAuthentication authentication) { this.authentication = authentication; } public TlsAuthentication getAuthentication() throws IOException { return authentication; } } bouncycastle-1.49.orig/test/src/org/bouncycastle/crypto/tls/test/LoggingDatagramTransport.java0000644000175000017500000000447612146536127032413 0ustar ebourgebourgpackage org.bouncycastle.crypto.tls.test; import java.io.IOException; import java.io.PrintStream; import org.bouncycastle.crypto.tls.DatagramTransport; public class LoggingDatagramTransport implements DatagramTransport { private static final String HEX_CHARS = "0123456789ABCDEF"; private final DatagramTransport transport; private final PrintStream output; private final long launchTimestamp; public LoggingDatagramTransport(DatagramTransport transport, PrintStream output) { this.transport = transport; this.output = output; this.launchTimestamp = System.currentTimeMillis(); } public int getReceiveLimit() throws IOException { return transport.getReceiveLimit(); } public int getSendLimit() throws IOException { return transport.getSendLimit(); } public int receive(byte[] buf, int off, int len, int waitMillis) throws IOException { int length = transport.receive(buf, off, len, waitMillis); if (length >= 0) { dumpDatagram("Received", buf, off, length); } return length; } public void send(byte[] buf, int off, int len) throws IOException { dumpDatagram("Sending", buf, off, len); transport.send(buf, off, len); } public void close() throws IOException { } private void dumpDatagram(String verb, byte[] buf, int off, int len) throws IOException { long timestamp = System.currentTimeMillis() - launchTimestamp; StringBuffer sb = new StringBuffer("(+" + timestamp + "ms) " + verb + " " + len + " byte datagram:"); for (int pos = 0; pos < len; ++pos) { if (pos % 16 == 0) { sb.append(System.getProperty("line.separator")); sb.append(" "); } else if (pos % 16 == 8) { sb.append('-'); } else { sb.append(' '); } int val = buf[off + pos] & 0xFF; sb.append(HEX_CHARS.charAt(val >> 4)); sb.append(HEX_CHARS.charAt(val & 0xF)); } dump(sb.toString()); } private synchronized void dump(String s) { output.println(s); } } bouncycastle-1.49.orig/test/src/org/bouncycastle/crypto/tls/test/TlsProtocolTest.java0000644000175000017500000001770312146541004030556 0ustar ebourgebourgpackage org.bouncycastle.crypto.tls.test; import java.io.IOException; import java.io.PipedInputStream; import java.io.PipedOutputStream; import java.io.PrintStream; import java.security.SecureRandom; import junit.framework.TestCase; import org.bouncycastle.asn1.x509.Certificate; import org.bouncycastle.crypto.tls.AlertLevel; import org.bouncycastle.crypto.tls.CertificateRequest; import org.bouncycastle.crypto.tls.ClientCertificateType; import org.bouncycastle.crypto.tls.DefaultTlsClient; import org.bouncycastle.crypto.tls.DefaultTlsServer; import org.bouncycastle.crypto.tls.TlsAuthentication; import org.bouncycastle.crypto.tls.TlsClientProtocol; import org.bouncycastle.crypto.tls.TlsCredentials; import org.bouncycastle.crypto.tls.TlsEncryptionCredentials; import org.bouncycastle.crypto.tls.TlsServerProtocol; import org.bouncycastle.crypto.tls.TlsSignerCredentials; public class TlsProtocolTest extends TestCase { public void testClientServer() throws Exception { SecureRandom secureRandom = new SecureRandom(); PipedInputStream clientRead = new PipedInputStream(); PipedInputStream serverRead = new PipedInputStream(); PipedOutputStream clientWrite = new PipedOutputStream(serverRead); PipedOutputStream serverWrite = new PipedOutputStream(clientRead); TlsClientProtocol clientProtocol = new TlsClientProtocol(clientRead, clientWrite, secureRandom); TlsServerProtocol serverProtocol = new TlsServerProtocol(serverRead, serverWrite, secureRandom); ServerThread serverThread = new ServerThread(serverProtocol); serverThread.start(); MyTlsClient client = new MyTlsClient(); clientProtocol.connect(client); // byte[] data = new byte[64]; // secureRandom.nextBytes(data); // // OutputStream output = clientProtocol.getOutputStream(); // output.write(data); // output.close(); // // byte[] echo = Streams.readAll(clientProtocol.getInputStream()); serverThread.join(); // assertTrue(Arrays.areEqual(data, echo)); } static class ServerThread extends Thread { private final TlsServerProtocol serverProtocol; ServerThread(TlsServerProtocol serverProtocol) { this.serverProtocol = serverProtocol; } public void run() { try { MyTlsServer server = new MyTlsServer(); serverProtocol.accept(server); // Streams.pipeAll(serverProtocol.getInputStream(), // serverProtocol.getOutputStream()); serverProtocol.close(); } catch (Exception e) { throw new RuntimeException(e); } } } static class MyTlsClient extends DefaultTlsClient { public void notifyAlertRaised(short alertLevel, short alertDescription, String message, Exception cause) { PrintStream out = (alertLevel == AlertLevel.fatal) ? System.err : System.out; out.println("TLS client raised alert (AlertLevel." + alertLevel + ", AlertDescription." + alertDescription + ")"); if (message != null) { out.println(message); } if (cause != null) { cause.printStackTrace(out); } } public void notifyAlertReceived(short alertLevel, short alertDescription) { PrintStream out = (alertLevel == AlertLevel.fatal) ? System.err : System.out; out.println("TLS client received alert (AlertLevel." + alertLevel + ", AlertDescription." + alertDescription + ")"); } public TlsAuthentication getAuthentication() throws IOException { return new TlsAuthentication() { public void notifyServerCertificate(org.bouncycastle.crypto.tls.Certificate serverCertificate) throws IOException { Certificate[] chain = serverCertificate.getCertificateList(); System.out.println("Received server certificate chain of length " + chain.length); for (int i = 0; i != chain.length; i++) { Certificate entry = chain[i]; // TODO Create fingerprint based on certificate signature algorithm digest System.out.println(" fingerprint:SHA-256 " + TlsTestUtils.fingerprint(entry) + " (" + entry.getSubject() + ")"); } } public TlsCredentials getClientCredentials(CertificateRequest certificateRequest) throws IOException { short[] certificateTypes = certificateRequest.getCertificateTypes(); if (certificateTypes != null) { for (int i = 0; i < certificateTypes.length; ++i) { if (certificateTypes[i] == ClientCertificateType.rsa_sign) { // TODO Create a distinct client certificate for use here return TlsTestUtils.loadSignerCredentials(context, new String[]{"x509-server.pem", "x509-ca.pem"}, "x509-server-key.pem"); } } } return null; } }; } } static class MyTlsServer extends DefaultTlsServer { public void notifyAlertRaised(short alertLevel, short alertDescription, String message, Exception cause) { PrintStream out = (alertLevel == AlertLevel.fatal) ? System.err : System.out; out.println("TLS server raised alert (AlertLevel." + alertLevel + ", AlertDescription." + alertDescription + ")"); if (message != null) { out.println(message); } if (cause != null) { cause.printStackTrace(out); } } public void notifyAlertReceived(short alertLevel, short alertDescription) { PrintStream out = (alertLevel == AlertLevel.fatal) ? System.err : System.out; out.println("TLS server received alert (AlertLevel." + alertLevel + ", AlertDescription." + alertDescription + ")"); } public CertificateRequest getCertificateRequest() { return new CertificateRequest(new short[]{ClientCertificateType.rsa_sign}, null); } public void notifyClientCertificate(org.bouncycastle.crypto.tls.Certificate clientCertificate) throws IOException { Certificate[] chain = clientCertificate.getCertificateList(); System.out.println("Received client certificate chain of length " + chain.length); for (int i = 0; i != chain.length; i++) { Certificate entry = chain[i]; // TODO Create fingerprint based on certificate signature algorithm digest System.out.println(" fingerprint:SHA-256 " + TlsTestUtils.fingerprint(entry) + " (" + entry.getSubject() + ")"); } } protected TlsEncryptionCredentials getRSAEncryptionCredentials() throws IOException { return TlsTestUtils.loadEncryptionCredentials(context, new String[]{"x509-server.pem", "x509-ca.pem"}, "x509-server-key.pem"); } protected TlsSignerCredentials getRSASignerCredentials() throws IOException { return TlsTestUtils.loadSignerCredentials(context, new String[]{"x509-server.pem", "x509-ca.pem"}, "x509-server-key.pem"); } } } bouncycastle-1.49.orig/test/src/org/bouncycastle/crypto/tls/test/MockDatagramAssociation.java0000644000175000017500000000551412146536044032166 0ustar ebourgebourgpackage org.bouncycastle.crypto.tls.test; import java.io.IOException; import java.net.DatagramPacket; import java.util.Vector; import org.bouncycastle.crypto.tls.DatagramTransport; public class MockDatagramAssociation { private int mtu; private MockDatagramTransport client, server; public MockDatagramAssociation(int mtu) { this.mtu = mtu; Vector clientQueue = new Vector(); Vector serverQueue = new Vector(); this.client = new MockDatagramTransport(clientQueue, serverQueue); this.server = new MockDatagramTransport(serverQueue, clientQueue); } public DatagramTransport getClient() { return client; } public DatagramTransport getServer() { return server; } private class MockDatagramTransport implements DatagramTransport { private Vector receiveQueue, sendQueue; MockDatagramTransport(Vector receiveQueue, Vector sendQueue) { this.receiveQueue = receiveQueue; this.sendQueue = sendQueue; } public int getReceiveLimit() throws IOException { return mtu; } public int getSendLimit() throws IOException { return mtu; } public int receive(byte[] buf, int off, int len, int waitMillis) throws IOException { synchronized (receiveQueue) { if (receiveQueue.isEmpty()) { try { receiveQueue.wait(waitMillis); } catch (InterruptedException e) { // TODO Keep waiting until full wait expired? } if (receiveQueue.isEmpty()) { return -1; } } DatagramPacket packet = (DatagramPacket)receiveQueue.remove(0); int copyLength = Math.min(len, packet.getLength()); System.arraycopy(packet.getData(), packet.getOffset(), buf, off, copyLength); return copyLength; } } public void send(byte[] buf, int off, int len) throws IOException { if (len > mtu) { // TODO Simulate rejection? } byte[] copy = new byte[len]; System.arraycopy(buf, off, copy, 0, len); DatagramPacket packet = new DatagramPacket(copy, len); synchronized (sendQueue) { sendQueue.addElement(packet); sendQueue.notify(); } } public void close() throws IOException { // TODO? } } } bouncycastle-1.49.orig/test/src/org/bouncycastle/crypto/tls/test/MockDTLSClient.java0000644000175000017500000000645412146540457030165 0ustar ebourgebourgpackage org.bouncycastle.crypto.tls.test; import java.io.IOException; import java.io.PrintStream; import org.bouncycastle.asn1.x509.Certificate; import org.bouncycastle.crypto.tls.AlertLevel; import org.bouncycastle.crypto.tls.CertificateRequest; import org.bouncycastle.crypto.tls.ClientCertificateType; import org.bouncycastle.crypto.tls.DefaultTlsClient; import org.bouncycastle.crypto.tls.ProtocolVersion; import org.bouncycastle.crypto.tls.TlsAuthentication; import org.bouncycastle.crypto.tls.TlsCredentials; public class MockDTLSClient extends DefaultTlsClient { public void notifyAlertRaised(short alertLevel, short alertDescription, String message, Exception cause) { PrintStream out = (alertLevel == AlertLevel.fatal) ? System.err : System.out; out.println("DTLS client raised alert (AlertLevel." + alertLevel + ", AlertDescription." + alertDescription + ")"); if (message != null) { out.println(message); } if (cause != null) { cause.printStackTrace(out); } } public void notifyAlertReceived(short alertLevel, short alertDescription) { PrintStream out = (alertLevel == AlertLevel.fatal) ? System.err : System.out; out.println("DTLS client received alert (AlertLevel." + alertLevel + ", AlertDescription." + alertDescription + ")"); } public ProtocolVersion getClientVersion() { return ProtocolVersion.DTLSv10; } public ProtocolVersion getMinimumVersion() { return ProtocolVersion.DTLSv10; } public TlsAuthentication getAuthentication() throws IOException { return new TlsAuthentication() { public void notifyServerCertificate(org.bouncycastle.crypto.tls.Certificate serverCertificate) throws IOException { Certificate[] chain = serverCertificate.getCertificateList(); System.out.println("Received server certificate chain of length " + chain.length); for (int i = 0; i != chain.length; i++) { Certificate entry = chain[i]; // TODO Create fingerprint based on certificate signature algorithm digest System.out.println(" fingerprint:SHA-256 " + TlsTestUtils.fingerprint(entry) + " (" + entry.getSubject() + ")"); } } public TlsCredentials getClientCredentials(CertificateRequest certificateRequest) throws IOException { short[] certificateTypes = certificateRequest.getCertificateTypes(); if (certificateTypes != null) { for (int i = 0; i < certificateTypes.length; ++i) { if (certificateTypes[i] == ClientCertificateType.rsa_sign) { // TODO Create a distinct client certificate for use here return TlsTestUtils.loadSignerCredentials(context, new String[]{"x509-server.pem", "x509-ca.pem"}, "x509-server-key.pem"); } } } return null; } }; } } bouncycastle-1.49.orig/test/src/org/bouncycastle/crypto/ec/0000755000175000017500000000000012152033550023364 5ustar ebourgebourgbouncycastle-1.49.orig/test/src/org/bouncycastle/crypto/ec/test/0000755000175000017500000000000012152033550024343 5ustar ebourgebourgbouncycastle-1.49.orig/test/src/org/bouncycastle/crypto/ec/test/AllTests.java0000644000175000017500000000163512137366704026763 0ustar ebourgebourgpackage org.bouncycastle.crypto.ec.test; import junit.framework.Test; import junit.framework.TestCase; import junit.framework.TestSuite; import org.bouncycastle.util.test.SimpleTestResult; public class AllTests extends TestCase { public void testCrypto() { org.bouncycastle.util.test.Test[] tests = { new ECElGamalTest(), new ECTransformationTest() }; for (int i = 0; i != tests.length; i++) { SimpleTestResult result = (SimpleTestResult)tests[i].perform(); if (!result.isSuccessful()) { fail(result.toString()); } } } public static void main (String[] args) { junit.textui.TestRunner.run(suite()); } public static Test suite() { TestSuite suite = new TestSuite("Lightweight EC ElGamal Tests"); suite.addTestSuite(AllTests.class); return suite; } } bouncycastle-1.49.orig/test/src/org/bouncycastle/crypto/ec/test/ECTransformationTest.java0000644000175000017500000001145012137365207031277 0ustar ebourgebourgpackage org.bouncycastle.crypto.ec.test; import java.math.BigInteger; import java.security.SecureRandom; import org.bouncycastle.crypto.AsymmetricCipherKeyPair; import org.bouncycastle.crypto.ec.ECDecryptor; import org.bouncycastle.crypto.ec.ECElGamalDecryptor; import org.bouncycastle.crypto.ec.ECElGamalEncryptor; import org.bouncycastle.crypto.ec.ECEncryptor; import org.bouncycastle.crypto.ec.ECNewPublicKeyTransform; import org.bouncycastle.crypto.ec.ECNewRandomnessTransform; import org.bouncycastle.crypto.ec.ECPair; import org.bouncycastle.crypto.ec.ECPairTransform; import org.bouncycastle.crypto.generators.ECKeyPairGenerator; import org.bouncycastle.crypto.params.ECDomainParameters; import org.bouncycastle.crypto.params.ECKeyGenerationParameters; import org.bouncycastle.crypto.params.ECPrivateKeyParameters; import org.bouncycastle.crypto.params.ECPublicKeyParameters; import org.bouncycastle.crypto.params.ParametersWithRandom; import org.bouncycastle.math.ec.ECCurve; import org.bouncycastle.math.ec.ECPoint; import org.bouncycastle.util.encoders.Hex; import org.bouncycastle.util.test.SimpleTest; public class ECTransformationTest extends SimpleTest { public String getName() { return "ECTransformationTest"; } public void performTest() throws Exception { ECCurve.Fp curve = new ECCurve.Fp( new BigInteger("6277101735386680763835789423207666416083908700390324961279"), // q new BigInteger("fffffffffffffffffffffffffffffffefffffffffffffffc", 16), // a new BigInteger("64210519e59c80e70fa7e9ab72243049feb8deecc146b9b1", 16)); // b ECDomainParameters params = new ECDomainParameters( curve, curve.decodePoint(Hex.decode("03188da80eb03090f67cbf20eb43a18800f4ff0afd82ff1012")), // G new BigInteger("6277101735386680763835789423176059013767194773182842284081")); // n ECPublicKeyParameters pubKey = new ECPublicKeyParameters( curve.decodePoint(Hex.decode("0262b12d60690cdcf330babab6e69763b471f994dd702d16a5")), // Q params); ECPrivateKeyParameters priKey = new ECPrivateKeyParameters( new BigInteger("651056770906015076056810763456358567190100156695615665659"), // d params); ParametersWithRandom pRandom = new ParametersWithRandom(pubKey, new SecureRandom()); doTest(priKey, pRandom, BigInteger.valueOf(20)); BigInteger rand = new BigInteger(pubKey.getParameters().getN().bitLength() - 1, new SecureRandom()); doTest(priKey, pRandom, rand); doSameKeyTest(priKey, pRandom, rand); } private void doTest(ECPrivateKeyParameters priKey, ParametersWithRandom pRandom, BigInteger value) { ECPoint data = priKey.getParameters().getG().multiply(value); ECEncryptor encryptor = new ECElGamalEncryptor(); encryptor.init(pRandom); ECPair pair = encryptor.encrypt(data); ECKeyPairGenerator ecGen = new ECKeyPairGenerator(); ecGen.init(new ECKeyGenerationParameters(priKey.getParameters(), new SecureRandom())); AsymmetricCipherKeyPair reEncKP = ecGen.generateKeyPair(); ECPairTransform ecr = new ECNewPublicKeyTransform(); ecr.init(reEncKP.getPublic()); ECPair srcPair = pair; // re-encrypt the message portion pair = ecr.transform(srcPair); ECDecryptor decryptor = new ECElGamalDecryptor(); decryptor.init(priKey); // decrypt out the original private key ECPoint p = decryptor.decrypt(new ECPair(srcPair.getX(), pair.getY())); decryptor.init(reEncKP.getPrivate()); // decrypt the fully transformed point. ECPoint result = decryptor.decrypt(new ECPair(pair.getX(), p)); if (!data.equals(result)) { fail("point pair failed to decrypt back to original"); } } private void doSameKeyTest(ECPrivateKeyParameters priKey, ParametersWithRandom pRandom, BigInteger value) { ECPoint data = priKey.getParameters().getG().multiply(value); ECEncryptor encryptor = new ECElGamalEncryptor(); encryptor.init(pRandom); ECPair pair = encryptor.encrypt(data); ECPairTransform ecr = new ECNewRandomnessTransform(); ecr.init(pRandom); ECPair srcPair = pair; // re-encrypt the message portion pair = ecr.transform(srcPair); ECDecryptor decryptor = new ECElGamalDecryptor(); decryptor.init(priKey); // decrypt the fully transformed point. ECPoint result = decryptor.decrypt(pair); if (!data.equals(result)) { fail("point pair failed to decrypt back to original"); } } public static void main(String[] args) { runTest(new ECTransformationTest()); } } bouncycastle-1.49.orig/test/src/org/bouncycastle/crypto/ec/test/ECElGamalTest.java0000644000175000017500000000557312132741703027576 0ustar ebourgebourgpackage org.bouncycastle.crypto.ec.test; import java.math.BigInteger; import java.security.SecureRandom; import org.bouncycastle.crypto.ec.ECDecryptor; import org.bouncycastle.crypto.ec.ECElGamalDecryptor; import org.bouncycastle.crypto.ec.ECElGamalEncryptor; import org.bouncycastle.crypto.ec.ECEncryptor; import org.bouncycastle.crypto.ec.ECPair; import org.bouncycastle.crypto.params.ECDomainParameters; import org.bouncycastle.crypto.params.ECPrivateKeyParameters; import org.bouncycastle.crypto.params.ECPublicKeyParameters; import org.bouncycastle.crypto.params.ParametersWithRandom; import org.bouncycastle.math.ec.ECCurve; import org.bouncycastle.math.ec.ECPoint; import org.bouncycastle.util.encoders.Hex; import org.bouncycastle.util.test.SimpleTest; public class ECElGamalTest extends SimpleTest { public String getName() { return "ECElGamal"; } public void performTest() throws Exception { ECCurve.Fp curve = new ECCurve.Fp( new BigInteger("6277101735386680763835789423207666416083908700390324961279"), // q new BigInteger("fffffffffffffffffffffffffffffffefffffffffffffffc", 16), // a new BigInteger("64210519e59c80e70fa7e9ab72243049feb8deecc146b9b1", 16)); // b ECDomainParameters params = new ECDomainParameters( curve, curve.decodePoint(Hex.decode("03188da80eb03090f67cbf20eb43a18800f4ff0afd82ff1012")), // G new BigInteger("6277101735386680763835789423176059013767194773182842284081")); // n ECPublicKeyParameters pubKey = new ECPublicKeyParameters( curve.decodePoint(Hex.decode("0262b12d60690cdcf330babab6e69763b471f994dd702d16a5")), // Q params); ECPrivateKeyParameters priKey = new ECPrivateKeyParameters( new BigInteger("651056770906015076056810763456358567190100156695615665659"), // d params); ParametersWithRandom pRandom = new ParametersWithRandom(pubKey, new SecureRandom()); doTest(priKey, pRandom, BigInteger.valueOf(20)); BigInteger rand = new BigInteger(pubKey.getParameters().getN().bitLength() - 1, new SecureRandom()); doTest(priKey, pRandom, rand); } private void doTest(ECPrivateKeyParameters priKey, ParametersWithRandom pRandom, BigInteger value) { ECPoint data = priKey.getParameters().getG().multiply(value); ECEncryptor encryptor = new ECElGamalEncryptor(); encryptor.init(pRandom); ECPair pair = encryptor.encrypt(data); ECDecryptor decryptor = new ECElGamalDecryptor(); decryptor.init(priKey); ECPoint result = decryptor.decrypt(pair); if (!data.equals(result)) { fail("point pair failed to decrypt back to original"); } } public static void main(String[] args) { runTest(new ECElGamalTest()); } } bouncycastle-1.49.orig/test/src/org/bouncycastle/crypto/test/0000755000175000017500000000000012152033550023754 5ustar ebourgebourgbouncycastle-1.49.orig/test/src/org/bouncycastle/crypto/test/NoekeonTest.java0000644000175000017500000000246610632663750027101 0ustar ebourgebourgpackage org.bouncycastle.crypto.test; import org.bouncycastle.crypto.engines.NoekeonEngine; import org.bouncycastle.crypto.params.KeyParameter; import org.bouncycastle.util.encoders.Hex; import org.bouncycastle.util.test.SimpleTest; /** * Noekeon tester */ public class NoekeonTest extends CipherTest { static SimpleTest[] tests = { new BlockCipherVectorTest(0, new NoekeonEngine(), new KeyParameter(Hex.decode("00000000000000000000000000000000")), "00000000000000000000000000000000", "b1656851699e29fa24b70148503d2dfc"), new BlockCipherVectorTest(1, new NoekeonEngine(), new KeyParameter(Hex.decode("ffffffffffffffffffffffffffffffff")), "ffffffffffffffffffffffffffffffff", "2a78421b87c7d0924f26113f1d1349b2"), new BlockCipherVectorTest(2, new NoekeonEngine(), new KeyParameter(Hex.decode("b1656851699e29fa24b70148503d2dfc")), "2a78421b87c7d0924f26113f1d1349b2", "e2f687e07b75660ffc372233bc47532c") }; NoekeonTest() { super(tests, new NoekeonEngine(), new KeyParameter(new byte[16])); } public String getName() { return "Noekeon"; } public static void main( String[] args) { runTest(new NoekeonTest()); } } bouncycastle-1.49.orig/test/src/org/bouncycastle/crypto/test/CamelliaLightTest.java0000644000175000017500000000613111165246650030171 0ustar ebourgebourgpackage org.bouncycastle.crypto.test; import org.bouncycastle.crypto.engines.CamelliaLightEngine; import org.bouncycastle.crypto.params.KeyParameter; import org.bouncycastle.util.encoders.Hex; import org.bouncycastle.util.test.SimpleTest; /** * Camellia tester - vectors from https://www.cosic.esat.kuleuven.be/nessie/testvectors/ and RFC 3713 */ public class CamelliaLightTest extends CipherTest { static SimpleTest[] tests = { new BlockCipherVectorTest(0, new CamelliaLightEngine(), new KeyParameter(Hex.decode("00000000000000000000000000000000")), "80000000000000000000000000000000", "07923A39EB0A817D1C4D87BDB82D1F1C"), new BlockCipherVectorTest(1, new CamelliaLightEngine(), new KeyParameter(Hex.decode("80000000000000000000000000000000")), "00000000000000000000000000000000", "6C227F749319A3AA7DA235A9BBA05A2C"), new BlockCipherVectorTest(2, new CamelliaLightEngine(), new KeyParameter(Hex.decode("0123456789abcdeffedcba9876543210")), "0123456789abcdeffedcba9876543210", "67673138549669730857065648eabe43"), // // 192 bit // new BlockCipherVectorTest(3, new CamelliaLightEngine(), new KeyParameter(Hex.decode("0123456789abcdeffedcba98765432100011223344556677")), "0123456789abcdeffedcba9876543210", "b4993401b3e996f84ee5cee7d79b09b9"), new BlockCipherVectorTest(4, new CamelliaLightEngine(), new KeyParameter(Hex.decode("000000000000000000000000000000000000000000000000")), "00040000000000000000000000000000", "9BCA6C88B928C1B0F57F99866583A9BC"), new BlockCipherVectorTest(5, new CamelliaLightEngine(), new KeyParameter(Hex.decode("949494949494949494949494949494949494949494949494")), "636EB22D84B006381235641BCF0308D2", "94949494949494949494949494949494"), // // 256 bit // new BlockCipherVectorTest(6, new CamelliaLightEngine(), new KeyParameter(Hex.decode("0123456789abcdeffedcba987654321000112233445566778899aabbccddeeff")), "0123456789abcdeffedcba9876543210", "9acc237dff16d76c20ef7c919e3a7509"), new BlockCipherVectorTest(7, new CamelliaLightEngine(), new KeyParameter(Hex.decode("4A4A4A4A4A4A4A4A4A4A4A4A4A4A4A4A4A4A4A4A4A4A4A4A4A4A4A4A4A4A4A4A")), "057764FE3A500EDBD988C5C3B56CBA9A", "4A4A4A4A4A4A4A4A4A4A4A4A4A4A4A4A"), new BlockCipherVectorTest(8, new CamelliaLightEngine(), new KeyParameter(Hex.decode("0303030303030303030303030303030303030303030303030303030303030303")), "7968B08ABA92193F2295121EF8D75C8A", "03030303030303030303030303030303"), }; CamelliaLightTest() { super(tests, new CamelliaLightEngine(), new KeyParameter(new byte[32])); } public String getName() { return "CamelliaLight"; } public static void main( String[] args) { runTest(new CamelliaLightTest()); } } bouncycastle-1.49.orig/test/src/org/bouncycastle/crypto/test/SHA384DigestTest.java0000644000175000017500000000313110330633061027466 0ustar ebourgebourgpackage org.bouncycastle.crypto.test; import org.bouncycastle.crypto.Digest; import org.bouncycastle.crypto.digests.SHA384Digest; /** * standard vector test for SHA-384 from FIPS Draft 180-2. * * Note, the first two vectors are _not_ from the draft, the last three are. */ public class SHA384DigestTest extends DigestTest { private static String[] messages = { "", "a", "abc", "abcdefghbcdefghicdefghijdefghijkefghijklfghijklmghijklmnhijklmnoijklmnopjklmnopqklmnopqrlmnopqrsmnopqrstnopqrstu" }; private static String[] digests = { "38b060a751ac96384cd9327eb1b1e36a21fdb71114be07434c0cc7bf63f6e1da274edebfe76f65fbd51ad2f14898b95b", "54a59b9f22b0b80880d8427e548b7c23abd873486e1f035dce9cd697e85175033caa88e6d57bc35efae0b5afd3145f31", "cb00753f45a35e8bb5a03d699ac65007272c32ab0eded1631a8b605a43ff5bed8086072ba1e7cc2358baeca134c825a7", "09330c33f71147e83d192fc782cd1b4753111b173b3b05d22fa08086e3b0f712fcc7c71a557e2db966c3e9fa91746039" }; static private String million_a_digest = "9d0e1809716474cb086e834e310a4a1ced149e9c00f248527972cec5704c2a5b07b8b3dc38ecc4ebae97ddd87f3d8985"; SHA384DigestTest() { super(new SHA384Digest(), messages, digests); } public void performTest() { super.performTest(); millionATest(million_a_digest); } protected Digest cloneDigest(Digest digest) { return new SHA384Digest((SHA384Digest)digest); } public static void main( String[] args) { runTest(new SHA384DigestTest()); } } bouncycastle-1.49.orig/test/src/org/bouncycastle/crypto/test/CipherTest.java0000644000175000017500000000521610525306762026707 0ustar ebourgebourgpackage org.bouncycastle.crypto.test; import org.bouncycastle.crypto.BlockCipher; import org.bouncycastle.crypto.DataLengthException; import org.bouncycastle.crypto.params.KeyParameter; import org.bouncycastle.util.test.SimpleTest; public abstract class CipherTest extends SimpleTest { private SimpleTest[] _tests; private BlockCipher _engine; private KeyParameter _validKey; // protected CipherTest( // SimpleTest[] tests) // { // _tests = tests; // } protected CipherTest( SimpleTest[] tests, BlockCipher engine, KeyParameter validKey) { _tests = tests; _engine = engine; _validKey = validKey; } public abstract String getName(); public void performTest() throws Exception { for (int i = 0; i != _tests.length; i++) { _tests[i].performTest(); } if (_engine != null) { // // state tests // byte[] buf = new byte[16]; try { _engine.processBlock(buf, 0, buf, 0); fail("failed initialisation check"); } catch (IllegalStateException e) { // expected } bufferSizeCheck((_engine)); } } private void bufferSizeCheck( BlockCipher engine) { byte[] correctBuf = new byte[engine.getBlockSize()]; byte[] shortBuf = new byte[correctBuf.length / 2]; engine.init(true, _validKey); try { engine.processBlock(shortBuf, 0, correctBuf, 0); fail("failed short input check"); } catch (DataLengthException e) { // expected } try { engine.processBlock(correctBuf, 0, shortBuf, 0); fail("failed short output check"); } catch (DataLengthException e) { // expected } engine.init(false, _validKey); try { engine.processBlock(shortBuf, 0, correctBuf, 0); fail("failed short input check"); } catch (DataLengthException e) { // expected } try { engine.processBlock(correctBuf, 0, shortBuf, 0); fail("failed short output check"); } catch (DataLengthException e) { // expected } } } bouncycastle-1.49.orig/test/src/org/bouncycastle/crypto/test/DigestTest.java0000644000175000017500000001103612143611410026674 0ustar ebourgebourgpackage org.bouncycastle.crypto.test; import org.bouncycastle.crypto.Digest; import org.bouncycastle.util.Memoable; import org.bouncycastle.util.encoders.Hex; import org.bouncycastle.util.test.SimpleTest; public abstract class DigestTest extends SimpleTest { private Digest digest; private String[] input; private String[] results; DigestTest( Digest digest, String[] input, String[] results) { this.digest = digest; this.input = input; this.results = results; } public String getName() { return digest.getAlgorithmName(); } public void performTest() { byte[] resBuf = new byte[digest.getDigestSize()]; for (int i = 0; i < input.length - 1; i++) { byte[] m = toByteArray(input[i]); vectorTest(digest, i, resBuf, m, Hex.decode(results[i])); } byte[] lastV = toByteArray(input[input.length - 1]); byte[] lastDigest = Hex.decode(results[input.length - 1]); vectorTest(digest, input.length - 1, resBuf, lastV, Hex.decode(results[input.length - 1])); // // clone test // digest.update(lastV, 0, lastV.length/2); // clone the Digest Digest d = cloneDigest(digest); digest.update(lastV, lastV.length/2, lastV.length - lastV.length/2); digest.doFinal(resBuf, 0); if (!areEqual(lastDigest, resBuf)) { fail("failing clone vector test", results[results.length - 1], new String(Hex.encode(resBuf))); } d.update(lastV, lastV.length/2, lastV.length - lastV.length/2); d.doFinal(resBuf, 0); if (!areEqual(lastDigest, resBuf)) { fail("failing second clone vector test", results[results.length - 1], new String(Hex.encode(resBuf))); } // // memo test // Memoable m = (Memoable)digest; digest.update(lastV, 0, lastV.length/2); // copy the Digest Memoable copy1 = m.copy(); Memoable copy2 = copy1.copy(); digest.update(lastV, lastV.length/2, lastV.length - lastV.length/2); digest.doFinal(resBuf, 0); if (!areEqual(lastDigest, resBuf)) { fail("failing memo vector test", results[results.length - 1], new String(Hex.encode(resBuf))); } m.reset(copy1); digest.update(lastV, lastV.length/2, lastV.length - lastV.length/2); digest.doFinal(resBuf, 0); if (!areEqual(lastDigest, resBuf)) { fail("failing memo reset vector test", results[results.length - 1], new String(Hex.encode(resBuf))); } Digest md = (Digest)copy2; md.update(lastV, lastV.length/2, lastV.length - lastV.length/2); md.doFinal(resBuf, 0); if (!areEqual(lastDigest, resBuf)) { fail("failing memo copy vector test", results[results.length - 1], new String(Hex.encode(resBuf))); } } private byte[] toByteArray(String input) { byte[] bytes = new byte[input.length()]; for (int i = 0; i != bytes.length; i++) { bytes[i] = (byte)input.charAt(i); } return bytes; } private void vectorTest( Digest digest, int count, byte[] resBuf, byte[] input, byte[] expected) { digest.update(input, 0, input.length); digest.doFinal(resBuf, 0); if (!areEqual(resBuf, expected)) { fail("Vector " + count + " failed got " + new String(Hex.encode(resBuf))); } } protected abstract Digest cloneDigest(Digest digest); // // optional tests // protected void millionATest( String expected) { byte[] resBuf = new byte[digest.getDigestSize()]; for (int i = 0; i < 1000000; i++) { digest.update((byte)'a'); } digest.doFinal(resBuf, 0); if (!areEqual(resBuf, Hex.decode(expected))) { fail("Million a's failed"); } } protected void sixtyFourKTest( String expected) { byte[] resBuf = new byte[digest.getDigestSize()]; for (int i = 0; i < 65536; i++) { digest.update((byte)(i & 0xff)); } digest.doFinal(resBuf, 0); if (!areEqual(resBuf, Hex.decode(expected))) { fail("64k test failed"); } } } bouncycastle-1.49.orig/test/src/org/bouncycastle/crypto/test/OAEPTest.java0000644000175000017500000012424212147563467026233 0ustar ebourgebourgpackage org.bouncycastle.crypto.test; import java.io.ByteArrayInputStream; import java.math.BigInteger; import java.security.SecureRandom; import org.bouncycastle.asn1.ASN1InputStream; import org.bouncycastle.asn1.ASN1Sequence; import org.bouncycastle.asn1.pkcs.PrivateKeyInfo; import org.bouncycastle.asn1.pkcs.RSAPrivateKey; import org.bouncycastle.asn1.pkcs.RSAPublicKey; import org.bouncycastle.asn1.x509.SubjectPublicKeyInfo; import org.bouncycastle.crypto.AsymmetricBlockCipher; import org.bouncycastle.crypto.InvalidCipherTextException; import org.bouncycastle.crypto.digests.SHA1Digest; import org.bouncycastle.crypto.digests.SHA256Digest; import org.bouncycastle.crypto.encodings.OAEPEncoding; import org.bouncycastle.crypto.engines.RSAEngine; import org.bouncycastle.crypto.params.ParametersWithRandom; import org.bouncycastle.crypto.params.RSAKeyParameters; import org.bouncycastle.crypto.params.RSAPrivateCrtKeyParameters; import org.bouncycastle.util.encoders.Hex; import org.bouncycastle.util.test.SimpleTest; public class OAEPTest extends SimpleTest { static byte[] pubKeyEnc1 = { (byte)0x30, (byte)0x5a, (byte)0x30, (byte)0x0d, (byte)0x06, (byte)0x09, (byte)0x2a, (byte)0x86, (byte)0x48, (byte)0x86, (byte)0xf7, (byte)0x0d, (byte)0x01, (byte)0x01, (byte)0x01, (byte)0x05, (byte)0x00, (byte)0x03, (byte)0x49, (byte)0x00, (byte)0x30, (byte)0x46, (byte)0x02, (byte)0x41, (byte)0x00, (byte)0xaa, (byte)0x36, (byte)0xab, (byte)0xce, (byte)0x88, (byte)0xac, (byte)0xfd, (byte)0xff, (byte)0x55, (byte)0x52, (byte)0x3c, (byte)0x7f, (byte)0xc4, (byte)0x52, (byte)0x3f, (byte)0x90, (byte)0xef, (byte)0xa0, (byte)0x0d, (byte)0xf3, (byte)0x77, (byte)0x4a, (byte)0x25, (byte)0x9f, (byte)0x2e, (byte)0x62, (byte)0xb4, (byte)0xc5, (byte)0xd9, (byte)0x9c, (byte)0xb5, (byte)0xad, (byte)0xb3, (byte)0x00, (byte)0xa0, (byte)0x28, (byte)0x5e, (byte)0x53, (byte)0x01, (byte)0x93, (byte)0x0e, (byte)0x0c, (byte)0x70, (byte)0xfb, (byte)0x68, (byte)0x76, (byte)0x93, (byte)0x9c, (byte)0xe6, (byte)0x16, (byte)0xce, (byte)0x62, (byte)0x4a, (byte)0x11, (byte)0xe0, (byte)0x08, (byte)0x6d, (byte)0x34, (byte)0x1e, (byte)0xbc, (byte)0xac, (byte)0xa0, (byte)0xa1, (byte)0xf5, (byte)0x02, (byte)0x01, (byte)0x11 }; static byte[] privKeyEnc1 = { (byte)0x30, (byte)0x82, (byte)0x01, (byte)0x52, (byte)0x02, (byte)0x01, (byte)0x00, (byte)0x30, (byte)0x0d, (byte)0x06, (byte)0x09, (byte)0x2a, (byte)0x86, (byte)0x48, (byte)0x86, (byte)0xf7, (byte)0x0d, (byte)0x01, (byte)0x01, (byte)0x01, (byte)0x05, (byte)0x00, (byte)0x04, (byte)0x82, (byte)0x01, (byte)0x3c, (byte)0x30, (byte)0x82, (byte)0x01, (byte)0x38, (byte)0x02, (byte)0x01, (byte)0x00, (byte)0x02, (byte)0x41, (byte)0x00, (byte)0xaa, (byte)0x36, (byte)0xab, (byte)0xce, (byte)0x88, (byte)0xac, (byte)0xfd, (byte)0xff, (byte)0x55, (byte)0x52, (byte)0x3c, (byte)0x7f, (byte)0xc4, (byte)0x52, (byte)0x3f, (byte)0x90, (byte)0xef, (byte)0xa0, (byte)0x0d, (byte)0xf3, (byte)0x77, (byte)0x4a, (byte)0x25, (byte)0x9f, (byte)0x2e, (byte)0x62, (byte)0xb4, (byte)0xc5, (byte)0xd9, (byte)0x9c, (byte)0xb5, (byte)0xad, (byte)0xb3, (byte)0x00, (byte)0xa0, (byte)0x28, (byte)0x5e, (byte)0x53, (byte)0x01, (byte)0x93, (byte)0x0e, (byte)0x0c, (byte)0x70, (byte)0xfb, (byte)0x68, (byte)0x76, (byte)0x93, (byte)0x9c, (byte)0xe6, (byte)0x16, (byte)0xce, (byte)0x62, (byte)0x4a, (byte)0x11, (byte)0xe0, (byte)0x08, (byte)0x6d, (byte)0x34, (byte)0x1e, (byte)0xbc, (byte)0xac, (byte)0xa0, (byte)0xa1, (byte)0xf5, (byte)0x02, (byte)0x01, (byte)0x11, (byte)0x02, (byte)0x40, (byte)0x0a, (byte)0x03, (byte)0x37, (byte)0x48, (byte)0x62, (byte)0x64, (byte)0x87, (byte)0x69, (byte)0x5f, (byte)0x5f, (byte)0x30, (byte)0xbc, (byte)0x38, (byte)0xb9, (byte)0x8b, (byte)0x44, (byte)0xc2, (byte)0xcd, (byte)0x2d, (byte)0xff, (byte)0x43, (byte)0x40, (byte)0x98, (byte)0xcd, (byte)0x20, (byte)0xd8, (byte)0xa1, (byte)0x38, (byte)0xd0, (byte)0x90, (byte)0xbf, (byte)0x64, (byte)0x79, (byte)0x7c, (byte)0x3f, (byte)0xa7, (byte)0xa2, (byte)0xcd, (byte)0xcb, (byte)0x3c, (byte)0xd1, (byte)0xe0, (byte)0xbd, (byte)0xba, (byte)0x26, (byte)0x54, (byte)0xb4, (byte)0xf9, (byte)0xdf, (byte)0x8e, (byte)0x8a, (byte)0xe5, (byte)0x9d, (byte)0x73, (byte)0x3d, (byte)0x9f, (byte)0x33, (byte)0xb3, (byte)0x01, (byte)0x62, (byte)0x4a, (byte)0xfd, (byte)0x1d, (byte)0x51, (byte)0x02, (byte)0x21, (byte)0x00, (byte)0xd8, (byte)0x40, (byte)0xb4, (byte)0x16, (byte)0x66, (byte)0xb4, (byte)0x2e, (byte)0x92, (byte)0xea, (byte)0x0d, (byte)0xa3, (byte)0xb4, (byte)0x32, (byte)0x04, (byte)0xb5, (byte)0xcf, (byte)0xce, (byte)0x33, (byte)0x52, (byte)0x52, (byte)0x4d, (byte)0x04, (byte)0x16, (byte)0xa5, (byte)0xa4, (byte)0x41, (byte)0xe7, (byte)0x00, (byte)0xaf, (byte)0x46, (byte)0x12, (byte)0x0d, (byte)0x02, (byte)0x21, (byte)0x00, (byte)0xc9, (byte)0x7f, (byte)0xb1, (byte)0xf0, (byte)0x27, (byte)0xf4, (byte)0x53, (byte)0xf6, (byte)0x34, (byte)0x12, (byte)0x33, (byte)0xea, (byte)0xaa, (byte)0xd1, (byte)0xd9, (byte)0x35, (byte)0x3f, (byte)0x6c, (byte)0x42, (byte)0xd0, (byte)0x88, (byte)0x66, (byte)0xb1, (byte)0xd0, (byte)0x5a, (byte)0x0f, (byte)0x20, (byte)0x35, (byte)0x02, (byte)0x8b, (byte)0x9d, (byte)0x89, (byte)0x02, (byte)0x20, (byte)0x59, (byte)0x0b, (byte)0x95, (byte)0x72, (byte)0xa2, (byte)0xc2, (byte)0xa9, (byte)0xc4, (byte)0x06, (byte)0x05, (byte)0x9d, (byte)0xc2, (byte)0xab, (byte)0x2f, (byte)0x1d, (byte)0xaf, (byte)0xeb, (byte)0x7e, (byte)0x8b, (byte)0x4f, (byte)0x10, (byte)0xa7, (byte)0x54, (byte)0x9e, (byte)0x8e, (byte)0xed, (byte)0xf5, (byte)0xb4, (byte)0xfc, (byte)0xe0, (byte)0x9e, (byte)0x05, (byte)0x02, (byte)0x21, (byte)0x00, (byte)0x8e, (byte)0x3c, (byte)0x05, (byte)0x21, (byte)0xfe, (byte)0x15, (byte)0xe0, (byte)0xea, (byte)0x06, (byte)0xa3, (byte)0x6f, (byte)0xf0, (byte)0xf1, (byte)0x0c, (byte)0x99, (byte)0x52, (byte)0xc3, (byte)0x5b, (byte)0x7a, (byte)0x75, (byte)0x14, (byte)0xfd, (byte)0x32, (byte)0x38, (byte)0xb8, (byte)0x0a, (byte)0xad, (byte)0x52, (byte)0x98, (byte)0x62, (byte)0x8d, (byte)0x51, (byte)0x02, (byte)0x20, (byte)0x36, (byte)0x3f, (byte)0xf7, (byte)0x18, (byte)0x9d, (byte)0xa8, (byte)0xe9, (byte)0x0b, (byte)0x1d, (byte)0x34, (byte)0x1f, (byte)0x71, (byte)0xd0, (byte)0x9b, (byte)0x76, (byte)0xa8, (byte)0xa9, (byte)0x43, (byte)0xe1, (byte)0x1d, (byte)0x10, (byte)0xb2, (byte)0x4d, (byte)0x24, (byte)0x9f, (byte)0x2d, (byte)0xea, (byte)0xfe, (byte)0xf8, (byte)0x0c, (byte)0x18, (byte)0x26 }; static byte[] output1 = { (byte)0x1b, (byte)0x8f, (byte)0x05, (byte)0xf9, (byte)0xca, (byte)0x1a, (byte)0x79, (byte)0x52, (byte)0x6e, (byte)0x53, (byte)0xf3, (byte)0xcc, (byte)0x51, (byte)0x4f, (byte)0xdb, (byte)0x89, (byte)0x2b, (byte)0xfb, (byte)0x91, (byte)0x93, (byte)0x23, (byte)0x1e, (byte)0x78, (byte)0xb9, (byte)0x92, (byte)0xe6, (byte)0x8d, (byte)0x50, (byte)0xa4, (byte)0x80, (byte)0xcb, (byte)0x52, (byte)0x33, (byte)0x89, (byte)0x5c, (byte)0x74, (byte)0x95, (byte)0x8d, (byte)0x5d, (byte)0x02, (byte)0xab, (byte)0x8c, (byte)0x0f, (byte)0xd0, (byte)0x40, (byte)0xeb, (byte)0x58, (byte)0x44, (byte)0xb0, (byte)0x05, (byte)0xc3, (byte)0x9e, (byte)0xd8, (byte)0x27, (byte)0x4a, (byte)0x9d, (byte)0xbf, (byte)0xa8, (byte)0x06, (byte)0x71, (byte)0x40, (byte)0x94, (byte)0x39, (byte)0xd2 }; static byte[] pubKeyEnc2 = { (byte)0x30, (byte)0x4c, (byte)0x30, (byte)0x0d, (byte)0x06, (byte)0x09, (byte)0x2a, (byte)0x86, (byte)0x48, (byte)0x86, (byte)0xf7, (byte)0x0d, (byte)0x01, (byte)0x01, (byte)0x01, (byte)0x05, (byte)0x00, (byte)0x03, (byte)0x3b, (byte)0x00, (byte)0x30, (byte)0x38, (byte)0x02, (byte)0x33, (byte)0x00, (byte)0xa3, (byte)0x07, (byte)0x9a, (byte)0x90, (byte)0xdf, (byte)0x0d, (byte)0xfd, (byte)0x72, (byte)0xac, (byte)0x09, (byte)0x0c, (byte)0xcc, (byte)0x2a, (byte)0x78, (byte)0xb8, (byte)0x74, (byte)0x13, (byte)0x13, (byte)0x3e, (byte)0x40, (byte)0x75, (byte)0x9c, (byte)0x98, (byte)0xfa, (byte)0xf8, (byte)0x20, (byte)0x4f, (byte)0x35, (byte)0x8a, (byte)0x0b, (byte)0x26, (byte)0x3c, (byte)0x67, (byte)0x70, (byte)0xe7, (byte)0x83, (byte)0xa9, (byte)0x3b, (byte)0x69, (byte)0x71, (byte)0xb7, (byte)0x37, (byte)0x79, (byte)0xd2, (byte)0x71, (byte)0x7b, (byte)0xe8, (byte)0x34, (byte)0x77, (byte)0xcf, (byte)0x02, (byte)0x01, (byte)0x03 }; static byte[] privKeyEnc2 = { (byte)0x30, (byte)0x82, (byte)0x01, (byte)0x13, (byte)0x02, (byte)0x01, (byte)0x00, (byte)0x30, (byte)0x0d, (byte)0x06, (byte)0x09, (byte)0x2a, (byte)0x86, (byte)0x48, (byte)0x86, (byte)0xf7, (byte)0x0d, (byte)0x01, (byte)0x01, (byte)0x01, (byte)0x05, (byte)0x00, (byte)0x04, (byte)0x81, (byte)0xfe, (byte)0x30, (byte)0x81, (byte)0xfb, (byte)0x02, (byte)0x01, (byte)0x00, (byte)0x02, (byte)0x33, (byte)0x00, (byte)0xa3, (byte)0x07, (byte)0x9a, (byte)0x90, (byte)0xdf, (byte)0x0d, (byte)0xfd, (byte)0x72, (byte)0xac, (byte)0x09, (byte)0x0c, (byte)0xcc, (byte)0x2a, (byte)0x78, (byte)0xb8, (byte)0x74, (byte)0x13, (byte)0x13, (byte)0x3e, (byte)0x40, (byte)0x75, (byte)0x9c, (byte)0x98, (byte)0xfa, (byte)0xf8, (byte)0x20, (byte)0x4f, (byte)0x35, (byte)0x8a, (byte)0x0b, (byte)0x26, (byte)0x3c, (byte)0x67, (byte)0x70, (byte)0xe7, (byte)0x83, (byte)0xa9, (byte)0x3b, (byte)0x69, (byte)0x71, (byte)0xb7, (byte)0x37, (byte)0x79, (byte)0xd2, (byte)0x71, (byte)0x7b, (byte)0xe8, (byte)0x34, (byte)0x77, (byte)0xcf, (byte)0x02, (byte)0x01, (byte)0x03, (byte)0x02, (byte)0x32, (byte)0x6c, (byte)0xaf, (byte)0xbc, (byte)0x60, (byte)0x94, (byte)0xb3, (byte)0xfe, (byte)0x4c, (byte)0x72, (byte)0xb0, (byte)0xb3, (byte)0x32, (byte)0xc6, (byte)0xfb, (byte)0x25, (byte)0xa2, (byte)0xb7, (byte)0x62, (byte)0x29, (byte)0x80, (byte)0x4e, (byte)0x68, (byte)0x65, (byte)0xfc, (byte)0xa4, (byte)0x5a, (byte)0x74, (byte)0xdf, (byte)0x0f, (byte)0x8f, (byte)0xb8, (byte)0x41, (byte)0x3b, (byte)0x52, (byte)0xc0, (byte)0xd0, (byte)0xe5, (byte)0x3d, (byte)0x9b, (byte)0x59, (byte)0x0f, (byte)0xf1, (byte)0x9b, (byte)0xe7, (byte)0x9f, (byte)0x49, (byte)0xdd, (byte)0x21, (byte)0xe5, (byte)0xeb, (byte)0x02, (byte)0x1a, (byte)0x00, (byte)0xcf, (byte)0x20, (byte)0x35, (byte)0x02, (byte)0x8b, (byte)0x9d, (byte)0x86, (byte)0x98, (byte)0x40, (byte)0xb4, (byte)0x16, (byte)0x66, (byte)0xb4, (byte)0x2e, (byte)0x92, (byte)0xea, (byte)0x0d, (byte)0xa3, (byte)0xb4, (byte)0x32, (byte)0x04, (byte)0xb5, (byte)0xcf, (byte)0xce, (byte)0x91, (byte)0x02, (byte)0x1a, (byte)0x00, (byte)0xc9, (byte)0x7f, (byte)0xb1, (byte)0xf0, (byte)0x27, (byte)0xf4, (byte)0x53, (byte)0xf6, (byte)0x34, (byte)0x12, (byte)0x33, (byte)0xea, (byte)0xaa, (byte)0xd1, (byte)0xd9, (byte)0x35, (byte)0x3f, (byte)0x6c, (byte)0x42, (byte)0xd0, (byte)0x88, (byte)0x66, (byte)0xb1, (byte)0xd0, (byte)0x5f, (byte)0x02, (byte)0x1a, (byte)0x00, (byte)0x8a, (byte)0x15, (byte)0x78, (byte)0xac, (byte)0x5d, (byte)0x13, (byte)0xaf, (byte)0x10, (byte)0x2b, (byte)0x22, (byte)0xb9, (byte)0x99, (byte)0xcd, (byte)0x74, (byte)0x61, (byte)0xf1, (byte)0x5e, (byte)0x6d, (byte)0x22, (byte)0xcc, (byte)0x03, (byte)0x23, (byte)0xdf, (byte)0xdf, (byte)0x0b, (byte)0x02, (byte)0x1a, (byte)0x00, (byte)0x86, (byte)0x55, (byte)0x21, (byte)0x4a, (byte)0xc5, (byte)0x4d, (byte)0x8d, (byte)0x4e, (byte)0xcd, (byte)0x61, (byte)0x77, (byte)0xf1, (byte)0xc7, (byte)0x36, (byte)0x90, (byte)0xce, (byte)0x2a, (byte)0x48, (byte)0x2c, (byte)0x8b, (byte)0x05, (byte)0x99, (byte)0xcb, (byte)0xe0, (byte)0x3f, (byte)0x02, (byte)0x1a, (byte)0x00, (byte)0x83, (byte)0xef, (byte)0xef, (byte)0xb8, (byte)0xa9, (byte)0xa4, (byte)0x0d, (byte)0x1d, (byte)0xb6, (byte)0xed, (byte)0x98, (byte)0xad, (byte)0x84, (byte)0xed, (byte)0x13, (byte)0x35, (byte)0xdc, (byte)0xc1, (byte)0x08, (byte)0xf3, (byte)0x22, (byte)0xd0, (byte)0x57, (byte)0xcf, (byte)0x8d }; static byte[] output2 = { (byte)0x14, (byte)0xbd, (byte)0xdd, (byte)0x28, (byte)0xc9, (byte)0x83, (byte)0x35, (byte)0x19, (byte)0x23, (byte)0x80, (byte)0xe8, (byte)0xe5, (byte)0x49, (byte)0xb1, (byte)0x58, (byte)0x2a, (byte)0x8b, (byte)0x40, (byte)0xb4, (byte)0x48, (byte)0x6d, (byte)0x03, (byte)0xa6, (byte)0xa5, (byte)0x31, (byte)0x1f, (byte)0x1f, (byte)0xd5, (byte)0xf0, (byte)0xa1, (byte)0x80, (byte)0xe4, (byte)0x17, (byte)0x53, (byte)0x03, (byte)0x29, (byte)0xa9, (byte)0x34, (byte)0x90, (byte)0x74, (byte)0xb1, (byte)0x52, (byte)0x13, (byte)0x54, (byte)0x29, (byte)0x08, (byte)0x24, (byte)0x52, (byte)0x62, (byte)0x51 }; static byte[] pubKeyEnc3 = { (byte)0x30, (byte)0x81, (byte)0x9d, (byte)0x30, (byte)0x0d, (byte)0x06, (byte)0x09, (byte)0x2a, (byte)0x86, (byte)0x48, (byte)0x86, (byte)0xf7, (byte)0x0d, (byte)0x01, (byte)0x01, (byte)0x01, (byte)0x05, (byte)0x00, (byte)0x03, (byte)0x81, (byte)0x8b, (byte)0x00, (byte)0x30, (byte)0x81, (byte)0x87, (byte)0x02, (byte)0x81, (byte)0x81, (byte)0x00, (byte)0xbb, (byte)0xf8, (byte)0x2f, (byte)0x09, (byte)0x06, (byte)0x82, (byte)0xce, (byte)0x9c, (byte)0x23, (byte)0x38, (byte)0xac, (byte)0x2b, (byte)0x9d, (byte)0xa8, (byte)0x71, (byte)0xf7, (byte)0x36, (byte)0x8d, (byte)0x07, (byte)0xee, (byte)0xd4, (byte)0x10, (byte)0x43, (byte)0xa4, (byte)0x40, (byte)0xd6, (byte)0xb6, (byte)0xf0, (byte)0x74, (byte)0x54, (byte)0xf5, (byte)0x1f, (byte)0xb8, (byte)0xdf, (byte)0xba, (byte)0xaf, (byte)0x03, (byte)0x5c, (byte)0x02, (byte)0xab, (byte)0x61, (byte)0xea, (byte)0x48, (byte)0xce, (byte)0xeb, (byte)0x6f, (byte)0xcd, (byte)0x48, (byte)0x76, (byte)0xed, (byte)0x52, (byte)0x0d, (byte)0x60, (byte)0xe1, (byte)0xec, (byte)0x46, (byte)0x19, (byte)0x71, (byte)0x9d, (byte)0x8a, (byte)0x5b, (byte)0x8b, (byte)0x80, (byte)0x7f, (byte)0xaf, (byte)0xb8, (byte)0xe0, (byte)0xa3, (byte)0xdf, (byte)0xc7, (byte)0x37, (byte)0x72, (byte)0x3e, (byte)0xe6, (byte)0xb4, (byte)0xb7, (byte)0xd9, (byte)0x3a, (byte)0x25, (byte)0x84, (byte)0xee, (byte)0x6a, (byte)0x64, (byte)0x9d, (byte)0x06, (byte)0x09, (byte)0x53, (byte)0x74, (byte)0x88, (byte)0x34, (byte)0xb2, (byte)0x45, (byte)0x45, (byte)0x98, (byte)0x39, (byte)0x4e, (byte)0xe0, (byte)0xaa, (byte)0xb1, (byte)0x2d, (byte)0x7b, (byte)0x61, (byte)0xa5, (byte)0x1f, (byte)0x52, (byte)0x7a, (byte)0x9a, (byte)0x41, (byte)0xf6, (byte)0xc1, (byte)0x68, (byte)0x7f, (byte)0xe2, (byte)0x53, (byte)0x72, (byte)0x98, (byte)0xca, (byte)0x2a, (byte)0x8f, (byte)0x59, (byte)0x46, (byte)0xf8, (byte)0xe5, (byte)0xfd, (byte)0x09, (byte)0x1d, (byte)0xbd, (byte)0xcb, (byte)0x02, (byte)0x01, (byte)0x11 }; static byte[] privKeyEnc3 = { (byte)0x30, (byte)0x82, (byte)0x02, (byte)0x75, (byte)0x02, (byte)0x01, (byte)0x00, (byte)0x30, (byte)0x0d, (byte)0x06, (byte)0x09, (byte)0x2a, (byte)0x86, (byte)0x48, (byte)0x86, (byte)0xf7, (byte)0x0d, (byte)0x01, (byte)0x01, (byte)0x01, (byte)0x05, (byte)0x00, (byte)0x04, (byte)0x82, (byte)0x02, (byte)0x5f, (byte)0x30, (byte)0x82, (byte)0x02, (byte)0x5b, (byte)0x02, (byte)0x01, (byte)0x00, (byte)0x02, (byte)0x81, (byte)0x81, (byte)0x00, (byte)0xbb, (byte)0xf8, (byte)0x2f, (byte)0x09, (byte)0x06, (byte)0x82, (byte)0xce, (byte)0x9c, (byte)0x23, (byte)0x38, (byte)0xac, (byte)0x2b, (byte)0x9d, (byte)0xa8, (byte)0x71, (byte)0xf7, (byte)0x36, (byte)0x8d, (byte)0x07, (byte)0xee, (byte)0xd4, (byte)0x10, (byte)0x43, (byte)0xa4, (byte)0x40, (byte)0xd6, (byte)0xb6, (byte)0xf0, (byte)0x74, (byte)0x54, (byte)0xf5, (byte)0x1f, (byte)0xb8, (byte)0xdf, (byte)0xba, (byte)0xaf, (byte)0x03, (byte)0x5c, (byte)0x02, (byte)0xab, (byte)0x61, (byte)0xea, (byte)0x48, (byte)0xce, (byte)0xeb, (byte)0x6f, (byte)0xcd, (byte)0x48, (byte)0x76, (byte)0xed, (byte)0x52, (byte)0x0d, (byte)0x60, (byte)0xe1, (byte)0xec, (byte)0x46, (byte)0x19, (byte)0x71, (byte)0x9d, (byte)0x8a, (byte)0x5b, (byte)0x8b, (byte)0x80, (byte)0x7f, (byte)0xaf, (byte)0xb8, (byte)0xe0, (byte)0xa3, (byte)0xdf, (byte)0xc7, (byte)0x37, (byte)0x72, (byte)0x3e, (byte)0xe6, (byte)0xb4, (byte)0xb7, (byte)0xd9, (byte)0x3a, (byte)0x25, (byte)0x84, (byte)0xee, (byte)0x6a, (byte)0x64, (byte)0x9d, (byte)0x06, (byte)0x09, (byte)0x53, (byte)0x74, (byte)0x88, (byte)0x34, (byte)0xb2, (byte)0x45, (byte)0x45, (byte)0x98, (byte)0x39, (byte)0x4e, (byte)0xe0, (byte)0xaa, (byte)0xb1, (byte)0x2d, (byte)0x7b, (byte)0x61, (byte)0xa5, (byte)0x1f, (byte)0x52, (byte)0x7a, (byte)0x9a, (byte)0x41, (byte)0xf6, (byte)0xc1, (byte)0x68, (byte)0x7f, (byte)0xe2, (byte)0x53, (byte)0x72, (byte)0x98, (byte)0xca, (byte)0x2a, (byte)0x8f, (byte)0x59, (byte)0x46, (byte)0xf8, (byte)0xe5, (byte)0xfd, (byte)0x09, (byte)0x1d, (byte)0xbd, (byte)0xcb, (byte)0x02, (byte)0x01, (byte)0x11, (byte)0x02, (byte)0x81, (byte)0x81, (byte)0x00, (byte)0xa5, (byte)0xda, (byte)0xfc, (byte)0x53, (byte)0x41, (byte)0xfa, (byte)0xf2, (byte)0x89, (byte)0xc4, (byte)0xb9, (byte)0x88, (byte)0xdb, (byte)0x30, (byte)0xc1, (byte)0xcd, (byte)0xf8, (byte)0x3f, (byte)0x31, (byte)0x25, (byte)0x1e, (byte)0x06, (byte)0x68, (byte)0xb4, (byte)0x27, (byte)0x84, (byte)0x81, (byte)0x38, (byte)0x01, (byte)0x57, (byte)0x96, (byte)0x41, (byte)0xb2, (byte)0x94, (byte)0x10, (byte)0xb3, (byte)0xc7, (byte)0x99, (byte)0x8d, (byte)0x6b, (byte)0xc4, (byte)0x65, (byte)0x74, (byte)0x5e, (byte)0x5c, (byte)0x39, (byte)0x26, (byte)0x69, (byte)0xd6, (byte)0x87, (byte)0x0d, (byte)0xa2, (byte)0xc0, (byte)0x82, (byte)0xa9, (byte)0x39, (byte)0xe3, (byte)0x7f, (byte)0xdc, (byte)0xb8, (byte)0x2e, (byte)0xc9, (byte)0x3e, (byte)0xda, (byte)0xc9, (byte)0x7f, (byte)0xf3, (byte)0xad, (byte)0x59, (byte)0x50, (byte)0xac, (byte)0xcf, (byte)0xbc, (byte)0x11, (byte)0x1c, (byte)0x76, (byte)0xf1, (byte)0xa9, (byte)0x52, (byte)0x94, (byte)0x44, (byte)0xe5, (byte)0x6a, (byte)0xaf, (byte)0x68, (byte)0xc5, (byte)0x6c, (byte)0x09, (byte)0x2c, (byte)0xd3, (byte)0x8d, (byte)0xc3, (byte)0xbe, (byte)0xf5, (byte)0xd2, (byte)0x0a, (byte)0x93, (byte)0x99, (byte)0x26, (byte)0xed, (byte)0x4f, (byte)0x74, (byte)0xa1, (byte)0x3e, (byte)0xdd, (byte)0xfb, (byte)0xe1, (byte)0xa1, (byte)0xce, (byte)0xcc, (byte)0x48, (byte)0x94, (byte)0xaf, (byte)0x94, (byte)0x28, (byte)0xc2, (byte)0xb7, (byte)0xb8, (byte)0x88, (byte)0x3f, (byte)0xe4, (byte)0x46, (byte)0x3a, (byte)0x4b, (byte)0xc8, (byte)0x5b, (byte)0x1c, (byte)0xb3, (byte)0xc1, (byte)0x02, (byte)0x41, (byte)0x00, (byte)0xee, (byte)0xcf, (byte)0xae, (byte)0x81, (byte)0xb1, (byte)0xb9, (byte)0xb3, (byte)0xc9, (byte)0x08, (byte)0x81, (byte)0x0b, (byte)0x10, (byte)0xa1, (byte)0xb5, (byte)0x60, (byte)0x01, (byte)0x99, (byte)0xeb, (byte)0x9f, (byte)0x44, (byte)0xae, (byte)0xf4, (byte)0xfd, (byte)0xa4, (byte)0x93, (byte)0xb8, (byte)0x1a, (byte)0x9e, (byte)0x3d, (byte)0x84, (byte)0xf6, (byte)0x32, (byte)0x12, (byte)0x4e, (byte)0xf0, (byte)0x23, (byte)0x6e, (byte)0x5d, (byte)0x1e, (byte)0x3b, (byte)0x7e, (byte)0x28, (byte)0xfa, (byte)0xe7, (byte)0xaa, (byte)0x04, (byte)0x0a, (byte)0x2d, (byte)0x5b, (byte)0x25, (byte)0x21, (byte)0x76, (byte)0x45, (byte)0x9d, (byte)0x1f, (byte)0x39, (byte)0x75, (byte)0x41, (byte)0xba, (byte)0x2a, (byte)0x58, (byte)0xfb, (byte)0x65, (byte)0x99, (byte)0x02, (byte)0x41, (byte)0x00, (byte)0xc9, (byte)0x7f, (byte)0xb1, (byte)0xf0, (byte)0x27, (byte)0xf4, (byte)0x53, (byte)0xf6, (byte)0x34, (byte)0x12, (byte)0x33, (byte)0xea, (byte)0xaa, (byte)0xd1, (byte)0xd9, (byte)0x35, (byte)0x3f, (byte)0x6c, (byte)0x42, (byte)0xd0, (byte)0x88, (byte)0x66, (byte)0xb1, (byte)0xd0, (byte)0x5a, (byte)0x0f, (byte)0x20, (byte)0x35, (byte)0x02, (byte)0x8b, (byte)0x9d, (byte)0x86, (byte)0x98, (byte)0x40, (byte)0xb4, (byte)0x16, (byte)0x66, (byte)0xb4, (byte)0x2e, (byte)0x92, (byte)0xea, (byte)0x0d, (byte)0xa3, (byte)0xb4, (byte)0x32, (byte)0x04, (byte)0xb5, (byte)0xcf, (byte)0xce, (byte)0x33, (byte)0x52, (byte)0x52, (byte)0x4d, (byte)0x04, (byte)0x16, (byte)0xa5, (byte)0xa4, (byte)0x41, (byte)0xe7, (byte)0x00, (byte)0xaf, (byte)0x46, (byte)0x15, (byte)0x03, (byte)0x02, (byte)0x40, (byte)0x54, (byte)0x49, (byte)0x4c, (byte)0xa6, (byte)0x3e, (byte)0xba, (byte)0x03, (byte)0x37, (byte)0xe4, (byte)0xe2, (byte)0x40, (byte)0x23, (byte)0xfc, (byte)0xd6, (byte)0x9a, (byte)0x5a, (byte)0xeb, (byte)0x07, (byte)0xdd, (byte)0xdc, (byte)0x01, (byte)0x83, (byte)0xa4, (byte)0xd0, (byte)0xac, (byte)0x9b, (byte)0x54, (byte)0xb0, (byte)0x51, (byte)0xf2, (byte)0xb1, (byte)0x3e, (byte)0xd9, (byte)0x49, (byte)0x09, (byte)0x75, (byte)0xea, (byte)0xb7, (byte)0x74, (byte)0x14, (byte)0xff, (byte)0x59, (byte)0xc1, (byte)0xf7, (byte)0x69, (byte)0x2e, (byte)0x9a, (byte)0x2e, (byte)0x20, (byte)0x2b, (byte)0x38, (byte)0xfc, (byte)0x91, (byte)0x0a, (byte)0x47, (byte)0x41, (byte)0x74, (byte)0xad, (byte)0xc9, (byte)0x3c, (byte)0x1f, (byte)0x67, (byte)0xc9, (byte)0x81, (byte)0x02, (byte)0x40, (byte)0x47, (byte)0x1e, (byte)0x02, (byte)0x90, (byte)0xff, (byte)0x0a, (byte)0xf0, (byte)0x75, (byte)0x03, (byte)0x51, (byte)0xb7, (byte)0xf8, (byte)0x78, (byte)0x86, (byte)0x4c, (byte)0xa9, (byte)0x61, (byte)0xad, (byte)0xbd, (byte)0x3a, (byte)0x8a, (byte)0x7e, (byte)0x99, (byte)0x1c, (byte)0x5c, (byte)0x05, (byte)0x56, (byte)0xa9, (byte)0x4c, (byte)0x31, (byte)0x46, (byte)0xa7, (byte)0xf9, (byte)0x80, (byte)0x3f, (byte)0x8f, (byte)0x6f, (byte)0x8a, (byte)0xe3, (byte)0x42, (byte)0xe9, (byte)0x31, (byte)0xfd, (byte)0x8a, (byte)0xe4, (byte)0x7a, (byte)0x22, (byte)0x0d, (byte)0x1b, (byte)0x99, (byte)0xa4, (byte)0x95, (byte)0x84, (byte)0x98, (byte)0x07, (byte)0xfe, (byte)0x39, (byte)0xf9, (byte)0x24, (byte)0x5a, (byte)0x98, (byte)0x36, (byte)0xda, (byte)0x3d, (byte)0x02, (byte)0x41, (byte)0x00, (byte)0xb0, (byte)0x6c, (byte)0x4f, (byte)0xda, (byte)0xbb, (byte)0x63, (byte)0x01, (byte)0x19, (byte)0x8d, (byte)0x26, (byte)0x5b, (byte)0xdb, (byte)0xae, (byte)0x94, (byte)0x23, (byte)0xb3, (byte)0x80, (byte)0xf2, (byte)0x71, (byte)0xf7, (byte)0x34, (byte)0x53, (byte)0x88, (byte)0x50, (byte)0x93, (byte)0x07, (byte)0x7f, (byte)0xcd, (byte)0x39, (byte)0xe2, (byte)0x11, (byte)0x9f, (byte)0xc9, (byte)0x86, (byte)0x32, (byte)0x15, (byte)0x4f, (byte)0x58, (byte)0x83, (byte)0xb1, (byte)0x67, (byte)0xa9, (byte)0x67, (byte)0xbf, (byte)0x40, (byte)0x2b, (byte)0x4e, (byte)0x9e, (byte)0x2e, (byte)0x0f, (byte)0x96, (byte)0x56, (byte)0xe6, (byte)0x98, (byte)0xea, (byte)0x36, (byte)0x66, (byte)0xed, (byte)0xfb, (byte)0x25, (byte)0x79, (byte)0x80, (byte)0x39, (byte)0xf7 }; static byte[] output3 = Hex.decode( "b8246b56a6ed5881aeb585d9a25b2ad790c417e080681bf1ac2bc3deb69d8bce" + "f0c4366fec400af052a72e9b0effb5b3f2f192dbeaca03c12740057113bf1f06" + "69ac22e9f3a7852e3c15d913cab0b8863a95c99294ce8674214954610346f4d4" + "74b26f7c48b42ee68e1f572a1fc4026ac456b4f59f7b621ea1b9d88f64202fb1"); byte[] seed = { (byte)0xaa, (byte)0xfd, (byte)0x12, (byte)0xf6, (byte)0x59, (byte)0xca, (byte)0xe6, (byte)0x34, (byte)0x89, (byte)0xb4, (byte)0x79, (byte)0xe5, (byte)0x07, (byte)0x6d, (byte)0xde, (byte)0xc2, (byte)0xf0, (byte)0x6c, (byte)0xb5, (byte)0x8f }; private class VecRand extends SecureRandom { byte[] seed; VecRand(byte[] seed) { this.seed = seed; } public void nextBytes( byte[] bytes) { System.arraycopy(seed, 0, bytes, 0, bytes.length); } } private void baseOaepTest( int id, byte[] pubKeyEnc, byte[] privKeyEnc, byte[] output) throws Exception { ByteArrayInputStream bIn = new ByteArrayInputStream(pubKeyEnc); ASN1InputStream dIn = new ASN1InputStream(bIn); // // extract the public key info. // RSAPublicKey pubStruct; pubStruct = RSAPublicKey.getInstance(new SubjectPublicKeyInfo((ASN1Sequence)dIn.readObject()).parsePublicKey()); bIn = new ByteArrayInputStream(privKeyEnc); dIn = new ASN1InputStream(bIn); // // extract the private key info. // RSAPrivateKey privStruct; privStruct = RSAPrivateKey.getInstance(new PrivateKeyInfo((ASN1Sequence)dIn.readObject()).parsePrivateKey()); RSAKeyParameters pubParameters = new RSAKeyParameters( false, pubStruct.getModulus(), pubStruct.getPublicExponent()); RSAKeyParameters privParameters = new RSAPrivateCrtKeyParameters( privStruct.getModulus(), privStruct.getPublicExponent(), privStruct.getPrivateExponent(), privStruct.getPrime1(), privStruct.getPrime2(), privStruct.getExponent1(), privStruct.getExponent2(), privStruct.getCoefficient()); byte[] input = new byte[] { (byte)0x54, (byte)0x85, (byte)0x9b, (byte)0x34, (byte)0x2c, (byte)0x49, (byte)0xea, (byte)0x2a }; encDec("id(" + id + ")", pubParameters, privParameters, seed, input, output); } private void encDec( String label, RSAKeyParameters pubParameters, RSAKeyParameters privParameters, byte[] seed, byte[] input, byte[] output) throws InvalidCipherTextException { AsymmetricBlockCipher cipher = new OAEPEncoding(new RSAEngine()); cipher.init(true, new ParametersWithRandom(pubParameters, new VecRand(seed))); byte[] out; out = cipher.processBlock(input, 0, input.length); for (int i = 0; i != output.length; i++) { if (out[i] != output[i]) { fail(label + " failed encryption"); } } cipher.init(false, privParameters); out = cipher.processBlock(output, 0, output.length); for (int i = 0; i != input.length; i++) { if (out[i] != input[i]) { fail(label + " failed decoding"); } } } /* * RSA vector tests from PKCS#1 page */ byte[] modulus_1024 = Hex.decode( "a8b3b284af8eb50b387034a860f146c4" + "919f318763cd6c5598c8ae4811a1e0ab" + "c4c7e0b082d693a5e7fced675cf46685" + "12772c0cbc64a742c6c630f533c8cc72" + "f62ae833c40bf25842e984bb78bdbf97" + "c0107d55bdb662f5c4e0fab9845cb514" + "8ef7392dd3aaff93ae1e6b667bb3d424" + "7616d4f5ba10d4cfd226de88d39f16fb"); byte[] pubExp_1024 = Hex.decode( "010001"); byte[] privExp_1024 = Hex.decode( "53339cfdb79fc8466a655c7316aca85c" + "55fd8f6dd898fdaf119517ef4f52e8fd" + "8e258df93fee180fa0e4ab29693cd83b" + "152a553d4ac4d1812b8b9fa5af0e7f55" + "fe7304df41570926f3311f15c4d65a73" + "2c483116ee3d3d2d0af3549ad9bf7cbf" + "b78ad884f84d5beb04724dc7369b31de" + "f37d0cf539e9cfcdd3de653729ead5d1"); byte[] prime1_1024 = Hex.decode( "d32737e7267ffe1341b2d5c0d150a81b" + "586fb3132bed2f8d5262864a9cb9f30a" + "f38be448598d413a172efb802c21acf1" + "c11c520c2f26a471dcad212eac7ca39d"); byte[] prime2_1024 = Hex.decode( "cc8853d1d54da630fac004f471f281c7" + "b8982d8224a490edbeb33d3e3d5cc93c" + "4765703d1dd791642f1f116a0dd852be" + "2419b2af72bfe9a030e860b0288b5d77"); byte[] primeExp1_1024 = Hex.decode( "0e12bf1718e9cef5599ba1c3882fe804" + "6a90874eefce8f2ccc20e4f2741fb0a3" + "3a3848aec9c9305fbecbd2d76819967d" + "4671acc6431e4037968db37878e695c1"); byte[] primeExp2_1024 = Hex.decode( "95297b0f95a2fa67d00707d609dfd4fc" + "05c89dafc2ef6d6ea55bec771ea33373" + "4d9251e79082ecda866efef13c459e1a" + "631386b7e354c899f5f112ca85d71583"); byte[] crtCoef_1024 = Hex.decode( "4f456c502493bdc0ed2ab756a3a6ed4d" + "67352a697d4216e93212b127a63d5411" + "ce6fa98d5dbefd73263e372814274381" + "8166ed7dd63687dd2a8ca1d2f4fbd8e1"); byte[] input_1024_1 = Hex.decode( "6628194e12073db03ba94cda9ef95323" + "97d50dba79b987004afefe34"); byte[] seed_1024_1 = Hex.decode( "18b776ea21069d69776a33e96bad48e1" + "dda0a5ef"); byte[] output_1024_1 = Hex.decode( "354fe67b4a126d5d35fe36c777791a3f" + "7ba13def484e2d3908aff722fad468fb" + "21696de95d0be911c2d3174f8afcc201" + "035f7b6d8e69402de5451618c21a535f" + "a9d7bfc5b8dd9fc243f8cf927db31322" + "d6e881eaa91a996170e657a05a266426" + "d98c88003f8477c1227094a0d9fa1e8c" + "4024309ce1ecccb5210035d47ac72e8a"); byte[] input_1024_2 = Hex.decode( "750c4047f547e8e41411856523298ac9" + "bae245efaf1397fbe56f9dd5"); byte[] seed_1024_2 = Hex.decode( "0cc742ce4a9b7f32f951bcb251efd925" + "fe4fe35f"); byte[] output_1024_2 = Hex.decode( "640db1acc58e0568fe5407e5f9b701df" + "f8c3c91e716c536fc7fcec6cb5b71c11" + "65988d4a279e1577d730fc7a29932e3f" + "00c81515236d8d8e31017a7a09df4352" + "d904cdeb79aa583adcc31ea698a4c052" + "83daba9089be5491f67c1a4ee48dc74b" + "bbe6643aef846679b4cb395a352d5ed1" + "15912df696ffe0702932946d71492b44"); byte[] input_1024_3 = Hex.decode( "d94ae0832e6445ce42331cb06d531a82" + "b1db4baad30f746dc916df24d4e3c245" + "1fff59a6423eb0e1d02d4fe646cf699d" + "fd818c6e97b051"); byte[] seed_1024_3 = Hex.decode( "2514df4695755a67b288eaf4905c36ee" + "c66fd2fd"); byte[] output_1024_3 = Hex.decode( "423736ed035f6026af276c35c0b3741b" + "365e5f76ca091b4e8c29e2f0befee603" + "595aa8322d602d2e625e95eb81b2f1c9" + "724e822eca76db8618cf09c5343503a4" + "360835b5903bc637e3879fb05e0ef326" + "85d5aec5067cd7cc96fe4b2670b6eac3" + "066b1fcf5686b68589aafb7d629b02d8" + "f8625ca3833624d4800fb081b1cf94eb"); byte[] input_1024_4 = Hex.decode( "52e650d98e7f2a048b4f86852153b97e" + "01dd316f346a19f67a85"); byte[] seed_1024_4 = Hex.decode( "c4435a3e1a18a68b6820436290a37cef" + "b85db3fb"); byte[] output_1024_4 = Hex.decode( "45ead4ca551e662c9800f1aca8283b05" + "25e6abae30be4b4aba762fa40fd3d38e" + "22abefc69794f6ebbbc05ddbb1121624" + "7d2f412fd0fba87c6e3acd888813646f" + "d0e48e785204f9c3f73d6d8239562722" + "dddd8771fec48b83a31ee6f592c4cfd4" + "bc88174f3b13a112aae3b9f7b80e0fc6" + "f7255ba880dc7d8021e22ad6a85f0755"); byte[] input_1024_5 = Hex.decode( "8da89fd9e5f974a29feffb462b49180f" + "6cf9e802"); byte[] seed_1024_5 = Hex.decode( "b318c42df3be0f83fea823f5a7b47ed5" + "e425a3b5"); byte[] output_1024_5 = Hex.decode( "36f6e34d94a8d34daacba33a2139d00a" + "d85a9345a86051e73071620056b920e2" + "19005855a213a0f23897cdcd731b4525" + "7c777fe908202befdd0b58386b1244ea" + "0cf539a05d5d10329da44e13030fd760" + "dcd644cfef2094d1910d3f433e1c7c6d" + "d18bc1f2df7f643d662fb9dd37ead905" + "9190f4fa66ca39e869c4eb449cbdc439"); byte[] input_1024_6 = Hex.decode( "26521050844271"); byte[] seed_1024_6 = Hex.decode( "e4ec0982c2336f3a677f6a356174eb0c" + "e887abc2"); byte[] output_1024_6 = Hex.decode( "42cee2617b1ecea4db3f4829386fbd61" + "dafbf038e180d837c96366df24c097b4" + "ab0fac6bdf590d821c9f10642e681ad0" + "5b8d78b378c0f46ce2fad63f74e0ad3d" + "f06b075d7eb5f5636f8d403b9059ca76" + "1b5c62bb52aa45002ea70baace08ded2" + "43b9d8cbd62a68ade265832b56564e43" + "a6fa42ed199a099769742df1539e8255"); byte[] modulus_1027 = Hex.decode( "051240b6cc0004fa48d0134671c078c7" + "c8dec3b3e2f25bc2564467339db38853" + "d06b85eea5b2de353bff42ac2e46bc97" + "fae6ac9618da9537a5c8f553c1e35762" + "5991d6108dcd7885fb3a25413f53efca" + "d948cb35cd9b9ae9c1c67626d113d57d" + "de4c5bea76bb5bb7de96c00d07372e96" + "85a6d75cf9d239fa148d70931b5f3fb0" + "39"); byte[] pubExp_1027 = Hex.decode( "010001"); byte[] privExp_1027 = Hex.decode( "0411ffca3b7ca5e9e9be7fe38a85105e" + "353896db05c5796aecd2a725161eb365" + "1c8629a9b862b904d7b0c7b37f8cb5a1" + "c2b54001018a00a1eb2cafe4ee4e9492" + "c348bc2bedab4b9ebbf064e8eff322b9" + "009f8eec653905f40df88a3cdc49d456" + "7f75627d41aca624129b46a0b7c698e5" + "e65f2b7ba102c749a10135b6540d0401"); byte[] prime1_1027 = Hex.decode( "027458c19ec1636919e736c9af25d609" + "a51b8f561d19c6bf6943dd1ee1ab8a4a" + "3f232100bd40b88decc6ba235548b6ef" + "792a11c9de823d0a7922c7095b6eba57" + "01"); byte[] prime2_1027 = Hex.decode( "0210ee9b33ab61716e27d251bd465f4b" + "35a1a232e2da00901c294bf22350ce49" + "0d099f642b5375612db63ba1f2038649" + "2bf04d34b3c22bceb909d13441b53b51" + "39"); byte[] primeExp1_1027 = Hex.decode( "39fa028b826e88c1121b750a8b242fa9" + "a35c5b66bdfd1fa637d3cc48a84a4f45" + "7a194e7727e49f7bcc6e5a5a412657fc" + "470c7322ebc37416ef458c307a8c0901"); byte[] primeExp2_1027 = Hex.decode( "015d99a84195943979fa9e1be2c3c1b6" + "9f432f46fd03e47d5befbbbfd6b1d137" + "1d83efb330a3e020942b2fed115e5d02" + "be24fd92c9019d1cecd6dd4cf1e54cc8" + "99"); byte[] crtCoef_1027 = Hex.decode( "01f0b7015170b3f5e42223ba30301c41" + "a6d87cbb70e30cb7d3c67d25473db1f6" + "cbf03e3f9126e3e97968279a865b2c2b" + "426524cfc52a683d31ed30eb984be412" + "ba"); byte[] input_1027_1 = Hex.decode( "4a86609534ee434a6cbca3f7e962e76d" + "455e3264c19f605f6e5ff6137c65c56d" + "7fb344cd52bc93374f3d166c9f0c6f9c" + "506bad19330972d2"); byte[] seed_1027_1 = Hex.decode( "1cac19ce993def55f98203f6852896c9" + "5ccca1f3"); byte[] output_1027_1 = Hex.decode( "04cce19614845e094152a3fe18e54e33" + "30c44e5efbc64ae16886cb1869014cc5" + "781b1f8f9e045384d0112a135ca0d12e" + "9c88a8e4063416deaae3844f60d6e96f" + "e155145f4525b9a34431ca3766180f70" + "e15a5e5d8e8b1a516ff870609f13f896" + "935ced188279a58ed13d07114277d75c" + "6568607e0ab092fd803a223e4a8ee0b1" + "a8"); byte[] input_1027_2 = Hex.decode( "b0adc4f3fe11da59ce992773d9059943" + "c03046497ee9d9f9a06df1166db46d98" + "f58d27ec074c02eee6cbe2449c8b9fc5" + "080c5c3f4433092512ec46aa793743c8"); byte[] seed_1027_2 = Hex.decode( "f545d5897585e3db71aa0cb8da76c51d" + "032ae963"); byte[] output_1027_2 = Hex.decode( "0097b698c6165645b303486fbf5a2a44" + "79c0ee85889b541a6f0b858d6b6597b1" + "3b854eb4f839af03399a80d79bda6578" + "c841f90d645715b280d37143992dd186" + "c80b949b775cae97370e4ec97443136c" + "6da484e970ffdb1323a20847821d3b18" + "381de13bb49aaea66530c4a4b8271f3e" + "ae172cd366e07e6636f1019d2a28aed1" + "5e"); byte[] input_1027_3 = Hex.decode( "bf6d42e701707b1d0206b0c8b45a1c72" + "641ff12889219a82bdea965b5e79a96b" + "0d0163ed9d578ec9ada20f2fbcf1ea3c" + "4089d83419ba81b0c60f3606da99"); byte[] seed_1027_3 = Hex.decode( "ad997feef730d6ea7be60d0dc52e72ea" + "cbfdd275"); byte[] output_1027_3 = Hex.decode( "0301f935e9c47abcb48acbbe09895d9f" + "5971af14839da4ff95417ee453d1fd77" + "319072bb7297e1b55d7561cd9d1bb24c" + "1a9a37c619864308242804879d86ebd0" + "01dce5183975e1506989b70e5a834341" + "54d5cbfd6a24787e60eb0c658d2ac193" + "302d1192c6e622d4a12ad4b53923bca2" + "46df31c6395e37702c6a78ae081fb9d0" + "65"); byte[] input_1027_4 = Hex.decode( "fb2ef112f5e766eb94019297934794f7" + "be2f6fc1c58e"); byte[] seed_1027_4 = Hex.decode( "136454df5730f73c807a7e40d8c1a312" + "ac5b9dd3"); byte[] output_1027_4 = Hex.decode( "02d110ad30afb727beb691dd0cf17d0a" + "f1a1e7fa0cc040ec1a4ba26a42c59d0a" + "796a2e22c8f357ccc98b6519aceb682e" + "945e62cb734614a529407cd452bee3e4" + "4fece8423cc19e55548b8b994b849c7e" + "cde4933e76037e1d0ce44275b08710c6" + "8e430130b929730ed77e09b015642c55" + "93f04e4ffb9410798102a8e96ffdfe11" + "e4"); byte[] input_1027_5 = Hex.decode( "28ccd447bb9e85166dabb9e5b7d1adad" + "c4b9d39f204e96d5e440ce9ad928bc1c" + "2284"); byte[] seed_1027_5 = Hex.decode( "bca8057f824b2ea257f2861407eef63d" + "33208681"); byte[] output_1027_5 = Hex.decode( "00dbb8a7439d90efd919a377c54fae8f" + "e11ec58c3b858362e23ad1b8a4431079" + "9066b99347aa525691d2adc58d9b06e3" + "4f288c170390c5f0e11c0aa3645959f1" + "8ee79e8f2be8d7ac5c23d061f18dd74b" + "8c5f2a58fcb5eb0c54f99f01a8324756" + "8292536583340948d7a8c97c4acd1e98" + "d1e29dc320e97a260532a8aa7a758a1e" + "c2"); byte[] input_1027_6 = Hex.decode( "f22242751ec6b1"); byte[] seed_1027_6 = Hex.decode( "2e7e1e17f647b5ddd033e15472f90f68" + "12f3ac4e"); byte[] output_1027_6 = Hex.decode( "00a5ffa4768c8bbecaee2db77e8f2eec" + "99595933545520835e5ba7db9493d3e1" + "7cddefe6a5f567624471908db4e2d83a" + "0fbee60608fc84049503b2234a07dc83" + "b27b22847ad8920ff42f674ef79b7628" + "0b00233d2b51b8cb2703a9d42bfbc825" + "0c96ec32c051e57f1b4ba528db89c37e" + "4c54e27e6e64ac69635ae887d9541619" + "a9"); private void oaepVecTest( int keySize, int no, RSAKeyParameters pubParam, RSAKeyParameters privParam, byte[] seed, byte[] input, byte[] output) throws Exception { encDec(keySize + " " + no, pubParam, privParam, seed, input, output); } public OAEPTest() { } public String getName() { return "OAEP"; } public void performTest() throws Exception { baseOaepTest(1, pubKeyEnc1, privKeyEnc1, output1); baseOaepTest(2, pubKeyEnc2, privKeyEnc2, output2); baseOaepTest(3, pubKeyEnc3, privKeyEnc3, output3); RSAKeyParameters pubParam = new RSAKeyParameters(false, new BigInteger(1, modulus_1024), new BigInteger(1, pubExp_1024)); RSAKeyParameters privParam = new RSAPrivateCrtKeyParameters(pubParam.getModulus(), pubParam.getExponent(), new BigInteger(1, privExp_1024), new BigInteger(1, prime1_1024), new BigInteger(1, prime2_1024), new BigInteger(1, primeExp1_1024), new BigInteger(1, primeExp2_1024), new BigInteger(1, crtCoef_1024)); oaepVecTest(1024, 1, pubParam, privParam, seed_1024_1, input_1024_1, output_1024_1); oaepVecTest(1024, 2, pubParam, privParam, seed_1024_2, input_1024_2, output_1024_2); oaepVecTest(1024, 3, pubParam, privParam, seed_1024_3, input_1024_3, output_1024_3); oaepVecTest(1024, 4, pubParam, privParam, seed_1024_4, input_1024_4, output_1024_4); oaepVecTest(1024, 5, pubParam, privParam, seed_1024_5, input_1024_5, output_1024_5); oaepVecTest(1024, 6, pubParam, privParam, seed_1024_6, input_1024_6, output_1024_6); pubParam = new RSAKeyParameters(false, new BigInteger(1, modulus_1027), new BigInteger(1, pubExp_1027)); privParam = new RSAPrivateCrtKeyParameters(pubParam.getModulus(), pubParam.getExponent(), new BigInteger(1, privExp_1027), new BigInteger(1, prime1_1027), new BigInteger(1, prime2_1027), new BigInteger(1, primeExp1_1027), new BigInteger(1, primeExp2_1027), new BigInteger(1, crtCoef_1027)); oaepVecTest(1027, 1, pubParam, privParam, seed_1027_1, input_1027_1, output_1027_1); oaepVecTest(1027, 2, pubParam, privParam, seed_1027_2, input_1027_2, output_1027_2); oaepVecTest(1027, 3, pubParam, privParam, seed_1027_3, input_1027_3, output_1027_3); oaepVecTest(1027, 4, pubParam, privParam, seed_1027_4, input_1027_4, output_1027_4); oaepVecTest(1027, 5, pubParam, privParam, seed_1027_5, input_1027_5, output_1027_5); oaepVecTest(1027, 6, pubParam, privParam, seed_1027_6, input_1027_6, output_1027_6); // // OAEP - public encrypt, private decrypt differring hashes // AsymmetricBlockCipher cipher = new OAEPEncoding(new RSAEngine(), new SHA256Digest(), new SHA1Digest(), new byte[10]); cipher.init(true, new ParametersWithRandom(pubParam, new SecureRandom())); byte[] input = new byte[10]; byte[] out = cipher.processBlock(input, 0, input.length); cipher.init(false, privParam); out = cipher.processBlock(out, 0, out.length); for (int i = 0; i != input.length; i++) { if (out[i] != input[i]) { fail("mixed digest failed decoding"); } } cipher = new OAEPEncoding(new RSAEngine(), new SHA1Digest(), new SHA256Digest(), new byte[10]); cipher.init(true, new ParametersWithRandom(pubParam, new SecureRandom())); out = cipher.processBlock(input, 0, input.length); cipher.init(false, privParam); out = cipher.processBlock(out, 0, out.length); for (int i = 0; i != input.length; i++) { if (out[i] != input[i]) { fail("mixed digest failed decoding"); } } } public static void main( String[] args) { runTest(new OAEPTest()); } } bouncycastle-1.49.orig/test/src/org/bouncycastle/crypto/test/PaddingTest.java0000644000175000017500000001165411013717661027043 0ustar ebourgebourgpackage org.bouncycastle.crypto.test; import java.security.SecureRandom; import org.bouncycastle.crypto.engines.DESEngine; import org.bouncycastle.crypto.paddings.BlockCipherPadding; import org.bouncycastle.crypto.paddings.ISO10126d2Padding; import org.bouncycastle.crypto.paddings.ISO7816d4Padding; import org.bouncycastle.crypto.paddings.PKCS7Padding; import org.bouncycastle.crypto.paddings.PaddedBufferedBlockCipher; import org.bouncycastle.crypto.paddings.TBCPadding; import org.bouncycastle.crypto.paddings.X923Padding; import org.bouncycastle.crypto.paddings.ZeroBytePadding; import org.bouncycastle.crypto.params.KeyParameter; import org.bouncycastle.crypto.InvalidCipherTextException; import org.bouncycastle.util.encoders.Hex; import org.bouncycastle.util.test.SimpleTest; /** * General Padding tests. */ public class PaddingTest extends SimpleTest { public PaddingTest() { } private void blockCheck( PaddedBufferedBlockCipher cipher, BlockCipherPadding padding, KeyParameter key, byte[] data) { byte[] out = new byte[data.length + 8]; byte[] dec = new byte[data.length]; try { cipher.init(true, key); int len = cipher.processBytes(data, 0, data.length, out, 0); len += cipher.doFinal(out, len); cipher.init(false, key); int decLen = cipher.processBytes(out, 0, len, dec, 0); decLen += cipher.doFinal(dec, decLen); if (!areEqual(data, dec)) { fail("failed to decrypt - i = " + data.length + ", padding = " + padding.getPaddingName()); } } catch (Exception e) { fail("Exception - " + e.toString(), e); } } public void testPadding( BlockCipherPadding padding, SecureRandom rand, byte[] ffVector, byte[] ZeroVector) { PaddedBufferedBlockCipher cipher = new PaddedBufferedBlockCipher(new DESEngine(), padding); KeyParameter key = new KeyParameter(Hex.decode("0011223344556677")); // // ff test // byte[] data = { (byte)0xff, (byte)0xff, (byte)0xff, (byte)0, (byte)0, (byte)0, (byte)0, (byte)0 }; if (ffVector != null) { padding.addPadding(data, 3); if (!areEqual(data, ffVector)) { fail("failed ff test for " + padding.getPaddingName()); } } // // zero test // if (ZeroVector != null) { data = new byte[8]; padding.addPadding(data, 4); if (!areEqual(data, ZeroVector)) { fail("failed zero test for " + padding.getPaddingName()); } } for (int i = 1; i != 200; i++) { data = new byte[i]; rand.nextBytes(data); blockCheck(cipher, padding, key, data); } } public void performTest() { SecureRandom rand = new SecureRandom(new byte[20]); rand.setSeed(System.currentTimeMillis()); testPadding(new PKCS7Padding(), rand, Hex.decode("ffffff0505050505"), Hex.decode("0000000004040404")); PKCS7Padding padder = new PKCS7Padding(); try { padder.padCount(new byte[8]); fail("invalid padding not detected"); } catch (InvalidCipherTextException e) { if (!"pad block corrupted".equals(e.getMessage())) { fail("wrong exception for corrupt padding: " + e); } } testPadding(new ISO10126d2Padding(), rand, null, null); testPadding(new X923Padding(), rand, null, null); testPadding(new TBCPadding(), rand, Hex.decode("ffffff0000000000"), Hex.decode("00000000ffffffff")); testPadding(new ZeroBytePadding(), rand, Hex.decode("ffffff0000000000"), null); testPadding(new ISO7816d4Padding(), rand, Hex.decode("ffffff8000000000"), Hex.decode("0000000080000000")); } public String getName() { return "PaddingTest"; } public static void main( String[] args) { runTest(new PaddingTest()); } } bouncycastle-1.49.orig/test/src/org/bouncycastle/crypto/test/CAST5Test.java0000644000175000017500000000233210330633061026275 0ustar ebourgebourgpackage org.bouncycastle.crypto.test; import org.bouncycastle.crypto.engines.CAST5Engine; import org.bouncycastle.crypto.params.KeyParameter; import org.bouncycastle.util.encoders.Hex; import org.bouncycastle.util.test.SimpleTest; /** * cast tester - vectors from http://www.ietf.org/rfc/rfc2144.txt */ public class CAST5Test extends CipherTest { static SimpleTest[] tests = { new BlockCipherVectorTest(0, new CAST5Engine(), new KeyParameter(Hex.decode("0123456712345678234567893456789A")), "0123456789ABCDEF", "238B4FE5847E44B2"), new BlockCipherVectorTest(0, new CAST5Engine(), new KeyParameter(Hex.decode("01234567123456782345")), "0123456789ABCDEF", "EB6A711A2C02271B"), new BlockCipherVectorTest(0, new CAST5Engine(), new KeyParameter(Hex.decode("0123456712")), "0123456789ABCDEF", "7Ac816d16E9B302E"), }; CAST5Test() { super(tests, new CAST5Engine(), new KeyParameter(new byte[16])); } public String getName() { return "CAST5"; } public static void main( String[] args) { runTest(new CAST5Test()); } } bouncycastle-1.49.orig/test/src/org/bouncycastle/crypto/test/GCMTest.java0000644000175000017500000005325612104607621026103 0ustar ebourgebourgpackage org.bouncycastle.crypto.test; import java.security.SecureRandom; import org.bouncycastle.crypto.InvalidCipherTextException; import org.bouncycastle.crypto.engines.AESFastEngine; import org.bouncycastle.crypto.modes.GCMBlockCipher; import org.bouncycastle.crypto.modes.gcm.BasicGCMMultiplier; import org.bouncycastle.crypto.modes.gcm.GCMMultiplier; import org.bouncycastle.crypto.modes.gcm.Tables64kGCMMultiplier; import org.bouncycastle.crypto.modes.gcm.Tables8kGCMMultiplier; import org.bouncycastle.crypto.params.AEADParameters; import org.bouncycastle.crypto.params.KeyParameter; import org.bouncycastle.util.encoders.Hex; import org.bouncycastle.util.test.SimpleTest; /** * Test vectors from "The Galois/Counter Mode of Operation (GCM)", McGrew/Viega, Appendix B */ public class GCMTest extends SimpleTest { private static final String[][] TEST_VECTORS = new String[][] { { "Test Case 1", "00000000000000000000000000000000", "", "", "000000000000000000000000", "", "58e2fccefa7e3061367f1d57a4e7455a", }, { "Test Case 2", "00000000000000000000000000000000", "00000000000000000000000000000000", "", "000000000000000000000000", "0388dace60b6a392f328c2b971b2fe78", "ab6e47d42cec13bdf53a67b21257bddf", }, { "Test Case 3", "feffe9928665731c6d6a8f9467308308", "d9313225f88406e5a55909c5aff5269a" + "86a7a9531534f7da2e4c303d8a318a72" + "1c3c0c95956809532fcf0e2449a6b525" + "b16aedf5aa0de657ba637b391aafd255", "", "cafebabefacedbaddecaf888", "42831ec2217774244b7221b784d0d49c" + "e3aa212f2c02a4e035c17e2329aca12e" + "21d514b25466931c7d8f6a5aac84aa05" + "1ba30b396a0aac973d58e091473f5985", "4d5c2af327cd64a62cf35abd2ba6fab4", }, { "Test Case 4", "feffe9928665731c6d6a8f9467308308", "d9313225f88406e5a55909c5aff5269a" + "86a7a9531534f7da2e4c303d8a318a72" + "1c3c0c95956809532fcf0e2449a6b525" + "b16aedf5aa0de657ba637b39", "feedfacedeadbeeffeedfacedeadbeef" + "abaddad2", "cafebabefacedbaddecaf888", "42831ec2217774244b7221b784d0d49c" + "e3aa212f2c02a4e035c17e2329aca12e" + "21d514b25466931c7d8f6a5aac84aa05" + "1ba30b396a0aac973d58e091", "5bc94fbc3221a5db94fae95ae7121a47", }, { "Test Case 5", "feffe9928665731c6d6a8f9467308308", "d9313225f88406e5a55909c5aff5269a" + "86a7a9531534f7da2e4c303d8a318a72" + "1c3c0c95956809532fcf0e2449a6b525" + "b16aedf5aa0de657ba637b39", "feedfacedeadbeeffeedfacedeadbeef" + "abaddad2", "cafebabefacedbad", "61353b4c2806934a777ff51fa22a4755" + "699b2a714fcdc6f83766e5f97b6c7423" + "73806900e49f24b22b097544d4896b42" + "4989b5e1ebac0f07c23f4598", "3612d2e79e3b0785561be14aaca2fccb", }, { "Test Case 6", "feffe9928665731c6d6a8f9467308308", "d9313225f88406e5a55909c5aff5269a" + "86a7a9531534f7da2e4c303d8a318a72" + "1c3c0c95956809532fcf0e2449a6b525" + "b16aedf5aa0de657ba637b39", "feedfacedeadbeeffeedfacedeadbeef" + "abaddad2", "9313225df88406e555909c5aff5269aa" + "6a7a9538534f7da1e4c303d2a318a728" + "c3c0c95156809539fcf0e2429a6b5254" + "16aedbf5a0de6a57a637b39b", "8ce24998625615b603a033aca13fb894" + "be9112a5c3a211a8ba262a3cca7e2ca7" + "01e4a9a4fba43c90ccdcb281d48c7c6f" + "d62875d2aca417034c34aee5", "619cc5aefffe0bfa462af43c1699d050", }, { "Test Case 7", "00000000000000000000000000000000" + "0000000000000000", "", "", "000000000000000000000000", "", "cd33b28ac773f74ba00ed1f312572435", }, { "Test Case 8", "00000000000000000000000000000000" + "0000000000000000", "00000000000000000000000000000000", "", "000000000000000000000000", "98e7247c07f0fe411c267e4384b0f600", "2ff58d80033927ab8ef4d4587514f0fb", }, { "Test Case 9", "feffe9928665731c6d6a8f9467308308" + "feffe9928665731c", "d9313225f88406e5a55909c5aff5269a" + "86a7a9531534f7da2e4c303d8a318a72" + "1c3c0c95956809532fcf0e2449a6b525" + "b16aedf5aa0de657ba637b391aafd255", "", "cafebabefacedbaddecaf888", "3980ca0b3c00e841eb06fac4872a2757" + "859e1ceaa6efd984628593b40ca1e19c" + "7d773d00c144c525ac619d18c84a3f47" + "18e2448b2fe324d9ccda2710acade256", "9924a7c8587336bfb118024db8674a14", }, { "Test Case 10", "feffe9928665731c6d6a8f9467308308" + "feffe9928665731c", "d9313225f88406e5a55909c5aff5269a" + "86a7a9531534f7da2e4c303d8a318a72" + "1c3c0c95956809532fcf0e2449a6b525" + "b16aedf5aa0de657ba637b39", "feedfacedeadbeeffeedfacedeadbeef" + "abaddad2", "cafebabefacedbaddecaf888", "3980ca0b3c00e841eb06fac4872a2757" + "859e1ceaa6efd984628593b40ca1e19c" + "7d773d00c144c525ac619d18c84a3f47" + "18e2448b2fe324d9ccda2710", "2519498e80f1478f37ba55bd6d27618c", }, { "Test Case 11", "feffe9928665731c6d6a8f9467308308" + "feffe9928665731c", "d9313225f88406e5a55909c5aff5269a" + "86a7a9531534f7da2e4c303d8a318a72" + "1c3c0c95956809532fcf0e2449a6b525" + "b16aedf5aa0de657ba637b39", "feedfacedeadbeeffeedfacedeadbeef" + "abaddad2", "cafebabefacedbad", "0f10f599ae14a154ed24b36e25324db8" + "c566632ef2bbb34f8347280fc4507057" + "fddc29df9a471f75c66541d4d4dad1c9" + "e93a19a58e8b473fa0f062f7", "65dcc57fcf623a24094fcca40d3533f8", }, { "Test Case 12", "feffe9928665731c6d6a8f9467308308" + "feffe9928665731c", "d9313225f88406e5a55909c5aff5269a" + "86a7a9531534f7da2e4c303d8a318a72" + "1c3c0c95956809532fcf0e2449a6b525" + "b16aedf5aa0de657ba637b39", "feedfacedeadbeeffeedfacedeadbeef" + "abaddad2", "9313225df88406e555909c5aff5269aa" + "6a7a9538534f7da1e4c303d2a318a728" + "c3c0c95156809539fcf0e2429a6b5254" + "16aedbf5a0de6a57a637b39b", "d27e88681ce3243c4830165a8fdcf9ff" + "1de9a1d8e6b447ef6ef7b79828666e45" + "81e79012af34ddd9e2f037589b292db3" + "e67c036745fa22e7e9b7373b", "dcf566ff291c25bbb8568fc3d376a6d9", }, { "Test Case 13", "00000000000000000000000000000000" + "00000000000000000000000000000000", "", "", "000000000000000000000000", "", "530f8afbc74536b9a963b4f1c4cb738b", }, { "Test Case 14", "00000000000000000000000000000000" + "00000000000000000000000000000000", "00000000000000000000000000000000", "", "000000000000000000000000", "cea7403d4d606b6e074ec5d3baf39d18", "d0d1c8a799996bf0265b98b5d48ab919", }, { "Test Case 15", "feffe9928665731c6d6a8f9467308308" + "feffe9928665731c6d6a8f9467308308", "d9313225f88406e5a55909c5aff5269a" + "86a7a9531534f7da2e4c303d8a318a72" + "1c3c0c95956809532fcf0e2449a6b525" + "b16aedf5aa0de657ba637b391aafd255", "", "cafebabefacedbaddecaf888", "522dc1f099567d07f47f37a32a84427d" + "643a8cdcbfe5c0c97598a2bd2555d1aa" + "8cb08e48590dbb3da7b08b1056828838" + "c5f61e6393ba7a0abcc9f662898015ad", "b094dac5d93471bdec1a502270e3cc6c", }, { "Test Case 16", "feffe9928665731c6d6a8f9467308308" + "feffe9928665731c6d6a8f9467308308", "d9313225f88406e5a55909c5aff5269a" + "86a7a9531534f7da2e4c303d8a318a72" + "1c3c0c95956809532fcf0e2449a6b525" + "b16aedf5aa0de657ba637b39", "feedfacedeadbeeffeedfacedeadbeef" + "abaddad2", "cafebabefacedbaddecaf888", "522dc1f099567d07f47f37a32a84427d" + "643a8cdcbfe5c0c97598a2bd2555d1aa" + "8cb08e48590dbb3da7b08b1056828838" + "c5f61e6393ba7a0abcc9f662", "76fc6ece0f4e1768cddf8853bb2d551b", }, { "Test Case 17", "feffe9928665731c6d6a8f9467308308" + "feffe9928665731c6d6a8f9467308308", "d9313225f88406e5a55909c5aff5269a" + "86a7a9531534f7da2e4c303d8a318a72" + "1c3c0c95956809532fcf0e2449a6b525" + "b16aedf5aa0de657ba637b39", "feedfacedeadbeeffeedfacedeadbeef" + "abaddad2", "cafebabefacedbad", "c3762df1ca787d32ae47c13bf19844cb" + "af1ae14d0b976afac52ff7d79bba9de0" + "feb582d33934a4f0954cc2363bc73f78" + "62ac430e64abe499f47c9b1f", "3a337dbf46a792c45e454913fe2ea8f2", }, { "Test Case 18", "feffe9928665731c6d6a8f9467308308" + "feffe9928665731c6d6a8f9467308308", "d9313225f88406e5a55909c5aff5269a" + "86a7a9531534f7da2e4c303d8a318a72" + "1c3c0c95956809532fcf0e2449a6b525" + "b16aedf5aa0de657ba637b39", "feedfacedeadbeeffeedfacedeadbeef" + "abaddad2", "9313225df88406e555909c5aff5269aa" + "6a7a9538534f7da1e4c303d2a318a728" + "c3c0c95156809539fcf0e2429a6b5254" + "16aedbf5a0de6a57a637b39b", "5a8def2f0c9e53f1f75d7853659e2a20" + "eeb2b22aafde6419a058ab4f6f746bf4" + "0fc0c3b780f244452da3ebf1c5d82cde" + "a2418997200ef82e44ae7e3f", "a44a8266ee1c8eb0c8b5d4cf5ae9f19a", }, }; public String getName() { return "GCM"; } public void performTest() throws Exception { for (int i = 0; i < TEST_VECTORS.length; ++i) { runTestCase(TEST_VECTORS[i]); } randomTests(); outputSizeTests(); } private void runTestCase(String[] testVector) throws InvalidCipherTextException { for (int macLength = 12; macLength <= 16; ++macLength) { runTestCase(testVector, macLength); } } private void runTestCase(String[] testVector, int macLength) throws InvalidCipherTextException { int pos = 0; String testName = testVector[pos++]; byte[] K = Hex.decode(testVector[pos++]); byte[] P = Hex.decode(testVector[pos++]); byte[] A = Hex.decode(testVector[pos++]); byte[] IV = Hex.decode(testVector[pos++]); byte[] C = Hex.decode(testVector[pos++]); // For short MAC, take leading bytes byte[] t = Hex.decode(testVector[pos++]); byte[] T = new byte[macLength]; System.arraycopy(t, 0, T, 0, T.length); // Default multiplier runTestCase(null, null, testName, K, IV, A, P, C, T); runTestCase(new BasicGCMMultiplier(), new BasicGCMMultiplier(), testName, K, IV, A, P, C, T); runTestCase(new Tables8kGCMMultiplier(), new Tables8kGCMMultiplier(), testName, K, IV, A, P, C, T); runTestCase(new Tables64kGCMMultiplier(), new Tables64kGCMMultiplier(), testName, K, IV, A, P, C, T); } private void runTestCase( GCMMultiplier encM, GCMMultiplier decM, String testName, byte[] K, byte[] IV, byte[] A, byte[] P, byte[] C, byte[] T) throws InvalidCipherTextException { byte[] fa = new byte[A.length / 2]; byte[] la = new byte[A.length - (A.length / 2)]; System.arraycopy(A, 0, fa, 0, fa.length); System.arraycopy(A, fa.length, la, 0, la.length); runTestCase(encM, decM, testName + " all initial associated data", K, IV, A, null, P, C, T); runTestCase(encM, decM, testName + " all subsequent associated data", K, IV, null, A, P, C, T); runTestCase(encM, decM, testName + " split associated data", K, IV, fa, la, P, C, T); } private void runTestCase( GCMMultiplier encM, GCMMultiplier decM, String testName, byte[] K, byte[] IV, byte[] A, byte[] SA, byte[] P, byte[] C, byte[] T) throws InvalidCipherTextException { AEADParameters parameters = new AEADParameters(new KeyParameter(K), T.length * 8, IV, A); GCMBlockCipher encCipher = initCipher(encM, true, parameters); GCMBlockCipher decCipher = initCipher(decM, false, parameters); checkTestCase(encCipher, decCipher, testName, SA, P, C, T); checkTestCase(encCipher, decCipher, testName + " (reused)", SA, P, C, T); // Key reuse AEADParameters keyReuseParams = new AEADParameters(null, parameters.getMacSize(), parameters.getNonce(), parameters.getAssociatedText()); encCipher.init(true, keyReuseParams); decCipher.init(false, keyReuseParams); checkTestCase(encCipher, decCipher, testName + " (key reuse)", SA, P, C, T); checkTestCase(encCipher, decCipher, testName + " (key reuse)", SA, P, C, T); } private GCMBlockCipher initCipher(GCMMultiplier m, boolean forEncryption, AEADParameters parameters) { GCMBlockCipher c = new GCMBlockCipher(new AESFastEngine(), m); c.init(forEncryption, parameters); return c; } private void checkTestCase( GCMBlockCipher encCipher, GCMBlockCipher decCipher, String testName, byte[] SA, byte[] P, byte[] C, byte[] T) throws InvalidCipherTextException { byte[] enc = new byte[encCipher.getOutputSize(P.length)]; if (SA != null) { encCipher.processAADBytes(SA, 0, SA.length); } int len = encCipher.processBytes(P, 0, P.length, enc, 0); len += encCipher.doFinal(enc, len); if (enc.length != len) { // System.out.println("" + enc.length + "/" + len); fail("encryption reported incorrect length: " + testName); } byte[] mac = encCipher.getMac(); byte[] data = new byte[P.length]; System.arraycopy(enc, 0, data, 0, data.length); byte[] tail = new byte[enc.length - P.length]; System.arraycopy(enc, P.length, tail, 0, tail.length); if (!areEqual(C, data)) { fail("incorrect encrypt in: " + testName); } if (!areEqual(T, mac)) { fail("getMac() returned wrong mac in: " + testName); } if (!areEqual(T, tail)) { fail("stream contained wrong mac in: " + testName); } byte[] dec = new byte[decCipher.getOutputSize(enc.length)]; if (SA != null) { decCipher.processAADBytes(SA, 0, SA.length); } len = decCipher.processBytes(enc, 0, enc.length, dec, 0); len += decCipher.doFinal(dec, len); mac = decCipher.getMac(); data = new byte[C.length]; System.arraycopy(dec, 0, data, 0, data.length); if (!areEqual(P, data)) { fail("incorrect decrypt in: " + testName); } } private void randomTests() throws InvalidCipherTextException { SecureRandom srng = new SecureRandom(); for (int i = 0; i < 10; ++i) { randomTest(srng, null); randomTest(srng, new BasicGCMMultiplier()); randomTest(srng, new Tables8kGCMMultiplier()); randomTest(srng, new Tables64kGCMMultiplier()); } } private void randomTest(SecureRandom srng, GCMMultiplier m) throws InvalidCipherTextException { int kLength = 16 + 8 * (Math.abs(srng.nextInt()) % 3); byte[] K = new byte[kLength]; srng.nextBytes(K); int pLength = srng.nextInt() >>> 16; byte[] P = new byte[pLength]; srng.nextBytes(P); int aLength = srng.nextInt() >>> 24; byte[] A = new byte[aLength]; srng.nextBytes(A); int saLength = srng.nextInt() >>> 24; byte[] SA = new byte[saLength]; srng.nextBytes(SA); int ivLength = 1 + (srng.nextInt() >>> 24); byte[] IV = new byte[ivLength]; srng.nextBytes(IV); GCMBlockCipher cipher = new GCMBlockCipher(new AESFastEngine(), m); AEADParameters parameters = new AEADParameters(new KeyParameter(K), 16 * 8, IV, A); cipher.init(true, parameters); byte[] C = new byte[cipher.getOutputSize(P.length)]; int predicted = cipher.getUpdateOutputSize(P.length); int split = nextInt(srng, SA.length + 1); cipher.processAADBytes(SA, 0, split); int len = cipher.processBytes(P, 0, P.length, C, 0); cipher.processAADBytes(SA, split, SA.length - split); if (predicted != len) { fail("encryption reported incorrect update length in randomised test"); } len += cipher.doFinal(C, len); if (C.length != len) { fail("encryption reported incorrect length in randomised test"); } byte[] encT = cipher.getMac(); byte[] tail = new byte[C.length - P.length]; System.arraycopy(C, P.length, tail, 0, tail.length); if (!areEqual(encT, tail)) { fail("stream contained wrong mac in randomised test"); } cipher.init(false, parameters); byte[] decP = new byte[cipher.getOutputSize(C.length)]; predicted = cipher.getUpdateOutputSize(C.length); split = nextInt(srng, SA.length + 1); cipher.processAADBytes(SA, 0, split); len = cipher.processBytes(C, 0, C.length, decP, 0); cipher.processAADBytes(SA, split, SA.length - split); if (predicted != len) { fail("decryption reported incorrect update length in randomised test"); } len += cipher.doFinal(decP, len); if (!areEqual(P, decP)) { fail("incorrect decrypt in randomised test"); } byte[] decT = cipher.getMac(); if (!areEqual(encT, decT)) { fail("decryption produced different mac from encryption"); } // // key reuse test // cipher.init(false, new AEADParameters(null, parameters.getMacSize(), parameters.getNonce(), parameters.getAssociatedText())); decP = new byte[cipher.getOutputSize(C.length)]; split = nextInt(srng, SA.length + 1); cipher.processAADBytes(SA, 0, split); len = cipher.processBytes(C, 0, C.length, decP, 0); cipher.processAADBytes(SA, split, SA.length - split); len += cipher.doFinal(decP, len); if (!areEqual(P, decP)) { fail("incorrect decrypt in randomised test"); } decT = cipher.getMac(); if (!areEqual(encT, decT)) { fail("decryption produced different mac from encryption"); } } private void outputSizeTests() { byte[] K = new byte[16]; byte[] A = null; byte[] IV = new byte[16]; GCMBlockCipher cipher = new GCMBlockCipher(new AESFastEngine(), new BasicGCMMultiplier()); AEADParameters parameters = new AEADParameters(new KeyParameter(K), 16 * 8, IV, A); cipher.init(true, parameters); if (cipher.getUpdateOutputSize(0) != 0) { fail("incorrect getUpdateOutputSize for initial 0 bytes encryption"); } if (cipher.getOutputSize(0) != 16) { fail("incorrect getOutputSize for initial 0 bytes encryption"); } cipher.init(false, parameters); if (cipher.getUpdateOutputSize(0) != 0) { fail("incorrect getUpdateOutputSize for initial 0 bytes decryption"); } // NOTE: 0 bytes would be truncated data, but we want it to fail in the doFinal, not here if (cipher.getOutputSize(0) != 0) { fail("fragile getOutputSize for initial 0 bytes decryption"); } if (cipher.getOutputSize(16) != 0) { fail("incorrect getOutputSize for initial MAC-size bytes decryption"); } } private static int nextInt(SecureRandom rand, int n) { if ((n & -n) == n) // i.e., n is a power of 2 { return (int)((n * (long)(rand.nextInt() >>> 1)) >> 31); } int bits, value; do { bits = rand.nextInt() >>> 1; value = bits % n; } while (bits - value + (n - 1) < 0); return value; } public static void main(String[] args) { runTest(new GCMTest()); } } bouncycastle-1.49.orig/test/src/org/bouncycastle/crypto/test/SerpentTest.java0000644000175000017500000001434700000000061027064 0ustar ebourgebourgpackage org.bouncycastle.crypto.test; import org.bouncycastle.crypto.engines.SerpentEngine; import org.bouncycastle.crypto.params.KeyParameter; import org.bouncycastle.util.encoders.Hex; import org.bouncycastle.util.test.SimpleTest; /** */ public class SerpentTest extends CipherTest { static SimpleTest[] tests = { new BlockCipherVectorTest(0, new SerpentEngine(), new KeyParameter(Hex.decode("0000000000000000000000000000000000000000000000000000000000000000")), "00000000000000000000000000000000", "8910494504181950f98dd998a82b6749"), new BlockCipherVectorTest(1, new SerpentEngine(), new KeyParameter(Hex.decode("00000000000000000000000000000000")), "80000000000000000000000000000000", "10b5ffb720b8cb9002a1142b0ba2e94a"), new BlockCipherVectorTest(2, new SerpentEngine(), new KeyParameter(Hex.decode("00000000000000000000000000000000")), "00000000008000000000000000000000", "4f057a42d8d5bd9746e434680ddcd5e5"), new BlockCipherVectorTest(3, new SerpentEngine(), new KeyParameter(Hex.decode("00000000000000000000000000000000")), "00000000000000000000400000000000", "99407bf8582ef12550886ef5b6f169b9"), new BlockCipherVectorTest(4, new SerpentEngine(), new KeyParameter(Hex.decode("000000000000000000000000000000000000000000000000")), "40000000000000000000000000000000", "d522a3b8d6d89d4d2a124fdd88f36896"), new BlockCipherVectorTest(5, new SerpentEngine(), new KeyParameter(Hex.decode("000000000000000000000000000000000000000000000000")), "00000000000200000000000000000000", "189b8ec3470085b3da97e82ca8964e32"), new BlockCipherVectorTest(6, new SerpentEngine(), new KeyParameter(Hex.decode("000000000000000000000000000000000000000000000000")), "00000000000000000000008000000000", "f77d868cf760b9143a89809510ccb099"), new BlockCipherVectorTest(7, new SerpentEngine(), new KeyParameter(Hex.decode("0000000000000000000000000000000000000000000000000000000000000000")), "08000000000000000000000000000000", "d43b7b981b829342fce0e3ec6f5f4c82"), new BlockCipherVectorTest(8, new SerpentEngine(), new KeyParameter(Hex.decode("0000000000000000000000000000000000000000000000000000000000000000")), "00000000000000000100000000000000", "0bf30e1a0c33ccf6d5293177886912a7"), new BlockCipherVectorTest(9, new SerpentEngine(), new KeyParameter(Hex.decode("0000000000000000000000000000000000000000000000000000000000000000")), "00000000000000000000000000000001", "6a7f3b805d2ddcba49b89770ade5e507"), new BlockCipherVectorTest(10, new SerpentEngine(), new KeyParameter(Hex.decode("80000000000000000000000000000000")), "00000000000000000000000000000000", "49afbfad9d5a34052cd8ffa5986bd2dd"), new BlockCipherVectorTest(11, new SerpentEngine(), new KeyParameter(Hex.decode("000000000000000000000000004000000000000000000000")), "00000000000000000000000000000000", "ba8829b1de058c4b48615d851fc74f17"), new BlockCipherVectorTest(12, new SerpentEngine(), new KeyParameter(Hex.decode("0000000000000000000000000000000000000000000000000000000100000000")), "00000000000000000000000000000000", "89f64377bf1e8a46c8247044e8056a98"), /* new BlockCipherMonteCarloTest(13, 10000, new SerpentEngine(), new KeyParameter(Hex.decode("47f5f881daab9b67b43bd1342e339c19")), "7a4f7db38c52a8b711b778a38d203b6b", "003380e19f10065740394f48e2fe80b7"), */ new BlockCipherMonteCarloTest(13, 100, new SerpentEngine(), new KeyParameter(Hex.decode("47f5f881daab9b67b43bd1342e339c19")), "7a4f7db38c52a8b711b778a38d203b6b", "4db75303d815c2f7cc6ca935d1c5a046"), /* new BlockCipherMonteCarloTest(14, 10000, new SerpentEngine(), new KeyParameter(Hex.decode("31fba879ebc5e80df35e6fa33eaf92d6")), "70a05e12f74589009692a337f53ff614", "afb5425426906db26b70bdf842ac5400"), */ new BlockCipherMonteCarloTest(14, 100, new SerpentEngine(), new KeyParameter(Hex.decode("31fba879ebc5e80df35e6fa33eaf92d6")), "70a05e12f74589009692a337f53ff614", "fc53a50f4d3bc9836001893d2f41742d"), /* new BlockCipherMonteCarloTest(15, 10000, new SerpentEngine(), new KeyParameter(Hex.decode("bde6dd392307984695aee80e574f9977caae9aa78eda53e8")), "9cc523d034a93740a0aa4e2054bb34d8", "1949d506ada7de1f1344986e8ea049b2"), */ new BlockCipherMonteCarloTest(15, 100, new SerpentEngine(), new KeyParameter(Hex.decode("bde6dd392307984695aee80e574f9977caae9aa78eda53e8")), "9cc523d034a93740a0aa4e2054bb34d8", "77117e6a9e80f40b2a36b7d755573c2d"), /* new BlockCipherMonteCarloTest(16, 10000, new SerpentEngine(), new KeyParameter(Hex.decode("60f6f8ad4290699dc50921a1bbcca92da914e7d9cf01a9317c79c0af8f2487a1")), "ee1a61106fae2d381d686cbf854bab65", "e57f45559027cb1f2ed9603d814e1c34"), */ new BlockCipherMonteCarloTest(16, 100, new SerpentEngine(), new KeyParameter(Hex.decode("60f6f8ad4290699dc50921a1bbcca92da914e7d9cf01a9317c79c0af8f2487a1")), "ee1a61106fae2d381d686cbf854bab65", "dcd7f13ea0dcdfd0139d1a42e2ffb84b") }; SerpentTest() { super(tests, new SerpentEngine(), new KeyParameter(new byte[32])); } public String getName() { return "Serpent"; } public static void main( String[] args) { runTest(new SerpentTest()); } } bouncycastle-1.49.orig/test/src/org/bouncycastle/crypto/test/GOST28147MacTest.java0000644000175000017500000000510310330633061027260 0ustar ebourgebourgpackage org.bouncycastle.crypto.test; import org.bouncycastle.crypto.Mac; import org.bouncycastle.crypto.engines.GOST28147Engine; import org.bouncycastle.crypto.macs.GOST28147Mac; import org.bouncycastle.crypto.params.KeyParameter; import org.bouncycastle.crypto.params.ParametersWithSBox; import org.bouncycastle.util.Arrays; import org.bouncycastle.util.encoders.Hex; import org.bouncycastle.util.test.SimpleTestResult; import org.bouncycastle.util.test.Test; import org.bouncycastle.util.test.TestResult; /** * GOST 28147 MAC tester */ public class GOST28147MacTest implements Test { // // these GOSTMac for testing. // static byte[] gkeyBytes1 = Hex.decode("6d145dc993f4019e104280df6fcd8cd8e01e101e4c113d7ec4f469ce6dcd9e49"); static byte[] gkeyBytes2 = Hex.decode("6d145dc993f4019e104280df6fcd8cd8e01e101e4c113d7ec4f469ce6dcd9e49"); static byte[] input3 = Hex.decode("7768617420646f2079612077616e7420666f72206e6f7468696e673f"); static byte[] input4 = Hex.decode("7768617420646f2079612077616e7420666f72206e6f7468696e673f"); static byte[] output7 = Hex.decode("93468a46"); static byte[] output8 = Hex.decode("93468a46"); public GOST28147MacTest() { } public TestResult perform() { // test1 Mac mac = new GOST28147Mac(); KeyParameter key = new KeyParameter(gkeyBytes1); mac.init(key); mac.update(input3, 0, input3.length); byte[] out = new byte[4]; mac.doFinal(out, 0); if (!Arrays.areEqual(out, output7)) { return new SimpleTestResult(false, getName() + ": Failed test 1 - expected " + new String(Hex.encode(output7)) + " got " + new String(Hex.encode(out))); } // test2 key = new KeyParameter(gkeyBytes2); ParametersWithSBox gparam = new ParametersWithSBox(key, GOST28147Engine.getSBox("E-A")); mac.init(gparam); mac.update(input4, 0, input4.length); out = new byte[4]; mac.doFinal(out, 0); if (!Arrays.areEqual(out, output8)) { return new SimpleTestResult(false, getName() + ": Failed test 2 - expected " + new String(Hex.encode(output8)) + " got " + new String(Hex.encode(out))); } return new SimpleTestResult(true, getName() + ": Okay"); } public String getName() { return "GOST28147Mac"; } public static void main( String[] args) { GOST28147MacTest test = new GOST28147MacTest(); TestResult result = test.perform(); System.out.println(result); } } bouncycastle-1.49.orig/test/src/org/bouncycastle/crypto/test/SHA1DigestTest.java0000644000175000017500000000173310330633061027316 0ustar ebourgebourgpackage org.bouncycastle.crypto.test; import org.bouncycastle.crypto.Digest; import org.bouncycastle.crypto.digests.SHA1Digest; /** * standard vector test for SHA-1 from "Handbook of Applied Cryptography", page 345. */ public class SHA1DigestTest extends DigestTest { private static String[] messages = { "", "a", "abc", "abcdefghijklmnopqrstuvwxyz" }; private static String[] digests = { "da39a3ee5e6b4b0d3255bfef95601890afd80709", "86f7e437faa5a7fce15d1ddcb9eaeaea377667b8", "a9993e364706816aba3e25717850c26c9cd0d89d", "32d10c7b8cf96570ca04ce37f2a19d84240d3a89" }; SHA1DigestTest() { super(new SHA1Digest(), messages, digests); } protected Digest cloneDigest(Digest digest) { return new SHA1Digest((SHA1Digest)digest); } public static void main( String[] args) { runTest(new SHA1DigestTest()); } } bouncycastle-1.49.orig/test/src/org/bouncycastle/crypto/test/SHA3DigestTest.java0000644000175000017500000003667512104600547027341 0ustar ebourgebourgpackage org.bouncycastle.crypto.test; import org.bouncycastle.crypto.Digest; import org.bouncycastle.crypto.Mac; import org.bouncycastle.crypto.digests.SHA3Digest; import org.bouncycastle.crypto.macs.HMac; import org.bouncycastle.crypto.params.KeyParameter; import org.bouncycastle.util.Arrays; import org.bouncycastle.util.encoders.Hex; import org.bouncycastle.util.test.SimpleTest; /** * SHA3 Digest Test */ public class SHA3DigestTest extends SimpleTest { final static String[] messages = { "", "54686520717569636b2062726f776e20666f78206a756d7073206f76657220746865206c617a7920646f67", "54686520717569636b2062726f776e20666f78206a756d7073206f76657220746865206c617a7920646f672e" }; final static String[] digests288 = { // the default settings "6753e3380c09e385d0339eb6b050a68f66cfd60a73476e6fd6adeb72f5edd7c6f04a5d01", // message[0] "0bbe6afae0d7e89054085c1cc47b1689772c89a41796891e197d1ca1b76f288154933ded", // message[1] "82558a209b960ddeb531e6dcb281885b2400ca160472462486e79f071e88a3330a8a303d", // message[2] "94049e1ad7ef5d5b0df2b880489e7ab09ec937c3bfc1b04470e503e1ac7b1133c18f86da", // 64k a-test "a9cb5a75b5b81b7528301e72553ed6770214fa963956e790528afe420de33c074e6f4220", // random alphabet test "eadaf5ba2ad6a2f6f338fce0e1efdad2a61bb38f6be6068b01093977acf99e97a5d5827c" // extremely long data test }; final static String[] digests224 = { "f71837502ba8e10837bdd8d365adb85591895602fc552b48b7390abd", "310aee6b30c47350576ac2873fa89fd190cdc488442f3ef654cf23fe", "c59d4eaeac728671c635ff645014e2afa935bebffdb5fbd207ffdeab", "f621e11c142fbf35fa8c22841c3a812ba1e0151be4f38d80b9f1ff53", "68b5fc8c87193155bba68a2485377e809ee4f81a85ef023b9e64add0", "c42e4aee858e1a8ad2976896b9d23dd187f64436ee15969afdbc68c5" }; final static String[] digests256 = { "c5d2460186f7233c927e7db2dcc703c0e500b653ca82273b7bfad8045d85a470", "4d741b6f1eb29cb2a9b9911c82f56fa8d73b04959d3d9d222895df6c0b28aa15", "578951e24efd62a3d63a86f7cd19aaa53c898fe287d2552133220370240b572d", "0047a916daa1f92130d870b542e22d3108444f5a7e4429f05762fb647e6ed9ed", "db368762253ede6d4f1db87e0b799b96e554eae005747a2ea687456ca8bcbd03", "5f313c39963dcf792b5470d4ade9f3a356a3e4021748690a958372e2b06f82a4" }; final static String[] digests384 = { "2c23146a63a29acf99e73b88f8c24eaa7dc60aa771780ccc006afbfa8fe2479b2dd2b21362337441ac12b515911957ff", "283990fa9d5fb731d786c5bbee94ea4db4910f18c62c03d173fc0a5e494422e8a0b3da7574dae7fa0baf005e504063b3", "9ad8e17325408eddb6edee6147f13856ad819bb7532668b605a24a2d958f88bd5c169e56dc4b2f89ffd325f6006d820b", "c704cfe7a1a53208ca9526cd24251e0acdc252ecd978eee05acd16425cfb404ea81f5a9e2e5e97784d63ee6a0618a398", "d4fe8586fd8f858dd2e4dee0bafc19b4c12b4e2a856054abc4b14927354931675cdcaf942267f204ea706c19f7beefc4", "9b7168b4494a80a86408e6b9dc4e5a1837c85dd8ff452ed410f2832959c08c8c0d040a892eb9a755776372d4a8732315" }; final static String[] digests512 = { "0eab42de4c3ceb9235fc91acffe746b29c29a8c366b7c60e4e67c466f36a4304c00fa9caf9d87976ba469bcbe06713b435f091ef2769fb160cdab33d3670680e", "d135bb84d0439dbac432247ee573a23ea7d3c9deb2a968eb31d47c4fb45f1ef4422d6c531b5b9bd6f449ebcc449ea94d0a8f05f62130fda612da53c79659f609", "ab7192d2b11f51c7dd744e7b3441febf397ca07bf812cceae122ca4ded6387889064f8db9230f173f6d1ab6e24b6e50f065b039f799f5592360a6558eb52d760", "34341ead153aa1d1fdcf6cf624c2b4f6894b6fd16dc38bd4ec971ac0385ad54fafcb2e0ed86a1e509456f4246fdcb02c3172824cd649d9ad54c51f7fb49ea67c", "dc44d4f4d36b07ab5fc04016cbe53548e5a7778671c58a43cb379fd00c06719b8073141fc22191ffc3db5f8b8983ae8341fa37f18c1c969664393aa5ceade64e", "3e122edaf37398231cfaca4c7c216c9d66d5b899ec1d7ac617c40c7261906a45fc01617a021e5da3bd8d4182695b5cb785a28237cbb167590e34718e56d8aab8" }; // test vectors from http://www.di-mgt.com.au/hmac_sha3_testvectors.html final static byte[][] macKeys = { Hex.decode("0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b"), Hex.decode("4a656665"), Hex.decode("aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa"), Hex.decode("0102030405060708090a0b0c0d0e0f10111213141516171819"), Hex.decode("aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa" + "aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa" + "aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa" + "aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa" + "aaaaaa"), Hex.decode("aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa" + "aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa" + "aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa" + "aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa" + "aaaaaa"), Hex.decode("aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa" + "aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa" + "aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa" + "aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa" + "aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa") }; final static String[] macData = { "4869205468657265", "7768617420646f2079612077616e7420666f72206e6f7468696e673f", "dddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddd" + "dddddddddddddddddddddddddddddddddddd", "cdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcd" + "cdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcd", "54657374205573696e67204c6172676572205468616e20426c6f636b2d53697a" + "65204b6579202d2048617368204b6579204669727374", "5468697320697320612074657374207573696e672061206c6172676572207468" + "616e20626c6f636b2d73697a65206b657920616e642061206c61726765722074" + "68616e20626c6f636b2d73697a6520646174612e20546865206b6579206e6565" + "647320746f20626520686173686564206265666f7265206265696e6720757365" + "642062792074686520484d414320616c676f726974686d2e", "5468697320697320612074657374207573696e672061206c6172676572207468" + "616e20626c6f636b2d73697a65206b657920616e642061206c61726765722074" + "68616e20626c6f636b2d73697a6520646174612e20546865206b6579206e6565" + "647320746f20626520686173686564206265666f7265206265696e6720757365\n" + "642062792074686520484d414320616c676f726974686d2e" }; final static String[] mac224 = { "b73d595a2ba9af815e9f2b4e53e78581ebd34a80b3bbaac4e702c4cc", "e824fec96c074f22f99235bb942da1982664ab692ca8501053cbd414", "770df38c99d6e2bacd68056dcfe07d4c89ae20b2686a6185e1faa449", "305a8f2dfb94bad28861a03cbc4d590febe775c58cb4961c28428a0b", "e7a52dfa45f95a217c100066b239aa8ad519be9b35d667268b1b57ff", "ba13009405a929f398b348885caa5419191bb948ada32194afc84104", "92649468be236c3c72c189909c063b13f994be05749dc91310db639e" }; final static String[] mac256 = { "9663d10c73ee294054dc9faf95647cb99731d12210ff7075fb3d3395abfb9821", "aa9aed448c7abc8b5e326ffa6a01cdedf7b4b831881468c044ba8dd4566369a1", "95f43e50f8df80a21977d51a8db3ba572dcd71db24687e6f86f47c1139b26260", "6331ba9b4af5804a68725b3663eb74814494b63c6093e35fb320a85d507936fd", "b4d0cdee7ec2ba81a88b86918958312300a15622377929a054a9ce3ae1fac2b6", "1fdc8cb4e27d07c10d897dec39c217792a6e64fa9c63a77ce42ad106ef284e02", "fdaa10a0299aecff9bb411cf2d7748a4022e4a26be3fb5b11b33d8c2b7ef5484" }; final static String[] mac384 = { "892dfdf5d51e4679bf320cd16d4c9dc6f749744608e003add7fba894acff87361efa4e5799be06b6461f43b60ae97048", "5af5c9a77a23a6a93d80649e562ab77f4f3552e3c5caffd93bdf8b3cfc6920e3023fc26775d9df1f3c94613146ad2c9d", "4243c29f2201992ff96441e3b91ff81d8c601d706fbc83252684a4bc51101ca9b2c06ddd03677303c502ac5331752a3c", "b730724d3d4090cda1be799f63acbbe389fef7792fc18676fa5453aab398664650ed029c3498bbe8056f06c658e1e693", "d62482ef601d7847439b55236e9679388ffcd53c62cd126f39be6ea63de762e26cd5974cb9a8de401b786b5555040f6f", "4860ea191ac34994cf88957afe5a836ef36e4cc1a66d75bf77defb7576122d75f60660e4cf731c6effac06402787e2b9", "fe9357e3cfa538eb0373a2ce8f1e26ad6590afdaf266f1300522e8896d27e73f654d0631c8fa598d4bb82af6b744f4f5" }; final static String[] mac512 = { "8852c63be8cfc21541a4ee5e5a9a852fc2f7a9adec2ff3a13718ab4ed81aaea0b87b7eb397323548e261a64e7fc75198f6663a11b22cd957f7c8ec858a1c7755", "c2962e5bbe1238007852f79d814dbbecd4682e6f097d37a363587c03bfa2eb0859d8d9c701e04cececfd3dd7bfd438f20b8b648e01bf8c11d26824b96cebbdcb", "eb0ed9580e0ec11fc66cbb646b1be904eaff6da4556d9334f65ee4b2c85739157bae9027c51505e49d1bb81cfa55e6822db55262d5a252c088a29a5e95b84a66", "b46193bb59f4f696bf702597616da91e2a4558a593f4b015e69141ba81e1e50ea580834c2b87f87baa25a3a03bfc9bb389847f2dc820beae69d30c4bb75369cb", "d05888a6ebf8460423ea7bc85ea4ffda847b32df32291d2ce115fd187707325c7ce4f71880d91008084ce24a38795d20e6a28328a0f0712dc38253370da3ebb5", "2c6b9748d35c4c8db0b4407dd2ed2381f133bdbd1dfaa69e30051eb6badfcca64299b88ae05fdbd3dd3dd7fe627e42e39e48b0fe8c7f1e85f2dbd52c2d753572", "6adc502f14e27812402fc81a807b28bf8a53c87bea7a1df6256bf66f5de1a4cb741407ad15ab8abc136846057f881969fbb159c321c904bfb557b77afb7778c8" }; final static KeyParameter truncKey = new KeyParameter(Hex.decode("0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c")); final static byte[] truncData = Hex.decode("546573742057697468205472756e636174696f6e"); final static byte[] trunc224 = Hex.decode("f52bbcfd654264e7133085c5e69b72c3"); final static byte[] trunc256 = Hex.decode("745e7e687f8335280d54202ef13cecc6"); final static byte[] trunc384 = Hex.decode("fa9aea2bc1e181e47cbb8c3df243814d"); final static byte[] trunc512 = Hex.decode("04c929fead434bba190dacfa554ce3f5"); final static byte[] xtremeData = Hex.decode("61626364656667686263646566676869636465666768696a6465666768696a6b65666768696a6b6c666768696a6b6c6d6768696a6b6c6d6e68696a6b6c6d6e6f"); SHA3DigestTest() { } public String getName() { return "SHA3"; } private void testDigest(Digest digest, String[] expected) { byte[] hash = new byte[digest.getDigestSize()]; for (int i = 0; i != messages.length; i++) { if (messages.length != 0) { byte[] data = Hex.decode(messages[i]); digest.update(data, 0, data.length); } digest.doFinal(hash, 0); if (!Arrays.areEqual(Hex.decode(expected[i]), hash)) { fail("sha3 mismatch on " + digest.getAlgorithmName() + " index " + i); } } byte[] k64 = new byte[1024 * 64]; for (int i = 0; i != k64.length; i++) { k64[i] = (byte)'a'; } digest.update(k64, 0, k64.length); digest.doFinal(hash, 0); if (!Arrays.areEqual(Hex.decode(expected[messages.length]), hash)) { fail("sha3 mismatch on " + digest.getAlgorithmName() + " 64k a"); } for (int i = 0; i != k64.length; i++) { digest.update((byte)'a'); } digest.doFinal(hash, 0); if (!Arrays.areEqual(Hex.decode(expected[messages.length]), hash)) { fail("sha3 mismatch on " + digest.getAlgorithmName() + " 64k a single"); } for (int i = 0; i != k64.length; i++) { k64[i] = (byte)('a' + (i % 26)); } digest.update(k64, 0, k64.length); digest.doFinal(hash, 0); if (!Arrays.areEqual(Hex.decode(expected[messages.length + 1]), hash)) { fail("sha3 mismatch on " + digest.getAlgorithmName() + " 64k alpha"); } for (int i = 0; i != 64; i++) { digest.update(k64[i * 1024]); digest.update(k64, i * 1024 + 1, 1023); } digest.doFinal(hash, 0); if (!Arrays.areEqual(Hex.decode(expected[messages.length + 1]), hash)) { fail("sha3 mismatch on " + digest.getAlgorithmName() + " 64k chunked alpha"); } testDigestDoFinal(digest); // // extremely long data test // // System.out.println("Starting very long"); // for (int i = 0; i != 16384; i++) // { // for (int j = 0; j != 1024; j++) // { // digest.update(xtremeData, 0, xtremeData.length); // } // } // // digest.doFinal(hash, 0); // // if (!Arrays.areEqual(Hex.decode(expected[messages.length + 2]), hash)) // { // fail("sha3 mismatch on " + digest.getAlgorithmName() + " extreme data test"); // } // System.out.println("Done"); } private void testDigestDoFinal(Digest digest) { byte[] hash = new byte[digest.getDigestSize()]; digest.doFinal(hash, 0); for (int i = 0; i <= digest.getDigestSize(); ++i) { byte[] cmp = new byte[2 * digest.getDigestSize()]; System.arraycopy(hash, 0, cmp, i, hash.length); byte[] buf = new byte[2 * digest.getDigestSize()]; digest.doFinal(buf, i); if (!Arrays.areEqual(cmp, buf)) { fail("sha3 offset doFinal on " + digest.getAlgorithmName()); } } } private void testMac(Digest digest, byte[][] keys, String[] data, String[] expected, byte[] truncExpected) { Mac mac = new HMac(digest); for (int i = 0; i != keys.length; i++) { mac.init(new KeyParameter(keys[i])); byte[] mData = Hex.decode(data[i]); mac.update(mData, 0, mData.length); byte[] macV = new byte[mac.getMacSize()]; mac.doFinal(macV, 0); if (!Arrays.areEqual(Hex.decode(expected[i]), macV)) { fail("sha3 HMAC mismatch on " + digest.getAlgorithmName()); } } mac = new HMac(digest); mac.init(truncKey); mac.update(truncData, 0, truncData.length); byte[] macV = new byte[mac.getMacSize()]; mac.doFinal(macV, 0); for (int i = 0; i != truncExpected.length; i++) { if (macV[i] != truncExpected[i]) { fail("mismatch on truncated HMAC for " + digest.getAlgorithmName()); } } } public void performTest() { testDigest(new SHA3Digest(), digests288); testDigest(new SHA3Digest(224), digests224); testDigest(new SHA3Digest(256), digests256); testDigest(new SHA3Digest(384), digests384); testDigest(new SHA3Digest(512), digests512); testMac(new SHA3Digest(224), macKeys, macData, mac224, trunc224); testMac(new SHA3Digest(256), macKeys, macData, mac256, trunc256); testMac(new SHA3Digest(384), macKeys, macData, mac384, trunc384); testMac(new SHA3Digest(512), macKeys, macData, mac512, trunc512); } protected Digest cloneDigest(Digest digest) { return new SHA3Digest((SHA3Digest)digest); } public static void main( String[] args) { runTest(new SHA3DigestTest()); } } bouncycastle-1.49.orig/test/src/org/bouncycastle/crypto/test/RSADigestSignerTest.java0000644000175000017500000000564010762773275030445 0ustar ebourgebourgpackage org.bouncycastle.crypto.test; import org.bouncycastle.crypto.digests.SHA1Digest; import org.bouncycastle.crypto.params.RSAKeyParameters; import org.bouncycastle.crypto.params.RSAPrivateCrtKeyParameters; import org.bouncycastle.crypto.signers.RSADigestSigner; import org.bouncycastle.util.encoders.Base64; import org.bouncycastle.util.test.SimpleTest; import java.math.BigInteger; public class RSADigestSignerTest extends SimpleTest { public String getName() { return "RSADigestSigner"; } public void performTest() throws Exception { BigInteger rsaPubMod = new BigInteger(Base64.decode("AIASoe2PQb1IP7bTyC9usjHP7FvnUMVpKW49iuFtrw/dMpYlsMMoIU2jupfifDpdFxIktSB4P+6Ymg5WjvHKTIrvQ7SR4zV4jaPTu56Ys0pZ9EDA6gb3HLjtU+8Bb1mfWM+yjKxcPDuFjwEtjGlPHg1Vq+CA9HNcMSKNn2+tW6qt")); BigInteger rsaPubExp = new BigInteger(Base64.decode("EQ==")); BigInteger rsaPrivMod = new BigInteger(Base64.decode("AIASoe2PQb1IP7bTyC9usjHP7FvnUMVpKW49iuFtrw/dMpYlsMMoIU2jupfifDpdFxIktSB4P+6Ymg5WjvHKTIrvQ7SR4zV4jaPTu56Ys0pZ9EDA6gb3HLjtU+8Bb1mfWM+yjKxcPDuFjwEtjGlPHg1Vq+CA9HNcMSKNn2+tW6qt")); BigInteger rsaPrivDP = new BigInteger(Base64.decode("JXzfzG5v+HtLJIZqYMUefJfFLu8DPuJGaLD6lI3cZ0babWZ/oPGoJa5iHpX4Ul/7l3s1PFsuy1GhzCdOdlfRcQ==")); BigInteger rsaPrivDQ = new BigInteger(Base64.decode("YNdJhw3cn0gBoVmMIFRZzflPDNthBiWy/dUMSRfJCxoZjSnr1gysZHK01HteV1YYNGcwPdr3j4FbOfri5c6DUQ==")); BigInteger rsaPrivExp = new BigInteger(Base64.decode("DxFAOhDajr00rBjqX+7nyZ/9sHWRCCp9WEN5wCsFiWVRPtdB+NeLcou7mWXwf1Y+8xNgmmh//fPV45G2dsyBeZbXeJwB7bzx9NMEAfedchyOwjR8PYdjK3NpTLKtZlEJ6Jkh4QihrXpZMO4fKZWUm9bid3+lmiq43FwW+Hof8/E=")); BigInteger rsaPrivP = new BigInteger(Base64.decode("AJ9StyTVW+AL/1s7RBtFwZGFBgd3zctBqzzwKPda6LbtIFDznmwDCqAlIQH9X14X7UPLokCDhuAa76OnDXb1OiE=")); BigInteger rsaPrivQ = new BigInteger(Base64.decode("AM3JfD79dNJ5A3beScSzPtWxx/tSLi0QHFtkuhtSizeXdkv5FSba7lVzwEOGKHmW829bRoNxThDy4ds1IihW1w0=")); BigInteger rsaPrivQinv = new BigInteger(Base64.decode("Lt0g7wrsNsQxuDdB8q/rH8fSFeBXMGLtCIqfOec1j7FEIuYA/ACiRDgXkHa0WgN7nLXSjHoy630wC5Toq8vvUg==")); RSAKeyParameters rsaPublic = new RSAKeyParameters(false, rsaPubMod, rsaPubExp); RSAPrivateCrtKeyParameters rsaPrivate = new RSAPrivateCrtKeyParameters(rsaPrivMod, rsaPubExp, rsaPrivExp, rsaPrivP, rsaPrivQ, rsaPrivDP, rsaPrivDQ, rsaPrivQinv); byte[] msg = new byte[] { 1, 6, 3, 32, 7, 43, 2, 5, 7, 78, 4, 23 }; RSADigestSigner signer = new RSADigestSigner(new SHA1Digest()); signer.init(true, rsaPrivate); signer.update(msg, 0, msg.length); byte[] sig = signer.generateSignature(); signer.init(false,rsaPublic); signer.update(msg, 0, msg.length); if (!signer.verifySignature(sig)) { fail("RSA IDigest Signer failed."); } } public static void main(String[] args) { runTest(new RSADigestSignerTest()); } } bouncycastle-1.49.orig/test/src/org/bouncycastle/crypto/test/CamelliaTest.java0000644000175000017500000000654110525306762027206 0ustar ebourgebourgpackage org.bouncycastle.crypto.test; import org.bouncycastle.crypto.engines.CamelliaEngine; import org.bouncycastle.crypto.params.KeyParameter; import org.bouncycastle.util.encoders.Hex; import org.bouncycastle.util.test.SimpleTest; import org.bouncycastle.util.test.TestResult; /** * Camellia tester - vectors from https://www.cosic.esat.kuleuven.be/nessie/testvectors/ and RFC 3713 */ public class CamelliaTest extends CipherTest { static SimpleTest[] tests = { new BlockCipherVectorTest(0, new CamelliaEngine(), new KeyParameter(Hex.decode("00000000000000000000000000000000")), "80000000000000000000000000000000", "07923A39EB0A817D1C4D87BDB82D1F1C"), new BlockCipherVectorTest(1, new CamelliaEngine(), new KeyParameter(Hex.decode("80000000000000000000000000000000")), "00000000000000000000000000000000", "6C227F749319A3AA7DA235A9BBA05A2C"), new BlockCipherVectorTest(2, new CamelliaEngine(), new KeyParameter(Hex.decode("0123456789abcdeffedcba9876543210")), "0123456789abcdeffedcba9876543210", "67673138549669730857065648eabe43"), // // 192 bit // new BlockCipherVectorTest(3, new CamelliaEngine(), new KeyParameter(Hex.decode("0123456789abcdeffedcba98765432100011223344556677")), "0123456789abcdeffedcba9876543210", "b4993401b3e996f84ee5cee7d79b09b9"), new BlockCipherVectorTest(4, new CamelliaEngine(), new KeyParameter(Hex.decode("000000000000000000000000000000000000000000000000")), "00040000000000000000000000000000", "9BCA6C88B928C1B0F57F99866583A9BC"), new BlockCipherVectorTest(5, new CamelliaEngine(), new KeyParameter(Hex.decode("949494949494949494949494949494949494949494949494")), "636EB22D84B006381235641BCF0308D2", "94949494949494949494949494949494"), // // 256 bit // new BlockCipherVectorTest(6, new CamelliaEngine(), new KeyParameter(Hex.decode("0123456789abcdeffedcba987654321000112233445566778899aabbccddeeff")), "0123456789abcdeffedcba9876543210", "9acc237dff16d76c20ef7c919e3a7509"), new BlockCipherVectorTest(7, new CamelliaEngine(), new KeyParameter(Hex.decode("4A4A4A4A4A4A4A4A4A4A4A4A4A4A4A4A4A4A4A4A4A4A4A4A4A4A4A4A4A4A4A4A")), "057764FE3A500EDBD988C5C3B56CBA9A", "4A4A4A4A4A4A4A4A4A4A4A4A4A4A4A4A"), new BlockCipherVectorTest(8, new CamelliaEngine(), new KeyParameter(Hex.decode("0303030303030303030303030303030303030303030303030303030303030303")), "7968B08ABA92193F2295121EF8D75C8A", "03030303030303030303030303030303"), }; CamelliaTest() { super(tests, new CamelliaEngine(), new KeyParameter(new byte[32])); } public String getName() { return "Camellia"; } public static void main( String[] args) { CamelliaTest test = new CamelliaTest(); TestResult result = test.perform(); System.out.println(result); } } bouncycastle-1.49.orig/test/src/org/bouncycastle/crypto/test/PSSBlindTest.java0000644000175000017500000006121211165246650027111 0ustar ebourgebourgpackage org.bouncycastle.crypto.test; import org.bouncycastle.crypto.AsymmetricCipherKeyPair; import org.bouncycastle.crypto.digests.SHA1Digest; import org.bouncycastle.crypto.engines.RSABlindingEngine; import org.bouncycastle.crypto.engines.RSAEngine; import org.bouncycastle.crypto.generators.RSABlindingFactorGenerator; import org.bouncycastle.crypto.generators.RSAKeyPairGenerator; import org.bouncycastle.crypto.params.ParametersWithRandom; import org.bouncycastle.crypto.params.RSABlindingParameters; import org.bouncycastle.crypto.params.RSAKeyGenerationParameters; import org.bouncycastle.crypto.params.RSAKeyParameters; import org.bouncycastle.crypto.params.RSAPrivateCrtKeyParameters; import org.bouncycastle.crypto.signers.PSSSigner; import org.bouncycastle.util.encoders.Hex; import org.bouncycastle.util.test.SimpleTest; import java.math.BigInteger; import java.security.SecureRandom; /* * RSA PSS test vectors for PKCS#1 V2.1 with blinding */ public class PSSBlindTest extends SimpleTest { private final int DATA_LENGTH = 1000; private final int NUM_TESTS = 50; private final int NUM_TESTS_WITH_KEY_GENERATION = 10; private class FixedRandom extends SecureRandom { byte[] vals; FixedRandom( byte[] vals) { this.vals = vals; } public void nextBytes( byte[] bytes) { System.arraycopy(vals, 0, bytes, 0, vals.length); } } // // Example 1: A 1024-bit RSA keypair // private RSAKeyParameters pub1 = new RSAKeyParameters(false, new BigInteger("a56e4a0e701017589a5187dc7ea841d156f2ec0e36ad52a44dfeb1e61f7ad991d8c51056ffedb162b4c0f283a12a88a394dff526ab7291cbb307ceabfce0b1dfd5cd9508096d5b2b8b6df5d671ef6377c0921cb23c270a70e2598e6ff89d19f105acc2d3f0cb35f29280e1386b6f64c4ef22e1e1f20d0ce8cffb2249bd9a2137",16), new BigInteger("010001",16)); private RSAKeyParameters prv1 = new RSAPrivateCrtKeyParameters( new BigInteger("a56e4a0e701017589a5187dc7ea841d156f2ec0e36ad52a44dfeb1e61f7ad991d8c51056ffedb162b4c0f283a12a88a394dff526ab7291cbb307ceabfce0b1dfd5cd9508096d5b2b8b6df5d671ef6377c0921cb23c270a70e2598e6ff89d19f105acc2d3f0cb35f29280e1386b6f64c4ef22e1e1f20d0ce8cffb2249bd9a2137",16), new BigInteger("010001",16), new BigInteger("33a5042a90b27d4f5451ca9bbbd0b44771a101af884340aef9885f2a4bbe92e894a724ac3c568c8f97853ad07c0266c8c6a3ca0929f1e8f11231884429fc4d9ae55fee896a10ce707c3ed7e734e44727a39574501a532683109c2abacaba283c31b4bd2f53c3ee37e352cee34f9e503bd80c0622ad79c6dcee883547c6a3b325",16), new BigInteger("e7e8942720a877517273a356053ea2a1bc0c94aa72d55c6e86296b2dfc967948c0a72cbccca7eacb35706e09a1df55a1535bd9b3cc34160b3b6dcd3eda8e6443",16), new BigInteger("b69dca1cf7d4d7ec81e75b90fcca874abcde123fd2700180aa90479b6e48de8d67ed24f9f19d85ba275874f542cd20dc723e6963364a1f9425452b269a6799fd",16), new BigInteger("28fa13938655be1f8a159cbaca5a72ea190c30089e19cd274a556f36c4f6e19f554b34c077790427bbdd8dd3ede2448328f385d81b30e8e43b2fffa027861979",16), new BigInteger("1a8b38f398fa712049898d7fb79ee0a77668791299cdfa09efc0e507acb21ed74301ef5bfd48be455eaeb6e1678255827580a8e4e8e14151d1510a82a3f2e729",16), new BigInteger("27156aba4126d24a81f3a528cbfb27f56886f840a9f6e86e17a44b94fe9319584b8e22fdde1e5a2e3bd8aa5ba8d8584194eb2190acf832b847f13a3d24a79f4d",16)); // PSSExample1.1 private byte[] msg1a = Hex.decode("cdc87da223d786df3b45e0bbbc721326d1ee2af806cc315475cc6f0d9c66e1b62371d45ce2392e1ac92844c310102f156a0d8d52c1f4c40ba3aa65095786cb769757a6563ba958fed0bcc984e8b517a3d5f515b23b8a41e74aa867693f90dfb061a6e86dfaaee64472c00e5f20945729cbebe77f06ce78e08f4098fba41f9d6193c0317e8b60d4b6084acb42d29e3808a3bc372d85e331170fcbf7cc72d0b71c296648b3a4d10f416295d0807aa625cab2744fd9ea8fd223c42537029828bd16be02546f130fd2e33b936d2676e08aed1b73318b750a0167d0"); private byte[] slt1a = Hex.decode("dee959c7e06411361420ff80185ed57f3e6776af"); private byte[] sig1a = Hex.decode("9074308fb598e9701b2294388e52f971faac2b60a5145af185df5287b5ed2887e57ce7fd44dc8634e407c8e0e4360bc226f3ec227f9d9e54638e8d31f5051215df6ebb9c2f9579aa77598a38f914b5b9c1bd83c4e2f9f382a0d0aa3542ffee65984a601bc69eb28deb27dca12c82c2d4c3f66cd500f1ff2b994d8a4e30cbb33c"); // PSSExample1.2 private byte[] msg1b = Hex.decode("851384cdfe819c22ed6c4ccb30daeb5cf059bc8e1166b7e3530c4c233e2b5f8f71a1cca582d43ecc72b1bca16dfc7013226b9e"); private byte[] slt1b = Hex.decode("ef2869fa40c346cb183dab3d7bffc98fd56df42d"); private byte[] sig1b = Hex.decode("3ef7f46e831bf92b32274142a585ffcefbdca7b32ae90d10fb0f0c729984f04ef29a9df0780775ce43739b97838390db0a5505e63de927028d9d29b219ca2c4517832558a55d694a6d25b9dab66003c4cccd907802193be5170d26147d37b93590241be51c25055f47ef62752cfbe21418fafe98c22c4d4d47724fdb5669e843"); // // Example 2: A 1025-bit RSA keypair // private RSAKeyParameters pub2 = new RSAKeyParameters(false, new BigInteger("01d40c1bcf97a68ae7cdbd8a7bf3e34fa19dcca4ef75a47454375f94514d88fed006fb829f8419ff87d6315da68a1ff3a0938e9abb3464011c303ad99199cf0c7c7a8b477dce829e8844f625b115e5e9c4a59cf8f8113b6834336a2fd2689b472cbb5e5cabe674350c59b6c17e176874fb42f8fc3d176a017edc61fd326c4b33c9", 16), new BigInteger("010001", 16)); private RSAKeyParameters prv2 = new RSAPrivateCrtKeyParameters( new BigInteger("01d40c1bcf97a68ae7cdbd8a7bf3e34fa19dcca4ef75a47454375f94514d88fed006fb829f8419ff87d6315da68a1ff3a0938e9abb3464011c303ad99199cf0c7c7a8b477dce829e8844f625b115e5e9c4a59cf8f8113b6834336a2fd2689b472cbb5e5cabe674350c59b6c17e176874fb42f8fc3d176a017edc61fd326c4b33c9", 16), new BigInteger("010001", 16), new BigInteger("027d147e4673057377fd1ea201565772176a7dc38358d376045685a2e787c23c15576bc16b9f444402d6bfc5d98a3e88ea13ef67c353eca0c0ddba9255bd7b8bb50a644afdfd1dd51695b252d22e7318d1b6687a1c10ff75545f3db0fe602d5f2b7f294e3601eab7b9d1cecd767f64692e3e536ca2846cb0c2dd486a39fa75b1", 16), new BigInteger("016601e926a0f8c9e26ecab769ea65a5e7c52cc9e080ef519457c644da6891c5a104d3ea7955929a22e7c68a7af9fcad777c3ccc2b9e3d3650bce404399b7e59d1", 16), new BigInteger("014eafa1d4d0184da7e31f877d1281ddda625664869e8379e67ad3b75eae74a580e9827abd6eb7a002cb5411f5266797768fb8e95ae40e3e8a01f35ff89e56c079", 16), new BigInteger("e247cce504939b8f0a36090de200938755e2444b29539a7da7a902f6056835c0db7b52559497cfe2c61a8086d0213c472c78851800b171f6401de2e9c2756f31", 16), new BigInteger("b12fba757855e586e46f64c38a70c68b3f548d93d787b399999d4c8f0bbd2581c21e19ed0018a6d5d3df86424b3abcad40199d31495b61309f27c1bf55d487c1", 16), new BigInteger("564b1e1fa003bda91e89090425aac05b91da9ee25061e7628d5f51304a84992fdc33762bd378a59f030a334d532bd0dae8f298ea9ed844636ad5fb8cbdc03cad", 16)); // PSS Example 2.1 private byte[] msg2a = Hex.decode("daba032066263faedb659848115278a52c44faa3a76f37515ed336321072c40a9d9b53bc05014078adf520875146aae70ff060226dcb7b1f1fc27e9360"); private byte[] slt2a = Hex.decode("57bf160bcb02bb1dc7280cf0458530b7d2832ff7"); private byte[] sig2a = Hex.decode("014c5ba5338328ccc6e7a90bf1c0ab3fd606ff4796d3c12e4b639ed9136a5fec6c16d8884bdd99cfdc521456b0742b736868cf90de099adb8d5ffd1deff39ba4007ab746cefdb22d7df0e225f54627dc65466131721b90af445363a8358b9f607642f78fab0ab0f43b7168d64bae70d8827848d8ef1e421c5754ddf42c2589b5b3"); // PSS Example 2.2 private byte[] msg2b = Hex.decode("e4f8601a8a6da1be34447c0959c058570c3668cfd51dd5f9ccd6ad4411fe8213486d78a6c49f93efc2ca2288cebc2b9b60bd04b1e220d86e3d4848d709d032d1e8c6a070c6af9a499fcf95354b14ba6127c739de1bb0fd16431e46938aec0cf8ad9eb72e832a7035de9b7807bdc0ed8b68eb0f5ac2216be40ce920c0db0eddd3860ed788efaccaca502d8f2bd6d1a7c1f41ff46f1681c8f1f818e9c4f6d91a0c7803ccc63d76a6544d843e084e363b8acc55aa531733edb5dee5b5196e9f03e8b731b3776428d9e457fe3fbcb3db7274442d785890e9cb0854b6444dace791d7273de1889719338a77fe"); private byte[] slt2b = Hex.decode("7f6dd359e604e60870e898e47b19bf2e5a7b2a90"); private byte[] sig2b = Hex.decode("010991656cca182b7f29d2dbc007e7ae0fec158eb6759cb9c45c5ff87c7635dd46d150882f4de1e9ae65e7f7d9018f6836954a47c0a81a8a6b6f83f2944d6081b1aa7c759b254b2c34b691da67cc0226e20b2f18b42212761dcd4b908a62b371b5918c5742af4b537e296917674fb914194761621cc19a41f6fb953fbcbb649dea"); // // Example 4: A 1027-bit RSA key pair // private RSAKeyParameters pub4 = new RSAKeyParameters(false, new BigInteger("054adb7886447efe6f57e0368f06cf52b0a3370760d161cef126b91be7f89c421b62a6ec1da3c311d75ed50e0ab5fff3fd338acc3aa8a4e77ee26369acb81ba900fa83f5300cf9bb6c53ad1dc8a178b815db4235a9a9da0c06de4e615ea1277ce559e9c108de58c14a81aa77f5a6f8d1335494498848c8b95940740be7bf7c3705", 16), new BigInteger("010001", 16)); private RSAKeyParameters prv4 = new RSAPrivateCrtKeyParameters( new BigInteger("054adb7886447efe6f57e0368f06cf52b0a3370760d161cef126b91be7f89c421b62a6ec1da3c311d75ed50e0ab5fff3fd338acc3aa8a4e77ee26369acb81ba900fa83f5300cf9bb6c53ad1dc8a178b815db4235a9a9da0c06de4e615ea1277ce559e9c108de58c14a81aa77f5a6f8d1335494498848c8b95940740be7bf7c3705", 16), new BigInteger("010001", 16), new BigInteger("fa041f8cd9697ceed38ec8caa275523b4dd72b09a301d3541d72f5d31c05cbce2d6983b36183af10690bd46c46131e35789431a556771dd0049b57461bf060c1f68472e8a67c25f357e5b6b4738fa541a730346b4a07649a2dfa806a69c975b6aba64678acc7f5913e89c622f2d8abb1e3e32554e39df94ba60c002e387d9011", 16), new BigInteger("029232336d2838945dba9dd7723f4e624a05f7375b927a87abe6a893a1658fd49f47f6c7b0fa596c65fa68a23f0ab432962d18d4343bd6fd671a5ea8d148413995", 16), new BigInteger("020ef5efe7c5394aed2272f7e81a74f4c02d145894cb1b3cab23a9a0710a2afc7e3329acbb743d01f680c4d02afb4c8fde7e20930811bb2b995788b5e872c20bb1", 16), new BigInteger("026e7e28010ecf2412d9523ad704647fb4fe9b66b1a681581b0e15553a89b1542828898f27243ebab45ff5e1acb9d4df1b051fbc62824dbc6f6c93261a78b9a759", 16), new BigInteger("012ddcc86ef655998c39ddae11718669e5e46cf1495b07e13b1014cd69b3af68304ad2a6b64321e78bf3bbca9bb494e91d451717e2d97564c6549465d0205cf421", 16), new BigInteger("010600c4c21847459fe576703e2ebecae8a5094ee63f536bf4ac68d3c13e5e4f12ac5cc10ab6a2d05a199214d1824747d551909636b774c22cac0b837599abcc75", 16)); // PSS Example 4.1 private byte[] msg4a = Hex.decode("9fb03b827c8217d9"); private byte[] slt4a = Hex.decode("ed7c98c95f30974fbe4fbddcf0f28d6021c0e91d"); private byte[] sig4a = Hex.decode("0323d5b7bf20ba4539289ae452ae4297080feff4518423ff4811a817837e7d82f1836cdfab54514ff0887bddeebf40bf99b047abc3ecfa6a37a3ef00f4a0c4a88aae0904b745c846c4107e8797723e8ac810d9e3d95dfa30ff4966f4d75d13768d20857f2b1406f264cfe75e27d7652f4b5ed3575f28a702f8c4ed9cf9b2d44948"); // PSS Example 4.2 private byte[] msg4b = Hex.decode("0ca2ad77797ece86de5bf768750ddb5ed6a3116ad99bbd17edf7f782f0db1cd05b0f677468c5ea420dc116b10e80d110de2b0461ea14a38be68620392e7e893cb4ea9393fb886c20ff790642305bf302003892e54df9f667509dc53920df583f50a3dd61abb6fab75d600377e383e6aca6710eeea27156e06752c94ce25ae99fcbf8592dbe2d7e27453cb44de07100ebb1a2a19811a478adbeab270f94e8fe369d90b3ca612f9f"); private byte[] slt4b = Hex.decode("22d71d54363a4217aa55113f059b3384e3e57e44"); private byte[] sig4b = Hex.decode("049d0185845a264d28feb1e69edaec090609e8e46d93abb38371ce51f4aa65a599bdaaa81d24fba66a08a116cb644f3f1e653d95c89db8bbd5daac2709c8984000178410a7c6aa8667ddc38c741f710ec8665aa9052be929d4e3b16782c1662114c5414bb0353455c392fc28f3db59054b5f365c49e1d156f876ee10cb4fd70598"); // // Example 8: A 1031-bit RSA key pair // private RSAKeyParameters pub8 = new RSAKeyParameters(false, new BigInteger("495370a1fb18543c16d3631e3163255df62be6eee890d5f25509e4f778a8ea6fbbbcdf85dff64e0d972003ab3681fbba6dd41fd541829b2e582de9f2a4a4e0a2d0900bef4753db3cee0ee06c7dfae8b1d53b5953218f9cceea695b08668edeaadced9463b1d790d5ebf27e9115b46cad4d9a2b8efab0561b0810344739ada0733f", 16), new BigInteger("010001", 16)); private RSAKeyParameters prv8 = new RSAPrivateCrtKeyParameters( new BigInteger("495370a1fb18543c16d3631e3163255df62be6eee890d5f25509e4f778a8ea6fbbbcdf85dff64e0d972003ab3681fbba6dd41fd541829b2e582de9f2a4a4e0a2d0900bef4753db3cee0ee06c7dfae8b1d53b5953218f9cceea695b08668edeaadced9463b1d790d5ebf27e9115b46cad4d9a2b8efab0561b0810344739ada0733f", 16), new BigInteger("010001", 16), new BigInteger("6c66ffe98980c38fcdeab5159898836165f4b4b817c4f6a8d486ee4ea9130fe9b9092bd136d184f95f504a607eac565846d2fdd6597a8967c7396ef95a6eeebb4578a643966dca4d8ee3de842de63279c618159c1ab54a89437b6a6120e4930afb52a4ba6ced8a4947ac64b30a3497cbe701c2d6266d517219ad0ec6d347dbe9", 16), new BigInteger("08dad7f11363faa623d5d6d5e8a319328d82190d7127d2846c439b0ab72619b0a43a95320e4ec34fc3a9cea876422305bd76c5ba7be9e2f410c8060645a1d29edb", 16), new BigInteger("0847e732376fc7900f898ea82eb2b0fc418565fdae62f7d9ec4ce2217b97990dd272db157f99f63c0dcbb9fbacdbd4c4dadb6df67756358ca4174825b48f49706d", 16), new BigInteger("05c2a83c124b3621a2aa57ea2c3efe035eff4560f33ddebb7adab81fce69a0c8c2edc16520dda83d59a23be867963ac65f2cc710bbcfb96ee103deb771d105fd85", 16), new BigInteger("04cae8aa0d9faa165c87b682ec140b8ed3b50b24594b7a3b2c220b3669bb819f984f55310a1ae7823651d4a02e99447972595139363434e5e30a7e7d241551e1b9", 16), new BigInteger("07d3e47bf686600b11ac283ce88dbb3f6051e8efd04680e44c171ef531b80b2b7c39fc766320e2cf15d8d99820e96ff30dc69691839c4b40d7b06e45307dc91f3f", 16)); // PSS Example 8.1 private byte[] msg8a = Hex.decode("81332f4be62948415ea1d899792eeacf6c6e1db1da8be13b5cea41db2fed467092e1ff398914c714259775f595f8547f735692a575e6923af78f22c6997ddb90fb6f72d7bb0dd5744a31decd3dc3685849836ed34aec596304ad11843c4f88489f209735f5fb7fdaf7cec8addc5818168f880acbf490d51005b7a8e84e43e54287977571dd99eea4b161eb2df1f5108f12a4142a83322edb05a75487a3435c9a78ce53ed93bc550857d7a9fb"); private byte[] slt8a = Hex.decode("1d65491d79c864b373009be6f6f2467bac4c78fa"); private byte[] sig8a = Hex.decode("0262ac254bfa77f3c1aca22c5179f8f040422b3c5bafd40a8f21cf0fa5a667ccd5993d42dbafb409c520e25fce2b1ee1e716577f1efa17f3da28052f40f0419b23106d7845aaf01125b698e7a4dfe92d3967bb00c4d0d35ba3552ab9a8b3eef07c7fecdbc5424ac4db1e20cb37d0b2744769940ea907e17fbbca673b20522380c5"); // PSS Example 8.2 private byte[] msg8b = Hex.decode("e2f96eaf0e05e7ba326ecca0ba7fd2f7c02356f3cede9d0faabf4fcc8e60a973e5595fd9ea08"); private byte[] slt8b = Hex.decode("435c098aa9909eb2377f1248b091b68987ff1838"); private byte[] sig8b = Hex.decode("2707b9ad5115c58c94e932e8ec0a280f56339e44a1b58d4ddcff2f312e5f34dcfe39e89c6a94dcee86dbbdae5b79ba4e0819a9e7bfd9d982e7ee6c86ee68396e8b3a14c9c8f34b178eb741f9d3f121109bf5c8172fada2e768f9ea1433032c004a8aa07eb990000a48dc94c8bac8aabe2b09b1aa46c0a2aa0e12f63fbba775ba7e"); // // Example 9: A 1536-bit RSA key pair // private RSAKeyParameters pub9 = new RSAKeyParameters(false, new BigInteger("e6bd692ac96645790403fdd0f5beb8b9bf92ed10007fc365046419dd06c05c5b5b2f48ecf989e4ce269109979cbb40b4a0ad24d22483d1ee315ad4ccb1534268352691c524f6dd8e6c29d224cf246973aec86c5bf6b1401a850d1b9ad1bb8cbcec47b06f0f8c7f45d3fc8f319299c5433ddbc2b3053b47ded2ecd4a4caefd614833dc8bb622f317ed076b8057fe8de3f84480ad5e83e4a61904a4f248fb397027357e1d30e463139815c6fd4fd5ac5b8172a45230ecb6318a04f1455d84e5a8b", 16), new BigInteger("010001", 16)); private RSAKeyParameters prv9 = new RSAPrivateCrtKeyParameters( new BigInteger("e6bd692ac96645790403fdd0f5beb8b9bf92ed10007fc365046419dd06c05c5b5b2f48ecf989e4ce269109979cbb40b4a0ad24d22483d1ee315ad4ccb1534268352691c524f6dd8e6c29d224cf246973aec86c5bf6b1401a850d1b9ad1bb8cbcec47b06f0f8c7f45d3fc8f319299c5433ddbc2b3053b47ded2ecd4a4caefd614833dc8bb622f317ed076b8057fe8de3f84480ad5e83e4a61904a4f248fb397027357e1d30e463139815c6fd4fd5ac5b8172a45230ecb6318a04f1455d84e5a8b", 16), new BigInteger("010001", 16), new BigInteger("6a7fd84fb85fad073b34406db74f8d61a6abc12196a961dd79565e9da6e5187bce2d980250f7359575359270d91590bb0e427c71460b55d51410b191bcf309fea131a92c8e702738fa719f1e0041f52e40e91f229f4d96a1e6f172e15596b4510a6daec26105f2bebc53316b87bdf21311666070e8dfee69d52c71a976caae79c72b68d28580dc686d9f5129d225f82b3d615513a882b3db91416b48ce08888213e37eeb9af800d81cab328ce420689903c00c7b5fd31b75503a6d419684d629", 16), new BigInteger("f8eb97e98df12664eefdb761596a69ddcd0e76daece6ed4bf5a1b50ac086f7928a4d2f8726a77e515b74da41988f220b1cc87aa1fc810ce99a82f2d1ce821edced794c6941f42c7a1a0b8c4d28c75ec60b652279f6154a762aed165d47dee367", 16), new BigInteger("ed4d71d0a6e24b93c2e5f6b4bbe05f5fb0afa042d204fe3378d365c2f288b6a8dad7efe45d153eef40cacc7b81ff934002d108994b94a5e4728cd9c963375ae49965bda55cbf0efed8d6553b4027f2d86208a6e6b489c176128092d629e49d3d", 16), new BigInteger("2bb68bddfb0c4f56c8558bffaf892d8043037841e7fa81cfa61a38c5e39b901c8ee71122a5da2227bd6cdeeb481452c12ad3d61d5e4f776a0ab556591befe3e59e5a7fddb8345e1f2f35b9f4cee57c32414c086aec993e9353e480d9eec6289f", 16), new BigInteger("4ff897709fad079746494578e70fd8546130eeab5627c49b080f05ee4ad9f3e4b7cba9d6a5dff113a41c3409336833f190816d8a6bc42e9bec56b7567d0f3c9c696db619b245d901dd856db7c8092e77e9a1cccd56ee4dba42c5fdb61aec2669", 16), new BigInteger("77b9d1137b50404a982729316efafc7dfe66d34e5a182600d5f30a0a8512051c560d081d4d0a1835ec3d25a60f4e4d6aa948b2bf3dbb5b124cbbc3489255a3a948372f6978496745f943e1db4f18382ceaa505dfc65757bb3f857a58dce52156", 16)); // PSS Example 9.1 private byte[] msg9a = Hex.decode("a88e265855e9d7ca36c68795f0b31b591cd6587c71d060a0b3f7f3eaef43795922028bc2b6ad467cfc2d7f659c5385aa70ba3672cdde4cfe4970cc7904601b278872bf51321c4a972f3c95570f3445d4f57980e0f20df54846e6a52c668f1288c03f95006ea32f562d40d52af9feb32f0fa06db65b588a237b34e592d55cf979f903a642ef64d2ed542aa8c77dc1dd762f45a59303ed75e541ca271e2b60ca709e44fa0661131e8d5d4163fd8d398566ce26de8730e72f9cca737641c244159420637028df0a18079d6208ea8b4711a2c750f5"); private byte[] slt9a = Hex.decode("c0a425313df8d7564bd2434d311523d5257eed80"); private byte[] sig9a = Hex.decode("586107226c3ce013a7c8f04d1a6a2959bb4b8e205ba43a27b50f124111bc35ef589b039f5932187cb696d7d9a32c0c38300a5cdda4834b62d2eb240af33f79d13dfbf095bf599e0d9686948c1964747b67e89c9aba5cd85016236f566cc5802cb13ead51bc7ca6bef3b94dcbdbb1d570469771df0e00b1a8a06777472d2316279edae86474668d4e1efff95f1de61c6020da32ae92bbf16520fef3cf4d88f61121f24bbd9fe91b59caf1235b2a93ff81fc403addf4ebdea84934a9cdaf8e1a9e"); // PSS Example 9.2 private byte[] msg9b = Hex.decode("c8c9c6af04acda414d227ef23e0820c3732c500dc87275e95b0d095413993c2658bc1d988581ba879c2d201f14cb88ced153a01969a7bf0a7be79c84c1486bc12b3fa6c59871b6827c8ce253ca5fefa8a8c690bf326e8e37cdb96d90a82ebab69f86350e1822e8bd536a2e"); private byte[] slt9b = Hex.decode("b307c43b4850a8dac2f15f32e37839ef8c5c0e91"); private byte[] sig9b = Hex.decode("80b6d643255209f0a456763897ac9ed259d459b49c2887e5882ecb4434cfd66dd7e1699375381e51cd7f554f2c271704b399d42b4be2540a0eca61951f55267f7c2878c122842dadb28b01bd5f8c025f7e228418a673c03d6bc0c736d0a29546bd67f786d9d692ccea778d71d98c2063b7a71092187a4d35af108111d83e83eae46c46aa34277e06044589903788f1d5e7cee25fb485e92949118814d6f2c3ee361489016f327fb5bc517eb50470bffa1afa5f4ce9aa0ce5b8ee19bf5501b958"); public String getName() { return "PSSBlindTest"; } private void testSig( int id, RSAKeyParameters pub, RSAKeyParameters prv, byte[] slt, byte[] msg, byte[] sig) throws Exception { RSABlindingFactorGenerator blindFactorGen = new RSABlindingFactorGenerator(); RSABlindingEngine blindingEngine = new RSABlindingEngine(); PSSSigner blindSigner = new PSSSigner(blindingEngine, new SHA1Digest(), 20); PSSSigner signer = new PSSSigner(new RSAEngine(), new SHA1Digest(), 20); blindFactorGen.init(pub); BigInteger blindFactor = blindFactorGen.generateBlindingFactor(); RSABlindingParameters params = new RSABlindingParameters(pub, blindFactor); // generate a blind signature blindSigner.init(true, new ParametersWithRandom(params, new FixedRandom(slt))); blindSigner.update(msg, 0, msg.length); byte[] blindedData = blindSigner.generateSignature(); RSAEngine signerEngine = new RSAEngine(); signerEngine.init(true, prv); byte[] blindedSig = signerEngine.processBlock(blindedData, 0, blindedData.length); // unblind the signature blindingEngine.init(false, params); byte[] s = blindingEngine.processBlock(blindedSig, 0, blindedSig.length); //signature verification if (!areEqual(s, sig)) { fail("test " + id + " failed generation"); } //verify signature with PSSSigner signer.init(false, pub); signer.update(msg, 0, msg.length); if (!signer.verifySignature(s)) { fail("test " + id + " failed PSSSigner verification"); } } private boolean isProcessingOkay( RSAKeyParameters pub, RSAKeyParameters prv, byte[] data, SecureRandom random) throws Exception { RSABlindingFactorGenerator blindFactorGen = new RSABlindingFactorGenerator(); RSABlindingEngine blindingEngine = new RSABlindingEngine(); PSSSigner blindSigner = new PSSSigner(blindingEngine, new SHA1Digest(), 20); PSSSigner pssEng = new PSSSigner(new RSAEngine(), new SHA1Digest(), 20); random.nextBytes(data); blindFactorGen.init(pub); BigInteger blindFactor = blindFactorGen.generateBlindingFactor(); RSABlindingParameters params = new RSABlindingParameters(pub, blindFactor); // generate a blind signature blindSigner.init(true, new ParametersWithRandom(params, random)); blindSigner.update(data, 0, data.length); byte[] blindedData = blindSigner.generateSignature(); RSAEngine signerEngine = new RSAEngine(); signerEngine.init(true, prv); byte[] blindedSig = signerEngine.processBlock(blindedData, 0, blindedData.length); // unblind the signature blindingEngine.init(false, params); byte[] s = blindingEngine.processBlock(blindedSig, 0, blindedSig.length); //verify signature with PSSSigner pssEng.init(false, pub); pssEng.update(data, 0, data.length); return pssEng.verifySignature(s); } public void performTest() throws Exception { testSig(1, pub1, prv1, slt1a, msg1a, sig1a); testSig(2, pub1, prv1, slt1b, msg1b, sig1b); testSig(3, pub2, prv2, slt2a, msg2a, sig2a); testSig(4, pub2, prv2, slt2b, msg2b, sig2b); testSig(5, pub4, prv4, slt4a, msg4a, sig4a); testSig(6, pub4, prv4, slt4b, msg4b, sig4b); testSig(7, pub8, prv8, slt8a, msg8a, sig8a); testSig(8, pub8, prv8, slt8b, msg8b, sig8b); testSig(9, pub9, prv9, slt9a, msg9a, sig9a); testSig(10, pub9, prv9, slt9b, msg9b, sig9b); // // loop test // int failed = 0; byte[] data = new byte[DATA_LENGTH]; SecureRandom random = new SecureRandom(); RSAKeyParameters[] kprv ={prv1, prv2, prv4, prv8, prv9}; RSAKeyParameters[] kpub ={pub1, pub2, pub4, pub8, pub9}; int i = 0; for (int j = 0; j < NUM_TESTS; j++, i++) { if (i == kprv.length) { i = 0; } if (!isProcessingOkay(kpub[i], kprv[i], data, random)) { failed++; } } if (failed != 0) { fail("loop test failed - failures: " + failed); } // // key generation test // RSAKeyPairGenerator pGen = new RSAKeyPairGenerator(); RSAKeyGenerationParameters genParam = new RSAKeyGenerationParameters( BigInteger.valueOf(0x11), new SecureRandom(), 1024, 25); pGen.init(genParam); failed = 0; for (int k = 0; k < NUM_TESTS_WITH_KEY_GENERATION; k++) { AsymmetricCipherKeyPair pair = pGen.generateKeyPair(); for (int j = 0; j < NUM_TESTS; j++) { if (!isProcessingOkay((RSAKeyParameters)pair.getPublic(), (RSAKeyParameters)pair.getPrivate(), data, random)) { failed++; } } } if (failed != 0) { fail("loop test with key generation failed - failures: " + failed); } } public static void main( String[] args) { runTest(new PSSBlindTest()); } } bouncycastle-1.49.orig/test/src/org/bouncycastle/crypto/test/CMacTest.java0000644000175000017500000001713410601146527026276 0ustar ebourgebourgpackage org.bouncycastle.crypto.test; import org.bouncycastle.crypto.BlockCipher; import org.bouncycastle.crypto.Mac; import org.bouncycastle.crypto.engines.AESFastEngine; import org.bouncycastle.crypto.macs.CMac; import org.bouncycastle.crypto.params.KeyParameter; import org.bouncycastle.util.encoders.Hex; import org.bouncycastle.util.test.SimpleTest; /** * CMAC tester - Official Test Vectors. */ public class CMacTest extends SimpleTest { private static final byte[] keyBytes128 = Hex.decode("2b7e151628aed2a6abf7158809cf4f3c"); private static final byte[] keyBytes192 = Hex.decode( "8e73b0f7da0e6452c810f32b809079e5" + "62f8ead2522c6b7b"); private static final byte[] keyBytes256 = Hex.decode( "603deb1015ca71be2b73aef0857d7781" + "1f352c073b6108d72d9810a30914dff4"); private static final byte[] input0 = Hex.decode(""); private static final byte[] input16 = Hex.decode("6bc1bee22e409f96e93d7e117393172a"); private static final byte[] input40 = Hex.decode( "6bc1bee22e409f96e93d7e117393172a" + "ae2d8a571e03ac9c9eb76fac45af8e5130c81c46a35ce411"); private static final byte[] input64 = Hex.decode( "6bc1bee22e409f96e93d7e117393172a" + "ae2d8a571e03ac9c9eb76fac45af8e51" + "30c81c46a35ce411e5fbc1191a0a52ef" + "f69f2445df4f9b17ad2b417be66c3710"); private static final byte[] output_k128_m0 = Hex.decode("bb1d6929e95937287fa37d129b756746"); private static final byte[] output_k128_m16 = Hex.decode("070a16b46b4d4144f79bdd9dd04a287c"); private static final byte[] output_k128_m40 = Hex.decode("dfa66747de9ae63030ca32611497c827"); private static final byte[] output_k128_m64 = Hex.decode("51f0bebf7e3b9d92fc49741779363cfe"); private static final byte[] output_k192_m0 = Hex.decode("d17ddf46adaacde531cac483de7a9367"); private static final byte[] output_k192_m16 = Hex.decode("9e99a7bf31e710900662f65e617c5184"); private static final byte[] output_k192_m40 = Hex.decode("8a1de5be2eb31aad089a82e6ee908b0e"); private static final byte[] output_k192_m64 = Hex.decode("a1d5df0eed790f794d77589659f39a11"); private static final byte[] output_k256_m0 = Hex.decode("028962f61b7bf89efc6b551f4667d983"); private static final byte[] output_k256_m16 = Hex.decode("28a7023f452e8f82bd4bf28d8c37c35c"); private static final byte[] output_k256_m40 = Hex.decode("aaf3d8f1de5640c232f5b169b9c911e6"); private static final byte[] output_k256_m64 = Hex.decode("e1992190549f6ed5696a2c056c315410"); public CMacTest() { } public void performTest() { BlockCipher cipher = new AESFastEngine(); Mac mac = new CMac(cipher, 128); //128 bytes key KeyParameter key = new KeyParameter(keyBytes128); // 0 bytes message - 128 bytes key mac.init(key); mac.update(input0, 0, input0.length); byte[] out = new byte[16]; mac.doFinal(out, 0); if (!areEqual(out, output_k128_m0)) { fail("Failed - expected " + new String(Hex.encode(output_k128_m0)) + " got " + new String(Hex.encode(out))); } // 16 bytes message - 128 bytes key mac.init(key); mac.update(input16, 0, input16.length); out = new byte[16]; mac.doFinal(out, 0); if (!areEqual(out, output_k128_m16)) { fail("Failed - expected " + new String(Hex.encode(output_k128_m16)) + " got " + new String(Hex.encode(out))); } // 40 bytes message - 128 bytes key mac.init(key); mac.update(input40, 0, input40.length); out = new byte[16]; mac.doFinal(out, 0); if (!areEqual(out, output_k128_m40)) { fail("Failed - expected " + new String(Hex.encode(output_k128_m40)) + " got " + new String(Hex.encode(out))); } // 64 bytes message - 128 bytes key mac.init(key); mac.update(input64, 0, input64.length); out = new byte[16]; mac.doFinal(out, 0); if (!areEqual(out, output_k128_m64)) { fail("Failed - expected " + new String(Hex.encode(output_k128_m64)) + " got " + new String(Hex.encode(out))); } //192 bytes key key = new KeyParameter(keyBytes192); // 0 bytes message - 192 bytes key mac.init(key); mac.update(input0, 0, input0.length); out = new byte[16]; mac.doFinal(out, 0); if (!areEqual(out, output_k192_m0)) { fail("Failed - expected " + new String(Hex.encode(output_k192_m0)) + " got " + new String(Hex.encode(out))); } // 16 bytes message - 192 bytes key mac.init(key); mac.update(input16, 0, input16.length); out = new byte[16]; mac.doFinal(out, 0); if (!areEqual(out, output_k192_m16)) { fail("Failed - expected " + new String(Hex.encode(output_k192_m16)) + " got " + new String(Hex.encode(out))); } // 40 bytes message - 192 bytes key mac.init(key); mac.update(input40, 0, input40.length); out = new byte[16]; mac.doFinal(out, 0); if (!areEqual(out, output_k192_m40)) { fail("Failed - expected " + new String(Hex.encode(output_k192_m40)) + " got " + new String(Hex.encode(out))); } // 64 bytes message - 192 bytes key mac.init(key); mac.update(input64, 0, input64.length); out = new byte[16]; mac.doFinal(out, 0); if (!areEqual(out, output_k192_m64)) { fail("Failed - expected " + new String(Hex.encode(output_k192_m64)) + " got " + new String(Hex.encode(out))); } //256 bytes key key = new KeyParameter(keyBytes256); // 0 bytes message - 256 bytes key mac.init(key); mac.update(input0, 0, input0.length); out = new byte[16]; mac.doFinal(out, 0); if (!areEqual(out, output_k256_m0)) { fail("Failed - expected " + new String(Hex.encode(output_k256_m0)) + " got " + new String(Hex.encode(out))); } // 16 bytes message - 256 bytes key mac.init(key); mac.update(input16, 0, input16.length); out = new byte[16]; mac.doFinal(out, 0); if (!areEqual(out, output_k256_m16)) { fail("Failed - expected " + new String(Hex.encode(output_k256_m16)) + " got " + new String(Hex.encode(out))); } // 40 bytes message - 256 bytes key mac.init(key); mac.update(input40, 0, input40.length); out = new byte[16]; mac.doFinal(out, 0); if (!areEqual(out, output_k256_m40)) { fail("Failed - expected " + new String(Hex.encode(output_k256_m40)) + " got " + new String(Hex.encode(out))); } // 64 bytes message - 256 bytes key mac.init(key); mac.update(input64, 0, input64.length); out = new byte[16]; mac.doFinal(out, 0); if (!areEqual(out, output_k256_m64)) { fail("Failed - expected " + new String(Hex.encode(output_k256_m64)) + " got " + new String(Hex.encode(out))); } } public String getName() { return "CMac"; } public static void main(String[] args) { runTest(new CMacTest()); } } bouncycastle-1.49.orig/test/src/org/bouncycastle/crypto/test/GOST28147Test.java0000644000175000017500000003562011576541432026663 0ustar ebourgebourgpackage org.bouncycastle.crypto.test; import org.bouncycastle.crypto.BufferedBlockCipher; import org.bouncycastle.crypto.CipherParameters; import org.bouncycastle.crypto.CryptoException; import org.bouncycastle.crypto.digests.GOST3411Digest; import org.bouncycastle.crypto.engines.GOST28147Engine; import org.bouncycastle.crypto.modes.CBCBlockCipher; import org.bouncycastle.crypto.modes.CFBBlockCipher; import org.bouncycastle.crypto.modes.GOFBBlockCipher; import org.bouncycastle.crypto.params.KeyParameter; import org.bouncycastle.crypto.params.ParametersWithIV; import org.bouncycastle.crypto.params.ParametersWithSBox; import org.bouncycastle.util.encoders.Hex; import org.bouncycastle.util.test.SimpleTest; public class GOST28147Test extends CipherTest { static String input1 = "0000000000000000"; static String output1 = "1b0bbc32cebcab42"; static String input2 = "bc350e71aac5f5c2"; static String output2 = "d35ab653493b49f5"; static String input3 = "bc350e71aa11345709acde"; static String output3 = "8824c124c4fd14301fb1e8"; static String input4 = "000102030405060708090a0b0c0d0e0fff0102030405060708090a0b0c0d0e0f"; static String output4 = "29b7083e0a6d955ca0ec5b04fdb4ea41949f1dd2efdf17baffc1780b031f3934"; static byte TestSBox[] = { 0x0,0x1,0x2,0x3,0x4,0x5,0x6,0x7,0x8,0x9,0xA,0xB,0xC,0xD,0xE,0xF, 0xF,0xE,0xD,0xC,0xB,0xA,0x9,0x8,0x7,0x6,0x5,0x4,0x3,0x2,0x1,0x0, 0x0,0x1,0x2,0x3,0x4,0x5,0x6,0x7,0x8,0x9,0xA,0xB,0xC,0xD,0xE,0xF, 0xF,0xE,0xD,0xC,0xB,0xA,0x9,0x8,0x7,0x6,0x5,0x4,0x3,0x2,0x1,0x0, 0x0,0x1,0x2,0x3,0x4,0x5,0x6,0x7,0x8,0x9,0xA,0xB,0xC,0xD,0xE,0xF, 0xF,0xE,0xD,0xC,0xB,0xA,0x9,0x8,0x7,0x6,0x5,0x4,0x3,0x2,0x1,0x0, 0x0,0x1,0x2,0x3,0x4,0x5,0x6,0x7,0x8,0x9,0xA,0xB,0xC,0xD,0xE,0xF, 0xF,0xE,0xD,0xC,0xB,0xA,0x9,0x8,0x7,0x6,0x5,0x4,0x3,0x2,0x1,0x0 }; static SimpleTest[] tests = { new BlockCipherVectorTest(1, new GOST28147Engine(), new KeyParameter(Hex.decode("546d203368656c326973652073736e62206167796967747473656865202c3d73")), input1, output1), new BlockCipherVectorTest(2, new CBCBlockCipher(new GOST28147Engine()), new ParametersWithIV(new KeyParameter(Hex.decode("00112233445566778899AABBCCDDEEFF00112233445566778899AABBCCDDEEFF")), Hex.decode("1234567890abcdef")), input2, output2), new BlockCipherVectorTest(3, new GOFBBlockCipher(new GOST28147Engine()), new ParametersWithIV(new KeyParameter(Hex.decode("0011223344556677889900112233445566778899001122334455667788990011")), Hex.decode("1234567890abcdef")), //IV input3, output3), new BlockCipherVectorTest(4, new CFBBlockCipher(new GOST28147Engine(), 64), new ParametersWithIV(new KeyParameter(Hex.decode("aafd12f659cae63489b479e5076ddec2f06cb58faafd12f659cae63489b479e5")), Hex.decode("aafd12f659cae634")), input4, output4), //tests with parameters, set S-box. new BlockCipherVectorTest(5, new GOST28147Engine(), new KeyParameter(Hex.decode("546d203368656c326973652073736e62206167796967747473656865202c3d73")),//key , default parameter S-box set to D-Test input1, output1), new BlockCipherVectorTest(6, new CFBBlockCipher(new GOST28147Engine(), 64), new ParametersWithIV( new ParametersWithSBox( new KeyParameter(Hex.decode("546d203368656c326973652073736e62206167796967747473656865202c3d73")), //key GOST28147Engine.getSBox("D-Test")), //type S-box Hex.decode("1234567890abcdef")), //IV "0000000000000000", //input message "b587f7a0814c911d"), //encrypt message new BlockCipherVectorTest(7, new CFBBlockCipher(new GOST28147Engine(), 64), new ParametersWithIV( new ParametersWithSBox( new KeyParameter(Hex.decode("546d203368656c326973652073736e62206167796967747473656865202c3d73")), //key GOST28147Engine.getSBox("E-Test")), //type S-box Hex.decode("1234567890abcdef")), //IV "0000000000000000", //input message "e8287f53f991d52b"), //encrypt message new BlockCipherVectorTest(8, new CFBBlockCipher(new GOST28147Engine(), 64), new ParametersWithIV( new ParametersWithSBox( new KeyParameter(Hex.decode("546d203368656c326973652073736e62206167796967747473656865202c3d73")), //key GOST28147Engine.getSBox("E-A")), //type S-box Hex.decode("1234567890abcdef")), //IV "0000000000000000", //input message "c41009dba22ebe35"), //encrypt message new BlockCipherVectorTest(9, new CFBBlockCipher(new GOST28147Engine(), 8), new ParametersWithIV( new ParametersWithSBox( new KeyParameter(Hex.decode("546d203368656c326973652073736e62206167796967747473656865202c3d73")), //key GOST28147Engine.getSBox("E-B")), //type S-box Hex.decode("1234567890abcdef")), //IV "0000000000000000", //input message "80d8723fcd3aba28"), //encrypt message new BlockCipherVectorTest(10, new CFBBlockCipher(new GOST28147Engine(), 8), new ParametersWithIV( new ParametersWithSBox( new KeyParameter(Hex.decode("546d203368656c326973652073736e62206167796967747473656865202c3d73")), //key GOST28147Engine.getSBox("E-C")), //type S-box Hex.decode("1234567890abcdef")), //IV "0000000000000000", //input message "739f6f95068499b5"), //encrypt message new BlockCipherVectorTest(11, new CFBBlockCipher(new GOST28147Engine(), 8), new ParametersWithIV( new ParametersWithSBox( new KeyParameter(Hex.decode("546d203368656c326973652073736e62206167796967747473656865202c3d73")), //key GOST28147Engine.getSBox("E-D")), //type S-box Hex.decode("1234567890abcdef")), //IV "0000000000000000", //input message "4663f720f4340f57"), //encrypt message new BlockCipherVectorTest(12, new CFBBlockCipher(new GOST28147Engine(), 8), new ParametersWithIV( new ParametersWithSBox( new KeyParameter(Hex.decode("546d203368656c326973652073736e62206167796967747473656865202c3d73")), //key GOST28147Engine.getSBox("D-A")), //type S-box Hex.decode("1234567890abcdef")), //IV "0000000000000000", //input message "5bb0a31d218ed564"), //encrypt message new BlockCipherVectorTest(13, new CFBBlockCipher(new GOST28147Engine(), 8), new ParametersWithIV( new ParametersWithSBox( new KeyParameter(Hex.decode("546d203368656c326973652073736e62206167796967747473656865202c3d73")), //key TestSBox), //set own S-box Hex.decode("1234567890abcdef")), //IV "0000000000000000", //input message "c3af96ef788667c5"), //encrypt message new BlockCipherVectorTest(14, new GOFBBlockCipher(new GOST28147Engine()), new ParametersWithIV( new ParametersWithSBox( new KeyParameter(Hex.decode("4ef72b778f0b0bebeef4f077551cb74a927b470ad7d7f2513454569a247e989d")), //key GOST28147Engine.getSBox("E-A")), //type S-box Hex.decode("1234567890abcdef")), //IV "bc350e71aa11345709acde", //input message "1bcc2282707c676fb656dc"), //encrypt message }; static private final int GOST28147_KEY_LENGTH = 32; private byte[] generateKey(byte[] startkey) { byte[] newKey = new byte[GOST28147_KEY_LENGTH]; GOST3411Digest digest = new GOST3411Digest(); digest.update(startkey, 0, startkey.length); digest.doFinal(newKey, 0); return newKey; } GOST28147Test() { super(tests, new GOST28147Engine(), new KeyParameter(new byte[32])); } public void performTest() throws Exception { super.performTest(); //advanced tests with GOST28147KeyGenerator: //encrypt on hesh message; ECB mode: byte[] in = Hex.decode("4e6f77206973207468652074696d6520666f7220616c6c20"); byte[] output = Hex.decode("8ad3c8f56b27ff1fbd46409359bdc796bc350e71aac5f5c0"); byte[] out = new byte[in.length]; byte[] key = generateKey(Hex.decode("0123456789abcdef")); //!!! heshing start_key - get 256 bits !!! // System.out.println(new String(Hex.encode(key))); CipherParameters param = new ParametersWithSBox(new KeyParameter(key), GOST28147Engine.getSBox("E-A")); //CipherParameters param = new GOST28147Parameters(key,"D-Test"); BufferedBlockCipher cipher = new BufferedBlockCipher(new GOST28147Engine()); cipher.init(true, param); int len1 = cipher.processBytes(in, 0, in.length, out, 0); try { cipher.doFinal(out, len1); } catch (CryptoException e) { fail("failed - exception " + e.toString(), e); } if (out.length != output.length) { fail("failed - " + "expected " + new String(Hex.encode(output)) + " got " + new String(Hex.encode(out))); } for (int i = 0; i != out.length; i++) { if (out[i] != output[i]) { fail("failed - " + "expected " + new String(Hex.encode(output)) + " got " + new String(Hex.encode(out))); } } //encrypt on hesh message; CFB mode: in = Hex.decode("bc350e71aac5f5c2"); output = Hex.decode("0ebbbafcf38f14a5"); out = new byte[in.length]; key = generateKey(Hex.decode("0123456789abcdef")); //!!! heshing start_key - get 256 bits !!! param = new ParametersWithIV(new ParametersWithSBox( new KeyParameter(key), //key GOST28147Engine.getSBox("E-A")), //type S-box Hex.decode("1234567890abcdef")); //IV cipher = new BufferedBlockCipher(new CFBBlockCipher(new GOST28147Engine(), 64)); cipher.init(true, param); len1 = cipher.processBytes(in, 0, in.length, out, 0); try { cipher.doFinal(out, len1); } catch (CryptoException e) { fail("failed - exception " + e.toString(), e); } if (out.length != output.length) { fail("failed - " + "expected " + new String(Hex.encode(output)) + " got " + new String(Hex.encode(out))); } for (int i = 0; i != out.length; i++) { if (out[i] != output[i]) { fail("failed - " + "expected " + new String(Hex.encode(output)) + " got " + new String(Hex.encode(out))); } } //encrypt on hesh message; CFB mode: in = Hex.decode("000102030405060708090a0b0c0d0e0fff0102030405060708090a0b0c0d0e0f"); output = Hex.decode("64988982819f0a1655e226e19ecad79d10cc73bac95c5d7da034786c12294225"); out = new byte[in.length]; key = generateKey(Hex.decode("aafd12f659cae63489b479e5076ddec2f06cb58faafd12f659cae63489b479e5")); //!!! heshing start_key - get 256 bits !!! param = new ParametersWithIV(new ParametersWithSBox( new KeyParameter(key), //key GOST28147Engine.getSBox("E-A")), //type S-box Hex.decode("aafd12f659cae634")); //IV cipher = new BufferedBlockCipher(new CFBBlockCipher(new GOST28147Engine(), 64)); cipher.init(true, param); len1 = cipher.processBytes(in, 0, in.length, out, 0); cipher.doFinal(out, len1); if (out.length != output.length) { fail("failed - " + "expected " + new String(Hex.encode(output)) + " got " + new String(Hex.encode(out))); } for (int i = 0; i != out.length; i++) { if (out[i] != output[i]) { fail("failed - " + "expected " + new String(Hex.encode(output)) + " got " + new String(Hex.encode(out))); } } //encrypt on hesh message; OFB mode: in = Hex.decode("bc350e71aa11345709acde"); output = Hex.decode("1bcc2282707c676fb656dc"); out = new byte[in.length]; key = generateKey(Hex.decode("0123456789abcdef")); //!!! heshing start_key - get 256 bits !!! param = new ParametersWithIV(new ParametersWithSBox( new KeyParameter(key), //key GOST28147Engine.getSBox("E-A")), //type S-box Hex.decode("1234567890abcdef")); //IV cipher = new BufferedBlockCipher(new GOFBBlockCipher(new GOST28147Engine())); cipher.init(true, param); len1 = cipher.processBytes(in, 0, in.length, out, 0); cipher.doFinal(out, len1); if (out.length != output.length) { fail("failed - " + "expected " + new String(Hex.encode(output)) + " got " + new String(Hex.encode(out))); } for (int i = 0; i != out.length; i++) { if (out[i] != output[i]) { fail("failed - " + "expected " + new String(Hex.encode(output)) + " got " + new String(Hex.encode(out))); } } // key reuse test param = new ParametersWithIV(null, // key and sbox reused Hex.decode("1234567890abcdef")); //IV cipher.init(true, param); len1 = cipher.processBytes(in, 0, in.length, out, 0); cipher.doFinal(out, len1); if (out.length != output.length) { fail("failed - " + "expected " + new String(Hex.encode(output)) + " got " + new String(Hex.encode(out))); } for (int i = 0; i != out.length; i++) { if (out[i] != output[i]) { fail("failed - " + "expected " + new String(Hex.encode(output)) + " got " + new String(Hex.encode(out))); } } } public String getName() { return "GOST28147"; } public static void main( String[] args) { runTest(new GOST28147Test()); } } bouncycastle-1.49.orig/test/src/org/bouncycastle/crypto/test/AESVectorFileTest.java0000644000175000017500000001710110330633061030051 0ustar ebourgebourgpackage org.bouncycastle.crypto.test; import java.io.BufferedReader; import java.io.File; import java.io.IOException; import java.io.InputStream; import java.io.InputStreamReader; import java.util.ArrayList; import java.util.Enumeration; import java.util.List; import java.util.zip.ZipEntry; import java.util.zip.ZipFile; import org.bouncycastle.crypto.BlockCipher; import org.bouncycastle.crypto.engines.AESEngine; import org.bouncycastle.crypto.engines.AESFastEngine; import org.bouncycastle.crypto.engines.AESLightEngine; import org.bouncycastle.crypto.params.KeyParameter; import org.bouncycastle.util.encoders.Hex; import org.bouncycastle.util.test.SimpleTestResult; import org.bouncycastle.util.test.Test; import org.bouncycastle.util.test.TestResult; /** * Test vectors from the NIST standard tests and Brian Gladman's vector set * * http://fp.gladman.plus.com/cryptography_technology/rijndael/ */ public class AESVectorFileTest implements Test { private int countOfTests = 0; private int testNum = 0; protected BlockCipher createNewEngineForTest() { return new AESEngine(); } private Test[] readTestVectors(InputStream inStream) { // initialize key, plaintext, ciphertext = null // read until find BLOCKSIZE= // return if not 128 // read KEYSIZE= or ignore // loop // read a line // if starts with BLOCKSIZE= // parse the rest. return if not 128 // if starts with KEY= // parse the rest and set KEY // if starts with PT= // parse the rest and set plaintext // if starts with CT= // parse the rest and set ciphertext // if starts with TEST= or end of file // if key, plaintext, ciphertext are all not null // save away their values as the next test // until end of file List tests = new ArrayList(); String key = null; String plaintext = null; String ciphertext = null; BufferedReader in = new BufferedReader(new InputStreamReader(inStream)); try { String line = in.readLine(); while (line != null) { line = line.trim().toLowerCase(); if (line.startsWith("blocksize=")) { int i = 0; try { i = Integer.parseInt(line.substring(10).trim()); } catch (Exception e) { } if (i != 128) { return null; } } else if (line.startsWith("keysize=")) { int i = 0; try { i = Integer.parseInt(line.substring(10).trim()); } catch (Exception e) { } if ((i != 128) && (i != 192) && (i != 256)) { return null; } } else if (line.startsWith("key=")) { key = line.substring(4).trim(); } else if (line.startsWith("pt=")) { plaintext = line.substring(3).trim(); } else if (line.startsWith("ct=")) { ciphertext = line.substring(3).trim(); } else if (line.startsWith("test=")) { if ((key != null) && (plaintext != null) && (ciphertext != null)) { tests.add(new BlockCipherVectorTest(testNum++, createNewEngineForTest(), new KeyParameter(Hex .decode(key)), plaintext, ciphertext)); } } line = in.readLine(); } try { in.close(); } catch (IOException e) { } } catch (IOException e) { } if ((key != null) && (plaintext != null) && (ciphertext != null)) { tests.add(new BlockCipherVectorTest(testNum++, createNewEngineForTest(), new KeyParameter(Hex.decode(key)), plaintext, ciphertext)); } return (Test[])(tests.toArray(new Test[tests.size()])); } public String getName() { return "AES"; } private TestResult performTestsFromZipFile(File zfile) { try { ZipFile inZip = new ZipFile(zfile); for (Enumeration files = inZip.entries(); files.hasMoreElements();) { Test[] tests = null; try { tests = readTestVectors(inZip .getInputStream((ZipEntry)(files.nextElement()))); } catch (Exception e) { return new SimpleTestResult(false, getName() + ": threw " + e); } if (tests != null) { for (int i = 0; i != tests.length; i++) { TestResult res = tests[i].perform(); countOfTests++; if (!res.isSuccessful()) { return res; } } } } inZip.close(); return new SimpleTestResult(true, getName() + ": Okay"); } catch (Exception e) { return new SimpleTestResult(false, getName() + ": threw " + e); } } private static final String[] zipFileNames = { "rijn.tv.ecbnk.zip", "rijn.tv.ecbnt.zip", "rijn.tv.ecbvk.zip", "rijn.tv.ecbvt.zip" }; public TestResult perform() { countOfTests = 0; for (int i = 0; i < zipFileNames.length; i++) { File inf = new File(zipFileNames[i]); TestResult res = performTestsFromZipFile(inf); if (!res.isSuccessful()) { return res; } } return new SimpleTestResult(true, getName() + ": " + countOfTests + " performed Okay"); } public static void main(String[] args) { AESVectorFileTest test = new AESVectorFileTest(); TestResult result = test.perform(); System.out.println(result); test = new AESLightVectorFileTest(); result = test.perform(); System.out.println(result); test = new AESFastVectorFileTest(); result = test.perform(); System.out.println(result); } private static class AESLightVectorFileTest extends AESVectorFileTest { protected BlockCipher createNewEngineForTest() { return new AESLightEngine(); } public String getName() { return "AESLight"; } } private static class AESFastVectorFileTest extends AESVectorFileTest { protected BlockCipher createNewEngineForTest() { return new AESFastEngine(); } public String getName() { return "AESFast"; } } } bouncycastle-1.49.orig/test/src/org/bouncycastle/crypto/test/RC4Test.java0000644000175000017500000000225010330633061026045 0ustar ebourgebourgpackage org.bouncycastle.crypto.test; import org.bouncycastle.crypto.engines.RC4Engine; import org.bouncycastle.crypto.params.KeyParameter; import org.bouncycastle.util.encoders.Hex; import org.bouncycastle.util.test.SimpleTest; /** * RC4 Test */ public class RC4Test extends SimpleTest { StreamCipherVectorTest[] tests = { new StreamCipherVectorTest(0, new RC4Engine(), new KeyParameter(Hex.decode("0123456789ABCDEF")), "4e6f772069732074", "3afbb5c77938280d"), new StreamCipherVectorTest(0, new RC4Engine(), new KeyParameter(Hex.decode("0123456789ABCDEF")), "68652074696d6520", "1cf1e29379266d59"), new StreamCipherVectorTest(0, new RC4Engine(), new KeyParameter(Hex.decode("0123456789ABCDEF")), "666f7220616c6c20", "12fbb0c771276459") }; public String getName() { return "RC4"; } public void performTest() { for (int i = 0; i != tests.length; i++) { tests[i].performTest(); } } public static void main( String[] args) { runTest(new RC4Test()); } } bouncycastle-1.49.orig/test/src/org/bouncycastle/crypto/test/DESedeTest.java0000644000175000017500000001316010531736712026562 0ustar ebourgebourgpackage org.bouncycastle.crypto.test; import org.bouncycastle.crypto.KeyGenerationParameters; import org.bouncycastle.crypto.Wrapper; import org.bouncycastle.crypto.engines.DESedeEngine; import org.bouncycastle.crypto.engines.DESedeWrapEngine; import org.bouncycastle.crypto.generators.DESedeKeyGenerator; import org.bouncycastle.crypto.params.DESedeParameters; import org.bouncycastle.crypto.params.KeyParameter; import org.bouncycastle.crypto.params.ParametersWithIV; import org.bouncycastle.util.encoders.Hex; import org.bouncycastle.util.test.SimpleTest; import java.security.SecureRandom; /** * DESede tester */ public class DESedeTest extends CipherTest { static private byte[] weakKey = // first 8 bytes non-weak { (byte)0x06,(byte)0x01,(byte)0x01,(byte)0x01, (byte)0x01,(byte)0x01,(byte)0x01,(byte)0x01, (byte)0x1f,(byte)0x1f,(byte)0x1f,(byte)0x1f, (byte)0x0e,(byte)0x0e,(byte)0x0e,(byte)0x0e, (byte)0xe0,(byte)0xe0,(byte)0xe0,(byte)0xe0, (byte)0xf1,(byte)0xf1,(byte)0xf1,(byte)0xf1, }; static String input1 = "4e6f77206973207468652074696d6520666f7220616c6c20"; static String input2 = "4e6f7720697320746865"; static SimpleTest[] tests = { new BlockCipherVectorTest(0, new DESedeEngine(), new DESedeParameters(Hex.decode("0123456789abcdef0123456789abcdef")), input1, "3fa40e8a984d48156a271787ab8883f9893d51ec4b563b53"), new BlockCipherVectorTest(1, new DESedeEngine(), new DESedeParameters(Hex.decode("0123456789abcdeffedcba9876543210")), input1, "d80a0d8b2bae5e4e6a0094171abcfc2775d2235a706e232c"), new BlockCipherVectorTest(2, new DESedeEngine(), new DESedeParameters(Hex.decode("0123456789abcdef0123456789abcdef0123456789abcdef")), input1, "3fa40e8a984d48156a271787ab8883f9893d51ec4b563b53"), new BlockCipherVectorTest(3, new DESedeEngine(), new DESedeParameters(Hex.decode("0123456789abcdeffedcba98765432100123456789abcdef")), input1, "d80a0d8b2bae5e4e6a0094171abcfc2775d2235a706e232c") }; DESedeTest() { super(tests, new DESedeEngine(), new KeyParameter(new byte[16])); } private void wrapTest( int id, byte[] kek, byte[] iv, byte[] in, byte[] out) { Wrapper wrapper = new DESedeWrapEngine(); wrapper.init(true, new ParametersWithIV(new KeyParameter(kek), iv)); try { byte[] cText = wrapper.wrap(in, 0, in.length); if (!areEqual(cText, out)) { fail(": failed wrap test " + id + " expected " + new String(Hex.encode(out)) + " got " + new String(Hex.encode(cText))); } } catch (Exception e) { fail("failed wrap test exception: " + e.toString(), e); } wrapper.init(false, new KeyParameter(kek)); try { byte[] pText = wrapper.unwrap(out, 0, out.length); if (!areEqual(pText, in)) { fail("failed unwrap test " + id + " expected " + new String(Hex.encode(in)) + " got " + new String(Hex.encode(pText))); } } catch (Exception e) { fail("failed unwrap test exception: " + e.toString(), e); } } public void performTest() throws Exception { super.performTest(); byte[] kek1 = Hex.decode("255e0d1c07b646dfb3134cc843ba8aa71f025b7c0838251f"); byte[] iv1 = Hex.decode("5dd4cbfc96f5453b"); byte[] in1 = Hex.decode("2923bf85e06dd6ae529149f1f1bae9eab3a7da3d860d3e98"); byte[] out1 = Hex.decode("690107618ef092b3b48ca1796b234ae9fa33ebb4159604037db5d6a84eb3aac2768c632775a467d4"); wrapTest(1, kek1, iv1, in1, out1); // // key generation // SecureRandom random = new SecureRandom(); DESedeKeyGenerator keyGen = new DESedeKeyGenerator(); keyGen.init(new KeyGenerationParameters(random, 112)); byte[] kB = keyGen.generateKey(); if (kB.length != 16) { fail("112 bit key wrong length."); } keyGen.init(new KeyGenerationParameters(random, 168)); kB = keyGen.generateKey(); if (kB.length != 24) { fail("168 bit key wrong length."); } try { keyGen.init(new KeyGenerationParameters(random, 200)); fail("invalid key length not detected."); } catch (IllegalArgumentException e) { // expected } try { DESedeParameters.isWeakKey(new byte[4], 0); fail("no exception on small key"); } catch (IllegalArgumentException e) { if (!e.getMessage().equals("key material too short.")) { fail("wrong exception"); } } try { new DESedeParameters(weakKey); fail("no exception on weak key"); } catch (IllegalArgumentException e) { if (!e.getMessage().equals("attempt to create weak DESede key")) { fail("wrong exception"); } } } public String getName() { return "DESede"; } public static void main( String[] args) { runTest(new DESedeTest()); } } bouncycastle-1.49.orig/test/src/org/bouncycastle/crypto/test/SHA384HMacTest.java0000644000175000017500000001065510330633061027070 0ustar ebourgebourgpackage org.bouncycastle.crypto.test; import org.bouncycastle.crypto.digests.SHA384Digest; import org.bouncycastle.crypto.macs.HMac; import org.bouncycastle.crypto.params.KeyParameter; import org.bouncycastle.util.Arrays; import org.bouncycastle.util.encoders.Hex; import org.bouncycastle.util.test.SimpleTestResult; import org.bouncycastle.util.test.Test; import org.bouncycastle.util.test.TestResult; /** * SHA384 HMac Test */ public class SHA384HMacTest implements Test { final static String[] keys = { "0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b", "4a656665", "aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa", "0102030405060708090a0b0c0d0e0f10111213141516171819", "0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c", "aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa", "aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa" }; final static String[] digests = { "afd03944d84895626b0825f4ab46907f15f9dadbe4101ec682aa034c7cebc59cfaea9ea9076ede7f4af152e8b2fa9cb6", "af45d2e376484031617f78d2b58a6b1b9c7ef464f5a01b47e42ec3736322445e8e2240ca5e69e2c78b3239ecfab21649", "88062608d3e6ad8a0aa2ace014c8a86f0aa635d947ac9febe83ef4e55966144b2a5ab39dc13814b94e3ab6e101a34f27", "3e8a69b7783c25851933ab6290af6ca77a9981480850009cc5577c6e1f573b4e6801dd23c4a7d679ccf8a386c674cffb", "3abf34c3503b2a23a46efc619baef897f4c8e42c934ce55ccbae9740fcbc1af4ca62269e2a37cd88ba926341efe4aeea", "4ece084485813e9088d2c63a041bc5b44f9ef1012a2b588f3cd11f05033ac4c60c2ef6ab4030fe8296248df163f44952", "6617178e941f020d351e2f254e8fd32c602420feb0b8fb9adccebb82461e99c5a678cc31e799176d3860e6110c46523e" }; final static String[] messages = { "Hi There", "what do ya want for nothing?", "0xdddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddd", "0xcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcd", "Test With Truncation", "Test Using Larger Than Block-Size Key - Hash Key First", "This is a test using a larger than block-size key and a larger than block-size data. The key needs to be hashed before being used by the HMAC algorithm." }; public String getName() { return "SHA384HMac"; } public TestResult perform() { HMac hmac = new HMac(new SHA384Digest()); byte[] resBuf = new byte[hmac.getMacSize()]; for (int i = 0; i < messages.length; i++) { byte[] m = messages[i].getBytes(); if (messages[i].startsWith("0x")) { m = Hex.decode(messages[i].substring(2)); } hmac.init(new KeyParameter(Hex.decode(keys[i]))); hmac.update(m, 0, m.length); hmac.doFinal(resBuf, 0); if (!Arrays.areEqual(resBuf, Hex.decode(digests[i]))) { return new SimpleTestResult(false, getName() + ": Vector " + i + " failed got -" + new String(Hex.encode(resBuf))); } } // // test reset // int vector = 0; // vector used for test byte[] m = messages[vector].getBytes(); if (messages[vector].startsWith("0x")) { m = Hex.decode(messages[vector].substring(2)); } hmac.init(new KeyParameter(Hex.decode(keys[vector]))); hmac.update(m, 0, m.length); hmac.doFinal(resBuf, 0); hmac.reset(); hmac.update(m, 0, m.length); hmac.doFinal(resBuf, 0); if (!Arrays.areEqual(resBuf, Hex.decode(digests[vector]))) { return new SimpleTestResult(false, getName() + "Reset with vector " + vector + " failed"); } return new SimpleTestResult(true, getName() + ": Okay"); } public static void main( String[] args) { SHA384HMacTest test = new SHA384HMacTest(); TestResult result = test.perform(); System.out.println(result); } } bouncycastle-1.49.orig/test/src/org/bouncycastle/crypto/test/MD5DigestTest.java0000644000175000017500000000164610330633061027212 0ustar ebourgebourgpackage org.bouncycastle.crypto.test; import org.bouncycastle.crypto.Digest; import org.bouncycastle.crypto.digests.MD5Digest; /** * standard vector test for MD5 from "Handbook of Applied Cryptography", page 345. */ public class MD5DigestTest extends DigestTest { static final String[] messages = { "", "a", "abc", "abcdefghijklmnopqrstuvwxyz" }; static final String[] digests = { "d41d8cd98f00b204e9800998ecf8427e", "0cc175b9c0f1b6a831c399e269772661", "900150983cd24fb0d6963f7d28e17f72", "c3fcd3d76192e4007dfb496cca67e13b" }; MD5DigestTest() { super(new MD5Digest(), messages, digests); } protected Digest cloneDigest(Digest digest) { return new MD5Digest((MD5Digest)digest); } public static void main( String[] args) { runTest(new MD5DigestTest()); } } bouncycastle-1.49.orig/test/src/org/bouncycastle/crypto/test/ElGamalTest.java0000644000175000017500000002272611163320603026771 0ustar ebourgebourgpackage org.bouncycastle.crypto.test; import org.bouncycastle.crypto.AsymmetricCipherKeyPair; import org.bouncycastle.crypto.DataLengthException; import org.bouncycastle.crypto.engines.ElGamalEngine; import org.bouncycastle.crypto.generators.ElGamalKeyPairGenerator; import org.bouncycastle.crypto.generators.ElGamalParametersGenerator; import org.bouncycastle.crypto.params.ElGamalKeyGenerationParameters; import org.bouncycastle.crypto.params.ElGamalParameters; import org.bouncycastle.crypto.params.ElGamalPrivateKeyParameters; import org.bouncycastle.crypto.params.ElGamalPublicKeyParameters; import org.bouncycastle.crypto.params.ParametersWithRandom; import org.bouncycastle.util.test.SimpleTest; import org.bouncycastle.util.encoders.Hex; import org.bouncycastle.util.Arrays; import java.math.BigInteger; import java.security.SecureRandom; public class ElGamalTest extends SimpleTest { private BigInteger g512 = new BigInteger("153d5d6172adb43045b68ae8e1de1070b6137005686d29d3d73a7749199681ee5b212c9b96bfdcfa5b20cd5e3fd2044895d609cf9b410b7a0f12ca1cb9a428cc", 16); private BigInteger p512 = new BigInteger("9494fec095f3b85ee286542b3836fc81a5dd0a0349b4c239dd38744d488cf8e31db8bcb7d33b41abb9e5a33cca9144b1cef332c94bf0573bf047a3aca98cdf3b", 16); private BigInteger g768 = new BigInteger("7c240073c1316c621df461b71ebb0cdcc90a6e5527e5e126633d131f87461c4dc4afc60c2cb0f053b6758871489a69613e2a8b4c8acde23954c08c81cbd36132cfd64d69e4ed9f8e51ed6e516297206672d5c0a69135df0a5dcf010d289a9ca1", 16); private BigInteger p768 = new BigInteger("8c9dd223debed1b80103b8b309715be009d48860ed5ae9b9d5d8159508efd802e3ad4501a7f7e1cfec78844489148cd72da24b21eddd01aa624291c48393e277cfc529e37075eccef957f3616f962d15b44aeab4039d01b817fde9eaa12fd73f", 16); private BigInteger g1024 = new BigInteger("1db17639cdf96bc4eabba19454f0b7e5bd4e14862889a725c96eb61048dcd676ceb303d586e30f060dbafd8a571a39c4d823982117da5cc4e0f89c77388b7a08896362429b94a18a327604eb7ff227bffbc83459ade299e57b5f77b50fb045250934938efa145511166e3197373e1b5b1e52de713eb49792bedde722c6717abf", 16); private BigInteger p1024 = new BigInteger("a00e283b3c624e5b2b4d9fbc2653b5185d99499b00fd1bf244c6f0bb817b4d1c451b2958d62a0f8a38caef059fb5ecd25d75ed9af403f5b5bdab97a642902f824e3c13789fed95fa106ddfe0ff4a707c85e2eb77d49e68f2808bcea18ce128b178cd287c6bc00efa9a1ad2a673fe0dceace53166f75b81d6709d5f8af7c66bb7", 16); private BigInteger yPgpBogusPSamp = new BigInteger("de4688497cc05b45fe8559bc9918c45afcad69b74123a7236eba409fd9de8ea34c7869839ee9df35e3d97576145d089841aa65b5b4e061fae52c37e430354269a02496b8ed8456f2d0d7c9b0db985fbcb21ae9f78507ed6e3a29db595b201b1a4f931c7d791eede65ccf918e8a61cf146859151c78c41ad48853694623467d78", 16); private BigInteger xPgpBogusPSamp = new BigInteger("cbaf780f2cfe4f987bbc5fcb0738bbd7912060ccfdf37cbfeea65c0fd857e74a8df6cc359375f28cf5725d081813c614410a78cbe4b06d677beea9ff0fa10b1dbc47a6ed8c5b8466d6a95d6574029dbdf72596392e1b6b230faf9916dc8455821c10527a375a4d1c8a54947d1fe714d321aca25ad486b4b456506999fd2fd11a", 16); private BigInteger gPgpBogusPSamp = new BigInteger("153ffe9522076d1cbd6e75f0816a0fc2ebd8b0e0091406587387a1763022088a03b411eed07ff50efb82b21f1608c352d10f63ba7e7e981a2f3387cec8af2915953d00493857663ae8919f517fe90f1d2abe7af4305a344b10d1a25d75f65902cd7fd775853d3ac43d7c5253ad666e1e63ee98cdcb10af81273d4ff053ff07d51", 16); private BigInteger pPgpBogusPSamp = new BigInteger("15061b26cdab4e865098a01c86f13b03220104c5443e950658b36b85245aa0c616a0c0d8d99c454bea087c172315e45b3bc9b925443948a2b6ba47608a6035b9a79a4ef34a78d7274a12ede8364f02d5030db864988643d7e92753df603bd69fbd2682ab0af64d1a866d1131a2cb13333cedb0a9e6eefddd9fff8154d34c2daab", 16); private int lPgpBogusPSamp = 0; public String getName() { return "ElGamal"; } private void testEnc( int size, int privateValueSize, BigInteger g, BigInteger p) { ElGamalParameters dhParams = new ElGamalParameters(p, g, privateValueSize); ElGamalKeyGenerationParameters params = new ElGamalKeyGenerationParameters(new SecureRandom(), dhParams); ElGamalKeyPairGenerator kpGen = new ElGamalKeyPairGenerator(); kpGen.init(params); // // generate pair // AsymmetricCipherKeyPair pair = kpGen.generateKeyPair(); ElGamalPublicKeyParameters pu = (ElGamalPublicKeyParameters)pair.getPublic(); ElGamalPrivateKeyParameters pv = (ElGamalPrivateKeyParameters)pair.getPrivate(); checkKeySize(privateValueSize, pv); ElGamalEngine e = new ElGamalEngine(); e.init(true, pu); if (e.getOutputBlockSize() != size / 4) { fail(size + " getOutputBlockSize() on encryption failed."); } byte[] message = Hex.decode("5468697320697320612074657374"); byte[] pText = message; byte[] cText = e.processBlock(pText, 0, pText.length); e.init(false, pv); if (e.getOutputBlockSize() != (size / 8) - 1) { fail(size + " getOutputBlockSize() on decryption failed."); } pText = e.processBlock(cText, 0, cText.length); if (!Arrays.areEqual(message, pText)) { fail(size + " bit test failed"); } e.init(true, pu); byte[] bytes = new byte[e.getInputBlockSize() + 2]; try { e.processBlock(bytes, 0, bytes.length); fail("out of range block not detected"); } catch (DataLengthException ex) { // expected } try { bytes[0] = (byte)0xff; e.processBlock(bytes, 0, bytes.length - 1); fail("out of range block not detected"); } catch (DataLengthException ex) { // expected } try { bytes[0] = (byte)0x7f; e.processBlock(bytes, 0, bytes.length - 1); } catch (DataLengthException ex) { fail("in range block failed"); } } private void checkKeySize( int privateValueSize, ElGamalPrivateKeyParameters priv) { if (privateValueSize != 0) { if (priv.getX().bitLength() != privateValueSize) { fail("limited key check failed for key size " + privateValueSize); } } } /** * this test is can take quiet a while * * @param size size of key in bits. */ private void testGeneration( int size) { ElGamalParametersGenerator pGen = new ElGamalParametersGenerator(); pGen.init(size, 10, new SecureRandom()); ElGamalParameters elParams = pGen.generateParameters(); if (elParams.getL() != 0) { fail("ElGamalParametersGenerator failed to set L to 0 in generated ElGamalParameters"); } ElGamalKeyGenerationParameters params = new ElGamalKeyGenerationParameters(new SecureRandom(), elParams); ElGamalKeyPairGenerator kpGen = new ElGamalKeyPairGenerator(); kpGen.init(params); // // generate first pair // AsymmetricCipherKeyPair pair = kpGen.generateKeyPair(); ElGamalPublicKeyParameters pu = (ElGamalPublicKeyParameters)pair.getPublic(); ElGamalPrivateKeyParameters pv = (ElGamalPrivateKeyParameters)pair.getPrivate(); ElGamalEngine e = new ElGamalEngine(); e.init(true, new ParametersWithRandom(pu, new SecureRandom())); byte[] message = Hex.decode("5468697320697320612074657374"); byte[] pText = message; byte[] cText = e.processBlock(pText, 0, pText.length); e.init(false, pv); pText = e.processBlock(cText, 0, cText.length); if (!Arrays.areEqual(message, pText)) { fail("generation test failed"); } } private void testInitCheck() { try { new ElGamalEngine().processBlock(new byte[]{ 1 }, 0, 1); fail("failed initialisation check"); } catch (IllegalStateException e) { // expected } } private void testInvalidP() { ElGamalParameters dhParams = new ElGamalParameters(pPgpBogusPSamp, gPgpBogusPSamp, lPgpBogusPSamp); ElGamalPublicKeyParameters pu = new ElGamalPublicKeyParameters(yPgpBogusPSamp, dhParams); ElGamalPrivateKeyParameters pv = new ElGamalPrivateKeyParameters(xPgpBogusPSamp, dhParams); ElGamalEngine e = new ElGamalEngine(); e.init(true, pu); byte[] message = Hex.decode("5468697320697320612074657374"); byte[] pText = message; byte[] cText = e.processBlock(pText, 0, pText.length); e.init(false, pv); pText = e.processBlock(cText, 0, cText.length); if (Arrays.areEqual(message, pText)) { fail("invalid test failed"); } } public void performTest() { testInvalidP(); testEnc(512, 0, g512, p512); testEnc(768, 0, g768, p768); testEnc(1024, 0, g1024, p1024); testEnc(512, 64, g512, p512); testEnc(768, 128, g768, p768); // // generation test. // testGeneration(258); testInitCheck(); } public static void main( String[] args) { runTest(new ElGamalTest()); } } bouncycastle-1.49.orig/test/src/org/bouncycastle/crypto/test/GOST3411DigestTest.java0000644000175000017500000000406111431177644027721 0ustar ebourgebourgpackage org.bouncycastle.crypto.test; import org.bouncycastle.crypto.Digest; import org.bouncycastle.crypto.digests.GOST3411Digest; public class GOST3411DigestTest extends DigestTest { private static final String[] messages = { "", "This is message, length=32 bytes", "Suppose the original message has length = 50 bytes", "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789" }; // If S-box = D-A (see: digest/GOST3411Digest.java; function: E(byte[] in, byte[] key); string: CipherParameters param = new GOST28147Parameters(key,"D-A");) private static final String[] digests = { "981e5f3ca30c841487830f84fb433e13ac1101569b9c13584ac483234cd656c0", "2cefc2f7b7bdc514e18ea57fa74ff357e7fa17d652c75f69cb1be7893ede48eb", "c3730c5cbccacf915ac292676f21e8bd4ef75331d9405e5f1a61dc3130a65011", "73b70a39497de53a6e08c67b6d4db853540f03e9389299d9b0156ef7e85d0f61" }; // If S-box = D-Test (see: digest/GOST3411Digest.java; function:E(byte[] in, byte[] key); string: CipherParameters param = new GOST28147Parameters(key,"D-Test");) // private static final String[] digests = // { // "ce85b99cc46752fffee35cab9a7b0278abb4c2d2055cff685af4912c49490f8d", // "b1c466d37519b82e8319819ff32595e047a28cb6f83eff1c6916a815a637fffa", // "471aba57a60a770d3a76130635c1fbea4ef14de51f78b4ae57dd893b62f55208", // "95c1af627c356496d80274330b2cff6a10c67b5f597087202f94d06d2338cf8e" // }; // 1 million 'a' static private String million_a_digest = "8693287aa62f9478f7cb312ec0866b6c4e4a0f11160441e8f4ffcd2715dd554f"; GOST3411DigestTest() { super(new GOST3411Digest(), messages, digests); } public void performTest() { super.performTest(); millionATest(million_a_digest); } protected Digest cloneDigest(Digest digest) { return new GOST3411Digest((GOST3411Digest)digest); } public static void main( String[] args) { runTest(new GOST3411DigestTest()); } } bouncycastle-1.49.orig/test/src/org/bouncycastle/crypto/test/SipHashTest.java0000644000175000017500000000330112151552117027017 0ustar ebourgebourgpackage org.bouncycastle.crypto.test; import org.bouncycastle.crypto.macs.SipHash; import org.bouncycastle.crypto.params.KeyParameter; import org.bouncycastle.crypto.util.Pack; import org.bouncycastle.util.encoders.Hex; import org.bouncycastle.util.test.SimpleTest; /* * SipHash test values from "SipHash: a fast short-input PRF", by Jean-Philippe * Aumasson and Daniel J. Bernstein (https://131002.net/siphash/siphash.pdf), Appendix A. */ public class SipHashTest extends SimpleTest { public String getName() { return "SipHash"; } public void performTest() throws Exception { byte[] key = Hex.decode("000102030405060708090a0b0c0d0e0f"); byte[] input = Hex.decode("000102030405060708090a0b0c0d0e"); long expected = 0xa129ca6149be45e5L; SipHash mac = new SipHash(); mac.init(new KeyParameter(key)); mac.update(input, 0, input.length); long result = mac.doFinal(); if (expected != result) { fail("Result does not match expected value for doFinal()"); } byte[] expectedBytes = new byte[8]; Pack.longToLittleEndian(expected, expectedBytes, 0); mac.update(input, 0, input.length); byte[] output = new byte[mac.getMacSize()]; int len = mac.doFinal(output, 0); if (len != output.length) { fail("Result length does not equal getMacSize() for doFinal(byte[],int)"); } if (!areEqual(expectedBytes, output)) { fail("Result does not match expected value for doFinal(byte[],int)"); } } public static void main(String[] args) { runTest(new SipHashTest()); } } bouncycastle-1.49.orig/test/src/org/bouncycastle/crypto/test/ISAACTest.java0000644000175000017500000002417610610672512026315 0ustar ebourgebourgpackage org.bouncycastle.crypto.test; import org.bouncycastle.crypto.engines.ISAACEngine; import org.bouncycastle.crypto.params.KeyParameter; import org.bouncycastle.util.encoders.Hex; import org.bouncycastle.util.test.SimpleTest; /** * ISAAC Test - see http://www.burtleburtle.net/bob/rand/isaacafa.html */ public class ISAACTest extends SimpleTest { byte[] out = Hex.decode( "f650e4c8e448e96d98db2fb4f5fad54f433f1afbedec154ad837048746ca4f9a" + "5de3743e88381097f1d444eb823cedb66a83e1e04a5f6355c744243325890e2e" + "7452e31957161df638a824f3002ed71329f5544951c08d83d78cb99ea0cc74f3" + "8f651659cbc8b7c2f5f71c6912ad6419e5792e1b860536b809b3ce98d45d6d81" + "f3b2612917e38f8529cf72ce349947b0c998f9ffb5e13dae32ae2a2bf7cf814c" + "8ebfa303cf22e0640b923200eca4d58aef53cec4d0f7b37d9c411a2affdf8a80" + "b40e27bcb4d2f97644b89b08f37c71d51a70e7e90bdb9c3060dc5207b3c3f24b" + "d7386806229749b54e232cd091dabc65a70e11018b87437e5781414fcdbc62e2" + "8107c9ff69d2e4ae3b18e752b143b6886f4e077295138769943c3c74afc17a97" + "0fd439636a529b0bd8c58a6aa8bcc22d2db35dfea7a2f4026cb167db538e1f4e" + "7275e2771d3b8e97ecc5dc9115e3a5b90369661430ab93ecac9fe69d7bc76811" + "60eda8da28833522d5295ebc5adb60e7f7e1cdd097166d14b67ec13a210f3925" + "64af0fef0d0286843aea3decb058bafbb8b0ccfcf2b5cc05e3a662d9814bc24c" + "2364a1aa37c0ed052b36505c451e7ec85d2a542fe43d0fbb91c8d92560d4d5f8" + "12a0594b9e8a51dacd49ebdb1b0dcdc1cd57c7f7e63444517ded386f2f36fa86" + "a6d1210133bc405db388d96cdb6dbe96fe29661c13edc0cbcb0eee4a70cc94ae" + "de11ed340606cf9f3a6ce38923d74f4ea37f63ff917bdec2d73f72d40e7e0e67" + "3d77d9a213add9228891b3db01a9bd7056a001e3d51f093dcc033ce35ad0d3b0" + "34105a8c6a123f57bd2e50247364944be89b1a3b21835c4d9f39e2d9d405ded8" + "294d37e5bccaaeed35a124b56708a2bcb00960ba2a98121a4d8fae820bb3263f" + "12595a196a1075890809e49421c171ec884d682514c8009bb0b84e7b03fb88f4" + "28e7cb789388b13bdd2dc1d5848f520a07c28cd168a3935872c9137d127dd430" + "c613f1578c2f0d55f7d3f39f309bfb788406b13746c0a6f53718d59708607f04" + "76904b6d04db4e13cd7411a7b510ce0ebfc7f7ccb83f957afdfef62dc35e4580" + "3ff1e5244112d96c02c9b944d5990dfbe7e265810d9c7e7e826dfa8966f1e0ab" + "30bcc764eadebeaced35e5ee0c571a7de4f3a26af7f58f7badf6bc235d023e65" + "1ed3ff4eec46b0b6d2a93b51e75b41c97e315aeb61119a5a53245b7933f6d7b1" + "cae8deba50fc8194afa92a6dc87c80064188bfcd8bace62e78ffa5685597ec0f" + "b4415f7d08294766ad56764309c36f903dde9f394a0a283c18080c8e080c79ec" + "79ae4c10cb9e15637cdd662f62d31911a4ca0cf15cf824cd3b708f991e16614c" + "b6b9d7665de87abb7229ea81d5b2d75056e6cd21fe1e42d596da2655c2b9aa36" + "b8f6fd4a6a158d1001913fd3af7d1fb80b5e435f90c107576554abda7a68710f" + "82ac484fd7e1c7be95c85eaa94a302f44d3cfbda786b29081010b27582d53d12" + "21e2a51c3d1e9150b059261dd0638e1a31860f0581f2864dff4cfc350451516d" + "bd086f26bc5654c165dfa427a82427f5582e3014b8d2486dc79a17499a1d7745" + "8766bb541e04a7f73d3dff8ad5ec6bf4dbef7d9f36ec0ea31feb2e4f15cfcc5c" + "d8c423fbd0ef3cc9eb244925ba5590c8a5f48ac433c5321c613b67b2479c3a22" + "e21339cc10d210aa931dd7e2ef05ee06b82f2703a385cb2c5d67133c877eb7b4" + "1e3437f75afb43ae53c078f394d904811d96458908063a85e13222281956b1e5" + "31860f132e7b022f21182ca396f703ac46819e2e0d28fe523724d4dca0eabe6b" + "c66699fdc6112fdd19c1e69c04d3658a4b55dd9931907d62f854b5224d678f26" + "22ae0582eafed133e4a51d2184bd6dd6c1a513753f28ee63fb737b1a70a1660e" + "8a8dfaa31be79937f7476978513c1764531ac6bf12c06908001cdb951a4b6a53" + "d067fce512b2cfb69ddb477f740e006639ddf25acc8bfa2df1b20eaf64f2632c" + "9783cdee63bfd4d80084cfe575f4e9e219b48fd06c48ddd87a36af9371865c4c" + "9ce0199d867027d72cb7b77f84ef01da72f5972f040f7074df9afa29c921f94e" + "75c08a3618c1ef9ad649a428c5b719378a30738ad97cd348858129a6239e3b0a" + "bbb8abc480fac4c2ecfcf20bd9d711f9e2a4ef71b5fe87c0be8b06b2aafef5a7" + "9c15db3b0aeb81654389a84a253b1d7a19047c797cdc78a2d20adf0356f55a71" + "3e730fa8fd8650d8959e234eb7546681dad1b22a142a6e858ef4bce668235b9d" + "85a13f8574096ae7a949bea229322d0dd568385882846526403dae086dd1943a" + "e1279bff9e7e4f041c3a4524484525e481d4cc5fe24124c0037464c0bf1bd691" + "26ceb003275ead3ac5bde90826414ff3a30519add7b43abe2ce5d3d588412761" + "97ca2070e5fbb9c7276df0b4308f751f37a97df6c9cd808cfe4cb3803d469303" + "aee19096c0d5d42a4e823ad3f5f9cc3b4286619c9ca45e1c66c97340891aec49" + "45bae606c798f04752649d6cce86fdfc80c6e402d6ec2f2b27c822821fe26ce0" + "92f57ea7de462f4d07497cae5a48755c721502dd6cbe7935836d80039ead7f70" + "9ab3a42f4c8652d632e39273e8fa38601da4f25a0cd6ef8102503f7d8854a0a1" + "9a30c4e88815715305efe29457c4c9252887d96fc1a71e3ce9f841632d0985de" + "d21e796c6fb5ce5602614abfc3c7be2cb54fed6fa617a083c3142d8f6079e4ce" + "ceffc1471d0cb81bdc153e5fe36ef5bbd531161a165b10157aa114ed3f7579b3" + "f7f395f1bc6172c7a86f875e0e6c51b3cdfec2af73c0e762824c2009c5a87748" + "94d401258aba3ffbd32be0608c17eff021e2547e07cffad905340e15f3310c92" + "9d8d190886ba527ff943f672ef73fbf046d95ca5c54cd95b9d855e894bb5af29"); byte[] outFFFFFFFF = Hex.decode( "de3b3f3c19e0629c1fc8b7836695d523e7804edd86ff7ce9b106f52caebae9d9" + "72f845d49ce17d7da44e49bae954aac0d0b1284b98a88eec1524fb6bc91a16b5" + "1192ac5334131446ac2442de9ff3d5867b9b9148881ee30a6e87dd88e5d1f7cd" + "98db31ff36f70d9850cfefaef42abb00ecc39ed308bf4b8030cdc2b6b7e42f0e" + "908030dd282f96edacc888b3a986e109c129998f89baa1b5da8970b07a6ab012" + "f10264f23c315c9c8e0c164955c68517b6a4f982b2626db70787f869ac6d551b" + "e34931627c7058e965c502e18d2cd370e6db3b70d947d61aa9717cf8394f48c6" + "3c796f3a154950846badb28b70d982f29bc670254e3e5e0f8e36b0a5f6da0a04" + "6b235ed6a42988c012bde74d879fa8eb5d59f5f40ed5e76601c9847b3edb2690"); byte[] outFFFF0000 = Hex.decode( "26c54b1f8c4e3fc582e9e8180f7aba5380463dcf58b03cbeda0ecc8ba90ccff8" + "5bd50896313d7efed44015faeac6964b241a7fb8a2e37127a7cbea0fd7c020f2" + "406371b87ef5185089504751e5e44352eff63e00e5c28f5dff0616a9a3a00f1f" + "4a1350e3a17be9abddfc2c94571450a0dc4c3c0c7c7f98e80c95f607d50c676a" + "9a3006f9d279a79a4d66b2ab0c52930c9ee84bc09895e70fa041b1a3a2966f11" + "6a47fd09705124b1f5c7ae055e54536e66584b1608f3612d81b72f109a385831" + "121945b207b90ac72437a248f27a121c2801f4153a8699fb047e193f7ba69e1b" + "b117869675d4c963e6070c2ca3d332ce830cb5e3d9ed2eee7faf0acc20fbe154" + "188ae789e95bd5c1f459dbd150aab6eb833170257084bc5d44e9df09f5624f9d" + "afecd0c9340ac8587f8625d343f7efd1cc8abcf7a6f90eabd4e8e2d906278d6e" + "431fcade165c8c467887fbf5c26d341557b064b98c60dd40ab262dc046d69647" + "56f3ddc1a07ae5f87be878b9334fcde40add68d2ca1dc05fb1670f998c7c4607" + "9a6e48bdb330ad8d30b61b5cc8dc156f5733905931949783f89ac396b65aa4b8" + "51f746b53ed8ea66130e1d75e8eab136e60450e3e600226bc8e17d03744ce94c" + "0eec9234fea5f18eef65d81f2f10cfbc0b112b8cde17c32eb33ed81d7356eac3" + "eb1cb9cefa6604c2d707949b6e5a83e60705bf6aae76dcc7d35d68ff149c1ac5" + "424bb4a39e2f496f886637fce3db4ba4ad12c1a32d25e1606f6635ff636486f6" + "714997b45477f38813c02afce4bebf196b813332f0decd567c745f441e736364"); byte[] out0000FFFF = Hex.decode( "bc31712f2a2f467a5abc737c57ce0f8d49d2f775eb850fc8f856daf19310fee2"+ "5bab40e78403c9ef4ccd971418992faf4e85ca643fa6b482f30c4659066158a6"+ "5bc3e620ba7ea5c34dd0eac5aabb2cf078d915fd1f8c437ed00423076c10f701"+ "eefa7fc7c461aca5db8a87be29d925c4212d4adcfa71ff5b06af15c048aa0dfd"+ "f0e645bc09fea200c430a88eb38c466ff358b836f1159656a078f6fc752f6db1"+ "6680bb30fc771a6a785bbb2298e947d7b3500e557775962248bedf4e82c16e66"+ "f39283ccb95e5399061056a11c4a280f00f7487888199487905273c7aa13012b"+ "4849eca626cbf071c782e084f9fded57de92313e5f61a6e81117fb1115eff275"+ "66fd5c755bb3b01bba69aeb8f1b1b1cc9709734be31b35bc707d372ba6fe70d1"+ "e2c3b0e5e74a7058faff6b11d3a168f19fecc9fcb36b3e6a5f828c01c22ac0c2"+ "5da2a3a9eec7e0ebbbf51472e430ed4cf1c7ab57ef9aea511e40250846d260b6"+ "17a3fdeba16cf4afaf700144d3296b58b22a3c79ed96f3e2fc8d9e3c660ae153"+ "8e0c285ccdc48b59117e80413bd0ad24c6a8d4f133fe1496f14351bb89904fa5"+ "e10c4b8d50e0604578389c336a9ab3d292beb90ce640fc028e697cf54e021e2f"+ "c0ca3fe0471fde5e5462f221739a74f5a13ae0621fe2a82e752bc294f63de48d"+ "e85430af71307a30441b861ab5380e6a6dbe1251c9baa567da14e38e5a0ccddf"+ "0127205c38fc3b77065e98101d219246103438d223ec7f8f533d4bb3a3d3407a"+ "944910f11e8e5492e86de7a0471250eca32f0838b3db02fffe71898712af3261"); public String getName() { return "ISAAC"; } public void performTest() { ISAACEngine engine = new ISAACEngine(); doTest(engine, Hex.decode("00000000"), out); doTest(engine, Hex.decode("ffffffff"), outFFFFFFFF); byte[] k = new byte[256 * 4]; for (int i = 0; i != k.length; i++) { k[i] = (byte)((i % 4 == 0 || i % 4 == 1) ? 0xff : 0x00); } doTest(engine, k, outFFFF0000); k = new byte[256 * 4]; for (int i = 0; i != k.length; i++) { k[i] = (byte)((i % 4 == 2 || i % 4 == 3) ? 0xff : 0x00); } doTest(engine, k, out0000FFFF); } private void doTest(ISAACEngine engine, byte[] key, byte[] output) { byte[] in = new byte[output.length]; byte[] enc = new byte[output.length]; engine.init(true, new KeyParameter(key)); engine.processBytes(in, 0, in.length, enc, 0); if (!areEqual(enc, output)) { fail("ciphertext mismatch"); } engine.init(false, new KeyParameter(key)); engine.processBytes(enc, 0, enc.length, enc, 0); if (!areEqual(enc, in)) { fail("plaintext mismatch"); } } public static void main( String[] args) { runTest(new ISAACTest()); } } bouncycastle-1.49.orig/test/src/org/bouncycastle/crypto/test/SHA224DigestTest.java0000644000175000017500000000250210330633061027460 0ustar ebourgebourgpackage org.bouncycastle.crypto.test; import org.bouncycastle.crypto.Digest; import org.bouncycastle.crypto.digests.SHA224Digest; /** * standard vector test for SHA-224 from RFC 3874 - only the last three are in * the RFC. */ public class SHA224DigestTest extends DigestTest { private static String[] messages = { "", "a", "abc", "abcdbcdecdefdefgefghfghighijhijkijkljklmklmnlmnomnopnopq" }; private static String[] digests = { "d14a028c2a3a2bc9476102bb288234c415a2b01f828ea62ac5b3e42f", "abd37534c7d9a2efb9465de931cd7055ffdb8879563ae98078d6d6d5", "23097d223405d8228642a477bda255b32aadbce4bda0b3f7e36c9da7", "75388b16512776cc5dba5da1fd890150b0c6455cb4f58b1952522525" }; // 1 million 'a' static private String million_a_digest = "20794655980c91d8bbb4c1ea97618a4bf03f42581948b2ee4ee7ad67"; SHA224DigestTest() { super(new SHA224Digest(), messages, digests); } public void performTest() { super.performTest(); millionATest(million_a_digest); } protected Digest cloneDigest(Digest digest) { return new SHA224Digest((SHA224Digest)digest); } public static void main( String[] args) { runTest(new SHA224DigestTest()); } } bouncycastle-1.49.orig/test/src/org/bouncycastle/crypto/test/SHA1HMacTest.java0000644000175000017500000000774412145535651026733 0ustar ebourgebourgpackage org.bouncycastle.crypto.test; import org.bouncycastle.crypto.digests.SHA1Digest; import org.bouncycastle.crypto.macs.HMac; import org.bouncycastle.crypto.params.KeyParameter; import org.bouncycastle.util.Arrays; import org.bouncycastle.util.encoders.Hex; import org.bouncycastle.util.test.SimpleTestResult; import org.bouncycastle.util.test.Test; import org.bouncycastle.util.test.TestResult; /** * SHA1 HMac Test, test vectors from RFC 2202 */ public class SHA1HMacTest implements Test { final static String[] keys = { "0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b", "4a656665", "aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa", "0102030405060708090a0b0c0d0e0f10111213141516171819", "0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c", "aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa", "aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa", "000102030405060708090A0B0C0D0E0F101112131415161718191A1B1C1D1E1F202122232425262728292A2B2C2D2E2F303132333435363738393A3B3C3D3E3F" }; final static String[] digests = { "b617318655057264e28bc0b6fb378c8ef146be00", "effcdf6ae5eb2fa2d27416d5f184df9c259a7c79", "125d7342b9ac11cd91a39af48aa17b4f63f175d3", "4c9007f4026250c6bc8414f9bf50c86c2d7235da", "4c1a03424b55e07fe7f27be1d58bb9324a9a5a04", "aa4ae5e15272d00e95705637ce8a3b55ed402112", "e8e99d0f45237d786d6bbaa7965c7808bbff1a91", "5FD596EE78D5553C8FF4E72D266DFD192366DA29" }; final static String[] messages = { "Hi There", "what do ya want for nothing?", "0xdddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddd", "0xcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcd", "Test With Truncation", "Test Using Larger Than Block-Size Key - Hash Key First", "Test Using Larger Than Block-Size Key and Larger Than One Block-Size Data", "Sample message for keylen=blocklen" }; public String getName() { return "SHA1HMac"; } public TestResult perform() { HMac hmac = new HMac(new SHA1Digest()); byte[] resBuf = new byte[hmac.getMacSize()]; for (int i = 0; i < messages.length; i++) { byte[] m = messages[i].getBytes(); if (messages[i].startsWith("0x")) { m = Hex.decode(messages[i].substring(2)); } hmac.init(new KeyParameter(Hex.decode(keys[i]))); hmac.update(m, 0, m.length); hmac.doFinal(resBuf, 0); if (!Arrays.areEqual(resBuf, Hex.decode(digests[i]))) { return new SimpleTestResult(false, getName() + ": Vector " + i + " failed"); } } // // test reset // int vector = 0; // vector used for test byte[] m = messages[vector].getBytes(); if (messages[vector].startsWith("0x")) { m = Hex.decode(messages[vector].substring(2)); } hmac.init(new KeyParameter(Hex.decode(keys[vector]))); hmac.update(m, 0, m.length); hmac.doFinal(resBuf, 0); hmac.reset(); hmac.update(m, 0, m.length); hmac.doFinal(resBuf, 0); if (!Arrays.areEqual(resBuf, Hex.decode(digests[vector]))) { return new SimpleTestResult(false, getName() + "Reset with vector " + vector + " failed"); } return new SimpleTestResult(true, getName() + ": Okay"); } public static void main( String[] args) { SHA1HMacTest test = new SHA1HMacTest(); TestResult result = test.perform(); System.out.println(result); } } bouncycastle-1.49.orig/test/src/org/bouncycastle/crypto/test/BlockCipherVectorTest.java0000644000175000017500000000361511447527724031055 0ustar ebourgebourgpackage org.bouncycastle.crypto.test; import org.bouncycastle.crypto.BlockCipher; import org.bouncycastle.crypto.BufferedBlockCipher; import org.bouncycastle.crypto.CipherParameters; import org.bouncycastle.util.encoders.Hex; import org.bouncycastle.util.test.SimpleTest; /** * a basic test that takes a cipher, key parameter, and an input * and output string. This test wraps the engine in a buffered block * cipher with padding disabled. */ public class BlockCipherVectorTest extends SimpleTest { int id; BlockCipher engine; CipherParameters param; byte[] input; byte[] output; public BlockCipherVectorTest( int id, BlockCipher engine, CipherParameters param, String input, String output) { this.id = id; this.engine = engine; this.param = param; this.input = Hex.decode(input); this.output = Hex.decode(output); } public String getName() { return engine.getAlgorithmName() + " Vector Test " + id; } public void performTest() throws Exception { BufferedBlockCipher cipher = new BufferedBlockCipher(engine); cipher.init(true, param); byte[] out = new byte[input.length]; int len1 = cipher.processBytes(input, 0, input.length, out, 0); cipher.doFinal(out, len1); if (!areEqual(out, output)) { fail("failed - " + "expected " + new String(Hex.encode(output)) + " got " + new String(Hex.encode(out))); } cipher.init(false, param); int len2 = cipher.processBytes(output, 0, output.length, out, 0); cipher.doFinal(out, len2); if (!areEqual(input, out)) { fail("failed reversal got " + new String(Hex.encode(out))); } } } bouncycastle-1.49.orig/test/src/org/bouncycastle/crypto/test/IDEATest.java0000644000175000017500000000213210525306762026171 0ustar ebourgebourgpackage org.bouncycastle.crypto.test; import org.bouncycastle.crypto.engines.IDEAEngine; import org.bouncycastle.crypto.params.KeyParameter; import org.bouncycastle.util.encoders.Hex; import org.bouncycastle.util.test.SimpleTest; /** */ public class IDEATest extends CipherTest { static SimpleTest[] tests = { new BlockCipherVectorTest(0, new IDEAEngine(), new KeyParameter(Hex.decode("00112233445566778899AABBCCDDEEFF")), "000102030405060708090a0b0c0d0e0f", "ed732271a7b39f475b4b2b6719f194bf"), new BlockCipherVectorTest(0, new IDEAEngine(), new KeyParameter(Hex.decode("00112233445566778899AABBCCDDEEFF")), "f0f1f2f3f4f5f6f7f8f9fafbfcfdfeff", "b8bc6ed5c899265d2bcfad1fc6d4287d") }; IDEATest() { super(tests, new IDEAEngine(), new KeyParameter(new byte[32])); } public String getName() { return "IDEA"; } public static void main( String[] args) { runTest(new IDEATest()); } } bouncycastle-1.49.orig/test/src/org/bouncycastle/crypto/test/RC2Test.java0000644000175000017500000000434410330633061026051 0ustar ebourgebourgpackage org.bouncycastle.crypto.test; import org.bouncycastle.crypto.engines.RC2Engine; import org.bouncycastle.crypto.params.KeyParameter; import org.bouncycastle.crypto.params.RC2Parameters; import org.bouncycastle.util.encoders.Hex; /** * RC2 tester - vectors from ftp://ftp.isi.edu/in-notes/rfc2268.txt * * RFC 2268 "A Description of the RC2(r) Encryption Algorithm" */ public class RC2Test extends CipherTest { static BlockCipherVectorTest[] tests = { new BlockCipherVectorTest(0, new RC2Engine(), new RC2Parameters(Hex.decode("0000000000000000"), 63), "0000000000000000", "ebb773f993278eff"), new BlockCipherVectorTest(1, new RC2Engine(), new RC2Parameters(Hex.decode("ffffffffffffffff"), 64), "ffffffffffffffff", "278b27e42e2f0d49"), new BlockCipherVectorTest(2, new RC2Engine(), new RC2Parameters(Hex.decode("3000000000000000"), 64), "1000000000000001", "30649edf9be7d2c2"), new BlockCipherVectorTest(3, new RC2Engine(), new RC2Parameters(Hex.decode("88"), 64), "0000000000000000", "61a8a244adacccf0"), new BlockCipherVectorTest(4, new RC2Engine(), new RC2Parameters(Hex.decode("88bca90e90875a"), 64), "0000000000000000", "6ccf4308974c267f"), new BlockCipherVectorTest(5, new RC2Engine(), new RC2Parameters(Hex.decode("88bca90e90875a7f0f79c384627bafb2"), 64), "0000000000000000", "1a807d272bbe5db1"), new BlockCipherVectorTest(6, new RC2Engine(), new RC2Parameters(Hex.decode("88bca90e90875a7f0f79c384627bafb2"), 128), "0000000000000000", "2269552ab0f85ca6"), new BlockCipherVectorTest(7, new RC2Engine(), new RC2Parameters(Hex.decode("88bca90e90875a7f0f79c384627bafb216f80a6f85920584c42fceb0be255daf1e"), 129), "0000000000000000", "5b78d3a43dfff1f1") }; RC2Test() { super(tests, new RC2Engine(), new KeyParameter(new byte[16])); } public String getName() { return "RC2"; } public static void main( String[] args) { runTest(new RC2Test()); } } bouncycastle-1.49.orig/test/src/org/bouncycastle/crypto/test/ResetTest.java0000644000175000017500000000524511447531537026565 0ustar ebourgebourgpackage org.bouncycastle.crypto.test; import org.bouncycastle.crypto.BufferedBlockCipher; import org.bouncycastle.crypto.DataLengthException; import org.bouncycastle.crypto.InvalidCipherTextException; import org.bouncycastle.crypto.engines.DESEngine; import org.bouncycastle.crypto.params.KeyParameter; import org.bouncycastle.util.encoders.Hex; import org.bouncycastle.util.test.SimpleTest; public class ResetTest extends SimpleTest { private static final byte[] input = Hex.decode("4e6f77206973207468652074696d6520666f7220616c6c20"); private static final byte[] output = Hex.decode("3fa40e8a984d48156a271787ab8883f9893d51ec4b563b53"); public String getName() { return "Reset"; } public void performTest() throws Exception { BufferedBlockCipher cipher = new BufferedBlockCipher(new DESEngine()); KeyParameter param = new KeyParameter(Hex.decode("0123456789abcdef")); basicTrial(cipher, param); cipher.init(false, param); byte[] out = new byte[input.length]; int len2 = cipher.processBytes(output, 0, output.length - 1, out, 0); try { cipher.doFinal(out, len2); fail("no DataLengthException - short input"); } catch (DataLengthException e) { // ignore } len2 = cipher.processBytes(output, 0, output.length, out, 0); cipher.doFinal(out, len2); if (!areEqual(input, out)) { fail("failed reversal one got " + new String(Hex.encode(out))); } len2 = cipher.processBytes(output, 0, output.length - 1, out, 0); try { cipher.doFinal(out, len2); fail("no DataLengthException - short output"); } catch (DataLengthException e) { // ignore } len2 = cipher.processBytes(output, 0, output.length, out, 0); cipher.doFinal(out, len2); if (!areEqual(input, out)) { fail("failed reversal two got " + new String(Hex.encode(out))); } } private void basicTrial(BufferedBlockCipher cipher, KeyParameter param) throws InvalidCipherTextException { cipher.init(true, param); byte[] out = new byte[input.length]; int len1 = cipher.processBytes(input, 0, input.length, out, 0); cipher.doFinal(out, len1); if (!areEqual(out, output)) { fail("failed - " + "expected " + new String(Hex.encode(output)) + " got " + new String(Hex.encode(out))); } } public static void main( String[] args) { runTest(new ResetTest()); } } bouncycastle-1.49.orig/test/src/org/bouncycastle/crypto/test/SHA256HMacTest.java0000644000175000017500000001031410330633061027056 0ustar ebourgebourgpackage org.bouncycastle.crypto.test; import org.bouncycastle.crypto.digests.SHA256Digest; import org.bouncycastle.crypto.macs.HMac; import org.bouncycastle.crypto.params.KeyParameter; import org.bouncycastle.util.Arrays; import org.bouncycastle.util.encoders.Hex; import org.bouncycastle.util.test.SimpleTestResult; import org.bouncycastle.util.test.Test; import org.bouncycastle.util.test.TestResult; /** * SHA256 HMac Test */ public class SHA256HMacTest implements Test { final static String[] keys = { "0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b", "4a656665", "aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa", "0102030405060708090a0b0c0d0e0f10111213141516171819", "0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c", "aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa", "aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa" }; final static String[] digests = { "b0344c61d8db38535ca8afceaf0bf12b881dc200c9833da726e9376c2e32cff7", "5bdcc146bf60754e6a042426089575c75a003f089d2739839dec58b964ec3843", "773ea91e36800e46854db8ebd09181a72959098b3ef8c122d9635514ced565fe", "82558a389a443c0ea4cc819899f2083a85f0faa3e578f8077a2e3ff46729665b", "a3b6167473100ee06e0c796c2955552bfa6f7c0a6a8aef8b93f860aab0cd20c5", "60e431591ee0b67f0d8a26aacbf5b77f8e0bc6213728c5140546040f0ee37f54", "9b09ffa71b942fcb27635fbcd5b0e944bfdc63644f0713938a7f51535c3a35e2" }; final static String[] messages = { "Hi There", "what do ya want for nothing?", "0xdddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddd", "0xcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcd", "Test With Truncation", "Test Using Larger Than Block-Size Key - Hash Key First", "This is a test using a larger than block-size key and a larger than block-size data. The key needs to be hashed before being used by the HMAC algorithm." }; public String getName() { return "SHA256HMac"; } public TestResult perform() { HMac hmac = new HMac(new SHA256Digest()); byte[] resBuf = new byte[hmac.getMacSize()]; for (int i = 0; i < messages.length; i++) { byte[] m = messages[i].getBytes(); if (messages[i].startsWith("0x")) { m = Hex.decode(messages[i].substring(2)); } hmac.init(new KeyParameter(Hex.decode(keys[i]))); hmac.update(m, 0, m.length); hmac.doFinal(resBuf, 0); if (!Arrays.areEqual(resBuf, Hex.decode(digests[i]))) { return new SimpleTestResult(false, getName() + ": Vector " + i + " failed got -" + new String(Hex.encode(resBuf))); } } // // test reset // int vector = 0; // vector used for test byte[] m = messages[vector].getBytes(); if (messages[vector].startsWith("0x")) { m = Hex.decode(messages[vector].substring(2)); } hmac.init(new KeyParameter(Hex.decode(keys[vector]))); hmac.update(m, 0, m.length); hmac.doFinal(resBuf, 0); hmac.reset(); hmac.update(m, 0, m.length); hmac.doFinal(resBuf, 0); if (!Arrays.areEqual(resBuf, Hex.decode(digests[vector]))) { return new SimpleTestResult(false, getName() + "Reset with vector " + vector + " failed"); } return new SimpleTestResult(true, getName() + ": Okay"); } public static void main( String[] args) { SHA256HMacTest test = new SHA256HMacTest(); TestResult result = test.perform(); System.out.println(result); } } bouncycastle-1.49.orig/test/src/org/bouncycastle/crypto/test/RIPEMD128DigestTest.java0000644000175000017500000000301710330633061030032 0ustar ebourgebourgpackage org.bouncycastle.crypto.test; import org.bouncycastle.crypto.Digest; import org.bouncycastle.crypto.digests.RIPEMD128Digest; /** * RIPEMD128 Digest Test */ public class RIPEMD128DigestTest extends DigestTest { final static String[] messages = { "", "a", "abc", "message digest", "abcdefghijklmnopqrstuvwxyz", "abcdbcdecdefdefgefghfghighijhijkijkljklmklmnlmnomnopnopq", "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789", "12345678901234567890123456789012345678901234567890123456789012345678901234567890" }; final static String[] digests = { "cdf26213a150dc3ecb610f18f6b38b46", "86be7afa339d0fc7cfc785e72f578d33", "c14a12199c66e4ba84636b0f69144c77", "9e327b3d6e523062afc1132d7df9d1b8", "fd2aa607f71dc8f510714922b371834e", "a1aa0689d0fafa2ddc22e88b49133a06", "d1e959eb179c911faea4624c60c5c702", "3f45ef194732c2dbb2c4a2c769795fa3" }; final static String million_a_digest = "4a7f5723f954eba1216c9d8f6320431f"; RIPEMD128DigestTest() { super(new RIPEMD128Digest(), messages, digests); } public void performTest() { super.performTest(); millionATest(million_a_digest); } protected Digest cloneDigest(Digest digest) { return new RIPEMD128Digest((RIPEMD128Digest)digest); } public static void main( String[] args) { runTest(new RIPEMD128DigestTest()); } } bouncycastle-1.49.orig/test/src/org/bouncycastle/crypto/test/CCMTest.java0000644000175000017500000002077112045616306026077 0ustar ebourgebourgpackage org.bouncycastle.crypto.test; import org.bouncycastle.crypto.InvalidCipherTextException; import org.bouncycastle.crypto.engines.AESEngine; import org.bouncycastle.crypto.engines.DESEngine; import org.bouncycastle.crypto.modes.CCMBlockCipher; import org.bouncycastle.crypto.params.AEADParameters; import org.bouncycastle.crypto.params.KeyParameter; import org.bouncycastle.crypto.params.ParametersWithIV; import org.bouncycastle.util.Strings; import org.bouncycastle.util.encoders.Hex; import org.bouncycastle.util.test.SimpleTest; /** * First four test vectors from * NIST Special Publication 800-38C. */ public class CCMTest extends SimpleTest { private byte[] K1 = Hex.decode("404142434445464748494a4b4c4d4e4f"); private byte[] N1 = Hex.decode("10111213141516"); private byte[] A1 = Hex.decode("0001020304050607"); private byte[] P1 = Hex.decode("20212223"); private byte[] C1 = Hex.decode("7162015b4dac255d"); private byte[] T1 = Hex.decode("6084341b"); private byte[] K2 = Hex.decode("404142434445464748494a4b4c4d4e4f"); private byte[] N2 = Hex.decode("1011121314151617"); private byte[] A2 = Hex.decode("000102030405060708090a0b0c0d0e0f"); private byte[] P2 = Hex.decode("202122232425262728292a2b2c2d2e2f"); private byte[] C2 = Hex.decode("d2a1f0e051ea5f62081a7792073d593d1fc64fbfaccd"); private byte[] T2 = Hex.decode("7f479ffca464"); private byte[] K3 = Hex.decode("404142434445464748494a4b4c4d4e4f"); private byte[] N3 = Hex.decode("101112131415161718191a1b"); private byte[] A3 = Hex.decode("000102030405060708090a0b0c0d0e0f10111213"); private byte[] P3 = Hex.decode("202122232425262728292a2b2c2d2e2f3031323334353637"); private byte[] C3 = Hex.decode("e3b201a9f5b71a7a9b1ceaeccd97e70b6176aad9a4428aa5484392fbc1b09951"); private byte[] T3 = Hex.decode("67c99240c7d51048"); private byte[] K4 = Hex.decode("404142434445464748494a4b4c4d4e4f"); private byte[] N4 = Hex.decode("101112131415161718191a1b1c"); private byte[] A4 = Hex.decode("000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f404142434445464748494a4b4c4d4e4f505152535455565758595a5b5c5d5e5f606162636465666768696a6b6c6d6e6f707172737475767778797a7b7c7d7e7f808182838485868788898a8b8c8d8e8f909192939495969798999a9b9c9d9e9fa0a1a2a3a4a5a6a7a8a9aaabacadaeafb0b1b2b3b4b5b6b7b8b9babbbcbdbebfc0c1c2c3c4c5c6c7c8c9cacbcccdcecfd0d1d2d3d4d5d6d7d8d9dadbdcdddedfe0e1e2e3e4e5e6e7e8e9eaebecedeeeff0f1f2f3f4f5f6f7f8f9fafbfcfdfeff"); private byte[] P4 = Hex.decode("202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f"); private byte[] C4 = Hex.decode("69915dad1e84c6376a68c2967e4dab615ae0fd1faec44cc484828529463ccf72b4ac6bec93e8598e7f0dadbcea5b"); private byte[] T4 = Hex.decode("f4dd5d0ee404617225ffe34fce91"); // // long data vector // private byte[] C5 = Hex.decode("49b17d8d3ea4e6174a48e2b65e6d8b417ac0dd3f8ee46ce4a4a2a509661cef52528c1cd9805333a5cfd482fa3f095a3c2fdd1cc47771c5e55fddd60b5c8d6d3fa5c8dd79d08b16242b6642106e7c0c28bd1064b31e6d7c9800c8397dbc3fa8071e6a38278b386c18d65d39c6ad1ef9501a5c8f68d38eb6474799f3cc898b4b9b97e87f9c95ce5c51bc9d758f17119586663a5684e0a0daf6520ec572b87473eb141d10471e4799ded9e607655402eca5176bbf792ef39dd135ac8d710da8e9e854fd3b95c681023f36b5ebe2fb213d0b62dd6e9e3cfe190b792ccb20c53423b2dca128f861a61d306910e1af418839467e466f0ec361d2539eedd99d4724f1b51c07beb40e875a87491ec8b27cd1"); private byte[] T5 = Hex.decode("5c768856796b627b13ec8641581b"); public void performTest() throws Exception { CCMBlockCipher ccm = new CCMBlockCipher(new AESEngine()); checkVectors(0, ccm, K1, 32, N1, A1, P1, T1, C1); checkVectors(1, ccm, K2, 48, N2, A2, P2, T2, C2); checkVectors(2, ccm, K3, 64, N3, A3, P3, T3, C3); ivParamTest(0, ccm, K1, N1); // // 4 has a reduced associated text which needs to be replicated // byte[] a4 = new byte[65536]; // 524288 / 8 for (int i = 0; i < a4.length; i += A4.length) { System.arraycopy(A4, 0, a4, i, A4.length); } checkVectors(3, ccm, K4, 112, N4, a4, P4, T4, C4); // // long data test // checkVectors(4, ccm, K4, 112, N4, A4, A4, T5, C5); // // exception tests // try { ccm.init(false, new AEADParameters(new KeyParameter(K1), 32, N2, A2)); ccm.processPacket(C2, 0, C2.length); fail("invalid cipher text not picked up"); } catch (InvalidCipherTextException e) { // expected } try { ccm = new CCMBlockCipher(new DESEngine()); fail("incorrect block size not picked up"); } catch (IllegalArgumentException e) { // expected } try { ccm.init(false, new KeyParameter(K1)); fail("illegal argument not picked up"); } catch (IllegalArgumentException e) { // expected } } private void checkVectors( int count, CCMBlockCipher ccm, byte[] k, int macSize, byte[] n, byte[] a, byte[] p, byte[] t, byte[] c) throws InvalidCipherTextException { byte[] fa = new byte[a.length / 2]; byte[] la = new byte[a.length - (a.length / 2)]; System.arraycopy(a, 0, fa, 0, fa.length); System.arraycopy(a, fa.length, la, 0, la.length); checkVectors(count, ccm, "all initial associated data", k, macSize, n, a, null, p, t, c); checkVectors(count, ccm, "subsequent associated data", k, macSize, n, null, a, p, t, c); checkVectors(count, ccm, "split associated data", k, macSize, n, fa, la, p, t, c); // checkVectors(count, ccm, "reuse key", null, macSize, n, fa, la, p, t, c); } private void checkVectors( int count, CCMBlockCipher ccm, String additionalDataType, byte[] k, int macSize, byte[] n, byte[] a, byte[] sa, byte[] p, byte[] t, byte[] c) throws InvalidCipherTextException { KeyParameter keyParam = (k == null) ? null : new KeyParameter(k); ccm.init(true, new AEADParameters(keyParam, macSize, n, a)); byte[] enc = new byte[c.length]; if (sa != null) { ccm.processAADBytes(sa, 0, sa.length); } int len = ccm.processBytes(p, 0, p.length, enc, 0); len += ccm.doFinal(enc, len); if (!areEqual(c, enc)) { fail("encrypted stream fails to match in test " + count + " with " + additionalDataType); } ccm.init(false, new AEADParameters(keyParam, macSize, n, a)); byte[] tmp = new byte[enc.length]; if (sa != null) { ccm.processAADBytes(sa, 0, sa.length); } len = ccm.processBytes(enc, 0, enc.length, tmp, 0); len += ccm.doFinal(tmp, len); byte[] dec = new byte[len]; System.arraycopy(tmp, 0, dec, 0, len); if (!areEqual(p, dec)) { fail("decrypted stream fails to match in test " + count + " with " + additionalDataType); } if (!areEqual(t, ccm.getMac())) { fail("MAC fails to match in test " + count + " with " + additionalDataType); } } private void ivParamTest( int count, CCMBlockCipher ccm, byte[] k, byte[] n) throws InvalidCipherTextException { byte[] p = Strings.toByteArray("hello world!!"); ccm.init(true, new ParametersWithIV(new KeyParameter(k), n)); byte[] enc = new byte[p.length + 8]; int len = ccm.processBytes(p, 0, p.length, enc, 0); len += ccm.doFinal(enc, len); ccm.init(false, new ParametersWithIV(new KeyParameter(k), n)); byte[] tmp = new byte[enc.length]; len = ccm.processBytes(enc, 0, enc.length, tmp, 0); len += ccm.doFinal(tmp, len); byte[] dec = new byte[len]; System.arraycopy(tmp, 0, dec, 0, len); if (!areEqual(p, dec)) { fail("decrypted stream fails to match in test " + count); } } public String getName() { return "CCM"; } public static void main( String[] args) { runTest(new CCMTest()); } } bouncycastle-1.49.orig/test/src/org/bouncycastle/crypto/test/Salsa20Test.java0000644000175000017500000001647010606355363026707 0ustar ebourgebourgpackage org.bouncycastle.crypto.test; import org.bouncycastle.crypto.CipherParameters; import org.bouncycastle.crypto.StreamCipher; import org.bouncycastle.crypto.engines.Salsa20Engine; import org.bouncycastle.crypto.params.KeyParameter; import org.bouncycastle.crypto.params.ParametersWithIV; import org.bouncycastle.util.encoders.Hex; import org.bouncycastle.util.test.SimpleTest; /** * Salsa20 Test */ public class Salsa20Test extends SimpleTest { byte[] zeroes = Hex.decode( "00000000000000000000000000000000" + "00000000000000000000000000000000" + "00000000000000000000000000000000" + "00000000000000000000000000000000"); String set1v0_0 = "4DFA5E481DA23EA09A31022050859936" + "DA52FCEE218005164F267CB65F5CFD7F" + "2B4F97E0FF16924A52DF269515110A07" + "F9E460BC65EF95DA58F740B7D1DBB0AA"; String set1v0_192 = "DA9C1581F429E0A00F7D67E23B730676" + "783B262E8EB43A25F55FB90B3E753AEF" + "8C6713EC66C51881111593CCB3E8CB8F" + "8DE124080501EEEB389C4BCB6977CF95"; String set1v0_256 = "7D5789631EB4554400E1E025935DFA7B" + "3E9039D61BDC58A8697D36815BF1985C" + "EFDF7AE112E5BB81E37ECF0616CE7147" + "FC08A93A367E08631F23C03B00A8DA2F"; String set1v0_448 = "B375703739DACED4DD4059FD71C3C47F" + "C2F9939670FAD4A46066ADCC6A564578" + "3308B90FFB72BE04A6B147CBE38CC0C3" + "B9267C296A92A7C69873F9F263BE9703"; String set1v9_0 = "0471076057830FB99202291177FBFE5D" + "38C888944DF8917CAB82788B91B53D1C" + "FB06D07A304B18BB763F888A61BB6B75" + "5CD58BEC9C4CFB7569CB91862E79C459"; String set1v9_192 = "D1D7E97556426E6CFC21312AE3811425" + "9E5A6FB10DACBD88E4354B0472556935" + "2B6DA5ACAFACD5E266F9575C2ED8E6F2" + "EFE4B4D36114C3A623DD49F4794F865B"; String set1v9_256 = "AF06FAA82C73291231E1BD916A773DE1" + "52FD2126C40A10C3A6EB40F22834B8CC" + "68BD5C6DBD7FC1EC8F34165C517C0B63" + "9DB0C60506D3606906B8463AA0D0EC2F"; String set1v9_448 = "AB3216F1216379EFD5EC589510B8FD35" + "014D0AA0B613040BAE63ECAB90A9AF79" + "661F8DA2F853A5204B0F8E72E9D9EB4D" + "BA5A4690E73A4D25F61EE7295215140C"; String set6v0_0 = "F5FAD53F79F9DF58C4AEA0D0ED9A9601" + "F278112CA7180D565B420A48019670EA" + "F24CE493A86263F677B46ACE1924773D" + "2BB25571E1AA8593758FC382B1280B71"; String set6v0_65472 = "B70C50139C63332EF6E77AC54338A407" + "9B82BEC9F9A403DFEA821B83F7860791" + "650EF1B2489D0590B1DE772EEDA4E3BC" + "D60FA7CE9CD623D9D2FD5758B8653E70"; String set6v0_65536 = "81582C65D7562B80AEC2F1A673A9D01C" + "9F892A23D4919F6AB47B9154E08E699B" + "4117D7C666477B60F8391481682F5D95" + "D96623DBC489D88DAA6956B9F0646B6E"; String set6v1_0 = "3944F6DC9F85B128083879FDF190F7DE" + "E4053A07BC09896D51D0690BD4DA4AC1" + "062F1E47D3D0716F80A9B4D85E6D6085" + "EE06947601C85F1A27A2F76E45A6AA87"; String set6v1_65472 = "36E03B4B54B0B2E04D069E690082C8C5" + "92DF56E633F5D8C7682A02A65ECD1371" + "8CA4352AACCB0DA20ED6BBBA62E177F2" + "10E3560E63BB822C4158CAA806A88C82"; String set6v1_65536 = "1B779E7A917C8C26039FFB23CF0EF8E0" + "8A1A13B43ACDD9402CF5DF38501098DF" + "C945A6CC69A6A17367BC03431A86B3ED" + "04B0245B56379BF997E25800AD837D7D"; public String getName() { return "Salsa20"; } public void performTest() { salsa20Test1(new ParametersWithIV(new KeyParameter(Hex.decode("80000000000000000000000000000000")), Hex.decode("0000000000000000")), set1v0_0, set1v0_192, set1v0_256, set1v0_448); salsa20Test1(new ParametersWithIV(new KeyParameter(Hex.decode("00400000000000000000000000000000")), Hex.decode("0000000000000000")), set1v9_0, set1v9_192, set1v9_256, set1v9_448); salsa20Test2(new ParametersWithIV(new KeyParameter(Hex.decode("0053A6F94C9FF24598EB3E91E4378ADD3083D6297CCF2275C81B6EC11467BA0D")), Hex.decode("0D74DB42A91077DE")), set6v0_0, set6v0_65472, set6v0_65536); salsa20Test2(new ParametersWithIV(new KeyParameter(Hex.decode("0558ABFE51A4F74A9DF04396E93C8FE23588DB2E81D4277ACD2073C6196CBF12")), Hex.decode("167DE44BB21980E7")), set6v1_0, set6v1_65472, set6v1_65536); reinitBug(); } private void salsa20Test1(CipherParameters params, String v0, String v192, String v256, String v448) { StreamCipher salsa = new Salsa20Engine(); byte[] buf = new byte[64]; salsa.init(true, params); for (int i = 0; i != 7; i++) { salsa.processBytes(zeroes, 0, 64, buf, 0); switch (i) { case 0: if (!areEqual(buf, Hex.decode(v0))) { mismatch("v0", v0, buf); } break; case 3: if (!areEqual(buf, Hex.decode(v192))) { mismatch("v192", v192, buf); } break; case 4: if (!areEqual(buf, Hex.decode(v256))) { mismatch("v256", v256, buf); } break; default: // ignore } } for (int i = 0; i != 64; i++) { buf[i] = salsa.returnByte(zeroes[i]); } if (!areEqual(buf, Hex.decode(v448))) { mismatch("v448", v448, buf); } } private void salsa20Test2(CipherParameters params, String v0, String v65472, String v65536) { StreamCipher salsa = new Salsa20Engine(); byte[] buf = new byte[64]; salsa.init(true, params); for (int i = 0; i != 1025; i++) { salsa.processBytes(zeroes, 0, 64, buf, 0); switch (i) { case 0: if (!areEqual(buf, Hex.decode(v0))) { mismatch("v0", v0, buf); } break; case 1023: if (!areEqual(buf, Hex.decode(v65472))) { mismatch("v65472", v65472, buf); } break; case 1024: if (!areEqual(buf, Hex.decode(v65536))) { mismatch("v65536", v65536, buf); } break; default: // ignore } } } private void mismatch(String name, String expected, byte[] found) { fail("mismatch on " + name, expected, new String(Hex.encode(found))); } private void reinitBug() { KeyParameter key = new KeyParameter(Hex.decode("80000000000000000000000000000000")); ParametersWithIV parameters = new ParametersWithIV(key, Hex.decode("0000000000000000")); StreamCipher salsa = new Salsa20Engine(); salsa.init(true, parameters); try { salsa.init(true, key); fail("Salsa20 should throw exception if no IV in Init"); } catch (IllegalArgumentException e) { } } public static void main( String[] args) { runTest(new Salsa20Test()); } } bouncycastle-1.49.orig/test/src/org/bouncycastle/crypto/test/ECNRTest.java0000644000175000017500000000625210425074751026224 0ustar ebourgebourgpackage org.bouncycastle.crypto.test; import java.math.BigInteger; import java.security.SecureRandom; import org.bouncycastle.crypto.params.ECDomainParameters; import org.bouncycastle.crypto.params.ECPrivateKeyParameters; import org.bouncycastle.crypto.params.ECPublicKeyParameters; import org.bouncycastle.crypto.params.ParametersWithRandom; import org.bouncycastle.crypto.signers.ECNRSigner; import org.bouncycastle.math.ec.ECCurve; import org.bouncycastle.util.BigIntegers; import org.bouncycastle.util.encoders.Hex; import org.bouncycastle.util.test.FixedSecureRandom; import org.bouncycastle.util.test.SimpleTest; /** * ECNR tests. */ public class ECNRTest extends SimpleTest { /** * a basic regression test with 239 bit prime */ BigInteger r = new BigInteger("308636143175167811492623515537541734843573549327605293463169625072911693"); BigInteger s = new BigInteger("852401710738814635664888632022555967400445256405412579597015412971797143"); byte[] kData = BigIntegers.asUnsignedByteArray(new BigInteger("700000017569056646655505781757157107570501575775705779575555657156756655")); SecureRandom k = new FixedSecureRandom(true, kData); private void ecNR239bitPrime() { ECCurve.Fp curve = new ECCurve.Fp( new BigInteger("883423532389192164791648750360308885314476597252960362792450860609699839"), // q new BigInteger("7fffffffffffffffffffffff7fffffffffff8000000000007ffffffffffc", 16), // a new BigInteger("6b016c3bdcf18941d0d654921475ca71a9db2fb27d1d37796185c2942c0a", 16)); // b ECDomainParameters params = new ECDomainParameters( curve, curve.decodePoint(Hex.decode("020ffa963cdca8816ccc33b8642bedf905c3d358573d3f27fbbd3b3cb9aaaf")), // G new BigInteger("883423532389192164791648750360308884807550341691627752275345424702807307")); // n ECPrivateKeyParameters priKey = new ECPrivateKeyParameters( new BigInteger("876300101507107567501066130761671078357010671067781776716671676178726717"), // d params); ECNRSigner ecnr = new ECNRSigner(); ParametersWithRandom param = new ParametersWithRandom(priKey, k); ecnr.init(true, param); byte[] message = new BigInteger("968236873715988614170569073515315707566766479517").toByteArray(); BigInteger[] sig = ecnr.generateSignature(message); if (!r.equals(sig[0])) { fail("r component wrong.", r, sig[0]); } if (!s.equals(sig[1])) { fail("s component wrong.", s, sig[1]); } // Verify the signature ECPublicKeyParameters pubKey = new ECPublicKeyParameters( curve.decodePoint(Hex.decode("025b6dc53bc61a2548ffb0f671472de6c9521a9d2d2534e65abfcbd5fe0c70")), // Q params); ecnr.init(false, pubKey); if (!ecnr.verifySignature(message, sig[0], sig[1])) { fail("signature fails"); } } public String getName() { return "ECNR"; } public void performTest() { ecNR239bitPrime(); } public static void main( String[] args) { runTest(new ECNRTest()); } } bouncycastle-1.49.orig/test/src/org/bouncycastle/crypto/test/HKDFGeneratorTest.java0000644000175000017500000002507712076514570030070 0ustar ebourgebourgpackage org.bouncycastle.crypto.test; import org.bouncycastle.crypto.Digest; import org.bouncycastle.crypto.digests.SHA1Digest; import org.bouncycastle.crypto.digests.SHA256Digest; import org.bouncycastle.crypto.generators.HKDFBytesGenerator; import org.bouncycastle.crypto.params.HKDFParameters; import org.bouncycastle.util.encoders.Hex; import org.bouncycastle.util.test.SimpleTest; /** * HKDF tests - vectors from RFC 5869, + 2 more, 101 and 102 */ public class HKDFGeneratorTest extends SimpleTest { public HKDFGeneratorTest() { } private void compareOKM(int test, byte[] calculatedOKM, byte[] testOKM) { if (!areEqual(calculatedOKM, testOKM)) { fail("HKDF failed generator test " + test); } } public void performTest() { { // === A.1. Test Case 1 - Basic test case with SHA-256 === Digest hash = new SHA256Digest(); byte[] ikm = Hex .decode("0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b"); byte[] salt = Hex.decode("000102030405060708090a0b0c"); byte[] info = Hex.decode("f0f1f2f3f4f5f6f7f8f9"); int l = 42; byte[] okm = new byte[l]; HKDFParameters params = new HKDFParameters(ikm, salt, info); HKDFBytesGenerator hkdf = new HKDFBytesGenerator(hash); hkdf.init(params); hkdf.generateBytes(okm, 0, l); compareOKM(1, okm, Hex.decode( "3cb25f25faacd57a90434f64d0362f2a" + "2d2d0a90cf1a5a4c5db02d56ecc4c5bf" + "34007208d5b887185865")); } // === A.2. Test Case 2 - Test with SHA-256 and longer inputs/outputs // === { Digest hash = new SHA256Digest(); byte[] ikm = Hex.decode("000102030405060708090a0b0c0d0e0f" + "101112131415161718191a1b1c1d1e1f" + "202122232425262728292a2b2c2d2e2f" + "303132333435363738393a3b3c3d3e3f" + "404142434445464748494a4b4c4d4e4f"); byte[] salt = Hex.decode("606162636465666768696a6b6c6d6e6f" + "707172737475767778797a7b7c7d7e7f" + "808182838485868788898a8b8c8d8e8f" + "909192939495969798999a9b9c9d9e9f" + "a0a1a2a3a4a5a6a7a8a9aaabacadaeaf"); byte[] info = Hex.decode("b0b1b2b3b4b5b6b7b8b9babbbcbdbebf" + "c0c1c2c3c4c5c6c7c8c9cacbcccdcecf" + "d0d1d2d3d4d5d6d7d8d9dadbdcdddedf" + "e0e1e2e3e4e5e6e7e8e9eaebecedeeef" + "f0f1f2f3f4f5f6f7f8f9fafbfcfdfeff"); int l = 82; byte[] okm = new byte[l]; HKDFParameters params = new HKDFParameters(ikm, salt, info); HKDFBytesGenerator hkdf = new HKDFBytesGenerator(hash); hkdf.init(params); hkdf.generateBytes(okm, 0, l); compareOKM(2, okm, Hex.decode( "b11e398dc80327a1c8e7f78c596a4934" + "4f012eda2d4efad8a050cc4c19afa97c" + "59045a99cac7827271cb41c65e590e09" + "da3275600c2f09b8367793a9aca3db71" + "cc30c58179ec3e87c14c01d5c1f3434f" + "1d87")); } { // === A.3. Test Case 3 - Test with SHA-256 and zero-length // salt/info === // setting salt to an empty byte array means that the salt is set to // HashLen zero valued bytes // setting info to null generates an empty byte array as info // structure Digest hash = new SHA256Digest(); byte[] ikm = Hex .decode("0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b"); byte[] salt = new byte[0]; byte[] info = null; int l = 42; byte[] okm = new byte[l]; HKDFParameters params = new HKDFParameters(ikm, salt, info); HKDFBytesGenerator hkdf = new HKDFBytesGenerator(hash); hkdf.init(params); hkdf.generateBytes(okm, 0, l); compareOKM(3, okm, Hex.decode( "8da4e775a563c18f715f802a063c5a31" + "b8a11f5c5ee1879ec3454e5f3c738d2d" + "9d201395faa4b61a96c8")); } { // === A.4. Test Case 4 - Basic test case with SHA-1 === Digest hash = new SHA1Digest(); byte[] ikm = Hex.decode("0b0b0b0b0b0b0b0b0b0b0b"); byte[] salt = Hex.decode("000102030405060708090a0b0c"); byte[] info = Hex.decode("f0f1f2f3f4f5f6f7f8f9"); int l = 42; byte[] okm = new byte[l]; HKDFParameters params = new HKDFParameters(ikm, salt, info); HKDFBytesGenerator hkdf = new HKDFBytesGenerator(hash); hkdf.init(params); hkdf.generateBytes(okm, 0, l); compareOKM(4, okm, Hex.decode( "085a01ea1b10f36933068b56efa5ad81" + "a4f14b822f5b091568a9cdd4f155fda2" + "c22e422478d305f3f896")); } // === A.5. Test Case 5 - Test with SHA-1 and longer inputs/outputs === { Digest hash = new SHA1Digest(); byte[] ikm = Hex.decode("000102030405060708090a0b0c0d0e0f" + "101112131415161718191a1b1c1d1e1f" + "202122232425262728292a2b2c2d2e2f" + "303132333435363738393a3b3c3d3e3f" + "404142434445464748494a4b4c4d4e4f"); byte[] salt = Hex.decode("606162636465666768696a6b6c6d6e6f" + "707172737475767778797a7b7c7d7e7f" + "808182838485868788898a8b8c8d8e8f" + "909192939495969798999a9b9c9d9e9f" + "a0a1a2a3a4a5a6a7a8a9aaabacadaeaf"); byte[] info = Hex.decode("b0b1b2b3b4b5b6b7b8b9babbbcbdbebf" + "c0c1c2c3c4c5c6c7c8c9cacbcccdcecf" + "d0d1d2d3d4d5d6d7d8d9dadbdcdddedf" + "e0e1e2e3e4e5e6e7e8e9eaebecedeeef" + "f0f1f2f3f4f5f6f7f8f9fafbfcfdfeff"); int l = 82; byte[] okm = new byte[l]; HKDFParameters params = new HKDFParameters(ikm, salt, info); HKDFBytesGenerator hkdf = new HKDFBytesGenerator(hash); hkdf.init(params); hkdf.generateBytes(okm, 0, l); compareOKM(5, okm, Hex.decode( "0bd770a74d1160f7c9f12cd5912a06eb" + "ff6adcae899d92191fe4305673ba2ffe" + "8fa3f1a4e5ad79f3f334b3b202b2173c" + "486ea37ce3d397ed034c7f9dfeb15c5e" + "927336d0441f4c4300e2cff0d0900b52" + "d3b4")); } { // === A.6. Test Case 6 - Test with SHA-1 and zero-length salt/info // === // setting salt to null should generate a new salt of HashLen zero // valued bytes Digest hash = new SHA1Digest(); byte[] ikm = Hex .decode("0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b"); byte[] salt = null; byte[] info = new byte[0]; int l = 42; byte[] okm = new byte[l]; HKDFParameters params = new HKDFParameters(ikm, salt, info); HKDFBytesGenerator hkdf = new HKDFBytesGenerator(hash); hkdf.init(params); hkdf.generateBytes(okm, 0, l); compareOKM(6, okm, Hex.decode( "0ac1af7002b3d761d1e55298da9d0506" + "b9ae52057220a306e07b6b87e8df21d0" + "ea00033de03984d34918")); } { // === A.7. Test Case 7 - Test with SHA-1, salt not provided, // zero-length info === // (salt defaults to HashLen zero octets) // this test is identical to test 6 in all ways bar the IKM value Digest hash = new SHA1Digest(); byte[] ikm = Hex .decode("0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c"); byte[] salt = null; byte[] info = new byte[0]; int l = 42; byte[] okm = new byte[l]; HKDFParameters params = new HKDFParameters(ikm, salt, info); HKDFBytesGenerator hkdf = new HKDFBytesGenerator(hash); hkdf.init(params); hkdf.generateBytes(okm, 0, l); compareOKM(7, okm, Hex.decode( "2c91117204d745f3500d636a62f64f0a" + "b3bae548aa53d423b0d1f27ebba6f5e5" + "673a081d70cce7acfc48")); } { // === A.101. Additional Test Case - Test with SHA-1, skipping extract // zero-length info === // (salt defaults to HashLen zero octets) // this test is identical to test 7 in all ways bar the IKM value // which is set to the PRK value Digest hash = new SHA1Digest(); byte[] ikm = Hex .decode("2adccada18779e7c2077ad2eb19d3f3e731385dd"); byte[] info = new byte[0]; int l = 42; byte[] okm = new byte[l]; HKDFParameters params = HKDFParameters.skipExtractParameters(ikm, info); HKDFBytesGenerator hkdf = new HKDFBytesGenerator(hash); hkdf.init(params); hkdf.generateBytes(okm, 0, l); compareOKM(101, okm, Hex.decode( "2c91117204d745f3500d636a62f64f0a" + "b3bae548aa53d423b0d1f27ebba6f5e5" + "673a081d70cce7acfc48")); } // === A.102. Additional Test Case - Test with SHA-1, maximum output === // (salt defaults to HashLen zero octets) // this test is identical to test 7 in all ways bar the IKM value Digest hash = new SHA1Digest(); byte[] ikm = Hex .decode("2adccada18779e7c2077ad2eb19d3f3e731385dd"); byte[] info = new byte[0]; int l = 255 * hash.getDigestSize(); byte[] okm = new byte[l]; HKDFParameters params = HKDFParameters.skipExtractParameters(ikm, info); HKDFBytesGenerator hkdf = new HKDFBytesGenerator(hash); hkdf.init(params); hkdf.generateBytes(okm, 0, l); int zeros = 0; for (int i = 0; i < hash.getDigestSize(); i++) { if (okm[i] == 0) { zeros++; } } if (zeros == hash.getDigestSize()) { fail("HKDF failed generator test " + 102); } } public String getName() { return "HKDF"; } public static void main( String[] args) { runTest(new HKDFGeneratorTest()); } } bouncycastle-1.49.orig/test/src/org/bouncycastle/crypto/test/RIPEMD256DigestTest.java0000644000175000017500000000344710330633061030043 0ustar ebourgebourgpackage org.bouncycastle.crypto.test; import org.bouncycastle.crypto.Digest; import org.bouncycastle.crypto.digests.RIPEMD256Digest; /** * RIPEMD128 Digest Test */ public class RIPEMD256DigestTest extends DigestTest { final static String[] messages = { "", "a", "abc", "message digest", "abcdefghijklmnopqrstuvwxyz", "abcdbcdecdefdefgefghfghighijhijkijkljklmklmnlmnomnopnopq", "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789", "12345678901234567890123456789012345678901234567890123456789012345678901234567890" }; final static String[] digests = { "02ba4c4e5f8ecd1877fc52d64d30e37a2d9774fb1e5d026380ae0168e3c5522d", "f9333e45d857f5d90a91bab70a1eba0cfb1be4b0783c9acfcd883a9134692925", "afbd6e228b9d8cbbcef5ca2d03e6dba10ac0bc7dcbe4680e1e42d2e975459b65", "87e971759a1ce47a514d5c914c392c9018c7c46bc14465554afcdf54a5070c0e", "649d3034751ea216776bf9a18acc81bc7896118a5197968782dd1fd97d8d5133", "3843045583aac6c8c8d9128573e7a9809afb2a0f34ccc36ea9e72f16f6368e3f", "5740a408ac16b720b84424ae931cbb1fe363d1d0bf4017f1a89f7ea6de77a0b8", "06fdcc7a409548aaf91368c06a6275b553e3f099bf0ea4edfd6778df89a890dd" }; final static String million_a_digest = "ac953744e10e31514c150d4d8d7b677342e33399788296e43ae4850ce4f97978"; RIPEMD256DigestTest() { super(new RIPEMD256Digest(), messages, digests); } public void performTest() { super.performTest(); millionATest(million_a_digest); } protected Digest cloneDigest(Digest digest) { return new RIPEMD256Digest((RIPEMD256Digest)digest); } public static void main( String[] args) { runTest(new RIPEMD256DigestTest()); } } bouncycastle-1.49.orig/test/src/org/bouncycastle/crypto/test/SHA512DigestTest.java0000644000175000017500000000342510330633061027465 0ustar ebourgebourgpackage org.bouncycastle.crypto.test; import org.bouncycastle.crypto.Digest; import org.bouncycastle.crypto.digests.SHA512Digest; /** * standard vector test for SHA-512 from FIPS Draft 180-2. * * Note, the first two vectors are _not_ from the draft, the last three are. */ public class SHA512DigestTest extends DigestTest { private static String[] messages = { "", "a", "abc", "abcdefghbcdefghicdefghijdefghijkefghijklfghijklmghijklmnhijklmnoijklmnopjklmnopqklmnopqrlmnopqrsmnopqrstnopqrstu" }; private static String[] digests = { "cf83e1357eefb8bdf1542850d66d8007d620e4050b5715dc83f4a921d36ce9ce47d0d13c5d85f2b0ff8318d2877eec2f63b931bd47417a81a538327af927da3e", "1f40fc92da241694750979ee6cf582f2d5d7d28e18335de05abc54d0560e0f5302860c652bf08d560252aa5e74210546f369fbbbce8c12cfc7957b2652fe9a75", "ddaf35a193617abacc417349ae20413112e6fa4e89a97ea20a9eeee64b55d39a2192992a274fc1a836ba3c23a3feebbd454d4423643ce80e2a9ac94fa54ca49f", "8e959b75dae313da8cf4f72814fc143f8f7779c6eb9f7fa17299aeadb6889018501d289e4900f7e4331b99dec4b5433ac7d329eeb6dd26545e96e55b874be909" }; // 1 million 'a' static private String million_a_digest = "e718483d0ce769644e2e42c7bc15b4638e1f98b13b2044285632a803afa973ebde0ff244877ea60a4cb0432ce577c31beb009c5c2c49aa2e4eadb217ad8cc09b"; SHA512DigestTest() { super(new SHA512Digest(), messages, digests); } public void performTest() { super.performTest(); millionATest(million_a_digest); } protected Digest cloneDigest(Digest digest) { return new SHA512Digest((SHA512Digest)digest); } public static void main( String[] args) { runTest(new SHA512DigestTest()); } } bouncycastle-1.49.orig/test/src/org/bouncycastle/crypto/test/KDF1GeneratorTest.java0000644000175000017500000000633610427071732030032 0ustar ebourgebourgpackage org.bouncycastle.crypto.test; import org.bouncycastle.crypto.DataLengthException; import org.bouncycastle.crypto.DerivationFunction; import org.bouncycastle.crypto.digests.ShortenedDigest; import org.bouncycastle.crypto.digests.SHA1Digest; import org.bouncycastle.crypto.digests.SHA256Digest; import org.bouncycastle.crypto.generators.KDF1BytesGenerator; import org.bouncycastle.crypto.params.ISO18033KDFParameters; import org.bouncycastle.util.encoders.Hex; import org.bouncycastle.util.test.SimpleTest; /** * KDF1 tests - vectors from ISO 18033. */ public class KDF1GeneratorTest extends SimpleTest { private byte[] seed1 = Hex.decode("d6e168c5f256a2dcff7ef12facd390f393c7a88d"); private byte[] mask1 = Hex.decode( "0742ba966813af75536bb6149cc44fc256fd6406df79665bc31dc5" + "a62f70535e52c53015b9d37d412ff3c1193439599e1b628774c50d9c" + "cb78d82c425e4521ee47b8c36a4bcffe8b8112a89312fc04420a39de" + "99223890e74ce10378bc515a212b97b8a6447ba6a8870278"); private byte[] seed2 = Hex.decode( "032e45326fa859a72ec235acff929b15d1372e30b207255f0611b8f785d7643741" + "52e0ac009e509e7ba30cd2f1778e113b64e135cf4e2292c75efe5288edfda4"); private byte[] mask2 = Hex.decode( "5f8de105b5e96b2e490ddecbd147dd1def7e3b8e0e6a26eb7b956ccb8b3bdc1ca9" + "75bc57c3989e8fbad31a224655d800c46954840ff32052cdf0d640562bdfadfa263c" + "fccf3c52b29f2af4a1869959bc77f854cf15bd7a25192985a842dbff8e13efee5b7e" + "7e55bbe4d389647c686a9a9ab3fb889b2d7767d3837eea4e0a2f04"); private byte[] seed3 = seed2; private byte[] mask3= Hex.decode( "09e2decf2a6e1666c2f6071ff4298305e2643fd510a2403db42a8743cb989de86e" + "668d168cbe604611ac179f819a3d18412e9eb45668f2923c087c12fee0c5a0d2a8aa" + "70185401fbbd99379ec76c663e875a60b4aacb1319fa11c3365a8b79a44669f26fb5" + "55c80391847b05eca1cb5cf8c2d531448d33fbaca19f6410ee1fcb"); public KDF1GeneratorTest() { } public void performTest() { checkMask(1, new KDF1BytesGenerator(new ShortenedDigest(new SHA256Digest(), 20)), seed1, mask1); checkMask(2, new KDF1BytesGenerator(new SHA1Digest()), seed2, mask2); checkMask(3, new KDF1BytesGenerator(new ShortenedDigest(new SHA256Digest(), 20)), seed3, mask3); try { new KDF1BytesGenerator(new SHA1Digest()).generateBytes(new byte[10], 0, 20); fail("short input array not caught"); } catch (DataLengthException e) { // expected } } private void checkMask( int count, DerivationFunction kdf, byte[] seed, byte[] result) { byte[] data = new byte[result.length]; kdf.init(new ISO18033KDFParameters(seed)); kdf.generateBytes(data, 0, data.length); if (!areEqual(result, data)) { fail("KDF1 failed generator test " + count); } } public String getName() { return "KDF1"; } public static void main( String[] args) { runTest(new KDF1GeneratorTest()); } } bouncycastle-1.49.orig/test/src/org/bouncycastle/crypto/test/RSATest.java0000644000175000017500000004033500000000115026065 0ustar ebourgebourgpackage org.bouncycastle.crypto.test; import java.math.BigInteger; import java.security.SecureRandom; import org.bouncycastle.crypto.AsymmetricBlockCipher; import org.bouncycastle.crypto.AsymmetricCipherKeyPair; import org.bouncycastle.crypto.CipherParameters; import org.bouncycastle.crypto.InvalidCipherTextException; import org.bouncycastle.crypto.encodings.OAEPEncoding; import org.bouncycastle.crypto.encodings.PKCS1Encoding; import org.bouncycastle.crypto.engines.RSAEngine; import org.bouncycastle.crypto.generators.RSAKeyPairGenerator; import org.bouncycastle.crypto.params.RSAKeyGenerationParameters; import org.bouncycastle.crypto.params.RSAKeyParameters; import org.bouncycastle.crypto.params.RSAPrivateCrtKeyParameters; import org.bouncycastle.util.Arrays; import org.bouncycastle.util.encoders.Hex; import org.bouncycastle.util.test.SimpleTest; public class RSATest extends SimpleTest { static BigInteger mod = new BigInteger("b259d2d6e627a768c94be36164c2d9fc79d97aab9253140e5bf17751197731d6f7540d2509e7b9ffee0a70a6e26d56e92d2edd7f85aba85600b69089f35f6bdbf3c298e05842535d9f064e6b0391cb7d306e0a2d20c4dfb4e7b49a9640bdea26c10ad69c3f05007ce2513cee44cfe01998e62b6c3637d3fc0391079b26ee36d5", 16); static BigInteger pubExp = new BigInteger("11", 16); static BigInteger privExp = new BigInteger("92e08f83cc9920746989ca5034dcb384a094fb9c5a6288fcc4304424ab8f56388f72652d8fafc65a4b9020896f2cde297080f2a540e7b7ce5af0b3446e1258d1dd7f245cf54124b4c6e17da21b90a0ebd22605e6f45c9f136d7a13eaac1c0f7487de8bd6d924972408ebb58af71e76fd7b012a8d0e165f3ae2e5077a8648e619", 16); static BigInteger p = new BigInteger("f75e80839b9b9379f1cf1128f321639757dba514642c206bbbd99f9a4846208b3e93fbbe5e0527cc59b1d4b929d9555853004c7c8b30ee6a213c3d1bb7415d03", 16); static BigInteger q = new BigInteger("b892d9ebdbfc37e397256dd8a5d3123534d1f03726284743ddc6be3a709edb696fc40c7d902ed804c6eee730eee3d5b20bf6bd8d87a296813c87d3b3cc9d7947", 16); static BigInteger pExp = new BigInteger("1d1a2d3ca8e52068b3094d501c9a842fec37f54db16e9a67070a8b3f53cc03d4257ad252a1a640eadd603724d7bf3737914b544ae332eedf4f34436cac25ceb5", 16); static BigInteger qExp = new BigInteger("6c929e4e81672fef49d9c825163fec97c4b7ba7acb26c0824638ac22605d7201c94625770984f78a56e6e25904fe7db407099cad9b14588841b94f5ab498dded", 16); static BigInteger crtCoef = new BigInteger("dae7651ee69ad1d081ec5e7188ae126f6004ff39556bde90e0b870962fa7b926d070686d8244fe5a9aa709a95686a104614834b0ada4b10f53197a5cb4c97339", 16); static String input = "4e6f77206973207468652074696d6520666f7220616c6c20676f6f64206d656e"; // // to check that we handling byte extension by big number correctly. // static String edgeInput = "ff6f77206973207468652074696d6520666f7220616c6c20676f6f64206d656e"; static byte[] oversizedSig = Hex.decode("01ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff004e6f77206973207468652074696d6520666f7220616c6c20676f6f64206d656e"); static byte[] dudBlock = Hex.decode("000fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff004e6f77206973207468652074696d6520666f7220616c6c20676f6f64206d656e"); static byte[] truncatedDataBlock = Hex.decode("0001ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff004e6f77206973207468652074696d6520666f7220616c6c20676f6f64206d656e"); static byte[] incorrectPadding = Hex.decode("0001ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff4e6f77206973207468652074696d6520666f7220616c6c20676f6f64206d656e"); static byte[] missingDataBlock = Hex.decode("0001ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff"); public String getName() { return "RSA"; } private void testStrictPKCS1Length(RSAKeyParameters pubParameters, RSAKeyParameters privParameters) { AsymmetricBlockCipher eng = new RSAEngine(); eng.init(true, privParameters); byte[] data = null; try { data = eng.processBlock(oversizedSig, 0, oversizedSig.length); } catch (Exception e) { fail("RSA: failed - exception " + e.toString(), e); } eng = new PKCS1Encoding(eng); eng.init(false, pubParameters); try { data = eng.processBlock(data, 0, data.length); fail("oversized signature block not recognised"); } catch (InvalidCipherTextException e) { if (!e.getMessage().equals("block incorrect size")) { fail("RSA: failed - exception " + e.toString(), e); } } //System.setProperty(PKCS1Encoding.STRICT_LENGTH_ENABLED_PROPERTY, "false"); System.getProperties().put(PKCS1Encoding.STRICT_LENGTH_ENABLED_PROPERTY, "false"); eng = new PKCS1Encoding(new RSAEngine()); eng.init(false, pubParameters); try { data = eng.processBlock(data, 0, data.length); } catch (InvalidCipherTextException e) { fail("RSA: failed - exception " + e.toString(), e); } System.getProperties().remove(PKCS1Encoding.STRICT_LENGTH_ENABLED_PROPERTY); } private void testTruncatedPKCS1Block(RSAKeyParameters pubParameters, RSAKeyParameters privParameters) { checkForPKCS1Exception(pubParameters, privParameters, truncatedDataBlock, "block truncated"); } private void testDudPKCS1Block(RSAKeyParameters pubParameters, RSAKeyParameters privParameters) { checkForPKCS1Exception(pubParameters, privParameters, dudBlock, "unknown block type"); } private void testWrongPaddingPKCS1Block(RSAKeyParameters pubParameters, RSAKeyParameters privParameters) { checkForPKCS1Exception(pubParameters, privParameters, incorrectPadding, "block padding incorrect"); } private void testMissingDataPKCS1Block(RSAKeyParameters pubParameters, RSAKeyParameters privParameters) { checkForPKCS1Exception(pubParameters, privParameters, missingDataBlock, "no data in block"); } private void checkForPKCS1Exception(RSAKeyParameters pubParameters, RSAKeyParameters privParameters, byte[] inputData, String expectedMessage) { AsymmetricBlockCipher eng = new RSAEngine(); eng.init(true, privParameters); byte[] data = null; try { data = eng.processBlock(inputData, 0, inputData.length); } catch (Exception e) { fail("RSA: failed - exception " + e.toString(), e); } eng = new PKCS1Encoding(eng); eng.init(false, pubParameters); try { data = eng.processBlock(data, 0, data.length); fail("missing data block not recognised"); } catch (InvalidCipherTextException e) { if (!e.getMessage().equals(expectedMessage)) { fail("RSA: failed - exception " + e.toString(), e); } } } private void testOAEP(RSAKeyParameters pubParameters, RSAKeyParameters privParameters) { // // OAEP - public encrypt, private decrypt // AsymmetricBlockCipher eng = new OAEPEncoding(new RSAEngine()); byte[] data = Hex.decode(input); eng.init(true, pubParameters); try { data = eng.processBlock(data, 0, data.length); } catch (Exception e) { fail("failed - exception " + e.toString(), e); } eng.init(false, privParameters); try { data = eng.processBlock(data, 0, data.length); } catch (Exception e) { fail("failed - exception " + e.toString(), e); } if (!input.equals(new String(Hex.encode(data)))) { fail("failed OAEP Test"); } } private void zeroBlockTest(CipherParameters encParameters, CipherParameters decParameters) { AsymmetricBlockCipher eng = new PKCS1Encoding(new RSAEngine()); eng.init(true, encParameters); if (eng.getOutputBlockSize() != ((PKCS1Encoding)eng).getUnderlyingCipher().getOutputBlockSize()) { fail("PKCS1 output block size incorrect"); } byte[] zero = new byte[0]; byte[] data = null; try { data = eng.processBlock(zero, 0, zero.length); } catch (Exception e) { fail("failed - exception " + e.toString(), e); } eng.init(false, decParameters); try { data = eng.processBlock(data, 0, data.length); } catch (Exception e) { fail("failed - exception " + e.toString(), e); } if (!Arrays.areEqual(zero, data)) { fail("failed PKCS1 zero Test"); } } public void performTest() { RSAKeyParameters pubParameters = new RSAKeyParameters(false, mod, pubExp); RSAKeyParameters privParameters = new RSAPrivateCrtKeyParameters(mod, pubExp, privExp, p, q, pExp, qExp, crtCoef); byte[] data = Hex.decode(edgeInput); // // RAW // AsymmetricBlockCipher eng = new RSAEngine(); eng.init(true, pubParameters); try { data = eng.processBlock(data, 0, data.length); } catch (Exception e) { fail("RSA: failed - exception " + e.toString(), e); } eng.init(false, privParameters); try { data = eng.processBlock(data, 0, data.length); } catch (Exception e) { fail("failed - exception " + e.toString(), e); } if (!edgeInput.equals(new String(Hex.encode(data)))) { fail("failed RAW edge Test"); } data = Hex.decode(input); eng.init(true, pubParameters); try { data = eng.processBlock(data, 0, data.length); } catch (Exception e) { fail("failed - exception " + e.toString(), e); } eng.init(false, privParameters); try { data = eng.processBlock(data, 0, data.length); } catch (Exception e) { fail("failed - exception " + e.toString(), e); } if (!input.equals(new String(Hex.encode(data)))) { fail("failed RAW Test"); } // // PKCS1 - public encrypt, private decrypt // eng = new PKCS1Encoding(eng); eng.init(true, pubParameters); if (eng.getOutputBlockSize() != ((PKCS1Encoding)eng).getUnderlyingCipher().getOutputBlockSize()) { fail("PKCS1 output block size incorrect"); } try { data = eng.processBlock(data, 0, data.length); } catch (Exception e) { fail("failed - exception " + e.toString(), e); } eng.init(false, privParameters); try { data = eng.processBlock(data, 0, data.length); } catch (Exception e) { fail("failed - exception " + e.toString(), e); } if (!input.equals(new String(Hex.encode(data)))) { fail("failed PKCS1 public/private Test"); } // // PKCS1 - private encrypt, public decrypt // eng = new PKCS1Encoding(((PKCS1Encoding)eng).getUnderlyingCipher()); eng.init(true, privParameters); try { data = eng.processBlock(data, 0, data.length); } catch (Exception e) { fail("failed - exception " + e.toString(), e); } eng.init(false, pubParameters); try { data = eng.processBlock(data, 0, data.length); } catch (Exception e) { fail("failed - exception " + e.toString(), e); } if (!input.equals(new String(Hex.encode(data)))) { fail("failed PKCS1 private/public Test"); } zeroBlockTest(pubParameters, privParameters); zeroBlockTest(privParameters, pubParameters); // // key generation test // RSAKeyPairGenerator pGen = new RSAKeyPairGenerator(); RSAKeyGenerationParameters genParam = new RSAKeyGenerationParameters( BigInteger.valueOf(0x11), new SecureRandom(), 768, 25); pGen.init(genParam); AsymmetricCipherKeyPair pair = pGen.generateKeyPair(); eng = new RSAEngine(); if (((RSAKeyParameters)pair.getPublic()).getModulus().bitLength() < 768) { fail("failed key generation (768) length test"); } eng.init(true, pair.getPublic()); try { data = eng.processBlock(data, 0, data.length); } catch (Exception e) { fail("failed - exception " + e.toString(), e); } eng.init(false, pair.getPrivate()); try { data = eng.processBlock(data, 0, data.length); } catch (Exception e) { fail("failed - exception " + e.toString(), e); } if (!input.equals(new String(Hex.encode(data)))) { fail("failed key generation (768) Test"); } genParam = new RSAKeyGenerationParameters(BigInteger.valueOf(0x11), new SecureRandom(), 1024, 25); pGen.init(genParam); pair = pGen.generateKeyPair(); eng.init(true, pair.getPublic()); if (((RSAKeyParameters)pair.getPublic()).getModulus().bitLength() < 1024) { fail("failed key generation (1024) length test"); } try { data = eng.processBlock(data, 0, data.length); } catch (Exception e) { fail("failed - exception " + e.toString(), e); } eng.init(false, pair.getPrivate()); try { data = eng.processBlock(data, 0, data.length); } catch (Exception e) { fail("failed - exception " + e.toString(), e); } if (!input.equals(new String(Hex.encode(data)))) { fail("failed key generation (1024) test"); } genParam = new RSAKeyGenerationParameters( BigInteger.valueOf(0x11), new SecureRandom(), 16, 25); pGen.init(genParam); for (int i = 0; i < 100; ++i) { pair = pGen.generateKeyPair(); RSAPrivateCrtKeyParameters privKey = (RSAPrivateCrtKeyParameters) pair.getPrivate(); BigInteger pqDiff = privKey.getP().subtract(privKey.getQ()).abs(); if (pqDiff.bitLength() < 5) { fail("P and Q too close in RSA key pair"); } } testOAEP(pubParameters, privParameters); testStrictPKCS1Length(pubParameters, privParameters); testDudPKCS1Block(pubParameters, privParameters); testMissingDataPKCS1Block(pubParameters, privParameters); testTruncatedPKCS1Block(pubParameters, privParameters); testWrongPaddingPKCS1Block(pubParameters, privParameters); try { new RSAEngine().processBlock(new byte[]{ 1 }, 0, 1); fail("failed initialisation check"); } catch (IllegalStateException e) { // expected } } public static void main( String[] args) { runTest(new RSATest()); } } bouncycastle-1.49.orig/test/src/org/bouncycastle/crypto/test/KDF2GeneratorTest.java0000644000175000017500000001023210540716527030025 0ustar ebourgebourgpackage org.bouncycastle.crypto.test; import org.bouncycastle.crypto.DataLengthException; import org.bouncycastle.crypto.DerivationFunction; import org.bouncycastle.crypto.digests.SHA1Digest; import org.bouncycastle.crypto.digests.SHA256Digest; import org.bouncycastle.crypto.digests.ShortenedDigest; import org.bouncycastle.crypto.generators.KDF2BytesGenerator; import org.bouncycastle.crypto.params.KDFParameters; import org.bouncycastle.util.encoders.Hex; import org.bouncycastle.util.test.SimpleTest; /** * KDF2 tests - vectors from ISO 18033. */ public class KDF2GeneratorTest extends SimpleTest { private byte[] seed1 = Hex.decode("d6e168c5f256a2dcff7ef12facd390f393c7a88d"); private byte[] mask1 = Hex.decode( "df79665bc31dc5a62f70535e52c53015b9d37d412ff3c119343959" + "9e1b628774c50d9ccb78d82c425e4521ee47b8c36a4bcffe8b8112a8" + "9312fc04420a39de99223890e74ce10378bc515a212b97b8a6447ba6" + "a8870278f0262727ca041fa1aa9f7b5d1cf7f308232fe861"); private byte[] seed2 = Hex.decode( "032e45326fa859a72ec235acff929b15d1372e30b207255f0611b8f785d7643741" + "52e0ac009e509e7ba30cd2f1778e113b64e135cf4e2292c75efe5288edfda4"); private byte[] mask2 = Hex.decode( "10a2403db42a8743cb989de86e668d168cbe604611ac179f819a3d18412e9eb456" + "68f2923c087c12fee0c5a0d2a8aa70185401fbbd99379ec76c663e875a60b4aacb13" + "19fa11c3365a8b79a44669f26fb555c80391847b05eca1cb5cf8c2d531448d33fbac" + "a19f6410ee1fcb260892670e0814c348664f6a7248aaf998a3acc6"); private byte[] adjustedMask2 = Hex.decode( "10a2403db42a8743cb989de86e668d168cbe6046e23ff26f741e87949a3bba1311ac1" + "79f819a3d18412e9eb45668f2923c087c1299005f8d5fd42ca257bc93e8fee0c5a0d2" + "a8aa70185401fbbd99379ec76c663e9a29d0b70f3fe261a59cdc24875a60b4aacb131" + "9fa11c3365a8b79a44669f26fba933d012db213d7e3b16349"); private byte[] sha1Mask = Hex.decode( "0e6a26eb7b956ccb8b3bdc1ca975bc57c3989e8fbad31a224655d800c46954840ff32" + "052cdf0d640562bdfadfa263cfccf3c52b29f2af4a1869959bc77f854cf15bd7a2519" + "2985a842dbff8e13efee5b7e7e55bbe4d389647c686a9a9ab3fb889b2d7767d3837ee" + "a4e0a2f04b53ca8f50fb31225c1be2d0126c8c7a4753b0807"); private byte[] seed3 = Hex.decode("CA7C0F8C3FFA87A96E1B74AC8E6AF594347BB40A"); private byte[] mask3 = Hex.decode("744AB703F5BC082E59185F6D049D2D367DB245C2"); private byte[] seed4 = Hex.decode("0499B502FC8B5BAFB0F4047E731D1F9FD8CD0D8881"); private byte[] mask4 = Hex.decode("03C62280C894E103C680B13CD4B4AE740A5EF0C72547292F82DC6B1777F47D63BA9D1EA732DBF386"); public KDF2GeneratorTest() { } public void performTest() { checkMask(1, new KDF2BytesGenerator(new ShortenedDigest(new SHA256Digest(), 20)), seed1, mask1); checkMask(2, new KDF2BytesGenerator(new ShortenedDigest(new SHA256Digest(), 20)), seed2, mask2); checkMask(3, new KDF2BytesGenerator(new SHA256Digest()), seed2, adjustedMask2); checkMask(4, new KDF2BytesGenerator(new SHA1Digest()), seed2, sha1Mask); checkMask(5, new KDF2BytesGenerator(new SHA1Digest()), seed3, mask3); checkMask(6, new KDF2BytesGenerator(new SHA1Digest()), seed4, mask4); try { new KDF2BytesGenerator(new SHA1Digest()).generateBytes(new byte[10], 0, 20); fail("short input array not caught"); } catch (DataLengthException e) { // expected } } private void checkMask( int count, DerivationFunction kdf, byte[] seed, byte[] result) { byte[] data = new byte[result.length]; kdf.init(new KDFParameters(seed, new byte[0])); kdf.generateBytes(data, 0, data.length); if (!areEqual(result, data)) { fail("KDF2 failed generator test " + count); } } public String getName() { return "KDF2"; } public static void main( String[] args) { runTest(new KDF2GeneratorTest()); } } bouncycastle-1.49.orig/test/src/org/bouncycastle/crypto/test/GOST3410Test.java0000644000175000017500000016151410531736712026564 0ustar ebourgebourgpackage org.bouncycastle.crypto.test; import org.bouncycastle.crypto.AsymmetricCipherKeyPair; import org.bouncycastle.crypto.generators.GOST3410KeyPairGenerator; import org.bouncycastle.crypto.generators.GOST3410ParametersGenerator; import org.bouncycastle.crypto.params.GOST3410KeyGenerationParameters; import org.bouncycastle.crypto.params.GOST3410Parameters; import org.bouncycastle.crypto.params.ParametersWithRandom; import org.bouncycastle.crypto.signers.GOST3410Signer; import org.bouncycastle.util.encoders.Hex; import org.bouncycastle.util.test.FixedSecureRandom; import org.bouncycastle.util.test.NumberParsing; import org.bouncycastle.util.test.SimpleTestResult; import org.bouncycastle.util.test.Test; import org.bouncycastle.util.test.TestResult; import java.math.BigInteger; import java.security.SecureRandom; public class GOST3410Test implements Test { byte[] hashmessage = Hex.decode("3042453136414534424341374533364339313734453431443642453241453435"); private byte[] zeroTwo(int length) { byte[] data = new byte[length]; data[data.length - 1] = 0x02; return data; } private class GOST3410_TEST1_512 implements Test { public String getName() { return "GOST3410-TEST1-512"; } FixedSecureRandom init_random = new FixedSecureRandom(new byte[][] { Hex.decode("00005EC900007341"), zeroTwo(64) }); FixedSecureRandom random = new FixedSecureRandom(Hex.decode("90F3A564439242F5186EBB224C8E223811B7105C64E4F5390807E6362DF4C72A")); FixedSecureRandom keyRandom = new FixedSecureRandom(Hex.decode("3036314538303830343630454235324435324234314132373832433138443046")); BigInteger pValue = new BigInteger("EE8172AE8996608FB69359B89EB82A69854510E2977A4D63BC97322CE5DC3386EA0A12B343E9190F23177539845839786BB0C345D165976EF2195EC9B1C379E3", 16); BigInteger qValue = new BigInteger("98915E7EC8265EDFCDA31E88F24809DDB064BDC7285DD50D7289F0AC6F49DD2D", 16); public TestResult perform() { BigInteger r = new BigInteger("3e5f895e276d81d2d52c0763270a458157b784c57abdbd807bc44fd43a32ac06",16); BigInteger s = new BigInteger("3f0dd5d4400d47c08e4ce505ff7434b6dbf729592e37c74856dab85115a60955",16); GOST3410ParametersGenerator pGen = new GOST3410ParametersGenerator(); pGen.init(512, 1, init_random); GOST3410Parameters params = pGen.generateParameters(); if (params.getValidationParameters() == null) { return new SimpleTestResult(false, getName() + "validation parameters wrong"); } if (params.getValidationParameters().getC() != 29505 || params.getValidationParameters().getX0() != 24265) { return new SimpleTestResult(false, getName() + "validation parameters values wrong"); } if (!init_random.isExhausted()) { return new SimpleTestResult(false, getName() + ": unexpected number of bytes used from 'init_random'."); } if (!pValue.equals(params.getP()) || !qValue.equals(params.getQ())) { return new SimpleTestResult(false, getName() + ": p or q wrong"); } GOST3410KeyPairGenerator GOST3410KeyGen = new GOST3410KeyPairGenerator(); GOST3410KeyGenerationParameters genParam = new GOST3410KeyGenerationParameters(keyRandom, params); GOST3410KeyGen.init(genParam); AsymmetricCipherKeyPair pair = GOST3410KeyGen.generateKeyPair(); if (!keyRandom.isExhausted()) { return new SimpleTestResult(false, getName() + ": unexpected number of bytes used from 'keyRandom'."); } ParametersWithRandom param = new ParametersWithRandom(pair.getPrivate(), random); GOST3410Signer gost3410 = new GOST3410Signer(); gost3410.init(true, param); BigInteger[] sig = gost3410.generateSignature(hashmessage); if (!random.isExhausted()) { return new SimpleTestResult(false, getName() + ": unexpected number of bytes used from 'random'."); } if (!r.equals(sig[0])) { return new SimpleTestResult(false, getName() + ": r component wrong." + System.getProperty("line.separator") + " expecting: " + r.toString(16) + System.getProperty("line.separator") + " got : " + sig[0].toString(16)); } if (!s.equals(sig[1])) { return new SimpleTestResult(false, getName() + ": s component wrong." + System.getProperty("line.separator") + " expecting: " + s.toString(16) + System.getProperty("line.separator") + " got : " + sig[1].toString(16)); } gost3410.init(false, pair.getPublic()); if (gost3410.verifySignature(hashmessage, sig[0], sig[1])) { return new SimpleTestResult(true, getName() + ": Okay"); } else { return new SimpleTestResult(false, getName() + ": verification fails"); } } } private class GOST3410_TEST2_512 implements Test { public String getName() { return "GOST3410-TEST2-512"; } FixedSecureRandom init_random = new FixedSecureRandom(new byte[][] { Hex.decode("000000003DFC46F1000000000000000D"), zeroTwo(64) }); FixedSecureRandom random = new FixedSecureRandom(Hex.decode("90F3A564439242F5186EBB224C8E223811B7105C64E4F5390807E6362DF4C72A")); FixedSecureRandom keyRandom = new FixedSecureRandom(Hex.decode("3036314538303830343630454235324435324234314132373832433138443046")); BigInteger pValue = new BigInteger("8b08eb135af966aab39df294538580c7da26765d6d38d30cf1c06aae0d1228c3316a0e29198460fad2b19dc381c15c888c6dfd0fc2c565abb0bf1faff9518f85", 16); BigInteger qValue = new BigInteger("931a58fb6f0dcdf2fe7549bc3f19f4724b56898f7f921a076601edb18c93dc75", 16); public TestResult perform() { BigInteger r = new BigInteger("7c07c8cf035c2a1cb2b7fae5807ac7cd623dfca7a1a68f6d858317822f1ea00d",16); BigInteger s = new BigInteger("7e9e036a6ff87dbf9b004818252b1f6fc310bdd4d17cb8c37d9c36c7884de60c",16); GOST3410ParametersGenerator pGen = new GOST3410ParametersGenerator(); pGen.init(512, 2, init_random); GOST3410Parameters params = pGen.generateParameters(); if (!init_random.isExhausted()) { return new SimpleTestResult(false, getName() + ": unexpected number of bytes used from 'init_random'."); } if (params.getValidationParameters() == null) { return new SimpleTestResult(false, getName() + ": validation parameters wrong"); } if (params.getValidationParameters().getCL() != 13 || params.getValidationParameters().getX0L() != 1039943409) { return new SimpleTestResult(false, getName() + ": validation parameters values wrong"); } if (!pValue.equals(params.getP()) || !qValue.equals(params.getQ())) { return new SimpleTestResult(false, getName() + ": p or q wrong"); } GOST3410KeyPairGenerator GOST3410KeyGen = new GOST3410KeyPairGenerator(); GOST3410KeyGenerationParameters genParam = new GOST3410KeyGenerationParameters(keyRandom, params); GOST3410KeyGen.init(genParam); AsymmetricCipherKeyPair pair = GOST3410KeyGen.generateKeyPair(); if (!keyRandom.isExhausted()) { return new SimpleTestResult(false, getName() + ": unexpected number of bytes used from 'keyRandom'."); } ParametersWithRandom param = new ParametersWithRandom(pair.getPrivate(), random); GOST3410Signer GOST3410 = new GOST3410Signer(); GOST3410.init(true, param); BigInteger[] sig = GOST3410.generateSignature(hashmessage); if (!random.isExhausted()) { return new SimpleTestResult(false, getName() + ": unexpected number of bytes used from 'random'."); } if (!r.equals(sig[0])) { return new SimpleTestResult(false, getName() + ": r component wrong." + System.getProperty("line.separator") + " expecting: " + r.toString(16) + System.getProperty("line.separator") + " got : " + sig[0].toString(16)); } if (!s.equals(sig[1])) { return new SimpleTestResult(false, getName() + ": s component wrong." + System.getProperty("line.separator") + " expecting: " + s.toString(16) + System.getProperty("line.separator") + " got : " + sig[1].toString(16)); } GOST3410.init(false, pair.getPublic()); if (GOST3410.verifySignature(hashmessage, sig[0], sig[1])) { return new SimpleTestResult(true, getName() + ": Okay"); } else { return new SimpleTestResult(false, getName() + ": verification fails"); } } } private class GOST3410_TEST1_1024 implements Test { public String getName() { return "GOST3410-TEST1-1024"; } SecureRandom init_random = new SecureRandom() { boolean firstInt = true; public int nextInt() { String x0 = "0xA565"; String c = "0x538B"; if (firstInt) { firstInt = false; return NumberParsing.decodeIntFromHex(x0); } return NumberParsing.decodeIntFromHex(c); } public void nextBytes(byte[] bytes) { byte[] d = Hex.decode("02"); System.arraycopy(d, 0, bytes, bytes.length-d.length, d.length); } }; SecureRandom random = new SecureRandom() { public void nextBytes(byte[] bytes) { byte[] k = Hex.decode("90F3A564439242F5186EBB224C8E223811B7105C64E4F5390807E6362DF4C72A"); int i; for (i = 0; i < (bytes.length - k.length); i += k.length) { System.arraycopy(k, 0, bytes, i, k.length); } if (i > bytes.length) { System.arraycopy(k, 0, bytes, i - k.length, bytes.length - (i - k.length)); } else { System.arraycopy(k, 0, bytes, i, bytes.length - i); } } }; SecureRandom keyRandom = new SecureRandom() { public void nextBytes(byte[] bytes) { byte[] x = Hex.decode("3036314538303830343630454235324435324234314132373832433138443046"); int i; for (i = 0; i < (bytes.length - x.length); i += x.length) { System.arraycopy(x, 0, bytes, i, x.length); } if (i > bytes.length) { System.arraycopy(x, 0, bytes, i - x.length, bytes.length - (i - x.length)); } else { System.arraycopy(x, 0, bytes, i, bytes.length - i); } } }; BigInteger pValue = new BigInteger("ab8f37938356529e871514c1f48c5cbce77b2f4fc9a2673ac2c1653da8984090c0ac73775159a26bef59909d4c9846631270e16653a6234668f2a52a01a39b921490e694c0f104b58d2e14970fccb478f98d01e975a1028b9536d912de5236d2dd2fc396b77153594d4178780e5f16f718471e2111c8ce64a7d7e196fa57142d", 16); BigInteger qValue = new BigInteger("bcc02ca0ce4f0753ec16105ee5d530aa00d39f3171842ab2c334a26b5f576e0f", 16); public TestResult perform() { BigInteger r = new BigInteger("a8790aabbd5a998ff524bad048ac69cd1faff2dab048265c8d60d1471c44a9ee",16); BigInteger s = new BigInteger("30df5ba32ac77170b9632559bef7d37620017756dff3fea1088b4267db0944b8",16); GOST3410ParametersGenerator pGen = new GOST3410ParametersGenerator(); pGen.init(1024, 1, init_random); GOST3410Parameters params = pGen.generateParameters(); if (!pValue.equals(params.getP()) || !qValue.equals(params.getQ())) { return new SimpleTestResult(false, getName() + ": p or q wrong"); } GOST3410KeyPairGenerator GOST3410KeyGen = new GOST3410KeyPairGenerator(); GOST3410KeyGenerationParameters genParam = new GOST3410KeyGenerationParameters(keyRandom, params); GOST3410KeyGen.init(genParam); AsymmetricCipherKeyPair pair = GOST3410KeyGen.generateKeyPair(); ParametersWithRandom param = new ParametersWithRandom(pair.getPrivate(), random); GOST3410Signer GOST3410 = new GOST3410Signer(); GOST3410.init(true, param); BigInteger[] sig = GOST3410.generateSignature(hashmessage); if (!r.equals(sig[0])) { return new SimpleTestResult(false, getName() + ": r component wrong." + System.getProperty("line.separator") + " expecting: " + r.toString(16) + System.getProperty("line.separator") + " got : " + sig[0].toString(16)); } if (!s.equals(sig[1])) { return new SimpleTestResult(false, getName() + ": s component wrong." + System.getProperty("line.separator") + " expecting: " + s.toString(16) + System.getProperty("line.separator") + " got : " + sig[1].toString(16)); } GOST3410.init(false, pair.getPublic()); if (GOST3410.verifySignature(hashmessage, sig[0], sig[1])) { return new SimpleTestResult(true, getName() + ": Okay"); } else { return new SimpleTestResult(false, getName() + ": verification fails"); } } } private class GOST3410_TEST2_1024 implements Test { public String getName() { return "GOST3410-TEST2-1024"; } SecureRandom init_random = new SecureRandom() { boolean firstLong = true; public long nextLong() { String x0 = "0x3DFC46F1"; String c = "0xD"; if (firstLong) { firstLong = false; return NumberParsing.decodeLongFromHex(x0); } return NumberParsing.decodeLongFromHex(c); } public void nextBytes(byte[] bytes) { byte[] d = Hex.decode("02"); System.arraycopy(d, 0, bytes, bytes.length-d.length, d.length); } }; SecureRandom random = new SecureRandom() { public void nextBytes(byte[] bytes) { byte[] k = Hex.decode("90F3A564439242F5186EBB224C8E223811B7105C64E4F5390807E6362DF4C72A"); int i; for (i = 0; i < (bytes.length - k.length); i += k.length) { System.arraycopy(k, 0, bytes, i, k.length); } if (i > bytes.length) { System.arraycopy(k, 0, bytes, i - k.length, bytes.length - (i - k.length)); } else { System.arraycopy(k, 0, bytes, i, bytes.length - i); } } }; SecureRandom keyRandom = new SecureRandom() { public void nextBytes(byte[] bytes) { byte[] x = Hex.decode("3036314538303830343630454235324435324234314132373832433138443046"); int i; for (i = 0; i < (bytes.length - x.length); i += x.length) { System.arraycopy(x, 0, bytes, i, x.length); } if (i > bytes.length) { System.arraycopy(x, 0, bytes, i - x.length, bytes.length - (i - x.length)); } else { System.arraycopy(x, 0, bytes, i, bytes.length - i); } } }; BigInteger pValue = new BigInteger("e2c4191c4b5f222f9ac2732562f6d9b4f18e7fb67a290ea1e03d750f0b9806755fc730d975bf3faa606d05c218b35a6c3706919aab92e0c58b1de4531c8fa8e7af43c2bff016251e21b2870897f6a27ac4450bca235a5b748ad386e4a0e4dfcb09152435abcfe48bd0b126a8122c7382f285a9864615c66decddf6afd355dfb7", 16); BigInteger qValue = new BigInteger("931a58fb6f0dcdf2fe7549bc3f19f4724b56898f7f921a076601edb18c93dc75", 16); public TestResult perform() { BigInteger r = new BigInteger("81d69a192e9c7ac21fc07da41bd07e230ba6a94eb9f3c1fd104c7bd976733ca5",16); BigInteger s = new BigInteger("315c879c8414f35feb4deb15e7cc0278c48e6ca1596325d6959338d860b0c47a",16); GOST3410ParametersGenerator pGen = new GOST3410ParametersGenerator(); pGen.init(1024, 2, init_random); GOST3410Parameters params = pGen.generateParameters(); if (!pValue.equals(params.getP()) || !qValue.equals(params.getQ())) { return new SimpleTestResult(false, getName() + ": p or q wrong"); } GOST3410KeyPairGenerator GOST3410KeyGen = new GOST3410KeyPairGenerator(); GOST3410KeyGenerationParameters genParam = new GOST3410KeyGenerationParameters(keyRandom, params); GOST3410KeyGen.init(genParam); AsymmetricCipherKeyPair pair = GOST3410KeyGen.generateKeyPair(); ParametersWithRandom param = new ParametersWithRandom(pair.getPrivate(), random); GOST3410Signer GOST3410 = new GOST3410Signer(); GOST3410.init(true, param); BigInteger[] sig = GOST3410.generateSignature(hashmessage); if (!r.equals(sig[0])) { return new SimpleTestResult(false, getName() + ": r component wrong." + System.getProperty("line.separator") + " expecting: " + r.toString(16) + System.getProperty("line.separator") + " got : " + sig[0].toString(16)); } if (!s.equals(sig[1])) { return new SimpleTestResult(false, getName() + ": s component wrong." + System.getProperty("line.separator") + " expecting: " + s.toString(16) + System.getProperty("line.separator") + " got : " + sig[1].toString(16)); } GOST3410.init(false, pair.getPublic()); if (GOST3410.verifySignature(hashmessage, sig[0], sig[1])) { return new SimpleTestResult(true, getName() + ": Okay"); } else { return new SimpleTestResult(false, getName() + ": verification fails"); } } } private class GOST3410_AParam implements Test { public String getName() { return "GOST3410-AParam"; } SecureRandom init_random = new SecureRandom() { boolean firstLong = true; public long nextLong() { String x0 = "0x520874F5"; String c = "0xEE39ADB3"; if (firstLong) { firstLong = false; return NumberParsing.decodeLongFromHex(x0); } return NumberParsing.decodeLongFromHex(c); } public void nextBytes(byte[] bytes) { byte[] d = Hex.decode("02"); System.arraycopy(d, 0, bytes, bytes.length-d.length, d.length); } }; SecureRandom random = new SecureRandom() { public void nextBytes(byte[] bytes) { byte[] k = Hex.decode("90F3A564439242F5186EBB224C8E223811B7105C64E4F5390807E6362DF4C72A"); int i; for (i = 0; i < (bytes.length - k.length); i += k.length) { System.arraycopy(k, 0, bytes, i, k.length); } if (i > bytes.length) { System.arraycopy(k, 0, bytes, i - k.length, bytes.length - (i - k.length)); } else { System.arraycopy(k, 0, bytes, i, bytes.length - i); } } }; SecureRandom keyRandom = new SecureRandom() { public void nextBytes(byte[] bytes) { byte[] x = Hex.decode("3036314538303830343630454235324435324234314132373832433138443046"); int i; for (i = 0; i < (bytes.length - x.length); i += x.length) { System.arraycopy(x, 0, bytes, i, x.length); } if (i > bytes.length) { System.arraycopy(x, 0, bytes, i - x.length, bytes.length - (i - x.length)); } else { System.arraycopy(x, 0, bytes, i, bytes.length - i); } } }; BigInteger pValue = new BigInteger("b4e25efb018e3c8b87505e2a67553c5edc56c2914b7e4f89d23f03f03377e70a2903489dd60e78418d3d851edb5317c4871e40b04228c3b7902963c4b7d85d52b9aa88f2afdbeb28da8869d6df846a1d98924e925561bd69300b9ddd05d247b5922d967cbb02671881c57d10e5ef72d3e6dad4223dc82aa1f7d0294651a480df", 16); BigInteger qValue = new BigInteger("972432a437178b30bd96195b773789ab2fff15594b176dd175b63256ee5af2cf", 16); public TestResult perform() { BigInteger r = new BigInteger("64a8856628e5669d85f62cd763dd4a99bc56d33dc0e1859122855d141e9e4774",16); BigInteger s = new BigInteger("319ebac97092b288d469a4b988248794f60c865bc97858d9a3135c6d1a1bf2dd",16); GOST3410ParametersGenerator pGen = new GOST3410ParametersGenerator(); pGen.init(1024, 2, init_random); GOST3410Parameters params = pGen.generateParameters(); if (!pValue.equals(params.getP()) || !qValue.equals(params.getQ())) { return new SimpleTestResult(false, getName() + ": p or q wrong"); } GOST3410KeyPairGenerator GOST3410KeyGen = new GOST3410KeyPairGenerator(); GOST3410KeyGenerationParameters genParam = new GOST3410KeyGenerationParameters(keyRandom, params); GOST3410KeyGen.init(genParam); AsymmetricCipherKeyPair pair = GOST3410KeyGen.generateKeyPair(); ParametersWithRandom param = new ParametersWithRandom(pair.getPrivate(), random); GOST3410Signer GOST3410 = new GOST3410Signer(); GOST3410.init(true, param); BigInteger[] sig = GOST3410.generateSignature(hashmessage); if (!r.equals(sig[0])) { return new SimpleTestResult(false, getName() + ": r component wrong." + System.getProperty("line.separator") + " expecting: " + r.toString(16) + System.getProperty("line.separator") + " got : " + sig[0].toString(16)); } if (!s.equals(sig[1])) { return new SimpleTestResult(false, getName() + ": s component wrong." + System.getProperty("line.separator") + " expecting: " + s.toString(16) + System.getProperty("line.separator") + " got : " + sig[1].toString(16)); } GOST3410.init(false, pair.getPublic()); if (GOST3410.verifySignature(hashmessage, sig[0], sig[1])) { return new SimpleTestResult(true, getName() + ": Okay"); } else { return new SimpleTestResult(false, getName() + ": verification fails"); } } } private class GOST3410_BParam implements Test { public String getName() { return "GOST3410-BParam"; } SecureRandom init_random = new SecureRandom() { boolean firstLong = true; public long nextLong() { String x0 = "0x5B977CDB"; String c = "0x6E9692DD"; if (firstLong) { firstLong = false; return NumberParsing.decodeLongFromHex(x0); } return NumberParsing.decodeLongFromHex(c); } public void nextBytes(byte[] bytes) { byte[] d = Hex.decode("bc3cbbdb7e6f848286e19ad9a27a8e297e5b71c53dd974cdf60f937356df69cbc97a300ccc71685c553046147f11568c4fddf363d9d886438345a62c3b75963d6546adfabf31b31290d12cae65ecb8309ef66782"); System.arraycopy(d, 0, bytes, bytes.length-d.length, d.length); } }; SecureRandom random = new SecureRandom() { public void nextBytes(byte[] bytes) { byte[] k = Hex.decode("90F3A564439242F5186EBB224C8E223811B7105C64E4F5390807E6362DF4C72A"); int i; for (i = 0; i < (bytes.length - k.length); i += k.length) { System.arraycopy(k, 0, bytes, i, k.length); } if (i > bytes.length) { System.arraycopy(k, 0, bytes, i - k.length, bytes.length - (i - k.length)); } else { System.arraycopy(k, 0, bytes, i, bytes.length - i); } } }; SecureRandom keyRandom = new SecureRandom() { public void nextBytes(byte[] bytes) { byte[] x = Hex.decode("3036314538303830343630454235324435324234314132373832433138443046"); int i; for (i = 0; i < (bytes.length - x.length); i += x.length) { System.arraycopy(x, 0, bytes, i, x.length); } if (i > bytes.length) { System.arraycopy(x, 0, bytes, i - x.length, bytes.length - (i - x.length)); } else { System.arraycopy(x, 0, bytes, i, bytes.length - i); } } }; BigInteger pValue = new BigInteger("c6971fc57524b30c9018c5e621de15499736854f56a6f8aee65a7a404632b3540f09020f67f04dc2e6783b141dceffd21a703035b7d0187c6e12cb4229922bafdb2225b73e6b23a0de36e20047065aea000c1a374283d0ad8dc1981e3995f0bb8c72526041fcb98ae6163e1e71a669d8364e9c4c3188f673c5f8ee6fadb41abf", 16); BigInteger qValue = new BigInteger("b09d634c10899cd7d4c3a7657403e05810b07c61a688bab2c37f475e308b0607", 16); public TestResult perform() { BigInteger r = new BigInteger("860d82c60e9502cd00c0e9e1f6563feafec304801974d745c5e02079946f729e",16); BigInteger s = new BigInteger("7ef49264ef022801aaa03033cd97915235fbab4c823ed936b0f360c22114688a",16); GOST3410ParametersGenerator pGen = new GOST3410ParametersGenerator(); pGen.init(1024, 2, init_random); GOST3410Parameters params = pGen.generateParameters(); if (!pValue.equals(params.getP()) || !qValue.equals(params.getQ())) { return new SimpleTestResult(false, getName() + ": p or q wrong"); } GOST3410KeyPairGenerator GOST3410KeyGen = new GOST3410KeyPairGenerator(); GOST3410KeyGenerationParameters genParam = new GOST3410KeyGenerationParameters(keyRandom, params); GOST3410KeyGen.init(genParam); AsymmetricCipherKeyPair pair = GOST3410KeyGen.generateKeyPair(); ParametersWithRandom param = new ParametersWithRandom(pair.getPrivate(), random); GOST3410Signer GOST3410 = new GOST3410Signer(); GOST3410.init(true, param); BigInteger[] sig = GOST3410.generateSignature(hashmessage); if (!r.equals(sig[0])) { return new SimpleTestResult(false, getName() + ": r component wrong." + System.getProperty("line.separator") + " expecting: " + r.toString(16) + System.getProperty("line.separator") + " got : " + sig[0].toString(16)); } if (!s.equals(sig[1])) { return new SimpleTestResult(false, getName() + ": s component wrong." + System.getProperty("line.separator") + " expecting: " + s.toString(16) + System.getProperty("line.separator") + " got : " + sig[1].toString(16)); } GOST3410.init(false, pair.getPublic()); if (GOST3410.verifySignature(hashmessage, sig[0], sig[1])) { return new SimpleTestResult(true, getName() + ": Okay"); } else { return new SimpleTestResult(false, getName() + ": verification fails"); } } } private class GOST3410_CParam implements Test { public String getName() { return "GOST3410-CParam"; } SecureRandom init_random = new SecureRandom() { boolean firstLong = true; public long nextLong() { String x0 = "0x43848744"; String c = "0xB50A826D"; if (firstLong) { firstLong = false; return NumberParsing.decodeLongFromHex(x0); } return NumberParsing.decodeLongFromHex(c); } public void nextBytes(byte[] bytes) { byte[] d = Hex.decode("7F575E8194BC5BDF"); System.arraycopy(d, 0, bytes, bytes.length-d.length, d.length); } }; SecureRandom random = new SecureRandom() { public void nextBytes(byte[] bytes) { byte[] k = Hex.decode("90F3A564439242F5186EBB224C8E223811B7105C64E4F5390807E6362DF4C72A"); int i; for (i = 0; i < (bytes.length - k.length); i += k.length) { System.arraycopy(k, 0, bytes, i, k.length); } if (i > bytes.length) { System.arraycopy(k, 0, bytes, i - k.length, bytes.length - (i - k.length)); } else { System.arraycopy(k, 0, bytes, i, bytes.length - i); } } }; SecureRandom keyRandom = new SecureRandom() { public void nextBytes(byte[] bytes) { byte[] x = Hex.decode("3036314538303830343630454235324435324234314132373832433138443046"); int i; for (i = 0; i < (bytes.length - x.length); i += x.length) { System.arraycopy(x, 0, bytes, i, x.length); } if (i > bytes.length) { System.arraycopy(x, 0, bytes, i - x.length, bytes.length - (i - x.length)); } else { System.arraycopy(x, 0, bytes, i, bytes.length - i); } } }; BigInteger pValue = new BigInteger("9d88e6d7fe3313bd2e745c7cdd2ab9ee4af3c8899e847de74a33783ea68bc30588ba1f738c6aaf8ab350531f1854c3837cc3c860ffd7e2e106c3f63b3d8a4c034ce73942a6c3d585b599cf695ed7a3c4a93b2b947b7157bb1a1c043ab41ec8566c6145e938a611906de0d32e562494569d7e999a0dda5c879bdd91fe124df1e9", 16); BigInteger qValue = new BigInteger("fadd197abd19a1b4653eecf7eca4d6a22b1f7f893b641f901641fbb555354faf", 16); public TestResult perform() { BigInteger r = new BigInteger("4deb95a0b35e7ed7edebe9bef5a0f93739e16b7ff27fe794d989d0c13159cfbc",16); BigInteger s = new BigInteger("e1d0d30345c24cfeb33efde3deee5fbbda78ddc822b719d860cd0ba1fb6bd43b",16); GOST3410ParametersGenerator pGen = new GOST3410ParametersGenerator(); pGen.init(1024, 2, init_random); GOST3410Parameters params = pGen.generateParameters(); if (!pValue.equals(params.getP()) || !qValue.equals(params.getQ())) { return new SimpleTestResult(false, getName() + ": p or q wrong"); } GOST3410KeyPairGenerator GOST3410KeyGen = new GOST3410KeyPairGenerator(); GOST3410KeyGenerationParameters genParam = new GOST3410KeyGenerationParameters(keyRandom, params); GOST3410KeyGen.init(genParam); AsymmetricCipherKeyPair pair = GOST3410KeyGen.generateKeyPair(); ParametersWithRandom param = new ParametersWithRandom(pair.getPrivate(), random); GOST3410Signer GOST3410 = new GOST3410Signer(); GOST3410.init(true, param); BigInteger[] sig = GOST3410.generateSignature(hashmessage); if (!r.equals(sig[0])) { return new SimpleTestResult(false, getName() + ": r component wrong." + System.getProperty("line.separator") + " expecting: " + r.toString(16) + System.getProperty("line.separator") + " got : " + sig[0].toString(16)); } if (!s.equals(sig[1])) { return new SimpleTestResult(false, getName() + ": s component wrong." + System.getProperty("line.separator") + " expecting: " + s.toString(16) + System.getProperty("line.separator") + " got : " + sig[1].toString(16)); } GOST3410.init(false, pair.getPublic()); if (GOST3410.verifySignature(hashmessage, sig[0], sig[1])) { return new SimpleTestResult(true, getName() + ": Okay"); } else { return new SimpleTestResult(false, getName() + ": verification fails"); } } } private class GOST3410_DParam implements Test { public String getName() { return "GOST3410-DParam"; } SecureRandom init_random = new SecureRandom() { boolean firstLong = true; public long nextLong() { String x0 = "0x13DA8B9D"; String c = "0xA0E9DE4B"; if (firstLong) { firstLong = false; return NumberParsing.decodeLongFromHex(x0); } return NumberParsing.decodeLongFromHex(c); } public void nextBytes(byte[] bytes) { byte[] d = Hex.decode("41ab97857f42614355d32db0b1069f109a4da283676c7c53a68185b4"); System.arraycopy(d, 0, bytes, bytes.length-d.length, d.length); } }; SecureRandom random = new SecureRandom() { public void nextBytes(byte[] bytes) { byte[] k = Hex.decode("90F3A564439242F5186EBB224C8E223811B7105C64E4F5390807E6362DF4C72A"); int i; for (i = 0; i < (bytes.length - k.length); i += k.length) { System.arraycopy(k, 0, bytes, i, k.length); } if (i > bytes.length) { System.arraycopy(k, 0, bytes, i - k.length, bytes.length - (i - k.length)); } else { System.arraycopy(k, 0, bytes, i, bytes.length - i); } } }; SecureRandom keyRandom = new SecureRandom() { public void nextBytes(byte[] bytes) { byte[] x = Hex.decode("3036314538303830343630454235324435324234314132373832433138443046"); int i; for (i = 0; i < (bytes.length - x.length); i += x.length) { System.arraycopy(x, 0, bytes, i, x.length); } if (i > bytes.length) { System.arraycopy(x, 0, bytes, i - x.length, bytes.length - (i - x.length)); } else { System.arraycopy(x, 0, bytes, i, bytes.length - i); } } }; BigInteger pValue = new BigInteger("80f102d32b0fd167d069c27a307adad2c466091904dbaa55d5b8cc7026f2f7a1919b890cb652c40e054e1e9306735b43d7b279eddf9102001cd9e1a831fe8a163eed89ab07cf2abe8242ac9dedddbf98d62cddd1ea4f5f15d3a42a6677bdd293b24260c0f27c0f1d15948614d567b66fa902baa11a69ae3bceadbb83e399c9b5", 16); BigInteger qValue = new BigInteger("f0f544c418aac234f683f033511b65c21651a6078bda2d69bb9f732867502149", 16); public TestResult perform() { BigInteger r = new BigInteger("712592d285b792e33b8a9a11e8e6c4f512ddf0042972bbfd1abb0a93e8fc6f54",16); BigInteger s = new BigInteger("2cf26758321258b130d5612111339f09ceb8668241f3482e38baa56529963f07",16); GOST3410ParametersGenerator pGen = new GOST3410ParametersGenerator(); pGen.init(1024, 2, init_random); GOST3410Parameters params = pGen.generateParameters(); if (!pValue.equals(params.getP()) || !qValue.equals(params.getQ())) { return new SimpleTestResult(false, getName() + ": p or q wrong"); } GOST3410KeyPairGenerator GOST3410KeyGen = new GOST3410KeyPairGenerator(); GOST3410KeyGenerationParameters genParam = new GOST3410KeyGenerationParameters(keyRandom, params); GOST3410KeyGen.init(genParam); AsymmetricCipherKeyPair pair = GOST3410KeyGen.generateKeyPair(); ParametersWithRandom param = new ParametersWithRandom(pair.getPrivate(), random); GOST3410Signer GOST3410 = new GOST3410Signer(); GOST3410.init(true, param); BigInteger[] sig = GOST3410.generateSignature(hashmessage); if (!r.equals(sig[0])) { return new SimpleTestResult(false, getName() + ": r component wrong." + System.getProperty("line.separator") + " expecting: " + r.toString(16) + System.getProperty("line.separator") + " got : " + sig[0].toString(16)); } if (!s.equals(sig[1])) { return new SimpleTestResult(false, getName() + ": s component wrong." + System.getProperty("line.separator") + " expecting: " + s.toString(16) + System.getProperty("line.separator") + " got : " + sig[1].toString(16)); } GOST3410.init(false, pair.getPublic()); if (GOST3410.verifySignature(hashmessage, sig[0], sig[1])) { return new SimpleTestResult(true, getName() + ": Okay"); } else { return new SimpleTestResult(false, getName() + ": verification fails"); } } } private class GOST3410_AExParam implements Test { public String getName() { return "GOST3410-AExParam"; } SecureRandom init_random = new SecureRandom() { boolean firstLong = true; public long nextLong() { String x0 = "0xD05E9F14"; String c = "0x46304C5F"; if (firstLong) { firstLong = false; return NumberParsing.decodeLongFromHex(x0); } return NumberParsing.decodeLongFromHex(c); } public void nextBytes(byte[] bytes) { byte[] d = Hex.decode("35ab875399cda33c146ca629660e5a5e5c07714ca326db032dd6751995cdb90a612b9228932d8302704ec24a5def7739c5813d83"); System.arraycopy(d, 0, bytes, bytes.length-d.length, d.length); } }; SecureRandom random = new SecureRandom() { public void nextBytes(byte[] bytes) { byte[] k = Hex.decode("90F3A564439242F5186EBB224C8E223811B7105C64E4F5390807E6362DF4C72A"); int i; for (i = 0; i < (bytes.length - k.length); i += k.length) { System.arraycopy(k, 0, bytes, i, k.length); } if (i > bytes.length) { System.arraycopy(k, 0, bytes, i - k.length, bytes.length - (i - k.length)); } else { System.arraycopy(k, 0, bytes, i, bytes.length - i); } } }; SecureRandom keyRandom = new SecureRandom() { public void nextBytes(byte[] bytes) { byte[] x = Hex.decode("3036314538303830343630454235324435324234314132373832433138443046"); int i; for (i = 0; i < (bytes.length - x.length); i += x.length) { System.arraycopy(x, 0, bytes, i, x.length); } if (i > bytes.length) { System.arraycopy(x, 0, bytes, i - x.length, bytes.length - (i - x.length)); } else { System.arraycopy(x, 0, bytes, i, bytes.length - i); } } }; BigInteger pValue = new BigInteger("ca3b3f2eee9fd46317d49595a9e7518e6c63d8f4eb4d22d10d28af0b8839f079f8289e603b03530784b9bb5a1e76859e4850c670c7b71c0df84ca3e0d6c177fe9f78a9d8433230a883cd82a2b2b5c7a3306980278570cdb79bf01074a69c9623348824b0c53791d53c6a78cab69e1cfb28368611a397f50f541e16db348dbe5f", 16); BigInteger qValue = new BigInteger("cae4d85f80c147704b0ca48e85fb00a9057aa4acc44668e17f1996d7152690d9", 16); public TestResult perform() { BigInteger r = new BigInteger("90892707282f433398488f19d31ac48523a8e2ded68944e0da91c6895ee7045e",16); BigInteger s = new BigInteger("3be4620ee88f1ee8f9dd63c7d145b7e554839feeca125049118262ea4651e9de",16); GOST3410ParametersGenerator pGen = new GOST3410ParametersGenerator(); pGen.init(1024, 2, init_random); GOST3410Parameters params = pGen.generateParameters(); if (!pValue.equals(params.getP()) || !qValue.equals(params.getQ())) { return new SimpleTestResult(false, getName() + ": p or q wrong"); } GOST3410KeyPairGenerator GOST3410KeyGen = new GOST3410KeyPairGenerator(); GOST3410KeyGenerationParameters genParam = new GOST3410KeyGenerationParameters(keyRandom, params); GOST3410KeyGen.init(genParam); AsymmetricCipherKeyPair pair = GOST3410KeyGen.generateKeyPair(); ParametersWithRandom param = new ParametersWithRandom(pair.getPrivate(), random); GOST3410Signer GOST3410 = new GOST3410Signer(); GOST3410.init(true, param); BigInteger[] sig = GOST3410.generateSignature(hashmessage); if (!r.equals(sig[0])) { return new SimpleTestResult(false, getName() + ": r component wrong." + System.getProperty("line.separator") + " expecting: " + r.toString(16) + System.getProperty("line.separator") + " got : " + sig[0].toString(16)); } if (!s.equals(sig[1])) { return new SimpleTestResult(false, getName() + ": s component wrong." + System.getProperty("line.separator") + " expecting: " + s.toString(16) + System.getProperty("line.separator") + " got : " + sig[1].toString(16)); } GOST3410.init(false, pair.getPublic()); if (GOST3410.verifySignature(hashmessage, sig[0], sig[1])) { return new SimpleTestResult(true, getName() + ": Okay"); } else { return new SimpleTestResult(false, getName() + ": verification fails"); } } } private class GOST3410_BExParam implements Test { public String getName() { return "GOST3410-BExParam"; } SecureRandom init_random = new SecureRandom() { boolean firstLong = true; public long nextLong() { String x0 = "0x7A007804"; String c = "0xD31A4FF7"; if (firstLong) { firstLong = false; return NumberParsing.decodeLongFromHex(x0); } return NumberParsing.decodeLongFromHex(c); } public void nextBytes(byte[] bytes) { byte[] d = Hex.decode("7ec123d161477762838c2bea9dbdf33074af6d41d108a066a1e7a07ab3048de2"); System.arraycopy(d, 0, bytes, bytes.length-d.length, d.length); } }; SecureRandom random = new SecureRandom() { public void nextBytes(byte[] bytes) { byte[] k = Hex.decode("90F3A564439242F5186EBB224C8E223811B7105C64E4F5390807E6362DF4C72A"); int i; for (i = 0; i < (bytes.length - k.length); i += k.length) { System.arraycopy(k, 0, bytes, i, k.length); } if (i > bytes.length) { System.arraycopy(k, 0, bytes, i - k.length, bytes.length - (i - k.length)); } else { System.arraycopy(k, 0, bytes, i, bytes.length - i); } } }; SecureRandom keyRandom = new SecureRandom() { public void nextBytes(byte[] bytes) { byte[] x = Hex.decode("3036314538303830343630454235324435324234314132373832433138443046"); int i; for (i = 0; i < (bytes.length - x.length); i += x.length) { System.arraycopy(x, 0, bytes, i, x.length); } if (i > bytes.length) { System.arraycopy(x, 0, bytes, i - x.length, bytes.length - (i - x.length)); } else { System.arraycopy(x, 0, bytes, i, bytes.length - i); } } }; BigInteger pValue = new BigInteger("9286dbda91eccfc3060aa5598318e2a639f5ba90a4ca656157b2673fb191cd0589ee05f4cef1bd13508408271458c30851ce7a4ef534742bfb11f4743c8f787b11193ba304c0e6bca25701bf88af1cb9b8fd4711d89f88e32b37d95316541bf1e5dbb4989b3df13659b88c0f97a3c1087b9f2d5317d557dcd4afc6d0a754e279", 16); BigInteger qValue = new BigInteger("c966e9b3b8b7cdd82ff0f83af87036c38f42238ec50a876cd390e43d67b6013f", 16); public TestResult perform() { BigInteger r = new BigInteger("8f79a582513df84dc247bcb624340cc0e5a34c4324a20ce7fe3ab8ff38a9db71",16); BigInteger s = new BigInteger("7508d22fd6cbb45efd438cb875e43f137247088d0f54b29a7c91f68a65b5fa85",16); GOST3410ParametersGenerator pGen = new GOST3410ParametersGenerator(); pGen.init(1024, 2, init_random); GOST3410Parameters params = pGen.generateParameters(); if (!pValue.equals(params.getP()) || !qValue.equals(params.getQ())) { return new SimpleTestResult(false, getName() + ": p or q wrong"); } GOST3410KeyPairGenerator GOST3410KeyGen = new GOST3410KeyPairGenerator(); GOST3410KeyGenerationParameters genParam = new GOST3410KeyGenerationParameters(keyRandom, params); GOST3410KeyGen.init(genParam); AsymmetricCipherKeyPair pair = GOST3410KeyGen.generateKeyPair(); ParametersWithRandom param = new ParametersWithRandom(pair.getPrivate(), random); GOST3410Signer GOST3410 = new GOST3410Signer(); GOST3410.init(true, param); BigInteger[] sig = GOST3410.generateSignature(hashmessage); if (!r.equals(sig[0])) { return new SimpleTestResult(false, getName() + ": r component wrong." + System.getProperty("line.separator") + " expecting: " + r.toString(16) + System.getProperty("line.separator") + " got : " + sig[0].toString(16)); } if (!s.equals(sig[1])) { return new SimpleTestResult(false, getName() + ": s component wrong." + System.getProperty("line.separator") + " expecting: " + s.toString(16) + System.getProperty("line.separator") + " got : " + sig[1].toString(16)); } GOST3410.init(false, pair.getPublic()); if (GOST3410.verifySignature(hashmessage, sig[0], sig[1])) { return new SimpleTestResult(true, getName() + ": Okay"); } else { return new SimpleTestResult(false, getName() + ": verification fails"); } } } private class GOST3410_CExParam implements Test { public String getName() { return "GOST3410-CExParam"; } SecureRandom init_random = new SecureRandom() { boolean firstLong = true; public long nextLong() { String x0 = "0x162AB910"; String c = "0x93F828D3"; if (firstLong) { firstLong = false; return NumberParsing.decodeLongFromHex(x0); } return NumberParsing.decodeLongFromHex(c); } public void nextBytes(byte[] bytes) { byte[] d = Hex.decode("ca82cce78a738bc46f103d53b9bf809745ec845e4f6da462606c51f60ecf302e31204b81"); System.arraycopy(d, 0, bytes, bytes.length-d.length, d.length); } }; SecureRandom random = new SecureRandom() { public void nextBytes(byte[] bytes) { byte[] k = Hex.decode("90F3A564439242F5186EBB224C8E223811B7105C64E4F5390807E6362DF4C72A"); int i; for (i = 0; i < (bytes.length - k.length); i += k.length) { System.arraycopy(k, 0, bytes, i, k.length); } if (i > bytes.length) { System.arraycopy(k, 0, bytes, i - k.length, bytes.length - (i - k.length)); } else { System.arraycopy(k, 0, bytes, i, bytes.length - i); } } }; SecureRandom keyRandom = new SecureRandom() { public void nextBytes(byte[] bytes) { byte[] x = Hex.decode("3036314538303830343630454235324435324234314132373832433138443046"); int i; for (i = 0; i < (bytes.length - x.length); i += x.length) { System.arraycopy(x, 0, bytes, i, x.length); } if (i > bytes.length) { System.arraycopy(x, 0, bytes, i - x.length, bytes.length - (i - x.length)); } else { System.arraycopy(x, 0, bytes, i, bytes.length - i); } } }; BigInteger pValue = new BigInteger("b194036ace14139d36d64295ae6c50fc4b7d65d8b340711366ca93f383653908ee637be428051d86612670ad7b402c09b820fa77d9da29c8111a8496da6c261a53ed252e4d8a69a20376e6addb3bdcd331749a491a184b8fda6d84c31cf05f9119b5ed35246ea4562d85928ba1136a8d0e5a7e5c764ba8902029a1336c631a1d", 16); BigInteger qValue = new BigInteger("96120477df0f3896628e6f4a88d83c93204c210ff262bccb7dae450355125259", 16); public TestResult perform() { BigInteger r = new BigInteger("169fdb2dc09f690b71332432bfec806042e258fa9a21dafe73c6abfbc71407d9",16); BigInteger s = new BigInteger("9002551808ae40d19f6f31fb67e4563101243cf07cffd5f2f8ff4c537b0c9866",16); GOST3410ParametersGenerator pGen = new GOST3410ParametersGenerator(); pGen.init(1024, 2, init_random); GOST3410Parameters params = pGen.generateParameters(); if (!pValue.equals(params.getP()) || !qValue.equals(params.getQ())) { return new SimpleTestResult(false, getName() + ": p or q wrong"); } GOST3410KeyPairGenerator GOST3410KeyGen = new GOST3410KeyPairGenerator(); GOST3410KeyGenerationParameters genParam = new GOST3410KeyGenerationParameters(keyRandom, params); GOST3410KeyGen.init(genParam); AsymmetricCipherKeyPair pair = GOST3410KeyGen.generateKeyPair(); ParametersWithRandom param = new ParametersWithRandom(pair.getPrivate(), random); GOST3410Signer GOST3410 = new GOST3410Signer(); GOST3410.init(true, param); BigInteger[] sig = GOST3410.generateSignature(hashmessage); if (!r.equals(sig[0])) { return new SimpleTestResult(false, getName() + ": r component wrong." + System.getProperty("line.separator") + " expecting: " + r.toString(16) + System.getProperty("line.separator") + " got : " + sig[0].toString(16)); } if (!s.equals(sig[1])) { return new SimpleTestResult(false, getName() + ": s component wrong." + System.getProperty("line.separator") + " expecting: " + s.toString(16) + System.getProperty("line.separator") + " got : " + sig[1].toString(16)); } GOST3410.init(false, pair.getPublic()); if (GOST3410.verifySignature(hashmessage, sig[0], sig[1])) { return new SimpleTestResult(true, getName() + ": Okay"); } else { return new SimpleTestResult(false, getName() + ": verification fails"); } } } Test tests[] = { new GOST3410_TEST1_512(), new GOST3410_TEST2_512(), // new GOST3410_TEST1_1024(), // new GOST3410_TEST2_1024(), // new GOST3410_AParam(), // new GOST3410_BParam(), // new GOST3410_CParam(), // new GOST3410_DParam(), // new GOST3410_AExParam(), // new GOST3410_BExParam(), // new GOST3410_CExParam() }; public String getName() { return "GOST3410"; } public TestResult perform() { for (int i = 0; i != tests.length; i++) { TestResult result = tests[i].perform(); if (!result.isSuccessful()) { return result; } } return new SimpleTestResult(true, "GOST3410: Okay"); } public static void main( String[] args) { GOST3410Test test = new GOST3410Test(); TestResult result = test.perform(); System.out.println(result); } } bouncycastle-1.49.orig/test/src/org/bouncycastle/crypto/test/RFC3211WrapTest.java0000644000175000017500000001427510544705535027257 0ustar ebourgebourgpackage org.bouncycastle.crypto.test; import org.bouncycastle.crypto.BlockCipher; import org.bouncycastle.crypto.InvalidCipherTextException; import org.bouncycastle.crypto.Wrapper; import org.bouncycastle.crypto.engines.DESEngine; import org.bouncycastle.crypto.engines.DESedeEngine; import org.bouncycastle.crypto.engines.RFC3211WrapEngine; import org.bouncycastle.crypto.modes.CBCBlockCipher; import org.bouncycastle.crypto.params.KeyParameter; import org.bouncycastle.crypto.params.ParametersWithIV; import org.bouncycastle.crypto.params.ParametersWithRandom; import org.bouncycastle.util.Arrays; import org.bouncycastle.util.encoders.Hex; import org.bouncycastle.util.test.SimpleTest; import java.security.SecureRandom; /** * Wrap Test based on RFC3211 test vectors */ public class RFC3211WrapTest extends SimpleTest { SecureRandom r1 = new SecureRandom() { int[] ints = { 0xC4, 0x36, 0xF5, 0x41 }; int count = 0; public int nextInt() { return ints[count++]; } }; SecureRandom r2 = new SecureRandom() { int[] ints = { 0xFA, 0x06, 0x0A, 0x45 }; int count = 0; public int nextInt() { return ints[count++]; } }; public String getName() { return "RFC3211Wrap"; } private void wrapTest( int id, BlockCipher engine, byte[] kek, byte[] iv, SecureRandom rand, byte[] in, byte[] out) throws Exception { Wrapper wrapper = new RFC3211WrapEngine(engine); wrapper.init(true, new ParametersWithRandom(new ParametersWithIV(new KeyParameter(kek), iv), rand)); byte[] cText = wrapper.wrap(in, 0, in.length); if (!Arrays.areEqual(cText, out)) { fail("failed wrap test " + id + " expected " + new String(Hex.encode(out)) + " got " + new String(Hex.encode(cText))); } wrapper.init(false, new ParametersWithIV(new KeyParameter(kek), iv)); byte[] pText = wrapper.unwrap(out, 0, out.length); if (!Arrays.areEqual(pText, in)) { fail("rfailed unwrap test " + id + " expected " + new String(Hex.encode(in)) + " got " + new String(Hex.encode(pText))); } } private void testCorruption() throws InvalidCipherTextException { byte[] kek = Hex.decode("D1DAA78615F287E6"); byte[] iv = Hex.decode("EFE598EF21B33D6D"); Wrapper wrapper = new RFC3211WrapEngine(new DESEngine()); wrapper.init(false, new ParametersWithIV(new KeyParameter(kek), iv)); byte[] block = Hex.decode("ff739D838C627C897323A2F8C436F541"); encryptBlock(kek, iv, block); try { wrapper.unwrap(block, 0, block.length); fail("bad length not detected"); } catch (InvalidCipherTextException e) { if (!e.getMessage().equals("wrapped key corrupted")) { fail("wrong exception on length"); } } block = Hex.decode("08639D838C627C897323A2F8C436F541"); testChecksum(kek, iv, block, wrapper); block = Hex.decode("08736D838C627C897323A2F8C436F541"); testChecksum(kek, iv, block, wrapper); block = Hex.decode("08739D638C627C897323A2F8C436F541"); testChecksum(kek, iv, block, wrapper); } private void testChecksum(byte[] kek, byte[] iv, byte[] block, Wrapper wrapper) { encryptBlock(kek, iv, block); try { wrapper.unwrap(block, 0, block.length); fail("bad checksum not detected"); } catch (InvalidCipherTextException e) { if (!e.getMessage().equals("wrapped key fails checksum")) { fail("wrong exception"); } } } private void encryptBlock(byte[] key, byte[] iv, byte[] cekBlock) { BlockCipher engine = new CBCBlockCipher(new DESEngine()); engine.init(true, new ParametersWithIV(new KeyParameter(key), iv)); for (int i = 0; i < cekBlock.length; i += 8) { engine.processBlock(cekBlock, i, cekBlock, i); } for (int i = 0; i < cekBlock.length; i += 8) { engine.processBlock(cekBlock, i, cekBlock, i); } } public void performTest() throws Exception { wrapTest(1, new DESEngine(), Hex.decode("D1DAA78615F287E6"), Hex.decode("EFE598EF21B33D6D"), r1, Hex.decode("8C627C897323A2F8"), Hex.decode("B81B2565EE373CA6DEDCA26A178B0C10")); wrapTest(2, new DESedeEngine(), Hex.decode("6A8970BF68C92CAEA84A8DF28510858607126380CC47AB2D"), Hex.decode("BAF1CA7931213C4E"), r2, Hex.decode("8C637D887223A2F965B566EB014B0FA5D52300A3F7EA40FFFC577203C71BAF3B"), Hex.decode("C03C514ABDB9E2C5AAC038572B5E24553876B377AAFB82ECA5A9D73F8AB143D9EC74E6CAD7DB260C")); testCorruption(); Wrapper wrapper = new RFC3211WrapEngine(new DESEngine()); ParametersWithIV params = new ParametersWithIV(new KeyParameter(new byte[16]), new byte[16]); byte[] buf = new byte[16]; try { wrapper.init(true, params); wrapper.unwrap(buf, 0, buf.length); fail("failed unwrap state test."); } catch (IllegalStateException e) { // expected } catch (InvalidCipherTextException e) { fail("unexpected exception: " + e, e); } try { wrapper.init(false, params); wrapper.wrap(buf, 0, buf.length); fail("failed unwrap state test."); } catch (IllegalStateException e) { // expected } // // short test // try { wrapper.init(false, params); wrapper.unwrap(buf, 0, buf.length / 2); fail("failed unwrap short test."); } catch (InvalidCipherTextException e) { // expected } } public static void main( String[] args) { runTest(new RFC3211WrapTest()); } } bouncycastle-1.49.orig/test/src/org/bouncycastle/crypto/test/PKCS12Test.java0000644000175000017500000001363510330633061026371 0ustar ebourgebourgpackage org.bouncycastle.crypto.test; import org.bouncycastle.crypto.CipherParameters; import org.bouncycastle.crypto.PBEParametersGenerator; import org.bouncycastle.crypto.digests.SHA1Digest; import org.bouncycastle.crypto.generators.PKCS12ParametersGenerator; import org.bouncycastle.crypto.params.KeyParameter; import org.bouncycastle.crypto.params.ParametersWithIV; import org.bouncycastle.util.encoders.Hex; import org.bouncycastle.util.test.SimpleTestResult; import org.bouncycastle.util.test.Test; import org.bouncycastle.util.test.TestResult; /** * test for PKCS12 key generation - vectors from * * http://www.drh-consultancy.demon.co.uk/test.txt */ public class PKCS12Test implements Test { char[] password1 = { 's', 'm', 'e', 'g' }; char[] password2 = { 'q', 'u', 'e', 'e', 'g' }; private boolean isEqual( byte[] a, byte[] b) { if (a.length != b.length) { return false; } for (int i = 0; i != a.length; i++) { if (a[i] != b[i]) { return false; } } return true; } private TestResult run1( int id, char[] password, byte[] salt, int iCount, byte[] result) { PBEParametersGenerator generator = new PKCS12ParametersGenerator( new SHA1Digest()); generator.init( PBEParametersGenerator.PKCS12PasswordToBytes(password), salt, iCount); CipherParameters key = generator.generateDerivedParameters(24 * 8); if (isEqual(result, ((KeyParameter)key).getKey())) { return new SimpleTestResult(true, "PKCS12Test: Okay"); } else { return new SimpleTestResult(false, "PKCS12Test: id " + id + " Failed"); } } private TestResult run2( int id, char[] password, byte[] salt, int iCount, byte[] result) { PBEParametersGenerator generator = new PKCS12ParametersGenerator( new SHA1Digest()); generator.init( PBEParametersGenerator.PKCS12PasswordToBytes(password), salt, iCount); ParametersWithIV params = (ParametersWithIV)generator.generateDerivedParameters(64, 64); if (isEqual(result, params.getIV())) { return new SimpleTestResult(true, "PKCS12Test: Okay"); } else { return new SimpleTestResult(false, "PKCS12Test: id " + id + " Failed"); } } private TestResult run3( int id, char[] password, byte[] salt, int iCount, byte[] result) { PBEParametersGenerator generator = new PKCS12ParametersGenerator( new SHA1Digest()); generator.init( PBEParametersGenerator.PKCS12PasswordToBytes(password), salt, iCount); CipherParameters key = generator.generateDerivedMacParameters(160); if (isEqual(result, ((KeyParameter)key).getKey())) { return new SimpleTestResult(true, "PKCS12Test: Okay"); } else { return new SimpleTestResult(false, "PKCS12Test: id " + id + " Failed"); } } public String getName() { return "PKCS12Test"; } public TestResult perform() { TestResult result; result = run1(1, password1, Hex.decode("0A58CF64530D823F"), 1, Hex.decode("8AAAE6297B6CB04642AB5B077851284EB7128F1A2A7FBCA3")); if (result.isSuccessful()) { result = run2(2, password1, Hex.decode("0A58CF64530D823F"), 1, Hex.decode("79993DFE048D3B76")); } if (result.isSuccessful()) { result = run1(3, password1, Hex.decode("642B99AB44FB4B1F"), 1, Hex.decode("F3A95FEC48D7711E985CFE67908C5AB79FA3D7C5CAA5D966")); } if (result.isSuccessful()) { result = run2(4, password1, Hex.decode("642B99AB44FB4B1F"), 1, Hex.decode("C0A38D64A79BEA1D")); } if (result.isSuccessful()) { result = run3(5, password1, Hex.decode("3D83C0E4546AC140"), 1, Hex.decode("8D967D88F6CAA9D714800AB3D48051D63F73A312")); } if (result.isSuccessful()) { result = run1(6, password2, Hex.decode("05DEC959ACFF72F7"), 1000, Hex.decode("ED2034E36328830FF09DF1E1A07DD357185DAC0D4F9EB3D4")); } if (result.isSuccessful()) { result = run2(7, password2, Hex.decode("05DEC959ACFF72F7"), 1000, Hex.decode("11DEDAD7758D4860")); } if (result.isSuccessful()) { result = run1(8, password2, Hex.decode("1682C0FC5B3F7EC5"), 1000, Hex.decode("483DD6E919D7DE2E8E648BA8F862F3FBFBDC2BCB2C02957F")); } if (result.isSuccessful()) { result = run2(9, password2, Hex.decode("1682C0FC5B3F7EC5"), 1000, Hex.decode("9D461D1B00355C50")); } if (result.isSuccessful()) { result = run3(10, password2, Hex.decode("263216FCC2FAB31C"), 1000, Hex.decode("5EC4C7A80DF652294C3925B6489A7AB857C83476")); } return result; } public static void main( String[] args) { PKCS12Test test = new PKCS12Test(); TestResult result = test.perform(); System.out.println(result); } } bouncycastle-1.49.orig/test/src/org/bouncycastle/crypto/test/TEATest.java0000644000175000017500000000271610540153517026103 0ustar ebourgebourgpackage org.bouncycastle.crypto.test; import org.bouncycastle.crypto.engines.TEAEngine; import org.bouncycastle.crypto.params.KeyParameter; import org.bouncycastle.util.encoders.Hex; import org.bouncycastle.util.test.SimpleTest; /** * TEA tester - based on C implementation results from http://www.simonshepherd.supanet.com/tea.htm */ public class TEATest extends CipherTest { static SimpleTest[] tests = { new BlockCipherVectorTest(0, new TEAEngine(), new KeyParameter(Hex.decode("00000000000000000000000000000000")), "0000000000000000", "41ea3a0a94baa940"), new BlockCipherVectorTest(1, new TEAEngine(), new KeyParameter(Hex.decode("00000000000000000000000000000000")), "0102030405060708", "6a2f9cf3fccf3c55"), new BlockCipherVectorTest(2, new TEAEngine(), new KeyParameter(Hex.decode("0123456712345678234567893456789A")), "0000000000000000", "34e943b0900f5dcb"), new BlockCipherVectorTest(3, new TEAEngine(), new KeyParameter(Hex.decode("0123456712345678234567893456789A")), "0102030405060708", "773dc179878a81c0"), }; TEATest() { super(tests, new TEAEngine(), new KeyParameter(new byte[16])); } public String getName() { return "TEA"; } public static void main( String[] args) { runTest(new TEATest()); } } bouncycastle-1.49.orig/test/src/org/bouncycastle/crypto/test/MD4DigestTest.java0000644000175000017500000000167410330633061027212 0ustar ebourgebourgpackage org.bouncycastle.crypto.test; import org.bouncycastle.crypto.Digest; import org.bouncycastle.crypto.digests.MD4Digest; /** * standard vector test for MD4 from RFC 1320. */ public class MD4DigestTest extends DigestTest { static private String[] messages = { "", "a", "abc", "12345678901234567890123456789012345678901234567890123456789012345678901234567890" }; static private String[] digests = { "31d6cfe0d16ae931b73c59d7e0c089c0", "bde52cb31de33e46245e05fbdbd6fb24", "a448017aaf21d8525fc10ae87aa6729d", "e33b4ddc9c38f2199c3e7b164fcc0536" }; MD4DigestTest() { super(new MD4Digest(), messages, digests); } protected Digest cloneDigest(Digest digest) { return new MD4Digest((MD4Digest)digest); } public static void main( String[] args) { runTest(new MD4DigestTest()); } } bouncycastle-1.49.orig/test/src/org/bouncycastle/crypto/test/SHA512t224DigestTest.java0000644000175000017500000000264512132420304030100 0ustar ebourgebourgpackage org.bouncycastle.crypto.test; import org.bouncycastle.crypto.Digest; import org.bouncycastle.crypto.digests.SHA512tDigest; /** * standard vector test for SHA-512/224 from FIPS 180-4. * * Note, only the last 2 message entries are FIPS originated.. */ public class SHA512t224DigestTest extends DigestTest { private static String[] messages = { "", "a", "abc", "abcdefghbcdefghicdefghijdefghijkefghijklfghijklmghijklmnhijklmnoijklmnopjklmnopqklmnopqrlmnopqrsmnopqrstnopqrstu" }; private static String[] digests = { "6ed0dd02806fa89e25de060c19d3ac86cabb87d6a0ddd05c333b84f4", "d5cdb9ccc769a5121d4175f2bfdd13d6310e0d3d361ea75d82108327", "4634270F707B6A54DAAE7530460842E20E37ED265CEEE9A43E8924AA", "23FEC5BB94D60B23308192640B0C453335D664734FE40E7268674AF9" }; // 1 million 'a' static private String million_a_digest = "37ab331d76f0d36de422bd0edeb22a28accd487b7a8453ae965dd287"; SHA512t224DigestTest() { super(new SHA512tDigest(224), messages, digests); } public void performTest() { super.performTest(); millionATest(million_a_digest); } protected Digest cloneDigest(Digest digest) { return new SHA512tDigest((SHA512tDigest)digest); } public static void main( String[] args) { runTest(new SHA512t224DigestTest()); } } bouncycastle-1.49.orig/test/src/org/bouncycastle/crypto/test/SkipjackTest.java0000644000175000017500000000155011273433217027226 0ustar ebourgebourgpackage org.bouncycastle.crypto.test; import org.bouncycastle.crypto.engines.SkipjackEngine; import org.bouncycastle.crypto.params.KeyParameter; import org.bouncycastle.util.encoders.Hex; import org.bouncycastle.util.test.SimpleTest; /** */ public class SkipjackTest extends CipherTest { static SimpleTest[] tests = { new BlockCipherVectorTest(0, new SkipjackEngine(), new KeyParameter(Hex.decode("00998877665544332211")), "33221100ddccbbaa", "2587cae27a12d300") }; SkipjackTest() { super(tests, new SkipjackEngine(), new KeyParameter(Hex.decode("00998877665544332211"))); } public String getName() { return "SKIPJACK"; } public static void main( String[] args) { runTest(new SkipjackTest()); } } bouncycastle-1.49.orig/test/src/org/bouncycastle/crypto/test/WhirlpoolDigestTest.java0000644000175000017500000000767212143605611030615 0ustar ebourgebourgpackage org.bouncycastle.crypto.test; import org.bouncycastle.crypto.Digest; import org.bouncycastle.crypto.digests.SHA1Digest; import org.bouncycastle.crypto.digests.WhirlpoolDigest; import org.bouncycastle.util.Arrays; import org.bouncycastle.util.encoders.Hex; import org.bouncycastle.util.test.SimpleTest; /** * ISO vector test for Whirlpool * */ public class WhirlpoolDigestTest extends DigestTest { private static String[] messages = { "", "a", "abc", "message digest", "abcdefghijklmnopqrstuvwxyz", "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789", "12345678901234567890123456789012345678901234567890123456789012345678901234567890", "abcdbcdecdefdefgefghfghighijhijk" }; private static String[] digests = { "19FA61D75522A4669B44E39C1D2E1726C530232130D407F89AFEE0964997F7A73E83BE698B288FEBCF88E3E03C4F0757EA8964E59B63D93708B138CC42A66EB3", "8ACA2602792AEC6F11A67206531FB7D7F0DFF59413145E6973C45001D0087B42D11BC645413AEFF63A42391A39145A591A92200D560195E53B478584FDAE231A", "4E2448A4C6F486BB16B6562C73B4020BF3043E3A731BCE721AE1B303D97E6D4C7181EEBDB6C57E277D0E34957114CBD6C797FC9D95D8B582D225292076D4EEF5", "378C84A4126E2DC6E56DCC7458377AAC838D00032230F53CE1F5700C0FFB4D3B8421557659EF55C106B4B52AC5A4AAA692ED920052838F3362E86DBD37A8903E", "F1D754662636FFE92C82EBB9212A484A8D38631EAD4238F5442EE13B8054E41B08BF2A9251C30B6A0B8AAE86177AB4A6F68F673E7207865D5D9819A3DBA4EB3B", "DC37E008CF9EE69BF11F00ED9ABA26901DD7C28CDEC066CC6AF42E40F82F3A1E08EBA26629129D8FB7CB57211B9281A65517CC879D7B962142C65F5A7AF01467", "466EF18BABB0154D25B9D38A6414F5C08784372BCCB204D6549C4AFADB6014294D5BD8DF2A6C44E538CD047B2681A51A2C60481E88C5A20B2C2A80CF3A9A083B", "2A987EA40F917061F5D6F0A0E4644F488A7A5A52DEEE656207C562F988E95C6916BDC8031BC5BE1B7B947639FE050B56939BAAA0ADFF9AE6745B7B181C3BE3FD" }; WhirlpoolDigestTest() { super(new WhirlpoolDigest(), messages, digests); } protected Digest cloneDigest(Digest digest) { return new WhirlpoolDigest((WhirlpoolDigest)digest); } private static String _millionAResultVector = "0C99005BEB57EFF50A7CF005560DDF5D29057FD86B20BFD62DECA0F1CCEA4AF51FC15490EDDC47AF32BB2B66C34FF9AD8C6008AD677F77126953B226E4ED8B01"; private static String _thirtyOneZeros = "3E3F188F8FEBBEB17A933FEAF7FE53A4858D80C915AD6A1418F0318E68D49B4E459223CD414E0FBC8A57578FD755D86E827ABEF4070FC1503E25D99E382F72BA"; public String getName() { return "Whirlpool"; } public void performTest() { super.performTest(); byte[] thirtyOneZeros = new byte[31]; performStandardVectorTest("31 zeroes test", thirtyOneZeros, _thirtyOneZeros); byte[] millionAInByteArray = new byte[1000000]; Arrays.fill(millionAInByteArray, (byte)'a'); performStandardVectorTest("Million 'a' test", millionAInByteArray, _millionAResultVector); } private void performStandardVectorTest(String testTitle, byte[] inputBytes, String resultsAsHex) { doPerformTest(testTitle, inputBytes, resultsAsHex); } private void doPerformTest(String testTitle, byte[] inputBytes, String resultsAsHex) { String resStr = createHexOutputFromDigest(inputBytes); if (!resultsAsHex.equals(resStr.toUpperCase())) { fail(testTitle, resultsAsHex, resStr); } } private String createHexOutputFromDigest(byte[] digestBytes) { String resStr; Digest digest = new WhirlpoolDigest(); byte[] resBuf = new byte[digest.getDigestSize()]; digest.update(digestBytes, 0, digestBytes.length); digest.doFinal(resBuf, 0); resStr = new String(Hex.encode(resBuf)); return resStr; } public static void main(String[] args) { runTest(new WhirlpoolDigestTest()); } } bouncycastle-1.49.orig/test/src/org/bouncycastle/crypto/test/DSTU4145Test.java0000644000175000017500000002274612104606213026566 0ustar ebourgebourgpackage org.bouncycastle.crypto.test; import java.math.BigInteger; import java.security.SecureRandom; import org.bouncycastle.crypto.CipherParameters; import org.bouncycastle.crypto.params.ECDomainParameters; import org.bouncycastle.crypto.params.ECPrivateKeyParameters; import org.bouncycastle.crypto.params.ECPublicKeyParameters; import org.bouncycastle.crypto.params.ParametersWithRandom; import org.bouncycastle.crypto.signers.DSTU4145Signer; import org.bouncycastle.math.ec.ECCurve; import org.bouncycastle.math.ec.ECPoint; import org.bouncycastle.util.encoders.Hex; import org.bouncycastle.util.test.FixedSecureRandom; import org.bouncycastle.util.test.SimpleTest; public class DSTU4145Test extends SimpleTest { private static final BigInteger ZERO = BigInteger.valueOf(0); private static final BigInteger ONE = BigInteger.valueOf(1); /** * @param args */ public static void main(String[] args) { runTest(new DSTU4145Test()); } public String getName() { return "DSTU4145"; } private void Test163() throws Exception { SecureRandom random = new FixedSecureRandom(Hex.decode("01025e40bd97db012b7a1d79de8e12932d247f61c6")); byte[] hash = Hex.decode("09c9c44277910c9aaee486883a2eb95b7180166ddf73532eeb76edaef52247ff"); for (int i = 0; i < hash.length / 2; i++) { byte tmp = hash[i]; hash[i] = hash[hash.length - 1 - i]; hash[hash.length - 1 - i] = tmp; } BigInteger r = new BigInteger("274ea2c0caa014a0d80a424f59ade7a93068d08a7", 16); BigInteger s = new BigInteger("2100d86957331832b8e8c230f5bd6a332b3615aca", 16); ECCurve.F2m curve = new ECCurve.F2m(163, 3, 6, 7, ONE, new BigInteger("5FF6108462A2DC8210AB403925E638A19C1455D21", 16)); ECPoint P = curve.createPoint(new BigInteger("72d867f93a93ac27df9ff01affe74885c8c540420", 16), new BigInteger("0224a9c3947852b97c5599d5f4ab81122adc3fd9b", 16), false); BigInteger n = new BigInteger("400000000000000000002BEC12BE2262D39BCF14D", 16); BigInteger d = new BigInteger("183f60fdf7951ff47d67193f8d073790c1c9b5a3e", 16); ECPoint Q = P.multiply(d).negate(); ECDomainParameters domain = new ECDomainParameters(curve, P, n); CipherParameters privKey = new ParametersWithRandom(new ECPrivateKeyParameters(d, domain), random); ECPublicKeyParameters pubKey = new ECPublicKeyParameters(Q, domain); DSTU4145Signer dstuSigner = new DSTU4145Signer(); dstuSigner.init(true, privKey); BigInteger[] rs = dstuSigner.generateSignature(hash); if (rs[0].compareTo(r) != 0) { fail("r component wrong"); } if (rs[1].compareTo(s) != 0) { fail("s component wrong"); } dstuSigner.init(false, pubKey); if (!dstuSigner.verifySignature(hash, r, s)) { fail("verification fails"); } } private void Test173() throws Exception { SecureRandom random = new FixedSecureRandom(Hex.decode("0000137449348C1249971759D99C252FFE1E14D8B31F")); byte[] hash = Hex.decode("0137187EA862117EF1484289470ECAC802C5A651FDA8"); for (int i = 0; i < hash.length / 2; i++) { byte tmp = hash[i]; hash[i] = hash[hash.length - 1 - i]; hash[hash.length - 1 - i] = tmp; } BigInteger r = new BigInteger("13ae89746386709cdbd237cc5ec20ca30004a82ead8", 16); BigInteger s = new BigInteger("3597912cdd093b3e711ccb74a79d3c4ab4c7cccdc60", 16); ECCurve.F2m curve = new ECCurve.F2m(173, 1, 2, 10, ZERO, new BigInteger("108576C80499DB2FC16EDDF6853BBB278F6B6FB437D9", 16)); ECPoint P = curve.createPoint(new BigInteger("BE6628EC3E67A91A4E470894FBA72B52C515F8AEE9", 16), new BigInteger("D9DEEDF655CF5412313C11CA566CDC71F4DA57DB45C", 16), false); BigInteger n = new BigInteger("800000000000000000000189B4E67606E3825BB2831", 16); BigInteger d = new BigInteger("955CD7E344303D1034E66933DC21C8044D42ADB8", 16); ECPoint Q = P.multiply(d).negate(); ECDomainParameters domain = new ECDomainParameters(curve, P, n); CipherParameters privKey = new ParametersWithRandom(new ECPrivateKeyParameters(d, domain), random); ECPublicKeyParameters pubKey = new ECPublicKeyParameters(Q, domain); DSTU4145Signer dstuSigner = new DSTU4145Signer(); dstuSigner.init(true, privKey); BigInteger[] rs = dstuSigner.generateSignature(hash); if (rs[0].compareTo(r) != 0) { fail("r component wrong"); } if (rs[1].compareTo(s) != 0) { fail("s component wrong"); } dstuSigner.init(false, pubKey); if (!dstuSigner.verifySignature(hash, r, s)) { fail("verification fails"); } } private void Test283() throws Exception { SecureRandom random = new FixedSecureRandom(Hex.decode("00000000245383CB3AD41BF30F5F7E8FBA858509B2D5558C92D539A6D994BFA98BC6940E")); byte[] hash = Hex.decode("0137187EA862117EF1484289470ECAC802C5A651FDA8"); for (int i = 0; i < hash.length / 2; i++) { byte tmp = hash[i]; hash[i] = hash[hash.length - 1 - i]; hash[hash.length - 1 - i] = tmp; } BigInteger r = new BigInteger("12a5edcc38d92208ff23036d75b000c7e4bc0f9af2d40b35f15d6fd15e01234e67781a8", 16); BigInteger s = new BigInteger("2de0775577f75b643cf5afc80d4fe10b21100690f17e2cab7bdc9b50ec87c5727aeb515", 16); ECCurve.F2m curve = new ECCurve.F2m(283, 5, 7, 12, ONE, new BigInteger("27B680AC8B8596DA5A4AF8A19A0303FCA97FD7645309FA2A581485AF6263E313B79A2F5", 16)); ECPoint P = curve.createPoint(new BigInteger("4D95820ACE761110824CE425C8089129487389B7F0E0A9D043DDC0BB0A4CC9EB25", 16), new BigInteger("954C9C4029B2C62DE35C2B9C2A164984BF1101951E3A68ED03DF234DDE5BB2013152F2", 16), false); BigInteger n = new BigInteger("3FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEF90399660FC938A90165B042A7CEFADB307", 16); BigInteger d = new BigInteger("B844EEAF15213E4BAD4FB84796D68F2448DB8EB7B4621EC0D51929874892C43E", 16); ECPoint Q = P.multiply(d).negate(); ECDomainParameters domain = new ECDomainParameters(curve, P, n); CipherParameters privKey = new ParametersWithRandom(new ECPrivateKeyParameters(d, domain), random); ECPublicKeyParameters pubKey = new ECPublicKeyParameters(Q, domain); DSTU4145Signer dstuSigner = new DSTU4145Signer(); dstuSigner.init(true, privKey); BigInteger[] rs = dstuSigner.generateSignature(hash); if (rs[0].compareTo(r) != 0) { fail("r component wrong"); } if (rs[1].compareTo(s) != 0) { fail("s component wrong"); } dstuSigner.init(false, pubKey); if (!dstuSigner.verifySignature(hash, r, s)) { fail("verification fails"); } } private void Test431() throws Exception { SecureRandom random = new FixedSecureRandom(Hex.decode("0000C4224DBBD800988DBAA39DE838294C345CDA5F5929D1174AA8D9340A5E79D10ACADE6B53CF873E7301A3871C2073AD75AB530457")); byte[] hash = Hex.decode("0137187EA862117EF1484289470ECAC802C5A651FDA8"); for (int i = 0; i < hash.length / 2; i++) { byte tmp = hash[i]; hash[i] = hash[hash.length - 1 - i]; hash[hash.length - 1 - i] = tmp; } BigInteger r = new BigInteger("1911fefb1f494bebcf8dffdf5276946ff9c9f662192ee18c718db47310a439c784fe07577b16e1edbe16179876e0792a634f1c9c3a2e", 16); BigInteger s = new BigInteger("3852170ee801c2083c52f1ea77b987a5432acecd9c654f064e87bf179e0a397151edbca430082e43bd38a67b55424b5bbc7f2713f620", 16); ECCurve.F2m curve = new ECCurve.F2m(431, 1, 3, 5, ONE, new BigInteger("3CE10490F6A708FC26DFE8C3D27C4F94E690134D5BFF988D8D28AAEAEDE975936C66BAC536B18AE2DC312CA493117DAA469C640CAF3", 16)); ECPoint P = curve.createPoint(new BigInteger("9548BCDF314CEEEAF099C780FFEFBF93F9FE5B5F55547603C9C8FC1A2774170882B3BE35E892C6D4296B8DEA282EC30FB344272791", 16), new BigInteger("4C6CBD7C62A8EEEFDE17A8B5E196E49A22CE6DE128ABD9FBD81FA4411AD5A38E2A810BEDE09A7C6226BCDCB4A4A5DA37B4725E00AA74", 16), false); BigInteger n = new BigInteger("3FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFBA3175458009A8C0A724F02F81AA8A1FCBAF80D90C7A95110504CF", 16); BigInteger d = new BigInteger("D0F97354E314191FD773E2404F478C8AEE0FF5109F39E6F37D1FEEC8B2ED1691D84C9882CC729E716A71CC013F66CAC60E29E22C", 16); ECPoint Q = P.multiply(d).negate(); ECDomainParameters domain = new ECDomainParameters(curve, P, n); CipherParameters privKey = new ParametersWithRandom(new ECPrivateKeyParameters(d, domain), random); ECPublicKeyParameters pubKey = new ECPublicKeyParameters(Q, domain); DSTU4145Signer dstuSigner = new DSTU4145Signer(); dstuSigner.init(true, privKey); BigInteger[] rs = dstuSigner.generateSignature(hash); if (rs[0].compareTo(r) != 0) { fail("r component wrong"); } if (rs[1].compareTo(s) != 0) { fail("s component wrong"); } dstuSigner.init(false, pubKey); if (!dstuSigner.verifySignature(hash, r, s)) { fail("verification fails"); } } public void performTest() throws Exception { Test163(); Test173(); Test283(); Test431(); } } bouncycastle-1.49.orig/test/src/org/bouncycastle/crypto/test/EqualsHashCodeTest.java0000644000175000017500000002316410646606452030333 0ustar ebourgebourgpackage org.bouncycastle.crypto.test; import org.bouncycastle.crypto.AsymmetricCipherKeyPair; import org.bouncycastle.crypto.generators.DHKeyPairGenerator; import org.bouncycastle.crypto.generators.ElGamalKeyPairGenerator; import org.bouncycastle.crypto.params.DHKeyGenerationParameters; import org.bouncycastle.crypto.params.DHKeyParameters; import org.bouncycastle.crypto.params.DHParameters; import org.bouncycastle.crypto.params.DHPrivateKeyParameters; import org.bouncycastle.crypto.params.DHPublicKeyParameters; import org.bouncycastle.crypto.params.DHValidationParameters; import org.bouncycastle.crypto.params.DSAParameters; import org.bouncycastle.crypto.params.DSAValidationParameters; import org.bouncycastle.crypto.params.ElGamalKeyGenerationParameters; import org.bouncycastle.crypto.params.ElGamalKeyParameters; import org.bouncycastle.crypto.params.ElGamalParameters; import org.bouncycastle.crypto.params.ElGamalPrivateKeyParameters; import org.bouncycastle.crypto.params.ElGamalPublicKeyParameters; import org.bouncycastle.crypto.params.GOST3410Parameters; import org.bouncycastle.crypto.params.GOST3410ValidationParameters; import org.bouncycastle.util.test.SimpleTest; import java.math.BigInteger; import java.security.SecureRandom; class DHTestKeyParameters extends DHKeyParameters { protected DHTestKeyParameters(boolean isPrivate, DHParameters params) { super(isPrivate, params); } } class ElGamalTestKeyParameters extends ElGamalKeyParameters { protected ElGamalTestKeyParameters(boolean isPrivate, ElGamalParameters params) { super(isPrivate, params); } } public class EqualsHashCodeTest extends SimpleTest { private static Object OTHER = new Object(); public String getName() { return "EqualsHashCode"; } private void doTest(Object a, Object equalsA, Object notEqualsA) { if (a.equals(null)) { fail("a equaled null"); } if (!a.equals(equalsA) || !equalsA.equals(a)) { fail("equality failed"); } if (a.equals(OTHER)) { fail("other inequality failed"); } if (a.equals(notEqualsA) || notEqualsA.equals(a)) { fail("inequality failed"); } if (a.hashCode() != equalsA.hashCode()) { fail("hashCode equality failed"); } } private void dhTest() { BigInteger g512 = new BigInteger("153d5d6172adb43045b68ae8e1de1070b6137005686d29d3d73a7749199681ee5b212c9b96bfdcfa5b20cd5e3fd2044895d609cf9b410b7a0f12ca1cb9a428cc", 16); BigInteger p512 = new BigInteger("9494fec095f3b85ee286542b3836fc81a5dd0a0349b4c239dd38744d488cf8e31db8bcb7d33b41abb9e5a33cca9144b1cef332c94bf0573bf047a3aca98cdf3b", 16); DHParameters dhParams = new DHParameters(p512, g512); DHKeyGenerationParameters params = new DHKeyGenerationParameters(new SecureRandom(), dhParams); DHKeyPairGenerator kpGen = new DHKeyPairGenerator(); kpGen.init(params); AsymmetricCipherKeyPair pair = kpGen.generateKeyPair(); DHPublicKeyParameters pu1 = (DHPublicKeyParameters)pair.getPublic(); DHPrivateKeyParameters pv1 = (DHPrivateKeyParameters)pair.getPrivate(); DHPublicKeyParameters pu2 = new DHPublicKeyParameters(pu1.getY(), pu1.getParameters()); DHPrivateKeyParameters pv2 = new DHPrivateKeyParameters(pv1.getX(), pv1.getParameters()); DHPublicKeyParameters pu3 = new DHPublicKeyParameters(pv1.getX(), pu1.getParameters()); DHPrivateKeyParameters pv3 = new DHPrivateKeyParameters(pu1.getY(), pu1.getParameters()); doTest(pu1, pu2, pu3); doTest(pv1, pv2, pv3); DHParameters pr1 = pu1.getParameters(); DHParameters pr2 = new DHParameters(pr1.getP(), pr1.getG(), pr1.getQ(), pr1.getM(), pr1.getL(), pr1.getJ(), pr1.getValidationParameters()); DHParameters pr3 = new DHParameters(pr1.getG(), pr1.getP(), pr1.getQ(), pr1.getM(), pr1.getL(), pr1.getJ(), pr1.getValidationParameters()); doTest(pr1, pr2, pr3); pr3 = new DHParameters(pr1.getG(), pr1.getP(), null, pr1.getM(), pr1.getL(), pr1.getJ(), pr1.getValidationParameters()); doTest(pr1, pr2, pr3); pu2 = new DHPublicKeyParameters(pu1.getY(), pr2); pv2 = new DHPrivateKeyParameters(pv1.getX(), pr2); doTest(pu1, pu2, pu3); doTest(pv1, pv2, pv3); DHValidationParameters vp1 = new DHValidationParameters(new byte[20], 1024); DHValidationParameters vp2 = new DHValidationParameters(new byte[20], 1024); DHValidationParameters vp3 = new DHValidationParameters(new byte[24], 1024); doTest(vp1, vp1, vp3); doTest(vp1, vp2, vp3); byte[] bytes = new byte[20]; bytes[0] = 1; vp3 = new DHValidationParameters(bytes, 1024); doTest(vp1, vp2, vp3); vp3 = new DHValidationParameters(new byte[20], 2048); doTest(vp1, vp2, vp3); DHTestKeyParameters k1 = new DHTestKeyParameters(false, null); DHTestKeyParameters k2 = new DHTestKeyParameters(false, null); DHTestKeyParameters k3 = new DHTestKeyParameters(false, pu1.getParameters()); doTest(k1, k2, k3); } private void elGamalTest() { BigInteger g512 = new BigInteger("153d5d6172adb43045b68ae8e1de1070b6137005686d29d3d73a7749199681ee5b212c9b96bfdcfa5b20cd5e3fd2044895d609cf9b410b7a0f12ca1cb9a428cc", 16); BigInteger p512 = new BigInteger("9494fec095f3b85ee286542b3836fc81a5dd0a0349b4c239dd38744d488cf8e31db8bcb7d33b41abb9e5a33cca9144b1cef332c94bf0573bf047a3aca98cdf3b", 16); ElGamalParameters dhParams = new ElGamalParameters(p512, g512); ElGamalKeyGenerationParameters params = new ElGamalKeyGenerationParameters(new SecureRandom(), dhParams); ElGamalKeyPairGenerator kpGen = new ElGamalKeyPairGenerator(); kpGen.init(params); AsymmetricCipherKeyPair pair = kpGen.generateKeyPair(); ElGamalPublicKeyParameters pu1 = (ElGamalPublicKeyParameters)pair.getPublic(); ElGamalPrivateKeyParameters pv1 = (ElGamalPrivateKeyParameters)pair.getPrivate(); ElGamalPublicKeyParameters pu2 = new ElGamalPublicKeyParameters(pu1.getY(), pu1.getParameters()); ElGamalPrivateKeyParameters pv2 = new ElGamalPrivateKeyParameters(pv1.getX(), pv1.getParameters()); ElGamalPublicKeyParameters pu3 = new ElGamalPublicKeyParameters(pv1.getX(), pu1.getParameters()); ElGamalPrivateKeyParameters pv3 = new ElGamalPrivateKeyParameters(pu1.getY(), pu1.getParameters()); doTest(pu1, pu2, pu3); doTest(pv1, pv2, pv3); ElGamalParameters pr1 = pu1.getParameters(); ElGamalParameters pr2 = new ElGamalParameters(pr1.getP(), pr1.getG()); ElGamalParameters pr3 = new ElGamalParameters(pr1.getG(), pr1.getP()); doTest(pr1, pr2, pr3); pu2 = new ElGamalPublicKeyParameters(pu1.getY(), pr2); pv2 = new ElGamalPrivateKeyParameters(pv1.getX(), pr2); doTest(pu1, pu2, pu3); doTest(pv1, pv2, pv3); ElGamalTestKeyParameters k1 = new ElGamalTestKeyParameters(false, null); ElGamalTestKeyParameters k2 = new ElGamalTestKeyParameters(false, null); ElGamalTestKeyParameters k3 = new ElGamalTestKeyParameters(false, pu1.getParameters()); doTest(k1, k2, k3); } private void dsaTest() { BigInteger a = BigInteger.valueOf(1), b = BigInteger.valueOf(2), c = BigInteger.valueOf(3); DSAParameters dsaP1 = new DSAParameters(a, b, c); DSAParameters dsaP2 = new DSAParameters(a, b, c); DSAParameters dsaP3 = new DSAParameters(b, c, a); doTest(dsaP1, dsaP2, dsaP3); DSAValidationParameters vp1 = new DSAValidationParameters(new byte[20], 1024); DSAValidationParameters vp2 = new DSAValidationParameters(new byte[20], 1024); DSAValidationParameters vp3 = new DSAValidationParameters(new byte[24], 1024); doTest(vp1, vp1, vp3); doTest(vp1, vp2, vp3); byte[] bytes = new byte[20]; bytes[0] = 1; vp3 = new DSAValidationParameters(bytes, 1024); doTest(vp1, vp2, vp3); vp3 = new DSAValidationParameters(new byte[20], 2048); doTest(vp1, vp2, vp3); } private void gost3410Test() { BigInteger a = BigInteger.valueOf(1), b = BigInteger.valueOf(2), c = BigInteger.valueOf(3); GOST3410Parameters g1 = new GOST3410Parameters(a, b, c); GOST3410Parameters g2 = new GOST3410Parameters(a, b, c); GOST3410Parameters g3 = new GOST3410Parameters(a, c, c); doTest(g1, g2, g3); GOST3410ValidationParameters v1 = new GOST3410ValidationParameters(100, 1); GOST3410ValidationParameters v2 = new GOST3410ValidationParameters(100, 1); GOST3410ValidationParameters v3 = new GOST3410ValidationParameters(101, 1); doTest(v1, v2, v3); v3 = new GOST3410ValidationParameters(100, 2); doTest(v1, v2, v3); v1 = new GOST3410ValidationParameters(100L, 1L); v2 = new GOST3410ValidationParameters(100L, 1L); v3 = new GOST3410ValidationParameters(101L, 1L); doTest(v1, v2, v3); v3 = new GOST3410ValidationParameters(100L, 2L); doTest(v1, v2, v3); } public void performTest() throws Exception { dhTest(); elGamalTest(); gost3410Test(); dsaTest(); } public static void main( String[] args) { runTest(new EqualsHashCodeTest()); } } bouncycastle-1.49.orig/test/src/org/bouncycastle/crypto/test/DSATest.java0000644000175000017500000005640312143666124026107 0ustar ebourgebourgpackage org.bouncycastle.crypto.test; import java.math.BigInteger; import java.security.SecureRandom; import org.bouncycastle.crypto.AsymmetricCipherKeyPair; import org.bouncycastle.crypto.digests.SHA224Digest; import org.bouncycastle.crypto.digests.SHA256Digest; import org.bouncycastle.crypto.generators.DSAKeyPairGenerator; import org.bouncycastle.crypto.generators.DSAParametersGenerator; import org.bouncycastle.crypto.params.DSAKeyGenerationParameters; import org.bouncycastle.crypto.params.DSAParameterGenerationParameters; import org.bouncycastle.crypto.params.DSAParameters; import org.bouncycastle.crypto.params.DSAPrivateKeyParameters; import org.bouncycastle.crypto.params.DSAPublicKeyParameters; import org.bouncycastle.crypto.params.DSAValidationParameters; import org.bouncycastle.crypto.params.ParametersWithRandom; import org.bouncycastle.crypto.signers.DSASigner; import org.bouncycastle.util.Arrays; import org.bouncycastle.util.BigIntegers; import org.bouncycastle.util.encoders.Hex; import org.bouncycastle.util.test.FixedSecureRandom; import org.bouncycastle.util.test.SimpleTest; /** * Test based on FIPS 186-2, Appendix 5, an example of DSA, and FIPS 168-3 test vectors. */ public class DSATest extends SimpleTest { byte[] k1 = Hex.decode("d5014e4b60ef2ba8b6211b4062ba3224e0427dd3"); byte[] k2 = Hex.decode("345e8d05c075c3a508df729a1685690e68fcfb8c8117847e89063bca1f85d968fd281540b6e13bd1af989a1fbf17e06462bf511f9d0b140fb48ac1b1baa5bded"); SecureRandom random = new FixedSecureRandom(new byte[][] { k1, k2}); byte[] keyData = Hex.decode("b5014e4b60ef2ba8b6211b4062ba3224e0427dd3"); SecureRandom keyRandom = new FixedSecureRandom(new byte[][] { keyData, keyData }); BigInteger pValue = new BigInteger("8df2a494492276aa3d25759bb06869cbeac0d83afb8d0cf7cbb8324f0d7882e5d0762fc5b7210eafc2e9adac32ab7aac49693dfbf83724c2ec0736ee31c80291", 16); BigInteger qValue = new BigInteger("c773218c737ec8ee993b4f2ded30f48edace915f", 16); public String getName() { return "DSA"; } public void performTest() { BigInteger r = new BigInteger("68076202252361894315274692543577577550894681403"); BigInteger s = new BigInteger("1089214853334067536215539335472893651470583479365"); DSAParametersGenerator pGen = new DSAParametersGenerator(); pGen.init(512, 80, random); DSAParameters params = pGen.generateParameters(); DSAValidationParameters pValid = params.getValidationParameters(); if (pValid.getCounter() != 105) { fail("Counter wrong"); } if (!pValue.equals(params.getP()) || !qValue.equals(params.getQ())) { fail("p or q wrong"); } DSAKeyPairGenerator dsaKeyGen = new DSAKeyPairGenerator(); DSAKeyGenerationParameters genParam = new DSAKeyGenerationParameters(keyRandom, params); dsaKeyGen.init(genParam); AsymmetricCipherKeyPair pair = dsaKeyGen.generateKeyPair(); ParametersWithRandom param = new ParametersWithRandom(pair.getPrivate(), keyRandom); DSASigner dsa = new DSASigner(); dsa.init(true, param); byte[] message = BigIntegers.asUnsignedByteArray(new BigInteger("968236873715988614170569073515315707566766479517")); BigInteger[] sig = dsa.generateSignature(message); if (!r.equals(sig[0])) { fail("r component wrong.", r, sig[0]); } if (!s.equals(sig[1])) { fail("s component wrong.", s, sig[1]); } dsa.init(false, pair.getPublic()); if (!dsa.verifySignature(message, sig[0], sig[1])) { fail("verification fails"); } dsa2Test1(); dsa2Test2(); dsa2Test3(); dsa2Test4(); } private void dsa2Test1() { byte[] seed = Hex.decode("ED8BEE8D1CB89229D2903CBF0E51EE7377F48698"); DSAParametersGenerator pGen = new DSAParametersGenerator(); pGen.init(new DSAParameterGenerationParameters(1024, 160, 80, new DSATestSecureRandom(seed))); DSAParameters params = pGen.generateParameters(); DSAValidationParameters pv = params.getValidationParameters(); if (pv.getCounter() != 5) { fail("counter incorrect"); } if (!Arrays.areEqual(seed, pv.getSeed())) { fail("seed incorrect"); } if (!params.getQ().equals(new BigInteger("E950511EAB424B9A19A2AEB4E159B7844C589C4F", 16))) { fail("Q incorrect"); } if (!params.getP().equals(new BigInteger( "E0A67598CD1B763B" + "C98C8ABB333E5DDA0CD3AA0E5E1FB5BA8A7B4EABC10BA338" + "FAE06DD4B90FDA70D7CF0CB0C638BE3341BEC0AF8A7330A3" + "307DED2299A0EE606DF035177A239C34A912C202AA5F83B9" + "C4A7CF0235B5316BFC6EFB9A248411258B30B839AF172440" + "F32563056CB67A861158DDD90E6A894C72A5BBEF9E286C6B", 16))) { fail("P incorrect"); } if (!params.getG().equals(new BigInteger( "D29D5121B0423C27" + "69AB21843E5A3240FF19CACC792264E3BB6BE4F78EDD1B15" + "C4DFF7F1D905431F0AB16790E1F773B5CE01C804E509066A" + "9919F5195F4ABC58189FD9FF987389CB5BEDF21B4DAB4F8B" + "76A055FFE2770988FE2EC2DE11AD92219F0B351869AC24DA" + "3D7BA87011A701CE8EE7BFE49486ED4527B7186CA4610A75", 16))) { fail("G incorrect"); } DSAKeyPairGenerator kpGen = new DSAKeyPairGenerator(); kpGen.init(new DSAKeyGenerationParameters(new FixedSecureRandom(Hex.decode("D0EC4E50BB290A42E9E355C73D8809345DE2E139")), params)); AsymmetricCipherKeyPair kp = kpGen.generateKeyPair(); DSAPublicKeyParameters pub = (DSAPublicKeyParameters)kp.getPublic(); DSAPrivateKeyParameters priv = (DSAPrivateKeyParameters)kp.getPrivate(); if (!pub.getY().equals(new BigInteger( "25282217F5730501" + "DD8DBA3EDFCF349AAFFEC20921128D70FAC44110332201BB" + "A3F10986140CBB97C726938060473C8EC97B4731DB004293" + "B5E730363609DF9780F8D883D8C4D41DED6A2F1E1BBBDC97" + "9E1B9D6D3C940301F4E978D65B19041FCF1E8B518F5C0576" + "C770FE5A7A485D8329EE2914A2DE1B5DA4A6128CEAB70F79", 16))) { fail("Y value incorrect"); } if (!priv.getX().equals( new BigInteger("D0EC4E50BB290A42E9E355C73D8809345DE2E139", 16))) { fail("X value incorrect"); } DSASigner signer = new DSASigner(); signer.init(true, new ParametersWithRandom(kp.getPrivate(), new FixedSecureRandom(Hex.decode("349C55648DCF992F3F33E8026CFAC87C1D2BA075")))); byte[] msg = Hex.decode("A9993E364706816ABA3E25717850C26C9CD0D89D"); BigInteger[] sig = signer.generateSignature(msg); if (!sig[0].equals(new BigInteger("636155AC9A4633B4665D179F9E4117DF68601F34", 16))) { fail("R value incorrect"); } if (!sig[1].equals(new BigInteger("6C540B02D9D4852F89DF8CFC99963204F4347704", 16))) { fail("S value incorrect"); } signer.init(false, kp.getPublic()); if (!signer.verifySignature(msg, sig[0], sig[1])) { fail("signature not verified"); } } private void dsa2Test2() { byte[] seed = Hex.decode("5AFCC1EFFC079A9CCA6ECA86D6E3CC3B18642D9BE1CC6207C84002A9"); DSAParametersGenerator pGen = new DSAParametersGenerator(new SHA224Digest()); pGen.init(new DSAParameterGenerationParameters(2048, 224, 80, new DSATestSecureRandom(seed))); DSAParameters params = pGen.generateParameters(); DSAValidationParameters pv = params.getValidationParameters(); if (pv.getCounter() != 21) { fail("counter incorrect"); } if (!Arrays.areEqual(seed, pv.getSeed())) { fail("seed incorrect"); } if (!params.getQ().equals(new BigInteger("90EAF4D1AF0708B1B612FF35E0A2997EB9E9D263C9CE659528945C0D", 16))) { fail("Q incorrect"); } if (!params.getP().equals(new BigInteger( "C196BA05AC29E1F9C3C72D56DFFC6154" + "A033F1477AC88EC37F09BE6C5BB95F51C296DD20D1A28A06" + "7CCC4D4316A4BD1DCA55ED1066D438C35AEBAABF57E7DAE4" + "28782A95ECA1C143DB701FD48533A3C18F0FE23557EA7AE6" + "19ECACC7E0B51652A8776D02A425567DED36EABD90CA33A1" + "E8D988F0BBB92D02D1D20290113BB562CE1FC856EEB7CDD9" + "2D33EEA6F410859B179E7E789A8F75F645FAE2E136D252BF" + "FAFF89528945C1ABE705A38DBC2D364AADE99BE0D0AAD82E" + "5320121496DC65B3930E38047294FF877831A16D5228418D" + "E8AB275D7D75651CEFED65F78AFC3EA7FE4D79B35F62A040" + "2A1117599ADAC7B269A59F353CF450E6982D3B1702D9CA83", 16))) { fail("P incorrect"); } if (!params.getG().equals(new BigInteger( "A59A749A11242C58C894E9E5A91804E8"+ "FA0AC64B56288F8D47D51B1EDC4D65444FECA0111D78F35F"+ "C9FDD4CB1F1B79A3BA9CBEE83A3F811012503C8117F98E50"+ "48B089E387AF6949BF8784EBD9EF45876F2E6A5A495BE64B"+ "6E770409494B7FEE1DBB1E4B2BC2A53D4F893D418B715959"+ "2E4FFFDF6969E91D770DAEBD0B5CB14C00AD68EC7DC1E574"+ "5EA55C706C4A1C5C88964E34D09DEB753AD418C1AD0F4FDF"+ "D049A955E5D78491C0B7A2F1575A008CCD727AB376DB6E69"+ "5515B05BD412F5B8C2F4C77EE10DA48ABD53F5DD498927EE"+ "7B692BBBCDA2FB23A516C5B4533D73980B2A3B60E384ED20"+ "0AE21B40D273651AD6060C13D97FD69AA13C5611A51B9085", 16))) { fail("G incorrect"); } DSAKeyPairGenerator kpGen = new DSAKeyPairGenerator(); kpGen.init(new DSAKeyGenerationParameters(new FixedSecureRandom(Hex.decode("00D0F09ED3E2568F6CADF9224117DA2AEC5A4300E009DE1366023E17")), params)); AsymmetricCipherKeyPair kp = kpGen.generateKeyPair(); DSAPublicKeyParameters pub = (DSAPublicKeyParameters)kp.getPublic(); DSAPrivateKeyParameters priv = (DSAPrivateKeyParameters)kp.getPrivate(); if (!pub.getY().equals(new BigInteger( "70035C9A3B225B258F16741F3941FBF0" + "6F3D056CD7BD864604CBB5EE9DD85304EE8E8E4ABD5E9032" + "11DDF25CE149075510ACE166970AFDC7DF552B7244F342FA" + "02F7A621405B754909D757F97290E1FE5036E904CF593446" + "0C046D95659821E1597ED9F2B1F0E20863A6BBD0CE74DACB" + "A5D8C68A90B29C2157CDEDB82EC12B81EE3068F9BF5F7F34" + "6ECA41ED174CCCD7D154FA4F42F80FFE1BF46AE9D8125DEB" + "5B4BA08A72BDD86596DBEDDC9550FDD650C58F5AE5133509" + "A702F79A31ECB490F7A3C5581631F7C5BE4FF7F9E9F27FA3" + "90E47347AD1183509FED6FCF198BA9A71AB3335B4F38BE8D" + "15496A00B6DC2263E20A5F6B662320A3A1EC033AA61E3B68", 16))) { fail("Y value incorrect"); } if (!priv.getX().equals( new BigInteger("00D0F09ED3E2568F6CADF9224117DA2AEC5A4300E009DE1366023E17", 16))) { fail("X value incorrect"); } DSASigner signer = new DSASigner(); signer.init(true, new ParametersWithRandom(kp.getPrivate(), new FixedSecureRandom(Hex.decode("735959CC4463B8B440E407EECA8A473BF6A6D1FE657546F67D401F05")))); byte[] msg = Hex.decode("23097D223405D8228642A477BDA255B32AADBCE4BDA0B3F7E36C9DA7"); BigInteger[] sig = signer.generateSignature(msg); if (!sig[0].equals(new BigInteger("4400138D05F9639CAF54A583CAAF25D2B76D0C3EAD752CE17DBC85FE", 16))) { fail("R value incorrect"); } if (!sig[1].equals(new BigInteger("874D4F12CB13B61732D398445698CFA9D92381D938AA57EE2C9327B3", 16))) { fail("S value incorrect"); } signer.init(false, kp.getPublic()); if (!signer.verifySignature(msg, sig[0], sig[1])) { fail("signature not verified"); } } private void dsa2Test3() { byte[] seed = Hex.decode("4783081972865EA95D43318AB2EAF9C61A2FC7BBF1B772A09017BDF5A58F4FF0"); DSAParametersGenerator pGen = new DSAParametersGenerator(new SHA256Digest()); pGen.init(new DSAParameterGenerationParameters(2048, 256, 80, new DSATestSecureRandom(seed))); DSAParameters params = pGen.generateParameters(); DSAValidationParameters pv = params.getValidationParameters(); if (pv.getCounter() != 12) { fail("counter incorrect"); } if (!Arrays.areEqual(seed, pv.getSeed())) { fail("seed incorrect"); } if (!params.getQ().equals(new BigInteger("C24ED361870B61E0D367F008F99F8A1F75525889C89DB1B673C45AF5867CB467", 16))) { fail("Q incorrect"); } if (!params.getP().equals(new BigInteger( "F56C2A7D366E3EBDEAA1891FD2A0D099" + "436438A673FED4D75F594959CFFEBCA7BE0FC72E4FE67D91" + "D801CBA0693AC4ED9E411B41D19E2FD1699C4390AD27D94C" + "69C0B143F1DC88932CFE2310C886412047BD9B1C7A67F8A2" + "5909132627F51A0C866877E672E555342BDF9355347DBD43" + "B47156B2C20BAD9D2B071BC2FDCF9757F75C168C5D9FC431" + "31BE162A0756D1BDEC2CA0EB0E3B018A8B38D3EF2487782A" + "EB9FBF99D8B30499C55E4F61E5C7DCEE2A2BB55BD7F75FCD" + "F00E48F2E8356BDB59D86114028F67B8E07B127744778AFF" + "1CF1399A4D679D92FDE7D941C5C85C5D7BFF91BA69F9489D" + "531D1EBFA727CFDA651390F8021719FA9F7216CEB177BD75", 16))) { fail("P incorrect"); } if (!params.getG().equals(new BigInteger( "8DC6CC814CAE4A1C05A3E186A6FE27EA" + "BA8CDB133FDCE14A963A92E809790CBA096EAA26140550C1" + "29FA2B98C16E84236AA33BF919CD6F587E048C52666576DB" + "6E925C6CBE9B9EC5C16020F9A44C9F1C8F7A8E611C1F6EC2" + "513EA6AA0B8D0F72FED73CA37DF240DB57BBB27431D61869" + "7B9E771B0B301D5DF05955425061A30DC6D33BB6D2A32BD0" + "A75A0A71D2184F506372ABF84A56AEEEA8EB693BF29A6403" + "45FA1298A16E85421B2208D00068A5A42915F82CF0B858C8" + "FA39D43D704B6927E0B2F916304E86FB6A1B487F07D8139E" + "428BB096C6D67A76EC0B8D4EF274B8A2CF556D279AD267CC" + "EF5AF477AFED029F485B5597739F5D0240F67C2D948A6279", 16))) { fail("G incorrect"); } DSAKeyPairGenerator kpGen = new DSAKeyPairGenerator(); kpGen.init(new DSAKeyGenerationParameters(new FixedSecureRandom(Hex.decode("0CAF2EF547EC49C4F3A6FE6DF4223A174D01F2C115D49A6F73437C29A2A8458C")), params)); AsymmetricCipherKeyPair kp = kpGen.generateKeyPair(); DSAPublicKeyParameters pub = (DSAPublicKeyParameters)kp.getPublic(); DSAPrivateKeyParameters priv = (DSAPrivateKeyParameters)kp.getPrivate(); if (!pub.getY().equals(new BigInteger( "2828003D7C747199143C370FDD07A286" + "1524514ACC57F63F80C38C2087C6B795B62DE1C224BF8D1D" + "1424E60CE3F5AE3F76C754A2464AF292286D873A7A30B7EA" + "CBBC75AAFDE7191D9157598CDB0B60E0C5AA3F6EBE425500" + "C611957DBF5ED35490714A42811FDCDEB19AF2AB30BEADFF" + "2907931CEE7F3B55532CFFAEB371F84F01347630EB227A41" + "9B1F3F558BC8A509D64A765D8987D493B007C4412C297CAF" + "41566E26FAEE475137EC781A0DC088A26C8804A98C23140E" + "7C936281864B99571EE95C416AA38CEEBB41FDBFF1EB1D1D" + "C97B63CE1355257627C8B0FD840DDB20ED35BE92F08C49AE" + "A5613957D7E5C7A6D5A5834B4CB069E0831753ECF65BA02B", 16))) { fail("Y value incorrect"); } if (!priv.getX().equals( new BigInteger("0CAF2EF547EC49C4F3A6FE6DF4223A174D01F2C115D49A6F73437C29A2A8458C", 16))) { fail("X value incorrect"); } DSASigner signer = new DSASigner(); signer.init(true, new ParametersWithRandom(kp.getPrivate(), new FixedSecureRandom(Hex.decode("0CAF2EF547EC49C4F3A6FE6DF4223A174D01F2C115D49A6F73437C29A2A8458C")))); byte[] msg = Hex.decode("BA7816BF8F01CFEA414140DE5DAE2223B00361A396177A9CB410FF61F20015AD"); BigInteger[] sig = signer.generateSignature(msg); if (!sig[0].equals(new BigInteger("315C875DCD4850E948B8AC42824E9483A32D5BA5ABE0681B9B9448D444F2BE3C", 16))) { fail("R value incorrect"); } if (!sig[1].equals(new BigInteger("89718D12E54A8D9ED066E4A55F7ED5A2229CD23B9A3CEE78F83ED6AA61F6BCB9", 16))) { fail("S value incorrect"); } signer.init(false, kp.getPublic()); if (!signer.verifySignature(msg, sig[0], sig[1])) { fail("signature not verified"); } } private void dsa2Test4() { byte[] seed = Hex.decode("193AFCA7C1E77B3C1ECC618C81322E47B8B8B997C9C83515C59CC446C2D9BD47"); DSAParametersGenerator pGen = new DSAParametersGenerator(new SHA256Digest()); pGen.init(new DSAParameterGenerationParameters(3072, 256, 80, new DSATestSecureRandom(seed))); DSAParameters params = pGen.generateParameters(); DSAValidationParameters pv = params.getValidationParameters(); if (pv.getCounter() != 20) { fail("counter incorrect"); } if (!Arrays.areEqual(seed, pv.getSeed())) { fail("seed incorrect"); } if (!params.getQ().equals(new BigInteger("CFA0478A54717B08CE64805B76E5B14249A77A4838469DF7F7DC987EFCCFB11D", 16))) { fail("Q incorrect"); } if (!params.getP().equals(new BigInteger( "90066455B5CFC38F9CAA4A48B4281F292C260FEEF01FD610" + "37E56258A7795A1C7AD46076982CE6BB956936C6AB4DCFE0" + "5E6784586940CA544B9B2140E1EB523F009D20A7E7880E4E" + "5BFA690F1B9004A27811CD9904AF70420EEFD6EA11EF7DA1" + "29F58835FF56B89FAA637BC9AC2EFAAB903402229F491D8D" + "3485261CD068699B6BA58A1DDBBEF6DB51E8FE34E8A78E54" + "2D7BA351C21EA8D8F1D29F5D5D15939487E27F4416B0CA63" + "2C59EFD1B1EB66511A5A0FBF615B766C5862D0BD8A3FE7A0" + "E0DA0FB2FE1FCB19E8F9996A8EA0FCCDE538175238FC8B0E" + "E6F29AF7F642773EBE8CD5402415A01451A840476B2FCEB0" + "E388D30D4B376C37FE401C2A2C2F941DAD179C540C1C8CE0" + "30D460C4D983BE9AB0B20F69144C1AE13F9383EA1C08504F" + "B0BF321503EFE43488310DD8DC77EC5B8349B8BFE97C2C56" + "0EA878DE87C11E3D597F1FEA742D73EEC7F37BE43949EF1A" + "0D15C3F3E3FC0A8335617055AC91328EC22B50FC15B941D3" + "D1624CD88BC25F3E941FDDC6200689581BFEC416B4B2CB73", 16))) { fail("P incorrect"); } if (!params.getG().equals(new BigInteger( "5E5CBA992E0A680D885EB903AEA78E4A45A469103D448EDE" + "3B7ACCC54D521E37F84A4BDD5B06B0970CC2D2BBB715F7B8" + "2846F9A0C393914C792E6A923E2117AB805276A975AADB52" + "61D91673EA9AAFFEECBFA6183DFCB5D3B7332AA19275AFA1" + "F8EC0B60FB6F66CC23AE4870791D5982AAD1AA9485FD8F4A" + "60126FEB2CF05DB8A7F0F09B3397F3937F2E90B9E5B9C9B6" + "EFEF642BC48351C46FB171B9BFA9EF17A961CE96C7E7A7CC" + "3D3D03DFAD1078BA21DA425198F07D2481622BCE45969D9C" + "4D6063D72AB7A0F08B2F49A7CC6AF335E08C4720E31476B6" + "7299E231F8BD90B39AC3AE3BE0C6B6CACEF8289A2E2873D5" + "8E51E029CAFBD55E6841489AB66B5B4B9BA6E2F784660896" + "AFF387D92844CCB8B69475496DE19DA2E58259B090489AC8" + "E62363CDF82CFD8EF2A427ABCD65750B506F56DDE3B98856" + "7A88126B914D7828E2B63A6D7ED0747EC59E0E0A23CE7D8A" + "74C1D2C2A7AFB6A29799620F00E11C33787F7DED3B30E1A2" + "2D09F1FBDA1ABBBFBF25CAE05A13F812E34563F99410E73B", 16))) { fail("G incorrect"); } DSAKeyPairGenerator kpGen = new DSAKeyPairGenerator(); kpGen.init(new DSAKeyGenerationParameters(new FixedSecureRandom(Hex.decode("3ABC1587297CE7B9EA1AD6651CF2BC4D7F92ED25CABC8553F567D1B40EBB8764")), params)); AsymmetricCipherKeyPair kp = kpGen.generateKeyPair(); DSAPublicKeyParameters pub = (DSAPublicKeyParameters)kp.getPublic(); DSAPrivateKeyParameters priv = (DSAPrivateKeyParameters)kp.getPrivate(); if (!pub.getY().equals(new BigInteger( "8B891C8692D3DE875879390F2698B26FBECCA6B075535DCE" + "6B0C862577F9FA0DEF6074E7A7624121224A595896ABD4CD" + "A56B2CEFB942E025D2A4282FFAA98A48CDB47E1A6FCB5CFB" + "393EF35AF9DF913102BB303C2B5C36C3F8FC04ED7B8B69FE" + "FE0CF3E1FC05CFA713B3435B2656E913BA8874AEA9F93600" + "6AEB448BCD005D18EC3562A33D04CF25C8D3D69844343442" + "FA3DB7DE618C5E2DA064573E61E6D5581BFB694A23AC87FD" + "5B52D62E954E1376DB8DDB524FFC0D469DF978792EE44173" + "8E5DB05A7DC43E94C11A2E7A4FBE383071FA36D2A7EC8A93" + "88FE1C4F79888A99D3B6105697C2556B79BB4D7E781CEBB3" + "D4866AD825A5E830846072289FDBC941FA679CA82F5F78B7" + "461B2404DB883D215F4E0676CF5493950AC5591697BFEA8D" + "1EE6EC016B89BA51CAFB5F9C84C989FA117375E94578F28B" + "E0B34CE0545DA46266FD77F62D8F2CEE92AB77012AFEBC11" + "008985A821CD2D978C7E6FE7499D1AAF8DE632C21BB48CA5" + "CBF9F31098FD3FD3854C49A65D9201744AACE540354974F9", 16))) { fail("Y value incorrect"); } if (!priv.getX().equals( new BigInteger("3ABC1587297CE7B9EA1AD6651CF2BC4D7F92ED25CABC8553F567D1B40EBB8764", 16))) { fail("X value incorrect"); } DSASigner signer = new DSASigner(); signer.init(true, new ParametersWithRandom(kp.getPrivate(), new FixedSecureRandom(Hex.decode("A6902C1E6E3943C5628061588A8B007BCCEA91DBF12915483F04B24AB0678BEE")))); byte[] msg = Hex.decode("BA7816BF8F01CFEA414140DE5DAE2223B00361A396177A9CB410FF61F20015AD"); BigInteger[] sig = signer.generateSignature(msg); if (!sig[0].equals(new BigInteger("5F184E645A38BE8FB4A6871B6503A9D12924C7ABE04B71410066C2ECA6E3BE3E", 16))) { fail("R value incorrect"); } if (!sig[1].equals(new BigInteger("91EB0C7BA3D4B9B60B825C3D9F2CADA8A2C9D7723267B033CBCDCF8803DB9C18", 16))) { fail("S value incorrect"); } signer.init(false, kp.getPublic()); if (!signer.verifySignature(msg, sig[0], sig[1])) { fail("signature not verified"); } } public static void main( String[] args) { runTest(new DSATest()); } private class DSATestSecureRandom extends FixedSecureRandom { private boolean first = true; public DSATestSecureRandom(byte[] value) { super(value); } public void nextBytes(byte[] bytes) { if (first) { super.nextBytes(bytes); first = false; } else { bytes[bytes.length - 1] = 2; } } } } bouncycastle-1.49.orig/test/src/org/bouncycastle/crypto/test/GMacTest.java0000644000175000017500000001457112146541032026300 0ustar ebourgebourgpackage org.bouncycastle.crypto.test; import org.bouncycastle.crypto.CipherParameters; import org.bouncycastle.crypto.Mac; import org.bouncycastle.crypto.engines.AESFastEngine; import org.bouncycastle.crypto.macs.GMac; import org.bouncycastle.crypto.modes.GCMBlockCipher; import org.bouncycastle.crypto.params.KeyParameter; import org.bouncycastle.crypto.params.ParametersWithIV; import org.bouncycastle.util.encoders.Hex; import org.bouncycastle.util.test.SimpleTest; /** * Test vectors for AES-GMAC, extracted from NIST CAVP GCM test * vectors. * */ public class GMacTest extends SimpleTest { private static class TestCase { private byte[] key; private byte[] iv; private byte[] ad; private byte[] tag; private String name; private TestCase(final String name, final String key, final String iv, final String ad, final String tag) { this.name = name; this.key = Hex.decode(key); this.iv = Hex.decode(iv); this.ad = Hex.decode(ad); this.tag = Hex.decode(tag); } public String getName() { return name; } public byte[] getKey() { return key; } public byte[] getIv() { return iv; } public byte[] getAd() { return ad; } public byte[] getTag() { return tag; } } private static TestCase[] TEST_VECTORS = new TestCase[] { // Count = 0, from each of the PTlen = 0 test vector sequences new TestCase("128/96/0/128", "11754cd72aec309bf52f7687212e8957", "3c819d9a9bed087615030b65", "", "250327c674aaf477aef2675748cf6971"), new TestCase("128/96/0/120", "272f16edb81a7abbea887357a58c1917", "794ec588176c703d3d2a7a07", "", "b6e6f197168f5049aeda32dafbdaeb"), new TestCase("128/96/0/112", "81b6844aab6a568c4556a2eb7eae752f", "ce600f59618315a6829bef4d", "", "89b43e9dbc1b4f597dbbc7655bb5"), new TestCase("128/96/0/104", "cde2f9a9b1a004165ef9dc981f18651b", "29512c29566c7322e1e33e8e", "", "2e58ce7dabd107c82759c66a75"), new TestCase("128/96/0/96", "b01e45cc3088aaba9fa43d81d481823f", "5a2c4a66468713456a4bd5e1", "", "014280f944f53c681164b2ff"), new TestCase("128/96/128/128", "77be63708971c4e240d1cb79e8d77feb", "e0e00f19fed7ba0136a797f3", "7a43ec1d9c0a5a78a0b16533a6213cab", "209fcc8d3675ed938e9c7166709dd946"), new TestCase("128/96/128/96", "bea48ae4980d27f357611014d4486625", "32bddb5c3aa998a08556454c", "8a50b0b8c7654bced884f7f3afda2ead", "8e0f6d8bf05ffebe6f500eb1"), new TestCase("128/96/384/128", "99e3e8793e686e571d8285c564f75e2b", "c2dd0ab868da6aa8ad9c0d23", "b668e42d4e444ca8b23cfdd95a9fedd5178aa521144890b093733cf5cf22526c5917ee476541809ac6867a8c399309fc", "3f4fba100eaf1f34b0baadaae9995d85"), new TestCase("128/96/384/96", "c77acd1b0918e87053cb3e51651e7013", "39ff857a81745d10f718ac00", "407992f82ea23b56875d9a3cb843ceb83fd27cb954f7c5534d58539fe96fb534502a1b38ea4fac134db0a42de4be1137", "2a5dc173285375dc82835876"), new TestCase( "128/1024/0/128", "d0f1f4defa1e8c08b4b26d576392027c", "42b4f01eb9f5a1ea5b1eb73b0fb0baed54f387ecaa0393c7d7dffc6af50146ecc021abf7eb9038d4303d91f8d741a11743166c0860208bcc02c6258fd9511a2fa626f96d60b72fcff773af4e88e7a923506e4916ecbd814651e9f445adef4ad6a6b6c7290cc13b956130eef5b837c939fcac0cbbcc9656cd75b13823ee5acdac", "", "7ab49b57ddf5f62c427950111c5c4f0d"), new TestCase( "128/1024/384/96", "3cce72d37933394a8cac8a82deada8f0", "aa2f0d676d705d9733c434e481972d4888129cf7ea55c66511b9c0d25a92a174b1e28aa072f27d4de82302828955aadcb817c4907361869bd657b45ff4a6f323871987fcf9413b0702d46667380cd493ed24331a28b9ce5bbfa82d3a6e7679fcce81254ba64abcad14fd18b22c560a9d2c1cd1d3c42dac44c683edf92aced894", "5686b458e9c176f4de8428d9ebd8e12f569d1c7595cf49a4b0654ab194409f86c0dd3fdb8eb18033bb4338c70f0b97d1", "a3a9444b21f330c3df64c8b6"), }; public void performTest() { for (int i = 0; i < TEST_VECTORS.length; i++) { TestCase testCase = TEST_VECTORS[i]; Mac mac = new GMac(new GCMBlockCipher(new AESFastEngine()), testCase.getTag().length * 8); CipherParameters key = new KeyParameter(testCase.getKey()); mac.init(new ParametersWithIV(key, testCase.getIv())); testSingleByte(mac, testCase); testMultibyte(mac, testCase); } // Invalid mac size testInvalidMacSize(97); testInvalidMacSize(136); testInvalidMacSize(88); testInvalidMacSize(64); } private void testInvalidMacSize(int size) { try { GMac mac = new GMac(new GCMBlockCipher(new AESFastEngine()), size); mac.init(new ParametersWithIV(null, new byte[16])); fail("Expected failure for illegal mac size " + size); } catch (IllegalArgumentException e) { } } private void testMultibyte(Mac mac, TestCase testCase) { mac.update(testCase.getAd(), 0, testCase.getAd().length); checkMac(mac, testCase); } private void testSingleByte(Mac mac, TestCase testCase) { final byte[] ad = testCase.getAd(); for (int i = 0; i < ad.length; i++) { mac.update(ad[i]); } checkMac(mac, testCase); } private void checkMac(Mac mac, TestCase testCase) { final byte[] generatedMac = new byte[mac.getMacSize()]; mac.doFinal(generatedMac, 0); if (!areEqual(testCase.getTag(), generatedMac)) { fail("Failed " + testCase.getName() + " - expected " + new String(Hex.encode(testCase.getTag())) + " got " + new String(Hex.encode(generatedMac))); } } public String getName() { return "GMac"; } public static void main(String[] args) { runTest(new GMacTest()); } } bouncycastle-1.49.orig/test/src/org/bouncycastle/crypto/test/HCFamilyTest.java0000644000175000017500000001600011165257341027121 0ustar ebourgebourgpackage org.bouncycastle.crypto.test; import org.bouncycastle.crypto.StreamCipher; import org.bouncycastle.crypto.engines.HC128Engine; import org.bouncycastle.crypto.engines.HC256Engine; import org.bouncycastle.crypto.params.KeyParameter; import org.bouncycastle.crypto.params.ParametersWithIV; import org.bouncycastle.util.encoders.Hex; import org.bouncycastle.util.test.SimpleTest; /** * HC-128 and HC-256 Tests. Based on the test vectors in the official reference * papers, respectively: *

     * http://www.ecrypt.eu.org/stream/p3ciphers/hc/hc128_p3.pdf
     * http://www.ecrypt.eu.org/stream/p3ciphers/hc/hc256_p3.pdf
     * 
    * See HCFamilyVecTest for a more exhaustive test based on the ecrypt vectors. */ public class HCFamilyTest extends SimpleTest { private static final byte[] MSG = new byte[64]; private static String[][] HC128_VerifiedTest = { { "Set 2, vector# 0", "00000000000000000000000000000000", "00000000000000000000000000000000", "82001573A003FD3B7FD72FFB0EAF63AA" + "C62F12DEB629DCA72785A66268EC758B" + "1EDB36900560898178E0AD009ABF1F49" + "1330DC1C246E3D6CB264F6900271D59C" }, { "Set 6, vector# 0", "0053A6F94C9FF24598EB3E91E4378ADD", "0D74DB42A91077DE45AC137AE148AF16", "2E1ED12A8551C05AF41FF39D8F9DF933" + "122B5235D48FC2A6F20037E69BDBBCE8" + "05782EFC16C455A4B3FF06142317535E" + "F876104C32445138CB26EBC2F88A684C" }, { "Set 6, vector# 1", "0558ABFE51A4F74A9DF04396E93C8FE2", "167DE44BB21980E74EB51C83EA51B81F", "4F864BF3C96D0363B1903F0739189138" + "F6ED2BC0AF583FEEA0CEA66BA7E06E63" + "FB28BF8B3CA0031D24ABB511C57DD17B" + "FC2861C32400072CB680DF2E58A5CECC" }, { "Set 6, vector# 2", "0A5DB00356A9FC4FA2F5489BEE4194E7", "1F86ED54BB2289F057BE258CF35AC128", "82168AB0023B79AAF1E6B4D823855E14" + "A7084378036A951B1CFEF35173875ED8" + "6CB66AB8410491A08582BE40080C3102" + "193BA567F9E95D096C3CC60927DD7901" }, { "Set 6, vector# 3", "0F62B5085BAE0154A7FA4DA0F34699EC", "288FF65DC42B92F960C72E95FC63CA31", "1CD8AEDDFE52E217E835D0B7E84E2922" + "D04B1ADBCA53C4522B1AA604C42856A9" + "0AF83E2614BCE65C0AECABDD8975B557" + "00D6A26D52FFF0888DA38F1DE20B77B7" } }; private static String[][] HC256_VerifiedTest = { { "Set 2, vector# 0", "00000000000000000000000000000000", "00000000000000000000000000000000", "5B078985D8F6F30D42C5C02FA6B67951" + "53F06534801F89F24E74248B720B4818" + "CD9227ECEBCF4DBF8DBF6977E4AE14FA" + "E8504C7BC8A9F3EA6C0106F5327E6981" }, { "Set 2, vector# 9", "09090909090909090909090909090909", "00000000000000000000000000000000", "F5C2926651AEED9AF1A9C2F04C03D081" + "2145B56AEA46EB283A25A4C9E3D8BEB4" + "821B418F06F2B9DCDF1A85AB8C02CD14" + "62E1BBCAEC9AB0E99AA6AFF918BA627C" }, { "Set 2, vector#135", "87878787878787878787878787878787", "00000000000000000000000000000000", "CEC0C3852E3B98233EBCB975C10B1191" + "3C69F2275EB97A1402EDF16C6FBE19BE" + "79D65360445BCB63676E6553B609A065" + "0155C3B22DD1975AC0F3F65063A2E16E" }, { "Set 6, vector# 0", "0053A6F94C9FF24598EB3E91E4378ADD" + "3083D6297CCF2275C81B6EC11467BA0D", "0D74DB42A91077DE45AC137AE148AF16" + "7DE44BB21980E74EB51C83EA51B81F86", "23D9E70A45EB0127884D66D9F6F23C01" + "D1F88AFD629270127247256C1FFF91E9" + "1A797BD98ADD23AE15BEE6EEA3CEFDBF" + "A3ED6D22D9C4F459DB10C40CDF4F4DFF" }, { "Set 6, vector# 1", "0558ABFE51A4F74A9DF04396E93C8FE2" + "3588DB2E81D4277ACD2073C6196CBF12", "167DE44BB21980E74EB51C83EA51B81F" + "86ED54BB2289F057BE258CF35AC1288F", "C44B5262F2EAD9C018213127686DB742" + "A72D3F2D61D18F0F4E7DE5B4F7ADABE0" + "7E0C82033B139F02BAACB4E2F2D0BE30" + "110C3A8A2B621523756692877C905DD0" }, { "Set 6, vector# 2", "0A5DB00356A9FC4FA2F5489BEE4194E7" + "3A8DE03386D92C7FD22578CB1E71C417", "1F86ED54BB2289F057BE258CF35AC128" + "8FF65DC42B92F960C72E95FC63CA3198", "9D13AA06122F4F03AE60D507701F1ED0" + "63D7530FF35EE76CAEDCBFB01D8A239E" + "FA4A44B272DE9B4092E2AD56E87C3A60" + "89F5A074D1F6E5B8FC6FABEE0C936F06" }, { "Set 6, vector# 3", "0F62B5085BAE0154A7FA4DA0F34699EC" + "3F92E5388BDE3184D72A7DD02376C91C", "288FF65DC42B92F960C72E95FC63CA31" + "98FF66CD349B0269D0379E056CD33AA1", "C8632038DA61679C4685288B37D3E232" + "7BC2D28C266B041FE0CA0D3CFEED8FD5" + "753259BAB757168F85EA96ADABD823CA" + "4684E918423E091565713FEDDE2CCFE0" } }; public String getName() { return "HC-128 and HC-256"; } public void performTest() { StreamCipher hc = new HC256Engine(); for (int i = 0; i != HC256_VerifiedTest.length; i++) { String[] test = HC256_VerifiedTest[i]; HCTest(hc, "HC-256 - " + test[0], Hex.decode(test[1]), Hex.decode(test[2]), Hex.decode(test[3])); } hc = new HC128Engine(); for (int i = 0; i != HC128_VerifiedTest.length; i++) { String[] test = HC128_VerifiedTest[i]; HCTest(hc, "HC-128 - " + test[0], Hex.decode(test[1]), Hex.decode(test[2]), Hex.decode(test[3])); } } private void HCTest(StreamCipher hc, String test, byte[] key, byte[] IV, byte[] expected) { KeyParameter kp = new KeyParameter(key); ParametersWithIV ivp = new ParametersWithIV(kp, IV); hc.init(true, ivp); for (int i = 0; i < 64; i++) { if (hc.returnByte(MSG[i]) != expected[i]) { fail(test + " failure at byte " + i); } } } public static void main(String[] args) { runTest(new HCFamilyTest()); } } bouncycastle-1.49.orig/test/src/org/bouncycastle/crypto/test/RSABlindedTest.java0000644000175000017500000003460410707053207027402 0ustar ebourgebourgpackage org.bouncycastle.crypto.test; import org.bouncycastle.crypto.AsymmetricBlockCipher; import org.bouncycastle.crypto.AsymmetricCipherKeyPair; import org.bouncycastle.crypto.InvalidCipherTextException; import org.bouncycastle.crypto.encodings.OAEPEncoding; import org.bouncycastle.crypto.encodings.PKCS1Encoding; import org.bouncycastle.crypto.engines.RSABlindedEngine; import org.bouncycastle.crypto.generators.RSAKeyPairGenerator; import org.bouncycastle.crypto.params.RSAKeyGenerationParameters; import org.bouncycastle.crypto.params.RSAKeyParameters; import org.bouncycastle.crypto.params.RSAPrivateCrtKeyParameters; import org.bouncycastle.util.encoders.Hex; import org.bouncycastle.util.test.SimpleTest; import java.math.BigInteger; import java.security.SecureRandom; public class RSABlindedTest extends SimpleTest { static BigInteger mod = new BigInteger("b259d2d6e627a768c94be36164c2d9fc79d97aab9253140e5bf17751197731d6f7540d2509e7b9ffee0a70a6e26d56e92d2edd7f85aba85600b69089f35f6bdbf3c298e05842535d9f064e6b0391cb7d306e0a2d20c4dfb4e7b49a9640bdea26c10ad69c3f05007ce2513cee44cfe01998e62b6c3637d3fc0391079b26ee36d5", 16); static BigInteger pubExp = new BigInteger("11", 16); static BigInteger privExp = new BigInteger("92e08f83cc9920746989ca5034dcb384a094fb9c5a6288fcc4304424ab8f56388f72652d8fafc65a4b9020896f2cde297080f2a540e7b7ce5af0b3446e1258d1dd7f245cf54124b4c6e17da21b90a0ebd22605e6f45c9f136d7a13eaac1c0f7487de8bd6d924972408ebb58af71e76fd7b012a8d0e165f3ae2e5077a8648e619", 16); static BigInteger p = new BigInteger("f75e80839b9b9379f1cf1128f321639757dba514642c206bbbd99f9a4846208b3e93fbbe5e0527cc59b1d4b929d9555853004c7c8b30ee6a213c3d1bb7415d03", 16); static BigInteger q = new BigInteger("b892d9ebdbfc37e397256dd8a5d3123534d1f03726284743ddc6be3a709edb696fc40c7d902ed804c6eee730eee3d5b20bf6bd8d87a296813c87d3b3cc9d7947", 16); static BigInteger pExp = new BigInteger("1d1a2d3ca8e52068b3094d501c9a842fec37f54db16e9a67070a8b3f53cc03d4257ad252a1a640eadd603724d7bf3737914b544ae332eedf4f34436cac25ceb5", 16); static BigInteger qExp = new BigInteger("6c929e4e81672fef49d9c825163fec97c4b7ba7acb26c0824638ac22605d7201c94625770984f78a56e6e25904fe7db407099cad9b14588841b94f5ab498dded", 16); static BigInteger crtCoef = new BigInteger("dae7651ee69ad1d081ec5e7188ae126f6004ff39556bde90e0b870962fa7b926d070686d8244fe5a9aa709a95686a104614834b0ada4b10f53197a5cb4c97339", 16); static String input = "4e6f77206973207468652074696d6520666f7220616c6c20676f6f64206d656e"; // // to check that we handling byte extension by big number correctly. // static String edgeInput = "ff6f77206973207468652074696d6520666f7220616c6c20676f6f64206d656e"; static byte[] oversizedSig = Hex.decode("01ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff004e6f77206973207468652074696d6520666f7220616c6c20676f6f64206d656e"); static byte[] dudBlock = Hex.decode("000fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff004e6f77206973207468652074696d6520666f7220616c6c20676f6f64206d656e"); static byte[] truncatedDataBlock = Hex.decode("0001ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff004e6f77206973207468652074696d6520666f7220616c6c20676f6f64206d656e"); static byte[] incorrectPadding = Hex.decode("0001ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff4e6f77206973207468652074696d6520666f7220616c6c20676f6f64206d656e"); static byte[] missingDataBlock = Hex.decode("0001ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff"); public String getName() { return "RSABlinded"; } private void testStrictPKCS1Length(RSAKeyParameters pubParameters, RSAKeyParameters privParameters) { AsymmetricBlockCipher eng = new RSABlindedEngine(); eng.init(true, privParameters); byte[] data = null; try { data = eng.processBlock(oversizedSig, 0, oversizedSig.length); } catch (Exception e) { fail("RSA: failed - exception " + e.toString(), e); } eng = new PKCS1Encoding(eng); eng.init(false, pubParameters); try { data = eng.processBlock(data, 0, data.length); fail("oversized signature block not recognised"); } catch (InvalidCipherTextException e) { if (!e.getMessage().equals("block incorrect size")) { fail("RSA: failed - exception " + e.toString(), e); } } //System.setProperty(PKCS1Encoding.STRICT_LENGTH_ENABLED_PROPERTY, "false"); System.getProperties().put(PKCS1Encoding.STRICT_LENGTH_ENABLED_PROPERTY, "false"); eng = new PKCS1Encoding(new RSABlindedEngine()); eng.init(false, pubParameters); try { data = eng.processBlock(data, 0, data.length); } catch (InvalidCipherTextException e) { fail("RSA: failed - exception " + e.toString(), e); } System.getProperties().remove(PKCS1Encoding.STRICT_LENGTH_ENABLED_PROPERTY); } private void testTruncatedPKCS1Block(RSAKeyParameters pubParameters, RSAKeyParameters privParameters) { checkForPKCS1Exception(pubParameters, privParameters, truncatedDataBlock, "block truncated"); } private void testDudPKCS1Block(RSAKeyParameters pubParameters, RSAKeyParameters privParameters) { checkForPKCS1Exception(pubParameters, privParameters, dudBlock, "unknown block type"); } private void testWrongPaddingPKCS1Block(RSAKeyParameters pubParameters, RSAKeyParameters privParameters) { checkForPKCS1Exception(pubParameters, privParameters, incorrectPadding, "block padding incorrect"); } private void testMissingDataPKCS1Block(RSAKeyParameters pubParameters, RSAKeyParameters privParameters) { checkForPKCS1Exception(pubParameters, privParameters, missingDataBlock, "no data in block"); } private void checkForPKCS1Exception(RSAKeyParameters pubParameters, RSAKeyParameters privParameters, byte[] inputData, String expectedMessage) { AsymmetricBlockCipher eng = new RSABlindedEngine(); eng.init(true, privParameters); byte[] data = null; try { data = eng.processBlock(inputData, 0, inputData.length); } catch (Exception e) { fail("RSA: failed - exception " + e.toString(), e); } eng = new PKCS1Encoding(eng); eng.init(false, pubParameters); try { data = eng.processBlock(data, 0, data.length); fail("missing data block not recognised"); } catch (InvalidCipherTextException e) { if (!e.getMessage().equals(expectedMessage)) { fail("RSA: failed - exception " + e.toString(), e); } } } private void testOAEP(RSAKeyParameters pubParameters, RSAKeyParameters privParameters) { // // OAEP - public encrypt, private decrypt // AsymmetricBlockCipher eng = new OAEPEncoding(new RSABlindedEngine()); byte[] data = Hex.decode(input); eng.init(true, pubParameters); try { data = eng.processBlock(data, 0, data.length); } catch (Exception e) { fail("failed - exception " + e.toString(), e); } eng.init(false, privParameters); try { data = eng.processBlock(data, 0, data.length); } catch (Exception e) { fail("failed - exception " + e.toString(), e); } if (!input.equals(new String(Hex.encode(data)))) { fail("failed OAEP Test"); } } public void performTest() { RSAKeyParameters pubParameters = new RSAKeyParameters(false, mod, pubExp); RSAKeyParameters privParameters = new RSAPrivateCrtKeyParameters(mod, pubExp, privExp, p, q, pExp, qExp, crtCoef); byte[] data = Hex.decode(edgeInput); // // RAW // AsymmetricBlockCipher eng = new RSABlindedEngine(); eng.init(true, pubParameters); try { data = eng.processBlock(data, 0, data.length); } catch (Exception e) { fail("RSA: failed - exception " + e.toString(), e); } eng.init(false, privParameters); try { data = eng.processBlock(data, 0, data.length); } catch (Exception e) { fail("failed - exception " + e.toString(), e); } if (!edgeInput.equals(new String(Hex.encode(data)))) { fail("failed RAW edge Test"); } data = Hex.decode(input); eng.init(true, pubParameters); try { data = eng.processBlock(data, 0, data.length); } catch (Exception e) { fail("failed - exception " + e.toString(), e); } eng.init(false, privParameters); try { data = eng.processBlock(data, 0, data.length); } catch (Exception e) { fail("failed - exception " + e.toString(), e); } if (!input.equals(new String(Hex.encode(data)))) { fail("failed RAW Test"); } // // PKCS1 - public encrypt, private decrypt // eng = new PKCS1Encoding(eng); eng.init(true, pubParameters); if (eng.getOutputBlockSize() != ((PKCS1Encoding)eng).getUnderlyingCipher().getOutputBlockSize()) { fail("PKCS1 output block size incorrect"); } try { data = eng.processBlock(data, 0, data.length); } catch (Exception e) { fail("failed - exception " + e.toString(), e); } eng.init(false, privParameters); try { data = eng.processBlock(data, 0, data.length); } catch (Exception e) { fail("failed - exception " + e.toString(), e); } if (!input.equals(new String(Hex.encode(data)))) { fail("failed PKCS1 public/private Test"); } // // PKCS1 - private encrypt, public decrypt // eng = new PKCS1Encoding(((PKCS1Encoding)eng).getUnderlyingCipher()); eng.init(true, privParameters); try { data = eng.processBlock(data, 0, data.length); } catch (Exception e) { fail("failed - exception " + e.toString(), e); } eng.init(false, pubParameters); try { data = eng.processBlock(data, 0, data.length); } catch (Exception e) { fail("failed - exception " + e.toString(), e); } if (!input.equals(new String(Hex.encode(data)))) { fail("failed PKCS1 private/public Test"); } // // key generation test // RSAKeyPairGenerator pGen = new RSAKeyPairGenerator(); RSAKeyGenerationParameters genParam = new RSAKeyGenerationParameters( BigInteger.valueOf(0x11), new SecureRandom(), 768, 25); pGen.init(genParam); AsymmetricCipherKeyPair pair = pGen.generateKeyPair(); eng = new RSABlindedEngine(); if (((RSAKeyParameters)pair.getPublic()).getModulus().bitLength() < 768) { fail("failed key generation (768) length test"); } eng.init(true, pair.getPublic()); try { data = eng.processBlock(data, 0, data.length); } catch (Exception e) { fail("failed - exception " + e.toString(), e); } eng.init(false, pair.getPrivate()); try { data = eng.processBlock(data, 0, data.length); } catch (Exception e) { fail("failed - exception " + e.toString(), e); } if (!input.equals(new String(Hex.encode(data)))) { fail("failed key generation (768) Test"); } genParam = new RSAKeyGenerationParameters(BigInteger.valueOf(0x11), new SecureRandom(), 1024, 25); pGen.init(genParam); pair = pGen.generateKeyPair(); eng.init(true, pair.getPublic()); if (((RSAKeyParameters)pair.getPublic()).getModulus().bitLength() < 1024) { fail("failed key generation (1024) length test"); } try { data = eng.processBlock(data, 0, data.length); } catch (Exception e) { fail("failed - exception " + e.toString(), e); } eng.init(false, pair.getPrivate()); try { data = eng.processBlock(data, 0, data.length); } catch (Exception e) { fail("failed - exception " + e.toString(), e); } if (!input.equals(new String(Hex.encode(data)))) { fail("failed key generation (1024) test"); } testOAEP(pubParameters, privParameters); testStrictPKCS1Length(pubParameters, privParameters); testDudPKCS1Block(pubParameters, privParameters); testMissingDataPKCS1Block(pubParameters, privParameters); testTruncatedPKCS1Block(pubParameters, privParameters); testWrongPaddingPKCS1Block(pubParameters, privParameters); try { new RSABlindedEngine().processBlock(new byte[]{ 1 }, 0, 1); fail("failed initialisation check"); } catch (IllegalStateException e) { // expected } } public static void main( String[] args) { runTest(new RSABlindedTest()); } } bouncycastle-1.49.orig/test/src/org/bouncycastle/crypto/test/PKCS5Test.java0000644000175000017500000002435712125450741026324 0ustar ebourgebourgpackage org.bouncycastle.crypto.test; import java.io.ByteArrayInputStream; import org.bouncycastle.asn1.ASN1InputStream; import org.bouncycastle.asn1.ASN1OctetString; import org.bouncycastle.asn1.pkcs.EncryptedPrivateKeyInfo; import org.bouncycastle.asn1.pkcs.EncryptionScheme; import org.bouncycastle.asn1.pkcs.KeyDerivationFunc; import org.bouncycastle.asn1.pkcs.PBES2Parameters; import org.bouncycastle.asn1.pkcs.PBKDF2Params; import org.bouncycastle.asn1.pkcs.PKCSObjectIdentifiers; import org.bouncycastle.asn1.pkcs.RC2CBCParameter; import org.bouncycastle.crypto.BufferedBlockCipher; import org.bouncycastle.crypto.CipherParameters; import org.bouncycastle.crypto.PBEParametersGenerator; import org.bouncycastle.crypto.engines.DESEngine; import org.bouncycastle.crypto.engines.DESedeEngine; import org.bouncycastle.crypto.engines.RC2Engine; import org.bouncycastle.crypto.generators.PKCS5S2ParametersGenerator; import org.bouncycastle.crypto.modes.CBCBlockCipher; import org.bouncycastle.crypto.paddings.PaddedBufferedBlockCipher; import org.bouncycastle.crypto.params.KeyParameter; import org.bouncycastle.crypto.params.ParametersWithIV; import org.bouncycastle.util.encoders.Base64; import org.bouncycastle.util.encoders.Hex; import org.bouncycastle.util.test.SimpleTest; /** * A test class for PKCS5 PBES2 with PBKDF2 (PKCS5 v2.0) using * test vectors provider at * * RSA's PKCS5 Page *
    * The vectors are Base 64 encoded and encrypted using the password "password" * (without quotes). They should all yield the same PrivateKeyInfo object. */ public class PKCS5Test extends SimpleTest { /** * encrypted using des-cbc. */ static byte[] sample1 = Base64.decode( "MIIBozA9BgkqhkiG9w0BBQ0wMDAbBgkqhkiG9w0BBQwwDgQIfWBDXwLp4K4CAggA" + "MBEGBSsOAwIHBAiaCF/AvOgQ6QSCAWDWX4BdAzCRNSQSANSuNsT5X8mWYO27mr3Y" + "9c9LoBVXGNmYWKA77MI4967f7SmjNcgXj3xNE/jmnVz6hhsjS8E5VPT3kfyVkpdZ" + "0lr5e9Yk2m3JWpPU7++v5zBkZmC4V/MwV/XuIs6U+vykgzMgpxQg0oZKS9zgmiZo" + "f/4dOCL0UtCDnyOSvqT7mCVIcMDIEKu8QbVlgZYBop08l60EuEU3gARUo8WsYQmO" + "Dz/ldx0Z+znIT0SXVuOwc+RVItC5T/Qx+aijmmpt+9l14nmaGBrEkmuhmtdvU/4v" + "aptewGRgmjOfD6cqK+zs0O5NrrJ3P/6ZSxXj91CQgrThGfOv72bUncXEMNtc8pks" + "2jpHFjGMdKufnadAD7XuMgzkkaklEXZ4f5tU6heIIwr51g0GBEGF96gYPFnjnSQM" + "75JE02Clo+DfcfXpcybPTwwFg2jd6JTTOfkdf6OdSlA/1XNK43FA"); /** * encrypted using des-ede3-cbc. */ static byte[] sample2 = Base64.decode( "MIIBpjBABgkqhkiG9w0BBQ0wMzAbBgkqhkiG9w0BBQwwDgQIeFeOWl1jywYCAggA" + "MBQGCCqGSIb3DQMHBAjUJ5eGBhQGtQSCAWBrHrRgqO8UUMLcWzZEtpk1l3mjxiF/" + "koCMkHsFwowgyWhEbgIkTgbSViK54LVK8PskekcGNLph+rB6bGZ7pPbL5pbXASJ8" + "+MkQcG3FZdlS4Ek9tTJDApj3O1UubZGFG4uvTlJJFbF1BOJ3MkY3XQ9Gl1qwv7j5" + "6e103Da7Cq9+oIDKmznza78XXQYrUsPo8mJGjUxPskEYlzwvHjKubRnYm/K6RKhi" + "5f4zX4BQ/Dt3H812ZjRXrsjAJP0KrD/jyD/jCT7zNBVPH1izBds+RwizyQAHwfNJ" + "BFR78TH4cgzB619X47FDVOnT0LqQNVd0O3cSwnPrXE9XR3tPayE+iOB15llFSmi8" + "z0ByOXldEpkezCn92Umk++suzIVj1qfsK+bv2phZWJPbLEIWPDRHUbYf76q5ArAr" + "u4xtxT/hoK3krEs/IN3d70qjlUJ36SEw1UaZ82PWhakQbdtu39ZraMJB"); /** * encrypted using rc2-cbc. */ static byte[] sample3 = Base64.decode( "MIIBrjBIBgkqhkiG9w0BBQ0wOzAeBgkqhkiG9w0BBQwwEQQIrHyQPBZqWLUCAggA" + "AgEQMBkGCCqGSIb3DQMCMA0CAToECEhbh7YZKiPSBIIBYCT1zp6o5jpFlIkgwPop" + "7bW1+8ACr4exqzkeb3WflQ8cWJ4cURxzVdvxUnXeW1VJdaQZtjS/QHs5GhPTG/0f" + "wtvnaPfwrIJ3FeGaZfcg2CrYhalOFmEb4xrE4KyoEQmUN8tb/Cg94uzd16BOPw21" + "RDnE8bnPdIGY7TyL95kbkqH23mK53pi7h+xWIgduW+atIqDyyt55f7WMZcvDvlj6" + "VpN/V0h+qxBHL274WA4dj6GYgeyUFpi60HdGCK7By2TBy8h1ZvKGjmB9h8jZvkx1" + "MkbRumXxyFsowTZawyYvO8Um6lbfEDP9zIEUq0IV8RqH2MRyblsPNSikyYhxX/cz" + "tdDxRKhilySbSBg5Kr8OfcwKp9bpinN96nmG4xr3Tch1bnVvqJzOQ5+Vva2WwVvH" + "2JkWvYm5WaANg4Q6bRxu9vz7DuhbJjQdZbxFezIAgrJdSe92B00jO/0Kny1WjiVO" + "6DA="); static byte[] result = Hex.decode( "30820155020100300d06092a864886f70d01010105000482013f3082013b020100024100" + "debbfc2c09d61bada2a9462f24224e54cc6b3cc0755f15ce318ef57e79df17026b6a85cc" + "a12428027245045df2052a329a2f9ad3d17b78a10572ad9b22bf343b020301000102402d" + "90a96adcec472743527bc023153d8f0d6e96b40c8ed228276d467d843306429f8670559b" + "f376dd41857f6397c2fc8d95e0e53ed62de420b855430ee4a1b8a1022100ffcaf0838239" + "31e073ff534f06a5d415b3d414bc614a4544a3dff7ed271817eb022100deea30242117db" + "2d3b8837f58f1da530ff83cf9283680da33683ec4e583610f1022100e6026381adb0a683" + "f16a8f4c096b462979b9e4277cc89f3ed8a905b46fa9ff9f02210097c146d4d1d2b3dbaf" + "53a504ff51674c5c271800de84d003f4f10ac6ab36e38102202bfa141f10bda874e1017d" + "845e82767c1c38e82745daf421f0c8cd09d7652387"); private class PBETest extends SimpleTest { int id; BufferedBlockCipher cipher; byte[] sample; int keySize; PBETest( int id, BufferedBlockCipher cipher, byte[] sample, int keySize) { this.id = id; this.cipher = cipher; this.sample = sample; this.keySize = keySize; } public String getName() { return cipher.getUnderlyingCipher().getAlgorithmName() + " PKCS5S2 Test " + id; } public void performTest() { char[] password = { 'p', 'a', 's', 's', 'w', 'o', 'r', 'd' }; PBEParametersGenerator generator = new PKCS5S2ParametersGenerator(); ByteArrayInputStream bIn = new ByteArrayInputStream(sample); ASN1InputStream dIn = new ASN1InputStream(bIn); EncryptedPrivateKeyInfo info = null; try { info = EncryptedPrivateKeyInfo.getInstance(dIn.readObject()); } catch (Exception e) { fail("failed construction - exception " + e.toString(), e); } PBES2Parameters alg = PBES2Parameters.getInstance(info.getEncryptionAlgorithm().getParameters()); PBKDF2Params func = PBKDF2Params.getInstance(alg.getKeyDerivationFunc().getParameters()); EncryptionScheme scheme = alg.getEncryptionScheme(); if (func.getKeyLength() != null) { keySize = func.getKeyLength().intValue() * 8; } int iterationCount = func.getIterationCount().intValue(); byte[] salt = func.getSalt(); generator.init( PBEParametersGenerator.PKCS5PasswordToBytes(password), salt, iterationCount); CipherParameters param; if (scheme.getAlgorithm().equals(PKCSObjectIdentifiers.RC2_CBC)) { RC2CBCParameter rc2Params = RC2CBCParameter.getInstance(scheme.getParameters()); byte[] iv = rc2Params.getIV(); param = new ParametersWithIV(generator.generateDerivedParameters(keySize), iv); } else { byte[] iv = ASN1OctetString.getInstance(scheme.getParameters()).getOctets(); param = new ParametersWithIV(generator.generateDerivedParameters(keySize), iv); } cipher.init(false, param); byte[] data = info.getEncryptedData(); byte[] out = new byte[cipher.getOutputSize(data.length)]; int len = cipher.processBytes(data, 0, data.length, out, 0); try { len += cipher.doFinal(out, len); } catch (Exception e) { fail("failed doFinal - exception " + e.toString()); } if (result.length != len) { fail("failed length"); } for (int i = 0; i != len; i++) { if (out[i] != result[i]) { fail("failed comparison"); } } } } public String getName() { return "PKCS5S2"; } public void performTest() throws Exception { BufferedBlockCipher cipher = new PaddedBufferedBlockCipher(new CBCBlockCipher(new DESEngine())); SimpleTest test = new PBETest(0, cipher, sample1, 64); test.performTest(); cipher = new PaddedBufferedBlockCipher(new CBCBlockCipher(new DESedeEngine())); test = new PBETest(1, cipher, sample2, 192); test.performTest(); cipher = new PaddedBufferedBlockCipher(new CBCBlockCipher(new RC2Engine())); test = new PBETest(2, cipher, sample3, 0); test.performTest(); // // RFC 3211 tests // char[] password = { 'p', 'a', 's', 's', 'w', 'o', 'r', 'd' }; PBEParametersGenerator generator = new PKCS5S2ParametersGenerator(); byte[] salt = Hex.decode("1234567878563412"); generator.init( PBEParametersGenerator.PKCS5PasswordToBytes(password), salt, 5); if (!areEqual(((KeyParameter)generator.generateDerivedParameters(64)).getKey(), Hex.decode("d1daa78615f287e6"))) { fail("64 test failed"); } password = "All n-entities must communicate with other n-entities via n-1 entiteeheehees".toCharArray(); generator.init( PBEParametersGenerator.PKCS5PasswordToBytes(password), salt, 500); if (!areEqual(((KeyParameter)generator.generateDerivedParameters(192)).getKey(), Hex.decode("6a8970bf68c92caea84a8df28510858607126380cc47ab2d"))) { fail("192 test failed"); } generator.init(PBEParametersGenerator.PKCS5PasswordToBytes(password), salt, 60000); if (!areEqual(((KeyParameter)generator.generateDerivedParameters(192)).getKey(), Hex.decode("29aaef810c12ecd2236bbcfb55407f9852b5573dc1c095bb"))) { fail("192 (60000) test failed"); } } public static void main( String[] args) { runTest(new PKCS5Test()); } } bouncycastle-1.49.orig/test/src/org/bouncycastle/crypto/test/AllTests.java0000644000175000017500000000172311347660206026366 0ustar ebourgebourgpackage org.bouncycastle.crypto.test; import junit.framework.Test; import junit.framework.TestCase; import junit.framework.TestSuite; import org.bouncycastle.util.test.SimpleTestResult; public class AllTests extends TestCase { public void testCrypto() { org.bouncycastle.util.test.Test[] tests = RegressionTest.tests; for (int i = 0; i != tests.length; i++) { SimpleTestResult result = (SimpleTestResult)tests[i].perform(); if (!result.isSuccessful()) { fail(result.toString()); } } } public static void main (String[] args) { junit.textui.TestRunner.run(suite()); } public static Test suite() { TestSuite suite = new TestSuite("Lightweight Crypto Tests"); suite.addTestSuite(AllTests.class); suite.addTestSuite(GCMReorderTest.class); return suite; } } bouncycastle-1.49.orig/test/src/org/bouncycastle/crypto/test/NullTest.java0000644000175000017500000000331110525306762026401 0ustar ebourgebourgpackage org.bouncycastle.crypto.test; import org.bouncycastle.crypto.BlockCipher; import org.bouncycastle.crypto.DataLengthException; import org.bouncycastle.crypto.engines.NullEngine; import org.bouncycastle.crypto.params.KeyParameter; import org.bouncycastle.util.encoders.Hex; import org.bouncycastle.util.test.SimpleTest; public class NullTest extends CipherTest { static SimpleTest[] tests = { new BlockCipherVectorTest(0, new NullEngine(), new KeyParameter(Hex.decode("00")), "00", "00") }; NullTest() { super(tests, new NullEngine(), new KeyParameter(new byte[2])); } public String getName() { return "Null"; } public void performTest() throws Exception { super.performTest(); BlockCipher engine = new NullEngine(); engine.init(true, null); byte[] buf = new byte[1]; engine.processBlock(buf, 0, buf, 0); if (buf[0] != 0) { fail("NullCipher changed data!"); } byte[] shortBuf = new byte[0]; try { engine.processBlock(shortBuf, 0, buf, 0); fail("failed short input check"); } catch (DataLengthException e) { // expected } try { engine.processBlock(buf, 0, shortBuf, 0); fail("failed short output check"); } catch (DataLengthException e) { // expected } } public static void main( String[] args) { runTest(new NullTest()); } } bouncycastle-1.49.orig/test/src/org/bouncycastle/crypto/test/RC2WrapTest.java0000644000175000017500000000704110330633061026700 0ustar ebourgebourgpackage org.bouncycastle.crypto.test; import java.security.SecureRandom; import org.bouncycastle.crypto.CipherParameters; import org.bouncycastle.crypto.Wrapper; import org.bouncycastle.crypto.engines.RC2WrapEngine; import org.bouncycastle.crypto.params.ParametersWithIV; import org.bouncycastle.crypto.params.ParametersWithRandom; import org.bouncycastle.crypto.params.RC2Parameters; import org.bouncycastle.util.Arrays; import org.bouncycastle.util.encoders.Hex; import org.bouncycastle.util.test.SimpleTestResult; import org.bouncycastle.util.test.Test; import org.bouncycastle.util.test.TestResult; /** * RC2 wrap tester */ public class RC2WrapTest implements Test { private class RFCRandom extends SecureRandom { public void nextBytes( byte[] nextBytes) { System.arraycopy(Hex.decode("4845cce7fd1250"), 0, nextBytes, 0, nextBytes.length); } } private TestResult wrapTest( int id, CipherParameters paramsWrap, CipherParameters paramsUnwrap, byte[] in, byte[] out) { Wrapper wrapper = new RC2WrapEngine(); wrapper.init(true, paramsWrap); try { byte[] cText = wrapper.wrap(in, 0, in.length); if (!Arrays.areEqual(cText, out)) { return new SimpleTestResult(false, getName() + ": failed wrap test " + id + " expected " + new String(Hex.encode(out)) + " got " + new String(Hex.encode(cText))); } } catch (Exception e) { return new SimpleTestResult(false, getName() + ": failed wrap test exception " + e.toString(), e); } wrapper.init(false, paramsUnwrap); try { byte[] pText = wrapper.unwrap(out, 0, out.length); if (!Arrays.areEqual(pText, in)) { return new SimpleTestResult(false, getName() + ": failed unwrap test " + id + " expected " + new String(Hex.encode(in)) + " got " + new String(Hex.encode(pText))); } } catch (Exception e) { return new SimpleTestResult(false, getName() + ": failed unwrap test exception " + e.toString(), e); } return new SimpleTestResult(true, getName() + ": Okay"); } public TestResult perform() { byte[] kek1 = Hex.decode("fd04fd08060707fb0003fefffd02fe05"); byte[] iv1 = Hex.decode("c7d90059b29e97f7"); byte[] in1 = Hex.decode("b70a25fbc9d86a86050ce0d711ead4d9"); byte[] out1 = Hex.decode("70e699fb5701f7833330fb71e87c85a420bdc99af05d22af5a0e48d35f3138986cbaafb4b28d4f35"); // // note the RFC 3217 test specifies a key to be used with an effective key size of // 40 bits which is why it is done here - in practice nothing less than 128 bits should be used. // CipherParameters paramWrap = new ParametersWithRandom(new ParametersWithIV(new RC2Parameters(kek1, 40), iv1), new RFCRandom()); CipherParameters paramUnwrap = new RC2Parameters(kek1, 40); TestResult result = wrapTest(1, paramWrap, paramUnwrap, in1, out1); if (!result.isSuccessful()) { return result; } return new SimpleTestResult(true, getName() + ": Okay"); } public String getName() { return "RC2Wrap"; } public static void main( String[] args) { RC2WrapTest test = new RC2WrapTest(); TestResult result = test.perform(); System.out.println(result); } } bouncycastle-1.49.orig/test/src/org/bouncycastle/crypto/test/DigestRandomNumberTest.java0000644000175000017500000001256411066122663031227 0ustar ebourgebourgpackage org.bouncycastle.crypto.test; import org.bouncycastle.util.test.SimpleTest; import org.bouncycastle.util.encoders.Hex; import org.bouncycastle.util.Arrays; import org.bouncycastle.crypto.prng.DigestRandomGenerator; import org.bouncycastle.crypto.digests.SHA1Digest; import org.bouncycastle.crypto.digests.SHA256Digest; import org.bouncycastle.crypto.Digest; public class DigestRandomNumberTest extends SimpleTest { private static final byte[] ZERO_SEED = { 0, 0, 0, 0, 0, 0, 0, 0 }; private static final byte[] TEST_SEED = Hex.decode("81dcfafc885914057876"); private static final byte[] expected0SHA1 = Hex.decode("95bca677b3d4ff793213c00892d2356ec729ee02"); private static final byte[] noCycle0SHA1 = Hex.decode("d57ccd0eb12c3938d59226412bc1268037b6b846"); private static final byte[] expected0SHA256 = Hex.decode("587e2dfd597d086e47ddcd343eac983a5c913bef8c6a1a560a5c1bc3a74b0991"); private static final byte[] noCycle0SHA256 = Hex.decode("e5776c4483486ba7be081f4e1b9dafbab25c8fae290fd5474c1ceda2c16f9509"); private static final byte[] expected100SHA1 = Hex.decode("b9d924092546e0876cafd4937d7364ebf9efa4be"); private static final byte[] expected100SHA256 = Hex.decode("fbc4aa54b948b99de104c44563a552899d718bb75d1941cc62a2444b0506abaf"); private static final byte[] expectedTestSHA1 = Hex.decode("e9ecef9f5306daf1ac51a89a211a64cb24415649"); private static final byte[] expectedTestSHA256 = Hex.decode("bdab3ca831b472a2fa09bd1bade541ef16c96640a91fcec553679a136061de98"); private static final byte[] sha1Xors = Hex.decode("7edcc1216934f3891b03ffa65821611a3e2b1f79"); private static final byte[] sha256Xors = Hex.decode("5ec48189cc0aa71e79c707bc3c33ffd47bbba368a83d6cfebf3cd3969d7f3eed"); public String getName() { return "DigestRandomNumber"; } private void doExpectedTest(Digest digest, int seed, byte[] expected) { doExpectedTest(digest, seed, expected, null); } private void doExpectedTest(Digest digest, int seed, byte[] expected, byte[] noCycle) { DigestRandomGenerator rGen = new DigestRandomGenerator(digest); byte[] output = new byte[digest.getDigestSize()]; rGen.addSeedMaterial(seed); for (int i = 0; i != 1024; i++) { rGen.nextBytes(output); } if (noCycle != null) { if (Arrays.areEqual(noCycle, output)) { fail("seed not being cycled!"); } } if (!Arrays.areEqual(expected, output)) { fail("expected output doesn't match"); } } private void doExpectedTest(Digest digest, byte[] seed, byte[] expected) { DigestRandomGenerator rGen = new DigestRandomGenerator(digest); byte[] output = new byte[digest.getDigestSize()]; rGen.addSeedMaterial(seed); for (int i = 0; i != 1024; i++) { rGen.nextBytes(output); } if (!Arrays.areEqual(expected, output)) { fail("expected output doesn't match"); } } private void doCountTest(Digest digest, byte[] seed, byte[] expectedXors) { DigestRandomGenerator rGen = new DigestRandomGenerator(digest); byte[] output = new byte[digest.getDigestSize()]; int[] averages = new int[digest.getDigestSize()]; byte[] ands = new byte[digest.getDigestSize()]; byte[] xors = new byte[digest.getDigestSize()]; byte[] ors = new byte[digest.getDigestSize()]; rGen.addSeedMaterial(seed); for (int i = 0; i != 1000000; i++) { rGen.nextBytes(output); for (int j = 0; j != output.length; j++) { averages[j] += output[j] & 0xff; ands[j] &= output[j]; xors[j] ^= output[j]; ors[j] |= output[j]; } } for (int i = 0; i != output.length; i++) { if ((averages[i] / 1000000) != 127) { fail("average test failed for " + digest.getAlgorithmName()); } if (ands[i] != 0) { fail("and test failed for " + digest.getAlgorithmName()); } if ((ors[i] & 0xff) != 0xff) { fail("or test failed for " + digest.getAlgorithmName()); } if (xors[i] != expectedXors[i]) { fail("xor test failed for " + digest.getAlgorithmName()); } } } public void performTest() throws Exception { doExpectedTest(new SHA1Digest(), 0, expected0SHA1, noCycle0SHA1); doExpectedTest(new SHA256Digest(), 0, expected0SHA256, noCycle0SHA256); doExpectedTest(new SHA1Digest(), 100, expected100SHA1); doExpectedTest(new SHA256Digest(), 100, expected100SHA256); doExpectedTest(new SHA1Digest(), ZERO_SEED, expected0SHA1); doExpectedTest(new SHA256Digest(), ZERO_SEED, expected0SHA256); doExpectedTest(new SHA1Digest(), TEST_SEED, expectedTestSHA1); doExpectedTest(new SHA256Digest(), TEST_SEED, expectedTestSHA256); doCountTest(new SHA1Digest(), TEST_SEED, sha1Xors); doCountTest(new SHA256Digest(), TEST_SEED, sha256Xors); } public static void main( String[] args) { runTest(new DigestRandomNumberTest()); } } bouncycastle-1.49.orig/test/src/org/bouncycastle/crypto/test/SRP6Test.java0000644000175000017500000002220611272215742026222 0ustar ebourgebourgpackage org.bouncycastle.crypto.test; import java.math.BigInteger; import java.security.SecureRandom; import org.bouncycastle.crypto.CryptoException; import org.bouncycastle.crypto.agreement.srp.SRP6Client; import org.bouncycastle.crypto.agreement.srp.SRP6Server; import org.bouncycastle.crypto.agreement.srp.SRP6Util; import org.bouncycastle.crypto.agreement.srp.SRP6VerifierGenerator; import org.bouncycastle.crypto.digests.SHA1Digest; import org.bouncycastle.crypto.digests.SHA256Digest; import org.bouncycastle.crypto.generators.DHParametersGenerator; import org.bouncycastle.crypto.params.DHParameters; import org.bouncycastle.util.encoders.Hex; import org.bouncycastle.util.test.SimpleTest; public class SRP6Test extends SimpleTest { private static final BigInteger ZERO = BigInteger.valueOf(0); private static BigInteger fromHex(String hex) { return new BigInteger(1, Hex.decode(hex)); } // 1024 bit example prime from RFC5054 and corresponding generator private static final BigInteger N_1024 = fromHex("EEAF0AB9ADB38DD69C33F80AFA8FC5E86072618775FF3C0B9EA2314C" + "9C256576D674DF7496EA81D3383B4813D692C6E0E0D5D8E250B98BE4" + "8E495C1D6089DAD15DC7D7B46154D6B6CE8EF4AD69B15D4982559B29" + "7BCF1885C529F566660E57EC68EDBC3C05726CC02FD4CBF4976EAA9A" + "FD5138FE8376435B9FC61D2FC0EB06E3"); private static final BigInteger g_1024 = BigInteger.valueOf(2); private final SecureRandom random = new SecureRandom(); public String getName() { return "SRP6"; } public void performTest() throws Exception { rfc5054AppendixBTestVectors(); testMutualVerification(N_1024, g_1024); testClientCatchesBadB(N_1024, g_1024); testServerCatchesBadA(N_1024, g_1024); testWithRandomParams(256); testWithRandomParams(384); testWithRandomParams(512); } private void rfc5054AppendixBTestVectors() throws Exception { byte[] I = "alice".getBytes("UTF8"); byte[] P = "password123".getBytes("UTF8"); byte[] s = Hex.decode("BEB25379D1A8581EB5A727673A2441EE"); BigInteger N = N_1024; BigInteger g = g_1024; BigInteger a = fromHex("60975527035CF2AD1989806F0407210BC81EDC04E2762A56AFD529DDDA2D4393"); BigInteger b = fromHex("E487CB59D31AC550471E81F00F6928E01DDA08E974A004F49E61F5D105284D20"); BigInteger expect_k = fromHex("7556AA045AEF2CDD07ABAF0F665C3E818913186F"); BigInteger expect_x = fromHex("94B7555AABE9127CC58CCF4993DB6CF84D16C124"); BigInteger expect_v = fromHex("7E273DE8696FFC4F4E337D05B4B375BEB0DDE1569E8FA00A9886D812" + "9BADA1F1822223CA1A605B530E379BA4729FDC59F105B4787E5186F5" + "C671085A1447B52A48CF1970B4FB6F8400BBF4CEBFBB168152E08AB5" + "EA53D15C1AFF87B2B9DA6E04E058AD51CC72BFC9033B564E26480D78" + "E955A5E29E7AB245DB2BE315E2099AFB"); BigInteger expect_A = fromHex("61D5E490F6F1B79547B0704C436F523DD0E560F0C64115BB72557EC4" + "4352E8903211C04692272D8B2D1A5358A2CF1B6E0BFCF99F921530EC" + "8E39356179EAE45E42BA92AEACED825171E1E8B9AF6D9C03E1327F44" + "BE087EF06530E69F66615261EEF54073CA11CF5858F0EDFDFE15EFEA" + "B349EF5D76988A3672FAC47B0769447B"); BigInteger expect_B = fromHex("BD0C61512C692C0CB6D041FA01BB152D4916A1E77AF46AE105393011" + "BAF38964DC46A0670DD125B95A981652236F99D9B681CBF87837EC99" + "6C6DA04453728610D0C6DDB58B318885D7D82C7F8DEB75CE7BD4FBAA" + "37089E6F9C6059F388838E7A00030B331EB76840910440B1B27AAEAE" + "EB4012B7D7665238A8E3FB004B117B58"); BigInteger expect_u = fromHex("CE38B9593487DA98554ED47D70A7AE5F462EF019"); BigInteger expect_S = fromHex("B0DC82BABCF30674AE450C0287745E7990A3381F63B387AAF271A10D" + "233861E359B48220F7C4693C9AE12B0A6F67809F0876E2D013800D6C" + "41BB59B6D5979B5C00A172B4A2A5903A0BDCAF8A709585EB2AFAFA8F" + "3499B200210DCC1F10EB33943CD67FC88A2F39A4BE5BEC4EC0A3212D" + "C346D7E474B29EDE8A469FFECA686E5A"); BigInteger k = SRP6Util.calculateK(new SHA1Digest(), N, g); if (!k.equals(expect_k)) { fail("wrong value of 'k'"); } BigInteger x = SRP6Util.calculateX(new SHA1Digest(), N, s, I, P); if (!x.equals(expect_x)) { fail("wrong value of 'x'"); } SRP6VerifierGenerator gen = new SRP6VerifierGenerator(); gen.init(N, g, new SHA1Digest()); BigInteger v = gen.generateVerifier(s, I, P); if (!v.equals(expect_v)) { fail("wrong value of 'v'"); } final BigInteger aVal = a; SRP6Client client = new SRP6Client() { protected BigInteger selectPrivateValue() { return aVal; } }; client.init(N, g, new SHA1Digest(), random); BigInteger A = client.generateClientCredentials(s, I, P); if (!A.equals(expect_A)) { fail("wrong value of 'A'"); } final BigInteger bVal = b; SRP6Server server = new SRP6Server() { protected BigInteger selectPrivateValue() { return bVal; } }; server.init(N, g, v, new SHA1Digest(), random); BigInteger B = server.generateServerCredentials(); if (!B.equals(expect_B)) { fail("wrong value of 'B'"); } BigInteger u = SRP6Util.calculateU(new SHA1Digest(), N, A, B); if (!u.equals(expect_u)) { fail("wrong value of 'u'"); } BigInteger clientS = client.calculateSecret(B); if (!clientS.equals(expect_S)) { fail("wrong value of 'S' (client)"); } BigInteger serverS = server.calculateSecret(A); if (!serverS.equals(expect_S)) { fail("wrong value of 'S' (server)"); } } private void testWithRandomParams(int bits) throws CryptoException { DHParametersGenerator paramGen = new DHParametersGenerator(); paramGen.init(bits, 25, random); DHParameters parameters = paramGen.generateParameters(); BigInteger g = parameters.getG(); BigInteger p = parameters.getP(); testMutualVerification(p, g); } private void testMutualVerification(BigInteger N, BigInteger g) throws CryptoException { byte[] I = "username".getBytes(); byte[] P = "password".getBytes(); byte[] s = new byte[16]; random.nextBytes(s); SRP6VerifierGenerator gen = new SRP6VerifierGenerator(); gen.init(N, g, new SHA256Digest()); BigInteger v = gen.generateVerifier(s, I, P); SRP6Client client = new SRP6Client(); client.init(N, g, new SHA256Digest(), random); SRP6Server server = new SRP6Server(); server.init(N, g, v, new SHA256Digest(), random); BigInteger A = client.generateClientCredentials(s, I, P); BigInteger B = server.generateServerCredentials(); BigInteger clientS = client.calculateSecret(B); BigInteger serverS = server.calculateSecret(A); if (!clientS.equals(serverS)) { fail("SRP agreement failed - client/server calculated different secrets"); } } private void testClientCatchesBadB(BigInteger N, BigInteger g) { byte[] I = "username".getBytes(); byte[] P = "password".getBytes(); byte[] s = new byte[16]; random.nextBytes(s); SRP6Client client = new SRP6Client(); client.init(N, g, new SHA256Digest(), random); client.generateClientCredentials(s, I, P); try { client.calculateSecret(ZERO); fail("Client failed to detect invalid value for 'B'"); } catch (CryptoException e) { // Expected } try { client.calculateSecret(N); fail("Client failed to detect invalid value for 'B'"); } catch (CryptoException e) { // Expected } } private void testServerCatchesBadA(BigInteger N, BigInteger g) { byte[] I = "username".getBytes(); byte[] P = "password".getBytes(); byte[] s = new byte[16]; random.nextBytes(s); SRP6VerifierGenerator gen = new SRP6VerifierGenerator(); gen.init(N, g, new SHA256Digest()); BigInteger v = gen.generateVerifier(s, I, P); SRP6Server server = new SRP6Server(); server.init(N, g, v, new SHA256Digest(), random); server.generateServerCredentials(); try { server.calculateSecret(ZERO); fail("Client failed to detect invalid value for 'A'"); } catch (CryptoException e) { // Expected } try { server.calculateSecret(N); fail("Client failed to detect invalid value for 'A'"); } catch (CryptoException e) { // Expected } } public static void main(String[] args) { runTest(new SRP6Test()); } } bouncycastle-1.49.orig/test/src/org/bouncycastle/crypto/test/ECGOST3410Test.java0000644000175000017500000002765210422362047026773 0ustar ebourgebourgpackage org.bouncycastle.crypto.test; import org.bouncycastle.util.encoders.Hex; import org.bouncycastle.util.test.FixedSecureRandom; import org.bouncycastle.util.test.SimpleTest; import org.bouncycastle.math.ec.ECCurve; import org.bouncycastle.math.ec.ECPoint; import org.bouncycastle.math.ec.ECFieldElement; import org.bouncycastle.crypto.params.*; import org.bouncycastle.crypto.signers.ECGOST3410Signer; import org.bouncycastle.crypto.generators.ECKeyPairGenerator; import org.bouncycastle.crypto.AsymmetricCipherKeyPair; import org.bouncycastle.crypto.digests.GOST3411Digest; import java.math.BigInteger; import java.security.SecureRandom; /** * ECGOST3410 tests are taken from GOST R 34.10-2001. */ public class ECGOST3410Test extends SimpleTest { byte[] hashmessage = Hex.decode("3042453136414534424341374533364339313734453431443642453241453435"); /** * ECGOST3410 over the field Fp
    */ BigInteger r = new BigInteger("29700980915817952874371204983938256990422752107994319651632687982059210933395"); BigInteger s = new BigInteger("574973400270084654178925310019147038455227042649098563933718999175515839552"); byte[] kData = new BigInteger("53854137677348463731403841147996619241504003434302020712960838528893196233395").toByteArray(); SecureRandom k = new FixedSecureRandom(kData); private void ecGOST3410_TEST() { BigInteger mod_p = new BigInteger("57896044618658097711785492504343953926634992332820282019728792003956564821041"); //p ECCurve.Fp curve = new ECCurve.Fp( mod_p, // p new BigInteger("7"), // a new BigInteger("43308876546767276905765904595650931995942111794451039583252968842033849580414")); // b ECDomainParameters params = new ECDomainParameters( curve, new ECPoint.Fp(curve, new ECFieldElement.Fp(mod_p,new BigInteger("2")), // x new ECFieldElement.Fp(mod_p,new BigInteger("4018974056539037503335449422937059775635739389905545080690979365213431566280"))), // y new BigInteger("57896044618658097711785492504343953927082934583725450622380973592137631069619")); // q ECPrivateKeyParameters priKey = new ECPrivateKeyParameters( new BigInteger("55441196065363246126355624130324183196576709222340016572108097750006097525544"), // d params); ParametersWithRandom param = new ParametersWithRandom(priKey, k); ECGOST3410Signer ecgost3410 = new ECGOST3410Signer(); ecgost3410.init(true, param); byte[] mVal = new BigInteger("20798893674476452017134061561508270130637142515379653289952617252661468872421").toByteArray(); byte[] message = new byte[mVal.length]; for (int i = 0; i != mVal.length; i++) { message[i] = mVal[mVal.length - 1 - i]; } BigInteger[] sig = ecgost3410.generateSignature(message); if (!r.equals(sig[0])) { fail("r component wrong.", r, sig[0]); } if (!s.equals(sig[1])) { fail("s component wrong.", s, sig[1]); } // Verify the signature ECPublicKeyParameters pubKey = new ECPublicKeyParameters( new ECPoint.Fp(curve, new ECFieldElement.Fp(mod_p, new BigInteger("57520216126176808443631405023338071176630104906313632182896741342206604859403")), // x new ECFieldElement.Fp(mod_p, new BigInteger("17614944419213781543809391949654080031942662045363639260709847859438286763994"))), // y params); ecgost3410.init(false, pubKey); if (!ecgost3410.verifySignature(message, sig[0], sig[1])) { fail("verification fails"); } } /** * Test Sign & Verify with test parameters * see: http://www.ietf.org/internet-drafts/draft-popov-cryptopro-cpalgs-01.txt * gostR3410-2001-TestParamSet P.46 */ private void ecGOST3410_TestParam() { SecureRandom random = new SecureRandom(); BigInteger mod_p = new BigInteger("57896044618658097711785492504343953926634992332820282019728792003956564821041"); //p ECCurve.Fp curve = new ECCurve.Fp( mod_p, // p new BigInteger("7"), // a new BigInteger("43308876546767276905765904595650931995942111794451039583252968842033849580414")); // b ECDomainParameters params = new ECDomainParameters( curve, new ECPoint.Fp(curve, new ECFieldElement.Fp(mod_p,new BigInteger("2")), // x new ECFieldElement.Fp(mod_p,new BigInteger("4018974056539037503335449422937059775635739389905545080690979365213431566280"))), // y new BigInteger("57896044618658097711785492504343953927082934583725450622380973592137631069619")); // q ECKeyPairGenerator pGen = new ECKeyPairGenerator(); ECKeyGenerationParameters genParam = new ECKeyGenerationParameters( params, random); pGen.init(genParam); AsymmetricCipherKeyPair pair = pGen.generateKeyPair(); ParametersWithRandom param = new ParametersWithRandom(pair.getPrivate(), random); ECGOST3410Signer ecgost3410 = new ECGOST3410Signer(); ecgost3410.init(true, param); //get hash message using the digest GOST3411. byte[] message = "Message for sign".getBytes(); GOST3411Digest gost3411 = new GOST3411Digest(); gost3411.update(message, 0, message.length); byte[] hashmessage = new byte[gost3411.getDigestSize()]; gost3411.doFinal(hashmessage, 0); BigInteger[] sig = ecgost3410.generateSignature(hashmessage); ecgost3410.init(false, pair.getPublic()); if (!ecgost3410.verifySignature(hashmessage, sig[0], sig[1])) { fail("signature fails"); } } /** * Test Sign & Verify with A parameters * see: http://www.ietf.org/internet-drafts/draft-popov-cryptopro-cpalgs-01.txt * gostR3410-2001-CryptoPro-A-ParamSet P.47 */ public void ecGOST3410_AParam() { SecureRandom random = new SecureRandom(); BigInteger mod_p = new BigInteger("115792089237316195423570985008687907853269984665640564039457584007913129639319"); //p ECCurve.Fp curve = new ECCurve.Fp( mod_p, // p new BigInteger("115792089237316195423570985008687907853269984665640564039457584007913129639316"), // a new BigInteger("166")); // b ECDomainParameters params = new ECDomainParameters( curve, new ECPoint.Fp(curve, new ECFieldElement.Fp(mod_p,new BigInteger("1")), // x new ECFieldElement.Fp(mod_p,new BigInteger("64033881142927202683649881450433473985931760268884941288852745803908878638612"))), // y new BigInteger("115792089237316195423570985008687907853073762908499243225378155805079068850323")); // q ECKeyPairGenerator pGen = new ECKeyPairGenerator(); ECKeyGenerationParameters genParam = new ECKeyGenerationParameters( params, random); pGen.init(genParam); AsymmetricCipherKeyPair pair = pGen.generateKeyPair(); ParametersWithRandom param = new ParametersWithRandom(pair.getPrivate(), random); ECGOST3410Signer ecgost3410 = new ECGOST3410Signer(); ecgost3410.init(true, param); BigInteger[] sig = ecgost3410.generateSignature(hashmessage); ecgost3410.init(false, pair.getPublic()); if (!ecgost3410.verifySignature(hashmessage, sig[0], sig[1])) { fail("signature fails"); } } /** * Test Sign & Verify with B parameters * see: http://www.ietf.org/internet-drafts/draft-popov-cryptopro-cpalgs-01.txt * gostR3410-2001-CryptoPro-B-ParamSet P.47-48 */ private void ecGOST3410_BParam() { SecureRandom random = new SecureRandom(); BigInteger mod_p = new BigInteger("57896044618658097711785492504343953926634992332820282019728792003956564823193"); //p ECCurve.Fp curve = new ECCurve.Fp( mod_p, // p new BigInteger("57896044618658097711785492504343953926634992332820282019728792003956564823190"), // a new BigInteger("28091019353058090096996979000309560759124368558014865957655842872397301267595")); // b ECDomainParameters params = new ECDomainParameters( curve, new ECPoint.Fp(curve, new ECFieldElement.Fp(mod_p,new BigInteger("1")), // x new ECFieldElement.Fp(mod_p,new BigInteger("28792665814854611296992347458380284135028636778229113005756334730996303888124"))), // y new BigInteger("57896044618658097711785492504343953927102133160255826820068844496087732066703")); // q ECKeyPairGenerator pGen = new ECKeyPairGenerator(); ECKeyGenerationParameters genParam = new ECKeyGenerationParameters( params, random); pGen.init(genParam); AsymmetricCipherKeyPair pair = pGen.generateKeyPair(); ParametersWithRandom param = new ParametersWithRandom(pair.getPrivate(), random); ECGOST3410Signer ecgost3410 = new ECGOST3410Signer(); ecgost3410.init(true, param); BigInteger[] sig = ecgost3410.generateSignature(hashmessage); ecgost3410.init(false, pair.getPublic()); if (!ecgost3410.verifySignature(hashmessage, sig[0], sig[1])) { fail("signature fails"); } } /** * Test Sign & Verify with C parameters * see: http://www.ietf.org/internet-drafts/draft-popov-cryptopro-cpalgs-01.txt * gostR3410-2001-CryptoPro-C-ParamSet P.48 */ private void ecGOST3410_CParam() { SecureRandom random = new SecureRandom(); BigInteger mod_p = new BigInteger("70390085352083305199547718019018437841079516630045180471284346843705633502619"); //p ECCurve.Fp curve = new ECCurve.Fp( mod_p, // p new BigInteger("70390085352083305199547718019018437841079516630045180471284346843705633502616"), // a new BigInteger("32858")); // b ECDomainParameters params = new ECDomainParameters( curve, new ECPoint.Fp(curve, new ECFieldElement.Fp(mod_p,new BigInteger("0")), // x new ECFieldElement.Fp(mod_p,new BigInteger("29818893917731240733471273240314769927240550812383695689146495261604565990247"))), // y new BigInteger("70390085352083305199547718019018437840920882647164081035322601458352298396601")); // q ECKeyPairGenerator pGen = new ECKeyPairGenerator(); ECKeyGenerationParameters genParam = new ECKeyGenerationParameters( params, random); pGen.init(genParam); AsymmetricCipherKeyPair pair = pGen.generateKeyPair(); ParametersWithRandom param = new ParametersWithRandom(pair.getPrivate(), random); ECGOST3410Signer ecgost3410 = new ECGOST3410Signer(); ecgost3410.init(true, param); BigInteger[] sig = ecgost3410.generateSignature(hashmessage); ecgost3410.init(false, pair.getPublic()); if (!ecgost3410.verifySignature(hashmessage, sig[0], sig[1])) { fail("signature fails"); } } public String getName() { return "ECGOST3410"; } public void performTest() { ecGOST3410_TEST(); ecGOST3410_TestParam(); ecGOST3410_AParam(); ecGOST3410_BParam(); ecGOST3410_CParam(); } public static void main( String[] args) { runTest(new ECGOST3410Test()); } } bouncycastle-1.49.orig/test/src/org/bouncycastle/crypto/test/ECTest.java0000644000175000017500000011124500000001400025724 0ustar ebourgebourgpackage org.bouncycastle.crypto.test; import java.math.BigInteger; import java.security.SecureRandom; import org.bouncycastle.asn1.nist.NISTNamedCurves; import org.bouncycastle.asn1.sec.SECNamedCurves; import org.bouncycastle.asn1.x9.X9ECParameters; import org.bouncycastle.crypto.AsymmetricCipherKeyPair; import org.bouncycastle.crypto.BasicAgreement; import org.bouncycastle.crypto.agreement.ECDHBasicAgreement; import org.bouncycastle.crypto.agreement.ECDHCBasicAgreement; import org.bouncycastle.crypto.agreement.ECMQVBasicAgreement; import org.bouncycastle.crypto.generators.ECKeyPairGenerator; import org.bouncycastle.crypto.params.ECDomainParameters; import org.bouncycastle.crypto.params.ECKeyGenerationParameters; import org.bouncycastle.crypto.params.ECPrivateKeyParameters; import org.bouncycastle.crypto.params.ECPublicKeyParameters; import org.bouncycastle.crypto.params.MQVPrivateParameters; import org.bouncycastle.crypto.params.MQVPublicParameters; import org.bouncycastle.crypto.params.ParametersWithRandom; import org.bouncycastle.crypto.signers.ECDSASigner; import org.bouncycastle.math.ec.ECCurve; import org.bouncycastle.math.ec.ECPoint; import org.bouncycastle.util.BigIntegers; import org.bouncycastle.util.encoders.Hex; import org.bouncycastle.util.test.FixedSecureRandom; import org.bouncycastle.util.test.SimpleTest; /** * ECDSA tests are taken from X9.62. */ public class ECTest extends SimpleTest { /** * X9.62 - 1998,
    * J.3.1, Page 152, ECDSA over the field Fp
    * an example with 192 bit prime */ private void testECDSA192bitPrime() { BigInteger r = new BigInteger("3342403536405981729393488334694600415596881826869351677613"); BigInteger s = new BigInteger("5735822328888155254683894997897571951568553642892029982342"); byte[] kData = BigIntegers.asUnsignedByteArray(new BigInteger("6140507067065001063065065565667405560006161556565665656654")); SecureRandom k = new FixedSecureRandom(kData); ECCurve.Fp curve = new ECCurve.Fp( new BigInteger("6277101735386680763835789423207666416083908700390324961279"), // q new BigInteger("fffffffffffffffffffffffffffffffefffffffffffffffc", 16), // a new BigInteger("64210519e59c80e70fa7e9ab72243049feb8deecc146b9b1", 16)); // b ECDomainParameters params = new ECDomainParameters( curve, curve.decodePoint(Hex.decode("03188da80eb03090f67cbf20eb43a18800f4ff0afd82ff1012")), // G new BigInteger("6277101735386680763835789423176059013767194773182842284081")); // n ECPrivateKeyParameters priKey = new ECPrivateKeyParameters( new BigInteger("651056770906015076056810763456358567190100156695615665659"), // d params); ParametersWithRandom param = new ParametersWithRandom(priKey, k); ECDSASigner ecdsa = new ECDSASigner(); ecdsa.init(true, param); byte[] message = new BigInteger("968236873715988614170569073515315707566766479517").toByteArray(); BigInteger[] sig = ecdsa.generateSignature(message); if (!r.equals(sig[0])) { fail("r component wrong." + System.getProperty("line.separator") + " expecting: " + r + System.getProperty("line.separator") + " got : " + sig[0]); } if (!s.equals(sig[1])) { fail("s component wrong." + System.getProperty("line.separator") + " expecting: " + s + System.getProperty("line.separator") + " got : " + sig[1]); } // Verify the signature ECPublicKeyParameters pubKey = new ECPublicKeyParameters( curve.decodePoint(Hex.decode("0262b12d60690cdcf330babab6e69763b471f994dd702d16a5")), // Q params); ecdsa.init(false, pubKey); if (!ecdsa.verifySignature(message, sig[0], sig[1])) { fail("verification fails"); } } private void decodeTest() { ECCurve.Fp curve = new ECCurve.Fp( new BigInteger("6277101735386680763835789423207666416083908700390324961279"), // q new BigInteger("fffffffffffffffffffffffffffffffefffffffffffffffc", 16), // a new BigInteger("64210519e59c80e70fa7e9ab72243049feb8deecc146b9b1", 16)); // b ECPoint p = curve.decodePoint(Hex.decode("03188da80eb03090f67cbf20eb43a18800f4ff0afd82ff1012")); if (!p.getX().toBigInteger().equals(new BigInteger("188da80eb03090f67cbf20eb43a18800f4ff0afd82ff1012", 16))) { fail("x uncompressed incorrectly"); } if (!p.getY().toBigInteger().equals(new BigInteger("7192b95ffc8da78631011ed6b24cdd573f977a11e794811", 16))) { fail("y uncompressed incorrectly"); } byte[] encoding = p.getEncoded(); if (!areEqual(encoding, Hex.decode("03188da80eb03090f67cbf20eb43a18800f4ff0afd82ff1012"))) { fail("point compressed incorrectly"); } } /** * X9.62 - 1998,
    * J.3.2, Page 155, ECDSA over the field Fp
    * an example with 239 bit prime */ private void testECDSA239bitPrime() { BigInteger r = new BigInteger("308636143175167811492622547300668018854959378758531778147462058306432176"); BigInteger s = new BigInteger("323813553209797357708078776831250505931891051755007842781978505179448783"); byte[] kData = BigIntegers.asUnsignedByteArray(new BigInteger("700000017569056646655505781757157107570501575775705779575555657156756655")); SecureRandom k = new FixedSecureRandom(true, kData); ECCurve.Fp curve = new ECCurve.Fp( new BigInteger("883423532389192164791648750360308885314476597252960362792450860609699839"), // q new BigInteger("7fffffffffffffffffffffff7fffffffffff8000000000007ffffffffffc", 16), // a new BigInteger("6b016c3bdcf18941d0d654921475ca71a9db2fb27d1d37796185c2942c0a", 16)); // b ECDomainParameters params = new ECDomainParameters( curve, curve.decodePoint(Hex.decode("020ffa963cdca8816ccc33b8642bedf905c3d358573d3f27fbbd3b3cb9aaaf")), // G new BigInteger("883423532389192164791648750360308884807550341691627752275345424702807307")); // n ECPrivateKeyParameters priKey = new ECPrivateKeyParameters( new BigInteger("876300101507107567501066130761671078357010671067781776716671676178726717"), // d params); ECDSASigner ecdsa = new ECDSASigner(); ParametersWithRandom param = new ParametersWithRandom(priKey, k); ecdsa.init(true, param); byte[] message = new BigInteger("968236873715988614170569073515315707566766479517").toByteArray(); BigInteger[] sig = ecdsa.generateSignature(message); if (!r.equals(sig[0])) { fail("r component wrong." + System.getProperty("line.separator") + " expecting: " + r + System.getProperty("line.separator") + " got : " + sig[0]); } if (!s.equals(sig[1])) { fail("s component wrong." + System.getProperty("line.separator") + " expecting: " + s + System.getProperty("line.separator") + " got : " + sig[1]); } // Verify the signature ECPublicKeyParameters pubKey = new ECPublicKeyParameters( curve.decodePoint(Hex.decode("025b6dc53bc61a2548ffb0f671472de6c9521a9d2d2534e65abfcbd5fe0c70")), // Q params); ecdsa.init(false, pubKey); if (!ecdsa.verifySignature(message, sig[0], sig[1])) { fail("signature fails"); } } /** * X9.62 - 1998,
    * J.2.1, Page 100, ECDSA over the field F2m
    * an example with 191 bit binary field */ private void testECDSA191bitBinary() { BigInteger r = new BigInteger("87194383164871543355722284926904419997237591535066528048"); BigInteger s = new BigInteger("308992691965804947361541664549085895292153777025772063598"); byte[] kData = BigIntegers.asUnsignedByteArray(new BigInteger("1542725565216523985789236956265265265235675811949404040041")); SecureRandom k = new FixedSecureRandom(kData); ECCurve.F2m curve = new ECCurve.F2m( 191, // m 9, //k new BigInteger("2866537B676752636A68F56554E12640276B649EF7526267", 16), // a new BigInteger("2E45EF571F00786F67B0081B9495A3D95462F5DE0AA185EC", 16)); // b ECDomainParameters params = new ECDomainParameters( curve, curve.decodePoint(Hex.decode("0436B3DAF8A23206F9C4F299D7B21A9C369137F2C84AE1AA0D765BE73433B3F95E332932E70EA245CA2418EA0EF98018FB")), // G new BigInteger("1569275433846670190958947355803350458831205595451630533029"), // n BigInteger.valueOf(2)); // h ECPrivateKeyParameters priKey = new ECPrivateKeyParameters( new BigInteger("1275552191113212300012030439187146164646146646466749494799"), // d params); ECDSASigner ecdsa = new ECDSASigner(); ParametersWithRandom param = new ParametersWithRandom(priKey, k); ecdsa.init(true, param); byte[] message = new BigInteger("968236873715988614170569073515315707566766479517").toByteArray(); BigInteger[] sig = ecdsa.generateSignature(message); if (!r.equals(sig[0])) { fail("r component wrong." + System.getProperty("line.separator") + " expecting: " + r + System.getProperty("line.separator") + " got : " + sig[0]); } if (!s.equals(sig[1])) { fail("s component wrong." + System.getProperty("line.separator") + " expecting: " + s + System.getProperty("line.separator") + " got : " + sig[1]); } // Verify the signature ECPublicKeyParameters pubKey = new ECPublicKeyParameters( curve.decodePoint(Hex.decode("045DE37E756BD55D72E3768CB396FFEB962614DEA4CE28A2E755C0E0E02F5FB132CAF416EF85B229BBB8E1352003125BA1")), // Q params); ecdsa.init(false, pubKey); if (!ecdsa.verifySignature(message, sig[0], sig[1])) { fail("signature fails"); } } /** * X9.62 - 1998,
    * J.2.1, Page 100, ECDSA over the field F2m
    * an example with 191 bit binary field */ private void testECDSA239bitBinary() { BigInteger r = new BigInteger("21596333210419611985018340039034612628818151486841789642455876922391552"); BigInteger s = new BigInteger("197030374000731686738334997654997227052849804072198819102649413465737174"); byte[] kData = BigIntegers.asUnsignedByteArray(new BigInteger("171278725565216523967285789236956265265265235675811949404040041670216363")); SecureRandom k = new FixedSecureRandom(kData); ECCurve.F2m curve = new ECCurve.F2m( 239, // m 36, //k new BigInteger("32010857077C5431123A46B808906756F543423E8D27877578125778AC76", 16), // a new BigInteger("790408F2EEDAF392B012EDEFB3392F30F4327C0CA3F31FC383C422AA8C16", 16)); // b ECDomainParameters params = new ECDomainParameters( curve, curve.decodePoint(Hex.decode("0457927098FA932E7C0A96D3FD5B706EF7E5F5C156E16B7E7C86038552E91D61D8EE5077C33FECF6F1A16B268DE469C3C7744EA9A971649FC7A9616305")), // G new BigInteger("220855883097298041197912187592864814557886993776713230936715041207411783"), // n BigInteger.valueOf(4)); // h ECPrivateKeyParameters priKey = new ECPrivateKeyParameters( new BigInteger("145642755521911534651321230007534120304391871461646461466464667494947990"), // d params); ECDSASigner ecdsa = new ECDSASigner(); ParametersWithRandom param = new ParametersWithRandom(priKey, k); ecdsa.init(true, param); byte[] message = new BigInteger("968236873715988614170569073515315707566766479517").toByteArray(); BigInteger[] sig = ecdsa.generateSignature(message); if (!r.equals(sig[0])) { fail("r component wrong." + System.getProperty("line.separator") + " expecting: " + r + System.getProperty("line.separator") + " got : " + sig[0]); } if (!s.equals(sig[1])) { fail("s component wrong." + System.getProperty("line.separator") + " expecting: " + s + System.getProperty("line.separator") + " got : " + sig[1]); } // Verify the signature ECPublicKeyParameters pubKey = new ECPublicKeyParameters( curve.decodePoint(Hex.decode("045894609CCECF9A92533F630DE713A958E96C97CCB8F5ABB5A688A238DEED6DC2D9D0C94EBFB7D526BA6A61764175B99CB6011E2047F9F067293F57F5")), // Q params); ecdsa.init(false, pubKey); if (!ecdsa.verifySignature(message, sig[0], sig[1])) { fail("signature fails"); } } // L 4.1 X9.62 2005 private void testECDSAP224sha224() { X9ECParameters p = NISTNamedCurves.getByName("P-224"); ECDomainParameters params = new ECDomainParameters(p.getCurve(), p.getG(), p.getN(), p.getH()); ECPrivateKeyParameters priKey = new ECPrivateKeyParameters( new BigInteger("6081831502424510080126737029209236539191290354021104541805484120491"), // d params); SecureRandom k = new FixedSecureRandom(BigIntegers.asUnsignedByteArray(new BigInteger("15456715103636396133226117016818339719732885723579037388121116732601"))); byte[] M = Hex.decode("8797A3C693CC292441039A4E6BAB7387F3B4F2A63D00ED384B378C79"); ECDSASigner dsa = new ECDSASigner(); dsa.init(true, new ParametersWithRandom(priKey, k)); BigInteger[] sig = dsa.generateSignature(M); BigInteger r = new BigInteger("26477406756127720855365980332052585411804331993436302005017227573742"); BigInteger s = new BigInteger("17694958233103667059888193972742186995283044672015112738919822429978"); if (!r.equals(sig[0])) { fail("r component wrong." + System.getProperty("line.separator") + " expecting: " + r + System.getProperty("line.separator") + " got : " + sig[0]); } if (!s.equals(sig[1])) { fail("s component wrong." + System.getProperty("line.separator") + " expecting: " + s + System.getProperty("line.separator") + " got : " + sig[1]); } // Verify the signature ECPublicKeyParameters pubKey = new ECPublicKeyParameters( params.getCurve().decodePoint(Hex.decode("03FD44EC11F9D43D9D23B1E1D1C9ED6519B40ECF0C79F48CF476CC43F1")), // Q params); dsa.init(false, pubKey); if (!dsa.verifySignature(M, sig[0], sig[1])) { fail("signature fails"); } } private void testECDSASecP224k1sha256() { X9ECParameters p = SECNamedCurves.getByName("secp224k1"); ECDomainParameters params = new ECDomainParameters(p.getCurve(), p.getG(), p.getN(), p.getH()); ECPrivateKeyParameters priKey = new ECPrivateKeyParameters( new BigInteger("BE6F6E91FE96840A6518B56F3FE21689903A64FA729057AB872A9F51", 16), // d params); SecureRandom k = new FixedSecureRandom(Hex.decode("00c39beac93db21c3266084429eb9b846b787c094f23a4de66447efbb3")); byte[] M = Hex.decode("E5D5A7ADF73C5476FAEE93A2C76CE94DC0557DB04CDC189504779117920B896D"); ECDSASigner dsa = new ECDSASigner(); dsa.init(true, new ParametersWithRandom(priKey, k)); BigInteger[] sig = dsa.generateSignature(M); BigInteger r = new BigInteger("8163E5941BED41DA441B33E653C632A55A110893133351E20CE7CB75", 16); BigInteger s = new BigInteger("D12C3FC289DDD5F6890DCE26B65792C8C50E68BF551D617D47DF15A8", 16); if (!r.equals(sig[0])) { fail("r component wrong." + System.getProperty("line.separator") + " expecting: " + r + System.getProperty("line.separator") + " got : " + sig[0]); } if (!s.equals(sig[1])) { fail("s component wrong." + System.getProperty("line.separator") + " expecting: " + s + System.getProperty("line.separator") + " got : " + sig[1]); } // Verify the signature ECPublicKeyParameters pubKey = new ECPublicKeyParameters( params.getCurve().decodePoint(Hex.decode("04C5C9B38D3603FCCD6994CBB9594E152B658721E483669BB42728520F484B537647EC816E58A8284D3B89DFEDB173AFDC214ECA95A836FA7C")), // Q params); dsa.init(false, pubKey); if (!dsa.verifySignature(M, sig[0], sig[1])) { fail("signature fails"); } } // L4.2 X9.62 2005 private void testECDSAP256sha256() { X9ECParameters p = NISTNamedCurves.getByName("P-256"); ECDomainParameters params = new ECDomainParameters(p.getCurve(), p.getG(), p.getN(), p.getH()); ECPrivateKeyParameters priKey = new ECPrivateKeyParameters( new BigInteger("20186677036482506117540275567393538695075300175221296989956723148347484984008"), // d params); SecureRandom k = new FixedSecureRandom(BigIntegers.asUnsignedByteArray(new BigInteger("72546832179840998877302529996971396893172522460793442785601695562409154906335"))); byte[] M = Hex.decode("1BD4ED430B0F384B4E8D458EFF1A8A553286D7AC21CB2F6806172EF5F94A06AD"); ECDSASigner dsa = new ECDSASigner(); dsa.init(true, new ParametersWithRandom(priKey, k)); BigInteger[] sig = dsa.generateSignature(M); BigInteger r = new BigInteger("97354732615802252173078420023658453040116611318111190383344590814578738210384"); BigInteger s = new BigInteger("98506158880355671805367324764306888225238061309262649376965428126566081727535"); if (!r.equals(sig[0])) { fail("r component wrong." + System.getProperty("line.separator") + " expecting: " + r + System.getProperty("line.separator") + " got : " + sig[0]); } if (!s.equals(sig[1])) { fail("s component wrong." + System.getProperty("line.separator") + " expecting: " + s + System.getProperty("line.separator") + " got : " + sig[1]); } // Verify the signature ECPublicKeyParameters pubKey = new ECPublicKeyParameters( params.getCurve().decodePoint(Hex.decode("03596375E6CE57E0F20294FC46BDFCFD19A39F8161B58695B3EC5B3D16427C274D")), // Q params); dsa.init(false, pubKey); if (!dsa.verifySignature(M, sig[0], sig[1])) { fail("signature fails"); } } private void testECDSAP224OneByteOver() { X9ECParameters p = NISTNamedCurves.getByName("P-224"); ECDomainParameters params = new ECDomainParameters(p.getCurve(), p.getG(), p.getN(), p.getH()); ECPrivateKeyParameters priKey = new ECPrivateKeyParameters( new BigInteger("6081831502424510080126737029209236539191290354021104541805484120491"), // d params); SecureRandom k = new FixedSecureRandom(BigIntegers.asUnsignedByteArray(new BigInteger("15456715103636396133226117016818339719732885723579037388121116732601"))); byte[] M = Hex.decode("8797A3C693CC292441039A4E6BAB7387F3B4F2A63D00ED384B378C79FF"); ECDSASigner dsa = new ECDSASigner(); dsa.init(true, new ParametersWithRandom(priKey, k)); BigInteger[] sig = dsa.generateSignature(M); BigInteger r = new BigInteger("26477406756127720855365980332052585411804331993436302005017227573742"); BigInteger s = new BigInteger("17694958233103667059888193972742186995283044672015112738919822429978"); if (!r.equals(sig[0])) { fail("r component wrong." + System.getProperty("line.separator") + " expecting: " + r + System.getProperty("line.separator") + " got : " + sig[0]); } if (!s.equals(sig[1])) { fail("s component wrong." + System.getProperty("line.separator") + " expecting: " + s + System.getProperty("line.separator") + " got : " + sig[1]); } // Verify the signature ECPublicKeyParameters pubKey = new ECPublicKeyParameters( params.getCurve().decodePoint(Hex.decode("03FD44EC11F9D43D9D23B1E1D1C9ED6519B40ECF0C79F48CF476CC43F1")), // Q params); dsa.init(false, pubKey); if (!dsa.verifySignature(M, sig[0], sig[1])) { fail("signature fails"); } } // L4.3 X9.62 2005 private void testECDSAP521sha512() { X9ECParameters p = NISTNamedCurves.getByName("P-521"); ECDomainParameters params = new ECDomainParameters(p.getCurve(), p.getG(), p.getN(), p.getH()); ECPrivateKeyParameters priKey = new ECPrivateKeyParameters( new BigInteger("617573726813476282316253885608633222275541026607493641741273231656161177732180358888434629562647985511298272498852936680947729040673640492310550142822667389"), // d params); SecureRandom k = new FixedSecureRandom(BigIntegers.asUnsignedByteArray(new BigInteger("6806532878215503520845109818432174847616958675335397773700324097584974639728725689481598054743894544060040710846048585856076812050552869216017728862957612913"))); byte[] M = Hex.decode("6893B64BD3A9615C39C3E62DDD269C2BAAF1D85915526083183CE14C2E883B48B193607C1ED871852C9DF9C3147B574DC1526C55DE1FE263A676346A20028A66"); ECDSASigner dsa = new ECDSASigner(); dsa.init(true, new ParametersWithRandom(priKey, k)); BigInteger[] sig = dsa.generateSignature(M); BigInteger r = new BigInteger("1368926195812127407956140744722257403535864168182534321188553460365652865686040549247096155740756318290773648848859639978618869784291633651685766829574104630"); BigInteger s = new BigInteger("1624754720348883715608122151214003032398685415003935734485445999065609979304811509538477657407457976246218976767156629169821116579317401249024208611945405790"); if (!r.equals(sig[0])) { fail("r component wrong." + System.getProperty("line.separator") + " expecting: " + r + System.getProperty("line.separator") + " got : " + sig[0]); } if (!s.equals(sig[1])) { fail("s component wrong." + System.getProperty("line.separator") + " expecting: " + s + System.getProperty("line.separator") + " got : " + sig[1]); } // Verify the signature ECPublicKeyParameters pubKey = new ECPublicKeyParameters( params.getCurve().decodePoint(Hex.decode("020145E221AB9F71C5FE740D8D2B94939A09E2816E2167A7D058125A06A80C014F553E8D6764B048FB6F2B687CEC72F39738F223D4CE6AFCBFF2E34774AA5D3C342CB3")), // Q params); dsa.init(false, pubKey); if (!dsa.verifySignature(M, sig[0], sig[1])) { fail("signature fails"); } } /** * General test for long digest. */ private void testECDSA239bitBinaryAndLargeDigest() { BigInteger r = new BigInteger("21596333210419611985018340039034612628818151486841789642455876922391552"); BigInteger s = new BigInteger("144940322424411242416373536877786566515839911620497068645600824084578597"); byte[] kData = BigIntegers.asUnsignedByteArray(new BigInteger("171278725565216523967285789236956265265265235675811949404040041670216363")); SecureRandom k = new FixedSecureRandom(kData); ECCurve.F2m curve = new ECCurve.F2m( 239, // m 36, //k new BigInteger("32010857077C5431123A46B808906756F543423E8D27877578125778AC76", 16), // a new BigInteger("790408F2EEDAF392B012EDEFB3392F30F4327C0CA3F31FC383C422AA8C16", 16)); // b ECDomainParameters params = new ECDomainParameters( curve, curve.decodePoint(Hex.decode("0457927098FA932E7C0A96D3FD5B706EF7E5F5C156E16B7E7C86038552E91D61D8EE5077C33FECF6F1A16B268DE469C3C7744EA9A971649FC7A9616305")), // G new BigInteger("220855883097298041197912187592864814557886993776713230936715041207411783"), // n BigInteger.valueOf(4)); // h ECPrivateKeyParameters priKey = new ECPrivateKeyParameters( new BigInteger("145642755521911534651321230007534120304391871461646461466464667494947990"), // d params); ECDSASigner ecdsa = new ECDSASigner(); ParametersWithRandom param = new ParametersWithRandom(priKey, k); ecdsa.init(true, param); byte[] message = new BigInteger("968236873715988614170569073515315707566766479517968236873715988614170569073515315707566766479517968236873715988614170569073515315707566766479517").toByteArray(); BigInteger[] sig = ecdsa.generateSignature(message); if (!r.equals(sig[0])) { fail("r component wrong." + System.getProperty("line.separator") + " expecting: " + r + System.getProperty("line.separator") + " got : " + sig[0]); } if (!s.equals(sig[1])) { fail("s component wrong." + System.getProperty("line.separator") + " expecting: " + s + System.getProperty("line.separator") + " got : " + sig[1]); } // Verify the signature ECPublicKeyParameters pubKey = new ECPublicKeyParameters( curve.decodePoint(Hex.decode("045894609CCECF9A92533F630DE713A958E96C97CCB8F5ABB5A688A238DEED6DC2D9D0C94EBFB7D526BA6A61764175B99CB6011E2047F9F067293F57F5")), // Q params); ecdsa.init(false, pubKey); if (!ecdsa.verifySignature(message, sig[0], sig[1])) { fail("signature fails"); } } /** * key generation test */ private void testECDSAKeyGenTest() { SecureRandom random = new SecureRandom(); ECCurve.Fp curve = new ECCurve.Fp( new BigInteger("883423532389192164791648750360308885314476597252960362792450860609699839"), // q new BigInteger("7fffffffffffffffffffffff7fffffffffff8000000000007ffffffffffc", 16), // a new BigInteger("6b016c3bdcf18941d0d654921475ca71a9db2fb27d1d37796185c2942c0a", 16)); // b ECDomainParameters params = new ECDomainParameters( curve, curve.decodePoint(Hex.decode("020ffa963cdca8816ccc33b8642bedf905c3d358573d3f27fbbd3b3cb9aaaf")), // G new BigInteger("883423532389192164791648750360308884807550341691627752275345424702807307")); // n ECKeyPairGenerator pGen = new ECKeyPairGenerator(); ECKeyGenerationParameters genParam = new ECKeyGenerationParameters( params, random); pGen.init(genParam); AsymmetricCipherKeyPair pair = pGen.generateKeyPair(); ParametersWithRandom param = new ParametersWithRandom(pair.getPrivate(), random); ECDSASigner ecdsa = new ECDSASigner(); ecdsa.init(true, param); byte[] message = new BigInteger("968236873715988614170569073515315707566766479517").toByteArray(); BigInteger[] sig = ecdsa.generateSignature(message); ecdsa.init(false, pair.getPublic()); if (!ecdsa.verifySignature(message, sig[0], sig[1])) { fail("signature fails"); } } /** * Basic Key Agreement Test */ private void testECBasicAgreementTest() { SecureRandom random = new SecureRandom(); ECCurve.Fp curve = new ECCurve.Fp( new BigInteger("883423532389192164791648750360308885314476597252960362792450860609699839"), // q new BigInteger("7fffffffffffffffffffffff7fffffffffff8000000000007ffffffffffc", 16), // a new BigInteger("6b016c3bdcf18941d0d654921475ca71a9db2fb27d1d37796185c2942c0a", 16)); // b ECDomainParameters params = new ECDomainParameters( curve, curve.decodePoint(Hex.decode("020ffa963cdca8816ccc33b8642bedf905c3d358573d3f27fbbd3b3cb9aaaf")), // G new BigInteger("883423532389192164791648750360308884807550341691627752275345424702807307")); // n ECKeyPairGenerator pGen = new ECKeyPairGenerator(); ECKeyGenerationParameters genParam = new ECKeyGenerationParameters( params, random); pGen.init(genParam); AsymmetricCipherKeyPair p1 = pGen.generateKeyPair(); AsymmetricCipherKeyPair p2 = pGen.generateKeyPair(); // // two way // BasicAgreement e1 = new ECDHBasicAgreement(); BasicAgreement e2 = new ECDHBasicAgreement(); e1.init(p1.getPrivate()); e2.init(p2.getPrivate()); BigInteger k1 = e1.calculateAgreement(p2.getPublic()); BigInteger k2 = e2.calculateAgreement(p1.getPublic()); if (!k1.equals(k2)) { fail("calculated agreement test failed"); } // // two way // e1 = new ECDHCBasicAgreement(); e2 = new ECDHCBasicAgreement(); e1.init(p1.getPrivate()); e2.init(p2.getPrivate()); k1 = e1.calculateAgreement(p2.getPublic()); k2 = e2.calculateAgreement(p1.getPublic()); if (!k1.equals(k2)) { fail("calculated agreement test failed"); } } private void testECMQVTestVector1() { // Test Vector from GEC-2 X9ECParameters x9 = SECNamedCurves.getByName("secp160r1"); ECDomainParameters p = new ECDomainParameters( x9.getCurve(), x9.getG(), x9.getN(), x9.getH(), x9.getSeed()); AsymmetricCipherKeyPair U1 = new AsymmetricCipherKeyPair( new ECPublicKeyParameters( p.getCurve().decodePoint(Hex.decode("0251B4496FECC406ED0E75A24A3C03206251419DC0")), p), new ECPrivateKeyParameters( new BigInteger("AA374FFC3CE144E6B073307972CB6D57B2A4E982", 16), p)); AsymmetricCipherKeyPair U2 = new AsymmetricCipherKeyPair( new ECPublicKeyParameters( p.getCurve().decodePoint(Hex.decode("03D99CE4D8BF52FA20BD21A962C6556B0F71F4CA1F")), p), new ECPrivateKeyParameters( new BigInteger("149EC7EA3A220A887619B3F9E5B4CA51C7D1779C", 16), p)); AsymmetricCipherKeyPair V1 = new AsymmetricCipherKeyPair( new ECPublicKeyParameters( p.getCurve().decodePoint(Hex.decode("0349B41E0E9C0369C2328739D90F63D56707C6E5BC")), p), new ECPrivateKeyParameters( new BigInteger("45FB58A92A17AD4B15101C66E74F277E2B460866", 16), p)); AsymmetricCipherKeyPair V2 = new AsymmetricCipherKeyPair( new ECPublicKeyParameters( p.getCurve().decodePoint(Hex.decode("02706E5D6E1F640C6E9C804E75DBC14521B1E5F3B5")), p), new ECPrivateKeyParameters( new BigInteger("18C13FCED9EADF884F7C595C8CB565DEFD0CB41E", 16), p)); BigInteger x = calculateAgreement(U1, U2, V1, V2); if (x == null || !x.equals(new BigInteger("5A6955CEFDB4E43255FB7FCF718611E4DF8E05AC", 16))) { fail("MQV Test Vector #1 agreement failed"); } } private void testECMQVTestVector2() { // Test Vector from GEC-2 X9ECParameters x9 = SECNamedCurves.getByName("sect163k1"); ECDomainParameters p = new ECDomainParameters( x9.getCurve(), x9.getG(), x9.getN(), x9.getH(), x9.getSeed()); AsymmetricCipherKeyPair U1 = new AsymmetricCipherKeyPair( new ECPublicKeyParameters( p.getCurve().decodePoint(Hex.decode("03037D529FA37E42195F10111127FFB2BB38644806BC")), p), new ECPrivateKeyParameters( new BigInteger("03A41434AA99C2EF40C8495B2ED9739CB2155A1E0D", 16), p)); AsymmetricCipherKeyPair U2 = new AsymmetricCipherKeyPair( new ECPublicKeyParameters( p.getCurve().decodePoint(Hex.decode("02015198E74BC2F1E5C9A62B80248DF0D62B9ADF8429")), p), new ECPrivateKeyParameters( new BigInteger("032FC4C61A8211E6A7C4B8B0C03CF35F7CF20DBD52", 16), p)); AsymmetricCipherKeyPair V1 = new AsymmetricCipherKeyPair( new ECPublicKeyParameters( p.getCurve().decodePoint(Hex.decode("03072783FAAB9549002B4F13140B88132D1C75B3886C")), p), new ECPrivateKeyParameters( new BigInteger("57E8A78E842BF4ACD5C315AA0569DB1703541D96", 16), p)); AsymmetricCipherKeyPair V2 = new AsymmetricCipherKeyPair( new ECPublicKeyParameters( p.getCurve().decodePoint(Hex.decode("03067E3AEA3510D69E8EDD19CB2A703DDC6CF5E56E32")), p), new ECPrivateKeyParameters( new BigInteger("02BD198B83A667A8D908EA1E6F90FD5C6D695DE94F", 16), p)); BigInteger x = calculateAgreement(U1, U2, V1, V2); if (x == null || !x.equals(new BigInteger("038359FFD30C0D5FC1E6154F483B73D43E5CF2B503", 16))) { fail("MQV Test Vector #2 agreement failed"); } } private void testECMQVRandom() { SecureRandom random = new SecureRandom(); ECCurve.Fp curve = new ECCurve.Fp( new BigInteger("883423532389192164791648750360308885314476597252960362792450860609699839"), // q new BigInteger("7fffffffffffffffffffffff7fffffffffff8000000000007ffffffffffc", 16), // a new BigInteger("6b016c3bdcf18941d0d654921475ca71a9db2fb27d1d37796185c2942c0a", 16)); // b ECDomainParameters parameters = new ECDomainParameters( curve, curve.decodePoint(Hex.decode("020ffa963cdca8816ccc33b8642bedf905c3d358573d3f27fbbd3b3cb9aaaf")), // G new BigInteger("883423532389192164791648750360308884807550341691627752275345424702807307")); // n ECKeyPairGenerator pGen = new ECKeyPairGenerator(); pGen.init(new ECKeyGenerationParameters(parameters, random)); // Pre-established key pairs AsymmetricCipherKeyPair U1 = pGen.generateKeyPair(); AsymmetricCipherKeyPair V1 = pGen.generateKeyPair(); // Ephemeral key pairs AsymmetricCipherKeyPair U2 = pGen.generateKeyPair(); AsymmetricCipherKeyPair V2 = pGen.generateKeyPair(); BigInteger x = calculateAgreement(U1, U2, V1, V2); if (x == null) { fail("MQV Test Vector (random) agreement failed"); } } private static BigInteger calculateAgreement( AsymmetricCipherKeyPair U1, AsymmetricCipherKeyPair U2, AsymmetricCipherKeyPair V1, AsymmetricCipherKeyPair V2) { ECMQVBasicAgreement u = new ECMQVBasicAgreement(); u.init(new MQVPrivateParameters( (ECPrivateKeyParameters)U1.getPrivate(), (ECPrivateKeyParameters)U2.getPrivate(), (ECPublicKeyParameters)U2.getPublic())); BigInteger ux = u.calculateAgreement(new MQVPublicParameters( (ECPublicKeyParameters)V1.getPublic(), (ECPublicKeyParameters)V2.getPublic())); ECMQVBasicAgreement v = new ECMQVBasicAgreement(); v.init(new MQVPrivateParameters( (ECPrivateKeyParameters)V1.getPrivate(), (ECPrivateKeyParameters)V2.getPrivate(), (ECPublicKeyParameters)V2.getPublic())); BigInteger vx = v.calculateAgreement(new MQVPublicParameters( (ECPublicKeyParameters)U1.getPublic(), (ECPublicKeyParameters)U2.getPublic())); if (ux.equals(vx)) { return ux; } return null; } public String getName() { return "EC"; } public void performTest() { decodeTest(); testECDSA192bitPrime(); testECDSA239bitPrime(); testECDSA191bitBinary(); testECDSA239bitBinary(); testECDSAKeyGenTest(); testECBasicAgreementTest(); testECDSAP224sha224(); testECDSAP224OneByteOver(); testECDSAP256sha256(); testECDSAP521sha512(); testECDSASecP224k1sha256(); testECDSA239bitBinaryAndLargeDigest(); testECMQVTestVector1(); testECMQVTestVector2(); testECMQVRandom(); } public static void main( String[] args) { runTest(new ECTest()); } } bouncycastle-1.49.orig/test/src/org/bouncycastle/crypto/test/TwofishTest.java0000644000175000017500000000261210525306762027115 0ustar ebourgebourgpackage org.bouncycastle.crypto.test; import org.bouncycastle.crypto.engines.TwofishEngine; import org.bouncycastle.crypto.params.KeyParameter; import org.bouncycastle.util.encoders.Hex; import org.bouncycastle.util.test.SimpleTest; public class TwofishTest extends CipherTest { static String key1 = "000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f"; static String key2 = "000102030405060708090a0b0c0d0e0f1011121314151617"; static String key3 = "000102030405060708090a0b0c0d0e0f"; static String input = "000102030405060708090A0B0C0D0E0F"; static SimpleTest[] tests = { new BlockCipherVectorTest(0, new TwofishEngine(), new KeyParameter(Hex.decode(key1)), input, "8ef0272c42db838bcf7b07af0ec30f38"), new BlockCipherVectorTest(1, new TwofishEngine(), new KeyParameter(Hex.decode(key2)), input, "95accc625366547617f8be4373d10cd7"), new BlockCipherVectorTest(2, new TwofishEngine(), new KeyParameter(Hex.decode(key3)), input, "9fb63337151be9c71306d159ea7afaa4") }; TwofishTest() { super(tests, new TwofishEngine(), new KeyParameter(new byte[32])); } public String getName() { return "Twofish"; } public static void main( String[] args) { runTest(new TwofishTest()); } } bouncycastle-1.49.orig/test/src/org/bouncycastle/crypto/test/RSAKeyEncapsulationTest.java0000750000175000017500000000360712151252353031312 0ustar ebourgebourgpackage org.bouncycastle.crypto.test; import java.math.BigInteger; import java.security.SecureRandom; import org.bouncycastle.crypto.AsymmetricCipherKeyPair; import org.bouncycastle.crypto.digests.SHA1Digest; import org.bouncycastle.crypto.generators.KDF2BytesGenerator; import org.bouncycastle.crypto.generators.RSAKeyPairGenerator; import org.bouncycastle.crypto.kems.RSAKeyEncapsulation; import org.bouncycastle.crypto.params.KeyParameter; import org.bouncycastle.crypto.params.RSAKeyGenerationParameters; import org.bouncycastle.util.test.SimpleTest; /** * Tests for the RSA Key Encapsulation Mechanism */ public class RSAKeyEncapsulationTest extends SimpleTest { public String getName() { return "RSAKeyEncapsulation"; } public void performTest() throws Exception { // Generate RSA key pair RSAKeyPairGenerator rsaGen = new RSAKeyPairGenerator(); rsaGen.init(new RSAKeyGenerationParameters(BigInteger.valueOf(65537), new SecureRandom(), 1024, 5)); AsymmetricCipherKeyPair keys = rsaGen.generateKeyPair(); // Set RSA-KEM parameters RSAKeyEncapsulation kem; KDF2BytesGenerator kdf = new KDF2BytesGenerator(new SHA1Digest()); SecureRandom rnd = new SecureRandom(); byte[] out = new byte[128]; KeyParameter key1, key2; // Test RSA-KEM kem = new RSAKeyEncapsulation(kdf, rnd); kem.init(keys.getPublic()); key1 = (KeyParameter)kem.encrypt(out, 128); kem.init(keys.getPrivate()); key2 = (KeyParameter)kem.decrypt(out, 128); if (!areEqual(key1.getKey(), key2.getKey())) { fail("failed test"); } } public static void main( String[] args) { runTest(new RSAKeyEncapsulationTest()); } } bouncycastle-1.49.orig/test/src/org/bouncycastle/crypto/test/StreamCipherVectorTest.java0000644000175000017500000000302710330633061031231 0ustar ebourgebourgpackage org.bouncycastle.crypto.test; import org.bouncycastle.crypto.CipherParameters; import org.bouncycastle.crypto.StreamCipher; import org.bouncycastle.util.encoders.Hex; import org.bouncycastle.util.test.SimpleTest; /** * a basic test that takes a stream cipher, key parameter, and an input * and output string. */ public class StreamCipherVectorTest extends SimpleTest { int id; StreamCipher cipher; CipherParameters param; byte[] input; byte[] output; public StreamCipherVectorTest( int id, StreamCipher cipher, CipherParameters param, String input, String output) { this.id = id; this.cipher = cipher; this.param = param; this.input = Hex.decode(input); this.output = Hex.decode(output); } public String getName() { return cipher.getAlgorithmName() + " Vector Test " + id; } public void performTest() { cipher.init(true, param); byte[] out = new byte[input.length]; cipher.processBytes(input, 0, input.length, out, 0); if (!areEqual(out, output)) { fail("failed.", new String(Hex.encode(output)) , new String(Hex.encode(out))); } cipher.init(false, param); cipher.processBytes(output, 0, output.length, out, 0); if (!areEqual(input, out)) { fail("failed reversal"); } } } bouncycastle-1.49.orig/test/src/org/bouncycastle/crypto/test/HCFamilyVecTest.java0000644000175000017500000001403611272213252027556 0ustar ebourgebourgpackage org.bouncycastle.crypto.test; import java.io.BufferedReader; import java.io.FileReader; import java.io.IOException; import java.io.Reader; import org.bouncycastle.crypto.CipherParameters; import org.bouncycastle.crypto.StreamCipher; import org.bouncycastle.crypto.engines.HC128Engine; import org.bouncycastle.crypto.engines.HC256Engine; import org.bouncycastle.crypto.params.KeyParameter; import org.bouncycastle.crypto.params.ParametersWithIV; import org.bouncycastle.util.Arrays; import org.bouncycastle.util.encoders.Hex; import org.bouncycastle.util.test.SimpleTest; /** * HC-128 and HC-256 Tests. Based on the test vectors in the official reference * papers, respectively: * * http://www.ecrypt.eu.org/stream/p3ciphers/hc/hc128_p3.pdf * http://www.ecrypt.eu.org/stream/p3ciphers/hc/hc256_p3.pdf */ public class HCFamilyVecTest extends SimpleTest { private static final String TEST_DATA_HOME = "bc.test.data.home"; private static class PeekableLineReader extends BufferedReader { public PeekableLineReader(Reader r) throws IOException { super(r); peek = super.readLine(); } public String peekLine() { return peek; } public String readLine() throws IOException { String tmp = peek; peek = super.readLine(); return tmp; } private String peek; } public String getName() { return "HC-128 and HC-256"; } public void performTest() throws Exception { runTests(new HC128Engine(), "hc-128/ecrypt_HC-128.txt"); runTests(new HC256Engine(), "hc-256/ecrypt_HC-256_128K_128IV.txt"); runTests(new HC256Engine(), "hc-256/ecrypt_HC-256_256K_128IV.txt"); runTests(new HC256Engine(), "hc-256/ecrypt_HC-256_128K_256IV.txt"); runTests(new HC256Engine(), "hc-256/ecrypt_HC-256_256K_256IV.txt"); } private void runTests(StreamCipher hc, String fileName) throws IOException { Reader resource = new FileReader(getDataHome() + "/" + fileName); PeekableLineReader r = new PeekableLineReader(resource); runAllVectors(hc, fileName, r); } private void runAllVectors(StreamCipher hc, String fileName, PeekableLineReader r) throws IOException { for (;;) { String line = r.readLine(); if (line == null) { break; } line = line.trim(); if (line.startsWith("Set ")) { runVector(hc, fileName, r, dellChar(line, ':')); } } } private String dellChar(String s, char c) { StringBuffer b = new StringBuffer(); for (int i = 0; i != s.length(); i++) { if (s.charAt(i) != c) { b.append(s.charAt(i)); } } return b.toString(); } private void runVector(StreamCipher hc, String fileName, PeekableLineReader r, String vectorName) throws IOException { // System.out.println(fileName + " => " + vectorName); String hexKey = readBlock(r); String hexIV = readBlock(r); CipherParameters cp = new KeyParameter(Hex.decode(hexKey)); cp = new ParametersWithIV(cp, Hex.decode(hexIV)); hc.init(true, cp); byte[] input = new byte[64]; byte[] output = new byte[64]; byte[] digest = new byte[64]; int pos = 0; for (;;) { String line1 = r.peekLine().trim(); int equalsPos = line1.indexOf('='); String lead = line1.substring(0, equalsPos - 1); String hexData = readBlock(r); byte[] data = Hex.decode(hexData); if (lead.equals("xor-digest")) { if (!Arrays.areEqual(data, digest)) { fail("Failed in " + fileName + " for test vector: " + vectorName + " at " + lead); // System.out.println(fileName + " => " + vectorName + " failed at " + lead); return; } break; } int posA = lead.indexOf('['); int posB = lead.indexOf(".."); int posC = lead.indexOf(']'); int start = Integer.parseInt(lead.substring(posA + 1, posB)); int end = Integer.parseInt(lead.substring(posB + 2, posC)); if (start % 64 != 0 || (end - start != 63)) { throw new IllegalStateException(vectorName + ": " + lead + " not on 64 byte boundaries"); } while (pos < end) { hc.processBytes(input, 0, input.length, output, 0); xor(digest, output); pos += 64; } if (!Arrays.areEqual(data, output)) { fail("Failed in " + fileName + " for test vector: " + vectorName + " at " + lead); // System.out.println(fileName + " => " + vectorName + " failed at " + lead); return; } } } private static String readBlock(PeekableLineReader r) throws IOException { String first = r.readLine().trim(); String result = first.substring(first.lastIndexOf(' ') + 1); for (;;) { String peek = r.peekLine().trim(); if (peek.length() < 1 || peek.indexOf('=') >= 0) { break; } result += r.readLine().trim(); } return result; } private static void xor(byte[] digest, byte[] block) { for (int i = 0; i < digest.length; ++i) { digest[i] ^= block[i]; } } private static String getDataHome() { String dataHome = System.getProperty(TEST_DATA_HOME); if (dataHome == null) { throw new IllegalStateException(TEST_DATA_HOME + " property not set"); } return dataHome + "/hc-256"; } public static void main(String[] args) { runTest(new HCFamilyVecTest()); } } bouncycastle-1.49.orig/test/src/org/bouncycastle/crypto/test/NonMemoableDigestTest.java0000644000175000017500000001000412143612457031017 0ustar ebourgebourgpackage org.bouncycastle.crypto.test; import org.bouncycastle.crypto.digests.NonMemoableDigest; import org.bouncycastle.crypto.digests.SHA1Digest; import org.bouncycastle.crypto.macs.HMac; import org.bouncycastle.crypto.params.KeyParameter; import org.bouncycastle.util.Arrays; import org.bouncycastle.util.encoders.Hex; import org.bouncycastle.util.test.SimpleTestResult; import org.bouncycastle.util.test.Test; import org.bouncycastle.util.test.TestResult; /** * SHA1 HMac Test, test vectors from RFC 2202 */ public class NonMemoableDigestTest implements Test { final static String[] keys = { "0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b", "4a656665", "aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa", "0102030405060708090a0b0c0d0e0f10111213141516171819", "0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c", "aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa", "aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa" }; final static String[] digests = { "b617318655057264e28bc0b6fb378c8ef146be00", "effcdf6ae5eb2fa2d27416d5f184df9c259a7c79", "125d7342b9ac11cd91a39af48aa17b4f63f175d3", "4c9007f4026250c6bc8414f9bf50c86c2d7235da", "4c1a03424b55e07fe7f27be1d58bb9324a9a5a04", "aa4ae5e15272d00e95705637ce8a3b55ed402112", "e8e99d0f45237d786d6bbaa7965c7808bbff1a91", "4c1a03424b55e07fe7f27be1d58bb9324a9a5a04", "aa4ae5e15272d00e95705637ce8a3b55ed402112", "e8e99d0f45237d786d6bbaa7965c7808bbff1a91" }; final static String[] messages = { "Hi There", "what do ya want for nothing?", "0xdddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddd", "0xcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcd", "Test With Truncation", "Test Using Larger Than Block-Size Key - Hash Key First", "Test Using Larger Than Block-Size Key and Larger Than One Block-Size Data" }; public String getName() { return "NonMemoableDigest"; } public TestResult perform() { HMac hmac = new HMac(new NonMemoableDigest(new SHA1Digest())); byte[] resBuf = new byte[hmac.getMacSize()]; for (int i = 0; i < messages.length; i++) { byte[] m = messages[i].getBytes(); if (messages[i].startsWith("0x")) { m = Hex.decode(messages[i].substring(2)); } hmac.init(new KeyParameter(Hex.decode(keys[i]))); hmac.update(m, 0, m.length); hmac.doFinal(resBuf, 0); if (!Arrays.areEqual(resBuf, Hex.decode(digests[i]))) { return new SimpleTestResult(false, getName() + ": Vector " + i + " failed"); } } // // test reset // int vector = 0; // vector used for test byte[] m = messages[vector].getBytes(); if (messages[vector].startsWith("0x")) { m = Hex.decode(messages[vector].substring(2)); } hmac.init(new KeyParameter(Hex.decode(keys[vector]))); hmac.update(m, 0, m.length); hmac.doFinal(resBuf, 0); hmac.reset(); hmac.update(m, 0, m.length); hmac.doFinal(resBuf, 0); if (!Arrays.areEqual(resBuf, Hex.decode(digests[vector]))) { return new SimpleTestResult(false, getName() + "Reset with vector " + vector + " failed"); } return new SimpleTestResult(true, getName() + ": Okay"); } public static void main( String[] args) { NonMemoableDigestTest test = new NonMemoableDigestTest(); TestResult result = test.perform(); System.out.println(result); } } bouncycastle-1.49.orig/test/src/org/bouncycastle/crypto/test/ISO9796Test.java0000644000175000017500000010647312131437511026465 0ustar ebourgebourgpackage org.bouncycastle.crypto.test; import java.math.BigInteger; import java.security.SecureRandom; import org.bouncycastle.crypto.AsymmetricBlockCipher; import org.bouncycastle.crypto.Digest; import org.bouncycastle.crypto.digests.RIPEMD128Digest; import org.bouncycastle.crypto.digests.RIPEMD160Digest; import org.bouncycastle.crypto.digests.SHA1Digest; import org.bouncycastle.crypto.digests.SHA256Digest; import org.bouncycastle.crypto.encodings.ISO9796d1Encoding; import org.bouncycastle.crypto.engines.RSABlindedEngine; import org.bouncycastle.crypto.engines.RSAEngine; import org.bouncycastle.crypto.params.AsymmetricKeyParameter; import org.bouncycastle.crypto.params.ParametersWithSalt; import org.bouncycastle.crypto.params.RSAKeyParameters; import org.bouncycastle.crypto.signers.ISO9796d2PSSSigner; import org.bouncycastle.crypto.signers.ISO9796d2Signer; import org.bouncycastle.util.Arrays; import org.bouncycastle.util.encoders.Base64; import org.bouncycastle.util.encoders.Hex; import org.bouncycastle.util.test.SimpleTest; /** * test vectors from ISO 9796-1 and ISO 9796-2 edition 1. */ public class ISO9796Test extends SimpleTest { static BigInteger mod1 = new BigInteger("0100000000000000000000000000000000bba2d15dbb303c8a21c5ebbcbae52b7125087920dd7cdf358ea119fd66fb064012ec8ce692f0a0b8e8321b041acd40b7", 16); static BigInteger pub1 = new BigInteger("03", 16); static BigInteger pri1 = new BigInteger("2aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaac9f0783a49dd5f6c5af651f4c9d0dc9281c96a3f16a85f9572d7cc3f2d0f25a9dbf1149e4cdc32273faadd3fda5dcda7", 16); static BigInteger mod2 = new BigInteger("ffffff7fa27087c35ebead78412d2bdffe0301edd494df13458974ea89b364708f7d0f5a00a50779ddf9f7d4cb80b8891324da251a860c4ec9ef288104b3858d", 16); static BigInteger pub2 = new BigInteger("03", 16); static BigInteger pri2 = new BigInteger("2aaaaa9545bd6bf5e51fc7940adcdca5550080524e18cfd88b96e8d1c19de6121b13fac0eb0495d47928e047724d91d1740f6968457ce53ec8e24c9362ce84b5", 16); static byte msg1[] = Hex.decode("0cbbaa99887766554433221100"); // // you'll need to see the ISO 9796 to make sense of this // static byte sig1[] = mod1.subtract(new BigInteger("309f873d8ded8379490f6097eaafdabc137d3ebfd8f25ab5f138d56a719cdc526bdd022ea65dabab920a81013a85d092e04d3e421caab717c90d89ea45a8d23a", 16)).toByteArray(); static byte msg2[] = Hex.decode("fedcba9876543210fedcba9876543210fedcba9876543210fedcba9876543210"); static byte sig2[] = new BigInteger("319bb9becb49f3ed1bca26d0fcf09b0b0a508e4d0bd43b350f959b72cd25b3af47d608fdcd248eada74fbe19990dbeb9bf0da4b4e1200243a14e5cab3f7e610c", 16).toByteArray(); static byte msg3[] = Hex.decode("0112233445566778899aabbccd"); static byte sig3[] = mod2.subtract(new BigInteger("58e59ffb4b1fb1bcdbf8d1fe9afa3730c78a318a1134f5791b7313d480ff07ac319b068edf8f212945cb09cf33df30ace54f4a063fcca0b732f4b662dc4e2454", 16)).toByteArray(); // // ISO 9796-2 // static BigInteger mod3 = new BigInteger("ffffffff78f6c55506c59785e871211ee120b0b5dd644aa796d82413a47b24573f1be5745b5cd9950f6b389b52350d4e01e90009669a8720bf265a2865994190a661dea3c7828e2e7ca1b19651adc2d5", 16); static BigInteger pub3 = new BigInteger("03", 16); static BigInteger pri3 = new BigInteger("2aaaaaaa942920e38120ee965168302fd0301d73a4e60c7143ceb0adf0bf30b9352f50e8b9e4ceedd65343b2179005b2f099915e4b0c37e41314bb0821ad8330d23cba7f589e0f129b04c46b67dfce9d", 16); static BigInteger mod4 = new BigInteger("FFFFFFFF45f1903ebb83d4d363f70dc647b839f2a84e119b8830b2dec424a1ce0c9fd667966b81407e89278283f27ca8857d40979407fc6da4cc8a20ecb4b8913b5813332409bc1f391a94c9c328dfe46695daf922259174544e2bfbe45cc5cd", 16); static BigInteger pub4 = new BigInteger("02", 16); static BigInteger pri4 = new BigInteger("1fffffffe8be3207d7707a9a6c7ee1b8c8f7073e5509c2337106165bd8849439c193faccf2cd70280fd124f0507e4f94cb66447680c6b87b6599d1b61c8f3600854a618262e9c1cb1438e485e47437be036d94b906087a61ee74ab0d9a1accd8", 16); static byte msg4[] = Hex.decode("6162636462636465636465666465666765666768666768696768696a68696a6b696a6b6c6a6b6c6d6b6c6d6e6c6d6e6f6d6e6f706e6f7071"); static byte sig4[] = Hex.decode("374695b7ee8b273925b4656cc2e008d41463996534aa5aa5afe72a52ffd84e118085f8558f36631471d043ad342de268b94b080bee18a068c10965f581e7f32899ad378835477064abed8ef3bd530fce"); static byte msg5[] = Hex.decode("fedcba9876543210fedcba9876543210fedcba9876543210fedcba9876543210fedcba9876543210fedcba9876543210fedcba9876543210fedcba9876543210fedcba9876543210fedcba9876543210fedcba9876543210fedcba9876543210fedcba9876543210fedcba9876543210"); static byte sig5[] = Hex.decode("5cf9a01854dbacaec83aae8efc563d74538192e95466babacd361d7c86000fe42dcb4581e48e4feb862d04698da9203b1803b262105104d510b365ee9c660857ba1c001aa57abfd1c8de92e47c275cae"); // // scheme 2 data // static BigInteger mod6 = new BigInteger("b259d2d6e627a768c94be36164c2d9fc79d97aab9253140e5bf17751197731d6f7540d2509e7b9ffee0a70a6e26d56e92d2edd7f85aba85600b69089f35f6bdbf3c298e05842535d9f064e6b0391cb7d306e0a2d20c4dfb4e7b49a9640bdea26c10ad69c3f05007ce2513cee44cfe01998e62b6c3637d3fc0391079b26ee36d5", 16); static BigInteger pub6 = new BigInteger("11", 16); static BigInteger pri6 = new BigInteger("92e08f83cc9920746989ca5034dcb384a094fb9c5a6288fcc4304424ab8f56388f72652d8fafc65a4b9020896f2cde297080f2a540e7b7ce5af0b3446e1258d1dd7f245cf54124b4c6e17da21b90a0ebd22605e6f45c9f136d7a13eaac1c0f7487de8bd6d924972408ebb58af71e76fd7b012a8d0e165f3ae2e5077a8648e619", 16); static byte sig6[] = new BigInteger("0073FEAF13EB12914A43FE635022BB4AB8188A8F3ABD8D8A9E4AD6C355EE920359C7F237AE36B1212FE947F676C68FE362247D27D1F298CA9302EB21F4A64C26CE44471EF8C0DFE1A54606F0BA8E63E87CDACA993BFA62973B567473B4D38FAE73AB228600934A9CC1D3263E632E21FD52D2B95C5F7023DA63DE9509C01F6C7BBC", 16).modPow(pri6, mod6).toByteArray(); static byte msg7[] = Hex.decode("6162636462636465636465666465666765666768666768696768696A68696A6B696A6B6C6A6B6C6D6B6C6D6E6C6D6E6F6D6E6F706E6F70716F70717270717273"); static byte sig7[] = new BigInteger("296B06224010E1EC230D4560A5F88F03550AAFCE31C805CE81E811E5E53E5F71AE64FC2A2A486B193E87972D90C54B807A862F21A21919A43ECF067240A8C8C641DE8DCDF1942CF790D136728FFC0D98FB906E7939C1EC0E64C0E067F0A7443D6170E411DF91F797D1FFD74009C4638462E69D5923E7433AEC028B9A90E633CC", 16).modPow(pri6, mod6).toByteArray(); static byte msg8[] = Hex.decode("FEDCBA9876543210FEDCBA9876543210FEDCBA9876543210FEDCBA9876543210FEDCBA9876543210FEDCBA9876543210FEDCBA9876543210FEDCBA9876543210FEDCBA9876543210FEDCBA9876543210FEDCBA9876543210FEDCBA9876543210FEDCBA9876543210FEDCBA9876543210FEDCBA9876543210FEDCBA9876543210FEDCBA98"); static byte sig8[] = new BigInteger("01402B29ABA104079677CE7FC3D5A84DB24494D6F9508B4596484F5B3CC7E8AFCC4DDE7081F21CAE9D4F94D6D2CCCB43FCEDA0988FFD4EF2EAE72CFDEB4A2638F0A34A0C49664CD9DB723315759D758836C8BA26AC4348B66958AC94AE0B5A75195B57ABFB9971E21337A4B517F2E820B81F26BCE7C66F48A2DB12A8F3D731CC", 16).modPow(pri6, mod6).toByteArray(); static byte msg9[] = Hex.decode("6162636462636465636465666465666765666768666768696768696A68696A6B696A6B6C6A6B6C6D6B6C6D6E6C6D6E6F6D6E6F706E6F70716F707172707172737172737472737475737475767475767775767778767778797778797A78797A61797A61627A6162636162636462636465"); static byte sig9[] = new BigInteger("6F2BB97571FE2EF205B66000E9DD06656655C1977F374E8666D636556A5FEEEEAF645555B25F45567C4EE5341F96FED86508C90A9E3F11B26E8D496139ED3E55ECE42860A6FB3A0817DAFBF13019D93E1D382DA07264FE99D9797D2F0B7779357CA7E74EE440D8855B7DDF15F000AC58EE3FFF144845E771907C0C83324A6FBC", 16).modPow(pri6, mod6).toByteArray(); public String getName() { return "ISO9796"; } private boolean isSameAs( byte[] a, int off, byte[] b) { if ((a.length - off) != b.length) { return false; } for (int i = 0; i != b.length; i++) { if (a[i + off] != b[i]) { return false; } } return true; } private boolean startsWith( byte[] a, byte[] b) { if (a.length < b.length) { return false; } for (int i = 0; i != b.length; i++) { if (a[i] != b[i]) { return false; } } return true; } private void doTest1() throws Exception { RSAKeyParameters pubParameters = new RSAKeyParameters(false, mod1, pub1); RSAKeyParameters privParameters = new RSAKeyParameters(true, mod1, pri1); RSAEngine rsa = new RSAEngine(); byte[] data; // // ISO 9796-1 - public encrypt, private decrypt // ISO9796d1Encoding eng = new ISO9796d1Encoding(rsa); eng.init(true, privParameters); eng.setPadBits(4); data = eng.processBlock(msg1, 0, msg1.length); eng.init(false, pubParameters); if (!areEqual(sig1, data)) { fail("failed ISO9796-1 generation Test 1"); } data = eng.processBlock(data, 0, data.length); if (!areEqual(msg1, data)) { fail("failed ISO9796-1 retrieve Test 1"); } } private void doTest2() throws Exception { RSAKeyParameters pubParameters = new RSAKeyParameters(false, mod1, pub1); RSAKeyParameters privParameters = new RSAKeyParameters(true, mod1, pri1); RSAEngine rsa = new RSAEngine(); byte[] data; // // ISO 9796-1 - public encrypt, private decrypt // ISO9796d1Encoding eng = new ISO9796d1Encoding(rsa); eng.init(true, privParameters); data = eng.processBlock(msg2, 0, msg2.length); eng.init(false, pubParameters); if (!isSameAs(data, 1, sig2)) { fail("failed ISO9796-1 generation Test 2"); } data = eng.processBlock(data, 0, data.length); if (!areEqual(msg2, data)) { fail("failed ISO9796-1 retrieve Test 2"); } } public void doTest3() throws Exception { RSAKeyParameters pubParameters = new RSAKeyParameters(false, mod2, pub2); RSAKeyParameters privParameters = new RSAKeyParameters(true, mod2, pri2); RSAEngine rsa = new RSAEngine(); byte[] data; // // ISO 9796-1 - public encrypt, private decrypt // ISO9796d1Encoding eng = new ISO9796d1Encoding(rsa); eng.init(true, privParameters); eng.setPadBits(4); data = eng.processBlock(msg3, 0, msg3.length); eng.init(false, pubParameters); if (!isSameAs(sig3, 1, data)) { fail("failed ISO9796-1 generation Test 3"); } data = eng.processBlock(data, 0, data.length); if (!isSameAs(msg3, 0, data)) { fail("failed ISO9796-1 retrieve Test 3"); } } public void doTest4() throws Exception { RSAKeyParameters pubParameters = new RSAKeyParameters(false, mod3, pub3); RSAKeyParameters privParameters = new RSAKeyParameters(true, mod3, pri3); RSAEngine rsa = new RSAEngine(); byte[] data; // // ISO 9796-2 - Signing // ISO9796d2Signer eng = new ISO9796d2Signer(rsa, new RIPEMD128Digest()); eng.init(true, privParameters); eng.update(msg4[0]); eng.update(msg4, 1, msg4.length - 1); data = eng.generateSignature(); eng.init(false, pubParameters); if (!isSameAs(sig4, 0, data)) { fail("failed ISO9796-2 generation Test 4"); } eng.update(msg4[0]); eng.update(msg4, 1, msg4.length - 1); if (!eng.verifySignature(sig4)) { fail("failed ISO9796-2 verify Test 4"); } if (eng.hasFullMessage()) { eng = new ISO9796d2Signer(rsa, new RIPEMD128Digest()); eng.init(false, pubParameters); if (!eng.verifySignature(sig4)) { fail("failed ISO9796-2 verify and recover Test 4"); } if (!isSameAs(eng.getRecoveredMessage(), 0, msg4)) { fail("failed ISO9796-2 recovered message Test 4"); } // try update with recovered eng.updateWithRecoveredMessage(sig4); if (!isSameAs(eng.getRecoveredMessage(), 0, msg4)) { fail("failed ISO9796-2 updateWithRecovered recovered message Test 4"); } if (!eng.verifySignature(sig4)) { fail("failed ISO9796-2 updateWithRecovered verify and recover Test 4"); } if (!isSameAs(eng.getRecoveredMessage(), 0, msg4)) { fail("failed ISO9796-2 updateWithRecovered recovered verify message Test 4"); } // should fail eng.updateWithRecoveredMessage(sig4); eng.update(msg4, 0, msg4.length); if (eng.verifySignature(sig4)) { fail("failed ISO9796-2 updateWithRecovered verify and recover Test 4"); } } else { fail("full message flag false - Test 4"); } } public void doTest5() throws Exception { RSAKeyParameters pubParameters = new RSAKeyParameters(false, mod3, pub3); RSAKeyParameters privParameters = new RSAKeyParameters(true, mod3, pri3); RSAEngine rsa = new RSAEngine(); byte[] data; // // ISO 9796-2 - Signing // ISO9796d2Signer eng = new ISO9796d2Signer(rsa, new RIPEMD160Digest(), true); eng.init(true, privParameters); eng.update(msg5[0]); eng.update(msg5, 1, msg5.length - 1); data = eng.generateSignature(); eng.init(false, pubParameters); if (!isSameAs(sig5, 0, data)) { fail("failed ISO9796-2 generation Test 5"); } eng.update(msg5[0]); eng.update(msg5, 1, msg5.length - 1); if (!eng.verifySignature(sig5)) { fail("failed ISO9796-2 verify Test 5"); } if (eng.hasFullMessage()) { fail("fullMessage true - Test 5"); } if (!startsWith(msg5, eng.getRecoveredMessage())) { fail("failed ISO9796-2 partial recovered message Test 5"); } int length = eng.getRecoveredMessage().length; if (length >= msg5.length) { fail("Test 5 recovered message too long"); } eng = new ISO9796d2Signer(rsa, new RIPEMD160Digest(), true); eng.init(false, pubParameters); eng.updateWithRecoveredMessage(sig5); if (!startsWith(msg5, eng.getRecoveredMessage())) { fail("failed ISO9796-2 updateWithRecovered partial recovered message Test 5"); } if (eng.hasFullMessage()) { fail("fullMessage updateWithRecovered true - Test 5"); } for (int i = length; i != msg5.length; i++) { eng.update(msg5[i]); } if (!eng.verifySignature(sig5)) { fail("failed ISO9796-2 verify Test 5"); } if (eng.hasFullMessage()) { fail("fullMessage updateWithRecovered true - Test 5"); } // should fail eng.updateWithRecoveredMessage(sig5); eng.update(msg5, 0, msg5.length); if (eng.verifySignature(sig5)) { fail("failed ISO9796-2 updateWithRecovered verify fail Test 5"); } } // // against a zero length string // public void doTest6() throws Exception { byte[] salt = Hex.decode("61DF870C4890FE85D6E3DD87C3DCE3723F91DB49"); RSAKeyParameters pubParameters = new RSAKeyParameters(false, mod6, pub6); RSAKeyParameters privParameters = new RSAKeyParameters(true, mod6, pri6); ParametersWithSalt sigParameters = new ParametersWithSalt(privParameters, salt); RSAEngine rsa = new RSAEngine(); byte[] data; // // ISO 9796-2 - PSS Signing // ISO9796d2PSSSigner eng = new ISO9796d2PSSSigner(rsa, new RIPEMD160Digest(), 20, true); eng.init(true, sigParameters); data = eng.generateSignature(); eng.init(false, pubParameters); if (!isSameAs(sig6, 1, data)) { fail("failed ISO9796-2 generation Test 6"); } if (!eng.verifySignature(data)) { fail("failed ISO9796-2 verify Test 6"); } } public void doTest7() throws Exception { byte[] salt = new byte[0]; RSAKeyParameters pubParameters = new RSAKeyParameters(false, mod6, pub6); RSAKeyParameters privParameters = new RSAKeyParameters(true, mod6, pri6); ParametersWithSalt sigParameters = new ParametersWithSalt(privParameters, salt); RSAEngine rsa = new RSAEngine(); byte[] data; // // ISO 9796-2 - PSS Signing // ISO9796d2PSSSigner eng = new ISO9796d2PSSSigner(rsa, new SHA1Digest(), 0, false); eng.init(true, sigParameters); eng.update(msg7[0]); eng.update(msg7, 1, msg7.length - 1); data = eng.generateSignature(); eng.init(false, pubParameters); if (!isSameAs(sig7, 0, data)) { fail("failed ISO9796-2 generation Test 7"); } eng.update(msg7[0]); eng.update(msg7, 1, msg7.length - 1); if (!eng.verifySignature(sig7)) { fail("failed ISO9796-2 verify Test 7"); } if (!isSameAs(msg7, 0, eng.getRecoveredMessage())) { fail("failed ISO9796-2 recovery Test 7"); } } public void doTest8() throws Exception { byte[] salt = Hex.decode("78E293203CBA1B7F92F05F4D171FF8CA3E738FF8"); RSAKeyParameters pubParameters = new RSAKeyParameters(false, mod6, pub6); RSAKeyParameters privParameters = new RSAKeyParameters(true, mod6, pri6); ParametersWithSalt sigParameters = new ParametersWithSalt(privParameters, salt); RSAEngine rsa = new RSAEngine(); byte[] data; // // ISO 9796-2 - PSS Signing // ISO9796d2PSSSigner eng = new ISO9796d2PSSSigner(rsa, new RIPEMD160Digest(), 20, false); eng.init(true, sigParameters); eng.update(msg8[0]); eng.update(msg8, 1, msg8.length - 1); data = eng.generateSignature(); eng.init(false, pubParameters); if (!isSameAs(sig8, 0, data)) { fail("failed ISO9796-2 generation Test 8"); } eng.update(msg8[0]); eng.update(msg8, 1, msg8.length - 1); if (!eng.verifySignature(sig8)) { fail("failed ISO9796-2 verify Test 8"); } } public void doTest9() throws Exception { RSAKeyParameters pubParameters = new RSAKeyParameters(false, mod6, pub6); RSAKeyParameters privParameters = new RSAKeyParameters(true, mod6, pri6); RSAEngine rsa = new RSAEngine(); byte[] data; // // ISO 9796-2 - PSS Signing // ISO9796d2PSSSigner eng = new ISO9796d2PSSSigner(rsa, new RIPEMD160Digest(), 0, true); eng.init(true, privParameters); eng.update(msg9[0]); eng.update(msg9, 1, msg9.length - 1); data = eng.generateSignature(); eng.init(false, pubParameters); if (!isSameAs(sig9, 0, data)) { fail("failed ISO9796-2 generation Test 9"); } eng.update(msg9[0]); eng.update(msg9, 1, msg9.length - 1); if (!eng.verifySignature(sig9)) { fail("failed ISO9796-2 verify Test 9"); } } public void doTest10() throws Exception { BigInteger mod = new BigInteger("B3ABE6D91A4020920F8B3847764ECB34C4EB64151A96FDE7B614DC986C810FF2FD73575BDF8532C06004C8B4C8B64F700A50AEC68C0701ED10E8D211A4EA554D", 16); BigInteger pubExp = new BigInteger("65537", 10); BigInteger priExp = new BigInteger("AEE76AE4716F77C5782838F328327012C097BD67E5E892E75C1356E372CCF8EE1AA2D2CBDFB4DA19F703743F7C0BA42B2D69202BA7338C294D1F8B6A5771FF41", 16); RSAKeyParameters pubParameters = new RSAKeyParameters(false, mod, pubExp); RSAKeyParameters privParameters = new RSAKeyParameters(true, mod, priExp); RSAEngine rsa = new RSAEngine(); byte[] data; // // ISO 9796-2 - PSS Signing // Digest dig = new SHA1Digest(); ISO9796d2PSSSigner eng = new ISO9796d2PSSSigner(rsa, dig, dig.getDigestSize()); // // as the padding is random this test needs to repeat a few times to // make sure // for (int i = 0; i != 500; i++) { eng.init(true, privParameters); eng.update(msg9[0]); eng.update(msg9, 1, msg9.length - 1); data = eng.generateSignature(); eng.init(false, pubParameters); eng.update(msg9[0]); eng.update(msg9, 1, msg9.length - 1); if (!eng.verifySignature(data)) { fail("failed ISO9796-2 verify Test 10"); } } } public void doTest11() throws Exception { BigInteger mod = new BigInteger("B3ABE6D91A4020920F8B3847764ECB34C4EB64151A96FDE7B614DC986C810FF2FD73575BDF8532C06004C8B4C8B64F700A50AEC68C0701ED10E8D211A4EA554D", 16); BigInteger pubExp = new BigInteger("65537", 10); BigInteger priExp = new BigInteger("AEE76AE4716F77C5782838F328327012C097BD67E5E892E75C1356E372CCF8EE1AA2D2CBDFB4DA19F703743F7C0BA42B2D69202BA7338C294D1F8B6A5771FF41", 16); RSAKeyParameters pubParameters = new RSAKeyParameters(false, mod, pubExp); RSAKeyParameters privParameters = new RSAKeyParameters(true, mod, priExp); RSAEngine rsa = new RSAEngine(); byte[] data; byte[] m1 = {1, 2, 3, 4, 5, 6, 7, 8, 9}; byte[] m2 = {1, 2, 3, 4, 5, 6, 7, 8, 9, 0}; byte[] m3 = {1, 2, 3, 4, 5, 6, 7, 8}; // // ISO 9796-2 - PSS Signing // Digest dig = new SHA1Digest(); ISO9796d2PSSSigner eng = new ISO9796d2PSSSigner(rsa, dig, dig.getDigestSize()); // // check message bounds // eng.init(true, privParameters); eng.update(m1, 0, m1.length); data = eng.generateSignature(); eng.init(false, pubParameters); eng.update(m2, 0, m2.length); if (eng.verifySignature(data)) { fail("failed ISO9796-2 m2 verify Test 11"); } eng.init(false, pubParameters); eng.update(m3, 0, m3.length); if (eng.verifySignature(data)) { fail("failed ISO9796-2 m3 verify Test 11"); } eng.init(false, pubParameters); eng.update(m1, 0, m1.length); if (!eng.verifySignature(data)) { fail("failed ISO9796-2 verify Test 11"); } } public void doTest12() throws Exception { BigInteger mod = new BigInteger("B3ABE6D91A4020920F8B3847764ECB34C4EB64151A96FDE7B614DC986C810FF2FD73575BDF8532C06004C8B4C8B64F700A50AEC68C0701ED10E8D211A4EA554D", 16); BigInteger pubExp = new BigInteger("65537", 10); BigInteger priExp = new BigInteger("AEE76AE4716F77C5782838F328327012C097BD67E5E892E75C1356E372CCF8EE1AA2D2CBDFB4DA19F703743F7C0BA42B2D69202BA7338C294D1F8B6A5771FF41", 16); RSAKeyParameters pubParameters = new RSAKeyParameters(false, mod, pubExp); RSAKeyParameters privParameters = new RSAKeyParameters(true, mod, priExp); RSAEngine rsa = new RSAEngine(); byte[] data; byte[] m1 = {1, 2, 3, 4, 5, 6, 7, 8, 9}; byte[] m2 = {1, 2, 3, 4, 5, 6, 7, 8, 9, 0}; byte[] m3 = {1, 2, 3, 4, 5, 6, 7, 8}; // // ISO 9796-2 - Signing // Digest dig = new SHA1Digest(); ISO9796d2Signer eng = new ISO9796d2Signer(rsa, dig); // // check message bounds // eng.init(true, privParameters); eng.update(m1, 0, m1.length); data = eng.generateSignature(); eng.init(false, pubParameters); eng.update(m2, 0, m2.length); if (eng.verifySignature(data)) { fail("failed ISO9796-2 m2 verify Test 12"); } eng.init(false, pubParameters); eng.update(m3, 0, m3.length); if (eng.verifySignature(data)) { fail("failed ISO9796-2 m3 verify Test 12"); } eng.init(false, pubParameters); eng.update(m1, 0, m1.length); if (!eng.verifySignature(data)) { fail("failed ISO9796-2 verify Test 12"); } } private void doTest13() throws Exception { BigInteger modulus = new BigInteger(1, Hex.decode("CDCBDABBF93BE8E8294E32B055256BBD0397735189BF75816341BB0D488D05D627991221DF7D59835C76A4BB4808ADEEB779E7794504E956ADC2A661B46904CDC71337DD29DDDD454124EF79CFDD7BC2C21952573CEFBA485CC38C6BD2428809B5A31A898A6B5648CAA4ED678D9743B589134B7187478996300EDBA16271A861")); BigInteger pubExp = new BigInteger(1, Hex.decode("010001")); BigInteger privExp = new BigInteger(1, Hex.decode("4BA6432AD42C74AA5AFCB6DF60FD57846CBC909489994ABD9C59FE439CC6D23D6DE2F3EA65B8335E796FD7904CA37C248367997257AFBD82B26F1A30525C447A236C65E6ADE43ECAAF7283584B2570FA07B340D9C9380D88EAACFFAEEFE7F472DBC9735C3FF3A3211E8A6BBFD94456B6A33C17A2C4EC18CE6335150548ED126D")); RSAKeyParameters pubParams = new RSAKeyParameters(false, modulus, pubExp); RSAKeyParameters privParams = new RSAKeyParameters(true, modulus, privExp); AsymmetricBlockCipher rsaEngine = new RSABlindedEngine(); Digest digest = new SHA256Digest(); // set challenge to all zero's for verification byte[] challenge = new byte[8]; // DOES NOT USE FINAL BOOLEAN TO INDICATE RECOVERY ISO9796d2Signer signer = new ISO9796d2Signer(rsaEngine, digest, false); // sign signer.init(true, privParams); signer.update(challenge, 0, challenge.length); byte[] sig = signer.generateSignature(); // verify signer.init(false, pubParams); signer.update(challenge, 0, challenge.length); if (!signer.verifySignature(sig)) { fail("basic verification failed"); } // === LETS ACTUALLY DO SOME RECOVERY, USING INPUT FROM INTERNAL AUTHENTICATE === signer.reset(); final String args0 = "482E20D1EDDED34359C38F5E7C01203F9D6B2641CDCA5C404D49ADAEDE034C7481D781D043722587761C90468DE69C6585A1E8B9C322F90E1B580EEDAB3F6007D0C366CF92B4DB8B41C8314929DCE2BE889C0129123484D2FD3D12763D2EBFD12AC8E51D7061AFCA1A53DEDEC7B9A617472A78C952CCC72467AE008E5F132994"; digest = new SHA1Digest(); signer = new ISO9796d2Signer(rsaEngine, digest, true); signer.init(false, pubParams); final byte[] signature = Hex.decode(args0); signer.updateWithRecoveredMessage(signature); signer.update(challenge, 0, challenge.length); if (!signer.verifySignature(signature)) { fail("recovered + challenge signature failed"); } // === FINALLY, USING SHA-256 === signer.reset(); digest = new SHA256Digest(); // NOTE setting implit to false does not actually do anything for verification !!! signer = new ISO9796d2Signer(rsaEngine, digest, false); signer.init(true, privParams); // generate NONCE of correct length using some inner knowledge int nonceLength = modulus.bitLength() / 8 - 1 - digest.getDigestSize() - 2; final byte[] nonce = new byte[nonceLength]; SecureRandom rnd = new SecureRandom(); rnd.nextBytes(nonce); signer.update(nonce, 0, nonce.length); signer.update(challenge, 0, challenge.length); byte[] sig3 = signer.generateSignature(); signer.init(false, pubParams); signer.updateWithRecoveredMessage(sig3); signer.update(challenge, 0, challenge.length); if (signer.verifySignature(sig3)) { if (signer.hasFullMessage()) { fail("signer indicates full message"); } byte[] recoverableMessage = signer.getRecoveredMessage(); // sanity check, normally the nonce is ignored in eMRTD specs (PKI Technical Report) if (!Arrays.areEqual(nonce, recoverableMessage)) { fail("Nonce compare with recoverable part of message failed"); } } else { fail("recoverable + nonce failed."); } } private static final byte[] longMessage = Base64.decode( "VVNIKzErU0U2ODAxNTMyOTcxOSsyKzErNisyKzErMTo6OTk5OTk5OTk5OTk5" + "OTo6OSsyOjo3Nzc3Nzc3Nzc3Nzc3Ojo5Kys1OjIwMTMwNDA1OjExMzUyMCdV" + "U0ErMTo6OjE2OjEnVVNDKzRmYjk3YzFhNDI5ZGIyZDYnVVNBKzY6MTY6MTox" + "MDoxKzE0OjIwNDgrMTI6/vn3S0h96eNhfmPN6OZUxXhd815h0tP871Hl+V1r" + "fHHUXvrPXmjHV0vdb8fYY1zxwvnQUcFBWXT43PFi7Xbow0/9e9l6/mhs1UJq" + "VPvp+ELbeXfn4Nj02ttk0e3H5Hfa69NYRuHv1WBO6lfizNnM9m9XYmh9TOrg" + "f9rDRtd+ZNbf4lz9fPTt9OXyxOJWRPr/0FLzxUVsddplfHxM3ndETFD7ffjI" + "/mhRYuL8WXZ733LeWFRCeOzKzmDz/HvT3GZx/XJMbFpqyOZjedzh6vZr1vrD" + "615TQfN7wtJJ29bN2Hvzb2f1xGHaXl7af0/w9dpR2dr7/HzuZEJKYc7JSkv4" + "/k37yERIbcrfbVTeVtR+dcVoeeRT41fmzMfzf8RnWOX4YMNifl0rMTM68EFA" + "QSdCR00rMzgwKzk5OTk5OTk5J0RUTSsxMzc6MjAxMzA0MDU6MTAyJ0ZUWCtB" + "QUkrKytJTlZPSUNFIFRFU1QnUkZGK09OOjEyMzQ1NidSRkYrRFE6MjIyMjIy" + "MjIyJ0RUTSsxNzE6MjAxMzA0MDE6MTAyJ05BRCtTVSs5OTk5OTk5OTk5OTk5" + "Ojo5KytURVNUIFNVUFBMSUVSOjpUcmFzZSByZWdpc3RlciBYWFhYWFhYK1Rl" + "c3QgYWRkcmVzcyBzdXBwbGllcitDaXR5KysxMjM0NStERSdSRkYrVkE6QTEy" + "MzQ1Njc4J05BRCtTQ08rOTk5OTk5OTk5OTk5OTo6OSsrVEVTVCBTVVBQTElF" + "Ujo6VHJhc2UgcmVnaXN0ZXIgWFhYWFhYWCtUZXN0IGFkZHJlc3Mgc3VwcGxp" + "ZXIrQ2l0eSsrMTIzNDUrREUnUkZGK1ZBOkExMjM0NTY3OCdOQUQrQlkrODg4" + "ODg4ODg4ODg4ODo6OSdOQUQrSVYrNzc3Nzc3Nzc3Nzc3Nzo6OSsrVEVTVCBC" + "VVlFUitUZXN0IGFkZHJlc3MgYnV5ZXIrQ2l0eTIrKzU0MzIxK0RFJ1JGRitW" + "QTpKODc2NTQzMjEnTkFEK0JDTys3Nzc3Nzc3Nzc3Nzc3Ojo5KytURVNUIEJV" + "WUVSK1Rlc3QgYWRkcmVzcyBidXllcitDaXR5MisrNTQzMjErREUnUkZGK1ZB" + "Oko4NzY1NDMyMSdOQUQrRFArODg4ODg4ODg4ODg4ODo6OSdOQUQrUFIrNzc3" + "Nzc3Nzc3Nzc3Nzo6OSdDVVgrMjpFVVI6NCdQQVQrMzUnRFRNKzEzOjIwMTMw" + "NjI0OjEwMidMSU4rMSsrMTExMTExMTExMTExMTpFTidQSUErMStBQUFBQUFB" + "OlNBJ0lNRCtGK00rOjo6UFJPRFVDVCBURVNUIDEnUVRZKzQ3OjEwLjAwMCdN" + "T0ErNjY6Ny4wMCdQUkkrQUFCOjEuMDAnUFJJK0FBQTowLjcwJ1JGRitPTjox" + "MjM0NTYnUkZGK0RROjIyMjIyMjIyMidUQVgrNytWQVQrKys6OjoyMS4wMDAn" + "QUxDK0ErKysxK1REJ1BDRCsxOjMwLjAwMCdNT0ErMjA0OjMuMDAnTElOKzIr" + "KzIyMjIyMjIyMjIyMjI6RU4nUElBKzErQkJCQkJCQjpTQSdJTUQrRitNKzo6" + "OlBST0RVQ1QgVEVTVCAyJ1FUWSs0NzoyMC4wMDAnTU9BKzY2OjgwLjAwJ1BS" + "SStBQUI6NS4wMCdQUkkrQUFBOjQuMDAnUkZGK09OOjEyMzQ1NidSRkYrRFE6" + "MjIyMjIyMjIyJ1RBWCs3K1ZBVCsrKzo6OjIxLjAwMCdBTEMrQSsrKzErVEQn" + "UENEKzE6MjAuMDAwJ01PQSsyMDQ6MjAuMDAnVU5TK1MnQ05UKzI6MidNT0Er" + "Nzk6ODcuMDAnTU9BKzEzOToxMDUuMjcnTU9BKzEyNTo4Ny4wMCdNT0ErMjYw" + "OjAuMDAnTU9BKzI1OTowLjAwJ01PQSsxNzY6MTguMjcnVEFYKzcrVkFUKysr" + "Ojo6MjEuMDAwJ01PQSsxNzY6MTguMjcnTU9BKzEyNTo4Ny4wMCc="); private static final byte[] shortPartialSig = Base64.decode( "sb8yyKk6HM1cJhICScMx7QRQunRyrZ1fbI42+T+TBGNjOknvzKuvG7aftGX7" + "O/RXuYgk6LTxpXv7+O5noUhMBsR2PKaHveuylU1WSPmDxDCui3kp4frqVH0w" + "8Vjpl5CsKqBsmKkbGCKE+smM0xFXhYxV8QUTB2XsWNCQiFiHPgwbpfWzZUNY" + "QPWd0A99P64EuUIYz1tkkDnLFmwQ19/PJu1a8orIQInmkVYWSsBsZ/7Ks6lx" + "nDHpAvgiRe+OXmJ/yuQy1O3FJYdyoqvjYRPBu3qYeBK9+9L3lExLilImH5aD" + "nJznaXcO8QFOxVPbrF2s4GdPIMDonEyAHdrnzoghlg=="); private void doShortPartialTest() throws Exception { byte[] recovered = Hex.decode("5553482b312b534536383031353332393731392b322b312b362b322b312b313a3a393939393939393939393939393a3a392b323a3a373737373737373737373737373a3a392b2b353a32303133303430353a313133"); BigInteger exp = new BigInteger("10001", 16); BigInteger mod = new BigInteger("b9b70b083da9e37e23cde8e654855db31e21d2d3fc11a5f91d2b3c311efa8f5e28c757dd6fc798631cb1b9d051c14119749cb122ad76e8c3fd7bd93abe282c026a14fba9f8023977a7a0d8b49a24d1ad87e4379a931846a1ef9520ea57e28c998cf65722683d0caaa0da8306973e2496a25cbd3cb4adb4b284e25604fabf12f385456c75da7c3c4cde37440cfb7db8c8fe6851e2bc59767b9f7218540238ac8acef3bc7bd3dc6671320c2c1a2ac8a6799ce1eaf62b9683ab1e1341b37b9249dbd6cd987b2f27b5c4619a1eda7f0fb0b59a519afbbc3cee640261cec90a4bb8fefbc844082dca9f549e56943e758579a453a357e6ccb37fc46718a5b8c3227e5d", 16); AsymmetricKeyParameter pubKey = new RSAKeyParameters(false, mod, exp); ISO9796d2PSSSigner pssSign = new ISO9796d2PSSSigner(new RSAEngine(), new SHA1Digest(), 20); pssSign.init(false, pubKey); pssSign.updateWithRecoveredMessage(shortPartialSig); pssSign.update(longMessage, pssSign.getRecoveredMessage().length, longMessage.length - pssSign.getRecoveredMessage().length); if (!pssSign.verifySignature(shortPartialSig)) { fail("short partial PSS sig verification failed."); } byte[] mm = pssSign.getRecoveredMessage(); if (!Arrays.areEqual(recovered, mm)) { fail("short partial PSS recovery failed"); } } private void doFullMessageTest() throws Exception { BigInteger modulus = new BigInteger(1, Hex.decode("CDCBDABBF93BE8E8294E32B055256BBD0397735189BF75816341BB0D488D05D627991221DF7D59835C76A4BB4808ADEEB779E7794504E956ADC2A661B46904CDC71337DD29DDDD454124EF79CFDD7BC2C21952573CEFBA485CC38C6BD2428809B5A31A898A6B5648CAA4ED678D9743B589134B7187478996300EDBA16271A861")); BigInteger pubExp = new BigInteger(1, Hex.decode("010001")); BigInteger privExp = new BigInteger(1, Hex.decode("4BA6432AD42C74AA5AFCB6DF60FD57846CBC909489994ABD9C59FE439CC6D23D6DE2F3EA65B8335E796FD7904CA37C248367997257AFBD82B26F1A30525C447A236C65E6ADE43ECAAF7283584B2570FA07B340D9C9380D88EAACFFAEEFE7F472DBC9735C3FF3A3211E8A6BBFD94456B6A33C17A2C4EC18CE6335150548ED126D")); RSAKeyParameters pubParams = new RSAKeyParameters(false, modulus, pubExp); RSAKeyParameters privParams = new RSAKeyParameters(true, modulus, privExp); AsymmetricBlockCipher rsaEngine = new RSABlindedEngine(); // set challenge to all zero's for verification byte[] challenge = new byte[8]; ISO9796d2PSSSigner pssSign = new ISO9796d2PSSSigner(new RSAEngine(), new SHA256Digest(), 20, true); pssSign.init(true, privParams); pssSign.update(challenge, 0, challenge.length); byte[] sig = pssSign.generateSignature(); pssSign.init(false, pubParams); pssSign.updateWithRecoveredMessage(sig); if (!pssSign.verifySignature(sig)) { fail("challenge PSS sig verification failed."); } byte[] mm = pssSign.getRecoveredMessage(); if (!Arrays.areEqual(challenge, mm)) { fail("challenge partial PSS recovery failed"); } } public void performTest() throws Exception { doTest1(); doTest2(); doTest3(); doTest4(); doTest5(); doTest6(); doTest7(); doTest8(); doTest9(); doTest10(); doTest11(); doTest12(); doTest13(); doShortPartialTest(); doFullMessageTest(); } public static void main( String[] args) { runTest(new ISO9796Test()); } } bouncycastle-1.49.orig/test/src/org/bouncycastle/crypto/test/RijndaelTest.java0000644000175000017500000002151110525306762027221 0ustar ebourgebourgpackage org.bouncycastle.crypto.test; import org.bouncycastle.crypto.engines.RijndaelEngine; import org.bouncycastle.crypto.params.KeyParameter; import org.bouncycastle.util.encoders.Hex; import org.bouncycastle.util.test.SimpleTest; /** * Test vectors from the NIST standard tests and Brian Gladman's vector set * * http://fp.gladman.plus.com/cryptography_technology/rijndael/ */ public class RijndaelTest extends CipherTest { static SimpleTest[] tests = { new BlockCipherVectorTest(0, new RijndaelEngine(128), new KeyParameter(Hex.decode("80000000000000000000000000000000")), "00000000000000000000000000000000", "0EDD33D3C621E546455BD8BA1418BEC8"), new BlockCipherVectorTest(1, new RijndaelEngine(128), new KeyParameter(Hex.decode("00000000000000000000000000000080")), "00000000000000000000000000000000", "172AEAB3D507678ECAF455C12587ADB7"), new BlockCipherMonteCarloTest(2, 10000, new RijndaelEngine(128), new KeyParameter(Hex.decode("00000000000000000000000000000000")), "00000000000000000000000000000000", "C34C052CC0DA8D73451AFE5F03BE297F"), new BlockCipherMonteCarloTest(3, 10000, new RijndaelEngine(128), new KeyParameter(Hex.decode("5F060D3716B345C253F6749ABAC10917")), "355F697E8B868B65B25A04E18D782AFA", "ACC863637868E3E068D2FD6E3508454A"), new BlockCipherVectorTest(4, new RijndaelEngine(128), new KeyParameter(Hex.decode("000000000000000000000000000000000000000000000000")), "80000000000000000000000000000000", "6CD02513E8D4DC986B4AFE087A60BD0C"), new BlockCipherMonteCarloTest(5, 10000, new RijndaelEngine(128), new KeyParameter(Hex.decode("AAFE47EE82411A2BF3F6752AE8D7831138F041560631B114")), "F3F6752AE8D7831138F041560631B114", "77BA00ED5412DFF27C8ED91F3C376172"), new BlockCipherVectorTest(6, new RijndaelEngine(128), new KeyParameter(Hex.decode("0000000000000000000000000000000000000000000000000000000000000000")), "80000000000000000000000000000000", "DDC6BF790C15760D8D9AEB6F9A75FD4E"), new BlockCipherMonteCarloTest(7, 10000, new RijndaelEngine(128), new KeyParameter(Hex.decode("28E79E2AFC5F7745FCCABE2F6257C2EF4C4EDFB37324814ED4137C288711A386")), "C737317FE0846F132B23C8C2A672CE22", "E58B82BFBA53C0040DC610C642121168"), new BlockCipherVectorTest(8, new RijndaelEngine(160), new KeyParameter(Hex.decode("2b7e151628aed2a6abf7158809cf4f3c")), "3243f6a8885a308d313198a2e03707344a409382", "16e73aec921314c29df905432bc8968ab64b1f51"), new BlockCipherVectorTest(8, new RijndaelEngine(160), new KeyParameter(Hex.decode("2b7e151628aed2a6abf7158809cf4f3c762e7160")), "3243f6a8885a308d313198a2e03707344a409382", "0553eb691670dd8a5a5b5addf1aa7450f7a0e587"), new BlockCipherVectorTest(8, new RijndaelEngine(160), new KeyParameter(Hex.decode("2b7e151628aed2a6abf7158809cf4f3c762e7160f38b4da5")), "3243f6a8885a308d313198a2e03707344a409382", "73cd6f3423036790463aa9e19cfcde894ea16623"), new BlockCipherVectorTest(8, new RijndaelEngine(160), new KeyParameter(Hex.decode("2b7e151628aed2a6abf7158809cf4f3c762e7160f38b4da56a784d90")), "3243f6a8885a308d313198a2e03707344a409382", "601b5dcd1cf4ece954c740445340bf0afdc048df"), new BlockCipherVectorTest(8, new RijndaelEngine(160), new KeyParameter(Hex.decode("2b7e151628aed2a6abf7158809cf4f3c762e7160f38b4da56a784d9045190cfe")), "3243f6a8885a308d313198a2e03707344a409382", "579e930b36c1529aa3e86628bacfe146942882cf"), new BlockCipherVectorTest(8, new RijndaelEngine(192), new KeyParameter(Hex.decode("2b7e151628aed2a6abf7158809cf4f3c")), "3243f6a8885a308d313198a2e03707344a4093822299f31d", "b24d275489e82bb8f7375e0d5fcdb1f481757c538b65148a"), new BlockCipherVectorTest(9, new RijndaelEngine(192), new KeyParameter(Hex.decode("2b7e151628aed2a6abf7158809cf4f3c762e7160f38b4da5")), "3243f6a8885a308d313198a2e03707344a4093822299f31d", "725ae43b5f3161de806a7c93e0bca93c967ec1ae1b71e1cf"), new BlockCipherVectorTest(10, new RijndaelEngine(192), new KeyParameter(Hex.decode("2b7e151628aed2a6abf7158809cf4f3c762e7160f38b4da56a784d90")), "3243f6a8885a308d313198a2e03707344a4093822299f31d", "bbfc14180afbf6a36382a061843f0b63e769acdc98769130"), new BlockCipherVectorTest(11, new RijndaelEngine(192), new KeyParameter(Hex.decode("2b7e151628aed2a6abf7158809cf4f3c762e7160f38b4da56a784d9045190cfe")), "3243f6a8885a308d313198a2e03707344a4093822299f31d", "0ebacf199e3315c2e34b24fcc7c46ef4388aa475d66c194c"), new BlockCipherVectorTest(12, new RijndaelEngine(224), new KeyParameter(Hex.decode("2b7e151628aed2a6abf7158809cf4f3c")), "3243f6a8885a308d313198a2e03707344a4093822299f31d0082efa9", "b0a8f78f6b3c66213f792ffd2a61631f79331407a5e5c8d3793aceb1"), new BlockCipherVectorTest(13, new RijndaelEngine(224), new KeyParameter(Hex.decode("2b7e151628aed2a6abf7158809cf4f3c762e7160")), "3243f6a8885a308d313198a2e03707344a4093822299f31d0082efa9", "08b99944edfce33a2acb131183ab0168446b2d15e958480010f545e3"), new BlockCipherVectorTest(14, new RijndaelEngine(224), new KeyParameter(Hex.decode("2b7e151628aed2a6abf7158809cf4f3c762e7160f38b4da5")), "3243f6a8885a308d313198a2e03707344a4093822299f31d0082efa9", "be4c597d8f7efe22a2f7e5b1938e2564d452a5bfe72399c7af1101e2"), new BlockCipherVectorTest(15, new RijndaelEngine(224), new KeyParameter(Hex.decode("2b7e151628aed2a6abf7158809cf4f3c762e7160f38b4da56a784d90")), "3243f6a8885a308d313198a2e03707344a4093822299f31d0082efa9", "ef529598ecbce297811b49bbed2c33bbe1241d6e1a833dbe119569e8"), new BlockCipherVectorTest(16, new RijndaelEngine(224), new KeyParameter(Hex.decode("2b7e151628aed2a6abf7158809cf4f3c762e7160f38b4da56a784d9045190cfe")), "3243f6a8885a308d313198a2e03707344a4093822299f31d0082efa9", "02fafc200176ed05deb8edb82a3555b0b10d47a388dfd59cab2f6c11"), new BlockCipherVectorTest(17, new RijndaelEngine(256), new KeyParameter(Hex.decode("2b7e151628aed2a6abf7158809cf4f3c")), "3243f6a8885a308d313198a2e03707344a4093822299f31d0082efa98ec4e6c8", "7d15479076b69a46ffb3b3beae97ad8313f622f67fedb487de9f06b9ed9c8f19"), new BlockCipherVectorTest(18, new RijndaelEngine(256), new KeyParameter(Hex.decode("2b7e151628aed2a6abf7158809cf4f3c762e7160")), "3243f6a8885a308d313198a2e03707344a4093822299f31d0082efa98ec4e6c8", "514f93fb296b5ad16aa7df8b577abcbd484decacccc7fb1f18dc567309ceeffd"), new BlockCipherVectorTest(19, new RijndaelEngine(256), new KeyParameter(Hex.decode("2b7e151628aed2a6abf7158809cf4f3c762e7160f38b4da5")), "3243f6a8885a308d313198a2e03707344a4093822299f31d0082efa98ec4e6c8", "5d7101727bb25781bf6715b0e6955282b9610e23a43c2eb062699f0ebf5887b2"), new BlockCipherVectorTest(20, new RijndaelEngine(256), new KeyParameter(Hex.decode("2b7e151628aed2a6abf7158809cf4f3c762e7160f38b4da56a784d90")), "3243f6a8885a308d313198a2e03707344a4093822299f31d0082efa98ec4e6c8", "d56c5a63627432579e1dd308b2c8f157b40a4bfb56fea1377b25d3ed3d6dbf80"), new BlockCipherVectorTest(21, new RijndaelEngine(256), new KeyParameter(Hex.decode("2b7e151628aed2a6abf7158809cf4f3c762e7160f38b4da56a784d9045190cfe")), "3243f6a8885a308d313198a2e03707344a4093822299f31d0082efa98ec4e6c8", "a49406115dfb30a40418aafa4869b7c6a886ff31602a7dd19c889dc64f7e4e7a") }; RijndaelTest() { super(tests, new RijndaelEngine(128), new KeyParameter(new byte[16])); } public String getName() { return "Rijndael"; } public static void main( String[] args) { runTest(new RijndaelTest()); } } bouncycastle-1.49.orig/test/src/org/bouncycastle/crypto/test/DHTest.java0000644000175000017500000003477111562112303025764 0ustar ebourgebourgpackage org.bouncycastle.crypto.test; import java.math.BigInteger; import java.security.SecureRandom; import org.bouncycastle.crypto.AsymmetricCipherKeyPair; import org.bouncycastle.crypto.agreement.DHAgreement; import org.bouncycastle.crypto.agreement.DHBasicAgreement; import org.bouncycastle.crypto.generators.DHBasicKeyPairGenerator; import org.bouncycastle.crypto.generators.DHKeyPairGenerator; import org.bouncycastle.crypto.generators.DHParametersGenerator; import org.bouncycastle.crypto.params.DHKeyGenerationParameters; import org.bouncycastle.crypto.params.DHParameters; import org.bouncycastle.crypto.params.DHPrivateKeyParameters; import org.bouncycastle.crypto.params.DHPublicKeyParameters; import org.bouncycastle.crypto.params.ParametersWithRandom; import org.bouncycastle.util.test.SimpleTest; public class DHTest extends SimpleTest { private BigInteger g512 = new BigInteger("153d5d6172adb43045b68ae8e1de1070b6137005686d29d3d73a7749199681ee5b212c9b96bfdcfa5b20cd5e3fd2044895d609cf9b410b7a0f12ca1cb9a428cc", 16); private BigInteger p512 = new BigInteger("9494fec095f3b85ee286542b3836fc81a5dd0a0349b4c239dd38744d488cf8e31db8bcb7d33b41abb9e5a33cca9144b1cef332c94bf0573bf047a3aca98cdf3b", 16); private BigInteger g768 = new BigInteger("7c240073c1316c621df461b71ebb0cdcc90a6e5527e5e126633d131f87461c4dc4afc60c2cb0f053b6758871489a69613e2a8b4c8acde23954c08c81cbd36132cfd64d69e4ed9f8e51ed6e516297206672d5c0a69135df0a5dcf010d289a9ca1", 16); private BigInteger p768 = new BigInteger("8c9dd223debed1b80103b8b309715be009d48860ed5ae9b9d5d8159508efd802e3ad4501a7f7e1cfec78844489148cd72da24b21eddd01aa624291c48393e277cfc529e37075eccef957f3616f962d15b44aeab4039d01b817fde9eaa12fd73f", 16); private BigInteger g1024 = new BigInteger("1db17639cdf96bc4eabba19454f0b7e5bd4e14862889a725c96eb61048dcd676ceb303d586e30f060dbafd8a571a39c4d823982117da5cc4e0f89c77388b7a08896362429b94a18a327604eb7ff227bffbc83459ade299e57b5f77b50fb045250934938efa145511166e3197373e1b5b1e52de713eb49792bedde722c6717abf", 16); private BigInteger p1024 = new BigInteger("a00e283b3c624e5b2b4d9fbc2653b5185d99499b00fd1bf244c6f0bb817b4d1c451b2958d62a0f8a38caef059fb5ecd25d75ed9af403f5b5bdab97a642902f824e3c13789fed95fa106ddfe0ff4a707c85e2eb77d49e68f2808bcea18ce128b178cd287c6bc00efa9a1ad2a673fe0dceace53166f75b81d6709d5f8af7c66bb7", 16); public String getName() { return "DH"; } private void testDH( int size, BigInteger g, BigInteger p) { DHKeyPairGenerator kpGen = getDHKeyPairGenerator(g, p); // // generate first pair // AsymmetricCipherKeyPair pair = kpGen.generateKeyPair(); DHPublicKeyParameters pu1 = (DHPublicKeyParameters)pair.getPublic(); DHPrivateKeyParameters pv1 = (DHPrivateKeyParameters)pair.getPrivate(); // // generate second pair // pair = kpGen.generateKeyPair(); DHPublicKeyParameters pu2 = (DHPublicKeyParameters)pair.getPublic(); DHPrivateKeyParameters pv2 = (DHPrivateKeyParameters)pair.getPrivate(); // // two way // DHAgreement e1 = new DHAgreement(); DHAgreement e2 = new DHAgreement(); e1.init(pv1); e2.init(pv2); BigInteger m1 = e1.calculateMessage(); BigInteger m2 = e2.calculateMessage(); BigInteger k1 = e1.calculateAgreement(pu2, m2); BigInteger k2 = e2.calculateAgreement(pu1, m1); if (!k1.equals(k2)) { fail(size + " bit 2-way test failed"); } } private void testDHBasic( int size, int privateValueSize, BigInteger g, BigInteger p) { DHBasicKeyPairGenerator kpGen = getDHBasicKeyPairGenerator(g, p, privateValueSize); // // generate first pair // AsymmetricCipherKeyPair pair = kpGen.generateKeyPair(); DHPublicKeyParameters pu1 = (DHPublicKeyParameters)pair.getPublic(); DHPrivateKeyParameters pv1 = (DHPrivateKeyParameters)pair.getPrivate(); checkKeySize(privateValueSize, pv1); // // generate second pair // pair = kpGen.generateKeyPair(); DHPublicKeyParameters pu2 = (DHPublicKeyParameters)pair.getPublic(); DHPrivateKeyParameters pv2 = (DHPrivateKeyParameters)pair.getPrivate(); checkKeySize(privateValueSize, pv2); // // two way // DHBasicAgreement e1 = new DHBasicAgreement(); DHBasicAgreement e2 = new DHBasicAgreement(); e1.init(pv1); e2.init(pv2); BigInteger k1 = e1.calculateAgreement(pu2); BigInteger k2 = e2.calculateAgreement(pu1); if (!k1.equals(k2)) { fail("basic " + size + " bit 2-way test failed"); } } private void checkKeySize( int privateValueSize, DHPrivateKeyParameters priv) { if (privateValueSize != 0) { if (priv.getX().bitLength() != privateValueSize) { fail("limited key check failed for key size " + privateValueSize); } } } private void testGPWithRandom( DHKeyPairGenerator kpGen) { // // generate first pair // AsymmetricCipherKeyPair pair = kpGen.generateKeyPair(); DHPublicKeyParameters pu1 = (DHPublicKeyParameters)pair.getPublic(); DHPrivateKeyParameters pv1 = (DHPrivateKeyParameters)pair.getPrivate(); // // generate second pair // pair = kpGen.generateKeyPair(); DHPublicKeyParameters pu2 = (DHPublicKeyParameters)pair.getPublic(); DHPrivateKeyParameters pv2 = (DHPrivateKeyParameters)pair.getPrivate(); // // two way // DHAgreement e1 = new DHAgreement(); DHAgreement e2 = new DHAgreement(); e1.init(new ParametersWithRandom(pv1, new SecureRandom())); e2.init(new ParametersWithRandom(pv2, new SecureRandom())); BigInteger m1 = e1.calculateMessage(); BigInteger m2 = e2.calculateMessage(); BigInteger k1 = e1.calculateAgreement(pu2, m2); BigInteger k2 = e2.calculateAgreement(pu1, m1); if (!k1.equals(k2)) { fail("basic with random 2-way test failed"); } } private void testSimpleWithRandom( DHBasicKeyPairGenerator kpGen) { // // generate first pair // AsymmetricCipherKeyPair pair = kpGen.generateKeyPair(); DHPublicKeyParameters pu1 = (DHPublicKeyParameters)pair.getPublic(); DHPrivateKeyParameters pv1 = (DHPrivateKeyParameters)pair.getPrivate(); // // generate second pair // pair = kpGen.generateKeyPair(); DHPublicKeyParameters pu2 = (DHPublicKeyParameters)pair.getPublic(); DHPrivateKeyParameters pv2 = (DHPrivateKeyParameters)pair.getPrivate(); // // two way // DHBasicAgreement e1 = new DHBasicAgreement(); DHBasicAgreement e2 = new DHBasicAgreement(); e1.init(new ParametersWithRandom(pv1, new SecureRandom())); e2.init(new ParametersWithRandom(pv2, new SecureRandom())); BigInteger k1 = e1.calculateAgreement(pu2); BigInteger k2 = e2.calculateAgreement(pu1); if (!k1.equals(k2)) { fail("basic with random 2-way test failed"); } } private DHBasicKeyPairGenerator getDHBasicKeyPairGenerator( BigInteger g, BigInteger p, int privateValueSize) { DHParameters dhParams = new DHParameters(p, g, null, privateValueSize); DHKeyGenerationParameters params = new DHKeyGenerationParameters(new SecureRandom(), dhParams); DHBasicKeyPairGenerator kpGen = new DHBasicKeyPairGenerator(); kpGen.init(params); return kpGen; } private DHKeyPairGenerator getDHKeyPairGenerator( BigInteger g, BigInteger p) { DHParameters dhParams = new DHParameters(p, g); DHKeyGenerationParameters params = new DHKeyGenerationParameters(new SecureRandom(), dhParams); DHKeyPairGenerator kpGen = new DHKeyPairGenerator(); kpGen.init(params); return kpGen; } /** * this test is can take quiet a while */ private void testGeneration( int size) { DHParametersGenerator pGen = new DHParametersGenerator(); pGen.init(size, 10, new SecureRandom()); DHParameters dhParams = pGen.generateParameters(); if (dhParams.getL() != 0) { fail("DHParametersGenerator failed to set J to 0 in generated DHParameters"); } DHKeyGenerationParameters params = new DHKeyGenerationParameters(new SecureRandom(), dhParams); DHBasicKeyPairGenerator kpGen = new DHBasicKeyPairGenerator(); kpGen.init(params); // // generate first pair // AsymmetricCipherKeyPair pair = kpGen.generateKeyPair(); DHPublicKeyParameters pu1 = (DHPublicKeyParameters)pair.getPublic(); DHPrivateKeyParameters pv1 = (DHPrivateKeyParameters)pair.getPrivate(); // // generate second pair // params = new DHKeyGenerationParameters(new SecureRandom(), pu1.getParameters()); kpGen.init(params); pair = kpGen.generateKeyPair(); DHPublicKeyParameters pu2 = (DHPublicKeyParameters)pair.getPublic(); DHPrivateKeyParameters pv2 = (DHPrivateKeyParameters)pair.getPrivate(); // // two way // DHBasicAgreement e1 = new DHBasicAgreement(); DHBasicAgreement e2 = new DHBasicAgreement(); e1.init(new ParametersWithRandom(pv1, new SecureRandom())); e2.init(new ParametersWithRandom(pv2, new SecureRandom())); BigInteger k1 = e1.calculateAgreement(pu2); BigInteger k2 = e2.calculateAgreement(pu1); if (!k1.equals(k2)) { fail("basic with " + size + " bit 2-way test failed"); } } private void testBounds() { BigInteger p1 = new BigInteger("00C8028E9151C6B51BCDB35C1F6B2527986A72D8546AE7A4BF41DC4289FF9837EE01592D36C324A0F066149B8B940C86C87D194206A39038AE3396F8E12435BB74449B70222D117B8A2BB77CB0D67A5D664DDE7B75E0FEC13CE0CAF258DAF3ADA0773F6FF0F2051D1859929AAA53B07809E496B582A89C3D7DA8B6E38305626621", 16); BigInteger g1 = new BigInteger("1F869713181464577FE4026B47102FA0D7675503A4FCDA810881FAEC3524E6DBAEA9B96561EF7F8BEA76466DF11C2F3EB1A90CC5851735BF860606481257EECE6418C0204E61004E85D7131CE54BCBC7AD67E53C79DCB715E7C8D083DCD85D728283EC8F96839B4C9FA7C0727C472BEB94E4613CAFA8D580119C0AF4BF8AF252", 16); int l1 = 1023; BigInteger p2 = new BigInteger("00B333C98720220CC3946F494E25231B3E19F9AD5F6B19F4E7ABF80D8826C491C3224D4F7415A14A7C11D1BE584405FED12C3554F103E56A72D986CA5E325BB9DE07AC37D1EAE5E5AC724D32EF638F0E4462D4C1FC7A45B9FD3A5DF5EC36A1FA4DAA3FBB66AA42B1B71DF416AB547E987513426C7BB8634F5F4D37705514FDC1E1", 16); BigInteger g2 = new BigInteger("2592F5A99FE46313650CCE66C94C15DBED9F4A45BD05C329986CF5D3E12139F0405A47C6385FEA27BFFEDC4CBABC5BB151F3BEE7CC3D51567F1E2B12A975AA9F48A70BDAAE7F5B87E70ADCF902490A3CBEFEDA41EBA8E12E02B56120B5FDEFBED07F5EAD3AE020DF3C8233216F8F0D35E13A7AE4DA5CBCC0D91EADBF20C281C6", 16); int l2 = 1024; DHKeyGenerationParameters params1 = new DHKeyGenerationParameters(new SecureRandom(), new DHParameters(p1, g1, null, l1)); DHKeyGenerationParameters params2 = new DHKeyGenerationParameters(new SecureRandom(), new DHParameters(p2, g2, null, l2)); DHBasicKeyPairGenerator kpGen = new DHBasicKeyPairGenerator(); kpGen.init(params1); kpGen.init(params2); } public void performTest() { testDHBasic(512, 0, g512, p512); testDHBasic(768, 0, g768, p768); testDHBasic(1024, 0, g1024, p1024); testDHBasic(512, 64, g512, p512); testDHBasic(768, 128, g768, p768); testDHBasic(1024, 256, g1024, p1024); testDH(512, g512, p512); testDH(768, g768, p768); testDH(1024, g1024, p1024); testBounds(); // // generation test. // testGeneration(256); // // with random test // DHBasicKeyPairGenerator kpBasicGen = getDHBasicKeyPairGenerator(g512, p512, 0); testSimpleWithRandom(kpBasicGen); DHKeyPairGenerator kpGen = getDHKeyPairGenerator(g512, p512); testGPWithRandom(kpGen); // // parameter tests // DHAgreement dh = new DHAgreement(); AsymmetricCipherKeyPair dhPair = kpGen.generateKeyPair(); try { dh.init(dhPair.getPublic()); fail("DHAgreement key check failed"); } catch (IllegalArgumentException e) { // ignore } DHKeyPairGenerator kpGen768 = getDHKeyPairGenerator(g768, p768); try { dh.init(dhPair.getPrivate()); dh.calculateAgreement((DHPublicKeyParameters)kpGen768.generateKeyPair().getPublic(), BigInteger.valueOf(100)); fail("DHAgreement agreement check failed"); } catch (IllegalArgumentException e) { // ignore } DHBasicAgreement dhBasic = new DHBasicAgreement(); AsymmetricCipherKeyPair dhBasicPair = kpBasicGen.generateKeyPair(); try { dhBasic.init(dhBasicPair.getPublic()); fail("DHBasicAgreement key check failed"); } catch (IllegalArgumentException e) { // expected } DHBasicKeyPairGenerator kpBasicGen768 = getDHBasicKeyPairGenerator(g768, p768, 0); try { dhBasic.init(dhPair.getPrivate()); dhBasic.calculateAgreement((DHPublicKeyParameters)kpBasicGen768.generateKeyPair().getPublic()); fail("DHBasicAgreement agreement check failed"); } catch (IllegalArgumentException e) { // expected } } public static void main( String[] args) { runTest(new DHTest()); } } bouncycastle-1.49.orig/test/src/org/bouncycastle/crypto/test/HashCommitmentTest.java0000644000175000017500000000335012150003626030377 0ustar ebourgebourgpackage org.bouncycastle.crypto.test; import java.security.SecureRandom; import org.bouncycastle.crypto.Commitment; import org.bouncycastle.crypto.Committer; import org.bouncycastle.crypto.DataLengthException; import org.bouncycastle.crypto.commitments.HashCommitter; import org.bouncycastle.crypto.digests.SHA1Digest; import org.bouncycastle.crypto.digests.SHA256Digest; import org.bouncycastle.util.encoders.Hex; import org.bouncycastle.util.test.SimpleTest; public class HashCommitmentTest extends SimpleTest { public String getName() { return "HashCommitmentTest"; } public void performTest() throws Exception { byte[] data = Hex.decode("4e6f77206973207468652074696d6520666f7220616c6c20"); Committer committer = new HashCommitter(new SHA256Digest(), new SecureRandom()); Commitment c = committer.commit(data); committer = new HashCommitter(new SHA256Digest(), new SecureRandom()); if (!committer.isRevealed(c, data)) { fail("commitment failed to validate"); } committer = new HashCommitter(new SHA1Digest(), new SecureRandom()); if (committer.isRevealed(c, data)) { fail("commitment validated!!"); } // SHA1 has a block size of 512 bits, try a message that's too big try { c = committer.commit(new byte[33]); } catch (DataLengthException e) { if (!e.getMessage().equals("Message to be committed to too large for digest.")) { fail("exception thrown but wrong message"); } } } public static void main(String[] args) { runTest(new HashCommitmentTest()); } } bouncycastle-1.49.orig/test/src/org/bouncycastle/crypto/test/RIPEMD128HMacTest.java0000644000175000017500000000601510330633061027424 0ustar ebourgebourgpackage org.bouncycastle.crypto.test; import org.bouncycastle.crypto.digests.RIPEMD128Digest; import org.bouncycastle.crypto.macs.HMac; import org.bouncycastle.crypto.params.KeyParameter; import org.bouncycastle.util.Arrays; import org.bouncycastle.util.encoders.Hex; import org.bouncycastle.util.test.SimpleTestResult; import org.bouncycastle.util.test.Test; import org.bouncycastle.util.test.TestResult; /** * RIPEMD128 HMac Test, test vectors from RFC 2286 */ public class RIPEMD128HMacTest implements Test { final static String[] keys = { "0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b", "4a656665", "aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa", "0102030405060708090a0b0c0d0e0f10111213141516171819", "0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c", "aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa", "aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa" }; final static String[] digests = { "fbf61f9492aa4bbf81c172e84e0734db", "875f828862b6b334b427c55f9f7ff09b", "09f0b2846d2f543da363cbec8d62a38d", "bdbbd7cf03e44b5aa60af815be4d2294", "e79808f24b25fd031c155f0d551d9a3a", "dc732928de98104a1f59d373c150acbb", "5c6bec96793e16d40690c237635f30c5" }; final static String[] messages = { "Hi There", "what do ya want for nothing?", "0xdddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddd", "0xcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcd", "Test With Truncation", "Test Using Larger Than Block-Size Key - Hash Key First", "Test Using Larger Than Block-Size Key and Larger Than One Block-Size Data" }; public String getName() { return "RIPEMD128HMac"; } public TestResult perform() { HMac hmac = new HMac(new RIPEMD128Digest()); byte[] resBuf = new byte[hmac.getMacSize()]; for (int i = 0; i < messages.length; i++) { byte[] m = messages[i].getBytes(); if (messages[i].startsWith("0x")) { m = Hex.decode(messages[i].substring(2)); } hmac.init(new KeyParameter(Hex.decode(keys[i]))); hmac.update(m, 0, m.length); hmac.doFinal(resBuf, 0); if (!Arrays.areEqual(resBuf, Hex.decode(digests[i]))) { return new SimpleTestResult(false, getName() + ": Vector " + i + " failed"); } } return new SimpleTestResult(true, getName() + ": Okay"); } public static void main( String[] args) { RIPEMD128HMacTest test = new RIPEMD128HMacTest(); TestResult result = test.perform(); System.out.println(result); } } bouncycastle-1.49.orig/test/src/org/bouncycastle/crypto/test/PSSTest.java0000644000175000017500000005353711521717165026153 0ustar ebourgebourgpackage org.bouncycastle.crypto.test; import java.math.BigInteger; import java.security.SecureRandom; import org.bouncycastle.crypto.digests.SHA1Digest; import org.bouncycastle.crypto.digests.SHA256Digest; import org.bouncycastle.crypto.engines.RSAEngine; import org.bouncycastle.crypto.params.ParametersWithRandom; import org.bouncycastle.crypto.params.RSAKeyParameters; import org.bouncycastle.crypto.params.RSAPrivateCrtKeyParameters; import org.bouncycastle.crypto.signers.PSSSigner; import org.bouncycastle.util.encoders.Hex; import org.bouncycastle.util.test.SimpleTest; /* * RSA PSS test vectors for PKCS#1 V2.1 */ public class PSSTest extends SimpleTest { private final int DATA_LENGTH = 1000; private final int NUM_TESTS = 500; private class FixedRandom extends SecureRandom { byte[] vals; FixedRandom( byte[] vals) { this.vals = vals; } public void nextBytes( byte[] bytes) { System.arraycopy(vals, 0, bytes, 0, vals.length); } } // // Example 1: A 1024-bit RSA keypair // private RSAKeyParameters pub1 = new RSAKeyParameters(false, new BigInteger("a56e4a0e701017589a5187dc7ea841d156f2ec0e36ad52a44dfeb1e61f7ad991d8c51056ffedb162b4c0f283a12a88a394dff526ab7291cbb307ceabfce0b1dfd5cd9508096d5b2b8b6df5d671ef6377c0921cb23c270a70e2598e6ff89d19f105acc2d3f0cb35f29280e1386b6f64c4ef22e1e1f20d0ce8cffb2249bd9a2137",16), new BigInteger("010001",16)); private RSAKeyParameters prv1 = new RSAPrivateCrtKeyParameters( new BigInteger("a56e4a0e701017589a5187dc7ea841d156f2ec0e36ad52a44dfeb1e61f7ad991d8c51056ffedb162b4c0f283a12a88a394dff526ab7291cbb307ceabfce0b1dfd5cd9508096d5b2b8b6df5d671ef6377c0921cb23c270a70e2598e6ff89d19f105acc2d3f0cb35f29280e1386b6f64c4ef22e1e1f20d0ce8cffb2249bd9a2137",16), new BigInteger("010001",16), new BigInteger("33a5042a90b27d4f5451ca9bbbd0b44771a101af884340aef9885f2a4bbe92e894a724ac3c568c8f97853ad07c0266c8c6a3ca0929f1e8f11231884429fc4d9ae55fee896a10ce707c3ed7e734e44727a39574501a532683109c2abacaba283c31b4bd2f53c3ee37e352cee34f9e503bd80c0622ad79c6dcee883547c6a3b325",16), new BigInteger("e7e8942720a877517273a356053ea2a1bc0c94aa72d55c6e86296b2dfc967948c0a72cbccca7eacb35706e09a1df55a1535bd9b3cc34160b3b6dcd3eda8e6443",16), new BigInteger("b69dca1cf7d4d7ec81e75b90fcca874abcde123fd2700180aa90479b6e48de8d67ed24f9f19d85ba275874f542cd20dc723e6963364a1f9425452b269a6799fd",16), new BigInteger("28fa13938655be1f8a159cbaca5a72ea190c30089e19cd274a556f36c4f6e19f554b34c077790427bbdd8dd3ede2448328f385d81b30e8e43b2fffa027861979",16), new BigInteger("1a8b38f398fa712049898d7fb79ee0a77668791299cdfa09efc0e507acb21ed74301ef5bfd48be455eaeb6e1678255827580a8e4e8e14151d1510a82a3f2e729",16), new BigInteger("27156aba4126d24a81f3a528cbfb27f56886f840a9f6e86e17a44b94fe9319584b8e22fdde1e5a2e3bd8aa5ba8d8584194eb2190acf832b847f13a3d24a79f4d",16)); // PSSExample1.1 private byte[] msg1a = Hex.decode("cdc87da223d786df3b45e0bbbc721326d1ee2af806cc315475cc6f0d9c66e1b62371d45ce2392e1ac92844c310102f156a0d8d52c1f4c40ba3aa65095786cb769757a6563ba958fed0bcc984e8b517a3d5f515b23b8a41e74aa867693f90dfb061a6e86dfaaee64472c00e5f20945729cbebe77f06ce78e08f4098fba41f9d6193c0317e8b60d4b6084acb42d29e3808a3bc372d85e331170fcbf7cc72d0b71c296648b3a4d10f416295d0807aa625cab2744fd9ea8fd223c42537029828bd16be02546f130fd2e33b936d2676e08aed1b73318b750a0167d0"); private byte[] slt1a = Hex.decode("dee959c7e06411361420ff80185ed57f3e6776af"); private byte[] sig1a = Hex.decode("9074308fb598e9701b2294388e52f971faac2b60a5145af185df5287b5ed2887e57ce7fd44dc8634e407c8e0e4360bc226f3ec227f9d9e54638e8d31f5051215df6ebb9c2f9579aa77598a38f914b5b9c1bd83c4e2f9f382a0d0aa3542ffee65984a601bc69eb28deb27dca12c82c2d4c3f66cd500f1ff2b994d8a4e30cbb33c"); // PSSExample1.2 private byte[] msg1b = Hex.decode("851384cdfe819c22ed6c4ccb30daeb5cf059bc8e1166b7e3530c4c233e2b5f8f71a1cca582d43ecc72b1bca16dfc7013226b9e"); private byte[] slt1b = Hex.decode("ef2869fa40c346cb183dab3d7bffc98fd56df42d"); private byte[] sig1b = Hex.decode("3ef7f46e831bf92b32274142a585ffcefbdca7b32ae90d10fb0f0c729984f04ef29a9df0780775ce43739b97838390db0a5505e63de927028d9d29b219ca2c4517832558a55d694a6d25b9dab66003c4cccd907802193be5170d26147d37b93590241be51c25055f47ef62752cfbe21418fafe98c22c4d4d47724fdb5669e843"); // // Example 2: A 1025-bit RSA keypair // private RSAKeyParameters pub2 = new RSAKeyParameters(false, new BigInteger("01d40c1bcf97a68ae7cdbd8a7bf3e34fa19dcca4ef75a47454375f94514d88fed006fb829f8419ff87d6315da68a1ff3a0938e9abb3464011c303ad99199cf0c7c7a8b477dce829e8844f625b115e5e9c4a59cf8f8113b6834336a2fd2689b472cbb5e5cabe674350c59b6c17e176874fb42f8fc3d176a017edc61fd326c4b33c9", 16), new BigInteger("010001", 16)); private RSAKeyParameters prv2 = new RSAPrivateCrtKeyParameters( new BigInteger("01d40c1bcf97a68ae7cdbd8a7bf3e34fa19dcca4ef75a47454375f94514d88fed006fb829f8419ff87d6315da68a1ff3a0938e9abb3464011c303ad99199cf0c7c7a8b477dce829e8844f625b115e5e9c4a59cf8f8113b6834336a2fd2689b472cbb5e5cabe674350c59b6c17e176874fb42f8fc3d176a017edc61fd326c4b33c9", 16), new BigInteger("010001", 16), new BigInteger("027d147e4673057377fd1ea201565772176a7dc38358d376045685a2e787c23c15576bc16b9f444402d6bfc5d98a3e88ea13ef67c353eca0c0ddba9255bd7b8bb50a644afdfd1dd51695b252d22e7318d1b6687a1c10ff75545f3db0fe602d5f2b7f294e3601eab7b9d1cecd767f64692e3e536ca2846cb0c2dd486a39fa75b1", 16), new BigInteger("016601e926a0f8c9e26ecab769ea65a5e7c52cc9e080ef519457c644da6891c5a104d3ea7955929a22e7c68a7af9fcad777c3ccc2b9e3d3650bce404399b7e59d1", 16), new BigInteger("014eafa1d4d0184da7e31f877d1281ddda625664869e8379e67ad3b75eae74a580e9827abd6eb7a002cb5411f5266797768fb8e95ae40e3e8a01f35ff89e56c079", 16), new BigInteger("e247cce504939b8f0a36090de200938755e2444b29539a7da7a902f6056835c0db7b52559497cfe2c61a8086d0213c472c78851800b171f6401de2e9c2756f31", 16), new BigInteger("b12fba757855e586e46f64c38a70c68b3f548d93d787b399999d4c8f0bbd2581c21e19ed0018a6d5d3df86424b3abcad40199d31495b61309f27c1bf55d487c1", 16), new BigInteger("564b1e1fa003bda91e89090425aac05b91da9ee25061e7628d5f51304a84992fdc33762bd378a59f030a334d532bd0dae8f298ea9ed844636ad5fb8cbdc03cad", 16)); // PSS Example 2.1 private byte[] msg2a = Hex.decode("daba032066263faedb659848115278a52c44faa3a76f37515ed336321072c40a9d9b53bc05014078adf520875146aae70ff060226dcb7b1f1fc27e9360"); private byte[] slt2a = Hex.decode("57bf160bcb02bb1dc7280cf0458530b7d2832ff7"); private byte[] sig2a = Hex.decode("014c5ba5338328ccc6e7a90bf1c0ab3fd606ff4796d3c12e4b639ed9136a5fec6c16d8884bdd99cfdc521456b0742b736868cf90de099adb8d5ffd1deff39ba4007ab746cefdb22d7df0e225f54627dc65466131721b90af445363a8358b9f607642f78fab0ab0f43b7168d64bae70d8827848d8ef1e421c5754ddf42c2589b5b3"); // PSS Example 2.2 private byte[] msg2b = Hex.decode("e4f8601a8a6da1be34447c0959c058570c3668cfd51dd5f9ccd6ad4411fe8213486d78a6c49f93efc2ca2288cebc2b9b60bd04b1e220d86e3d4848d709d032d1e8c6a070c6af9a499fcf95354b14ba6127c739de1bb0fd16431e46938aec0cf8ad9eb72e832a7035de9b7807bdc0ed8b68eb0f5ac2216be40ce920c0db0eddd3860ed788efaccaca502d8f2bd6d1a7c1f41ff46f1681c8f1f818e9c4f6d91a0c7803ccc63d76a6544d843e084e363b8acc55aa531733edb5dee5b5196e9f03e8b731b3776428d9e457fe3fbcb3db7274442d785890e9cb0854b6444dace791d7273de1889719338a77fe"); private byte[] slt2b = Hex.decode("7f6dd359e604e60870e898e47b19bf2e5a7b2a90"); private byte[] sig2b = Hex.decode("010991656cca182b7f29d2dbc007e7ae0fec158eb6759cb9c45c5ff87c7635dd46d150882f4de1e9ae65e7f7d9018f6836954a47c0a81a8a6b6f83f2944d6081b1aa7c759b254b2c34b691da67cc0226e20b2f18b42212761dcd4b908a62b371b5918c5742af4b537e296917674fb914194761621cc19a41f6fb953fbcbb649dea"); // // Example 4: A 1027-bit RSA key pair // private RSAKeyParameters pub4 = new RSAKeyParameters(false, new BigInteger("054adb7886447efe6f57e0368f06cf52b0a3370760d161cef126b91be7f89c421b62a6ec1da3c311d75ed50e0ab5fff3fd338acc3aa8a4e77ee26369acb81ba900fa83f5300cf9bb6c53ad1dc8a178b815db4235a9a9da0c06de4e615ea1277ce559e9c108de58c14a81aa77f5a6f8d1335494498848c8b95940740be7bf7c3705", 16), new BigInteger("010001", 16)); private RSAKeyParameters prv4 = new RSAPrivateCrtKeyParameters( new BigInteger("054adb7886447efe6f57e0368f06cf52b0a3370760d161cef126b91be7f89c421b62a6ec1da3c311d75ed50e0ab5fff3fd338acc3aa8a4e77ee26369acb81ba900fa83f5300cf9bb6c53ad1dc8a178b815db4235a9a9da0c06de4e615ea1277ce559e9c108de58c14a81aa77f5a6f8d1335494498848c8b95940740be7bf7c3705", 16), new BigInteger("010001", 16), new BigInteger("fa041f8cd9697ceed38ec8caa275523b4dd72b09a301d3541d72f5d31c05cbce2d6983b36183af10690bd46c46131e35789431a556771dd0049b57461bf060c1f68472e8a67c25f357e5b6b4738fa541a730346b4a07649a2dfa806a69c975b6aba64678acc7f5913e89c622f2d8abb1e3e32554e39df94ba60c002e387d9011", 16), new BigInteger("029232336d2838945dba9dd7723f4e624a05f7375b927a87abe6a893a1658fd49f47f6c7b0fa596c65fa68a23f0ab432962d18d4343bd6fd671a5ea8d148413995", 16), new BigInteger("020ef5efe7c5394aed2272f7e81a74f4c02d145894cb1b3cab23a9a0710a2afc7e3329acbb743d01f680c4d02afb4c8fde7e20930811bb2b995788b5e872c20bb1", 16), new BigInteger("026e7e28010ecf2412d9523ad704647fb4fe9b66b1a681581b0e15553a89b1542828898f27243ebab45ff5e1acb9d4df1b051fbc62824dbc6f6c93261a78b9a759", 16), new BigInteger("012ddcc86ef655998c39ddae11718669e5e46cf1495b07e13b1014cd69b3af68304ad2a6b64321e78bf3bbca9bb494e91d451717e2d97564c6549465d0205cf421", 16), new BigInteger("010600c4c21847459fe576703e2ebecae8a5094ee63f536bf4ac68d3c13e5e4f12ac5cc10ab6a2d05a199214d1824747d551909636b774c22cac0b837599abcc75", 16)); // PSS Example 4.1 private byte[] msg4a = Hex.decode("9fb03b827c8217d9"); private byte[] slt4a = Hex.decode("ed7c98c95f30974fbe4fbddcf0f28d6021c0e91d"); private byte[] sig4a = Hex.decode("0323d5b7bf20ba4539289ae452ae4297080feff4518423ff4811a817837e7d82f1836cdfab54514ff0887bddeebf40bf99b047abc3ecfa6a37a3ef00f4a0c4a88aae0904b745c846c4107e8797723e8ac810d9e3d95dfa30ff4966f4d75d13768d20857f2b1406f264cfe75e27d7652f4b5ed3575f28a702f8c4ed9cf9b2d44948"); // PSS Example 4.2 private byte[] msg4b = Hex.decode("0ca2ad77797ece86de5bf768750ddb5ed6a3116ad99bbd17edf7f782f0db1cd05b0f677468c5ea420dc116b10e80d110de2b0461ea14a38be68620392e7e893cb4ea9393fb886c20ff790642305bf302003892e54df9f667509dc53920df583f50a3dd61abb6fab75d600377e383e6aca6710eeea27156e06752c94ce25ae99fcbf8592dbe2d7e27453cb44de07100ebb1a2a19811a478adbeab270f94e8fe369d90b3ca612f9f"); private byte[] slt4b = Hex.decode("22d71d54363a4217aa55113f059b3384e3e57e44"); private byte[] sig4b = Hex.decode("049d0185845a264d28feb1e69edaec090609e8e46d93abb38371ce51f4aa65a599bdaaa81d24fba66a08a116cb644f3f1e653d95c89db8bbd5daac2709c8984000178410a7c6aa8667ddc38c741f710ec8665aa9052be929d4e3b16782c1662114c5414bb0353455c392fc28f3db59054b5f365c49e1d156f876ee10cb4fd70598"); // // Example 8: A 1031-bit RSA key pair // private RSAKeyParameters pub8 = new RSAKeyParameters(false, new BigInteger("495370a1fb18543c16d3631e3163255df62be6eee890d5f25509e4f778a8ea6fbbbcdf85dff64e0d972003ab3681fbba6dd41fd541829b2e582de9f2a4a4e0a2d0900bef4753db3cee0ee06c7dfae8b1d53b5953218f9cceea695b08668edeaadced9463b1d790d5ebf27e9115b46cad4d9a2b8efab0561b0810344739ada0733f", 16), new BigInteger("010001", 16)); private RSAKeyParameters prv8 = new RSAPrivateCrtKeyParameters( new BigInteger("495370a1fb18543c16d3631e3163255df62be6eee890d5f25509e4f778a8ea6fbbbcdf85dff64e0d972003ab3681fbba6dd41fd541829b2e582de9f2a4a4e0a2d0900bef4753db3cee0ee06c7dfae8b1d53b5953218f9cceea695b08668edeaadced9463b1d790d5ebf27e9115b46cad4d9a2b8efab0561b0810344739ada0733f", 16), new BigInteger("010001", 16), new BigInteger("6c66ffe98980c38fcdeab5159898836165f4b4b817c4f6a8d486ee4ea9130fe9b9092bd136d184f95f504a607eac565846d2fdd6597a8967c7396ef95a6eeebb4578a643966dca4d8ee3de842de63279c618159c1ab54a89437b6a6120e4930afb52a4ba6ced8a4947ac64b30a3497cbe701c2d6266d517219ad0ec6d347dbe9", 16), new BigInteger("08dad7f11363faa623d5d6d5e8a319328d82190d7127d2846c439b0ab72619b0a43a95320e4ec34fc3a9cea876422305bd76c5ba7be9e2f410c8060645a1d29edb", 16), new BigInteger("0847e732376fc7900f898ea82eb2b0fc418565fdae62f7d9ec4ce2217b97990dd272db157f99f63c0dcbb9fbacdbd4c4dadb6df67756358ca4174825b48f49706d", 16), new BigInteger("05c2a83c124b3621a2aa57ea2c3efe035eff4560f33ddebb7adab81fce69a0c8c2edc16520dda83d59a23be867963ac65f2cc710bbcfb96ee103deb771d105fd85", 16), new BigInteger("04cae8aa0d9faa165c87b682ec140b8ed3b50b24594b7a3b2c220b3669bb819f984f55310a1ae7823651d4a02e99447972595139363434e5e30a7e7d241551e1b9", 16), new BigInteger("07d3e47bf686600b11ac283ce88dbb3f6051e8efd04680e44c171ef531b80b2b7c39fc766320e2cf15d8d99820e96ff30dc69691839c4b40d7b06e45307dc91f3f", 16)); // PSS Example 8.1 private byte[] msg8a = Hex.decode("81332f4be62948415ea1d899792eeacf6c6e1db1da8be13b5cea41db2fed467092e1ff398914c714259775f595f8547f735692a575e6923af78f22c6997ddb90fb6f72d7bb0dd5744a31decd3dc3685849836ed34aec596304ad11843c4f88489f209735f5fb7fdaf7cec8addc5818168f880acbf490d51005b7a8e84e43e54287977571dd99eea4b161eb2df1f5108f12a4142a83322edb05a75487a3435c9a78ce53ed93bc550857d7a9fb"); private byte[] slt8a = Hex.decode("1d65491d79c864b373009be6f6f2467bac4c78fa"); private byte[] sig8a = Hex.decode("0262ac254bfa77f3c1aca22c5179f8f040422b3c5bafd40a8f21cf0fa5a667ccd5993d42dbafb409c520e25fce2b1ee1e716577f1efa17f3da28052f40f0419b23106d7845aaf01125b698e7a4dfe92d3967bb00c4d0d35ba3552ab9a8b3eef07c7fecdbc5424ac4db1e20cb37d0b2744769940ea907e17fbbca673b20522380c5"); // PSS Example 8.2 private byte[] msg8b = Hex.decode("e2f96eaf0e05e7ba326ecca0ba7fd2f7c02356f3cede9d0faabf4fcc8e60a973e5595fd9ea08"); private byte[] slt8b = Hex.decode("435c098aa9909eb2377f1248b091b68987ff1838"); private byte[] sig8b = Hex.decode("2707b9ad5115c58c94e932e8ec0a280f56339e44a1b58d4ddcff2f312e5f34dcfe39e89c6a94dcee86dbbdae5b79ba4e0819a9e7bfd9d982e7ee6c86ee68396e8b3a14c9c8f34b178eb741f9d3f121109bf5c8172fada2e768f9ea1433032c004a8aa07eb990000a48dc94c8bac8aabe2b09b1aa46c0a2aa0e12f63fbba775ba7e"); // // Example 9: A 1536-bit RSA key pair // private RSAKeyParameters pub9 = new RSAKeyParameters(false, new BigInteger("e6bd692ac96645790403fdd0f5beb8b9bf92ed10007fc365046419dd06c05c5b5b2f48ecf989e4ce269109979cbb40b4a0ad24d22483d1ee315ad4ccb1534268352691c524f6dd8e6c29d224cf246973aec86c5bf6b1401a850d1b9ad1bb8cbcec47b06f0f8c7f45d3fc8f319299c5433ddbc2b3053b47ded2ecd4a4caefd614833dc8bb622f317ed076b8057fe8de3f84480ad5e83e4a61904a4f248fb397027357e1d30e463139815c6fd4fd5ac5b8172a45230ecb6318a04f1455d84e5a8b", 16), new BigInteger("010001", 16)); private RSAKeyParameters prv9 = new RSAPrivateCrtKeyParameters( new BigInteger("e6bd692ac96645790403fdd0f5beb8b9bf92ed10007fc365046419dd06c05c5b5b2f48ecf989e4ce269109979cbb40b4a0ad24d22483d1ee315ad4ccb1534268352691c524f6dd8e6c29d224cf246973aec86c5bf6b1401a850d1b9ad1bb8cbcec47b06f0f8c7f45d3fc8f319299c5433ddbc2b3053b47ded2ecd4a4caefd614833dc8bb622f317ed076b8057fe8de3f84480ad5e83e4a61904a4f248fb397027357e1d30e463139815c6fd4fd5ac5b8172a45230ecb6318a04f1455d84e5a8b", 16), new BigInteger("010001", 16), new BigInteger("6a7fd84fb85fad073b34406db74f8d61a6abc12196a961dd79565e9da6e5187bce2d980250f7359575359270d91590bb0e427c71460b55d51410b191bcf309fea131a92c8e702738fa719f1e0041f52e40e91f229f4d96a1e6f172e15596b4510a6daec26105f2bebc53316b87bdf21311666070e8dfee69d52c71a976caae79c72b68d28580dc686d9f5129d225f82b3d615513a882b3db91416b48ce08888213e37eeb9af800d81cab328ce420689903c00c7b5fd31b75503a6d419684d629", 16), new BigInteger("f8eb97e98df12664eefdb761596a69ddcd0e76daece6ed4bf5a1b50ac086f7928a4d2f8726a77e515b74da41988f220b1cc87aa1fc810ce99a82f2d1ce821edced794c6941f42c7a1a0b8c4d28c75ec60b652279f6154a762aed165d47dee367", 16), new BigInteger("ed4d71d0a6e24b93c2e5f6b4bbe05f5fb0afa042d204fe3378d365c2f288b6a8dad7efe45d153eef40cacc7b81ff934002d108994b94a5e4728cd9c963375ae49965bda55cbf0efed8d6553b4027f2d86208a6e6b489c176128092d629e49d3d", 16), new BigInteger("2bb68bddfb0c4f56c8558bffaf892d8043037841e7fa81cfa61a38c5e39b901c8ee71122a5da2227bd6cdeeb481452c12ad3d61d5e4f776a0ab556591befe3e59e5a7fddb8345e1f2f35b9f4cee57c32414c086aec993e9353e480d9eec6289f", 16), new BigInteger("4ff897709fad079746494578e70fd8546130eeab5627c49b080f05ee4ad9f3e4b7cba9d6a5dff113a41c3409336833f190816d8a6bc42e9bec56b7567d0f3c9c696db619b245d901dd856db7c8092e77e9a1cccd56ee4dba42c5fdb61aec2669", 16), new BigInteger("77b9d1137b50404a982729316efafc7dfe66d34e5a182600d5f30a0a8512051c560d081d4d0a1835ec3d25a60f4e4d6aa948b2bf3dbb5b124cbbc3489255a3a948372f6978496745f943e1db4f18382ceaa505dfc65757bb3f857a58dce52156", 16)); // PSS Example 9.1 private byte[] msg9a = Hex.decode("a88e265855e9d7ca36c68795f0b31b591cd6587c71d060a0b3f7f3eaef43795922028bc2b6ad467cfc2d7f659c5385aa70ba3672cdde4cfe4970cc7904601b278872bf51321c4a972f3c95570f3445d4f57980e0f20df54846e6a52c668f1288c03f95006ea32f562d40d52af9feb32f0fa06db65b588a237b34e592d55cf979f903a642ef64d2ed542aa8c77dc1dd762f45a59303ed75e541ca271e2b60ca709e44fa0661131e8d5d4163fd8d398566ce26de8730e72f9cca737641c244159420637028df0a18079d6208ea8b4711a2c750f5"); private byte[] slt9a = Hex.decode("c0a425313df8d7564bd2434d311523d5257eed80"); private byte[] sig9a = Hex.decode("586107226c3ce013a7c8f04d1a6a2959bb4b8e205ba43a27b50f124111bc35ef589b039f5932187cb696d7d9a32c0c38300a5cdda4834b62d2eb240af33f79d13dfbf095bf599e0d9686948c1964747b67e89c9aba5cd85016236f566cc5802cb13ead51bc7ca6bef3b94dcbdbb1d570469771df0e00b1a8a06777472d2316279edae86474668d4e1efff95f1de61c6020da32ae92bbf16520fef3cf4d88f61121f24bbd9fe91b59caf1235b2a93ff81fc403addf4ebdea84934a9cdaf8e1a9e"); // PSS Example 9.2 private byte[] msg9b = Hex.decode("c8c9c6af04acda414d227ef23e0820c3732c500dc87275e95b0d095413993c2658bc1d988581ba879c2d201f14cb88ced153a01969a7bf0a7be79c84c1486bc12b3fa6c59871b6827c8ce253ca5fefa8a8c690bf326e8e37cdb96d90a82ebab69f86350e1822e8bd536a2e"); private byte[] slt9b = Hex.decode("b307c43b4850a8dac2f15f32e37839ef8c5c0e91"); private byte[] sig9b = Hex.decode("80b6d643255209f0a456763897ac9ed259d459b49c2887e5882ecb4434cfd66dd7e1699375381e51cd7f554f2c271704b399d42b4be2540a0eca61951f55267f7c2878c122842dadb28b01bd5f8c025f7e228418a673c03d6bc0c736d0a29546bd67f786d9d692ccea778d71d98c2063b7a71092187a4d35af108111d83e83eae46c46aa34277e06044589903788f1d5e7cee25fb485e92949118814d6f2c3ee361489016f327fb5bc517eb50470bffa1afa5f4ce9aa0ce5b8ee19bf5501b958"); public String getName() { return "PSSTest"; } private void testSig( int id, RSAKeyParameters pub, RSAKeyParameters prv, byte[] slt, byte[] msg, byte[] sig) throws Exception { PSSSigner eng = new PSSSigner(new RSAEngine(), new SHA1Digest(), 20); eng.init(true, new ParametersWithRandom(prv, new FixedRandom(slt))); eng.update(msg, 0, msg.length); byte[] s = eng.generateSignature(); if (!areEqual(s, sig)) { fail("test " + id + " failed generation"); } eng.init(false, pub); eng.update(msg, 0, msg.length); if (!eng.verifySignature(s)) { fail("test " + id + " failed verification"); } } public void performTest() throws Exception { testSig(1, pub1, prv1, slt1a, msg1a, sig1a); testSig(2, pub1, prv1, slt1b, msg1b, sig1b); testSig(3, pub2, prv2, slt2a, msg2a, sig2a); testSig(4, pub2, prv2, slt2b, msg2b, sig2b); testSig(5, pub4, prv4, slt4a, msg4a, sig4a); testSig(6, pub4, prv4, slt4b, msg4b, sig4b); testSig(7, pub8, prv8, slt8a, msg8a, sig8a); testSig(8, pub8, prv8, slt8b, msg8b, sig8b); testSig(9, pub9, prv9, slt9a, msg9a, sig9a); testSig(10, pub9, prv9, slt9b, msg9b, sig9b); // // loop test - sha-1 only // PSSSigner eng = new PSSSigner(new RSAEngine(), new SHA1Digest(), 20); int failed = 0; byte[] data = new byte[DATA_LENGTH]; SecureRandom random = new SecureRandom(); random.nextBytes(data); for (int j = 0; j < NUM_TESTS; j++) { eng.init(true, new ParametersWithRandom(prv8, random)); eng.update(data, 0, data.length); byte[] s = eng.generateSignature(); eng.init(false, pub8); eng.update(data, 0, data.length); if (!eng.verifySignature(s)) { failed++; } } if (failed != 0) { fail("loop test failed - failures: " + failed); } // // loop test - sha-256 and sha-1 // eng = new PSSSigner(new RSAEngine(), new SHA256Digest(), new SHA1Digest(), 20); failed = 0; data = new byte[DATA_LENGTH]; random.nextBytes(data); for (int j = 0; j < NUM_TESTS; j++) { eng.init(true, new ParametersWithRandom(prv8, random)); eng.update(data, 0, data.length); byte[] s = eng.generateSignature(); eng.init(false, pub8); eng.update(data, 0, data.length); if (!eng.verifySignature(s)) { failed++; } } if (failed != 0) { fail("loop test failed - failures: " + failed); } } public static void main( String[] args) { runTest(new PSSTest()); } } bouncycastle-1.49.orig/test/src/org/bouncycastle/crypto/test/NaccacheSternTest.java0000644000175000017500000002557310557412253030204 0ustar ebourgebourgpackage org.bouncycastle.crypto.test; import java.math.BigInteger; import java.security.SecureRandom; import java.util.Vector; import org.bouncycastle.crypto.AsymmetricCipherKeyPair; import org.bouncycastle.crypto.InvalidCipherTextException; import org.bouncycastle.crypto.engines.NaccacheSternEngine; import org.bouncycastle.crypto.generators.NaccacheSternKeyPairGenerator; import org.bouncycastle.crypto.params.NaccacheSternKeyGenerationParameters; import org.bouncycastle.crypto.params.NaccacheSternKeyParameters; import org.bouncycastle.crypto.params.NaccacheSternPrivateKeyParameters; import org.bouncycastle.util.encoders.Hex; import org.bouncycastle.util.test.SimpleTest; /** * Test case for NaccacheStern cipher. For details on this cipher, please see * * http://www.gemplus.com/smart/rd/publications/pdf/NS98pkcs.pdf * * Performs the following tests: *
      *
    • Toy example from the NaccacheSternPaper
    • *
    • 768 bit test with text "Now is the time for all good men." (ripped from RSA test) and * the same test with the first byte replaced by 0xFF
    • *
    • 1024 bit test analog to 768 bit test
    • *
    */ public class NaccacheSternTest extends SimpleTest { static final boolean debug = false; static final NaccacheSternEngine cryptEng = new NaccacheSternEngine(); static final NaccacheSternEngine decryptEng = new NaccacheSternEngine(); static { cryptEng.setDebug(debug); decryptEng.setDebug(debug); } // Values from NaccacheStern paper static final BigInteger a = BigInteger.valueOf(101); static final BigInteger u1 = BigInteger.valueOf(3); static final BigInteger u2 = BigInteger.valueOf(5); static final BigInteger u3 = BigInteger.valueOf(7); static final BigInteger b = BigInteger.valueOf(191); static final BigInteger v1 = BigInteger.valueOf(11); static final BigInteger v2 = BigInteger.valueOf(13); static final BigInteger v3 = BigInteger.valueOf(17); static final BigInteger ONE = BigInteger.valueOf(1); static final BigInteger TWO = BigInteger.valueOf(2); static final BigInteger sigma = u1.multiply(u2).multiply(u3).multiply(v1) .multiply(v2).multiply(v3); static final BigInteger p = TWO.multiply(a).multiply(u1).multiply(u2) .multiply(u3).add(ONE); static final BigInteger q = TWO.multiply(b).multiply(v1).multiply(v2) .multiply(v3).add(ONE); static final BigInteger n = p.multiply(q); static final BigInteger phi_n = p.subtract(ONE).multiply(q.subtract(ONE)); static final BigInteger g = BigInteger.valueOf(131); static final Vector smallPrimes = new Vector(); // static final BigInteger paperTest = BigInteger.valueOf(202); static final String input = "4e6f77206973207468652074696d6520666f7220616c6c20676f6f64206d656e"; static final BigInteger paperTest = BigInteger.valueOf(202); // // to check that we handling byte extension by big number correctly. // static final String edgeInput = "ff6f77206973207468652074696d6520666f7220616c6c20676f6f64206d656e"; public String getName() { return "NaccacheStern"; } public void performTest() { // Test with given key from NaccacheSternPaper (totally insecure) // First the Parameters from the NaccacheStern Paper // (see http://www.gemplus.com/smart/rd/publications/pdf/NS98pkcs.pdf ) smallPrimes.addElement(u1); smallPrimes.addElement(u2); smallPrimes.addElement(u3); smallPrimes.addElement(v1); smallPrimes.addElement(v2); smallPrimes.addElement(v3); NaccacheSternKeyParameters pubParameters = new NaccacheSternKeyParameters(false, g, n, sigma.bitLength()); NaccacheSternPrivateKeyParameters privParameters = new NaccacheSternPrivateKeyParameters(g, n, sigma.bitLength(), smallPrimes, phi_n); AsymmetricCipherKeyPair pair = new AsymmetricCipherKeyPair(pubParameters, privParameters); // Initialize Engines with KeyPair if (debug) { System.out.println("initializing encryption engine"); } cryptEng.init(true, pair.getPublic()); if (debug) { System.out.println("initializing decryption engine"); } decryptEng.init(false, pair.getPrivate()); byte[] data = paperTest.toByteArray(); if (!new BigInteger(data).equals(new BigInteger(enDeCrypt(data)))) { fail("failed NaccacheStern paper test"); } // // key generation test // // // 768 Bit test // if (debug) { System.out.println(); System.out.println("768 Bit TEST"); } // specify key generation parameters NaccacheSternKeyGenerationParameters genParam = new NaccacheSternKeyGenerationParameters(new SecureRandom(), 768, 8, 30, debug); // Initialize Key generator and generate key pair NaccacheSternKeyPairGenerator pGen = new NaccacheSternKeyPairGenerator(); pGen.init(genParam); pair = pGen.generateKeyPair(); if (((NaccacheSternKeyParameters)pair.getPublic()).getModulus().bitLength() < 768) { System.out.println("FAILED: key size is <786 bit, exactly " + ((NaccacheSternKeyParameters)pair.getPublic()).getModulus().bitLength() + " bit"); fail("failed key generation (768) length test"); } // Initialize Engines with KeyPair if (debug) { System.out.println("initializing " + genParam.getStrength() + " bit encryption engine"); } cryptEng.init(true, pair.getPublic()); if (debug) { System.out.println("initializing " + genParam.getStrength() + " bit decryption engine"); } decryptEng.init(false, pair.getPrivate()); // Basic data input data = Hex.decode(input); if (!new BigInteger(1, data).equals(new BigInteger(1, enDeCrypt(data)))) { fail("failed encryption decryption (" + genParam.getStrength() + ") basic test"); } // Data starting with FF byte (would be interpreted as negative // BigInteger) data = Hex.decode(edgeInput); if (!new BigInteger(1, data).equals(new BigInteger(1, enDeCrypt(data)))) { fail("failed encryption decryption (" + genParam.getStrength() + ") edgeInput test"); } // // 1024 Bit Test // /* if (debug) { System.out.println(); System.out.println("1024 Bit TEST"); } // specify key generation parameters genParam = new NaccacheSternKeyGenerationParameters(new SecureRandom(), 1024, 8, 40); pGen.init(genParam); pair = pGen.generateKeyPair(); if (((NaccacheSternKeyParameters)pair.getPublic()).getModulus().bitLength() < 1024) { if (debug) { System.out.println("FAILED: key size is <1024 bit, exactly " + ((NaccacheSternKeyParameters)pair.getPublic()).getModulus().bitLength() + " bit"); } fail("failed key generation (1024) length test"); } // Initialize Engines with KeyPair if (debug) { System.out.println("initializing " + genParam.getStrength() + " bit encryption engine"); } cryptEng.init(true, pair.getPublic()); if (debug) { System.out.println("initializing " + genParam.getStrength() + " bit decryption engine"); } decryptEng.init(false, pair.getPrivate()); if (debug) { System.out.println("Data is " + new BigInteger(1, data)); } // Basic data input data = Hex.decode(input); if (!new BigInteger(1, data).equals(new BigInteger(1, enDeCrypt(data)))) { fail("failed encryption decryption (" + genParam.getStrength() + ") basic test"); } // Data starting with FF byte (would be interpreted as negative // BigInteger) data = Hex.decode(edgeInput); if (!new BigInteger(1, data).equals(new BigInteger(1, enDeCrypt(data)))) { fail("failed encryption decryption (" + genParam.getStrength() + ") edgeInput test"); } */ // END OF TEST CASE try { new NaccacheSternEngine().processBlock(new byte[]{ 1 }, 0, 1); fail("failed initialisation check"); } catch (IllegalStateException e) { // expected } catch (InvalidCipherTextException e) { fail("failed initialisation check"); } if (debug) { System.out.println("All tests successful"); } } private byte[] enDeCrypt(byte[] input) { // create work array byte[] data = new byte[input.length]; System.arraycopy(input, 0, data, 0, data.length); // Perform encryption like in the paper from Naccache-Stern if (debug) { System.out.println("encrypting data. Data representation\n" // + "As String:.... " + new String(data) + "\n" + "As BigInteger: " + new BigInteger(1, data)); System.out.println("data length is " + data.length); } try { data = cryptEng.processData(data); } catch (InvalidCipherTextException e) { if (debug) { System.out.println("failed - exception " + e.toString() + "\n" + e.getMessage()); } fail("failed - exception " + e.toString() + "\n" + e.getMessage()); } if (debug) { System.out.println("enrypted data representation\n" // + "As String:.... " + new String(data) + "\n" + "As BigInteger: " + new BigInteger(1, data)); System.out.println("data length is " + data.length); } try { data = decryptEng.processData(data); } catch (InvalidCipherTextException e) { if (debug) { System.out.println("failed - exception " + e.toString() + "\n" + e.getMessage()); } fail("failed - exception " + e.toString() + "\n" + e.getMessage()); } if (debug) { System.out.println("decrypted data representation\n" // + "As String:.... " + new String(data) + "\n" + "As BigInteger: " + new BigInteger(1, data)); System.out.println("data length is " + data.length); } return data; } public static void main(String[] args) { runTest(new NaccacheSternTest()); } } bouncycastle-1.49.orig/test/src/org/bouncycastle/crypto/test/AESTest.java0000644000175000017500000003267411567577272026132 0ustar ebourgebourgpackage org.bouncycastle.crypto.test; import org.bouncycastle.crypto.BlockCipher; import org.bouncycastle.crypto.BufferedBlockCipher; import org.bouncycastle.crypto.InvalidCipherTextException; import org.bouncycastle.crypto.engines.AESEngine; import org.bouncycastle.crypto.modes.CBCBlockCipher; import org.bouncycastle.crypto.modes.CFBBlockCipher; import org.bouncycastle.crypto.modes.OFBBlockCipher; import org.bouncycastle.crypto.modes.SICBlockCipher; import org.bouncycastle.crypto.params.KeyParameter; import org.bouncycastle.crypto.params.ParametersWithIV; import org.bouncycastle.util.encoders.Hex; import org.bouncycastle.util.test.SimpleTest; /** * Test vectors from the NIST standard tests and Brian Gladman's vector set * * http://fp.gladman.plus.com/cryptography_technology/rijndael/ */ public class AESTest extends CipherTest { private static final byte[] tData = Hex.decode("AAFE47EE82411A2BF3F6752AE8D7831138F041560631B114F3F6752AE8D7831138F041560631B1145A01020304050607"); private static final byte[] outCBC1 = Hex.decode("a444a9a4d46eb30cb7ed34d62873a89f8fdf2bf8a54e1aeadd06fd85c9cb46f021ee7cd4f418fa0bb72e9d07c70d5d20"); private static final byte[] outCBC2 = Hex.decode("585681354f0e01a86b32f94ebb6a675045d923cf201263c2aaecca2b4de82da0edd74ca5efd654c688f8a58e61955b11"); private static final byte[] outSIC1 = Hex.decode("82a1744e8ebbd053ca72362d5e570326e0b6fdaf824ab673fbf029042886b23c75129a015852913790f81f94447475a0"); private static final byte[] outSIC2 = Hex.decode("146cbb581d9e12c3333dd9c736fbb93043c92019f78580da48f81f80b3f551d58ea836fed480fc6912fefa9c5c89cc24"); private static final byte[] outCFB1 = Hex.decode("82a1744e8ebbd053ca72362d5e5703264b4182de3208c374b8ac4fa36af9c5e5f4f87d1e3b67963d06acf5eb13914c90"); private static final byte[] outCFB2 = Hex.decode("146cbb581d9e12c3333dd9c736fbb9303c8a3eb5185e2809e9d3c28e25cc2d2b6f5c11ee28d6530f72c412b1438a816a"); private static final byte[] outOFB1 = Hex.decode("82a1744e8ebbd053ca72362d5e5703261ebf1fdbec05e57b3465b583132f84b43bf95b2c89040ad1677b22d42db69a7a"); private static final byte[] outOFB2 = Hex.decode("146cbb581d9e12c3333dd9c736fbb9309ea4c2a7696c84959a2dada49f2f1c5905db1f0cec3a31acbc4701e74ab05e1f"); static SimpleTest[] tests = { new BlockCipherVectorTest(0, new AESEngine(), new KeyParameter(Hex.decode("80000000000000000000000000000000")), "00000000000000000000000000000000", "0EDD33D3C621E546455BD8BA1418BEC8"), new BlockCipherVectorTest(1, new AESEngine(), new KeyParameter(Hex.decode("00000000000000000000000000000080")), "00000000000000000000000000000000", "172AEAB3D507678ECAF455C12587ADB7"), new BlockCipherMonteCarloTest(2, 10000, new AESEngine(), new KeyParameter(Hex.decode("00000000000000000000000000000000")), "00000000000000000000000000000000", "C34C052CC0DA8D73451AFE5F03BE297F"), new BlockCipherMonteCarloTest(3, 10000, new AESEngine(), new KeyParameter(Hex.decode("5F060D3716B345C253F6749ABAC10917")), "355F697E8B868B65B25A04E18D782AFA", "ACC863637868E3E068D2FD6E3508454A"), new BlockCipherVectorTest(4, new AESEngine(), new KeyParameter(Hex.decode("000000000000000000000000000000000000000000000000")), "80000000000000000000000000000000", "6CD02513E8D4DC986B4AFE087A60BD0C"), new BlockCipherMonteCarloTest(5, 10000, new AESEngine(), new KeyParameter(Hex.decode("AAFE47EE82411A2BF3F6752AE8D7831138F041560631B114")), "F3F6752AE8D7831138F041560631B114", "77BA00ED5412DFF27C8ED91F3C376172"), new BlockCipherVectorTest(6, new AESEngine(), new KeyParameter(Hex.decode("0000000000000000000000000000000000000000000000000000000000000000")), "80000000000000000000000000000000", "DDC6BF790C15760D8D9AEB6F9A75FD4E"), new BlockCipherMonteCarloTest(7, 10000, new AESEngine(), new KeyParameter(Hex.decode("28E79E2AFC5F7745FCCABE2F6257C2EF4C4EDFB37324814ED4137C288711A386")), "C737317FE0846F132B23C8C2A672CE22", "E58B82BFBA53C0040DC610C642121168"), new BlockCipherVectorTest(8, new AESEngine(), new KeyParameter(Hex.decode("80000000000000000000000000000000")), "00000000000000000000000000000000", "0EDD33D3C621E546455BD8BA1418BEC8"), new BlockCipherVectorTest(9, new AESEngine(), new KeyParameter(Hex.decode("00000000000000000000000000000080")), "00000000000000000000000000000000", "172AEAB3D507678ECAF455C12587ADB7"), new BlockCipherMonteCarloTest(10, 10000, new AESEngine(), new KeyParameter(Hex.decode("00000000000000000000000000000000")), "00000000000000000000000000000000", "C34C052CC0DA8D73451AFE5F03BE297F"), new BlockCipherMonteCarloTest(11, 10000, new AESEngine(), new KeyParameter(Hex.decode("5F060D3716B345C253F6749ABAC10917")), "355F697E8B868B65B25A04E18D782AFA", "ACC863637868E3E068D2FD6E3508454A"), new BlockCipherVectorTest(12, new AESEngine(), new KeyParameter(Hex.decode("000000000000000000000000000000000000000000000000")), "80000000000000000000000000000000", "6CD02513E8D4DC986B4AFE087A60BD0C"), new BlockCipherMonteCarloTest(13, 10000, new AESEngine(), new KeyParameter(Hex.decode("AAFE47EE82411A2BF3F6752AE8D7831138F041560631B114")), "F3F6752AE8D7831138F041560631B114", "77BA00ED5412DFF27C8ED91F3C376172"), new BlockCipherVectorTest(14, new AESEngine(), new KeyParameter(Hex.decode("0000000000000000000000000000000000000000000000000000000000000000")), "80000000000000000000000000000000", "DDC6BF790C15760D8D9AEB6F9A75FD4E"), new BlockCipherMonteCarloTest(15, 10000, new AESEngine(), new KeyParameter(Hex.decode("28E79E2AFC5F7745FCCABE2F6257C2EF4C4EDFB37324814ED4137C288711A386")), "C737317FE0846F132B23C8C2A672CE22", "E58B82BFBA53C0040DC610C642121168"), new BlockCipherVectorTest(16, new AESEngine(), new KeyParameter(Hex.decode("80000000000000000000000000000000")), "00000000000000000000000000000000", "0EDD33D3C621E546455BD8BA1418BEC8"), new BlockCipherVectorTest(17, new AESEngine(), new KeyParameter(Hex.decode("00000000000000000000000000000080")), "00000000000000000000000000000000", "172AEAB3D507678ECAF455C12587ADB7"), new BlockCipherMonteCarloTest(18, 10000, new AESEngine(), new KeyParameter(Hex.decode("00000000000000000000000000000000")), "00000000000000000000000000000000", "C34C052CC0DA8D73451AFE5F03BE297F"), new BlockCipherMonteCarloTest(19, 10000, new AESEngine(), new KeyParameter(Hex.decode("5F060D3716B345C253F6749ABAC10917")), "355F697E8B868B65B25A04E18D782AFA", "ACC863637868E3E068D2FD6E3508454A"), new BlockCipherVectorTest(20, new AESEngine(), new KeyParameter(Hex.decode("000000000000000000000000000000000000000000000000")), "80000000000000000000000000000000", "6CD02513E8D4DC986B4AFE087A60BD0C"), new BlockCipherMonteCarloTest(21, 10000, new AESEngine(), new KeyParameter(Hex.decode("AAFE47EE82411A2BF3F6752AE8D7831138F041560631B114")), "F3F6752AE8D7831138F041560631B114", "77BA00ED5412DFF27C8ED91F3C376172"), new BlockCipherVectorTest(22, new AESEngine(), new KeyParameter(Hex.decode("0000000000000000000000000000000000000000000000000000000000000000")), "80000000000000000000000000000000", "DDC6BF790C15760D8D9AEB6F9A75FD4E"), new BlockCipherMonteCarloTest(23, 10000, new AESEngine(), new KeyParameter(Hex.decode("28E79E2AFC5F7745FCCABE2F6257C2EF4C4EDFB37324814ED4137C288711A386")), "C737317FE0846F132B23C8C2A672CE22", "E58B82BFBA53C0040DC610C642121168") }; private BlockCipher _engine = new AESEngine(); public AESTest() { super(tests, new AESEngine(), new KeyParameter(new byte[16])); } public String getName() { return "AES"; } private void testNullSIC() throws InvalidCipherTextException { BufferedBlockCipher b = new BufferedBlockCipher(new SICBlockCipher(new AESEngine())); KeyParameter kp = new KeyParameter(Hex.decode("5F060D3716B345C253F6749ABAC10917")); b.init(true, new ParametersWithIV(kp, new byte[16])); byte[] out = new byte[b.getOutputSize(tData.length)]; int len = b.processBytes(tData, 0, tData.length, out, 0); len += b.doFinal(out, len); if (!areEqual(outSIC1, out)) { fail("no match on first nullSIC check"); } b.init(true, new ParametersWithIV(null, Hex.decode("000102030405060708090a0b0c0d0e0f"))); len = b.processBytes(tData, 0, tData.length, out, 0); len += b.doFinal(out, len); if (!areEqual(outSIC2, out)) { fail("no match on second nullSIC check"); } } private void testNullCBC() throws InvalidCipherTextException { BufferedBlockCipher b = new BufferedBlockCipher(new CBCBlockCipher(new AESEngine())); KeyParameter kp = new KeyParameter(Hex.decode("5F060D3716B345C253F6749ABAC10917")); b.init(true, new ParametersWithIV(kp, new byte[16])); byte[] out = new byte[b.getOutputSize(tData.length)]; int len = b.processBytes(tData, 0, tData.length, out, 0); len += b.doFinal(out, len); if (!areEqual(outCBC1, out)) { fail("no match on first nullCBC check"); } b.init(true, new ParametersWithIV(null, Hex.decode("000102030405060708090a0b0c0d0e0f"))); len = b.processBytes(tData, 0, tData.length, out, 0); len += b.doFinal(out, len); if (!areEqual(outCBC2, out)) { fail("no match on second nullCBC check"); } } private void testNullOFB() throws InvalidCipherTextException { BufferedBlockCipher b = new BufferedBlockCipher(new OFBBlockCipher(new AESEngine(), 128)); KeyParameter kp = new KeyParameter(Hex.decode("5F060D3716B345C253F6749ABAC10917")); b.init(true, new ParametersWithIV(kp, new byte[16])); byte[] out = new byte[b.getOutputSize(tData.length)]; int len = b.processBytes(tData, 0, tData.length, out, 0); len += b.doFinal(out, len); if (!areEqual(outOFB1, out)) { fail("no match on first nullOFB check"); } b.init(true, new ParametersWithIV(null, Hex.decode("000102030405060708090a0b0c0d0e0f"))); len = b.processBytes(tData, 0, tData.length, out, 0); len += b.doFinal(out, len); if (!areEqual(outOFB2, out)) { fail("no match on second nullOFB check"); } } private void testNullCFB() throws InvalidCipherTextException { BufferedBlockCipher b = new BufferedBlockCipher(new CFBBlockCipher(new AESEngine(), 128)); KeyParameter kp = new KeyParameter(Hex.decode("5F060D3716B345C253F6749ABAC10917")); b.init(true, new ParametersWithIV(kp, new byte[16])); byte[] out = new byte[b.getOutputSize(tData.length)]; int len = b.processBytes(tData, 0, tData.length, out, 0); len += b.doFinal(out, len); if (!areEqual(outCFB1, out)) { fail("no match on first nullCFB check"); } b.init(true, new ParametersWithIV(null, Hex.decode("000102030405060708090a0b0c0d0e0f"))); len = b.processBytes(tData, 0, tData.length, out, 0); len += b.doFinal(out, len); if (!areEqual(outCFB2, out)) { fail("no match on second nullCFB check"); } } public void performTest() throws Exception { super.performTest(); byte[] keyBytes = new byte[16]; _engine.init(true, new KeyParameter(keyBytes)); // // init tests // try { byte[] dudKey = new byte[6]; _engine.init(true, new KeyParameter(dudKey)); fail("failed key length check"); } catch (IllegalArgumentException e) { // expected } try { byte[] iv = new byte[16]; _engine.init(true, new ParametersWithIV(null, iv)); fail("failed parameter check"); } catch (IllegalArgumentException e) { // expected } testNullCBC(); testNullSIC(); testNullOFB(); testNullCFB(); } public static void main( String[] args) { runTest(new AESTest()); } } bouncycastle-1.49.orig/test/src/org/bouncycastle/crypto/test/SHA256DigestTest.java0000644000175000017500000000263210330633061027471 0ustar ebourgebourgpackage org.bouncycastle.crypto.test; import org.bouncycastle.crypto.Digest; import org.bouncycastle.crypto.digests.SHA256Digest; /** * standard vector test for SHA-256 from FIPS Draft 180-2. * * Note, the first two vectors are _not_ from the draft, the last three are. */ public class SHA256DigestTest extends DigestTest { private static String[] messages = { "", "a", "abc", "abcdbcdecdefdefgefghfghighijhijkijkljklmklmnlmnomnopnopq" }; private static String[] digests = { "e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855", "ca978112ca1bbdcafac231b39a23dc4da786eff8147c4e72b9807785afee48bb", "ba7816bf8f01cfea414140de5dae2223b00361a396177a9cb410ff61f20015ad", "248d6a61d20638b8e5c026930c3e6039a33ce45964ff2167f6ecedd419db06c1" }; // 1 million 'a' static private String million_a_digest = "cdc76e5c9914fb9281a1c7e284d73e67f1809a48a497200e046d39ccc7112cd0"; SHA256DigestTest() { super(new SHA256Digest(), messages, digests); } public void performTest() { super.performTest(); millionATest(million_a_digest); } protected Digest cloneDigest(Digest digest) { return new SHA256Digest((SHA256Digest)digest); } public static void main( String[] args) { runTest(new SHA256DigestTest()); } } bouncycastle-1.49.orig/test/src/org/bouncycastle/crypto/test/SCryptTest.java0000644000175000017500000000600411702737275026722 0ustar ebourgebourgpackage org.bouncycastle.crypto.test; import java.io.BufferedReader; import java.io.FileReader; import org.bouncycastle.crypto.generators.SCrypt; import org.bouncycastle.util.Strings; import org.bouncycastle.util.encoders.Hex; import org.bouncycastle.util.test.SimpleTest; /* * scrypt test vectors from "Stronger Key Derivation Via Sequential Memory-hard Functions" Appendix B. * (http://www.tarsnap.com/scrypt/scrypt.pdf) */ public class SCryptTest extends SimpleTest { private static final String TEST_DATA_HOME = "bc.test.data.home"; public String getName() { return "SCrypt"; } public void performTest() throws Exception { BufferedReader br = new BufferedReader(new FileReader(getDataHome() + "/TestVectors.txt")); int count = 0; String line = br.readLine(); while (line != null) { ++count; String header = line; StringBuffer data = new StringBuffer(); while (!isEndData(line = br.readLine())) { for (int i = 0; i != line.length(); i++) { if (line.charAt(i) != ' ') { data.append(line.charAt(i)); } } } int start = header.indexOf('(') + 1; int limit = header.lastIndexOf(')'); String argStr = header.substring(start, limit); String[] args = Strings.split(argStr, ','); byte[] P = extractQuotedString(args[0]); byte[] S = extractQuotedString(args[1]); int N = extractInteger(args[2]); int r = extractInteger(args[3]); int p = extractInteger(args[4]); int dkLen = extractInteger(args[5]); byte[] expected = Hex.decode(data.toString()); // This skips very expensive test case(s), remove check to re-enable if (N <= 16384) { byte[] result = SCrypt.generate(P, S, N, r, p, dkLen); if (!areEqual(expected, result)) { fail("Result does not match expected value in test case " + count); } } } br.close(); } private static boolean isEndData(String line) { return line == null || line.startsWith("scrypt"); } private static byte[] extractQuotedString(String arg) { arg = arg.trim(); arg = arg.substring(1, arg.length() - 1); return Strings.toByteArray(arg); } private static int extractInteger(String arg) { return Integer.parseInt(arg.trim()); } private static String getDataHome() { String dataHome = System.getProperty(TEST_DATA_HOME); if (dataHome == null) { throw new IllegalStateException(TEST_DATA_HOME + " property not set"); } return dataHome + "/scrypt"; } public static void main(String[] args) { runTest(new SCryptTest()); } } bouncycastle-1.49.orig/test/src/org/bouncycastle/crypto/test/Grainv1Test.java0000644000175000017500000000755512151552117027006 0ustar ebourgebourgpackage org.bouncycastle.crypto.test; import org.bouncycastle.crypto.CipherParameters; import org.bouncycastle.crypto.StreamCipher; import org.bouncycastle.crypto.engines.Grainv1Engine; import org.bouncycastle.crypto.params.KeyParameter; import org.bouncycastle.crypto.params.ParametersWithIV; import org.bouncycastle.util.encoders.Hex; import org.bouncycastle.util.test.SimpleTest; /** * Grain v1 Test */ public class Grainv1Test extends SimpleTest { String keyStream1 = "dee931cf1662a72f77d0"; String keyStream2 = "7f362bd3f7abae203664"; String keyStream4 = "017D13ECB20AE0C9ACF784CB06525F72" + "CE6D52BEBB948F124668C35064559024" + "49EEA505C19F3EE4D052C3D19DA9C4D1" + "B92DBC7F07AFEA6A3D845DE60D8471FD"; public String getName() { return "Grain v1"; } public void performTest() { Grainv1Test1(new ParametersWithIV(new KeyParameter(Hex .decode("00000000000000000000")), Hex .decode("0000000000000000"))); Grainv1Test2(new ParametersWithIV(new KeyParameter(Hex .decode("0123456789abcdef1234")), Hex .decode("0123456789abcdef"))); Grainv1Test3(new ParametersWithIV(new KeyParameter(Hex .decode("0123456789abcdef1234")), Hex .decode("0123456789abcdef"))); Grainv1Test4(new ParametersWithIV(new KeyParameter(Hex .decode("0F62B5085BAE0154A7FA")), Hex .decode("288FF65DC42B92F9"))); } private void Grainv1Test1(CipherParameters params) { StreamCipher grain = new Grainv1Engine(); byte[] in = new byte[10]; byte[] out = new byte[10]; grain.init(true, params); grain.processBytes(in, 0, in.length, out, 0); if (!areEqual(out, Hex.decode(keyStream1))) { mismatch("Keystream 1", keyStream1, out); } grain.reset(); grain.processBytes(in, 0, in.length, out, 0); if (!areEqual(out, Hex.decode(keyStream1))) { mismatch("Keystream 1", keyStream1, out); } } private void Grainv1Test2(CipherParameters params) { StreamCipher grain = new Grainv1Engine(); byte[] in = new byte[10]; byte[] out = new byte[10]; grain.init(true, params); grain.processBytes(in, 0, in.length, out, 0); if (!areEqual(out, Hex.decode(keyStream2))) { mismatch("Keystream 2", keyStream2, out); } grain.reset(); grain.processBytes(in, 0, in.length, out, 0); if (!areEqual(out, Hex.decode(keyStream2))) { mismatch("Keystream 2", keyStream2, out); } } private void Grainv1Test3(CipherParameters params) { StreamCipher grain = new Grainv1Engine(); byte[] in = "Encrypt me!".getBytes(); byte[] cipher = new byte[in.length]; byte[] clear = new byte[in.length]; grain.init(true, params); grain.processBytes(in, 0, in.length, cipher, 0); grain.reset(); grain.processBytes(cipher, 0, cipher.length, clear, 0); if (!areEqual(in, clear)) { mismatch("Test 3", new String(Hex.encode(in)), clear); } } private void Grainv1Test4(CipherParameters params) { StreamCipher grain = new Grainv1Engine(); byte[] in = new byte[keyStream4.length() / 2]; byte[] out = new byte[in.length]; grain.init(true, params); grain.processBytes(in, 0, in.length, out, 0); if (!areEqual(out, Hex.decode(keyStream4))) { mismatch("Keystream 4", keyStream4, out); } } private void mismatch(String name, String expected, byte[] found) { fail("mismatch on " + name, expected, new String(Hex.encode(found))); } public static void main(String[] args) { runTest(new Grainv1Test()); } } bouncycastle-1.49.orig/test/src/org/bouncycastle/crypto/test/RIPEMD160HMacTest.java0000644000175000017500000000612510330633061027422 0ustar ebourgebourgpackage org.bouncycastle.crypto.test; import org.bouncycastle.crypto.digests.RIPEMD160Digest; import org.bouncycastle.crypto.macs.HMac; import org.bouncycastle.crypto.params.KeyParameter; import org.bouncycastle.util.Arrays; import org.bouncycastle.util.encoders.Hex; import org.bouncycastle.util.test.SimpleTestResult; import org.bouncycastle.util.test.Test; import org.bouncycastle.util.test.TestResult; /** * RIPEMD160 HMac Test, test vectors from RFC 2286 */ public class RIPEMD160HMacTest implements Test { final static String[] keys = { "0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b", "4a656665", "aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa", "0102030405060708090a0b0c0d0e0f10111213141516171819", "0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c", "aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa", "aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa" }; final static String[] digests = { "24cb4bd67d20fc1a5d2ed7732dcc39377f0a5668", "dda6c0213a485a9e24f4742064a7f033b43c4069", "b0b105360de759960ab4f35298e116e295d8e7c1", "d5ca862f4d21d5e610e18b4cf1beb97a4365ecf4", "7619693978f91d90539ae786500ff3d8e0518e39", "6466ca07ac5eac29e1bd523e5ada7605b791fd8b", "69ea60798d71616cce5fd0871e23754cd75d5a0a" }; final static String[] messages = { "Hi There", "what do ya want for nothing?", "0xdddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddd", "0xcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcd", "Test With Truncation", "Test Using Larger Than Block-Size Key - Hash Key First", "Test Using Larger Than Block-Size Key and Larger Than One Block-Size Data" }; public String getName() { return "RIPEMD160HMac"; } public TestResult perform() { HMac hmac = new HMac(new RIPEMD160Digest()); byte[] resBuf = new byte[hmac.getMacSize()]; for (int i = 0; i < messages.length; i++) { byte[] m = messages[i].getBytes(); if (messages[i].startsWith("0x")) { m = Hex.decode(messages[i].substring(2)); } hmac.init(new KeyParameter(Hex.decode(keys[i]))); hmac.update(m, 0, m.length); hmac.doFinal(resBuf, 0); if (!Arrays.areEqual(resBuf, Hex.decode(digests[i]))) { return new SimpleTestResult(false, getName() + ": Vector " + i + " failed"); } } return new SimpleTestResult(true, getName() + ": Okay"); } public static void main( String[] args) { RIPEMD160HMacTest test = new RIPEMD160HMacTest(); TestResult result = test.perform(); System.out.println(result); } } bouncycastle-1.49.orig/test/src/org/bouncycastle/crypto/test/TigerDigestTest.java0000644000175000017500000000355310330633061027676 0ustar ebourgebourgpackage org.bouncycastle.crypto.test; import org.bouncycastle.crypto.Digest; import org.bouncycastle.crypto.digests.TigerDigest; /** * Tiger Digest Test */ public class TigerDigestTest extends DigestTest { final static String[] messages = { "", "abc", "Tiger", "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+-", "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvw", "ABCDEFGHIJKLMNOPQRSTUVWXYZ=abcdefghijklmnopqrstuvwxyz+0123456789", "Tiger - A Fast New Hash Function, by Ross Anderson and Eli Biham, proceedings of Fast Software Encryption 3, Cambridge, 1996.", "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+-ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+-" }; final static String[] digests = { "3293AC630C13F0245F92BBB1766E16167A4E58492DDE73F3", "2AAB1484E8C158F2BFB8C5FF41B57A525129131C957B5F93", "DD00230799F5009FEC6DEBC838BB6A27DF2B9D6F110C7937", "F71C8583902AFB879EDFE610F82C0D4786A3A534504486B5", "38F41D9D9A710A10C3727AC0DEEAA270727D9F926EC10139", "48CEEB6308B87D46E95D656112CDF18D97915F9765658957", "631ABDD103EB9A3D245B6DFD4D77B257FC7439501D1568DD", "C54034E5B43EB8005848A7E0AE6AAC76E4FF590AE715FD25", "C54034E5B43EB8005848A7E0AE6AAC76E4FF590AE715FD25" }; final static String hash64k = "FDF4F5B35139F48E710E421BE5AF411DE1A8AAC333F26204"; TigerDigestTest() { super(new TigerDigest(), messages, digests); } public void performTest() { super.performTest(); sixtyFourKTest(hash64k); } protected Digest cloneDigest(Digest digest) { return new TigerDigest((TigerDigest)digest); } public static void main( String[] args) { runTest(new TigerDigestTest()); } } bouncycastle-1.49.orig/test/src/org/bouncycastle/crypto/test/AESLightTest.java0000644000175000017500000002031310330633061027055 0ustar ebourgebourgpackage org.bouncycastle.crypto.test; import org.bouncycastle.crypto.BlockCipher; import org.bouncycastle.crypto.engines.AESLightEngine; import org.bouncycastle.crypto.params.KeyParameter; import org.bouncycastle.crypto.params.ParametersWithIV; import org.bouncycastle.util.encoders.Hex; import org.bouncycastle.util.test.SimpleTest; /** * Test vectors from the NIST standard tests and Brian Gladman's vector set * * http://fp.gladman.plus.com/cryptography_technology/rijndael/ */ public class AESLightTest extends CipherTest { static SimpleTest[] tests = { new BlockCipherVectorTest(0, new AESLightEngine(), new KeyParameter(Hex.decode("80000000000000000000000000000000")), "00000000000000000000000000000000", "0EDD33D3C621E546455BD8BA1418BEC8"), new BlockCipherVectorTest(1, new AESLightEngine(), new KeyParameter(Hex.decode("00000000000000000000000000000080")), "00000000000000000000000000000000", "172AEAB3D507678ECAF455C12587ADB7"), new BlockCipherMonteCarloTest(2, 10000, new AESLightEngine(), new KeyParameter(Hex.decode("00000000000000000000000000000000")), "00000000000000000000000000000000", "C34C052CC0DA8D73451AFE5F03BE297F"), new BlockCipherMonteCarloTest(3, 10000, new AESLightEngine(), new KeyParameter(Hex.decode("5F060D3716B345C253F6749ABAC10917")), "355F697E8B868B65B25A04E18D782AFA", "ACC863637868E3E068D2FD6E3508454A"), new BlockCipherVectorTest(4, new AESLightEngine(), new KeyParameter(Hex.decode("000000000000000000000000000000000000000000000000")), "80000000000000000000000000000000", "6CD02513E8D4DC986B4AFE087A60BD0C"), new BlockCipherMonteCarloTest(5, 10000, new AESLightEngine(), new KeyParameter(Hex.decode("AAFE47EE82411A2BF3F6752AE8D7831138F041560631B114")), "F3F6752AE8D7831138F041560631B114", "77BA00ED5412DFF27C8ED91F3C376172"), new BlockCipherVectorTest(6, new AESLightEngine(), new KeyParameter(Hex.decode("0000000000000000000000000000000000000000000000000000000000000000")), "80000000000000000000000000000000", "DDC6BF790C15760D8D9AEB6F9A75FD4E"), new BlockCipherMonteCarloTest(7, 10000, new AESLightEngine(), new KeyParameter(Hex.decode("28E79E2AFC5F7745FCCABE2F6257C2EF4C4EDFB37324814ED4137C288711A386")), "C737317FE0846F132B23C8C2A672CE22", "E58B82BFBA53C0040DC610C642121168"), new BlockCipherVectorTest(8, new AESLightEngine(), new KeyParameter(Hex.decode("80000000000000000000000000000000")), "00000000000000000000000000000000", "0EDD33D3C621E546455BD8BA1418BEC8"), new BlockCipherVectorTest(9, new AESLightEngine(), new KeyParameter(Hex.decode("00000000000000000000000000000080")), "00000000000000000000000000000000", "172AEAB3D507678ECAF455C12587ADB7"), new BlockCipherMonteCarloTest(10, 10000, new AESLightEngine(), new KeyParameter(Hex.decode("00000000000000000000000000000000")), "00000000000000000000000000000000", "C34C052CC0DA8D73451AFE5F03BE297F"), new BlockCipherMonteCarloTest(11, 10000, new AESLightEngine(), new KeyParameter(Hex.decode("5F060D3716B345C253F6749ABAC10917")), "355F697E8B868B65B25A04E18D782AFA", "ACC863637868E3E068D2FD6E3508454A"), new BlockCipherVectorTest(12, new AESLightEngine(), new KeyParameter(Hex.decode("000000000000000000000000000000000000000000000000")), "80000000000000000000000000000000", "6CD02513E8D4DC986B4AFE087A60BD0C"), new BlockCipherMonteCarloTest(13, 10000, new AESLightEngine(), new KeyParameter(Hex.decode("AAFE47EE82411A2BF3F6752AE8D7831138F041560631B114")), "F3F6752AE8D7831138F041560631B114", "77BA00ED5412DFF27C8ED91F3C376172"), new BlockCipherVectorTest(14, new AESLightEngine(), new KeyParameter(Hex.decode("0000000000000000000000000000000000000000000000000000000000000000")), "80000000000000000000000000000000", "DDC6BF790C15760D8D9AEB6F9A75FD4E"), new BlockCipherMonteCarloTest(15, 10000, new AESLightEngine(), new KeyParameter(Hex.decode("28E79E2AFC5F7745FCCABE2F6257C2EF4C4EDFB37324814ED4137C288711A386")), "C737317FE0846F132B23C8C2A672CE22", "E58B82BFBA53C0040DC610C642121168"), new BlockCipherVectorTest(16, new AESLightEngine(), new KeyParameter(Hex.decode("80000000000000000000000000000000")), "00000000000000000000000000000000", "0EDD33D3C621E546455BD8BA1418BEC8"), new BlockCipherVectorTest(17, new AESLightEngine(), new KeyParameter(Hex.decode("00000000000000000000000000000080")), "00000000000000000000000000000000", "172AEAB3D507678ECAF455C12587ADB7"), new BlockCipherMonteCarloTest(18, 10000, new AESLightEngine(), new KeyParameter(Hex.decode("00000000000000000000000000000000")), "00000000000000000000000000000000", "C34C052CC0DA8D73451AFE5F03BE297F"), new BlockCipherMonteCarloTest(19, 10000, new AESLightEngine(), new KeyParameter(Hex.decode("5F060D3716B345C253F6749ABAC10917")), "355F697E8B868B65B25A04E18D782AFA", "ACC863637868E3E068D2FD6E3508454A"), new BlockCipherVectorTest(20, new AESLightEngine(), new KeyParameter(Hex.decode("000000000000000000000000000000000000000000000000")), "80000000000000000000000000000000", "6CD02513E8D4DC986B4AFE087A60BD0C"), new BlockCipherMonteCarloTest(21, 10000, new AESLightEngine(), new KeyParameter(Hex.decode("AAFE47EE82411A2BF3F6752AE8D7831138F041560631B114")), "F3F6752AE8D7831138F041560631B114", "77BA00ED5412DFF27C8ED91F3C376172"), new BlockCipherVectorTest(22, new AESLightEngine(), new KeyParameter(Hex.decode("0000000000000000000000000000000000000000000000000000000000000000")), "80000000000000000000000000000000", "DDC6BF790C15760D8D9AEB6F9A75FD4E"), new BlockCipherMonteCarloTest(23, 10000, new AESLightEngine(), new KeyParameter(Hex.decode("28E79E2AFC5F7745FCCABE2F6257C2EF4C4EDFB37324814ED4137C288711A386")), "C737317FE0846F132B23C8C2A672CE22", "E58B82BFBA53C0040DC610C642121168") }; private BlockCipher _engine = new AESLightEngine(); AESLightTest() { super(tests, new AESLightEngine(), new KeyParameter(new byte[16])); } public String getName() { return "AESLight"; } public void performTest() throws Exception { super.performTest(); byte[] keyBytes = new byte[16]; _engine.init(true, new KeyParameter(keyBytes)); // // init tests // try { byte[] dudKey = new byte[6]; _engine.init(true, new KeyParameter(dudKey)); fail("failed key length check"); } catch (IllegalArgumentException e) { // expected } try { byte[] iv = new byte[16]; _engine.init(true, new ParametersWithIV(null, iv)); fail("failed parameter check"); } catch (IllegalArgumentException e) { // expected } } public static void main( String[] args) { runTest(new AESLightTest()); } } bouncycastle-1.49.orig/test/src/org/bouncycastle/crypto/test/XTEATest.java0000644000175000017500000000273010540153517026227 0ustar ebourgebourgpackage org.bouncycastle.crypto.test; import org.bouncycastle.crypto.engines.XTEAEngine; import org.bouncycastle.crypto.params.KeyParameter; import org.bouncycastle.util.encoders.Hex; import org.bouncycastle.util.test.SimpleTest; /** * TEA tester - based on C implementation results from http://www.simonshepherd.supanet.com/tea.htm */ public class XTEATest extends CipherTest { static SimpleTest[] tests = { new BlockCipherVectorTest(0, new XTEAEngine(), new KeyParameter(Hex.decode("00000000000000000000000000000000")), "0000000000000000", "dee9d4d8f7131ed9"), new BlockCipherVectorTest(1, new XTEAEngine(), new KeyParameter(Hex.decode("00000000000000000000000000000000")), "0102030405060708", "065c1b8975c6a816"), new BlockCipherVectorTest(2, new XTEAEngine(), new KeyParameter(Hex.decode("0123456712345678234567893456789A")), "0000000000000000", "1ff9a0261ac64264"), new BlockCipherVectorTest(3, new XTEAEngine(), new KeyParameter(Hex.decode("0123456712345678234567893456789A")), "0102030405060708", "8c67155b2ef91ead"), }; XTEATest() { super(tests, new XTEAEngine(), new KeyParameter(new byte[16])); } public String getName() { return "XTEA"; } public static void main( String[] args) { runTest(new XTEATest()); } } bouncycastle-1.49.orig/test/src/org/bouncycastle/crypto/test/Grain128Test.java0000644000175000017500000000630012151552117026755 0ustar ebourgebourgpackage org.bouncycastle.crypto.test; import org.bouncycastle.crypto.CipherParameters; import org.bouncycastle.crypto.StreamCipher; import org.bouncycastle.crypto.engines.Grain128Engine; import org.bouncycastle.crypto.params.KeyParameter; import org.bouncycastle.crypto.params.ParametersWithIV; import org.bouncycastle.util.encoders.Hex; import org.bouncycastle.util.test.SimpleTest; /** * Grain-128 Test */ public class Grain128Test extends SimpleTest { String keyStream1 = "f09b7bf7d7f6b5c2de2ffc73ac21397f"; String keyStream2 = "afb5babfa8de896b4b9c6acaf7c4fbfd"; public String getName() { return "Grain-128"; } public void performTest() { Grain128Test1(new ParametersWithIV(new KeyParameter(Hex .decode("00000000000000000000000000000000")), Hex .decode("000000000000000000000000"))); Grain128Test2(new ParametersWithIV(new KeyParameter(Hex .decode("0123456789abcdef123456789abcdef0")), Hex .decode("0123456789abcdef12345678"))); Grain128Test3(new ParametersWithIV(new KeyParameter(Hex .decode("0123456789abcdef123456789abcdef0")), Hex .decode("0123456789abcdef12345678"))); } private void Grain128Test1(CipherParameters params) { StreamCipher grain = new Grain128Engine(); byte[] in = new byte[16]; byte[] out = new byte[16]; grain.init(true, params); grain.processBytes(in, 0, in.length, out, 0); if (!areEqual(out, Hex.decode(keyStream1))) { mismatch("Keystream 1", keyStream1, out); } grain.reset(); grain.processBytes(in, 0, in.length, out, 0); if (!areEqual(out, Hex.decode(keyStream1))) { mismatch("Keystream 1", keyStream1, out); } } private void Grain128Test2(CipherParameters params) { StreamCipher grain = new Grain128Engine(); byte[] in = new byte[16]; byte[] out = new byte[16]; grain.init(true, params); grain.processBytes(in, 0, in.length, out, 0); if (!areEqual(out, Hex.decode(keyStream2))) { mismatch("Keystream 2", keyStream2, out); } grain.reset(); grain.processBytes(in, 0, in.length, out, 0); if (!areEqual(out, Hex.decode(keyStream2))) { mismatch("Keystream 2", keyStream2, out); } } private void Grain128Test3(CipherParameters params) { StreamCipher grain = new Grain128Engine(); byte[] in = "Encrypt me!".getBytes(); byte[] cipher = new byte[in.length]; byte[] clear = new byte[in.length]; grain.init(true, params); grain.processBytes(in, 0, in.length, cipher, 0); grain.reset(); grain.processBytes(cipher, 0, cipher.length, clear, 0); if (!areEqual(in, clear)) { mismatch("Test 3", new String(Hex.encode(in)), clear); } } private void mismatch(String name, String expected, byte[] found) { fail("mismatch on " + name, expected, new String(Hex.encode(found))); } public static void main(String[] args) { runTest(new Grain128Test()); } } bouncycastle-1.49.orig/test/src/org/bouncycastle/crypto/test/ISO9797Alg3MacTest.java0000644000175000017500000000751411511176633027620 0ustar ebourgebourgpackage org.bouncycastle.crypto.test; import org.bouncycastle.crypto.BlockCipher; import org.bouncycastle.crypto.Mac; import org.bouncycastle.crypto.engines.DESEngine; import org.bouncycastle.crypto.macs.ISO9797Alg3Mac; import org.bouncycastle.crypto.paddings.ISO7816d4Padding; import org.bouncycastle.crypto.params.KeyParameter; import org.bouncycastle.crypto.params.ParametersWithIV; import org.bouncycastle.util.Arrays; import org.bouncycastle.util.encoders.Hex; import org.bouncycastle.util.test.SimpleTest; public class ISO9797Alg3MacTest extends SimpleTest { static byte[] keyBytes = Hex.decode("7CA110454A1A6E570131D9619DC1376E"); static byte[] input1 = "Hello World !!!!".getBytes(); static byte[] output1 = Hex.decode("F09B856213BAB83B"); public ISO9797Alg3MacTest() { } public void performTest() { KeyParameter key = new KeyParameter(keyBytes); BlockCipher cipher = new DESEngine(); Mac mac = new ISO9797Alg3Mac(cipher); // // standard DAC - zero IV // mac.init(key); mac.update(input1, 0, input1.length); byte[] out = new byte[8]; mac.doFinal(out, 0); if (!areEqual(out, output1)) { fail("Failed - expected " + new String(Hex.encode(output1)) + " got " + new String(Hex.encode(out))); } // // reset // mac.reset(); mac.init(key); for (int i = 0; i != input1.length / 2; i++) { mac.update(input1[i]); } mac.update(input1, input1.length / 2, input1.length - (input1.length / 2)); mac.doFinal(out, 0); if (!areEqual(out, output1)) { fail("Reset failed - expected " + new String(Hex.encode(output1)) + " got " + new String(Hex.encode(out))); } testMacWithIv(); } private void testMacWithIv() { byte[] inputData = new byte[]{0x1, 0x2, 0x3, 0x4, 0x5, 0x6, 0x7, 0x8}; byte[] key = new byte[]{0x1, 0x2, 0x3, 0x4, 0x5, 0x6, 0x7, 0x8, 0x1, 0x2, 0x3, 0x4, 0x5, 0x6, 0x7, 0x8}; byte[] zeroIv = new byte[8]; byte[] nonZeroIv = new byte[]{0x5, 0x6, 0x7, 0x8, 0x1, 0x2, 0x3, 0x4}; KeyParameter simpleParameter = new KeyParameter(key); ParametersWithIV zeroIvParameter = new ParametersWithIV(new KeyParameter(key), zeroIv); ISO9797Alg3Mac mac1 = new ISO9797Alg3Mac(new DESEngine(), new ISO7816d4Padding()); // we calculate a reference MAC with a null IV mac1.init(simpleParameter); mac1.update(inputData, 0, inputData.length); byte[] output1 = new byte[mac1.getMacSize()]; mac1.doFinal(output1, 0); // we then check that passing a vector of 0s is the same as not using any IV ISO9797Alg3Mac mac2 = new ISO9797Alg3Mac(new DESEngine(), new ISO7816d4Padding()); mac2.init(zeroIvParameter); mac2.update(inputData, 0, inputData.length); byte[] output2 = new byte[mac2.getMacSize()]; mac2.doFinal(output2, 0); if (!Arrays.areEqual(output1, output2)) { fail("zero IV test failed"); } // and then check that a non zero IV parameter produces a different results. ParametersWithIV nonZeroIvParameter = new ParametersWithIV(new KeyParameter(key), nonZeroIv); mac2 = new ISO9797Alg3Mac(new DESEngine(), new ISO7816d4Padding()); mac2.init(nonZeroIvParameter); mac2.update(inputData, 0, inputData.length); output2 = new byte[mac2.getMacSize()]; mac2.doFinal(output2, 0); if (Arrays.areEqual(output1, output2)) { fail("non-zero IV test failed"); } } public String getName() { return "ISO9797Alg3Mac"; } public static void main( String[] args) { runTest(new ISO9797Alg3MacTest()); } } bouncycastle-1.49.orig/test/src/org/bouncycastle/crypto/test/BlowfishTest.java0000644000175000017500000000447210525306762027255 0ustar ebourgebourgpackage org.bouncycastle.crypto.test; import org.bouncycastle.crypto.engines.BlowfishEngine; import org.bouncycastle.crypto.params.KeyParameter; import org.bouncycastle.util.encoders.Hex; import org.bouncycastle.util.test.SimpleTest; /** * blowfish tester - vectors from http://www.counterpane.com/vectors.txt */ public class BlowfishTest extends CipherTest { static SimpleTest[] tests = { new BlockCipherVectorTest(0, new BlowfishEngine(), new KeyParameter(Hex.decode("0000000000000000")), "0000000000000000", "4EF997456198DD78"), new BlockCipherVectorTest(1, new BlowfishEngine(), new KeyParameter(Hex.decode("FFFFFFFFFFFFFFFF")), "FFFFFFFFFFFFFFFF", "51866FD5B85ECB8A"), new BlockCipherVectorTest(2, new BlowfishEngine(), new KeyParameter(Hex.decode("3000000000000000")), "1000000000000001", "7D856F9A613063F2"), new BlockCipherVectorTest(3, new BlowfishEngine(), new KeyParameter(Hex.decode("1111111111111111")), "1111111111111111", "2466DD878B963C9D"), new BlockCipherVectorTest(4, new BlowfishEngine(), new KeyParameter(Hex.decode("0123456789ABCDEF")), "1111111111111111", "61F9C3802281B096"), new BlockCipherVectorTest(5, new BlowfishEngine(), new KeyParameter(Hex.decode("FEDCBA9876543210")), "0123456789ABCDEF", "0ACEAB0FC6A0A28D"), new BlockCipherVectorTest(6, new BlowfishEngine(), new KeyParameter(Hex.decode("7CA110454A1A6E57")), "01A1D6D039776742", "59C68245EB05282B"), new BlockCipherVectorTest(7, new BlowfishEngine(), new KeyParameter(Hex.decode("0131D9619DC1376E")), "5CD54CA83DEF57DA", "B1B8CC0B250F09A0"), }; BlowfishTest() { super(tests, new BlowfishEngine(), new KeyParameter(new byte[16])); } public String getName() { return "Blowfish"; } public static void main( String[] args) { runTest(new BlowfishTest()); } } bouncycastle-1.49.orig/test/src/org/bouncycastle/crypto/test/SHA512t256DigestTest.java0000644000175000017500000000271512110601406030103 0ustar ebourgebourgpackage org.bouncycastle.crypto.test; import org.bouncycastle.crypto.Digest; import org.bouncycastle.crypto.digests.SHA512tDigest; /** * standard vector test for SHA-512/256 from FIPS 180-4. * * Note, only the last 2 message entries are FIPS originated.. */ public class SHA512t256DigestTest extends DigestTest { private static String[] messages = { "", "a", "abc", "abcdefghbcdefghicdefghijdefghijkefghijklfghijklmghijklmnhijklmnoijklmnopjklmnopqklmnopqrlmnopqrsmnopqrstnopqrstu" }; private static String[] digests = { "c672b8d1ef56ed28ab87c3622c5114069bdd3ad7b8f9737498d0c01ecef0967a", "455e518824bc0601f9fb858ff5c37d417d67c2f8e0df2babe4808858aea830f8", "53048E2681941EF99B2E29B76B4C7DABE4C2D0C634FC6D46E0E2F13107E7AF23", "3928E184FB8690F840DA3988121D31BE65CB9D3EF83EE6146FEAC861E19B563A" }; // 1 million 'a' static private String million_a_digest = "9a59a052930187a97038cae692f30708aa6491923ef5194394dc68d56c74fb21"; SHA512t256DigestTest() { super(new SHA512tDigest(256), messages, digests); } public void performTest() { super.performTest(); millionATest(million_a_digest); } protected Digest cloneDigest(Digest digest) { return new SHA512tDigest((SHA512tDigest)digest); } public static void main( String[] args) { runTest(new SHA512t256DigestTest()); } } bouncycastle-1.49.orig/test/src/org/bouncycastle/crypto/test/SHA224HMacTest.java0000644000175000017500000001022210330633061027047 0ustar ebourgebourgpackage org.bouncycastle.crypto.test; import org.bouncycastle.crypto.digests.SHA224Digest; import org.bouncycastle.crypto.macs.HMac; import org.bouncycastle.crypto.params.KeyParameter; import org.bouncycastle.util.Arrays; import org.bouncycastle.util.encoders.Hex; import org.bouncycastle.util.test.SimpleTestResult; import org.bouncycastle.util.test.Test; import org.bouncycastle.util.test.TestResult; /** * SHA224 HMac Test */ public class SHA224HMacTest implements Test { final static String[] keys = { "0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b", "4a656665", "aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa", "0102030405060708090a0b0c0d0e0f10111213141516171819", "0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c", "aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa", "aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa" }; final static String[] digests = { "896fb1128abbdf196832107cd49df33f47b4b1169912ba4f53684b22", "a30e01098bc6dbbf45690f3a7e9e6d0f8bbea2a39e6148008fd05e44", "7fb3cb3588c6c1f6ffa9694d7d6ad2649365b0c1f65d69d1ec8333ea", "6c11506874013cac6a2abc1bb382627cec6a90d86efc012de7afec5a", "0e2aea68a90c8d37c988bcdb9fca6fa8099cd857c7ec4a1815cac54c", "95e9a0db962095adaebe9b2d6f0dbce2d499f112f2d2b7273fa6870e", "3a854166ac5d9f023f54d517d0b39dbd946770db9c2b95c9f6f565d1" }; final static String[] messages = { "Hi There", "what do ya want for nothing?", "0xdddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddd", "0xcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcd", "Test With Truncation", "Test Using Larger Than Block-Size Key - Hash Key First", "This is a test using a larger than block-size key and a larger than block-size data. The key needs to be hashed before being used by the HMAC algorithm." }; public String getName() { return "SHA224HMac"; } public TestResult perform() { HMac hmac = new HMac(new SHA224Digest()); byte[] resBuf = new byte[hmac.getMacSize()]; for (int i = 0; i < messages.length; i++) { byte[] m = messages[i].getBytes(); if (messages[i].startsWith("0x")) { m = Hex.decode(messages[i].substring(2)); } hmac.init(new KeyParameter(Hex.decode(keys[i]))); hmac.update(m, 0, m.length); hmac.doFinal(resBuf, 0); if (!Arrays.areEqual(resBuf, Hex.decode(digests[i]))) { return new SimpleTestResult(false, getName() + ": Vector " + i + " failed got -" + new String(Hex.encode(resBuf))); } } // // test reset // int vector = 0; // vector used for test byte[] m = messages[vector].getBytes(); if (messages[vector].startsWith("0x")) { m = Hex.decode(messages[vector].substring(2)); } hmac.init(new KeyParameter(Hex.decode(keys[vector]))); hmac.update(m, 0, m.length); hmac.doFinal(resBuf, 0); hmac.reset(); hmac.update(m, 0, m.length); hmac.doFinal(resBuf, 0); if (!Arrays.areEqual(resBuf, Hex.decode(digests[vector]))) { return new SimpleTestResult(false, getName() + "Reset with vector " + vector + " failed"); } return new SimpleTestResult(true, getName() + ": Okay"); } public static void main( String[] args) { SHA224HMacTest test = new SHA224HMacTest(); TestResult result = test.perform(); System.out.println(result); } } bouncycastle-1.49.orig/test/src/org/bouncycastle/crypto/test/DHKEKGeneratorTest.java0000644000175000017500000000453410543152032030161 0ustar ebourgebourgpackage org.bouncycastle.crypto.test; import org.bouncycastle.asn1.DERObjectIdentifier; import org.bouncycastle.asn1.pkcs.PKCSObjectIdentifiers; import org.bouncycastle.crypto.DerivationFunction; import org.bouncycastle.crypto.DerivationParameters; import org.bouncycastle.crypto.agreement.kdf.DHKDFParameters; import org.bouncycastle.crypto.agreement.kdf.DHKEKGenerator; import org.bouncycastle.crypto.digests.SHA1Digest; import org.bouncycastle.util.encoders.Hex; import org.bouncycastle.util.test.SimpleTest; /** * DHKEK Generator tests - from RFC 2631. */ public class DHKEKGeneratorTest extends SimpleTest { private byte[] seed1 = Hex.decode("000102030405060708090a0b0c0d0e0f10111213"); private DERObjectIdentifier alg1 = PKCSObjectIdentifiers.id_alg_CMS3DESwrap; private byte[] result1 = Hex.decode("a09661392376f7044d9052a397883246b67f5f1ef63eb5fb"); private byte[] seed2 = Hex.decode("000102030405060708090a0b0c0d0e0f10111213"); private DERObjectIdentifier alg2 = PKCSObjectIdentifiers.id_alg_CMSRC2wrap; private byte[] partyAInfo = Hex.decode( "0123456789abcdeffedcba9876543201" + "0123456789abcdeffedcba9876543201" + "0123456789abcdeffedcba9876543201" + "0123456789abcdeffedcba9876543201"); private byte[] result2 = Hex.decode("48950c46e0530075403cce72889604e0"); public DHKEKGeneratorTest() { } public void performTest() { checkMask(1, new DHKEKGenerator(new SHA1Digest()), new DHKDFParameters(alg1, 192, seed1), result1); checkMask(2, new DHKEKGenerator(new SHA1Digest()), new DHKDFParameters(alg2, 128, seed2, partyAInfo), result2); } private void checkMask( int count, DerivationFunction kdf, DerivationParameters params, byte[] result) { byte[] data = new byte[result.length]; kdf.init(params); kdf.generateBytes(data, 0, data.length); if (!areEqual(result, data)) { fail("DHKEKGenerator failed generator test " + count); } } public String getName() { return "DHKEKGenerator"; } public static void main( String[] args) { runTest(new DHKEKGeneratorTest()); } } bouncycastle-1.49.orig/test/src/org/bouncycastle/crypto/test/ECIESKeyEncapsulationTest.java0000750000175000017500000001066112151252353031513 0ustar ebourgebourgpackage org.bouncycastle.crypto.test; import java.security.SecureRandom; import org.bouncycastle.asn1.sec.SECNamedCurves; import org.bouncycastle.asn1.x9.X9ECParameters; import org.bouncycastle.crypto.AsymmetricCipherKeyPair; import org.bouncycastle.crypto.digests.SHA1Digest; import org.bouncycastle.crypto.generators.ECKeyPairGenerator; import org.bouncycastle.crypto.generators.KDF2BytesGenerator; import org.bouncycastle.crypto.kems.ECIESKeyEncapsulation; import org.bouncycastle.crypto.params.ECDomainParameters; import org.bouncycastle.crypto.params.ECKeyGenerationParameters; import org.bouncycastle.crypto.params.KeyParameter; import org.bouncycastle.util.test.SimpleTest; /** * Tests for the ECIES Key Encapsulation Mechanism */ public class ECIESKeyEncapsulationTest extends SimpleTest { public String getName() { return "ECIESKeyEncapsulation"; } public void performTest() throws Exception { // Set EC domain parameters and generate key pair X9ECParameters spec = SECNamedCurves.getByName("secp224r1"); ECDomainParameters ecDomain = new ECDomainParameters(spec.getCurve(), spec.getG(), spec.getN()); ECKeyPairGenerator ecGen = new ECKeyPairGenerator(); ecGen.init(new ECKeyGenerationParameters(ecDomain, new SecureRandom())); AsymmetricCipherKeyPair keys = ecGen.generateKeyPair(); // Set ECIES-KEM parameters ECIESKeyEncapsulation kem; KDF2BytesGenerator kdf = new KDF2BytesGenerator(new SHA1Digest()); SecureRandom rnd = new SecureRandom(); byte[] out = new byte[57]; KeyParameter key1, key2; // Test basic ECIES-KEM kem = new ECIESKeyEncapsulation(kdf, rnd); kem.init(keys.getPublic()); key1 = (KeyParameter)kem.encrypt(out, 128); kem.init(keys.getPrivate()); key2 = (KeyParameter)kem.decrypt(out, 128); if (!areEqual(key1.getKey(), key2.getKey())) { fail("failed basic test"); } // Test ECIES-KEM using new cofactor mode kem = new ECIESKeyEncapsulation(kdf, rnd, true, false, false); kem.init(keys.getPublic()); key1 = (KeyParameter)kem.encrypt(out, 128); kem.init(keys.getPrivate()); key2 = (KeyParameter)kem.decrypt(out, 128); if (!areEqual(key1.getKey(), key2.getKey())) { fail("failed cofactor test"); } // Test ECIES-KEM using old cofactor mode kem = new ECIESKeyEncapsulation(kdf, rnd, false, true, false); kem.init(keys.getPublic()); key1 = (KeyParameter)kem.encrypt(out, 128); kem.init(keys.getPrivate()); key2 = (KeyParameter)kem.decrypt(out, 128); if (!areEqual(key1.getKey(), key2.getKey())) { fail("failed old cofactor test"); } // Test ECIES-KEM using single hash mode kem = new ECIESKeyEncapsulation(kdf, rnd, false, false, true); kem.init(keys.getPublic()); key1 = (KeyParameter)kem.encrypt(out, 128); kem.init(keys.getPrivate()); key2 = (KeyParameter)kem.decrypt(out, 128); if (!areEqual(key1.getKey(), key2.getKey())) { fail("failed single hash test"); } // Test ECIES-KEM using new cofactor mode and single hash mode kem = new ECIESKeyEncapsulation(kdf, rnd, true, false, true); kem.init(keys.getPublic()); key1 = (KeyParameter)kem.encrypt(out, 128); kem.init(keys.getPrivate()); key2 = (KeyParameter)kem.decrypt(out, 128); if (!areEqual(key1.getKey(), key2.getKey())) { fail("failed cofactor and single hash test"); } // Test ECIES-KEM using old cofactor mode and single hash mode kem = new ECIESKeyEncapsulation(kdf, rnd, false, true, true); kem.init(keys.getPublic()); key1 = (KeyParameter)kem.encrypt(out, 128); kem.init(keys.getPrivate()); key2 = (KeyParameter)kem.decrypt(out, 128); if (!areEqual(key1.getKey(), key2.getKey())) { fail("failed old cofactor and single hash test"); } } public static void main( String[] args) { runTest(new ECIESKeyEncapsulationTest()); } } bouncycastle-1.49.orig/test/src/org/bouncycastle/crypto/test/DESTest.java0000644000175000017500000001737410531736712026117 0ustar ebourgebourgpackage org.bouncycastle.crypto.test; import org.bouncycastle.crypto.KeyGenerationParameters; import org.bouncycastle.crypto.engines.DESEngine; import org.bouncycastle.crypto.generators.DESKeyGenerator; import org.bouncycastle.crypto.modes.CBCBlockCipher; import org.bouncycastle.crypto.modes.CFBBlockCipher; import org.bouncycastle.crypto.modes.OFBBlockCipher; import org.bouncycastle.crypto.params.DESParameters; import org.bouncycastle.crypto.params.KeyParameter; import org.bouncycastle.crypto.params.ParametersWithIV; import org.bouncycastle.util.encoders.Hex; import org.bouncycastle.util.test.SimpleTest; import java.security.SecureRandom; class DESParityTest extends SimpleTest { public String getName() { return "DESParityTest"; } public void performTest() { byte[] k1In = { (byte)0xff, (byte)0xff, (byte)0xff, (byte)0xff, (byte)0xff, (byte)0xff, (byte)0xff, (byte)0xff }; byte[] k1Out = { (byte)0xfe, (byte)0xfe, (byte)0xfe, (byte)0xfe, (byte)0xfe, (byte)0xfe, (byte)0xfe, (byte)0xfe }; byte[] k2In = { (byte)0xef, (byte)0xcb, (byte)0xda, (byte)0x4f, (byte)0xaa, (byte)0x99, (byte)0x7f, (byte)0x63 }; byte[] k2Out = { (byte)0xef, (byte)0xcb, (byte)0xda, (byte)0x4f, (byte)0xab, (byte)0x98, (byte)0x7f, (byte)0x62 }; DESParameters.setOddParity(k1In); for (int i = 0; i != k1In.length; i++) { if (k1In[i] != k1Out[i]) { fail("Failed " + "got " + new String(Hex.encode(k1In)) + " expected " + new String(Hex.encode(k1Out))); } } DESParameters.setOddParity(k2In); for (int i = 0; i != k2In.length; i++) { if (k2In[i] != k2Out[i]) { fail("Failed " + "got " + new String(Hex.encode(k2In)) + " expected " + new String(Hex.encode(k2Out))); } } } } class KeyGenTest extends SimpleTest { public String getName() { return "KeyGenTest"; } public void performTest() { DESKeyGenerator keyGen = new DESKeyGenerator(); keyGen.init(new KeyGenerationParameters(new SecureRandom(), 56)); byte[] kB = keyGen.generateKey(); if (kB.length != 8) { fail("DES bit key wrong length."); } } } class DESParametersTest extends SimpleTest { static private byte[] weakKeys = { (byte)0x01,(byte)0x01,(byte)0x01,(byte)0x01, (byte)0x01,(byte)0x01,(byte)0x01,(byte)0x01, (byte)0x1f,(byte)0x1f,(byte)0x1f,(byte)0x1f, (byte)0x0e,(byte)0x0e,(byte)0x0e,(byte)0x0e, (byte)0xe0,(byte)0xe0,(byte)0xe0,(byte)0xe0, (byte)0xf1,(byte)0xf1,(byte)0xf1,(byte)0xf1, (byte)0xfe,(byte)0xfe,(byte)0xfe,(byte)0xfe, (byte)0xfe,(byte)0xfe,(byte)0xfe,(byte)0xfe, /* semi-weak keys */ (byte)0x01,(byte)0xfe,(byte)0x01,(byte)0xfe, (byte)0x01,(byte)0xfe,(byte)0x01,(byte)0xfe, (byte)0x1f,(byte)0xe0,(byte)0x1f,(byte)0xe0, (byte)0x0e,(byte)0xf1,(byte)0x0e,(byte)0xf1, (byte)0x01,(byte)0xe0,(byte)0x01,(byte)0xe0, (byte)0x01,(byte)0xf1,(byte)0x01,(byte)0xf1, (byte)0x1f,(byte)0xfe,(byte)0x1f,(byte)0xfe, (byte)0x0e,(byte)0xfe,(byte)0x0e,(byte)0xfe, (byte)0x01,(byte)0x1f,(byte)0x01,(byte)0x1f, (byte)0x01,(byte)0x0e,(byte)0x01,(byte)0x0e, (byte)0xe0,(byte)0xfe,(byte)0xe0,(byte)0xfe, (byte)0xf1,(byte)0xfe,(byte)0xf1,(byte)0xfe, (byte)0xfe,(byte)0x01,(byte)0xfe,(byte)0x01, (byte)0xfe,(byte)0x01,(byte)0xfe,(byte)0x01, (byte)0xe0,(byte)0x1f,(byte)0xe0,(byte)0x1f, (byte)0xf1,(byte)0x0e,(byte)0xf1,(byte)0x0e, (byte)0xe0,(byte)0x01,(byte)0xe0,(byte)0x01, (byte)0xf1,(byte)0x01,(byte)0xf1,(byte)0x01, (byte)0xfe,(byte)0x1f,(byte)0xfe,(byte)0x1f, (byte)0xfe,(byte)0x0e,(byte)0xfe,(byte)0x0e, (byte)0x1f,(byte)0x01,(byte)0x1f,(byte)0x01, (byte)0x0e,(byte)0x01,(byte)0x0e,(byte)0x01, (byte)0xfe,(byte)0xe0,(byte)0xfe,(byte)0xe0, (byte)0xfe,(byte)0xf1,(byte)0xfe,(byte)0xf1 }; public String getName() { return "DESParameters"; } public void performTest() throws Exception { try { DESParameters.isWeakKey(new byte[4], 0); fail("no exception on small key"); } catch (IllegalArgumentException e) { if (!e.getMessage().equals("key material too short.")) { fail("wrong exception"); } } try { new DESParameters(weakKeys); fail("no exception on weak key"); } catch (IllegalArgumentException e) { if (!e.getMessage().equals("attempt to create weak DES key")) { fail("wrong exception"); } } for (int i = 0; i != weakKeys.length; i += 8) { if (!DESParameters.isWeakKey(weakKeys, i)) { fail("weakKey test failed"); } } } } /** * DES tester - vectors from FIPS 81 */ public class DESTest extends CipherTest { static String input1 = "4e6f77206973207468652074696d6520666f7220616c6c20"; static String input2 = "4e6f7720697320746865"; static String input3 = "4e6f7720697320746865aabbcc"; static SimpleTest[] tests = { new BlockCipherVectorTest(0, new DESEngine(), new KeyParameter(Hex.decode("0123456789abcdef")), input1, "3fa40e8a984d48156a271787ab8883f9893d51ec4b563b53"), new BlockCipherVectorTest(1, new CBCBlockCipher(new DESEngine()), new ParametersWithIV(new KeyParameter(Hex.decode("0123456789abcdef")), Hex.decode("1234567890abcdef")), input1, "e5c7cdde872bf27c43e934008c389c0f683788499a7c05f6"), new BlockCipherVectorTest(2, new CFBBlockCipher(new DESEngine(), 8), new ParametersWithIV(new KeyParameter(Hex.decode("0123456789abcdef")), Hex.decode("1234567890abcdef")), input2, "f31fda07011462ee187f"), new BlockCipherVectorTest(3, new CFBBlockCipher(new DESEngine(), 64), new ParametersWithIV(new KeyParameter(Hex.decode("0123456789abcdef")), Hex.decode("1234567890abcdef")), input1, "f3096249c7f46e51a69e839b1a92f78403467133898ea622"), new BlockCipherVectorTest(4, new OFBBlockCipher(new DESEngine(), 8), new ParametersWithIV(new KeyParameter(Hex.decode("0123456789abcdef")), Hex.decode("1234567890abcdef")), input2, "f34a2850c9c64985d684"), new BlockCipherVectorTest(5, new CFBBlockCipher(new DESEngine(), 64), new ParametersWithIV(new KeyParameter(Hex.decode("0123456789abcdef")), Hex.decode("1234567890abcdef")), input3, "f3096249c7f46e51a69e0954bf"), new BlockCipherVectorTest(6, new OFBBlockCipher(new DESEngine(), 64), new ParametersWithIV(new KeyParameter(Hex.decode("0123456789abcdef")), Hex.decode("1234567890abcdef")), input3, "f3096249c7f46e5135f2c0eb8b"), new DESParityTest(), new DESParametersTest(), new KeyGenTest() }; public DESTest() { super(tests, new DESEngine(), new KeyParameter(new byte[8])); } public String getName() { return "DES"; } public static void main( String[] args) { runTest(new DESTest()); } } bouncycastle-1.49.orig/test/src/org/bouncycastle/crypto/test/MD2DigestTest.java0000644000175000017500000000240210330633061027176 0ustar ebourgebourgpackage org.bouncycastle.crypto.test; import org.bouncycastle.crypto.Digest; import org.bouncycastle.crypto.digests.MD2Digest; /** * standard vector test for MD2 * from RFC1319 by B.Kaliski of RSA Laboratories April 1992 * */ public class MD2DigestTest extends DigestTest { static final String messages[] = { "", "a", "abc", "message digest", "abcdefghijklmnopqrstuvwxyz", "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789", "12345678901234567890123456789012345678901234567890123456789012345678901234567890" }; static final String digests[] = { "8350e5a3e24c153df2275c9f80692773", "32ec01ec4a6dac72c0ab96fb34c0b5d1", "da853b0d3f88d99b30283a69e6ded6bb", "ab4f496bfb2a530b219ff33031fe06b0", "4e8ddff3650292ab5a4108c3aa47940b", "da33def2a42df13975352846c30338cd", "d5976f79d83d3a0dc9806c3c66f3efd8" }; MD2DigestTest() { super(new MD2Digest(), messages, digests); } protected Digest cloneDigest( Digest digest) { return new MD2Digest((MD2Digest)digest); } public static void main( String[] args) { runTest(new MD2DigestTest()); } } bouncycastle-1.49.orig/test/src/org/bouncycastle/crypto/test/RC6Test.java0000644000175000017500000000515710525306762026073 0ustar ebourgebourgpackage org.bouncycastle.crypto.test; import org.bouncycastle.crypto.engines.RC6Engine; import org.bouncycastle.crypto.params.KeyParameter; import org.bouncycastle.util.encoders.Hex; import org.bouncycastle.util.test.SimpleTest; /** * RC6 Test - test vectors from AES Submitted RSA Reference implementation. * ftp://ftp.funet.fi/pub/crypt/cryptography/symmetric/aes/rc6-unix-refc.tar */ public class RC6Test extends CipherTest { static SimpleTest[] tests = { new BlockCipherVectorTest(0, new RC6Engine(), new KeyParameter( Hex.decode("00000000000000000000000000000000")), "80000000000000000000000000000000", "f71f65e7b80c0c6966fee607984b5cdf"), new BlockCipherVectorTest(1, new RC6Engine(), new KeyParameter( Hex.decode("000000000000000000000000000000008000000000000000")), "00000000000000000000000000000000", "dd04c176440bbc6686c90aee775bd368"), new BlockCipherVectorTest(2, new RC6Engine(), new KeyParameter( Hex.decode("000000000000000000000000000000000000001000000000")), "00000000000000000000000000000000", "937fe02d20fcb72f0f57201012b88ba4"), new BlockCipherVectorTest(3, new RC6Engine(), new KeyParameter( Hex.decode("00000001000000000000000000000000")), "00000000000000000000000000000000", "8a380594d7396453771a1dfbe2914c8e"), new BlockCipherVectorTest(4, new RC6Engine(), new KeyParameter( Hex.decode("1000000000000000000000000000000000000000000000000000000000000000")), "00000000000000000000000000000000", "11395d4bfe4c8258979ee2bf2d24dff4"), new BlockCipherVectorTest(5, new RC6Engine(), new KeyParameter( Hex.decode("0000000000000000000000000000000000080000000000000000000000000000")), "00000000000000000000000000000000", "3d6f7e99f6512553bb983e8f75672b97") }; RC6Test() { super(tests, new RC6Engine(), new KeyParameter(new byte[32])); } public String getName() { return "RC6"; } public static void main( String[] args) { runTest(new RC6Test()); } } bouncycastle-1.49.orig/test/src/org/bouncycastle/crypto/test/SHA512HMacTest.java0000644000175000017500000001121210330633061027047 0ustar ebourgebourgpackage org.bouncycastle.crypto.test; import org.bouncycastle.crypto.digests.SHA512Digest; import org.bouncycastle.crypto.macs.HMac; import org.bouncycastle.crypto.params.KeyParameter; import org.bouncycastle.util.Arrays; import org.bouncycastle.util.encoders.Hex; import org.bouncycastle.util.test.SimpleTestResult; import org.bouncycastle.util.test.Test; import org.bouncycastle.util.test.TestResult; /** * SHA512 HMac Test */ public class SHA512HMacTest implements Test { final static String[] keys = { "0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b", "4a656665", "aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa", "0102030405060708090a0b0c0d0e0f10111213141516171819", "0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c", "aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa", "aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa" }; final static String[] digests = { "87aa7cdea5ef619d4ff0b4241a1d6cb02379f4e2ce4ec2787ad0b30545e17cdedaa833b7d6b8a702038b274eaea3f4e4be9d914eeb61f1702e696c203a126854", "164b7a7bfcf819e2e395fbe73b56e0a387bd64222e831fd610270cd7ea2505549758bf75c05a994a6d034f65f8f0e6fdcaeab1a34d4a6b4b636e070a38bce737", "fa73b0089d56a284efb0f0756c890be9b1b5dbdd8ee81a3655f83e33b2279d39bf3e848279a722c806b485a47e67c807b946a337bee8942674278859e13292fb", "b0ba465637458c6990e5a8c5f61d4af7e576d97ff94b872de76f8050361ee3dba91ca5c11aa25eb4d679275cc5788063a5f19741120c4f2de2adebeb10a298dd", "415fad6271580a531d4179bc891d87a650188707922a4fbb36663a1eb16da008711c5b50ddd0fc235084eb9d3364a1454fb2ef67cd1d29fe6773068ea266e96b", "80b24263c7c1a3ebb71493c1dd7be8b49b46d1f41b4aeec1121b013783f8f3526b56d037e05f2598bd0fd2215d6a1e5295e64f73f63f0aec8b915a985d786598", "e37b6a775dc87dbaa4dfa9f96e5e3ffddebd71f8867289865df5a32d20cdc944b6022cac3c4982b10d5eeb55c3e4de15134676fb6de0446065c97440fa8c6a58" }; final static String[] messages = { "Hi There", "what do ya want for nothing?", "0xdddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddd", "0xcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcd", "Test With Truncation", "Test Using Larger Than Block-Size Key - Hash Key First", "This is a test using a larger than block-size key and a larger than block-size data. The key needs to be hashed before being used by the HMAC algorithm." }; public String getName() { return "SHA512HMac"; } public TestResult perform() { HMac hmac = new HMac(new SHA512Digest()); byte[] resBuf = new byte[hmac.getMacSize()]; for (int i = 0; i < messages.length; i++) { byte[] m = messages[i].getBytes(); if (messages[i].startsWith("0x")) { m = Hex.decode(messages[i].substring(2)); } hmac.init(new KeyParameter(Hex.decode(keys[i]))); hmac.update(m, 0, m.length); hmac.doFinal(resBuf, 0); if (!Arrays.areEqual(resBuf, Hex.decode(digests[i]))) { return new SimpleTestResult(false, getName() + ": Vector " + i + " failed got -" + new String(Hex.encode(resBuf))); } } // // test reset // int vector = 0; // vector used for test byte[] m = messages[vector].getBytes(); if (messages[vector].startsWith("0x")) { m = Hex.decode(messages[vector].substring(2)); } hmac.init(new KeyParameter(Hex.decode(keys[vector]))); hmac.update(m, 0, m.length); hmac.doFinal(resBuf, 0); hmac.reset(); hmac.update(m, 0, m.length); hmac.doFinal(resBuf, 0); if (!Arrays.areEqual(resBuf, Hex.decode(digests[vector]))) { return new SimpleTestResult(false, getName() + "Reset with vector " + vector + " failed"); } return new SimpleTestResult(true, getName() + ": Okay"); } public static void main( String[] args) { SHA512HMacTest test = new SHA512HMacTest(); TestResult result = test.perform(); System.out.println(result); } } bouncycastle-1.49.orig/test/src/org/bouncycastle/crypto/test/RIPEMD320DigestTest.java0000644000175000017500000000367710330633061030040 0ustar ebourgebourgpackage org.bouncycastle.crypto.test; import org.bouncycastle.crypto.Digest; import org.bouncycastle.crypto.digests.RIPEMD320Digest; /** * RIPEMD320 Digest Test */ public class RIPEMD320DigestTest extends DigestTest { final static String[] messages = { "", "a", "abc", "message digest", "abcdefghijklmnopqrstuvwxyz", "abcdbcdecdefdefgefghfghighijhijkijkljklmklmnlmnomnopnopq", "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789", "12345678901234567890123456789012345678901234567890123456789012345678901234567890" }; final static String[] digests = { "22d65d5661536cdc75c1fdf5c6de7b41b9f27325ebc61e8557177d705a0ec880151c3a32a00899b8", "ce78850638f92658a5a585097579926dda667a5716562cfcf6fbe77f63542f99b04705d6970dff5d", "de4c01b3054f8930a79d09ae738e92301e5a17085beffdc1b8d116713e74f82fa942d64cdbc4682d", "3a8e28502ed45d422f68844f9dd316e7b98533fa3f2a91d29f84d425c88d6b4eff727df66a7c0197", "cabdb1810b92470a2093aa6bce05952c28348cf43ff60841975166bb40ed234004b8824463e6b009", "d034a7950cf722021ba4b84df769a5de2060e259df4c9bb4a4268c0e935bbc7470a969c9d072a1ac", "ed544940c86d67f250d232c30b7b3e5770e0c60c8cb9a4cafe3b11388af9920e1b99230b843c86a4", "557888af5f6d8ed62ab66945c6d2a0a47ecd5341e915eb8fea1d0524955f825dc717e4a008ab2d42" }; final static String million_a_digest = "bdee37f4371e20646b8b0d862dda16292ae36f40965e8c8509e63d1dbddecc503e2b63eb9245bb66"; RIPEMD320DigestTest() { super(new RIPEMD320Digest(), messages, digests); } public void performTest() { super.performTest(); millionATest(million_a_digest); } protected Digest cloneDigest(Digest digest) { return new RIPEMD320Digest((RIPEMD320Digest)digest); } public static void main( String[] args) { runTest(new RIPEMD320DigestTest()); } } bouncycastle-1.49.orig/test/src/org/bouncycastle/crypto/test/ECDHKEKGeneratorTest.java0000644000175000017500000000511010543152032030360 0ustar ebourgebourgpackage org.bouncycastle.crypto.test; import org.bouncycastle.asn1.DERObjectIdentifier; import org.bouncycastle.asn1.nist.NISTObjectIdentifiers; import org.bouncycastle.asn1.pkcs.PKCSObjectIdentifiers; import org.bouncycastle.crypto.DerivationFunction; import org.bouncycastle.crypto.DerivationParameters; import org.bouncycastle.crypto.agreement.kdf.DHKDFParameters; import org.bouncycastle.crypto.agreement.kdf.ECDHKEKGenerator; import org.bouncycastle.crypto.digests.SHA1Digest; import org.bouncycastle.util.encoders.Hex; import org.bouncycastle.util.test.SimpleTest; /** * ECDHKEK Generator tests. */ public class ECDHKEKGeneratorTest extends SimpleTest { private byte[] seed1 = Hex.decode("db4a8daba1f98791d54e940175dd1a5f3a0826a1066aa9b668d4dc1e1e0790158dcad1533c03b44214d1b61fefa8b579"); private DERObjectIdentifier alg1 = NISTObjectIdentifiers.id_aes256_wrap; private byte[] result1 = Hex.decode("8ecc6d85caf25eaba823a7d620d4ab0d33e4c645f2"); private byte[] seed2 = Hex.decode("75d7487b5d3d2bfb3c69ce0365fe64e3bfab5d0d63731628a9f47eb8fddfa28c65decaf228a0b38f0c51c6a3356d7c56"); private DERObjectIdentifier alg2 = NISTObjectIdentifiers.id_aes128_wrap; private byte[] result2 = Hex.decode("042be1faca3a4a8fc859241bfb87ba35"); private byte[] seed3 = Hex.decode("fdeb6d809f997e8ac174d638734dc36d37aaf7e876e39967cd82b1cada3de772449788461ee7f856bad9305627f8e48b"); private DERObjectIdentifier alg3 = PKCSObjectIdentifiers.id_alg_CMS3DESwrap; private byte[] result3 = Hex.decode("bcd701fc92109b1b9d6f3b6497ad5ca9627fa8a597010305"); public ECDHKEKGeneratorTest() { } public void performTest() { checkMask(1, new ECDHKEKGenerator(new SHA1Digest()), new DHKDFParameters(alg1, 256, seed1), result1); checkMask(2, new ECDHKEKGenerator(new SHA1Digest()), new DHKDFParameters(alg2, 128, seed2), result2); checkMask(3, new ECDHKEKGenerator(new SHA1Digest()), new DHKDFParameters(alg3, 192, seed3), result3); } private void checkMask( int count, DerivationFunction kdf, DerivationParameters params, byte[] result) { byte[] data = new byte[result.length]; kdf.init(params); kdf.generateBytes(data, 0, data.length); if (!areEqual(result, data)) { fail("ECDHKEKGenerator failed generator test " + count); } } public String getName() { return "ECDHKEKGenerator"; } public static void main( String[] args) { runTest(new ECDHKEKGeneratorTest()); } } bouncycastle-1.49.orig/test/src/org/bouncycastle/crypto/test/OCBTest.java0000644000175000017500000002204112132420515026060 0ustar ebourgebourgpackage org.bouncycastle.crypto.test; import org.bouncycastle.crypto.InvalidCipherTextException; import org.bouncycastle.crypto.engines.AESFastEngine; import org.bouncycastle.crypto.modes.AEADBlockCipher; import org.bouncycastle.crypto.modes.OCBBlockCipher; import org.bouncycastle.crypto.params.AEADParameters; import org.bouncycastle.crypto.params.KeyParameter; import org.bouncycastle.crypto.params.ParametersWithIV; import org.bouncycastle.util.Arrays; import org.bouncycastle.util.encoders.Hex; import org.bouncycastle.util.test.SimpleTest; /** * Test vectors from the "work in progress" Internet-Draft The OCB Authenticated-Encryption * Algorithm */ public class OCBTest extends SimpleTest { private static final String K = "000102030405060708090A0B0C0D0E0F"; private static final String N = "000102030405060708090A0B"; // Each test vector contains the strings A, P, C in order private static final String[][] TEST_VECTORS = new String[][]{ {"", "", "197B9C3C441D3C83EAFB2BEF633B9182"}, {"0001020304050607", "0001020304050607", "92B657130A74B85A16DC76A46D47E1EAD537209E8A96D14E"}, {"0001020304050607", "", "98B91552C8C009185044E30A6EB2FE21"}, {"", "0001020304050607", "92B657130A74B85A971EFFCAE19AD4716F88E87B871FBEED"}, {"000102030405060708090A0B0C0D0E0F", "000102030405060708090A0B0C0D0E0F", "BEA5E8798DBE7110031C144DA0B26122776C9924D6723A1F" + "C4524532AC3E5BEB"}, {"000102030405060708090A0B0C0D0E0F", "", "7DDB8E6CEA6814866212509619B19CC6"}, {"", "000102030405060708090A0B0C0D0E0F", "BEA5E8798DBE7110031C144DA0B2612213CC8B747807121A" + "4CBB3E4BD6B456AF"}, {"000102030405060708090A0B0C0D0E0F1011121314151617", "000102030405060708090A0B0C0D0E0F1011121314151617", "BEA5E8798DBE7110031C144DA0B26122FCFCEE7A2A8D4D48" + "5FA94FC3F38820F1DC3F3D1FD4E55E1C"}, {"000102030405060708090A0B0C0D0E0F1011121314151617", "", "282026DA3068BC9FA118681D559F10F6"}, {"", "000102030405060708090A0B0C0D0E0F1011121314151617", "BEA5E8798DBE7110031C144DA0B26122FCFCEE7A2A8D4D48" + "6EF2F52587FDA0ED97DC7EEDE241DF68"}, { "000102030405060708090A0B0C0D0E0F1011121314151617" + "18191A1B1C1D1E1F", "000102030405060708090A0B0C0D0E0F1011121314151617" + "18191A1B1C1D1E1F", "BEA5E8798DBE7110031C144DA0B26122CEAAB9B05DF771A6" + "57149D53773463CBB2A040DD3BD5164372D76D7BB6824240"}, {"000102030405060708090A0B0C0D0E0F1011121314151617" + "18191A1B1C1D1E1F", "", "E1E072633BADE51A60E85951D9C42A1B"}, { "", "000102030405060708090A0B0C0D0E0F1011121314151617" + "18191A1B1C1D1E1F", "BEA5E8798DBE7110031C144DA0B26122CEAAB9B05DF771A6" + "57149D53773463CB4A3BAE824465CFDAF8C41FC50C7DF9D9"}, { "000102030405060708090A0B0C0D0E0F1011121314151617" + "18191A1B1C1D1E1F2021222324252627", "000102030405060708090A0B0C0D0E0F1011121314151617" + "18191A1B1C1D1E1F2021222324252627", "BEA5E8798DBE7110031C144DA0B26122CEAAB9B05DF771A6" + "57149D53773463CB68C65778B058A635659C623211DEEA0D" + "E30D2C381879F4C8"}, {"000102030405060708090A0B0C0D0E0F1011121314151617" + "18191A1B1C1D1E1F2021222324252627", "", "7AEB7A69A1687DD082CA27B0D9A37096"}, { "", "000102030405060708090A0B0C0D0E0F1011121314151617" + "18191A1B1C1D1E1F2021222324252627", "BEA5E8798DBE7110031C144DA0B26122CEAAB9B05DF771A6" + "57149D53773463CB68C65778B058A635060C8467F4ABAB5E" + "8B3C2067A2E115DC"}, }; public String getName() { return "OCB"; } public void performTest() throws Exception { for (int i = 0; i < TEST_VECTORS.length; ++i) { runTestCase("Test Case " + i, TEST_VECTORS[i]); } runLongerTestCase(128, Hex.decode("B2B41CBF9B05037DA7F16C24A35C1C94")); runLongerTestCase(192, Hex.decode("1529F894659D2B51B776740211E7D083")); runLongerTestCase(256, Hex.decode("42B83106E473C0EEE086C8D631FD4C7B")); } private void runTestCase(String testName, String[] testVector) throws InvalidCipherTextException { runTestCase(testName, testVector, 128); } private void runTestCase(String testName, String[] testVector, int macLengthBits) throws InvalidCipherTextException { byte[] key = Hex.decode(K); byte[] nonce = Hex.decode(N); int pos = 0; byte[] A = Hex.decode(testVector[pos++]); byte[] P = Hex.decode(testVector[pos++]); byte[] C = Hex.decode(testVector[pos++]); int macLengthBytes = macLengthBits / 8; // TODO Variations processing AAD and cipher bytes incrementally KeyParameter keyParameter = new KeyParameter(key); AEADParameters aeadParameters = new AEADParameters(keyParameter, macLengthBits, nonce, A); OCBBlockCipher encCipher = initCipher(true, aeadParameters); OCBBlockCipher decCipher = initCipher(false, aeadParameters); checkTestCase(encCipher, decCipher, testName, macLengthBytes, P, C); checkTestCase(encCipher, decCipher, testName + " (reused)", macLengthBytes, P, C); // TODO Key reuse } private OCBBlockCipher initCipher(boolean forEncryption, AEADParameters parameters) { OCBBlockCipher c = new OCBBlockCipher(new AESFastEngine(), new AESFastEngine()); c.init(forEncryption, parameters); return c; } private void checkTestCase(OCBBlockCipher encCipher, OCBBlockCipher decCipher, String testName, int macLengthBytes, byte[] P, byte[] C) throws InvalidCipherTextException { byte[] tag = Arrays.copyOfRange(C, C.length - macLengthBytes, C.length); { byte[] enc = new byte[encCipher.getOutputSize(P.length)]; int len = encCipher.processBytes(P, 0, P.length, enc, 0); len += encCipher.doFinal(enc, len); if (enc.length != len) { fail("encryption reported incorrect length: " + testName); } if (!areEqual(C, enc)) { fail("incorrect encrypt in: " + testName); } if (!areEqual(tag, encCipher.getMac())) { fail("getMac() not the same as the appended tag: " + testName); } } { byte[] dec = new byte[decCipher.getOutputSize(C.length)]; int len = decCipher.processBytes(C, 0, C.length, dec, 0); len += decCipher.doFinal(dec, len); if (dec.length != len) { fail("decryption reported incorrect length: " + testName); } if (!areEqual(P, dec)) { fail("incorrect decrypt in: " + testName); } if (!areEqual(tag, decCipher.getMac())) { fail("getMac() not the same as the appended tag: " + testName); } } } private void runLongerTestCase(int aesKeySize, byte[] expectedOutput) throws InvalidCipherTextException { KeyParameter key = new KeyParameter(new byte[aesKeySize / 8]); byte[] N = new byte[12]; AEADBlockCipher c1 = new OCBBlockCipher(new AESFastEngine(), new AESFastEngine()); c1.init(true, new ParametersWithIV(key, N)); AEADBlockCipher c2 = new OCBBlockCipher(new AESFastEngine(), new AESFastEngine()); long total = 0; byte[] S = new byte[128]; for (int i = 0; i < 128; ++i) { N[11] = (byte)i; c2.init(true, new ParametersWithIV(key, N)); total += updateCiphers(c1, c2, S, i, true, true); total += updateCiphers(c1, c2, S, i, false, true); total += updateCiphers(c1, c2, S, i, true, false); } if (total != 22400L) { fail("test generated the wrong amount of input: " + total); } byte[] output = new byte[c1.getOutputSize(0)]; c1.doFinal(output, 0); if (!areEqual(expectedOutput, output)) { fail("incorrect encrypt in long-form test"); } } private int updateCiphers(AEADBlockCipher c1, AEADBlockCipher c2, byte[] S, int i, boolean includeAAD, boolean includePlaintext) throws InvalidCipherTextException { int inputLen = includePlaintext ? i : 0; int outputLen = c2.getOutputSize(inputLen); byte[] output = new byte[outputLen]; int len = 0; if (includeAAD) { c2.processAADBytes(S, 0, i); } if (includePlaintext) { len += c2.processBytes(S, 0, i, output, len); } len += c2.doFinal(output, len); c1.processAADBytes(output, 0, len); return len; } public static void main(String[] args) { runTest(new OCBTest()); } } bouncycastle-1.49.orig/test/src/org/bouncycastle/crypto/test/SEEDTest.java0000644000175000017500000000342311272020004026171 0ustar ebourgebourgpackage org.bouncycastle.crypto.test; import org.bouncycastle.crypto.engines.SEEDEngine; import org.bouncycastle.crypto.params.KeyParameter; import org.bouncycastle.util.encoders.Hex; import org.bouncycastle.util.test.SimpleTest; /** * SEED tester - vectors http://www.ietf.org/rfc/rfc4009.txt */ public class SEEDTest extends CipherTest { static SimpleTest[] tests = { new BlockCipherVectorTest(0, new SEEDEngine(), new KeyParameter(Hex.decode("00000000000000000000000000000000")), "000102030405060708090a0b0c0d0e0f", "5EBAC6E0054E166819AFF1CC6D346CDB"), new BlockCipherVectorTest(0, new SEEDEngine(), new KeyParameter(Hex.decode("000102030405060708090a0b0c0d0e0f")), "00000000000000000000000000000000", "c11f22f20140505084483597e4370f43"), new BlockCipherVectorTest(0, new SEEDEngine(), new KeyParameter(Hex.decode("4706480851E61BE85D74BFB3FD956185")), "83A2F8A288641FB9A4E9A5CC2F131C7D", "EE54D13EBCAE706D226BC3142CD40D4A"), new BlockCipherVectorTest(0, new SEEDEngine(), new KeyParameter(Hex.decode("28DBC3BC49FFD87DCFA509B11D422BE7")), "B41E6BE2EBA84A148E2EED84593C5EC7", "9B9B7BFCD1813CB95D0B3618F40F5122"), new BlockCipherVectorTest(0, new SEEDEngine(), new KeyParameter(Hex.decode("0E0E0E0E0E0E0E0E0E0E0E0E0E0E0E0E")), "0E0E0E0E0E0E0E0E0E0E0E0E0E0E0E0E", "8296F2F1B007AB9D533FDEE35A9AD850"), }; SEEDTest() { super(tests, new SEEDEngine(), new KeyParameter(new byte[16])); } public String getName() { return "SEED"; } public static void main( String[] args) { runTest(new SEEDTest()); } } bouncycastle-1.49.orig/test/src/org/bouncycastle/crypto/test/AESFastTest.java0000644000175000017500000002025410330633061026707 0ustar ebourgebourgpackage org.bouncycastle.crypto.test; import org.bouncycastle.crypto.BlockCipher; import org.bouncycastle.crypto.engines.AESFastEngine; import org.bouncycastle.crypto.params.KeyParameter; import org.bouncycastle.crypto.params.ParametersWithIV; import org.bouncycastle.util.encoders.Hex; import org.bouncycastle.util.test.SimpleTest; /** * Test vectors from the NIST standard tests and Brian Gladman's vector set * * http://fp.gladman.plus.com/cryptography_technology/rijndael/ */ public class AESFastTest extends CipherTest { static SimpleTest[] tests = { new BlockCipherVectorTest(0, new AESFastEngine(), new KeyParameter(Hex.decode("80000000000000000000000000000000")), "00000000000000000000000000000000", "0EDD33D3C621E546455BD8BA1418BEC8"), new BlockCipherVectorTest(1, new AESFastEngine(), new KeyParameter(Hex.decode("00000000000000000000000000000080")), "00000000000000000000000000000000", "172AEAB3D507678ECAF455C12587ADB7"), new BlockCipherMonteCarloTest(2, 10000, new AESFastEngine(), new KeyParameter(Hex.decode("00000000000000000000000000000000")), "00000000000000000000000000000000", "C34C052CC0DA8D73451AFE5F03BE297F"), new BlockCipherMonteCarloTest(3, 10000, new AESFastEngine(), new KeyParameter(Hex.decode("5F060D3716B345C253F6749ABAC10917")), "355F697E8B868B65B25A04E18D782AFA", "ACC863637868E3E068D2FD6E3508454A"), new BlockCipherVectorTest(4, new AESFastEngine(), new KeyParameter(Hex.decode("000000000000000000000000000000000000000000000000")), "80000000000000000000000000000000", "6CD02513E8D4DC986B4AFE087A60BD0C"), new BlockCipherMonteCarloTest(5, 10000, new AESFastEngine(), new KeyParameter(Hex.decode("AAFE47EE82411A2BF3F6752AE8D7831138F041560631B114")), "F3F6752AE8D7831138F041560631B114", "77BA00ED5412DFF27C8ED91F3C376172"), new BlockCipherVectorTest(6, new AESFastEngine(), new KeyParameter(Hex.decode("0000000000000000000000000000000000000000000000000000000000000000")), "80000000000000000000000000000000", "DDC6BF790C15760D8D9AEB6F9A75FD4E"), new BlockCipherMonteCarloTest(7, 10000, new AESFastEngine(), new KeyParameter(Hex.decode("28E79E2AFC5F7745FCCABE2F6257C2EF4C4EDFB37324814ED4137C288711A386")), "C737317FE0846F132B23C8C2A672CE22", "E58B82BFBA53C0040DC610C642121168"), new BlockCipherVectorTest(8, new AESFastEngine(), new KeyParameter(Hex.decode("80000000000000000000000000000000")), "00000000000000000000000000000000", "0EDD33D3C621E546455BD8BA1418BEC8"), new BlockCipherVectorTest(9, new AESFastEngine(), new KeyParameter(Hex.decode("00000000000000000000000000000080")), "00000000000000000000000000000000", "172AEAB3D507678ECAF455C12587ADB7"), new BlockCipherMonteCarloTest(10, 10000, new AESFastEngine(), new KeyParameter(Hex.decode("00000000000000000000000000000000")), "00000000000000000000000000000000", "C34C052CC0DA8D73451AFE5F03BE297F"), new BlockCipherMonteCarloTest(11, 10000, new AESFastEngine(), new KeyParameter(Hex.decode("5F060D3716B345C253F6749ABAC10917")), "355F697E8B868B65B25A04E18D782AFA", "ACC863637868E3E068D2FD6E3508454A"), new BlockCipherVectorTest(12, new AESFastEngine(), new KeyParameter(Hex.decode("000000000000000000000000000000000000000000000000")), "80000000000000000000000000000000", "6CD02513E8D4DC986B4AFE087A60BD0C"), new BlockCipherMonteCarloTest(13, 10000, new AESFastEngine(), new KeyParameter(Hex.decode("AAFE47EE82411A2BF3F6752AE8D7831138F041560631B114")), "F3F6752AE8D7831138F041560631B114", "77BA00ED5412DFF27C8ED91F3C376172"), new BlockCipherVectorTest(14, new AESFastEngine(), new KeyParameter(Hex.decode("0000000000000000000000000000000000000000000000000000000000000000")), "80000000000000000000000000000000", "DDC6BF790C15760D8D9AEB6F9A75FD4E"), new BlockCipherMonteCarloTest(15, 10000, new AESFastEngine(), new KeyParameter(Hex.decode("28E79E2AFC5F7745FCCABE2F6257C2EF4C4EDFB37324814ED4137C288711A386")), "C737317FE0846F132B23C8C2A672CE22", "E58B82BFBA53C0040DC610C642121168"), new BlockCipherVectorTest(16, new AESFastEngine(), new KeyParameter(Hex.decode("80000000000000000000000000000000")), "00000000000000000000000000000000", "0EDD33D3C621E546455BD8BA1418BEC8"), new BlockCipherVectorTest(17, new AESFastEngine(), new KeyParameter(Hex.decode("00000000000000000000000000000080")), "00000000000000000000000000000000", "172AEAB3D507678ECAF455C12587ADB7"), new BlockCipherMonteCarloTest(18, 10000, new AESFastEngine(), new KeyParameter(Hex.decode("00000000000000000000000000000000")), "00000000000000000000000000000000", "C34C052CC0DA8D73451AFE5F03BE297F"), new BlockCipherMonteCarloTest(19, 10000, new AESFastEngine(), new KeyParameter(Hex.decode("5F060D3716B345C253F6749ABAC10917")), "355F697E8B868B65B25A04E18D782AFA", "ACC863637868E3E068D2FD6E3508454A"), new BlockCipherVectorTest(20, new AESFastEngine(), new KeyParameter(Hex.decode("000000000000000000000000000000000000000000000000")), "80000000000000000000000000000000", "6CD02513E8D4DC986B4AFE087A60BD0C"), new BlockCipherMonteCarloTest(21, 10000, new AESFastEngine(), new KeyParameter(Hex.decode("AAFE47EE82411A2BF3F6752AE8D7831138F041560631B114")), "F3F6752AE8D7831138F041560631B114", "77BA00ED5412DFF27C8ED91F3C376172"), new BlockCipherVectorTest(22, new AESFastEngine(), new KeyParameter(Hex.decode("0000000000000000000000000000000000000000000000000000000000000000")), "80000000000000000000000000000000", "DDC6BF790C15760D8D9AEB6F9A75FD4E"), new BlockCipherMonteCarloTest(23, 10000, new AESFastEngine(), new KeyParameter(Hex.decode("28E79E2AFC5F7745FCCABE2F6257C2EF4C4EDFB37324814ED4137C288711A386")), "C737317FE0846F132B23C8C2A672CE22", "E58B82BFBA53C0040DC610C642121168") }; private BlockCipher _engine = new AESFastEngine(); AESFastTest() { super(tests, new AESFastEngine(), new KeyParameter(new byte[16])); } public String getName() { return "AESFast"; } public void performTest() throws Exception { super.performTest(); byte[] keyBytes = new byte[16]; _engine.init(true, new KeyParameter(keyBytes)); // // init tests // try { byte[] dudKey = new byte[6]; _engine.init(true, new KeyParameter(dudKey)); fail("failed key length check"); } catch (IllegalArgumentException e) { // expected } try { byte[] iv = new byte[16]; _engine.init(true, new ParametersWithIV(null, iv)); fail("failed parameter check"); } catch (IllegalArgumentException e) { // expected } } public static void main( String[] args) { runTest(new AESFastTest()); } } bouncycastle-1.49.orig/test/src/org/bouncycastle/crypto/test/VMPCTest.java0000644000175000017500000000547210676460254026252 0ustar ebourgebourgpackage org.bouncycastle.crypto.test; import org.bouncycastle.crypto.CipherParameters; import org.bouncycastle.crypto.engines.VMPCEngine; import org.bouncycastle.crypto.params.KeyParameter; import org.bouncycastle.crypto.params.ParametersWithIV; import org.bouncycastle.util.Arrays; import org.bouncycastle.util.encoders.Hex; import org.bouncycastle.util.test.SimpleTest; /** * VMPC Test */ public class VMPCTest extends SimpleTest { private static final byte[] input = new byte[1000000]; public String getName() { return "VMPC"; } private void checkByte(byte[] array, int position, byte b) { if (array[position] != b) { fail("Fail on position " + position, new String(Hex.encode(new byte[] { b })), new String(Hex.encode(new byte[] { array[position] }))); } } public void performTest() { byte[] key = Hex.decode("9661410AB797D8A9EB767C21172DF6C7"); byte[] iv = Hex.decode("4B5C2F003E67F39557A8D26F3DA2B155"); CipherParameters kp = new KeyParameter(key); CipherParameters kpwiv = new ParametersWithIV(kp, iv); VMPCEngine engine = new VMPCEngine(); try { engine.init(true, kp); fail("init failed to throw expected exception"); } catch (IllegalArgumentException e) { // Expected } engine.init(true, kpwiv); checkEngine(engine); engine.reset(); byte[] output = checkEngine(engine); engine.init(false, kpwiv); byte[] recovered = new byte[output.length]; engine.processBytes(output, 0, output.length, recovered, 0); if (!Arrays.areEqual(input, recovered)) { fail("decrypted bytes differ from original bytes"); } } private byte[] checkEngine(VMPCEngine engine) { byte[] output = new byte[input.length]; engine.processBytes(input, 0, output.length, output, 0); checkByte(output, 0, (byte) 0xA8); checkByte(output, 1, (byte) 0x24); checkByte(output, 2, (byte) 0x79); checkByte(output, 3, (byte) 0xF5); checkByte(output, 252, (byte) 0xB8); checkByte(output, 253, (byte) 0xFC); checkByte(output, 254, (byte) 0x66); checkByte(output, 255, (byte) 0xA4); checkByte(output, 1020, (byte) 0xE0); checkByte(output, 1021, (byte) 0x56); checkByte(output, 1022, (byte) 0x40); checkByte(output, 1023, (byte) 0xA5); checkByte(output, 102396, (byte) 0x81); checkByte(output, 102397, (byte) 0xCA); checkByte(output, 102398, (byte) 0x49); checkByte(output, 102399, (byte) 0x9A); return output; } public static void main(String[] args) { runTest(new VMPCTest()); } } bouncycastle-1.49.orig/test/src/org/bouncycastle/crypto/test/EAXTest.java0000644000175000017500000003057112045616306026111 0ustar ebourgebourgpackage org.bouncycastle.crypto.test; import java.security.SecureRandom; import org.bouncycastle.crypto.InvalidCipherTextException; import org.bouncycastle.crypto.engines.AESFastEngine; import org.bouncycastle.crypto.modes.AEADBlockCipher; import org.bouncycastle.crypto.modes.EAXBlockCipher; import org.bouncycastle.crypto.params.AEADParameters; import org.bouncycastle.crypto.params.KeyParameter; import org.bouncycastle.crypto.params.ParametersWithIV; import org.bouncycastle.util.Strings; import org.bouncycastle.util.encoders.Hex; import org.bouncycastle.util.test.SimpleTest; public class EAXTest extends SimpleTest { private byte[] K1 = Hex.decode("233952DEE4D5ED5F9B9C6D6FF80FF478"); private byte[] N1 = Hex.decode("62EC67F9C3A4A407FCB2A8C49031A8B3"); private byte[] A1 = Hex.decode("6BFB914FD07EAE6B"); private byte[] P1 = Hex.decode(""); private byte[] C1 = Hex.decode("E037830E8389F27B025A2D6527E79D01"); private byte[] T1 = Hex.decode("E037830E8389F27B025A2D6527E79D01"); private byte[] K2 = Hex.decode("91945D3F4DCBEE0BF45EF52255F095A4"); private byte[] N2 = Hex.decode("BECAF043B0A23D843194BA972C66DEBD"); private byte[] A2 = Hex.decode("FA3BFD4806EB53FA"); private byte[] P2 = Hex.decode("F7FB"); private byte[] C2 = Hex.decode("19DD5C4C9331049D0BDAB0277408F67967E5"); private byte[] T2 = Hex.decode("5C4C9331049D0BDAB0277408F67967E5"); private byte[] K3 = Hex.decode("01F74AD64077F2E704C0F60ADA3DD523"); private byte[] N3 = Hex.decode("70C3DB4F0D26368400A10ED05D2BFF5E"); private byte[] A3 = Hex.decode("234A3463C1264AC6"); private byte[] P3 = Hex.decode("1A47CB4933"); private byte[] C3 = Hex.decode("D851D5BAE03A59F238A23E39199DC9266626C40F80"); private byte[] T3 = Hex.decode("3A59F238A23E39199DC9266626C40F80"); private byte[] K4 = Hex.decode("D07CF6CBB7F313BDDE66B727AFD3C5E8"); private byte[] N4 = Hex.decode("8408DFFF3C1A2B1292DC199E46B7D617"); private byte[] A4 = Hex.decode("33CCE2EABFF5A79D"); private byte[] P4 = Hex.decode("481C9E39B1"); private byte[] C4 = Hex.decode("632A9D131AD4C168A4225D8E1FF755939974A7BEDE"); private byte[] T4 = Hex.decode("D4C168A4225D8E1FF755939974A7BEDE"); private byte[] K5 = Hex.decode("35B6D0580005BBC12B0587124557D2C2"); private byte[] N5 = Hex.decode("FDB6B06676EEDC5C61D74276E1F8E816"); private byte[] A5 = Hex.decode("AEB96EAEBE2970E9"); private byte[] P5 = Hex.decode("40D0C07DA5E4"); private byte[] C5 = Hex.decode("071DFE16C675CB0677E536F73AFE6A14B74EE49844DD"); private byte[] T5 = Hex.decode("CB0677E536F73AFE6A14B74EE49844DD"); private byte[] K6 = Hex.decode("BD8E6E11475E60B268784C38C62FEB22"); private byte[] N6 = Hex.decode("6EAC5C93072D8E8513F750935E46DA1B"); private byte[] A6 = Hex.decode("D4482D1CA78DCE0F"); private byte[] P6 = Hex.decode("4DE3B35C3FC039245BD1FB7D"); private byte[] C6 = Hex.decode("835BB4F15D743E350E728414ABB8644FD6CCB86947C5E10590210A4F"); private byte[] T6 = Hex.decode("ABB8644FD6CCB86947C5E10590210A4F"); private byte[] K7 = Hex.decode("7C77D6E813BED5AC98BAA417477A2E7D"); private byte[] N7 = Hex.decode("1A8C98DCD73D38393B2BF1569DEEFC19"); private byte[] A7 = Hex.decode("65D2017990D62528"); private byte[] P7 = Hex.decode("8B0A79306C9CE7ED99DAE4F87F8DD61636"); private byte[] C7 = Hex.decode("02083E3979DA014812F59F11D52630DA30137327D10649B0AA6E1C181DB617D7F2"); private byte[] T7 = Hex.decode("137327D10649B0AA6E1C181DB617D7F2"); private byte[] K8 = Hex.decode("5FFF20CAFAB119CA2FC73549E20F5B0D"); private byte[] N8 = Hex.decode("DDE59B97D722156D4D9AFF2BC7559826"); private byte[] A8 = Hex.decode("54B9F04E6A09189A"); private byte[] P8 = Hex.decode("1BDA122BCE8A8DBAF1877D962B8592DD2D56"); private byte[] C8 = Hex.decode("2EC47B2C4954A489AFC7BA4897EDCDAE8CC33B60450599BD02C96382902AEF7F832A"); private byte[] T8 = Hex.decode("3B60450599BD02C96382902AEF7F832A"); private byte[] K9 = Hex.decode("A4A4782BCFFD3EC5E7EF6D8C34A56123"); private byte[] N9 = Hex.decode("B781FCF2F75FA5A8DE97A9CA48E522EC"); private byte[] A9 = Hex.decode("899A175897561D7E"); private byte[] P9 = Hex.decode("6CF36720872B8513F6EAB1A8A44438D5EF11"); private byte[] C9 = Hex.decode("0DE18FD0FDD91E7AF19F1D8EE8733938B1E8E7F6D2231618102FDB7FE55FF1991700"); private byte[] T9 = Hex.decode("E7F6D2231618102FDB7FE55FF1991700"); private byte[] K10 = Hex.decode("8395FCF1E95BEBD697BD010BC766AAC3"); private byte[] N10 = Hex.decode("22E7ADD93CFC6393C57EC0B3C17D6B44"); private byte[] A10 = Hex.decode("126735FCC320D25A"); private byte[] P10 = Hex.decode("CA40D7446E545FFAED3BD12A740A659FFBBB3CEAB7"); private byte[] C10 = Hex.decode("CB8920F87A6C75CFF39627B56E3ED197C552D295A7CFC46AFC253B4652B1AF3795B124AB6E"); private byte[] T10 = Hex.decode("CFC46AFC253B4652B1AF3795B124AB6E"); private byte[] K11 = Hex.decode("8395FCF1E95BEBD697BD010BC766AAC3"); private byte[] N11 = Hex.decode("22E7ADD93CFC6393C57EC0B3C17D6B44"); private byte[] A11 = Hex.decode("126735FCC320D25A"); private byte[] P11 = Hex.decode("CA40D7446E545FFAED3BD12A740A659FFBBB3CEAB7"); private byte[] C11 = Hex.decode("CB8920F87A6C75CFF39627B56E3ED197C552D295A7CFC46AFC"); private byte[] T11 = Hex.decode("CFC46AFC"); private static final int NONCE_LEN = 8; private static final int MAC_LEN = 8; private static final int AUTHEN_LEN = 20; public String getName() { return "EAX"; } public void performTest() throws Exception { checkVectors(1, K1, 128, N1, A1, P1, T1, C1); checkVectors(2, K2, 128, N2, A2, P2, T2, C2); checkVectors(3, K3, 128, N3, A3, P3, T3, C3); checkVectors(4, K4, 128, N4, A4, P4, T4, C4); checkVectors(5, K5, 128, N5, A5, P5, T5, C5); checkVectors(6, K6, 128, N6, A6, P6, T6, C6); checkVectors(7, K7, 128, N7, A7, P7, T7, C7); checkVectors(8, K8, 128, N8, A8, P8, T8, C8); checkVectors(9, K9, 128, N9, A9, P9, T9, C9); checkVectors(10, K10, 128, N10, A10, P10, T10, C10); checkVectors(11, K11, 32, N11, A11, P11, T11, C11); EAXBlockCipher eax = new EAXBlockCipher(new AESFastEngine()); ivParamTest(1, eax, K1, N1); // // exception tests // try { eax.init(false, new AEADParameters(new KeyParameter(K1), 32, N2, A2)); byte[] enc = new byte[C2.length]; int len = eax.processBytes(C2, 0, C2.length, enc, 0); len += eax.doFinal(enc, len); fail("invalid cipher text not picked up"); } catch (InvalidCipherTextException e) { // expected } try { eax.init(false, new KeyParameter(K1)); fail("illegal argument not picked up"); } catch (IllegalArgumentException e) { // expected } randomTests(); } private void checkVectors( int count, byte[] k, int macSize, byte[] n, byte[] a, byte[] p, byte[] t, byte[] c) throws InvalidCipherTextException { byte[] fa = new byte[a.length / 2]; byte[] la = new byte[a.length - (a.length / 2)]; System.arraycopy(a, 0, fa, 0, fa.length); System.arraycopy(a, fa.length, la, 0, la.length); checkVectors(count, "all initial associated data", k, macSize, n, a, null, p, t, c); checkVectors(count, "subsequent associated data", k, macSize, n, null, a, p, t, c); checkVectors(count, "split associated data", k, macSize, n, fa, la, p, t, c); } private void checkVectors( int count, String additionalDataType, byte[] k, int macSize, byte[] n, byte[] a, byte[] sa, byte[] p, byte[] t, byte[] c) throws InvalidCipherTextException { EAXBlockCipher encEax = new EAXBlockCipher(new AESFastEngine()); EAXBlockCipher decEax = new EAXBlockCipher(new AESFastEngine()); AEADParameters parameters = new AEADParameters(new KeyParameter(k), macSize, n, a); encEax.init(true, parameters); decEax.init(false, parameters); runCheckVectors(count, encEax, decEax, additionalDataType, sa, p, t, c); runCheckVectors(count, encEax, decEax, additionalDataType, sa, p, t, c); // key reuse test parameters = new AEADParameters(null, macSize, n, a); encEax.init(true, parameters); decEax.init(false, parameters); runCheckVectors(count, encEax, decEax, additionalDataType, sa, p, t, c); runCheckVectors(count, encEax, decEax, additionalDataType, sa, p, t, c); } private void runCheckVectors( int count, EAXBlockCipher encEax, EAXBlockCipher decEax, String additionalDataType, byte[] sa, byte[] p, byte[] t, byte[] c) throws InvalidCipherTextException { byte[] enc = new byte[c.length]; if (sa != null) { encEax.processAADBytes(sa, 0, sa.length); } int len = encEax.processBytes(p, 0, p.length, enc, 0); len += encEax.doFinal(enc, len); if (!areEqual(c, enc)) { fail("encrypted stream fails to match in test " + count + " with " + additionalDataType); } byte[] tmp = new byte[enc.length]; if (sa != null) { decEax.processAADBytes(sa, 0, sa.length); } len = decEax.processBytes(enc, 0, enc.length, tmp, 0); len += decEax.doFinal(tmp, len); byte[] dec = new byte[len]; System.arraycopy(tmp, 0, dec, 0, len); if (!areEqual(p, dec)) { fail("decrypted stream fails to match in test " + count + " with " + additionalDataType); } if (!areEqual(t, decEax.getMac())) { fail("MAC fails to match in test " + count + " with " + additionalDataType); } } private void ivParamTest( int count, AEADBlockCipher eax, byte[] k, byte[] n) throws InvalidCipherTextException { byte[] p = Strings.toByteArray("hello world!!"); eax.init(true, new ParametersWithIV(new KeyParameter(k), n)); byte[] enc = new byte[p.length + 8]; int len = eax.processBytes(p, 0, p.length, enc, 0); len += eax.doFinal(enc, len); eax.init(false, new ParametersWithIV(new KeyParameter(k), n)); byte[] tmp = new byte[enc.length]; len = eax.processBytes(enc, 0, enc.length, tmp, 0); len += eax.doFinal(tmp, len); byte[] dec = new byte[len]; System.arraycopy(tmp, 0, dec, 0, len); if (!areEqual(p, dec)) { fail("decrypted stream fails to match in test " + count); } } private void randomTests() throws InvalidCipherTextException { SecureRandom srng = new SecureRandom(); for (int i = 0; i < 10; ++i) { randomTest(srng); } } private void randomTest( SecureRandom srng) throws InvalidCipherTextException { int DAT_LEN = srng.nextInt() >>> 22; // Note: JDK1.0 compatibility byte[] nonce = new byte[NONCE_LEN]; byte[] authen = new byte[AUTHEN_LEN]; byte[] datIn = new byte[DAT_LEN]; byte[] key = new byte[16]; srng.nextBytes(nonce); srng.nextBytes(authen); srng.nextBytes(datIn); srng.nextBytes(key); AESFastEngine engine = new AESFastEngine(); KeyParameter sessKey = new KeyParameter(key); EAXBlockCipher eaxCipher = new EAXBlockCipher(engine); AEADParameters params = new AEADParameters(sessKey, MAC_LEN * 8, nonce, authen); eaxCipher.init(true, params); byte[] intrDat = new byte[eaxCipher.getOutputSize(datIn.length)]; int outOff = eaxCipher.processBytes(datIn, 0, DAT_LEN, intrDat, 0); outOff += eaxCipher.doFinal(intrDat, outOff); eaxCipher.init(false, params); byte[] datOut = new byte[eaxCipher.getOutputSize(outOff)]; int resultLen = eaxCipher.processBytes(intrDat, 0, outOff, datOut, 0); eaxCipher.doFinal(datOut, resultLen); if (!areEqual(datIn, datOut)) { fail("EAX roundtrip failed to match"); } } public static void main(String[] args) { runTest(new EAXTest()); } } bouncycastle-1.49.orig/test/src/org/bouncycastle/crypto/test/GCMReorderTest.java0000644000175000017500000002346711640230466027432 0ustar ebourgebourgpackage org.bouncycastle.crypto.test; import java.io.IOException; import java.security.SecureRandom; import junit.framework.TestCase; import org.bouncycastle.crypto.modes.gcm.GCMExponentiator; import org.bouncycastle.crypto.modes.gcm.GCMMultiplier; import org.bouncycastle.crypto.modes.gcm.Tables1kGCMExponentiator; import org.bouncycastle.crypto.modes.gcm.Tables64kGCMMultiplier; import org.bouncycastle.crypto.util.Pack; import org.bouncycastle.util.Arrays; import org.bouncycastle.util.encoders.Hex; public class GCMReorderTest extends TestCase { private static final byte[] H; private static final SecureRandom random = new SecureRandom(); private static final GCMMultiplier mul = new Tables64kGCMMultiplier(); private static final GCMExponentiator exp = new Tables1kGCMExponentiator(); private static final byte[] EMPTY = new byte[0]; static { H = new byte[16]; random.nextBytes(H); mul.init(Arrays.clone(H)); exp.init(Arrays.clone(H)); } public void testCombine() throws Exception { for (int count = 0; count < 10; ++count) { byte[] A = randomBytes(1000); byte[] C = randomBytes(1000); byte[] ghashA_ = GHASH(A, EMPTY); byte[] ghash_C = GHASH(EMPTY, C); byte[] ghashAC = GHASH(A, C); byte[] ghashCombine = combine_GHASH(ghashA_, (long)A.length * 8, ghash_C, (long)C.length * 8); assertTrue(Arrays.areEqual(ghashAC, ghashCombine)); } } public void testConcatAuth() throws Exception { for (int count = 0; count < 10; ++count) { byte[] P = randomBlocks(100); byte[] A = randomBytes(1000); byte[] PA = concatArrays(P, A); byte[] ghashP_ = GHASH(P, EMPTY); byte[] ghashA_ = GHASH(A, EMPTY); byte[] ghashPA_ = GHASH(PA, EMPTY); byte[] ghashConcat = concatAuth_GHASH(ghashP_, (long)P.length * 8, ghashA_, (long)A.length * 8); assertTrue(Arrays.areEqual(ghashPA_, ghashConcat)); } } public void testConcatCrypt() throws Exception { for (int count = 0; count < 10; ++count) { byte[] P = randomBlocks(100); byte[] A = randomBytes(1000); byte[] PA = concatArrays(P, A); byte[] ghash_P = GHASH(EMPTY, P); byte[] ghash_A = GHASH(EMPTY, A); byte[] ghash_PA = GHASH(EMPTY, PA); byte[] ghashConcat = concatCrypt_GHASH(ghash_P, (long)P.length * 8, ghash_A, (long)A.length * 8); assertTrue(Arrays.areEqual(ghash_PA, ghashConcat)); } } public void testExp() { { byte[] buf1 = new byte[16]; buf1[0] = (byte)0x80; byte[] buf2 = new byte[16]; for (int pow = 0; pow != 100; ++pow) { exp.exponentiateX(pow, buf2); assertTrue(Arrays.areEqual(buf1, buf2)); mul.multiplyH(buf1); } } long[] testPow = new long[]{ 10, 1, 8, 17, 24, 13, 2, 13, 2, 3 }; byte[][] testData = new byte[][]{ Hex.decode("9185848a877bd87ba071e281f476e8e7"), Hex.decode("697ce3052137d80745d524474fb6b290"), Hex.decode("2696fc47198bb23b11296e4f88720a17"), Hex.decode("01f2f0ead011a4ae0cf3572f1b76dd8e"), Hex.decode("a53060694a044e4b7fa1e661c5a7bb6b"), Hex.decode("39c0392e8b6b0e04a7565c85394c2c4c"), Hex.decode("519c362d502e07f2d8b7597a359a5214"), Hex.decode("5a527a393675705e19b2117f67695af4"), Hex.decode("27fc0901d1d332a53ba4d4386c2109d2"), Hex.decode("93ca9b57174aabedf8220e83366d7df6"), }; for (int i = 0; i != 10; ++i) { long pow = testPow[i]; byte[] data = Arrays.clone(testData[i]); byte[] expected = Arrays.clone(data); for (int j = 0; j < pow; ++j) { mul.multiplyH(expected); } byte[] H_a = new byte[16]; exp.exponentiateX(pow, H_a); byte[] actual = multiply(data, H_a); assertTrue(Arrays.areEqual(expected, actual)); } } public void testMultiply() { byte[] expected = Arrays.clone(H); mul.multiplyH(expected); assertTrue(Arrays.areEqual(expected, multiply(H, H))); for (int count = 0; count < 10; ++count) { byte[] a = new byte[16]; random.nextBytes(a); byte[] b = new byte[16]; random.nextBytes(b); expected = Arrays.clone(a); mul.multiplyH(expected); assertTrue(Arrays.areEqual(expected, multiply(a, H))); assertTrue(Arrays.areEqual(expected, multiply(H, a))); expected = Arrays.clone(b); mul.multiplyH(expected); assertTrue(Arrays.areEqual(expected, multiply(b, H))); assertTrue(Arrays.areEqual(expected, multiply(H, b))); assertTrue(Arrays.areEqual(multiply(a, b), multiply(b, a))); } } private byte[] randomBlocks(int upper) { byte[] bs = new byte[16 * random.nextInt(upper)]; random.nextBytes(bs); return bs; } private byte[] randomBytes(int upper) { byte[] bs = new byte[random.nextInt(upper)]; random.nextBytes(bs); return bs; } private byte[] concatArrays(byte[] a, byte[] b) throws IOException { byte[] ab = new byte[a.length + b.length]; System.arraycopy(a, 0, ab, 0, a.length); System.arraycopy(b, 0, ab, a.length, b.length); return ab; } private byte[] combine_GHASH(byte[] ghashA_, long bitlenA, byte[] ghash_C, long bitlenC) { // Note: bitlenA must be aligned to the block size long c = (bitlenC + 127) >>> 7; byte[] H_c = new byte[16]; exp.exponentiateX(c, H_c); byte[] tmp1 = lengthBlock(bitlenA, 0); mul.multiplyH(tmp1); byte[] ghashAC = Arrays.clone(ghashA_); xor(ghashAC, tmp1); ghashAC = multiply(ghashAC, H_c); // No need to touch the len(C) part (second 8 bytes) xor(ghashAC, tmp1); xor(ghashAC, ghash_C); return ghashAC; } private byte[] concatAuth_GHASH(byte[] ghashP, long bitlenP, byte[] ghashA, long bitlenA) { // Note: bitlenP must be aligned to the block size long a = (bitlenA + 127) >>> 7; byte[] tmp1 = lengthBlock(bitlenP, 0); mul.multiplyH(tmp1); byte[] tmp2 = lengthBlock(bitlenA ^ (bitlenP + bitlenA), 0); mul.multiplyH(tmp2); byte[] H_a = new byte[16]; exp.exponentiateX(a, H_a); byte[] ghashC = Arrays.clone(ghashP); xor(ghashC, tmp1); ghashC = multiply(ghashC, H_a); xor(ghashC, tmp2); xor(ghashC, ghashA); return ghashC; } private byte[] concatCrypt_GHASH(byte[] ghashP, long bitlenP, byte[] ghashA, long bitlenA) { // Note: bitlenP must be aligned to the block size long a = (bitlenA + 127) >>> 7; byte[] tmp1 = lengthBlock(0, bitlenP); mul.multiplyH(tmp1); byte[] tmp2 = lengthBlock(0, bitlenA ^ (bitlenP + bitlenA)); mul.multiplyH(tmp2); byte[] H_a = new byte[16]; exp.exponentiateX(a, H_a); byte[] ghashC = Arrays.clone(ghashP); xor(ghashC, tmp1); ghashC = multiply(ghashC, H_a); xor(ghashC, tmp2); xor(ghashC, ghashA); return ghashC; } private byte[] GHASH(byte[] A, byte[] C) { byte[] X = new byte[16]; { for (int pos = 0; pos < A.length; pos += 16) { byte[] tmp = new byte[16]; int num = Math.min(A.length - pos, 16); System.arraycopy(A, pos, tmp, 0, num); xor(X, tmp); mul.multiplyH(X); } } { for (int pos = 0; pos < C.length; pos += 16) { byte[] tmp = new byte[16]; int num = Math.min(C.length - pos, 16); System.arraycopy(C, pos, tmp, 0, num); xor(X, tmp); mul.multiplyH(X); } } { xor(X, lengthBlock((long)A.length * 8, (long)C.length * 8)); mul.multiplyH(X); } return X; } private static byte[] lengthBlock(long bitlenA, long bitlenC) { byte[] tmp = new byte[16]; Pack.longToBigEndian(bitlenA, tmp, 0); Pack.longToBigEndian(bitlenC, tmp, 8); return tmp; } private static void xor(byte[] block, byte[] val) { for (int i = 15; i >= 0; --i) { block[i] ^= val[i]; } } private static byte[] multiply(byte[] a, byte[] b) { byte[] c = new byte[16]; byte[] tmp = Arrays.clone(b); for (int i = 0; i < 16; ++i) { byte bits = a[i]; for (int j = 7; j >= 0; --j) { if ((bits & (1 << j)) != 0) { xor(c, tmp); } boolean lsb = (tmp[15] & 1) != 0; shiftRight(tmp); if (lsb) { // R = new byte[]{ 0xe1, ... }; // GCMUtil.xor(v, R); tmp[0] ^= (byte)0xe1; } } } return c; } private static void shiftRight(byte[] block) { int i = 0; int bit = 0; for (;;) { int b = block[i] & 0xff; block[i] = (byte) ((b >>> 1) | bit); if (++i == 16) { break; } bit = (b & 1) << 7; } } } bouncycastle-1.49.orig/test/src/org/bouncycastle/crypto/test/MGF1GeneratorTest.java0000644000175000017500000000626710427071732030042 0ustar ebourgebourgpackage org.bouncycastle.crypto.test; import org.bouncycastle.crypto.DataLengthException; import org.bouncycastle.crypto.DerivationFunction; import org.bouncycastle.crypto.digests.SHA1Digest; import org.bouncycastle.crypto.digests.SHA256Digest; import org.bouncycastle.crypto.digests.ShortenedDigest; import org.bouncycastle.crypto.generators.MGF1BytesGenerator; import org.bouncycastle.crypto.params.MGFParameters; import org.bouncycastle.util.encoders.Hex; import org.bouncycastle.util.test.SimpleTest; /** * MGF1 tests - vectors from ISO 18033 for KDF1 (equivalent). */ public class MGF1GeneratorTest extends SimpleTest { private byte[] seed1 = Hex.decode("d6e168c5f256a2dcff7ef12facd390f393c7a88d"); private byte[] mask1 = Hex.decode( "0742ba966813af75536bb6149cc44fc256fd6406df79665bc31dc5" + "a62f70535e52c53015b9d37d412ff3c1193439599e1b628774c50d9c" + "cb78d82c425e4521ee47b8c36a4bcffe8b8112a89312fc04420a39de" + "99223890e74ce10378bc515a212b97b8a6447ba6a8870278"); private byte[] seed2 = Hex.decode( "032e45326fa859a72ec235acff929b15d1372e30b207255f0611b8f785d7643741" + "52e0ac009e509e7ba30cd2f1778e113b64e135cf4e2292c75efe5288edfda4"); private byte[] mask2 = Hex.decode( "5f8de105b5e96b2e490ddecbd147dd1def7e3b8e0e6a26eb7b956ccb8b3bdc1ca9" + "75bc57c3989e8fbad31a224655d800c46954840ff32052cdf0d640562bdfadfa263c" + "fccf3c52b29f2af4a1869959bc77f854cf15bd7a25192985a842dbff8e13efee5b7e" + "7e55bbe4d389647c686a9a9ab3fb889b2d7767d3837eea4e0a2f04"); private byte[] seed3 = seed2; private byte[] mask3= Hex.decode( "09e2decf2a6e1666c2f6071ff4298305e2643fd510a2403db42a8743cb989de86e" + "668d168cbe604611ac179f819a3d18412e9eb45668f2923c087c12fee0c5a0d2a8aa" + "70185401fbbd99379ec76c663e875a60b4aacb1319fa11c3365a8b79a44669f26fb5" + "55c80391847b05eca1cb5cf8c2d531448d33fbaca19f6410ee1fcb"); public void performTest() { checkMask(1, new MGF1BytesGenerator(new ShortenedDigest(new SHA256Digest(), 20)), seed1, mask1); checkMask(2, new MGF1BytesGenerator(new SHA1Digest()), seed2, mask2); checkMask(3, new MGF1BytesGenerator(new ShortenedDigest(new SHA256Digest(), 20)), seed3, mask3); try { new MGF1BytesGenerator(new SHA1Digest()).generateBytes(new byte[10], 0, 20); fail("short input array not caught"); } catch (DataLengthException e) { // expected } } private void checkMask( int count, DerivationFunction kdf, byte[] seed, byte[] result) { byte[] data = new byte[result.length]; kdf.init(new MGFParameters(seed)); kdf.generateBytes(data, 0, data.length); if (!areEqual(result, data)) { fail("MGF1 failed generator test " + count); } } public String getName() { return "MGF1"; } public static void main( String[] args) { runTest(new MGF1GeneratorTest()); } } bouncycastle-1.49.orig/test/src/org/bouncycastle/crypto/test/RC5Test.java0000644000175000017500000002212310330633061026047 0ustar ebourgebourgpackage org.bouncycastle.crypto.test; import org.bouncycastle.crypto.engines.RC532Engine; import org.bouncycastle.crypto.engines.RC564Engine; import org.bouncycastle.crypto.modes.CBCBlockCipher; import org.bouncycastle.crypto.params.ParametersWithIV; import org.bouncycastle.crypto.params.RC5Parameters; import org.bouncycastle.util.encoders.Hex; import org.bouncycastle.util.test.SimpleTestResult; import org.bouncycastle.util.test.Test; import org.bouncycastle.util.test.TestResult; /** * RC5 tester - vectors from ftp://ftp.nordu.net/rfc/rfc2040.txt * * RFC 2040 "The RC5, RC5-CBC, RC5-CBC-Pad, and RC5-CTS Algorithms" */ public class RC5Test implements Test { BlockCipherVectorTest[] tests = { new BlockCipherVectorTest(0, new CBCBlockCipher(new RC532Engine()), new ParametersWithIV( new RC5Parameters(Hex.decode("00"), 0), Hex.decode("0000000000000000")), "0000000000000000", "7a7bba4d79111d1e"), new BlockCipherVectorTest(1, new CBCBlockCipher(new RC532Engine()), new ParametersWithIV( new RC5Parameters(Hex.decode("00"), 0), Hex.decode("0000000000000000")), "ffffffffffffffff", "797bba4d78111d1e"), new BlockCipherVectorTest(2, new CBCBlockCipher(new RC532Engine()), new ParametersWithIV( new RC5Parameters(Hex.decode("00"), 0), Hex.decode("0000000000000001")), "0000000000000000", "7a7bba4d79111d1f"), new BlockCipherVectorTest(3, new CBCBlockCipher(new RC532Engine()), new ParametersWithIV( new RC5Parameters(Hex.decode("00"), 0), Hex.decode("0000000000000000")), "0000000000000001", "7a7bba4d79111d1f"), new BlockCipherVectorTest(4, new CBCBlockCipher(new RC532Engine()), new ParametersWithIV( new RC5Parameters(Hex.decode("00"), 0), Hex.decode("0102030405060708")), "1020304050607080", "8b9ded91ce7794a6"), new BlockCipherVectorTest(5, new CBCBlockCipher(new RC532Engine()), new ParametersWithIV( new RC5Parameters(Hex.decode("11"), 1), Hex.decode("0000000000000000")), "0000000000000000", "2f759fe7ad86a378"), new BlockCipherVectorTest(6, new CBCBlockCipher(new RC532Engine()), new ParametersWithIV( new RC5Parameters(Hex.decode("00"), 2), Hex.decode("0000000000000000")), "0000000000000000", "dca2694bf40e0788"), new BlockCipherVectorTest(7, new CBCBlockCipher(new RC532Engine()), new ParametersWithIV( new RC5Parameters(Hex.decode("00000000"), 2), Hex.decode("0000000000000000")), "0000000000000000", "dca2694bf40e0788"), new BlockCipherVectorTest(8, new CBCBlockCipher(new RC532Engine()), new ParametersWithIV( new RC5Parameters(Hex.decode("00000000"), 8), Hex.decode("0000000000000000")), "0000000000000000", "dcfe098577eca5ff"), new BlockCipherVectorTest(9, new CBCBlockCipher(new RC532Engine()), new ParametersWithIV( new RC5Parameters(Hex.decode("00"), 8), Hex.decode("0102030405060708")), "1020304050607080", "9646fb77638f9ca8"), new BlockCipherVectorTest(10, new CBCBlockCipher(new RC532Engine()), new ParametersWithIV( new RC5Parameters(Hex.decode("00"), 12), Hex.decode("0102030405060708")), "1020304050607080", "b2b3209db6594da4"), new BlockCipherVectorTest(11, new CBCBlockCipher(new RC532Engine()), new ParametersWithIV( new RC5Parameters(Hex.decode("00"), 16), Hex.decode("0102030405060708")), "1020304050607080", "545f7f32a5fc3836"), new BlockCipherVectorTest(12, new CBCBlockCipher(new RC532Engine()), new ParametersWithIV( new RC5Parameters(Hex.decode("01020304"), 8), Hex.decode("0000000000000000")), "ffffffffffffffff", "8285e7c1b5bc7402"), new BlockCipherVectorTest(13, new CBCBlockCipher(new RC532Engine()), new ParametersWithIV( new RC5Parameters(Hex.decode("01020304"), 12), Hex.decode("0000000000000000")), "ffffffffffffffff", "fc586f92f7080934"), new BlockCipherVectorTest(14, new CBCBlockCipher(new RC532Engine()), new ParametersWithIV( new RC5Parameters(Hex.decode("01020304"), 16), Hex.decode("0000000000000000")), "ffffffffffffffff", "cf270ef9717ff7c4"), new BlockCipherVectorTest(15, new CBCBlockCipher(new RC532Engine()), new ParametersWithIV( new RC5Parameters(Hex.decode("0102030405060708"), 12), Hex.decode("0000000000000000")), "ffffffffffffffff", "e493f1c1bb4d6e8c"), new BlockCipherVectorTest(16, new CBCBlockCipher(new RC532Engine()), new ParametersWithIV( new RC5Parameters(Hex.decode("0102030405060708"), 8), Hex.decode("0102030405060708")), "1020304050607080", "5c4c041e0f217ac3"), new BlockCipherVectorTest(17, new CBCBlockCipher(new RC532Engine()), new ParametersWithIV( new RC5Parameters(Hex.decode("0102030405060708"), 12), Hex.decode("0102030405060708")), "1020304050607080", "921f12485373b4f7"), new BlockCipherVectorTest(18, new CBCBlockCipher(new RC532Engine()), new ParametersWithIV( new RC5Parameters(Hex.decode("0102030405060708"), 16), Hex.decode("0102030405060708")), "1020304050607080", "5ba0ca6bbe7f5fad"), new BlockCipherVectorTest(19, new CBCBlockCipher(new RC532Engine()), new ParametersWithIV( new RC5Parameters(Hex.decode("01020304050607081020304050607080"), 8), Hex.decode("0102030405060708")), "1020304050607080", "c533771cd0110e63"), new BlockCipherVectorTest(20, new CBCBlockCipher(new RC532Engine()), new ParametersWithIV( new RC5Parameters(Hex.decode("01020304050607081020304050607080"), 12), Hex.decode("0102030405060708")), "1020304050607080", "294ddb46b3278d60"), new BlockCipherVectorTest(21, new CBCBlockCipher(new RC532Engine()), new ParametersWithIV( new RC5Parameters(Hex.decode("01020304050607081020304050607080"), 16), Hex.decode("0102030405060708")), "1020304050607080", "dad6bda9dfe8f7e8"), new BlockCipherVectorTest(22, new CBCBlockCipher(new RC532Engine()), new ParametersWithIV( new RC5Parameters(Hex.decode("0102030405"), 12), Hex.decode("0000000000000000")), "ffffffffffffffff", "97e0787837ed317f"), new BlockCipherVectorTest(23, new CBCBlockCipher(new RC532Engine()), new ParametersWithIV( new RC5Parameters(Hex.decode("0102030405"), 8), Hex.decode("0000000000000000")), "ffffffffffffffff", "7875dbf6738c6478"), new BlockCipherVectorTest(23, new CBCBlockCipher(new RC532Engine()), new ParametersWithIV( new RC5Parameters(Hex.decode("0102030405"), 8), Hex.decode("7875dbf6738c6478")), "0808080808080808", "8f34c3c681c99695"), new BlockCipherVectorTest(640, new CBCBlockCipher(new RC564Engine()), new ParametersWithIV( new RC5Parameters(Hex.decode("00"), 0), Hex.decode("00000000000000000000000000000000")), "00000000000000000000000000000000", "9f09b98d3f6062d9d4d59973d00e0e63"), new BlockCipherVectorTest(641, new CBCBlockCipher(new RC564Engine()), new ParametersWithIV( new RC5Parameters(Hex.decode("00"), 0), Hex.decode("00000000000000000000000000000000")), "ffffffffffffffffffffffffffffffff", "9e09b98d3f6062d9d3d59973d00e0e63") }; public String getName() { return "RC5"; } public TestResult perform() { for (int i = 0; i != tests.length; i++) { TestResult res = tests[i].perform(); if (!res.isSuccessful()) { return res; } } return new SimpleTestResult(true, getName() + ": Okay"); } public static void main( String[] args) { RC5Test test = new RC5Test(); TestResult result = test.perform(); System.out.println(result); } } bouncycastle-1.49.orig/test/src/org/bouncycastle/crypto/test/VMPCKSA3Test.java0000644000175000017500000000552710676460254026675 0ustar ebourgebourgpackage org.bouncycastle.crypto.test; import org.bouncycastle.crypto.CipherParameters; import org.bouncycastle.crypto.engines.VMPCKSA3Engine; import org.bouncycastle.crypto.params.KeyParameter; import org.bouncycastle.crypto.params.ParametersWithIV; import org.bouncycastle.util.Arrays; import org.bouncycastle.util.encoders.Hex; import org.bouncycastle.util.test.SimpleTest; /** * VMPC Test */ public class VMPCKSA3Test extends SimpleTest { private static final byte[] input = new byte[1000000]; public String getName() { return "VMPC-KSA3"; } private void checkByte(byte[] array, int position, byte b) { if (array[position] != b) { fail("Fail on position " + position, new String(Hex.encode(new byte[] { b })), new String(Hex.encode(new byte[] { array[position] }))); } } public void performTest() { byte[] key = Hex.decode("9661410AB797D8A9EB767C21172DF6C7"); byte[] iv = Hex.decode("4B5C2F003E67F39557A8D26F3DA2B155"); CipherParameters kp = new KeyParameter(key); CipherParameters kpwiv = new ParametersWithIV(kp, iv); VMPCKSA3Engine engine = new VMPCKSA3Engine(); try { engine.init(true, kp); fail("init failed to throw expected exception"); } catch (IllegalArgumentException e) { // Expected } engine.init(true, kpwiv); checkEngine(engine); engine.reset(); byte[] output = checkEngine(engine); engine.init(false, kpwiv); byte[] recovered = new byte[output.length]; engine.processBytes(output, 0, output.length, recovered, 0); if (!Arrays.areEqual(input, recovered)) { fail("decrypted bytes differ from original bytes"); } } private byte[] checkEngine(VMPCKSA3Engine engine) { byte[] output = new byte[input.length]; engine.processBytes(input, 0, output.length, output, 0); checkByte(output, 0, (byte) 0xB6); checkByte(output, 1, (byte) 0xEB); checkByte(output, 2, (byte) 0xAE); checkByte(output, 3, (byte) 0xFE); checkByte(output, 252, (byte) 0x48); checkByte(output, 253, (byte) 0x17); checkByte(output, 254, (byte) 0x24); checkByte(output, 255, (byte) 0x73); checkByte(output, 1020, (byte) 0x1D); checkByte(output, 1021, (byte) 0xAE); checkByte(output, 1022, (byte) 0xC3); checkByte(output, 1023, (byte) 0x5A); checkByte(output, 102396, (byte) 0x1D); checkByte(output, 102397, (byte) 0xA7); checkByte(output, 102398, (byte) 0xE1); checkByte(output, 102399, (byte) 0xDC); return output; } public static void main(String[] args) { runTest(new VMPCKSA3Test()); } } bouncycastle-1.49.orig/test/src/org/bouncycastle/crypto/test/ModeTest.java0000644000175000017500000000623510330633061026350 0ustar ebourgebourgpackage org.bouncycastle.crypto.test; import org.bouncycastle.crypto.BlockCipher; import org.bouncycastle.crypto.engines.DESEngine; import org.bouncycastle.crypto.modes.CFBBlockCipher; import org.bouncycastle.crypto.modes.OFBBlockCipher; import org.bouncycastle.crypto.params.KeyParameter; import org.bouncycastle.crypto.params.ParametersWithIV; import org.bouncycastle.util.encoders.Hex; import org.bouncycastle.util.test.SimpleTestResult; import org.bouncycastle.util.test.Test; import org.bouncycastle.util.test.TestResult; /** * CFB/OFB Mode test of IV padding. */ public class ModeTest implements Test { public ModeTest() { } private boolean isEqualTo( byte[] a, byte[] b) { for (int i = 0; i != a.length; i++) { if (a[i] != b[i]) { return false; } } return true; } public TestResult perform() { KeyParameter key = new KeyParameter(Hex.decode("0011223344556677")); byte[] input = Hex.decode("4e6f7720"); byte[] out1 = new byte[4]; byte[] out2 = new byte[4]; BlockCipher ofb = new OFBBlockCipher(new DESEngine(), 32); ofb.init(true, new ParametersWithIV(key, Hex.decode("1122334455667788"))); ofb.processBlock(input, 0, out1, 0); ofb.init(false, new ParametersWithIV(key, Hex.decode("1122334455667788"))); ofb.processBlock(out1, 0, out2, 0); if (!isEqualTo(out2, input)) { return new SimpleTestResult(false, getName() + ": test 1 - in != out"); } ofb.init(true, new ParametersWithIV(key, Hex.decode("11223344"))); ofb.processBlock(input, 0, out1, 0); ofb.init(false, new ParametersWithIV(key, Hex.decode("0000000011223344"))); ofb.processBlock(out1, 0, out2, 0); if (!isEqualTo(out2, input)) { return new SimpleTestResult(false, getName() + ": test 2 - in != out"); } BlockCipher cfb = new CFBBlockCipher(new DESEngine(), 32); cfb.init(true, new ParametersWithIV(key, Hex.decode("1122334455667788"))); cfb.processBlock(input, 0, out1, 0); cfb.init(false, new ParametersWithIV(key, Hex.decode("1122334455667788"))); cfb.processBlock(out1, 0, out2, 0); if (!isEqualTo(out2, input)) { return new SimpleTestResult(false, getName() + ": test 3 - in != out"); } cfb.init(true, new ParametersWithIV(key, Hex.decode("11223344"))); cfb.processBlock(input, 0, out1, 0); cfb.init(false, new ParametersWithIV(key, Hex.decode("0000000011223344"))); cfb.processBlock(out1, 0, out2, 0); if (!isEqualTo(out2, input)) { return new SimpleTestResult(false, getName() + ": test 4 - in != out"); } return new SimpleTestResult(true, getName() + ": Okay"); } public String getName() { return "ModeTest"; } public static void main( String[] args) { ModeTest test = new ModeTest(); TestResult result = test.perform(); System.out.println(result); } } bouncycastle-1.49.orig/test/src/org/bouncycastle/crypto/test/CTSTest.java0000644000175000017500000000563310330633061026116 0ustar ebourgebourgpackage org.bouncycastle.crypto.test; import org.bouncycastle.crypto.BlockCipher; import org.bouncycastle.crypto.BufferedBlockCipher; import org.bouncycastle.crypto.CipherParameters; import org.bouncycastle.crypto.engines.DESEngine; import org.bouncycastle.crypto.engines.SkipjackEngine; import org.bouncycastle.crypto.modes.CBCBlockCipher; import org.bouncycastle.crypto.modes.CTSBlockCipher; import org.bouncycastle.crypto.params.KeyParameter; import org.bouncycastle.crypto.params.ParametersWithIV; import org.bouncycastle.util.encoders.Hex; import org.bouncycastle.util.test.SimpleTest; /** * CTS tester */ public class CTSTest extends SimpleTest { static byte[] in1 = Hex.decode("4e6f7720697320746865207420"); static byte[] in2 = Hex.decode("000102030405060708090a0b0c0d0e0fff0102030405060708090a0b0c0d0e0f0aaa"); static byte[] out1 = Hex.decode("9952f131588465033fa40e8a98"); static byte[] out2 = Hex.decode("358f84d01eb42988dc34efb994"); static byte[] out3 = Hex.decode("170171cfad3f04530c509b0c1f0be0aefbd45a8e3755a873bff5ea198504b71683c6"); private void testCTS( int id, BlockCipher cipher, CipherParameters params, byte[] input, byte[] output) throws Exception { byte[] out = new byte[input.length]; BufferedBlockCipher engine = new CTSBlockCipher(cipher); engine.init(true, params); int len = engine.processBytes(input, 0, input.length, out, 0); engine.doFinal(out, len); if (!areEqual(output, out)) { fail("failed encryption expected " + new String(Hex.encode(output)) + " got " + new String(Hex.encode(out))); } engine.init(false, params); len = engine.processBytes(output, 0, output.length, out, 0); engine.doFinal(out, len); if (!areEqual(input, out)) { fail("failed encryption expected " + new String(Hex.encode(input)) + " got " + new String(Hex.encode(out))); } } public String getName() { return "CTS"; } public void performTest() throws Exception { byte[] key1 = { (byte)0x01, (byte)0x23, (byte)0x45, (byte)0x67, (byte)0x89, (byte)0xAB, (byte)0xCD, (byte)0xEF }; byte[] key2 = { (byte)0x01, (byte)0x23, (byte)0x45, (byte)0x67, (byte)0x89, (byte)0xAB, (byte)0xCD, (byte)0xEF, (byte)0xee, (byte)0xff }; byte[] iv = { 1, 2, 3, 4, 5, 6, 7, 8 }; testCTS(1, new DESEngine(), new KeyParameter(key1), in1, out1); testCTS(2, new CBCBlockCipher(new DESEngine()), new ParametersWithIV(new KeyParameter(key1), iv), in1, out2); testCTS(3, new CBCBlockCipher(new SkipjackEngine()), new ParametersWithIV(new KeyParameter(key2), iv), in2, out3); } public static void main( String[] args) { runTest(new CTSTest()); } } bouncycastle-1.49.orig/test/src/org/bouncycastle/crypto/test/CAST6Test.java0000644000175000017500000000261410525306762026314 0ustar ebourgebourgpackage org.bouncycastle.crypto.test; import org.bouncycastle.crypto.engines.CAST6Engine; import org.bouncycastle.crypto.params.KeyParameter; import org.bouncycastle.util.encoders.Hex; import org.bouncycastle.util.test.SimpleTest; /** * cast6 tester - vectors from http://www.ietf.org/rfc/rfc2612.txt */ public class CAST6Test extends CipherTest { static SimpleTest[] tests = { new BlockCipherVectorTest(0, new CAST6Engine(), new KeyParameter(Hex.decode("2342bb9efa38542c0af75647f29f615d")), "00000000000000000000000000000000", "c842a08972b43d20836c91d1b7530f6b"), new BlockCipherVectorTest(0, new CAST6Engine(), new KeyParameter(Hex.decode("2342bb9efa38542cbed0ac83940ac298bac77a7717942863")), "00000000000000000000000000000000", "1b386c0210dcadcbdd0e41aa08a7a7e8"), new BlockCipherVectorTest(0, new CAST6Engine(), new KeyParameter(Hex.decode("2342bb9efa38542cbed0ac83940ac2988d7c47ce264908461cc1b5137ae6b604")), "00000000000000000000000000000000", "4f6a2038286897b9c9870136553317fa") }; CAST6Test() { super(tests, new CAST6Engine(), new KeyParameter(new byte[16])); } public String getName() { return "CAST6"; } public static void main( String[] args) { runTest(new CAST6Test()); } } bouncycastle-1.49.orig/test/src/org/bouncycastle/crypto/test/BlockCipherMonteCarloTest.java0000644000175000017500000000425410330633061031634 0ustar ebourgebourgpackage org.bouncycastle.crypto.test; import org.bouncycastle.crypto.BlockCipher; import org.bouncycastle.crypto.BufferedBlockCipher; import org.bouncycastle.crypto.CipherParameters; import org.bouncycastle.util.encoders.Hex; import org.bouncycastle.util.test.SimpleTest; /** * a basic test that takes a cipher, key parameter, and an input * and output string. This test wraps the engine in a buffered block * cipher with padding disabled. */ public class BlockCipherMonteCarloTest extends SimpleTest { int id; int iterations; BlockCipher engine; CipherParameters param; byte[] input; byte[] output; public BlockCipherMonteCarloTest( int id, int iterations, BlockCipher engine, CipherParameters param, String input, String output) { this.id = id; this.iterations = iterations; this.engine = engine; this.param = param; this.input = Hex.decode(input); this.output = Hex.decode(output); } public String getName() { return engine.getAlgorithmName() + " Monte Carlo Test " + id; } public void performTest() throws Exception { BufferedBlockCipher cipher = new BufferedBlockCipher(engine); cipher.init(true, param); byte[] out = new byte[input.length]; System.arraycopy(input, 0, out, 0, out.length); for (int i = 0; i != iterations; i++) { int len1 = cipher.processBytes(out, 0, out.length, out, 0); cipher.doFinal(out, len1); } if (!areEqual(out, output)) { fail("failed - " + "expected " + new String(Hex.encode(output)) + " got " + new String(Hex.encode(out))); } cipher.init(false, param); for (int i = 0; i != iterations; i++) { int len1 = cipher.processBytes(out, 0, out.length, out, 0); cipher.doFinal(out, len1); } if (!areEqual(input, out)) { fail("failed reversal"); } } } bouncycastle-1.49.orig/test/src/org/bouncycastle/crypto/test/VMPCMacTest.java0000644000175000017500000000255410725007113026653 0ustar ebourgebourgpackage org.bouncycastle.crypto.test; import org.bouncycastle.crypto.CipherParameters; import org.bouncycastle.crypto.macs.VMPCMac; import org.bouncycastle.crypto.params.KeyParameter; import org.bouncycastle.crypto.params.ParametersWithIV; import org.bouncycastle.util.Arrays; import org.bouncycastle.util.encoders.Hex; import org.bouncycastle.util.test.SimpleTest; public class VMPCMacTest extends SimpleTest { public String getName() { return "VMPC-MAC"; } public static void main(String[] args) { runTest(new VMPCMacTest()); } static byte[] output1 = Hex.decode("9BDA16E2AD0E284774A3ACBC8835A8326C11FAAD"); public void performTest() throws Exception { CipherParameters kp = new KeyParameter( Hex.decode("9661410AB797D8A9EB767C21172DF6C7")); CipherParameters kpwiv = new ParametersWithIV(kp, Hex.decode("4B5C2F003E67F39557A8D26F3DA2B155")); byte[] m = new byte[256]; for (int i = 0; i < 256; i++) { m[i] = (byte) i; } VMPCMac mac = new VMPCMac(); mac.init(kpwiv); mac.update(m, 0, m.length); byte[] out = new byte[20]; mac.doFinal(out, 0); if (!Arrays.areEqual(out, output1)) { fail("Fail", new String(Hex.encode(output1)), new String(Hex.encode(out))); } } } bouncycastle-1.49.orig/test/src/org/bouncycastle/crypto/test/package.html0000644000175000017500000000014710330633061026236 0ustar ebourgebourg Example code and test classes for the lightweight API. bouncycastle-1.49.orig/test/src/org/bouncycastle/crypto/test/AESWrapTest.java0000644000175000017500000001441210330633061026722 0ustar ebourgebourgpackage org.bouncycastle.crypto.test; import org.bouncycastle.crypto.DataLengthException; import org.bouncycastle.crypto.InvalidCipherTextException; import org.bouncycastle.crypto.Wrapper; import org.bouncycastle.crypto.engines.AESWrapEngine; import org.bouncycastle.crypto.params.KeyParameter; import org.bouncycastle.util.Arrays; import org.bouncycastle.util.encoders.Hex; import org.bouncycastle.util.test.SimpleTestResult; import org.bouncycastle.util.test.Test; import org.bouncycastle.util.test.TestResult; /** * Wrap Test */ public class AESWrapTest implements Test { public String getName() { return "AESWrap"; } private TestResult wrapTest( int id, byte[] kek, byte[] in, byte[] out) { Wrapper wrapper = new AESWrapEngine(); wrapper.init(true, new KeyParameter(kek)); try { byte[] cText = wrapper.wrap(in, 0, in.length); if (!Arrays.areEqual(cText, out)) { return new SimpleTestResult(false, getName() + ": failed wrap test " + id + " expected " + new String(Hex.encode(out)) + " got " + new String(Hex.encode(cText))); } } catch (Exception e) { return new SimpleTestResult(false, getName() + ": failed wrap test exception " + e.toString()); } wrapper.init(false, new KeyParameter(kek)); try { byte[] pText = wrapper.unwrap(out, 0, out.length); if (!Arrays.areEqual(pText, in)) { return new SimpleTestResult(false, getName() + ": failed unwrap test " + id + " expected " + new String(Hex.encode(in)) + " got " + new String(Hex.encode(pText))); } } catch (Exception e) { return new SimpleTestResult(false, getName() + ": failed unwrap test exception.", e); } return new SimpleTestResult(true, getName() + ": Okay"); } public TestResult perform() { byte[] kek1 = Hex.decode("000102030405060708090a0b0c0d0e0f"); byte[] in1 = Hex.decode("00112233445566778899aabbccddeeff"); byte[] out1 = Hex.decode("1fa68b0a8112b447aef34bd8fb5a7b829d3e862371d2cfe5"); TestResult result = wrapTest(1, kek1, in1, out1); if (!result.isSuccessful()) { return result; } byte[] kek2 = Hex.decode("000102030405060708090a0b0c0d0e0f1011121314151617"); byte[] in2 = Hex.decode("00112233445566778899aabbccddeeff"); byte[] out2 = Hex.decode("96778b25ae6ca435f92b5b97c050aed2468ab8a17ad84e5d"); result = wrapTest(2, kek2, in2, out2); if (!result.isSuccessful()) { return result; } byte[] kek3 = Hex.decode("000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f"); byte[] in3 = Hex.decode("00112233445566778899aabbccddeeff"); byte[] out3 = Hex.decode("64e8c3f9ce0f5ba263e9777905818a2a93c8191e7d6e8ae7"); result = wrapTest(3, kek3, in3, out3); if (!result.isSuccessful()) { return result; } byte[] kek4 = Hex.decode("000102030405060708090a0b0c0d0e0f1011121314151617"); byte[] in4 = Hex.decode("00112233445566778899aabbccddeeff0001020304050607"); byte[] out4 = Hex.decode("031d33264e15d33268f24ec260743edce1c6c7ddee725a936ba814915c6762d2"); result = wrapTest(4, kek4, in4, out4); if (!result.isSuccessful()) { return result; } byte[] kek5 = Hex.decode("000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f"); byte[] in5 = Hex.decode("00112233445566778899aabbccddeeff0001020304050607"); byte[] out5 = Hex.decode("a8f9bc1612c68b3ff6e6f4fbe30e71e4769c8b80a32cb8958cd5d17d6b254da1"); result = wrapTest(5, kek5, in5, out5); if (!result.isSuccessful()) { return result; } byte[] kek6 = Hex.decode("000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f"); byte[] in6 = Hex.decode("00112233445566778899aabbccddeeff000102030405060708090a0b0c0d0e0f"); byte[] out6 = Hex.decode("28c9f404c4b810f4cbccb35cfb87f8263f5786e2d80ed326cbc7f0e71a99f43bfb988b9b7a02dd21"); result = wrapTest(6, kek6, in6, out6); if (!result.isSuccessful()) { return result; } Wrapper wrapper = new AESWrapEngine(); KeyParameter key = new KeyParameter(new byte[16]); byte[] buf = new byte[16]; try { wrapper.init(true, key); wrapper.unwrap(buf, 0, buf.length); return new SimpleTestResult(false, getName() + ": failed unwrap state test."); } catch (IllegalStateException e) { // expected } catch (InvalidCipherTextException e) { return new SimpleTestResult(false, getName() + ": unexpected exception: " + e, e); } try { wrapper.init(false, key); wrapper.wrap(buf, 0, buf.length); return new SimpleTestResult(false, getName() + ": failed unwrap state test."); } catch (IllegalStateException e) { // expected } // // short test // try { wrapper.init(false, key); wrapper.unwrap(buf, 0, buf.length / 2); return new SimpleTestResult(false, getName() + ": failed unwrap short test."); } catch (InvalidCipherTextException e) { // expected } try { wrapper.init(true, key); wrapper.wrap(buf, 0, 15); return new SimpleTestResult(false, getName() + ": failed wrap length test."); } catch (DataLengthException e) { // expected } return new SimpleTestResult(true, getName() + ": Okay"); } public static void main( String[] args) { AESWrapTest test = new AESWrapTest(); TestResult result = test.perform(); System.out.println(result); } } bouncycastle-1.49.orig/test/src/org/bouncycastle/crypto/test/ShortenedDigestTest.java0000644000175000017500000000413410427071732030563 0ustar ebourgebourg/* * Created on 6/05/2006 * * To change the template for this generated file go to * Window>Preferences>Java>Code Generation>Code and Comments */ package org.bouncycastle.crypto.test; import org.bouncycastle.crypto.ExtendedDigest; import org.bouncycastle.crypto.digests.SHA1Digest; import org.bouncycastle.crypto.digests.SHA512Digest; import org.bouncycastle.crypto.digests.ShortenedDigest; import org.bouncycastle.util.test.SimpleTest; public class ShortenedDigestTest extends SimpleTest { public void performTest() { ExtendedDigest d = new SHA1Digest(); ShortenedDigest sd = new ShortenedDigest(new SHA1Digest(), 10); if (sd.getDigestSize() != 10) { fail("size check wrong for SHA-1"); } if (sd.getByteLength() != d.getByteLength()) { fail("byte length check wrong for SHA-1"); } // // check output fits // sd.doFinal(new byte[10], 0); d = new SHA512Digest(); sd = new ShortenedDigest(new SHA512Digest(), 20); if (sd.getDigestSize() != 20) { fail("size check wrong for SHA-512"); } if (sd.getByteLength() != d.getByteLength()) { fail("byte length check wrong for SHA-512"); } // // check output fits // sd.doFinal(new byte[20], 0); try { new ShortenedDigest(null, 20); fail("null parameter not caught"); } catch (IllegalArgumentException e) { // expected } try { new ShortenedDigest(new SHA1Digest(), 50); fail("short digest not caught"); } catch (IllegalArgumentException e) { // expected } } public String getName() { return "ShortenedDigest"; } public static void main( String[] args) { runTest(new ShortenedDigestTest()); } } bouncycastle-1.49.orig/test/src/org/bouncycastle/crypto/test/MacTest.java0000644000175000017500000001113510330633061026157 0ustar ebourgebourgpackage org.bouncycastle.crypto.test; import org.bouncycastle.crypto.BlockCipher; import org.bouncycastle.crypto.Mac; import org.bouncycastle.crypto.engines.DESEngine; import org.bouncycastle.crypto.macs.CBCBlockCipherMac; import org.bouncycastle.crypto.macs.CFBBlockCipherMac; import org.bouncycastle.crypto.params.KeyParameter; import org.bouncycastle.crypto.params.ParametersWithIV; import org.bouncycastle.crypto.paddings.PKCS7Padding; import org.bouncycastle.util.encoders.Hex; import org.bouncycastle.util.test.SimpleTest; /** * MAC tester - vectors from * FIP 81 and * FIP 113. */ public class MacTest extends SimpleTest { static byte[] keyBytes = Hex.decode("0123456789abcdef"); static byte[] ivBytes = Hex.decode("1234567890abcdef"); static byte[] input1 = Hex.decode("37363534333231204e6f77206973207468652074696d6520666f7220"); static byte[] output1 = Hex.decode("f1d30f68"); static byte[] output2 = Hex.decode("58d2e77e"); static byte[] output3 = Hex.decode("cd647403"); // // these aren't NIST vectors, just for regression testing. // static byte[] input2 = Hex.decode("3736353433323120"); static byte[] output4 = Hex.decode("3af549c9"); static byte[] output5 = Hex.decode("188fbdd5"); static byte[] output6 = Hex.decode("7045eecd"); public MacTest() { } public void performTest() { KeyParameter key = new KeyParameter(keyBytes); BlockCipher cipher = new DESEngine(); Mac mac = new CBCBlockCipherMac(cipher); // // standard DAC - zero IV // mac.init(key); mac.update(input1, 0, input1.length); byte[] out = new byte[4]; mac.doFinal(out, 0); if (!areEqual(out, output1)) { fail("Failed - expected " + new String(Hex.encode(output1)) + " got " + new String(Hex.encode(out))); } // // mac with IV. // ParametersWithIV param = new ParametersWithIV(key, ivBytes); mac.init(param); mac.update(input1, 0, input1.length); out = new byte[4]; mac.doFinal(out, 0); if (!areEqual(out, output2)) { fail("Failed - expected " + new String(Hex.encode(output2)) + " got " + new String(Hex.encode(out))); } // // CFB mac with IV - 8 bit CFB mode // param = new ParametersWithIV(key, ivBytes); mac = new CFBBlockCipherMac(cipher); mac.init(param); mac.update(input1, 0, input1.length); out = new byte[4]; mac.doFinal(out, 0); if (!areEqual(out, output3)) { fail("Failed - expected " + new String(Hex.encode(output3)) + " got " + new String(Hex.encode(out))); } // // word aligned data - zero IV // mac.init(key); mac.update(input2, 0, input2.length); out = new byte[4]; mac.doFinal(out, 0); if (!areEqual(out, output4)) { fail("Failed - expected " + new String(Hex.encode(output4)) + " got " + new String(Hex.encode(out))); } // // word aligned data - zero IV - CBC padding // mac = new CBCBlockCipherMac(cipher, new PKCS7Padding()); mac.init(key); mac.update(input2, 0, input2.length); out = new byte[4]; mac.doFinal(out, 0); if (!areEqual(out, output5)) { fail("Failed - expected " + new String(Hex.encode(output5)) + " got " + new String(Hex.encode(out))); } // // non-word aligned data - zero IV - CBC padding // mac.reset(); mac.update(input1, 0, input1.length); out = new byte[4]; mac.doFinal(out, 0); if (!areEqual(out, output6)) { fail("Failed - expected " + new String(Hex.encode(output6)) + " got " + new String(Hex.encode(out))); } // // non-word aligned data - zero IV - CBC padding // mac.init(key); mac.update(input1, 0, input1.length); out = new byte[4]; mac.doFinal(out, 0); if (!areEqual(out, output6)) { fail("Failed - expected " + new String(Hex.encode(output6)) + " got " + new String(Hex.encode(out))); } } public String getName() { return "Mac"; } public static void main( String[] args) { runTest(new MacTest()); } } bouncycastle-1.49.orig/test/src/org/bouncycastle/crypto/test/RIPEMD160DigestTest.java0000644000175000017500000000311710330633061030027 0ustar ebourgebourgpackage org.bouncycastle.crypto.test; import org.bouncycastle.crypto.Digest; import org.bouncycastle.crypto.digests.RIPEMD160Digest; /** * RIPEMD160 Digest Test */ public class RIPEMD160DigestTest extends DigestTest { final static String[] messages = { "", "a", "abc", "message digest", "abcdefghijklmnopqrstuvwxyz", "abcdbcdecdefdefgefghfghighijhijkijkljklmklmnlmnomnopnopq", "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789", "12345678901234567890123456789012345678901234567890123456789012345678901234567890" }; final static String[] digests = { "9c1185a5c5e9fc54612808977ee8f548b2258d31", "0bdc9d2d256b3ee9daae347be6f4dc835a467ffe", "8eb208f7e05d987a9b044a8e98c6b087f15a0bfc", "5d0689ef49d2fae572b881b123a85ffa21595f36", "f71c27109c692c1b56bbdceb5b9d2865b3708dbc", "12a053384a9c0c88e405a06c27dcf49ada62eb2b", "b0e20b6e3116640286ed3a87a5713079b21f5189", "9b752e45573d4b39f4dbd3323cab82bf63326bfb" }; final static String million_a_digest = "52783243c1697bdbe16d37f97f68f08325dc1528"; RIPEMD160DigestTest() { super(new RIPEMD160Digest(), messages, digests); } public void performTest() { super.performTest(); millionATest(million_a_digest); } protected Digest cloneDigest(Digest digest) { return new RIPEMD160Digest((RIPEMD160Digest)digest); } public static void main( String[] args) { runTest(new RIPEMD160DigestTest()); } } bouncycastle-1.49.orig/test/src/org/bouncycastle/crypto/test/RegressionTest.java0000644000175000017500000000726512150002220027575 0ustar ebourgebourgpackage org.bouncycastle.crypto.test; import org.bouncycastle.util.test.Test; import org.bouncycastle.util.test.TestResult; public class RegressionTest { public static Test[] tests = { new AESTest(), new AESLightTest(), new AESFastTest(), new AESWrapTest(), new DESTest(), new DESedeTest(), new ModeTest(), new PaddingTest(), new DHTest(), new ElGamalTest(), new DSATest(), new ECTest(), new GOST3410Test(), new ECGOST3410Test(), new ECIESTest(), new ECNRTest(), new MacTest(), new GOST28147MacTest(), new RC2Test(), new RC2WrapTest(), new RC4Test(), new RC5Test(), new RC6Test(), new RijndaelTest(), new SerpentTest(), new CamelliaTest(), new CamelliaLightTest(), new DigestRandomNumberTest(), new SkipjackTest(), new BlowfishTest(), new TwofishTest(), new CAST5Test(), new CAST6Test(), new GOST28147Test(), new IDEATest(), new RSATest(), new RSABlindedTest(), new RSADigestSignerTest(), new PSSBlindTest(), new ISO9796Test(), new ISO9797Alg3MacTest(), new MD2DigestTest(), new MD4DigestTest(), new MD5DigestTest(), new SHA1DigestTest(), new SHA224DigestTest(), new SHA256DigestTest(), new SHA384DigestTest(), new SHA512DigestTest(), new SHA512t224DigestTest(), new SHA512t256DigestTest(), new SHA3DigestTest(), new RIPEMD128DigestTest(), new RIPEMD160DigestTest(), new RIPEMD256DigestTest(), new RIPEMD320DigestTest(), new TigerDigestTest(), new GOST3411DigestTest(), new WhirlpoolDigestTest(), new MD5HMacTest(), new SHA1HMacTest(), new SHA224HMacTest(), new SHA256HMacTest(), new SHA384HMacTest(), new SHA512HMacTest(), new RIPEMD128HMacTest(), new RIPEMD160HMacTest(), new OAEPTest(), new PSSTest(), new CTSTest(), new CCMTest(), new PKCS5Test(), new PKCS12Test(), new KDF1GeneratorTest(), new KDF2GeneratorTest(), new MGF1GeneratorTest(), new HKDFGeneratorTest(), new DHKEKGeneratorTest(), new ECDHKEKGeneratorTest(), new ShortenedDigestTest(), new EqualsHashCodeTest(), new TEATest(), new XTEATest(), new RFC3211WrapTest(), new SEEDTest(), new Salsa20Test(), new CMacTest(), new EAXTest(), new GCMTest(), new GMacTest(), new HCFamilyTest(), new HCFamilyVecTest(), new ISAACTest(), new NoekeonTest(), new VMPCKSA3Test(), new VMPCMacTest(), new VMPCTest(), new Grainv1Test(), new Grain128Test(), //new NaccacheSternTest(), new SRP6Test(), new SCryptTest(), new ResetTest(), new NullTest(), new DSTU4145Test(), new SipHashTest(), new OCBTest(), new NonMemoableDigestTest(), new RSAKeyEncapsulationTest(), new ECIESKeyEncapsulationTest(), new HashCommitmentTest() }; public static void main( String[] args) { for (int i = 0; i != tests.length; i++) { TestResult result = tests[i].perform(); if (result.getException() != null) { result.getException().printStackTrace(); } System.out.println(result); } } } bouncycastle-1.49.orig/test/src/org/bouncycastle/crypto/test/MD5HMacTest.java0000644000175000017500000000635510770032642026613 0ustar ebourgebourg package org.bouncycastle.crypto.test; import org.bouncycastle.crypto.digests.MD5Digest; import org.bouncycastle.crypto.macs.HMac; import org.bouncycastle.crypto.params.KeyParameter; import org.bouncycastle.util.encoders.Hex; import org.bouncycastle.util.test.SimpleTest; /** * MD5 HMac Test, test vectors from RFC 2202 */ public class MD5HMacTest extends SimpleTest { final static String[] keys = { "0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b", "4a656665", "aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa", "0102030405060708090a0b0c0d0e0f10111213141516171819", "0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c", "aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa", "aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa" }; final static String[] digests = { "9294727a3638bb1c13f48ef8158bfc9d", "750c783e6ab0b503eaa86e310a5db738", "56be34521d144c88dbb8c733f0e8b3f6", "697eaf0aca3a3aea3a75164746ffaa79", "56461ef2342edc00f9bab995690efd4c", "6b1ab7fe4bd7bf8f0b62e6ce61b9d0cd", "6f630fad67cda0ee1fb1f562db3aa53e" }; final static String[] messages = { "Hi There", "what do ya want for nothing?", "0xdddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddd", "0xcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcd", "Test With Truncation", "Test Using Larger Than Block-Size Key - Hash Key First", "Test Using Larger Than Block-Size Key and Larger Than One Block-Size Data" }; public String getName() { return "MD5HMac"; } public void performTest() { HMac hmac = new HMac(new MD5Digest()); byte[] resBuf = new byte[hmac.getMacSize()]; for (int i = 0; i < messages.length; i++) { byte[] m = messages[i].getBytes(); if (messages[i].startsWith("0x")) { m = Hex.decode(messages[i].substring(2)); } hmac.init(new KeyParameter(Hex.decode(keys[i]))); hmac.update(m, 0, m.length); hmac.doFinal(resBuf, 0); if (!areEqual(resBuf, Hex.decode(digests[i]))) { fail("Vector " + i + " failed"); } } // test reset int vector = 0; // vector used for test byte[] m = messages[vector].getBytes(); if (messages[vector].startsWith("0x")) { m = Hex.decode(messages[vector].substring(2)); } hmac.init(new KeyParameter(Hex.decode(keys[vector]))); hmac.update(m, 0, m.length); hmac.doFinal(resBuf, 0); hmac.reset(); hmac.update(m, 0, m.length); hmac.doFinal(resBuf, 0); if (!areEqual(resBuf, Hex.decode(digests[vector]))) { fail("Reset with vector " + vector + " failed"); } } public static void main( String[] args) { runTest(new MD5HMacTest()); } } bouncycastle-1.49.orig/test/src/org/bouncycastle/crypto/test/ECIESTest.java0000644000175000017500000003255512033473217026327 0ustar ebourgebourgpackage org.bouncycastle.crypto.test; import java.math.BigInteger; import java.security.SecureRandom; import org.bouncycastle.crypto.AsymmetricCipherKeyPair; import org.bouncycastle.crypto.BufferedBlockCipher; import org.bouncycastle.crypto.KeyEncoder; import org.bouncycastle.crypto.KeyGenerationParameters; import org.bouncycastle.crypto.agreement.ECDHBasicAgreement; import org.bouncycastle.crypto.digests.SHA1Digest; import org.bouncycastle.crypto.engines.IESEngine; import org.bouncycastle.crypto.engines.TwofishEngine; import org.bouncycastle.crypto.generators.ECKeyPairGenerator; import org.bouncycastle.crypto.generators.EphemeralKeyPairGenerator; import org.bouncycastle.crypto.generators.KDF2BytesGenerator; import org.bouncycastle.crypto.macs.HMac; import org.bouncycastle.crypto.modes.CBCBlockCipher; import org.bouncycastle.crypto.paddings.PaddedBufferedBlockCipher; import org.bouncycastle.crypto.params.AsymmetricKeyParameter; import org.bouncycastle.crypto.params.ECDomainParameters; import org.bouncycastle.crypto.params.ECKeyGenerationParameters; import org.bouncycastle.crypto.params.ECPrivateKeyParameters; import org.bouncycastle.crypto.params.ECPublicKeyParameters; import org.bouncycastle.crypto.params.IESParameters; import org.bouncycastle.crypto.params.IESWithCipherParameters; import org.bouncycastle.crypto.parsers.ECIESPublicKeyParser; import org.bouncycastle.math.ec.ECCurve; import org.bouncycastle.util.encoders.Hex; import org.bouncycastle.util.test.SimpleTest; /** * test for ECIES - Elliptic Curve Integrated Encryption Scheme */ public class ECIESTest extends SimpleTest { ECIESTest() { } public String getName() { return "ECIES"; } private void staticTest() throws Exception { ECCurve.Fp curve = new ECCurve.Fp( new BigInteger("6277101735386680763835789423207666416083908700390324961279"), // q new BigInteger("fffffffffffffffffffffffffffffffefffffffffffffffc", 16), // a new BigInteger("64210519e59c80e70fa7e9ab72243049feb8deecc146b9b1", 16)); // b ECDomainParameters params = new ECDomainParameters( curve, curve.decodePoint(Hex.decode("03188da80eb03090f67cbf20eb43a18800f4ff0afd82ff1012")), // G new BigInteger("6277101735386680763835789423176059013767194773182842284081")); // n ECPrivateKeyParameters priKey = new ECPrivateKeyParameters( new BigInteger("651056770906015076056810763456358567190100156695615665659"), // d params); ECPublicKeyParameters pubKey = new ECPublicKeyParameters( curve.decodePoint(Hex.decode("0262b12d60690cdcf330babab6e69763b471f994dd702d16a5")), // Q params); AsymmetricCipherKeyPair p1 = new AsymmetricCipherKeyPair(pubKey, priKey); AsymmetricCipherKeyPair p2 = new AsymmetricCipherKeyPair(pubKey, priKey); // // stream test // IESEngine i1 = new IESEngine( new ECDHBasicAgreement(), new KDF2BytesGenerator(new SHA1Digest()), new HMac(new SHA1Digest())); IESEngine i2 = new IESEngine( new ECDHBasicAgreement(), new KDF2BytesGenerator(new SHA1Digest()), new HMac(new SHA1Digest())); byte[] d = new byte[] { 1, 2, 3, 4, 5, 6, 7, 8 }; byte[] e = new byte[] { 8, 7, 6, 5, 4, 3, 2, 1 }; IESParameters p = new IESParameters(d, e, 64); i1.init(true, p1.getPrivate(), p2.getPublic(), p); i2.init(false, p2.getPrivate(), p1.getPublic(), p); byte[] message = Hex.decode("1234567890abcdef"); byte[] out1 = i1.processBlock(message, 0, message.length); if (!areEqual(out1, Hex.decode("468d89877e8238802403ec4cb6b329faeccfa6f3a730f2cdb3c0a8e8"))) { fail("stream cipher test failed on enc"); } byte[] out2 = i2.processBlock(out1, 0, out1.length); if (!areEqual(out2, message)) { fail("stream cipher test failed"); } // // twofish with CBC // BufferedBlockCipher c1 = new PaddedBufferedBlockCipher( new CBCBlockCipher(new TwofishEngine())); BufferedBlockCipher c2 = new PaddedBufferedBlockCipher( new CBCBlockCipher(new TwofishEngine())); i1 = new IESEngine( new ECDHBasicAgreement(), new KDF2BytesGenerator(new SHA1Digest()), new HMac(new SHA1Digest()), c1); i2 = new IESEngine( new ECDHBasicAgreement(), new KDF2BytesGenerator(new SHA1Digest()), new HMac(new SHA1Digest()), c2); d = new byte[] { 1, 2, 3, 4, 5, 6, 7, 8 }; e = new byte[] { 8, 7, 6, 5, 4, 3, 2, 1 }; p = new IESWithCipherParameters(d, e, 64, 128); i1.init(true, p1.getPrivate(), p2.getPublic(), p); i2.init(false, p2.getPrivate(), p1.getPublic(), p); message = Hex.decode("1234567890abcdef"); out1 = i1.processBlock(message, 0, message.length); if (!areEqual(out1, Hex.decode("b8a06ea5c2b9df28b58a0a90a734cde8c9c02903e5c220021fe4417410d1e53a32a71696"))) { fail("twofish cipher test failed on enc"); } out2 = i2.processBlock(out1, 0, out1.length); if (!areEqual(out2, message)) { fail("twofish cipher test failed"); } } private void doEphemeralTest() throws Exception { ECCurve.Fp curve = new ECCurve.Fp( new BigInteger("6277101735386680763835789423207666416083908700390324961279"), // q new BigInteger("fffffffffffffffffffffffffffffffefffffffffffffffc", 16), // a new BigInteger("64210519e59c80e70fa7e9ab72243049feb8deecc146b9b1", 16)); // b ECDomainParameters params = new ECDomainParameters( curve, curve.decodePoint(Hex.decode("03188da80eb03090f67cbf20eb43a18800f4ff0afd82ff1012")), // G new BigInteger("6277101735386680763835789423176059013767194773182842284081")); // n ECPrivateKeyParameters priKey = new ECPrivateKeyParameters( new BigInteger("651056770906015076056810763456358567190100156695615665659"), // d params); ECPublicKeyParameters pubKey = new ECPublicKeyParameters( curve.decodePoint(Hex.decode("0262b12d60690cdcf330babab6e69763b471f994dd702d16a5")), // Q params); AsymmetricCipherKeyPair p1 = new AsymmetricCipherKeyPair(pubKey, priKey); AsymmetricCipherKeyPair p2 = new AsymmetricCipherKeyPair(pubKey, priKey); // Generate the ephemeral key pair ECKeyPairGenerator gen = new ECKeyPairGenerator(); gen.init(new ECKeyGenerationParameters(params, new SecureRandom())); EphemeralKeyPairGenerator ephKeyGen = new EphemeralKeyPairGenerator(gen, new KeyEncoder() { public byte[] getEncoded(AsymmetricKeyParameter keyParameter) { return ((ECPublicKeyParameters)keyParameter).getQ().getEncoded(); } }); // // stream test // IESEngine i1 = new IESEngine( new ECDHBasicAgreement(), new KDF2BytesGenerator(new SHA1Digest()), new HMac(new SHA1Digest())); IESEngine i2 = new IESEngine( new ECDHBasicAgreement(), new KDF2BytesGenerator(new SHA1Digest()), new HMac(new SHA1Digest())); byte[] d = new byte[] { 1, 2, 3, 4, 5, 6, 7, 8 }; byte[] e = new byte[] { 8, 7, 6, 5, 4, 3, 2, 1 }; IESParameters p = new IESParameters(d, e, 64); i1.init(p2.getPublic(), p, ephKeyGen); i2.init(p2.getPrivate(), p, new ECIESPublicKeyParser(params)); byte[] message = Hex.decode("1234567890abcdef"); byte[] out1 = i1.processBlock(message, 0, message.length); byte[] out2 = i2.processBlock(out1, 0, out1.length); if (!areEqual(out2, message)) { fail("stream cipher test failed"); } // // twofish with CBC // BufferedBlockCipher c1 = new PaddedBufferedBlockCipher( new CBCBlockCipher(new TwofishEngine())); BufferedBlockCipher c2 = new PaddedBufferedBlockCipher( new CBCBlockCipher(new TwofishEngine())); i1 = new IESEngine( new ECDHBasicAgreement(), new KDF2BytesGenerator(new SHA1Digest()), new HMac(new SHA1Digest()), c1); i2 = new IESEngine( new ECDHBasicAgreement(), new KDF2BytesGenerator(new SHA1Digest()), new HMac(new SHA1Digest()), c2); d = new byte[] { 1, 2, 3, 4, 5, 6, 7, 8 }; e = new byte[] { 8, 7, 6, 5, 4, 3, 2, 1 }; p = new IESWithCipherParameters(d, e, 64, 128); i1.init(p2.getPublic(), p, ephKeyGen); i2.init(p2.getPrivate(), p, new ECIESPublicKeyParser(params)); message = Hex.decode("1234567890abcdef"); out1 = i1.processBlock(message, 0, message.length); out2 = i2.processBlock(out1, 0, out1.length); if (!areEqual(out2, message)) { fail("twofish cipher test failed"); } } private void doTest(AsymmetricCipherKeyPair p1, AsymmetricCipherKeyPair p2) throws Exception { // // stream test // IESEngine i1 = new IESEngine( new ECDHBasicAgreement(), new KDF2BytesGenerator(new SHA1Digest()), new HMac(new SHA1Digest())); IESEngine i2 = new IESEngine( new ECDHBasicAgreement(), new KDF2BytesGenerator(new SHA1Digest()), new HMac(new SHA1Digest())); byte[] d = new byte[] { 1, 2, 3, 4, 5, 6, 7, 8 }; byte[] e = new byte[] { 8, 7, 6, 5, 4, 3, 2, 1 }; IESParameters p = new IESParameters(d, e, 64); i1.init(true, p1.getPrivate(), p2.getPublic(), p); i2.init(false, p2.getPrivate(), p1.getPublic(), p); byte[] message = Hex.decode("1234567890abcdef"); byte[] out1 = i1.processBlock(message, 0, message.length); byte[] out2 = i2.processBlock(out1, 0, out1.length); if (!areEqual(out2, message)) { fail("stream cipher test failed"); } // // twofish with CBC // BufferedBlockCipher c1 = new PaddedBufferedBlockCipher( new CBCBlockCipher(new TwofishEngine())); BufferedBlockCipher c2 = new PaddedBufferedBlockCipher( new CBCBlockCipher(new TwofishEngine())); i1 = new IESEngine( new ECDHBasicAgreement(), new KDF2BytesGenerator(new SHA1Digest()), new HMac(new SHA1Digest()), c1); i2 = new IESEngine( new ECDHBasicAgreement(), new KDF2BytesGenerator(new SHA1Digest()), new HMac(new SHA1Digest()), c2); d = new byte[] { 1, 2, 3, 4, 5, 6, 7, 8 }; e = new byte[] { 8, 7, 6, 5, 4, 3, 2, 1 }; p = new IESWithCipherParameters(d, e, 64, 128); i1.init(true, p1.getPrivate(), p2.getPublic(), p); i2.init(false, p2.getPrivate(), p1.getPublic(), p); message = Hex.decode("1234567890abcdef"); out1 = i1.processBlock(message, 0, message.length); out2 = i2.processBlock(out1, 0, out1.length); if (!areEqual(out2, message)) { fail("twofish cipher test failed"); } } public void performTest() throws Exception { staticTest(); ECCurve.Fp curve = new ECCurve.Fp( new BigInteger("6277101735386680763835789423207666416083908700390324961279"), // q new BigInteger("fffffffffffffffffffffffffffffffefffffffffffffffc", 16), // a new BigInteger("64210519e59c80e70fa7e9ab72243049feb8deecc146b9b1", 16)); // b ECDomainParameters params = new ECDomainParameters( curve, curve.decodePoint(Hex.decode("03188da80eb03090f67cbf20eb43a18800f4ff0afd82ff1012")), // G new BigInteger("6277101735386680763835789423176059013767194773182842284081")); // n ECKeyPairGenerator eGen = new ECKeyPairGenerator(); KeyGenerationParameters gParam = new ECKeyGenerationParameters(params, new SecureRandom()); eGen.init(gParam); AsymmetricCipherKeyPair p1 = eGen.generateKeyPair(); AsymmetricCipherKeyPair p2 = eGen.generateKeyPair(); doTest(p1, p2); doEphemeralTest(); } public static void main( String[] args) { runTest(new ECIESTest()); } } bouncycastle-1.49.orig/test/src/org/bouncycastle/crypto/prng/0000755000175000017500000000000012152033550023743 5ustar ebourgebourgbouncycastle-1.49.orig/test/src/org/bouncycastle/crypto/prng/test/0000755000175000017500000000000012152033550024722 5ustar ebourgebourgbouncycastle-1.49.orig/test/src/org/bouncycastle/crypto/prng/test/HashDRBGTest.java0000644000175000017500000006070612143337351027766 0ustar ebourgebourgpackage org.bouncycastle.crypto.prng.test; import org.bouncycastle.crypto.digests.SHA1Digest; import org.bouncycastle.crypto.digests.SHA256Digest; import org.bouncycastle.crypto.digests.SHA384Digest; import org.bouncycastle.crypto.digests.SHA512Digest; import org.bouncycastle.crypto.prng.drbg.HashSP800DRBG; import org.bouncycastle.crypto.prng.drbg.SP80090DRBG; import org.bouncycastle.util.encoders.Hex; import org.bouncycastle.util.test.SimpleTest; /** * DRBG Test */ public class HashDRBGTest extends SimpleTest { public String getName() { return "HashDRBG"; } public static void main(String[] args) { runTest(new HashDRBGTest()); } private DRBGTestVector[] createTestVectorData() { return new DRBGTestVector[] { new DRBGTestVector( new SHA1Digest(), new SHA1EntropyProvider().get(440), false, "2021222324", 80, new String[] { "9F7CFF1ECA23E750F66326969F11800F12088BA68E441D15D888B3FE12BF66FE057494F4546DE2F1", "B77AA5C0CD55BBCEED7574AF223AFD988C7EEC8EFF4A94E5E89D26A04F58FA79F5E0D3702D7A9A6A" } ), new DRBGTestVector( new SHA1Digest(), new SHA1EntropyProvider().get(440), false, "2021222324", 80, new String[] { "AB438BD3B01A0AF85CFEE29F7D7B71621C4908B909124D430E7B406FB1086EA994C582E0D656D989", "29D9098F987E7005314A0F51B3DD2B8122F4AED706735DE6AD5DDBF223177C1E5F3AEBC52FAB90B9" }) .setPersonalizationString("404142434445464748494A4B4C4D4E4F505152535455565758595A5B5C5D5E5F606162636465666768696A6B6C6D6E6F70717273747576"), new DRBGTestVector( new SHA1Digest(), new SHA1EntropyProvider().get(440), false, "2021222324", 80, new String[] { "E76B4EDD5C865BC8AFD809A59B69B429AC7F4352A579BCF3F75E56249A3491F87C3CA6848B0FAB25", "6577B6B4F87A93240B199FE51A3B335313683103DECE171E3256FB7E803586CA4E45DD242EB01F70" }) .addAdditionalInput("606162636465666768696A6B6C6D6E6F707172737475767778797A7B7C7D7E7F808182838485868788898A8B8C8D8E8F90919293949596") .addAdditionalInput("A0A1A2A3A4A5A6A7A8A9AAABACADAEAFB0B1B2B3B4B5B6B7B8B9BABBBCBDBEBFC0C1C2C3C4C5C6C7C8C9CACBCCCDCECFD0D1D2D3D4D5D6"), new DRBGTestVector( new SHA1Digest(), new SHA1EntropyProvider().get(440), true, "2021222324", 80, new String[] { "56EF4913373994D5539F4D7D17AFE7448CDF5E72416CC6A71A340059FA0D5AE526B23250C46C0944", "575B37A2739814F966C63B60A2C4F149CA9ACC84FC4B25493289B085C67B2E30F5F0B99A2C349E2A" }), new DRBGTestVector( new SHA1Digest(), new SHA1EntropyProvider().get(440), true, "2021222324", 80, new String[] { "532CA1165DCFF21C55592687639884AF4BC4B057DF8F41DE653AB44E2ADEC7C9303E75ABE277EDBF", "73C2C67C696D686D0C4DBCEB5C2AF7DDF6F020B6874FAE4390F102117ECAAFF54418529A367005A0" }) .setPersonalizationString("404142434445464748494A4B4C4D4E4F505152535455565758595A5B5C5D5E5F606162636465666768696A6B6C6D6E6F70717273747576"), new DRBGTestVector( new SHA1Digest(), new SHA1EntropyProvider().get(440), true, "2021222324", 80, new String[] { "183C242A1430E46C4ED70B4DBE1BF9AB0AB8721CDCA2A2D1820AD6F6C956858543B2AA191D8D1287", "F196F9BD021C745CBD5AC7BFCE48EAAF0D0E7C091FBF436940E63A198EE770D9A4F0718669AF2BC9" }) .addAdditionalInput("606162636465666768696A6B6C6D6E6F707172737475767778797A7B7C7D7E7F808182838485868788898A8B8C8D8E8F90919293949596") .addAdditionalInput("A0A1A2A3A4A5A6A7A8A9AAABACADAEAFB0B1B2B3B4B5B6B7B8B9BABBBCBDBEBFC0C1C2C3C4C5C6C7C8C9CACBCCCDCECFD0D1D2D3D4D5D6"), new DRBGTestVector( new SHA256Digest(), new SHA256EntropyProvider().get(440), false, "2021222324252627", 128, new String[] { "77E05A0E7DC78AB5D8934D5E93E82C06" + "A07C04CEE6C9C53045EEB485872777CF3B3E35C474F976B8" + "94BF301A86FA651F463970E89D4A0534B2ECAD29EC044E7E", "5FF4BA493C40CFFF3B01E472C575668C" + "CE3880B9290B05BFEDE5EC96ED5E9B2898508B09BC800EEE" + "099A3C90602ABD4B1D4F343D497C6055C87BB956D53BF351" } ), new DRBGTestVector( new SHA256Digest(), new SHA256EntropyProvider().get(440), true, "2021222324252627", 128, new String[] { "92275523C70E567BCF9B35EC50B933F8" + "12616DF586B7F72EE1BC7735A5C2654373CBBC72316DFF84" + "20A33BF02B97AC8D1952583F270ACD7005CC027F4CF1187E", "681A46B2AA8694A0FE4DEEA720927A84" + "EAAA985E59C19F8BE0984D8CBEF8C69B754167641946E040" + "EE2043E1CCB29DCF063C0A50830E428E6DCA262ECD77C542" }), new DRBGTestVector( new SHA384Digest(), new SHA384EntropyProvider().get(888), false, "202122232425262728292A2B", 192, new String[] { "04FF23AD15E78790ADD36B438BBC097C7A11747CC2CCEEDE" + "2C978B23B3DC63B732C953061D7764990ABFEFC47A581B92" + "1BC0428C4F12212460E406A0F0651E7F0CB9A90ABFDB07B5" + "25565C74F0AA085082F6CF213AAFAD0C0646895078F1E1FE", "4F35B85F95DEE3E873054905CFD02341653E18F529930CBE" + "14D909F37FEAF2C790D22FAE7516B4590BE35D53E2FE1A35" + "AFE4B6607CB358589C3B4D094A1D81FE0717F1DF5BDDEB3E" + "114F130BB781E66C22B5B770E8AE115FF39F8ADAF66DEEDF" } ), new DRBGTestVector( new SHA384Digest(), new SHA384EntropyProvider().get(888), true, "202122232425262728292A2B", 192, new String[] { "97993B78F7C31C0E876DC92EB7D6C408E09D608AD6B99D0E" + "A2229B05A578C426334FCC8A1C7E676ED2D89A5B4CDF5B3F" + "4ADF11936BF14F4E10909DBA9C24F4FDFFDE72351DA8E2CC" + "3B135A395373899E5F1A5955B880CA9B9E9DD4C9CA7FA4D4", "F5983946320E36C64EF283CA1F65D197CF81624EC6778E77" + "0E78949D84EF21A45CDD62D1DB76920D4C2836FC6AE5299F" + "AF1357D9701FAD10FBD88D1E2832239436D76EB271BDC3CA" + "04425EC88BC0E89A4D5C37FFCE7C6C3ABDE9C413AE6D3FEA" } ), new DRBGTestVector( new SHA512Digest(), new SHA512EntropyProvider().get(888), false, "202122232425262728292A2B2C2D2E2F", 256, new String[] { "DA126CF95C6BF97E" + "2F731F2137A907ACC70FD7AC9EBACD1C6E31C74029B052E3" + "AABC48F3B00993F2B2381F7650A55322A968C86E05DE88E6" + "367F6EF89A601DB4342E9086C7AC13B5E56C32E9E668040B" + "73847893C5BFD38A1CF44F348B4EEE4CD68ADB7E7B8C837F" + "19BC4F902761F7CFF24AB1D704FD11C4E929D8553753B55D", "400B977CE8A2BB6A" + "84C6FD1CF901459685ABF5408CFF4588CEDF52E2D2DC300A" + "A9B4FAED8CD0161C2172B1FD269253195883D6EBF21020F2" + "C20E5F2C81AE60C8595B834A229B1F5B726C1125717E6207" + "8886EF38E61E32707AD5F8116C6393DFB6E7C7AE0E8E92BB" + "D7E0C3D04BBA02F5169F2F569A58158915FEE4C9D28D45DB" } ) .setPersonalizationString( "404142434445464748494A4B4C4D4E" + "4F505152535455565758595A5B5C5D5E5F60616263646566" + "6768696A6B6C6D6E6F707172737475767778797A7B7C7D7E" + "7F808182838485868788898A8B8C8D8E8F90919293949596" + "9798999A9B9C9D9E9FA0A1A2A3A4A5A6A7A8A9AAABACADAE") .addAdditionalInput( "606162636465666768696A6B6C6D6E" + "6F707172737475767778797A7B7C7D7E7F80818283848586" + "8788898A8B8C8D8E8F909192939495969798999A9B9C9D9E" + "9FA0A1A2A3A4A5A6A7A8A9AAABACADAEAFB0B1B2B3B4B5B6" + "B7B8B9BABBBCBDBEBFC0C1C2C3C4C5C6C7C8C9CACBCCCDCE") .addAdditionalInput( "A0A1A2A3A4A5A6A7A8A9AAABACADAE" + "AFB0B1B2B3B4B5B6B7B8B9BABBBCBDBEBFC0C1C2C3C4C5C6" + "C7C8C9CACBCCCDCECFD0D1D2D3D4D5D6D7D8D9DADBDCDDDE" + "DFE0E1E2E3E4E5E6E7E8E9EAEBECEDEEEFF0F1F2F3F4F5F6" + "F7F8F9FAFBFCFDFEFF000102030405060708090A0B0C0D0E"), new DRBGTestVector( new SHA512Digest(), new SHA512EntropyProvider().get(888), true, "202122232425262728292A2B2C2D2E2F", 256, new String[] { "F93CA6855590A77F" + "07354097E90E026648B6115DF008FFEDBD9D9811F54E8286" + "EF00FDD6BA1E58DF2535E3FBDD9A9BA3754A97F36EE83322" + "1582060A1F37FCE4EE8826636B28EAD589593F4CA8B64738" + "8F24EB3F0A34796968D21BDEE6F81FD5DF93536F935937B8" + "025EC8CBF57DDB0C61F2E41463CC1516D657DA2829C6BF90", "4817618F48C60FB1" + "CE5BFBDA0CAF4591882A31F6EE3FE0F78779992A06EC60F3" + "7FB9A8D6108C231F0A927754B0599FA4FA27A4E25E065EF0" + "3085B892979DC0E7A1080883CAEBFDFD3665A8F2D061C521" + "F7D6E3DA2AF8B97B6B43B6EC831AF515070A83BBB9AC95ED" + "4EF49B756A2377A5F0833D847E27A88DDB0C2CE4AD782E7B " } ), new DRBGTestVector( new SHA512Digest(), new SHA512EntropyProvider().get(888), true, "202122232425262728292A2B2C2D2E2F", 256, new String[] { "0455DD4AD7DBACB2" + "410BE58DF7248D765A4547ABAEE1743B0BCAD37EBD06DA7C" + "F7CE5E2216E525327E9E2005EBEF2CE53BD733B18128627D" + "3FD6153089373AF2606A1584646A0EA488BFEF45228699A0" + "89CEA8AEC44502D86D9591F3552C688B7F7B45FCB0C3C2B9" + "43C1CD8A6FC63DF4D81C3DA543C9CF2843855EA84E4F959C", "C047D46D7F614E4E" + "4A7952C79A451F8F7ACA379967E2977C401C626A2ED70D74" + "A63660579A354115BC8C8C8CC3AEA3050686A0CFCDB6FA9C" + "F78D4C2165BAF851C6F9B1CD16A2E14C15C6DAAC56C16E75" + "FC84A14D58B41622E88B0F1B1995587FD8BAA999CBA98025" + "4C8AB9A9691DF7B84D88B639A9A3106DEABEB63748B99C09" } ) .addAdditionalInput( "606162636465666768696A6B6C6D6E" + "6F707172737475767778797A7B7C7D7E7F80818283848586" + "8788898A8B8C8D8E8F909192939495969798999A9B9C9D9E" + "9FA0A1A2A3A4A5A6A7A8A9AAABACADAEAFB0B1B2B3B4B5B6" + "B7B8B9BABBBCBDBEBFC0C1C2C3C4C5C6C7C8C9CACBCCCDCE") .addAdditionalInput( "A0A1A2A3A4A5A6A7A8A9AAABACADAE" + "AFB0B1B2B3B4B5B6B7B8B9BABBBCBDBEBFC0C1C2C3C4C5C6" + "C7C8C9CACBCCCDCECFD0D1D2D3D4D5D6D7D8D9DADBDCDDDE" + "DFE0E1E2E3E4E5E6E7E8E9EAEBECEDEEEFF0F1F2F3F4F5F6" + "F7F8F9FAFBFCFDFEFF000102030405060708090A0B0C0D0E"), new DRBGTestVector( new SHA512Digest(), new SHA512EntropyProvider().get(888), true, "202122232425262728292A2B2C2D2E2F", 256, new String[] { "22EB93A67911DA73" + "85D9180C78127DE1A04FF713114C07C9C615F7CC5EF72744" + "A2DDCD7C3CB85E65DED8EF5F240FBDCBEBBDE2BAAC8ECF7D" + "CBC8AC333E54607AD41DC495D83DF72A05EF55B127C1441C" + "9A0EFFDA2C7954DB6C2D04342EB812E5E0B11D6C395F41ED" + "A2702ECE5BA479E2DFA18F953097492636C12FE30CE5C968", "E66698CFBF1B3F2E" + "919C03036E584EAA81CF1C6666240AF05F70637043733954" + "D8A1E5A66A04C53C6900FDC145D4A3A80A31F5868ACE9AC9" + "4E14E2051F624A05EEA1F8B684AA5410BCE315E76EA07C71" + "5D6F34731320FF0DCF78D795E6EFA2DF92B98BE636CDFBA2" + "9008DD392112AEC202F2E481CB9D83F987FEA69CD1B368BB" } ) .setPersonalizationString( "404142434445464748494A4B4C4D4E" + "4F505152535455565758595A5B5C5D5E5F60616263646566" + "6768696A6B6C6D6E6F707172737475767778797A7B7C7D7E" + "7F808182838485868788898A8B8C8D8E8F90919293949596" + "9798999A9B9C9D9E9FA0A1A2A3A4A5A6A7A8A9AAABACADAE"), new DRBGTestVector( new SHA512Digest(), new SHA512EntropyProvider().get(888), true, "202122232425262728292A2B2C2D2E2F", 256, new String[] { "7596A76372308BD5" + "A5613439934678B35521A94D81ABFE63A21ACF61ABB88B61" + "E86A12C37F308F2BBBE32BE4B38D03AE808386494D70EF52" + "E9E1365DD18B7784CAB826F31D47579E4D57F69D8BF3152B" + "95741946CEBE58571DF58ED39980D9AF44E69F01E8989759" + "8E40171101A0E3302838E0AD9E849C01988993CF9F6E5263", "DBE5EE36FCD85301" + "303E1C3617C1AC5E23C08885D0BEFAAD0C85A0D89F85B9F1" + "6ECE3D88A24EB96504F2F13EFA7049621782F5DE2C416A0D" + "294CCFE53545C4E309C48E1E285A2B829A574B72B3C2FBE1" + "34D01E3706B486F2401B9820E17298A342666918E15B8462" + "87F8C5AF2D96B20FAF3D0BB392E15F4A06CDB0DECD1B6AD7" } ) .setPersonalizationString( "404142434445464748494A4B4C4D4E" + "4F505152535455565758595A5B5C5D5E5F60616263646566" + "6768696A6B6C6D6E6F707172737475767778797A7B7C7D7E" + "7F808182838485868788898A8B8C8D8E8F90919293949596" + "9798999A9B9C9D9E9FA0A1A2A3A4A5A6A7A8A9AAABACADAE") .addAdditionalInput( "606162636465666768696A6B6C6D6E" + "6F707172737475767778797A7B7C7D7E7F80818283848586" + "8788898A8B8C8D8E8F909192939495969798999A9B9C9D9E" + "9FA0A1A2A3A4A5A6A7A8A9AAABACADAEAFB0B1B2B3B4B5B6" + "B7B8B9BABBBCBDBEBFC0C1C2C3C4C5C6C7C8C9CACBCCCDCE") .addAdditionalInput( "A0A1A2A3A4A5A6A7A8A9AAABACADAE" + "AFB0B1B2B3B4B5B6B7B8B9BABBBCBDBEBFC0C1C2C3C4C5C6" + "C7C8C9CACBCCCDCECFD0D1D2D3D4D5D6D7D8D9DADBDCDDDE" + "DFE0E1E2E3E4E5E6E7E8E9EAEBECEDEEEFF0F1F2F3F4F5F6" + "F7F8F9FAFBFCFDFEFF000102030405060708090A0B0C0D0E") }; } public void performTest() throws Exception { DRBGTestVector[] tests = createTestVectorData(); for (int i = 0; i != tests.length; i++) { DRBGTestVector tv = tests[i]; byte[] nonce = tv.nonce(); byte[] personalisationString = tv.personalizationString(); SP80090DRBG d = new HashSP800DRBG(tv.getDigest(), tv.securityStrength(), tv.entropySource(), personalisationString, nonce); byte[] output = new byte[tv.expectedValue(0).length]; d.generate(output, tv.additionalInput(0), tv.predictionResistance()); byte[] expected = tv.expectedValue(0); if (!areEqual(expected, output)) { fail("Test #" + (i + 1) + ".1 failed, expected " + new String(Hex.encode(tv.expectedValue(0))) + " got " + new String(Hex.encode(output))); } output = new byte[tv.expectedValue(0).length]; d.generate(output, tv.additionalInput(1), tv.predictionResistance()); expected = tv.expectedValue(1); if (!areEqual(expected, output)) { fail("Test #" + (i + 1) + ".2 failed, expected " + new String(Hex.encode(tv.expectedValue(1))) + " got " + new String(Hex.encode(output))); } } // Exception tests // SP80090DRBG d; try { d = new HashSP800DRBG(new SHA256Digest(), 256, new SHA256EntropyProvider().get(128), null, null); fail("no exception thrown"); } catch (IllegalArgumentException e) { if (!e.getMessage().equals("Not enough entropy for security strength required")) { fail("Wrong exception", e); } } try { d = new HashSP800DRBG(new SHA1Digest(), 256, new SHA256EntropyProvider().get(256), null, null); fail("no exception thrown"); } catch (IllegalArgumentException e) { if (!e.getMessage().equals("Requested security strength is not supported by the derivation function")) { fail("Wrong exception", e); } } } private class SHA1EntropyProvider extends TestEntropySourceProvider { SHA1EntropyProvider() { super( Hex.decode( "000102030405060708090A0B0C0D0E0F101112131415161718191A1B1C1D1E1F202122232425262728292A2B2C2D2E2F30313233343536" + "808182838485868788898A8B8C8D8E8F909192939495969798999A9B9C9D9E9FA0A1A2A3A4A5A6A7A8A9AAABACADAEAFB0B1B2B3B4B5B6" + "C0C1C2C3C4C5C6C7C8C9CACBCCCDCECFD0D1D2D3D4D5D6D7D8D9DADBDCDDDEDFE0E1E2E3E4E5E6E7E8E9EAEBECEDEEEFF0F1F2F3F4F5F6"), true); } } private class SHA256EntropyProvider extends TestEntropySourceProvider { SHA256EntropyProvider() { super(Hex.decode( "00010203040506" + "0708090A0B0C0D0E0F101112131415161718191A1B1C1D1E" + "1F202122232425262728292A2B2C2D2E2F30313233343536" + "80818283848586" + "8788898A8B8C8D8E8F909192939495969798999A9B9C9D9E" + "9FA0A1A2A3A4A5A6A7A8A9AAABACADAEAFB0B1B2B3B4B5B6" + "C0C1C2C3C4C5C6" + "C7C8C9CACBCCCDCECFD0D1D2D3D4D5D6D7D8D9DADBDCDDDE" + "DFE0E1E2E3E4E5E6E7E8E9EAEBECEDEEEFF0F1F2F3F4F5F6"), true); } } private class SHA384EntropyProvider extends TestEntropySourceProvider { SHA384EntropyProvider() { super(Hex.decode( "000102030405060708090A0B0C0D0E0F101112131415161718191A1B1C1D1E1F20212223242526" + "2728292A2B2C2D2E2F303132333435363738393A3B3C3D3E3F404142434445464748494A4B4C4D4E4F50515253545556" + "5758595A5B5C5D5E5F606162636465666768696A6B6C6D6E" + "808182838485868788898A8B8C8D8E" + "8F909192939495969798999A9B9C9D9E9FA0A1A2A3A4A5A6" + "A7A8A9AAABACADAEAFB0B1B2B3B4B5B6B7B8B9BABBBCBDBE" + "BFC0C1C2C3C4C5C6C7C8C9CACBCCCDCECFD0D1D2D3D4D5D6" + "D7D8D9DADBDCDDDEDFE0E1E2E3E4E5E6E7E8E9EAEBECEDEE" + "C0C1C2C3C4C5C6C7C8C9CACBCCCDCE" + "CFD0D1D2D3D4D5D6D7D8D9DADBDCDDDEDFE0E1E2E3E4E5E6" + "E7E8E9EAEBECEDEEEFF0F1F2F3F4F5F6F7F8F9FAFBFCFDFE" + "FF000102030405060708090A0B0C0D0E0F10111213141516" + "1718191A1B1C1D1E1F202122232425262728292A2B2C2D2E"), true); } } private class SHA512EntropyProvider extends TestEntropySourceProvider { SHA512EntropyProvider() { super(Hex.decode( "000102030405060708090A0B0C0D0E" + "0F101112131415161718191A1B1C1D1E1F20212223242526" + "2728292A2B2C2D2E2F303132333435363738393A3B3C3D3E" + "3F404142434445464748494A4B4C4D4E4F50515253545556" + "5758595A5B5C5D5E5F606162636465666768696A6B6C6D6E" + "808182838485868788898A8B8C8D8E" + "8F909192939495969798999A9B9C9D9E9FA0A1A2A3A4A5A6" + "A7A8A9AAABACADAEAFB0B1B2B3B4B5B6B7B8B9BABBBCBDBE" + "BFC0C1C2C3C4C5C6C7C8C9CACBCCCDCECFD0D1D2D3D4D5D6" + "D7D8D9DADBDCDDDEDFE0E1E2E3E4E5E6E7E8E9EAEBECEDEE" + "C0C1C2C3C4C5C6C7C8C9CACBCCCDCE" + "CFD0D1D2D3D4D5D6D7D8D9DADBDCDDDEDFE0E1E2E3E4E5E6" + "E7E8E9EAEBECEDEEEFF0F1F2F3F4F5F6F7F8F9FAFBFCFDFE" + "FF000102030405060708090A0B0C0D0E0F10111213141516" + "1718191A1B1C1D1E1F202122232425262728292A2B2C2D2E"), true); } } } bouncycastle-1.49.orig/test/src/org/bouncycastle/crypto/prng/test/HMacDRBGTest.java0000644000175000017500000006462312143337351027715 0ustar ebourgebourgpackage org.bouncycastle.crypto.prng.test; import org.bouncycastle.crypto.digests.SHA1Digest; import org.bouncycastle.crypto.digests.SHA256Digest; import org.bouncycastle.crypto.digests.SHA384Digest; import org.bouncycastle.crypto.digests.SHA512Digest; import org.bouncycastle.crypto.macs.HMac; import org.bouncycastle.crypto.prng.drbg.HMacSP800DRBG; import org.bouncycastle.crypto.prng.drbg.SP80090DRBG; import org.bouncycastle.util.encoders.Hex; import org.bouncycastle.util.test.SimpleTest; /** * HMAC SP800-90 DRBG */ public class HMacDRBGTest extends SimpleTest { public String getName() { return "HMacDRBG"; } public static void main(String[] args) { runTest(new HMacDRBGTest()); } private DRBGTestVector[] createTestVectorData() { return new DRBGTestVector[] { new DRBGTestVector( new SHA1Digest(), new SHA1EntropyProvider().get(440), false, "2021222324", 80, new String[] { "5A7D3B449F481CB38DF79AD2B1FCC01E57F8135E8C0B22CD0630BFB0127FB5408C8EFC17A929896E", "82cf772ec3e84b00fc74f5df104efbfb2428554e9ce367d03aeade37827fa8e9cb6a08196115d948" }), new DRBGTestVector( new SHA1Digest(), new SHA1EntropyProvider().get(440), false, "2021222324", 80, new String[] { "B3BD05246CBA12A64735A4E3FDE599BC1BE30F439BD060208EEA7D71F9D123DF47B3CE069D98EDE6", "B5DADA380E2872DF935BCA55B882C8C9376902AB639765472B71ACEBE2EA8B1B6B49629CB67317E0" }) .setPersonalizationString("404142434445464748494A4B4C4D4E4F505152535455565758595A5B5C5D5E5F606162636465666768696A6B6C6D6E6F70717273747576"), new DRBGTestVector( new SHA1Digest(), new SHA1EntropyProvider().get(440), false, "2021222324", 80, new String[] { "C7AAAC583C6EF6300714C2CC5D06C148CFFB40449AD0BB26FAC0497B5C57E161E36681BCC930CE80", "6EBD2B7B5E0A2AD7A24B1BF9A1DBA47D43271719B9C37B7FE81BA94045A14A7CB514B446666EA5A7" }) .addAdditionalInput("606162636465666768696A6B6C6D6E6F707172737475767778797A7B7C7D7E7F808182838485868788898A8B8C8D8E8F90919293949596") .addAdditionalInput("A0A1A2A3A4A5A6A7A8A9AAABACADAEAFB0B1B2B3B4B5B6B7B8B9BABBBCBDBEBFC0C1C2C3C4C5C6C7C8C9CACBCCCDCECFD0D1D2D3D4D5D6"), new DRBGTestVector( new SHA1Digest(), new SHA1EntropyProvider().get(440), true, "2021222324", 80, new String[] { "FEC4597F06A3A8CC8529D59557B9E661053809C0BC0EFC282ABD87605CC90CBA9B8633DCB1DAE02E", "84ADD5E2D2041C01723A4DE4335B13EFDF16B0E51A0AD39BD15E862E644F31E4A2D7D843E57C5968" }), new DRBGTestVector( new SHA1Digest(), new SHA1EntropyProvider().get(440), true, "2021222324", 80, new String[] { "6C37FDD729AA40F80BC6AB08CA7CC649794F6998B57081E4220F22C5C283E2C91B8E305AB869C625", "CAF57DCFEA393B9236BF691FA456FEA7FDF1DF8361482CA54D5FA723F4C88B4FA504BF03277FA783" }) .setPersonalizationString("404142434445464748494A4B4C4D4E4F505152535455565758595A5B5C5D5E5F606162636465666768696A6B6C6D6E6F70717273747576"), new DRBGTestVector( new SHA1Digest(), new SHA1EntropyProvider().get(440), true, "2021222324", 80, new String[] { "A1BA8FA58BB5013F43F7B6ED52B4539FA16DC77957AEE815B9C07004C7E992EB8C7E591964AFEEA2", "84264A73A818C95C2F424B37D3CC990B046FB50C2DC64A164211889A010F2471A0912FFEA1BF0195" }) .addAdditionalInput("606162636465666768696A6B6C6D6E6F707172737475767778797A7B7C7D7E7F808182838485868788898A8B8C8D8E8F90919293949596") .addAdditionalInput("A0A1A2A3A4A5A6A7A8A9AAABACADAEAFB0B1B2B3B4B5B6B7B8B9BABBBCBDBEBFC0C1C2C3C4C5C6C7C8C9CACBCCCDCECFD0D1D2D3D4D5D6"), new DRBGTestVector( new SHA256Digest(), new SHA256EntropyProvider().get(440), false, "2021222324252627", 128, new String[] { "D67B8C1734F46FA3F763CF57C6F9F4F2" + "DC1089BD8BC1F6F023950BFC5617635208C8501238AD7A44" + "00DEFEE46C640B61AF77C2D1A3BFAA90EDE5D207406E5403", "8FDAEC20F8B421407059E3588920DA7E" + "DA9DCE3CF8274DFA1C59C108C1D0AA9B0FA38DA5C792037C" + "4D33CD070CA7CD0C5608DBA8B885654639DE2187B74CB263" }), new DRBGTestVector( new SHA256Digest(), new SHA256EntropyProvider().get(440), true, "2021222324252627", 128, new String[] { "FABD0AE25C69DC2EFDEFB7F20C5A31B5" + "7AC938AB771AA19BF8F5F1468F665C938C9A1A5DF0628A56" + "90F15A1AD8A613F31BBD65EEAD5457D5D26947F29FE91AA7", "6BD925B0E1C232EFD67CCD84F722E927" + "ECB46AB2B740014777AF14BA0BBF53A45BDBB62B3F7D0B9C" + "8EEAD057C0EC754EF8B53E60A1F434F05946A8B686AFBC7A" }), new DRBGTestVector( new SHA384Digest(), new SHA384EntropyProvider().get(888), false, "202122232425262728292A2B", 192, new String[]{ "03AB8BCE4D1DBBB636C5C5B7E1C58499FEB1C619CDD11D35" + "CD6CF6BB8F20EF27B6F5F9054FF900DB9EBF7BF30ED4DCBB" + "BC8D5B51C965EA226FFEE2CA5AB2EFD00754DC32F357BF7A" + "E42275E0F7704DC44E50A5220AD05AB698A22640AC634829", "B907E77144FD55A54E9BA1A6A0EED0AAC780020C41A15DD8" + "9A6C163830BA1D094E6A17100FF71EE30A96E1EE04D2A966" + "03832A4E404F1966C2B5F4CB61B9927E8D12AC1E1A24CF23" + "88C14E8EC96C35181EAEE32AAA46330DEAAFE5E7CE783C74"}) .setPersonalizationString( "404142434445464748494A4B4C4D4E" + "4F505152535455565758595A5B5C5D5E5F60616263646566" + "6768696A6B6C6D6E6F707172737475767778797A7B7C7D7E" + "7F808182838485868788898A8B8C8D8E8F90919293949596" + "9798999A9B9C9D9E9FA0A1A2A3A4A5A6A7A8A9AAABACADAE"), new DRBGTestVector( new SHA384Digest(), new SHA384EntropyProvider().get(888), true, "202122232425262728292A2B", 192, new String[]{ "804A3AD720F4FCE8738D0632514FEF16430CB7D63A8DF1A5" + "F02A3CE3BD7ED6A668B69E63E2BB93F096EE753D6194A0F1" + "A32711063653009636337D22167CC4402D019AC216FA574F" + "091CF6EA283568D737A77BE38E8F09382C69E76B142ABC3A", "73B8E55C753202176A17B9B9754A9FE6F23B01861FCD4059" + "6AEAA301AF1AEF8AF0EAF22FBF34541EFFAB1431666ACACC" + "759338C7E28672819D53CFEF10A3E19DAFBD53295F1980A9" + "F491504A2725506784B7AC826D92C838A8668171CAAA86E7"}) .setPersonalizationString( "404142434445464748494A4B4C4D4E" + "4F505152535455565758595A5B5C5D5E5F60616263646566" + "6768696A6B6C6D6E6F707172737475767778797A7B7C7D7E" + "7F808182838485868788898A8B8C8D8E8F90919293949596" + "9798999A9B9C9D9E9FA0A1A2A3A4A5A6A7A8A9AAABACADAE"), new DRBGTestVector( new SHA512Digest(), new SHA512EntropyProvider().get(888), false, "202122232425262728292A2B2C2D2E2F", 256, new String[]{ "2A5FF6520C20F66E" + "D5EA431BD4AEAC58F975EEC9A015137D5C94B73AA09CB8B5" + "9D611DDEECEB34A52BB999424009EB9EAC5353F92A6699D2" + "0A02164EEBBC6492941E10426323898465DFD731C7E04730" + "60A5AA8973841FDF3446FB6E72A58DA8BDA2A57A36F3DD98" + "6DF85C8A5C6FF31CDE660BF8A841B21DD6AA9D3AC356B87B", "0EDC8D7D7CEEC7FE" + "36333FB30C0A9A4B27AA0BECBF075568B006C1C3693B1C29" + "0F84769C213F98EB5880909EDF068FDA6BFC43503987BBBD" + "4FC23AFBE982FE4B4B007910CC4874EEC217405421C8D8A1" + "BA87EC684D0AF9A6101D9DB787AE82C3A6A25ED478DF1B12" + "212CEC325466F3AC7C48A56166DD0B119C8673A1A9D54F67"}) .setPersonalizationString( "404142434445464748494A4B4C4D4E" + "4F505152535455565758595A5B5C5D5E5F60616263646566" + "6768696A6B6C6D6E6F707172737475767778797A7B7C7D7E" + "7F808182838485868788898A8B8C8D8E8F90919293949596" + "9798999A9B9C9D9E9FA0A1A2A3A4A5A6A7A8A9AAABACADAE"), new DRBGTestVector( new SHA512Digest(), new SHA512EntropyProvider().get(888), true, "202122232425262728292A2B2C2D2E2F", 256, new String[]{ "AAE4DC3C9ECC74D9" + "061DD527117EF3D29E1E52B26853C539D6CA797E8DA3D0BB" + "171D8E30B8B194D8C28F7F6BE3B986B88506DC6A01B294A7" + "165DD1C3470F7BE7B396AA0DB7D50C4051E7C7E1C8A7D21A" + "2B5878C0BCB163CAA79366E7A1162FDC88429616CD3E6977" + "8D327520A6BBBF71D8AA2E03EC4A9DAA0E77CF93E1EE30D2 ", "129FF6D31A23FFBC" + "870632B35EE477C2280DDD2ECDABEDB900C78418BE2D243B" + "B9D8E5093ECE7B6BF48638D8F704D134ADDEB7F4E9D5C142" + "CD05683E72B516486AF24AEC15D61E81E270DD4EBED91B62" + "12EB8896A6250D5C8BC3A4A12F7E3068FBDF856F47EB23D3" + "79F82C1EBCD1585FB260B9C0C42625FBCEE68CAD773CD5B1"}) .setPersonalizationString( "404142434445464748494A4B4C4D4E" + "4F505152535455565758595A5B5C5D5E5F60616263646566" + "6768696A6B6C6D6E6F707172737475767778797A7B7C7D7E" + "7F808182838485868788898A8B8C8D8E8F90919293949596" + "9798999A9B9C9D9E9FA0A1A2A3A4A5A6A7A8A9AAABACADAE"), new DRBGTestVector( new SHA512Digest(), new SHA512EntropyProvider().get(888), false, "202122232425262728292A2B2C2D2E2F", 256, new String[]{ "7AE31A2DEC31075F" + "E5972660C16D22ECC0D415C5693001BE5A468B590BC1AE2C" + "43F647F8D681AEEA0D87B79B0B4E5D089CA2C9D327534234" + "0254E6B04690D77A71A294DA9568479EEF8BB2A2110F18B6" + "22F60F35235DE0E8F9D7E98105D84AA24AF0757AF005DFD5" + "2FA51DE3F44FCE0C5F3A27FCE8B0F6E4A3F7C7B53CE34A3D", "D83A8084630F286D" + "A4DB49B9F6F608C8993F7F1397EA0D6F4A72CF3EF2733A11" + "AB823C29F2EBDEC3EDE962F93D920A1DB59C84E1E879C29F" + "5F9995FC3A6A3AF9B587CA7C13EA197D423E81E1D6469942" + "B6E2CA83A97E91F6B298266AC148A1809776C26AF5E239A5" + "5A2BEB9E752203A694E1F3FE2B3E6A0C9C314421CDB55FBD "}) .setPersonalizationString( "404142434445464748494A4B4C4D4E" + "4F505152535455565758595A5B5C5D5E5F60616263646566" + "6768696A6B6C6D6E6F707172737475767778797A7B7C7D7E" + "7F808182838485868788898A8B8C8D8E8F90919293949596" + "9798999A9B9C9D9E9FA0A1A2A3A4A5A6A7A8A9AAABACADAE") .addAdditionalInput( "606162636465666768696A6B6C6D6E" + "6F707172737475767778797A7B7C7D7E7F80818283848586" + "8788898A8B8C8D8E8F909192939495969798999A9B9C9D9E" + "9FA0A1A2A3A4A5A6A7A8A9AAABACADAEAFB0B1B2B3B4B5B6" + "B7B8B9BABBBCBDBEBFC0C1C2C3C4C5C6C7C8C9CACBCCCDCE") .addAdditionalInput( "A0A1A2A3A4A5A6A7A8A9AAABACADAE" + "AFB0B1B2B3B4B5B6B7B8B9BABBBCBDBEBFC0C1C2C3C4C5C6" + "C7C8C9CACBCCCDCECFD0D1D2D3D4D5D6D7D8D9DADBDCDDDE" + "DFE0E1E2E3E4E5E6E7E8E9EAEBECEDEEEFF0F1F2F3F4F5F6" + "F7F8F9FAFBFCFDFEFF000102030405060708090A0B0C0D0E"), new DRBGTestVector( new SHA512Digest(), new SHA512EntropyProvider().get(888), true, "202122232425262728292A2B2C2D2E2F", 256, new String[]{ "28FD6060C4F35F4D" + "317AB2060EE32019E0DAA330F3F5650BBCA57CB67EE6AF1C" + "6F25D1B01F3601EDA85DC2ED29A9B2BA4C85CF491CE7185F" + "1A2BD9378AE3C655BD1CEC2EE108AE7FC382989F6D4FEA8A" + "B01499697C2F07945CE02C5ED617D04287FEAF3BA638A4CE" + "F3BB6B827E40AF16279580FCF1FDAD830930F7FDE341E2AF", "C0B1601AFE39338B" + "58DC2BE7C256AEBE3C21C5A939BEEC7E97B3528AC420F0C6" + "341847187666E0FF578A8EB0A37809F877365A28DF2FA0F0" + "6354A6F02496747369375B9A9D6B756FDC4A8FB308E08256" + "9D79A85BB960F747256626389A3B45B0ABE7ECBC39D5CD7B" + "2C18DF2E5FDE8C9B8D43474C54B6F9839468445929B438C7"}), new DRBGTestVector( new SHA512Digest(), new SHA512EntropyProvider().get(888), true, "202122232425262728292A2B2C2D2E2F", 256, new String[]{ "72691D2103FB567C" + "CD30370715B36666F63430087B1C688281CA0974DB456BDB" + "A7EB5C48CFF62EA05F9508F3B530CE995A272B11EC079C13" + "923EEF8E011A93C19B58CC6716BC7CB8BD886CAA60C14D85" + "C023348BD77738C475D6C7E1D9BFF4B12C43D8CC73F838DC" + "4F8BD476CF8328EEB71B3D873D6B7B859C9B21065638FF95", "8570DA3D47E1E160" + "5CF3E44B8D328B995EFC64107B6292D1B1036B5F88CE3160" + "2F12BEB71D801C0942E7C0864B3DB67A9356DB203490D881" + "24FE86BCE38AC2269B4FDA6ABAA884039DF80A0336A24D79" + "1EB3067C8F5F0CF0F18DD73B66A7B316FB19E02835CC6293" + "65FCD1D3BE640178ED9093B91B36E1D68135F2785BFF505C"}) .addAdditionalInput( "606162636465666768696A6B6C6D6E" + "6F707172737475767778797A7B7C7D7E7F80818283848586" + "8788898A8B8C8D8E8F909192939495969798999A9B9C9D9E" + "9FA0A1A2A3A4A5A6A7A8A9AAABACADAEAFB0B1B2B3B4B5B6" + "B7B8B9BABBBCBDBEBFC0C1C2C3C4C5C6C7C8C9CACBCCCDCE") .addAdditionalInput( "A0A1A2A3A4A5A6A7A8A9AAABACADAE" + "AFB0B1B2B3B4B5B6B7B8B9BABBBCBDBEBFC0C1C2C3C4C5C6" + "C7C8C9CACBCCCDCECFD0D1D2D3D4D5D6D7D8D9DADBDCDDDE" + "DFE0E1E2E3E4E5E6E7E8E9EAEBECEDEEEFF0F1F2F3F4F5F6" + "F7F8F9FAFBFCFDFEFF000102030405060708090A0B0C0D0E"), new DRBGTestVector( new SHA512Digest(), new SHA512EntropyProvider().get(888), true, "202122232425262728292A2B2C2D2E2F", 256, new String[]{ "AAE4DC3C9ECC74D9" + "061DD527117EF3D29E1E52B26853C539D6CA797E8DA3D0BB" + "171D8E30B8B194D8C28F7F6BE3B986B88506DC6A01B294A7" + "165DD1C3470F7BE7B396AA0DB7D50C4051E7C7E1C8A7D21A" + "2B5878C0BCB163CAA79366E7A1162FDC88429616CD3E6977" + "8D327520A6BBBF71D8AA2E03EC4A9DAA0E77CF93E1EE30D2 ", "129FF6D31A23FFBC" + "870632B35EE477C2280DDD2ECDABEDB900C78418BE2D243B" + "B9D8E5093ECE7B6BF48638D8F704D134ADDEB7F4E9D5C142" + "CD05683E72B516486AF24AEC15D61E81E270DD4EBED91B62" + "12EB8896A6250D5C8BC3A4A12F7E3068FBDF856F47EB23D3" + "79F82C1EBCD1585FB260B9C0C42625FBCEE68CAD773CD5B1"}) .setPersonalizationString( "404142434445464748494A4B4C4D4E" + "4F505152535455565758595A5B5C5D5E5F60616263646566" + "6768696A6B6C6D6E6F707172737475767778797A7B7C7D7E" + "7F808182838485868788898A8B8C8D8E8F90919293949596" + "9798999A9B9C9D9E9FA0A1A2A3A4A5A6A7A8A9AAABACADAE"), new DRBGTestVector( new SHA512Digest(), new SHA512EntropyProvider().get(888), true, "202122232425262728292A2B2C2D2E2F", 256, new String[]{ "B8E827652175E6E0" + "6E513C7BE94B5810C14ED94AD903647940CAEB7EE014C848" + "8DCBBE6D4D6616D06656A3DC707CDAC4F02EE6D8408C065F" + "CB068C0760DA47C5D60E5D70D09DC3929B6979615D117F7B" + "EDCC661A98514B3A1F55B2CBABDCA59F11823E4838065F1F" + "8431CBF28A577738234AF3F188C7190CC19739E72E9BBFFF", "7ED41B9CFDC8C256" + "83BBB4C553CC2DC61F690E62ABC9F038A16B8C519690CABE" + "BD1B5C196C57CF759BB9871BE0C163A57315EA96F615136D" + "064572F09F26D659D24211F9610FFCDFFDA8CE23FFA96735" + "7595182660877766035EED800B05364CE324A75EB63FD9B3" + "EED956D147480B1D0A42DF8AA990BB628666F6F61D60CBE2"}) .setPersonalizationString( "404142434445464748494A4B4C4D4E" + "4F505152535455565758595A5B5C5D5E5F60616263646566" + "6768696A6B6C6D6E6F707172737475767778797A7B7C7D7E" + "7F808182838485868788898A8B8C8D8E8F90919293949596" + "9798999A9B9C9D9E9FA0A1A2A3A4A5A6A7A8A9AAABACADAE") .addAdditionalInput( "606162636465666768696A6B6C6D6E" + "6F707172737475767778797A7B7C7D7E7F80818283848586" + "8788898A8B8C8D8E8F909192939495969798999A9B9C9D9E" + "9FA0A1A2A3A4A5A6A7A8A9AAABACADAEAFB0B1B2B3B4B5B6" + "B7B8B9BABBBCBDBEBFC0C1C2C3C4C5C6C7C8C9CACBCCCDCE") .addAdditionalInput( "A0A1A2A3A4A5A6A7A8A9AAABACADAE" + "AFB0B1B2B3B4B5B6B7B8B9BABBBCBDBEBFC0C1C2C3C4C5C6" + "C7C8C9CACBCCCDCECFD0D1D2D3D4D5D6D7D8D9DADBDCDDDE" + "DFE0E1E2E3E4E5E6E7E8E9EAEBECEDEEEFF0F1F2F3F4F5F6" + "F7F8F9FAFBFCFDFEFF000102030405060708090A0B0C0D0E") }; } public void performTest() throws Exception { DRBGTestVector[] tests = createTestVectorData(); for (int i = 0; i != tests.length; i++) { DRBGTestVector tv = tests[i]; byte[] nonce = tv.nonce(); byte[] personalisationString = tv.personalizationString(); SP80090DRBG d = new HMacSP800DRBG(new HMac(tv.getDigest()), tv.securityStrength(), tv.entropySource(), personalisationString, nonce); byte[] output = new byte[tv.expectedValue(0).length]; d.generate(output, tv.additionalInput(0), tv.predictionResistance()); byte[] expected = tv.expectedValue(0); if (!areEqual(expected, output)) { fail("Test #" + (i + 1) + ".1 failed, expected " + new String(Hex.encode(tv.expectedValue(0))) + " got " + new String(Hex.encode(output))); } output = new byte[tv.expectedValue(0).length]; d.generate(output, tv.additionalInput(1), tv.predictionResistance()); expected = tv.expectedValue(1); if (!areEqual(expected, output)) { fail("Test #" + (i + 1) + ".2 failed, expected " + new String(Hex.encode(tv.expectedValue(1))) + " got " + new String(Hex.encode(output))); } } // Exception tests // SP80090DRBG d; try { d = new HMacSP800DRBG(new HMac(new SHA256Digest()), 256, new SHA256EntropyProvider().get(128), null, null); fail("no exception thrown"); } catch (IllegalArgumentException e) { if (!e.getMessage().equals("Not enough entropy for security strength required")) { fail("Wrong exception", e); } } } private class SHA1EntropyProvider extends TestEntropySourceProvider { SHA1EntropyProvider() { super( Hex.decode( "000102030405060708090A0B0C0D0E0F101112131415161718191A1B1C1D1E1F202122232425262728292A2B2C2D2E2F30313233343536" + "808182838485868788898A8B8C8D8E8F909192939495969798999A9B9C9D9E9FA0A1A2A3A4A5A6A7A8A9AAABACADAEAFB0B1B2B3B4B5B6" + "C0C1C2C3C4C5C6C7C8C9CACBCCCDCECFD0D1D2D3D4D5D6D7D8D9DADBDCDDDEDFE0E1E2E3E4E5E6E7E8E9EAEBECEDEEEFF0F1F2F3F4F5F6"), true); } } private class SHA256EntropyProvider extends TestEntropySourceProvider { SHA256EntropyProvider() { super(Hex.decode( "00010203040506" + "0708090A0B0C0D0E0F101112131415161718191A1B1C1D1E" + "1F202122232425262728292A2B2C2D2E2F30313233343536" + "80818283848586" + "8788898A8B8C8D8E8F909192939495969798999A9B9C9D9E" + "9FA0A1A2A3A4A5A6A7A8A9AAABACADAEAFB0B1B2B3B4B5B6" + "C0C1C2C3C4C5C6" + "C7C8C9CACBCCCDCECFD0D1D2D3D4D5D6D7D8D9DADBDCDDDE" + "DFE0E1E2E3E4E5E6E7E8E9EAEBECEDEEEFF0F1F2F3F4F5F6"), true); } } private class SHA384EntropyProvider extends TestEntropySourceProvider { SHA384EntropyProvider() { super(Hex.decode( "000102030405060708090A0B0C0D0E0F101112131415161718191A1B1C1D1E1F20212223242526" + "2728292A2B2C2D2E2F303132333435363738393A3B3C3D3E3F404142434445464748494A4B4C4D4E4F50515253545556" + "5758595A5B5C5D5E5F606162636465666768696A6B6C6D6E" + "808182838485868788898A8B8C8D8E" + "8F909192939495969798999A9B9C9D9E9FA0A1A2A3A4A5A6" + "A7A8A9AAABACADAEAFB0B1B2B3B4B5B6B7B8B9BABBBCBDBE" + "BFC0C1C2C3C4C5C6C7C8C9CACBCCCDCECFD0D1D2D3D4D5D6" + "D7D8D9DADBDCDDDEDFE0E1E2E3E4E5E6E7E8E9EAEBECEDEE" + "C0C1C2C3C4C5C6C7C8C9CACBCCCDCE" + "CFD0D1D2D3D4D5D6D7D8D9DADBDCDDDEDFE0E1E2E3E4E5E6" + "E7E8E9EAEBECEDEEEFF0F1F2F3F4F5F6F7F8F9FAFBFCFDFE" + "FF000102030405060708090A0B0C0D0E0F10111213141516" + "1718191A1B1C1D1E1F202122232425262728292A2B2C2D2E"), true); } } private class SHA512EntropyProvider extends TestEntropySourceProvider { SHA512EntropyProvider() { super(Hex.decode( "000102030405060708090A0B0C0D0E" + "0F101112131415161718191A1B1C1D1E1F20212223242526" + "2728292A2B2C2D2E2F303132333435363738393A3B3C3D3E" + "3F404142434445464748494A4B4C4D4E4F50515253545556" + "5758595A5B5C5D5E5F606162636465666768696A6B6C6D6E" + "808182838485868788898A8B8C8D8E" + "8F909192939495969798999A9B9C9D9E9FA0A1A2A3A4A5A6" + "A7A8A9AAABACADAEAFB0B1B2B3B4B5B6B7B8B9BABBBCBDBE" + "BFC0C1C2C3C4C5C6C7C8C9CACBCCCDCECFD0D1D2D3D4D5D6" + "D7D8D9DADBDCDDDEDFE0E1E2E3E4E5E6E7E8E9EAEBECEDEE" + "C0C1C2C3C4C5C6C7C8C9CACBCCCDCE" + "CFD0D1D2D3D4D5D6D7D8D9DADBDCDDDEDFE0E1E2E3E4E5E6" + "E7E8E9EAEBECEDEEEFF0F1F2F3F4F5F6F7F8F9FAFBFCFDFE" + "FF000102030405060708090A0B0C0D0E0F10111213141516" + "1718191A1B1C1D1E1F202122232425262728292A2B2C2D2E"), true); } } } bouncycastle-1.49.orig/test/src/org/bouncycastle/crypto/prng/test/TestEntropySourceProvider.java0000644000175000017500000000216212151552117032766 0ustar ebourgebourgpackage org.bouncycastle.crypto.prng.test; import org.bouncycastle.crypto.prng.EntropySource; import org.bouncycastle.crypto.prng.EntropySourceProvider; public class TestEntropySourceProvider implements EntropySourceProvider { private final byte[] data; private final boolean isPredictionResistant; protected TestEntropySourceProvider(byte[] data, boolean isPredictionResistant) { this.data = data; this.isPredictionResistant = isPredictionResistant; } public EntropySource get(final int bitsRequired) { return new EntropySource() { int index = 0; public boolean isPredictionResistant() { return isPredictionResistant; } public byte[] getEntropy() { byte[] rv = new byte[bitsRequired / 8]; System.arraycopy(data, index, rv, 0, rv.length); index += bitsRequired / 8; return rv; } public int entropySize() { return bitsRequired; } }; } } bouncycastle-1.49.orig/test/src/org/bouncycastle/crypto/prng/test/DualECDRBGTest.java0000644000175000017500000004342112143337407030175 0ustar ebourgebourgpackage org.bouncycastle.crypto.prng.test; import org.bouncycastle.crypto.digests.SHA1Digest; import org.bouncycastle.crypto.digests.SHA256Digest; import org.bouncycastle.crypto.digests.SHA384Digest; import org.bouncycastle.crypto.digests.SHA512Digest; import org.bouncycastle.crypto.prng.drbg.DualECSP800DRBG; import org.bouncycastle.crypto.prng.drbg.SP80090DRBG; import org.bouncycastle.util.encoders.Hex; import org.bouncycastle.util.test.SimpleTest; /** * Dual EC SP800-90 DRBG test */ public class DualECDRBGTest extends SimpleTest { public String getName() { return "DualECDRBG"; } public static void main(String[] args) { runTest(new DualECDRBGTest()); } private DRBGTestVector[] createTestVectorData() { return new DRBGTestVector[] { new DRBGTestVector( new SHA256Digest(), new SHA256EntropyProvider().get(128), false, "2021222324252627", 128, new String[] { "FF5163C388F791E96F1052D5C8F0BD6FBF7144839C4890FF85487C5C12702E4C9849AF518AE68DEB14D3A62702BBDE4B98AB211765FD87ACA12FC2A6", "9A0A11F2DFB88F7260559DD8DA6134EB2B34CC0415FA8FD0474DB6B85E1A08385F41B435DF81296B1B4EDF66E0107C0844E3D28A89B05046B89177F2" }), new DRBGTestVector( new SHA256Digest(), new SHA256EntropyProvider().get(128), false, "2021222324252627", 128, new String[] { "C08E954FCD486D0B0934A0236692AC705A835D1A3C94D2ACD4684AB26E978D7D42E73CC06D6EC1472C63E51BED7F71518395836E2052BBD73A20CABB", "1D76DEE36FCC5F9478C112EAFA1C4CCD0635435A6F3A247A3BA3849790B5245070E95C1A67BE7A39BFB213F2C0EFCC171A3253DA6D54DA4362EA2099" }) .addAdditionalInput("606162636465666768696A6B6C6D6E6F") .addAdditionalInput("A0A1A2A3A4A5A6A7A8A9AAABACADAEAF"), new DRBGTestVector( new SHA256Digest(), new SHA256EntropyProvider().get(128), false, "2021222324252627", 128, new String[] { "3AB095CC493A8730D70DE923108B2E4710799044FFC27D0A1156250DDF97E8B05ACE055E49F3E3F5B928CCD18317A3E68FCB0B6F0459ADF9ECF79C87", "7B902FC35B0AF50F57F8822936D08A96E41B16967C6B1AA0BC05032F0D53919DC587B664C883E2FE8F3948002FCD8BCBFC4706BCAA2075EF6BF41167" }) .setPersonalizationString("404142434445464748494A4B4C4D4E4F"), new DRBGTestVector( new SHA256Digest(), new SHA256EntropyProvider().get(128), false, "2021222324252627", 128, new String[] { "3B68A1D95ED0312150AC1991189780F37EC50E75249F915CD806BBA0C44F9E3A919B2390805E1E90C1D2D1C823B17B96DB44535B72E0CFB62723529D", "250B933475E3BD4FC85D97FD797834B599DEDEDF8B6F15474E1F31B4AF215CFA7A8C0A0296A2E374B3886BB0CC7E49DBB19324564B451E64F12864F9" }) .setPersonalizationString("404142434445464748494A4B4C4D4E4F") .addAdditionalInput("606162636465666768696A6B6C6D6E6F") .addAdditionalInput("A0A1A2A3A4A5A6A7A8A9AAABACADAEAF"), new DRBGTestVector( new SHA256Digest(), new SHA256EntropyProvider().get(128), true, "2021222324252627", 128, new String[] { "8C77288EDBEA9A742464F78D55E33593C1BF5F9D8CD8609D6D53BAC4E4B42252A227A99BAD0F2358B05955CD35723B549401C71C9C1F32F8A2018E24", "56ECA61C64F69C1C232E992623C71418BD0B96D783118FAAD94A09E3A9DB74D15E805BA7F14625995CA77612B2EF7A05863699ECBABF70D3D422C014" }), new DRBGTestVector( new SHA256Digest(), new SHA256EntropyProvider().get(128), true, "2021222324252627", 128, new String[] { "A5C397DFEB540E86F0470E9625D5C5AC2D50016FB201E8DF574F2201DFBB42A799FEB9E238AAD301A493382250EEE60D2E2927E500E848E57535ABD1", "BF9894630BEBAF0A0EDFE726285EB055FD2ED678B76673803DD327F49DBEDE87D3E447A6EB73B5D5C52A40078132677F412E9E7DE32B9B1CB32421B9" }) .addAdditionalInput("606162636465666768696A6B6C6D6E6F") .addAdditionalInput("A0A1A2A3A4A5A6A7A8A9AAABACADAEAF"), new DRBGTestVector( new SHA384Digest(), new SHA384EntropyProvider().get(192), false, "202122232425262728292A2B", 192, new String[] { "1F858858B65357D6360E1ED8F8475767B08DAB30718CCA01C6FAE77A4BDCE2702C76D0FB4758EA1ED6AA587CFD26B9011DC8A75D0B4154193BB2C1798FFA52BCAB208310" + "3CD2AAD44BEED56D042FC2B8915D7D9BED6437EFEB1582EE", "6E4AAB63938212C870F24BB067A32CA9E7FC2343" + "5D411729268C8BA6F90E87074D04888CE2CC5A916B7AC93F" + "EDE85E2995645DFCC4CE44B9FB41F1BFCC5E9F59EE3A8E1B" + "8F85247F741B7C480521EE6BF8BA319B59048E65F08FAA76" }), new DRBGTestVector( new SHA384Digest(), new SHA384EntropyProvider().get(192), false, "202122232425262728292A2B", 192, new String[] { "E6A30AB0C9AFCBA673E4F1C94B3DB1F0C7D78B3D" + "87B967281BE1E7B3CAF5200AED502C26B84FC169FE8336BD" + "23271CB299812F2CF1955AA63FC362044ABA246EF1610F9E" + "DC613924A84A00F8DB3FC65C13373F3171EB20848FA9A70E", "8585764DF1C86EA12ACCB882525BF6217B447486" + "5EBFDA367B8657FA80471139BAC626172B9F219DF2CE9099" + "F65833E07CD1A8DD80468779EA3C26620A2C9C9F5C7EFCDD" + "C036E6F6C8BF70316D3C37FC246A4CC79B3F1DB971D72ED0" }) .setPersonalizationString("404142434445464748494A4B4C4D4E4F5051525354555657"), new DRBGTestVector( new SHA384Digest(), new SHA384EntropyProvider().get(192), false, "202122232425262728292A2B", 192, new String[] { "13F6EA9BBA7BABDC2A52A3B9FD73D65ECAA638A0" + "4C74BCCA2ACDE6FD29FEA4B5D884E095E87D1B7C0DEB9D37" + "7AD81FBFEEA2D5EF82C0F6F52B9FCC359E769AC9DF2A876C" + "58BAF21657814F3E66D1680B1D4EBD65581E42534F85197D", "FC0A36F4D20F8F83BE3430AA3C36A49191821A82" + "072BBC3D5AFF8D7EC39484D646277CE87599B6FE8CCA9862" + "559703A10F4DE1066BFD30B80C325E774B512525BC6D3734" + "4C93906368243D31F89E99C4D2A6E9BEB24D5F7267360DCA" }) .setPersonalizationString("404142434445464748494A4B4C4D4E4F5051525354555657") .addAdditionalInput("606162636465666768696A6B6C6D6E6F7071727374757677") .addAdditionalInput("A0A1A2A3A4A5A6A7A8A9AAABACADAEAFB0B1B2B3B4B5B6B7"), new DRBGTestVector( new SHA384Digest(), new SHA384EntropyProvider().get(192), true, "202122232425262728292A2B", 192, new String[] { "FE55601BF734493013705CCEB76E44AAD48373F7" + "42E72B83D4701FA6549255F1CDE6217953522FF973BA4F6E" + "C96D2BDCF14A76BE7DEB61781E34B99335BD714F17C91739" + "B4E2AB57E36E9C3116E215D3D94FCFAD532636874875CAC7", "F5E59D0ABADE81F62FFAB9D4A6A26FF200016608" + "A7215E389858FFED83FBC75CFD33DBA6688C89AA32AD22E4" + "80EA3D04EADFB35567B67564207E64B77844E8E4A87502D5" + "02DBBB6D8277F1CACDB7CF8D293D09DB7DD59A950821507A" }) .addAdditionalInput("606162636465666768696A6B6C6D6E6F7071727374757677") .addAdditionalInput("A0A1A2A3A4A5A6A7A8A9AAABACADAEAFB0B1B2B3B4B5B6B7"), new DRBGTestVector( new SHA384Digest(), new SHA384EntropyProvider().get(192), true, "202122232425262728292A2B", 192, new String[] { "CC788F70FB08F256D9604333630D85936D400F45" + "718DC3F939A8B9F6F75D3E4EC17D68FBB924AEACB7021295" + "48FA63CE9BCB82176639B64DE890A47025B5582312FE934E" + "F0D0A12697C0F05D2DA108CCADB511BA0EB62F4051BB2354", "2C922EA620D76E4137B315EBC29E518F80951B3F" + "0E6173FA2BFD94A230EE513EE2E4EB330D802F620DD24911" + "534EC0F95A1F1D44A2125F5D57476A666FC372092B55D0D6" + "8B49738F5BC466EC206AB3CF6A972B38BCFAE5FCD53C7E21 " }), new DRBGTestVector( new SHA512Digest(), new SHA512EntropyProvider().get(256), false, "202122232425262728292A2B2C2D2E2F", 256, new String[] { "7A8313798EE1" + "D1898712683F2D0B0DEE5804146ABA64FDA8DB4E539CC8D1" + "E59C74EE5AA48E73E958C8EC85DD529D42E68B4F7E02FFAF" + "3E3EF8312AEA68BC08A414885E60A7DF0B55F9D90210B319" + "E9B8FD23E078A4153636F29AA3CAC8198CB1D5D846151653" + "ECE275A591089261238014E5058410065AB8229EB9115E8E", "918B5D79E646" + "64966D954BC5E2946BF48F061BF0C2701C3C2D1F75EA821E" + "1DA05D5B3C2C4EEA246E806B53BF6BDB3F3D53A3AE756C2A" + "45C72603973A3DE1BC367C283CA124A5589CEAB30E5D2D74" + "8A40DD874FF15B032CF4F4B2AAD590B0DB91A0D38FCE93C5" + "AAD4E55AC482F86FF06FAE66B7C7CCA7E45557E1A5A3B85D" }), new DRBGTestVector( new SHA512Digest(), new SHA512EntropyProvider().get(256), true, "202122232425262728292A2B2C2D2E2F", 256, new String[] { "C7ED88A2C690" + "1C04802BA2BB04262921B19664835A4A3C002CB9F13E35E3" + "DEB3698A436BF1C85B070E9E6977CA78A5130905AA0C01A9" + "4130F5133DF904A4ACF59A7DD01227E8FCA1C8D51F093839" + "46ECD950113104760D7E216CAF581FE9D3AACE6FC4CDDC4C" + "CD736D26A60BE8BE2A6A78CD752D1EC7CCC802638B177307", "83B78B206785" + "4412EEB24AEA86064D510C68FD96DBF94EAC1BC2022752D7" + "558AEB9F97B9CBC1B9648FE4D88E2C82A6F530675E1DB92D" + "396D6D85BDAD2A23CBD10AD808ECCCFBFC811EB68AE835E4" + "912E011DD10A4399C8DE2D9D88F81B6168B05D282B9DAC1E" + "65E0A45F61043E1FA047870DD582295E6C50DD1185B13594 " }) .setPersonalizationString("404142434445464748494A4B4C4D4E4F505152535455565758595A5B5C5D5E5F") .addAdditionalInput("606162636465666768696A6B6C6D6E6F707172737475767778797A7B7C7D7E7F") .addAdditionalInput("A0A1A2A3A4A5A6A7A8A9AAABACADAEAFB0B1B2B3B4B5B6B7B8B9BABBBCBDBEBF"), new DRBGTestVector( new SHA512Digest(), new SHA512EntropyProvider().get(256), true, "202122232425262728292A2B2C2D2E2F", 256, new String[] { "CC7035C73040" + "5CF5DF7137ED9E10744B75B540AFFC68EB564B71C0F737E8" + "F656B6171940497FA90D8F383EFB6FC6717BA14AAA164EF5" + "6641C0F513312551DCD21D0A5B0DBDCD97F627E968DFD752" + "56C11CF2BCCA5822EAACE796A34CB7D2F8CD8CC6DBE76274" + "498289BBC4C2F1CADA6185D82605CF992EC285BC4945EE9E", "0E6C329AD1BE" + "681EB1E6F5E03A89E3D80153D6CCDD5A3ECF865003EE4A2D" + "E5A23B7F43681361CFAFC3A3FEF17777E75CF9D6685573C8" + "87A3962CB955076D45D6F1E45EE4B8CB31A4731CDA031FA2" + "815B6D34E29F2603526CE186576F4CCA3FEDF7F8ACDB37C9" + "9D762706ABE4967D44739C8CFCFCC76C58B1ED243AC394C0" }) }; } public void performTest() throws Exception { DRBGTestVector[] tests = createTestVectorData(); for (int i = 0; i != tests.length; i++) { DRBGTestVector tv = tests[i]; byte[] nonce = tv.nonce(); byte[] personalisationString = tv.personalizationString(); SP80090DRBG d = new DualECSP800DRBG(tv.getDigest(), tv.securityStrength(), tv.entropySource(), personalisationString, nonce); byte[] output = new byte[tv.expectedValue(0).length]; d.generate(output, tv.additionalInput(0), tv.predictionResistance()); byte[] expected = tv.expectedValue(0); if (!areEqual(expected, output)) { fail("Test #" + (i + 1) + ".1 failed, expected " + new String(Hex.encode(tv.expectedValue(0))) + " got " + new String(Hex.encode(output))); } output = new byte[tv.expectedValue(1).length]; d.generate(output, tv.additionalInput(1), tv.predictionResistance()); expected = tv.expectedValue(1); if (!areEqual(expected, output)) { fail("Test #" + (i + 1) + ".2 failed, expected " + new String(Hex.encode(tv.expectedValue(1))) + " got " + new String(Hex.encode(output))); } } // Exception tests // SP80090DRBG d; try { d = new DualECSP800DRBG(new SHA256Digest(), 256, new SHA256EntropyProvider().get(128), null, null); fail("no exception thrown"); } catch (IllegalArgumentException e) { if (!e.getMessage().equals("EntropySource must provide between 256 and 4096 bits")) { fail("Wrong exception", e); } } try { d = new DualECSP800DRBG(new SHA256Digest(), 256, new SHA256EntropyProvider().get(1 << (13 - 1) + 1), null, null); fail("no exception thrown"); } catch (IllegalArgumentException e) { if (!e.getMessage().equals("EntropySource must provide between 256 and 4096 bits")) { fail("Wrong exception", e); } } try { d = new DualECSP800DRBG(new SHA1Digest(), 256, new SHA256EntropyProvider().get(256), null, null); fail("no exception thrown"); } catch (IllegalArgumentException e) { if (!e.getMessage().equals("Requested security strength is not supported by digest")) { fail("Wrong exception", e); } } } private class SHA256EntropyProvider extends TestEntropySourceProvider { SHA256EntropyProvider() { super(Hex.decode( "000102030405060708090A0B0C0D0E0F " + "808182838485868788898A8B8C8D8E8F" + "C0C1C2C3C4C5C6C7C8C9CACBCCCDCECF"), true); } } private class SHA384EntropyProvider extends TestEntropySourceProvider { SHA384EntropyProvider() { super(Hex.decode( "000102030405060708090A0B0C0D0E0F1011121314151617" + "808182838485868788898A8B8C8D8E8F9091929394959697" + "C0C1C2C3C4C5C6C7C8C9CACBCCCDCECFD0D1D2D3D4D5D6D7"), true); } } private class SHA512EntropyProvider extends TestEntropySourceProvider { SHA512EntropyProvider() { super(Hex.decode( "000102030405060708090A0B0C0D0E0F101112131415161718191A1B1C1D1E1F" + "808182838485868788898A8B8C8D8E8F909192939495969798999A9B9C9D9E9F" + "C0C1C2C3C4C5C6C7C8C9CACBCCCDCECFD0D1D2D3D4D5D6D7D8D9DADBDCDDDEDF"), true); } } } bouncycastle-1.49.orig/test/src/org/bouncycastle/crypto/prng/test/AllTests.java0000644000175000017500000000165212143336411027326 0ustar ebourgebourgpackage org.bouncycastle.crypto.prng.test; import junit.framework.Test; import junit.framework.TestCase; import junit.framework.TestSuite; import org.bouncycastle.util.test.SimpleTestResult; public class AllTests extends TestCase { public void testCrypto() { org.bouncycastle.util.test.Test[] tests = RegressionTest.tests; for (int i = 0; i != tests.length; i++) { SimpleTestResult result = (SimpleTestResult)tests[i].perform(); if (!result.isSuccessful()) { fail(result.toString()); } } } public static void main (String[] args) { junit.textui.TestRunner.run(suite()); } public static Test suite() { TestSuite suite = new TestSuite("Lightweight Crypto PRNG Tests"); suite.addTestSuite(AllTests.class); return suite; } } bouncycastle-1.49.orig/test/src/org/bouncycastle/crypto/prng/test/DRBGTestVector.java0000644000175000017500000000620412143336411030332 0ustar ebourgebourgpackage org.bouncycastle.crypto.prng.test; import java.util.ArrayList; import java.util.List; import org.bouncycastle.crypto.BlockCipher; import org.bouncycastle.crypto.Digest; import org.bouncycastle.crypto.prng.EntropySource; import org.bouncycastle.util.encoders.Hex; public class DRBGTestVector { private Digest _digest; private BlockCipher _cipher; private int _keySizeInBits; private EntropySource _eSource; private boolean _pr; private String _nonce; private String _personalisation; private int _ss; private String[] _ev; private List _ai = new ArrayList(); public DRBGTestVector(Digest digest, EntropySource eSource, boolean predictionResistance, String nonce, int securityStrength, String[] expected) { _digest = digest; _eSource = eSource; _pr = predictionResistance; _nonce = nonce; _ss = securityStrength; _ev = expected; _personalisation = null; } public DRBGTestVector(BlockCipher cipher, int keySizeInBits, EntropySource eSource, boolean predictionResistance, String nonce, int securityStrength, String[] expected) { _cipher = cipher; _keySizeInBits = keySizeInBits; _eSource = eSource; _pr = predictionResistance; _nonce = nonce; _ss = securityStrength; _ev = expected; _personalisation = null; } public Digest getDigest() { return _digest; } public BlockCipher getCipher() { return _cipher; } public int keySizeInBits() { return _keySizeInBits; } public DRBGTestVector addAdditionalInput(String input) { _ai.add(input); return this; } public DRBGTestVector setPersonalizationString(String p) { _personalisation = p; return this; } public EntropySource entropySource() { return _eSource; } public boolean predictionResistance() { return _pr; } public byte[] nonce() { if (_nonce == null) { return null; } return Hex.decode(_nonce); } public byte[] personalizationString() { if (_personalisation == null) { return null; } return Hex.decode(_personalisation); } public int securityStrength() { return _ss; } public byte[] expectedValue(int index) { return Hex.decode(_ev[index]); } public byte[] additionalInput(int position) { int len = _ai.size(); byte[] rv; if (position >= len) { rv = null; } else { rv = Hex.decode((String)(_ai.get(position))); } return rv; } } bouncycastle-1.49.orig/test/src/org/bouncycastle/crypto/prng/test/SP800RandomTest.java0000644000175000017500000002737012143337351030357 0ustar ebourgebourgpackage org.bouncycastle.crypto.prng.test; import java.security.SecureRandom; import org.bouncycastle.crypto.digests.SHA1Digest; import org.bouncycastle.crypto.digests.SHA256Digest; import org.bouncycastle.crypto.engines.DESedeEngine; import org.bouncycastle.crypto.macs.HMac; import org.bouncycastle.crypto.prng.SP800SecureRandomBuilder; import org.bouncycastle.util.Arrays; import org.bouncycastle.util.encoders.Hex; import org.bouncycastle.util.test.SimpleTest; public class SP800RandomTest extends SimpleTest { public String getName() { return "SP800RandomTest"; } private void testHashRandom() { DRBGTestVector tv = new DRBGTestVector( new SHA1Digest(), new SHA1EntropyProvider().get(440), true, "2021222324", 80, new String[] { "532CA1165DCFF21C55592687639884AF4BC4B057DF8F41DE653AB44E2ADEC7C9303E75ABE277EDBF", "73C2C67C696D686D0C4DBCEB5C2AF7DDF6F020B6874FAE4390F102117ECAAFF54418529A367005A0" }) .setPersonalizationString("404142434445464748494A4B4C4D4E4F505152535455565758595A5B5C5D5E5F606162636465666768696A6B6C6D6E6F70717273747576"); doHashTest(0, tv); tv = new DRBGTestVector( new SHA1Digest(), new SHA1EntropyProvider().get(440), false, "2021222324", 80, new String[] { "AB438BD3B01A0AF85CFEE29F7D7B71621C4908B909124D430E7B406FB1086EA994C582E0D656D989", "29D9098F987E7005314A0F51B3DD2B8122F4AED706735DE6AD5DDBF223177C1E5F3AEBC52FAB90B9" }) .setPersonalizationString("404142434445464748494A4B4C4D4E4F505152535455565758595A5B5C5D5E5F606162636465666768696A6B6C6D6E6F70717273747576"); doHashTest(1, tv); } private void doHashTest(int index, DRBGTestVector tv) { SP800SecureRandomBuilder rBuild = new SP800SecureRandomBuilder(new SHA1EntropyProvider()); rBuild.setPersonalizationString(tv.personalizationString()); rBuild.setSecurityStrength(tv.securityStrength()); rBuild.setEntropyBitsRequired(tv.entropySource().getEntropy().length * 8); SecureRandom random = rBuild.buildHash(tv.getDigest(), tv.nonce(), tv.predictionResistance()); byte[] expected = tv.expectedValue(0); byte[] produced = new byte[expected.length]; random.nextBytes(produced); if (!Arrays.areEqual(expected, produced)) { fail(index + " SP800 Hash SecureRandom produced incorrect result (1)"); } random.nextBytes(produced); expected = tv.expectedValue(1); if (!Arrays.areEqual(expected, produced)) { fail(index + " SP800 Hash SecureRandom produced incorrect result (2)"); } } private void testHMACRandom() { DRBGTestVector tv = new DRBGTestVector( new SHA1Digest(), new SHA1EntropyProvider().get(440), true, "2021222324", 80, new String[] { "6C37FDD729AA40F80BC6AB08CA7CC649794F6998B57081E4220F22C5C283E2C91B8E305AB869C625", "CAF57DCFEA393B9236BF691FA456FEA7FDF1DF8361482CA54D5FA723F4C88B4FA504BF03277FA783" }) .setPersonalizationString("404142434445464748494A4B4C4D4E4F505152535455565758595A5B5C5D5E5F606162636465666768696A6B6C6D6E6F70717273747576"); doHMACTest(tv); tv = new DRBGTestVector( new SHA1Digest(), new SHA1EntropyProvider().get(440), false, "2021222324", 80, new String[] { "5A7D3B449F481CB38DF79AD2B1FCC01E57F8135E8C0B22CD0630BFB0127FB5408C8EFC17A929896E", "82cf772ec3e84b00fc74f5df104efbfb2428554e9ce367d03aeade37827fa8e9cb6a08196115d948" }); doHMACTest(tv); } private void doHMACTest(DRBGTestVector tv) { SP800SecureRandomBuilder rBuild = new SP800SecureRandomBuilder(new SHA1EntropyProvider()); rBuild.setPersonalizationString(tv.personalizationString()); rBuild.setSecurityStrength(tv.securityStrength()); rBuild.setEntropyBitsRequired(tv.entropySource().getEntropy().length * 8); SecureRandom random = rBuild.buildHMAC(new HMac(tv.getDigest()), tv.nonce(), tv.predictionResistance()); byte[] expected = tv.expectedValue(0); byte[] produced = new byte[expected.length]; random.nextBytes(produced); if (!Arrays.areEqual(expected, produced)) { fail("SP800 HMAC SecureRandom produced incorrect result (1)"); } random.nextBytes(produced); expected = tv.expectedValue(1); if (!Arrays.areEqual(expected, produced)) { fail("SP800 HMAC SecureRandom produced incorrect result (2)"); } } private void testDualECRandom() { DRBGTestVector tv = new DRBGTestVector( new SHA256Digest(), new SHA256EntropyProvider().get(128), false, "2021222324252627", 128, new String[] { "3AB095CC493A8730D70DE923108B2E4710799044FFC27D0A1156250DDF97E8B05ACE055E49F3E3F5B928CCD18317A3E68FCB0B6F0459ADF9ECF79C87", "7B902FC35B0AF50F57F8822936D08A96E41B16967C6B1AA0BC05032F0D53919DC587B664C883E2FE8F3948002FCD8BCBFC4706BCAA2075EF6BF41167" }) .setPersonalizationString("404142434445464748494A4B4C4D4E4F"); doDualECTest(1, tv); tv = new DRBGTestVector( new SHA256Digest(), new SHA256EntropyProvider().get(128), true, "2021222324252627", 128, new String[] { "8C77288EDBEA9A742464F78D55E33593C1BF5F9D8CD8609D6D53BAC4E4B42252A227A99BAD0F2358B05955CD35723B549401C71C9C1F32F8A2018E24", "56ECA61C64F69C1C232E992623C71418BD0B96D783118FAAD94A09E3A9DB74D15E805BA7F14625995CA77612B2EF7A05863699ECBABF70D3D422C014" }); doDualECTest(2, tv); } private void doDualECTest(int index, DRBGTestVector tv) { SP800SecureRandomBuilder rBuild = new SP800SecureRandomBuilder(new SHA256EntropyProvider()); rBuild.setPersonalizationString(tv.personalizationString()); rBuild.setSecurityStrength(tv.securityStrength()); rBuild.setEntropyBitsRequired(tv.securityStrength()); SecureRandom random = rBuild.buildDualEC(tv.getDigest(), tv.nonce(), tv.predictionResistance()); byte[] expected = tv.expectedValue(0); byte[] produced = new byte[expected.length]; random.nextBytes(produced); if (!Arrays.areEqual(expected, produced)) { fail(index + " SP800 Dual EC SecureRandom produced incorrect result (1)"); } random.nextBytes(produced); expected = tv.expectedValue(1); if (!Arrays.areEqual(expected, produced)) { fail(index + " SP800 Dual EC SecureRandom produced incorrect result (2)"); } } private void testCTRRandom() { DRBGTestVector tv = new DRBGTestVector( new DESedeEngine(), 168, new Bit232EntropyProvider().get(232), false, "20212223242526", 112, new String[] { "ABC88224514D0316EA3D48AEE3C9A2B4", "D3D3F372E43E7ABDC4FA293743EED076" } ); doCTRTest(tv); tv = new DRBGTestVector( new DESedeEngine(), 168, new Bit232EntropyProvider().get(232), true, "20212223242526", 112, new String[] { "64983055D014550B39DE699E43130B64", "035FDDA8582A2214EC722C410A8D95D3" } ) .setPersonalizationString("404142434445464748494A4B4C4D4E4F505152535455565758595A5B5C"); doCTRTest(tv); } private void doCTRTest(DRBGTestVector tv) { SP800SecureRandomBuilder rBuild = new SP800SecureRandomBuilder(new Bit232EntropyProvider()); rBuild.setPersonalizationString(tv.personalizationString()); rBuild.setSecurityStrength(tv.securityStrength()); rBuild.setEntropyBitsRequired(tv.entropySource().getEntropy().length * 8); SecureRandom random = rBuild.buildCTR(tv.getCipher(), tv.keySizeInBits(), tv.nonce(), tv.predictionResistance()); byte[] expected = tv.expectedValue(0); byte[] produced = new byte[expected.length]; random.nextBytes(produced); if (!Arrays.areEqual(expected, produced)) { fail("SP800 CTR SecureRandom produced incorrect result (1)"); } random.nextBytes(produced); expected = tv.expectedValue(1); if (!Arrays.areEqual(expected, produced)) { fail("SP800 CTR SecureRandom produced incorrect result (2)"); } } public void performTest() throws Exception { testHashRandom(); testHMACRandom(); testCTRRandom(); testDualECRandom(); } public static void main(String[] args) { runTest(new SP800RandomTest()); } // for HMAC/Hash private class SHA1EntropyProvider extends TestEntropySourceProvider { SHA1EntropyProvider() { super( Hex.decode( "000102030405060708090A0B0C0D0E0F101112131415161718191A1B1C1D1E1F202122232425262728292A2B2C2D2E2F30313233343536" + "808182838485868788898A8B8C8D8E8F909192939495969798999A9B9C9D9E9FA0A1A2A3A4A5A6A7A8A9AAABACADAEAFB0B1B2B3B4B5B6" + "C0C1C2C3C4C5C6C7C8C9CACBCCCDCECFD0D1D2D3D4D5D6D7D8D9DADBDCDDDEDFE0E1E2E3E4E5E6E7E8E9EAEBECEDEEEFF0F1F2F3F4F5F6"), true); } } // for Dual EC private class SHA256EntropyProvider extends TestEntropySourceProvider { SHA256EntropyProvider() { super(Hex.decode( "000102030405060708090A0B0C0D0E0F " + "808182838485868788898A8B8C8D8E8F" + "C0C1C2C3C4C5C6C7C8C9CACBCCCDCECF"), true); } } private class Bit232EntropyProvider extends TestEntropySourceProvider { Bit232EntropyProvider() { super(Hex.decode( "000102030405060708090A0B0C0D0E0F101112131415161718191A1B1C" + "808182838485868788898A8B8C8D8E8F909192939495969798999A9B9C" + "C0C1C2C3C4C5C6C7C8C9CACBCCCDCECFD0D1D2D3D4D5D6D7D8D9DADBDC"), true); } } } bouncycastle-1.49.orig/test/src/org/bouncycastle/crypto/prng/test/RegressionTest.java0000644000175000017500000000134312143336411030550 0ustar ebourgebourgpackage org.bouncycastle.crypto.prng.test; import org.bouncycastle.util.test.Test; import org.bouncycastle.util.test.TestResult; public class RegressionTest { public static Test[] tests = { new CTRDRBGTest(), new DualECDRBGTest(), new HashDRBGTest(), new HMacDRBGTest(), new SP800RandomTest() }; public static void main( String[] args) { for (int i = 0; i != tests.length; i++) { TestResult result = tests[i].perform(); if (result.getException() != null) { result.getException().printStackTrace(); } System.out.println(result); } } } bouncycastle-1.49.orig/test/src/org/bouncycastle/crypto/prng/test/CTRDRBGTest.java0000644000175000017500000005453012143641051027524 0ustar ebourgebourgpackage org.bouncycastle.crypto.prng.test; import org.bouncycastle.crypto.BlockCipher; import org.bouncycastle.crypto.CipherParameters; import org.bouncycastle.crypto.DataLengthException; import org.bouncycastle.crypto.engines.AESEngine; import org.bouncycastle.crypto.engines.AESFastEngine; import org.bouncycastle.crypto.engines.DESedeEngine; import org.bouncycastle.crypto.params.DESedeParameters; import org.bouncycastle.crypto.params.KeyParameter; import org.bouncycastle.crypto.prng.drbg.CTRSP800DRBG; import org.bouncycastle.crypto.prng.drbg.SP80090DRBG; import org.bouncycastle.util.Arrays; import org.bouncycastle.util.encoders.Hex; import org.bouncycastle.util.test.SimpleTest; /** * CTR DRBG Test */ public class CTRDRBGTest extends SimpleTest { public String getName() { return "CTRDRBGTest"; } public static void main(String[] args) { runTest(new CTRDRBGTest()); } private DRBGTestVector[] createTestVectorData() { return new DRBGTestVector[] { new DRBGTestVector( new DESedeEngine(), 168, new Bit232EntropyProvider().get(232), false, "20212223242526", 112, new String[] { "ABC88224514D0316EA3D48AEE3C9A2B4", "D3D3F372E43E7ABDC4FA293743EED076" } ), new DRBGTestVector( new DESedeEngine(), 168, new Bit232EntropyProvider().get(232), false, "20212223242526", 112, new String[] { "D4564EE072ACA5BD279536E14F94CB12", "1CCD9AFEF15A9679BA75E35225585DEA" } ) .addAdditionalInput("606162636465666768696A6B6C6D6E6F707172737475767778797A7B7C") .addAdditionalInput("A0A1A2A3A4A5A6A7A8A9AAABACADAEAFB0B1B2B3B4B5B6B7B8B9BABBBC"), new DRBGTestVector( new DESedeEngine(), 168, new Bit232EntropyProvider().get(232), false, "20212223242526", 112, new String[] { "760BED7D92B083B10AF31CF0656081EB", "FD1AC41482384D823CF3FD6F0E6C88B3" } ) .setPersonalizationString("404142434445464748494A4B4C4D4E4F505152535455565758595A5B5C"), new DRBGTestVector( new DESedeEngine(), 168, new Bit232EntropyProvider().get(232), false, "20212223242526", 112, new String[] { "7A4C1D7ADC8A67FDB50100ED23583A2C", "43044D311C0E07541CA5C8B0916976B2" } ) .setPersonalizationString("404142434445464748494A4B4C4D4E4F505152535455565758595A5B5C") .addAdditionalInput("606162636465666768696A6B6C6D6E6F707172737475767778797A7B7C") .addAdditionalInput("A0A1A2A3A4A5A6A7A8A9AAABACADAEAFB0B1B2B3B4B5B6B7B8B9BABBBC"), new DRBGTestVector( new DESedeEngine(), 168, new Bit232EntropyProvider().get(232), true, "20212223242526", 112, new String[] { "8FB78ABCA75C9F284E974E36141866BC", "9D9745FF31C42A4488CBB771B13B5D86" } ), new DRBGTestVector( new DESedeEngine(), 168, new Bit232EntropyProvider().get(232), true, "20212223242526", 112, new String[] { "0E389920A09B485AA4ABD0CA7E60D89C", "F4478EC6659A0D3577625B0C73A211DD" } ) .addAdditionalInput("606162636465666768696A6B6C6D6E6F707172737475767778797A7B7C") .addAdditionalInput("A0A1A2A3A4A5A6A7A8A9AAABACADAEAFB0B1B2B3B4B5B6B7B8B9BABBBC"), new DRBGTestVector( new DESedeEngine(), 168, new Bit232EntropyProvider().get(232), true, "20212223242526", 112, new String[] { "64983055D014550B39DE699E43130B64", "035FDDA8582A2214EC722C410A8D95D3" } ) .setPersonalizationString("404142434445464748494A4B4C4D4E4F505152535455565758595A5B5C"), new DRBGTestVector( new DESedeEngine(), 168, new Bit232EntropyProvider().get(232), true, "20212223242526", 112, new String[] { "A29C1A8C42FBC562D7D1DBA7DC541FFE", "0BDA66B049429061C013E4228C2F44C6" } ) .setPersonalizationString("404142434445464748494A4B4C4D4E4F505152535455565758595A5B5C") .addAdditionalInput("606162636465666768696A6B6C6D6E6F707172737475767778797A7B7C") .addAdditionalInput("A0A1A2A3A4A5A6A7A8A9AAABACADAEAFB0B1B2B3B4B5B6B7B8B9BABBBC"), new DRBGTestVector( new AESFastEngine(), 128, new Bit256EntropyProvider().get(256), false, "2021222324252627", 128, new String[] { "8CF59C8CF6888B96EB1C1E3E79D82387AF08A9E5FF75E23F1FBCD4559B6B997E", "69CDEF912C692D61B1DA4C05146B52EB7B8849BD87937835328254EC25A9180E" } ), new DRBGTestVector( new AESFastEngine(), 128, new Bit256EntropyProvider().get(256), false, "2021222324252627", 128, new String[] { "E8C74A4B7BFFB53BEB80E78CA86BB6DF70E2032AEB473E0DD54D2339CEFCE9D0", "26B3F823B4DBAFC23B141375E10B3AEB7A0B5DEF1C7D760B6F827D01ECD17AC7" } ) .addAdditionalInput("606162636465666768696A6B6C6D6E6F707172737475767778797A7B7C7D7E7F") .addAdditionalInput("A0A1A2A3A4A5A6A7A8A9AAABACADAEAFB0B1B2B3B4B5B6B7B8B9BABBBCBDBEBF"), new DRBGTestVector( new AESFastEngine(), 128, new Bit256EntropyProvider().get(256), false, "2021222324252627", 128, new String[] { "18FDEFBDC43D7A36D5D6D862205765D1D701C9F237007030DF1B8E70EE4EEE29", "9888F1D38BB1CCE31B363AA1BD9B39616876C30DEE1FF0B7BD8C4C441715C833" } ) .setPersonalizationString("404142434445464748494A4B4C4D4E4F505152535455565758595A5B5C5D5E5F"), new DRBGTestVector( new AESFastEngine(), 128, new Bit256EntropyProvider().get(256), true, "2021222324252627", 128, new String[] { "BFF4B85D68C84529F24F69F9ACF1756E29BA648DDEB825C225FA32BA490EF4A9", "9BD2635137A52AF7D0FCBEFEFB97EA93A0F4C438BD98956C0DACB04F15EE25B3" } ), new DRBGTestVector( new AESFastEngine(), 128, new Bit256EntropyProvider().get(256), true, "2021222324252627", 128, new String[] { "4573AC8BBB33D7CC4DBEF3EEDF6EAE748B536C3A1082CEE4948CDB51C83A7F9C", "99C628CDD87BD8C2F1FE443AA7F761DA16886436326323354DA6311FFF5BC678" } ) .addAdditionalInput("606162636465666768696A6B6C6D6E6F707172737475767778797A7B7C7D7E7F") .addAdditionalInput("A0A1A2A3A4A5A6A7A8A9AAABACADAEAFB0B1B2B3B4B5B6B7B8B9BABBBCBDBEBF"), new DRBGTestVector( new AESFastEngine(), 128, new Bit256EntropyProvider().get(256), true, "2021222324252627", 128, new String[] { "F324104E2FA14F79D8AA60DF06B93B3BC157324958F0A7EE1E193677A70E0250", "78F4C840134F40DC001BFAD3A90B5EF4DEBDBFAC3CFDF0CD69A89DC4FD34713F" } ) .setPersonalizationString("404142434445464748494A4B4C4D4E4F505152535455565758595A5B5C5D5E5F"), new DRBGTestVector( new AESFastEngine(), 192, new Bit320EntropyProvider().get(320), false, "202122232425262728292A2B", 192, new String[] { "E231244B3235B085C81604424357E85201E3828B5C45568679A5555F867AAC8C", "DDD0F7BCCADADAA31A67652259CE569A271DD85CF66C3D6A7E9FAED61F38D219" } ) .setPersonalizationString("404142434445464748494A4B4C4D4E4F505152535455565758595A5B5C5D5E5F6061626364656667"), new DRBGTestVector( new AESFastEngine(), 192, new Bit320EntropyProvider().get(320), true, "202122232425262728292A2B", 192, new String[] { "F780D4A2C25CF8EE7407D948EC0B724A4235D8B20E65081392755CA7912AD7C0", "BA14617F915BA964CB79276BDADC840C14B631BBD1A59097054FA6DFF863B238" } ) .setPersonalizationString("404142434445464748494A4B4C4D4E4F505152535455565758595A5B5C5D5E5F6061626364656667"), new DRBGTestVector( new AESFastEngine(), 256, new Bit384EntropyProvider().get(384), false, "202122232425262728292A2B2C2D2E2F", 256, new String[] { "47111E146562E9AA2FB2A1B095D37A8165AF8FC7CA611D632BE7D4C145C83900", "98A28E3B1BA363C9DAF0F6887A1CF52B833D3354D77A7C10837DD63DD2E645F8" } ) .setPersonalizationString("404142434445464748494A4B4C4D4E4F505152535455565758595A5B5C5D5E5F606162636465666768696A6B6C6D6E6F") .addAdditionalInput("606162636465666768696A6B6C6D6E6F707172737475767778797A7B7C7D7E7F808182838485868788898A8B8C8D8E8F") .addAdditionalInput("A0A1A2A3A4A5A6A7A8A9AAABACADAEAFB0B1B2B3B4B5B6B7B8B9BABBBCBDBEBFC0C1C2C3C4C5C6C7C8C9CACBCCCDCECF"), new DRBGTestVector( new AESFastEngine(), 256, new Bit384EntropyProvider().get(384), true, "202122232425262728292A2B2C2D2E2F", 256, new String[] { "71BB3F9C9CEAF4E6C92A83EB4C7225010EE150AC75E23F5F77AD5073EF24D88A", "386DEBBBF091BBF0502957B0329938FB836B82E594A2F5FDD5EB28D4E35528F4" } ) .addAdditionalInput("606162636465666768696A6B6C6D6E6F707172737475767778797A7B7C7D7E7F808182838485868788898A8B8C8D8E8F") .addAdditionalInput("A0A1A2A3A4A5A6A7A8A9AAABACADAEAFB0B1B2B3B4B5B6B7B8B9BABBBCBDBEBFC0C1C2C3C4C5C6C7C8C9CACBCCCDCECF"), new DRBGTestVector( new AESFastEngine(), 256, new Bit384EntropyProvider().get(384), true, "202122232425262728292A2B2C2D2E2F", 256, new String[] { "1A2E3FEE9056E98D375525FDC2B63B95B47CE51FCF594D804BD5A17F2E01139B", "601F95384F0D85946301D1EACE8F645A825CE38F1E2565B0C0C439448E9CA8AC" } ) .setPersonalizationString("404142434445464748494A4B4C4D4E4F505152535455565758595A5B5C5D5E5F606162636465666768696A6B6C6D6E6F"), new DRBGTestVector( new AESFastEngine(), 256, new Bit384EntropyProvider().get(384), true, "202122232425262728292A2B2C2D2E2F", 256, new String[] { "EAE6BCE781807E524D26605EA198077932D01EEB445B9AC6C5D99C101D29F46E", "738E99C95AF59519AAD37FF3D5180986ADEBAB6E95836725097E50A8D1D0BD28" } ) .setPersonalizationString("404142434445464748494A4B4C4D4E4F505152535455565758595A5B5C5D5E5F606162636465666768696A6B6C6D6E6F") .addAdditionalInput("606162636465666768696A6B6C6D6E6F707172737475767778797A7B7C7D7E7F808182838485868788898A8B8C8D8E8F") .addAdditionalInput("A0A1A2A3A4A5A6A7A8A9AAABACADAEAFB0B1B2B3B4B5B6B7B8B9BABBBCBDBEBFC0C1C2C3C4C5C6C7C8C9CACBCCCDCECF") }; } public void performTest() throws Exception { DRBGTestVector[] tests = createTestVectorData(); for (int i = 0; i != tests.length; i++) { DRBGTestVector tv = tests[i]; byte[] nonce = tv.nonce(); byte[] personalisationString = tv.personalizationString(); SP80090DRBG d = new CTRSP800DRBG(tv.getCipher(), tv.keySizeInBits(), tv.securityStrength(), tv.entropySource(), personalisationString, nonce); byte[] output = new byte[tv.expectedValue(0).length]; d.generate(output, tv.additionalInput(0), tv.predictionResistance()); byte[] expected = tv.expectedValue(0); if (!areEqual(expected, output)) { fail("Test #" + (i + 1) + ".1 failed, expected " + new String(Hex.encode(tv.expectedValue(0))) + " got " + new String(Hex.encode(output))); } output = new byte[tv.expectedValue(0).length]; d.generate(output, tv.additionalInput(1), tv.predictionResistance()); expected = tv.expectedValue(1); if (!areEqual(expected, output)) { fail("Test #" + (i + 1) + ".2 failed, expected " + new String(Hex.encode(tv.expectedValue(1))) + " got " + new String(Hex.encode(output))); } } // DESede/TDEA key parity test DRBGTestVector tv = tests[0]; SP80090DRBG drbg = new CTRSP800DRBG(new KeyParityCipher(tv.getCipher()), tv.keySizeInBits(), tv.securityStrength(), tv.entropySource(), tv.personalizationString(), tv.nonce()); byte[] output = new byte[tv.expectedValue(0).length]; drbg.generate(output, tv.additionalInput(0), tv.predictionResistance()); // Exception tests SP80090DRBG d; try { d = new CTRSP800DRBG(new AESEngine(), 256, 256, new Bit232EntropyProvider().get(128), null, null); fail("no exception thrown"); } catch (IllegalArgumentException e) { if (!e.getMessage().equals("Not enough entropy for security strength required")) { fail("Wrong exception", e); } } try { d = new CTRSP800DRBG(new DESedeEngine(), 256, 256, new Bit232EntropyProvider().get(232), null, null); fail("no exception thrown"); } catch (IllegalArgumentException e) { if (!e.getMessage().equals("Requested security strength is not supported by block cipher and key size")) { fail("Wrong exception", e); } } try { d = new CTRSP800DRBG(new DESedeEngine(), 168, 256, new Bit232EntropyProvider().get(232), null, null); fail("no exception thrown"); } catch (IllegalArgumentException e) { if (!e.getMessage().equals("Requested security strength is not supported by block cipher and key size")) { fail("Wrong exception", e); } } try { d = new CTRSP800DRBG(new AESEngine(), 192, 256, new Bit232EntropyProvider().get(232), null, null); fail("no exception thrown"); } catch (IllegalArgumentException e) { if (!e.getMessage().equals("Requested security strength is not supported by block cipher and key size")) { fail("Wrong exception", e); } } } private class Bit232EntropyProvider extends TestEntropySourceProvider { Bit232EntropyProvider() { super(Hex.decode( "000102030405060708090A0B0C0D0E0F101112131415161718191A1B1C" + "808182838485868788898A8B8C8D8E8F909192939495969798999A9B9C" + "C0C1C2C3C4C5C6C7C8C9CACBCCCDCECFD0D1D2D3D4D5D6D7D8D9DADBDC"), true); } } private class Bit256EntropyProvider extends TestEntropySourceProvider { Bit256EntropyProvider() { super(Hex.decode( "0001020304050607"+ "08090A0B0C0D0E0F101112131415161718191A1B1C1D1E1F"+ "8081828384858687"+ "88898A8B8C8D8E8F909192939495969798999A9B9C9D9E9F"+ "C0C1C2C3C4C5C6C7"+ "C8C9CACBCCCDCECFD0D1D2D3D4D5D6D7D8D9DADBDCDDDEDF"), true); } } private class Bit320EntropyProvider extends TestEntropySourceProvider { Bit320EntropyProvider() { super(Hex.decode( "000102030405060708090A0B0C0D0E0F"+ "101112131415161718191A1B1C1D1E1F2021222324252627"+ "808182838485868788898A8B8C8D8E8F"+ "909192939495969798999A9B9C9D9E9FA0A1A2A3A4A5A6A7"+ "C0C1C2C3C4C5C6C7C8C9CACBCCCDCECF"+ "D0D1D2D3D4D5D6D7D8D9DADBDCDDDEDFE0E1E2E3E4E5E6E7"), true); } } private class Bit384EntropyProvider extends TestEntropySourceProvider { Bit384EntropyProvider() { super(Hex.decode( "000102030405060708090A0B0C0D0E0F1011121314151617" + "18191A1B1C1D1E1F202122232425262728292A2B2C2D2E2F" + "808182838485868788898A8B8C8D8E8F9091929394959697" + "98999A9B9C9D9E9FA0A1A2A3A4A5A6A7A8A9AAABACADAEAF" + "C0C1C2C3C4C5C6C7C8C9CACBCCCDCECFD0D1D2D3D4D5D6D7" + "D8D9DADBDCDDDEDFE0E1E2E3E4E5E6E7E8E9EAEBECEDEEEF"), true); } } private class KeyParityCipher implements BlockCipher { private BlockCipher cipher; KeyParityCipher(BlockCipher cipher) { this.cipher = cipher; } public void init(boolean forEncryption, CipherParameters params) throws IllegalArgumentException { byte[] k = Arrays.clone(((KeyParameter)params).getKey()); DESedeParameters.setOddParity(k); if (!Arrays.areEqual(((KeyParameter)params).getKey(), k)) { fail("key not odd parity"); } cipher.init(forEncryption, params); } public String getAlgorithmName() { return cipher.getAlgorithmName(); } public int getBlockSize() { return cipher.getBlockSize(); } public int processBlock(byte[] in, int inOff, byte[] out, int outOff) throws DataLengthException, IllegalStateException { return cipher.processBlock(in, inOff, out, outOff); } public void reset() { cipher.reset(); } } } bouncycastle-1.49.orig/test/src/org/bouncycastle/crypto/agreement/0000755000175000017500000000000012152033550024744 5ustar ebourgebourgbouncycastle-1.49.orig/test/src/org/bouncycastle/crypto/agreement/test/0000755000175000017500000000000012152033550025723 5ustar ebourgebourgbouncycastle-1.49.orig/test/src/org/bouncycastle/crypto/agreement/test/JPAKEUtilTest.java0000644000175000017500000001721312103354520031121 0ustar ebourgebourgpackage org.bouncycastle.crypto.agreement.test; import java.math.BigInteger; import java.security.SecureRandom; import junit.framework.TestCase; import org.bouncycastle.crypto.CryptoException; import org.bouncycastle.crypto.Digest; import org.bouncycastle.crypto.agreement.jpake.JPAKEPrimeOrderGroup; import org.bouncycastle.crypto.agreement.jpake.JPAKEPrimeOrderGroups; import org.bouncycastle.crypto.agreement.jpake.JPAKEUtil; import org.bouncycastle.crypto.digests.SHA1Digest; import org.bouncycastle.crypto.digests.SHA256Digest; public class JPAKEUtilTest extends TestCase { private static final BigInteger TEN = BigInteger.valueOf(10); public void testValidateGx4() throws CryptoException { JPAKEUtil.validateGx4(TEN); try { JPAKEUtil.validateGx4(BigInteger.ONE); fail(); } catch (CryptoException e) { // pass } } public void testValidateGa() throws CryptoException { JPAKEUtil.validateGa(TEN); try { JPAKEUtil.validateGa(BigInteger.ONE); fail(); } catch (CryptoException e) { // pass } } public void testValidateParticipantIdsDiffer() throws CryptoException { JPAKEUtil.validateParticipantIdsDiffer("a", "b"); JPAKEUtil.validateParticipantIdsDiffer("a", "A"); try { JPAKEUtil.validateParticipantIdsDiffer("a", "a"); fail(); } catch (CryptoException e) { // pass } } public void testValidateParticipantIdsEqual() throws CryptoException { JPAKEUtil.validateParticipantIdsEqual("a", "a"); try { JPAKEUtil.validateParticipantIdsEqual("a", "b"); fail(); } catch (CryptoException e) { // pass } } public void testValidateMacTag() throws CryptoException { JPAKEPrimeOrderGroup pg1 = JPAKEPrimeOrderGroups.SUN_JCE_1024; SecureRandom random = new SecureRandom(); Digest digest = new SHA256Digest(); BigInteger x1 = JPAKEUtil.generateX1(pg1.getQ(), random); BigInteger x2 = JPAKEUtil.generateX2(pg1.getQ(), random); BigInteger x3 = JPAKEUtil.generateX1(pg1.getQ(), random); BigInteger x4 = JPAKEUtil.generateX2(pg1.getQ(), random); BigInteger gx1 = JPAKEUtil.calculateGx(pg1.getP(), pg1.getG(), x1); BigInteger gx2 = JPAKEUtil.calculateGx(pg1.getP(), pg1.getG(), x2); BigInteger gx3 = JPAKEUtil.calculateGx(pg1.getP(), pg1.getG(), x3); BigInteger gx4 = JPAKEUtil.calculateGx(pg1.getP(), pg1.getG(), x4); BigInteger gB = JPAKEUtil.calculateGA(pg1.getP(), gx3, gx1, gx2); BigInteger s = JPAKEUtil.calculateS("password".toCharArray()); BigInteger xs = JPAKEUtil.calculateX2s(pg1.getQ(), x4, s); BigInteger B = JPAKEUtil.calculateA(pg1.getP(), pg1.getQ(), gB, xs); BigInteger keyingMaterial = JPAKEUtil.calculateKeyingMaterial(pg1.getP(), pg1.getQ(), gx4, x2, s, B); BigInteger macTag = JPAKEUtil.calculateMacTag("participantId", "partnerParticipantId", gx1, gx2, gx3, gx4, keyingMaterial, digest); // should succed JPAKEUtil.validateMacTag("partnerParticipantId", "participantId", gx3, gx4, gx1, gx2, keyingMaterial, digest, macTag); // validating own macTag (as opposed to the other party's mactag) try { JPAKEUtil.validateMacTag("participantId", "partnerParticipantId", gx1, gx2, gx3, gx4, keyingMaterial, digest, macTag); fail(); } catch (CryptoException e) { // pass } // participant ids switched try { JPAKEUtil.validateMacTag("participantId", "partnerParticipantId", gx3, gx4, gx1, gx2, keyingMaterial, digest, macTag); fail(); } catch (CryptoException e) { // pass } } public void testValidateNotNull() { JPAKEUtil.validateNotNull("a", "description"); try { JPAKEUtil.validateNotNull(null, "description"); fail(); } catch (NullPointerException e) { // pass } } public void testValidateZeroKnowledgeProof() throws CryptoException { JPAKEPrimeOrderGroup pg1 = JPAKEPrimeOrderGroups.SUN_JCE_1024; SecureRandom random = new SecureRandom(); Digest digest1 = new SHA256Digest(); BigInteger x1 = JPAKEUtil.generateX1(pg1.getQ(), random); BigInteger gx1 = JPAKEUtil.calculateGx(pg1.getP(), pg1.getG(), x1); String participantId1 = "participant1"; BigInteger[] zkp1 = JPAKEUtil.calculateZeroKnowledgeProof(pg1.getP(), pg1.getQ(), pg1.getG(), gx1, x1, participantId1, digest1, random); // should succeed JPAKEUtil.validateZeroKnowledgeProof(pg1.getP(), pg1.getQ(), pg1.getG(), gx1, zkp1, participantId1, digest1); // wrong group JPAKEPrimeOrderGroup pg2 = JPAKEPrimeOrderGroups.NIST_3072; try { JPAKEUtil.validateZeroKnowledgeProof(pg2.getP(), pg2.getQ(), pg2.getG(), gx1, zkp1, participantId1, digest1); fail(); } catch (CryptoException e) { // pass } // wrong digest Digest digest2 = new SHA1Digest(); try { JPAKEUtil.validateZeroKnowledgeProof(pg1.getP(), pg1.getQ(), pg1.getG(), gx1, zkp1, participantId1, digest2); fail(); } catch (CryptoException e) { // pass } // wrong participant String participantId2 = "participant2"; try { JPAKEUtil.validateZeroKnowledgeProof(pg1.getP(), pg1.getQ(), pg1.getG(), gx1, zkp1, participantId2, digest1); fail(); } catch (CryptoException e) { // pass } // wrong gx BigInteger x2 = JPAKEUtil.generateX1(pg1.getQ(), random); BigInteger gx2 = JPAKEUtil.calculateGx(pg1.getP(), pg1.getG(), x2); try { JPAKEUtil.validateZeroKnowledgeProof(pg1.getP(), pg1.getQ(), pg1.getG(), gx2, zkp1, participantId1, digest1); fail(); } catch (CryptoException e) { // pass } // wrong zkp BigInteger[] zkp2 = JPAKEUtil.calculateZeroKnowledgeProof(pg1.getP(), pg1.getQ(), pg1.getG(), gx2, x2, participantId1, digest1, random); try { JPAKEUtil.validateZeroKnowledgeProof(pg1.getP(), pg1.getQ(), pg1.getG(), gx1, zkp2, participantId1, digest1); fail(); } catch (CryptoException e) { // pass } // gx <= 0 try { JPAKEUtil.validateZeroKnowledgeProof(pg1.getP(), pg1.getQ(), pg1.getG(), BigInteger.ZERO, zkp1, participantId1, digest1); fail(); } catch (CryptoException e) { // pass } // gx >= p try { JPAKEUtil.validateZeroKnowledgeProof(pg1.getP(), pg1.getQ(), pg1.getG(), pg1.getP(), zkp1, participantId1, digest1); fail(); } catch (CryptoException e) { // pass } // gx mod q == 1 try { JPAKEUtil.validateZeroKnowledgeProof(pg1.getP(), pg1.getQ(), pg1.getG(), pg1.getQ().add(BigInteger.ONE), zkp1, participantId1, digest1); fail(); } catch (CryptoException e) { // pass } } } bouncycastle-1.49.orig/test/src/org/bouncycastle/crypto/agreement/test/JPAKEPrimeOrderGroupTest.java0000644000175000017500000000411012103354520033261 0ustar ebourgebourgpackage org.bouncycastle.crypto.agreement.test; import java.math.BigInteger; import junit.framework.TestCase; import org.bouncycastle.crypto.CryptoException; import org.bouncycastle.crypto.agreement.jpake.JPAKEPrimeOrderGroup; public class JPAKEPrimeOrderGroupTest extends TestCase { public void testConstruction() throws CryptoException { // p-1 not evenly divisible by q try { new JPAKEPrimeOrderGroup(BigInteger.valueOf(7), BigInteger.valueOf(5), BigInteger.valueOf(6)); fail(); } catch (IllegalArgumentException e) { // pass } // g < 2 try { new JPAKEPrimeOrderGroup(BigInteger.valueOf(11), BigInteger.valueOf(5), BigInteger.valueOf(1)); fail(); } catch (IllegalArgumentException e) { // pass } // g > p-1 try { new JPAKEPrimeOrderGroup(BigInteger.valueOf(11), BigInteger.valueOf(5), BigInteger.valueOf(11)); fail(); } catch (IllegalArgumentException e) { // pass } // g^q mod p not equal 1 try { new JPAKEPrimeOrderGroup(BigInteger.valueOf(11), BigInteger.valueOf(5), BigInteger.valueOf(6)); fail(); } catch (IllegalArgumentException e) { // pass } // p not prime try { new JPAKEPrimeOrderGroup(BigInteger.valueOf(15), BigInteger.valueOf(2), BigInteger.valueOf(4)); fail(); } catch (IllegalArgumentException e) { // pass } // q not prime try { new JPAKEPrimeOrderGroup(BigInteger.valueOf(7), BigInteger.valueOf(6), BigInteger.valueOf(3)); fail(); } catch (IllegalArgumentException e) { // pass } // should succeed new JPAKEPrimeOrderGroup(BigInteger.valueOf(7), BigInteger.valueOf(3), BigInteger.valueOf(4)); } } bouncycastle-1.49.orig/test/src/org/bouncycastle/crypto/agreement/test/JPAKEParticipantTest.java0000644000175000017500000003762012103354520032466 0ustar ebourgebourgpackage org.bouncycastle.crypto.agreement.test; import java.math.BigInteger; import java.security.SecureRandom; import junit.framework.TestCase; import org.bouncycastle.crypto.CryptoException; import org.bouncycastle.crypto.Digest; import org.bouncycastle.crypto.agreement.jpake.JPAKEParticipant; import org.bouncycastle.crypto.agreement.jpake.JPAKEPrimeOrderGroup; import org.bouncycastle.crypto.agreement.jpake.JPAKEPrimeOrderGroups; import org.bouncycastle.crypto.agreement.jpake.JPAKERound1Payload; import org.bouncycastle.crypto.agreement.jpake.JPAKERound2Payload; import org.bouncycastle.crypto.agreement.jpake.JPAKERound3Payload; import org.bouncycastle.crypto.agreement.jpake.JPAKEUtil; import org.bouncycastle.crypto.digests.SHA256Digest; public class JPAKEParticipantTest extends TestCase { public void testConstruction() throws CryptoException { JPAKEPrimeOrderGroup group = JPAKEPrimeOrderGroups.SUN_JCE_1024; SecureRandom random = new SecureRandom(); Digest digest = new SHA256Digest(); String participantId = "participantId"; char[] password = "password".toCharArray(); // should succeed new JPAKEParticipant(participantId, password, group, digest, random); // null participantId try { new JPAKEParticipant(null, password, group, digest, random); fail(); } catch (NullPointerException e) { // pass } // null password try { new JPAKEParticipant(participantId, null, group, digest, random); fail(); } catch (NullPointerException e) { // pass } // empty password try { new JPAKEParticipant(participantId, "".toCharArray(), group, digest, random); fail(); } catch (IllegalArgumentException e) { // pass } // null group try { new JPAKEParticipant(participantId, password, null, digest, random); fail(); } catch (NullPointerException e) { // pass } // null digest try { new JPAKEParticipant(participantId, password, group, null, random); fail(); } catch (NullPointerException e) { // pass } // null random try { new JPAKEParticipant(participantId, password, group, digest, null); fail(); } catch (NullPointerException e) { // pass } } public void testSuccessfulExchange() throws CryptoException { JPAKEParticipant alice = createAlice(); JPAKEParticipant bob = createBob(); ExchangeAfterRound2Creation exchange = runExchangeUntilRound2Creation(alice, bob); alice.validateRound2PayloadReceived(exchange.bobRound2Payload); bob.validateRound2PayloadReceived(exchange.aliceRound2Payload); BigInteger aliceKeyingMaterial = alice.calculateKeyingMaterial(); BigInteger bobKeyingMaterial = bob.calculateKeyingMaterial(); JPAKERound3Payload aliceRound3Payload = alice.createRound3PayloadToSend(aliceKeyingMaterial); JPAKERound3Payload bobRound3Payload = bob.createRound3PayloadToSend(bobKeyingMaterial); alice.validateRound3PayloadReceived(bobRound3Payload, aliceKeyingMaterial); bob.validateRound3PayloadReceived(aliceRound3Payload, bobKeyingMaterial); assertEquals(aliceKeyingMaterial, bobKeyingMaterial); } public void testIncorrectPassword() throws CryptoException { JPAKEParticipant alice = createAlice(); JPAKEParticipant bob = createBobWithWrongPassword(); ExchangeAfterRound2Creation exchange = runExchangeUntilRound2Creation(alice, bob); alice.validateRound2PayloadReceived(exchange.bobRound2Payload); bob.validateRound2PayloadReceived(exchange.aliceRound2Payload); BigInteger aliceKeyingMaterial = alice.calculateKeyingMaterial(); BigInteger bobKeyingMaterial = bob.calculateKeyingMaterial(); JPAKERound3Payload aliceRound3Payload = alice.createRound3PayloadToSend(aliceKeyingMaterial); JPAKERound3Payload bobRound3Payload = bob.createRound3PayloadToSend(bobKeyingMaterial); try { alice.validateRound3PayloadReceived(bobRound3Payload, aliceKeyingMaterial); fail(); } catch (CryptoException e) { // pass } try { bob.validateRound3PayloadReceived(aliceRound3Payload, bobKeyingMaterial); fail(); } catch (CryptoException e) { // pass } } /** * Tests that {@link JPAKEParticipant} throws appropriate {@link IllegalStateException}s * when the methods are called in the wrong order. */ public void testStateValidation() throws CryptoException { JPAKEParticipant alice = createAlice(); JPAKEParticipant bob = createBob(); // We're testing alice here. Bob is just used for help. // START ROUND 1 CHECKS assertEquals(JPAKEParticipant.STATE_INITIALIZED, alice.getState()); // create round 2 before round 1 try { alice.createRound2PayloadToSend(); fail(); } catch (IllegalStateException e) { // pass } JPAKERound1Payload aliceRound1Payload = alice.createRound1PayloadToSend(); assertEquals(JPAKEParticipant.STATE_ROUND_1_CREATED, alice.getState()); // create round 1 payload twice try { alice.createRound1PayloadToSend(); fail(); } catch (IllegalStateException e) { // pass } // create round 2 before validating round 1 try { alice.createRound2PayloadToSend(); fail(); } catch (IllegalStateException e) { // pass } // validate round 2 before validating round 1 try { alice.validateRound2PayloadReceived(null); fail(); } catch (IllegalStateException e) { // pass } JPAKERound1Payload bobRound1Payload = bob.createRound1PayloadToSend(); alice.validateRound1PayloadReceived(bobRound1Payload); assertEquals(JPAKEParticipant.STATE_ROUND_1_VALIDATED, alice.getState()); // validate round 1 payload twice try { alice.validateRound1PayloadReceived(bobRound1Payload); fail(); } catch (IllegalStateException e) { // pass } bob.validateRound1PayloadReceived(aliceRound1Payload); // START ROUND 2 CHECKS JPAKERound2Payload aliceRound2Payload = alice.createRound2PayloadToSend(); assertEquals(JPAKEParticipant.STATE_ROUND_2_CREATED, alice.getState()); // create round 2 payload twice try { alice.createRound2PayloadToSend(); fail(); } catch (IllegalStateException e) { // pass } // create key before validating round 2 try { alice.calculateKeyingMaterial(); fail(); } catch (IllegalStateException e) { // pass } // validate round 3 before validating round 2 try { alice.validateRound3PayloadReceived(null, null); fail(); } catch (IllegalStateException e) { // pass } JPAKERound2Payload bobRound2Payload = bob.createRound2PayloadToSend(); alice.validateRound2PayloadReceived(bobRound2Payload); assertEquals(JPAKEParticipant.STATE_ROUND_2_VALIDATED, alice.getState()); // validate round 2 payload twice try { alice.validateRound2PayloadReceived(bobRound2Payload); fail(); } catch (IllegalStateException e) { // pass } bob.validateRound2PayloadReceived(aliceRound2Payload); // create round 3 before calculating key try { alice.createRound3PayloadToSend(BigInteger.ONE); fail(); } catch (IllegalStateException e) { // pass } // START KEY CALCULATION CHECKS BigInteger aliceKeyingMaterial = alice.calculateKeyingMaterial(); assertEquals(JPAKEParticipant.STATE_KEY_CALCULATED, alice.getState()); // calculate key twice try { alice.calculateKeyingMaterial(); fail(); } catch (IllegalStateException e) { // pass } BigInteger bobKeyingMaterial = bob.calculateKeyingMaterial(); // START ROUND 3 CHECKS JPAKERound3Payload aliceRound3Payload = alice.createRound3PayloadToSend(aliceKeyingMaterial); assertEquals(JPAKEParticipant.STATE_ROUND_3_CREATED, alice.getState()); // create round 3 payload twice try { alice.createRound3PayloadToSend(aliceKeyingMaterial); fail(); } catch (IllegalStateException e) { // pass } JPAKERound3Payload bobRound3Payload = bob.createRound3PayloadToSend(bobKeyingMaterial); alice.validateRound3PayloadReceived(bobRound3Payload, aliceKeyingMaterial); assertEquals(JPAKEParticipant.STATE_ROUND_3_VALIDATED, alice.getState()); // validate round 3 payload twice try { alice.validateRound3PayloadReceived(bobRound3Payload, aliceKeyingMaterial); fail(); } catch (IllegalStateException e) { // pass } bob.validateRound3PayloadReceived(aliceRound3Payload, bobKeyingMaterial); } /** * Tests that {@link JPAKEParticipant#validateRound1PayloadReceived(JPAKERound1Payload)} * calls the appropriate validate methods in {@link JPAKEUtil}. * Note that {@link JPAKEUtilTest} tests the individual validate methods * called by {@link JPAKEParticipant} more extensively. */ public void testValidateRound1PayloadReceived() throws CryptoException { // We're testing alice here. Bob is just used for help. JPAKERound1Payload bobRound1Payload = createBob().createRound1PayloadToSend(); // should succeed createAlice().validateRound1PayloadReceived(bobRound1Payload); // alice verifies alice's payload try { JPAKEParticipant alice = createAlice(); alice.validateRound1PayloadReceived(alice.createRound1PayloadToSend()); fail(); } catch (CryptoException e) { // pass } // g^x4 == 1 try { createAlice().validateRound1PayloadReceived(new JPAKERound1Payload( bobRound1Payload.getParticipantId(), bobRound1Payload.getGx1(), BigInteger.ONE, bobRound1Payload.getKnowledgeProofForX1(), bobRound1Payload.getKnowledgeProofForX2())); fail(); } catch (CryptoException e) { // pass } // zero knowledge proof for x3 fails try { JPAKERound1Payload bobRound1Payload2 = createBob().createRound1PayloadToSend(); createAlice().validateRound1PayloadReceived(new JPAKERound1Payload( bobRound1Payload.getParticipantId(), bobRound1Payload.getGx1(), bobRound1Payload.getGx2(), bobRound1Payload2.getKnowledgeProofForX1(), bobRound1Payload.getKnowledgeProofForX2())); fail(); } catch (CryptoException e) { // pass } // zero knowledge proof for x4 fails try { JPAKERound1Payload bobRound1Payload2 = createBob().createRound1PayloadToSend(); createAlice().validateRound1PayloadReceived(new JPAKERound1Payload( bobRound1Payload.getParticipantId(), bobRound1Payload.getGx1(), bobRound1Payload.getGx2(), bobRound1Payload.getKnowledgeProofForX1(), bobRound1Payload2.getKnowledgeProofForX2())); fail(); } catch (CryptoException e) { // pass } } /** * Tests that {@link JPAKEParticipant#validateRound2PayloadReceived(JPAKERound2Payload)} * calls the appropriate validate methods in {@link JPAKEUtil}. * Note that {@link JPAKEUtilTest} tests the individual validate methods * called by {@link JPAKEParticipant} more extensively. */ public void testValidateRound2PayloadReceived() throws CryptoException { // We're testing alice here. Bob is just used for help. // should succeed ExchangeAfterRound2Creation exchange1 = runExchangeUntilRound2Creation(createAlice(), createBob()); exchange1.alice.validateRound2PayloadReceived(exchange1.bobRound2Payload); // alice verifies alice's payload ExchangeAfterRound2Creation exchange2 = runExchangeUntilRound2Creation(createAlice(), createBob()); try { exchange2.alice.validateRound2PayloadReceived(exchange2.aliceRound2Payload); fail(); } catch (CryptoException e) { // pass } // wrong z ExchangeAfterRound2Creation exchange3 = runExchangeUntilRound2Creation(createAlice(), createBob()); ExchangeAfterRound2Creation exchange4 = runExchangeUntilRound2Creation(createAlice(), createBob()); try { exchange3.alice.validateRound2PayloadReceived(exchange4.bobRound2Payload); fail(); } catch (CryptoException e) { // pass } } private static class ExchangeAfterRound2Creation { public JPAKEParticipant alice; public JPAKERound2Payload aliceRound2Payload; public JPAKERound2Payload bobRound2Payload; public ExchangeAfterRound2Creation( JPAKEParticipant alice, JPAKERound2Payload aliceRound2Payload, JPAKERound2Payload bobRound2Payload) { this.alice = alice; this.aliceRound2Payload = aliceRound2Payload; this.bobRound2Payload = bobRound2Payload; } } private ExchangeAfterRound2Creation runExchangeUntilRound2Creation(JPAKEParticipant alice, JPAKEParticipant bob) throws CryptoException { JPAKERound1Payload aliceRound1Payload = alice.createRound1PayloadToSend(); JPAKERound1Payload bobRound1Payload = bob.createRound1PayloadToSend(); alice.validateRound1PayloadReceived(bobRound1Payload); bob.validateRound1PayloadReceived(aliceRound1Payload); JPAKERound2Payload aliceRound2Payload = alice.createRound2PayloadToSend(); JPAKERound2Payload bobRound2Payload = bob.createRound2PayloadToSend(); return new ExchangeAfterRound2Creation( alice, aliceRound2Payload, bobRound2Payload); } private JPAKEParticipant createAlice() { return createParticipant("alice", "password"); } private JPAKEParticipant createBob() { return createParticipant("bob", "password"); } private JPAKEParticipant createBobWithWrongPassword() { return createParticipant("bob", "wrong"); } private JPAKEParticipant createParticipant(String participantId, String password) { return new JPAKEParticipant( participantId, password.toCharArray(), JPAKEPrimeOrderGroups.SUN_JCE_1024); } } bouncycastle-1.49.orig/test/src/org/bouncycastle/crypto/agreement/test/AllTests.java0000644000175000017500000000111612103354520030317 0ustar ebourgebourgpackage org.bouncycastle.crypto.agreement.test; import junit.framework.Test; import junit.framework.TestCase; import junit.framework.TestSuite; public class AllTests extends TestCase { public static void main(String[] args) { junit.textui.TestRunner.run(suite()); } public static Test suite() { TestSuite suite = new TestSuite("JPKAE Engine Tests"); suite.addTestSuite(JPAKEParticipantTest.class); suite.addTestSuite(JPAKEPrimeOrderGroupTest.class); suite.addTestSuite(JPAKEUtilTest.class); return suite; } } bouncycastle-1.49.orig/test/src/org/bouncycastle/asn1/0000755000175000017500000000000012152033550022317 5ustar ebourgebourgbouncycastle-1.49.orig/test/src/org/bouncycastle/asn1/test/0000755000175000017500000000000012152033550023276 5ustar ebourgebourgbouncycastle-1.49.orig/test/src/org/bouncycastle/asn1/test/ContentHintsUnitTest.java0000644000175000017500000000441011625364337030276 0ustar ebourgebourgpackage org.bouncycastle.asn1.test; import java.io.IOException; import org.bouncycastle.asn1.ASN1InputStream; import org.bouncycastle.asn1.ASN1ObjectIdentifier; import org.bouncycastle.asn1.ASN1Sequence; import org.bouncycastle.asn1.DERUTF8String; import org.bouncycastle.asn1.ess.ContentHints; public class ContentHintsUnitTest extends ASN1UnitTest { public String getName() { return "ContentHints"; } public void performTest() throws Exception { DERUTF8String contentDescription = new DERUTF8String("Description"); ASN1ObjectIdentifier contentType = new ASN1ObjectIdentifier("1.2.2.3"); ContentHints hints = new ContentHints(contentType); checkConstruction(hints, contentType, null); hints = new ContentHints(contentType, contentDescription); checkConstruction(hints, contentType, contentDescription); hints = ContentHints.getInstance(null); if (hints != null) { fail("null getInstance() failed."); } try { ContentHints.getInstance(new Object()); fail("getInstance() failed to detect bad object."); } catch (IllegalArgumentException e) { // expected } } private void checkConstruction( ContentHints hints, ASN1ObjectIdentifier contentType, DERUTF8String description) throws IOException { checkValues(hints, contentType, description); hints = ContentHints.getInstance(hints); checkValues(hints, contentType, description); ASN1InputStream aIn = new ASN1InputStream(hints.toASN1Primitive().getEncoded()); ASN1Sequence seq = (ASN1Sequence)aIn.readObject(); hints = ContentHints.getInstance(seq); checkValues(hints, contentType, description); } private void checkValues( ContentHints hints, ASN1ObjectIdentifier contentType, DERUTF8String description) { checkMandatoryField("contentType", contentType, hints.getContentType()); checkOptionalField("description", description, hints.getContentDescription()); } public static void main( String[] args) { runTest(new ContentHintsUnitTest()); } } bouncycastle-1.49.orig/test/src/org/bouncycastle/asn1/test/BitStringConstantTester.java0000644000175000017500000000124210453643505030757 0ustar ebourgebourgpackage org.bouncycastle.asn1.test; public class BitStringConstantTester { private static final int[] bits = { 1 << 7, 1 << 6, 1 << 5, 1 << 4, 1 << 3, 1 << 2, 1 << 1, 1 << 0, 1 << 15, 1 << 14, 1 << 13, 1 << 12, 1 << 11, 1 << 10, 1 << 9, 1 << 8, 1 << 23, 1 << 22, 1 << 21, 1 << 20, 1 << 19, 1 << 18, 1 << 17, 1 << 16, 1 << 31, 1 << 30, 1 << 29, 1 << 28, 1 << 27, 1 << 26, 1 << 25, 1 << 24 }; public static void testFlagValueCorrect( int bitNo, int value) { if (bits[bitNo] != value) { throw new IllegalArgumentException("bit value " + bitNo + " wrong"); } } } bouncycastle-1.49.orig/test/src/org/bouncycastle/asn1/test/DeclarationOfMajorityUnitTest.java0000644000175000017500000000506711737275254032123 0ustar ebourgebourgpackage org.bouncycastle.asn1.test; import java.io.IOException; import org.bouncycastle.asn1.ASN1GeneralizedTime; import org.bouncycastle.asn1.ASN1InputStream; import org.bouncycastle.asn1.DERGeneralizedTime; import org.bouncycastle.asn1.DERTaggedObject; import org.bouncycastle.asn1.isismtt.x509.DeclarationOfMajority; public class DeclarationOfMajorityUnitTest extends ASN1UnitTest { public String getName() { return "DeclarationOfMajority"; } public void performTest() throws Exception { ASN1GeneralizedTime dateOfBirth = new ASN1GeneralizedTime("20070315173729Z"); DeclarationOfMajority decl = new DeclarationOfMajority(dateOfBirth); checkConstruction(decl, DeclarationOfMajority.dateOfBirth, dateOfBirth, -1); decl = new DeclarationOfMajority(6); checkConstruction(decl, DeclarationOfMajority.notYoungerThan, null, 6); decl = DeclarationOfMajority.getInstance(null); if (decl != null) { fail("null getInstance() failed."); } try { DeclarationOfMajority.getInstance(new Object()); fail("getInstance() failed to detect bad object."); } catch (IllegalArgumentException e) { // expected } } private void checkConstruction( DeclarationOfMajority decl, int type, DERGeneralizedTime dateOfBirth, int notYoungerThan) throws IOException { checkValues(decl, type, dateOfBirth, notYoungerThan); decl = DeclarationOfMajority.getInstance(decl); checkValues(decl, type, dateOfBirth, notYoungerThan); ASN1InputStream aIn = new ASN1InputStream(decl.toASN1Object().getEncoded()); DERTaggedObject info = (DERTaggedObject)aIn.readObject(); decl = DeclarationOfMajority.getInstance(info); checkValues(decl, type, dateOfBirth, notYoungerThan); } private void checkValues( DeclarationOfMajority decl, int type, DERGeneralizedTime dateOfBirth, int notYoungerThan) { checkMandatoryField("type", type, decl.getType()); checkOptionalField("dateOfBirth", dateOfBirth, decl.getDateOfBirth()); if (notYoungerThan != -1 && notYoungerThan != decl.notYoungerThan()) { fail("notYoungerThan mismatch"); } } public static void main( String[] args) { runTest(new DeclarationOfMajorityUnitTest()); } } bouncycastle-1.49.orig/test/src/org/bouncycastle/asn1/test/CommitmentTypeQualifierUnitTest.java0000644000175000017500000000560110361171076032471 0ustar ebourgebourgpackage org.bouncycastle.asn1.test; import java.io.IOException; import org.bouncycastle.asn1.ASN1Encodable; import org.bouncycastle.asn1.ASN1InputStream; import org.bouncycastle.asn1.ASN1Sequence; import org.bouncycastle.asn1.DERObjectIdentifier; import org.bouncycastle.asn1.esf.CommitmentTypeIdentifier; import org.bouncycastle.asn1.esf.CommitmentTypeQualifier; import org.bouncycastle.util.test.SimpleTest; public class CommitmentTypeQualifierUnitTest extends SimpleTest { public String getName() { return "CommitmentTypeQualifier"; } public void performTest() throws Exception { CommitmentTypeQualifier ctq = new CommitmentTypeQualifier(CommitmentTypeIdentifier.proofOfOrigin); checkConstruction(ctq, CommitmentTypeIdentifier.proofOfOrigin, null); ASN1Encodable info = new DERObjectIdentifier("1.2"); ctq = new CommitmentTypeQualifier(CommitmentTypeIdentifier.proofOfOrigin, info); checkConstruction(ctq, CommitmentTypeIdentifier.proofOfOrigin, info); ctq = CommitmentTypeQualifier.getInstance(null); if (ctq != null) { fail("null getInstance() failed."); } try { CommitmentTypeQualifier.getInstance(new Object()); fail("getInstance() failed to detect bad object."); } catch (IllegalArgumentException e) { // expected } } private void checkConstruction( CommitmentTypeQualifier mv, DERObjectIdentifier commitmenttTypeId, ASN1Encodable qualifier) throws IOException { checkStatement(mv, commitmenttTypeId, qualifier); mv = CommitmentTypeQualifier.getInstance(mv); checkStatement(mv, commitmenttTypeId, qualifier); ASN1InputStream aIn = new ASN1InputStream(mv.toASN1Object().getEncoded()); ASN1Sequence seq = (ASN1Sequence)aIn.readObject(); mv = CommitmentTypeQualifier.getInstance(seq); checkStatement(mv, commitmenttTypeId, qualifier); } private void checkStatement( CommitmentTypeQualifier ctq, DERObjectIdentifier commitmentTypeId, ASN1Encodable qualifier) { if (!ctq.getCommitmentTypeIdentifier().equals(commitmentTypeId)) { fail("commitmentTypeIds don't match."); } if (qualifier != null) { if (!ctq.getQualifier().equals(qualifier)) { fail("qualifiers don't match."); } } else if (ctq.getQualifier() != null) { fail("qualifier found when none expected."); } } public static void main( String[] args) { runTest(new CommitmentTypeQualifierUnitTest()); } } bouncycastle-1.49.orig/test/src/org/bouncycastle/asn1/test/StringTest.java0000644000175000017500000001275111705174314026264 0ustar ebourgebourgpackage org.bouncycastle.asn1.test; import java.io.IOException; import org.bouncycastle.asn1.ASN1Primitive; import org.bouncycastle.asn1.ASN1String; import org.bouncycastle.asn1.DERBMPString; import org.bouncycastle.asn1.DERBitString; import org.bouncycastle.asn1.DERGeneralString; import org.bouncycastle.asn1.DERIA5String; import org.bouncycastle.asn1.DERNumericString; import org.bouncycastle.asn1.DERPrintableString; import org.bouncycastle.asn1.DERT61String; import org.bouncycastle.asn1.DERUTF8String; import org.bouncycastle.asn1.DERUniversalString; import org.bouncycastle.asn1.DERVisibleString; import org.bouncycastle.util.Strings; import org.bouncycastle.util.test.SimpleTest; /** * X.690 test example */ public class StringTest extends SimpleTest { public String getName() { return "String"; } public void performTest() throws IOException { DERBitString bs = new DERBitString( new byte[] { (byte)0x01,(byte)0x23,(byte)0x45,(byte)0x67,(byte)0x89,(byte)0xab,(byte)0xcd,(byte)0xef }); if (!bs.getString().equals("#0309000123456789ABCDEF")) { fail("DERBitString.getString() result incorrect"); } if (!bs.toString().equals("#0309000123456789ABCDEF")) { fail("DERBitString.toString() result incorrect"); } bs = new DERBitString( new byte[] { (byte)0xfe,(byte)0xdc,(byte)0xba,(byte)0x98,(byte)0x76,(byte)0x54,(byte)0x32,(byte)0x10 }); if (!bs.getString().equals("#030900FEDCBA9876543210")) { fail("DERBitString.getString() result incorrect"); } if (!bs.toString().equals("#030900FEDCBA9876543210")) { fail("DERBitString.toString() result incorrect"); } DERUniversalString us = new DERUniversalString( new byte[] { (byte)0x01,(byte)0x23,(byte)0x45,(byte)0x67,(byte)0x89,(byte)0xab,(byte)0xcd,(byte)0xef }); if (!us.getString().equals("#1C080123456789ABCDEF")) { fail("DERUniversalString.getString() result incorrect"); } if (!us.toString().equals("#1C080123456789ABCDEF")) { fail("DERUniversalString.toString() result incorrect"); } us = new DERUniversalString( new byte[] { (byte)0xfe,(byte)0xdc,(byte)0xba,(byte)0x98,(byte)0x76,(byte)0x54,(byte)0x32,(byte)0x10 }); if (!us.getString().equals("#1C08FEDCBA9876543210")) { fail("DERUniversalString.getString() result incorrect"); } if (!us.toString().equals("#1C08FEDCBA9876543210")) { fail("DERUniversalString.toString() result incorrect"); } byte[] t61Bytes = new byte[] { -1, -2, -3, -4, -5, -6, -7, -8 }; String t61String = new String(t61Bytes, "iso-8859-1"); DERT61String t61 = new DERT61String(Strings.fromByteArray(t61Bytes)); if (!t61.getString().equals(t61String)) { fail("DERT61String.getString() result incorrect"); } if (!t61.toString().equals(t61String)) { fail("DERT61String.toString() result incorrect"); } char[] shortChars = new char[] { 'a', 'b', 'c', 'd', 'e'}; char[] longChars = new char[1000]; for (int i = 0; i != longChars.length; i++) { longChars[i] = 'X'; } checkString(new DERBMPString(new String(shortChars)), new DERBMPString(new String(longChars))); checkString(new DERUTF8String(new String(shortChars)), new DERUTF8String(new String(longChars))); checkString(new DERIA5String(new String(shortChars)), new DERIA5String(new String(longChars))); checkString(new DERPrintableString(new String(shortChars)), new DERPrintableString(new String(longChars))); checkString(new DERVisibleString(new String(shortChars)), new DERVisibleString(new String(longChars))); checkString(new DERGeneralString(new String(shortChars)), new DERGeneralString(new String(longChars))); checkString(new DERT61String(new String(shortChars)), new DERT61String(new String(longChars))); shortChars = new char[] { '1', '2', '3', '4', '5'}; longChars = new char[1000]; for (int i = 0; i != longChars.length; i++) { longChars[i] = '1'; } checkString(new DERNumericString(new String(shortChars)), new DERNumericString(new String(longChars))); byte[] shortBytes = new byte[] { (byte)'a', (byte)'b', (byte)'c', (byte)'d', (byte)'e'}; byte[] longBytes = new byte[1000]; for (int i = 0; i != longChars.length; i++) { longBytes[i] = (byte)'X'; } checkString(new DERUniversalString(shortBytes), new DERUniversalString(longBytes)); } private void checkString(ASN1String shortString, ASN1String longString) throws IOException { ASN1String short2 = (ASN1String)ASN1Primitive.fromByteArray(((ASN1Primitive)shortString).getEncoded()); if (!shortString.toString().equals(short2.toString())) { fail(short2.getClass().getName() + " shortBytes result incorrect"); } ASN1String long2 = (ASN1String)ASN1Primitive.fromByteArray(((ASN1Primitive)longString).getEncoded()); if (!longString.toString().equals(long2.toString())) { fail(long2.getClass().getName() + " longBytes result incorrect"); } } public static void main( String[] args) { runTest(new StringTest()); } } bouncycastle-1.49.orig/test/src/org/bouncycastle/asn1/test/GetInstanceTest.java0000644000175000017500000012623712103440465027223 0ustar ebourgebourgpackage org.bouncycastle.asn1.test; import java.lang.reflect.Method; import java.math.BigInteger; import java.util.Date; import java.util.Vector; import junit.framework.TestCase; import org.bouncycastle.asn1.ASN1EncodableVector; import org.bouncycastle.asn1.ASN1Enumerated; import org.bouncycastle.asn1.ASN1GeneralizedTime; import org.bouncycastle.asn1.ASN1Integer; import org.bouncycastle.asn1.ASN1Object; import org.bouncycastle.asn1.ASN1ObjectIdentifier; import org.bouncycastle.asn1.ASN1TaggedObject; import org.bouncycastle.asn1.ASN1UTCTime; import org.bouncycastle.asn1.DERBMPString; import org.bouncycastle.asn1.DERBitString; import org.bouncycastle.asn1.DERGeneralString; import org.bouncycastle.asn1.DERIA5String; import org.bouncycastle.asn1.DERNull; import org.bouncycastle.asn1.DERNumericString; import org.bouncycastle.asn1.DEROctetString; import org.bouncycastle.asn1.DERPrintableString; import org.bouncycastle.asn1.DERSequence; import org.bouncycastle.asn1.DERSet; import org.bouncycastle.asn1.DERT61String; import org.bouncycastle.asn1.DERTaggedObject; import org.bouncycastle.asn1.DERUTF8String; import org.bouncycastle.asn1.DERUniversalString; import org.bouncycastle.asn1.DERVisibleString; import org.bouncycastle.asn1.cmp.CAKeyUpdAnnContent; import org.bouncycastle.asn1.cmp.CMPCertificate; import org.bouncycastle.asn1.cmp.CRLAnnContent; import org.bouncycastle.asn1.cmp.CertConfirmContent; import org.bouncycastle.asn1.cmp.CertOrEncCert; import org.bouncycastle.asn1.cmp.CertRepMessage; import org.bouncycastle.asn1.cmp.CertResponse; import org.bouncycastle.asn1.cmp.CertifiedKeyPair; import org.bouncycastle.asn1.cmp.Challenge; import org.bouncycastle.asn1.cmp.ErrorMsgContent; import org.bouncycastle.asn1.cmp.GenMsgContent; import org.bouncycastle.asn1.cmp.GenRepContent; import org.bouncycastle.asn1.cmp.InfoTypeAndValue; import org.bouncycastle.asn1.cmp.KeyRecRepContent; import org.bouncycastle.asn1.cmp.OOBCertHash; import org.bouncycastle.asn1.cmp.PBMParameter; import org.bouncycastle.asn1.cmp.PKIBody; import org.bouncycastle.asn1.cmp.PKIConfirmContent; import org.bouncycastle.asn1.cmp.PKIFailureInfo; import org.bouncycastle.asn1.cmp.PKIFreeText; import org.bouncycastle.asn1.cmp.PKIHeader; import org.bouncycastle.asn1.cmp.PKIMessage; import org.bouncycastle.asn1.cmp.PKIMessages; import org.bouncycastle.asn1.cmp.PKIStatus; import org.bouncycastle.asn1.cmp.PKIStatusInfo; import org.bouncycastle.asn1.cmp.POPODecKeyChallContent; import org.bouncycastle.asn1.cmp.POPODecKeyRespContent; import org.bouncycastle.asn1.cmp.PollRepContent; import org.bouncycastle.asn1.cmp.PollReqContent; import org.bouncycastle.asn1.cmp.ProtectedPart; import org.bouncycastle.asn1.cmp.RevAnnContent; import org.bouncycastle.asn1.cmp.RevDetails; import org.bouncycastle.asn1.cmp.RevRepContent; import org.bouncycastle.asn1.cmp.RevReqContent; import org.bouncycastle.asn1.cms.Attribute; import org.bouncycastle.asn1.cms.Attributes; import org.bouncycastle.asn1.cms.AuthEnvelopedData; import org.bouncycastle.asn1.cms.AuthenticatedData; import org.bouncycastle.asn1.cms.CompressedData; import org.bouncycastle.asn1.cms.ContentInfo; import org.bouncycastle.asn1.cms.EncryptedContentInfo; import org.bouncycastle.asn1.cms.EncryptedData; import org.bouncycastle.asn1.cms.EnvelopedData; import org.bouncycastle.asn1.cms.Evidence; import org.bouncycastle.asn1.cms.IssuerAndSerialNumber; import org.bouncycastle.asn1.cms.KEKIdentifier; import org.bouncycastle.asn1.cms.KEKRecipientInfo; import org.bouncycastle.asn1.cms.KeyAgreeRecipientIdentifier; import org.bouncycastle.asn1.cms.KeyAgreeRecipientInfo; import org.bouncycastle.asn1.cms.KeyTransRecipientInfo; import org.bouncycastle.asn1.cms.MetaData; import org.bouncycastle.asn1.cms.OriginatorIdentifierOrKey; import org.bouncycastle.asn1.cms.OriginatorInfo; import org.bouncycastle.asn1.cms.OriginatorPublicKey; import org.bouncycastle.asn1.cms.OtherKeyAttribute; import org.bouncycastle.asn1.cms.OtherRecipientInfo; import org.bouncycastle.asn1.cms.PasswordRecipientInfo; import org.bouncycastle.asn1.cms.RecipientEncryptedKey; import org.bouncycastle.asn1.cms.RecipientIdentifier; import org.bouncycastle.asn1.cms.RecipientInfo; import org.bouncycastle.asn1.cms.RecipientKeyIdentifier; import org.bouncycastle.asn1.cms.SignerIdentifier; import org.bouncycastle.asn1.cms.SignerInfo; import org.bouncycastle.asn1.cms.TimeStampAndCRL; import org.bouncycastle.asn1.cms.TimeStampTokenEvidence; import org.bouncycastle.asn1.cms.TimeStampedData; import org.bouncycastle.asn1.cms.ecc.MQVuserKeyingMaterial; import org.bouncycastle.asn1.crmf.AttributeTypeAndValue; import org.bouncycastle.asn1.crmf.CertId; import org.bouncycastle.asn1.crmf.CertReqMessages; import org.bouncycastle.asn1.crmf.CertReqMsg; import org.bouncycastle.asn1.crmf.CertRequest; import org.bouncycastle.asn1.crmf.CertTemplate; import org.bouncycastle.asn1.crmf.Controls; import org.bouncycastle.asn1.crmf.EncKeyWithID; import org.bouncycastle.asn1.crmf.EncryptedKey; import org.bouncycastle.asn1.crmf.EncryptedValue; import org.bouncycastle.asn1.crmf.OptionalValidity; import org.bouncycastle.asn1.crmf.PKIArchiveOptions; import org.bouncycastle.asn1.crmf.PKIPublicationInfo; import org.bouncycastle.asn1.crmf.PKMACValue; import org.bouncycastle.asn1.crmf.POPOPrivKey; import org.bouncycastle.asn1.crmf.POPOSigningKey; import org.bouncycastle.asn1.crmf.POPOSigningKeyInput; import org.bouncycastle.asn1.crmf.ProofOfPossession; import org.bouncycastle.asn1.crmf.SinglePubInfo; import org.bouncycastle.asn1.cryptopro.ECGOST3410ParamSetParameters; import org.bouncycastle.asn1.cryptopro.GOST28147Parameters; import org.bouncycastle.asn1.cryptopro.GOST3410ParamSetParameters; import org.bouncycastle.asn1.cryptopro.GOST3410PublicKeyAlgParameters; import org.bouncycastle.asn1.eac.CVCertificate; import org.bouncycastle.asn1.eac.CVCertificateRequest; import org.bouncycastle.asn1.eac.CertificateBody; import org.bouncycastle.asn1.eac.PublicKeyDataObject; import org.bouncycastle.asn1.eac.RSAPublicKey; import org.bouncycastle.asn1.eac.UnsignedInteger; import org.bouncycastle.asn1.esf.CommitmentTypeIndication; import org.bouncycastle.asn1.esf.CommitmentTypeQualifier; import org.bouncycastle.asn1.esf.CompleteRevocationRefs; import org.bouncycastle.asn1.esf.CrlIdentifier; import org.bouncycastle.asn1.esf.CrlListID; import org.bouncycastle.asn1.esf.CrlOcspRef; import org.bouncycastle.asn1.esf.CrlValidatedID; import org.bouncycastle.asn1.esf.OcspIdentifier; import org.bouncycastle.asn1.esf.OcspListID; import org.bouncycastle.asn1.esf.OcspResponsesID; import org.bouncycastle.asn1.esf.OtherHash; import org.bouncycastle.asn1.esf.OtherHashAlgAndValue; import org.bouncycastle.asn1.esf.OtherRevRefs; import org.bouncycastle.asn1.esf.OtherRevVals; import org.bouncycastle.asn1.esf.RevocationValues; import org.bouncycastle.asn1.esf.SPUserNotice; import org.bouncycastle.asn1.esf.SPuri; import org.bouncycastle.asn1.esf.SigPolicyQualifierInfo; import org.bouncycastle.asn1.esf.SigPolicyQualifiers; import org.bouncycastle.asn1.esf.SignaturePolicyId; import org.bouncycastle.asn1.esf.SignaturePolicyIdentifier; import org.bouncycastle.asn1.esf.SignerAttribute; import org.bouncycastle.asn1.esf.SignerLocation; import org.bouncycastle.asn1.ess.ContentHints; import org.bouncycastle.asn1.ess.ContentIdentifier; import org.bouncycastle.asn1.ess.ESSCertID; import org.bouncycastle.asn1.ess.ESSCertIDv2; import org.bouncycastle.asn1.ess.OtherCertID; import org.bouncycastle.asn1.ess.OtherSigningCertificate; import org.bouncycastle.asn1.ess.SigningCertificate; import org.bouncycastle.asn1.ess.SigningCertificateV2; import org.bouncycastle.asn1.icao.CscaMasterList; import org.bouncycastle.asn1.icao.DataGroupHash; import org.bouncycastle.asn1.icao.LDSSecurityObject; import org.bouncycastle.asn1.icao.LDSVersionInfo; import org.bouncycastle.asn1.isismtt.ocsp.CertHash; import org.bouncycastle.asn1.isismtt.ocsp.RequestedCertificate; import org.bouncycastle.asn1.isismtt.x509.AdditionalInformationSyntax; import org.bouncycastle.asn1.isismtt.x509.AdmissionSyntax; import org.bouncycastle.asn1.isismtt.x509.Admissions; import org.bouncycastle.asn1.isismtt.x509.DeclarationOfMajority; import org.bouncycastle.asn1.isismtt.x509.MonetaryLimit; import org.bouncycastle.asn1.isismtt.x509.NamingAuthority; import org.bouncycastle.asn1.isismtt.x509.ProcurationSyntax; import org.bouncycastle.asn1.isismtt.x509.ProfessionInfo; import org.bouncycastle.asn1.isismtt.x509.Restriction; import org.bouncycastle.asn1.misc.CAST5CBCParameters; import org.bouncycastle.asn1.misc.IDEACBCPar; import org.bouncycastle.asn1.mozilla.PublicKeyAndChallenge; import org.bouncycastle.asn1.ocsp.BasicOCSPResponse; import org.bouncycastle.asn1.ocsp.CertID; import org.bouncycastle.asn1.ocsp.CertStatus; import org.bouncycastle.asn1.ocsp.CrlID; import org.bouncycastle.asn1.ocsp.OCSPRequest; import org.bouncycastle.asn1.ocsp.OCSPResponse; import org.bouncycastle.asn1.ocsp.OCSPResponseStatus; import org.bouncycastle.asn1.ocsp.Request; import org.bouncycastle.asn1.ocsp.ResponderID; import org.bouncycastle.asn1.ocsp.ResponseBytes; import org.bouncycastle.asn1.ocsp.ResponseData; import org.bouncycastle.asn1.ocsp.RevokedInfo; import org.bouncycastle.asn1.ocsp.Signature; import org.bouncycastle.asn1.ocsp.SingleResponse; import org.bouncycastle.asn1.ocsp.TBSRequest; import org.bouncycastle.asn1.oiw.OIWObjectIdentifiers; import org.bouncycastle.asn1.pkcs.AuthenticatedSafe; import org.bouncycastle.asn1.pkcs.CertificationRequest; import org.bouncycastle.asn1.pkcs.CertificationRequestInfo; import org.bouncycastle.asn1.pkcs.DHParameter; import org.bouncycastle.asn1.pkcs.EncryptedPrivateKeyInfo; import org.bouncycastle.asn1.pkcs.MacData; import org.bouncycastle.asn1.pkcs.PBEParameter; import org.bouncycastle.asn1.pkcs.PBES2Parameters; import org.bouncycastle.asn1.pkcs.PBKDF2Params; import org.bouncycastle.asn1.pkcs.PKCS12PBEParams; import org.bouncycastle.asn1.pkcs.Pfx; import org.bouncycastle.asn1.pkcs.PrivateKeyInfo; import org.bouncycastle.asn1.pkcs.RC2CBCParameter; import org.bouncycastle.asn1.pkcs.RSAESOAEPparams; import org.bouncycastle.asn1.pkcs.RSAPrivateKey; import org.bouncycastle.asn1.pkcs.RSASSAPSSparams; import org.bouncycastle.asn1.pkcs.SafeBag; import org.bouncycastle.asn1.pkcs.SignedData; import org.bouncycastle.asn1.sec.ECPrivateKey; import org.bouncycastle.asn1.smime.SMIMECapabilities; import org.bouncycastle.asn1.smime.SMIMECapability; import org.bouncycastle.asn1.tsp.Accuracy; import org.bouncycastle.asn1.tsp.MessageImprint; import org.bouncycastle.asn1.tsp.TSTInfo; import org.bouncycastle.asn1.tsp.TimeStampReq; import org.bouncycastle.asn1.tsp.TimeStampResp; import org.bouncycastle.asn1.x500.DirectoryString; import org.bouncycastle.asn1.x500.RDN; import org.bouncycastle.asn1.x500.X500Name; import org.bouncycastle.asn1.x509.AccessDescription; import org.bouncycastle.asn1.x509.AlgorithmIdentifier; import org.bouncycastle.asn1.x509.AttCertIssuer; import org.bouncycastle.asn1.x509.AttCertValidityPeriod; import org.bouncycastle.asn1.x509.AttributeCertificate; import org.bouncycastle.asn1.x509.AttributeCertificateInfo; import org.bouncycastle.asn1.x509.AuthorityInformationAccess; import org.bouncycastle.asn1.x509.AuthorityKeyIdentifier; import org.bouncycastle.asn1.x509.BasicConstraints; import org.bouncycastle.asn1.x509.CRLDistPoint; import org.bouncycastle.asn1.x509.CRLNumber; import org.bouncycastle.asn1.x509.CRLReason; import org.bouncycastle.asn1.x509.Certificate; import org.bouncycastle.asn1.x509.CertificateList; import org.bouncycastle.asn1.x509.CertificatePair; import org.bouncycastle.asn1.x509.CertificatePolicies; import org.bouncycastle.asn1.x509.DSAParameter; import org.bouncycastle.asn1.x509.DigestInfo; import org.bouncycastle.asn1.x509.DisplayText; import org.bouncycastle.asn1.x509.DistributionPoint; import org.bouncycastle.asn1.x509.DistributionPointName; import org.bouncycastle.asn1.x509.ExtendedKeyUsage; import org.bouncycastle.asn1.x509.Extensions; import org.bouncycastle.asn1.x509.GeneralName; import org.bouncycastle.asn1.x509.GeneralNames; import org.bouncycastle.asn1.x509.GeneralSubtree; import org.bouncycastle.asn1.x509.Holder; import org.bouncycastle.asn1.x509.IetfAttrSyntax; import org.bouncycastle.asn1.x509.IssuerSerial; import org.bouncycastle.asn1.x509.IssuingDistributionPoint; import org.bouncycastle.asn1.x509.NameConstraints; import org.bouncycastle.asn1.x509.NoticeReference; import org.bouncycastle.asn1.x509.ObjectDigestInfo; import org.bouncycastle.asn1.x509.PolicyInformation; import org.bouncycastle.asn1.x509.PolicyMappings; import org.bouncycastle.asn1.x509.PolicyQualifierInfo; import org.bouncycastle.asn1.x509.PrivateKeyUsagePeriod; import org.bouncycastle.asn1.x509.RSAPublicKeyStructure; import org.bouncycastle.asn1.x509.RoleSyntax; import org.bouncycastle.asn1.x509.SubjectDirectoryAttributes; import org.bouncycastle.asn1.x509.SubjectKeyIdentifier; import org.bouncycastle.asn1.x509.SubjectPublicKeyInfo; import org.bouncycastle.asn1.x509.TBSCertList; import org.bouncycastle.asn1.x509.TBSCertificate; import org.bouncycastle.asn1.x509.TBSCertificateStructure; import org.bouncycastle.asn1.x509.Target; import org.bouncycastle.asn1.x509.TargetInformation; import org.bouncycastle.asn1.x509.Targets; import org.bouncycastle.asn1.x509.Time; import org.bouncycastle.asn1.x509.UserNotice; import org.bouncycastle.asn1.x509.V2Form; import org.bouncycastle.asn1.x509.X509CertificateStructure; import org.bouncycastle.asn1.x509.X509Extensions; import org.bouncycastle.asn1.x509.X509Name; import org.bouncycastle.asn1.x509.qualified.BiometricData; import org.bouncycastle.asn1.x509.qualified.Iso4217CurrencyCode; import org.bouncycastle.asn1.x509.qualified.MonetaryValue; import org.bouncycastle.asn1.x509.qualified.QCStatement; import org.bouncycastle.asn1.x509.qualified.SemanticsInformation; import org.bouncycastle.asn1.x509.qualified.TypeOfBiometricData; import org.bouncycastle.asn1.x509.sigi.NameOrPseudonym; import org.bouncycastle.asn1.x509.sigi.PersonalData; import org.bouncycastle.asn1.x9.DHDomainParameters; import org.bouncycastle.asn1.x9.DHPublicKey; import org.bouncycastle.asn1.x9.DHValidationParms; import org.bouncycastle.asn1.x9.X962Parameters; import org.bouncycastle.asn1.x9.X9ECParameters; import org.bouncycastle.util.Integers; import org.bouncycastle.util.encoders.Base64; public class GetInstanceTest extends TestCase { public static byte[] attrCert = Base64.decode( "MIIHQDCCBqkCAQEwgZChgY2kgYowgYcxHDAaBgkqhkiG9w0BCQEWDW1sb3JjaEB2" + "dC5lZHUxHjAcBgNVBAMTFU1hcmt1cyBMb3JjaCAobWxvcmNoKTEbMBkGA1UECxMS" + "VmlyZ2luaWEgVGVjaCBVc2VyMRAwDgYDVQQLEwdDbGFzcyAyMQswCQYDVQQKEwJ2" + "dDELMAkGA1UEBhMCVVMwgYmkgYYwgYMxGzAZBgkqhkiG9w0BCQEWDHNzaGFoQHZ0" + "LmVkdTEbMBkGA1UEAxMSU3VtaXQgU2hhaCAoc3NoYWgpMRswGQYDVQQLExJWaXJn" + "aW5pYSBUZWNoIFVzZXIxEDAOBgNVBAsTB0NsYXNzIDExCzAJBgNVBAoTAnZ0MQsw" + "CQYDVQQGEwJVUzANBgkqhkiG9w0BAQQFAAIBBTAiGA8yMDAzMDcxODE2MDgwMloY" + "DzIwMDMwNzI1MTYwODAyWjCCBU0wggVJBgorBgEEAbRoCAEBMYIFORaCBTU8UnVs" + "ZSBSdWxlSWQ9IkZpbGUtUHJpdmlsZWdlLVJ1bGUiIEVmZmVjdD0iUGVybWl0Ij4K" + "IDxUYXJnZXQ+CiAgPFN1YmplY3RzPgogICA8U3ViamVjdD4KICAgIDxTdWJqZWN0" + "TWF0Y2ggTWF0Y2hJZD0idXJuOm9hc2lzOm5hbWVzOnRjOnhhY21sOjEuMDpmdW5j" + "dGlvbjpzdHJpbmctZXF1YWwiPgogICAgIDxBdHRyaWJ1dGVWYWx1ZSBEYXRhVHlw" + "ZT0iaHR0cDovL3d3dy53My5vcmcvMjAwMS9YTUxTY2hlbWEjc3RyaW5nIj4KICAg" + "ICAgIENOPU1hcmt1cyBMb3JjaDwvQXR0cmlidXRlVmFsdWU+CiAgICAgPFN1Ympl" + "Y3RBdHRyaWJ1dGVEZXNpZ25hdG9yIEF0dHJpYnV0ZUlkPSJ1cm46b2FzaXM6bmFt" + "ZXM6dGM6eGFjbWw6MS4wOnN1YmplY3Q6c3ViamVjdC1pZCIgRGF0YVR5cGU9Imh0" + "dHA6Ly93d3cudzMub3JnLzIwMDEvWE1MU2NoZW1hI3N0cmluZyIgLz4gCiAgICA8" + "L1N1YmplY3RNYXRjaD4KICAgPC9TdWJqZWN0PgogIDwvU3ViamVjdHM+CiAgPFJl" + "c291cmNlcz4KICAgPFJlc291cmNlPgogICAgPFJlc291cmNlTWF0Y2ggTWF0Y2hJ" + "ZD0idXJuOm9hc2lzOm5hbWVzOnRjOnhhY21sOjEuMDpmdW5jdGlvbjpzdHJpbmct" + "ZXF1YWwiPgogICAgIDxBdHRyaWJ1dGVWYWx1ZSBEYXRhVHlwZT0iaHR0cDovL3d3" + "dy53My5vcmcvMjAwMS9YTUxTY2hlbWEjYW55VVJJIj4KICAgICAgaHR0cDovL3p1" + "bmkuY3MudnQuZWR1PC9BdHRyaWJ1dGVWYWx1ZT4KICAgICA8UmVzb3VyY2VBdHRy" + "aWJ1dGVEZXNpZ25hdG9yIEF0dHJpYnV0ZUlkPSJ1cm46b2FzaXM6bmFtZXM6dGM6" + "eGFjbWw6MS4wOnJlc291cmNlOnJlc291cmNlLWlkIiBEYXRhVHlwZT0iaHR0cDov" + "L3d3dy53My5vcmcvMjAwMS9YTUxTY2hlbWEjYW55VVJJIiAvPiAKICAgIDwvUmVz" + "b3VyY2VNYXRjaD4KICAgPC9SZXNvdXJjZT4KICA8L1Jlc291cmNlcz4KICA8QWN0" + "aW9ucz4KICAgPEFjdGlvbj4KICAgIDxBY3Rpb25NYXRjaCBNYXRjaElkPSJ1cm46" + "b2FzaXM6bmFtZXM6dGM6eGFjbWw6MS4wOmZ1bmN0aW9uOnN0cmluZy1lcXVhbCI+" + "CiAgICAgPEF0dHJpYnV0ZVZhbHVlIERhdGFUeXBlPSJodHRwOi8vd3d3LnczLm9y" + "Zy8yMDAxL1hNTFNjaGVtYSNzdHJpbmciPgpEZWxlZ2F0ZSBBY2Nlc3MgICAgIDwv" + "QXR0cmlidXRlVmFsdWU+CgkgIDxBY3Rpb25BdHRyaWJ1dGVEZXNpZ25hdG9yIEF0" + "dHJpYnV0ZUlkPSJ1cm46b2FzaXM6bmFtZXM6dGM6eGFjbWw6MS4wOmFjdGlvbjph" + "Y3Rpb24taWQiIERhdGFUeXBlPSJodHRwOi8vd3d3LnczLm9yZy8yMDAxL1hNTFNj" + "aGVtYSNzdHJpbmciIC8+IAogICAgPC9BY3Rpb25NYXRjaD4KICAgPC9BY3Rpb24+" + "CiAgPC9BY3Rpb25zPgogPC9UYXJnZXQ+CjwvUnVsZT4KMA0GCSqGSIb3DQEBBAUA" + "A4GBAGiJSM48XsY90HlYxGmGVSmNR6ZW2As+bot3KAfiCIkUIOAqhcphBS23egTr" + "6asYwy151HshbPNYz+Cgeqs45KkVzh7bL/0e1r8sDVIaaGIkjHK3CqBABnfSayr3" + "Rd1yBoDdEv8Qb+3eEPH6ab9021AsLEnJ6LWTmybbOpMNZ3tv"); byte[] cert1 = Base64.decode( "MIIDXjCCAsegAwIBAgIBBzANBgkqhkiG9w0BAQQFADCBtzELMAkGA1UEBhMCQVUx" + "ETAPBgNVBAgTCFZpY3RvcmlhMRgwFgYDVQQHEw9Tb3V0aCBNZWxib3VybmUxGjAY" + "BgNVBAoTEUNvbm5lY3QgNCBQdHkgTHRkMR4wHAYDVQQLExVDZXJ0aWZpY2F0ZSBB" + "dXRob3JpdHkxFTATBgNVBAMTDENvbm5lY3QgNCBDQTEoMCYGCSqGSIb3DQEJARYZ" + "d2VibWFzdGVyQGNvbm5lY3Q0LmNvbS5hdTAeFw0wMDA2MDIwNzU2MjFaFw0wMTA2" + "MDIwNzU2MjFaMIG4MQswCQYDVQQGEwJBVTERMA8GA1UECBMIVmljdG9yaWExGDAW" + "BgNVBAcTD1NvdXRoIE1lbGJvdXJuZTEaMBgGA1UEChMRQ29ubmVjdCA0IFB0eSBM" + "dGQxFzAVBgNVBAsTDldlYnNlcnZlciBUZWFtMR0wGwYDVQQDExR3d3cyLmNvbm5l" + "Y3Q0LmNvbS5hdTEoMCYGCSqGSIb3DQEJARYZd2VibWFzdGVyQGNvbm5lY3Q0LmNv" + "bS5hdTCBnzANBgkqhkiG9w0BAQEFAAOBjQAwgYkCgYEArvDxclKAhyv7Q/Wmr2re" + "Gw4XL9Cnh9e+6VgWy2AWNy/MVeXdlxzd7QAuc1eOWQkGQEiLPy5XQtTY+sBUJ3AO" + "Rvd2fEVJIcjf29ey7bYua9J/vz5MG2KYo9/WCHIwqD9mmG9g0xLcfwq/s8ZJBswE" + "7sb85VU+h94PTvsWOsWuKaECAwEAAaN3MHUwJAYDVR0RBB0wG4EZd2VibWFzdGVy" + "QGNvbm5lY3Q0LmNvbS5hdTA6BglghkgBhvhCAQ0ELRYrbW9kX3NzbCBnZW5lcmF0" + "ZWQgY3VzdG9tIHNlcnZlciBjZXJ0aWZpY2F0ZTARBglghkgBhvhCAQEEBAMCBkAw" + "DQYJKoZIhvcNAQEEBQADgYEAotccfKpwSsIxM1Hae8DR7M/Rw8dg/RqOWx45HNVL" + "iBS4/3N/TO195yeQKbfmzbAA2jbPVvIvGgTxPgO1MP4ZgvgRhasaa0qCJCkWvpM4" + "yQf33vOiYQbpv4rTwzU8AmRlBG45WdjyNIigGV+oRc61aKCTnLq7zB8N3z1TF/bF" + "5/8="); private byte[] v2CertList = Base64.decode( "MIICjTCCAfowDQYJKoZIhvcNAQECBQAwXzELMAkGA1UEBhMCVVMxIDAeBgNVBAoT" + "F1JTQSBEYXRhIFNlY3VyaXR5LCBJbmMuMS4wLAYDVQQLEyVTZWN1cmUgU2VydmVy" + "IENlcnRpZmljYXRpb24gQXV0aG9yaXR5Fw05NTA1MDIwMjEyMjZaFw05NTA2MDEw" + "MDAxNDlaMIIBaDAWAgUCQQAABBcNOTUwMjAxMTcyNDI2WjAWAgUCQQAACRcNOTUw" + "MjEwMDIxNjM5WjAWAgUCQQAADxcNOTUwMjI0MDAxMjQ5WjAWAgUCQQAADBcNOTUw" + "MjI1MDA0NjQ0WjAWAgUCQQAAGxcNOTUwMzEzMTg0MDQ5WjAWAgUCQQAAFhcNOTUw" + "MzE1MTkxNjU0WjAWAgUCQQAAGhcNOTUwMzE1MTk0MDQxWjAWAgUCQQAAHxcNOTUw" + "MzI0MTk0NDMzWjAWAgUCcgAABRcNOTUwMzI5MjAwNzExWjAWAgUCcgAAERcNOTUw" + "MzMwMDIzNDI2WjAWAgUCQQAAIBcNOTUwNDA3MDExMzIxWjAWAgUCcgAAHhcNOTUw" + "NDA4MDAwMjU5WjAWAgUCcgAAQRcNOTUwNDI4MTcxNzI0WjAWAgUCcgAAOBcNOTUw" + "NDI4MTcyNzIxWjAWAgUCcgAATBcNOTUwNTAyMDIxMjI2WjANBgkqhkiG9w0BAQIF" + "AAN+AHqOEJXSDejYy0UwxxrH/9+N2z5xu/if0J6qQmK92W0hW158wpJg+ovV3+wQ" + "wvIEPRL2rocL0tKfAsVq1IawSJzSNgxG0lrcla3MrJBnZ4GaZDu4FutZh72MR3Gt" + "JaAL3iTJHJD55kK2D/VoyY1djlsPuNh6AEgdVwFAyp0v"); private static final Object[] NULL_ARGS = new Object[] { null }; private void doFullGetInstanceTest(Class clazz, ASN1Object o1) throws Exception { Method m; try { m = clazz.getMethod("getInstance", Object.class); } catch (NoSuchMethodException e) { fail("no getInstance method found"); return; } ASN1Object o2 = (ASN1Object)m.invoke(clazz, NULL_ARGS); if (o2 != null) { fail(clazz.getName() + " null failed"); } o2 = (ASN1Object)m.invoke(clazz, o1); if (!o1.equals(o2) || !clazz.isInstance(o2)) { fail(clazz.getName() + " equality failed"); } o2 = (ASN1Object)m.invoke(clazz, o1.getEncoded()); if (!o1.equals(o2) || !clazz.isInstance(o2)) { fail(clazz.getName() + " encoded equality failed"); } o2 = (ASN1Object)m.invoke(clazz, o1.toASN1Primitive()); if (!o1.equals(o2) || !clazz.isInstance(o2)) { fail(clazz.getName() + " sequence equality failed"); } try { m = clazz.getMethod("getInstance", ASN1TaggedObject.class, Boolean.TYPE); } catch (NoSuchMethodException e) { return; } ASN1TaggedObject t = new DERTaggedObject(true, 0, o1); o2 = (ASN1Object)m.invoke(clazz, t, true); if (!o1.equals(o2) || !clazz.isInstance(o2)) { fail(clazz.getName() + " tag equality failed"); } t = new DERTaggedObject(true, 0, o1.toASN1Primitive()); o2 = (ASN1Object)m.invoke(clazz, t, true); if (!o1.equals(o2) || !clazz.isInstance(o2)) { fail(clazz.getName() + " tag equality failed"); } t = ASN1TaggedObject.getInstance(t.getEncoded()); o2 = (ASN1Object)m.invoke(clazz, t, true); if (!o1.equals(o2) || !clazz.isInstance(o2)) { fail(clazz.getName() + " tag equality failed"); } t = new DERTaggedObject(false, 0, o1); o2 = (ASN1Object)m.invoke(clazz, t, false); if (!o1.equals(o2) || !clazz.isInstance(o2)) { fail(clazz.getName() + " tag equality failed"); } t = new DERTaggedObject(false, 0, o1.toASN1Primitive()); o2 = (ASN1Object)m.invoke(clazz, t, false); if (!o1.equals(o2) || !clazz.isInstance(o2)) { fail(clazz.getName() + " tag equality failed"); } t = ASN1TaggedObject.getInstance(t.getEncoded()); o2 = (ASN1Object)m.invoke(clazz, t, false); if (!o1.equals(o2) || !clazz.isInstance(o2)) { fail(clazz.getName() + " tag equality failed"); } } public void testGetInstance() throws Exception { doFullGetInstanceTest(DERPrintableString.class, new DERPrintableString("hello world")); doFullGetInstanceTest(DERBMPString.class, new DERBMPString("hello world")); doFullGetInstanceTest(DERUTF8String.class, new DERUTF8String("hello world")); doFullGetInstanceTest(DERUniversalString.class, new DERUniversalString(new byte[20])); doFullGetInstanceTest(DERIA5String.class, new DERIA5String("hello world")); doFullGetInstanceTest(DERGeneralString.class, new DERGeneralString("hello world")); doFullGetInstanceTest(DERNumericString.class, new DERNumericString("hello world")); doFullGetInstanceTest(DERNumericString.class, new DERNumericString("99999", true)); doFullGetInstanceTest(DERT61String.class, new DERT61String("hello world")); doFullGetInstanceTest(DERVisibleString.class, new DERVisibleString("hello world")); doFullGetInstanceTest(ASN1Integer.class, new ASN1Integer(1)); doFullGetInstanceTest(ASN1GeneralizedTime.class, new ASN1GeneralizedTime(new Date())); doFullGetInstanceTest(ASN1UTCTime.class, new ASN1UTCTime(new Date())); doFullGetInstanceTest(ASN1Enumerated.class, new ASN1Enumerated(1)); CMPCertificate cmpCert = new CMPCertificate(Certificate.getInstance(cert1)); CertificateList crl = CertificateList.getInstance(v2CertList); AttributeCertificate attributeCert = AttributeCertificate.getInstance(attrCert); doFullGetInstanceTest(CAKeyUpdAnnContent.class, new CAKeyUpdAnnContent(cmpCert, cmpCert, cmpCert)); CertConfirmContent.getInstance(null); CertifiedKeyPair.getInstance(null); CertOrEncCert.getInstance(null); CertRepMessage.getInstance(null); doFullGetInstanceTest(CertResponse.class, new CertResponse(new ASN1Integer(1), new PKIStatusInfo(PKIStatus.granted))); doFullGetInstanceTest(org.bouncycastle.asn1.cmp.CertStatus.class, new org.bouncycastle.asn1.cmp.CertStatus(new byte[10], BigInteger.valueOf(1), new PKIStatusInfo(PKIStatus.granted))); doFullGetInstanceTest(Challenge.class, new Challenge(new AlgorithmIdentifier(OIWObjectIdentifiers.idSHA1, DERNull.INSTANCE), new byte[10], new byte[10])); doFullGetInstanceTest(CMPCertificate.class, cmpCert); doFullGetInstanceTest(CRLAnnContent.class, new CRLAnnContent(crl)); doFullGetInstanceTest(ErrorMsgContent.class, new ErrorMsgContent(new PKIStatusInfo(PKIStatus.granted), new ASN1Integer(1), new PKIFreeText("fred"))); GenMsgContent.getInstance(null); GenRepContent.getInstance(null); InfoTypeAndValue.getInstance(null); KeyRecRepContent.getInstance(null); OOBCertHash.getInstance(null); PBMParameter.getInstance(null); PKIBody.getInstance(null); PKIConfirmContent.getInstance(null); PKIFreeText.getInstance(null); doFullGetInstanceTest(PKIFreeText.class, new PKIFreeText("hello world")); doFullGetInstanceTest(PKIFreeText.class, new PKIFreeText(new String[]{"hello", "world"})); doFullGetInstanceTest(PKIFreeText.class, new PKIFreeText(new DERUTF8String[]{new DERUTF8String("hello"), new DERUTF8String("world")})); PKIHeader.getInstance(null); PKIMessage.getInstance(null); PKIMessages.getInstance(null); doFullGetInstanceTest(PKIStatusInfo.class, new PKIStatusInfo(PKIStatus.rejection, new PKIFreeText("hello world"), new PKIFailureInfo(PKIFailureInfo.badAlg))); doFullGetInstanceTest(PKIStatusInfo.class, new PKIStatusInfo(PKIStatus.granted, new PKIFreeText("hello world"))); PKIStatus.getInstance(null); PollRepContent.getInstance(null); PollReqContent.getInstance(null); POPODecKeyChallContent.getInstance(null); POPODecKeyRespContent.getInstance(null); ProtectedPart.getInstance(null); RevAnnContent.getInstance(null); RevDetails.getInstance(null); RevRepContent.getInstance(null); RevReqContent.getInstance(null); Attribute.getInstance(null); Attributes.getInstance(null); AuthenticatedData.getInstance(null); AuthenticatedData.getInstance(null); AuthEnvelopedData.getInstance(null); AuthEnvelopedData.getInstance(null); CompressedData.getInstance(null); CompressedData.getInstance(null); ContentInfo.getInstance(null); EncryptedContentInfo.getInstance(null); EncryptedData.getInstance(null); EnvelopedData.getInstance(null); EnvelopedData.getInstance(null); Evidence.getInstance(null); IssuerAndSerialNumber.getInstance(null); KEKIdentifier.getInstance(null); KEKIdentifier.getInstance(null); KEKRecipientInfo.getInstance(null); KEKRecipientInfo.getInstance(null); KeyAgreeRecipientIdentifier.getInstance(null); KeyAgreeRecipientIdentifier.getInstance(null); KeyAgreeRecipientInfo.getInstance(null); KeyAgreeRecipientInfo.getInstance(null); KeyTransRecipientInfo.getInstance(null); MetaData.getInstance(null); OriginatorIdentifierOrKey.getInstance(null); OriginatorIdentifierOrKey.getInstance(null); OriginatorInfo.getInstance(null); OriginatorInfo.getInstance(null); OriginatorPublicKey.getInstance(null); OriginatorPublicKey.getInstance(null); OtherKeyAttribute.getInstance(null); OtherRecipientInfo.getInstance(null); OtherRecipientInfo.getInstance(null); PasswordRecipientInfo.getInstance(null); PasswordRecipientInfo.getInstance(null); RecipientEncryptedKey.getInstance(null); RecipientIdentifier.getInstance(null); RecipientInfo.getInstance(null); RecipientKeyIdentifier.getInstance(null); RecipientKeyIdentifier.getInstance(null); SignedData.getInstance(null); SignerIdentifier.getInstance(null); SignerInfo.getInstance(null); Time.getInstance(null); Time.getInstance(null); TimeStampAndCRL.getInstance(null); TimeStampedData.getInstance(null); TimeStampTokenEvidence.getInstance(null); AttributeTypeAndValue.getInstance(null); doFullGetInstanceTest(CertId.class, new CertId(new GeneralName(new X500Name("CN=Test")), BigInteger.valueOf(1))); CertReqMessages.getInstance(null); CertReqMsg.getInstance(null); CertRequest.getInstance(null); CertTemplate.getInstance(null); Controls.getInstance(null); EncKeyWithID.getInstance(null); EncryptedKey.getInstance(null); EncryptedValue.getInstance(null); OptionalValidity.getInstance(null); PKIArchiveOptions.getInstance(null); PKIPublicationInfo.getInstance(null); PKMACValue.getInstance(null); PKMACValue.getInstance(null); POPOPrivKey.getInstance(null); POPOSigningKeyInput.getInstance(null); POPOSigningKey.getInstance(null); POPOSigningKey.getInstance(null); ProofOfPossession.getInstance(null); SinglePubInfo.getInstance(null); ECGOST3410ParamSetParameters.getInstance(null); ECGOST3410ParamSetParameters.getInstance(null); GOST28147Parameters.getInstance(null); GOST28147Parameters.getInstance(null); GOST3410ParamSetParameters.getInstance(null); GOST3410ParamSetParameters.getInstance(null); GOST3410PublicKeyAlgParameters.getInstance(null); GOST3410PublicKeyAlgParameters.getInstance(null); CertificateBody.getInstance(null); CVCertificate.getInstance(null); CVCertificateRequest.getInstance(null); PublicKeyDataObject.getInstance(null); UnsignedInteger.getInstance(null); CommitmentTypeIndication.getInstance(null); CommitmentTypeQualifier.getInstance(null); OcspIdentifier ocspIdentifier = new OcspIdentifier(new ResponderID(new X500Name("CN=Test")), new ASN1GeneralizedTime(new Date())); CrlListID crlListID = new CrlListID(new CrlValidatedID[]{new CrlValidatedID(new OtherHash(new byte[20]))}); OcspListID ocspListID = new OcspListID(new OcspResponsesID[] { new OcspResponsesID(ocspIdentifier) }); OtherRevRefs otherRevRefs = new OtherRevRefs(new ASN1ObjectIdentifier("1.2.1"), new DERSequence()); OtherRevVals otherRevVals = new OtherRevVals(new ASN1ObjectIdentifier("1.2.1"), new DERSequence()); CrlOcspRef crlOcspRef = new CrlOcspRef(crlListID, ocspListID, otherRevRefs); doFullGetInstanceTest(CompleteRevocationRefs.class, new CompleteRevocationRefs(new CrlOcspRef[]{crlOcspRef, crlOcspRef})); doFullGetInstanceTest(CrlIdentifier.class, new CrlIdentifier(new X500Name("CN=Test"), new ASN1UTCTime(new Date()), BigInteger.valueOf(1))); doFullGetInstanceTest(CrlListID.class, crlListID); doFullGetInstanceTest(CrlOcspRef.class, crlOcspRef); doFullGetInstanceTest(CrlValidatedID.class, new CrlValidatedID(new OtherHash(new byte[20]))); doFullGetInstanceTest(OcspIdentifier.class, ocspIdentifier); doFullGetInstanceTest(OcspListID.class, ocspListID); doFullGetInstanceTest(OcspResponsesID.class, new OcspResponsesID(ocspIdentifier)); OtherHashAlgAndValue otherHashAlgAndValue = new OtherHashAlgAndValue(new AlgorithmIdentifier(OIWObjectIdentifiers.idSHA1, DERNull.INSTANCE), new DEROctetString(new byte[10])); doFullGetInstanceTest(OtherHashAlgAndValue.class, otherHashAlgAndValue); OtherHash.getInstance(null); doFullGetInstanceTest(OtherRevRefs.class, otherRevRefs); doFullGetInstanceTest(OtherRevVals.class, otherRevVals); doFullGetInstanceTest(RevocationValues.class, new RevocationValues(new CertificateList[]{crl}, null, otherRevVals)); SignaturePolicyId signaturePolicyId = new SignaturePolicyId(new ASN1ObjectIdentifier("1.2.1"), otherHashAlgAndValue); doFullGetInstanceTest(SignaturePolicyIdentifier.class, new SignaturePolicyIdentifier()); doFullGetInstanceTest(SignaturePolicyIdentifier.class, new SignaturePolicyIdentifier(signaturePolicyId)); doFullGetInstanceTest(SignaturePolicyId.class, signaturePolicyId); doFullGetInstanceTest(SignerAttribute.class, new SignerAttribute(new org.bouncycastle.asn1.x509.Attribute[]{new org.bouncycastle.asn1.x509.Attribute(new ASN1ObjectIdentifier("1.2.1"), new DERSet())})); doFullGetInstanceTest(SignerAttribute.class, new SignerAttribute(attributeCert)); ASN1EncodableVector postalAddr = new ASN1EncodableVector(); postalAddr.add(new DERUTF8String("line 1")); postalAddr.add(new DERUTF8String("line 2")); doFullGetInstanceTest(SignerLocation.class, new SignerLocation(new DERUTF8String("AU"), new DERUTF8String("Melbourne"), new DERSequence(postalAddr))); doFullGetInstanceTest(SigPolicyQualifierInfo.class, new SigPolicyQualifierInfo(new ASN1ObjectIdentifier("1.2.1"), new DERSequence())); SigPolicyQualifiers.getInstance(null); SPuri.getInstance(null); Vector v = new Vector(); v.add(Integers.valueOf(1)); v.add(BigInteger.valueOf(2)); NoticeReference noticeReference = new NoticeReference("BC", v); doFullGetInstanceTest(SPUserNotice.class, new SPUserNotice(noticeReference, new DisplayText("hello world"))); ContentHints.getInstance(null); ContentIdentifier.getInstance(null); ESSCertID.getInstance(null); ESSCertIDv2.getInstance(null); OtherCertID.getInstance(null); OtherSigningCertificate.getInstance(null); SigningCertificate.getInstance(null); SigningCertificateV2.getInstance(null); CscaMasterList.getInstance(null); DataGroupHash.getInstance(null); LDSSecurityObject.getInstance(null); LDSVersionInfo.getInstance(null); CAST5CBCParameters.getInstance(null); IDEACBCPar.getInstance(null); PublicKeyAndChallenge.getInstance(null); BasicOCSPResponse.getInstance(null); BasicOCSPResponse.getInstance(null); doFullGetInstanceTest(CertID.class, new CertID(new AlgorithmIdentifier(OIWObjectIdentifiers.idSHA1, DERNull.INSTANCE), new DEROctetString(new byte[1]), new DEROctetString(new byte[1]), new ASN1Integer(1))); CertStatus.getInstance(null); CertStatus.getInstance(null); CrlID.getInstance(null); OCSPRequest.getInstance(null); OCSPRequest.getInstance(null); OCSPResponse.getInstance(null); OCSPResponse.getInstance(null); OCSPResponseStatus.getInstance(null); Request.getInstance(null); Request.getInstance(null); ResponderID.getInstance(null); ResponderID.getInstance(null); ResponseBytes.getInstance(null); ResponseBytes.getInstance(null); ResponseData.getInstance(null); ResponseData.getInstance(null); RevokedInfo.getInstance(null); RevokedInfo.getInstance(null); Signature.getInstance(null); Signature.getInstance(null); SingleResponse.getInstance(null); SingleResponse.getInstance(null); TBSRequest.getInstance(null); TBSRequest.getInstance(null); Attribute.getInstance(null); AuthenticatedSafe.getInstance(null); CertificationRequestInfo.getInstance(null); CertificationRequest.getInstance(null); ContentInfo.getInstance(null); DHParameter.getInstance(null); EncryptedData.getInstance(null); EncryptedPrivateKeyInfo.getInstance(null); AlgorithmIdentifier.getInstance(null); IssuerAndSerialNumber.getInstance(null); MacData.getInstance(null); PBEParameter.getInstance(null); PBES2Parameters.getInstance(null); PBKDF2Params.getInstance(null); Pfx.getInstance(null); PKCS12PBEParams.getInstance(null); PrivateKeyInfo.getInstance(null); PrivateKeyInfo.getInstance(null); RC2CBCParameter.getInstance(null); RSAESOAEPparams.getInstance(null); RSAPrivateKey.getInstance(null); RSAPrivateKey.getInstance(null); RSAPublicKey.getInstance(null); RSAPublicKey.getInstance(null); RSASSAPSSparams.getInstance(null); SafeBag.getInstance(null); SignedData.getInstance(null); SignerInfo.getInstance(null); ECPrivateKey.getInstance(null); SMIMECapabilities.getInstance(null); SMIMECapability.getInstance(null); Accuracy.getInstance(null); MessageImprint.getInstance(null); TimeStampReq.getInstance(null); TimeStampResp.getInstance(null); TSTInfo.getInstance(null); AttributeTypeAndValue.getInstance(null); DirectoryString.getInstance(null); DirectoryString.getInstance(null); RDN.getInstance(null); X500Name.getInstance(null); X500Name.getInstance(null); AccessDescription.getInstance(null); AlgorithmIdentifier.getInstance(null); AlgorithmIdentifier.getInstance(null); AttCertIssuer.getInstance(null); AttCertIssuer.getInstance(null); AttCertValidityPeriod.getInstance(null); AttributeCertificateInfo.getInstance(null); AttributeCertificateInfo.getInstance(null); AttributeCertificate.getInstance(null); Attribute.getInstance(null); AuthorityInformationAccess.getInstance(null); AuthorityKeyIdentifier.getInstance(null); AuthorityKeyIdentifier.getInstance(null); BasicConstraints.getInstance(null); BasicConstraints.getInstance(null); Certificate.getInstance(null); Certificate.getInstance(null); CertificateList.getInstance(null); CertificateList.getInstance(null); CertificatePair.getInstance(null); CertificatePolicies.getInstance(null); CertificatePolicies.getInstance(null); CRLDistPoint.getInstance(null); CRLDistPoint.getInstance(null); CRLNumber.getInstance(null); CRLReason.getInstance(null); DigestInfo.getInstance(null); DigestInfo.getInstance(null); DisplayText.getInstance(null); DisplayText.getInstance(null); DistributionPoint.getInstance(null); DistributionPoint.getInstance(null); DistributionPointName.getInstance(null); DistributionPointName.getInstance(null); DSAParameter.getInstance(null); DSAParameter.getInstance(null); ExtendedKeyUsage.getInstance(null); ExtendedKeyUsage.getInstance(null); Extensions.getInstance(null); Extensions.getInstance(null); GeneralName.getInstance(null); GeneralName.getInstance(null); GeneralNames.getInstance(null); GeneralNames.getInstance(null); GeneralSubtree generalSubtree = new GeneralSubtree(new GeneralName(new X500Name("CN=Test"))); ASN1ObjectIdentifier algOid = new ASN1ObjectIdentifier("1.2.1"); ObjectDigestInfo objectDigestInfo = new ObjectDigestInfo(ObjectDigestInfo.otherObjectDigest, algOid, new AlgorithmIdentifier(algOid), new byte[20]); doFullGetInstanceTest(GeneralSubtree.class, generalSubtree); doFullGetInstanceTest(Holder.class, new Holder(objectDigestInfo)); IetfAttrSyntax.getInstance(null); IssuerSerial.getInstance(null); IssuerSerial.getInstance(null); IssuingDistributionPoint.getInstance(null); IssuingDistributionPoint.getInstance(null); DERBitString.getInstance(null); v.clear(); v.add(generalSubtree); doFullGetInstanceTest(NameConstraints.class, new NameConstraints(null, null)); doFullGetInstanceTest(NoticeReference.class, noticeReference); doFullGetInstanceTest(ObjectDigestInfo.class, objectDigestInfo); PolicyInformation.getInstance(null); PolicyMappings.getInstance(null); PolicyQualifierInfo.getInstance(null); PrivateKeyUsagePeriod.getInstance(null); doFullGetInstanceTest(RoleSyntax.class, new RoleSyntax(new GeneralNames(new GeneralName(new X500Name("CN=Test"))), new GeneralName(GeneralName.uniformResourceIdentifier, "http://bc"))); RSAPublicKeyStructure.getInstance(null); RSAPublicKeyStructure.getInstance(null); SubjectDirectoryAttributes.getInstance(null); SubjectKeyIdentifier.getInstance(null); SubjectKeyIdentifier.getInstance(null); SubjectPublicKeyInfo.getInstance(null); SubjectPublicKeyInfo.getInstance(null); TargetInformation.getInstance(null); Target.getInstance(null); Targets.getInstance(null); TBSCertificate.getInstance(null); TBSCertificate.getInstance(null); TBSCertificateStructure.getInstance(null); TBSCertificateStructure.getInstance(null); TBSCertList.CRLEntry.getInstance(null); TBSCertList.getInstance(null); TBSCertList.getInstance(null); Time.getInstance(null); Time.getInstance(null); doFullGetInstanceTest(UserNotice.class, new UserNotice(noticeReference, "hello world")); V2Form.getInstance(null); V2Form.getInstance(null); X509CertificateStructure.getInstance(null); X509CertificateStructure.getInstance(null); X509Extensions.getInstance(null); X509Extensions.getInstance(null); X509Name.getInstance(null); X509Name.getInstance(null); DHDomainParameters.getInstance(null); DHDomainParameters.getInstance(null); DHPublicKey.getInstance(null); DHPublicKey.getInstance(null); DHValidationParms.getInstance(null); DHValidationParms.getInstance(null); X962Parameters.getInstance(null); X962Parameters.getInstance(null); X9ECParameters.getInstance(null); MQVuserKeyingMaterial.getInstance(null); MQVuserKeyingMaterial.getInstance(null); CertHash.getInstance(null); RequestedCertificate.getInstance(null); RequestedCertificate.getInstance(null); AdditionalInformationSyntax.getInstance(null); Admissions.getInstance(null); AdmissionSyntax.getInstance(null); DeclarationOfMajority.getInstance(null); MonetaryLimit.getInstance(null); NamingAuthority.getInstance(null); NamingAuthority.getInstance(null); ProcurationSyntax.getInstance(null); ProfessionInfo.getInstance(null); Restriction.getInstance(null); BiometricData.getInstance(null); Iso4217CurrencyCode.getInstance(null); MonetaryValue.getInstance(null); QCStatement.getInstance(null); SemanticsInformation.getInstance(null); TypeOfBiometricData.getInstance(null); NameOrPseudonym.getInstance(null); PersonalData.getInstance(null); } public String getName() { return "GetInstanceNullTest"; } } bouncycastle-1.49.orig/test/src/org/bouncycastle/asn1/test/CscaMasterListTest.java0000644000175000017500000000230711624572761027703 0ustar ebourgebourgpackage org.bouncycastle.asn1.test; import java.io.IOException; import org.bouncycastle.asn1.ASN1Primitive; import org.bouncycastle.asn1.icao.CscaMasterList; import org.bouncycastle.util.Arrays; import org.bouncycastle.util.io.Streams; import org.bouncycastle.util.test.SimpleTest; public class CscaMasterListTest extends SimpleTest { public String getName() { return "CscaMasterList"; } public void performTest() throws Exception { byte[] input = getInput("masterlist-content.data"); CscaMasterList parsedList = CscaMasterList.getInstance(ASN1Primitive.fromByteArray(input)); if (parsedList.getCertStructs().length != 3) { fail("Cert structure parsing failed: incorrect length"); } byte[] output = parsedList.getEncoded(); if (!Arrays.areEqual(input, output)) { fail("Encoding failed after parse"); } } private byte[] getInput(String name) throws IOException { return Streams.readAll(getClass().getResourceAsStream(name)); } public static void main( String[] args) { runTest(new CscaMasterListTest()); } } bouncycastle-1.49.orig/test/src/org/bouncycastle/asn1/test/OtherSigningCertificateUnitTest.java0000644000175000017500000000447010571225326032420 0ustar ebourgebourgpackage org.bouncycastle.asn1.test; import org.bouncycastle.asn1.ASN1InputStream; import org.bouncycastle.asn1.ASN1Sequence; import org.bouncycastle.asn1.DERObjectIdentifier; import org.bouncycastle.asn1.ess.OtherCertID; import org.bouncycastle.asn1.ess.OtherSigningCertificate; import org.bouncycastle.asn1.x509.AlgorithmIdentifier; import java.io.IOException; public class OtherSigningCertificateUnitTest extends ASN1UnitTest { public String getName() { return "OtherSigningCertificate"; } public void performTest() throws Exception { AlgorithmIdentifier algId = new AlgorithmIdentifier(new DERObjectIdentifier("1.2.2.3")); byte[] digest = new byte[20]; OtherCertID otherCertID = new OtherCertID(algId, digest); OtherSigningCertificate otherCert = new OtherSigningCertificate(otherCertID); checkConstruction(otherCert, otherCertID); otherCert = OtherSigningCertificate.getInstance(null); if (otherCert != null) { fail("null getInstance() failed."); } try { OtherCertID.getInstance(new Object()); fail("getInstance() failed to detect bad object."); } catch (IllegalArgumentException e) { // expected } } private void checkConstruction( OtherSigningCertificate otherCert, OtherCertID otherCertID) throws IOException { checkValues(otherCert, otherCertID); otherCert = OtherSigningCertificate.getInstance(otherCert); checkValues(otherCert, otherCertID); ASN1InputStream aIn = new ASN1InputStream(otherCert.toASN1Object().getEncoded()); ASN1Sequence seq = (ASN1Sequence)aIn.readObject(); otherCert = OtherSigningCertificate.getInstance(seq); checkValues(otherCert, otherCertID); } private void checkValues( OtherSigningCertificate otherCert, OtherCertID otherCertID) { if (otherCert.getCerts().length != 1) { fail("getCerts() length wrong"); } checkMandatoryField("getCerts()[0]", otherCertID, otherCert.getCerts()[0]); } public static void main( String[] args) { runTest(new OtherSigningCertificateUnitTest()); } } bouncycastle-1.49.orig/test/src/org/bouncycastle/asn1/test/CertificateTest.java0000644000175000017500000005202212070233270027224 0ustar ebourgebourgpackage org.bouncycastle.asn1.test; import java.io.ByteArrayInputStream; import java.util.Enumeration; import org.bouncycastle.asn1.ASN1InputStream; import org.bouncycastle.asn1.ASN1Integer; import org.bouncycastle.asn1.ASN1ObjectIdentifier; import org.bouncycastle.asn1.ASN1OctetString; import org.bouncycastle.asn1.ASN1Sequence; import org.bouncycastle.asn1.util.ASN1Dump; import org.bouncycastle.asn1.x509.AlgorithmIdentifier; import org.bouncycastle.asn1.x509.AttCertIssuer; import org.bouncycastle.asn1.x509.AttCertValidityPeriod; import org.bouncycastle.asn1.x509.Attribute; import org.bouncycastle.asn1.x509.AttributeCertificate; import org.bouncycastle.asn1.x509.AttributeCertificateInfo; import org.bouncycastle.asn1.x509.AuthorityKeyIdentifier; import org.bouncycastle.asn1.x509.BasicConstraints; import org.bouncycastle.asn1.x509.CRLDistPoint; import org.bouncycastle.asn1.x509.Certificate; import org.bouncycastle.asn1.x509.DistributionPoint; import org.bouncycastle.asn1.x509.ExtendedKeyUsage; import org.bouncycastle.asn1.x509.Extension; import org.bouncycastle.asn1.x509.Extensions; import org.bouncycastle.asn1.x509.GeneralName; import org.bouncycastle.asn1.x509.GeneralNames; import org.bouncycastle.asn1.x509.Holder; import org.bouncycastle.asn1.x509.KeyPurposeId; import org.bouncycastle.asn1.x509.KeyUsage; import org.bouncycastle.asn1.x509.PolicyInformation; import org.bouncycastle.asn1.x509.SubjectKeyIdentifier; import org.bouncycastle.asn1.x509.TBSCertificate; import org.bouncycastle.util.encoders.Base64; import org.bouncycastle.util.test.SimpleTest; public class CertificateTest extends SimpleTest { // // server.crt // byte[] cert1 = Base64.decode( "MIIDXjCCAsegAwIBAgIBBzANBgkqhkiG9w0BAQQFADCBtzELMAkGA1UEBhMCQVUx" + "ETAPBgNVBAgTCFZpY3RvcmlhMRgwFgYDVQQHEw9Tb3V0aCBNZWxib3VybmUxGjAY" + "BgNVBAoTEUNvbm5lY3QgNCBQdHkgTHRkMR4wHAYDVQQLExVDZXJ0aWZpY2F0ZSBB" + "dXRob3JpdHkxFTATBgNVBAMTDENvbm5lY3QgNCBDQTEoMCYGCSqGSIb3DQEJARYZ" + "d2VibWFzdGVyQGNvbm5lY3Q0LmNvbS5hdTAeFw0wMDA2MDIwNzU2MjFaFw0wMTA2" + "MDIwNzU2MjFaMIG4MQswCQYDVQQGEwJBVTERMA8GA1UECBMIVmljdG9yaWExGDAW" + "BgNVBAcTD1NvdXRoIE1lbGJvdXJuZTEaMBgGA1UEChMRQ29ubmVjdCA0IFB0eSBM" + "dGQxFzAVBgNVBAsTDldlYnNlcnZlciBUZWFtMR0wGwYDVQQDExR3d3cyLmNvbm5l" + "Y3Q0LmNvbS5hdTEoMCYGCSqGSIb3DQEJARYZd2VibWFzdGVyQGNvbm5lY3Q0LmNv" + "bS5hdTCBnzANBgkqhkiG9w0BAQEFAAOBjQAwgYkCgYEArvDxclKAhyv7Q/Wmr2re" + "Gw4XL9Cnh9e+6VgWy2AWNy/MVeXdlxzd7QAuc1eOWQkGQEiLPy5XQtTY+sBUJ3AO" + "Rvd2fEVJIcjf29ey7bYua9J/vz5MG2KYo9/WCHIwqD9mmG9g0xLcfwq/s8ZJBswE" + "7sb85VU+h94PTvsWOsWuKaECAwEAAaN3MHUwJAYDVR0RBB0wG4EZd2VibWFzdGVy" + "QGNvbm5lY3Q0LmNvbS5hdTA6BglghkgBhvhCAQ0ELRYrbW9kX3NzbCBnZW5lcmF0" + "ZWQgY3VzdG9tIHNlcnZlciBjZXJ0aWZpY2F0ZTARBglghkgBhvhCAQEEBAMCBkAw" + "DQYJKoZIhvcNAQEEBQADgYEAotccfKpwSsIxM1Hae8DR7M/Rw8dg/RqOWx45HNVL" + "iBS4/3N/TO195yeQKbfmzbAA2jbPVvIvGgTxPgO1MP4ZgvgRhasaa0qCJCkWvpM4" + "yQf33vOiYQbpv4rTwzU8AmRlBG45WdjyNIigGV+oRc61aKCTnLq7zB8N3z1TF/bF" + "5/8="); // // ca.crt // byte[] cert2 = Base64.decode( "MIIDbDCCAtWgAwIBAgIBADANBgkqhkiG9w0BAQQFADCBtzELMAkGA1UEBhMCQVUx" + "ETAPBgNVBAgTCFZpY3RvcmlhMRgwFgYDVQQHEw9Tb3V0aCBNZWxib3VybmUxGjAY" + "BgNVBAoTEUNvbm5lY3QgNCBQdHkgTHRkMR4wHAYDVQQLExVDZXJ0aWZpY2F0ZSBB" + "dXRob3JpdHkxFTATBgNVBAMTDENvbm5lY3QgNCBDQTEoMCYGCSqGSIb3DQEJARYZ" + "d2VibWFzdGVyQGNvbm5lY3Q0LmNvbS5hdTAeFw0wMDA2MDIwNzU1MzNaFw0wMTA2" + "MDIwNzU1MzNaMIG3MQswCQYDVQQGEwJBVTERMA8GA1UECBMIVmljdG9yaWExGDAW" + "BgNVBAcTD1NvdXRoIE1lbGJvdXJuZTEaMBgGA1UEChMRQ29ubmVjdCA0IFB0eSBM" + "dGQxHjAcBgNVBAsTFUNlcnRpZmljYXRlIEF1dGhvcml0eTEVMBMGA1UEAxMMQ29u" + "bmVjdCA0IENBMSgwJgYJKoZIhvcNAQkBFhl3ZWJtYXN0ZXJAY29ubmVjdDQuY29t" + "LmF1MIGfMA0GCSqGSIb3DQEBAQUAA4GNADCBiQKBgQDgs5ptNG6Qv1ZpCDuUNGmv" + "rhjqMDPd3ri8JzZNRiiFlBA4e6/ReaO1U8ASewDeQMH6i9R6degFdQRLngbuJP0s" + "xcEE+SksEWNvygfzLwV9J/q+TQDyJYK52utb++lS0b48A1KPLwEsyL6kOAgelbur" + "ukwxowprKUIV7Knf1ajetQIDAQABo4GFMIGCMCQGA1UdEQQdMBuBGXdlYm1hc3Rl" + "ckBjb25uZWN0NC5jb20uYXUwDwYDVR0TBAgwBgEB/wIBADA2BglghkgBhvhCAQ0E" + "KRYnbW9kX3NzbCBnZW5lcmF0ZWQgY3VzdG9tIENBIGNlcnRpZmljYXRlMBEGCWCG" + "SAGG+EIBAQQEAwICBDANBgkqhkiG9w0BAQQFAAOBgQCsGvfdghH8pPhlwm1r3pQk" + "msnLAVIBb01EhbXm2861iXZfWqGQjrGAaA0ZpXNk9oo110yxoqEoSJSzniZa7Xtz" + "soTwNUpE0SLHvWf/SlKdFWlzXA+vOZbzEv4UmjeelekTm7lc01EEa5QRVzOxHFtQ" + "DhkaJ8VqOMajkQFma2r9iA=="); // // testx509.pem // byte[] cert3 = Base64.decode( "MIIBWzCCAQYCARgwDQYJKoZIhvcNAQEEBQAwODELMAkGA1UEBhMCQVUxDDAKBgNV" + "BAgTA1FMRDEbMBkGA1UEAxMSU1NMZWF5L3JzYSB0ZXN0IENBMB4XDTk1MDYxOTIz" + "MzMxMloXDTk1MDcxNzIzMzMxMlowOjELMAkGA1UEBhMCQVUxDDAKBgNVBAgTA1FM" + "RDEdMBsGA1UEAxMUU1NMZWF5L3JzYSB0ZXN0IGNlcnQwXDANBgkqhkiG9w0BAQEF" + "AANLADBIAkEAqtt6qS5GTxVxGZYWa0/4u+IwHf7p2LNZbcPBp9/OfIcYAXBQn8hO" + "/Re1uwLKXdCjIoaGs4DLdG88rkzfyK5dPQIDAQABMAwGCCqGSIb3DQIFBQADQQAE" + "Wc7EcF8po2/ZO6kNCwK/ICH6DobgLekA5lSLr5EvuioZniZp5lFzAw4+YzPQ7XKJ" + "zl9HYIMxATFyqSiD9jsx"); // // v3-cert1.pem // byte[] cert4 = Base64.decode( "MIICjTCCAfigAwIBAgIEMaYgRzALBgkqhkiG9w0BAQQwRTELMAkGA1UEBhMCVVMx" + "NjA0BgNVBAoTLU5hdGlvbmFsIEFlcm9uYXV0aWNzIGFuZCBTcGFjZSBBZG1pbmlz" + "dHJhdGlvbjAmFxE5NjA1MjgxMzQ5MDUrMDgwMBcROTgwNTI4MTM0OTA1KzA4MDAw" + "ZzELMAkGA1UEBhMCVVMxNjA0BgNVBAoTLU5hdGlvbmFsIEFlcm9uYXV0aWNzIGFu" + "ZCBTcGFjZSBBZG1pbmlzdHJhdGlvbjEgMAkGA1UEBRMCMTYwEwYDVQQDEwxTdGV2" + "ZSBTY2hvY2gwWDALBgkqhkiG9w0BAQEDSQAwRgJBALrAwyYdgxmzNP/ts0Uyf6Bp" + "miJYktU/w4NG67ULaN4B5CnEz7k57s9o3YY3LecETgQ5iQHmkwlYDTL2fTgVfw0C" + "AQOjgaswgagwZAYDVR0ZAQH/BFowWDBWMFQxCzAJBgNVBAYTAlVTMTYwNAYDVQQK" + "Ey1OYXRpb25hbCBBZXJvbmF1dGljcyBhbmQgU3BhY2UgQWRtaW5pc3RyYXRpb24x" + "DTALBgNVBAMTBENSTDEwFwYDVR0BAQH/BA0wC4AJODMyOTcwODEwMBgGA1UdAgQR" + "MA8ECTgzMjk3MDgyM4ACBSAwDQYDVR0KBAYwBAMCBkAwCwYJKoZIhvcNAQEEA4GB" + "AH2y1VCEw/A4zaXzSYZJTTUi3uawbbFiS2yxHvgf28+8Js0OHXk1H1w2d6qOHH21" + "X82tZXd/0JtG0g1T9usFFBDvYK8O0ebgz/P5ELJnBL2+atObEuJy1ZZ0pBDWINR3" + "WkDNLCGiTkCKp0F5EWIrVDwh54NNevkCQRZita+z4IBO"); // // v3-cert2.pem // byte[] cert5 = Base64.decode( "MIICiTCCAfKgAwIBAgIEMeZfHzANBgkqhkiG9w0BAQQFADB9MQswCQYDVQQGEwJD" + "YTEPMA0GA1UEBxMGTmVwZWFuMR4wHAYDVQQLExVObyBMaWFiaWxpdHkgQWNjZXB0" + "ZWQxHzAdBgNVBAoTFkZvciBEZW1vIFB1cnBvc2VzIE9ubHkxHDAaBgNVBAMTE0Vu" + "dHJ1c3QgRGVtbyBXZWIgQ0EwHhcNOTYwNzEyMTQyMDE1WhcNOTYxMDEyMTQyMDE1" + "WjB0MSQwIgYJKoZIhvcNAQkBExVjb29rZUBpc3NsLmF0bC5ocC5jb20xCzAJBgNV" + "BAYTAlVTMScwJQYDVQQLEx5IZXdsZXR0IFBhY2thcmQgQ29tcGFueSAoSVNTTCkx" + "FjAUBgNVBAMTDVBhdWwgQS4gQ29va2UwXDANBgkqhkiG9w0BAQEFAANLADBIAkEA" + "6ceSq9a9AU6g+zBwaL/yVmW1/9EE8s5you1mgjHnj0wAILuoB3L6rm6jmFRy7QZT" + "G43IhVZdDua4e+5/n1ZslwIDAQABo2MwYTARBglghkgBhvhCAQEEBAMCB4AwTAYJ" + "YIZIAYb4QgENBD8WPVRoaXMgY2VydGlmaWNhdGUgaXMgb25seSBpbnRlbmRlZCBm" + "b3IgZGVtb25zdHJhdGlvbiBwdXJwb3Nlcy4wDQYJKoZIhvcNAQEEBQADgYEAi8qc" + "F3zfFqy1sV8NhjwLVwOKuSfhR/Z8mbIEUeSTlnH3QbYt3HWZQ+vXI8mvtZoBc2Fz" + "lexKeIkAZXCesqGbs6z6nCt16P6tmdfbZF3I3AWzLquPcOXjPf4HgstkyvVBn0Ap" + "jAFN418KF/Cx4qyHB4cjdvLrRjjQLnb2+ibo7QU="); byte[] cert6 = Base64.decode( "MIIEDjCCAvagAwIBAgIEFAAq2jANBgkqhkiG9w0BAQUFADBLMSowKAYDVQQDEyFT" + "dW4gTWljcm9zeXN0ZW1zIEluYyBDQSAoQ2xhc3MgQikxHTAbBgNVBAoTFFN1biBN" + "aWNyb3N5c3RlbXMgSW5jMB4XDTA0MDIyOTAwNDMzNFoXDTA5MDMwMTAwNDMzNFow" + "NzEdMBsGA1UEChMUU3VuIE1pY3Jvc3lzdGVtcyBJbmMxFjAUBgNVBAMTDXN0b3Jl" + "LnN1bi5jb20wgZ8wDQYJKoZIhvcNAQEBBQADgY0AMIGJAoGBAP9ErzFT7MPg2bVV" + "LNmHTgN4kmiRNlPpuLGWS7EDIXYBbLeSSOCp/e1ANcOGnsuf0WIq9ejd/CPyEfh4" + "sWoVvQzpOfHZ/Jyei29PEuxzWT+4kQmCx3+sLK25lAnDFsz1KiFmB6Y3GJ/JSjpp" + "L0Yy1R9YlIc82I8gSw44y5JDABW5AgMBAAGjggGQMIIBjDAOBgNVHQ8BAf8EBAMC" + "BaAwHQYDVR0OBBYEFG1WB3PApZM7OPPVWJ31UrERaoKWMEcGA1UdIARAMD4wPAYL" + "YIZIAYb3AIN9k18wLTArBggrBgEFBQcCARYfaHR0cDovL3d3dy5zdW4uY29tL3Br" + "aS9jcHMuaHRtbDCBhQYDVR0fBH4wfDB6oCegJYYjaHR0cDovL3d3dy5zdW4uY29t" + "L3BraS9wa2lzbWljYS5jcmyiT6RNMEsxKjAoBgNVBAMTIVN1biBNaWNyb3N5c3Rl" + "bXMgSW5jIENBIChDbGFzcyBCKTEdMBsGA1UEChMUU3VuIE1pY3Jvc3lzdGVtcyBJ" + "bmMwHwYDVR0jBBgwFoAUT7ZnqR/EEBSgG6h1wdYMI5RiiWswVAYIKwYBBQUHAQEE" + "SDBGMB0GCCsGAQUFBzABhhFodHRwOi8vdmEuc3VuLmNvbTAlBggrBgEFBQcwAYYZ" + "aHR0cDovL3ZhLmNlbnRyYWwuc3VuLmNvbTATBgNVHSUEDDAKBggrBgEFBQcDATAN" + "BgkqhkiG9w0BAQUFAAOCAQEAq3byQgyU24tBpR07iQK7agm1zQyzDQ6itdbji0ln" + "T7fOd5Pnp99iig8ovwWliNtXKAmgtJY60jWz7nEuk38AioZJhS+RPWIWX/+2PRV7" + "s2aWTzM3n43BypD+jU2qF9c9kDWP/NW9K9IcrS7SfU/2MZVmiCMD/9FEL+CWndwE" + "JJQ/oenXm44BFISI/NjV7fMckN8EayPvgtzQkD5KnEiggOD6HOrwTDFR+tmAEJ0K" + "ZttQNwOzCOcEdxXTg6qBHUbONdL7bjTT5NzV+JR/bnfiCqHzdnGwfbHzhmrnXw8j" + "QCVXcfBfL9++nmpNNRlnJMRdYGeCY6OAfh/PRo8/fXak1Q=="); byte[] cert7 = Base64.decode( "MIIFJDCCBAygAwIBAgIKEcJZuwAAAAAABzANBgkqhkiG9w0BAQUFADAPMQ0wCwYD" + "VQQDEwRNU0NBMB4XDTA0MDUyMjE2MTM1OFoXDTA1MDUyMjE2MjM1OFowaTEbMBkG" + "CSqGSIb3DQEJCBMMMTkyLjE2OC4xLjMzMScwJQYJKoZIhvcNAQkCExhwaXhmaXJl" + "d2FsbC5jaXNjb3BpeC5jb20xITAfBgNVBAMTGHBpeGZpcmV3YWxsLmNpc2NvcGl4" + "LmNvbTB8MA0GCSqGSIb3DQEBAQUAA2sAMGgCYQCbcsY7vrjweXZiFQdhUafEjJV+" + "HRy5UKmuCy0237ffmYrN+XNLw0h90cdCSK6KPZebd2E2Bc2UmTikc/FY8meBT3/E" + "O/Osmywzi++Ur8/IrDvtuR1zd0c/xEPnV1ZRezkCAwEAAaOCAs4wggLKMAsGA1Ud" + "DwQEAwIFoDAdBgNVHQ4EFgQUzJBSxkQiN9TKvhTMQ1/Aq4gZnHswHwYDVR0jBBgw" + "FoAUMsxzXVh+5UKMNpwNHmqSfcRYfJ4wgfcGA1UdHwSB7zCB7DCB6aCB5qCB44aB" + "r2xkYXA6Ly8vQ049TVNDQSxDTj1NQVVELENOPUNEUCxDTj1QdWJsaWMlMjBLZXkl" + "MjBTZXJ2aWNlcyxDTj1TZXJ2aWNlcyxDTj1Db25maWd1cmF0aW9uLERDPWludCxE" + "Qz1wcmltZWtleSxEQz1zZT9jZXJ0aWZpY2F0ZVJldm9jYXRpb25MaXN0P2Jhc2U/" + "b2JqZWN0Q2xhc3M9Y1JMRGlzdHJpYnV0aW9uUG9pbnSGL2h0dHA6Ly9tYXVkLmlu" + "dC5wcmltZWtleS5zZS9DZXJ0RW5yb2xsL01TQ0EuY3JsMIIBEAYIKwYBBQUHAQEE" + "ggECMIH/MIGqBggrBgEFBQcwAoaBnWxkYXA6Ly8vQ049TVNDQSxDTj1BSUEsQ049" + "UHVibGljJTIwS2V5JTIwU2VydmljZXMsQ049U2VydmljZXMsQ049Q29uZmlndXJh" + "dGlvbixEQz1pbnQsREM9cHJpbWVrZXksREM9c2U/Y0FDZXJ0aWZpY2F0ZT9iYXNl" + "P29iamVjdENsYXNzPWNlcnRpZmljYXRpb25BdXRob3JpdHkwUAYIKwYBBQUHMAKG" + "RGh0dHA6Ly9tYXVkLmludC5wcmltZWtleS5zZS9DZXJ0RW5yb2xsL01BVUQuaW50" + "LnByaW1la2V5LnNlX01TQ0EuY3J0MCwGA1UdEQEB/wQiMCCCGHBpeGZpcmV3YWxs" + "LmNpc2NvcGl4LmNvbYcEwKgBITA/BgkrBgEEAYI3FAIEMh4wAEkAUABTAEUAQwBJ" + "AG4AdABlAHIAbQBlAGQAaQBhAHQAZQBPAGYAZgBsAGkAbgBlMA0GCSqGSIb3DQEB" + "BQUAA4IBAQCa0asiPbObLJjpSz6ndJ7y4KOWMiuuBc/VQBnLr7RBCF3ZlZ6z1+e6" + "dmv8se/z11NgateKfxw69IhLCriA960HEgX9Z61MiVG+DrCFpbQyp8+hPFHoqCZN" + "b7upc8k2OtJW6KPaP9k0DW52YQDIky4Vb2rZeC4AMCorWN+KlndHhr1HFA14HxwA" + "4Mka0FM6HNWnBV2UmTjBZMDr/OrGH1jLYIceAaZK0X2R+/DWXeeqIga8jwP5empq" + "JetYnkXdtTbEh3xL0BX+mZl8vDI+/PGcwox/7YjFmyFWphRMxk9CZ3rF2/FQWMJP" + "YqQpKiQOmQg5NAhcwffLAuVjVVibPYqi"); byte[] cert8 = Base64.decode( "MIIB0zCCATwCAQEwbqBsMGekZTBjMQswCQYDVQQGEwJERTELMAkGA1UECBMCQlkx" + "EzARBgNVBAcTClJlZ2Vuc2J1cmcxEDAOBgNVBAoTB0FDIFRlc3QxCzAJBgNVBAsT" + "AkNBMRMwEQYDVQQDEwpBQyBUZXN0IENBAgEBoHYwdKRyMHAxCzAJBgNVBAYTAkRF" + "MQswCQYDVQQIEwJCWTETMBEGA1UEBxMKUmVnZW5zYnVyZzESMBAGA1UEChMJQUMg" + "SXNzdWVyMRowGAYDVQQLExFBQyBJc3N1ZXIgc2VjdGlvbjEPMA0GA1UEAxMGQUMg" + "TWFuMA0GCSqGSIb3DQEBBQUAAgEBMCIYDzIwMDQxMTI2MTI1MjUxWhgPMjAwNDEy" + "MzEyMzAwMDBaMBkwFwYDVRhIMRAwDoEMREFVMTIzNDU2Nzg5MA0GCSqGSIb3DQEB" + "BQUAA4GBABd4Odx3yEMGL/BvItuT1RafNR2uuWuZbajg0pD6bshUsl+WCIfRiEkq" + "lHMkpI7WqAZikdnAEQ5jQsVWEuVejWxR6gjejKxc0fb9qpIui7/GoI5Eh6dmG20e" + "xbwJL3+6YYFrZwxR8cC5rPvWrblUR5XKJy+Zp/H5+t9iANnL1L8J"); String[] subjects = { "C=AU,ST=Victoria,L=South Melbourne,O=Connect 4 Pty Ltd,OU=Webserver Team,CN=www2.connect4.com.au,E=webmaster@connect4.com.au", "C=AU,ST=Victoria,L=South Melbourne,O=Connect 4 Pty Ltd,OU=Certificate Authority,CN=Connect 4 CA,E=webmaster@connect4.com.au", "C=AU,ST=QLD,CN=SSLeay/rsa test cert", "C=US,O=National Aeronautics and Space Administration,SERIALNUMBER=16+CN=Steve Schoch", "E=cooke@issl.atl.hp.com,C=US,OU=Hewlett Packard Company (ISSL),CN=Paul A. Cooke", "O=Sun Microsystems Inc,CN=store.sun.com", "unstructuredAddress=192.168.1.33,unstructuredName=pixfirewall.ciscopix.com,CN=pixfirewall.ciscopix.com" }; public String getName() { return "Certificate"; } public void checkCertificate( int id, byte[] cert) throws Exception { ByteArrayInputStream bIn = new ByteArrayInputStream(cert); ASN1InputStream aIn = new ASN1InputStream(bIn); ASN1Sequence seq = (ASN1Sequence)aIn.readObject(); // String dump = ASN1Dump.dumpAsString(seq); Certificate obj = Certificate.getInstance(seq); TBSCertificate tbsCert = obj.getTBSCertificate(); if (!tbsCert.getSubject().toString().equals(subjects[id - 1])) { fail("failed subject test for certificate id " + id + " got " + tbsCert.getSubject().toString()); } if (tbsCert.getVersionNumber() == 3) { Extensions ext = tbsCert.getExtensions(); if (ext != null) { Enumeration en = ext.oids(); while (en.hasMoreElements()) { ASN1ObjectIdentifier oid = (ASN1ObjectIdentifier)en.nextElement(); Extension extVal = ext.getExtension(oid); ASN1OctetString oct = extVal.getExtnValue(); ASN1InputStream extIn = new ASN1InputStream(new ByteArrayInputStream(oct.getOctets())); if (oid.equals(Extension.subjectKeyIdentifier)) { SubjectKeyIdentifier si = SubjectKeyIdentifier.getInstance(extIn.readObject()); if (!si.equals(SubjectKeyIdentifier.fromExtensions(ext))) { fail("SubjectKeyIdentifier not matched"); } } else if (oid.equals(Extension.keyUsage)) { KeyUsage ku = KeyUsage.getInstance(extIn.readObject()); if (!ku.equals(KeyUsage.fromExtensions(ext))) { fail("KeyUsage not matched"); } } else if (oid.equals(Extension.extendedKeyUsage)) { ExtendedKeyUsage ku = ExtendedKeyUsage.getInstance(extIn.readObject()); ASN1Sequence sq = (ASN1Sequence)ku.toASN1Primitive(); for (int i = 0; i != sq.size(); i++) { ASN1ObjectIdentifier p = ASN1ObjectIdentifier.getInstance(KeyPurposeId.getInstance(sq.getObjectAt(i))); } if (!ku.equals(ExtendedKeyUsage.fromExtensions(ext))) { fail("ExtendedKeyUsage not matched"); } } else if (oid.equals(Extension.subjectAlternativeName)) { GeneralNames gn = GeneralNames.getInstance(extIn.readObject()); ASN1Sequence sq = (ASN1Sequence)gn.toASN1Primitive(); for (int i = 0; i != sq.size(); i++) { GeneralName n = GeneralName.getInstance(sq.getObjectAt(i)); } } else if (oid.equals(Extension.issuerAlternativeName)) { GeneralNames gn = GeneralNames.getInstance(extIn.readObject()); ASN1Sequence sq = (ASN1Sequence)gn.toASN1Primitive(); for (int i = 0; i != sq.size(); i++) { GeneralName n = GeneralName.getInstance(sq.getObjectAt(i)); } } else if (oid.equals(Extension.cRLDistributionPoints)) { CRLDistPoint p = CRLDistPoint.getInstance(extIn.readObject()); DistributionPoint[] points = p.getDistributionPoints(); for (int i = 0; i != points.length; i++) { // do nothing } } else if (oid.equals(Extension.certificatePolicies)) { ASN1Sequence cp = (ASN1Sequence)extIn.readObject(); for (int i = 0; i != cp.size(); i++) { PolicyInformation.getInstance(cp.getObjectAt(i)); } } else if (oid.equals(Extension.authorityKeyIdentifier)) { AuthorityKeyIdentifier auth = AuthorityKeyIdentifier.getInstance(extIn.readObject()); if (!auth.equals(AuthorityKeyIdentifier.fromExtensions(ext))) { fail("AuthorityKeyIdentifier not matched"); } } else if (oid.equals(Extension.basicConstraints)) { BasicConstraints bc = BasicConstraints.getInstance(extIn.readObject()); if (!bc.equals(BasicConstraints.fromExtensions(ext))) { fail("BasicConstraints not matched"); } } else { //System.out.println(oid.getId()); } } } } } public void checkAttributeCertificate( int id, byte[] cert) throws Exception { ByteArrayInputStream bIn; ASN1InputStream aIn; String dump = ""; bIn = new ByteArrayInputStream(cert); aIn = new ASN1InputStream(bIn); ASN1Sequence seq = (ASN1Sequence) aIn.readObject(); dump = ASN1Dump.dumpAsString(seq); AttributeCertificate obj = new AttributeCertificate(seq); AttributeCertificateInfo acInfo = obj.getAcinfo(); // Version if (!(acInfo.getVersion().equals(new ASN1Integer(1))) && (!(acInfo.getVersion().equals(new ASN1Integer(2))))) { fail( "failed AC Version test for id " + id); } // Holder Holder h = acInfo.getHolder(); if (h == null) { fail( "failed AC Holder test, it's null, for id " + id); } // Issuer AttCertIssuer aci = acInfo.getIssuer(); if (aci == null) { fail( "failed AC Issuer test, it's null, for id " + id); } // Signature AlgorithmIdentifier sig = acInfo.getSignature(); if (sig == null) { fail( "failed AC Signature test for id " + id); } // Serial ASN1Integer serial = acInfo.getSerialNumber(); // Validity AttCertValidityPeriod validity = acInfo.getAttrCertValidityPeriod(); if (validity == null) { fail("failed AC AttCertValidityPeriod test for id " + id); } // Attributes ASN1Sequence attribSeq = acInfo.getAttributes(); Attribute att[] = new Attribute[attribSeq.size()]; for (int i = 0; i < attribSeq.size(); i++) { att[i] = Attribute.getInstance(attribSeq.getObjectAt(i)); } // IssuerUniqueId // TODO, how to best test? // X509 Extensions Extensions ext = acInfo.getExtensions(); if (ext != null) { Enumeration en = ext.oids(); while (en.hasMoreElements()) { ASN1ObjectIdentifier oid = (ASN1ObjectIdentifier) en .nextElement(); Extension extVal = ext.getExtension(oid); } } } public void performTest() throws Exception { checkCertificate(1, cert1); checkCertificate(2, cert2); checkCertificate(3, cert3); checkCertificate(4, cert4); checkCertificate(5, cert5); checkCertificate(6, cert6); checkCertificate(7, cert7); checkAttributeCertificate(8,cert8); } public static void main( String[] args) { runTest(new CertificateTest()); } } bouncycastle-1.49.orig/test/src/org/bouncycastle/asn1/test/ASN1UnitTest.java0000644000175000017500000000427510574472666026400 0ustar ebourgebourgpackage org.bouncycastle.asn1.test; import org.bouncycastle.asn1.ASN1Encodable; import org.bouncycastle.util.test.SimpleTest; import java.math.BigInteger; public abstract class ASN1UnitTest extends SimpleTest { protected void checkMandatoryField(String name, ASN1Encodable expected, ASN1Encodable present) { if (!expected.equals(present)) { fail(name + " field doesn't match."); } } protected void checkMandatoryField(String name, String expected, String present) { if (!expected.equals(present)) { fail(name + " field doesn't match."); } } protected void checkMandatoryField(String name, byte[] expected, byte[] present) { if (!areEqual(expected, present)) { fail(name + " field doesn't match."); } } protected void checkMandatoryField(String name, int expected, int present) { if (expected != present) { fail(name + " field doesn't match."); } } protected void checkOptionalField(String name, ASN1Encodable expected, ASN1Encodable present) { if (expected != null) { if (!expected.equals(present)) { fail(name + " field doesn't match."); } } else if (present != null) { fail(name + " field found when none expected."); } } protected void checkOptionalField(String name, String expected, String present) { if (expected != null) { if (!expected.equals(present)) { fail(name + " field doesn't match."); } } else if (present != null) { fail(name + " field found when none expected."); } } protected void checkOptionalField(String name, BigInteger expected, BigInteger present) { if (expected != null) { if (!expected.equals(present)) { fail(name + " field doesn't match."); } } else if (present != null) { fail(name + " field found when none expected."); } } } bouncycastle-1.49.orig/test/src/org/bouncycastle/asn1/test/MonetaryLimitUnitTest.java0000644000175000017500000000410510574463432030452 0ustar ebourgebourgpackage org.bouncycastle.asn1.test; import org.bouncycastle.asn1.ASN1InputStream; import org.bouncycastle.asn1.ASN1Sequence; import org.bouncycastle.asn1.isismtt.x509.MonetaryLimit; import java.io.IOException; public class MonetaryLimitUnitTest extends ASN1UnitTest { public String getName() { return "MonetaryLimit"; } public void performTest() throws Exception { String currency = "AUD"; int amount = 1; int exponent = 2; MonetaryLimit limit = new MonetaryLimit(currency, amount, exponent); checkConstruction(limit, currency, amount, exponent); limit = MonetaryLimit.getInstance(null); if (limit != null) { fail("null getInstance() failed."); } try { MonetaryLimit.getInstance(new Object()); fail("getInstance() failed to detect bad object."); } catch (IllegalArgumentException e) { // expected } } private void checkConstruction( MonetaryLimit limit, String currency, int amount, int exponent) throws IOException { checkValues(limit, currency, amount, exponent); limit = MonetaryLimit.getInstance(limit); checkValues(limit, currency, amount, exponent); ASN1InputStream aIn = new ASN1InputStream(limit.toASN1Object().getEncoded()); ASN1Sequence seq = (ASN1Sequence)aIn.readObject(); limit = MonetaryLimit.getInstance(seq); checkValues(limit, currency, amount, exponent); } private void checkValues( MonetaryLimit limit, String currency, int amount, int exponent) { checkMandatoryField("currency", currency, limit.getCurrency()); checkMandatoryField("amount", amount, limit.getAmount().intValue()); checkMandatoryField("exponent", exponent, limit.getExponent().intValue()); } public static void main( String[] args) { runTest(new MonetaryLimitUnitTest()); } } bouncycastle-1.49.orig/test/src/org/bouncycastle/asn1/test/MiscTest.java0000644000175000017500000000674411625103534025713 0ustar ebourgebourgpackage org.bouncycastle.asn1.test; import java.io.ByteArrayInputStream; import java.io.ByteArrayOutputStream; import org.bouncycastle.asn1.ASN1Encodable; import org.bouncycastle.asn1.ASN1InputStream; import org.bouncycastle.asn1.ASN1OutputStream; import org.bouncycastle.asn1.ASN1Primitive; import org.bouncycastle.asn1.DERIA5String; import org.bouncycastle.asn1.misc.CAST5CBCParameters; import org.bouncycastle.asn1.misc.IDEACBCPar; import org.bouncycastle.asn1.misc.NetscapeCertType; import org.bouncycastle.asn1.misc.NetscapeRevocationURL; import org.bouncycastle.asn1.misc.VerisignCzagExtension; import org.bouncycastle.util.encoders.Base64; import org.bouncycastle.util.test.SimpleTestResult; import org.bouncycastle.util.test.Test; import org.bouncycastle.util.test.TestResult; public class MiscTest implements Test { private boolean isSameAs( byte[] a, byte[] b) { if (a.length != b.length) { return false; } for (int i = 0; i != a.length; i++) { if (a[i] != b[i]) { return false; } } return true; } public TestResult perform() { byte[] testIv = { 1, 2, 3, 4, 5, 6, 7, 8 }; ASN1Encodable[] values = { new CAST5CBCParameters(testIv, 128), new NetscapeCertType(NetscapeCertType.smime), new VerisignCzagExtension(new DERIA5String("hello")), new IDEACBCPar(testIv), new NetscapeRevocationURL(new DERIA5String("http://test")) }; byte[] data = Base64.decode("MA4ECAECAwQFBgcIAgIAgAMCBSAWBWhlbGxvMAoECAECAwQFBgcIFgtodHRwOi8vdGVzdA=="); try { ByteArrayOutputStream bOut = new ByteArrayOutputStream(); ASN1OutputStream aOut = new ASN1OutputStream(bOut); for (int i = 0; i != values.length; i++) { aOut.writeObject(values[i]); } ASN1Primitive[] readValues = new ASN1Primitive[values.length]; if (!isSameAs(bOut.toByteArray(), data)) { return new SimpleTestResult(false, getName() + ": Failed data check"); } ByteArrayInputStream bIn = new ByteArrayInputStream(bOut.toByteArray()); ASN1InputStream aIn = new ASN1InputStream(bIn); for (int i = 0; i != values.length; i++) { ASN1Primitive o = aIn.readObject(); if (!values[i].equals(o)) { return new SimpleTestResult(false, getName() + ": Failed equality test for " + o); } if (o.hashCode() != values[i].hashCode()) { return new SimpleTestResult(false, getName() + ": Failed hashCode test for " + o); } } return new SimpleTestResult(true, getName() + ": Okay"); } catch (Exception e) { return new SimpleTestResult(false, getName() + ": Failed - exception " + e.toString(), e); } } public String getName() { return "Misc"; } public static void main( String[] args) { MiscTest test = new MiscTest(); TestResult result = test.perform(); System.out.println(result); } } bouncycastle-1.49.orig/test/src/org/bouncycastle/asn1/test/OIDTest.java0000644000175000017500000001141211644752136025430 0ustar ebourgebourgpackage org.bouncycastle.asn1.test; import java.io.ByteArrayInputStream; import java.io.ByteArrayOutputStream; import java.io.IOException; import org.bouncycastle.asn1.ASN1InputStream; import org.bouncycastle.asn1.ASN1ObjectIdentifier; import org.bouncycastle.asn1.ASN1OutputStream; import org.bouncycastle.asn1.DERObjectIdentifier; import org.bouncycastle.asn1.DEROutputStream; import org.bouncycastle.asn1.pkcs.PKCSObjectIdentifiers; import org.bouncycastle.util.encoders.Hex; import org.bouncycastle.util.test.SimpleTest; /** * X.690 test example */ public class OIDTest extends SimpleTest { byte[] req1 = Hex.decode("0603813403"); byte[] req2 = Hex.decode("06082A36FFFFFFDD6311"); public String getName() { return "OID"; } private void recodeCheck( String oid, byte[] enc) throws IOException { ByteArrayInputStream bIn = new ByteArrayInputStream(enc); ASN1InputStream aIn = new ASN1InputStream(bIn); DERObjectIdentifier o = new DERObjectIdentifier(oid); DERObjectIdentifier encO = (DERObjectIdentifier)aIn.readObject(); if (!o.equals(encO)) { fail("oid ID didn't match", o, encO); } ByteArrayOutputStream bOut = new ByteArrayOutputStream(); DEROutputStream dOut = new DEROutputStream(bOut); dOut.writeObject(o); byte[] bytes = bOut.toByteArray(); if (bytes.length != enc.length) { fail("failed length test"); } for (int i = 0; i != enc.length; i++) { if (bytes[i] != enc[i]) { fail("failed comparison test", new String(Hex.encode(enc)), new String(Hex.encode(bytes))); } } } private void validOidCheck( String oid) throws IOException { DERObjectIdentifier o = new DERObjectIdentifier(oid); ByteArrayOutputStream bOut = new ByteArrayOutputStream(); ASN1OutputStream aOut = new ASN1OutputStream(bOut); aOut.writeObject(o); ByteArrayInputStream bIn = new ByteArrayInputStream(bOut.toByteArray()); ASN1InputStream aIn = new ASN1InputStream(bIn); o = (DERObjectIdentifier)aIn.readObject(); if (!o.getId().equals(oid)) { fail("failed oid check for " + oid); } } private void invalidOidCheck( String oid) { try { new DERObjectIdentifier(oid); fail("failed to catch bad oid: " + oid); } catch (IllegalArgumentException e) { // expected } } private void branchCheck(String stem, String branch) { String expected = stem + "." + branch; String actual = new ASN1ObjectIdentifier(stem).branch(branch).getId(); if (!expected.equals(actual)) { fail("failed 'branch' check for " + stem + "/" + branch); } } private void onCheck(String stem, String test, boolean expected) { if (expected != new ASN1ObjectIdentifier(test).on(new ASN1ObjectIdentifier(stem))) { fail("failed 'on' check for " + stem + "/" + test); } } public void performTest() throws IOException { recodeCheck("2.100.3", req1); recodeCheck("1.2.54.34359733987.17", req2); validOidCheck(PKCSObjectIdentifiers.pkcs_9_at_contentType.getId()); validOidCheck("0.1"); validOidCheck("1.1.127.32512.8323072.2130706432.545460846592.139637976727552.35747322042253312.9151314442816847872"); validOidCheck("1.2.123.12345678901.1.1.1"); validOidCheck("2.25.196556539987194312349856245628873852187.1"); invalidOidCheck("0"); invalidOidCheck("1"); invalidOidCheck("2"); invalidOidCheck("3.1"); invalidOidCheck("..1"); invalidOidCheck("192.168.1.1"); invalidOidCheck(".123452"); invalidOidCheck("1."); invalidOidCheck("1.345.23.34..234"); invalidOidCheck("1.345.23.34.234."); invalidOidCheck(".12.345.77.234"); invalidOidCheck(".12.345.77.234."); invalidOidCheck("1.2.3.4.A.5"); invalidOidCheck("1,2"); branchCheck("1.1", "2.2"); onCheck("1.1", "1.1", false); onCheck("1.1", "1.2", false); onCheck("1.1", "1.2.1", false); onCheck("1.1", "2.1", false); onCheck("1.1", "1.11", false); onCheck("1.12", "1.1.2", false); onCheck("1.1", "1.1.1", true); onCheck("1.1", "1.1.2", true); } public static void main( String[] args) { runTest(new OIDTest()); } } bouncycastle-1.49.orig/test/src/org/bouncycastle/asn1/test/PKIFailureInfoTest.java0000644000175000017500000000530511625355332027564 0ustar ebourgebourgpackage org.bouncycastle.asn1.test; import java.io.IOException; import org.bouncycastle.asn1.ASN1Encoding; import org.bouncycastle.asn1.ASN1InputStream; import org.bouncycastle.asn1.DERBitString; import org.bouncycastle.asn1.cmp.PKIFailureInfo; import org.bouncycastle.util.encoders.Base64; import org.bouncycastle.util.test.SimpleTest; /** * PKIFailureInfoTest */ public class PKIFailureInfoTest extends SimpleTest { // A correct hex encoded BAD_DATA_FORMAT PKIFailureInfo private static final byte[] CORRECT_FAILURE_INFO = Base64.decode("AwIANQ=="); public String getName() { return "PKIFailureInfo"; } private void testEncoding() throws IOException { DERBitString bitString = (DERBitString)new ASN1InputStream(CORRECT_FAILURE_INFO).readObject(); PKIFailureInfo correct = new PKIFailureInfo(bitString); PKIFailureInfo bug = new PKIFailureInfo(PKIFailureInfo.badRequest | PKIFailureInfo.badTime |PKIFailureInfo.badDataFormat | PKIFailureInfo.incorrectData); if (!areEqual(correct.getEncoded(ASN1Encoding.DER),bug.getEncoded(ASN1Encoding.DER))) { fail("encoding doesn't match"); } } public void performTest() throws IOException { BitStringConstantTester.testFlagValueCorrect(0, PKIFailureInfo.badAlg); BitStringConstantTester.testFlagValueCorrect(1, PKIFailureInfo.badMessageCheck); BitStringConstantTester.testFlagValueCorrect(2, PKIFailureInfo.badRequest); BitStringConstantTester.testFlagValueCorrect(3, PKIFailureInfo.badTime); BitStringConstantTester.testFlagValueCorrect(4, PKIFailureInfo.badCertId); BitStringConstantTester.testFlagValueCorrect(5, PKIFailureInfo.badDataFormat); BitStringConstantTester.testFlagValueCorrect(6, PKIFailureInfo.wrongAuthority); BitStringConstantTester.testFlagValueCorrect(7, PKIFailureInfo.incorrectData); BitStringConstantTester.testFlagValueCorrect(8, PKIFailureInfo.missingTimeStamp); BitStringConstantTester.testFlagValueCorrect(9, PKIFailureInfo.badPOP); BitStringConstantTester.testFlagValueCorrect(14, PKIFailureInfo.timeNotAvailable); BitStringConstantTester.testFlagValueCorrect(15, PKIFailureInfo.unacceptedPolicy); BitStringConstantTester.testFlagValueCorrect(16, PKIFailureInfo.unacceptedExtension); BitStringConstantTester.testFlagValueCorrect(17, PKIFailureInfo.addInfoNotAvailable); BitStringConstantTester.testFlagValueCorrect(25, PKIFailureInfo.systemFailure); testEncoding(); } public static void main( String[] args) { runTest(new PKIFailureInfoTest()); } } bouncycastle-1.49.orig/test/src/org/bouncycastle/asn1/test/AttributeTableUnitTest.java0000644000175000017500000000764310371620477030601 0ustar ebourgebourgpackage org.bouncycastle.asn1.test; import java.util.Hashtable; import org.bouncycastle.asn1.ASN1EncodableVector; import org.bouncycastle.asn1.DERObjectIdentifier; import org.bouncycastle.asn1.DERSet; import org.bouncycastle.asn1.cms.Attribute; import org.bouncycastle.asn1.cms.AttributeTable; import org.bouncycastle.util.test.SimpleTest; public class AttributeTableUnitTest extends SimpleTest { private static final DERObjectIdentifier type1 = new DERObjectIdentifier("1.1.1"); private static final DERObjectIdentifier type2 = new DERObjectIdentifier("1.1.2"); private static final DERObjectIdentifier type3 = new DERObjectIdentifier("1.1.3"); public String getName() { return "AttributeTable"; } public void performTest() throws Exception { ASN1EncodableVector v = new ASN1EncodableVector(); v.add(new Attribute(type1, new DERSet(type1))); v.add(new Attribute(type2, new DERSet(type2))); AttributeTable table = new AttributeTable(v); Attribute a = table.get(type1); if (a == null) { fail("type1 attribute not found."); } if (!a.getAttrValues().equals(new DERSet(type1))) { fail("wrong value retrieved for type1!"); } a = table.get(type2); if (a == null) { fail("type2 attribute not found."); } if (!a.getAttrValues().equals(new DERSet(type2))) { fail("wrong value retrieved for type2!"); } a = table.get(type3); if (a != null) { fail("type3 attribute found when none expected."); } ASN1EncodableVector vec = table.getAll(type1); if (vec.size() != 1) { fail("wrong vector size for type1."); } vec = table.getAll(type3); if (vec.size() != 0) { fail("wrong vector size for type3."); } vec = table.toASN1EncodableVector(); if (vec.size() != 2) { fail("wrong vector size for single."); } Hashtable t = table.toHashtable(); if (t.size() != 2) { fail("hashtable wrong size."); } // multiple v = new ASN1EncodableVector(); v.add(new Attribute(type1, new DERSet(type1))); v.add(new Attribute(type1, new DERSet(type2))); v.add(new Attribute(type1, new DERSet(type3))); v.add(new Attribute(type2, new DERSet(type2))); table = new AttributeTable(v); a = table.get(type1); if (!a.getAttrValues().equals(new DERSet(type1))) { fail("wrong value retrieved for type1 multi get!"); } vec = table.getAll(type1); if (vec.size() != 3) { fail("wrong vector size for multiple type1."); } a = (Attribute)vec.get(0); if (!a.getAttrValues().equals(new DERSet(type1))) { fail("wrong value retrieved for type1(0)!"); } a = (Attribute)vec.get(1); if (!a.getAttrValues().equals(new DERSet(type2))) { fail("wrong value retrieved for type1(1)!"); } a = (Attribute)vec.get(2); if (!a.getAttrValues().equals(new DERSet(type3))) { fail("wrong value retrieved for type1(2)!"); } vec = table.getAll(type2); if (vec.size() != 1) { fail("wrong vector size for multiple type2."); } vec = table.toASN1EncodableVector(); if (vec.size() != 4) { fail("wrong vector size for multiple."); } } public static void main( String[] args) { runTest(new AttributeTableUnitTest()); } } bouncycastle-1.49.orig/test/src/org/bouncycastle/asn1/test/IssuingDistributionPointUnitTest.java0000644000175000017500000000745511624572761032726 0ustar ebourgebourgpackage org.bouncycastle.asn1.test; import java.io.IOException; import org.bouncycastle.asn1.ASN1Primitive; import org.bouncycastle.asn1.ASN1Sequence; import org.bouncycastle.asn1.x509.DistributionPointName; import org.bouncycastle.asn1.x509.GeneralName; import org.bouncycastle.asn1.x509.GeneralNames; import org.bouncycastle.asn1.x509.IssuingDistributionPoint; import org.bouncycastle.asn1.x509.ReasonFlags; import org.bouncycastle.asn1.x509.X509Name; import org.bouncycastle.util.test.SimpleTest; public class IssuingDistributionPointUnitTest extends SimpleTest { public String getName() { return "IssuingDistributionPoint"; } public void performTest() throws Exception { DistributionPointName name = new DistributionPointName( new GeneralNames(new GeneralName(new X509Name("cn=test")))); ReasonFlags reasonFlags = new ReasonFlags(ReasonFlags.cACompromise); checkPoint(6, name, true, true, reasonFlags, true, true); checkPoint(2, name, false, false, reasonFlags, false, false); checkPoint(0, null, false, false, null, false, false); try { IssuingDistributionPoint.getInstance(new Object()); fail("getInstance() failed to detect bad object."); } catch (IllegalArgumentException e) { // expected } } private void checkPoint( int size, DistributionPointName distributionPoint, boolean onlyContainsUserCerts, boolean onlyContainsCACerts, ReasonFlags onlySomeReasons, boolean indirectCRL, boolean onlyContainsAttributeCerts) throws IOException { IssuingDistributionPoint point = new IssuingDistributionPoint(distributionPoint, onlyContainsUserCerts, onlyContainsCACerts, onlySomeReasons, indirectCRL, onlyContainsAttributeCerts); checkValues(point, distributionPoint, onlyContainsUserCerts, onlyContainsCACerts, onlySomeReasons, indirectCRL, onlyContainsAttributeCerts); ASN1Sequence seq = ASN1Sequence.getInstance(ASN1Primitive.fromByteArray(point.getEncoded())); if (seq.size() != size) { fail("size mismatch"); } point = IssuingDistributionPoint.getInstance(seq); checkValues(point, distributionPoint, onlyContainsUserCerts, onlyContainsCACerts, onlySomeReasons, indirectCRL, onlyContainsAttributeCerts); } private void checkValues(IssuingDistributionPoint point, DistributionPointName distributionPoint, boolean onlyContainsUserCerts, boolean onlyContainsCACerts, ReasonFlags onlySomeReasons, boolean indirectCRL, boolean onlyContainsAttributeCerts) { if (point.onlyContainsUserCerts() != onlyContainsUserCerts) { fail("mismatch on onlyContainsUserCerts"); } if (point.onlyContainsCACerts() != onlyContainsCACerts) { fail("mismatch on onlyContainsCACerts"); } if (point.isIndirectCRL() != indirectCRL) { fail("mismatch on indirectCRL"); } if (point.onlyContainsAttributeCerts() != onlyContainsAttributeCerts) { fail("mismatch on onlyContainsAttributeCerts"); } if (!isEquiv(onlySomeReasons, point.getOnlySomeReasons())) { fail("mismatch on onlySomeReasons"); } if (!isEquiv(distributionPoint, point.getDistributionPoint())) { fail("mismatch on distributionPoint"); } } private boolean isEquiv(Object o1, Object o2) { if (o1 == null) { return o2 == null; } return o1.equals(o2); } public static void main( String[] args) { runTest(new IssuingDistributionPointUnitTest()); } }bouncycastle-1.49.orig/test/src/org/bouncycastle/asn1/test/OctetStringTest.java0000644000175000017500000001404211624652555027266 0ustar ebourgebourgpackage org.bouncycastle.asn1.test; import java.io.ByteArrayOutputStream; import java.io.InputStream; import java.io.OutputStream; import junit.framework.Test; import junit.framework.TestCase; import junit.framework.TestSuite; import org.bouncycastle.asn1.ASN1OctetStringParser; import org.bouncycastle.asn1.ASN1SequenceParser; import org.bouncycastle.asn1.ASN1StreamParser; import org.bouncycastle.asn1.BEROctetStringGenerator; import org.bouncycastle.asn1.BERSequenceGenerator; import org.bouncycastle.asn1.BERTags; import org.bouncycastle.asn1.DERInteger; import org.bouncycastle.asn1.DERObjectIdentifier; import org.bouncycastle.asn1.DERSequenceGenerator; import org.bouncycastle.asn1.cms.CMSObjectIdentifiers; import org.bouncycastle.asn1.cms.CompressedDataParser; import org.bouncycastle.asn1.cms.ContentInfoParser; public class OctetStringTest extends TestCase { public void testReadingWriting() throws Exception { ByteArrayOutputStream bOut = new ByteArrayOutputStream(); BEROctetStringGenerator octGen = new BEROctetStringGenerator(bOut); OutputStream out = octGen.getOctetOutputStream(); out.write(new byte[] { 1, 2, 3, 4 }); out.write(new byte[4]); out.close(); ASN1StreamParser aIn = new ASN1StreamParser(bOut.toByteArray()); ASN1OctetStringParser s = (ASN1OctetStringParser)aIn.readObject(); InputStream in = s.getOctetStream(); int count = 0; while (in.read() >= 0) { count++; } assertEquals(8, count); } public void testReadingWritingZeroInLength() throws Exception { ByteArrayOutputStream bOut = new ByteArrayOutputStream(); BEROctetStringGenerator octGen = new BEROctetStringGenerator(bOut); OutputStream out = octGen.getOctetOutputStream(); out.write(new byte[] { 1, 2, 3, 4 }); out.write(new byte[512]); // forces a zero to appear in length out.close(); ASN1StreamParser aIn = new ASN1StreamParser(bOut.toByteArray()); ASN1OctetStringParser s = (ASN1OctetStringParser)aIn.readObject(); InputStream in = s.getOctetStream(); int count = 0; while (in.read() >= 0) { count++; } assertEquals(516, count); } public void testReadingWritingNested() throws Exception { ByteArrayOutputStream bOut = new ByteArrayOutputStream(); BERSequenceGenerator sGen = new BERSequenceGenerator(bOut); BEROctetStringGenerator octGen = new BEROctetStringGenerator(sGen.getRawOutputStream()); OutputStream out = octGen.getOctetOutputStream(); BERSequenceGenerator inSGen = new BERSequenceGenerator(out); BEROctetStringGenerator inOctGen = new BEROctetStringGenerator(inSGen.getRawOutputStream()); OutputStream inOut = inOctGen.getOctetOutputStream(); inOut.write(new byte[] { 1, 2, 3, 4 }); inOut.write(new byte[10]); inOut.close(); inSGen.close(); out.close(); sGen.close(); ASN1StreamParser aIn = new ASN1StreamParser(bOut.toByteArray()); ASN1SequenceParser sq = (ASN1SequenceParser)aIn.readObject(); ASN1OctetStringParser s = (ASN1OctetStringParser)sq.readObject(); ASN1StreamParser aIn2 = new ASN1StreamParser(s.getOctetStream()); ASN1SequenceParser sq2 = (ASN1SequenceParser)aIn2.readObject(); ASN1OctetStringParser inS = (ASN1OctetStringParser)sq2.readObject(); InputStream in = inS.getOctetStream(); int count = 0; while (in.read() >= 0) { count++; } assertEquals(14, count); } public void testNestedStructure() throws Exception { ByteArrayOutputStream bOut = new ByteArrayOutputStream(); BERSequenceGenerator sGen = new BERSequenceGenerator(bOut); sGen.addObject(new DERObjectIdentifier(CMSObjectIdentifiers.compressedData.getId())); BERSequenceGenerator cGen = new BERSequenceGenerator(sGen.getRawOutputStream(), 0, true); cGen.addObject(new DERInteger(0)); // // AlgorithmIdentifier // DERSequenceGenerator algGen = new DERSequenceGenerator(cGen.getRawOutputStream()); algGen.addObject(new DERObjectIdentifier("1.2")); algGen.close(); // // Encapsulated ContentInfo // BERSequenceGenerator eiGen = new BERSequenceGenerator(cGen.getRawOutputStream()); eiGen.addObject(new DERObjectIdentifier("1.1")); BEROctetStringGenerator octGen = new BEROctetStringGenerator(eiGen.getRawOutputStream(), 0, true); // // output containing zeroes // OutputStream out = octGen.getOctetOutputStream(); out.write(new byte[] { 1, 2, 3, 4 }); out.write(new byte[4]); out.write(new byte[20]); out.close(); eiGen.close(); cGen.close(); sGen.close(); // // reading back // ASN1StreamParser aIn = new ASN1StreamParser(bOut.toByteArray()); ContentInfoParser cp = new ContentInfoParser((ASN1SequenceParser)aIn.readObject()); CompressedDataParser comData = new CompressedDataParser((ASN1SequenceParser)cp.getContent(BERTags.SEQUENCE)); ContentInfoParser content = comData.getEncapContentInfo(); ASN1OctetStringParser bytes = (ASN1OctetStringParser)content.getContent(BERTags.OCTET_STRING); InputStream in = bytes.getOctetStream(); int count = 0; while (in.read() >= 0) { count++; } assertEquals(28, count); } public static Test suite() { return new TestSuite(OctetStringTest.class); } } bouncycastle-1.49.orig/test/src/org/bouncycastle/asn1/test/TypeOfBiometricDataUnitTest.java0000644000175000017500000000724211706152250031507 0ustar ebourgebourgpackage org.bouncycastle.asn1.test; import java.io.IOException; import org.bouncycastle.asn1.ASN1InputStream; import org.bouncycastle.asn1.ASN1ObjectIdentifier; import org.bouncycastle.asn1.ASN1Primitive; import org.bouncycastle.asn1.DERObjectIdentifier; import org.bouncycastle.asn1.x509.qualified.TypeOfBiometricData; import org.bouncycastle.util.test.SimpleTest; public class TypeOfBiometricDataUnitTest extends SimpleTest { public String getName() { return "TypeOfBiometricData"; } public void performTest() throws Exception { // // predefined // checkPredefinedType(TypeOfBiometricData.PICTURE); checkPredefinedType(TypeOfBiometricData.HANDWRITTEN_SIGNATURE); // // non-predefined // ASN1ObjectIdentifier localType = new ASN1ObjectIdentifier("1.1"); TypeOfBiometricData type = new TypeOfBiometricData(localType); checkNonPredefined(type, localType); type = TypeOfBiometricData.getInstance(type); checkNonPredefined(type, localType); ASN1Primitive obj = type.toASN1Primitive(); type = TypeOfBiometricData.getInstance(obj); checkNonPredefined(type, localType); type = TypeOfBiometricData.getInstance(null); if (type != null) { fail("null getInstance() failed."); } try { TypeOfBiometricData.getInstance(new Object()); fail("getInstance() failed to detect bad object."); } catch (IllegalArgumentException e) { // expected } try { new TypeOfBiometricData(100); fail("constructor failed to detect bad predefined type."); } catch (IllegalArgumentException e) { // expected } if (TypeOfBiometricData.PICTURE != 0) { fail("predefined picture should be 0"); } if (TypeOfBiometricData.HANDWRITTEN_SIGNATURE != 1) { fail("predefined handwritten signature should be 1"); } } private void checkPredefinedType( int predefinedType) throws IOException { TypeOfBiometricData type = new TypeOfBiometricData(predefinedType); checkPredefined(type, predefinedType); type = TypeOfBiometricData.getInstance(type); checkPredefined(type, predefinedType); ASN1InputStream aIn = new ASN1InputStream(type.toASN1Object().getEncoded()); ASN1Primitive obj = aIn.readObject(); type = TypeOfBiometricData.getInstance(obj); checkPredefined(type, predefinedType); } private void checkPredefined( TypeOfBiometricData type, int value) { if (!type.isPredefined()) { fail("predefined type expected but not found."); } if (type.getPredefinedBiometricType() != value) { fail("predefined type does not match."); } } private void checkNonPredefined( TypeOfBiometricData type, DERObjectIdentifier value) { if (type.isPredefined()) { fail("predefined type found when not expected."); } if (!type.getBiometricDataOid().equals(value)) { fail("data oid does not match."); } } public static void main( String[] args) { runTest(new TypeOfBiometricDataUnitTest()); } } bouncycastle-1.49.orig/test/src/org/bouncycastle/asn1/test/InputStreamTest.java0000644000175000017500000000410111271743113027254 0ustar ebourgebourgpackage org.bouncycastle.asn1.test; import java.io.IOException; import org.bouncycastle.asn1.ASN1InputStream; import org.bouncycastle.util.test.SimpleTest; public class InputStreamTest extends SimpleTest { private static final byte[] outOfBoundsLength = new byte[] { (byte)0x30, (byte)0xff, (byte)0xff, (byte)0xff, (byte)0xff, (byte)0xff }; private static final byte[] negativeLength = new byte[] { (byte)0x30, (byte)0x84, (byte)0xff, (byte)0xff, (byte)0xff, (byte)0xff }; private static final byte[] outsideLimitLength = new byte[] { (byte)0x30, (byte)0x83, (byte)0x0f, (byte)0xff, (byte)0xff }; public String getName() { return "InputStream"; } public void performTest() throws Exception { ASN1InputStream aIn = new ASN1InputStream(outOfBoundsLength); try { aIn.readObject(); fail("out of bounds length not detected."); } catch (IOException e) { if (!e.getMessage().startsWith("DER length more than 4 bytes")) { fail("wrong exception: " + e.getMessage()); } } aIn = new ASN1InputStream(negativeLength); try { aIn.readObject(); fail("negative length not detected."); } catch (IOException e) { if (!e.getMessage().equals("corrupted stream - negative length found")) { fail("wrong exception: " + e.getMessage()); } } aIn = new ASN1InputStream(outsideLimitLength); try { aIn.readObject(); fail("outside limit length not detected."); } catch (IOException e) { if (!e.getMessage().equals("corrupted stream - out of bounds length found")) { fail("wrong exception: " + e.getMessage()); } } } public static void main( String[] args) { runTest(new InputStreamTest()); } } bouncycastle-1.49.orig/test/src/org/bouncycastle/asn1/test/PKCS10Test.java0000644000175000017500000000707011625357214025720 0ustar ebourgebourgpackage org.bouncycastle.asn1.test; import java.io.ByteArrayInputStream; import java.io.ByteArrayOutputStream; import org.bouncycastle.asn1.ASN1InputStream; import org.bouncycastle.asn1.ASN1Sequence; import org.bouncycastle.asn1.DEROutputStream; import org.bouncycastle.asn1.pkcs.CertificationRequest; import org.bouncycastle.util.encoders.Base64; import org.bouncycastle.util.test.SimpleTestResult; import org.bouncycastle.util.test.Test; import org.bouncycastle.util.test.TestResult; public class PKCS10Test implements Test { byte[] req1 = Base64.decode( "MIHoMIGTAgEAMC4xDjAMBgNVBAMTBVRlc3QyMQ8wDQYDVQQKEwZBbmFUb20xCzAJBgNVBAYTAlNF" + "MFwwDQYJKoZIhvcNAQEBBQADSwAwSAJBALlEt31Tzt2MlcOljvacJgzQVhmlMoqAOgqJ9Pgd3Gux" + "Z7/WcIlgW4QCB7WZT21O1YoghwBhPDMcNGrHei9kHQkCAwEAAaAAMA0GCSqGSIb3DQEBBQUAA0EA" + "NDEI4ecNtJ3uHwGGlitNFq9WxcoZ0djbQJ5hABMotav6gtqlrwKXY2evaIrsNwkJtNdwwH18aQDU" + "KCjOuBL38Q=="); byte[] req2 = Base64.decode( "MIIB6TCCAVICAQAwgagxCzAJBgNVBAYTAlVTMRMwEQYDVQQIEwpDYWxpZm9ybmlhMRQwEgYDVQQH" + "EwtTYW50YSBDbGFyYTEMMAoGA1UEChMDQUJCMVEwTwYDVQQLHEhQAAAAAAAAAG8AAAAAAAAAdwAA" + "AAAAAABlAAAAAAAAAHIAAAAAAAAAIAAAAAAAAABUAAAAAAAAABxIAAAAAAAARAAAAAAAAAAxDTAL" + "BgNVBAMTBGJsdWUwgZ8wDQYJKoZIhvcNAQEBBQADgY0AMIGJAoGBANETRZ+6occCOrFxNhfKIp4C" + "mMkxwhBNb7TnnahpbM9O0r4hrBPcfYuL7u9YX/jN0YNUP+/CiT39HhSe/bikaBPDEyNsl988I8vX" + "piEdgxYq/+LTgGHbjRsRYCkPtmzwBbuBldNF8bV7pu0v4UScSsExmGqqDlX1TbPU8KkPU1iTAgMB" + "AAGgADANBgkqhkiG9w0BAQQFAAOBgQAFbrs9qUwh93CtETk7DeUD5HcdCnxauo1bck44snSV6MZV" + "OCIGaYu1501kmhEvAtVVRr6SEHwimfQDDIjnrWwYsEr/DT6tkTZAbfRd3qUu3iKjT0H0vlUZp0hJ" + "66mINtBM84uZFBfoXiWY8M3FuAnGmvy6ah/dYtJorTxLKiGkew=="); public String getName() { return "PKCS10"; } public TestResult pkcs10Test( String testName, byte[] req) { try { ByteArrayInputStream bIn = new ByteArrayInputStream(req); ASN1InputStream aIn = new ASN1InputStream(bIn); CertificationRequest r = new CertificationRequest((ASN1Sequence)aIn.readObject()); ByteArrayOutputStream bOut = new ByteArrayOutputStream(); DEROutputStream dOut = new DEROutputStream(bOut); dOut.writeObject(r.toASN1Primitive()); byte[] bytes = bOut.toByteArray(); if (bytes.length != req.length) { return new SimpleTestResult(false, getName() + ": " + testName + " failed length test"); } for (int i = 0; i != req.length; i++) { if (bytes[i] != req[i]) { return new SimpleTestResult(false, getName() + ": " + testName + " failed comparison test"); } } } catch (Exception e) { return new SimpleTestResult(false, getName() + ": Exception - " + testName + " " + e.toString()); } return new SimpleTestResult(true, getName() + ": Okay"); } public TestResult perform() { TestResult res = pkcs10Test("basic CR", req1); if (!res.isSuccessful()) { return res; } return pkcs10Test("Universal CR", req2); } public static void main( String[] args) { Test test = new PKCS10Test(); TestResult result = test.perform(); System.out.println(result); } } bouncycastle-1.49.orig/test/src/org/bouncycastle/asn1/test/BitStringTest.java0000644000175000017500000000442511624572761026732 0ustar ebourgebourgpackage org.bouncycastle.asn1.test; import java.io.IOException; import org.bouncycastle.asn1.ASN1Primitive; import org.bouncycastle.asn1.DERBitString; import org.bouncycastle.asn1.x509.KeyUsage; import org.bouncycastle.util.test.SimpleTestResult; import org.bouncycastle.util.test.Test; import org.bouncycastle.util.test.TestResult; public class BitStringTest implements Test { public TestResult perform() { KeyUsage k = new KeyUsage(KeyUsage.digitalSignature); if ((k.getBytes()[0] != (byte)KeyUsage.digitalSignature) || (k.getPadBits() != 7)) { return new SimpleTestResult(false, getName() + ": failed digitalSignature"); } k = new KeyUsage(KeyUsage.nonRepudiation); if ((k.getBytes()[0] != (byte)KeyUsage.nonRepudiation) || (k.getPadBits() != 6)) { return new SimpleTestResult(false, getName() + ": failed nonRepudiation"); } k = new KeyUsage(KeyUsage.keyEncipherment); if ((k.getBytes()[0] != (byte)KeyUsage.keyEncipherment) || (k.getPadBits() != 5)) { return new SimpleTestResult(false, getName() + ": failed keyEncipherment"); } k = new KeyUsage(KeyUsage.cRLSign); if ((k.getBytes()[0] != (byte)KeyUsage.cRLSign) || (k.getPadBits() != 1)) { return new SimpleTestResult(false, getName() + ": failed cRLSign"); } k = new KeyUsage(KeyUsage.decipherOnly); if ((k.getBytes()[1] != (byte)(KeyUsage.decipherOnly >> 8)) || (k.getPadBits() != 7)) { return new SimpleTestResult(false, getName() + ": failed decipherOnly"); } // test for zero length bit string try { ASN1Primitive.fromByteArray(new DERBitString(new byte[0], 0).getEncoded()); } catch (IOException e) { return new SimpleTestResult(false, getName() + ": " + e); } return new SimpleTestResult(true, getName() + ": Okay"); } public String getName() { return "BitString"; } public static void main( String[] args) { BitStringTest test = new BitStringTest(); TestResult result = test.perform(); System.out.println(result); } } bouncycastle-1.49.orig/test/src/org/bouncycastle/asn1/test/RestrictionUnitTest.java0000644000175000017500000000322511625362145030161 0ustar ebourgebourgpackage org.bouncycastle.asn1.test; import java.io.IOException; import org.bouncycastle.asn1.ASN1InputStream; import org.bouncycastle.asn1.ASN1String; import org.bouncycastle.asn1.isismtt.x509.Restriction; import org.bouncycastle.asn1.x500.DirectoryString; public class RestrictionUnitTest extends ASN1UnitTest { public String getName() { return "Restriction"; } public void performTest() throws Exception { DirectoryString res = new DirectoryString("test"); Restriction restriction = new Restriction(res.getString()); checkConstruction(restriction, res); try { Restriction.getInstance(new Object()); fail("getInstance() failed to detect bad object."); } catch (IllegalArgumentException e) { // expected } } private void checkConstruction( Restriction restriction, DirectoryString res) throws IOException { checkValues(restriction, res); restriction = Restriction.getInstance(restriction); checkValues(restriction, res); ASN1InputStream aIn = new ASN1InputStream(restriction.toASN1Object().getEncoded()); ASN1String str = (ASN1String)aIn.readObject(); restriction = Restriction.getInstance(str); checkValues(restriction, res); } private void checkValues( Restriction restriction, DirectoryString res) { checkMandatoryField("restriction", res, restriction.getRestriction()); } public static void main( String[] args) { runTest(new RestrictionUnitTest()); } } bouncycastle-1.49.orig/test/src/org/bouncycastle/asn1/test/ParsingTest.java0000644000175000017500000003046611347573742026436 0ustar ebourgebourgpackage org.bouncycastle.asn1.test; import java.io.IOException; import org.bouncycastle.asn1.ASN1InputStream; import org.bouncycastle.asn1.ASN1StreamParser; import org.bouncycastle.util.encoders.Base64; import org.bouncycastle.util.test.SimpleTest; public class ParsingTest extends SimpleTest { String[] streams = { "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" }; public String getName() { return "ParsingTest"; } public void performTest() throws Exception { inputStreamTest(); parserTest(); } private void parserTest() { for (int i = 0; i != streams.length; i++) { ASN1StreamParser aIn = new ASN1StreamParser(Base64.decode(streams[i])); try { Object obj; while ((obj = aIn.readObject()) != null) { } fail("bad stream parsed successfully!"); } catch (IOException e) { // ignore } } } private void inputStreamTest() { for (int i = 0; i != streams.length; i++) { ASN1InputStream aIn = new ASN1InputStream(Base64.decode(streams[i])); try { Object obj; while ((obj = aIn.readObject()) != null) { } fail("bad stream parsed successfully!"); } catch (IOException e) { // ignore } } } public static void main( String[] args) { runTest(new ParsingTest()); } } bouncycastle-1.49.orig/test/src/org/bouncycastle/asn1/test/KeyUsageTest.java0000644000175000017500000000223410453643505026530 0ustar ebourgebourgpackage org.bouncycastle.asn1.test; import java.io.IOException; import org.bouncycastle.asn1.x509.KeyUsage; import org.bouncycastle.util.test.SimpleTest; public class KeyUsageTest extends SimpleTest { public String getName() { return "KeyUsage"; } public void performTest() throws IOException { BitStringConstantTester.testFlagValueCorrect(0, KeyUsage.digitalSignature); BitStringConstantTester.testFlagValueCorrect(1, KeyUsage.nonRepudiation); BitStringConstantTester.testFlagValueCorrect(2, KeyUsage.keyEncipherment); BitStringConstantTester.testFlagValueCorrect(3, KeyUsage.dataEncipherment); BitStringConstantTester.testFlagValueCorrect(4, KeyUsage.keyAgreement); BitStringConstantTester.testFlagValueCorrect(5, KeyUsage.keyCertSign); BitStringConstantTester.testFlagValueCorrect(6, KeyUsage.cRLSign); BitStringConstantTester.testFlagValueCorrect(7, KeyUsage.encipherOnly); BitStringConstantTester.testFlagValueCorrect(8, KeyUsage.decipherOnly); } public static void main( String[] args) { runTest(new KeyUsageTest()); } } bouncycastle-1.49.orig/test/src/org/bouncycastle/asn1/test/LDSSecurityObjectUnitTest.java0000644000175000017500000001404011531054040031136 0ustar ebourgebourgpackage org.bouncycastle.asn1.test; import java.io.IOException; import java.util.Random; import org.bouncycastle.asn1.ASN1EncodableVector; import org.bouncycastle.asn1.ASN1InputStream; import org.bouncycastle.asn1.ASN1Sequence; import org.bouncycastle.asn1.DEROctetString; import org.bouncycastle.asn1.DERSequence; import org.bouncycastle.asn1.icao.DataGroupHash; import org.bouncycastle.asn1.icao.LDSSecurityObject; import org.bouncycastle.asn1.icao.LDSVersionInfo; import org.bouncycastle.asn1.x509.AlgorithmIdentifier; import org.bouncycastle.util.test.SimpleTest; public class LDSSecurityObjectUnitTest extends SimpleTest { public String getName() { return "LDSSecurityObject"; } private byte[] generateHash() { Random rand = new Random(); byte[] bytes = new byte[20]; for (int i = 0; i != bytes.length; i++) { bytes[i] = (byte)rand.nextInt(); } return bytes; } public void performTest() throws Exception { AlgorithmIdentifier algoId = new AlgorithmIdentifier("1.3.14.3.2.26"); DataGroupHash[] datas = new DataGroupHash[2]; datas[0] = new DataGroupHash(1, new DEROctetString(generateHash())); datas[1] = new DataGroupHash(2, new DEROctetString(generateHash())); LDSSecurityObject so = new LDSSecurityObject(algoId, datas); checkConstruction(so, algoId, datas); LDSVersionInfo versionInfo = new LDSVersionInfo("Hello", "world"); so = new LDSSecurityObject(algoId, datas, versionInfo); checkConstruction(so, algoId, datas, versionInfo); try { LDSSecurityObject.getInstance(null); } catch (Exception e) { fail("getInstance() failed to handle null."); } try { LDSSecurityObject.getInstance(new Object()); fail("getInstance() failed to detect bad object."); } catch (IllegalArgumentException e) { // expected } try { ASN1EncodableVector v = new ASN1EncodableVector(); LDSSecurityObject.getInstance(new DERSequence(v)); fail("constructor failed to detect empty sequence."); } catch (IllegalArgumentException e) { // expected } try { new LDSSecurityObject(algoId, new DataGroupHash[1]); fail("constructor failed to detect small DataGroupHash array."); } catch (IllegalArgumentException e) { // expected } try { new LDSSecurityObject(algoId, new DataGroupHash[LDSSecurityObject.ub_DataGroups + 1]); fail("constructor failed to out of bounds DataGroupHash array."); } catch (IllegalArgumentException e) { // expected } } private void checkConstruction( LDSSecurityObject so, AlgorithmIdentifier digestAlgorithmIdentifier, DataGroupHash[] datagroupHash) throws IOException { checkStatement(so, digestAlgorithmIdentifier, datagroupHash, null); so = LDSSecurityObject.getInstance(so); checkStatement(so, digestAlgorithmIdentifier, datagroupHash, null); ASN1InputStream aIn = new ASN1InputStream(so.toASN1Object().getEncoded()); ASN1Sequence seq = (ASN1Sequence)aIn.readObject(); so = LDSSecurityObject.getInstance(seq); checkStatement(so, digestAlgorithmIdentifier, datagroupHash, null); } private void checkConstruction( LDSSecurityObject so, AlgorithmIdentifier digestAlgorithmIdentifier, DataGroupHash[] datagroupHash, LDSVersionInfo versionInfo) throws IOException { if (so.getVersion() != 1) { fail("version number not 1"); } checkStatement(so, digestAlgorithmIdentifier, datagroupHash, versionInfo); so = LDSSecurityObject.getInstance(so); checkStatement(so, digestAlgorithmIdentifier, datagroupHash, versionInfo); ASN1InputStream aIn = new ASN1InputStream(so.toASN1Object().getEncoded()); ASN1Sequence seq = (ASN1Sequence)aIn.readObject(); so = LDSSecurityObject.getInstance(seq); checkStatement(so, digestAlgorithmIdentifier, datagroupHash, versionInfo); } private void checkStatement( LDSSecurityObject so, AlgorithmIdentifier digestAlgorithmIdentifier, DataGroupHash[] datagroupHash, LDSVersionInfo versionInfo) { if (digestAlgorithmIdentifier != null) { if (!so.getDigestAlgorithmIdentifier().equals(digestAlgorithmIdentifier)) { fail("ids don't match."); } } else if (so.getDigestAlgorithmIdentifier() != null) { fail("digest algorithm Id found when none expected."); } if (datagroupHash != null) { DataGroupHash[] datas = so.getDatagroupHash(); for (int i = 0; i != datas.length; i++) { if (!datagroupHash[i].equals(datas[i])) { fail("name registration authorities don't match."); } } } else if (so.getDatagroupHash() != null) { fail("data hash groups found when none expected."); } if (versionInfo != null) { if (!versionInfo.equals(so.getVersionInfo())) { fail("versionInfo doesn't match"); } } else if (so.getVersionInfo() != null) { fail("version info found when none expected."); } } public static void main( String[] args) { runTest(new LDSSecurityObjectUnitTest()); } } bouncycastle-1.49.orig/test/src/org/bouncycastle/asn1/test/OCSPTest.java0000644000175000017500000001744110330633061025553 0ustar ebourgebourgpackage org.bouncycastle.asn1.test; import java.io.ByteArrayInputStream; import org.bouncycastle.asn1.ASN1InputStream; import org.bouncycastle.asn1.DEROctetString; import org.bouncycastle.asn1.ocsp.BasicOCSPResponse; import org.bouncycastle.asn1.ocsp.OCSPRequest; import org.bouncycastle.asn1.ocsp.OCSPResponse; import org.bouncycastle.asn1.ocsp.ResponseBytes; import org.bouncycastle.util.encoders.Base64; import org.bouncycastle.util.test.Test; import org.bouncycastle.util.test.TestResult; import org.bouncycastle.util.test.SimpleTestResult; public class OCSPTest implements Test { private byte[] unsignedReq = Base64.decode( "MEIwQDA+MDwwOjAJBgUrDgMCGgUABBRDb9GODnq7lRhSkEqw4XX24huERwQUkY4j" + "a6eKuDlkVP9hRgkEvIWqHPECAQE="); private byte[] signedReq = Base64.decode( "MIIC9jBAMD4wPDA6MAkGBSsOAwIaBQAEFENv0Y4OeruVGFKQSrDhdfbiG4RHBBTc" + "Mr1fP+mZAxbF2ZdehWxn6mtAngIBAaCCArAwggKsMA0GCSqGSIb3DQEBBQUAA4GB" + "AAzHBm4nL5AcRQB3Jkz7ScNeZF+GbRZ0p4kBDTnqi3IeESuso12yJhpqqyijdnj5" + "gd4/GsSAgdluLHyYZ6wgozV7G9MDXCnFnG4PBUW05HaVX81JYAp+amVyU0NOgNrG" + "90npVBsHb0o+UlkxNgMiEbSkp/TeGb6YURsYKhmwp7BgoIICFTCCAhEwggINMIIB" + "dqADAgECAgEBMA0GCSqGSIb3DQEBBAUAMCUxFjAUBgNVBAoTDUJvdW5jeSBDYXN0" + "bGUxCzAJBgNVBAYTAkFVMB4XDTA0MTAyNDEzNDc0M1oXDTA1MDIwMTEzNDc0M1ow" + "JTEWMBQGA1UEChMNQm91bmN5IENhc3RsZTELMAkGA1UEBhMCQVUwgZ8wDQYJKoZI" + "hvcNAQEBBQADgY0AMIGJAoGBAJBmLeIzthMHUeTkOeJ76iBxcMHY31o/i3a9VT12" + "y2FcS/ejJmeUCMTdtwl5alOwXY66vF4DyT1VU/nJG3mHpSoqq7qrMXOIFGcXg1Wf" + "oJRrQgTOLdQ6bod7i9ME/EjEJy70orh0nVS7NGcu0R5TjcbLde2J5zxjb/W9wqfy" + "RovJAgMBAAGjTTBLMB0GA1UdDgQWBBTcMr1fP+mZAxbF2ZdehWxn6mtAnjAfBgNV" + "HSMEGDAWgBTcMr1fP+mZAxbF2ZdehWxn6mtAnjAJBgNVHRMEAjAAMA0GCSqGSIb3" + "DQEBBAUAA4GBAF/4EH1KkNrNxocJPIp7lThmG1KIVYESIadowMowrbok46ESofRF" + "OIPku07W+e1Y1Y1KXLIiPMG3IGwrBrn04iLsbbBUiN37BcC/VyT4xKJ2MYscGjKL" + "ua/9bU0lOyeTRAwqb8towWRd5lLYAI3RQ7dhStUTFp3Vqd803PJ/cpR6"); private byte[] response = Base64.decode( "MIIFnAoBAKCCBZUwggWRBgkrBgEFBQcwAQEEggWCMIIFfjCCARehgZ8wgZwx" + "CzAJBgNVBAYTAklOMRcwFQYDVQQIEw5BbmRocmEgcHJhZGVzaDESMBAGA1UE" + "BxMJSHlkZXJhYmFkMQwwCgYDVQQKEwNUQ1MxDDAKBgNVBAsTA0FUQzEeMBwG" + "A1UEAxMVVENTLUNBIE9DU1AgUmVzcG9uZGVyMSQwIgYJKoZIhvcNAQkBFhVv" + "Y3NwQHRjcy1jYS50Y3MuY28uaW4YDzIwMDMwNDAyMTIzNDU4WjBiMGAwOjAJ" + "BgUrDgMCGgUABBRs07IuoCWNmcEl1oHwIak1BPnX8QQUtGyl/iL9WJ1VxjxF" + "j0hAwJ/s1AcCAQKhERgPMjAwMjA4MjkwNzA5MjZaGA8yMDAzMDQwMjEyMzQ1" + "OFowDQYJKoZIhvcNAQEFBQADgYEAfbN0TCRFKdhsmvOdUoiJ+qvygGBzDxD/" + "VWhXYA+16AphHLIWNABR3CgHB3zWtdy2j7DJmQ/R7qKj7dUhWLSqclAiPgFt" + "QQ1YvSJAYfEIdyHkxv4NP0LSogxrumANcDyC9yt/W9yHjD2ICPBIqCsZLuLk" + "OHYi5DlwWe9Zm9VFwCGgggPMMIIDyDCCA8QwggKsoAMCAQICAQYwDQYJKoZI" + "hvcNAQEFBQAwgZQxFDASBgNVBAMTC1RDUy1DQSBPQ1NQMSYwJAYJKoZIhvcN" + "AQkBFhd0Y3MtY2FAdGNzLWNhLnRjcy5jby5pbjEMMAoGA1UEChMDVENTMQww" + "CgYDVQQLEwNBVEMxEjAQBgNVBAcTCUh5ZGVyYWJhZDEXMBUGA1UECBMOQW5k" + "aHJhIHByYWRlc2gxCzAJBgNVBAYTAklOMB4XDTAyMDgyOTA3MTE0M1oXDTAz" + "MDgyOTA3MTE0M1owgZwxCzAJBgNVBAYTAklOMRcwFQYDVQQIEw5BbmRocmEg" + "cHJhZGVzaDESMBAGA1UEBxMJSHlkZXJhYmFkMQwwCgYDVQQKEwNUQ1MxDDAK" + "BgNVBAsTA0FUQzEeMBwGA1UEAxMVVENTLUNBIE9DU1AgUmVzcG9uZGVyMSQw" + "IgYJKoZIhvcNAQkBFhVvY3NwQHRjcy1jYS50Y3MuY28uaW4wgZ8wDQYJKoZI" + "hvcNAQEBBQADgY0AMIGJAoGBAM+XWW4caMRv46D7L6Bv8iwtKgmQu0SAybmF" + "RJiz12qXzdvTLt8C75OdgmUomxp0+gW/4XlTPUqOMQWv463aZRv9Ust4f8MH" + "EJh4ekP/NS9+d8vEO3P40ntQkmSMcFmtA9E1koUtQ3MSJlcs441JjbgUaVnm" + "jDmmniQnZY4bU3tVAgMBAAGjgZowgZcwDAYDVR0TAQH/BAIwADALBgNVHQ8E" + "BAMCB4AwEwYDVR0lBAwwCgYIKwYBBQUHAwkwNgYIKwYBBQUHAQEEKjAoMCYG" + "CCsGAQUFBzABhhpodHRwOi8vMTcyLjE5LjQwLjExMDo3NzAwLzAtBgNVHR8E" + "JjAkMCKgIKAehhxodHRwOi8vMTcyLjE5LjQwLjExMC9jcmwuY3JsMA0GCSqG" + "SIb3DQEBBQUAA4IBAQB6FovM3B4VDDZ15o12gnADZsIk9fTAczLlcrmXLNN4" + "PgmqgnwF0Ymj3bD5SavDOXxbA65AZJ7rBNAguLUo+xVkgxmoBH7R2sBxjTCc" + "r07NEadxM3HQkt0aX5XYEl8eRoifwqYAI9h0ziZfTNes8elNfb3DoPPjqq6V" + "mMg0f0iMS4W8LjNPorjRB+kIosa1deAGPhq0eJ8yr0/s2QR2/WFD5P4aXc8I" + "KWleklnIImS3zqiPrq6tl2Bm8DZj7vXlTOwmraSQxUwzCKwYob1yGvNOUQTq" + "pG6jxn7jgDawHU1+WjWQe4Q34/pWeGLysxTraMa+Ug9kPe+jy/qRX2xwvKBZ"); private boolean isSameAs( byte[] a, byte[] b) { if (a.length != b.length) { return false; } for (int i = 0; i != a.length; i++) { if (a[i] != b[i]) { return false; } } return true; } private TestResult unsignedRequest() { try { ASN1InputStream aIn = new ASN1InputStream(new ByteArrayInputStream(unsignedReq)); OCSPRequest req = OCSPRequest.getInstance(aIn.readObject()); if (!isSameAs(req.getEncoded(), unsignedReq)) { return new SimpleTestResult(false, getName() + ": OCSP unsigned request failed to re-encode"); } return new SimpleTestResult(true, getName() + ": Okay"); } catch (Exception e) { return new SimpleTestResult(false, getName() + ": failed unsigned exception - " + e.toString(), e); } } private TestResult signedRequest() { try { ASN1InputStream aIn = new ASN1InputStream(new ByteArrayInputStream(signedReq)); OCSPRequest req = OCSPRequest.getInstance(aIn.readObject()); if (!isSameAs(req.getEncoded(), signedReq)) { return new SimpleTestResult(false, getName() + ": OCSP signed request failed to re-encode"); } return new SimpleTestResult(true, getName() + ": Okay"); } catch (Exception e) { return new SimpleTestResult(false, getName() + ": failed signed exception - " + e.toString(), e); } } private TestResult response() { try { ASN1InputStream aIn = new ASN1InputStream(new ByteArrayInputStream(response)); OCSPResponse resp = OCSPResponse.getInstance(aIn.readObject()); ResponseBytes rBytes = ResponseBytes.getInstance(resp.getResponseBytes()); aIn = new ASN1InputStream(new ByteArrayInputStream(rBytes.getResponse().getOctets())); BasicOCSPResponse bResp = BasicOCSPResponse.getInstance(aIn.readObject()); resp = new OCSPResponse(resp.getResponseStatus(), new ResponseBytes(rBytes.getResponseType(), new DEROctetString(bResp.getEncoded()))); if (!isSameAs(resp.getEncoded(), response)) { return new SimpleTestResult(false, getName() + ": OCSP response failed to re-encode"); } return new SimpleTestResult(true, getName() + ": Okay"); } catch (Exception e) { return new SimpleTestResult(false, getName() + ": failed response exception - " + e.toString(), e); } } public TestResult perform() { TestResult res = unsignedRequest(); if (!res.isSuccessful()) { return res; } res = signedRequest(); if (!res.isSuccessful()) { return res; } return response(); } public String getName() { return "OCSP"; } public static void main( String[] args) { OCSPTest test = new OCSPTest(); TestResult result = test.perform(); System.out.println(result); } } bouncycastle-1.49.orig/test/src/org/bouncycastle/asn1/test/UTCTimeTest.java0000644000175000017500000000536710536762161026301 0ustar ebourgebourgpackage org.bouncycastle.asn1.test; import org.bouncycastle.asn1.DERUTCTime; import org.bouncycastle.util.test.SimpleTest; import java.text.SimpleDateFormat; import java.util.SimpleTimeZone; /** * X.690 test example */ public class UTCTimeTest extends SimpleTest { String[] input = { "020122122220Z", "020122122220-1000", "020122122220+1000", "020122122220+00", "0201221222Z", "0201221222-1000", "0201221222+1000", "0201221222+00", "550122122220Z", "5501221222Z" }; String[] output = { "20020122122220GMT+00:00", "20020122122220GMT-10:00", "20020122122220GMT+10:00", "20020122122220GMT+00:00", "20020122122200GMT+00:00", "20020122122200GMT-10:00", "20020122122200GMT+10:00", "20020122122200GMT+00:00", "19550122122220GMT+00:00", "19550122122200GMT+00:00" }; String[] zOutput1 = { "20020122122220Z", "20020122222220Z", "20020122022220Z", "20020122122220Z", "20020122122200Z", "20020122222200Z", "20020122022200Z", "20020122122200Z", "19550122122220Z", "19550122122200Z" }; String[] zOutput2 = { "20020122122220Z", "20020122222220Z", "20020122022220Z", "20020122122220Z", "20020122122200Z", "20020122222200Z", "20020122022200Z", "20020122122200Z", "19550122122220Z", "19550122122200Z" }; public String getName() { return "UTCTime"; } public void performTest() throws Exception { SimpleDateFormat yyyyF = new SimpleDateFormat("yyyyMMddHHmmss'Z'"); SimpleDateFormat yyF = new SimpleDateFormat("yyyyMMddHHmmss'Z'"); yyyyF.setTimeZone(new SimpleTimeZone(0,"Z")); yyF.setTimeZone(new SimpleTimeZone(0,"Z")); for (int i = 0; i != input.length; i++) { DERUTCTime t = new DERUTCTime(input[i]); if (!t.getAdjustedTime().equals(output[i])) { fail("failed conversion test " + i); } if (!yyyyF.format(t.getAdjustedDate()).equals(zOutput1[i])) { fail("failed date conversion test " + i); } if (!yyF.format(t.getDate()).equals(zOutput2[i])) { fail("failed date shortened conversion test " + i); } } } public static void main( String[] args) { runTest(new UTCTimeTest()); } } bouncycastle-1.49.orig/test/src/org/bouncycastle/asn1/test/NamingAuthorityUnitTest.java0000644000175000017500000000622410574463432031003 0ustar ebourgebourgpackage org.bouncycastle.asn1.test; import org.bouncycastle.asn1.ASN1InputStream; import org.bouncycastle.asn1.ASN1Sequence; import org.bouncycastle.asn1.DERObjectIdentifier; import org.bouncycastle.asn1.isismtt.x509.NamingAuthority; import org.bouncycastle.asn1.x500.DirectoryString; import java.io.IOException; public class NamingAuthorityUnitTest extends ASN1UnitTest { public String getName() { return "NamingAuthority"; } public void performTest() throws Exception { DERObjectIdentifier namingAuthorityID = new DERObjectIdentifier("1.2.3"); String namingAuthorityURL = "url"; DirectoryString namingAuthorityText = new DirectoryString("text"); NamingAuthority auth = new NamingAuthority(namingAuthorityID, namingAuthorityURL, namingAuthorityText); checkConstruction(auth, namingAuthorityID, namingAuthorityURL, namingAuthorityText); auth = new NamingAuthority(null, namingAuthorityURL, namingAuthorityText); checkConstruction(auth, null, namingAuthorityURL, namingAuthorityText); auth = new NamingAuthority(namingAuthorityID, null, namingAuthorityText); checkConstruction(auth, namingAuthorityID, null, namingAuthorityText); auth = new NamingAuthority(namingAuthorityID, namingAuthorityURL, null); checkConstruction(auth, namingAuthorityID, namingAuthorityURL, null); auth = NamingAuthority.getInstance(null); if (auth != null) { fail("null getInstance() failed."); } try { NamingAuthority.getInstance(new Object()); fail("getInstance() failed to detect bad object."); } catch (IllegalArgumentException e) { // expected } } private void checkConstruction( NamingAuthority auth, DERObjectIdentifier namingAuthorityID, String namingAuthorityURL, DirectoryString namingAuthorityText) throws IOException { checkValues(auth, namingAuthorityID, namingAuthorityURL, namingAuthorityText); auth = NamingAuthority.getInstance(auth); checkValues(auth, namingAuthorityID, namingAuthorityURL, namingAuthorityText); ASN1InputStream aIn = new ASN1InputStream(auth.toASN1Object().getEncoded()); ASN1Sequence seq = (ASN1Sequence)aIn.readObject(); auth = NamingAuthority.getInstance(seq); checkValues(auth, namingAuthorityID, namingAuthorityURL, namingAuthorityText); } private void checkValues( NamingAuthority auth, DERObjectIdentifier namingAuthorityId, String namingAuthorityURL, DirectoryString namingAuthorityText) { checkOptionalField("namingAuthorityId", namingAuthorityId, auth.getNamingAuthorityId()); checkOptionalField("namingAuthorityURL", namingAuthorityURL, auth.getNamingAuthorityUrl()); checkOptionalField("namingAuthorityText", namingAuthorityText, auth.getNamingAuthorityText()); } public static void main( String[] args) { runTest(new NamingAuthorityUnitTest()); } } bouncycastle-1.49.orig/test/src/org/bouncycastle/asn1/test/SMIMETest.java0000644000175000017500000000707111625103500025655 0ustar ebourgebourgpackage org.bouncycastle.asn1.test; import java.io.ByteArrayInputStream; import org.bouncycastle.asn1.ASN1InputStream; import org.bouncycastle.asn1.ASN1Primitive; import org.bouncycastle.asn1.DERGeneralizedTime; import org.bouncycastle.asn1.DEROctetString; import org.bouncycastle.asn1.cms.RecipientKeyIdentifier; import org.bouncycastle.asn1.smime.SMIMECapabilitiesAttribute; import org.bouncycastle.asn1.smime.SMIMECapability; import org.bouncycastle.asn1.smime.SMIMECapabilityVector; import org.bouncycastle.asn1.smime.SMIMEEncryptionKeyPreferenceAttribute; import org.bouncycastle.util.encoders.Base64; import org.bouncycastle.util.test.SimpleTestResult; import org.bouncycastle.util.test.Test; import org.bouncycastle.util.test.TestResult; public class SMIMETest implements Test { byte[] attrBytes = Base64.decode("MDQGCSqGSIb3DQEJDzEnMCUwCgYIKoZIhvcNAwcwDgYIKoZIhvcNAwICAgCAMAcGBSsOAwIH"); byte[] prefBytes = Base64.decode("MCwGCyqGSIb3DQEJEAILMR2hGwQIAAAAAAAAAAAYDzIwMDcwMzE1MTczNzI5Wg=="); private boolean isSameAs( byte[] a, byte[] b) { if (a.length != b.length) { return false; } for (int i = 0; i != a.length; i++) { if (a[i] != b[i]) { return false; } } return true; } public TestResult perform() { SMIMECapabilityVector caps = new SMIMECapabilityVector(); caps.addCapability(SMIMECapability.dES_EDE3_CBC); caps.addCapability(SMIMECapability.rC2_CBC, 128); caps.addCapability(SMIMECapability.dES_CBC); SMIMECapabilitiesAttribute attr = new SMIMECapabilitiesAttribute(caps); SMIMEEncryptionKeyPreferenceAttribute pref = new SMIMEEncryptionKeyPreferenceAttribute( new RecipientKeyIdentifier(new DEROctetString(new byte[8]), new DERGeneralizedTime("20070315173729Z"), null)); try { if (!isSameAs(attr.getEncoded(), attrBytes)) { return new SimpleTestResult(false, getName() + ": Failed attr data check"); } ByteArrayInputStream bIn = new ByteArrayInputStream(attrBytes); ASN1InputStream aIn = new ASN1InputStream(bIn); ASN1Primitive o = aIn.readObject(); if (!attr.equals(o)) { return new SimpleTestResult(false, getName() + ": Failed equality test for attr"); } if (!isSameAs(pref.getEncoded(), prefBytes)) { return new SimpleTestResult(false, getName() + ": Failed attr data check"); } bIn = new ByteArrayInputStream(prefBytes); aIn = new ASN1InputStream(bIn); o = aIn.readObject(); if (!pref.equals(o)) { return new SimpleTestResult(false, getName() + ": Failed equality test for pref"); } return new SimpleTestResult(true, getName() + ": Okay"); } catch (Exception e) { return new SimpleTestResult(false, getName() + ": Failed - exception " + e.toString(), e); } } public String getName() { return "SMIME"; } public static void main( String[] args) { SMIMETest test = new SMIMETest(); TestResult result = test.perform(); System.out.println(result); } } bouncycastle-1.49.orig/test/src/org/bouncycastle/asn1/test/RequestedCertificateUnitTest.java0000644000175000017500000000624311737272275031773 0ustar ebourgebourgpackage org.bouncycastle.asn1.test; import java.io.IOException; import org.bouncycastle.asn1.ASN1InputStream; import org.bouncycastle.asn1.isismtt.ocsp.RequestedCertificate; import org.bouncycastle.asn1.x509.Certificate; import org.bouncycastle.util.encoders.Base64; public class RequestedCertificateUnitTest extends ASN1UnitTest { byte[] certBytes = Base64.decode( "MIIBWzCCAQYCARgwDQYJKoZIhvcNAQEEBQAwODELMAkGA1UEBhMCQVUxDDAKBgNV" + "BAgTA1FMRDEbMBkGA1UEAxMSU1NMZWF5L3JzYSB0ZXN0IENBMB4XDTk1MDYxOTIz" + "MzMxMloXDTk1MDcxNzIzMzMxMlowOjELMAkGA1UEBhMCQVUxDDAKBgNVBAgTA1FM" + "RDEdMBsGA1UEAxMUU1NMZWF5L3JzYSB0ZXN0IGNlcnQwXDANBgkqhkiG9w0BAQEF" + "AANLADBIAkEAqtt6qS5GTxVxGZYWa0/4u+IwHf7p2LNZbcPBp9/OfIcYAXBQn8hO" + "/Re1uwLKXdCjIoaGs4DLdG88rkzfyK5dPQIDAQABMAwGCCqGSIb3DQIFBQADQQAE" + "Wc7EcF8po2/ZO6kNCwK/ICH6DobgLekA5lSLr5EvuioZniZp5lFzAw4+YzPQ7XKJ" + "zl9HYIMxATFyqSiD9jsx"); public String getName() { return "RequestedCertificate"; } public void performTest() throws Exception { int type = 1; byte[] certOctets = new byte[20]; Certificate cert = Certificate.getInstance(certBytes); RequestedCertificate requested = new RequestedCertificate(type, certOctets); checkConstruction(requested, type, certOctets, null); requested = new RequestedCertificate(cert); checkConstruction(requested, RequestedCertificate.certificate, null, cert); requested = RequestedCertificate.getInstance(null); if (requested != null) { fail("null getInstance() failed."); } try { RequestedCertificate.getInstance(new Object()); fail("getInstance() failed to detect bad object."); } catch (IllegalArgumentException e) { // expected } } private void checkConstruction( RequestedCertificate requested, int type, byte[] certOctets, Certificate cert) throws IOException { checkValues(requested, type, certOctets, cert); requested = RequestedCertificate.getInstance(requested); checkValues(requested, type, certOctets, cert); ASN1InputStream aIn = new ASN1InputStream(requested.toASN1Object().getEncoded()); Object obj = aIn.readObject(); requested = RequestedCertificate.getInstance(obj); checkValues(requested, type, certOctets, cert); } private void checkValues( RequestedCertificate requested, int type, byte[] certOctets, Certificate cert) throws IOException { checkMandatoryField("certType", type, requested.getType()); if (requested.getType() == RequestedCertificate.certificate) { checkMandatoryField("certificate", cert.getEncoded(), requested.getCertificateBytes()); } else { checkMandatoryField("certificateOctets", certOctets, requested.getCertificateBytes()); } } public static void main( String[] args) { runTest(new RequestedCertificateUnitTest()); } } bouncycastle-1.49.orig/test/src/org/bouncycastle/asn1/test/SetTest.java0000644000175000017500000000604510705061772025552 0ustar ebourgebourgpackage org.bouncycastle.asn1.test; import org.bouncycastle.asn1.ASN1EncodableVector; import org.bouncycastle.asn1.ASN1Set; import org.bouncycastle.asn1.ASN1TaggedObject; import org.bouncycastle.asn1.BERSet; import org.bouncycastle.asn1.DERBitString; import org.bouncycastle.asn1.DERBoolean; import org.bouncycastle.asn1.DERInteger; import org.bouncycastle.asn1.DEROctetString; import org.bouncycastle.asn1.DERSequence; import org.bouncycastle.asn1.DERSet; import org.bouncycastle.asn1.DERTaggedObject; import org.bouncycastle.util.test.SimpleTest; /** * Set sorting test example */ public class SetTest extends SimpleTest { public String getName() { return "Set"; } private void checkedSortedSet(int attempt, ASN1Set s) { if (s.getObjectAt(0) instanceof DERBoolean && s.getObjectAt(1) instanceof DERInteger && s.getObjectAt(2) instanceof DERBitString && s.getObjectAt(3) instanceof DEROctetString) { return; } fail("sorting failed on attempt: " + attempt); } public void performTest() { ASN1EncodableVector v = new ASN1EncodableVector(); byte[] data = new byte[10]; v.add(new DEROctetString(data)); v.add(new DERBitString(data)); v.add(new DERInteger(100)); v.add(new DERBoolean(true)); checkedSortedSet(0, new DERSet(v)); v = new ASN1EncodableVector(); v.add(new DERInteger(100)); v.add(new DERBoolean(true)); v.add(new DEROctetString(data)); v.add(new DERBitString(data)); checkedSortedSet(1, new DERSet(v)); v = new ASN1EncodableVector(); v.add(new DERBoolean(true)); v.add(new DEROctetString(data)); v.add(new DERBitString(data)); v.add(new DERInteger(100)); checkedSortedSet(2, new DERSet(v)); v = new ASN1EncodableVector(); v.add(new DERBitString(data)); v.add(new DEROctetString(data)); v.add(new DERInteger(100)); v.add(new DERBoolean(true)); checkedSortedSet(3, new DERSet(v)); v = new ASN1EncodableVector(); v.add(new DEROctetString(data)); v.add(new DERBitString(data)); v.add(new DERInteger(100)); v.add(new DERBoolean(true)); ASN1Set s = new BERSet(v); if (!(s.getObjectAt(0) instanceof DEROctetString)) { fail("BER set sort order changed."); } // create an implicitly tagged "set" without sorting ASN1TaggedObject tag = new DERTaggedObject(false, 1, new DERSequence(v)); s = ASN1Set.getInstance(tag, false); if (s.getObjectAt(0) instanceof DERBoolean) { fail("sorted when shouldn't be."); } // equality test v = new ASN1EncodableVector(); v.add(new DERBoolean(true)); v.add(new DERBoolean(true)); v.add(new DERBoolean(true)); s = new DERSet(v); } public static void main( String[] args) { runTest(new SetTest()); } } bouncycastle-1.49.orig/test/src/org/bouncycastle/asn1/test/PKCS12Test.java0000644000175000017500000002624311625624627025732 0ustar ebourgebourgpackage org.bouncycastle.asn1.test; import java.io.ByteArrayInputStream; import java.io.ByteArrayOutputStream; import org.bouncycastle.asn1.ASN1InputStream; import org.bouncycastle.asn1.ASN1OctetString; import org.bouncycastle.asn1.ASN1OutputStream; import org.bouncycastle.asn1.ASN1Sequence; import org.bouncycastle.asn1.BEROctetString; import org.bouncycastle.asn1.DLSequence; import org.bouncycastle.asn1.pkcs.AuthenticatedSafe; import org.bouncycastle.asn1.pkcs.ContentInfo; import org.bouncycastle.asn1.pkcs.EncryptedData; import org.bouncycastle.asn1.pkcs.EncryptedPrivateKeyInfo; import org.bouncycastle.asn1.pkcs.MacData; import org.bouncycastle.asn1.pkcs.PKCSObjectIdentifiers; import org.bouncycastle.asn1.pkcs.Pfx; import org.bouncycastle.asn1.pkcs.SafeBag; import org.bouncycastle.asn1.x509.AlgorithmIdentifier; import org.bouncycastle.asn1.x509.DigestInfo; import org.bouncycastle.util.Arrays; import org.bouncycastle.util.encoders.Base64; import org.bouncycastle.util.test.SimpleTest; public class PKCS12Test extends SimpleTest { byte[] pkcs12 = Base64.decode( "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" + "AgFkAAA="); public void performTest() throws Exception { ASN1InputStream aIn = new ASN1InputStream(new ByteArrayInputStream(pkcs12)); ASN1Sequence obj = (ASN1Sequence)aIn.readObject(); Pfx bag = Pfx.getInstance(obj); ContentInfo info = bag.getAuthSafe(); MacData mData = bag.getMacData(); DigestInfo dInfo = mData.getMac(); AlgorithmIdentifier algId = dInfo.getAlgorithmId(); byte[] salt = mData.getSalt(); int itCount = mData.getIterationCount().intValue(); aIn = new ASN1InputStream(new ByteArrayInputStream(((ASN1OctetString)info.getContent()).getOctets())); AuthenticatedSafe authSafe = AuthenticatedSafe.getInstance(aIn.readObject()); ContentInfo[] c = authSafe.getContentInfo(); // // private key section // if (!c[0].getContentType().equals(PKCSObjectIdentifiers.data)) { fail("failed comparison data test"); } aIn = new ASN1InputStream(new ByteArrayInputStream(((ASN1OctetString)c[0].getContent()).getOctets())); ASN1Sequence seq = (ASN1Sequence)aIn.readObject(); SafeBag b = SafeBag.getInstance(seq.getObjectAt(0)); if (!b.getBagId().equals(PKCSObjectIdentifiers.pkcs8ShroudedKeyBag)) { fail("failed comparison shroudedKeyBag test"); } EncryptedPrivateKeyInfo encInfo = EncryptedPrivateKeyInfo.getInstance(b.getBagValue()); encInfo = new EncryptedPrivateKeyInfo(encInfo.getEncryptionAlgorithm(), encInfo.getEncryptedData()); b = new SafeBag(PKCSObjectIdentifiers.pkcs8ShroudedKeyBag, encInfo.toASN1Primitive(), b.getBagAttributes()); ByteArrayOutputStream abOut = new ByteArrayOutputStream(); ASN1OutputStream berOut = new ASN1OutputStream(abOut); berOut.writeObject(new DLSequence(b)); c[0] = new ContentInfo(PKCSObjectIdentifiers.data, new BEROctetString(abOut.toByteArray())); // // certificates // if (!c[1].getContentType().equals(PKCSObjectIdentifiers.encryptedData)) { fail("failed comparison encryptedData test"); } EncryptedData eData = EncryptedData.getInstance(c[1].getContent()); c[1] = new ContentInfo(PKCSObjectIdentifiers.encryptedData, eData); // // create an octet stream represent the BER encoding of authSafe // authSafe = new AuthenticatedSafe(c); abOut = new ByteArrayOutputStream(); berOut = new ASN1OutputStream(abOut); berOut.writeObject(authSafe); info = new ContentInfo(PKCSObjectIdentifiers.data, new BEROctetString(abOut.toByteArray())); mData = new MacData(new DigestInfo(algId, dInfo.getDigest()), salt, itCount); bag = new Pfx(info, mData); // // comparison test // ByteArrayOutputStream bOut = new ByteArrayOutputStream(); ASN1OutputStream aOut = new ASN1OutputStream(bOut); aOut.writeObject(bag); if (!Arrays.areEqual(bOut.toByteArray(), pkcs12)) { fail("failed comparison test"); } } public String getName() { return "PKCS12"; } public static void main( String[] args) { runTest(new PKCS12Test()); } } bouncycastle-1.49.orig/test/src/org/bouncycastle/asn1/test/CMSTest.java0000644000175000017500000003734211625105602025436 0ustar ebourgebourgpackage org.bouncycastle.asn1.test; import java.io.ByteArrayInputStream; import java.io.ByteArrayOutputStream; import java.io.InputStream; import org.bouncycastle.asn1.ASN1InputStream; import org.bouncycastle.asn1.ASN1OctetStringParser; import org.bouncycastle.asn1.ASN1OutputStream; import org.bouncycastle.asn1.ASN1SequenceParser; import org.bouncycastle.asn1.ASN1Set; import org.bouncycastle.asn1.ASN1SetParser; import org.bouncycastle.asn1.ASN1StreamParser; import org.bouncycastle.asn1.BERTags; import org.bouncycastle.asn1.DERSet; import org.bouncycastle.asn1.cms.CMSObjectIdentifiers; import org.bouncycastle.asn1.cms.CompressedData; import org.bouncycastle.asn1.cms.ContentInfo; import org.bouncycastle.asn1.cms.ContentInfoParser; import org.bouncycastle.asn1.cms.EncryptedContentInfoParser; import org.bouncycastle.asn1.cms.EnvelopedData; import org.bouncycastle.asn1.cms.EnvelopedDataParser; import org.bouncycastle.asn1.cms.KEKRecipientInfo; import org.bouncycastle.asn1.cms.KeyTransRecipientInfo; import org.bouncycastle.asn1.cms.RecipientInfo; import org.bouncycastle.asn1.cms.SignedData; import org.bouncycastle.util.encoders.Base64; import org.bouncycastle.util.io.Streams; import org.bouncycastle.util.test.SimpleTestResult; import org.bouncycastle.util.test.Test; import org.bouncycastle.util.test.TestResult; public class CMSTest implements Test { // // compressed data object // byte[] compData = Base64.decode( "MIAGCyqGSIb3DQEJEAEJoIAwgAIBADANBgsqhkiG9w0BCRADCDCABgkqhkiG9w0BBwGggCSABIIC" + "Hnic7ZRdb9owFIbvK/k/5PqVYPFXGK12YYyboVFASSp1vQtZGiLRACZE49/XHoUW7S/0tXP8Efux" + "fU5ivWnasml72XFb3gb5druui7ytN803M570nii7C5r8tfwR281hy/p/KSM3+jzH5s3+pbQ90xSb" + "P3VT3QbLusnt8WPIuN5vN/vaA2+DulnXTXkXvNTr8j8ouZmkCmGI/UW+ZS/C8zP0bz2dz0zwLt+1" + "UEk2M8mlaxjRMByAhZTj0RGYg4TvogiRASROsZgjpVcJCb1KV6QzQeDJ1XkoQ5Jm+C5PbOHZZGRi" + "v+ORAcshOGeCcdFJyfgFxdtCdEcmOrbinc/+BBMzRThEYpwl+jEBpciSGWQkI0TSlREmD/eOHb2D" + "SGLuESm/iKUFt1y4XHBO2a5oq0IKJKWLS9kUZTA7vC5LSxYmgVL46SIWxIfWBQd6AdrnjLmH94UT" + "vGxVibLqRCtIpp4g2qpdtqK1LiOeolpVK5wVQ5P7+QjZAlrh0cePYTx/gNZuB9Vhndtgujl9T/tg" + "W9ogK+3rnmg3YWygnTuF5GDS+Q/jIVLnCcYZFc6Kk/+c80wKwZjwdZIqDYWRH68MuBQSXLgXYXj2" + "3CAaYOBNJMliTl0X7eV5DnoKIFSKYdj3cRpD/cK/JWTHJRe76MUXnfBW8m7Hd5zhQ4ri2NrVF/WL" + "+kV1/3AGSlJ32bFPd2BsQD8uSzIx6lObkjdz95c0AAAAAAAAAAAAAAAA"); // // enveloped data // byte[] envDataKeyTrns = Base64.decode( "MIAGCSqGSIb3DQEHA6CAMIACAQAxgcQwgcECAQAwKjAlMRYwFAYDVQQKEw1Cb3Vu" + "Y3kgQ2FzdGxlMQswCQYDVQQGEwJBVQIBCjANBgkqhkiG9w0BAQEFAASBgC5vdGrB" + "itQSGwifLf3KwPILjaB4WEXgT/IIO1KDzrsbItCJsMA0Smq2y0zptxT0pSRL6JRg" + "NMxLk1ySnrIrvGiEPLMR1zjxlT8yQ6VLX+kEoK43ztd1aaLw0oBfrcXcLN7BEpZ1" + "TIdjlBfXIOx1S88WY1MiYqJJFc3LMwRUaTEDMIAGCSqGSIb3DQEHATAdBglghkgB" + "ZQMEARYEEAfxLMWeaBOTTZQwUq0Y5FuggAQgwOJhL04rjSZCBCSOv5i5XpFfGsOd" + "YSHSqwntGpFqCx4AAAAAAAAAAAAA"); byte[] envDataKEK = Base64.decode( "MIAGCSqGSIb3DQEHA6CAMIACAQIxUqJQAgEEMAcEBQECAwQFMBAGCyqGSIb3DQEJE" + "AMHAgE6BDC7G/HyUPilIrin2Yeajqmj795VoLWETRnZAAFcAiQdoQWyz+oCh6WY/H" + "jHHi+0y+cwgAYJKoZIhvcNAQcBMBQGCCqGSIb3DQMHBAiY3eDBBbF6naCABBiNdzJb" + "/v6+UZB3XXKipxFDUpz9GyjzB+gAAAAAAAAAAAAA"); byte[] envDataNestedNDEF = Base64.decode( "MIAGCSqGSIb3DQEHA6CAMIACAQAxge8wgewCAQAwgZUwgY8xKDAmBgNVBAoMH1RoZSBMZWdpb24g" + "b2YgdGhlIEJvdW5jeSBDYXN0bGUxLzAtBgkqhkiG9w0BCQEWIGZlZWRiYWNrLWNyeXB0b0Bib3Vu" + "Y3ljYXN0bGUub3JnMREwDwYDVQQIDAhWaWN0b3JpYTESMBAGA1UEBwwJTWVsYm91cm5lMQswCQYD" + "VQQGEwJBVQIBATANBgkqhkiG9w0BAQEFAARABIXMd8xiTyWDKO/LQfvdGYTPW3I9oSQWwtm4OIaN" + "VINpfY2lfwTvbmE6VXiLKeALC0dMBV8z7DEM9hE0HVmvLDCABgkqhkiG9w0BBwEwHQYJYIZIAWUD" + "BAECBBB32ko6WrVxDTqwUYEpV6IUoIAEggKgS6RowrhNlmWWI13zxD/lryxkZ5oWXPUfNiUxYX/P" + "r5iscW3s8VKJKUpJ4W5SNA7JGL4l/5LmSnJ4Qu/xzxcoH4r4vmt75EDE9p2Ob2Xi1NuSFAZubJFc" + "Zlnp4e05UHKikmoaz0PbiAi277sLQlK2FcVsntTYVT00y8+IwuuQu0ATVqkXC+VhfjV/sK6vQZnw" + "2rQKedZhLB7B4dUkmxCujb/UAq4lgSpLMXg2P6wMimTczXyQxRiZxPeI4ByCENjkafXbfcJft2eD" + "gv1DEDdYM5WrW9Z75b4lmJiOJ/xxDniHCvum7KGXzpK1d1mqTlpzPC2xoz08/MO4lRf5Mb0bYdq6" + "CjMaYqVwGsYryp/2ayX+d8H+JphEG+V9Eg8uPcDoibwhDI4KkoyGHstPw5bxcy7vVFt7LXUdNjJc" + "K1wxaUKEXDGKt9Vj93FnBTLMX0Pc9HpueV5o1ipX34dn/P3HZB9XK8ScbrE38B1VnIgylStnhVFO" + "Cj9s7qSVqI2L+xYHJRHsxaMumIRnmRuOqdXDfIo28EZAnFtQ/b9BziMGVvAW5+A8h8s2oazhSmK2" + "23ftV7uv98ScgE8fCd3PwT1kKJM83ThTYyBzokvMfPYCCvsonMV+kTWXhWcwjYTS4ukrpR452ZdW" + "l3aJqDnzobt5FK4T8OGciOj+1PxYFZyRmCuafm2Dx6o7Et2Tu/T5HYvhdY9jHyqtDl2PXH4CTnVi" + "gA1YOAArjPVmsZVwAM3Ml46uyXXhcsXwQ1X0Tv4D+PSa/id4UQ2cObOw8Cj1eW2GB8iJIZVqkZaU" + "XBexqgWYOIoxjqODSeoZKiBsTK3c+oOUBqBDueY1i55swE2o6dDt95FluX6iyr/q4w2wLt3upY1J" + "YL+TuvZxAKviuAczMS1bAAAAAAAAAAAAAA=="); // // signed data // byte[] signedData = Base64.decode( "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" + "a+fEv4J8wQ8Xwvk0C8iMAAAAAAAA"); private boolean isSameAs( byte[] a, byte[] b) { if (a.length != b.length) { return false; } for (int i = 0; i != a.length; i++) { if (a[i] != b[i]) { return false; } } return true; } private TestResult compressionTest() { try { ASN1InputStream aIn = new ASN1InputStream(new ByteArrayInputStream(compData)); ContentInfo info = ContentInfo.getInstance(aIn.readObject()); CompressedData data = CompressedData.getInstance(info.getContent()); data = new CompressedData(data.getCompressionAlgorithmIdentifier(), data.getEncapContentInfo()); info = new ContentInfo(CMSObjectIdentifiers.compressedData, data); ByteArrayOutputStream bOut = new ByteArrayOutputStream(); ASN1OutputStream aOut = new ASN1OutputStream(bOut); aOut.writeObject(info); if (!isSameAs(bOut.toByteArray(), compData)) { return new SimpleTestResult(false, getName() + ": CMS compression failed to re-encode"); } return new SimpleTestResult(true, getName() + ": Okay"); } catch (Exception e) { return new SimpleTestResult(false, getName() + ": CMS compression failed - " + e.toString(), e); } } private TestResult envelopedTest() { try { // // Key trans // ASN1InputStream aIn = new ASN1InputStream(new ByteArrayInputStream(envDataKeyTrns)); ContentInfo info = ContentInfo.getInstance(aIn.readObject()); EnvelopedData envData = EnvelopedData.getInstance(info.getContent()); ASN1Set s = envData.getRecipientInfos(); if (s.size() != 1) { return new SimpleTestResult(false, getName() + ": CMS KeyTrans enveloped, wrong number of recipients"); } RecipientInfo recip = RecipientInfo.getInstance(s.getObjectAt(0)); if (recip.getInfo() instanceof KeyTransRecipientInfo) { KeyTransRecipientInfo inf = KeyTransRecipientInfo.getInstance(recip.getInfo()); inf = new KeyTransRecipientInfo(inf.getRecipientIdentifier(), inf.getKeyEncryptionAlgorithm(), inf.getEncryptedKey()); s = new DERSet(new RecipientInfo(inf)); } else { return new SimpleTestResult(false, getName() + ": CMS KeyTrans enveloped, wrong recipient type"); } ByteArrayOutputStream bOut = new ByteArrayOutputStream(); ASN1OutputStream aOut = new ASN1OutputStream(bOut); envData = new EnvelopedData(envData.getOriginatorInfo(), s, envData.getEncryptedContentInfo(), envData.getUnprotectedAttrs()); info = new ContentInfo(CMSObjectIdentifiers.envelopedData, envData); aOut.writeObject(info); if (!isSameAs(bOut.toByteArray(), envDataKeyTrns)) { return new SimpleTestResult(false, getName() + ": CMS KeyTrans enveloped failed to re-encode"); } // // KEK // aIn = new ASN1InputStream(new ByteArrayInputStream(envDataKEK)); info = ContentInfo.getInstance(aIn.readObject()); envData = EnvelopedData.getInstance(info.getContent()); s = envData.getRecipientInfos(); if (s.size() != 1) { return new SimpleTestResult(false, getName() + ": CMS KEK enveloped, wrong number of recipients"); } recip = RecipientInfo.getInstance(s.getObjectAt(0)); if (recip.getInfo() instanceof KEKRecipientInfo) { KEKRecipientInfo inf = KEKRecipientInfo.getInstance(recip.getInfo()); inf = new KEKRecipientInfo(inf.getKekid(), inf.getKeyEncryptionAlgorithm(), inf.getEncryptedKey()); s = new DERSet(new RecipientInfo(inf)); } else { return new SimpleTestResult(false, getName() + ": CMS KEK enveloped, wrong recipient type"); } bOut = new ByteArrayOutputStream(); aOut = new ASN1OutputStream(bOut); envData = new EnvelopedData(envData.getOriginatorInfo(), s, envData.getEncryptedContentInfo(), envData.getUnprotectedAttrs()); info = new ContentInfo(CMSObjectIdentifiers.envelopedData, envData); aOut.writeObject(info); if (!isSameAs(bOut.toByteArray(), envDataKEK)) { System.out.println(new String(Base64.encode(bOut.toByteArray()))); return new SimpleTestResult(false, getName() + ": CMS KEK enveloped failed to re-encode"); } // Nested NDEF problem ASN1StreamParser asn1In = new ASN1StreamParser(new ByteArrayInputStream(envDataNestedNDEF)); ContentInfoParser ci = new ContentInfoParser((ASN1SequenceParser)asn1In.readObject()); EnvelopedDataParser ed = new EnvelopedDataParser((ASN1SequenceParser)ci .getContent(BERTags.SEQUENCE)); ed.getVersion(); ed.getOriginatorInfo(); ed.getRecipientInfos().toASN1Primitive(); EncryptedContentInfoParser eci = ed.getEncryptedContentInfo(); eci.getContentType(); eci.getContentEncryptionAlgorithm(); InputStream dataIn = ((ASN1OctetStringParser)eci.getEncryptedContent(BERTags.OCTET_STRING)) .getOctetStream(); Streams.drain(dataIn); dataIn.close(); // Test data doesn't have unprotected attrs, bug was being thrown by this call ASN1SetParser upa = ed.getUnprotectedAttrs(); if (upa != null) { upa.toASN1Primitive(); } return new SimpleTestResult(true, getName() + ": Okay"); } catch (Exception e) { return new SimpleTestResult(false, getName() + ": CMS enveloped failed - " + e.toString(), e); } } private TestResult signedTest() { try { ASN1InputStream aIn = new ASN1InputStream(new ByteArrayInputStream(signedData)); ContentInfo info = ContentInfo.getInstance(aIn.readObject()); SignedData sData = SignedData.getInstance(info.getContent()); ByteArrayOutputStream bOut = new ByteArrayOutputStream(); ASN1OutputStream aOut = new ASN1OutputStream(bOut); sData = new SignedData(sData.getDigestAlgorithms(), sData.getEncapContentInfo(), sData.getCertificates(), sData.getCRLs(), sData.getSignerInfos()); info = new ContentInfo(CMSObjectIdentifiers.signedData, sData); aOut.writeObject(info); if (!isSameAs(bOut.toByteArray(), signedData)) { return new SimpleTestResult(false, getName() + ": CMS signed failed to re-encode"); } return new SimpleTestResult(true, getName() + ": Okay"); } catch (Exception e) { return new SimpleTestResult(false, getName() + ": CMS signed failed - " + e.toString(), e); } } public TestResult perform() { TestResult res = compressionTest(); if (!res.isSuccessful()) { return res; } res = envelopedTest(); if (!res.isSuccessful()) { return res; } return signedTest(); } public String getName() { return "CMS"; } public static void main( String[] args) { CMSTest test = new CMSTest(); TestResult result = test.perform(); System.out.println(result); } } bouncycastle-1.49.orig/test/src/org/bouncycastle/asn1/test/ProfessionInfoUnitTest.java0000644000175000017500000001036611724561172030624 0ustar ebourgebourgpackage org.bouncycastle.asn1.test; import java.io.IOException; import org.bouncycastle.asn1.ASN1InputStream; import org.bouncycastle.asn1.ASN1ObjectIdentifier; import org.bouncycastle.asn1.ASN1Sequence; import org.bouncycastle.asn1.DERObjectIdentifier; import org.bouncycastle.asn1.DEROctetString; import org.bouncycastle.asn1.isismtt.x509.NamingAuthority; import org.bouncycastle.asn1.isismtt.x509.ProcurationSyntax; import org.bouncycastle.asn1.isismtt.x509.ProfessionInfo; import org.bouncycastle.asn1.x500.DirectoryString; public class ProfessionInfoUnitTest extends ASN1UnitTest { public String getName() { return "ProfessionInfo"; } public void performTest() throws Exception { NamingAuthority auth = new NamingAuthority(new DERObjectIdentifier("1.2.3"), "url", new DirectoryString("fred")); DirectoryString[] professionItems = { new DirectoryString("substitution") }; ASN1ObjectIdentifier[] professionOids = { new ASN1ObjectIdentifier("1.2.3") }; String registrationNumber = "12345"; DEROctetString addProfInfo = new DEROctetString(new byte[20]); ProfessionInfo info = new ProfessionInfo(auth, professionItems, professionOids, registrationNumber, addProfInfo); checkConstruction(info, auth, professionItems, professionOids, registrationNumber, addProfInfo); info = new ProfessionInfo(null, professionItems, professionOids, registrationNumber, addProfInfo); checkConstruction(info, null, professionItems, professionOids, registrationNumber, addProfInfo); info = new ProfessionInfo(auth, professionItems, null, registrationNumber, addProfInfo); checkConstruction(info, auth, professionItems, null, registrationNumber, addProfInfo); info = new ProfessionInfo(auth, professionItems, professionOids, null, addProfInfo); checkConstruction(info, auth, professionItems, professionOids, null, addProfInfo); info = new ProfessionInfo(auth, professionItems, professionOids, registrationNumber, null); checkConstruction(info, auth, professionItems, professionOids, registrationNumber, null); info = ProfessionInfo.getInstance(null); if (info != null) { fail("null getInstance() failed."); } try { ProcurationSyntax.getInstance(new Object()); fail("getInstance() failed to detect bad object."); } catch (IllegalArgumentException e) { // expected } } private void checkConstruction( ProfessionInfo profInfo, NamingAuthority auth, DirectoryString[] professionItems, DERObjectIdentifier[] professionOids, String registrationNumber, DEROctetString addProfInfo) throws IOException { checkValues(profInfo, auth, professionItems, professionOids, registrationNumber, addProfInfo); profInfo = ProfessionInfo.getInstance(profInfo); checkValues(profInfo, auth, professionItems, professionOids, registrationNumber, addProfInfo); ASN1InputStream aIn = new ASN1InputStream(profInfo.toASN1Object().getEncoded()); ASN1Sequence seq = (ASN1Sequence)aIn.readObject(); profInfo = ProfessionInfo.getInstance(seq); checkValues(profInfo, auth, professionItems, professionOids, registrationNumber, addProfInfo); } private void checkValues( ProfessionInfo profInfo, NamingAuthority auth, DirectoryString[] professionItems, DERObjectIdentifier[] professionOids, String registrationNumber, DEROctetString addProfInfo) { checkOptionalField("auth", auth, profInfo.getNamingAuthority()); checkMandatoryField("professionItems", professionItems[0], profInfo.getProfessionItems()[0]); if (professionOids != null) { checkOptionalField("professionOids", professionOids[0], profInfo.getProfessionOIDs()[0]); } checkOptionalField("registrationNumber", registrationNumber, profInfo.getRegistrationNumber()); checkOptionalField("addProfessionInfo", addProfInfo, profInfo.getAddProfessionInfo()); } public static void main( String[] args) { runTest(new ProfessionInfoUnitTest()); } } bouncycastle-1.49.orig/test/src/org/bouncycastle/asn1/test/AdmissionsUnitTest.java0000644000175000017500000000461210571736200027762 0ustar ebourgebourgpackage org.bouncycastle.asn1.test; import org.bouncycastle.asn1.ASN1InputStream; import org.bouncycastle.asn1.ASN1Sequence; import org.bouncycastle.asn1.DERObjectIdentifier; import org.bouncycastle.asn1.isismtt.x509.Admissions; import org.bouncycastle.asn1.isismtt.x509.NamingAuthority; import org.bouncycastle.asn1.isismtt.x509.ProfessionInfo; import org.bouncycastle.asn1.x500.DirectoryString; import org.bouncycastle.asn1.x509.GeneralName; import org.bouncycastle.asn1.x509.X509Name; import java.io.IOException; public class AdmissionsUnitTest extends ASN1UnitTest { public String getName() { return "Admissions"; } public void performTest() throws Exception { GeneralName name = new GeneralName(new X509Name("CN=hello world")); NamingAuthority auth = new NamingAuthority(new DERObjectIdentifier("1.2.3"), "url", new DirectoryString("fred")); Admissions admissions = new Admissions(name, auth, new ProfessionInfo[0]); checkConstruction(admissions, name, auth); admissions = Admissions.getInstance(null); if (admissions != null) { fail("null getInstance() failed."); } try { Admissions.getInstance(new Object()); fail("getInstance() failed to detect bad object."); } catch (IllegalArgumentException e) { // expected } } private void checkConstruction( Admissions admissions, GeneralName name, NamingAuthority auth) throws IOException { checkValues(admissions, name, auth); admissions = Admissions.getInstance(admissions); checkValues(admissions, name, auth); ASN1InputStream aIn = new ASN1InputStream(admissions.toASN1Object().getEncoded()); ASN1Sequence info = (ASN1Sequence)aIn.readObject(); admissions = Admissions.getInstance(info); checkValues(admissions, name, auth); } private void checkValues( Admissions admissions, GeneralName name, NamingAuthority auth) { checkMandatoryField("admissionAuthority", name, admissions.getAdmissionAuthority()); checkMandatoryField("namingAuthority", auth, admissions.getNamingAuthority()); } public static void main( String[] args) { runTest(new AdmissionsUnitTest()); } } bouncycastle-1.49.orig/test/src/org/bouncycastle/asn1/test/AdditionalInformationSyntaxUnitTest.java0000644000175000017500000000343511625362145033344 0ustar ebourgebourgpackage org.bouncycastle.asn1.test; import java.io.IOException; import org.bouncycastle.asn1.ASN1InputStream; import org.bouncycastle.asn1.ASN1String; import org.bouncycastle.asn1.isismtt.x509.AdditionalInformationSyntax; import org.bouncycastle.asn1.x500.DirectoryString; public class AdditionalInformationSyntaxUnitTest extends ASN1UnitTest { public String getName() { return "AdditionalInformationSyntax"; } public void performTest() throws Exception { AdditionalInformationSyntax syntax = new AdditionalInformationSyntax("hello world"); checkConstruction(syntax, new DirectoryString("hello world")); try { AdditionalInformationSyntax.getInstance(new Object()); fail("getInstance() failed to detect bad object."); } catch (IllegalArgumentException e) { // expected } } private void checkConstruction( AdditionalInformationSyntax syntax, DirectoryString information) throws IOException { checkValues(syntax, information); syntax = AdditionalInformationSyntax.getInstance(syntax); checkValues(syntax, information); ASN1InputStream aIn = new ASN1InputStream(syntax.toASN1Object().getEncoded()); ASN1String info = (ASN1String)aIn.readObject(); syntax = AdditionalInformationSyntax.getInstance(info); checkValues(syntax, information); } private void checkValues( AdditionalInformationSyntax syntax, DirectoryString information) { checkMandatoryField("information", information, syntax.getInformation()); } public static void main( String[] args) { runTest(new AdditionalInformationSyntaxUnitTest()); } } bouncycastle-1.49.orig/test/src/org/bouncycastle/asn1/test/SubjectKeyIdentifierTest.java0000644000175000017500000000315111624572761031073 0ustar ebourgebourgpackage org.bouncycastle.asn1.test; import java.io.IOException; import org.bouncycastle.asn1.ASN1Primitive; import org.bouncycastle.asn1.x509.SubjectKeyIdentifier; import org.bouncycastle.asn1.x509.SubjectPublicKeyInfo; import org.bouncycastle.util.Arrays; import org.bouncycastle.util.encoders.Base64; import org.bouncycastle.util.encoders.Hex; import org.bouncycastle.util.test.SimpleTest; public class SubjectKeyIdentifierTest extends SimpleTest { private static byte[] pubKeyInfo = Base64.decode( "MFgwCwYJKoZIhvcNAQEBA0kAMEYCQQC6wMMmHYMZszT/7bNFMn+gaZoiWJLVP8ODRuu1C2jeAe" + "QpxM+5Oe7PaN2GNy3nBE4EOYkB5pMJWA0y9n04FX8NAgED"); private static byte[] shaID = Hex.decode("d8128a06d6c2feb0865994a2936e7b75b836a021"); private static byte[] shaTruncID = Hex.decode("436e7b75b836a021"); public String getName() { return "SubjectKeyIdentifier"; } public void performTest() throws IOException { SubjectPublicKeyInfo pubInfo = SubjectPublicKeyInfo.getInstance(ASN1Primitive.fromByteArray(pubKeyInfo)); SubjectKeyIdentifier ski = SubjectKeyIdentifier.createSHA1KeyIdentifier(pubInfo); if (!Arrays.areEqual(shaID, ski.getKeyIdentifier())) { fail("SHA-1 ID does not match"); } ski = SubjectKeyIdentifier.createTruncatedSHA1KeyIdentifier(pubInfo); if (!Arrays.areEqual(shaTruncID, ski.getKeyIdentifier())) { fail("truncated SHA-1 ID does not match"); } } public static void main( String[] args) { runTest(new SubjectKeyIdentifierTest()); } } bouncycastle-1.49.orig/test/src/org/bouncycastle/asn1/test/DERApplicationSpecificTest.java0000644000175000017500000000516311625105642031260 0ustar ebourgebourgpackage org.bouncycastle.asn1.test; import org.bouncycastle.asn1.ASN1Encoding; import org.bouncycastle.asn1.ASN1Primitive; import org.bouncycastle.asn1.BERTags; import org.bouncycastle.asn1.DERApplicationSpecific; import org.bouncycastle.asn1.DERInteger; import org.bouncycastle.util.Arrays; import org.bouncycastle.util.encoders.Hex; import org.bouncycastle.util.test.SimpleTest; public class DERApplicationSpecificTest extends SimpleTest { private static final byte[] impData = Hex.decode("430109"); private static final byte[] certData = Hex.decode( "7F218201897F4E8201495F290100420E44454356434145504153533030317F49" + "81FD060A04007F00070202020202811CD7C134AA264366862A18302575D1D787" + "B09F075797DA89F57EC8C0FF821C68A5E62CA9CE6C1C299803A6C1530B514E18" + "2AD8B0042A59CAD29F43831C2580F63CCFE44138870713B1A92369E33E2135D2" + "66DBB372386C400B8439040D9029AD2C7E5CF4340823B2A87DC68C9E4CE3174C" + "1E6EFDEE12C07D58AA56F772C0726F24C6B89E4ECDAC24354B9E99CAA3F6D376" + "1402CD851CD7C134AA264366862A18302575D0FB98D116BC4B6DDEBCA3A5A793" + "9F863904393EE8E06DB6C7F528F8B4260B49AA93309824D92CDB1807E5437EE2" + "E26E29B73A7111530FA86B350037CB9415E153704394463797139E148701015F" + "200E44454356434145504153533030317F4C0E060904007F0007030102015301" + "C15F25060007000400015F24060009000400015F37384CCF25C59F3612EEE188" + "75F6C5F2E2D21F0395683B532A26E4C189B71EFE659C3F26E0EB9AEAE9986310" + "7F9B0DADA16414FFA204516AEE2B"); public String getName() { return "DERApplicationSpecific"; } public void performTest() throws Exception { DERInteger value = new DERInteger(9); DERApplicationSpecific tagged = new DERApplicationSpecific(false, 3, value); if (!areEqual(impData, tagged.getEncoded())) { fail("implicit encoding failed"); } DERInteger recVal = (DERInteger)tagged.getObject(BERTags.INTEGER); if (!value.equals(recVal)) { fail("implicit read back failed"); } DERApplicationSpecific certObj = (DERApplicationSpecific) ASN1Primitive.fromByteArray(certData); if (!certObj.isConstructed() || certObj.getApplicationTag() != 33) { fail("parsing of certificate data failed"); } byte[] encoded = certObj.getEncoded(ASN1Encoding.DER); if (!Arrays.areEqual(certData, encoded)) { fail("re-encoding of certificate data failed"); } } public static void main( String[] args) { runTest(new DERApplicationSpecificTest()); } } bouncycastle-1.49.orig/test/src/org/bouncycastle/asn1/test/TagTest.java0000644000175000017500000000650711624653521025535 0ustar ebourgebourgpackage org.bouncycastle.asn1.test; import java.io.IOException; import java.security.SecureRandom; import org.bouncycastle.asn1.ASN1InputStream; import org.bouncycastle.asn1.ASN1Primitive; import org.bouncycastle.asn1.ASN1TaggedObject; import org.bouncycastle.asn1.DERApplicationSpecific; import org.bouncycastle.util.encoders.Base64; import org.bouncycastle.util.encoders.Hex; import org.bouncycastle.util.test.SimpleTest; /** * X.690 test example */ public class TagTest extends SimpleTest { byte[] longTagged = Base64.decode( "ZSRzIp8gEEZFRENCQTk4NzY1NDMyMTCfIQwyMDA2MDQwMTEyMzSUCCAFERVz" + "A4kCAHEXGBkalAggBRcYGRqUCCAFZS6QAkRFkQlURUNITklLRVKSBQECAwQF" + "kxAREhMUFRYXGBkalAggBREVcwOJAgBxFxgZGpQIIAUXGBkalAggBWUukAJE" + "RZEJVEVDSE5JS0VSkgUBAgMEBZMQERITFBUWFxgZGpQIIAURFXMDiQIAcRcY" + "GRqUCCAFFxgZGpQIIAVlLpACREWRCVRFQ0hOSUtFUpIFAQIDBAWTEBESExQV" + "FhcYGRqUCCAFERVzA4kCAHEXGBkalAggBRcYGRqUCCAFFxgZGpQIIAUXGBka" + "lAg="); byte[] longAppSpecificTag = Hex.decode("5F610101"); public String getName() { return "Tag"; } public void performTest() throws IOException { ASN1InputStream aIn = new ASN1InputStream(longTagged); DERApplicationSpecific app = (DERApplicationSpecific)aIn.readObject(); aIn = new ASN1InputStream(app.getContents()); app = (DERApplicationSpecific)aIn.readObject(); aIn = new ASN1InputStream(app.getContents()); ASN1TaggedObject tagged = (ASN1TaggedObject)aIn.readObject(); if (tagged.getTagNo() != 32) { fail("unexpected tag value found - not 32"); } tagged = (ASN1TaggedObject)ASN1Primitive.fromByteArray(tagged.getEncoded()); if (tagged.getTagNo() != 32) { fail("unexpected tag value found on recode - not 32"); } tagged = (ASN1TaggedObject)aIn.readObject(); if (tagged.getTagNo() != 33) { fail("unexpected tag value found - not 33"); } tagged = (ASN1TaggedObject)ASN1Primitive.fromByteArray(tagged.getEncoded()); if (tagged.getTagNo() != 33) { fail("unexpected tag value found on recode - not 33"); } aIn = new ASN1InputStream(longAppSpecificTag); app = (DERApplicationSpecific)aIn.readObject(); if (app.getApplicationTag() != 97) { fail("incorrect tag number read"); } app = (DERApplicationSpecific)ASN1Primitive.fromByteArray(app.getEncoded()); if (app.getApplicationTag() != 97) { fail("incorrect tag number read on recode"); } SecureRandom sr = new SecureRandom(); for (int i = 0; i < 100; ++i) { int testTag = sr.nextInt() >>> (1 + (sr.nextInt() >>> 1) % 26); app = new DERApplicationSpecific(testTag, new byte[]{ 1 }); app = (DERApplicationSpecific)ASN1Primitive.fromByteArray(app.getEncoded()); if (app.getApplicationTag() != testTag) { fail("incorrect tag number read on recode (random test value: " + testTag + ")"); } } } public static void main( String[] args) { runTest(new TagTest()); } } bouncycastle-1.49.orig/test/src/org/bouncycastle/asn1/test/AllTests.java0000644000175000017500000000214311725320340025675 0ustar ebourgebourgpackage org.bouncycastle.asn1.test; import junit.framework.Test; import junit.framework.TestCase; import junit.framework.TestSuite; import org.bouncycastle.util.test.SimpleTestResult; public class AllTests extends TestCase { public void testASN1() { org.bouncycastle.util.test.Test[] tests = RegressionTest.tests; for (int i = 0; i != tests.length; i++) { SimpleTestResult result = (SimpleTestResult)tests[i].perform(); if (!result.isSuccessful()) { fail(result.toString()); } } } public static void main (String[] args) { junit.textui.TestRunner.run(suite()); } public static Test suite() { TestSuite suite = new TestSuite("ASN.1 Tests"); suite.addTestSuite(AllTests.class); suite.addTestSuite(GetInstanceTest.class); suite.addTestSuite(ASN1SequenceParserTest.class); suite.addTestSuite(OctetStringTest.class); suite.addTestSuite(ParseTest.class); return suite; } } bouncycastle-1.49.orig/test/src/org/bouncycastle/asn1/test/BiometricDataUnitTest.java0000644000175000017500000000746012103437527030367 0ustar ebourgebourgpackage org.bouncycastle.asn1.test; import java.security.SecureRandom; import org.bouncycastle.asn1.ASN1InputStream; import org.bouncycastle.asn1.ASN1OctetString; import org.bouncycastle.asn1.ASN1Sequence; import org.bouncycastle.asn1.DERIA5String; import org.bouncycastle.asn1.DERNull; import org.bouncycastle.asn1.DEROctetString; import org.bouncycastle.asn1.oiw.OIWObjectIdentifiers; import org.bouncycastle.asn1.x509.AlgorithmIdentifier; import org.bouncycastle.asn1.x509.qualified.BiometricData; import org.bouncycastle.asn1.x509.qualified.TypeOfBiometricData; import org.bouncycastle.util.test.SimpleTest; public class BiometricDataUnitTest extends SimpleTest { public String getName() { return "BiometricData"; } private byte[] generateHash() { SecureRandom rand = new SecureRandom(); byte[] bytes = new byte[20]; rand.nextBytes(bytes); return bytes; } public void performTest() throws Exception { TypeOfBiometricData dataType = new TypeOfBiometricData(TypeOfBiometricData.HANDWRITTEN_SIGNATURE); AlgorithmIdentifier hashAlgorithm = new AlgorithmIdentifier(OIWObjectIdentifiers.idSHA1, DERNull.INSTANCE); ASN1OctetString dataHash = new DEROctetString(generateHash()); BiometricData bd = new BiometricData(dataType, hashAlgorithm, dataHash); checkConstruction(bd, dataType, hashAlgorithm, dataHash, null); DERIA5String dataUri = new DERIA5String("http://test"); bd = new BiometricData(dataType, hashAlgorithm, dataHash, dataUri); checkConstruction(bd, dataType, hashAlgorithm, dataHash, dataUri); bd = BiometricData.getInstance(null); if (bd != null) { fail("null getInstance() failed."); } try { BiometricData.getInstance(new Object()); fail("getInstance() failed to detect bad object."); } catch (IllegalArgumentException e) { // expected } } private void checkConstruction( BiometricData bd, TypeOfBiometricData dataType, AlgorithmIdentifier hashAlgorithm, ASN1OctetString dataHash, DERIA5String dataUri) throws Exception { checkValues(bd, dataType, hashAlgorithm, dataHash, dataUri); bd = BiometricData.getInstance(bd); checkValues(bd, dataType, hashAlgorithm, dataHash, dataUri); ASN1InputStream aIn = new ASN1InputStream(bd.toASN1Object().getEncoded()); ASN1Sequence seq = (ASN1Sequence)aIn.readObject(); bd = BiometricData.getInstance(seq); checkValues(bd, dataType, hashAlgorithm, dataHash, dataUri); } private void checkValues( BiometricData bd, TypeOfBiometricData dataType, AlgorithmIdentifier algID, ASN1OctetString dataHash, DERIA5String sourceDataURI) { if (!bd.getTypeOfBiometricData().equals(dataType)) { fail("types don't match."); } if (!bd.getHashAlgorithm().equals(algID)) { fail("hash algorithms don't match."); } if (!bd.getBiometricDataHash().equals(dataHash)) { fail("hash algorithms don't match."); } if (sourceDataURI != null) { if (!bd.getSourceDataUri().equals(sourceDataURI)) { fail("data uris don't match."); } } else if (bd.getSourceDataUri() != null) { fail("data uri found when none expected."); } } public static void main( String[] args) { runTest(new BiometricDataUnitTest()); } } bouncycastle-1.49.orig/test/src/org/bouncycastle/asn1/test/NetscapeCertTypeTest.java0000644000175000017500000000221310453643505030232 0ustar ebourgebourgpackage org.bouncycastle.asn1.test; import java.io.IOException; import org.bouncycastle.asn1.misc.NetscapeCertType; import org.bouncycastle.util.test.SimpleTest; public class NetscapeCertTypeTest extends SimpleTest { public String getName() { return "NetscapeCertType"; } public void performTest() throws IOException { BitStringConstantTester.testFlagValueCorrect(0, NetscapeCertType.sslClient); BitStringConstantTester.testFlagValueCorrect(1, NetscapeCertType.sslServer); BitStringConstantTester.testFlagValueCorrect(2, NetscapeCertType.smime); BitStringConstantTester.testFlagValueCorrect(3, NetscapeCertType.objectSigning); BitStringConstantTester.testFlagValueCorrect(4, NetscapeCertType.reserved); BitStringConstantTester.testFlagValueCorrect(5, NetscapeCertType.sslCA); BitStringConstantTester.testFlagValueCorrect(6, NetscapeCertType.smimeCA); BitStringConstantTester.testFlagValueCorrect(7, NetscapeCertType.objectSigningCA); } public static void main( String[] args) { runTest(new NetscapeCertTypeTest()); } } bouncycastle-1.49.orig/test/src/org/bouncycastle/asn1/test/CertHashUnitTest.java0000644000175000017500000000406710571225326027360 0ustar ebourgebourgpackage org.bouncycastle.asn1.test; import org.bouncycastle.asn1.ASN1InputStream; import org.bouncycastle.asn1.ASN1Sequence; import org.bouncycastle.asn1.DERObjectIdentifier; import org.bouncycastle.asn1.isismtt.ocsp.CertHash; import org.bouncycastle.asn1.x509.AlgorithmIdentifier; import java.io.IOException; public class CertHashUnitTest extends ASN1UnitTest { public String getName() { return "CertHash"; } public void performTest() throws Exception { AlgorithmIdentifier algId = new AlgorithmIdentifier(new DERObjectIdentifier("1.2.2.3")); byte[] digest = new byte[20]; CertHash certID = new CertHash(algId, digest); checkConstruction(certID, algId, digest); certID = CertHash.getInstance(null); if (certID != null) { fail("null getInstance() failed."); } try { CertHash.getInstance(new Object()); fail("getInstance() failed to detect bad object."); } catch (IllegalArgumentException e) { // expected } } private void checkConstruction( CertHash certHash, AlgorithmIdentifier algId, byte[] digest) throws IOException { checkValues(certHash, algId, digest); certHash = CertHash.getInstance(certHash); checkValues(certHash, algId, digest); ASN1InputStream aIn = new ASN1InputStream(certHash.toASN1Object().getEncoded()); ASN1Sequence seq = (ASN1Sequence)aIn.readObject(); certHash = CertHash.getInstance(seq); checkValues(certHash, algId, digest); } private void checkValues( CertHash certHash, AlgorithmIdentifier algId, byte[] digest) { checkMandatoryField("algorithmHash", algId, certHash.getHashAlgorithm()); checkMandatoryField("certificateHash", digest, certHash.getCertificateHash()); } public static void main( String[] args) { runTest(new CertHashUnitTest()); } } bouncycastle-1.49.orig/test/src/org/bouncycastle/asn1/test/DataGroupHashUnitTest.java0000644000175000017500000000520411531054040030331 0ustar ebourgebourgpackage org.bouncycastle.asn1.test; import java.io.IOException; import java.util.Random; import org.bouncycastle.asn1.ASN1InputStream; import org.bouncycastle.asn1.ASN1OctetString; import org.bouncycastle.asn1.ASN1Sequence; import org.bouncycastle.asn1.DEROctetString; import org.bouncycastle.asn1.icao.DataGroupHash; import org.bouncycastle.util.test.SimpleTest; public class DataGroupHashUnitTest extends SimpleTest { public String getName() { return "DataGroupHash"; } private byte[] generateHash() { Random rand = new Random(); byte[] bytes = new byte[20]; for (int i = 0; i != bytes.length; i++) { bytes[i] = (byte)rand.nextInt(); } return bytes; } public void performTest() throws Exception { int dataGroupNumber = 1; ASN1OctetString dataHash = new DEROctetString(generateHash()); DataGroupHash dg = new DataGroupHash(dataGroupNumber, dataHash); checkConstruction(dg, dataGroupNumber, dataHash); try { DataGroupHash.getInstance(null); } catch (Exception e) { fail("getInstance() failed to handle null."); } try { DataGroupHash.getInstance(new Object()); fail("getInstance() failed to detect bad object."); } catch (IllegalArgumentException e) { // expected } } private void checkConstruction( DataGroupHash dg, int dataGroupNumber, ASN1OctetString dataGroupHashValue) throws IOException { checkValues(dg, dataGroupNumber, dataGroupHashValue); dg = DataGroupHash.getInstance(dg); checkValues(dg, dataGroupNumber, dataGroupHashValue); ASN1InputStream aIn = new ASN1InputStream(dg.toASN1Object().getEncoded()); ASN1Sequence seq = (ASN1Sequence)aIn.readObject(); dg = DataGroupHash.getInstance(seq); checkValues(dg, dataGroupNumber, dataGroupHashValue); } private void checkValues( DataGroupHash dg, int dataGroupNumber, ASN1OctetString dataGroupHashValue) { if (dg.getDataGroupNumber() != dataGroupNumber) { fail("group number don't match."); } if (!dg.getDataGroupHashValue().equals(dataGroupHashValue)) { fail("hash value don't match."); } } public static void main( String[] args) { runTest(new DataGroupHashUnitTest()); } } bouncycastle-1.49.orig/test/src/org/bouncycastle/asn1/test/CommitmentTypeIndicationUnitTest.java0000644000175000017500000000575310361171076032641 0ustar ebourgebourgpackage org.bouncycastle.asn1.test; import java.io.IOException; import org.bouncycastle.asn1.ASN1Encodable; import org.bouncycastle.asn1.ASN1InputStream; import org.bouncycastle.asn1.ASN1Sequence; import org.bouncycastle.asn1.DERObjectIdentifier; import org.bouncycastle.asn1.DERSequence; import org.bouncycastle.asn1.esf.CommitmentTypeIdentifier; import org.bouncycastle.asn1.esf.CommitmentTypeIndication; import org.bouncycastle.util.test.SimpleTest; public class CommitmentTypeIndicationUnitTest extends SimpleTest { public String getName() { return "CommitmentTypeIndication"; } public void performTest() throws Exception { CommitmentTypeIndication cti = new CommitmentTypeIndication(CommitmentTypeIdentifier.proofOfOrigin); checkConstruction(cti, CommitmentTypeIdentifier.proofOfOrigin, null); ASN1Sequence qualifier = new DERSequence(new DERObjectIdentifier("1.2")); cti = new CommitmentTypeIndication(CommitmentTypeIdentifier.proofOfOrigin, qualifier); checkConstruction(cti, CommitmentTypeIdentifier.proofOfOrigin, qualifier); cti = CommitmentTypeIndication.getInstance(null); if (cti != null) { fail("null getInstance() failed."); } try { CommitmentTypeIndication.getInstance(new Object()); fail("getInstance() failed to detect bad object."); } catch (IllegalArgumentException e) { // expected } } private void checkConstruction( CommitmentTypeIndication mv, DERObjectIdentifier commitmenttTypeId, ASN1Encodable qualifier) throws IOException { checkStatement(mv, commitmenttTypeId, qualifier); mv = CommitmentTypeIndication.getInstance(mv); checkStatement(mv, commitmenttTypeId, qualifier); ASN1InputStream aIn = new ASN1InputStream(mv.toASN1Object().getEncoded()); ASN1Sequence seq = (ASN1Sequence)aIn.readObject(); mv = CommitmentTypeIndication.getInstance(seq); checkStatement(mv, commitmenttTypeId, qualifier); } private void checkStatement( CommitmentTypeIndication cti, DERObjectIdentifier commitmentTypeId, ASN1Encodable qualifier) { if (!cti.getCommitmentTypeId().equals(commitmentTypeId)) { fail("commitmentTypeIds don't match."); } if (qualifier != null) { if (!cti.getCommitmentTypeQualifier().equals(qualifier)) { fail("qualifiers don't match."); } } else if (cti.getCommitmentTypeQualifier() != null) { fail("qualifier found when none expected."); } } public static void main( String[] args) { runTest(new CommitmentTypeIndicationUnitTest()); } } bouncycastle-1.49.orig/test/src/org/bouncycastle/asn1/test/AdmissionSyntaxUnitTest.java0000644000175000017500000000551511724561172031016 0ustar ebourgebourgpackage org.bouncycastle.asn1.test; import java.io.IOException; import org.bouncycastle.asn1.ASN1InputStream; import org.bouncycastle.asn1.ASN1ObjectIdentifier; import org.bouncycastle.asn1.ASN1Sequence; import org.bouncycastle.asn1.DERSequence; import org.bouncycastle.asn1.isismtt.x509.AdmissionSyntax; import org.bouncycastle.asn1.isismtt.x509.Admissions; import org.bouncycastle.asn1.isismtt.x509.NamingAuthority; import org.bouncycastle.asn1.isismtt.x509.ProfessionInfo; import org.bouncycastle.asn1.x500.DirectoryString; import org.bouncycastle.asn1.x509.GeneralName; import org.bouncycastle.asn1.x509.X509Name; public class AdmissionSyntaxUnitTest extends ASN1UnitTest { public String getName() { return "AdmissionSyntax"; } public void performTest() throws Exception { GeneralName name = new GeneralName(new X509Name("CN=hello world")); ASN1Sequence admissions = new DERSequence( new Admissions(name, new NamingAuthority(new ASN1ObjectIdentifier("1.2.3"), "url", new DirectoryString("fred")), new ProfessionInfo[0])); AdmissionSyntax syntax = new AdmissionSyntax(name, admissions); checkConstruction(syntax, name, admissions); syntax = AdmissionSyntax.getInstance(null); if (syntax != null) { fail("null getInstance() failed."); } try { AdmissionSyntax.getInstance(new Object()); fail("getInstance() failed to detect bad object."); } catch (IllegalArgumentException e) { // expected } } private void checkConstruction( AdmissionSyntax syntax, GeneralName authority, ASN1Sequence admissions) throws IOException { checkValues(syntax, authority, admissions); syntax = AdmissionSyntax.getInstance(syntax); checkValues(syntax, authority, admissions); ASN1InputStream aIn = new ASN1InputStream(syntax.toASN1Object().getEncoded()); ASN1Sequence info = (ASN1Sequence)aIn.readObject(); syntax = AdmissionSyntax.getInstance(info); checkValues(syntax, authority, admissions); } private void checkValues( AdmissionSyntax syntax, GeneralName authority, ASN1Sequence admissions) { checkMandatoryField("admissionAuthority", authority, syntax.getAdmissionAuthority()); Admissions[] adm = syntax.getContentsOfAdmissions(); if (adm.length != 1 || !adm[0].equals(admissions.getObjectAt(0))) { fail("admissions check failed"); } } public static void main( String[] args) { runTest(new AdmissionSyntaxUnitTest()); } } bouncycastle-1.49.orig/test/src/org/bouncycastle/asn1/test/GenerationTest.java0000644000175000017500000003777112147754267027136 0ustar ebourgebourgpackage org.bouncycastle.asn1.test; import java.io.ByteArrayInputStream; import java.io.ByteArrayOutputStream; import java.io.IOException; import java.math.BigInteger; import java.text.ParseException; import java.util.Date; import java.util.Hashtable; import java.util.Vector; import org.bouncycastle.asn1.ASN1EncodableVector; import org.bouncycastle.asn1.ASN1GeneralizedTime; import org.bouncycastle.asn1.ASN1InputStream; import org.bouncycastle.asn1.ASN1Integer; import org.bouncycastle.asn1.ASN1OutputStream; import org.bouncycastle.asn1.ASN1Primitive; import org.bouncycastle.asn1.DERNull; import org.bouncycastle.asn1.DEROctetString; import org.bouncycastle.asn1.DERSequence; import org.bouncycastle.asn1.oiw.ElGamalParameter; import org.bouncycastle.asn1.oiw.OIWObjectIdentifiers; import org.bouncycastle.asn1.pkcs.PKCSObjectIdentifiers; import org.bouncycastle.asn1.x500.X500Name; import org.bouncycastle.asn1.x509.AlgorithmIdentifier; import org.bouncycastle.asn1.x509.AuthorityKeyIdentifier; import org.bouncycastle.asn1.x509.CRLReason; import org.bouncycastle.asn1.x509.Extension; import org.bouncycastle.asn1.x509.Extensions; import org.bouncycastle.asn1.x509.ExtensionsGenerator; import org.bouncycastle.asn1.x509.GeneralName; import org.bouncycastle.asn1.x509.GeneralNames; import org.bouncycastle.asn1.x509.IssuingDistributionPoint; import org.bouncycastle.asn1.x509.KeyUsage; import org.bouncycastle.asn1.x509.RSAPublicKeyStructure; import org.bouncycastle.asn1.x509.SubjectKeyIdentifier; import org.bouncycastle.asn1.x509.SubjectPublicKeyInfo; import org.bouncycastle.asn1.x509.TBSCertList; import org.bouncycastle.asn1.x509.TBSCertificate; import org.bouncycastle.asn1.x509.Time; import org.bouncycastle.asn1.x509.V1TBSCertificateGenerator; import org.bouncycastle.asn1.x509.V2TBSCertListGenerator; import org.bouncycastle.asn1.x509.V3TBSCertificateGenerator; import org.bouncycastle.asn1.x509.X509Extension; import org.bouncycastle.asn1.x509.X509Extensions; import org.bouncycastle.asn1.x509.X509Name; import org.bouncycastle.util.Arrays; import org.bouncycastle.util.encoders.Base64; import org.bouncycastle.util.test.SimpleTest; public class GenerationTest extends SimpleTest { private byte[] v1Cert = Base64.decode( "MIGtAgEBMA0GCSqGSIb3DQEBBAUAMCUxCzAJBgNVBAMMAkFVMRYwFAYDVQQKDA1Cb" + "3VuY3kgQ2FzdGxlMB4XDTcwMDEwMTAwMDAwMVoXDTcwMDEwMTAwMDAxMlowNjELMA" + "kGA1UEAwwCQVUxFjAUBgNVBAoMDUJvdW5jeSBDYXN0bGUxDzANBgNVBAsMBlRlc3Q" + "gMTAaMA0GCSqGSIb3DQEBAQUAAwkAMAYCAQECAQI="); private byte[] v3Cert = Base64.decode( "MIIBSKADAgECAgECMA0GCSqGSIb3DQEBBAUAMCUxCzAJBgNVBAMMAkFVMRYwFAYD" + "VQQKDA1Cb3VuY3kgQ2FzdGxlMB4XDTcwMDEwMTAwMDAwMVoXDTcwMDEwMTAwMDAw" + "MlowNjELMAkGA1UEAwwCQVUxFjAUBgNVBAoMDUJvdW5jeSBDYXN0bGUxDzANBgNV" + "BAsMBlRlc3QgMjAYMBAGBisOBwIBATAGAgEBAgECAwQAAgEDo4GVMIGSMGEGA1Ud" + "IwEB/wRXMFWAFDZPdpHPzKi7o8EJokkQU2uqCHRRoTqkODA2MQswCQYDVQQDDAJB" + "VTEWMBQGA1UECgwNQm91bmN5IENhc3RsZTEPMA0GA1UECwwGVGVzdCAyggECMCAG" + "A1UdDgEB/wQWBBQ2T3aRz8you6PBCaJJEFNrqgh0UTALBgNVHQ8EBAMCBBA="); private byte[] v3CertNullSubject = Base64.decode( "MIHGoAMCAQICAQIwDQYJKoZIhvcNAQEEBQAwJTELMAkGA1UEAwwCQVUxFjAUBgNVB" + "AoMDUJvdW5jeSBDYXN0bGUwHhcNNzAwMTAxMDAwMDAxWhcNNzAwMTAxMDAwMDAyWj" + "AAMBgwEAYGKw4HAgEBMAYCAQECAQIDBAACAQOjSjBIMEYGA1UdEQEB/wQ8MDqkODA" + "2MQswCQYDVQQDDAJBVTEWMBQGA1UECgwNQm91bmN5IENhc3RsZTEPMA0GA1UECwwG" + "VGVzdCAy"); private byte[] v2CertList = Base64.decode( "MIIBQwIBATANBgkqhkiG9w0BAQUFADAlMQswCQYDVQQDDAJBVTEWMBQGA1UECgwN" + "Qm91bmN5IENhc3RsZRcNNzAwMTAxMDAwMDAwWhcNNzAwMTAxMDAwMDAyWjAiMCAC" + "AQEXDTcwMDEwMTAwMDAwMVowDDAKBgNVHRUEAwoBCqCBxTCBwjBhBgNVHSMBAf8E" + "VzBVgBQ2T3aRz8you6PBCaJJEFNrqgh0UaE6pDgwNjELMAkGA1UEAwwCQVUxFjAU" + "BgNVBAoMDUJvdW5jeSBDYXN0bGUxDzANBgNVBAsMBlRlc3QgMoIBAjBDBgNVHRIE" + "PDA6pDgwNjELMAkGA1UEAwwCQVUxFjAUBgNVBAoMDUJvdW5jeSBDYXN0bGUxDzAN" + "BgNVBAsMBlRlc3QgMzAKBgNVHRQEAwIBATAMBgNVHRwBAf8EAjAA"); private void tbsV1CertGen() throws IOException { V1TBSCertificateGenerator gen = new V1TBSCertificateGenerator(); Date startDate = new Date(1000); Date endDate = new Date(12000); gen.setSerialNumber(new ASN1Integer(1)); gen.setStartDate(new Time(startDate)); gen.setEndDate(new Time(endDate)); gen.setIssuer(new X500Name("CN=AU,O=Bouncy Castle")); gen.setSubject(new X500Name("CN=AU,O=Bouncy Castle,OU=Test 1")); gen.setSignature(new AlgorithmIdentifier(PKCSObjectIdentifiers.md5WithRSAEncryption, DERNull.INSTANCE)); SubjectPublicKeyInfo info = new SubjectPublicKeyInfo(new AlgorithmIdentifier(PKCSObjectIdentifiers.rsaEncryption, DERNull.INSTANCE), new RSAPublicKeyStructure(BigInteger.valueOf(1), BigInteger.valueOf(2))); gen.setSubjectPublicKeyInfo(info); TBSCertificate tbs = gen.generateTBSCertificate(); ByteArrayOutputStream bOut = new ByteArrayOutputStream(); ASN1OutputStream aOut = new ASN1OutputStream(bOut); aOut.writeObject(tbs); if (!Arrays.areEqual(bOut.toByteArray(), v1Cert)) { fail("failed v1 cert generation"); } // // read back test // ASN1InputStream aIn = new ASN1InputStream(new ByteArrayInputStream(v1Cert)); ASN1Primitive o = aIn.readObject(); bOut = new ByteArrayOutputStream(); aOut = new ASN1OutputStream(bOut); aOut.writeObject(o); if (!Arrays.areEqual(bOut.toByteArray(), v1Cert)) { fail("failed v1 cert read back test"); } } private AuthorityKeyIdentifier createAuthorityKeyId( SubjectPublicKeyInfo info, X500Name name, int sNumber) { GeneralName genName = new GeneralName(name); ASN1EncodableVector v = new ASN1EncodableVector(); v.add(genName); return new AuthorityKeyIdentifier( info, GeneralNames.getInstance(new DERSequence(v)), BigInteger.valueOf(sNumber)); } private void tbsV3CertGen() throws IOException { V3TBSCertificateGenerator gen = new V3TBSCertificateGenerator(); Date startDate = new Date(1000); Date endDate = new Date(2000); gen.setSerialNumber(new ASN1Integer(2)); gen.setStartDate(new Time(startDate)); gen.setEndDate(new Time(endDate)); gen.setIssuer(new X500Name("CN=AU,O=Bouncy Castle")); gen.setSubject(new X500Name("CN=AU,O=Bouncy Castle,OU=Test 2")); gen.setSignature(new AlgorithmIdentifier(PKCSObjectIdentifiers.md5WithRSAEncryption, DERNull.INSTANCE)); SubjectPublicKeyInfo info = new SubjectPublicKeyInfo(new AlgorithmIdentifier(OIWObjectIdentifiers.elGamalAlgorithm, new ElGamalParameter(BigInteger.valueOf(1), BigInteger.valueOf(2))), new ASN1Integer(3)); gen.setSubjectPublicKeyInfo(info); // // add extensions // Vector order = new Vector(); Hashtable extensions = new Hashtable(); order.addElement(X509Extension.authorityKeyIdentifier); order.addElement(X509Extension.subjectKeyIdentifier); order.addElement(X509Extension.keyUsage); extensions.put(X509Extension.authorityKeyIdentifier, new X509Extension(true, new DEROctetString(createAuthorityKeyId(info, new X500Name("CN=AU,O=Bouncy Castle,OU=Test 2"), 2)))); extensions.put(X509Extension.subjectKeyIdentifier, new X509Extension(true, new DEROctetString(new SubjectKeyIdentifier(info)))); extensions.put(X509Extension.keyUsage, new X509Extension(false, new DEROctetString(new KeyUsage(KeyUsage.dataEncipherment)))); X509Extensions ex = new X509Extensions(order, extensions); gen.setExtensions(ex); TBSCertificate tbs = gen.generateTBSCertificate(); ByteArrayOutputStream bOut = new ByteArrayOutputStream(); ASN1OutputStream aOut = new ASN1OutputStream(bOut); aOut.writeObject(tbs); if (!Arrays.areEqual(bOut.toByteArray(), v3Cert)) { fail("failed v3 cert generation"); } // // read back test // ASN1InputStream aIn = new ASN1InputStream(new ByteArrayInputStream(v3Cert)); ASN1Primitive o = aIn.readObject(); bOut = new ByteArrayOutputStream(); aOut = new ASN1OutputStream(bOut); aOut.writeObject(o); if (!Arrays.areEqual(bOut.toByteArray(), v3Cert)) { fail("failed v3 cert read back test"); } } private void tbsV3CertGenWithNullSubject() throws IOException { V3TBSCertificateGenerator gen = new V3TBSCertificateGenerator(); Date startDate = new Date(1000); Date endDate = new Date(2000); gen.setSerialNumber(new ASN1Integer(2)); gen.setStartDate(new Time(startDate)); gen.setEndDate(new Time(endDate)); gen.setIssuer(new X500Name("CN=AU,O=Bouncy Castle")); gen.setSignature(new AlgorithmIdentifier(PKCSObjectIdentifiers.md5WithRSAEncryption, DERNull.INSTANCE)); SubjectPublicKeyInfo info = new SubjectPublicKeyInfo(new AlgorithmIdentifier(OIWObjectIdentifiers.elGamalAlgorithm, new ElGamalParameter(BigInteger.valueOf(1), BigInteger.valueOf(2))), new ASN1Integer(3)); gen.setSubjectPublicKeyInfo(info); try { gen.generateTBSCertificate(); fail("null subject not caught!"); } catch (IllegalStateException e) { if (!e.getMessage().equals("not all mandatory fields set in V3 TBScertificate generator")) { fail("unexpected exception", e); } } // // add extensions // Vector order = new Vector(); Hashtable extensions = new Hashtable(); order.addElement(X509Extension.subjectAlternativeName); extensions.put(X509Extension.subjectAlternativeName, new X509Extension(true, new DEROctetString(new GeneralNames(new GeneralName(new X509Name("CN=AU,O=Bouncy Castle,OU=Test 2")))))); X509Extensions ex = new X509Extensions(order, extensions); gen.setExtensions(ex); TBSCertificate tbs = gen.generateTBSCertificate(); ByteArrayOutputStream bOut = new ByteArrayOutputStream(); ASN1OutputStream aOut = new ASN1OutputStream(bOut); aOut.writeObject(tbs); if (!Arrays.areEqual(bOut.toByteArray(), v3CertNullSubject)) { fail("failed v3 null sub cert generation"); } // // read back test // ASN1InputStream aIn = new ASN1InputStream(new ByteArrayInputStream(v3CertNullSubject)); ASN1Primitive o = aIn.readObject(); bOut = new ByteArrayOutputStream(); aOut = new ASN1OutputStream(bOut); aOut.writeObject(o); if (!Arrays.areEqual(bOut.toByteArray(), v3CertNullSubject)) { fail("failed v3 null sub cert read back test"); } } private void tbsV2CertListGen() throws IOException { V2TBSCertListGenerator gen = new V2TBSCertListGenerator(); gen.setIssuer(new X500Name("CN=AU,O=Bouncy Castle")); gen.addCRLEntry(new ASN1Integer(1), new Time(new Date(1000)), CRLReason.aACompromise); gen.setNextUpdate(new Time(new Date(2000))); gen.setThisUpdate(new Time(new Date(500))); gen.setSignature(new AlgorithmIdentifier(PKCSObjectIdentifiers.sha1WithRSAEncryption, DERNull.INSTANCE)); // // extensions // SubjectPublicKeyInfo info = new SubjectPublicKeyInfo(new AlgorithmIdentifier(OIWObjectIdentifiers.elGamalAlgorithm, new ElGamalParameter(BigInteger.valueOf(1), BigInteger.valueOf(2))), new ASN1Integer(3)); ExtensionsGenerator extGen = new ExtensionsGenerator(); extGen.addExtension(Extension.authorityKeyIdentifier, true, createAuthorityKeyId(info, new X500Name("CN=AU,O=Bouncy Castle,OU=Test 2"), 2)); extGen.addExtension(Extension.issuerAlternativeName, false, new GeneralNames(new GeneralName(new X500Name("CN=AU,O=Bouncy Castle,OU=Test 3")))); extGen.addExtension(Extension.cRLNumber, false, new ASN1Integer(1)); extGen.addExtension(Extension.issuingDistributionPoint, true, IssuingDistributionPoint.getInstance(new DERSequence())); Extensions ex = extGen.generate(); gen.setExtensions(ex); TBSCertList tbs = gen.generateTBSCertList(); ByteArrayOutputStream bOut = new ByteArrayOutputStream(); ASN1OutputStream aOut = new ASN1OutputStream(bOut); aOut.writeObject(tbs); if (!Arrays.areEqual(bOut.toByteArray(), v2CertList)) { System.out.println(new String(Base64.encode(bOut.toByteArray()))); fail("failed v2 cert list generation"); } // // read back test // ASN1InputStream aIn = new ASN1InputStream(new ByteArrayInputStream(v2CertList)); ASN1Primitive o = aIn.readObject(); bOut = new ByteArrayOutputStream(); aOut = new ASN1OutputStream(bOut); aOut.writeObject(o); if (!Arrays.areEqual(bOut.toByteArray(), v2CertList)) { fail("failed v2 cert list read back test"); } // // check we can add a custom reason // gen.addCRLEntry(new ASN1Integer(1), new Time(new Date(1000)), CRLReason.aACompromise); // // check invalidity date gen.addCRLEntry(new ASN1Integer(2), new Time(new Date(1000)), CRLReason.affiliationChanged, new ASN1GeneralizedTime(new Date(2000))); TBSCertList crl = gen.generateTBSCertList(); TBSCertList.CRLEntry[] entries = crl.getRevokedCertificates(); for (int i = 0; i != entries.length; i++) { TBSCertList.CRLEntry entry = entries[i]; if (entry.getUserCertificate().equals(new ASN1Integer(1))) { Extensions extensions = entry.getExtensions(); Extension ext = extensions.getExtension(Extension.reasonCode); CRLReason r = CRLReason.getInstance(ext.getParsedValue()); if (r.getValue().intValue() != CRLReason.aACompromise) { fail("reason code mismatch"); } } else if (entry.getUserCertificate().equals(new ASN1Integer(2))) { Extensions extensions = entry.getExtensions(); Extension ext = extensions.getExtension(Extension.reasonCode); CRLReason r = CRLReason.getInstance(ext.getParsedValue()); if (r.getValue().intValue() != CRLReason.affiliationChanged) { fail("reason code mismatch"); } ext = extensions.getExtension(Extension.invalidityDate); ASN1GeneralizedTime t = ASN1GeneralizedTime.getInstance(ext.getParsedValue()); try { if (!t.getDate().equals(new Date(2000))) { fail("invalidity date mismatch"); } } catch (ParseException e) { fail("can't parse date", e); } } } } public void performTest() throws Exception { tbsV1CertGen(); tbsV3CertGen(); tbsV3CertGenWithNullSubject(); tbsV2CertListGen(); } public String getName() { return "Generation"; } public static void main( String[] args) { runTest(new GenerationTest()); } } bouncycastle-1.49.orig/test/src/org/bouncycastle/asn1/test/SignerLocationUnitTest.java0000644000175000017500000001277411725566517030617 0ustar ebourgebourgpackage org.bouncycastle.asn1.test; import java.io.IOException; import org.bouncycastle.asn1.ASN1EncodableVector; import org.bouncycastle.asn1.ASN1InputStream; import org.bouncycastle.asn1.ASN1Sequence; import org.bouncycastle.asn1.DERSequence; import org.bouncycastle.asn1.DERTaggedObject; import org.bouncycastle.asn1.DERUTF8String; import org.bouncycastle.asn1.esf.SignerLocation; import org.bouncycastle.util.test.SimpleTest; public class SignerLocationUnitTest extends SimpleTest { public String getName() { return "SignerLocation"; } public void performTest() throws Exception { DERUTF8String countryName = new DERUTF8String("Australia"); SignerLocation sl = new SignerLocation(countryName, null, null); checkConstruction(sl, countryName, null, null); DERUTF8String localityName = new DERUTF8String("Melbourne"); sl = new SignerLocation(null, localityName, null); checkConstruction(sl, null, localityName, null); sl = new SignerLocation(countryName, localityName, null); checkConstruction(sl, countryName, localityName, null); ASN1EncodableVector v = new ASN1EncodableVector(); v.add(new DERUTF8String("line 1")); v.add(new DERUTF8String("line 2")); ASN1Sequence postalAddress = new DERSequence(v); sl = new SignerLocation(null, null, postalAddress); checkConstruction(sl, null, null, postalAddress); sl = new SignerLocation(countryName, null, postalAddress); checkConstruction(sl, countryName, null, postalAddress); sl = new SignerLocation(countryName, localityName, postalAddress); checkConstruction(sl, countryName, localityName, postalAddress); sl = SignerLocation.getInstance(null); if (sl != null) { fail("null getInstance() failed."); } try { SignerLocation.getInstance(new Object()); fail("getInstance() failed to detect bad object."); } catch (IllegalArgumentException e) { // expected } // // out of range postal address // v = new ASN1EncodableVector(); v.add(new DERUTF8String("line 1")); v.add(new DERUTF8String("line 2")); v.add(new DERUTF8String("line 3")); v.add(new DERUTF8String("line 4")); v.add(new DERUTF8String("line 5")); v.add(new DERUTF8String("line 6")); v.add(new DERUTF8String("line 7")); postalAddress = new DERSequence(v); try { new SignerLocation(null, null, postalAddress); fail("constructor failed to detect bad postalAddress."); } catch (IllegalArgumentException e) { // expected } try { SignerLocation.getInstance(new DERSequence(new DERTaggedObject(2, postalAddress))); fail("sequence constructor failed to detect bad postalAddress."); } catch (IllegalArgumentException e) { // expected } try { SignerLocation.getInstance(new DERSequence(new DERTaggedObject(5, postalAddress))); fail("sequence constructor failed to detect bad tag."); } catch (IllegalArgumentException e) { // expected } } private void checkConstruction( SignerLocation sl, DERUTF8String countryName, DERUTF8String localityName, ASN1Sequence postalAddress) throws IOException { checkValues(sl, countryName, localityName, postalAddress); sl = SignerLocation.getInstance(sl); checkValues(sl, countryName, localityName, postalAddress); ASN1InputStream aIn = new ASN1InputStream(sl.toASN1Object().getEncoded()); ASN1Sequence seq = (ASN1Sequence)aIn.readObject(); sl = SignerLocation.getInstance(seq); checkValues(sl, countryName, localityName, postalAddress); } private void checkValues( SignerLocation sl, DERUTF8String countryName, DERUTF8String localityName, ASN1Sequence postalAddress) { if (countryName != null) { if (!countryName.equals(sl.getCountryName())) { fail("countryNames don't match."); } } else if (sl.getCountryName() != null) { fail("countryName found when none expected."); } if (localityName != null) { if (!localityName.equals(sl.getLocalityName())) { fail("localityNames don't match."); } } else if (sl.getLocalityName() != null) { fail("localityName found when none expected."); } if (postalAddress != null) { if (!postalAddress.equals(sl.getPostalAddress())) { fail("postalAddresses don't match."); } } else if (sl.getPostalAddress() != null) { fail("postalAddress found when none expected."); } } public static void main( String[] args) { runTest(new SignerLocationUnitTest()); } } bouncycastle-1.49.orig/test/src/org/bouncycastle/asn1/test/Iso4217CurrencyCodeUnitTest.java0000644000175000017500000000664211625106236031235 0ustar ebourgebourgpackage org.bouncycastle.asn1.test; import org.bouncycastle.asn1.ASN1Primitive; import org.bouncycastle.asn1.x509.qualified.Iso4217CurrencyCode; import org.bouncycastle.util.test.SimpleTest; public class Iso4217CurrencyCodeUnitTest extends SimpleTest { private static final String ALPHABETIC_CURRENCY_CODE = "AUD"; private static final int NUMERIC_CURRENCY_CODE = 1; public String getName() { return "Iso4217CurrencyCode"; } public void performTest() throws Exception { // // alphabetic // Iso4217CurrencyCode cc = new Iso4217CurrencyCode(ALPHABETIC_CURRENCY_CODE); checkNumeric(cc, ALPHABETIC_CURRENCY_CODE); cc = Iso4217CurrencyCode.getInstance(cc); checkNumeric(cc, ALPHABETIC_CURRENCY_CODE); ASN1Primitive obj = cc.toASN1Object(); cc = Iso4217CurrencyCode.getInstance(obj); checkNumeric(cc, ALPHABETIC_CURRENCY_CODE); // // numeric // cc = new Iso4217CurrencyCode(NUMERIC_CURRENCY_CODE); checkNumeric(cc, NUMERIC_CURRENCY_CODE); cc = Iso4217CurrencyCode.getInstance(cc); checkNumeric(cc, NUMERIC_CURRENCY_CODE); obj = cc.toASN1Object(); cc = Iso4217CurrencyCode.getInstance(obj); checkNumeric(cc, NUMERIC_CURRENCY_CODE); cc = Iso4217CurrencyCode.getInstance(null); if (cc != null) { fail("null getInstance() failed."); } try { Iso4217CurrencyCode.getInstance(new Object()); fail("getInstance() failed to detect bad object."); } catch (IllegalArgumentException e) { // expected } try { new Iso4217CurrencyCode("ABCD"); fail("constructor failed to detect out of range currencycode."); } catch (IllegalArgumentException e) { // expected } try { new Iso4217CurrencyCode(0); fail("constructor failed to detect out of range small numeric code."); } catch (IllegalArgumentException e) { // expected } try { new Iso4217CurrencyCode(1000); fail("constructor failed to detect out of range large numeric code."); } catch (IllegalArgumentException e) { // expected } } private void checkNumeric( Iso4217CurrencyCode cc, String code) { if (!cc.isAlphabetic()) { fail("non-alphabetic code found when one expected."); } if (!cc.getAlphabetic().equals(code)) { fail("string codes don't match."); } } private void checkNumeric( Iso4217CurrencyCode cc, int code) { if (cc.isAlphabetic()) { fail("alphabetic code found when one not expected."); } if (cc.getNumeric() != code) { fail("numeric codes don't match."); } } public static void main( String[] args) { runTest(new Iso4217CurrencyCodeUnitTest()); } } bouncycastle-1.49.orig/test/src/org/bouncycastle/asn1/test/ProcurationSyntaxUnitTest.java0000644000175000017500000000675311724561172031402 0ustar ebourgebourgpackage org.bouncycastle.asn1.test; import java.io.IOException; import org.bouncycastle.asn1.ASN1InputStream; import org.bouncycastle.asn1.ASN1Integer; import org.bouncycastle.asn1.ASN1Sequence; import org.bouncycastle.asn1.isismtt.x509.ProcurationSyntax; import org.bouncycastle.asn1.x500.DirectoryString; import org.bouncycastle.asn1.x509.GeneralName; import org.bouncycastle.asn1.x509.GeneralNames; import org.bouncycastle.asn1.x509.IssuerSerial; import org.bouncycastle.asn1.x509.X509Name; public class ProcurationSyntaxUnitTest extends ASN1UnitTest { public String getName() { return "ProcurationSyntax"; } public void performTest() throws Exception { String country = "AU"; DirectoryString typeOfSubstitution = new DirectoryString("substitution"); GeneralName thirdPerson = new GeneralName(new X509Name("CN=thirdPerson")); IssuerSerial certRef = new IssuerSerial(new GeneralNames(new GeneralName(new X509Name("CN=test"))), new ASN1Integer(1)); ProcurationSyntax procuration = new ProcurationSyntax(country, typeOfSubstitution, thirdPerson); checkConstruction(procuration, country, typeOfSubstitution, thirdPerson, null); procuration = new ProcurationSyntax(country, typeOfSubstitution, certRef); checkConstruction(procuration, country, typeOfSubstitution, null, certRef); procuration = new ProcurationSyntax(null, typeOfSubstitution, certRef); checkConstruction(procuration, null, typeOfSubstitution, null, certRef); procuration = new ProcurationSyntax(country, null, certRef); checkConstruction(procuration, country, null, null, certRef); procuration = ProcurationSyntax.getInstance(null); if (procuration != null) { fail("null getInstance() failed."); } try { ProcurationSyntax.getInstance(new Object()); fail("getInstance() failed to detect bad object."); } catch (IllegalArgumentException e) { // expected } } private void checkConstruction( ProcurationSyntax procuration, String country, DirectoryString typeOfSubstitution, GeneralName thirdPerson, IssuerSerial certRef) throws IOException { checkValues(procuration, country, typeOfSubstitution, thirdPerson, certRef); procuration = ProcurationSyntax.getInstance(procuration); checkValues(procuration, country, typeOfSubstitution, thirdPerson, certRef); ASN1InputStream aIn = new ASN1InputStream(procuration.toASN1Object().getEncoded()); ASN1Sequence seq = (ASN1Sequence)aIn.readObject(); procuration = ProcurationSyntax.getInstance(seq); checkValues(procuration, country, typeOfSubstitution, thirdPerson, certRef); } private void checkValues( ProcurationSyntax procuration, String country, DirectoryString typeOfSubstitution, GeneralName thirdPerson, IssuerSerial certRef) { checkOptionalField("country", country, procuration.getCountry()); checkOptionalField("typeOfSubstitution", typeOfSubstitution, procuration.getTypeOfSubstitution()); checkOptionalField("thirdPerson", thirdPerson, procuration.getThirdPerson()); checkOptionalField("certRef", certRef, procuration.getCertRef()); } public static void main( String[] args) { runTest(new ProcurationSyntaxUnitTest()); } } bouncycastle-1.49.orig/test/src/org/bouncycastle/asn1/test/X500NameTest.java0000644000175000017500000006062412151455040026247 0ustar ebourgebourgpackage org.bouncycastle.asn1.test; import java.io.ByteArrayInputStream; import java.io.ByteArrayOutputStream; import java.io.IOException; import org.bouncycastle.asn1.ASN1Encodable; import org.bouncycastle.asn1.ASN1EncodableVector; import org.bouncycastle.asn1.ASN1InputStream; import org.bouncycastle.asn1.ASN1ObjectIdentifier; import org.bouncycastle.asn1.ASN1OutputStream; import org.bouncycastle.asn1.ASN1Primitive; import org.bouncycastle.asn1.ASN1Sequence; import org.bouncycastle.asn1.ASN1Set; import org.bouncycastle.asn1.ASN1String; import org.bouncycastle.asn1.ASN1TaggedObject; import org.bouncycastle.asn1.DERGeneralizedTime; import org.bouncycastle.asn1.DERIA5String; import org.bouncycastle.asn1.DERPrintableString; import org.bouncycastle.asn1.DERSequence; import org.bouncycastle.asn1.DERSet; import org.bouncycastle.asn1.DERTaggedObject; import org.bouncycastle.asn1.DERUTF8String; import org.bouncycastle.asn1.x500.RDN; import org.bouncycastle.asn1.x500.X500Name; import org.bouncycastle.asn1.x500.X500NameBuilder; import org.bouncycastle.asn1.x500.style.BCStrictStyle; import org.bouncycastle.asn1.x500.style.BCStyle; import org.bouncycastle.asn1.x509.X509DefaultEntryConverter; import org.bouncycastle.util.encoders.Hex; import org.bouncycastle.util.test.SimpleTest; public class X500NameTest extends SimpleTest { String[] subjects = { "C=AU,ST=Victoria,L=South Melbourne,O=Connect 4 Pty Ltd,OU=Webserver Team,CN=www2.connect4.com.au,E=webmaster@connect4.com.au", "C=AU,ST=Victoria,L=South Melbourne,O=Connect 4 Pty Ltd,OU=Certificate Authority,CN=Connect 4 CA,E=webmaster@connect4.com.au", "C=AU,ST=QLD,CN=SSLeay/rsa test cert", "C=US,O=National Aeronautics and Space Administration,SERIALNUMBER=16+CN=Steve Schoch", "E=cooke@issl.atl.hp.com,C=US,OU=Hewlett Packard Company (ISSL),CN=Paul A. Cooke", "O=Sun Microsystems Inc,CN=store.sun.com", "unstructuredAddress=192.168.1.33,unstructuredName=pixfirewall.ciscopix.com,CN=pixfirewall.ciscopix.com", "CN=*.canal-plus.com,OU=Provided by TBS INTERNET http://www.tbs-certificats.com/,OU=\\ CANAL \\+,O=CANAL\\+DISTRIBUTION,L=issy les moulineaux,ST=Hauts de Seine,C=FR", "O=Bouncy Castle,CN=www.bouncycastle.org\\ ", "O=Bouncy Castle,CN=c:\\\\fred\\\\bob", }; String[] hexSubjects = { "CN=\\20Test\\20X,O=\\20Test,C=GB", // input "CN=\\ Test X,O=\\ Test,C=GB", // expected "CN=\\20Test\\20X\\20,O=\\20Test,C=GB", // input "CN=\\ Test X\\ ,O=\\ Test,C=GB" // expected }; public String getName() { return "X500Name"; } private static X500Name fromBytes( byte[] bytes) throws IOException { return X500Name.getInstance(new ASN1InputStream(new ByteArrayInputStream(bytes)).readObject()); } private ASN1Encodable createEntryValue(ASN1ObjectIdentifier oid, String value) { X500NameBuilder builder = new X500NameBuilder(BCStyle.INSTANCE); builder.addRDN(oid, value); X500Name name = builder.build(); ASN1Sequence seq = (ASN1Sequence)name.toASN1Primitive(); ASN1Set set = ASN1Set.getInstance(seq.getObjectAt(0).toASN1Primitive()); seq = (ASN1Sequence)set.getObjectAt(0); return seq.getObjectAt(1); } private ASN1Encodable createEntryValueFromString(ASN1ObjectIdentifier oid, String value) { X500NameBuilder builder = new X500NameBuilder(BCStyle.INSTANCE); builder.addRDN(oid, value); X500Name name = new X500Name(builder.build().toString()); ASN1Sequence seq = (ASN1Sequence)name.toASN1Primitive(); ASN1Set set = ASN1Set.getInstance(seq.getObjectAt(0).toASN1Primitive()); seq = (ASN1Sequence)set.getObjectAt(0); return seq.getObjectAt(1); } private void testEncodingPrintableString(ASN1ObjectIdentifier oid, String value) { ASN1Encodable converted = createEntryValue(oid, value); if (!(converted instanceof DERPrintableString)) { fail("encoding for " + oid + " not printable string"); } } private void testEncodingIA5String(ASN1ObjectIdentifier oid, String value) { ASN1Encodable converted = createEntryValue(oid, value); if (!(converted instanceof DERIA5String)) { fail("encoding for " + oid + " not IA5String"); } } private void testEncodingUTF8String(ASN1ObjectIdentifier oid, String value) throws IOException { ASN1Encodable converted = createEntryValue(oid, value); if (!(converted instanceof DERUTF8String)) { fail("encoding for " + oid + " not IA5String"); } if (!value.equals((DERUTF8String.getInstance(converted.toASN1Primitive().getEncoded()).getString()))) { fail("decoding not correct"); } } private void testEncodingGeneralizedTime(ASN1ObjectIdentifier oid, String value) { ASN1Encodable converted = createEntryValue(oid, value); if (!(converted instanceof DERGeneralizedTime)) { fail("encoding for " + oid + " not GeneralizedTime"); } converted = createEntryValueFromString(oid, value); if (!(converted instanceof DERGeneralizedTime)) { fail("encoding for " + oid + " not GeneralizedTime"); } } public void performTest() throws Exception { testEncodingPrintableString(BCStyle.C, "AU"); testEncodingPrintableString(BCStyle.SERIALNUMBER, "123456"); testEncodingPrintableString(BCStyle.DN_QUALIFIER, "123456"); testEncodingIA5String(BCStyle.EmailAddress, "test@test.com"); testEncodingIA5String(BCStyle.DC, "test"); // correct encoding testEncodingGeneralizedTime(BCStyle.DATE_OF_BIRTH, "#180F32303032303132323132323232305A"); // compatibility encoding testEncodingGeneralizedTime(BCStyle.DATE_OF_BIRTH, "20020122122220Z"); testEncodingUTF8String(BCStyle.CN, "Mörsky"); // // composite // X500NameBuilder builder = new X500NameBuilder(BCStyle.INSTANCE); builder.addRDN(BCStyle.C, "AU"); builder.addRDN(BCStyle.O, "The Legion of the Bouncy Castle"); builder.addRDN(BCStyle.L, "Melbourne"); builder.addRDN(BCStyle.ST, "Victoria"); builder.addRDN(BCStyle.E, "feedback-crypto@bouncycastle.org"); X500Name name1 = builder.build(); if (!name1.equals(name1)) { fail("Failed same object test"); } // if (!name1.equals(name1, true)) // { // fail("Failed same object test - in Order"); // } builder = new X500NameBuilder(BCStyle.INSTANCE); builder.addRDN(BCStyle.C, "AU"); builder.addRDN(BCStyle.O, "The Legion of the Bouncy Castle"); builder.addRDN(BCStyle.L, "Melbourne"); builder.addRDN(BCStyle.ST, "Victoria"); builder.addRDN(BCStyle.E, "feedback-crypto@bouncycastle.org"); X500Name name2 = builder.build(); if (!name1.equals(name2)) { fail("Failed same name test"); } // if (!name1.equals(name2, true)) // { // fail("Failed same name test - in Order"); // } if (name1.hashCode() != name2.hashCode()) { fail("Failed same name test - in Order"); } X500NameBuilder builder1 = new X500NameBuilder(BCStyle.INSTANCE); builder.addRDN(BCStyle.C, "AU"); builder.addRDN(BCStyle.O, "The Legion of the Bouncy Castle"); builder.addRDN(BCStyle.L, "Melbourne"); builder.addRDN(BCStyle.ST, "Victoria"); builder.addRDN(BCStyle.E, "feedback-crypto@bouncycastle.org"); X500NameBuilder builder2 = new X500NameBuilder(BCStyle.INSTANCE); builder.addRDN(BCStyle.E, "feedback-crypto@bouncycastle.org"); builder.addRDN(BCStyle.C, "AU"); builder.addRDN(BCStyle.O, "The Legion of the Bouncy Castle"); builder.addRDN(BCStyle.L, "Melbourne"); builder.addRDN(BCStyle.ST, "Victoria"); name1 = builder1.build(); name2 = builder2.build(); if (!name1.equals(name2)) { fail("Failed reverse name test"); } if (name1.hashCode() != name2.hashCode()) { fail("Failed reverse name test hashCode"); } // if (name1.equals(name2, true)) // { // fail("Failed reverse name test - in Order"); // } // // if (!name1.equals(name2, false)) // { // fail("Failed reverse name test - in Order false"); // } // Vector oids = name1.getOIDs(); // if (!compareVectors(oids, ord1)) // { // fail("oid comparison test"); // } /* Vector val1 = new Vector(); val1.addElement("AU"); val1.addElement("The Legion of the Bouncy Castle"); val1.addElement("Melbourne"); val1.addElement("Victoria"); val1.addElement("feedback-crypto@bouncycastle.org"); name1 = new X500Name(ord1, val1); Vector values = name1.getValues(); if (!compareVectors(values, val1)) { fail("value comparison test"); } ord2 = new Vector(); ord2.addElement(X500Name.ST); ord2.addElement(X500Name.ST); ord2.addElement(X500Name.L); ord2.addElement(X500Name.O); ord2.addElement(X500Name.C); name1 = new X500Name(ord1, attrs); name2 = new X500Name(ord2, attrs); if (name1.equals(name2)) { fail("Failed different name test"); } ord2 = new Vector(); ord2.addElement(X500Name.ST); ord2.addElement(X500Name.L); ord2.addElement(X500Name.O); ord2.addElement(X500Name.C); name1 = new X500Name(ord1, attrs); name2 = new X500Name(ord2, attrs); if (name1.equals(name2)) { fail("Failed subset name test"); } compositeTest(); */ ByteArrayOutputStream bOut; ASN1OutputStream aOut; ASN1InputStream aIn; /* // // getValues test // Vector v1 = name1.getValues(X500Name.O); if (v1.size() != 1 || !v1.elementAt(0).equals("The Legion of the Bouncy Castle")) { fail("O test failed"); } Vector v2 = name1.getValues(X500Name.L); if (v2.size() != 1 || !v2.elementAt(0).equals("Melbourne")) { fail("L test failed"); } */ // // general subjects test // for (int i = 0; i != subjects.length; i++) { X500Name name = new X500Name(subjects[i]); bOut = new ByteArrayOutputStream(); aOut = new ASN1OutputStream(bOut); aOut.writeObject(name); aIn = new ASN1InputStream(new ByteArrayInputStream(bOut.toByteArray())); name = X500Name.getInstance(aIn.readObject()); if (!name.toString().equals(subjects[i])) { fail("failed regeneration test " + i + " got: " + name.toString() + " expected " + subjects[i]); } } for (int i = 0; i < hexSubjects.length; i += 2) { X500Name name = new X500Name(hexSubjects[i]); bOut = new ByteArrayOutputStream(); aOut = new ASN1OutputStream(bOut); aOut.writeObject(name); aIn = new ASN1InputStream(new ByteArrayInputStream(bOut.toByteArray())); name = X500Name.getInstance(aIn.readObject()); if (!name.toString().equals(hexSubjects[i + 1])) { fail("failed hex regeneration test " + i + " got: " + name.toString() + " expected " + subjects[i]); } } // // sort test // X500Name unsorted = new X500Name("SERIALNUMBER=BBB + CN=AA"); if (!fromBytes(unsorted.getEncoded()).toString().equals("CN=AA+SERIALNUMBER=BBB")) { fail("failed sort test 1"); } unsorted = new X500Name("CN=AA + SERIALNUMBER=BBB"); if (!fromBytes(unsorted.getEncoded()).toString().equals("CN=AA+SERIALNUMBER=BBB")) { fail("failed sort test 2"); } unsorted = new X500Name("SERIALNUMBER=B + CN=AA"); if (!fromBytes(unsorted.getEncoded()).toString().equals("SERIALNUMBER=B+CN=AA")) { fail("failed sort test 3"); } unsorted = new X500Name("CN=AA + SERIALNUMBER=B"); if (!fromBytes(unsorted.getEncoded()).toString().equals("SERIALNUMBER=B+CN=AA")) { fail("failed sort test 4"); } // // equality tests // equalityTest(new X500Name("CN=The Legion"), new X500Name("CN=The Legion")); equalityTest(new X500Name("CN= The Legion"), new X500Name("CN=The Legion")); equalityTest(new X500Name("CN=The Legion "), new X500Name("CN=The Legion")); equalityTest(new X500Name("CN= The Legion "), new X500Name("CN=The Legion")); equalityTest(new X500Name("CN= the legion "), new X500Name("CN=The Legion")); equalityTest(new X500Name("CN= the legion+C=AU, O=Legion "), new X500Name("CN=The Legion+C=AU, O=Legion")); // # test X500Name n1 = new X500Name("SERIALNUMBER=8,O=ABC,CN=ABC Class 3 CA,C=LT"); X500Name n2 = new X500Name("2.5.4.5=8,O=ABC,CN=ABC Class 3 CA,C=LT"); X500Name n3 = new X500Name("2.5.4.5=#130138,O=ABC,CN=ABC Class 3 CA,C=LT"); equalityTest(n1, n2); equalityTest(n2, n3); equalityTest(n3, n1); n1 = new X500Name("2.5.4.5=#130138,CN=SSC Class 3 CA,O=UAB Skaitmeninio sertifikavimo centras,C=LT"); n2 = new X500Name("SERIALNUMBER=#130138,CN=SSC Class 3 CA,O=UAB Skaitmeninio sertifikavimo centras,C=LT"); n3 = X500Name.getInstance(ASN1Primitive.fromByteArray(Hex.decode("3063310b3009060355040613024c54312f302d060355040a1326" + "55414220536b6169746d656e696e696f20736572746966696b6176696d6f2063656e74726173311730150603550403130e53534320436c6173732033204341310a30080603550405130138"))); equalityTest(n1, n2); equalityTest(n2, n3); equalityTest(n3, n1); n1 = new X500Name("SERIALNUMBER=8,O=XX,CN=ABC Class 3 CA,C=LT"); n2 = new X500Name("2.5.4.5=8,O=,CN=ABC Class 3 CA,C=LT"); // if (n1.equals(n2)) // { // fail("empty inequality check failed"); // } n1 = new X500Name("SERIALNUMBER=8,O=,CN=ABC Class 3 CA,C=LT"); n2 = new X500Name("2.5.4.5=8,O=,CN=ABC Class 3 CA,C=LT"); equalityTest(n1, n2); equalityTest(X500Name.getInstance(BCStrictStyle.INSTANCE, n1), X500Name.getInstance(BCStrictStyle.INSTANCE, n2)); n2 = new X500Name("C=LT,2.5.4.5=8,O=,CN=ABC Class 3 CA"); equalityTest(n1, n2); if (X500Name.getInstance(BCStrictStyle.INSTANCE, n1).equals(X500Name.getInstance(BCStrictStyle.INSTANCE, n2))) { fail("strict comparison failed"); } // // inequality to sequences // name1 = new X500Name("CN=The Legion"); if (name1.equals(new DERSequence())) { fail("inequality test with sequence"); } if (name1.equals(new DERSequence(new DERSet()))) { fail("inequality test with sequence and set"); } ASN1EncodableVector v = new ASN1EncodableVector(); v.add(new ASN1ObjectIdentifier("1.1")); v.add(new ASN1ObjectIdentifier("1.1")); if (name1.equals(new DERSequence(new DERSet(new DERSet(v))))) { fail("inequality test with sequence and bad set"); } if (name1.equals(new DERSequence(new DERSet(new DERSet(v))))) { fail("inequality test with sequence and bad set"); } if (name1.equals(new DERSequence(new DERSet(new DERSequence())))) { fail("inequality test with sequence and short sequence"); } if (name1.equals(new DERSequence(new DERSet(new DERSequence())))) { fail("inequality test with sequence and short sequence"); } v = new ASN1EncodableVector(); v.add(new ASN1ObjectIdentifier("1.1")); v.add(new DERSequence()); if (name1.equals(new DERSequence(new DERSet(new DERSequence(v))))) { fail("inequality test with sequence and bad sequence"); } if (name1.equals(null)) { fail("inequality test with null"); } // if (name1.equals(null, true)) // { // fail("inequality test with null"); // } // // this is contrived but it checks sorting of sets with equal elements // unsorted = new X500Name("CN=AA + CN=AA + CN=AA"); ASN1ObjectIdentifier[] types = unsorted.getAttributeTypes(); if (types.length != 3 || !types[0].equals(BCStyle.CN) || !types[1].equals(BCStyle.CN) || !types[2].equals(BCStyle.CN)) { fail("types not matched correctly"); } // general type test X500Name nested = new X500Name("CN=AA + CN=AA, C=AU"); types = nested.getAttributeTypes(); if (types.length != 3 || !types[0].equals(BCStyle.CN) || !types[1].equals(BCStyle.CN) || !types[2].equals(BCStyle.C)) { fail("nested types not matched correctly"); } // // tagging test - only works if CHOICE implemented // ASN1TaggedObject tag = new DERTaggedObject(false, 1, new X500Name("CN=AA")); if (!tag.isExplicit()) { fail("failed to explicitly tag CHOICE object"); } X500Name name = X500Name.getInstance(tag, false); if (!name.equals(new X500Name("CN=AA"))) { fail("failed to recover tagged name"); } DERUTF8String testString = new DERUTF8String("The Legion of the Bouncy Castle"); byte[] encodedBytes = testString.getEncoded(); byte[] hexEncodedBytes = Hex.encode(encodedBytes); String hexEncodedString = "#" + new String(hexEncodedBytes); DERUTF8String converted = (DERUTF8String) new X509DefaultEntryConverter().getConvertedValue( BCStyle.L , hexEncodedString); if (!converted.equals(testString)) { fail("failed X509DefaultEntryConverter test"); } // // try escaped. // converted = (DERUTF8String) new X509DefaultEntryConverter().getConvertedValue( BCStyle.L , "\\" + hexEncodedString); if (!converted.equals(new DERUTF8String(hexEncodedString))) { fail("failed X509DefaultEntryConverter test got " + converted + " expected: " + hexEncodedString); } // // try a weird value // X500Name n = new X500Name("CN=\\#nothex#string"); if (!n.toString().equals("CN=\\#nothex#string")) { fail("# string not properly escaped."); } RDN[] vls = n.getRDNs(BCStyle.CN); if (vls.length != 1 || !getValue(vls[0]).equals("#nothex#string")) { fail("escaped # not reduced properly"); } types = n.getAttributeTypes(); if (types.length != 1 || !types[0].equals(BCStyle.CN)) { fail("type not matched correctly"); } n = new X500Name("CN=\"a+b\""); vls = n.getRDNs(BCStyle.CN); if (vls.length != 1 || !getValue(vls[0]).equals("a+b")) { fail("escaped + not reduced properly"); } n = new X500Name("CN=a\\+b"); vls = n.getRDNs(BCStyle.CN); if (vls.length != 1 || !getValue(vls[0]).equals("a+b")) { fail("escaped + not reduced properly"); } if (!n.toString().equals("CN=a\\+b")) { fail("+ in string not properly escaped."); } n = new X500Name("CN=a\\=b"); vls = n.getRDNs(BCStyle.CN); if (vls.length != 1 || !getValue(vls[0]).equals("a=b")) { fail("escaped = not reduced properly"); } if (!n.toString().equals("CN=a\\=b")) { fail("= in string not properly escaped."); } n = new X500Name("TELEPHONENUMBER=\"+61999999999\""); vls = n.getRDNs(BCStyle.TELEPHONE_NUMBER); if (vls.length != 1 || !getValue(vls[0]).equals("+61999999999")) { fail("telephonenumber escaped + not reduced properly"); } n = new X500Name("TELEPHONENUMBER=\\+61999999999"); vls = n.getRDNs(BCStyle.TELEPHONE_NUMBER); if (vls.length != 1 || !getValue(vls[0]).equals("+61999999999")) { fail("telephonenumber escaped + not reduced properly"); } // test query methods if (!"E".equals(BCStyle.INSTANCE.oidToDisplayName(BCStyle.EmailAddress))) { fail("display name for E incorrect"); } String[] aliases = BCStyle.INSTANCE.oidToAttrNames(BCStyle.EmailAddress); if (aliases.length != 2) { fail("no aliases found"); } if (!("e".equals(aliases[0]) || "e".equals(aliases[1]))) { fail("first alias name for E incorrect"); } if (!("emailaddress".equals(aliases[0]) || "emailaddress".equals(aliases[1]))) { fail("second alias name for E incorrect"); } if (BCStyle.INSTANCE.oidToDisplayName(new ASN1ObjectIdentifier("1.2.1")) != null) { fail("unknown oid matched!"); } if (BCStyle.INSTANCE.oidToAttrNames(new ASN1ObjectIdentifier("1.2.1")).length != 0) { fail("unknown oid matched aliases!"); } } private String getValue(RDN vl) { return ((ASN1String)vl.getFirst().getValue()).getString(); } /* private boolean compareVectors(Vector a, Vector b) // for compatibility with early JDKs { if (a.size() != b.size()) { return false; } for (int i = 0; i != a.size(); i++) { if (!a.elementAt(i).equals(b.elementAt(i))) { return false; } } return true; } private void compositeTest() throws IOException { // // composite test // byte[] enc = Hex.decode("305e310b300906035504061302415531283026060355040a0c1f546865204c6567696f6e206f662074686520426f756e637920436173746c653125301006035504070c094d656c626f75726e653011060355040b0c0a4173636f742056616c65"); ASN1InputStream aIn = new ASN1InputStream(new ByteArrayInputStream(enc)); X500Name n = X500Name.getInstance(aIn.readObject()); if (!n.toString().equals("C=AU,O=The Legion of the Bouncy Castle,L=Melbourne+OU=Ascot Vale")) { fail("Failed composite to string test got: " + n.toString()); } if (!n.toString(true, X500Name.DefaultSymbols).equals("L=Melbourne+OU=Ascot Vale,O=The Legion of the Bouncy Castle,C=AU")) { fail("Failed composite to string test got: " + n.toString(true, X500Name.DefaultSymbols)); } n = new X500Name(true, "L=Melbourne+OU=Ascot Vale,O=The Legion of the Bouncy Castle,C=AU"); if (!n.toString().equals("C=AU,O=The Legion of the Bouncy Castle,L=Melbourne+OU=Ascot Vale")) { fail("Failed composite to string reversal test got: " + n.toString()); } n = new X500Name("C=AU, O=The Legion of the Bouncy Castle, L=Melbourne + OU=Ascot Vale"); ByteArrayOutputStream bOut = new ByteArrayOutputStream(); ASN1OutputStream aOut = new ASN1OutputStream(bOut); aOut.writeObject(n); byte[] enc2 = bOut.toByteArray(); if (!Arrays.areEqual(enc, enc2)) { fail("Failed composite string to encoding test"); } // // dud name test - handle empty DN without barfing. // n = new X500Name("C=CH,O=,OU=dummy,CN=mail@dummy.com"); n = X500Name.getInstance(ASN1Object.fromByteArray(n.getEncoded())); } */ private void equalityTest(X500Name name1, X500Name name2) { if (!name1.equals(name2)) { fail("equality test failed for " + name1 + " : " + name2); } if (name1.hashCode() != name2.hashCode()) { fail("hashCodeTest test failed for " + name1 + " : " + name2); } } public static void main( String[] args) { runTest(new X500NameTest()); } } bouncycastle-1.49.orig/test/src/org/bouncycastle/asn1/test/MonetaryValueUnitTest.java0000644000175000017500000000436610361171076030453 0ustar ebourgebourgpackage org.bouncycastle.asn1.test; import org.bouncycastle.asn1.ASN1InputStream; import org.bouncycastle.asn1.ASN1Sequence; import org.bouncycastle.asn1.x509.qualified.Iso4217CurrencyCode; import org.bouncycastle.asn1.x509.qualified.MonetaryValue; import org.bouncycastle.util.test.SimpleTest; public class MonetaryValueUnitTest extends SimpleTest { private static final int TEST_AMOUNT = 100; private static final int ZERO_EXPONENT = 0; private static final String CURRENCY_CODE = "AUD"; public String getName() { return "MonetaryValue"; } public void performTest() throws Exception { MonetaryValue mv = new MonetaryValue(new Iso4217CurrencyCode(CURRENCY_CODE), TEST_AMOUNT, ZERO_EXPONENT); checkValues(mv, TEST_AMOUNT, ZERO_EXPONENT); mv = MonetaryValue.getInstance(mv); checkValues(mv, TEST_AMOUNT, ZERO_EXPONENT); ASN1InputStream aIn = new ASN1InputStream(mv.toASN1Object().getEncoded()); ASN1Sequence seq = (ASN1Sequence)aIn.readObject(); mv = MonetaryValue.getInstance(seq); checkValues(mv, TEST_AMOUNT, ZERO_EXPONENT); mv = MonetaryValue.getInstance(null); if (mv != null) { fail("null getInstance() failed."); } try { MonetaryValue.getInstance(new Object()); fail("getInstance() failed to detect bad object."); } catch (IllegalArgumentException e) { // expected } } private void checkValues( MonetaryValue mv, int amount, int exponent) { if (mv.getAmount().intValue() != amount) { fail("amounts don't match."); } if (mv.getExponent().intValue() != exponent) { fail("exponents don't match."); } Iso4217CurrencyCode cc = mv.getCurrency(); if (!cc.getAlphabetic().equals(CURRENCY_CODE)) { fail("currency code wrong"); } } public static void main( String[] args) { runTest(new MonetaryValueUnitTest()); } } bouncycastle-1.49.orig/test/src/org/bouncycastle/asn1/test/DERUTF8StringTest.java0000644000175000017500000000602411703706643027266 0ustar ebourgebourgpackage org.bouncycastle.asn1.test; import org.bouncycastle.asn1.DEROctetString; import org.bouncycastle.asn1.DERUTF8String; import org.bouncycastle.util.Arrays; import org.bouncycastle.util.Strings; import org.bouncycastle.util.test.SimpleTestResult; import org.bouncycastle.util.test.Test; import org.bouncycastle.util.test.TestResult; public class DERUTF8StringTest implements Test { /** * Unicode code point U+10400 coded as surrogate in two native Java UTF-16 * code units */ private final static char[] glyph1_utf16 = { 0xd801, 0xdc00 }; /** * U+10400 coded in UTF-8 */ private final static byte[] glyph1_utf8 = { (byte)0xF0, (byte)0x90, (byte)0x90, (byte)0x80 }; /** * Unicode code point U+6771 in native Java UTF-16 */ private final static char[] glyph2_utf16 = { 0x6771 }; /** * U+6771 coded in UTF-8 */ private final static byte[] glyph2_utf8 = { (byte)0xE6, (byte)0x9D, (byte)0xB1 }; /** * Unicode code point U+00DF in native Java UTF-16 */ private final static char[] glyph3_utf16 = { 0x00DF }; /** * U+00DF coded in UTF-8 */ private final static byte[] glyph3_utf8 = { (byte)0xC3, (byte)0x9f }; /** * Unicode code point U+0041 in native Java UTF-16 */ private final static char[] glyph4_utf16 = { 0x0041 }; /** * U+0041 coded in UTF-8 */ private final static byte[] glyph4_utf8 = { 0x41 }; private final static byte[][] glyphs_utf8 = { glyph1_utf8, glyph2_utf8, glyph3_utf8, glyph4_utf8 }; private final static char[][] glyphs_utf16 = { glyph1_utf16, glyph2_utf16, glyph3_utf16, glyph4_utf16 }; public TestResult perform() { try { for (int i = 0; i < glyphs_utf16.length; i++) { String s = new String(glyphs_utf16[i]); byte[] b1 = new DERUTF8String(s).getEncoded(); byte temp[] = new byte[b1.length - 2]; System.arraycopy(b1, 2, temp, 0, b1.length - 2); byte[] b2 = new DERUTF8String(Strings.fromUTF8ByteArray(new DEROctetString(temp).getOctets())).getEncoded(); if (!Arrays.areEqual(b1, b2)) { return new SimpleTestResult(false, getName() + ": failed UTF-8 encoding and decoding"); } if (!Arrays.areEqual(temp, glyphs_utf8[i])) { return new SimpleTestResult(false, getName() + ": failed UTF-8 encoding and decoding"); } } } catch (Exception e) { return new SimpleTestResult(false, getName() + ": failed with Exception " + e.getMessage()); } return new SimpleTestResult(true, getName() + ": Okay"); } public String getName() { return "DERUTF8String"; } public static void main(String[] args) { DERUTF8StringTest test = new DERUTF8StringTest(); TestResult result = test.perform(); System.out.println(result); } } bouncycastle-1.49.orig/test/src/org/bouncycastle/asn1/test/ObjectIdentifierTest.java0000644000175000017500000000163112021243442030211 0ustar ebourgebourgpackage org.bouncycastle.asn1.test; import org.bouncycastle.asn1.ASN1ObjectIdentifier; import org.bouncycastle.util.test.SimpleTest; import org.bouncycastle.util.test.TestResult; public class ObjectIdentifierTest extends SimpleTest { public String getName() { return "ObjectIdentifier"; } public void performTest() throws Exception { // exercise the object cache for (int i = 0; i < 1024; i++) { for (int j = 0; j != 17000; j++) { byte[] encoded = new ASN1ObjectIdentifier("1.1." + i + "." + j).getEncoded(); ASN1ObjectIdentifier.getInstance(encoded); } } } public static void main( String[] args) { ObjectIdentifierTest test = new ObjectIdentifierTest(); TestResult result = test.perform(); System.out.println(result); } } bouncycastle-1.49.orig/test/src/org/bouncycastle/asn1/test/X9Test.java0000644000175000017500000001447111726011310025304 0ustar ebourgebourgpackage org.bouncycastle.asn1.test; import java.io.ByteArrayInputStream; import java.io.ByteArrayOutputStream; import java.math.BigInteger; import org.bouncycastle.asn1.ASN1InputStream; import org.bouncycastle.asn1.ASN1OctetString; import org.bouncycastle.asn1.ASN1Primitive; import org.bouncycastle.asn1.DEROutputStream; import org.bouncycastle.asn1.pkcs.PrivateKeyInfo; import org.bouncycastle.asn1.sec.ECPrivateKey; import org.bouncycastle.asn1.x509.AlgorithmIdentifier; import org.bouncycastle.asn1.x509.SubjectPublicKeyInfo; import org.bouncycastle.asn1.x9.X962NamedCurves; import org.bouncycastle.asn1.x9.X962Parameters; import org.bouncycastle.asn1.x9.X9ECParameters; import org.bouncycastle.asn1.x9.X9ECPoint; import org.bouncycastle.asn1.x9.X9IntegerConverter; import org.bouncycastle.asn1.x9.X9ObjectIdentifiers; import org.bouncycastle.math.ec.ECFieldElement; import org.bouncycastle.math.ec.ECPoint; import org.bouncycastle.util.encoders.Base64; import org.bouncycastle.util.test.SimpleTest; public class X9Test extends SimpleTest { private byte[] namedPub = Base64.decode("MBowEwYHKoZIzj0CAQYIKoZIzj0DAQEDAwADAQ=="); private byte[] expPub = Base64.decode( "MIHfMIHXBgcqhkjOPQIBMIHLAgEBMCkGByqGSM49AQECHn///////////////3///////4AAAA" + "AAAH///////zBXBB5///////////////9///////+AAAAAAAB///////wEHiVXBfoqMGZUsfTL" + "A9anUKMMJQEC1JiHF9m6FattPgMVAH1zdBaP/jRxtgqFdoahlHXTv6L/BB8DZ2iujhi7ks/PAF" + "yUmqLG2UhT0OZgu/hUsclQX+laAh5///////////////9///+XXetBs6YFfDxDIUZSZVECAQED" + "AwADAQ=="); private byte[] namedPriv = Base64.decode("MCICAQAwEwYHKoZIzj0CAQYIKoZIzj0DAQEECDAGAgEBBAEK"); private byte[] expPriv = Base64.decode( "MIHnAgEAMIHXBgcqhkjOPQIBMIHLAgEBMCkGByqGSM49AQECHn///////////////3///////4" + "AAAAAAAH///////zBXBB5///////////////9///////+AAAAAAAB///////wEHiVXBfoqMGZU" + "sfTLA9anUKMMJQEC1JiHF9m6FattPgMVAH1zdBaP/jRxtgqFdoahlHXTv6L/BB8DZ2iujhi7ks" + "/PAFyUmqLG2UhT0OZgu/hUsclQX+laAh5///////////////9///+XXetBs6YFfDxDIUZSZVEC" + "AQEECDAGAgEBBAEU"); private void encodePublicKey() throws Exception { ByteArrayOutputStream bOut = new ByteArrayOutputStream(); DEROutputStream dOut = new DEROutputStream(bOut); X9ECParameters ecP = X962NamedCurves.getByOID(X9ObjectIdentifiers.prime239v3); X9IntegerConverter conv = new X9IntegerConverter(); if (conv.getByteLength(ecP.getCurve()) != 30) { fail("wrong byte length reported for curve"); } if (ecP.getCurve().getFieldSize() != 239) { fail("wrong field size reported for curve"); } // // named curve // X962Parameters params = new X962Parameters(X9ObjectIdentifiers.prime192v1); ASN1OctetString p = ASN1OctetString.getInstance(new X9ECPoint(new ECPoint.Fp(ecP.getCurve(), new ECFieldElement.Fp(BigInteger.valueOf(2), BigInteger.valueOf(1)), new ECFieldElement.Fp(BigInteger.valueOf(4), BigInteger.valueOf(3)), true))); SubjectPublicKeyInfo info = new SubjectPublicKeyInfo(new AlgorithmIdentifier(X9ObjectIdentifiers.id_ecPublicKey, params), p.getOctets()); if (!areEqual(info.getEncoded(), namedPub)) { fail("failed public named generation"); } ASN1InputStream aIn = new ASN1InputStream(new ByteArrayInputStream(namedPub)); ASN1Primitive o = aIn.readObject(); if (!info.equals(o)) { fail("failed public named equality"); } // // explicit curve parameters // params = new X962Parameters(ecP); info = new SubjectPublicKeyInfo(new AlgorithmIdentifier(X9ObjectIdentifiers.id_ecPublicKey, params), p.getOctets()); if (!areEqual(info.getEncoded(), expPub)) { fail("failed public explicit generation"); } aIn = new ASN1InputStream(new ByteArrayInputStream(expPub)); o = aIn.readObject(); if (!info.equals(o)) { fail("failed public explicit equality"); } } private void encodePrivateKey() throws Exception { ByteArrayOutputStream bOut = new ByteArrayOutputStream(); DEROutputStream dOut = new DEROutputStream(bOut); X9ECParameters ecP = X962NamedCurves.getByOID(X9ObjectIdentifiers.prime239v3); // // named curve // X962Parameters params = new X962Parameters(X9ObjectIdentifiers.prime192v1); ASN1OctetString p = ASN1OctetString.getInstance(new X9ECPoint(new ECPoint.Fp(ecP.getCurve(), new ECFieldElement.Fp(BigInteger.valueOf(2), BigInteger.valueOf(1)), new ECFieldElement.Fp(BigInteger.valueOf(4), BigInteger.valueOf(3)), true))); PrivateKeyInfo info = new PrivateKeyInfo(new AlgorithmIdentifier(X9ObjectIdentifiers.id_ecPublicKey, params), new ECPrivateKey(BigInteger.valueOf(10))); if (!areEqual(info.getEncoded(), namedPriv)) { fail("failed private named generation"); } ASN1InputStream aIn = new ASN1InputStream(new ByteArrayInputStream(namedPriv)); ASN1Primitive o = aIn.readObject(); if (!info.equals(o)) { fail("failed private named equality"); } // // explicit curve parameters // params = new X962Parameters(ecP); info = new PrivateKeyInfo(new AlgorithmIdentifier(X9ObjectIdentifiers.id_ecPublicKey, params), new ECPrivateKey(BigInteger.valueOf(20))); if (!areEqual(info.getEncoded(), expPriv)) { fail("failed private explicit generation"); } aIn = new ASN1InputStream(new ByteArrayInputStream(expPriv)); o = aIn.readObject(); if (!info.equals(o)) { fail("failed private explicit equality"); } } public void performTest() throws Exception { encodePublicKey(); encodePrivateKey(); } public String getName() { return "X9"; } public static void main( String[] args) { runTest(new X9Test()); } } bouncycastle-1.49.orig/test/src/org/bouncycastle/asn1/test/RFC4519Test.java0000644000175000017500000001206111511171717025744 0ustar ebourgebourgpackage org.bouncycastle.asn1.test; import org.bouncycastle.asn1.ASN1ObjectIdentifier; import org.bouncycastle.asn1.x500.X500Name; import org.bouncycastle.asn1.x500.X500NameStyle; import org.bouncycastle.asn1.x500.style.RFC4519Style; import org.bouncycastle.util.Arrays; import org.bouncycastle.util.encoders.Hex; import org.bouncycastle.util.test.SimpleTest; public class RFC4519Test extends SimpleTest { static String[] attributeTypes = { "businessCategory", "c", "cn", "dc", "description", "destinationIndicator", "distinguishedName", "dnQualifier", "enhancedSearchGuide", "facsimileTelephoneNumber", "generationQualifier", "givenName", "houseIdentifier", "initials", "internationalISDNNumber", "l", "member", "name", "o", "ou", "owner", "physicalDeliveryOfficeName", "postalAddress", "postalCode", "postOfficeBox", "preferredDeliveryMethod", "registeredAddress", "roleOccupant", "searchGuide", "seeAlso", "serialNumber", "sn", "st", "street", "telephoneNumber", "teletexTerminalIdentifier", "telexNumber", "title", "uid", "uniqueMember", "userPassword", "x121Address", "x500UniqueIdentifier" }; static ASN1ObjectIdentifier[] attributeTypeOIDs = { new ASN1ObjectIdentifier("2.5.4.15"), new ASN1ObjectIdentifier("2.5.4.6"), new ASN1ObjectIdentifier("2.5.4.3"), new ASN1ObjectIdentifier("0.9.2342.19200300.100.1.25"), new ASN1ObjectIdentifier("2.5.4.13"), new ASN1ObjectIdentifier("2.5.4.27"), new ASN1ObjectIdentifier("2.5.4.49"), new ASN1ObjectIdentifier("2.5.4.46"), new ASN1ObjectIdentifier("2.5.4.47"), new ASN1ObjectIdentifier("2.5.4.23"), new ASN1ObjectIdentifier("2.5.4.44"), new ASN1ObjectIdentifier("2.5.4.42"), new ASN1ObjectIdentifier("2.5.4.51"), new ASN1ObjectIdentifier("2.5.4.43"), new ASN1ObjectIdentifier("2.5.4.25"), new ASN1ObjectIdentifier("2.5.4.7"), new ASN1ObjectIdentifier("2.5.4.31"), new ASN1ObjectIdentifier("2.5.4.41"), new ASN1ObjectIdentifier("2.5.4.10"), new ASN1ObjectIdentifier("2.5.4.11"), new ASN1ObjectIdentifier("2.5.4.32"), new ASN1ObjectIdentifier("2.5.4.19"), new ASN1ObjectIdentifier("2.5.4.16"), new ASN1ObjectIdentifier("2.5.4.17"), new ASN1ObjectIdentifier("2.5.4.18"), new ASN1ObjectIdentifier("2.5.4.28"), new ASN1ObjectIdentifier("2.5.4.26"), new ASN1ObjectIdentifier("2.5.4.33"), new ASN1ObjectIdentifier("2.5.4.14"), new ASN1ObjectIdentifier("2.5.4.34"), new ASN1ObjectIdentifier("2.5.4.5"), new ASN1ObjectIdentifier("2.5.4.4"), new ASN1ObjectIdentifier("2.5.4.8"), new ASN1ObjectIdentifier("2.5.4.9"), new ASN1ObjectIdentifier("2.5.4.20"), new ASN1ObjectIdentifier("2.5.4.22"), new ASN1ObjectIdentifier("2.5.4.21"), new ASN1ObjectIdentifier("2.5.4.12"), new ASN1ObjectIdentifier("0.9.2342.19200300.100.1.1"), new ASN1ObjectIdentifier("2.5.4.50"), new ASN1ObjectIdentifier("2.5.4.35"), new ASN1ObjectIdentifier("2.5.4.24"), new ASN1ObjectIdentifier("2.5.4.45") }; public String getName() { return "RFC4519Test"; } public void performTest() throws Exception { X500NameStyle style = RFC4519Style.INSTANCE; for (int i = 0; i != attributeTypes.length; i++) { if (!attributeTypeOIDs[i].equals(style.attrNameToOID(attributeTypes[i]))) { fail("mismatch for " + attributeTypes[i]); } } byte[] enc = Hex.decode("305e310b300906035504061302415531283026060355040a0c1f546865204c6567696f6e206f662074686520426f756e637920436173746c653125301006035504070c094d656c626f75726e653011060355040b0c0a4173636f742056616c65"); X500Name n = new X500Name(style, X500Name.getInstance(enc)); if (!n.toString().equals("l=Melbourne+ou=Ascot Vale,o=The Legion of the Bouncy Castle,c=AU")) { fail("Failed composite to string test got: " + n.toString()); } n = new X500Name(style, "l=Melbourne+ou=Ascot Vale,o=The Legion of the Bouncy Castle,c=AU"); if (!Arrays.areEqual(n.getEncoded(), enc)) { fail("re-encoding test after parse failed"); } } public static void main( String[] args) { runTest(new RFC4519Test()); } } bouncycastle-1.49.orig/test/src/org/bouncycastle/asn1/test/TargetInformationTest.java0000644000175000017500000000337511625355266030464 0ustar ebourgebourgpackage org.bouncycastle.asn1.test; import org.bouncycastle.asn1.x509.GeneralName; import org.bouncycastle.asn1.x509.Target; import org.bouncycastle.asn1.x509.TargetInformation; import org.bouncycastle.asn1.x509.Targets; import org.bouncycastle.util.test.SimpleTest; public class TargetInformationTest extends SimpleTest { public String getName() { return "TargetInformation"; } public void performTest() throws Exception { Target[] targets = new Target[2]; Target targetName = new Target(Target.targetName, new GeneralName(GeneralName.dNSName, "www.test.com")); Target targetGroup = new Target(Target.targetGroup, new GeneralName(GeneralName.directoryName, "o=Test, ou=Test")); targets[0] = targetName; targets[1] = targetGroup; Targets targetss = new Targets(targets); TargetInformation targetInformation1 = new TargetInformation(targetss); // use an Target array TargetInformation targetInformation2 = new TargetInformation(targets); // targetInformation1 and targetInformation2 must have same // encoding. if (!targetInformation1.equals(targetInformation2)) { fail("targetInformation1 and targetInformation2 should have the same encoding."); } TargetInformation targetInformation3 = TargetInformation.getInstance(targetInformation1); TargetInformation targetInformation4 = TargetInformation.getInstance(targetInformation2); if (!targetInformation3.equals(targetInformation4)) { fail("targetInformation3 and targetInformation4 should have the same encoding."); } } public static void main(String[] args) { runTest(new TargetInformationTest()); } } bouncycastle-1.49.orig/test/src/org/bouncycastle/asn1/test/ParseTest.java0000644000175000017500000004453511625105757026103 0ustar ebourgebourgpackage org.bouncycastle.asn1.test; import java.io.IOException; import junit.framework.TestCase; import org.bouncycastle.asn1.ASN1OctetStringParser; import org.bouncycastle.asn1.ASN1SequenceParser; import org.bouncycastle.asn1.ASN1StreamParser; import org.bouncycastle.asn1.ASN1TaggedObjectParser; import org.bouncycastle.asn1.BERTags; import org.bouncycastle.asn1.cms.ContentInfoParser; import org.bouncycastle.asn1.cms.EncryptedContentInfoParser; import org.bouncycastle.asn1.cms.EnvelopedDataParser; import org.bouncycastle.util.encoders.Base64; import org.bouncycastle.util.encoders.Hex; import org.bouncycastle.util.io.Streams; public class ParseTest extends TestCase { private static byte[] classCastTest = Base64.decode( "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"); private static byte[] derExpTest = Base64.decode( "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" + "yv8TOTFCWnZEUTtVA9+2CpwfmuEjD2UQ4vxoM+o="); byte[] longTagged = Hex.decode("9f1f023330"); public void testClassCast() throws IOException { parseEnveloped(classCastTest); } public void testDerExp() throws IOException { parseEnveloped(derExpTest); } public void testLongTag() throws IOException { ASN1StreamParser aIn = new ASN1StreamParser(longTagged); ASN1TaggedObjectParser tagged = (ASN1TaggedObjectParser)aIn.readObject(); assertEquals(31, tagged.getTagNo()); } private void parseEnveloped(byte[] data) throws IOException { ASN1StreamParser aIn = new ASN1StreamParser(data); ContentInfoParser cP = new ContentInfoParser((ASN1SequenceParser)aIn.readObject()); EnvelopedDataParser eP = new EnvelopedDataParser((ASN1SequenceParser)cP.getContent(BERTags.SEQUENCE)); eP.getRecipientInfos().toASN1Primitive(); // Must drain the parser! EncryptedContentInfoParser ecP = eP.getEncryptedContentInfo(); ASN1OctetStringParser content = (ASN1OctetStringParser)ecP.getEncryptedContent(BERTags.OCTET_STRING); Streams.drain(content.getOctetStream()); } } bouncycastle-1.49.orig/test/src/org/bouncycastle/asn1/test/SemanticsInformationUnitTest.java0000644000175000017500000000751211706151726032014 0ustar ebourgebourgpackage org.bouncycastle.asn1.test; import org.bouncycastle.asn1.ASN1EncodableVector; import org.bouncycastle.asn1.ASN1InputStream; import org.bouncycastle.asn1.ASN1ObjectIdentifier; import org.bouncycastle.asn1.ASN1Sequence; import org.bouncycastle.asn1.DERObjectIdentifier; import org.bouncycastle.asn1.DERSequence; import org.bouncycastle.asn1.x509.GeneralName; import org.bouncycastle.asn1.x509.X509Name; import org.bouncycastle.asn1.x509.qualified.SemanticsInformation; import org.bouncycastle.util.test.SimpleTest; public class SemanticsInformationUnitTest extends SimpleTest { public String getName() { return "SemanticsInformation"; } public void performTest() throws Exception { ASN1ObjectIdentifier statementId = new ASN1ObjectIdentifier("1.1"); SemanticsInformation mv = new SemanticsInformation(statementId); checkConstruction(mv, statementId, null); GeneralName[] names = new GeneralName[2]; names[0] = new GeneralName(GeneralName.rfc822Name, "test@test.org"); names[1] = new GeneralName(new X509Name("cn=test")); mv = new SemanticsInformation(statementId, names); checkConstruction(mv, statementId, names); mv = new SemanticsInformation(names); checkConstruction(mv, null, names); mv = SemanticsInformation.getInstance(null); if (mv != null) { fail("null getInstance() failed."); } try { SemanticsInformation.getInstance(new Object()); fail("getInstance() failed to detect bad object."); } catch (IllegalArgumentException e) { // expected } try { ASN1EncodableVector v = new ASN1EncodableVector(); SemanticsInformation.getInstance(new DERSequence(v)); fail("constructor failed to detect empty sequence."); } catch (IllegalArgumentException e) { // expected } } private void checkConstruction( SemanticsInformation mv, DERObjectIdentifier semanticsIdentifier, GeneralName[] names) throws Exception { checkStatement(mv, semanticsIdentifier, names); mv = SemanticsInformation.getInstance(mv); checkStatement(mv, semanticsIdentifier, names); ASN1InputStream aIn = new ASN1InputStream(mv.toASN1Object().getEncoded()); ASN1Sequence seq = (ASN1Sequence)aIn.readObject(); mv = SemanticsInformation.getInstance(seq); checkStatement(mv, semanticsIdentifier, names); } private void checkStatement( SemanticsInformation si, DERObjectIdentifier id, GeneralName[] names) { if (id != null) { if (!si.getSemanticsIdentifier().equals(id)) { fail("ids don't match."); } } else if (si.getSemanticsIdentifier() != null) { fail("statementId found when none expected."); } if (names != null) { GeneralName[] siNames = si.getNameRegistrationAuthorities(); for (int i = 0; i != siNames.length; i++) { if (!names[i].equals(siNames[i])) { fail("name registration authorities don't match."); } } } else if (si.getNameRegistrationAuthorities() != null) { fail("name registration authorities found when none expected."); } } public static void main( String[] args) { runTest(new SemanticsInformationUnitTest()); } } bouncycastle-1.49.orig/test/src/org/bouncycastle/asn1/test/NameOrPseudonymUnitTest.java0000644000175000017500000000540011625364337030743 0ustar ebourgebourgpackage org.bouncycastle.asn1.test; import java.io.IOException; import org.bouncycastle.asn1.ASN1InputStream; import org.bouncycastle.asn1.ASN1Sequence; import org.bouncycastle.asn1.ASN1String; import org.bouncycastle.asn1.DERSequence; import org.bouncycastle.asn1.x500.DirectoryString; import org.bouncycastle.asn1.x509.sigi.NameOrPseudonym; public class NameOrPseudonymUnitTest extends ASN1UnitTest { public String getName() { return "NameOrPseudonym"; } public void performTest() throws Exception { String pseudonym = "pseudonym"; DirectoryString surname = new DirectoryString("surname"); ASN1Sequence givenName = new DERSequence(new DirectoryString("givenName")); NameOrPseudonym id = new NameOrPseudonym(pseudonym); checkConstruction(id, pseudonym, null, null); id = new NameOrPseudonym(surname, givenName); checkConstruction(id, null, surname, givenName); id = NameOrPseudonym.getInstance(null); if (id != null) { fail("null getInstance() failed."); } try { NameOrPseudonym.getInstance(new Object()); fail("getInstance() failed to detect bad object."); } catch (IllegalArgumentException e) { // expected } } private void checkConstruction( NameOrPseudonym id, String pseudonym, DirectoryString surname, ASN1Sequence givenName) throws IOException { checkValues(id, pseudonym, surname, givenName); id = NameOrPseudonym.getInstance(id); checkValues(id, pseudonym, surname, givenName); ASN1InputStream aIn = new ASN1InputStream(id.toASN1Object().getEncoded()); if (surname != null) { ASN1Sequence seq = (ASN1Sequence)aIn.readObject(); id = NameOrPseudonym.getInstance(seq); } else { ASN1String s = (ASN1String)aIn.readObject(); id = NameOrPseudonym.getInstance(s); } checkValues(id, pseudonym, surname, givenName); } private void checkValues( NameOrPseudonym id, String pseudonym, DirectoryString surname, ASN1Sequence givenName) { if (surname != null) { checkMandatoryField("surname", surname, id.getSurname()); checkMandatoryField("givenName", givenName, new DERSequence(id.getGivenName()[0])); } else { checkOptionalField("pseudonym", new DirectoryString(pseudonym), id.getPseudonym()); } } public static void main( String[] args) { runTest(new NameOrPseudonymUnitTest()); } } bouncycastle-1.49.orig/test/src/org/bouncycastle/asn1/test/ASN1SequenceParserTest.java0000644000175000017500000002730610756644217030401 0ustar ebourgebourgpackage org.bouncycastle.asn1.test; import junit.framework.Test; import junit.framework.TestCase; import junit.framework.TestSuite; import org.bouncycastle.asn1.ASN1Null; import org.bouncycastle.asn1.ASN1SequenceParser; import org.bouncycastle.asn1.ASN1StreamParser; import org.bouncycastle.asn1.BERSequenceGenerator; import org.bouncycastle.asn1.DERInteger; import org.bouncycastle.asn1.DERObjectIdentifier; import org.bouncycastle.asn1.DERSequenceGenerator; import org.bouncycastle.util.encoders.Hex; import java.io.ByteArrayOutputStream; import java.io.IOException; import java.math.BigInteger; import java.util.Arrays; public class ASN1SequenceParserTest extends TestCase { private static final byte[] seqData = Hex.decode("3006020100060129"); private static final byte[] nestedSeqData = Hex.decode("300b0201000601293003020101"); private static final byte[] expTagSeqData = Hex.decode("a1083006020100060129"); private static final byte[] implTagSeqData = Hex.decode("a106020100060129"); private static final byte[] nestedSeqExpTagData = Hex.decode("300d020100060129a1053003020101"); private static final byte[] nestedSeqImpTagData = Hex.decode("300b020100060129a103020101"); private static final byte[] berSeqData = Hex.decode("30800201000601290000"); private static final byte[] berDERNestedSeqData = Hex.decode("308002010006012930030201010000"); private static final byte[] berNestedSeqData = Hex.decode("3080020100060129308002010100000000"); private static final byte[] berExpTagSeqData = Hex.decode("a180308002010006012900000000"); private static final byte[] berSeqWithDERNullData = Hex.decode("308005000201000601290000"); public void testDERWriting() throws Exception { ByteArrayOutputStream bOut = new ByteArrayOutputStream(); DERSequenceGenerator seqGen = new DERSequenceGenerator(bOut); seqGen.addObject(new DERInteger(BigInteger.valueOf(0))); seqGen.addObject(new DERObjectIdentifier("1.1")); seqGen.close(); assertTrue("basic DER writing test failed.", Arrays.equals(seqData, bOut.toByteArray())); } public void testNestedDERWriting() throws Exception { ByteArrayOutputStream bOut = new ByteArrayOutputStream(); DERSequenceGenerator seqGen1 = new DERSequenceGenerator(bOut); seqGen1.addObject(new DERInteger(BigInteger.valueOf(0))); seqGen1.addObject(new DERObjectIdentifier("1.1")); DERSequenceGenerator seqGen2 = new DERSequenceGenerator(seqGen1.getRawOutputStream()); seqGen2.addObject(new DERInteger(BigInteger.valueOf(1))); seqGen2.close(); seqGen1.close(); assertTrue("nested DER writing test failed.", Arrays.equals(nestedSeqData, bOut.toByteArray())); } public void testDERExplicitTaggedSequenceWriting() throws Exception { ByteArrayOutputStream bOut = new ByteArrayOutputStream(); DERSequenceGenerator seqGen = new DERSequenceGenerator(bOut, 1, true); seqGen.addObject(new DERInteger(BigInteger.valueOf(0))); seqGen.addObject(new DERObjectIdentifier("1.1")); seqGen.close(); assertTrue("explicit tag writing test failed.", Arrays.equals(expTagSeqData, bOut.toByteArray())); } public void testDERImplicitTaggedSequenceWriting() throws Exception { ByteArrayOutputStream bOut = new ByteArrayOutputStream(); DERSequenceGenerator seqGen = new DERSequenceGenerator(bOut, 1, false); seqGen.addObject(new DERInteger(BigInteger.valueOf(0))); seqGen.addObject(new DERObjectIdentifier("1.1")); seqGen.close(); assertTrue("implicit tag writing test failed.", Arrays.equals(implTagSeqData, bOut.toByteArray())); } public void testNestedExplicitTagDERWriting() throws Exception { ByteArrayOutputStream bOut = new ByteArrayOutputStream(); DERSequenceGenerator seqGen1 = new DERSequenceGenerator(bOut); seqGen1.addObject(new DERInteger(BigInteger.valueOf(0))); seqGen1.addObject(new DERObjectIdentifier("1.1")); DERSequenceGenerator seqGen2 = new DERSequenceGenerator(seqGen1.getRawOutputStream(), 1, true); seqGen2.addObject(new DERInteger(BigInteger.valueOf(1))); seqGen2.close(); seqGen1.close(); assertTrue("nested explicit tagged DER writing test failed.", Arrays.equals(nestedSeqExpTagData, bOut.toByteArray())); } public void testNestedImplicitTagDERWriting() throws Exception { ByteArrayOutputStream bOut = new ByteArrayOutputStream(); DERSequenceGenerator seqGen1 = new DERSequenceGenerator(bOut); seqGen1.addObject(new DERInteger(BigInteger.valueOf(0))); seqGen1.addObject(new DERObjectIdentifier("1.1")); DERSequenceGenerator seqGen2 = new DERSequenceGenerator(seqGen1.getRawOutputStream(), 1, false); seqGen2.addObject(new DERInteger(BigInteger.valueOf(1))); seqGen2.close(); seqGen1.close(); assertTrue("nested implicit tagged DER writing test failed.", Arrays.equals(nestedSeqImpTagData, bOut.toByteArray())); } public void testBERWriting() throws Exception { ByteArrayOutputStream bOut = new ByteArrayOutputStream(); BERSequenceGenerator seqGen = new BERSequenceGenerator(bOut); seqGen.addObject(new DERInteger(BigInteger.valueOf(0))); seqGen.addObject(new DERObjectIdentifier("1.1")); seqGen.close(); assertTrue("basic BER writing test failed.", Arrays.equals(berSeqData, bOut.toByteArray())); } public void testNestedBERDERWriting() throws Exception { ByteArrayOutputStream bOut = new ByteArrayOutputStream(); BERSequenceGenerator seqGen1 = new BERSequenceGenerator(bOut); seqGen1.addObject(new DERInteger(BigInteger.valueOf(0))); seqGen1.addObject(new DERObjectIdentifier("1.1")); DERSequenceGenerator seqGen2 = new DERSequenceGenerator(seqGen1.getRawOutputStream()); seqGen2.addObject(new DERInteger(BigInteger.valueOf(1))); seqGen2.close(); seqGen1.close(); assertTrue("nested BER/DER writing test failed.", Arrays.equals(berDERNestedSeqData, bOut.toByteArray())); } public void testNestedBERWriting() throws Exception { ByteArrayOutputStream bOut = new ByteArrayOutputStream(); BERSequenceGenerator seqGen1 = new BERSequenceGenerator(bOut); seqGen1.addObject(new DERInteger(BigInteger.valueOf(0))); seqGen1.addObject(new DERObjectIdentifier("1.1")); BERSequenceGenerator seqGen2 = new BERSequenceGenerator(seqGen1.getRawOutputStream()); seqGen2.addObject(new DERInteger(BigInteger.valueOf(1))); seqGen2.close(); seqGen1.close(); assertTrue("nested BER writing test failed.", Arrays.equals(berNestedSeqData, bOut.toByteArray())); } public void testDERReading() throws Exception { ASN1StreamParser aIn = new ASN1StreamParser(seqData); ASN1SequenceParser seq = (ASN1SequenceParser)aIn.readObject(); Object o; int count = 0; assertNotNull("null sequence returned", seq); while ((o = seq.readObject()) != null) { switch (count) { case 0: assertTrue(o instanceof DERInteger); break; case 1: assertTrue(o instanceof DERObjectIdentifier); break; } count++; } assertEquals("wrong number of objects in sequence", 2, count); } private void testNestedReading( byte[] data) throws Exception { ASN1StreamParser aIn = new ASN1StreamParser(data); ASN1SequenceParser seq = (ASN1SequenceParser)aIn.readObject(); Object o; int count = 0; assertNotNull("null sequence returned", seq); while ((o = seq.readObject()) != null) { switch (count) { case 0: assertTrue(o instanceof DERInteger); break; case 1: assertTrue(o instanceof DERObjectIdentifier); break; case 2: assertTrue(o instanceof ASN1SequenceParser); ASN1SequenceParser s = (ASN1SequenceParser)o; // NB: Must exhaust the nested parser while (s.readObject() != null) { // Nothing } break; } count++; } assertEquals("wrong number of objects in sequence", 3, count); } public void testNestedDERReading() throws Exception { testNestedReading(nestedSeqData); } public void testBERReading() throws Exception { ASN1StreamParser aIn = new ASN1StreamParser(berSeqData); ASN1SequenceParser seq = (ASN1SequenceParser)aIn.readObject(); Object o; int count = 0; assertNotNull("null sequence returned", seq); while ((o = seq.readObject()) != null) { switch (count) { case 0: assertTrue(o instanceof DERInteger); break; case 1: assertTrue(o instanceof DERObjectIdentifier); break; } count++; } assertEquals("wrong number of objects in sequence", 2, count); } public void testNestedBERDERReading() throws Exception { testNestedReading(berDERNestedSeqData); } public void testNestedBERReading() throws Exception { testNestedReading(berNestedSeqData); } public void testBERExplicitTaggedSequenceWriting() throws Exception { ByteArrayOutputStream bOut = new ByteArrayOutputStream(); BERSequenceGenerator seqGen = new BERSequenceGenerator(bOut, 1, true); seqGen.addObject(new DERInteger(BigInteger.valueOf(0))); seqGen.addObject(new DERObjectIdentifier("1.1")); seqGen.close(); assertTrue("explicit BER tag writing test failed.", Arrays.equals(berExpTagSeqData, bOut.toByteArray())); } public void testSequenceWithDERNullReading() throws Exception { testParseWithNull(berSeqWithDERNullData); } private void testParseWithNull(byte[] data) throws IOException { ASN1StreamParser aIn = new ASN1StreamParser(data); ASN1SequenceParser seq = (ASN1SequenceParser)aIn.readObject(); Object o; int count = 0; assertNotNull("null sequence returned", seq); while ((o = seq.readObject()) != null) { switch (count) { case 0: assertTrue(o instanceof ASN1Null); break; case 1: assertTrue(o instanceof DERInteger); break; case 2: assertTrue(o instanceof DERObjectIdentifier); break; } count++; } assertEquals("wrong number of objects in sequence", 3, count); } public static Test suite() { return new TestSuite(ASN1SequenceParserTest.class); } } bouncycastle-1.49.orig/test/src/org/bouncycastle/asn1/test/ESSCertIDv2UnitTest.java0000644000175000017500000000156411625105537027615 0ustar ebourgebourgpackage org.bouncycastle.asn1.test; import org.bouncycastle.asn1.ASN1Primitive; import org.bouncycastle.asn1.ess.ESSCertIDv2; import org.bouncycastle.asn1.nist.NISTObjectIdentifiers; import org.bouncycastle.asn1.x509.AlgorithmIdentifier; public class ESSCertIDv2UnitTest extends ASN1UnitTest { public String getName() { return "ESSCertIDv2"; } public void performTest() throws Exception { // check getInstance on default algorithm. byte[] digest = new byte [256]; ESSCertIDv2 essCertIdv2 = new ESSCertIDv2(new AlgorithmIdentifier( NISTObjectIdentifiers.id_sha256), digest); ASN1Primitive asn1Object = essCertIdv2.toASN1Primitive(); ESSCertIDv2.getInstance(asn1Object); } public static void main( String[] args) { runTest(new ESSCertIDv2UnitTest()); } }bouncycastle-1.49.orig/test/src/org/bouncycastle/asn1/test/GeneralNameTest.java0000644000175000017500000001235211701226727027173 0ustar ebourgebourgpackage org.bouncycastle.asn1.test; import org.bouncycastle.asn1.x509.GeneralName; import org.bouncycastle.util.Arrays; import org.bouncycastle.util.encoders.Hex; import org.bouncycastle.util.test.SimpleTest; public class GeneralNameTest extends SimpleTest { private static final byte[] ipv4 = Hex.decode("87040a090800"); private static final byte[] ipv4WithMask1 = Hex.decode("87080a090800ffffff00"); private static final byte[] ipv4WithMask2 = Hex.decode("87080a090800ffff8000"); private static final byte[] ipv4WithMask3 = Hex.decode("87080a090800ffffc000"); private static final byte[] ipv6a = Hex.decode("871020010db885a308d313198a2e03707334"); private static final byte[] ipv6b = Hex.decode("871020010db885a3000013198a2e03707334"); private static final byte[] ipv6c = Hex.decode("871000000000000000000000000000000001"); private static final byte[] ipv6d = Hex.decode("871020010db885a3000000008a2e03707334"); private static final byte[] ipv6e = Hex.decode("871020010db885a3000000008a2e0a090800"); private static final byte[] ipv6f = Hex.decode("872020010db885a3000000008a2e0a090800ffffffffffff00000000000000000000"); private static final byte[] ipv6g = Hex.decode("872020010db885a3000000008a2e0a090800ffffffffffffffffffffffffffffffff"); private static final byte[] ipv6h = Hex.decode("872020010db885a300000000000000000000ffffffffffff00000000000000000000"); private static final byte[] ipv6i = Hex.decode("872020010db885a300000000000000000000fffffffffffe00000000000000000000"); private static final byte[] ipv6j = Hex.decode("872020010db885a300000000000000000000ffffffffffff80000000000000000000"); public String getName() { return "GeneralName"; } public void performTest() throws Exception { GeneralName nm = new GeneralName(GeneralName.iPAddress, "10.9.8.0"); if (!Arrays.areEqual(nm.getEncoded(), ipv4)) { fail("ipv4 encoding failed"); } nm = new GeneralName(GeneralName.iPAddress, "10.9.8.0/255.255.255.0"); if (!Arrays.areEqual(nm.getEncoded(), ipv4WithMask1)) { fail("ipv4 with netmask 1 encoding failed"); } nm = new GeneralName(GeneralName.iPAddress, "10.9.8.0/24"); if (!Arrays.areEqual(nm.getEncoded(), ipv4WithMask1)) { fail("ipv4 with netmask 2 encoding failed"); } nm = new GeneralName(GeneralName.iPAddress, "10.9.8.0/255.255.128.0"); if (!Arrays.areEqual(nm.getEncoded(), ipv4WithMask2)) { fail("ipv4 with netmask 3a encoding failed"); } nm = new GeneralName(GeneralName.iPAddress, "10.9.8.0/17"); if (!Arrays.areEqual(nm.getEncoded(), ipv4WithMask2)) { fail("ipv4 with netmask 3b encoding failed"); } nm = new GeneralName(GeneralName.iPAddress, "10.9.8.0/255.255.192.0"); if (!Arrays.areEqual(nm.getEncoded(), ipv4WithMask3)) { fail("ipv4 with netmask 3a encoding failed"); } nm = new GeneralName(GeneralName.iPAddress, "10.9.8.0/18"); if (!Arrays.areEqual(nm.getEncoded(), ipv4WithMask3)) { fail("ipv4 with netmask 3b encoding failed"); } nm = new GeneralName(GeneralName.iPAddress, "2001:0db8:85a3:08d3:1319:8a2e:0370:7334"); if (!Arrays.areEqual(nm.getEncoded(), ipv6a)) { fail("ipv6 with netmask encoding failed"); } nm = new GeneralName(GeneralName.iPAddress, "2001:0db8:85a3::1319:8a2e:0370:7334"); if (!Arrays.areEqual(nm.getEncoded(), ipv6b)) { fail("ipv6b encoding failed"); } nm = new GeneralName(GeneralName.iPAddress, "::1"); if (!Arrays.areEqual(nm.getEncoded(), ipv6c)) { fail("ipv6c failed"); } nm = new GeneralName(GeneralName.iPAddress, "2001:0db8:85a3::8a2e:0370:7334"); if (!Arrays.areEqual(nm.getEncoded(), ipv6d)) { fail("ipv6d failed"); } nm = new GeneralName(GeneralName.iPAddress, "2001:0db8:85a3::8a2e:10.9.8.0"); if (!Arrays.areEqual(nm.getEncoded(), ipv6e)) { fail("ipv6e failed"); } nm = new GeneralName(GeneralName.iPAddress, "2001:0db8:85a3::8a2e:10.9.8.0/ffff:ffff:ffff::0000"); if (!Arrays.areEqual(nm.getEncoded(), ipv6f)) { fail("ipv6f failed"); } nm = new GeneralName(GeneralName.iPAddress, "2001:0db8:85a3::8a2e:10.9.8.0/128"); if (!Arrays.areEqual(nm.getEncoded(), ipv6g)) { fail("ipv6g failed"); } nm = new GeneralName(GeneralName.iPAddress, "2001:0db8:85a3::/48"); if (!Arrays.areEqual(nm.getEncoded(), ipv6h)) { fail("ipv6h failed"); } nm = new GeneralName(GeneralName.iPAddress, "2001:0db8:85a3::/47"); if (!Arrays.areEqual(nm.getEncoded(), ipv6i)) { fail("ipv6i failed"); } nm = new GeneralName(GeneralName.iPAddress, "2001:0db8:85a3::/49"); if (!Arrays.areEqual(nm.getEncoded(), ipv6j)) { fail("ipv6j failed"); } } public static void main( String[] args) { runTest(new GeneralNameTest()); } } bouncycastle-1.49.orig/test/src/org/bouncycastle/asn1/test/EncryptedPrivateKeyInfoTest.java0000644000175000017500000001176311727731066031604 0ustar ebourgebourgpackage org.bouncycastle.asn1.test; import java.io.ByteArrayInputStream; import java.io.ByteArrayOutputStream; import org.bouncycastle.asn1.ASN1InputStream; import org.bouncycastle.asn1.ASN1Primitive; import org.bouncycastle.asn1.DEROutputStream; import org.bouncycastle.asn1.pkcs.EncryptedPrivateKeyInfo; import org.bouncycastle.asn1.util.ASN1Dump; import org.bouncycastle.util.encoders.Base64; import org.bouncycastle.util.test.SimpleTest; /** * Test the reading and writing of EncryptedPrivateKeyInfo objects using * the test vectors provided at * * RSA's PKCS5 Page. *
    * The vectors are Base 64 encoded and encrypted using the password "password" * (without quotes). They should all yield the same PrivateKeyInfo object. */ public class EncryptedPrivateKeyInfoTest extends SimpleTest { static byte[] sample1 = Base64.decode( "MIIBozA9BgkqhkiG9w0BBQ0wMDAbBgkqhkiG9w0BBQwwDgQIfWBDXwLp4K4CAggA" + "MBEGBSsOAwIHBAiaCF/AvOgQ6QSCAWDWX4BdAzCRNSQSANSuNsT5X8mWYO27mr3Y" + "9c9LoBVXGNmYWKA77MI4967f7SmjNcgXj3xNE/jmnVz6hhsjS8E5VPT3kfyVkpdZ" + "0lr5e9Yk2m3JWpPU7++v5zBkZmC4V/MwV/XuIs6U+vykgzMgpxQg0oZKS9zgmiZo" + "f/4dOCL0UtCDnyOSvqT7mCVIcMDIEKu8QbVlgZYBop08l60EuEU3gARUo8WsYQmO" + "Dz/ldx0Z+znIT0SXVuOwc+RVItC5T/Qx+aijmmpt+9l14nmaGBrEkmuhmtdvU/4v" + "aptewGRgmjOfD6cqK+zs0O5NrrJ3P/6ZSxXj91CQgrThGfOv72bUncXEMNtc8pks" + "2jpHFjGMdKufnadAD7XuMgzkkaklEXZ4f5tU6heIIwr51g0GBEGF96gYPFnjnSQM" + "75JE02Clo+DfcfXpcybPTwwFg2jd6JTTOfkdf6OdSlA/1XNK43FA"); static byte[] sample2 = Base64.decode( "MIIBpjBABgkqhkiG9w0BBQ0wMzAbBgkqhkiG9w0BBQwwDgQIeFeOWl1jywYCAggA" + "MBQGCCqGSIb3DQMHBAjUJ5eGBhQGtQSCAWBrHrRgqO8UUMLcWzZEtpk1l3mjxiF/" + "koCMkHsFwowgyWhEbgIkTgbSViK54LVK8PskekcGNLph+rB6bGZ7pPbL5pbXASJ8" + "+MkQcG3FZdlS4Ek9tTJDApj3O1UubZGFG4uvTlJJFbF1BOJ3MkY3XQ9Gl1qwv7j5" + "6e103Da7Cq9+oIDKmznza78XXQYrUsPo8mJGjUxPskEYlzwvHjKubRnYm/K6RKhi" + "5f4zX4BQ/Dt3H812ZjRXrsjAJP0KrD/jyD/jCT7zNBVPH1izBds+RwizyQAHwfNJ" + "BFR78TH4cgzB619X47FDVOnT0LqQNVd0O3cSwnPrXE9XR3tPayE+iOB15llFSmi8" + "z0ByOXldEpkezCn92Umk++suzIVj1qfsK+bv2phZWJPbLEIWPDRHUbYf76q5ArAr" + "u4xtxT/hoK3krEs/IN3d70qjlUJ36SEw1UaZ82PWhakQbdtu39ZraMJB"); static byte[] sample3 = Base64.decode( "MIIBrjBIBgkqhkiG9w0BBQ0wOzAeBgkqhkiG9w0BBQwwEQQIrHyQPBZqWLUCAggA" + "AgEQMBkGCCqGSIb3DQMCMA0CAToECEhbh7YZKiPSBIIBYCT1zp6o5jpFlIkgwPop" + "7bW1+8ACr4exqzkeb3WflQ8cWJ4cURxzVdvxUnXeW1VJdaQZtjS/QHs5GhPTG/0f" + "wtvnaPfwrIJ3FeGaZfcg2CrYhalOFmEb4xrE4KyoEQmUN8tb/Cg94uzd16BOPw21" + "RDnE8bnPdIGY7TyL95kbkqH23mK53pi7h+xWIgduW+atIqDyyt55f7WMZcvDvlj6" + "VpN/V0h+qxBHL274WA4dj6GYgeyUFpi60HdGCK7By2TBy8h1ZvKGjmB9h8jZvkx1" + "MkbRumXxyFsowTZawyYvO8Um6lbfEDP9zIEUq0IV8RqH2MRyblsPNSikyYhxX/cz" + "tdDxRKhilySbSBg5Kr8OfcwKp9bpinN96nmG4xr3Tch1bnVvqJzOQ5+Vva2WwVvH" + "2JkWvYm5WaANg4Q6bRxu9vz7DuhbJjQdZbxFezIAgrJdSe92B00jO/0Kny1WjiVO" + "6DA="); public String getName() { return "EncryptedPrivateKeyInfoTest"; } private void test( int id, byte[] sample) { ByteArrayInputStream bIn = new ByteArrayInputStream(sample); ASN1InputStream aIn = new ASN1InputStream(bIn); EncryptedPrivateKeyInfo info = null; try { info = EncryptedPrivateKeyInfo.getInstance(aIn.readObject()); } catch (Exception e) { fail("test " + id + " failed construction - exception " + e.toString(), e); } ByteArrayOutputStream bOut = new ByteArrayOutputStream(); DEROutputStream dOut = new DEROutputStream(bOut); try { dOut.writeObject(info); } catch (Exception e) { fail("test " + id + " failed writing - exception " + e.toString(), e); } byte[] bytes = bOut.toByteArray(); if (bytes.length != sample.length) { try { bIn = new ByteArrayInputStream(bytes); aIn = new ASN1InputStream(bIn); ASN1Primitive obj = aIn.readObject(); fail("test " + id + " length mismatch - expected " + sample.length + System.getProperty("line.separator") + ASN1Dump.dumpAsString(info) + " got " + bytes.length + System.getProperty("line.separator") + ASN1Dump.dumpAsString(obj)); } catch (Exception e) { fail("test " + id + " length mismatch - exception " + e.toString()); } } for (int i = 0; i != bytes.length; i++) { if (bytes[i] != sample[i]) { fail("test " + id + " data mismatch"); } } } public void performTest() { test(0, sample1); test(1, sample2); test(2, sample3); } public static void main( String[] args) { runTest(new EncryptedPrivateKeyInfoTest()); } } bouncycastle-1.49.orig/test/src/org/bouncycastle/asn1/test/OtherCertIDUnitTest.java0000644000175000017500000000534311724302253027765 0ustar ebourgebourgpackage org.bouncycastle.asn1.test; import java.io.IOException; import org.bouncycastle.asn1.ASN1InputStream; import org.bouncycastle.asn1.ASN1Integer; import org.bouncycastle.asn1.ASN1Sequence; import org.bouncycastle.asn1.DERObjectIdentifier; import org.bouncycastle.asn1.ess.OtherCertID; import org.bouncycastle.asn1.x509.AlgorithmIdentifier; import org.bouncycastle.asn1.x509.GeneralName; import org.bouncycastle.asn1.x509.GeneralNames; import org.bouncycastle.asn1.x509.IssuerSerial; import org.bouncycastle.asn1.x509.X509Name; public class OtherCertIDUnitTest extends ASN1UnitTest { public String getName() { return "OtherCertID"; } public void performTest() throws Exception { AlgorithmIdentifier algId = new AlgorithmIdentifier(new DERObjectIdentifier("1.2.2.3")); byte[] digest = new byte[20]; IssuerSerial issuerSerial = new IssuerSerial(new GeneralNames(new GeneralName(new X509Name("CN=test"))), new ASN1Integer(1)); OtherCertID certID = new OtherCertID(algId, digest); checkConstruction(certID, algId, digest, null); certID = new OtherCertID(algId, digest, issuerSerial); checkConstruction(certID, algId, digest, issuerSerial); certID = OtherCertID.getInstance(null); if (certID != null) { fail("null getInstance() failed."); } try { OtherCertID.getInstance(new Object()); fail("getInstance() failed to detect bad object."); } catch (IllegalArgumentException e) { // expected } } private void checkConstruction( OtherCertID certID, AlgorithmIdentifier algId, byte[] digest, IssuerSerial issuerSerial) throws IOException { checkValues(certID, algId, digest, issuerSerial); certID = OtherCertID.getInstance(certID); checkValues(certID, algId, digest, issuerSerial); ASN1InputStream aIn = new ASN1InputStream(certID.toASN1Object().getEncoded()); ASN1Sequence seq = (ASN1Sequence)aIn.readObject(); certID = OtherCertID.getInstance(seq); checkValues(certID, algId, digest, issuerSerial); } private void checkValues( OtherCertID certID, AlgorithmIdentifier algId, byte[] digest, IssuerSerial issuerSerial) { checkMandatoryField("algorithmHash", algId, certID.getAlgorithmHash()); checkMandatoryField("certHash", digest, certID.getCertHash()); checkOptionalField("issuerSerial", issuerSerial, certID.getIssuerSerial()); } public static void main( String[] args) { runTest(new OtherCertIDUnitTest()); } } bouncycastle-1.49.orig/test/src/org/bouncycastle/asn1/test/PersonalDataUnitTest.java0000644000175000017500000001077711737275254030253 0ustar ebourgebourgpackage org.bouncycastle.asn1.test; import java.io.IOException; import java.math.BigInteger; import org.bouncycastle.asn1.ASN1GeneralizedTime; import org.bouncycastle.asn1.ASN1InputStream; import org.bouncycastle.asn1.ASN1Sequence; import org.bouncycastle.asn1.DERGeneralizedTime; import org.bouncycastle.asn1.x500.DirectoryString; import org.bouncycastle.asn1.x509.sigi.NameOrPseudonym; import org.bouncycastle.asn1.x509.sigi.PersonalData; public class PersonalDataUnitTest extends ASN1UnitTest { public String getName() { return "PersonalData"; } public void performTest() throws Exception { NameOrPseudonym nameOrPseudonym = new NameOrPseudonym("pseudonym"); BigInteger nameDistinguisher = BigInteger.valueOf(10); ASN1GeneralizedTime dateOfBirth= new ASN1GeneralizedTime("20070315173729Z"); DirectoryString placeOfBirth = new DirectoryString("placeOfBirth"); String gender = "M"; DirectoryString postalAddress = new DirectoryString("address"); PersonalData data = new PersonalData(nameOrPseudonym, nameDistinguisher, dateOfBirth, placeOfBirth, gender, postalAddress); checkConstruction(data, nameOrPseudonym, nameDistinguisher, dateOfBirth, placeOfBirth, gender, postalAddress); data = new PersonalData(nameOrPseudonym, null, dateOfBirth, placeOfBirth, gender, postalAddress); checkConstruction(data, nameOrPseudonym, null, dateOfBirth, placeOfBirth, gender, postalAddress); data = new PersonalData(nameOrPseudonym, nameDistinguisher, null, placeOfBirth, gender, postalAddress); checkConstruction(data, nameOrPseudonym, nameDistinguisher, null, placeOfBirth, gender, postalAddress); data = new PersonalData(nameOrPseudonym, nameDistinguisher, dateOfBirth, null, gender, postalAddress); checkConstruction(data, nameOrPseudonym, nameDistinguisher, dateOfBirth, null, gender, postalAddress); data = new PersonalData(nameOrPseudonym, nameDistinguisher, dateOfBirth, placeOfBirth, null, postalAddress); checkConstruction(data, nameOrPseudonym, nameDistinguisher, dateOfBirth, placeOfBirth, null, postalAddress); data = new PersonalData(nameOrPseudonym, nameDistinguisher, dateOfBirth, placeOfBirth, gender, null); checkConstruction(data, nameOrPseudonym, nameDistinguisher, dateOfBirth, placeOfBirth, gender, null); data = PersonalData.getInstance(null); if (data != null) { fail("null getInstance() failed."); } try { PersonalData.getInstance(new Object()); fail("getInstance() failed to detect bad object."); } catch (IllegalArgumentException e) { // expected } } private void checkConstruction( PersonalData data, NameOrPseudonym nameOrPseudonym, BigInteger nameDistinguisher, DERGeneralizedTime dateOfBirth, DirectoryString placeOfBirth, String gender, DirectoryString postalAddress) throws IOException { checkValues(data, nameOrPseudonym, nameDistinguisher, dateOfBirth, placeOfBirth, gender, postalAddress); data = PersonalData.getInstance(data); checkValues(data, nameOrPseudonym, nameDistinguisher, dateOfBirth, placeOfBirth, gender, postalAddress); ASN1InputStream aIn = new ASN1InputStream(data.toASN1Object().getEncoded()); ASN1Sequence seq = (ASN1Sequence)aIn.readObject(); data = PersonalData.getInstance(seq); checkValues(data, nameOrPseudonym, nameDistinguisher, dateOfBirth, placeOfBirth, gender, postalAddress); } private void checkValues( PersonalData data, NameOrPseudonym nameOrPseudonym, BigInteger nameDistinguisher, DERGeneralizedTime dateOfBirth, DirectoryString placeOfBirth, String gender, DirectoryString postalAddress) { checkMandatoryField("nameOrPseudonym", nameOrPseudonym, data.getNameOrPseudonym()); checkOptionalField("nameDistinguisher", nameDistinguisher, data.getNameDistinguisher()); checkOptionalField("dateOfBirth", dateOfBirth, data.getDateOfBirth()); checkOptionalField("placeOfBirth", placeOfBirth, data.getPlaceOfBirth()); checkOptionalField("gender", gender, data.getGender()); checkOptionalField("postalAddress", postalAddress, data.getPostalAddress()); } public static void main( String[] args) { runTest(new PersonalDataUnitTest()); } } bouncycastle-1.49.orig/test/src/org/bouncycastle/asn1/test/X509NameTest.java0000644000175000017500000005305612132660053026262 0ustar ebourgebourgpackage org.bouncycastle.asn1.test; import java.io.ByteArrayInputStream; import java.io.ByteArrayOutputStream; import java.io.IOException; import java.util.Hashtable; import java.util.Vector; import org.bouncycastle.asn1.ASN1Encodable; import org.bouncycastle.asn1.ASN1EncodableVector; import org.bouncycastle.asn1.ASN1InputStream; import org.bouncycastle.asn1.ASN1ObjectIdentifier; import org.bouncycastle.asn1.ASN1OutputStream; import org.bouncycastle.asn1.ASN1Primitive; import org.bouncycastle.asn1.ASN1Sequence; import org.bouncycastle.asn1.ASN1Set; import org.bouncycastle.asn1.DERGeneralizedTime; import org.bouncycastle.asn1.DERIA5String; import org.bouncycastle.asn1.DERObjectIdentifier; import org.bouncycastle.asn1.DERPrintableString; import org.bouncycastle.asn1.DERSequence; import org.bouncycastle.asn1.DERSet; import org.bouncycastle.asn1.DERUTF8String; import org.bouncycastle.asn1.x500.X500Name; import org.bouncycastle.asn1.x500.X500NameBuilder; import org.bouncycastle.asn1.x500.style.BCStyle; import org.bouncycastle.asn1.x509.X509DefaultEntryConverter; import org.bouncycastle.asn1.x509.X509Name; import org.bouncycastle.util.Arrays; import org.bouncycastle.util.encoders.Hex; import org.bouncycastle.util.test.SimpleTest; public class X509NameTest extends SimpleTest { String[] subjects = { "C=AU,ST=Victoria,L=South Melbourne,O=Connect 4 Pty Ltd,OU=Webserver Team,CN=www2.connect4.com.au,E=webmaster@connect4.com.au", "C=AU,ST=Victoria,L=South Melbourne,O=Connect 4 Pty Ltd,OU=Certificate Authority,CN=Connect 4 CA,E=webmaster@connect4.com.au", "C=AU,ST=QLD,CN=SSLeay/rsa test cert", "C=US,O=National Aeronautics and Space Administration,SERIALNUMBER=16+CN=Steve Schoch", "E=cooke@issl.atl.hp.com,C=US,OU=Hewlett Packard Company (ISSL),CN=Paul A. Cooke", "O=Sun Microsystems Inc,CN=store.sun.com", "unstructuredAddress=192.168.1.33,unstructuredName=pixfirewall.ciscopix.com,CN=pixfirewall.ciscopix.com", "CN=*.canal-plus.com,OU=Provided by TBS INTERNET http://www.tbs-certificats.com/,OU=\\ CANAL \\+,O=CANAL\\+DISTRIBUTION,L=issy les moulineaux,ST=Hauts de Seine,C=FR", "O=Bouncy Castle,CN=www.bouncycastle.org\\ ", "O=Bouncy Castle,CN=c:\\\\fred\\\\bob" }; public String getName() { return "X509Name"; } private static X509Name fromBytes( byte[] bytes) throws IOException { return X509Name.getInstance(new ASN1InputStream(new ByteArrayInputStream(bytes)).readObject()); } private ASN1Encodable createEntryValue(DERObjectIdentifier oid, String value) { Hashtable attrs = new Hashtable(); attrs.put(oid, value); Vector order = new Vector(); order.addElement(oid); X509Name name = new X509Name(order, attrs); ASN1Sequence seq = (ASN1Sequence)name.toASN1Primitive(); ASN1Set set = (ASN1Set)seq.getObjectAt(0); seq = (ASN1Sequence)set.getObjectAt(0); return seq.getObjectAt(1); } private ASN1Encodable createEntryValueFromString(DERObjectIdentifier oid, String value) { Hashtable attrs = new Hashtable(); attrs.put(oid, value); Vector order = new Vector(); order.addElement(oid); X509Name name = new X509Name(new X509Name(order, attrs).toString()); ASN1Sequence seq = (ASN1Sequence)name.toASN1Primitive(); ASN1Set set = (ASN1Set)seq.getObjectAt(0); seq = (ASN1Sequence)set.getObjectAt(0); return seq.getObjectAt(1); } private void testEncodingPrintableString(DERObjectIdentifier oid, String value) { ASN1Encodable converted = createEntryValue(oid, value); if (!(converted instanceof DERPrintableString)) { fail("encoding for " + oid + " not printable string"); } } private void testEncodingIA5String(DERObjectIdentifier oid, String value) { ASN1Encodable converted = createEntryValue(oid, value); if (!(converted instanceof DERIA5String)) { fail("encoding for " + oid + " not IA5String"); } } private void testEncodingUTF8String(DERObjectIdentifier oid, String value) throws IOException { ASN1Encodable converted = createEntryValue(oid, value); if (!(converted instanceof DERUTF8String)) { fail("encoding for " + oid + " not IA5String"); } if (!value.equals((DERUTF8String.getInstance(converted.toASN1Primitive().getEncoded()).getString()))) { fail("decoding not correct"); } } private void testEncodingGeneralizedTime(DERObjectIdentifier oid, String value) { ASN1Encodable converted = createEntryValue(oid, value); if (!(converted instanceof DERGeneralizedTime)) { fail("encoding for " + oid + " not GeneralizedTime"); } converted = createEntryValueFromString(oid, value); if (!(converted instanceof DERGeneralizedTime)) { fail("encoding for " + oid + " not GeneralizedTime"); } } public void performTest() throws Exception { testEncodingPrintableString(X509Name.C, "AU"); testEncodingPrintableString(X509Name.SERIALNUMBER, "123456"); testEncodingPrintableString(X509Name.DN_QUALIFIER, "123456"); testEncodingIA5String(X509Name.EmailAddress, "test@test.com"); testEncodingIA5String(X509Name.DC, "test"); // correct encoding testEncodingGeneralizedTime(X509Name.DATE_OF_BIRTH, "#180F32303032303132323132323232305A"); // compatibility encoding testEncodingGeneralizedTime(X509Name.DATE_OF_BIRTH, "20020122122220Z"); testEncodingUTF8String(X509Name.CN, "Mörsky"); // // composite // Hashtable attrs = new Hashtable(); attrs.put(X509Name.C, "AU"); attrs.put(X509Name.O, "The Legion of the Bouncy Castle"); attrs.put(X509Name.L, "Melbourne"); attrs.put(X509Name.ST, "Victoria"); attrs.put(X509Name.E, "feedback-crypto@bouncycastle.org"); Vector order = new Vector(); order.addElement(X509Name.C); order.addElement(X509Name.O); order.addElement(X509Name.L); order.addElement(X509Name.ST); order.addElement(X509Name.E); X509Name name1 = new X509Name(order, attrs); if (!name1.equals(name1)) { fail("Failed same object test"); } if (!name1.equals(name1, true)) { fail("Failed same object test - in Order"); } X509Name name2 = new X509Name(order, attrs); if (!name1.equals(name2)) { fail("Failed same name test"); } if (!name1.equals(name2, true)) { fail("Failed same name test - in Order"); } if (name1.hashCode() != name2.hashCode()) { fail("Failed same name test - in Order"); } Vector ord1 = new Vector(); ord1.addElement(X509Name.C); ord1.addElement(X509Name.O); ord1.addElement(X509Name.L); ord1.addElement(X509Name.ST); ord1.addElement(X509Name.E); Vector ord2 = new Vector(); ord2.addElement(X509Name.E); ord2.addElement(X509Name.ST); ord2.addElement(X509Name.L); ord2.addElement(X509Name.O); ord2.addElement(X509Name.C); name1 = new X509Name(ord1, attrs); name2 = new X509Name(ord2, attrs); if (!name1.equals(name2)) { fail("Failed reverse name test"); } if (name1.hashCode() != name2.hashCode()) { fail("Failed reverse name test hashCode"); } if (name1.equals(name2, true)) { fail("Failed reverse name test - in Order"); } if (!name1.equals(name2, false)) { fail("Failed reverse name test - in Order false"); } Vector oids = name1.getOIDs(); if (!compareVectors(oids, ord1)) { fail("oid comparison test"); } Vector val1 = new Vector(); val1.addElement("AU"); val1.addElement("The Legion of the Bouncy Castle"); val1.addElement("Melbourne"); val1.addElement("Victoria"); val1.addElement("feedback-crypto@bouncycastle.org"); name1 = new X509Name(ord1, val1); Vector values = name1.getValues(); if (!compareVectors(values, val1)) { fail("value comparison test"); } ord2 = new Vector(); ord2.addElement(X509Name.ST); ord2.addElement(X509Name.ST); ord2.addElement(X509Name.L); ord2.addElement(X509Name.O); ord2.addElement(X509Name.C); name1 = new X509Name(ord1, attrs); name2 = new X509Name(ord2, attrs); if (name1.equals(name2)) { fail("Failed different name test"); } ord2 = new Vector(); ord2.addElement(X509Name.ST); ord2.addElement(X509Name.L); ord2.addElement(X509Name.O); ord2.addElement(X509Name.C); name1 = new X509Name(ord1, attrs); name2 = new X509Name(ord2, attrs); if (name1.equals(name2)) { fail("Failed subset name test"); } compositeTest(); ByteArrayOutputStream bOut; ASN1OutputStream aOut; ASN1InputStream aIn; // // getValues test // Vector v1 = name1.getValues(X509Name.O); if (v1.size() != 1 || !v1.elementAt(0).equals("The Legion of the Bouncy Castle")) { fail("O test failed"); } Vector v2 = name1.getValues(X509Name.L); if (v2.size() != 1 || !v2.elementAt(0).equals("Melbourne")) { fail("L test failed"); } // // general subjects test // for (int i = 0; i != subjects.length; i++) { X509Name name = new X509Name(subjects[i]); bOut = new ByteArrayOutputStream(); aOut = new ASN1OutputStream(bOut); aOut.writeObject(name); aIn = new ASN1InputStream(new ByteArrayInputStream(bOut.toByteArray())); name = X509Name.getInstance(aIn.readObject()); if (!name.toString().equals(subjects[i])) { fail("failed regeneration test " + i + " got " + name.toString()); } } // // sort test // X509Name unsorted = new X509Name("SERIALNUMBER=BBB + CN=AA"); if (!fromBytes(unsorted.getEncoded()).toString().equals("CN=AA+SERIALNUMBER=BBB")) { fail("failed sort test 1"); } unsorted = new X509Name("CN=AA + SERIALNUMBER=BBB"); if (!fromBytes(unsorted.getEncoded()).toString().equals("CN=AA+SERIALNUMBER=BBB")) { fail("failed sort test 2"); } unsorted = new X509Name("SERIALNUMBER=B + CN=AA"); if (!fromBytes(unsorted.getEncoded()).toString().equals("SERIALNUMBER=B+CN=AA")) { fail("failed sort test 3"); } unsorted = new X509Name("CN=AA + SERIALNUMBER=B"); if (!fromBytes(unsorted.getEncoded()).toString().equals("SERIALNUMBER=B+CN=AA")) { fail("failed sort test 4"); } // // equality tests // equalityTest(new X509Name("CN=The Legion"), new X509Name("CN=The Legion")); equalityTest(new X509Name("CN= The Legion"), new X509Name("CN=The Legion")); equalityTest(new X509Name("CN=The Legion "), new X509Name("CN=The Legion")); equalityTest(new X509Name("CN= The Legion "), new X509Name("CN=The Legion")); equalityTest(new X509Name("CN= the legion "), new X509Name("CN=The Legion")); // # test X509Name n1 = new X509Name("SERIALNUMBER=8,O=ABC,CN=ABC Class 3 CA,C=LT"); X509Name n2 = new X509Name("2.5.4.5=8,O=ABC,CN=ABC Class 3 CA,C=LT"); X509Name n3 = new X509Name("2.5.4.5=#130138,O=ABC,CN=ABC Class 3 CA,C=LT"); equalityTest(n1, n2); equalityTest(n2, n3); equalityTest(n3, n1); n1 = new X509Name(true, "2.5.4.5=#130138,CN=SSC Class 3 CA,O=UAB Skaitmeninio sertifikavimo centras,C=LT"); n2 = new X509Name(true, "SERIALNUMBER=#130138,CN=SSC Class 3 CA,O=UAB Skaitmeninio sertifikavimo centras,C=LT"); n3 = X509Name.getInstance(ASN1Primitive.fromByteArray(Hex.decode("3063310b3009060355040613024c54312f302d060355040a1326" + "55414220536b6169746d656e696e696f20736572746966696b6176696d6f2063656e74726173311730150603550403130e53534320436c6173732033204341310a30080603550405130138"))); equalityTest(n1, n2); equalityTest(n2, n3); equalityTest(n3, n1); n1 = new X509Name("SERIALNUMBER=8,O=XX,CN=ABC Class 3 CA,C=LT"); n2 = new X509Name("2.5.4.5=8,O=,CN=ABC Class 3 CA,C=LT"); if (n1.equals(n2)) { fail("empty inequality check failed"); } n1 = new X509Name("SERIALNUMBER=8,O=,CN=ABC Class 3 CA,C=LT"); n2 = new X509Name("2.5.4.5=8,O=,CN=ABC Class 3 CA,C=LT"); equalityTest(n1, n2); // // inequality to sequences // name1 = new X509Name("CN=The Legion"); if (name1.equals(new DERSequence())) { fail("inequality test with sequence"); } if (name1.equals(new DERSequence(new DERSet()))) { fail("inequality test with sequence and set"); } ASN1EncodableVector v = new ASN1EncodableVector(); v.add(new DERObjectIdentifier("1.1")); v.add(new DERObjectIdentifier("1.1")); if (name1.equals(new DERSequence(new DERSet(new DERSet(v))))) { fail("inequality test with sequence and bad set"); } if (name1.equals(new DERSequence(new DERSet(new DERSet(v))), true)) { fail("inequality test with sequence and bad set"); } if (name1.equals(new DERSequence(new DERSet(new DERSequence())))) { fail("inequality test with sequence and short sequence"); } if (name1.equals(new DERSequence(new DERSet(new DERSequence())), true)) { fail("inequality test with sequence and short sequence"); } v = new ASN1EncodableVector(); v.add(new DERObjectIdentifier("1.1")); v.add(new DERSequence()); if (name1.equals(new DERSequence(new DERSet(new DERSequence(v))))) { fail("inequality test with sequence and bad sequence"); } if (name1.equals(null)) { fail("inequality test with null"); } if (name1.equals(null, true)) { fail("inequality test with null"); } // // this is contrived but it checks sorting of sets with equal elements // unsorted = new X509Name("CN=AA + CN=AA + CN=AA"); // // tagging test - only works if CHOICE implemented // /* ASN1TaggedObject tag = new DERTaggedObject(false, 1, new X509Name("CN=AA")); if (!tag.isExplicit()) { fail("failed to explicitly tag CHOICE object"); } X509Name name = X509Name.getInstance(tag, false); if (!name.equals(new X509Name("CN=AA"))) { fail("failed to recover tagged name"); } */ DERUTF8String testString = new DERUTF8String("The Legion of the Bouncy Castle"); byte[] encodedBytes = testString.getEncoded(); byte[] hexEncodedBytes = Hex.encode(encodedBytes); String hexEncodedString = "#" + new String(hexEncodedBytes); DERUTF8String converted = (DERUTF8String) new X509DefaultEntryConverter().getConvertedValue( X509Name.L , hexEncodedString); if (!converted.equals(testString)) { fail("failed X509DefaultEntryConverter test"); } // // try escaped. // converted = (DERUTF8String) new X509DefaultEntryConverter().getConvertedValue( X509Name.L , "\\" + hexEncodedString); if (!converted.equals(new DERUTF8String(hexEncodedString))) { fail("failed X509DefaultEntryConverter test got " + converted + " expected: " + hexEncodedString); } // // try a weird value // X509Name n = new X509Name("CN=\\#nothex#string"); if (!n.toString().equals("CN=\\#nothex#string")) { fail("# string not properly escaped."); } Vector vls = n.getValues(X509Name.CN); if (vls.size() != 1 || !vls.elementAt(0).equals("#nothex#string")) { fail("escaped # not reduced properly"); } n = new X509Name("CN=\"a+b\""); vls = n.getValues(X509Name.CN); if (vls.size() != 1 || !vls.elementAt(0).equals("a+b")) { fail("escaped + not reduced properly"); } n = new X509Name("CN=a\\+b"); vls = n.getValues(X509Name.CN); if (vls.size() != 1 || !vls.elementAt(0).equals("a+b")) { fail("escaped + not reduced properly"); } if (!n.toString().equals("CN=a\\+b")) { fail("+ in string not properly escaped."); } n = new X509Name("CN=a\\=b"); vls = n.getValues(X509Name.CN); if (vls.size() != 1 || !vls.elementAt(0).equals("a=b")) { fail("escaped = not reduced properly"); } if (!n.toString().equals("CN=a\\=b")) { fail("= in string not properly escaped."); } n = new X509Name("TELEPHONENUMBER=\"+61999999999\""); vls = n.getValues(X509Name.TELEPHONE_NUMBER); if (vls.size() != 1 || !vls.elementAt(0).equals("+61999999999")) { fail("telephonenumber escaped + not reduced properly"); } n = new X509Name("TELEPHONENUMBER=\\+61999999999"); vls = n.getValues(X509Name.TELEPHONE_NUMBER); if (vls.size() != 1 || !vls.elementAt(0).equals("+61999999999")) { fail("telephonenumber escaped + not reduced properly"); } // migration X500NameBuilder builder = new X500NameBuilder(BCStyle.INSTANCE); builder.addMultiValuedRDN(new ASN1ObjectIdentifier[] { BCStyle.CN, BCStyle.SN }, new String[] { "Thomas", "CVR:12341233-UID:1111" }); builder.addRDN(BCStyle.O, "Test"); builder.addRDN(BCStyle.C, "DK"); X500Name subject = builder.build(); ASN1Primitive derObject = subject.toASN1Primitive(); X509Name instance = X509Name.getInstance(derObject); } private boolean compareVectors(Vector a, Vector b) // for compatibility with early JDKs { if (a.size() != b.size()) { return false; } for (int i = 0; i != a.size(); i++) { if (!a.elementAt(i).equals(b.elementAt(i))) { return false; } } return true; } private void compositeTest() throws IOException { // // composite test // byte[] enc = Hex.decode("305e310b300906035504061302415531283026060355040a0c1f546865204c6567696f6e206f662074686520426f756e637920436173746c653125301006035504070c094d656c626f75726e653011060355040b0c0a4173636f742056616c65"); ASN1InputStream aIn = new ASN1InputStream(new ByteArrayInputStream(enc)); X509Name n = X509Name.getInstance(aIn.readObject()); if (!n.toString().equals("C=AU,O=The Legion of the Bouncy Castle,L=Melbourne+OU=Ascot Vale")) { fail("Failed composite to string test got: " + n.toString()); } if (!n.toString(true, X509Name.DefaultSymbols).equals("L=Melbourne+OU=Ascot Vale,O=The Legion of the Bouncy Castle,C=AU")) { fail("Failed composite to string test got: " + n.toString(true, X509Name.DefaultSymbols)); } n = new X509Name(true, "L=Melbourne+OU=Ascot Vale,O=The Legion of the Bouncy Castle,C=AU"); if (!n.toString().equals("C=AU,O=The Legion of the Bouncy Castle,L=Melbourne+OU=Ascot Vale")) { fail("Failed composite to string reversal test got: " + n.toString()); } n = new X509Name("C=AU, O=The Legion of the Bouncy Castle, L=Melbourne + OU=Ascot Vale"); ByteArrayOutputStream bOut = new ByteArrayOutputStream(); ASN1OutputStream aOut = new ASN1OutputStream(bOut); aOut.writeObject(n); byte[] enc2 = bOut.toByteArray(); if (!Arrays.areEqual(enc, enc2)) { //fail("Failed composite string to encoding test"); } // // dud name test - handle empty DN without barfing. // n = new X509Name("C=CH,O=,OU=dummy,CN=mail@dummy.com"); n = X509Name.getInstance(ASN1Primitive.fromByteArray(n.getEncoded())); } private void equalityTest(X509Name x509Name, X509Name x509Name1) { if (!x509Name.equals(x509Name1)) { fail("equality test failed for " + x509Name + " : " + x509Name1); } if (x509Name.hashCode() != x509Name1.hashCode()) { fail("hashCodeTest test failed for " + x509Name + " : " + x509Name1); } if (!x509Name.equals(x509Name1, true)) { fail("equality test failed for " + x509Name + " : " + x509Name1); } } public static void main( String[] args) { runTest(new X509NameTest()); } } bouncycastle-1.49.orig/test/src/org/bouncycastle/asn1/test/X509ExtensionsTest.java0000644000175000017500000000506411625355151027543 0ustar ebourgebourgpackage org.bouncycastle.asn1.test; import org.bouncycastle.asn1.ASN1ObjectIdentifier; import org.bouncycastle.asn1.x509.X509Extensions; import org.bouncycastle.asn1.x509.X509ExtensionsGenerator; import org.bouncycastle.util.test.SimpleTest; public class X509ExtensionsTest extends SimpleTest { private static final ASN1ObjectIdentifier OID_2 = new ASN1ObjectIdentifier("1.2.2"); private static final ASN1ObjectIdentifier OID_3 = new ASN1ObjectIdentifier("1.2.3"); private static final ASN1ObjectIdentifier OID_1 = new ASN1ObjectIdentifier("1.2.1"); public String getName() { return "X509Extensions"; } public void performTest() throws Exception { X509ExtensionsGenerator gen = new X509ExtensionsGenerator(); gen.addExtension(OID_1, true, new byte[20]); gen.addExtension(OID_2, true, new byte[20]); X509Extensions ext1 = gen.generate(); X509Extensions ext2 = gen.generate(); if (!ext1.equals(ext2)) { fail("equals test failed"); } gen.reset(); gen.addExtension(OID_2, true, new byte[20]); gen.addExtension(OID_1, true, new byte[20]); ext2 = gen.generate(); if (ext1.equals(ext2)) { fail("inequality test failed"); } if (!ext1.equivalent(ext2)) { fail("equivalence true failed"); } gen.reset(); gen.addExtension(OID_1, true, new byte[22]); gen.addExtension(OID_2, true, new byte[20]); ext2 = gen.generate(); if (ext1.equals(ext2)) { fail("inequality 1 failed"); } if (ext1.equivalent(ext2)) { fail("non-equivalence 1 failed"); } gen.reset(); gen.addExtension(OID_3, true, new byte[20]); gen.addExtension(OID_2, true, new byte[20]); ext2 = gen.generate(); if (ext1.equals(ext2)) { fail("inequality 2 failed"); } if (ext1.equivalent(ext2)) { fail("non-equivalence 2 failed"); } try { gen.addExtension(OID_2, true, new byte[20]); fail("repeated oid"); } catch (IllegalArgumentException e) { if (!e.getMessage().equals("extension 1.2.2 already added")) { fail("wrong exception on repeated oid: " + e.getMessage()); } } } public static void main( String[] args) { runTest(new X509ExtensionsTest()); } } bouncycastle-1.49.orig/test/src/org/bouncycastle/asn1/test/QCStatementUnitTest.java0000644000175000017500000000567611706151751030057 0ustar ebourgebourgpackage org.bouncycastle.asn1.test; import java.io.IOException; import org.bouncycastle.asn1.ASN1Encodable; import org.bouncycastle.asn1.ASN1InputStream; import org.bouncycastle.asn1.ASN1ObjectIdentifier; import org.bouncycastle.asn1.ASN1Sequence; import org.bouncycastle.asn1.DERObjectIdentifier; import org.bouncycastle.asn1.x509.qualified.QCStatement; import org.bouncycastle.asn1.x509.qualified.RFC3739QCObjectIdentifiers; import org.bouncycastle.asn1.x509.qualified.SemanticsInformation; import org.bouncycastle.util.test.SimpleTest; public class QCStatementUnitTest extends SimpleTest { public String getName() { return "QCStatement"; } public void performTest() throws Exception { QCStatement mv = new QCStatement(RFC3739QCObjectIdentifiers.id_qcs_pkixQCSyntax_v1); checkConstruction(mv, RFC3739QCObjectIdentifiers.id_qcs_pkixQCSyntax_v1, null); ASN1Encodable info = new SemanticsInformation(new ASN1ObjectIdentifier("1.2")); mv = new QCStatement(RFC3739QCObjectIdentifiers.id_qcs_pkixQCSyntax_v1, info); checkConstruction(mv, RFC3739QCObjectIdentifiers.id_qcs_pkixQCSyntax_v1, info); mv = QCStatement.getInstance(null); if (mv != null) { fail("null getInstance() failed."); } try { QCStatement.getInstance(new Object()); fail("getInstance() failed to detect bad object."); } catch (IllegalArgumentException e) { // expected } } private void checkConstruction( QCStatement mv, DERObjectIdentifier statementId, ASN1Encodable statementInfo) throws IOException { checkStatement(mv, statementId, statementInfo); mv = QCStatement.getInstance(mv); checkStatement(mv, statementId, statementInfo); ASN1InputStream aIn = new ASN1InputStream(mv.toASN1Object().getEncoded()); ASN1Sequence seq = (ASN1Sequence)aIn.readObject(); mv = QCStatement.getInstance(seq); checkStatement(mv, statementId, statementInfo); } private void checkStatement( QCStatement qcs, DERObjectIdentifier statementId, ASN1Encodable statementInfo) throws IOException { if (!qcs.getStatementId().equals(statementId)) { fail("statementIds don't match."); } if (statementInfo != null) { if (!qcs.getStatementInfo().equals(statementInfo)) { fail("statementInfos don't match."); } } else if (qcs.getStatementInfo() != null) { fail("statementInfo found when none expected."); } } public static void main( String[] args) { runTest(new QCStatementUnitTest()); } } bouncycastle-1.49.orig/test/src/org/bouncycastle/asn1/test/EqualsAndHashCodeTest.java0000644000175000017500000001140711625105460030264 0ustar ebourgebourgpackage org.bouncycastle.asn1.test; import java.io.ByteArrayInputStream; import java.io.ByteArrayOutputStream; import java.util.Date; import org.bouncycastle.asn1.ASN1InputStream; import org.bouncycastle.asn1.ASN1OutputStream; import org.bouncycastle.asn1.ASN1Primitive; import org.bouncycastle.asn1.BERConstructedOctetString; import org.bouncycastle.asn1.BERSequence; import org.bouncycastle.asn1.BERSet; import org.bouncycastle.asn1.BERTaggedObject; import org.bouncycastle.asn1.DERApplicationSpecific; import org.bouncycastle.asn1.DERBMPString; import org.bouncycastle.asn1.DERBitString; import org.bouncycastle.asn1.DERBoolean; import org.bouncycastle.asn1.DEREnumerated; import org.bouncycastle.asn1.DERGeneralString; import org.bouncycastle.asn1.DERGeneralizedTime; import org.bouncycastle.asn1.DERIA5String; import org.bouncycastle.asn1.DERInteger; import org.bouncycastle.asn1.DERNull; import org.bouncycastle.asn1.DERNumericString; import org.bouncycastle.asn1.DERObjectIdentifier; import org.bouncycastle.asn1.DEROctetString; import org.bouncycastle.asn1.DERPrintableString; import org.bouncycastle.asn1.DERSequence; import org.bouncycastle.asn1.DERSet; import org.bouncycastle.asn1.DERT61String; import org.bouncycastle.asn1.DERTaggedObject; import org.bouncycastle.asn1.DERUTCTime; import org.bouncycastle.asn1.DERUTF8String; import org.bouncycastle.asn1.DERUniversalString; import org.bouncycastle.asn1.DERVisibleString; import org.bouncycastle.util.test.SimpleTestResult; import org.bouncycastle.util.test.Test; import org.bouncycastle.util.test.TestResult; public class EqualsAndHashCodeTest implements Test { public TestResult perform() { byte[] data = { 0, 1, 0, 1, 0, 0, 1 }; ASN1Primitive values[] = { new BERConstructedOctetString(data), new BERSequence(new DERPrintableString("hello world")), new BERSet(new DERPrintableString("hello world")), new BERTaggedObject(0, new DERPrintableString("hello world")), new DERApplicationSpecific(0, data), new DERBitString(data), new DERBMPString("hello world"), new DERBoolean(true), new DERBoolean(false), new DEREnumerated(100), new DERGeneralizedTime("20070315173729Z"), new DERGeneralString("hello world"), new DERIA5String("hello"), new DERInteger(1000), new DERNull(), new DERNumericString("123456"), new DERObjectIdentifier("1.1.1.10000.1"), new DEROctetString(data), new DERPrintableString("hello world"), new DERSequence(new DERPrintableString("hello world")), new DERSet(new DERPrintableString("hello world")), new DERT61String("hello world"), new DERTaggedObject(0, new DERPrintableString("hello world")), new DERUniversalString(data), new DERUTCTime(new Date()), new DERUTF8String("hello world"), new DERVisibleString("hello world") }; try { ByteArrayOutputStream bOut = new ByteArrayOutputStream(); ASN1OutputStream aOut = new ASN1OutputStream(bOut); for (int i = 0; i != values.length; i++) { aOut.writeObject(values[i]); } ASN1Primitive[] readValues = new ASN1Primitive[values.length]; ByteArrayInputStream bIn = new ByteArrayInputStream(bOut.toByteArray()); ASN1InputStream aIn = new ASN1InputStream(bIn); for (int i = 0; i != values.length; i++) { ASN1Primitive o = aIn.readObject(); if (!o.equals(values[i])) { return new SimpleTestResult(false, getName() + ": Failed equality test for " + o.getClass()); } if (o.hashCode() != values[i].hashCode()) { return new SimpleTestResult(false, getName() + ": Failed hashCode test for " + o.getClass()); } } } catch (Exception e) { return new SimpleTestResult(false, getName() + ": Failed - exception " + e.toString(), e); } return new SimpleTestResult(true, getName() + ": Okay"); } public String getName() { return "EqualsAndHashCode"; } public static void main( String[] args) { EqualsAndHashCodeTest test = new EqualsAndHashCodeTest(); TestResult result = test.perform(); System.out.println(result); } } bouncycastle-1.49.orig/test/src/org/bouncycastle/asn1/test/package.html0000644000175000017500000000012510330633061025554 0ustar ebourgebourg Test programs for the ASN.1 package. bouncycastle-1.49.orig/test/src/org/bouncycastle/asn1/test/GeneralizedTimeTest.java0000644000175000017500000001316611470174641030071 0ustar ebourgebourgpackage org.bouncycastle.asn1.test; import java.text.SimpleDateFormat; import java.util.Date; import java.util.SimpleTimeZone; import java.util.TimeZone; import org.bouncycastle.asn1.DERGeneralizedTime; import org.bouncycastle.util.test.SimpleTest; /** * X.690 test example */ public class GeneralizedTimeTest extends SimpleTest { String[] input = { "20020122122220", "20020122122220Z", "20020122122220-1000", "20020122122220+00", "20020122122220.1", "20020122122220.1Z", "20020122122220.1-1000", "20020122122220.1+00", "20020122122220.01", "20020122122220.01Z", "20020122122220.01-1000", "20020122122220.01+00", "20020122122220.001", "20020122122220.001Z", "20020122122220.001-1000", "20020122122220.001+00", "20020122122220.0001", "20020122122220.0001Z", "20020122122220.0001-1000", "20020122122220.0001+00", "20020122122220.0001+1000" }; String[] output = { "20020122122220", "20020122122220GMT+00:00", "20020122122220GMT-10:00", "20020122122220GMT+00:00", "20020122122220.1", "20020122122220.1GMT+00:00", "20020122122220.1GMT-10:00", "20020122122220.1GMT+00:00", "20020122122220.01", "20020122122220.01GMT+00:00", "20020122122220.01GMT-10:00", "20020122122220.01GMT+00:00", "20020122122220.001", "20020122122220.001GMT+00:00", "20020122122220.001GMT-10:00", "20020122122220.001GMT+00:00", "20020122122220.0001", "20020122122220.0001GMT+00:00", "20020122122220.0001GMT-10:00", "20020122122220.0001GMT+00:00", "20020122122220.0001GMT+10:00" }; String[] zOutput = { "20020122122220Z", "20020122122220Z", "20020122222220Z", "20020122122220Z", "20020122122220Z", "20020122122220Z", "20020122222220Z", "20020122122220Z", "20020122122220Z", "20020122122220Z", "20020122222220Z", "20020122122220Z", "20020122122220Z", "20020122122220Z", "20020122222220Z", "20020122122220Z", "20020122122220Z", "20020122122220Z", "20020122222220Z", "20020122122220Z", "20020122022220Z" }; String[] mzOutput = { "20020122122220.000Z", "20020122122220.000Z", "20020122222220.000Z", "20020122122220.000Z", "20020122122220.100Z", "20020122122220.100Z", "20020122222220.100Z", "20020122122220.100Z", "20020122122220.010Z", "20020122122220.010Z", "20020122222220.010Z", "20020122122220.010Z", "20020122122220.001Z", "20020122122220.001Z", "20020122222220.001Z", "20020122122220.001Z", "20020122122220.000Z", "20020122122220.000Z", "20020122222220.000Z", "20020122122220.000Z", "20020122022220.000Z" }; public String getName() { return "GeneralizedTime"; } public void performTest() throws Exception { SimpleDateFormat dateF = new SimpleDateFormat("yyyyMMddHHmmss'Z'"); dateF.setTimeZone(new SimpleTimeZone(0,"Z")); for (int i = 0; i != input.length; i++) { DERGeneralizedTime t = new DERGeneralizedTime(input[i]); if (output[i].indexOf('G') > 0) // don't check local time the same way { if (!t.getTime().equals(output[i])) { fail("failed conversion test"); } if (!dateF.format(t.getDate()).equals(zOutput[i])) { fail("failed date conversion test"); } } else { String offset = calculateGMTOffset(t.getDate()); if (!t.getTime().equals(output[i] + offset)) { fail("failed conversion test"); } } } dateF = new SimpleDateFormat("yyyyMMddHHmmss.SSS'Z'"); dateF.setTimeZone(new SimpleTimeZone(0,"Z")); for (int i = 0; i != input.length; i++) { DERGeneralizedTime t = new DERGeneralizedTime(input[i]); if (!dateF.format(t.getDate()).equals(mzOutput[i])) { fail("failed long date conversion test"); } } } private String calculateGMTOffset(Date date) { String sign = "+"; TimeZone timeZone = TimeZone.getDefault(); int offset = timeZone.getRawOffset(); if (offset < 0) { sign = "-"; offset = -offset; } int hours = offset / (60 * 60 * 1000); int minutes = (offset - (hours * 60 * 60 * 1000)) / (60 * 1000); if (timeZone.useDaylightTime() && timeZone.inDaylightTime(date)) { hours += sign.equals("+") ? 1 : -1; } return "GMT" + sign + convert(hours) + ":" + convert(minutes); } private String convert(int time) { if (time < 10) { return "0" + time; } return Integer.toString(time); } public static void main( String[] args) { runTest(new GeneralizedTimeTest()); } } bouncycastle-1.49.orig/test/src/org/bouncycastle/asn1/test/RegressionTest.java0000644000175000017500000000543112021243616027125 0ustar ebourgebourgpackage org.bouncycastle.asn1.test; import org.bouncycastle.util.test.Test; import org.bouncycastle.util.test.TestResult; public class RegressionTest { public static Test[] tests = { new InputStreamTest(), new EqualsAndHashCodeTest(), new TagTest(), new SetTest(), new DERUTF8StringTest(), new CertificateTest(), new GenerationTest(), new CMSTest(), new OCSPTest(), new OIDTest(), new PKCS10Test(), new PKCS12Test(), new X509NameTest(), new X500NameTest(), new X509ExtensionsTest(), new GeneralizedTimeTest(), new BitStringTest(), new MiscTest(), new SMIMETest(), new X9Test(), new MonetaryValueUnitTest(), new BiometricDataUnitTest(), new Iso4217CurrencyCodeUnitTest(), new SemanticsInformationUnitTest(), new QCStatementUnitTest(), new TypeOfBiometricDataUnitTest(), new SignerLocationUnitTest(), new CommitmentTypeQualifierUnitTest(), new CommitmentTypeIndicationUnitTest(), new EncryptedPrivateKeyInfoTest(), new DataGroupHashUnitTest(), new LDSSecurityObjectUnitTest(), new CscaMasterListTest(), new AttributeTableUnitTest(), new ReasonFlagsTest(), new NetscapeCertTypeTest(), new PKIFailureInfoTest(), new KeyUsageTest(), new StringTest(), new UTCTimeTest(), new RequestedCertificateUnitTest(), new OtherCertIDUnitTest(), new OtherSigningCertificateUnitTest(), new ContentHintsUnitTest(), new CertHashUnitTest(), new AdditionalInformationSyntaxUnitTest(), new AdmissionSyntaxUnitTest(), new AdmissionsUnitTest(), new DeclarationOfMajorityUnitTest(), new ProcurationSyntaxUnitTest(), new ProfessionInfoUnitTest(), new RestrictionUnitTest(), new NamingAuthorityUnitTest(), new MonetaryLimitUnitTest(), new NameOrPseudonymUnitTest(), new PersonalDataUnitTest(), new DERApplicationSpecificTest(), new IssuingDistributionPointUnitTest(), new TargetInformationTest(), new SubjectKeyIdentifierTest(), new ESSCertIDv2UnitTest(), new ParsingTest(), new GeneralNameTest(), new ObjectIdentifierTest(), new RFC4519Test() }; public static void main( String[] args) { for (int i = 0; i != tests.length; i++) { TestResult result = tests[i].perform(); if (result.getException() != null) { result.getException().printStackTrace(); } System.out.println(result); } } } bouncycastle-1.49.orig/test/src/org/bouncycastle/asn1/test/ReasonFlagsTest.java0000644000175000017500000000231310453643505027215 0ustar ebourgebourgpackage org.bouncycastle.asn1.test; import java.io.IOException; import org.bouncycastle.asn1.x509.ReasonFlags; import org.bouncycastle.util.test.SimpleTest; public class ReasonFlagsTest extends SimpleTest { public String getName() { return "ReasonFlags"; } public void performTest() throws IOException { BitStringConstantTester.testFlagValueCorrect(0, ReasonFlags.unused); BitStringConstantTester.testFlagValueCorrect(1, ReasonFlags.keyCompromise); BitStringConstantTester.testFlagValueCorrect(2, ReasonFlags.cACompromise); BitStringConstantTester.testFlagValueCorrect(3, ReasonFlags.affiliationChanged); BitStringConstantTester.testFlagValueCorrect(4, ReasonFlags.superseded); BitStringConstantTester.testFlagValueCorrect(5, ReasonFlags.cessationOfOperation); BitStringConstantTester.testFlagValueCorrect(6, ReasonFlags.certificateHold); BitStringConstantTester.testFlagValueCorrect(7, ReasonFlags.privilegeWithdrawn); BitStringConstantTester.testFlagValueCorrect(8, ReasonFlags.aACompromise); } public static void main( String[] args) { runTest(new ReasonFlagsTest()); } } bouncycastle-1.49.orig/test/src/org/bouncycastle/dvcs/0000755000175000017500000000000012152033550022414 5ustar ebourgebourgbouncycastle-1.49.orig/test/src/org/bouncycastle/dvcs/test/0000755000175000017500000000000012152033550023373 5ustar ebourgebourgbouncycastle-1.49.orig/test/src/org/bouncycastle/dvcs/test/DVCSParseTest.java0000644000175000017500000016533512151252353026650 0ustar ebourgebourgpackage org.bouncycastle.dvcs.test; import java.io.IOException; import java.math.BigInteger; import java.util.ArrayList; import java.util.Iterator; import java.util.List; import junit.framework.TestCase; import org.bouncycastle.asn1.ASN1GeneralizedTime; import org.bouncycastle.asn1.ASN1Integer; import org.bouncycastle.asn1.ASN1ObjectIdentifier; import org.bouncycastle.asn1.ASN1Sequence; import org.bouncycastle.asn1.DERSequence; import org.bouncycastle.asn1.cmp.PKIStatus; import org.bouncycastle.asn1.cmp.PKIStatusInfo; import org.bouncycastle.asn1.cms.ContentInfo; import org.bouncycastle.asn1.cms.SignedData; import org.bouncycastle.asn1.dvcs.CertEtcToken; import org.bouncycastle.asn1.dvcs.DVCSCertInfo; import org.bouncycastle.asn1.dvcs.DVCSCertInfoBuilder; import org.bouncycastle.asn1.dvcs.DVCSErrorNotice; import org.bouncycastle.asn1.dvcs.DVCSRequest; import org.bouncycastle.asn1.dvcs.DVCSRequestInformation; import org.bouncycastle.asn1.dvcs.DVCSRequestInformationBuilder; import org.bouncycastle.asn1.dvcs.DVCSResponse; import org.bouncycastle.asn1.dvcs.DVCSTime; import org.bouncycastle.asn1.dvcs.Data; import org.bouncycastle.asn1.dvcs.ServiceType; import org.bouncycastle.asn1.dvcs.TargetEtcChain; import org.bouncycastle.asn1.util.ASN1Dump; import org.bouncycastle.asn1.x509.AlgorithmIdentifier; import org.bouncycastle.asn1.x509.Certificate; import org.bouncycastle.asn1.x509.DigestInfo; import org.bouncycastle.asn1.x509.GeneralName; import org.bouncycastle.asn1.x509.PolicyInformation; import org.bouncycastle.cms.CMSException; import org.bouncycastle.cms.CMSSignedData; import org.bouncycastle.dvcs.DVCSException; import org.bouncycastle.util.encoders.Base64; import org.bouncycastle.util.encoders.Hex; public class DVCSParseTest extends TestCase { // Clepsydre requests and responses private static final String REQUEST_CCPD_CLEPSYDRE = "MIICRgYJKoZIhvcNAQcCoIICNzCCAjMCAQMxCzAJBgUrDgMCGgUAMIGZBgsqhkiG9w0BCRABB6CBiQSBhjCBgzBgCgEEoE2kSzBJMQswCQYDVQQGEwJGUjEOMAwGA1UEBxMFUGFyaXMxEDAOBgNVBAoTB0VkZWxXZWIxGDAWBgNVBAMTD1BldGVyIFN5bHZlc3RlcqEMBgorBgEEAak9AQIBMB8wBwYFKw4DAhoEFHW2ha9viUZ96AcVJR5Fl4/NH6VmMYIBgzCCAX8CAQEwfDBwMQswCQYDVQQGEwJGUjEVMBMGA1UEChMMRWRlbFdlYiBTLkEuMSgwJgYDVQQLEx9DbGVwc3lkcmUgRGVtb25zdHJhdGlvbiBTZXJ2aWNlMSAwHgYDVQQDExdUaW1lIFN0YW1waW5nIEF1dGhvcml0eQIIAJSIFyE0N3YwCQYFKw4DAhoFAKBfMBoGCSqGSIb3DQEJAzENBgsqhkiG9w0BCRABBzAcBgkqhkiG9w0BCQUxDxcNMDAwNDE3MTcxNDU3WjAjBgkqhkiG9w0BCQQxFgQUTajC0s58DQRBL0QTM3XbL1st+dwwDQYJKoZIhvcNAQEBBQAEgYBuew429QhfFjwxeyi7C8LGF2emtVTxmOJviZYODJnmy0DBm43Y147TK0H3FiZbtwi/5pWy2QFs/rEsUsFa0jHzjsrdEaFyBSlBat0oQKpcd8adHYBT22+cTKWjj5KLGD/VOq0Bh2nD/dPYw9DKa+YNTlNuUCCZfJTCRCUbBsCZlg=="; private static final String RESPONSE_CCPD_CLEPSYDRE = "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"; // Top-Cross requests and responses private static final String REQUEST_CPD_TOMSK = "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"; private static final String RESPONSE_CPD_TOMSK = "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"; // private static final String REQUEST_VSD_TOMSK = ""; // private static final String RESPONSE_VSD_TOMSK = ""; private static final String REQUEST_VPKC_TOMSK = "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"; private static final String RESPONSE_VPKC_TOMSK = "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"; private static final String REQUEST_CCPD_TOMSK = "MIIFagYJKoZIhvcNAQcCoIIFWzCCBVcCAQMxDDAKBgYqhQMCAgkFADBuBgsqhkiG9w0BCRABB6BfBF0wWzAKCgEEAgUAwDELHDA1MBEGBiqFAwICCQYHKoUDAgIeAQQgvrgCrtSqJuzWwWE7XelQv0cB71ehcXkh/Oikezqvl1agFgYLKoUDAhUBAQIBAwKgBwIFAJ7ldeKgggN0MIIDcDCCAx2gAwIBAgIKJjs9ewAAAAA3FDAKBgYqhQMCAgMFADCB5zEbMBkGCSqGSIb3DQEJARYMdWRjc0B1ZGNzLnJ1MQswCQYDVQQGEwJSVTEXMBUGA1UECB4OBCIEPgQ8BEEEOgQwBE8xEzARBgNVBAceCgQiBD4EPARBBDoxRzBFBgNVBAoTPlRvbXNrIFN0YXRlIFVuaXZlcnNpdHkgb2YgQ29udHJvbCBTeXN0ZW1zIGFuZCBSYWRpb2VsZWN0cm9uaWNzMScwJQYDVQQLHh4EJgQiBBEAIAAtACAEIwQmACAEIQQ4BDEEOARABDgxGzAZBgNVBAMTElVEQyBTaWJpcmlhIFRTVUNTUjAeFw0xMTEyMDcwNDI0MDBaFw0xMjEyMDcwNDMzMDBaMB8xHTAbBgNVBAMeFABSAEMAQQBJAFIAXwB0AGUAYwBoMGMwHAYGKoUDAgITMBIGByqFAwICJAAGByqFAwICHgEDQwAEQLgMQUEkI9li1pn4dHHEWv5SSCjI77W6wfG3mSzEKw0vd3qQUTd86xZGAEwVC2dxJIdiQlSuMtyog6vSau3FriKjggFsMIIBaDAOBgNVHQ8BAf8EBAMCBPAwMAYDVR0lBCkwJwYIKwYBBQUHAwQGCCqFAwMTAgUCBgcqhQMCAiIGBggrBgEFBQcDAjAdBgNVHQ4EFgQU/hZ+9/9Tt/94ckUhTWabJMCegqQwHwYDVR0jBBgwFoAUuR6KgNhm2o7kHyiMQFiMXOrW5yIwWgYDVR0fBFMwUTBPoE2gS4YjaHR0cDovL3d3dy51ZGNzLnJ1L2NlcnRzcnYvdWRjcy5jcmyGJGh0dHA6Ly93d3cyLnVkY3MucnUvY2VydHNydi91ZGNzLmNybDBxBggrBgEFBQcBAQRlMGMwLwYIKwYBBQUHMAKGI2h0dHA6Ly93d3cudWRjcy5ydS9jZXJ0c3J2L3VkY3MuY2VyMDAGCCsGAQUFBzAChiRodHRwOi8vd3d3Mi51ZGNzLnJ1L2NlcnRzcnYvdWRjcy5jZXIwFQYDVR0gBA4wDDAKBggqhQMDEwIFATAKBgYqhQMCAgMFAANBALCWVdYVTPSLtijWd6utGC/rtl0mGvU3UjyaHC2jbFovDwyRpx13BseqbcsxBA+aNabeH2WuEQMirhVt7lpV4jMxggFaMIIBVgIBATCB9jCB5zEbMBkGCSqGSIb3DQEJARYMdWRjc0B1ZGNzLnJ1MQswCQYDVQQGEwJSVTEXMBUGA1UECB4OBCIEPgQ8BEEEOgQwBE8xEzARBgNVBAceCgQiBD4EPARBBDoxRzBFBgNVBAoTPlRvbXNrIFN0YXRlIFVuaXZlcnNpdHkgb2YgQ29udHJvbCBTeXN0ZW1zIGFuZCBSYWRpb2VsZWN0cm9uaWNzMScwJQYDVQQLHh4EJgQiBBEAIAAtACAEIwQmACAEIQQ4BDEEOARABDgxGzAZBgNVBAMTElVEQyBTaWJpcmlhIFRTVUNTUgIKJjs9ewAAAAA3FDAKBgYqhQMCAgkFADAKBgYqhQMCAhMFAARAl0/LMiXMPCJIkAgCI6x3/8wPBDTR8P5GGs40Xzbz1rdvxcBTPEsyp8kNYMzxmQNegTOFemy15KKnQq8e4Fja6w=="; private static final String RESPONSE_CCPD_TOMSK = "MIIGugYJKoZIhvcNAQcCoIIGqzCCBqcCAQMxDDAKBgYqhQMCAgkFADBwBgsqhkiG9w0BCRABCKBhBF8wXTAKCgEEAgUAwDELHDA1MBEGBiqFAwICCQYHKoUDAgIeAQQgvrgCrtSqJuzWwWE7XelQv0cB71ehcXkh/Oikezqvl1YCAhhwGA8yMDEyMTIwNDA0MDY0M1qgAwIBAKCCBHMwggRvMIIEHKADAgECAgowVZiJAAAAADVaMAoGBiqFAwICAwUAMIHnMRswGQYJKoZIhvcNAQkBFgx1ZGNzQHVkY3MucnUxCzAJBgNVBAYTAlJVMRcwFQYDVQQIHg4EIgQ+BDwEQQQ6BDAETzETMBEGA1UEBx4KBCIEPgQ8BEEEOjFHMEUGA1UEChM+VG9tc2sgU3RhdGUgVW5pdmVyc2l0eSBvZiBDb250cm9sIFN5c3RlbXMgYW5kIFJhZGlvZWxlY3Ryb25pY3MxJzAlBgNVBAseHgQmBCIEEQAgAC0AIAQjBCYAIAQhBDgEMQQ4BEAEODEbMBkGA1UEAxMSVURDIFNpYmlyaWEgVFNVQ1NSMB4XDTExMTAyMDEwMjcwMFoXDTEzMDEyMDEwMzYwMFowggE4MQswCQYDVQQGEwJSVTETMBEGA1UEBx4KBCIEHgQcBCEEGjFDMEEGA1UECh46BBAENAQ8BDgEPQQ4BEEEQgRABDAERgQ4BE8AIAQiBD4EPARBBDoEPgQ5ACAEPgQxBDsEMARBBEIEODGBgTB/BgNVBAseeAQaBD4EPAQ4BEIENQRCACAEOAQ9BEQEPgRABDwEMARCBDgENwQwBEYEOAQ4ACAEOAAgBEEEMgRPBDcEOAAgBBAENAQ8BDgEPQQ4BEEEQgRABDAERgQ4BDgAIAQiBD4EPARBBDoEPgQ5ACAEPgQxBDsEMARBBEIEODFLMEkGA1UEAx5CBC0EGwQVBBoEIgQgBB4EHQQdBCsEGQAgBB0EHgQiBBAEIAQYBBAEIgAgACgARABWAEMAUwAsACAATwBDAFMAUAApMGMwHAYGKoUDAgITMBIGByqFAwICJAAGByqFAwICHgEDQwAEQIo5pHpksfRGL3IMW+/ztQB3ea+Jh+lei/e1Ml/xhoPYHssE6pv7D7qv8LlYnFvNn/3+4bhx5SJVH+Xo08KR+d2jggFQMIIBTDAdBgNVHSUEFjAUBggrBgEFBQcDCQYIKwYBBQUHAwowCwYDVR0PBAQDAgbAMA8GCSsGAQUFBzABBQQCBQAwHQYDVR0OBBYEFF+aiOU1eH40sGhpBJWx0XnZoNjYMB8GA1UdIwQYMBaAFLkeioDYZtqO5B8ojEBYjFzq1uciMFoGA1UdHwRTMFEwT6BNoEuGI2h0dHA6Ly93d3cudWRjcy5ydS9jZXJ0c3J2L3VkY3MuY3JshiRodHRwOi8vd3d3Mi51ZGNzLnJ1L2NlcnRzcnYvdWRjcy5jcmwwcQYIKwYBBQUHAQEEZTBjMC8GCCsGAQUFBzAChiNodHRwOi8vd3d3LnVkY3MucnUvY2VydHNydi91ZGNzLmNlcjAwBggrBgEFBQcwAoYkaHR0cDovL3d3dzIudWRjcy5ydS9jZXJ0c3J2L3VkY3MuY2VyMAoGBiqFAwICAwUAA0EAMPpel9k/cxdhbRok77LEatERjWifXfT9O6krfoCfYJ73jpw+KPKVagjPiIF31K5ofSB0Sfrti54ZA6PG1GzqSDGCAakwggGlAgEBMIH2MIHnMRswGQYJKoZIhvcNAQkBFgx1ZGNzQHVkY3MucnUxCzAJBgNVBAYTAlJVMRcwFQYDVQQIHg4EIgQ+BDwEQQQ6BDAETzETMBEGA1UEBx4KBCIEPgQ8BEEEOjFHMEUGA1UEChM+VG9tc2sgU3RhdGUgVW5pdmVyc2l0eSBvZiBDb250cm9sIFN5c3RlbXMgYW5kIFJhZGlvZWxlY3Ryb25pY3MxJzAlBgNVBAseHgQmBCIEEQAgAC0AIAQjBCYAIAQhBDgEMQQ4BEAEODEbMBkGA1UEAxMSVURDIFNpYmlyaWEgVFNVQ1NSAgowVZiJAAAAADVaMAoGBiqFAwICCQUAoE0wLwYJKoZIhvcNAQkEMSIEINO9R6CnEfi/gJi+AWp3FDKG0HZ5Fq94JvwCoRpXze93MBoGCSqGSIb3DQEJAzENBgsqhkiG9w0BCRABCDAKBgYqhQMCAhMFAARAIVnBio5IT1m+Dkzxktb9BRoElW5au5SO8T/+wGXnWD86CsBF25F5jvN6a2l83XzD0YDrC0wuMsY/dyThotWwvw=="; // expected info initialization: private static final DVCSRequest REQ_CCPD_CLEPSYDRE, REQ_CCPD_TOMSK, REQ_CPD_TOMSK, REQ_VPKC_TOMSK; private static final DVCSResponse RES_CCPD_CLEPSYDRE, RES_CCPD_TOMSK, RES_CPD_TOMSK, RES_VPKC_TOMSK; private static List requests = new ArrayList(); private static List responses = new ArrayList(); static { GeneralName CLEPSYDRE_REQUESTER = GeneralName.getInstance(Hex.decode("A44B3049310B3009060355040613024652310E300C0603550407130550617269733110300E060355040A13074564656C576562311830160603550403130F50657465722053796C766573746572")); GeneralName CLEPSYDRE_RESPONDER = GeneralName.getInstance(Hex.decode("A4723070310B300906035504061302465231153013060355040A130C4564656C57656220532E412E31283026060355040B131F436C657073796472652044656D6F6E7374726174696F6E20536572766963653120301E0603550403131754696D65205374616D70696E6720417574686F72697479")); PolicyInformation CLEPSYDRE_POLICY = new PolicyInformation(new ASN1ObjectIdentifier("1.3.6.1.4.1.5309.1.2.1")); DVCSRequestInformationBuilder INFO_CCPD_CLEPSYDRE = new DVCSRequestInformationBuilder(ServiceType.CCPD); INFO_CCPD_CLEPSYDRE.setRequester(CLEPSYDRE_REQUESTER); INFO_CCPD_CLEPSYDRE.setRequestPolicy(CLEPSYDRE_POLICY); DigestInfo DIGEST_CCPD_CLEPSYDRE = new DigestInfo(new AlgorithmIdentifier(new ASN1ObjectIdentifier("1.3.14.3.2.26")), Hex.decode("75B685AF6F89467DE80715251E45978FCD1FA566")); DVCSRequestInformationBuilder INFO_CCPD_CLEPSYDRE2 = new DVCSRequestInformationBuilder(ServiceType.CCPD); INFO_CCPD_CLEPSYDRE2.setRequester(CLEPSYDRE_REQUESTER); INFO_CCPD_CLEPSYDRE2.setRequestPolicy(CLEPSYDRE_POLICY); INFO_CCPD_CLEPSYDRE2.setDVCS(CLEPSYDRE_RESPONDER); REQ_CCPD_CLEPSYDRE = new DVCSRequest(INFO_CCPD_CLEPSYDRE.build(), new Data(DIGEST_CCPD_CLEPSYDRE)); RES_CCPD_CLEPSYDRE = new DVCSResponse(new DVCSCertInfo(INFO_CCPD_CLEPSYDRE2.build(), DIGEST_CCPD_CLEPSYDRE, new ASN1Integer(new BigInteger(Hex.decode("01780A1ECA8823"))), new DVCSTime(new ASN1GeneralizedTime("20000417171617Z")))); DVCSRequestInformationBuilder INFO_CCPD_TOMSK = new DVCSRequestInformationBuilder(ServiceType.CCPD); INFO_CCPD_TOMSK.setNonce(new BigInteger(Hex.decode("00C0310B1C"))); DigestInfo DIGEST_CCPD_TOMSK = new DigestInfo(new AlgorithmIdentifier(new ASN1ObjectIdentifier("1.2.643.2.2.9"), new ASN1ObjectIdentifier("1.2.643.2.2.30.1")), Hex.decode("BEB802AED4AA26ECD6C1613B5DE950BF4701EF57A1717921FCE8A47B3AAF9756")); GeneralName ID_CCPD_TOMSK = GeneralName.getInstance(Hex.decode("A016060B2A85030215010102010302A0070205009EE575E2")); REQ_CCPD_TOMSK = new DVCSRequest(INFO_CCPD_TOMSK.build(), new Data(DIGEST_CCPD_TOMSK), ID_CCPD_TOMSK); DVCSCertInfoBuilder certInfoBldr = new DVCSCertInfoBuilder(INFO_CCPD_TOMSK.build(), DIGEST_CCPD_TOMSK, new ASN1Integer(6256), new DVCSTime(new ASN1GeneralizedTime("20121204040643Z"))); certInfoBldr.setDvStatus(new PKIStatusInfo(PKIStatus.granted)); RES_CCPD_TOMSK = new DVCSResponse(certInfoBldr.build()); DVCSRequestInformationBuilder INFO_CPD_TOMSK = new DVCSRequestInformationBuilder(ServiceType.CPD); INFO_CPD_TOMSK.setNonce(new BigInteger("234303415")); DVCSRequestInformationBuilder INFO_CPD_TOMSK2 = new DVCSRequestInformationBuilder(ServiceType.CPD); INFO_CPD_TOMSK2.setNonce(new BigInteger("1957381177")); String CPD_DATA_TOMSK = "30820418308203C5A003020102020A4CE0FAF7000000003CD0300A06062A850302020305003081E7311B301906092A864886F70D010901160C7564637340756463732E7275310B30090603550406130252553117301506035504081E0E0422043E043C0441043A0430044F3113301106035504071E0A0422043E043C0441043A31473045060355040A133E546F6D736B20537461746520556E6976657273697479206F6620436F6E74726F6C2053797374656D7320616E6420526164696F656C656374726F6E69637331273025060355040B1E1E0426042204110020002D0020042304260020042104380431043804400438311B301906035504031312554443205369626972696120545355435352301E170D3132313131323033323830305A170D3133303330333036313930305A3081D13128302606092A864886F70D0109011619746573745F75646373406374622E726B2E74757375722E7275310B30090603550406130252553113301106035504070C0AD0A2D0BED0BCD181D0BA313D303B060355040A0C34D0A3D0B4D0BED181D182D0BED0B2D0B5D180D18FD18ED189D0B8D0B920D0A6D0B5D0BDD182D18020D0A1D0B8D0B1D0B8D180D0B83144304206035504030C3BD0A2D0B5D181D182D0BED0B2D18BD0B920D09FD0BED0BBD18CD0B7D0BED0B2D0B0D182D0B5D0BBD18C20D0A3D0A620D0A1D0B8D0B1D0B8D180D0B83063301C06062A8503020213301206072A85030202240006072A850302021E010343000440474D47E4F21779C52C2249D0C07BA20D14B2E64E2E35ECCA7BBCC44D67E13DBF419B4F9D8F326411CD77B7621E3302C75D53A56BDD6016849B85F591629D3B58A38201613082015D300E0603551D0F0101FF0404030204F030260603551D25041F301D06082B0601050507030406072A85030202220606082B06010505070302301D0603551D0E04160414E2554D2891FF3AA4394D07B41711D40B57D8253D301F0603551D23041830168014B91E8A80D866DA8EE41F288C40588C5CEAD6E722305A0603551D1F04533051304FA04DA04B8623687474703A2F2F7777772E756463732E72752F636572747372762F756463732E63726C8624687474703A2F2F777777322E756463732E72752F636572747372762F756463732E63726C307106082B0601050507010104653063302F06082B060105050730028623687474703A2F2F7777772E756463732E72752F636572747372762F756463732E636572303006082B060105050730028624687474703A2F2F777777322E756463732E72752F636572747372762F756463732E63657230140603551D20040D300B300906072A850303130204300A06062A850302020305000341001189C3FA073C79B4691766296F0B1DC21308EEEC03406B031CD9425574512999192E5528F0A09E97683D06EC5B8CA79F14E2BC37E1F1900919C29567D9220FF4"; DigestInfo DIGEST_CPD_TOMSK = DIGEST_CCPD_TOMSK; GeneralName ID_CPD_TOMSK = GeneralName.getInstance(Hex.decode("A016060B2A85030215010102010302A00702050085BA0D41")); REQ_CPD_TOMSK = new DVCSRequest(INFO_CPD_TOMSK.build(), new Data(Hex.decode(CPD_DATA_TOMSK)), ID_CPD_TOMSK); certInfoBldr = new DVCSCertInfoBuilder(INFO_CPD_TOMSK2.build(), DIGEST_CPD_TOMSK, new ASN1Integer(6329), new DVCSTime(new ASN1GeneralizedTime("20121205065720Z"))); certInfoBldr.setDvStatus(new PKIStatusInfo(PKIStatus.granted)); RES_CPD_TOMSK = new DVCSResponse(certInfoBldr.build()); DVCSRequestInformationBuilder INFO_VPKC_TOMSK = new DVCSRequestInformationBuilder(ServiceType.VPKC); INFO_VPKC_TOMSK.setNonce(new BigInteger(Hex.decode("00D3F85051"))); String VPKC_DATA_TOMSK = CPD_DATA_TOMSK; DigestInfo DIGEST_VPKC_TOMSK = new DigestInfo(new AlgorithmIdentifier(new ASN1ObjectIdentifier("1.2.643.2.2.9"), new ASN1ObjectIdentifier("1.2.643.2.2.30.1")), Hex.decode("FD97A3191C95D2AD733C11ABE0E6AEB081AF8735177F50F6B08C29D3AAFE8DE7")); GeneralName ID_VPKC_TOMSK = GeneralName.getInstance(Hex.decode("A016060B2A85030215010102010302A007020500AE344E64")); CertEtcToken target = new CertEtcToken(CertEtcToken.TAG_CERTIFICATE, Certificate.getInstance(Hex.decode(VPKC_DATA_TOMSK))); TargetEtcChain REQ_CERTS = new TargetEtcChain(target); TargetEtcChain[] RES_CERTS = TargetEtcChain.arrayFromSequence(new DERSequence(ASN1Sequence.getInstance(Hex.decode("308216BBA0820418308203C5A003020102020A4CE0FAF7000000003CD0300A06062A850302020305003081E7311B301906092A864886F70D010901160C7564637340756463732E7275310B30090603550406130252553117301506035504081E0E0422043E043C0441043A0430044F3113301106035504071E0A0422043E043C0441043A31473045060355040A133E546F6D736B20537461746520556E6976657273697479206F6620436F6E74726F6C2053797374656D7320616E6420526164696F656C656374726F6E69637331273025060355040B1E1E0426042204110020002D0020042304260020042104380431043804400438311B301906035504031312554443205369626972696120545355435352301E170D3132313131323033323830305A170D3133303330333036313930305A3081D13128302606092A864886F70D0109011619746573745F75646373406374622E726B2E74757375722E7275310B30090603550406130252553113301106035504070C0AD0A2D0BED0BCD181D0BA313D303B060355040A0C34D0A3D0B4D0BED181D182D0BED0B2D0B5D180D18FD18ED189D0B8D0B920D0A6D0B5D0BDD182D18020D0A1D0B8D0B1D0B8D180D0B83144304206035504030C3BD0A2D0B5D181D182D0BED0B2D18BD0B920D09FD0BED0BBD18CD0B7D0BED0B2D0B0D182D0B5D0BBD18C20D0A3D0A620D0A1D0B8D0B1D0B8D180D0B83063301C06062A8503020213301206072A85030202240006072A850302021E010343000440474D47E4F21779C52C2249D0C07BA20D14B2E64E2E35ECCA7BBCC44D67E13DBF419B4F9D8F326411CD77B7621E3302C75D53A56BDD6016849B85F591629D3B58A38201613082015D300E0603551D0F0101FF0404030204F030260603551D25041F301D06082B0601050507030406072A85030202220606082B06010505070302301D0603551D0E04160414E2554D2891FF3AA4394D07B41711D40B57D8253D301F0603551D23041830168014B91E8A80D866DA8EE41F288C40588C5CEAD6E722305A0603551D1F04533051304FA04DA04B8623687474703A2F2F7777772E756463732E72752F636572747372762F756463732E63726C8624687474703A2F2F777777322E756463732E72752F636572747372762F756463732E63726C307106082B0601050507010104653063302F06082B060105050730028623687474703A2F2F7777772E756463732E72752F636572747372762F756463732E636572303006082B060105050730028624687474703A2F2F777777322E756463732E72752F636572747372762F756463732E63657230140603551D20040D300B300906072A850303130204300A06062A850302020305000341001189C3FA073C79B4691766296F0B1DC21308EEEC03406B031CD9425574512999192E5528F0A09E97683D06EC5B8CA79F14E2BC37E1F1900919C29567D9220FF43082129BA48212923082123F020101300A06062A850302020305003081E7311B301906092A864886F70D010901160C7564637340756463732E7275310B30090603550406130252553117301506035504081E0E0422043E043C0441043A0430044F3113301106035504071E0A0422043E043C0441043A31473045060355040A133E546F6D736B20537461746520556E6976657273697479206F6620436F6E74726F6C2053797374656D7320616E6420526164696F656C656374726F6E69637331273025060355040B1E1E0426042204110020002D0020042304260020042104380431043804400438311B301906035504031312554443205369626972696120545355435352170D3132313230333233313434325A170D3132313230343131333434325A308210C23029020A63D1113D0000000037F4170D3132303532393035343134325A300C300A0603551D1504030A01053029020A531056A0000000003C9D170D3132303530343036343030375A300C300A0603551D1504030A01053029020A7355CE0D000000003859170D3132303530323035333830375A300C300A0603551D1504030A01053029020A4AE834300000000037AC170D3132303430353130303130385A300C300A0603551D1504030A01053029020A59B4198A000000003CB0170D3132303330323038313635395A300C300A0603551D1504030A01063029020A18249CA60000000038B2170D3132303330313038343833375A300C300A0603551D1504030A01053029020A6DEAF612000000003824170D3132303232373131303433335A300C300A0603551D1504030A0105301B020A39D1DE4A000000003C87170D3132303232343035333433325A3029020A4444F4C4000000003BA1170D3132303232323037333635315A300C300A0603551D1504030A01063029020A43625071000000003B8E170D3132303231373033343333395A300C300A0603551D1504030A01063029020A431B3050000000003B82170D3132303231373033333935335A300C300A0603551D1504030A01063029020A6433B6890000000037FC170D3132303231373032353935395A300C300A0603551D1504030A0106301B020A1C5BF404000000003C4B170D3132303231363039343931305A3029020A1CF6345A0000000036F5170D3132303231363038353732365A300C300A0603551D1504030A01063029020A6D864F01000000003C04170D3132303231343039303935375A300C300A0603551D1504030A0106301B020A162D584F000000003C2C170D3132303231343037343732335A301B020A16E8FE85000000003C31170D3132303231343037343730395A3029020A72C498EC000000003C19170D3132303231303130303135395A300C300A0603551D1504030A01063029020A14FA364A000000003ADE170D3132303230363130313334345A300C300A0603551D1504030A01063029020A43182533000000003B81170D3132303230363034323931375A300C300A0603551D1504030A01063029020A431508FF000000003B80170D3132303230363032353230355A300C300A0603551D1504030A01063029020A43120ED9000000003B7F170D3132303230363032343630315A300C300A0603551D1504030A01063029020A430E73FF000000003B7E170D3132303230363032343232365A300C300A0603551D1504030A01063029020A43061D4B000000003B7C170D3132303230333035313032365A300C300A0603551D1504030A01063029020A42FEF88F000000003B7A170D3132303230323130323435365A300C300A0603551D1504030A01063029020A430AC0DB000000003B7D170D3132303230313037323132365A300C300A0603551D1504030A01063029020A4302B4DB000000003B7B170D3132303230313033323635345A300C300A0603551D1504030A01063029020A3DCCBBBA000000003B63170D3132303133313033313030315A300C300A0603551D1504030A01063029020A2A403F0B000000003B32170D3132303133303038343932325A300C300A0603551D1504030A01063029020A396432E1000000003B43170D3132303133303036333730355A300C300A0603551D1504030A01063029020A49EC23230000000037A2170D3132303133303035353233395A300C300A0603551D1504030A01063029020A60B42B980000000039AC170D3132303132373037353935345A300C300A0603551D1504030A0106301B020A25540752000000003B1C170D3132303132363130353831305A3029020A6137E543000000003AB7170D3132303132363034343034335A300C300A0603551D1504030A01063029020A612DCD96000000003AB6170D3132303132363034333531395A300C300A0603551D1504030A01063029020A60C303950000000039AE170D3132303132363034323632365A300C300A0603551D1504030A0106301B020A2439FB96000000003B02170D3132303132363034313035355A3029020A30AE0A2300000000376D170D3132303132353130313933305A300C300A0603551D1504030A01063029020A2BFFA7C3000000003756170D3132303132353130303432375A300C300A0603551D1504030A01063029020A1BB71C85000000003A26170D3132303132353130303135315A300C300A0603551D1504030A01063029020A2BCF205C00000000373B170D3132303132353130303130325A300C300A0603551D1504030A01063029020A2BF039FE00000000374B170D3132303132353130303031395A300C300A0603551D1504030A01063029020A1F099C2E000000003A77170D3132303132353039353934305A300C300A0603551D1504030A01063029020A2BC7A320000000003736170D3132303132353039353930305A300C300A0603551D1504030A01063029020A2BFBD81D000000003753170D3132303132353039353833385A300C300A0603551D1504030A01063029020A2BD484BB00000000373D170D3132303132353039353831355A300C300A0603551D1504030A01063029020A2BF49B8400000000374E170D3132303132353039353735335A300C300A0603551D1504030A01063029020A2C00D595000000003757170D3132303132353039353730335A300C300A0603551D1504030A01063029020A2BBC0A02000000003730170D3132303132353039353630315A300C300A0603551D1504030A01063029020A2BEB9798000000003748170D3132303132353039353533355A300C300A0603551D1504030A01063029020A2BDAB5A2000000003741170D3132303132353039353431355A300C300A0603551D1504030A01063029020A2C090F8A000000003759170D3132303132353039353333305A300C300A0603551D1504030A01063029020A2BF79616000000003750170D3132303132353039353231325A300C300A0603551D1504030A01063029020A2BEEB34F00000000374A170D3132303132353039353130385A300C300A0603551D1504030A01063029020A2BF675B200000000374F170D3132303132353039353034325A300C300A0603551D1504030A01063029020A2BD60C9400000000373E170D3132303132353039343932345A300C300A0603551D1504030A01063029020A2BD79BDF00000000373F170D3132303132353039303130385A300C300A0603551D1504030A01063029020A2BFD4C4F000000003754170D3132303132353039303034335A300C300A0603551D1504030A01063029020A6F1D206D000000003849170D3132303132353038353730345A300C300A0603551D1504030A01063029020A2BF93ACE000000003751170D3132303132353038353434385A300C300A0603551D1504030A01063029020A2BDD470B000000003743170D3132303132353038353431365A300C300A0603551D1504030A01063029020A2BE15CE1000000003746170D3132303132353038353132345A300C300A0603551D1504030A01063029020A2BDE86AF000000003744170D3132303132353038353035315A300C300A0603551D1504030A01063029020A2BFAA02A000000003752170D3132303132353038353032335A300C300A0603551D1504030A01063029020A2BC89D6E000000003737170D3132303132353038343935355A300C300A0603551D1504030A01063029020A2BD8D7CA000000003740170D3132303132353038343932395A300C300A0603551D1504030A01063029020A2BD1434C00000000373C170D3132303132353038343930355A300C300A0603551D1504030A01063029020A2BCA8FB8000000003738170D3132303132353038343834325A300C300A0603551D1504030A01063029020A1BD74138000000003A2B170D3132303132353038343733305A300C300A0603551D1504030A01063029020A1BC46DC3000000003A27170D3132303132353038343435325A300C300A0603551D1504030A01063029020A31B2B567000000003770170D3132303132353038343331305A300C300A0603551D1504030A01063029020A1EBAE5CA000000003A6A170D3132303132333038343431355A300C300A0603551D1504030A01063029020A16507403000000003ACD170D3132303132303038333631325A300C300A0603551D1504030A0106301B020A1133D59A000000003AC0170D3132303131393038353835335A301B020A54EC6BAC00000000391F170D3132303131393038343732345A3029020A562EC02700000000393D170D3132303131393038303834315A300C300A0603551D1504030A01063029020A13E616DA000000003A8D170D3132303131373038333431335A300C300A0603551D1504030A01063029020A2BE02163000000003745170D3132303131363039353233345A300C300A0603551D1504030A01063029020A2BBE7768000000003731170D3132303131363037353833385A300C300A0603551D1504030A01063029020A2BF1A4AA00000000374C170D3132303131363037353430335A300C300A0603551D1504030A0106301B020A1DEC32B1000000003A4B170D3132303131363034343831345A3029020A1BF65268000000003A32170D3132303131353139333235335A300C300A0603551D1504030A01063029020A2BC3E0F7000000003733170D3132303131353138313433315A300C300A0603551D1504030A01063029020A6106BEDE0000000039E4170D3132303131333039313832395A300C300A0603551D1504030A01063029020A55C46B6B0000000037E8170D3132303131333032323430305A300C300A0603551D1504030A01063029020A5AFE0124000000003967170D3132303131313036353831315A300C300A0603551D1504030A01063029020A2142E738000000003705170D3132303131313035353030315A300C300A0603551D1504030A0106301B020A568BE0F9000000003944170D3132303131303130323032345A301B020A129514C00000000038E5170D3131313233303036323033345A301B020A12A8C2E50000000038E6170D3131313233303036313933305A301B020A1752822400000000390A170D3131313232393033333733375A3029020A1337AE5C0000000038ED170D3131313232393033313532325A300C300A0603551D1504030A01063029020A1E4BBF640000000038D3170D3131313232373039343330315A300C300A0603551D1504030A01043029020A1E4892770000000038D2170D3131313232373039343230335A300C300A0603551D1504030A01043029020A7907BD3100000000388F170D3131313232333036323630315A300C300A0603551D1504030A01063029020A2B130CE6000000003721170D3131313232313038323935345A300C300A0603551D1504030A01063029020A2BC1E40E000000003732170D3131313232313034353730375A300C300A0603551D1504030A01063029020A69D631FD00000000381A170D3131313232303037343330345A300C300A0603551D1504030A01063029020A4062B7A800000000377B170D3131313231323036323733385A300C300A0603551D1504030A01043029020A31D45B0C000000003771170D3131313231323034333733335A300C300A0603551D1504030A01063029020A3069086E00000000376A170D3131313230393034303333385A300C300A0603551D1504030A01043029020A2C02217D000000003758170D3131313230383037323930355A300C300A0603551D1504030A01043029020A2B6B5CEF00000000372B170D3131313230383035333232315A300C300A0603551D1504030A01043029020A21D19C1E000000003709170D3131313230363037353935375A300C300A0603551D1504030A0106A060305E301F0603551D23041830168014B91E8A80D866DA8EE41F288C40588C5CEAD6E722301006092B06010401823715010403020100300B0603551D140404020209E0301C06092B0601040182371504040F170D3132313230343035323434325A300A06062A850302020305000341006D9C3CCD9EFB17C5BB0F8EA40FAF62F9C7A5765D163E270AFC998AF701D7F984F5AF494B963DA7647638D2C3E252D5C2E00EA75DE8B5C1A405F692D206961B3AA203020100")))); REQ_VPKC_TOMSK = new DVCSRequest(INFO_VPKC_TOMSK.build(), new Data(REQ_CERTS), ID_VPKC_TOMSK); certInfoBldr = new DVCSCertInfoBuilder(INFO_VPKC_TOMSK.build(), DIGEST_VPKC_TOMSK, new ASN1Integer(6257), new DVCSTime(new ASN1GeneralizedTime("20121204040753Z"))); certInfoBldr.setDvStatus(new PKIStatusInfo(PKIStatus.granted)); certInfoBldr.setCerts(RES_CERTS); RES_VPKC_TOMSK = new DVCSResponse(certInfoBldr.build()); requests.add(new Info("req_ccpd_clepsydre", REQUEST_CCPD_CLEPSYDRE, REQ_CCPD_CLEPSYDRE)); requests.add(new Info("req_ccpd_tomsk", REQUEST_CCPD_TOMSK, REQ_CCPD_TOMSK)); requests.add(new Info("req_cpd_tomsk", REQUEST_CPD_TOMSK, REQ_CPD_TOMSK)); requests.add(new Info("req_vpkc_tomsk", REQUEST_VPKC_TOMSK, REQ_VPKC_TOMSK)); responses.add(new Info("res_ccpd_clepsydre", RESPONSE_CCPD_CLEPSYDRE, RES_CCPD_CLEPSYDRE)); responses.add(new Info("res_ccpd_tomsk", RESPONSE_CCPD_TOMSK, RES_CCPD_TOMSK)); responses.add(new Info("res_cpd_tomsk", RESPONSE_CPD_TOMSK, RES_CPD_TOMSK)); responses.add(new Info("res_vpkc_tomsk", RESPONSE_VPKC_TOMSK, RES_VPKC_TOMSK)); } private static boolean areNull(String type, Object result, Object expected) { if (result == null && expected == null) { return true; } if (result == null && expected != null) { fail("Result '" + type + "' is null, whereas expected '" + type + "' is not null"); } if (result != null && expected == null) { fail("Result '" + type + "' is not null, whereas expected '" + type + "' is null"); } return false; } //////////////////////////////////////////////////// // PARSE TESTS // //////////////////////////////////////////////////// private static void validate(String type, Object result, Object expected) { if (areNull(type, result, expected)) { return; } if (!result.equals(expected)) { fail("Different " + type + ": " + result + " while expected: " + expected); } } private static void validateArray(String type, Object[] result, Object[] expected) { if (areNull(type, result, expected)) { return; } if (result.length != expected.length) { fail("Different " + type + ": " + result + " while expected: " + expected); } for (int i = 0; i != result.length; i++) { if (!result[i].equals(expected[i])) { fail("Different " + type + ": " + result[i] + " while expected: " + expected[i]); } } } public void testParseRequests() throws IOException, DVCSException, CMSException { for (Iterator it = requests.iterator(); it.hasNext();) { Info info = (Info)it.next(); testParseRequest(info.name, info.base64, (DVCSRequest)info.expected); } } private void testParseRequest(String name, String base64request, DVCSRequest expected) throws DVCSException, IOException, CMSException { byte[] requestBytes = Base64.decode(base64request); org.bouncycastle.dvcs.DVCSRequest request = new org.bouncycastle.dvcs.DVCSRequest(new CMSSignedData(requestBytes)); validate(name, request.getContent(), expected); } public void testParseResponses() throws IOException, DVCSException, CMSException { for (Iterator it = responses.iterator(); it.hasNext();) { Info info = (Info)it.next(); testParseResponse(info.name, info.base64, (DVCSResponse)info.expected); } } //////////////////////////////////////////////////// // VALIDATIONS // //////////////////////////////////////////////////// private void testParseResponse(String name, String base64response, DVCSResponse expected) throws DVCSException, IOException, CMSException { byte[] responseBytes = Base64.decode(base64response); org.bouncycastle.dvcs.DVCSResponse response = new org.bouncycastle.dvcs.DVCSResponse(new CMSSignedData(responseBytes)); validate(name, response.getContent(), expected); } /* DVCSRequest ::= SEQUENCE { requestInformation DVCSRequestInformation, data Data, transactionIdentifier GeneralName OPTIONAL } */ private void validate(String name, DVCSRequest result, DVCSRequest expected) { validate(name + ".requestInformation", result.getRequestInformation(), expected.getRequestInformation()); validate(name + ".data", result.getData(), expected.getData()); validate(name + ".transactionIdentifier", result.getTransactionIdentifier(), expected.getTransactionIdentifier()); } /* DVCSRequestInformation ::= SEQUENCE { version INTEGER DEFAULT 1 , service ServiceType, nonce Nonce OPTIONAL, requestTime DVCSTime OPTIONAL, requester [0] GeneralNames OPTIONAL, requestPolicy [1] PolicyInformation OPTIONAL, dvcs [2] GeneralNames OPTIONAL, dataLocations [3] GeneralNames OPTIONAL, extensions [4] IMPLICIT Extensions OPTIONAL } */ private void validate(String name, DVCSRequestInformation info, DVCSRequestInformation expected) { validate(name + ".version", new Integer(info.getVersion()), new Integer(expected.getVersion())); validate(name + ".service", info.getService().getValue(), expected.getService().getValue()); validate(name + ".nonce", info.getNonce(), expected.getNonce()); validate(name + ".requestTime", info.getRequestTime(), expected.getRequestTime()); validate(name + ".requester", info.getRequester(), expected.getRequester()); validate(name + ".requestPolicy", info.getRequestPolicy(), expected.getRequestPolicy()); validate(name + ".dvcs", info.getDVCS(), expected.getDVCS()); validate(name + ".dataLocations", info.getDataLocations(), expected.getDataLocations()); validate(name + ".extensions", info.getExtensions(), expected.getExtensions()); } /* DVCSTime ::= CHOICE { genTime GeneralizedTime, timeStampToken ContentInfo } */ private void validate(String name, DVCSTime result, DVCSTime expected) { if (areNull(name, result, expected)) { return; } validate(name + ".genTime", result.getGenTime(), expected.getGenTime()); validate(name + ".timeStampToken", result.getTimeStampToken(), expected.getTimeStampToken()); } /* Data ::= CHOICE { message OCTET STRING , messageImprint DigestInfo, certs SEQUENCE SIZE (1..MAX) OF TargetEtcChain } */ private void validate(String name, Data result, Data expected) { validate(name + ".message", result.getMessage(), expected.getMessage()); validate(name + ".messageImprint", result.getMessageImprint(), expected.getMessageImprint()); validateArray(name + ".certs", result.getCerts(), expected.getCerts()); } /* DVCSResponse ::= CHOICE { dvCertInfo DVCSCertInfo , dvErrorNote [0] DVCSErrorNotice } */ private void validate(String name, DVCSResponse result, DVCSResponse expected) { validate(name + ".dvCertInfo", result.getCertInfo(), expected.getCertInfo()); validate(name + ".dvErrorNote", result.getErrorNotice(), expected.getErrorNotice()); } /* DVCSCertInfo::= SEQUENCE { version Integer DEFAULT 1 , dvReqInfo DVCSRequestInformation, messageImprint DigestInfo, serialNumber Integer, responseTime DVCSTime, dvStatus [0] PKIStatusInfo OPTIONAL, policy [1] PolicyInformation OPTIONAL, reqSignature [2] SignerInfos OPTIONAL, certs [3] SEQUENCE SIZE (1..MAX) OF TargetEtcChain OPTIONAL, extensions Extensions OPTIONAL } */ private void validate(String name, DVCSCertInfo result, DVCSCertInfo expected) { if (areNull(name, result, expected)) { return; } validate(name + ".version", new Integer(result.getVersion()), new Integer(expected.getVersion())); validate(name + ".dvReqInfo", result.getDvReqInfo(), expected.getDvReqInfo()); validate(name + ".messageImprint", result.getMessageImprint(), expected.getMessageImprint()); validate(name + ".serialNumber", result.getSerialNumber(), expected.getSerialNumber()); validate(name + ".responseTime", result.getResponseTime(), expected.getResponseTime()); validate(name + ".dvStatus", result.getDvStatus(), expected.getDvStatus()); validate(name + ".policy", result.getPolicy(), expected.getPolicy()); validate(name + ".reqSignature", result.getReqSignature(), expected.getReqSignature()); validateArray(name + ".certs", result.getCerts(), expected.getCerts()); validateArray(name + ".certs", result.getCerts(), expected.getCerts()); validate(name + ".extensions", result.getExtensions(), expected.getExtensions()); } /* DVCSErrorNotice ::= SEQUENCE { transactionStatus PKIStatusInfo , transactionIdentifier GeneralName OPTIONAL } */ private void validate(String name, DVCSErrorNotice result, DVCSErrorNotice expected) { if (areNull(name, result, expected)) { return; } validate(name + ".transactionStatus", result.getTransactionStatus(), expected.getTransactionStatus()); validate(name + ".transactionIdentifier", result.getTransactionIdentifier(), expected.getTransactionIdentifier()); } private static class Info { public String name; public String base64; public Object expected; public Info(String name, String base64, Object expected) { this.name = name; this.base64 = base64; this.expected = expected; } } } bouncycastle-1.49.orig/test/src/org/bouncycastle/dvcs/test/AllTests.java0000644000175000017500000002031612132420260025767 0ustar ebourgebourgpackage org.bouncycastle.dvcs.test; import java.io.IOException; import java.security.KeyPair; import java.security.Security; import java.security.cert.CertificateEncodingException; import java.security.cert.X509Certificate; import junit.framework.Test; import junit.framework.TestCase; import junit.framework.TestSuite; import org.bouncycastle.asn1.dvcs.CertEtcToken; import org.bouncycastle.asn1.dvcs.TargetEtcChain; import org.bouncycastle.cert.jcajce.JcaX509CertificateHolder; import org.bouncycastle.cms.CMSSignedData; import org.bouncycastle.cms.CMSSignedDataGenerator; import org.bouncycastle.cms.SignerId; import org.bouncycastle.cms.SignerInformationVerifier; import org.bouncycastle.cms.SignerInformationVerifierProvider; import org.bouncycastle.cms.jcajce.JcaSignerInfoGeneratorBuilder; import org.bouncycastle.cms.jcajce.JcaSimpleSignerInfoVerifierBuilder; import org.bouncycastle.cms.test.CMSTestUtil; import org.bouncycastle.dvcs.CCPDRequestBuilder; import org.bouncycastle.dvcs.CCPDRequestData; import org.bouncycastle.dvcs.CPDRequestBuilder; import org.bouncycastle.dvcs.CPDRequestData; import org.bouncycastle.dvcs.DVCSException; import org.bouncycastle.dvcs.DVCSRequest; import org.bouncycastle.dvcs.MessageImprint; import org.bouncycastle.dvcs.MessageImprintBuilder; import org.bouncycastle.dvcs.SignedDVCSMessageGenerator; import org.bouncycastle.dvcs.TargetChain; import org.bouncycastle.dvcs.VPKCRequestBuilder; import org.bouncycastle.dvcs.VPKCRequestData; import org.bouncycastle.dvcs.VSDRequestBuilder; import org.bouncycastle.dvcs.VSDRequestData; import org.bouncycastle.jce.provider.BouncyCastleProvider; import org.bouncycastle.operator.ContentSigner; import org.bouncycastle.operator.OperatorCreationException; import org.bouncycastle.operator.jcajce.JcaContentSignerBuilder; import org.bouncycastle.operator.jcajce.JcaDigestCalculatorProviderBuilder; import org.bouncycastle.util.Arrays; import org.bouncycastle.util.io.Streams; public class AllTests extends TestCase { private static final String BC = BouncyCastleProvider.PROVIDER_NAME; private static boolean initialised = false; private static String origDN; private static KeyPair origKP; private static X509Certificate origCert; private static String signDN; private static KeyPair signKP; private static X509Certificate signCert; private static void init() throws Exception { if (!initialised) { initialised = true; if (Security.getProvider(BC) == null) { Security.addProvider(new BouncyCastleProvider()); } origDN = "O=Bouncy Castle, C=AU"; origKP = CMSTestUtil.makeKeyPair(); origCert = CMSTestUtil.makeCertificate(origKP, origDN, origKP, origDN); signDN = "CN=Bob, OU=Sales, O=Bouncy Castle, C=AU"; signKP = CMSTestUtil.makeKeyPair(); signCert = CMSTestUtil.makeCertificate(signKP, signDN, origKP, origDN); } } public void setUp() throws Exception { init(); } private byte[] getInput(String name) throws IOException { return Streams.readAll(getClass().getResourceAsStream(name)); } public void testCCPDRequest() throws Exception { SignedDVCSMessageGenerator gen = getSignedDVCSMessageGenerator(); CCPDRequestBuilder reqBuilder = new CCPDRequestBuilder(); MessageImprintBuilder imprintBuilder = new MessageImprintBuilder(new SHA1DigestCalculator()); MessageImprint messageImprint = imprintBuilder.build(new byte[100]); CMSSignedData reqMsg = gen.build(reqBuilder.build(messageImprint)); assertTrue(reqMsg.verifySignatures(new SignerInformationVerifierProvider() { public SignerInformationVerifier get(SignerId sid) throws OperatorCreationException { return new JcaSimpleSignerInfoVerifierBuilder().setProvider(BC).build(signCert); } })); DVCSRequest request = new DVCSRequest(reqMsg); CCPDRequestData reqData = (CCPDRequestData)request.getData(); assertEquals(messageImprint, reqData.getMessageImprint()); } private CMSSignedData getWrappedCPDRequest() throws OperatorCreationException, CertificateEncodingException, DVCSException, IOException { SignedDVCSMessageGenerator gen = getSignedDVCSMessageGenerator(); CPDRequestBuilder reqBuilder = new CPDRequestBuilder(); return gen.build(reqBuilder.build(new byte[100])); } public void testCPDRequest() throws Exception { CMSSignedData reqMsg = getWrappedCPDRequest(); assertTrue(reqMsg.verifySignatures(new SignerInformationVerifierProvider() { public SignerInformationVerifier get(SignerId sid) throws OperatorCreationException { return new JcaSimpleSignerInfoVerifierBuilder().setProvider(BC).build(signCert); } })); DVCSRequest request = new DVCSRequest(reqMsg); CPDRequestData reqData = (CPDRequestData)request.getData(); assertTrue(Arrays.areEqual(new byte[100], reqData.getMessage())); } public void testVPKCRequest() throws Exception { SignedDVCSMessageGenerator gen = getSignedDVCSMessageGenerator(); VPKCRequestBuilder reqBuilder = new VPKCRequestBuilder(); reqBuilder.addTargetChain(new JcaX509CertificateHolder(signCert)); CMSSignedData reqMsg = gen.build(reqBuilder.build()); assertTrue(reqMsg.verifySignatures(new SignerInformationVerifierProvider() { public SignerInformationVerifier get(SignerId sid) throws OperatorCreationException { return new JcaSimpleSignerInfoVerifierBuilder().setProvider(BC).build(signCert); } })); DVCSRequest request = new DVCSRequest(reqMsg); VPKCRequestData reqData = (VPKCRequestData)request.getData(); assertEquals(new TargetEtcChain(new CertEtcToken(CertEtcToken.TAG_CERTIFICATE, new JcaX509CertificateHolder(signCert).toASN1Structure())), ((TargetChain)reqData.getCerts().get(0)).toASN1Structure()); } public void testVSDRequest() throws Exception { CMSSignedData message = getWrappedCPDRequest(); SignedDVCSMessageGenerator gen = getSignedDVCSMessageGenerator(); VSDRequestBuilder reqBuilder = new VSDRequestBuilder(); CMSSignedData reqMsg = gen.build(reqBuilder.build(message)); assertTrue(reqMsg.verifySignatures(new SignerInformationVerifierProvider() { public SignerInformationVerifier get(SignerId sid) throws OperatorCreationException { return new JcaSimpleSignerInfoVerifierBuilder().setProvider(BC).build(signCert); } })); DVCSRequest request = new DVCSRequest(reqMsg); VSDRequestData reqData = (VSDRequestData)request.getData(); assertEquals(message.toASN1Structure().getContentType(), reqData.getParsedMessage().toASN1Structure().getContentType()); } private SignedDVCSMessageGenerator getSignedDVCSMessageGenerator() throws OperatorCreationException, CertificateEncodingException { CMSSignedDataGenerator sigDataGen = new CMSSignedDataGenerator(); JcaDigestCalculatorProviderBuilder calculatorProviderBuilder = new JcaDigestCalculatorProviderBuilder().setProvider(BC); ContentSigner contentSigner = new JcaContentSignerBuilder("SHA1withRSA").setProvider(BC).build(signKP.getPrivate()); sigDataGen.addSignerInfoGenerator(new JcaSignerInfoGeneratorBuilder(calculatorProviderBuilder.build()).build(contentSigner, signCert)); return new SignedDVCSMessageGenerator(sigDataGen); } public static void main(String[] args) throws Exception { Security.addProvider(new BouncyCastleProvider()); junit.textui.TestRunner.run(suite()); } public static Test suite() throws Exception { TestSuite suite= new TestSuite("EAC tests"); suite.addTestSuite(AllTests.class); suite.addTestSuite(DVCSParseTest.class); return new DVCSTestSetup(suite); } } bouncycastle-1.49.orig/test/src/org/bouncycastle/dvcs/test/DVCSTestSetup.java0000644000175000017500000000101012131665034026653 0ustar ebourgebourg package org.bouncycastle.dvcs.test; import java.security.Security; import junit.extensions.TestSetup; import junit.framework.Test; import org.bouncycastle.jce.provider.BouncyCastleProvider; class DVCSTestSetup extends TestSetup { public DVCSTestSetup(Test test) { super(test); } protected void setUp() { Security.addProvider(new BouncyCastleProvider()); } protected void tearDown() { Security.removeProvider(BouncyCastleProvider.PROVIDER_NAME); } } bouncycastle-1.49.orig/test/src/org/bouncycastle/dvcs/test/SHA1DigestCalculator.java0000644000175000017500000000177012131665034030116 0ustar ebourgebourgpackage org.bouncycastle.dvcs.test; import java.io.ByteArrayOutputStream; import java.io.OutputStream; import org.bouncycastle.asn1.oiw.OIWObjectIdentifiers; import org.bouncycastle.asn1.x509.AlgorithmIdentifier; import org.bouncycastle.crypto.Digest; import org.bouncycastle.crypto.digests.SHA1Digest; import org.bouncycastle.operator.DigestCalculator; class SHA1DigestCalculator implements DigestCalculator { private ByteArrayOutputStream bOut = new ByteArrayOutputStream(); public AlgorithmIdentifier getAlgorithmIdentifier() { return new AlgorithmIdentifier(OIWObjectIdentifiers.idSHA1); } public OutputStream getOutputStream() { return bOut; } public byte[] getDigest() { byte[] bytes = bOut.toByteArray(); bOut.reset(); Digest sha1 = new SHA1Digest(); sha1.update(bytes, 0, bytes.length); byte[] digest = new byte[sha1.getDigestSize()]; sha1.doFinal(digest, 0); return digest; } } bouncycastle-1.49.orig/test/src/org/bouncycastle/util/0000755000175000017500000000000012152033550022432 5ustar ebourgebourgbouncycastle-1.49.orig/test/src/org/bouncycastle/util/utiltest/0000755000175000017500000000000012152033550024307 5ustar ebourgebourgbouncycastle-1.49.orig/test/src/org/bouncycastle/util/utiltest/AllTests.java0000644000175000017500000000070012057751740026716 0ustar ebourgebourgpackage org.bouncycastle.util.utiltest; import junit.framework.Test; import junit.framework.TestSuite; public class AllTests { public static void main (String[] args) { junit.textui.TestRunner.run (suite()); } public static Test suite() { TestSuite suite = new TestSuite("util tests"); suite.addTestSuite(IPTest.class); suite.addTestSuite(BigIntegersTest.class); return suite; } } bouncycastle-1.49.orig/test/src/org/bouncycastle/util/utiltest/BigIntegersTest.java0000644000175000017500000000476212057752747030251 0ustar ebourgebourgpackage org.bouncycastle.util.utiltest; import java.math.BigInteger; import junit.framework.Assert; import junit.framework.TestCase; import org.bouncycastle.util.Arrays; import org.bouncycastle.util.BigIntegers; import org.bouncycastle.util.IPAddress; import org.bouncycastle.util.encoders.Hex; public class BigIntegersTest extends TestCase { public String getName() { return "BigIntegers"; } public void testAsUnsignedByteArray() { BigInteger a = new BigInteger(1, Hex.decode("ff12345678")); byte[] a5 = BigIntegers.asUnsignedByteArray(a); Assert.assertEquals(5, a5.length); Assert.assertTrue(Arrays.areEqual(a5, Hex.decode("ff12345678"))); BigInteger b = new BigInteger(1, Hex.decode("0f12345678")); byte[] b5 = BigIntegers.asUnsignedByteArray(b); Assert.assertEquals(5, b5.length); Assert.assertTrue(Arrays.areEqual(b5, Hex.decode("0f12345678"))); } public void testFixedLengthUnsignedByteArray() { BigInteger a = new BigInteger(1, Hex.decode("ff12345678")); byte[] a5 = BigIntegers.asUnsignedByteArray(5, a); Assert.assertEquals(5, a5.length); Assert.assertTrue(Arrays.areEqual(a5, Hex.decode("ff12345678"))); byte[] a6 = BigIntegers.asUnsignedByteArray(6, a); Assert.assertEquals(6, a6.length); Assert.assertEquals(0, a6[0]); Assert.assertTrue(Arrays.areEqual(a6, Hex.decode("00ff12345678"))); BigInteger b = new BigInteger(1, Hex.decode("0f12345678")); byte[] b5 = BigIntegers.asUnsignedByteArray(5, b); Assert.assertEquals(5, b5.length); Assert.assertTrue(Arrays.areEqual(b5, Hex.decode("0f12345678"))); byte[] b6 = BigIntegers.asUnsignedByteArray(6, b); Assert.assertEquals(6, b6.length); Assert.assertEquals(0, b6[0]); Assert.assertTrue(Arrays.areEqual(b6, Hex.decode("000f12345678"))); BigInteger c = new BigInteger(1, Hex.decode("ff123456789a")); try { byte[] c5 = BigIntegers.asUnsignedByteArray(5, c); fail("no exception thrown"); } catch (IllegalArgumentException e) { // ignore } BigInteger d = new BigInteger(1, Hex.decode("0f123456789a")); try { byte[] c5 = BigIntegers.asUnsignedByteArray(5, d); fail("no exception thrown"); } catch (IllegalArgumentException e) { // ignore } } } bouncycastle-1.49.orig/test/src/org/bouncycastle/util/utiltest/IPTest.java0000644000175000017500000000262511730525250026333 0ustar ebourgebourgpackage org.bouncycastle.util.utiltest; import junit.framework.TestCase; import org.bouncycastle.util.IPAddress; public class IPTest extends TestCase { private static final String validIP4v[] = new String[] { "0.0.0.0", "255.255.255.255", "192.168.0.0" }; private static final String invalidIP4v[] = new String[] { "0.0.0.0.1", "256.255.255.255", "1", "A.B.C", "1:.4.6.5" }; private static final String validIP6v[] = new String[] { "0:0:0:0:0:0:0:0", "FFFF:FFFF:FFFF:FFFF:FFFF:FFFF:FFFF:FFFF", "0:1:2:3:FFFF:5:FFFF:1" }; private static final String invalidIP6v[] = new String[] { "0.0.0.0:1", "FFFF:FFFF:FFFF:FFFF:FFFF:FFFF:FFFF:FFFFF" }; private void testIP(String[] valid, String[] invalid) { for (int i = 0; i < valid.length; i++) { if (!IPAddress.isValid(valid[i])) { fail("Valid input string not accepted: " + valid[i] + "."); } } for (int i = 0; i < invalid.length; i++) { if (IPAddress.isValid(invalid[i])) { fail("Invalid input string accepted: " + invalid[i] + "."); } } } public String getName() { return "IPTest"; } public void testIPv4() { testIP(validIP4v, invalidIP4v); } public void testIPv6() { testIP(validIP6v, invalidIP6v); } } bouncycastle-1.49.orig/test/src/org/bouncycastle/util/encoders/0000755000175000017500000000000012152033550024234 5ustar ebourgebourgbouncycastle-1.49.orig/test/src/org/bouncycastle/util/encoders/test/0000755000175000017500000000000012152033550025213 5ustar ebourgebourgbouncycastle-1.49.orig/test/src/org/bouncycastle/util/encoders/test/AbstractCoderTest.java0000644000175000017500000001414310330633061031440 0ustar ebourgebourgpackage org.bouncycastle.util.encoders.test; import java.io.ByteArrayOutputStream; import java.io.IOException; import java.util.Arrays; import java.util.Random; import junit.framework.TestCase; import org.bouncycastle.util.encoders.Encoder; public abstract class AbstractCoderTest extends TestCase { private static final int[] SIZES_TO_CHECK = {64, 128, 1024, 1025, 1026, 2048, 2049, 2050, 4096, 4097, 4098, 8192, 8193, 8194}; protected Encoder enc; private Random r; AbstractCoderTest( String name) { super(name); } protected void setUp() { r = new Random(); } private void checkArrayOfSize(int size) throws IOException { byte[] original = new byte[size]; r.nextBytes(original); ByteArrayOutputStream bOut = new ByteArrayOutputStream(); enc.encode(original, 0, original.length, bOut); byte[] encoded = bOut.toByteArray(); assertTrue(encoded.length > original.length); assertTrue(encoded.length <= (original.length * 2)); checkEncoding(encoded); checkSimpleDecode(original, encoded); checkStringDecode(original, encoded); checkOutputStreamDecode(original, encoded); int offset = r.nextInt(20); byte[] offsetEncoded = new byte[offset + encoded.length]; System.arraycopy(encoded, 0, offsetEncoded, offset, encoded.length); checkOffsetDecode(original, offsetEncoded, offset, encoded.length); offset = r.nextInt(20); byte[] offsetOriginal = new byte[offset + original.length]; System.arraycopy(original, 0, offsetOriginal, offset, original.length); checkOffsetEncode(original, offsetOriginal, offset, original.length); byte[] encodedWithSpace = addWhitespace(encoded); checkSimpleDecode(original, encodedWithSpace); checkStringDecode(original, encodedWithSpace); checkOutputStreamDecode(original, encodedWithSpace); } public void testEncode() throws IOException { for (int i = 0; i < SIZES_TO_CHECK.length; i++) { checkArrayOfSize(SIZES_TO_CHECK[i]); } } private void checkEncoding(byte[] encoded) { String encString = convertBytesToString(encoded); for (int i = 0; i < encString.length(); i++) { char c = encString.charAt(i); if (c == paddingChar()) { // should only be padding at end of string assertTrue(i > encString.length() - 3); continue; } else if (isEncodedChar(c)) { continue; } fail("Unexpected encoded character " + c); } } private void checkOutputStreamDecode(byte[] original, byte[] encoded) { String encString = convertBytesToString(encoded); ByteArrayOutputStream out = new ByteArrayOutputStream(); try { assertEquals(original.length, enc.decode(encString, out)); assertTrue(Arrays.equals(original, out.toByteArray())); } catch (IOException e) { fail("This shouldn't happen"); } } private void checkSimpleDecode(byte[] original, byte[] encoded) throws IOException { ByteArrayOutputStream bOut = new ByteArrayOutputStream(); enc.decode(encoded, 0, encoded.length, bOut); assertTrue(Arrays.equals(original, bOut.toByteArray())); } private void checkOffsetEncode(byte[] original, byte[] offsetOriginal, int off, int length) throws IOException { ByteArrayOutputStream bOut = new ByteArrayOutputStream(); enc.encode(offsetOriginal, off, length, bOut); byte[] encoded = bOut.toByteArray(); bOut.reset(); enc.decode(encoded, 0, encoded.length, bOut); assertTrue(Arrays.equals(original, bOut.toByteArray())); } private void checkOffsetDecode(byte[] original, byte[] encoded, int off, int length) throws IOException { ByteArrayOutputStream bOut = new ByteArrayOutputStream(); enc.decode(encoded, off, length, bOut); assertTrue(Arrays.equals(original, bOut.toByteArray())); } private void checkStringDecode(byte[] original, byte[] encoded) throws IOException { String encString = convertBytesToString(encoded); ByteArrayOutputStream bOut = new ByteArrayOutputStream(); enc.decode(encString, bOut); assertTrue(Arrays.equals(original, bOut.toByteArray())); } private byte[] addWhitespace(byte[] encoded) { ByteArrayOutputStream out = new ByteArrayOutputStream(); addSpace(out); for (int i = 0; i < encoded.length - 5; i++) { out.write(encoded, i, 1); if (r.nextInt(100) < 5) { addSpace(out); } } for (int i = encoded.length - 5; i < encoded.length; i++) { out.write(encoded, i, 1); } addSpace(out); return out.toByteArray(); } private void addSpace(ByteArrayOutputStream out) { do { switch (r.nextInt(3)) { case 0 : out.write((int) '\n'); break; case 1 : out.write((int) '\r'); break; case 2 : out.write((int) '\t'); break; case 3 : out.write((int) ' '); break; } } while (r.nextBoolean()); } private String convertBytesToString(byte[] encoded) { StringBuffer b = new StringBuffer(); for (int i = 0; i != encoded.length; i++) { b.append((char)(encoded[i] & 0xff)); } return b.toString(); } abstract protected char paddingChar(); abstract protected boolean isEncodedChar(char c); } bouncycastle-1.49.orig/test/src/org/bouncycastle/util/encoders/test/Base64Test.java0000644000175000017500000000760511735222524027761 0ustar ebourgebourgpackage org.bouncycastle.util.encoders.test; import java.io.IOException; import org.bouncycastle.util.Arrays; import org.bouncycastle.util.Strings; import org.bouncycastle.util.encoders.Base64; import org.bouncycastle.util.encoders.Base64Encoder; import org.bouncycastle.util.encoders.DecoderException; import org.bouncycastle.util.encoders.Hex; public class Base64Test extends AbstractCoderTest { private static final String sample1 = "mO4TyLWG7vjFWdKT8IJcVbZ/jwc="; private static final byte[] sample1Bytes = Hex.decode("98ee13c8b586eef8c559d293f0825c55b67f8f07"); private static final String sample2 = "F4I4p8Vf/mS+Kxvri3FPoMcqmJ1f"; private static final byte[] sample2Bytes = Hex.decode("178238a7c55ffe64be2b1beb8b714fa0c72a989d5f"); private static final String sample3 = "UJmEdJYodqHJmd7Rtv6/OP29/jUEFw=="; private static final byte[] sample3Bytes = Hex.decode("50998474962876a1c999ded1b6febf38fdbdfe350417"); private static final String invalid1 = "%O4TyLWG7vjFWdKT8IJcVbZ/jwc="; private static final String invalid2 = "F%I4p8Vf/mS+Kxvri3FPoMcqmJ1f"; private static final String invalid3 = "UJ%EdJYodqHJmd7Rtv6/OP29/jUEFw=="; private static final String invalid4 = "mO4%yLWG7vjFWdKT8IJcVbZ/jwc="; private static final String invalid5 = "UJmEdJYodqHJmd7Rtv6/OP29/jUEF%=="; private static final String invalid6 = "mO4TyLWG7vjFWdKT8IJcVbZ/jw%="; private static final String invalid7 = "F4I4p8Vf/mS+Kxvri3FPoMcqmJ1%"; private static final String invalid8 = "UJmEdJYodqHJmd7Rtv6/OP29/jUE%c=="; private static final String invalid9 = "mO4TyLWG7vjFWdKT8IJcVbZ/j%c="; private static final String invalida = "F4I4p8Vf/mS+Kxvri3FPoMcqmJ%1"; private static final String invalidb = "UJmEdJYodqHJmd7Rtv6/OP29/jU%Fc=="; private static final String invalidc = "mO4TyLWG7vjFWdKT8IJcVbZ/%wc="; private static final String invalidd = "F4I4p8Vf/mS+Kxvri3FPoMcqm%1c"; public Base64Test( String name) { super(name); } protected void setUp() { super.setUp(); enc = new Base64Encoder(); } public void testSamples() throws IOException { assertTrue(Arrays.areEqual(sample1Bytes, Base64.decode(sample1))); assertTrue(Arrays.areEqual(sample1Bytes, Base64.decode(Strings.toByteArray(sample1)))); assertTrue(Arrays.areEqual(sample2Bytes, Base64.decode(sample2))); assertTrue(Arrays.areEqual(sample2Bytes, Base64.decode(Strings.toByteArray(sample2)))); assertTrue(Arrays.areEqual(sample3Bytes, Base64.decode(sample3))); assertTrue(Arrays.areEqual(sample3Bytes, Base64.decode(Strings.toByteArray(sample3)))); } public void testInvalidInput() throws IOException { String[] invalid = new String[] { invalid1, invalid2, invalid3, invalid4, invalid5, invalid6, invalid7, invalid8, invalid9, invalida, invalidb, invalidc, invalidd }; for (int i = 0; i != invalid.length; i++) { invalidTest(invalid[i]); invalidTest(Strings.toByteArray(invalid[i])); } } private void invalidTest(String data) { try { Base64.decode(data); } catch (DecoderException e) { return; } fail("invalid String data parsed"); } private void invalidTest(byte[] data) { try { Base64.decode(data); } catch (DecoderException e) { return; } fail("invalid byte data parsed"); } protected char paddingChar() { return '='; } protected boolean isEncodedChar(char c) { if (Character.isLetterOrDigit(c)) { return true; } else if (c == '+') { return true; } else if (c == '/') { return true; } return false; } } bouncycastle-1.49.orig/test/src/org/bouncycastle/util/encoders/test/AllTests.java0000644000175000017500000000072410330633061027613 0ustar ebourgebourgpackage org.bouncycastle.util.encoders.test; import junit.framework.*; public class AllTests { public static void main (String[] args) { junit.textui.TestRunner.run (suite()); } public static Test suite() { TestSuite suite = new TestSuite("encoder tests"); suite.addTestSuite(Base64Test.class); suite.addTestSuite(UrlBase64Test.class); suite.addTestSuite(HexTest.class); return suite; } } bouncycastle-1.49.orig/test/src/org/bouncycastle/util/encoders/test/UrlBase64Test.java0000644000175000017500000000764711735226206030453 0ustar ebourgebourgpackage org.bouncycastle.util.encoders.test; import java.io.IOException; import org.bouncycastle.util.Arrays; import org.bouncycastle.util.Strings; import org.bouncycastle.util.encoders.DecoderException; import org.bouncycastle.util.encoders.Hex; import org.bouncycastle.util.encoders.UrlBase64; import org.bouncycastle.util.encoders.UrlBase64Encoder; public class UrlBase64Test extends AbstractCoderTest { private static final String sample1 = "mO4TyLWG7vjFWdKT8IJcVbZ_jwc."; private static final byte[] sample1Bytes = Hex.decode("98ee13c8b586eef8c559d293f0825c55b67f8f07"); private static final String sample2 = "F4I4p8Vf_mS-Kxvri3FPoMcqmJ1f"; private static final byte[] sample2Bytes = Hex.decode("178238a7c55ffe64be2b1beb8b714fa0c72a989d5f"); private static final String sample3 = "UJmEdJYodqHJmd7Rtv6_OP29_jUEFw.."; private static final byte[] sample3Bytes = Hex.decode("50998474962876a1c999ded1b6febf38fdbdfe350417"); private static final String invalid1 = "%O4TyLWG7vjFWdKT8IJcVbZ_jwc."; private static final String invalid2 = "F%I4p8Vf_mS-Kxvri3FPoMcqmJ1f"; private static final String invalid3 = "UJ%EdJYodqHJmd7Rtv6_OP29_jUEFw.."; private static final String invalid4 = "mO4%yLWG7vjFWdKT8IJcVbZ_jwc."; private static final String invalid5 = "UJmEdJYodqHJmd7Rtv6_OP29_jUEF%.."; private static final String invalid6 = "mO4TyLWG7vjFWdKT8IJcVbZ_jw%."; private static final String invalid7 = "F4I4p8Vf_mS-Kxvri3FPoMcqmJ1%"; private static final String invalid8 = "UJmEdJYodqHJmd7Rtv6_OP29_jUE%c.."; private static final String invalid9 = "mO4TyLWG7vjFWdKT8IJcVbZ_j%c."; private static final String invalida = "F4I4p8Vf_mS-Kxvri3FPoMcqmJ%1"; private static final String invalidb = "UJmEdJYodqHJmd7Rtv6_OP29_jU%Fc.."; private static final String invalidc = "mO4TyLWG7vjFWdKT8IJcVbZ_%wc."; private static final String invalidd = "F4I4p8Vf_mS-Kxvri3FPoMcqm%1c"; public UrlBase64Test( String name) { super(name); } protected void setUp() { super.setUp(); enc = new UrlBase64Encoder(); } public void testSamples() throws IOException { assertTrue(Arrays.areEqual(sample1Bytes, UrlBase64.decode(sample1))); assertTrue(Arrays.areEqual(sample1Bytes, UrlBase64.decode(Strings.toByteArray(sample1)))); assertTrue(Arrays.areEqual(sample2Bytes, UrlBase64.decode(sample2))); assertTrue(Arrays.areEqual(sample2Bytes, UrlBase64.decode(Strings.toByteArray(sample2)))); assertTrue(Arrays.areEqual(sample3Bytes, UrlBase64.decode(sample3))); assertTrue(Arrays.areEqual(sample3Bytes, UrlBase64.decode(Strings.toByteArray(sample3)))); } public void testInvalidInput() throws IOException { String[] invalid = new String[] { invalid1, invalid2, invalid3, invalid4, invalid5, invalid6, invalid7, invalid8, invalid9, invalida, invalidb, invalidc, invalidd }; for (int i = 0; i != invalid.length; i++) { invalidTest(invalid[i]); invalidTest(Strings.toByteArray(invalid[i])); } } private void invalidTest(String data) { try { UrlBase64.decode(data); } catch (DecoderException e) { return; } fail("invalid String data parsed"); } private void invalidTest(byte[] data) { try { UrlBase64.decode(data); } catch (DecoderException e) { return; } fail("invalid byte data parsed"); } protected char paddingChar() { return '.'; } protected boolean isEncodedChar(char c) { if (Character.isLetterOrDigit(c)) { return true; } else if (c == '-') { return true; } else if (c == '_') { return true; } return false; } } bouncycastle-1.49.orig/test/src/org/bouncycastle/util/encoders/test/EncoderTest.java0000644000175000017500000001555310422362133030306 0ustar ebourgebourgpackage org.bouncycastle.util.encoders.test; import java.util.Arrays; import java.util.Random; import org.bouncycastle.util.encoders.Base64; import org.bouncycastle.util.encoders.Hex; import org.bouncycastle.util.test.SimpleTest; public class EncoderTest extends SimpleTest { public static final boolean DEBUG = true; public static void main( String[] args) { runTest(new EncoderTest()); } public String getName() { return "Encoder"; } /* * * TESTS * */ public void performTest() { testHex(); testBase64(); testBase64WithNL(); } public void testBase64() { try { Random _r = new Random(); byte[] _orig1024 = new byte[1024]; _r.nextBytes(_orig1024); byte[] _orig2048 = new byte[2048]; _r.nextBytes(_orig2048); byte[] _orig4096 = new byte[4096]; _r.nextBytes(_orig4096); byte[] _orig8192 = new byte[8192]; _r.nextBytes(_orig8192); byte[] _enc1024 = Base64.encode(_orig1024); byte[] _enc2048 = Base64.encode(_orig2048); byte[] _enc4096 = Base64.encode(_orig4096); byte[] _enc8192 = Base64.encode(_orig8192); byte[] _dec1024 = Base64.decode(_enc1024); byte[] _dec2048 = Base64.decode(_enc2048); byte[] _dec4096 = Base64.decode(_enc4096); byte[] _dec8192 = Base64.decode(_enc8192); if(!Arrays.equals(_orig1024, _dec1024)) { fail("Failed Base64 test"); } if(!Arrays.equals(_orig2048, _dec2048)) { fail("Failed Base64 test"); } if(!Arrays.equals(_orig4096, _dec4096)) { fail("Failed Base64 test"); } if(!Arrays.equals(_orig8192, _dec8192)) { fail("Failed Base64 test"); } byte[] _orig1025 = new byte[1025]; _r.nextBytes(_orig1025); byte[] _orig2049 = new byte[2049]; _r.nextBytes(_orig2049); byte[] _orig4097 = new byte[4097]; _r.nextBytes(_orig4097); byte[] _orig8193 = new byte[8193]; _r.nextBytes(_orig8193); byte[] _enc1025 = Base64.encode(_orig1025); byte[] _enc2049 = Base64.encode(_orig2049); byte[] _enc4097 = Base64.encode(_orig4097); byte[] _enc8193 = Base64.encode(_orig8193); byte[] _dec1025 = Base64.decode(_enc1025); byte[] _dec2049 = Base64.decode(_enc2049); byte[] _dec4097 = Base64.decode(_enc4097); byte[] _dec8193 = Base64.decode(_enc8193); if(!Arrays.equals(_orig1025, _dec1025)) { fail("Failed Base64 test"); } if(!Arrays.equals(_orig2049, _dec2049)) { fail("Failed Base64 test"); } if(!Arrays.equals(_orig4097, _dec4097)) { fail("Failed Base64 test"); } if(!Arrays.equals(_orig8193, _dec8193)) { fail("Failed Base64 test"); } } catch(Exception ex) { fail("Failed Base64 test"); } } public void testBase64WithNL() { byte[] dec = Base64.decode("SVNC" + "\n" + "QUQ=\n"); if (dec.length != 5) { fail("got length " + dec.length + " when expecting 10"); } if (!areEqual(dec, Base64.decode("SVNCQUQ="))) { fail("decodings are not equal"); } } public void testHex() { try { Random _r = new Random(); byte[] _orig1024 = new byte[1024]; _r.nextBytes(_orig1024); byte[] _orig2048 = new byte[2048]; _r.nextBytes(_orig2048); byte[] _orig4096 = new byte[4096]; _r.nextBytes(_orig4096); byte[] _orig8192 = new byte[8192]; _r.nextBytes(_orig8192); byte[] _enc1024 = Hex.encode(_orig1024); byte[] _enc2048 = Hex.encode(_orig2048); byte[] _enc4096 = Hex.encode(_orig4096); byte[] _enc8192 = Hex.encode(_orig8192); byte[] _dec1024 = Hex.decode(_enc1024); byte[] _dec2048 = Hex.decode(_enc2048); byte[] _dec4096 = Hex.decode(_enc4096); byte[] _dec8192 = Hex.decode(_enc8192); if(!Arrays.equals(_orig1024, _dec1024)) { fail("Failed Hex test"); } if(!Arrays.equals(_orig2048, _dec2048)) { fail("Failed Hex test"); } if(!Arrays.equals(_orig4096, _dec4096)) { fail("Failed Hex test"); } if(!Arrays.equals(_orig8192, _dec8192)) { fail("Failed Hex test"); } byte[] _orig1025 = new byte[1025]; _r.nextBytes(_orig1025); byte[] _orig2049 = new byte[2049]; _r.nextBytes(_orig2049); byte[] _orig4097 = new byte[4097]; _r.nextBytes(_orig4097); byte[] _orig8193 = new byte[8193]; _r.nextBytes(_orig8193); byte[] _enc1025 = Hex.encode(_orig1025); byte[] _enc2049 = Hex.encode(_orig2049); byte[] _enc4097 = Hex.encode(_orig4097); byte[] _enc8193 = Hex.encode(_orig8193); byte[] _dec1025 = Hex.decode(_enc1025); byte[] _dec2049 = Hex.decode(_enc2049); byte[] _dec4097 = Hex.decode(_enc4097); byte[] _dec8193 = Hex.decode(_enc8193); if(!Arrays.equals(_orig1025, _dec1025)) { fail("Failed Hex test"); } if(!Arrays.equals(_orig2049, _dec2049)) { fail("Failed Hex test"); } if(!Arrays.equals(_orig4097, _dec4097)) { fail("Failed Hex test"); } if(!Arrays.equals(_orig8193, _dec8193)) { fail("Failed Hex test"); } } catch(Exception ex) { fail("Failed Hex test"); } } } bouncycastle-1.49.orig/test/src/org/bouncycastle/util/encoders/test/HexTest.java0000644000175000017500000000371711735224111027453 0ustar ebourgebourgpackage org.bouncycastle.util.encoders.test; import java.io.IOException; import org.bouncycastle.util.Strings; import org.bouncycastle.util.encoders.DecoderException; import org.bouncycastle.util.encoders.Hex; import org.bouncycastle.util.encoders.HexEncoder; public class HexTest extends AbstractCoderTest { private static final String invalid1 = "%O4T"; private static final String invalid2 = "FZI4"; private static final String invalid3 = "ae%E"; private static final String invalid4 = "fO4%"; private static final String invalid5 = "beefe"; private static final String invalid6 = "beefs"; public HexTest( String name) { super(name); } protected void setUp() { super.setUp(); enc = new HexEncoder(); } protected char paddingChar() { return 0; } protected boolean isEncodedChar(char c) { if ('A' <= c && c <= 'F') { return true; } if ('a' <= c && c <= 'f') { return true; } if ('0' <= c && c <= '9') { return true; } return false; } public void testInvalidInput() throws IOException { String[] invalid = new String[] { invalid1, invalid2, invalid3, invalid4, invalid5, invalid6 }; for (int i = 0; i != invalid.length; i++) { invalidTest(invalid[i]); invalidTest(Strings.toByteArray(invalid[i])); } } private void invalidTest(String data) { try { Hex.decode(data); } catch (DecoderException e) { return; } fail("invalid String data parsed"); } private void invalidTest(byte[] data) { try { Hex.decode(data); } catch (DecoderException e) { return; } fail("invalid byte data parsed"); } } bouncycastle-1.49.orig/test/src/org/bouncycastle/util/io/0000755000175000017500000000000012152033550023041 5ustar ebourgebourgbouncycastle-1.49.orig/test/src/org/bouncycastle/util/io/pem/0000755000175000017500000000000012152033550023622 5ustar ebourgebourgbouncycastle-1.49.orig/test/src/org/bouncycastle/util/io/pem/test/0000755000175000017500000000000012152033550024601 5ustar ebourgebourgbouncycastle-1.49.orig/test/src/org/bouncycastle/util/io/pem/test/AllTests.java0000644000175000017500000000433511730525501027207 0ustar ebourgebourgpackage org.bouncycastle.util.io.pem.test; import java.io.ByteArrayOutputStream; import java.io.IOException; import java.io.OutputStreamWriter; import java.util.ArrayList; import java.util.Collections; import java.util.List; import junit.framework.Test; import junit.framework.TestCase; import junit.framework.TestSuite; import org.bouncycastle.util.io.pem.PemHeader; import org.bouncycastle.util.io.pem.PemObject; import org.bouncycastle.util.io.pem.PemWriter; public class AllTests extends TestCase { public void testPemLength() throws IOException { for (int i = 1; i != 60; i++) { lengthTest("CERTIFICATE", Collections.EMPTY_LIST, new byte[i]); } lengthTest("CERTIFICATE", Collections.EMPTY_LIST, new byte[100]); lengthTest("CERTIFICATE", Collections.EMPTY_LIST, new byte[101]); lengthTest("CERTIFICATE", Collections.EMPTY_LIST, new byte[102]); lengthTest("CERTIFICATE", Collections.EMPTY_LIST, new byte[103]); lengthTest("CERTIFICATE", Collections.EMPTY_LIST, new byte[1000]); lengthTest("CERTIFICATE", Collections.EMPTY_LIST, new byte[1001]); lengthTest("CERTIFICATE", Collections.EMPTY_LIST, new byte[1002]); lengthTest("CERTIFICATE", Collections.EMPTY_LIST, new byte[1003]); List headers = new ArrayList(); headers.add(new PemHeader("Proc-Type", "4,ENCRYPTED")); headers.add(new PemHeader("DEK-Info", "DES3,0001020304050607")); lengthTest("RSA PRIVATE KEY", headers, new byte[103]); } private void lengthTest(String type, List headers, byte[] data) throws IOException { ByteArrayOutputStream bOut = new ByteArrayOutputStream(); PemWriter pWrt = new PemWriter(new OutputStreamWriter(bOut)); PemObject pemObj = new PemObject(type, headers, data); pWrt.writeObject(pemObj); pWrt.close(); assertEquals(bOut.toByteArray().length, pWrt.getOutputSize(pemObj)); } public static void main (String[] args) { junit.textui.TestRunner.run (suite()); } public static Test suite() { TestSuite suite = new TestSuite("util tests"); suite.addTestSuite(AllTests.class); return suite; } }bouncycastle-1.49.orig/test/src/org/bouncycastle/cert/0000755000175000017500000000000012152033550022412 5ustar ebourgebourgbouncycastle-1.49.orig/test/src/org/bouncycastle/cert/crmf/0000755000175000017500000000000012152033550023341 5ustar ebourgebourgbouncycastle-1.49.orig/test/src/org/bouncycastle/cert/crmf/test/0000755000175000017500000000000012152033550024320 5ustar ebourgebourgbouncycastle-1.49.orig/test/src/org/bouncycastle/cert/crmf/test/AllTests.java0000644000175000017500000004043500000000433026703 0ustar ebourgebourgpackage org.bouncycastle.cert.crmf.test; import java.io.IOException; import java.math.BigInteger; import java.security.GeneralSecurityException; import java.security.KeyPair; import java.security.KeyPairGenerator; import java.security.PrivateKey; import java.security.PublicKey; import java.security.SecureRandom; import java.security.Security; import java.security.cert.X509Certificate; import java.security.interfaces.RSAPublicKey; import java.util.Date; import javax.security.auth.x500.X500Principal; import junit.framework.Test; import junit.framework.TestCase; import junit.framework.TestSuite; import org.bouncycastle.asn1.ASN1ObjectIdentifier; import org.bouncycastle.asn1.crmf.CRMFObjectIdentifiers; import org.bouncycastle.asn1.crmf.EncKeyWithID; import org.bouncycastle.asn1.crmf.EncryptedValue; import org.bouncycastle.asn1.x500.X500Name; import org.bouncycastle.asn1.x509.GeneralName; import org.bouncycastle.cert.X509CertificateHolder; import org.bouncycastle.cert.X509v1CertificateBuilder; import org.bouncycastle.cert.crmf.EncryptedValueBuilder; import org.bouncycastle.cert.crmf.EncryptedValuePadder; import org.bouncycastle.cert.crmf.EncryptedValueParser; import org.bouncycastle.cert.crmf.FixedLengthMGF1Padder; import org.bouncycastle.cert.crmf.PKIArchiveControl; import org.bouncycastle.cert.crmf.PKMACBuilder; import org.bouncycastle.cert.crmf.ValueDecryptorGenerator; import org.bouncycastle.cert.crmf.jcajce.JcaCertificateRequestMessage; import org.bouncycastle.cert.crmf.jcajce.JcaCertificateRequestMessageBuilder; import org.bouncycastle.cert.crmf.jcajce.JcaEncryptedValueBuilder; import org.bouncycastle.cert.crmf.jcajce.JcaPKIArchiveControlBuilder; import org.bouncycastle.cert.crmf.jcajce.JceAsymmetricValueDecryptorGenerator; import org.bouncycastle.cert.crmf.jcajce.JceCRMFEncryptorBuilder; import org.bouncycastle.cert.crmf.jcajce.JcePKMACValuesCalculator; import org.bouncycastle.cert.jcajce.JcaX509CertificateConverter; import org.bouncycastle.cert.jcajce.JcaX509v1CertificateBuilder; import org.bouncycastle.cms.CMSAlgorithm; import org.bouncycastle.cms.CMSEnvelopedDataGenerator; import org.bouncycastle.cms.RecipientId; import org.bouncycastle.cms.RecipientInformation; import org.bouncycastle.cms.RecipientInformationStore; import org.bouncycastle.cms.jcajce.JceCMSContentEncryptorBuilder; import org.bouncycastle.cms.jcajce.JceKeyTransEnvelopedRecipient; import org.bouncycastle.cms.jcajce.JceKeyTransRecipientId; import org.bouncycastle.cms.jcajce.JceKeyTransRecipientInfoGenerator; import org.bouncycastle.jce.provider.BouncyCastleProvider; import org.bouncycastle.operator.OperatorCreationException; import org.bouncycastle.operator.jcajce.JcaContentSignerBuilder; import org.bouncycastle.operator.jcajce.JcaContentVerifierProviderBuilder; import org.bouncycastle.operator.jcajce.JceAsymmetricKeyWrapper; import org.bouncycastle.util.Arrays; public class AllTests extends TestCase { private static final byte[] TEST_DATA = "Hello world!".getBytes(); private static final String BC = BouncyCastleProvider.PROVIDER_NAME; private static final String PASSPHRASE = "hello world"; /* * * INFRASTRUCTURE * */ public AllTests(String name) { super(name); } public static void main(String args[]) { junit.textui.TestRunner.run(AllTests.class); } public static Test suite() { return new TestSuite(AllTests.class); } public void setUp() { Security.addProvider(new BouncyCastleProvider()); } public void tearDown() { } public void testBasicMessageWithArchiveControl() throws Exception { KeyPairGenerator kGen = KeyPairGenerator.getInstance("RSA", BC); kGen.initialize(512); KeyPair kp = kGen.generateKeyPair(); X509Certificate cert = makeV1Certificate(kp, "CN=Test", kp, "CN=Test"); JcaCertificateRequestMessageBuilder certReqBuild = new JcaCertificateRequestMessageBuilder(BigInteger.ONE); certReqBuild.setSubject(new X500Principal("CN=Test")) .setPublicKey(kp.getPublic()); certReqBuild.addControl(new JcaPKIArchiveControlBuilder(kp.getPrivate(), new X500Principal("CN=Test")) .addRecipientGenerator(new JceKeyTransRecipientInfoGenerator(cert).setProvider(BC)) .build(new JceCMSContentEncryptorBuilder(new ASN1ObjectIdentifier(CMSEnvelopedDataGenerator.AES128_CBC)).setProvider(BC).build())); JcaCertificateRequestMessage certReqMsg = new JcaCertificateRequestMessage(certReqBuild.build()); assertEquals(new X500Principal("CN=Test"), certReqMsg.getSubjectX500Principal()); assertEquals(kp.getPublic(), certReqMsg.getPublicKey()); PKIArchiveControl archiveControl = (PKIArchiveControl)certReqMsg.getControl(CRMFObjectIdentifiers.id_regCtrl_pkiArchiveOptions); assertEquals(PKIArchiveControl.encryptedPrivKey, archiveControl.getArchiveType()); assertTrue(archiveControl.isEnvelopedData()); RecipientInformationStore recips = archiveControl.getEnvelopedData().getRecipientInfos(); RecipientId recipientId = new JceKeyTransRecipientId(cert); RecipientInformation recipientInformation = recips.get(recipientId); assertNotNull(recipientInformation); EncKeyWithID encKeyWithID = EncKeyWithID.getInstance(recipientInformation.getContent(new JceKeyTransEnvelopedRecipient(kp.getPrivate()).setProvider(BC))); assertTrue(encKeyWithID.hasIdentifier()); assertFalse(encKeyWithID.isIdentifierUTF8String()); assertEquals(new GeneralName(X500Name.getInstance(new X500Principal("CN=Test").getEncoded())), encKeyWithID.getIdentifier()); assertTrue(Arrays.areEqual(kp.getPrivate().getEncoded(), encKeyWithID.getPrivateKey().getEncoded())); } public void testProofOfPossessionWithoutSender() throws Exception { KeyPairGenerator kGen = KeyPairGenerator.getInstance("RSA", BC); kGen.initialize(512); KeyPair kp = kGen.generateKeyPair(); X509Certificate cert = makeV1Certificate(kp, "CN=Test", kp, "CN=Test"); JcaCertificateRequestMessageBuilder certReqBuild = new JcaCertificateRequestMessageBuilder(BigInteger.ONE); certReqBuild.setPublicKey(kp.getPublic()) .setAuthInfoPKMAC(new PKMACBuilder(new JcePKMACValuesCalculator()), "fred".toCharArray()) .setProofOfPossessionSigningKeySigner(new JcaContentSignerBuilder("SHA1withRSA").setProvider(BC).build(kp.getPrivate())); certReqBuild.addControl(new JcaPKIArchiveControlBuilder(kp.getPrivate(), new X500Principal("CN=test")) .addRecipientGenerator(new JceKeyTransRecipientInfoGenerator(cert).setProvider(BC)) .build(new JceCMSContentEncryptorBuilder(new ASN1ObjectIdentifier(CMSEnvelopedDataGenerator.AES128_CBC)).setProvider(BC).build())); JcaCertificateRequestMessage certReqMsg = new JcaCertificateRequestMessage(certReqBuild.build().getEncoded()); // check that internal check on popo signing is working okay try { certReqMsg.isValidSigningKeyPOP(new JcaContentVerifierProviderBuilder().setProvider(BC).build(kp.getPublic())); fail("IllegalStateException not thrown"); } catch (IllegalStateException e) { // ignore } assertTrue(certReqMsg.isValidSigningKeyPOP(new JcaContentVerifierProviderBuilder().setProvider(BC).build(kp.getPublic()), new PKMACBuilder(new JcePKMACValuesCalculator().setProvider(BC)), "fred".toCharArray())); assertEquals(kp.getPublic(), certReqMsg.getPublicKey()); } public void testProofOfPossessionWithSender() throws Exception { KeyPairGenerator kGen = KeyPairGenerator.getInstance("RSA", BC); kGen.initialize(512); KeyPair kp = kGen.generateKeyPair(); X509Certificate cert = makeV1Certificate(kp, "CN=Test", kp, "CN=Test"); JcaCertificateRequestMessageBuilder certReqBuild = new JcaCertificateRequestMessageBuilder(BigInteger.ONE); certReqBuild.setPublicKey(kp.getPublic()) .setAuthInfoSender(new X500Principal("CN=Test")) .setProofOfPossessionSigningKeySigner(new JcaContentSignerBuilder("SHA1withRSA").setProvider(BC).build(kp.getPrivate())); certReqBuild.addControl(new JcaPKIArchiveControlBuilder(kp.getPrivate(), new X500Principal("CN=test")) .addRecipientGenerator(new JceKeyTransRecipientInfoGenerator(cert).setProvider(BC)) .build(new JceCMSContentEncryptorBuilder(new ASN1ObjectIdentifier(CMSEnvelopedDataGenerator.AES128_CBC)).setProvider(BC).build())); JcaCertificateRequestMessage certReqMsg = new JcaCertificateRequestMessage(certReqBuild.build().getEncoded()); // check that internal check on popo signing is working okay try { certReqMsg.isValidSigningKeyPOP(new JcaContentVerifierProviderBuilder().setProvider(BC).build(kp.getPublic()), new PKMACBuilder(new JcePKMACValuesCalculator().setProvider(BC)), "fred".toCharArray()); fail("IllegalStateException not thrown"); } catch (IllegalStateException e) { // ignore } assertTrue(certReqMsg.isValidSigningKeyPOP(new JcaContentVerifierProviderBuilder().setProvider(BC).build(kp.getPublic()))); assertEquals(kp.getPublic(), certReqMsg.getPublicKey()); } public void testProofOfPossessionWithTemplate() throws Exception { KeyPairGenerator kGen = KeyPairGenerator.getInstance("RSA", BC); kGen.initialize(512); KeyPair kp = kGen.generateKeyPair(); X509Certificate cert = makeV1Certificate(kp, "CN=Test", kp, "CN=Test"); JcaCertificateRequestMessageBuilder certReqBuild = new JcaCertificateRequestMessageBuilder(BigInteger.ONE); certReqBuild.setPublicKey(kp.getPublic()) .setSubject(new X500Principal("CN=Test")) .setAuthInfoSender(new X500Principal("CN=Test")) .setProofOfPossessionSigningKeySigner(new JcaContentSignerBuilder("SHA1withRSA").setProvider(BC).build(kp.getPrivate())); certReqBuild.addControl(new JcaPKIArchiveControlBuilder(kp.getPrivate(), new X500Principal("CN=test")) .addRecipientGenerator(new JceKeyTransRecipientInfoGenerator(cert).setProvider(BC)) .build(new JceCMSContentEncryptorBuilder(new ASN1ObjectIdentifier(CMSEnvelopedDataGenerator.AES128_CBC)).setProvider(BC).build())); JcaCertificateRequestMessage certReqMsg = new JcaCertificateRequestMessage(certReqBuild.build().getEncoded()); assertTrue(certReqMsg.isValidSigningKeyPOP(new JcaContentVerifierProviderBuilder().setProvider(BC).build(kp.getPublic()))); assertEquals(kp.getPublic(), certReqMsg.getPublicKey()); } public void testEncryptedValue() throws Exception { KeyPairGenerator kGen = KeyPairGenerator.getInstance("RSA", BC); kGen.initialize(512); KeyPair kp = kGen.generateKeyPair(); X509Certificate cert = makeV1Certificate(kp, "CN=Test", kp, "CN=Test"); JcaEncryptedValueBuilder build = new JcaEncryptedValueBuilder(new JceAsymmetricKeyWrapper(cert.getPublicKey()).setProvider(BC), new JceCRMFEncryptorBuilder(CMSAlgorithm.AES128_CBC).setProvider(BC).build()); EncryptedValue value = build.build(cert); ValueDecryptorGenerator decGen = new JceAsymmetricValueDecryptorGenerator(kp.getPrivate()).setProvider(BC); // try direct encryptedValueParserTest(value, decGen, cert); // try indirect encryptedValueParserTest(EncryptedValue.getInstance(value.getEncoded()), decGen, cert); } private void encryptedValueParserTest(EncryptedValue value, ValueDecryptorGenerator decGen, X509Certificate cert) throws Exception { EncryptedValueParser parser = new EncryptedValueParser(value); X509CertificateHolder holder = parser.readCertificateHolder(decGen); assertTrue(Arrays.areEqual(cert.getEncoded(), holder.getEncoded())); } public void testEncryptedValuePassphrase() throws Exception { char[] passphrase = PASSPHRASE.toCharArray(); KeyPairGenerator kGen = KeyPairGenerator.getInstance("RSA", BC); kGen.initialize(512); KeyPair kp = kGen.generateKeyPair(); X509Certificate cert = makeV1Certificate(kp, "CN=Test", kp, "CN=Test"); EncryptedValueBuilder build = new EncryptedValueBuilder(new JceAsymmetricKeyWrapper(cert.getPublicKey()).setProvider(BC), new JceCRMFEncryptorBuilder(CMSAlgorithm.AES128_CBC).setProvider(BC).build()); EncryptedValue value = build.build(passphrase); ValueDecryptorGenerator decGen = new JceAsymmetricValueDecryptorGenerator(kp.getPrivate()).setProvider(BC); // try direct encryptedValuePassphraseParserTest(value, null, decGen, cert); // try indirect encryptedValuePassphraseParserTest(EncryptedValue.getInstance(value.getEncoded()), null, decGen, cert); } public void testEncryptedValuePassphraseWithPadding() throws Exception { char[] passphrase = PASSPHRASE.toCharArray(); KeyPairGenerator kGen = KeyPairGenerator.getInstance("RSA", BC); kGen.initialize(512); KeyPair kp = kGen.generateKeyPair(); X509Certificate cert = makeV1Certificate(kp, "CN=Test", kp, "CN=Test"); FixedLengthMGF1Padder mgf1Padder = new FixedLengthMGF1Padder(200, new SecureRandom()); EncryptedValueBuilder build = new EncryptedValueBuilder(new JceAsymmetricKeyWrapper(cert.getPublicKey()).setProvider(BC), new JceCRMFEncryptorBuilder(CMSAlgorithm.AES128_CBC).setProvider(BC).build(), mgf1Padder); EncryptedValue value = build.build(passphrase); ValueDecryptorGenerator decGen = new JceAsymmetricValueDecryptorGenerator(kp.getPrivate()).setProvider(BC); // try direct encryptedValuePassphraseParserTest(value, mgf1Padder, decGen, cert); // try indirect encryptedValuePassphraseParserTest(EncryptedValue.getInstance(value.getEncoded()), mgf1Padder, decGen, cert); } private void encryptedValuePassphraseParserTest(EncryptedValue value, EncryptedValuePadder padder, ValueDecryptorGenerator decGen, X509Certificate cert) throws Exception { EncryptedValueParser parser = new EncryptedValueParser(value, padder); assertTrue(Arrays.areEqual(PASSPHRASE.toCharArray(), parser.readPassphrase(decGen))); } private static X509Certificate makeV1Certificate(KeyPair subKP, String _subDN, KeyPair issKP, String _issDN) throws GeneralSecurityException, IOException, OperatorCreationException { PublicKey subPub = subKP.getPublic(); PrivateKey issPriv = issKP.getPrivate(); PublicKey issPub = issKP.getPublic(); X509v1CertificateBuilder v1CertGen = new JcaX509v1CertificateBuilder( new X500Name(_issDN), BigInteger.valueOf(System.currentTimeMillis()), new Date(System.currentTimeMillis()), new Date(System.currentTimeMillis() + (1000L * 60 * 60 * 24 * 100)), new X500Name(_subDN), subPub); JcaContentSignerBuilder signerBuilder = null; if (issPub instanceof RSAPublicKey) { signerBuilder = new JcaContentSignerBuilder("SHA1WithRSA"); } else if (issPub.getAlgorithm().equals("DSA")) { signerBuilder = new JcaContentSignerBuilder("SHA1withDSA"); } else if (issPub.getAlgorithm().equals("ECDSA")) { signerBuilder = new JcaContentSignerBuilder("SHA1withECDSA"); } else if (issPub.getAlgorithm().equals("ECGOST3410")) { signerBuilder = new JcaContentSignerBuilder("GOST3411withECGOST3410"); } else { signerBuilder = new JcaContentSignerBuilder("GOST3411WithGOST3410"); } signerBuilder.setProvider(BC); X509Certificate _cert = new JcaX509CertificateConverter().setProvider(BC).getCertificate(v1CertGen.build(signerBuilder.build(issPriv))); _cert.checkValidity(new Date()); _cert.verify(issPub); return _cert; } }bouncycastle-1.49.orig/test/src/org/bouncycastle/cert/cmp/0000755000175000017500000000000012152033550023171 5ustar ebourgebourgbouncycastle-1.49.orig/test/src/org/bouncycastle/cert/cmp/test/0000755000175000017500000000000012152033550024150 5ustar ebourgebourgbouncycastle-1.49.orig/test/src/org/bouncycastle/cert/cmp/test/AllTests.java0000644000175000017500000002615111741216474026566 0ustar ebourgebourgpackage org.bouncycastle.cert.cmp.test; import java.io.FileInputStream; import java.io.IOException; import java.math.BigInteger; import java.security.GeneralSecurityException; import java.security.KeyPair; import java.security.KeyPairGenerator; import java.security.PrivateKey; import java.security.PublicKey; import java.security.Security; import java.security.cert.X509Certificate; import java.util.Date; import junit.framework.Test; import junit.framework.TestCase; import junit.framework.TestSuite; import org.bouncycastle.asn1.ASN1Primitive; import org.bouncycastle.asn1.DERSequence; import org.bouncycastle.asn1.cmp.CertConfirmContent; import org.bouncycastle.asn1.cmp.CertRepMessage; import org.bouncycastle.asn1.cmp.PKIBody; import org.bouncycastle.asn1.cmp.PKIMessage; import org.bouncycastle.asn1.crmf.CertReqMessages; import org.bouncycastle.asn1.crmf.CertReqMsg; import org.bouncycastle.asn1.crmf.ProofOfPossession; import org.bouncycastle.asn1.crmf.SubsequentMessage; import org.bouncycastle.asn1.x500.X500Name; import org.bouncycastle.asn1.x509.GeneralName; import org.bouncycastle.cert.CertException; import org.bouncycastle.cert.X509CertificateHolder; import org.bouncycastle.cert.X509v3CertificateBuilder; import org.bouncycastle.cert.cmp.CertificateConfirmationContent; import org.bouncycastle.cert.cmp.CertificateConfirmationContentBuilder; import org.bouncycastle.cert.cmp.CertificateStatus; import org.bouncycastle.cert.cmp.GeneralPKIMessage; import org.bouncycastle.cert.cmp.ProtectedPKIMessage; import org.bouncycastle.cert.cmp.ProtectedPKIMessageBuilder; import org.bouncycastle.cert.crmf.CertificateRequestMessageBuilder; import org.bouncycastle.cert.crmf.PKMACBuilder; import org.bouncycastle.cert.crmf.jcajce.JcaCertificateRequestMessageBuilder; import org.bouncycastle.cert.crmf.jcajce.JcePKMACValuesCalculator; import org.bouncycastle.cert.jcajce.JcaX509CertificateConverter; import org.bouncycastle.cert.jcajce.JcaX509v3CertificateBuilder; import org.bouncycastle.jce.provider.BouncyCastleProvider; import org.bouncycastle.operator.ContentSigner; import org.bouncycastle.operator.ContentVerifierProvider; import org.bouncycastle.operator.OperatorCreationException; import org.bouncycastle.operator.jcajce.JcaContentSignerBuilder; import org.bouncycastle.operator.jcajce.JcaContentVerifierProviderBuilder; import org.bouncycastle.operator.jcajce.JcaDigestCalculatorProviderBuilder; import org.bouncycastle.util.io.Streams; public class AllTests extends TestCase { private static final byte[] TEST_DATA = "Hello world!".getBytes(); private static final String BC = BouncyCastleProvider.PROVIDER_NAME; private static final String TEST_DATA_HOME = "bc.test.data.home"; /* * * INFRASTRUCTURE * */ public AllTests(String name) { super(name); } public static void main(String args[]) { junit.textui.TestRunner.run(AllTests.class); } public static Test suite() { return new TestSuite(AllTests.class); } public void setUp() { Security.addProvider(new BouncyCastleProvider()); } public void tearDown() { } public void testProtectedMessage() throws Exception { KeyPairGenerator kGen = KeyPairGenerator.getInstance("RSA", BC); kGen.initialize(512); KeyPair kp = kGen.generateKeyPair(); X509CertificateHolder cert = makeV3Certificate(kp, "CN=Test", kp, "CN=Test"); GeneralName sender = new GeneralName(new X500Name("CN=Sender")); GeneralName recipient = new GeneralName(new X500Name("CN=Recip")); ContentSigner signer = new JcaContentSignerBuilder("MD5WithRSAEncryption").setProvider(BC).build(kp.getPrivate()); ProtectedPKIMessage message = new ProtectedPKIMessageBuilder(sender, recipient) .setBody(new PKIBody(PKIBody.TYPE_INIT_REP, CertRepMessage.getInstance(new DERSequence(new DERSequence())))) .addCMPCertificate(cert) .build(signer); X509Certificate jcaCert = new JcaX509CertificateConverter().setProvider(BC).getCertificate(message.getCertificates()[0]); ContentVerifierProvider verifierProvider = new JcaContentVerifierProviderBuilder().setProvider(BC).build(jcaCert.getPublicKey()); assertTrue(message.verify(verifierProvider)); assertEquals(sender, message.getHeader().getSender()); assertEquals(recipient, message.getHeader().getRecipient()); } public void testMacProtectedMessage() throws Exception { KeyPairGenerator kGen = KeyPairGenerator.getInstance("RSA", BC); kGen.initialize(512); KeyPair kp = kGen.generateKeyPair(); X509CertificateHolder cert = makeV3Certificate(kp, "CN=Test", kp, "CN=Test"); GeneralName sender = new GeneralName(new X500Name("CN=Sender")); GeneralName recipient = new GeneralName(new X500Name("CN=Recip")); ProtectedPKIMessage message = new ProtectedPKIMessageBuilder(sender, recipient) .setBody(new PKIBody(PKIBody.TYPE_INIT_REP, CertRepMessage.getInstance(new DERSequence(new DERSequence())))) .addCMPCertificate(cert) .build(new PKMACBuilder(new JcePKMACValuesCalculator().setProvider(BC)).build("secret".toCharArray())); PKMACBuilder pkMacBuilder = new PKMACBuilder(new JcePKMACValuesCalculator().setProvider(BC)); assertTrue(message.verify(pkMacBuilder, "secret".toCharArray())); assertEquals(sender, message.getHeader().getSender()); assertEquals(recipient, message.getHeader().getRecipient()); } public void testConfirmationMessage() throws Exception { KeyPairGenerator kGen = KeyPairGenerator.getInstance("RSA", BC); kGen.initialize(512); KeyPair kp = kGen.generateKeyPair(); X509CertificateHolder cert = makeV3Certificate(kp, "CN=Test", kp, "CN=Test"); GeneralName sender = new GeneralName(new X500Name("CN=Sender")); GeneralName recipient = new GeneralName(new X500Name("CN=Recip")); CertificateConfirmationContent content = new CertificateConfirmationContentBuilder() .addAcceptedCertificate(cert, BigInteger.valueOf(1)) .build(new JcaDigestCalculatorProviderBuilder().build()); ContentSigner signer = new JcaContentSignerBuilder("MD5WithRSAEncryption").setProvider(BC).build(kp.getPrivate()); ProtectedPKIMessage message = new ProtectedPKIMessageBuilder(sender, recipient) .setBody(new PKIBody(PKIBody.TYPE_CERT_CONFIRM, content.toASN1Structure())) .addCMPCertificate(cert) .build(signer); X509Certificate jcaCert = new JcaX509CertificateConverter().setProvider(BC).getCertificate(message.getCertificates()[0]); ContentVerifierProvider verifierProvider = new JcaContentVerifierProviderBuilder().setProvider(BC).build(jcaCert.getPublicKey()); assertTrue(message.verify(verifierProvider)); assertEquals(sender, message.getHeader().getSender()); assertEquals(recipient, message.getHeader().getRecipient()); content = new CertificateConfirmationContent(CertConfirmContent.getInstance(message.getBody().getContent())); CertificateStatus[] statusList = content.getStatusMessages(); assertEquals(1, statusList.length); assertTrue(statusList[0].isVerified(cert, new JcaDigestCalculatorProviderBuilder().setProvider(BC).build())); } public void testSampleCr() throws Exception { PKIMessage msg = loadMessage("sample_cr.der"); ProtectedPKIMessage procMsg = new ProtectedPKIMessage(new GeneralPKIMessage(msg)); assertTrue(procMsg.verify(new PKMACBuilder(new JcePKMACValuesCalculator().setProvider(BC)), "TopSecret1234".toCharArray())); } public void testSubsequentMessage() throws Exception { KeyPairGenerator kGen = KeyPairGenerator.getInstance("RSA", BC); kGen.initialize(512); KeyPair kp = kGen.generateKeyPair(); X509CertificateHolder cert = makeV3Certificate(kp, "CN=Test", kp, "CN=Test"); ContentSigner signer = new JcaContentSignerBuilder("SHA256withRSA").setProvider(BC).build( kp.getPrivate()); GeneralName user = new GeneralName(new X500Name("CN=Test")); CertificateRequestMessageBuilder builder = new JcaCertificateRequestMessageBuilder( BigInteger.valueOf(1)).setPublicKey(kp.getPublic()).setProofOfPossessionSubsequentMessage( SubsequentMessage.encrCert); ProtectedPKIMessage certRequestMsg = new ProtectedPKIMessageBuilder(user, user).setTransactionID(new byte[] { 1, 2, 3, 4, 5 }).setBody( new PKIBody(PKIBody.TYPE_KEY_UPDATE_REQ, new CertReqMessages(builder.build().toASN1Structure()))).addCMPCertificate( cert).build(signer); ProtectedPKIMessage msg = new ProtectedPKIMessage(new GeneralPKIMessage(certRequestMsg.toASN1Structure().getEncoded())); CertReqMessages reqMsgs = CertReqMessages.getInstance(msg.getBody().getContent()); CertReqMsg reqMsg = reqMsgs.toCertReqMsgArray()[0]; assertEquals(ProofOfPossession.TYPE_KEY_ENCIPHERMENT, reqMsg.getPopo().getType()); } private static X509CertificateHolder makeV3Certificate(KeyPair subKP, String _subDN, KeyPair issKP, String _issDN) throws GeneralSecurityException, IOException, OperatorCreationException, CertException { PublicKey subPub = subKP.getPublic(); PrivateKey issPriv = issKP.getPrivate(); PublicKey issPub = issKP.getPublic(); X509v3CertificateBuilder v1CertGen = new JcaX509v3CertificateBuilder( new X500Name(_issDN), BigInteger.valueOf(System.currentTimeMillis()), new Date(System.currentTimeMillis()), new Date(System.currentTimeMillis() + (1000L * 60 * 60 * 24 * 100)), new X500Name(_subDN), subPub); ContentSigner signer = new JcaContentSignerBuilder("SHA1WithRSA").setProvider(BC).build(issPriv); X509CertificateHolder certHolder = v1CertGen.build(signer); ContentVerifierProvider verifier = new JcaContentVerifierProviderBuilder().setProvider(BC).build(issPub); assertTrue(certHolder.isSignatureValid(verifier)); return certHolder; } private static PKIMessage loadMessage(String name) { String dataHome = System.getProperty(TEST_DATA_HOME); if (dataHome == null) { throw new IllegalStateException(TEST_DATA_HOME + " property not set"); } try { return PKIMessage.getInstance(ASN1Primitive.fromByteArray(Streams.readAll(new FileInputStream(dataHome + "/cmp/" + name)))); } catch (IOException e) { throw new RuntimeException(e.toString()); } } }bouncycastle-1.49.orig/test/src/org/bouncycastle/cert/ocsp/0000755000175000017500000000000012152033550023356 5ustar ebourgebourgbouncycastle-1.49.orig/test/src/org/bouncycastle/cert/ocsp/test/0000755000175000017500000000000012152033550024335 5ustar ebourgebourgbouncycastle-1.49.orig/test/src/org/bouncycastle/cert/ocsp/test/OCSPTest.java0000644000175000017500000011311412143623010026601 0ustar ebourgebourgpackage org.bouncycastle.cert.ocsp.test; import java.io.IOException; import java.math.BigInteger; import java.security.KeyPair; import java.security.Security; import java.util.Date; import java.util.Random; import java.util.Set; import java.util.Vector; import org.bouncycastle.asn1.ASN1Encodable; import org.bouncycastle.asn1.ASN1Exception; import org.bouncycastle.asn1.ASN1OctetString; import org.bouncycastle.asn1.DEROctetString; import org.bouncycastle.asn1.ocsp.OCSPObjectIdentifiers; import org.bouncycastle.asn1.x509.Extension; import org.bouncycastle.asn1.x509.ExtensionsGenerator; import org.bouncycastle.asn1.x509.GeneralName; import org.bouncycastle.asn1.x509.X509Name; import org.bouncycastle.cert.CertIOException; import org.bouncycastle.cert.X509CertificateHolder; import org.bouncycastle.cert.jcajce.JcaX509CertificateHolder; import org.bouncycastle.cert.ocsp.BasicOCSPResp; import org.bouncycastle.cert.ocsp.BasicOCSPRespBuilder; import org.bouncycastle.cert.ocsp.CertificateID; import org.bouncycastle.cert.ocsp.CertificateStatus; import org.bouncycastle.cert.ocsp.OCSPReq; import org.bouncycastle.cert.ocsp.OCSPReqBuilder; import org.bouncycastle.cert.ocsp.OCSPResp; import org.bouncycastle.cert.ocsp.OCSPRespBuilder; import org.bouncycastle.cert.ocsp.Req; import org.bouncycastle.cert.ocsp.RespID; import org.bouncycastle.cert.ocsp.SingleResp; import org.bouncycastle.cert.ocsp.jcajce.JcaBasicOCSPRespBuilder; import org.bouncycastle.jce.X509Principal; import org.bouncycastle.jce.provider.BouncyCastleProvider; import org.bouncycastle.ocsp.test.OCSPTestUtil; import org.bouncycastle.operator.DigestCalculatorProvider; import org.bouncycastle.operator.jcajce.JcaContentSignerBuilder; import org.bouncycastle.operator.jcajce.JcaContentVerifierProviderBuilder; import org.bouncycastle.operator.jcajce.JcaDigestCalculatorProviderBuilder; import org.bouncycastle.util.encoders.Base64; import org.bouncycastle.util.test.SimpleTest; public class OCSPTest extends SimpleTest { byte[] testResp1 = Base64.decode( "MIIFnAoBAKCCBZUwggWRBgkrBgEFBQcwAQEEggWCMIIFfjCCARehgZ8wgZwx" + "CzAJBgNVBAYTAklOMRcwFQYDVQQIEw5BbmRocmEgcHJhZGVzaDESMBAGA1UE" + "BxMJSHlkZXJhYmFkMQwwCgYDVQQKEwNUQ1MxDDAKBgNVBAsTA0FUQzEeMBwG" + "A1UEAxMVVENTLUNBIE9DU1AgUmVzcG9uZGVyMSQwIgYJKoZIhvcNAQkBFhVv" + "Y3NwQHRjcy1jYS50Y3MuY28uaW4YDzIwMDMwNDAyMTIzNDU4WjBiMGAwOjAJ" + "BgUrDgMCGgUABBRs07IuoCWNmcEl1oHwIak1BPnX8QQUtGyl/iL9WJ1VxjxF" + "j0hAwJ/s1AcCAQKhERgPMjAwMjA4MjkwNzA5MjZaGA8yMDAzMDQwMjEyMzQ1" + "OFowDQYJKoZIhvcNAQEFBQADgYEAfbN0TCRFKdhsmvOdUoiJ+qvygGBzDxD/" + "VWhXYA+16AphHLIWNABR3CgHB3zWtdy2j7DJmQ/R7qKj7dUhWLSqclAiPgFt" + "QQ1YvSJAYfEIdyHkxv4NP0LSogxrumANcDyC9yt/W9yHjD2ICPBIqCsZLuLk" + "OHYi5DlwWe9Zm9VFwCGgggPMMIIDyDCCA8QwggKsoAMCAQICAQYwDQYJKoZI" + "hvcNAQEFBQAwgZQxFDASBgNVBAMTC1RDUy1DQSBPQ1NQMSYwJAYJKoZIhvcN" + "AQkBFhd0Y3MtY2FAdGNzLWNhLnRjcy5jby5pbjEMMAoGA1UEChMDVENTMQww" + "CgYDVQQLEwNBVEMxEjAQBgNVBAcTCUh5ZGVyYWJhZDEXMBUGA1UECBMOQW5k" + "aHJhIHByYWRlc2gxCzAJBgNVBAYTAklOMB4XDTAyMDgyOTA3MTE0M1oXDTAz" + "MDgyOTA3MTE0M1owgZwxCzAJBgNVBAYTAklOMRcwFQYDVQQIEw5BbmRocmEg" + "cHJhZGVzaDESMBAGA1UEBxMJSHlkZXJhYmFkMQwwCgYDVQQKEwNUQ1MxDDAK" + "BgNVBAsTA0FUQzEeMBwGA1UEAxMVVENTLUNBIE9DU1AgUmVzcG9uZGVyMSQw" + "IgYJKoZIhvcNAQkBFhVvY3NwQHRjcy1jYS50Y3MuY28uaW4wgZ8wDQYJKoZI" + "hvcNAQEBBQADgY0AMIGJAoGBAM+XWW4caMRv46D7L6Bv8iwtKgmQu0SAybmF" + "RJiz12qXzdvTLt8C75OdgmUomxp0+gW/4XlTPUqOMQWv463aZRv9Ust4f8MH" + "EJh4ekP/NS9+d8vEO3P40ntQkmSMcFmtA9E1koUtQ3MSJlcs441JjbgUaVnm" + "jDmmniQnZY4bU3tVAgMBAAGjgZowgZcwDAYDVR0TAQH/BAIwADALBgNVHQ8E" + "BAMCB4AwEwYDVR0lBAwwCgYIKwYBBQUHAwkwNgYIKwYBBQUHAQEEKjAoMCYG" + "CCsGAQUFBzABhhpodHRwOi8vMTcyLjE5LjQwLjExMDo3NzAwLzAtBgNVHR8E" + "JjAkMCKgIKAehhxodHRwOi8vMTcyLjE5LjQwLjExMC9jcmwuY3JsMA0GCSqG" + "SIb3DQEBBQUAA4IBAQB6FovM3B4VDDZ15o12gnADZsIk9fTAczLlcrmXLNN4" + "PgmqgnwF0Ymj3bD5SavDOXxbA65AZJ7rBNAguLUo+xVkgxmoBH7R2sBxjTCc" + "r07NEadxM3HQkt0aX5XYEl8eRoifwqYAI9h0ziZfTNes8elNfb3DoPPjqq6V" + "mMg0f0iMS4W8LjNPorjRB+kIosa1deAGPhq0eJ8yr0/s2QR2/WFD5P4aXc8I" + "KWleklnIImS3zqiPrq6tl2Bm8DZj7vXlTOwmraSQxUwzCKwYob1yGvNOUQTq" + "pG6jxn7jgDawHU1+WjWQe4Q34/pWeGLysxTraMa+Ug9kPe+jy/qRX2xwvKBZ"); byte[] testResp2 = Base64.decode( "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" + "A5oyOoNv0w+8bbtMNEc1"); /** * extra version number encoding. */ private static byte[] irregReq = Base64.decode( "MIIQpTBUoAMCAQAwTTBLMEkwCQYFKw4DAhoFAAQUIcFvFFVjPem15pKox4cfcnzF" + "Kf4EFJf8OQzmVmyJ/hc4EhitQbXcqAzDAhB9ePsP19SuP6CsAgFwQuEAoIIQSzCC" + "EEcwDQYJKoZIhvcNAQEFBQADgYEAlq/Tjl8OtFM8Tib1JYTiaPy9vFDr8UZhqXJI" + "FyrdgtUyyDt0EcrgnBGacAeRZzF5sokIC6DjXweU7EItGqrpw/RaCUPUWFpPxR6y" + "HjuzrLmICocTI9MH7dRUXm0qpxoY987sx1PtWB4pSR99ixBtq3OPNdsI0uJ+Qkei" + "LbEZyvWggg+wMIIPrDCCA5owggKCoAMCAQICEEAxXx/eFe7gm/NX7AkcS68wDQYJ" + "KoZIhvcNAQEFBQAwgZoxCzAJBgNVBAYTAlNFMTMwMQYDVQQKDCpMw6Ruc2bDtnJz" + "w6RrcmluZ2FyIEJhbmsgQWt0aWVib2xhZyAocHVibCkxFTATBgNVBAUTDDExMTEx" + "MTExMTExMTE/MD0GA1UEAww2TMOkbnNmw7Zyc8Oka3JpbmdhciBCYW5rIFB1cmNo" + "YXNlciBDQTEgZm9yIEJhbmtJRCBURVNUMB4XDTA4MTAwNjIyMDAwMFoXDTEwMTAx" + "MDIxNTk1OVowgZExCzAJBgNVBAYTAlNFMTMwMQYDVQQKDCpMw6Ruc2bDtnJzw6Rr" + "cmluZ2FyIEJhbmsgQWt0aWVib2xhZyAocHVibCkxFTATBgNVBAUTDDExMTExMTEx" + "MTExMTE2MDQGA1UEAwwtTMOkbnNmw7Zyc8Oka3JpbmdhciBCYW5rIE9DU1AgZm9y" + "IEJhbmtJRCBURVNUMIGfMA0GCSqGSIb3DQEBAQUAA4GNADCBiQKBgQC5e/h6aL2m" + "DVpWeu5e5p1Ps9kbvuuGeAp9zJDYLbZz7uzT67X+s59HaViroD2+2my/gg7rX7tK" + "H9VXpJad1W9O19SjfNyxgeAMwVMkrbb4IlrQwu0v/Ub8JPxSWwZZXYiODq5abeXA" + "abMYIHxSaSkhrsUj1dpSAohHLJRlq707swIDAQABo2cwZTAfBgNVHSMEGDAWgBTR" + "vcp2QyNdNGZ+q7TjKSrrHZqxmDATBgNVHSAEDDAKMAgGBiqFcDwBBjAOBgNVHQ8B" + "Af8EBAMCBkAwHQYDVR0OBBYEFF/3557FEvkA8iiPv2XcBclxKnTdMA0GCSqGSIb3" + "DQEBBQUAA4IBAQAOxRvHO89XJ0v83BZdPFzEBA4B2Tqc1oABUn13S6fAkcGWvOmG" + "eY61MK16aMnLPNDadZrAqJc6PEtVY57uaywE9acwv9XpHO0bcS94tLwvZZJ2KBt0" + "Oq96gaI6gnJViUjyWjm+qBZvod0QPOLGv6wUPoiNcCpSid/COTjKpLYpCJj3ZWUV" + "nsTRWSRVXsdY/xI0gs/A8/c5P1PuTxoi99RTmcruoFxvV4MmhWyX7IGqG4OAtLdo" + "yefz/90FPGOrmqY9OgEb+gNuTM26YDvSs1dfarPl89d8jjwxHgNbZjh2VHFqKolJ" + "8TB8ZS5aNvhHPumOOE47y95rTBxrxSmGvKb8MIIENDCCAxygAwIBAgIRAJAFaeOw" + "7XbxH/DN/Vvhjx8wDQYJKoZIhvcNAQEFBQAwgZUxCzAJBgNVBAYTAlNFMTMwMQYD" + "VQQKDCpMw6Ruc2bDtnJzw6RrcmluZ2FyIEJhbmsgQWt0aWVib2xhZyAocHVibCkx" + "FTATBgNVBAUTDDExMTExMTExMTExMTE6MDgGA1UEAwwxTMOkbnNmw7Zyc8Oka3Jp" + "bmdhciBCYW5rIFJvb3QgQ0ExIGZvciBCYW5rSUQgVEVTVDAeFw0wNzEwMDExMjAw" + "MzdaFw0yOTA3MDExMjAwMzdaMIGaMQswCQYDVQQGEwJTRTEzMDEGA1UECgwqTMOk" + "bnNmw7Zyc8Oka3JpbmdhciBCYW5rIEFrdGllYm9sYWcgKHB1YmwpMRUwEwYDVQQF" + "EwwxMTExMTExMTExMTExPzA9BgNVBAMMNkzDpG5zZsO2cnPDpGtyaW5nYXIgQmFu" + "ayBQdXJjaGFzZXIgQ0ExIGZvciBCYW5rSUQgVEVTVDCCASIwDQYJKoZIhvcNAQEB" + "BQADggEPADCCAQoCggEBAMK5WbYojYRX1ZKrbxJBgbd4x503LfMWgr67sVD5L0NY" + "1RPhZVFJRKJWvawE5/eXJ4oNQwc831h2jiOgINXuKyGXqdAVGBcpFwIxTfzxwT4l" + "fvztr8pE6wk7mLLwKUvIjbM3EF1IL3zUI3UU/U5ioyGmcb/o4GGN71kMmvV/vrkU" + "02/s7xicXNxYej4ExLiCkS5+j/+3sR47Uq5cL9e8Yg7t5/6FyLGQjKoS8HU/abYN" + "4kpx/oyrxzrXMhnMVDiI8QX9NYGJwI8KZ/LU6GDq/NnZ3gG5v4l4UU1GhgUbrk4I" + "AZPDu99zvwCtkdj9lJN0eDv8jdyEPZ6g1qPBE0pCNqcCAwEAAaN4MHYwDwYDVR0T" + "AQH/BAUwAwEB/zATBgNVHSAEDDAKMAgGBiqFcDwBBjAOBgNVHQ8BAf8EBAMCAQYw" + "HwYDVR0jBBgwFoAUnkjp1bkQUOrkRiLgxpxwAe2GQFYwHQYDVR0OBBYEFNG9ynZD" + "I100Zn6rtOMpKusdmrGYMA0GCSqGSIb3DQEBBQUAA4IBAQAPVSC4HEd+yCtSgL0j" + "NI19U2hJeP28lAD7OA37bcLP7eNrvfU/2tuqY7rEn1m44fUbifewdgR8x2DzhM0m" + "fJcA5Z12PYUb85L9z8ewGQdyHLNlMpKSTP+0lebSc/obFbteC4jjuvux60y5KVOp" + "osXbGw2qyrS6uhZJrTDP1B+bYg/XBttG+i7Qzx0S5Tq//VU9OfAQZWpvejadKAk9" + "WCcXq6zALiJcxsUwOHZRvvHDxkHuf5eZpPvm1gaqa+G9CtV+oysZMU1eTRasBHsB" + "NRWYfOSXggsyqRHfIAVieB4VSsB8WhZYm8UgYoLhAQfSJ5Xq5cwBOHkVj33MxAyP" + "c7Y5MIID/zCCAuegAwIBAgIRAOXEoBcV4gV3Z92gk5AuRgwwDQYJKoZIhvcNAQEF" + "BQAwZjEkMCIGA1UECgwbRmluYW5zaWVsbCBJRC1UZWtuaWsgQklEIEFCMR8wHQYD" + "VQQLDBZCYW5rSUQgTWVtYmVyIEJhbmtzIENBMR0wGwYDVQQDDBRCYW5rSUQgUm9v" + "dCBDQSBURVNUMjAeFw0wNzEwMDExMTQ1NDlaFw0yOTA4MDExMTU4MjVaMIGVMQsw" + "CQYDVQQGEwJTRTEzMDEGA1UECgwqTMOkbnNmw7Zyc8Oka3JpbmdhciBCYW5rIEFr" + "dGllYm9sYWcgKHB1YmwpMRUwEwYDVQQFEwwxMTExMTExMTExMTExOjA4BgNVBAMM" + "MUzDpG5zZsO2cnPDpGtyaW5nYXIgQmFuayBSb290IENBMSBmb3IgQmFua0lEIFRF" + "U1QwggEiMA0GCSqGSIb3DQEBAQUAA4IBDwAwggEKAoIBAQDBzn7IXIpyOGCCTuzL" + "DKE/T+pFRTgFh3QgKtifZ4zxdvB2Sd5+90vUEGcGExUhzpgb9gOUrT1eE0XhdiUR" + "YuYYpJI/nzPQWTsRtEaql7NHBPKnEauoA9oAhCT4pE5gLlqpTfkB8nAsRTI2XqpI" + "hQ7vTvnTRx20xog21NIbz1GztV8H1kBH2eDvRX7cXGiugp6CXV/le9cB+/4TBNUN" + "Xqupt79dM49KCoDuYr72W7Hv4BSWw3IInEN2m8T2X6UBpBGkCiGwLQy/+KOmYRK7" + "1PSFC0rXDwOJ0HJ/8fHwx6vLMxHAQ6s/9vOW10MjgjSQlbVqH/4Pa+TlpWumSV4E" + "l0z9AgMBAAGjeDB2MA8GA1UdEwEB/wQFMAMBAf8wEwYDVR0gBAwwCjAIBgYqhXA8" + "AQYwDgYDVR0PAQH/BAQDAgEGMB8GA1UdIwQYMBaAFJuTMPljHcYdrRO9sEi1amb4" + "tE3VMB0GA1UdDgQWBBSeSOnVuRBQ6uRGIuDGnHAB7YZAVjANBgkqhkiG9w0BAQUF" + "AAOCAQEArnW/9n+G+84JOgv1Wn4tsBBS7QgJp1rdCoiNrZPx2du/7Wz3wQVNKBjL" + "eMCyLjg0OVHuq4hpCv9MZpUqdcUW8gpp4dLDAAd1uE7xqVuG8g4Ir5qocxbZHQew" + "fnqSJJDlEZgDeZIzod92OO+htv0MWqKWbr3Mo2Hqhn+t0+UVWsW4k44e7rUw3xQq" + "r2VdMJv/C68BXUgqh3pplUDjWyXfreiACTT0q3HT6v6WaihKCa2WY9Kd1IkDcLHb" + "TZk8FqMmGn72SgJw3H5Dvu7AiZijjNAUulMnMpxBEKyFTU2xRBlZZVcp50VJ2F7+" + "siisxbcYOAX4GztLMlcyq921Ov/ipDCCA88wggK3oAMCAQICEQCmaX+5+m5bF5us" + "CtyMq41SMA0GCSqGSIb3DQEBBQUAMGYxJDAiBgNVBAoMG0ZpbmFuc2llbGwgSUQt" + "VGVrbmlrIEJJRCBBQjEfMB0GA1UECwwWQmFua0lEIE1lbWJlciBCYW5rcyBDQTEd" + "MBsGA1UEAwwUQmFua0lEIFJvb3QgQ0EgVEVTVDIwHhcNMDQwODEzMDcyMDEwWhcN" + "MjkwODEyMTIwMjQ2WjBmMSQwIgYDVQQKDBtGaW5hbnNpZWxsIElELVRla25payBC" + "SUQgQUIxHzAdBgNVBAsMFkJhbmtJRCBNZW1iZXIgQmFua3MgQ0ExHTAbBgNVBAMM" + "FEJhbmtJRCBSb290IENBIFRFU1QyMIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIB" + "CgKCAQEA25D0f1gipbACk4Bg3t6ODUlCWOU0TWeTkzAHR7IRB5T++yvsVosedMMW" + "6KYYTbPONeJSt5kydX+wZi9nVNdlhkNULLbDKWfRY7x+B9MR1Q0Kq/e4VR0uRsak" + "Bv5iwEYZ7cSR63HfBaPTqQsGobq+wtGH5JeTBrmCt4A3kN1UWgX32Dv/I3m7v8bK" + "iwh4cnvAD9PIOtq6pOmAkSvLvp8jCy3qFLe9KAxm8M/ZAmnxYaRV8DVEg57FGoG6" + "oiG3Ixx8PSVVdzpFY4kuUFLi4ueMPwjnXFiBhhWJJeOtFG3Lc2aW3zvcDbD/MsDm" + "rSZNTmtbOOou8xuMKjlNY9PU5MHIaQIDAQABo3gwdjAPBgNVHRMBAf8EBTADAQH/" + "MBMGA1UdIAQMMAowCAYGKoVwPAEGMA4GA1UdDwEB/wQEAwIBBjAfBgNVHSMEGDAW" + "gBSbkzD5Yx3GHa0TvbBItWpm+LRN1TAdBgNVHQ4EFgQUm5Mw+WMdxh2tE72wSLVq" + "Zvi0TdUwDQYJKoZIhvcNAQEFBQADggEBAIQ4ZBHWssA38pfNzH5A+H3SXpAlI8Jc" + "LuoMVOIwwbfd1Up0xopCs+Ay41v8FZtcTMFqCVTih2nzVusTgnFBPMPJ2cnTlRue" + "kAtVRNsiWn2/Ool/OXoYf5YnpgYu8t9jLCBCoDS5YJg714r9V9hCwfey8TCWBU80" + "vL7EIfjK13nUxf8d49GzZlFMNqGDMjfMp1FYrHBGLZBr8br/G/7em1Cprw7iR8cw" + "pddz+QXXFIrIz5Y9D/x1RrwoLibPw0kMrSwI2G4aCvoBySfbD6cpnJf6YHRctdSb" + "755zhdBW7XWTl6ReUVuEt0hTFms4F60kFAi5hIbDRSN1Slv5yP2b0EA="); private static byte[] invalidResp = Base64.decode( "MIIGggoAoIIGfDCCBngGCSsGAQUFBzABAQSCBmkwggZlMIHeoTQwMjELMAkG" + "A1UEBhMCVVMxDTALBgNVBAoMBGlXYXkxFDASBgNVBAMMC2lXYXkgT3BlbkNB" + "GA8yMDEyMDEyMzIxMjkxMVowbjBsMEQwCQYFKw4DAhoFAAQUPA5ymcOyHyZJ" + "d7DAidsEh79Uh6QEFMHnDLGSc/VElMBzr5f0+LQnpN2YAgsA5xIzv2Ln0dAa" + "94IAGA8yMDEyMDEyMzIxMjkxMVqgERgPMjAxMjAxMjMyMTM0MTFaoSUwIzAh" + "BgkrBgEFBQcwAQIEFCHEdgCz5w64KgppPIetaRzxewinMA0GCSqGSIb3DQEB" + "CwUAA4IBAQBsW8cXR4eOLgclY/uRodjso/5xkHIAiJy+DpgqELRrnzKe87HO" + "Km7DCicz1nwsPJskK14xtIw1rfQ8nzgztriComAUVc/pxJ9wQWGZI3d2dNbW" + "AmecKb/mG0QrJrt3U5D0+CFTUq5u7NOs1jZRe+df9TDLBr0vIA6a0I6K9M9F" + "ZOPWU/j5KVjoi0/kv4wnxRzQ2zc4Z3b5gm9T0MXMH5bST3z4yhOs/NRezNTA" + "fBQvimS60d4fybH0pXcVYUH81y5fm9rCpuwQ6rMt2vi0ZKrfyVom4OIAr/gh" + "Doj8Yh/LdtI1RvFkAL3pvzs06cfg3qM38b9Uh9w93w4/Hguw14eroIIEbDCC" + "BGgwggRkMIIDTKADAgECAgEBMA0GCSqGSIb3DQEBCwUAMDIxCzAJBgNVBAYT" + "AlVTMQ0wCwYDVQQKDARpV2F5MRQwEgYDVQQDDAtpV2F5IE9wZW5DQTAeFw0x" + "MjAxMjAxNTIyMjFaFw0zMjAxMTUxNTIyMjFaMDIxCzAJBgNVBAYTAlVTMQ0w" + "CwYDVQQKDARpV2F5MRQwEgYDVQQDDAtpV2F5IE9wZW5DQTCCASIwDQYJKoZI" + "hvcNAQEBBQADggEPADCCAQoCggEBALOnLWYPvGNLxodQQ16tqCKflpEQF2OA" + "0inZbIeUVxOgph5Qf562XV1Mtbv5Agv+z4/LSLbwuo28NTkhSlEEwf1k9vL9" + "/wFvpPZ4ecpqXOS6LJ6khmMh53IwK/QpG8CeF9UxTZskjQzD9XgnNGYd2BIj" + "qVbzU5qWhsPYPRrsAaE2jS6My5+xfiw46/Xj26VZQ/PR/rVURsc40fpCE30y" + "TyORQeeZfjb/LxXH3e/3wjya04MBACv+uX89n5YXG7OH6zTriMAOn/aiXPfE" + "E8g834RKvVS7ruELWG/IcZDC+Eoy2qtgG7y1rFlXd3H/6rny+Xd+BZrt0WP/" + "hfezklVw3asCAwEAAaOCAYMwggF/MA8GA1UdEwEB/wQFMAMBAf8wCwYDVR0P" + "BAQDAgEGMB0GA1UdDgQWBBTB5wyxknP1RJTAc6+X9Pi0J6TdmDAfBgNVHSME" + "GDAWgBTB5wyxknP1RJTAc6+X9Pi0J6TdmDAjBgNVHREEHDAagRhzdXBwb3J0" + "QGl3YXlzb2Z0d2FyZS5jb20wIwYDVR0SBBwwGoEYc3VwcG9ydEBpd2F5c29m" + "dHdhcmUuY29tMIGYBggrBgEFBQcBAQSBizCBiDA5BggrBgEFBQcwAoYtaHR0" + "cDovL2l3NTRjZW50LXZtMi9wa2kvcHViL2NhY2VydC9jYWNlcnQuY3J0MCUG" + "CCsGAQUFBzABhhlodHRwOi8vaXc1NGNlbnQtdm0yOjI1NjAvMCQGCCsGAQUF" + "BzAMhhhodHRwOi8vaXc1NGNlbnQtdm0yOjgzMC8wOgYDVR0fBDMwMTAvoC2g" + "K4YpaHR0cDovL2l3NTRjZW50LXZtMi9wa2kvcHViL2NybC9jYWNybC5jcmww" + "DQYJKoZIhvcNAQELBQADggEBAE9wBjQ1c+HAO2gIzT+J5Gqgrcu/m7t4hnHN" + "m5eyIfwXD1T6wOhovFmzPTaO9BSNsi4G5R7yZxOHeLN4PIY2kwFIbSkg7mwe" + "5aGp2RPIuK/MtzMZT6pq8uMGhzyHGsqtdkz7p26/G0anU2u59eimcvISdwNE" + "QXOIp/KNUC+Vx+Pmfw8PuFYDNacZ6YXp5qKoEjyUoBhNicmVINTNfDu0CQhu" + "pDr2UmDMDT2cdmTSRC0rcTe3BNzWqtsXNmIBFL1oB7B0PZbmFm8Bgvk1azxa" + "ClrcOKZWKOWa14XJy/DJk6nlOiq5W2AglUt8JVOpa5oVdiNRIT2WoGnpqVV9" + "tUeoWog="); private static final String BC = "BC"; public String getName() { return "OCSP"; } private void testECDSA() throws Exception { String signDN = "O=Bouncy Castle, C=AU"; KeyPair signKP = OCSPTestUtil.makeECKeyPair(); X509CertificateHolder testCert = new JcaX509CertificateHolder(OCSPTestUtil.makeECDSACertificate(signKP, signDN, signKP, signDN)); DigestCalculatorProvider digCalcProv = new JcaDigestCalculatorProviderBuilder().setProvider(BC).build(); String origDN = "CN=Eric H. Echidna, E=eric@bouncycastle.org, O=Bouncy Castle, C=AU"; GeneralName origName = new GeneralName(new X509Name(origDN)); // // general id value for our test issuer cert and a serial number. // CertificateID id = new CertificateID(digCalcProv.get(CertificateID.HASH_SHA1), testCert, BigInteger.valueOf(1)); // // basic request generation // OCSPReqBuilder gen = new OCSPReqBuilder(); gen.addRequest(id); OCSPReq req = gen.build(); if (req.isSigned()) { fail("signed but shouldn't be"); } X509CertificateHolder[] certs = req.getCerts(); if (certs.length != 0) { fail("0 certs expected, but not found"); } Req[] requests = req.getRequestList(); if (!requests[0].getCertID().equals(id)) { fail("Failed isFor test"); } // // request generation with signing // X509CertificateHolder[] chain = new X509CertificateHolder[1]; gen = new OCSPReqBuilder(); gen.setRequestorName(new GeneralName(GeneralName.directoryName, new X509Principal("CN=fred"))); gen.addRequest( new CertificateID(digCalcProv.get(CertificateID.HASH_SHA1), testCert, BigInteger.valueOf(1))); chain[0] = testCert; req = gen.build(new JcaContentSignerBuilder("SHA1withECDSA").setProvider(BC).build( signKP.getPrivate()), chain); if (!req.isSigned()) { fail("not signed but should be"); } if (!req.isSignatureValid(new JcaContentVerifierProviderBuilder().setProvider(BC).build(signKP.getPublic()))) { fail("signature failed to verify"); } requests = req.getRequestList(); if (!requests[0].getCertID().equals(id)) { fail("Failed isFor test"); } certs = req.getCerts(); if (certs == null) { fail("null certs found"); } if (certs.length != 1 || !certs[0].equals(testCert)) { fail("incorrect certs found in request"); } // // encoding test // byte[] reqEnc = req.getEncoded(); OCSPReq newReq = new OCSPReq(reqEnc); if (!newReq.isSignatureValid(new JcaContentVerifierProviderBuilder().setProvider(BC).build(signKP.getPublic()))) { fail("newReq signature failed to verify"); } // // request generation with signing and nonce // chain = new X509CertificateHolder[1]; gen = new OCSPReqBuilder(); Vector oids = new Vector(); Vector values = new Vector(); byte[] sampleNonce = new byte[16]; Random rand = new Random(); rand.nextBytes(sampleNonce); gen.setRequestorName(new GeneralName(GeneralName.directoryName, new X509Principal("CN=fred"))); ExtensionsGenerator extGen = new ExtensionsGenerator(); extGen.addExtension(OCSPObjectIdentifiers.id_pkix_ocsp_nonce, false, new DEROctetString(sampleNonce)); gen.setRequestExtensions(extGen.generate()); gen.addRequest( new CertificateID(digCalcProv.get(CertificateID.HASH_SHA1), testCert, BigInteger.valueOf(1))); chain[0] = testCert; req = gen.build(new JcaContentSignerBuilder("SHA1withECDSA").setProvider(BC).build(signKP.getPrivate()), chain); if (!req.isSigned()) { fail("not signed but should be"); } if (!req.isSignatureValid(new JcaContentVerifierProviderBuilder().setProvider(BC).build(signKP.getPublic()))) { fail("signature failed to verify"); } // // extension check. // Set extOids = req.getCriticalExtensionOIDs(); if (extOids.size() != 0) { fail("wrong number of critical extensions in OCSP request."); } extOids = req.getNonCriticalExtensionOIDs(); if (extOids.size() != 1) { fail("wrong number of non-critical extensions in OCSP request."); } Extension extValue = req.getExtension(OCSPObjectIdentifiers.id_pkix_ocsp_nonce); ASN1Encodable extObj = extValue.getParsedValue(); if (!(extObj instanceof ASN1OctetString)) { fail("wrong extension type found."); } if (!areEqual(((ASN1OctetString)extObj).getOctets(), sampleNonce)) { fail("wrong extension value found."); } // // request list check // requests = req.getRequestList(); if (!requests[0].getCertID().equals(id)) { fail("Failed isFor test"); } // // response generation // BasicOCSPRespBuilder respGen = new JcaBasicOCSPRespBuilder(signKP.getPublic(), digCalcProv.get(RespID.HASH_SHA1)); respGen.addResponse(id, CertificateStatus.GOOD); BasicOCSPResp resp = respGen.build(new JcaContentSignerBuilder("SHA1withECDSA").setProvider(BC).build(signKP.getPrivate()), chain, new Date()); } private void testRSA() throws Exception { String signDN = "O=Bouncy Castle, C=AU"; KeyPair signKP = OCSPTestUtil.makeKeyPair(); X509CertificateHolder testCert = new JcaX509CertificateHolder(OCSPTestUtil.makeCertificate(signKP, signDN, signKP, signDN)); DigestCalculatorProvider digCalcProv = new JcaDigestCalculatorProviderBuilder().setProvider(BC).build(); String origDN = "CN=Eric H. Echidna, E=eric@bouncycastle.org, O=Bouncy Castle, C=AU"; GeneralName origName = new GeneralName(new X509Name(origDN)); // // general id value for our test issuer cert and a serial number. // CertificateID id = new CertificateID(digCalcProv.get(CertificateID.HASH_SHA1), testCert, BigInteger.valueOf(1)); // // basic request generation // OCSPReqBuilder gen = new OCSPReqBuilder(); gen.addRequest( new CertificateID(digCalcProv.get(CertificateID.HASH_SHA1), testCert, BigInteger.valueOf(1))); OCSPReq req = gen.build(); if (req.isSigned()) { fail("signed but shouldn't be"); } X509CertificateHolder[] certs = req.getCerts(); if (certs.length != 0) { fail("0 certs expected, but not found"); } Req[] requests = req.getRequestList(); if (!requests[0].getCertID().equals(id)) { fail("Failed isFor test"); } // // request generation with signing // X509CertificateHolder[] chain = new X509CertificateHolder[1]; gen = new OCSPReqBuilder(); gen.setRequestorName(new GeneralName(GeneralName.directoryName, new X509Principal("CN=fred"))); gen.addRequest( new CertificateID(digCalcProv.get(CertificateID.HASH_SHA1), testCert, BigInteger.valueOf(1))); chain[0] = testCert; req = gen.build(new JcaContentSignerBuilder("SHA1withRSA").setProvider(BC).build(signKP.getPrivate()), chain); if (!req.isSigned()) { fail("not signed but should be"); } if (!req.isSignatureValid(new JcaContentVerifierProviderBuilder().setProvider(BC).build(signKP.getPublic()))) { fail("signature failed to verify"); } requests = req.getRequestList(); if (!requests[0].getCertID().equals(id)) { fail("Failed isFor test"); } certs = req.getCerts(); if (certs == null) { fail("null certs found"); } if (certs.length != 1 || !certs[0].equals(testCert)) { fail("incorrect certs found in request"); } // // encoding test // byte[] reqEnc = req.getEncoded(); OCSPReq newReq = new OCSPReq(reqEnc); if (!newReq.isSignatureValid(new JcaContentVerifierProviderBuilder().setProvider(BC).build(signKP.getPublic()))) { fail("newReq signature failed to verify"); } // // request generation with signing and nonce // chain = new X509CertificateHolder[1]; gen = new OCSPReqBuilder(); byte[] sampleNonce = new byte[16]; Random rand = new Random(); rand.nextBytes(sampleNonce); gen.setRequestorName(new GeneralName(GeneralName.directoryName, new X509Principal("CN=fred"))); ExtensionsGenerator extGen = new ExtensionsGenerator(); extGen.addExtension(OCSPObjectIdentifiers.id_pkix_ocsp_nonce, false, new DEROctetString(sampleNonce)); gen.setRequestExtensions(extGen.generate()); gen.addRequest( new CertificateID(digCalcProv.get(CertificateID.HASH_SHA1), testCert, BigInteger.valueOf(1))); chain[0] = testCert; req = gen.build(new JcaContentSignerBuilder("SHA1withRSA").setProvider(BC).build(signKP.getPrivate()), chain); if (!req.isSigned()) { fail("not signed but should be"); } if (!req.isSignatureValid(new JcaContentVerifierProviderBuilder().setProvider(BC).build(signKP.getPublic()))) { fail("signature failed to verify"); } // // extension check. // Set extOids = req.getCriticalExtensionOIDs(); if (extOids.size() != 0) { fail("wrong number of critical extensions in OCSP request."); } extOids = req.getNonCriticalExtensionOIDs(); if (extOids.size() != 1) { fail("wrong number of non-critical extensions in OCSP request."); } Extension ext = req.getExtension(OCSPObjectIdentifiers.id_pkix_ocsp_nonce); ASN1Encodable extObj = ext.getParsedValue(); if (!(extObj instanceof ASN1OctetString)) { fail("wrong extension type found."); } if (!areEqual(((ASN1OctetString)extObj).getOctets(), sampleNonce)) { fail("wrong extension value found."); } // // request list check // requests = req.getRequestList(); if (!requests[0].getCertID().equals(id)) { fail("Failed isFor test"); } // // response generation // BasicOCSPRespBuilder respGen = new JcaBasicOCSPRespBuilder(signKP.getPublic(), digCalcProv.get(RespID.HASH_SHA1)); respGen.addResponse(id, CertificateStatus.GOOD); BasicOCSPResp resp = respGen.build(new JcaContentSignerBuilder("SHA1withRSA").setProvider(BC).build(signKP.getPrivate()), chain, new Date()); OCSPRespBuilder rGen = new OCSPRespBuilder(); byte[] enc = rGen.build(OCSPRespBuilder.SUCCESSFUL, resp).getEncoded(); } private void testIrregularVersionReq() throws Exception { OCSPReq ocspRequest = new OCSPReq(irregReq); X509CertificateHolder cert = ocspRequest.getCerts()[0]; if (!ocspRequest.isSignatureValid(new JcaContentVerifierProviderBuilder().setProvider(BC).build(cert))) { fail("extra version encoding test failed"); } } public void testInvalidResp() throws Exception { try { OCSPResp response = new OCSPResp(invalidResp); } catch (CertIOException e) { if (e.getCause() instanceof ASN1Exception) { Throwable c = ((ASN1Exception)e.getCause()).getCause(); if (!c.getMessage().equals("ENUMERATED has zero length")) { fail("parsing failed, but for wrong reason: " + c.getMessage()); } } else { fail("parsing failed, but for wrong reason: " + e.getMessage()); } } } public void performTest() throws Exception { String signDN = "O=Bouncy Castle, C=AU"; KeyPair signKP = OCSPTestUtil.makeKeyPair(); X509CertificateHolder testCert = new JcaX509CertificateHolder(OCSPTestUtil.makeCertificate(signKP, signDN, signKP, signDN)); String origDN = "CN=Eric H. Echidna, E=eric@bouncycastle.org, O=Bouncy Castle, C=AU"; GeneralName origName = new GeneralName(new X509Name(origDN)); DigestCalculatorProvider digCalcProv = new JcaDigestCalculatorProviderBuilder().setProvider(BC).build(); // // general id value for our test issuer cert and a serial number. // CertificateID id = new CertificateID(digCalcProv.get(CertificateID.HASH_SHA1), testCert, BigInteger.valueOf(1)); // // basic request generation // OCSPReqBuilder gen = new OCSPReqBuilder(); gen.addRequest( new CertificateID(digCalcProv.get(CertificateID.HASH_SHA1), testCert, BigInteger.valueOf(1))); OCSPReq req = gen.build(); if (req.isSigned()) { fail("signed but shouldn't be"); } X509CertificateHolder[] certs = req.getCerts(); if (certs.length != 0) { fail("0 certs expected, but not found"); } Req[] requests = req.getRequestList(); if (!requests[0].getCertID().equals(id)) { fail("Failed isFor test"); } // // request generation with signing // X509CertificateHolder[] chain = new X509CertificateHolder[1]; gen = new OCSPReqBuilder(); gen.setRequestorName(new GeneralName(GeneralName.directoryName, new X509Principal("CN=fred"))); gen.addRequest( new CertificateID(digCalcProv.get(CertificateID.HASH_SHA1), testCert, BigInteger.valueOf(1))); chain[0] = testCert; req = gen.build(new JcaContentSignerBuilder("SHA1withRSA").setProvider(BC).build(signKP.getPrivate()), chain); if (!req.isSigned()) { fail("not signed but should be"); } if (!req.isSignatureValid(new JcaContentVerifierProviderBuilder().setProvider(BC).build(signKP.getPublic()))) { fail("signature failed to verify"); } requests = req.getRequestList(); if (!requests[0].getCertID().equals(id)) { fail("Failed isFor test"); } certs = req.getCerts(); if (certs == null) { fail("null certs found"); } if (certs.length != 1 || !certs[0].equals(testCert)) { fail("incorrect certs found in request"); } // // encoding test // byte[] reqEnc = req.getEncoded(); OCSPReq newReq = new OCSPReq(reqEnc); if (!newReq.isSignatureValid(new JcaContentVerifierProviderBuilder().setProvider(BC).build(signKP.getPublic()))) { fail("newReq signature failed to verify"); } // // request generation with signing and nonce // chain = new X509CertificateHolder[1]; gen = new OCSPReqBuilder(); Vector oids = new Vector(); Vector values = new Vector(); byte[] sampleNonce = new byte[16]; Random rand = new Random(); rand.nextBytes(sampleNonce); gen.setRequestorName(new GeneralName(GeneralName.directoryName, new X509Principal("CN=fred"))); ExtensionsGenerator extGen = new ExtensionsGenerator(); extGen.addExtension(OCSPObjectIdentifiers.id_pkix_ocsp_nonce, false, new DEROctetString(sampleNonce)); gen.setRequestExtensions(extGen.generate()); gen.addRequest( new CertificateID(digCalcProv.get(CertificateID.HASH_SHA1), testCert, BigInteger.valueOf(1))); chain[0] = testCert; req = gen.build(new JcaContentSignerBuilder("SHA1withRSA").setProvider(BC).build(signKP.getPrivate()), chain); if (!req.isSigned()) { fail("not signed but should be"); } if (!req.isSignatureValid(new JcaContentVerifierProviderBuilder().setProvider(BC).build(signKP.getPublic()))) { fail("signature failed to verify"); } // // extension check. // Set extOids = req.getCriticalExtensionOIDs(); if (extOids.size() != 0) { fail("wrong number of critical extensions in OCSP request."); } extOids = req.getNonCriticalExtensionOIDs(); if (extOids.size() != 1) { fail("wrong number of non-critical extensions in OCSP request."); } Extension ext = req.getExtension(OCSPObjectIdentifiers.id_pkix_ocsp_nonce); ASN1Encodable extObj = ext.getParsedValue(); if (!(extObj instanceof ASN1OctetString)) { fail("wrong extension type found."); } if (!areEqual(((ASN1OctetString)extObj).getOctets(), sampleNonce)) { fail("wrong extension value found."); } // // request list check // requests = req.getRequestList(); if (!requests[0].getCertID().equals(id)) { fail("Failed isFor test"); } // // response parsing - test 1 // OCSPResp response = new OCSPResp(testResp1); if (response.getStatus() != 0) { fail("response status not zero."); } BasicOCSPResp brep = (BasicOCSPResp)response.getResponseObject(); chain = brep.getCerts(); if (!brep.isSignatureValid(new JcaContentVerifierProviderBuilder().setProvider(BC).build(chain[0]))) { fail("response 1 failed to verify."); } // // test 2 // SingleResp[] singleResp = brep.getResponses(); response = new OCSPResp(testResp2); if (response.getStatus() != 0) { fail("response status not zero."); } brep = (BasicOCSPResp)response.getResponseObject(); chain = brep.getCerts(); if (!brep.isSignatureValid(new JcaContentVerifierProviderBuilder().setProvider(BC).build(chain[0]))) { fail("response 2 failed to verify."); } singleResp = brep.getResponses(); // // simple response generation // OCSPRespBuilder respGen = new OCSPRespBuilder(); OCSPResp resp = respGen.build(OCSPRespBuilder.SUCCESSFUL, response.getResponseObject()); if (!resp.getResponseObject().equals(response.getResponseObject())) { fail("response fails to match"); } testECDSA(); testRSA(); testIrregularVersionReq(); testInvalidResp(); // // Empty data test // try { response = new OCSPResp(new byte[0]); fail("no exception thrown"); } catch (IOException e) { if (!e.getMessage().equals("malformed response: no response data found")) { fail("wrong exception"); } } try { req = new OCSPReq(new byte[0]); fail("no exception thrown"); } catch (IOException e) { if (!e.getMessage().equals("malformed request: no request data found")) { fail("wrong exception"); } } } public static void main( String[] args) { Security.addProvider(new BouncyCastleProvider()); runTest(new OCSPTest()); } } bouncycastle-1.49.orig/test/src/org/bouncycastle/cert/ocsp/test/AllTests.java0000644000175000017500000000213411475104547026747 0ustar ebourgebourgpackage org.bouncycastle.cert.ocsp.test; import java.security.Security; import junit.framework.Test; import junit.framework.TestCase; import junit.framework.TestSuite; import org.bouncycastle.jce.provider.BouncyCastleProvider; import org.bouncycastle.util.test.SimpleTestResult; public class AllTests extends TestCase { public void testOCSP() { Security.addProvider(new BouncyCastleProvider()); org.bouncycastle.util.test.Test[] tests = new org.bouncycastle.util.test.Test[] { new OCSPTest() }; for (int i = 0; i != tests.length; i++) { SimpleTestResult result = (SimpleTestResult)tests[i].perform(); if (!result.isSuccessful()) { fail(result.toString()); } } } public static void main (String[] args) { junit.textui.TestRunner.run(suite()); } public static Test suite() { TestSuite suite = new TestSuite("OCSP Tests"); suite.addTestSuite(AllTests.class); return suite; } } bouncycastle-1.49.orig/test/src/org/bouncycastle/cert/test/0000755000175000017500000000000012152033550023371 5ustar ebourgebourgbouncycastle-1.49.orig/test/src/org/bouncycastle/cert/test/BcAttrCertSelectorTest.java0000644000175000017500000002342011737303571030606 0ustar ebourgebourgpackage org.bouncycastle.cert.test; import java.math.BigInteger; import java.util.Date; import junit.framework.TestCase; import org.bouncycastle.asn1.ASN1EncodableVector; import org.bouncycastle.asn1.ASN1ObjectIdentifier; import org.bouncycastle.asn1.DERSequence; import org.bouncycastle.asn1.x500.X500Name; import org.bouncycastle.asn1.x509.AlgorithmIdentifier; import org.bouncycastle.asn1.x509.Extension; import org.bouncycastle.asn1.x509.GeneralName; import org.bouncycastle.asn1.x509.Target; import org.bouncycastle.asn1.x509.TargetInformation; import org.bouncycastle.cert.AttributeCertificateHolder; import org.bouncycastle.cert.AttributeCertificateIssuer; import org.bouncycastle.cert.X509AttributeCertificateHolder; import org.bouncycastle.cert.X509CertificateHolder; import org.bouncycastle.cert.X509v2AttributeCertificateBuilder; import org.bouncycastle.cert.selector.X509AttributeCertificateHolderSelectorBuilder; import org.bouncycastle.crypto.params.RSAPrivateCrtKeyParameters; import org.bouncycastle.operator.ContentSigner; import org.bouncycastle.operator.DefaultDigestAlgorithmIdentifierFinder; import org.bouncycastle.operator.DefaultSignatureAlgorithmIdentifierFinder; import org.bouncycastle.operator.bc.BcRSAContentSignerBuilder; import org.bouncycastle.util.encoders.Base64; public class BcAttrCertSelectorTest extends TestCase { DefaultSignatureAlgorithmIdentifierFinder sigAlgFinder = new DefaultSignatureAlgorithmIdentifierFinder(); DefaultDigestAlgorithmIdentifierFinder digAlgFinder = new DefaultDigestAlgorithmIdentifierFinder(); static final RSAPrivateCrtKeyParameters RSA_PRIVATE_KEY_SPEC = new RSAPrivateCrtKeyParameters( new BigInteger( "b4a7e46170574f16a97082b22be58b6a2a629798419be12872a4bdba626cfae9900f76abfb12139dce5de56564fab2b6543165a040c606887420e33d91ed7ed7", 16), new BigInteger("11", 16), new BigInteger( "9f66f6b05410cd503b2709e88115d55daced94d1a34d4e32bf824d0dde6028ae79c5f07b580f5dce240d7111f7ddb130a7945cd7d957d1920994da389f490c89", 16), new BigInteger( "c0a0758cdf14256f78d4708c86becdead1b50ad4ad6c5c703e2168fbf37884cb", 16), new BigInteger( "f01734d7960ea60070f1b06f2bb81bfac48ff192ae18451d5e56c734a5aab8a5", 16), new BigInteger( "b54bb9edff22051d9ee60f9351a48591b6500a319429c069a3e335a1d6171391", 16), new BigInteger( "d3d83daf2a0cecd3367ae6f8ae1aeb82e9ac2f816c6fc483533d8297dd7884cd", 16), new BigInteger( "b8f52fc6f38593dabb661d3f50f8897f8106eee68b1bce78a95b132b4e5b5d19", 16)); static final byte[] holderCert = Base64 .decode("MIIGjTCCBXWgAwIBAgICAPswDQYJKoZIhvcNAQEEBQAwaTEdMBsGCSqGSIb3DQEJ" + "ARYOaXJtaGVscEB2dC5lZHUxLjAsBgNVBAMTJVZpcmdpbmlhIFRlY2ggQ2VydGlm" + "aWNhdGlvbiBBdXRob3JpdHkxCzAJBgNVBAoTAnZ0MQswCQYDVQQGEwJVUzAeFw0w" + "MzAxMzExMzUyMTRaFw0wNDAxMzExMzUyMTRaMIGDMRswGQYJKoZIhvcNAQkBFgxz" + "c2hhaEB2dC5lZHUxGzAZBgNVBAMTElN1bWl0IFNoYWggKHNzaGFoKTEbMBkGA1UE" + "CxMSVmlyZ2luaWEgVGVjaCBVc2VyMRAwDgYDVQQLEwdDbGFzcyAxMQswCQYDVQQK" + "EwJ2dDELMAkGA1UEBhMCVVMwgZ8wDQYJKoZIhvcNAQEBBQADgY0AMIGJAoGBAPDc" + "scgSKmsEp0VegFkuitD5j5PUkDuzLjlfaYONt2SN8WeqU4j2qtlCnsipa128cyKS" + "JzYe9duUdNxquh5BPIkMkHBw4jHoQA33tk0J/sydWdN74/AHPpPieK5GHwhU7GTG" + "rCCS1PJRxjXqse79ExAlul+gjQwHeldAC+d4A6oZAgMBAAGjggOmMIIDojAMBgNV" + "HRMBAf8EAjAAMBEGCWCGSAGG+EIBAQQEAwIFoDAOBgNVHQ8BAf8EBAMCA/gwHQYD" + "VR0lBBYwFAYIKwYBBQUHAwIGCCsGAQUFBwMEMB0GA1UdDgQWBBRUIoWAzlXbzBYE" + "yVTjQFWyMMKo1jCBkwYDVR0jBIGLMIGIgBTgc3Fm+TGqKDhen+oKfbl+xVbj2KFt" + "pGswaTEdMBsGCSqGSIb3DQEJARYOaXJtaGVscEB2dC5lZHUxLjAsBgNVBAMTJVZp" + "cmdpbmlhIFRlY2ggQ2VydGlmaWNhdGlvbiBBdXRob3JpdHkxCzAJBgNVBAoTAnZ0" + "MQswCQYDVQQGEwJVU4IBADCBiwYJYIZIAYb4QgENBH4WfFZpcmdpbmlhIFRlY2gg" + "Q2VydGlmaWNhdGlvbiBBdXRob3JpdHkgZGlnaXRhbCBjZXJ0aWZpY2F0ZXMgYXJl" + "IHN1YmplY3QgdG8gcG9saWNpZXMgbG9jYXRlZCBhdCBodHRwOi8vd3d3LnBraS52" + "dC5lZHUvY2EvY3BzLy4wFwYDVR0RBBAwDoEMc3NoYWhAdnQuZWR1MBkGA1UdEgQS" + "MBCBDmlybWhlbHBAdnQuZWR1MEMGCCsGAQUFBwEBBDcwNTAzBggrBgEFBQcwAoYn" + "aHR0cDovL2JveDE3Ny5jYy52dC5lZHUvY2EvaXNzdWVycy5odG1sMEQGA1UdHwQ9" + "MDswOaA3oDWGM2h0dHA6Ly9ib3gxNzcuY2MudnQuZWR1L2h0ZG9jcy1wdWJsaWMv" + "Y3JsL2NhY3JsLmNybDBUBgNVHSAETTBLMA0GCysGAQQBtGgFAQEBMDoGCysGAQQB" + "tGgFAQEBMCswKQYIKwYBBQUHAgEWHWh0dHA6Ly93d3cucGtpLnZ0LmVkdS9jYS9j" + "cHMvMD8GCWCGSAGG+EIBBAQyFjBodHRwOi8vYm94MTc3LmNjLnZ0LmVkdS9jZ2kt" + "cHVibGljL2NoZWNrX3Jldl9jYT8wPAYJYIZIAYb4QgEDBC8WLWh0dHA6Ly9ib3gx" + "NzcuY2MudnQuZWR1L2NnaS1wdWJsaWMvY2hlY2tfcmV2PzBLBglghkgBhvhCAQcE" + "PhY8aHR0cHM6Ly9ib3gxNzcuY2MudnQuZWR1L35PcGVuQ0E4LjAxMDYzMC9jZ2kt" + "cHVibGljL3JlbmV3YWw/MCwGCWCGSAGG+EIBCAQfFh1odHRwOi8vd3d3LnBraS52" + "dC5lZHUvY2EvY3BzLzANBgkqhkiG9w0BAQQFAAOCAQEAHJ2ls9yjpZVcu5DqiE67" + "r7BfkdMnm7IOj2v8cd4EAlPp6OPBmjwDMwvKRBb/P733kLBqFNWXWKTpT008R0KB" + "8kehbx4h0UPz9vp31zhGv169+5iReQUUQSIwTGNWGLzrT8kPdvxiSAvdAJxcbRBm" + "KzDic5I8PoGe48kSCkPpT1oNmnivmcu5j1SMvlx0IS2BkFMksr0OHiAW1elSnE/N" + "RuX2k73b3FucwVxB3NRo3vgoHPCTnh9r4qItAHdxFlF+pPtbw2oHESKRfMRfOIHz" + "CLQWSIa6Tvg4NIV3RRJ0sbCObesyg08lymalQMdkXwtRn5eGE00SHWwEUjSXP2gR" + "3g=="); public String getName() { return "AttrCertSelector"; } private X509AttributeCertificateHolder createAttrCert() throws Exception { X509CertificateHolder iCertHolder = new X509CertificateHolder(holderCert); // // a sample key pair. // // RSAPublicKeySpec pubKeySpec = new RSAPublicKeySpec( // new BigInteger( // "b4a7e46170574f16a97082b22be58b6a2a629798419be12872a4bdba626cfae9900f76abfb12139dce5de56564fab2b6543165a040c606887420e33d91ed7ed7", // 16), new BigInteger("11", 16)); X509v2AttributeCertificateBuilder gen = new X509v2AttributeCertificateBuilder( new AttributeCertificateHolder(iCertHolder.getSubject()), new AttributeCertificateIssuer(new X500Name("cn=test")), BigInteger.ONE, new Date(System.currentTimeMillis() - 50000), new Date(System.currentTimeMillis() + 50000)); // the actual attributes GeneralName roleName = new GeneralName(GeneralName.rfc822Name, "DAU123456789@test.com"); ASN1EncodableVector roleSyntax = new ASN1EncodableVector(); roleSyntax.add(roleName); // roleSyntax OID: 2.5.24.72 gen.addAttribute(new ASN1ObjectIdentifier("2.5.24.72"), new DERSequence(roleSyntax)); AlgorithmIdentifier sigAlg = sigAlgFinder.find("SHA1withRSA"); AlgorithmIdentifier digAlg = digAlgFinder.find(sigAlg); ContentSigner sigGen = new BcRSAContentSignerBuilder(sigAlg, digAlg).build(RSA_PRIVATE_KEY_SPEC); Target targetName = new Target(Target.targetName, new GeneralName(GeneralName.dNSName, "www.test.com")); Target targetGroup = new Target(Target.targetGroup, new GeneralName( GeneralName.directoryName, "o=Test, ou=Test")); Target[] targets = new Target[2]; targets[0] = targetName; targets[1] = targetGroup; TargetInformation targetInformation = new TargetInformation(targets); gen.addExtension(Extension.targetInformation, true, targetInformation); return gen.build(sigGen); } public void testSelector() throws Exception { X509AttributeCertificateHolder aCert = createAttrCert(); X509AttributeCertificateHolderSelectorBuilder sel = new X509AttributeCertificateHolderSelectorBuilder(); sel.setAttributeCert(aCert); boolean match = sel.build().match(aCert); if (!match) { fail("Selector does not match attribute certificate."); } sel.setAttributeCert(null); match = sel.build().match(aCert); if (!match) { fail("Selector does not match attribute certificate."); } sel.setHolder(aCert.getHolder()); match = sel.build().match(aCert); if (!match) { fail("Selector does not match attribute certificate holder."); } sel.setHolder(null); sel.setIssuer(aCert.getIssuer()); match = sel.build().match(aCert); if (!match) { fail("Selector does not match attribute certificate issuer."); } sel.setIssuer(null); X509CertificateHolder iCert = new X509CertificateHolder(holderCert); match = aCert.getHolder().match(iCert); if (!match) { fail("Issuer holder does not match signing certificate of attribute certificate."); } sel.setSerialNumber(aCert.getSerialNumber()); match = sel.build().match(aCert); if (!match) { fail("Selector does not match attribute certificate serial number."); } sel.setAttributeCertificateValid(new Date()); match = sel.build().match(aCert); if (!match) { fail("Selector does not match attribute certificate time."); } sel.addTargetName(new GeneralName(2, "www.test.com")); match = sel.build().match(aCert); if (!match) { fail("Selector does not match attribute certificate target name."); } sel.setTargetNames(null); sel.addTargetGroup(new GeneralName(4, "o=Test, ou=Test")); match = sel.build().match(aCert); if (!match) { fail("Selector does not match attribute certificate target group."); } sel.setTargetGroups(null); } } bouncycastle-1.49.orig/test/src/org/bouncycastle/cert/test/AttrCertTest.java0000644000175000017500000006561611724561172026654 0ustar ebourgebourgpackage org.bouncycastle.cert.test; import java.io.ByteArrayInputStream; import java.io.IOException; import java.math.BigInteger; import java.security.KeyFactory; import java.security.PrivateKey; import java.security.PublicKey; import java.security.Security; import java.security.cert.CertificateFactory; import java.security.cert.X509Certificate; import java.security.spec.RSAPrivateCrtKeySpec; import java.security.spec.RSAPublicKeySpec; import java.util.ArrayList; import java.util.Collection; import java.util.Date; import java.util.List; import java.util.Set; import javax.security.auth.x500.X500Principal; import org.bouncycastle.asn1.ASN1Encodable; import org.bouncycastle.asn1.ASN1EncodableVector; import org.bouncycastle.asn1.ASN1ObjectIdentifier; import org.bouncycastle.asn1.ASN1String; import org.bouncycastle.asn1.DEROctetString; import org.bouncycastle.asn1.DERSequence; import org.bouncycastle.asn1.x500.X500Name; import org.bouncycastle.asn1.x509.Attribute; import org.bouncycastle.asn1.x509.Extension; import org.bouncycastle.asn1.x509.GeneralName; import org.bouncycastle.asn1.x509.GeneralNames; import org.bouncycastle.cert.AttributeCertificateHolder; import org.bouncycastle.cert.AttributeCertificateIssuer; import org.bouncycastle.cert.X509AttributeCertificateHolder; import org.bouncycastle.cert.X509v2AttributeCertificateBuilder; import org.bouncycastle.cert.jcajce.JcaCertStore; import org.bouncycastle.cert.jcajce.JcaX509CertificateHolder; import org.bouncycastle.jce.provider.BouncyCastleProvider; import org.bouncycastle.operator.ContentSigner; import org.bouncycastle.operator.jcajce.JcaContentSignerBuilder; import org.bouncycastle.operator.jcajce.JcaContentVerifierProviderBuilder; import org.bouncycastle.util.Store; import org.bouncycastle.util.encoders.Base64; import org.bouncycastle.util.test.SimpleTest; public class AttrCertTest extends SimpleTest { private static final String BC = BouncyCastleProvider.PROVIDER_NAME; private static final RSAPrivateCrtKeySpec RSA_PRIVATE_KEY_SPEC = new RSAPrivateCrtKeySpec( new BigInteger("b4a7e46170574f16a97082b22be58b6a2a629798419be12872a4bdba626cfae9900f76abfb12139dce5de56564fab2b6543165a040c606887420e33d91ed7ed7", 16), new BigInteger("11", 16), new BigInteger("9f66f6b05410cd503b2709e88115d55daced94d1a34d4e32bf824d0dde6028ae79c5f07b580f5dce240d7111f7ddb130a7945cd7d957d1920994da389f490c89", 16), new BigInteger("c0a0758cdf14256f78d4708c86becdead1b50ad4ad6c5c703e2168fbf37884cb", 16), new BigInteger("f01734d7960ea60070f1b06f2bb81bfac48ff192ae18451d5e56c734a5aab8a5", 16), new BigInteger("b54bb9edff22051d9ee60f9351a48591b6500a319429c069a3e335a1d6171391", 16), new BigInteger("d3d83daf2a0cecd3367ae6f8ae1aeb82e9ac2f816c6fc483533d8297dd7884cd", 16), new BigInteger("b8f52fc6f38593dabb661d3f50f8897f8106eee68b1bce78a95b132b4e5b5d19", 16)); public static byte[] attrCert = Base64.decode( "MIIHQDCCBqkCAQEwgZChgY2kgYowgYcxHDAaBgkqhkiG9w0BCQEWDW1sb3JjaEB2" + "dC5lZHUxHjAcBgNVBAMTFU1hcmt1cyBMb3JjaCAobWxvcmNoKTEbMBkGA1UECxMS" + "VmlyZ2luaWEgVGVjaCBVc2VyMRAwDgYDVQQLEwdDbGFzcyAyMQswCQYDVQQKEwJ2" + "dDELMAkGA1UEBhMCVVMwgYmkgYYwgYMxGzAZBgkqhkiG9w0BCQEWDHNzaGFoQHZ0" + "LmVkdTEbMBkGA1UEAxMSU3VtaXQgU2hhaCAoc3NoYWgpMRswGQYDVQQLExJWaXJn" + "aW5pYSBUZWNoIFVzZXIxEDAOBgNVBAsTB0NsYXNzIDExCzAJBgNVBAoTAnZ0MQsw" + "CQYDVQQGEwJVUzANBgkqhkiG9w0BAQQFAAIBBTAiGA8yMDAzMDcxODE2MDgwMloY" + "DzIwMDMwNzI1MTYwODAyWjCCBU0wggVJBgorBgEEAbRoCAEBMYIFORaCBTU8UnVs" + "ZSBSdWxlSWQ9IkZpbGUtUHJpdmlsZWdlLVJ1bGUiIEVmZmVjdD0iUGVybWl0Ij4K" + "IDxUYXJnZXQ+CiAgPFN1YmplY3RzPgogICA8U3ViamVjdD4KICAgIDxTdWJqZWN0" + "TWF0Y2ggTWF0Y2hJZD0idXJuOm9hc2lzOm5hbWVzOnRjOnhhY21sOjEuMDpmdW5j" + "dGlvbjpzdHJpbmctZXF1YWwiPgogICAgIDxBdHRyaWJ1dGVWYWx1ZSBEYXRhVHlw" + "ZT0iaHR0cDovL3d3dy53My5vcmcvMjAwMS9YTUxTY2hlbWEjc3RyaW5nIj4KICAg" + "ICAgIENOPU1hcmt1cyBMb3JjaDwvQXR0cmlidXRlVmFsdWU+CiAgICAgPFN1Ympl" + "Y3RBdHRyaWJ1dGVEZXNpZ25hdG9yIEF0dHJpYnV0ZUlkPSJ1cm46b2FzaXM6bmFt" + "ZXM6dGM6eGFjbWw6MS4wOnN1YmplY3Q6c3ViamVjdC1pZCIgRGF0YVR5cGU9Imh0" + "dHA6Ly93d3cudzMub3JnLzIwMDEvWE1MU2NoZW1hI3N0cmluZyIgLz4gCiAgICA8" + "L1N1YmplY3RNYXRjaD4KICAgPC9TdWJqZWN0PgogIDwvU3ViamVjdHM+CiAgPFJl" + "c291cmNlcz4KICAgPFJlc291cmNlPgogICAgPFJlc291cmNlTWF0Y2ggTWF0Y2hJ" + "ZD0idXJuOm9hc2lzOm5hbWVzOnRjOnhhY21sOjEuMDpmdW5jdGlvbjpzdHJpbmct" + "ZXF1YWwiPgogICAgIDxBdHRyaWJ1dGVWYWx1ZSBEYXRhVHlwZT0iaHR0cDovL3d3" + "dy53My5vcmcvMjAwMS9YTUxTY2hlbWEjYW55VVJJIj4KICAgICAgaHR0cDovL3p1" + "bmkuY3MudnQuZWR1PC9BdHRyaWJ1dGVWYWx1ZT4KICAgICA8UmVzb3VyY2VBdHRy" + "aWJ1dGVEZXNpZ25hdG9yIEF0dHJpYnV0ZUlkPSJ1cm46b2FzaXM6bmFtZXM6dGM6" + "eGFjbWw6MS4wOnJlc291cmNlOnJlc291cmNlLWlkIiBEYXRhVHlwZT0iaHR0cDov" + "L3d3dy53My5vcmcvMjAwMS9YTUxTY2hlbWEjYW55VVJJIiAvPiAKICAgIDwvUmVz" + "b3VyY2VNYXRjaD4KICAgPC9SZXNvdXJjZT4KICA8L1Jlc291cmNlcz4KICA8QWN0" + "aW9ucz4KICAgPEFjdGlvbj4KICAgIDxBY3Rpb25NYXRjaCBNYXRjaElkPSJ1cm46" + "b2FzaXM6bmFtZXM6dGM6eGFjbWw6MS4wOmZ1bmN0aW9uOnN0cmluZy1lcXVhbCI+" + "CiAgICAgPEF0dHJpYnV0ZVZhbHVlIERhdGFUeXBlPSJodHRwOi8vd3d3LnczLm9y" + "Zy8yMDAxL1hNTFNjaGVtYSNzdHJpbmciPgpEZWxlZ2F0ZSBBY2Nlc3MgICAgIDwv" + "QXR0cmlidXRlVmFsdWU+CgkgIDxBY3Rpb25BdHRyaWJ1dGVEZXNpZ25hdG9yIEF0" + "dHJpYnV0ZUlkPSJ1cm46b2FzaXM6bmFtZXM6dGM6eGFjbWw6MS4wOmFjdGlvbjph" + "Y3Rpb24taWQiIERhdGFUeXBlPSJodHRwOi8vd3d3LnczLm9yZy8yMDAxL1hNTFNj" + "aGVtYSNzdHJpbmciIC8+IAogICAgPC9BY3Rpb25NYXRjaD4KICAgPC9BY3Rpb24+" + "CiAgPC9BY3Rpb25zPgogPC9UYXJnZXQ+CjwvUnVsZT4KMA0GCSqGSIb3DQEBBAUA" + "A4GBAGiJSM48XsY90HlYxGmGVSmNR6ZW2As+bot3KAfiCIkUIOAqhcphBS23egTr" + "6asYwy151HshbPNYz+Cgeqs45KkVzh7bL/0e1r8sDVIaaGIkjHK3CqBABnfSayr3" + "Rd1yBoDdEv8Qb+3eEPH6ab9021AsLEnJ6LWTmybbOpMNZ3tv"); byte[] signCert = Base64.decode( "MIIGjTCCBXWgAwIBAgICAPswDQYJKoZIhvcNAQEEBQAwaTEdMBsGCSqGSIb3DQEJ" + "ARYOaXJtaGVscEB2dC5lZHUxLjAsBgNVBAMTJVZpcmdpbmlhIFRlY2ggQ2VydGlm" + "aWNhdGlvbiBBdXRob3JpdHkxCzAJBgNVBAoTAnZ0MQswCQYDVQQGEwJVUzAeFw0w" + "MzAxMzExMzUyMTRaFw0wNDAxMzExMzUyMTRaMIGDMRswGQYJKoZIhvcNAQkBFgxz" + "c2hhaEB2dC5lZHUxGzAZBgNVBAMTElN1bWl0IFNoYWggKHNzaGFoKTEbMBkGA1UE" + "CxMSVmlyZ2luaWEgVGVjaCBVc2VyMRAwDgYDVQQLEwdDbGFzcyAxMQswCQYDVQQK" + "EwJ2dDELMAkGA1UEBhMCVVMwgZ8wDQYJKoZIhvcNAQEBBQADgY0AMIGJAoGBAPDc" + "scgSKmsEp0VegFkuitD5j5PUkDuzLjlfaYONt2SN8WeqU4j2qtlCnsipa128cyKS" + "JzYe9duUdNxquh5BPIkMkHBw4jHoQA33tk0J/sydWdN74/AHPpPieK5GHwhU7GTG" + "rCCS1PJRxjXqse79ExAlul+gjQwHeldAC+d4A6oZAgMBAAGjggOmMIIDojAMBgNV" + "HRMBAf8EAjAAMBEGCWCGSAGG+EIBAQQEAwIFoDAOBgNVHQ8BAf8EBAMCA/gwHQYD" + "VR0lBBYwFAYIKwYBBQUHAwIGCCsGAQUFBwMEMB0GA1UdDgQWBBRUIoWAzlXbzBYE" + "yVTjQFWyMMKo1jCBkwYDVR0jBIGLMIGIgBTgc3Fm+TGqKDhen+oKfbl+xVbj2KFt" + "pGswaTEdMBsGCSqGSIb3DQEJARYOaXJtaGVscEB2dC5lZHUxLjAsBgNVBAMTJVZp" + "cmdpbmlhIFRlY2ggQ2VydGlmaWNhdGlvbiBBdXRob3JpdHkxCzAJBgNVBAoTAnZ0" + "MQswCQYDVQQGEwJVU4IBADCBiwYJYIZIAYb4QgENBH4WfFZpcmdpbmlhIFRlY2gg" + "Q2VydGlmaWNhdGlvbiBBdXRob3JpdHkgZGlnaXRhbCBjZXJ0aWZpY2F0ZXMgYXJl" + "IHN1YmplY3QgdG8gcG9saWNpZXMgbG9jYXRlZCBhdCBodHRwOi8vd3d3LnBraS52" + "dC5lZHUvY2EvY3BzLy4wFwYDVR0RBBAwDoEMc3NoYWhAdnQuZWR1MBkGA1UdEgQS" + "MBCBDmlybWhlbHBAdnQuZWR1MEMGCCsGAQUFBwEBBDcwNTAzBggrBgEFBQcwAoYn" + "aHR0cDovL2JveDE3Ny5jYy52dC5lZHUvY2EvaXNzdWVycy5odG1sMEQGA1UdHwQ9" + "MDswOaA3oDWGM2h0dHA6Ly9ib3gxNzcuY2MudnQuZWR1L2h0ZG9jcy1wdWJsaWMv" + "Y3JsL2NhY3JsLmNybDBUBgNVHSAETTBLMA0GCysGAQQBtGgFAQEBMDoGCysGAQQB" + "tGgFAQEBMCswKQYIKwYBBQUHAgEWHWh0dHA6Ly93d3cucGtpLnZ0LmVkdS9jYS9j" + "cHMvMD8GCWCGSAGG+EIBBAQyFjBodHRwOi8vYm94MTc3LmNjLnZ0LmVkdS9jZ2kt" + "cHVibGljL2NoZWNrX3Jldl9jYT8wPAYJYIZIAYb4QgEDBC8WLWh0dHA6Ly9ib3gx" + "NzcuY2MudnQuZWR1L2NnaS1wdWJsaWMvY2hlY2tfcmV2PzBLBglghkgBhvhCAQcE" + "PhY8aHR0cHM6Ly9ib3gxNzcuY2MudnQuZWR1L35PcGVuQ0E4LjAxMDYzMC9jZ2kt" + "cHVibGljL3JlbmV3YWw/MCwGCWCGSAGG+EIBCAQfFh1odHRwOi8vd3d3LnBraS52" + "dC5lZHUvY2EvY3BzLzANBgkqhkiG9w0BAQQFAAOCAQEAHJ2ls9yjpZVcu5DqiE67" + "r7BfkdMnm7IOj2v8cd4EAlPp6OPBmjwDMwvKRBb/P733kLBqFNWXWKTpT008R0KB" + "8kehbx4h0UPz9vp31zhGv169+5iReQUUQSIwTGNWGLzrT8kPdvxiSAvdAJxcbRBm" + "KzDic5I8PoGe48kSCkPpT1oNmnivmcu5j1SMvlx0IS2BkFMksr0OHiAW1elSnE/N" + "RuX2k73b3FucwVxB3NRo3vgoHPCTnh9r4qItAHdxFlF+pPtbw2oHESKRfMRfOIHz" + "CLQWSIa6Tvg4NIV3RRJ0sbCObesyg08lymalQMdkXwtRn5eGE00SHWwEUjSXP2gR" + "3g=="); static byte[] certWithBaseCertificateID = Base64.decode( "MIIBqzCCARQCAQEwSKBGMD6kPDA6MQswCQYDVQQGEwJJVDEOMAwGA1UEChMFVU5JVE4xDDAKBgNV" + "BAsTA0RJVDENMAsGA1UEAxMEcm9vdAIEAVMVjqB6MHikdjB0MQswCQYDVQQGEwJBVTEoMCYGA1UE" + "ChMfVGhlIExlZ2lvbiBvZiB0aGUgQm91bmN5IENhc3RsZTEjMCEGA1UECxMaQm91bmN5IFByaW1h" + "cnkgQ2VydGlmaWNhdGUxFjAUBgNVBAMTDUJvdW5jeSBDYXN0bGUwDQYJKoZIhvcNAQEFBQACBQKW" + "RhnHMCIYDzIwMDUxMjEyMTIwMDQyWhgPMjAwNTEyMTkxMjAxMzJaMA8wDQYDVRhIMQaBBGVWSVAw" + "DQYJKoZIhvcNAQEFBQADgYEAUAVin9StDaA+InxtXq/av6rUQLI9p1X6louBcj4kYJnxRvTrHpsr" + "N3+i9Uq/uk5lRdAqmPFvcmSbuE3TRAsjrXON5uFiBBKZ1AouLqcr8nHbwcdwjJ9TyUNO9I4hfpSH" + "UHHXMtBKgp4MOkhhX8xTGyWg3hp23d3GaUeg/IYlXBI="); byte[] holderCertWithBaseCertificateID = Base64.decode( "MIIBwDCCASmgAwIBAgIEAVMVjjANBgkqhkiG9w0BAQUFADA6MQswCQYDVQQGEwJJVDEOMAwGA1UE" + "ChMFVU5JVE4xDDAKBgNVBAsTA0RJVDENMAsGA1UEAxMEcm9vdDAeFw0wNTExMTExMjAxMzJaFw0w" + "NjA2MTYxMjAxMzJaMD4xCzAJBgNVBAYTAklUMQ4wDAYDVQQKEwVVTklUTjEMMAoGA1UECxMDRElU" + "MREwDwYDVQQDEwhMdWNhQm9yejBaMA0GCSqGSIb3DQEBAQUAA0kAMEYCQQC0p+RhcFdPFqlwgrIr" + "5YtqKmKXmEGb4ShypL26Ymz66ZAPdqv7EhOdzl3lZWT6srZUMWWgQMYGiHQg4z2R7X7XAgERoxUw" + "EzARBglghkgBhvhCAQEEBAMCBDAwDQYJKoZIhvcNAQEFBQADgYEAsX50VPQQCWmHvPq9y9DeCpmS" + "4szcpFAhpZyn6gYRwY9CRZVtmZKH8713XhkGDWcIEMcG0u3oTz3tdKgPU5uyIPrDEWr6w8ClUj4x" + "5aVz5c2223+dVY7KES//JSB2bE/KCIchN3kAioQ4K8O3e0OL6oDVjsqKGw5bfahgKuSIk/Q="); public String getName() { return "AttrCertTest"; } private void testCertWithBaseCertificateID() throws Exception { X509AttributeCertificateHolder attrCert = new X509AttributeCertificateHolder(certWithBaseCertificateID); CertificateFactory fact = CertificateFactory.getInstance("X.509", "BC"); X509Certificate cert = (X509Certificate)fact.generateCertificate(new ByteArrayInputStream(holderCertWithBaseCertificateID)); AttributeCertificateHolder holder = attrCert.getHolder(); if (holder.getEntityNames() != null) { fail("entity names set when none expected"); } if (!holder.getSerialNumber().equals(cert.getSerialNumber())) { fail("holder serial number doesn't match"); } if (!holder.getIssuer()[0].equals(X500Name.getInstance(cert.getIssuerX500Principal().getEncoded()))) { fail("holder issuer doesn't match"); } if (!holder.match(new JcaX509CertificateHolder(cert))) { fail("holder not matching holder certificate"); } if (!holder.equals(holder.clone())) { fail("holder clone test failed"); } if (!attrCert.getIssuer().equals(attrCert.getIssuer().clone())) { fail("issuer clone test failed"); } //equalityAndHashCodeTest(attrCert, certWithBaseCertificateID); } private void equalityAndHashCodeTest(X509AttributeCertificateHolder attrCert, byte[] encoding) throws IOException { if (!attrCert.equals(attrCert)) { fail("same certificate not equal"); } if (!attrCert.getHolder().equals(attrCert.getHolder())) { fail("same holder not equal"); } if (!attrCert.getIssuer().equals(attrCert.getIssuer())) { fail("same issuer not equal"); } if (attrCert.getHolder().equals(attrCert.getIssuer())) { fail("wrong holder equal"); } if (attrCert.getIssuer().equals(attrCert.getHolder())) { fail("wrong issuer equal"); } X509AttributeCertificateHolder attrCert2 = new X509AttributeCertificateHolder(encoding); if (attrCert2.getHolder().hashCode() != attrCert.getHolder().hashCode()) { fail("holder hashCode test failed"); } if (!attrCert2.getHolder().equals(attrCert.getHolder())) { fail("holder equals test failed"); } if (attrCert2.getIssuer().hashCode() != attrCert.getIssuer().hashCode()) { fail("issuer hashCode test failed"); } if (!attrCert2.getIssuer().equals(attrCert.getIssuer())) { fail("issuer equals test failed"); } } private void testGenerateWithCert() throws Exception { CertificateFactory fact = CertificateFactory.getInstance("X.509","BC"); X509Certificate iCert = (X509Certificate)fact.generateCertificate(new ByteArrayInputStream(signCert)); // // a sample key pair. // RSAPublicKeySpec pubKeySpec = new RSAPublicKeySpec( new BigInteger("b4a7e46170574f16a97082b22be58b6a2a629798419be12872a4bdba626cfae9900f76abfb12139dce5de56564fab2b6543165a040c606887420e33d91ed7ed7", 16), new BigInteger("11", 16)); // // set up the keys // PrivateKey privKey; PublicKey pubKey; KeyFactory kFact = KeyFactory.getInstance("RSA", "BC"); privKey = kFact.generatePrivate(RSA_PRIVATE_KEY_SPEC); pubKey = kFact.generatePublic(pubKeySpec); X509v2AttributeCertificateBuilder gen = new X509v2AttributeCertificateBuilder( new AttributeCertificateHolder(new JcaX509CertificateHolder(iCert)), new AttributeCertificateIssuer(new X500Name("cn=test")), BigInteger.ONE, new Date(System.currentTimeMillis() - 50000), new Date(System.currentTimeMillis() + 50000)); // the actual attributes GeneralName roleName = new GeneralName(GeneralName.rfc822Name, "DAU123456789"); ASN1EncodableVector roleSyntax = new ASN1EncodableVector(); roleSyntax.add(roleName); // roleSyntax OID: 2.5.24.72; gen.addAttribute(new ASN1ObjectIdentifier("2.5.24.72"), new DERSequence(roleSyntax)); ContentSigner sigGen = new JcaContentSignerBuilder("SHA1WithRSAEncryption").setProvider(BC).build(privKey); X509AttributeCertificateHolder aCert = gen.build(sigGen); if (!aCert.isValidOn(new Date())) { fail("certificate invalid"); } if (!aCert.isSignatureValid(new JcaContentVerifierProviderBuilder().setProvider(BC).build(pubKey))) { fail("certificate signature not valid"); } AttributeCertificateHolder holder = aCert.getHolder(); if (holder.getEntityNames() != null) { fail("entity names set when none expected"); } if (!holder.getSerialNumber().equals(iCert.getSerialNumber())) { fail("holder serial number doesn't match"); } if (!holder.getIssuer()[0].equals(X500Name.getInstance(iCert.getIssuerX500Principal().getEncoded()))) { fail("holder issuer doesn't match"); } if (!holder.match(new JcaX509CertificateHolder(iCert))) { fail("generated holder not matching holder certificate"); } Attribute[] attrs = aCert.getAttributes(new ASN1ObjectIdentifier("2.5.24.72")); if (attrs == null) { fail("attributes related to 2.5.24.72 not found"); } Attribute attr = attrs[0]; if (!attr.getAttrType().getId().equals("2.5.24.72")) { fail("attribute oid mismatch"); } ASN1Encodable[] values = attr.getAttrValues().toArray(); GeneralName role = GeneralNames.getInstance(values[0]).getNames()[0]; if (role.getTagNo() != GeneralName.rfc822Name) { fail("wrong general name type found in role"); } if (!((ASN1String)role.getName()).getString().equals("DAU123456789")) { fail("wrong general name value found in role"); } X509Certificate sCert = (X509Certificate)fact.generateCertificate(new ByteArrayInputStream(holderCertWithBaseCertificateID)); if (holder.match(new JcaX509CertificateHolder(sCert))) { fail("generated holder matching wrong certificate"); } equalityAndHashCodeTest(aCert, aCert.getEncoded()); } private void testGenerateWithPrincipal() throws Exception { CertificateFactory fact = CertificateFactory.getInstance("X.509","BC"); X509Certificate iCert = (X509Certificate)fact.generateCertificate(new ByteArrayInputStream(signCert)); // // a sample key pair. // RSAPublicKeySpec pubKeySpec = new RSAPublicKeySpec( new BigInteger("b4a7e46170574f16a97082b22be58b6a2a629798419be12872a4bdba626cfae9900f76abfb12139dce5de56564fab2b6543165a040c606887420e33d91ed7ed7", 16), new BigInteger("11", 16)); // // set up the keys // PrivateKey privKey; PublicKey pubKey; KeyFactory kFact = KeyFactory.getInstance("RSA", "BC"); privKey = kFact.generatePrivate(RSA_PRIVATE_KEY_SPEC); pubKey = kFact.generatePublic(pubKeySpec); X509v2AttributeCertificateBuilder gen = new X509v2AttributeCertificateBuilder( new AttributeCertificateHolder(new JcaX509CertificateHolder(iCert).getSubject()), new AttributeCertificateIssuer(new X500Name("cn=test")), BigInteger.ONE, new Date(System.currentTimeMillis() - 50000), new Date(System.currentTimeMillis() + 50000)); // the actual attributes GeneralName roleName = new GeneralName(GeneralName.rfc822Name, "DAU123456789"); ASN1EncodableVector roleSyntax = new ASN1EncodableVector(); roleSyntax.add(roleName); // roleSyntax OID: 2.5.24.72 gen.addAttribute(new ASN1ObjectIdentifier("2.5.24.72"), new DERSequence(roleSyntax)); ContentSigner sigGen = new JcaContentSignerBuilder("SHA1WithRSAEncryption").setProvider(BC).build(privKey); X509AttributeCertificateHolder aCert = gen.build(sigGen); if (!aCert.isValidOn(new Date())) { fail("certificate invalid"); } if (!aCert.isSignatureValid(new JcaContentVerifierProviderBuilder().setProvider(BC).build(pubKey))) { fail("certificate signature not valid"); } AttributeCertificateHolder holder = aCert.getHolder(); if (holder.getEntityNames() == null) { fail("entity names not set when expected"); } if (holder.getSerialNumber() != null) { fail("holder serial number found when none expected"); } if (holder.getIssuer() != null) { fail("holder issuer found when none expected"); } if (!holder.match(new JcaX509CertificateHolder(iCert))) { fail("generated holder not matching holder certificate"); } X509Certificate sCert = (X509Certificate)fact.generateCertificate(new ByteArrayInputStream(holderCertWithBaseCertificateID)); if (holder.match(sCert)) { fail("principal generated holder matching wrong certificate"); } equalityAndHashCodeTest(aCert, aCert.getEncoded()); } public void performTest() throws Exception { X509AttributeCertificateHolder aCert = new X509AttributeCertificateHolder(attrCert); CertificateFactory fact = CertificateFactory.getInstance("X.509","BC"); X509Certificate sCert = (X509Certificate)fact.generateCertificate(new ByteArrayInputStream(signCert)); if (!aCert.isSignatureValid(new JcaContentVerifierProviderBuilder().setProvider(BC).build(sCert))) { fail("certificate signature not valid"); } // // search test // List list = new ArrayList(); list.add(sCert); Store store = new JcaCertStore(list); Collection certs = store.getMatches(aCert.getIssuer()); if (certs.size() != 1 || !certs.contains(new JcaX509CertificateHolder(sCert))) { fail("sCert not found by issuer"); } Attribute[] attrs = aCert.getAttributes(new ASN1ObjectIdentifier("1.3.6.1.4.1.6760.8.1.1")); if (attrs == null || attrs.length != 1) { fail("attribute not found"); } // // reencode test // aCert = new X509AttributeCertificateHolder(aCert.getEncoded()); if (!aCert.isSignatureValid(new JcaContentVerifierProviderBuilder().setProvider(BC).build(sCert))) { fail("certificate signature not valid"); } X509AttributeCertificateHolder saCert = new X509AttributeCertificateHolder(aCert.getEncoded()); if (!aCert.getNotAfter().equals(saCert.getNotAfter())) { fail("failed date comparison"); } // base generator test // // a sample key pair. // RSAPublicKeySpec pubKeySpec = new RSAPublicKeySpec( new BigInteger("b4a7e46170574f16a97082b22be58b6a2a629798419be12872a4bdba626cfae9900f76abfb12139dce5de56564fab2b6543165a040c606887420e33d91ed7ed7", 16), new BigInteger("11", 16)); RSAPrivateCrtKeySpec privKeySpec = RSA_PRIVATE_KEY_SPEC; // // set up the keys // PrivateKey privKey; PublicKey pubKey; KeyFactory kFact = KeyFactory.getInstance("RSA", "BC"); privKey = kFact.generatePrivate(privKeySpec); pubKey = kFact.generatePublic(pubKeySpec); X509v2AttributeCertificateBuilder gen = new X509v2AttributeCertificateBuilder( aCert.getHolder(), aCert.getIssuer(), aCert.getSerialNumber(), new Date(System.currentTimeMillis() - 50000), new Date(System.currentTimeMillis() + 50000)); gen.addAttribute(attrs[0].getAttrType(), attrs[0].getAttributeValues()); ContentSigner sigGen = new JcaContentSignerBuilder("SHA1WithRSAEncryption").setProvider(BC).build(privKey); aCert = gen.build(sigGen); if (!aCert.isValidOn(new Date())) { fail("certificate not valid"); } if (!aCert.isSignatureValid(new JcaContentVerifierProviderBuilder().setProvider(BC).build(pubKey))) { fail("signature not valid"); } // as the issuer is the same this should still work (even though it is not // technically correct certs = store.getMatches(aCert.getIssuer()); if (certs.size() != 1 || !certs.contains(new JcaX509CertificateHolder(sCert))) { fail("sCert not found by issuer"); } attrs = aCert.getAttributes(new ASN1ObjectIdentifier("1.3.6.1.4.1.6760.8.1.1")); if (attrs == null || attrs.length != 1) { fail("attribute not found"); } // // reencode test // aCert = new X509AttributeCertificateHolder(aCert.getEncoded()); if (!aCert.isSignatureValid(new JcaContentVerifierProviderBuilder().setProvider(BC).build(pubKey))) { fail("signature not valid"); } AttributeCertificateIssuer issuer = aCert.getIssuer(); X500Name[] principals = issuer.getNames(); // // test holder // AttributeCertificateHolder holder = aCert.getHolder(); if (holder.getEntityNames() == null) { fail("entity names not set"); } if (holder.getSerialNumber() != null) { fail("holder serial number set when none expected"); } if (holder.getIssuer() != null) { fail("holder issuer set when none expected"); } principals = holder.getEntityNames(); X500Principal principal0 = new X500Principal(principals[0].getEncoded()); if (!principal0.toString().equals("C=US, O=vt, OU=Class 2, OU=Virginia Tech User, CN=Markus Lorch (mlorch), EMAILADDRESS=mlorch@vt.edu")) { fail("principal[0] for entity names don't match"); } // // extension test // if (aCert.hasExtensions()) { fail("hasExtensions true with no extensions"); } gen.addExtension(new ASN1ObjectIdentifier("1.1"), true, new DEROctetString(new byte[10])); gen.addExtension(new ASN1ObjectIdentifier("2.2"), false, new DEROctetString(new byte[20])); aCert = gen.build(new JcaContentSignerBuilder("SHA1withRSA").setProvider(BC).build(privKey)); Set exts = aCert.getCriticalExtensionOIDs(); if (exts.size() != 1 || !exts.contains(new ASN1ObjectIdentifier("1.1"))) { System.err.println(exts); fail("critical extension test failed"); } exts = aCert.getNonCriticalExtensionOIDs(); if (exts.size() != 1 || !exts.contains(new ASN1ObjectIdentifier("2.2"))) { fail("non-critical extension test failed"); } if (aCert.getCriticalExtensionOIDs().isEmpty()) { fail("critical extensions not found"); } Extension ext = aCert.getExtension(new ASN1ObjectIdentifier("1.1")); ASN1Encodable extValue = ext.getParsedValue(); if (!extValue.equals(new DEROctetString(new byte[10]))) { fail("wrong extension value found for 1.1"); } testCertWithBaseCertificateID(); testGenerateWithCert(); testGenerateWithPrincipal(); } public static void main( String[] args) { Security.addProvider(new BouncyCastleProvider()); runTest(new AttrCertTest()); } } bouncycastle-1.49.orig/test/src/org/bouncycastle/cert/test/ConverterTest.java0000644000175000017500000000451511726257111027057 0ustar ebourgebourgpackage org.bouncycastle.cert.test; import java.math.BigInteger; import java.security.cert.X509CertSelector; import junit.framework.Test; import junit.framework.TestCase; import junit.framework.TestSuite; import org.bouncycastle.asn1.DEROctetString; import org.bouncycastle.asn1.x500.X500Name; import org.bouncycastle.cert.selector.X509CertificateHolderSelector; import org.bouncycastle.cert.selector.jcajce.JcaSelectorConverter; import org.bouncycastle.cert.selector.jcajce.JcaX509CertSelectorConverter; import org.bouncycastle.util.Arrays; public class ConverterTest extends TestCase { public void testCertificateSelectorConversion() throws Exception { JcaX509CertSelectorConverter converter = new JcaX509CertSelectorConverter(); JcaSelectorConverter toSelector = new JcaSelectorConverter(); X509CertificateHolderSelector sid1 = new X509CertificateHolderSelector(new X500Name("CN=Test"), BigInteger.valueOf(1), new byte[20]); X509CertSelector conv = converter.getCertSelector(sid1); assertTrue(conv.getIssuerAsString().equals("CN=Test")); assertTrue(Arrays.areEqual(conv.getSubjectKeyIdentifier(), new DEROctetString(new byte[20]).getEncoded())); assertEquals(conv.getSerialNumber(), sid1.getSerialNumber()); X509CertificateHolderSelector sid2 = toSelector.getCertificateHolderSelector(conv); assertEquals(sid1, sid2); sid1 = new X509CertificateHolderSelector(new X500Name("CN=Test"), BigInteger.valueOf(1)); conv = converter.getCertSelector(sid1); assertTrue(conv.getIssuerAsString().equals("CN=Test")); assertNull(conv.getSubjectKeyIdentifier()); assertEquals(conv.getSerialNumber(), sid1.getSerialNumber()); sid2 = toSelector.getCertificateHolderSelector(conv); assertEquals(sid1, sid2); sid1 = new X509CertificateHolderSelector(new byte[20]); conv = converter.getCertSelector(sid1); assertNull(conv.getIssuerAsString()); assertTrue(Arrays.areEqual(conv.getSubjectKeyIdentifier(), new DEROctetString(new byte[20]).getEncoded())); assertNull(conv.getSerialNumber()); sid2 = toSelector.getCertificateHolderSelector(conv); assertEquals(sid1, sid2); } public static Test suite() { return new TestSuite(ConverterTest.class); } } bouncycastle-1.49.orig/test/src/org/bouncycastle/cert/test/BcAttrCertTest.java0000644000175000017500000006301611737301302027100 0ustar ebourgebourgpackage org.bouncycastle.cert.test; import java.io.IOException; import java.math.BigInteger; import java.util.ArrayList; import java.util.Collection; import java.util.Date; import java.util.List; import java.util.Set; import junit.framework.TestCase; import org.bouncycastle.asn1.ASN1Encodable; import org.bouncycastle.asn1.ASN1EncodableVector; import org.bouncycastle.asn1.ASN1ObjectIdentifier; import org.bouncycastle.asn1.ASN1String; import org.bouncycastle.asn1.DEROctetString; import org.bouncycastle.asn1.DERSequence; import org.bouncycastle.asn1.x500.X500Name; import org.bouncycastle.asn1.x500.style.RFC4519Style; import org.bouncycastle.asn1.x509.AlgorithmIdentifier; import org.bouncycastle.asn1.x509.Attribute; import org.bouncycastle.asn1.x509.Extension; import org.bouncycastle.asn1.x509.GeneralName; import org.bouncycastle.asn1.x509.GeneralNames; import org.bouncycastle.cert.AttributeCertificateHolder; import org.bouncycastle.cert.AttributeCertificateIssuer; import org.bouncycastle.cert.X509AttributeCertificateHolder; import org.bouncycastle.cert.X509CertificateHolder; import org.bouncycastle.cert.X509v2AttributeCertificateBuilder; import org.bouncycastle.crypto.params.AsymmetricKeyParameter; import org.bouncycastle.crypto.params.RSAKeyParameters; import org.bouncycastle.crypto.params.RSAPrivateCrtKeyParameters; import org.bouncycastle.operator.ContentSigner; import org.bouncycastle.operator.DefaultDigestAlgorithmIdentifierFinder; import org.bouncycastle.operator.DefaultSignatureAlgorithmIdentifierFinder; import org.bouncycastle.operator.bc.BcRSAContentSignerBuilder; import org.bouncycastle.operator.bc.BcRSAContentVerifierProviderBuilder; import org.bouncycastle.util.CollectionStore; import org.bouncycastle.util.Store; import org.bouncycastle.util.encoders.Base64; public class BcAttrCertTest extends TestCase { DefaultSignatureAlgorithmIdentifierFinder sigAlgFinder = new DefaultSignatureAlgorithmIdentifierFinder(); DefaultDigestAlgorithmIdentifierFinder digAlgFinder = new DefaultDigestAlgorithmIdentifierFinder(); private static final AsymmetricKeyParameter RSA_PRIVATE_KEY_SPEC = new RSAPrivateCrtKeyParameters( new BigInteger("b4a7e46170574f16a97082b22be58b6a2a629798419be12872a4bdba626cfae9900f76abfb12139dce5de56564fab2b6543165a040c606887420e33d91ed7ed7", 16), new BigInteger("11", 16), new BigInteger("9f66f6b05410cd503b2709e88115d55daced94d1a34d4e32bf824d0dde6028ae79c5f07b580f5dce240d7111f7ddb130a7945cd7d957d1920994da389f490c89", 16), new BigInteger("c0a0758cdf14256f78d4708c86becdead1b50ad4ad6c5c703e2168fbf37884cb", 16), new BigInteger("f01734d7960ea60070f1b06f2bb81bfac48ff192ae18451d5e56c734a5aab8a5", 16), new BigInteger("b54bb9edff22051d9ee60f9351a48591b6500a319429c069a3e335a1d6171391", 16), new BigInteger("d3d83daf2a0cecd3367ae6f8ae1aeb82e9ac2f816c6fc483533d8297dd7884cd", 16), new BigInteger("b8f52fc6f38593dabb661d3f50f8897f8106eee68b1bce78a95b132b4e5b5d19", 16)); public static byte[] attrCert = Base64.decode( "MIIHQDCCBqkCAQEwgZChgY2kgYowgYcxHDAaBgkqhkiG9w0BCQEWDW1sb3JjaEB2" + "dC5lZHUxHjAcBgNVBAMTFU1hcmt1cyBMb3JjaCAobWxvcmNoKTEbMBkGA1UECxMS" + "VmlyZ2luaWEgVGVjaCBVc2VyMRAwDgYDVQQLEwdDbGFzcyAyMQswCQYDVQQKEwJ2" + "dDELMAkGA1UEBhMCVVMwgYmkgYYwgYMxGzAZBgkqhkiG9w0BCQEWDHNzaGFoQHZ0" + "LmVkdTEbMBkGA1UEAxMSU3VtaXQgU2hhaCAoc3NoYWgpMRswGQYDVQQLExJWaXJn" + "aW5pYSBUZWNoIFVzZXIxEDAOBgNVBAsTB0NsYXNzIDExCzAJBgNVBAoTAnZ0MQsw" + "CQYDVQQGEwJVUzANBgkqhkiG9w0BAQQFAAIBBTAiGA8yMDAzMDcxODE2MDgwMloY" + "DzIwMDMwNzI1MTYwODAyWjCCBU0wggVJBgorBgEEAbRoCAEBMYIFORaCBTU8UnVs" + "ZSBSdWxlSWQ9IkZpbGUtUHJpdmlsZWdlLVJ1bGUiIEVmZmVjdD0iUGVybWl0Ij4K" + "IDxUYXJnZXQ+CiAgPFN1YmplY3RzPgogICA8U3ViamVjdD4KICAgIDxTdWJqZWN0" + "TWF0Y2ggTWF0Y2hJZD0idXJuOm9hc2lzOm5hbWVzOnRjOnhhY21sOjEuMDpmdW5j" + "dGlvbjpzdHJpbmctZXF1YWwiPgogICAgIDxBdHRyaWJ1dGVWYWx1ZSBEYXRhVHlw" + "ZT0iaHR0cDovL3d3dy53My5vcmcvMjAwMS9YTUxTY2hlbWEjc3RyaW5nIj4KICAg" + "ICAgIENOPU1hcmt1cyBMb3JjaDwvQXR0cmlidXRlVmFsdWU+CiAgICAgPFN1Ympl" + "Y3RBdHRyaWJ1dGVEZXNpZ25hdG9yIEF0dHJpYnV0ZUlkPSJ1cm46b2FzaXM6bmFt" + "ZXM6dGM6eGFjbWw6MS4wOnN1YmplY3Q6c3ViamVjdC1pZCIgRGF0YVR5cGU9Imh0" + "dHA6Ly93d3cudzMub3JnLzIwMDEvWE1MU2NoZW1hI3N0cmluZyIgLz4gCiAgICA8" + "L1N1YmplY3RNYXRjaD4KICAgPC9TdWJqZWN0PgogIDwvU3ViamVjdHM+CiAgPFJl" + "c291cmNlcz4KICAgPFJlc291cmNlPgogICAgPFJlc291cmNlTWF0Y2ggTWF0Y2hJ" + "ZD0idXJuOm9hc2lzOm5hbWVzOnRjOnhhY21sOjEuMDpmdW5jdGlvbjpzdHJpbmct" + "ZXF1YWwiPgogICAgIDxBdHRyaWJ1dGVWYWx1ZSBEYXRhVHlwZT0iaHR0cDovL3d3" + "dy53My5vcmcvMjAwMS9YTUxTY2hlbWEjYW55VVJJIj4KICAgICAgaHR0cDovL3p1" + "bmkuY3MudnQuZWR1PC9BdHRyaWJ1dGVWYWx1ZT4KICAgICA8UmVzb3VyY2VBdHRy" + "aWJ1dGVEZXNpZ25hdG9yIEF0dHJpYnV0ZUlkPSJ1cm46b2FzaXM6bmFtZXM6dGM6" + "eGFjbWw6MS4wOnJlc291cmNlOnJlc291cmNlLWlkIiBEYXRhVHlwZT0iaHR0cDov" + "L3d3dy53My5vcmcvMjAwMS9YTUxTY2hlbWEjYW55VVJJIiAvPiAKICAgIDwvUmVz" + "b3VyY2VNYXRjaD4KICAgPC9SZXNvdXJjZT4KICA8L1Jlc291cmNlcz4KICA8QWN0" + "aW9ucz4KICAgPEFjdGlvbj4KICAgIDxBY3Rpb25NYXRjaCBNYXRjaElkPSJ1cm46" + "b2FzaXM6bmFtZXM6dGM6eGFjbWw6MS4wOmZ1bmN0aW9uOnN0cmluZy1lcXVhbCI+" + "CiAgICAgPEF0dHJpYnV0ZVZhbHVlIERhdGFUeXBlPSJodHRwOi8vd3d3LnczLm9y" + "Zy8yMDAxL1hNTFNjaGVtYSNzdHJpbmciPgpEZWxlZ2F0ZSBBY2Nlc3MgICAgIDwv" + "QXR0cmlidXRlVmFsdWU+CgkgIDxBY3Rpb25BdHRyaWJ1dGVEZXNpZ25hdG9yIEF0" + "dHJpYnV0ZUlkPSJ1cm46b2FzaXM6bmFtZXM6dGM6eGFjbWw6MS4wOmFjdGlvbjph" + "Y3Rpb24taWQiIERhdGFUeXBlPSJodHRwOi8vd3d3LnczLm9yZy8yMDAxL1hNTFNj" + "aGVtYSNzdHJpbmciIC8+IAogICAgPC9BY3Rpb25NYXRjaD4KICAgPC9BY3Rpb24+" + "CiAgPC9BY3Rpb25zPgogPC9UYXJnZXQ+CjwvUnVsZT4KMA0GCSqGSIb3DQEBBAUA" + "A4GBAGiJSM48XsY90HlYxGmGVSmNR6ZW2As+bot3KAfiCIkUIOAqhcphBS23egTr" + "6asYwy151HshbPNYz+Cgeqs45KkVzh7bL/0e1r8sDVIaaGIkjHK3CqBABnfSayr3" + "Rd1yBoDdEv8Qb+3eEPH6ab9021AsLEnJ6LWTmybbOpMNZ3tv"); byte[] signCert = Base64.decode( "MIIGjTCCBXWgAwIBAgICAPswDQYJKoZIhvcNAQEEBQAwaTEdMBsGCSqGSIb3DQEJ" + "ARYOaXJtaGVscEB2dC5lZHUxLjAsBgNVBAMTJVZpcmdpbmlhIFRlY2ggQ2VydGlm" + "aWNhdGlvbiBBdXRob3JpdHkxCzAJBgNVBAoTAnZ0MQswCQYDVQQGEwJVUzAeFw0w" + "MzAxMzExMzUyMTRaFw0wNDAxMzExMzUyMTRaMIGDMRswGQYJKoZIhvcNAQkBFgxz" + "c2hhaEB2dC5lZHUxGzAZBgNVBAMTElN1bWl0IFNoYWggKHNzaGFoKTEbMBkGA1UE" + "CxMSVmlyZ2luaWEgVGVjaCBVc2VyMRAwDgYDVQQLEwdDbGFzcyAxMQswCQYDVQQK" + "EwJ2dDELMAkGA1UEBhMCVVMwgZ8wDQYJKoZIhvcNAQEBBQADgY0AMIGJAoGBAPDc" + "scgSKmsEp0VegFkuitD5j5PUkDuzLjlfaYONt2SN8WeqU4j2qtlCnsipa128cyKS" + "JzYe9duUdNxquh5BPIkMkHBw4jHoQA33tk0J/sydWdN74/AHPpPieK5GHwhU7GTG" + "rCCS1PJRxjXqse79ExAlul+gjQwHeldAC+d4A6oZAgMBAAGjggOmMIIDojAMBgNV" + "HRMBAf8EAjAAMBEGCWCGSAGG+EIBAQQEAwIFoDAOBgNVHQ8BAf8EBAMCA/gwHQYD" + "VR0lBBYwFAYIKwYBBQUHAwIGCCsGAQUFBwMEMB0GA1UdDgQWBBRUIoWAzlXbzBYE" + "yVTjQFWyMMKo1jCBkwYDVR0jBIGLMIGIgBTgc3Fm+TGqKDhen+oKfbl+xVbj2KFt" + "pGswaTEdMBsGCSqGSIb3DQEJARYOaXJtaGVscEB2dC5lZHUxLjAsBgNVBAMTJVZp" + "cmdpbmlhIFRlY2ggQ2VydGlmaWNhdGlvbiBBdXRob3JpdHkxCzAJBgNVBAoTAnZ0" + "MQswCQYDVQQGEwJVU4IBADCBiwYJYIZIAYb4QgENBH4WfFZpcmdpbmlhIFRlY2gg" + "Q2VydGlmaWNhdGlvbiBBdXRob3JpdHkgZGlnaXRhbCBjZXJ0aWZpY2F0ZXMgYXJl" + "IHN1YmplY3QgdG8gcG9saWNpZXMgbG9jYXRlZCBhdCBodHRwOi8vd3d3LnBraS52" + "dC5lZHUvY2EvY3BzLy4wFwYDVR0RBBAwDoEMc3NoYWhAdnQuZWR1MBkGA1UdEgQS" + "MBCBDmlybWhlbHBAdnQuZWR1MEMGCCsGAQUFBwEBBDcwNTAzBggrBgEFBQcwAoYn" + "aHR0cDovL2JveDE3Ny5jYy52dC5lZHUvY2EvaXNzdWVycy5odG1sMEQGA1UdHwQ9" + "MDswOaA3oDWGM2h0dHA6Ly9ib3gxNzcuY2MudnQuZWR1L2h0ZG9jcy1wdWJsaWMv" + "Y3JsL2NhY3JsLmNybDBUBgNVHSAETTBLMA0GCysGAQQBtGgFAQEBMDoGCysGAQQB" + "tGgFAQEBMCswKQYIKwYBBQUHAgEWHWh0dHA6Ly93d3cucGtpLnZ0LmVkdS9jYS9j" + "cHMvMD8GCWCGSAGG+EIBBAQyFjBodHRwOi8vYm94MTc3LmNjLnZ0LmVkdS9jZ2kt" + "cHVibGljL2NoZWNrX3Jldl9jYT8wPAYJYIZIAYb4QgEDBC8WLWh0dHA6Ly9ib3gx" + "NzcuY2MudnQuZWR1L2NnaS1wdWJsaWMvY2hlY2tfcmV2PzBLBglghkgBhvhCAQcE" + "PhY8aHR0cHM6Ly9ib3gxNzcuY2MudnQuZWR1L35PcGVuQ0E4LjAxMDYzMC9jZ2kt" + "cHVibGljL3JlbmV3YWw/MCwGCWCGSAGG+EIBCAQfFh1odHRwOi8vd3d3LnBraS52" + "dC5lZHUvY2EvY3BzLzANBgkqhkiG9w0BAQQFAAOCAQEAHJ2ls9yjpZVcu5DqiE67" + "r7BfkdMnm7IOj2v8cd4EAlPp6OPBmjwDMwvKRBb/P733kLBqFNWXWKTpT008R0KB" + "8kehbx4h0UPz9vp31zhGv169+5iReQUUQSIwTGNWGLzrT8kPdvxiSAvdAJxcbRBm" + "KzDic5I8PoGe48kSCkPpT1oNmnivmcu5j1SMvlx0IS2BkFMksr0OHiAW1elSnE/N" + "RuX2k73b3FucwVxB3NRo3vgoHPCTnh9r4qItAHdxFlF+pPtbw2oHESKRfMRfOIHz" + "CLQWSIa6Tvg4NIV3RRJ0sbCObesyg08lymalQMdkXwtRn5eGE00SHWwEUjSXP2gR" + "3g=="); static byte[] certWithBaseCertificateID = Base64.decode( "MIIBqzCCARQCAQEwSKBGMD6kPDA6MQswCQYDVQQGEwJJVDEOMAwGA1UEChMFVU5JVE4xDDAKBgNV" + "BAsTA0RJVDENMAsGA1UEAxMEcm9vdAIEAVMVjqB6MHikdjB0MQswCQYDVQQGEwJBVTEoMCYGA1UE" + "ChMfVGhlIExlZ2lvbiBvZiB0aGUgQm91bmN5IENhc3RsZTEjMCEGA1UECxMaQm91bmN5IFByaW1h" + "cnkgQ2VydGlmaWNhdGUxFjAUBgNVBAMTDUJvdW5jeSBDYXN0bGUwDQYJKoZIhvcNAQEFBQACBQKW" + "RhnHMCIYDzIwMDUxMjEyMTIwMDQyWhgPMjAwNTEyMTkxMjAxMzJaMA8wDQYDVRhIMQaBBGVWSVAw" + "DQYJKoZIhvcNAQEFBQADgYEAUAVin9StDaA+InxtXq/av6rUQLI9p1X6louBcj4kYJnxRvTrHpsr" + "N3+i9Uq/uk5lRdAqmPFvcmSbuE3TRAsjrXON5uFiBBKZ1AouLqcr8nHbwcdwjJ9TyUNO9I4hfpSH" + "UHHXMtBKgp4MOkhhX8xTGyWg3hp23d3GaUeg/IYlXBI="); byte[] holderCertWithBaseCertificateID = Base64.decode( "MIIBwDCCASmgAwIBAgIEAVMVjjANBgkqhkiG9w0BAQUFADA6MQswCQYDVQQGEwJJVDEOMAwGA1UE" + "ChMFVU5JVE4xDDAKBgNVBAsTA0RJVDENMAsGA1UEAxMEcm9vdDAeFw0wNTExMTExMjAxMzJaFw0w" + "NjA2MTYxMjAxMzJaMD4xCzAJBgNVBAYTAklUMQ4wDAYDVQQKEwVVTklUTjEMMAoGA1UECxMDRElU" + "MREwDwYDVQQDEwhMdWNhQm9yejBaMA0GCSqGSIb3DQEBAQUAA0kAMEYCQQC0p+RhcFdPFqlwgrIr" + "5YtqKmKXmEGb4ShypL26Ymz66ZAPdqv7EhOdzl3lZWT6srZUMWWgQMYGiHQg4z2R7X7XAgERoxUw" + "EzARBglghkgBhvhCAQEEBAMCBDAwDQYJKoZIhvcNAQEFBQADgYEAsX50VPQQCWmHvPq9y9DeCpmS" + "4szcpFAhpZyn6gYRwY9CRZVtmZKH8713XhkGDWcIEMcG0u3oTz3tdKgPU5uyIPrDEWr6w8ClUj4x" + "5aVz5c2223+dVY7KES//JSB2bE/KCIchN3kAioQ4K8O3e0OL6oDVjsqKGw5bfahgKuSIk/Q="); public String getName() { return "AttrCertTest"; } public void testCertWithBaseCertificateID() throws Exception { X509AttributeCertificateHolder attrCert = new X509AttributeCertificateHolder(certWithBaseCertificateID); X509CertificateHolder cert = new X509CertificateHolder(holderCertWithBaseCertificateID); AttributeCertificateHolder holder = attrCert.getHolder(); if (holder.getEntityNames() != null) { fail("entity names set when none expected"); } if (!holder.getSerialNumber().equals(cert.getSerialNumber())) { fail("holder serial number doesn't match"); } if (!holder.getIssuer()[0].equals(cert.getIssuer())) { fail("holder issuer doesn't match"); } if (!holder.match(cert)) { fail("holder not matching holder certificate"); } if (!holder.equals(holder.clone())) { fail("holder clone test failed"); } if (!attrCert.getIssuer().equals(attrCert.getIssuer().clone())) { fail("issuer clone test failed"); } //equalityAndHashCodeTest(attrCert, certWithBaseCertificateID); } private void equalityAndHashCodeTest(X509AttributeCertificateHolder attrCert, byte[] encoding) throws IOException { if (!attrCert.equals(attrCert)) { fail("same certificate not equal"); } if (!attrCert.getHolder().equals(attrCert.getHolder())) { fail("same holder not equal"); } if (!attrCert.getIssuer().equals(attrCert.getIssuer())) { fail("same issuer not equal"); } if (attrCert.getHolder().equals(attrCert.getIssuer())) { fail("wrong holder equal"); } if (attrCert.getIssuer().equals(attrCert.getHolder())) { fail("wrong issuer equal"); } X509AttributeCertificateHolder attrCert2 = new X509AttributeCertificateHolder(encoding); if (attrCert2.getHolder().hashCode() != attrCert.getHolder().hashCode()) { fail("holder hashCode test failed"); } if (!attrCert2.getHolder().equals(attrCert.getHolder())) { fail("holder equals test failed"); } if (attrCert2.getIssuer().hashCode() != attrCert.getIssuer().hashCode()) { fail("issuer hashCode test failed"); } if (!attrCert2.getIssuer().equals(attrCert.getIssuer())) { fail("issuer equals test failed"); } } public void testGenerateWithCert() throws Exception { X509CertificateHolder iCert = new X509CertificateHolder(signCert); // // a sample key pair. // AsymmetricKeyParameter pubKey = new RSAKeyParameters( false, new BigInteger("b4a7e46170574f16a97082b22be58b6a2a629798419be12872a4bdba626cfae9900f76abfb12139dce5de56564fab2b6543165a040c606887420e33d91ed7ed7", 16), new BigInteger("11", 16)); // // set up the keys // AsymmetricKeyParameter privKey = RSA_PRIVATE_KEY_SPEC; X509v2AttributeCertificateBuilder gen = new X509v2AttributeCertificateBuilder( new AttributeCertificateHolder(iCert), new AttributeCertificateIssuer(new X500Name("cn=test")), BigInteger.ONE, new Date(System.currentTimeMillis() - 50000), new Date(System.currentTimeMillis() + 50000)); // the actual attributes GeneralName roleName = new GeneralName(GeneralName.rfc822Name, "DAU123456789"); ASN1EncodableVector roleSyntax = new ASN1EncodableVector(); roleSyntax.add(roleName); // roleSyntax OID: 2.5.24.72; gen.addAttribute(new ASN1ObjectIdentifier("2.5.24.72"), new DERSequence(roleSyntax)); AlgorithmIdentifier sigAlg = sigAlgFinder.find("SHA1withRSA"); AlgorithmIdentifier digAlg = digAlgFinder.find(sigAlg); ContentSigner sigGen = new BcRSAContentSignerBuilder(sigAlg, digAlg).build(privKey); X509AttributeCertificateHolder aCert = gen.build(sigGen); if (!aCert.isValidOn(new Date())) { fail("certificate invalid"); } if (!aCert.isSignatureValid(new BcRSAContentVerifierProviderBuilder(digAlgFinder).build(pubKey))) { fail("certificate signature not valid"); } AttributeCertificateHolder holder = aCert.getHolder(); if (holder.getEntityNames() != null) { fail("entity names set when none expected"); } if (!holder.getSerialNumber().equals(iCert.getSerialNumber())) { fail("holder serial number doesn't match"); } if (!holder.getIssuer()[0].equals(iCert.getIssuer())) { fail("holder issuer doesn't match"); } if (!holder.match(iCert)) { fail("generated holder not matching holder certificate"); } Attribute[] attrs = aCert.getAttributes(new ASN1ObjectIdentifier("2.5.24.72")); if (attrs == null) { fail("attributes related to 2.5.24.72 not found"); } Attribute attr = attrs[0]; if (!attr.getAttrType().getId().equals("2.5.24.72")) { fail("attribute oid mismatch"); } ASN1Encodable[] values = attr.getAttrValues().toArray(); GeneralName role = GeneralNames.getInstance(values[0]).getNames()[0]; if (role.getTagNo() != GeneralName.rfc822Name) { fail("wrong general name type found in role"); } if (!((ASN1String)role.getName()).getString().equals("DAU123456789")) { fail("wrong general name value found in role"); } X509CertificateHolder sCert = new X509CertificateHolder(holderCertWithBaseCertificateID); if (holder.match(sCert)) { fail("generated holder matching wrong certificate"); } equalityAndHashCodeTest(aCert, aCert.getEncoded()); } public void testGenerateWithPrincipal() throws Exception { X509CertificateHolder iCert = new X509CertificateHolder(signCert); // // a sample key pair. // RSAKeyParameters pubKey = new RSAKeyParameters( false, new BigInteger("b4a7e46170574f16a97082b22be58b6a2a629798419be12872a4bdba626cfae9900f76abfb12139dce5de56564fab2b6543165a040c606887420e33d91ed7ed7", 16), new BigInteger("11", 16)); // // set up the keys // AsymmetricKeyParameter privKey = RSA_PRIVATE_KEY_SPEC; X509v2AttributeCertificateBuilder gen = new X509v2AttributeCertificateBuilder( new AttributeCertificateHolder(iCert.getSubject()), new AttributeCertificateIssuer(new X500Name("cn=test")), BigInteger.ONE, new Date(System.currentTimeMillis() - 50000), new Date(System.currentTimeMillis() + 50000)); // the actual attributes GeneralName roleName = new GeneralName(GeneralName.rfc822Name, "DAU123456789"); ASN1EncodableVector roleSyntax = new ASN1EncodableVector(); roleSyntax.add(roleName); // roleSyntax OID: 2.5.24.72 gen.addAttribute(new ASN1ObjectIdentifier("2.5.24.72"), new DERSequence(roleSyntax)); AlgorithmIdentifier sigAlg = sigAlgFinder.find("SHA1withRSA"); AlgorithmIdentifier digAlg = digAlgFinder.find(sigAlg); ContentSigner sigGen = new BcRSAContentSignerBuilder(sigAlg, digAlg).build(privKey); X509AttributeCertificateHolder aCert = gen.build(sigGen); if (!aCert.isValidOn(new Date())) { fail("certificate invalid"); } if (!aCert.isSignatureValid(new BcRSAContentVerifierProviderBuilder(digAlgFinder).build(pubKey))) { fail("certificate signature not valid"); } AttributeCertificateHolder holder = aCert.getHolder(); if (holder.getEntityNames() == null) { fail("entity names not set when expected"); } if (holder.getSerialNumber() != null) { fail("holder serial number found when none expected"); } if (holder.getIssuer() != null) { fail("holder issuer found when none expected"); } if (!holder.match(iCert)) { fail("generated holder not matching holder certificate"); } X509CertificateHolder sCert = new X509CertificateHolder(holderCertWithBaseCertificateID); if (holder.match(sCert)) { fail("principal generated holder matching wrong certificate"); } equalityAndHashCodeTest(aCert, aCert.getEncoded()); } public void testFully() throws Exception { X509AttributeCertificateHolder aCert = new X509AttributeCertificateHolder(attrCert); X509CertificateHolder sCert = new X509CertificateHolder(signCert); if (!aCert.isSignatureValid(new BcRSAContentVerifierProviderBuilder(digAlgFinder).build(sCert))) { fail("certificate signature not valid"); } // // search test // List list = new ArrayList(); list.add(sCert); Store store = new CollectionStore(list); Collection certs = store.getMatches(aCert.getIssuer()); if (certs.size() != 1 || !certs.contains(sCert)) { fail("sCert not found by issuer"); } Attribute[] attrs = aCert.getAttributes(new ASN1ObjectIdentifier("1.3.6.1.4.1.6760.8.1.1")); if (attrs == null || attrs.length != 1) { fail("attribute not found"); } // // reencode test // aCert = new X509AttributeCertificateHolder(aCert.getEncoded()); if (!aCert.isSignatureValid(new BcRSAContentVerifierProviderBuilder(digAlgFinder).build(sCert))) { fail("certificate signature not valid"); } X509AttributeCertificateHolder saCert = new X509AttributeCertificateHolder(aCert.getEncoded()); if (!aCert.getNotAfter().equals(saCert.getNotAfter())) { fail("failed date comparison"); } // base generator test // // a sample key pair. // AsymmetricKeyParameter pubKey = new RSAKeyParameters( false, new BigInteger("b4a7e46170574f16a97082b22be58b6a2a629798419be12872a4bdba626cfae9900f76abfb12139dce5de56564fab2b6543165a040c606887420e33d91ed7ed7", 16), new BigInteger("11", 16)); AsymmetricKeyParameter privKey = RSA_PRIVATE_KEY_SPEC; X509v2AttributeCertificateBuilder gen = new X509v2AttributeCertificateBuilder( aCert.getHolder(), aCert.getIssuer(), aCert.getSerialNumber(), new Date(System.currentTimeMillis() - 50000), new Date(System.currentTimeMillis() + 50000)); gen.addAttribute(attrs[0].getAttrType(), attrs[0].getAttributeValues()); AlgorithmIdentifier sigAlg = sigAlgFinder.find("SHA1withRSA"); AlgorithmIdentifier digAlg = digAlgFinder.find(sigAlg); ContentSigner sigGen = new BcRSAContentSignerBuilder(sigAlg, digAlg).build(privKey); aCert = gen.build(sigGen); if (!aCert.isValidOn(new Date())) { fail("certificate not valid"); } if (!aCert.isSignatureValid(new BcRSAContentVerifierProviderBuilder(digAlgFinder).build(pubKey))) { fail("signature not valid"); } // as the issuer is the same this should still work (even though it is not // technically correct certs = store.getMatches(aCert.getIssuer()); if (certs.size() != 1 || !certs.contains(sCert)) { fail("sCert not found by issuer"); } attrs = aCert.getAttributes(new ASN1ObjectIdentifier("1.3.6.1.4.1.6760.8.1.1")); if (attrs == null || attrs.length != 1) { fail("attribute not found"); } // // reencode test // aCert = new X509AttributeCertificateHolder(aCert.getEncoded()); if (!aCert.isSignatureValid(new BcRSAContentVerifierProviderBuilder(digAlgFinder).build(pubKey))) { fail("signature not valid"); } AttributeCertificateIssuer issuer = aCert.getIssuer(); X500Name[] principals = issuer.getNames(); // // test holder // AttributeCertificateHolder holder = aCert.getHolder(); if (holder.getEntityNames() == null) { fail("entity names not set"); } if (holder.getSerialNumber() != null) { fail("holder serial number set when none expected"); } if (holder.getIssuer() != null) { fail("holder issuer set when none expected"); } principals = holder.getEntityNames(); X500Name principal0 = new X500Name(RFC4519Style.INSTANCE, principals[0]); if (!principal0.toString().equals("c=US,o=vt,ou=Class 2,ou=Virginia Tech User,cn=Markus Lorch (mlorch),1.2.840.113549.1.9.1=mlorch@vt.edu")) { System.err.println(principal0.toString()); fail("principal[0] for entity names don't match"); } // // extension test // if (aCert.hasExtensions()) { fail("hasExtensions true with no extensions"); } gen.addExtension(new ASN1ObjectIdentifier("1.1"), true, new DEROctetString(new byte[10])); gen.addExtension(new ASN1ObjectIdentifier("2.2"), false, new DEROctetString(new byte[20])); aCert = gen.build(sigGen); Set exts = aCert.getCriticalExtensionOIDs(); if (exts.size() != 1 || !exts.contains(new ASN1ObjectIdentifier("1.1"))) { fail("critical extension test failed"); } exts = aCert.getNonCriticalExtensionOIDs(); if (exts.size() != 1 || !exts.contains(new ASN1ObjectIdentifier("2.2"))) { fail("non-critical extension test failed"); } if (aCert.getCriticalExtensionOIDs().isEmpty()) { fail("critical extensions not found"); } Extension ext = aCert.getExtension(new ASN1ObjectIdentifier("1.1")); ASN1Encodable extValue = ext.getParsedValue(); if (!extValue.equals(new DEROctetString(new byte[10]))) { fail("wrong extension value found for 1.1"); } } } bouncycastle-1.49.orig/test/src/org/bouncycastle/cert/test/PKCS10Test.java0000644000175000017500000006564012132447316026017 0ustar ebourgebourgpackage org.bouncycastle.cert.test; import java.math.BigInteger; import java.security.KeyFactory; import java.security.KeyPair; import java.security.KeyPairGenerator; import java.security.PrivateKey; import java.security.PublicKey; import java.security.SecureRandom; import java.security.Security; import java.security.Signature; import java.security.spec.RSAPrivateCrtKeySpec; import java.security.spec.RSAPublicKeySpec; import java.util.Vector; import javax.security.auth.x500.X500Principal; import org.bouncycastle.asn1.DERObjectIdentifier; import org.bouncycastle.asn1.DEROctetString; import org.bouncycastle.asn1.cryptopro.CryptoProObjectIdentifiers; import org.bouncycastle.asn1.pkcs.Attribute; import org.bouncycastle.asn1.pkcs.PKCSObjectIdentifiers; import org.bouncycastle.asn1.x500.X500Name; import org.bouncycastle.asn1.x500.X500NameBuilder; import org.bouncycastle.asn1.x500.style.BCStyle; import org.bouncycastle.asn1.x509.BasicConstraints; import org.bouncycastle.asn1.x509.KeyUsage; import org.bouncycastle.asn1.x509.SubjectKeyIdentifier; import org.bouncycastle.asn1.x509.X509Extension; import org.bouncycastle.asn1.x509.X509Extensions; import org.bouncycastle.asn1.x9.X9ObjectIdentifiers; import org.bouncycastle.jce.ECGOST3410NamedCurveTable; import org.bouncycastle.jce.ECNamedCurveTable; import org.bouncycastle.jce.interfaces.ECPointEncoder; import org.bouncycastle.jce.provider.BouncyCastleProvider; import org.bouncycastle.jce.spec.ECNamedCurveParameterSpec; import org.bouncycastle.jce.spec.ECParameterSpec; import org.bouncycastle.jce.spec.ECPrivateKeySpec; import org.bouncycastle.jce.spec.ECPublicKeySpec; import org.bouncycastle.math.ec.ECCurve; import org.bouncycastle.operator.ContentSigner; import org.bouncycastle.operator.ContentVerifierProvider; import org.bouncycastle.operator.jcajce.JcaContentSignerBuilder; import org.bouncycastle.operator.jcajce.JcaContentVerifierProviderBuilder; import org.bouncycastle.pkcs.PKCS10CertificationRequest; import org.bouncycastle.pkcs.PKCS10CertificationRequestBuilder; import org.bouncycastle.pkcs.jcajce.JcaPKCS10CertificationRequest; import org.bouncycastle.pkcs.jcajce.JcaPKCS10CertificationRequestBuilder; import org.bouncycastle.util.Arrays; import org.bouncycastle.util.encoders.Base64; import org.bouncycastle.util.encoders.Hex; import org.bouncycastle.util.test.SimpleTest; import org.bouncycastle.x509.extension.SubjectKeyIdentifierStructure; /** **/ public class PKCS10Test extends SimpleTest { private static final String BC = BouncyCastleProvider.PROVIDER_NAME; private byte[] gost3410EC_A = Base64.decode( "MIIBOzCB6wIBADB/MQ0wCwYDVQQDEwR0ZXN0MRUwEwYDVQQKEwxEZW1vcyBDbyBMdGQxHjAcBgNV" +"BAsTFUNyeXB0b2dyYXBoeSBkaXZpc2lvbjEPMA0GA1UEBxMGTW9zY293MQswCQYDVQQGEwJydTEZ" +"MBcGCSqGSIb3DQEJARYKc2RiQGRvbC5ydTBjMBwGBiqFAwICEzASBgcqhQMCAiMBBgcqhQMCAh4B" +"A0MABEBYx0P2D7YuuZo5HgdIAUKAXcLBDZ+4LYFgbKjrfStVfH59lc40BQ2FZ7M703hLpXK8GiBQ" +"GEYpKaAuQZnMIpByoAAwCAYGKoUDAgIDA0EAgXMcTrhdOY2Er2tHOSAgnMezqrYxocZTWhxmW5Rl" +"JY6lbXH5rndCn4swFzXU+YhgAsJv1wQBaoZEWRl5WV4/nA=="); private byte[] gost3410EC_B = Base64.decode( "MIIBPTCB7QIBADCBgDENMAsGA1UEAxMEdGVzdDEWMBQGA1UEChMNRGVtb3MgQ28gTHRkLjEeMBwG" +"A1UECxMVQ3J5cHRvZ3JhcGh5IGRpdmlzaW9uMQ8wDQYDVQQHEwZNb3Njb3cxCzAJBgNVBAYTAnJ1" +"MRkwFwYJKoZIhvcNAQkBFgpzZGJAZG9sLnJ1MGMwHAYGKoUDAgITMBIGByqFAwICIwIGByqFAwIC" +"HgEDQwAEQI5SLoWT7dZVilbV9j5B/fyIDuDs6x4pjqNC2TtFYbpRHrk/Wc5g/mcHvD80tsm5o1C7" +"7cizNzkvAVUM4VT4Dz6gADAIBgYqhQMCAgMDQQAoT5TwJ8o+bSrxckymyo3diwG7ZbSytX4sRiKy" +"wXPWRS9LlBvPO2NqwpS2HUnxSU8rzfL9fJcybATf7Yt1OEVq"); private byte[] gost3410EC_C = Base64.decode( "MIIBRDCB9AIBADCBhzEVMBMGA1UEAxMMdGVzdCByZXF1ZXN0MRUwEwYDVQQKEwxEZW1vcyBDbyBM" +"dGQxHjAcBgNVBAsTFUNyeXB0b2dyYXBoeSBkaXZpc2lvbjEPMA0GA1UEBxMGTW9zY293MQswCQYD" +"VQQGEwJydTEZMBcGCSqGSIb3DQEJARYKc2RiQGRvbC5ydTBjMBwGBiqFAwICEzASBgcqhQMCAiMD" +"BgcqhQMCAh4BA0MABEBcmGh7OmR4iqqj+ycYo1S1fS7r5PhisSQU2Ezuz8wmmmR2zeTZkdMYCOBa" +"UTMNms0msW3wuYDho7nTDNscHTB5oAAwCAYGKoUDAgIDA0EAVoOMbfyo1Un4Ss7WQrUjHJoiaYW8" +"Ime5LeGGU2iW3ieAv6es/FdMrwTKkqn5dhd3aL/itFg5oQbhyfXw5yw/QQ=="); private byte[] gost3410EC_ExA = Base64.decode( "MIIBOzCB6wIBADB/MQ0wCwYDVQQDEwR0ZXN0MRUwEwYDVQQKEwxEZW1vcyBDbyBMdGQxHjAcBgNV" + "BAsTFUNyeXB0b2dyYXBoeSBkaXZpc2lvbjEPMA0GA1UEBxMGTW9zY293MQswCQYDVQQGEwJydTEZ" + "MBcGCSqGSIb3DQEJARYKc2RiQGRvbC5ydTBjMBwGBiqFAwICEzASBgcqhQMCAiQABgcqhQMCAh4B" + "A0MABEDkqNT/3f8NHj6EUiWnK4JbVZBh31bEpkwq9z3jf0u8ZndG56Vt+K1ZB6EpFxLT7hSIos0w" + "weZ2YuTZ4w43OgodoAAwCAYGKoUDAgIDA0EASk/IUXWxoi6NtcUGVF23VRV1L3undB4sRZLp4Vho" + "gQ7m3CMbZFfJ2cPu6QyarseXGYHmazoirH5lGjEo535c1g=="); private byte[] gost3410EC_ExB = Base64.decode( "MIIBPTCB7QIBADCBgDENMAsGA1UEAxMEdGVzdDEWMBQGA1UEChMNRGVtb3MgQ28gTHRkLjEeMBwG" + "A1UECxMVQ3J5cHRvZ3JhcGh5IGRpdmlzaW9uMQ8wDQYDVQQHEwZNb3Njb3cxCzAJBgNVBAYTAnJ1" + "MRkwFwYJKoZIhvcNAQkBFgpzZGJAZG9sLnJ1MGMwHAYGKoUDAgITMBIGByqFAwICJAEGByqFAwIC" + "HgEDQwAEQMBWYUKPy/1Kxad9ChAmgoSWSYOQxRnXo7KEGLU5RNSXA4qMUvArWzvhav+EYUfTbWLh" + "09nELDyHt2XQcvgQHnSgADAIBgYqhQMCAgMDQQAdaNhgH/ElHp64mbMaEo1tPCg9Q22McxpH8rCz" + "E0QBpF4H5mSSQVGI5OAXHToetnNuh7gHHSynyCupYDEHTbkZ"); public String getName() { return "PKCS10CertRequest"; } private void generationTest(int keySize, String keyName, String sigName, String provider) throws Exception { KeyPairGenerator kpg = KeyPairGenerator.getInstance(keyName, "BC"); kpg.initialize(keySize); KeyPair kp = kpg.genKeyPair(); X500NameBuilder x500NameBld = new X500NameBuilder(BCStyle.INSTANCE); x500NameBld.addRDN(BCStyle.C, "AU"); x500NameBld.addRDN(BCStyle.O, "The Legion of the Bouncy Castle"); x500NameBld.addRDN(BCStyle.L, "Melbourne"); x500NameBld.addRDN(BCStyle.ST, "Victoria"); x500NameBld.addRDN(BCStyle.EmailAddress, "feedback-crypto@bouncycastle.org"); X500Name subject = x500NameBld.build(); PKCS10CertificationRequestBuilder requestBuilder = new JcaPKCS10CertificationRequestBuilder(subject, kp.getPublic()); PKCS10CertificationRequest req1 = requestBuilder.build(new JcaContentSignerBuilder(sigName).setProvider(provider).build(kp.getPrivate())); JcaPKCS10CertificationRequest req2 = new JcaPKCS10CertificationRequest(req1.getEncoded()).setProvider(provider); if (!req2.isSignatureValid(new JcaContentVerifierProviderBuilder().setProvider(provider).build(kp.getPublic()))) { fail(sigName + ": Failed verify check."); } if (!Arrays.areEqual(req2.getPublicKey().getEncoded(), req1.getSubjectPublicKeyInfo().getEncoded())) { fail(keyName + ": Failed public key check."); } } private void generationTestX500Principal(int keySize, String keyName, String sigName, String provider) throws Exception { KeyPairGenerator kpg = KeyPairGenerator.getInstance(keyName, "BC"); kpg.initialize(keySize); KeyPair kp = kpg.genKeyPair(); X500NameBuilder x500NameBld = new X500NameBuilder(BCStyle.INSTANCE); x500NameBld.addRDN(BCStyle.C, "AU"); x500NameBld.addRDN(BCStyle.O, "The Legion of the Bouncy Castle"); x500NameBld.addRDN(BCStyle.L, "Melbourne"); x500NameBld.addRDN(BCStyle.ST, "Victoria"); x500NameBld.addRDN(BCStyle.EmailAddress, "feedback-crypto@bouncycastle.org"); X500Name subject = x500NameBld.build(); PKCS10CertificationRequestBuilder requestBuilder = new JcaPKCS10CertificationRequestBuilder(new X500Principal(subject.getEncoded()), kp.getPublic()); PKCS10CertificationRequest req1 = requestBuilder.build(new JcaContentSignerBuilder(sigName).setProvider(provider).build(kp.getPrivate())); JcaPKCS10CertificationRequest req2 = new JcaPKCS10CertificationRequest(req1.getEncoded()).setProvider(provider); if (!req2.isSignatureValid(new JcaContentVerifierProviderBuilder().setProvider(provider).build(kp.getPublic()))) { fail(sigName + ": Failed verify check."); } if (!Arrays.areEqual(req2.getPublicKey().getEncoded(), req1.getSubjectPublicKeyInfo().getEncoded())) { fail(keyName + ": Failed public key check."); } if (!Arrays.areEqual(req2.getSubject().getEncoded(), req1.getSubject().getEncoded())) { fail(keyName + ": Failed subject key check."); } } /* * we generate a self signed certificate for the sake of testing - SHA224withECDSA */ private void createECRequest(String algorithm, DERObjectIdentifier algOid, DERObjectIdentifier curveOid) throws Exception { ECNamedCurveParameterSpec spec = ECNamedCurveTable.getParameterSpec(curveOid.getId()); KeyPairGenerator ecGen = KeyPairGenerator.getInstance("ECDSA", "BC"); ecGen.initialize(spec); // // set up the keys // PrivateKey privKey; PublicKey pubKey; KeyPair pair = ecGen.generateKeyPair(); privKey = pair.getPrivate(); pubKey = pair.getPublic(); ContentSigner signer = new JcaContentSignerBuilder(algorithm).setProvider(BC).build(privKey); PKCS10CertificationRequestBuilder reqBuilder = new JcaPKCS10CertificationRequestBuilder(new X500Name("CN=XXX"), pubKey); PKCS10CertificationRequest req = reqBuilder.build(signer); ContentVerifierProvider verifier = new JcaContentVerifierProviderBuilder().setProvider(BC).build(pubKey); if (!req.isSignatureValid(verifier)) { fail("Failed verify check EC."); } req = new PKCS10CertificationRequest(req.getEncoded()); if (!req.isSignatureValid(verifier)) { fail("Failed verify check EC encoded."); } // // try with point compression turned off // ((ECPointEncoder)pubKey).setPointFormat("UNCOMPRESSED"); reqBuilder = new JcaPKCS10CertificationRequestBuilder(new X500Name("CN=XXX"), pubKey); req = reqBuilder.build(signer); if (!req.isSignatureValid(verifier)) { fail("Failed verify check EC uncompressed."); } req = new PKCS10CertificationRequest(req.getEncoded()); if (!req.isSignatureValid(verifier)) { fail("Failed verify check EC uncompressed encoded."); } if (!req.toASN1Structure().getSignatureAlgorithm().getAlgorithm().equals(algOid)) { fail("ECDSA oid incorrect."); } if (req.toASN1Structure().getSignatureAlgorithm().getParameters() != null) { fail("ECDSA parameters incorrect."); } Signature sig = Signature.getInstance(algorithm, "BC"); sig.initVerify(pubKey); sig.update(req.toASN1Structure().getCertificationRequestInfo().getEncoded()); if (!sig.verify(req.toASN1Structure().getSignature().getBytes())) { fail("signature not mapped correctly."); } } private void createECRequest(String algorithm, DERObjectIdentifier algOid) throws Exception { ECCurve.Fp curve = new ECCurve.Fp( new BigInteger("6864797660130609714981900799081393217269435300143305409394463459185543183397656052122559640661454554977296311391480858037121987999716643812574028291115057151"), // q (or p) new BigInteger("01FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFC", 16), // a new BigInteger("0051953EB9618E1C9A1F929A21A0B68540EEA2DA725B99B315F3B8B489918EF109E156193951EC7E937B1652C0BD3BB1BF073573DF883D2C34F1EF451FD46B503F00", 16)); // b ECParameterSpec spec = new ECParameterSpec( curve, curve.decodePoint(Hex.decode("0200C6858E06B70404E9CD9E3ECB662395B4429C648139053FB521F828AF606B4D3DBAA14B5E77EFE75928FE1DC127A2FFA8DE3348B3C1856A429BF97E7E31C2E5BD66")), // G new BigInteger("01FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFA51868783BF2F966B7FCC0148F709A5D03BB5C9B8899C47AEBB6FB71E91386409", 16)); // n ECPrivateKeySpec privKeySpec = new ECPrivateKeySpec( new BigInteger("5769183828869504557786041598510887460263120754767955773309066354712783118202294874205844512909370791582896372147797293913785865682804434049019366394746072023"), // d spec); ECPublicKeySpec pubKeySpec = new ECPublicKeySpec( curve.decodePoint(Hex.decode("02006BFDD2C9278B63C92D6624F151C9D7A822CC75BD983B17D25D74C26740380022D3D8FAF304781E416175EADF4ED6E2B47142D2454A7AC7801DD803CF44A4D1F0AC")), // Q spec); // // set up the keys // PrivateKey privKey; PublicKey pubKey; KeyFactory fact = KeyFactory.getInstance("ECDSA", "BC"); privKey = fact.generatePrivate(privKeySpec); pubKey = fact.generatePublic(pubKeySpec); PKCS10CertificationRequest req = new JcaPKCS10CertificationRequestBuilder( new X500Name("CN=XXX"), pubKey).build(new JcaContentSignerBuilder(algorithm).setProvider(BC).build(privKey)); if (!req.isSignatureValid(new JcaContentVerifierProviderBuilder().setProvider(BC).build(pubKey))) { fail("Failed verify check EC."); } req = new PKCS10CertificationRequest(req.getEncoded()); if (!req.isSignatureValid(new JcaContentVerifierProviderBuilder().setProvider(BC).build(pubKey))) { fail("Failed verify check EC encoded."); } // // try with point compression turned off // ((ECPointEncoder)pubKey).setPointFormat("UNCOMPRESSED"); req = new JcaPKCS10CertificationRequestBuilder( new X500Name("CN=XXX"), pubKey).build(new JcaContentSignerBuilder(algorithm).setProvider(BC).build(privKey)); if (!req.isSignatureValid(new JcaContentVerifierProviderBuilder().setProvider(BC).build(pubKey))) { fail("Failed verify check EC uncompressed."); } JcaPKCS10CertificationRequest jcaReq = new JcaPKCS10CertificationRequest(new PKCS10CertificationRequest(req.getEncoded())); if (!jcaReq.isSignatureValid(new JcaContentVerifierProviderBuilder().setProvider(BC).build(jcaReq.getPublicKey()))) { fail("Failed verify check EC uncompressed encoded."); } if (!jcaReq.getSignatureAlgorithm().getAlgorithm().equals(algOid)) { fail("ECDSA oid incorrect."); } if (jcaReq.getSignatureAlgorithm().getParameters() != null) { fail("ECDSA parameters incorrect."); } Signature sig = Signature.getInstance(algorithm, BC); sig.initVerify(pubKey); sig.update(req.toASN1Structure().getCertificationRequestInfo().getEncoded()); if (!sig.verify(req.getSignature())) { fail("signature not mapped correctly."); } } private void createECGOSTRequest() throws Exception { String algorithm = "GOST3411withECGOST3410"; KeyPairGenerator ecGostKpg = KeyPairGenerator.getInstance("ECGOST3410", "BC"); ecGostKpg.initialize(ECGOST3410NamedCurveTable.getParameterSpec("GostR3410-2001-CryptoPro-A"), new SecureRandom()); // // set up the keys // KeyPair pair = ecGostKpg.generateKeyPair(); PrivateKey privKey = pair.getPrivate(); PublicKey pubKey = pair.getPublic(); PKCS10CertificationRequest req = new JcaPKCS10CertificationRequestBuilder( new X500Name("CN=XXX"), pubKey).build(new JcaContentSignerBuilder(algorithm).setProvider(BC).build(privKey)); if (!req.isSignatureValid(new JcaContentVerifierProviderBuilder().setProvider(BC).build(pubKey))) { fail("Failed verify check EC."); } req = new PKCS10CertificationRequest(req.getEncoded()); if (!req.isSignatureValid(new JcaContentVerifierProviderBuilder().setProvider(BC).build(pubKey))) { fail("Failed verify check EC encoded."); } if (!req.getSignatureAlgorithm().getAlgorithm().equals(CryptoProObjectIdentifiers.gostR3411_94_with_gostR3410_2001)) { fail("ECGOST oid incorrect."); } if (req.getSignatureAlgorithm().getParameters() != null) { fail("ECGOST parameters incorrect."); } Signature sig = Signature.getInstance(algorithm, "BC"); sig.initVerify(pubKey); sig.update(req.toASN1Structure().getCertificationRequestInfo().getEncoded()); if (!sig.verify(req.getSignature())) { fail("signature not mapped correctly."); } } private void createPSSTest(String algorithm) throws Exception { RSAPublicKeySpec pubKeySpec = new RSAPublicKeySpec( new BigInteger("a56e4a0e701017589a5187dc7ea841d156f2ec0e36ad52a44dfeb1e61f7ad991d8c51056ffedb162b4c0f283a12a88a394dff526ab7291cbb307ceabfce0b1dfd5cd9508096d5b2b8b6df5d671ef6377c0921cb23c270a70e2598e6ff89d19f105acc2d3f0cb35f29280e1386b6f64c4ef22e1e1f20d0ce8cffb2249bd9a2137",16), new BigInteger("010001",16)); RSAPrivateCrtKeySpec privKeySpec = new RSAPrivateCrtKeySpec( new BigInteger("a56e4a0e701017589a5187dc7ea841d156f2ec0e36ad52a44dfeb1e61f7ad991d8c51056ffedb162b4c0f283a12a88a394dff526ab7291cbb307ceabfce0b1dfd5cd9508096d5b2b8b6df5d671ef6377c0921cb23c270a70e2598e6ff89d19f105acc2d3f0cb35f29280e1386b6f64c4ef22e1e1f20d0ce8cffb2249bd9a2137",16), new BigInteger("010001",16), new BigInteger("33a5042a90b27d4f5451ca9bbbd0b44771a101af884340aef9885f2a4bbe92e894a724ac3c568c8f97853ad07c0266c8c6a3ca0929f1e8f11231884429fc4d9ae55fee896a10ce707c3ed7e734e44727a39574501a532683109c2abacaba283c31b4bd2f53c3ee37e352cee34f9e503bd80c0622ad79c6dcee883547c6a3b325",16), new BigInteger("e7e8942720a877517273a356053ea2a1bc0c94aa72d55c6e86296b2dfc967948c0a72cbccca7eacb35706e09a1df55a1535bd9b3cc34160b3b6dcd3eda8e6443",16), new BigInteger("b69dca1cf7d4d7ec81e75b90fcca874abcde123fd2700180aa90479b6e48de8d67ed24f9f19d85ba275874f542cd20dc723e6963364a1f9425452b269a6799fd",16), new BigInteger("28fa13938655be1f8a159cbaca5a72ea190c30089e19cd274a556f36c4f6e19f554b34c077790427bbdd8dd3ede2448328f385d81b30e8e43b2fffa027861979",16), new BigInteger("1a8b38f398fa712049898d7fb79ee0a77668791299cdfa09efc0e507acb21ed74301ef5bfd48be455eaeb6e1678255827580a8e4e8e14151d1510a82a3f2e729",16), new BigInteger("27156aba4126d24a81f3a528cbfb27f56886f840a9f6e86e17a44b94fe9319584b8e22fdde1e5a2e3bd8aa5ba8d8584194eb2190acf832b847f13a3d24a79f4d",16)); KeyFactory fact = KeyFactory.getInstance("RSA", "BC"); PrivateKey privKey = fact.generatePrivate(privKeySpec); PublicKey pubKey = fact.generatePublic(pubKeySpec); PKCS10CertificationRequest req = new JcaPKCS10CertificationRequestBuilder( new X500Name("CN=XXX"), pubKey).build(new JcaContentSignerBuilder(algorithm).setProvider(BC).build(privKey)); if (!req.isSignatureValid(new JcaContentVerifierProviderBuilder().setProvider(BC).build(pubKey))) { fail("Failed verify check PSS."); } JcaPKCS10CertificationRequest jcaReq = new JcaPKCS10CertificationRequest(req.getEncoded()).setProvider(BC); if (!jcaReq.isSignatureValid(new JcaContentVerifierProviderBuilder().setProvider(BC).build(jcaReq.getPublicKey()))) { fail("Failed verify check PSS encoded."); } if (!jcaReq.getSignatureAlgorithm().getAlgorithm().equals(PKCSObjectIdentifiers.id_RSASSA_PSS)) { fail("PSS oid incorrect."); } if (jcaReq.getSignatureAlgorithm().getParameters() == null) { fail("PSS parameters incorrect."); } Signature sig = Signature.getInstance(algorithm, "BC"); sig.initVerify(pubKey); sig.update(jcaReq.toASN1Structure().getCertificationRequestInfo().getEncoded()); if (!sig.verify(req.getSignature())) { fail("signature not mapped correctly."); } } // previous code found to cause a NullPointerException private void nullPointerTest() throws Exception { KeyPairGenerator keyGen = KeyPairGenerator.getInstance("RSA", "BC"); keyGen.initialize(1024, new SecureRandom()); KeyPair pair = keyGen.generateKeyPair(); Vector oids = new Vector(); Vector values = new Vector(); oids.add(X509Extension.basicConstraints); values.add(new X509Extension(true, new DEROctetString(new BasicConstraints(true)))); oids.add(X509Extension.keyUsage); values.add(new X509Extension(true, new DEROctetString( new KeyUsage(KeyUsage.keyCertSign | KeyUsage.cRLSign)))); SubjectKeyIdentifier subjectKeyIdentifier = new SubjectKeyIdentifierStructure(pair.getPublic()); X509Extension ski = new X509Extension(false, new DEROctetString(subjectKeyIdentifier)); oids.add(X509Extension.subjectKeyIdentifier); values.add(ski); PKCS10CertificationRequest p1 = new JcaPKCS10CertificationRequestBuilder( new X500Name("cn=csr"), pair.getPublic()) .addAttribute(PKCSObjectIdentifiers.pkcs_9_at_extensionRequest, new X509Extensions(oids, values)) .build(new JcaContentSignerBuilder("SHA1withRSA").setProvider(BC).build(pair.getPrivate())); PKCS10CertificationRequest p2 = new JcaPKCS10CertificationRequestBuilder( new X500Name("cn=csr"), pair.getPublic()) .addAttribute(PKCSObjectIdentifiers.pkcs_9_at_extensionRequest, new X509Extensions(oids, values)) .build(new JcaContentSignerBuilder("SHA1withRSA").setProvider(BC).build(pair.getPrivate())); if (!p1.equals(p2)) { fail("cert request comparison failed"); } Attribute[] attr1 = p1.getAttributes(); Attribute[] attr2 = p1.getAttributes(); checkAttrs(1, attr1, attr2); attr1 = p1.getAttributes(PKCSObjectIdentifiers.pkcs_9_at_extensionRequest); attr2 = p1.getAttributes(PKCSObjectIdentifiers.pkcs_9_at_extensionRequest); checkAttrs(1, attr1, attr2); } private void checkAttrs(int expectedLength, Attribute[] attr1, Attribute[] attr2) { if (expectedLength != attr1.length) { fail("expected length mismatch"); } if (attr1.length != attr2.length) { fail("atrribute length mismatch"); } for (int i = 0; i != attr1.length; i++) { if (!attr1[i].equals(attr2[i])) { fail("atrribute mismatch"); } } } public void performTest() throws Exception { generationTest(512, "RSA", "SHA1withRSA", "BC"); generationTestX500Principal(512, "RSA", "SHA1withRSA", "BC"); generationTest(512, "GOST3410", "GOST3411withGOST3410", "BC"); if (Security.getProvider("SunRsaSign") != null) { generationTest(512, "RSA", "SHA1withRSA", "SunRsaSign"); } // elliptic curve GOST A parameter set JcaPKCS10CertificationRequest req = new JcaPKCS10CertificationRequest(gost3410EC_A).setProvider(BC); if (!req.isSignatureValid(new JcaContentVerifierProviderBuilder().setProvider(BC).build(req.getPublicKey()))) { fail("Failed verify check gost3410EC_A."); } // elliptic curve GOST B parameter set req = new JcaPKCS10CertificationRequest(gost3410EC_B).setProvider(BC); if (!req.isSignatureValid(new JcaContentVerifierProviderBuilder().setProvider(BC).build(req.getPublicKey()))) { fail("Failed verify check gost3410EC_B."); } // elliptic curve GOST C parameter set req = new JcaPKCS10CertificationRequest(gost3410EC_C).setProvider(BC); if (!req.isSignatureValid(new JcaContentVerifierProviderBuilder().setProvider(BC).build(req.getPublicKey()))) { fail("Failed verify check gost3410EC_C."); } // elliptic curve GOST ExA parameter set req = new JcaPKCS10CertificationRequest(gost3410EC_ExA).setProvider(BC); if (!req.isSignatureValid(new JcaContentVerifierProviderBuilder().setProvider(BC).build(req.getPublicKey()))) { fail("Failed verify check gost3410EC_ExA."); } // elliptic curve GOST ExB parameter set req = new JcaPKCS10CertificationRequest(gost3410EC_ExB).setProvider(BC); if (!req.isSignatureValid(new JcaContentVerifierProviderBuilder().setProvider(BC).build(req.getPublicKey()))) { fail("Failed verify check gost3410EC_ExA."); } // elliptic curve openSSL KeyPairGenerator g = KeyPairGenerator.getInstance("ECDSA", "BC"); ECCurve curve = new ECCurve.Fp( new BigInteger("883423532389192164791648750360308885314476597252960362792450860609699839"), // q new BigInteger("7fffffffffffffffffffffff7fffffffffff8000000000007ffffffffffc", 16), // a new BigInteger("6b016c3bdcf18941d0d654921475ca71a9db2fb27d1d37796185c2942c0a", 16)); // b ECParameterSpec ecSpec = new ECParameterSpec( curve, curve.decodePoint(Hex.decode("020ffa963cdca8816ccc33b8642bedf905c3d358573d3f27fbbd3b3cb9aaaf")), // G new BigInteger("883423532389192164791648750360308884807550341691627752275345424702807307")); // n g.initialize(ecSpec, new SecureRandom()); KeyPair kp = g.generateKeyPair(); req = new JcaPKCS10CertificationRequest(new JcaPKCS10CertificationRequestBuilder( new X500Name("CN=XXX"), kp.getPublic()).build(new JcaContentSignerBuilder( "ECDSAWITHSHA1").setProvider(BC).build(kp.getPrivate()))); if (!req.isSignatureValid(new JcaContentVerifierProviderBuilder().setProvider(BC).build(req.getPublicKey()))) { fail("Failed verify check EC."); } createECRequest("SHA1withECDSA", X9ObjectIdentifiers.ecdsa_with_SHA1); createECRequest("SHA224withECDSA", X9ObjectIdentifiers.ecdsa_with_SHA224); createECRequest("SHA256withECDSA", X9ObjectIdentifiers.ecdsa_with_SHA256); createECRequest("SHA384withECDSA", X9ObjectIdentifiers.ecdsa_with_SHA384); createECRequest("SHA512withECDSA", X9ObjectIdentifiers.ecdsa_with_SHA512); createECRequest("SHA1withECDSA", X9ObjectIdentifiers.ecdsa_with_SHA1, new DERObjectIdentifier("1.3.132.0.34")); createECGOSTRequest(); createPSSTest("SHA1withRSAandMGF1"); createPSSTest("SHA224withRSAandMGF1"); createPSSTest("SHA256withRSAandMGF1"); createPSSTest("SHA384withRSAandMGF1"); nullPointerTest(); } public static void main( String[] args) { Security.addProvider(new BouncyCastleProvider()); runTest(new PKCS10Test()); } } bouncycastle-1.49.orig/test/src/org/bouncycastle/cert/test/X509ExtensionUtilsTest.java0000644000175000017500000000340311725015710030462 0ustar ebourgebourgpackage org.bouncycastle.cert.test; import java.io.IOException; import org.bouncycastle.asn1.ASN1Primitive; import org.bouncycastle.asn1.x509.SubjectKeyIdentifier; import org.bouncycastle.asn1.x509.SubjectPublicKeyInfo; import org.bouncycastle.cert.X509ExtensionUtils; import org.bouncycastle.util.Arrays; import org.bouncycastle.util.encoders.Base64; import org.bouncycastle.util.encoders.Hex; import org.bouncycastle.util.test.SimpleTest; public class X509ExtensionUtilsTest extends SimpleTest { private static byte[] pubKeyInfo = Base64.decode( "MFgwCwYJKoZIhvcNAQEBA0kAMEYCQQC6wMMmHYMZszT/7bNFMn+gaZoiWJLVP8ODRuu1C2jeAe" + "QpxM+5Oe7PaN2GNy3nBE4EOYkB5pMJWA0y9n04FX8NAgED"); private static byte[] shaID = Hex.decode("d8128a06d6c2feb0865994a2936e7b75b836a021"); private static byte[] shaTruncID = Hex.decode("436e7b75b836a021"); private X509ExtensionUtils x509ExtensionUtils = new X509ExtensionUtils(new SHA1DigestCalculator()); public String getName() { return "X509ExtensionUtilsTest"; } public void performTest() throws IOException { SubjectPublicKeyInfo pubInfo = SubjectPublicKeyInfo.getInstance(ASN1Primitive.fromByteArray(pubKeyInfo)); SubjectKeyIdentifier ski = x509ExtensionUtils.createSubjectKeyIdentifier(pubInfo); if (!Arrays.areEqual(shaID, ski.getKeyIdentifier())) { fail("SHA-1 ID does not match"); } ski = x509ExtensionUtils.createTruncatedSubjectKeyIdentifier(pubInfo); if (!Arrays.areEqual(shaTruncID, ski.getKeyIdentifier())) { fail("truncated SHA-1 ID does not match"); } } public static void main( String[] args) { runTest(new X509ExtensionUtilsTest()); } } bouncycastle-1.49.orig/test/src/org/bouncycastle/cert/test/BcCertTest.java0000644000175000017500000020076611737303571026264 0ustar ebourgebourgpackage org.bouncycastle.cert.test; import java.io.ByteArrayInputStream; import java.io.IOException; import java.io.UnsupportedEncodingException; import java.math.BigInteger; import java.security.SecureRandom; import java.security.cert.CRL; import java.security.cert.CertificateException; import java.security.cert.CertificateFactory; import java.security.cert.X509CRL; import java.security.cert.X509Certificate; import java.util.Collection; import java.util.Date; import java.util.Iterator; import java.util.List; import java.util.Set; import junit.framework.TestCase; import org.bouncycastle.asn1.ASN1EncodableVector; import org.bouncycastle.asn1.ASN1Enumerated; import org.bouncycastle.asn1.ASN1Object; import org.bouncycastle.asn1.ASN1ObjectIdentifier; import org.bouncycastle.asn1.DERBitString; import org.bouncycastle.asn1.DERSequence; import org.bouncycastle.asn1.pkcs.PKCSObjectIdentifiers; import org.bouncycastle.asn1.x500.X500Name; import org.bouncycastle.asn1.x500.X500NameBuilder; import org.bouncycastle.asn1.x500.style.RFC4519Style; import org.bouncycastle.asn1.x509.AlgorithmIdentifier; import org.bouncycastle.asn1.x509.AuthorityKeyIdentifier; import org.bouncycastle.asn1.x509.CRLReason; import org.bouncycastle.asn1.x509.Certificate; import org.bouncycastle.asn1.x509.Extension; import org.bouncycastle.asn1.x509.Extensions; import org.bouncycastle.asn1.x509.ExtensionsGenerator; import org.bouncycastle.asn1.x509.GeneralName; import org.bouncycastle.asn1.x509.GeneralNames; import org.bouncycastle.asn1.x509.KeyPurposeId; import org.bouncycastle.asn1.x509.KeyUsage; import org.bouncycastle.asn1.x509.SubjectPublicKeyInfo; import org.bouncycastle.cert.CertException; import org.bouncycastle.cert.X509CRLEntryHolder; import org.bouncycastle.cert.X509CRLHolder; import org.bouncycastle.cert.X509CertificateHolder; import org.bouncycastle.cert.X509v1CertificateBuilder; import org.bouncycastle.cert.X509v2CRLBuilder; import org.bouncycastle.cert.X509v3CertificateBuilder; import org.bouncycastle.cert.bc.BcX509ExtensionUtils; import org.bouncycastle.cert.bc.BcX509v1CertificateBuilder; import org.bouncycastle.cert.bc.BcX509v3CertificateBuilder; import org.bouncycastle.cert.jcajce.JcaX509CertificateConverter; import org.bouncycastle.crypto.AsymmetricCipherKeyPair; import org.bouncycastle.crypto.AsymmetricCipherKeyPairGenerator; import org.bouncycastle.crypto.generators.DSAKeyPairGenerator; import org.bouncycastle.crypto.generators.DSAParametersGenerator; import org.bouncycastle.crypto.generators.RSAKeyPairGenerator; import org.bouncycastle.crypto.params.AsymmetricKeyParameter; import org.bouncycastle.crypto.params.DSAKeyGenerationParameters; import org.bouncycastle.crypto.params.DSAParameters; import org.bouncycastle.crypto.params.RSAKeyGenerationParameters; import org.bouncycastle.crypto.params.RSAKeyParameters; import org.bouncycastle.crypto.params.RSAPrivateCrtKeyParameters; import org.bouncycastle.crypto.util.SubjectPublicKeyInfoFactory; import org.bouncycastle.jce.provider.test.PEMData; import org.bouncycastle.operator.ContentSigner; import org.bouncycastle.operator.ContentVerifierProvider; import org.bouncycastle.operator.DefaultDigestAlgorithmIdentifierFinder; import org.bouncycastle.operator.DefaultSignatureAlgorithmIdentifierFinder; import org.bouncycastle.operator.OperatorCreationException; import org.bouncycastle.operator.bc.BcDSAContentSignerBuilder; import org.bouncycastle.operator.bc.BcDSAContentVerifierProviderBuilder; import org.bouncycastle.operator.bc.BcRSAContentSignerBuilder; import org.bouncycastle.operator.bc.BcRSAContentVerifierProviderBuilder; import org.bouncycastle.util.encoders.Base64; public class BcCertTest extends TestCase { DefaultSignatureAlgorithmIdentifierFinder sigAlgFinder = new DefaultSignatureAlgorithmIdentifierFinder(); DefaultDigestAlgorithmIdentifierFinder digAlgFinder = new DefaultDigestAlgorithmIdentifierFinder(); // // server.crt // byte[] cert1 = Base64.decode( "MIIDXjCCAsegAwIBAgIBBzANBgkqhkiG9w0BAQQFADCBtzELMAkGA1UEBhMCQVUx" + "ETAPBgNVBAgTCFZpY3RvcmlhMRgwFgYDVQQHEw9Tb3V0aCBNZWxib3VybmUxGjAY" + "BgNVBAoTEUNvbm5lY3QgNCBQdHkgTHRkMR4wHAYDVQQLExVDZXJ0aWZpY2F0ZSBB" + "dXRob3JpdHkxFTATBgNVBAMTDENvbm5lY3QgNCBDQTEoMCYGCSqGSIb3DQEJARYZ" + "d2VibWFzdGVyQGNvbm5lY3Q0LmNvbS5hdTAeFw0wMDA2MDIwNzU2MjFaFw0wMTA2" + "MDIwNzU2MjFaMIG4MQswCQYDVQQGEwJBVTERMA8GA1UECBMIVmljdG9yaWExGDAW" + "BgNVBAcTD1NvdXRoIE1lbGJvdXJuZTEaMBgGA1UEChMRQ29ubmVjdCA0IFB0eSBM" + "dGQxFzAVBgNVBAsTDldlYnNlcnZlciBUZWFtMR0wGwYDVQQDExR3d3cyLmNvbm5l" + "Y3Q0LmNvbS5hdTEoMCYGCSqGSIb3DQEJARYZd2VibWFzdGVyQGNvbm5lY3Q0LmNv" + "bS5hdTCBnzANBgkqhkiG9w0BAQEFAAOBjQAwgYkCgYEArvDxclKAhyv7Q/Wmr2re" + "Gw4XL9Cnh9e+6VgWy2AWNy/MVeXdlxzd7QAuc1eOWQkGQEiLPy5XQtTY+sBUJ3AO" + "Rvd2fEVJIcjf29ey7bYua9J/vz5MG2KYo9/WCHIwqD9mmG9g0xLcfwq/s8ZJBswE" + "7sb85VU+h94PTvsWOsWuKaECAwEAAaN3MHUwJAYDVR0RBB0wG4EZd2VibWFzdGVy" + "QGNvbm5lY3Q0LmNvbS5hdTA6BglghkgBhvhCAQ0ELRYrbW9kX3NzbCBnZW5lcmF0" + "ZWQgY3VzdG9tIHNlcnZlciBjZXJ0aWZpY2F0ZTARBglghkgBhvhCAQEEBAMCBkAw" + "DQYJKoZIhvcNAQEEBQADgYEAotccfKpwSsIxM1Hae8DR7M/Rw8dg/RqOWx45HNVL" + "iBS4/3N/TO195yeQKbfmzbAA2jbPVvIvGgTxPgO1MP4ZgvgRhasaa0qCJCkWvpM4" + "yQf33vOiYQbpv4rTwzU8AmRlBG45WdjyNIigGV+oRc61aKCTnLq7zB8N3z1TF/bF" + "5/8="); // // ca.crt // byte[] cert2 = Base64.decode( "MIIDbDCCAtWgAwIBAgIBADANBgkqhkiG9w0BAQQFADCBtzELMAkGA1UEBhMCQVUx" + "ETAPBgNVBAgTCFZpY3RvcmlhMRgwFgYDVQQHEw9Tb3V0aCBNZWxib3VybmUxGjAY" + "BgNVBAoTEUNvbm5lY3QgNCBQdHkgTHRkMR4wHAYDVQQLExVDZXJ0aWZpY2F0ZSBB" + "dXRob3JpdHkxFTATBgNVBAMTDENvbm5lY3QgNCBDQTEoMCYGCSqGSIb3DQEJARYZ" + "d2VibWFzdGVyQGNvbm5lY3Q0LmNvbS5hdTAeFw0wMDA2MDIwNzU1MzNaFw0wMTA2" + "MDIwNzU1MzNaMIG3MQswCQYDVQQGEwJBVTERMA8GA1UECBMIVmljdG9yaWExGDAW" + "BgNVBAcTD1NvdXRoIE1lbGJvdXJuZTEaMBgGA1UEChMRQ29ubmVjdCA0IFB0eSBM" + "dGQxHjAcBgNVBAsTFUNlcnRpZmljYXRlIEF1dGhvcml0eTEVMBMGA1UEAxMMQ29u" + "bmVjdCA0IENBMSgwJgYJKoZIhvcNAQkBFhl3ZWJtYXN0ZXJAY29ubmVjdDQuY29t" + "LmF1MIGfMA0GCSqGSIb3DQEBAQUAA4GNADCBiQKBgQDgs5ptNG6Qv1ZpCDuUNGmv" + "rhjqMDPd3ri8JzZNRiiFlBA4e6/ReaO1U8ASewDeQMH6i9R6degFdQRLngbuJP0s" + "xcEE+SksEWNvygfzLwV9J/q+TQDyJYK52utb++lS0b48A1KPLwEsyL6kOAgelbur" + "ukwxowprKUIV7Knf1ajetQIDAQABo4GFMIGCMCQGA1UdEQQdMBuBGXdlYm1hc3Rl" + "ckBjb25uZWN0NC5jb20uYXUwDwYDVR0TBAgwBgEB/wIBADA2BglghkgBhvhCAQ0E" + "KRYnbW9kX3NzbCBnZW5lcmF0ZWQgY3VzdG9tIENBIGNlcnRpZmljYXRlMBEGCWCG" + "SAGG+EIBAQQEAwICBDANBgkqhkiG9w0BAQQFAAOBgQCsGvfdghH8pPhlwm1r3pQk" + "msnLAVIBb01EhbXm2861iXZfWqGQjrGAaA0ZpXNk9oo110yxoqEoSJSzniZa7Xtz" + "soTwNUpE0SLHvWf/SlKdFWlzXA+vOZbzEv4UmjeelekTm7lc01EEa5QRVzOxHFtQ" + "DhkaJ8VqOMajkQFma2r9iA=="); // // testx509.pem // byte[] cert3 = Base64.decode( "MIIBWzCCAQYCARgwDQYJKoZIhvcNAQEEBQAwODELMAkGA1UEBhMCQVUxDDAKBgNV" + "BAgTA1FMRDEbMBkGA1UEAxMSU1NMZWF5L3JzYSB0ZXN0IENBMB4XDTk1MDYxOTIz" + "MzMxMloXDTk1MDcxNzIzMzMxMlowOjELMAkGA1UEBhMCQVUxDDAKBgNVBAgTA1FM" + "RDEdMBsGA1UEAxMUU1NMZWF5L3JzYSB0ZXN0IGNlcnQwXDANBgkqhkiG9w0BAQEF" + "AANLADBIAkEAqtt6qS5GTxVxGZYWa0/4u+IwHf7p2LNZbcPBp9/OfIcYAXBQn8hO" + "/Re1uwLKXdCjIoaGs4DLdG88rkzfyK5dPQIDAQABMAwGCCqGSIb3DQIFBQADQQAE" + "Wc7EcF8po2/ZO6kNCwK/ICH6DobgLekA5lSLr5EvuioZniZp5lFzAw4+YzPQ7XKJ" + "zl9HYIMxATFyqSiD9jsx"); // // v3-cert1.pem // byte[] cert4 = Base64.decode( "MIICjTCCAfigAwIBAgIEMaYgRzALBgkqhkiG9w0BAQQwRTELMAkGA1UEBhMCVVMx" + "NjA0BgNVBAoTLU5hdGlvbmFsIEFlcm9uYXV0aWNzIGFuZCBTcGFjZSBBZG1pbmlz" + "dHJhdGlvbjAmFxE5NjA1MjgxMzQ5MDUrMDgwMBcROTgwNTI4MTM0OTA1KzA4MDAw" + "ZzELMAkGA1UEBhMCVVMxNjA0BgNVBAoTLU5hdGlvbmFsIEFlcm9uYXV0aWNzIGFu" + "ZCBTcGFjZSBBZG1pbmlzdHJhdGlvbjEgMAkGA1UEBRMCMTYwEwYDVQQDEwxTdGV2" + "ZSBTY2hvY2gwWDALBgkqhkiG9w0BAQEDSQAwRgJBALrAwyYdgxmzNP/ts0Uyf6Bp" + "miJYktU/w4NG67ULaN4B5CnEz7k57s9o3YY3LecETgQ5iQHmkwlYDTL2fTgVfw0C" + "AQOjgaswgagwZAYDVR0ZAQH/BFowWDBWMFQxCzAJBgNVBAYTAlVTMTYwNAYDVQQK" + "Ey1OYXRpb25hbCBBZXJvbmF1dGljcyBhbmQgU3BhY2UgQWRtaW5pc3RyYXRpb24x" + "DTALBgNVBAMTBENSTDEwFwYDVR0BAQH/BA0wC4AJODMyOTcwODEwMBgGA1UdAgQR" + "MA8ECTgzMjk3MDgyM4ACBSAwDQYDVR0KBAYwBAMCBkAwCwYJKoZIhvcNAQEEA4GB" + "AH2y1VCEw/A4zaXzSYZJTTUi3uawbbFiS2yxHvgf28+8Js0OHXk1H1w2d6qOHH21" + "X82tZXd/0JtG0g1T9usFFBDvYK8O0ebgz/P5ELJnBL2+atObEuJy1ZZ0pBDWINR3" + "WkDNLCGiTkCKp0F5EWIrVDwh54NNevkCQRZita+z4IBO"); // // v3-cert2.pem // byte[] cert5 = Base64.decode( "MIICiTCCAfKgAwIBAgIEMeZfHzANBgkqhkiG9w0BAQQFADB9MQswCQYDVQQGEwJD" + "YTEPMA0GA1UEBxMGTmVwZWFuMR4wHAYDVQQLExVObyBMaWFiaWxpdHkgQWNjZXB0" + "ZWQxHzAdBgNVBAoTFkZvciBEZW1vIFB1cnBvc2VzIE9ubHkxHDAaBgNVBAMTE0Vu" + "dHJ1c3QgRGVtbyBXZWIgQ0EwHhcNOTYwNzEyMTQyMDE1WhcNOTYxMDEyMTQyMDE1" + "WjB0MSQwIgYJKoZIhvcNAQkBExVjb29rZUBpc3NsLmF0bC5ocC5jb20xCzAJBgNV" + "BAYTAlVTMScwJQYDVQQLEx5IZXdsZXR0IFBhY2thcmQgQ29tcGFueSAoSVNTTCkx" + "FjAUBgNVBAMTDVBhdWwgQS4gQ29va2UwXDANBgkqhkiG9w0BAQEFAANLADBIAkEA" + "6ceSq9a9AU6g+zBwaL/yVmW1/9EE8s5you1mgjHnj0wAILuoB3L6rm6jmFRy7QZT" + "G43IhVZdDua4e+5/n1ZslwIDAQABo2MwYTARBglghkgBhvhCAQEEBAMCB4AwTAYJ" + "YIZIAYb4QgENBD8WPVRoaXMgY2VydGlmaWNhdGUgaXMgb25seSBpbnRlbmRlZCBm" + "b3IgZGVtb25zdHJhdGlvbiBwdXJwb3Nlcy4wDQYJKoZIhvcNAQEEBQADgYEAi8qc" + "F3zfFqy1sV8NhjwLVwOKuSfhR/Z8mbIEUeSTlnH3QbYt3HWZQ+vXI8mvtZoBc2Fz" + "lexKeIkAZXCesqGbs6z6nCt16P6tmdfbZF3I3AWzLquPcOXjPf4HgstkyvVBn0Ap" + "jAFN418KF/Cx4qyHB4cjdvLrRjjQLnb2+ibo7QU="); // // pem encoded pkcs7 // byte[] cert6 = Base64.decode( "MIAGCSqGSIb3DQEHAqCAMIACAQExCzAJBgUrDgMCGgUAMIAGCSqGSIb3DQEHAQAAoIIJbzCCAj0w" + "ggGmAhEAzbp/VvDf5LxU/iKss3KqVTANBgkqhkiG9w0BAQIFADBfMQswCQYDVQQGEwJVUzEXMBUG" + "A1UEChMOVmVyaVNpZ24sIEluYy4xNzA1BgNVBAsTLkNsYXNzIDEgUHVibGljIFByaW1hcnkgQ2Vy" + "dGlmaWNhdGlvbiBBdXRob3JpdHkwHhcNOTYwMTI5MDAwMDAwWhcNMjgwODAxMjM1OTU5WjBfMQsw" + "CQYDVQQGEwJVUzEXMBUGA1UEChMOVmVyaVNpZ24sIEluYy4xNzA1BgNVBAsTLkNsYXNzIDEgUHVi" + "bGljIFByaW1hcnkgQ2VydGlmaWNhdGlvbiBBdXRob3JpdHkwgZ8wDQYJKoZIhvcNAQEBBQADgY0A" + "MIGJAoGBAOUZv22jVmEtmUhx9mfeuY3rt56GgAqRDvo4Ja9GiILlc6igmyRdDR/MZW4MsNBWhBiH" + "mgabEKFz37RYOWtuwfYV1aioP6oSBo0xrH+wNNePNGeICc0UEeJORVZpH3gCgNrcR5EpuzbJY1zF" + "4Ncth3uhtzKwezC6Ki8xqu6jZ9rbAgMBAAEwDQYJKoZIhvcNAQECBQADgYEATD+4i8Zo3+5DMw5d" + "6abLB4RNejP/khv0Nq3YlSI2aBFsfELM85wuxAc/FLAPT/+Qknb54rxK6Y/NoIAK98Up8YIiXbix" + "3YEjo3slFUYweRb46gVLlH8dwhzI47f0EEA8E8NfH1PoSOSGtHuhNbB7Jbq4046rPzidADQAmPPR" + "cZQwggMuMIICl6ADAgECAhEA0nYujRQMPX2yqCVdr+4NdTANBgkqhkiG9w0BAQIFADBfMQswCQYD" + "VQQGEwJVUzEXMBUGA1UEChMOVmVyaVNpZ24sIEluYy4xNzA1BgNVBAsTLkNsYXNzIDEgUHVibGlj" + "IFByaW1hcnkgQ2VydGlmaWNhdGlvbiBBdXRob3JpdHkwHhcNOTgwNTEyMDAwMDAwWhcNMDgwNTEy" + "MjM1OTU5WjCBzDEXMBUGA1UEChMOVmVyaVNpZ24sIEluYy4xHzAdBgNVBAsTFlZlcmlTaWduIFRy" + "dXN0IE5ldHdvcmsxRjBEBgNVBAsTPXd3dy52ZXJpc2lnbi5jb20vcmVwb3NpdG9yeS9SUEEgSW5j" + "b3JwLiBCeSBSZWYuLExJQUIuTFREKGMpOTgxSDBGBgNVBAMTP1ZlcmlTaWduIENsYXNzIDEgQ0Eg" + "SW5kaXZpZHVhbCBTdWJzY3JpYmVyLVBlcnNvbmEgTm90IFZhbGlkYXRlZDCBnzANBgkqhkiG9w0B" + "AQEFAAOBjQAwgYkCgYEAu1pEigQWu1X9A3qKLZRPFXg2uA1Ksm+cVL+86HcqnbnwaLuV2TFBcHqB" + "S7lIE1YtxwjhhEKrwKKSq0RcqkLwgg4C6S/7wju7vsknCl22sDZCM7VuVIhPh0q/Gdr5FegPh7Yc" + "48zGmo5/aiSS4/zgZbqnsX7vyds3ashKyAkG5JkCAwEAAaN8MHowEQYJYIZIAYb4QgEBBAQDAgEG" + "MEcGA1UdIARAMD4wPAYLYIZIAYb4RQEHAQEwLTArBggrBgEFBQcCARYfd3d3LnZlcmlzaWduLmNv" + "bS9yZXBvc2l0b3J5L1JQQTAPBgNVHRMECDAGAQH/AgEAMAsGA1UdDwQEAwIBBjANBgkqhkiG9w0B" + "AQIFAAOBgQCIuDc73dqUNwCtqp/hgQFxHpJqbS/28Z3TymQ43BuYDAeGW4UVag+5SYWklfEXfWe0" + "fy0s3ZpCnsM+tI6q5QsG3vJWKvozx74Z11NMw73I4xe1pElCY+zCphcPXVgaSTyQXFWjZSAA/Rgg" + "5V+CprGoksVYasGNAzzrw80FopCubjCCA/gwggNhoAMCAQICEBbbn/1G1zppD6KsP01bwywwDQYJ" + "KoZIhvcNAQEEBQAwgcwxFzAVBgNVBAoTDlZlcmlTaWduLCBJbmMuMR8wHQYDVQQLExZWZXJpU2ln" + "biBUcnVzdCBOZXR3b3JrMUYwRAYDVQQLEz13d3cudmVyaXNpZ24uY29tL3JlcG9zaXRvcnkvUlBB" + "IEluY29ycC4gQnkgUmVmLixMSUFCLkxURChjKTk4MUgwRgYDVQQDEz9WZXJpU2lnbiBDbGFzcyAx" + "IENBIEluZGl2aWR1YWwgU3Vic2NyaWJlci1QZXJzb25hIE5vdCBWYWxpZGF0ZWQwHhcNMDAxMDAy" + "MDAwMDAwWhcNMDAxMjAxMjM1OTU5WjCCAQcxFzAVBgNVBAoTDlZlcmlTaWduLCBJbmMuMR8wHQYD" + "VQQLExZWZXJpU2lnbiBUcnVzdCBOZXR3b3JrMUYwRAYDVQQLEz13d3cudmVyaXNpZ24uY29tL3Jl" + "cG9zaXRvcnkvUlBBIEluY29ycC4gYnkgUmVmLixMSUFCLkxURChjKTk4MR4wHAYDVQQLExVQZXJz" + "b25hIE5vdCBWYWxpZGF0ZWQxJzAlBgNVBAsTHkRpZ2l0YWwgSUQgQ2xhc3MgMSAtIE1pY3Jvc29m" + "dDETMBEGA1UEAxQKRGF2aWQgUnlhbjElMCMGCSqGSIb3DQEJARYWZGF2aWRAbGl2ZW1lZGlhLmNv" + "bS5hdTCBnzANBgkqhkiG9w0BAQEFAAOBjQAwgYkCgYEAqxBsdeNmSvFqhMNwhQgNzM8mdjX9eSXb" + "DawpHtQHjmh0AKJSa3IwUY0VIsyZHuXWktO/CgaMBVPt6OVf/n0R2sQigMP6Y+PhEiS0vCJBL9aK" + "0+pOo2qXrjVBmq+XuCyPTnc+BOSrU26tJsX0P9BYorwySiEGxGanBNATdVL4NdUCAwEAAaOBnDCB" + "mTAJBgNVHRMEAjAAMEQGA1UdIAQ9MDswOQYLYIZIAYb4RQEHAQgwKjAoBggrBgEFBQcCARYcaHR0" + "cHM6Ly93d3cudmVyaXNpZ24uY29tL3JwYTARBglghkgBhvhCAQEEBAMCB4AwMwYDVR0fBCwwKjAo" + "oCagJIYiaHR0cDovL2NybC52ZXJpc2lnbi5jb20vY2xhc3MxLmNybDANBgkqhkiG9w0BAQQFAAOB" + "gQBC8yIIdVGpFTf8/YiL14cMzcmL0nIRm4kGR3U59z7UtcXlfNXXJ8MyaeI/BnXwG/gD5OKYqW6R" + "yca9vZOxf1uoTBl82gInk865ED3Tej6msCqFzZffnSUQvOIeqLxxDlqYRQ6PmW2nAnZeyjcnbI5Y" + "syQSM2fmo7n6qJFP+GbFezGCAkUwggJBAgEBMIHhMIHMMRcwFQYDVQQKEw5WZXJpU2lnbiwgSW5j" + "LjEfMB0GA1UECxMWVmVyaVNpZ24gVHJ1c3QgTmV0d29yazFGMEQGA1UECxM9d3d3LnZlcmlzaWdu" + "LmNvbS9yZXBvc2l0b3J5L1JQQSBJbmNvcnAuIEJ5IFJlZi4sTElBQi5MVEQoYyk5ODFIMEYGA1UE" + "AxM/VmVyaVNpZ24gQ2xhc3MgMSBDQSBJbmRpdmlkdWFsIFN1YnNjcmliZXItUGVyc29uYSBOb3Qg" + "VmFsaWRhdGVkAhAW25/9Rtc6aQ+irD9NW8MsMAkGBSsOAwIaBQCggbowGAYJKoZIhvcNAQkDMQsG" + "CSqGSIb3DQEHATAcBgkqhkiG9w0BCQUxDxcNMDAxMDAyMTczNTE4WjAjBgkqhkiG9w0BCQQxFgQU" + "gZjSaBEY2oxGvlQUIMnxSXhivK8wWwYJKoZIhvcNAQkPMU4wTDAKBggqhkiG9w0DBzAOBggqhkiG" + "9w0DAgICAIAwDQYIKoZIhvcNAwICAUAwBwYFKw4DAgcwDQYIKoZIhvcNAwICASgwBwYFKw4DAh0w" + "DQYJKoZIhvcNAQEBBQAEgYAzk+PU91/ZFfoiuKOECjxEh9fDYE2jfDCheBIgh5gdcCo+sS1WQs8O" + "HreQ9Nop/JdJv1DQMBK6weNBBDoP0EEkRm1XCC144XhXZC82jBZohYmi2WvDbbC//YN58kRMYMyy" + "srrfn4Z9I+6kTriGXkrpGk9Q0LSGjmG2BIsqiF0dvwAAAAAAAA=="); // // dsaWithSHA1 cert // byte[] cert7 = Base64.decode( "MIIEXAYJKoZIhvcNAQcCoIIETTCCBEkCAQExCzAJBgUrDgMCGgUAMAsGCSqG" + "SIb3DQEHAaCCAsMwggK/MIIB4AIBADCBpwYFKw4DAhswgZ0CQQEkJRHP+mN7" + "d8miwTMN55CUSmo3TO8WGCxgY61TX5k+7NU4XPf1TULjw3GobwaJX13kquPh" + "fVXk+gVy46n4Iw3hAhUBSe/QF4BUj+pJOF9ROBM4u+FEWA8CQQD4mSJbrABj" + "TUWrlnAte8pS22Tq4/FPO7jHSqjijUHfXKTrHL1OEqV3SVWcFy5j/cqBgX/z" + "m8Q12PFp/PjOhh+nMA4xDDAKBgNVBAMTA0lEMzAeFw05NzEwMDEwMDAwMDBa" + "Fw0zODAxMDEwMDAwMDBaMA4xDDAKBgNVBAMTA0lEMzCB8DCBpwYFKw4DAhsw" + "gZ0CQQEkJRHP+mN7d8miwTMN55CUSmo3TO8WGCxgY61TX5k+7NU4XPf1TULj" + "w3GobwaJX13kquPhfVXk+gVy46n4Iw3hAhUBSe/QF4BUj+pJOF9ROBM4u+FE" + "WA8CQQD4mSJbrABjTUWrlnAte8pS22Tq4/FPO7jHSqjijUHfXKTrHL1OEqV3" + "SVWcFy5j/cqBgX/zm8Q12PFp/PjOhh+nA0QAAkEAkYkXLYMtGVGWj9OnzjPn" + "sB9sefSRPrVegZJCZbpW+Iv0/1RP1u04pHG9vtRpIQLjzUiWvLMU9EKQTThc" + "eNMmWDCBpwYFKw4DAhswgZ0CQQEkJRHP+mN7d8miwTMN55CUSmo3TO8WGCxg" + "Y61TX5k+7NU4XPf1TULjw3GobwaJX13kquPhfVXk+gVy46n4Iw3hAhUBSe/Q" + "F4BUj+pJOF9ROBM4u+FEWA8CQQD4mSJbrABjTUWrlnAte8pS22Tq4/FPO7jH" + "SqjijUHfXKTrHL1OEqV3SVWcFy5j/cqBgX/zm8Q12PFp/PjOhh+nAy8AMCwC" + "FBY3dBSdeprGcqpr6wr3xbG+6WW+AhRMm/facKJNxkT3iKgJbp7R8Xd3QTGC" + "AWEwggFdAgEBMBMwDjEMMAoGA1UEAxMDSUQzAgEAMAkGBSsOAwIaBQCgXTAY" + "BgkqhkiG9w0BCQMxCwYJKoZIhvcNAQcBMBwGCSqGSIb3DQEJBTEPFw0wMjA1" + "MjQyMzEzMDdaMCMGCSqGSIb3DQEJBDEWBBS4WMsoJhf7CVbZYCFcjoTRzPkJ" + "xjCBpwYFKw4DAhswgZ0CQQEkJRHP+mN7d8miwTMN55CUSmo3TO8WGCxgY61T" + "X5k+7NU4XPf1TULjw3GobwaJX13kquPhfVXk+gVy46n4Iw3hAhUBSe/QF4BU" + "j+pJOF9ROBM4u+FEWA8CQQD4mSJbrABjTUWrlnAte8pS22Tq4/FPO7jHSqji" + "jUHfXKTrHL1OEqV3SVWcFy5j/cqBgX/zm8Q12PFp/PjOhh+nBC8wLQIVALID" + "dt+MHwawrDrwsO1Z6sXBaaJsAhRaKssrpevmLkbygKPV07XiAKBG02Zvb2Jh" + "cg=="); // // testcrl.pem // byte[] crl1 = Base64.decode( "MIICjTCCAfowDQYJKoZIhvcNAQECBQAwXzELMAkGA1UEBhMCVVMxIDAeBgNVBAoT" + "F1JTQSBEYXRhIFNlY3VyaXR5LCBJbmMuMS4wLAYDVQQLEyVTZWN1cmUgU2VydmVy" + "IENlcnRpZmljYXRpb24gQXV0aG9yaXR5Fw05NTA1MDIwMjEyMjZaFw05NTA2MDEw" + "MDAxNDlaMIIBaDAWAgUCQQAABBcNOTUwMjAxMTcyNDI2WjAWAgUCQQAACRcNOTUw" + "MjEwMDIxNjM5WjAWAgUCQQAADxcNOTUwMjI0MDAxMjQ5WjAWAgUCQQAADBcNOTUw" + "MjI1MDA0NjQ0WjAWAgUCQQAAGxcNOTUwMzEzMTg0MDQ5WjAWAgUCQQAAFhcNOTUw" + "MzE1MTkxNjU0WjAWAgUCQQAAGhcNOTUwMzE1MTk0MDQxWjAWAgUCQQAAHxcNOTUw" + "MzI0MTk0NDMzWjAWAgUCcgAABRcNOTUwMzI5MjAwNzExWjAWAgUCcgAAERcNOTUw" + "MzMwMDIzNDI2WjAWAgUCQQAAIBcNOTUwNDA3MDExMzIxWjAWAgUCcgAAHhcNOTUw" + "NDA4MDAwMjU5WjAWAgUCcgAAQRcNOTUwNDI4MTcxNzI0WjAWAgUCcgAAOBcNOTUw" + "NDI4MTcyNzIxWjAWAgUCcgAATBcNOTUwNTAyMDIxMjI2WjANBgkqhkiG9w0BAQIF" + "AAN+AHqOEJXSDejYy0UwxxrH/9+N2z5xu/if0J6qQmK92W0hW158wpJg+ovV3+wQ" + "wvIEPRL2rocL0tKfAsVq1IawSJzSNgxG0lrcla3MrJBnZ4GaZDu4FutZh72MR3Gt" + "JaAL3iTJHJD55kK2D/VoyY1djlsPuNh6AEgdVwFAyp0v"); // // ecdsa cert with extra octet string. // byte[] oldEcdsa = Base64.decode( "MIICljCCAkCgAwIBAgIBATALBgcqhkjOPQQBBQAwgY8xCzAJBgNVBAYTAkFVMSgwJ" + "gYDVQQKEx9UaGUgTGVnaW9uIG9mIHRoZSBCb3VuY3kgQ2FzdGxlMRIwEAYDVQQHEw" + "lNZWxib3VybmUxETAPBgNVBAgTCFZpY3RvcmlhMS8wLQYJKoZIhvcNAQkBFiBmZWV" + "kYmFjay1jcnlwdG9AYm91bmN5Y2FzdGxlLm9yZzAeFw0wMTEyMDcwMTAwMDRaFw0w" + "MTEyMDcwMTAxNDRaMIGPMQswCQYDVQQGEwJBVTEoMCYGA1UEChMfVGhlIExlZ2lvb" + "iBvZiB0aGUgQm91bmN5IENhc3RsZTESMBAGA1UEBxMJTWVsYm91cm5lMREwDwYDVQ" + "QIEwhWaWN0b3JpYTEvMC0GCSqGSIb3DQEJARYgZmVlZGJhY2stY3J5cHRvQGJvdW5" + "jeWNhc3RsZS5vcmcwgeQwgb0GByqGSM49AgEwgbECAQEwKQYHKoZIzj0BAQIef///" + "////////////f///////gAAAAAAAf///////MEAEHn///////////////3///////" + "4AAAAAAAH///////AQeawFsO9zxiUHQ1lSSFHXKcanbL7J9HTd5YYXClCwKBB8CD/" + "qWPNyogWzMM7hkK+35BcPTWFc9Pyf7vTs8uaqvAh5///////////////9///+eXpq" + "fXZBx+9FSJoiQnQsDIgAEHwJbbcU7xholSP+w9nFHLebJUhqdLSU05lq/y9X+DHAw" + "CwYHKoZIzj0EAQUAA0MAMEACHnz6t4UNoVROp74ma4XNDjjGcjaqiIWPZLK8Bdw3G" + "QIeLZ4j3a6ividZl344UH+UPUE7xJxlYGuy7ejTsqRR"); byte[] keyUsage = Base64.decode( "MIIE7TCCBFagAwIBAgIEOAOR7jANBgkqhkiG9w0BAQQFADCByTELMAkGA1UE" + "BhMCVVMxFDASBgNVBAoTC0VudHJ1c3QubmV0MUgwRgYDVQQLFD93d3cuZW50" + "cnVzdC5uZXQvQ2xpZW50X0NBX0luZm8vQ1BTIGluY29ycC4gYnkgcmVmLiBs" + "aW1pdHMgbGlhYi4xJTAjBgNVBAsTHChjKSAxOTk5IEVudHJ1c3QubmV0IExp" + "bWl0ZWQxMzAxBgNVBAMTKkVudHJ1c3QubmV0IENsaWVudCBDZXJ0aWZpY2F0" + "aW9uIEF1dGhvcml0eTAeFw05OTEwMTIxOTI0MzBaFw0xOTEwMTIxOTU0MzBa" + "MIHJMQswCQYDVQQGEwJVUzEUMBIGA1UEChMLRW50cnVzdC5uZXQxSDBGBgNV" + "BAsUP3d3dy5lbnRydXN0Lm5ldC9DbGllbnRfQ0FfSW5mby9DUFMgaW5jb3Jw" + "LiBieSByZWYuIGxpbWl0cyBsaWFiLjElMCMGA1UECxMcKGMpIDE5OTkgRW50" + "cnVzdC5uZXQgTGltaXRlZDEzMDEGA1UEAxMqRW50cnVzdC5uZXQgQ2xpZW50" + "IENlcnRpZmljYXRpb24gQXV0aG9yaXR5MIGdMA0GCSqGSIb3DQEBAQUAA4GL" + "ADCBhwKBgQDIOpleMRffrCdvkHvkGf9FozTC28GoT/Bo6oT9n3V5z8GKUZSv" + "x1cDR2SerYIbWtp/N3hHuzeYEpbOxhN979IMMFGpOZ5V+Pux5zDeg7K6PvHV" + "iTs7hbqqdCz+PzFur5GVbgbUB01LLFZHGARS2g4Qk79jkJvh34zmAqTmT173" + "iwIBA6OCAeAwggHcMBEGCWCGSAGG+EIBAQQEAwIABzCCASIGA1UdHwSCARkw" + "ggEVMIHkoIHhoIHepIHbMIHYMQswCQYDVQQGEwJVUzEUMBIGA1UEChMLRW50" + "cnVzdC5uZXQxSDBGBgNVBAsUP3d3dy5lbnRydXN0Lm5ldC9DbGllbnRfQ0Ff" + "SW5mby9DUFMgaW5jb3JwLiBieSByZWYuIGxpbWl0cyBsaWFiLjElMCMGA1UE" + "CxMcKGMpIDE5OTkgRW50cnVzdC5uZXQgTGltaXRlZDEzMDEGA1UEAxMqRW50" + "cnVzdC5uZXQgQ2xpZW50IENlcnRpZmljYXRpb24gQXV0aG9yaXR5MQ0wCwYD" + "VQQDEwRDUkwxMCygKqAohiZodHRwOi8vd3d3LmVudHJ1c3QubmV0L0NSTC9D" + "bGllbnQxLmNybDArBgNVHRAEJDAigA8xOTk5MTAxMjE5MjQzMFqBDzIwMTkx" + "MDEyMTkyNDMwWjALBgNVHQ8EBAMCAQYwHwYDVR0jBBgwFoAUxPucKXuXzUyW" + "/O5bs8qZdIuV6kwwHQYDVR0OBBYEFMT7nCl7l81MlvzuW7PKmXSLlepMMAwG" + "A1UdEwQFMAMBAf8wGQYJKoZIhvZ9B0EABAwwChsEVjQuMAMCBJAwDQYJKoZI" + "hvcNAQEEBQADgYEAP66K8ddmAwWePvrqHEa7pFuPeJoSSJn59DXeDDYHAmsQ" + "OokUgZwxpnyyQbJq5wcBoUv5nyU7lsqZwz6hURzzwy5E97BnRqqS5TvaHBkU" + "ODDV4qIxJS7x7EU47fgGWANzYrAQMY9Av2TgXD7FTx/aEkP/TOYGJqibGapE" + "PHayXOw="); byte[] nameCert = Base64.decode( "MIIEFjCCA3+gAwIBAgIEdS8BozANBgkqhkiG9w0BAQUFADBKMQswCQYDVQQGEwJE"+ "RTERMA8GA1UEChQIREFURVYgZUcxKDAMBgcCggYBCgcUEwExMBgGA1UEAxQRQ0Eg"+ "REFURVYgRDAzIDE6UE4wIhgPMjAwMTA1MTAxMDIyNDhaGA8yMDA0MDUwOTEwMjI0"+ "OFowgYQxCzAJBgNVBAYTAkRFMQ8wDQYDVQQIFAZCYXllcm4xEjAQBgNVBAcUCU7I"+ "dXJuYmVyZzERMA8GA1UEChQIREFURVYgZUcxHTAbBgNVBAUTFDAwMDAwMDAwMDA4"+ "OTU3NDM2MDAxMR4wHAYDVQQDFBVEaWV0bWFyIFNlbmdlbmxlaXRuZXIwgaEwDQYJ"+ "KoZIhvcNAQEBBQADgY8AMIGLAoGBAJLI/LJLKaHoMk8fBECW/od8u5erZi6jI8Ug"+ "C0a/LZyQUO/R20vWJs6GrClQtXB+AtfiBSnyZOSYzOdfDI8yEKPEv8qSuUPpOHps"+ "uNCFdLZF1vavVYGEEWs2+y+uuPmg8q1oPRyRmUZ+x9HrDvCXJraaDfTEd9olmB/Z"+ "AuC/PqpjAgUAwAAAAaOCAcYwggHCMAwGA1UdEwEB/wQCMAAwDwYDVR0PAQH/BAUD"+ "AwdAADAxBgNVHSAEKjAoMCYGBSskCAEBMB0wGwYIKwYBBQUHAgEWD3d3dy56cy5k"+ "YXRldi5kZTApBgNVHREEIjAggR5kaWV0bWFyLnNlbmdlbmxlaXRuZXJAZGF0ZXYu"+ "ZGUwgYQGA1UdIwR9MHuhc6RxMG8xCzAJBgNVBAYTAkRFMT0wOwYDVQQKFDRSZWd1"+ "bGllcnVuZ3NiZWjIb3JkZSBmyHVyIFRlbGVrb21tdW5pa2F0aW9uIHVuZCBQb3N0"+ "MSEwDAYHAoIGAQoHFBMBMTARBgNVBAMUCjVSLUNBIDE6UE6CBACm8LkwDgYHAoIG"+ "AQoMAAQDAQEAMEcGA1UdHwRAMD4wPKAUoBKGEHd3dy5jcmwuZGF0ZXYuZGWiJKQi"+ "MCAxCzAJBgNVBAYTAkRFMREwDwYDVQQKFAhEQVRFViBlRzAWBgUrJAgDBAQNMAsT"+ "A0VVUgIBBQIBATAdBgNVHQ4EFgQUfv6xFP0xk7027folhy+ziZvBJiwwLAYIKwYB"+ "BQUHAQEEIDAeMBwGCCsGAQUFBzABhhB3d3cuZGlyLmRhdGV2LmRlMA0GCSqGSIb3"+ "DQEBBQUAA4GBAEOVX6uQxbgtKzdgbTi6YLffMftFr2mmNwch7qzpM5gxcynzgVkg"+ "pnQcDNlm5AIbS6pO8jTCLfCd5TZ5biQksBErqmesIl3QD+VqtB+RNghxectZ3VEs"+ "nCUtcE7tJ8O14qwCb3TxS9dvIUFiVi4DjbxX46TdcTbTaK8/qr6AIf+l"); byte[] probSelfSignedCert = Base64.decode( "MIICxTCCAi6gAwIBAgIQAQAAAAAAAAAAAAAAAAAAATANBgkqhkiG9w0BAQUFADBF" + "MScwJQYDVQQKEx4gRElSRUNUSU9OIEdFTkVSQUxFIERFUyBJTVBPVFMxGjAYBgNV" + "BAMTESBBQyBNSU5FRkkgQiBURVNUMB4XDTA0MDUwNzEyMDAwMFoXDTE0MDUwNzEy" + "MDAwMFowRTEnMCUGA1UEChMeIERJUkVDVElPTiBHRU5FUkFMRSBERVMgSU1QT1RT" + "MRowGAYDVQQDExEgQUMgTUlORUZJIEIgVEVTVDCBnzANBgkqhkiG9w0BAQEFAAOB" + "jQAwgYkCgYEAveoCUOAukZdcFCs2qJk76vSqEX0ZFzHqQ6faBPZWjwkgUNwZ6m6m" + "qWvvyq1cuxhoDvpfC6NXILETawYc6MNwwxsOtVVIjuXlcF17NMejljJafbPximEt" + "DQ4LcQeSp4K7FyFlIAMLyt3BQ77emGzU5fjFTvHSUNb3jblx0sV28c0CAwEAAaOB" + "tTCBsjAfBgNVHSMEGDAWgBSEJ4bLbvEQY8cYMAFKPFD1/fFXlzAdBgNVHQ4EFgQU" + "hCeGy27xEGPHGDABSjxQ9f3xV5cwDgYDVR0PAQH/BAQDAgEGMBEGCWCGSAGG+EIB" + "AQQEAwIBBjA8BgNVHR8ENTAzMDGgL6AthitodHRwOi8vYWRvbmlzLnBrNy5jZXJ0" + "cGx1cy5uZXQvZGdpLXRlc3QuY3JsMA8GA1UdEwEB/wQFMAMBAf8wDQYJKoZIhvcN" + "AQEFBQADgYEAmToHJWjd3+4zknfsP09H6uMbolHNGG0zTS2lrLKpzcmkQfjhQpT9" + "LUTBvfs1jdjo9fGmQLvOG+Sm51Rbjglb8bcikVI5gLbclOlvqLkm77otjl4U4Z2/" + "Y0vP14Aov3Sn3k+17EfReYUZI4liuB95ncobC4e8ZM++LjQcIM0s+Vs="); byte[] gost34102001base = Base64.decode( "MIIB1DCCAYECEEjpVKXP6Wn1yVz3VeeDQa8wCgYGKoUDAgIDBQAwbTEfMB0G" + "A1UEAwwWR29zdFIzNDEwLTIwMDEgZXhhbXBsZTESMBAGA1UECgwJQ3J5cHRv" + "UHJvMQswCQYDVQQGEwJSVTEpMCcGCSqGSIb3DQEJARYaR29zdFIzNDEwLTIw" + "MDFAZXhhbXBsZS5jb20wHhcNMDUwMjAzMTUxNjQ2WhcNMTUwMjAzMTUxNjQ2" + "WjBtMR8wHQYDVQQDDBZHb3N0UjM0MTAtMjAwMSBleGFtcGxlMRIwEAYDVQQK" + "DAlDcnlwdG9Qcm8xCzAJBgNVBAYTAlJVMSkwJwYJKoZIhvcNAQkBFhpHb3N0" + "UjM0MTAtMjAwMUBleGFtcGxlLmNvbTBjMBwGBiqFAwICEzASBgcqhQMCAiQA" + "BgcqhQMCAh4BA0MABECElWh1YAIaQHUIzROMMYks/eUFA3pDXPRtKw/nTzJ+" + "V4/rzBa5lYgD0Jp8ha4P5I3qprt+VsfLsN8PZrzK6hpgMAoGBiqFAwICAwUA" + "A0EAHw5dw/aw/OiNvHyOE65kvyo4Hp0sfz3csM6UUkp10VO247ofNJK3tsLb" + "HOLjUaqzefrlGb11WpHYrvWFg+FcLA=="); private final byte[] emptyDNCert = Base64.decode( "MIICfTCCAeagAwIBAgIBajANBgkqhkiG9w0BAQQFADB8MQswCQYDVQQGEwJVUzEMMAoGA1UEChMD" + "Q0RXMQkwBwYDVQQLEwAxCTAHBgNVBAcTADEJMAcGA1UECBMAMRowGAYDVQQDExFUZW1wbGFyIFRl" + "c3QgMTAyNDEiMCAGCSqGSIb3DQEJARYTdGVtcGxhcnRlc3RAY2R3LmNvbTAeFw0wNjA1MjIwNTAw" + "MDBaFw0xMDA1MjIwNTAwMDBaMHwxCzAJBgNVBAYTAlVTMQwwCgYDVQQKEwNDRFcxCTAHBgNVBAsT" + "ADEJMAcGA1UEBxMAMQkwBwYDVQQIEwAxGjAYBgNVBAMTEVRlbXBsYXIgVGVzdCAxMDI0MSIwIAYJ" + "KoZIhvcNAQkBFhN0ZW1wbGFydGVzdEBjZHcuY29tMIGfMA0GCSqGSIb3DQEBAQUAA4GNADCBiQKB" + "gQDH3aJpJBfM+A3d84j5YcU6zEQaQ76u5xO9NSBmHjZykKS2kCcUqPpvVOPDA5WgV22dtKPh+lYV" + "iUp7wyCVwAKibq8HIbihHceFqMKzjwC639rMoDJ7bi/yzQWz1Zg+075a4FGPlUKn7Yfu89wKkjdW" + "wDpRPXc/agqBnrx5pJTXzQIDAQABow8wDTALBgNVHQ8EBAMCALEwDQYJKoZIhvcNAQEEBQADgYEA" + "RRsRsjse3i2/KClFVd6YLZ+7K1BE0WxFyY2bbytkwQJSxvv3vLSuweFUbhNxutb68wl/yW4GLy4b" + "1QdyswNxrNDXTuu5ILKhRDDuWeocz83aG2KGtr3JlFyr3biWGEyn5WUOE6tbONoQDJ0oPYgI6CAc" + "EHdUp0lioOCt6UOw7Cs="); private AsymmetricKeyParameter dudPublicKey = new AsymmetricKeyParameter(true) { public String getAlgorithm() { return null; } public String getFormat() { return null; } public byte[] getEncoded() { return null; } }; public String getName() { return "CertTest"; } public void checkCertificate( int id, byte[] bytes) { try { X509CertificateHolder certHldr = new X509CertificateHolder(bytes); SubjectPublicKeyInfo k = certHldr.getSubjectPublicKeyInfo(); // System.out.println(cert); } catch (Exception e) { fail(e.toString()); } } /* public void checkNameCertificate( int id, byte[] bytes) { ByteArrayInputStream bIn; String dump = ""; try { bIn = new ByteArrayInputStream(bytes); CertificateFactory fact = CertificateFactory.getInstance("X.509", "LKBX-BC"); X509Certificate cert = (X509Certificate)fact.generateCertificate(bIn); AsymmetricKeyParameter k = cert.getAsymmetricKeyParameter(); if (!cert.getIssuerDN().toString().equals("C=DE,O=DATEV eG,0.2.262.1.10.7.20=1+CN=CA DATEV D03 1:PN")) { fail(id + " failed - name test."); } // System.out.println(cert); } catch (Exception e) { fail(dump + System.getProperty("line.separator") + getName() + ": "+ id + " failed - exception " + e.toString(), e); } } */ public void checkKeyUsage( int id, byte[] bytes) throws IOException { X509CertificateHolder certHld = new X509CertificateHolder(bytes); if ((DERBitString.getInstance(certHld.getExtension(Extension.keyUsage).getParsedValue()).getBytes()[0] & 0x01) != 0) { fail("error generating cert - key usage wrong."); } } public void checkSelfSignedCertificate( int id, byte[] bytes) throws OperatorCreationException, IOException, CertException { X509CertificateHolder certHolder = new X509CertificateHolder(bytes); assertTrue(certHolder.isSignatureValid(new BcRSAContentVerifierProviderBuilder(digAlgFinder).build(certHolder))); } /** * we generate a self signed certificate for the sake of testing - RSA */ public void checkCreation1() throws Exception { // // a sample key pair. // AsymmetricKeyParameter pubKey = new RSAKeyParameters( false, new BigInteger("b4a7e46170574f16a97082b22be58b6a2a629798419be12872a4bdba626cfae9900f76abfb12139dce5de56564fab2b6543165a040c606887420e33d91ed7ed7", 16), new BigInteger("11", 16)); AsymmetricKeyParameter privKey = new RSAPrivateCrtKeyParameters( new BigInteger("b4a7e46170574f16a97082b22be58b6a2a629798419be12872a4bdba626cfae9900f76abfb12139dce5de56564fab2b6543165a040c606887420e33d91ed7ed7", 16), new BigInteger("11", 16), new BigInteger("9f66f6b05410cd503b2709e88115d55daced94d1a34d4e32bf824d0dde6028ae79c5f07b580f5dce240d7111f7ddb130a7945cd7d957d1920994da389f490c89", 16), new BigInteger("c0a0758cdf14256f78d4708c86becdead1b50ad4ad6c5c703e2168fbf37884cb", 16), new BigInteger("f01734d7960ea60070f1b06f2bb81bfac48ff192ae18451d5e56c734a5aab8a5", 16), new BigInteger("b54bb9edff22051d9ee60f9351a48591b6500a319429c069a3e335a1d6171391", 16), new BigInteger("d3d83daf2a0cecd3367ae6f8ae1aeb82e9ac2f816c6fc483533d8297dd7884cd", 16), new BigInteger("b8f52fc6f38593dabb661d3f50f8897f8106eee68b1bce78a95b132b4e5b5d19", 16)); // // distinguished name table. // X500NameBuilder builder = new X500NameBuilder(RFC4519Style.INSTANCE); builder.addRDN(RFC4519Style.c, "AU"); builder.addRDN(RFC4519Style.o, "The Legion of the Bouncy Castle"); builder.addRDN(RFC4519Style.l, "Melbourne"); builder.addRDN(RFC4519Style.st, "Victoria"); builder.addRDN(PKCSObjectIdentifiers.pkcs_9_at_emailAddress, "feedback-crypto@bouncycastle.org"); // // extensions // // // create the certificate - version 3 - without extensions // AlgorithmIdentifier sigAlg = sigAlgFinder.find("SHA256WithRSAEncryption"); ContentSigner sigGen = new BcRSAContentSignerBuilder(sigAlg, digAlgFinder.find(sigAlg)).build(privKey); X509v3CertificateBuilder certGen = new BcX509v3CertificateBuilder(builder.build(), BigInteger.valueOf(1), new Date(System.currentTimeMillis() - 50000), new Date(System.currentTimeMillis() + 50000),builder.build(), pubKey); X509CertificateHolder certH = certGen.build(sigGen); assertTrue(certH.isValidOn(new Date())); ContentVerifierProvider contentVerifierProvider = new BcRSAContentVerifierProviderBuilder(new DefaultDigestAlgorithmIdentifierFinder()).build(pubKey); assertTrue(certH.isSignatureValid(contentVerifierProvider)); X509Certificate cert = new JcaX509CertificateConverter().getCertificate(certH); Set dummySet = cert.getNonCriticalExtensionOIDs(); if (dummySet != null) { fail("non-critical oid set should be null"); } dummySet = cert.getCriticalExtensionOIDs(); if (dummySet != null) { fail("critical oid set should be null"); } // // create the certificate - version 3 - with extensions // sigGen = new BcRSAContentSignerBuilder(sigAlgFinder.find("MD5WithRSA"), digAlgFinder.find(sigAlgFinder.find("MD5withRSA"))).build(privKey); certGen = new BcX509v3CertificateBuilder(builder.build(), BigInteger.valueOf(1) , new Date(System.currentTimeMillis() - 50000) , new Date(System.currentTimeMillis() + 50000) , builder.build() , pubKey) .addExtension(new ASN1ObjectIdentifier("2.5.29.15"), true, new KeyUsage(KeyUsage.encipherOnly)) .addExtension(new ASN1ObjectIdentifier("2.5.29.37"), true, new DERSequence(KeyPurposeId.anyExtendedKeyUsage)) .addExtension(new ASN1ObjectIdentifier("2.5.29.17"), true, new GeneralNames(new GeneralName(GeneralName.rfc822Name, "test@test.test"))); X509CertificateHolder certHolder = certGen.build(sigGen); assertTrue(certHolder.isValidOn(new Date())); contentVerifierProvider = new BcRSAContentVerifierProviderBuilder(digAlgFinder).build(pubKey); if (!certHolder.isSignatureValid(contentVerifierProvider)) { fail("signature test failed"); } ByteArrayInputStream bIn = new ByteArrayInputStream(certHolder.getEncoded()); CertificateFactory certFact = CertificateFactory.getInstance("X.509"); cert = (X509Certificate)certFact.generateCertificate(bIn); if (!cert.getKeyUsage()[7]) { fail("error generating cert - key usage wrong."); } List l = cert.getExtendedKeyUsage(); if (!l.get(0).equals(KeyPurposeId.anyExtendedKeyUsage.getId())) { fail("failed extended key usage test"); } Collection c = cert.getSubjectAlternativeNames(); Iterator it = c.iterator(); while (it.hasNext()) { List gn = (List)it.next(); if (!gn.get(1).equals("test@test.test")) { fail("failed subject alternative names test"); } } // System.out.println(cert); // // create the certificate - version 1 // sigGen = new BcRSAContentSignerBuilder(sigAlgFinder.find("MD5WithRSA"), digAlgFinder.find(sigAlgFinder.find("MD5withRSA"))).build(privKey); X509v1CertificateBuilder certGen1 = new BcX509v1CertificateBuilder(builder.build(), BigInteger.valueOf(1), new Date(System.currentTimeMillis() - 50000),new Date(System.currentTimeMillis() + 50000),builder.build(),pubKey); cert = new JcaX509CertificateConverter().getCertificate(certGen1.build(sigGen)); assertTrue(certHolder.isValidOn(new Date())); contentVerifierProvider = new BcRSAContentVerifierProviderBuilder(new DefaultDigestAlgorithmIdentifierFinder()).build(pubKey); assertTrue(certHolder.isSignatureValid(contentVerifierProvider)); bIn = new ByteArrayInputStream(cert.getEncoded()); certFact = CertificateFactory.getInstance("X.509"); cert = (X509Certificate)certFact.generateCertificate(bIn); // System.out.println(cert); if (!cert.getIssuerDN().equals(cert.getSubjectDN())) { fail("name comparison fails"); } // // a lightweight key pair. // RSAKeyParameters lwPubKey = new RSAKeyParameters( false, new BigInteger("b4a7e46170574f16a97082b22be58b6a2a629798419be12872a4bdba626cfae9900f76abfb12139dce5de56564fab2b6543165a040c606887420e33d91ed7ed7", 16), new BigInteger("11", 16)); RSAPrivateCrtKeyParameters lwPrivKey = new RSAPrivateCrtKeyParameters( new BigInteger("b4a7e46170574f16a97082b22be58b6a2a629798419be12872a4bdba626cfae9900f76abfb12139dce5de56564fab2b6543165a040c606887420e33d91ed7ed7", 16), new BigInteger("11", 16), new BigInteger("9f66f6b05410cd503b2709e88115d55daced94d1a34d4e32bf824d0dde6028ae79c5f07b580f5dce240d7111f7ddb130a7945cd7d957d1920994da389f490c89", 16), new BigInteger("c0a0758cdf14256f78d4708c86becdead1b50ad4ad6c5c703e2168fbf37884cb", 16), new BigInteger("f01734d7960ea60070f1b06f2bb81bfac48ff192ae18451d5e56c734a5aab8a5", 16), new BigInteger("b54bb9edff22051d9ee60f9351a48591b6500a319429c069a3e335a1d6171391", 16), new BigInteger("d3d83daf2a0cecd3367ae6f8ae1aeb82e9ac2f816c6fc483533d8297dd7884cd", 16), new BigInteger("b8f52fc6f38593dabb661d3f50f8897f8106eee68b1bce78a95b132b4e5b5d19", 16)); // // distinguished name table. // builder = new X500NameBuilder(RFC4519Style.INSTANCE); builder.addRDN(RFC4519Style.c, "AU"); builder.addRDN(RFC4519Style.o, "The Legion of the Bouncy Castle"); builder.addRDN(RFC4519Style.l, "Melbourne"); builder.addRDN(RFC4519Style.st, "Victoria"); builder.addRDN(PKCSObjectIdentifiers.pkcs_9_at_emailAddress, "feedback-crypto@bouncycastle.org"); // // extensions // // // create the certificate - version 3 - without extensions // AlgorithmIdentifier sigAlgId = new DefaultSignatureAlgorithmIdentifierFinder().find("SHA256WithRSAEncryption"); AlgorithmIdentifier digAlgId = new DefaultDigestAlgorithmIdentifierFinder().find(sigAlgId); sigGen = new BcRSAContentSignerBuilder(sigAlgId, digAlgId).build(lwPrivKey); SubjectPublicKeyInfo pubInfo = SubjectPublicKeyInfoFactory.createSubjectPublicKeyInfo(lwPubKey); certGen = new X509v3CertificateBuilder(builder.build(), BigInteger.valueOf(1), new Date(System.currentTimeMillis() - 50000), new Date(System.currentTimeMillis() + 50000), builder.build(), pubInfo); certHolder = certGen.build(sigGen); assertTrue(certHolder.isValidOn(new Date())); contentVerifierProvider = new BcRSAContentVerifierProviderBuilder(new DefaultDigestAlgorithmIdentifierFinder()).build(lwPubKey); assertTrue(certHolder.isSignatureValid(contentVerifierProvider)); if (!certHolder.isSignatureValid(contentVerifierProvider)) { fail("lw sig verification failed"); } } /** * we generate a self signed certificate for the sake of testing - DSA */ public void checkCreation2() throws Exception { // // set up the keys // AsymmetricKeyParameter privKey; AsymmetricKeyParameter pubKey; AsymmetricCipherKeyPairGenerator kpg = new DSAKeyPairGenerator(); BigInteger r = new BigInteger("68076202252361894315274692543577577550894681403"); BigInteger s = new BigInteger("1089214853334067536215539335472893651470583479365"); DSAParametersGenerator pGen = new DSAParametersGenerator(); pGen.init(512, 80, new SecureRandom()); DSAParameters params = pGen.generateParameters(); DSAKeyGenerationParameters genParam = new DSAKeyGenerationParameters(new SecureRandom(), params); kpg.init(genParam); AsymmetricCipherKeyPair pair = kpg.generateKeyPair(); privKey = (AsymmetricKeyParameter)pair.getPrivate(); pubKey = (AsymmetricKeyParameter)pair.getPublic(); // // distinguished name table. // X500NameBuilder builder = createStdBuilder(); // // extensions // // // create the certificate - version 3 // AlgorithmIdentifier sigAlgId = sigAlgFinder.find("SHA1withDSA"); AlgorithmIdentifier digAlgId = digAlgFinder.find(sigAlgId); ContentSigner sigGen = new BcDSAContentSignerBuilder(sigAlgId, digAlgId).build(privKey); X509v3CertificateBuilder certGen = new BcX509v3CertificateBuilder(builder.build(),BigInteger.valueOf(1),new Date(System.currentTimeMillis() - 50000),new Date(System.currentTimeMillis() + 50000),builder.build(),pubKey); X509CertificateHolder cert = certGen.build(sigGen); assertTrue(cert.isValidOn(new Date())); assertTrue(cert.isSignatureValid(new BcDSAContentVerifierProviderBuilder(digAlgFinder).build(pubKey))); // // create the certificate - version 1 // sigAlgId = sigAlgFinder.find("SHA1withDSA"); digAlgId = digAlgFinder.find(sigAlgId); sigGen = new BcDSAContentSignerBuilder(sigAlgId, digAlgId).build(privKey); X509v1CertificateBuilder certGen1 = new BcX509v1CertificateBuilder(builder.build(),BigInteger.valueOf(1),new Date(System.currentTimeMillis() - 50000),new Date(System.currentTimeMillis() + 50000),builder.build(),pubKey); cert = certGen1.build(sigGen); assertTrue(cert.isValidOn(new Date())); assertTrue(cert.isSignatureValid(new BcDSAContentVerifierProviderBuilder(digAlgFinder).build(pubKey))); ByteArrayInputStream bIn = new ByteArrayInputStream(cert.getEncoded()); CertificateFactory fact = CertificateFactory.getInstance("X.509"); X509Certificate x509cert = (X509Certificate)fact.generateCertificate(bIn); //System.out.println(cert); } private X500NameBuilder createStdBuilder() { X500NameBuilder builder = new X500NameBuilder(RFC4519Style.INSTANCE); builder.addRDN(RFC4519Style.c, "AU"); builder.addRDN(RFC4519Style.o, "The Legion of the Bouncy Castle"); builder.addRDN(RFC4519Style.l, "Melbourne"); builder.addRDN(RFC4519Style.st, "Victoria"); builder.addRDN(PKCSObjectIdentifiers.pkcs_9_at_emailAddress, "feedback-crypto@bouncycastle.org"); return builder; } private void checkCRL( int id, byte[] bytes) { String dump = ""; try { X509CRLHolder crlHolder = new X509CRLHolder(bytes); } catch (Exception e) { fail(dump + System.getProperty("line.separator") + getName() + ": "+ id + " failed - exception " + e.toString()); } } public void checkCRLCreation1() throws Exception { AsymmetricCipherKeyPairGenerator kpg = new RSAKeyPairGenerator(); RSAKeyGenerationParameters genParam = new RSAKeyGenerationParameters( BigInteger.valueOf(0x1001), new SecureRandom(), 1024, 25); kpg.init(genParam); AsymmetricCipherKeyPair pair = kpg.generateKeyPair(); Date now = new Date(); X509v2CRLBuilder crlGen = new X509v2CRLBuilder(new X500Name("CN=Test CA"), now); BcX509ExtensionUtils extFact = new BcX509ExtensionUtils(new SHA1DigestCalculator()); crlGen.setNextUpdate(new Date(now.getTime() + 100000)); crlGen.addCRLEntry(BigInteger.ONE, now, CRLReason.privilegeWithdrawn); crlGen.addExtension(Extension.authorityKeyIdentifier, false, extFact.createAuthorityKeyIdentifier(pair.getPublic())); AlgorithmIdentifier sigAlg = sigAlgFinder.find("SHA256withRSAEncryption"); AlgorithmIdentifier digAlg = digAlgFinder.find(sigAlg); X509CRLHolder crl = crlGen.build(new BcRSAContentSignerBuilder(sigAlg, digAlg).build(pair.getPrivate())); if (!crl.getIssuer().equals(new X500Name("CN=Test CA"))) { fail("failed CRL issuer test"); } Extension authExt = crl.getExtension(Extension.authorityKeyIdentifier); if (authExt == null) { fail("failed to find CRL extension"); } AuthorityKeyIdentifier authId = AuthorityKeyIdentifier.getInstance(authExt.getParsedValue()); X509CRLEntryHolder entry = crl.getRevokedCertificate(BigInteger.ONE); if (entry == null) { fail("failed to find CRL entry"); } if (!entry.getSerialNumber().equals(BigInteger.ONE)) { fail("CRL cert serial number does not match"); } if (!entry.hasExtensions()) { fail("CRL entry extension not found"); } Extension ext = entry.getExtension(Extension.reasonCode); if (ext != null) { ASN1Enumerated reasonCode = ASN1Enumerated.getInstance(ext.getParsedValue()); if (reasonCode.getValue().intValue() != CRLReason.privilegeWithdrawn) { fail("CRL entry reasonCode wrong"); } } else { fail("CRL entry reasonCode not found"); } } public void checkCRLCreation2() throws Exception { AsymmetricCipherKeyPairGenerator kpg = new RSAKeyPairGenerator(); RSAKeyGenerationParameters genParam = new RSAKeyGenerationParameters( BigInteger.valueOf(0x1001), new SecureRandom(), 1024, 25); kpg.init(genParam); AsymmetricCipherKeyPair pair = kpg.generateKeyPair(); Date now = new Date(); X509v2CRLBuilder crlGen = new X509v2CRLBuilder(new X500Name("CN=Test CA"), now); crlGen.setNextUpdate(new Date(now.getTime() + 100000)); ExtensionsGenerator extGen = new ExtensionsGenerator(); CRLReason crlReason = CRLReason.lookup(CRLReason.privilegeWithdrawn); extGen.addExtension(Extension.reasonCode, false, crlReason); BcX509ExtensionUtils extFact = new BcX509ExtensionUtils(new SHA1DigestCalculator()); crlGen.addCRLEntry(BigInteger.ONE, now, extGen.generate()); crlGen.addExtension(Extension.authorityKeyIdentifier, false, extFact.createAuthorityKeyIdentifier((AsymmetricKeyParameter)pair.getPublic())); AlgorithmIdentifier sigAlg = sigAlgFinder.find("SHA256withRSAEncryption"); AlgorithmIdentifier digAlg = digAlgFinder.find(sigAlg); X509CRLHolder crlHolder = crlGen.build(new BcRSAContentSignerBuilder(sigAlg, digAlg).build((AsymmetricKeyParameter)pair.getPrivate())); if (!crlHolder.getIssuer().equals(new X500Name("CN=Test CA"))) { fail("failed CRL issuer test"); } Extension authExt = crlHolder.getExtension(Extension.authorityKeyIdentifier); if (authExt == null) { fail("failed to find CRL extension"); } AuthorityKeyIdentifier authId = AuthorityKeyIdentifier.getInstance(authExt.getParsedValue()); X509CRLEntryHolder entry = crlHolder.getRevokedCertificate(BigInteger.ONE); if (entry == null) { fail("failed to find CRL entry"); } if (!entry.getSerialNumber().equals(BigInteger.ONE)) { fail("CRL cert serial number does not match"); } if (!entry.hasExtensions()) { fail("CRL entry extension not found"); } Extension ext = entry.getExtension(Extension.reasonCode); if (ext != null) { ASN1Enumerated reasonCode = ASN1Enumerated.getInstance(ext.getParsedValue()); if (reasonCode.getValue().intValue() != CRLReason.privilegeWithdrawn) { fail("CRL entry reasonCode wrong"); } } else { fail("CRL entry reasonCode not found"); } } public void checkCRLCreation3() throws Exception { AsymmetricCipherKeyPairGenerator kpg = new RSAKeyPairGenerator(); RSAKeyGenerationParameters genParam = new RSAKeyGenerationParameters( BigInteger.valueOf(0x1001), new SecureRandom(), 1024, 25); kpg.init(genParam); AsymmetricCipherKeyPair pair = kpg.generateKeyPair(); Date now = new Date(); X509v2CRLBuilder crlGen = new X509v2CRLBuilder(new X500Name("CN=Test CA"), now); crlGen.setNextUpdate(new Date(now.getTime() + 100000)); ExtensionsGenerator extGen = new ExtensionsGenerator(); CRLReason crlReason = CRLReason.lookup(CRLReason.privilegeWithdrawn); extGen.addExtension(Extension.reasonCode, false, crlReason); BcX509ExtensionUtils extFact = new BcX509ExtensionUtils(new SHA1DigestCalculator()); Extensions entryExtensions = extGen.generate(); crlGen.addCRLEntry(BigInteger.ONE, now, entryExtensions); crlGen.addExtension(Extension.authorityKeyIdentifier, false, extFact.createAuthorityKeyIdentifier((AsymmetricKeyParameter)pair.getPublic())); AlgorithmIdentifier sigAlg = sigAlgFinder.find("SHA256withRSAEncryption"); AlgorithmIdentifier digAlg = digAlgFinder.find(sigAlg); X509CRLHolder crlHolder = crlGen.build(new BcRSAContentSignerBuilder(sigAlg, digAlg).build((AsymmetricKeyParameter)pair.getPrivate())); if (!crlHolder.getIssuer().equals(new X500Name("CN=Test CA"))) { fail("failed CRL issuer test"); } Extension authExt = crlHolder.getExtension(Extension.authorityKeyIdentifier); if (authExt == null) { fail("failed to find CRL extension"); } AuthorityKeyIdentifier authId = AuthorityKeyIdentifier.getInstance(authExt.getParsedValue()); X509CRLEntryHolder entry = crlHolder.getRevokedCertificate(BigInteger.ONE); if (entry == null) { fail("failed to find CRL entry"); } if (!entry.getSerialNumber().equals(BigInteger.ONE)) { fail("CRL cert serial number does not match"); } if (!entry.hasExtensions()) { fail("CRL entry extension not found"); } Extension ext = entry.getExtension(Extension.reasonCode); if (ext != null) { ASN1Enumerated reasonCode = ASN1Enumerated.getInstance(ext.getParsedValue()); if (reasonCode.getValue().intValue() != CRLReason.privilegeWithdrawn) { fail("CRL entry reasonCode wrong"); } } else { fail("CRL entry reasonCode not found"); } // // check loading of existing CRL // now = new Date(); crlGen = new X509v2CRLBuilder(new X500Name("CN=Test CA"), now); crlGen.setNextUpdate(new Date(now.getTime() + 100000)); crlGen.addCRL(crlHolder); crlGen.addCRLEntry(BigInteger.valueOf(2), now, entryExtensions); crlGen.addExtension(Extension.authorityKeyIdentifier, false, extFact.createAuthorityKeyIdentifier(pair.getPublic())); crlHolder = crlGen.build(new BcRSAContentSignerBuilder(sigAlg, digAlg).build(pair.getPrivate())); int count = 0; boolean oneFound = false; boolean twoFound = false; Iterator it = crlHolder.getRevokedCertificates().iterator(); while (it.hasNext()) { X509CRLEntryHolder crlEnt = (X509CRLEntryHolder)it.next(); if (crlEnt.getSerialNumber().intValue() == 1) { oneFound = true; Extension extn = crlEnt.getExtension(Extension.reasonCode); if (extn != null) { ASN1Enumerated reasonCode = ASN1Enumerated.getInstance(extn.getParsedValue()); if (reasonCode.getValue().intValue() != CRLReason.privilegeWithdrawn) { fail("CRL entry reasonCode wrong on recheck"); } } else { fail("CRL entry reasonCode not found on recheck"); } } else if (crlEnt.getSerialNumber().intValue() == 2) { twoFound = true; } count++; } if (count != 2) { fail("wrong number of CRLs found, got: " + count); } if (!oneFound || !twoFound) { fail("wrong CRLs found in copied list"); } // // check factory read back // CertificateFactory cFact = CertificateFactory.getInstance("X.509"); X509CRL readCrl = (X509CRL)cFact.generateCRL(new ByteArrayInputStream(crlHolder.getEncoded())); if (readCrl == null) { fail("crl not returned!"); } Collection col = cFact.generateCRLs(new ByteArrayInputStream(crlHolder.getEncoded())); if (col.size() != 1) { fail("wrong number of CRLs found in collection"); } } public void checkCreation5() throws Exception { // // a sample key pair. // AsymmetricKeyParameter pubKey = new RSAKeyParameters( false, new BigInteger("b4a7e46170574f16a97082b22be58b6a2a629798419be12872a4bdba626cfae9900f76abfb12139dce5de56564fab2b6543165a040c606887420e33d91ed7ed7", 16), new BigInteger("11", 16)); AsymmetricKeyParameter privKey = new RSAPrivateCrtKeyParameters( new BigInteger("b4a7e46170574f16a97082b22be58b6a2a629798419be12872a4bdba626cfae9900f76abfb12139dce5de56564fab2b6543165a040c606887420e33d91ed7ed7", 16), new BigInteger("11", 16), new BigInteger("9f66f6b05410cd503b2709e88115d55daced94d1a34d4e32bf824d0dde6028ae79c5f07b580f5dce240d7111f7ddb130a7945cd7d957d1920994da389f490c89", 16), new BigInteger("c0a0758cdf14256f78d4708c86becdead1b50ad4ad6c5c703e2168fbf37884cb", 16), new BigInteger("f01734d7960ea60070f1b06f2bb81bfac48ff192ae18451d5e56c734a5aab8a5", 16), new BigInteger("b54bb9edff22051d9ee60f9351a48591b6500a319429c069a3e335a1d6171391", 16), new BigInteger("d3d83daf2a0cecd3367ae6f8ae1aeb82e9ac2f816c6fc483533d8297dd7884cd", 16), new BigInteger("b8f52fc6f38593dabb661d3f50f8897f8106eee68b1bce78a95b132b4e5b5d19", 16)); // // set up the keys // SecureRandom rand = new SecureRandom(); // // distinguished name table. // X500NameBuilder builder = createStdBuilder(); // // create base certificate - version 3 // AlgorithmIdentifier sigAlg = sigAlgFinder.find("MD5WithRSA"); AlgorithmIdentifier digAlg = digAlgFinder.find(sigAlg); ContentSigner sigGen = new BcRSAContentSignerBuilder(sigAlg, digAlg).build(privKey); ASN1ObjectIdentifier extOid = new ASN1ObjectIdentifier("2.5.29.37"); X509v3CertificateBuilder certGen = new BcX509v3CertificateBuilder(builder.build(),BigInteger.valueOf(1),new Date(System.currentTimeMillis() - 50000),new Date(System.currentTimeMillis() + 50000),builder.build(),pubKey) .addExtension(new ASN1ObjectIdentifier("2.5.29.15"), true, new KeyUsage(KeyUsage.encipherOnly)) .addExtension(extOid, true, new DERSequence(KeyPurposeId.anyExtendedKeyUsage)) .addExtension(new ASN1ObjectIdentifier("2.5.29.17"), true, new GeneralNames(new GeneralName(GeneralName.rfc822Name, "test@test.test"))); X509CertificateHolder baseCert = certGen.build(sigGen); // // copy certificate // certGen = new BcX509v3CertificateBuilder(builder.build(),BigInteger.valueOf(1),new Date(System.currentTimeMillis() - 50000),new Date(System.currentTimeMillis() + 50000),builder.build(),pubKey) .copyAndAddExtension(new ASN1ObjectIdentifier("2.5.29.15"), true, baseCert) .copyAndAddExtension(extOid, false, baseCert); X509CertificateHolder cert = certGen.build(sigGen); assertTrue(cert.isValidOn(new Date())); assertTrue(cert.isSignatureValid(new BcRSAContentVerifierProviderBuilder(digAlgFinder).build(pubKey))); if (!baseCert.getExtension(new ASN1ObjectIdentifier("2.5.29.15")).equals(cert.getExtension(new ASN1ObjectIdentifier("2.5.29.15")))) { fail("2.5.29.15 differs"); } assertTrue(baseCert.getExtension(extOid).getExtnId().equals(cert.getExtension(extOid).getExtnId())); assertFalse(baseCert.getExtension(extOid).isCritical() == cert.getExtension(extOid).isCritical()); if (!baseCert.getExtension(extOid).getParsedValue().equals(cert.getExtension(extOid).getParsedValue())) { fail("2.5.29.37 differs"); } // // exception test // try { certGen.copyAndAddExtension(new ASN1ObjectIdentifier("2.5.99.99"), true, baseCert); fail("exception not thrown on dud extension copy"); } catch (NullPointerException e) { // expected } // try // { // certGen.setPublicKey(dudPublicKey); // // certGen.generate(privKey, BC); // // fail("key without encoding not detected in v3"); // } // catch (IllegalArgumentException e) // { // // expected // } } public void testForgedSignature() throws Exception { String cert = "MIIBsDCCAVoCAQYwDQYJKoZIhvcNAQEFBQAwYzELMAkGA1UEBhMCQVUxEzARBgNV" + "BAgTClF1ZWVuc2xhbmQxGjAYBgNVBAoTEUNyeXB0U29mdCBQdHkgTHRkMSMwIQYD" + "VQQDExpTZXJ2ZXIgdGVzdCBjZXJ0ICg1MTIgYml0KTAeFw0wNjA5MTEyMzU4NTVa" + "Fw0wNjEwMTEyMzU4NTVaMGMxCzAJBgNVBAYTAkFVMRMwEQYDVQQIEwpRdWVlbnNs" + "YW5kMRowGAYDVQQKExFDcnlwdFNvZnQgUHR5IEx0ZDEjMCEGA1UEAxMaU2VydmVy" + "IHRlc3QgY2VydCAoNTEyIGJpdCkwXDANBgkqhkiG9w0BAQEFAANLADBIAkEAn7PD" + "hCeV/xIxUg8V70YRxK2A5jZbD92A12GN4PxyRQk0/lVmRUNMaJdq/qigpd9feP/u" + "12S4PwTLb/8q/v657QIDAQABMA0GCSqGSIb3DQEBBQUAA0EAbynCRIlUQgaqyNgU" + "DF6P14yRKUtX8akOP2TwStaSiVf/akYqfLFm3UGka5XbPj4rifrZ0/sOoZEEBvHQ" + "e20sRA=="; X509CertificateHolder hldr = new X509CertificateHolder(Base64.decode(cert)); assertFalse(hldr.isSignatureValid(new BcRSAContentVerifierProviderBuilder(digAlgFinder).build(hldr))); } private void pemTest() throws Exception { CertificateFactory cf = CertificateFactory.getInstance("X.509"); X509Certificate cert = readPEMCert(cf, PEMData.CERTIFICATE_1); if (cert == null) { fail("PEM cert not read"); } cert = readPEMCert(cf, "-----BEGIN CERTIFICATE-----" + PEMData.CERTIFICATE_2); if (cert == null) { fail("PEM cert with extraneous header not read"); } CRL crl = cf.generateCRL(new ByteArrayInputStream(PEMData.CRL_1.getBytes("US-ASCII"))); if (crl == null) { fail("PEM crl not read"); } Collection col = cf.generateCertificates(new ByteArrayInputStream(PEMData.CERTIFICATE_2.getBytes("US-ASCII"))); if (col.size() != 1 || !col.contains(cert)) { fail("PEM cert collection not right"); } col = cf.generateCRLs(new ByteArrayInputStream(PEMData.CRL_2.getBytes("US-ASCII"))); if (col.size() != 1 || !col.contains(crl)) { fail("PEM crl collection not right"); } } private static X509Certificate readPEMCert(CertificateFactory cf, String pemData) throws CertificateException, UnsupportedEncodingException { return (X509Certificate)cf.generateCertificate(new ByteArrayInputStream(pemData.getBytes("US-ASCII"))); } private void createPSSCert(String algorithm) throws Exception { AsymmetricCipherKeyPair pair = generateLongFixedKeys(); AsymmetricKeyParameter privKey = (AsymmetricKeyParameter)pair.getPrivate(); AsymmetricKeyParameter pubKey = (AsymmetricKeyParameter)pair.getPublic(); // // distinguished name table. // X500NameBuilder builder = createStdBuilder(); // // create base certificate - version 3 // BcX509ExtensionUtils extFact = new BcX509ExtensionUtils(new SHA1DigestCalculator()); AlgorithmIdentifier sigAlgId = sigAlgFinder.find(algorithm); AlgorithmIdentifier digAlgId = digAlgFinder.find(sigAlgId); ContentSigner sigGen = new BcRSAContentSignerBuilder(sigAlgId, digAlgId).build(privKey); BcX509v3CertificateBuilder certGen = new BcX509v3CertificateBuilder(builder.build(),BigInteger.valueOf(1), new Date(System.currentTimeMillis() - 50000),new Date(System.currentTimeMillis() + 50000),builder.build(),pubKey); certGen.addExtension(new ASN1ObjectIdentifier("2.5.29.15"), true, new KeyUsage(KeyUsage.encipherOnly)); certGen.addExtension(new ASN1ObjectIdentifier("2.5.29.37"), true, new DERSequence(KeyPurposeId.anyExtendedKeyUsage)); certGen.addExtension(new ASN1ObjectIdentifier("2.5.29.17"), true, new GeneralNames(new GeneralName(GeneralName.rfc822Name, "test@test.test"))); certGen.addExtension(Extension.authorityKeyIdentifier, true, extFact.createAuthorityKeyIdentifier(pubKey)); X509CertificateHolder baseCert = certGen.build(sigGen); assertTrue(baseCert.isSignatureValid(new BcRSAContentVerifierProviderBuilder(digAlgFinder).build(pubKey))); } private AsymmetricCipherKeyPair generateLongFixedKeys() { RSAKeyParameters pubKeySpec = new RSAKeyParameters( false, new BigInteger("a56e4a0e701017589a5187dc7ea841d156f2ec0e36ad52a44dfeb1e61f7ad991d8c51056ffedb162b4c0f283a12a88a394dff526ab7291cbb307ceabfce0b1dfd5cd9508096d5b2b8b6df5d671ef6377c0921cb23c270a70e2598e6ff89d19f105acc2d3f0cb35f29280e1386b6f64c4ef22e1e1f20d0ce8cffb2249bd9a2137",16), new BigInteger("010001",16)); RSAKeyParameters privKeySpec = new RSAPrivateCrtKeyParameters( new BigInteger("a56e4a0e701017589a5187dc7ea841d156f2ec0e36ad52a44dfeb1e61f7ad991d8c51056ffedb162b4c0f283a12a88a394dff526ab7291cbb307ceabfce0b1dfd5cd9508096d5b2b8b6df5d671ef6377c0921cb23c270a70e2598e6ff89d19f105acc2d3f0cb35f29280e1386b6f64c4ef22e1e1f20d0ce8cffb2249bd9a2137",16), new BigInteger("010001",16), new BigInteger("33a5042a90b27d4f5451ca9bbbd0b44771a101af884340aef9885f2a4bbe92e894a724ac3c568c8f97853ad07c0266c8c6a3ca0929f1e8f11231884429fc4d9ae55fee896a10ce707c3ed7e734e44727a39574501a532683109c2abacaba283c31b4bd2f53c3ee37e352cee34f9e503bd80c0622ad79c6dcee883547c6a3b325",16), new BigInteger("e7e8942720a877517273a356053ea2a1bc0c94aa72d55c6e86296b2dfc967948c0a72cbccca7eacb35706e09a1df55a1535bd9b3cc34160b3b6dcd3eda8e6443",16), new BigInteger("b69dca1cf7d4d7ec81e75b90fcca874abcde123fd2700180aa90479b6e48de8d67ed24f9f19d85ba275874f542cd20dc723e6963364a1f9425452b269a6799fd",16), new BigInteger("28fa13938655be1f8a159cbaca5a72ea190c30089e19cd274a556f36c4f6e19f554b34c077790427bbdd8dd3ede2448328f385d81b30e8e43b2fffa027861979",16), new BigInteger("1a8b38f398fa712049898d7fb79ee0a77668791299cdfa09efc0e507acb21ed74301ef5bfd48be455eaeb6e1678255827580a8e4e8e14151d1510a82a3f2e729",16), new BigInteger("27156aba4126d24a81f3a528cbfb27f56886f840a9f6e86e17a44b94fe9319584b8e22fdde1e5a2e3bd8aa5ba8d8584194eb2190acf832b847f13a3d24a79f4d",16)); return new AsymmetricCipherKeyPair(pubKeySpec, privKeySpec); } public void testNullDerNullCert() throws Exception { AsymmetricCipherKeyPair pair = generateLongFixedKeys(); AsymmetricKeyParameter pubKey = (AsymmetricKeyParameter)pair.getPublic(); AsymmetricKeyParameter privKey = (AsymmetricKeyParameter)pair.getPrivate(); DefaultSignatureAlgorithmIdentifierFinder sigAlgFinder = new DefaultSignatureAlgorithmIdentifierFinder(); DefaultDigestAlgorithmIdentifierFinder digAlgFinder = new DefaultDigestAlgorithmIdentifierFinder(); AlgorithmIdentifier sigAlgId = sigAlgFinder.find("MD5withRSA"); AlgorithmIdentifier digAlgId = digAlgFinder.find(sigAlgId); ContentSigner sigGen = new BcRSAContentSignerBuilder(sigAlgId, digAlgId).build(privKey); BcX509v3CertificateBuilder certGen = new BcX509v3CertificateBuilder(new X500Name("CN=Test"),BigInteger.valueOf(1),new Date(System.currentTimeMillis() - 50000),new Date(System.currentTimeMillis() + 50000),new X500Name("CN=Test"),pubKey); X509CertificateHolder cert = certGen.build(sigGen); Certificate struct = Certificate.getInstance(cert.getEncoded()); ASN1Object tbsCertificate = struct.getTBSCertificate(); AlgorithmIdentifier sig = struct.getSignatureAlgorithm(); ASN1EncodableVector v = new ASN1EncodableVector(); v.add(tbsCertificate); v.add(new AlgorithmIdentifier(sig.getAlgorithm())); v.add(struct.getSignature()); // verify ByteArrayInputStream bIn; String dump = ""; bIn = new ByteArrayInputStream(new DERSequence(v).getEncoded()); cert = new X509CertificateHolder(new DERSequence(v).getEncoded()); assertTrue(cert.isSignatureValid(new BcRSAContentVerifierProviderBuilder(digAlgFinder).build(pubKey))); } public void testCertificates() throws Exception { checkCertificate(1, cert1); checkCertificate(2, cert2); checkCertificate(3, cert3); checkCertificate(4, cert4); checkCertificate(5, cert5); //checkCertificate(7, cert7); checkKeyUsage(8, keyUsage); checkSelfSignedCertificate(11, probSelfSignedCert); checkCRL(1, crl1); checkCreation1(); checkCreation2(); checkCreation5(); createPSSCert("SHA1withRSAandMGF1"); createPSSCert("SHA224withRSAandMGF1"); createPSSCert("SHA256withRSAandMGF1"); createPSSCert("SHA384withRSAandMGF1"); checkCRLCreation1(); checkCRLCreation2(); checkCRLCreation3(); pemTest(); checkCertificate(18, emptyDNCert); } } bouncycastle-1.49.orig/test/src/org/bouncycastle/cert/test/AllTests.java0000644000175000017500000000322412110046617025772 0ustar ebourgebourgpackage org.bouncycastle.cert.test; import java.security.Security; import junit.framework.Test; import junit.framework.TestCase; import junit.framework.TestSuite; import org.bouncycastle.jce.provider.BouncyCastleProvider; import org.bouncycastle.util.test.SimpleTestResult; public class AllTests extends TestCase { public void testSimpleTests() { org.bouncycastle.util.test.Test[] tests = new org.bouncycastle.util.test.Test[] { new CertTest(), new PKCS10Test(), new AttrCertSelectorTest(), new AttrCertTest(), new X509ExtensionUtilsTest() }; for (int i = 0; i != tests.length; i++) { SimpleTestResult result = (SimpleTestResult)tests[i].perform(); if (!result.isSuccessful()) { if (result.getException() != null) { result.getException().printStackTrace(); } fail(result.toString()); } } } public static void main (String[] args) { junit.textui.TestRunner.run(suite()); } public static Test suite() { TestSuite suite = new TestSuite("Cert Tests"); if (Security.getProvider("BC") == null) { Security.addProvider(new BouncyCastleProvider()); } suite.addTestSuite(AllTests.class); suite.addTestSuite(BcAttrCertSelectorTest.class); suite.addTestSuite(BcAttrCertSelectorTest.class); suite.addTestSuite(BcAttrCertTest.class); suite.addTestSuite(BcCertTest.class); suite.addTestSuite(BcPKCS10Test.class); suite.addTest(ConverterTest.suite()); return suite; } }bouncycastle-1.49.orig/test/src/org/bouncycastle/cert/test/PEMData.java0000644000175000017500000001603311726302771025464 0ustar ebourgebourgpackage org.bouncycastle.cert.test; public class PEMData { public static String CERTIFICATE_1 = "-----BEGIN X509 CERTIFICATE-----\r" + "MIIDXjCCAsegAwIBAgIBBzANBgkqhkiG9w0BAQQFADCBtzELMAkGA1UEBhMCQVUx\r" + "ETAPBgNVBAgTCFZpY3RvcmlhMRgwFgYDVQQHEw9Tb3V0aCBNZWxib3VybmUxGjAY\r" + "BgNVBAoTEUNvbm5lY3QgNCBQdHkgTHRkMR4wHAYDVQQLExVDZXJ0aWZpY2F0ZSBB\r" + "dXRob3JpdHkxFTATBgNVBAMTDENvbm5lY3QgNCBDQTEoMCYGCSqGSIb3DQEJARYZ\r" + "d2VibWFzdGVyQGNvbm5lY3Q0LmNvbS5hdTAeFw0wMDA2MDIwNzU2MjFaFw0wMTA2\r" + "MDIwNzU2MjFaMIG4MQswCQYDVQQGEwJBVTERMA8GA1UECBMIVmljdG9yaWExGDAW\r" + "BgNVBAcTD1NvdXRoIE1lbGJvdXJuZTEaMBgGA1UEChMRQ29ubmVjdCA0IFB0eSBM\r" + "dGQxFzAVBgNVBAsTDldlYnNlcnZlciBUZWFtMR0wGwYDVQQDExR3d3cyLmNvbm5l\r" + "Y3Q0LmNvbS5hdTEoMCYGCSqGSIb3DQEJARYZd2VibWFzdGVyQGNvbm5lY3Q0LmNv\r" + "bS5hdTCBnzANBgkqhkiG9w0BAQEFAAOBjQAwgYkCgYEArvDxclKAhyv7Q/Wmr2re\r" + "Gw4XL9Cnh9e+6VgWy2AWNy/MVeXdlxzd7QAuc1eOWQkGQEiLPy5XQtTY+sBUJ3AO\r" + "Rvd2fEVJIcjf29ey7bYua9J/vz5MG2KYo9/WCHIwqD9mmG9g0xLcfwq/s8ZJBswE\r" + "7sb85VU+h94PTvsWOsWuKaECAwEAAaN3MHUwJAYDVR0RBB0wG4EZd2VibWFzdGVy\r" + "QGNvbm5lY3Q0LmNvbS5hdTA6BglghkgBhvhCAQ0ELRYrbW9kX3NzbCBnZW5lcmF0\r" + "ZWQgY3VzdG9tIHNlcnZlciBjZXJ0aWZpY2F0ZTARBglghkgBhvhCAQEEBAMCBkAw\r" + "DQYJKoZIhvcNAQEEBQADgYEAotccfKpwSsIxM1Hae8DR7M/Rw8dg/RqOWx45HNVL\r" + "iBS4/3N/TO195yeQKbfmzbAA2jbPVvIvGgTxPgO1MP4ZgvgRhasaa0qCJCkWvpM4\r" + "yQf33vOiYQbpv4rTwzU8AmRlBG45WdjyNIigGV+oRc61aKCTnLq7zB8N3z1TF/bF\r" + "5/8=\r" + "-----END X509 CERTIFICATE-----\r"; public static String CERTIFICATE_2 = "-----BEGIN CERTIFICATE-----\n" + "MIIDXjCCAsegAwIBAgIBBzANBgkqhkiG9w0BAQQFADCBtzELMAkGA1UEBhMCQVUx\n" + "ETAPBgNVBAgTCFZpY3RvcmlhMRgwFgYDVQQHEw9Tb3V0aCBNZWxib3VybmUxGjAY\n" + "BgNVBAoTEUNvbm5lY3QgNCBQdHkgTHRkMR4wHAYDVQQLExVDZXJ0aWZpY2F0ZSBB\n" + "dXRob3JpdHkxFTATBgNVBAMTDENvbm5lY3QgNCBDQTEoMCYGCSqGSIb3DQEJARYZ\n" + "d2VibWFzdGVyQGNvbm5lY3Q0LmNvbS5hdTAeFw0wMDA2MDIwNzU2MjFaFw0wMTA2\n" + "MDIwNzU2MjFaMIG4MQswCQYDVQQGEwJBVTERMA8GA1UECBMIVmljdG9yaWExGDAW\n" + "BgNVBAcTD1NvdXRoIE1lbGJvdXJuZTEaMBgGA1UEChMRQ29ubmVjdCA0IFB0eSBM\n" + "dGQxFzAVBgNVBAsTDldlYnNlcnZlciBUZWFtMR0wGwYDVQQDExR3d3cyLmNvbm5l\n" + "Y3Q0LmNvbS5hdTEoMCYGCSqGSIb3DQEJARYZd2VibWFzdGVyQGNvbm5lY3Q0LmNv\n" + "bS5hdTCBnzANBgkqhkiG9w0BAQEFAAOBjQAwgYkCgYEArvDxclKAhyv7Q/Wmr2re\n" + "Gw4XL9Cnh9e+6VgWy2AWNy/MVeXdlxzd7QAuc1eOWQkGQEiLPy5XQtTY+sBUJ3AO\n" + "Rvd2fEVJIcjf29ey7bYua9J/vz5MG2KYo9/WCHIwqD9mmG9g0xLcfwq/s8ZJBswE\n" + "7sb85VU+h94PTvsWOsWuKaECAwEAAaN3MHUwJAYDVR0RBB0wG4EZd2VibWFzdGVy\n" + "QGNvbm5lY3Q0LmNvbS5hdTA6BglghkgBhvhCAQ0ELRYrbW9kX3NzbCBnZW5lcmF0\n" + "ZWQgY3VzdG9tIHNlcnZlciBjZXJ0aWZpY2F0ZTARBglghkgBhvhCAQEEBAMCBkAw\n" + "DQYJKoZIhvcNAQEEBQADgYEAotccfKpwSsIxM1Hae8DR7M/Rw8dg/RqOWx45HNVL\n" + "iBS4/3N/TO195yeQKbfmzbAA2jbPVvIvGgTxPgO1MP4ZgvgRhasaa0qCJCkWvpM4\n" + "yQf33vOiYQbpv4rTwzU8AmRlBG45WdjyNIigGV+oRc61aKCTnLq7zB8N3z1TF/bF\n" + "5/8=\n" + "-----END CERTIFICATE-----\n"; public static String CRL_1 = "-----BEGIN X509 CRL-----\r\n" + "MIICjTCCAfowDQYJKoZIhvcNAQECBQAwXzELMAkGA1UEBhMCVVMxIDAeBgNVBAoT\r\n" + "F1JTQSBEYXRhIFNlY3VyaXR5LCBJbmMuMS4wLAYDVQQLEyVTZWN1cmUgU2VydmVy\r\n" + "IENlcnRpZmljYXRpb24gQXV0aG9yaXR5Fw05NTA1MDIwMjEyMjZaFw05NTA2MDEw\r\n" + "MDAxNDlaMIIBaDAWAgUCQQAABBcNOTUwMjAxMTcyNDI2WjAWAgUCQQAACRcNOTUw\r\n" + "MjEwMDIxNjM5WjAWAgUCQQAADxcNOTUwMjI0MDAxMjQ5WjAWAgUCQQAADBcNOTUw\r\n" + "MjI1MDA0NjQ0WjAWAgUCQQAAGxcNOTUwMzEzMTg0MDQ5WjAWAgUCQQAAFhcNOTUw\r\n" + "MzE1MTkxNjU0WjAWAgUCQQAAGhcNOTUwMzE1MTk0MDQxWjAWAgUCQQAAHxcNOTUw\r\n" + "MzI0MTk0NDMzWjAWAgUCcgAABRcNOTUwMzI5MjAwNzExWjAWAgUCcgAAERcNOTUw\r\n" + "MzMwMDIzNDI2WjAWAgUCQQAAIBcNOTUwNDA3MDExMzIxWjAWAgUCcgAAHhcNOTUw\r\n" + "NDA4MDAwMjU5WjAWAgUCcgAAQRcNOTUwNDI4MTcxNzI0WjAWAgUCcgAAOBcNOTUw\r\n" + "NDI4MTcyNzIxWjAWAgUCcgAATBcNOTUwNTAyMDIxMjI2WjANBgkqhkiG9w0BAQIF\r\n" + "AAN+AHqOEJXSDejYy0UwxxrH/9+N2z5xu/if0J6qQmK92W0hW158wpJg+ovV3+wQ\r\n" + "wvIEPRL2rocL0tKfAsVq1IawSJzSNgxG0lrcla3MrJBnZ4GaZDu4FutZh72MR3Gt\r\n" + "JaAL3iTJHJD55kK2D/VoyY1djlsPuNh6AEgdVwFAyp0v\r\n" + "-----END X509 CRL-----\r\n"; public static String CRL_2 = "-----BEGIN CRL-----\r\n" + "MIICjTCCAfowDQYJKoZIhvcNAQECBQAwXzELMAkGA1UEBhMCVVMxIDAeBgNVBAoT\r\n" + "F1JTQSBEYXRhIFNlY3VyaXR5LCBJbmMuMS4wLAYDVQQLEyVTZWN1cmUgU2VydmVy\r\n" + "IENlcnRpZmljYXRpb24gQXV0aG9yaXR5Fw05NTA1MDIwMjEyMjZaFw05NTA2MDEw\r\n" + "MDAxNDlaMIIBaDAWAgUCQQAABBcNOTUwMjAxMTcyNDI2WjAWAgUCQQAACRcNOTUw\r\n" + "MjEwMDIxNjM5WjAWAgUCQQAADxcNOTUwMjI0MDAxMjQ5WjAWAgUCQQAADBcNOTUw\r\n" + "MjI1MDA0NjQ0WjAWAgUCQQAAGxcNOTUwMzEzMTg0MDQ5WjAWAgUCQQAAFhcNOTUw\r\n" + "MzE1MTkxNjU0WjAWAgUCQQAAGhcNOTUwMzE1MTk0MDQxWjAWAgUCQQAAHxcNOTUw\r\n" + "MzI0MTk0NDMzWjAWAgUCcgAABRcNOTUwMzI5MjAwNzExWjAWAgUCcgAAERcNOTUw\r\n" + "MzMwMDIzNDI2WjAWAgUCQQAAIBcNOTUwNDA3MDExMzIxWjAWAgUCcgAAHhcNOTUw\r\n" + "NDA4MDAwMjU5WjAWAgUCcgAAQRcNOTUwNDI4MTcxNzI0WjAWAgUCcgAAOBcNOTUw\r\n" + "NDI4MTcyNzIxWjAWAgUCcgAATBcNOTUwNTAyMDIxMjI2WjANBgkqhkiG9w0BAQIF\r\n" + "AAN+AHqOEJXSDejYy0UwxxrH/9+N2z5xu/if0J6qQmK92W0hW158wpJg+ovV3+wQ\r\n" + "wvIEPRL2rocL0tKfAsVq1IawSJzSNgxG0lrcla3MrJBnZ4GaZDu4FutZh72MR3Gt\r\n" + "JaAL3iTJHJD55kK2D/VoyY1djlsPuNh6AEgdVwFAyp0v\r\n" + "-----END CRL-----\r\n"; static String ATTRIBUTE_CERTIFICATE_1 = "-----BEGIN X509 ATTRIBUTE CERTIFICATE-----\r\n" + "MIIBuDCCASECAQEwZ6BlMGCkXjBcMQswCQYDVQQGEwJBVTEoMCYGA1UEChMfVGhl\r\n" + "IExlZ2lvbiBvZiB0aGUgQm91bmN5IENhc3RsZTEjMCEGA1UECxMaQm91bmN5IFBy\r\n" + "aW1hcnkgQ2VydGlmaWNhdGUCARSgYjBgpF4wXDELMAkGA1UEBhMCQVUxKDAmBgNV\r\n" + "BAoTH1RoZSBMZWdpb24gb2YgdGhlIEJvdW5jeSBDYXN0bGUxIzAhBgNVBAsTGkJv\r\n" + "dW5jeSBQcmltYXJ5IENlcnRpZmljYXRlMA0GCSqGSIb3DQEBBQUAAgEBMCIYDzIw\r\n" + "MDUwNjEwMDI0MTMzWhgPMjAwNTA2MTAwMjQzMTNaMBkwFwYDVRhIMRAwDoEMREFV\r\n" + "MTIzNDU2Nzg5MA0GCSqGSIb3DQEBBQUAA4GBALAYXT9zdxSR5zdPLAon1xIPehgI\r\n" + "NZhjM7w0uu3OdzSV5sC31X1Kx9vi5RIWiM9VimRTwbQIod9POttD5QMXCwQb/fm7\r\n" + "eiJqL2YBIXOeClB19VrQe8xQtMFbyuFpDiM7QdvIam9ShZZMEMGjv9QHI64M4b0G\r\n" + "odUBlSsJwPPQjZSU\r\n" + "-----END X509 ATTRIBUTE CERTIFICATE-----\r\n"; static String ATTRIBUTE_CERTIFICATE_2 = "-----BEGIN ATTRIBUTE CERTIFICATE-----\r\n" + "MIIBuDCCASECAQEwZ6BlMGCkXjBcMQswCQYDVQQGEwJBVTEoMCYGA1UEChMfVGhl\r\n" + "IExlZ2lvbiBvZiB0aGUgQm91bmN5IENhc3RsZTEjMCEGA1UECxMaQm91bmN5IFBy\r\n" + "aW1hcnkgQ2VydGlmaWNhdGUCARSgYjBgpF4wXDELMAkGA1UEBhMCQVUxKDAmBgNV\r\n" + "BAoTH1RoZSBMZWdpb24gb2YgdGhlIEJvdW5jeSBDYXN0bGUxIzAhBgNVBAsTGkJv\r\n" + "dW5jeSBQcmltYXJ5IENlcnRpZmljYXRlMA0GCSqGSIb3DQEBBQUAAgEBMCIYDzIw\r\n" + "MDUwNjEwMDI0MTMzWhgPMjAwNTA2MTAwMjQzMTNaMBkwFwYDVRhIMRAwDoEMREFV\r\n" + "MTIzNDU2Nzg5MA0GCSqGSIb3DQEBBQUAA4GBALAYXT9zdxSR5zdPLAon1xIPehgI\r\n" + "NZhjM7w0uu3OdzSV5sC31X1Kx9vi5RIWiM9VimRTwbQIod9POttD5QMXCwQb/fm7\r\n" + "eiJqL2YBIXOeClB19VrQe8xQtMFbyuFpDiM7QdvIam9ShZZMEMGjv9QHI64M4b0G\r\n" + "odUBlSsJwPPQjZSU\r\n" + "-----END ATTRIBUTE CERTIFICATE-----\r\n"; } bouncycastle-1.49.orig/test/src/org/bouncycastle/cert/test/BcPKCS10Test.java0000644000175000017500000002515411737303571026264 0ustar ebourgebourgpackage org.bouncycastle.cert.test; import java.math.BigInteger; import java.security.SecureRandom; import junit.framework.TestCase; import org.bouncycastle.asn1.pkcs.Attribute; import org.bouncycastle.asn1.pkcs.PKCSObjectIdentifiers; import org.bouncycastle.asn1.x500.X500Name; import org.bouncycastle.asn1.x500.X500NameBuilder; import org.bouncycastle.asn1.x500.style.RFC4519Style; import org.bouncycastle.asn1.x509.AlgorithmIdentifier; import org.bouncycastle.asn1.x509.BasicConstraints; import org.bouncycastle.asn1.x509.Extension; import org.bouncycastle.asn1.x509.ExtensionsGenerator; import org.bouncycastle.asn1.x509.KeyUsage; import org.bouncycastle.asn1.x509.SubjectKeyIdentifier; import org.bouncycastle.cert.bc.BcX509ExtensionUtils; import org.bouncycastle.crypto.AsymmetricCipherKeyPair; import org.bouncycastle.crypto.AsymmetricCipherKeyPairGenerator; import org.bouncycastle.crypto.generators.RSAKeyPairGenerator; import org.bouncycastle.crypto.params.AsymmetricKeyParameter; import org.bouncycastle.crypto.params.RSAKeyGenerationParameters; import org.bouncycastle.crypto.params.RSAKeyParameters; import org.bouncycastle.crypto.params.RSAPrivateCrtKeyParameters; import org.bouncycastle.operator.DefaultDigestAlgorithmIdentifierFinder; import org.bouncycastle.operator.DefaultSignatureAlgorithmIdentifierFinder; import org.bouncycastle.operator.bc.BcContentSignerBuilder; import org.bouncycastle.operator.bc.BcRSAContentSignerBuilder; import org.bouncycastle.operator.bc.BcRSAContentVerifierProviderBuilder; import org.bouncycastle.pkcs.PKCS10CertificationRequest; import org.bouncycastle.pkcs.PKCS10CertificationRequestBuilder; import org.bouncycastle.pkcs.bc.BcPKCS10CertificationRequest; import org.bouncycastle.pkcs.bc.BcPKCS10CertificationRequestBuilder; import org.bouncycastle.util.Arrays; public class BcPKCS10Test extends TestCase { public String getName() { return "PKCS10CertRequest"; } private void generationTest(int keySize, String keyName, String sigName) throws Exception { AsymmetricCipherKeyPairGenerator kpg = new RSAKeyPairGenerator(); RSAKeyGenerationParameters genParam = new RSAKeyGenerationParameters( BigInteger.valueOf(0x1001), new SecureRandom(), keySize, 25); kpg.init(genParam); AsymmetricCipherKeyPair kp = kpg.generateKeyPair(); X500NameBuilder x500NameBld = new X500NameBuilder(RFC4519Style.INSTANCE); x500NameBld.addRDN(RFC4519Style.c, "AU"); x500NameBld.addRDN(RFC4519Style.o, "The Legion of the Bouncy Castle"); x500NameBld.addRDN(RFC4519Style.l, "Melbourne"); x500NameBld.addRDN(RFC4519Style.st, "Victoria"); x500NameBld.addRDN(PKCSObjectIdentifiers.pkcs_9_at_emailAddress, "feedback-crypto@bouncycastle.org"); X500Name subject = x500NameBld.build(); PKCS10CertificationRequestBuilder requestBuilder = new BcPKCS10CertificationRequestBuilder(subject, kp.getPublic()); DefaultSignatureAlgorithmIdentifierFinder sigAlgFinder = new DefaultSignatureAlgorithmIdentifierFinder(); DefaultDigestAlgorithmIdentifierFinder digAlgFinder = new DefaultDigestAlgorithmIdentifierFinder(); AlgorithmIdentifier sigAlgId = sigAlgFinder.find("SHA1withRSA"); AlgorithmIdentifier digAlgId = digAlgFinder.find(sigAlgId); BcContentSignerBuilder contentSignerBuilder = new BcRSAContentSignerBuilder(sigAlgId, digAlgId); PKCS10CertificationRequest req1 = requestBuilder.build(contentSignerBuilder.build(kp.getPrivate())); BcPKCS10CertificationRequest req2 = new BcPKCS10CertificationRequest(req1.getEncoded()); if (!req2.isSignatureValid(new BcRSAContentVerifierProviderBuilder(digAlgFinder).build(kp.getPublic()))) { fail(sigName + ": Failed verify check."); } if (!Arrays.areEqual(req2.getSubjectPublicKeyInfo().getEncoded(), req1.getSubjectPublicKeyInfo().getEncoded())) { fail(keyName + ": Failed public key check."); } } private void createPSSTest(String algorithm) throws Exception { AsymmetricKeyParameter pubKey = new RSAKeyParameters( false, new BigInteger("a56e4a0e701017589a5187dc7ea841d156f2ec0e36ad52a44dfeb1e61f7ad991d8c51056ffedb162b4c0f283a12a88a394dff526ab7291cbb307ceabfce0b1dfd5cd9508096d5b2b8b6df5d671ef6377c0921cb23c270a70e2598e6ff89d19f105acc2d3f0cb35f29280e1386b6f64c4ef22e1e1f20d0ce8cffb2249bd9a2137",16), new BigInteger("010001",16)); AsymmetricKeyParameter privKey = new RSAPrivateCrtKeyParameters( new BigInteger("a56e4a0e701017589a5187dc7ea841d156f2ec0e36ad52a44dfeb1e61f7ad991d8c51056ffedb162b4c0f283a12a88a394dff526ab7291cbb307ceabfce0b1dfd5cd9508096d5b2b8b6df5d671ef6377c0921cb23c270a70e2598e6ff89d19f105acc2d3f0cb35f29280e1386b6f64c4ef22e1e1f20d0ce8cffb2249bd9a2137",16), new BigInteger("010001",16), new BigInteger("33a5042a90b27d4f5451ca9bbbd0b44771a101af884340aef9885f2a4bbe92e894a724ac3c568c8f97853ad07c0266c8c6a3ca0929f1e8f11231884429fc4d9ae55fee896a10ce707c3ed7e734e44727a39574501a532683109c2abacaba283c31b4bd2f53c3ee37e352cee34f9e503bd80c0622ad79c6dcee883547c6a3b325",16), new BigInteger("e7e8942720a877517273a356053ea2a1bc0c94aa72d55c6e86296b2dfc967948c0a72cbccca7eacb35706e09a1df55a1535bd9b3cc34160b3b6dcd3eda8e6443",16), new BigInteger("b69dca1cf7d4d7ec81e75b90fcca874abcde123fd2700180aa90479b6e48de8d67ed24f9f19d85ba275874f542cd20dc723e6963364a1f9425452b269a6799fd",16), new BigInteger("28fa13938655be1f8a159cbaca5a72ea190c30089e19cd274a556f36c4f6e19f554b34c077790427bbdd8dd3ede2448328f385d81b30e8e43b2fffa027861979",16), new BigInteger("1a8b38f398fa712049898d7fb79ee0a77668791299cdfa09efc0e507acb21ed74301ef5bfd48be455eaeb6e1678255827580a8e4e8e14151d1510a82a3f2e729",16), new BigInteger("27156aba4126d24a81f3a528cbfb27f56886f840a9f6e86e17a44b94fe9319584b8e22fdde1e5a2e3bd8aa5ba8d8584194eb2190acf832b847f13a3d24a79f4d",16)); DefaultSignatureAlgorithmIdentifierFinder sigAlgFinder = new DefaultSignatureAlgorithmIdentifierFinder(); DefaultDigestAlgorithmIdentifierFinder digAlgFinder = new DefaultDigestAlgorithmIdentifierFinder(); AlgorithmIdentifier sigAlgId = sigAlgFinder.find(algorithm); AlgorithmIdentifier digAlgId = digAlgFinder.find(sigAlgId); BcContentSignerBuilder contentSignerBuilder = new BcRSAContentSignerBuilder(sigAlgId, digAlgId); PKCS10CertificationRequest req = new BcPKCS10CertificationRequestBuilder(new X500Name("CN=XXX"), pubKey).build(contentSignerBuilder.build(privKey)); if (!req.isSignatureValid(new BcRSAContentVerifierProviderBuilder(digAlgFinder).build(pubKey))) { fail("Failed verify check PSS."); } BcPKCS10CertificationRequest bcReq = new BcPKCS10CertificationRequest(req.getEncoded()); if (!bcReq.isSignatureValid(new BcRSAContentVerifierProviderBuilder(digAlgFinder).build(bcReq.getPublicKey()))) { fail("Failed verify check PSS encoded."); } if (!bcReq.getSignatureAlgorithm().getAlgorithm().equals(PKCSObjectIdentifiers.id_RSASSA_PSS)) { fail("PSS oid incorrect."); } if (bcReq.getSignatureAlgorithm().getParameters() == null) { fail("PSS parameters incorrect."); } } // previous code found to cause a NullPointerException private void nullPointerTest() throws Exception { AsymmetricCipherKeyPairGenerator kpg = new RSAKeyPairGenerator(); RSAKeyGenerationParameters genParam = new RSAKeyGenerationParameters( BigInteger.valueOf(0x1001), new SecureRandom(), 1024, 25); kpg.init(genParam); AsymmetricCipherKeyPair kp = kpg.generateKeyPair(); ExtensionsGenerator extGen = new ExtensionsGenerator(); extGen.addExtension(Extension.basicConstraints, true, new BasicConstraints(true)); extGen.addExtension(Extension.keyUsage, true, new KeyUsage(KeyUsage.keyCertSign | KeyUsage.cRLSign)); BcX509ExtensionUtils extUtils = new BcX509ExtensionUtils(new SHA1DigestCalculator()); SubjectKeyIdentifier subjectKeyIdentifier = extUtils.createSubjectKeyIdentifier(kp.getPublic()); extGen.addExtension(Extension.subjectKeyIdentifier, false, subjectKeyIdentifier); DefaultSignatureAlgorithmIdentifierFinder sigAlgFinder = new DefaultSignatureAlgorithmIdentifierFinder(); DefaultDigestAlgorithmIdentifierFinder digAlgFinder = new DefaultDigestAlgorithmIdentifierFinder(); AlgorithmIdentifier sigAlgId = sigAlgFinder.find("SHA1withRSA"); AlgorithmIdentifier digAlgId = digAlgFinder.find(sigAlgId); BcContentSignerBuilder contentSignerBuilder = new BcRSAContentSignerBuilder(sigAlgId, digAlgId); PKCS10CertificationRequest p1 = new BcPKCS10CertificationRequestBuilder( new X500Name("cn=csr"), kp.getPublic()) .addAttribute(PKCSObjectIdentifiers.pkcs_9_at_extensionRequest, extGen.generate()) .build(contentSignerBuilder.build(kp.getPrivate())); PKCS10CertificationRequest p2 = new BcPKCS10CertificationRequestBuilder( new X500Name("cn=csr"), kp.getPublic()) .addAttribute(PKCSObjectIdentifiers.pkcs_9_at_extensionRequest, extGen.generate()) .build(contentSignerBuilder.build(kp.getPrivate())); if (!p1.equals(p2)) { fail("cert request comparison failed"); } Attribute[] attr1 = p1.getAttributes(); Attribute[] attr2 = p1.getAttributes(); checkAttrs(1, attr1, attr2); attr1 = p1.getAttributes(PKCSObjectIdentifiers.pkcs_9_at_extensionRequest); attr2 = p1.getAttributes(PKCSObjectIdentifiers.pkcs_9_at_extensionRequest); checkAttrs(1, attr1, attr2); } private void checkAttrs(int expectedLength, Attribute[] attr1, Attribute[] attr2) { if (expectedLength != attr1.length) { fail("expected length mismatch"); } if (attr1.length != attr2.length) { fail("atrribute length mismatch"); } for (int i = 0; i != attr1.length; i++) { if (!attr1[i].equals(attr2[i])) { fail("atrribute mismatch"); } } } public void testPKCS10() throws Exception { generationTest(512, "RSA", "SHA1withRSA"); createPSSTest("SHA1withRSAandMGF1"); createPSSTest("SHA224withRSAandMGF1"); createPSSTest("SHA256withRSAandMGF1"); createPSSTest("SHA384withRSAandMGF1"); nullPointerTest(); } } bouncycastle-1.49.orig/test/src/org/bouncycastle/cert/test/SHA1DigestCalculator.java0000644000175000017500000000177011725015601030111 0ustar ebourgebourgpackage org.bouncycastle.cert.test; import java.io.ByteArrayOutputStream; import java.io.OutputStream; import org.bouncycastle.asn1.oiw.OIWObjectIdentifiers; import org.bouncycastle.asn1.x509.AlgorithmIdentifier; import org.bouncycastle.crypto.Digest; import org.bouncycastle.crypto.digests.SHA1Digest; import org.bouncycastle.operator.DigestCalculator; class SHA1DigestCalculator implements DigestCalculator { private ByteArrayOutputStream bOut = new ByteArrayOutputStream(); public AlgorithmIdentifier getAlgorithmIdentifier() { return new AlgorithmIdentifier(OIWObjectIdentifiers.idSHA1); } public OutputStream getOutputStream() { return bOut; } public byte[] getDigest() { byte[] bytes = bOut.toByteArray(); bOut.reset(); Digest sha1 = new SHA1Digest(); sha1.update(bytes, 0, bytes.length); byte[] digest = new byte[sha1.getDigestSize()]; sha1.doFinal(digest, 0); return digest; } } bouncycastle-1.49.orig/test/src/org/bouncycastle/cert/test/CertTest.java0000644000175000017500000044426312132446724026017 0ustar ebourgebourgpackage org.bouncycastle.cert.test; import java.io.ByteArrayInputStream; import java.io.IOException; import java.io.UnsupportedEncodingException; import java.math.BigInteger; import java.security.KeyFactory; import java.security.KeyPair; import java.security.KeyPairGenerator; import java.security.KeyStore; import java.security.NoSuchAlgorithmException; import java.security.NoSuchProviderException; import java.security.PrivateKey; import java.security.PublicKey; import java.security.SecureRandom; import java.security.Security; import java.security.Signature; import java.security.cert.CRL; import java.security.cert.Certificate; import java.security.cert.CertificateException; import java.security.cert.CertificateFactory; import java.security.cert.X509CRL; import java.security.cert.X509CRLEntry; import java.security.cert.X509Certificate; import java.security.spec.InvalidKeySpecException; import java.security.spec.RSAPrivateCrtKeySpec; import java.security.spec.RSAPublicKeySpec; import java.util.Collection; import java.util.Date; import java.util.Iterator; import java.util.List; import java.util.Set; import java.util.Vector; import javax.security.auth.x500.X500Principal; import org.bouncycastle.asn1.ASN1Encodable; import org.bouncycastle.asn1.ASN1EncodableVector; import org.bouncycastle.asn1.ASN1Enumerated; import org.bouncycastle.asn1.ASN1ObjectIdentifier; import org.bouncycastle.asn1.ASN1Primitive; import org.bouncycastle.asn1.DEREnumerated; import org.bouncycastle.asn1.DERNull; import org.bouncycastle.asn1.DERObjectIdentifier; import org.bouncycastle.asn1.DEROctetString; import org.bouncycastle.asn1.DERSequence; import org.bouncycastle.asn1.pkcs.PKCSObjectIdentifiers; import org.bouncycastle.asn1.pkcs.RSAPublicKey; import org.bouncycastle.asn1.x500.X500Name; import org.bouncycastle.asn1.x500.X500NameBuilder; import org.bouncycastle.asn1.x500.style.BCStyle; import org.bouncycastle.asn1.x509.AlgorithmIdentifier; import org.bouncycastle.asn1.x509.AuthorityKeyIdentifier; import org.bouncycastle.asn1.x509.CRLReason; import org.bouncycastle.asn1.x509.Extension; import org.bouncycastle.asn1.x509.ExtensionsGenerator; import org.bouncycastle.asn1.x509.GeneralName; import org.bouncycastle.asn1.x509.GeneralNames; import org.bouncycastle.asn1.x509.IssuingDistributionPoint; import org.bouncycastle.asn1.x509.KeyPurposeId; import org.bouncycastle.asn1.x509.SubjectPublicKeyInfo; import org.bouncycastle.asn1.x509.X509CertificateStructure; import org.bouncycastle.asn1.x509.X509Extension; import org.bouncycastle.asn1.x509.X509Extensions; import org.bouncycastle.asn1.x9.X9ObjectIdentifiers; import org.bouncycastle.cert.X509CRLEntryHolder; import org.bouncycastle.cert.X509CRLHolder; import org.bouncycastle.cert.X509CertificateHolder; import org.bouncycastle.cert.X509v1CertificateBuilder; import org.bouncycastle.cert.X509v2CRLBuilder; import org.bouncycastle.cert.X509v3CertificateBuilder; import org.bouncycastle.cert.jcajce.JcaX509CRLConverter; import org.bouncycastle.cert.jcajce.JcaX509CRLHolder; import org.bouncycastle.cert.jcajce.JcaX509CertificateConverter; import org.bouncycastle.cert.jcajce.JcaX509CertificateHolder; import org.bouncycastle.cert.jcajce.JcaX509v1CertificateBuilder; import org.bouncycastle.cert.jcajce.JcaX509v2CRLBuilder; import org.bouncycastle.cert.jcajce.JcaX509v3CertificateBuilder; import org.bouncycastle.crypto.params.RSAKeyParameters; import org.bouncycastle.crypto.params.RSAPrivateCrtKeyParameters; import org.bouncycastle.jce.X509KeyUsage; import org.bouncycastle.jce.X509Principal; import org.bouncycastle.jce.interfaces.ECPointEncoder; import org.bouncycastle.jce.provider.BouncyCastleProvider; import org.bouncycastle.jce.spec.ECParameterSpec; import org.bouncycastle.jce.spec.ECPrivateKeySpec; import org.bouncycastle.jce.spec.ECPublicKeySpec; import org.bouncycastle.jce.spec.GOST3410ParameterSpec; import org.bouncycastle.math.ec.ECCurve; import org.bouncycastle.operator.ContentSigner; import org.bouncycastle.operator.ContentVerifierProvider; import org.bouncycastle.operator.DefaultDigestAlgorithmIdentifierFinder; import org.bouncycastle.operator.DefaultSignatureAlgorithmIdentifierFinder; import org.bouncycastle.operator.bc.BcRSAContentSignerBuilder; import org.bouncycastle.operator.bc.BcRSAContentVerifierProviderBuilder; import org.bouncycastle.operator.jcajce.JcaContentSignerBuilder; import org.bouncycastle.operator.jcajce.JcaContentVerifierProviderBuilder; import org.bouncycastle.util.encoders.Base64; import org.bouncycastle.util.encoders.Hex; import org.bouncycastle.util.test.SimpleTest; import org.bouncycastle.x509.extension.AuthorityKeyIdentifierStructure; import org.bouncycastle.x509.extension.X509ExtensionUtil; public class CertTest extends SimpleTest { private static final String BC = org.bouncycastle.jce.provider.BouncyCastleProvider.PROVIDER_NAME; // test CA byte[] testCAp12 = Base64.decode( "MIACAQMwgAYJKoZIhvcNAQcBoIAkgASCA+gwgDCABgkqhkiG9w0BBwGggCSA" + "BIID6DCCCFIwggL/BgsqhkiG9w0BDAoBAqCCArIwggKuMCgGCiqGSIb3DQEM" + "AQMwGgQUjWJR94N+oDQ1XlXO/kUSwu3UOL0CAgQABIICgFjzMa65mpNKYQRA" + "+avbnOjYZ7JkTA5XY7CBcOVwNySY6/ye5Ms6VYl7mCgqzzdDQhT02Th8wXMr" + "fibaC5E/tJRfdWt1zYr9NTLxLG6iCNPXJGGV6aXznv+UFTnzbzGGIAf0zpYf" + "DOOUMusnBeJO2GVETk6DyjtVqx0sLAJKDZQadpao4K5mr5t4bz7zGoykoKNN" + "TRH1tcrb6FYIPy5cf9vAHbyEB6pBdRjFQMYt50fpQGdQ8az9vvf6fLgQe20x" + "e9PtDeqVU+5xNHeWauyVWIjp5penVkptAMYBr5qqNHfg1WuP2V1BO4SI/VWQ" + "+EBKzlOjbH84KDVPDtOQGtmGYmZElxvfpz+S5rHajfzgIKQDT6Y4PTKPtMuF" + "3OYcrVb7EKhTv1lXEQcNrR2+Apa4r2SZnTBq+1JeAGMNzwsMbAEcolljNiVs" + "Lbvxng/WYTBb7+v8EjhthVdyMIY9KoKLXWMtfadEchRPqHGcEJDJ0BlwaVcn" + "UQrexG/UILyVCaKc8yZOI9plAquDx2bGHi6FI4LdToAllX6gX2GncTeuCSuo" + "o0//DBO3Hj7Pj5sGPZsSqzVQ1kH90/jResUN3vm09WtXKo8TELmmjA1yMqXe" + "1r0mP6uN+yvjF1djC9SjovIh/jOG2RiqRy7bGtPRRchgIJCJlC1UoWygJpD6" + "5dlzKMnQLikJ5BhsCIx2F96rmQXXKd7pIwCH7tiKHefQrszHpYO7QvBhwLsk" + "y1bUnakLrgF3wdgwGGxbmuE9mNRVh3piVLGtVw6pH/9jOjmJ6JPbZ8idOpl5" + "fEXOc81CFHTwv/U4oTfjKej4PTCZr58tYO6DdhA5XoEGNmjv4rgZJH1m6iUx" + "OjATBgkqhkiG9w0BCRQxBh4EAGMAYTAjBgkqhkiG9w0BCRUxFgQUKBwy0CF7" + "51A+BhNFCrsws2AG0nYwggVLBgsqhkiG9w0BDAoBAqCCBPowggT2MCgGCiqG" + "SIb3DQEMAQMwGgQUf9t4IA/TP6OsH4GCiDg1BsRCqTwCAgQABIIEyHjGPJZg" + "zhkF93/jM4WTnQUgWOR3PlTmhUSKjyMCLUBSrICocLVsz316NHPT3lqr0Lu2" + "eKXlE5GRDp/c8RToTzMvEDdwi2PHP8sStrGJa1ruNRpOMnVAj8gnyd5KcyYJ" + "3j+Iv/56hzPFXsZMg8gtbPphRxb3xHEZj/xYXYfUhfdElezrBIID6LcWRZS2" + "MuuVddZToLOIdVWSTDZLscR6BIID6Ok+m+VC82JjvLNK4pZqO7Re9s/KAxV9" + "f3wfJ7C7kmr8ar4Mlp9jYfO11lCcBEL86sM93JypgayWp53NN2nYQjnQDafR" + "NrtlthQuR36ir2DEuSp4ySqsSXX/nD3AVOvrpbN88RUIK8Yx36tRaBOBL8tv" + "9aKDfgpWKK4NHxA7V3QkHCAVqLpUZlIvVqEcvjNpzn6ydDQLGk7x5itNlWdn" + "Kq/LfgMlXrTY/kKC4k7xogFS/FRIR10NP3lU+vAEa5T299QZv7c7n2OSVg6K" + "xEXwjYNhfsLP3PlaCppouc2xsq/zSvymZPWsVztuoMwEfVeTtoSEUU8cqOiw" + "Q1NpGtvrO1R28uRdelAVcrIu0qBAbdB5xb+xMfMhVhk7iuSZsYzKJVjK1CNK" + "4w+zNqfkZQQOdh1Qj1t5u/22HDTSzZKTot4brIywo6lxboFE0IDJwU8y62vF" + "4PEBPJDeXBuzbqurQhMS19J8h9wjw2quPAJ0E8dPR5B/1qPAuWYs1i2z2AtL" + "FwNU2B+u53EpI4kM/+Wh3wPZ7lxlXcooUc3+5tZdBqcN+s1A2JU5fkMu05/J" + "FSMG89+L5cwygPZssQ0uQFMqIpbbJp2IF76DYvVOdMnnWMgmw4n9sTcLb7Tf" + "GZAQEr3OLtXHxTAX6WnQ1rdDMiMGTvx4Kj1JrtENPI8Y7m6bhIfSuwUk4v3j" + "/DlPmCzGKsZHfjUvaqiZ/Kg+V4gdOMiIlhUwrR3jbxrX1xXNJ+RjwQzC0wX8" + "C8kGF4hK/DUil20EVZNmrTgqsBBqKLMKDNM7rGhyadlG1eg55rJL07ROmXfY" + "PbMtgPQBVVGcvM58jsW8NlCF5XUBNVSOfNSePUOOccPMTCt4VqRZobciIn7i" + "G6lGby6sS8KMRxmnviLWNVWqWyxjFhuv3S8zVplFmzJR7oXk8bcGW9QV93yN" + "fceR9ZVQdEITPTqVE3r2sgrzgFYZAJ+tMzDfkL4NcSBnivfCS1APRttG1RHJ" + "6nxjpf1Ya6CGkM17BdAeEtdXqBb/0B9n0hgPA8EIe5hfL+cGRx4aO8HldCMb" + "YQUFIOFmuj4xn83eFSlh2zllSVaVj0epIqtcXWWefVpjZKlOgoivrTy9JSGp" + "fbsDw/xZMPGYHehbtm60alZK/t4yrfyGLkeWq7FjK31WfIgx9KAEQM4G1cPx" + "dX6Jj0YdoWKrJh7GdqoCSdrwtR5NkG8ecuYPm9P+UUFg+nbcqR7zWVv0MulQ" + "X4LQoKN8iOXZYZDmKbgLYdh4BY8bqVELaHFZ3rU33EUoATO+43IQXHq5qyB5" + "xJVvT6AEggPo0DNHyUyRNMHoT3feYuDiQszN/4N5qVLZL6UeBIGGwmAQq7CK" + "2A2P67/7bjze+LZcvXgoBmkKPn9hVembyEPwow6wGVhrGDWiEvdNE/Tp3n6D" + "NqLIOhnWfTnsinWNXIlqxa6V/jE+MBcGCSqGSIb3DQEJFDEKHggAcgBvAG8A" + "dDAjBgkqhkiG9w0BCRUxFgQUioImRvGskdQCWPVdgD2wKGBiE/0AAAAAAAAw" + "gAYJKoZIhvcNAQcGoIAwgAIBADCABgkqhkiG9w0BBwEwKAYKKoZIhvcNAQwB" + "BjAaBBTOsaVE8IK7OpXHzfobYSfBfnKvTwICBACggASCCLirl2JOsxIiKwDT" + "/iW4D7qRq4W2mdXiLuH8RTJzfARcWtfWRrszakA6Fi0WAsslor3EYMgBpNtJ" + "yctpSfAO2ToEWNlzqRNffiy1UvxC7Pxo9coaDBfsD9hi253dxsCS+fkGlywA" + "eSlHJ2JEhDz7Y7CO6i95LzvZTzz7075UZvSP5FcVjNlKyfDMVVN3tPXl5/Ej" + "4l/rakdyg72d/ajx/VaG5S81Oy2sjTdG+j6G7aMgpAx7dkgiNr65f9rLU7M9" + "sm24II3RZzfUcjHHSZUvwtXIJSBnHkYft7GqzCFHnikLapFh9ObMdc4qTQQA" + "H7Upo0WD/rxgdKN0Bdj9BLZHm1Ixca6rBVOecg80t/kFXipwBihMUmPbHlWB" + "UGjX1kDRyfvqlcDDWr7elGenqNX1qTYCGi41ChLC9igaQRP48NI3aqgx0bu4" + "P2G19T+/E7UZrCc8VIlKUEGRNKSqVtC7IlqyoLdPms9TXzrYJkklB0m23VXI" + "PyJ5MmmRFXOAtLXwqnLGNLYcafbS2F4MPOjkclWgEtOHKmJctBRI14eMlpN2" + "gBMTYxVkOG7ehUtMbWnjTvivqRxsYPmRCC+m7wiHQodtm2fgJtfwhpRSmLu1" + "/KHohc6ESh62ACsn8nfBthsbzuDxV0fsCgbUDomjWpGs+nBgZFYGAkE1z2Ao" + "Xd7CvA3PZJ5HFtyJrEu8VAbCtU5ZLjXzbALiJ7BqJdzigqsxeieabsR+GCKz" + "Drwk1RltTIZnP3EeQbD+mGPa2BjchseaaLNMVDngkc91Zdg2j18dfIabG4AS" + "CvfM4DfwPdwD2UT48V8608u5OWc7O2sIcxVWv1IrbEFLSKchTPPnfKmdDji3" + "LEoD6t1VPYfn0Ch/NEANOLdncsOUDzQCWscA3+6pkfH8ZaCxfyUU/SHGYKkW" + "7twRpR9ka3Wr7rjMjmT0c24YNIUx9ZDt7iquCAdyRHHc13JQ+IWaoqo1z3b8" + "tz6AIfm1dWgcMlzEAc80Jg/SdASCA+g2sROpkVxAyhOY/EIp1Fm+PSIPQ5dE" + "r5wV7ne2gr40Zuxs5Mrra9Jm79hrErhe4nepA6/DkcHqVDW5sqDwSgLuwVui" + "I2yjBt4xBShc6jUxKTRN43cMlZa4rKaEF636gBMUZHDD+zTRE5rtHKFggvwc" + "LiitHXI+Fg9mH/h0cQRDYebc02bQikxKagfeUxm0DbEFH172VV+4L69MP6SY" + "eyMyRyBXNvLBKDVI5klORE7ZMJGCf2pi3vQr+tSM3W51QmK3HuL+tcish4QW" + "WOxVimmczo7tT/JPwSWcklTV4uvnAVLEfptl66Bu9I2/Kn3yPWElAoQvHjMD" + "O47+CVcuhgX5OXt0Sy8OX09j733FG4XFImnBneae6FrxNoi3tMRyHaIwBjIo" + "8VvqhWjPIJKytMT2/42TpsuD4Pj64m77sIx0rAjmU7s0kG4YdkgeSi+1R4X7" + "hkEFVJe3fId7/sItU2BMHkQGBDELAP7gJFzqTLDuSoiVNJ6kB6vkC+VQ7nmn" + "0xyzrOTNcrSBGc2dCXEI6eYi8/2K9y7ZS9dOEUi8SHfc4WNT4EJ8Qsvn61EW" + "jM8Ye5av/t3iE8NGtiMbbsIorEweL8y88vEMkgqZ7MpLbb2iiAv8Zm16GWAv" + "GRD7rUJfi/3dcXiskUCOg5rIRcn2ImVehqKAPArLbLAx7NJ6UZmB+99N3DpH" + "Jk81BkWPwQF8UlPdwjQh7qJUHTjEYAQI2wmL2jttToq59g3xbrLVUM/5X2Xy" + "Fy619lDydw0TZiGq8zA39lwT92WpziDeV5/vuj2gpcFs3f0cUSJlPsw7Y0mE" + "D/uPk7Arn/iP1oZboM9my/H3tm3rOP5xYxkXI/kVsNucTMLwd4WWdtKk3DLg" + "Ms1tcEdAUQ/ZJ938OJf1uzSixDhlMVedweIJMw72V9VpWUf+QC+SHOvGpdSz" + "2a7mU340J0rsQp7HnS71XWPjtxVCN0Mva+gnF+VTEnamQFEETrEydaqFYQEh" + "im5qr32YOiQiwdrIXJ+p9bNxAbaDBmBI/1bdDU9ffr+AGrxxgjvYGiUQk0d/" + "SDvxlE+S9EZlTWirRatglklVndYdkzJDte7ZJSgjlXkbTgy++QW/xRQ0Ya3o" + "ouQepoTkJ2b48ELe4KCKKTOfR0fTzd0578hSdpYuOCylYBZeuLIo6JH3VeoV" + "dggXMYHtYPuj+ABN3utwP/5s5LZ553sMkI/0bJq8ytE/+BFh1rTbRksAuT6B" + "d98lpDAXjyM1HcKD78YiXotdSISU+pYkIbyn4UG8SKzV9mCxAed1cgjE1BWW" + "DUB+xwlFMQTFpj8fhhYYMcwUF8tmv22Snemkaq3pjJKPBIIB7/jK7pfLMSSS" + "5ojMvWzu9mTegbl9v2K73XqZ/N4LZ5BqxnMdCBM4cCbA2LMwX8WAVlKper6X" + "zdTxRf4SWuzzlOXIyhWaH1g9Yp3PkaWh/BpPne/DXZmfyrTCPWGlbu1oqdKq" + "CgORN9B0+biTWiqgozvtbnCkK+LXqRYbghsWNlOhpm5NykUl7T2xRswYK8gz" + "5vq/xCY5hq+TvgZOT0Fzx426nbNqyGmdjbCpPf2t4s5o3C48WhNSg3vSSJes" + "RVJ4dV1TfXkytIKk/gzLafJfS+AcLeE48MyCOohhLFHdYC9f+lrk51xEANTc" + "xpn26JO1sO7iha8iccRmMYwi6tgDRVKFp6X5VVHXy8hXzxEbWWFL/GkUIjyD" + "hm0KXaarhP9Iah+/j6CI6eVLIhyMsA5itsYX+bJ0I8KmVkXelbwX7tcwSUAs" + "0Wq8oiV8Mi+DawkhTWE2etz07uMseR71jHEr7KE6WXo+SO995Xyop74fLtje" + "GLZroH91GWF4rDZvTJg9l8319oqF0DJ7bTukl3CJqVS3sVNrRIF33vRsmqWL" + "BaaZ1Q8Bt04L19Ka2HsEYLMfTLPGO7HSb9baHezRCQTnVoABm+8iZEXj3Od9" + "ga9TnxFa5KhXerqUscjdXPauElDwmqGhCgAAAAAAAAAAAAAAAAAAAAAAADA9" + "MCEwCQYFKw4DAhoFAAQUWT4N9h+ObRftdP8+GldXCQRf9JoEFDjO/tjAH7We" + "HLhcYQcQ1R+RucctAgIEAAAA"); // // server.crt // byte[] cert1 = Base64.decode( "MIIDXjCCAsegAwIBAgIBBzANBgkqhkiG9w0BAQQFADCBtzELMAkGA1UEBhMCQVUx" + "ETAPBgNVBAgTCFZpY3RvcmlhMRgwFgYDVQQHEw9Tb3V0aCBNZWxib3VybmUxGjAY" + "BgNVBAoTEUNvbm5lY3QgNCBQdHkgTHRkMR4wHAYDVQQLExVDZXJ0aWZpY2F0ZSBB" + "dXRob3JpdHkxFTATBgNVBAMTDENvbm5lY3QgNCBDQTEoMCYGCSqGSIb3DQEJARYZ" + "d2VibWFzdGVyQGNvbm5lY3Q0LmNvbS5hdTAeFw0wMDA2MDIwNzU2MjFaFw0wMTA2" + "MDIwNzU2MjFaMIG4MQswCQYDVQQGEwJBVTERMA8GA1UECBMIVmljdG9yaWExGDAW" + "BgNVBAcTD1NvdXRoIE1lbGJvdXJuZTEaMBgGA1UEChMRQ29ubmVjdCA0IFB0eSBM" + "dGQxFzAVBgNVBAsTDldlYnNlcnZlciBUZWFtMR0wGwYDVQQDExR3d3cyLmNvbm5l" + "Y3Q0LmNvbS5hdTEoMCYGCSqGSIb3DQEJARYZd2VibWFzdGVyQGNvbm5lY3Q0LmNv" + "bS5hdTCBnzANBgkqhkiG9w0BAQEFAAOBjQAwgYkCgYEArvDxclKAhyv7Q/Wmr2re" + "Gw4XL9Cnh9e+6VgWy2AWNy/MVeXdlxzd7QAuc1eOWQkGQEiLPy5XQtTY+sBUJ3AO" + "Rvd2fEVJIcjf29ey7bYua9J/vz5MG2KYo9/WCHIwqD9mmG9g0xLcfwq/s8ZJBswE" + "7sb85VU+h94PTvsWOsWuKaECAwEAAaN3MHUwJAYDVR0RBB0wG4EZd2VibWFzdGVy" + "QGNvbm5lY3Q0LmNvbS5hdTA6BglghkgBhvhCAQ0ELRYrbW9kX3NzbCBnZW5lcmF0" + "ZWQgY3VzdG9tIHNlcnZlciBjZXJ0aWZpY2F0ZTARBglghkgBhvhCAQEEBAMCBkAw" + "DQYJKoZIhvcNAQEEBQADgYEAotccfKpwSsIxM1Hae8DR7M/Rw8dg/RqOWx45HNVL" + "iBS4/3N/TO195yeQKbfmzbAA2jbPVvIvGgTxPgO1MP4ZgvgRhasaa0qCJCkWvpM4" + "yQf33vOiYQbpv4rTwzU8AmRlBG45WdjyNIigGV+oRc61aKCTnLq7zB8N3z1TF/bF" + "5/8="); // // ca.crt // byte[] cert2 = Base64.decode( "MIIDbDCCAtWgAwIBAgIBADANBgkqhkiG9w0BAQQFADCBtzELMAkGA1UEBhMCQVUx" + "ETAPBgNVBAgTCFZpY3RvcmlhMRgwFgYDVQQHEw9Tb3V0aCBNZWxib3VybmUxGjAY" + "BgNVBAoTEUNvbm5lY3QgNCBQdHkgTHRkMR4wHAYDVQQLExVDZXJ0aWZpY2F0ZSBB" + "dXRob3JpdHkxFTATBgNVBAMTDENvbm5lY3QgNCBDQTEoMCYGCSqGSIb3DQEJARYZ" + "d2VibWFzdGVyQGNvbm5lY3Q0LmNvbS5hdTAeFw0wMDA2MDIwNzU1MzNaFw0wMTA2" + "MDIwNzU1MzNaMIG3MQswCQYDVQQGEwJBVTERMA8GA1UECBMIVmljdG9yaWExGDAW" + "BgNVBAcTD1NvdXRoIE1lbGJvdXJuZTEaMBgGA1UEChMRQ29ubmVjdCA0IFB0eSBM" + "dGQxHjAcBgNVBAsTFUNlcnRpZmljYXRlIEF1dGhvcml0eTEVMBMGA1UEAxMMQ29u" + "bmVjdCA0IENBMSgwJgYJKoZIhvcNAQkBFhl3ZWJtYXN0ZXJAY29ubmVjdDQuY29t" + "LmF1MIGfMA0GCSqGSIb3DQEBAQUAA4GNADCBiQKBgQDgs5ptNG6Qv1ZpCDuUNGmv" + "rhjqMDPd3ri8JzZNRiiFlBA4e6/ReaO1U8ASewDeQMH6i9R6degFdQRLngbuJP0s" + "xcEE+SksEWNvygfzLwV9J/q+TQDyJYK52utb++lS0b48A1KPLwEsyL6kOAgelbur" + "ukwxowprKUIV7Knf1ajetQIDAQABo4GFMIGCMCQGA1UdEQQdMBuBGXdlYm1hc3Rl" + "ckBjb25uZWN0NC5jb20uYXUwDwYDVR0TBAgwBgEB/wIBADA2BglghkgBhvhCAQ0E" + "KRYnbW9kX3NzbCBnZW5lcmF0ZWQgY3VzdG9tIENBIGNlcnRpZmljYXRlMBEGCWCG" + "SAGG+EIBAQQEAwICBDANBgkqhkiG9w0BAQQFAAOBgQCsGvfdghH8pPhlwm1r3pQk" + "msnLAVIBb01EhbXm2861iXZfWqGQjrGAaA0ZpXNk9oo110yxoqEoSJSzniZa7Xtz" + "soTwNUpE0SLHvWf/SlKdFWlzXA+vOZbzEv4UmjeelekTm7lc01EEa5QRVzOxHFtQ" + "DhkaJ8VqOMajkQFma2r9iA=="); // // testx509.pem // byte[] cert3 = Base64.decode( "MIIBWzCCAQYCARgwDQYJKoZIhvcNAQEEBQAwODELMAkGA1UEBhMCQVUxDDAKBgNV" + "BAgTA1FMRDEbMBkGA1UEAxMSU1NMZWF5L3JzYSB0ZXN0IENBMB4XDTk1MDYxOTIz" + "MzMxMloXDTk1MDcxNzIzMzMxMlowOjELMAkGA1UEBhMCQVUxDDAKBgNVBAgTA1FM" + "RDEdMBsGA1UEAxMUU1NMZWF5L3JzYSB0ZXN0IGNlcnQwXDANBgkqhkiG9w0BAQEF" + "AANLADBIAkEAqtt6qS5GTxVxGZYWa0/4u+IwHf7p2LNZbcPBp9/OfIcYAXBQn8hO" + "/Re1uwLKXdCjIoaGs4DLdG88rkzfyK5dPQIDAQABMAwGCCqGSIb3DQIFBQADQQAE" + "Wc7EcF8po2/ZO6kNCwK/ICH6DobgLekA5lSLr5EvuioZniZp5lFzAw4+YzPQ7XKJ" + "zl9HYIMxATFyqSiD9jsx"); // // v3-cert1.pem // byte[] cert4 = Base64.decode( "MIICjTCCAfigAwIBAgIEMaYgRzALBgkqhkiG9w0BAQQwRTELMAkGA1UEBhMCVVMx" + "NjA0BgNVBAoTLU5hdGlvbmFsIEFlcm9uYXV0aWNzIGFuZCBTcGFjZSBBZG1pbmlz" + "dHJhdGlvbjAmFxE5NjA1MjgxMzQ5MDUrMDgwMBcROTgwNTI4MTM0OTA1KzA4MDAw" + "ZzELMAkGA1UEBhMCVVMxNjA0BgNVBAoTLU5hdGlvbmFsIEFlcm9uYXV0aWNzIGFu" + "ZCBTcGFjZSBBZG1pbmlzdHJhdGlvbjEgMAkGA1UEBRMCMTYwEwYDVQQDEwxTdGV2" + "ZSBTY2hvY2gwWDALBgkqhkiG9w0BAQEDSQAwRgJBALrAwyYdgxmzNP/ts0Uyf6Bp" + "miJYktU/w4NG67ULaN4B5CnEz7k57s9o3YY3LecETgQ5iQHmkwlYDTL2fTgVfw0C" + "AQOjgaswgagwZAYDVR0ZAQH/BFowWDBWMFQxCzAJBgNVBAYTAlVTMTYwNAYDVQQK" + "Ey1OYXRpb25hbCBBZXJvbmF1dGljcyBhbmQgU3BhY2UgQWRtaW5pc3RyYXRpb24x" + "DTALBgNVBAMTBENSTDEwFwYDVR0BAQH/BA0wC4AJODMyOTcwODEwMBgGA1UdAgQR" + "MA8ECTgzMjk3MDgyM4ACBSAwDQYDVR0KBAYwBAMCBkAwCwYJKoZIhvcNAQEEA4GB" + "AH2y1VCEw/A4zaXzSYZJTTUi3uawbbFiS2yxHvgf28+8Js0OHXk1H1w2d6qOHH21" + "X82tZXd/0JtG0g1T9usFFBDvYK8O0ebgz/P5ELJnBL2+atObEuJy1ZZ0pBDWINR3" + "WkDNLCGiTkCKp0F5EWIrVDwh54NNevkCQRZita+z4IBO"); // // v3-cert2.pem // byte[] cert5 = Base64.decode( "MIICiTCCAfKgAwIBAgIEMeZfHzANBgkqhkiG9w0BAQQFADB9MQswCQYDVQQGEwJD" + "YTEPMA0GA1UEBxMGTmVwZWFuMR4wHAYDVQQLExVObyBMaWFiaWxpdHkgQWNjZXB0" + "ZWQxHzAdBgNVBAoTFkZvciBEZW1vIFB1cnBvc2VzIE9ubHkxHDAaBgNVBAMTE0Vu" + "dHJ1c3QgRGVtbyBXZWIgQ0EwHhcNOTYwNzEyMTQyMDE1WhcNOTYxMDEyMTQyMDE1" + "WjB0MSQwIgYJKoZIhvcNAQkBExVjb29rZUBpc3NsLmF0bC5ocC5jb20xCzAJBgNV" + "BAYTAlVTMScwJQYDVQQLEx5IZXdsZXR0IFBhY2thcmQgQ29tcGFueSAoSVNTTCkx" + "FjAUBgNVBAMTDVBhdWwgQS4gQ29va2UwXDANBgkqhkiG9w0BAQEFAANLADBIAkEA" + "6ceSq9a9AU6g+zBwaL/yVmW1/9EE8s5you1mgjHnj0wAILuoB3L6rm6jmFRy7QZT" + "G43IhVZdDua4e+5/n1ZslwIDAQABo2MwYTARBglghkgBhvhCAQEEBAMCB4AwTAYJ" + "YIZIAYb4QgENBD8WPVRoaXMgY2VydGlmaWNhdGUgaXMgb25seSBpbnRlbmRlZCBm" + "b3IgZGVtb25zdHJhdGlvbiBwdXJwb3Nlcy4wDQYJKoZIhvcNAQEEBQADgYEAi8qc" + "F3zfFqy1sV8NhjwLVwOKuSfhR/Z8mbIEUeSTlnH3QbYt3HWZQ+vXI8mvtZoBc2Fz" + "lexKeIkAZXCesqGbs6z6nCt16P6tmdfbZF3I3AWzLquPcOXjPf4HgstkyvVBn0Ap" + "jAFN418KF/Cx4qyHB4cjdvLrRjjQLnb2+ibo7QU="); // // pem encoded pkcs7 // byte[] cert6 = Base64.decode( "MIAGCSqGSIb3DQEHAqCAMIACAQExCzAJBgUrDgMCGgUAMIAGCSqGSIb3DQEHAQAAoIIJbzCCAj0w" + "ggGmAhEAzbp/VvDf5LxU/iKss3KqVTANBgkqhkiG9w0BAQIFADBfMQswCQYDVQQGEwJVUzEXMBUG" + "A1UEChMOVmVyaVNpZ24sIEluYy4xNzA1BgNVBAsTLkNsYXNzIDEgUHVibGljIFByaW1hcnkgQ2Vy" + "dGlmaWNhdGlvbiBBdXRob3JpdHkwHhcNOTYwMTI5MDAwMDAwWhcNMjgwODAxMjM1OTU5WjBfMQsw" + "CQYDVQQGEwJVUzEXMBUGA1UEChMOVmVyaVNpZ24sIEluYy4xNzA1BgNVBAsTLkNsYXNzIDEgUHVi" + "bGljIFByaW1hcnkgQ2VydGlmaWNhdGlvbiBBdXRob3JpdHkwgZ8wDQYJKoZIhvcNAQEBBQADgY0A" + "MIGJAoGBAOUZv22jVmEtmUhx9mfeuY3rt56GgAqRDvo4Ja9GiILlc6igmyRdDR/MZW4MsNBWhBiH" + "mgabEKFz37RYOWtuwfYV1aioP6oSBo0xrH+wNNePNGeICc0UEeJORVZpH3gCgNrcR5EpuzbJY1zF" + "4Ncth3uhtzKwezC6Ki8xqu6jZ9rbAgMBAAEwDQYJKoZIhvcNAQECBQADgYEATD+4i8Zo3+5DMw5d" + "6abLB4RNejP/khv0Nq3YlSI2aBFsfELM85wuxAc/FLAPT/+Qknb54rxK6Y/NoIAK98Up8YIiXbix" + "3YEjo3slFUYweRb46gVLlH8dwhzI47f0EEA8E8NfH1PoSOSGtHuhNbB7Jbq4046rPzidADQAmPPR" + "cZQwggMuMIICl6ADAgECAhEA0nYujRQMPX2yqCVdr+4NdTANBgkqhkiG9w0BAQIFADBfMQswCQYD" + "VQQGEwJVUzEXMBUGA1UEChMOVmVyaVNpZ24sIEluYy4xNzA1BgNVBAsTLkNsYXNzIDEgUHVibGlj" + "IFByaW1hcnkgQ2VydGlmaWNhdGlvbiBBdXRob3JpdHkwHhcNOTgwNTEyMDAwMDAwWhcNMDgwNTEy" + "MjM1OTU5WjCBzDEXMBUGA1UEChMOVmVyaVNpZ24sIEluYy4xHzAdBgNVBAsTFlZlcmlTaWduIFRy" + "dXN0IE5ldHdvcmsxRjBEBgNVBAsTPXd3dy52ZXJpc2lnbi5jb20vcmVwb3NpdG9yeS9SUEEgSW5j" + "b3JwLiBCeSBSZWYuLExJQUIuTFREKGMpOTgxSDBGBgNVBAMTP1ZlcmlTaWduIENsYXNzIDEgQ0Eg" + "SW5kaXZpZHVhbCBTdWJzY3JpYmVyLVBlcnNvbmEgTm90IFZhbGlkYXRlZDCBnzANBgkqhkiG9w0B" + "AQEFAAOBjQAwgYkCgYEAu1pEigQWu1X9A3qKLZRPFXg2uA1Ksm+cVL+86HcqnbnwaLuV2TFBcHqB" + "S7lIE1YtxwjhhEKrwKKSq0RcqkLwgg4C6S/7wju7vsknCl22sDZCM7VuVIhPh0q/Gdr5FegPh7Yc" + "48zGmo5/aiSS4/zgZbqnsX7vyds3ashKyAkG5JkCAwEAAaN8MHowEQYJYIZIAYb4QgEBBAQDAgEG" + "MEcGA1UdIARAMD4wPAYLYIZIAYb4RQEHAQEwLTArBggrBgEFBQcCARYfd3d3LnZlcmlzaWduLmNv" + "bS9yZXBvc2l0b3J5L1JQQTAPBgNVHRMECDAGAQH/AgEAMAsGA1UdDwQEAwIBBjANBgkqhkiG9w0B" + "AQIFAAOBgQCIuDc73dqUNwCtqp/hgQFxHpJqbS/28Z3TymQ43BuYDAeGW4UVag+5SYWklfEXfWe0" + "fy0s3ZpCnsM+tI6q5QsG3vJWKvozx74Z11NMw73I4xe1pElCY+zCphcPXVgaSTyQXFWjZSAA/Rgg" + "5V+CprGoksVYasGNAzzrw80FopCubjCCA/gwggNhoAMCAQICEBbbn/1G1zppD6KsP01bwywwDQYJ" + "KoZIhvcNAQEEBQAwgcwxFzAVBgNVBAoTDlZlcmlTaWduLCBJbmMuMR8wHQYDVQQLExZWZXJpU2ln" + "biBUcnVzdCBOZXR3b3JrMUYwRAYDVQQLEz13d3cudmVyaXNpZ24uY29tL3JlcG9zaXRvcnkvUlBB" + "IEluY29ycC4gQnkgUmVmLixMSUFCLkxURChjKTk4MUgwRgYDVQQDEz9WZXJpU2lnbiBDbGFzcyAx" + "IENBIEluZGl2aWR1YWwgU3Vic2NyaWJlci1QZXJzb25hIE5vdCBWYWxpZGF0ZWQwHhcNMDAxMDAy" + "MDAwMDAwWhcNMDAxMjAxMjM1OTU5WjCCAQcxFzAVBgNVBAoTDlZlcmlTaWduLCBJbmMuMR8wHQYD" + "VQQLExZWZXJpU2lnbiBUcnVzdCBOZXR3b3JrMUYwRAYDVQQLEz13d3cudmVyaXNpZ24uY29tL3Jl" + "cG9zaXRvcnkvUlBBIEluY29ycC4gYnkgUmVmLixMSUFCLkxURChjKTk4MR4wHAYDVQQLExVQZXJz" + "b25hIE5vdCBWYWxpZGF0ZWQxJzAlBgNVBAsTHkRpZ2l0YWwgSUQgQ2xhc3MgMSAtIE1pY3Jvc29m" + "dDETMBEGA1UEAxQKRGF2aWQgUnlhbjElMCMGCSqGSIb3DQEJARYWZGF2aWRAbGl2ZW1lZGlhLmNv" + "bS5hdTCBnzANBgkqhkiG9w0BAQEFAAOBjQAwgYkCgYEAqxBsdeNmSvFqhMNwhQgNzM8mdjX9eSXb" + "DawpHtQHjmh0AKJSa3IwUY0VIsyZHuXWktO/CgaMBVPt6OVf/n0R2sQigMP6Y+PhEiS0vCJBL9aK" + "0+pOo2qXrjVBmq+XuCyPTnc+BOSrU26tJsX0P9BYorwySiEGxGanBNATdVL4NdUCAwEAAaOBnDCB" + "mTAJBgNVHRMEAjAAMEQGA1UdIAQ9MDswOQYLYIZIAYb4RQEHAQgwKjAoBggrBgEFBQcCARYcaHR0" + "cHM6Ly93d3cudmVyaXNpZ24uY29tL3JwYTARBglghkgBhvhCAQEEBAMCB4AwMwYDVR0fBCwwKjAo" + "oCagJIYiaHR0cDovL2NybC52ZXJpc2lnbi5jb20vY2xhc3MxLmNybDANBgkqhkiG9w0BAQQFAAOB" + "gQBC8yIIdVGpFTf8/YiL14cMzcmL0nIRm4kGR3U59z7UtcXlfNXXJ8MyaeI/BnXwG/gD5OKYqW6R" + "yca9vZOxf1uoTBl82gInk865ED3Tej6msCqFzZffnSUQvOIeqLxxDlqYRQ6PmW2nAnZeyjcnbI5Y" + "syQSM2fmo7n6qJFP+GbFezGCAkUwggJBAgEBMIHhMIHMMRcwFQYDVQQKEw5WZXJpU2lnbiwgSW5j" + "LjEfMB0GA1UECxMWVmVyaVNpZ24gVHJ1c3QgTmV0d29yazFGMEQGA1UECxM9d3d3LnZlcmlzaWdu" + "LmNvbS9yZXBvc2l0b3J5L1JQQSBJbmNvcnAuIEJ5IFJlZi4sTElBQi5MVEQoYyk5ODFIMEYGA1UE" + "AxM/VmVyaVNpZ24gQ2xhc3MgMSBDQSBJbmRpdmlkdWFsIFN1YnNjcmliZXItUGVyc29uYSBOb3Qg" + "VmFsaWRhdGVkAhAW25/9Rtc6aQ+irD9NW8MsMAkGBSsOAwIaBQCggbowGAYJKoZIhvcNAQkDMQsG" + "CSqGSIb3DQEHATAcBgkqhkiG9w0BCQUxDxcNMDAxMDAyMTczNTE4WjAjBgkqhkiG9w0BCQQxFgQU" + "gZjSaBEY2oxGvlQUIMnxSXhivK8wWwYJKoZIhvcNAQkPMU4wTDAKBggqhkiG9w0DBzAOBggqhkiG" + "9w0DAgICAIAwDQYIKoZIhvcNAwICAUAwBwYFKw4DAgcwDQYIKoZIhvcNAwICASgwBwYFKw4DAh0w" + "DQYJKoZIhvcNAQEBBQAEgYAzk+PU91/ZFfoiuKOECjxEh9fDYE2jfDCheBIgh5gdcCo+sS1WQs8O" + "HreQ9Nop/JdJv1DQMBK6weNBBDoP0EEkRm1XCC144XhXZC82jBZohYmi2WvDbbC//YN58kRMYMyy" + "srrfn4Z9I+6kTriGXkrpGk9Q0LSGjmG2BIsqiF0dvwAAAAAAAA=="); // // dsaWithSHA1 cert // byte[] cert7 = Base64.decode( "MIIEXAYJKoZIhvcNAQcCoIIETTCCBEkCAQExCzAJBgUrDgMCGgUAMAsGCSqG" + "SIb3DQEHAaCCAsMwggK/MIIB4AIBADCBpwYFKw4DAhswgZ0CQQEkJRHP+mN7" + "d8miwTMN55CUSmo3TO8WGCxgY61TX5k+7NU4XPf1TULjw3GobwaJX13kquPh" + "fVXk+gVy46n4Iw3hAhUBSe/QF4BUj+pJOF9ROBM4u+FEWA8CQQD4mSJbrABj" + "TUWrlnAte8pS22Tq4/FPO7jHSqjijUHfXKTrHL1OEqV3SVWcFy5j/cqBgX/z" + "m8Q12PFp/PjOhh+nMA4xDDAKBgNVBAMTA0lEMzAeFw05NzEwMDEwMDAwMDBa" + "Fw0zODAxMDEwMDAwMDBaMA4xDDAKBgNVBAMTA0lEMzCB8DCBpwYFKw4DAhsw" + "gZ0CQQEkJRHP+mN7d8miwTMN55CUSmo3TO8WGCxgY61TX5k+7NU4XPf1TULj" + "w3GobwaJX13kquPhfVXk+gVy46n4Iw3hAhUBSe/QF4BUj+pJOF9ROBM4u+FE" + "WA8CQQD4mSJbrABjTUWrlnAte8pS22Tq4/FPO7jHSqjijUHfXKTrHL1OEqV3" + "SVWcFy5j/cqBgX/zm8Q12PFp/PjOhh+nA0QAAkEAkYkXLYMtGVGWj9OnzjPn" + "sB9sefSRPrVegZJCZbpW+Iv0/1RP1u04pHG9vtRpIQLjzUiWvLMU9EKQTThc" + "eNMmWDCBpwYFKw4DAhswgZ0CQQEkJRHP+mN7d8miwTMN55CUSmo3TO8WGCxg" + "Y61TX5k+7NU4XPf1TULjw3GobwaJX13kquPhfVXk+gVy46n4Iw3hAhUBSe/Q" + "F4BUj+pJOF9ROBM4u+FEWA8CQQD4mSJbrABjTUWrlnAte8pS22Tq4/FPO7jH" + "SqjijUHfXKTrHL1OEqV3SVWcFy5j/cqBgX/zm8Q12PFp/PjOhh+nAy8AMCwC" + "FBY3dBSdeprGcqpr6wr3xbG+6WW+AhRMm/facKJNxkT3iKgJbp7R8Xd3QTGC" + "AWEwggFdAgEBMBMwDjEMMAoGA1UEAxMDSUQzAgEAMAkGBSsOAwIaBQCgXTAY" + "BgkqhkiG9w0BCQMxCwYJKoZIhvcNAQcBMBwGCSqGSIb3DQEJBTEPFw0wMjA1" + "MjQyMzEzMDdaMCMGCSqGSIb3DQEJBDEWBBS4WMsoJhf7CVbZYCFcjoTRzPkJ" + "xjCBpwYFKw4DAhswgZ0CQQEkJRHP+mN7d8miwTMN55CUSmo3TO8WGCxgY61T" + "X5k+7NU4XPf1TULjw3GobwaJX13kquPhfVXk+gVy46n4Iw3hAhUBSe/QF4BU" + "j+pJOF9ROBM4u+FEWA8CQQD4mSJbrABjTUWrlnAte8pS22Tq4/FPO7jHSqji" + "jUHfXKTrHL1OEqV3SVWcFy5j/cqBgX/zm8Q12PFp/PjOhh+nBC8wLQIVALID" + "dt+MHwawrDrwsO1Z6sXBaaJsAhRaKssrpevmLkbygKPV07XiAKBG02Zvb2Jh" + "cg=="); // // testcrl.pem // byte[] crl1 = Base64.decode( "MIICjTCCAfowDQYJKoZIhvcNAQECBQAwXzELMAkGA1UEBhMCVVMxIDAeBgNVBAoT" + "F1JTQSBEYXRhIFNlY3VyaXR5LCBJbmMuMS4wLAYDVQQLEyVTZWN1cmUgU2VydmVy" + "IENlcnRpZmljYXRpb24gQXV0aG9yaXR5Fw05NTA1MDIwMjEyMjZaFw05NTA2MDEw" + "MDAxNDlaMIIBaDAWAgUCQQAABBcNOTUwMjAxMTcyNDI2WjAWAgUCQQAACRcNOTUw" + "MjEwMDIxNjM5WjAWAgUCQQAADxcNOTUwMjI0MDAxMjQ5WjAWAgUCQQAADBcNOTUw" + "MjI1MDA0NjQ0WjAWAgUCQQAAGxcNOTUwMzEzMTg0MDQ5WjAWAgUCQQAAFhcNOTUw" + "MzE1MTkxNjU0WjAWAgUCQQAAGhcNOTUwMzE1MTk0MDQxWjAWAgUCQQAAHxcNOTUw" + "MzI0MTk0NDMzWjAWAgUCcgAABRcNOTUwMzI5MjAwNzExWjAWAgUCcgAAERcNOTUw" + "MzMwMDIzNDI2WjAWAgUCQQAAIBcNOTUwNDA3MDExMzIxWjAWAgUCcgAAHhcNOTUw" + "NDA4MDAwMjU5WjAWAgUCcgAAQRcNOTUwNDI4MTcxNzI0WjAWAgUCcgAAOBcNOTUw" + "NDI4MTcyNzIxWjAWAgUCcgAATBcNOTUwNTAyMDIxMjI2WjANBgkqhkiG9w0BAQIF" + "AAN+AHqOEJXSDejYy0UwxxrH/9+N2z5xu/if0J6qQmK92W0hW158wpJg+ovV3+wQ" + "wvIEPRL2rocL0tKfAsVq1IawSJzSNgxG0lrcla3MrJBnZ4GaZDu4FutZh72MR3Gt" + "JaAL3iTJHJD55kK2D/VoyY1djlsPuNh6AEgdVwFAyp0v"); // // ecdsa cert with extra octet string. // byte[] oldEcdsa = Base64.decode( "MIICljCCAkCgAwIBAgIBATALBgcqhkjOPQQBBQAwgY8xCzAJBgNVBAYTAkFVMSgwJ" + "gYDVQQKEx9UaGUgTGVnaW9uIG9mIHRoZSBCb3VuY3kgQ2FzdGxlMRIwEAYDVQQHEw" + "lNZWxib3VybmUxETAPBgNVBAgTCFZpY3RvcmlhMS8wLQYJKoZIhvcNAQkBFiBmZWV" + "kYmFjay1jcnlwdG9AYm91bmN5Y2FzdGxlLm9yZzAeFw0wMTEyMDcwMTAwMDRaFw0w" + "MTEyMDcwMTAxNDRaMIGPMQswCQYDVQQGEwJBVTEoMCYGA1UEChMfVGhlIExlZ2lvb" + "iBvZiB0aGUgQm91bmN5IENhc3RsZTESMBAGA1UEBxMJTWVsYm91cm5lMREwDwYDVQ" + "QIEwhWaWN0b3JpYTEvMC0GCSqGSIb3DQEJARYgZmVlZGJhY2stY3J5cHRvQGJvdW5" + "jeWNhc3RsZS5vcmcwgeQwgb0GByqGSM49AgEwgbECAQEwKQYHKoZIzj0BAQIef///" + "////////////f///////gAAAAAAAf///////MEAEHn///////////////3///////" + "4AAAAAAAH///////AQeawFsO9zxiUHQ1lSSFHXKcanbL7J9HTd5YYXClCwKBB8CD/" + "qWPNyogWzMM7hkK+35BcPTWFc9Pyf7vTs8uaqvAh5///////////////9///+eXpq" + "fXZBx+9FSJoiQnQsDIgAEHwJbbcU7xholSP+w9nFHLebJUhqdLSU05lq/y9X+DHAw" + "CwYHKoZIzj0EAQUAA0MAMEACHnz6t4UNoVROp74ma4XNDjjGcjaqiIWPZLK8Bdw3G" + "QIeLZ4j3a6ividZl344UH+UPUE7xJxlYGuy7ejTsqRR"); byte[] uncompressedPtEC = Base64.decode( "MIIDKzCCAsGgAwIBAgICA+kwCwYHKoZIzj0EAQUAMGYxCzAJBgNVBAYTAkpQ" + "MRUwEwYDVQQKEwxuaXRlY2guYWMuanAxDjAMBgNVBAsTBWFpbGFiMQ8wDQYD" + "VQQDEwZ0ZXN0Y2ExHzAdBgkqhkiG9w0BCQEWEHRlc3RjYUBsb2NhbGhvc3Qw" + "HhcNMDExMDEzMTE1MzE3WhcNMjAxMjEyMTE1MzE3WjBmMQswCQYDVQQGEwJK" + "UDEVMBMGA1UEChMMbml0ZWNoLmFjLmpwMQ4wDAYDVQQLEwVhaWxhYjEPMA0G" + "A1UEAxMGdGVzdGNhMR8wHQYJKoZIhvcNAQkBFhB0ZXN0Y2FAbG9jYWxob3N0" + "MIIBczCCARsGByqGSM49AgEwggEOAgEBMDMGByqGSM49AQECKEdYWnajFmnZ" + "tzrukK2XWdle2v+GsD9l1ZiR6g7ozQDbhFH/bBiMDQcwVAQoJ5EQKrI54/CT" + "xOQ2pMsd/fsXD+EX8YREd8bKHWiLz8lIVdD5cBNeVwQoMKSc6HfI7vKZp8Q2" + "zWgIFOarx1GQoWJbMcSt188xsl30ncJuJT2OoARRBAqJ4fD+q6hbqgNSjTQ7" + "htle1KO3eiaZgcJ8rrnyN8P+5A8+5K+H9aQ/NbBR4Gs7yto5PXIUZEUgodHA" + "TZMSAcSq5ZYt4KbnSYaLY0TtH9CqAigEwZ+hglbT21B7ZTzYX2xj0x+qooJD" + "hVTLtIPaYJK2HrMPxTw6/zfrAgEPA1IABAnvfFcFDgD/JicwBGn6vR3N8MIn" + "mptZf/mnJ1y649uCF60zOgdwIyI7pVSxBFsJ7ohqXEHW0x7LrGVkdSEiipiH" + "LYslqh3xrqbAgPbl93GUo0IwQDAPBgNVHRMBAf8EBTADAQH/MA4GA1UdDwEB" + "/wQEAwIBxjAdBgNVHQ4EFgQUAEo62Xm9H6DcsE0zUDTza4BRG90wCwYHKoZI" + "zj0EAQUAA1cAMFQCKAQsCHHSNOqfJXLgt3bg5+k49hIBGVr/bfG0B9JU3rNt" + "Ycl9Y2zfRPUCKAK2ccOQXByAWfsasDu8zKHxkZv7LVDTFjAIffz3HaCQeVhD" + "z+fauEg="); byte[] keyUsage = Base64.decode( "MIIE7TCCBFagAwIBAgIEOAOR7jANBgkqhkiG9w0BAQQFADCByTELMAkGA1UE" + "BhMCVVMxFDASBgNVBAoTC0VudHJ1c3QubmV0MUgwRgYDVQQLFD93d3cuZW50" + "cnVzdC5uZXQvQ2xpZW50X0NBX0luZm8vQ1BTIGluY29ycC4gYnkgcmVmLiBs" + "aW1pdHMgbGlhYi4xJTAjBgNVBAsTHChjKSAxOTk5IEVudHJ1c3QubmV0IExp" + "bWl0ZWQxMzAxBgNVBAMTKkVudHJ1c3QubmV0IENsaWVudCBDZXJ0aWZpY2F0" + "aW9uIEF1dGhvcml0eTAeFw05OTEwMTIxOTI0MzBaFw0xOTEwMTIxOTU0MzBa" + "MIHJMQswCQYDVQQGEwJVUzEUMBIGA1UEChMLRW50cnVzdC5uZXQxSDBGBgNV" + "BAsUP3d3dy5lbnRydXN0Lm5ldC9DbGllbnRfQ0FfSW5mby9DUFMgaW5jb3Jw" + "LiBieSByZWYuIGxpbWl0cyBsaWFiLjElMCMGA1UECxMcKGMpIDE5OTkgRW50" + "cnVzdC5uZXQgTGltaXRlZDEzMDEGA1UEAxMqRW50cnVzdC5uZXQgQ2xpZW50" + "IENlcnRpZmljYXRpb24gQXV0aG9yaXR5MIGdMA0GCSqGSIb3DQEBAQUAA4GL" + "ADCBhwKBgQDIOpleMRffrCdvkHvkGf9FozTC28GoT/Bo6oT9n3V5z8GKUZSv" + "x1cDR2SerYIbWtp/N3hHuzeYEpbOxhN979IMMFGpOZ5V+Pux5zDeg7K6PvHV" + "iTs7hbqqdCz+PzFur5GVbgbUB01LLFZHGARS2g4Qk79jkJvh34zmAqTmT173" + "iwIBA6OCAeAwggHcMBEGCWCGSAGG+EIBAQQEAwIABzCCASIGA1UdHwSCARkw" + "ggEVMIHkoIHhoIHepIHbMIHYMQswCQYDVQQGEwJVUzEUMBIGA1UEChMLRW50" + "cnVzdC5uZXQxSDBGBgNVBAsUP3d3dy5lbnRydXN0Lm5ldC9DbGllbnRfQ0Ff" + "SW5mby9DUFMgaW5jb3JwLiBieSByZWYuIGxpbWl0cyBsaWFiLjElMCMGA1UE" + "CxMcKGMpIDE5OTkgRW50cnVzdC5uZXQgTGltaXRlZDEzMDEGA1UEAxMqRW50" + "cnVzdC5uZXQgQ2xpZW50IENlcnRpZmljYXRpb24gQXV0aG9yaXR5MQ0wCwYD" + "VQQDEwRDUkwxMCygKqAohiZodHRwOi8vd3d3LmVudHJ1c3QubmV0L0NSTC9D" + "bGllbnQxLmNybDArBgNVHRAEJDAigA8xOTk5MTAxMjE5MjQzMFqBDzIwMTkx" + "MDEyMTkyNDMwWjALBgNVHQ8EBAMCAQYwHwYDVR0jBBgwFoAUxPucKXuXzUyW" + "/O5bs8qZdIuV6kwwHQYDVR0OBBYEFMT7nCl7l81MlvzuW7PKmXSLlepMMAwG" + "A1UdEwQFMAMBAf8wGQYJKoZIhvZ9B0EABAwwChsEVjQuMAMCBJAwDQYJKoZI" + "hvcNAQEEBQADgYEAP66K8ddmAwWePvrqHEa7pFuPeJoSSJn59DXeDDYHAmsQ" + "OokUgZwxpnyyQbJq5wcBoUv5nyU7lsqZwz6hURzzwy5E97BnRqqS5TvaHBkU" + "ODDV4qIxJS7x7EU47fgGWANzYrAQMY9Av2TgXD7FTx/aEkP/TOYGJqibGapE" + "PHayXOw="); byte[] nameCert = Base64.decode( "MIIEFjCCA3+gAwIBAgIEdS8BozANBgkqhkiG9w0BAQUFADBKMQswCQYDVQQGEwJE"+ "RTERMA8GA1UEChQIREFURVYgZUcxKDAMBgcCggYBCgcUEwExMBgGA1UEAxQRQ0Eg"+ "REFURVYgRDAzIDE6UE4wIhgPMjAwMTA1MTAxMDIyNDhaGA8yMDA0MDUwOTEwMjI0"+ "OFowgYQxCzAJBgNVBAYTAkRFMQ8wDQYDVQQIFAZCYXllcm4xEjAQBgNVBAcUCU7I"+ "dXJuYmVyZzERMA8GA1UEChQIREFURVYgZUcxHTAbBgNVBAUTFDAwMDAwMDAwMDA4"+ "OTU3NDM2MDAxMR4wHAYDVQQDFBVEaWV0bWFyIFNlbmdlbmxlaXRuZXIwgaEwDQYJ"+ "KoZIhvcNAQEBBQADgY8AMIGLAoGBAJLI/LJLKaHoMk8fBECW/od8u5erZi6jI8Ug"+ "C0a/LZyQUO/R20vWJs6GrClQtXB+AtfiBSnyZOSYzOdfDI8yEKPEv8qSuUPpOHps"+ "uNCFdLZF1vavVYGEEWs2+y+uuPmg8q1oPRyRmUZ+x9HrDvCXJraaDfTEd9olmB/Z"+ "AuC/PqpjAgUAwAAAAaOCAcYwggHCMAwGA1UdEwEB/wQCMAAwDwYDVR0PAQH/BAUD"+ "AwdAADAxBgNVHSAEKjAoMCYGBSskCAEBMB0wGwYIKwYBBQUHAgEWD3d3dy56cy5k"+ "YXRldi5kZTApBgNVHREEIjAggR5kaWV0bWFyLnNlbmdlbmxlaXRuZXJAZGF0ZXYu"+ "ZGUwgYQGA1UdIwR9MHuhc6RxMG8xCzAJBgNVBAYTAkRFMT0wOwYDVQQKFDRSZWd1"+ "bGllcnVuZ3NiZWjIb3JkZSBmyHVyIFRlbGVrb21tdW5pa2F0aW9uIHVuZCBQb3N0"+ "MSEwDAYHAoIGAQoHFBMBMTARBgNVBAMUCjVSLUNBIDE6UE6CBACm8LkwDgYHAoIG"+ "AQoMAAQDAQEAMEcGA1UdHwRAMD4wPKAUoBKGEHd3dy5jcmwuZGF0ZXYuZGWiJKQi"+ "MCAxCzAJBgNVBAYTAkRFMREwDwYDVQQKFAhEQVRFViBlRzAWBgUrJAgDBAQNMAsT"+ "A0VVUgIBBQIBATAdBgNVHQ4EFgQUfv6xFP0xk7027folhy+ziZvBJiwwLAYIKwYB"+ "BQUHAQEEIDAeMBwGCCsGAQUFBzABhhB3d3cuZGlyLmRhdGV2LmRlMA0GCSqGSIb3"+ "DQEBBQUAA4GBAEOVX6uQxbgtKzdgbTi6YLffMftFr2mmNwch7qzpM5gxcynzgVkg"+ "pnQcDNlm5AIbS6pO8jTCLfCd5TZ5biQksBErqmesIl3QD+VqtB+RNghxectZ3VEs"+ "nCUtcE7tJ8O14qwCb3TxS9dvIUFiVi4DjbxX46TdcTbTaK8/qr6AIf+l"); byte[] probSelfSignedCert = Base64.decode( "MIICxTCCAi6gAwIBAgIQAQAAAAAAAAAAAAAAAAAAATANBgkqhkiG9w0BAQUFADBF" + "MScwJQYDVQQKEx4gRElSRUNUSU9OIEdFTkVSQUxFIERFUyBJTVBPVFMxGjAYBgNV" + "BAMTESBBQyBNSU5FRkkgQiBURVNUMB4XDTA0MDUwNzEyMDAwMFoXDTE0MDUwNzEy" + "MDAwMFowRTEnMCUGA1UEChMeIERJUkVDVElPTiBHRU5FUkFMRSBERVMgSU1QT1RT" + "MRowGAYDVQQDExEgQUMgTUlORUZJIEIgVEVTVDCBnzANBgkqhkiG9w0BAQEFAAOB" + "jQAwgYkCgYEAveoCUOAukZdcFCs2qJk76vSqEX0ZFzHqQ6faBPZWjwkgUNwZ6m6m" + "qWvvyq1cuxhoDvpfC6NXILETawYc6MNwwxsOtVVIjuXlcF17NMejljJafbPximEt" + "DQ4LcQeSp4K7FyFlIAMLyt3BQ77emGzU5fjFTvHSUNb3jblx0sV28c0CAwEAAaOB" + "tTCBsjAfBgNVHSMEGDAWgBSEJ4bLbvEQY8cYMAFKPFD1/fFXlzAdBgNVHQ4EFgQU" + "hCeGy27xEGPHGDABSjxQ9f3xV5cwDgYDVR0PAQH/BAQDAgEGMBEGCWCGSAGG+EIB" + "AQQEAwIBBjA8BgNVHR8ENTAzMDGgL6AthitodHRwOi8vYWRvbmlzLnBrNy5jZXJ0" + "cGx1cy5uZXQvZGdpLXRlc3QuY3JsMA8GA1UdEwEB/wQFMAMBAf8wDQYJKoZIhvcN" + "AQEFBQADgYEAmToHJWjd3+4zknfsP09H6uMbolHNGG0zTS2lrLKpzcmkQfjhQpT9" + "LUTBvfs1jdjo9fGmQLvOG+Sm51Rbjglb8bcikVI5gLbclOlvqLkm77otjl4U4Z2/" + "Y0vP14Aov3Sn3k+17EfReYUZI4liuB95ncobC4e8ZM++LjQcIM0s+Vs="); byte[] gost34102001base = Base64.decode( "MIIB1DCCAYECEEjpVKXP6Wn1yVz3VeeDQa8wCgYGKoUDAgIDBQAwbTEfMB0G" + "A1UEAwwWR29zdFIzNDEwLTIwMDEgZXhhbXBsZTESMBAGA1UECgwJQ3J5cHRv" + "UHJvMQswCQYDVQQGEwJSVTEpMCcGCSqGSIb3DQEJARYaR29zdFIzNDEwLTIw" + "MDFAZXhhbXBsZS5jb20wHhcNMDUwMjAzMTUxNjQ2WhcNMTUwMjAzMTUxNjQ2" + "WjBtMR8wHQYDVQQDDBZHb3N0UjM0MTAtMjAwMSBleGFtcGxlMRIwEAYDVQQK" + "DAlDcnlwdG9Qcm8xCzAJBgNVBAYTAlJVMSkwJwYJKoZIhvcNAQkBFhpHb3N0" + "UjM0MTAtMjAwMUBleGFtcGxlLmNvbTBjMBwGBiqFAwICEzASBgcqhQMCAiQA" + "BgcqhQMCAh4BA0MABECElWh1YAIaQHUIzROMMYks/eUFA3pDXPRtKw/nTzJ+" + "V4/rzBa5lYgD0Jp8ha4P5I3qprt+VsfLsN8PZrzK6hpgMAoGBiqFAwICAwUA" + "A0EAHw5dw/aw/OiNvHyOE65kvyo4Hp0sfz3csM6UUkp10VO247ofNJK3tsLb" + "HOLjUaqzefrlGb11WpHYrvWFg+FcLA=="); byte[] gost341094base = Base64.decode( "MIICDzCCAbwCEBcxKsIb0ghYvAQeUjfQdFAwCgYGKoUDAgIEBQAwaTEdMBsG" + "A1UEAwwUR29zdFIzNDEwLTk0IGV4YW1wbGUxEjAQBgNVBAoMCUNyeXB0b1By" + "bzELMAkGA1UEBhMCUlUxJzAlBgkqhkiG9w0BCQEWGEdvc3RSMzQxMC05NEBl" + "eGFtcGxlLmNvbTAeFw0wNTAyMDMxNTE2NTFaFw0xNTAyMDMxNTE2NTFaMGkx" + "HTAbBgNVBAMMFEdvc3RSMzQxMC05NCBleGFtcGxlMRIwEAYDVQQKDAlDcnlw" + "dG9Qcm8xCzAJBgNVBAYTAlJVMScwJQYJKoZIhvcNAQkBFhhHb3N0UjM0MTAt" + "OTRAZXhhbXBsZS5jb20wgaUwHAYGKoUDAgIUMBIGByqFAwICIAIGByqFAwIC" + "HgEDgYQABIGAu4Rm4XmeWzTYLIB/E6gZZnFX/oxUJSFHbzALJ3dGmMb7R1W+" + "t7Lzk2w5tUI3JoTiDRCKJA4fDEJNKzsRK6i/ZjkyXJSLwaj+G2MS9gklh8x1" + "G/TliYoJgmjTXHemD7aQEBON4z58nJHWrA0ILD54wbXCtrcaqCqLRYGTMjJ2" + "+nswCgYGKoUDAgIEBQADQQBxKNhOmjgz/i5CEgLOyKyz9pFGkDcaymsWYQWV" + "v7CZ0pTM8IzMzkUBW3GHsUjCFpanFZDfg2zuN+3kT+694n9B"); byte[] gost341094A = Base64.decode( "MIICSDCCAfWgAwIBAgIBATAKBgYqhQMCAgQFADCBgTEXMBUGA1UEAxMOZGVmYXVsdDM0MTAtOTQx" + "DTALBgNVBAoTBERpZ3QxDzANBgNVBAsTBkNyeXB0bzEOMAwGA1UEBxMFWS1vbGExDDAKBgNVBAgT" + "A01FTDELMAkGA1UEBhMCcnUxGzAZBgkqhkiG9w0BCQEWDHRlc3RAdGVzdC5ydTAeFw0wNTAzMjkx" + "MzExNTdaFw0wNjAzMjkxMzExNTdaMIGBMRcwFQYDVQQDEw5kZWZhdWx0MzQxMC05NDENMAsGA1UE" + "ChMERGlndDEPMA0GA1UECxMGQ3J5cHRvMQ4wDAYDVQQHEwVZLW9sYTEMMAoGA1UECBMDTUVMMQsw" + "CQYDVQQGEwJydTEbMBkGCSqGSIb3DQEJARYMdGVzdEB0ZXN0LnJ1MIGlMBwGBiqFAwICFDASBgcq" + "hQMCAiACBgcqhQMCAh4BA4GEAASBgIQACDLEuxSdRDGgdZxHmy30g/DUYkRxO9Mi/uSHX5NjvZ31" + "b7JMEMFqBtyhql1HC5xZfUwZ0aT3UnEFDfFjLP+Bf54gA+LPkQXw4SNNGOj+klnqgKlPvoqMGlwa" + "+hLPKbS561WpvB2XSTgbV+pqqXR3j6j30STmybelEV3RdS2Now8wDTALBgNVHQ8EBAMCB4AwCgYG" + "KoUDAgIEBQADQQBCFy7xWRXtNVXflKvDs0pBdBuPzjCMeZAXVxK8vUxsxxKu76d9CsvhgIFknFRi" + "wWTPiZenvNoJ4R1uzeX+vREm"); byte[] gost341094B = Base64.decode( "MIICSDCCAfWgAwIBAgIBATAKBgYqhQMCAgQFADCBgTEXMBUGA1UEAxMOcGFyYW0xLTM0MTAtOTQx" + "DTALBgNVBAoTBERpZ3QxDzANBgNVBAsTBkNyeXB0bzEOMAwGA1UEBxMFWS1PbGExDDAKBgNVBAgT" + "A01lbDELMAkGA1UEBhMCcnUxGzAZBgkqhkiG9w0BCQEWDHRlc3RAdGVzdC5ydTAeFw0wNTAzMjkx" + "MzEzNTZaFw0wNjAzMjkxMzEzNTZaMIGBMRcwFQYDVQQDEw5wYXJhbTEtMzQxMC05NDENMAsGA1UE" + "ChMERGlndDEPMA0GA1UECxMGQ3J5cHRvMQ4wDAYDVQQHEwVZLU9sYTEMMAoGA1UECBMDTWVsMQsw" + "CQYDVQQGEwJydTEbMBkGCSqGSIb3DQEJARYMdGVzdEB0ZXN0LnJ1MIGlMBwGBiqFAwICFDASBgcq" + "hQMCAiADBgcqhQMCAh4BA4GEAASBgEa+AAcZmijWs1M9x5Pn9efE8D9ztG1NMoIt0/hNZNqln3+j" + "lMZjyqPt+kTLIjtmvz9BRDmIDk6FZz+4LhG2OTL7yGpWfrMxMRr56nxomTN9aLWRqbyWmn3brz9Y" + "AUD3ifnwjjIuW7UM84JNlDTOdxx0XRUfLQIPMCXe9cO02Xskow8wDTALBgNVHQ8EBAMCB4AwCgYG" + "KoUDAgIEBQADQQBzFcnuYc/639OTW+L5Ecjw9KxGr+dwex7lsS9S1BUgKa3m1d5c+cqI0B2XUFi5" + "4iaHHJG0dCyjtQYLJr0OZjRw"); byte[] gost34102001A = Base64.decode( "MIICCzCCAbigAwIBAgIBATAKBgYqhQMCAgMFADCBhDEaMBgGA1UEAxMRZGVmYXVsdC0zNDEwLTIw" + "MDExDTALBgNVBAoTBERpZ3QxDzANBgNVBAsTBkNyeXB0bzEOMAwGA1UEBxMFWS1PbGExDDAKBgNV" + "BAgTA01lbDELMAkGA1UEBhMCcnUxGzAZBgkqhkiG9w0BCQEWDHRlc3RAdGVzdC5ydTAeFw0wNTAz" + "MjkxMzE4MzFaFw0wNjAzMjkxMzE4MzFaMIGEMRowGAYDVQQDExFkZWZhdWx0LTM0MTAtMjAwMTEN" + "MAsGA1UEChMERGlndDEPMA0GA1UECxMGQ3J5cHRvMQ4wDAYDVQQHEwVZLU9sYTEMMAoGA1UECBMD" + "TWVsMQswCQYDVQQGEwJydTEbMBkGCSqGSIb3DQEJARYMdGVzdEB0ZXN0LnJ1MGMwHAYGKoUDAgIT" + "MBIGByqFAwICIwEGByqFAwICHgEDQwAEQG/4c+ZWb10IpeHfmR+vKcbpmSOClJioYmCVgnojw0Xn" + "ned0KTg7TJreRUc+VX7vca4hLQaZ1o/TxVtfEApK/O6jDzANMAsGA1UdDwQEAwIHgDAKBgYqhQMC" + "AgMFAANBAN8y2b6HuIdkD3aWujpfQbS1VIA/7hro4vLgDhjgVmev/PLzFB8oTh3gKhExpDo82IEs" + "ZftGNsbbyp1NFg7zda0="); byte[] gostCA1 = Base64.decode( "MIIDNDCCAuGgAwIBAgIQZLcKDcWcQopF+jp4p9jylDAKBgYqhQMCAgQFADBm" + "MQswCQYDVQQGEwJSVTEPMA0GA1UEBxMGTW9zY293MRcwFQYDVQQKEw5PT08g" + "Q3J5cHRvLVBybzEUMBIGA1UECxMLRGV2ZWxvcG1lbnQxFzAVBgNVBAMTDkNQ" + "IENTUCBUZXN0IENBMB4XDTAyMDYwOTE1NTIyM1oXDTA5MDYwOTE1NTkyOVow" + "ZjELMAkGA1UEBhMCUlUxDzANBgNVBAcTBk1vc2NvdzEXMBUGA1UEChMOT09P" + "IENyeXB0by1Qcm8xFDASBgNVBAsTC0RldmVsb3BtZW50MRcwFQYDVQQDEw5D" + "UCBDU1AgVGVzdCBDQTCBpTAcBgYqhQMCAhQwEgYHKoUDAgIgAgYHKoUDAgIe" + "AQOBhAAEgYAYglywKuz1nMc9UiBYOaulKy53jXnrqxZKbCCBSVaJ+aCKbsQm" + "glhRFrw6Mwu8Cdeabo/ojmea7UDMZd0U2xhZFRti5EQ7OP6YpqD0alllo7za" + "4dZNXdX+/ag6fOORSLFdMpVx5ganU0wHMPk67j+audnCPUj/plbeyccgcdcd" + "WaOCASIwggEeMAsGA1UdDwQEAwIBxjAPBgNVHRMBAf8EBTADAQH/MB0GA1Ud" + "DgQWBBTe840gTo4zt2twHilw3PD9wJaX0TCBygYDVR0fBIHCMIG/MDygOqA4" + "hjYtaHR0cDovL2ZpZXdhbGwvQ2VydEVucm9sbC9DUCUyMENTUCUyMFRlc3Ql" + "MjBDQSgzKS5jcmwwRKBCoECGPmh0dHA6Ly93d3cuY3J5cHRvcHJvLnJ1L0Nl" + "cnRFbnJvbGwvQ1AlMjBDU1AlMjBUZXN0JTIwQ0EoMykuY3JsMDmgN6A1hjMt" + "ZmlsZTovL1xcZmlld2FsbFxDZXJ0RW5yb2xsXENQIENTUCBUZXN0IENBKDMp" + "LmNybC8wEgYJKwYBBAGCNxUBBAUCAwMAAzAKBgYqhQMCAgQFAANBAIJi7ni7" + "9rwMR5rRGTFftt2k70GbqyUEfkZYOzrgdOoKiB4IIsIstyBX0/ne6GsL9Xan" + "G2IN96RB7KrowEHeW+k="); byte[] gostCA2 = Base64.decode( "MIIC2DCCAoWgAwIBAgIQe9ZCugm42pRKNcHD8466zTAKBgYqhQMCAgMFADB+" + "MRowGAYJKoZIhvcNAQkBFgtzYmFAZGlndC5ydTELMAkGA1UEBhMCUlUxDDAK" + "BgNVBAgTA01FTDEUMBIGA1UEBxMLWW9zaGthci1PbGExDTALBgNVBAoTBERp" + "Z3QxDzANBgNVBAsTBkNyeXB0bzEPMA0GA1UEAxMGc2JhLUNBMB4XDTA0MDgw" + "MzEzMzE1OVoXDTE0MDgwMzEzNDAxMVowfjEaMBgGCSqGSIb3DQEJARYLc2Jh" + "QGRpZ3QucnUxCzAJBgNVBAYTAlJVMQwwCgYDVQQIEwNNRUwxFDASBgNVBAcT" + "C1lvc2hrYXItT2xhMQ0wCwYDVQQKEwREaWd0MQ8wDQYDVQQLEwZDcnlwdG8x" + "DzANBgNVBAMTBnNiYS1DQTBjMBwGBiqFAwICEzASBgcqhQMCAiMBBgcqhQMC" + "Ah4BA0MABEDMSy10CuOH+i8QKG2UWA4XmCt6+BFrNTZQtS6bOalyDY8Lz+G7" + "HybyipE3PqdTB4OIKAAPsEEeZOCZd2UXGQm5o4HaMIHXMBMGCSsGAQQBgjcU" + "AgQGHgQAQwBBMAsGA1UdDwQEAwIBhjAPBgNVHRMBAf8EBTADAQH/MB0GA1Ud" + "DgQWBBRJJl3LcNMxkZI818STfoi3ng1xoDBxBgNVHR8EajBoMDGgL6Athito" + "dHRwOi8vc2JhLmRpZ3QubG9jYWwvQ2VydEVucm9sbC9zYmEtQ0EuY3JsMDOg" + "MaAvhi1maWxlOi8vXFxzYmEuZGlndC5sb2NhbFxDZXJ0RW5yb2xsXHNiYS1D" + "QS5jcmwwEAYJKwYBBAGCNxUBBAMCAQAwCgYGKoUDAgIDBQADQQA+BRJHbc/p" + "q8EYl6iJqXCuR+ozRmH7hPAP3c4KqYSC38TClCgBloLapx/3/WdatctFJW/L" + "mcTovpq088927shE"); byte[] inDirectCrl = Base64.decode( "MIIdXjCCHMcCAQEwDQYJKoZIhvcNAQEFBQAwdDELMAkGA1UEBhMCREUxHDAaBgNV" +"BAoUE0RldXRzY2hlIFRlbGVrb20gQUcxFzAVBgNVBAsUDlQtVGVsZVNlYyBUZXN0" +"MS4wDAYHAoIGAQoHFBMBMTAeBgNVBAMUF1QtVGVsZVNlYyBUZXN0IERJUiA4OlBO" +"Fw0wNjA4MDQwODQ1MTRaFw0wNjA4MDQxNDQ1MTRaMIIbfzB+AgQvrj/pFw0wMzA3" +"MjIwNTQxMjhaMGcwZQYDVR0dAQH/BFswWaRXMFUxCzAJBgNVBAYTAkRFMRwwGgYD" +"VQQKFBNEZXV0c2NoZSBUZWxla29tIEFHMSgwDAYHAoIGAQoHFBMBMTAYBgNVBAMU" +"EVNpZ0cgVGVzdCBDQSA0OlBOMH4CBC+uP+oXDTAzMDcyMjA1NDEyOFowZzBlBgNV" +"HR0BAf8EWzBZpFcwVTELMAkGA1UEBhMCREUxHDAaBgNVBAoUE0RldXRzY2hlIFRl" +"bGVrb20gQUcxKDAMBgcCggYBCgcUEwExMBgGA1UEAxQRU2lnRyBUZXN0IENBIDQ6" +"UE4wfgIEL64/5xcNMDQwNDA1MTMxODE3WjBnMGUGA1UdHQEB/wRbMFmkVzBVMQsw" +"CQYDVQQGEwJERTEcMBoGA1UEChQTRGV1dHNjaGUgVGVsZWtvbSBBRzEoMAwGBwKC" +"BgEKBxQTATEwGAYDVQQDFBFTaWdHIFRlc3QgQ0EgNDpQTjB+AgQvrj/oFw0wNDA0" +"MDUxMzE4MTdaMGcwZQYDVR0dAQH/BFswWaRXMFUxCzAJBgNVBAYTAkRFMRwwGgYD" +"VQQKFBNEZXV0c2NoZSBUZWxla29tIEFHMSgwDAYHAoIGAQoHFBMBMTAYBgNVBAMU" +"EVNpZ0cgVGVzdCBDQSA0OlBOMH4CBC+uP+UXDTAzMDExMzExMTgxMVowZzBlBgNV" +"HR0BAf8EWzBZpFcwVTELMAkGA1UEBhMCREUxHDAaBgNVBAoUE0RldXRzY2hlIFRl" +"bGVrb20gQUcxKDAMBgcCggYBCgcUEwExMBgGA1UEAxQRU2lnRyBUZXN0IENBIDQ6" +"UE4wfgIEL64/5hcNMDMwMTEzMTExODExWjBnMGUGA1UdHQEB/wRbMFmkVzBVMQsw" +"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"); byte[] directCRL = Base64.decode( "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" +"MQ=="); private final byte[] pkcs7CrlProblem = Base64.decode( "MIIwSAYJKoZIhvcNAQcCoIIwOTCCMDUCAQExCzAJBgUrDgMCGgUAMAsGCSqG" + "SIb3DQEHAaCCEsAwggP4MIIC4KADAgECAgF1MA0GCSqGSIb3DQEBBQUAMEUx" + "CzAJBgNVBAYTAlVTMRYwFAYDVQQKEw1HZW9UcnVzdCBJbmMuMR4wHAYDVQQD" + "ExVHZW9UcnVzdCBDQSBmb3IgQWRvYmUwHhcNMDQxMjAyMjEyNTM5WhcNMDYx" + "MjMwMjEyNTM5WjBMMQswCQYDVQQGEwJVUzEVMBMGA1UEChMMR2VvVHJ1c3Qg" + "SW5jMSYwJAYDVQQDEx1HZW9UcnVzdCBBZG9iZSBPQ1NQIFJlc3BvbmRlcjCB" + "nzANBgkqhkiG9w0BAQEFAAOBjQAwgYkCgYEA4gnNYhtw7U6QeVXZODnGhHMj" + "+OgZ0DB393rEk6a2q9kq129IA2e03yKBTfJfQR9aWKc2Qj90dsSqPjvTDHFG" + "Qsagm2FQuhnA3fb1UWhPzeEIdm6bxDsnQ8nWqKqxnWZzELZbdp3I9bBLizIq" + "obZovzt60LNMghn/unvvuhpeVSsCAwEAAaOCAW4wggFqMA4GA1UdDwEB/wQE" + "AwIE8DCB5QYDVR0gAQH/BIHaMIHXMIHUBgkqhkiG9y8BAgEwgcYwgZAGCCsG" + "AQUFBwICMIGDGoGAVGhpcyBjZXJ0aWZpY2F0ZSBoYXMgYmVlbiBpc3N1ZWQg" + "aW4gYWNjb3JkYW5jZSB3aXRoIHRoZSBBY3JvYmF0IENyZWRlbnRpYWxzIENQ" + "UyBsb2NhdGVkIGF0IGh0dHA6Ly93d3cuZ2VvdHJ1c3QuY29tL3Jlc291cmNl" + "cy9jcHMwMQYIKwYBBQUHAgEWJWh0dHA6Ly93d3cuZ2VvdHJ1c3QuY29tL3Jl" + "c291cmNlcy9jcHMwEwYDVR0lBAwwCgYIKwYBBQUHAwkwOgYDVR0fBDMwMTAv" + "oC2gK4YpaHR0cDovL2NybC5nZW90cnVzdC5jb20vY3Jscy9hZG9iZWNhMS5j" + "cmwwHwYDVR0jBBgwFoAUq4BZw2WDbR19E70Zw+wajw1HaqMwDQYJKoZIhvcN" + "AQEFBQADggEBAENJf1BD7PX5ivuaawt90q1OGzXpIQL/ClzEeFVmOIxqPc1E" + "TFRq92YuxG5b6+R+k+tGkmCwPLcY8ipg6ZcbJ/AirQhohzjlFuT6YAXsTfEj" + "CqEZfWM2sS7crK2EYxCMmKE3xDfPclYtrAoz7qZvxfQj0TuxHSstHZv39wu2" + "ZiG1BWiEcyDQyTgqTOXBoZmfJtshuAcXmTpgkrYSrS37zNlPTGh+pMYQ0yWD" + "c8OQRJR4OY5ZXfdna01mjtJTOmj6/6XPoLPYTq2gQrc2BCeNJ4bEhLb7sFVB" + "PbwPrpzTE/HRbQHDrzj0YimDxeOUV/UXctgvYwHNtEkcBLsOm/uytMYwggSh" + "MIIDiaADAgECAgQ+HL0oMA0GCSqGSIb3DQEBBQUAMGkxCzAJBgNVBAYTAlVT" + "MSMwIQYDVQQKExpBZG9iZSBTeXN0ZW1zIEluY29ycG9yYXRlZDEdMBsGA1UE" + "CxMUQWRvYmUgVHJ1c3QgU2VydmljZXMxFjAUBgNVBAMTDUFkb2JlIFJvb3Qg" + "Q0EwHhcNMDMwMTA4MjMzNzIzWhcNMjMwMTA5MDAwNzIzWjBpMQswCQYDVQQG" + "EwJVUzEjMCEGA1UEChMaQWRvYmUgU3lzdGVtcyBJbmNvcnBvcmF0ZWQxHTAb" + "BgNVBAsTFEFkb2JlIFRydXN0IFNlcnZpY2VzMRYwFAYDVQQDEw1BZG9iZSBS" + "b290IENBMIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEAzE9UhPen" + "ouczU38/nBKIayyZR2d+Dx65rRSI+cMQ2B3w8NWfaQovWTWwzGypTJwVoJ/O" + "IL+gz1Ti4CBmRT85hjh+nMSOByLGJPYBErA131XqaZCw24U3HuJOB7JCoWoT" + "aaBm6oCREVkqmwh5WiBELcm9cziLPC/gQxtdswvwrzUaKf7vppLdgUydPVmO" + "rTE8QH6bkTYG/OJcjdGNJtVcRc+vZT+xqtJilvSoOOq6YEL09BxKNRXO+E4i" + "Vg+VGMX4lp+f+7C3eCXpgGu91grwxnSUnfMPUNuad85LcIMjjaDKeCBEXDxU" + "ZPHqojAZn+pMBk0GeEtekt8i0slns3rSAQIDAQABo4IBTzCCAUswEQYJYIZI" + "AYb4QgEBBAQDAgAHMIGOBgNVHR8EgYYwgYMwgYCgfqB8pHoweDELMAkGA1UE" + "BhMCVVMxIzAhBgNVBAoTGkFkb2JlIFN5c3RlbXMgSW5jb3Jwb3JhdGVkMR0w" + "GwYDVQQLExRBZG9iZSBUcnVzdCBTZXJ2aWNlczEWMBQGA1UEAxMNQWRvYmUg" + "Um9vdCBDQTENMAsGA1UEAxMEQ1JMMTArBgNVHRAEJDAigA8yMDAzMDEwODIz" + "MzcyM1qBDzIwMjMwMTA5MDAwNzIzWjALBgNVHQ8EBAMCAQYwHwYDVR0jBBgw" + "FoAUgrc4SpOqmxDvgLvZVOLxD/uAnN4wHQYDVR0OBBYEFIK3OEqTqpsQ74C7" + "2VTi8Q/7gJzeMAwGA1UdEwQFMAMBAf8wHQYJKoZIhvZ9B0EABBAwDhsIVjYu" + "MDo0LjADAgSQMA0GCSqGSIb3DQEBBQUAA4IBAQAy2p9DdcH6b8lv26sdNjc+" + "vGEZNrcCPB0jWZhsnu5NhedUyCAfp9S74r8Ad30ka3AvXME6dkm10+AjhCpx" + "aiLzwScpmBX2NZDkBEzDjbyfYRzn/SSM0URDjBa6m02l1DUvvBHOvfdRN42f" + "kOQU8Rg/vulZEjX5M5LznuDVa5pxm5lLyHHD4bFhCcTl+pHwQjo3fTT5cujN" + "qmIcIenV9IIQ43sFti1oVgt+fpIsb01yggztVnSynbmrLSsdEF/bJ3Vwj/0d" + "1+ICoHnlHOX/r2RAUS2em0fbQqV8H8KmSLDXvpJpTaT2KVfFeBEY3IdRyhOy" + "Yp1PKzK9MaXB+lKrBYjIMIIEyzCCA7OgAwIBAgIEPhy9tTANBgkqhkiG9w0B" + "AQUFADBpMQswCQYDVQQGEwJVUzEjMCEGA1UEChMaQWRvYmUgU3lzdGVtcyBJ" + "bmNvcnBvcmF0ZWQxHTAbBgNVBAsTFEFkb2JlIFRydXN0IFNlcnZpY2VzMRYw" + "FAYDVQQDEw1BZG9iZSBSb290IENBMB4XDTA0MDExNzAwMDMzOVoXDTE1MDEx" + "NTA4MDAwMFowRTELMAkGA1UEBhMCVVMxFjAUBgNVBAoTDUdlb1RydXN0IElu" + "Yy4xHjAcBgNVBAMTFUdlb1RydXN0IENBIGZvciBBZG9iZTCCASIwDQYJKoZI" + "hvcNAQEBBQADggEPADCCAQoCggEBAKfld+BkeFrnOYW8r9L1WygTDlTdSfrO" + "YvWS/Z6Ye5/l+HrBbOHqQCXBcSeCpz7kB2WdKMh1FOE4e9JlmICsHerBLdWk" + "emU+/PDb69zh8E0cLoDfxukF6oVPXj6WSThdSG7H9aXFzRr6S3XGCuvgl+Qw" + "DTLiLYW+ONF6DXwt3TQQtKReJjOJZk46ZZ0BvMStKyBaeB6DKZsmiIo89qso" + "13VDZINH2w1KvXg0ygDizoNtbvgAPFymwnsINS1klfQlcvn0x0RJm9bYQXK3" + "5GNZAgL3M7Lqrld0jMfIUaWvuHCLyivytRuzq1dJ7E8rmidjDEk/G+27pf13" + "fNZ7vR7M+IkCAwEAAaOCAZ0wggGZMBIGA1UdEwEB/wQIMAYBAf8CAQEwUAYD" + "VR0gBEkwRzBFBgkqhkiG9y8BAgEwODA2BggrBgEFBQcCARYqaHR0cHM6Ly93" + "d3cuYWRvYmUuY29tL21pc2MvcGtpL2Nkc19jcC5odG1sMBQGA1UdJQQNMAsG" + "CSqGSIb3LwEBBTCBsgYDVR0fBIGqMIGnMCKgIKAehhxodHRwOi8vY3JsLmFk" + "b2JlLmNvbS9jZHMuY3JsMIGAoH6gfKR6MHgxCzAJBgNVBAYTAlVTMSMwIQYD" + "VQQKExpBZG9iZSBTeXN0ZW1zIEluY29ycG9yYXRlZDEdMBsGA1UECxMUQWRv" + "YmUgVHJ1c3QgU2VydmljZXMxFjAUBgNVBAMTDUFkb2JlIFJvb3QgQ0ExDTAL" + "BgNVBAMTBENSTDEwCwYDVR0PBAQDAgEGMB8GA1UdIwQYMBaAFIK3OEqTqpsQ" + "74C72VTi8Q/7gJzeMB0GA1UdDgQWBBSrgFnDZYNtHX0TvRnD7BqPDUdqozAZ" + "BgkqhkiG9n0HQQAEDDAKGwRWNi4wAwIEkDANBgkqhkiG9w0BAQUFAAOCAQEA" + "PzlZLqIAjrFeEWEs0uC29YyJhkXOE9mf3YSaFGsITF+Gl1j0pajTjyH4R35Q" + "r3floW2q3HfNzTeZ90Jnr1DhVERD6zEMgJpCtJqVuk0sixuXJHghS/KicKf4" + "YXJJPx9epuIRF1siBRnznnF90svmOJMXApc0jGnYn3nQfk4kaShSnDaYaeYR" + "DJKcsiWhl6S5zfwS7Gg8hDeyckhMQKKWnlG1CQrwlSFisKCduoodwRtWgft8" + "kx13iyKK3sbalm6vnVc+5nufS4vI+TwMXoV63NqYaSroafBWk0nL53zGXPEy" + "+A69QhzEViJKn2Wgqt5gt++jMMNImbRObIqgfgF1VjCCBUwwggQ0oAMCAQIC" + "AgGDMA0GCSqGSIb3DQEBBQUAMEUxCzAJBgNVBAYTAlVTMRYwFAYDVQQKEw1H" + "ZW9UcnVzdCBJbmMuMR4wHAYDVQQDExVHZW9UcnVzdCBDQSBmb3IgQWRvYmUw" + "HhcNMDYwMzI0MTU0MjI5WhcNMDkwNDA2MTQ0MjI5WjBzMQswCQYDVQQGEwJV" + "UzELMAkGA1UECBMCTUExETAPBgNVBAoTCEdlb1RydXN0MR0wGwYDVQQDExRN" + "YXJrZXRpbmcgRGVwYXJ0bWVudDElMCMGCSqGSIb3DQEJARYWbWFya2V0aW5n" + "QGdlb3RydXN0LmNvbTCCASIwDQYJKoZIhvcNAQEBBQADggEPADCCAQoCggEB" + "ANmvajTO4XJvAU2nVcLmXeCnAQX7RZt+7+ML3InmqQ3LCGo1weop09zV069/" + "1x/Nmieol7laEzeXxd2ghjGzwfXafqQEqHn6+vBCvqdNPoSi63fSWhnuDVWp" + "KVDOYgxOonrXl+Cc43lu4zRSq+Pi5phhrjDWcH74a3/rdljUt4c4GFezFXfa" + "w2oTzWkxj2cTSn0Szhpr17+p66UNt8uknlhmu4q44Speqql2HwmCEnpLYJrK" + "W3fOq5D4qdsvsLR2EABLhrBezamLI3iGV8cRHOUTsbTMhWhv/lKfHAyf4XjA" + "z9orzvPN5jthhIfICOFq/nStTgakyL4Ln+nFAB/SMPkCAwEAAaOCAhYwggIS" + "MA4GA1UdDwEB/wQEAwIF4DCB5QYDVR0gAQH/BIHaMIHXMIHUBgkqhkiG9y8B" + "AgEwgcYwgZAGCCsGAQUFBwICMIGDGoGAVGhpcyBjZXJ0aWZpY2F0ZSBoYXMg" + "YmVlbiBpc3N1ZWQgaW4gYWNjb3JkYW5jZSB3aXRoIHRoZSBBY3JvYmF0IENy" + "ZWRlbnRpYWxzIENQUyBsb2NhdGVkIGF0IGh0dHA6Ly93d3cuZ2VvdHJ1c3Qu" + "Y29tL3Jlc291cmNlcy9jcHMwMQYIKwYBBQUHAgEWJWh0dHA6Ly93d3cuZ2Vv" + "dHJ1c3QuY29tL3Jlc291cmNlcy9jcHMwOgYDVR0fBDMwMTAvoC2gK4YpaHR0" + "cDovL2NybC5nZW90cnVzdC5jb20vY3Jscy9hZG9iZWNhMS5jcmwwHwYDVR0j" + "BBgwFoAUq4BZw2WDbR19E70Zw+wajw1HaqMwRAYIKwYBBQUHAQEEODA2MDQG" + "CCsGAQUFBzABhihodHRwOi8vYWRvYmUtb2NzcC5nZW90cnVzdC5jb20vcmVz" + "cG9uZGVyMBQGA1UdJQQNMAsGCSqGSIb3LwEBBTA8BgoqhkiG9y8BAQkBBC4w" + "LAIBAYYnaHR0cDovL2Fkb2JlLXRpbWVzdGFtcC5nZW90cnVzdC5jb20vdHNh" + "MBMGCiqGSIb3LwEBCQIEBTADAgEBMAwGA1UdEwQFMAMCAQAwDQYJKoZIhvcN" + "AQEFBQADggEBAAOhy6QxOo+i3h877fvDvTa0plGD2bIqK7wMdNqbMDoSWied" + "FIcgcBOIm2wLxOjZBAVj/3lDq59q2rnVeNnfXM0/N0MHI9TumHRjU7WNk9e4" + "+JfJ4M+c3anrWOG3NE5cICDVgles+UHjXetHWql/LlP04+K2ZOLb6LE2xGnI" + "YyLW9REzCYNAVF+/WkYdmyceHtaBZdbyVAJq0NAJPsfgY1pWcBo31Mr1fpX9" + "WrXNTYDCqMyxMImJTmN3iI68tkXlNrhweQoArKFqBysiBkXzG/sGKYY6tWKU" + "pzjLc3vIp/LrXC5zilROes8BSvwu1w9qQrJNcGwo7O4uijoNtyYil1Exgh1Q" + "MIIdTAIBATBLMEUxCzAJBgNVBAYTAlVTMRYwFAYDVQQKEw1HZW9UcnVzdCBJ" + "bmMuMR4wHAYDVQQDExVHZW9UcnVzdCBDQSBmb3IgQWRvYmUCAgGDMAkGBSsO" + "AwIaBQCgggxMMBgGCSqGSIb3DQEJAzELBgkqhkiG9w0BBwEwIwYJKoZIhvcN" + "AQkEMRYEFP4R6qIdpQJzWyzrqO8X1ZfJOgChMIIMCQYJKoZIhvcvAQEIMYIL" + "+jCCC/agggZ5MIIGdTCCA6gwggKQMA0GCSqGSIb3DQEBBQUAMEUxCzAJBgNV" + "BAYTAlVTMRYwFAYDVQQKEw1HZW9UcnVzdCBJbmMuMR4wHAYDVQQDExVHZW9U" + "cnVzdCBDQSBmb3IgQWRvYmUXDTA2MDQwNDE3NDAxMFoXDTA2MDQwNTE3NDAx" + "MFowggIYMBMCAgC5Fw0wNTEwMTEyMDM2MzJaMBICAVsXDTA0MTEwNDE1MDk0" + "MVowEwICALgXDTA1MTIxMjIyMzgzOFowEgIBWhcNMDQxMTA0MTUwOTMzWjAT" + "AgIA5hcNMDUwODI3MDQwOTM4WjATAgIAtxcNMDYwMTE2MTc1NTEzWjATAgIA" + "hhcNMDUxMjEyMjIzODU1WjATAgIAtRcNMDUwNzA2MTgzODQwWjATAgIA4BcN" + "MDYwMzIwMDc0ODM0WjATAgIAgRcNMDUwODAyMjIzMTE1WjATAgIA3xcNMDUx" + "MjEyMjIzNjUwWjASAgFKFw0wNDExMDQxNTA5MTZaMBICAUQXDTA0MTEwNDE1" + "MDg1M1owEgIBQxcNMDQxMDAzMDEwMDQwWjASAgFsFw0wNDEyMDYxOTQ0MzFa" + "MBMCAgEoFw0wNjAzMDkxMjA3MTJaMBMCAgEkFw0wNjAxMTYxNzU1MzRaMBIC" + "AWcXDTA1MDMxODE3NTYxNFowEwICAVEXDTA2MDEzMTExMjcxMVowEgIBZBcN" + "MDQxMTExMjI0ODQxWjATAgIA8RcNMDUwOTE2MTg0ODAxWjATAgIBThcNMDYw" + "MjIxMjAxMDM2WjATAgIAwRcNMDUxMjEyMjIzODE2WjASAgFiFw0wNTAxMTAx" + "NjE5MzRaMBICAWAXDTA1MDExMDE5MDAwNFowEwICAL4XDTA1MDUxNzE0NTYx" + "MFowDQYJKoZIhvcNAQEFBQADggEBAEKhRMS3wVho1U3EvEQJZC8+JlUngmZQ" + "A78KQbHPWNZWFlNvPuf/b0s7Lu16GfNHXh1QAW6Y5Hi1YtYZ3YOPyMd4Xugt" + "gCdumbB6xtKsDyN5RvTht6ByXj+CYlYqsL7RX0izJZ6mJn4fjMkqzPKNOjb8" + "kSn5T6rn93BjlATtCE8tPVOM8dnqGccRE0OV59+nDBXc90UMt5LdEbwaUOap" + "snVB0oLcNm8d/HnlVH6RY5LnDjrT4vwfe/FApZtTecEWsllVUXDjSpwfcfD/" + "476/lpGySB2otALqzImlA9R8Ok3hJ8dnF6hhQ5Oe6OJMnGYgdhkKbxsKkdib" + "tTVl3qmH5QAwggLFMIIBrQIBATANBgkqhkiG9w0BAQUFADBpMQswCQYDVQQG" + "EwJVUzEjMCEGA1UEChMaQWRvYmUgU3lzdGVtcyBJbmNvcnBvcmF0ZWQxHTAb" + "BgNVBAsTFEFkb2JlIFRydXN0IFNlcnZpY2VzMRYwFAYDVQQDEw1BZG9iZSBS" + "b290IENBFw0wNjAxMjcxODMzMzFaFw0wNzAxMjcwMDAwMDBaMIHeMCMCBD4c" + "vUAXDTAzMDEyMTIzNDY1NlowDDAKBgNVHRUEAwoBBDAjAgQ+HL1BFw0wMzAx" + "MjEyMzQ3MjJaMAwwCgYDVR0VBAMKAQQwIwIEPhy9YhcNMDMwMTIxMjM0NzQy" + "WjAMMAoGA1UdFQQDCgEEMCMCBD4cvWEXDTA0MDExNzAxMDg0OFowDDAKBgNV" + "HRUEAwoBBDAjAgQ+HL2qFw0wNDAxMTcwMTA5MDVaMAwwCgYDVR0VBAMKAQQw" + "IwIEPhy9qBcNMDQwMTE3MDEzOTI5WjAMMAoGA1UdFQQDCgEEoC8wLTAKBgNV" + "HRQEAwIBDzAfBgNVHSMEGDAWgBSCtzhKk6qbEO+Au9lU4vEP+4Cc3jANBgkq" + "hkiG9w0BAQUFAAOCAQEAwtXF9042wG39icUlsotn5tpE3oCusLb/hBpEONhx" + "OdfEQOq0w5hf/vqaxkcf71etA+KpbEUeSVaHMHRPhx/CmPrO9odE139dJdbt" + "9iqbrC9iZokFK3h/es5kg73xujLKd7C/u5ngJ4mwBtvhMLjFjF2vJhPKHL4C" + "IgMwdaUAhrcNzy16v+mw/VGJy3Fvc6oCESW1K9tvFW58qZSNXrMlsuidgunM" + "hPKG+z0SXVyCqL7pnqKiaGddcgujYGOSY4S938oVcfZeZQEODtSYGlzldojX" + "C1U1hCK5+tHAH0Ox/WqRBIol5VCZQwJftf44oG8oviYq52aaqSejXwmfT6zb" + "76GCBXUwggVxMIIFbQoBAKCCBWYwggViBgkrBgEFBQcwAQEEggVTMIIFTzCB" + "taIWBBS+8EpykfXdl4h3z7m/NZfdkAQQERgPMjAwNjA0MDQyMDIwMTVaMGUw" + "YzA7MAkGBSsOAwIaBQAEFEb4BuZYkbjBjOjT6VeA/00fBvQaBBT3fTSQniOp" + "BbHBSkz4xridlX0bsAICAYOAABgPMjAwNjA0MDQyMDIwMTVaoBEYDzIwMDYw" + "NDA1MDgyMDE1WqEjMCEwHwYJKwYBBQUHMAECBBIEEFqooq/R2WltD7TposkT" + "BhMwDQYJKoZIhvcNAQEFBQADgYEAMig6lty4b0JDsT/oanfQG5x6jVKPACpp" + "1UA9SJ0apJJa7LeIdDFmu5C2S/CYiKZm4A4P9cAu0YzgLHxE4r6Op+HfVlAG" + "6bzUe1P/hi1KCJ8r8wxOZAktQFPSzs85RAZwkHMfB0lP2e/h666Oye+Zf8VH" + "RaE+/xZ7aswE89HXoumgggQAMIID/DCCA/gwggLgoAMCAQICAXUwDQYJKoZI" + "hvcNAQEFBQAwRTELMAkGA1UEBhMCVVMxFjAUBgNVBAoTDUdlb1RydXN0IElu" + "Yy4xHjAcBgNVBAMTFUdlb1RydXN0IENBIGZvciBBZG9iZTAeFw0wNDEyMDIy" + "MTI1MzlaFw0wNjEyMzAyMTI1MzlaMEwxCzAJBgNVBAYTAlVTMRUwEwYDVQQK" + "EwxHZW9UcnVzdCBJbmMxJjAkBgNVBAMTHUdlb1RydXN0IEFkb2JlIE9DU1Ag" + "UmVzcG9uZGVyMIGfMA0GCSqGSIb3DQEBAQUAA4GNADCBiQKBgQDiCc1iG3Dt" + "TpB5Vdk4OcaEcyP46BnQMHf3esSTprar2SrXb0gDZ7TfIoFN8l9BH1pYpzZC" + "P3R2xKo+O9MMcUZCxqCbYVC6GcDd9vVRaE/N4Qh2bpvEOydDydaoqrGdZnMQ" + "tlt2ncj1sEuLMiqhtmi/O3rQs0yCGf+6e++6Gl5VKwIDAQABo4IBbjCCAWow" + "DgYDVR0PAQH/BAQDAgTwMIHlBgNVHSABAf8EgdowgdcwgdQGCSqGSIb3LwEC" + "ATCBxjCBkAYIKwYBBQUHAgIwgYMagYBUaGlzIGNlcnRpZmljYXRlIGhhcyBi" + "ZWVuIGlzc3VlZCBpbiBhY2NvcmRhbmNlIHdpdGggdGhlIEFjcm9iYXQgQ3Jl" + "ZGVudGlhbHMgQ1BTIGxvY2F0ZWQgYXQgaHR0cDovL3d3dy5nZW90cnVzdC5j" + "b20vcmVzb3VyY2VzL2NwczAxBggrBgEFBQcCARYlaHR0cDovL3d3dy5nZW90" + "cnVzdC5jb20vcmVzb3VyY2VzL2NwczATBgNVHSUEDDAKBggrBgEFBQcDCTA6" + "BgNVHR8EMzAxMC+gLaArhilodHRwOi8vY3JsLmdlb3RydXN0LmNvbS9jcmxz" + "L2Fkb2JlY2ExLmNybDAfBgNVHSMEGDAWgBSrgFnDZYNtHX0TvRnD7BqPDUdq" + "ozANBgkqhkiG9w0BAQUFAAOCAQEAQ0l/UEPs9fmK+5prC33SrU4bNekhAv8K" + "XMR4VWY4jGo9zURMVGr3Zi7Eblvr5H6T60aSYLA8txjyKmDplxsn8CKtCGiH" + "OOUW5PpgBexN8SMKoRl9YzaxLtysrYRjEIyYoTfEN89yVi2sCjPupm/F9CPR" + "O7EdKy0dm/f3C7ZmIbUFaIRzINDJOCpM5cGhmZ8m2yG4BxeZOmCSthKtLfvM" + "2U9MaH6kxhDTJYNzw5BElHg5jlld92drTWaO0lM6aPr/pc+gs9hOraBCtzYE" + "J40nhsSEtvuwVUE9vA+unNMT8dFtAcOvOPRiKYPF45RX9Rdy2C9jAc20SRwE" + "uw6b+7K0xjANBgkqhkiG9w0BAQEFAASCAQC7a4yICFGCEMPlJbydK5qLG3rV" + "sip7Ojjz9TB4nLhC2DgsIHds8jjdq2zguInluH2nLaBCVS+qxDVlTjgbI2cB" + "TaWS8nglC7nNjzkKAsa8vThA8FZUVXTW0pb74jNJJU2AA27bb4g+4WgunCrj" + "fpYp+QjDyMmdrJVqRmt5eQN+dpVxMS9oq+NrhOSEhyIb4/rejgNg9wnVK1ms" + "l5PxQ4x7kpm7+Ua41//owkJVWykRo4T1jo4eHEz1DolPykAaKie2VKH/sMqR" + "Spjh4E5biKJLOV9fKivZWKAXByXfwUbbMsJvz4v/2yVHFy9xP+tqB5ZbRoDK" + "k8PzUyCprozn+/22oYIPijCCD4YGCyqGSIb3DQEJEAIOMYIPdTCCD3EGCSqG" + "SIb3DQEHAqCCD2Iwgg9eAgEDMQswCQYFKw4DAhoFADCB+gYLKoZIhvcNAQkQ" + "AQSggeoEgecwgeQCAQEGAikCMCEwCQYFKw4DAhoFAAQUoT97qeCv3FXYaEcS" + "gY8patCaCA8CAiMHGA8yMDA2MDQwNDIwMjA1N1owAwIBPAEB/wIIO0yRre3L" + "8/6ggZCkgY0wgYoxCzAJBgNVBAYTAlVTMRYwFAYDVQQIEw1NYXNzYWNodXNl" + "dHRzMRAwDgYDVQQHEwdOZWVkaGFtMRUwEwYDVQQKEwxHZW9UcnVzdCBJbmMx" + "EzARBgNVBAsTClByb2R1Y3Rpb24xJTAjBgNVBAMTHGFkb2JlLXRpbWVzdGFt" + "cC5nZW90cnVzdC5jb22gggzJMIIDUTCCAjmgAwIBAgICAI8wDQYJKoZIhvcN" + "AQEFBQAwRTELMAkGA1UEBhMCVVMxFjAUBgNVBAoTDUdlb1RydXN0IEluYy4x" + "HjAcBgNVBAMTFUdlb1RydXN0IENBIGZvciBBZG9iZTAeFw0wNTAxMTAwMTI5" + "MTBaFw0xNTAxMTUwODAwMDBaMIGKMQswCQYDVQQGEwJVUzEWMBQGA1UECBMN" + "TWFzc2FjaHVzZXR0czEQMA4GA1UEBxMHTmVlZGhhbTEVMBMGA1UEChMMR2Vv" + "VHJ1c3QgSW5jMRMwEQYDVQQLEwpQcm9kdWN0aW9uMSUwIwYDVQQDExxhZG9i" + "ZS10aW1lc3RhbXAuZ2VvdHJ1c3QuY29tMIGfMA0GCSqGSIb3DQEBAQUAA4GN" + "ADCBiQKBgQDRbxJotLFPWQuuEDhKtOMaBUJepGxIvWxeahMbq1DVmqnk88+j" + "w/5lfPICPzQZ1oHrcTLSAFM7Mrz3pyyQKQKMqUyiemzuG/77ESUNfBNSUfAF" + "PdtHuDMU8Is8ABVnFk63L+wdlvvDIlKkE08+VTKCRdjmuBVltMpQ6QcLFQzm" + "AQIDAQABo4GIMIGFMDoGA1UdHwQzMDEwL6AtoCuGKWh0dHA6Ly9jcmwuZ2Vv" + "dHJ1c3QuY29tL2NybHMvYWRvYmVjYTEuY3JsMB8GA1UdIwQYMBaAFKuAWcNl" + "g20dfRO9GcPsGo8NR2qjMA4GA1UdDwEB/wQEAwIGwDAWBgNVHSUBAf8EDDAK" + "BggrBgEFBQcDCDANBgkqhkiG9w0BAQUFAAOCAQEAmnyXjdtX+F79Nf0KggTd" + "6YC2MQD9s09IeXTd8TP3rBmizfM+7f3icggeCGakNfPRmIUMLoa0VM5Kt37T" + "2X0TqzBWusfbKx7HnX4v1t/G8NJJlT4SShSHv+8bjjU4lUoCmW2oEcC5vXwP" + "R5JfjCyois16npgcO05ZBT+LLDXyeBijE6qWmwLDfEpLyILzVRmyU4IE7jvm" + "rgb3GXwDUvd3yQXGRRHbPCh3nj9hBGbuzyt7GnlqnEie3wzIyMG2ET/wvTX5" + "4BFXKNe7lDLvZj/MXvd3V7gMTSVW0kAszKao56LfrVTgp1VX3UBQYwmQqaoA" + "UwFezih+jEvjW6cYJo/ErDCCBKEwggOJoAMCAQICBD4cvSgwDQYJKoZIhvcN" + "AQEFBQAwaTELMAkGA1UEBhMCVVMxIzAhBgNVBAoTGkFkb2JlIFN5c3RlbXMg" + "SW5jb3Jwb3JhdGVkMR0wGwYDVQQLExRBZG9iZSBUcnVzdCBTZXJ2aWNlczEW" + "MBQGA1UEAxMNQWRvYmUgUm9vdCBDQTAeFw0wMzAxMDgyMzM3MjNaFw0yMzAx" + "MDkwMDA3MjNaMGkxCzAJBgNVBAYTAlVTMSMwIQYDVQQKExpBZG9iZSBTeXN0" + "ZW1zIEluY29ycG9yYXRlZDEdMBsGA1UECxMUQWRvYmUgVHJ1c3QgU2Vydmlj" + "ZXMxFjAUBgNVBAMTDUFkb2JlIFJvb3QgQ0EwggEiMA0GCSqGSIb3DQEBAQUA" + "A4IBDwAwggEKAoIBAQDMT1SE96ei5zNTfz+cEohrLJlHZ34PHrmtFIj5wxDY" + "HfDw1Z9pCi9ZNbDMbKlMnBWgn84gv6DPVOLgIGZFPzmGOH6cxI4HIsYk9gES" + "sDXfVeppkLDbhTce4k4HskKhahNpoGbqgJERWSqbCHlaIEQtyb1zOIs8L+BD" + "G12zC/CvNRop/u+mkt2BTJ09WY6tMTxAfpuRNgb84lyN0Y0m1VxFz69lP7Gq" + "0mKW9Kg46rpgQvT0HEo1Fc74TiJWD5UYxfiWn5/7sLd4JemAa73WCvDGdJSd" + "8w9Q25p3zktwgyONoMp4IERcPFRk8eqiMBmf6kwGTQZ4S16S3yLSyWezetIB" + "AgMBAAGjggFPMIIBSzARBglghkgBhvhCAQEEBAMCAAcwgY4GA1UdHwSBhjCB" + "gzCBgKB+oHykejB4MQswCQYDVQQGEwJVUzEjMCEGA1UEChMaQWRvYmUgU3lz" + "dGVtcyBJbmNvcnBvcmF0ZWQxHTAbBgNVBAsTFEFkb2JlIFRydXN0IFNlcnZp" + "Y2VzMRYwFAYDVQQDEw1BZG9iZSBSb290IENBMQ0wCwYDVQQDEwRDUkwxMCsG" + "A1UdEAQkMCKADzIwMDMwMTA4MjMzNzIzWoEPMjAyMzAxMDkwMDA3MjNaMAsG" + "A1UdDwQEAwIBBjAfBgNVHSMEGDAWgBSCtzhKk6qbEO+Au9lU4vEP+4Cc3jAd" + "BgNVHQ4EFgQUgrc4SpOqmxDvgLvZVOLxD/uAnN4wDAYDVR0TBAUwAwEB/zAd" + "BgkqhkiG9n0HQQAEEDAOGwhWNi4wOjQuMAMCBJAwDQYJKoZIhvcNAQEFBQAD" + "ggEBADLan0N1wfpvyW/bqx02Nz68YRk2twI8HSNZmGye7k2F51TIIB+n1Lvi" + "vwB3fSRrcC9cwTp2SbXT4COEKnFqIvPBJymYFfY1kOQETMONvJ9hHOf9JIzR" + "REOMFrqbTaXUNS+8Ec6991E3jZ+Q5BTxGD++6VkSNfkzkvOe4NVrmnGbmUvI" + "ccPhsWEJxOX6kfBCOjd9NPly6M2qYhwh6dX0ghDjewW2LWhWC35+kixvTXKC" + "DO1WdLKduastKx0QX9sndXCP/R3X4gKgeeUc5f+vZEBRLZ6bR9tCpXwfwqZI" + "sNe+kmlNpPYpV8V4ERjch1HKE7JinU8rMr0xpcH6UqsFiMgwggTLMIIDs6AD" + "AgECAgQ+HL21MA0GCSqGSIb3DQEBBQUAMGkxCzAJBgNVBAYTAlVTMSMwIQYD" + "VQQKExpBZG9iZSBTeXN0ZW1zIEluY29ycG9yYXRlZDEdMBsGA1UECxMUQWRv" + "YmUgVHJ1c3QgU2VydmljZXMxFjAUBgNVBAMTDUFkb2JlIFJvb3QgQ0EwHhcN" + "MDQwMTE3MDAwMzM5WhcNMTUwMTE1MDgwMDAwWjBFMQswCQYDVQQGEwJVUzEW" + "MBQGA1UEChMNR2VvVHJ1c3QgSW5jLjEeMBwGA1UEAxMVR2VvVHJ1c3QgQ0Eg" + "Zm9yIEFkb2JlMIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEAp+V3" + "4GR4Wuc5hbyv0vVbKBMOVN1J+s5i9ZL9nph7n+X4esFs4epAJcFxJ4KnPuQH" + "ZZ0oyHUU4Th70mWYgKwd6sEt1aR6ZT788Nvr3OHwTRwugN/G6QXqhU9ePpZJ" + "OF1Ibsf1pcXNGvpLdcYK6+CX5DANMuIthb440XoNfC3dNBC0pF4mM4lmTjpl" + "nQG8xK0rIFp4HoMpmyaIijz2qyjXdUNkg0fbDUq9eDTKAOLOg21u+AA8XKbC" + "ewg1LWSV9CVy+fTHREmb1thBcrfkY1kCAvczsuquV3SMx8hRpa+4cIvKK/K1" + "G7OrV0nsTyuaJ2MMST8b7bul/Xd81nu9Hsz4iQIDAQABo4IBnTCCAZkwEgYD" + "VR0TAQH/BAgwBgEB/wIBATBQBgNVHSAESTBHMEUGCSqGSIb3LwECATA4MDYG" + "CCsGAQUFBwIBFipodHRwczovL3d3dy5hZG9iZS5jb20vbWlzYy9wa2kvY2Rz" + "X2NwLmh0bWwwFAYDVR0lBA0wCwYJKoZIhvcvAQEFMIGyBgNVHR8Egaowgacw" + "IqAgoB6GHGh0dHA6Ly9jcmwuYWRvYmUuY29tL2Nkcy5jcmwwgYCgfqB8pHow" + "eDELMAkGA1UEBhMCVVMxIzAhBgNVBAoTGkFkb2JlIFN5c3RlbXMgSW5jb3Jw" + "b3JhdGVkMR0wGwYDVQQLExRBZG9iZSBUcnVzdCBTZXJ2aWNlczEWMBQGA1UE" + "AxMNQWRvYmUgUm9vdCBDQTENMAsGA1UEAxMEQ1JMMTALBgNVHQ8EBAMCAQYw" + "HwYDVR0jBBgwFoAUgrc4SpOqmxDvgLvZVOLxD/uAnN4wHQYDVR0OBBYEFKuA" + "WcNlg20dfRO9GcPsGo8NR2qjMBkGCSqGSIb2fQdBAAQMMAobBFY2LjADAgSQ" + "MA0GCSqGSIb3DQEBBQUAA4IBAQA/OVkuogCOsV4RYSzS4Lb1jImGRc4T2Z/d" + "hJoUawhMX4aXWPSlqNOPIfhHflCvd+Whbarcd83NN5n3QmevUOFUREPrMQyA" + "mkK0mpW6TSyLG5ckeCFL8qJwp/hhckk/H16m4hEXWyIFGfOecX3Sy+Y4kxcC" + "lzSMadifedB+TiRpKFKcNphp5hEMkpyyJaGXpLnN/BLsaDyEN7JySExAopae" + "UbUJCvCVIWKwoJ26ih3BG1aB+3yTHXeLIorextqWbq+dVz7me59Li8j5PAxe" + "hXrc2phpKuhp8FaTScvnfMZc8TL4Dr1CHMRWIkqfZaCq3mC376Mww0iZtE5s" + "iqB+AXVWMYIBgDCCAXwCAQEwSzBFMQswCQYDVQQGEwJVUzEWMBQGA1UEChMN" + "R2VvVHJ1c3QgSW5jLjEeMBwGA1UEAxMVR2VvVHJ1c3QgQ0EgZm9yIEFkb2Jl" + "AgIAjzAJBgUrDgMCGgUAoIGMMBoGCSqGSIb3DQEJAzENBgsqhkiG9w0BCRAB" + "BDAcBgkqhkiG9w0BCQUxDxcNMDYwNDA0MjAyMDU3WjAjBgkqhkiG9w0BCQQx" + "FgQUp7AnXBqoNcarvO7fMJut1og2U5AwKwYLKoZIhvcNAQkQAgwxHDAaMBgw" + "FgQU1dH4eZTNhgxdiSABrat6zsPdth0wDQYJKoZIhvcNAQEBBQAEgYCinr/F" + "rMiQz/MRm9ZD5YGcC0Qo2dRTPd0Aop8mZ4g1xAhKFLnp7lLsjCbkSDpVLDBh" + "cnCk7CV+3FT5hlvt8OqZlR0CnkSnCswLFhrppiWle6cpxlwGqyAteC8uKtQu" + "wjE5GtBKLcCOAzQYyyuNZZeB6oCZ+3mPhZ62FxrvvEGJCgAAAAAAAAAAAAAA" + "AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA" + "AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA" + "AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA" + "AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA" + "AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA" + "AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA" + "AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA" + "AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA" + "AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA=="); private final byte[] emptyDNCert = Base64.decode( "MIICfTCCAeagAwIBAgIBajANBgkqhkiG9w0BAQQFADB8MQswCQYDVQQGEwJVUzEMMAoGA1UEChMD" + "Q0RXMQkwBwYDVQQLEwAxCTAHBgNVBAcTADEJMAcGA1UECBMAMRowGAYDVQQDExFUZW1wbGFyIFRl" + "c3QgMTAyNDEiMCAGCSqGSIb3DQEJARYTdGVtcGxhcnRlc3RAY2R3LmNvbTAeFw0wNjA1MjIwNTAw" + "MDBaFw0xMDA1MjIwNTAwMDBaMHwxCzAJBgNVBAYTAlVTMQwwCgYDVQQKEwNDRFcxCTAHBgNVBAsT" + "ADEJMAcGA1UEBxMAMQkwBwYDVQQIEwAxGjAYBgNVBAMTEVRlbXBsYXIgVGVzdCAxMDI0MSIwIAYJ" + "KoZIhvcNAQkBFhN0ZW1wbGFydGVzdEBjZHcuY29tMIGfMA0GCSqGSIb3DQEBAQUAA4GNADCBiQKB" + "gQDH3aJpJBfM+A3d84j5YcU6zEQaQ76u5xO9NSBmHjZykKS2kCcUqPpvVOPDA5WgV22dtKPh+lYV" + "iUp7wyCVwAKibq8HIbihHceFqMKzjwC639rMoDJ7bi/yzQWz1Zg+075a4FGPlUKn7Yfu89wKkjdW" + "wDpRPXc/agqBnrx5pJTXzQIDAQABow8wDTALBgNVHQ8EBAMCALEwDQYJKoZIhvcNAQEEBQADgYEA" + "RRsRsjse3i2/KClFVd6YLZ+7K1BE0WxFyY2bbytkwQJSxvv3vLSuweFUbhNxutb68wl/yW4GLy4b" + "1QdyswNxrNDXTuu5ILKhRDDuWeocz83aG2KGtr3JlFyr3biWGEyn5WUOE6tbONoQDJ0oPYgI6CAc" + "EHdUp0lioOCt6UOw7Cs="); private final byte[] gostRFC4491_94 = Base64.decode( "MIICCzCCAboCECMO42BGlSTOxwvklBgufuswCAYGKoUDAgIEMGkxHTAbBgNVBAMM" + "FEdvc3RSMzQxMC05NCBleGFtcGxlMRIwEAYDVQQKDAlDcnlwdG9Qcm8xCzAJBgNV" + "BAYTAlJVMScwJQYJKoZIhvcNAQkBFhhHb3N0UjM0MTAtOTRAZXhhbXBsZS5jb20w" + "HhcNMDUwODE2MTIzMjUwWhcNMTUwODE2MTIzMjUwWjBpMR0wGwYDVQQDDBRHb3N0" + "UjM0MTAtOTQgZXhhbXBsZTESMBAGA1UECgwJQ3J5cHRvUHJvMQswCQYDVQQGEwJS" + "VTEnMCUGCSqGSIb3DQEJARYYR29zdFIzNDEwLTk0QGV4YW1wbGUuY29tMIGlMBwG" + "BiqFAwICFDASBgcqhQMCAiACBgcqhQMCAh4BA4GEAASBgLuEZuF5nls02CyAfxOo" + "GWZxV/6MVCUhR28wCyd3RpjG+0dVvrey85NsObVCNyaE4g0QiiQOHwxCTSs7ESuo" + "v2Y5MlyUi8Go/htjEvYJJYfMdRv05YmKCYJo01x3pg+2kBATjeM+fJyR1qwNCCw+" + "eMG1wra3Gqgqi0WBkzIydvp7MAgGBiqFAwICBANBABHHCH4S3ALxAiMpR3aPRyqB" + "g1DjB8zy5DEjiULIc+HeIveF81W9lOxGkZxnrFjXBSqnjLeFKgF1hffXOAP7zUM="); private final byte[] gostRFC4491_2001 = Base64.decode( "MIIB0DCCAX8CECv1xh7CEb0Xx9zUYma0LiEwCAYGKoUDAgIDMG0xHzAdBgNVBAMM" + "Fkdvc3RSMzQxMC0yMDAxIGV4YW1wbGUxEjAQBgNVBAoMCUNyeXB0b1BybzELMAkG" + "A1UEBhMCUlUxKTAnBgkqhkiG9w0BCQEWGkdvc3RSMzQxMC0yMDAxQGV4YW1wbGUu" + "Y29tMB4XDTA1MDgxNjE0MTgyMFoXDTE1MDgxNjE0MTgyMFowbTEfMB0GA1UEAwwW" + "R29zdFIzNDEwLTIwMDEgZXhhbXBsZTESMBAGA1UECgwJQ3J5cHRvUHJvMQswCQYD" + "VQQGEwJSVTEpMCcGCSqGSIb3DQEJARYaR29zdFIzNDEwLTIwMDFAZXhhbXBsZS5j" + "b20wYzAcBgYqhQMCAhMwEgYHKoUDAgIkAAYHKoUDAgIeAQNDAARAhJVodWACGkB1" + "CM0TjDGJLP3lBQN6Q1z0bSsP508yfleP68wWuZWIA9CafIWuD+SN6qa7flbHy7Df" + "D2a8yuoaYDAIBgYqhQMCAgMDQQA8L8kJRLcnqeyn1en7U23Sw6pkfEQu3u0xFkVP" + "vFQ/3cHeF26NG+xxtZPz3TaTVXdoiYkXYiD02rEx1bUcM97i"); private PublicKey dudPublicKey = new PublicKey() { public String getAlgorithm() { return null; } public String getFormat() { return null; } public byte[] getEncoded() { return null; } }; public String getName() { return "CertTest"; } public void checkCertificate( int id, byte[] bytes) { ByteArrayInputStream bIn; String dump = ""; try { bIn = new ByteArrayInputStream(bytes); CertificateFactory fact = CertificateFactory.getInstance("X.509", "BC"); Certificate cert = fact.generateCertificate(bIn); PublicKey k = cert.getPublicKey(); // System.out.println(cert); } catch (Exception e) { fail(dump + System.getProperty("line.separator") + getName() + ": "+ id + " failed - exception " + e.toString(), e); } } public void checkNameCertificate( int id, byte[] bytes) { ByteArrayInputStream bIn; String dump = ""; try { bIn = new ByteArrayInputStream(bytes); CertificateFactory fact = CertificateFactory.getInstance("X.509", "BC"); X509Certificate cert = (X509Certificate)fact.generateCertificate(bIn); PublicKey k = cert.getPublicKey(); if (!cert.getIssuerDN().toString().equals("C=DE,O=DATEV eG,0.2.262.1.10.7.20=1+CN=CA DATEV D03 1:PN")) { fail(id + " failed - name test."); } // System.out.println(cert); } catch (Exception e) { fail(dump + System.getProperty("line.separator") + getName() + ": "+ id + " failed - exception " + e.toString(), e); } } public void checkKeyUsage( int id, byte[] bytes) { ByteArrayInputStream bIn; String dump = ""; try { bIn = new ByteArrayInputStream(bytes); CertificateFactory fact = CertificateFactory.getInstance("X.509", "BC"); X509Certificate cert = (X509Certificate)fact.generateCertificate(bIn); PublicKey k = cert.getPublicKey(); if (cert.getKeyUsage()[7]) { fail("error generating cert - key usage wrong."); } // System.out.println(cert); } catch (Exception e) { fail(dump + System.getProperty("line.separator") + getName() + ": "+ id + " failed - exception " + e.toString(), e); } } public void checkSelfSignedCertificate( int id, byte[] bytes) { ByteArrayInputStream bIn; String dump = ""; try { bIn = new ByteArrayInputStream(bytes); CertificateFactory fact = CertificateFactory.getInstance("X.509", "BC"); Certificate cert = fact.generateCertificate(bIn); PublicKey k = cert.getPublicKey(); cert.verify(k); // System.out.println(cert); } catch (Exception e) { fail(dump + System.getProperty("line.separator") + getName() + ": "+ id + " failed - exception " + e.toString(), e); } } /** * Test a generated certificate with the sun provider */ private void sunProviderCheck(byte[] encoding) throws CertificateException { CertificateFactory certFact = CertificateFactory.getInstance("X.509"); certFact.generateCertificate(new ByteArrayInputStream(encoding)); } /** * we generate a self signed certificate for the sake of testing - RSA */ public void checkCreation1() throws Exception { // // a sample key pair. // RSAPublicKeySpec pubKeySpec = new RSAPublicKeySpec( new BigInteger("b4a7e46170574f16a97082b22be58b6a2a629798419be12872a4bdba626cfae9900f76abfb12139dce5de56564fab2b6543165a040c606887420e33d91ed7ed7", 16), new BigInteger("11", 16)); RSAPrivateCrtKeySpec privKeySpec = new RSAPrivateCrtKeySpec( new BigInteger("b4a7e46170574f16a97082b22be58b6a2a629798419be12872a4bdba626cfae9900f76abfb12139dce5de56564fab2b6543165a040c606887420e33d91ed7ed7", 16), new BigInteger("11", 16), new BigInteger("9f66f6b05410cd503b2709e88115d55daced94d1a34d4e32bf824d0dde6028ae79c5f07b580f5dce240d7111f7ddb130a7945cd7d957d1920994da389f490c89", 16), new BigInteger("c0a0758cdf14256f78d4708c86becdead1b50ad4ad6c5c703e2168fbf37884cb", 16), new BigInteger("f01734d7960ea60070f1b06f2bb81bfac48ff192ae18451d5e56c734a5aab8a5", 16), new BigInteger("b54bb9edff22051d9ee60f9351a48591b6500a319429c069a3e335a1d6171391", 16), new BigInteger("d3d83daf2a0cecd3367ae6f8ae1aeb82e9ac2f816c6fc483533d8297dd7884cd", 16), new BigInteger("b8f52fc6f38593dabb661d3f50f8897f8106eee68b1bce78a95b132b4e5b5d19", 16)); // // set up the keys // PrivateKey privKey; PublicKey pubKey; KeyFactory fact = KeyFactory.getInstance("RSA", "BC"); privKey = fact.generatePrivate(privKeySpec); pubKey = fact.generatePublic(pubKeySpec); // // distinguished name table. // X500NameBuilder builder = new X500NameBuilder(BCStyle.INSTANCE); builder.addRDN(BCStyle.C, "AU"); builder.addRDN(BCStyle.O, "The Legion of the Bouncy Castle"); builder.addRDN(BCStyle.L, "Melbourne"); builder.addRDN(BCStyle.ST, "Victoria"); builder.addRDN(BCStyle.E, "feedback-crypto@bouncycastle.org"); // // extensions // // // create the certificate - version 3 - without extensions // ContentSigner sigGen = new JcaContentSignerBuilder("SHA256WithRSAEncryption").setProvider(BC).build(privKey); X509v3CertificateBuilder certGen = new JcaX509v3CertificateBuilder(builder.build(), BigInteger.valueOf(1), new Date(System.currentTimeMillis() - 50000), new Date(System.currentTimeMillis() + 50000),builder.build(), pubKey); X509Certificate cert = new JcaX509CertificateConverter().setProvider(BC).getCertificate(certGen.build(sigGen)); cert.checkValidity(new Date()); cert.verify(pubKey); cert.verify(cert.getPublicKey()); Set dummySet = cert.getNonCriticalExtensionOIDs(); if (dummySet != null) { fail("non-critical oid set should be null"); } dummySet = cert.getCriticalExtensionOIDs(); if (dummySet != null) { fail("critical oid set should be null"); } // // create the certificate - version 3 - with extensions // sigGen = new JcaContentSignerBuilder("MD5WithRSAEncryption").setProvider(BC).build(privKey); certGen = new JcaX509v3CertificateBuilder(builder.build(), BigInteger.valueOf(1) , new Date(System.currentTimeMillis() - 50000) , new Date(System.currentTimeMillis() + 50000) , builder.build() , pubKey) .addExtension(new ASN1ObjectIdentifier("2.5.29.15"), true, new X509KeyUsage(X509KeyUsage.encipherOnly)) .addExtension(new ASN1ObjectIdentifier("2.5.29.37"), true, new DERSequence(KeyPurposeId.anyExtendedKeyUsage)) .addExtension(new ASN1ObjectIdentifier("2.5.29.17"), true, new GeneralNames(new GeneralName[] { new GeneralName(GeneralName.rfc822Name, "test@test.test"), new GeneralName(GeneralName.dNSName, "dom.test.test") })); X509CertificateHolder certHolder = certGen.build(sigGen); cert = new JcaX509CertificateConverter().setProvider(BC).getCertificate(certHolder); cert.checkValidity(new Date()); cert.verify(pubKey); cert.verify(cert.getPublicKey()); ContentVerifierProvider contentVerifierProvider = new JcaContentVerifierProviderBuilder().setProvider(BC).build(pubKey); if (!certHolder.isSignatureValid(contentVerifierProvider)) { fail("signature test failed"); } ByteArrayInputStream bIn = new ByteArrayInputStream(cert.getEncoded()); CertificateFactory certFact = CertificateFactory.getInstance("X.509", "BC"); cert = (X509Certificate)certFact.generateCertificate(bIn); if (!cert.getKeyUsage()[7]) { fail("error generating cert - key usage wrong."); } List l = cert.getExtendedKeyUsage(); if (!l.get(0).equals(KeyPurposeId.anyExtendedKeyUsage.getId())) { fail("failed extended key usage test"); } Collection c = cert.getSubjectAlternativeNames(); Iterator it = c.iterator(); while (it.hasNext()) { List gn = (List)it.next(); if (!gn.get(1).equals("test@test.test") && !gn.get(1).equals("dom.test.test")) { fail("failed subject alternative names test"); } } sunProviderCheck(certHolder.getEncoded()); sunProviderCheck(cert.getEncoded()); // System.out.println(cert); // // create the certificate - version 1 // sigGen = new JcaContentSignerBuilder("MD5WithRSAEncryption").setProvider(BC).build(privKey); X509v1CertificateBuilder certGen1 = new JcaX509v1CertificateBuilder(builder.build(), BigInteger.valueOf(1), new Date(System.currentTimeMillis() - 50000),new Date(System.currentTimeMillis() + 50000),builder.build(),pubKey); cert = new JcaX509CertificateConverter().setProvider(BC).getCertificate(certGen1.build(sigGen)); cert.checkValidity(new Date()); cert.verify(pubKey); cert.verify(cert.getPublicKey()); bIn = new ByteArrayInputStream(cert.getEncoded()); certFact = CertificateFactory.getInstance("X.509", "BC"); cert = (X509Certificate)certFact.generateCertificate(bIn); // System.out.println(cert); if (!cert.getIssuerDN().equals(cert.getSubjectDN())) { fail("name comparison fails"); } sunProviderCheck(certHolder.getEncoded()); sunProviderCheck(cert.getEncoded()); // // a lightweight key pair. // RSAKeyParameters lwPubKey = new RSAKeyParameters( false, new BigInteger("b4a7e46170574f16a97082b22be58b6a2a629798419be12872a4bdba626cfae9900f76abfb12139dce5de56564fab2b6543165a040c606887420e33d91ed7ed7", 16), new BigInteger("11", 16)); RSAPrivateCrtKeyParameters lwPrivKey = new RSAPrivateCrtKeyParameters( new BigInteger("b4a7e46170574f16a97082b22be58b6a2a629798419be12872a4bdba626cfae9900f76abfb12139dce5de56564fab2b6543165a040c606887420e33d91ed7ed7", 16), new BigInteger("11", 16), new BigInteger("9f66f6b05410cd503b2709e88115d55daced94d1a34d4e32bf824d0dde6028ae79c5f07b580f5dce240d7111f7ddb130a7945cd7d957d1920994da389f490c89", 16), new BigInteger("c0a0758cdf14256f78d4708c86becdead1b50ad4ad6c5c703e2168fbf37884cb", 16), new BigInteger("f01734d7960ea60070f1b06f2bb81bfac48ff192ae18451d5e56c734a5aab8a5", 16), new BigInteger("b54bb9edff22051d9ee60f9351a48591b6500a319429c069a3e335a1d6171391", 16), new BigInteger("d3d83daf2a0cecd3367ae6f8ae1aeb82e9ac2f816c6fc483533d8297dd7884cd", 16), new BigInteger("b8f52fc6f38593dabb661d3f50f8897f8106eee68b1bce78a95b132b4e5b5d19", 16)); // // distinguished name table. // builder = new X500NameBuilder(BCStyle.INSTANCE); builder.addRDN(BCStyle.C, "AU"); builder.addRDN(BCStyle.O, "The Legion of the Bouncy Castle"); builder.addRDN(BCStyle.L, "Melbourne"); builder.addRDN(BCStyle.ST, "Victoria"); builder.addRDN(BCStyle.E, "feedback-crypto@bouncycastle.org"); // // extensions // // // create the certificate - version 3 - without extensions // AlgorithmIdentifier sigAlgId = new DefaultSignatureAlgorithmIdentifierFinder().find("SHA256WithRSAEncryption"); AlgorithmIdentifier digAlgId = new DefaultDigestAlgorithmIdentifierFinder().find(sigAlgId); sigGen = new BcRSAContentSignerBuilder(sigAlgId, digAlgId).build(lwPrivKey); SubjectPublicKeyInfo pubInfo = new SubjectPublicKeyInfo(new AlgorithmIdentifier(PKCSObjectIdentifiers.rsaEncryption, DERNull.INSTANCE), new RSAPublicKey(lwPubKey.getModulus(), lwPubKey.getExponent())); certGen = new X509v3CertificateBuilder(builder.build(), BigInteger.valueOf(1), new Date(System.currentTimeMillis() - 50000), new Date(System.currentTimeMillis() + 50000), builder.build(), pubInfo); certHolder = certGen.build(sigGen); cert = new JcaX509CertificateConverter().setProvider(BC).getCertificate(certHolder); cert.checkValidity(new Date()); cert.verify(pubKey); contentVerifierProvider = new BcRSAContentVerifierProviderBuilder(new DefaultDigestAlgorithmIdentifierFinder()).build(lwPubKey); if (!certHolder.isSignatureValid(contentVerifierProvider)) { fail("lw sig verification failed"); } } /** * we generate a self signed certificate for the sake of testing - DSA */ public void checkCreation2() throws Exception { // // set up the keys // PrivateKey privKey; PublicKey pubKey; try { KeyPairGenerator g = KeyPairGenerator.getInstance("DSA", "SUN"); g.initialize(512, new SecureRandom()); KeyPair p = g.generateKeyPair(); privKey = p.getPrivate(); pubKey = p.getPublic(); } catch (Exception e) { fail("error setting up keys - " + e.toString()); return; } // // distinguished name table. // X500NameBuilder builder = createStdBuilder(); // // extensions // // // create the certificate - version 3 // ContentSigner sigGen = new JcaContentSignerBuilder("SHA1withDSA").setProvider(BC).build(privKey); JcaX509v3CertificateBuilder certGen = new JcaX509v3CertificateBuilder(builder.build(),BigInteger.valueOf(1),new Date(System.currentTimeMillis() - 50000),new Date(System.currentTimeMillis() + 50000),builder.build(),pubKey); X509Certificate cert = new JcaX509CertificateConverter().setProvider(BC).getCertificate(certGen.build(sigGen)); cert.checkValidity(new Date()); cert.verify(pubKey); ByteArrayInputStream bIn = new ByteArrayInputStream(cert.getEncoded()); CertificateFactory fact = CertificateFactory.getInstance("X.509", BC); cert = (X509Certificate)fact.generateCertificate(bIn); // System.out.println(cert); // // create the certificate - version 1 // sigGen = new JcaContentSignerBuilder("SHA1withDSA").setProvider(BC).build(privKey); JcaX509v1CertificateBuilder certGen1 = new JcaX509v1CertificateBuilder(builder.build(),BigInteger.valueOf(1),new Date(System.currentTimeMillis() - 50000),new Date(System.currentTimeMillis() + 50000),builder.build(),pubKey); cert = new JcaX509CertificateConverter().setProvider(BC).getCertificate(certGen1.build(sigGen)); cert.checkValidity(new Date()); cert.verify(pubKey); bIn = new ByteArrayInputStream(cert.getEncoded()); fact = CertificateFactory.getInstance("X.509", BC); cert = (X509Certificate)fact.generateCertificate(bIn); //System.out.println(cert); // // exception test // try { certGen1 = new JcaX509v1CertificateBuilder(builder.build(),BigInteger.valueOf(1),new Date(System.currentTimeMillis() - 50000),new Date(System.currentTimeMillis() + 50000),builder.build(),dudPublicKey); fail("key without encoding not detected in v1"); } catch (IllegalArgumentException e) { // expected } } private X500NameBuilder createStdBuilder() { X500NameBuilder builder = new X500NameBuilder(BCStyle.INSTANCE); builder.addRDN(BCStyle.C, "AU"); builder.addRDN(BCStyle.O, "The Legion of the Bouncy Castle"); builder.addRDN(BCStyle.L, "Melbourne"); builder.addRDN(BCStyle.ST, "Victoria"); builder.addRDN(BCStyle.E, "feedback-crypto@bouncycastle.org"); return builder; } /** * we generate a self signed certificate for the sake of testing - ECDSA */ public void checkCreation3() { ECCurve curve = new ECCurve.Fp( new BigInteger("883423532389192164791648750360308885314476597252960362792450860609699839"), // q new BigInteger("7fffffffffffffffffffffff7fffffffffff8000000000007ffffffffffc", 16), // a new BigInteger("6b016c3bdcf18941d0d654921475ca71a9db2fb27d1d37796185c2942c0a", 16)); // b ECParameterSpec spec = new ECParameterSpec( curve, curve.decodePoint(Hex.decode("020ffa963cdca8816ccc33b8642bedf905c3d358573d3f27fbbd3b3cb9aaaf")), // G new BigInteger("883423532389192164791648750360308884807550341691627752275345424702807307")); // n ECPrivateKeySpec privKeySpec = new ECPrivateKeySpec( new BigInteger("876300101507107567501066130761671078357010671067781776716671676178726717"), // d spec); ECPublicKeySpec pubKeySpec = new ECPublicKeySpec( curve.decodePoint(Hex.decode("025b6dc53bc61a2548ffb0f671472de6c9521a9d2d2534e65abfcbd5fe0c70")), // Q spec); // // set up the keys // PrivateKey privKey; PublicKey pubKey; try { KeyFactory fact = KeyFactory.getInstance("ECDSA", BC); privKey = fact.generatePrivate(privKeySpec); pubKey = fact.generatePublic(pubKeySpec); } catch (Exception e) { fail("error setting up keys - " + e.toString()); return; } // // distinguished name table. // X500NameBuilder builder = createStdBuilder(); // // toString test // X500Name p = builder.build(); String s = p.toString(); if (!s.equals("C=AU,O=The Legion of the Bouncy Castle,L=Melbourne,ST=Victoria,E=feedback-crypto@bouncycastle.org")) { fail("ordered X509Principal test failed - s = " + s + "."); } // p = new X509Principal(attrs); // s = p.toString(); // // // // // we need two of these as the hash code for strings changed... // // // if (!s.equals("O=The Legion of the Bouncy Castle,E=feedback-crypto@bouncycastle.org,ST=Victoria,L=Melbourne,C=AU") && !s.equals("ST=Victoria,L=Melbourne,C=AU,E=feedback-crypto@bouncycastle.org,O=The Legion of the Bouncy Castle")) // { // fail("unordered X509Principal test failed."); // } // // create the certificate - version 3 // try { ContentSigner sigGen = new JcaContentSignerBuilder("SHA1withECDSA").setProvider(BC).build(privKey); JcaX509v3CertificateBuilder certGen = new JcaX509v3CertificateBuilder(builder.build(),BigInteger.valueOf(1),new Date(System.currentTimeMillis() - 50000),new Date(System.currentTimeMillis() + 50000),builder.build(),pubKey); X509Certificate cert = new JcaX509CertificateConverter().setProvider(BC).getCertificate(certGen.build(sigGen)); cert.checkValidity(new Date()); cert.verify(pubKey); ByteArrayInputStream bIn = new ByteArrayInputStream(cert.getEncoded()); CertificateFactory fact = CertificateFactory.getInstance("X.509", BC); cert = (X509Certificate)fact.generateCertificate(bIn); // // try with point compression turned off // ((ECPointEncoder)pubKey).setPointFormat("UNCOMPRESSED"); certGen = new JcaX509v3CertificateBuilder(builder.build(),BigInteger.valueOf(1),new Date(System.currentTimeMillis() - 50000),new Date(System.currentTimeMillis() + 50000),builder.build(),pubKey); cert = new JcaX509CertificateConverter().setProvider(BC).getCertificate(certGen.build(sigGen)); cert.checkValidity(new Date()); cert.verify(pubKey); bIn = new ByteArrayInputStream(cert.getEncoded()); fact = CertificateFactory.getInstance("X.509", BC); cert = (X509Certificate)fact.generateCertificate(bIn); // System.out.println(cert); } catch (Exception e) { fail("error setting generating cert - " + e.toString()); } X509Principal pr = new X509Principal("O=\"The Bouncy Castle, The Legion of\",E=feedback-crypto@bouncycastle.org,ST=Victoria,L=Melbourne,C=AU"); if (!pr.toString().equals("O=The Bouncy Castle\\, The Legion of,E=feedback-crypto@bouncycastle.org,ST=Victoria,L=Melbourne,C=AU")) { fail("string based X509Principal test failed."); } pr = new X509Principal("O=The Bouncy Castle\\, The Legion of,E=feedback-crypto@bouncycastle.org,ST=Victoria,L=Melbourne,C=AU"); if (!pr.toString().equals("O=The Bouncy Castle\\, The Legion of,E=feedback-crypto@bouncycastle.org,ST=Victoria,L=Melbourne,C=AU")) { fail("string based X509Principal test failed."); } } /** * we generate a self signed certificate for the sake of testing - SHA224withECDSA */ private void createECCert(String algorithm, DERObjectIdentifier algOid) throws Exception { ECCurve.Fp curve = new ECCurve.Fp( new BigInteger("6864797660130609714981900799081393217269435300143305409394463459185543183397656052122559640661454554977296311391480858037121987999716643812574028291115057151"), // q (or p) new BigInteger("01FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFC", 16), // a new BigInteger("0051953EB9618E1C9A1F929A21A0B68540EEA2DA725B99B315F3B8B489918EF109E156193951EC7E937B1652C0BD3BB1BF073573DF883D2C34F1EF451FD46B503F00", 16)); // b ECParameterSpec spec = new ECParameterSpec( curve, curve.decodePoint(Hex.decode("0200C6858E06B70404E9CD9E3ECB662395B4429C648139053FB521F828AF606B4D3DBAA14B5E77EFE75928FE1DC127A2FFA8DE3348B3C1856A429BF97E7E31C2E5BD66")), // G new BigInteger("01FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFA51868783BF2F966B7FCC0148F709A5D03BB5C9B8899C47AEBB6FB71E91386409", 16)); // n ECPrivateKeySpec privKeySpec = new ECPrivateKeySpec( new BigInteger("5769183828869504557786041598510887460263120754767955773309066354712783118202294874205844512909370791582896372147797293913785865682804434049019366394746072023"), // d spec); ECPublicKeySpec pubKeySpec = new ECPublicKeySpec( curve.decodePoint(Hex.decode("02006BFDD2C9278B63C92D6624F151C9D7A822CC75BD983B17D25D74C26740380022D3D8FAF304781E416175EADF4ED6E2B47142D2454A7AC7801DD803CF44A4D1F0AC")), // Q spec); // // set up the keys // PrivateKey privKey; PublicKey pubKey; KeyFactory fact = KeyFactory.getInstance("ECDSA", BC); privKey = fact.generatePrivate(privKeySpec); pubKey = fact.generatePublic(pubKeySpec); // // distinguished name table. // X500NameBuilder builder = createStdBuilder(); // // create the certificate - version 3 // ContentSigner sigGen = new JcaContentSignerBuilder(algorithm).setProvider(BC).build(privKey); X509v3CertificateBuilder certGen = new JcaX509v3CertificateBuilder(builder.build(),BigInteger.valueOf(1),new Date(System.currentTimeMillis() - 50000),new Date(System.currentTimeMillis() + 50000),builder.build(),pubKey); X509Certificate cert = new JcaX509CertificateConverter().setProvider(BC).getCertificate(certGen.build(sigGen)); cert.checkValidity(new Date()); cert.verify(pubKey); ByteArrayInputStream bIn = new ByteArrayInputStream(cert.getEncoded()); CertificateFactory certFact = CertificateFactory.getInstance("X.509", BC); cert = (X509Certificate)certFact.generateCertificate(bIn); // // try with point compression turned off // ((ECPointEncoder)pubKey).setPointFormat("UNCOMPRESSED"); certGen = new JcaX509v3CertificateBuilder(builder.build(),BigInteger.valueOf(1),new Date(System.currentTimeMillis() - 50000),new Date(System.currentTimeMillis() + 50000),builder.build(),pubKey); cert = new JcaX509CertificateConverter().setProvider(BC).getCertificate(certGen.build(sigGen)); cert.checkValidity(new Date()); cert.verify(pubKey); bIn = new ByteArrayInputStream(cert.getEncoded()); certFact = CertificateFactory.getInstance("X.509", BC); cert = (X509Certificate)certFact.generateCertificate(bIn); if (!cert.getSigAlgOID().equals(algOid.toString())) { fail("ECDSA oid incorrect."); } if (cert.getSigAlgParams() != null) { fail("sig parameters present"); } Signature sig = Signature.getInstance(algorithm, BC); sig.initVerify(pubKey); sig.update(cert.getTBSCertificate()); if (!sig.verify(cert.getSignature())) { fail("EC certificate signature not mapped correctly."); } // System.out.println(cert); } private void checkCRL( int id, byte[] bytes) { ByteArrayInputStream bIn; String dump = ""; try { bIn = new ByteArrayInputStream(bytes); CertificateFactory fact = CertificateFactory.getInstance("X.509", BC); CRL cert = fact.generateCRL(bIn); // System.out.println(cert); } catch (Exception e) { fail(dump + System.getProperty("line.separator") + getName() + ": "+ id + " failed - exception " + e.toString(), e); } } public void checkCRLCreation1() throws Exception { KeyPairGenerator kpGen = KeyPairGenerator.getInstance("RSA", BC); Date now = new Date(); KeyPair pair = kpGen.generateKeyPair(); X509v2CRLBuilder crlGen = new X509v2CRLBuilder(new X500Name("CN=Test CA"), now); crlGen.setNextUpdate(new Date(now.getTime() + 100000)); crlGen.addCRLEntry(BigInteger.ONE, now, CRLReason.privilegeWithdrawn); crlGen.addExtension(X509Extensions.AuthorityKeyIdentifier, false, new AuthorityKeyIdentifierStructure(pair.getPublic())); X509CRLHolder crl = crlGen.build(new JcaContentSignerBuilder("SHA256withRSAEncryption").setProvider(BC).build(pair.getPrivate())); if (!crl.getIssuer().equals(new X500Name("CN=Test CA"))) { fail("failed CRL issuer test"); } Extension authExt = crl.getExtension(Extension.authorityKeyIdentifier); if (authExt == null) { fail("failed to find CRL extension"); } AuthorityKeyIdentifier authId = new AuthorityKeyIdentifierStructure(authExt); X509CRLEntryHolder entry = crl.getRevokedCertificate(BigInteger.ONE); if (entry == null) { fail("failed to find CRL entry"); } if (!entry.getSerialNumber().equals(BigInteger.ONE)) { fail("CRL cert serial number does not match"); } if (!entry.hasExtensions()) { fail("CRL entry extension not found"); } Extension ext = entry.getExtension(X509Extension.reasonCode); if (ext != null) { ASN1Enumerated reasonCode = (ASN1Enumerated)ASN1Enumerated.getInstance(ext.getParsedValue()); if (reasonCode.getValue().intValue() != CRLReason.privilegeWithdrawn) { fail("CRL entry reasonCode wrong"); } } else { fail("CRL entry reasonCode not found"); } } public void checkCRLCreation2() throws Exception { KeyPairGenerator kpGen = KeyPairGenerator.getInstance("RSA", BC); Date now = new Date(); KeyPair pair = kpGen.generateKeyPair(); X509v2CRLBuilder crlGen = new JcaX509v2CRLBuilder(new X500Principal("CN=Test CA"), now); crlGen.setNextUpdate(new Date(now.getTime() + 100000)); Vector extOids = new Vector(); Vector extValues = new Vector(); CRLReason crlReason = CRLReason.lookup(CRLReason.privilegeWithdrawn); try { extOids.addElement(X509Extensions.ReasonCode); extValues.addElement(new X509Extension(false, new DEROctetString(crlReason.getEncoded()))); } catch (IOException e) { throw new IllegalArgumentException("error encoding reason: " + e); } X509Extensions entryExtensions = new X509Extensions(extOids, extValues); crlGen.addCRLEntry(BigInteger.ONE, now, entryExtensions); crlGen.addExtension(X509Extensions.AuthorityKeyIdentifier, false, new AuthorityKeyIdentifierStructure(pair.getPublic())); X509CRLHolder crlHolder = crlGen.build(new JcaContentSignerBuilder("SHA256withRSAEncryption").setProvider(BC).build(pair.getPrivate())); X509CRL crl = new JcaX509CRLConverter().setProvider(BC).getCRL(crlHolder); if (!crl.getIssuerX500Principal().equals(new X500Principal("CN=Test CA"))) { fail("failed CRL issuer test"); } byte[] authExt = crl.getExtensionValue(X509Extensions.AuthorityKeyIdentifier.getId()); if (authExt == null) { fail("failed to find CRL extension"); } AuthorityKeyIdentifier authId = new AuthorityKeyIdentifierStructure(authExt); X509CRLEntry entry = crl.getRevokedCertificate(BigInteger.ONE); if (entry == null) { fail("failed to find CRL entry"); } if (!entry.getSerialNumber().equals(BigInteger.ONE)) { fail("CRL cert serial number does not match"); } if (!entry.hasExtensions()) { fail("CRL entry extension not found"); } byte[] ext = entry.getExtensionValue(X509Extensions.ReasonCode.getId()); if (ext != null) { DEREnumerated reasonCode = (DEREnumerated)X509ExtensionUtil.fromExtensionValue(ext); if (reasonCode.getValue().intValue() != CRLReason.privilegeWithdrawn) { fail("CRL entry reasonCode wrong"); } } else { fail("CRL entry reasonCode not found"); } } public void checkCRLCreation3() throws Exception { KeyPairGenerator kpGen = KeyPairGenerator.getInstance("RSA", BC); Date now = new Date(); KeyPair pair = kpGen.generateKeyPair(); X509v2CRLBuilder crlGen = new JcaX509v2CRLBuilder(new X500Principal("CN=Test CA"), now); crlGen.setNextUpdate(new Date(now.getTime() + 100000)); Vector extOids = new Vector(); Vector extValues = new Vector(); CRLReason crlReason = CRLReason.lookup(CRLReason.privilegeWithdrawn); try { extOids.addElement(X509Extensions.ReasonCode); extValues.addElement(new X509Extension(false, new DEROctetString(crlReason.getEncoded()))); } catch (IOException e) { throw new IllegalArgumentException("error encoding reason: " + e); } X509Extensions entryExtensions = new X509Extensions(extOids, extValues); crlGen.addCRLEntry(BigInteger.ONE, now, entryExtensions); crlGen.addExtension(X509Extensions.AuthorityKeyIdentifier, false, new AuthorityKeyIdentifierStructure(pair.getPublic())); X509CRLHolder crlHolder = crlGen.build(new JcaContentSignerBuilder("SHA256withRSAEncryption").setProvider(BC).build(pair.getPrivate())); X509CRL crl = new JcaX509CRLConverter().setProvider(BC).getCRL(crlHolder); if (!crl.getIssuerX500Principal().equals(new X500Principal("CN=Test CA"))) { fail("failed CRL issuer test"); } byte[] authExt = crl.getExtensionValue(X509Extensions.AuthorityKeyIdentifier.getId()); if (authExt == null) { fail("failed to find CRL extension"); } AuthorityKeyIdentifier authId = new AuthorityKeyIdentifierStructure(authExt); X509CRLEntry entry = crl.getRevokedCertificate(BigInteger.ONE); if (entry == null) { fail("failed to find CRL entry"); } if (!entry.getSerialNumber().equals(BigInteger.ONE)) { fail("CRL cert serial number does not match"); } if (!entry.hasExtensions()) { fail("CRL entry extension not found"); } byte[] ext = entry.getExtensionValue(X509Extensions.ReasonCode.getId()); if (ext != null) { DEREnumerated reasonCode = (DEREnumerated)X509ExtensionUtil.fromExtensionValue(ext); if (reasonCode.getValue().intValue() != CRLReason.privilegeWithdrawn) { fail("CRL entry reasonCode wrong"); } } else { fail("CRL entry reasonCode not found"); } // // check loading of existing CRL // now = new Date(); crlGen = new X509v2CRLBuilder(new X500Name("CN=Test CA"), now); crlGen.setNextUpdate(new Date(now.getTime() + 100000)); crlGen.addCRL(new JcaX509CRLHolder(crl)); crlGen.addCRLEntry(BigInteger.valueOf(2), now, entryExtensions); crlGen.addExtension(X509Extension.authorityKeyIdentifier, false, new AuthorityKeyIdentifierStructure(pair.getPublic())); crlHolder = crlGen.build(new JcaContentSignerBuilder("SHA256withRSAEncryption").setProvider(BC).build(pair.getPrivate())); int count = 0; boolean oneFound = false; boolean twoFound = false; Iterator it = crlHolder.getRevokedCertificates().iterator(); while (it.hasNext()) { X509CRLEntryHolder crlEnt = (X509CRLEntryHolder)it.next(); if (crlEnt.getSerialNumber().intValue() == 1) { oneFound = true; Extension extn = crlEnt.getExtension(X509Extension.reasonCode); if (extn != null) { ASN1Enumerated reasonCode = (ASN1Enumerated)ASN1Enumerated.getInstance(extn.getParsedValue()); if (reasonCode.getValue().intValue() != CRLReason.privilegeWithdrawn) { fail("CRL entry reasonCode wrong"); } } else { fail("CRL entry reasonCode not found"); } } else if (crlEnt.getSerialNumber().intValue() == 2) { twoFound = true; } count++; } if (count != 2) { fail("wrong number of CRLs found"); } if (!oneFound || !twoFound) { fail("wrong CRLs found in copied list"); } // // check factory read back // CertificateFactory cFact = CertificateFactory.getInstance("X.509", BC); X509CRL readCrl = (X509CRL)cFact.generateCRL(new ByteArrayInputStream(crlHolder.getEncoded())); if (readCrl == null) { fail("crl not returned!"); } Collection col = cFact.generateCRLs(new ByteArrayInputStream(crlHolder.getEncoded())); if (col.size() != 1) { fail("wrong number of CRLs found in collection"); } } /** * we generate a self signed certificate for the sake of testing - GOST3410 */ public void checkCreation4() throws Exception { // // set up the keys // PrivateKey privKey; PublicKey pubKey; KeyPairGenerator g = KeyPairGenerator.getInstance("GOST3410", BC); GOST3410ParameterSpec gost3410P = new GOST3410ParameterSpec("GostR3410-94-CryptoPro-A"); g.initialize(gost3410P, new SecureRandom()); KeyPair p = g.generateKeyPair(); privKey = p.getPrivate(); pubKey = p.getPublic(); // // distinguished name table. // X500NameBuilder builder = createStdBuilder(); // // extensions // // // create the certificate - version 3 // ContentSigner sigGen = new JcaContentSignerBuilder("GOST3411withGOST3410").setProvider(BC).build(privKey); X509v3CertificateBuilder certGen = new JcaX509v3CertificateBuilder(builder.build(),BigInteger.valueOf(1),new Date(System.currentTimeMillis() - 50000),new Date(System.currentTimeMillis() + 50000),builder.build(),pubKey); X509Certificate cert = new JcaX509CertificateConverter().setProvider(BC).getCertificate(certGen.build(sigGen)); cert.checkValidity(new Date()); // // check verifies in general // cert.verify(pubKey); // // check verifies with contained key // cert.verify(cert.getPublicKey()); ByteArrayInputStream bIn = new ByteArrayInputStream(cert.getEncoded()); CertificateFactory fact = CertificateFactory.getInstance("X.509", BC); cert = (X509Certificate)fact.generateCertificate(bIn); //System.out.println(cert); //check getEncoded() byte[] bytes = cert.getEncoded(); } public void checkCreation5() throws Exception { // // a sample key pair. // RSAPublicKeySpec pubKeySpec = new RSAPublicKeySpec( new BigInteger("b4a7e46170574f16a97082b22be58b6a2a629798419be12872a4bdba626cfae9900f76abfb12139dce5de56564fab2b6543165a040c606887420e33d91ed7ed7", 16), new BigInteger("11", 16)); RSAPrivateCrtKeySpec privKeySpec = new RSAPrivateCrtKeySpec( new BigInteger("b4a7e46170574f16a97082b22be58b6a2a629798419be12872a4bdba626cfae9900f76abfb12139dce5de56564fab2b6543165a040c606887420e33d91ed7ed7", 16), new BigInteger("11", 16), new BigInteger("9f66f6b05410cd503b2709e88115d55daced94d1a34d4e32bf824d0dde6028ae79c5f07b580f5dce240d7111f7ddb130a7945cd7d957d1920994da389f490c89", 16), new BigInteger("c0a0758cdf14256f78d4708c86becdead1b50ad4ad6c5c703e2168fbf37884cb", 16), new BigInteger("f01734d7960ea60070f1b06f2bb81bfac48ff192ae18451d5e56c734a5aab8a5", 16), new BigInteger("b54bb9edff22051d9ee60f9351a48591b6500a319429c069a3e335a1d6171391", 16), new BigInteger("d3d83daf2a0cecd3367ae6f8ae1aeb82e9ac2f816c6fc483533d8297dd7884cd", 16), new BigInteger("b8f52fc6f38593dabb661d3f50f8897f8106eee68b1bce78a95b132b4e5b5d19", 16)); // // set up the keys // SecureRandom rand = new SecureRandom(); PrivateKey privKey; PublicKey pubKey; KeyFactory fact = KeyFactory.getInstance("RSA", BC); privKey = fact.generatePrivate(privKeySpec); pubKey = fact.generatePublic(pubKeySpec); // // distinguished name table. // Vector ord = new Vector(); Vector values = new Vector(); X500NameBuilder builder = createStdBuilder(); // // create base certificate - version 3 // ContentSigner sigGen = new JcaContentSignerBuilder("MD5WithRSAEncryption").setProvider(BC).build(privKey); X509v3CertificateBuilder certGen = new JcaX509v3CertificateBuilder(builder.build(),BigInteger.valueOf(1),new Date(System.currentTimeMillis() - 50000),new Date(System.currentTimeMillis() + 50000),builder.build(),pubKey) .addExtension(new ASN1ObjectIdentifier("2.5.29.15"), true, new X509KeyUsage(X509KeyUsage.encipherOnly)) .addExtension(new ASN1ObjectIdentifier("2.5.29.37"), true, new DERSequence(KeyPurposeId.anyExtendedKeyUsage)) .addExtension(new ASN1ObjectIdentifier("2.5.29.17"), true, new GeneralNames(new GeneralName(GeneralName.rfc822Name, "test@test.test"))); X509Certificate baseCert = new JcaX509CertificateConverter().setProvider(BC).getCertificate(certGen.build(sigGen)); // // copy certificate // certGen = new JcaX509v3CertificateBuilder(builder.build(),BigInteger.valueOf(1),new Date(System.currentTimeMillis() - 50000),new Date(System.currentTimeMillis() + 50000),builder.build(),pubKey) .copyAndAddExtension(new ASN1ObjectIdentifier("2.5.29.15"), true, baseCert) .copyAndAddExtension(new ASN1ObjectIdentifier("2.5.29.37"), false, baseCert); X509Certificate cert = new JcaX509CertificateConverter().setProvider(BC).getCertificate(certGen.build(sigGen)); cert.checkValidity(new Date()); cert.verify(pubKey); if (!areEqual(baseCert.getExtensionValue("2.5.29.15"), cert.getExtensionValue("2.5.29.15"))) { fail("2.5.29.15 differs"); } if (!areEqual(baseCert.getExtensionValue("2.5.29.37"), cert.getExtensionValue("2.5.29.37"))) { fail("2.5.29.37 differs"); } // // exception test // try { certGen.copyAndAddExtension(new ASN1ObjectIdentifier("2.5.99.99"), true, new JcaX509CertificateHolder(baseCert)); fail("exception not thrown on dud extension copy"); } catch (NullPointerException e) { // expected } // try // { // certGen.setPublicKey(dudPublicKey); // // certGen.generate(privKey, BC); // // fail("key without encoding not detected in v3"); // } // catch (IllegalArgumentException e) // { // // expected // } } private void testForgedSignature() throws Exception { String cert = "MIIBsDCCAVoCAQYwDQYJKoZIhvcNAQEFBQAwYzELMAkGA1UEBhMCQVUxEzARBgNV" + "BAgTClF1ZWVuc2xhbmQxGjAYBgNVBAoTEUNyeXB0U29mdCBQdHkgTHRkMSMwIQYD" + "VQQDExpTZXJ2ZXIgdGVzdCBjZXJ0ICg1MTIgYml0KTAeFw0wNjA5MTEyMzU4NTVa" + "Fw0wNjEwMTEyMzU4NTVaMGMxCzAJBgNVBAYTAkFVMRMwEQYDVQQIEwpRdWVlbnNs" + "YW5kMRowGAYDVQQKExFDcnlwdFNvZnQgUHR5IEx0ZDEjMCEGA1UEAxMaU2VydmVy" + "IHRlc3QgY2VydCAoNTEyIGJpdCkwXDANBgkqhkiG9w0BAQEFAANLADBIAkEAn7PD" + "hCeV/xIxUg8V70YRxK2A5jZbD92A12GN4PxyRQk0/lVmRUNMaJdq/qigpd9feP/u" + "12S4PwTLb/8q/v657QIDAQABMA0GCSqGSIb3DQEBBQUAA0EAbynCRIlUQgaqyNgU" + "DF6P14yRKUtX8akOP2TwStaSiVf/akYqfLFm3UGka5XbPj4rifrZ0/sOoZEEBvHQ" + "e20sRA=="; CertificateFactory certFact = CertificateFactory.getInstance("X.509", BC); X509Certificate x509 = (X509Certificate)certFact.generateCertificate(new ByteArrayInputStream(Base64.decode(cert))); try { x509.verify(x509.getPublicKey()); fail("forged RSA signature passed"); } catch (Exception e) { // expected } } private void pemTest() throws Exception { CertificateFactory cf = CertificateFactory.getInstance("X.509", BC); Certificate cert = readPEMCert(cf, PEMData.CERTIFICATE_1); if (cert == null) { fail("PEM cert not read"); } cert = readPEMCert(cf, "-----BEGIN CERTIFICATE-----" + PEMData.CERTIFICATE_2); if (cert == null) { fail("PEM cert with extraneous header not read"); } CRL crl = cf.generateCRL(new ByteArrayInputStream(PEMData.CRL_1.getBytes("US-ASCII"))); if (crl == null) { fail("PEM crl not read"); } Collection col = cf.generateCertificates(new ByteArrayInputStream(PEMData.CERTIFICATE_2.getBytes("US-ASCII"))); if (col.size() != 1 || !col.contains(cert)) { fail("PEM cert collection not right"); } col = cf.generateCRLs(new ByteArrayInputStream(PEMData.CRL_2.getBytes("US-ASCII"))); if (col.size() != 1 || !col.contains(crl)) { fail("PEM crl collection not right"); } } private static Certificate readPEMCert(CertificateFactory cf, String pemData) throws CertificateException, UnsupportedEncodingException { return cf.generateCertificate(new ByteArrayInputStream(pemData.getBytes("US-ASCII"))); } private void pkcs7Test() throws Exception { /* ASN1EncodableVector certs = new ASN1EncodableVector(); certs.add(new ASN1InputStream(CertPathTest.rootCertBin).readObject()); certs.add(new DERTaggedObject(false, 2, new ASN1InputStream(AttrCertTest.attrCert).readObject())); ASN1EncodableVector crls = new ASN1EncodableVector(); crls.add(new ASN1InputStream(CertPathTest.rootCrlBin).readObject()); SignedData sigData = new SignedData(new DERSet(), new ContentInfo(CMSObjectIdentifiers.data, null), new DERSet(certs), new DERSet(crls), new DERSet()); ContentInfo info = new ContentInfo(CMSObjectIdentifiers.signedData, sigData); CertificateFactory cf = CertificateFactory.getInstance("X.509", BC); X509Certificate cert = (X509Certificate)cf.generateCertificate(new ByteArrayInputStream(info.getEncoded())); if (cert == null || !areEqual(cert.getEncoded(), certs.get(0).getDERObject().getEncoded())) { fail("PKCS7 cert not read"); } X509CRL crl = (X509CRL)cf.generateCRL(new ByteArrayInputStream(info.getEncoded())); if (crl == null || !areEqual(crl.getEncoded(), crls.get(0).getDERObject().getEncoded())) { fail("PKCS7 crl not read"); } Collection col = cf.generateCertificates(new ByteArrayInputStream(info.getEncoded())); if (col.size() != 1 || !col.contains(cert)) { fail("PKCS7 cert collection not right"); } col = cf.generateCRLs(new ByteArrayInputStream(info.getEncoded())); if (col.size() != 1 || !col.contains(crl)) { fail("PKCS7 crl collection not right"); } // data with no certificates or CRLs sigData = new SignedData(new DERSet(), new ContentInfo(CMSObjectIdentifiers.data, null), new DERSet(), new DERSet(), new DERSet()); info = new ContentInfo(CMSObjectIdentifiers.signedData, sigData); cert = (X509Certificate)cf.generateCertificate(new ByteArrayInputStream(info.getEncoded())); if (cert != null) { fail("PKCS7 cert present"); } crl = (X509CRL)cf.generateCRL(new ByteArrayInputStream(info.getEncoded())); if (crl != null) { fail("PKCS7 crl present"); } // data with absent certificates and CRLS sigData = new SignedData(new DERSet(), new ContentInfo(CMSObjectIdentifiers.data, null), null, null, new DERSet()); info = new ContentInfo(CMSObjectIdentifiers.signedData, sigData); cert = (X509Certificate)cf.generateCertificate(new ByteArrayInputStream(info.getEncoded())); if (cert != null) { fail("PKCS7 cert present"); } crl = (X509CRL)cf.generateCRL(new ByteArrayInputStream(info.getEncoded())); if (crl != null) { fail("PKCS7 crl present"); } // // sample message // InputStream in = new ByteArrayInputStream(pkcs7CrlProblem); Collection certCol = cf.generateCertificates(in); Collection crlCol = cf.generateCRLs(in); if (crlCol.size() != 0) { fail("wrong number of CRLs: " + crlCol.size()); } if (certCol.size() != 4) { fail("wrong number of Certs: " + certCol.size()); } */ } private void createPSSCert(String algorithm) throws Exception { KeyPair pair = generateLongFixedKeys(); PrivateKey privKey = pair.getPrivate(); PublicKey pubKey = pair.getPublic(); // // distinguished name table. // X500NameBuilder builder = createStdBuilder(); // // create base certificate - version 3 // ContentSigner sigGen = new JcaContentSignerBuilder(algorithm).setProvider(BC).build(privKey); JcaX509v3CertificateBuilder certGen = new JcaX509v3CertificateBuilder(builder.build(),BigInteger.valueOf(1), new Date(System.currentTimeMillis() - 50000),new Date(System.currentTimeMillis() + 50000),builder.build(),pubKey); certGen.addExtension(new ASN1ObjectIdentifier("2.5.29.15"), true, new X509KeyUsage(X509KeyUsage.encipherOnly)); certGen.addExtension(new ASN1ObjectIdentifier("2.5.29.37"), true, new DERSequence(KeyPurposeId.anyExtendedKeyUsage)); certGen.addExtension(new ASN1ObjectIdentifier("2.5.29.17"), true, new GeneralNames(new GeneralName(GeneralName.rfc822Name, "test@test.test"))); X509Certificate baseCert = new JcaX509CertificateConverter().setProvider(BC).getCertificate(certGen.build(sigGen)); baseCert.verify(pubKey); } private KeyPair generateLongFixedKeys() throws NoSuchAlgorithmException, NoSuchProviderException, InvalidKeySpecException { RSAPublicKeySpec pubKeySpec = new RSAPublicKeySpec( new BigInteger("a56e4a0e701017589a5187dc7ea841d156f2ec0e36ad52a44dfeb1e61f7ad991d8c51056ffedb162b4c0f283a12a88a394dff526ab7291cbb307ceabfce0b1dfd5cd9508096d5b2b8b6df5d671ef6377c0921cb23c270a70e2598e6ff89d19f105acc2d3f0cb35f29280e1386b6f64c4ef22e1e1f20d0ce8cffb2249bd9a2137",16), new BigInteger("010001",16)); RSAPrivateCrtKeySpec privKeySpec = new RSAPrivateCrtKeySpec( new BigInteger("a56e4a0e701017589a5187dc7ea841d156f2ec0e36ad52a44dfeb1e61f7ad991d8c51056ffedb162b4c0f283a12a88a394dff526ab7291cbb307ceabfce0b1dfd5cd9508096d5b2b8b6df5d671ef6377c0921cb23c270a70e2598e6ff89d19f105acc2d3f0cb35f29280e1386b6f64c4ef22e1e1f20d0ce8cffb2249bd9a2137",16), new BigInteger("010001",16), new BigInteger("33a5042a90b27d4f5451ca9bbbd0b44771a101af884340aef9885f2a4bbe92e894a724ac3c568c8f97853ad07c0266c8c6a3ca0929f1e8f11231884429fc4d9ae55fee896a10ce707c3ed7e734e44727a39574501a532683109c2abacaba283c31b4bd2f53c3ee37e352cee34f9e503bd80c0622ad79c6dcee883547c6a3b325",16), new BigInteger("e7e8942720a877517273a356053ea2a1bc0c94aa72d55c6e86296b2dfc967948c0a72cbccca7eacb35706e09a1df55a1535bd9b3cc34160b3b6dcd3eda8e6443",16), new BigInteger("b69dca1cf7d4d7ec81e75b90fcca874abcde123fd2700180aa90479b6e48de8d67ed24f9f19d85ba275874f542cd20dc723e6963364a1f9425452b269a6799fd",16), new BigInteger("28fa13938655be1f8a159cbaca5a72ea190c30089e19cd274a556f36c4f6e19f554b34c077790427bbdd8dd3ede2448328f385d81b30e8e43b2fffa027861979",16), new BigInteger("1a8b38f398fa712049898d7fb79ee0a77668791299cdfa09efc0e507acb21ed74301ef5bfd48be455eaeb6e1678255827580a8e4e8e14151d1510a82a3f2e729",16), new BigInteger("27156aba4126d24a81f3a528cbfb27f56886f840a9f6e86e17a44b94fe9319584b8e22fdde1e5a2e3bd8aa5ba8d8584194eb2190acf832b847f13a3d24a79f4d",16)); KeyFactory fact = KeyFactory.getInstance("RSA", BC); return new KeyPair(fact.generatePublic(pubKeySpec), fact.generatePrivate(privKeySpec)); } private void rfc4491Test() throws Exception { CertificateFactory certFact = CertificateFactory.getInstance("X.509", BC); X509Certificate x509 = (X509Certificate)certFact.generateCertificate(new ByteArrayInputStream(gostRFC4491_94)); x509.verify(x509.getPublicKey(), BC); x509 = (X509Certificate)certFact.generateCertificate(new ByteArrayInputStream(gostRFC4491_2001)); x509.verify(x509.getPublicKey(), BC); } private void testNullDerNullCert() throws Exception { KeyPair pair = generateLongFixedKeys(); PublicKey pubKey = pair.getPublic(); PrivateKey privKey = pair.getPrivate(); ContentSigner sigGen = new JcaContentSignerBuilder("MD5WithRSAEncryption").setProvider(BC).build(privKey); JcaX509v3CertificateBuilder certGen = new JcaX509v3CertificateBuilder(new X500Name("CN=Test"),BigInteger.valueOf(1),new Date(System.currentTimeMillis() - 50000),new Date(System.currentTimeMillis() + 50000),new X500Name("CN=Test"),pubKey); X509Certificate cert = new JcaX509CertificateConverter().setProvider(BC).getCertificate(certGen.build(sigGen)); X509CertificateStructure struct = X509CertificateStructure.getInstance(ASN1Primitive.fromByteArray(cert.getEncoded())); ASN1Encodable tbsCertificate = struct.getTBSCertificate(); AlgorithmIdentifier sig = struct.getSignatureAlgorithm(); ASN1EncodableVector v = new ASN1EncodableVector(); v.add(tbsCertificate); v.add(new AlgorithmIdentifier(sig.getAlgorithm())); v.add(struct.getSignature()); // verify ByteArrayInputStream bIn; String dump = ""; try { bIn = new ByteArrayInputStream(new DERSequence(v).getEncoded()); CertificateFactory fact = CertificateFactory.getInstance("X.509", BC); cert = (X509Certificate)fact.generateCertificate(bIn); cert.verify(cert.getPublicKey()); } catch (Exception e) { fail(dump + System.getProperty("line.separator") + getName() + ": testNullDerNull failed - exception " + e.toString(), e); } } private void testDirect() throws Exception { KeyStore keyStore = KeyStore.getInstance("PKCS12", "BC"); ByteArrayInputStream input = new ByteArrayInputStream(testCAp12); keyStore.load(input, "test".toCharArray()); X509Certificate certificate = (X509Certificate) keyStore.getCertificate("ca"); PrivateKey privateKey = (PrivateKey) keyStore.getKey("ca", null); X500Name issuer = X500Name.getInstance(certificate.getIssuerX500Principal().getEncoded()); X509v2CRLBuilder builder = new X509v2CRLBuilder(issuer, new Date()); builder.addCRLEntry(certificate.getSerialNumber(), new Date(), CRLReason.cACompromise); JcaContentSignerBuilder contentSignerBuilder = new JcaContentSignerBuilder("SHA256WithRSAEncryption"); contentSignerBuilder.setProvider("BC"); X509CRLHolder cRLHolder = builder.build(contentSignerBuilder.build(privateKey)); if (!cRLHolder.isSignatureValid(new JcaContentVerifierProviderBuilder().setProvider("BC").build(certificate))) { fail("CRL signature not valid"); } X509CRLEntryHolder cRLEntryHolder = cRLHolder.getRevokedCertificate(certificate.getSerialNumber()); if (!cRLEntryHolder.getCertificateIssuer().equals(new GeneralNames(new GeneralName(cRLHolder.getIssuer())))) { fail("certificate issuer incorrect"); } JcaX509CRLConverter converter = new JcaX509CRLConverter(); converter.setProvider("BC"); X509CRL crl = converter.getCRL(cRLHolder); crl.verify(certificate.getPublicKey()); if (!crl.isRevoked(certificate)) { fail("Certificate should be revoked"); } // now encode the CRL and load the CRL with the JCE provider CertificateFactory fac = CertificateFactory.getInstance("X.509"); X509CRL jceCRL = (X509CRL) fac.generateCRL(new ByteArrayInputStream(crl.getEncoded())); jceCRL.verify(certificate.getPublicKey()); if (!jceCRL.isRevoked(certificate)) { fail("This certificate should also be revoked"); } } private void testIndirect() throws Exception { KeyStore keyStore = KeyStore.getInstance("PKCS12", "BC"); ByteArrayInputStream input = new ByteArrayInputStream(testCAp12); keyStore.load(input, "test".toCharArray()); X509Certificate certificate = (X509Certificate) keyStore.getCertificate("ca"); PrivateKey privateKey = (PrivateKey) keyStore.getKey("ca", null); X500Name crlIssuer = X500Name.getInstance(certificate.getSubjectX500Principal().getEncoded()); X500Name caName = X500Name.getInstance(certificate.getIssuerX500Principal().getEncoded()); X509v2CRLBuilder builder = new X509v2CRLBuilder(crlIssuer, new Date()); builder.addExtension(Extension.issuingDistributionPoint, true, new IssuingDistributionPoint(null, true, false)); ExtensionsGenerator extGen = new ExtensionsGenerator(); extGen.addExtension(Extension.reasonCode, false, CRLReason.lookup(CRLReason.cACompromise)); extGen.addExtension(Extension.certificateIssuer, true, new GeneralNames(new GeneralName(caName))); builder.addCRLEntry(certificate.getSerialNumber(), new Date(), extGen.generate()); JcaContentSignerBuilder contentSignerBuilder = new JcaContentSignerBuilder("SHA256WithRSAEncryption"); contentSignerBuilder.setProvider("BC"); X509CRLHolder cRLHolder = builder.build(contentSignerBuilder.build(privateKey)); if (!cRLHolder.isSignatureValid(new JcaContentVerifierProviderBuilder().setProvider("BC").build(certificate))) { fail("CRL signature not valid"); } X509CRLEntryHolder cRLEntryHolder = cRLHolder.getRevokedCertificate(certificate.getSerialNumber()); if (!cRLEntryHolder.getCertificateIssuer().equals(new GeneralNames(new GeneralName(X500Name.getInstance(certificate.getIssuerX500Principal().getEncoded()))))) { fail("certificate issuer incorrect"); } JcaX509CRLConverter converter = new JcaX509CRLConverter(); converter.setProvider("BC"); X509CRL crl = converter.getCRL(cRLHolder); crl.verify(certificate.getPublicKey()); if (!crl.isRevoked(certificate)) { fail("Certificate should be revoked"); } // now encode the CRL and load the CRL with the JCE provider CertificateFactory fac = CertificateFactory.getInstance("X.509"); X509CRL jceCRL = (X509CRL) fac.generateCRL(new ByteArrayInputStream(crl.getEncoded())); jceCRL.verify(certificate.getPublicKey()); if (!jceCRL.isRevoked(certificate)) { fail("This certificate should also be revoked"); } } private void testIndirect2() throws Exception { KeyStore keyStore = KeyStore.getInstance("PKCS12", "BC"); ByteArrayInputStream input = new ByteArrayInputStream(testCAp12); keyStore.load(input, "test".toCharArray()); X509Certificate certificate = (X509Certificate) keyStore.getCertificate("ca"); PrivateKey privateKey = (PrivateKey) keyStore.getKey("ca", null); X500Name crlIssuer = X500Name.getInstance(certificate.getSubjectX500Principal().getEncoded()); X500Name caName = X500Name.getInstance(certificate.getIssuerX500Principal().getEncoded()); X509v2CRLBuilder builder = new X509v2CRLBuilder(crlIssuer, new Date()); builder.addExtension(Extension.issuingDistributionPoint, true, new IssuingDistributionPoint(null, true, false)); builder.addCRLEntry(BigInteger.valueOf(100), new Date(), CRLReason.cACompromise); builder.addCRLEntry(BigInteger.valueOf(120), new Date(), CRLReason.cACompromise); ExtensionsGenerator extGen = new ExtensionsGenerator(); extGen.addExtension(Extension.reasonCode, false, CRLReason.lookup(CRLReason.cACompromise)); extGen.addExtension(Extension.certificateIssuer, true, new GeneralNames(new GeneralName(caName))); builder.addCRLEntry(certificate.getSerialNumber(), new Date(), extGen.generate()); builder.addCRLEntry(BigInteger.valueOf(130), new Date(), CRLReason.cACompromise); JcaContentSignerBuilder contentSignerBuilder = new JcaContentSignerBuilder("SHA256WithRSAEncryption"); contentSignerBuilder.setProvider("BC"); X509CRLHolder cRLHolder = builder.build(contentSignerBuilder.build(privateKey)); if (!cRLHolder.isSignatureValid(new JcaContentVerifierProviderBuilder().setProvider("BC").build(certificate))) { fail("CRL signature not valid"); } X509CRLEntryHolder cRLEntryHolder = cRLHolder.getRevokedCertificate(certificate.getSerialNumber()); if (!cRLEntryHolder.getCertificateIssuer().equals(new GeneralNames(new GeneralName(caName)))) { fail("certificate issuer incorrect"); } cRLEntryHolder = cRLHolder.getRevokedCertificate(BigInteger.valueOf(130)); if (!cRLEntryHolder.getCertificateIssuer().equals(new GeneralNames(new GeneralName(caName)))) { fail("certificate issuer incorrect"); } cRLEntryHolder = cRLHolder.getRevokedCertificate(BigInteger.valueOf(100)); if (!cRLEntryHolder.getCertificateIssuer().equals(new GeneralNames(new GeneralName(cRLHolder.getIssuer())))) { fail("certificate issuer incorrect"); } JcaX509CRLConverter converter = new JcaX509CRLConverter(); converter.setProvider("BC"); X509CRL crl = converter.getCRL(cRLHolder); crl.verify(certificate.getPublicKey()); X509CRLEntry crlEntry = crl.getRevokedCertificate(BigInteger.valueOf(100)); if (crlEntry.getCertificateIssuer() != null) { fail("JCA 1 certificate issuer incorrect"); } crlEntry = crl.getRevokedCertificate(BigInteger.valueOf(130)); if (!crlEntry.getCertificateIssuer().equals(new X500Principal(caName.getEncoded()))) { fail("JCA 2 certificate issuer incorrect"); } } // issuing distribution point must be set for an indirect CRL to be recognised private void testMalformedIndirect() throws Exception { KeyStore keyStore = KeyStore.getInstance("PKCS12", "BC"); ByteArrayInputStream input = new ByteArrayInputStream(testCAp12); keyStore.load(input, "test".toCharArray()); X509Certificate certificate = (X509Certificate) keyStore.getCertificate("ca"); PrivateKey privateKey = (PrivateKey) keyStore.getKey("ca", null); X500Name crlIssuer = X500Name.getInstance(certificate.getSubjectX500Principal().getEncoded()); X500Name caName = X500Name.getInstance(certificate.getIssuerX500Principal().getEncoded()); X509v2CRLBuilder builder = new X509v2CRLBuilder(crlIssuer, new Date()); ExtensionsGenerator extGen = new ExtensionsGenerator(); extGen.addExtension(Extension.reasonCode, false, CRLReason.lookup(CRLReason.cACompromise)); extGen.addExtension(Extension.certificateIssuer, true, new GeneralNames(new GeneralName(caName))); builder.addCRLEntry(certificate.getSerialNumber(), new Date(), extGen.generate()); JcaContentSignerBuilder contentSignerBuilder = new JcaContentSignerBuilder("SHA256WithRSAEncryption"); contentSignerBuilder.setProvider("BC"); X509CRLHolder cRLHolder = builder.build(contentSignerBuilder.build(privateKey)); if (!cRLHolder.isSignatureValid(new JcaContentVerifierProviderBuilder().setProvider("BC").build(certificate))) { fail("CRL signature not valid"); } X509CRLEntryHolder cRLEntryHolder = cRLHolder.getRevokedCertificate(certificate.getSerialNumber()); if (!cRLEntryHolder.getCertificateIssuer().equals(new GeneralNames(new GeneralName(cRLHolder.getIssuer())))) { fail("certificate issuer incorrect"); } JcaX509CRLConverter converter = new JcaX509CRLConverter(); converter.setProvider("BC"); X509CRL crl = converter.getCRL(cRLHolder); crl.verify(certificate.getPublicKey()); if (crl.isRevoked(certificate)) { throw new Exception("Certificate should not be revoked"); } } public void performTest() throws Exception { testDirect(); testIndirect(); testIndirect2(); testMalformedIndirect(); checkCertificate(1, cert1); checkCertificate(2, cert2); checkCertificate(3, cert3); checkCertificate(4, cert4); checkCertificate(5, cert5); checkCertificate(6, oldEcdsa); checkCertificate(7, cert7); checkKeyUsage(8, keyUsage); checkSelfSignedCertificate(9, uncompressedPtEC); checkNameCertificate(10, nameCert); checkSelfSignedCertificate(11, probSelfSignedCert); checkSelfSignedCertificate(12, gostCA1); checkSelfSignedCertificate(13, gostCA2); checkSelfSignedCertificate(14, gost341094base); checkSelfSignedCertificate(15, gost34102001base); checkSelfSignedCertificate(16, gost341094A); checkSelfSignedCertificate(17, gost341094B); checkSelfSignedCertificate(17, gost34102001A); checkCRL(1, crl1); checkCreation1(); checkCreation2(); checkCreation3(); checkCreation4(); checkCreation5(); createECCert("SHA1withECDSA", X9ObjectIdentifiers.ecdsa_with_SHA1); createECCert("SHA224withECDSA", X9ObjectIdentifiers.ecdsa_with_SHA224); createECCert("SHA256withECDSA", X9ObjectIdentifiers.ecdsa_with_SHA256); createECCert("SHA384withECDSA", X9ObjectIdentifiers.ecdsa_with_SHA384); createECCert("SHA512withECDSA", X9ObjectIdentifiers.ecdsa_with_SHA512); createPSSCert("SHA1withRSAandMGF1"); createPSSCert("SHA224withRSAandMGF1"); createPSSCert("SHA256withRSAandMGF1"); createPSSCert("SHA384withRSAandMGF1"); checkCRLCreation1(); checkCRLCreation2(); checkCRLCreation3(); pemTest(); pkcs7Test(); rfc4491Test(); testForgedSignature(); testNullDerNullCert(); checkCertificate(18, emptyDNCert); } public static void main( String[] args) { Security.addProvider(new BouncyCastleProvider()); runTest(new CertTest()); } }bouncycastle-1.49.orig/test/src/org/bouncycastle/cert/test/AttrCertSelectorTest.java0000644000175000017500000002516211731467175030353 0ustar ebourgebourgpackage org.bouncycastle.cert.test; import java.io.ByteArrayInputStream; import java.math.BigInteger; import java.security.KeyFactory; import java.security.PrivateKey; import java.security.Security; import java.security.cert.CertificateFactory; import java.security.cert.X509Certificate; import java.security.spec.RSAPrivateCrtKeySpec; import java.util.Date; import org.bouncycastle.asn1.ASN1EncodableVector; import org.bouncycastle.asn1.ASN1ObjectIdentifier; import org.bouncycastle.asn1.DERSequence; import org.bouncycastle.asn1.x500.X500Name; import org.bouncycastle.asn1.x509.GeneralName; import org.bouncycastle.asn1.x509.Target; import org.bouncycastle.asn1.x509.TargetInformation; import org.bouncycastle.asn1.x509.X509Extension; import org.bouncycastle.cert.AttributeCertificateHolder; import org.bouncycastle.cert.AttributeCertificateIssuer; import org.bouncycastle.cert.X509AttributeCertificateHolder; import org.bouncycastle.cert.X509CertificateHolder; import org.bouncycastle.cert.X509v2AttributeCertificateBuilder; import org.bouncycastle.cert.jcajce.JcaX509CertificateHolder; import org.bouncycastle.cert.selector.X509AttributeCertificateHolderSelectorBuilder; import org.bouncycastle.jce.provider.BouncyCastleProvider; import org.bouncycastle.operator.ContentSigner; import org.bouncycastle.operator.jcajce.JcaContentSignerBuilder; import org.bouncycastle.util.encoders.Base64; import org.bouncycastle.util.test.SimpleTest; import org.bouncycastle.util.test.Test; import org.bouncycastle.util.test.TestResult; public class AttrCertSelectorTest extends SimpleTest { private static final String BC = BouncyCastleProvider.PROVIDER_NAME; static final RSAPrivateCrtKeySpec RSA_PRIVATE_KEY_SPEC = new RSAPrivateCrtKeySpec( new BigInteger( "b4a7e46170574f16a97082b22be58b6a2a629798419be12872a4bdba626cfae9900f76abfb12139dce5de56564fab2b6543165a040c606887420e33d91ed7ed7", 16), new BigInteger("11", 16), new BigInteger( "9f66f6b05410cd503b2709e88115d55daced94d1a34d4e32bf824d0dde6028ae79c5f07b580f5dce240d7111f7ddb130a7945cd7d957d1920994da389f490c89", 16), new BigInteger( "c0a0758cdf14256f78d4708c86becdead1b50ad4ad6c5c703e2168fbf37884cb", 16), new BigInteger( "f01734d7960ea60070f1b06f2bb81bfac48ff192ae18451d5e56c734a5aab8a5", 16), new BigInteger( "b54bb9edff22051d9ee60f9351a48591b6500a319429c069a3e335a1d6171391", 16), new BigInteger( "d3d83daf2a0cecd3367ae6f8ae1aeb82e9ac2f816c6fc483533d8297dd7884cd", 16), new BigInteger( "b8f52fc6f38593dabb661d3f50f8897f8106eee68b1bce78a95b132b4e5b5d19", 16)); static final byte[] holderCert = Base64 .decode("MIIGjTCCBXWgAwIBAgICAPswDQYJKoZIhvcNAQEEBQAwaTEdMBsGCSqGSIb3DQEJ" + "ARYOaXJtaGVscEB2dC5lZHUxLjAsBgNVBAMTJVZpcmdpbmlhIFRlY2ggQ2VydGlm" + "aWNhdGlvbiBBdXRob3JpdHkxCzAJBgNVBAoTAnZ0MQswCQYDVQQGEwJVUzAeFw0w" + "MzAxMzExMzUyMTRaFw0wNDAxMzExMzUyMTRaMIGDMRswGQYJKoZIhvcNAQkBFgxz" + "c2hhaEB2dC5lZHUxGzAZBgNVBAMTElN1bWl0IFNoYWggKHNzaGFoKTEbMBkGA1UE" + "CxMSVmlyZ2luaWEgVGVjaCBVc2VyMRAwDgYDVQQLEwdDbGFzcyAxMQswCQYDVQQK" + "EwJ2dDELMAkGA1UEBhMCVVMwgZ8wDQYJKoZIhvcNAQEBBQADgY0AMIGJAoGBAPDc" + "scgSKmsEp0VegFkuitD5j5PUkDuzLjlfaYONt2SN8WeqU4j2qtlCnsipa128cyKS" + "JzYe9duUdNxquh5BPIkMkHBw4jHoQA33tk0J/sydWdN74/AHPpPieK5GHwhU7GTG" + "rCCS1PJRxjXqse79ExAlul+gjQwHeldAC+d4A6oZAgMBAAGjggOmMIIDojAMBgNV" + "HRMBAf8EAjAAMBEGCWCGSAGG+EIBAQQEAwIFoDAOBgNVHQ8BAf8EBAMCA/gwHQYD" + "VR0lBBYwFAYIKwYBBQUHAwIGCCsGAQUFBwMEMB0GA1UdDgQWBBRUIoWAzlXbzBYE" + "yVTjQFWyMMKo1jCBkwYDVR0jBIGLMIGIgBTgc3Fm+TGqKDhen+oKfbl+xVbj2KFt" + "pGswaTEdMBsGCSqGSIb3DQEJARYOaXJtaGVscEB2dC5lZHUxLjAsBgNVBAMTJVZp" + "cmdpbmlhIFRlY2ggQ2VydGlmaWNhdGlvbiBBdXRob3JpdHkxCzAJBgNVBAoTAnZ0" + "MQswCQYDVQQGEwJVU4IBADCBiwYJYIZIAYb4QgENBH4WfFZpcmdpbmlhIFRlY2gg" + "Q2VydGlmaWNhdGlvbiBBdXRob3JpdHkgZGlnaXRhbCBjZXJ0aWZpY2F0ZXMgYXJl" + "IHN1YmplY3QgdG8gcG9saWNpZXMgbG9jYXRlZCBhdCBodHRwOi8vd3d3LnBraS52" + "dC5lZHUvY2EvY3BzLy4wFwYDVR0RBBAwDoEMc3NoYWhAdnQuZWR1MBkGA1UdEgQS" + "MBCBDmlybWhlbHBAdnQuZWR1MEMGCCsGAQUFBwEBBDcwNTAzBggrBgEFBQcwAoYn" + "aHR0cDovL2JveDE3Ny5jYy52dC5lZHUvY2EvaXNzdWVycy5odG1sMEQGA1UdHwQ9" + "MDswOaA3oDWGM2h0dHA6Ly9ib3gxNzcuY2MudnQuZWR1L2h0ZG9jcy1wdWJsaWMv" + "Y3JsL2NhY3JsLmNybDBUBgNVHSAETTBLMA0GCysGAQQBtGgFAQEBMDoGCysGAQQB" + "tGgFAQEBMCswKQYIKwYBBQUHAgEWHWh0dHA6Ly93d3cucGtpLnZ0LmVkdS9jYS9j" + "cHMvMD8GCWCGSAGG+EIBBAQyFjBodHRwOi8vYm94MTc3LmNjLnZ0LmVkdS9jZ2kt" + "cHVibGljL2NoZWNrX3Jldl9jYT8wPAYJYIZIAYb4QgEDBC8WLWh0dHA6Ly9ib3gx" + "NzcuY2MudnQuZWR1L2NnaS1wdWJsaWMvY2hlY2tfcmV2PzBLBglghkgBhvhCAQcE" + "PhY8aHR0cHM6Ly9ib3gxNzcuY2MudnQuZWR1L35PcGVuQ0E4LjAxMDYzMC9jZ2kt" + "cHVibGljL3JlbmV3YWw/MCwGCWCGSAGG+EIBCAQfFh1odHRwOi8vd3d3LnBraS52" + "dC5lZHUvY2EvY3BzLzANBgkqhkiG9w0BAQQFAAOCAQEAHJ2ls9yjpZVcu5DqiE67" + "r7BfkdMnm7IOj2v8cd4EAlPp6OPBmjwDMwvKRBb/P733kLBqFNWXWKTpT008R0KB" + "8kehbx4h0UPz9vp31zhGv169+5iReQUUQSIwTGNWGLzrT8kPdvxiSAvdAJxcbRBm" + "KzDic5I8PoGe48kSCkPpT1oNmnivmcu5j1SMvlx0IS2BkFMksr0OHiAW1elSnE/N" + "RuX2k73b3FucwVxB3NRo3vgoHPCTnh9r4qItAHdxFlF+pPtbw2oHESKRfMRfOIHz" + "CLQWSIa6Tvg4NIV3RRJ0sbCObesyg08lymalQMdkXwtRn5eGE00SHWwEUjSXP2gR" + "3g=="); public String getName() { return "AttrCertSelector"; } private X509AttributeCertificateHolder createAttrCert() throws Exception { CertificateFactory fact = CertificateFactory.getInstance("X.509", "BC"); X509Certificate iCert = (X509Certificate) fact .generateCertificate(new ByteArrayInputStream(holderCert)); X509CertificateHolder iCertHolder = new JcaX509CertificateHolder(iCert); // // a sample key pair. // // RSAPublicKeySpec pubKeySpec = new RSAPublicKeySpec( // new BigInteger( // "b4a7e46170574f16a97082b22be58b6a2a629798419be12872a4bdba626cfae9900f76abfb12139dce5de56564fab2b6543165a040c606887420e33d91ed7ed7", // 16), new BigInteger("11", 16)); // // set up the keys // PrivateKey privKey; KeyFactory kFact = KeyFactory.getInstance("RSA", "BC"); privKey = kFact.generatePrivate(RSA_PRIVATE_KEY_SPEC); X509v2AttributeCertificateBuilder gen = new X509v2AttributeCertificateBuilder( new AttributeCertificateHolder(iCertHolder.getSubject()), new AttributeCertificateIssuer(new X500Name("cn=test")), BigInteger.valueOf(1), new Date(System.currentTimeMillis() - 50000), new Date(System.currentTimeMillis() + 50000)); // the actual attributes GeneralName roleName = new GeneralName(GeneralName.rfc822Name, "DAU123456789@test.com"); ASN1EncodableVector roleSyntax = new ASN1EncodableVector(); roleSyntax.add(roleName); // roleSyntax OID: 2.5.24.72 gen.addAttribute(new ASN1ObjectIdentifier("2.5.24.72"), new DERSequence(roleSyntax)); ContentSigner sigGen = new JcaContentSignerBuilder("SHA1WithRSAEncryption").setProvider(BC).build(privKey); Target targetName = new Target(Target.targetName, new GeneralName(GeneralName.dNSName, "www.test.com")); Target targetGroup = new Target(Target.targetGroup, new GeneralName( GeneralName.directoryName, "o=Test, ou=Test")); Target[] targets = new Target[2]; targets[0] = targetName; targets[1] = targetGroup; TargetInformation targetInformation = new TargetInformation(targets); gen.addExtension(X509Extension.targetInformation, true, targetInformation); return gen.build(sigGen); } public void testSelector() throws Exception { X509AttributeCertificateHolder aCert = createAttrCert(); X509AttributeCertificateHolderSelectorBuilder sel = new X509AttributeCertificateHolderSelectorBuilder(); sel.setAttributeCert(aCert); boolean match = sel.build().match(aCert); if (!match) { fail("Selector does not match attribute certificate."); } sel.setAttributeCert(null); match = sel.build().match(aCert); if (!match) { fail("Selector does not match attribute certificate."); } sel.setHolder(aCert.getHolder()); match = sel.build().match(aCert); if (!match) { fail("Selector does not match attribute certificate holder."); } sel.setHolder(null); sel.setIssuer(aCert.getIssuer()); match = sel.build().match(aCert); if (!match) { fail("Selector does not match attribute certificate issuer."); } sel.setIssuer(null); CertificateFactory fact = CertificateFactory.getInstance("X.509", "BC"); X509CertificateHolder iCert = new JcaX509CertificateHolder((X509Certificate) fact .generateCertificate(new ByteArrayInputStream(holderCert))); match = aCert.getHolder().match(iCert); if (!match) { fail("Issuer holder does not match signing certificate of attribute certificate."); } sel.setSerialNumber(aCert.getSerialNumber()); match = sel.build().match(aCert); if (!match) { fail("Selector does not match attribute certificate serial number."); } sel.setAttributeCertificateValid(new Date()); match = sel.build().match(aCert); if (!match) { fail("Selector does not match attribute certificate time."); } sel.addTargetName(new GeneralName(2, "www.test.com")); match = sel.build().match(aCert); if (!match) { fail("Selector does not match attribute certificate target name."); } sel.setTargetNames(null); sel.addTargetGroup(new GeneralName(4, "o=Test, ou=Test")); match = sel.build().match(aCert); if (!match) { fail("Selector does not match attribute certificate target group."); } sel.setTargetGroups(null); } public void performTest() throws Exception { Security.addProvider(new BouncyCastleProvider()); testSelector(); } public static void main(String[] args) { Test test = new AttrCertSelectorTest(); TestResult result = test.perform(); System.out.println(result); } } bouncycastle-1.49.orig/test/src/org/bouncycastle/pqc/0000755000175000017500000000000012152033550022240 5ustar ebourgebourgbouncycastle-1.49.orig/test/src/org/bouncycastle/pqc/crypto/0000755000175000017500000000000012152033550023560 5ustar ebourgebourgbouncycastle-1.49.orig/test/src/org/bouncycastle/pqc/crypto/test/0000755000175000017500000000000012152033550024537 5ustar ebourgebourgbouncycastle-1.49.orig/test/src/org/bouncycastle/pqc/crypto/test/EncryptionKeyTest.java0000644000175000017500000000501212113320253031037 0ustar ebourgebourgpackage org.bouncycastle.pqc.crypto.test; import java.io.ByteArrayInputStream; import java.io.ByteArrayOutputStream; import java.io.IOException; import junit.framework.TestCase; import org.bouncycastle.crypto.AsymmetricCipherKeyPair; import org.bouncycastle.pqc.crypto.ntru.NTRUEncryptionKeyPairGenerator; import org.bouncycastle.pqc.crypto.ntru.NTRUEncryptionKeyGenerationParameters; import org.bouncycastle.pqc.crypto.ntru.NTRUEncryptionPrivateKeyParameters; import org.bouncycastle.pqc.crypto.ntru.NTRUEncryptionPublicKeyParameters; public class EncryptionKeyTest extends TestCase { public void testEncode() throws IOException { for (NTRUEncryptionKeyGenerationParameters params : new NTRUEncryptionKeyGenerationParameters[]{NTRUEncryptionKeyGenerationParameters.APR2011_743, NTRUEncryptionKeyGenerationParameters.APR2011_743_FAST, NTRUEncryptionKeyGenerationParameters.EES1499EP1}) { testEncode(params); } } private void testEncode(NTRUEncryptionKeyGenerationParameters params) throws IOException { NTRUEncryptionKeyPairGenerator kpGen = new NTRUEncryptionKeyPairGenerator(); kpGen.init(params); AsymmetricCipherKeyPair kp = kpGen.generateKeyPair(); byte[] priv = ((NTRUEncryptionPrivateKeyParameters)kp.getPrivate()).getEncoded(); byte[] pub = ((NTRUEncryptionPublicKeyParameters)kp.getPublic()).getEncoded(); AsymmetricCipherKeyPair kp2 = new AsymmetricCipherKeyPair(new NTRUEncryptionPublicKeyParameters(pub, params.getEncryptionParameters()), new NTRUEncryptionPrivateKeyParameters(priv, params.getEncryptionParameters())); assertEquals(kp.getPublic(), kp2.getPublic()); assertEquals(kp.getPrivate(), kp2.getPrivate()); ByteArrayOutputStream bos1 = new ByteArrayOutputStream(); ByteArrayOutputStream bos2 = new ByteArrayOutputStream(); ((NTRUEncryptionPrivateKeyParameters)kp.getPrivate()).writeTo(bos1); ((NTRUEncryptionPublicKeyParameters)kp.getPublic()).writeTo(bos2); ByteArrayInputStream bis1 = new ByteArrayInputStream(bos1.toByteArray()); ByteArrayInputStream bis2 = new ByteArrayInputStream(bos2.toByteArray()); AsymmetricCipherKeyPair kp3 = new AsymmetricCipherKeyPair(new NTRUEncryptionPublicKeyParameters(bis2, params.getEncryptionParameters()), new NTRUEncryptionPrivateKeyParameters(bis1, params.getEncryptionParameters())); assertEquals(kp.getPublic(), kp3.getPublic()); assertEquals(kp.getPrivate(), kp3.getPrivate()); } }bouncycastle-1.49.orig/test/src/org/bouncycastle/pqc/crypto/test/McElieceKobaraImaiCipherTest.java0000644000175000017500000000676612105021514032775 0ustar ebourgebourgpackage org.bouncycastle.pqc.crypto.test; import java.security.SecureRandom; import java.util.Random; import org.bouncycastle.crypto.AsymmetricCipherKeyPair; import org.bouncycastle.crypto.Digest; import org.bouncycastle.crypto.digests.SHA256Digest; import org.bouncycastle.crypto.params.ParametersWithRandom; import org.bouncycastle.pqc.crypto.mceliece.McElieceCCA2KeyGenerationParameters; import org.bouncycastle.pqc.crypto.mceliece.McElieceCCA2KeyPairGenerator; import org.bouncycastle.pqc.crypto.mceliece.McElieceCCA2Parameters; import org.bouncycastle.pqc.crypto.mceliece.McElieceKobaraImaiCipher; import org.bouncycastle.pqc.crypto.mceliece.McElieceKobaraImaiDigestCipher; import org.bouncycastle.util.test.SimpleTest; public class McElieceKobaraImaiCipherTest extends SimpleTest { SecureRandom keyRandom = new SecureRandom(); public String getName() { return "McElieceKobaraImai"; } public void performTest() { int numPassesKPG = 1; int numPassesEncDec = 10; Random rand = new Random(); byte[] mBytes; for (int j = 0; j < numPassesKPG; j++) { McElieceCCA2Parameters params = new McElieceCCA2Parameters(); McElieceCCA2KeyPairGenerator mcElieceCCA2KeyGen = new McElieceCCA2KeyPairGenerator(); McElieceCCA2KeyGenerationParameters genParam = new McElieceCCA2KeyGenerationParameters(keyRandom, params); mcElieceCCA2KeyGen.init(genParam); AsymmetricCipherKeyPair pair = mcElieceCCA2KeyGen.generateKeyPair(); ParametersWithRandom param = new ParametersWithRandom(pair.getPublic(), keyRandom); Digest msgDigest = new SHA256Digest(); McElieceKobaraImaiDigestCipher mcElieceKobaraImaiDigestCipher = new McElieceKobaraImaiDigestCipher(new McElieceKobaraImaiCipher(), msgDigest); for (int k = 1; k <= numPassesEncDec; k++) { System.out.println("############### test: " + k); // initialize for encryption mcElieceKobaraImaiDigestCipher.init(true, param); // generate random message int mLength = (rand.nextInt() & 0x1f) + 1; mBytes = new byte[mLength]; rand.nextBytes(mBytes); // encrypt mcElieceKobaraImaiDigestCipher.update(mBytes, 0, mBytes.length); byte[] enc = mcElieceKobaraImaiDigestCipher.messageEncrypt(); // initialize for decryption mcElieceKobaraImaiDigestCipher.init(false, pair.getPrivate()); byte[] constructedmessage = mcElieceKobaraImaiDigestCipher.messageDecrypt(enc); // XXX write in McElieceFujisakiDigestCipher? msgDigest.update(mBytes, 0, mBytes.length); byte[] hash = new byte[msgDigest.getDigestSize()]; msgDigest.doFinal(hash, 0); boolean verified = true; for (int i = 0; i < hash.length; i++) { verified = verified && hash[i] == constructedmessage[i]; } if (!verified) { fail("en/decryption fails"); } else { System.out.println("test okay"); System.out.println(); } } } } public static void main( String[] args) { runTest(new McElieceKobaraImaiCipherTest()); } } bouncycastle-1.49.orig/test/src/org/bouncycastle/pqc/crypto/test/NTRUSignatureKeyTest.java0000644000175000017500000000503612146637147031410 0ustar ebourgebourgpackage org.bouncycastle.pqc.crypto.test; import java.io.ByteArrayInputStream; import java.io.ByteArrayOutputStream; import java.io.IOException; import junit.framework.TestCase; import org.bouncycastle.crypto.AsymmetricCipherKeyPair; import org.bouncycastle.pqc.crypto.ntru.NTRUSigner; import org.bouncycastle.pqc.crypto.ntru.NTRUSigningKeyGenerationParameters; import org.bouncycastle.pqc.crypto.ntru.NTRUSigningKeyPairGenerator; import org.bouncycastle.pqc.crypto.ntru.NTRUSigningPrivateKeyParameters; import org.bouncycastle.pqc.crypto.ntru.NTRUSigningPublicKeyParameters; public class NTRUSignatureKeyTest extends TestCase { public void testEncode() throws IOException { for (NTRUSigningKeyGenerationParameters params : new NTRUSigningKeyGenerationParameters[]{NTRUSigningKeyGenerationParameters.TEST157, NTRUSigningKeyGenerationParameters.TEST157_PROD}) { testEncode(params); } } private void testEncode(NTRUSigningKeyGenerationParameters params) throws IOException { NTRUSigner ntru = new NTRUSigner(params.getSigningParameters()); NTRUSigningKeyPairGenerator kGen = new NTRUSigningKeyPairGenerator(); kGen.init(params); AsymmetricCipherKeyPair kp = kGen.generateKeyPair(); NTRUSigningPrivateKeyParameters kPriv = (NTRUSigningPrivateKeyParameters)kp.getPrivate(); NTRUSigningPublicKeyParameters kPub = (NTRUSigningPublicKeyParameters)kp.getPublic(); // encode to byte[] and reconstruct byte[] priv = kPriv.getEncoded(); byte[] pub = kPub.getEncoded(); AsymmetricCipherKeyPair kp2 = new AsymmetricCipherKeyPair(new NTRUSigningPublicKeyParameters(pub, params.getSigningParameters()), new NTRUSigningPrivateKeyParameters(priv, params)); assertEquals(kPub, kp2.getPublic()); assertEquals(kPriv, kp2.getPrivate()); // encode to OutputStream and reconstruct ByteArrayOutputStream bos1 = new ByteArrayOutputStream(); ByteArrayOutputStream bos2 = new ByteArrayOutputStream(); kPriv.writeTo(bos1); kPub.writeTo(bos2); ByteArrayInputStream bis1 = new ByteArrayInputStream(bos1.toByteArray()); ByteArrayInputStream bis2 = new ByteArrayInputStream(bos2.toByteArray()); AsymmetricCipherKeyPair kp3 = new AsymmetricCipherKeyPair(new NTRUSigningPublicKeyParameters(bis2, params.getSigningParameters()), new NTRUSigningPrivateKeyParameters(bis1, params)); assertEquals(kPub, kp3.getPublic()); assertEquals(kPriv, kp3.getPrivate()); } }bouncycastle-1.49.orig/test/src/org/bouncycastle/pqc/crypto/test/McEliecePointchevalCipherTest.java0000644000175000017500000000700112105021514033231 0ustar ebourgebourgpackage org.bouncycastle.pqc.crypto.test; import java.security.SecureRandom; import java.util.Random; import org.bouncycastle.crypto.AsymmetricCipherKeyPair; import org.bouncycastle.crypto.Digest; import org.bouncycastle.crypto.digests.SHA256Digest; import org.bouncycastle.crypto.params.ParametersWithRandom; import org.bouncycastle.pqc.crypto.mceliece.McElieceCCA2KeyGenerationParameters; import org.bouncycastle.pqc.crypto.mceliece.McElieceCCA2KeyPairGenerator; import org.bouncycastle.pqc.crypto.mceliece.McElieceCCA2Parameters; import org.bouncycastle.pqc.crypto.mceliece.McEliecePointchevalCipher; import org.bouncycastle.pqc.crypto.mceliece.McEliecePointchevalDigestCipher; import org.bouncycastle.util.test.SimpleTest; public class McEliecePointchevalCipherTest extends SimpleTest { SecureRandom keyRandom = new SecureRandom(); public String getName() { return "McElieceFujisaki"; } public void performTest() { int numPassesKPG = 1; int numPassesEncDec = 10; Random rand = new Random(); byte[] mBytes; for (int j = 0; j < numPassesKPG; j++) { McElieceCCA2Parameters params = new McElieceCCA2Parameters(); McElieceCCA2KeyPairGenerator mcElieceCCA2KeyGen = new McElieceCCA2KeyPairGenerator(); McElieceCCA2KeyGenerationParameters genParam = new McElieceCCA2KeyGenerationParameters(keyRandom, params); mcElieceCCA2KeyGen.init(genParam); AsymmetricCipherKeyPair pair = mcElieceCCA2KeyGen.generateKeyPair(); ParametersWithRandom param = new ParametersWithRandom(pair.getPublic(), keyRandom); Digest msgDigest = new SHA256Digest(); McEliecePointchevalDigestCipher mcEliecePointchevalDigestCipher = new McEliecePointchevalDigestCipher(new McEliecePointchevalCipher(), msgDigest); for (int k = 1; k <= numPassesEncDec; k++) { System.out.println("############### test: " + k); // initialize for encryption mcEliecePointchevalDigestCipher.init(true, param); // generate random message int mLength = (rand.nextInt() & 0x1f) + 1; mBytes = new byte[mLength]; rand.nextBytes(mBytes); // encrypt mcEliecePointchevalDigestCipher.update(mBytes, 0, mBytes.length); byte[] enc = mcEliecePointchevalDigestCipher.messageEncrypt(); // initialize for decryption mcEliecePointchevalDigestCipher.init(false, pair.getPrivate()); byte[] constructedmessage = mcEliecePointchevalDigestCipher.messageDecrypt(enc); // XXX write in McElieceFujisakiDigestCipher? msgDigest.update(mBytes, 0, mBytes.length); byte[] hash = new byte[msgDigest.getDigestSize()]; msgDigest.doFinal(hash, 0); boolean verified = true; for (int i = 0; i < hash.length; i++) { verified = verified && hash[i] == constructedmessage[i]; } if (!verified) { fail("en/decryption fails"); } else { System.out.println("test okay"); System.out.println(); } } } } public static void main( String[] args) { runTest(new McEliecePointchevalCipherTest()); } } bouncycastle-1.49.orig/test/src/org/bouncycastle/pqc/crypto/test/NTRUSignatureParametersTest.java0000644000175000017500000000436212113320253032741 0ustar ebourgebourgpackage org.bouncycastle.pqc.crypto.test; import java.io.ByteArrayInputStream; import java.io.ByteArrayOutputStream; import java.io.IOException; import junit.framework.TestCase; import org.bouncycastle.pqc.crypto.ntru.NTRUSigningKeyGenerationParameters; public class NTRUSignatureParametersTest extends TestCase { public void testLoadSave() throws IOException { for (NTRUSigningKeyGenerationParameters params : new NTRUSigningKeyGenerationParameters[]{NTRUSigningKeyGenerationParameters.TEST157, NTRUSigningKeyGenerationParameters.TEST157_PROD}) { testLoadSave(params); } } private void testLoadSave(NTRUSigningKeyGenerationParameters params) throws IOException { ByteArrayOutputStream os = new ByteArrayOutputStream(); params.writeTo(os); ByteArrayInputStream is = new ByteArrayInputStream(os.toByteArray()); assertEquals(params, new NTRUSigningKeyGenerationParameters(is)); } public void testEqualsHashCode() throws IOException { for (NTRUSigningKeyGenerationParameters params : new NTRUSigningKeyGenerationParameters[]{NTRUSigningKeyGenerationParameters.TEST157, NTRUSigningKeyGenerationParameters.TEST157_PROD}) { testEqualsHashCode(params); } } private void testEqualsHashCode(NTRUSigningKeyGenerationParameters params) throws IOException { ByteArrayOutputStream os = new ByteArrayOutputStream(); params.writeTo(os); ByteArrayInputStream is = new ByteArrayInputStream(os.toByteArray()); NTRUSigningKeyGenerationParameters params2 = new NTRUSigningKeyGenerationParameters(is); assertEquals(params, params2); assertEquals(params.hashCode(), params2.hashCode()); params.N += 1; assertFalse(params.equals(params2)); assertFalse(params.equals(params2)); assertFalse(params.hashCode() == params2.hashCode()); } public void testClone() { for (NTRUSigningKeyGenerationParameters params : new NTRUSigningKeyGenerationParameters[]{NTRUSigningKeyGenerationParameters.TEST157, NTRUSigningKeyGenerationParameters.TEST157_PROD}) { assertEquals(params, params.clone()); } } }bouncycastle-1.49.orig/test/src/org/bouncycastle/pqc/crypto/test/BitStringTest.java0000644000175000017500000000544512113315606030161 0ustar ebourgebourgpackage org.bouncycastle.pqc.crypto.test; import junit.framework.TestCase; import org.bouncycastle.pqc.crypto.ntru.IndexGenerator.BitString; import org.bouncycastle.util.Arrays; public class BitStringTest extends TestCase { public void testAppendBitsByteArray() { BitString bs = new BitString(); bs.appendBits((byte)78); assertBitStringEquals(bs, new byte[]{78}); bs.appendBits((byte)-5); assertBitStringEquals(bs, new byte[]{78, -5}); bs.appendBits((byte)127); assertBitStringEquals(bs, new byte[]{78, -5, 127}); bs.appendBits((byte)0); assertBitStringEquals(bs, new byte[]{78, -5, 127, 0}); bs.appendBits((byte)100); assertBitStringEquals(bs, new byte[]{78, -5, 127, 0, 100}); } private void assertBitStringEquals(BitString bs, byte[] arr) { byte[] bsBytes = bs.getBytes(); assertTrue(bsBytes.length >= arr.length); arr = copyOf(arr, bsBytes.length); assertTrue(Arrays.areEqual(arr, bsBytes)); } public void testGetTrailing() { BitString bs = new BitString(); bs.appendBits((byte)78); BitString bs2 = bs.getTrailing(3); assertBitStringEquals(bs2, new byte[]{6}); bs = new BitString(); bs.appendBits((byte)78); bs.appendBits((byte)-5); bs2 = bs.getTrailing(9); assertBitStringEquals(bs2, new byte[]{78, 1}); bs2.appendBits((byte)100); assertBitStringEquals(bs2, new byte[]{78, -55}); bs = bs2.getTrailing(13); assertBitStringEquals(bs, new byte[]{78, 9}); bs2 = bs2.getTrailing(11); assertBitStringEquals(bs2, new byte[]{78, 1}); bs2.appendBits((byte)100); assertBitStringEquals(bs2, new byte[]{78, 33, 3}); bs2 = bs2.getTrailing(16); assertBitStringEquals(bs2, new byte[]{78, 33}); } public void testGetLeadingAsInt() { BitString bs = new BitString(); bs.appendBits((byte)78); bs.appendBits((byte)42); assertEquals(1, bs.getLeadingAsInt(3)); assertEquals(84, bs.getLeadingAsInt(9)); assertEquals(338, bs.getLeadingAsInt(11)); BitString bs2 = bs.getTrailing(11); assertBitStringEquals(bs2, new byte[]{78, 2}); assertEquals(590, bs2.getLeadingAsInt(11)); assertEquals(9, bs2.getLeadingAsInt(5)); bs2.appendBits((byte)115); assertEquals(230, bs2.getLeadingAsInt(9)); assertEquals(922, bs2.getLeadingAsInt(11)); bs2.appendBits((byte)-36); assertEquals(55, bs2.getLeadingAsInt(6)); } private byte[] copyOf(byte[] src, int length) { byte[] tmp = new byte[length]; System.arraycopy(src, 0, tmp, 0, tmp.length > src.length ? src.length : tmp.length); return tmp; } }bouncycastle-1.49.orig/test/src/org/bouncycastle/pqc/crypto/test/GMSSSignerTest.java0000644000175000017500000000547012121455422030173 0ustar ebourgebourgpackage org.bouncycastle.pqc.crypto.test; import java.math.BigInteger; import java.security.SecureRandom; import org.bouncycastle.crypto.AsymmetricCipherKeyPair; import org.bouncycastle.crypto.Digest; import org.bouncycastle.crypto.Signer; import org.bouncycastle.crypto.digests.SHA224Digest; import org.bouncycastle.crypto.params.ParametersWithRandom; import org.bouncycastle.pqc.crypto.DigestingMessageSigner; import org.bouncycastle.pqc.crypto.gmss.GMSSDigestProvider; import org.bouncycastle.pqc.crypto.gmss.GMSSKeyGenerationParameters; import org.bouncycastle.pqc.crypto.gmss.GMSSKeyPairGenerator; import org.bouncycastle.pqc.crypto.gmss.GMSSParameters; import org.bouncycastle.pqc.crypto.gmss.GMSSPrivateKeyParameters; import org.bouncycastle.pqc.crypto.gmss.GMSSSigner; import org.bouncycastle.util.BigIntegers; import org.bouncycastle.util.encoders.Hex; import org.bouncycastle.util.test.FixedSecureRandom; import org.bouncycastle.util.test.SimpleTest; public class GMSSSignerTest extends SimpleTest { byte[] keyData = Hex.decode("b5014e4b60ef2ba8b6211b4062ba3224e0427dd3"); SecureRandom keyRandom = new FixedSecureRandom(new byte[][]{keyData, keyData}); public String getName() { return "GMSS"; } public void performTest() throws Exception { GMSSParameters params = new GMSSParameters(3, new int[]{15, 15, 10}, new int[]{5, 5, 4}, new int[]{3, 3, 2}); GMSSDigestProvider digProvider = new GMSSDigestProvider() { public Digest get() { return new SHA224Digest(); } }; GMSSKeyPairGenerator gmssKeyGen = new GMSSKeyPairGenerator(digProvider); GMSSKeyGenerationParameters genParam = new GMSSKeyGenerationParameters(keyRandom, params); gmssKeyGen.init(genParam); AsymmetricCipherKeyPair pair = gmssKeyGen.generateKeyPair(); ParametersWithRandom param = new ParametersWithRandom(pair.getPrivate(), keyRandom); // TODO Signer gmssSigner = new DigestingMessageSigner(new GMSSSigner(digProvider), new SHA224Digest()); gmssSigner.init(true, param); byte[] message = BigIntegers.asUnsignedByteArray(new BigInteger("968236873715988614170569073515315707566766479517")); gmssSigner.update(message, 0, message.length); byte[] sig = gmssSigner.generateSignature(); gmssSigner.init(false, pair.getPublic()); gmssSigner.update(message, 0, message.length); if (!gmssSigner.verifySignature(sig)) { fail("verification fails"); } if (!((GMSSPrivateKeyParameters)pair.getPrivate()).isUsed()) { fail("private key not marked as used"); } } public static void main( String[] args) { runTest(new GMSSSignerTest()); } } bouncycastle-1.49.orig/test/src/org/bouncycastle/pqc/crypto/test/McEliecePKCSCipherTest.java0000644000175000017500000000656212105020152031525 0ustar ebourgebourgpackage org.bouncycastle.pqc.crypto.test; import java.security.SecureRandom; import java.util.Random; import org.bouncycastle.crypto.AsymmetricCipherKeyPair; import org.bouncycastle.crypto.Digest; import org.bouncycastle.crypto.digests.SHA256Digest; import org.bouncycastle.crypto.params.ParametersWithRandom; import org.bouncycastle.pqc.crypto.mceliece.McElieceKeyGenerationParameters; import org.bouncycastle.pqc.crypto.mceliece.McElieceKeyPairGenerator; import org.bouncycastle.pqc.crypto.mceliece.McEliecePKCSCipher; import org.bouncycastle.pqc.crypto.mceliece.McEliecePKCSDigestCipher; import org.bouncycastle.pqc.crypto.mceliece.McElieceParameters; import org.bouncycastle.util.test.SimpleTest; public class McEliecePKCSCipherTest extends SimpleTest { SecureRandom keyRandom = new SecureRandom(); public String getName() { return "McEliecePKCS"; } public void performTest() { int numPassesKPG = 1; int numPassesEncDec = 10; Random rand = new Random(); byte[] mBytes; for (int j = 0; j < numPassesKPG; j++) { McElieceParameters params = new McElieceParameters(); McElieceKeyPairGenerator mcElieceKeyGen = new McElieceKeyPairGenerator(); McElieceKeyGenerationParameters genParam = new McElieceKeyGenerationParameters(keyRandom, params); mcElieceKeyGen.init(genParam); AsymmetricCipherKeyPair pair = mcElieceKeyGen.generateKeyPair(); ParametersWithRandom param = new ParametersWithRandom(pair.getPublic(), keyRandom); Digest msgDigest = new SHA256Digest(); McEliecePKCSDigestCipher mcEliecePKCSDigestCipher = new McEliecePKCSDigestCipher(new McEliecePKCSCipher(), msgDigest); for (int k = 1; k <= numPassesEncDec; k++) { System.out.println("############### test: " + k); // initialize for encryption mcEliecePKCSDigestCipher.init(true, param); // generate random message int mLength = (rand.nextInt() & 0x1f) + 1; mBytes = new byte[mLength]; rand.nextBytes(mBytes); // encrypt mcEliecePKCSDigestCipher.update(mBytes, 0, mBytes.length); byte[] enc = mcEliecePKCSDigestCipher.messageEncrypt(); // initialize for decryption mcEliecePKCSDigestCipher.init(false, pair.getPrivate()); byte[] constructedmessage = mcEliecePKCSDigestCipher.messageDecrypt(enc); // XXX write in McElieceFujisakiDigestCipher? msgDigest.update(mBytes, 0, mBytes.length); byte[] hash = new byte[msgDigest.getDigestSize()]; msgDigest.doFinal(hash, 0); boolean verified = true; for (int i = 0; i < hash.length; i++) { verified = verified && hash[i] == constructedmessage[i]; } if (!verified) { fail("en/decryption fails"); } else { System.out.println("test okay"); System.out.println(); } } } } public static void main( String[] args) { runTest(new McEliecePKCSCipherTest()); } } bouncycastle-1.49.orig/test/src/org/bouncycastle/pqc/crypto/test/NTRUEncryptTest.java0000644000175000017500000010215512113320253030377 0ustar ebourgebourgpackage org.bouncycastle.pqc.crypto.test; import java.io.IOException; import java.security.SecureRandom; import junit.framework.TestCase; import org.bouncycastle.crypto.AsymmetricCipherKeyPair; import org.bouncycastle.crypto.DataLengthException; import org.bouncycastle.crypto.InvalidCipherTextException; import org.bouncycastle.pqc.crypto.ntru.NTRUEngine; import org.bouncycastle.pqc.crypto.ntru.NTRUEncryptionKeyPairGenerator; import org.bouncycastle.pqc.crypto.ntru.NTRUEncryptionKeyGenerationParameters; import org.bouncycastle.pqc.crypto.ntru.NTRUEncryptionPrivateKeyParameters; import org.bouncycastle.pqc.crypto.ntru.NTRUEncryptionPublicKeyParameters; import org.bouncycastle.pqc.crypto.ntru.NTRUParameters; import org.bouncycastle.pqc.math.ntru.polynomial.DenseTernaryPolynomial; import org.bouncycastle.pqc.math.ntru.polynomial.IntegerPolynomial; import org.bouncycastle.pqc.math.ntru.polynomial.Polynomial; import org.bouncycastle.pqc.math.ntru.polynomial.SparseTernaryPolynomial; import org.bouncycastle.pqc.math.ntru.polynomial.TernaryPolynomial; import org.bouncycastle.util.Arrays; public class NTRUEncryptTest extends TestCase { public void testEncryptDecrypt() throws InvalidCipherTextException { NTRUEncryptionKeyGenerationParameters params = NTRUEncryptionKeyGenerationParameters.APR2011_743.clone(); // set df1..df3 and dr1..dr3 so params can be used for SIMPLE as well as PRODUCT params.df1 = NTRUEncryptionKeyGenerationParameters.APR2011_743_FAST.df1; params.df2 = NTRUEncryptionKeyGenerationParameters.APR2011_743_FAST.df2; params.df3 = NTRUEncryptionKeyGenerationParameters.APR2011_743_FAST.df3; params.dr1 = NTRUEncryptionKeyGenerationParameters.APR2011_743_FAST.dr1; params.dr2 = NTRUEncryptionKeyGenerationParameters.APR2011_743_FAST.dr2; params.dr3 = NTRUEncryptionKeyGenerationParameters.APR2011_743_FAST.dr3; int[] values = new int[] { NTRUParameters.TERNARY_POLYNOMIAL_TYPE_SIMPLE, NTRUParameters.TERNARY_POLYNOMIAL_TYPE_PRODUCT }; for (int i = 0; i != values.length; i++) { int polyType = values[i]; boolean[] booleans = {true, false}; for (int j = 0; j != booleans.length; j++) { params.polyType = polyType; params.fastFp = booleans[j]; VisibleNTRUEngine ntru = new VisibleNTRUEngine(); NTRUEncryptionKeyPairGenerator ntruGen = new NTRUEncryptionKeyPairGenerator(); ntruGen.init(params); AsymmetricCipherKeyPair kp = ntruGen.generateKeyPair(); testPolynomial(ntru, kp, params); testText(ntru, kp, params); // sparse/dense params.sparse = !params.sparse; testText(ntru, kp, params); params.sparse = !params.sparse; testEmpty(ntru, kp, params); testMaxLength(ntru, kp, params); testTooLong(ntru, kp, params); testInvalidEncoding(ntru, kp, params); } } } // encrypts and decrypts a polynomial private void testPolynomial(VisibleNTRUEngine ntru, AsymmetricCipherKeyPair kp, NTRUEncryptionKeyGenerationParameters params) { SecureRandom random = new SecureRandom(); IntegerPolynomial m = DenseTernaryPolynomial.generateRandom(params.N, random); SparseTernaryPolynomial r = SparseTernaryPolynomial.generateRandom(params.N, params.dr, params.dr, random); ntru.init(true, kp.getPublic()); // just to set params IntegerPolynomial e = ntru.encrypt(m, r, ((NTRUEncryptionPublicKeyParameters)kp.getPublic()).h); IntegerPolynomial c = ntru.decrypt(e, ((NTRUEncryptionPrivateKeyParameters)kp.getPrivate()).t, ((NTRUEncryptionPrivateKeyParameters)kp.getPrivate()).fp); assertTrue(Arrays.areEqual(m.coeffs, c.coeffs)); } // encrypts and decrypts text private void testText(NTRUEngine ntru, AsymmetricCipherKeyPair kp, NTRUEncryptionKeyGenerationParameters params) throws InvalidCipherTextException { byte[] plainText = "text to encrypt".getBytes(); ntru.init(true, kp.getPublic()); byte[] encrypted = ntru.processBlock(plainText, 0, plainText.length); ntru.init(false, kp.getPrivate()); byte[] decrypted = ntru.processBlock(encrypted, 0, encrypted.length); assertTrue(Arrays.areEqual(plainText, decrypted)); } // tests an empty message private void testEmpty(NTRUEngine ntru, AsymmetricCipherKeyPair kp, NTRUEncryptionKeyGenerationParameters params) throws InvalidCipherTextException { byte[] plainText = "".getBytes(); ntru.init(true, kp.getPublic()); byte[] encrypted = ntru.processBlock(plainText, 0, plainText.length); ntru.init(false, kp.getPrivate()); byte[] decrypted = ntru.processBlock(encrypted, 0, encrypted.length); assertTrue(Arrays.areEqual(plainText, decrypted)); } // tests a message of the maximum allowed length private void testMaxLength(NTRUEngine ntru, AsymmetricCipherKeyPair kp, NTRUEncryptionKeyGenerationParameters params) throws InvalidCipherTextException { byte[] plainText = new byte[params.maxMsgLenBytes]; System.arraycopy("secret encrypted text".getBytes(), 0, plainText, 0, 21); ntru.init(true, kp.getPublic()); byte[] encrypted = ntru.processBlock(plainText, 0, plainText.length); ntru.init(false, kp.getPrivate()); byte[] decrypted = ntru.processBlock(encrypted, 0, encrypted.length); assertTrue(Arrays.areEqual(plainText, decrypted)); } // tests a message that is too long private void testTooLong(NTRUEngine ntru, AsymmetricCipherKeyPair kp, NTRUEncryptionKeyGenerationParameters params) { byte[] plainText = new byte[params.maxMsgLenBytes + 1]; try { System.arraycopy("secret encrypted text".getBytes(), 0, plainText, 0, 21); ntru.init(true, kp.getPublic()); byte[] encrypted = ntru.processBlock(plainText, 0, plainText.length); ntru.init(false, kp.getPrivate()); byte[] decrypted = ntru.processBlock(encrypted, 0, encrypted.length); assertTrue(Arrays.areEqual(plainText, decrypted)); fail("An exception should have been thrown!"); } catch (DataLengthException ex) { assertEquals("Message too long: " + plainText.length + ">" + params.maxMsgLenBytes, ex.getMessage()); } catch (InvalidCipherTextException e) { e.printStackTrace(); //To change body of catch statement use File | Settings | File Templates. } } // tests that altering the public key *AFTER* encryption causes the decrypted message to be rejected private void testInvalidEncoding(NTRUEngine ntru, AsymmetricCipherKeyPair kp, NTRUEncryptionKeyGenerationParameters params) { try { byte[] plainText = "secret encrypted text".getBytes(); ntru.init(true, kp.getPublic()); byte[] encrypted = ntru.processBlock(plainText, 0, plainText.length); NTRUEncryptionPrivateKeyParameters orig = (NTRUEncryptionPrivateKeyParameters)kp.getPrivate(); IntegerPolynomial h = (IntegerPolynomial)((NTRUEncryptionPublicKeyParameters)kp.getPublic()).h.clone(); h.coeffs[0] = (h.coeffs[0] + 111) % params.q; // alter h NTRUEncryptionPrivateKeyParameters privKey = new NTRUEncryptionPrivateKeyParameters(h, orig.t, orig.fp, params.getEncryptionParameters()); ntru.init(false, privKey); ntru.processBlock(encrypted, 0, encrypted.length); fail("An exception should have been thrown!"); } catch (InvalidCipherTextException ex) { assertEquals("Invalid message encoding", ex.getMessage()); } } // encrypts and decrypts text using an encoded key pair (fastFp=false, simple ternary polynomials) public void testEncodedKeysSlow() throws IOException, InvalidCipherTextException { byte[] plainText = "secret encrypted text".getBytes(); // dense polynomials NTRUEncryptionKeyGenerationParameters params = NTRUEncryptionKeyGenerationParameters.APR2011_743; NTRUEngine ntru = new NTRUEngine(); byte[] privBytes = {2, -94, 95, 65, -107, 27, 98, 62, -15, -62, 21, -4, 119, -117, 7, 68, 100, 113, -36, -82, 87, -87, -82, 24, -45, -75, -74, -108, 105, 24, 123, 117, 124, 74, -27, 42, -106, -78, 114, 27, 18, 77, -41, 105, -113, 39, 49, 46, 109, -69, 61, 77, 49, 117, 14, -29, 42, 3, 120, -121, -120, -37, 95, 84, 60, -9, -31, -64, 31, 72, 115, -15, 21, -6, 27, -60, -73, -29, -33, -81, -43, 106, 65, 114, 102, -14, -115, -96, 9, 54, 23, -18, -24, -76, 84, -41, -79, 35, 88, 11, 41, 67, 44, -63, -28, 76, 84, -41, -103, 106, -22, 35, -2, -40, -48, -121, -128, 76, 63, 123, -11, 103, -35, -32, 21, -51, -99, -40, -103, -12, 64, -80, 57, -56, 1, -51, 103, 83, 50, 111, -87, -98, 7, -109, 25, -51, 23, -92}; byte[] pubBytes = {91, -66, -25, -81, -66, -33, 25, -31, 48, 23, -38, 20, -30, -120, -17, 1, 21, 51, -11, 102, -50, 62, 71, 79, 32, -49, -57, 105, 21, -34, -45, -67, 113, -46, -103, 57, 28, -54, -21, 94, -112, -63, 105, -100, -95, 21, -52, 50, 11, -22, -63, -35, -42, 50, 93, -40, 23, 0, 121, 23, -93, 111, -98, -14, 92, -24, -117, -8, -109, -118, -4, -107, -60, 100, -128, -47, -92, -117, -108, 39, -113, 43, 48, 68, 95, 123, -112, 41, -27, -99, 59, 33, -57, -120, -44, 72, -98, -105, -91, -52, -89, 107, 119, 87, -36, -102, -83, 67, -8, 30, -54, 74, 93, 119, -3, 126, 69, -104, -44, -24, 124, 108, -125, 73, 98, 121, -49, -37, -24, 87, -71, 91, 8, -31, -50, 95, 112, 27, 97, -93, 3, -73, -54, -16, -92, -108, -74, 88, -5, 23, 70, 69, -49, -46, -50, 65, 69, -54, -41, 109, 8, -80, -23, -84, 120, -77, 26, 99, -104, -33, 82, 91, 22, -17, 113, -29, 66, -7, -114, -101, -111, -47, -1, -3, -57, 62, 79, -70, -58, 45, 76, 28, -117, 59, -117, 113, 84, -55, 48, 119, 58, -105, -20, 80, 102, 14, -69, -69, 5, 11, -87, 107, 15, 105, -69, -27, -24, 47, -18, -54, -45, -67, 27, -52, -20, -94, 64, -26, -58, 98, 33, -61, 71, -101, 120, 28, 113, 72, 127, 50, 123, 36, -97, 78, 32, -74, 105, 62, 92, 84, -17, 21, -75, 24, -90, -78, -4, -121, 47, -82, 119, 27, -61, 17, -66, 43, 96, -49, -6, 66, -13, -75, -95, 64, -12, -39, 111, 46, -3, -123, 82, 12, -26, -30, -29, 71, -108, -79, -112, 13, 16, -70, 7, 100, 84, 89, -100, 114, 47, 56, 71, 83, 63, -61, -39, -53, -100, 23, -31, -52, -46, 36, -13, 62, 107, 28, -28, 92, 116, -59, 28, -111, -23, -44, 21, -2, 127, -112, 54, -126, 13, -104, 47, -43, -109, -19, 107, -94, -126, 50, 92, -69, 1, 115, -121, -52, -100, 25, 126, -7, 86, 77, 72, -2, -104, -42, 98, -16, 54, -67, 117, 14, -73, 4, 58, 121, 35, 1, 99, -127, -9, -60, 32, -37, -106, 6, -108, -13, -62, 23, -20, -9, 21, 15, 4, 126, -112, 123, 34, -67, -51, 43, -30, -75, 119, -112, -58, -55, -90, 2, -5, -46, -12, 119, 87, 24, -52, 2, -29, 113, 61, -82, -101, 57, -11, -107, -11, 67, -42, -43, -13, 112, -49, 82, 60, 13, -50, 108, 64, -64, 53, -107, -9, 102, -33, 75, -100, -115, 102, -113, -48, 19, -119, -72, -65, 22, -65, -93, 34, -71, 75, 101, 54, 126, 75, 34, -21, -53, -36, 127, -21, 70, 24, 89, -88, 63, -43, -4, 68, 97, -45, -101, -125, -38, 98, -118, -34, -63, 23, 78, 15, 17, 101, -107, 119, -41, 107, 117, 17, 108, 43, -93, -6, -23, -30, 49, -61, 27, 61, -125, -68, 51, 40, -106, -61, 51, 127, 2, 123, 7, -50, -115, -32, -95, -96, 67, 4, 5, 59, -45, 61, 95, 14, 2, -76, -121, 8, 125, 16, -126, 58, 118, -32, 19, -113, -113, 120, -101, 86, 76, -90, 50, -92, 51, -92, 1, 121, -74, -101, -33, 53, -53, -83, 46, 20, -87, -112, -61, -87, 106, -126, 64, 99, -60, 70, 120, 47, -53, 36, 20, -90, 110, 61, -93, 55, -10, 85, 45, 52, 79, 87, 100, -81, -85, 34, 55, -91, 27, 116, -18, -71, -11, 87, -11, 76, 48, 97, -78, 64, -100, -59, -12, 19, -90, 121, 48, -19, 64, 113, -70, -14, -70, 92, 124, 42, 95, 7, -115, 36, 127, 73, 33, 30, 121, 88, 16, -90, 99, 120, -68, 64, -125, -78, 76, 112, 68, 8, 105, 10, -47, -124, 39, -107, -101, 46, -61, 118, -74, 102, -62, -6, -128, 17, -45, 61, 76, 63, -10, -41, 50, -113, 75, -83, -59, -51, -23, -61, 47, 7, -80, 126, -2, 79, -53, 110, -93, -38, -91, -22, 20, -84, -113, -124, -73, 124, 0, 33, -58, 63, -26, 52, 7, 74, 65, 38, -33, 21, -9, -1, 120, -16, 47, -96, 59, -64, 74, 6, 48, -67, -32, -26, 35, 68, 47, 82, 36, 52, 41, 112, -28, -22, -51, -6, -49, 105, 16, -34, 99, -41, 75, 7, 79, -22, -125, -30, -126, 35, 119, -43, -30, 32, 8, 44, -42, -98, 78, -92, -95, -10, -94, -1, -91, -122, 77, 0, 40, -23, 36, 85, 123, -57, -74, -69, -90, 89, 111, -120, 22, 5, -48, 114, 59, 31, 31, -25, -3, 24, 110, -110, 73, -40, 92, -26, -12, 52, 83, -98, -119, -6, -117, -89, 95, 83, -25, 122, -26, 114, 81, 25, 110, 79, -49, -39, 10, -78, -65, 57, -90, -46, -126, 15, -124, -104, -89, -66, -87, 24, -45, 39, -34, -40, -13, 106, 12, -25, -116, -47, 79, -81, 64, -17, -31, -70, 87, 36, 46, 102, 107, 48, 88, 34, 46, 24, 63, -100, 106, 27, 58, -71, 38, 60, -66, 45, -89, 39, -60, -116, -14, -119, 118, 0, -24, -9, 38, -71, -79, 124, -119, -64, -9, 71, -56, -82, -73, -69, 127, -1, -20, 123, 32, -43, 49, 5, 49, 105, -5, -2, 5, -105, -111, 89, -30, -41, -49, 61, 80, 69, 44, -33, -116, -45, -96, 63, 28, -17, -106, -94, 90, -40, -88, 122, 116, 116, 113, -65, 104, 119, -3, 96, -45, 18, -120, -111, 83, 43, -5, 101, 71, 48, 104, -112, -95, -46, 53, -96, -93, -126, 96, 56, 104, -111, 114, -1, -44, -120, -112, -19, 100, 41, -122, 23, -78, 33, -35, 11, 57, -18, 106, -40, 74, 61, 66, 54, -77, 96, 70, 108, -128, 91, -97, -36, -23, -86, -91, 44, 58, 117, 2, 26, 44, 95, 79, -101, -81, -92, 110, -81, -12, -88, -21, -83, 60, 93, -121, -114, -48, -34, -119, -1, 127, -121, 54, -128, -106, -39, -108, 81, 17, -3, -13, -57, 74, 41, -122, -65, -107, -118, -65, -61, 103, -69, 19}; byte[] fullBytes = new byte[pubBytes.length + privBytes.length]; System.arraycopy(pubBytes, 0, fullBytes, 0, pubBytes.length); System.arraycopy(privBytes, 0, fullBytes, pubBytes.length, privBytes.length); NTRUEncryptionPrivateKeyParameters priv = new NTRUEncryptionPrivateKeyParameters(fullBytes, params.getEncryptionParameters()); NTRUEncryptionPublicKeyParameters pub = new NTRUEncryptionPublicKeyParameters(pubBytes, params.getEncryptionParameters()); AsymmetricCipherKeyPair kp = new AsymmetricCipherKeyPair(pub, priv); ntru.init(true, kp.getPublic()); byte[] encrypted = ntru.processBlock(plainText, 0, plainText.length); ntru.init(false, kp.getPrivate()); byte[] decrypted = ntru.processBlock(encrypted, 0, encrypted.length); assertTrue(Arrays.areEqual(plainText, decrypted)); // sparse polynomials params = NTRUEncryptionKeyGenerationParameters.EES1499EP1; ntru = new NTRUEngine(); privBytes = new byte[] {116, 7, 118, 121, 6, 77, -36, 60, 65, 108, 10, -106, 12, 9, -22, -113, 122, -31, -31, 18, 120, 81, -33, 5, 122, -76, 109, -30, -101, -45, 21, 13, -11, -49, -111, 46, 91, 4, -28, -109, 121, -119, -121, -58, -113, -9, -10, -25, -53, 40, -86, -22, -50, 42, 52, 107, 119, 17, 33, 125, -26, 33, 55, 25, -77, -65, -106, 116, -67, 91, 105, -7, 42, -107, -54, 101, 12, -12, 57, -116, 45, -107, -17, 110, 35, -64, 19, -38, -122, 115, -93, 53, 69, 66, -106, 17, 20, -71, 121, 23, -21, -45, 108, 97, 23, -98, -12, -41, -31, -53, 30, -42, 15, 85, -21, -89, 118, 42, -117, -39, 69, 0, -63, 83, 48, -80, -14, -123, -4, -116, -90, -107, -89, 119, 29, -30, 69, 22, -84, 47, 117, -123, 102, -116, 35, 93, -13, 84, -9, -122, 58, 101, 93, -106, -119, -35, -75, 76, 27, -125, -22, 68, 101, 49, 103, -13, -98, 93, -56, -110, -19, -12, 74, 104, 7, 6, -11, 47, 57, 90, 75, -30, 47, 66, -58, 14, 14, 70, 11, -119, -36, -118, -55, -53, 101, -73, -77, 33, -29, 96, -86, 38, 47, 103, 19, -37, -17, -50, -82, -87, -119, 37, -54, 77, -69, -16, -48, -52, 110, -26, 111, 35, 26, -53, -10, 9, -108, -34, 102, 7, -18, -72, -26, 24, -50, -43, 92, 56, -94, 23, -36, 60, 28, -121, 27, 127, -93, -79, -45, -60, 105, -6, -88, 72, -41, 47, -51, 3, 91, 116, 75, 122, -94, -113, 28, -96, -62, -29, -74, -85, -93, 51, 58, 72, 44, 9, 18, -48, -24, 73, 122, 60, -23, 83, -110, -7, -111, -69, 106, 51, 118, -83, -18, 109, -32, 40, 22}; pubBytes = new byte[] {-62, 56, 59, -46, 30, -19, 22, -115, -20, 117, -14, 3, 2, -57, 85, -24, 27, 57, 49, -93, -52, 87, 49, 96, 15, 95, -95, -86, -61, 50, -18, 3, 109, -55, -110, -57, 82, 124, -5, -57, 68, -18, 126, 114, 6, -22, 8, 121, 125, 29, -16, 112, -81, 27, -7, 109, -44, -123, -15, -14, 74, -126, 95, -94, -91, 119, 80, -48, 41, 49, 6, 104, 93, -97, -108, -82, 93, 70, -127, -113, -22, -103, 35, -115, 20, -115, 63, 57, -84, -18, -107, 81, 44, -16, 83, 71, -27, -2, -125, 87, 26, 100, -116, 110, 94, -46, -56, -82, 119, -110, -127, -99, -8, -118, 90, 64, -29, 102, 99, 92, 86, -117, 26, -89, 32, 17, 55, -65, -10, -5, -74, 19, 13, 113, -15, -103, 17, 10, -127, -95, -79, 19, 11, -24, 59, 28, -70, -55, -69, -105, -20, -117, 66, 4, 77, 116, -124, -62, 19, 109, 49, -120, 10, -15, 108, 84, 126, 122, -46, -37, 114, -78, -72, 34, -12, 25, -104, -3, 114, -94, 16, 31, 31, -124, -109, -64, 57, -47, -113, -26, 97, -58, 112, -40, 49, 80, -54, -115, -98, -60, -123, 91, 14, 75, -86, 77, -93, 68, 112, 82, 79, 28, -25, 49, -27, -112, 103, 60, -128, 95, -63, 2, -51, 2, -107, 80, 113, 18, 123, 24, 70, 77, -56, -48, 33, 89, 88, 29, 112, -102, -15, 52, -96, 17, -9, 6, -11, -119, 29, -107, -84, -19, 84, 124, 19, 90, -60, -41, 123, -81, 96, -119, 17, -61, 62, 55, 95, -73, -13, -60, 56, 77, 24, -39, -107, -78, 47, -91, 88, 90, 34, 112, -80, 83, -58, 127, 76, -97, -40, 78, -20, -1, -62, 19, 6, -43, -46, -36, -53, -22, -28, -119, 8, 19, 79, -9, -54, -126, -3, -20, -110, -82, 51, 3, 1, -123, -41, -40, -11, 91, -52, 48, 104, -11, -2, 49, 45, 52, -33, 109, -44, -30, -44, -83, -108, -10, 77, 106, 82, 3, 14, -48, -18, -79, -64, -34, -63, -18, 122, 33, 25, 44, 82, -112, 111, 68, 97, -58, -38, 25, 62, 78, 97, -36, 57, -19, 122, -18, -74, 67, -127, -24, 32, -45, 67, -106, 90, 0, 1, 91, 30, -80, 95, 9, 78, -4, -14, 16, 111, -56, -102, -90, 52, -1, 116, 19, -127, -23, -87, 103, -94, -111, 118, 53, -69, 77, 17, -3, 31, -53, -21, -78, 124, -88, 52, 117, 34, -52, -77, -107, -38, -102, 23, 73, -76, -88, 95, 64, -85, 12, 36, -86, 86, -17, 77, 121, 90, 24, -49, -107, 33, -116, 65, 13, 91, 118, -107, -21, 65, -59, 18, 125, 61, -65, -68, -19, 23, 88, 60, -6, 78, -8, 69, -62, -118, -93, 97, -64, -67, 28, 28, -87, -97, 72, -125, -119, 4, -43, 7, 22, -15, 52, 52, -82, -5, -51, 99, 20, -59, -2, -54, -67, 40, -128, -20, -37, 50, 123, 32, 8, -39, -105, 93, 73, 77, 84, 43, 89, 88, -6, 7, -108, 81, 27, 1, 50, 16, -101, 67, 95, 119, 105, 70, 99, -127, 22, 127, -33, -19, -113, -55, -100, 122, -86, 98, 53, 27, -95, 4, -121, -96, 87, 67, -98, -37, -10, 92, 29, -3, -115, -23, 37, 8, -30, 99, -117, 62, 101, 83, 49, 60, -83, -47, -33, 41, -118, 76, -7, 111, -15, 123, -59, 53, 2, -20, -57, 24, 57, 62, 84, -26, -11, 93, -118, 54, -13, 56, 77, -66, 18, -62, -76, 80, 98, 26, 120, -93, 55, 103, -1, 78, -92, 120, -23, -60, -75, 11, 53, -62, -94, -80, 120, 113, 33, -24, -64, -5, 23, 120, -14, 61, 26, -1, 56, 79, 34, 116, -16, -95, -71, 40, -89, -50, 71, -117, -109, 2, -2, -34, 94, -78, -88, -27, 70, 94, -86, 123, -49, 107, -65, -67, 84, 90, 123, -61, -2, 43, -119, -93, 75, -4, -81, 98, -36, 125, -23, -37, 81, 104, 90, -63, -52, 88, -96, -44, 25, 3, -37, -123, -48, 113, -76, -94, -109, -115, 37, -39, 104, -124, 82, -73, 100, 48, -54, -40, -65, 81, 16, -85, -41, 60, 42, 117, 65, 77, 14, -8, -56, 52, -118, -109, 125, 13, 64, -20, 125, -37, -74, -28, 118, 112, -126, 18, -101, 11, 75, 30, -4, -121, -13, -65, -13, -122, -53, -52, 20, -2, 67, 18, -106, 67, 83, -111, 15, 106, 10, 113, 53, -112, -3, 118, 8, -56, 40, 53, 23, -123, 96, 87, -118, -97, -116, -47, 85, -73, -85, -82, 124, -55, 55, 61, 46, 12, -6, 34, 22, -22, 3, 115, -49, 102, 23, 46, 39, 0, 118, 3, -45, 48, -73, -38, 29, -36, 11, -127, -86, 30, 29, -2, -108, -114, 64, 110, 86, -46, -91, -64, 95, -40, -65, 49, -79, -126, -37, -103, -71, 53, -85, 45, -51, 33, -28, -126, 36, -77, -120, 55, -54, 72, -21, 58, -87, -73, 18, -12, 20, -100, 30, 118, -83, -22, -90, 71, -64, 108, 101, -46, 36, 105, -46, -91, 60, -113, 72, 100, 82, -90, 106, -127, 65, -94, 17, 77, -10, -112, 46, 118, 72, -84, 57, -86, -114, 88, 91, 79, 30, 107, -35, 61, 81, 71, 40, -29, -6, -107, 61, -62, -6, 65, -68, 118, 61, 110, -115, -119, -73, 104, 59, -66, -89, -127, -8, -67, 122, -38, 79, -13, 93, 1, -32, -47, -3, 62, 88, -112, 105, 73, 96, 73, -104, -126, -69, 21, -22, 16, -85, 116, 9, 82, 54, -15, -55, -67, 68, -23, 16, -89, 48, -17, -107, 60, -43, -34, 66, -114, 63, -3, -26, 68, 68, -86, 120, -111, 99, 61, 101, 27, 93, 31, 90, -33, -94, 29, -89, 41, -80, 26, -23, -80, 27, 107, 69, -45, -123, 62, 63, 80, 1, -28, 52, -8, 35, -86, -127, 76, 102, 83, -104, -79, -98, 77, -28, 118, 18, -15, -98, -39, 2, -58, 95, 64, 105, -82, -7, 96, 110, 104, 127, 126, -124, 26, 36, 33, -42, 59, 82, 127, 42, -24, -61, -50, -18, -87, 22, -32, -125, -70, 103, -121, -112, -94, 58, -95, -97, 53, 95, -61, -83, 42, 37, 80, 51, -118, 125, 15, 67, 41, -97, 41, -121, 29, -88, 100, -113, 39, 101, 47, 91, -36, 48, -56, -13, 12, 37, 0, 81, 3, -40, 8, 36, -65, -11, -32, 108, 62, 79, 70, 91, -83, 2, -47, 0, 91, 10, 87, -19, -40, 96, 106, 41, 120, -53, 40, -114, 90, 64, 59, -115, 39, 2, 53, -49, -72, -114, 94, 5, 49, 74, 13, 50, -14, 76, -123, -11, -81, 100, 120, 16, -41, -72, -118, 28, 41, 98, 122, 27, 18, -108, -43, 51, -71, 93, -13, -42, -64, -118, -106, 45, 108, 72, -128, 58, -123, -29, -114, 15, 52, -72, 108, -62, 75, -15, 105, -89, 25, 37, 13, -21, -109, 68, 5, -89, 69, 10, -46, 18, -57, 77, -103, -74, 57, -43, -110, 1, -80, 82, 5, -9, -49, -53, 83, 4, 44, 64, -117, -67, -11, 1, -65, -81, 34, -23, -71, 14, 105, -93, 2, -120, 90, 92, -6, -128, -16, -51, 27, 123, 71, -117, -72, -81, 26, 28, 5, -117, -30, 22, -72, -76, -32, -14, 82, 90, 69, 74, -94, -72, -30, -17, 12, -37, -3, -80, 72, 2, -40, 41, 0, -53, 48, -37, -117, -128, -120, -80, 28, 49, -52, 114, -119, 92, -42, -105, 125, -95, 78, 76, 123, -56, 32, -66, 69, -58, 57, -77, -100, -70, 125, 53, -115, 8, 116, 88, -34, 86, -75, 55, 64, 79, -113, -124, -91, 50, -82, -119, 50, 11, 87, -14, -25, 15, -1, -49, -127, -5, -50, 72, -29, -78, 101, -119, -21, -15, 97, -63, 57, -123, -94, -24, -8, 104, 86, 79, 49, 102, -8, -76, 8, 69, 99, -64, -108, 70, 36, 71, -127, 56, 39, 78, 109, 42, -42, -2, 126, 17, -88, -65, -23, -64, 78, 87, 7, 6, -82, -98, 41, -46, -10, -25, 90, -73, 24, 127, -27, 118, -9, 81, -3, 115, -4, 47, 86, -30, -9, -50, 32, 86, 114, 58, -5, 78, 74, 36, 29, -126, 116, 117, -114, -92, -121, -36, -86, -18, 55, 49, 112, 43, 111, -99, -116, 70, 60, -63, 87, -4, -35, 15, 28, -27, -65, 66, 115, -33, 112, 94, 74, -22, 104, -56, -27, 39, -8, -53, -120, 8, -109, 73, -68, 67, 40, -59, 59, 121, -76, -41, -80, -54, -88, -120, -121, -118, -58, 74, -120, 82, -88, -113, 30, -8, 54, -126, -106, 37, -43, -74, -56, 40, -76, 93, 91, 28, -59, -30, -2, 107, 6, -89, -69, -121, -125, -109, 5, -94, -7, -2, -5, -67, 54, -90, 39, 5, -80, 93, -99, 82, -100, -128, -8, -39, -109, 66, -11, 99, -41, 18, -32, -122, 69, 6, -95, -21, 9, 19, -117, -34, -42, 11, 20, 84, 89, 91, -61, -13, -7, 55, 90, -15, 62, 59, -4, 125, -127, -24, -124, -99, -63, -23, 52, 111, -52, -60, -113, -65, -26, 127, 57, 21, 102, 101, -77, 66, -116, 117, 80, 7, 1, -96, -29, -99, 75, -73, 44, -99, 61, -73, 15, -18, 89, 95, 104, -12, 94, 33, 13, -49, 118, -84, -122, -2, -121, 62, -32, -80, 11, -10, 102, -67, 20, -3, 25, -6, 51, -17, -123, -76, 103, 3, 127, -107, -5, 122, 65, 22, 113, 120, 6, -19, -110, 86, 55, -88, -124, 0, -54, 17, 112, 15, 105, -28, 111, -93, 85, -59, -88, 28, 123, 55, 117, 10, 76, 54, -98, 116, 40, -65, -53, -80, 46, 66, -8, -114, 102, 66, 67, -117, 46, 21, -116, -38, 58, -105, 101, 37, -16, 5, 55, -33, -87, 72, 122, -114, -91, 41, -114, 77, 50, 109, 35, -61, 9, -55, -118, 126, -35, -108, 5, 62, 125, -109, -115, -55, 32, -71, 69, 110, 87, -82, 119, 26, 103, -77, -38, -13, 113, 74, 69, 116, 94, -21, 5, 35, 73, -80, -87, 80, 13, 108, 1, 82, -56, -35, -21, -78, -98, 121, 112, -117, 72, 47, 76, -97, -84, -110, -35, -19, -120, -13, 127, 5, 56, 72, -22, 110, -8, -71, 0, -57, -125, -101, 60, -64, -32, 1, 126, -109, 9, 84, 117, 62, -68, -106, 28, -118, -52, -81, 112, 11, 55, 68, -86, -65, 123, 83, 55, -72, 110, 63, -90, 31, 11, 90, -60, 20, 14, -36, 5, -92, 11, -100, 64, -57, -72, -105, 7, 103, 125, 99, -88, 32, -5, 41, -115, -11, 89, 81, 77, -33, -7, -123, -17, 109, 59, 40, -12, -61, 98, -91, 19, -36, 108, 118, -124, -82, -40, -124, -66, 19, 127, -73, -39, 99, 43, -16, -44, -83, -77, -34, 68, -118, -71, -116, 114, 120, -34, -105, -32, -46, 102, 73, -79, 7, 42, 35, -66, 125, 34, 113, 66, 78, 71, 6, 44, -17, 4, -80, 38, -59, 12, -8, -78, 103, 8, 80, 18, -74, 20, 3, 56, -20, 106, -1, -12, 83, 4, 68, -119, 84, -87, 97, -53, 102, 119, 34, -85, 22, -26, 55, -107, 96, -70, 77, -68, -96, -15, -22, -77, -55, 5, 103, -42, -87, 122, -80, -103, -37, -120, -56, -16, -51, -7, -19, -104, 120, 9, 54, -85, 48, -76, -38, 58, -68, 116, -20, -44, 22, -32, 75, -46, -41, 13, -100, 16, -59, -93, -115, 54, 22, -110, -46, -119, 44, -98, -48, 4, -58, -115, -57, 103, -56, 36, -63, 104, -114, -125, 92, 65, 117, -21, -59, -31, 56, -98, -126, 56, 47, -116, 100, 122, -98, 4, 26, -29, -127, -113, 73, 48, 106, 125, -69, -127, 62, 56, -79, 76, 84, -46, -31, -17, 94, -98, 62, 63, 118, -24, 63, 123, -93, -46, 103, 117, -120, -35, 19, 25, 15, -110, -125, 12, -75, -50, 103, 49, 47, 98, 92, 10, -88, 54, -53, 19, 25, -90, 93, -49, 64, 126, -106, -30, -52, 58, 37, 68, -18, -60, 15, -27, 93, -124, 88, 110, -80, -106, 88, 55, 108, -58, -43, -70, 76, 85, 98, 27, -66, 18, 75, 69, 114, 90, -26, -10, -12, -126, 84, -109, 108, 15, -115, 90, 11, -127, 63, -7, 47, 92, -72, 38, -58, -35, 18, 25, 12, -103, 0}; fullBytes = new byte[pubBytes.length + privBytes.length]; System.arraycopy(pubBytes, 0, fullBytes, 0, pubBytes.length); System.arraycopy(privBytes, 0, fullBytes, pubBytes.length, privBytes.length); priv = new NTRUEncryptionPrivateKeyParameters(fullBytes, params.getEncryptionParameters()); pub = new NTRUEncryptionPublicKeyParameters(pubBytes, params.getEncryptionParameters()); kp = new AsymmetricCipherKeyPair(pub, priv); ntru.init(true, kp.getPublic()); encrypted = ntru.processBlock(plainText, 0, plainText.length); ntru.init(false, kp.getPrivate()); decrypted = ntru.processBlock(encrypted, 0, encrypted.length); assertTrue(Arrays.areEqual(plainText, decrypted)); } // encrypts and decrypts text using an encoded key pair (fastFp=true) public void testEncodedKeysFast() throws IOException, InvalidCipherTextException { byte[] plainText = "secret encrypted text".getBytes(); NTRUEncryptionKeyGenerationParameters params = NTRUEncryptionKeyGenerationParameters.APR2011_743_FAST; NTRUEngine ntru = new NTRUEngine(); byte[] privBytes = {10, 16, 2, 30, -40, -63, -109, -77, -72, -122, 66, 23, -30, -44, -82, 0, 95, 64, 68, 48, -62, -14, 26, -19, -72, -25, 72, 123, 98, 84, -83, 0, 7, 40, 65, 35, 68, 113, 12, -112, 32, -123, 58, 85, -30, -109, -74, 0, 34, -8, -126, 57, 30, 98, -107, -45, -88, 102, 68, 42, -30, -108, -89, 0, 38, -40, -61, 37, 82, 113, -115, 123, -100, 5, 46, 125, -23, 78, -111, -76, 36, -90, 67, -31, 10, 2, 96, -127, 21, 50, -79, 13, -125, -124, 38, 55, -67, -95, 81, -107, 12, 117, -86, 99, -127, 11}; byte[] pubBytes = {108, -76, -104, -75, -87, -65, -18, -5, 45, -57, -100, -83, 51, 99, 94, 15, -73, 89, -100, 40, -114, 91, -107, 104, 127, 22, 13, 5, -16, 69, -104, -126, -44, 119, 47, -48, 75, 66, 83, -37, -66, -84, 73, 52, 23, -27, 53, 63, 56, 14, -2, 43, -59, -85, -80, 46, 38, -126, 75, -8, -63, 88, 104, 13, 72, -25, -10, -58, -51, 117, -84, 115, -24, -53, 83, -103, -97, 46, 90, -82, -61, 113, -49, -24, -72, 24, -124, -42, -36, 7, 41, 8, 14, -71, -75, -84, -24, -39, 56, 67, 88, 67, 66, -13, 70, -119, -64, 74, -100, -58, 35, 105, -20, 93, 80, -116, -55, 37, -52, 64, 0, -36, -71, 8, 77, -10, -41, -22, -73, 4, -115, -74, -74, -73, 23, -10, -26, 48, 125, -114, -32, -116, 74, 19, -104, 59, 43, 4, 97, -84, 112, 45, 16, 3, -110, -13, 119, -6, 29, -80, 109, 82, -31, 82, 30, 76, -111, -122, -50, -69, -41, -123, 107, 78, -35, 24, -121, -87, -108, 13, 70, 32, -74, 112, 104, -40, -61, 86, -125, 60, -94, -5, -18, 55, 54, -128, 83, -88, 71, 71, -66, 29, -113, 120, 30, 16, -38, 37, 96, -90, 38, -85, 88, 59, 15, -69, 6, -8, 1, 1, 71, 12, 60, -26, -110, 97, 77, 33, 58, 63, 104, 108, 83, 72, -21, -99, 115, -125, -16, 12, 99, 68, 39, -97, -6, 17, 26, -59, 123, -110, -37, -71, 47, 50, 5, 110, -34, 89, -74, 20, 79, -108, -7, 42, 106, -112, 44, 107, 106, -50, 55, 127, -124, 53, 123, -119, -46, -114, -52, -85, 75, 34, -39, -125, 58, -5, -31, -81, -37, -94, -123, 113, 11, -104, -124, 96, -103, 9, 108, 115, 97, -6, 98, -43, 26, -89, -23, 83, 60, 34, -86, -54, 107, 78, -48, 118, -31, -19, 29, -106, 108, 117, 83, 119, 51, -45, 115, 108, -13, -89, -29, 29, -120, 108, 20, 22, -3, 22, 78, -109, 95, 3, -68, -10, -53, -117, -96, -49, 9, 7, 38, 116, 33, -65, 31, 9, -5, -73, 127, 52, 113, 87, -39, 119, -96, 74, -105, 75, -89, 63, 69, -109, -127, 92, -54, 17, -98, -23, -69, 123, -125, 23, -93, 44, -11, -25, -101, 120, -29, 113, -33, 0, -117, -100, -114, 22, 41, -46, 29, -109, 107, 37, -94, 125, 46, 17, 16, -65, -14, 105, -118, 51, -21, 121, -5, 56, 29, 30, -69, -38, -10, -77, -74, 6, -105, 83, 110, 23, 114, -11, -123, -14, 30, -11, -9, 84, -90, -20, -29, 72, -85, 97, -74, -59, -112, -15, -51, -105, 117, 123, -17, -64, -127, 127, -33, -102, 88, 77, 122, -127, -15, 121, -125, -32, 53, 113, 45, -22, 84, -87, 20, 36, 65, 83, -84, -66, -22, 4, 15, -108, -92, 109, -128, -48, 4, -27, -13, 25, 51, -10, 34, 87, 88, 38, -87, 89, -64, -62, 20, 78, 35, -26, -2, 55, 3, -72, -64, 30, 28, -105, 6, -37, -38, -8, 26, -118, 105, -37, -30, 85, -66, 105, -46, -37, -11, -72, 71, 43, -65, -44, 17, -79, 98, 79, -77, -111, 95, 74, 101, -40, -106, 14, -108, -112, 86, 108, 49, 72, -38, -103, -31, 65, -119, 8, 78, -89, 100, -28, 116, 94, 15, -18, 108, 101, 85, 8, -6, 111, -82, -49, -66, -89, 28, -84, -85, -119, 111, 45, 83, -60, -40, -45, -101, -105, -35, 123, -1, 13, -112, 79, -80, -85, -109, -71, 69, 104, 95, -93, 121, -17, 83, 117, -73, -63, -65, -107, -72, 118, -102, -56, 38, 79, 121, -25, -86, -81, -38, 8, 122, 97, 37, 82, -40, 53, 11, 124, -94, -76, -107, -125, -9, -119, 63, 52, -34, -72, -21, 59, 3, -100, -127, 47, -102, 19, -37, -45, -114, -65, 39, -106, 6, -127, -110, -38, 96, -38, -51, 110, -3, 28, 8, 102, -102, 96, -127, 109, -56, -53, -13, 59, -98, 92, 80, 1, 55, -91, -122, -105, 28, 69, -85, 109, -38, 105, 87, -5, 3, -102, 62, -92, 60, 43, -20, -7, -23, -84, 106, 121, -48, 123, -112, 56, -17, -52, 14, -123, -122, 64, 14, -23, -71, 60, 70, -121, 6, 37, -15, 77, 96, 104, -34, 58, -125, -61, 1, -26, 118, -78, -35, -1, 0, 5, 33, -98, -86, -127, 25, 56, -91, 82, -33, 60, -64, -86, 27, 31, -80, -79, 118, -12, -18, 40, -72, 32, 119, -28, -62, 100, -121, -71, -79, -9, 38, -37, 25, 65, -46, 8, -112, 37, 9, -56, 123, -40, -44, -90, -21, -54, -2, -7, 107, -93, 24, -126, 69, 42, -111, -84, 57, 69, -119, 21, 60, 57, -122, 111, -99, 49, -46, -119, 100, 98, 24, -62, 112, 122, 46, 18, -35, -67, 89, 104, 82, 12, 125, 57, -70, -112, -109, 96, 51, -68, 1, -101, -59, -92, 54, 85, -41, 17, 31, 94, 75, -128, 53, 84, 0, -83, -94, -123, 49, -30, -24, 18, 46, 48, -33, 120, 66, -69, 70, 23, -124, -117, 81, 96, 46, 47, -33, 83, -13, -14, -94, 49, 66, -46, 84, -27, -77, 6, 0, -75, -18, 86, -119, -88, 82, -50, 55, -20, 63, 55, -57, 22, -108, -103, -17, -22, 64, 65, 90, -34, -96, -117, 51, 119, -103, -35, 95, -15, -118, 2, -31, 31, -9, -58, 84, -75, 80, 39, -101, -56, 16, -75, 59, 48, -63, -24, -95, 119, 73, -110, -115, 49, -18, 54, -124, 112, -61, -40, -105, -118, -66, 15, -107, 75, 82, -70, -87, -11, -11, 48, 41, 119, -42, -34, -33, 57, 23, -14, -45, -125, -108, -75, 3, 44, 44, 58, 126, -126, -20, -123, 58, 114, 79, -102, -115, 115, 12, 66, 108, 84, 43, -46, -80, -41, -70, 111, -114, 123, 21, 1, 34, -72, 23, 105, -52, -39, -54, -119, 45, 77, -16, -66, -105, -11, 91, -46, 77, -104, -93, 52, -3, 17, 55, -10, 67, -33, 43, 75, -103, 106, 7, -35, -65, -21, 68, 118, -38, 59, -115, 31}; byte[] fullBytes = new byte[pubBytes.length + privBytes.length]; System.arraycopy(pubBytes, 0, fullBytes, 0, pubBytes.length); System.arraycopy(privBytes, 0, fullBytes, pubBytes.length, privBytes.length); NTRUEncryptionPrivateKeyParameters priv = new NTRUEncryptionPrivateKeyParameters(fullBytes, params.getEncryptionParameters()); NTRUEncryptionPublicKeyParameters pub = new NTRUEncryptionPublicKeyParameters(pubBytes, params.getEncryptionParameters()); AsymmetricCipherKeyPair kp = new AsymmetricCipherKeyPair(pub, priv); ntru.init(true, kp.getPublic()); byte[] encrypted = ntru.processBlock(plainText, 0, plainText.length); assertEquals(encrypted.length, ntru.getOutputBlockSize()); ntru.init(false, kp.getPrivate()); byte[] decrypted = ntru.processBlock(encrypted, 0, encrypted.length); assertTrue(Arrays.areEqual(plainText, decrypted)); } private class VisibleNTRUEngine extends NTRUEngine { public IntegerPolynomial encrypt(IntegerPolynomial m, TernaryPolynomial r, IntegerPolynomial pubKey) { return super.encrypt(m, r, pubKey); } public IntegerPolynomial decrypt(IntegerPolynomial e, Polynomial priv_t, IntegerPolynomial priv_fp) { return super.decrypt(e, priv_t, priv_fp); } } }bouncycastle-1.49.orig/test/src/org/bouncycastle/pqc/crypto/test/NTRUEncryptionParametersTest.java0000644000175000017500000000361612113320253033133 0ustar ebourgebourgpackage org.bouncycastle.pqc.crypto.test; import java.io.ByteArrayInputStream; import java.io.ByteArrayOutputStream; import java.io.IOException; import junit.framework.TestCase; import org.bouncycastle.pqc.crypto.ntru.NTRUEncryptionKeyGenerationParameters; public class NTRUEncryptionParametersTest extends TestCase { public void testLoadSave() throws IOException { NTRUEncryptionKeyGenerationParameters params = NTRUEncryptionKeyGenerationParameters.EES1499EP1; ByteArrayOutputStream os = new ByteArrayOutputStream(); params.writeTo(os); ByteArrayInputStream is = new ByteArrayInputStream(os.toByteArray()); assertEquals(params, new NTRUEncryptionKeyGenerationParameters(is)); } public void testEqualsHashCode() throws IOException { ByteArrayOutputStream os = new ByteArrayOutputStream(); NTRUEncryptionKeyGenerationParameters.EES1499EP1.writeTo(os); ByteArrayInputStream is = new ByteArrayInputStream(os.toByteArray()); NTRUEncryptionKeyGenerationParameters params = new NTRUEncryptionKeyGenerationParameters(is); assertEquals(params, NTRUEncryptionKeyGenerationParameters.EES1499EP1); assertEquals(params.hashCode(), NTRUEncryptionKeyGenerationParameters.EES1499EP1.hashCode()); params.N += 1; assertFalse(params.equals(NTRUEncryptionKeyGenerationParameters.EES1499EP1)); assertFalse(NTRUEncryptionKeyGenerationParameters.EES1499EP1.equals(params)); assertFalse(params.hashCode() == NTRUEncryptionKeyGenerationParameters.EES1499EP1.hashCode()); } public void testClone() { NTRUEncryptionKeyGenerationParameters params = NTRUEncryptionKeyGenerationParameters.APR2011_439; assertEquals(params, params.clone()); params = NTRUEncryptionKeyGenerationParameters.APR2011_439_FAST; assertEquals(params, params.clone()); } }bouncycastle-1.49.orig/test/src/org/bouncycastle/pqc/crypto/test/AllTests.java0000644000175000017500000000253412146616656027162 0ustar ebourgebourgpackage org.bouncycastle.pqc.crypto.test; import junit.framework.Test; import junit.framework.TestCase; import junit.framework.TestSuite; import org.bouncycastle.util.test.SimpleTestResult; public class AllTests extends TestCase { public void testCrypto() { org.bouncycastle.util.test.Test[] tests = RegressionTest.tests; for (int i = 0; i != tests.length; i++) { SimpleTestResult result = (SimpleTestResult)tests[i].perform(); if (!result.isSuccessful()) { fail(result.toString()); } } } public static void main (String[] args) { junit.textui.TestRunner.run(suite()); } public static Test suite() { TestSuite suite = new TestSuite("Lightweight PQ Crypto Tests"); suite.addTestSuite(AllTests.class); suite.addTestSuite(BitStringTest.class); suite.addTestSuite(EncryptionKeyTest.class); suite.addTestSuite(NTRUEncryptionParametersTest.class); suite.addTestSuite(NTRUEncryptTest.class); suite.addTestSuite(NTRUSignatureParametersTest.class); suite.addTestSuite(NTRUSignatureKeyTest.class); suite.addTestSuite(NTRUSignerTest.class); suite.addTestSuite(NTRUSigningParametersTest.class); return suite; } } bouncycastle-1.49.orig/test/src/org/bouncycastle/pqc/crypto/test/RainbowSignerTest.java0000644000175000017500000000437012151252353031022 0ustar ebourgebourgpackage org.bouncycastle.pqc.crypto.test; import java.math.BigInteger; import java.security.SecureRandom; import org.bouncycastle.crypto.AsymmetricCipherKeyPair; import org.bouncycastle.crypto.digests.SHA224Digest; import org.bouncycastle.crypto.params.ParametersWithRandom; import org.bouncycastle.pqc.crypto.DigestingMessageSigner; import org.bouncycastle.pqc.crypto.rainbow.RainbowKeyGenerationParameters; import org.bouncycastle.pqc.crypto.rainbow.RainbowKeyPairGenerator; import org.bouncycastle.pqc.crypto.rainbow.RainbowParameters; import org.bouncycastle.pqc.crypto.rainbow.RainbowSigner; import org.bouncycastle.util.BigIntegers; import org.bouncycastle.util.encoders.Hex; import org.bouncycastle.util.test.FixedSecureRandom; import org.bouncycastle.util.test.SimpleTest; public class RainbowSignerTest extends SimpleTest { byte[] keyData = Hex.decode("b5014e4b60ef2ba8b6211b4062ba3224e0427dd3"); SecureRandom keyRandom = new FixedSecureRandom(new byte[][] { keyData, keyData }); public String getName() { return "Rainbow"; } public void performTest() { RainbowParameters params = new RainbowParameters(); RainbowKeyPairGenerator rainbowKeyGen = new RainbowKeyPairGenerator(); RainbowKeyGenerationParameters genParam = new RainbowKeyGenerationParameters(keyRandom, params); rainbowKeyGen.init(genParam); AsymmetricCipherKeyPair pair = rainbowKeyGen.generateKeyPair(); ParametersWithRandom param = new ParametersWithRandom(pair.getPrivate(), keyRandom); DigestingMessageSigner rainbowSigner = new DigestingMessageSigner(new RainbowSigner() , new SHA224Digest()); rainbowSigner.init(true, param); byte[] message = BigIntegers.asUnsignedByteArray(new BigInteger("968236873715988614170569073515315707566766479517")); rainbowSigner.update(message, 0, message.length); byte[] sig = rainbowSigner.generateSignature(); rainbowSigner.init(false, pair.getPublic()); rainbowSigner.update(message, 0, message.length); if (!rainbowSigner.verify(sig)) { fail("verification fails"); } } public static void main( String[] args) { runTest(new RainbowSignerTest()); } } bouncycastle-1.49.orig/test/src/org/bouncycastle/pqc/crypto/test/NTRUSignerTest.java0000644000175000017500000002503012146637147030221 0ustar ebourgebourgpackage org.bouncycastle.pqc.crypto.test; import java.io.IOException; import java.util.Random; import junit.framework.TestCase; import org.bouncycastle.crypto.AsymmetricCipherKeyPair; import org.bouncycastle.pqc.crypto.ntru.NTRUSigner; import org.bouncycastle.pqc.crypto.ntru.NTRUSigningKeyGenerationParameters; import org.bouncycastle.pqc.crypto.ntru.NTRUSigningKeyPairGenerator; import org.bouncycastle.pqc.crypto.ntru.NTRUSigningParameters; import org.bouncycastle.pqc.crypto.ntru.NTRUSigningPrivateKeyParameters; import org.bouncycastle.pqc.crypto.ntru.NTRUSigningPublicKeyParameters; import org.bouncycastle.pqc.math.ntru.polynomial.IntegerPolynomial; import org.bouncycastle.pqc.math.ntru.polynomial.Polynomial; import org.bouncycastle.util.Arrays; public class NTRUSignerTest extends TestCase { public void testCreateBasis() { for (NTRUSigningKeyGenerationParameters params : new NTRUSigningKeyGenerationParameters[]{NTRUSigningKeyGenerationParameters.TEST157.clone(), NTRUSigningKeyGenerationParameters.TEST157_PROD.clone()}) { testCreateBasis(params); } } private void testCreateBasis(NTRUSigningKeyGenerationParameters params) { NTRUSigningKeyPairGenerator ntru = new NTRUSigningKeyPairGenerator(); ntru.init(params); NTRUSigningKeyPairGenerator.FGBasis basis = (NTRUSigningKeyPairGenerator.FGBasis)ntru.generateBoundedBasis(); assertTrue(equalsQ(basis.f, basis.fPrime, basis.F, basis.G, params.q, params.N)); // test KeyGenAlg.FLOAT (default=RESULTANT) params.keyGenAlg = NTRUSigningKeyGenerationParameters.KEY_GEN_ALG_FLOAT; ntru.init(params); basis = (NTRUSigningKeyPairGenerator.FGBasis)ntru.generateBoundedBasis(); assertTrue(equalsQ(basis.f, basis.fPrime, basis.F, basis.G, params.q, params.N)); } // verifies that f*G-g*F=q private boolean equalsQ(Polynomial f, Polynomial g, IntegerPolynomial F, IntegerPolynomial G, int q, int N) { IntegerPolynomial x = f.mult(G); x.sub(g.mult(F)); boolean equalsQ = true; for (int i = 1; i < x.coeffs.length; i++) { equalsQ &= x.coeffs[i] == 0; } equalsQ &= x.coeffs[0] == q; return equalsQ; } /** * a test for the one-method-call variants: sign(byte, SignatureKeyPair) and verify(byte[], byte[], SignatureKeyPair) */ public void testSignVerify() throws IOException { for (NTRUSigningKeyGenerationParameters params : new NTRUSigningKeyGenerationParameters[]{NTRUSigningKeyGenerationParameters.TEST157.clone(), NTRUSigningKeyGenerationParameters.TEST157_PROD.clone()}) { testSignVerify(params); } } private void testSignVerify(NTRUSigningKeyGenerationParameters params) throws IOException { NTRUSigner ntru = new NTRUSigner(params.getSigningParameters()); NTRUSigningKeyPairGenerator kGen = new NTRUSigningKeyPairGenerator(); kGen.init(params); AsymmetricCipherKeyPair kp = kGen.generateKeyPair(); Random rng = new Random(); byte[] msg = new byte[10 + rng.nextInt(1000)]; rng.nextBytes(msg); // sign and verify ntru.init(true, kp.getPrivate()); ntru.update(msg, 0, msg.length); byte[] s = ntru.generateSignature(); ntru.init(false, kp.getPublic()); ntru.update(msg, 0, msg.length); boolean valid = ntru.verifySignature(s); assertTrue(valid); // altering the signature should make it invalid s[rng.nextInt(params.N)] += 1; ntru.init(false, kp.getPublic()); ntru.update(msg, 0, msg.length); valid = ntru.verifySignature(s); assertFalse(valid); // test that a random signature fails rng.nextBytes(s); ntru.init(false, kp.getPublic()); ntru.update(msg, 0, msg.length); valid = ntru.verifySignature(s); assertFalse(valid); // encode, decode keypair, test NTRUSigningPrivateKeyParameters priv = new NTRUSigningPrivateKeyParameters(((NTRUSigningPrivateKeyParameters)kp.getPrivate()).getEncoded(), params); NTRUSigningPublicKeyParameters pub = new NTRUSigningPublicKeyParameters(((NTRUSigningPublicKeyParameters)kp.getPublic()).getEncoded(), params.getSigningParameters()); kp = new AsymmetricCipherKeyPair(pub, priv); ntru.init(true, kp.getPrivate()); ntru.update(msg, 0, msg.length); s = ntru.generateSignature(); ntru.init(false, kp.getPublic()); ntru.update(msg, 0, msg.length); valid = ntru.verifySignature(s); assertTrue(valid); // altering the signature should make it invalid s[rng.nextInt(s.length)] += 1; ntru.init(false, kp.getPublic()); ntru.update(msg, 0, msg.length); valid = ntru.verifySignature(s); assertFalse(valid); // sparse/dense params.sparse = !params.sparse; ntru.init(true, kp.getPrivate()); ntru.update(msg, 0, msg.length); s = ntru.generateSignature(); ntru.init(false, kp.getPublic()); ntru.update(msg, 0, msg.length); valid = ntru.verifySignature(s); assertTrue(valid); s[rng.nextInt(s.length)] += 1; ntru.init(false, kp.getPublic()); ntru.update(msg, 0, msg.length); valid = ntru.verifySignature(s); assertFalse(valid); params.sparse = !params.sparse; // decrease NormBound to force multiple signing attempts NTRUSigningKeyGenerationParameters params2 = params.clone(); params2.normBoundSq *= 4.0 / 9; params2.signFailTolerance = 10000; ntru = new NTRUSigner(params2.getSigningParameters()); ntru.init(true, kp.getPrivate()); ntru.update(msg, 0, msg.length); s = ntru.generateSignature(); ntru.init(false, kp.getPublic()); ntru.update(msg, 0, msg.length); valid = ntru.verifySignature(s); assertTrue(valid); // test KeyGenAlg.FLOAT (default=RESULTANT) params2 = params.clone(); params.keyGenAlg = NTRUSigningKeyGenerationParameters.KEY_GEN_ALG_FLOAT; ntru = new NTRUSigner(params.getSigningParameters()); kGen.init(params); kp = kGen.generateKeyPair(); ntru.init(true, kp.getPrivate()); ntru.update(msg, 0, msg.length); s = ntru.generateSignature(); ntru.init(false, kp.getPublic()); ntru.update(msg, 0, msg.length); valid = ntru.verifySignature(s); assertTrue(valid); s[rng.nextInt(s.length)] += 1; ntru.init(false, kp.getPublic()); ntru.update(msg, 0, msg.length); valid = ntru.verifySignature(s); assertFalse(valid); } /** * test for the initSign/update/sign and initVerify/update/verify variant */ public void testInitUpdateSign() { for (NTRUSigningKeyGenerationParameters params : new NTRUSigningKeyGenerationParameters[]{NTRUSigningKeyGenerationParameters.TEST157.clone(), NTRUSigningKeyGenerationParameters.TEST157_PROD.clone()}) { testInitUpdateSign(params); } } private void testInitUpdateSign(NTRUSigningKeyGenerationParameters params) { NTRUSigner ntru = new NTRUSigner(params.getSigningParameters()); NTRUSigningKeyPairGenerator kGen = new NTRUSigningKeyPairGenerator(); kGen.init(params); AsymmetricCipherKeyPair kp = kGen.generateKeyPair(); Random rng = new Random(); byte[] msg = new byte[10 + rng.nextInt(1000)]; rng.nextBytes(msg); // sign and verify a message in two pieces each ntru.init(true, kp.getPrivate()); int splitIdx = rng.nextInt(msg.length); ntru.update(msg[0]); // first byte ntru.update(msg, 1, splitIdx - 1); // part 1 of msg ntru.update(msg, splitIdx, msg.length - splitIdx); byte[] s = ntru.generateSignature(); // part 2 of msg ntru.init(false, kp.getPublic()); splitIdx = rng.nextInt(msg.length); ntru.update(msg, 0, splitIdx); // part 1 of msg ntru.update(msg, splitIdx, msg.length - splitIdx); // part 2 of msg boolean valid = ntru.verifySignature(s); assertTrue(valid); // verify the same signature with the one-step method ntru.init(false, (NTRUSigningPublicKeyParameters)kp.getPublic()); ntru.update(msg, 0, msg.length); // part 1 of msg valid = ntru.verifySignature(s); assertTrue(valid); // sign using the one-step method and verify using the multi-step method ntru.init(true, kp.getPrivate()); ntru.update(msg, 0, msg.length); s = ntru.generateSignature(); ntru.init(false, (NTRUSigningPublicKeyParameters)kp.getPublic()); splitIdx = rng.nextInt(msg.length); ntru.update(msg, 0, splitIdx); // part 1 of msg ntru.update(msg, splitIdx, msg.length - splitIdx); // part 2 of msg valid = ntru.verifySignature(s); assertTrue(valid); } public void testCreateMsgRep() { for (NTRUSigningKeyGenerationParameters params : new NTRUSigningKeyGenerationParameters[]{NTRUSigningKeyGenerationParameters.TEST157.clone(), NTRUSigningKeyGenerationParameters.TEST157_PROD.clone()}) { testCreateMsgRep(params); } } private void testCreateMsgRep(NTRUSigningKeyGenerationParameters params) { VisibleNTRUSigner ntru = new VisibleNTRUSigner(params.getSigningParameters()); byte[] msgHash = "adfsadfsdfs23234234".getBytes(); // verify that the message representative is reproducible IntegerPolynomial i1 = ntru.createMsgRep(msgHash, 1); IntegerPolynomial i2 = ntru.createMsgRep(msgHash, 1); assertTrue(Arrays.areEqual(i1.coeffs, i2.coeffs)); i1 = ntru.createMsgRep(msgHash, 5); i2 = ntru.createMsgRep(msgHash, 5); assertTrue(Arrays.areEqual(i1.coeffs, i2.coeffs)); i1 = ntru.createMsgRep(msgHash, 2); i2 = ntru.createMsgRep(msgHash, 3); assertFalse(Arrays.areEqual(i1.coeffs, i2.coeffs)); } private class VisibleNTRUSigner extends NTRUSigner { /** * Constructs a new instance with a set of signature parameters. * * @param params signature parameters */ public VisibleNTRUSigner(NTRUSigningParameters params) { super(params); } public IntegerPolynomial createMsgRep(byte[] hash, int i) { return super.createMsgRep(hash, i); } } }bouncycastle-1.49.orig/test/src/org/bouncycastle/pqc/crypto/test/NTRUSigningParametersTest.java0000644000175000017500000000436112146637147032420 0ustar ebourgebourgpackage org.bouncycastle.pqc.crypto.test; import java.io.ByteArrayInputStream; import java.io.ByteArrayOutputStream; import java.io.IOException; import junit.framework.TestCase; import org.bouncycastle.pqc.crypto.ntru.NTRUSigningKeyGenerationParameters; public class NTRUSigningParametersTest extends TestCase { public void testLoadSave() throws IOException { for (NTRUSigningKeyGenerationParameters params : new NTRUSigningKeyGenerationParameters[]{NTRUSigningKeyGenerationParameters.TEST157, NTRUSigningKeyGenerationParameters.TEST157_PROD}) { testLoadSave(params); } } private void testLoadSave(NTRUSigningKeyGenerationParameters params) throws IOException { ByteArrayOutputStream os = new ByteArrayOutputStream(); params.writeTo(os); ByteArrayInputStream is = new ByteArrayInputStream(os.toByteArray()); assertEquals(params, new NTRUSigningKeyGenerationParameters(is)); } public void testEqualsHashCode() throws IOException { for (NTRUSigningKeyGenerationParameters params : new NTRUSigningKeyGenerationParameters[]{NTRUSigningKeyGenerationParameters.TEST157, NTRUSigningKeyGenerationParameters.TEST157_PROD}) { testEqualsHashCode(params); } } private void testEqualsHashCode(NTRUSigningKeyGenerationParameters params) throws IOException { ByteArrayOutputStream os = new ByteArrayOutputStream(); params.writeTo(os); ByteArrayInputStream is = new ByteArrayInputStream(os.toByteArray()); NTRUSigningKeyGenerationParameters params2 = new NTRUSigningKeyGenerationParameters(is); assertEquals(params, params2); assertEquals(params.hashCode(), params2.hashCode()); params.N += 1; assertFalse(params.equals(params2)); assertFalse(params.equals(params2)); assertFalse(params.hashCode() == params2.hashCode()); } public void testClone() { for (NTRUSigningKeyGenerationParameters params : new NTRUSigningKeyGenerationParameters[]{NTRUSigningKeyGenerationParameters.TEST157, NTRUSigningKeyGenerationParameters.TEST157_PROD}) { assertEquals(params, params.clone()); } } }bouncycastle-1.49.orig/test/src/org/bouncycastle/pqc/crypto/test/McElieceFujisakiCipherTest.java0000644000175000017500000000673312105021514032535 0ustar ebourgebourgpackage org.bouncycastle.pqc.crypto.test; import java.security.SecureRandom; import java.util.Random; import org.bouncycastle.crypto.AsymmetricCipherKeyPair; import org.bouncycastle.crypto.Digest; import org.bouncycastle.crypto.digests.SHA256Digest; import org.bouncycastle.crypto.params.ParametersWithRandom; import org.bouncycastle.pqc.crypto.mceliece.McElieceCCA2KeyGenerationParameters; import org.bouncycastle.pqc.crypto.mceliece.McElieceCCA2KeyPairGenerator; import org.bouncycastle.pqc.crypto.mceliece.McElieceCCA2Parameters; import org.bouncycastle.pqc.crypto.mceliece.McElieceFujisakiCipher; import org.bouncycastle.pqc.crypto.mceliece.McElieceFujisakiDigestCipher; import org.bouncycastle.util.test.SimpleTest; public class McElieceFujisakiCipherTest extends SimpleTest { SecureRandom keyRandom = new SecureRandom(); public String getName() { return "McElieceFujisaki"; } public void performTest() { int numPassesKPG = 1; int numPassesEncDec = 10; Random rand = new Random(); byte[] mBytes; for (int j = 0; j < numPassesKPG; j++) { McElieceCCA2Parameters params = new McElieceCCA2Parameters(); McElieceCCA2KeyPairGenerator mcElieceCCA2KeyGen = new McElieceCCA2KeyPairGenerator(); McElieceCCA2KeyGenerationParameters genParam = new McElieceCCA2KeyGenerationParameters(keyRandom, params); mcElieceCCA2KeyGen.init(genParam); AsymmetricCipherKeyPair pair = mcElieceCCA2KeyGen.generateKeyPair(); ParametersWithRandom param = new ParametersWithRandom(pair.getPublic(), keyRandom); Digest msgDigest = new SHA256Digest(); McElieceFujisakiDigestCipher mcElieceFujisakiDigestCipher = new McElieceFujisakiDigestCipher(new McElieceFujisakiCipher(), msgDigest); for (int k = 1; k <= numPassesEncDec; k++) { System.out.println("############### test: " + k); // initialize for encryption mcElieceFujisakiDigestCipher.init(true, param); // generate random message int mLength = (rand.nextInt() & 0x1f) + 1;; mBytes = new byte[mLength]; rand.nextBytes(mBytes); // encrypt mcElieceFujisakiDigestCipher.update(mBytes, 0, mBytes.length); byte[] enc = mcElieceFujisakiDigestCipher.messageEncrypt(); // initialize for decryption mcElieceFujisakiDigestCipher.init(false, pair.getPrivate()); byte[] constructedmessage = mcElieceFujisakiDigestCipher.messageDecrypt(enc); // XXX write in McElieceFujisakiDigestCipher? msgDigest.update(mBytes, 0, mBytes.length); byte[] hash = new byte[msgDigest.getDigestSize()]; msgDigest.doFinal(hash, 0); boolean verified = true; for (int i = 0; i < hash.length; i++) { verified = verified && hash[i] == constructedmessage[i]; } if (!verified) { fail("en/decryption fails"); } else { System.out.println("test okay"); System.out.println(); } } } } public static void main( String[] args) { runTest(new McElieceFujisakiCipherTest()); } } bouncycastle-1.49.orig/test/src/org/bouncycastle/pqc/crypto/test/RegressionTest.java0000644000175000017500000000147212104616324030371 0ustar ebourgebourgpackage org.bouncycastle.pqc.crypto.test; import org.bouncycastle.util.test.Test; import org.bouncycastle.util.test.TestResult; public class RegressionTest { public static Test[] tests = { new GMSSSignerTest(), new McElieceFujisakiCipherTest(), new McElieceKobaraImaiCipherTest(), new McEliecePKCSCipherTest(), new McEliecePointchevalCipherTest(), new RainbowSignerTest() }; public static void main( String[] args) { for (int i = 0; i != tests.length; i++) { TestResult result = tests[i].perform(); if (result.getException() != null) { result.getException().printStackTrace(); } System.out.println(result); } } } bouncycastle-1.49.orig/test/src/org/bouncycastle/pqc/math/0000755000175000017500000000000012152033550023171 5ustar ebourgebourgbouncycastle-1.49.orig/test/src/org/bouncycastle/pqc/math/ntru/0000755000175000017500000000000012152033550024161 5ustar ebourgebourgbouncycastle-1.49.orig/test/src/org/bouncycastle/pqc/math/ntru/util/0000755000175000017500000000000012152033550025136 5ustar ebourgebourgbouncycastle-1.49.orig/test/src/org/bouncycastle/pqc/math/ntru/util/test/0000755000175000017500000000000012152033550026115 5ustar ebourgebourgbouncycastle-1.49.orig/test/src/org/bouncycastle/pqc/math/ntru/util/test/AllTests.java0000644000175000017500000000077112113311460030514 0ustar ebourgebourgpackage org.bouncycastle.pqc.math.ntru.util.test; import junit.framework.Test; import junit.framework.TestCase; import junit.framework.TestSuite; public class AllTests extends TestCase { public static void main (String[] args) { junit.textui.TestRunner.run(suite()); } public static Test suite() { TestSuite suite = new TestSuite("NTRU ArrayEncoder Tests"); suite.addTestSuite(ArrayEncoderTest.class); return suite; } } bouncycastle-1.49.orig/test/src/org/bouncycastle/pqc/math/ntru/util/test/ArrayEncoderTest.java0000644000175000017500000000265612113311460032203 0ustar ebourgebourgpackage org.bouncycastle.pqc.math.ntru.util.test; import java.security.SecureRandom; import java.util.Random; import junit.framework.TestCase; import org.bouncycastle.pqc.math.ntru.polynomial.DenseTernaryPolynomial; import org.bouncycastle.pqc.math.ntru.polynomial.test.PolynomialGenerator; import org.bouncycastle.pqc.math.ntru.util.ArrayEncoder; import org.bouncycastle.util.Arrays; public class ArrayEncoderTest extends TestCase { public void testEncodeDecodeModQ() { int[] coeffs = PolynomialGenerator.generateRandom(1000, 2048).coeffs; byte[] data = ArrayEncoder.encodeModQ(coeffs, 2048); int[] coeffs2 = ArrayEncoder.decodeModQ(data, 1000, 2048); assertTrue(Arrays.areEqual(coeffs, coeffs2)); } public void testEncodeDecodeMod3Sves() { Random rng = new Random(); byte[] data = new byte[180]; rng.nextBytes(data); int[] coeffs = ArrayEncoder.decodeMod3Sves(data, 960); byte[] data2 = ArrayEncoder.encodeMod3Sves(coeffs); assertTrue(Arrays.areEqual(data, data2)); } public void testEncodeDecodeMod3Tight() { SecureRandom random = new SecureRandom(); int[] coeffs = DenseTernaryPolynomial.generateRandom(1000, random).coeffs; byte[] data = ArrayEncoder.encodeMod3Tight(coeffs); int[] coeffs2 = ArrayEncoder.decodeMod3Tight(data, 1000); assertTrue(Arrays.areEqual(coeffs, coeffs2)); } }bouncycastle-1.49.orig/test/src/org/bouncycastle/pqc/math/ntru/euclid/0000755000175000017500000000000012152033550025426 5ustar ebourgebourgbouncycastle-1.49.orig/test/src/org/bouncycastle/pqc/math/ntru/euclid/test/0000755000175000017500000000000012152033550026405 5ustar ebourgebourgbouncycastle-1.49.orig/test/src/org/bouncycastle/pqc/math/ntru/euclid/test/IntEuclideanTest.java0000644000175000017500000000321212113311460032446 0ustar ebourgebourg/** * Copyright (c) 2011 Tim Buktu (tbuktu@hotmail.com) * * Permission is hereby granted, free of charge, to any person obtaining a * copy of this software and associated documentation files (the "Software"), * to deal in the Software without restriction, including without limitation * the rights to use, copy, modify, merge, publish, distribute, sublicense, * and/or sell copies of the Software, and to permit persons to whom the * Software is furnished to do so, subject to the following conditions: * * The above copyright notice and this permission notice shall be included in * all copies or substantial portions of the Software. * * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER * DEALINGS IN THE SOFTWARE. */ package org.bouncycastle.pqc.math.ntru.euclid.test; import junit.framework.TestCase; import org.bouncycastle.pqc.math.ntru.euclid.IntEuclidean; public class IntEuclideanTest extends TestCase { public void testCalculate() { IntEuclidean r = IntEuclidean.calculate(120, 23); assertEquals(-9, r.x); assertEquals(47, r.y); assertEquals(1, r.gcd); r = IntEuclidean.calculate(126, 231); assertEquals(2, r.x); assertEquals(-1, r.y); assertEquals(21, r.gcd); } }bouncycastle-1.49.orig/test/src/org/bouncycastle/pqc/math/ntru/euclid/test/AllTests.java0000644000175000017500000000104412113311460030776 0ustar ebourgebourgpackage org.bouncycastle.pqc.math.ntru.euclid.test; import junit.framework.Test; import junit.framework.TestCase; import junit.framework.TestSuite; public class AllTests extends TestCase { public static void main (String[] args) { junit.textui.TestRunner.run(suite()); } public static Test suite() { TestSuite suite = new TestSuite("NTRU Euclid Tests"); suite.addTestSuite(BigIntEuclideanTest.class); suite.addTestSuite(IntEuclideanTest.class); return suite; } } bouncycastle-1.49.orig/test/src/org/bouncycastle/pqc/math/ntru/euclid/test/BigIntEuclideanTest.java0000644000175000017500000000141612113311460033074 0ustar ebourgebourgpackage org.bouncycastle.pqc.math.ntru.euclid.test; import java.math.BigInteger; import junit.framework.TestCase; import org.bouncycastle.pqc.math.ntru.euclid.BigIntEuclidean; public class BigIntEuclideanTest extends TestCase { public void testCalculate() { BigIntEuclidean r = BigIntEuclidean.calculate(BigInteger.valueOf(120), BigInteger.valueOf(23)); assertEquals(BigInteger.valueOf(-9), r.x); assertEquals(BigInteger.valueOf(47), r.y); assertEquals(BigInteger.valueOf(1), r.gcd); r = BigIntEuclidean.calculate(BigInteger.valueOf(126), BigInteger.valueOf(231)); assertEquals(BigInteger.valueOf(2), r.x); assertEquals(BigInteger.valueOf(-1), r.y); assertEquals(BigInteger.valueOf(21), r.gcd); } }bouncycastle-1.49.orig/test/src/org/bouncycastle/pqc/math/ntru/polynomial/0000755000175000017500000000000012152033550026344 5ustar ebourgebourgbouncycastle-1.49.orig/test/src/org/bouncycastle/pqc/math/ntru/polynomial/test/0000755000175000017500000000000012152033550027323 5ustar ebourgebourg././@LongLink0000000000000000000000000000015000000000000011561 Lustar rootrootbouncycastle-1.49.orig/test/src/org/bouncycastle/pqc/math/ntru/polynomial/test/PolynomialGenerator.javabouncycastle-1.49.orig/test/src/org/bouncycastle/pqc/math/ntru/polynomial/test/PolynomialGenerator.j0000644000175000017500000000136312113311460033467 0ustar ebourgebourgpackage org.bouncycastle.pqc.math.ntru.polynomial.test; import java.util.Random; import org.bouncycastle.pqc.math.ntru.polynomial.IntegerPolynomial; public class PolynomialGenerator { /** * Creates a random polynomial with N coefficients * between 0 and q-1. * * @param N length of the polynomial * @param q coefficients will all be below this number * @return a random polynomial */ public static IntegerPolynomial generateRandom(int N, int q) { Random rng = new Random(); int[] coeffs = new int[N]; for (int i = 0; i < N; i++) { coeffs[i] = rng.nextInt(q); } return new IntegerPolynomial(coeffs); } }././@LongLink0000000000000000000000000000015200000000000011563 Lustar rootrootbouncycastle-1.49.orig/test/src/org/bouncycastle/pqc/math/ntru/polynomial/test/IntegerPolynomialTest.javabouncycastle-1.49.orig/test/src/org/bouncycastle/pqc/math/ntru/polynomial/test/IntegerPolynomialTest0000644000175000017500000007345412113320253033560 0ustar ebourgebourgpackage org.bouncycastle.pqc.math.ntru.polynomial.test; import java.math.BigInteger; import java.security.SecureRandom; import junit.framework.TestCase; import org.bouncycastle.pqc.crypto.ntru.NTRUSigningKeyGenerationParameters; import org.bouncycastle.pqc.math.ntru.polynomial.BigIntPolynomial; import org.bouncycastle.pqc.math.ntru.polynomial.DenseTernaryPolynomial; import org.bouncycastle.pqc.math.ntru.polynomial.IntegerPolynomial; import org.bouncycastle.pqc.math.ntru.polynomial.Resultant; import org.bouncycastle.util.Arrays; public class IntegerPolynomialTest extends TestCase { public void testMult() { // multiplication modulo q IntegerPolynomial a = new IntegerPolynomial(new int[]{-1, 1, 1, 0, -1, 0, 1, 0, 0, 1, -1}); IntegerPolynomial b = new IntegerPolynomial(new int[]{14, 11, 26, 24, 14, 16, 30, 7, 25, 6, 19}); IntegerPolynomial c = a.mult(b, 32); assertEqualsMod(new int[]{3, -7, -10, -11, 10, 7, 6, 7, 5, -3, -7}, c.coeffs, 32); a = new IntegerPolynomial(new int[]{15, 27, 18, 16, 12, 13, 16, 2, 28, 22, 26}); b = new IntegerPolynomial(new int[]{-1, 0, 1, 1, 0, 1, 0, 0, -1, 0, -1}); c = a.mult(b, 32); assertEqualsMod(new int[]{8, 25, 22, 20, 12, 24, 15, 19, 12, 19, 16}, c.coeffs, 32); // multiplication without a modulus a = new IntegerPolynomial(new int[]{1, 1, 0, 0, -1, -1, 0, 0, -1, 0, 1}); b = new IntegerPolynomial(new int[]{704, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}); c = a.mult(b); // mult(p, modulus) should give the same result as mult(p) followed by modulus a = new IntegerPolynomial(new int[]{1, 0, -1, 1, 0, 1, 1, 1, -1, 1, -1}); b = new IntegerPolynomial(new int[]{0, 1, 1, 0, 0, -1, -1, 1, 1, -1, 1}); c = a.mult(b); c.modPositive(20); IntegerPolynomial d = a.mult(b, 20); d.modPositive(20); assertTrue(Arrays.areEqual(c.coeffs, d.coeffs)); } void assertEqualsMod(int[] arr1, int[] arr2, int m) { assertEquals(arr1.length, arr2.length); for (int i = 0; i < arr1.length; i++) { assertEquals((arr1[i] + m) % m, (arr2[i] + m) % m); } } public void testInvertFq() { SecureRandom random = new SecureRandom(); // Verify an example from the NTRU tutorial IntegerPolynomial a = new IntegerPolynomial(new int[]{-1, 1, 1, 0, -1, 0, 1, 0, 0, 1, -1}); IntegerPolynomial b = a.invertFq(32); assertEqualsMod(new int[]{5, 9, 6, 16, 4, 15, 16, 22, 20, 18, 30}, b.coeffs, 32); verifyInverse(a, b, 32); // test 3 random polynomials int numInvertible = 0; while (numInvertible < 3) { a = DenseTernaryPolynomial.generateRandom(853, random); b = a.invertFq(2048); if (b != null) { numInvertible++; verifyInverse(a, b, 2048); } } // test a non-invertible polynomial a = new IntegerPolynomial(new int[]{-1, 0, 1, 1, 0, 0, -1, 0, -1, 0, 1}); b = a.invertFq(32); assertNull(b); } public void testInvertF3() { IntegerPolynomial a = new IntegerPolynomial(new int[]{-1, 1, 1, 0, -1, 0, 1, 0, 0, 1, -1}); IntegerPolynomial b = a.invertF3(); assertEqualsMod(new int[]{1, 2, 0, 2, 2, 1, 0, 2, 1, 2, 0}, b.coeffs, 3); verifyInverse(a, b, 3); // test a non-invertible polynomial a = new IntegerPolynomial(new int[]{0, 1, -1, 1, 0, 0, 0, 0, -1, 0, 0}); b = a.invertF3(); assertNull(b); } // tests if a*b=1 (mod modulus) private void verifyInverse(IntegerPolynomial a, IntegerPolynomial b, int modulus) { IntegerPolynomial c = a.mult(b, modulus); for (int i = 1; i < c.coeffs.length; i++) { c.coeffs[i] %= modulus; } c.ensurePositive(modulus); assertTrue(c.equalsOne()); } public void testFromToBinary() { byte[] a = new byte[]{-44, -33, 30, -109, 101, -28, -6, -105, -45, 113, -72, 99, 101, 15, 9, 49, -80, -76, 58, 42, -57, -113, -89, -14, -125, 24, 125, -16, 37, -58, 10, -49, -77, -31, 120, 103, -29, 105, -56, -126, -92, 36, 125, 127, -90, 38, 9, 4, 104, 10, -78, -106, -88, -1, -1, -43, -19, 90, 41, 0, -43, 102, 118, -72, -122, 19, -76, 57, -59, -2, 35, 47, 83, 114, 86, -115, -125, 58, 75, 115, -29, -6, 108, 6, -77, -51, 127, -8, -8, -58, -30, -126, 110, -5, -35, -41, -37, 69, 22, -48, 26, 4, -120, -19, -32, -81, -77, 124, -7, -2, -46, -96, 38, -35, 88, 4, -5, 16, 101, 29, 7, 2, 88, 35, -64, 31, -66, -70, 120, -97, 76, -74, -97, -61, 52, -56, 87, -35, 5, 95, -93, -30, 10, 38, 17, -102, -25, 86, 7, -43, 44, -52, -108, 33, -18, -110, -9, -115, 66, -71, 66, 1, -90, -72, 90, -88, -38, 75, 47, -124, -120, -15, -49, -8, 85, 5, 17, -88, 76, 99, -4, 83, 16, -91, 82, 116, 112, -83, 56, -45, -26, 125, 13, -75, -115, 92, -12, -59, 3, -12, 14, -6, 43, -17, 121, 122, 22, 92, -74, 99, -59, -103, 113, 8, -103, 114, 99, -48, 92, -88, 77, 81, 5, 31, -4, -69, -24, 23, 94, 126, 71, 93, 20, 77, 82, -54, -14, 86, 45, -81, 0, 52, -63, -66, 48, 104, -54, 15, -73, -2, -52, 115, 76, 28, -5, -94, -63, 117, -69, 0, 61, 22, -1, 71, -115, 9, -73, -100, -128, -31, 106, -74, -61, -37, 98, -6, 11, -5, 6, -18, -53, -6, 11, -49, 62, 23, 6, -128, 38, -91, 89, -34, 18, -38, -110, -101, 43, 36, 62, 101, 112, 59, -91, 78, -81, 61, 126, -21, -42, -110, -38, -27, 69, 57, 9, 24, -50, -118, 31, -17, 42, 87, -54, 122, -16, 42, -47, -19, -80, 16, 54, -97, -89, 81, -22, -35, 45, 54, -46, 22, -122, -95, -17, 7, -127, 105, -100, -56, -98, -105, 101, -81, 104, 121, -7, 33, 126, 110, -125, -85, 111, -52, 123, -98, 41, -42, 88, -68, -17, 39, -19, -96, -10, -117, 13, -88, -75, -101, -16, -7, 73, 23, -12, 41, -116, -105, -64, -4, 103, 49, -15, -49, 60, 88, -25, -21, 42, 26, 95, -90, -83, -69, 64, -2, 50, -116, -64, 26, -29, -93, -120, -70, 32, -38, 39, -126, -19, 103, 127, 65, 54, 110, 94, 126, -82, -80, -18, 43, 45, 56, -118, 109, 36, -8, 10, 113, 69, 53, -122, -127, 92, -127, -73, 70, -19, -105, -80, -15, -5, 99, -109, -27, 119, -76, -57, -48, 42, -35, 23, 39, -126, 44, -107, -100, -125, 117, -50, 115, -79, -16, 104, 8, -102, 83, -73, 21, -85, 113, -87, -54, 93, 63, -108, -64, 109, -74, 15, 14, -119, -6, -68, 45, 37, -15, -97, -95, -55, 89, 25, -63, -92, -80, -27, -8, 55, 50, 96, -91, 40, -74, 110, -96, 94, 6, 85, 92, 0, 34, -122, 5, -126, 123, 37, -90, -94, 60, 14, 36, 49, -98, -23, 57, 75, 63, 106, -7, -36, -89, 84, 71, 60, -21, 104, -47, 90, -52, -66, 88, -91, -81, -3, 116, 23, 62, -47, -84, -118, 65, 31, 7, -103, 37, -29, 115, -114, 73, 12, -121, 96, -91, -7, 56, 10, -72, 27, -45, 122, -27, -38, 74, 64, 30, -60, 64, -21, 48, 101, 113, 126, -60, -103, 71, 100, -117, 124, -125, 116, 78, 114, -74, 42, -81, -54, 34, 33, -10, 19, 23, 24, 40, 0, -8, 78, 100, 73, -88, -95, -62, -115, -18, 47, 10, -14, -39, 82, 27, -9, -115, -70, 92, -6, 39, 45, -71, -109, -41, 94, -88, -63, 19, -58, -37, -31, 1, 127, -42, 125, -120, -57, 120, -86, -6, 17, -27, -37, 47, 55, -22, -11, -31, 38, -1, 29, 56, -34, -104, -66, -62, 72, -11, -30, -30, 61, -31, 10, -63, 116, -84, 118, -127, 6, 17, -36, 91, 123, 77, 35, 22, 110, 114, 107, -3, 52, 11, 86, 68, -56, 0, 119, -43, -73, 112, 89, -4, -122, -71, -26, 103, -118, -61, -112, -108, -44, -25, -22, 4, 24, 53, -5, -71, 9, -41, 84, -28, 22, 99, 39, -26, -2, -51, 68, 63, -15, 99, 66, -78, 46, -89, 21, -38, -114, -51, 100, -59, 84, -76, -105, 51, 28, 19, 74, 42, 91, -73, 12, -89, -128, 34, 38, -100, 121, -78, 114, -28, 127, -29, 50, 105, -6, 36, 98, -35, 79, -58, 5, -13, -86, -101, -108, -99, -70, 25, 103, 63, 57, 79, -12, -63, 125, -54, 61, 15, 6, -79, 90, 76, 103, -45, 7, 39, 93, 107, 58, 76, 80, 56, -108, 55, -22, 36, 125, -91, -65, 11, 69, 10, -19, -14, -4, -26, -36, 114, 124, 63, -31, 88, 92, 108, 33, -52, -22, 80, -65, 57, 126, 43, -13, 122, -8, 68, 72, 92, -50, 100, -91, 1, -81, 75, 95, -11, -99, 38, 121, -20, -70, 82, -125, -94, -18, 16, 59, 89, 18, -96, 91, -97, 62, -96, 127, 45, 70, 16, 84, -43, -75, -118, 81, 58, 84, -115, -120, -3, 41, -103, -70, 123, 26, 101, 33, 58, 13, -11, -73, -84, -47, -7, 81, -63, 60, -45, 30, 100, -51, -15, 73, 58, -119, -3, 62, -63, -17, -69, -44, 60, -54, -115, -59, 23, -59, 98, -89, -72, 20, -96, 27, 53, -89, 59, -85, -29, 120, 23, 62, 8, -86, 113, 87, -15, 102, 106, -104, 57, -57, 37, 110, 118, 109, 25, 64, 26, -20, -86, -2, 60, -70, -33, 67, 13, -28, -29, -63, -37, 67, 99, 84, 121, -126, -38, 45, 24, 122, 51, 11, -19, -80, 26, -106, -95, 82, 69, -2, -75, 62, 106, -120, 87, -107, 87, 17, 102, -52, -16, 22, 12, -86, -48, -95, -61, 109, 64, -29, 111, 40, -90, -35, 49, 88, -15, 122, 127, 87, 113, 116, 93, 100, 28, -70, -87, -40, -1, -126, -114, 7, 79, 16, 2, -47, -98, -102, 49, 58, 61, -32, 44, 18, -26, 37, 27, -123, -76, 56, 91, 51, -21, -48, -122, -33, 40, -8, -62, -56, -126, 91, -51, 76, -29, 127, -22, -18, -110, 27, 13, -111, 81, 51, -104, 70, 98, 12, 120, -7, 15, 104, -43, -104, 124, 46, 116, 7, -26, 21, 33, 105, 17, -99, -42, -106, 8, -85, 39, 8, 79, -54, -81, 109, 40, 25, 29, -18, -90, 22, 85, -12, -16, 61, 49, -31, 127, 64, 5, 25, 39, -65, -42, 13, -97, -92, 36, -126, -18, -4, -22, -14, 109, -93, -76, -5, 13, 74, 44, 103, 79, 110, 85, 58, 39, -24, 119, 120, 122, 120, 43, 110, 67, 21, 47, 39, -48, 7, 91, -51, 126, 100, -38, -124, 0, -97, 99, -123, 118, -27, 8, 102, -106, -23, -53, -4, -56, -9, -126, -85, 93, -4, -5, 4, 49, 29, 2, 63, 78, -32, -106, 118, 111, 52, 54, 74, 53, 106, 39, -95, -38, -18, 118, -5, 94, -83, -97, -27, 62, -56, -90, -36, 43, 43, -113, 119, -89, 44, -108, -46, 66, 28, 66, -38, 3, -62, -83, -35, -127, -2, 51, 104, 105, 40, 76, -10, -124, -95, 52, 11, 101, -32, -122, -73, -17, 37, -126, 68, -126, 55, 112, -126, 38, 99, -63, 123, -74, -31, 58, 8, 93, -68, 111, -22, -24, -23, 9, -87, -25, -115, 81, -116, -91, 60, 96, -102, -1, -7, 73, 99, 46, -78, 62, 48, -116, -52, -44, -5, 82, -45, 5, -55, -101, 101, 65, -109, -108, 26, 98, -55, 11, -86, 57, 30, 92, -58, 20, 82, 65, 103, 27, -64, 76, 123, -56, -16, -111, -83, 125, 65, 111, 9, 123, 14, 119, 126, -80, 79, 94, -19, 66, -25, 35, 112, -64, 10, -66, -86, 51, 56, -78, 103, 92, -116, 8, 75, 41, -49, -79, -53, 125, -32, -76, -27, 59, -8, -4, -94, -104, -15, 79, -7, -124, 32, -87, -104, 85, -118, -36, 125, 65, 111, -105, 5, -105, 40, -50, 2, 118, 123, -54, 59, -22, 94, 20, 99, -87, -27, 28, -30, -109, 72, -19, 92, 60, 19, 115, 47, 96, -96, 10, -74, 60, 96, -86, 101, 101, 68, -44, -72, 9, -36, 126, 96, -45, -12, 9, 14, -15, 79, -79, -48, 8, -107, -81, 47, 35, -36, -107, -120, -36, -124, 37, 103, -60, -35, -74, 100, -38, -88, -99, -99, -94, -107, 79, 115, 108, 54, 119, 73, 84, 110, -74, 92, 57, 108, 80, 47, -36, -119, -115, 58, -62, -4, -97, 43, -98, 5, 112, 47, 59, -89, 82, -69, -103, 39, -29, 75, -9, -94, -72, 99, -64, 22, -10, 21, 89, 101, 21, 94, -30, -17, 73, -36, -68, -89, -91, -94, 99, -106, 119, -116, 123, -19, 54, -99, 64, -119, 82, 120, -106, -99, 80, 69, 29, -48, 77, 28, 13, 92, -107, -77, 94, -116, 108, 89, -115, 96, -41, 25, 99, -65, 118, -5, -16, 48, -122, 5, 50, -123, -115, 13, 24, 7, 15, -103, -62, -71, 92, -82, -5, -70, 49, -6, -51, -17, -47, 12, 46, -86, 30, 93, 84, -101, 43, -92, -87, -118, -110, -32, 52, 115, -4, 36, -2, -79, -69, -46, -110, 70, -82, 6, 21, -27, -11, 94, 42, -81, -96, 116, -102, -38, 36, 32, 91, 28, 80, -45, 116, -94, -33, -5, -102, 64, -96, 27, -2, 100, -126, 59, -71, 33, -36, -124, 123, 99, -76, 108, 127, -11, -24, -19, 84, -6, 19, 105, -19, -18, 120, -14, 23, 39, 54, 87, 105, 58, -95, -15, 127, -65, 114, 49, 4, -66, 32, -7, 84, 43, -103, 76, 11, 36, -68, -3, -98, -5, -43, 35, -48, 20, -40, -33, -123, 1, -54, -44, 99, -68, 8, -100, 97, -49, -10, 110, 49, 84, 46, -85, 98, -103, -58, -4, 104, -100, -40, -79, 67, -20, -95, 85, 51, 73, 10, -25, 102, 68, -97, -83, -39, 35, 2, -111, 71, 62, -89, 20, 25, -126, 17, -81, -29, 39, -27, -55, 55, -122, 97, 23, -99, 55, 86, 33, -9, 8, 55, -40, -84, 39, 38, 37, -29, 87, 113, -118, -26, 123, -95, 24, -126, 119, -94, 17, 83, -43, 10, 63, -98, 72, 8, 16, -95, -96, 119, -91, 6, 71, -60, 1, -77, 4, 53, -121, 55, 7, 36, -86, -49, -118, -121, 56, 84, -49, -57, -99, 3, -68, 37, -108, -72, 114, -74, 120, 3, 121, -28, -106, 54, -20, 63, -121, -85, -59, -111, 32, 13, -69, 122, 90, 5, 40, 88, 15, -90, 125, -28, 89, 95, 73, 96, 60, -60, -51, 102, 7, 57, 91, 59, 15, 92, -76, -34, -23, -77, 90, 45, 91, 77, -63, 94, -127, 74, -97, -44, 50, -87, -94, -25, -71, 112, 127, -117, 6, 32, -113, 54, 83, -31, 111, -73, 53, 34, -32, -98, 125, -39, 63, 15, 72, -69, 87, -118, 108, 17, 84, 15, 61, -47, 54, -24, -79, 91, 28, -28, 66, 53, 22, 9, -28, -12, 38, 64, 75, -122, 96, -59, -45, 4, -19, 47, -30, 75, -94, 62, -64, 76, -49, 19, -66, -34, 3, 84, -2, -54, 13, -84, 86, -117, 94, -27, 89, 16, 96, 52, -77, -36, -116, 27, -52, -33, -50, 14, -59, 77, 93, -109, 8, -89, 81, -114, -29, -94, 73, -119, -56, -19, 88, -17, -33, 125, -18, -68, 113, 40, -128, -112, -119, -106, -106, -30, 23, -77, 49, 3, 98, -101, 99, -107, -121, -12, -112, 24, -74, -74, 79, -17, 96, 65, -52, 86, -63, 45, 84, 119, -42, 61, -91, 29, -87, 65, -85, 99, -14, 71, 33, -41, -48, -2, -121, 78, -38, 41, -7, -37, 48, 122, 61, -124, 42, -22, 24, 2, -49, 74, -81, -88, -89, -107, 109, 53, -68, 90, -117, 123, -109, -28, 12, 80, 120, 26, -104, 73, 70, -36, 34, -80, -104, 23, 16, 14, -96, -5, 27, 71, 25, -8, -125, 58, 88, -52, -97, -97, -93, 11, -44, 116, 42, -102, -100, -31, -86, 71, 84, 70, 27, 117, -67, 92, -84, -13, 54, -102, 34, 5, 19, -76, 71, 89, 22, -49, -34, -29}; IntegerPolynomial poly = IntegerPolynomial.fromBinary(a, 1499, 2048); byte[] b = poly.toBinary(2048); // verify that bytes 0..2047 match, ignore non-relevant bits of byte 2048 assertTrue(Arrays.areEqual(copyOf(a, 2047), copyOf(b, 2047))); assertEquals((a[a.length - 1] & 1) >> (7 - (1499 * 11) % 8), (b[b.length - 1] & 1) >> (7 - (1499 * 11) % 8)); } public void testFromToBinary3Sves() { byte[] a = new byte[]{-112, -78, 19, 15, 99, -65, -56, -90, 44, -93, -109, 104, 40, 90, -84, -21, -124, 51, -33, 4, -51, -106, 33, 86, -76, 42, 41, -17, 47, 79, 81, -29, 15, 116, 101, 120, 116, 32, 116, 111, 32, 101, 110, 99, 114, 121, 112, 116, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}; IntegerPolynomial poly = IntegerPolynomial.fromBinary3Sves(a, 1499); byte[] b = poly.toBinary3Sves(); assertTrue(Arrays.areEqual(a, b)); } public void testFromToBinary3Tight() { int[] c = new int[]{0, 0, 0, 0, 0, 0, 0, 1, 0, 0, -1, -1, 0, 0, 0, 0, 0, 0, 0, -1, 0, 0, 0, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, -1, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -1, 0, 0, 0, 0, 0, -1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -1, 0, 0, 0, 0, 0, 1, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 1, -1, 0, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 1, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -1, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 0, 0, 0, 0, 0, 0, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -1, 0, 1, 0, 0, 0, -1, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, -1, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -1, 1, 0, 0, 0, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -1, 0, 1, 0, 1, 0, 1, 0, -1, 0, 0, 1, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -1, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, -1, -1, 0, 1, 0, 0, 0, 0, 0, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 0, -1, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -1, 0, 0, 0, 0, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -1, 1, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, -1, 0, 1, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -1, 0, -1, -1, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, -1, 0, 0, 0, 0, 0, 0, 0, 1, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, -1, 0, 0, 0, 0, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -1, 0, 0, 0, 0, 0, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -1, 0, 0, 0, 0, 0, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -1, 0, 0, 0, -1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, -1, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -1, 0, 1, 0, 0, 0, 0, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -1, -1, 0, 0, 0, 0, 0, 0, 0, 0, -1, 0, 0, 0, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 1, 0, 0, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -1, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -1, 0, 0, 1, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -1, 0, 0, 0, -1, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, -1, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 1, 0, 0, 1, 0, 0, 0, 0, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, -1, 0, 0, 0, 0, 1, 0, 0, 0, 0, -1, 0, 0, 0, 0, 0, 1, 0, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0}; IntegerPolynomial poly1 = new IntegerPolynomial(c); IntegerPolynomial poly2 = IntegerPolynomial.fromBinary3Tight(poly1.toBinary3Tight(), c.length); assertTrue(Arrays.areEqual(poly1.coeffs, poly2.coeffs)); IntegerPolynomial poly3 = new IntegerPolynomial(new int[]{0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -1, 0, 0, 0, 0, 0, 0, 0, -1, 0, 0, 0, 0, 0, -1, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 1, -1, -1, 0, 0, 0, 1, 0, -1, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 1, 0, 0, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -1, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, -1, 1, 0, 0, 0, 1, 0, 0, 0, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -1, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 0, 1, 0, 0, 0, 0, -1, 0, 0, 0, 0, 0, 1, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -1, -1, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -1, 0, 0, 0, 0, 0, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -1, -1, 0, 0, 0, 0, 0, 0, -1, 0, 0, 0, 0, 0, 1, 0, 1, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -1, 0, -1, 0, 0, 1, 0, 0, 0, 0, 1, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 1, -1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, -1, 0, 0, 0, 0, -1, 0, 0, 0, 0, 0, 0, -1, 0, 0, 0, 0, 0, 0, 0, -1, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -1, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, -1, 0, 0, 0, 0, -1, 0, 0, 0, 0, 0, 0, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -1, 0, 0, 0, 0, 1, 0, -1, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -1, 0, 0, 0, 0, 0, 0, 1, 1, 0, 0, 0, 0, 0, 0, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -1, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -1, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -1, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -1, 0, 0, 0, -1, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -1, 0, 1, 1, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, -1, 0, 0, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -1, 0, -1, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -1, 0, -1, 1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -1, 0, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, -1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0}); byte[] arr = poly3.toBinary3Tight(); IntegerPolynomial poly4 = IntegerPolynomial.fromBinary3Tight(arr, 1499); assertTrue(Arrays.areEqual(poly3.coeffs, poly4.coeffs)); IntegerPolynomial poly5 = new IntegerPolynomial(new int[]{0, 0, 0, 1, -1, -1, -1}); arr = poly5.toBinary3Tight(); IntegerPolynomial poly6 = IntegerPolynomial.fromBinary3Tight(arr, 7); assertTrue(Arrays.areEqual(poly5.coeffs, poly6.coeffs)); SecureRandom random = new SecureRandom(); for (int i = 0; i < 100; i++) { IntegerPolynomial poly7 = DenseTernaryPolynomial.generateRandom(157, random); arr = poly7.toBinary3Tight(); IntegerPolynomial poly8 = IntegerPolynomial.fromBinary3Tight(arr, 157); assertTrue(Arrays.areEqual(poly7.coeffs, poly8.coeffs)); } } public void testResultant() { SecureRandom random = new SecureRandom(); NTRUSigningKeyGenerationParameters params = NTRUSigningKeyGenerationParameters.APR2011_439; IntegerPolynomial a = DenseTernaryPolynomial.generateRandom(params.N, params.d, params.d, random); verifyResultant(a, a.resultant()); a = new IntegerPolynomial(new int[]{0, 0, 0, 0, 0, 0, 0, 0, -1, 0, 1, 0, 0, 0, 0, 0, 1, -1, 0, 0, -1, 0, 0, 0, 1, 0, 0, 0, -1, -1, 0, -1, 1, -1, 0, -1, 0, -1, -1, -1, 0, 0, 0, 1, 1, -1, -1, -1, 0, -1, -1, 0, 0, 1, 0, 0, 0, 0, 0, -1, 0, 0, 1, 0, 0, 1, 1, -1, 0, 1, -1, 0, 1, 0, 1, 0, -1, -1, 0, 1, 0, -1, 1, 1, 1, 1, 0, 0, -1, -1, 1, 0, 0, -1, -1, 0, -1, 0, 0, 0, 1, 0, 1, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 1, -1, 0, 0, 0, 0, -1, 0, 0, 0, 1, 0, 1, 0, 1, -1, 0, 0, 1, 1, 1, 0, 0, 0, -1, 0, 0, 0, 0, 1, 0, 1, 0, -1, -1, 0, -1, -1, -1, 0, -1, -1, 0, 0, 0, 1, 1, 0, 0, 0, 1, 0, 0, 1, -1, 0, 1, 0, -1, 0, 0, 0, 0, 0, 0, -1, -1, 0, -1, -1, 1, 1, 0, 0, -1, 1, 0, 0, 0, -1, 1, -1, 0, -1, 0, 0, 0, -1, 0, 0, 0, 0, 0, -1, 1, 1, 0, 0, -1, 1, 0, 0, 1, 0, 0, 0, 1, 0, 1, 0, 0, 0, 0, 0, 0, 1, -1, 0, 1, 0, -1, -1, 0, 0, 0, 0, 0, 1, -1, 0, 0, 0, 1, -1, 1, -1, -1, 1, -1, 0, 1, 0, 0, 0, 1, 0, 0, 1, -1, 0, 0, 0, 0, 0, 0, 0, -1, 0, 1, 0, -1, 0, 1, -1, 0, 0, 1, 1, 0, 0, 1, 1, 0, -1, 0, -1, 1, -1, -1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, 0, 1, -1, 0, 0, 1, -1, 1, 0, 0, 1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, -1, 1, 0, -1, -1, 0, 0, -1, 0, 1, 1, -1, 1, -1, 0, 0, 0, 1}); verifyResultant(a, a.resultant()); } // verifies that res=rho*a mod x^n-1 private void verifyResultant(IntegerPolynomial a, Resultant r) { BigIntPolynomial b = new BigIntPolynomial(a).mult(r.rho); BigInteger[] bCoeffs = b.getCoeffs(); for (int j = 1; j < bCoeffs.length - 1; j++) { assertEquals(BigInteger.ZERO, bCoeffs[j]); } if (r.res.equals(BigInteger.ZERO)) { assertEquals(BigInteger.ZERO, bCoeffs[0].subtract(bCoeffs[bCoeffs.length - 1])); } else { assertEquals(BigInteger.ZERO, (bCoeffs[0].subtract(bCoeffs[bCoeffs.length - 1]).mod(r.res))); } assertEquals(bCoeffs[0].subtract(r.res), bCoeffs[bCoeffs.length - 1].negate()); } public void testResultantMod() { int p = 46337; // prime; must be less than sqrt(2^31) or integer overflows will occur IntegerPolynomial a = new IntegerPolynomial(new int[]{0, 0, 0, 0, 0, 0, 0, 0, -1, 0, 1, 0, 0, 0, 0, 0, 1, -1, 0, 0, -1, 0, 0, 0, 1, 0, 0, 0, -1, -1, 0, -1, 1, -1, 0, -1, 0, -1, -1, -1, 0, 0, 0, 1, 1, -1, -1, -1, 0, -1, -1, 0, 0, 1, 0, 0, 0, 0, 0, -1, 0, 0, 1, 0, 0, 1, 1, -1, 0, 1, -1, 0, 1, 0, 1, 0, -1, -1, 0, 1, 0, -1, 1, 1, 1, 1, 0, 0, -1, -1, 1, 0, 0, -1, -1, 0, -1, 0, 0, 0, 1, 0, 1, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 1, -1, 0, 0, 0, 0, -1, 0, 0, 0, 1, 0, 1, 0, 1, -1, 0, 0, 1, 1, 1, 0, 0, 0, -1, 0, 0, 0, 0, 1, 0, 1, 0, -1, -1, 0, -1, -1, -1, 0, -1, -1, 0, 0, 0, 1, 1, 0, 0, 0, 1, 0, 0, 1, -1, 0, 1, 0, -1, 0, 0, 0, 0, 0, 0, -1, -1, 0, -1, -1, 1, 1, 0, 0, -1, 1, 0, 0, 0, -1, 1, -1, 0, -1, 0, 0, 0, -1, 0, 0, 0, 0, 0, -1, 1, 1, 0, 0, -1, 1, 0, 0, 1, 0, 0, 0, 1, 0, 1, 0, 0, 0, 0, 0, 0, 1, -1, 0, 1, 0, -1, -1, 0, 0, 0, 0, 0, 1, -1, 0, 0, 0, 1, -1, 1, -1, -1, 1, -1, 0, 1, 0, 0, 0, 1, 0, 0, 1, -1, 0, 0, 0, 0, 0, 0, 0, -1, 0, 1, 0, -1, 0, 1, -1, 0, 0, 1, 1, 0, 0, 1, 1, 0, -1, 0, -1, 1, -1, -1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, 0, 1, -1, 0, 0, 1, -1, 1, 0, 0, 1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, -1, 1, 0, -1, -1, 0, 0, -1, 0, 1, 1, -1, 1, -1, 0, 0, 0, 1}); verifyResultant(a, a.resultant(p), p); SecureRandom random = new SecureRandom(); for (int i = 0; i < 10; i++) { a = DenseTernaryPolynomial.generateRandom(853, random); verifyResultant(a, a.resultant(p), p); } } // verifies that res=rho*a mod x^n-1 mod p private void verifyResultant(IntegerPolynomial a, Resultant r, int p) { BigIntPolynomial b = new BigIntPolynomial(a).mult(r.rho); b.mod(BigInteger.valueOf(p)); BigInteger[] bCoeffs = b.getCoeffs(); for (int j = 1; j < bCoeffs.length - 1; j++) { assertEquals(BigInteger.ZERO, bCoeffs[j]); } if (r.res.equals(BigInteger.ZERO)) { assertEquals(BigInteger.ZERO, bCoeffs[0].subtract(bCoeffs[bCoeffs.length - 1])); } else { assertEquals(BigInteger.ZERO, (bCoeffs[0].subtract(bCoeffs[bCoeffs.length - 1]).subtract(r.res).mod(BigInteger.valueOf(p)))); } assertEquals(BigInteger.ZERO, bCoeffs[0].subtract(r.res).subtract(bCoeffs[bCoeffs.length - 1].negate()).mod(BigInteger.valueOf(p))); } private byte[] copyOf(byte[] src, int length) { byte[] tmp = new byte[length]; System.arraycopy(src, 0, tmp, 0, tmp.length); return tmp; } }././@LongLink0000000000000000000000000000015000000000000011561 Lustar rootrootbouncycastle-1.49.orig/test/src/org/bouncycastle/pqc/math/ntru/polynomial/test/LongPolynomial2Test.javabouncycastle-1.49.orig/test/src/org/bouncycastle/pqc/math/ntru/polynomial/test/LongPolynomial2Test.j0000644000175000017500000000443412113311460033364 0ustar ebourgebourgpackage org.bouncycastle.pqc.math.ntru.polynomial.test; import java.util.Random; import junit.framework.TestCase; import org.bouncycastle.pqc.math.ntru.polynomial.IntegerPolynomial; import org.bouncycastle.pqc.math.ntru.polynomial.LongPolynomial2; import org.bouncycastle.util.Arrays; public class LongPolynomial2Test extends TestCase { public void testMult() { IntegerPolynomial i1 = new IntegerPolynomial(new int[]{1368, 2047, 672, 871, 1662, 1352, 1099, 1608}); IntegerPolynomial i2 = new IntegerPolynomial(new int[]{1729, 1924, 806, 179, 1530, 1381, 1695, 60}); LongPolynomial2 a = new LongPolynomial2(i1); LongPolynomial2 b = new LongPolynomial2(i2); IntegerPolynomial c1 = i1.mult(i2, 2048); IntegerPolynomial c2 = a.mult(b).toIntegerPolynomial(); assertTrue(Arrays.areEqual(c1.coeffs, c2.coeffs)); // test 10 random polynomials Random rng = new Random(); for (int i = 0; i < 10; i++) { int N = 2 + rng.nextInt(2000); i1 = PolynomialGenerator.generateRandom(N, 2048); i2 = PolynomialGenerator.generateRandom(N, 2048); a = new LongPolynomial2(i1); b = new LongPolynomial2(i2); c1 = i1.mult(i2); c1.modPositive(2048); c2 = a.mult(b).toIntegerPolynomial(); assertTrue(Arrays.areEqual(c1.coeffs, c2.coeffs)); } } public void testSubAnd() { IntegerPolynomial i1 = new IntegerPolynomial(new int[]{1368, 2047, 672, 871, 1662, 1352, 1099, 1608}); IntegerPolynomial i2 = new IntegerPolynomial(new int[]{1729, 1924, 806, 179, 1530, 1381, 1695, 60}); LongPolynomial2 a = new LongPolynomial2(i1); LongPolynomial2 b = new LongPolynomial2(i2); a.subAnd(b, 2047); i1.sub(i2); i1.modPositive(2048); assertTrue(Arrays.areEqual(a.toIntegerPolynomial().coeffs, i1.coeffs)); } public void testMult2And() { IntegerPolynomial i1 = new IntegerPolynomial(new int[]{1368, 2047, 672, 871, 1662, 1352, 1099, 1608}); LongPolynomial2 i2 = new LongPolynomial2(i1); i2.mult2And(2047); i1.mult(2); i1.modPositive(2048); assertTrue(Arrays.areEqual(i1.coeffs, i2.toIntegerPolynomial().coeffs)); } }././@LongLink0000000000000000000000000000015500000000000011566 Lustar rootrootbouncycastle-1.49.orig/test/src/org/bouncycastle/pqc/math/ntru/polynomial/test/BigDecimalPolynomialTest.javabouncycastle-1.49.orig/test/src/org/bouncycastle/pqc/math/ntru/polynomial/test/BigDecimalPolynomialT0000644000175000017500000000364712113311460033424 0ustar ebourgebourgpackage org.bouncycastle.pqc.math.ntru.polynomial.test; import java.math.BigDecimal; import java.security.SecureRandom; import junit.framework.TestCase; import org.bouncycastle.pqc.math.ntru.polynomial.BigDecimalPolynomial; import org.bouncycastle.pqc.math.ntru.polynomial.BigIntPolynomial; import org.bouncycastle.pqc.math.ntru.polynomial.DenseTernaryPolynomial; import org.bouncycastle.pqc.math.ntru.polynomial.IntegerPolynomial; public class BigDecimalPolynomialTest extends TestCase { public void testMult() { BigDecimalPolynomial a = new BigDecimalPolynomial(new BigIntPolynomial(new IntegerPolynomial(new int[]{4, -1, 9, 2, 1, -5, 12, -7, 0, -9, 5}))); BigDecimalPolynomial b = new BigDecimalPolynomial(new BigIntPolynomial(new IntegerPolynomial(new int[]{-6, 0, 0, 13, 3, -2, -4, 10, 11, 2, -1}))); BigDecimalPolynomial c = a.mult(b); BigDecimal[] expectedCoeffs = new BigDecimalPolynomial(new BigIntPolynomial(new IntegerPolynomial(new int[]{2, -189, 77, 124, -29, 0, -75, 124, -49, 267, 34}))).getCoeffs(); BigDecimal[] cCoeffs = c.getCoeffs(); assertEquals(expectedCoeffs.length, cCoeffs.length); for (int i = 0; i != cCoeffs.length; i++) { assertEquals(expectedCoeffs[i], cCoeffs[i]); } // multiply a polynomial by its inverse modulo 2048 and check that the result is 1 SecureRandom random = new SecureRandom(); IntegerPolynomial d, dInv; do { d = DenseTernaryPolynomial.generateRandom(1001, 333, 334, random); dInv = d.invertFq(2048); } while (dInv == null); d.mod(2048); BigDecimalPolynomial e = new BigDecimalPolynomial(new BigIntPolynomial(d)); BigIntPolynomial f = new BigIntPolynomial(dInv); IntegerPolynomial g = new IntegerPolynomial(e.mult(f).round()); g.modPositive(2048); assertTrue(g.equalsOne()); } }././@LongLink0000000000000000000000000000016000000000000011562 Lustar rootrootbouncycastle-1.49.orig/test/src/org/bouncycastle/pqc/math/ntru/polynomial/test/SparseTernaryPolynomialTest.javabouncycastle-1.49.orig/test/src/org/bouncycastle/pqc/math/ntru/polynomial/test/SparseTernaryPolynomi0000644000175000017500000000315412113311460033576 0ustar ebourgebourgpackage org.bouncycastle.pqc.math.ntru.polynomial.test; import java.io.ByteArrayInputStream; import java.io.IOException; import java.security.SecureRandom; import junit.framework.TestCase; import org.bouncycastle.pqc.math.ntru.polynomial.BigIntPolynomial; import org.bouncycastle.pqc.math.ntru.polynomial.DenseTernaryPolynomial; import org.bouncycastle.pqc.math.ntru.polynomial.IntegerPolynomial; import org.bouncycastle.pqc.math.ntru.polynomial.SparseTernaryPolynomial; public class SparseTernaryPolynomialTest extends TestCase { /** * tests mult(IntegerPolynomial) and mult(BigIntPolynomial) */ public void testMult() { SecureRandom random = new SecureRandom(); SparseTernaryPolynomial p1 = SparseTernaryPolynomial.generateRandom(1000, 500, 500, random); IntegerPolynomial p2 = DenseTernaryPolynomial.generateRandom(1000, random); IntegerPolynomial prod1 = p1.mult(p2); IntegerPolynomial prod2 = p1.mult(p2); assertEquals(prod1, prod2); BigIntPolynomial p3 = new BigIntPolynomial(p2); BigIntPolynomial prod3 = p1.mult(p3); assertEquals(new BigIntPolynomial(prod1), prod3); } public void testFromToBinary() throws IOException { SecureRandom random = new SecureRandom(); SparseTernaryPolynomial poly1 = SparseTernaryPolynomial.generateRandom(1000, 100, 101, random); ByteArrayInputStream poly1Stream = new ByteArrayInputStream(poly1.toBinary()); SparseTernaryPolynomial poly2 = SparseTernaryPolynomial.fromBinary(poly1Stream, 1000, 100, 101); assertEquals(poly1, poly2); } }././@LongLink0000000000000000000000000000015100000000000011562 Lustar rootrootbouncycastle-1.49.orig/test/src/org/bouncycastle/pqc/math/ntru/polynomial/test/BigIntPolynomialTest.javabouncycastle-1.49.orig/test/src/org/bouncycastle/pqc/math/ntru/polynomial/test/BigIntPolynomialTest.0000644000175000017500000000201012113311460033371 0ustar ebourgebourgpackage org.bouncycastle.pqc.math.ntru.polynomial.test; import java.math.BigInteger; import junit.framework.TestCase; import org.bouncycastle.pqc.math.ntru.polynomial.BigIntPolynomial; import org.bouncycastle.pqc.math.ntru.polynomial.IntegerPolynomial; public class BigIntPolynomialTest extends TestCase { public void testMult() { BigIntPolynomial a = new BigIntPolynomial(new IntegerPolynomial(new int[]{4, -1, 9, 2, 1, -5, 12, -7, 0, -9, 5})); BigIntPolynomial b = new BigIntPolynomial(new IntegerPolynomial(new int[]{-6, 0, 0, 13, 3, -2, -4, 10, 11, 2, -1})); BigIntPolynomial c = a.mult(b); BigInteger[] expectedCoeffs = new BigIntPolynomial(new IntegerPolynomial(new int[]{2, -189, 77, 124, -29, 0, -75, 124, -49, 267, 34})).getCoeffs(); BigInteger[] cCoeffs = c.getCoeffs(); assertEquals(expectedCoeffs.length, cCoeffs.length); for (int i = 0; i != cCoeffs.length; i++) { assertEquals(expectedCoeffs[i], cCoeffs[i]); } } }bouncycastle-1.49.orig/test/src/org/bouncycastle/pqc/math/ntru/polynomial/test/AllTests.java0000644000175000017500000000153012113311460031714 0ustar ebourgebourgpackage org.bouncycastle.pqc.math.ntru.polynomial.test; import junit.framework.Test; import junit.framework.TestCase; import junit.framework.TestSuite; public class AllTests extends TestCase { public static void main (String[] args) { junit.textui.TestRunner.run(suite()); } public static Test suite() { TestSuite suite = new TestSuite("NTRU Polynomial Tests"); suite.addTestSuite(BigDecimalPolynomialTest.class); suite.addTestSuite(BigIntPolynomialTest.class); suite.addTestSuite(IntegerPolynomialTest.class); suite.addTestSuite(LongPolynomial2Test.class); suite.addTestSuite(LongPolynomial5Test.class); suite.addTestSuite(ProductFormPolynomialTest.class); suite.addTestSuite(SparseTernaryPolynomialTest.class); return suite; } } ././@LongLink0000000000000000000000000000015600000000000011567 Lustar rootrootbouncycastle-1.49.orig/test/src/org/bouncycastle/pqc/math/ntru/polynomial/test/ProductFormPolynomialTest.javabouncycastle-1.49.orig/test/src/org/bouncycastle/pqc/math/ntru/polynomial/test/ProductFormPolynomial0000644000175000017500000000277712113320253033567 0ustar ebourgebourgpackage org.bouncycastle.pqc.math.ntru.polynomial.test; import java.security.SecureRandom; import junit.framework.TestCase; import org.bouncycastle.pqc.crypto.ntru.NTRUEncryptionKeyGenerationParameters; import org.bouncycastle.pqc.math.ntru.polynomial.IntegerPolynomial; import org.bouncycastle.pqc.math.ntru.polynomial.ProductFormPolynomial; public class ProductFormPolynomialTest extends TestCase { private NTRUEncryptionKeyGenerationParameters params; private int N; private int df1; private int df2; private int df3; private int q; public void setUp() { params = NTRUEncryptionKeyGenerationParameters.APR2011_439_FAST; N = params.N; df1 = params.df1; df2 = params.df2; df3 = params.df3; q = params.q; } public void testFromToBinary() throws Exception { ProductFormPolynomial p1 = ProductFormPolynomial.generateRandom(N, df1, df2, df3, df3 - 1, new SecureRandom()); byte[] bin1 = p1.toBinary(); ProductFormPolynomial p2 = ProductFormPolynomial.fromBinary(bin1, N, df1, df2, df3, df3 - 1); assertEquals(p1, p2); } public void testMult() { ProductFormPolynomial p1 = ProductFormPolynomial.generateRandom(N, df1, df2, df3, df3 - 1, new SecureRandom()); IntegerPolynomial p2 = PolynomialGenerator.generateRandom(N, q); IntegerPolynomial p3 = p1.mult(p2); IntegerPolynomial p4 = p1.toIntegerPolynomial().mult(p2); assertEquals(p3, p4); } }././@LongLink0000000000000000000000000000015000000000000011561 Lustar rootrootbouncycastle-1.49.orig/test/src/org/bouncycastle/pqc/math/ntru/polynomial/test/LongPolynomial5Test.javabouncycastle-1.49.orig/test/src/org/bouncycastle/pqc/math/ntru/polynomial/test/LongPolynomial5Test.j0000644000175000017500000000452012113311460033363 0ustar ebourgebourgpackage org.bouncycastle.pqc.math.ntru.polynomial.test; import java.security.SecureRandom; import junit.framework.TestCase; import org.bouncycastle.pqc.math.ntru.polynomial.DenseTernaryPolynomial; import org.bouncycastle.pqc.math.ntru.polynomial.IntegerPolynomial; import org.bouncycastle.pqc.math.ntru.polynomial.LongPolynomial5; import org.bouncycastle.util.Arrays; public class LongPolynomial5Test extends TestCase { public void testMult() { testMult(new int[]{2}, new int[]{-1}); testMult(new int[]{2, 0}, new int[]{-1, 0}); testMult(new int[]{2, 0, 3}, new int[]{-1, 0, 1}); testMult(new int[]{2, 0, 3, 1}, new int[]{-1, 0, 1, 1}); testMult(new int[]{2, 0, 3, 1, 2}, new int[]{-1, 0, 1, 1, 0}); testMult(new int[]{2, 0, 3, 1, 1, 5}, new int[]{1, -1, 1, 1, 0, 1}); testMult(new int[]{2, 0, 3, 1, 1, 5, 1, 4}, new int[]{1, 0, 1, 1, -1, 1, 0, -1}); testMult(new int[]{1368, 2047, 672, 871, 1662, 1352, 1099, 1608}, new int[]{1, 0, 1, 1, -1, 1, 0, -1}); // test random polynomials SecureRandom rng = new SecureRandom(); for (int i = 0; i < 10; i++) { int[] coeffs1 = new int[rng.nextInt(2000) + 1]; int[] coeffs2 = DenseTernaryPolynomial.generateRandom(coeffs1.length, rng).coeffs; testMult(coeffs1, coeffs2); } } private void testMult(int[] coeffs1, int[] coeffs2) { IntegerPolynomial i1 = new IntegerPolynomial(coeffs1); IntegerPolynomial i2 = new IntegerPolynomial(coeffs2); LongPolynomial5 a = new LongPolynomial5(i1); DenseTernaryPolynomial b = new DenseTernaryPolynomial(i2); IntegerPolynomial c1 = i1.mult(i2, 2048); IntegerPolynomial c2 = a.mult(b).toIntegerPolynomial(); assertEqualsMod(c1.coeffs, c2.coeffs, 2048); } private void assertEqualsMod(int[] arr1, int[] arr2, int m) { assertEquals(arr1.length, arr2.length); for (int i = 0; i < arr1.length; i++) { assertEquals((arr1[i] + m) % m, (arr2[i] + m) % m); } } public void testToIntegerPolynomial() { int[] coeffs = new int[]{2, 0, 3, 1, 1, 5, 1, 4}; LongPolynomial5 p = new LongPolynomial5(new IntegerPolynomial(coeffs)); assertTrue(Arrays.areEqual(coeffs, p.toIntegerPolynomial().coeffs)); } }bouncycastle-1.49.orig/test/src/org/bouncycastle/pqc/jcajce/0000755000175000017500000000000012152033550023457 5ustar ebourgebourgbouncycastle-1.49.orig/test/src/org/bouncycastle/pqc/jcajce/provider/0000755000175000017500000000000012152033550025311 5ustar ebourgebourgbouncycastle-1.49.orig/test/src/org/bouncycastle/pqc/jcajce/provider/test/0000755000175000017500000000000012152033550026270 5ustar ebourgebourg././@LongLink0000000000000000000000000000015100000000000011562 Lustar rootrootbouncycastle-1.49.orig/test/src/org/bouncycastle/pqc/jcajce/provider/test/AsymmetricBlockCipherTest.javabouncycastle-1.49.orig/test/src/org/bouncycastle/pqc/jcajce/provider/test/AsymmetricBlockCipherTest.0000644000175000017500000000441312057035105033360 0ustar ebourgebourgpackage org.bouncycastle.pqc.jcajce.provider.test; import java.security.KeyPair; import java.security.KeyPairGenerator; import java.security.PrivateKey; import java.security.PublicKey; import java.security.spec.AlgorithmParameterSpec; import javax.crypto.Cipher; import org.bouncycastle.pqc.math.linearalgebra.ByteUtils; public abstract class AsymmetricBlockCipherTest extends FlexiTest { protected Cipher cipher; protected KeyPair keyPair; protected PublicKey pubKey; protected PrivateKey privKey; protected KeyPairGenerator kpg; private byte[] mBytes; private byte[] cBytes; private byte[] dBytes; protected final void performEnDecryptionTest(int numPassesKPG, int numPassesEncDec, AlgorithmParameterSpec params) { try { for (int j = 0; j < numPassesKPG; j++) { keyPair = kpg.genKeyPair(); pubKey = keyPair.getPublic(); privKey = keyPair.getPrivate(); for (int k = 1; k <= numPassesEncDec; k++) { // initialize for encryption cipher.init(Cipher.ENCRYPT_MODE, pubKey, params, sr); // generate random message final int plainTextSize = cipher.getBlockSize(); int mLength = rand.nextInt(plainTextSize) + 1; mBytes = new byte[mLength]; rand.nextBytes(mBytes); // encrypt cBytes = cipher.doFinal(mBytes); // initialize for decryption cipher.init(Cipher.DECRYPT_MODE, privKey, params); // decrypt dBytes = cipher.doFinal(cBytes); // compare assertEquals("Encryption and Decryption test failed:\n" + " actual decrypted text: " + ByteUtils.toHexString(dBytes) + "\n expected plain text: " + ByteUtils.toHexString(mBytes), mBytes, dBytes); } } } catch (Exception e) { e.printStackTrace(); fail(e); } } } bouncycastle-1.49.orig/test/src/org/bouncycastle/pqc/jcajce/provider/test/FlexiTest.java0000644000175000017500000000332712057007237031056 0ustar ebourgebourgpackage org.bouncycastle.pqc.jcajce.provider.test; import java.security.SecureRandom; import java.security.Security; import java.util.Arrays; import java.util.Random; import junit.framework.TestCase; import org.bouncycastle.pqc.jcajce.provider.BouncyCastlePQCProvider; public abstract class FlexiTest extends TestCase { /** * Source of randomness */ protected Random rand; /** * Secure source of randomness */ protected SecureRandom sr; protected void setUp() { Security.addProvider(new BouncyCastlePQCProvider()); // initialize sources of randomness rand = new Random(); sr = new SecureRandom(); // TODO need it? sr.setSeed(sr.generateSeed(20)); } protected static final void assertEquals(byte[] expected, byte[] actual) { assertTrue(Arrays.equals(expected, actual)); } protected static final void assertEquals(String message, byte[] expected, byte[] actual) { assertTrue(message, Arrays.equals(expected, actual)); } protected static final void assertEquals(int[] expected, int[] actual) { assertTrue(Arrays.equals(expected, actual)); } protected static final void assertEquals(String message, int[] expected, int[] actual) { assertTrue(message, Arrays.equals(expected, actual)); } /** * Method used to report test failure when in exception is thrown. * * @param e the exception */ protected static final void fail(Exception e) { fail("Exception thrown: " + e.getClass().getName() + ":\n" + e.getMessage()); } } ././@LongLink0000000000000000000000000000015400000000000011565 Lustar rootrootbouncycastle-1.49.orig/test/src/org/bouncycastle/pqc/jcajce/provider/test/McElieceKobaraImaiCipherTest.javabouncycastle-1.49.orig/test/src/org/bouncycastle/pqc/jcajce/provider/test/McElieceKobaraImaiCipherTe0000644000175000017500000000204412057007333033231 0ustar ebourgebourgpackage org.bouncycastle.pqc.jcajce.provider.test; import java.security.KeyPairGenerator; import java.security.spec.AlgorithmParameterSpec; import javax.crypto.Cipher; import org.bouncycastle.pqc.jcajce.spec.ECCKeyGenParameterSpec; public class McElieceKobaraImaiCipherTest extends AsymmetricHybridCipherTest { protected void setUp() { super.setUp(); try { kpg = KeyPairGenerator.getInstance("McElieceKobaraImai"); cipher = Cipher.getInstance("McElieceKobaraImaiWithSHA256"); } catch (Exception e) { e.printStackTrace(); } } /** * Test encryption and decryption performance for SHA256 message digest and parameters * m=11, t=50. */ public void testEnDecryption_SHA256_11_50() throws Exception { // initialize key pair generator AlgorithmParameterSpec kpgParams = new ECCKeyGenParameterSpec(11, 50); kpg.initialize(kpgParams); performEnDecryptionTest(1, 10, 32, null); } } bouncycastle-1.49.orig/test/src/org/bouncycastle/pqc/jcajce/provider/test/KeyPairGeneratorTest.java0000644000175000017500000000245112057035105033212 0ustar ebourgebourgpackage org.bouncycastle.pqc.jcajce.provider.test; import java.security.KeyFactory; import java.security.KeyPair; import java.security.KeyPairGenerator; import java.security.PrivateKey; import java.security.PublicKey; import java.security.spec.PKCS8EncodedKeySpec; import java.security.spec.X509EncodedKeySpec; public abstract class KeyPairGeneratorTest extends FlexiTest { protected KeyPairGenerator kpg; protected KeyFactory kf; protected final void performKeyPairEncodingTest() { try { KeyPair keyPair = kpg.genKeyPair(); PublicKey pubKey = keyPair.getPublic(); PrivateKey privKey = keyPair.getPrivate(); byte[] encPubKey = pubKey.getEncoded(); byte[] encPrivKey = privKey.getEncoded(); X509EncodedKeySpec pubKeySpec = new X509EncodedKeySpec(encPubKey); PKCS8EncodedKeySpec privKeySpec = new PKCS8EncodedKeySpec( encPrivKey); PublicKey decPubKey = kf.generatePublic(pubKeySpec); PrivateKey decPrivKey = kf.generatePrivate(privKeySpec); assertEquals(pubKey, decPubKey); assertEquals(privKey, decPrivKey); } catch (Exception e) { e.printStackTrace(); fail(e); } } } ././@LongLink0000000000000000000000000000015500000000000011566 Lustar rootrootbouncycastle-1.49.orig/test/src/org/bouncycastle/pqc/jcajce/provider/test/McEliecePointchevalCipherTest.javabouncycastle-1.49.orig/test/src/org/bouncycastle/pqc/jcajce/provider/test/McEliecePointchevalCipherT0000644000175000017500000000207612057007333033346 0ustar ebourgebourgpackage org.bouncycastle.pqc.jcajce.provider.test; import java.security.KeyPairGenerator; import java.security.spec.AlgorithmParameterSpec; import javax.crypto.Cipher; import org.bouncycastle.pqc.jcajce.spec.ECCKeyGenParameterSpec; public class McEliecePointchevalCipherTest extends AsymmetricHybridCipherTest { protected void setUp() { super.setUp(); try { kpg = KeyPairGenerator.getInstance("McEliecePointcheval"); cipher = Cipher.getInstance("McEliecePointchevalWithSHA256"); } catch (Exception e) { e.printStackTrace(); } } /** * Test encryption and decryption performance for SHA256 message digest and parameters * m=11, t=50. */ public void testEnDecryption_SHA256_11_50() throws Exception { // initialize key pair generator AlgorithmParameterSpec kpgParams = new ECCKeyGenParameterSpec(11, 50); kpg.initialize(kpgParams); // perform test performEnDecryptionTest(1, 10, 32, null); } } bouncycastle-1.49.orig/test/src/org/bouncycastle/pqc/jcajce/provider/test/RainbowSignatureTest.java0000644000175000017500000003325212151552116033266 0ustar ebourgebourgpackage org.bouncycastle.pqc.jcajce.provider.test; import java.io.File; import java.io.FileInputStream; import java.io.FileOutputStream; import java.io.IOException; import java.io.InputStream; import java.security.InvalidAlgorithmParameterException; import java.security.InvalidKeyException; import java.security.Key; import java.security.KeyFactory; import java.security.KeyPair; import java.security.KeyPairGenerator; import java.security.PrivateKey; import java.security.PublicKey; import java.security.SecureRandom; import java.security.Security; import java.security.Signature; import java.security.SignatureException; import java.security.spec.AlgorithmParameterSpec; import java.security.spec.PKCS8EncodedKeySpec; import java.security.spec.X509EncodedKeySpec; import java.util.Random; import junit.framework.TestCase; import org.bouncycastle.pqc.jcajce.provider.BouncyCastlePQCProvider; import org.bouncycastle.pqc.jcajce.spec.RainbowParameterSpec; import org.bouncycastle.util.encoders.Hex; public class RainbowSignatureTest extends TestCase { protected KeyPairGenerator kpg; protected Signature sig; private Signature sigVerify; private KeyPair keyPair; private PublicKey pubKey; private PrivateKey privKey; private byte[] mBytes; private byte[] sigBytes; private boolean valid; Random rand = new Random(); private KeyFactory kf; public void setUp() { if (Security.getProvider(BouncyCastlePQCProvider.PROVIDER_NAME) == null) { Security.addProvider(new BouncyCastlePQCProvider()); } } /** * Test signature generation and verification * * @param numPassesKPG the number of key pair generation passes * @param numPassesSigVer the number of sign/verify passes * @param kpgParams the parameters for the key pair generator */ protected final void performSignVerifyTest(int numPassesKPG, int numPassesSigVer, AlgorithmParameterSpec kpgParams) throws Exception { this.performSignVerifyTest(numPassesKPG, numPassesSigVer, kpgParams, 100); } /** * Test signature generation and verification * * @param numPassesKPG the number of key pair generation passes * @param numPassesSigVer the number of sign/verify passes * @param kpgParams the parameters for the key pair generator * @param messageSize length of the messages which are signed in bytes */ protected final void performSignVerifyTest(int numPassesKPG, int numPassesSigVer, AlgorithmParameterSpec kpgParams, int messageSize) throws Exception { // generate new signature instance for verification // sigVerify = (Signature) sig.getClass().newInstance(); sigVerify = Signature.getInstance("SHA384WITHRainbow"); for (int j = 0; j < numPassesKPG; j++) { // generate key pair if (kpgParams != null) { kpg.initialize(kpgParams); } keyPair = kpg.genKeyPair(); pubKey = keyPair.getPublic(); privKey = keyPair.getPrivate(); // initialize signature instances sig.initSign(privKey); sigVerify.initVerify(pubKey); for (int k = 1; k <= numPassesSigVer; k++) { // generate random message mBytes = new byte[messageSize]; rand.nextBytes(mBytes); // sign sig.update(mBytes); sigBytes = sig.sign(); // verify sigVerify.update(mBytes); valid = sigVerify.verify(sigBytes); // compare assertTrue( "Signature generation and verification test failed.\n" + "Message: \"" + new String(Hex.encode(mBytes)) + "\"\n" + privKey + "\n" + pubKey, valid); } } } /** * Test signature generation and verification * * @param numPassesKPG the number of key pair generation passes * @param numPassesSigVer the number of sign/verify passes * @param keySize the key size for the key pair generator */ protected final void performSignVerifyTest(int numPassesKPG, int numPassesSigVer, int keySize) throws Exception { System.out.println("=== TEST ==="); System.out.println(numPassesKPG + " Tests"); System.out.println("KeySize: " + keySize + ""); for (int j = 0; j < numPassesKPG; j++) { // generate key pair kpg.initialize(keySize); keyPair = kpg.genKeyPair(); pubKey = keyPair.getPublic(); //writeKey("RainbowPubKey", pubKey); privKey = keyPair.getPrivate(); // it causes errors! cause RainbowParameters will be null //pubKey = getPublicKey("RainbowPubKey"); // initialize signature instances sig.initSign(privKey, new SecureRandom()); sigVerify.initVerify(pubKey); for (int k = 1; k <= numPassesSigVer; k++) { // generate random message final int messageSize = 100; mBytes = new byte[messageSize]; rand.nextBytes(mBytes); sig.update(mBytes, 0, mBytes.length); sigBytes = sig.sign(); // verify sigVerify.update(mBytes, 0, mBytes.length); valid = sigVerify.verify(sigBytes); // compare assertTrue( "Signature generation and verification test failed.\n" + "Message: \"" + new String(Hex.encode(mBytes)) + "\"\n" + privKey + "\n" + pubKey, valid); } } } protected final void performSignVerifyTest(int numPassesSigVer, PublicKey pubKey, PrivateKey privKey) throws Exception { // initialize signature instances sig.initSign(privKey); sigVerify.initVerify(pubKey); for (int k = 1; k <= numPassesSigVer; k++) { // generate random message final int messageSize = 100; mBytes = new byte[messageSize]; rand.nextBytes(mBytes); // sign sig.update(mBytes); sigBytes = sig.sign(); // verify sigVerify.update(mBytes); valid = sigVerify.verify(sigBytes); // compare assertTrue( "Signature generation and verification test failed.\n" + "Message: \"" + new String(Hex.encode(mBytes)) + "\"\n" + privKey + "\n" + pubKey, valid); } } protected final void performVerifyTest(PublicKey pk, byte[] signature, byte[] message) { try { sig.initVerify(pk); sig.update(message); valid = sig.verify(signature); assertTrue("Signature generation and verification test failed.\n" + "Message: \"" + new String(Hex.encode(mBytes)) + "\"\n" + privKey + "\n" + pubKey, valid); } catch (InvalidKeyException e) { e.printStackTrace(); } catch (SignatureException e) { e.printStackTrace(); } } /** * Using ParameterSpecs to initialize the key pair generator without initialization. */ public void testRainbowWithSHA224() throws Exception { kpg = KeyPairGenerator.getInstance("Rainbow", BouncyCastlePQCProvider.PROVIDER_NAME); sig = Signature.getInstance("SHA224WITHRainbow", BouncyCastlePQCProvider.PROVIDER_NAME); sigVerify = Signature.getInstance("SHA224WITHRainbow", BouncyCastlePQCProvider.PROVIDER_NAME); performSignVerifyTest(1, 1, 28); } public void testRainbowithSHA256() throws Exception { kpg = KeyPairGenerator.getInstance("Rainbow"); sig = Signature.getInstance("SHA256WITHRainbow"); sigVerify = Signature.getInstance("SHA256WITHRainbow"); performSignVerifyTest(1, 1, 32); } public void testRainbowWithSHA384() throws Exception { kpg = KeyPairGenerator.getInstance("Rainbow"); sig = Signature.getInstance("SHA384WITHRainbow"); sigVerify = Signature.getInstance("SHA384WITHRainbow"); performSignVerifyTest(1, 1, 48); } public void testRainbowWithSHA512() throws Exception { kpg = KeyPairGenerator.getInstance("Rainbow"); sig = Signature.getInstance("SHA512WITHRainbow"); sigVerify = Signature.getInstance("SHA512WITHRainbow"); performSignVerifyTest(1, 1, 64); } public void test_KeyFactory() throws Exception { kpg = KeyPairGenerator.getInstance("Rainbow"); KeyFactory kf = KeyFactory.getInstance("Rainbow"); AlgorithmParameterSpec specs = new RainbowParameterSpec(); try { kpg.initialize(specs); } catch (InvalidAlgorithmParameterException e) { e.printStackTrace(); } // XXX kpg.initialize(5); keyPair = kpg.genKeyPair(); pubKey = keyPair.getPublic(); privKey = keyPair.getPrivate(); byte[] pubKeyBytes = pubKey.getEncoded(); X509EncodedKeySpec pubKeySpec = new X509EncodedKeySpec(pubKeyBytes); PKCS8EncodedKeySpec privKeySpec = new PKCS8EncodedKeySpec(privKey.getEncoded()); PublicKey publicKeyKF = kf.generatePublic(pubKeySpec); assertEquals(pubKey, publicKeyKF); assertEquals(pubKey.hashCode(), publicKeyKF.hashCode()); PrivateKey privKeyKF = kf.generatePrivate(privKeySpec); assertEquals(privKey, privKeyKF); assertEquals(privKey.hashCode(), privKeyKF.hashCode()); } public PrivateKey getPrivateKey(String file) throws Exception { byte[] privKeyBytes = getBytesFromFile(new File(file)); PKCS8EncodedKeySpec privKeySpec = new PKCS8EncodedKeySpec(privKeyBytes); return kf.generatePrivate(privKeySpec); } public void writeToFile(String filename, String data) throws IOException { FileOutputStream fos = new FileOutputStream(filename); fos.write(data.getBytes()); fos.close(); } public void testSignVerifyWithRandomParams() throws Exception { kpg = KeyPairGenerator.getInstance("Rainbow"); sig = Signature.getInstance("SHA384WITHRainbow"); int[] vi; for (int kgen = 1; kgen <= 10; kgen++) { vi = chooseRandomParams(); RainbowParameterSpec rbParams = new RainbowParameterSpec(vi); performSignVerifyTest(1, 100, rbParams); } } /** * build up the set of vinegars per layer (vi) * * @return parameters vi */ private int[] chooseRandomParams() { int n = rand.nextInt(10) + 2; int[] vi = new int[n]; vi[0] = rand.nextInt(10) + 2; for (int i = 1; i < n; i++) { vi[i] = vi[i - 1]; vi[i] += rand.nextInt(10) + 1; } return vi; } /* public void testSignVerifyWithSpecialParams() throws Exception { kpg = KeyPairGenerator.getInstance("RainbowWithSHA384"); sig = Signature.getInstance("SHA384WITHRainbow"); int[] vi = { 3, 20, 25, 30, 40, 60, 80, 100 }; performSignVerifyTest(10, 200, new RainbowParameterSpec(vi)); } */ public void testSignVerifyWithDefaultParams() throws Exception { kpg = KeyPairGenerator.getInstance("Rainbow"); sig = Signature.getInstance("SHA384WITHRainbow"); performSignVerifyTest(15, 100, new RainbowParameterSpec()); } public void writeKey(String file, Key key) throws IOException { byte[] privKeyBytes = key.getEncoded(); FileOutputStream fos = new FileOutputStream(file); fos.write(privKeyBytes); fos.close(); } public PublicKey getPublicKey(String file) throws Exception { kf = KeyFactory.getInstance("Rainbow"); byte[] pubKeyBytes = getBytesFromFile(new File(file)); X509EncodedKeySpec pubKeySpec = new X509EncodedKeySpec(pubKeyBytes); return kf.generatePublic(pubKeySpec); } public byte[] getBytesFromFile(File file) throws IOException { InputStream is = new FileInputStream(file); // Get the size of the file long length = file.length(); // You cannot create an array using a long type. // It needs to be an int type. // Before converting to an int type, check // to ensure that file is not larger than Integer.MAX_VALUE. if (length > Integer.MAX_VALUE) { // File is too large } // Create the byte array to hold the data byte[] bytes = new byte[(int)length]; // Read in the bytes int offset = 0; int numRead = 0; while (offset < bytes.length && (numRead = is.read(bytes, offset, bytes.length - offset)) >= 0) { offset += numRead; } // Ensure all the bytes have been read in if (offset < bytes.length) { throw new IOException("Could not completely read file " + file.getName()); } // Close the input stream and return bytes is.close(); return bytes; } } ././@LongLink0000000000000000000000000000015200000000000011563 Lustar rootrootbouncycastle-1.49.orig/test/src/org/bouncycastle/pqc/jcajce/provider/test/AsymmetricHybridCipherTest.javabouncycastle-1.49.orig/test/src/org/bouncycastle/pqc/jcajce/provider/test/AsymmetricHybridCipherTest0000644000175000017500000000533412057035105033474 0ustar ebourgebourgpackage org.bouncycastle.pqc.jcajce.provider.test; import java.security.KeyPair; import java.security.KeyPairGenerator; import java.security.PrivateKey; import java.security.PublicKey; import java.security.spec.AlgorithmParameterSpec; import javax.crypto.Cipher; import org.bouncycastle.pqc.jcajce.provider.util.AsymmetricHybridCipher; import org.bouncycastle.pqc.math.linearalgebra.ByteUtils; /** * Base class for unit tests of {@link AsymmetricHybridCipher}s. */ public abstract class AsymmetricHybridCipherTest extends FlexiTest { /** * the {@link KeyPairGenerator} to use for the test */ protected KeyPairGenerator kpg; /** * the {@link AsymmetricHybridCipher} to use for the test */ protected Cipher cipher; private KeyPair keyPair; private PublicKey pubKey; private PrivateKey privKey; private byte[] mBytes, cBytes, dBytes; protected final void performEnDecryptionTest(int numPassesKPG, int numPassesEncDec, int plainTextSize, AlgorithmParameterSpec params) { try { for (int j = 0; j < numPassesKPG; j++) { // generate key pair //kpg.initialize(params); keyPair = kpg.genKeyPair(); pubKey = keyPair.getPublic(); privKey = keyPair.getPrivate(); for (int k = 1; k <= numPassesEncDec; k++) { // initialize for encryption cipher.init(Cipher.ENCRYPT_MODE, pubKey, params, sr); // generate random message int mLength = rand.nextInt(plainTextSize) + 1; mBytes = new byte[mLength]; rand.nextBytes(mBytes); // encrypt cBytes = cipher.doFinal(mBytes); // initialize for decryption cipher.init(Cipher.DECRYPT_MODE, privKey, params); // decrypt dBytes = cipher.doFinal(cBytes); // compare assertEquals( "Encryption/decryption test failed for message \"" + ByteUtils.toHexString(mBytes) + "\":\n actual decrypted text: " + ByteUtils.toHexString(dBytes) + "\n expected plain text: " + ByteUtils.toHexString(mBytes), mBytes, dBytes); } } } catch (Exception e) { e.printStackTrace(); fail(e); } } } ././@LongLink0000000000000000000000000000016000000000000011562 Lustar rootrootbouncycastle-1.49.orig/test/src/org/bouncycastle/pqc/jcajce/provider/test/McElieceCCA2KeyPairGeneratorTest.javabouncycastle-1.49.orig/test/src/org/bouncycastle/pqc/jcajce/provider/test/McElieceCCA2KeyPairGenerat0000644000175000017500000000153712057035105033055 0ustar ebourgebourgpackage org.bouncycastle.pqc.jcajce.provider.test; import java.security.KeyFactory; import java.security.KeyPairGenerator; import java.security.NoSuchAlgorithmException; import org.bouncycastle.pqc.jcajce.spec.ECCKeyGenParameterSpec; public class McElieceCCA2KeyPairGeneratorTest extends KeyPairGeneratorTest { protected void setUp() { super.setUp(); try { kf = KeyFactory.getInstance("McElieceCCA2"); } catch (NoSuchAlgorithmException e) { e.printStackTrace(); } } public void testKeyPairEncoding_9_33() throws Exception { kpg = KeyPairGenerator.getInstance("McElieceKobaraImai"); ECCKeyGenParameterSpec params = new ECCKeyGenParameterSpec(9, 33); kpg.initialize(params); performKeyPairEncodingTest(); } } ././@LongLink0000000000000000000000000000014600000000000011566 Lustar rootrootbouncycastle-1.49.orig/test/src/org/bouncycastle/pqc/jcajce/provider/test/McEliecePKCSCipherTest.javabouncycastle-1.49.orig/test/src/org/bouncycastle/pqc/jcajce/provider/test/McEliecePKCSCipherTest.jav0000644000175000017500000000202400000000102033062 0ustar ebourgebourgpackage org.bouncycastle.pqc.jcajce.provider.test; import java.security.KeyPairGenerator; import javax.crypto.Cipher; import org.bouncycastle.pqc.jcajce.spec.ECCKeyGenParameterSpec; public class McEliecePKCSCipherTest extends AsymmetricBlockCipherTest { protected void setUp() { super.setUp(); try { kpg = KeyPairGenerator.getInstance("McEliecePKCS"); cipher = Cipher.getInstance("McEliecePKCSwithSHA256"); } catch (Exception e) { e.printStackTrace(); } } public void testEnDecryption_9_33() throws Exception { ECCKeyGenParameterSpec params = new ECCKeyGenParameterSpec(9, 33); kpg.initialize(params); performEnDecryptionTest(2, 10, params); } public void testEnDecryption_11_50() throws Exception { ECCKeyGenParameterSpec params = new ECCKeyGenParameterSpec(11, 50); kpg.initialize(params); performEnDecryptionTest(2, 10, params); } } bouncycastle-1.49.orig/test/src/org/bouncycastle/pqc/jcajce/provider/test/AllTests.java0000644000175000017500000000177112057035105030676 0ustar ebourgebourgpackage org.bouncycastle.pqc.jcajce.provider.test; import java.security.Security; import junit.framework.Test; import junit.framework.TestCase; import junit.framework.TestSuite; import org.bouncycastle.pqc.jcajce.provider.BouncyCastlePQCProvider; public class AllTests extends TestCase { public static void main (String[] args) { junit.textui.TestRunner.run(suite()); } public static Test suite() { TestSuite suite = new TestSuite("PQC JCE Tests"); if (Security.getProvider(BouncyCastlePQCProvider.PROVIDER_NAME) == null) { Security.addProvider(new BouncyCastlePQCProvider()); } suite.addTestSuite(RainbowSignatureTest.class); suite.addTestSuite(McElieceFujisakiCipherTest.class); suite.addTestSuite(McElieceKobaraImaiCipherTest.class); suite.addTestSuite(McEliecePointchevalCipherTest.class); suite.addTestSuite(McEliecePKCSCipherTest.class); return suite; } } ././@LongLink0000000000000000000000000000015200000000000011563 Lustar rootrootbouncycastle-1.49.orig/test/src/org/bouncycastle/pqc/jcajce/provider/test/McElieceCCA2PrimitivesTest.javabouncycastle-1.49.orig/test/src/org/bouncycastle/pqc/jcajce/provider/test/McElieceCCA2PrimitivesTest0000644000175000017500000000377712057035105033206 0ustar ebourgebourgpackage org.bouncycastle.pqc.jcajce.provider.test; import java.security.KeyPair; import java.security.KeyPairGenerator; import java.security.NoSuchAlgorithmException; import org.bouncycastle.pqc.jcajce.provider.mceliece.BCMcElieceCCA2PrivateKey; import org.bouncycastle.pqc.jcajce.provider.mceliece.BCMcElieceCCA2PublicKey; import org.bouncycastle.pqc.jcajce.provider.mceliece.McElieceCCA2Primitives; import org.bouncycastle.pqc.jcajce.spec.ECCKeyGenParameterSpec; import org.bouncycastle.pqc.math.linearalgebra.GF2Vector; public class McElieceCCA2PrimitivesTest extends FlexiTest { KeyPairGenerator kpg; protected void setUp() { super.setUp(); try { kpg = KeyPairGenerator.getInstance("McElieceKobaraImai"); } catch (NoSuchAlgorithmException e) { e.printStackTrace(); } } public void testPrimitives() throws Exception { int m = 11; int t = 50; initKPG(m, t); int n = 1 << m; KeyPair pair = kpg.genKeyPair(); BCMcElieceCCA2PublicKey pubKey = (BCMcElieceCCA2PublicKey)pair.getPublic(); BCMcElieceCCA2PrivateKey privKey = (BCMcElieceCCA2PrivateKey)pair .getPrivate(); GF2Vector plaintext = new GF2Vector(pubKey.getK(), sr); GF2Vector errors = new GF2Vector(n, t, sr); GF2Vector ciphertext = McElieceCCA2Primitives.encryptionPrimitive( pubKey, plaintext, errors); GF2Vector[] dec = McElieceCCA2Primitives.decryptionPrimitive(privKey, ciphertext); GF2Vector plaintextAgain = dec[0]; GF2Vector errorsAgain = dec[1]; assertEquals(plaintext, plaintextAgain); assertEquals(errors, errorsAgain); } /** * Initialize the key pair generator with the given parameters. */ private void initKPG(int m, int t) throws Exception { ECCKeyGenParameterSpec params = new ECCKeyGenParameterSpec(m, t); kpg.initialize(params); } } ././@LongLink0000000000000000000000000000015400000000000011565 Lustar rootrootbouncycastle-1.49.orig/test/src/org/bouncycastle/pqc/jcajce/provider/test/McElieceKeyPairGeneratorTest.javabouncycastle-1.49.orig/test/src/org/bouncycastle/pqc/jcajce/provider/test/McElieceKeyPairGeneratorTe0000644000175000017500000000152012057007435033313 0ustar ebourgebourgpackage org.bouncycastle.pqc.jcajce.provider.test; import java.security.KeyFactory; import java.security.KeyPairGenerator; import java.security.NoSuchAlgorithmException; import org.bouncycastle.pqc.jcajce.spec.ECCKeyGenParameterSpec; public class McElieceKeyPairGeneratorTest extends KeyPairGeneratorTest { protected void setUp() { super.setUp(); try { kf = KeyFactory.getInstance("McEliece"); } catch (NoSuchAlgorithmException e) { e.printStackTrace(); } } public void testKeyPairEncoding_9_33() throws Exception { kpg = KeyPairGenerator.getInstance("McEliecePKCS"); ECCKeyGenParameterSpec params = new ECCKeyGenParameterSpec(9, 33); kpg.initialize(params); performKeyPairEncodingTest(); } } ././@LongLink0000000000000000000000000000015200000000000011563 Lustar rootrootbouncycastle-1.49.orig/test/src/org/bouncycastle/pqc/jcajce/provider/test/McElieceFujisakiCipherTest.javabouncycastle-1.49.orig/test/src/org/bouncycastle/pqc/jcajce/provider/test/McElieceFujisakiCipherTest0000644000175000017500000000200512057007333033343 0ustar ebourgebourgpackage org.bouncycastle.pqc.jcajce.provider.test; import java.security.KeyPairGenerator; import javax.crypto.Cipher; import org.bouncycastle.pqc.jcajce.spec.ECCKeyGenParameterSpec; public class McElieceFujisakiCipherTest extends AsymmetricHybridCipherTest { protected void setUp() { super.setUp(); try { kpg = KeyPairGenerator.getInstance("McElieceFujisaki"); cipher = Cipher.getInstance("McElieceFujisakiWithSHA256"); } catch (Exception e) { e.printStackTrace(); } } /** * Test encryption and decryption performance for SHA256 message digest and parameters * m=11, t=50. */ public void testEnDecryption_SHA256_11_50() throws Exception { // initialize key pair generator ECCKeyGenParameterSpec kpgParams = new ECCKeyGenParameterSpec(11, 50); kpg.initialize(kpgParams); // perform test performEnDecryptionTest(1, 10, 32, null); } } bouncycastle-1.49.orig/test/src/org/bouncycastle/mail/0000755000175000017500000000000012152033550022377 5ustar ebourgebourgbouncycastle-1.49.orig/test/src/org/bouncycastle/mail/smime/0000755000175000017500000000000012152033550023511 5ustar ebourgebourgbouncycastle-1.49.orig/test/src/org/bouncycastle/mail/smime/test/0000755000175000017500000000000012152033550024470 5ustar ebourgebourgbouncycastle-1.49.orig/test/src/org/bouncycastle/mail/smime/test/SMIMECompressedTest.java0000644000175000017500000001655211726257322031116 0ustar ebourgebourgpackage org.bouncycastle.mail.smime.test; import java.io.ByteArrayOutputStream; import java.io.InputStream; import java.security.KeyPair; import java.security.cert.CertStore; import java.security.cert.CollectionCertStoreParameters; import java.security.cert.X509Certificate; import java.util.ArrayList; import java.util.Collection; import java.util.Iterator; import java.util.List; import javax.mail.Session; import javax.mail.internet.MimeBodyPart; import javax.mail.internet.MimeMessage; import javax.mail.internet.MimeMultipart; import junit.framework.Test; import junit.framework.TestCase; import junit.framework.TestSuite; import org.bouncycastle.asn1.ASN1EncodableVector; import org.bouncycastle.asn1.cms.AttributeTable; import org.bouncycastle.asn1.smime.SMIMECapabilitiesAttribute; import org.bouncycastle.asn1.smime.SMIMECapability; import org.bouncycastle.asn1.smime.SMIMECapabilityVector; import org.bouncycastle.cms.SignerInformation; import org.bouncycastle.cms.SignerInformationStore; import org.bouncycastle.cms.jcajce.JcaX509CertSelectorConverter; import org.bouncycastle.cms.test.CMSTestUtil; import org.bouncycastle.mail.smime.SMIMECompressed; import org.bouncycastle.mail.smime.SMIMECompressedGenerator; import org.bouncycastle.mail.smime.SMIMECompressedParser; import org.bouncycastle.mail.smime.SMIMESigned; import org.bouncycastle.mail.smime.SMIMESignedGenerator; import org.bouncycastle.mail.smime.SMIMEUtil; import org.bouncycastle.util.Arrays; public class SMIMECompressedTest extends TestCase { private static final String COMPRESSED_CONTENT_TYPE = "application/pkcs7-mime; name=\"smime.p7z\"; smime-type=compressed-data"; private static final JcaX509CertSelectorConverter selectorConverter = new JcaX509CertSelectorConverter(); boolean DEBUG = true; MimeBodyPart msg; String signDN; KeyPair signKP; X509Certificate signCert; String origDN; KeyPair origKP; X509Certificate origCert; String reciDN; KeyPair reciKP; X509Certificate reciCert; KeyPair dsaSignKP; X509Certificate dsaSignCert; KeyPair dsaOrigKP; X509Certificate dsaOrigCert; /* * * INFRASTRUCTURE * */ public SMIMECompressedTest( String name) throws Exception { super(name); msg = SMIMETestUtil.makeMimeBodyPart("Hello world!"); signDN = "O=Bouncy Castle, C=AU"; signKP = CMSTestUtil.makeKeyPair(); signCert = CMSTestUtil.makeCertificate(signKP, signDN, signKP, signDN); origDN = "CN=Eric H. Echidna, E=eric@bouncycastle.org, O=Bouncy Castle, C=AU"; origKP = CMSTestUtil.makeKeyPair(); origCert = CMSTestUtil.makeCertificate(origKP, origDN, signKP, signDN); } public static void main(String args[]) { junit.textui.TestRunner.run(SMIMECompressedTest.class); } public static Test suite() { return new SMIMETestSetup(new TestSuite(SMIMECompressedTest.class)); } public void testHeaders() throws Exception { SMIMECompressedGenerator cgen = new SMIMECompressedGenerator(); MimeBodyPart cbp = cgen.generate(msg, SMIMECompressedGenerator.ZLIB); assertEquals(COMPRESSED_CONTENT_TYPE, cbp.getHeader("Content-Type")[0]); assertEquals("attachment; filename=\"smime.p7z\"", cbp.getHeader("Content-Disposition")[0]); assertEquals("S/MIME Compressed Message", cbp.getHeader("Content-Description")[0]); } public void testBasic() throws Exception { SMIMECompressedGenerator cgen = new SMIMECompressedGenerator(); ByteArrayOutputStream bOut = new ByteArrayOutputStream(); MimeBodyPart cbp = cgen.generate(msg, SMIMECompressedGenerator.ZLIB); SMIMECompressed sc = new SMIMECompressed(cbp); msg.writeTo(bOut); assertTrue(Arrays.areEqual(bOut.toByteArray(), sc.getContent())); } public void testParser() throws Exception { SMIMECompressedGenerator cgen = new SMIMECompressedGenerator(); ByteArrayOutputStream bOut1 = new ByteArrayOutputStream(); ByteArrayOutputStream bOut2 = new ByteArrayOutputStream(); MimeBodyPart cbp = cgen.generate(msg, SMIMECompressedGenerator.ZLIB); SMIMECompressedParser sc = new SMIMECompressedParser(cbp); msg.writeTo(bOut1); InputStream in = sc.getContent().getContentStream(); int ch; while ((ch = in.read()) >= 0) { bOut2.write(ch); } assertTrue(Arrays.areEqual(bOut1.toByteArray(), bOut2.toByteArray())); } /* * test compressing and uncompressing of a multipart-signed message. */ public void testCompressedSHA1WithRSA() throws Exception { List certList = new ArrayList(); certList.add(origCert); certList.add(signCert); CertStore certs = CertStore.getInstance("Collection", new CollectionCertStoreParameters(certList), "BC"); ASN1EncodableVector signedAttrs = new ASN1EncodableVector(); SMIMECapabilityVector caps = new SMIMECapabilityVector(); caps.addCapability(SMIMECapability.dES_EDE3_CBC); caps.addCapability(SMIMECapability.rC2_CBC, 128); caps.addCapability(SMIMECapability.dES_CBC); signedAttrs.add(new SMIMECapabilitiesAttribute(caps)); SMIMESignedGenerator gen = new SMIMESignedGenerator(); gen.addSigner(origKP.getPrivate(), origCert, SMIMESignedGenerator.DIGEST_SHA1, new AttributeTable(signedAttrs), null); gen.addCertificatesAndCRLs(certs); MimeMultipart smp = gen.generate(msg, "BC"); MimeMessage bp2 = new MimeMessage((Session)null); bp2.setContent(smp); bp2.saveChanges(); SMIMECompressedGenerator cgen = new SMIMECompressedGenerator(); MimeBodyPart cbp = cgen.generate(bp2, SMIMECompressedGenerator.ZLIB); SMIMECompressed cm = new SMIMECompressed(cbp); MimeMultipart mm = (MimeMultipart)SMIMEUtil.toMimeBodyPart(cm.getContent()).getContent(); SMIMESigned s = new SMIMESigned(mm); ByteArrayOutputStream _baos = new ByteArrayOutputStream(); msg.writeTo(_baos); _baos.close(); byte[] _msgBytes = _baos.toByteArray(); _baos = new ByteArrayOutputStream(); s.getContent().writeTo(_baos); _baos.close(); byte[] _resBytes = _baos.toByteArray(); assertEquals(true, Arrays.areEqual(_msgBytes, _resBytes)); certs = s.getCertificatesAndCRLs("Collection", "BC"); SignerInformationStore signers = s.getSignerInfos(); Collection c = signers.getSigners(); Iterator it = c.iterator(); while (it.hasNext()) { SignerInformation signer = (SignerInformation)it.next(); Collection certCollection = certs.getCertificates(selectorConverter.getCertSelector(signer.getSID())); Iterator certIt = certCollection.iterator(); X509Certificate cert = (X509Certificate)certIt.next(); assertEquals(true, signer.verify(cert, "BC")); } } } bouncycastle-1.49.orig/test/src/org/bouncycastle/mail/smime/test/SMIMETestUtil.java0000644000175000017500000000226510536763067027731 0ustar ebourgebourgpackage org.bouncycastle.mail.smime.test; import org.bouncycastle.jce.provider.BouncyCastleProvider; import javax.mail.MessagingException; import javax.mail.internet.MimeBodyPart; import javax.mail.internet.MimeMultipart; import java.security.Security; public class SMIMETestUtil { public static final boolean DEBUG = true; static { Security.addProvider(new BouncyCastleProvider()); } /* * * MAIL * */ public static MimeBodyPart makeMimeBodyPart(String msg) throws MessagingException { MimeBodyPart _mbp = new MimeBodyPart(); _mbp.setText(msg); return _mbp; } public static MimeBodyPart makeMimeBodyPart(MimeMultipart mm) throws MessagingException { MimeBodyPart _mbp = new MimeBodyPart(); _mbp.setContent(mm, mm.getContentType()); return _mbp; } public static MimeMultipart makeMimeMultipart(String msg1, String msg2) throws MessagingException { MimeMultipart _mm = new MimeMultipart(); _mm.addBodyPart(makeMimeBodyPart(msg1)); _mm.addBodyPart(makeMimeBodyPart(msg2)); return _mm; } } bouncycastle-1.49.orig/test/src/org/bouncycastle/mail/smime/test/NewSMIMESignedTest.java0000644000175000017500000012753111726036237030675 0ustar ebourgebourgpackage org.bouncycastle.mail.smime.test; import java.io.ByteArrayOutputStream; import java.io.File; import java.io.FileNotFoundException; import java.io.FilterOutputStream; import java.io.IOException; import java.io.OutputStream; import java.io.UnsupportedEncodingException; import java.security.KeyPair; import java.security.MessageDigest; import java.security.cert.X509Certificate; import java.util.ArrayList; import java.util.Arrays; import java.util.Collection; import java.util.Date; import java.util.Enumeration; import java.util.Iterator; import java.util.List; import java.util.Map; import java.util.Properties; import javax.mail.BodyPart; import javax.mail.MessagingException; import javax.mail.Session; import javax.mail.internet.ContentType; import javax.mail.internet.InternetHeaders; import javax.mail.internet.MimeBodyPart; import javax.mail.internet.MimeMessage; import javax.mail.internet.MimeMultipart; import junit.framework.Test; import junit.framework.TestCase; import junit.framework.TestSuite; import org.bouncycastle.asn1.ASN1EncodableVector; import org.bouncycastle.asn1.ASN1OctetString; import org.bouncycastle.asn1.DERSet; import org.bouncycastle.asn1.cms.Attribute; import org.bouncycastle.asn1.cms.AttributeTable; import org.bouncycastle.asn1.cms.CMSAttributes; import org.bouncycastle.asn1.cms.Time; import org.bouncycastle.asn1.cryptopro.CryptoProObjectIdentifiers; import org.bouncycastle.asn1.nist.NISTObjectIdentifiers; import org.bouncycastle.asn1.pkcs.PKCSObjectIdentifiers; import org.bouncycastle.asn1.smime.SMIMECapabilitiesAttribute; import org.bouncycastle.asn1.smime.SMIMECapability; import org.bouncycastle.asn1.smime.SMIMECapabilityVector; import org.bouncycastle.asn1.teletrust.TeleTrusTObjectIdentifiers; import org.bouncycastle.cert.X509CertificateHolder; import org.bouncycastle.cert.jcajce.JcaAttrCertStore; import org.bouncycastle.cert.jcajce.JcaCertStore; import org.bouncycastle.cert.jcajce.JcaX509AttributeCertificateHolder; import org.bouncycastle.cms.DefaultSignedAttributeTableGenerator; import org.bouncycastle.cms.SignerInformation; import org.bouncycastle.cms.SignerInformationStore; import org.bouncycastle.cms.jcajce.JcaSimpleSignerInfoGeneratorBuilder; import org.bouncycastle.cms.jcajce.JcaSimpleSignerInfoVerifierBuilder; import org.bouncycastle.cms.test.CMSTestUtil; import org.bouncycastle.mail.smime.SMIMESigned; import org.bouncycastle.mail.smime.SMIMESignedGenerator; import org.bouncycastle.mail.smime.SMIMESignedParser; import org.bouncycastle.mail.smime.util.CRLFOutputStream; import org.bouncycastle.mail.smime.util.FileBackedMimeBodyPart; import org.bouncycastle.operator.jcajce.JcaDigestCalculatorProviderBuilder; import org.bouncycastle.util.Store; import org.bouncycastle.x509.X509AttributeCertificate; public class NewSMIMESignedTest extends TestCase { static MimeBodyPart msg; static MimeBodyPart msgR; static MimeBodyPart msgRN; static String _origDN; static KeyPair _origKP; static X509Certificate _origCert; static String _signDN; static KeyPair _signKP; static X509Certificate _signCert; static String reciDN; static KeyPair reciKP; static X509Certificate reciCert; private static KeyPair _signGostKP; private static X509Certificate _signGostCert; private static KeyPair _signEcDsaKP; private static X509Certificate _signEcDsaCert; private static KeyPair _signEcGostKP; private static X509Certificate _signEcGostCert; KeyPair dsaSignKP; X509Certificate dsaSignCert; KeyPair dsaOrigKP; X509Certificate dsaOrigCert; private static final String BC = "BC"; static { try { msg = SMIMETestUtil.makeMimeBodyPart("Hello world!\n"); msgR = SMIMETestUtil.makeMimeBodyPart("Hello world!\r"); msgRN = SMIMETestUtil.makeMimeBodyPart("Hello world!\r\n"); _origDN = "O=Bouncy Castle, C=AU"; _origKP = CMSTestUtil.makeKeyPair(); _origCert = CMSTestUtil.makeCertificate(_origKP, _origDN, _origKP, _origDN); _signDN = "CN=Eric H. Echidna, E=eric@bouncycastle.org, O=Bouncy Castle, C=AU"; _signKP = CMSTestUtil.makeKeyPair(); _signCert = CMSTestUtil.makeCertificate(_signKP, _signDN, _origKP, _origDN); _signGostKP = CMSTestUtil.makeGostKeyPair(); _signGostCert = CMSTestUtil.makeCertificate(_signGostKP, _signDN, _origKP, _origDN); _signEcDsaKP = CMSTestUtil.makeEcDsaKeyPair(); _signEcDsaCert = CMSTestUtil.makeCertificate(_signEcDsaKP, _signDN, _origKP, _origDN); _signEcGostKP = CMSTestUtil.makeEcGostKeyPair(); _signEcGostCert = CMSTestUtil.makeCertificate(_signEcGostKP, _signDN, _origKP, _origDN); } catch (Exception e) { throw new RuntimeException("problem setting up signed test class: " + e); } } private static class LineOutputStream extends FilterOutputStream { private static byte newline[]; public LineOutputStream(OutputStream outputstream) { super(outputstream); } public void writeln(String s) throws MessagingException { try { byte abyte0[] = getBytes(s); super.out.write(abyte0); super.out.write(newline); } catch(Exception exception) { throw new MessagingException("IOException", exception); } } public void writeln() throws MessagingException { try { super.out.write(newline); } catch(Exception exception) { throw new MessagingException("IOException", exception); } } static { newline = new byte[2]; newline[0] = 13; newline[1] = 10; } private static byte[] getBytes(String s) { char ac[] = s.toCharArray(); int i = ac.length; byte abyte0[] = new byte[i]; int j = 0; while (j < i) { abyte0[j] = (byte)ac[j++]; } return abyte0; } } /* * * INFRASTRUCTURE * */ public NewSMIMESignedTest(String name) { super(name); } public static void main(String args[]) { junit.textui.TestRunner.run(NewSMIMESignedTest.class); } public static Test suite() { return new SMIMETestSetup(new TestSuite(NewSMIMESignedTest.class)); } public void testHeaders() throws Exception { MimeMultipart smm = generateMultiPartRsa("SHA1withRSA", msg, SMIMESignedGenerator.RFC3851_MICALGS); BodyPart bp = smm.getBodyPart(1); assertEquals("application/pkcs7-signature; name=smime.p7s; smime-type=signed-data", bp.getHeader("Content-Type")[0]); assertEquals("attachment; filename=\"smime.p7s\"", bp.getHeader("Content-Disposition")[0]); assertEquals("S/MIME Cryptographic Signature", bp.getHeader("Content-Description")[0]); } public void testHeadersEncapsulated() throws Exception { List certList = new ArrayList(); certList.add(_signCert); certList.add(_origCert); Store certs = new JcaCertStore(certList); ASN1EncodableVector signedAttrs = generateSignedAttributes(); SMIMESignedGenerator gen = new SMIMESignedGenerator(); gen.addSignerInfoGenerator(new JcaSimpleSignerInfoGeneratorBuilder().setProvider(BC).setSignedAttributeGenerator(new AttributeTable(signedAttrs)).build("SHA1withRSA", _signKP.getPrivate(), _signCert)); gen.addCertificates(certs); MimeBodyPart res = gen.generateEncapsulated(msg); assertEquals("application/pkcs7-mime; name=smime.p7m; smime-type=signed-data", res.getHeader("Content-Type")[0]); assertEquals("attachment; filename=\"smime.p7m\"", res.getHeader("Content-Disposition")[0]); assertEquals("S/MIME Cryptographic Signed Data", res.getHeader("Content-Description")[0]); } public void testMultipartTextText() throws Exception { MimeBodyPart part1 = createTemplate("text/html", "7bit"); MimeBodyPart part2 = createTemplate("text/xml", "7bit"); multipartMixedTest(part1, part2); } public void testMultipartTextBinary() throws Exception { MimeBodyPart part1 = createTemplate("text/html", "7bit"); MimeBodyPart part2 = createTemplate("text/xml", "binary"); multipartMixedTest(part1, part2); } public void testMultipartBinaryText() throws Exception { MimeBodyPart part1 = createTemplate("text/xml", "binary"); MimeBodyPart part2 = createTemplate("text/html", "7bit"); multipartMixedTest(part1, part2); } public void testMultipartBinaryBinary() throws Exception { MimeBodyPart part1 = createTemplate("text/xml", "binary"); MimeBodyPart part2 = createTemplate("text/html", "binary"); multipartMixedTest(part1, part2); } public void testSHA1WithRSAPSS() throws Exception { rsaPSSTest("SHA1", SMIMESignedGenerator.DIGEST_SHA1); } public void testSHA224WithRSAPSS() throws Exception { rsaPSSTest("SHA224", SMIMESignedGenerator.DIGEST_SHA224); } public void testSHA256WithRSAPSS() throws Exception { rsaPSSTest("SHA256", SMIMESignedGenerator.DIGEST_SHA256); } public void testSHA384WithRSAPSS() throws Exception { rsaPSSTest("SHA384", SMIMESignedGenerator.DIGEST_SHA384); } public void multipartMixedTest(MimeBodyPart part1, MimeBodyPart part2) throws Exception { MimeMultipart mp = new MimeMultipart(); mp.addBodyPart(part1); mp.addBodyPart(part2); MimeBodyPart m = new MimeBodyPart(); m.setContent(mp); MimeMultipart smm = generateMultiPartRsa("SHA1withRSA", m, SMIMESignedGenerator.RFC3851_MICALGS); SMIMESigned s = new SMIMESigned(smm); verifySigners(s.getCertificates(), s.getSignerInfos()); AttributeTable attr = ((SignerInformation)s.getSignerInfos().getSigners().iterator().next()).getSignedAttributes(); Attribute a = attr.get(CMSAttributes.messageDigest); byte[] contentDigest = ASN1OctetString.getInstance(a.getAttrValues().getObjectAt(0)).getOctets(); mp = (MimeMultipart)m.getContent(); ContentType contentType = new ContentType(mp.getContentType()); String boundary = "--" + contentType.getParameter("boundary"); ByteArrayOutputStream bOut = new ByteArrayOutputStream(); LineOutputStream lOut = new LineOutputStream(bOut); Enumeration headers = m.getAllHeaderLines(); while (headers.hasMoreElements()) { lOut.writeln((String)headers.nextElement()); } lOut.writeln(); // CRLF separator lOut.writeln(boundary); writePart(mp.getBodyPart(0), bOut); lOut.writeln(); // CRLF terminator lOut.writeln(boundary); writePart(mp.getBodyPart(1), bOut); lOut.writeln(); lOut.writeln(boundary + "--"); MessageDigest dig = MessageDigest.getInstance("SHA1", BC); assertTrue(Arrays.equals(contentDigest, dig.digest(bOut.toByteArray()))); } private void writePart(BodyPart part, ByteArrayOutputStream bOut) throws MessagingException, IOException { if (part.getHeader("Content-Transfer-Encoding")[0].equals("binary")) { part.writeTo(bOut); } else { part.writeTo(new CRLFOutputStream(bOut)); } } public void testSHA1WithRSA() throws Exception { MimeMultipart smm = generateMultiPartRsa("SHA1withRSA", msg, SMIMESignedGenerator.RFC3851_MICALGS); SMIMESigned s = new SMIMESigned(smm); verifyMessageBytes(msg, s.getContent()); verifySigners(s.getCertificates(), s.getSignerInfos()); } public void testSHA1WithRSAAddSigners() throws Exception { MimeMultipart smm = generateMultiPartRsa("SHA1withRSA", msg, SMIMESignedGenerator.RFC3851_MICALGS); SMIMESigned s = new SMIMESigned(smm); List certList = new ArrayList(); certList.add(_signCert); certList.add(_origCert); Store certs = new JcaCertStore(certList); SMIMESignedGenerator gen = new SMIMESignedGenerator(); gen.addSigners(s.getSignerInfos()); gen.addCertificates(certs); SMIMESigned newS = new SMIMESigned(gen.generate(msg)); verifyMessageBytes(msg, newS.getContent()); verifySigners(newS.getCertificates(), newS.getSignerInfos()); } public void testMD5WithRSAAddSignersSHA1() throws Exception { MimeMultipart smm = generateMultiPartRsa("SHA1withRSA", msg, SMIMESignedGenerator.STANDARD_MICALGS); SMIMESigned s = new SMIMESigned(smm); assertEquals("sha-1", getMicAlg(smm)); List certList = new ArrayList(); certList.add(_signCert); certList.add(_origCert); Store certs = new JcaCertStore(certList); SMIMESignedGenerator gen = new SMIMESignedGenerator(); gen.addSignerInfoGenerator(new JcaSimpleSignerInfoGeneratorBuilder().setProvider(BC).build("MD5withRSA", _signKP.getPrivate(), _signCert)); gen.addSigners(s.getSignerInfos()); gen.addCertificates(certs); smm = gen.generate(msg); SMIMESigned newS = new SMIMESigned(gen.generate(msg)); verifyMessageBytes(msg, newS.getContent()); verifySigners(newS.getCertificates(), newS.getSignerInfos()); assertEquals("\"md5,sha-1\"", getMicAlg(smm)); } public void testSHA1WithRSACanonicalization() throws Exception { Date testTime = new Date(); MimeMultipart smm = generateMultiPartRsa("SHA1withRSA", msg, testTime, SMIMESignedGenerator.RFC3851_MICALGS); byte[] sig1 = getEncodedStream(smm); smm = generateMultiPartRsa("SHA1withRSA", msgR, testTime, SMIMESignedGenerator.RFC3851_MICALGS); byte[] sig2 = getEncodedStream(smm); assertTrue(Arrays.equals(sig1, sig2)); smm = generateMultiPartRsa("SHA1withRSA", msgRN, testTime, SMIMESignedGenerator.RFC3851_MICALGS); byte[] sig3 = getEncodedStream(smm); assertTrue(Arrays.equals(sig1, sig3)); } private byte[] getEncodedStream(MimeMultipart smm) throws IOException, MessagingException { ByteArrayOutputStream bOut = new ByteArrayOutputStream(); smm.getBodyPart(1).writeTo(bOut); return bOut.toByteArray(); } public void testSHA1WithRSAEncapsulated() throws Exception { MimeBodyPart res = generateEncapsulatedRsa("SHA1withRSA", msg); SMIMESigned s = new SMIMESigned(res); verifyMessageBytes(msg, s.getContent()); verifySigners(s.getCertificates(), s.getSignerInfos()); } public void testSHA1WithRSAEncapsulatedParser() throws Exception { MimeBodyPart res = generateEncapsulatedRsa("SHA1withRSA", msg); SMIMESignedParser s = new SMIMESignedParser(new JcaDigestCalculatorProviderBuilder().setProvider(BC).build(), res); FileBackedMimeBodyPart content = (FileBackedMimeBodyPart)s.getContent(); verifyMessageBytes(msg, content); content.dispose(); verifySigners(s.getCertificates(), s.getSignerInfos()); s.close(); } public void testSHA1WithRSAEncapsulatedParserAndFile() throws Exception { File tmp = File.createTempFile("bcTest", ".mime"); MimeBodyPart res = generateEncapsulatedRsa("SHA1withRSA", msg); SMIMESignedParser s = new SMIMESignedParser(new JcaDigestCalculatorProviderBuilder().setProvider(BC).build(), res, tmp); FileBackedMimeBodyPart content = (FileBackedMimeBodyPart)s.getContent(); verifyMessageBytes(msg, s.getContent()); verifySigners(s.getCertificates(), s.getSignerInfos()); assertTrue(tmp.exists()); s.close(); content.dispose(); assertFalse(tmp.exists()); } public void testMD5WithRSA() throws Exception { MimeMultipart smm = generateMultiPartRsa("MD5withRSA", msg, SMIMESignedGenerator.RFC3851_MICALGS); SMIMESigned s = new SMIMESigned(smm); assertEquals("md5", getMicAlg(smm)); assertEquals(getDigestOid(s.getSignerInfos()), PKCSObjectIdentifiers.md5.toString()); verifyMessageBytes(msg, s.getContent()); verifySigners(s.getCertificates(), s.getSignerInfos()); } public void testSHA224WithRSA() throws Exception { MimeMultipart smm = generateMultiPartRsa("SHA224withRSA", msg, SMIMESignedGenerator.STANDARD_MICALGS); SMIMESigned s = new SMIMESigned(smm); assertEquals("sha-224", getMicAlg(smm)); assertEquals(getDigestOid(s.getSignerInfos()), NISTObjectIdentifiers.id_sha224.toString()); verifyMessageBytes(msg, s.getContent()); verifySigners(s.getCertificates(), s.getSignerInfos()); } public void testSHA224WithRSARfc3851() throws Exception { MimeMultipart smm = generateMultiPartRsa("SHA224withRSA", msg, SMIMESignedGenerator.RFC3851_MICALGS); SMIMESigned s = new SMIMESigned(smm); assertEquals("sha224", getMicAlg(smm)); assertEquals(getDigestOid(s.getSignerInfos()), NISTObjectIdentifiers.id_sha224.toString()); verifyMessageBytes(msg, s.getContent()); verifySigners(s.getCertificates(), s.getSignerInfos()); } public void testSHA256WithRSA() throws Exception { MimeMultipart smm = generateMultiPartRsa("SHA256withRSA", msg, SMIMESignedGenerator.STANDARD_MICALGS); SMIMESigned s = new SMIMESigned(smm); assertEquals("sha-256", getMicAlg(smm)); assertEquals(getDigestOid(s.getSignerInfos()), NISTObjectIdentifiers.id_sha256.toString()); verifyMessageBytes(msg, s.getContent()); verifySigners(s.getCertificates(), s.getSignerInfos()); } public void testSHA256WithRSARfc3851() throws Exception { MimeMultipart smm = generateMultiPartRsa("SHA256withRSA", msg, SMIMESignedGenerator.RFC3851_MICALGS); SMIMESigned s = new SMIMESigned(smm); assertEquals("sha256", getMicAlg(smm)); assertEquals(getDigestOid(s.getSignerInfos()), NISTObjectIdentifiers.id_sha256.toString()); verifyMessageBytes(msg, s.getContent()); verifySigners(s.getCertificates(), s.getSignerInfos()); } public void testSHA384WithRSA() throws Exception { MimeMultipart smm = generateMultiPartRsa("SHA384withRSA", msg, SMIMESignedGenerator.STANDARD_MICALGS); SMIMESigned s = new SMIMESigned(smm); assertEquals("sha-384", getMicAlg(smm)); assertEquals(getDigestOid(s.getSignerInfos()), NISTObjectIdentifiers.id_sha384.toString()); verifyMessageBytes(msg, s.getContent()); verifySigners(s.getCertificates(), s.getSignerInfos()); } public void testSHA384WithRSARfc3851() throws Exception { MimeMultipart smm = generateMultiPartRsa("SHA384withRSA", msg, SMIMESignedGenerator.RFC3851_MICALGS); SMIMESigned s = new SMIMESigned(smm); assertEquals("sha384", getMicAlg(smm)); assertEquals(getDigestOid(s.getSignerInfos()), NISTObjectIdentifiers.id_sha384.toString()); verifyMessageBytes(msg, s.getContent()); verifySigners(s.getCertificates(), s.getSignerInfos()); } public void testSHA512WithRSA() throws Exception { MimeMultipart smm = generateMultiPartRsa("SHA512withRSA", msg, SMIMESignedGenerator.STANDARD_MICALGS); SMIMESigned s = new SMIMESigned(smm); assertEquals("sha-512", getMicAlg(smm)); assertEquals(getDigestOid(s.getSignerInfos()), NISTObjectIdentifiers.id_sha512.toString()); verifyMessageBytes(msg, s.getContent()); verifySigners(s.getCertificates(), s.getSignerInfos()); } public void testSHA512WithRSARfc3851() throws Exception { MimeMultipart smm = generateMultiPartRsa("SHA512withRSA", msg, SMIMESignedGenerator.RFC3851_MICALGS); SMIMESigned s = new SMIMESigned(smm); assertEquals("sha512", getMicAlg(smm)); assertEquals(getDigestOid(s.getSignerInfos()), NISTObjectIdentifiers.id_sha512.toString()); verifyMessageBytes(msg, s.getContent()); verifySigners(s.getCertificates(), s.getSignerInfos()); } public void testRIPEMD160WithRSA() throws Exception { MimeMultipart smm = generateMultiPartRsa("RIPEMD160withRSA", msg, SMIMESignedGenerator.RFC3851_MICALGS); SMIMESigned s = new SMIMESigned(smm); assertEquals("unknown", getMicAlg(smm)); assertEquals(getDigestOid(s.getSignerInfos()), TeleTrusTObjectIdentifiers.ripemd160.toString()); verifyMessageBytes(msg, s.getContent()); verifySigners(s.getCertificates(), s.getSignerInfos()); } public void testGOST3411WithGOST3410() throws Exception { MimeMultipart smm = generateMultiPartGost(msg); SMIMESigned s = new SMIMESigned(smm); assertEquals("gostr3411-94", getMicAlg(smm)); assertEquals(getDigestOid(s.getSignerInfos()), CryptoProObjectIdentifiers.gostR3411.getId()); verifyMessageBytes(msg, s.getContent()); verifySigners(s.getCertificates(), s.getSignerInfos()); } public void testGOST3411WithECGOST3410() throws Exception { MimeMultipart smm = generateMultiPartECGost(msg); SMIMESigned s = new SMIMESigned(smm); assertEquals("gostr3411-94", getMicAlg(smm)); assertEquals(getDigestOid(s.getSignerInfos()), CryptoProObjectIdentifiers.gostR3411.getId()); verifyMessageBytes(msg, s.getContent()); verifySigners(s.getCertificates(), s.getSignerInfos()); } public void testSHA224WithRSAParser() throws Exception { MimeMultipart smm = generateMultiPartRsa("SHA224withRSA", msg, SMIMESignedGenerator.RFC3851_MICALGS); SMIMESignedParser s = new SMIMESignedParser(new JcaDigestCalculatorProviderBuilder().setProvider(BC).build(), smm); Store certs = s.getCertificates(); assertEquals(getDigestOid(s.getSignerInfos()), NISTObjectIdentifiers.id_sha224.toString()); verifyMessageBytes(msg, s.getContent()); verifySigners(certs, s.getSignerInfos()); } public void testSHA224WithRSAParserEncryptedWithDES() throws Exception { List certList = new ArrayList(); certList.add(_signCert); certList.add(_origCert); Store certs = new JcaCertStore(certList); ASN1EncodableVector signedAttrs = generateSignedAttributes(); SMIMESignedGenerator gen = new SMIMESignedGenerator(); gen.addSignerInfoGenerator(new JcaSimpleSignerInfoGeneratorBuilder().setProvider(BC).setSignedAttributeGenerator(new DefaultSignedAttributeTableGenerator(new AttributeTable(signedAttrs))).build("SHA224withRSA", _signKP.getPrivate(), _signCert)); gen.addCertificates(certs); MimeMultipart smm = gen.generate(msg); SMIMESignedParser s = new SMIMESignedParser(new JcaDigestCalculatorProviderBuilder().setProvider(BC).build(), smm); certs = s.getCertificates(); assertEquals(getDigestOid(s.getSignerInfos()), NISTObjectIdentifiers.id_sha224.toString()); verifyMessageBytes(msg, s.getContent()); verifySigners(certs, s.getSignerInfos()); } public void testSHA1withDSA() throws Exception { dsaSignKP = CMSTestUtil.makeDsaKeyPair(); dsaSignCert = CMSTestUtil.makeCertificate(dsaSignKP, _origDN, dsaSignKP, _origDN); dsaOrigKP = CMSTestUtil.makeDsaKeyPair(); dsaOrigCert = CMSTestUtil.makeCertificate(dsaOrigKP, _signDN, dsaSignKP, _origDN); List certList = new ArrayList(); certList.add(dsaOrigCert); certList.add(dsaSignCert); Store certs = new JcaCertStore(certList); SMIMESignedGenerator gen = new SMIMESignedGenerator(); gen.addSignerInfoGenerator(new JcaSimpleSignerInfoGeneratorBuilder().setProvider("BC").build("SHA1withDSA", dsaOrigKP.getPrivate(), dsaOrigCert)); gen.addCertificates(certs); MimeMultipart smm = gen.generate(msg); SMIMESigned s = new SMIMESigned(smm); verifyMessageBytes(msg, s.getContent()); verifySigners(s.getCertificates(), s.getSignerInfos()); } public void testSHA256WithRSABinary() throws Exception { MimeBodyPart msg = generateBinaryPart(); MimeMultipart smm = generateMultiPartRsa("SHA256withRSA", msg, SMIMESignedGenerator.RFC3851_MICALGS); SMIMESigned s = new SMIMESigned(smm); verifyMessageBytes(msg, s.getContent()); verifySigners(s.getCertificates(), s.getSignerInfos()); } public void testSHA256WithRSABinaryWithParser() throws Exception { MimeBodyPart msg = generateBinaryPart(); MimeMultipart smm = generateMultiPartRsa("SHA256withRSA", msg, SMIMESignedGenerator.RFC3851_MICALGS); SMIMESignedParser s = new SMIMESignedParser(new JcaDigestCalculatorProviderBuilder().setProvider(BC).build(), smm); verifyMessageBytes(msg, s.getContent()); verifySigners(s.getCertificates(), s.getSignerInfos()); } public void testWithAttributeCertificate() throws Exception { List certList = new ArrayList(); certList.add(_signCert); certList.add(_origCert); Store certs = new JcaCertStore(certList); ASN1EncodableVector signedAttrs = generateSignedAttributes(); SMIMESignedGenerator gen = new SMIMESignedGenerator(); gen.addSignerInfoGenerator(new JcaSimpleSignerInfoGeneratorBuilder().setProvider(BC).setSignedAttributeGenerator(new DefaultSignedAttributeTableGenerator(new AttributeTable(signedAttrs))).build("SHA256withRSA", _signKP.getPrivate(), _signCert)); gen.addCertificates(certs); X509AttributeCertificate attrCert = CMSTestUtil.getAttributeCertificate(); Store store = new JcaAttrCertStore(attrCert); gen.addAttributeCertificates(store); SMIMESigned s = new SMIMESigned(gen.generateEncapsulated(msg)); verifyMessageBytes(msg, s.getContent()); verifySigners(s.getCertificates(), s.getSignerInfos()); Store attrCerts = s.getAttributeCertificates(); assertTrue(attrCerts.getMatches(null).contains(new JcaX509AttributeCertificateHolder(attrCert))); } private void rsaPSSTest(String digest, String digestOID) throws Exception { MimeMultipart smm = generateMultiPartRsaPSS(digest, msg, null); SMIMESignedParser s = new SMIMESignedParser(new JcaDigestCalculatorProviderBuilder().setProvider(BC).build(), smm); Store certs = s.getCertificates(); assertEquals(getDigestOid(s.getSignerInfos()), digestOID); verifyMessageBytes(msg, s.getContent()); verifySigners(certs, s.getSignerInfos()); } private MimeBodyPart generateBinaryPart() throws MessagingException { byte[] content = new byte[] { 1, 2, 3, 4, 5, 6, 7, 8, 9, 0, 10, 11, 12, 13, 14, 10, 10, 15, 16 }; InternetHeaders ih = new InternetHeaders(); ih.setHeader("Content-Transfer-Encoding", "binary"); return new MimeBodyPart(ih, content); } private MimeMultipart generateMultiPartRsa( String algorithm, MimeBodyPart msg, Date signingTime, Map micalgs) throws Exception { List certList = new ArrayList(); certList.add(_signCert); certList.add(_origCert); Store certs = new JcaCertStore(certList); ASN1EncodableVector signedAttrs = generateSignedAttributes(); if (signingTime != null) { signedAttrs.add(new Attribute(CMSAttributes.signingTime, new DERSet(new Time(signingTime)))); } SMIMESignedGenerator gen = new SMIMESignedGenerator(micalgs); gen.addSignerInfoGenerator(new JcaSimpleSignerInfoGeneratorBuilder().setProvider(BC).setSignedAttributeGenerator(new DefaultSignedAttributeTableGenerator(new AttributeTable(signedAttrs))).build(algorithm, _signKP.getPrivate(), _signCert)); gen.addCertificates(certs); return gen.generate(msg); } private MimeMultipart generateMultiPartRsaPSS( String digest, MimeBodyPart msg, Date signingTime) throws Exception { List certList = new ArrayList(); certList.add(_signCert); certList.add(_origCert); Store certs = new JcaCertStore(certList); ASN1EncodableVector signedAttrs = generateSignedAttributes(); if (signingTime != null) { signedAttrs.add(new Attribute(CMSAttributes.signingTime, new DERSet(new Time(signingTime)))); } SMIMESignedGenerator gen = new SMIMESignedGenerator(); gen.addSignerInfoGenerator(new JcaSimpleSignerInfoGeneratorBuilder().setProvider(BC).setSignedAttributeGenerator(new AttributeTable(signedAttrs)).build(digest + "withRSAandMGF1", _signKP.getPrivate(), _signCert)); gen.addCertificates(certs); return gen.generate(msg); } private MimeMultipart generateMultiPartGost( MimeBodyPart msg) throws Exception { List certList = new ArrayList(); certList.add(_signCert); certList.add(_signGostCert); Store certs = new JcaCertStore(certList); SMIMESignedGenerator gen = new SMIMESignedGenerator(); gen.addSignerInfoGenerator(new JcaSimpleSignerInfoGeneratorBuilder().setProvider(BC).build("GOST3411withGOST3410", _signGostKP.getPrivate(), _signGostCert)); gen.addCertificates(certs); return gen.generate(msg); } private MimeMultipart generateMultiPartECGost( MimeBodyPart msg) throws Exception { List certList = new ArrayList(); certList.add(_signCert); certList.add(_signEcGostCert); Store certs = new JcaCertStore(certList); SMIMESignedGenerator gen = new SMIMESignedGenerator(); gen.addSignerInfoGenerator(new JcaSimpleSignerInfoGeneratorBuilder().setProvider(BC).build("GOST3411withECGOST3410", _signEcGostKP.getPrivate(), _signEcGostCert)); gen.addCertificates(certs); return gen.generate(msg); } private MimeMultipart generateMultiPartRsa(String algorithm, MimeBodyPart msg, Map micalgs) throws Exception { return generateMultiPartRsa(algorithm, msg, null, micalgs); } private MimeBodyPart generateEncapsulatedRsa(String sigAlg, MimeBodyPart msg) throws Exception { List certList = new ArrayList(); certList.add(_signCert); certList.add(_origCert); Store certs = new JcaCertStore(certList); ASN1EncodableVector signedAttrs = generateSignedAttributes(); SMIMESignedGenerator gen = new SMIMESignedGenerator(); gen.addSignerInfoGenerator(new JcaSimpleSignerInfoGeneratorBuilder().setProvider(BC).setSignedAttributeGenerator(new AttributeTable(signedAttrs)).build(sigAlg, _signKP.getPrivate(), _signCert)); gen.addCertificates(certs); return gen.generateEncapsulated(msg); } public void testCertificateManagement() throws Exception { List certList = new ArrayList(); certList.add(_signCert); certList.add(_origCert); Store certs = new JcaCertStore(certList); SMIMESignedGenerator gen = new SMIMESignedGenerator(); gen.addCertificates(certs); MimeBodyPart smm = gen.generateCertificateManagement(); SMIMESigned s = new SMIMESigned(smm); certs = s.getCertificates(); assertEquals(2, certs.getMatches(null).size()); } public void testMimeMultipart() throws Exception { MimeBodyPart m = createMultipartMessage(); List certList = new ArrayList(); certList.add(_signCert); certList.add(_origCert); Store certs = new JcaCertStore(certList); ASN1EncodableVector signedAttrs = generateSignedAttributes(); SMIMESignedGenerator gen = new SMIMESignedGenerator("binary"); gen.addSignerInfoGenerator(new JcaSimpleSignerInfoGeneratorBuilder().setProvider(BC).setSignedAttributeGenerator(new AttributeTable(signedAttrs)).build("SHA1withRSA", _signKP.getPrivate(), _signCert)); gen.addCertificates(certs); MimeMultipart mm = gen.generate(m); SMIMESigned s = new SMIMESigned(mm); verifySigners(s.getCertificates(), s.getSignerInfos()); byte[] contentDigest = (byte[])gen.getGeneratedDigests().get(SMIMESignedGenerator.DIGEST_SHA1); AttributeTable table = ((SignerInformation)s.getSignerInfos().getSigners().iterator().next()).getSignedAttributes(); Attribute hash = table.get(CMSAttributes.messageDigest); assertTrue(MessageDigest.isEqual(contentDigest, ((ASN1OctetString)hash.getAttrValues().getObjectAt(0)).getOctets())); } public void testMimeMultipartBinaryReader() throws Exception { MimeBodyPart m = createMultipartMessage(); List certList = new ArrayList(); certList.add(_signCert); certList.add(_origCert); Store certs = new JcaCertStore(certList); ASN1EncodableVector signedAttrs = generateSignedAttributes(); SMIMESignedGenerator gen = new SMIMESignedGenerator("binary"); gen.addSignerInfoGenerator(new JcaSimpleSignerInfoGeneratorBuilder().setProvider(BC).setSignedAttributeGenerator(new AttributeTable(signedAttrs)).build("SHA1withRSA", _signKP.getPrivate(), _signCert)); gen.addCertificates(certs); MimeMultipart mm = gen.generate(m); SMIMESigned s = new SMIMESigned(mm, "binary"); verifySigners(s.getCertificates(), s.getSignerInfos()); } public void testMimeMultipartBinaryParser() throws Exception { MimeBodyPart m = createMultipartMessage(); List certList = new ArrayList(); certList.add(_signCert); certList.add(_origCert); Store certs = new JcaCertStore(certList); ASN1EncodableVector signedAttrs = generateSignedAttributes(); SMIMESignedGenerator gen = new SMIMESignedGenerator("binary"); gen.addSignerInfoGenerator(new JcaSimpleSignerInfoGeneratorBuilder().setProvider(BC).setSignedAttributeGenerator(new AttributeTable(signedAttrs)).build("SHA1withRSA", _signKP.getPrivate(), _signCert)); gen.addCertificates(certs); MimeMultipart mm = gen.generate(m); SMIMESignedParser s = new SMIMESignedParser(new JcaDigestCalculatorProviderBuilder().setProvider(BC).build(), mm, "binary"); verifySigners(s.getCertificates(), s.getSignerInfos()); } public void testMimeMultipartBinaryParserGetMimeContent() throws Exception { MimeBodyPart m = createMultipartMessage(); List certList = new ArrayList(); certList.add(_signCert); certList.add(_origCert); Store certs = new JcaCertStore(certList); ASN1EncodableVector signedAttrs = generateSignedAttributes(); SMIMESignedGenerator gen = new SMIMESignedGenerator("binary"); gen.addSignerInfoGenerator(new JcaSimpleSignerInfoGeneratorBuilder().setProvider(BC).setSignedAttributeGenerator(new AttributeTable(signedAttrs)).build("SHA1withRSA", _signKP.getPrivate(), _signCert)); gen.addCertificates(certs); MimeMultipart mm = gen.generate(m); SMIMESignedParser s = new SMIMESignedParser(new JcaDigestCalculatorProviderBuilder().setProvider(BC).build(), mm, "binary"); verifySigners(s.getCertificates(), s.getSignerInfos()); MimeMessage bp = s.getContentAsMimeMessage(Session.getDefaultInstance(new Properties())); } private MimeBodyPart createMultipartMessage() throws MessagingException { MimeBodyPart msg1 = new MimeBodyPart(); msg1.setText("Hello part 1!\n"); MimeBodyPart msg2 = new MimeBodyPart(); msg2.setText("Hello part 2!\n"); MimeMultipart mp = new MimeMultipart(); mp.addBodyPart(msg1); mp.addBodyPart(msg2); MimeBodyPart m = new MimeBodyPart(); m.setContent(mp); return m; } public void testQuotable() throws Exception { MimeMessage message = loadMessage("quotable.message"); SMIMESigned s = new SMIMESigned((MimeMultipart)message.getContent()); verifySigners(s.getCertificates(), s.getSignerInfos()); } public void testQuotableParser() throws Exception { MimeMessage message = loadMessage("quotable.message"); SMIMESignedParser s = new SMIMESignedParser(new JcaDigestCalculatorProviderBuilder().setProvider(BC).build(), (MimeMultipart)message.getContent()); verifySigners(s.getCertificates(), s.getSignerInfos()); } public void testEmbeddedMulti() throws Exception { MimeMessage message = loadMessage("embeddedmulti.message"); SMIMESigned s = new SMIMESigned((MimeMultipart)message.getContent()); verifySigners(s.getCertificates(), s.getSignerInfos()); } public void testEmbeddedMultiParser() throws Exception { MimeMessage message = loadMessage("embeddedmulti.message"); SMIMESignedParser s = new SMIMESignedParser(new JcaDigestCalculatorProviderBuilder().setProvider(BC).build(), (MimeMultipart)message.getContent()); verifySigners(s.getCertificates(), s.getSignerInfos()); } public void testMultiAlternative() throws Exception { MimeMessage message = loadMessage("multi-alternative.eml"); SMIMESigned s = new SMIMESigned((MimeMultipart)message.getContent()); verifySigners(s.getCertificates(), s.getSignerInfos()); } public void testExtraNlInPostamble() throws Exception { MimeMessage message = loadMessage("extra-nl.eml"); SMIMESigned s = new SMIMESigned((MimeMultipart)message.getContent()); verifySigners(s.getCertificates(), s.getSignerInfos()); } public void testSignAttachmentOnly() throws Exception { MimeMessage m = loadMessage("attachonly.eml"); List certList = new ArrayList(); certList.add(_signCert); certList.add(_origCert); Store certs = new JcaCertStore(certList); ASN1EncodableVector signedAttrs = generateSignedAttributes(); SMIMESignedGenerator gen = new SMIMESignedGenerator("binary"); gen.addSignerInfoGenerator(new JcaSimpleSignerInfoGeneratorBuilder().setProvider(BC).setSignedAttributeGenerator(new AttributeTable(signedAttrs)).build("SHA1withRSA", _signKP.getPrivate(), _signCert)); gen.addCertificates(certs); MimeMultipart mm = gen.generate(m, BC); SMIMESigned s = new SMIMESigned(mm); verifySigners(s.getCertificates(), s.getSignerInfos()); SMIMESignedParser sp = new SMIMESignedParser(new JcaDigestCalculatorProviderBuilder().setProvider(BC).build(), mm); verifySigners(sp.getCertificates(), sp.getSignerInfos()); } public void testMultiAlternativeParser() throws Exception { MimeMessage message = loadMessage("multi-alternative.eml"); SMIMESignedParser s = new SMIMESignedParser(new JcaDigestCalculatorProviderBuilder().setProvider(BC).build(), (MimeMultipart)message.getContent()); verifySigners(s.getCertificates(), s.getSignerInfos()); } public void testBasicAS2() throws Exception { MimeMessage message = loadMessage("basicAS2.message"); SMIMESigned s = new SMIMESigned((MimeMultipart)message.getContent()); verifySigners(s.getCertificates(), s.getSignerInfos()); } public void testBasicAS2Parser() throws Exception { MimeMessage message = loadMessage("basicAS2.message"); SMIMESignedParser s = new SMIMESignedParser(new JcaDigestCalculatorProviderBuilder().setProvider(BC).build(), (MimeMultipart)message.getContent()); verifySigners(s.getCertificates(), s.getSignerInfos()); } public void testRawAS2Parser() throws Exception { MimeMessage message = loadMessage("rawAS2.message"); SMIMESignedParser s = new SMIMESignedParser(new JcaDigestCalculatorProviderBuilder().setProvider(BC).build(), (MimeMultipart)message.getContent()); verifySigners(s.getCertificates(), s.getSignerInfos()); } private String getDigestOid(SignerInformationStore s) { return ((SignerInformation)s.getSigners().iterator().next()).getDigestAlgOID(); } private void verifySigners(Store certs, SignerInformationStore signers) throws Exception { Collection c = signers.getSigners(); Iterator it = c.iterator(); while (it.hasNext()) { SignerInformation signer = (SignerInformation)it.next(); Collection certCollection = certs.getMatches(signer.getSID()); Iterator certIt = certCollection.iterator(); X509CertificateHolder certHolder = (X509CertificateHolder)certIt.next(); assertEquals(true, signer.verify(new JcaSimpleSignerInfoVerifierBuilder().build(certHolder))); } } private void verifyMessageBytes(MimeBodyPart a, MimeBodyPart b) throws Exception { ByteArrayOutputStream bOut1 = new ByteArrayOutputStream(); a.writeTo(bOut1); bOut1.close(); ByteArrayOutputStream bOut2 = new ByteArrayOutputStream(); b.writeTo(bOut2); bOut2.close(); assertEquals(true, Arrays.equals(bOut1.toByteArray(), bOut2.toByteArray())); } private ASN1EncodableVector generateSignedAttributes() { ASN1EncodableVector signedAttrs = new ASN1EncodableVector(); SMIMECapabilityVector caps = new SMIMECapabilityVector(); caps.addCapability(SMIMECapability.dES_EDE3_CBC); caps.addCapability(SMIMECapability.rC2_CBC, 128); caps.addCapability(SMIMECapability.dES_CBC); signedAttrs.add(new SMIMECapabilitiesAttribute(caps)); return signedAttrs; } private MimeMessage loadMessage(String name) throws MessagingException, FileNotFoundException { Session session = Session.getDefaultInstance(System.getProperties(), null); return new MimeMessage(session, getClass().getResourceAsStream(name)); } private MimeBodyPart createTemplate(String contentType, String contentTransferEncoding) throws UnsupportedEncodingException, MessagingException { byte[] content = "\n\n \n\n\n".getBytes("US-ASCII"); InternetHeaders ih = new InternetHeaders(); ih.setHeader("Content-Type", contentType); ih.setHeader("Content-Transfer-Encoding", contentTransferEncoding); return new MimeBodyPart(ih, content); } private String getMicAlg(MimeMultipart mm) { String contentType = mm.getContentType(); String micAlg = contentType.substring(contentType.indexOf("micalg=") + 7); return micAlg.substring(0, micAlg.indexOf(';')); } } bouncycastle-1.49.orig/test/src/org/bouncycastle/mail/smime/test/SMIMEMiscTest.java0000644000175000017500000003004111726245377027701 0ustar ebourgebourgpackage org.bouncycastle.mail.smime.test; import java.io.ByteArrayOutputStream; import java.io.File; import java.io.FileInputStream; import java.io.FileOutputStream; import java.security.KeyPair; import java.security.Security; import java.security.cert.CertStore; import java.security.cert.CollectionCertStoreParameters; import java.security.cert.X509Certificate; import java.util.ArrayList; import java.util.Arrays; import java.util.Collection; import java.util.Iterator; import java.util.List; import java.util.Properties; import javax.mail.Address; import javax.mail.Message; import javax.mail.Session; import javax.mail.internet.InternetAddress; import javax.mail.internet.MimeBodyPart; import javax.mail.internet.MimeMessage; import javax.mail.internet.MimeMultipart; import junit.framework.Test; import junit.framework.TestCase; import junit.framework.TestSuite; import org.bouncycastle.asn1.ASN1EncodableVector; import org.bouncycastle.asn1.cms.AttributeTable; import org.bouncycastle.asn1.smime.SMIMECapabilitiesAttribute; import org.bouncycastle.asn1.smime.SMIMECapability; import org.bouncycastle.asn1.smime.SMIMECapabilityVector; import org.bouncycastle.cms.CMSException; import org.bouncycastle.cms.RecipientInformation; import org.bouncycastle.cms.SignerInformation; import org.bouncycastle.cms.SignerInformationStore; import org.bouncycastle.cms.jcajce.JcaX509CertSelectorConverter; import org.bouncycastle.cms.test.CMSTestUtil; import org.bouncycastle.jce.provider.BouncyCastleProvider; import org.bouncycastle.mail.smime.SMIMECompressedGenerator; import org.bouncycastle.mail.smime.SMIMEEnveloped; import org.bouncycastle.mail.smime.SMIMEEnvelopedGenerator; import org.bouncycastle.mail.smime.SMIMESigned; import org.bouncycastle.mail.smime.SMIMESignedGenerator; import org.bouncycastle.mail.smime.SMIMESignedParser; import org.bouncycastle.mail.smime.SMIMEUtil; import org.bouncycastle.mail.smime.util.FileBackedMimeBodyPart; public class SMIMEMiscTest extends TestCase { static MimeBodyPart msg; static String signDN; static KeyPair signKP; static X509Certificate signCert; static String origDN; static KeyPair origKP; static X509Certificate origCert; static String reciDN; static KeyPair reciKP; static X509Certificate reciCert; private static final JcaX509CertSelectorConverter selectorConverter = new JcaX509CertSelectorConverter(); KeyPair dsaSignKP; X509Certificate dsaSignCert; KeyPair dsaOrigKP; X509Certificate dsaOrigCert; static { try { msg = SMIMETestUtil.makeMimeBodyPart("Hello world!\n"); signDN = "O=Bouncy Castle, C=AU"; signKP = CMSTestUtil.makeKeyPair(); signCert = CMSTestUtil.makeCertificate(signKP, signDN, signKP, signDN); origDN = "CN=Eric H. Echidna, E=eric@bouncycastle.org, O=Bouncy Castle, C=AU"; origKP = CMSTestUtil.makeKeyPair(); origCert = CMSTestUtil.makeCertificate(origKP, origDN, signKP, signDN); } catch (Exception e) { throw new RuntimeException("problem setting up signed test class: " + e); } } /* * * INFRASTRUCTURE * */ public SMIMEMiscTest(String name) { super(name); } public static void main(String args[]) { Security.addProvider(new BouncyCastleProvider()); junit.textui.TestRunner.run(SMIMEMiscTest.class); } public static Test suite() { return new SMIMETestSetup(new TestSuite(SMIMEMiscTest.class)); } public void testSHA256WithRSAParserEncryptedWithAES() throws Exception { List certList = new ArrayList(); certList.add(origCert); certList.add(signCert); CertStore certs = CertStore.getInstance("Collection", new CollectionCertStoreParameters(certList), "BC"); SMIMEEnvelopedGenerator encGen = new SMIMEEnvelopedGenerator(); encGen.addKeyTransRecipient(origCert); MimeBodyPart mp = encGen.generate(msg, SMIMEEnvelopedGenerator.AES128_CBC, "BC"); ASN1EncodableVector signedAttrs = generateSignedAttributes(); SMIMESignedGenerator gen = new SMIMESignedGenerator(); gen.addSigner(origKP.getPrivate(), origCert, SMIMESignedGenerator.DIGEST_SHA256, new AttributeTable(signedAttrs), null); gen.addCertificatesAndCRLs(certs); MimeMultipart smm = gen.generate(mp, "BC"); File tmpFile = File.createTempFile("bcTest", ".mime"); MimeMessage msg = createMimeMessage(tmpFile, smm); SMIMESignedParser s = new SMIMESignedParser((MimeMultipart)msg.getContent()); certs = s.getCertificatesAndCRLs("Collection", "BC"); verifyMessageBytes(mp, s.getContent()); verifySigners(certs, s.getSignerInfos()); tmpFile.delete(); } public void testSHA256WithRSACompressed() throws Exception { List certList = new ArrayList(); certList.add(origCert); certList.add(signCert); CertStore certs = CertStore.getInstance("Collection", new CollectionCertStoreParameters(certList), "BC"); SMIMECompressedGenerator cGen = new SMIMECompressedGenerator(); MimeBodyPart mp = cGen.generate(msg, SMIMECompressedGenerator.ZLIB); ASN1EncodableVector signedAttrs = generateSignedAttributes(); SMIMESignedGenerator gen = new SMIMESignedGenerator(); gen.addSigner(origKP.getPrivate(), origCert, SMIMESignedGenerator.DIGEST_SHA256, new AttributeTable(signedAttrs), null); gen.addCertificatesAndCRLs(certs); MimeMultipart smm = gen.generate(mp, "BC"); File tmpFile = File.createTempFile("bcTest", ".mime"); MimeMessage msg = createMimeMessage(tmpFile, smm); SMIMESigned s = new SMIMESigned((MimeMultipart)msg.getContent()); certs = s.getCertificatesAndCRLs("Collection", "BC"); verifyMessageBytes(mp, s.getContent()); verifySigners(certs, s.getSignerInfos()); tmpFile.delete(); } public void testQuotePrintableSigPreservation() throws Exception { MimeMessage msg = new MimeMessage((Session)null, getClass().getResourceAsStream("qp-soft-break.eml")); SMIMEEnvelopedGenerator encGen = new SMIMEEnvelopedGenerator(); encGen.addKeyTransRecipient(origCert); MimeBodyPart mp = encGen.generate(msg, SMIMEEnvelopedGenerator.AES128_CBC, "BC"); SMIMEEnveloped env = new SMIMEEnveloped(mp); RecipientInformation ri = (RecipientInformation)env.getRecipientInfos().getRecipients().iterator().next(); MimeBodyPart mm = SMIMEUtil.toMimeBodyPart(ri.getContentStream(origKP.getPrivate(), "BC")); SMIMESigned s = new SMIMESigned((MimeMultipart)mm.getContent()); Collection c = s.getSignerInfos().getSigners(); Iterator it = c.iterator(); CertStore certs = s.getCertificatesAndCRLs("Collection", "BC"); while (it.hasNext()) { SignerInformation signer = (SignerInformation)it.next(); Collection certCollection = certs.getCertificates(selectorConverter.getCertSelector(signer.getSID())); Iterator certIt = certCollection.iterator(); X509Certificate cert = (X509Certificate)certIt.next(); assertEquals(true, signer.verify(cert, "BC")); } ((FileBackedMimeBodyPart)mm).dispose(); } public void testSHA256WithRSAParserCompressed() throws Exception { List certList = new ArrayList(); certList.add(origCert); certList.add(signCert); CertStore certs = CertStore.getInstance("Collection", new CollectionCertStoreParameters(certList), "BC"); SMIMECompressedGenerator cGen = new SMIMECompressedGenerator(); MimeBodyPart mp = cGen.generate(msg, SMIMECompressedGenerator.ZLIB); ASN1EncodableVector signedAttrs = generateSignedAttributes(); SMIMESignedGenerator gen = new SMIMESignedGenerator(); gen.addSigner(origKP.getPrivate(), origCert, SMIMESignedGenerator.DIGEST_SHA256, new AttributeTable(signedAttrs), null); gen.addCertificatesAndCRLs(certs); MimeMultipart smm = gen.generate(mp, "BC"); File tmpFile = File.createTempFile("bcTest", ".mime"); MimeMessage msg = createMimeMessage(tmpFile, smm); SMIMESignedParser s = new SMIMESignedParser((MimeMultipart)msg.getContent()); certs = s.getCertificatesAndCRLs("Collection", "BC"); verifyMessageBytes(mp, s.getContent()); verifySigners(certs, s.getSignerInfos()); tmpFile.delete(); } public void testBrokenEnvelope() throws Exception { Session session = Session.getDefaultInstance(System.getProperties(), null); MimeMessage msg = new MimeMessage(session, getClass().getResourceAsStream("brokenEnv.message")); try { new SMIMEEnveloped(msg); } catch (CMSException e) { if (!e.getMessage().equals("Malformed content.")) { fail("wrong exception on bogus envelope"); } } } private void verifySigners(CertStore certs, SignerInformationStore signers) throws Exception { Collection c = signers.getSigners(); Iterator it = c.iterator(); while (it.hasNext()) { SignerInformation signer = (SignerInformation)it.next(); Collection certCollection = certs.getCertificates(selectorConverter.getCertSelector(signer.getSID())); Iterator certIt = certCollection.iterator(); X509Certificate cert = (X509Certificate)certIt.next(); assertEquals(true, signer.verify(cert, "BC")); } } private void verifyMessageBytes(MimeBodyPart a, MimeBodyPart b) throws Exception { ByteArrayOutputStream bOut1 = new ByteArrayOutputStream(); a.writeTo(bOut1); bOut1.close(); ByteArrayOutputStream bOut2 = new ByteArrayOutputStream(); b.writeTo(bOut2); bOut2.close(); assertEquals(true, Arrays.equals(bOut1.toByteArray(), bOut2.toByteArray())); } /** * Create a mime message representing the multipart. We need to do * this as otherwise no raw content stream for the message will exist. */ private MimeMessage createMimeMessage(File tmpFile, MimeMultipart smm) throws Exception { FileOutputStream fOut = new FileOutputStream(tmpFile); Properties props = System.getProperties(); Session session = Session.getDefaultInstance(props, null); Address fromUser = new InternetAddress("\"Eric H. Echidna\""); Address toUser = new InternetAddress("example@bouncycastle.org"); MimeMessage body = new MimeMessage(session); body.setFrom(fromUser); body.setRecipient(Message.RecipientType.TO, toUser); body.setSubject("example signed message"); body.setContent(smm, smm.getContentType()); body.saveChanges(); body.writeTo(fOut); fOut.close(); return new MimeMessage(session, new FileInputStream(tmpFile)); } private ASN1EncodableVector generateSignedAttributes() { ASN1EncodableVector signedAttrs = new ASN1EncodableVector(); SMIMECapabilityVector caps = new SMIMECapabilityVector(); caps.addCapability(SMIMECapability.dES_EDE3_CBC); caps.addCapability(SMIMECapability.rC2_CBC, 128); caps.addCapability(SMIMECapability.dES_CBC); signedAttrs.add(new SMIMECapabilitiesAttribute(caps)); return signedAttrs; } } bouncycastle-1.49.orig/test/src/org/bouncycastle/mail/smime/test/NewSMIMEEnvelopedTest.java0000644000175000017500000004352012070676025031376 0ustar ebourgebourgpackage org.bouncycastle.mail.smime.test; import java.io.ByteArrayOutputStream; import java.io.FileNotFoundException; import java.io.IOException; import java.io.InputStreamReader; import java.security.KeyPair; import java.security.MessageDigest; import java.security.NoSuchAlgorithmException; import java.security.PrivateKey; import java.security.cert.CertificateEncodingException; import java.security.cert.CertificateFactory; import java.security.cert.X509Certificate; import java.util.Arrays; import javax.crypto.Cipher; import javax.mail.MessagingException; import javax.mail.Session; import javax.mail.internet.MimeBodyPart; import javax.mail.internet.MimeMessage; import junit.framework.Test; import junit.framework.TestCase; import junit.framework.TestSuite; import org.bouncycastle.asn1.ASN1ObjectIdentifier; import org.bouncycastle.asn1.x509.SubjectPublicKeyInfo; import org.bouncycastle.cms.CMSAlgorithm; import org.bouncycastle.cms.KeyTransRecipientId; import org.bouncycastle.cms.RecipientId; import org.bouncycastle.cms.RecipientInformation; import org.bouncycastle.cms.RecipientInformationStore; import org.bouncycastle.cms.jcajce.JceCMSContentEncryptorBuilder; import org.bouncycastle.cms.jcajce.JceKeyTransEnvelopedRecipient; import org.bouncycastle.cms.jcajce.JceKeyTransRecipientId; import org.bouncycastle.cms.jcajce.JceKeyTransRecipientInfoGenerator; import org.bouncycastle.cms.test.CMSTestUtil; import org.bouncycastle.jce.provider.BouncyCastleProvider; import org.bouncycastle.mail.smime.SMIMEEnveloped; import org.bouncycastle.mail.smime.SMIMEEnvelopedGenerator; import org.bouncycastle.mail.smime.SMIMEEnvelopedParser; import org.bouncycastle.mail.smime.SMIMEUtil; import org.bouncycastle.mail.smime.util.FileBackedMimeBodyPart; import org.bouncycastle.openssl.PEMReader; import org.bouncycastle.util.encoders.Base64; public class NewSMIMEEnvelopedTest extends TestCase { private static final String BC = BouncyCastleProvider.PROVIDER_NAME; private static String _signDN; private static KeyPair _signKP; private static String _reciDN; private static KeyPair _reciKP; private static X509Certificate _reciCert; private static String _reciDN2; private static KeyPair _reciKP2; private static X509Certificate _reciCert2; private static boolean _initialised = false; private static final byte[] testMessage = Base64.decode( "TUlNRS1WZXJzaW9uOiAxLjANCkNvbnRlbnQtVHlwZTogbXVsdGlwYXJ0L21peGVkOyANCglib3VuZGFye" + "T0iLS0tLT1fUGFydF8wXzI2MDM5NjM4Ni4xMzUyOTA0NzUwMTMyIg0KQ29udGVudC1MYW5ndWFnZTogZW" + "4NCkNvbnRlbnQtRGVzY3JpcHRpb246IEEgbWFpbCBmb2xsb3dpbmcgdGhlIERJUkVDVCBwcm9qZWN0IHN" + "wZWNpZmljYXRpb25zDQoNCi0tLS0tLT1fUGFydF8wXzI2MDM5NjM4Ni4xMzUyOTA0NzUwMTMyDQpDb250" + "ZW50LVR5cGU6IHRleHQvcGxhaW47IG5hbWU9bnVsbDsgY2hhcnNldD11cy1hc2NpaQ0KQ29udGVudC1Uc" + "mFuc2Zlci1FbmNvZGluZzogN2JpdA0KQ29udGVudC1EaXNwb3NpdGlvbjogaW5saW5lOyBmaWxlbmFtZT" + "1udWxsDQoNCkNpYW8gZnJvbSB2aWVubmENCi0tLS0tLT1fUGFydF8wXzI2MDM5NjM4Ni4xMzUyOTA0NzU" + "wMTMyLS0NCg=="); private static void init() throws Exception { if (!_initialised) { _initialised = true; _signDN = "O=Bouncy Castle, C=AU"; _signKP = CMSTestUtil.makeKeyPair(); _reciDN = "CN=Doug, OU=Sales, O=Bouncy Castle, C=AU"; _reciKP = CMSTestUtil.makeKeyPair(); _reciCert = CMSTestUtil.makeCertificate(_reciKP, _reciDN, _signKP, _signDN); _reciDN2 = "CN=Fred, OU=Sales, O=Bouncy Castle, C=AU"; _reciKP2 = CMSTestUtil.makeKeyPair(); _reciCert2 = CMSTestUtil.makeCertificate(_reciKP2, _reciDN2, _signKP, _signDN); } } public NewSMIMEEnvelopedTest( String name) { super(name); } public static void main( String args[]) { junit.textui.TestRunner.run(NewSMIMEEnvelopedTest.class); } public static Test suite() throws Exception { return new SMIMETestSetup(new TestSuite(NewSMIMEEnvelopedTest.class)); } public void setUp() throws Exception { init(); } private MimeMessage loadMessage(String name) throws MessagingException, FileNotFoundException { Session session = Session.getDefaultInstance(System.getProperties(), null); return new MimeMessage(session, getClass().getResourceAsStream(name)); } private X509Certificate loadCert(String name) throws Exception { return (X509Certificate)CertificateFactory.getInstance("X.509", BC).generateCertificate(getClass().getResourceAsStream(name)); } private PrivateKey loadKey(String name) throws Exception { return ((KeyPair)(new PEMReader(new InputStreamReader(getClass().getResourceAsStream(name)))).readObject()).getPrivate(); } public void testHeaders() throws Exception { MimeBodyPart msg = SMIMETestUtil.makeMimeBodyPart("WallaWallaWashington"); SMIMEEnvelopedGenerator gen = new SMIMEEnvelopedGenerator(); gen.addRecipientInfoGenerator(new JceKeyTransRecipientInfoGenerator(_reciCert).setProvider(BC)); // // generate a MimeBodyPart object which encapsulates the content // we want encrypted. // MimeBodyPart mp = gen.generate(msg, new JceCMSContentEncryptorBuilder(CMSAlgorithm.DES_EDE3_CBC).setProvider(BC).build()); assertEquals("application/pkcs7-mime; name=\"smime.p7m\"; smime-type=enveloped-data", mp.getHeader("Content-Type")[0]); assertEquals("attachment; filename=\"smime.p7m\"", mp.getHeader("Content-Disposition")[0]); assertEquals("S/MIME Encrypted Message", mp.getHeader("Content-Description")[0]); } public void testDESEDE3Encrypted() throws Exception { MimeBodyPart msg = SMIMETestUtil.makeMimeBodyPart("WallaWallaWashington"); String algorithm = SMIMEEnvelopedGenerator.DES_EDE3_CBC; verifyAlgorithm(algorithm, msg); } public void testParserDESEDE3Encrypted() throws Exception { MimeBodyPart msg = SMIMETestUtil.makeMimeBodyPart("WallaWallaWashington"); String algorithm = SMIMEEnvelopedGenerator.DES_EDE3_CBC; verifyParserAlgorithm(algorithm, msg); } public void testIDEAEncrypted() throws Exception { if (isPresent("IDEA")) { MimeBodyPart msg = SMIMETestUtil.makeMimeBodyPart("WallaWallaWashington"); String algorithm = SMIMEEnvelopedGenerator.IDEA_CBC; verifyAlgorithm(algorithm, msg); } } private boolean isPresent(String algorithm) throws Exception { try { Cipher.getInstance(algorithm, BC); return true; } catch (NoSuchAlgorithmException e) { return false; } } public void testRC2Encrypted() throws Exception { MimeBodyPart msg = SMIMETestUtil.makeMimeBodyPart("WallaWallaWashington"); String algorithm = SMIMEEnvelopedGenerator.RC2_CBC; verifyAlgorithm(algorithm, msg); } public void testCASTEncrypted() throws Exception { MimeBodyPart msg = SMIMETestUtil.makeMimeBodyPart("WallaWallaWashington"); String algorithm = SMIMEEnvelopedGenerator.CAST5_CBC; verifyAlgorithm(algorithm, msg); } public void testAES128Encrypted() throws Exception { MimeBodyPart msg = SMIMETestUtil.makeMimeBodyPart("WallaWallaWashington"); String algorithm = SMIMEEnvelopedGenerator.AES128_CBC; verifyAlgorithm(algorithm, msg); } public void testAES192Encrypted() throws Exception { MimeBodyPart msg = SMIMETestUtil.makeMimeBodyPart("WallaWallaWashington"); String algorithm = SMIMEEnvelopedGenerator.AES192_CBC; verifyAlgorithm(algorithm, msg); } public void testAES256Encrypted() throws Exception { MimeBodyPart msg = SMIMETestUtil.makeMimeBodyPart("WallaWallaWashington"); String algorithm = SMIMEEnvelopedGenerator.AES256_CBC; verifyAlgorithm(algorithm, msg); } public void testSubKeyId() throws Exception { MimeBodyPart msg = SMIMETestUtil.makeMimeBodyPart("WallaWallaWashington"); SMIMEEnvelopedGenerator gen = new SMIMEEnvelopedGenerator(); // // create a subject key id - this has to be done the same way as // it is done in the certificate associated with the private key // MessageDigest dig = MessageDigest.getInstance("SHA1", BC); dig.update(SubjectPublicKeyInfo.getInstance(_reciCert.getPublicKey().getEncoded()).getPublicKeyData().getBytes()); gen.addRecipientInfoGenerator(new JceKeyTransRecipientInfoGenerator(dig.digest(), _reciCert.getPublicKey()).setProvider(BC)); // // generate a MimeBodyPart object which encapsulates the content // we want encrypted. // MimeBodyPart mp = gen.generate(msg, new JceCMSContentEncryptorBuilder(CMSAlgorithm.DES_EDE3_CBC).setProvider(BC).build()); SMIMEEnveloped m = new SMIMEEnveloped(mp); dig.update(SubjectPublicKeyInfo.getInstance(_reciCert.getPublicKey().getEncoded()).getPublicKeyData().getBytes()); RecipientId recId = new KeyTransRecipientId(dig.digest()); RecipientInformationStore recipients = m.getRecipientInfos(); RecipientInformation recipient = recipients.get(recId); MimeBodyPart res = SMIMEUtil.toMimeBodyPart(recipient.getContent(new JceKeyTransEnvelopedRecipient(_reciKP.getPrivate()).setProvider(BC))); verifyMessageBytes(msg, res); } public void testDotNetEncMailMatch() throws Exception { MimeMessage message = loadMessage("dotnet_encrypted_mail.eml"); SMIMEEnveloped env = new SMIMEEnveloped(message); RecipientInformationStore store = env.getRecipientInfos(); assertNotNull(store.get(new JceKeyTransRecipientId(loadCert("dotnet_enc_cert.pem")))); } public void testAES128() throws Exception { MimeMessage message = loadMessage("test128.message"); SMIMEEnveloped env = new SMIMEEnveloped(message); RecipientInformationStore store = env.getRecipientInfos(); RecipientInformation recipInfo = store.get(new JceKeyTransRecipientId(loadCert("cert.pem"))); assertNotNull(recipInfo); byte[] content = recipInfo.getContent(new JceKeyTransEnvelopedRecipient(loadKey("key.pem"))); assertTrue(org.bouncycastle.util.Arrays.areEqual(testMessage, content)); } public void testAES192() throws Exception { MimeMessage message = loadMessage("test192.message"); SMIMEEnveloped env = new SMIMEEnveloped(message); RecipientInformationStore store = env.getRecipientInfos(); RecipientInformation recipInfo = store.get(new JceKeyTransRecipientId(loadCert("cert.pem"))); assertNotNull(recipInfo); byte[] content = recipInfo.getContent(new JceKeyTransEnvelopedRecipient(loadKey("key.pem"))); assertTrue(org.bouncycastle.util.Arrays.areEqual(testMessage, content)); } public void testAES256() throws Exception { MimeMessage message = loadMessage("test256.message"); SMIMEEnveloped env = new SMIMEEnveloped(message); RecipientInformationStore store = env.getRecipientInfos(); RecipientInformation recipInfo = store.get(new JceKeyTransRecipientId(loadCert("cert.pem"))); assertNotNull(recipInfo); byte[] content = recipInfo.getContent(new JceKeyTransEnvelopedRecipient(loadKey("key.pem"))); assertTrue(org.bouncycastle.util.Arrays.areEqual(testMessage, content)); } public void testCapEncrypt() throws Exception { MimeBodyPart msg = SMIMETestUtil.makeMimeBodyPart("WallaWallaWashington"); SMIMEEnvelopedGenerator gen = new SMIMEEnvelopedGenerator(); // // create a subject key id - this has to be done the same way as // it is done in the certificate associated with the private key // MessageDigest dig = MessageDigest.getInstance("SHA1", BC); dig.update(_reciCert.getPublicKey().getEncoded()); gen.addRecipientInfoGenerator(new JceKeyTransRecipientInfoGenerator(dig.digest(), _reciCert.getPublicKey()).setProvider(BC)); // // generate a MimeBodyPart object which encapsulates the content // we want encrypted. // MimeBodyPart mp = gen.generate(msg, new JceCMSContentEncryptorBuilder(CMSAlgorithm.RC2_CBC, 40).setProvider(BC).build()); SMIMEEnveloped m = new SMIMEEnveloped(mp); dig.update(_reciCert.getPublicKey().getEncoded()); RecipientId recId = new KeyTransRecipientId(dig.digest()); RecipientInformationStore recipients = m.getRecipientInfos(); RecipientInformation recipient = recipients.get(recId); MimeBodyPart res = SMIMEUtil.toMimeBodyPart(recipient.getContent(new JceKeyTransEnvelopedRecipient(_reciKP.getPrivate()).setProvider(BC))); verifyMessageBytes(msg, res); } public void testTwoRecipients() throws Exception { MimeBodyPart _msg = SMIMETestUtil.makeMimeBodyPart("WallaWallaWashington"); SMIMEEnvelopedGenerator gen = new SMIMEEnvelopedGenerator(); gen.addRecipientInfoGenerator(new JceKeyTransRecipientInfoGenerator(_reciCert).setProvider(BC)); gen.addRecipientInfoGenerator(new JceKeyTransRecipientInfoGenerator(_reciCert2).setProvider(BC)); // // generate a MimeBodyPart object which encapsulates the content // we want encrypted. // MimeBodyPart mp = gen.generate(_msg, new JceCMSContentEncryptorBuilder(CMSAlgorithm.RC2_CBC, 40).setProvider(BC).build()); SMIMEEnvelopedParser m = new SMIMEEnvelopedParser(mp); RecipientId recId = getRecipientId(_reciCert2); RecipientInformationStore recipients = m.getRecipientInfos(); RecipientInformation recipient = recipients.get(recId); FileBackedMimeBodyPart res = SMIMEUtil.toMimeBodyPart(recipient.getContentStream(new JceKeyTransEnvelopedRecipient(_reciKP2.getPrivate()).setProvider(BC))); verifyMessageBytes(_msg, res); m = new SMIMEEnvelopedParser(mp); res.dispose(); recId = getRecipientId(_reciCert); recipients = m.getRecipientInfos(); recipient = recipients.get(recId); res = SMIMEUtil.toMimeBodyPart(recipient.getContentStream(new JceKeyTransEnvelopedRecipient(_reciKP.getPrivate()).setProvider(BC))); verifyMessageBytes(_msg, res); res.dispose(); } private void verifyAlgorithm( String algorithmOid, MimeBodyPart msg) throws Exception { SMIMEEnvelopedGenerator gen = new SMIMEEnvelopedGenerator(); gen.addRecipientInfoGenerator(new JceKeyTransRecipientInfoGenerator(_reciCert).setProvider(BC)); // // generate a MimeBodyPart object which encapsulates the content // we want encrypted. // MimeBodyPart mp = gen.generate(msg, new JceCMSContentEncryptorBuilder(new ASN1ObjectIdentifier(algorithmOid)).setProvider(BC).build()); SMIMEEnveloped m = new SMIMEEnveloped(mp); RecipientId recId = getRecipientId(_reciCert); RecipientInformationStore recipients = m.getRecipientInfos(); RecipientInformation recipient = recipients.get(recId); MimeBodyPart res = SMIMEUtil.toMimeBodyPart(recipient.getContent(new JceKeyTransEnvelopedRecipient(_reciKP.getPrivate()).setProvider(BC))); verifyMessageBytes(msg, res); } private void verifyParserAlgorithm( String algorithmOid, MimeBodyPart msg) throws Exception { SMIMEEnvelopedGenerator gen = new SMIMEEnvelopedGenerator(); gen.addRecipientInfoGenerator(new JceKeyTransRecipientInfoGenerator(_reciCert).setProvider(BC)); // // generate a MimeBodyPart object which encapsulates the content // we want encrypted. // MimeBodyPart mp = gen.generate(msg, new JceCMSContentEncryptorBuilder(new ASN1ObjectIdentifier(algorithmOid)).setProvider(BC).build()); SMIMEEnvelopedParser m = new SMIMEEnvelopedParser(mp); RecipientId recId = getRecipientId(_reciCert); RecipientInformationStore recipients = m.getRecipientInfos(); RecipientInformation recipient = recipients.get(recId); MimeBodyPart res = SMIMEUtil.toMimeBodyPart(recipient.getContent(new JceKeyTransEnvelopedRecipient(_reciKP.getPrivate()).setProvider(BC))); verifyMessageBytes(msg, res); } private RecipientId getRecipientId( X509Certificate cert) throws IOException, CertificateEncodingException { RecipientId recId = new JceKeyTransRecipientId(cert); return recId; } private void verifyMessageBytes(MimeBodyPart a, MimeBodyPart b) throws IOException, MessagingException { ByteArrayOutputStream _baos = new ByteArrayOutputStream(); a.writeTo(_baos); _baos.close(); byte[] _msgBytes = _baos.toByteArray(); _baos = new ByteArrayOutputStream(); b.writeTo(_baos); _baos.close(); byte[] _resBytes = _baos.toByteArray(); assertEquals(true, Arrays.equals(_msgBytes, _resBytes)); } } bouncycastle-1.49.orig/test/src/org/bouncycastle/mail/smime/test/AllTests.java0000644000175000017500000000140211474363025027074 0ustar ebourgebourgpackage org.bouncycastle.mail.smime.test; import junit.framework.Test; import junit.framework.TestSuite; public class AllTests { public static void main (String[] args) throws Exception { junit.textui.TestRunner.run (suite()); } public static Test suite() throws Exception { TestSuite suite= new TestSuite("SMIME tests"); suite.addTest(SMIMESignedTest.suite()); suite.addTest(NewSMIMESignedTest.suite()); suite.addTest(SignedMailValidatorTest.suite()); suite.addTest(SMIMEEnvelopedTest.suite()); suite.addTest(NewSMIMEEnvelopedTest.suite()); suite.addTest(SMIMECompressedTest.suite()); suite.addTest(SMIMEMiscTest.suite()); return suite; } } bouncycastle-1.49.orig/test/src/org/bouncycastle/mail/smime/test/SignedMailValidatorTest.java0000644000175000017500000004511711625356362032102 0ustar ebourgebourgpackage org.bouncycastle.mail.smime.test; import java.io.InputStream; import java.security.KeyPair; import java.security.Security; import java.security.cert.CertPath; import java.security.cert.CertStore; import java.security.cert.CertificateFactory; import java.security.cert.CollectionCertStoreParameters; import java.security.cert.PKIXParameters; import java.security.cert.TrustAnchor; import java.security.cert.X509CRL; import java.security.cert.X509Certificate; import java.util.ArrayList; import java.util.HashSet; import java.util.Iterator; import java.util.List; import java.util.Locale; import java.util.Properties; import java.util.Set; import java.util.TimeZone; import javax.mail.Address; import javax.mail.Message; import javax.mail.Session; import javax.mail.internet.InternetAddress; import javax.mail.internet.MimeBodyPart; import javax.mail.internet.MimeMessage; import javax.mail.internet.MimeMultipart; import junit.framework.Test; import junit.framework.TestCase; import junit.framework.TestSuite; import org.bouncycastle.asn1.ASN1Encodable; import org.bouncycastle.asn1.ASN1Encoding; import org.bouncycastle.asn1.x509.X509Extension; import org.bouncycastle.cms.SignerInformation; import org.bouncycastle.cms.test.CMSTestUtil; import org.bouncycastle.i18n.ErrorBundle; import org.bouncycastle.mail.smime.SMIMESignedGenerator; import org.bouncycastle.mail.smime.validator.SignedMailValidator; import org.bouncycastle.x509.PKIXCertPathReviewer; import org.bouncycastle.x509.extension.X509ExtensionUtil; public class SignedMailValidatorTest extends TestCase { static String TEST_TRUST_ACHOR = "validator.root.crt"; public void testShortKey() throws Exception { String message = "validator.shortKey.eml"; PKIXParameters params = createDefaultParams(); SignedMailValidator.ValidationResult result = doTest(message, params); assertTrue(result.isValidSignature()); assertContainsMessage(result.getNotifications(), "SignedMailValidator.shortSigningKey", "Warning: The signing key is only 512 bits long."); } public void testKeyUsage() throws Exception { String message = "validator.keyUsage.eml"; PKIXParameters params = createDefaultParams(); SignedMailValidator.ValidationResult result = doTest(message, params); assertTrue(result.isVerifiedSignature()); assertTrue(result.getCertPathReview().isValidCertPath()); assertFalse(result.isValidSignature()); assertContainsMessage( result.getErrors(), "SignedMailValidator.signingNotPermitted", "The key usage extension of signer certificate does not permit using the key for email signatures."); } public void testExtKeyUsage() throws Exception { String message = "validator.extKeyUsage.eml"; PKIXParameters params = createDefaultParams(); SignedMailValidator.ValidationResult result = doTest(message, params); assertTrue(result.isVerifiedSignature()); assertTrue(result.getCertPathReview().isValidCertPath()); assertFalse(result.isValidSignature()); assertContainsMessage( result.getErrors(), "SignedMailValidator.extKeyUsageNotPermitted", "The extended key usage extension of the signer certificate does not permit using the key for email signatures."); } public void testNoEmail() throws Exception { String message = "validator.noEmail.eml"; PKIXParameters params = createDefaultParams(); SignedMailValidator.ValidationResult result = doTest(message, params); assertTrue(result.isVerifiedSignature()); assertTrue(result.getCertPathReview().isValidCertPath()); assertFalse(result.isValidSignature()); assertContainsMessage( result.getErrors(), "SignedMailValidator.noEmailInCert", "The signer certificate is not usable for email signatures: it contains no email address."); } public void testNotYetValid() throws Exception { String message = "validator.notYetValid.eml"; PKIXParameters params = createDefaultParams(); SignedMailValidator.ValidationResult result = doTest(message, params); assertTrue(result.isVerifiedSignature()); assertFalse(result.isValidSignature()); assertContainsMessage(result.getErrors(), "SignedMailValidator.certNotYetValid", "The message was signed at Aug 28, 2006 3:04:01 PM GMT. But the certificate is not valid before Dec 28, 2006 2:19:31 PM GMT."); PKIXCertPathReviewer review = result.getCertPathReview(); assertFalse(review.isValidCertPath()); assertContainsMessage( review.getErrors(0), "CertPathReviewer.certificateNotYetValid", "Could not validate the certificate. Certificate is not valid until Dec 28, 2006 2:19:31 PM GMT."); } public void testExpired() throws Exception { String message = "validator.expired.eml"; PKIXParameters params = createDefaultParams(); SignedMailValidator.ValidationResult result = doTest(message, params); assertTrue(result.isVerifiedSignature()); assertFalse(result.isValidSignature()); assertContainsMessage(result.getErrors(), "SignedMailValidator.certExpired", "The message was signed at Sep 1, 2006 9:08:35 AM GMT. But the certificate expired at Sep 1, 2006 8:39:20 AM GMT."); PKIXCertPathReviewer review = result.getCertPathReview(); assertFalse(review.isValidCertPath()); assertContainsMessage( review.getErrors(0), "CertPathReviewer.certificateExpired", "Could not validate the certificate. Certificate expired on Sep 1, 2006 8:39:20 AM GMT."); } public void testRevoked() throws Exception { String message = "validator.revoked.eml"; PKIXParameters params = createDefaultParams(); List crlList = new ArrayList(); crlList.add(loadCRL("validator.revoked.crl")); CertStore crls = CertStore.getInstance("Collection",new CollectionCertStoreParameters(crlList)); params.addCertStore(crls); params.setRevocationEnabled(true); SignedMailValidator.ValidationResult result = doTest(message, params); assertTrue(result.isVerifiedSignature()); assertFalse(result.isValidSignature()); PKIXCertPathReviewer review = result.getCertPathReview(); assertFalse(review.isValidCertPath()); assertContainsMessage( review.getErrors(0), "CertPathReviewer.certRevoked", "The certificate was revoked at Sep 1, 2006 9:30:00 AM GMT. Reason: Key Compromise."); } public void testLongValidity() throws Exception { String message = "validator.longValidity.eml"; PKIXParameters params = createDefaultParams(); SignedMailValidator.ValidationResult result = doTest(message, params); assertTrue(result.isVerifiedSignature()); assertTrue(result.isValidSignature()); assertContainsMessage(result.getNotifications(), "SignedMailValidator.longValidity", "Warning: The signing certificate has a very long validity period: from Sep 1, 2006 11:00:00 AM GMT until Aug 8, 2106 11:00:00 AM GMT."); } public void testSelfSignedCert() throws Exception { MimeBodyPart baseMsg = SMIMETestUtil.makeMimeBodyPart("Hello world!\n"); String signDN = "CN=Eric H. Echidna, E=eric@bouncycastle.org, O=Bouncy Castle, C=AU"; KeyPair signKP = CMSTestUtil.makeKeyPair(); X509Certificate signCert = CMSTestUtil.makeV1Certificate(signKP, signDN, signKP, signDN); // check basic path validation Set trustanchors = new HashSet(); TrustAnchor ta = new TrustAnchor(signCert, null); trustanchors.add(ta); X509Certificate rootCert = ta.getTrustedCert(); // init cert stores List certStores = new ArrayList(); List certList = new ArrayList(); certList.add(rootCert); CertStore store = CertStore.getInstance("Collection", new CollectionCertStoreParameters(certList)); certStores.add(store); // first path CertPath path = SignedMailValidator.createCertPath(rootCert, trustanchors, certStores); assertTrue("path size is not 1", path.getCertificates().size() == 1); // check message validation certList = new ArrayList(); certList.add(signCert); CertStore certs = CertStore.getInstance("Collection", new CollectionCertStoreParameters(certList), "BC"); SMIMESignedGenerator gen = new SMIMESignedGenerator(); gen.addSigner(signKP.getPrivate(), signCert, SMIMESignedGenerator.DIGEST_SHA1); gen.addCertificatesAndCRLs(certs); MimeMultipart signedMsg = gen.generate(baseMsg, "BC"); Properties props = System.getProperties(); Session session = Session.getDefaultInstance(props, null); // read message MimeMessage msg = new MimeMessage(session); Address fromUser = new InternetAddress("\"Eric H. Echidna\""); Address toUser = new InternetAddress("example@bouncycastle.org"); msg.setFrom(fromUser); msg.setRecipient(Message.RecipientType.TO, toUser); msg.setContent(signedMsg, signedMsg.getContentType()); msg.saveChanges(); PKIXParameters params = new PKIXParameters(trustanchors); params.setRevocationEnabled(false); SignedMailValidator validator = new SignedMailValidator(msg, params); SignerInformation signer = (SignerInformation) validator .getSignerInformationStore().getSigners().iterator().next(); SignedMailValidator.ValidationResult res = validator.getValidationResult(signer); assertTrue(res.isVerifiedSignature()); assertTrue(res.isValidSignature()); } // TODO: this test needs to be replaced, unfortunately it was working due to a bug in // trust anchor extension handling // public void testCorruptRootStore() throws Exception // { // String message = "validator.validMail.eml"; // Set trustanchors = new HashSet(); // trustanchors.add(getTrustAnchor(TEST_TRUST_ACHOR)); // trustanchors.add(getTrustAnchor("validator.fakeRoot.crt")); // PKIXParameters params = new PKIXParameters(trustanchors); // params.setRevocationEnabled(false); // // SignedMailValidator.ValidationResult result = doTest(message, params); // // assertTrue(result.isVerifiedSignature()); // assertFalse(result.isValidSignature()); // // PKIXCertPathReviewer review = result.getCertPathReview(); // // assertFalse(review.isValidCertPath()); // assertContainsMessage(review.getErrors(-1), // "CertPathReviewer.conflictingTrustAnchors", // "Warning: corrupt trust root store: There are 2 trusted public keys for the CA \"CN=SignedMailValidatorTest Root, C=CH\" - please ensure with CA which is the correct key."); // } public void testCircular() throws Exception { String message = "circular.eml"; PKIXParameters params = createDefaultParams(); SignedMailValidator.ValidationResult result = doTest(message, params); assertTrue(result.isVerifiedSignature()); assertFalse(result.isValidSignature()); assertFalse(result.getCertPathReview().isValidCertPath()); assertTrue("cert path size", result.getCertPathReview().getCertPathSize() > 2); } public void testExtendedReviewer() throws Exception { try { // Get a Session object with the default properties. Properties props = System.getProperties(); Session session = Session.getDefaultInstance(props, null); // read message MimeMessage msg = new MimeMessage(session, getClass().getResourceAsStream("validator.shortKey.eml")); SignedMailValidator validator = new SignedMailValidator(msg, createDefaultParams(), String.class); fail(); } catch (IllegalArgumentException e) { assertTrue(e.getMessage().startsWith("certPathReviewerClass is not a subclass of")); } // Get a Session object with the default properties. Properties props = System.getProperties(); Session session = Session.getDefaultInstance(props, null); // read message MimeMessage msg = new MimeMessage(session, getClass().getResourceAsStream("validator.shortKey.eml")); SignedMailValidator validator = new SignedMailValidator(msg, createDefaultParams(), DummyCertPathReviewer.class); SignerInformation sInfo = (SignerInformation) validator.getSignerInformationStore().getSigners().iterator().next(); SignedMailValidator.ValidationResult result = validator.getValidationResult(sInfo); assertTrue(result.isValidSignature()); assertContainsMessage(result.getNotifications(), "SignedMailValidator.shortSigningKey", "Warning: The signing key is only 512 bits long."); } public void testCreateCertPath() throws Exception { // load trust anchor Set trustanchors = new HashSet(); TrustAnchor ta = getTrustAnchor("certpath_root.crt"); trustanchors.add(ta); X509Certificate rootCert = ta.getTrustedCert(); X509Certificate interCert1 = loadCert("certpath_inter1.crt"); X509Certificate interCert2 = loadCert("certpath_inter2.crt"); X509Certificate endCert1 = loadCert("certpath_end1.crt"); X509Certificate endCert2 = loadCert("certpath_end2.crt"); // init cert stores List certStores = new ArrayList(); List certList = new ArrayList(); certList.add(interCert1); certList.add(interCert2); CertStore store = CertStore.getInstance("Collection", new CollectionCertStoreParameters(certList)); certStores.add(store); // first path CertPath path = SignedMailValidator.createCertPath(endCert1, trustanchors, certStores); assertTrue("path size is not 3", path.getCertificates().size() == 3); assertEquals("different end certificate", path.getCertificates().get(0), endCert1); assertEquals("different intermediate certificate", path.getCertificates().get(1), interCert1); assertEquals("different root certificate", path.getCertificates().get(2), rootCert); // second path path = SignedMailValidator.createCertPath(endCert2, trustanchors, certStores); assertTrue("path size is not 3", path.getCertificates().size() == 3); assertEquals("different end certificate", path.getCertificates().get(0), endCert2); assertEquals("different intermediate certificate", path.getCertificates().get(1), interCert2); assertEquals("different root certificate", path.getCertificates().get(2), rootCert); } private SignedMailValidator.ValidationResult doTest(String message, PKIXParameters params) throws Exception { // Get a Session object with the default properties. Properties props = System.getProperties(); Session session = Session.getDefaultInstance(props, null); // read message MimeMessage msg = new MimeMessage(session, getClass().getResourceAsStream(message)); SignedMailValidator validator = new SignedMailValidator(msg, params); SignerInformation signer = (SignerInformation) validator .getSignerInformationStore().getSigners().iterator().next(); return validator.getValidationResult(signer); } private void assertContainsMessage(List msgList, String messageId, String text) throws Exception { Iterator it = msgList.iterator(); boolean found = false; while (it.hasNext()) { ErrorBundle message = (ErrorBundle) it.next(); if (message.getId().equals(messageId)) { found = true; assertEquals(text, message.getText(Locale.ENGLISH, TimeZone .getTimeZone("GMT"))); break; } } assertTrue("Expected message not found!", found); } private PKIXParameters createDefaultParams() throws Exception { Set trustanchors = new HashSet(); trustanchors.add(getTrustAnchor(TEST_TRUST_ACHOR)); PKIXParameters defParams = new PKIXParameters(trustanchors); defParams.setRevocationEnabled(false); return defParams; } private TrustAnchor getTrustAnchor(String trustcert) throws Exception { X509Certificate cert = loadCert(trustcert); if (cert != null) { byte[] ncBytes = cert .getExtensionValue(X509Extension.nameConstraints.getId()); if (ncBytes != null) { ASN1Encodable extValue = X509ExtensionUtil .fromExtensionValue(ncBytes); return new TrustAnchor(cert, extValue.toASN1Primitive().getEncoded(ASN1Encoding.DER)); } return new TrustAnchor(cert, null); } return null; } private X509Certificate loadCert(String certfile) throws Exception { X509Certificate cert = null; InputStream in = getClass().getResourceAsStream(certfile); CertificateFactory cf = CertificateFactory.getInstance("X.509", "BC"); cert = (X509Certificate) cf.generateCertificate(in); return cert; } private X509CRL loadCRL(String crlfile) throws Exception { X509CRL crl = null; InputStream in = this.getClass().getResourceAsStream(crlfile); CertificateFactory cf = CertificateFactory.getInstance("x.509", "BC"); crl = (X509CRL) cf.generateCRL(in); return crl; } public void setUp() { if (Security.getProvider("BC") == null) { Security .addProvider(new org.bouncycastle.jce.provider.BouncyCastleProvider()); } } public static void main(String[] args) throws Exception { junit.textui.TestRunner.run(suite()); } public static Test suite() throws Exception { TestSuite suite = new TestSuite("SignedMailValidator Tests"); suite.addTestSuite(SignedMailValidatorTest.class); return suite; } } bouncycastle-1.49.orig/test/src/org/bouncycastle/mail/smime/test/DummyCertPathReviewer.java0000644000175000017500000000024410606356714031606 0ustar ebourgebourgpackage org.bouncycastle.mail.smime.test; import org.bouncycastle.x509.PKIXCertPathReviewer; public class DummyCertPathReviewer extends PKIXCertPathReviewer { } bouncycastle-1.49.orig/test/src/org/bouncycastle/mail/smime/test/SMIMETestSetup.java0000644000175000017500000000332010330633061030063 0ustar ebourgebourg// Copyright (c) 2005 The Legion Of The Bouncy Castle (http://www.bouncycastle.org) package org.bouncycastle.mail.smime.test; import junit.extensions.TestSetup; import junit.framework.Test; import javax.activation.CommandMap; import javax.activation.MailcapCommandMap; import java.security.Security; class SMIMETestSetup extends TestSetup { private CommandMap originalMap = null; public SMIMETestSetup(Test test) { super(test); } protected void setUp() { Security .addProvider(new org.bouncycastle.jce.provider.BouncyCastleProvider()); MailcapCommandMap _mailcap = (MailcapCommandMap)CommandMap .getDefaultCommandMap(); _mailcap .addMailcap("application/pkcs7-signature;; x-java-content-handler=org.bouncycastle.mail.smime.handlers.pkcs7_signature"); _mailcap .addMailcap("application/pkcs7-mime;; x-java-content-handler=org.bouncycastle.mail.smime.handlers.pkcs7_mime"); _mailcap .addMailcap("application/x-pkcs7-signature;; x-java-content-handler=org.bouncycastle.mail.smime.handlers.x_pkcs7_signature"); _mailcap .addMailcap("application/x-pkcs7-mime;; x-java-content-handler=org.bouncycastle.mail.smime.handlers.x_pkcs7_mime"); _mailcap .addMailcap("multipart/signed;; x-java-content-handler=org.bouncycastle.mail.smime.handlers.multipart_signed"); originalMap = CommandMap.getDefaultCommandMap(); CommandMap.setDefaultCommandMap(_mailcap); } protected void tearDown() { CommandMap.setDefaultCommandMap(originalMap); originalMap = null; Security.removeProvider("BC"); } } bouncycastle-1.49.orig/test/src/org/bouncycastle/mail/smime/test/SMIMEEnvelopedTest.java0000644000175000017500000003102011521706600030705 0ustar ebourgebourgpackage org.bouncycastle.mail.smime.test; import java.io.ByteArrayOutputStream; import java.io.IOException; import java.security.KeyPair; import java.security.MessageDigest; import java.security.NoSuchAlgorithmException; import java.security.cert.CertificateEncodingException; import java.security.cert.X509Certificate; import java.util.Arrays; import javax.crypto.Cipher; import javax.mail.MessagingException; import javax.mail.internet.MimeBodyPart; import junit.framework.Test; import junit.framework.TestCase; import junit.framework.TestSuite; import org.bouncycastle.cms.KeyTransRecipientId; import org.bouncycastle.cms.RecipientId; import org.bouncycastle.cms.RecipientInformation; import org.bouncycastle.cms.RecipientInformationStore; import org.bouncycastle.cms.jcajce.JceKeyTransRecipientId; import org.bouncycastle.cms.test.CMSTestUtil; import org.bouncycastle.mail.smime.SMIMEEnveloped; import org.bouncycastle.mail.smime.SMIMEEnvelopedGenerator; import org.bouncycastle.mail.smime.SMIMEEnvelopedParser; import org.bouncycastle.mail.smime.SMIMEUtil; import org.bouncycastle.mail.smime.util.FileBackedMimeBodyPart; public class SMIMEEnvelopedTest extends TestCase { private static String _signDN; private static KeyPair _signKP; private static String _reciDN; private static KeyPair _reciKP; private static X509Certificate _reciCert; private static String _reciDN2; private static KeyPair _reciKP2; private static X509Certificate _reciCert2; private static boolean _initialised = false; private static void init() throws Exception { if (!_initialised) { _initialised = true; _signDN = "O=Bouncy Castle, C=AU"; _signKP = CMSTestUtil.makeKeyPair(); _reciDN = "CN=Doug, OU=Sales, O=Bouncy Castle, C=AU"; _reciKP = CMSTestUtil.makeKeyPair(); _reciCert = CMSTestUtil.makeCertificate(_reciKP, _reciDN, _signKP, _signDN); _reciDN2 = "CN=Fred, OU=Sales, O=Bouncy Castle, C=AU"; _reciKP2 = CMSTestUtil.makeKeyPair(); _reciCert2 = CMSTestUtil.makeCertificate(_reciKP2, _reciDN2, _signKP, _signDN); } } public SMIMEEnvelopedTest( String name) { super(name); } public static void main( String args[]) { junit.textui.TestRunner.run(SMIMEEnvelopedTest.class); } public static Test suite() throws Exception { return new SMIMETestSetup(new TestSuite(SMIMEEnvelopedTest.class)); } public void setUp() throws Exception { init(); } public void testHeaders() throws Exception { MimeBodyPart _msg = SMIMETestUtil.makeMimeBodyPart("WallaWallaWashington"); SMIMEEnvelopedGenerator gen = new SMIMEEnvelopedGenerator(); gen.addKeyTransRecipient(_reciCert); // // generate a MimeBodyPart object which encapsulates the content // we want encrypted. // MimeBodyPart mp = gen.generate(_msg, SMIMEEnvelopedGenerator.DES_EDE3_CBC, "BC"); assertEquals("application/pkcs7-mime; name=\"smime.p7m\"; smime-type=enveloped-data", mp.getHeader("Content-Type")[0]); assertEquals("attachment; filename=\"smime.p7m\"", mp.getHeader("Content-Disposition")[0]); assertEquals("S/MIME Encrypted Message", mp.getHeader("Content-Description")[0]); } public void testDESEDE3Encrypted() throws Exception { MimeBodyPart msg = SMIMETestUtil.makeMimeBodyPart("WallaWallaWashington"); String algorithm = SMIMEEnvelopedGenerator.DES_EDE3_CBC; verifyAlgorithm(algorithm, msg); } public void testParserDESEDE3Encrypted() throws Exception { MimeBodyPart msg = SMIMETestUtil.makeMimeBodyPart("WallaWallaWashington"); String algorithm = SMIMEEnvelopedGenerator.DES_EDE3_CBC; verifyParserAlgorithm(algorithm, msg); } public void testIDEAEncrypted() throws Exception { if (isPresent("IDEA")) { MimeBodyPart msg = SMIMETestUtil.makeMimeBodyPart("WallaWallaWashington"); String algorithm = SMIMEEnvelopedGenerator.IDEA_CBC; verifyAlgorithm(algorithm, msg); } } private boolean isPresent(String algorithm) throws Exception { try { Cipher.getInstance(algorithm, "BC"); return true; } catch (NoSuchAlgorithmException e) { return false; } } public void testRC2Encrypted() throws Exception { MimeBodyPart msg = SMIMETestUtil.makeMimeBodyPart("WallaWallaWashington"); String algorithm = SMIMEEnvelopedGenerator.RC2_CBC; verifyAlgorithm(algorithm, msg); } public void testCASTEncrypted() throws Exception { MimeBodyPart msg = SMIMETestUtil.makeMimeBodyPart("WallaWallaWashington"); String algorithm = SMIMEEnvelopedGenerator.CAST5_CBC; verifyAlgorithm(algorithm, msg); } public void testAES128Encrypted() throws Exception { MimeBodyPart msg = SMIMETestUtil.makeMimeBodyPart("WallaWallaWashington"); String algorithm = SMIMEEnvelopedGenerator.AES128_CBC; verifyAlgorithm(algorithm, msg); } public void testAES192Encrypted() throws Exception { MimeBodyPart msg = SMIMETestUtil.makeMimeBodyPart("WallaWallaWashington"); String algorithm = SMIMEEnvelopedGenerator.AES192_CBC; verifyAlgorithm(algorithm, msg); } public void testAES256Encrypted() throws Exception { MimeBodyPart msg = SMIMETestUtil.makeMimeBodyPart("WallaWallaWashington"); String algorithm = SMIMEEnvelopedGenerator.AES256_CBC; verifyAlgorithm(algorithm, msg); } public void testSubKeyId() throws Exception { MimeBodyPart _msg = SMIMETestUtil.makeMimeBodyPart("WallaWallaWashington"); SMIMEEnvelopedGenerator gen = new SMIMEEnvelopedGenerator(); // // create a subject key id - this has to be done the same way as // it is done in the certificate associated with the private key // MessageDigest dig = MessageDigest.getInstance("SHA1", "BC"); dig.update(_reciCert.getPublicKey().getEncoded()); gen.addKeyTransRecipient(_reciCert.getPublicKey(), dig.digest()); // // generate a MimeBodyPart object which encapsulates the content // we want encrypted. // MimeBodyPart mp = gen.generate(_msg, SMIMEEnvelopedGenerator.DES_EDE3_CBC, "BC"); SMIMEEnveloped m = new SMIMEEnveloped(mp); dig.update(_reciCert.getPublicKey().getEncoded()); RecipientId recId = new KeyTransRecipientId(dig.digest()); RecipientInformationStore recipients = m.getRecipientInfos(); RecipientInformation recipient = recipients.get(recId); MimeBodyPart res = SMIMEUtil.toMimeBodyPart(recipient.getContent(_reciKP.getPrivate(), "BC")); verifyMessageBytes(_msg, res); } public void testCapEncrypt() throws Exception { MimeBodyPart _msg = SMIMETestUtil.makeMimeBodyPart("WallaWallaWashington"); SMIMEEnvelopedGenerator gen = new SMIMEEnvelopedGenerator(); // // create a subject key id - this has to be done the same way as // it is done in the certificate associated with the private key // MessageDigest dig = MessageDigest.getInstance("SHA1", "BC"); dig.update(_reciCert.getPublicKey().getEncoded()); gen.addKeyTransRecipient(_reciCert.getPublicKey(), dig.digest()); // // generate a MimeBodyPart object which encapsulates the content // we want encrypted. // MimeBodyPart mp = gen.generate(_msg, SMIMEEnvelopedGenerator.RC2_CBC, 40, "BC"); SMIMEEnveloped m = new SMIMEEnveloped(mp); dig.update(_reciCert.getPublicKey().getEncoded()); RecipientId recId = new KeyTransRecipientId(dig.digest()); RecipientInformationStore recipients = m.getRecipientInfos(); RecipientInformation recipient = recipients.get(recId); MimeBodyPart res = SMIMEUtil.toMimeBodyPart(recipient.getContent(_reciKP.getPrivate(), "BC")); verifyMessageBytes(_msg, res); } public void testTwoRecipients() throws Exception { MimeBodyPart _msg = SMIMETestUtil.makeMimeBodyPart("WallaWallaWashington"); SMIMEEnvelopedGenerator gen = new SMIMEEnvelopedGenerator(); gen.addKeyTransRecipient(_reciCert); gen.addKeyTransRecipient(_reciCert2); // // generate a MimeBodyPart object which encapsulates the content // we want encrypted. // MimeBodyPart mp = gen.generate(_msg, SMIMEEnvelopedGenerator.RC2_CBC, 40, "BC"); SMIMEEnvelopedParser m = new SMIMEEnvelopedParser(mp); RecipientId recId = getRecipientId(_reciCert2); RecipientInformationStore recipients = m.getRecipientInfos(); RecipientInformation recipient = recipients.get(recId); FileBackedMimeBodyPart res = SMIMEUtil.toMimeBodyPart(recipient.getContentStream(_reciKP2.getPrivate(), "BC")); verifyMessageBytes(_msg, res); m = new SMIMEEnvelopedParser(mp); res.dispose(); recId = getRecipientId(_reciCert); recipients = m.getRecipientInfos(); recipient = recipients.get(recId); res = SMIMEUtil.toMimeBodyPart(recipient.getContentStream(_reciKP.getPrivate(), "BC")); verifyMessageBytes(_msg, res); res.dispose(); } private void verifyAlgorithm( String algorithmOid, MimeBodyPart msg) throws Exception { SMIMEEnvelopedGenerator gen = new SMIMEEnvelopedGenerator(); gen.addKeyTransRecipient(_reciCert); // // generate a MimeBodyPart object which encapsulates the content // we want encrypted. // MimeBodyPart mp = gen.generate(msg, algorithmOid, "BC"); SMIMEEnveloped m = new SMIMEEnveloped(mp); RecipientId recId = getRecipientId(_reciCert); RecipientInformationStore recipients = m.getRecipientInfos(); RecipientInformation recipient = recipients.get(recId); MimeBodyPart res = SMIMEUtil.toMimeBodyPart(recipient.getContent(_reciKP.getPrivate(), "BC")); verifyMessageBytes(msg, res); } private void verifyParserAlgorithm( String algorithmOid, MimeBodyPart msg) throws Exception { SMIMEEnvelopedGenerator gen = new SMIMEEnvelopedGenerator(); gen.addKeyTransRecipient(_reciCert); // // generate a MimeBodyPart object which encapsulates the content // we want encrypted. // MimeBodyPart mp = gen.generate(msg, algorithmOid, "BC"); SMIMEEnvelopedParser m = new SMIMEEnvelopedParser(mp); RecipientId recId = getRecipientId(_reciCert); RecipientInformationStore recipients = m.getRecipientInfos(); RecipientInformation recipient = recipients.get(recId); MimeBodyPart res = SMIMEUtil.toMimeBodyPart(recipient.getContent(_reciKP.getPrivate(), "BC")); verifyMessageBytes(msg, res); } private RecipientId getRecipientId( X509Certificate cert) throws IOException, CertificateEncodingException { RecipientId recId = new JceKeyTransRecipientId(cert); return recId; } private void verifyMessageBytes(MimeBodyPart a, MimeBodyPart b) throws IOException, MessagingException { ByteArrayOutputStream _baos = new ByteArrayOutputStream(); a.writeTo(_baos); _baos.close(); byte[] _msgBytes = _baos.toByteArray(); _baos = new ByteArrayOutputStream(); b.writeTo(_baos); _baos.close(); byte[] _resBytes = _baos.toByteArray(); assertEquals(true, Arrays.equals(_msgBytes, _resBytes)); } } bouncycastle-1.49.orig/test/src/org/bouncycastle/mail/smime/test/package.html0000644000175000017500000000030610330633061026747 0ustar ebourgebourg Regression tests for the org.bouncycastle.mail.smime package.

    Note: The classes in this package are also a useful source of example code. bouncycastle-1.49.orig/test/src/org/bouncycastle/mail/smime/test/SMIMESignedTest.java0000644000175000017500000012437411726245377030234 0ustar ebourgebourgpackage org.bouncycastle.mail.smime.test; import java.io.ByteArrayOutputStream; import java.io.File; import java.io.FileNotFoundException; import java.io.FilterOutputStream; import java.io.IOException; import java.io.OutputStream; import java.io.UnsupportedEncodingException; import java.security.KeyPair; import java.security.MessageDigest; import java.security.cert.CertStore; import java.security.cert.CollectionCertStoreParameters; import java.security.cert.X509Certificate; import java.util.ArrayList; import java.util.Arrays; import java.util.Collection; import java.util.Collections; import java.util.Date; import java.util.Enumeration; import java.util.Iterator; import java.util.List; import java.util.Map; import java.util.Properties; import javax.mail.BodyPart; import javax.mail.MessagingException; import javax.mail.Session; import javax.mail.internet.ContentType; import javax.mail.internet.InternetHeaders; import javax.mail.internet.MimeBodyPart; import javax.mail.internet.MimeMessage; import javax.mail.internet.MimeMultipart; import junit.framework.Test; import junit.framework.TestCase; import junit.framework.TestSuite; import org.bouncycastle.asn1.ASN1EncodableVector; import org.bouncycastle.asn1.ASN1OctetString; import org.bouncycastle.asn1.DERSet; import org.bouncycastle.asn1.cms.Attribute; import org.bouncycastle.asn1.cms.AttributeTable; import org.bouncycastle.asn1.cms.CMSAttributes; import org.bouncycastle.asn1.cms.Time; import org.bouncycastle.asn1.cryptopro.CryptoProObjectIdentifiers; import org.bouncycastle.asn1.nist.NISTObjectIdentifiers; import org.bouncycastle.asn1.pkcs.PKCSObjectIdentifiers; import org.bouncycastle.asn1.smime.SMIMECapabilitiesAttribute; import org.bouncycastle.asn1.smime.SMIMECapability; import org.bouncycastle.asn1.smime.SMIMECapabilityVector; import org.bouncycastle.asn1.teletrust.TeleTrusTObjectIdentifiers; import org.bouncycastle.cms.SignerInformation; import org.bouncycastle.cms.SignerInformationStore; import org.bouncycastle.cms.jcajce.JcaX509CertSelectorConverter; import org.bouncycastle.cms.test.CMSTestUtil; import org.bouncycastle.mail.smime.SMIMESigned; import org.bouncycastle.mail.smime.SMIMESignedGenerator; import org.bouncycastle.mail.smime.SMIMESignedParser; import org.bouncycastle.mail.smime.util.CRLFOutputStream; import org.bouncycastle.mail.smime.util.FileBackedMimeBodyPart; import org.bouncycastle.x509.X509AttributeCertificate; import org.bouncycastle.x509.X509CollectionStoreParameters; import org.bouncycastle.x509.X509Store; public class SMIMESignedTest extends TestCase { static MimeBodyPart msg; static MimeBodyPart msgR; static MimeBodyPart msgRN; static String _origDN; static KeyPair _origKP; static X509Certificate _origCert; static String _signDN; static KeyPair _signKP; static X509Certificate _signCert; static String reciDN; static KeyPair reciKP; static X509Certificate reciCert; private static KeyPair _signGostKP; private static X509Certificate _signGostCert; private static KeyPair _signEcDsaKP; private static X509Certificate _signEcDsaCert; private static KeyPair _signEcGostKP; private static X509Certificate _signEcGostCert; private static final JcaX509CertSelectorConverter selectorConverter = new JcaX509CertSelectorConverter(); KeyPair dsaSignKP; X509Certificate dsaSignCert; KeyPair dsaOrigKP; X509Certificate dsaOrigCert; static { try { msg = SMIMETestUtil.makeMimeBodyPart("Hello world!\n"); msgR = SMIMETestUtil.makeMimeBodyPart("Hello world!\r"); msgRN = SMIMETestUtil.makeMimeBodyPart("Hello world!\r\n"); _origDN = "O=Bouncy Castle, C=AU"; _origKP = CMSTestUtil.makeKeyPair(); _origCert = CMSTestUtil.makeCertificate(_origKP, _origDN, _origKP, _origDN); _signDN = "CN=Eric H. Echidna, E=eric@bouncycastle.org, O=Bouncy Castle, C=AU"; _signKP = CMSTestUtil.makeKeyPair(); _signCert = CMSTestUtil.makeCertificate(_signKP, _signDN, _origKP, _origDN); _signGostKP = CMSTestUtil.makeGostKeyPair(); _signGostCert = CMSTestUtil.makeCertificate(_signGostKP, _signDN, _origKP, _origDN); _signEcDsaKP = CMSTestUtil.makeEcDsaKeyPair(); _signEcDsaCert = CMSTestUtil.makeCertificate(_signEcDsaKP, _signDN, _origKP, _origDN); _signEcGostKP = CMSTestUtil.makeEcGostKeyPair(); _signEcGostCert = CMSTestUtil.makeCertificate(_signEcGostKP, _signDN, _origKP, _origDN); } catch (Exception e) { throw new RuntimeException("problem setting up signed test class: " + e); } } private static class LineOutputStream extends FilterOutputStream { private static byte newline[]; public LineOutputStream(OutputStream outputstream) { super(outputstream); } public void writeln(String s) throws MessagingException { try { byte abyte0[] = getBytes(s); super.out.write(abyte0); super.out.write(newline); } catch(Exception exception) { throw new MessagingException("IOException", exception); } } public void writeln() throws MessagingException { try { super.out.write(newline); } catch(Exception exception) { throw new MessagingException("IOException", exception); } } static { newline = new byte[2]; newline[0] = 13; newline[1] = 10; } private static byte[] getBytes(String s) { char ac[] = s.toCharArray(); int i = ac.length; byte abyte0[] = new byte[i]; int j = 0; while (j < i) { abyte0[j] = (byte)ac[j++]; } return abyte0; } } /* * * INFRASTRUCTURE * */ public SMIMESignedTest(String name) { super(name); } public static void main(String args[]) { junit.textui.TestRunner.run(SMIMESignedTest.class); } public static Test suite() { return new SMIMETestSetup(new TestSuite(SMIMESignedTest.class)); } public void testHeaders() throws Exception { MimeMultipart smm = generateMultiPartRsa(SMIMESignedGenerator.DIGEST_SHA1, msg, SMIMESignedGenerator.RFC3851_MICALGS); BodyPart bp = smm.getBodyPart(1); assertEquals("application/pkcs7-signature; name=smime.p7s; smime-type=signed-data", bp.getHeader("Content-Type")[0]); assertEquals("attachment; filename=\"smime.p7s\"", bp.getHeader("Content-Disposition")[0]); assertEquals("S/MIME Cryptographic Signature", bp.getHeader("Content-Description")[0]); } public void testHeadersEncapsulated() throws Exception { List certList = new ArrayList(); certList.add(_signCert); certList.add(_origCert); CertStore certs = CertStore.getInstance("Collection", new CollectionCertStoreParameters(certList), "BC"); ASN1EncodableVector signedAttrs = generateSignedAttributes(); SMIMESignedGenerator gen = new SMIMESignedGenerator(); gen.addSigner(_signKP.getPrivate(), _signCert, SMIMESignedGenerator.DIGEST_SHA1, new AttributeTable(signedAttrs), null); gen.addCertificatesAndCRLs(certs); MimeBodyPart res = gen.generateEncapsulated(msg, "BC"); assertEquals("application/pkcs7-mime; name=smime.p7m; smime-type=signed-data", res.getHeader("Content-Type")[0]); assertEquals("attachment; filename=\"smime.p7m\"", res.getHeader("Content-Disposition")[0]); assertEquals("S/MIME Cryptographic Signed Data", res.getHeader("Content-Description")[0]); } public void testMultipartTextText() throws Exception { MimeBodyPart part1 = createTemplate("text/html", "7bit"); MimeBodyPart part2 = createTemplate("text/xml", "7bit"); multipartMixedTest(part1, part2); } public void testMultipartTextBinary() throws Exception { MimeBodyPart part1 = createTemplate("text/html", "7bit"); MimeBodyPart part2 = createTemplate("text/xml", "binary"); multipartMixedTest(part1, part2); } public void testMultipartBinaryText() throws Exception { MimeBodyPart part1 = createTemplate("text/xml", "binary"); MimeBodyPart part2 = createTemplate("text/html", "7bit"); multipartMixedTest(part1, part2); } public void testMultipartBinaryBinary() throws Exception { MimeBodyPart part1 = createTemplate("text/xml", "binary"); MimeBodyPart part2 = createTemplate("text/html", "binary"); multipartMixedTest(part1, part2); } public void testSHA1WithRSAPSS() throws Exception { rsaPSSTest(SMIMESignedGenerator.DIGEST_SHA1); } public void testSHA224WithRSAPSS() throws Exception { rsaPSSTest(SMIMESignedGenerator.DIGEST_SHA224); } public void testSHA256WithRSAPSS() throws Exception { rsaPSSTest(SMIMESignedGenerator.DIGEST_SHA256); } public void testSHA384WithRSAPSS() throws Exception { rsaPSSTest(SMIMESignedGenerator.DIGEST_SHA384); } public void multipartMixedTest(MimeBodyPart part1, MimeBodyPart part2) throws Exception { MimeMultipart mp = new MimeMultipart(); mp.addBodyPart(part1); mp.addBodyPart(part2); MimeBodyPart m = new MimeBodyPart(); m.setContent(mp); MimeMultipart smm = generateMultiPartRsa(SMIMESignedGenerator.DIGEST_SHA1, m, SMIMESignedGenerator.RFC3851_MICALGS); SMIMESigned s = new SMIMESigned(smm); verifySigners(s.getCertificatesAndCRLs("Collection", "BC"), s.getSignerInfos()); AttributeTable attr = ((SignerInformation)s.getSignerInfos().getSigners().iterator().next()).getSignedAttributes(); Attribute a = attr.get(CMSAttributes.messageDigest); byte[] contentDigest = ASN1OctetString.getInstance(a.getAttrValues().getObjectAt(0)).getOctets(); mp = (MimeMultipart)m.getContent(); ContentType contentType = new ContentType(mp.getContentType()); String boundary = "--" + contentType.getParameter("boundary"); ByteArrayOutputStream bOut = new ByteArrayOutputStream(); LineOutputStream lOut = new LineOutputStream(bOut); Enumeration headers = m.getAllHeaderLines(); while (headers.hasMoreElements()) { lOut.writeln((String)headers.nextElement()); } lOut.writeln(); // CRLF separator lOut.writeln(boundary); writePart(mp.getBodyPart(0), bOut); lOut.writeln(); // CRLF terminator lOut.writeln(boundary); writePart(mp.getBodyPart(1), bOut); lOut.writeln(); lOut.writeln(boundary + "--"); MessageDigest dig = MessageDigest.getInstance("SHA1", "BC"); assertTrue(Arrays.equals(contentDigest, dig.digest(bOut.toByteArray()))); } private void writePart(BodyPart part, ByteArrayOutputStream bOut) throws MessagingException, IOException { if (part.getHeader("Content-Transfer-Encoding")[0].equals("binary")) { part.writeTo(bOut); } else { part.writeTo(new CRLFOutputStream(bOut)); } } public void testSHA1WithRSA() throws Exception { MimeMultipart smm = generateMultiPartRsa(SMIMESignedGenerator.DIGEST_SHA1, msg, SMIMESignedGenerator.RFC3851_MICALGS); SMIMESigned s = new SMIMESigned(smm); verifyMessageBytes(msg, s.getContent()); verifySigners(s.getCertificatesAndCRLs("Collection", "BC"), s.getSignerInfos()); } public void testSHA1WithRSAAddSigners() throws Exception { MimeMultipart smm = generateMultiPartRsa(SMIMESignedGenerator.DIGEST_SHA1, msg, SMIMESignedGenerator.RFC3851_MICALGS); SMIMESigned s = new SMIMESigned(smm); List certList = new ArrayList(); certList.add(_signCert); certList.add(_origCert); CertStore certs = CertStore.getInstance("Collection", new CollectionCertStoreParameters(certList), "BC"); SMIMESignedGenerator gen = new SMIMESignedGenerator(); gen.addSigners(s.getSignerInfos()); gen.addCertificatesAndCRLs(certs); SMIMESigned newS = new SMIMESigned(gen.generate(msg, "BC")); verifyMessageBytes(msg, newS.getContent()); verifySigners(newS.getCertificatesAndCRLs("Collection", "BC"), newS.getSignerInfos()); } public void testMD5WithRSAAddSignersSHA1() throws Exception { MimeMultipart smm = generateMultiPartRsa(SMIMESignedGenerator.DIGEST_SHA1, msg, SMIMESignedGenerator.RFC3851_MICALGS); SMIMESigned s = new SMIMESigned(smm); List certList = new ArrayList(); certList.add(_signCert); certList.add(_origCert); CertStore certs = CertStore.getInstance("Collection", new CollectionCertStoreParameters(certList), "BC"); SMIMESignedGenerator gen = new SMIMESignedGenerator(); gen.addSigner(_signKP.getPrivate(), _signCert, SMIMESignedGenerator.DIGEST_MD5); gen.addSigners(s.getSignerInfos()); gen.addCertificatesAndCRLs(certs); smm = gen.generate(msg, "BC"); SMIMESigned newS = new SMIMESigned(gen.generate(msg, "BC")); verifyMessageBytes(msg, newS.getContent()); verifySigners(newS.getCertificatesAndCRLs("Collection", "BC"), newS.getSignerInfos()); assertEquals("\"md5,sha-1\"", getMicAlg(smm)); } public void testSHA1WithRSACanonicalization() throws Exception { Date testTime = new Date(); MimeMultipart smm = generateMultiPartRsa(SMIMESignedGenerator.DIGEST_SHA1, msg, testTime, SMIMESignedGenerator.RFC3851_MICALGS); byte[] sig1 = getEncodedStream(smm); smm = generateMultiPartRsa(SMIMESignedGenerator.DIGEST_SHA1, msgR, testTime, SMIMESignedGenerator.RFC3851_MICALGS); byte[] sig2 = getEncodedStream(smm); assertTrue(Arrays.equals(sig1, sig2)); smm = generateMultiPartRsa(SMIMESignedGenerator.DIGEST_SHA1, msgRN, testTime, SMIMESignedGenerator.RFC3851_MICALGS); byte[] sig3 = getEncodedStream(smm); assertTrue(Arrays.equals(sig1, sig3)); } private byte[] getEncodedStream(MimeMultipart smm) throws IOException, MessagingException { ByteArrayOutputStream bOut = new ByteArrayOutputStream(); smm.getBodyPart(1).writeTo(bOut); return bOut.toByteArray(); } public void testSHA1WithRSAEncapsulated() throws Exception { MimeBodyPart res = generateEncapsulatedRsa(SMIMESignedGenerator.DIGEST_SHA1, msg); SMIMESigned s = new SMIMESigned(res); verifyMessageBytes(msg, s.getContent()); verifySigners(s.getCertificatesAndCRLs("Collection", "BC"), s.getSignerInfos()); } public void testSHA1WithRSAEncapsulatedParser() throws Exception { MimeBodyPart res = generateEncapsulatedRsa(SMIMESignedGenerator.DIGEST_SHA1, msg); SMIMESignedParser s = new SMIMESignedParser(res); FileBackedMimeBodyPart content = (FileBackedMimeBodyPart)s.getContent(); verifyMessageBytes(msg, content); content.dispose(); verifySigners(s.getCertificatesAndCRLs("Collection", "BC"), s.getSignerInfos()); s.close(); } public void testSHA1WithRSAEncapsulatedParserAndFile() throws Exception { File tmp = File.createTempFile("bcTest", ".mime"); MimeBodyPart res = generateEncapsulatedRsa(SMIMESignedGenerator.DIGEST_SHA1, msg); SMIMESignedParser s = new SMIMESignedParser(res, tmp); FileBackedMimeBodyPart content = (FileBackedMimeBodyPart)s.getContent(); verifyMessageBytes(msg, s.getContent()); verifySigners(s.getCertificatesAndCRLs("Collection", "BC"), s.getSignerInfos()); assertTrue(tmp.exists()); s.close(); content.dispose(); assertFalse(tmp.exists()); } public void testMD5WithRSA() throws Exception { MimeMultipart smm = generateMultiPartRsa(SMIMESignedGenerator.DIGEST_MD5, msg, SMIMESignedGenerator.RFC3851_MICALGS); SMIMESigned s = new SMIMESigned(smm); assertEquals("md5", getMicAlg(smm)); assertEquals(getDigestOid(s.getSignerInfos()), PKCSObjectIdentifiers.md5.toString()); verifyMessageBytes(msg, s.getContent()); verifySigners(s.getCertificatesAndCRLs("Collection", "BC"), s.getSignerInfos()); } public void testSHA224WithRSA() throws Exception { MimeMultipart smm = generateMultiPartRsa(SMIMESignedGenerator.DIGEST_SHA224, msg, SMIMESignedGenerator.RFC3851_MICALGS); SMIMESigned s = new SMIMESigned(smm); assertEquals("sha224", getMicAlg(smm)); assertEquals(getDigestOid(s.getSignerInfos()), NISTObjectIdentifiers.id_sha224.toString()); verifyMessageBytes(msg, s.getContent()); verifySigners(s.getCertificatesAndCRLs("Collection", "BC"), s.getSignerInfos()); } public void testSHA256WithRSA() throws Exception { MimeMultipart smm = generateMultiPartRsa(SMIMESignedGenerator.DIGEST_SHA256, msg, SMIMESignedGenerator.RFC3851_MICALGS); SMIMESigned s = new SMIMESigned(smm); assertEquals("sha256", getMicAlg(smm)); assertEquals(getDigestOid(s.getSignerInfos()), NISTObjectIdentifiers.id_sha256.toString()); verifyMessageBytes(msg, s.getContent()); verifySigners(s.getCertificatesAndCRLs("Collection", "BC"), s.getSignerInfos()); } public void testSHA384WithRSA() throws Exception { MimeMultipart smm = generateMultiPartRsa(SMIMESignedGenerator.DIGEST_SHA384, msg, SMIMESignedGenerator.RFC3851_MICALGS); SMIMESigned s = new SMIMESigned(smm); assertEquals("sha384", getMicAlg(smm)); assertEquals(getDigestOid(s.getSignerInfos()), NISTObjectIdentifiers.id_sha384.toString()); verifyMessageBytes(msg, s.getContent()); verifySigners(s.getCertificatesAndCRLs("Collection", "BC"), s.getSignerInfos()); } public void testSHA512WithRSA() throws Exception { MimeMultipart smm = generateMultiPartRsa(SMIMESignedGenerator.DIGEST_SHA512, msg, SMIMESignedGenerator.RFC3851_MICALGS); SMIMESigned s = new SMIMESigned(smm); assertEquals("sha512", getMicAlg(smm)); assertEquals(getDigestOid(s.getSignerInfos()), NISTObjectIdentifiers.id_sha512.toString()); verifyMessageBytes(msg, s.getContent()); verifySigners(s.getCertificatesAndCRLs("Collection", "BC"), s.getSignerInfos()); } public void testRIPEMD160WithRSA() throws Exception { MimeMultipart smm = generateMultiPartRsa(SMIMESignedGenerator.DIGEST_RIPEMD160, msg, SMIMESignedGenerator.RFC3851_MICALGS); SMIMESigned s = new SMIMESigned(smm); assertEquals("unknown", getMicAlg(smm)); assertEquals(getDigestOid(s.getSignerInfos()), TeleTrusTObjectIdentifiers.ripemd160.toString()); verifyMessageBytes(msg, s.getContent()); verifySigners(s.getCertificatesAndCRLs("Collection", "BC"), s.getSignerInfos()); } public void testGOST3411WithGOST3410() throws Exception { MimeMultipart smm = generateMultiPartGost(msg); SMIMESigned s = new SMIMESigned(smm); assertEquals("gostr3411-94", getMicAlg(smm)); assertEquals(getDigestOid(s.getSignerInfos()), CryptoProObjectIdentifiers.gostR3411.getId()); verifyMessageBytes(msg, s.getContent()); verifySigners(s.getCertificatesAndCRLs("Collection", "BC"), s.getSignerInfos()); } public void testGOST3411WithECGOST3410() throws Exception { MimeMultipart smm = generateMultiPartECGost(msg); SMIMESigned s = new SMIMESigned(smm); assertEquals("gostr3411-94", getMicAlg(smm)); assertEquals(getDigestOid(s.getSignerInfos()), CryptoProObjectIdentifiers.gostR3411.getId()); verifyMessageBytes(msg, s.getContent()); verifySigners(s.getCertificatesAndCRLs("Collection", "BC"), s.getSignerInfos()); } public void testSHA224WithRSAParser() throws Exception { MimeMultipart smm = generateMultiPartRsa(SMIMESignedGenerator.DIGEST_SHA224, msg, SMIMESignedGenerator.RFC3851_MICALGS); SMIMESignedParser s = new SMIMESignedParser(smm); CertStore certs = s.getCertificatesAndCRLs("Collection", "BC"); assertEquals(getDigestOid(s.getSignerInfos()), NISTObjectIdentifiers.id_sha224.toString()); verifyMessageBytes(msg, s.getContent()); verifySigners(certs, s.getSignerInfos()); } public void testSHA224WithRSAParserEncryptedWithDES() throws Exception { List certList = new ArrayList(); certList.add(_signCert); certList.add(_origCert); CertStore certs = CertStore.getInstance("Collection", new CollectionCertStoreParameters(certList), "BC"); ASN1EncodableVector signedAttrs = generateSignedAttributes(); SMIMESignedGenerator gen = new SMIMESignedGenerator(); gen.addSigner(_signKP.getPrivate(), _signCert, SMIMESignedGenerator.DIGEST_SHA224, new AttributeTable(signedAttrs), null); gen.addCertificatesAndCRLs(certs); MimeMultipart smm = gen.generate(msg, "BC"); SMIMESignedParser s = new SMIMESignedParser(smm); certs = s.getCertificatesAndCRLs("Collection", "BC"); assertEquals(getDigestOid(s.getSignerInfos()), NISTObjectIdentifiers.id_sha224.toString()); verifyMessageBytes(msg, s.getContent()); verifySigners(certs, s.getSignerInfos()); } public void testSHA1withDSA() throws Exception { dsaSignKP = CMSTestUtil.makeDsaKeyPair(); dsaSignCert = CMSTestUtil.makeCertificate(dsaSignKP, _origDN, dsaSignKP, _origDN); dsaOrigKP = CMSTestUtil.makeDsaKeyPair(); dsaOrigCert = CMSTestUtil.makeCertificate(dsaOrigKP, _signDN, dsaSignKP, _origDN); List certList = new ArrayList(); certList.add(dsaOrigCert); certList.add(dsaSignCert); CertStore certs = CertStore.getInstance("Collection", new CollectionCertStoreParameters(certList), "BC"); SMIMESignedGenerator gen = new SMIMESignedGenerator(); gen.addSigner(dsaOrigKP.getPrivate(), dsaOrigCert, SMIMESignedGenerator.DIGEST_SHA1); gen.addCertificatesAndCRLs(certs); MimeMultipart smm = gen.generate(msg, "BC"); SMIMESigned s = new SMIMESigned(smm); verifyMessageBytes(msg, s.getContent()); verifySigners(s.getCertificatesAndCRLs("Collection", "BC"), s.getSignerInfos()); } public void testSHA256WithRSABinary() throws Exception { MimeBodyPart msg = generateBinaryPart(); MimeMultipart smm = generateMultiPartRsa(SMIMESignedGenerator.DIGEST_SHA256, msg, SMIMESignedGenerator.RFC3851_MICALGS); SMIMESigned s = new SMIMESigned(smm); verifyMessageBytes(msg, s.getContent()); verifySigners(s.getCertificatesAndCRLs("Collection", "BC"), s.getSignerInfos()); } public void testSHA256WithRSABinaryWithParser() throws Exception { MimeBodyPart msg = generateBinaryPart(); MimeMultipart smm = generateMultiPartRsa(SMIMESignedGenerator.DIGEST_SHA256, msg, SMIMESignedGenerator.RFC3851_MICALGS); SMIMESignedParser s = new SMIMESignedParser(smm); verifyMessageBytes(msg, s.getContent()); verifySigners(s.getCertificatesAndCRLs("Collection", "BC"), s.getSignerInfos()); } public void testWithAttributeCertificate() throws Exception { List certList = new ArrayList(); certList.add(_signCert); certList.add(_origCert); CertStore certs = CertStore.getInstance("Collection", new CollectionCertStoreParameters(certList), "BC"); ASN1EncodableVector signedAttrs = generateSignedAttributes(); SMIMESignedGenerator gen = new SMIMESignedGenerator(); gen.addSigner(_signKP.getPrivate(), _signCert, SMIMESignedGenerator.DIGEST_SHA256, new AttributeTable(signedAttrs), null); gen.addCertificatesAndCRLs(certs); X509AttributeCertificate attrCert = CMSTestUtil.getAttributeCertificate(); X509Store store = X509Store.getInstance("AttributeCertificate/Collection", new X509CollectionStoreParameters(Collections.singleton(attrCert)), "BC"); gen.addAttributeCertificates(store); SMIMESigned s = new SMIMESigned(gen.generateEncapsulated(msg, "BC")); verifyMessageBytes(msg, s.getContent()); verifySigners(s.getCertificatesAndCRLs("Collection", "BC"), s.getSignerInfos()); X509Store attrCerts = s.getAttributeCertificates("Collection", "BC"); assertTrue(attrCerts.getMatches(null).contains(attrCert)); } private void rsaPSSTest(String digestOID) throws Exception { MimeMultipart smm = generateMultiPartRsaPSS(digestOID, msg, null); SMIMESignedParser s = new SMIMESignedParser(smm); CertStore certs = s.getCertificatesAndCRLs("Collection", "BC"); assertEquals(getDigestOid(s.getSignerInfos()), digestOID); verifyMessageBytes(msg, s.getContent()); verifySigners(certs, s.getSignerInfos()); } private MimeBodyPart generateBinaryPart() throws MessagingException { byte[] content = new byte[] { 1, 2, 3, 4, 5, 6, 7, 8, 9, 0, 10, 11, 12, 13, 14, 10, 10, 15, 16 }; InternetHeaders ih = new InternetHeaders(); ih.setHeader("Content-Transfer-Encoding", "binary"); return new MimeBodyPart(ih, content); } private MimeMultipart generateMultiPartRsa( String digestOid, MimeBodyPart msg, Date signingTime, Map micalgs) throws Exception { List certList = new ArrayList(); certList.add(_signCert); certList.add(_origCert); CertStore certs = CertStore.getInstance("Collection", new CollectionCertStoreParameters(certList), "BC"); ASN1EncodableVector signedAttrs = generateSignedAttributes(); if (signingTime != null) { signedAttrs.add(new Attribute(CMSAttributes.signingTime, new DERSet(new Time(signingTime)))); } SMIMESignedGenerator gen = new SMIMESignedGenerator(micalgs); gen.addSigner(_signKP.getPrivate(), _signCert, digestOid, new AttributeTable(signedAttrs), null); gen.addCertificatesAndCRLs(certs); return gen.generate(msg, "BC"); } private MimeMultipart generateMultiPartRsaPSS( String digestOid, MimeBodyPart msg, Date signingTime) throws Exception { List certList = new ArrayList(); certList.add(_signCert); certList.add(_origCert); CertStore certs = CertStore.getInstance("Collection", new CollectionCertStoreParameters(certList), "BC"); ASN1EncodableVector signedAttrs = generateSignedAttributes(); if (signingTime != null) { signedAttrs.add(new Attribute(CMSAttributes.signingTime, new DERSet(new Time(signingTime)))); } SMIMESignedGenerator gen = new SMIMESignedGenerator(); gen.addSigner(_signKP.getPrivate(), _signCert, SMIMESignedGenerator.ENCRYPTION_RSA_PSS, digestOid, new AttributeTable(signedAttrs), null); gen.addCertificatesAndCRLs(certs); return gen.generate(msg, "BC"); } private MimeMultipart generateMultiPartGost( MimeBodyPart msg) throws Exception { List certList = new ArrayList(); certList.add(_signCert); certList.add(_signGostCert); CertStore certs = CertStore.getInstance("Collection", new CollectionCertStoreParameters(certList), "BC"); SMIMESignedGenerator gen = new SMIMESignedGenerator(); gen.addSigner(_signGostKP.getPrivate(), _signGostCert, SMIMESignedGenerator.DIGEST_GOST3411); gen.addCertificatesAndCRLs(certs); return gen.generate(msg, "BC"); } private MimeMultipart generateMultiPartECGost( MimeBodyPart msg) throws Exception { List certList = new ArrayList(); certList.add(_signCert); certList.add(_signEcGostCert); CertStore certs = CertStore.getInstance("Collection", new CollectionCertStoreParameters(certList), "BC"); SMIMESignedGenerator gen = new SMIMESignedGenerator(); gen.addSigner(_signEcGostKP.getPrivate(), _signEcGostCert, SMIMESignedGenerator.DIGEST_GOST3411); gen.addCertificatesAndCRLs(certs); return gen.generate(msg, "BC"); } private MimeMultipart generateMultiPartRsa(String digestOid, MimeBodyPart msg, Map micalgs) throws Exception { return generateMultiPartRsa(digestOid, msg, null, micalgs); } private MimeBodyPart generateEncapsulatedRsa(String digestOid, MimeBodyPart msg) throws Exception { List certList = new ArrayList(); certList.add(_signCert); certList.add(_origCert); CertStore certs = CertStore.getInstance("Collection", new CollectionCertStoreParameters(certList), "BC"); ASN1EncodableVector signedAttrs = generateSignedAttributes(); SMIMESignedGenerator gen = new SMIMESignedGenerator(); gen.addSigner(_signKP.getPrivate(), _signCert, digestOid, new AttributeTable(signedAttrs), null); gen.addCertificatesAndCRLs(certs); return gen.generateEncapsulated(msg, "BC"); } public void testCertificateManagement() throws Exception { List certList = new ArrayList(); certList.add(_signCert); certList.add(_origCert); CertStore certs = CertStore.getInstance("Collection", new CollectionCertStoreParameters(certList), "BC"); SMIMESignedGenerator gen = new SMIMESignedGenerator(); gen.addCertificatesAndCRLs(certs); MimeBodyPart smm = gen.generateCertificateManagement("BC"); SMIMESigned s = new SMIMESigned(smm); certs = s.getCertificatesAndCRLs("Collection", "BC"); assertEquals(2, certs.getCertificates(null).size()); } public void testMimeMultipart() throws Exception { MimeBodyPart m = createMultipartMessage(); List certList = new ArrayList(); certList.add(_signCert); certList.add(_origCert); CertStore certs = CertStore.getInstance("Collection", new CollectionCertStoreParameters(certList), "BC"); ASN1EncodableVector signedAttrs = generateSignedAttributes(); SMIMESignedGenerator gen = new SMIMESignedGenerator("binary"); gen.addSigner(_signKP.getPrivate(), _signCert, SMIMESignedGenerator.DIGEST_SHA1, new AttributeTable(signedAttrs), null); gen.addCertificatesAndCRLs(certs); MimeMultipart mm = gen.generate(m, "BC"); SMIMESigned s = new SMIMESigned(mm); verifySigners(s.getCertificatesAndCRLs("Collection", "BC"), s.getSignerInfos()); byte[] contentDigest = (byte[])gen.getGeneratedDigests().get(SMIMESignedGenerator.DIGEST_SHA1); AttributeTable table = ((SignerInformation)s.getSignerInfos().getSigners().iterator().next()).getSignedAttributes(); Attribute hash = table.get(CMSAttributes.messageDigest); assertTrue(MessageDigest.isEqual(contentDigest, ((ASN1OctetString)hash.getAttrValues().getObjectAt(0)).getOctets())); } public void testMimeMultipartBinaryReader() throws Exception { MimeBodyPart m = createMultipartMessage(); List certList = new ArrayList(); certList.add(_signCert); certList.add(_origCert); CertStore certs = CertStore.getInstance("Collection", new CollectionCertStoreParameters(certList), "BC"); ASN1EncodableVector signedAttrs = generateSignedAttributes(); SMIMESignedGenerator gen = new SMIMESignedGenerator("binary"); gen.addSigner(_signKP.getPrivate(), _signCert, SMIMESignedGenerator.DIGEST_SHA1, new AttributeTable(signedAttrs), null); gen.addCertificatesAndCRLs(certs); MimeMultipart mm = gen.generate(m, "BC"); SMIMESigned s = new SMIMESigned(mm, "binary"); verifySigners(s.getCertificatesAndCRLs("Collection", "BC"), s.getSignerInfos()); } public void testMimeMultipartBinaryParser() throws Exception { MimeBodyPart m = createMultipartMessage(); List certList = new ArrayList(); certList.add(_signCert); certList.add(_origCert); CertStore certs = CertStore.getInstance("Collection", new CollectionCertStoreParameters(certList), "BC"); ASN1EncodableVector signedAttrs = generateSignedAttributes(); SMIMESignedGenerator gen = new SMIMESignedGenerator("binary"); gen.addSigner(_signKP.getPrivate(), _signCert, SMIMESignedGenerator.DIGEST_SHA1, new AttributeTable(signedAttrs), null); gen.addCertificatesAndCRLs(certs); MimeMultipart mm = gen.generate(m, "BC"); SMIMESignedParser s = new SMIMESignedParser(mm, "binary"); verifySigners(s.getCertificatesAndCRLs("Collection", "BC"), s.getSignerInfos()); } public void testMimeMultipartBinaryParserGetMimeContent() throws Exception { MimeBodyPart m = createMultipartMessage(); List certList = new ArrayList(); certList.add(_signCert); certList.add(_origCert); CertStore certs = CertStore.getInstance("Collection", new CollectionCertStoreParameters(certList), "BC"); ASN1EncodableVector signedAttrs = generateSignedAttributes(); SMIMESignedGenerator gen = new SMIMESignedGenerator("binary"); gen.addSigner(_signKP.getPrivate(), _signCert, SMIMESignedGenerator.DIGEST_SHA1, new AttributeTable(signedAttrs), null); gen.addCertificatesAndCRLs(certs); MimeMultipart mm = gen.generate(m, "BC"); SMIMESignedParser s = new SMIMESignedParser(mm, "binary"); verifySigners(s.getCertificatesAndCRLs("Collection", "BC"), s.getSignerInfos()); MimeMessage bp = s.getContentAsMimeMessage(Session.getDefaultInstance(new Properties())); } private MimeBodyPart createMultipartMessage() throws MessagingException { MimeBodyPart msg1 = new MimeBodyPart(); msg1.setText("Hello part 1!\n"); MimeBodyPart msg2 = new MimeBodyPart(); msg2.setText("Hello part 2!\n"); MimeMultipart mp = new MimeMultipart(); mp.addBodyPart(msg1); mp.addBodyPart(msg2); MimeBodyPart m = new MimeBodyPart(); m.setContent(mp); return m; } public void testQuotable() throws Exception { MimeMessage message = loadMessage("quotable.message"); SMIMESigned s = new SMIMESigned((MimeMultipart)message.getContent()); verifySigners(s.getCertificatesAndCRLs("Collection", "BC"), s.getSignerInfos()); } public void testQuotableParser() throws Exception { MimeMessage message = loadMessage("quotable.message"); SMIMESignedParser s = new SMIMESignedParser((MimeMultipart)message.getContent()); verifySigners(s.getCertificatesAndCRLs("Collection", "BC"), s.getSignerInfos()); } public void testEmbeddedMulti() throws Exception { MimeMessage message = loadMessage("embeddedmulti.message"); SMIMESigned s = new SMIMESigned((MimeMultipart)message.getContent()); verifySigners(s.getCertificatesAndCRLs("Collection", "BC"), s.getSignerInfos()); } public void testEmbeddedMultiParser() throws Exception { MimeMessage message = loadMessage("embeddedmulti.message"); SMIMESignedParser s = new SMIMESignedParser((MimeMultipart)message.getContent()); verifySigners(s.getCertificatesAndCRLs("Collection", "BC"), s.getSignerInfos()); } public void testMultiAlternative() throws Exception { MimeMessage message = loadMessage("multi-alternative.eml"); SMIMESigned s = new SMIMESigned((MimeMultipart)message.getContent()); verifySigners(s.getCertificatesAndCRLs("Collection", "BC"), s.getSignerInfos()); } public void testExtraNlInPostamble() throws Exception { MimeMessage message = loadMessage("extra-nl.eml"); SMIMESigned s = new SMIMESigned((MimeMultipart)message.getContent()); verifySigners(s.getCertificatesAndCRLs("Collection", "BC"), s.getSignerInfos()); } public void testSignAttachmentOnly() throws Exception { MimeMessage m = loadMessage("attachonly.eml"); List certList = new ArrayList(); certList.add(_signCert); certList.add(_origCert); CertStore certs = CertStore.getInstance("Collection", new CollectionCertStoreParameters(certList), "BC"); ASN1EncodableVector signedAttrs = generateSignedAttributes(); SMIMESignedGenerator gen = new SMIMESignedGenerator("binary"); gen.addSigner(_signKP.getPrivate(), _signCert, SMIMESignedGenerator.DIGEST_SHA1, new AttributeTable(signedAttrs), null); gen.addCertificatesAndCRLs(certs); MimeMultipart mm = gen.generate(m, "BC"); SMIMESigned s = new SMIMESigned(mm); verifySigners(s.getCertificatesAndCRLs("Collection", "BC"), s.getSignerInfos()); SMIMESignedParser sp = new SMIMESignedParser(mm); verifySigners(sp.getCertificatesAndCRLs("Collection", "BC"), sp.getSignerInfos()); } public void testMultiAlternativeParser() throws Exception { MimeMessage message = loadMessage("multi-alternative.eml"); SMIMESignedParser s = new SMIMESignedParser((MimeMultipart)message.getContent()); verifySigners(s.getCertificatesAndCRLs("Collection", "BC"), s.getSignerInfos()); } public void testBasicAS2() throws Exception { MimeMessage message = loadMessage("basicAS2.message"); SMIMESigned s = new SMIMESigned((MimeMultipart)message.getContent()); verifySigners(s.getCertificatesAndCRLs("Collection", "BC"), s.getSignerInfos()); } public void testBasicAS2Parser() throws Exception { MimeMessage message = loadMessage("basicAS2.message"); SMIMESignedParser s = new SMIMESignedParser((MimeMultipart)message.getContent()); verifySigners(s.getCertificatesAndCRLs("Collection", "BC"), s.getSignerInfos()); } private String getDigestOid(SignerInformationStore s) { return ((SignerInformation)s.getSigners().iterator().next()).getDigestAlgOID(); } private void verifySigners(CertStore certs, SignerInformationStore signers) throws Exception { Collection c = signers.getSigners(); Iterator it = c.iterator(); while (it.hasNext()) { SignerInformation signer = (SignerInformation)it.next(); Collection certCollection = certs.getCertificates(selectorConverter.getCertSelector(signer.getSID())); Iterator certIt = certCollection.iterator(); X509Certificate cert = (X509Certificate)certIt.next(); assertEquals(true, signer.verify(cert, "BC")); } } private void verifyMessageBytes(MimeBodyPart a, MimeBodyPart b) throws Exception { ByteArrayOutputStream bOut1 = new ByteArrayOutputStream(); a.writeTo(bOut1); bOut1.close(); ByteArrayOutputStream bOut2 = new ByteArrayOutputStream(); b.writeTo(bOut2); bOut2.close(); assertEquals(true, Arrays.equals(bOut1.toByteArray(), bOut2.toByteArray())); } private ASN1EncodableVector generateSignedAttributes() { ASN1EncodableVector signedAttrs = new ASN1EncodableVector(); SMIMECapabilityVector caps = new SMIMECapabilityVector(); caps.addCapability(SMIMECapability.dES_EDE3_CBC); caps.addCapability(SMIMECapability.rC2_CBC, 128); caps.addCapability(SMIMECapability.dES_CBC); signedAttrs.add(new SMIMECapabilitiesAttribute(caps)); return signedAttrs; } private MimeMessage loadMessage(String name) throws MessagingException, FileNotFoundException { Session session = Session.getDefaultInstance(System.getProperties(), null); return new MimeMessage(session, getClass().getResourceAsStream(name)); } private MimeBodyPart createTemplate(String contentType, String contentTransferEncoding) throws UnsupportedEncodingException, MessagingException { byte[] content = "\n\n \n\n\n".getBytes("US-ASCII"); InternetHeaders ih = new InternetHeaders(); ih.setHeader("Content-Type", contentType); ih.setHeader("Content-Transfer-Encoding", contentTransferEncoding); return new MimeBodyPart(ih, content); } private String getMicAlg(MimeMultipart mm) { String contentType = mm.getContentType(); String micAlg = contentType.substring(contentType.indexOf("micalg=") + 7); return micAlg.substring(0, micAlg.indexOf(';')); } } bouncycastle-1.49.orig/test/src/org/bouncycastle/i18n/0000755000175000017500000000000012152033550022234 5ustar ebourgebourgbouncycastle-1.49.orig/test/src/org/bouncycastle/i18n/test/0000755000175000017500000000000012152033550023213 5ustar ebourgebourgbouncycastle-1.49.orig/test/src/org/bouncycastle/i18n/test/LocalizedMessageTest.java0000644000175000017500000001553110621263377030151 0ustar ebourgebourgpackage org.bouncycastle.i18n.test; import junit.framework.TestCase; import org.bouncycastle.i18n.LocaleString; import org.bouncycastle.i18n.LocalizedMessage; import org.bouncycastle.i18n.MissingEntryException; import org.bouncycastle.i18n.filter.HTMLFilter; import org.bouncycastle.i18n.filter.TrustedInput; import java.io.UnsupportedEncodingException; import java.net.MalformedURLException; import java.net.URL; import java.net.URLClassLoader; import java.util.Date; import java.util.Locale; import java.util.TimeZone; public class LocalizedMessageTest extends TestCase { private static final String TEST_RESOURCE = "org.bouncycastle.i18n.test.I18nTestMessages"; private static final String UTF8_TEST_RESOURCE = "org.bouncycastle.i18n.test.I18nUTF8TestMessages"; /* * test message id's */ private static final String timeTestId = "time"; private static final String argsTestId = "arguments"; private static final String localeTestId = "hello"; private static final String missingTestId = "missing"; private static final String filterTestId = "filter"; private static final String utf8TestId = "utf8"; /* * Test method for 'org.bouncycastle.i18n.LocalizedMessage.getEntry(String, * Locale, TimeZone)' */ public void testGetEntry() { LocalizedMessage msg; // test different locales msg = new LocalizedMessage(TEST_RESOURCE, localeTestId); assertEquals("Hello world.", msg.getEntry("text", Locale.ENGLISH, TimeZone.getDefault())); assertEquals("Hallo Welt.", msg.getEntry("text", Locale.GERMAN, TimeZone.getDefault())); // test arguments Object[] args = new Object[] { "Nobody" }; msg = new LocalizedMessage(TEST_RESOURCE, argsTestId, args); assertEquals("My name is Nobody.", msg.getEntry("text", Locale.ENGLISH, TimeZone.getDefault())); assertEquals("Mein Name ist Nobody.", msg.getEntry("text", Locale.GERMAN, TimeZone.getDefault())); // test timezones // test date 17. Aug. 13:12:00 GMT Date testDate = new Date(1155820320000l); args = new Object[] { new TrustedInput(testDate) }; msg = new LocalizedMessage(TEST_RESOURCE, timeTestId, args); assertEquals("It's 1:12:00 PM GMT at Aug 17, 2006.", msg.getEntry( "text", Locale.ENGLISH, TimeZone.getTimeZone("GMT"))); assertEquals("Es ist 13.12 Uhr GMT am 17.08.2006.", msg.getEntry( "text", Locale.GERMAN, TimeZone.getTimeZone("GMT"))); // test time with filter args = new Object[] { new TrustedInput(testDate) }; msg = new LocalizedMessage(TEST_RESOURCE, timeTestId, args); msg.setFilter(new HTMLFilter()); assertEquals("It's 1:12:00 PM GMT at Aug 17, 2006.", msg.getEntry( "text", Locale.ENGLISH, TimeZone.getTimeZone("GMT"))); assertEquals("Es ist 13.12 Uhr GMT am 17.08.2006.", msg.getEntry( "text", Locale.GERMAN, TimeZone.getTimeZone("GMT"))); // test number args = new Object[] { new TrustedInput(new Float(0.2)) }; msg = new LocalizedMessage(TEST_RESOURCE, "number", args); assertEquals("20%", msg.getEntry("text", Locale.ENGLISH, TimeZone.getDefault())); // test filters String untrusted = ""; args = new Object[] { untrusted }; msg = new LocalizedMessage(TEST_RESOURCE,filterTestId,args); msg.setFilter(new HTMLFilter()); assertEquals("The following part should contain no HTML tags: " + "<script>doBadThings()</script>", msg.getEntry("text",Locale.ENGLISH, TimeZone.getDefault())); // test missing entry msg = new LocalizedMessage(TEST_RESOURCE, missingTestId); try { String text = msg.getEntry("text", Locale.UK, TimeZone .getDefault()); fail(); } catch (MissingEntryException e) { System.out.println(e.getDebugMsg()); } // test missing entry try { URLClassLoader cl = URLClassLoader.newInstance(new URL[] {new URL("file:///nonexistent/")}); msg = new LocalizedMessage(TEST_RESOURCE, missingTestId); msg.setClassLoader(cl); try { String text = msg.getEntry("text", Locale.UK, TimeZone .getDefault()); fail(); } catch (MissingEntryException e) { System.out.println(e.getDebugMsg()); } } catch (MalformedURLException e) { } // test utf8 try { msg = new LocalizedMessage(UTF8_TEST_RESOURCE, utf8TestId, "UTF-8"); assertEquals("some umlauts äöüèéà", msg.getEntry("text", Locale.GERMAN, TimeZone.getDefault())); } catch (UnsupportedEncodingException e) { } } public void testLocalizedArgs() { LocaleString ls = new LocaleString(TEST_RESOURCE, "name"); // without filter Object[] args = new Object[] { ls }; LocalizedMessage msg = new LocalizedMessage(TEST_RESOURCE, argsTestId, args); assertEquals("My name is John.", msg.getEntry("text", Locale.ENGLISH, TimeZone.getDefault())); assertEquals("Mein Name ist Hans.", msg.getEntry("text", Locale.GERMAN, TimeZone.getDefault())); // with filter msg.setFilter(new HTMLFilter()); assertEquals("My name is John.", msg.getEntry("text", Locale.ENGLISH, TimeZone.getDefault())); assertEquals("Mein Name ist Hans.", msg.getEntry("text", Locale.GERMAN, TimeZone.getDefault())); // add extra args LocaleString lsExtra = new LocaleString(TEST_RESOURCE, "hello.text"); msg.setExtraArguments(new Object[] {" ", lsExtra}); assertEquals("My name is John. Hello world.", msg.getEntry("text", Locale.ENGLISH, TimeZone.getDefault())); assertEquals("Mein Name ist Hans. Hallo Welt.", msg.getEntry("text", Locale.GERMAN, TimeZone.getDefault())); // missing localized arg try { ls = new LocaleString(TEST_RESOURCE, "noname"); args = new Object[] { ls }; msg = new LocalizedMessage(TEST_RESOURCE, argsTestId, args); msg.getEntry("text", Locale.ENGLISH, TimeZone.getDefault()); fail(); } catch (MissingEntryException e) { assertEquals("Can't find entry noname in resource file org.bouncycastle.i18n.test.I18nTestMessages.", e.getMessage()); } } } bouncycastle-1.49.orig/test/src/org/bouncycastle/i18n/test/I18nUTF8TestMessages_de.properties0000644000175000017500000000004710574414726031536 0ustar ebourgebourg utf8.text = some umlauts äöüèéà bouncycastle-1.49.orig/test/src/org/bouncycastle/i18n/test/AllTests.java0000644000175000017500000000124510474276150025625 0ustar ebourgebourg package org.bouncycastle.i18n.test; import org.bouncycastle.i18n.filter.test.HTMLFilterTest; import org.bouncycastle.i18n.filter.test.SQLFilterTest; import junit.framework.Test; import junit.framework.TestCase; import junit.framework.TestSuite; public class AllTests extends TestCase { public static void main (String[] args) { junit.textui.TestRunner.run (suite()); } public static Test suite() { TestSuite suite = new TestSuite("i18n tests"); suite.addTestSuite(LocalizedMessageTest.class); suite.addTestSuite(HTMLFilterTest.class); suite.addTestSuite(SQLFilterTest.class); return suite; } } bouncycastle-1.49.orig/test/src/org/bouncycastle/i18n/test/I18nTestMessages_en.properties0000644000175000017500000000033510621263377031076 0ustar ebourgebourg time.text = It''s {0,time,full} at {0,date}. hello.text = Hello world. arguments.text = My name is {0}. filter.text = The following part should contain no HTML tags: {0} number.text = {0,number,percent} name = John bouncycastle-1.49.orig/test/src/org/bouncycastle/i18n/test/I18nTestMessages_de.properties0000644000175000017500000000017310621263377031064 0ustar ebourgebourg time.text = Es ist {0,time,full} am {0,date}. hello.text = Hallo Welt. arguments.text = Mein Name ist {0}. name = Hans bouncycastle-1.49.orig/test/src/org/bouncycastle/i18n/filter/0000755000175000017500000000000012152033550023521 5ustar ebourgebourgbouncycastle-1.49.orig/test/src/org/bouncycastle/i18n/filter/test/0000755000175000017500000000000012152033550024500 5ustar ebourgebourgbouncycastle-1.49.orig/test/src/org/bouncycastle/i18n/filter/test/HTMLFilterTest.java0000644000175000017500000000154710474276150030136 0ustar ebourgebourgpackage org.bouncycastle.i18n.filter.test; import org.bouncycastle.i18n.filter.Filter; import org.bouncycastle.i18n.filter.HTMLFilter; import junit.framework.TestCase; public class HTMLFilterTest extends TestCase { private static final String test1 = "hello world"; private static final String test2 = ""; private static final String test3 = "javascript:attack()"; private static final String test4 = "\"hello\""; public void testDoFilter() { Filter dummy = new HTMLFilter(); assertEquals("No filtering", "hello world", dummy.doFilter(test1)); assertEquals("script tags", "<script></script>", dummy.doFilter(test2)); assertEquals("javascript link", "javascript:attack()", dummy.doFilter(test3)); assertEquals("", ""hello"", dummy.doFilter(test4)); } } bouncycastle-1.49.orig/test/src/org/bouncycastle/i18n/filter/test/SQLFilterTest.java0000644000175000017500000000073010474276150030022 0ustar ebourgebourg package org.bouncycastle.i18n.filter.test; import org.bouncycastle.i18n.filter.Filter; import org.bouncycastle.i18n.filter.SQLFilter; import junit.framework.TestCase; public class SQLFilterTest extends TestCase { private static final String test1 = "\'\"=-/\\;\r\n"; public void testDoFilter() { Filter filter = new SQLFilter(); assertEquals("encode special charaters","\\\'\\\"\\=\\-\\/\\\\\\;\\r\\n",filter.doFilter(test1)); } } bouncycastle-1.49.orig/test/src/org/bouncycastle/ocsp/0000755000175000017500000000000012152033550022421 5ustar ebourgebourgbouncycastle-1.49.orig/test/src/org/bouncycastle/ocsp/test/0000755000175000017500000000000012152033550023400 5ustar ebourgebourgbouncycastle-1.49.orig/test/src/org/bouncycastle/ocsp/test/OCSPTest.java0000644000175000017500000007723611735227237025703 0ustar ebourgebourgpackage org.bouncycastle.ocsp.test; import java.io.ByteArrayInputStream; import java.math.BigInteger; import java.security.KeyPair; import java.security.Security; import java.security.cert.X509Certificate; import java.util.Date; import java.util.Random; import java.util.Set; import java.util.Vector; import org.bouncycastle.asn1.ASN1Encodable; import org.bouncycastle.asn1.ASN1OctetString; import org.bouncycastle.asn1.DEROctetString; import org.bouncycastle.asn1.ocsp.OCSPObjectIdentifiers; import org.bouncycastle.asn1.x509.GeneralName; import org.bouncycastle.asn1.x509.X509Extension; import org.bouncycastle.asn1.x509.X509Extensions; import org.bouncycastle.asn1.x509.X509Name; import org.bouncycastle.jce.X509Principal; import org.bouncycastle.jce.provider.BouncyCastleProvider; import org.bouncycastle.ocsp.BasicOCSPResp; import org.bouncycastle.ocsp.BasicOCSPRespGenerator; import org.bouncycastle.ocsp.CertificateID; import org.bouncycastle.ocsp.CertificateStatus; import org.bouncycastle.ocsp.OCSPReq; import org.bouncycastle.ocsp.OCSPReqGenerator; import org.bouncycastle.ocsp.OCSPResp; import org.bouncycastle.ocsp.OCSPRespGenerator; import org.bouncycastle.ocsp.Req; import org.bouncycastle.ocsp.SingleResp; import org.bouncycastle.util.encoders.Base64; import org.bouncycastle.util.test.SimpleTest; import org.bouncycastle.x509.extension.X509ExtensionUtil; public class OCSPTest extends SimpleTest { byte[] testResp1 = Base64.decode( "MIIFnAoBAKCCBZUwggWRBgkrBgEFBQcwAQEEggWCMIIFfjCCARehgZ8wgZwx" + "CzAJBgNVBAYTAklOMRcwFQYDVQQIEw5BbmRocmEgcHJhZGVzaDESMBAGA1UE" + "BxMJSHlkZXJhYmFkMQwwCgYDVQQKEwNUQ1MxDDAKBgNVBAsTA0FUQzEeMBwG" + "A1UEAxMVVENTLUNBIE9DU1AgUmVzcG9uZGVyMSQwIgYJKoZIhvcNAQkBFhVv" + "Y3NwQHRjcy1jYS50Y3MuY28uaW4YDzIwMDMwNDAyMTIzNDU4WjBiMGAwOjAJ" + "BgUrDgMCGgUABBRs07IuoCWNmcEl1oHwIak1BPnX8QQUtGyl/iL9WJ1VxjxF" + "j0hAwJ/s1AcCAQKhERgPMjAwMjA4MjkwNzA5MjZaGA8yMDAzMDQwMjEyMzQ1" + "OFowDQYJKoZIhvcNAQEFBQADgYEAfbN0TCRFKdhsmvOdUoiJ+qvygGBzDxD/" + "VWhXYA+16AphHLIWNABR3CgHB3zWtdy2j7DJmQ/R7qKj7dUhWLSqclAiPgFt" + "QQ1YvSJAYfEIdyHkxv4NP0LSogxrumANcDyC9yt/W9yHjD2ICPBIqCsZLuLk" + "OHYi5DlwWe9Zm9VFwCGgggPMMIIDyDCCA8QwggKsoAMCAQICAQYwDQYJKoZI" + "hvcNAQEFBQAwgZQxFDASBgNVBAMTC1RDUy1DQSBPQ1NQMSYwJAYJKoZIhvcN" + "AQkBFhd0Y3MtY2FAdGNzLWNhLnRjcy5jby5pbjEMMAoGA1UEChMDVENTMQww" + "CgYDVQQLEwNBVEMxEjAQBgNVBAcTCUh5ZGVyYWJhZDEXMBUGA1UECBMOQW5k" + "aHJhIHByYWRlc2gxCzAJBgNVBAYTAklOMB4XDTAyMDgyOTA3MTE0M1oXDTAz" + "MDgyOTA3MTE0M1owgZwxCzAJBgNVBAYTAklOMRcwFQYDVQQIEw5BbmRocmEg" + "cHJhZGVzaDESMBAGA1UEBxMJSHlkZXJhYmFkMQwwCgYDVQQKEwNUQ1MxDDAK" + "BgNVBAsTA0FUQzEeMBwGA1UEAxMVVENTLUNBIE9DU1AgUmVzcG9uZGVyMSQw" + "IgYJKoZIhvcNAQkBFhVvY3NwQHRjcy1jYS50Y3MuY28uaW4wgZ8wDQYJKoZI" + "hvcNAQEBBQADgY0AMIGJAoGBAM+XWW4caMRv46D7L6Bv8iwtKgmQu0SAybmF" + "RJiz12qXzdvTLt8C75OdgmUomxp0+gW/4XlTPUqOMQWv463aZRv9Ust4f8MH" + "EJh4ekP/NS9+d8vEO3P40ntQkmSMcFmtA9E1koUtQ3MSJlcs441JjbgUaVnm" + "jDmmniQnZY4bU3tVAgMBAAGjgZowgZcwDAYDVR0TAQH/BAIwADALBgNVHQ8E" + "BAMCB4AwEwYDVR0lBAwwCgYIKwYBBQUHAwkwNgYIKwYBBQUHAQEEKjAoMCYG" + "CCsGAQUFBzABhhpodHRwOi8vMTcyLjE5LjQwLjExMDo3NzAwLzAtBgNVHR8E" + "JjAkMCKgIKAehhxodHRwOi8vMTcyLjE5LjQwLjExMC9jcmwuY3JsMA0GCSqG" + "SIb3DQEBBQUAA4IBAQB6FovM3B4VDDZ15o12gnADZsIk9fTAczLlcrmXLNN4" + "PgmqgnwF0Ymj3bD5SavDOXxbA65AZJ7rBNAguLUo+xVkgxmoBH7R2sBxjTCc" + "r07NEadxM3HQkt0aX5XYEl8eRoifwqYAI9h0ziZfTNes8elNfb3DoPPjqq6V" + "mMg0f0iMS4W8LjNPorjRB+kIosa1deAGPhq0eJ8yr0/s2QR2/WFD5P4aXc8I" + "KWleklnIImS3zqiPrq6tl2Bm8DZj7vXlTOwmraSQxUwzCKwYob1yGvNOUQTq" + "pG6jxn7jgDawHU1+WjWQe4Q34/pWeGLysxTraMa+Ug9kPe+jy/qRX2xwvKBZ"); byte[] testResp2 = Base64.decode( "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" + "A5oyOoNv0w+8bbtMNEc1"); /** * extra version number encoding. */ private static byte[] irregReq = Base64.decode( "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"); public String getName() { return "OCSP"; } private void testECDSA() throws Exception { String signDN = "O=Bouncy Castle, C=AU"; KeyPair signKP = OCSPTestUtil.makeECKeyPair(); X509Certificate testCert = OCSPTestUtil.makeECDSACertificate(signKP, signDN, signKP, signDN); String origDN = "CN=Eric H. Echidna, E=eric@bouncycastle.org, O=Bouncy Castle, C=AU"; GeneralName origName = new GeneralName(new X509Name(origDN)); // // general id value for our test issuer cert and a serial number. // CertificateID id = new CertificateID(CertificateID.HASH_SHA1, testCert, BigInteger.valueOf(1)); // // basic request generation // OCSPReqGenerator gen = new OCSPReqGenerator(); gen.addRequest(id); OCSPReq req = gen.generate(); if (req.isSigned()) { fail("signed but shouldn't be"); } X509Certificate[] certs = req.getCerts("BC"); if (certs != null) { fail("null certs expected, but not found"); } Req[] requests = req.getRequestList(); if (!requests[0].getCertID().equals(id)) { fail("Failed isFor test"); } // // request generation with signing // X509Certificate[] chain = new X509Certificate[1]; gen = new OCSPReqGenerator(); gen.setRequestorName(new GeneralName(GeneralName.directoryName, new X509Principal("CN=fred"))); gen.addRequest( new CertificateID(CertificateID.HASH_SHA1, testCert, BigInteger.valueOf(1))); chain[0] = testCert; req = gen.generate("SHA1withECDSA", signKP.getPrivate(), chain, "BC"); if (!req.isSigned()) { fail("not signed but should be"); } if (!req.verify(signKP.getPublic(), "BC")) { fail("signature failed to verify"); } requests = req.getRequestList(); if (!requests[0].getCertID().equals(id)) { fail("Failed isFor test"); } certs = req.getCerts("BC"); if (certs == null) { fail("null certs found"); } if (certs.length != 1 || !certs[0].equals(testCert)) { fail("incorrect certs found in request"); } // // encoding test // byte[] reqEnc = req.getEncoded(); OCSPReq newReq = new OCSPReq(reqEnc); if (!newReq.verify(signKP.getPublic(), "BC")) { fail("newReq signature failed to verify"); } // // request generation with signing and nonce // chain = new X509Certificate[1]; gen = new OCSPReqGenerator(); Vector oids = new Vector(); Vector values = new Vector(); byte[] sampleNonce = new byte[16]; Random rand = new Random(); rand.nextBytes(sampleNonce); gen.setRequestorName(new GeneralName(GeneralName.directoryName, new X509Principal("CN=fred"))); oids.addElement(OCSPObjectIdentifiers.id_pkix_ocsp_nonce); values.addElement(new X509Extension(false, new DEROctetString(new DEROctetString(sampleNonce)))); gen.setRequestExtensions(new X509Extensions(oids, values)); gen.addRequest( new CertificateID(CertificateID.HASH_SHA1, testCert, BigInteger.valueOf(1))); chain[0] = testCert; req = gen.generate("SHA1withECDSA", signKP.getPrivate(), chain, "BC"); if (!req.isSigned()) { fail("not signed but should be"); } if (!req.verify(signKP.getPublic(), "BC")) { fail("signature failed to verify"); } // // extension check. // Set extOids = req.getCriticalExtensionOIDs(); if (extOids.size() != 0) { fail("wrong number of critical extensions in OCSP request."); } extOids = req.getNonCriticalExtensionOIDs(); if (extOids.size() != 1) { fail("wrong number of non-critical extensions in OCSP request."); } byte[] extValue = req.getExtensionValue(OCSPObjectIdentifiers.id_pkix_ocsp_nonce.getId()); ASN1Encodable extObj = X509ExtensionUtil.fromExtensionValue(extValue); if (!(extObj instanceof ASN1OctetString)) { fail("wrong extension type found."); } if (!areEqual(((ASN1OctetString)extObj).getOctets(), sampleNonce)) { fail("wrong extension value found."); } // // request list check // requests = req.getRequestList(); if (!requests[0].getCertID().equals(id)) { fail("Failed isFor test"); } // // response generation // BasicOCSPRespGenerator respGen = new BasicOCSPRespGenerator(signKP.getPublic()); respGen.addResponse(id, CertificateStatus.GOOD); BasicOCSPResp resp = respGen.generate("SHA1withECDSA", signKP.getPrivate(), chain, new Date(), "BC"); } private void testRSA() throws Exception { String signDN = "O=Bouncy Castle, C=AU"; KeyPair signKP = OCSPTestUtil.makeKeyPair(); X509Certificate testCert = OCSPTestUtil.makeCertificate(signKP, signDN, signKP, signDN); String origDN = "CN=Eric H. Echidna, E=eric@bouncycastle.org, O=Bouncy Castle, C=AU"; GeneralName origName = new GeneralName(new X509Name(origDN)); // // general id value for our test issuer cert and a serial number. // CertificateID id = new CertificateID(CertificateID.HASH_SHA1, testCert, BigInteger.valueOf(1)); // // basic request generation // OCSPReqGenerator gen = new OCSPReqGenerator(); gen.addRequest( new CertificateID(CertificateID.HASH_SHA1, testCert, BigInteger.valueOf(1))); OCSPReq req = gen.generate(); if (req.isSigned()) { fail("signed but shouldn't be"); } X509Certificate[] certs = req.getCerts("BC"); if (certs != null) { fail("null certs expected, but not found"); } Req[] requests = req.getRequestList(); if (!requests[0].getCertID().equals(id)) { fail("Failed isFor test"); } // // request generation with signing // X509Certificate[] chain = new X509Certificate[1]; gen = new OCSPReqGenerator(); gen.setRequestorName(new GeneralName(GeneralName.directoryName, new X509Principal("CN=fred"))); gen.addRequest( new CertificateID(CertificateID.HASH_SHA1, testCert, BigInteger.valueOf(1))); chain[0] = testCert; req = gen.generate("SHA1withRSA", signKP.getPrivate(), chain, "BC"); if (!req.isSigned()) { fail("not signed but should be"); } if (!req.verify(signKP.getPublic(), "BC")) { fail("signature failed to verify"); } requests = req.getRequestList(); if (!requests[0].getCertID().equals(id)) { fail("Failed isFor test"); } certs = req.getCerts("BC"); if (certs == null) { fail("null certs found"); } if (certs.length != 1 || !certs[0].equals(testCert)) { fail("incorrect certs found in request"); } // // encoding test // byte[] reqEnc = req.getEncoded(); OCSPReq newReq = new OCSPReq(reqEnc); if (!newReq.verify(signKP.getPublic(), "BC")) { fail("newReq signature failed to verify"); } // // request generation with signing and nonce // chain = new X509Certificate[1]; gen = new OCSPReqGenerator(); Vector oids = new Vector(); Vector values = new Vector(); byte[] sampleNonce = new byte[16]; Random rand = new Random(); rand.nextBytes(sampleNonce); gen.setRequestorName(new GeneralName(GeneralName.directoryName, new X509Principal("CN=fred"))); oids.addElement(OCSPObjectIdentifiers.id_pkix_ocsp_nonce); values.addElement(new X509Extension(false, new DEROctetString(new DEROctetString(sampleNonce)))); gen.setRequestExtensions(new X509Extensions(oids, values)); gen.addRequest( new CertificateID(CertificateID.HASH_SHA1, testCert, BigInteger.valueOf(1))); chain[0] = testCert; req = gen.generate("SHA1withRSA", signKP.getPrivate(), chain, "BC"); if (!req.isSigned()) { fail("not signed but should be"); } if (!req.verify(signKP.getPublic(), "BC")) { fail("signature failed to verify"); } // // extension check. // Set extOids = req.getCriticalExtensionOIDs(); if (extOids.size() != 0) { fail("wrong number of critical extensions in OCSP request."); } extOids = req.getNonCriticalExtensionOIDs(); if (extOids.size() != 1) { fail("wrong number of non-critical extensions in OCSP request."); } byte[] extValue = req.getExtensionValue(OCSPObjectIdentifiers.id_pkix_ocsp_nonce.getId()); ASN1Encodable extObj = X509ExtensionUtil.fromExtensionValue(extValue); if (!(extObj instanceof ASN1OctetString)) { fail("wrong extension type found."); } if (!areEqual(((ASN1OctetString)extObj).getOctets(), sampleNonce)) { fail("wrong extension value found."); } // // request list check // requests = req.getRequestList(); if (!requests[0].getCertID().equals(id)) { fail("Failed isFor test"); } // // response generation // BasicOCSPRespGenerator respGen = new BasicOCSPRespGenerator(signKP.getPublic()); respGen.addResponse(id, CertificateStatus.GOOD); BasicOCSPResp resp = respGen.generate("SHA1withRSA", signKP.getPrivate(), chain, new Date(), "BC"); OCSPRespGenerator rGen = new OCSPRespGenerator(); byte[] enc = rGen.generate(OCSPRespGenerator.SUCCESSFUL, resp).getEncoded(); } private void testIrregularVersionReq() throws Exception { OCSPReq ocspRequest = new OCSPReq(irregReq); X509Certificate cert = ocspRequest.getCerts("BC")[0]; if (!ocspRequest.verify(cert.getPublicKey(), "BC")) { fail("extra version encoding test failed"); } } public void performTest() throws Exception { String signDN = "O=Bouncy Castle, C=AU"; KeyPair signKP = OCSPTestUtil.makeKeyPair(); X509Certificate testCert = OCSPTestUtil.makeCertificate(signKP, signDN, signKP, signDN); String origDN = "CN=Eric H. Echidna, E=eric@bouncycastle.org, O=Bouncy Castle, C=AU"; GeneralName origName = new GeneralName(new X509Name(origDN)); // // general id value for our test issuer cert and a serial number. // CertificateID id = new CertificateID(CertificateID.HASH_SHA1, testCert, BigInteger.valueOf(1)); // // general id value for our test issuer cert and a serial number and the default provider // id = new CertificateID(CertificateID.HASH_SHA1, testCert, BigInteger.valueOf(1), null); // // basic request generation // OCSPReqGenerator gen = new OCSPReqGenerator(); gen.addRequest( new CertificateID(CertificateID.HASH_SHA1, testCert, BigInteger.valueOf(1))); OCSPReq req = gen.generate(); if (req.isSigned()) { fail("signed but shouldn't be"); } X509Certificate[] certs = req.getCerts("BC"); if (certs != null) { fail("null certs expected, but not found"); } Req[] requests = req.getRequestList(); if (!requests[0].getCertID().equals(id)) { fail("Failed isFor test"); } // // request generation with signing // X509Certificate[] chain = new X509Certificate[1]; gen = new OCSPReqGenerator(); gen.setRequestorName(new GeneralName(GeneralName.directoryName, new X509Principal("CN=fred"))); gen.addRequest( new CertificateID(CertificateID.HASH_SHA1, testCert, BigInteger.valueOf(1))); chain[0] = testCert; req = gen.generate("SHA1withRSA", signKP.getPrivate(), chain, "BC"); if (!req.isSigned()) { fail("not signed but should be"); } if (!req.verify(signKP.getPublic(), "BC")) { fail("signature failed to verify"); } requests = req.getRequestList(); if (!requests[0].getCertID().equals(id)) { fail("Failed isFor test"); } certs = req.getCerts("BC"); if (certs == null) { fail("null certs found"); } if (certs.length != 1 || !certs[0].equals(testCert)) { fail("incorrect certs found in request"); } // // encoding test // byte[] reqEnc = req.getEncoded(); OCSPReq newReq = new OCSPReq(reqEnc); if (!newReq.verify(signKP.getPublic(), "BC")) { fail("newReq signature failed to verify"); } // // request generation with signing and nonce // chain = new X509Certificate[1]; gen = new OCSPReqGenerator(); Vector oids = new Vector(); Vector values = new Vector(); byte[] sampleNonce = new byte[16]; Random rand = new Random(); rand.nextBytes(sampleNonce); gen.setRequestorName(new GeneralName(GeneralName.directoryName, new X509Principal("CN=fred"))); oids.addElement(OCSPObjectIdentifiers.id_pkix_ocsp_nonce); values.addElement(new X509Extension(false, new DEROctetString(new DEROctetString(sampleNonce)))); gen.setRequestExtensions(new X509Extensions(oids, values)); gen.addRequest( new CertificateID(CertificateID.HASH_SHA1, testCert, BigInteger.valueOf(1))); chain[0] = testCert; req = gen.generate("SHA1withRSA", signKP.getPrivate(), chain, "BC"); if (!req.isSigned()) { fail("not signed but should be"); } if (!req.verify(signKP.getPublic(), "BC")) { fail("signature failed to verify"); } // // extension check. // Set extOids = req.getCriticalExtensionOIDs(); if (extOids.size() != 0) { fail("wrong number of critical extensions in OCSP request."); } extOids = req.getNonCriticalExtensionOIDs(); if (extOids.size() != 1) { fail("wrong number of non-critical extensions in OCSP request."); } byte[] extValue = req.getExtensionValue(OCSPObjectIdentifiers.id_pkix_ocsp_nonce.getId()); ASN1Encodable extObj = X509ExtensionUtil.fromExtensionValue(extValue); if (!(extObj instanceof ASN1OctetString)) { fail("wrong extension type found."); } if (!areEqual(((ASN1OctetString)extObj).getOctets(), sampleNonce)) { fail("wrong extension value found."); } // // request list check // requests = req.getRequestList(); if (!requests[0].getCertID().equals(id)) { fail("Failed isFor test"); } // // response parsing - test 1 // OCSPResp response = new OCSPResp(new ByteArrayInputStream(testResp1)); if (response.getStatus() != 0) { fail("response status not zero."); } BasicOCSPResp brep = (BasicOCSPResp)response.getResponseObject(); chain = brep.getCerts("BC"); if (!brep.verify(chain[0].getPublicKey(), "BC")) { fail("response 1 failed to verify."); } // // test 2 // SingleResp[] singleResp = brep.getResponses(); response = new OCSPResp(new ByteArrayInputStream(testResp2)); if (response.getStatus() != 0) { fail("response status not zero."); } brep = (BasicOCSPResp)response.getResponseObject(); chain = brep.getCerts("BC"); if (!brep.verify(chain[0].getPublicKey(), "BC")) { fail("response 2 failed to verify."); } singleResp = brep.getResponses(); // // simple response generation // OCSPRespGenerator respGen = new OCSPRespGenerator(); OCSPResp resp = respGen.generate(OCSPRespGenerator.SUCCESSFUL, response.getResponseObject()); if (!resp.getResponseObject().equals(response.getResponseObject())) { fail("response fails to match"); } testECDSA(); testRSA(); testIrregularVersionReq(); } public static void main( String[] args) { Security.addProvider(new BouncyCastleProvider()); runTest(new OCSPTest()); } } bouncycastle-1.49.orig/test/src/org/bouncycastle/ocsp/test/AllTests.java0000644000175000017500000000213010354623145026001 0ustar ebourgebourgpackage org.bouncycastle.ocsp.test; import java.security.Security; import junit.framework.Test; import junit.framework.TestCase; import junit.framework.TestSuite; import org.bouncycastle.jce.provider.BouncyCastleProvider; import org.bouncycastle.util.test.SimpleTestResult; public class AllTests extends TestCase { public void testOCSP() { Security.addProvider(new BouncyCastleProvider()); org.bouncycastle.util.test.Test[] tests = new org.bouncycastle.util.test.Test[] { new OCSPTest() }; for (int i = 0; i != tests.length; i++) { SimpleTestResult result = (SimpleTestResult)tests[i].perform(); if (!result.isSuccessful()) { fail(result.toString()); } } } public static void main (String[] args) { junit.textui.TestRunner.run(suite()); } public static Test suite() { TestSuite suite = new TestSuite("OCSP Tests"); suite.addTestSuite(AllTests.class); return suite; } } bouncycastle-1.49.orig/test/src/org/bouncycastle/ocsp/test/OCSPTestUtil.java0000644000175000017500000001314111740716225026516 0ustar ebourgebourgpackage org.bouncycastle.ocsp.test; import java.io.ByteArrayInputStream; import java.io.IOException; import java.math.BigInteger; import java.security.KeyPair; import java.security.KeyPairGenerator; import java.security.PrivateKey; import java.security.PublicKey; import java.security.SecureRandom; import java.security.cert.X509Certificate; import java.util.Date; import javax.crypto.KeyGenerator; import org.bouncycastle.asn1.ASN1InputStream; import org.bouncycastle.asn1.ASN1Sequence; import org.bouncycastle.asn1.x509.AuthorityKeyIdentifier; import org.bouncycastle.asn1.x509.BasicConstraints; import org.bouncycastle.asn1.x509.SubjectKeyIdentifier; import org.bouncycastle.asn1.x509.SubjectPublicKeyInfo; import org.bouncycastle.asn1.x509.X509Extensions; import org.bouncycastle.asn1.x509.X509Name; import org.bouncycastle.x509.X509V3CertificateGenerator; public class OCSPTestUtil { public static SecureRandom rand; public static KeyPairGenerator kpg, eckpg; public static KeyGenerator desede128kg; public static KeyGenerator desede192kg; public static KeyGenerator rc240kg; public static KeyGenerator rc264kg; public static KeyGenerator rc2128kg; public static BigInteger serialNumber; public static final boolean DEBUG = true; static { try { rand = new SecureRandom(); kpg = KeyPairGenerator.getInstance("RSA", "BC"); kpg.initialize(1024, rand); serialNumber = new BigInteger("1"); eckpg = KeyPairGenerator.getInstance("ECDSA", "BC"); eckpg.initialize(192, rand); } catch(Exception ex) { throw new RuntimeException(ex.toString()); } } public static KeyPair makeKeyPair() { return kpg.generateKeyPair(); } public static KeyPair makeECKeyPair() { return eckpg.generateKeyPair(); } public static X509Certificate makeCertificate(KeyPair _subKP, String _subDN, KeyPair _issKP, String _issDN) throws Exception { return makeCertificate(_subKP, _subDN, _issKP, _issDN, false); } public static X509Certificate makeECDSACertificate(KeyPair _subKP, String _subDN, KeyPair _issKP, String _issDN) throws Exception { return makeECDSACertificate(_subKP, _subDN, _issKP, _issDN, false); } public static X509Certificate makeCACertificate(KeyPair _subKP, String _subDN, KeyPair _issKP, String _issDN) throws Exception { return makeCertificate(_subKP, _subDN, _issKP, _issDN, true); } public static X509Certificate makeCertificate(KeyPair _subKP, String _subDN, KeyPair _issKP, String _issDN, boolean _ca) throws Exception { return makeCertificate(_subKP,_subDN, _issKP, _issDN, "MD5withRSA", _ca); } public static X509Certificate makeECDSACertificate(KeyPair _subKP, String _subDN, KeyPair _issKP, String _issDN, boolean _ca) throws Exception { return makeCertificate(_subKP,_subDN, _issKP, _issDN, "SHA1WithECDSA", _ca); } public static X509Certificate makeCertificate(KeyPair _subKP, String _subDN, KeyPair _issKP, String _issDN, String algorithm, boolean _ca) throws Exception { PublicKey _subPub = _subKP.getPublic(); PrivateKey _issPriv = _issKP.getPrivate(); PublicKey _issPub = _issKP.getPublic(); X509V3CertificateGenerator _v3CertGen = new X509V3CertificateGenerator(); _v3CertGen.reset(); _v3CertGen.setSerialNumber(allocateSerialNumber()); _v3CertGen.setIssuerDN(new X509Name(_issDN)); _v3CertGen.setNotBefore(new Date(System.currentTimeMillis())); _v3CertGen.setNotAfter(new Date(System.currentTimeMillis() + (1000L * 60 * 60 * 24 * 100))); _v3CertGen.setSubjectDN(new X509Name(_subDN)); _v3CertGen.setPublicKey(_subPub); _v3CertGen.setSignatureAlgorithm(algorithm); _v3CertGen.addExtension(X509Extensions.SubjectKeyIdentifier, false, createSubjectKeyId(_subPub)); _v3CertGen.addExtension(X509Extensions.AuthorityKeyIdentifier, false, createAuthorityKeyId(_issPub)); _v3CertGen.addExtension(X509Extensions.BasicConstraints, false, new BasicConstraints(_ca)); X509Certificate _cert = _v3CertGen.generate(_issPriv); _cert.checkValidity(new Date()); _cert.verify(_issPub); return _cert; } /* * * INTERNAL METHODS * */ private static AuthorityKeyIdentifier createAuthorityKeyId(PublicKey _pubKey) throws IOException { ByteArrayInputStream _bais = new ByteArrayInputStream(_pubKey .getEncoded()); SubjectPublicKeyInfo _info = new SubjectPublicKeyInfo( (ASN1Sequence)new ASN1InputStream(_bais).readObject()); return new AuthorityKeyIdentifier(_info); } private static SubjectKeyIdentifier createSubjectKeyId(PublicKey _pubKey) throws IOException { ByteArrayInputStream _bais = new ByteArrayInputStream(_pubKey .getEncoded()); SubjectPublicKeyInfo _info = new SubjectPublicKeyInfo( (ASN1Sequence)new ASN1InputStream(_bais).readObject()); return new SubjectKeyIdentifier(_info); } private static BigInteger allocateSerialNumber() { BigInteger _tmp = serialNumber; serialNumber = serialNumber.add(BigInteger.valueOf(1)); return _tmp; } } bouncycastle-1.49.orig/test/src/org/bouncycastle/ocsp/test/package.html0000644000175000017500000000011610330633061025656 0ustar ebourgebourg Test class for OCSP messages. bouncycastle-1.49.orig/test/src/org/bouncycastle/cms/0000755000175000017500000000000012152033550022237 5ustar ebourgebourgbouncycastle-1.49.orig/test/src/org/bouncycastle/cms/test/0000755000175000017500000000000012152033550023216 5ustar ebourgebourgbouncycastle-1.49.orig/test/src/org/bouncycastle/cms/test/NewCompressedDataTest.java0000644000175000017500000001542511526131275030307 0ustar ebourgebourgpackage org.bouncycastle.cms.test; import java.util.Arrays; import junit.framework.Test; import junit.framework.TestCase; import junit.framework.TestSuite; import org.bouncycastle.cms.CMSCompressedData; import org.bouncycastle.cms.CMSCompressedDataGenerator; import org.bouncycastle.cms.CMSException; import org.bouncycastle.cms.CMSProcessableByteArray; import org.bouncycastle.cms.jcajce.ZlibCompressor; import org.bouncycastle.cms.jcajce.ZlibExpanderProvider; import org.bouncycastle.util.encoders.Base64; import org.bouncycastle.util.io.StreamOverflowException; public class NewCompressedDataTest extends TestCase { private static final byte[] TEST_DATA = "Hello world!".getBytes(); /* * * INFRASTRUCTURE * */ public NewCompressedDataTest(String name) { super(name); } public static void main(String args[]) { junit.textui.TestRunner.run(NewCompressedDataTest.class); } public static Test suite() { return new CMSTestSetup(new TestSuite(NewCompressedDataTest.class)); } public void setUp() { } public void tearDown() { } public void testWorkingData() throws Exception { byte[] compData = Base64 .decode("MIAGCyqGSIb3DQEJEAEJoIAwgAIBADANBgsqhkiG9w0BCRADCDCABgkqhkiG9w0BBwGggCSABIIC" + "Hnic7ZRdb9owFIbvK/k/5PqVYPFXGK12YYyboVFASSp1vQtZGiLRACZE49/XHoUW7S/0tXP8Efux" + "fU5ivWnasml72XFb3gb5druui7ytN803M570nii7C5r8tfwR281hy/p/KSM3+jzH5s3+pbQ90xSb" + "P3VT3QbLusnt8WPIuN5vN/vaA2+DulnXTXkXvNTr8j8ouZmkCmGI/UW+ZS/C8zP0bz2dz0zwLt+1" + "UEk2M8mlaxjRMByAhZTj0RGYg4TvogiRASROsZgjpVcJCb1KV6QzQeDJ1XkoQ5Jm+C5PbOHZZGRi" + "v+ORAcshOGeCcdFJyfgFxdtCdEcmOrbinc/+BBMzRThEYpwl+jEBpciSGWQkI0TSlREmD/eOHb2D" + "SGLuESm/iKUFt1y4XHBO2a5oq0IKJKWLS9kUZTA7vC5LSxYmgVL46SIWxIfWBQd6AdrnjLmH94UT" + "vGxVibLqRCtIpp4g2qpdtqK1LiOeolpVK5wVQ5P7+QjZAlrh0cePYTx/gNZuB9Vhndtgujl9T/tg" + "W9ogK+3rnmg3YWygnTuF5GDS+Q/jIVLnCcYZFc6Kk/+c80wKwZjwdZIqDYWRH68MuBQSXLgXYXj2" + "3CAaYOBNJMliTl0X7eV5DnoKIFSKYdj3cRpD/cK/JWTHJRe76MUXnfBW8m7Hd5zhQ4ri2NrVF/WL" + "+kV1/3AGSlJ32bFPd2BsQD8uSzIx6lObkjdz95c0AAAAAAAAAAAAAAAA"); byte[] uncompData = Base64 .decode("Q29udGVudC1UeXBlOiBhcHBsaWNhdGlvbi9FREktWDEyOyBuYW1lPUdyb3VwMi54MTINCkNvbnRl" + "bnQtVHJhbnNmZXItRW5jb2Rpbmc6IGJpbmFyeQ0KQ29udGVudC1EaXNwb3NpdGlvbjogaW5saW5l" + "OyBmaWxlbmFtZT1Hcm91cDIueDEyDQoNCklTQSowMCpzc3Nzc3Nzc3NzKjAwKnJycnJycnJycnIqW" + "loqQ1lDTE9ORSAgICAgICAgKlpaKlBBUlRORVIgICAgICAgICo5NjEwMDcqMjAxMypVKjAwMjAwKj" + "AwMDAwMDAwMSowKlQqKg1HUypQTypTMVMxUzFTMVMxUzFTMVMqUjFSMVIxUjFSMVIxUjFSKjk2MTA" + "wNyoyMDEzKjAwMDAwMDAwNCpYKjAwMzA1MA1TVCo4NTAqMDAwMDQwMDAxDUJFRyowMCpCRSoyYSo0" + "MzMyNDIzNHY1NTIzKjk2MTAwNyoyM3RjNHZ5MjR2MmgzdmgzdmgqWloqSUVMKjA5KlJFKjA5DUNVU" + "ioxMSpUUk4qNTY1Nio2NSo1NjYqSU1GKjAwNio5NjEwMDcNUkVGKjZBKjQzM3IxYzNyMzRyMzRjMz" + "MxMnFjdGdjNTQqUmVmZXJlbmNlIE51bWJlcg1QRVIqQUEqSGFucyBHdXR0ZW4qQ1AqMS4zMjIuMzI" + "zLjQ0NDQqKioqKnJnZzRlZ3Y0dDQNVEFYKjR0Z3RidDR0cjR0cipHTCpnaGdoKioqKioqKioqRypD" + "DUZPQipUUCpDQSpVU0EqMDIqRE9NKkNDKlJlZ3VsYXIgTG9jYXRpb25zIHBlciBUZXJtcw1DVFAqR" + "EUqQzA0KjQ1MyoyNTAwMCpEOSpTRUwqMjMyMTQqMjM0MzI0MjM0MjMqRVMqNDIyNDM0MjMNU0FDKk" + "EqQjAwMCpBRSozNTQ1KjM0NDIzMDANQ1VSKjExKjc2Nyo3NzY3KjY1DVBPMSoxMTEtYWFhKjEwMDA" + "wMDAqQVMqOTAuMDAqQkQqQUsqMjM0MjM1djM1MzRxNmYzNTM0djQzNTM0NTN2cTNxMzIqKioqKioq" + "KioqKkExKnl0cmgNUE8xKjExMS1hYWEqMTAwMDAwMCpBUyo5MC4wMCpCRCpBSyoyMzQyMzV2MzUzN" + "HE2ZjM1MzR2NDM1MzQ1M3ZxM3EzMioqKioqKioqKioqQTEqeXRyaA1QTzEqMTExLWFhYSoxMDAwMD" + "AwKkFTKjkwLjAwKkJEKkFLKjIzNDIzNXYzNTM0cTZmMzUzNHY0MzUzNDUzdnEzcTMyKioqKioqKio" + "qKipBMSp5dHJoDVBPMSoxMTEtYWFhKjEwMDAwMDAqQVMqOTAuMDAqQkQqQUsqMjM0MjM1djM1MzRx" + "NmYzNTM0djQzNTM0NTN2cTNxMzIqKioqKioqKioqKkExKnl0cmgNUE8xKjExMS1hYWEqMTAwMDAwM" + "CpBUyo5MC4wMCpCRCpBSyoyMzQyMzV2MzUzNHE2ZjM1MzR2NDM1MzQ1M3ZxM3EzMioqKioqKioqKi" + "oqQTEqeXRyaA1QTzEqMTExLWFhYSoxMDAwMDAwKkFTKjkwLjAwKkJEKkFLKjIzNDIzNXYzNTM0cTZ" + "mMzUzNHY0MzUzNDUzdnEzcTMyKioqKioqKioqKipBMSp5dHJoDVBPMSoxMTEtYWFhKjEwMDAwMDAq" + "QVMqOTAuMDAqQkQqQUsqMjM0MjM1djM1MzRxNmYzNTM0djQzNTM0NTN2cTNxMzIqKioqKioqKioqK" + "kExKnl0cmgNUE8xKjExMS1hYWEqMTAwMDAwMCpBUyo5MC4wMCpCRCpBSyoyMzQyMzV2MzUzNHE2Zj" + "M1MzR2NDM1MzQ1M3ZxM3EzMioqKioqKioqKioqQTEqeXRyaA1QTzEqMTExLWFhYSoxMDAwMDAwKkF" + "TKjkwLjAwKkJEKkFLKjIzNDIzNXYzNTM0cTZmMzUzNHY0MzUzNDUzdnEzcTMyKioqKioqKioqKipB" + "MSp5dHJoDVBPMSoxMTEtYWFhKjEwMDAwMDAqQVMqOTAuMDAqQkQqQUsqMjM0MjM1djM1MzRxNmYzN" + "TM0djQzNTM0NTN2cTNxMzIqKioqKioqKioqKkExKnl0cmgNQ1RUKjENU0UqMjIqMDAwMDQwMDAxDUdFKjEqMDAwMDAwMDA0DUlFQSoxKjAwMDAwMDAwMQ0="); CMSCompressedData ed = new CMSCompressedData(compData); assertEquals(true, Arrays.equals(uncompData, ed.getContent(new ZlibExpanderProvider()))); } public void testEach() throws Exception { CMSCompressedData cd = getStdData(); assertEquals(true, Arrays.equals(TEST_DATA, cd.getContent(new ZlibExpanderProvider()))); } public void testLimitUnder() throws Exception { CMSCompressedData cd = getStdData(); try { cd.getContent(new ZlibExpanderProvider(TEST_DATA.length / 2)); } catch (CMSException e) { assertEquals(true, e.getCause() instanceof StreamOverflowException); } } public void testLimitOver() throws Exception { CMSCompressedData cd = getStdData(); assertEquals(true, Arrays.equals(TEST_DATA, cd.getContent(new ZlibExpanderProvider(TEST_DATA.length * 2)))); } public void testLimitEqual() throws Exception { CMSCompressedData cd = getStdData(); assertEquals(true, Arrays.equals(TEST_DATA, cd.getContent(new ZlibExpanderProvider(TEST_DATA.length)))); } private CMSCompressedData getStdData() throws CMSException { CMSProcessableByteArray testData = new CMSProcessableByteArray(TEST_DATA); CMSCompressedDataGenerator gen = new CMSCompressedDataGenerator(); return gen.generate(testData, new ZlibCompressor()); } } bouncycastle-1.49.orig/test/src/org/bouncycastle/cms/test/NewAuthenticatedDataTest.java0000644000175000017500000004244611701213634030763 0ustar ebourgebourgpackage org.bouncycastle.cms.test; import java.security.KeyPair; import java.security.NoSuchAlgorithmException; import java.security.NoSuchProviderException; import java.security.cert.X509Certificate; import java.util.Arrays; import java.util.Collection; import java.util.Iterator; import javax.crypto.SecretKey; import junit.framework.Test; import junit.framework.TestCase; import junit.framework.TestSuite; import org.bouncycastle.asn1.ASN1ObjectIdentifier; import org.bouncycastle.asn1.DERObjectIdentifier; import org.bouncycastle.asn1.oiw.OIWObjectIdentifiers; import org.bouncycastle.asn1.pkcs.PKCSObjectIdentifiers; import org.bouncycastle.asn1.x509.AlgorithmIdentifier; import org.bouncycastle.cert.X509CertificateHolder; import org.bouncycastle.cms.CMSAlgorithm; import org.bouncycastle.cms.CMSAuthenticatedData; import org.bouncycastle.cms.CMSAuthenticatedDataGenerator; import org.bouncycastle.cms.CMSException; import org.bouncycastle.cms.CMSProcessableByteArray; import org.bouncycastle.cms.OriginatorInfoGenerator; import org.bouncycastle.cms.PasswordRecipient; import org.bouncycastle.cms.PasswordRecipientInformation; import org.bouncycastle.cms.RecipientInformation; import org.bouncycastle.cms.RecipientInformationStore; import org.bouncycastle.cms.jcajce.JceCMSMacCalculatorBuilder; import org.bouncycastle.cms.jcajce.JceKEKAuthenticatedRecipient; import org.bouncycastle.cms.jcajce.JceKEKRecipientInfoGenerator; import org.bouncycastle.cms.jcajce.JceKeyAgreeAuthenticatedRecipient; import org.bouncycastle.cms.jcajce.JceKeyAgreeRecipientInfoGenerator; import org.bouncycastle.cms.jcajce.JceKeyTransAuthenticatedRecipient; import org.bouncycastle.cms.jcajce.JceKeyTransRecipientInfoGenerator; import org.bouncycastle.cms.jcajce.JcePasswordAuthenticatedRecipient; import org.bouncycastle.cms.jcajce.JcePasswordRecipientInfoGenerator; import org.bouncycastle.jce.provider.BouncyCastleProvider; import org.bouncycastle.operator.DigestCalculatorProvider; import org.bouncycastle.operator.OperatorCreationException; import org.bouncycastle.operator.jcajce.JcaDigestCalculatorProviderBuilder; import org.bouncycastle.util.encoders.Hex; public class NewAuthenticatedDataTest extends TestCase { private static final String BC = BouncyCastleProvider.PROVIDER_NAME; private static String _signDN; private static KeyPair _signKP; private static X509Certificate _signCert; private static String _origDN; private static KeyPair _origKP; private static X509Certificate _origCert; private static String _reciDN; private static KeyPair _reciKP; private static X509Certificate _reciCert; private static KeyPair _origEcKP; private static KeyPair _reciEcKP; private static X509Certificate _reciEcCert; private static boolean _initialised = false; public boolean DEBUG = true; private static void init() throws Exception { if (!_initialised) { _initialised = true; _signDN = "O=Bouncy Castle, C=AU"; _signKP = CMSTestUtil.makeKeyPair(); _signCert = CMSTestUtil.makeCertificate(_signKP, _signDN, _signKP, _signDN); _origDN = "CN=Bob, OU=Sales, O=Bouncy Castle, C=AU"; _origKP = CMSTestUtil.makeKeyPair(); _origCert = CMSTestUtil.makeCertificate(_origKP, _origDN, _signKP, _signDN); _reciDN = "CN=Doug, OU=Sales, O=Bouncy Castle, C=AU"; _reciKP = CMSTestUtil.makeKeyPair(); _reciCert = CMSTestUtil.makeCertificate(_reciKP, _reciDN, _signKP, _signDN); _origEcKP = CMSTestUtil.makeEcDsaKeyPair(); _reciEcKP = CMSTestUtil.makeEcDsaKeyPair(); _reciEcCert = CMSTestUtil.makeCertificate(_reciEcKP, _reciDN, _signKP, _signDN); } } public void setUp() throws Exception { init(); } public NewAuthenticatedDataTest(String name) { super(name); } public static void main(String args[]) { junit.textui.TestRunner.run(NewAuthenticatedDataTest.class); } public static Test suite() throws Exception { init(); return new CMSTestSetup(new TestSuite(NewAuthenticatedDataTest.class)); } public void testKeyTransDESede() throws Exception { tryKeyTrans(CMSAlgorithm.DES_EDE3_CBC); } public void testKeyTransDESedeWithDigest() throws Exception { tryKeyTransWithDigest(CMSAlgorithm.DES_EDE3_CBC); } public void testKeyTransRC2() throws Exception { tryKeyTrans(CMSAlgorithm.RC2_CBC); } public void testKEKDESede() throws Exception { tryKekAlgorithm(CMSTestUtil.makeDesede192Key(), new DERObjectIdentifier("1.2.840.113549.1.9.16.3.6")); } public void testKEKDESedeWithDigest() throws Exception { tryKekAlgorithmWithDigest(CMSTestUtil.makeDesede192Key(), new DERObjectIdentifier("1.2.840.113549.1.9.16.3.6")); } public void testPasswordAES256() throws Exception { passwordTest(CMSAuthenticatedDataGenerator.AES256_CBC); } public void testECKeyAgree() throws Exception { byte[] data = Hex.decode("504b492d4320434d5320456e76656c6f706564446174612053616d706c65"); CMSAuthenticatedDataGenerator adGen = new CMSAuthenticatedDataGenerator(); JceKeyAgreeRecipientInfoGenerator recipientGenerator = new JceKeyAgreeRecipientInfoGenerator(CMSAlgorithm.ECDH_SHA1KDF, _origEcKP.getPrivate(), _origEcKP.getPublic(), CMSAlgorithm.AES128_WRAP).setProvider(BC); recipientGenerator.addRecipient(_reciEcCert); adGen.addRecipientInfoGenerator(recipientGenerator); CMSAuthenticatedData ad = adGen.generate( new CMSProcessableByteArray(data), new JceCMSMacCalculatorBuilder(CMSAlgorithm.DES_EDE3_CBC).setProvider(BC).build()); RecipientInformationStore recipients = ad.getRecipientInfos(); assertEquals(ad.getMacAlgOID(), CMSAuthenticatedDataGenerator.DES_EDE3_CBC); Collection c = recipients.getRecipients(); Iterator it = c.iterator(); if (it.hasNext()) { RecipientInformation recipient = (RecipientInformation)it.next(); byte[] recData = recipient.getContent(new JceKeyAgreeAuthenticatedRecipient(_reciEcKP.getPrivate()).setProvider(BC)); assertTrue(Arrays.equals(data, recData)); assertTrue(Arrays.equals(ad.getMac(), recipient.getMac())); } else { fail("no recipient found"); } } public void testEncoding() throws Exception { byte[] data = "Eric H. Echidna".getBytes(); CMSAuthenticatedDataGenerator adGen = new CMSAuthenticatedDataGenerator(); adGen.addRecipientInfoGenerator(new JceKeyTransRecipientInfoGenerator(_reciCert).setProvider(BC)); CMSAuthenticatedData ad = adGen.generate( new CMSProcessableByteArray(data), new JceCMSMacCalculatorBuilder(CMSAlgorithm.DES_EDE3_CBC).setProvider(BC).build()); ad = new CMSAuthenticatedData(ad.getEncoded()); RecipientInformationStore recipients = ad.getRecipientInfos(); assertEquals(CMSAuthenticatedDataGenerator.DES_EDE3_CBC, ad.getMacAlgOID()); Collection c = recipients.getRecipients(); assertEquals(1, c.size()); Iterator it = c.iterator(); while (it.hasNext()) { RecipientInformation recipient = (RecipientInformation)it.next(); assertEquals(recipient.getKeyEncryptionAlgOID(), PKCSObjectIdentifiers.rsaEncryption.getId()); byte[] recData = recipient.getContent(new JceKeyTransAuthenticatedRecipient(_reciKP.getPrivate()).setProvider(BC)); assertTrue(Arrays.equals(data, recData)); assertTrue(Arrays.equals(ad.getMac(), recipient.getMac())); } } public void testOriginatorInfo() throws Exception { byte[] data = "Eric H. Echidna".getBytes(); ASN1ObjectIdentifier macAlg = CMSAlgorithm.DES_EDE3_CBC; CMSAuthenticatedDataGenerator adGen = new CMSAuthenticatedDataGenerator(); X509CertificateHolder origCert = new X509CertificateHolder(_origCert.getEncoded()); adGen.setOriginatorInfo(new OriginatorInfoGenerator(origCert).generate()); adGen.addRecipientInfoGenerator(new JceKeyTransRecipientInfoGenerator(_reciCert).setProvider(BC)); CMSAuthenticatedData ad = adGen.generate( new CMSProcessableByteArray(data), new JceCMSMacCalculatorBuilder(macAlg).setProvider(BC).build()); assertTrue(ad.getOriginatorInfo().getCertificates().getMatches(null).contains(origCert)); RecipientInformationStore recipients = ad.getRecipientInfos(); assertEquals(ad.getMacAlgOID(), macAlg.getId()); Collection c = recipients.getRecipients(); assertEquals(1, c.size()); Iterator it = c.iterator(); while (it.hasNext()) { RecipientInformation recipient = (RecipientInformation)it.next(); assertEquals(recipient.getKeyEncryptionAlgOID(), PKCSObjectIdentifiers.rsaEncryption.getId()); byte[] recData = recipient.getContent(new JceKeyTransAuthenticatedRecipient(_reciKP.getPrivate()).setProvider(BC)); assertTrue(Arrays.equals(data, recData)); assertTrue(Arrays.equals(ad.getMac(), recipient.getMac())); } } private void tryKeyTrans(ASN1ObjectIdentifier macAlg) throws Exception { byte[] data = "Eric H. Echidna".getBytes(); CMSAuthenticatedDataGenerator adGen = new CMSAuthenticatedDataGenerator(); adGen.addRecipientInfoGenerator(new JceKeyTransRecipientInfoGenerator(_reciCert).setProvider(BC)); CMSAuthenticatedData ad = adGen.generate( new CMSProcessableByteArray(data), new JceCMSMacCalculatorBuilder(macAlg).setProvider(BC).build()); RecipientInformationStore recipients = ad.getRecipientInfos(); assertEquals(ad.getMacAlgOID(), macAlg.getId()); Collection c = recipients.getRecipients(); assertEquals(1, c.size()); Iterator it = c.iterator(); while (it.hasNext()) { RecipientInformation recipient = (RecipientInformation)it.next(); assertEquals(recipient.getKeyEncryptionAlgOID(), PKCSObjectIdentifiers.rsaEncryption.getId()); byte[] recData = recipient.getContent(new JceKeyTransAuthenticatedRecipient(_reciKP.getPrivate()).setProvider(BC)); assertTrue(Arrays.equals(data, recData)); assertTrue(Arrays.equals(ad.getMac(), recipient.getMac())); } } private void tryKeyTransWithDigest(ASN1ObjectIdentifier macAlg) throws Exception { byte[] data = "Eric H. Echidna".getBytes(); CMSAuthenticatedDataGenerator adGen = new CMSAuthenticatedDataGenerator(); DigestCalculatorProvider calcProvider = new JcaDigestCalculatorProviderBuilder().setProvider(BC).build(); adGen.addRecipientInfoGenerator(new JceKeyTransRecipientInfoGenerator(_reciCert).setProvider(BC)); CMSAuthenticatedData ad = adGen.generate( new CMSProcessableByteArray(data), new JceCMSMacCalculatorBuilder(macAlg).setProvider(BC).build(), calcProvider.get(new AlgorithmIdentifier(OIWObjectIdentifiers.idSHA1))); RecipientInformationStore recipients = ad.getRecipientInfos(); assertEquals(ad.getMacAlgOID(), macAlg.getId()); Collection c = recipients.getRecipients(); assertEquals(1, c.size()); Iterator it = c.iterator(); while (it.hasNext()) { RecipientInformation recipient = (RecipientInformation)it.next(); assertEquals(recipient.getKeyEncryptionAlgOID(), PKCSObjectIdentifiers.rsaEncryption.getId()); byte[] recData = recipient.getContent(new JceKeyTransAuthenticatedRecipient(_reciKP.getPrivate()).setProvider(BC)); assertTrue(Arrays.equals(data, recData)); assertTrue(Arrays.equals(ad.getMac(), recipient.getMac())); assertTrue(Arrays.equals(ad.getContentDigest(), recipient.getContentDigest())); } } private void tryKekAlgorithm(SecretKey kek, DERObjectIdentifier algOid) throws NoSuchAlgorithmException, NoSuchProviderException, CMSException, OperatorCreationException { byte[] data = "Eric H. Echidna".getBytes(); CMSAuthenticatedDataGenerator adGen = new CMSAuthenticatedDataGenerator(); byte[] kekId = new byte[] { 1, 2, 3, 4, 5 }; adGen.addRecipientInfoGenerator(new JceKEKRecipientInfoGenerator(kekId, kek).setProvider(BC)); CMSAuthenticatedData ad = adGen.generate( new CMSProcessableByteArray(data), new JceCMSMacCalculatorBuilder(CMSAlgorithm.DES_EDE3_CBC).setProvider(BC).build()); RecipientInformationStore recipients = ad.getRecipientInfos(); Collection c = recipients.getRecipients(); Iterator it = c.iterator(); assertEquals(ad.getMacAlgOID(), CMSAuthenticatedDataGenerator.DES_EDE3_CBC); if (it.hasNext()) { RecipientInformation recipient = (RecipientInformation)it.next(); assertEquals(recipient.getKeyEncryptionAlgOID(), algOid.getId()); byte[] recData = recipient.getContent(new JceKEKAuthenticatedRecipient(kek).setProvider(BC)); assertTrue(Arrays.equals(data, recData)); assertTrue(Arrays.equals(ad.getMac(), recipient.getMac())); } else { fail("no recipient found"); } } private void tryKekAlgorithmWithDigest(SecretKey kek, DERObjectIdentifier algOid) throws NoSuchAlgorithmException, NoSuchProviderException, CMSException, OperatorCreationException { byte[] data = "Eric H. Echidna".getBytes(); CMSAuthenticatedDataGenerator adGen = new CMSAuthenticatedDataGenerator(); DigestCalculatorProvider calcProvider = new JcaDigestCalculatorProviderBuilder().setProvider(BC).build(); byte[] kekId = new byte[] { 1, 2, 3, 4, 5 }; adGen.addRecipientInfoGenerator(new JceKEKRecipientInfoGenerator(kekId, kek).setProvider(BC)); CMSAuthenticatedData ad = adGen.generate( new CMSProcessableByteArray(data), new JceCMSMacCalculatorBuilder(CMSAlgorithm.DES_EDE3_CBC).setProvider(BC).build(), calcProvider.get(new AlgorithmIdentifier(OIWObjectIdentifiers.idSHA1))); RecipientInformationStore recipients = ad.getRecipientInfos(); Collection c = recipients.getRecipients(); Iterator it = c.iterator(); assertEquals(ad.getMacAlgOID(), CMSAuthenticatedDataGenerator.DES_EDE3_CBC); if (it.hasNext()) { RecipientInformation recipient = (RecipientInformation)it.next(); assertEquals(recipient.getKeyEncryptionAlgOID(), algOid.getId()); byte[] recData = recipient.getContent(new JceKEKAuthenticatedRecipient(kek).setProvider(BC)); assertTrue(Arrays.equals(data, recData)); assertTrue(Arrays.equals(ad.getMac(), recipient.getMac())); assertTrue(Arrays.equals(ad.getContentDigest(), recipient.getContentDigest())); } else { fail("no recipient found"); } } private void passwordTest(String algorithm) throws Exception { byte[] data = Hex.decode("504b492d4320434d5320456e76656c6f706564446174612053616d706c65"); CMSAuthenticatedDataGenerator adGen = new CMSAuthenticatedDataGenerator(); adGen.addRecipientInfoGenerator(new JcePasswordRecipientInfoGenerator(new ASN1ObjectIdentifier(algorithm), "password".toCharArray()).setProvider(BC).setSaltAndIterationCount(new byte[20], 5)); CMSAuthenticatedData ad = adGen.generate( new CMSProcessableByteArray(data), new JceCMSMacCalculatorBuilder(CMSAlgorithm.DES_EDE3_CBC).setProvider(BC).build()); RecipientInformationStore recipients = ad.getRecipientInfos(); assertEquals(ad.getMacAlgOID(), CMSAuthenticatedDataGenerator.DES_EDE3_CBC); Collection c = recipients.getRecipients(); Iterator it = c.iterator(); if (it.hasNext()) { PasswordRecipientInformation recipient = (PasswordRecipientInformation)it.next(); PasswordRecipient pbeRep = new JcePasswordAuthenticatedRecipient("password".toCharArray()).setProvider(BC); byte[] recData = recipient.getContent(pbeRep); assertTrue(Arrays.equals(data, recData)); assertTrue(Arrays.equals(ad.getMac(), recipient.getMac())); } else { fail("no recipient found"); } } }bouncycastle-1.49.orig/test/src/org/bouncycastle/cms/test/CompressedDataStreamTest.java0000644000175000017500000001441110330633061030773 0ustar ebourgebourgpackage org.bouncycastle.cms.test; import java.io.ByteArrayOutputStream; import java.io.OutputStream; import java.util.Arrays; import java.util.Random; import junit.framework.Test; import junit.framework.TestCase; import junit.framework.TestSuite; import org.bouncycastle.cms.CMSCompressedDataParser; import org.bouncycastle.cms.CMSCompressedDataStreamGenerator; import org.bouncycastle.util.encoders.Base64; public class CompressedDataStreamTest extends TestCase { public CompressedDataStreamTest(String name) { super(name); } public void testWorkingData() throws Exception { byte[] compData = Base64.decode( "MIAGCyqGSIb3DQEJEAEJoIAwgAIBADANBgsqhkiG9w0BCRADCDCABgkqhkiG9w0BBwGggCSABIIC" + "Hnic7ZRdb9owFIbvK/k/5PqVYPFXGK12YYyboVFASSp1vQtZGiLRACZE49/XHoUW7S/0tXP8Efux" + "fU5ivWnasml72XFb3gb5druui7ytN803M570nii7C5r8tfwR281hy/p/KSM3+jzH5s3+pbQ90xSb" + "P3VT3QbLusnt8WPIuN5vN/vaA2+DulnXTXkXvNTr8j8ouZmkCmGI/UW+ZS/C8zP0bz2dz0zwLt+1" + "UEk2M8mlaxjRMByAhZTj0RGYg4TvogiRASROsZgjpVcJCb1KV6QzQeDJ1XkoQ5Jm+C5PbOHZZGRi" + "v+ORAcshOGeCcdFJyfgFxdtCdEcmOrbinc/+BBMzRThEYpwl+jEBpciSGWQkI0TSlREmD/eOHb2D" + "SGLuESm/iKUFt1y4XHBO2a5oq0IKJKWLS9kUZTA7vC5LSxYmgVL46SIWxIfWBQd6AdrnjLmH94UT" + "vGxVibLqRCtIpp4g2qpdtqK1LiOeolpVK5wVQ5P7+QjZAlrh0cePYTx/gNZuB9Vhndtgujl9T/tg" + "W9ogK+3rnmg3YWygnTuF5GDS+Q/jIVLnCcYZFc6Kk/+c80wKwZjwdZIqDYWRH68MuBQSXLgXYXj2" + "3CAaYOBNJMliTl0X7eV5DnoKIFSKYdj3cRpD/cK/JWTHJRe76MUXnfBW8m7Hd5zhQ4ri2NrVF/WL" + "+kV1/3AGSlJ32bFPd2BsQD8uSzIx6lObkjdz95c0AAAAAAAAAAAAAAAA"); byte[] uncompData = Base64.decode( "Q29udGVudC1UeXBlOiBhcHBsaWNhdGlvbi9FREktWDEyOyBuYW1lPUdyb3VwMi54MTINCkNvbnRl" + "bnQtVHJhbnNmZXItRW5jb2Rpbmc6IGJpbmFyeQ0KQ29udGVudC1EaXNwb3NpdGlvbjogaW5saW5l" + "OyBmaWxlbmFtZT1Hcm91cDIueDEyDQoNCklTQSowMCpzc3Nzc3Nzc3NzKjAwKnJycnJycnJycnIqW" + "loqQ1lDTE9ORSAgICAgICAgKlpaKlBBUlRORVIgICAgICAgICo5NjEwMDcqMjAxMypVKjAwMjAwKj" + "AwMDAwMDAwMSowKlQqKg1HUypQTypTMVMxUzFTMVMxUzFTMVMqUjFSMVIxUjFSMVIxUjFSKjk2MTA" + "wNyoyMDEzKjAwMDAwMDAwNCpYKjAwMzA1MA1TVCo4NTAqMDAwMDQwMDAxDUJFRyowMCpCRSoyYSo0" + "MzMyNDIzNHY1NTIzKjk2MTAwNyoyM3RjNHZ5MjR2MmgzdmgzdmgqWloqSUVMKjA5KlJFKjA5DUNVU" + "ioxMSpUUk4qNTY1Nio2NSo1NjYqSU1GKjAwNio5NjEwMDcNUkVGKjZBKjQzM3IxYzNyMzRyMzRjMz" + "MxMnFjdGdjNTQqUmVmZXJlbmNlIE51bWJlcg1QRVIqQUEqSGFucyBHdXR0ZW4qQ1AqMS4zMjIuMzI" + "zLjQ0NDQqKioqKnJnZzRlZ3Y0dDQNVEFYKjR0Z3RidDR0cjR0cipHTCpnaGdoKioqKioqKioqRypD" + "DUZPQipUUCpDQSpVU0EqMDIqRE9NKkNDKlJlZ3VsYXIgTG9jYXRpb25zIHBlciBUZXJtcw1DVFAqR" + "EUqQzA0KjQ1MyoyNTAwMCpEOSpTRUwqMjMyMTQqMjM0MzI0MjM0MjMqRVMqNDIyNDM0MjMNU0FDKk" + "EqQjAwMCpBRSozNTQ1KjM0NDIzMDANQ1VSKjExKjc2Nyo3NzY3KjY1DVBPMSoxMTEtYWFhKjEwMDA" + "wMDAqQVMqOTAuMDAqQkQqQUsqMjM0MjM1djM1MzRxNmYzNTM0djQzNTM0NTN2cTNxMzIqKioqKioq" + "KioqKkExKnl0cmgNUE8xKjExMS1hYWEqMTAwMDAwMCpBUyo5MC4wMCpCRCpBSyoyMzQyMzV2MzUzN" + "HE2ZjM1MzR2NDM1MzQ1M3ZxM3EzMioqKioqKioqKioqQTEqeXRyaA1QTzEqMTExLWFhYSoxMDAwMD" + "AwKkFTKjkwLjAwKkJEKkFLKjIzNDIzNXYzNTM0cTZmMzUzNHY0MzUzNDUzdnEzcTMyKioqKioqKio" + "qKipBMSp5dHJoDVBPMSoxMTEtYWFhKjEwMDAwMDAqQVMqOTAuMDAqQkQqQUsqMjM0MjM1djM1MzRx" + "NmYzNTM0djQzNTM0NTN2cTNxMzIqKioqKioqKioqKkExKnl0cmgNUE8xKjExMS1hYWEqMTAwMDAwM" + "CpBUyo5MC4wMCpCRCpBSyoyMzQyMzV2MzUzNHE2ZjM1MzR2NDM1MzQ1M3ZxM3EzMioqKioqKioqKi" + "oqQTEqeXRyaA1QTzEqMTExLWFhYSoxMDAwMDAwKkFTKjkwLjAwKkJEKkFLKjIzNDIzNXYzNTM0cTZ" + "mMzUzNHY0MzUzNDUzdnEzcTMyKioqKioqKioqKipBMSp5dHJoDVBPMSoxMTEtYWFhKjEwMDAwMDAq" + "QVMqOTAuMDAqQkQqQUsqMjM0MjM1djM1MzRxNmYzNTM0djQzNTM0NTN2cTNxMzIqKioqKioqKioqK" + "kExKnl0cmgNUE8xKjExMS1hYWEqMTAwMDAwMCpBUyo5MC4wMCpCRCpBSyoyMzQyMzV2MzUzNHE2Zj" + "M1MzR2NDM1MzQ1M3ZxM3EzMioqKioqKioqKioqQTEqeXRyaA1QTzEqMTExLWFhYSoxMDAwMDAwKkF" + "TKjkwLjAwKkJEKkFLKjIzNDIzNXYzNTM0cTZmMzUzNHY0MzUzNDUzdnEzcTMyKioqKioqKioqKipB" + "MSp5dHJoDVBPMSoxMTEtYWFhKjEwMDAwMDAqQVMqOTAuMDAqQkQqQUsqMjM0MjM1djM1MzRxNmYzN" + "TM0djQzNTM0NTN2cTNxMzIqKioqKioqKioqKkExKnl0cmgNQ1RUKjENU0UqMjIqMDAwMDQwMDAxDU" + "dFKjEqMDAwMDAwMDA0DUlFQSoxKjAwMDAwMDAwMQ0="); CMSCompressedDataParser ed = new CMSCompressedDataParser(compData); assertEquals(true, Arrays.equals(uncompData, CMSTestUtil.streamToByteArray(ed.getContent().getContentStream()))); } public void testEach() throws Exception { byte[] testData = "Hello world!".getBytes(); CMSCompressedDataStreamGenerator gen = new CMSCompressedDataStreamGenerator(); ByteArrayOutputStream bOut = new ByteArrayOutputStream(); OutputStream cOut = gen.open(bOut, CMSCompressedDataStreamGenerator.ZLIB); cOut.write(testData); cOut.close(); CMSCompressedDataParser ed = new CMSCompressedDataParser(bOut.toByteArray()); assertEquals(true, Arrays.equals(testData, CMSTestUtil.streamToByteArray(ed.getContent().getContentStream()))); } public void test1000() throws Exception { byte[] testData = new byte[10000]; Random rand = new Random(); rand.setSeed(0); for (int i = 0; i != 10; i++) { CMSCompressedDataStreamGenerator gen = new CMSCompressedDataStreamGenerator(); ByteArrayOutputStream bOut = new ByteArrayOutputStream(); OutputStream cOut = gen.open(bOut, CMSCompressedDataStreamGenerator.ZLIB); rand.nextBytes(testData); cOut.write(testData); cOut.close(); CMSCompressedDataParser ed = new CMSCompressedDataParser(bOut.toByteArray()); assertEquals(true, Arrays.equals(testData, CMSTestUtil.streamToByteArray(ed.getContent().getContentStream()))); } } public static Test suite() { return new TestSuite(CompressedDataStreamTest.class); } } bouncycastle-1.49.orig/test/src/org/bouncycastle/cms/test/SunProviderTest.java0000644000175000017500000002171411726257322027221 0ustar ebourgebourgpackage org.bouncycastle.cms.test; import java.io.ByteArrayInputStream; import java.io.ByteArrayOutputStream; import java.io.IOException; import java.io.OutputStream; import java.math.BigInteger; import java.security.GeneralSecurityException; import java.security.KeyPair; import java.security.KeyPairGenerator; import java.security.MessageDigest; import java.security.NoSuchAlgorithmException; import java.security.NoSuchProviderException; import java.security.PrivateKey; import java.security.PublicKey; import java.security.SecureRandom; import java.security.cert.CertStore; import java.security.cert.CollectionCertStoreParameters; import java.security.cert.X509Certificate; import java.util.ArrayList; import java.util.Arrays; import java.util.Collection; import java.util.Date; import java.util.Iterator; import java.util.List; import junit.framework.Test; import junit.framework.TestCase; import junit.framework.TestSuite; import org.bouncycastle.asn1.ASN1InputStream; import org.bouncycastle.asn1.cms.ContentInfo; import org.bouncycastle.asn1.pkcs.PKCSObjectIdentifiers; import org.bouncycastle.asn1.x509.X509Name; import org.bouncycastle.cms.CMSEnvelopedData; import org.bouncycastle.cms.CMSEnvelopedDataGenerator; import org.bouncycastle.cms.CMSProcessable; import org.bouncycastle.cms.CMSProcessableByteArray; import org.bouncycastle.cms.CMSSignedData; import org.bouncycastle.cms.CMSSignedDataGenerator; import org.bouncycastle.cms.CMSSignedDataParser; import org.bouncycastle.cms.CMSSignedDataStreamGenerator; import org.bouncycastle.cms.CMSTypedStream; import org.bouncycastle.cms.RecipientInformation; import org.bouncycastle.cms.RecipientInformationStore; import org.bouncycastle.cms.SignerInformation; import org.bouncycastle.cms.SignerInformationStore; import org.bouncycastle.cms.jcajce.JcaX509CertSelectorConverter; import org.bouncycastle.x509.X509V3CertificateGenerator; public class SunProviderTest extends TestCase { static KeyPair keyPair; static X509Certificate keyCert; private static final String TEST_MESSAGE = "Hello World!"; private static final JcaX509CertSelectorConverter selectorConverter = new JcaX509CertSelectorConverter(); static { try { keyPair = generateKeyPair(); String origDN = "O=Bouncy Castle, C=AU"; keyCert = makeCertificate(keyPair, origDN, keyPair, origDN); } catch (Exception e) { throw new RuntimeException(e); } } public void testSHA1WithRSAEncapsulated() throws Exception { List certList = new ArrayList(); CMSProcessable msg = new CMSProcessableByteArray(TEST_MESSAGE.getBytes()); certList.add(keyCert); CertStore certsAndCrls = CertStore.getInstance("Collection", new CollectionCertStoreParameters(certList), "SUN"); CMSSignedDataGenerator gen = new CMSSignedDataGenerator(); gen.addSigner(keyPair.getPrivate(), keyCert, CMSSignedDataGenerator.DIGEST_SHA1); gen.addCertificatesAndCRLs(certsAndCrls); CMSSignedData s = gen.generate(msg, true, "SunRsaSign"); ByteArrayInputStream bIn = new ByteArrayInputStream(s.getEncoded()); ASN1InputStream aIn = new ASN1InputStream(bIn); s = new CMSSignedData(ContentInfo.getInstance(aIn.readObject())); certsAndCrls = s.getCertificatesAndCRLs("Collection", "SUN"); SignerInformationStore signers = s.getSignerInfos(); Collection c = signers.getSigners(); Iterator it = c.iterator(); while (it.hasNext()) { SignerInformation signer = (SignerInformation)it.next(); Collection certCollection = certsAndCrls.getCertificates(selectorConverter.getCertSelector(signer.getSID())); Iterator certIt = certCollection.iterator(); X509Certificate cert = (X509Certificate)certIt.next(); assertEquals(true, signer.verify(cert, "SunRsaSign")); } } public void testSHA1WithRSAStream() throws Exception { List certList = new ArrayList(); ByteArrayOutputStream bOut = new ByteArrayOutputStream(); certList.add(keyCert); CertStore certsAndCrls = CertStore.getInstance("Collection", new CollectionCertStoreParameters(certList), "SUN"); CMSSignedDataStreamGenerator gen = new CMSSignedDataStreamGenerator(); gen.addSigner(keyPair.getPrivate(), keyCert, CMSSignedDataStreamGenerator.DIGEST_SHA1, "SunRsaSign"); gen.addCertificatesAndCRLs(certsAndCrls); OutputStream sigOut = gen.open(bOut); sigOut.write(TEST_MESSAGE.getBytes()); sigOut.close(); CMSSignedDataParser sp = new CMSSignedDataParser( new CMSTypedStream(new ByteArrayInputStream(TEST_MESSAGE.getBytes())), bOut.toByteArray()); sp.getSignedContent().drain(); // // compute expected content digest // MessageDigest md = MessageDigest.getInstance("SHA1", "SUN"); byte[] contentDigest = md.digest(TEST_MESSAGE.getBytes()); CertStore certStore = sp.getCertificatesAndCRLs("Collection", "SUN"); SignerInformationStore signers = sp.getSignerInfos(); Collection c = signers.getSigners(); Iterator it = c.iterator(); while (it.hasNext()) { SignerInformation signer = (SignerInformation)it.next(); Collection certCollection = certStore.getCertificates(selectorConverter.getCertSelector(signer.getSID())); Iterator certIt = certCollection.iterator(); X509Certificate cert = (X509Certificate)certIt.next(); assertEquals(true, signer.verify(cert, "SunRsaSign")); if (contentDigest != null) { assertTrue(MessageDigest.isEqual(contentDigest, signer.getContentDigest())); } } } public void testKeyTransDES() throws Exception { testKeyTrans(CMSEnvelopedDataGenerator.DES_EDE3_CBC); } public void testKeyTransAES128() throws Exception { testKeyTrans(CMSEnvelopedDataGenerator.AES128_CBC); } public void testKeyTransAES192() throws Exception { testKeyTrans(CMSEnvelopedDataGenerator.AES192_CBC); } public void testKeyTransAES256() throws Exception { testKeyTrans(CMSEnvelopedDataGenerator.AES256_CBC); } private void testKeyTrans(String algorithm) throws Exception { byte[] data = "WallaWallaWashington".getBytes(); CMSEnvelopedDataGenerator edGen = new CMSEnvelopedDataGenerator(); edGen.addKeyTransRecipient(keyCert); CMSEnvelopedData ed = edGen.generate( new CMSProcessableByteArray(data), algorithm, "SunJCE"); RecipientInformationStore recipients = ed.getRecipientInfos(); assertEquals(ed.getEncryptionAlgOID(), algorithm); Collection c = recipients.getRecipients(); assertEquals(1, c.size()); Iterator it = c.iterator(); while (it.hasNext()) { RecipientInformation recipient = (RecipientInformation)it.next(); assertEquals(recipient.getKeyEncryptionAlgOID(), PKCSObjectIdentifiers.rsaEncryption.getId()); byte[] recData = recipient.getContent(keyPair.getPrivate(), "SunJCE"); assertEquals(true, Arrays.equals(data, recData)); } } private static KeyPair generateKeyPair() throws NoSuchProviderException, NoSuchAlgorithmException { KeyPairGenerator kpg = KeyPairGenerator.getInstance("RSA", "SunRsaSign"); kpg.initialize(512, new SecureRandom()); return kpg.generateKeyPair(); } private static X509Certificate makeCertificate(KeyPair subKP, String _subDN, KeyPair issKP, String _issDN) throws GeneralSecurityException, IOException { PublicKey subPub = subKP.getPublic(); PrivateKey issPriv = issKP.getPrivate(); PublicKey issPub = issKP.getPublic(); X509V3CertificateGenerator v3CertGen = new X509V3CertificateGenerator(); v3CertGen.reset(); v3CertGen.setSerialNumber(BigInteger.valueOf(1)); v3CertGen.setIssuerDN(new X509Name(_issDN)); v3CertGen.setNotBefore(new Date(System.currentTimeMillis())); v3CertGen.setNotAfter(new Date(System.currentTimeMillis() + (1000L * 60 * 60 * 24 * 100))); v3CertGen.setSubjectDN(new X509Name(_subDN)); v3CertGen.setPublicKey(subPub); v3CertGen.setSignatureAlgorithm("SHA1WithRSA"); X509Certificate _cert = v3CertGen.generate(issPriv, "SunRsaSign"); _cert.checkValidity(new Date()); _cert.verify(issPub); return _cert; } public static Test suite() throws Exception { return new TestSuite(SunProviderTest.class); } } bouncycastle-1.49.orig/test/src/org/bouncycastle/cms/test/ConverterTest.java0000644000175000017500000000742111726257111026703 0ustar ebourgebourgpackage org.bouncycastle.cms.test; import java.math.BigInteger; import java.security.cert.X509CertSelector; import junit.framework.Test; import junit.framework.TestCase; import junit.framework.TestSuite; import org.bouncycastle.asn1.DEROctetString; import org.bouncycastle.asn1.x500.X500Name; import org.bouncycastle.cms.KeyTransRecipientId; import org.bouncycastle.cms.SignerId; import org.bouncycastle.cms.jcajce.JcaSelectorConverter; import org.bouncycastle.cms.jcajce.JcaX509CertSelectorConverter; import org.bouncycastle.util.Arrays; public class ConverterTest extends TestCase { public void testSignerIdConversion() throws Exception { JcaX509CertSelectorConverter converter = new JcaX509CertSelectorConverter(); JcaSelectorConverter toSelector = new JcaSelectorConverter(); SignerId sid1 = new SignerId(new X500Name("CN=Test"), BigInteger.valueOf(1), new byte[20]); X509CertSelector conv = converter.getCertSelector(sid1); assertTrue(conv.getIssuerAsString().equals("CN=Test")); assertTrue(Arrays.areEqual(conv.getSubjectKeyIdentifier(), new DEROctetString(new byte[20]).getEncoded())); assertEquals(conv.getSerialNumber(), sid1.getSerialNumber()); SignerId sid2 = toSelector.getSignerId(conv); assertEquals(sid1, sid2); sid1 = new SignerId(new X500Name("CN=Test"), BigInteger.valueOf(1)); conv = converter.getCertSelector(sid1); assertTrue(conv.getIssuerAsString().equals("CN=Test")); assertNull(conv.getSubjectKeyIdentifier()); assertEquals(conv.getSerialNumber(), sid1.getSerialNumber()); sid2 = toSelector.getSignerId(conv); assertEquals(sid1, sid2); sid1 = new SignerId(new byte[20]); conv = converter.getCertSelector(sid1); assertNull(conv.getIssuerAsString()); assertTrue(Arrays.areEqual(conv.getSubjectKeyIdentifier(), new DEROctetString(new byte[20]).getEncoded())); assertNull(conv.getSerialNumber()); sid2 = toSelector.getSignerId(conv); assertEquals(sid1, sid2); } public void testRecipientIdConversion() throws Exception { JcaX509CertSelectorConverter converter = new JcaX509CertSelectorConverter(); JcaSelectorConverter toSelector = new JcaSelectorConverter(); KeyTransRecipientId ktid1 = new KeyTransRecipientId(new X500Name("CN=Test"), BigInteger.valueOf(1), new byte[20]); X509CertSelector conv = converter.getCertSelector(ktid1); assertTrue(conv.getIssuerAsString().equals("CN=Test")); assertTrue(Arrays.areEqual(conv.getSubjectKeyIdentifier(), new DEROctetString(new byte[20]).getEncoded())); assertEquals(conv.getSerialNumber(), ktid1.getSerialNumber()); KeyTransRecipientId ktid2 = toSelector.getKeyTransRecipientId(conv); assertEquals(ktid1, ktid2); ktid1 = new KeyTransRecipientId(new X500Name("CN=Test"), BigInteger.valueOf(1)); conv = converter.getCertSelector(ktid1); assertTrue(conv.getIssuerAsString().equals("CN=Test")); assertNull(conv.getSubjectKeyIdentifier()); assertEquals(conv.getSerialNumber(), ktid1.getSerialNumber()); ktid2 = toSelector.getKeyTransRecipientId(conv); assertEquals(ktid1, ktid2); ktid1 = new KeyTransRecipientId(new byte[20]); conv = converter.getCertSelector(ktid1); assertNull(conv.getIssuerAsString()); assertTrue(Arrays.areEqual(conv.getSubjectKeyIdentifier(), new DEROctetString(new byte[20]).getEncoded())); assertNull(conv.getSerialNumber()); ktid2 = toSelector.getKeyTransRecipientId(conv); assertEquals(ktid1, ktid2); } public static Test suite() throws Exception { return new TestSuite(ConverterTest.class); } } bouncycastle-1.49.orig/test/src/org/bouncycastle/cms/test/NewEnvelopedDataTest.java0000644000175000017500000013507412033230517030120 0ustar ebourgebourgpackage org.bouncycastle.cms.test; import java.io.IOException; import java.security.GeneralSecurityException; import java.security.Key; import java.security.KeyFactory; import java.security.KeyPair; import java.security.NoSuchAlgorithmException; import java.security.NoSuchProviderException; import java.security.PrivateKey; import java.security.cert.CertificateEncodingException; import java.security.cert.X509Certificate; import java.security.spec.PKCS8EncodedKeySpec; import java.util.Arrays; import java.util.Collection; import java.util.Hashtable; import java.util.Iterator; import javax.crypto.SecretKey; import javax.crypto.spec.SecretKeySpec; import junit.framework.Test; import junit.framework.TestCase; import junit.framework.TestSuite; import org.bouncycastle.asn1.ASN1InputStream; import org.bouncycastle.asn1.ASN1ObjectIdentifier; import org.bouncycastle.asn1.ASN1OctetString; import org.bouncycastle.asn1.ASN1Sequence; import org.bouncycastle.asn1.DERObjectIdentifier; import org.bouncycastle.asn1.DEROctetString; import org.bouncycastle.asn1.DERSet; import org.bouncycastle.asn1.DERUTF8String; import org.bouncycastle.asn1.cms.Attribute; import org.bouncycastle.asn1.cms.AttributeTable; import org.bouncycastle.asn1.kisa.KISAObjectIdentifiers; import org.bouncycastle.asn1.nist.NISTObjectIdentifiers; import org.bouncycastle.asn1.ntt.NTTObjectIdentifiers; import org.bouncycastle.asn1.pkcs.PKCSObjectIdentifiers; import org.bouncycastle.asn1.x500.X500Name; import org.bouncycastle.asn1.x509.X509Extension; import org.bouncycastle.cert.X509CertificateHolder; import org.bouncycastle.cert.jcajce.JcaX509CertificateHolder; import org.bouncycastle.cms.CMSAlgorithm; import org.bouncycastle.cms.CMSEnvelopedData; import org.bouncycastle.cms.CMSEnvelopedDataGenerator; import org.bouncycastle.cms.CMSException; import org.bouncycastle.cms.CMSProcessableByteArray; import org.bouncycastle.cms.KeyTransRecipientInformation; import org.bouncycastle.cms.OriginatorInfoGenerator; import org.bouncycastle.cms.OriginatorInformation; import org.bouncycastle.cms.PasswordRecipient; import org.bouncycastle.cms.PasswordRecipientInformation; import org.bouncycastle.cms.RecipientId; import org.bouncycastle.cms.RecipientInformation; import org.bouncycastle.cms.RecipientInformationStore; import org.bouncycastle.cms.SimpleAttributeTableGenerator; import org.bouncycastle.cms.bc.BcCMSContentEncryptorBuilder; import org.bouncycastle.cms.bc.BcRSAKeyTransRecipientInfoGenerator; import org.bouncycastle.cms.jcajce.JceCMSContentEncryptorBuilder; import org.bouncycastle.cms.jcajce.JceKEKEnvelopedRecipient; import org.bouncycastle.cms.jcajce.JceKEKRecipientInfoGenerator; import org.bouncycastle.cms.jcajce.JceKeyAgreeEnvelopedRecipient; import org.bouncycastle.cms.jcajce.JceKeyAgreeRecipientId; import org.bouncycastle.cms.jcajce.JceKeyAgreeRecipientInfoGenerator; import org.bouncycastle.cms.jcajce.JceKeyTransEnvelopedRecipient; import org.bouncycastle.cms.jcajce.JceKeyTransRecipientId; import org.bouncycastle.cms.jcajce.JceKeyTransRecipientInfoGenerator; import org.bouncycastle.cms.jcajce.JcePasswordEnvelopedRecipient; import org.bouncycastle.cms.jcajce.JcePasswordRecipientInfoGenerator; import org.bouncycastle.jce.provider.BouncyCastleProvider; import org.bouncycastle.operator.OutputEncryptor; import org.bouncycastle.util.encoders.Base64; import org.bouncycastle.util.encoders.Hex; public class NewEnvelopedDataTest extends TestCase { private static final String BC = BouncyCastleProvider.PROVIDER_NAME; private static String _signDN; private static KeyPair _signKP; private static X509Certificate _signCert; private static String _origDN; private static KeyPair _origKP; private static X509Certificate _origCert; private static String _reciDN; private static String _reciDN2; private static KeyPair _reciKP; private static X509Certificate _reciCert; private static KeyPair _origEcKP; private static KeyPair _reciEcKP; private static X509Certificate _reciEcCert; private static KeyPair _reciEcKP2; private static X509Certificate _reciEcCert2; private static boolean _initialised = false; private byte[] oldKEK = Base64.decode( "MIAGCSqGSIb3DQEHA6CAMIACAQIxQaI/MD0CAQQwBwQFAQIDBAUwDQYJYIZIAWUDBAEFBQAEI" + "Fi2eHTPM4bQSjP4DUeDzJZLpfemW2gF1SPq7ZPHJi1mMIAGCSqGSIb3DQEHATAUBggqhkiG9w" + "0DBwQImtdGyUdGGt6ggAQYk9X9z01YFBkU7IlS3wmsKpm/zpZClTceAAAAAAAAAAAAAA=="); private byte[] ecKeyAgreeMsgAES256 = Base64.decode( "MIAGCSqGSIb3DQEHA6CAMIACAQIxgcShgcECAQOgQ6FBMAsGByqGSM49AgEF" + "AAMyAAPdXlSTpub+qqno9hUGkUDl+S3/ABhPziIB5yGU4678tgOgU5CiKG9Z" + "kfnabIJ3nZYwGgYJK4EFEIZIPwACMA0GCWCGSAFlAwQBLQUAMFswWTAtMCgx" + "EzARBgNVBAMTCkFkbWluLU1EU0UxETAPBgNVBAoTCDRCQ1QtMklEAgEBBCi/" + "rJRLbFwEVW6PcLLmojjW9lI/xGD7CfZzXrqXFw8iHaf3hTRau1gYMIAGCSqG" + "SIb3DQEHATAdBglghkgBZQMEASoEEMtCnKKPwccmyrbgeSIlA3qggAQQDLw8" + "pNJR97bPpj6baG99bQQQwhEDsoj5Xg1oOxojHVcYzAAAAAAAAAAAAAA="); private byte[] ecKeyAgreeMsgAES128 = Base64.decode( "MIAGCSqGSIb3DQEHA6CAMIACAQIxgbShgbECAQOgQ6FBMAsGByqGSM49AgEF" + "AAMyAAL01JLEgKvKh5rbxI/hOxs/9WEezMIsAbUaZM4l5tn3CzXAN505nr5d" + "LhrcurMK+tAwGgYJK4EFEIZIPwACMA0GCWCGSAFlAwQBBQUAMEswSTAtMCgx" + "EzARBgNVBAMTCkFkbWluLU1EU0UxETAPBgNVBAoTCDRCQ1QtMklEAgEBBBhi" + "FLjc5g6aqDT3f8LomljOwl1WTrplUT8wgAYJKoZIhvcNAQcBMB0GCWCGSAFl" + "AwQBAgQQzXjms16Y69S/rB0EbHqRMaCABBAFmc/QdVW6LTKdEy97kaZzBBBa" + "fQuviUS03NycpojELx0bAAAAAAAAAAAAAA=="); private byte[] ecKeyAgreeMsgDESEDE = Base64.decode( "MIAGCSqGSIb3DQEHA6CAMIACAQIxgcahgcMCAQOgQ6FBMAsGByqGSM49AgEF" + "AAMyAALIici6Nx1WN5f0ThH2A8ht9ovm0thpC5JK54t73E1RDzCifePaoQo0" + "xd6sUqoyGaYwHAYJK4EFEIZIPwACMA8GCyqGSIb3DQEJEAMGBQAwWzBZMC0w" + "KDETMBEGA1UEAxMKQWRtaW4tTURTRTERMA8GA1UEChMINEJDVC0ySUQCAQEE" + "KJuqZQ1NB1vXrKPOnb4TCpYOsdm6GscWdwAAZlm2EHMp444j0s55J9wwgAYJ" + "KoZIhvcNAQcBMBQGCCqGSIb3DQMHBAjwnsDMsafCrKCABBjyPvqFOVMKxxut" + "VfTx4fQlNGJN8S2ATRgECMcTQ/dsmeViAAAAAAAAAAAAAA=="); private byte[] ecMQVKeyAgreeMsgAES128 = Base64.decode( "MIAGCSqGSIb3DQEHA6CAMIACAQIxgf2hgfoCAQOgQ6FBMAsGByqGSM49AgEF" + "AAMyAAPDKU+0H58tsjpoYmYCInMr/FayvCCkupebgsnpaGEB7qS9vzcNVUj6" + "mrnmiC2grpmhRwRFMEMwQTALBgcqhkjOPQIBBQADMgACZpD13z9c7DzRWx6S" + "0xdbq3S+EJ7vWO+YcHVjTD8NcQDcZcWASW899l1PkL936zsuMBoGCSuBBRCG" + "SD8AEDANBglghkgBZQMEAQUFADBLMEkwLTAoMRMwEQYDVQQDEwpBZG1pbi1N" + "RFNFMREwDwYDVQQKEwg0QkNULTJJRAIBAQQYFq58L71nyMK/70w3nc6zkkRy" + "RL7DHmpZMIAGCSqGSIb3DQEHATAdBglghkgBZQMEAQIEEDzRUpreBsZXWHBe" + "onxOtSmggAQQ7csAZXwT1lHUqoazoy8bhAQQq+9Zjj8iGdOWgyebbfj67QAA" + "AAAAAAAAAAA="); private byte[] ecKeyAgreeKey = Base64.decode( "MIG2AgEAMBAGByqGSM49AgEGBSuBBAAiBIGeMIGbAgEBBDC8vp7xVTbKSgYVU5Wc" + "hGkWbzaj+yUFETIWP1Dt7+WSpq3ikSPdl7PpHPqnPVZfoIWhZANiAgSYHTgxf+Dd" + "Tt84dUvuSKkFy3RhjxJmjwIscK6zbEUzKhcPQG2GHzXhWK5x1kov0I74XpGhVkya" + "ElH5K6SaOXiXAzcyNGggTOk4+ZFnz5Xl0pBje3zKxPhYu0SnCw7Pcqw="); private byte[] bobPrivRsaEncrypt = Base64.decode( "MIIChQIBADANBgkqhkiG9w0BAQEFAASCAmAwggJcAgEAAoGBAKnhZ5g/OdVf" + "8qCTQV6meYmFyDVdmpFb+x0B2hlwJhcPvaUi0DWFbXqYZhRBXM+3twg7CcmR" + "uBlpN235ZR572akzJKN/O7uvRgGGNjQyywcDWVL8hYsxBLjMGAgUSOZPHPtd" + "YMTgXB9T039T2GkB8QX4enDRvoPGXzjPHCyqaqfrAgMBAAECgYBnzUhMmg2P" + "mMIbZf8ig5xt8KYGHbztpwOIlPIcaw+LNd4Ogngwy+e6alatd8brUXlweQqg" + "9P5F4Kmy9Bnah5jWMIR05PxZbMHGd9ypkdB8MKCixQheIXFD/A0HPfD6bRSe" + "TmPwF1h5HEuYHD09sBvf+iU7o8AsmAX2EAnYh9sDGQJBANDDIsbeopkYdo+N" + "vKZ11mY/1I1FUox29XLE6/BGmvE+XKpVC5va3Wtt+Pw7PAhDk7Vb/s7q/WiE" + "I2Kv8zHCueUCQQDQUfweIrdb7bWOAcjXq/JY1PeClPNTqBlFy2bKKBlf4hAr" + "84/sajB0+E0R9KfEILVHIdxJAfkKICnwJAiEYH2PAkA0umTJSChXdNdVUN5q" + "SO8bKlocSHseIVnDYDubl6nA7xhmqU5iUjiEzuUJiEiUacUgFJlaV/4jbOSn" + "I3vQgLeFAkEAni+zN5r7CwZdV+EJBqRd2ZCWBgVfJAZAcpw6iIWchw+dYhKI" + "FmioNRobQ+g4wJhprwMKSDIETukPj3d9NDAlBwJAVxhn1grStavCunrnVNqc" + "BU+B1O8BiR4yPWnLMcRSyFRVJQA7HCp8JlDV6abXd8vPFfXuC9WN7rOvTKF8" + "Y0ZB9qANMAsGA1UdDzEEAwIAEA=="); private byte[] rfc4134ex5_1 = Base64.decode( "MIIBHgYJKoZIhvcNAQcDoIIBDzCCAQsCAQAxgcAwgb0CAQAwJjASMRAwDgYD" + "VQQDEwdDYXJsUlNBAhBGNGvHgABWvBHTbi7NXXHQMA0GCSqGSIb3DQEBAQUA" + "BIGAC3EN5nGIiJi2lsGPcP2iJ97a4e8kbKQz36zg6Z2i0yx6zYC4mZ7mX7FB" + "s3IWg+f6KgCLx3M1eCbWx8+MDFbbpXadCDgO8/nUkUNYeNxJtuzubGgzoyEd" + "8Ch4H/dd9gdzTd+taTEgS0ipdSJuNnkVY4/M652jKKHRLFf02hosdR8wQwYJ" + "KoZIhvcNAQcBMBQGCCqGSIb3DQMHBAgtaMXpRwZRNYAgDsiSf8Z9P43LrY4O" + "xUk660cu1lXeCSFOSOpOJ7FuVyU="); private byte[] rfc4134ex5_2 = Base64.decode( "MIIBZQYJKoZIhvcNAQcDoIIBVjCCAVICAQIxggEAMIG9AgEAMCYwEjEQMA4G" + "A1UEAxMHQ2FybFJTQQIQRjRrx4AAVrwR024uzV1x0DANBgkqhkiG9w0BAQEF" + "AASBgJQmQojGi7Z4IP+CVypBmNFoCDoEp87khtgyff2N4SmqD3RxPx+8hbLQ" + "t9i3YcMwcap+aiOkyqjMalT03VUC0XBOGv+HYI3HBZm/aFzxoq+YOXAWs5xl" + "GerZwTOc9j6AYlK4qXvnztR5SQ8TBjlzytm4V7zg+TGrnGVNQBNw47Ewoj4C" + "AQQwDQQLTWFpbExpc3RSQzIwEAYLKoZIhvcNAQkQAwcCAToEGHcUr5MSJ/g9" + "HnJVHsQ6X56VcwYb+OfojTBJBgkqhkiG9w0BBwEwGgYIKoZIhvcNAwIwDgIC" + "AKAECJwE0hkuKlWhgCBeKNXhojuej3org9Lt7n+wWxOhnky5V50vSpoYRfRR" + "yw=="); public NewEnvelopedDataTest() { } private static void init() throws Exception { if (!_initialised) { _initialised = true; _signDN = "O=Bouncy Castle, C=AU"; _signKP = CMSTestUtil.makeKeyPair(); _signCert = CMSTestUtil.makeCertificate(_signKP, _signDN, _signKP, _signDN); _origDN = "CN=Bob, OU=Sales, O=Bouncy Castle, C=AU"; _origKP = CMSTestUtil.makeKeyPair(); _origCert = CMSTestUtil.makeCertificate(_origKP, _origDN, _signKP, _signDN); _reciDN = "CN=Doug, OU=Sales, O=Bouncy Castle, C=AU"; _reciDN2 = "CN=Fred, OU=Sales, O=Bouncy Castle, C=AU"; _reciKP = CMSTestUtil.makeKeyPair(); _reciCert = CMSTestUtil.makeCertificate(_reciKP, _reciDN, _signKP, _signDN); _origEcKP = CMSTestUtil.makeEcDsaKeyPair(); _reciEcKP = CMSTestUtil.makeEcDsaKeyPair(); _reciEcCert = CMSTestUtil.makeCertificate(_reciEcKP, _reciDN, _signKP, _signDN); _reciEcKP2 = CMSTestUtil.makeEcDsaKeyPair(); _reciEcCert2 = CMSTestUtil.makeCertificate(_reciEcKP2, _reciDN2, _signKP, _signDN); } } public static void main( String args[]) throws Exception { junit.textui.TestRunner.run(NewEnvelopedDataTest.suite()); } public static Test suite() throws Exception { init(); return new CMSTestSetup(new TestSuite(NewEnvelopedDataTest.class)); } public void testUnprotectedAttributes() throws Exception { byte[] data = "WallaWallaWashington".getBytes(); CMSEnvelopedDataGenerator edGen = new CMSEnvelopedDataGenerator(); edGen.addRecipientInfoGenerator(new JceKeyTransRecipientInfoGenerator(_reciCert).setProvider(BC)); Hashtable attrs = new Hashtable(); attrs.put(PKCSObjectIdentifiers.id_aa_contentHint, new Attribute(PKCSObjectIdentifiers.id_aa_contentHint, new DERSet(new DERUTF8String("Hint")))); attrs.put(PKCSObjectIdentifiers.id_aa_receiptRequest, new Attribute(PKCSObjectIdentifiers.id_aa_receiptRequest, new DERSet(new DERUTF8String("Request")))); AttributeTable attrTable = new AttributeTable(attrs); edGen.setUnprotectedAttributeGenerator(new SimpleAttributeTableGenerator(attrTable)); CMSEnvelopedData ed = edGen.generate( new CMSProcessableByteArray(data), new JceCMSContentEncryptorBuilder(CMSAlgorithm.DES_EDE3_CBC).setProvider(BC).build()); RecipientInformationStore recipients = ed.getRecipientInfos(); assertEquals(ed.getEncryptionAlgOID(), CMSEnvelopedDataGenerator.DES_EDE3_CBC); attrTable = ed.getUnprotectedAttributes(); assertEquals(attrs.size(), 2); assertEquals(new DERUTF8String("Hint"), attrTable.get(PKCSObjectIdentifiers.id_aa_contentHint).getAttrValues().getObjectAt(0)); assertEquals(new DERUTF8String("Request"), attrTable.get(PKCSObjectIdentifiers.id_aa_receiptRequest).getAttrValues().getObjectAt(0)); Collection c = recipients.getRecipients(); assertEquals(1, c.size()); Iterator it = c.iterator(); while (it.hasNext()) { RecipientInformation recipient = (RecipientInformation)it.next(); assertEquals(recipient.getKeyEncryptionAlgOID(), PKCSObjectIdentifiers.rsaEncryption.getId()); byte[] recData = recipient.getContent(new JceKeyTransEnvelopedRecipient(_reciKP.getPrivate()).setProvider(BC)); assertEquals(true, Arrays.equals(data, recData)); } } public void testKeyTrans() throws Exception { byte[] data = "WallaWallaWashington".getBytes(); CMSEnvelopedDataGenerator edGen = new CMSEnvelopedDataGenerator(); edGen.addRecipientInfoGenerator(new JceKeyTransRecipientInfoGenerator(_reciCert).setProvider(BC)); edGen.addRecipientInfoGenerator(new JceKeyTransRecipientInfoGenerator(ASN1OctetString.getInstance(ASN1OctetString.getInstance(_reciCert.getExtensionValue(X509Extension.subjectKeyIdentifier.getId())).getOctets()).getOctets(), _reciCert.getPublicKey()).setProvider(BC)); CMSEnvelopedData ed = edGen.generate( new CMSProcessableByteArray(data), new JceCMSContentEncryptorBuilder(CMSAlgorithm.DES_EDE3_CBC).setProvider(BC).build()); RecipientInformationStore recipients = ed.getRecipientInfos(); assertEquals(ed.getEncryptionAlgOID(), CMSEnvelopedDataGenerator.DES_EDE3_CBC); Collection c = recipients.getRecipients(); assertEquals(2, c.size()); Iterator it = c.iterator(); while (it.hasNext()) { RecipientInformation recipient = (RecipientInformation)it.next(); assertEquals(recipient.getKeyEncryptionAlgOID(), PKCSObjectIdentifiers.rsaEncryption.getId()); byte[] recData = recipient.getContent(new JceKeyTransEnvelopedRecipient(_reciKP.getPrivate()).setProvider(BC)); assertEquals(true, Arrays.equals(data, recData)); } RecipientId id = new JceKeyTransRecipientId(_reciCert); Collection collection = recipients.getRecipients(id); if (collection.size() != 2) { fail("recipients not matched using general recipient ID."); } assertTrue(collection.iterator().next() instanceof RecipientInformation); } public void testKeyTransWithAlgMapping() throws Exception { byte[] data = "WallaWallaWashington".getBytes(); CMSEnvelopedDataGenerator edGen = new CMSEnvelopedDataGenerator(); edGen.addRecipientInfoGenerator(new JceKeyTransRecipientInfoGenerator(_reciCert).setAlgorithmMapping(PKCSObjectIdentifiers.rsaEncryption, "RSA/2/PKCS1Padding").setProvider(BC)); CMSEnvelopedData ed = edGen.generate( new CMSProcessableByteArray(data), new JceCMSContentEncryptorBuilder(CMSAlgorithm.DES_EDE3_CBC).setProvider(BC).build()); RecipientInformationStore recipients = ed.getRecipientInfos(); assertEquals(ed.getEncryptionAlgOID(), CMSEnvelopedDataGenerator.DES_EDE3_CBC); Collection c = recipients.getRecipients(); assertEquals(1, c.size()); Iterator it = c.iterator(); while (it.hasNext()) { RecipientInformation recipient = (RecipientInformation)it.next(); assertEquals(recipient.getKeyEncryptionAlgOID(), PKCSObjectIdentifiers.rsaEncryption.getId()); byte[] recData = recipient.getContent(new JceKeyTransEnvelopedRecipient(_reciKP.getPrivate()).setAlgorithmMapping(PKCSObjectIdentifiers.rsaEncryption, "RSA/2/PKCS1Padding").setProvider(BC)); assertEquals(true, Arrays.equals(data, recData)); } RecipientId id = new JceKeyTransRecipientId(_reciCert); Collection collection = recipients.getRecipients(id); if (collection.size() != 1) { fail("recipients not matched using general recipient ID."); } assertTrue(collection.iterator().next() instanceof RecipientInformation); } public void testOriginatorInfoGeneration() throws Exception { byte[] data = "WallaWallaWashington".getBytes(); CMSEnvelopedDataGenerator edGen = new CMSEnvelopedDataGenerator(); X509CertificateHolder origCert = new X509CertificateHolder(_origCert.getEncoded()); edGen.setOriginatorInfo(new OriginatorInfoGenerator(origCert).generate()); edGen.addRecipientInfoGenerator(new JceKeyTransRecipientInfoGenerator(_reciCert).setProvider(BC)); edGen.addRecipientInfoGenerator(new JceKeyTransRecipientInfoGenerator(ASN1OctetString.getInstance(ASN1OctetString.getInstance(_reciCert.getExtensionValue(X509Extension.subjectKeyIdentifier.getId())).getOctets()).getOctets(), _reciCert.getPublicKey()).setProvider(BC)); CMSEnvelopedData ed = edGen.generate( new CMSProcessableByteArray(data), new JceCMSContentEncryptorBuilder(CMSAlgorithm.DES_EDE3_CBC).setProvider(BC).build()); RecipientInformationStore recipients = ed.getRecipientInfos(); assertEquals(ed.getEncryptionAlgOID(), CMSEnvelopedDataGenerator.DES_EDE3_CBC); assertTrue(ed.getOriginatorInfo().getCertificates().getMatches(null).contains(origCert)); Collection c = recipients.getRecipients(); assertEquals(2, c.size()); Iterator it = c.iterator(); while (it.hasNext()) { RecipientInformation recipient = (RecipientInformation)it.next(); assertEquals(recipient.getKeyEncryptionAlgOID(), PKCSObjectIdentifiers.rsaEncryption.getId()); byte[] recData = recipient.getContent(new JceKeyTransEnvelopedRecipient(_reciKP.getPrivate()).setProvider(BC)); assertEquals(true, Arrays.equals(data, recData)); } RecipientId id = new JceKeyTransRecipientId(_reciCert); Collection collection = recipients.getRecipients(id); if (collection.size() != 2) { fail("recipients not matched using general recipient ID."); } assertTrue(collection.iterator().next() instanceof RecipientInformation); } public void testKeyTransRC4() throws Exception { byte[] data = "WallaWallaBouncyCastle".getBytes(); CMSEnvelopedDataGenerator edGen = new CMSEnvelopedDataGenerator(); edGen.addRecipientInfoGenerator(new JceKeyTransRecipientInfoGenerator(_reciCert).setProvider(BC)); CMSEnvelopedData ed = edGen.generate( new CMSProcessableByteArray(data), new JceCMSContentEncryptorBuilder(new ASN1ObjectIdentifier("1.2.840.113549.3.4")).setProvider(BC).build()); RecipientInformationStore recipients = ed.getRecipientInfos(); assertEquals(ed.getEncryptionAlgOID(), "1.2.840.113549.3.4"); Collection c = recipients.getRecipients(); assertEquals(1, c.size()); Iterator it = c.iterator(); while (it.hasNext()) { RecipientInformation recipient = (RecipientInformation)it.next(); byte[] recData = recipient.getContent(new JceKeyTransEnvelopedRecipient(_reciKP.getPrivate()).setProvider(BC)); assertEquals(true, Arrays.equals(data, recData)); } } public void testKeyTrans128RC4() throws Exception { byte[] data = "WallaWallaBouncyCastle".getBytes(); CMSEnvelopedDataGenerator edGen = new CMSEnvelopedDataGenerator(); edGen.addRecipientInfoGenerator(new JceKeyTransRecipientInfoGenerator(_reciCert).setProvider(BC)); CMSEnvelopedData ed = edGen.generate( new CMSProcessableByteArray(data), new JceCMSContentEncryptorBuilder(new ASN1ObjectIdentifier("1.2.840.113549.3.4"), 128).setProvider(BC).build()); RecipientInformationStore recipients = ed.getRecipientInfos(); assertEquals(ed.getEncryptionAlgOID(), "1.2.840.113549.3.4"); Collection c = recipients.getRecipients(); Iterator it = c.iterator(); if (it.hasNext()) { RecipientInformation recipient = (RecipientInformation)it.next(); byte[] recData = recipient.getContent(new JceKeyTransEnvelopedRecipient(_reciKP.getPrivate()).setProvider(BC)); assertEquals(true, Arrays.equals(data, recData)); } else { fail("no recipient found"); } } public void testKeyTransLight128RC4() throws Exception { byte[] data = "WallaWallaBouncyCastle".getBytes(); CMSEnvelopedDataGenerator edGen = new CMSEnvelopedDataGenerator(); edGen.addRecipientInfoGenerator(new BcRSAKeyTransRecipientInfoGenerator(new JcaX509CertificateHolder(_reciCert))); CMSEnvelopedData ed = edGen.generate( new CMSProcessableByteArray(data), new JceCMSContentEncryptorBuilder(new ASN1ObjectIdentifier("1.2.840.113549.3.4"), 128).setProvider(BC).build()); RecipientInformationStore recipients = ed.getRecipientInfos(); assertEquals(ed.getEncryptionAlgOID(), "1.2.840.113549.3.4"); Collection c = recipients.getRecipients(); Iterator it = c.iterator(); if (it.hasNext()) { RecipientInformation recipient = (RecipientInformation)it.next(); byte[] recData = recipient.getContent(new JceKeyTransEnvelopedRecipient(_reciKP.getPrivate()).setProvider(BC)); assertEquals(true, Arrays.equals(data, recData)); } else { fail("no recipient found"); } } public void testKeyTransODES() throws Exception { byte[] data = "WallaWallaBouncyCastle".getBytes(); CMSEnvelopedDataGenerator edGen = new CMSEnvelopedDataGenerator(); edGen.addRecipientInfoGenerator(new JceKeyTransRecipientInfoGenerator(_reciCert).setProvider(BC)); CMSEnvelopedData ed = edGen.generate( new CMSProcessableByteArray(data), new JceCMSContentEncryptorBuilder(new ASN1ObjectIdentifier("1.3.14.3.2.7")).setProvider(BC).build()); RecipientInformationStore recipients = ed.getRecipientInfos(); assertEquals(ed.getEncryptionAlgOID(), "1.3.14.3.2.7"); Collection c = recipients.getRecipients(); Iterator it = c.iterator(); if (it.hasNext()) { RecipientInformation recipient = (RecipientInformation)it.next(); byte[] recData = recipient.getContent(new JceKeyTransEnvelopedRecipient(_reciKP.getPrivate()).setProvider(BC)); assertEquals(true, Arrays.equals(data, recData)); } else { fail("no recipient found"); } } public void testKeyTransSmallAES() throws Exception { byte[] data = new byte[] { 0, 1, 2, 3 }; CMSEnvelopedDataGenerator edGen = new CMSEnvelopedDataGenerator(); edGen.addRecipientInfoGenerator(new JceKeyTransRecipientInfoGenerator(_reciCert).setProvider(BC)); CMSEnvelopedData ed = edGen.generate( new CMSProcessableByteArray(data), new JceCMSContentEncryptorBuilder(CMSAlgorithm.AES128_CBC).setProvider(BC).build()); RecipientInformationStore recipients = ed.getRecipientInfos(); assertEquals(ed.getEncryptionAlgOID(), CMSEnvelopedDataGenerator.AES128_CBC); Collection c = recipients.getRecipients(); Iterator it = c.iterator(); if (it.hasNext()) { RecipientInformation recipient = (RecipientInformation)it.next(); byte[] recData = recipient.getContent(new JceKeyTransEnvelopedRecipient(_reciKP.getPrivate()).setProvider(BC)); assertEquals(true, Arrays.equals(data, recData)); } else { fail("no recipient found"); } } public void testKeyTransDESEDE3Light() throws Exception { byte[] data = new byte[] { 0, 1, 2, 3 }; CMSEnvelopedDataGenerator edGen = new CMSEnvelopedDataGenerator(); edGen.addRecipientInfoGenerator(new BcRSAKeyTransRecipientInfoGenerator(new JcaX509CertificateHolder(_reciCert))); CMSEnvelopedData ed = edGen.generate( new CMSProcessableByteArray(data), new BcCMSContentEncryptorBuilder(CMSAlgorithm.DES_EDE3_CBC, 192).build()); RecipientInformationStore recipients = ed.getRecipientInfos(); assertEquals(ed.getEncryptionAlgOID(), CMSEnvelopedDataGenerator.DES_EDE3_CBC); Collection c = recipients.getRecipients(); Iterator it = c.iterator(); if (it.hasNext()) { RecipientInformation recipient = (RecipientInformation)it.next(); byte[] recData = recipient.getContent(new JceKeyTransEnvelopedRecipient(_reciKP.getPrivate()).setProvider(BC)); assertEquals(true, Arrays.equals(data, recData)); } else { fail("no recipient found"); } } public void testKeyTransDES() throws Exception { tryKeyTrans(CMSAlgorithm.DES_CBC, CMSAlgorithm.DES_CBC, 8, DEROctetString.class); } public void testKeyTransCAST5() throws Exception { tryKeyTrans(CMSAlgorithm.CAST5_CBC, CMSAlgorithm.CAST5_CBC, 16, ASN1Sequence.class); } public void testKeyTransAES128() throws Exception { tryKeyTrans(CMSAlgorithm.AES128_CBC, NISTObjectIdentifiers.id_aes128_CBC, 16, DEROctetString.class); } public void testKeyTransAES192() throws Exception { tryKeyTrans(CMSAlgorithm.AES192_CBC, NISTObjectIdentifiers.id_aes192_CBC, 24, DEROctetString.class); } public void testKeyTransAES256() throws Exception { tryKeyTrans(CMSAlgorithm.AES256_CBC, NISTObjectIdentifiers.id_aes256_CBC, 32, DEROctetString.class); } public void testKeyTransSEED() throws Exception { tryKeyTrans(CMSAlgorithm.SEED_CBC, KISAObjectIdentifiers.id_seedCBC, 16, DEROctetString.class); } public void testKeyTransCamellia128() throws Exception { tryKeyTrans(CMSAlgorithm.CAMELLIA128_CBC, NTTObjectIdentifiers.id_camellia128_cbc, 16, DEROctetString.class); } public void testKeyTransCamellia192() throws Exception { tryKeyTrans(CMSAlgorithm.CAMELLIA192_CBC, NTTObjectIdentifiers.id_camellia192_cbc, 24, DEROctetString.class); } public void testKeyTransCamellia256() throws Exception { tryKeyTrans(CMSAlgorithm.CAMELLIA256_CBC, NTTObjectIdentifiers.id_camellia256_cbc, 32, DEROctetString.class); } private void tryKeyTrans(ASN1ObjectIdentifier generatorOID, ASN1ObjectIdentifier checkOID, int keySize, Class asn1Params) throws Exception { byte[] data = "WallaWallaWashington".getBytes(); CMSEnvelopedDataGenerator edGen = new CMSEnvelopedDataGenerator(); edGen.addRecipientInfoGenerator(new JceKeyTransRecipientInfoGenerator(_reciCert).setProvider(BC)); OutputEncryptor encryptor = new JceCMSContentEncryptorBuilder(generatorOID).setProvider(BC).build(); CMSEnvelopedData ed = edGen.generate( new CMSProcessableByteArray(data), encryptor); RecipientInformationStore recipients = ed.getRecipientInfos(); assertEquals(checkOID.getId(), ed.getEncryptionAlgOID()); assertEquals(keySize, ((byte[])encryptor.getKey().getRepresentation()).length); if (asn1Params != null) { ASN1InputStream aIn = new ASN1InputStream(ed.getEncryptionAlgParams()); assertTrue(asn1Params.isAssignableFrom(aIn.readObject().getClass())); } Collection c = recipients.getRecipients(); assertEquals(1, c.size()); Iterator it = c.iterator(); if (!it.hasNext()) { fail("no recipients found"); } while (it.hasNext()) { RecipientInformation recipient = (RecipientInformation)it.next(); assertEquals(recipient.getKeyEncryptionAlgOID(), PKCSObjectIdentifiers.rsaEncryption.getId()); byte[] recData = recipient.getContent(new JceKeyTransEnvelopedRecipient(_reciKP.getPrivate()).setProvider(BC)); assertEquals(true, Arrays.equals(data, recData)); } } public void testErroneousKEK() throws Exception { byte[] data = "WallaWallaWashington".getBytes(); SecretKey kek = new SecretKeySpec(new byte[] { 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16 }, "AES"); CMSEnvelopedData ed = new CMSEnvelopedData(oldKEK); RecipientInformationStore recipients = ed.getRecipientInfos(); assertEquals(ed.getEncryptionAlgOID(), CMSEnvelopedDataGenerator.DES_EDE3_CBC); Collection c = recipients.getRecipients(); Iterator it = c.iterator(); if (it.hasNext()) { RecipientInformation recipient = (RecipientInformation)it.next(); assertEquals(recipient.getKeyEncryptionAlgOID(), NISTObjectIdentifiers.id_aes128_wrap.getId()); byte[] recData = recipient.getContent(new JceKEKEnvelopedRecipient(kek).setProvider(BC)); assertEquals(true, Arrays.equals(data, recData)); } else { fail("no recipient found"); } } public void testDESKEK() throws Exception { tryKekAlgorithm(CMSTestUtil.makeDesede192Key(), new DERObjectIdentifier("1.2.840.113549.1.9.16.3.6")); } public void testRC2128KEK() throws Exception { tryKekAlgorithm(CMSTestUtil.makeRC2128Key(), new DERObjectIdentifier("1.2.840.113549.1.9.16.3.7")); } public void testAES128KEK() throws Exception { tryKekAlgorithm(CMSTestUtil.makeAESKey(128), NISTObjectIdentifiers.id_aes128_wrap); } public void testAES192KEK() throws Exception { tryKekAlgorithm(CMSTestUtil.makeAESKey(192), NISTObjectIdentifiers.id_aes192_wrap); } public void testAES256KEK() throws Exception { tryKekAlgorithm(CMSTestUtil.makeAESKey(256), NISTObjectIdentifiers.id_aes256_wrap); } public void testSEED128KEK() throws Exception { tryKekAlgorithm(CMSTestUtil.makeSEEDKey(), KISAObjectIdentifiers.id_npki_app_cmsSeed_wrap); } public void testCamellia128KEK() throws Exception { tryKekAlgorithm(CMSTestUtil.makeCamelliaKey(128), NTTObjectIdentifiers.id_camellia128_wrap); } public void testCamellia192KEK() throws Exception { tryKekAlgorithm(CMSTestUtil.makeCamelliaKey(192), NTTObjectIdentifiers.id_camellia192_wrap); } public void testCamellia256KEK() throws Exception { tryKekAlgorithm(CMSTestUtil.makeCamelliaKey(256), NTTObjectIdentifiers.id_camellia256_wrap); } private void tryKekAlgorithm(SecretKey kek, DERObjectIdentifier algOid) throws NoSuchAlgorithmException, NoSuchProviderException, CMSException { byte[] data = "WallaWallaWashington".getBytes(); CMSEnvelopedDataGenerator edGen = new CMSEnvelopedDataGenerator(); byte[] kekId = new byte[] { 1, 2, 3, 4, 5 }; edGen.addRecipientInfoGenerator(new JceKEKRecipientInfoGenerator(kekId, kek).setProvider(BC)); CMSEnvelopedData ed = edGen.generate( new CMSProcessableByteArray(data), new JceCMSContentEncryptorBuilder(CMSAlgorithm.DES_EDE3_CBC).setProvider(BC).build()); RecipientInformationStore recipients = ed.getRecipientInfos(); Collection c = recipients.getRecipients(); Iterator it = c.iterator(); assertEquals(ed.getEncryptionAlgOID(), CMSEnvelopedDataGenerator.DES_EDE3_CBC); if (it.hasNext()) { RecipientInformation recipient = (RecipientInformation)it.next(); assertEquals(algOid.getId(), recipient.getKeyEncryptionAlgOID()); byte[] recData = recipient.getContent(new JceKEKEnvelopedRecipient(kek).setProvider(BC)); assertTrue(Arrays.equals(data, recData)); } else { fail("no recipient found"); } } public void testECKeyAgree() throws Exception { byte[] data = Hex.decode("504b492d4320434d5320456e76656c6f706564446174612053616d706c65"); CMSEnvelopedDataGenerator edGen = new CMSEnvelopedDataGenerator(); edGen.addRecipientInfoGenerator(new JceKeyAgreeRecipientInfoGenerator(CMSAlgorithm.ECDH_SHA1KDF, _origEcKP.getPrivate(), _origEcKP.getPublic(), CMSAlgorithm.AES128_WRAP).addRecipient(_reciEcCert).setProvider(BC)); CMSEnvelopedData ed = edGen.generate( new CMSProcessableByteArray(data), new JceCMSContentEncryptorBuilder(CMSAlgorithm.AES128_CBC).setProvider(BC).build()); assertEquals(ed.getEncryptionAlgOID(), CMSEnvelopedDataGenerator.AES128_CBC); RecipientInformationStore recipients = ed.getRecipientInfos(); confirmDataReceived(recipients, data, _reciEcCert, _reciEcKP.getPrivate(), BC); confirmNumberRecipients(recipients, 1); } public void testECMQVKeyAgree() throws Exception { byte[] data = Hex.decode("504b492d4320434d5320456e76656c6f706564446174612053616d706c65"); CMSEnvelopedDataGenerator edGen = new CMSEnvelopedDataGenerator(); edGen.addRecipientInfoGenerator(new JceKeyAgreeRecipientInfoGenerator(CMSAlgorithm.ECMQV_SHA1KDF, _origEcKP.getPrivate(), _origEcKP.getPublic(), CMSAlgorithm.AES128_WRAP).addRecipient(_reciEcCert).setProvider(BC)); CMSEnvelopedData ed = edGen.generate( new CMSProcessableByteArray(data), new JceCMSContentEncryptorBuilder(CMSAlgorithm.AES128_CBC).setProvider(BC).build()); assertEquals(ed.getEncryptionAlgOID(), CMSEnvelopedDataGenerator.AES128_CBC); RecipientInformationStore recipients = ed.getRecipientInfos(); confirmDataReceived(recipients, data, _reciEcCert, _reciEcKP.getPrivate(), BC); confirmNumberRecipients(recipients, 1); } public void testECMQVKeyAgreeMultiple() throws Exception { byte[] data = Hex.decode("504b492d4320434d5320456e76656c6f706564446174612053616d706c65"); CMSEnvelopedDataGenerator edGen = new CMSEnvelopedDataGenerator(); JceKeyAgreeRecipientInfoGenerator recipientGenerator = new JceKeyAgreeRecipientInfoGenerator(CMSAlgorithm.ECMQV_SHA1KDF, _origEcKP.getPrivate(), _origEcKP.getPublic(), CMSAlgorithm.AES128_WRAP).setProvider(BC); recipientGenerator.addRecipient(_reciEcCert); recipientGenerator.addRecipient(_reciEcCert2); edGen.addRecipientInfoGenerator(recipientGenerator); CMSEnvelopedData ed = edGen.generate( new CMSProcessableByteArray(data), new JceCMSContentEncryptorBuilder(CMSAlgorithm.AES128_CBC).setProvider(BC).build()); assertEquals(ed.getEncryptionAlgOID(), CMSEnvelopedDataGenerator.AES128_CBC); RecipientInformationStore recipients = ed.getRecipientInfos(); confirmDataReceived(recipients, data, _reciEcCert, _reciEcKP.getPrivate(), BC); confirmDataReceived(recipients, data, _reciEcCert2, _reciEcKP2.getPrivate(), BC); confirmNumberRecipients(recipients, 2); } private static void confirmDataReceived(RecipientInformationStore recipients, byte[] expectedData, X509Certificate reciCert, PrivateKey reciPrivKey, String provider) throws CMSException, NoSuchProviderException, CertificateEncodingException, IOException { RecipientId rid = new JceKeyAgreeRecipientId(reciCert); RecipientInformation recipient = recipients.get(rid); assertNotNull(recipient); byte[] actualData = recipient.getContent(new JceKeyAgreeEnvelopedRecipient(reciPrivKey).setProvider(provider)); assertEquals(true, Arrays.equals(expectedData, actualData)); } private static void confirmNumberRecipients(RecipientInformationStore recipients, int count) { assertEquals(count, recipients.getRecipients().size()); } public void testECKeyAgreeVectors() throws Exception { PKCS8EncodedKeySpec privSpec = new PKCS8EncodedKeySpec(ecKeyAgreeKey); KeyFactory fact = KeyFactory.getInstance("ECDH", BC); PrivateKey privKey = fact.generatePrivate(privSpec); verifyECKeyAgreeVectors(privKey, "2.16.840.1.101.3.4.1.42", ecKeyAgreeMsgAES256); verifyECKeyAgreeVectors(privKey, "2.16.840.1.101.3.4.1.2", ecKeyAgreeMsgAES128); verifyECKeyAgreeVectors(privKey, "1.2.840.113549.3.7", ecKeyAgreeMsgDESEDE); } public void testECMQVKeyAgreeVectors() throws Exception { PKCS8EncodedKeySpec privSpec = new PKCS8EncodedKeySpec(ecKeyAgreeKey); KeyFactory fact = KeyFactory.getInstance("ECDH", BC); PrivateKey privKey = fact.generatePrivate(privSpec); verifyECMQVKeyAgreeVectors(privKey, "2.16.840.1.101.3.4.1.2", ecMQVKeyAgreeMsgAES128); } public void testPasswordAES256() throws Exception { passwordTest(CMSEnvelopedDataGenerator.AES256_CBC); passwordUTF8Test(CMSEnvelopedDataGenerator.AES256_CBC); } public void testPasswordDESEDE() throws Exception { passwordTest(CMSEnvelopedDataGenerator.DES_EDE3_CBC); passwordUTF8Test(CMSEnvelopedDataGenerator.DES_EDE3_CBC); } public void testRFC4134ex5_1() throws Exception { byte[] data = Hex.decode("5468697320697320736f6d652073616d706c6520636f6e74656e742e"); KeyFactory kFact = KeyFactory.getInstance("RSA", BC); Key key = kFact.generatePrivate(new PKCS8EncodedKeySpec(bobPrivRsaEncrypt)); CMSEnvelopedData ed = new CMSEnvelopedData(rfc4134ex5_1); RecipientInformationStore recipients = ed.getRecipientInfos(); assertEquals("1.2.840.113549.3.7", ed.getEncryptionAlgOID()); Collection c = recipients.getRecipients(); Iterator it = c.iterator(); if (it.hasNext()) { RecipientInformation recipient = (RecipientInformation)it.next(); byte[] recData = recipient.getContent(new JceKeyTransEnvelopedRecipient((PrivateKey)key).setProvider(BC)); assertEquals(true, Arrays.equals(data, recData)); } else { fail("no recipient found"); } } public void testRFC4134ex5_2() throws Exception { byte[] data = Hex.decode("5468697320697320736f6d652073616d706c6520636f6e74656e742e"); KeyFactory kFact = KeyFactory.getInstance("RSA", BC); PrivateKey key = kFact.generatePrivate(new PKCS8EncodedKeySpec(bobPrivRsaEncrypt)); CMSEnvelopedData ed = new CMSEnvelopedData(rfc4134ex5_2); RecipientInformationStore recipients = ed.getRecipientInfos(); assertEquals("1.2.840.113549.3.2", ed.getEncryptionAlgOID()); Collection c = recipients.getRecipients(); Iterator it = c.iterator(); if (it.hasNext()) { while (it.hasNext()) { RecipientInformation recipient = (RecipientInformation)it.next(); byte[] recData; if (recipient instanceof KeyTransRecipientInformation) { recData = recipient.getContent(new JceKeyTransEnvelopedRecipient(key).setProvider(BC)); assertEquals(true, Arrays.equals(data, recData)); } } } else { fail("no recipient found"); } } public void testOriginatorInfo() throws Exception { CMSEnvelopedData env = new CMSEnvelopedData(CMSSampleMessages.originatorMessage); RecipientInformationStore recipients = env.getRecipientInfos(); OriginatorInformation origInfo = env.getOriginatorInfo(); assertEquals(new X500Name("C=US,O=U.S. Government,OU=HSPD12Lab,OU=Agents,CN=user1"), ((X509CertificateHolder)origInfo.getCertificates().getMatches(null).iterator().next()).getSubject()); assertEquals(CMSEnvelopedDataGenerator.DES_EDE3_CBC, env.getEncryptionAlgOID()); } private void passwordTest(String algorithm) throws Exception { byte[] data = Hex.decode("504b492d4320434d5320456e76656c6f706564446174612053616d706c65"); CMSEnvelopedDataGenerator edGen = new CMSEnvelopedDataGenerator(); edGen.addRecipientInfoGenerator(new JcePasswordRecipientInfoGenerator(new ASN1ObjectIdentifier(algorithm), "password".toCharArray()).setProvider(BC).setPasswordConversionScheme(PasswordRecipient.PKCS5_SCHEME2).setSaltAndIterationCount(new byte[20], 5)); CMSEnvelopedData ed = edGen.generate( new CMSProcessableByteArray(data), new JceCMSContentEncryptorBuilder(CMSAlgorithm.AES128_CBC).setProvider(BC).build()); RecipientInformationStore recipients = ed.getRecipientInfos(); assertEquals(ed.getEncryptionAlgOID(), CMSEnvelopedDataGenerator.AES128_CBC); Collection c = recipients.getRecipients(); Iterator it = c.iterator(); if (it.hasNext()) { PasswordRecipientInformation recipient = (PasswordRecipientInformation)it.next(); byte[] recData = recipient.getContent(new JcePasswordEnvelopedRecipient("password".toCharArray()).setPasswordConversionScheme(PasswordRecipient.PKCS5_SCHEME2).setProvider(BC)); assertEquals(true, Arrays.equals(data, recData)); } else { fail("no recipient found"); } // // try algorithm parameters constructor // it = c.iterator(); RecipientInformation recipient = (RecipientInformation)it.next(); byte[] recData = recipient.getContent(new JcePasswordEnvelopedRecipient("password".toCharArray()).setPasswordConversionScheme(PasswordRecipient.PKCS5_SCHEME2).setProvider(BC)); assertEquals(true, Arrays.equals(data, recData)); } private void passwordUTF8Test(String algorithm) throws Exception { byte[] data = Hex.decode("504b492d4320434d5320456e76656c6f706564446174612053616d706c65"); CMSEnvelopedDataGenerator edGen = new CMSEnvelopedDataGenerator(); edGen.addRecipientInfoGenerator(new JcePasswordRecipientInfoGenerator(new ASN1ObjectIdentifier(algorithm), "abc\u5639\u563b".toCharArray()).setProvider(BC).setSaltAndIterationCount(new byte[20], 5)); CMSEnvelopedData ed = edGen.generate( new CMSProcessableByteArray(data), new JceCMSContentEncryptorBuilder(CMSAlgorithm.AES128_CBC).setProvider(BC).build()); RecipientInformationStore recipients = ed.getRecipientInfos(); assertEquals(ed.getEncryptionAlgOID(), CMSEnvelopedDataGenerator.AES128_CBC); Collection c = recipients.getRecipients(); Iterator it = c.iterator(); if (it.hasNext()) { RecipientInformation recipient = (RecipientInformation)it.next(); byte[] recData = recipient.getContent(new JcePasswordEnvelopedRecipient("abc\u5639\u563b".toCharArray()).setProvider(BC)); assertEquals(true, Arrays.equals(data, recData)); } else { fail("no recipient found"); } // // try algorithm parameters constructor // it = c.iterator(); RecipientInformation recipient = (RecipientInformation)it.next(); byte[] recData = recipient.getContent(new JcePasswordEnvelopedRecipient("abc\u5639\u563b".toCharArray()).setProvider(BC)); assertEquals(true, Arrays.equals(data, recData)); } private void verifyECKeyAgreeVectors(PrivateKey privKey, String wrapAlg, byte[] message) throws CMSException, GeneralSecurityException { byte[] data = Hex.decode("504b492d4320434d5320456e76656c6f706564446174612053616d706c65"); CMSEnvelopedData ed = new CMSEnvelopedData(message); RecipientInformationStore recipients = ed.getRecipientInfos(); Collection c = recipients.getRecipients(); Iterator it = c.iterator(); assertEquals(wrapAlg, ed.getEncryptionAlgOID()); if (it.hasNext()) { RecipientInformation recipient = (RecipientInformation)it.next(); assertEquals("1.3.133.16.840.63.0.2", recipient.getKeyEncryptionAlgOID()); byte[] recData = recipient.getContent(new JceKeyAgreeEnvelopedRecipient(privKey).setProvider(BC)); assertTrue(Arrays.equals(data, recData)); } else { fail("no recipient found"); } } private void verifyECMQVKeyAgreeVectors(PrivateKey privKey, String wrapAlg, byte[] message) throws CMSException, GeneralSecurityException { byte[] data = Hex.decode("504b492d4320434d5320456e76656c6f706564446174612053616d706c65"); CMSEnvelopedData ed = new CMSEnvelopedData(message); RecipientInformationStore recipients = ed.getRecipientInfos(); Collection c = recipients.getRecipients(); Iterator it = c.iterator(); assertEquals(wrapAlg, ed.getEncryptionAlgOID()); if (it.hasNext()) { RecipientInformation recipient = (RecipientInformation)it.next(); assertEquals("1.3.133.16.840.63.0.16", recipient.getKeyEncryptionAlgOID()); byte[] recData = recipient.getContent(new JceKeyAgreeEnvelopedRecipient(privKey).setProvider(BC)); assertTrue(Arrays.equals(data, recData)); } else { fail("no recipient found"); } } }bouncycastle-1.49.orig/test/src/org/bouncycastle/cms/test/BcEnvelopedDataTest.java0000644000175000017500000011331312110046631027701 0ustar ebourgebourgpackage org.bouncycastle.cms.test; import java.io.IOException; import java.security.GeneralSecurityException; import java.security.Key; import java.security.KeyFactory; import java.security.KeyPair; import java.security.NoSuchAlgorithmException; import java.security.NoSuchProviderException; import java.security.PrivateKey; import java.security.Security; import java.security.cert.CertificateEncodingException; import java.security.cert.X509Certificate; import java.security.spec.PKCS8EncodedKeySpec; import java.util.Arrays; import java.util.Collection; import java.util.Hashtable; import java.util.Iterator; import javax.crypto.SecretKey; import junit.framework.Test; import junit.framework.TestCase; import junit.framework.TestSuite; import org.bouncycastle.asn1.ASN1ObjectIdentifier; import org.bouncycastle.asn1.DEROctetString; import org.bouncycastle.asn1.DERSet; import org.bouncycastle.asn1.DERUTF8String; import org.bouncycastle.asn1.cms.Attribute; import org.bouncycastle.asn1.cms.AttributeTable; import org.bouncycastle.asn1.nist.NISTObjectIdentifiers; import org.bouncycastle.asn1.pkcs.PKCSObjectIdentifiers; import org.bouncycastle.asn1.pkcs.PrivateKeyInfo; import org.bouncycastle.cert.jcajce.JcaX509CertificateHolder; import org.bouncycastle.cms.CMSAlgorithm; import org.bouncycastle.cms.CMSEnvelopedData; import org.bouncycastle.cms.CMSEnvelopedDataGenerator; import org.bouncycastle.cms.CMSException; import org.bouncycastle.cms.CMSProcessableByteArray; import org.bouncycastle.cms.KeyTransRecipientInformation; import org.bouncycastle.cms.PasswordRecipient; import org.bouncycastle.cms.PasswordRecipientInformation; import org.bouncycastle.cms.RecipientId; import org.bouncycastle.cms.RecipientInformation; import org.bouncycastle.cms.RecipientInformationStore; import org.bouncycastle.cms.SimpleAttributeTableGenerator; import org.bouncycastle.cms.bc.BcCMSContentEncryptorBuilder; import org.bouncycastle.cms.bc.BcKEKEnvelopedRecipient; import org.bouncycastle.cms.bc.BcKEKRecipientInfoGenerator; import org.bouncycastle.cms.bc.BcPasswordEnvelopedRecipient; import org.bouncycastle.cms.bc.BcPasswordRecipientInfoGenerator; import org.bouncycastle.cms.bc.BcRSAKeyTransEnvelopedRecipient; import org.bouncycastle.cms.bc.BcRSAKeyTransRecipientInfoGenerator; import org.bouncycastle.cms.jcajce.JceKeyAgreeEnvelopedRecipient; import org.bouncycastle.cms.jcajce.JceKeyAgreeRecipientId; import org.bouncycastle.cms.jcajce.JceKeyAgreeRecipientInfoGenerator; import org.bouncycastle.crypto.params.KeyParameter; import org.bouncycastle.crypto.util.PrivateKeyFactory; import org.bouncycastle.jce.provider.BouncyCastleProvider; import org.bouncycastle.operator.OutputEncryptor; import org.bouncycastle.operator.bc.BcAESSymmetricKeyUnwrapper; import org.bouncycastle.operator.bc.BcAESSymmetricKeyWrapper; import org.bouncycastle.operator.bc.BcSymmetricKeyUnwrapper; import org.bouncycastle.operator.bc.BcSymmetricKeyWrapper; import org.bouncycastle.util.encoders.Base64; import org.bouncycastle.util.encoders.Hex; public class BcEnvelopedDataTest extends TestCase { private static final String BC = BouncyCastleProvider.PROVIDER_NAME; private static String _signDN; private static KeyPair _signKP; private static X509Certificate _signCert; private static String _origDN; private static KeyPair _origKP; private static X509Certificate _origCert; private static String _reciDN; private static String _reciDN2; private static KeyPair _reciKP; private static X509Certificate _reciCert; private static KeyPair _origEcKP; private static KeyPair _reciEcKP; private static X509Certificate _reciEcCert; private static KeyPair _reciEcKP2; private static X509Certificate _reciEcCert2; private static boolean _initialised = false; private byte[] oldKEK = Base64.decode( "MIAGCSqGSIb3DQEHA6CAMIACAQIxQaI/MD0CAQQwBwQFAQIDBAUwDQYJYIZIAWUDBAEFBQAEI" + "Fi2eHTPM4bQSjP4DUeDzJZLpfemW2gF1SPq7ZPHJi1mMIAGCSqGSIb3DQEHATAUBggqhkiG9w" + "0DBwQImtdGyUdGGt6ggAQYk9X9z01YFBkU7IlS3wmsKpm/zpZClTceAAAAAAAAAAAAAA=="); private byte[] ecKeyAgreeMsgAES256 = Base64.decode( "MIAGCSqGSIb3DQEHA6CAMIACAQIxgcShgcECAQOgQ6FBMAsGByqGSM49AgEF" + "AAMyAAPdXlSTpub+qqno9hUGkUDl+S3/ABhPziIB5yGU4678tgOgU5CiKG9Z" + "kfnabIJ3nZYwGgYJK4EFEIZIPwACMA0GCWCGSAFlAwQBLQUAMFswWTAtMCgx" + "EzARBgNVBAMTCkFkbWluLU1EU0UxETAPBgNVBAoTCDRCQ1QtMklEAgEBBCi/" + "rJRLbFwEVW6PcLLmojjW9lI/xGD7CfZzXrqXFw8iHaf3hTRau1gYMIAGCSqG" + "SIb3DQEHATAdBglghkgBZQMEASoEEMtCnKKPwccmyrbgeSIlA3qggAQQDLw8" + "pNJR97bPpj6baG99bQQQwhEDsoj5Xg1oOxojHVcYzAAAAAAAAAAAAAA="); private byte[] ecKeyAgreeMsgAES128 = Base64.decode( "MIAGCSqGSIb3DQEHA6CAMIACAQIxgbShgbECAQOgQ6FBMAsGByqGSM49AgEF" + "AAMyAAL01JLEgKvKh5rbxI/hOxs/9WEezMIsAbUaZM4l5tn3CzXAN505nr5d" + "LhrcurMK+tAwGgYJK4EFEIZIPwACMA0GCWCGSAFlAwQBBQUAMEswSTAtMCgx" + "EzARBgNVBAMTCkFkbWluLU1EU0UxETAPBgNVBAoTCDRCQ1QtMklEAgEBBBhi" + "FLjc5g6aqDT3f8LomljOwl1WTrplUT8wgAYJKoZIhvcNAQcBMB0GCWCGSAFl" + "AwQBAgQQzXjms16Y69S/rB0EbHqRMaCABBAFmc/QdVW6LTKdEy97kaZzBBBa" + "fQuviUS03NycpojELx0bAAAAAAAAAAAAAA=="); private byte[] ecKeyAgreeMsgDESEDE = Base64.decode( "MIAGCSqGSIb3DQEHA6CAMIACAQIxgcahgcMCAQOgQ6FBMAsGByqGSM49AgEF" + "AAMyAALIici6Nx1WN5f0ThH2A8ht9ovm0thpC5JK54t73E1RDzCifePaoQo0" + "xd6sUqoyGaYwHAYJK4EFEIZIPwACMA8GCyqGSIb3DQEJEAMGBQAwWzBZMC0w" + "KDETMBEGA1UEAxMKQWRtaW4tTURTRTERMA8GA1UEChMINEJDVC0ySUQCAQEE" + "KJuqZQ1NB1vXrKPOnb4TCpYOsdm6GscWdwAAZlm2EHMp444j0s55J9wwgAYJ" + "KoZIhvcNAQcBMBQGCCqGSIb3DQMHBAjwnsDMsafCrKCABBjyPvqFOVMKxxut" + "VfTx4fQlNGJN8S2ATRgECMcTQ/dsmeViAAAAAAAAAAAAAA=="); private byte[] ecMQVKeyAgreeMsgAES128 = Base64.decode( "MIAGCSqGSIb3DQEHA6CAMIACAQIxgf2hgfoCAQOgQ6FBMAsGByqGSM49AgEF" + "AAMyAAPDKU+0H58tsjpoYmYCInMr/FayvCCkupebgsnpaGEB7qS9vzcNVUj6" + "mrnmiC2grpmhRwRFMEMwQTALBgcqhkjOPQIBBQADMgACZpD13z9c7DzRWx6S" + "0xdbq3S+EJ7vWO+YcHVjTD8NcQDcZcWASW899l1PkL936zsuMBoGCSuBBRCG" + "SD8AEDANBglghkgBZQMEAQUFADBLMEkwLTAoMRMwEQYDVQQDEwpBZG1pbi1N" + "RFNFMREwDwYDVQQKEwg0QkNULTJJRAIBAQQYFq58L71nyMK/70w3nc6zkkRy" + "RL7DHmpZMIAGCSqGSIb3DQEHATAdBglghkgBZQMEAQIEEDzRUpreBsZXWHBe" + "onxOtSmggAQQ7csAZXwT1lHUqoazoy8bhAQQq+9Zjj8iGdOWgyebbfj67QAA" + "AAAAAAAAAAA="); private byte[] ecKeyAgreeKey = Base64.decode( "MIG2AgEAMBAGByqGSM49AgEGBSuBBAAiBIGeMIGbAgEBBDC8vp7xVTbKSgYVU5Wc" + "hGkWbzaj+yUFETIWP1Dt7+WSpq3ikSPdl7PpHPqnPVZfoIWhZANiAgSYHTgxf+Dd" + "Tt84dUvuSKkFy3RhjxJmjwIscK6zbEUzKhcPQG2GHzXhWK5x1kov0I74XpGhVkya" + "ElH5K6SaOXiXAzcyNGggTOk4+ZFnz5Xl0pBje3zKxPhYu0SnCw7Pcqw="); private byte[] bobPrivRsaEncrypt = Base64.decode( "MIIChQIBADANBgkqhkiG9w0BAQEFAASCAmAwggJcAgEAAoGBAKnhZ5g/OdVf" + "8qCTQV6meYmFyDVdmpFb+x0B2hlwJhcPvaUi0DWFbXqYZhRBXM+3twg7CcmR" + "uBlpN235ZR572akzJKN/O7uvRgGGNjQyywcDWVL8hYsxBLjMGAgUSOZPHPtd" + "YMTgXB9T039T2GkB8QX4enDRvoPGXzjPHCyqaqfrAgMBAAECgYBnzUhMmg2P" + "mMIbZf8ig5xt8KYGHbztpwOIlPIcaw+LNd4Ogngwy+e6alatd8brUXlweQqg" + "9P5F4Kmy9Bnah5jWMIR05PxZbMHGd9ypkdB8MKCixQheIXFD/A0HPfD6bRSe" + "TmPwF1h5HEuYHD09sBvf+iU7o8AsmAX2EAnYh9sDGQJBANDDIsbeopkYdo+N" + "vKZ11mY/1I1FUox29XLE6/BGmvE+XKpVC5va3Wtt+Pw7PAhDk7Vb/s7q/WiE" + "I2Kv8zHCueUCQQDQUfweIrdb7bWOAcjXq/JY1PeClPNTqBlFy2bKKBlf4hAr" + "84/sajB0+E0R9KfEILVHIdxJAfkKICnwJAiEYH2PAkA0umTJSChXdNdVUN5q" + "SO8bKlocSHseIVnDYDubl6nA7xhmqU5iUjiEzuUJiEiUacUgFJlaV/4jbOSn" + "I3vQgLeFAkEAni+zN5r7CwZdV+EJBqRd2ZCWBgVfJAZAcpw6iIWchw+dYhKI" + "FmioNRobQ+g4wJhprwMKSDIETukPj3d9NDAlBwJAVxhn1grStavCunrnVNqc" + "BU+B1O8BiR4yPWnLMcRSyFRVJQA7HCp8JlDV6abXd8vPFfXuC9WN7rOvTKF8" + "Y0ZB9qANMAsGA1UdDzEEAwIAEA=="); private byte[] rfc4134ex5_1 = Base64.decode( "MIIBHgYJKoZIhvcNAQcDoIIBDzCCAQsCAQAxgcAwgb0CAQAwJjASMRAwDgYD" + "VQQDEwdDYXJsUlNBAhBGNGvHgABWvBHTbi7NXXHQMA0GCSqGSIb3DQEBAQUA" + "BIGAC3EN5nGIiJi2lsGPcP2iJ97a4e8kbKQz36zg6Z2i0yx6zYC4mZ7mX7FB" + "s3IWg+f6KgCLx3M1eCbWx8+MDFbbpXadCDgO8/nUkUNYeNxJtuzubGgzoyEd" + "8Ch4H/dd9gdzTd+taTEgS0ipdSJuNnkVY4/M652jKKHRLFf02hosdR8wQwYJ" + "KoZIhvcNAQcBMBQGCCqGSIb3DQMHBAgtaMXpRwZRNYAgDsiSf8Z9P43LrY4O" + "xUk660cu1lXeCSFOSOpOJ7FuVyU="); private byte[] rfc4134ex5_2 = Base64.decode( "MIIBZQYJKoZIhvcNAQcDoIIBVjCCAVICAQIxggEAMIG9AgEAMCYwEjEQMA4G" + "A1UEAxMHQ2FybFJTQQIQRjRrx4AAVrwR024uzV1x0DANBgkqhkiG9w0BAQEF" + "AASBgJQmQojGi7Z4IP+CVypBmNFoCDoEp87khtgyff2N4SmqD3RxPx+8hbLQ" + "t9i3YcMwcap+aiOkyqjMalT03VUC0XBOGv+HYI3HBZm/aFzxoq+YOXAWs5xl" + "GerZwTOc9j6AYlK4qXvnztR5SQ8TBjlzytm4V7zg+TGrnGVNQBNw47Ewoj4C" + "AQQwDQQLTWFpbExpc3RSQzIwEAYLKoZIhvcNAQkQAwcCAToEGHcUr5MSJ/g9" + "HnJVHsQ6X56VcwYb+OfojTBJBgkqhkiG9w0BBwEwGgYIKoZIhvcNAwIwDgIC" + "AKAECJwE0hkuKlWhgCBeKNXhojuej3org9Lt7n+wWxOhnky5V50vSpoYRfRR" + "yw=="); public BcEnvelopedDataTest() { } private static void init() throws Exception { if (!_initialised) { _initialised = true; if (Security.getProvider(BC) == null) { Security.addProvider(new BouncyCastleProvider()); } _signDN = "O=Bouncy Castle, C=AU"; _signKP = CMSTestUtil.makeKeyPair(); _signCert = CMSTestUtil.makeCertificate(_signKP, _signDN, _signKP, _signDN); _origDN = "CN=Bob, OU=Sales, O=Bouncy Castle, C=AU"; _origKP = CMSTestUtil.makeKeyPair(); _origCert = CMSTestUtil.makeCertificate(_origKP, _origDN, _signKP, _signDN); _reciDN = "CN=Doug, OU=Sales, O=Bouncy Castle, C=AU"; _reciDN2 = "CN=Fred, OU=Sales, O=Bouncy Castle, C=AU"; _reciKP = CMSTestUtil.makeKeyPair(); _reciCert = CMSTestUtil.makeCertificate(_reciKP, _reciDN, _signKP, _signDN); _origEcKP = CMSTestUtil.makeEcDsaKeyPair(); _reciEcKP = CMSTestUtil.makeEcDsaKeyPair(); _reciEcCert = CMSTestUtil.makeCertificate(_reciEcKP, _reciDN, _signKP, _signDN); _reciEcKP2 = CMSTestUtil.makeEcDsaKeyPair(); _reciEcCert2 = CMSTestUtil.makeCertificate(_reciEcKP2, _reciDN2, _signKP, _signDN); } } public static void main( String args[]) throws Exception { junit.textui.TestRunner.run(BcEnvelopedDataTest.suite()); } public static Test suite() throws Exception { init(); return new CMSTestSetup(new TestSuite(BcEnvelopedDataTest.class)); } public void testUnprotectedAttributes() throws Exception { byte[] data = "WallaWallaWashington".getBytes(); CMSEnvelopedDataGenerator edGen = new CMSEnvelopedDataGenerator(); edGen.addRecipientInfoGenerator(new BcRSAKeyTransRecipientInfoGenerator(new JcaX509CertificateHolder(_reciCert))); Hashtable attrs = new Hashtable(); attrs.put(PKCSObjectIdentifiers.id_aa_contentHint, new Attribute(PKCSObjectIdentifiers.id_aa_contentHint, new DERSet(new DERUTF8String("Hint")))); attrs.put(PKCSObjectIdentifiers.id_aa_receiptRequest, new Attribute(PKCSObjectIdentifiers.id_aa_receiptRequest, new DERSet(new DERUTF8String("Request")))); AttributeTable attrTable = new AttributeTable(attrs); edGen.setUnprotectedAttributeGenerator(new SimpleAttributeTableGenerator(attrTable)); CMSEnvelopedData ed = edGen.generate( new CMSProcessableByteArray(data), new BcCMSContentEncryptorBuilder(CMSAlgorithm.DES_EDE3_CBC).build()); RecipientInformationStore recipients = ed.getRecipientInfos(); assertEquals(ed.getEncryptionAlgOID(), CMSAlgorithm.DES_EDE3_CBC.getId()); attrTable = ed.getUnprotectedAttributes(); assertEquals(attrs.size(), 2); assertEquals(new DERUTF8String("Hint"), attrTable.get(PKCSObjectIdentifiers.id_aa_contentHint).getAttrValues().getObjectAt(0)); assertEquals(new DERUTF8String("Request"), attrTable.get(PKCSObjectIdentifiers.id_aa_receiptRequest).getAttrValues().getObjectAt(0)); Collection c = recipients.getRecipients(); assertEquals(1, c.size()); Iterator it = c.iterator(); while (it.hasNext()) { RecipientInformation recipient = (RecipientInformation)it.next(); assertEquals(recipient.getKeyEncryptionAlgOID(), PKCSObjectIdentifiers.rsaEncryption.getId()); byte[] recData = recipient.getContent(new BcRSAKeyTransEnvelopedRecipient(PrivateKeyFactory.createKey(_reciKP.getPrivate().getEncoded()))); assertEquals(true, Arrays.equals(data, recData)); } } public void testKeyTrans() throws Exception { byte[] data = "WallaWallaWashington".getBytes(); CMSEnvelopedDataGenerator edGen = new CMSEnvelopedDataGenerator(); edGen.addRecipientInfoGenerator(new BcRSAKeyTransRecipientInfoGenerator(new JcaX509CertificateHolder(_reciCert))); CMSEnvelopedData ed = edGen.generate( new CMSProcessableByteArray(data), new BcCMSContentEncryptorBuilder(CMSAlgorithm.DES_EDE3_CBC).build()); RecipientInformationStore recipients = ed.getRecipientInfos(); assertEquals(ed.getEncryptionAlgOID(), CMSAlgorithm.DES_EDE3_CBC.getId()); Collection c = recipients.getRecipients(); assertEquals(1, c.size()); Iterator it = c.iterator(); while (it.hasNext()) { RecipientInformation recipient = (RecipientInformation)it.next(); assertEquals(recipient.getKeyEncryptionAlgOID(), PKCSObjectIdentifiers.rsaEncryption.getId()); byte[] recData = recipient.getContent(new BcRSAKeyTransEnvelopedRecipient(PrivateKeyFactory.createKey(PrivateKeyInfo.getInstance(_reciKP.getPrivate().getEncoded())))); assertEquals(true, Arrays.equals(data, recData)); } } public void testKeyTransRC4() throws Exception { byte[] data = "WallaWallaBouncyCastle".getBytes(); CMSEnvelopedDataGenerator edGen = new CMSEnvelopedDataGenerator(); edGen.addRecipientInfoGenerator(new BcRSAKeyTransRecipientInfoGenerator(new JcaX509CertificateHolder(_reciCert))); CMSEnvelopedData ed = edGen.generate( new CMSProcessableByteArray(data), new BcCMSContentEncryptorBuilder(new ASN1ObjectIdentifier("1.2.840.113549.3.4")).build()); RecipientInformationStore recipients = ed.getRecipientInfos(); assertEquals(ed.getEncryptionAlgOID(), new ASN1ObjectIdentifier("1.2.840.113549.3.4").getId()); Collection c = recipients.getRecipients(); assertEquals(1, c.size()); Iterator it = c.iterator(); while (it.hasNext()) { RecipientInformation recipient = (RecipientInformation)it.next(); byte[] recData = recipient.getContent(new BcRSAKeyTransEnvelopedRecipient(PrivateKeyFactory.createKey(PrivateKeyInfo.getInstance(_reciKP.getPrivate().getEncoded())))); assertEquals(true, Arrays.equals(data, recData)); } } public void testKeyTrans128RC4() throws Exception { byte[] data = "WallaWallaBouncyCastle".getBytes(); CMSEnvelopedDataGenerator edGen = new CMSEnvelopedDataGenerator(); edGen.addRecipientInfoGenerator(new BcRSAKeyTransRecipientInfoGenerator(new JcaX509CertificateHolder(_reciCert))); CMSEnvelopedData ed = edGen.generate( new CMSProcessableByteArray(data), new BcCMSContentEncryptorBuilder(new ASN1ObjectIdentifier("1.2.840.113549.3.4"), 128).build()); RecipientInformationStore recipients = ed.getRecipientInfos(); assertEquals(ed.getEncryptionAlgOID(), "1.2.840.113549.3.4"); Collection c = recipients.getRecipients(); Iterator it = c.iterator(); if (it.hasNext()) { RecipientInformation recipient = (RecipientInformation)it.next(); byte[] recData = recipient.getContent(new BcRSAKeyTransEnvelopedRecipient(PrivateKeyFactory.createKey(PrivateKeyInfo.getInstance(_reciKP.getPrivate().getEncoded())))); assertEquals(true, Arrays.equals(data, recData)); } else { fail("no recipient found"); } } public void testKeyTransLight128RC4() throws Exception { byte[] data = "WallaWallaBouncyCastle".getBytes(); CMSEnvelopedDataGenerator edGen = new CMSEnvelopedDataGenerator(); edGen.addRecipientInfoGenerator(new BcRSAKeyTransRecipientInfoGenerator(new JcaX509CertificateHolder(_reciCert))); CMSEnvelopedData ed = edGen.generate( new CMSProcessableByteArray(data), new BcCMSContentEncryptorBuilder(new ASN1ObjectIdentifier("1.2.840.113549.3.4"), 128).build()); RecipientInformationStore recipients = ed.getRecipientInfos(); assertEquals(ed.getEncryptionAlgOID(), "1.2.840.113549.3.4"); Collection c = recipients.getRecipients(); Iterator it = c.iterator(); if (it.hasNext()) { RecipientInformation recipient = (RecipientInformation)it.next(); byte[] recData = recipient.getContent(new BcRSAKeyTransEnvelopedRecipient(PrivateKeyFactory.createKey(PrivateKeyInfo.getInstance(_reciKP.getPrivate().getEncoded())))); assertEquals(true, Arrays.equals(data, recData)); } else { fail("no recipient found"); } } public void testKeyTransODES() throws Exception { byte[] data = "WallaWallaBouncyCastle".getBytes(); CMSEnvelopedDataGenerator edGen = new CMSEnvelopedDataGenerator(); edGen.addRecipientInfoGenerator(new BcRSAKeyTransRecipientInfoGenerator(new JcaX509CertificateHolder(_reciCert))); CMSEnvelopedData ed = edGen.generate( new CMSProcessableByteArray(data), new BcCMSContentEncryptorBuilder(new ASN1ObjectIdentifier("1.3.14.3.2.7")).build()); RecipientInformationStore recipients = ed.getRecipientInfos(); assertEquals(ed.getEncryptionAlgOID(), "1.3.14.3.2.7"); Collection c = recipients.getRecipients(); Iterator it = c.iterator(); if (it.hasNext()) { RecipientInformation recipient = (RecipientInformation)it.next(); byte[] recData = recipient.getContent(new BcRSAKeyTransEnvelopedRecipient(PrivateKeyFactory.createKey(PrivateKeyInfo.getInstance(_reciKP.getPrivate().getEncoded())))); assertEquals(true, Arrays.equals(data, recData)); } else { fail("no recipient found"); } } public void testKeyTransSmallAES() throws Exception { byte[] data = new byte[] { 0, 1, 2, 3 }; CMSEnvelopedDataGenerator edGen = new CMSEnvelopedDataGenerator(); edGen.addRecipientInfoGenerator(new BcRSAKeyTransRecipientInfoGenerator(new JcaX509CertificateHolder(_reciCert))); CMSEnvelopedData ed = edGen.generate( new CMSProcessableByteArray(data), new BcCMSContentEncryptorBuilder(CMSAlgorithm.AES128_CBC).build()); RecipientInformationStore recipients = ed.getRecipientInfos(); assertEquals(ed.getEncryptionAlgOID(), CMSAlgorithm.AES128_CBC.getId()); Collection c = recipients.getRecipients(); Iterator it = c.iterator(); if (it.hasNext()) { RecipientInformation recipient = (RecipientInformation)it.next(); byte[] recData = recipient.getContent(new BcRSAKeyTransEnvelopedRecipient(PrivateKeyFactory.createKey(PrivateKeyInfo.getInstance(_reciKP.getPrivate().getEncoded())))); assertEquals(true, Arrays.equals(data, recData)); } else { fail("no recipient found"); } } public void testKeyTransAES128() throws Exception { tryKeyTrans(CMSAlgorithm.AES128_CBC, NISTObjectIdentifiers.id_aes128_CBC, 16, DEROctetString.class); } public void testKeyTransAES192() throws Exception { tryKeyTrans(CMSAlgorithm.AES192_CBC, NISTObjectIdentifiers.id_aes192_CBC, 24, DEROctetString.class); } public void testKeyTransAES256() throws Exception { tryKeyTrans(CMSAlgorithm.AES256_CBC, NISTObjectIdentifiers.id_aes256_CBC, 32, DEROctetString.class); } private void tryKeyTrans(ASN1ObjectIdentifier generatorOID, ASN1ObjectIdentifier checkOID, int keySize, Class asn1Params) throws Exception { byte[] data = "WallaWallaWashington".getBytes(); CMSEnvelopedDataGenerator edGen = new CMSEnvelopedDataGenerator(); edGen.addRecipientInfoGenerator(new BcRSAKeyTransRecipientInfoGenerator(new JcaX509CertificateHolder(_reciCert))); OutputEncryptor encryptor = new BcCMSContentEncryptorBuilder(generatorOID).build(); CMSEnvelopedData ed = edGen.generate( new CMSProcessableByteArray(data), encryptor); RecipientInformationStore recipients = ed.getRecipientInfos(); assertEquals(checkOID.getId(), ed.getEncryptionAlgOID()); assertEquals(keySize, ((byte[])encryptor.getKey().getRepresentation()).length); if (asn1Params != null) { assertTrue(asn1Params.isAssignableFrom(ed.getContentEncryptionAlgorithm().getParameters().toASN1Primitive().getClass())); } Collection c = recipients.getRecipients(); assertEquals(1, c.size()); Iterator it = c.iterator(); if (!it.hasNext()) { fail("no recipients found"); } while (it.hasNext()) { RecipientInformation recipient = (RecipientInformation)it.next(); assertEquals(recipient.getKeyEncryptionAlgOID(), PKCSObjectIdentifiers.rsaEncryption.getId()); byte[] recData = recipient.getContent(new BcRSAKeyTransEnvelopedRecipient(PrivateKeyFactory.createKey(PrivateKeyInfo.getInstance(_reciKP.getPrivate().getEncoded())))); assertEquals(true, Arrays.equals(data, recData)); } } public void testAES128KEK() throws Exception { SecretKey key = CMSTestUtil.makeAESKey(128); tryKekAlgorithm(new BcAESSymmetricKeyWrapper(new KeyParameter(key.getEncoded())), new BcAESSymmetricKeyUnwrapper(new KeyParameter(key.getEncoded())), NISTObjectIdentifiers.id_aes128_wrap); } public void testAES192KEK() throws Exception { SecretKey key = CMSTestUtil.makeAESKey(192); tryKekAlgorithm(new BcAESSymmetricKeyWrapper(new KeyParameter(key.getEncoded())), new BcAESSymmetricKeyUnwrapper(new KeyParameter(key.getEncoded())), NISTObjectIdentifiers.id_aes192_wrap); } public void testAES256KEK() throws Exception { SecretKey key = CMSTestUtil.makeAESKey(256); tryKekAlgorithm(new BcAESSymmetricKeyWrapper(new KeyParameter(key.getEncoded())), new BcAESSymmetricKeyUnwrapper(new KeyParameter(key.getEncoded())), NISTObjectIdentifiers.id_aes256_wrap); } private void tryKekAlgorithm(BcSymmetricKeyWrapper kekWrapper, BcSymmetricKeyUnwrapper kekUnwrapper, ASN1ObjectIdentifier algOid) throws NoSuchAlgorithmException, NoSuchProviderException, CMSException { byte[] data = "WallaWallaWashington".getBytes(); CMSEnvelopedDataGenerator edGen = new CMSEnvelopedDataGenerator(); byte[] kekId = new byte[] { 1, 2, 3, 4, 5 }; edGen.addRecipientInfoGenerator(new BcKEKRecipientInfoGenerator(kekId, kekWrapper)); CMSEnvelopedData ed = edGen.generate( new CMSProcessableByteArray(data), new BcCMSContentEncryptorBuilder(CMSAlgorithm.DES_EDE3_CBC).build()); RecipientInformationStore recipients = ed.getRecipientInfos(); Collection c = recipients.getRecipients(); Iterator it = c.iterator(); assertEquals(ed.getEncryptionAlgOID(), CMSAlgorithm.DES_EDE3_CBC.getId()); if (it.hasNext()) { RecipientInformation recipient = (RecipientInformation)it.next(); assertEquals(algOid.getId(), recipient.getKeyEncryptionAlgOID()); byte[] recData = recipient.getContent(new BcKEKEnvelopedRecipient(kekUnwrapper)); assertTrue(Arrays.equals(data, recData)); } else { fail("no recipient found"); } } public void testECKeyAgree() throws Exception { byte[] data = Hex.decode("504b492d4320434d5320456e76656c6f706564446174612053616d706c65"); CMSEnvelopedDataGenerator edGen = new CMSEnvelopedDataGenerator(); edGen.addRecipientInfoGenerator(new JceKeyAgreeRecipientInfoGenerator(CMSAlgorithm.ECDH_SHA1KDF, _origEcKP.getPrivate(), _origEcKP.getPublic(), CMSAlgorithm.AES128_WRAP).addRecipient(_reciEcCert).setProvider(BC)); CMSEnvelopedData ed = edGen.generate( new CMSProcessableByteArray(data), new BcCMSContentEncryptorBuilder(CMSAlgorithm.AES128_CBC).build()); assertEquals(ed.getEncryptionAlgOID(), CMSAlgorithm.AES128_CBC.getId()); RecipientInformationStore recipients = ed.getRecipientInfos(); confirmDataReceived(recipients, data, _reciEcCert, _reciEcKP.getPrivate(), BC); confirmNumberRecipients(recipients, 1); } public void testECMQVKeyAgree() throws Exception { byte[] data = Hex.decode("504b492d4320434d5320456e76656c6f706564446174612053616d706c65"); CMSEnvelopedDataGenerator edGen = new CMSEnvelopedDataGenerator(); edGen.addRecipientInfoGenerator(new JceKeyAgreeRecipientInfoGenerator(CMSAlgorithm.ECMQV_SHA1KDF, _origEcKP.getPrivate(), _origEcKP.getPublic(), CMSAlgorithm.AES128_WRAP).addRecipient(_reciEcCert).setProvider(BC)); CMSEnvelopedData ed = edGen.generate( new CMSProcessableByteArray(data), new BcCMSContentEncryptorBuilder(CMSAlgorithm.AES128_CBC).build()); assertEquals(ed.getEncryptionAlgOID(), CMSAlgorithm.AES128_CBC.getId()); RecipientInformationStore recipients = ed.getRecipientInfos(); confirmDataReceived(recipients, data, _reciEcCert, _reciEcKP.getPrivate(), BC); confirmNumberRecipients(recipients, 1); } public void testECMQVKeyAgreeMultiple() throws Exception { byte[] data = Hex.decode("504b492d4320434d5320456e76656c6f706564446174612053616d706c65"); CMSEnvelopedDataGenerator edGen = new CMSEnvelopedDataGenerator(); JceKeyAgreeRecipientInfoGenerator recipientGenerator = new JceKeyAgreeRecipientInfoGenerator(CMSAlgorithm.ECMQV_SHA1KDF, _origEcKP.getPrivate(), _origEcKP.getPublic(), CMSAlgorithm.AES128_WRAP).setProvider(BC); recipientGenerator.addRecipient(_reciEcCert); recipientGenerator.addRecipient(_reciEcCert2); edGen.addRecipientInfoGenerator(recipientGenerator); CMSEnvelopedData ed = edGen.generate( new CMSProcessableByteArray(data), new BcCMSContentEncryptorBuilder(CMSAlgorithm.AES128_CBC).build()); assertEquals(ed.getEncryptionAlgOID(), CMSAlgorithm.AES128_CBC.getId()); RecipientInformationStore recipients = ed.getRecipientInfos(); confirmDataReceived(recipients, data, _reciEcCert, _reciEcKP.getPrivate(), BC); confirmDataReceived(recipients, data, _reciEcCert2, _reciEcKP2.getPrivate(), BC); confirmNumberRecipients(recipients, 2); } private static void confirmDataReceived(RecipientInformationStore recipients, byte[] expectedData, X509Certificate reciCert, PrivateKey reciPrivKey, String provider) throws CMSException, NoSuchProviderException, CertificateEncodingException, IOException { RecipientId rid = new JceKeyAgreeRecipientId(reciCert); RecipientInformation recipient = recipients.get(rid); assertNotNull(recipient); byte[] actualData = recipient.getContent(new JceKeyAgreeEnvelopedRecipient(reciPrivKey).setProvider(provider)); assertEquals(true, Arrays.equals(expectedData, actualData)); } private static void confirmNumberRecipients(RecipientInformationStore recipients, int count) { assertEquals(count, recipients.getRecipients().size()); } public void testECKeyAgreeVectors() throws Exception { PKCS8EncodedKeySpec privSpec = new PKCS8EncodedKeySpec(ecKeyAgreeKey); KeyFactory fact = KeyFactory.getInstance("ECDH", BC); PrivateKey privKey = fact.generatePrivate(privSpec); verifyECKeyAgreeVectors(privKey, "2.16.840.1.101.3.4.1.42", ecKeyAgreeMsgAES256); verifyECKeyAgreeVectors(privKey, "2.16.840.1.101.3.4.1.2", ecKeyAgreeMsgAES128); verifyECKeyAgreeVectors(privKey, "1.2.840.113549.3.7", ecKeyAgreeMsgDESEDE); } public void testECMQVKeyAgreeVectors() throws Exception { PKCS8EncodedKeySpec privSpec = new PKCS8EncodedKeySpec(ecKeyAgreeKey); KeyFactory fact = KeyFactory.getInstance("ECDH", BC); PrivateKey privKey = fact.generatePrivate(privSpec); verifyECMQVKeyAgreeVectors(privKey, "2.16.840.1.101.3.4.1.2", ecMQVKeyAgreeMsgAES128); } public void testPasswordAES256() throws Exception { passwordTest(CMSAlgorithm.AES256_CBC); passwordUTF8Test(CMSAlgorithm.AES256_CBC); } public void testPasswordDESEDE() throws Exception { passwordTest(CMSAlgorithm.DES_EDE3_CBC); passwordUTF8Test(CMSAlgorithm.DES_EDE3_CBC); } public void testRFC4134ex5_1() throws Exception { byte[] data = Hex.decode("5468697320697320736f6d652073616d706c6520636f6e74656e742e"); KeyFactory kFact = KeyFactory.getInstance("RSA", BC); Key key = kFact.generatePrivate(new PKCS8EncodedKeySpec(bobPrivRsaEncrypt)); CMSEnvelopedData ed = new CMSEnvelopedData(rfc4134ex5_1); RecipientInformationStore recipients = ed.getRecipientInfos(); assertEquals("1.2.840.113549.3.7", ed.getEncryptionAlgOID()); Collection c = recipients.getRecipients(); Iterator it = c.iterator(); if (it.hasNext()) { RecipientInformation recipient = (RecipientInformation)it.next(); byte[] recData = recipient.getContent(new BcRSAKeyTransEnvelopedRecipient(PrivateKeyFactory.createKey(PrivateKeyInfo.getInstance(key.getEncoded())))); assertEquals(true, Arrays.equals(data, recData)); } else { fail("no recipient found"); } } public void testRFC4134ex5_2() throws Exception { byte[] data = Hex.decode("5468697320697320736f6d652073616d706c6520636f6e74656e742e"); KeyFactory kFact = KeyFactory.getInstance("RSA", BC); PrivateKey key = kFact.generatePrivate(new PKCS8EncodedKeySpec(bobPrivRsaEncrypt)); CMSEnvelopedData ed = new CMSEnvelopedData(rfc4134ex5_2); RecipientInformationStore recipients = ed.getRecipientInfos(); assertEquals("1.2.840.113549.3.2", ed.getEncryptionAlgOID()); Collection c = recipients.getRecipients(); Iterator it = c.iterator(); if (it.hasNext()) { while (it.hasNext()) { RecipientInformation recipient = (RecipientInformation)it.next(); byte[] recData; if (recipient instanceof KeyTransRecipientInformation) { recData = recipient.getContent(new BcRSAKeyTransEnvelopedRecipient(PrivateKeyFactory.createKey(PrivateKeyInfo.getInstance(key.getEncoded())))); assertEquals(true, Arrays.equals(data, recData)); } } } else { fail("no recipient found"); } } public void testOriginatorInfo() throws Exception { CMSEnvelopedData env = new CMSEnvelopedData(CMSSampleMessages.originatorMessage); RecipientInformationStore recipients = env.getRecipientInfos(); assertEquals(CMSAlgorithm.DES_EDE3_CBC.getId(), env.getEncryptionAlgOID()); } private void passwordTest(ASN1ObjectIdentifier algorithm) throws Exception { byte[] data = Hex.decode("504b492d4320434d5320456e76656c6f706564446174612053616d706c65"); CMSEnvelopedDataGenerator edGen = new CMSEnvelopedDataGenerator(); edGen.addRecipientInfoGenerator(new BcPasswordRecipientInfoGenerator(algorithm, "password".toCharArray()).setPasswordConversionScheme(PasswordRecipient.PKCS5_SCHEME2).setSaltAndIterationCount(new byte[20], 5)); CMSEnvelopedData ed = edGen.generate( new CMSProcessableByteArray(data), new BcCMSContentEncryptorBuilder(CMSAlgorithm.AES128_CBC).build()); RecipientInformationStore recipients = ed.getRecipientInfos(); assertEquals(ed.getEncryptionAlgOID(), CMSAlgorithm.AES128_CBC.getId()); Collection c = recipients.getRecipients(); Iterator it = c.iterator(); if (it.hasNext()) { PasswordRecipientInformation recipient = (PasswordRecipientInformation)it.next(); byte[] recData = recipient.getContent(new BcPasswordEnvelopedRecipient("password".toCharArray()).setPasswordConversionScheme(PasswordRecipient.PKCS5_SCHEME2)); assertEquals(true, Arrays.equals(data, recData)); } else { fail("no recipient found"); } // // try algorithm parameters constructor // it = c.iterator(); RecipientInformation recipient = (RecipientInformation)it.next(); byte[] recData = recipient.getContent(new BcPasswordEnvelopedRecipient("password".toCharArray()).setPasswordConversionScheme(PasswordRecipient.PKCS5_SCHEME2)); assertEquals(true, Arrays.equals(data, recData)); } private void passwordUTF8Test(ASN1ObjectIdentifier algorithm) throws Exception { byte[] data = Hex.decode("504b492d4320434d5320456e76656c6f706564446174612053616d706c65"); CMSEnvelopedDataGenerator edGen = new CMSEnvelopedDataGenerator(); edGen.addRecipientInfoGenerator(new BcPasswordRecipientInfoGenerator(algorithm, "abc\u5639\u563b".toCharArray()).setSaltAndIterationCount(new byte[20], 5)); CMSEnvelopedData ed = edGen.generate( new CMSProcessableByteArray(data), new BcCMSContentEncryptorBuilder(CMSAlgorithm.AES128_CBC).build()); RecipientInformationStore recipients = ed.getRecipientInfos(); assertEquals(ed.getEncryptionAlgOID(), CMSAlgorithm.AES128_CBC.getId()); Collection c = recipients.getRecipients(); Iterator it = c.iterator(); if (it.hasNext()) { RecipientInformation recipient = (RecipientInformation)it.next(); byte[] recData = recipient.getContent(new BcPasswordEnvelopedRecipient("abc\u5639\u563b".toCharArray())); assertEquals(true, Arrays.equals(data, recData)); } else { fail("no recipient found"); } // // try algorithm parameters constructor // it = c.iterator(); RecipientInformation recipient = (RecipientInformation)it.next(); byte[] recData = recipient.getContent(new BcPasswordEnvelopedRecipient("abc\u5639\u563b".toCharArray())); assertEquals(true, Arrays.equals(data, recData)); } private void verifyECKeyAgreeVectors(PrivateKey privKey, String wrapAlg, byte[] message) throws CMSException, GeneralSecurityException { byte[] data = Hex.decode("504b492d4320434d5320456e76656c6f706564446174612053616d706c65"); CMSEnvelopedData ed = new CMSEnvelopedData(message); RecipientInformationStore recipients = ed.getRecipientInfos(); Collection c = recipients.getRecipients(); Iterator it = c.iterator(); assertEquals(wrapAlg, ed.getEncryptionAlgOID()); if (it.hasNext()) { RecipientInformation recipient = (RecipientInformation)it.next(); assertEquals("1.3.133.16.840.63.0.2", recipient.getKeyEncryptionAlgOID()); byte[] recData = recipient.getContent(new JceKeyAgreeEnvelopedRecipient(privKey).setProvider(BC)); assertTrue(Arrays.equals(data, recData)); } else { fail("no recipient found"); } } private void verifyECMQVKeyAgreeVectors(PrivateKey privKey, String wrapAlg, byte[] message) throws CMSException, GeneralSecurityException { byte[] data = Hex.decode("504b492d4320434d5320456e76656c6f706564446174612053616d706c65"); CMSEnvelopedData ed = new CMSEnvelopedData(message); RecipientInformationStore recipients = ed.getRecipientInfos(); Collection c = recipients.getRecipients(); Iterator it = c.iterator(); assertEquals(wrapAlg, ed.getEncryptionAlgOID()); if (it.hasNext()) { RecipientInformation recipient = (RecipientInformation)it.next(); assertEquals("1.3.133.16.840.63.0.16", recipient.getKeyEncryptionAlgOID()); byte[] recData = recipient.getContent(new JceKeyAgreeEnvelopedRecipient(privKey).setProvider(BC)); assertTrue(Arrays.equals(data, recData)); } else { fail("no recipient found"); } } } bouncycastle-1.49.orig/test/src/org/bouncycastle/cms/test/CMSTestUtil.java0000644000175000017500000004072312116546761026224 0ustar ebourgebourgpackage org.bouncycastle.cms.test; import java.io.ByteArrayOutputStream; import java.io.IOException; import java.io.InputStream; import java.math.BigInteger; import java.security.GeneralSecurityException; import java.security.KeyPair; import java.security.KeyPairGenerator; import java.security.PrivateKey; import java.security.PublicKey; import java.security.SecureRandom; import java.security.cert.X509CRL; import java.security.cert.X509Certificate; import java.security.interfaces.RSAPublicKey; import java.security.spec.DSAParameterSpec; import java.util.Date; import javax.crypto.KeyGenerator; import javax.crypto.SecretKey; import org.bouncycastle.asn1.cryptopro.CryptoProObjectIdentifiers; import org.bouncycastle.asn1.x500.X500Name; import org.bouncycastle.asn1.x509.AuthorityKeyIdentifier; import org.bouncycastle.asn1.x509.BasicConstraints; import org.bouncycastle.asn1.x509.CRLReason; import org.bouncycastle.asn1.x509.SubjectKeyIdentifier; import org.bouncycastle.asn1.x509.SubjectPublicKeyInfo; import org.bouncycastle.asn1.x509.X509Extension; import org.bouncycastle.asn1.x509.X509Name; import org.bouncycastle.cert.X509ExtensionUtils; import org.bouncycastle.cert.X509v2CRLBuilder; import org.bouncycastle.cert.jcajce.JcaX509CRLConverter; import org.bouncycastle.jce.ECGOST3410NamedCurveTable; import org.bouncycastle.jce.provider.BouncyCastleProvider; import org.bouncycastle.jce.spec.GOST3410ParameterSpec; import org.bouncycastle.operator.jcajce.JcaContentSignerBuilder; import org.bouncycastle.util.encoders.Base64; import org.bouncycastle.x509.X509AttributeCertificate; import org.bouncycastle.x509.X509StreamParser; import org.bouncycastle.x509.X509V1CertificateGenerator; import org.bouncycastle.x509.X509V3CertificateGenerator; import org.bouncycastle.x509.extension.AuthorityKeyIdentifierStructure; public class CMSTestUtil { public static SecureRandom rand; public static KeyPairGenerator kpg; public static KeyPairGenerator gostKpg; public static KeyPairGenerator dsaKpg; public static KeyPairGenerator ecGostKpg; public static KeyPairGenerator ecDsaKpg; public static KeyGenerator aes192kg; public static KeyGenerator desede128kg; public static KeyGenerator desede192kg; public static KeyGenerator rc240kg; public static KeyGenerator rc264kg; public static KeyGenerator rc2128kg; public static KeyGenerator aesKg; public static KeyGenerator seedKg; public static KeyGenerator camelliaKg; public static BigInteger serialNumber; public static final boolean DEBUG = true; private static byte[] attrCert = Base64.decode( "MIIHQDCCBqkCAQEwgZChgY2kgYowgYcxHDAaBgkqhkiG9w0BCQEWDW1sb3JjaEB2" + "dC5lZHUxHjAcBgNVBAMTFU1hcmt1cyBMb3JjaCAobWxvcmNoKTEbMBkGA1UECxMS" + "VmlyZ2luaWEgVGVjaCBVc2VyMRAwDgYDVQQLEwdDbGFzcyAyMQswCQYDVQQKEwJ2" + "dDELMAkGA1UEBhMCVVMwgYmkgYYwgYMxGzAZBgkqhkiG9w0BCQEWDHNzaGFoQHZ0" + "LmVkdTEbMBkGA1UEAxMSU3VtaXQgU2hhaCAoc3NoYWgpMRswGQYDVQQLExJWaXJn" + "aW5pYSBUZWNoIFVzZXIxEDAOBgNVBAsTB0NsYXNzIDExCzAJBgNVBAoTAnZ0MQsw" + "CQYDVQQGEwJVUzANBgkqhkiG9w0BAQQFAAIBBTAiGA8yMDAzMDcxODE2MDgwMloY" + "DzIwMDMwNzI1MTYwODAyWjCCBU0wggVJBgorBgEEAbRoCAEBMYIFORaCBTU8UnVs" + "ZSBSdWxlSWQ9IkZpbGUtUHJpdmlsZWdlLVJ1bGUiIEVmZmVjdD0iUGVybWl0Ij4K" + "IDxUYXJnZXQ+CiAgPFN1YmplY3RzPgogICA8U3ViamVjdD4KICAgIDxTdWJqZWN0" + "TWF0Y2ggTWF0Y2hJZD0idXJuOm9hc2lzOm5hbWVzOnRjOnhhY21sOjEuMDpmdW5j" + "dGlvbjpzdHJpbmctZXF1YWwiPgogICAgIDxBdHRyaWJ1dGVWYWx1ZSBEYXRhVHlw" + "ZT0iaHR0cDovL3d3dy53My5vcmcvMjAwMS9YTUxTY2hlbWEjc3RyaW5nIj4KICAg" + "ICAgIENOPU1hcmt1cyBMb3JjaDwvQXR0cmlidXRlVmFsdWU+CiAgICAgPFN1Ympl" + "Y3RBdHRyaWJ1dGVEZXNpZ25hdG9yIEF0dHJpYnV0ZUlkPSJ1cm46b2FzaXM6bmFt" + "ZXM6dGM6eGFjbWw6MS4wOnN1YmplY3Q6c3ViamVjdC1pZCIgRGF0YVR5cGU9Imh0" + "dHA6Ly93d3cudzMub3JnLzIwMDEvWE1MU2NoZW1hI3N0cmluZyIgLz4gCiAgICA8" + "L1N1YmplY3RNYXRjaD4KICAgPC9TdWJqZWN0PgogIDwvU3ViamVjdHM+CiAgPFJl" + "c291cmNlcz4KICAgPFJlc291cmNlPgogICAgPFJlc291cmNlTWF0Y2ggTWF0Y2hJ" + "ZD0idXJuOm9hc2lzOm5hbWVzOnRjOnhhY21sOjEuMDpmdW5jdGlvbjpzdHJpbmct" + "ZXF1YWwiPgogICAgIDxBdHRyaWJ1dGVWYWx1ZSBEYXRhVHlwZT0iaHR0cDovL3d3" + "dy53My5vcmcvMjAwMS9YTUxTY2hlbWEjYW55VVJJIj4KICAgICAgaHR0cDovL3p1" + "bmkuY3MudnQuZWR1PC9BdHRyaWJ1dGVWYWx1ZT4KICAgICA8UmVzb3VyY2VBdHRy" + "aWJ1dGVEZXNpZ25hdG9yIEF0dHJpYnV0ZUlkPSJ1cm46b2FzaXM6bmFtZXM6dGM6" + "eGFjbWw6MS4wOnJlc291cmNlOnJlc291cmNlLWlkIiBEYXRhVHlwZT0iaHR0cDov" + "L3d3dy53My5vcmcvMjAwMS9YTUxTY2hlbWEjYW55VVJJIiAvPiAKICAgIDwvUmVz" + "b3VyY2VNYXRjaD4KICAgPC9SZXNvdXJjZT4KICA8L1Jlc291cmNlcz4KICA8QWN0" + "aW9ucz4KICAgPEFjdGlvbj4KICAgIDxBY3Rpb25NYXRjaCBNYXRjaElkPSJ1cm46" + "b2FzaXM6bmFtZXM6dGM6eGFjbWw6MS4wOmZ1bmN0aW9uOnN0cmluZy1lcXVhbCI+" + "CiAgICAgPEF0dHJpYnV0ZVZhbHVlIERhdGFUeXBlPSJodHRwOi8vd3d3LnczLm9y" + "Zy8yMDAxL1hNTFNjaGVtYSNzdHJpbmciPgpEZWxlZ2F0ZSBBY2Nlc3MgICAgIDwv" + "QXR0cmlidXRlVmFsdWU+CgkgIDxBY3Rpb25BdHRyaWJ1dGVEZXNpZ25hdG9yIEF0" + "dHJpYnV0ZUlkPSJ1cm46b2FzaXM6bmFtZXM6dGM6eGFjbWw6MS4wOmFjdGlvbjph" + "Y3Rpb24taWQiIERhdGFUeXBlPSJodHRwOi8vd3d3LnczLm9yZy8yMDAxL1hNTFNj" + "aGVtYSNzdHJpbmciIC8+IAogICAgPC9BY3Rpb25NYXRjaD4KICAgPC9BY3Rpb24+" + "CiAgPC9BY3Rpb25zPgogPC9UYXJnZXQ+CjwvUnVsZT4KMA0GCSqGSIb3DQEBBAUA" + "A4GBAGiJSM48XsY90HlYxGmGVSmNR6ZW2As+bot3KAfiCIkUIOAqhcphBS23egTr" + "6asYwy151HshbPNYz+Cgeqs45KkVzh7bL/0e1r8sDVIaaGIkjHK3CqBABnfSayr3" + "Rd1yBoDdEv8Qb+3eEPH6ab9021AsLEnJ6LWTmybbOpMNZ3tv"); static { try { java.security.Security.addProvider(new BouncyCastleProvider()); rand = new SecureRandom(); kpg = KeyPairGenerator.getInstance("RSA", "BC"); kpg.initialize(1024, rand); gostKpg = KeyPairGenerator.getInstance("GOST3410", "BC"); GOST3410ParameterSpec gost3410P = new GOST3410ParameterSpec(CryptoProObjectIdentifiers.gostR3410_94_CryptoPro_A.getId()); gostKpg.initialize(gost3410P, new SecureRandom()); dsaKpg = KeyPairGenerator.getInstance("DSA", "BC"); DSAParameterSpec dsaSpec = new DSAParameterSpec( new BigInteger("7434410770759874867539421675728577177024889699586189000788950934679315164676852047058354758883833299702695428196962057871264685291775577130504050839126673"), new BigInteger("1138656671590261728308283492178581223478058193247"), new BigInteger("4182906737723181805517018315469082619513954319976782448649747742951189003482834321192692620856488639629011570381138542789803819092529658402611668375788410")); dsaKpg.initialize(dsaSpec, new SecureRandom()); ecGostKpg = KeyPairGenerator.getInstance("ECGOST3410", "BC"); ecGostKpg.initialize(ECGOST3410NamedCurveTable.getParameterSpec("GostR3410-2001-CryptoPro-A"), new SecureRandom()); ecDsaKpg = KeyPairGenerator.getInstance("ECDSA", "BC"); ecDsaKpg.initialize(239, new SecureRandom()); aes192kg = KeyGenerator.getInstance("AES", "BC"); aes192kg.init(192, rand); desede128kg = KeyGenerator.getInstance("DESEDE", "BC"); desede128kg.init(112, rand); desede192kg = KeyGenerator.getInstance("DESEDE", "BC"); desede192kg.init(168, rand); rc240kg = KeyGenerator.getInstance("RC2", "BC"); rc240kg.init(40, rand); rc264kg = KeyGenerator.getInstance("RC2", "BC"); rc264kg.init(64, rand); rc2128kg = KeyGenerator.getInstance("RC2", "BC"); rc2128kg.init(128, rand); aesKg = KeyGenerator.getInstance("AES", "BC"); seedKg = KeyGenerator.getInstance("SEED", "BC"); camelliaKg = KeyGenerator.getInstance("Camellia", "BC"); serialNumber = new BigInteger("1"); } catch (Exception ex) { throw new RuntimeException(ex.toString()); } } public static String dumpBase64( byte[] data) { StringBuffer buf = new StringBuffer(); data = Base64.encode(data); for (int i = 0; i < data.length; i += 64) { if (i + 64 < data.length) { buf.append(new String(data, i, 64)); } else { buf.append(new String(data, i, data.length - i)); } buf.append('\n'); } return buf.toString(); } public static X509AttributeCertificate getAttributeCertificate() throws Exception { X509StreamParser parser = X509StreamParser.getInstance("AttributeCertificate", "BC"); parser.init(CMSTestUtil.attrCert); return (X509AttributeCertificate)parser.read(); } public static KeyPair makeKeyPair() { return kpg.generateKeyPair(); } public static KeyPair makeGostKeyPair() { return gostKpg.generateKeyPair(); } public static KeyPair makeDsaKeyPair() { return dsaKpg.generateKeyPair(); } public static KeyPair makeEcDsaKeyPair() { return ecDsaKpg.generateKeyPair(); } public static KeyPair makeEcGostKeyPair() { return ecGostKpg.generateKeyPair(); } public static SecretKey makeDesede128Key() { return desede128kg.generateKey(); } public static SecretKey makeAES192Key() { return aes192kg.generateKey(); } public static SecretKey makeDesede192Key() { return desede192kg.generateKey(); } public static SecretKey makeRC240Key() { return rc240kg.generateKey(); } public static SecretKey makeRC264Key() { return rc264kg.generateKey(); } public static SecretKey makeRC2128Key() { return rc2128kg.generateKey(); } public static SecretKey makeSEEDKey() { return seedKg.generateKey(); } public static SecretKey makeAESKey(int keySize) { aesKg.init(keySize); return aesKg.generateKey(); } public static SecretKey makeCamelliaKey(int keySize) { camelliaKg.init(keySize); return camelliaKg.generateKey(); } public static X509Certificate makeCertificate(KeyPair _subKP, String _subDN, KeyPair _issKP, String _issDN) throws GeneralSecurityException, IOException { return makeCertificate(_subKP, _subDN, _issKP, _issDN, false); } public static X509Certificate makeCACertificate(KeyPair _subKP, String _subDN, KeyPair _issKP, String _issDN) throws GeneralSecurityException, IOException { return makeCertificate(_subKP, _subDN, _issKP, _issDN, true); } public static X509Certificate makeV1Certificate(KeyPair subKP, String _subDN, KeyPair issKP, String _issDN) throws GeneralSecurityException, IOException { PublicKey subPub = subKP.getPublic(); PrivateKey issPriv = issKP.getPrivate(); PublicKey issPub = issKP.getPublic(); X509V1CertificateGenerator v1CertGen = new X509V1CertificateGenerator(); v1CertGen.reset(); v1CertGen.setSerialNumber(allocateSerialNumber()); v1CertGen.setIssuerDN(new X509Name(_issDN)); v1CertGen.setNotBefore(new Date(System.currentTimeMillis())); v1CertGen.setNotAfter(new Date(System.currentTimeMillis() + (1000L * 60 * 60 * 24 * 100))); v1CertGen.setSubjectDN(new X509Name(_subDN)); v1CertGen.setPublicKey(subPub); if (issPub instanceof RSAPublicKey) { v1CertGen.setSignatureAlgorithm("SHA1WithRSA"); } else if (issPub.getAlgorithm().equals("DSA")) { v1CertGen.setSignatureAlgorithm("SHA1withDSA"); } else if (issPub.getAlgorithm().equals("ECDSA")) { v1CertGen.setSignatureAlgorithm("SHA1withECDSA"); } else if (issPub.getAlgorithm().equals("ECGOST3410")) { v1CertGen.setSignatureAlgorithm("GOST3411withECGOST3410"); } else { v1CertGen.setSignatureAlgorithm("GOST3411WithGOST3410"); } X509Certificate _cert = v1CertGen.generate(issPriv); _cert.checkValidity(new Date()); _cert.verify(issPub); return _cert; } public static X509Certificate makeCertificate(KeyPair subKP, String _subDN, KeyPair issKP, String _issDN, boolean _ca) throws GeneralSecurityException, IOException { PublicKey subPub = subKP.getPublic(); PrivateKey issPriv = issKP.getPrivate(); PublicKey issPub = issKP.getPublic(); X509V3CertificateGenerator v3CertGen = new X509V3CertificateGenerator(); v3CertGen.reset(); v3CertGen.setSerialNumber(allocateSerialNumber()); v3CertGen.setIssuerDN(new X509Name(_issDN)); v3CertGen.setNotBefore(new Date(System.currentTimeMillis())); v3CertGen.setNotAfter(new Date(System.currentTimeMillis() + (1000L * 60 * 60 * 24 * 100))); v3CertGen.setSubjectDN(new X509Name(_subDN)); v3CertGen.setPublicKey(subPub); if (issPub instanceof RSAPublicKey) { v3CertGen.setSignatureAlgorithm("SHA1WithRSA"); } else if (issPub.getAlgorithm().equals("DSA")) { v3CertGen.setSignatureAlgorithm("SHA1withDSA"); } else if (issPub.getAlgorithm().equals("ECDSA")) { v3CertGen.setSignatureAlgorithm("SHA1withECDSA"); } else if (issPub.getAlgorithm().equals("ECGOST3410")) { v3CertGen.setSignatureAlgorithm("GOST3411withECGOST3410"); } else { v3CertGen.setSignatureAlgorithm("GOST3411WithGOST3410"); } v3CertGen.addExtension( X509Extension.subjectKeyIdentifier, false, createSubjectKeyId(subPub)); v3CertGen.addExtension( X509Extension.authorityKeyIdentifier, false, createAuthorityKeyId(issPub)); v3CertGen.addExtension( X509Extension.basicConstraints, false, new BasicConstraints(_ca)); X509Certificate _cert = v3CertGen.generate(issPriv); _cert.checkValidity(new Date()); _cert.verify(issPub); return _cert; } public static X509CRL makeCrl(KeyPair pair) throws Exception { Date now = new Date(); X509v2CRLBuilder crlGen = new X509v2CRLBuilder(new X500Name("CN=Test CA"), now); crlGen.setNextUpdate(new Date(now.getTime() + 100000)); crlGen.addCRLEntry(BigInteger.ONE, now, CRLReason.privilegeWithdrawn); crlGen.addExtension(X509Extension.authorityKeyIdentifier, false, new AuthorityKeyIdentifierStructure(pair.getPublic())); return new JcaX509CRLConverter().setProvider("BC").getCRL(crlGen.build(new JcaContentSignerBuilder("SHA256WithRSAEncryption").setProvider("BC").build(pair.getPrivate()))); } /* * * INTERNAL METHODS * */ private static final X509ExtensionUtils extUtils = new X509ExtensionUtils(new SHA1DigestCalculator()); private static AuthorityKeyIdentifier createAuthorityKeyId( PublicKey _pubKey) throws IOException { return extUtils.createAuthorityKeyIdentifier(SubjectPublicKeyInfo.getInstance(_pubKey.getEncoded())); } static SubjectKeyIdentifier createSubjectKeyId( PublicKey _pubKey) throws IOException { return extUtils.createSubjectKeyIdentifier(SubjectPublicKeyInfo.getInstance(_pubKey.getEncoded())); } private static BigInteger allocateSerialNumber() { BigInteger _tmp = serialNumber; serialNumber = serialNumber.add(BigInteger.ONE); return _tmp; } public static byte[] streamToByteArray( InputStream in) throws IOException { ByteArrayOutputStream bOut = new ByteArrayOutputStream(); int ch; while ((ch = in.read()) >= 0) { bOut.write(ch); } return bOut.toByteArray(); } } bouncycastle-1.49.orig/test/src/org/bouncycastle/cms/test/AuthenticatedDataStreamTest.java0000644000175000017500000001037711417520647031474 0ustar ebourgebourgpackage org.bouncycastle.cms.test; import java.io.ByteArrayOutputStream; import java.io.OutputStream; import java.security.KeyPair; import java.security.cert.X509Certificate; import java.util.Arrays; import java.util.Collection; import java.util.Iterator; import junit.framework.Test; import junit.framework.TestCase; import junit.framework.TestSuite; import org.bouncycastle.asn1.pkcs.PKCSObjectIdentifiers; import org.bouncycastle.cms.CMSAuthenticatedDataGenerator; import org.bouncycastle.cms.CMSAuthenticatedDataParser; import org.bouncycastle.cms.CMSAuthenticatedDataStreamGenerator; import org.bouncycastle.cms.RecipientInformation; import org.bouncycastle.cms.RecipientInformationStore; import org.bouncycastle.jce.provider.BouncyCastleProvider; public class AuthenticatedDataStreamTest extends TestCase { private static final String BC = BouncyCastleProvider.PROVIDER_NAME; private static String _signDN; private static KeyPair _signKP; private static X509Certificate _signCert; private static String _origDN; private static KeyPair _origKP; private static X509Certificate _origCert; private static String _reciDN; private static KeyPair _reciKP; private static X509Certificate _reciCert; private static KeyPair _origEcKP; private static KeyPair _reciEcKP; private static X509Certificate _reciEcCert; private static boolean _initialised = false; public boolean DEBUG = true; private static void init() throws Exception { if (!_initialised) { _initialised = true; _signDN = "O=Bouncy Castle, C=AU"; _signKP = CMSTestUtil.makeKeyPair(); _signCert = CMSTestUtil.makeCertificate(_signKP, _signDN, _signKP, _signDN); _origDN = "CN=Bob, OU=Sales, O=Bouncy Castle, C=AU"; _origKP = CMSTestUtil.makeKeyPair(); _origCert = CMSTestUtil.makeCertificate(_origKP, _origDN, _signKP, _signDN); _reciDN = "CN=Doug, OU=Sales, O=Bouncy Castle, C=AU"; _reciKP = CMSTestUtil.makeKeyPair(); _reciCert = CMSTestUtil.makeCertificate(_reciKP, _reciDN, _signKP, _signDN); _origEcKP = CMSTestUtil.makeEcDsaKeyPair(); _reciEcKP = CMSTestUtil.makeEcDsaKeyPair(); _reciEcCert = CMSTestUtil.makeCertificate(_reciEcKP, _reciDN, _signKP, _signDN); } } public void setUp() throws Exception { init(); } public AuthenticatedDataStreamTest(String name) { super(name); } public static void main(String args[]) { junit.textui.TestRunner.run(AuthenticatedDataStreamTest.class); } public static Test suite() throws Exception { init(); return new CMSTestSetup(new TestSuite(AuthenticatedDataStreamTest.class)); } public void testKeyTransDESede() throws Exception { tryKeyTrans(CMSAuthenticatedDataGenerator.DES_EDE3_CBC); } private void tryKeyTrans(String macAlg) throws Exception { byte[] data = "Eric H. Echidna".getBytes(); CMSAuthenticatedDataStreamGenerator adGen = new CMSAuthenticatedDataStreamGenerator(); ByteArrayOutputStream bOut = new ByteArrayOutputStream(); adGen.addKeyTransRecipient(_reciCert); OutputStream aOut = adGen.open(bOut, macAlg, BC); aOut.write(data); aOut.close(); CMSAuthenticatedDataParser ad = new CMSAuthenticatedDataParser(bOut.toByteArray()); RecipientInformationStore recipients = ad.getRecipientInfos(); assertEquals(ad.getMacAlgOID(), macAlg); Collection c = recipients.getRecipients(); assertEquals(1, c.size()); Iterator it = c.iterator(); while (it.hasNext()) { RecipientInformation recipient = (RecipientInformation)it.next(); assertEquals(recipient.getKeyEncryptionAlgOID(), PKCSObjectIdentifiers.rsaEncryption.getId()); byte[] recData = recipient.getContent(_reciKP.getPrivate(), BC); assertTrue(Arrays.equals(data, recData)); assertTrue(Arrays.equals(ad.getMac(), recipient.getMac())); } } }bouncycastle-1.49.orig/test/src/org/bouncycastle/cms/test/BcSignedDataTest.java0000644000175000017500000022204512110046640027174 0ustar ebourgebourgpackage org.bouncycastle.cms.test; import java.io.ByteArrayInputStream; import java.io.IOException; import java.security.KeyFactory; import java.security.KeyPair; import java.security.MessageDigest; import java.security.Security; import java.security.cert.X509CRL; import java.security.cert.X509Certificate; import java.security.spec.PKCS8EncodedKeySpec; import java.security.spec.X509EncodedKeySpec; import java.util.ArrayList; import java.util.Collection; import java.util.HashMap; import java.util.Iterator; import java.util.List; import java.util.Map; import junit.framework.Test; import junit.framework.TestCase; import junit.framework.TestSuite; import org.bouncycastle.asn1.ASN1EncodableVector; import org.bouncycastle.asn1.ASN1InputStream; import org.bouncycastle.asn1.ASN1ObjectIdentifier; import org.bouncycastle.asn1.ASN1OctetString; import org.bouncycastle.asn1.DEROctetString; import org.bouncycastle.asn1.DERSet; import org.bouncycastle.asn1.cms.Attribute; import org.bouncycastle.asn1.cms.AttributeTable; import org.bouncycastle.asn1.cms.CMSAttributes; import org.bouncycastle.asn1.cms.ContentInfo; import org.bouncycastle.asn1.oiw.OIWObjectIdentifiers; import org.bouncycastle.asn1.pkcs.PKCSObjectIdentifiers; import org.bouncycastle.asn1.x509.AlgorithmIdentifier; import org.bouncycastle.cert.X509AttributeCertificateHolder; import org.bouncycastle.cert.X509CertificateHolder; import org.bouncycastle.cert.jcajce.JcaCRLStore; import org.bouncycastle.cert.jcajce.JcaCertStore; import org.bouncycastle.cert.jcajce.JcaX509CRLHolder; import org.bouncycastle.cert.jcajce.JcaX509CertificateHolder; import org.bouncycastle.cms.CMSAbsentContent; import org.bouncycastle.cms.CMSAlgorithm; import org.bouncycastle.cms.CMSException; import org.bouncycastle.cms.CMSProcessableByteArray; import org.bouncycastle.cms.CMSSignedData; import org.bouncycastle.cms.CMSSignedDataGenerator; import org.bouncycastle.cms.CMSSignedDataParser; import org.bouncycastle.cms.CMSTypedData; import org.bouncycastle.cms.DefaultCMSSignatureAlgorithmNameGenerator; import org.bouncycastle.cms.DefaultSignedAttributeTableGenerator; import org.bouncycastle.cms.SignerId; import org.bouncycastle.cms.SignerInfoGeneratorBuilder; import org.bouncycastle.cms.SignerInformation; import org.bouncycastle.cms.SignerInformationStore; import org.bouncycastle.cms.bc.BcRSASignerInfoVerifierBuilder; import org.bouncycastle.cms.jcajce.JcaSignerInfoGeneratorBuilder; import org.bouncycastle.cms.jcajce.JcaSimpleSignerInfoGeneratorBuilder; import org.bouncycastle.cms.jcajce.JcaSimpleSignerInfoVerifierBuilder; import org.bouncycastle.crypto.params.AsymmetricKeyParameter; import org.bouncycastle.crypto.util.PrivateKeyFactory; import org.bouncycastle.jcajce.provider.config.ConfigurableProvider; import org.bouncycastle.jce.provider.BouncyCastleProvider; import org.bouncycastle.operator.ContentSigner; import org.bouncycastle.operator.DefaultDigestAlgorithmIdentifierFinder; import org.bouncycastle.operator.DefaultSignatureAlgorithmIdentifierFinder; import org.bouncycastle.operator.DigestCalculatorProvider; import org.bouncycastle.operator.bc.BcContentSignerBuilder; import org.bouncycastle.operator.bc.BcDigestCalculatorProvider; import org.bouncycastle.operator.bc.BcRSAContentSignerBuilder; import org.bouncycastle.operator.jcajce.JcaContentSignerBuilder; import org.bouncycastle.operator.jcajce.JcaDigestCalculatorProviderBuilder; import org.bouncycastle.util.CollectionStore; import org.bouncycastle.util.Store; import org.bouncycastle.util.encoders.Base64; import org.bouncycastle.util.io.Streams; public class BcSignedDataTest extends TestCase { private static final String BC = BouncyCastleProvider.PROVIDER_NAME; boolean DEBUG = true; private static String _origDN; private static KeyPair _origKP; private static X509Certificate _origCert; private static String _signDN; private static KeyPair _signKP; private static X509Certificate _signCert; private static KeyPair _signEcDsaKP; private static X509Certificate _signEcDsaCert; private static KeyPair _signEcGostKP; private static X509Certificate _signEcGostCert; private static KeyPair _signDsaKP; private static X509Certificate _signDsaCert; private static String _reciDN; private static KeyPair _reciKP; private static X509Certificate _reciCert; private static X509CRL _signCrl; private static boolean _initialised = false; private byte[] disorderedMessage = Base64.decode( "SU9fc3RkaW5fdXNlZABfX2xpYmNfc3RhcnRfbWFpbgBnZXRob3N0aWQAX19n" + "bW9uX3M="); private byte[] disorderedSet = Base64.decode( "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" + "gQBpSRdnDb6AcNVaXSmGo6+kVPIBhot1LzJOGaPyDNpGXxd7LV4tMBF1U7gr" + "4k1g9BO6YiMWvw9uiTZmn0CfV8+k4fWEuG/nmafRoGIuay2f+ILuT+C0rnp1" + "4FgMsEhuVNJJAmb12QV0PZII+UneyhAneZuQQzVUkTcVgYxogxdSOzCCAlUw" + "ggHBoAMCAQICBACdekowCgYGKyQDAwECBQAwbzELMAkGA1UEBhMCREUxPTA7" + "BgNVBAoUNFJlZ3VsaWVydW5nc2JlaMhvcmRlIGbIdXIgVGVsZWtvbW11bmlr" + "YXRpb24gdW5kIFBvc3QxITAMBgcCggYBCgcUEwExMBEGA1UEAxQKNlItQ2Eg" + "MTpQTjAiGA8yMDAxMDIwMTEzNDcwN1oYDzIwMDUwMzIyMDg1NTUxWjBvMQsw" + "CQYDVQQGEwJERTE9MDsGA1UEChQ0UmVndWxpZXJ1bmdzYmVoyG9yZGUgZsh1" + "ciBUZWxla29tbXVuaWthdGlvbiB1bmQgUG9zdDEhMAwGBwKCBgEKBxQTATEw" + "EQYDVQQDFAo1Ui1DQSAxOlBOMIGhMA0GCSqGSIb3DQEBAQUAA4GPADCBiwKB" + "gQCKHkFTJx8GmoqFTxEOxpK9XkC3NZ5dBEKiUv0Ife3QMqeGMoCUnyJxwW0k" + "2/53duHxtv2yHSZpFKjrjvE/uGwdOMqBMTjMzkFg19e9JPv061wyADOucOIa" + "NAgha/zFt9XUyrHF21knKCvDNExv2MYIAagkTKajLMAw0bu1J0FadQIFAMAA" + "AAEwCgYGKyQDAwECBQADgYEAV1yTi+2gyB7sUhn4PXmi/tmBxAfe5oBjDW8m" + "gxtfudxKGZ6l/FUPNcrSc5oqBYxKWtLmf3XX87LcblYsch617jtNTkMzhx9e" + "qxiD02ufcrxz2EVt0Akdqiz8mdVeqp3oLcNU/IttpSrcA91CAnoUXtDZYwb/" + "gdQ4FI9l3+qo/0UwggJVMIIBwaADAgECAgQAxIymMAoGBiskAwMBAgUAMG8x" + "CzAJBgNVBAYTAkRFMT0wOwYDVQQKFDRSZWd1bGllcnVuZ3NiZWjIb3JkZSBm" + "yHVyIFRlbGVrb21tdW5pa2F0aW9uIHVuZCBQb3N0MSEwDAYHAoIGAQoHFBMB" + "MTARBgNVBAMUCjZSLUNhIDE6UE4wIhgPMjAwMTEwMTUxMzMxNThaGA8yMDA1" + "MDYwMTA5NTIxN1owbzELMAkGA1UEBhMCREUxPTA7BgNVBAoUNFJlZ3VsaWVy" + "dW5nc2JlaMhvcmRlIGbIdXIgVGVsZWtvbW11bmlrYXRpb24gdW5kIFBvc3Qx" + "ITAMBgcCggYBCgcUEwExMBEGA1UEAxQKN1ItQ0EgMTpQTjCBoTANBgkqhkiG" + "9w0BAQEFAAOBjwAwgYsCgYEAiokD/j6lEP4FexF356OpU5teUpGGfUKjIrFX" + "BHc79G0TUzgVxqMoN1PWnWktQvKo8ETaugxLkP9/zfX3aAQzDW4Zki6x6GDq" + "fy09Agk+RJvhfbbIzRkV4sBBco0n73x7TfG/9NTgVr/96U+I+z/1j30aboM6" + "9OkLEhjxAr0/GbsCBQDAAAABMAoGBiskAwMBAgUAA4GBAHWRqRixt+EuqHhR" + "K1kIxKGZL2vZuakYV0R24Gv/0ZR52FE4ECr+I49o8FP1qiGSwnXB0SwjuH2S" + "iGiSJi+iH/MeY85IHwW1P5e+bOMvEOFhZhQXQixOD7totIoFtdyaj1XGYRef" + "0f2cPOjNJorXHGV8wuBk+/j++sxbd/Net3FtMIICVTCCAcGgAwIBAgIEAMSM" + "pzAKBgYrJAMDAQIFADBvMQswCQYDVQQGEwJERTE9MDsGA1UEChQ0UmVndWxp" + "ZXJ1bmdzYmVoyG9yZGUgZsh1ciBUZWxla29tbXVuaWthdGlvbiB1bmQgUG9z" + "dDEhMAwGBwKCBgEKBxQTATEwEQYDVQQDFAo3Ui1DQSAxOlBOMCIYDzIwMDEx" + "MDE1MTMzNDE0WhgPMjAwNTA2MDEwOTUyMTdaMG8xCzAJBgNVBAYTAkRFMT0w" + "OwYDVQQKFDRSZWd1bGllcnVuZ3NiZWjIb3JkZSBmyHVyIFRlbGVrb21tdW5p" + "a2F0aW9uIHVuZCBQb3N0MSEwDAYHAoIGAQoHFBMBMTARBgNVBAMUCjZSLUNh" + "IDE6UE4wgaEwDQYJKoZIhvcNAQEBBQADgY8AMIGLAoGBAIOiqxUkzVyqnvth" + "ihnltsE5m1Xn5TZKeR/2MQPStc5hJ+V4yptEtIx+Fn5rOoqT5VEVWhcE35wd" + "bPvgJyQFn5msmhPQT/6XSGOlrWRoFummXN9lQzAjCj1sgTcmoLCVQ5s5WpCA" + "OXFwVWu16qndz3sPItn3jJ0F3Kh3w79NglvPAgUAwAAAATAKBgYrJAMDAQIF" + "AAOBgQBi5W96UVDoNIRkCncqr1LLG9vF9SGBIkvFpLDIIbcvp+CXhlvsdCJl" + "0pt2QEPSDl4cmpOet+CxJTdTuMeBNXxhb7Dvualog69w/+K2JbPhZYxuVFZs" + "Zh5BkPn2FnbNu3YbJhE60aIkikr72J4XZsI5DxpZCGh6xyV/YPRdKSljFjCC" + "AlQwggHAoAMCAQICAwyDqzAKBgYrJAMDAQIFADBvMQswCQYDVQQGEwJERTE9" + "MDsGA1UEChQ0UmVndWxpZXJ1bmdzYmVoyG9yZGUgZsh1ciBUZWxla29tbXVu" + "aWthdGlvbiB1bmQgUG9zdDEhMAwGBwKCBgEKBxQTATEwEQYDVQQDFAo1Ui1D" + "QSAxOlBOMCIYDzIwMDAwMzIyMDk0MTI3WhgPMjAwNDAxMjExNjA0NTNaMG8x" + "CzAJBgNVBAYTAkRFMT0wOwYDVQQKFDRSZWd1bGllcnVuZ3NiZWjIb3JkZSBm" + "yHVyIFRlbGVrb21tdW5pa2F0aW9uIHVuZCBQb3N0MSEwDAYHAoIGAQoHFBMB" + "MTARBgNVBAMUCjRSLUNBIDE6UE4wgaEwDQYJKoZIhvcNAQEBBQADgY8AMIGL" + "AoGBAI8x26tmrFJanlm100B7KGlRemCD1R93PwdnG7svRyf5ZxOsdGrDszNg" + "xg6ouO8ZHQMT3NC2dH8TvO65Js+8bIyTm51azF6clEg0qeWNMKiiXbBXa+ph" + "hTkGbXiLYvACZ6/MTJMJ1lcrjpRF7BXtYeYMcEF6znD4pxOqrtbf9z5hAgUA" + "wAAAATAKBgYrJAMDAQIFAAOBgQB99BjSKlGPbMLQAgXlvA9jUsDNhpnVm3a1" + "YkfxSqS/dbQlYkbOKvCxkPGA9NBxisBM8l1zFynVjJoy++aysRmcnLY/sHaz" + "23BF2iU7WERy18H3lMBfYB6sXkfYiZtvQZcWaO48m73ZBySuiV3iXpb2wgs/" + "Cs20iqroAWxwq/W/9jCCAlMwggG/oAMCAQICBDsFZ9UwCgYGKyQDAwECBQAw" + "bzELMAkGA1UEBhMCREUxITAMBgcCggYBCgcUEwExMBEGA1UEAxQKNFItQ0Eg" + "MTpQTjE9MDsGA1UEChQ0UmVndWxpZXJ1bmdzYmVoyG9yZGUgZsh1ciBUZWxl" + "a29tbXVuaWthdGlvbiB1bmQgUG9zdDAiGA8xOTk5MDEyMTE3MzUzNFoYDzIw" + "MDQwMTIxMTYwMDAyWjBvMQswCQYDVQQGEwJERTE9MDsGA1UEChQ0UmVndWxp" + "ZXJ1bmdzYmVoyG9yZGUgZsh1ciBUZWxla29tbXVuaWthdGlvbiB1bmQgUG9z" + "dDEhMAwGBwKCBgEKBxQTATEwEQYDVQQDFAozUi1DQSAxOlBOMIGfMA0GCSqG" + "SIb3DQEBAQUAA4GNADCBiQKBgI4B557mbKQg/AqWBXNJhaT/6lwV93HUl4U8" + "u35udLq2+u9phns1WZkdM3gDfEpL002PeLfHr1ID/96dDYf04lAXQfombils" + "of1C1k32xOvxjlcrDOuPEMxz9/HDAQZA5MjmmYHAIulGI8Qg4Tc7ERRtg/hd" + "0QX0/zoOeXoDSEOBAgTAAAABMAoGBiskAwMBAgUAA4GBAIyzwfT3keHI/n2P" + "LrarRJv96mCohmDZNpUQdZTVjGu5VQjVJwk3hpagU0o/t/FkdzAjOdfEw8Ql" + "3WXhfIbNLv1YafMm2eWSdeYbLcbB5yJ1od+SYyf9+tm7cwfDAcr22jNRBqx8" + "wkWKtKDjWKkevaSdy99sAI8jebHtWz7jzydKMIID9TCCA16gAwIBAgICbMcw" + "DQYJKoZIhvcNAQEFBQAwSzELMAkGA1UEBhMCREUxEjAQBgNVBAoUCVNpZ250" + "cnVzdDEoMAwGBwKCBgEKBxQTATEwGAYDVQQDFBFDQSBTSUdOVFJVU1QgMTpQ" + "TjAeFw0wNDA3MzAxMzAyNDZaFw0wNzA3MzAxMzAyNDZaMDwxETAPBgNVBAMM" + "CFlhY29tOlBOMQ4wDAYDVQRBDAVZYWNvbTELMAkGA1UEBhMCREUxCjAIBgNV" + "BAUTATEwgZ8wDQYJKoZIhvcNAQEBBQADgY0AMIGJAoGBAIWzLlYLQApocXIp" + "pgCCpkkOUVLgcLYKeOd6/bXAnI2dTHQqT2bv7qzfUnYvOqiNgYdF13pOYtKg" + "XwXMTNFL4ZOI6GoBdNs9TQiZ7KEWnqnr2945HYx7UpgTBclbOK/wGHuCdcwO" + "x7juZs1ZQPFG0Lv8RoiV9s6HP7POqh1sO0P/AgMBAAGjggH1MIIB8TCBnAYD" + "VR0jBIGUMIGRgBQcZzNghfnXoXRm8h1+VITC5caNRqFzpHEwbzELMAkGA1UE" + "BhMCREUxPTA7BgNVBAoUNFJlZ3VsaWVydW5nc2JlaMhvcmRlIGbIdXIgVGVs" + "ZWtvbW11bmlrYXRpb24gdW5kIFBvc3QxITAMBgcCggYBCgcUEwExMBEGA1UE" + "AxQKNVItQ0EgMTpQToIEALs8rjAdBgNVHQ4EFgQU2e5KAzkVuKaM9I5heXkz" + "bcAIuR8wDgYDVR0PAQH/BAQDAgZAMBIGA1UdIAQLMAkwBwYFKyQIAQEwfwYD" + "VR0fBHgwdjB0oCygKoYobGRhcDovL2Rpci5zaWdudHJ1c3QuZGUvbz1TaWdu" + "dHJ1c3QsYz1kZaJEpEIwQDEdMBsGA1UEAxMUQ1JMU2lnblNpZ250cnVzdDE6" + "UE4xEjAQBgNVBAoTCVNpZ250cnVzdDELMAkGA1UEBhMCREUwYgYIKwYBBQUH" + "AQEEVjBUMFIGCCsGAQUFBzABhkZodHRwOi8vZGlyLnNpZ250cnVzdC5kZS9T" + "aWdudHJ1c3QvT0NTUC9zZXJ2bGV0L2h0dHBHYXRld2F5LlBvc3RIYW5kbGVy" + "MBgGCCsGAQUFBwEDBAwwCjAIBgYEAI5GAQEwDgYHAoIGAQoMAAQDAQH/MA0G" + "CSqGSIb3DQEBBQUAA4GBAHn1m3GcoyD5GBkKUY/OdtD6Sj38LYqYCF+qDbJR" + "6pqUBjY2wsvXepUppEler+stH8mwpDDSJXrJyuzf7xroDs4dkLl+Rs2x+2tg" + "BjU+ABkBDMsym2WpwgA8LCdymmXmjdv9tULxY+ec2pjSEzql6nEZNEfrU8nt" + "ZCSCavgqW4TtMYIBejCCAXYCAQEwUTBLMQswCQYDVQQGEwJERTESMBAGA1UE" + "ChQJU2lnbnRydXN0MSgwDAYHAoIGAQoHFBMBMTAYBgNVBAMUEUNBIFNJR05U" + "UlVTVCAxOlBOAgJsxzAJBgUrDgMCGgUAoIGAMBgGCSqGSIb3DQEJAzELBgkq" + "hkiG9w0BBwEwIwYJKoZIhvcNAQkEMRYEFIYfhPoyfGzkLWWSSLjaHb4HQmaK" + "MBwGCSqGSIb3DQEJBTEPFw0wNTAzMjQwNzM4MzVaMCEGBSskCAYFMRgWFi92" + "YXIvZmlsZXMvdG1wXzEvdGVzdDEwDQYJKoZIhvcNAQEFBQAEgYA2IvA8lhVz" + "VD5e/itUxbFboKxeKnqJ5n/KuO/uBCl1N14+7Z2vtw1sfkIG+bJdp3OY2Cmn" + "mrQcwsN99Vjal4cXVj8t+DJzFG9tK9dSLvD3q9zT/GQ0kJXfimLVwCa4NaSf" + "Qsu4xtG0Rav6bCcnzabAkKuNNvKtH8amSRzk870DBg=="); public static byte[] xtraCounterSig = Base64.decode( "MIIR/AYJKoZIhvcNAQcCoIIR7TCCEekCAQExCzAJBgUrDgMCGgUAMBoGCSqG" + "SIb3DQEHAaANBAtIZWxsbyB3b3JsZKCCDnkwggTPMIIDt6ADAgECAgRDnYD3" + "MA0GCSqGSIb3DQEBBQUAMFgxCzAJBgNVBAYTAklUMRowGAYDVQQKExFJbi5U" + "ZS5TLkEuIFMucC5BLjEtMCsGA1UEAxMkSW4uVGUuUy5BLiAtIENlcnRpZmlj" + "YXRpb24gQXV0aG9yaXR5MB4XDTA4MDkxMjExNDMxMloXDTEwMDkxMjExNDMx" + "MlowgdgxCzAJBgNVBAYTAklUMSIwIAYDVQQKDBlJbnRlc2EgUy5wLkEuLzA1" + "MjYyODkwMDE0MSowKAYDVQQLDCFCdXNpbmVzcyBDb2xsYWJvcmF0aW9uICYg" + "U2VjdXJpdHkxHjAcBgNVBAMMFU1BU1NJTUlMSUFOTyBaSUNDQVJESTERMA8G" + "A1UEBAwIWklDQ0FSREkxFTATBgNVBCoMDE1BU1NJTUlMSUFOTzEcMBoGA1UE" + "BRMTSVQ6WkNDTVNNNzZIMTRMMjE5WTERMA8GA1UELhMIMDAwMDI1ODUwgaAw" + "DQYJKoZIhvcNAQEBBQADgY4AMIGKAoGBALeJTjmyFgx1SIP6c2AuB/kuyHo5" + "j/prKELTALsFDimre/Hxr3wOSet1TdQfFzU8Lu+EJqgfV9cV+cI1yeH1rZs7" + "lei7L3tX/VR565IywnguX5xwvteASgWZr537Fkws50bvTEMyYOj1Tf3FZvZU" + "z4n4OD39KI4mfR9i1eEVIxR3AgQAizpNo4IBoTCCAZ0wHQYDVR0RBBYwFIES" + "emljY2FyZGlAaW50ZXNhLml0MC8GCCsGAQUFBwEDBCMwITAIBgYEAI5GAQEw" + "CwYGBACORgEDAgEUMAgGBgQAjkYBBDBZBgNVHSAEUjBQME4GBgQAizABATBE" + "MEIGCCsGAQUFBwIBFjZodHRwOi8vZS10cnVzdGNvbS5pbnRlc2EuaXQvY2Ff" + "cHViYmxpY2EvQ1BTX0lOVEVTQS5odG0wDgYDVR0PAQH/BAQDAgZAMIGDBgNV" + "HSMEfDB6gBQZCQOW0bjFWBt+EORuxPagEgkQqKFcpFowWDELMAkGA1UEBhMC" + "SVQxGjAYBgNVBAoTEUluLlRlLlMuQS4gUy5wLkEuMS0wKwYDVQQDEyRJbi5U" + "ZS5TLkEuIC0gQ2VydGlmaWNhdGlvbiBBdXRob3JpdHmCBDzRARMwOwYDVR0f" + "BDQwMjAwoC6gLIYqaHR0cDovL2UtdHJ1c3Rjb20uaW50ZXNhLml0L0NSTC9J" + "TlRFU0EuY3JsMB0GA1UdDgQWBBTf5ItL8KmQh541Dxt7YxcWI1254TANBgkq" + "hkiG9w0BAQUFAAOCAQEAgW+uL1CVWQepbC/wfCmR6PN37Sueb4xiKQj2mTD5" + "UZ5KQjpivy/Hbuf0NrfKNiDEhAvoHSPC31ebGiKuTMFNyZPHfPEUnyYGSxea" + "2w837aXJFr6utPNQGBRi89kH90sZDlXtOSrZI+AzJJn5QK3F9gjcayU2NZXQ" + "MJgRwYmFyn2w4jtox+CwXPQ9E5XgxiMZ4WDL03cWVXDLX00EOJwnDDMUNTRI" + "m9Zv+4SKTNlfFbi9UTBqWBySkDzAelsfB2U61oqc2h1xKmCtkGMmN9iZT+Qz" + "ZC/vaaT+hLEBFGAH2gwFrYc4/jTBKyBYeU1vsAxsibIoTs1Apgl6MH75qPDL" + "BzCCBM8wggO3oAMCAQICBEOdgPcwDQYJKoZIhvcNAQEFBQAwWDELMAkGA1UE" + "BhMCSVQxGjAYBgNVBAoTEUluLlRlLlMuQS4gUy5wLkEuMS0wKwYDVQQDEyRJ" + "bi5UZS5TLkEuIC0gQ2VydGlmaWNhdGlvbiBBdXRob3JpdHkwHhcNMDgwOTEy" + "MTE0MzEyWhcNMTAwOTEyMTE0MzEyWjCB2DELMAkGA1UEBhMCSVQxIjAgBgNV" + "BAoMGUludGVzYSBTLnAuQS4vMDUyNjI4OTAwMTQxKjAoBgNVBAsMIUJ1c2lu" + "ZXNzIENvbGxhYm9yYXRpb24gJiBTZWN1cml0eTEeMBwGA1UEAwwVTUFTU0lN" + "SUxJQU5PIFpJQ0NBUkRJMREwDwYDVQQEDAhaSUNDQVJESTEVMBMGA1UEKgwM" + "TUFTU0lNSUxJQU5PMRwwGgYDVQQFExNJVDpaQ0NNU003NkgxNEwyMTlZMREw" + "DwYDVQQuEwgwMDAwMjU4NTCBoDANBgkqhkiG9w0BAQEFAAOBjgAwgYoCgYEA" + "t4lOObIWDHVIg/pzYC4H+S7IejmP+msoQtMAuwUOKat78fGvfA5J63VN1B8X" + "NTwu74QmqB9X1xX5wjXJ4fWtmzuV6Lsve1f9VHnrkjLCeC5fnHC+14BKBZmv" + "nfsWTCznRu9MQzJg6PVN/cVm9lTPifg4Pf0ojiZ9H2LV4RUjFHcCBACLOk2j" + "ggGhMIIBnTAdBgNVHREEFjAUgRJ6aWNjYXJkaUBpbnRlc2EuaXQwLwYIKwYB" + "BQUHAQMEIzAhMAgGBgQAjkYBATALBgYEAI5GAQMCARQwCAYGBACORgEEMFkG" + "A1UdIARSMFAwTgYGBACLMAEBMEQwQgYIKwYBBQUHAgEWNmh0dHA6Ly9lLXRy" + "dXN0Y29tLmludGVzYS5pdC9jYV9wdWJibGljYS9DUFNfSU5URVNBLmh0bTAO" + "BgNVHQ8BAf8EBAMCBkAwgYMGA1UdIwR8MHqAFBkJA5bRuMVYG34Q5G7E9qAS" + "CRCooVykWjBYMQswCQYDVQQGEwJJVDEaMBgGA1UEChMRSW4uVGUuUy5BLiBT" + "LnAuQS4xLTArBgNVBAMTJEluLlRlLlMuQS4gLSBDZXJ0aWZpY2F0aW9uIEF1" + "dGhvcml0eYIEPNEBEzA7BgNVHR8ENDAyMDCgLqAshipodHRwOi8vZS10cnVz" + "dGNvbS5pbnRlc2EuaXQvQ1JML0lOVEVTQS5jcmwwHQYDVR0OBBYEFN/ki0vw" + "qZCHnjUPG3tjFxYjXbnhMA0GCSqGSIb3DQEBBQUAA4IBAQCBb64vUJVZB6ls" + "L/B8KZHo83ftK55vjGIpCPaZMPlRnkpCOmK/L8du5/Q2t8o2IMSEC+gdI8Lf" + "V5saIq5MwU3Jk8d88RSfJgZLF5rbDzftpckWvq6081AYFGLz2Qf3SxkOVe05" + "Ktkj4DMkmflArcX2CNxrJTY1ldAwmBHBiYXKfbDiO2jH4LBc9D0TleDGIxnh" + "YMvTdxZVcMtfTQQ4nCcMMxQ1NEib1m/7hIpM2V8VuL1RMGpYHJKQPMB6Wx8H" + "ZTrWipzaHXEqYK2QYyY32JlP5DNkL+9ppP6EsQEUYAfaDAWthzj+NMErIFh5" + "TW+wDGyJsihOzUCmCXowfvmo8MsHMIIEzzCCA7egAwIBAgIEQ52A9zANBgkq" + "hkiG9w0BAQUFADBYMQswCQYDVQQGEwJJVDEaMBgGA1UEChMRSW4uVGUuUy5B" + "LiBTLnAuQS4xLTArBgNVBAMTJEluLlRlLlMuQS4gLSBDZXJ0aWZpY2F0aW9u" + "IEF1dGhvcml0eTAeFw0wODA5MTIxMTQzMTJaFw0xMDA5MTIxMTQzMTJaMIHY" + "MQswCQYDVQQGEwJJVDEiMCAGA1UECgwZSW50ZXNhIFMucC5BLi8wNTI2Mjg5" + "MDAxNDEqMCgGA1UECwwhQnVzaW5lc3MgQ29sbGFib3JhdGlvbiAmIFNlY3Vy" + "aXR5MR4wHAYDVQQDDBVNQVNTSU1JTElBTk8gWklDQ0FSREkxETAPBgNVBAQM" + "CFpJQ0NBUkRJMRUwEwYDVQQqDAxNQVNTSU1JTElBTk8xHDAaBgNVBAUTE0lU" + "OlpDQ01TTTc2SDE0TDIxOVkxETAPBgNVBC4TCDAwMDAyNTg1MIGgMA0GCSqG" + "SIb3DQEBAQUAA4GOADCBigKBgQC3iU45shYMdUiD+nNgLgf5Lsh6OY/6ayhC" + "0wC7BQ4pq3vx8a98DknrdU3UHxc1PC7vhCaoH1fXFfnCNcnh9a2bO5Xouy97" + "V/1UeeuSMsJ4Ll+ccL7XgEoFma+d+xZMLOdG70xDMmDo9U39xWb2VM+J+Dg9" + "/SiOJn0fYtXhFSMUdwIEAIs6TaOCAaEwggGdMB0GA1UdEQQWMBSBEnppY2Nh" + "cmRpQGludGVzYS5pdDAvBggrBgEFBQcBAwQjMCEwCAYGBACORgEBMAsGBgQA" + "jkYBAwIBFDAIBgYEAI5GAQQwWQYDVR0gBFIwUDBOBgYEAIswAQEwRDBCBggr" + "BgEFBQcCARY2aHR0cDovL2UtdHJ1c3Rjb20uaW50ZXNhLml0L2NhX3B1YmJs" + "aWNhL0NQU19JTlRFU0EuaHRtMA4GA1UdDwEB/wQEAwIGQDCBgwYDVR0jBHww" + "eoAUGQkDltG4xVgbfhDkbsT2oBIJEKihXKRaMFgxCzAJBgNVBAYTAklUMRow" + "GAYDVQQKExFJbi5UZS5TLkEuIFMucC5BLjEtMCsGA1UEAxMkSW4uVGUuUy5B" + "LiAtIENlcnRpZmljYXRpb24gQXV0aG9yaXR5ggQ80QETMDsGA1UdHwQ0MDIw" + "MKAuoCyGKmh0dHA6Ly9lLXRydXN0Y29tLmludGVzYS5pdC9DUkwvSU5URVNB" + "LmNybDAdBgNVHQ4EFgQU3+SLS/CpkIeeNQ8be2MXFiNdueEwDQYJKoZIhvcN" + "AQEFBQADggEBAIFvri9QlVkHqWwv8Hwpkejzd+0rnm+MYikI9pkw+VGeSkI6" + "Yr8vx27n9Da3yjYgxIQL6B0jwt9XmxoirkzBTcmTx3zxFJ8mBksXmtsPN+2l" + "yRa+rrTzUBgUYvPZB/dLGQ5V7Tkq2SPgMySZ+UCtxfYI3GslNjWV0DCYEcGJ" + "hcp9sOI7aMfgsFz0PROV4MYjGeFgy9N3FlVwy19NBDicJwwzFDU0SJvWb/uE" + "ikzZXxW4vVEwalgckpA8wHpbHwdlOtaKnNodcSpgrZBjJjfYmU/kM2Qv72mk" + "/oSxARRgB9oMBa2HOP40wSsgWHlNb7AMbImyKE7NQKYJejB++ajwywcxggM8" + "MIIDOAIBATBgMFgxCzAJBgNVBAYTAklUMRowGAYDVQQKExFJbi5UZS5TLkEu" + "IFMucC5BLjEtMCsGA1UEAxMkSW4uVGUuUy5BLiAtIENlcnRpZmljYXRpb24g" + "QXV0aG9yaXR5AgRDnYD3MAkGBSsOAwIaBQAwDQYJKoZIhvcNAQEBBQAEgYB+" + "lH2cwLqc91mP8prvgSV+RRzk13dJdZvdoVjgQoFrPhBiZCNIEoHvIhMMA/sM" + "X6euSRZk7EjD24FasCEGYyd0mJVLEy6TSPmuW+wWz/28w3a6IWXBGrbb/ild" + "/CJMkPgLPGgOVD1WDwiNKwfasiQSFtySf5DPn3jFevdLeMmEY6GCAjIwggEV" + "BgkqhkiG9w0BCQYxggEGMIIBAgIBATBgMFgxCzAJBgNVBAYTAklUMRowGAYD" + "VQQKExFJbi5UZS5TLkEuIFMucC5BLjEtMCsGA1UEAxMkSW4uVGUuUy5BLiAt" + "IENlcnRpZmljYXRpb24gQXV0aG9yaXR5AgRDnYD3MAkGBSsOAwIaBQAwDQYJ" + "KoZIhvcNAQEBBQAEgYBHlOULfT5GDigIvxP0qZOy8VbpntmzaPF55VV4buKV" + "35J+uHp98gXKp0LrHM69V5IRKuyuQzHHFBqsXxsRI9o6KoOfgliD9Xc+BeMg" + "dKzQhBhBYoFREq8hQM0nSbqDNHYAQyNHMzUA/ZQUO5dlFuH8Dw3iDYAhNtfd" + "PrlchKJthDCCARUGCSqGSIb3DQEJBjGCAQYwggECAgEBMGAwWDELMAkGA1UE" + "BhMCSVQxGjAYBgNVBAoTEUluLlRlLlMuQS4gUy5wLkEuMS0wKwYDVQQDEyRJ" + "bi5UZS5TLkEuIC0gQ2VydGlmaWNhdGlvbiBBdXRob3JpdHkCBEOdgPcwCQYF" + "Kw4DAhoFADANBgkqhkiG9w0BAQEFAASBgEeU5Qt9PkYOKAi/E/Spk7LxVume" + "2bNo8XnlVXhu4pXfkn64en3yBcqnQusczr1XkhEq7K5DMccUGqxfGxEj2joq" + "g5+CWIP1dz4F4yB0rNCEGEFigVESryFAzSdJuoM0dgBDI0czNQD9lBQ7l2UW" + "4fwPDeINgCE2190+uVyEom2E"); byte[] noSignedAttrSample2 = Base64.decode( "MIIIlAYJKoZIhvcNAQcCoIIIhTCCCIECAQExCzAJBgUrDgMCGgUAMAsGCSqG" + "SIb3DQEHAaCCB3UwggOtMIIDa6ADAgECAgEzMAsGByqGSM44BAMFADCBkDEL" + "MAkGA1UEBhMCVVMxCzAJBgNVBAgTAkNBMRIwEAYDVQQHEwlQYWxvIEFsdG8x" + "HTAbBgNVBAoTFFN1biBNaWNyb3N5c3RlbXMgSW5jMSMwIQYDVQQLExpKYXZh" + "IFNvZnR3YXJlIENvZGUgU2lnbmluZzEcMBoGA1UEAxMTSkNFIENvZGUgU2ln" + "bmluZyBDQTAeFw0wMTA1MjkxNjQ3MTFaFw0wNjA1MjgxNjQ3MTFaMG4xHTAb" + "BgNVBAoTFFN1biBNaWNyb3N5c3RlbXMgSW5jMSMwIQYDVQQLExpKYXZhIFNv" + "ZnR3YXJlIENvZGUgU2lnbmluZzEoMCYGA1UEAxMfVGhlIExlZ2lvbiBvZiB0" + "aGUgQm91bmN5IENhc3RsZTCCAbcwggEsBgcqhkjOOAQBMIIBHwKBgQD9f1OB" + "HXUSKVLfSpwu7OTn9hG3UjzvRADDHj+AtlEmaUVdQCJR+1k9jVj6v8X1ujD2" + "y5tVbNeBO4AdNG/yZmC3a5lQpaSfn+gEexAiwk+7qdf+t8Yb+DtX58aophUP" + "BPuD9tPFHsMCNVQTWhaRMvZ1864rYdcq7/IiAxmd0UgBxwIVAJdgUI8VIwvM" + "spK5gqLrhAvwWBz1AoGBAPfhoIXWmz3ey7yrXDa4V7l5lK+7+jrqgvlXTAs9" + "B4JnUVlXjrrUWU/mcQcQgYC0SRZxI+hMKBYTt88JMozIpuE8FnqLVHyNKOCj" + "rh4rs6Z1kW6jfwv6ITVi8ftiegEkO8yk8b6oUZCJqIPf4VrlnwaSi2ZegHtV" + "JWQBTDv+z0kqA4GEAAKBgBWry/FCAZ6miyy39+ftsa+h9lxoL+JtV0MJcUyQ" + "E4VAhpAwWb8vyjba9AwOylYQTktHX5sAkFvjBiU0LOYDbFSTVZSHMRJgfjxB" + "SHtICjOEvr1BJrrOrdzqdxcOUge5n7El124BCrv91x5Ol8UTwtiO9LrRXF/d" + "SyK+RT5n1klRo3YwdDARBglghkgBhvhCAQEEBAMCAIcwDgYDVR0PAQH/BAQD" + "AgHGMB0GA1UdDgQWBBQwMY4NRcco1AO3w1YsokfDLVseEjAPBgNVHRMBAf8E" + "BTADAQH/MB8GA1UdIwQYMBaAFGXi9IbJ007wkU5Yomr12HhamsGmMAsGByqG" + "SM44BAMFAAMvADAsAhRmigTu6QV0sTfEkVljgij/hhdVfAIUQZvMxAnIHc30" + "y/u0C1T5UEG9glUwggPAMIIDfqADAgECAgEQMAsGByqGSM44BAMFADCBkDEL" + "MAkGA1UEBhMCVVMxCzAJBgNVBAgTAkNBMRIwEAYDVQQHEwlQYWxvIEFsdG8x" + "HTAbBgNVBAoTFFN1biBNaWNyb3N5c3RlbXMgSW5jMSMwIQYDVQQLExpKYXZh" + "IFNvZnR3YXJlIENvZGUgU2lnbmluZzEcMBoGA1UEAxMTSkNFIENvZGUgU2ln" + "bmluZyBDQTAeFw0wMTA0MjUwNzAwMDBaFw0yMDA0MjUwNzAwMDBaMIGQMQsw" + "CQYDVQQGEwJVUzELMAkGA1UECBMCQ0ExEjAQBgNVBAcTCVBhbG8gQWx0bzEd" + "MBsGA1UEChMUU3VuIE1pY3Jvc3lzdGVtcyBJbmMxIzAhBgNVBAsTGkphdmEg" + "U29mdHdhcmUgQ29kZSBTaWduaW5nMRwwGgYDVQQDExNKQ0UgQ29kZSBTaWdu" + "aW5nIENBMIIBtzCCASwGByqGSM44BAEwggEfAoGBAOuvNwQeylEeaV2w8o/2" + "tUkfxqSZBdcpv3S3avUZ2B7kG/gKAZqY/3Cr4kpWhmxTs/zhyIGMMfDE87CL" + "5nAG7PdpaNuDTHIpiSk2F1w7SgegIAIqRpdRHXDICBgLzgxum3b3BePn+9Nh" + "eeFgmiSNBpWDPFEg4TDPOFeCphpyDc7TAhUAhCVF4bq5qWKreehbMLiJaxv/" + "e3UCgYEAq8l0e3Tv7kK1alNNO92QBnJokQ8LpCl2LlU71a5NZVx+KjoEpmem" + "0HGqpde34sFyDaTRqh6SVEwgAAmisAlBGTMAssNcrkL4sYvKfJbYEH83RFuq" + "zHjI13J2N2tAmahVZvqoAx6LShECactMuCUGHKB30sms0j3pChD6dnC3+9wD" + "gYQAAoGALQmYXKy4nMeZfu4gGSo0kPnXq6uu3WtylQ1m+O8nj0Sy7ShEx/6v" + "sKYnbwBnRYJbB6hWVjvSKVFhXmk51y50dxLPGUr1LcjLcmHETm/6R0M/FLv6" + "vBhmKMLZZot6LS/CYJJLFP5YPiF/aGK+bEhJ+aBLXoWdGRD5FUVRG3HU9wuj" + "ZjBkMBEGCWCGSAGG+EIBAQQEAwIABzAPBgNVHRMBAf8EBTADAQH/MB8GA1Ud" + "IwQYMBaAFGXi9IbJ007wkU5Yomr12HhamsGmMB0GA1UdDgQWBBRl4vSGydNO" + "8JFOWKJq9dh4WprBpjALBgcqhkjOOAQDBQADLwAwLAIUKvfPPJdd+Xi2CNdB" + "tNkNRUzktJwCFEXNdWkOIfod1rMpsun3Mx0z/fxJMYHoMIHlAgEBMIGWMIGQ" + "MQswCQYDVQQGEwJVUzELMAkGA1UECBMCQ0ExEjAQBgNVBAcTCVBhbG8gQWx0" + "bzEdMBsGA1UEChMUU3VuIE1pY3Jvc3lzdGVtcyBJbmMxIzAhBgNVBAsTGkph" + "dmEgU29mdHdhcmUgQ29kZSBTaWduaW5nMRwwGgYDVQQDExNKQ0UgQ29kZSBT" + "aWduaW5nIENBAgEzMAkGBSsOAwIaBQAwCwYHKoZIzjgEAQUABC8wLQIVAIGV" + "khm+kbV4a/+EP45PHcq0hIViAhR4M9os6IrJnoEDS3Y3l7O6zrSosA=="); /* * * INFRASTRUCTURE * */ public BcSignedDataTest(String name) { super(name); } public static void main(String args[]) { junit.textui.TestRunner.run(BcSignedDataTest.class); } public static Test suite() throws Exception { init(); return new CMSTestSetup(new TestSuite(BcSignedDataTest.class)); } private static void init() throws Exception { if (!_initialised) { _initialised = true; if (Security.getProvider(BC) == null) { Security.addProvider(new BouncyCastleProvider()); } _origDN = "O=Bouncy Castle, C=AU"; _origKP = CMSTestUtil.makeKeyPair(); _origCert = CMSTestUtil.makeCertificate(_origKP, _origDN, _origKP, _origDN); _signDN = "CN=Bob, OU=Sales, O=Bouncy Castle, C=AU"; _signKP = CMSTestUtil.makeKeyPair(); _signCert = CMSTestUtil.makeCertificate(_signKP, _signDN, _origKP, _origDN); _signDsaKP = CMSTestUtil.makeDsaKeyPair(); _signDsaCert = CMSTestUtil.makeCertificate(_signDsaKP, _signDN, _origKP, _origDN); _signEcDsaKP = CMSTestUtil.makeEcDsaKeyPair(); _signEcDsaCert = CMSTestUtil.makeCertificate(_signEcDsaKP, _signDN, _origKP, _origDN); _reciDN = "CN=Doug, OU=Sales, O=Bouncy Castle, C=AU"; _reciKP = CMSTestUtil.makeKeyPair(); _reciCert = CMSTestUtil.makeCertificate(_reciKP, _reciDN, _signKP, _signDN); _signCrl = CMSTestUtil.makeCrl(_signKP); } } private void verifyRSASignatures(CMSSignedData s, byte[] contentDigest) throws Exception { Store certStore = s.getCertificates(); SignerInformationStore signers = s.getSignerInfos(); Collection c = signers.getSigners(); Iterator it = c.iterator(); while (it.hasNext()) { SignerInformation signer = (SignerInformation)it.next(); Collection certCollection = certStore.getMatches(signer.getSID()); Iterator certIt = certCollection.iterator(); X509CertificateHolder cert = (X509CertificateHolder)certIt.next(); assertEquals(true, signer.verify(new BcRSASignerInfoVerifierBuilder(new DefaultCMSSignatureAlgorithmNameGenerator(), new DefaultSignatureAlgorithmIdentifierFinder(), new DefaultDigestAlgorithmIdentifierFinder(), new BcDigestCalculatorProvider()).build(cert))); if (contentDigest != null) { assertTrue(MessageDigest.isEqual(contentDigest, signer.getContentDigest())); } } } private void verifySignatures(CMSSignedData s, byte[] contentDigest) throws Exception { Store certStore = s.getCertificates(); Store crlStore = s.getCRLs(); SignerInformationStore signers = s.getSignerInfos(); Collection c = signers.getSigners(); Iterator it = c.iterator(); while (it.hasNext()) { SignerInformation signer = (SignerInformation)it.next(); Collection certCollection = certStore.getMatches(signer.getSID()); Iterator certIt = certCollection.iterator(); X509CertificateHolder cert = (X509CertificateHolder)certIt.next(); assertEquals(true, signer.verify(new JcaSimpleSignerInfoVerifierBuilder().setProvider(BC).build(cert))); if (contentDigest != null) { assertTrue(MessageDigest.isEqual(contentDigest, signer.getContentDigest())); } } Collection certColl = certStore.getMatches(null); Collection crlColl = crlStore.getMatches(null); assertEquals(certColl.size(), s.getCertificates().getMatches(null).size()); assertEquals(crlColl.size(), s.getCRLs().getMatches(null).size()); } private void verifySignatures(CMSSignedData s) throws Exception { verifySignatures(s, null); } public void testDetachedVerification() throws Exception { byte[] data = "Hello World!".getBytes(); List certList = new ArrayList(); CMSTypedData msg = new CMSProcessableByteArray(data); certList.add(_origCert); certList.add(_signCert); Store certs = new JcaCertStore(certList); CMSSignedDataGenerator gen = new CMSSignedDataGenerator(); DigestCalculatorProvider digProvider = new JcaDigestCalculatorProviderBuilder().setProvider(BC).build(); JcaSignerInfoGeneratorBuilder signerInfoGeneratorBuilder = new JcaSignerInfoGeneratorBuilder(digProvider); ContentSigner sha1Signer = new JcaContentSignerBuilder("SHA1withRSA").setProvider(BC).build(_origKP.getPrivate()); ContentSigner md5Signer = new JcaContentSignerBuilder("MD5withRSA").setProvider(BC).build(_origKP.getPrivate()); gen.addSignerInfoGenerator(signerInfoGeneratorBuilder.build(sha1Signer, _origCert)); gen.addSignerInfoGenerator(signerInfoGeneratorBuilder.build(md5Signer, _origCert)); gen.addCertificates(certs); CMSSignedData s = gen.generate(msg); MessageDigest sha1 = MessageDigest.getInstance("SHA1", BC); MessageDigest md5 = MessageDigest.getInstance("MD5", BC); Map hashes = new HashMap(); byte[] sha1Hash = sha1.digest(data); byte[] md5Hash = md5.digest(data); hashes.put(CMSAlgorithm.SHA1, sha1Hash); hashes.put(CMSAlgorithm.MD5, md5Hash); s = new CMSSignedData(hashes, s.getEncoded()); verifySignatures(s, null); } public void testSHA1AndMD5WithRSAEncapsulatedRepeated() throws Exception { List certList = new ArrayList(); CMSTypedData msg = new CMSProcessableByteArray("Hello World!".getBytes()); certList.add(_origCert); certList.add(_signCert); Store certs = new JcaCertStore(certList); CMSSignedDataGenerator gen = new CMSSignedDataGenerator(); DigestCalculatorProvider digCalcProv = new JcaDigestCalculatorProviderBuilder().setProvider(BC).build(); gen.addSignerInfoGenerator(new JcaSignerInfoGeneratorBuilder(digCalcProv).build(new JcaContentSignerBuilder("SHA1withRSA").setProvider(BC).build(_origKP.getPrivate()), _origCert)); gen.addSignerInfoGenerator(new JcaSignerInfoGeneratorBuilder(digCalcProv).build(new JcaContentSignerBuilder("MD5withRSA").setProvider(BC).build(_origKP.getPrivate()), _origCert)); gen.addCertificates(certs); CMSSignedData s = gen.generate(msg, true); ByteArrayInputStream bIn = new ByteArrayInputStream(s.getEncoded()); ASN1InputStream aIn = new ASN1InputStream(bIn); s = new CMSSignedData(ContentInfo.getInstance(aIn.readObject())); certs = s.getCertificates(); SignerInformationStore signers = s.getSignerInfos(); assertEquals(2, signers.size()); Collection c = signers.getSigners(); Iterator it = c.iterator(); SignerId sid = null; while (it.hasNext()) { SignerInformation signer = (SignerInformation)it.next(); Collection certCollection = certs.getMatches(signer.getSID()); Iterator certIt = certCollection.iterator(); X509CertificateHolder cert = (X509CertificateHolder)certIt.next(); sid = signer.getSID(); assertEquals(true, signer.verify(new JcaSimpleSignerInfoVerifierBuilder().setProvider(BC).build(cert))); // // check content digest // byte[] contentDigest = (byte[])gen.getGeneratedDigests().get(signer.getDigestAlgOID()); AttributeTable table = signer.getSignedAttributes(); Attribute hash = table.get(CMSAttributes.messageDigest); assertTrue(MessageDigest.isEqual(contentDigest, ((ASN1OctetString)hash.getAttrValues().getObjectAt(0)).getOctets())); } c = signers.getSigners(sid); assertEquals(2, c.size()); // // try using existing signer // gen = new CMSSignedDataGenerator(); gen.addSigners(s.getSignerInfos()); gen.addCertificates(s.getCertificates()); s = gen.generate(msg, true); bIn = new ByteArrayInputStream(s.getEncoded()); aIn = new ASN1InputStream(bIn); s = new CMSSignedData(ContentInfo.getInstance(aIn.readObject())); certs = s.getCertificates(); signers = s.getSignerInfos(); c = signers.getSigners(); it = c.iterator(); assertEquals(2, c.size()); while (it.hasNext()) { SignerInformation signer = (SignerInformation)it.next(); Collection certCollection = certs.getMatches(signer.getSID()); Iterator certIt = certCollection.iterator(); X509CertificateHolder cert = (X509CertificateHolder)certIt.next(); assertEquals(true, signer.verify(new JcaSimpleSignerInfoVerifierBuilder().setProvider(BC).build(cert))); } checkSignerStoreReplacement(s, signers); } public void testSHA1WithRSANoAttributes() throws Exception { List certList = new ArrayList(); CMSTypedData msg = new CMSProcessableByteArray("Hello world!".getBytes()); certList.add(_origCert); certList.add(_signCert); Store certs = new JcaCertStore(certList); CMSSignedDataGenerator gen = new CMSSignedDataGenerator(); ContentSigner sha1Signer = new JcaContentSignerBuilder("SHA1withRSA").setProvider(BC).build(_origKP.getPrivate()); JcaSignerInfoGeneratorBuilder builder = new JcaSignerInfoGeneratorBuilder(new JcaDigestCalculatorProviderBuilder().setProvider(BC).build()); builder.setDirectSignature(true); gen.addSignerInfoGenerator(builder.build(sha1Signer, _origCert)); gen.addCertificates(certs); CMSSignedData s = gen.generate(msg, false); // // compute expected content digest // MessageDigest md = MessageDigest.getInstance("SHA1", BC); verifySignatures(s, md.digest("Hello world!".getBytes())); } public void testSHA1WithRSANoAttributesSimple() throws Exception { List certList = new ArrayList(); CMSTypedData msg = new CMSProcessableByteArray("Hello world!".getBytes()); certList.add(_origCert); certList.add(_signCert); Store certs = new JcaCertStore(certList); CMSSignedDataGenerator gen = new CMSSignedDataGenerator(); JcaSimpleSignerInfoGeneratorBuilder builder = new JcaSimpleSignerInfoGeneratorBuilder().setProvider(BC).setDirectSignature(true); gen.addSignerInfoGenerator(builder.build("SHA1withRSA", _origKP.getPrivate(), _origCert)); gen.addCertificates(certs); CMSSignedData s = gen.generate(msg, false); // // compute expected content digest // MessageDigest md = MessageDigest.getInstance("SHA1", BC); verifySignatures(s, md.digest("Hello world!".getBytes())); } public void testSHA1WithRSAViaConfig() throws Exception { List certList = new ArrayList(); CMSTypedData msg = new CMSProcessableByteArray("Hello world!".getBytes()); certList.add(_origCert); certList.add(_signCert); Store certs = new JcaCertStore(certList); // set some bogus mappings. TestCMSSignatureAlgorithmNameGenerator sigAlgNameGen = new TestCMSSignatureAlgorithmNameGenerator(); sigAlgNameGen.setEncryptionAlgorithmMapping(PKCSObjectIdentifiers.rsaEncryption, "XXXX"); sigAlgNameGen.setDigestAlgorithmMapping(OIWObjectIdentifiers.idSHA1, "YYYY"); CMSSignedDataGenerator gen = new CMSSignedDataGenerator(); ContentSigner sha1Signer = new JcaContentSignerBuilder("SHA1withRSA").setProvider(BC).build(_origKP.getPrivate()); gen.addSignerInfoGenerator(new JcaSignerInfoGeneratorBuilder(new JcaDigestCalculatorProviderBuilder().setProvider(BC).build()).build(sha1Signer, _origCert)); gen.addCertificates(certs); CMSSignedData s; try { // try the bogus mappings s = gen.generate(msg, false); } catch (CMSException e) { if (!e.getMessage().startsWith("no such algorithm: YYYYwithXXXX")) { throw e; } } finally { // reset to the real ones sigAlgNameGen.setEncryptionAlgorithmMapping(PKCSObjectIdentifiers.rsaEncryption, "RSA"); sigAlgNameGen.setDigestAlgorithmMapping(OIWObjectIdentifiers.idSHA1, "SHA1"); } s = gen.generate(msg, false); // // compute expected content digest // MessageDigest md = MessageDigest.getInstance("SHA1", BC); verifySignatures(s, md.digest("Hello world!".getBytes())); } public void testSHA1WithRSAAndAttributeTableSimple() throws Exception { MessageDigest md = MessageDigest.getInstance("SHA1", BC); List certList = new ArrayList(); CMSTypedData msg = new CMSProcessableByteArray("Hello world!".getBytes()); certList.add(_origCert); certList.add(_signCert); Store certs = new JcaCertStore(certList); CMSSignedDataGenerator gen = new CMSSignedDataGenerator(); Attribute attr = new Attribute(CMSAttributes.messageDigest, new DERSet( new DEROctetString( md.digest("Hello world!".getBytes())))); ASN1EncodableVector v = new ASN1EncodableVector(); v.add(attr); SignerInfoGeneratorBuilder builder = new SignerInfoGeneratorBuilder(new BcDigestCalculatorProvider()).setSignedAttributeGenerator(new DefaultSignedAttributeTableGenerator(new AttributeTable(v))); AlgorithmIdentifier sha1withRSA = new DefaultSignatureAlgorithmIdentifierFinder().find("SHA1withRSA"); gen.addSignerInfoGenerator(builder.build(new BcRSAContentSignerBuilder(sha1withRSA, new DefaultDigestAlgorithmIdentifierFinder().find(sha1withRSA)).build(PrivateKeyFactory.createKey(_origKP.getPrivate().getEncoded())), new JcaX509CertificateHolder(_origCert))); gen.addCertificates(certs); CMSSignedData s = gen.generate(new CMSAbsentContent(), false); // // the signature is detached, so need to add msg before passing on // s = new CMSSignedData(msg, s.getEncoded()); // // compute expected content digest // verifySignatures(s, md.digest("Hello world!".getBytes())); verifyRSASignatures(s, md.digest("Hello world!".getBytes())); } public void testSHA1WithRSAAndAttributeTable() throws Exception { MessageDigest md = MessageDigest.getInstance("SHA1", BC); List certList = new ArrayList(); CMSTypedData msg = new CMSProcessableByteArray("Hello world!".getBytes()); certList.add(_origCert); certList.add(_signCert); Store certs = new JcaCertStore(certList); CMSSignedDataGenerator gen = new CMSSignedDataGenerator(); Attribute attr = new Attribute(CMSAttributes.messageDigest, new DERSet( new DEROctetString( md.digest("Hello world!".getBytes())))); ASN1EncodableVector v = new ASN1EncodableVector(); v.add(attr); JcaSignerInfoGeneratorBuilder builder = new JcaSignerInfoGeneratorBuilder(new JcaDigestCalculatorProviderBuilder().setProvider(BC).build()); builder.setSignedAttributeGenerator(new DefaultSignedAttributeTableGenerator(new AttributeTable(v))); ContentSigner sha1Signer = new JcaContentSignerBuilder("SHA1withRSA").setProvider(BC).build(_origKP.getPrivate()); gen.addSignerInfoGenerator(builder.build(sha1Signer, _origCert)); gen.addCertificates(certs); CMSSignedData s = gen.generate(new CMSAbsentContent(), false); // // the signature is detached, so need to add msg before passing on // s = new CMSSignedData(msg, s.getEncoded()); // // compute expected content digest // verifySignatures(s, md.digest("Hello world!".getBytes())); verifyRSASignatures(s, md.digest("Hello world!".getBytes())); } public void testLwSHA1WithRSAAndAttributeTable() throws Exception { MessageDigest md = MessageDigest.getInstance("SHA1", BC); List certList = new ArrayList(); CMSTypedData msg = new CMSProcessableByteArray("Hello world!".getBytes()); certList.add(_origCert); certList.add(_signCert); Store certs = new JcaCertStore(certList); CMSSignedDataGenerator gen = new CMSSignedDataGenerator(); Attribute attr = new Attribute(CMSAttributes.messageDigest, new DERSet( new DEROctetString( md.digest("Hello world!".getBytes())))); ASN1EncodableVector v = new ASN1EncodableVector(); v.add(attr); AsymmetricKeyParameter privKey = PrivateKeyFactory.createKey(_origKP.getPrivate().getEncoded()); AlgorithmIdentifier sigAlgId = new DefaultSignatureAlgorithmIdentifierFinder().find("SHA1withRSA"); AlgorithmIdentifier digAlgId = new DefaultDigestAlgorithmIdentifierFinder().find(sigAlgId); BcContentSignerBuilder contentSignerBuilder = new BcRSAContentSignerBuilder(sigAlgId, digAlgId); gen.addSignerInfoGenerator( new SignerInfoGeneratorBuilder(new BcDigestCalculatorProvider()) .setSignedAttributeGenerator(new DefaultSignedAttributeTableGenerator(new AttributeTable(v))) .build(contentSignerBuilder.build(privKey), new JcaX509CertificateHolder(_origCert))); gen.addCertificates(certs); CMSSignedData s = gen.generate(new CMSAbsentContent(), false); // // the signature is detached, so need to add msg before passing on // s = new CMSSignedData(msg, s.getEncoded()); // // compute expected content digest // verifySignatures(s, md.digest("Hello world!".getBytes())); verifyRSASignatures(s, md.digest("Hello world!".getBytes())); } public void testSHA1WithRSAEncapsulated() throws Exception { encapsulatedTest(_signKP, _signCert, "SHA1withRSA"); } public void testSHA1WithRSAEncapsulatedSubjectKeyID() throws Exception { subjectKeyIDTest(_signKP, _signCert, "SHA1withRSA"); } public void testSHA1WithRSAPSS() throws Exception { rsaPSSTest("SHA1withRSAandMGF1"); } public void testSHA224WithRSAPSS() throws Exception { rsaPSSTest("SHA224withRSAandMGF1"); } public void testSHA256WithRSAPSS() throws Exception { rsaPSSTest("SHA256withRSAandMGF1"); } public void testSHA384WithRSAPSS() throws Exception { rsaPSSTest("SHA384withRSAandMGF1"); } public void testSHA224WithRSAEncapsulated() throws Exception { encapsulatedTest(_signKP, _signCert, "SHA224withRSA"); } public void testSHA256WithRSAEncapsulated() throws Exception { encapsulatedTest(_signKP, _signCert, "SHA256withRSA"); } public void testRIPEMD128WithRSAEncapsulated() throws Exception { encapsulatedTest(_signKP, _signCert, "RIPEMD128withRSA"); } public void testRIPEMD160WithRSAEncapsulated() throws Exception { encapsulatedTest(_signKP, _signCert, "RIPEMD160withRSA"); } public void testRIPEMD256WithRSAEncapsulated() throws Exception { encapsulatedTest(_signKP, _signCert, "RIPEMD256withRSA"); } public void testECDSAEncapsulated() throws Exception { encapsulatedTest(_signEcDsaKP, _signEcDsaCert, "SHA1withECDSA"); } public void testECDSAEncapsulatedSubjectKeyID() throws Exception { subjectKeyIDTest(_signEcDsaKP, _signEcDsaCert, "SHA1withECDSA"); } public void testECDSASHA224Encapsulated() throws Exception { encapsulatedTest(_signEcDsaKP, _signEcDsaCert, "SHA224withECDSA"); } public void testECDSASHA256Encapsulated() throws Exception { encapsulatedTest(_signEcDsaKP, _signEcDsaCert, "SHA256withECDSA"); } public void testECDSASHA384Encapsulated() throws Exception { encapsulatedTest(_signEcDsaKP, _signEcDsaCert, "SHA384withECDSA"); } public void testECDSASHA512Encapsulated() throws Exception { encapsulatedTest(_signEcDsaKP, _signEcDsaCert, "SHA512withECDSA"); } public void testECDSASHA512EncapsulatedWithKeyFactoryAsEC() throws Exception { X509EncodedKeySpec pubSpec = new X509EncodedKeySpec(_signEcDsaKP.getPublic().getEncoded()); PKCS8EncodedKeySpec privSpec = new PKCS8EncodedKeySpec(_signEcDsaKP.getPrivate().getEncoded()); KeyFactory keyFact = KeyFactory.getInstance("EC", BC); KeyPair kp = new KeyPair(keyFact.generatePublic(pubSpec), keyFact.generatePrivate(privSpec)); encapsulatedTest(kp, _signEcDsaCert, "SHA512withECDSA"); } public void testDSAEncapsulated() throws Exception { encapsulatedTest(_signDsaKP, _signDsaCert, "SHA1withDSA"); } public void testDSAEncapsulatedSubjectKeyID() throws Exception { subjectKeyIDTest(_signDsaKP, _signDsaCert, "SHA1withDSA"); } public void testSHA1WithRSACounterSignature() throws Exception { List certList = new ArrayList(); List crlList = new ArrayList(); CMSTypedData msg = new CMSProcessableByteArray("Hello World!".getBytes()); certList.add(_signCert); certList.add(_origCert); crlList.add(_signCrl); Store certStore = new JcaCertStore(certList); Store crlStore = new JcaCRLStore(crlList); CMSSignedDataGenerator gen = new CMSSignedDataGenerator(); ContentSigner sha1Signer = new JcaContentSignerBuilder("SHA1withRSA").setProvider(BC).build(_signKP.getPrivate()); gen.addSignerInfoGenerator(new JcaSignerInfoGeneratorBuilder(new JcaDigestCalculatorProviderBuilder().setProvider(BC).build()).build(sha1Signer, _signCert)); gen.addCertificates(certStore); gen.addCRLs(crlStore); CMSSignedData s = gen.generate(msg, true); SignerInformation origSigner = (SignerInformation)s.getSignerInfos().getSigners().toArray()[0]; SignerInformationStore counterSigners1 = gen.generateCounterSigners(origSigner); SignerInformationStore counterSigners2 = gen.generateCounterSigners(origSigner); SignerInformation signer1 = SignerInformation.addCounterSigners(origSigner, counterSigners1); SignerInformation signer2 = SignerInformation.addCounterSigners(signer1, counterSigners2); SignerInformationStore cs = signer2.getCounterSignatures(); Collection csSigners = cs.getSigners(); assertEquals(2, csSigners.size()); Iterator it = csSigners.iterator(); while (it.hasNext()) { SignerInformation cSigner = (SignerInformation)it.next(); Collection certCollection = certStore.getMatches(cSigner.getSID()); Iterator certIt = certCollection.iterator(); X509CertificateHolder cert = (X509CertificateHolder)certIt.next(); assertTrue(cSigner.isCounterSignature()); assertNull(cSigner.getSignedAttributes().get(PKCSObjectIdentifiers.pkcs_9_at_contentType)); assertEquals(true, cSigner.verify(new JcaSimpleSignerInfoVerifierBuilder().setProvider(BC).build(cert))); } } private void rsaPSSTest(String signatureAlgorithmName) throws Exception { List certList = new ArrayList(); CMSTypedData msg = new CMSProcessableByteArray("Hello world!".getBytes()); certList.add(_origCert); certList.add(_signCert); Store certs = new JcaCertStore(certList); CMSSignedDataGenerator gen = new CMSSignedDataGenerator(); ContentSigner contentSigner = new JcaContentSignerBuilder(signatureAlgorithmName).setProvider(BC).build(_origKP.getPrivate()); JcaSignerInfoGeneratorBuilder siBuilder = new JcaSignerInfoGeneratorBuilder(new JcaDigestCalculatorProviderBuilder().setProvider(BC).build()); siBuilder.setDirectSignature(true); gen.addSignerInfoGenerator(siBuilder.build(contentSigner, _origCert)); gen.addCertificates(certs); CMSSignedData s = gen.generate(msg, false); // // compute expected content digest // String digestName = signatureAlgorithmName.substring(0, signatureAlgorithmName.indexOf('w')); MessageDigest md = MessageDigest.getInstance(digestName, BC); verifySignatures(s, md.digest("Hello world!".getBytes())); } private void subjectKeyIDTest( KeyPair signaturePair, X509Certificate signatureCert, String signatureAlgorithm) throws Exception { List certList = new ArrayList(); List crlList = new ArrayList(); CMSTypedData msg = new CMSProcessableByteArray("Hello World!".getBytes()); certList.add(signatureCert); certList.add(_origCert); crlList.add(_signCrl); Store certStore = new JcaCertStore(certList); Store crlStore = new JcaCRLStore(crlList); CMSSignedDataGenerator gen = new CMSSignedDataGenerator(); ContentSigner contentSigner = new JcaContentSignerBuilder(signatureAlgorithm).setProvider(BC).build(signaturePair.getPrivate()); gen.addSignerInfoGenerator(new JcaSignerInfoGeneratorBuilder(new JcaDigestCalculatorProviderBuilder().setProvider(BC).build()).build(contentSigner, CMSTestUtil.createSubjectKeyId(signatureCert.getPublicKey()).getKeyIdentifier())); gen.addCertificates(certStore); gen.addCRLs(crlStore); CMSSignedData s = gen.generate(msg, true); assertEquals(3, s.getVersion()); ByteArrayInputStream bIn = new ByteArrayInputStream(s.getEncoded()); ASN1InputStream aIn = new ASN1InputStream(bIn); s = new CMSSignedData(ContentInfo.getInstance(aIn.readObject())); certStore = s.getCertificates(); SignerInformationStore signers = s.getSignerInfos(); Collection c = signers.getSigners(); Iterator it = c.iterator(); while (it.hasNext()) { SignerInformation signer = (SignerInformation)it.next(); Collection certCollection = certStore.getMatches(signer.getSID()); Iterator certIt = certCollection.iterator(); X509CertificateHolder cert = (X509CertificateHolder)certIt.next(); assertEquals(true, signer.verify(new JcaSimpleSignerInfoVerifierBuilder().setProvider(BC).build(cert))); } // // check for CRLs // Collection crls = crlStore.getMatches(null); assertEquals(1, crls.size()); assertTrue(crls.contains(new JcaX509CRLHolder(_signCrl))); // // try using existing signer // gen = new CMSSignedDataGenerator(); gen.addSigners(s.getSignerInfos()); gen.addCertificates(s.getCertificates()); s = gen.generate(msg, true); bIn = new ByteArrayInputStream(s.getEncoded()); aIn = new ASN1InputStream(bIn); s = new CMSSignedData(ContentInfo.getInstance(aIn.readObject())); certStore = s.getCertificates(); signers = s.getSignerInfos(); c = signers.getSigners(); it = c.iterator(); while (it.hasNext()) { SignerInformation signer = (SignerInformation)it.next(); Collection certCollection = certStore.getMatches(signer.getSID()); Iterator certIt = certCollection.iterator(); X509CertificateHolder cert = (X509CertificateHolder)certIt.next(); assertEquals(true, signer.verify(new JcaSimpleSignerInfoVerifierBuilder().setProvider(BC).build(cert))); } checkSignerStoreReplacement(s, signers); } private void encapsulatedTest( KeyPair signaturePair, X509Certificate signatureCert, String signatureAlgorithm) throws Exception { ConfigurableProvider provider = (ConfigurableProvider)Security.getProvider(BC); if (!provider.hasAlgorithm("Signature", signatureAlgorithm)) { return; } List certList = new ArrayList(); List crlList = new ArrayList(); CMSTypedData msg = new CMSProcessableByteArray("Hello World!".getBytes()); certList.add(signatureCert); certList.add(_origCert); crlList.add(_signCrl); Store certs = new JcaCertStore(certList); Store crlStore = new JcaCRLStore(crlList); CMSSignedDataGenerator gen = new CMSSignedDataGenerator(); ContentSigner contentSigner = new JcaContentSignerBuilder(signatureAlgorithm).setProvider(BC).build(signaturePair.getPrivate()); gen.addSignerInfoGenerator(new JcaSignerInfoGeneratorBuilder(new JcaDigestCalculatorProviderBuilder().setProvider(BC).build()).build(contentSigner, signatureCert)); gen.addCertificates(certs); CMSSignedData s = gen.generate(msg, true); ByteArrayInputStream bIn = new ByteArrayInputStream(s.getEncoded()); ASN1InputStream aIn = new ASN1InputStream(bIn); s = new CMSSignedData(ContentInfo.getInstance(aIn.readObject())); certs = s.getCertificates(); SignerInformationStore signers = s.getSignerInfos(); Collection c = signers.getSigners(); Iterator it = c.iterator(); while (it.hasNext()) { SignerInformation signer = (SignerInformation)it.next(); Collection certCollection = certs.getMatches(signer.getSID()); Iterator certIt = certCollection.iterator(); X509CertificateHolder cert = (X509CertificateHolder)certIt.next(); assertEquals(true, signer.verify(new JcaSimpleSignerInfoVerifierBuilder().setProvider(BC).build(cert))); } // // check for CRLs // Collection crls = crlStore.getMatches(null); assertEquals(1, crls.size()); assertTrue(crls.contains(new JcaX509CRLHolder(_signCrl))); // // try using existing signer // gen = new CMSSignedDataGenerator(); gen.addSigners(s.getSignerInfos()); gen.addCertificates(s.getCertificates()); s = gen.generate(msg, true); bIn = new ByteArrayInputStream(s.getEncoded()); aIn = new ASN1InputStream(bIn); s = new CMSSignedData(ContentInfo.getInstance(aIn.readObject())); certs = s.getCertificates(); signers = s.getSignerInfos(); c = signers.getSigners(); it = c.iterator(); while (it.hasNext()) { SignerInformation signer = (SignerInformation)it.next(); Collection certCollection = certs.getMatches(signer.getSID()); Iterator certIt = certCollection.iterator(); X509CertificateHolder cert = (X509CertificateHolder)certIt.next(); assertEquals(true, signer.verify(new JcaSimpleSignerInfoVerifierBuilder().setProvider(BC).build(cert))); } checkSignerStoreReplacement(s, signers); } // // signerInformation store replacement test. // private void checkSignerStoreReplacement( CMSSignedData orig, SignerInformationStore signers) throws Exception { CMSSignedData s = CMSSignedData.replaceSigners(orig, signers); Store certs = s.getCertificates(); signers = s.getSignerInfos(); Collection c = signers.getSigners(); Iterator it = c.iterator(); while (it.hasNext()) { SignerInformation signer = (SignerInformation)it.next(); Collection certCollection = certs.getMatches(signer.getSID()); Iterator certIt = certCollection.iterator(); X509CertificateHolder cert = (X509CertificateHolder)certIt.next(); assertEquals(true, signer.verify(new JcaSimpleSignerInfoVerifierBuilder().setProvider(BC).build(cert))); } } public void testUnsortedAttributes() throws Exception { CMSSignedData s = new CMSSignedData(new CMSProcessableByteArray(disorderedMessage), disorderedSet); Store certs = s.getCertificates(); SignerInformationStore signers = s.getSignerInfos(); Collection c = signers.getSigners(); Iterator it = c.iterator(); while (it.hasNext()) { SignerInformation signer = (SignerInformation)it.next(); Collection certCollection = certs.getMatches(signer.getSID()); Iterator certIt = certCollection.iterator(); X509CertificateHolder cert = (X509CertificateHolder)certIt.next(); assertEquals(true, signer.verify(new JcaSimpleSignerInfoVerifierBuilder().setProvider(BC).build(cert))); } } public void testNullContentWithSigner() throws Exception { List certList = new ArrayList(); certList.add(_origCert); certList.add(_signCert); Store certs = new JcaCertStore(certList); CMSSignedDataGenerator gen = new CMSSignedDataGenerator(); ContentSigner sha1Signer = new JcaContentSignerBuilder("SHA1withRSA").setProvider(BC).build(_origKP.getPrivate()); gen.addSignerInfoGenerator(new JcaSignerInfoGeneratorBuilder(new JcaDigestCalculatorProviderBuilder().setProvider(BC).build()).build(sha1Signer, _origCert)); gen.addCertificates(certs); CMSSignedData s = gen.generate(new CMSAbsentContent(), false); ByteArrayInputStream bIn = new ByteArrayInputStream(s.getEncoded()); ASN1InputStream aIn = new ASN1InputStream(bIn); s = new CMSSignedData(ContentInfo.getInstance(aIn.readObject())); verifySignatures(s); } public void testWithAttributeCertificate() throws Exception { List certList = new ArrayList(); CMSTypedData msg = new CMSProcessableByteArray("Hello World!".getBytes()); certList.add(_signDsaCert); Store certs = new JcaCertStore(certList); CMSSignedDataGenerator gen = new CMSSignedDataGenerator(); JcaSignerInfoGeneratorBuilder builder = new JcaSignerInfoGeneratorBuilder(new JcaDigestCalculatorProviderBuilder().setProvider(BC).build()); ContentSigner sha1Signer = new JcaContentSignerBuilder("SHA1withRSA").setProvider(BC).build(_origKP.getPrivate()); gen.addSignerInfoGenerator(builder.build(sha1Signer, _origCert)); gen.addCertificates(certs); X509AttributeCertificateHolder attrCert = new X509AttributeCertificateHolder(CMSTestUtil.getAttributeCertificate().getEncoded()); List attrList = new ArrayList(); attrList.add(new X509AttributeCertificateHolder(attrCert.getEncoded())); Store store = new CollectionStore(attrList); gen.addAttributeCertificates(store); CMSSignedData sd = gen.generate(msg); assertEquals(4, sd.getVersion()); store = sd.getAttributeCertificates(); Collection coll = store.getMatches(null); assertEquals(1, coll.size()); assertTrue(coll.contains(new X509AttributeCertificateHolder(attrCert.getEncoded()))); // // create new certstore // certList = new ArrayList(); certList.add(_origCert); certList.add(_signCert); certs = new JcaCertStore(certList); // // replace certs // sd = CMSSignedData.replaceCertificatesAndCRLs(sd, certs, null, null); verifySignatures(sd); } public void testCertStoreReplacement() throws Exception { List certList = new ArrayList(); CMSTypedData msg = new CMSProcessableByteArray("Hello World!".getBytes()); certList.add(_signDsaCert); Store certs = new JcaCertStore(certList); CMSSignedDataGenerator gen = new CMSSignedDataGenerator(); ContentSigner sha1Signer = new JcaContentSignerBuilder("SHA1withRSA").setProvider(BC).build(_origKP.getPrivate()); gen.addSignerInfoGenerator(new JcaSignerInfoGeneratorBuilder(new JcaDigestCalculatorProviderBuilder().setProvider(BC).build()).build(sha1Signer, _origCert)); gen.addCertificates(certs); CMSSignedData sd = gen.generate(msg); // // create new certstore // certList = new ArrayList(); certList.add(_origCert); certList.add(_signCert); certs = new JcaCertStore(certList); // // replace certs // sd = CMSSignedData.replaceCertificatesAndCRLs(sd, certs, null, null); verifySignatures(sd); } public void testEncapsulatedCertStoreReplacement() throws Exception { List certList = new ArrayList(); CMSTypedData msg = new CMSProcessableByteArray("Hello World!".getBytes()); certList.add(_signDsaCert); Store certs = new JcaCertStore(certList); CMSSignedDataGenerator gen = new CMSSignedDataGenerator(); ContentSigner sha1Signer = new JcaContentSignerBuilder("SHA1withRSA").setProvider(BC).build(_origKP.getPrivate()); gen.addSignerInfoGenerator(new JcaSignerInfoGeneratorBuilder(new JcaDigestCalculatorProviderBuilder().setProvider(BC).build()).build(sha1Signer, _origCert)); gen.addCertificates(certs); CMSSignedData sd = gen.generate(msg, true); // // create new certstore // certList = new ArrayList(); certList.add(_origCert); certList.add(_signCert); certs = new JcaCertStore(certList); // // replace certs // sd = CMSSignedData.replaceCertificatesAndCRLs(sd, certs, null, null); verifySignatures(sd); } public void testCertOrdering1() throws Exception { List certList = new ArrayList(); CMSTypedData msg = new CMSProcessableByteArray("Hello World!".getBytes()); certList.add(_origCert); certList.add(_signCert); certList.add(_signDsaCert); Store certs = new JcaCertStore(certList); CMSSignedDataGenerator gen = new CMSSignedDataGenerator(); ContentSigner sha1Signer = new JcaContentSignerBuilder("SHA1withRSA").setProvider(BC).build(_origKP.getPrivate()); gen.addSignerInfoGenerator(new JcaSignerInfoGeneratorBuilder(new JcaDigestCalculatorProviderBuilder().setProvider(BC).build()).build(sha1Signer, _origCert)); gen.addCertificates(certs); CMSSignedData sd = gen.generate(msg, true); certs = sd.getCertificates(); Iterator it = certs.getMatches(null).iterator(); assertEquals(new JcaX509CertificateHolder(_origCert), it.next()); assertEquals(new JcaX509CertificateHolder(_signCert), it.next()); assertEquals(new JcaX509CertificateHolder(_signDsaCert), it.next()); } public void testCertOrdering2() throws Exception { List certList = new ArrayList(); CMSTypedData msg = new CMSProcessableByteArray("Hello World!".getBytes()); certList.add(_signCert); certList.add(_signDsaCert); certList.add(_origCert); Store certs = new JcaCertStore(certList); CMSSignedDataGenerator gen = new CMSSignedDataGenerator(); ContentSigner sha1Signer = new JcaContentSignerBuilder("SHA1withRSA").setProvider(BC).build(_origKP.getPrivate()); gen.addSignerInfoGenerator(new JcaSignerInfoGeneratorBuilder(new JcaDigestCalculatorProviderBuilder().setProvider(BC).build()).build(sha1Signer, _origCert)); gen.addCertificates(certs); CMSSignedData sd = gen.generate(msg, true); certs = sd.getCertificates(); Iterator it = certs.getMatches(null).iterator(); assertEquals(new JcaX509CertificateHolder(_signCert), it.next()); assertEquals(new JcaX509CertificateHolder(_signDsaCert), it.next()); assertEquals(new JcaX509CertificateHolder(_origCert), it.next()); } public void testSignerStoreReplacement() throws Exception { List certList = new ArrayList(); CMSTypedData msg = new CMSProcessableByteArray("Hello World!".getBytes()); certList.add(_origCert); certList.add(_signCert); Store certs = new JcaCertStore(certList); CMSSignedDataGenerator gen = new CMSSignedDataGenerator(); ContentSigner sha1Signer = new JcaContentSignerBuilder("SHA1withRSA").setProvider(BC).build(_origKP.getPrivate()); gen.addSignerInfoGenerator(new JcaSignerInfoGeneratorBuilder(new JcaDigestCalculatorProviderBuilder().setProvider(BC).build()).build(sha1Signer, _origCert)); gen.addCertificates(certs); CMSSignedData original = gen.generate(msg, true); // // create new Signer // gen = new CMSSignedDataGenerator(); ContentSigner sha224Signer = new JcaContentSignerBuilder("SHA224withRSA").setProvider(BC).build(_origKP.getPrivate()); gen.addSignerInfoGenerator(new JcaSignerInfoGeneratorBuilder(new JcaDigestCalculatorProviderBuilder().setProvider(BC).build()).build(sha224Signer, _origCert)); gen.addCertificates(certs); CMSSignedData newSD = gen.generate(msg, true); // // replace signer // CMSSignedData sd = CMSSignedData.replaceSigners(original, newSD.getSignerInfos()); SignerInformation signer = (SignerInformation)sd.getSignerInfos().getSigners().iterator().next(); assertEquals(CMSAlgorithm.SHA224.getId(), signer.getDigestAlgOID()); // we use a parser here as it requires the digests to be correct in the digest set, if it // isn't we'll get a NullPointerException CMSSignedDataParser sp = new CMSSignedDataParser(new JcaDigestCalculatorProviderBuilder().setProvider(BC).build(), sd.getEncoded()); sp.getSignedContent().drain(); verifySignatures(sp); } public void testEncapsulatedSamples() throws Exception { testSample("PSSSignDataSHA1Enc.sig"); testSample("PSSSignDataSHA256Enc.sig"); testSample("PSSSignDataSHA512Enc.sig"); } public void testSamples() throws Exception { testSample("PSSSignData.data", "PSSSignDataSHA1.sig"); testSample("PSSSignData.data", "PSSSignDataSHA256.sig"); testSample("PSSSignData.data", "PSSSignDataSHA512.sig"); } public void testCounterSig() throws Exception { CMSSignedData sig = new CMSSignedData(getInput("counterSig.p7m")); SignerInformationStore ss = sig.getSignerInfos(); Collection signers = ss.getSigners(); SignerInformationStore cs = ((SignerInformation)signers.iterator().next()).getCounterSignatures(); Collection csSigners = cs.getSigners(); assertEquals(1, csSigners.size()); Iterator it = csSigners.iterator(); while (it.hasNext()) { SignerInformation cSigner = (SignerInformation)it.next(); Collection certCollection = sig.getCertificates().getMatches(cSigner.getSID()); Iterator certIt = certCollection.iterator(); X509CertificateHolder cert = (X509CertificateHolder)certIt.next(); assertTrue(cSigner.isCounterSignature()); assertNull(cSigner.getSignedAttributes().get(PKCSObjectIdentifiers.pkcs_9_at_contentType)); assertEquals(true, cSigner.verify(new JcaSimpleSignerInfoVerifierBuilder().setProvider(BC).build(cert))); } verifySignatures(sig); } private void testSample(String sigName) throws Exception { CMSSignedData sig = new CMSSignedData(getInput(sigName)); verifySignatures(sig); } private void testSample(String messageName, String sigName) throws Exception { CMSSignedData sig = new CMSSignedData(new CMSProcessableByteArray(getInput(messageName)), getInput(sigName)); verifySignatures(sig); } private byte[] getInput(String name) throws IOException { return Streams.readAll(getClass().getResourceAsStream(name)); } public void testForMultipleCounterSignatures() throws Exception { CMSSignedData sd = new CMSSignedData(xtraCounterSig); for (Iterator sI = sd.getSignerInfos().getSigners().iterator(); sI.hasNext();) { SignerInformation sigI = (SignerInformation)sI.next(); SignerInformationStore counter = sigI.getCounterSignatures(); List sigs = new ArrayList(counter.getSigners()); assertEquals(2, sigs.size()); } } private void verifySignatures(CMSSignedDataParser sp) throws Exception { Store certs = sp.getCertificates(); SignerInformationStore signers = sp.getSignerInfos(); Collection c = signers.getSigners(); Iterator it = c.iterator(); while (it.hasNext()) { SignerInformation signer = (SignerInformation)it.next(); Collection certCollection = certs.getMatches(signer.getSID()); Iterator certIt = certCollection.iterator(); X509CertificateHolder cert = (X509CertificateHolder)certIt.next(); assertEquals(true, signer.verify(new JcaSimpleSignerInfoVerifierBuilder().setProvider(BC).build(cert))); } } private class TestCMSSignatureAlgorithmNameGenerator extends DefaultCMSSignatureAlgorithmNameGenerator { void setDigestAlgorithmMapping(ASN1ObjectIdentifier oid, String algName) { super.setSigningDigestAlgorithmMapping(oid, algName); } void setEncryptionAlgorithmMapping(ASN1ObjectIdentifier oid, String algName) { super.setSigningEncryptionAlgorithmMapping(oid, algName); } } } bouncycastle-1.49.orig/test/src/org/bouncycastle/cms/test/EnvelopedDataTest.java0000644000175000017500000010647611507246212027456 0ustar ebourgebourgpackage org.bouncycastle.cms.test; import java.io.IOException; import java.security.GeneralSecurityException; import java.security.Key; import java.security.KeyFactory; import java.security.KeyPair; import java.security.NoSuchAlgorithmException; import java.security.NoSuchProviderException; import java.security.PrivateKey; import java.security.Security; import java.security.cert.CertificateEncodingException; import java.security.cert.X509Certificate; import java.security.spec.PKCS8EncodedKeySpec; import java.util.ArrayList; import java.util.Arrays; import java.util.Collection; import java.util.Iterator; import javax.crypto.SecretKey; import javax.crypto.spec.SecretKeySpec; import junit.framework.Test; import junit.framework.TestCase; import junit.framework.TestSuite; import org.bouncycastle.asn1.ASN1InputStream; import org.bouncycastle.asn1.ASN1Sequence; import org.bouncycastle.asn1.DERObjectIdentifier; import org.bouncycastle.asn1.DEROctetString; import org.bouncycastle.asn1.kisa.KISAObjectIdentifiers; import org.bouncycastle.asn1.nist.NISTObjectIdentifiers; import org.bouncycastle.asn1.ntt.NTTObjectIdentifiers; import org.bouncycastle.asn1.pkcs.PKCSObjectIdentifiers; import org.bouncycastle.cms.CMSEnvelopedData; import org.bouncycastle.cms.CMSEnvelopedDataGenerator; import org.bouncycastle.cms.CMSException; import org.bouncycastle.cms.CMSPBEKey; import org.bouncycastle.cms.CMSProcessableByteArray; import org.bouncycastle.cms.KeyTransRecipientInformation; import org.bouncycastle.cms.PKCS5Scheme2PBEKey; import org.bouncycastle.cms.PKCS5Scheme2UTF8PBEKey; import org.bouncycastle.cms.PasswordRecipientInformation; import org.bouncycastle.cms.RecipientId; import org.bouncycastle.cms.RecipientInformation; import org.bouncycastle.cms.RecipientInformationStore; import org.bouncycastle.cms.jcajce.JceKeyAgreeRecipientId; import org.bouncycastle.jce.provider.BouncyCastleProvider; import org.bouncycastle.util.encoders.Base64; import org.bouncycastle.util.encoders.Hex; public class EnvelopedDataTest extends TestCase { private static final String BC = BouncyCastleProvider.PROVIDER_NAME; private static String _signDN; private static KeyPair _signKP; private static X509Certificate _signCert; private static String _origDN; private static KeyPair _origKP; private static X509Certificate _origCert; private static String _reciDN; private static String _reciDN2; private static KeyPair _reciKP; private static X509Certificate _reciCert; private static KeyPair _origEcKP; private static KeyPair _reciEcKP; private static X509Certificate _reciEcCert; private static KeyPair _reciEcKP2; private static X509Certificate _reciEcCert2; private static boolean _initialised = false; private byte[] oldKEK = Base64.decode( "MIAGCSqGSIb3DQEHA6CAMIACAQIxQaI/MD0CAQQwBwQFAQIDBAUwDQYJYIZIAWUDBAEFBQAEI" + "Fi2eHTPM4bQSjP4DUeDzJZLpfemW2gF1SPq7ZPHJi1mMIAGCSqGSIb3DQEHATAUBggqhkiG9w" + "0DBwQImtdGyUdGGt6ggAQYk9X9z01YFBkU7IlS3wmsKpm/zpZClTceAAAAAAAAAAAAAA=="); private byte[] ecKeyAgreeMsgAES256 = Base64.decode( "MIAGCSqGSIb3DQEHA6CAMIACAQIxgcShgcECAQOgQ6FBMAsGByqGSM49AgEF" + "AAMyAAPdXlSTpub+qqno9hUGkUDl+S3/ABhPziIB5yGU4678tgOgU5CiKG9Z" + "kfnabIJ3nZYwGgYJK4EFEIZIPwACMA0GCWCGSAFlAwQBLQUAMFswWTAtMCgx" + "EzARBgNVBAMTCkFkbWluLU1EU0UxETAPBgNVBAoTCDRCQ1QtMklEAgEBBCi/" + "rJRLbFwEVW6PcLLmojjW9lI/xGD7CfZzXrqXFw8iHaf3hTRau1gYMIAGCSqG" + "SIb3DQEHATAdBglghkgBZQMEASoEEMtCnKKPwccmyrbgeSIlA3qggAQQDLw8" + "pNJR97bPpj6baG99bQQQwhEDsoj5Xg1oOxojHVcYzAAAAAAAAAAAAAA="); private byte[] ecKeyAgreeMsgAES128 = Base64.decode( "MIAGCSqGSIb3DQEHA6CAMIACAQIxgbShgbECAQOgQ6FBMAsGByqGSM49AgEF" + "AAMyAAL01JLEgKvKh5rbxI/hOxs/9WEezMIsAbUaZM4l5tn3CzXAN505nr5d" + "LhrcurMK+tAwGgYJK4EFEIZIPwACMA0GCWCGSAFlAwQBBQUAMEswSTAtMCgx" + "EzARBgNVBAMTCkFkbWluLU1EU0UxETAPBgNVBAoTCDRCQ1QtMklEAgEBBBhi" + "FLjc5g6aqDT3f8LomljOwl1WTrplUT8wgAYJKoZIhvcNAQcBMB0GCWCGSAFl" + "AwQBAgQQzXjms16Y69S/rB0EbHqRMaCABBAFmc/QdVW6LTKdEy97kaZzBBBa" + "fQuviUS03NycpojELx0bAAAAAAAAAAAAAA=="); private byte[] ecKeyAgreeMsgDESEDE = Base64.decode( "MIAGCSqGSIb3DQEHA6CAMIACAQIxgcahgcMCAQOgQ6FBMAsGByqGSM49AgEF" + "AAMyAALIici6Nx1WN5f0ThH2A8ht9ovm0thpC5JK54t73E1RDzCifePaoQo0" + "xd6sUqoyGaYwHAYJK4EFEIZIPwACMA8GCyqGSIb3DQEJEAMGBQAwWzBZMC0w" + "KDETMBEGA1UEAxMKQWRtaW4tTURTRTERMA8GA1UEChMINEJDVC0ySUQCAQEE" + "KJuqZQ1NB1vXrKPOnb4TCpYOsdm6GscWdwAAZlm2EHMp444j0s55J9wwgAYJ" + "KoZIhvcNAQcBMBQGCCqGSIb3DQMHBAjwnsDMsafCrKCABBjyPvqFOVMKxxut" + "VfTx4fQlNGJN8S2ATRgECMcTQ/dsmeViAAAAAAAAAAAAAA=="); private byte[] ecMQVKeyAgreeMsgAES128 = Base64.decode( "MIAGCSqGSIb3DQEHA6CAMIACAQIxgf2hgfoCAQOgQ6FBMAsGByqGSM49AgEF" + "AAMyAAPDKU+0H58tsjpoYmYCInMr/FayvCCkupebgsnpaGEB7qS9vzcNVUj6" + "mrnmiC2grpmhRwRFMEMwQTALBgcqhkjOPQIBBQADMgACZpD13z9c7DzRWx6S" + "0xdbq3S+EJ7vWO+YcHVjTD8NcQDcZcWASW899l1PkL936zsuMBoGCSuBBRCG" + "SD8AEDANBglghkgBZQMEAQUFADBLMEkwLTAoMRMwEQYDVQQDEwpBZG1pbi1N" + "RFNFMREwDwYDVQQKEwg0QkNULTJJRAIBAQQYFq58L71nyMK/70w3nc6zkkRy" + "RL7DHmpZMIAGCSqGSIb3DQEHATAdBglghkgBZQMEAQIEEDzRUpreBsZXWHBe" + "onxOtSmggAQQ7csAZXwT1lHUqoazoy8bhAQQq+9Zjj8iGdOWgyebbfj67QAA" + "AAAAAAAAAAA="); private byte[] ecKeyAgreeKey = Base64.decode( "MIG2AgEAMBAGByqGSM49AgEGBSuBBAAiBIGeMIGbAgEBBDC8vp7xVTbKSgYVU5Wc" + "hGkWbzaj+yUFETIWP1Dt7+WSpq3ikSPdl7PpHPqnPVZfoIWhZANiAgSYHTgxf+Dd" + "Tt84dUvuSKkFy3RhjxJmjwIscK6zbEUzKhcPQG2GHzXhWK5x1kov0I74XpGhVkya" + "ElH5K6SaOXiXAzcyNGggTOk4+ZFnz5Xl0pBje3zKxPhYu0SnCw7Pcqw="); private byte[] bobPrivRsaEncrypt = Base64.decode( "MIIChQIBADANBgkqhkiG9w0BAQEFAASCAmAwggJcAgEAAoGBAKnhZ5g/OdVf" + "8qCTQV6meYmFyDVdmpFb+x0B2hlwJhcPvaUi0DWFbXqYZhRBXM+3twg7CcmR" + "uBlpN235ZR572akzJKN/O7uvRgGGNjQyywcDWVL8hYsxBLjMGAgUSOZPHPtd" + "YMTgXB9T039T2GkB8QX4enDRvoPGXzjPHCyqaqfrAgMBAAECgYBnzUhMmg2P" + "mMIbZf8ig5xt8KYGHbztpwOIlPIcaw+LNd4Ogngwy+e6alatd8brUXlweQqg" + "9P5F4Kmy9Bnah5jWMIR05PxZbMHGd9ypkdB8MKCixQheIXFD/A0HPfD6bRSe" + "TmPwF1h5HEuYHD09sBvf+iU7o8AsmAX2EAnYh9sDGQJBANDDIsbeopkYdo+N" + "vKZ11mY/1I1FUox29XLE6/BGmvE+XKpVC5va3Wtt+Pw7PAhDk7Vb/s7q/WiE" + "I2Kv8zHCueUCQQDQUfweIrdb7bWOAcjXq/JY1PeClPNTqBlFy2bKKBlf4hAr" + "84/sajB0+E0R9KfEILVHIdxJAfkKICnwJAiEYH2PAkA0umTJSChXdNdVUN5q" + "SO8bKlocSHseIVnDYDubl6nA7xhmqU5iUjiEzuUJiEiUacUgFJlaV/4jbOSn" + "I3vQgLeFAkEAni+zN5r7CwZdV+EJBqRd2ZCWBgVfJAZAcpw6iIWchw+dYhKI" + "FmioNRobQ+g4wJhprwMKSDIETukPj3d9NDAlBwJAVxhn1grStavCunrnVNqc" + "BU+B1O8BiR4yPWnLMcRSyFRVJQA7HCp8JlDV6abXd8vPFfXuC9WN7rOvTKF8" + "Y0ZB9qANMAsGA1UdDzEEAwIAEA=="); private byte[] rfc4134ex5_1 = Base64.decode( "MIIBHgYJKoZIhvcNAQcDoIIBDzCCAQsCAQAxgcAwgb0CAQAwJjASMRAwDgYD" + "VQQDEwdDYXJsUlNBAhBGNGvHgABWvBHTbi7NXXHQMA0GCSqGSIb3DQEBAQUA" + "BIGAC3EN5nGIiJi2lsGPcP2iJ97a4e8kbKQz36zg6Z2i0yx6zYC4mZ7mX7FB" + "s3IWg+f6KgCLx3M1eCbWx8+MDFbbpXadCDgO8/nUkUNYeNxJtuzubGgzoyEd" + "8Ch4H/dd9gdzTd+taTEgS0ipdSJuNnkVY4/M652jKKHRLFf02hosdR8wQwYJ" + "KoZIhvcNAQcBMBQGCCqGSIb3DQMHBAgtaMXpRwZRNYAgDsiSf8Z9P43LrY4O" + "xUk660cu1lXeCSFOSOpOJ7FuVyU="); private byte[] rfc4134ex5_2 = Base64.decode( "MIIBZQYJKoZIhvcNAQcDoIIBVjCCAVICAQIxggEAMIG9AgEAMCYwEjEQMA4G" + "A1UEAxMHQ2FybFJTQQIQRjRrx4AAVrwR024uzV1x0DANBgkqhkiG9w0BAQEF" + "AASBgJQmQojGi7Z4IP+CVypBmNFoCDoEp87khtgyff2N4SmqD3RxPx+8hbLQ" + "t9i3YcMwcap+aiOkyqjMalT03VUC0XBOGv+HYI3HBZm/aFzxoq+YOXAWs5xl" + "GerZwTOc9j6AYlK4qXvnztR5SQ8TBjlzytm4V7zg+TGrnGVNQBNw47Ewoj4C" + "AQQwDQQLTWFpbExpc3RSQzIwEAYLKoZIhvcNAQkQAwcCAToEGHcUr5MSJ/g9" + "HnJVHsQ6X56VcwYb+OfojTBJBgkqhkiG9w0BBwEwGgYIKoZIhvcNAwIwDgIC" + "AKAECJwE0hkuKlWhgCBeKNXhojuej3org9Lt7n+wWxOhnky5V50vSpoYRfRR" + "yw=="); public EnvelopedDataTest() { } private static void init() throws Exception { if (!_initialised) { _initialised = true; _signDN = "O=Bouncy Castle, C=AU"; _signKP = CMSTestUtil.makeKeyPair(); _signCert = CMSTestUtil.makeCertificate(_signKP, _signDN, _signKP, _signDN); _origDN = "CN=Bob, OU=Sales, O=Bouncy Castle, C=AU"; _origKP = CMSTestUtil.makeKeyPair(); _origCert = CMSTestUtil.makeCertificate(_origKP, _origDN, _signKP, _signDN); _reciDN = "CN=Doug, OU=Sales, O=Bouncy Castle, C=AU"; _reciDN2 = "CN=Fred, OU=Sales, O=Bouncy Castle, C=AU"; _reciKP = CMSTestUtil.makeKeyPair(); _reciCert = CMSTestUtil.makeCertificate(_reciKP, _reciDN, _signKP, _signDN); _origEcKP = CMSTestUtil.makeEcDsaKeyPair(); _reciEcKP = CMSTestUtil.makeEcDsaKeyPair(); _reciEcCert = CMSTestUtil.makeCertificate(_reciEcKP, _reciDN, _signKP, _signDN); _reciEcKP2 = CMSTestUtil.makeEcDsaKeyPair(); _reciEcCert2 = CMSTestUtil.makeCertificate(_reciEcKP2, _reciDN2, _signKP, _signDN); } } public static void main( String args[]) throws Exception { junit.textui.TestRunner.run(EnvelopedDataTest.suite()); } public static Test suite() throws Exception { init(); return new CMSTestSetup(new TestSuite(EnvelopedDataTest.class)); } public void testKeyTrans() throws Exception { byte[] data = "WallaWallaWashington".getBytes(); CMSEnvelopedDataGenerator edGen = new CMSEnvelopedDataGenerator(); edGen.addKeyTransRecipient(_reciCert); CMSEnvelopedData ed = edGen.generate( new CMSProcessableByteArray(data), CMSEnvelopedDataGenerator.DES_EDE3_CBC, BC); RecipientInformationStore recipients = ed.getRecipientInfos(); assertEquals(ed.getEncryptionAlgOID(), CMSEnvelopedDataGenerator.DES_EDE3_CBC); Collection c = recipients.getRecipients(); assertEquals(1, c.size()); Iterator it = c.iterator(); while (it.hasNext()) { RecipientInformation recipient = (RecipientInformation)it.next(); assertEquals(recipient.getKeyEncryptionAlgOID(), PKCSObjectIdentifiers.rsaEncryption.getId()); byte[] recData = recipient.getContent(_reciKP.getPrivate(), BC); assertEquals(true, Arrays.equals(data, recData)); } } public void testKeyTransCAST5SunJCE() throws Exception { if (Security.getProvider("SunJCE") == null) { return; } String version = System.getProperty("java.version"); if (version.startsWith("1.4") || version.startsWith("1.3")) { return; } byte[] data = "WallaWallaWashington".getBytes(); CMSEnvelopedDataGenerator edGen = new CMSEnvelopedDataGenerator(); edGen.addKeyTransRecipient(_reciCert); CMSEnvelopedData ed = edGen.generate( new CMSProcessableByteArray(data), CMSEnvelopedDataGenerator.CAST5_CBC, "SunJCE"); RecipientInformationStore recipients = ed.getRecipientInfos(); assertEquals(ed.getEncryptionAlgOID(), CMSEnvelopedDataGenerator.CAST5_CBC); Collection c = recipients.getRecipients(); assertEquals(1, c.size()); Iterator it = c.iterator(); while (it.hasNext()) { RecipientInformation recipient = (RecipientInformation)it.next(); assertEquals(recipient.getKeyEncryptionAlgOID(), PKCSObjectIdentifiers.rsaEncryption.getId()); byte[] recData = recipient.getContent(_reciKP.getPrivate(), "SunJCE"); assertEquals(true, Arrays.equals(data, recData)); } } public void testKeyTransRC4() throws Exception { byte[] data = "WallaWallaBouncyCastle".getBytes(); CMSEnvelopedDataGenerator edGen = new CMSEnvelopedDataGenerator(); edGen.addKeyTransRecipient(_reciCert); CMSEnvelopedData ed = edGen.generate( new CMSProcessableByteArray(data), "1.2.840.113549.3.4", BC); RecipientInformationStore recipients = ed.getRecipientInfos(); assertEquals(ed.getEncryptionAlgOID(), "1.2.840.113549.3.4"); Collection c = recipients.getRecipients(); assertEquals(1, c.size()); Iterator it = c.iterator(); while (it.hasNext()) { RecipientInformation recipient = (RecipientInformation)it.next(); byte[] recData = recipient.getContent(_reciKP.getPrivate(), BC); assertEquals(true, Arrays.equals(data, recData)); } } public void testKeyTrans128RC4() throws Exception { byte[] data = "WallaWallaBouncyCastle".getBytes(); CMSEnvelopedDataGenerator edGen = new CMSEnvelopedDataGenerator(); edGen.addKeyTransRecipient(_reciCert); CMSEnvelopedData ed = edGen.generate( new CMSProcessableByteArray(data), "1.2.840.113549.3.4", 128, BC); RecipientInformationStore recipients = ed.getRecipientInfos(); assertEquals(ed.getEncryptionAlgOID(), "1.2.840.113549.3.4"); Collection c = recipients.getRecipients(); Iterator it = c.iterator(); if (it.hasNext()) { RecipientInformation recipient = (RecipientInformation)it.next(); byte[] recData = recipient.getContent(_reciKP.getPrivate(), BC); assertEquals(true, Arrays.equals(data, recData)); } else { fail("no recipient found"); } } public void testKeyTransODES() throws Exception { byte[] data = "WallaWallaBouncyCastle".getBytes(); CMSEnvelopedDataGenerator edGen = new CMSEnvelopedDataGenerator(); edGen.addKeyTransRecipient(_reciCert); CMSEnvelopedData ed = edGen.generate( new CMSProcessableByteArray(data), "1.3.14.3.2.7", BC); RecipientInformationStore recipients = ed.getRecipientInfos(); assertEquals(ed.getEncryptionAlgOID(), "1.3.14.3.2.7"); Collection c = recipients.getRecipients(); Iterator it = c.iterator(); if (it.hasNext()) { RecipientInformation recipient = (RecipientInformation)it.next(); byte[] recData = recipient.getContent(_reciKP.getPrivate(), BC); assertEquals(true, Arrays.equals(data, recData)); } else { fail("no recipient found"); } } public void testKeyTransSmallAES() throws Exception { byte[] data = new byte[] { 0, 1, 2, 3 }; CMSEnvelopedDataGenerator edGen = new CMSEnvelopedDataGenerator(); edGen.addKeyTransRecipient(_reciCert); CMSEnvelopedData ed = edGen.generate( new CMSProcessableByteArray(data), CMSEnvelopedDataGenerator.AES128_CBC, BC); RecipientInformationStore recipients = ed.getRecipientInfos(); assertEquals(ed.getEncryptionAlgOID(), CMSEnvelopedDataGenerator.AES128_CBC); Collection c = recipients.getRecipients(); Iterator it = c.iterator(); if (it.hasNext()) { RecipientInformation recipient = (RecipientInformation)it.next(); byte[] recData = recipient.getContent(_reciKP.getPrivate(), BC); assertEquals(true, Arrays.equals(data, recData)); } else { fail("no recipient found"); } } public void testKeyTransCAST5() throws Exception { tryKeyTrans(CMSEnvelopedDataGenerator.CAST5_CBC, new DERObjectIdentifier(CMSEnvelopedDataGenerator.CAST5_CBC), ASN1Sequence.class); } public void testKeyTransAES128() throws Exception { tryKeyTrans(CMSEnvelopedDataGenerator.AES128_CBC, NISTObjectIdentifiers.id_aes128_CBC, DEROctetString.class); } public void testKeyTransAES192() throws Exception { tryKeyTrans(CMSEnvelopedDataGenerator.AES192_CBC, NISTObjectIdentifiers.id_aes192_CBC, DEROctetString.class); } public void testKeyTransAES256() throws Exception { tryKeyTrans(CMSEnvelopedDataGenerator.AES256_CBC, NISTObjectIdentifiers.id_aes256_CBC, DEROctetString.class); } public void testKeyTransSEED() throws Exception { tryKeyTrans(CMSEnvelopedDataGenerator.SEED_CBC, KISAObjectIdentifiers.id_seedCBC, DEROctetString.class); } public void testKeyTransCamellia128() throws Exception { tryKeyTrans(CMSEnvelopedDataGenerator.CAMELLIA128_CBC, NTTObjectIdentifiers.id_camellia128_cbc, DEROctetString.class); } public void testKeyTransCamellia192() throws Exception { tryKeyTrans(CMSEnvelopedDataGenerator.CAMELLIA192_CBC, NTTObjectIdentifiers.id_camellia192_cbc, DEROctetString.class); } public void testKeyTransCamellia256() throws Exception { tryKeyTrans(CMSEnvelopedDataGenerator.CAMELLIA256_CBC, NTTObjectIdentifiers.id_camellia256_cbc, DEROctetString.class); } private void tryKeyTrans(String generatorOID, DERObjectIdentifier checkOID, Class asn1Params) throws Exception { byte[] data = "WallaWallaWashington".getBytes(); CMSEnvelopedDataGenerator edGen = new CMSEnvelopedDataGenerator(); edGen.addKeyTransRecipient(_reciCert); CMSEnvelopedData ed = edGen.generate( new CMSProcessableByteArray(data), generatorOID, BC); RecipientInformationStore recipients = ed.getRecipientInfos(); assertEquals(checkOID.getId(), ed.getEncryptionAlgOID()); if (asn1Params != null) { ASN1InputStream aIn = new ASN1InputStream(ed.getEncryptionAlgParams()); assertTrue(asn1Params.isAssignableFrom(aIn.readObject().getClass())); } Collection c = recipients.getRecipients(); assertEquals(1, c.size()); Iterator it = c.iterator(); if (!it.hasNext()) { fail("no recipients found"); } while (it.hasNext()) { RecipientInformation recipient = (RecipientInformation)it.next(); assertEquals(recipient.getKeyEncryptionAlgOID(), PKCSObjectIdentifiers.rsaEncryption.getId()); byte[] recData = recipient.getContent(_reciKP.getPrivate(), BC); assertEquals(true, Arrays.equals(data, recData)); } } public void testErrorneousKEK() throws Exception { byte[] data = "WallaWallaWashington".getBytes(); SecretKey kek = new SecretKeySpec(new byte[] { 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16 }, "AES"); CMSEnvelopedData ed = new CMSEnvelopedData(oldKEK); RecipientInformationStore recipients = ed.getRecipientInfos(); assertEquals(ed.getEncryptionAlgOID(), CMSEnvelopedDataGenerator.DES_EDE3_CBC); Collection c = recipients.getRecipients(); Iterator it = c.iterator(); if (it.hasNext()) { RecipientInformation recipient = (RecipientInformation)it.next(); assertEquals(recipient.getKeyEncryptionAlgOID(), NISTObjectIdentifiers.id_aes128_wrap.getId()); byte[] recData = recipient.getContent(kek, BC); assertEquals(true, Arrays.equals(data, recData)); } else { fail("no recipient found"); } } public void testDESKEK() throws Exception { tryKekAlgorithm(CMSTestUtil.makeDesede192Key(), new DERObjectIdentifier("1.2.840.113549.1.9.16.3.6")); } public void testRC2128KEK() throws Exception { tryKekAlgorithm(CMSTestUtil.makeRC2128Key(), new DERObjectIdentifier("1.2.840.113549.1.9.16.3.7")); } public void testAES128KEK() throws Exception { tryKekAlgorithm(CMSTestUtil.makeAESKey(128), NISTObjectIdentifiers.id_aes128_wrap); } public void testAES192KEK() throws Exception { tryKekAlgorithm(CMSTestUtil.makeAESKey(192), NISTObjectIdentifiers.id_aes192_wrap); } public void testAES256KEK() throws Exception { tryKekAlgorithm(CMSTestUtil.makeAESKey(256), NISTObjectIdentifiers.id_aes256_wrap); } public void testSEED128KEK() throws Exception { tryKekAlgorithm(CMSTestUtil.makeSEEDKey(), KISAObjectIdentifiers.id_npki_app_cmsSeed_wrap); } public void testCamellia128KEK() throws Exception { tryKekAlgorithm(CMSTestUtil.makeCamelliaKey(128), NTTObjectIdentifiers.id_camellia128_wrap); } public void testCamellia192KEK() throws Exception { tryKekAlgorithm(CMSTestUtil.makeCamelliaKey(192), NTTObjectIdentifiers.id_camellia192_wrap); } public void testCamellia256KEK() throws Exception { tryKekAlgorithm(CMSTestUtil.makeCamelliaKey(256), NTTObjectIdentifiers.id_camellia256_wrap); } private void tryKekAlgorithm(SecretKey kek, DERObjectIdentifier algOid) throws NoSuchAlgorithmException, NoSuchProviderException, CMSException { byte[] data = "WallaWallaWashington".getBytes(); CMSEnvelopedDataGenerator edGen = new CMSEnvelopedDataGenerator(); byte[] kekId = new byte[] { 1, 2, 3, 4, 5 }; edGen.addKEKRecipient(kek, kekId); CMSEnvelopedData ed = edGen.generate( new CMSProcessableByteArray(data), CMSEnvelopedDataGenerator.DES_EDE3_CBC, BC); RecipientInformationStore recipients = ed.getRecipientInfos(); Collection c = recipients.getRecipients(); Iterator it = c.iterator(); assertEquals(ed.getEncryptionAlgOID(), CMSEnvelopedDataGenerator.DES_EDE3_CBC); if (it.hasNext()) { RecipientInformation recipient = (RecipientInformation)it.next(); assertEquals(algOid.getId(), recipient.getKeyEncryptionAlgOID()); byte[] recData = recipient.getContent(kek, BC); assertTrue(Arrays.equals(data, recData)); } else { fail("no recipient found"); } } public void testECKeyAgree() throws Exception { byte[] data = Hex.decode("504b492d4320434d5320456e76656c6f706564446174612053616d706c65"); CMSEnvelopedDataGenerator edGen = new CMSEnvelopedDataGenerator(); edGen.addKeyAgreementRecipient(CMSEnvelopedDataGenerator.ECDH_SHA1KDF, _origEcKP.getPrivate(), _origEcKP.getPublic(), _reciEcCert, CMSEnvelopedDataGenerator.AES128_WRAP, BC); CMSEnvelopedData ed = edGen.generate( new CMSProcessableByteArray(data), CMSEnvelopedDataGenerator.AES128_CBC, BC); assertEquals(ed.getEncryptionAlgOID(), CMSEnvelopedDataGenerator.AES128_CBC); RecipientInformationStore recipients = ed.getRecipientInfos(); confirmDataReceived(recipients, data, _reciEcCert, _reciEcKP.getPrivate(), BC); confirmNumberRecipients(recipients, 1); } public void testECMQVKeyAgree() throws Exception { byte[] data = Hex.decode("504b492d4320434d5320456e76656c6f706564446174612053616d706c65"); CMSEnvelopedDataGenerator edGen = new CMSEnvelopedDataGenerator(); edGen.addKeyAgreementRecipient(CMSEnvelopedDataGenerator.ECMQV_SHA1KDF, _origEcKP.getPrivate(), _origEcKP.getPublic(), _reciEcCert, CMSEnvelopedDataGenerator.AES128_WRAP, BC); CMSEnvelopedData ed = edGen.generate( new CMSProcessableByteArray(data), CMSEnvelopedDataGenerator.AES128_CBC, BC); assertEquals(ed.getEncryptionAlgOID(), CMSEnvelopedDataGenerator.AES128_CBC); RecipientInformationStore recipients = ed.getRecipientInfos(); confirmDataReceived(recipients, data, _reciEcCert, _reciEcKP.getPrivate(), BC); confirmNumberRecipients(recipients, 1); } public void testECMQVKeyAgreeMultiple() throws Exception { byte[] data = Hex.decode("504b492d4320434d5320456e76656c6f706564446174612053616d706c65"); CMSEnvelopedDataGenerator edGen = new CMSEnvelopedDataGenerator(); ArrayList recipientCerts = new ArrayList(); recipientCerts.add(_reciEcCert); recipientCerts.add(_reciEcCert2); edGen.addKeyAgreementRecipients(CMSEnvelopedDataGenerator.ECMQV_SHA1KDF, _origEcKP.getPrivate(), _origEcKP.getPublic(), recipientCerts, CMSEnvelopedDataGenerator.AES128_WRAP, BC); CMSEnvelopedData ed = edGen.generate( new CMSProcessableByteArray(data), CMSEnvelopedDataGenerator.AES128_CBC, BC); assertEquals(ed.getEncryptionAlgOID(), CMSEnvelopedDataGenerator.AES128_CBC); RecipientInformationStore recipients = ed.getRecipientInfos(); confirmDataReceived(recipients, data, _reciEcCert, _reciEcKP.getPrivate(), BC); confirmDataReceived(recipients, data, _reciEcCert2, _reciEcKP2.getPrivate(), BC); confirmNumberRecipients(recipients, 2); } private static void confirmDataReceived(RecipientInformationStore recipients, byte[] expectedData, X509Certificate reciCert, PrivateKey reciPrivKey, String provider) throws CMSException, NoSuchProviderException, CertificateEncodingException, IOException { RecipientId rid = new JceKeyAgreeRecipientId(reciCert); RecipientInformation recipient = recipients.get(rid); assertNotNull(recipient); byte[] actualData = recipient.getContent(reciPrivKey, provider); assertEquals(true, Arrays.equals(expectedData, actualData)); } private static void confirmNumberRecipients(RecipientInformationStore recipients, int count) { assertEquals(count, recipients.getRecipients().size()); } public void testECKeyAgreeVectors() throws Exception { PKCS8EncodedKeySpec privSpec = new PKCS8EncodedKeySpec(ecKeyAgreeKey); KeyFactory fact = KeyFactory.getInstance("ECDH", BC); PrivateKey privKey = fact.generatePrivate(privSpec); verifyECKeyAgreeVectors(privKey, "2.16.840.1.101.3.4.1.42", ecKeyAgreeMsgAES256); verifyECKeyAgreeVectors(privKey, "2.16.840.1.101.3.4.1.2", ecKeyAgreeMsgAES128); verifyECKeyAgreeVectors(privKey, "1.2.840.113549.3.7", ecKeyAgreeMsgDESEDE); } public void testECMQVKeyAgreeVectors() throws Exception { PKCS8EncodedKeySpec privSpec = new PKCS8EncodedKeySpec(ecKeyAgreeKey); KeyFactory fact = KeyFactory.getInstance("ECDH", BC); PrivateKey privKey = fact.generatePrivate(privSpec); verifyECMQVKeyAgreeVectors(privKey, "2.16.840.1.101.3.4.1.2", ecMQVKeyAgreeMsgAES128); } public void testPasswordAES256() throws Exception { passwordTest(CMSEnvelopedDataGenerator.AES256_CBC); passwordUTF8Test(CMSEnvelopedDataGenerator.AES256_CBC); } public void testPasswordDESEDE() throws Exception { passwordTest(CMSEnvelopedDataGenerator.DES_EDE3_CBC); passwordUTF8Test(CMSEnvelopedDataGenerator.DES_EDE3_CBC); } public void testRFC4134ex5_1() throws Exception { byte[] data = Hex.decode("5468697320697320736f6d652073616d706c6520636f6e74656e742e"); KeyFactory kFact = KeyFactory.getInstance("RSA", BC); Key key = kFact.generatePrivate(new PKCS8EncodedKeySpec(bobPrivRsaEncrypt)); CMSEnvelopedData ed = new CMSEnvelopedData(rfc4134ex5_1); RecipientInformationStore recipients = ed.getRecipientInfos(); assertEquals("1.2.840.113549.3.7", ed.getEncryptionAlgOID()); Collection c = recipients.getRecipients(); Iterator it = c.iterator(); if (it.hasNext()) { RecipientInformation recipient = (RecipientInformation)it.next(); byte[] recData = recipient.getContent(key, BC); assertEquals(true, Arrays.equals(data, recData)); } else { fail("no recipient found"); } } public void testRFC4134ex5_2() throws Exception { byte[] data = Hex.decode("5468697320697320736f6d652073616d706c6520636f6e74656e742e"); KeyFactory kFact = KeyFactory.getInstance("RSA", BC); Key key = kFact.generatePrivate(new PKCS8EncodedKeySpec(bobPrivRsaEncrypt)); CMSEnvelopedData ed = new CMSEnvelopedData(rfc4134ex5_2); RecipientInformationStore recipients = ed.getRecipientInfos(); assertEquals("1.2.840.113549.3.2", ed.getEncryptionAlgOID()); Collection c = recipients.getRecipients(); Iterator it = c.iterator(); if (it.hasNext()) { while (it.hasNext()) { RecipientInformation recipient = (RecipientInformation)it.next(); byte[] recData; if (recipient instanceof KeyTransRecipientInformation) { recData = recipient.getContent(key, BC); assertEquals(true, Arrays.equals(data, recData)); } } } else { fail("no recipient found"); } } public void testOriginatorInfo() throws Exception { CMSEnvelopedData env = new CMSEnvelopedData(CMSSampleMessages.originatorMessage); RecipientInformationStore recipients = env.getRecipientInfos(); assertEquals(CMSEnvelopedDataGenerator.DES_EDE3_CBC, env.getEncryptionAlgOID()); } private void passwordTest(String algorithm) throws Exception { byte[] data = Hex.decode("504b492d4320434d5320456e76656c6f706564446174612053616d706c65"); CMSEnvelopedDataGenerator edGen = new CMSEnvelopedDataGenerator(); edGen.addPasswordRecipient(new PKCS5Scheme2PBEKey("password".toCharArray(), new byte[20], 5), algorithm); CMSEnvelopedData ed = edGen.generate( new CMSProcessableByteArray(data), CMSEnvelopedDataGenerator.AES128_CBC, BC); RecipientInformationStore recipients = ed.getRecipientInfos(); assertEquals(ed.getEncryptionAlgOID(), CMSEnvelopedDataGenerator.AES128_CBC); Collection c = recipients.getRecipients(); Iterator it = c.iterator(); if (it.hasNext()) { PasswordRecipientInformation recipient = (PasswordRecipientInformation)it.next(); CMSPBEKey key = new PKCS5Scheme2PBEKey("password".toCharArray(), recipient.getKeyDerivationAlgParameters(BC)); byte[] recData = recipient.getContent(key, BC); assertEquals(true, Arrays.equals(data, recData)); } else { fail("no recipient found"); } // // try algorithm parameters constructor // it = c.iterator(); RecipientInformation recipient = (RecipientInformation)it.next(); byte[] recData = recipient.getContent(new PKCS5Scheme2PBEKey("password".toCharArray(), ((PasswordRecipientInformation)recipient).getKeyDerivationAlgParameters(BC)), BC); assertEquals(true, Arrays.equals(data, recData)); } private void passwordUTF8Test(String algorithm) throws Exception { byte[] data = Hex.decode("504b492d4320434d5320456e76656c6f706564446174612053616d706c65"); CMSEnvelopedDataGenerator edGen = new CMSEnvelopedDataGenerator(); edGen.addPasswordRecipient(new PKCS5Scheme2UTF8PBEKey("abc\u5639\u563b".toCharArray(), new byte[20], 5), algorithm); CMSEnvelopedData ed = edGen.generate( new CMSProcessableByteArray(data), CMSEnvelopedDataGenerator.AES128_CBC, BC); RecipientInformationStore recipients = ed.getRecipientInfos(); assertEquals(ed.getEncryptionAlgOID(), CMSEnvelopedDataGenerator.AES128_CBC); Collection c = recipients.getRecipients(); Iterator it = c.iterator(); if (it.hasNext()) { RecipientInformation recipient = (RecipientInformation)it.next(); byte[] recData = recipient.getContent(new PKCS5Scheme2UTF8PBEKey("abc\u5639\u563b".toCharArray(), new byte[20], 5), BC); assertEquals(true, Arrays.equals(data, recData)); } else { fail("no recipient found"); } // // try algorithm parameters constructor // it = c.iterator(); RecipientInformation recipient = (RecipientInformation)it.next(); byte[] recData = recipient.getContent(new PKCS5Scheme2UTF8PBEKey("abc\u5639\u563b".toCharArray(), ((PasswordRecipientInformation)recipient).getKeyDerivationAlgParameters(BC)), BC); assertEquals(true, Arrays.equals(data, recData)); } private void verifyECKeyAgreeVectors(PrivateKey privKey, String wrapAlg, byte[] message) throws CMSException, GeneralSecurityException { byte[] data = Hex.decode("504b492d4320434d5320456e76656c6f706564446174612053616d706c65"); CMSEnvelopedData ed = new CMSEnvelopedData(message); RecipientInformationStore recipients = ed.getRecipientInfos(); Collection c = recipients.getRecipients(); Iterator it = c.iterator(); assertEquals(wrapAlg, ed.getEncryptionAlgOID()); if (it.hasNext()) { RecipientInformation recipient = (RecipientInformation)it.next(); assertEquals("1.3.133.16.840.63.0.2", recipient.getKeyEncryptionAlgOID()); byte[] recData = recipient.getContent(privKey, BC); assertTrue(Arrays.equals(data, recData)); } else { fail("no recipient found"); } } private void verifyECMQVKeyAgreeVectors(PrivateKey privKey, String wrapAlg, byte[] message) throws CMSException, GeneralSecurityException { byte[] data = Hex.decode("504b492d4320434d5320456e76656c6f706564446174612053616d706c65"); CMSEnvelopedData ed = new CMSEnvelopedData(message); RecipientInformationStore recipients = ed.getRecipientInfos(); Collection c = recipients.getRecipients(); Iterator it = c.iterator(); assertEquals(wrapAlg, ed.getEncryptionAlgOID()); if (it.hasNext()) { RecipientInformation recipient = (RecipientInformation)it.next(); assertEquals("1.3.133.16.840.63.0.16", recipient.getKeyEncryptionAlgOID()); byte[] recData = recipient.getContent(privKey, BC); assertTrue(Arrays.equals(data, recData)); } else { fail("no recipient found"); } } } bouncycastle-1.49.orig/test/src/org/bouncycastle/cms/test/Rfc4134Test.java0000644000175000017500000003424712110046700025754 0ustar ebourgebourgpackage org.bouncycastle.cms.test; import java.io.ByteArrayInputStream; import java.io.FileInputStream; import java.io.IOException; import java.security.KeyFactory; import java.security.MessageDigest; import java.security.NoSuchAlgorithmException; import java.security.NoSuchProviderException; import java.security.PrivateKey; import java.security.PublicKey; import java.security.Security; import java.security.cert.CertStore; import java.security.cert.CertificateFactory; import java.security.cert.X509Certificate; import java.security.interfaces.DSAParams; import java.security.interfaces.DSAPublicKey; import java.security.spec.DSAPublicKeySpec; import java.security.spec.InvalidKeySpecException; import java.security.spec.PKCS8EncodedKeySpec; import java.util.Arrays; import java.util.Collection; import java.util.Iterator; import junit.framework.Test; import junit.framework.TestCase; import junit.framework.TestSuite; import org.bouncycastle.asn1.ASN1EncodableVector; import org.bouncycastle.asn1.DERSequence; import org.bouncycastle.asn1.DERUTF8String; import org.bouncycastle.asn1.cms.Attribute; import org.bouncycastle.asn1.cms.AttributeTable; import org.bouncycastle.asn1.cms.CMSAttributes; import org.bouncycastle.asn1.cms.CMSObjectIdentifiers; import org.bouncycastle.asn1.pkcs.PKCSObjectIdentifiers; import org.bouncycastle.cms.CMSEnvelopedData; import org.bouncycastle.cms.CMSEnvelopedDataGenerator; import org.bouncycastle.cms.CMSEnvelopedDataParser; import org.bouncycastle.cms.CMSException; import org.bouncycastle.cms.CMSProcessableByteArray; import org.bouncycastle.cms.CMSSignedData; import org.bouncycastle.cms.CMSSignedDataParser; import org.bouncycastle.cms.CMSTypedStream; import org.bouncycastle.cms.RecipientInformation; import org.bouncycastle.cms.RecipientInformationStore; import org.bouncycastle.cms.SignerInformation; import org.bouncycastle.cms.SignerInformationStore; import org.bouncycastle.cms.jcajce.JcaX509CertSelectorConverter; import org.bouncycastle.jce.provider.BouncyCastleProvider; import org.bouncycastle.util.encoders.Hex; import org.bouncycastle.util.io.Streams; public class Rfc4134Test extends TestCase { private static final String BC = BouncyCastleProvider.PROVIDER_NAME; private static final String TEST_DATA_HOME = "bc.test.data.home"; private static byte[] exContent = getRfc4134Data("ExContent.bin"); private static byte[] sha1 = Hex.decode("406aec085279ba6e16022d9e0629c0229687dd48"); private static final JcaX509CertSelectorConverter selectorConverter = new JcaX509CertSelectorConverter(); public Rfc4134Test(String name) { super(name); } public static void main(String args[]) { Security.addProvider(new BouncyCastleProvider()); junit.textui.TestRunner.run(Rfc4134Test.class); } public static Test suite() throws Exception { return new CMSTestSetup(new TestSuite(Rfc4134Test.class)); } public void test4_1() throws Exception { byte[] data = getRfc4134Data("4.1.bin"); CMSSignedData signedData = new CMSSignedData(data); verifySignatures(signedData); CMSSignedDataParser parser = new CMSSignedDataParser(data); verifySignatures(parser); } public void test4_2() throws Exception { byte[] data = getRfc4134Data("4.2.bin"); CMSSignedData signedData = new CMSSignedData(data); verifySignatures(signedData); CMSSignedDataParser parser = new CMSSignedDataParser(data); verifySignatures(parser); } public void testRfc4_3() throws Exception { byte[] data = getRfc4134Data("4.3.bin"); CMSSignedData signedData = new CMSSignedData(new CMSProcessableByteArray(exContent), data); verifySignatures(signedData, sha1); CMSSignedDataParser parser = new CMSSignedDataParser( new CMSTypedStream(new ByteArrayInputStream(exContent)), data); verifySignatures(parser); } public void test4_4() throws Exception { byte[] data = getRfc4134Data("4.4.bin"); byte[] counterSigCert = getRfc4134Data("AliceRSASignByCarl.cer"); CMSSignedData signedData = new CMSSignedData(data); verifySignatures(signedData, sha1); verifySignerInfo4_4(getFirstSignerInfo(signedData.getSignerInfos()), counterSigCert); CMSSignedDataParser parser = new CMSSignedDataParser(data); verifySignatures(parser); verifySignerInfo4_4(getFirstSignerInfo(parser.getSignerInfos()), counterSigCert); } public void test4_5() throws Exception { byte[] data = getRfc4134Data("4.5.bin"); CMSSignedData signedData = new CMSSignedData(data); verifySignatures(signedData); CMSSignedDataParser parser = new CMSSignedDataParser(data); verifySignatures(parser); } public void test4_6() throws Exception { byte[] data = getRfc4134Data("4.6.bin"); CMSSignedData signedData = new CMSSignedData(data); verifySignatures(signedData); CMSSignedDataParser parser = new CMSSignedDataParser(data); verifySignatures(parser); } public void test4_7() throws Exception { byte[] data = getRfc4134Data("4.7.bin"); CMSSignedData signedData = new CMSSignedData(data); verifySignatures(signedData); CMSSignedDataParser parser = new CMSSignedDataParser(data); verifySignatures(parser); } public void test5_1() throws Exception { byte[] data = getRfc4134Data("5.1.bin"); CMSEnvelopedData envelopedData = new CMSEnvelopedData(data); verifyEnvelopedData(envelopedData, CMSEnvelopedDataGenerator.DES_EDE3_CBC); CMSEnvelopedDataParser envelopedParser = new CMSEnvelopedDataParser(data); verifyEnvelopedData(envelopedParser, CMSEnvelopedDataGenerator.DES_EDE3_CBC); } public void test5_2() throws Exception { byte[] data = getRfc4134Data("5.2.bin"); CMSEnvelopedData envelopedData = new CMSEnvelopedData(data); verifyEnvelopedData(envelopedData, CMSEnvelopedDataGenerator.RC2_CBC); CMSEnvelopedDataParser envelopedParser = new CMSEnvelopedDataParser(data); verifyEnvelopedData(envelopedParser, CMSEnvelopedDataGenerator.RC2_CBC); } private void verifyEnvelopedData(CMSEnvelopedData envelopedData, String symAlgorithmOID) throws NoSuchAlgorithmException, NoSuchProviderException, InvalidKeySpecException, CMSException { byte[] privKeyData = getRfc4134Data("BobPrivRSAEncrypt.pri"); PKCS8EncodedKeySpec keySpec = new PKCS8EncodedKeySpec(privKeyData); KeyFactory keyFact = KeyFactory.getInstance("RSA", BC); PrivateKey privKey = keyFact.generatePrivate(keySpec); RecipientInformationStore recipients = envelopedData.getRecipientInfos(); assertEquals(envelopedData.getEncryptionAlgOID(), symAlgorithmOID); Collection c = recipients.getRecipients(); assertTrue(c.size() >= 1 && c.size() <= 2); Iterator it = c.iterator(); verifyRecipient((RecipientInformation)it.next(), privKey); if (c.size() == 2) { RecipientInformation recInfo = (RecipientInformation)it.next(); assertEquals(PKCSObjectIdentifiers.id_alg_CMSRC2wrap.getId(), recInfo.getKeyEncryptionAlgOID()); } } private void verifyEnvelopedData(CMSEnvelopedDataParser envelopedParser, String symAlgorithmOID) throws NoSuchAlgorithmException, NoSuchProviderException, InvalidKeySpecException, CMSException { byte[] privKeyData = getRfc4134Data("BobPrivRSAEncrypt.pri"); PKCS8EncodedKeySpec keySpec = new PKCS8EncodedKeySpec(privKeyData); KeyFactory keyFact = KeyFactory.getInstance("RSA", BC); PrivateKey privKey = keyFact.generatePrivate(keySpec); RecipientInformationStore recipients = envelopedParser.getRecipientInfos(); assertEquals(envelopedParser.getEncryptionAlgOID(), symAlgorithmOID); Collection c = recipients.getRecipients(); assertTrue(c.size() >= 1 && c.size() <= 2); Iterator it = c.iterator(); verifyRecipient((RecipientInformation)it.next(), privKey); if (c.size() == 2) { RecipientInformation recInfo = (RecipientInformation)it.next(); assertEquals(PKCSObjectIdentifiers.id_alg_CMSRC2wrap.getId(), recInfo.getKeyEncryptionAlgOID()); } } private void verifyRecipient(RecipientInformation recipient, PrivateKey privKey) throws CMSException, NoSuchProviderException { assertEquals(recipient.getKeyEncryptionAlgOID(), PKCSObjectIdentifiers.rsaEncryption.getId()); byte[] recData = recipient.getContent(privKey, BC); assertEquals(true, Arrays.equals(exContent, recData)); } private void verifySignerInfo4_4(SignerInformation signerInfo, byte[] counterSigCert) throws Exception { verifyCounterSignature(signerInfo, counterSigCert); verifyContentHint(signerInfo); } private SignerInformation getFirstSignerInfo(SignerInformationStore store) { return (SignerInformation)store.getSigners().iterator().next(); } private void verifyCounterSignature(SignerInformation signInfo, byte[] certificate) throws Exception { SignerInformation csi = (SignerInformation)signInfo.getCounterSignatures().getSigners().iterator().next(); CertificateFactory certFact = CertificateFactory.getInstance("X.509", BC); X509Certificate cert = (X509Certificate)certFact.generateCertificate(new ByteArrayInputStream(certificate)); assertTrue(csi.verify(cert, BC)); } private void verifyContentHint(SignerInformation signInfo) { AttributeTable attrTable = signInfo.getUnsignedAttributes(); Attribute attr = attrTable.get(CMSAttributes.contentHint); assertEquals(1, attr.getAttrValues().size()); ASN1EncodableVector v = new ASN1EncodableVector(); v.add(new DERUTF8String("Content Hints Description Buffer")); v.add(CMSObjectIdentifiers.data); assertTrue(attr.getAttrValues().getObjectAt(0).equals(new DERSequence(v))); } private void verifySignatures(CMSSignedData s, byte[] contentDigest) throws Exception { CertStore certStore = s.getCertificatesAndCRLs("Collection", BC); SignerInformationStore signers = s.getSignerInfos(); Collection c = signers.getSigners(); Iterator it = c.iterator(); while (it.hasNext()) { SignerInformation signer = (SignerInformation)it.next(); Collection certCollection = certStore.getCertificates(selectorConverter.getCertSelector(signer.getSID())); Iterator certIt = certCollection.iterator(); X509Certificate cert = (X509Certificate)certIt.next(); verifySigner(signer, cert); if (contentDigest != null) { assertTrue(MessageDigest.isEqual(contentDigest, signer.getContentDigest())); } } Collection certColl = certStore.getCertificates(null); Collection crlColl = certStore.getCRLs(null); assertEquals(certColl.size(), s.getCertificates("Collection", BC).getMatches(null).size()); assertEquals(crlColl.size(), s.getCRLs("Collection", BC).getMatches(null).size()); } private void verifySignatures(CMSSignedData s) throws Exception { verifySignatures(s, null); } private void verifySignatures(CMSSignedDataParser sp) throws Exception { CMSTypedStream sc = sp.getSignedContent(); if (sc != null) { sc.drain(); } CertStore certs = sp.getCertificatesAndCRLs("Collection", BC); SignerInformationStore signers = sp.getSignerInfos(); Collection c = signers.getSigners(); Iterator it = c.iterator(); while (it.hasNext()) { SignerInformation signer = (SignerInformation)it.next(); Collection certCollection = certs.getCertificates(selectorConverter.getCertSelector(signer.getSID())); Iterator certIt = certCollection.iterator(); X509Certificate cert = (X509Certificate)certIt.next(); verifySigner(signer, cert); } } private void verifySigner(SignerInformation signer, X509Certificate cert) throws Exception { if (cert.getPublicKey() instanceof DSAPublicKey) { DSAPublicKey key = (DSAPublicKey)cert.getPublicKey(); if (key.getParams() == null) { assertEquals(true, signer.verify(getInheritedKey(key), BC)); } else { assertEquals(true, signer.verify(cert, BC)); } } else { assertEquals(true, signer.verify(cert, BC)); } } private PublicKey getInheritedKey(DSAPublicKey key) throws Exception { CertificateFactory certFact = CertificateFactory.getInstance("X.509", BC); X509Certificate cert = (X509Certificate)certFact.generateCertificate(new ByteArrayInputStream(getRfc4134Data("CarlDSSSelf.cer"))); DSAParams dsaParams = ((DSAPublicKey)cert.getPublicKey()).getParams(); DSAPublicKeySpec dsaPubKeySpec = new DSAPublicKeySpec( key.getY(), dsaParams.getP(), dsaParams.getQ(), dsaParams.getG()); KeyFactory keyFactory = KeyFactory.getInstance("DSA", BC); return keyFactory.generatePublic(dsaPubKeySpec); } private static byte[] getRfc4134Data(String name) { String dataHome = System.getProperty(TEST_DATA_HOME); if (dataHome == null) { throw new IllegalStateException(TEST_DATA_HOME + " property not set"); } try { return Streams.readAll(new FileInputStream(dataHome + "/rfc4134/" + name)); } catch (IOException e) { throw new RuntimeException(e.toString()); } } } bouncycastle-1.49.orig/test/src/org/bouncycastle/cms/test/SignedDataTest.java0000644000175000017500000017771711726245377026772 0ustar ebourgebourgpackage org.bouncycastle.cms.test; import java.io.ByteArrayInputStream; import java.io.IOException; import java.security.KeyFactory; import java.security.KeyPair; import java.security.MessageDigest; import java.security.NoSuchAlgorithmException; import java.security.cert.CertStore; import java.security.cert.CollectionCertStoreParameters; import java.security.cert.X509CRL; import java.security.cert.X509Certificate; import java.security.spec.PKCS8EncodedKeySpec; import java.security.spec.X509EncodedKeySpec; import java.util.ArrayList; import java.util.Collection; import java.util.Collections; import java.util.HashMap; import java.util.Iterator; import java.util.List; import java.util.Map; import junit.framework.Test; import junit.framework.TestCase; import junit.framework.TestSuite; import org.bouncycastle.asn1.ASN1EncodableVector; import org.bouncycastle.asn1.ASN1InputStream; import org.bouncycastle.asn1.ASN1OctetString; import org.bouncycastle.asn1.DEROctetString; import org.bouncycastle.asn1.DERSet; import org.bouncycastle.asn1.cms.Attribute; import org.bouncycastle.asn1.cms.AttributeTable; import org.bouncycastle.asn1.cms.CMSAttributes; import org.bouncycastle.asn1.cms.ContentInfo; import org.bouncycastle.asn1.oiw.OIWObjectIdentifiers; import org.bouncycastle.asn1.pkcs.PKCSObjectIdentifiers; import org.bouncycastle.cms.CMSConfig; import org.bouncycastle.cms.CMSProcessable; import org.bouncycastle.cms.CMSProcessableByteArray; import org.bouncycastle.cms.CMSSignedData; import org.bouncycastle.cms.CMSSignedDataGenerator; import org.bouncycastle.cms.CMSSignedDataParser; import org.bouncycastle.cms.SignerId; import org.bouncycastle.cms.SignerInformation; import org.bouncycastle.cms.SignerInformationStore; import org.bouncycastle.cms.jcajce.JcaX509CertSelectorConverter; import org.bouncycastle.jce.provider.BouncyCastleProvider; import org.bouncycastle.util.encoders.Base64; import org.bouncycastle.util.io.Streams; import org.bouncycastle.x509.X509AttributeCertificate; import org.bouncycastle.x509.X509CollectionStoreParameters; import org.bouncycastle.x509.X509Store; public class SignedDataTest extends TestCase { private static final String BC = BouncyCastleProvider.PROVIDER_NAME; boolean DEBUG = true; private static String _origDN; private static KeyPair _origKP; private static X509Certificate _origCert; private static String _signDN; private static KeyPair _signKP; private static X509Certificate _signCert; private static KeyPair _signGostKP; private static X509Certificate _signGostCert; private static KeyPair _signEcDsaKP; private static X509Certificate _signEcDsaCert; private static KeyPair _signEcGostKP; private static X509Certificate _signEcGostCert; private static KeyPair _signDsaKP; private static X509Certificate _signDsaCert; private static String _reciDN; private static KeyPair _reciKP; private static X509Certificate _reciCert; private static X509CRL _signCrl; private static boolean _initialised = false; private byte[] disorderedMessage = Base64.decode( "SU9fc3RkaW5fdXNlZABfX2xpYmNfc3RhcnRfbWFpbgBnZXRob3N0aWQAX19n" + "bW9uX3M="); private byte[] disorderedSet = Base64.decode( "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" + "gQBpSRdnDb6AcNVaXSmGo6+kVPIBhot1LzJOGaPyDNpGXxd7LV4tMBF1U7gr" + "4k1g9BO6YiMWvw9uiTZmn0CfV8+k4fWEuG/nmafRoGIuay2f+ILuT+C0rnp1" + "4FgMsEhuVNJJAmb12QV0PZII+UneyhAneZuQQzVUkTcVgYxogxdSOzCCAlUw" + "ggHBoAMCAQICBACdekowCgYGKyQDAwECBQAwbzELMAkGA1UEBhMCREUxPTA7" + "BgNVBAoUNFJlZ3VsaWVydW5nc2JlaMhvcmRlIGbIdXIgVGVsZWtvbW11bmlr" + "YXRpb24gdW5kIFBvc3QxITAMBgcCggYBCgcUEwExMBEGA1UEAxQKNlItQ2Eg" + "MTpQTjAiGA8yMDAxMDIwMTEzNDcwN1oYDzIwMDUwMzIyMDg1NTUxWjBvMQsw" + "CQYDVQQGEwJERTE9MDsGA1UEChQ0UmVndWxpZXJ1bmdzYmVoyG9yZGUgZsh1" + "ciBUZWxla29tbXVuaWthdGlvbiB1bmQgUG9zdDEhMAwGBwKCBgEKBxQTATEw" + "EQYDVQQDFAo1Ui1DQSAxOlBOMIGhMA0GCSqGSIb3DQEBAQUAA4GPADCBiwKB" + "gQCKHkFTJx8GmoqFTxEOxpK9XkC3NZ5dBEKiUv0Ife3QMqeGMoCUnyJxwW0k" + "2/53duHxtv2yHSZpFKjrjvE/uGwdOMqBMTjMzkFg19e9JPv061wyADOucOIa" + "NAgha/zFt9XUyrHF21knKCvDNExv2MYIAagkTKajLMAw0bu1J0FadQIFAMAA" + "AAEwCgYGKyQDAwECBQADgYEAV1yTi+2gyB7sUhn4PXmi/tmBxAfe5oBjDW8m" + "gxtfudxKGZ6l/FUPNcrSc5oqBYxKWtLmf3XX87LcblYsch617jtNTkMzhx9e" + "qxiD02ufcrxz2EVt0Akdqiz8mdVeqp3oLcNU/IttpSrcA91CAnoUXtDZYwb/" + "gdQ4FI9l3+qo/0UwggJVMIIBwaADAgECAgQAxIymMAoGBiskAwMBAgUAMG8x" + "CzAJBgNVBAYTAkRFMT0wOwYDVQQKFDRSZWd1bGllcnVuZ3NiZWjIb3JkZSBm" + "yHVyIFRlbGVrb21tdW5pa2F0aW9uIHVuZCBQb3N0MSEwDAYHAoIGAQoHFBMB" + "MTARBgNVBAMUCjZSLUNhIDE6UE4wIhgPMjAwMTEwMTUxMzMxNThaGA8yMDA1" + "MDYwMTA5NTIxN1owbzELMAkGA1UEBhMCREUxPTA7BgNVBAoUNFJlZ3VsaWVy" + "dW5nc2JlaMhvcmRlIGbIdXIgVGVsZWtvbW11bmlrYXRpb24gdW5kIFBvc3Qx" + "ITAMBgcCggYBCgcUEwExMBEGA1UEAxQKN1ItQ0EgMTpQTjCBoTANBgkqhkiG" + "9w0BAQEFAAOBjwAwgYsCgYEAiokD/j6lEP4FexF356OpU5teUpGGfUKjIrFX" + "BHc79G0TUzgVxqMoN1PWnWktQvKo8ETaugxLkP9/zfX3aAQzDW4Zki6x6GDq" + "fy09Agk+RJvhfbbIzRkV4sBBco0n73x7TfG/9NTgVr/96U+I+z/1j30aboM6" + "9OkLEhjxAr0/GbsCBQDAAAABMAoGBiskAwMBAgUAA4GBAHWRqRixt+EuqHhR" + "K1kIxKGZL2vZuakYV0R24Gv/0ZR52FE4ECr+I49o8FP1qiGSwnXB0SwjuH2S" + "iGiSJi+iH/MeY85IHwW1P5e+bOMvEOFhZhQXQixOD7totIoFtdyaj1XGYRef" + "0f2cPOjNJorXHGV8wuBk+/j++sxbd/Net3FtMIICVTCCAcGgAwIBAgIEAMSM" + "pzAKBgYrJAMDAQIFADBvMQswCQYDVQQGEwJERTE9MDsGA1UEChQ0UmVndWxp" + "ZXJ1bmdzYmVoyG9yZGUgZsh1ciBUZWxla29tbXVuaWthdGlvbiB1bmQgUG9z" + "dDEhMAwGBwKCBgEKBxQTATEwEQYDVQQDFAo3Ui1DQSAxOlBOMCIYDzIwMDEx" + "MDE1MTMzNDE0WhgPMjAwNTA2MDEwOTUyMTdaMG8xCzAJBgNVBAYTAkRFMT0w" + "OwYDVQQKFDRSZWd1bGllcnVuZ3NiZWjIb3JkZSBmyHVyIFRlbGVrb21tdW5p" + "a2F0aW9uIHVuZCBQb3N0MSEwDAYHAoIGAQoHFBMBMTARBgNVBAMUCjZSLUNh" + "IDE6UE4wgaEwDQYJKoZIhvcNAQEBBQADgY8AMIGLAoGBAIOiqxUkzVyqnvth" + "ihnltsE5m1Xn5TZKeR/2MQPStc5hJ+V4yptEtIx+Fn5rOoqT5VEVWhcE35wd" + "bPvgJyQFn5msmhPQT/6XSGOlrWRoFummXN9lQzAjCj1sgTcmoLCVQ5s5WpCA" + "OXFwVWu16qndz3sPItn3jJ0F3Kh3w79NglvPAgUAwAAAATAKBgYrJAMDAQIF" + "AAOBgQBi5W96UVDoNIRkCncqr1LLG9vF9SGBIkvFpLDIIbcvp+CXhlvsdCJl" + "0pt2QEPSDl4cmpOet+CxJTdTuMeBNXxhb7Dvualog69w/+K2JbPhZYxuVFZs" + "Zh5BkPn2FnbNu3YbJhE60aIkikr72J4XZsI5DxpZCGh6xyV/YPRdKSljFjCC" + "AlQwggHAoAMCAQICAwyDqzAKBgYrJAMDAQIFADBvMQswCQYDVQQGEwJERTE9" + "MDsGA1UEChQ0UmVndWxpZXJ1bmdzYmVoyG9yZGUgZsh1ciBUZWxla29tbXVu" + "aWthdGlvbiB1bmQgUG9zdDEhMAwGBwKCBgEKBxQTATEwEQYDVQQDFAo1Ui1D" + "QSAxOlBOMCIYDzIwMDAwMzIyMDk0MTI3WhgPMjAwNDAxMjExNjA0NTNaMG8x" + "CzAJBgNVBAYTAkRFMT0wOwYDVQQKFDRSZWd1bGllcnVuZ3NiZWjIb3JkZSBm" + "yHVyIFRlbGVrb21tdW5pa2F0aW9uIHVuZCBQb3N0MSEwDAYHAoIGAQoHFBMB" + "MTARBgNVBAMUCjRSLUNBIDE6UE4wgaEwDQYJKoZIhvcNAQEBBQADgY8AMIGL" + "AoGBAI8x26tmrFJanlm100B7KGlRemCD1R93PwdnG7svRyf5ZxOsdGrDszNg" + "xg6ouO8ZHQMT3NC2dH8TvO65Js+8bIyTm51azF6clEg0qeWNMKiiXbBXa+ph" + "hTkGbXiLYvACZ6/MTJMJ1lcrjpRF7BXtYeYMcEF6znD4pxOqrtbf9z5hAgUA" + "wAAAATAKBgYrJAMDAQIFAAOBgQB99BjSKlGPbMLQAgXlvA9jUsDNhpnVm3a1" + "YkfxSqS/dbQlYkbOKvCxkPGA9NBxisBM8l1zFynVjJoy++aysRmcnLY/sHaz" + "23BF2iU7WERy18H3lMBfYB6sXkfYiZtvQZcWaO48m73ZBySuiV3iXpb2wgs/" + "Cs20iqroAWxwq/W/9jCCAlMwggG/oAMCAQICBDsFZ9UwCgYGKyQDAwECBQAw" + "bzELMAkGA1UEBhMCREUxITAMBgcCggYBCgcUEwExMBEGA1UEAxQKNFItQ0Eg" + "MTpQTjE9MDsGA1UEChQ0UmVndWxpZXJ1bmdzYmVoyG9yZGUgZsh1ciBUZWxl" + "a29tbXVuaWthdGlvbiB1bmQgUG9zdDAiGA8xOTk5MDEyMTE3MzUzNFoYDzIw" + "MDQwMTIxMTYwMDAyWjBvMQswCQYDVQQGEwJERTE9MDsGA1UEChQ0UmVndWxp" + "ZXJ1bmdzYmVoyG9yZGUgZsh1ciBUZWxla29tbXVuaWthdGlvbiB1bmQgUG9z" + "dDEhMAwGBwKCBgEKBxQTATEwEQYDVQQDFAozUi1DQSAxOlBOMIGfMA0GCSqG" + "SIb3DQEBAQUAA4GNADCBiQKBgI4B557mbKQg/AqWBXNJhaT/6lwV93HUl4U8" + "u35udLq2+u9phns1WZkdM3gDfEpL002PeLfHr1ID/96dDYf04lAXQfombils" + "of1C1k32xOvxjlcrDOuPEMxz9/HDAQZA5MjmmYHAIulGI8Qg4Tc7ERRtg/hd" + "0QX0/zoOeXoDSEOBAgTAAAABMAoGBiskAwMBAgUAA4GBAIyzwfT3keHI/n2P" + "LrarRJv96mCohmDZNpUQdZTVjGu5VQjVJwk3hpagU0o/t/FkdzAjOdfEw8Ql" + "3WXhfIbNLv1YafMm2eWSdeYbLcbB5yJ1od+SYyf9+tm7cwfDAcr22jNRBqx8" + "wkWKtKDjWKkevaSdy99sAI8jebHtWz7jzydKMIID9TCCA16gAwIBAgICbMcw" + "DQYJKoZIhvcNAQEFBQAwSzELMAkGA1UEBhMCREUxEjAQBgNVBAoUCVNpZ250" + "cnVzdDEoMAwGBwKCBgEKBxQTATEwGAYDVQQDFBFDQSBTSUdOVFJVU1QgMTpQ" + "TjAeFw0wNDA3MzAxMzAyNDZaFw0wNzA3MzAxMzAyNDZaMDwxETAPBgNVBAMM" + "CFlhY29tOlBOMQ4wDAYDVQRBDAVZYWNvbTELMAkGA1UEBhMCREUxCjAIBgNV" + "BAUTATEwgZ8wDQYJKoZIhvcNAQEBBQADgY0AMIGJAoGBAIWzLlYLQApocXIp" + "pgCCpkkOUVLgcLYKeOd6/bXAnI2dTHQqT2bv7qzfUnYvOqiNgYdF13pOYtKg" + "XwXMTNFL4ZOI6GoBdNs9TQiZ7KEWnqnr2945HYx7UpgTBclbOK/wGHuCdcwO" + "x7juZs1ZQPFG0Lv8RoiV9s6HP7POqh1sO0P/AgMBAAGjggH1MIIB8TCBnAYD" + "VR0jBIGUMIGRgBQcZzNghfnXoXRm8h1+VITC5caNRqFzpHEwbzELMAkGA1UE" + "BhMCREUxPTA7BgNVBAoUNFJlZ3VsaWVydW5nc2JlaMhvcmRlIGbIdXIgVGVs" + "ZWtvbW11bmlrYXRpb24gdW5kIFBvc3QxITAMBgcCggYBCgcUEwExMBEGA1UE" + "AxQKNVItQ0EgMTpQToIEALs8rjAdBgNVHQ4EFgQU2e5KAzkVuKaM9I5heXkz" + "bcAIuR8wDgYDVR0PAQH/BAQDAgZAMBIGA1UdIAQLMAkwBwYFKyQIAQEwfwYD" + "VR0fBHgwdjB0oCygKoYobGRhcDovL2Rpci5zaWdudHJ1c3QuZGUvbz1TaWdu" + "dHJ1c3QsYz1kZaJEpEIwQDEdMBsGA1UEAxMUQ1JMU2lnblNpZ250cnVzdDE6" + "UE4xEjAQBgNVBAoTCVNpZ250cnVzdDELMAkGA1UEBhMCREUwYgYIKwYBBQUH" + "AQEEVjBUMFIGCCsGAQUFBzABhkZodHRwOi8vZGlyLnNpZ250cnVzdC5kZS9T" + "aWdudHJ1c3QvT0NTUC9zZXJ2bGV0L2h0dHBHYXRld2F5LlBvc3RIYW5kbGVy" + "MBgGCCsGAQUFBwEDBAwwCjAIBgYEAI5GAQEwDgYHAoIGAQoMAAQDAQH/MA0G" + "CSqGSIb3DQEBBQUAA4GBAHn1m3GcoyD5GBkKUY/OdtD6Sj38LYqYCF+qDbJR" + "6pqUBjY2wsvXepUppEler+stH8mwpDDSJXrJyuzf7xroDs4dkLl+Rs2x+2tg" + "BjU+ABkBDMsym2WpwgA8LCdymmXmjdv9tULxY+ec2pjSEzql6nEZNEfrU8nt" + "ZCSCavgqW4TtMYIBejCCAXYCAQEwUTBLMQswCQYDVQQGEwJERTESMBAGA1UE" + "ChQJU2lnbnRydXN0MSgwDAYHAoIGAQoHFBMBMTAYBgNVBAMUEUNBIFNJR05U" + "UlVTVCAxOlBOAgJsxzAJBgUrDgMCGgUAoIGAMBgGCSqGSIb3DQEJAzELBgkq" + "hkiG9w0BBwEwIwYJKoZIhvcNAQkEMRYEFIYfhPoyfGzkLWWSSLjaHb4HQmaK" + "MBwGCSqGSIb3DQEJBTEPFw0wNTAzMjQwNzM4MzVaMCEGBSskCAYFMRgWFi92" + "YXIvZmlsZXMvdG1wXzEvdGVzdDEwDQYJKoZIhvcNAQEFBQAEgYA2IvA8lhVz" + "VD5e/itUxbFboKxeKnqJ5n/KuO/uBCl1N14+7Z2vtw1sfkIG+bJdp3OY2Cmn" + "mrQcwsN99Vjal4cXVj8t+DJzFG9tK9dSLvD3q9zT/GQ0kJXfimLVwCa4NaSf" + "Qsu4xtG0Rav6bCcnzabAkKuNNvKtH8amSRzk870DBg=="); public static byte[] xtraCounterSig = Base64.decode( "MIIR/AYJKoZIhvcNAQcCoIIR7TCCEekCAQExCzAJBgUrDgMCGgUAMBoGCSqG" + "SIb3DQEHAaANBAtIZWxsbyB3b3JsZKCCDnkwggTPMIIDt6ADAgECAgRDnYD3" + "MA0GCSqGSIb3DQEBBQUAMFgxCzAJBgNVBAYTAklUMRowGAYDVQQKExFJbi5U" + "ZS5TLkEuIFMucC5BLjEtMCsGA1UEAxMkSW4uVGUuUy5BLiAtIENlcnRpZmlj" + "YXRpb24gQXV0aG9yaXR5MB4XDTA4MDkxMjExNDMxMloXDTEwMDkxMjExNDMx" + "MlowgdgxCzAJBgNVBAYTAklUMSIwIAYDVQQKDBlJbnRlc2EgUy5wLkEuLzA1" + "MjYyODkwMDE0MSowKAYDVQQLDCFCdXNpbmVzcyBDb2xsYWJvcmF0aW9uICYg" + "U2VjdXJpdHkxHjAcBgNVBAMMFU1BU1NJTUlMSUFOTyBaSUNDQVJESTERMA8G" + "A1UEBAwIWklDQ0FSREkxFTATBgNVBCoMDE1BU1NJTUlMSUFOTzEcMBoGA1UE" + "BRMTSVQ6WkNDTVNNNzZIMTRMMjE5WTERMA8GA1UELhMIMDAwMDI1ODUwgaAw" + "DQYJKoZIhvcNAQEBBQADgY4AMIGKAoGBALeJTjmyFgx1SIP6c2AuB/kuyHo5" + "j/prKELTALsFDimre/Hxr3wOSet1TdQfFzU8Lu+EJqgfV9cV+cI1yeH1rZs7" + "lei7L3tX/VR565IywnguX5xwvteASgWZr537Fkws50bvTEMyYOj1Tf3FZvZU" + "z4n4OD39KI4mfR9i1eEVIxR3AgQAizpNo4IBoTCCAZ0wHQYDVR0RBBYwFIES" + "emljY2FyZGlAaW50ZXNhLml0MC8GCCsGAQUFBwEDBCMwITAIBgYEAI5GAQEw" + "CwYGBACORgEDAgEUMAgGBgQAjkYBBDBZBgNVHSAEUjBQME4GBgQAizABATBE" + "MEIGCCsGAQUFBwIBFjZodHRwOi8vZS10cnVzdGNvbS5pbnRlc2EuaXQvY2Ff" + "cHViYmxpY2EvQ1BTX0lOVEVTQS5odG0wDgYDVR0PAQH/BAQDAgZAMIGDBgNV" + "HSMEfDB6gBQZCQOW0bjFWBt+EORuxPagEgkQqKFcpFowWDELMAkGA1UEBhMC" + "SVQxGjAYBgNVBAoTEUluLlRlLlMuQS4gUy5wLkEuMS0wKwYDVQQDEyRJbi5U" + "ZS5TLkEuIC0gQ2VydGlmaWNhdGlvbiBBdXRob3JpdHmCBDzRARMwOwYDVR0f" + "BDQwMjAwoC6gLIYqaHR0cDovL2UtdHJ1c3Rjb20uaW50ZXNhLml0L0NSTC9J" + "TlRFU0EuY3JsMB0GA1UdDgQWBBTf5ItL8KmQh541Dxt7YxcWI1254TANBgkq" + "hkiG9w0BAQUFAAOCAQEAgW+uL1CVWQepbC/wfCmR6PN37Sueb4xiKQj2mTD5" + "UZ5KQjpivy/Hbuf0NrfKNiDEhAvoHSPC31ebGiKuTMFNyZPHfPEUnyYGSxea" + "2w837aXJFr6utPNQGBRi89kH90sZDlXtOSrZI+AzJJn5QK3F9gjcayU2NZXQ" + "MJgRwYmFyn2w4jtox+CwXPQ9E5XgxiMZ4WDL03cWVXDLX00EOJwnDDMUNTRI" + "m9Zv+4SKTNlfFbi9UTBqWBySkDzAelsfB2U61oqc2h1xKmCtkGMmN9iZT+Qz" + "ZC/vaaT+hLEBFGAH2gwFrYc4/jTBKyBYeU1vsAxsibIoTs1Apgl6MH75qPDL" + "BzCCBM8wggO3oAMCAQICBEOdgPcwDQYJKoZIhvcNAQEFBQAwWDELMAkGA1UE" + "BhMCSVQxGjAYBgNVBAoTEUluLlRlLlMuQS4gUy5wLkEuMS0wKwYDVQQDEyRJ" + "bi5UZS5TLkEuIC0gQ2VydGlmaWNhdGlvbiBBdXRob3JpdHkwHhcNMDgwOTEy" + "MTE0MzEyWhcNMTAwOTEyMTE0MzEyWjCB2DELMAkGA1UEBhMCSVQxIjAgBgNV" + "BAoMGUludGVzYSBTLnAuQS4vMDUyNjI4OTAwMTQxKjAoBgNVBAsMIUJ1c2lu" + "ZXNzIENvbGxhYm9yYXRpb24gJiBTZWN1cml0eTEeMBwGA1UEAwwVTUFTU0lN" + "SUxJQU5PIFpJQ0NBUkRJMREwDwYDVQQEDAhaSUNDQVJESTEVMBMGA1UEKgwM" + "TUFTU0lNSUxJQU5PMRwwGgYDVQQFExNJVDpaQ0NNU003NkgxNEwyMTlZMREw" + "DwYDVQQuEwgwMDAwMjU4NTCBoDANBgkqhkiG9w0BAQEFAAOBjgAwgYoCgYEA" + "t4lOObIWDHVIg/pzYC4H+S7IejmP+msoQtMAuwUOKat78fGvfA5J63VN1B8X" + "NTwu74QmqB9X1xX5wjXJ4fWtmzuV6Lsve1f9VHnrkjLCeC5fnHC+14BKBZmv" + "nfsWTCznRu9MQzJg6PVN/cVm9lTPifg4Pf0ojiZ9H2LV4RUjFHcCBACLOk2j" + "ggGhMIIBnTAdBgNVHREEFjAUgRJ6aWNjYXJkaUBpbnRlc2EuaXQwLwYIKwYB" + "BQUHAQMEIzAhMAgGBgQAjkYBATALBgYEAI5GAQMCARQwCAYGBACORgEEMFkG" + "A1UdIARSMFAwTgYGBACLMAEBMEQwQgYIKwYBBQUHAgEWNmh0dHA6Ly9lLXRy" + "dXN0Y29tLmludGVzYS5pdC9jYV9wdWJibGljYS9DUFNfSU5URVNBLmh0bTAO" + "BgNVHQ8BAf8EBAMCBkAwgYMGA1UdIwR8MHqAFBkJA5bRuMVYG34Q5G7E9qAS" + "CRCooVykWjBYMQswCQYDVQQGEwJJVDEaMBgGA1UEChMRSW4uVGUuUy5BLiBT" + "LnAuQS4xLTArBgNVBAMTJEluLlRlLlMuQS4gLSBDZXJ0aWZpY2F0aW9uIEF1" + "dGhvcml0eYIEPNEBEzA7BgNVHR8ENDAyMDCgLqAshipodHRwOi8vZS10cnVz" + "dGNvbS5pbnRlc2EuaXQvQ1JML0lOVEVTQS5jcmwwHQYDVR0OBBYEFN/ki0vw" + "qZCHnjUPG3tjFxYjXbnhMA0GCSqGSIb3DQEBBQUAA4IBAQCBb64vUJVZB6ls" + "L/B8KZHo83ftK55vjGIpCPaZMPlRnkpCOmK/L8du5/Q2t8o2IMSEC+gdI8Lf" + "V5saIq5MwU3Jk8d88RSfJgZLF5rbDzftpckWvq6081AYFGLz2Qf3SxkOVe05" + "Ktkj4DMkmflArcX2CNxrJTY1ldAwmBHBiYXKfbDiO2jH4LBc9D0TleDGIxnh" + "YMvTdxZVcMtfTQQ4nCcMMxQ1NEib1m/7hIpM2V8VuL1RMGpYHJKQPMB6Wx8H" + "ZTrWipzaHXEqYK2QYyY32JlP5DNkL+9ppP6EsQEUYAfaDAWthzj+NMErIFh5" + "TW+wDGyJsihOzUCmCXowfvmo8MsHMIIEzzCCA7egAwIBAgIEQ52A9zANBgkq" + "hkiG9w0BAQUFADBYMQswCQYDVQQGEwJJVDEaMBgGA1UEChMRSW4uVGUuUy5B" + "LiBTLnAuQS4xLTArBgNVBAMTJEluLlRlLlMuQS4gLSBDZXJ0aWZpY2F0aW9u" + "IEF1dGhvcml0eTAeFw0wODA5MTIxMTQzMTJaFw0xMDA5MTIxMTQzMTJaMIHY" + "MQswCQYDVQQGEwJJVDEiMCAGA1UECgwZSW50ZXNhIFMucC5BLi8wNTI2Mjg5" + "MDAxNDEqMCgGA1UECwwhQnVzaW5lc3MgQ29sbGFib3JhdGlvbiAmIFNlY3Vy" + "aXR5MR4wHAYDVQQDDBVNQVNTSU1JTElBTk8gWklDQ0FSREkxETAPBgNVBAQM" + "CFpJQ0NBUkRJMRUwEwYDVQQqDAxNQVNTSU1JTElBTk8xHDAaBgNVBAUTE0lU" + "OlpDQ01TTTc2SDE0TDIxOVkxETAPBgNVBC4TCDAwMDAyNTg1MIGgMA0GCSqG" + "SIb3DQEBAQUAA4GOADCBigKBgQC3iU45shYMdUiD+nNgLgf5Lsh6OY/6ayhC" + "0wC7BQ4pq3vx8a98DknrdU3UHxc1PC7vhCaoH1fXFfnCNcnh9a2bO5Xouy97" + "V/1UeeuSMsJ4Ll+ccL7XgEoFma+d+xZMLOdG70xDMmDo9U39xWb2VM+J+Dg9" + "/SiOJn0fYtXhFSMUdwIEAIs6TaOCAaEwggGdMB0GA1UdEQQWMBSBEnppY2Nh" + "cmRpQGludGVzYS5pdDAvBggrBgEFBQcBAwQjMCEwCAYGBACORgEBMAsGBgQA" + "jkYBAwIBFDAIBgYEAI5GAQQwWQYDVR0gBFIwUDBOBgYEAIswAQEwRDBCBggr" + "BgEFBQcCARY2aHR0cDovL2UtdHJ1c3Rjb20uaW50ZXNhLml0L2NhX3B1YmJs" + "aWNhL0NQU19JTlRFU0EuaHRtMA4GA1UdDwEB/wQEAwIGQDCBgwYDVR0jBHww" + "eoAUGQkDltG4xVgbfhDkbsT2oBIJEKihXKRaMFgxCzAJBgNVBAYTAklUMRow" + "GAYDVQQKExFJbi5UZS5TLkEuIFMucC5BLjEtMCsGA1UEAxMkSW4uVGUuUy5B" + "LiAtIENlcnRpZmljYXRpb24gQXV0aG9yaXR5ggQ80QETMDsGA1UdHwQ0MDIw" + "MKAuoCyGKmh0dHA6Ly9lLXRydXN0Y29tLmludGVzYS5pdC9DUkwvSU5URVNB" + "LmNybDAdBgNVHQ4EFgQU3+SLS/CpkIeeNQ8be2MXFiNdueEwDQYJKoZIhvcN" + "AQEFBQADggEBAIFvri9QlVkHqWwv8Hwpkejzd+0rnm+MYikI9pkw+VGeSkI6" + "Yr8vx27n9Da3yjYgxIQL6B0jwt9XmxoirkzBTcmTx3zxFJ8mBksXmtsPN+2l" + "yRa+rrTzUBgUYvPZB/dLGQ5V7Tkq2SPgMySZ+UCtxfYI3GslNjWV0DCYEcGJ" + "hcp9sOI7aMfgsFz0PROV4MYjGeFgy9N3FlVwy19NBDicJwwzFDU0SJvWb/uE" + "ikzZXxW4vVEwalgckpA8wHpbHwdlOtaKnNodcSpgrZBjJjfYmU/kM2Qv72mk" + "/oSxARRgB9oMBa2HOP40wSsgWHlNb7AMbImyKE7NQKYJejB++ajwywcxggM8" + "MIIDOAIBATBgMFgxCzAJBgNVBAYTAklUMRowGAYDVQQKExFJbi5UZS5TLkEu" + "IFMucC5BLjEtMCsGA1UEAxMkSW4uVGUuUy5BLiAtIENlcnRpZmljYXRpb24g" + "QXV0aG9yaXR5AgRDnYD3MAkGBSsOAwIaBQAwDQYJKoZIhvcNAQEBBQAEgYB+" + "lH2cwLqc91mP8prvgSV+RRzk13dJdZvdoVjgQoFrPhBiZCNIEoHvIhMMA/sM" + "X6euSRZk7EjD24FasCEGYyd0mJVLEy6TSPmuW+wWz/28w3a6IWXBGrbb/ild" + "/CJMkPgLPGgOVD1WDwiNKwfasiQSFtySf5DPn3jFevdLeMmEY6GCAjIwggEV" + "BgkqhkiG9w0BCQYxggEGMIIBAgIBATBgMFgxCzAJBgNVBAYTAklUMRowGAYD" + "VQQKExFJbi5UZS5TLkEuIFMucC5BLjEtMCsGA1UEAxMkSW4uVGUuUy5BLiAt" + "IENlcnRpZmljYXRpb24gQXV0aG9yaXR5AgRDnYD3MAkGBSsOAwIaBQAwDQYJ" + "KoZIhvcNAQEBBQAEgYBHlOULfT5GDigIvxP0qZOy8VbpntmzaPF55VV4buKV" + "35J+uHp98gXKp0LrHM69V5IRKuyuQzHHFBqsXxsRI9o6KoOfgliD9Xc+BeMg" + "dKzQhBhBYoFREq8hQM0nSbqDNHYAQyNHMzUA/ZQUO5dlFuH8Dw3iDYAhNtfd" + "PrlchKJthDCCARUGCSqGSIb3DQEJBjGCAQYwggECAgEBMGAwWDELMAkGA1UE" + "BhMCSVQxGjAYBgNVBAoTEUluLlRlLlMuQS4gUy5wLkEuMS0wKwYDVQQDEyRJ" + "bi5UZS5TLkEuIC0gQ2VydGlmaWNhdGlvbiBBdXRob3JpdHkCBEOdgPcwCQYF" + "Kw4DAhoFADANBgkqhkiG9w0BAQEFAASBgEeU5Qt9PkYOKAi/E/Spk7LxVume" + "2bNo8XnlVXhu4pXfkn64en3yBcqnQusczr1XkhEq7K5DMccUGqxfGxEj2joq" + "g5+CWIP1dz4F4yB0rNCEGEFigVESryFAzSdJuoM0dgBDI0czNQD9lBQ7l2UW" + "4fwPDeINgCE2190+uVyEom2E"); byte[] noSignedAttrSample2 = Base64.decode( "MIIIlAYJKoZIhvcNAQcCoIIIhTCCCIECAQExCzAJBgUrDgMCGgUAMAsGCSqG" + "SIb3DQEHAaCCB3UwggOtMIIDa6ADAgECAgEzMAsGByqGSM44BAMFADCBkDEL" + "MAkGA1UEBhMCVVMxCzAJBgNVBAgTAkNBMRIwEAYDVQQHEwlQYWxvIEFsdG8x" + "HTAbBgNVBAoTFFN1biBNaWNyb3N5c3RlbXMgSW5jMSMwIQYDVQQLExpKYXZh" + "IFNvZnR3YXJlIENvZGUgU2lnbmluZzEcMBoGA1UEAxMTSkNFIENvZGUgU2ln" + "bmluZyBDQTAeFw0wMTA1MjkxNjQ3MTFaFw0wNjA1MjgxNjQ3MTFaMG4xHTAb" + "BgNVBAoTFFN1biBNaWNyb3N5c3RlbXMgSW5jMSMwIQYDVQQLExpKYXZhIFNv" + "ZnR3YXJlIENvZGUgU2lnbmluZzEoMCYGA1UEAxMfVGhlIExlZ2lvbiBvZiB0" + "aGUgQm91bmN5IENhc3RsZTCCAbcwggEsBgcqhkjOOAQBMIIBHwKBgQD9f1OB" + "HXUSKVLfSpwu7OTn9hG3UjzvRADDHj+AtlEmaUVdQCJR+1k9jVj6v8X1ujD2" + "y5tVbNeBO4AdNG/yZmC3a5lQpaSfn+gEexAiwk+7qdf+t8Yb+DtX58aophUP" + "BPuD9tPFHsMCNVQTWhaRMvZ1864rYdcq7/IiAxmd0UgBxwIVAJdgUI8VIwvM" + "spK5gqLrhAvwWBz1AoGBAPfhoIXWmz3ey7yrXDa4V7l5lK+7+jrqgvlXTAs9" + "B4JnUVlXjrrUWU/mcQcQgYC0SRZxI+hMKBYTt88JMozIpuE8FnqLVHyNKOCj" + "rh4rs6Z1kW6jfwv6ITVi8ftiegEkO8yk8b6oUZCJqIPf4VrlnwaSi2ZegHtV" + "JWQBTDv+z0kqA4GEAAKBgBWry/FCAZ6miyy39+ftsa+h9lxoL+JtV0MJcUyQ" + "E4VAhpAwWb8vyjba9AwOylYQTktHX5sAkFvjBiU0LOYDbFSTVZSHMRJgfjxB" + "SHtICjOEvr1BJrrOrdzqdxcOUge5n7El124BCrv91x5Ol8UTwtiO9LrRXF/d" + "SyK+RT5n1klRo3YwdDARBglghkgBhvhCAQEEBAMCAIcwDgYDVR0PAQH/BAQD" + "AgHGMB0GA1UdDgQWBBQwMY4NRcco1AO3w1YsokfDLVseEjAPBgNVHRMBAf8E" + "BTADAQH/MB8GA1UdIwQYMBaAFGXi9IbJ007wkU5Yomr12HhamsGmMAsGByqG" + "SM44BAMFAAMvADAsAhRmigTu6QV0sTfEkVljgij/hhdVfAIUQZvMxAnIHc30" + "y/u0C1T5UEG9glUwggPAMIIDfqADAgECAgEQMAsGByqGSM44BAMFADCBkDEL" + "MAkGA1UEBhMCVVMxCzAJBgNVBAgTAkNBMRIwEAYDVQQHEwlQYWxvIEFsdG8x" + "HTAbBgNVBAoTFFN1biBNaWNyb3N5c3RlbXMgSW5jMSMwIQYDVQQLExpKYXZh" + "IFNvZnR3YXJlIENvZGUgU2lnbmluZzEcMBoGA1UEAxMTSkNFIENvZGUgU2ln" + "bmluZyBDQTAeFw0wMTA0MjUwNzAwMDBaFw0yMDA0MjUwNzAwMDBaMIGQMQsw" + "CQYDVQQGEwJVUzELMAkGA1UECBMCQ0ExEjAQBgNVBAcTCVBhbG8gQWx0bzEd" + "MBsGA1UEChMUU3VuIE1pY3Jvc3lzdGVtcyBJbmMxIzAhBgNVBAsTGkphdmEg" + "U29mdHdhcmUgQ29kZSBTaWduaW5nMRwwGgYDVQQDExNKQ0UgQ29kZSBTaWdu" + "aW5nIENBMIIBtzCCASwGByqGSM44BAEwggEfAoGBAOuvNwQeylEeaV2w8o/2" + "tUkfxqSZBdcpv3S3avUZ2B7kG/gKAZqY/3Cr4kpWhmxTs/zhyIGMMfDE87CL" + "5nAG7PdpaNuDTHIpiSk2F1w7SgegIAIqRpdRHXDICBgLzgxum3b3BePn+9Nh" + "eeFgmiSNBpWDPFEg4TDPOFeCphpyDc7TAhUAhCVF4bq5qWKreehbMLiJaxv/" + "e3UCgYEAq8l0e3Tv7kK1alNNO92QBnJokQ8LpCl2LlU71a5NZVx+KjoEpmem" + "0HGqpde34sFyDaTRqh6SVEwgAAmisAlBGTMAssNcrkL4sYvKfJbYEH83RFuq" + "zHjI13J2N2tAmahVZvqoAx6LShECactMuCUGHKB30sms0j3pChD6dnC3+9wD" + "gYQAAoGALQmYXKy4nMeZfu4gGSo0kPnXq6uu3WtylQ1m+O8nj0Sy7ShEx/6v" + "sKYnbwBnRYJbB6hWVjvSKVFhXmk51y50dxLPGUr1LcjLcmHETm/6R0M/FLv6" + "vBhmKMLZZot6LS/CYJJLFP5YPiF/aGK+bEhJ+aBLXoWdGRD5FUVRG3HU9wuj" + "ZjBkMBEGCWCGSAGG+EIBAQQEAwIABzAPBgNVHRMBAf8EBTADAQH/MB8GA1Ud" + "IwQYMBaAFGXi9IbJ007wkU5Yomr12HhamsGmMB0GA1UdDgQWBBRl4vSGydNO" + "8JFOWKJq9dh4WprBpjALBgcqhkjOOAQDBQADLwAwLAIUKvfPPJdd+Xi2CNdB" + "tNkNRUzktJwCFEXNdWkOIfod1rMpsun3Mx0z/fxJMYHoMIHlAgEBMIGWMIGQ" + "MQswCQYDVQQGEwJVUzELMAkGA1UECBMCQ0ExEjAQBgNVBAcTCVBhbG8gQWx0" + "bzEdMBsGA1UEChMUU3VuIE1pY3Jvc3lzdGVtcyBJbmMxIzAhBgNVBAsTGkph" + "dmEgU29mdHdhcmUgQ29kZSBTaWduaW5nMRwwGgYDVQQDExNKQ0UgQ29kZSBT" + "aWduaW5nIENBAgEzMAkGBSsOAwIaBQAwCwYHKoZIzjgEAQUABC8wLQIVAIGV" + "khm+kbV4a/+EP45PHcq0hIViAhR4M9os6IrJnoEDS3Y3l7O6zrSosA=="); private JcaX509CertSelectorConverter selectorConverter = new JcaX509CertSelectorConverter(); /* * * INFRASTRUCTURE * */ public SignedDataTest(String name) { super(name); } public static void main(String args[]) { junit.textui.TestRunner.run(SignedDataTest.class); } public static Test suite() throws Exception { init(); return new CMSTestSetup(new TestSuite(SignedDataTest.class)); } private static void init() throws Exception { if (!_initialised) { _initialised = true; _origDN = "O=Bouncy Castle, C=AU"; _origKP = CMSTestUtil.makeKeyPair(); _origCert = CMSTestUtil.makeCertificate(_origKP, _origDN, _origKP, _origDN); _signDN = "CN=Bob, OU=Sales, O=Bouncy Castle, C=AU"; _signKP = CMSTestUtil.makeKeyPair(); _signCert = CMSTestUtil.makeCertificate(_signKP, _signDN, _origKP, _origDN); _signGostKP = CMSTestUtil.makeGostKeyPair(); _signGostCert = CMSTestUtil.makeCertificate(_signGostKP, _signDN, _origKP, _origDN); _signDsaKP = CMSTestUtil.makeDsaKeyPair(); _signDsaCert = CMSTestUtil.makeCertificate(_signDsaKP, _signDN, _origKP, _origDN); _signEcDsaKP = CMSTestUtil.makeEcDsaKeyPair(); _signEcDsaCert = CMSTestUtil.makeCertificate(_signEcDsaKP, _signDN, _origKP, _origDN); _signEcGostKP = CMSTestUtil.makeEcGostKeyPair(); _signEcGostCert = CMSTestUtil.makeCertificate(_signEcGostKP, _signDN, _origKP, _origDN); _reciDN = "CN=Doug, OU=Sales, O=Bouncy Castle, C=AU"; _reciKP = CMSTestUtil.makeKeyPair(); _reciCert = CMSTestUtil.makeCertificate(_reciKP, _reciDN, _signKP, _signDN); _signCrl = CMSTestUtil.makeCrl(_signKP); } } private void verifySignatures(CMSSignedData s, byte[] contentDigest) throws Exception { CertStore certStore = s.getCertificatesAndCRLs("Collection", BC); SignerInformationStore signers = s.getSignerInfos(); Collection c = signers.getSigners(); Iterator it = c.iterator(); while (it.hasNext()) { SignerInformation signer = (SignerInformation)it.next(); Collection certCollection = certStore.getCertificates(selectorConverter.getCertSelector(signer.getSID())); Iterator certIt = certCollection.iterator(); X509Certificate cert = (X509Certificate)certIt.next(); assertEquals(true, signer.verify(cert, BC)); if (contentDigest != null) { assertTrue(MessageDigest.isEqual(contentDigest, signer.getContentDigest())); } } Collection certColl = certStore.getCertificates(null); Collection crlColl = certStore.getCRLs(null); assertEquals(certColl.size(), s.getCertificates("Collection", BC).getMatches(null).size()); assertEquals(crlColl.size(), s.getCRLs("Collection", BC).getMatches(null).size()); } private void verifySignatures(CMSSignedData s) throws Exception { verifySignatures(s, null); } public void testDetachedVerification() throws Exception { byte[] data = "Hello World!".getBytes(); List certList = new ArrayList(); CMSProcessable msg = new CMSProcessableByteArray(data); certList.add(_origCert); certList.add(_signCert); CertStore certs = CertStore.getInstance("Collection", new CollectionCertStoreParameters(certList), BC); CMSSignedDataGenerator gen = new CMSSignedDataGenerator(); gen.addSigner(_origKP.getPrivate(), _origCert, CMSSignedDataGenerator.DIGEST_SHA1); gen.addSigner(_origKP.getPrivate(), _origCert, CMSSignedDataGenerator.DIGEST_MD5); gen.addCertificatesAndCRLs(certs); CMSSignedData s = gen.generate(msg, BC); MessageDigest sha1 = MessageDigest.getInstance("SHA1", BC); MessageDigest md5 = MessageDigest.getInstance("MD5", BC); Map hashes = new HashMap(); byte[] sha1Hash = sha1.digest(data); byte[] md5Hash = md5.digest(data); hashes.put(CMSSignedDataGenerator.DIGEST_SHA1, sha1Hash); hashes.put(CMSSignedDataGenerator.DIGEST_MD5, md5Hash); s = new CMSSignedData(hashes, s.getEncoded()); verifySignatures(s, null); } public void testSHA1AndMD5WithRSAEncapsulatedRepeated() throws Exception { List certList = new ArrayList(); CMSProcessable msg = new CMSProcessableByteArray("Hello World!".getBytes()); certList.add(_origCert); certList.add(_signCert); CertStore certs = CertStore.getInstance("Collection", new CollectionCertStoreParameters(certList), BC); CMSSignedDataGenerator gen = new CMSSignedDataGenerator(); gen.addSigner(_origKP.getPrivate(), _origCert, CMSSignedDataGenerator.DIGEST_SHA1); gen.addSigner(_origKP.getPrivate(), _origCert, CMSSignedDataGenerator.DIGEST_MD5); gen.addCertificatesAndCRLs(certs); CMSSignedData s = gen.generate(msg, true, BC); ByteArrayInputStream bIn = new ByteArrayInputStream(s.getEncoded()); ASN1InputStream aIn = new ASN1InputStream(bIn); s = new CMSSignedData(ContentInfo.getInstance(aIn.readObject())); certs = s.getCertificatesAndCRLs("Collection", BC); SignerInformationStore signers = s.getSignerInfos(); assertEquals(2, signers.size()); Collection c = signers.getSigners(); Iterator it = c.iterator(); SignerId sid = null; while (it.hasNext()) { SignerInformation signer = (SignerInformation)it.next(); Collection certCollection = certs.getCertificates(selectorConverter.getCertSelector(signer.getSID())); Iterator certIt = certCollection.iterator(); X509Certificate cert = (X509Certificate)certIt.next(); sid = signer.getSID(); assertEquals(true, signer.verify(cert, BC)); // // check content digest // byte[] contentDigest = (byte[])gen.getGeneratedDigests().get(signer.getDigestAlgOID()); AttributeTable table = signer.getSignedAttributes(); Attribute hash = table.get(CMSAttributes.messageDigest); assertTrue(MessageDigest.isEqual(contentDigest, ((ASN1OctetString)hash.getAttrValues().getObjectAt(0)).getOctets())); } c = signers.getSigners(sid); assertEquals(2, c.size()); // // try using existing signer // gen = new CMSSignedDataGenerator(); gen.addSigners(s.getSignerInfos()); gen.addCertificatesAndCRLs(s.getCertificatesAndCRLs("Collection", BC)); s = gen.generate(msg, true, BC); bIn = new ByteArrayInputStream(s.getEncoded()); aIn = new ASN1InputStream(bIn); s = new CMSSignedData(ContentInfo.getInstance(aIn.readObject())); certs = s.getCertificatesAndCRLs("Collection", BC); signers = s.getSignerInfos(); c = signers.getSigners(); it = c.iterator(); assertEquals(2, c.size()); while (it.hasNext()) { SignerInformation signer = (SignerInformation)it.next(); Collection certCollection = certs.getCertificates(selectorConverter.getCertSelector(signer.getSID())); Iterator certIt = certCollection.iterator(); X509Certificate cert = (X509Certificate)certIt.next(); assertEquals(true, signer.verify(cert, BC)); } checkSignerStoreReplacement(s, signers); } public void testSHA1WithRSANoAttributes() throws Exception { List certList = new ArrayList(); CMSProcessable msg = new CMSProcessableByteArray("Hello world!".getBytes()); certList.add(_origCert); certList.add(_signCert); CertStore certs = CertStore.getInstance("Collection", new CollectionCertStoreParameters(certList), BC); CMSSignedDataGenerator gen = new CMSSignedDataGenerator(); gen.addSigner(_origKP.getPrivate(), _origCert, CMSSignedDataGenerator.DIGEST_SHA1); gen.addCertificatesAndCRLs(certs); CMSSignedData s = gen.generate(CMSSignedDataGenerator.DATA, msg, false, BC, false); // // compute expected content digest // MessageDigest md = MessageDigest.getInstance("SHA1", BC); verifySignatures(s, md.digest("Hello world!".getBytes())); } public void testSHA1WithRSAViaConfig() throws Exception { List certList = new ArrayList(); CMSProcessable msg = new CMSProcessableByteArray("Hello world!".getBytes()); certList.add(_origCert); certList.add(_signCert); CertStore certs = CertStore.getInstance("Collection", new CollectionCertStoreParameters(certList), BC); // set some bogus mappings. CMSConfig.setSigningEncryptionAlgorithmMapping(PKCSObjectIdentifiers.rsaEncryption.getId(), "XXXX"); CMSConfig.setSigningDigestAlgorithmMapping(OIWObjectIdentifiers.idSHA1.getId(), "YYYY"); CMSSignedDataGenerator gen = new CMSSignedDataGenerator(); gen.addSigner(_origKP.getPrivate(), _origCert, CMSSignedDataGenerator.DIGEST_SHA1); gen.addCertificatesAndCRLs(certs); CMSSignedData s; try { // try the bogus mappings s = gen.generate(CMSSignedDataGenerator.DATA, msg, false, BC, false); } catch (NoSuchAlgorithmException e) { if (!e.getMessage().startsWith("Unknown signature type requested: YYYYWITHXXXX")) { throw e; } } finally { // reset to the real ones CMSConfig.setSigningEncryptionAlgorithmMapping(PKCSObjectIdentifiers.rsaEncryption.getId(), "RSA"); CMSConfig.setSigningDigestAlgorithmMapping(OIWObjectIdentifiers.idSHA1.getId(), "SHA1"); } s = gen.generate(CMSSignedDataGenerator.DATA, msg, false, BC, false); // // compute expected content digest // MessageDigest md = MessageDigest.getInstance("SHA1", BC); verifySignatures(s, md.digest("Hello world!".getBytes())); } public void testSHA1WithRSAAndAttributeTable() throws Exception { MessageDigest md = MessageDigest.getInstance("SHA1", BC); List certList = new ArrayList(); CMSProcessable msg = new CMSProcessableByteArray("Hello world!".getBytes()); certList.add(_origCert); certList.add(_signCert); CertStore certs = CertStore.getInstance("Collection", new CollectionCertStoreParameters(certList), BC); CMSSignedDataGenerator gen = new CMSSignedDataGenerator(); Attribute attr = new Attribute(CMSAttributes.messageDigest, new DERSet( new DEROctetString( md.digest("Hello world!".getBytes())))); ASN1EncodableVector v = new ASN1EncodableVector(); v.add(attr); gen.addSigner(_origKP.getPrivate(), _origCert, CMSSignedDataGenerator.DIGEST_SHA1, new AttributeTable(v), null); gen.addCertificatesAndCRLs(certs); CMSSignedData s = gen.generate(CMSSignedDataGenerator.DATA, null, false, BC); // // the signature is detached, so need to add msg before passing on // s = new CMSSignedData(msg, s.getEncoded()); // // compute expected content digest // verifySignatures(s, md.digest("Hello world!".getBytes())); } public void testSHA1WithRSAEncapsulated() throws Exception { encapsulatedTest(_signKP, _signCert, CMSSignedDataGenerator.DIGEST_SHA1); } public void testSHA1WithRSAEncapsulatedSubjectKeyID() throws Exception { subjectKeyIDTest(_signKP, _signCert, CMSSignedDataGenerator.DIGEST_SHA1); } public void testSHA1WithRSAPSS() throws Exception { rsaPSSTest("SHA1", CMSSignedDataGenerator.DIGEST_SHA1); } public void testSHA224WithRSAPSS() throws Exception { rsaPSSTest("SHA224", CMSSignedDataGenerator.DIGEST_SHA224); } public void testSHA256WithRSAPSS() throws Exception { rsaPSSTest("SHA256", CMSSignedDataGenerator.DIGEST_SHA256); } public void testSHA384WithRSAPSS() throws Exception { rsaPSSTest("SHA384", CMSSignedDataGenerator.DIGEST_SHA384); } public void testSHA224WithRSAEncapsulated() throws Exception { encapsulatedTest(_signKP, _signCert, CMSSignedDataGenerator.DIGEST_SHA224); } public void testSHA256WithRSAEncapsulated() throws Exception { encapsulatedTest(_signKP, _signCert, CMSSignedDataGenerator.DIGEST_SHA256); } public void testRIPEMD128WithRSAEncapsulated() throws Exception { encapsulatedTest(_signKP, _signCert, CMSSignedDataGenerator.DIGEST_RIPEMD128); } public void testRIPEMD160WithRSAEncapsulated() throws Exception { encapsulatedTest(_signKP, _signCert, CMSSignedDataGenerator.DIGEST_RIPEMD160); } public void testRIPEMD256WithRSAEncapsulated() throws Exception { encapsulatedTest(_signKP, _signCert, CMSSignedDataGenerator.DIGEST_RIPEMD256); } public void testECDSAEncapsulated() throws Exception { encapsulatedTest(_signEcDsaKP, _signEcDsaCert, CMSSignedDataGenerator.DIGEST_SHA1); } public void testECDSAEncapsulatedSubjectKeyID() throws Exception { subjectKeyIDTest(_signEcDsaKP, _signEcDsaCert, CMSSignedDataGenerator.DIGEST_SHA1); } public void testECDSASHA224Encapsulated() throws Exception { encapsulatedTest(_signEcDsaKP, _signEcDsaCert, CMSSignedDataGenerator.DIGEST_SHA224); } public void testECDSASHA256Encapsulated() throws Exception { encapsulatedTest(_signEcDsaKP, _signEcDsaCert, CMSSignedDataGenerator.DIGEST_SHA256); } public void testECDSASHA384Encapsulated() throws Exception { encapsulatedTest(_signEcDsaKP, _signEcDsaCert, CMSSignedDataGenerator.DIGEST_SHA384); } public void testECDSASHA512Encapsulated() throws Exception { encapsulatedTest(_signEcDsaKP, _signEcDsaCert, CMSSignedDataGenerator.DIGEST_SHA512); } public void testECDSASHA512EncapsulatedWithKeyFactoryAsEC() throws Exception { X509EncodedKeySpec pubSpec = new X509EncodedKeySpec(_signEcDsaKP.getPublic().getEncoded()); PKCS8EncodedKeySpec privSpec = new PKCS8EncodedKeySpec(_signEcDsaKP.getPrivate().getEncoded()); KeyFactory keyFact = KeyFactory.getInstance("EC", BC); KeyPair kp = new KeyPair(keyFact.generatePublic(pubSpec), keyFact.generatePrivate(privSpec)); encapsulatedTest(kp, _signEcDsaCert, CMSSignedDataGenerator.DIGEST_SHA512); } public void testDSAEncapsulated() throws Exception { encapsulatedTest(_signDsaKP, _signDsaCert, CMSSignedDataGenerator.DIGEST_SHA1); } public void testDSAEncapsulatedSubjectKeyID() throws Exception { subjectKeyIDTest(_signDsaKP, _signDsaCert, CMSSignedDataGenerator.DIGEST_SHA1); } public void testGOST3411WithGOST3410Encapsulated() throws Exception { encapsulatedTest(_signGostKP, _signGostCert, CMSSignedDataGenerator.DIGEST_GOST3411); } public void testGOST3411WithECGOST3410Encapsulated() throws Exception { encapsulatedTest(_signEcGostKP, _signEcGostCert, CMSSignedDataGenerator.DIGEST_GOST3411); } public void testSHA1WithRSACounterSignature() throws Exception { List certList = new ArrayList(); CMSProcessable msg = new CMSProcessableByteArray("Hello World!".getBytes()); certList.add(_signCert); certList.add(_origCert); certList.add(_signCrl); CertStore certsAndCrls = CertStore.getInstance("Collection", new CollectionCertStoreParameters(certList), BC); CMSSignedDataGenerator gen = new CMSSignedDataGenerator(); gen.addSigner(_signKP.getPrivate(), _signCert, CMSSignedDataGenerator.DIGEST_SHA1); gen.addCertificatesAndCRLs(certsAndCrls); CMSSignedData s = gen.generate(msg, true, BC); SignerInformation origSigner = (SignerInformation)s.getSignerInfos().getSigners().toArray()[0]; SignerInformationStore counterSigners1 = gen.generateCounterSigners(origSigner, BC); SignerInformationStore counterSigners2 = gen.generateCounterSigners(origSigner, BC); SignerInformation signer1 = SignerInformation.addCounterSigners(origSigner, counterSigners1); SignerInformation signer2 = SignerInformation.addCounterSigners(signer1, counterSigners2); SignerInformationStore cs = signer2.getCounterSignatures(); Collection csSigners = cs.getSigners(); assertEquals(2, csSigners.size()); Iterator it = csSigners.iterator(); while (it.hasNext()) { SignerInformation cSigner = (SignerInformation)it.next(); Collection certCollection = certsAndCrls.getCertificates(selectorConverter.getCertSelector(cSigner.getSID())); Iterator certIt = certCollection.iterator(); X509Certificate cert = (X509Certificate)certIt.next(); assertNull(cSigner.getSignedAttributes().get(PKCSObjectIdentifiers.pkcs_9_at_contentType)); assertEquals(true, cSigner.verify(cert, BC)); } } private void rsaPSSTest(String digestName, String digestOID) throws Exception { List certList = new ArrayList(); CMSProcessable msg = new CMSProcessableByteArray("Hello world!".getBytes()); certList.add(_origCert); certList.add(_signCert); CertStore certs = CertStore.getInstance("Collection", new CollectionCertStoreParameters(certList), BC); CMSSignedDataGenerator gen = new CMSSignedDataGenerator(); gen.addSigner(_origKP.getPrivate(), _origCert, CMSSignedDataGenerator.ENCRYPTION_RSA_PSS, digestOID); gen.addCertificatesAndCRLs(certs); CMSSignedData s = gen.generate(CMSSignedDataGenerator.DATA, msg, false, BC, false); // // compute expected content digest // MessageDigest md = MessageDigest.getInstance(digestName, BC); verifySignatures(s, md.digest("Hello world!".getBytes())); } private void subjectKeyIDTest( KeyPair signaturePair, X509Certificate signatureCert, String digestAlgorithm) throws Exception { List certList = new ArrayList(); CMSProcessable msg = new CMSProcessableByteArray("Hello World!".getBytes()); certList.add(signatureCert); certList.add(_origCert); certList.add(_signCrl); CertStore certsAndCrls = CertStore.getInstance("Collection", new CollectionCertStoreParameters(certList), BC); CMSSignedDataGenerator gen = new CMSSignedDataGenerator(); gen.addSigner(signaturePair.getPrivate(), CMSTestUtil.createSubjectKeyId(signatureCert.getPublicKey()).getKeyIdentifier(), digestAlgorithm); gen.addCertificatesAndCRLs(certsAndCrls); CMSSignedData s = gen.generate(msg, true, BC); assertEquals(3, s.getVersion()); ByteArrayInputStream bIn = new ByteArrayInputStream(s.getEncoded()); ASN1InputStream aIn = new ASN1InputStream(bIn); s = new CMSSignedData(ContentInfo.getInstance(aIn.readObject())); certsAndCrls = s.getCertificatesAndCRLs("Collection", BC); SignerInformationStore signers = s.getSignerInfos(); Collection c = signers.getSigners(); Iterator it = c.iterator(); while (it.hasNext()) { SignerInformation signer = (SignerInformation)it.next(); Collection certCollection = certsAndCrls.getCertificates(selectorConverter.getCertSelector(signer.getSID())); Iterator certIt = certCollection.iterator(); X509Certificate cert = (X509Certificate)certIt.next(); assertEquals(true, signer.verify(cert, BC)); } // // check for CRLs // Collection crls = certsAndCrls.getCRLs(null); assertEquals(1, crls.size()); assertTrue(crls.contains(_signCrl)); // // try using existing signer // gen = new CMSSignedDataGenerator(); gen.addSigners(s.getSignerInfos()); gen.addCertificatesAndCRLs(s.getCertificatesAndCRLs("Collection", BC)); s = gen.generate(msg, true, BC); bIn = new ByteArrayInputStream(s.getEncoded()); aIn = new ASN1InputStream(bIn); s = new CMSSignedData(ContentInfo.getInstance(aIn.readObject())); certsAndCrls = s.getCertificatesAndCRLs("Collection", BC); signers = s.getSignerInfos(); c = signers.getSigners(); it = c.iterator(); while (it.hasNext()) { SignerInformation signer = (SignerInformation)it.next(); Collection certCollection = certsAndCrls.getCertificates(selectorConverter.getCertSelector(signer.getSID())); Iterator certIt = certCollection.iterator(); X509Certificate cert = (X509Certificate)certIt.next(); assertEquals(true, signer.verify(cert, BC)); } checkSignerStoreReplacement(s, signers); } private void encapsulatedTest( KeyPair signaturePair, X509Certificate signatureCert, String digestAlgorithm) throws Exception { List certList = new ArrayList(); CMSProcessable msg = new CMSProcessableByteArray("Hello World!".getBytes()); certList.add(signatureCert); certList.add(_origCert); certList.add(_signCrl); CertStore certsAndCrls = CertStore.getInstance("Collection", new CollectionCertStoreParameters(certList), BC); CMSSignedDataGenerator gen = new CMSSignedDataGenerator(); gen.addSigner(signaturePair.getPrivate(), signatureCert, digestAlgorithm); gen.addCertificatesAndCRLs(certsAndCrls); CMSSignedData s = gen.generate(msg, true, BC); ByteArrayInputStream bIn = new ByteArrayInputStream(s.getEncoded()); ASN1InputStream aIn = new ASN1InputStream(bIn); s = new CMSSignedData(ContentInfo.getInstance(aIn.readObject())); certsAndCrls = s.getCertificatesAndCRLs("Collection", BC); SignerInformationStore signers = s.getSignerInfos(); Collection c = signers.getSigners(); Iterator it = c.iterator(); while (it.hasNext()) { SignerInformation signer = (SignerInformation)it.next(); Collection certCollection = certsAndCrls.getCertificates(selectorConverter.getCertSelector(signer.getSID())); Iterator certIt = certCollection.iterator(); X509Certificate cert = (X509Certificate)certIt.next(); assertEquals(true, signer.verify(cert, BC)); } // // check for CRLs // Collection crls = certsAndCrls.getCRLs(null); assertEquals(1, crls.size()); assertTrue(crls.contains(_signCrl)); // // try using existing signer // gen = new CMSSignedDataGenerator(); gen.addSigners(s.getSignerInfos()); gen.addCertificatesAndCRLs(s.getCertificatesAndCRLs("Collection", BC)); s = gen.generate(msg, true, BC); bIn = new ByteArrayInputStream(s.getEncoded()); aIn = new ASN1InputStream(bIn); s = new CMSSignedData(ContentInfo.getInstance(aIn.readObject())); certsAndCrls = s.getCertificatesAndCRLs("Collection", BC); signers = s.getSignerInfos(); c = signers.getSigners(); it = c.iterator(); while (it.hasNext()) { SignerInformation signer = (SignerInformation)it.next(); Collection certCollection = certsAndCrls.getCertificates(selectorConverter.getCertSelector(signer.getSID())); Iterator certIt = certCollection.iterator(); X509Certificate cert = (X509Certificate)certIt.next(); assertEquals(true, signer.verify(cert, BC)); } checkSignerStoreReplacement(s, signers); } // // signerInformation store replacement test. // private void checkSignerStoreReplacement( CMSSignedData orig, SignerInformationStore signers) throws Exception { CMSSignedData s = CMSSignedData.replaceSigners(orig, signers); CertStore certs = s.getCertificatesAndCRLs("Collection", BC); signers = s.getSignerInfos(); Collection c = signers.getSigners(); Iterator it = c.iterator(); while (it.hasNext()) { SignerInformation signer = (SignerInformation)it.next(); Collection certCollection = certs.getCertificates(selectorConverter.getCertSelector(signer.getSID())); Iterator certIt = certCollection.iterator(); X509Certificate cert = (X509Certificate)certIt.next(); assertEquals(true, signer.verify(cert, BC)); } } public void testUnsortedAttributes() throws Exception { CMSSignedData s = new CMSSignedData(new CMSProcessableByteArray(disorderedMessage), disorderedSet); CertStore certs = s.getCertificatesAndCRLs("Collection", BC); SignerInformationStore signers = s.getSignerInfos(); Collection c = signers.getSigners(); Iterator it = c.iterator(); while (it.hasNext()) { SignerInformation signer = (SignerInformation)it.next(); Collection certCollection = certs.getCertificates(selectorConverter.getCertSelector(signer.getSID())); Iterator certIt = certCollection.iterator(); X509Certificate cert = (X509Certificate)certIt.next(); assertEquals(true, signer.verify(cert, BC)); } } public void testNullContentWithSigner() throws Exception { List certList = new ArrayList(); certList.add(_origCert); certList.add(_signCert); CertStore certs = CertStore.getInstance("Collection", new CollectionCertStoreParameters(certList), BC); CMSSignedDataGenerator gen = new CMSSignedDataGenerator(); gen.addSigner(_origKP.getPrivate(), _origCert, CMSSignedDataGenerator.DIGEST_SHA1); gen.addCertificatesAndCRLs(certs); CMSSignedData s = gen.generate(null, false, BC); ByteArrayInputStream bIn = new ByteArrayInputStream(s.getEncoded()); ASN1InputStream aIn = new ASN1InputStream(bIn); s = new CMSSignedData(ContentInfo.getInstance(aIn.readObject())); verifySignatures(s); } public void testWithAttributeCertificate() throws Exception { List certList = new ArrayList(); CMSProcessable msg = new CMSProcessableByteArray("Hello World!".getBytes()); certList.add(_signDsaCert); CertStore certs = CertStore.getInstance("Collection", new CollectionCertStoreParameters(certList), BC); CMSSignedDataGenerator gen = new CMSSignedDataGenerator(); gen.addSigner(_origKP.getPrivate(), _origCert, CMSSignedDataGenerator.DIGEST_SHA1); gen.addCertificatesAndCRLs(certs); X509AttributeCertificate attrCert = CMSTestUtil.getAttributeCertificate(); X509Store store = X509Store.getInstance("AttributeCertificate/Collection", new X509CollectionStoreParameters(Collections.singleton(attrCert)), BC); gen.addAttributeCertificates(store); CMSSignedData sd = gen.generate(msg, BC); assertEquals(4, sd.getVersion()); store = sd.getAttributeCertificates("Collection", BC); Collection coll = store.getMatches(null); assertEquals(1, coll.size()); assertTrue(coll.contains(attrCert)); // // create new certstore // certList = new ArrayList(); certList.add(_origCert); certList.add(_signCert); certs = CertStore.getInstance("Collection", new CollectionCertStoreParameters(certList), BC); // // replace certs // sd = CMSSignedData.replaceCertificatesAndCRLs(sd, certs); verifySignatures(sd); } public void testCertStoreReplacement() throws Exception { List certList = new ArrayList(); CMSProcessable msg = new CMSProcessableByteArray("Hello World!".getBytes()); certList.add(_signDsaCert); CertStore certs = CertStore.getInstance("Collection", new CollectionCertStoreParameters(certList), BC); CMSSignedDataGenerator gen = new CMSSignedDataGenerator(); gen.addSigner(_origKP.getPrivate(), _origCert, CMSSignedDataGenerator.DIGEST_SHA1); gen.addCertificatesAndCRLs(certs); CMSSignedData sd = gen.generate(msg, BC); // // create new certstore // certList = new ArrayList(); certList.add(_origCert); certList.add(_signCert); certs = CertStore.getInstance("Collection", new CollectionCertStoreParameters(certList), BC); // // replace certs // sd = CMSSignedData.replaceCertificatesAndCRLs(sd, certs); verifySignatures(sd); } public void testEncapsulatedCertStoreReplacement() throws Exception { List certList = new ArrayList(); CMSProcessable msg = new CMSProcessableByteArray("Hello World!".getBytes()); certList.add(_signDsaCert); CertStore certs = CertStore.getInstance("Collection", new CollectionCertStoreParameters(certList), BC); CMSSignedDataGenerator gen = new CMSSignedDataGenerator(); gen.addSigner(_origKP.getPrivate(), _origCert, CMSSignedDataGenerator.DIGEST_SHA1); gen.addCertificatesAndCRLs(certs); CMSSignedData sd = gen.generate(msg, true, BC); // // create new certstore // certList = new ArrayList(); certList.add(_origCert); certList.add(_signCert); certs = CertStore.getInstance("Collection", new CollectionCertStoreParameters(certList), BC); // // replace certs // sd = CMSSignedData.replaceCertificatesAndCRLs(sd, certs); verifySignatures(sd); } public void testCertOrdering1() throws Exception { List certList = new ArrayList(); CMSProcessable msg = new CMSProcessableByteArray("Hello World!".getBytes()); certList.add(_origCert); certList.add(_signCert); certList.add(_signDsaCert); CertStore certs = CertStore.getInstance("Collection", new CollectionCertStoreParameters(certList), BC); CMSSignedDataGenerator gen = new CMSSignedDataGenerator(); gen.addSigner(_origKP.getPrivate(), _origCert, CMSSignedDataGenerator.DIGEST_SHA1); gen.addCertificatesAndCRLs(certs); CMSSignedData sd = gen.generate(msg, true, BC); certs = sd.getCertificatesAndCRLs("Collection", BC); Iterator it = certs.getCertificates(null).iterator(); assertEquals(_origCert, it.next()); assertEquals(_signCert, it.next()); assertEquals(_signDsaCert, it.next()); } public void testCertOrdering2() throws Exception { List certList = new ArrayList(); CMSProcessable msg = new CMSProcessableByteArray("Hello World!".getBytes()); certList.add(_signCert); certList.add(_signDsaCert); certList.add(_origCert); CertStore certs = CertStore.getInstance("Collection", new CollectionCertStoreParameters(certList), BC); CMSSignedDataGenerator gen = new CMSSignedDataGenerator(); gen.addSigner(_origKP.getPrivate(), _origCert, CMSSignedDataGenerator.DIGEST_SHA1); gen.addCertificatesAndCRLs(certs); CMSSignedData sd = gen.generate(msg, true, BC); certs = sd.getCertificatesAndCRLs("Collection", BC); Iterator it = certs.getCertificates(null).iterator(); assertEquals(_signCert, it.next()); assertEquals(_signDsaCert, it.next()); assertEquals(_origCert, it.next()); } public void testSignerStoreReplacement() throws Exception { List certList = new ArrayList(); CMSProcessable msg = new CMSProcessableByteArray("Hello World!".getBytes()); certList.add(_origCert); certList.add(_signCert); CertStore certs = CertStore.getInstance("Collection", new CollectionCertStoreParameters(certList), BC); CMSSignedDataGenerator gen = new CMSSignedDataGenerator(); gen.addSigner(_origKP.getPrivate(), _origCert, CMSSignedDataGenerator.DIGEST_SHA1); gen.addCertificatesAndCRLs(certs); CMSSignedData original = gen.generate(msg, true, BC); // // create new Signer // gen = new CMSSignedDataGenerator(); gen.addSigner(_origKP.getPrivate(), _origCert, CMSSignedDataGenerator.DIGEST_SHA224); gen.addCertificatesAndCRLs(certs); CMSSignedData newSD = gen.generate(msg, true, BC); // // replace signer // CMSSignedData sd = CMSSignedData.replaceSigners(original, newSD.getSignerInfos()); SignerInformation signer = (SignerInformation)sd.getSignerInfos().getSigners().iterator().next(); assertEquals(CMSSignedDataGenerator.DIGEST_SHA224, signer.getDigestAlgOID()); // we use a parser here as it requires the digests to be correct in the digest set, if it // isn't we'll get a NullPointerException CMSSignedDataParser sp = new CMSSignedDataParser(sd.getEncoded()); sp.getSignedContent().drain(); verifySignatures(sp); } public void testEncapsulatedSamples() throws Exception { testSample("PSSSignDataSHA1Enc.sig"); testSample("PSSSignDataSHA256Enc.sig"); testSample("PSSSignDataSHA512Enc.sig"); } public void testSamples() throws Exception { testSample("PSSSignData.data", "PSSSignDataSHA1.sig"); testSample("PSSSignData.data", "PSSSignDataSHA256.sig"); testSample("PSSSignData.data", "PSSSignDataSHA512.sig"); } public void testCounterSig() throws Exception { CMSSignedData sig = new CMSSignedData(getInput("counterSig.p7m")); SignerInformationStore ss = sig.getSignerInfos(); Collection signers = ss.getSigners(); SignerInformationStore cs = ((SignerInformation)signers.iterator().next()).getCounterSignatures(); Collection csSigners = cs.getSigners(); assertEquals(1, csSigners.size()); Iterator it = csSigners.iterator(); while (it.hasNext()) { SignerInformation cSigner = (SignerInformation)it.next(); Collection certCollection = sig.getCertificatesAndCRLs("Collection", BC).getCertificates(selectorConverter.getCertSelector(cSigner.getSID())); Iterator certIt = certCollection.iterator(); X509Certificate cert = (X509Certificate)certIt.next(); assertNull(cSigner.getSignedAttributes().get(PKCSObjectIdentifiers.pkcs_9_at_contentType)); assertEquals(true, cSigner.verify(cert, BC)); } verifySignatures(sig); } private void testSample(String sigName) throws Exception { CMSSignedData sig = new CMSSignedData(getInput(sigName)); verifySignatures(sig); } private void testSample(String messageName, String sigName) throws Exception { CMSSignedData sig = new CMSSignedData(new CMSProcessableByteArray(getInput(messageName)), getInput(sigName)); verifySignatures(sig); } private byte[] getInput(String name) throws IOException { return Streams.readAll(getClass().getResourceAsStream(name)); } public void testForMultipleCounterSignatures() throws Exception { CMSSignedData sd = new CMSSignedData(xtraCounterSig); for (Iterator sI = sd.getSignerInfos().getSigners().iterator(); sI.hasNext();) { SignerInformation sigI = (SignerInformation)sI.next(); SignerInformationStore counter = sigI.getCounterSignatures(); List sigs = new ArrayList(counter.getSigners()); assertEquals(2, sigs.size()); } } private void verifySignatures(CMSSignedDataParser sp) throws Exception { CertStore certs = sp.getCertificatesAndCRLs("Collection", BC); SignerInformationStore signers = sp.getSignerInfos(); Collection c = signers.getSigners(); Iterator it = c.iterator(); while (it.hasNext()) { SignerInformation signer = (SignerInformation)it.next(); Collection certCollection = certs.getCertificates(selectorConverter.getCertSelector(signer.getSID())); Iterator certIt = certCollection.iterator(); X509Certificate cert = (X509Certificate)certIt.next(); assertEquals(true, signer.verify(cert, BC)); } } } bouncycastle-1.49.orig/test/src/org/bouncycastle/cms/test/EnvelopedDataStreamTest.java0000644000175000017500000005227211507246517030634 0ustar ebourgebourgpackage org.bouncycastle.cms.test; import java.io.BufferedOutputStream; import java.io.ByteArrayOutputStream; import java.io.InputStream; import java.io.OutputStream; import java.security.Key; import java.security.KeyFactory; import java.security.KeyPair; import java.security.Security; import java.security.cert.X509Certificate; import java.security.spec.PKCS8EncodedKeySpec; import java.util.Arrays; import java.util.Collection; import java.util.Iterator; import javax.crypto.SecretKey; import junit.framework.Test; import junit.framework.TestCase; import junit.framework.TestSuite; import org.bouncycastle.asn1.ASN1InputStream; import org.bouncycastle.asn1.DEROutputStream; import org.bouncycastle.asn1.pkcs.PKCSObjectIdentifiers; import org.bouncycastle.cms.CMSEnvelopedDataGenerator; import org.bouncycastle.cms.CMSEnvelopedDataParser; import org.bouncycastle.cms.CMSEnvelopedDataStreamGenerator; import org.bouncycastle.cms.CMSTypedStream; import org.bouncycastle.cms.KEKRecipientId; import org.bouncycastle.cms.RecipientId; import org.bouncycastle.cms.RecipientInformation; import org.bouncycastle.cms.RecipientInformationStore; import org.bouncycastle.cms.jcajce.JceKeyAgreeRecipientId; import org.bouncycastle.jce.provider.BouncyCastleProvider; import org.bouncycastle.util.encoders.Base64; import org.bouncycastle.util.encoders.Hex; public class EnvelopedDataStreamTest extends TestCase { private static final String BC = BouncyCastleProvider.PROVIDER_NAME; private static final int BUFFER_SIZE = 4000; private static String _signDN; private static KeyPair _signKP; private static X509Certificate _signCert; private static String _origDN; private static KeyPair _origKP; private static X509Certificate _origCert; private static String _reciDN; private static KeyPair _reciKP; private static X509Certificate _reciCert; private static KeyPair _origEcKP; private static KeyPair _reciEcKP; private static X509Certificate _reciEcCert; private static boolean _initialised = false; public EnvelopedDataStreamTest() { } private static void init() throws Exception { if (!_initialised) { _initialised = true; _signDN = "O=Bouncy Castle, C=AU"; _signKP = CMSTestUtil.makeKeyPair(); _signCert = CMSTestUtil.makeCertificate(_signKP, _signDN, _signKP, _signDN); _origDN = "CN=Bob, OU=Sales, O=Bouncy Castle, C=AU"; _origKP = CMSTestUtil.makeKeyPair(); _origCert = CMSTestUtil.makeCertificate(_origKP, _origDN, _signKP, _signDN); _reciDN = "CN=Doug, OU=Sales, O=Bouncy Castle, C=AU"; _reciKP = CMSTestUtil.makeKeyPair(); _reciCert = CMSTestUtil.makeCertificate(_reciKP, _reciDN, _signKP, _signDN); _origEcKP = CMSTestUtil.makeEcDsaKeyPair(); _reciEcKP = CMSTestUtil.makeEcDsaKeyPair(); _reciEcCert = CMSTestUtil.makeCertificate(_reciEcKP, _reciDN, _signKP, _signDN); } } public void setUp() throws Exception { init(); } public void testWorkingData() throws Exception { byte[] keyData = Base64.decode( "MIICdgIBADANBgkqhkiG9w0BAQEFAASCAmAwggJcAgEAAoGBAKrAz/SQKrcQ" + "nj9IxHIfKDbuXsMqUpI06s2gps6fp7RDNvtUDDMOciWGFhD45YSy8GO0mPx3" + "Nkc7vKBqX4TLcqLUz7kXGOHGOwiPZoNF+9jBMPNROe/B0My0PkWg9tuq+nxN" + "64oD47+JvDwrpNOS5wsYavXeAW8Anv9ZzHLU7KwZAgMBAAECgYA/fqdVt+5K" + "WKGfwr1Z+oAHvSf7xtchiw/tGtosZ24DOCNP3fcTXUHQ9kVqVkNyzt9ZFCT3" + "bJUAdBQ2SpfuV4DusVeQZVzcROKeA09nPkxBpTefWbSDQGhb+eZq9L8JDRSW" + "HyYqs+MBoUpLw7GKtZiJkZyY6CsYkAnQ+uYVWq/TIQJBAP5zafO4HUV/w4KD" + "VJi+ua+GYF1Sg1t/dYL1kXO9GP1p75YAmtm6LdnOCas7wj70/G1YlPGkOP0V" + "GFzeG5KAmAUCQQCryvKU9nwWA+kypcQT9Yr1P4vGS0APYoBThnZq7jEPc5Cm" + "ZI82yseSxSeea0+8KQbZ5mvh1p3qImDLEH/iNSQFAkAghS+tboKPN10NeSt+" + "uiGRRWNbiggv0YJ7Uldcq3ZeLQPp7/naiekCRUsHD4Qr97OrZf7jQ1HlRqTu" + "eZScjMLhAkBNUMZCQnhwFAyEzdPkQ7LpU1MdyEopYmRssuxijZao5JLqQAGw" + "YCzXokGFa7hz72b09F4DQurJL/WuDlvvu4jdAkEAxwT9lylvfSfEQw4/qQgZ" + "MFB26gqB6Gqs1pHIZCzdliKx5BO3VDeUGfXMI8yOkbXoWbYx5xPid/+N8R//" + "+sxLBw=="); byte[] envData = Base64.decode( "MIAGCSqGSIb3DQEHA6CAMIACAQAxgcQwgcECAQAwKjAlMRYwFAYDVQQKEw1C" + "b3VuY3kgQ2FzdGxlMQswCQYDVQQGEwJBVQIBHjANBgkqhkiG9w0BAQEFAASB" + "gDmnaDZ0vDJNlaUSYyEXsgbaUH+itNTjCOgv77QTX2ImXj+kTctM19PQF2I1" + "0/NL0fjakvCgBTHKmk13a7jqB6cX3bysenHNrglHsgNGgeXQ7ggAq5fV/JQQ" + "T7rSxEtuwpbuHQnoVUZahOHVKy/a0uLr9iIh1A3y+yZTZaG505ZJMIAGCSqG" + "SIb3DQEHATAdBglghkgBZQMEAQIEENmkYNbDXiZxJWtq82qIRZKggAQgkOGr" + "1JcTsADStez1eY4+rO4DtyBIyUYQ3pilnbirfPkAAAAAAAAAAAAA"); CMSEnvelopedDataParser ep = new CMSEnvelopedDataParser(envData); RecipientInformationStore recipients = ep.getRecipientInfos(); assertEquals(ep.getEncryptionAlgOID(), CMSEnvelopedDataGenerator.AES128_CBC); Collection c = recipients.getRecipients(); Iterator it = c.iterator(); PKCS8EncodedKeySpec keySpec = new PKCS8EncodedKeySpec(keyData); KeyFactory keyFact = KeyFactory.getInstance("RSA", BC); Key priKey = keyFact.generatePrivate(keySpec); byte[] data = Hex.decode("57616c6c6157616c6c6157617368696e67746f6e"); while (it.hasNext()) { RecipientInformation recipient = (RecipientInformation)it.next(); assertEquals(recipient.getKeyEncryptionAlgOID(), PKCSObjectIdentifiers.rsaEncryption.getId()); CMSTypedStream recData = recipient.getContentStream(priKey, BC); assertEquals(true, Arrays.equals(data, CMSTestUtil.streamToByteArray(recData.getContentStream()))); } } private void verifyData( ByteArrayOutputStream encodedStream, String expectedOid, byte[] expectedData) throws Exception { CMSEnvelopedDataParser ep = new CMSEnvelopedDataParser(encodedStream.toByteArray()); RecipientInformationStore recipients = ep.getRecipientInfos(); assertEquals(ep.getEncryptionAlgOID(), expectedOid); Collection c = recipients.getRecipients(); Iterator it = c.iterator(); while (it.hasNext()) { RecipientInformation recipient = (RecipientInformation)it.next(); assertEquals(recipient.getKeyEncryptionAlgOID(), PKCSObjectIdentifiers.rsaEncryption.getId()); CMSTypedStream recData = recipient.getContentStream(_reciKP.getPrivate(), BC); assertEquals(true, Arrays.equals(expectedData, CMSTestUtil.streamToByteArray(recData.getContentStream()))); } } public void testKeyTransAES128BufferedStream() throws Exception { byte[] data = new byte[2000]; for (int i = 0; i != 2000; i++) { data[i] = (byte)(i & 0xff); } // // unbuffered // CMSEnvelopedDataStreamGenerator edGen = new CMSEnvelopedDataStreamGenerator(); edGen.addKeyTransRecipient(_reciCert); ByteArrayOutputStream bOut = new ByteArrayOutputStream(); OutputStream out = edGen.open( bOut, CMSEnvelopedDataGenerator.AES128_CBC, BC); for (int i = 0; i != 2000; i++) { out.write(data[i]); } out.close(); verifyData(bOut, CMSEnvelopedDataGenerator.AES128_CBC, data); int unbufferedLength = bOut.toByteArray().length; // // Using buffered output - should be == to unbuffered // edGen = new CMSEnvelopedDataStreamGenerator(); edGen.addKeyTransRecipient(_reciCert); bOut = new ByteArrayOutputStream(); out = edGen.open(bOut, CMSEnvelopedDataGenerator.AES128_CBC, BC); BufferedOutputStream bfOut = new BufferedOutputStream(out, 300); for (int i = 0; i != 2000; i++) { bfOut.write(data[i]); } bfOut.close(); verifyData(bOut, CMSEnvelopedDataGenerator.AES128_CBC, data); assertTrue(bOut.toByteArray().length == unbufferedLength); } public void testKeyTransAES128Buffered() throws Exception { byte[] data = new byte[2000]; for (int i = 0; i != 2000; i++) { data[i] = (byte)(i & 0xff); } // // unbuffered // CMSEnvelopedDataStreamGenerator edGen = new CMSEnvelopedDataStreamGenerator(); edGen.addKeyTransRecipient(_reciCert); ByteArrayOutputStream bOut = new ByteArrayOutputStream(); OutputStream out = edGen.open( bOut, CMSEnvelopedDataGenerator.AES128_CBC, BC); for (int i = 0; i != 2000; i++) { out.write(data[i]); } out.close(); verifyData(bOut, CMSEnvelopedDataGenerator.AES128_CBC, data); int unbufferedLength = bOut.toByteArray().length; // // buffered - less than default of 1000 // edGen = new CMSEnvelopedDataStreamGenerator(); edGen.setBufferSize(300); edGen.addKeyTransRecipient(_reciCert); bOut = new ByteArrayOutputStream(); out = edGen.open(bOut, CMSEnvelopedDataGenerator.AES128_CBC, BC); for (int i = 0; i != 2000; i++) { out.write(data[i]); } out.close(); verifyData(bOut, CMSEnvelopedDataGenerator.AES128_CBC, data); assertTrue(bOut.toByteArray().length > unbufferedLength); } public void testKeyTransAES128Der() throws Exception { byte[] data = new byte[2000]; for (int i = 0; i != 2000; i++) { data[i] = (byte)(i & 0xff); } CMSEnvelopedDataStreamGenerator edGen = new CMSEnvelopedDataStreamGenerator(); edGen.addKeyTransRecipient(_reciCert); ByteArrayOutputStream bOut = new ByteArrayOutputStream(); OutputStream out = edGen.open( bOut, CMSEnvelopedDataGenerator.AES128_CBC, BC); for (int i = 0; i != 2000; i++) { out.write(data[i]); } out.close(); // convert to DER ASN1InputStream aIn = new ASN1InputStream(bOut.toByteArray()); bOut.reset(); DEROutputStream dOut = new DEROutputStream(bOut); dOut.writeObject(aIn.readObject()); verifyData(bOut, CMSEnvelopedDataGenerator.AES128_CBC, data); } public void testKeyTransAES128Throughput() throws Exception { byte[] data = new byte[40001]; for (int i = 0; i != data.length; i++) { data[i] = (byte)(i & 0xff); } // // buffered // CMSEnvelopedDataStreamGenerator edGen = new CMSEnvelopedDataStreamGenerator(); edGen.setBufferSize(BUFFER_SIZE); edGen.addKeyTransRecipient(_reciCert); ByteArrayOutputStream bOut = new ByteArrayOutputStream(); OutputStream out = edGen.open(bOut, CMSEnvelopedDataGenerator.AES128_CBC, BC); for (int i = 0; i != data.length; i++) { out.write(data[i]); } out.close(); CMSEnvelopedDataParser ep = new CMSEnvelopedDataParser(bOut.toByteArray()); RecipientInformationStore recipients = ep.getRecipientInfos(); Collection c = recipients.getRecipients(); Iterator it = c.iterator(); if (it.hasNext()) { RecipientInformation recipient = (RecipientInformation)it.next(); assertEquals(recipient.getKeyEncryptionAlgOID(), PKCSObjectIdentifiers.rsaEncryption.getId()); CMSTypedStream recData = recipient.getContentStream(_reciKP.getPrivate(), BC); InputStream dataStream = recData.getContentStream(); ByteArrayOutputStream dataOut = new ByteArrayOutputStream(); int len; byte[] buf = new byte[BUFFER_SIZE]; int count = 0; while (count != 10 && (len = dataStream.read(buf)) > 0) { assertEquals(buf.length, len); dataOut.write(buf); count++; } len = dataStream.read(buf); dataOut.write(buf, 0, len); assertEquals(true, Arrays.equals(data, dataOut.toByteArray())); } else { fail("recipient not found."); } } public void testKeyTransAES128() throws Exception { byte[] data = "WallaWallaWashington".getBytes(); CMSEnvelopedDataStreamGenerator edGen = new CMSEnvelopedDataStreamGenerator(); edGen.addKeyTransRecipient(_reciCert); ByteArrayOutputStream bOut = new ByteArrayOutputStream(); OutputStream out = edGen.open( bOut, CMSEnvelopedDataGenerator.AES128_CBC, BC); out.write(data); out.close(); CMSEnvelopedDataParser ep = new CMSEnvelopedDataParser(bOut.toByteArray()); RecipientInformationStore recipients = ep.getRecipientInfos(); assertEquals(ep.getEncryptionAlgOID(), CMSEnvelopedDataGenerator.AES128_CBC); Collection c = recipients.getRecipients(); Iterator it = c.iterator(); while (it.hasNext()) { RecipientInformation recipient = (RecipientInformation)it.next(); assertEquals(recipient.getKeyEncryptionAlgOID(), PKCSObjectIdentifiers.rsaEncryption.getId()); CMSTypedStream recData = recipient.getContentStream(_reciKP.getPrivate(), BC); assertEquals(true, Arrays.equals(data, CMSTestUtil.streamToByteArray(recData.getContentStream()))); } ep.close(); } public void testKeyTransCAST5SunJCE() throws Exception { if (Security.getProvider("SunJCE") == null) { return; } String version = System.getProperty("java.version"); if (version.startsWith("1.4") || version.startsWith("1.3")) { return; } byte[] data = "WallaWallaWashington".getBytes(); CMSEnvelopedDataStreamGenerator edGen = new CMSEnvelopedDataStreamGenerator(); edGen.addKeyTransRecipient(_reciCert); ByteArrayOutputStream bOut = new ByteArrayOutputStream(); OutputStream out = edGen.open( bOut, CMSEnvelopedDataGenerator.CAST5_CBC, "SunJCE"); out.write(data); out.close(); CMSEnvelopedDataParser ep = new CMSEnvelopedDataParser(bOut.toByteArray()); RecipientInformationStore recipients = ep.getRecipientInfos(); assertEquals(ep.getEncryptionAlgOID(), CMSEnvelopedDataGenerator.CAST5_CBC); Collection c = recipients.getRecipients(); Iterator it = c.iterator(); while (it.hasNext()) { RecipientInformation recipient = (RecipientInformation)it.next(); assertEquals(recipient.getKeyEncryptionAlgOID(), PKCSObjectIdentifiers.rsaEncryption.getId()); CMSTypedStream recData = recipient.getContentStream(_reciKP.getPrivate(), "SunJCE"); assertEquals(true, Arrays.equals(data, CMSTestUtil.streamToByteArray(recData.getContentStream()))); } ep.close(); } public void testAESKEK() throws Exception { byte[] data = "WallaWallaWashington".getBytes(); SecretKey kek = CMSTestUtil.makeAES192Key(); CMSEnvelopedDataStreamGenerator edGen = new CMSEnvelopedDataStreamGenerator(); byte[] kekId = new byte[] { 1, 2, 3, 4, 5 }; edGen.addKEKRecipient(kek, kekId); ByteArrayOutputStream bOut = new ByteArrayOutputStream(); OutputStream out = edGen.open( bOut, CMSEnvelopedDataGenerator.DES_EDE3_CBC, BC); out.write(data); out.close(); CMSEnvelopedDataParser ep = new CMSEnvelopedDataParser(bOut.toByteArray()); RecipientInformationStore recipients = ep.getRecipientInfos(); assertEquals(ep.getEncryptionAlgOID(), CMSEnvelopedDataGenerator.DES_EDE3_CBC); Collection c = recipients.getRecipients(); Iterator it = c.iterator(); while (it.hasNext()) { RecipientInformation recipient = (RecipientInformation)it.next(); assertEquals(recipient.getKeyEncryptionAlgOID(), "2.16.840.1.101.3.4.1.25"); CMSTypedStream recData = recipient.getContentStream(kek, BC); assertEquals(true, Arrays.equals(data, CMSTestUtil.streamToByteArray(recData.getContentStream()))); } ep.close(); } public void testTwoAESKEK() throws Exception { byte[] data = "WallaWallaWashington".getBytes(); SecretKey kek1 = CMSTestUtil.makeAES192Key(); SecretKey kek2 = CMSTestUtil.makeAES192Key(); CMSEnvelopedDataStreamGenerator edGen = new CMSEnvelopedDataStreamGenerator(); byte[] kekId1 = new byte[] { 1, 2, 3, 4, 5 }; byte[] kekId2 = new byte[] { 5, 4, 3, 2, 1 }; edGen.addKEKRecipient(kek1, kekId1); edGen.addKEKRecipient(kek2, kekId2); ByteArrayOutputStream bOut = new ByteArrayOutputStream(); OutputStream out = edGen.open( bOut, CMSEnvelopedDataGenerator.DES_EDE3_CBC, BC); out.write(data); out.close(); CMSEnvelopedDataParser ep = new CMSEnvelopedDataParser(bOut.toByteArray()); RecipientInformationStore recipients = ep.getRecipientInfos(); assertEquals(ep.getEncryptionAlgOID(), CMSEnvelopedDataGenerator.DES_EDE3_CBC); RecipientId recSel = new KEKRecipientId(kekId2); RecipientInformation recipient = recipients.get(recSel); assertEquals(recipient.getKeyEncryptionAlgOID(), "2.16.840.1.101.3.4.1.25"); CMSTypedStream recData = recipient.getContentStream(kek2, BC); assertEquals(true, Arrays.equals(data, CMSTestUtil.streamToByteArray(recData.getContentStream()))); ep.close(); } public void testECKeyAgree() throws Exception { byte[] data = Hex.decode("504b492d4320434d5320456e76656c6f706564446174612053616d706c65"); CMSEnvelopedDataStreamGenerator edGen = new CMSEnvelopedDataStreamGenerator(); edGen.addKeyAgreementRecipient(CMSEnvelopedDataGenerator.ECDH_SHA1KDF, _origEcKP.getPrivate(), _origEcKP.getPublic(), _reciEcCert, CMSEnvelopedDataGenerator.AES128_WRAP, BC); ByteArrayOutputStream bOut = new ByteArrayOutputStream(); OutputStream out = edGen.open( bOut, CMSEnvelopedDataGenerator.AES128_CBC, BC); out.write(data); out.close(); CMSEnvelopedDataParser ep = new CMSEnvelopedDataParser(bOut.toByteArray()); RecipientInformationStore recipients = ep.getRecipientInfos(); assertEquals(ep.getEncryptionAlgOID(), CMSEnvelopedDataGenerator.AES128_CBC); RecipientId recSel = new JceKeyAgreeRecipientId(_reciEcCert); RecipientInformation recipient = recipients.get(recSel); CMSTypedStream recData = recipient.getContentStream(_reciEcKP.getPrivate(), BC); assertEquals(true, Arrays.equals(data, CMSTestUtil.streamToByteArray(recData.getContentStream()))); ep.close(); } public void testOriginatorInfo() throws Exception { CMSEnvelopedDataParser env = new CMSEnvelopedDataParser(CMSSampleMessages.originatorMessage); env.getRecipientInfos(); assertEquals(CMSEnvelopedDataGenerator.DES_EDE3_CBC, env.getEncryptionAlgOID()); } public static Test suite() throws Exception { return new CMSTestSetup(new TestSuite(EnvelopedDataStreamTest.class)); } } bouncycastle-1.49.orig/test/src/org/bouncycastle/cms/test/AllTests.java0000644000175000017500000000343511737304707025636 0ustar ebourgebourgpackage org.bouncycastle.cms.test; import javax.crypto.Cipher; import junit.framework.Test; import junit.framework.TestSuite; public class AllTests { public static void main (String[] args) throws Exception { junit.textui.TestRunner.run(suite()); } public static Test suite() throws Exception { TestSuite suite = new TestSuite("CMS tests"); suite.addTest(AuthenticatedDataTest.suite()); suite.addTest(AuthenticatedDataStreamTest.suite()); suite.addTest(CompressedDataTest.suite()); suite.addTest(NewCompressedDataTest.suite()); suite.addTest(SignedDataTest.suite()); suite.addTest(NewSignedDataTest.suite()); suite.addTest(EnvelopedDataTest.suite()); suite.addTest(NewEnvelopedDataTest.suite()); suite.addTest(NewAuthenticatedDataTest.suite()); suite.addTest(NewAuthenticatedDataStreamTest.suite()); suite.addTest(CompressedDataStreamTest.suite()); suite.addTest(NewCompressedDataStreamTest.suite()); suite.addTest(SignedDataStreamTest.suite()); suite.addTest(NewSignedDataStreamTest.suite()); suite.addTest(EnvelopedDataStreamTest.suite()); suite.addTest(NewEnvelopedDataStreamTest.suite()); suite.addTest(MiscDataStreamTest.suite()); suite.addTest(Rfc4134Test.suite()); suite.addTest(ConverterTest.suite()); suite.addTest(BcEnvelopedDataTest.suite()); suite.addTest(BcSignedDataTest.suite()); try { Cipher.getInstance("RSA", "SunJCE"); suite.addTest(SunProviderTest.suite()); suite.addTest(NullProviderTest.suite()); } catch (Exception e) { // ignore } return suite; } } bouncycastle-1.49.orig/test/src/org/bouncycastle/cms/test/NewSignedDataStreamTest.java0000644000175000017500000013444112121767102030564 0ustar ebourgebourgpackage org.bouncycastle.cms.test; import java.io.BufferedOutputStream; import java.io.ByteArrayInputStream; import java.io.ByteArrayOutputStream; import java.io.OutputStream; import java.security.KeyPair; import java.security.MessageDigest; import java.security.Security; import java.security.cert.X509CRL; import java.security.cert.X509Certificate; import java.util.ArrayList; import java.util.Collection; import java.util.Collections; import java.util.Hashtable; import java.util.Iterator; import java.util.List; import java.util.Map; import junit.framework.Test; import junit.framework.TestCase; import junit.framework.TestSuite; import org.bouncycastle.asn1.ASN1ObjectIdentifier; import org.bouncycastle.asn1.ASN1OctetString; import org.bouncycastle.asn1.DEROctetString; import org.bouncycastle.asn1.DERSet; import org.bouncycastle.asn1.cms.Attribute; import org.bouncycastle.asn1.cms.AttributeTable; import org.bouncycastle.asn1.cms.CMSAttributes; import org.bouncycastle.asn1.cms.CMSObjectIdentifiers; import org.bouncycastle.asn1.ocsp.OCSPResponse; import org.bouncycastle.cert.X509AttributeCertificateHolder; import org.bouncycastle.cert.X509CertificateHolder; import org.bouncycastle.cert.jcajce.JcaCRLStore; import org.bouncycastle.cert.jcajce.JcaCertStore; import org.bouncycastle.cert.jcajce.JcaX509AttributeCertificateHolder; import org.bouncycastle.cert.jcajce.JcaX509CRLHolder; import org.bouncycastle.cert.jcajce.JcaX509CertificateHolder; import org.bouncycastle.cert.ocsp.OCSPResp; import org.bouncycastle.cms.CMSAlgorithm; import org.bouncycastle.cms.CMSAttributeTableGenerator; import org.bouncycastle.cms.CMSProcessableByteArray; import org.bouncycastle.cms.CMSSignedData; import org.bouncycastle.cms.CMSSignedDataGenerator; import org.bouncycastle.cms.CMSSignedDataParser; import org.bouncycastle.cms.CMSSignedDataStreamGenerator; import org.bouncycastle.cms.CMSTypedData; import org.bouncycastle.cms.CMSTypedStream; import org.bouncycastle.cms.DefaultSignedAttributeTableGenerator; import org.bouncycastle.cms.SignerInformation; import org.bouncycastle.cms.SignerInformationStore; import org.bouncycastle.cms.jcajce.JcaSignerInfoGeneratorBuilder; import org.bouncycastle.cms.jcajce.JcaSimpleSignerInfoGeneratorBuilder; import org.bouncycastle.cms.jcajce.JcaSimpleSignerInfoVerifierBuilder; import org.bouncycastle.jce.provider.BouncyCastleProvider; import org.bouncycastle.operator.ContentSigner; import org.bouncycastle.operator.jcajce.JcaContentSignerBuilder; import org.bouncycastle.operator.jcajce.JcaDigestCalculatorProviderBuilder; import org.bouncycastle.util.CollectionStore; import org.bouncycastle.util.Store; import org.bouncycastle.util.encoders.Base64; public class NewSignedDataStreamTest extends TestCase { byte[] successResp = Base64.decode( "MIIFnAoBAKCCBZUwggWRBgkrBgEFBQcwAQEEggWCMIIFfjCCARehgZ8wgZwx" + "CzAJBgNVBAYTAklOMRcwFQYDVQQIEw5BbmRocmEgcHJhZGVzaDESMBAGA1UE" + "BxMJSHlkZXJhYmFkMQwwCgYDVQQKEwNUQ1MxDDAKBgNVBAsTA0FUQzEeMBwG" + "A1UEAxMVVENTLUNBIE9DU1AgUmVzcG9uZGVyMSQwIgYJKoZIhvcNAQkBFhVv" + "Y3NwQHRjcy1jYS50Y3MuY28uaW4YDzIwMDMwNDAyMTIzNDU4WjBiMGAwOjAJ" + "BgUrDgMCGgUABBRs07IuoCWNmcEl1oHwIak1BPnX8QQUtGyl/iL9WJ1VxjxF" + "j0hAwJ/s1AcCAQKhERgPMjAwMjA4MjkwNzA5MjZaGA8yMDAzMDQwMjEyMzQ1" + "OFowDQYJKoZIhvcNAQEFBQADgYEAfbN0TCRFKdhsmvOdUoiJ+qvygGBzDxD/" + "VWhXYA+16AphHLIWNABR3CgHB3zWtdy2j7DJmQ/R7qKj7dUhWLSqclAiPgFt" + "QQ1YvSJAYfEIdyHkxv4NP0LSogxrumANcDyC9yt/W9yHjD2ICPBIqCsZLuLk" + "OHYi5DlwWe9Zm9VFwCGgggPMMIIDyDCCA8QwggKsoAMCAQICAQYwDQYJKoZI" + "hvcNAQEFBQAwgZQxFDASBgNVBAMTC1RDUy1DQSBPQ1NQMSYwJAYJKoZIhvcN" + "AQkBFhd0Y3MtY2FAdGNzLWNhLnRjcy5jby5pbjEMMAoGA1UEChMDVENTMQww" + "CgYDVQQLEwNBVEMxEjAQBgNVBAcTCUh5ZGVyYWJhZDEXMBUGA1UECBMOQW5k" + "aHJhIHByYWRlc2gxCzAJBgNVBAYTAklOMB4XDTAyMDgyOTA3MTE0M1oXDTAz" + "MDgyOTA3MTE0M1owgZwxCzAJBgNVBAYTAklOMRcwFQYDVQQIEw5BbmRocmEg" + "cHJhZGVzaDESMBAGA1UEBxMJSHlkZXJhYmFkMQwwCgYDVQQKEwNUQ1MxDDAK" + "BgNVBAsTA0FUQzEeMBwGA1UEAxMVVENTLUNBIE9DU1AgUmVzcG9uZGVyMSQw" + "IgYJKoZIhvcNAQkBFhVvY3NwQHRjcy1jYS50Y3MuY28uaW4wgZ8wDQYJKoZI" + "hvcNAQEBBQADgY0AMIGJAoGBAM+XWW4caMRv46D7L6Bv8iwtKgmQu0SAybmF" + "RJiz12qXzdvTLt8C75OdgmUomxp0+gW/4XlTPUqOMQWv463aZRv9Ust4f8MH" + "EJh4ekP/NS9+d8vEO3P40ntQkmSMcFmtA9E1koUtQ3MSJlcs441JjbgUaVnm" + "jDmmniQnZY4bU3tVAgMBAAGjgZowgZcwDAYDVR0TAQH/BAIwADALBgNVHQ8E" + "BAMCB4AwEwYDVR0lBAwwCgYIKwYBBQUHAwkwNgYIKwYBBQUHAQEEKjAoMCYG" + "CCsGAQUFBzABhhpodHRwOi8vMTcyLjE5LjQwLjExMDo3NzAwLzAtBgNVHR8E" + "JjAkMCKgIKAehhxodHRwOi8vMTcyLjE5LjQwLjExMC9jcmwuY3JsMA0GCSqG" + "SIb3DQEBBQUAA4IBAQB6FovM3B4VDDZ15o12gnADZsIk9fTAczLlcrmXLNN4" + "PgmqgnwF0Ymj3bD5SavDOXxbA65AZJ7rBNAguLUo+xVkgxmoBH7R2sBxjTCc" + "r07NEadxM3HQkt0aX5XYEl8eRoifwqYAI9h0ziZfTNes8elNfb3DoPPjqq6V" + "mMg0f0iMS4W8LjNPorjRB+kIosa1deAGPhq0eJ8yr0/s2QR2/WFD5P4aXc8I" + "KWleklnIImS3zqiPrq6tl2Bm8DZj7vXlTOwmraSQxUwzCKwYob1yGvNOUQTq" + "pG6jxn7jgDawHU1+WjWQe4Q34/pWeGLysxTraMa+Ug9kPe+jy/qRX2xwvKBZ"); private static final String BC = BouncyCastleProvider.PROVIDER_NAME; private static final String TEST_MESSAGE = "Hello World!"; private static String _signDN; private static KeyPair _signKP; private static X509Certificate _signCert; private static String _origDN; private static KeyPair _origKP; private static X509Certificate _origCert; private static String _reciDN; private static KeyPair _reciKP; private static X509Certificate _reciCert; private static KeyPair _origDsaKP; private static X509Certificate _origDsaCert; private static X509CRL _signCrl; private static X509CRL _origCrl; private static boolean _initialised = false; public NewSignedDataStreamTest(String name) { super(name); } private static void init() throws Exception { if (!_initialised) { _initialised = true; if (Security.getProvider(BC) == null) { Security.addProvider(new BouncyCastleProvider()); } _signDN = "O=Bouncy Castle, C=AU"; _signKP = CMSTestUtil.makeKeyPair(); _signCert = CMSTestUtil.makeCertificate(_signKP, _signDN, _signKP, _signDN); _origDN = "CN=Bob, OU=Sales, O=Bouncy Castle, C=AU"; _origKP = CMSTestUtil.makeKeyPair(); _origCert = CMSTestUtil.makeCertificate(_origKP, _origDN, _signKP, _signDN); _origDsaKP = CMSTestUtil.makeDsaKeyPair(); _origDsaCert = CMSTestUtil.makeCertificate(_origDsaKP, _origDN, _signKP, _signDN); _reciDN = "CN=Doug, OU=Sales, O=Bouncy Castle, C=AU"; _reciKP = CMSTestUtil.makeKeyPair(); _reciCert = CMSTestUtil.makeCertificate(_reciKP, _reciDN, _signKP, _signDN); _signCrl = CMSTestUtil.makeCrl(_signKP); _origCrl = CMSTestUtil.makeCrl(_origKP); } } private void verifySignatures(CMSSignedDataParser sp, byte[] contentDigest) throws Exception { Store certStore = sp.getCertificates(); Store crlStore = sp.getCRLs(); SignerInformationStore signers = sp.getSignerInfos(); Collection c = signers.getSigners(); Iterator it = c.iterator(); while (it.hasNext()) { SignerInformation signer = (SignerInformation)it.next(); Collection certCollection = certStore.getMatches(signer.getSID()); Iterator certIt = certCollection.iterator(); X509CertificateHolder cert = (X509CertificateHolder)certIt.next(); assertEquals(true, signer.verify(new JcaSimpleSignerInfoVerifierBuilder().setProvider(BC).build(cert))); if (contentDigest != null) { assertTrue(MessageDigest.isEqual(contentDigest, signer.getContentDigest())); } } assertEquals(certStore.getMatches(null).size(), sp.getCertificates().getMatches(null).size()); assertEquals(crlStore.getMatches(null).size(), sp.getCRLs().getMatches(null).size()); } private void verifySignatures(CMSSignedDataParser sp) throws Exception { verifySignatures(sp, null); } private void verifyEncodedData(ByteArrayOutputStream bOut) throws Exception { CMSSignedDataParser sp; sp = new CMSSignedDataParser(new JcaDigestCalculatorProviderBuilder().setProvider(BC).build(), bOut.toByteArray()); sp.getSignedContent().drain(); verifySignatures(sp); sp.close(); } private void checkSigParseable(byte[] sig) throws Exception { CMSSignedDataParser sp = new CMSSignedDataParser(new JcaDigestCalculatorProviderBuilder().setProvider(BC).build(), sig); sp.getVersion(); CMSTypedStream sc = sp.getSignedContent(); if (sc != null) { sc.drain(); } sp.getCertificates(); sp.getCRLs(); sp.getSignerInfos(); sp.close(); } // public void testEarlyInvalidKeyException() throws Exception // { // try // { // CMSSignedDataStreamGenerator gen = new CMSSignedDataStreamGenerator(); // gen.addSigner( _origKP.getPrivate(), _origCert, // "DSA", // DOESN'T MATCH KEY ALG // CMSSignedDataStreamGenerator.DIGEST_SHA1, BC); // // fail("Expected InvalidKeyException in addSigner"); // } // catch (InvalidKeyException e) // { // // Ignore // } // } // public void testEarlyNoSuchAlgorithmException() throws Exception // { // try // { // CMSSignedDataStreamGenerator gen = new CMSSignedDataStreamGenerator(); // gen.addSigner( _origKP.getPrivate(), _origCert, // CMSSignedDataStreamGenerator.DIGEST_SHA1, // BAD OID! // CMSSignedDataStreamGenerator.DIGEST_SHA1, BC); // // fail("Expected NoSuchAlgorithmException in addSigner"); // } // catch (NoSuchAlgorithmException e) // { // // Ignore // } // } public void testSha1EncapsulatedSignature() throws Exception { byte[] encapSigData = Base64.decode( "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" + "n7MsJMoKN3Kd2Vzh6s10PFgeAAAAAAAA"); CMSSignedDataParser sp = new CMSSignedDataParser(new JcaDigestCalculatorProviderBuilder().setProvider(BC).build(), encapSigData); sp.getSignedContent().drain(); verifySignatures(sp); } public void testSHA1WithRSANoAttributes() throws Exception { List certList = new ArrayList(); CMSTypedData msg = new CMSProcessableByteArray(TEST_MESSAGE.getBytes()); certList.add(_origCert); certList.add(_signCert); Store certs = new JcaCertStore(certList); CMSSignedDataGenerator gen = new CMSSignedDataGenerator(); ContentSigner sha1Signer = new JcaContentSignerBuilder("SHA1withRSA").setProvider(BC).build(_origKP.getPrivate()); JcaSignerInfoGeneratorBuilder siBuilder = new JcaSignerInfoGeneratorBuilder(new JcaDigestCalculatorProviderBuilder().setProvider(BC).build()); siBuilder.setDirectSignature(true); gen.addSignerInfoGenerator(siBuilder.build(sha1Signer, _origCert)); gen.addCertificates(certs); CMSSignedData s = gen.generate(msg, false); CMSSignedDataParser sp = new CMSSignedDataParser(new JcaDigestCalculatorProviderBuilder().setProvider(BC).build(), new CMSTypedStream(new ByteArrayInputStream(TEST_MESSAGE.getBytes())), s.getEncoded()); sp.getSignedContent().drain(); // // compute expected content digest // MessageDigest md = MessageDigest.getInstance("SHA1", BC); verifySignatures(sp, md.digest(TEST_MESSAGE.getBytes())); } public void testDSANoAttributes() throws Exception { List certList = new ArrayList(); CMSTypedData msg = new CMSProcessableByteArray(TEST_MESSAGE.getBytes()); certList.add(_origDsaCert); certList.add(_signCert); JcaCertStore certs = new JcaCertStore(certList); CMSSignedDataGenerator gen = new CMSSignedDataGenerator(); JcaSignerInfoGeneratorBuilder builder = new JcaSignerInfoGeneratorBuilder(new JcaDigestCalculatorProviderBuilder().setProvider(BC).build()); builder.setDirectSignature(true); gen.addSignerInfoGenerator(builder.build(new JcaContentSignerBuilder("SHA1withDSA").setProvider(BC).build(_origDsaKP.getPrivate()), _origDsaCert)); gen.addCertificates(certs); CMSSignedData s = gen.generate(msg); CMSSignedDataParser sp = new CMSSignedDataParser(new JcaDigestCalculatorProviderBuilder().setProvider(BC).build(), new CMSTypedStream(new ByteArrayInputStream(TEST_MESSAGE.getBytes())), s.getEncoded()); sp.getSignedContent().drain(); // // compute expected content digest // MessageDigest md = MessageDigest.getInstance("SHA1", BC); verifySignatures(sp, md.digest(TEST_MESSAGE.getBytes())); } public void testSHA1WithRSA() throws Exception { List certList = new ArrayList(); List crlList = new ArrayList(); ByteArrayOutputStream bOut = new ByteArrayOutputStream(); certList.add(_origCert); certList.add(_signCert); crlList.add(_signCrl); crlList.add(_origCrl); Store certs = new JcaCertStore(certList); Store crls = new JcaCRLStore(crlList); CMSSignedDataStreamGenerator gen = new CMSSignedDataStreamGenerator(); ContentSigner sha1Signer = new JcaContentSignerBuilder("SHA1withRSA").setProvider(BC).build(_origKP.getPrivate()); gen.addSignerInfoGenerator(new JcaSignerInfoGeneratorBuilder(new JcaDigestCalculatorProviderBuilder().setProvider(BC).build()).build(sha1Signer, _origCert)); gen.addCertificates(certs); gen.addCRLs(crls); OutputStream sigOut = gen.open(bOut); sigOut.write(TEST_MESSAGE.getBytes()); sigOut.close(); checkSigParseable(bOut.toByteArray()); CMSSignedDataParser sp = new CMSSignedDataParser(new JcaDigestCalculatorProviderBuilder().setProvider(BC).build(), new CMSTypedStream(new ByteArrayInputStream(TEST_MESSAGE.getBytes())), bOut.toByteArray()); sp.getSignedContent().drain(); // // compute expected content digest // MessageDigest md = MessageDigest.getInstance("SHA1", BC); verifySignatures(sp, md.digest(TEST_MESSAGE.getBytes())); // // try using existing signer // gen = new CMSSignedDataStreamGenerator(); gen.addSigners(sp.getSignerInfos()); gen.addCertificates(sp.getCertificates()); gen.addCRLs(sp.getCRLs()); bOut.reset(); sigOut = gen.open(bOut, true); sigOut.write(TEST_MESSAGE.getBytes()); sigOut.close(); verifyEncodedData(bOut); // // look for the CRLs // Collection col = sp.getCRLs().getMatches(null); assertEquals(2, col.size()); assertTrue(col.contains(new JcaX509CRLHolder(_signCrl))); assertTrue(col.contains(new JcaX509CRLHolder(_origCrl))); } public void testSHA1WithRSAAndOtherRevocation() throws Exception { List certList = new ArrayList(); CMSTypedData msg = new CMSProcessableByteArray("Hello world!".getBytes()); ByteArrayOutputStream bOut = new ByteArrayOutputStream(); certList.add(_origCert); certList.add(_signCert); Store certs = new JcaCertStore(certList); CMSSignedDataStreamGenerator gen = new CMSSignedDataStreamGenerator(); ContentSigner sha1Signer = new JcaContentSignerBuilder("SHA1withRSA").setProvider(BC).build(_origKP.getPrivate()); gen.addSignerInfoGenerator(new JcaSignerInfoGeneratorBuilder(new JcaDigestCalculatorProviderBuilder().setProvider(BC).build()).build(sha1Signer, _origCert)); gen.addCertificates(certs); List otherInfo = new ArrayList(); OCSPResp response = new OCSPResp(successResp); otherInfo.add(response.toASN1Structure()); gen.addOtherRevocationInfo(CMSObjectIdentifiers.id_ri_ocsp_response, new CollectionStore(otherInfo)); OutputStream sigOut = gen.open(bOut, true); sigOut.write(TEST_MESSAGE.getBytes()); sigOut.close(); CMSSignedDataParser sp = new CMSSignedDataParser(new JcaDigestCalculatorProviderBuilder().setProvider(BC).build(), bOut.toByteArray()); CMSTypedStream stream = sp.getSignedContent(); assertEquals(CMSObjectIdentifiers.data, stream.getContentType()); stream.drain(); // // check version // assertEquals(5, sp.getVersion()); // // compute expected content digest // MessageDigest md = MessageDigest.getInstance("SHA1", BC); verifySignatures(sp, md.digest(TEST_MESSAGE.getBytes())); Store dataOtherInfo = sp.getOtherRevocationInfo(CMSObjectIdentifiers.id_ri_ocsp_response); assertEquals(1, dataOtherInfo.getMatches(null).size()); OCSPResp dataResponse = new OCSPResp(OCSPResponse.getInstance(dataOtherInfo.getMatches(null).iterator().next())); assertEquals(response, dataResponse); } public void testSHA1WithRSANonData() throws Exception { List certList = new ArrayList(); List crlList = new ArrayList(); ByteArrayOutputStream bOut = new ByteArrayOutputStream(); certList.add(new JcaX509CertificateHolder(_origCert)); certList.add(new JcaX509CertificateHolder(_signCert)); crlList.add(new JcaX509CRLHolder(_signCrl)); crlList.add(new JcaX509CRLHolder(_origCrl)); Store certs = new JcaCertStore(certList); Store crls = new JcaCRLStore(crlList); CMSSignedDataStreamGenerator gen = new CMSSignedDataStreamGenerator(); ContentSigner sha1Signer = new JcaContentSignerBuilder("SHA1withRSA").setProvider(BC).build(_origKP.getPrivate()); gen.addSignerInfoGenerator(new JcaSignerInfoGeneratorBuilder(new JcaDigestCalculatorProviderBuilder().setProvider(BC).build()).build(sha1Signer, _origCert)); gen.addCertificates(certs); gen.addCRLs(crls); OutputStream sigOut = gen.open(new ASN1ObjectIdentifier("1.2.3.4"), bOut, true); sigOut.write(TEST_MESSAGE.getBytes()); sigOut.close(); CMSSignedDataParser sp = new CMSSignedDataParser(new JcaDigestCalculatorProviderBuilder().setProvider(BC).build(), bOut.toByteArray()); CMSTypedStream stream = sp.getSignedContent(); assertEquals(new ASN1ObjectIdentifier("1.2.3.4"), stream.getContentType()); stream.drain(); // // compute expected content digest // MessageDigest md = MessageDigest.getInstance("SHA1", BC); verifySignatures(sp, md.digest(TEST_MESSAGE.getBytes())); } public void testSHA1AndMD5WithRSA() throws Exception { List certList = new ArrayList(); ByteArrayOutputStream bOut = new ByteArrayOutputStream(); certList.add(_origCert); certList.add(_signCert); Store certs = new JcaCertStore(certList); CMSSignedDataStreamGenerator gen = new CMSSignedDataStreamGenerator(); JcaSignerInfoGeneratorBuilder signerInfoGeneratorBuilder = new JcaSignerInfoGeneratorBuilder(new JcaDigestCalculatorProviderBuilder().setProvider(BC).build()); ContentSigner sha1Signer = new JcaContentSignerBuilder("SHA1withRSA").setProvider(BC).build(_origKP.getPrivate()); ContentSigner md5Signer = new JcaContentSignerBuilder("MD5withRSA").setProvider(BC).build(_origKP.getPrivate()); gen.addSignerInfoGenerator(signerInfoGeneratorBuilder.build(sha1Signer, _origCert)); gen.addSignerInfoGenerator(signerInfoGeneratorBuilder.build(md5Signer, _origCert)); gen.addCertificates(certs); OutputStream sigOut = gen.open(bOut); sigOut.write(TEST_MESSAGE.getBytes()); sigOut.close(); checkSigParseable(bOut.toByteArray()); CMSSignedDataParser sp = new CMSSignedDataParser(new JcaDigestCalculatorProviderBuilder().setProvider(BC).build(), new CMSTypedStream(new ByteArrayInputStream(TEST_MESSAGE.getBytes())), bOut.toByteArray()); sp.getSignedContent().drain(); verifySignatures(sp); } public void testSHA1WithRSAEncapsulatedBufferedStream() throws Exception { List certList = new ArrayList(); ByteArrayOutputStream bOut = new ByteArrayOutputStream(); certList.add(_origCert); certList.add(_signCert); Store certs = new JcaCertStore(certList); // // find unbuffered length // CMSSignedDataStreamGenerator gen = new CMSSignedDataStreamGenerator(); ContentSigner sha1Signer = new JcaContentSignerBuilder("SHA1withRSA").setProvider(BC).build(_origKP.getPrivate()); gen.addSignerInfoGenerator(new JcaSignerInfoGeneratorBuilder(new JcaDigestCalculatorProviderBuilder().setProvider(BC).build()).build(sha1Signer, _origCert)); gen.addCertificates(certs); OutputStream sigOut = gen.open(bOut, true); for (int i = 0; i != 2000; i++) { sigOut.write(i & 0xff); } sigOut.close(); CMSSignedDataParser sp = new CMSSignedDataParser(new JcaDigestCalculatorProviderBuilder().setProvider(BC).build(), bOut.toByteArray()); sp.getSignedContent().drain(); verifySignatures(sp); int unbufferedLength = bOut.toByteArray().length; // // find buffered length with buffered stream - should be equal // bOut = new ByteArrayOutputStream(); gen = new CMSSignedDataStreamGenerator(); gen.addSignerInfoGenerator(new JcaSignerInfoGeneratorBuilder(new JcaDigestCalculatorProviderBuilder().setProvider(BC).build()).build(sha1Signer, _origCert)); gen.addCertificates(certs); sigOut = gen.open(bOut, true); BufferedOutputStream bfOut = new BufferedOutputStream(sigOut, 300); for (int i = 0; i != 2000; i++) { bfOut.write(i & 0xff); } bfOut.close(); verifyEncodedData(bOut); assertTrue(bOut.toByteArray().length == unbufferedLength); } public void testSHA1WithRSAEncapsulatedBuffered() throws Exception { List certList = new ArrayList(); ByteArrayOutputStream bOut = new ByteArrayOutputStream(); certList.add(_origCert); certList.add(_signCert); Store certs = new JcaCertStore(certList); // // find unbuffered length // CMSSignedDataStreamGenerator gen = new CMSSignedDataStreamGenerator(); ContentSigner sha1Signer = new JcaContentSignerBuilder("SHA1withRSA").setProvider(BC).build(_origKP.getPrivate()); gen.addSignerInfoGenerator(new JcaSignerInfoGeneratorBuilder(new JcaDigestCalculatorProviderBuilder().setProvider(BC).build()).build(sha1Signer, _origCert)); gen.addCertificates(certs); OutputStream sigOut = gen.open(bOut, true); for (int i = 0; i != 2000; i++) { sigOut.write(i & 0xff); } sigOut.close(); CMSSignedDataParser sp = new CMSSignedDataParser(new JcaDigestCalculatorProviderBuilder().setProvider(BC).build(), bOut.toByteArray()); sp.getSignedContent().drain(); verifySignatures(sp); int unbufferedLength = bOut.toByteArray().length; // // find buffered length - buffer size less than default // bOut = new ByteArrayOutputStream(); gen = new CMSSignedDataStreamGenerator(); gen.setBufferSize(300); gen.addSignerInfoGenerator(new JcaSignerInfoGeneratorBuilder(new JcaDigestCalculatorProviderBuilder().setProvider(BC).build()).build(sha1Signer, _origCert)); gen.addCertificates(certs); sigOut = gen.open(bOut, true); for (int i = 0; i != 2000; i++) { sigOut.write(i & 0xff); } sigOut.close(); verifyEncodedData(bOut); assertTrue(bOut.toByteArray().length > unbufferedLength); } public void testSHA1WithRSAEncapsulated() throws Exception { List certList = new ArrayList(); ByteArrayOutputStream bOut = new ByteArrayOutputStream(); certList.add(_origCert); certList.add(_signCert); Store certs = new JcaCertStore(certList); CMSSignedDataStreamGenerator gen = new CMSSignedDataStreamGenerator(); ContentSigner sha1Signer = new JcaContentSignerBuilder("SHA1withRSA").setProvider(BC).build(_origKP.getPrivate()); gen.addSignerInfoGenerator(new JcaSignerInfoGeneratorBuilder(new JcaDigestCalculatorProviderBuilder().setProvider(BC).build()).build(sha1Signer, _origCert)); gen.addCertificates(certs); OutputStream sigOut = gen.open(bOut, true); sigOut.write(TEST_MESSAGE.getBytes()); sigOut.close(); CMSSignedDataParser sp = new CMSSignedDataParser(new JcaDigestCalculatorProviderBuilder().setProvider(BC).build(), bOut.toByteArray()); sp.getSignedContent().drain(); verifySignatures(sp); byte[] contentDigest = (byte[])gen.getGeneratedDigests().get(CMSAlgorithm.SHA1.getId()); AttributeTable table = ((SignerInformation)sp.getSignerInfos().getSigners().iterator().next()).getSignedAttributes(); Attribute hash = table.get(CMSAttributes.messageDigest); assertTrue(MessageDigest.isEqual(contentDigest, ((ASN1OctetString)hash.getAttrValues().getObjectAt(0)).getOctets())); // // try using existing signer // gen = new CMSSignedDataStreamGenerator(); gen.addSigners(sp.getSignerInfos()); gen.addCertificates(sp.getCertificates()); bOut.reset(); sigOut = gen.open(bOut, true); sigOut.write(TEST_MESSAGE.getBytes()); sigOut.close(); CMSSignedData sd = new CMSSignedData(new CMSProcessableByteArray(TEST_MESSAGE.getBytes()), bOut.toByteArray()); assertEquals(1, sd.getSignerInfos().getSigners().size()); verifyEncodedData(bOut); } public void testSHA1WithRSAEncapsulatedSubjectKeyID() throws Exception { List certList = new ArrayList(); ByteArrayOutputStream bOut = new ByteArrayOutputStream(); certList.add(_origCert); certList.add(_signCert); Store certs = new JcaCertStore(certList); CMSSignedDataStreamGenerator gen = new CMSSignedDataStreamGenerator(); ContentSigner sha1Signer = new JcaContentSignerBuilder("SHA1withRSA").setProvider(BC).build(_origKP.getPrivate()); gen.addSignerInfoGenerator(new JcaSignerInfoGeneratorBuilder(new JcaDigestCalculatorProviderBuilder().setProvider(BC).build()).build(sha1Signer, CMSTestUtil.createSubjectKeyId(_origCert.getPublicKey()).getKeyIdentifier())); gen.addCertificates(certs); OutputStream sigOut = gen.open(bOut, true); sigOut.write(TEST_MESSAGE.getBytes()); sigOut.close(); CMSSignedDataParser sp = new CMSSignedDataParser(new JcaDigestCalculatorProviderBuilder().setProvider(BC).build(), bOut.toByteArray()); sp.getSignedContent().drain(); verifySignatures(sp); byte[] contentDigest = (byte[])gen.getGeneratedDigests().get(CMSAlgorithm.SHA1.getId()); AttributeTable table = ((SignerInformation)sp.getSignerInfos().getSigners().iterator().next()).getSignedAttributes(); Attribute hash = table.get(CMSAttributes.messageDigest); assertTrue(MessageDigest.isEqual(contentDigest, ((ASN1OctetString)hash.getAttrValues().getObjectAt(0)).getOctets())); // // try using existing signer // gen = new CMSSignedDataStreamGenerator(); gen.addSigners(sp.getSignerInfos()); gen.addCertificates(sp.getCertificates()); bOut.reset(); sigOut = gen.open(bOut, true); sigOut.write(TEST_MESSAGE.getBytes()); sigOut.close(); CMSSignedData sd = new CMSSignedData(new CMSProcessableByteArray(TEST_MESSAGE.getBytes()), bOut.toByteArray()); assertEquals(1, sd.getSignerInfos().getSigners().size()); verifyEncodedData(bOut); } public void testAttributeGenerators() throws Exception { final ASN1ObjectIdentifier dummyOid1 = new ASN1ObjectIdentifier("1.2.3"); final ASN1ObjectIdentifier dummyOid2 = new ASN1ObjectIdentifier("1.2.3.4"); List certList = new ArrayList(); ByteArrayOutputStream bOut = new ByteArrayOutputStream(); certList.add(_origCert); certList.add(_signCert); JcaCertStore certs = new JcaCertStore(certList); CMSSignedDataStreamGenerator gen = new CMSSignedDataStreamGenerator(); CMSAttributeTableGenerator signedGen = new DefaultSignedAttributeTableGenerator() { public AttributeTable getAttributes(Map parameters) { Hashtable table = createStandardAttributeTable(parameters); DEROctetString val = new DEROctetString((byte[])parameters.get(CMSAttributeTableGenerator.DIGEST)); Attribute attr = new Attribute(dummyOid1, new DERSet(val)); table.put(attr.getAttrType(), attr); return new AttributeTable(table); } }; CMSAttributeTableGenerator unsignedGen = new CMSAttributeTableGenerator() { public AttributeTable getAttributes(Map parameters) { DEROctetString val = new DEROctetString((byte[])parameters.get(CMSAttributeTableGenerator.SIGNATURE)); Attribute attr = new Attribute(dummyOid2, new DERSet(val)); return new AttributeTable(new DERSet(attr)); } }; ContentSigner sha1Signer = new JcaContentSignerBuilder("SHA1withRSA").setProvider(BC).build(_origKP.getPrivate()); JcaSignerInfoGeneratorBuilder siBuilder = new JcaSignerInfoGeneratorBuilder(new JcaDigestCalculatorProviderBuilder().setProvider(BC).build()); siBuilder.setSignedAttributeGenerator(signedGen).setUnsignedAttributeGenerator(unsignedGen); gen.addSignerInfoGenerator(siBuilder.build(sha1Signer, _origCert)); gen.addCertificates(certs); OutputStream sigOut = gen.open(bOut, true); sigOut.write(TEST_MESSAGE.getBytes()); sigOut.close(); CMSSignedDataParser sp = new CMSSignedDataParser(new JcaDigestCalculatorProviderBuilder().setProvider(BC).build(), bOut.toByteArray()); sp.getSignedContent().drain(); verifySignatures(sp); // // check attributes // SignerInformationStore signers = sp.getSignerInfos(); Collection c = signers.getSigners(); Iterator it = c.iterator(); while (it.hasNext()) { SignerInformation signer = (SignerInformation)it.next(); checkAttribute(signer.getContentDigest(), signer.getSignedAttributes().get(dummyOid1)); checkAttribute(signer.getSignature(), signer.getUnsignedAttributes().get(dummyOid2)); } } private void checkAttribute(byte[] expected, Attribute attr) { DEROctetString value = (DEROctetString)attr.getAttrValues().getObjectAt(0); assertEquals(new DEROctetString(expected), value); } public void testWithAttributeCertificate() throws Exception { List certList = new ArrayList(); certList.add(_signCert); Store certs = new JcaCertStore(certList); CMSSignedDataStreamGenerator gen = new CMSSignedDataStreamGenerator(); ContentSigner sha1Signer = new JcaContentSignerBuilder("SHA1withRSA").setProvider(BC).build(_origKP.getPrivate()); gen.addSignerInfoGenerator(new JcaSignerInfoGeneratorBuilder(new JcaDigestCalculatorProviderBuilder().setProvider(BC).build()).build(sha1Signer, _origCert)); gen.addCertificates(certs); X509AttributeCertificateHolder attrCert = new JcaX509AttributeCertificateHolder(CMSTestUtil.getAttributeCertificate()); Store store = new CollectionStore(Collections.singleton(attrCert)); gen.addAttributeCertificates(store); ByteArrayOutputStream bOut = new ByteArrayOutputStream(); OutputStream sigOut = gen.open(bOut, true); sigOut.write(TEST_MESSAGE.getBytes()); sigOut.close(); CMSSignedDataParser sp = new CMSSignedDataParser(new JcaDigestCalculatorProviderBuilder().setProvider(BC).build(), bOut.toByteArray()); sp.getSignedContent().drain(); assertEquals(4, sp.getVersion()); // store = sp.getAttributeCertificates(); // // Collection coll = store.getMatches(null); // // assertEquals(1, coll.size()); // // assertTrue(coll.contains(new JcaX509AttributeCertificateHolder(attrCert))); } public void testSignerStoreReplacement() throws Exception { List certList = new ArrayList(); ByteArrayOutputStream bOut = new ByteArrayOutputStream(); byte[] data = TEST_MESSAGE.getBytes(); certList.add(_origCert); certList.add(_signCert); Store certs = new JcaCertStore(certList); CMSSignedDataStreamGenerator gen = new CMSSignedDataStreamGenerator(); gen.addSignerInfoGenerator(new JcaSimpleSignerInfoGeneratorBuilder().setProvider(BC).build("SHA1withRSA", _origKP.getPrivate(), _origCert)); gen.addCertificates(certs); OutputStream sigOut = gen.open(bOut, false); sigOut.write(data); sigOut.close(); checkSigParseable(bOut.toByteArray()); // // create new Signer // ByteArrayInputStream original = new ByteArrayInputStream(bOut.toByteArray()); bOut.reset(); gen = new CMSSignedDataStreamGenerator(); gen.addSignerInfoGenerator(new JcaSimpleSignerInfoGeneratorBuilder().setProvider(BC).build("SHA224withRSA", _origKP.getPrivate(), _origCert)); gen.addCertificates(certs); sigOut = gen.open(bOut); sigOut.write(data); sigOut.close(); checkSigParseable(bOut.toByteArray()); CMSSignedData sd = new CMSSignedData(bOut.toByteArray()); // // replace signer // ByteArrayOutputStream newOut = new ByteArrayOutputStream(); CMSSignedDataParser.replaceSigners(original, sd.getSignerInfos(), newOut); sd = new CMSSignedData(new CMSProcessableByteArray(data), newOut.toByteArray()); SignerInformation signer = (SignerInformation)sd.getSignerInfos().getSigners().iterator().next(); assertEquals(signer.getDigestAlgOID(), CMSAlgorithm.SHA224.getId()); CMSSignedDataParser sp = new CMSSignedDataParser(new JcaDigestCalculatorProviderBuilder().setProvider(BC).build(), new CMSTypedStream(new ByteArrayInputStream(data)), newOut.toByteArray()); sp.getSignedContent().drain(); verifySignatures(sp); } public void testEncapsulatedSignerStoreReplacement() throws Exception { List certList = new ArrayList(); ByteArrayOutputStream bOut = new ByteArrayOutputStream(); certList.add(_origCert); certList.add(_signCert); Store certs = new JcaCertStore(certList); CMSSignedDataStreamGenerator gen = new CMSSignedDataStreamGenerator(); gen.addSignerInfoGenerator(new JcaSimpleSignerInfoGeneratorBuilder().setProvider(BC).build("SHA1withRSA", _origKP.getPrivate(), _origCert)); gen.addCertificates(certs); OutputStream sigOut = gen.open(bOut, true); sigOut.write(TEST_MESSAGE.getBytes()); sigOut.close(); // // create new Signer // ByteArrayInputStream original = new ByteArrayInputStream(bOut.toByteArray()); bOut.reset(); gen = new CMSSignedDataStreamGenerator(); gen.addSignerInfoGenerator(new JcaSimpleSignerInfoGeneratorBuilder().setProvider(BC).build("SHA224withRSA", _origKP.getPrivate(), _origCert)); gen.addCertificates(certs); sigOut = gen.open(bOut, true); sigOut.write(TEST_MESSAGE.getBytes()); sigOut.close(); CMSSignedData sd = new CMSSignedData(bOut.toByteArray()); // // replace signer // ByteArrayOutputStream newOut = new ByteArrayOutputStream(); CMSSignedDataParser.replaceSigners(original, sd.getSignerInfos(), newOut); sd = new CMSSignedData(newOut.toByteArray()); SignerInformation signer = (SignerInformation)sd.getSignerInfos().getSigners().iterator().next(); assertEquals(signer.getDigestAlgOID(), CMSAlgorithm.SHA224.getId()); CMSSignedDataParser sp = new CMSSignedDataParser(new JcaDigestCalculatorProviderBuilder().setProvider(BC).build(), newOut.toByteArray()); sp.getSignedContent().drain(); verifySignatures(sp); } public void testCertStoreReplacement() throws Exception { List certList = new ArrayList(); ByteArrayOutputStream bOut = new ByteArrayOutputStream(); byte[] data = TEST_MESSAGE.getBytes(); certList.add(_origDsaCert); JcaCertStore certs = new JcaCertStore(certList); CMSSignedDataStreamGenerator gen = new CMSSignedDataStreamGenerator(); JcaSignerInfoGeneratorBuilder builder = new JcaSignerInfoGeneratorBuilder(new JcaDigestCalculatorProviderBuilder().setProvider(BC).build()); gen.addSignerInfoGenerator(builder.build(new JcaContentSignerBuilder("SHA1withRSA").build(_origKP.getPrivate()), _origCert)); gen.addCertificates(certs); OutputStream sigOut = gen.open(bOut); sigOut.write(data); sigOut.close(); checkSigParseable(bOut.toByteArray()); // // create new certstore with the right certificates // certList = new ArrayList(); certList.add(_origCert); certList.add(_signCert); certs = new JcaCertStore(certList); // // replace certs // ByteArrayInputStream original = new ByteArrayInputStream(bOut.toByteArray()); ByteArrayOutputStream newOut = new ByteArrayOutputStream(); CMSSignedDataParser.replaceCertificatesAndCRLs(original, certs, null, null, newOut); CMSSignedDataParser sp = new CMSSignedDataParser(new JcaDigestCalculatorProviderBuilder().setProvider(BC).build(), new CMSTypedStream(new ByteArrayInputStream(data)), newOut.toByteArray()); sp.getSignedContent().drain(); verifySignatures(sp); } public void testEncapsulatedCertStoreReplacement() throws Exception { List certList = new ArrayList(); ByteArrayOutputStream bOut = new ByteArrayOutputStream(); certList.add(_origDsaCert); Store certs = new JcaCertStore(certList); CMSSignedDataStreamGenerator gen = new CMSSignedDataStreamGenerator(); JcaSignerInfoGeneratorBuilder builder = new JcaSignerInfoGeneratorBuilder(new JcaDigestCalculatorProviderBuilder().setProvider(BC).build()); gen.addSignerInfoGenerator(builder.build(new JcaContentSignerBuilder("SHA1withRSA").build(_origKP.getPrivate()), _origCert)); gen.addCertificates(certs); OutputStream sigOut = gen.open(bOut, true); sigOut.write(TEST_MESSAGE.getBytes()); sigOut.close(); // // create new certstore with the right certificates // certList = new ArrayList(); certList.add(_origCert); certList.add(_signCert); certs = new JcaCertStore(certList); // // replace certs // ByteArrayInputStream original = new ByteArrayInputStream(bOut.toByteArray()); ByteArrayOutputStream newOut = new ByteArrayOutputStream(); CMSSignedDataParser.replaceCertificatesAndCRLs(original, certs, null, null, newOut); CMSSignedDataParser sp = new CMSSignedDataParser(new JcaDigestCalculatorProviderBuilder().setProvider(BC).build(), newOut.toByteArray()); sp.getSignedContent().drain(); verifySignatures(sp); } public void testCertOrdering1() throws Exception { List certList = new ArrayList(); ByteArrayOutputStream bOut = new ByteArrayOutputStream(); certList.add(_origCert); certList.add(_signCert); Store certs = new JcaCertStore(certList); CMSSignedDataStreamGenerator gen = new CMSSignedDataStreamGenerator(); gen.addSignerInfoGenerator(new JcaSimpleSignerInfoGeneratorBuilder().setProvider(BC).build("SHA1withRSA", _origKP.getPrivate(), _origCert)); gen.addCertificates(certs); OutputStream sigOut = gen.open(bOut, true); sigOut.write(TEST_MESSAGE.getBytes()); sigOut.close(); CMSSignedDataParser sp = new CMSSignedDataParser(new JcaDigestCalculatorProviderBuilder().setProvider(BC).build(), bOut.toByteArray()); sp.getSignedContent().drain(); certs = sp.getCertificates(); Iterator it = certs.getMatches(null).iterator(); assertEquals(new JcaX509CertificateHolder(_origCert), it.next()); assertEquals(new JcaX509CertificateHolder(_signCert), it.next()); } public void testCertOrdering2() throws Exception { List certList = new ArrayList(); ByteArrayOutputStream bOut = new ByteArrayOutputStream(); certList.add(_signCert); certList.add(_origCert); Store certs = new JcaCertStore(certList); CMSSignedDataStreamGenerator gen = new CMSSignedDataStreamGenerator(); gen.addSignerInfoGenerator(new JcaSimpleSignerInfoGeneratorBuilder().setProvider(BC).build("SHA1withRSA", _origKP.getPrivate(), _origCert)); gen.addCertificates(certs); OutputStream sigOut = gen.open(bOut, true); sigOut.write(TEST_MESSAGE.getBytes()); sigOut.close(); CMSSignedDataParser sp = new CMSSignedDataParser(new JcaDigestCalculatorProviderBuilder().setProvider(BC).build(), bOut.toByteArray()); sp.getSignedContent().drain(); certs = sp.getCertificates(); Iterator it = certs.getMatches(null).iterator(); assertEquals(new JcaX509CertificateHolder(_signCert), it.next()); assertEquals(new JcaX509CertificateHolder(_origCert), it.next()); } public static Test suite() throws Exception { init(); return new CMSTestSetup(new TestSuite(NewSignedDataStreamTest.class)); } } bouncycastle-1.49.orig/test/src/org/bouncycastle/cms/test/CompressedDataTest.java0000644000175000017500000001506611261266420027633 0ustar ebourgebourgpackage org.bouncycastle.cms.test; import java.util.Arrays; import junit.framework.Test; import junit.framework.TestCase; import junit.framework.TestSuite; import org.bouncycastle.cms.CMSCompressedData; import org.bouncycastle.cms.CMSCompressedDataGenerator; import org.bouncycastle.cms.CMSException; import org.bouncycastle.cms.CMSProcessableByteArray; import org.bouncycastle.util.encoders.Base64; import org.bouncycastle.util.io.StreamOverflowException; public class CompressedDataTest extends TestCase { private static final byte[] TEST_DATA = "Hello world!".getBytes(); /* * * INFRASTRUCTURE * */ public CompressedDataTest(String name) { super(name); } public static void main(String args[]) { junit.textui.TestRunner.run(CompressedDataTest.class); } public static Test suite() { return new CMSTestSetup(new TestSuite(CompressedDataTest.class)); } public void setUp() { } public void tearDown() { } public void testWorkingData() throws Exception { byte[] compData = Base64 .decode("MIAGCyqGSIb3DQEJEAEJoIAwgAIBADANBgsqhkiG9w0BCRADCDCABgkqhkiG9w0BBwGggCSABIIC" + "Hnic7ZRdb9owFIbvK/k/5PqVYPFXGK12YYyboVFASSp1vQtZGiLRACZE49/XHoUW7S/0tXP8Efux" + "fU5ivWnasml72XFb3gb5druui7ytN803M570nii7C5r8tfwR281hy/p/KSM3+jzH5s3+pbQ90xSb" + "P3VT3QbLusnt8WPIuN5vN/vaA2+DulnXTXkXvNTr8j8ouZmkCmGI/UW+ZS/C8zP0bz2dz0zwLt+1" + "UEk2M8mlaxjRMByAhZTj0RGYg4TvogiRASROsZgjpVcJCb1KV6QzQeDJ1XkoQ5Jm+C5PbOHZZGRi" + "v+ORAcshOGeCcdFJyfgFxdtCdEcmOrbinc/+BBMzRThEYpwl+jEBpciSGWQkI0TSlREmD/eOHb2D" + "SGLuESm/iKUFt1y4XHBO2a5oq0IKJKWLS9kUZTA7vC5LSxYmgVL46SIWxIfWBQd6AdrnjLmH94UT" + "vGxVibLqRCtIpp4g2qpdtqK1LiOeolpVK5wVQ5P7+QjZAlrh0cePYTx/gNZuB9Vhndtgujl9T/tg" + "W9ogK+3rnmg3YWygnTuF5GDS+Q/jIVLnCcYZFc6Kk/+c80wKwZjwdZIqDYWRH68MuBQSXLgXYXj2" + "3CAaYOBNJMliTl0X7eV5DnoKIFSKYdj3cRpD/cK/JWTHJRe76MUXnfBW8m7Hd5zhQ4ri2NrVF/WL" + "+kV1/3AGSlJ32bFPd2BsQD8uSzIx6lObkjdz95c0AAAAAAAAAAAAAAAA"); byte[] uncompData = Base64 .decode("Q29udGVudC1UeXBlOiBhcHBsaWNhdGlvbi9FREktWDEyOyBuYW1lPUdyb3VwMi54MTINCkNvbnRl" + "bnQtVHJhbnNmZXItRW5jb2Rpbmc6IGJpbmFyeQ0KQ29udGVudC1EaXNwb3NpdGlvbjogaW5saW5l" + "OyBmaWxlbmFtZT1Hcm91cDIueDEyDQoNCklTQSowMCpzc3Nzc3Nzc3NzKjAwKnJycnJycnJycnIqW" + "loqQ1lDTE9ORSAgICAgICAgKlpaKlBBUlRORVIgICAgICAgICo5NjEwMDcqMjAxMypVKjAwMjAwKj" + "AwMDAwMDAwMSowKlQqKg1HUypQTypTMVMxUzFTMVMxUzFTMVMqUjFSMVIxUjFSMVIxUjFSKjk2MTA" + "wNyoyMDEzKjAwMDAwMDAwNCpYKjAwMzA1MA1TVCo4NTAqMDAwMDQwMDAxDUJFRyowMCpCRSoyYSo0" + "MzMyNDIzNHY1NTIzKjk2MTAwNyoyM3RjNHZ5MjR2MmgzdmgzdmgqWloqSUVMKjA5KlJFKjA5DUNVU" + "ioxMSpUUk4qNTY1Nio2NSo1NjYqSU1GKjAwNio5NjEwMDcNUkVGKjZBKjQzM3IxYzNyMzRyMzRjMz" + "MxMnFjdGdjNTQqUmVmZXJlbmNlIE51bWJlcg1QRVIqQUEqSGFucyBHdXR0ZW4qQ1AqMS4zMjIuMzI" + "zLjQ0NDQqKioqKnJnZzRlZ3Y0dDQNVEFYKjR0Z3RidDR0cjR0cipHTCpnaGdoKioqKioqKioqRypD" + "DUZPQipUUCpDQSpVU0EqMDIqRE9NKkNDKlJlZ3VsYXIgTG9jYXRpb25zIHBlciBUZXJtcw1DVFAqR" + "EUqQzA0KjQ1MyoyNTAwMCpEOSpTRUwqMjMyMTQqMjM0MzI0MjM0MjMqRVMqNDIyNDM0MjMNU0FDKk" + "EqQjAwMCpBRSozNTQ1KjM0NDIzMDANQ1VSKjExKjc2Nyo3NzY3KjY1DVBPMSoxMTEtYWFhKjEwMDA" + "wMDAqQVMqOTAuMDAqQkQqQUsqMjM0MjM1djM1MzRxNmYzNTM0djQzNTM0NTN2cTNxMzIqKioqKioq" + "KioqKkExKnl0cmgNUE8xKjExMS1hYWEqMTAwMDAwMCpBUyo5MC4wMCpCRCpBSyoyMzQyMzV2MzUzN" + "HE2ZjM1MzR2NDM1MzQ1M3ZxM3EzMioqKioqKioqKioqQTEqeXRyaA1QTzEqMTExLWFhYSoxMDAwMD" + "AwKkFTKjkwLjAwKkJEKkFLKjIzNDIzNXYzNTM0cTZmMzUzNHY0MzUzNDUzdnEzcTMyKioqKioqKio" + "qKipBMSp5dHJoDVBPMSoxMTEtYWFhKjEwMDAwMDAqQVMqOTAuMDAqQkQqQUsqMjM0MjM1djM1MzRx" + "NmYzNTM0djQzNTM0NTN2cTNxMzIqKioqKioqKioqKkExKnl0cmgNUE8xKjExMS1hYWEqMTAwMDAwM" + "CpBUyo5MC4wMCpCRCpBSyoyMzQyMzV2MzUzNHE2ZjM1MzR2NDM1MzQ1M3ZxM3EzMioqKioqKioqKi" + "oqQTEqeXRyaA1QTzEqMTExLWFhYSoxMDAwMDAwKkFTKjkwLjAwKkJEKkFLKjIzNDIzNXYzNTM0cTZ" + "mMzUzNHY0MzUzNDUzdnEzcTMyKioqKioqKioqKipBMSp5dHJoDVBPMSoxMTEtYWFhKjEwMDAwMDAq" + "QVMqOTAuMDAqQkQqQUsqMjM0MjM1djM1MzRxNmYzNTM0djQzNTM0NTN2cTNxMzIqKioqKioqKioqK" + "kExKnl0cmgNUE8xKjExMS1hYWEqMTAwMDAwMCpBUyo5MC4wMCpCRCpBSyoyMzQyMzV2MzUzNHE2Zj" + "M1MzR2NDM1MzQ1M3ZxM3EzMioqKioqKioqKioqQTEqeXRyaA1QTzEqMTExLWFhYSoxMDAwMDAwKkF" + "TKjkwLjAwKkJEKkFLKjIzNDIzNXYzNTM0cTZmMzUzNHY0MzUzNDUzdnEzcTMyKioqKioqKioqKipB" + "MSp5dHJoDVBPMSoxMTEtYWFhKjEwMDAwMDAqQVMqOTAuMDAqQkQqQUsqMjM0MjM1djM1MzRxNmYzN" + "TM0djQzNTM0NTN2cTNxMzIqKioqKioqKioqKkExKnl0cmgNQ1RUKjENU0UqMjIqMDAwMDQwMDAxDUdFKjEqMDAwMDAwMDA0DUlFQSoxKjAwMDAwMDAwMQ0="); CMSCompressedData ed = new CMSCompressedData(compData); assertEquals(true, Arrays.equals(uncompData, ed.getContent())); } public void testEach() throws Exception { CMSCompressedData cd = getStdData(); assertEquals(true, Arrays.equals(TEST_DATA, cd.getContent())); } public void testLimitUnder() throws Exception { CMSCompressedData cd = getStdData(); try { cd.getContent(TEST_DATA.length / 2); } catch (CMSException e) { assertEquals(true, e.getCause() instanceof StreamOverflowException); } } public void testLimitOver() throws Exception { CMSCompressedData cd = getStdData(); assertEquals(true, Arrays.equals(TEST_DATA, cd.getContent(TEST_DATA.length * 2))); } public void testLimitEqual() throws Exception { CMSCompressedData cd = getStdData(); assertEquals(true, Arrays.equals(TEST_DATA, cd.getContent(TEST_DATA.length))); } private CMSCompressedData getStdData() throws CMSException { CMSProcessableByteArray testData = new CMSProcessableByteArray(TEST_DATA); CMSCompressedDataGenerator gen = new CMSCompressedDataGenerator(); return gen.generate(testData, CMSCompressedDataGenerator.ZLIB); } } bouncycastle-1.49.orig/test/src/org/bouncycastle/cms/test/AuthenticatedDataTest.java0000644000175000017500000002363411417520647030320 0ustar ebourgebourgpackage org.bouncycastle.cms.test; import java.security.KeyPair; import java.security.NoSuchAlgorithmException; import java.security.NoSuchProviderException; import java.security.cert.X509Certificate; import java.util.Arrays; import java.util.Collection; import java.util.Iterator; import javax.crypto.SecretKey; import junit.framework.Test; import junit.framework.TestCase; import junit.framework.TestSuite; import org.bouncycastle.asn1.DERObjectIdentifier; import org.bouncycastle.asn1.pkcs.PKCSObjectIdentifiers; import org.bouncycastle.cms.CMSAuthenticatedData; import org.bouncycastle.cms.CMSAuthenticatedDataGenerator; import org.bouncycastle.cms.CMSException; import org.bouncycastle.cms.CMSPBEKey; import org.bouncycastle.cms.CMSProcessableByteArray; import org.bouncycastle.cms.PKCS5Scheme2PBEKey; import org.bouncycastle.cms.PasswordRecipientInformation; import org.bouncycastle.cms.RecipientInformation; import org.bouncycastle.cms.RecipientInformationStore; import org.bouncycastle.jce.provider.BouncyCastleProvider; import org.bouncycastle.util.encoders.Hex; public class AuthenticatedDataTest extends TestCase { private static final String BC = BouncyCastleProvider.PROVIDER_NAME; private static String _signDN; private static KeyPair _signKP; private static X509Certificate _signCert; private static String _origDN; private static KeyPair _origKP; private static X509Certificate _origCert; private static String _reciDN; private static KeyPair _reciKP; private static X509Certificate _reciCert; private static KeyPair _origEcKP; private static KeyPair _reciEcKP; private static X509Certificate _reciEcCert; private static boolean _initialised = false; public boolean DEBUG = true; private static void init() throws Exception { if (!_initialised) { _initialised = true; _signDN = "O=Bouncy Castle, C=AU"; _signKP = CMSTestUtil.makeKeyPair(); _signCert = CMSTestUtil.makeCertificate(_signKP, _signDN, _signKP, _signDN); _origDN = "CN=Bob, OU=Sales, O=Bouncy Castle, C=AU"; _origKP = CMSTestUtil.makeKeyPair(); _origCert = CMSTestUtil.makeCertificate(_origKP, _origDN, _signKP, _signDN); _reciDN = "CN=Doug, OU=Sales, O=Bouncy Castle, C=AU"; _reciKP = CMSTestUtil.makeKeyPair(); _reciCert = CMSTestUtil.makeCertificate(_reciKP, _reciDN, _signKP, _signDN); _origEcKP = CMSTestUtil.makeEcDsaKeyPair(); _reciEcKP = CMSTestUtil.makeEcDsaKeyPair(); _reciEcCert = CMSTestUtil.makeCertificate(_reciEcKP, _reciDN, _signKP, _signDN); } } public void setUp() throws Exception { init(); } public AuthenticatedDataTest(String name) { super(name); } public static void main(String args[]) { junit.textui.TestRunner.run(AuthenticatedDataTest.class); } public static Test suite() throws Exception { init(); return new CMSTestSetup(new TestSuite(AuthenticatedDataTest.class)); } public void testKeyTransDESede() throws Exception { tryKeyTrans(CMSAuthenticatedDataGenerator.DES_EDE3_CBC); } public void testKEKDESede() throws Exception { tryKekAlgorithm(CMSTestUtil.makeDesede192Key(), new DERObjectIdentifier("1.2.840.113549.1.9.16.3.6")); } public void testPasswordAES256() throws Exception { passwordTest(CMSAuthenticatedDataGenerator.AES256_CBC); } public void testECKeyAgree() throws Exception { byte[] data = Hex.decode("504b492d4320434d5320456e76656c6f706564446174612053616d706c65"); CMSAuthenticatedDataGenerator adGen = new CMSAuthenticatedDataGenerator(); adGen.addKeyAgreementRecipient(CMSAuthenticatedDataGenerator.ECDH_SHA1KDF, _origEcKP.getPrivate(), _origEcKP.getPublic(), _reciEcCert, CMSAuthenticatedDataGenerator.AES128_WRAP, BC); CMSAuthenticatedData ad = adGen.generate( new CMSProcessableByteArray(data), CMSAuthenticatedDataGenerator.DES_EDE3_CBC, BC); RecipientInformationStore recipients = ad.getRecipientInfos(); assertEquals(ad.getMacAlgOID(), CMSAuthenticatedDataGenerator.DES_EDE3_CBC); Collection c = recipients.getRecipients(); Iterator it = c.iterator(); if (it.hasNext()) { RecipientInformation recipient = (RecipientInformation)it.next(); byte[] recData = recipient.getContent(_reciEcKP.getPrivate(), BC); assertTrue(Arrays.equals(data, recData)); assertTrue(Arrays.equals(ad.getMac(), recipient.getMac())); } else { fail("no recipient found"); } } public void testEncoding() throws Exception { byte[] data = "Eric H. Echidna".getBytes(); CMSAuthenticatedDataGenerator adGen = new CMSAuthenticatedDataGenerator(); adGen.addKeyTransRecipient(_reciCert); CMSAuthenticatedData ad = adGen.generate( new CMSProcessableByteArray(data), CMSAuthenticatedDataGenerator.DES_EDE3_CBC, BC); ad = new CMSAuthenticatedData(ad.getEncoded()); RecipientInformationStore recipients = ad.getRecipientInfos(); assertEquals(CMSAuthenticatedDataGenerator.DES_EDE3_CBC, ad.getMacAlgOID()); Collection c = recipients.getRecipients(); assertEquals(1, c.size()); Iterator it = c.iterator(); while (it.hasNext()) { RecipientInformation recipient = (RecipientInformation)it.next(); assertEquals(recipient.getKeyEncryptionAlgOID(), PKCSObjectIdentifiers.rsaEncryption.getId()); byte[] recData = recipient.getContent(_reciKP.getPrivate(), BC); assertTrue(Arrays.equals(data, recData)); assertTrue(Arrays.equals(ad.getMac(), recipient.getMac())); } } private void tryKeyTrans(String macAlg) throws Exception { byte[] data = "Eric H. Echidna".getBytes(); CMSAuthenticatedDataGenerator adGen = new CMSAuthenticatedDataGenerator(); adGen.addKeyTransRecipient(_reciCert); CMSAuthenticatedData ad = adGen.generate( new CMSProcessableByteArray(data), macAlg, BC); RecipientInformationStore recipients = ad.getRecipientInfos(); assertEquals(ad.getMacAlgOID(), macAlg); Collection c = recipients.getRecipients(); assertEquals(1, c.size()); Iterator it = c.iterator(); while (it.hasNext()) { RecipientInformation recipient = (RecipientInformation)it.next(); assertEquals(recipient.getKeyEncryptionAlgOID(), PKCSObjectIdentifiers.rsaEncryption.getId()); byte[] recData = recipient.getContent(_reciKP.getPrivate(), BC); assertTrue(Arrays.equals(data, recData)); assertTrue(Arrays.equals(ad.getMac(), recipient.getMac())); } } private void tryKekAlgorithm(SecretKey kek, DERObjectIdentifier algOid) throws NoSuchAlgorithmException, NoSuchProviderException, CMSException { byte[] data = "Eric H. Echidna".getBytes(); CMSAuthenticatedDataGenerator adGen = new CMSAuthenticatedDataGenerator(); byte[] kekId = new byte[] { 1, 2, 3, 4, 5 }; adGen.addKEKRecipient(kek, kekId); CMSAuthenticatedData ad = adGen.generate( new CMSProcessableByteArray(data), CMSAuthenticatedDataGenerator.DES_EDE3_CBC, BC); RecipientInformationStore recipients = ad.getRecipientInfos(); Collection c = recipients.getRecipients(); Iterator it = c.iterator(); assertEquals(ad.getMacAlgOID(), CMSAuthenticatedDataGenerator.DES_EDE3_CBC); if (it.hasNext()) { RecipientInformation recipient = (RecipientInformation)it.next(); assertEquals(recipient.getKeyEncryptionAlgOID(), algOid.getId()); byte[] recData = recipient.getContent(kek, BC); assertTrue(Arrays.equals(data, recData)); assertTrue(Arrays.equals(ad.getMac(), recipient.getMac())); } else { fail("no recipient found"); } } private void passwordTest(String algorithm) throws Exception { byte[] data = Hex.decode("504b492d4320434d5320456e76656c6f706564446174612053616d706c65"); CMSAuthenticatedDataGenerator adGen = new CMSAuthenticatedDataGenerator(); adGen.addPasswordRecipient(new PKCS5Scheme2PBEKey("password".toCharArray(), new byte[20], 5), algorithm); CMSAuthenticatedData ad = adGen.generate( new CMSProcessableByteArray(data), CMSAuthenticatedDataGenerator.DES_EDE3_CBC, BC); RecipientInformationStore recipients = ad.getRecipientInfos(); assertEquals(ad.getMacAlgOID(), CMSAuthenticatedDataGenerator.DES_EDE3_CBC); Collection c = recipients.getRecipients(); Iterator it = c.iterator(); if (it.hasNext()) { PasswordRecipientInformation recipient = (PasswordRecipientInformation)it.next(); CMSPBEKey key = new PKCS5Scheme2PBEKey("password".toCharArray(), recipient.getKeyDerivationAlgParameters(BC)); byte[] recData = recipient.getContent(key, BC); assertTrue(Arrays.equals(data, recData)); assertTrue(Arrays.equals(ad.getMac(), recipient.getMac())); } else { fail("no recipient found"); } } }bouncycastle-1.49.orig/test/src/org/bouncycastle/cms/test/NewEnvelopedDataStreamTest.java0000644000175000017500000006603311701215134031271 0ustar ebourgebourgpackage org.bouncycastle.cms.test; import java.io.BufferedOutputStream; import java.io.ByteArrayOutputStream; import java.io.InputStream; import java.io.OutputStream; import java.security.KeyFactory; import java.security.KeyPair; import java.security.PrivateKey; import java.security.Security; import java.security.cert.X509Certificate; import java.security.spec.PKCS8EncodedKeySpec; import java.util.Arrays; import java.util.Collection; import java.util.Hashtable; import java.util.Iterator; import javax.crypto.SecretKey; import junit.framework.Test; import junit.framework.TestCase; import junit.framework.TestSuite; import org.bouncycastle.asn1.ASN1InputStream; import org.bouncycastle.asn1.DEROutputStream; import org.bouncycastle.asn1.DERSet; import org.bouncycastle.asn1.DERUTF8String; import org.bouncycastle.asn1.cms.Attribute; import org.bouncycastle.asn1.cms.AttributeTable; import org.bouncycastle.asn1.pkcs.PKCSObjectIdentifiers; import org.bouncycastle.asn1.x500.X500Name; import org.bouncycastle.cert.X509CertificateHolder; import org.bouncycastle.cms.CMSAlgorithm; import org.bouncycastle.cms.CMSEnvelopedDataGenerator; import org.bouncycastle.cms.CMSEnvelopedDataParser; import org.bouncycastle.cms.CMSEnvelopedDataStreamGenerator; import org.bouncycastle.cms.CMSTypedStream; import org.bouncycastle.cms.KEKRecipientId; import org.bouncycastle.cms.OriginatorInfoGenerator; import org.bouncycastle.cms.OriginatorInformation; import org.bouncycastle.cms.RecipientId; import org.bouncycastle.cms.RecipientInformation; import org.bouncycastle.cms.RecipientInformationStore; import org.bouncycastle.cms.SimpleAttributeTableGenerator; import org.bouncycastle.cms.jcajce.JceCMSContentEncryptorBuilder; import org.bouncycastle.cms.jcajce.JceKEKEnvelopedRecipient; import org.bouncycastle.cms.jcajce.JceKEKRecipientInfoGenerator; import org.bouncycastle.cms.jcajce.JceKeyAgreeEnvelopedRecipient; import org.bouncycastle.cms.jcajce.JceKeyAgreeRecipientId; import org.bouncycastle.cms.jcajce.JceKeyAgreeRecipientInfoGenerator; import org.bouncycastle.cms.jcajce.JceKeyTransEnvelopedRecipient; import org.bouncycastle.cms.jcajce.JceKeyTransRecipientInfoGenerator; import org.bouncycastle.jce.provider.BouncyCastleProvider; import org.bouncycastle.util.encoders.Base64; import org.bouncycastle.util.encoders.Hex; public class NewEnvelopedDataStreamTest extends TestCase { private static final String BC = BouncyCastleProvider.PROVIDER_NAME; private static final int BUFFER_SIZE = 4000; private static String _signDN; private static KeyPair _signKP; private static X509Certificate _signCert; private static String _origDN; private static KeyPair _origKP; private static X509Certificate _origCert; private static String _reciDN; private static KeyPair _reciKP; private static X509Certificate _reciCert; private static KeyPair _origEcKP; private static KeyPair _reciEcKP; private static X509Certificate _reciEcCert; private static boolean _initialised = false; public NewEnvelopedDataStreamTest() { } private static void init() throws Exception { if (!_initialised) { _initialised = true; _signDN = "O=Bouncy Castle, C=AU"; _signKP = CMSTestUtil.makeKeyPair(); _signCert = CMSTestUtil.makeCertificate(_signKP, _signDN, _signKP, _signDN); _origDN = "CN=Bob, OU=Sales, O=Bouncy Castle, C=AU"; _origKP = CMSTestUtil.makeKeyPair(); _origCert = CMSTestUtil.makeCertificate(_origKP, _origDN, _signKP, _signDN); _reciDN = "CN=Doug, OU=Sales, O=Bouncy Castle, C=AU"; _reciKP = CMSTestUtil.makeKeyPair(); _reciCert = CMSTestUtil.makeCertificate(_reciKP, _reciDN, _signKP, _signDN); _origEcKP = CMSTestUtil.makeEcDsaKeyPair(); _reciEcKP = CMSTestUtil.makeEcDsaKeyPair(); _reciEcCert = CMSTestUtil.makeCertificate(_reciEcKP, _reciDN, _signKP, _signDN); } } public void setUp() throws Exception { init(); } public void testWorkingData() throws Exception { byte[] keyData = Base64.decode( "MIICdgIBADANBgkqhkiG9w0BAQEFAASCAmAwggJcAgEAAoGBAKrAz/SQKrcQ" + "nj9IxHIfKDbuXsMqUpI06s2gps6fp7RDNvtUDDMOciWGFhD45YSy8GO0mPx3" + "Nkc7vKBqX4TLcqLUz7kXGOHGOwiPZoNF+9jBMPNROe/B0My0PkWg9tuq+nxN" + "64oD47+JvDwrpNOS5wsYavXeAW8Anv9ZzHLU7KwZAgMBAAECgYA/fqdVt+5K" + "WKGfwr1Z+oAHvSf7xtchiw/tGtosZ24DOCNP3fcTXUHQ9kVqVkNyzt9ZFCT3" + "bJUAdBQ2SpfuV4DusVeQZVzcROKeA09nPkxBpTefWbSDQGhb+eZq9L8JDRSW" + "HyYqs+MBoUpLw7GKtZiJkZyY6CsYkAnQ+uYVWq/TIQJBAP5zafO4HUV/w4KD" + "VJi+ua+GYF1Sg1t/dYL1kXO9GP1p75YAmtm6LdnOCas7wj70/G1YlPGkOP0V" + "GFzeG5KAmAUCQQCryvKU9nwWA+kypcQT9Yr1P4vGS0APYoBThnZq7jEPc5Cm" + "ZI82yseSxSeea0+8KQbZ5mvh1p3qImDLEH/iNSQFAkAghS+tboKPN10NeSt+" + "uiGRRWNbiggv0YJ7Uldcq3ZeLQPp7/naiekCRUsHD4Qr97OrZf7jQ1HlRqTu" + "eZScjMLhAkBNUMZCQnhwFAyEzdPkQ7LpU1MdyEopYmRssuxijZao5JLqQAGw" + "YCzXokGFa7hz72b09F4DQurJL/WuDlvvu4jdAkEAxwT9lylvfSfEQw4/qQgZ" + "MFB26gqB6Gqs1pHIZCzdliKx5BO3VDeUGfXMI8yOkbXoWbYx5xPid/+N8R//" + "+sxLBw=="); byte[] envData = Base64.decode( "MIAGCSqGSIb3DQEHA6CAMIACAQAxgcQwgcECAQAwKjAlMRYwFAYDVQQKEw1C" + "b3VuY3kgQ2FzdGxlMQswCQYDVQQGEwJBVQIBHjANBgkqhkiG9w0BAQEFAASB" + "gDmnaDZ0vDJNlaUSYyEXsgbaUH+itNTjCOgv77QTX2ImXj+kTctM19PQF2I1" + "0/NL0fjakvCgBTHKmk13a7jqB6cX3bysenHNrglHsgNGgeXQ7ggAq5fV/JQQ" + "T7rSxEtuwpbuHQnoVUZahOHVKy/a0uLr9iIh1A3y+yZTZaG505ZJMIAGCSqG" + "SIb3DQEHATAdBglghkgBZQMEAQIEENmkYNbDXiZxJWtq82qIRZKggAQgkOGr" + "1JcTsADStez1eY4+rO4DtyBIyUYQ3pilnbirfPkAAAAAAAAAAAAA"); CMSEnvelopedDataParser ep = new CMSEnvelopedDataParser(envData); RecipientInformationStore recipients = ep.getRecipientInfos(); assertEquals(ep.getEncryptionAlgOID(), CMSEnvelopedDataGenerator.AES128_CBC); Collection c = recipients.getRecipients(); Iterator it = c.iterator(); PKCS8EncodedKeySpec keySpec = new PKCS8EncodedKeySpec(keyData); KeyFactory keyFact = KeyFactory.getInstance("RSA", BC); PrivateKey priKey = keyFact.generatePrivate(keySpec); byte[] data = Hex.decode("57616c6c6157616c6c6157617368696e67746f6e"); while (it.hasNext()) { RecipientInformation recipient = (RecipientInformation)it.next(); assertEquals(recipient.getKeyEncryptionAlgOID(), PKCSObjectIdentifiers.rsaEncryption.getId()); CMSTypedStream recData = recipient.getContentStream(new JceKeyTransEnvelopedRecipient(priKey).setProvider(BC)); assertEquals(true, Arrays.equals(data, CMSTestUtil.streamToByteArray(recData.getContentStream()))); } } private void verifyData( ByteArrayOutputStream encodedStream, String expectedOid, byte[] expectedData) throws Exception { CMSEnvelopedDataParser ep = new CMSEnvelopedDataParser(encodedStream.toByteArray()); RecipientInformationStore recipients = ep.getRecipientInfos(); assertEquals(ep.getEncryptionAlgOID(), expectedOid); Collection c = recipients.getRecipients(); Iterator it = c.iterator(); while (it.hasNext()) { RecipientInformation recipient = (RecipientInformation)it.next(); assertEquals(recipient.getKeyEncryptionAlgOID(), PKCSObjectIdentifiers.rsaEncryption.getId()); CMSTypedStream recData = recipient.getContentStream(new JceKeyTransEnvelopedRecipient(_reciKP.getPrivate()).setProvider(BC)); assertEquals(true, Arrays.equals(expectedData, CMSTestUtil.streamToByteArray(recData.getContentStream()))); } } public void testUnprotectedAttributes() throws Exception { byte[] data = "WallaWallaWashington".getBytes(); CMSEnvelopedDataStreamGenerator edGen = new CMSEnvelopedDataStreamGenerator(); edGen.addRecipientInfoGenerator(new JceKeyTransRecipientInfoGenerator(_reciCert).setProvider(BC)); Hashtable attrs = new Hashtable(); attrs.put(PKCSObjectIdentifiers.id_aa_contentHint, new Attribute(PKCSObjectIdentifiers.id_aa_contentHint, new DERSet(new DERUTF8String("Hint")))); attrs.put(PKCSObjectIdentifiers.id_aa_receiptRequest, new Attribute(PKCSObjectIdentifiers.id_aa_receiptRequest, new DERSet(new DERUTF8String("Request")))); AttributeTable attrTable = new AttributeTable(attrs); edGen.setUnprotectedAttributeGenerator(new SimpleAttributeTableGenerator(attrTable)); ByteArrayOutputStream bOut = new ByteArrayOutputStream(); OutputStream out = edGen.open( bOut, new JceCMSContentEncryptorBuilder(CMSAlgorithm.AES128_CBC).setProvider(BC).build()); out.write(data); out.close(); CMSEnvelopedDataParser ed = new CMSEnvelopedDataParser(bOut.toByteArray()); RecipientInformationStore recipients = ed.getRecipientInfos(); Collection c = recipients.getRecipients(); assertEquals(1, c.size()); Iterator it = c.iterator(); while (it.hasNext()) { RecipientInformation recipient = (RecipientInformation)it.next(); assertEquals(recipient.getKeyEncryptionAlgOID(), PKCSObjectIdentifiers.rsaEncryption.getId()); byte[] recData = recipient.getContent(new JceKeyTransEnvelopedRecipient(_reciKP.getPrivate()).setProvider(BC)); assertEquals(true, Arrays.equals(data, recData)); } attrTable = ed.getUnprotectedAttributes(); assertEquals(attrs.size(), 2); assertEquals(new DERUTF8String("Hint"), attrTable.get(PKCSObjectIdentifiers.id_aa_contentHint).getAttrValues().getObjectAt(0)); assertEquals(new DERUTF8String("Request"), attrTable.get(PKCSObjectIdentifiers.id_aa_receiptRequest).getAttrValues().getObjectAt(0)); } public void testKeyTransAES128BufferedStream() throws Exception { byte[] data = new byte[2000]; for (int i = 0; i != 2000; i++) { data[i] = (byte)(i & 0xff); } // // unbuffered // CMSEnvelopedDataStreamGenerator edGen = new CMSEnvelopedDataStreamGenerator(); edGen.addRecipientInfoGenerator(new JceKeyTransRecipientInfoGenerator(_reciCert).setProvider(BC)); ByteArrayOutputStream bOut = new ByteArrayOutputStream(); OutputStream out = edGen.open( bOut, new JceCMSContentEncryptorBuilder(CMSAlgorithm.AES128_CBC).setProvider(BC).build()); for (int i = 0; i != 2000; i++) { out.write(data[i]); } out.close(); verifyData(bOut, CMSEnvelopedDataGenerator.AES128_CBC, data); int unbufferedLength = bOut.toByteArray().length; // // Using buffered output - should be == to unbuffered // edGen = new CMSEnvelopedDataStreamGenerator(); edGen.addRecipientInfoGenerator(new JceKeyTransRecipientInfoGenerator(_reciCert).setProvider(BC)); bOut = new ByteArrayOutputStream(); out = edGen.open(bOut, new JceCMSContentEncryptorBuilder(CMSAlgorithm.AES128_CBC).setProvider(BC).build()); BufferedOutputStream bfOut = new BufferedOutputStream(out, 300); for (int i = 0; i != 2000; i++) { bfOut.write(data[i]); } bfOut.close(); verifyData(bOut, CMSEnvelopedDataGenerator.AES128_CBC, data); assertTrue(bOut.toByteArray().length == unbufferedLength); } public void testKeyTransAES128Buffered() throws Exception { byte[] data = new byte[2000]; for (int i = 0; i != 2000; i++) { data[i] = (byte)(i & 0xff); } // // unbuffered // CMSEnvelopedDataStreamGenerator edGen = new CMSEnvelopedDataStreamGenerator(); edGen.addRecipientInfoGenerator(new JceKeyTransRecipientInfoGenerator(_reciCert).setProvider(BC)); ByteArrayOutputStream bOut = new ByteArrayOutputStream(); OutputStream out = edGen.open( bOut, new JceCMSContentEncryptorBuilder(CMSAlgorithm.AES128_CBC).setProvider(BC).build()); for (int i = 0; i != 2000; i++) { out.write(data[i]); } out.close(); verifyData(bOut, CMSEnvelopedDataGenerator.AES128_CBC, data); int unbufferedLength = bOut.toByteArray().length; // // buffered - less than default of 1000 // edGen = new CMSEnvelopedDataStreamGenerator(); edGen.setBufferSize(300); edGen.addRecipientInfoGenerator(new JceKeyTransRecipientInfoGenerator(_reciCert).setProvider(BC)); bOut = new ByteArrayOutputStream(); out = edGen.open(bOut, new JceCMSContentEncryptorBuilder(CMSAlgorithm.AES128_CBC).setProvider(BC).build()); for (int i = 0; i != 2000; i++) { out.write(data[i]); } out.close(); verifyData(bOut, CMSEnvelopedDataGenerator.AES128_CBC, data); assertTrue(bOut.toByteArray().length > unbufferedLength); } public void testKeyTransAES128Der() throws Exception { byte[] data = new byte[2000]; for (int i = 0; i != 2000; i++) { data[i] = (byte)(i & 0xff); } CMSEnvelopedDataStreamGenerator edGen = new CMSEnvelopedDataStreamGenerator(); edGen.addRecipientInfoGenerator(new JceKeyTransRecipientInfoGenerator(_reciCert).setProvider(BC)); ByteArrayOutputStream bOut = new ByteArrayOutputStream(); OutputStream out = edGen.open( bOut, new JceCMSContentEncryptorBuilder(CMSAlgorithm.AES128_CBC).setProvider(BC).build()); for (int i = 0; i != 2000; i++) { out.write(data[i]); } out.close(); // convert to DER ASN1InputStream aIn = new ASN1InputStream(bOut.toByteArray()); bOut.reset(); DEROutputStream dOut = new DEROutputStream(bOut); dOut.writeObject(aIn.readObject()); verifyData(bOut, CMSEnvelopedDataGenerator.AES128_CBC, data); } public void testKeyTransAES128Throughput() throws Exception { byte[] data = new byte[40001]; for (int i = 0; i != data.length; i++) { data[i] = (byte)(i & 0xff); } // // buffered // CMSEnvelopedDataStreamGenerator edGen = new CMSEnvelopedDataStreamGenerator(); edGen.setBufferSize(BUFFER_SIZE); edGen.addRecipientInfoGenerator(new JceKeyTransRecipientInfoGenerator(_reciCert).setProvider(BC)); ByteArrayOutputStream bOut = new ByteArrayOutputStream(); OutputStream out = edGen.open(bOut, new JceCMSContentEncryptorBuilder(CMSAlgorithm.AES128_CBC).setProvider(BC).build()); for (int i = 0; i != data.length; i++) { out.write(data[i]); } out.close(); CMSEnvelopedDataParser ep = new CMSEnvelopedDataParser(bOut.toByteArray()); RecipientInformationStore recipients = ep.getRecipientInfos(); Collection c = recipients.getRecipients(); Iterator it = c.iterator(); if (it.hasNext()) { RecipientInformation recipient = (RecipientInformation)it.next(); assertEquals(recipient.getKeyEncryptionAlgOID(), PKCSObjectIdentifiers.rsaEncryption.getId()); CMSTypedStream recData = recipient.getContentStream(new JceKeyTransEnvelopedRecipient(_reciKP.getPrivate()).setProvider(BC)); InputStream dataStream = recData.getContentStream(); ByteArrayOutputStream dataOut = new ByteArrayOutputStream(); int len; byte[] buf = new byte[BUFFER_SIZE]; int count = 0; while (count != 10 && (len = dataStream.read(buf)) > 0) { assertEquals(buf.length, len); dataOut.write(buf); count++; } len = dataStream.read(buf); dataOut.write(buf, 0, len); assertEquals(true, Arrays.equals(data, dataOut.toByteArray())); } else { fail("recipient not found."); } } public void testKeyTransAES128AndOriginatorInfo() throws Exception { byte[] data = "WallaWallaWashington".getBytes(); CMSEnvelopedDataStreamGenerator edGen = new CMSEnvelopedDataStreamGenerator(); X509CertificateHolder origCert = new X509CertificateHolder(_origCert.getEncoded()); edGen.setOriginatorInfo(new OriginatorInfoGenerator(origCert).generate()); edGen.addRecipientInfoGenerator(new JceKeyTransRecipientInfoGenerator(_reciCert).setProvider(BC)); ByteArrayOutputStream bOut = new ByteArrayOutputStream(); OutputStream out = edGen.open( bOut, new JceCMSContentEncryptorBuilder(CMSAlgorithm.AES128_CBC).setProvider(BC).build()); out.write(data); out.close(); CMSEnvelopedDataParser ep = new CMSEnvelopedDataParser(bOut.toByteArray()); assertTrue(ep.getOriginatorInfo().getCertificates().getMatches(null).contains(origCert)); RecipientInformationStore recipients = ep.getRecipientInfos(); assertEquals(ep.getEncryptionAlgOID(), CMSEnvelopedDataGenerator.AES128_CBC); Collection c = recipients.getRecipients(); Iterator it = c.iterator(); while (it.hasNext()) { RecipientInformation recipient = (RecipientInformation)it.next(); assertEquals(recipient.getKeyEncryptionAlgOID(), PKCSObjectIdentifiers.rsaEncryption.getId()); CMSTypedStream recData = recipient.getContentStream(new JceKeyTransEnvelopedRecipient(_reciKP.getPrivate()).setProvider(BC)); assertEquals(true, Arrays.equals(data, CMSTestUtil.streamToByteArray(recData.getContentStream()))); } ep.close(); } public void testKeyTransAES128() throws Exception { byte[] data = "WallaWallaWashington".getBytes(); CMSEnvelopedDataStreamGenerator edGen = new CMSEnvelopedDataStreamGenerator(); edGen.addRecipientInfoGenerator(new JceKeyTransRecipientInfoGenerator(_reciCert).setProvider(BC)); ByteArrayOutputStream bOut = new ByteArrayOutputStream(); OutputStream out = edGen.open( bOut, new JceCMSContentEncryptorBuilder(CMSAlgorithm.AES128_CBC).setProvider(BC).build()); out.write(data); out.close(); CMSEnvelopedDataParser ep = new CMSEnvelopedDataParser(bOut.toByteArray()); RecipientInformationStore recipients = ep.getRecipientInfos(); assertEquals(ep.getEncryptionAlgOID(), CMSEnvelopedDataGenerator.AES128_CBC); Collection c = recipients.getRecipients(); Iterator it = c.iterator(); while (it.hasNext()) { RecipientInformation recipient = (RecipientInformation)it.next(); assertEquals(recipient.getKeyEncryptionAlgOID(), PKCSObjectIdentifiers.rsaEncryption.getId()); CMSTypedStream recData = recipient.getContentStream(new JceKeyTransEnvelopedRecipient(_reciKP.getPrivate()).setProvider(BC)); assertEquals(true, Arrays.equals(data, CMSTestUtil.streamToByteArray(recData.getContentStream()))); } ep.close(); } public void testKeyTransCAST5SunJCE() throws Exception { if (Security.getProvider("SunJCE") == null) { return; } String version = System.getProperty("java.version"); if (version.startsWith("1.4") || version.startsWith("1.3")) { return; } byte[] data = "WallaWallaWashington".getBytes(); CMSEnvelopedDataStreamGenerator edGen = new CMSEnvelopedDataStreamGenerator(); edGen.addRecipientInfoGenerator(new JceKeyTransRecipientInfoGenerator(_reciCert).setProvider("SunJCE")); ByteArrayOutputStream bOut = new ByteArrayOutputStream(); OutputStream out = edGen.open( bOut, new JceCMSContentEncryptorBuilder(CMSAlgorithm.CAST5_CBC).setProvider(BC).build()); out.write(data); out.close(); CMSEnvelopedDataParser ep = new CMSEnvelopedDataParser(bOut.toByteArray()); RecipientInformationStore recipients = ep.getRecipientInfos(); assertEquals(ep.getEncryptionAlgOID(), CMSEnvelopedDataGenerator.CAST5_CBC); Collection c = recipients.getRecipients(); Iterator it = c.iterator(); while (it.hasNext()) { RecipientInformation recipient = (RecipientInformation)it.next(); assertEquals(recipient.getKeyEncryptionAlgOID(), PKCSObjectIdentifiers.rsaEncryption.getId()); CMSTypedStream recData = recipient.getContentStream(new JceKeyTransEnvelopedRecipient(_reciKP.getPrivate()).setProvider("SunJCE").setContentProvider(BC)); assertEquals(true, Arrays.equals(data, CMSTestUtil.streamToByteArray(recData.getContentStream()))); } ep.close(); } public void testAESKEK() throws Exception { byte[] data = "WallaWallaWashington".getBytes(); SecretKey kek = CMSTestUtil.makeAES192Key(); CMSEnvelopedDataStreamGenerator edGen = new CMSEnvelopedDataStreamGenerator(); byte[] kekId = new byte[] { 1, 2, 3, 4, 5 }; edGen.addRecipientInfoGenerator(new JceKEKRecipientInfoGenerator(kekId, kek).setProvider(BC)); ByteArrayOutputStream bOut = new ByteArrayOutputStream(); OutputStream out = edGen.open( bOut, new JceCMSContentEncryptorBuilder(CMSAlgorithm.DES_EDE3_CBC).setProvider(BC).build()); out.write(data); out.close(); CMSEnvelopedDataParser ep = new CMSEnvelopedDataParser(bOut.toByteArray()); RecipientInformationStore recipients = ep.getRecipientInfos(); assertEquals(ep.getEncryptionAlgOID(), CMSEnvelopedDataGenerator.DES_EDE3_CBC); Collection c = recipients.getRecipients(); Iterator it = c.iterator(); while (it.hasNext()) { RecipientInformation recipient = (RecipientInformation)it.next(); assertEquals(recipient.getKeyEncryptionAlgOID(), "2.16.840.1.101.3.4.1.25"); CMSTypedStream recData = recipient.getContentStream(new JceKEKEnvelopedRecipient(kek).setProvider(BC)); assertEquals(true, Arrays.equals(data, CMSTestUtil.streamToByteArray(recData.getContentStream()))); } ep.close(); } public void testTwoAESKEK() throws Exception { byte[] data = "WallaWallaWashington".getBytes(); SecretKey kek1 = CMSTestUtil.makeAES192Key(); SecretKey kek2 = CMSTestUtil.makeAES192Key(); CMSEnvelopedDataStreamGenerator edGen = new CMSEnvelopedDataStreamGenerator(); byte[] kekId1 = new byte[] { 1, 2, 3, 4, 5 }; byte[] kekId2 = new byte[] { 5, 4, 3, 2, 1 }; edGen.addRecipientInfoGenerator(new JceKEKRecipientInfoGenerator(kekId1, kek1).setProvider(BC)); edGen.addRecipientInfoGenerator(new JceKEKRecipientInfoGenerator(kekId2, kek2).setProvider(BC)); ByteArrayOutputStream bOut = new ByteArrayOutputStream(); OutputStream out = edGen.open( bOut, new JceCMSContentEncryptorBuilder(CMSAlgorithm.DES_EDE3_CBC).setProvider(BC).build()); out.write(data); out.close(); CMSEnvelopedDataParser ep = new CMSEnvelopedDataParser(bOut.toByteArray()); RecipientInformationStore recipients = ep.getRecipientInfos(); assertEquals(ep.getEncryptionAlgOID(), CMSEnvelopedDataGenerator.DES_EDE3_CBC); RecipientId recSel = new KEKRecipientId(kekId2); RecipientInformation recipient = recipients.get(recSel); assertEquals(recipient.getKeyEncryptionAlgOID(), "2.16.840.1.101.3.4.1.25"); CMSTypedStream recData = recipient.getContentStream(new JceKEKEnvelopedRecipient(kek2).setProvider(BC)); assertEquals(true, Arrays.equals(data, CMSTestUtil.streamToByteArray(recData.getContentStream()))); ep.close(); } public void testECKeyAgree() throws Exception { byte[] data = Hex.decode("504b492d4320434d5320456e76656c6f706564446174612053616d706c65"); CMSEnvelopedDataStreamGenerator edGen = new CMSEnvelopedDataStreamGenerator(); JceKeyAgreeRecipientInfoGenerator recipientGenerator = new JceKeyAgreeRecipientInfoGenerator(CMSAlgorithm.ECDH_SHA1KDF, _origEcKP.getPrivate(), _origEcKP.getPublic(), CMSAlgorithm.AES128_WRAP).setProvider(BC); recipientGenerator.addRecipient(_reciEcCert); edGen.addRecipientInfoGenerator(recipientGenerator); ByteArrayOutputStream bOut = new ByteArrayOutputStream(); OutputStream out = edGen.open( bOut, new JceCMSContentEncryptorBuilder(CMSAlgorithm.AES128_CBC).setProvider(BC).build()); out.write(data); out.close(); CMSEnvelopedDataParser ep = new CMSEnvelopedDataParser(bOut.toByteArray()); RecipientInformationStore recipients = ep.getRecipientInfos(); assertEquals(ep.getEncryptionAlgOID(), CMSEnvelopedDataGenerator.AES128_CBC); RecipientId recSel = new JceKeyAgreeRecipientId(_reciEcCert); RecipientInformation recipient = recipients.get(recSel); CMSTypedStream recData = recipient.getContentStream(new JceKeyAgreeEnvelopedRecipient(_reciEcKP.getPrivate()).setProvider(BC)); assertEquals(true, Arrays.equals(data, CMSTestUtil.streamToByteArray(recData.getContentStream()))); ep.close(); } public void testOriginatorInfo() throws Exception { CMSEnvelopedDataParser env = new CMSEnvelopedDataParser(CMSSampleMessages.originatorMessage); OriginatorInformation origInfo = env.getOriginatorInfo(); RecipientInformationStore recipients = env.getRecipientInfos(); assertEquals(new X500Name("C=US,O=U.S. Government,OU=HSPD12Lab,OU=Agents,CN=user1"), ((X509CertificateHolder)origInfo.getCertificates().getMatches(null).iterator().next()).getSubject()); assertEquals(CMSEnvelopedDataGenerator.DES_EDE3_CBC, env.getEncryptionAlgOID()); } public static Test suite() throws Exception { return new CMSTestSetup(new TestSuite(NewEnvelopedDataStreamTest.class)); } } bouncycastle-1.49.orig/test/src/org/bouncycastle/cms/test/NewCompressedDataStreamTest.java0000644000175000017500000001465011526662001031456 0ustar ebourgebourgpackage org.bouncycastle.cms.test; import java.io.ByteArrayOutputStream; import java.io.OutputStream; import java.util.Arrays; import java.util.Random; import junit.framework.Test; import junit.framework.TestCase; import junit.framework.TestSuite; import org.bouncycastle.cms.CMSCompressedDataParser; import org.bouncycastle.cms.CMSCompressedDataStreamGenerator; import org.bouncycastle.cms.jcajce.ZlibCompressor; import org.bouncycastle.cms.jcajce.ZlibExpanderProvider; import org.bouncycastle.util.encoders.Base64; public class NewCompressedDataStreamTest extends TestCase { public NewCompressedDataStreamTest(String name) { super(name); } public void testWorkingData() throws Exception { byte[] compData = Base64.decode( "MIAGCyqGSIb3DQEJEAEJoIAwgAIBADANBgsqhkiG9w0BCRADCDCABgkqhkiG9w0BBwGggCSABIIC" + "Hnic7ZRdb9owFIbvK/k/5PqVYPFXGK12YYyboVFASSp1vQtZGiLRACZE49/XHoUW7S/0tXP8Efux" + "fU5ivWnasml72XFb3gb5druui7ytN803M570nii7C5r8tfwR281hy/p/KSM3+jzH5s3+pbQ90xSb" + "P3VT3QbLusnt8WPIuN5vN/vaA2+DulnXTXkXvNTr8j8ouZmkCmGI/UW+ZS/C8zP0bz2dz0zwLt+1" + "UEk2M8mlaxjRMByAhZTj0RGYg4TvogiRASROsZgjpVcJCb1KV6QzQeDJ1XkoQ5Jm+C5PbOHZZGRi" + "v+ORAcshOGeCcdFJyfgFxdtCdEcmOrbinc/+BBMzRThEYpwl+jEBpciSGWQkI0TSlREmD/eOHb2D" + "SGLuESm/iKUFt1y4XHBO2a5oq0IKJKWLS9kUZTA7vC5LSxYmgVL46SIWxIfWBQd6AdrnjLmH94UT" + "vGxVibLqRCtIpp4g2qpdtqK1LiOeolpVK5wVQ5P7+QjZAlrh0cePYTx/gNZuB9Vhndtgujl9T/tg" + "W9ogK+3rnmg3YWygnTuF5GDS+Q/jIVLnCcYZFc6Kk/+c80wKwZjwdZIqDYWRH68MuBQSXLgXYXj2" + "3CAaYOBNJMliTl0X7eV5DnoKIFSKYdj3cRpD/cK/JWTHJRe76MUXnfBW8m7Hd5zhQ4ri2NrVF/WL" + "+kV1/3AGSlJ32bFPd2BsQD8uSzIx6lObkjdz95c0AAAAAAAAAAAAAAAA"); byte[] uncompData = Base64.decode( "Q29udGVudC1UeXBlOiBhcHBsaWNhdGlvbi9FREktWDEyOyBuYW1lPUdyb3VwMi54MTINCkNvbnRl" + "bnQtVHJhbnNmZXItRW5jb2Rpbmc6IGJpbmFyeQ0KQ29udGVudC1EaXNwb3NpdGlvbjogaW5saW5l" + "OyBmaWxlbmFtZT1Hcm91cDIueDEyDQoNCklTQSowMCpzc3Nzc3Nzc3NzKjAwKnJycnJycnJycnIqW" + "loqQ1lDTE9ORSAgICAgICAgKlpaKlBBUlRORVIgICAgICAgICo5NjEwMDcqMjAxMypVKjAwMjAwKj" + "AwMDAwMDAwMSowKlQqKg1HUypQTypTMVMxUzFTMVMxUzFTMVMqUjFSMVIxUjFSMVIxUjFSKjk2MTA" + "wNyoyMDEzKjAwMDAwMDAwNCpYKjAwMzA1MA1TVCo4NTAqMDAwMDQwMDAxDUJFRyowMCpCRSoyYSo0" + "MzMyNDIzNHY1NTIzKjk2MTAwNyoyM3RjNHZ5MjR2MmgzdmgzdmgqWloqSUVMKjA5KlJFKjA5DUNVU" + "ioxMSpUUk4qNTY1Nio2NSo1NjYqSU1GKjAwNio5NjEwMDcNUkVGKjZBKjQzM3IxYzNyMzRyMzRjMz" + "MxMnFjdGdjNTQqUmVmZXJlbmNlIE51bWJlcg1QRVIqQUEqSGFucyBHdXR0ZW4qQ1AqMS4zMjIuMzI" + "zLjQ0NDQqKioqKnJnZzRlZ3Y0dDQNVEFYKjR0Z3RidDR0cjR0cipHTCpnaGdoKioqKioqKioqRypD" + "DUZPQipUUCpDQSpVU0EqMDIqRE9NKkNDKlJlZ3VsYXIgTG9jYXRpb25zIHBlciBUZXJtcw1DVFAqR" + "EUqQzA0KjQ1MyoyNTAwMCpEOSpTRUwqMjMyMTQqMjM0MzI0MjM0MjMqRVMqNDIyNDM0MjMNU0FDKk" + "EqQjAwMCpBRSozNTQ1KjM0NDIzMDANQ1VSKjExKjc2Nyo3NzY3KjY1DVBPMSoxMTEtYWFhKjEwMDA" + "wMDAqQVMqOTAuMDAqQkQqQUsqMjM0MjM1djM1MzRxNmYzNTM0djQzNTM0NTN2cTNxMzIqKioqKioq" + "KioqKkExKnl0cmgNUE8xKjExMS1hYWEqMTAwMDAwMCpBUyo5MC4wMCpCRCpBSyoyMzQyMzV2MzUzN" + "HE2ZjM1MzR2NDM1MzQ1M3ZxM3EzMioqKioqKioqKioqQTEqeXRyaA1QTzEqMTExLWFhYSoxMDAwMD" + "AwKkFTKjkwLjAwKkJEKkFLKjIzNDIzNXYzNTM0cTZmMzUzNHY0MzUzNDUzdnEzcTMyKioqKioqKio" + "qKipBMSp5dHJoDVBPMSoxMTEtYWFhKjEwMDAwMDAqQVMqOTAuMDAqQkQqQUsqMjM0MjM1djM1MzRx" + "NmYzNTM0djQzNTM0NTN2cTNxMzIqKioqKioqKioqKkExKnl0cmgNUE8xKjExMS1hYWEqMTAwMDAwM" + "CpBUyo5MC4wMCpCRCpBSyoyMzQyMzV2MzUzNHE2ZjM1MzR2NDM1MzQ1M3ZxM3EzMioqKioqKioqKi" + "oqQTEqeXRyaA1QTzEqMTExLWFhYSoxMDAwMDAwKkFTKjkwLjAwKkJEKkFLKjIzNDIzNXYzNTM0cTZ" + "mMzUzNHY0MzUzNDUzdnEzcTMyKioqKioqKioqKipBMSp5dHJoDVBPMSoxMTEtYWFhKjEwMDAwMDAq" + "QVMqOTAuMDAqQkQqQUsqMjM0MjM1djM1MzRxNmYzNTM0djQzNTM0NTN2cTNxMzIqKioqKioqKioqK" + "kExKnl0cmgNUE8xKjExMS1hYWEqMTAwMDAwMCpBUyo5MC4wMCpCRCpBSyoyMzQyMzV2MzUzNHE2Zj" + "M1MzR2NDM1MzQ1M3ZxM3EzMioqKioqKioqKioqQTEqeXRyaA1QTzEqMTExLWFhYSoxMDAwMDAwKkF" + "TKjkwLjAwKkJEKkFLKjIzNDIzNXYzNTM0cTZmMzUzNHY0MzUzNDUzdnEzcTMyKioqKioqKioqKipB" + "MSp5dHJoDVBPMSoxMTEtYWFhKjEwMDAwMDAqQVMqOTAuMDAqQkQqQUsqMjM0MjM1djM1MzRxNmYzN" + "TM0djQzNTM0NTN2cTNxMzIqKioqKioqKioqKkExKnl0cmgNQ1RUKjENU0UqMjIqMDAwMDQwMDAxDU" + "dFKjEqMDAwMDAwMDA0DUlFQSoxKjAwMDAwMDAwMQ0="); CMSCompressedDataParser ed = new CMSCompressedDataParser(compData); assertEquals(true, Arrays.equals(uncompData, CMSTestUtil.streamToByteArray(ed.getContent(new ZlibExpanderProvider()).getContentStream()))); } public void testEach() throws Exception { byte[] testData = "Hello world!".getBytes(); CMSCompressedDataStreamGenerator gen = new CMSCompressedDataStreamGenerator(); ByteArrayOutputStream bOut = new ByteArrayOutputStream(); OutputStream cOut = gen.open(bOut, new ZlibCompressor()); cOut.write(testData); cOut.close(); CMSCompressedDataParser ed = new CMSCompressedDataParser(bOut.toByteArray()); assertEquals(true, Arrays.equals(testData, CMSTestUtil.streamToByteArray(ed.getContent(new ZlibExpanderProvider()).getContentStream()))); } public void test1000() throws Exception { byte[] testData = new byte[10000]; Random rand = new Random(); rand.setSeed(0); for (int i = 0; i != 10; i++) { CMSCompressedDataStreamGenerator gen = new CMSCompressedDataStreamGenerator(); ByteArrayOutputStream bOut = new ByteArrayOutputStream(); OutputStream cOut = gen.open(bOut, new ZlibCompressor()); rand.nextBytes(testData); cOut.write(testData); cOut.close(); CMSCompressedDataParser ed = new CMSCompressedDataParser(bOut.toByteArray()); assertEquals(true, Arrays.equals(testData, CMSTestUtil.streamToByteArray(ed.getContent(new ZlibExpanderProvider()).getContentStream()))); } } public static Test suite() { return new TestSuite(NewCompressedDataStreamTest.class); } } bouncycastle-1.49.orig/test/src/org/bouncycastle/cms/test/SignedDataStreamTest.java0000644000175000017500000011422611726245377030130 0ustar ebourgebourgpackage org.bouncycastle.cms.test; import java.io.BufferedOutputStream; import java.io.ByteArrayInputStream; import java.io.ByteArrayOutputStream; import java.io.OutputStream; import java.security.InvalidKeyException; import java.security.KeyPair; import java.security.MessageDigest; import java.security.NoSuchAlgorithmException; import java.security.cert.CertStore; import java.security.cert.CollectionCertStoreParameters; import java.security.cert.X509CRL; import java.security.cert.X509Certificate; import java.util.ArrayList; import java.util.Collection; import java.util.Collections; import java.util.Hashtable; import java.util.Iterator; import java.util.List; import java.util.Map; import junit.framework.Test; import junit.framework.TestCase; import junit.framework.TestSuite; import org.bouncycastle.asn1.ASN1ObjectIdentifier; import org.bouncycastle.asn1.ASN1OctetString; import org.bouncycastle.asn1.DEROctetString; import org.bouncycastle.asn1.DERSet; import org.bouncycastle.asn1.cms.Attribute; import org.bouncycastle.asn1.cms.AttributeTable; import org.bouncycastle.asn1.cms.CMSAttributes; import org.bouncycastle.cms.CMSAttributeTableGenerator; import org.bouncycastle.cms.CMSProcessable; import org.bouncycastle.cms.CMSProcessableByteArray; import org.bouncycastle.cms.CMSSignedData; import org.bouncycastle.cms.CMSSignedDataGenerator; import org.bouncycastle.cms.CMSSignedDataParser; import org.bouncycastle.cms.CMSSignedDataStreamGenerator; import org.bouncycastle.cms.CMSSignedGenerator; import org.bouncycastle.cms.CMSTypedStream; import org.bouncycastle.cms.DefaultSignedAttributeTableGenerator; import org.bouncycastle.cms.SignerInformation; import org.bouncycastle.cms.SignerInformationStore; import org.bouncycastle.cms.jcajce.JcaX509CertSelectorConverter; import org.bouncycastle.jce.provider.BouncyCastleProvider; import org.bouncycastle.util.encoders.Base64; import org.bouncycastle.x509.X509AttributeCertificate; import org.bouncycastle.x509.X509CollectionStoreParameters; import org.bouncycastle.x509.X509Store; public class SignedDataStreamTest extends TestCase { private static final String BC = BouncyCastleProvider.PROVIDER_NAME; private static final String TEST_MESSAGE = "Hello World!"; private static String _signDN; private static KeyPair _signKP; private static X509Certificate _signCert; private static String _origDN; private static KeyPair _origKP; private static X509Certificate _origCert; private static String _reciDN; private static KeyPair _reciKP; private static X509Certificate _reciCert; private static KeyPair _origDsaKP; private static X509Certificate _origDsaCert; private static X509CRL _signCrl; private static X509CRL _origCrl; private static boolean _initialised = false; private static final JcaX509CertSelectorConverter selectorConverter = new JcaX509CertSelectorConverter(); public SignedDataStreamTest(String name) { super(name); } private static void init() throws Exception { if (!_initialised) { _initialised = true; _signDN = "O=Bouncy Castle, C=AU"; _signKP = CMSTestUtil.makeKeyPair(); _signCert = CMSTestUtil.makeCertificate(_signKP, _signDN, _signKP, _signDN); _origDN = "CN=Bob, OU=Sales, O=Bouncy Castle, C=AU"; _origKP = CMSTestUtil.makeKeyPair(); _origCert = CMSTestUtil.makeCertificate(_origKP, _origDN, _signKP, _signDN); _origDsaKP = CMSTestUtil.makeDsaKeyPair(); _origDsaCert = CMSTestUtil.makeCertificate(_origDsaKP, _origDN, _signKP, _signDN); _reciDN = "CN=Doug, OU=Sales, O=Bouncy Castle, C=AU"; _reciKP = CMSTestUtil.makeKeyPair(); _reciCert = CMSTestUtil.makeCertificate(_reciKP, _reciDN, _signKP, _signDN); _signCrl = CMSTestUtil.makeCrl(_signKP); _origCrl = CMSTestUtil.makeCrl(_origKP); } } private void verifySignatures(CMSSignedDataParser sp, byte[] contentDigest) throws Exception { CertStore certStore = sp.getCertificatesAndCRLs("Collection", BC); SignerInformationStore signers = sp.getSignerInfos(); Collection c = signers.getSigners(); Iterator it = c.iterator(); while (it.hasNext()) { SignerInformation signer = (SignerInformation)it.next(); Collection certCollection = certStore.getCertificates(selectorConverter.getCertSelector(signer.getSID())); Iterator certIt = certCollection.iterator(); X509Certificate cert = (X509Certificate)certIt.next(); assertEquals(true, signer.verify(cert, BC)); if (contentDigest != null) { assertTrue(MessageDigest.isEqual(contentDigest, signer.getContentDigest())); } } Collection certColl = certStore.getCertificates(null); Collection crlColl = certStore.getCRLs(null); assertEquals(certColl.size(), sp.getCertificates("Collection", BC).getMatches(null).size()); assertEquals(crlColl.size(), sp.getCRLs("Collection", BC).getMatches(null).size()); } private void verifySignatures(CMSSignedDataParser sp) throws Exception { verifySignatures(sp, null); } private void verifyEncodedData(ByteArrayOutputStream bOut) throws Exception { CMSSignedDataParser sp; sp = new CMSSignedDataParser(bOut.toByteArray()); sp.getSignedContent().drain(); verifySignatures(sp); sp.close(); } private void checkSigParseable(byte[] sig) throws Exception { CMSSignedDataParser sp = new CMSSignedDataParser(sig); sp.getVersion(); CMSTypedStream sc = sp.getSignedContent(); if (sc != null) { sc.drain(); } sp.getCertificatesAndCRLs("Collection", BC); sp.getSignerInfos(); sp.close(); } public void testEarlyInvalidKeyException() throws Exception { try { CMSSignedDataStreamGenerator gen = new CMSSignedDataStreamGenerator(); gen.addSigner( _origKP.getPrivate(), _origCert, "DSA", // DOESN'T MATCH KEY ALG CMSSignedDataStreamGenerator.DIGEST_SHA1, BC); fail("Expected InvalidKeyException in addSigner"); } catch (InvalidKeyException e) { // Ignore } } public void testEarlyNoSuchAlgorithmException() throws Exception { try { CMSSignedDataStreamGenerator gen = new CMSSignedDataStreamGenerator(); gen.addSigner( _origKP.getPrivate(), _origCert, CMSSignedDataStreamGenerator.DIGEST_SHA1, // BAD OID! CMSSignedDataStreamGenerator.DIGEST_SHA1, BC); fail("Expected NoSuchAlgorithmException in addSigner"); } catch (NoSuchAlgorithmException e) { // Ignore } } public void testSha1EncapsulatedSignature() throws Exception { byte[] encapSigData = Base64.decode( "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" + "n7MsJMoKN3Kd2Vzh6s10PFgeAAAAAAAA"); CMSSignedDataParser sp = new CMSSignedDataParser(encapSigData); sp.getSignedContent().drain(); verifySignatures(sp); } public void testSHA1WithRSANoAttributes() throws Exception { List certList = new ArrayList(); CMSProcessable msg = new CMSProcessableByteArray(TEST_MESSAGE.getBytes()); certList.add(_origCert); certList.add(_signCert); CertStore certs = CertStore.getInstance("Collection", new CollectionCertStoreParameters(certList), BC); CMSSignedDataGenerator gen = new CMSSignedDataGenerator(); gen.addSigner(_origKP.getPrivate(), _origCert, CMSSignedDataGenerator.DIGEST_SHA1); gen.addCertificatesAndCRLs(certs); CMSSignedData s = gen.generate(CMSSignedDataGenerator.DATA, msg, false, BC, false); CMSSignedDataParser sp = new CMSSignedDataParser( new CMSTypedStream(new ByteArrayInputStream(TEST_MESSAGE.getBytes())), s.getEncoded()); sp.getSignedContent().drain(); // // compute expected content digest // MessageDigest md = MessageDigest.getInstance("SHA1", BC); verifySignatures(sp, md.digest(TEST_MESSAGE.getBytes())); } public void testDSANoAttributes() throws Exception { List certList = new ArrayList(); CMSProcessable msg = new CMSProcessableByteArray(TEST_MESSAGE.getBytes()); certList.add(_origDsaCert); certList.add(_signCert); CertStore certs = CertStore.getInstance("Collection", new CollectionCertStoreParameters(certList), BC); CMSSignedDataGenerator gen = new CMSSignedDataGenerator(); gen.addSigner(_origDsaKP.getPrivate(), _origDsaCert, CMSSignedDataGenerator.DIGEST_SHA1); gen.addCertificatesAndCRLs(certs); CMSSignedData s = gen.generate(CMSSignedDataGenerator.DATA, msg, false, BC, false); CMSSignedDataParser sp = new CMSSignedDataParser( new CMSTypedStream(new ByteArrayInputStream(TEST_MESSAGE.getBytes())), s.getEncoded()); sp.getSignedContent().drain(); // // compute expected content digest // MessageDigest md = MessageDigest.getInstance("SHA1", BC); verifySignatures(sp, md.digest(TEST_MESSAGE.getBytes())); } public void testSHA1WithRSA() throws Exception { List certList = new ArrayList(); ByteArrayOutputStream bOut = new ByteArrayOutputStream(); certList.add(_origCert); certList.add(_signCert); certList.add(_signCrl); certList.add(_origCrl); CertStore certsAndCrls = CertStore.getInstance("Collection", new CollectionCertStoreParameters(certList), BC); CMSSignedDataStreamGenerator gen = new CMSSignedDataStreamGenerator(); gen.addSigner(_origKP.getPrivate(), _origCert, CMSSignedDataStreamGenerator.DIGEST_SHA1, BC); gen.addCertificatesAndCRLs(certsAndCrls); OutputStream sigOut = gen.open(bOut); sigOut.write(TEST_MESSAGE.getBytes()); sigOut.close(); checkSigParseable(bOut.toByteArray()); CMSSignedDataParser sp = new CMSSignedDataParser( new CMSTypedStream(new ByteArrayInputStream(TEST_MESSAGE.getBytes())), bOut.toByteArray()); sp.getSignedContent().drain(); // // compute expected content digest // MessageDigest md = MessageDigest.getInstance("SHA1", BC); verifySignatures(sp, md.digest(TEST_MESSAGE.getBytes())); // // try using existing signer // gen = new CMSSignedDataStreamGenerator(); gen.addSigners(sp.getSignerInfos()); gen.addCertificatesAndCRLs(sp.getCertificatesAndCRLs("Collection", BC)); bOut.reset(); sigOut = gen.open(bOut, true); sigOut.write(TEST_MESSAGE.getBytes()); sigOut.close(); verifyEncodedData(bOut); // // look for the CRLs // Collection col = certsAndCrls.getCRLs(null); assertEquals(2, col.size()); assertTrue(col.contains(_signCrl)); assertTrue(col.contains(_origCrl)); } public void testSHA1WithRSANonData() throws Exception { List certList = new ArrayList(); ByteArrayOutputStream bOut = new ByteArrayOutputStream(); certList.add(_origCert); certList.add(_signCert); certList.add(_signCrl); certList.add(_origCrl); CertStore certsAndCrls = CertStore.getInstance("Collection", new CollectionCertStoreParameters(certList), BC); CMSSignedDataStreamGenerator gen = new CMSSignedDataStreamGenerator(); gen.addSigner(_origKP.getPrivate(), _origCert, CMSSignedDataStreamGenerator.DIGEST_SHA1, BC); gen.addCertificatesAndCRLs(certsAndCrls); OutputStream sigOut = gen.open(bOut, "1.2.3.4", true); sigOut.write(TEST_MESSAGE.getBytes()); sigOut.close(); CMSSignedDataParser sp = new CMSSignedDataParser(bOut.toByteArray()); CMSTypedStream stream = sp.getSignedContent(); assertEquals(new ASN1ObjectIdentifier("1.2.3.4"), stream.getContentType()); stream.drain(); // // compute expected content digest // MessageDigest md = MessageDigest.getInstance("SHA1", BC); verifySignatures(sp, md.digest(TEST_MESSAGE.getBytes())); } public void testSHA1AndMD5WithRSA() throws Exception { List certList = new ArrayList(); ByteArrayOutputStream bOut = new ByteArrayOutputStream(); certList.add(_origCert); certList.add(_signCert); CertStore certs = CertStore.getInstance("Collection", new CollectionCertStoreParameters(certList), BC); CMSSignedDataStreamGenerator gen = new CMSSignedDataStreamGenerator(); gen.addSigner(_origKP.getPrivate(), _origCert, CMSSignedDataStreamGenerator.DIGEST_SHA1, BC); gen.addSigner(_origKP.getPrivate(), _origCert, CMSSignedDataStreamGenerator.DIGEST_MD5, BC); gen.addCertificatesAndCRLs(certs); OutputStream sigOut = gen.open(bOut); sigOut.write(TEST_MESSAGE.getBytes()); sigOut.close(); checkSigParseable(bOut.toByteArray()); CMSSignedDataParser sp = new CMSSignedDataParser( new CMSTypedStream(new ByteArrayInputStream(TEST_MESSAGE.getBytes())), bOut.toByteArray()); sp.getSignedContent().drain(); verifySignatures(sp); } public void testSHA1WithRSAEncapsulatedBufferedStream() throws Exception { List certList = new ArrayList(); ByteArrayOutputStream bOut = new ByteArrayOutputStream(); certList.add(_origCert); certList.add(_signCert); CertStore certs = CertStore.getInstance("Collection", new CollectionCertStoreParameters(certList), BC); // // find unbuffered length // CMSSignedDataStreamGenerator gen = new CMSSignedDataStreamGenerator(); gen.addSigner(_origKP.getPrivate(), _origCert, CMSSignedDataStreamGenerator.DIGEST_SHA1, BC); gen.addCertificatesAndCRLs(certs); OutputStream sigOut = gen.open(bOut, true); for (int i = 0; i != 2000; i++) { sigOut.write(i & 0xff); } sigOut.close(); CMSSignedDataParser sp = new CMSSignedDataParser(bOut.toByteArray()); sp.getSignedContent().drain(); verifySignatures(sp); int unbufferedLength = bOut.toByteArray().length; // // find buffered length with buffered stream - should be equal // bOut = new ByteArrayOutputStream(); gen = new CMSSignedDataStreamGenerator(); gen.addSigner(_origKP.getPrivate(), _origCert, CMSSignedDataStreamGenerator.DIGEST_SHA1, BC); gen.addCertificatesAndCRLs(certs); sigOut = gen.open(bOut, true); BufferedOutputStream bfOut = new BufferedOutputStream(sigOut, 300); for (int i = 0; i != 2000; i++) { bfOut.write(i & 0xff); } bfOut.close(); verifyEncodedData(bOut); assertTrue(bOut.toByteArray().length == unbufferedLength); } public void testSHA1WithRSAEncapsulatedBuffered() throws Exception { List certList = new ArrayList(); ByteArrayOutputStream bOut = new ByteArrayOutputStream(); certList.add(_origCert); certList.add(_signCert); CertStore certs = CertStore.getInstance("Collection", new CollectionCertStoreParameters(certList), BC); // // find unbuffered length // CMSSignedDataStreamGenerator gen = new CMSSignedDataStreamGenerator(); gen.addSigner(_origKP.getPrivate(), _origCert, CMSSignedDataStreamGenerator.DIGEST_SHA1, BC); gen.addCertificatesAndCRLs(certs); OutputStream sigOut = gen.open(bOut, true); for (int i = 0; i != 2000; i++) { sigOut.write(i & 0xff); } sigOut.close(); CMSSignedDataParser sp = new CMSSignedDataParser(bOut.toByteArray()); sp.getSignedContent().drain(); verifySignatures(sp); int unbufferedLength = bOut.toByteArray().length; // // find buffered length - buffer size less than default // bOut = new ByteArrayOutputStream(); gen = new CMSSignedDataStreamGenerator(); gen.setBufferSize(300); gen.addSigner(_origKP.getPrivate(), _origCert, CMSSignedDataStreamGenerator.DIGEST_SHA1, BC); gen.addCertificatesAndCRLs(certs); sigOut = gen.open(bOut, true); for (int i = 0; i != 2000; i++) { sigOut.write(i & 0xff); } sigOut.close(); verifyEncodedData(bOut); assertTrue(bOut.toByteArray().length > unbufferedLength); } public void testSHA1WithRSAEncapsulated() throws Exception { List certList = new ArrayList(); ByteArrayOutputStream bOut = new ByteArrayOutputStream(); certList.add(_origCert); certList.add(_signCert); CertStore certs = CertStore.getInstance("Collection", new CollectionCertStoreParameters(certList), BC); CMSSignedDataStreamGenerator gen = new CMSSignedDataStreamGenerator(); gen.addSigner(_origKP.getPrivate(), _origCert, CMSSignedDataStreamGenerator.DIGEST_SHA1, BC); gen.addCertificatesAndCRLs(certs); OutputStream sigOut = gen.open(bOut, true); sigOut.write(TEST_MESSAGE.getBytes()); sigOut.close(); CMSSignedDataParser sp = new CMSSignedDataParser(bOut.toByteArray()); sp.getSignedContent().drain(); verifySignatures(sp); byte[] contentDigest = (byte[])gen.getGeneratedDigests().get(CMSSignedGenerator.DIGEST_SHA1); AttributeTable table = ((SignerInformation)sp.getSignerInfos().getSigners().iterator().next()).getSignedAttributes(); Attribute hash = table.get(CMSAttributes.messageDigest); assertTrue(MessageDigest.isEqual(contentDigest, ((ASN1OctetString)hash.getAttrValues().getObjectAt(0)).getOctets())); // // try using existing signer // gen = new CMSSignedDataStreamGenerator(); gen.addSigners(sp.getSignerInfos()); gen.addCertificatesAndCRLs(sp.getCertificatesAndCRLs("Collection", BC)); bOut.reset(); sigOut = gen.open(bOut, true); sigOut.write(TEST_MESSAGE.getBytes()); sigOut.close(); CMSSignedData sd = new CMSSignedData(new CMSProcessableByteArray(TEST_MESSAGE.getBytes()), bOut.toByteArray()); assertEquals(1, sd.getSignerInfos().getSigners().size()); verifyEncodedData(bOut); } public void testSHA1WithRSAEncapsulatedSubjectKeyID() throws Exception { List certList = new ArrayList(); ByteArrayOutputStream bOut = new ByteArrayOutputStream(); certList.add(_origCert); certList.add(_signCert); CertStore certs = CertStore.getInstance("Collection", new CollectionCertStoreParameters(certList), BC); CMSSignedDataStreamGenerator gen = new CMSSignedDataStreamGenerator(); gen.addSigner(_origKP.getPrivate(), CMSTestUtil.createSubjectKeyId(_origCert.getPublicKey()).getKeyIdentifier(), CMSSignedDataStreamGenerator.DIGEST_SHA1, BC); gen.addCertificatesAndCRLs(certs); OutputStream sigOut = gen.open(bOut, true); sigOut.write(TEST_MESSAGE.getBytes()); sigOut.close(); CMSSignedDataParser sp = new CMSSignedDataParser(bOut.toByteArray()); sp.getSignedContent().drain(); verifySignatures(sp); byte[] contentDigest = (byte[])gen.getGeneratedDigests().get(CMSSignedGenerator.DIGEST_SHA1); AttributeTable table = ((SignerInformation)sp.getSignerInfos().getSigners().iterator().next()).getSignedAttributes(); Attribute hash = table.get(CMSAttributes.messageDigest); assertTrue(MessageDigest.isEqual(contentDigest, ((ASN1OctetString)hash.getAttrValues().getObjectAt(0)).getOctets())); // // try using existing signer // gen = new CMSSignedDataStreamGenerator(); gen.addSigners(sp.getSignerInfos()); gen.addCertificatesAndCRLs(sp.getCertificatesAndCRLs("Collection", BC)); bOut.reset(); sigOut = gen.open(bOut, true); sigOut.write(TEST_MESSAGE.getBytes()); sigOut.close(); CMSSignedData sd = new CMSSignedData(new CMSProcessableByteArray(TEST_MESSAGE.getBytes()), bOut.toByteArray()); assertEquals(1, sd.getSignerInfos().getSigners().size()); verifyEncodedData(bOut); } public void testAttributeGenerators() throws Exception { final ASN1ObjectIdentifier dummyOid1 = new ASN1ObjectIdentifier("1.2.3"); final ASN1ObjectIdentifier dummyOid2 = new ASN1ObjectIdentifier("1.2.3.4"); List certList = new ArrayList(); ByteArrayOutputStream bOut = new ByteArrayOutputStream(); certList.add(_origCert); certList.add(_signCert); CertStore certs = CertStore.getInstance("Collection", new CollectionCertStoreParameters(certList), BC); CMSSignedDataStreamGenerator gen = new CMSSignedDataStreamGenerator(); CMSAttributeTableGenerator signedGen = new DefaultSignedAttributeTableGenerator() { public AttributeTable getAttributes(Map parameters) { Hashtable table = createStandardAttributeTable(parameters); DEROctetString val = new DEROctetString((byte[])parameters.get(CMSAttributeTableGenerator.DIGEST)); Attribute attr = new Attribute(dummyOid1, new DERSet(val)); table.put(attr.getAttrType(), attr); return new AttributeTable(table); } }; CMSAttributeTableGenerator unsignedGen = new CMSAttributeTableGenerator() { public AttributeTable getAttributes(Map parameters) { DEROctetString val = new DEROctetString((byte[])parameters.get(CMSAttributeTableGenerator.SIGNATURE)); Attribute attr = new Attribute(dummyOid2, new DERSet(val)); return new AttributeTable(new DERSet(attr)); } }; gen.addSigner(_origKP.getPrivate(), _origCert, CMSSignedDataStreamGenerator.DIGEST_SHA1, signedGen, unsignedGen, BC); gen.addCertificatesAndCRLs(certs); OutputStream sigOut = gen.open(bOut, true); sigOut.write(TEST_MESSAGE.getBytes()); sigOut.close(); CMSSignedDataParser sp = new CMSSignedDataParser(bOut.toByteArray()); sp.getSignedContent().drain(); verifySignatures(sp); // // check attributes // SignerInformationStore signers = sp.getSignerInfos(); Collection c = signers.getSigners(); Iterator it = c.iterator(); while (it.hasNext()) { SignerInformation signer = (SignerInformation)it.next(); checkAttribute(signer.getContentDigest(), signer.getSignedAttributes().get(dummyOid1)); checkAttribute(signer.getSignature(), signer.getUnsignedAttributes().get(dummyOid2)); } } private void checkAttribute(byte[] expected, Attribute attr) { DEROctetString value = (DEROctetString)attr.getAttrValues().getObjectAt(0); assertEquals(new DEROctetString(expected), value); } public void testWithAttributeCertificate() throws Exception { List certList = new ArrayList(); certList.add(_signCert); CertStore certs = CertStore.getInstance("Collection", new CollectionCertStoreParameters(certList), BC); CMSSignedDataStreamGenerator gen = new CMSSignedDataStreamGenerator(); gen.addSigner(_origKP.getPrivate(), _origCert, CMSSignedDataGenerator.DIGEST_SHA1, BC); gen.addCertificatesAndCRLs(certs); X509AttributeCertificate attrCert = CMSTestUtil.getAttributeCertificate(); X509Store store = X509Store.getInstance("AttributeCertificate/Collection", new X509CollectionStoreParameters(Collections.singleton(attrCert)), BC); gen.addAttributeCertificates(store); ByteArrayOutputStream bOut = new ByteArrayOutputStream(); OutputStream sigOut = gen.open(bOut, true); sigOut.write(TEST_MESSAGE.getBytes()); sigOut.close(); CMSSignedDataParser sp = new CMSSignedDataParser(bOut.toByteArray()); sp.getSignedContent().drain(); assertEquals(4, sp.getVersion()); store = sp.getAttributeCertificates("Collection", BC); Collection coll = store.getMatches(null); assertEquals(1, coll.size()); assertTrue(coll.contains(attrCert)); } public void testSignerStoreReplacement() throws Exception { List certList = new ArrayList(); ByteArrayOutputStream bOut = new ByteArrayOutputStream(); byte[] data = TEST_MESSAGE.getBytes(); certList.add(_origCert); certList.add(_signCert); CertStore certs = CertStore.getInstance("Collection", new CollectionCertStoreParameters(certList), BC); CMSSignedDataStreamGenerator gen = new CMSSignedDataStreamGenerator(); gen.addSigner(_origKP.getPrivate(), _origCert, CMSSignedDataStreamGenerator.DIGEST_SHA1, BC); gen.addCertificatesAndCRLs(certs); OutputStream sigOut = gen.open(bOut, false); sigOut.write(data); sigOut.close(); checkSigParseable(bOut.toByteArray()); // // create new Signer // ByteArrayInputStream original = new ByteArrayInputStream(bOut.toByteArray()); bOut.reset(); gen = new CMSSignedDataStreamGenerator(); gen.addSigner(_origKP.getPrivate(), _origCert, CMSSignedDataStreamGenerator.DIGEST_SHA224, BC); gen.addCertificatesAndCRLs(certs); sigOut = gen.open(bOut); sigOut.write(data); sigOut.close(); checkSigParseable(bOut.toByteArray()); CMSSignedData sd = new CMSSignedData(bOut.toByteArray()); // // replace signer // ByteArrayOutputStream newOut = new ByteArrayOutputStream(); CMSSignedDataParser.replaceSigners(original, sd.getSignerInfos(), newOut); sd = new CMSSignedData(new CMSProcessableByteArray(data), newOut.toByteArray()); SignerInformation signer = (SignerInformation)sd.getSignerInfos().getSigners().iterator().next(); assertEquals(signer.getDigestAlgOID(), CMSSignedDataStreamGenerator.DIGEST_SHA224); CMSSignedDataParser sp = new CMSSignedDataParser(new CMSTypedStream(new ByteArrayInputStream(data)), newOut.toByteArray()); sp.getSignedContent().drain(); verifySignatures(sp); } public void testEncapsulatedSignerStoreReplacement() throws Exception { List certList = new ArrayList(); ByteArrayOutputStream bOut = new ByteArrayOutputStream(); certList.add(_origCert); certList.add(_signCert); CertStore certs = CertStore.getInstance("Collection", new CollectionCertStoreParameters(certList), BC); CMSSignedDataStreamGenerator gen = new CMSSignedDataStreamGenerator(); gen.addSigner(_origKP.getPrivate(), _origCert, CMSSignedDataStreamGenerator.DIGEST_SHA1, BC); gen.addCertificatesAndCRLs(certs); OutputStream sigOut = gen.open(bOut, true); sigOut.write(TEST_MESSAGE.getBytes()); sigOut.close(); // // create new Signer // ByteArrayInputStream original = new ByteArrayInputStream(bOut.toByteArray()); bOut.reset(); gen = new CMSSignedDataStreamGenerator(); gen.addSigner(_origKP.getPrivate(), _origCert, CMSSignedDataStreamGenerator.DIGEST_SHA224, BC); gen.addCertificatesAndCRLs(certs); sigOut = gen.open(bOut, true); sigOut.write(TEST_MESSAGE.getBytes()); sigOut.close(); CMSSignedData sd = new CMSSignedData(bOut.toByteArray()); // // replace signer // ByteArrayOutputStream newOut = new ByteArrayOutputStream(); CMSSignedDataParser.replaceSigners(original, sd.getSignerInfos(), newOut); sd = new CMSSignedData(newOut.toByteArray()); SignerInformation signer = (SignerInformation)sd.getSignerInfos().getSigners().iterator().next(); assertEquals(signer.getDigestAlgOID(), CMSSignedDataStreamGenerator.DIGEST_SHA224); CMSSignedDataParser sp = new CMSSignedDataParser(newOut.toByteArray()); sp.getSignedContent().drain(); verifySignatures(sp); } public void testCertStoreReplacement() throws Exception { List certList = new ArrayList(); ByteArrayOutputStream bOut = new ByteArrayOutputStream(); byte[] data = TEST_MESSAGE.getBytes(); certList.add(_origDsaCert); CertStore certs = CertStore.getInstance("Collection", new CollectionCertStoreParameters(certList), BC); CMSSignedDataStreamGenerator gen = new CMSSignedDataStreamGenerator(); gen.addSigner(_origKP.getPrivate(), _origCert, CMSSignedDataStreamGenerator.DIGEST_SHA1, BC); gen.addCertificatesAndCRLs(certs); OutputStream sigOut = gen.open(bOut); sigOut.write(data); sigOut.close(); checkSigParseable(bOut.toByteArray()); // // create new certstore with the right certificates // certList = new ArrayList(); certList.add(_origCert); certList.add(_signCert); certs = CertStore.getInstance("Collection", new CollectionCertStoreParameters(certList), BC); // // replace certs // ByteArrayInputStream original = new ByteArrayInputStream(bOut.toByteArray()); ByteArrayOutputStream newOut = new ByteArrayOutputStream(); CMSSignedDataParser.replaceCertificatesAndCRLs(original, certs, newOut); CMSSignedDataParser sp = new CMSSignedDataParser(new CMSTypedStream(new ByteArrayInputStream(data)), newOut.toByteArray()); sp.getSignedContent().drain(); verifySignatures(sp); } public void testEncapsulatedCertStoreReplacement() throws Exception { List certList = new ArrayList(); ByteArrayOutputStream bOut = new ByteArrayOutputStream(); certList.add(_origDsaCert); CertStore certs = CertStore.getInstance("Collection", new CollectionCertStoreParameters(certList), BC); CMSSignedDataStreamGenerator gen = new CMSSignedDataStreamGenerator(); gen.addSigner(_origKP.getPrivate(), _origCert, CMSSignedDataStreamGenerator.DIGEST_SHA1, BC); gen.addCertificatesAndCRLs(certs); OutputStream sigOut = gen.open(bOut, true); sigOut.write(TEST_MESSAGE.getBytes()); sigOut.close(); // // create new certstore with the right certificates // certList = new ArrayList(); certList.add(_origCert); certList.add(_signCert); certs = CertStore.getInstance("Collection", new CollectionCertStoreParameters(certList), BC); // // replace certs // ByteArrayInputStream original = new ByteArrayInputStream(bOut.toByteArray()); ByteArrayOutputStream newOut = new ByteArrayOutputStream(); CMSSignedDataParser.replaceCertificatesAndCRLs(original, certs, newOut); CMSSignedDataParser sp = new CMSSignedDataParser(newOut.toByteArray()); sp.getSignedContent().drain(); verifySignatures(sp); } public void testCertOrdering1() throws Exception { List certList = new ArrayList(); ByteArrayOutputStream bOut = new ByteArrayOutputStream(); certList.add(_origCert); certList.add(_signCert); CertStore certs = CertStore.getInstance("Collection", new CollectionCertStoreParameters(certList), BC); CMSSignedDataStreamGenerator gen = new CMSSignedDataStreamGenerator(); gen.addSigner(_origKP.getPrivate(), _origCert, CMSSignedDataStreamGenerator.DIGEST_SHA1, BC); gen.addCertificatesAndCRLs(certs); OutputStream sigOut = gen.open(bOut, true); sigOut.write(TEST_MESSAGE.getBytes()); sigOut.close(); CMSSignedDataParser sp = new CMSSignedDataParser(bOut.toByteArray()); sp.getSignedContent().drain(); certs = sp.getCertificatesAndCRLs("Collection", BC); Iterator it = certs.getCertificates(null).iterator(); assertEquals(_origCert, it.next()); assertEquals(_signCert, it.next()); } public void testCertOrdering2() throws Exception { List certList = new ArrayList(); ByteArrayOutputStream bOut = new ByteArrayOutputStream(); certList.add(_signCert); certList.add(_origCert); CertStore certs = CertStore.getInstance("Collection", new CollectionCertStoreParameters(certList), BC); CMSSignedDataStreamGenerator gen = new CMSSignedDataStreamGenerator(); gen.addSigner(_origKP.getPrivate(), _origCert, CMSSignedDataStreamGenerator.DIGEST_SHA1, BC); gen.addCertificatesAndCRLs(certs); OutputStream sigOut = gen.open(bOut, true); sigOut.write(TEST_MESSAGE.getBytes()); sigOut.close(); CMSSignedDataParser sp = new CMSSignedDataParser(bOut.toByteArray()); sp.getSignedContent().drain(); certs = sp.getCertificatesAndCRLs("Collection", BC); Iterator it = certs.getCertificates(null).iterator(); assertEquals(_signCert, it.next()); assertEquals(_origCert, it.next()); } public static Test suite() throws Exception { init(); return new CMSTestSetup(new TestSuite(SignedDataStreamTest.class)); } } bouncycastle-1.49.orig/test/src/org/bouncycastle/cms/test/NewAuthenticatedDataStreamTest.java0000644000175000017500000002112711701213634032130 0ustar ebourgebourgpackage org.bouncycastle.cms.test; import java.io.ByteArrayOutputStream; import java.io.OutputStream; import java.security.KeyPair; import java.security.cert.X509Certificate; import java.util.Arrays; import java.util.Collection; import java.util.Iterator; import junit.framework.Test; import junit.framework.TestCase; import junit.framework.TestSuite; import org.bouncycastle.asn1.ASN1ObjectIdentifier; import org.bouncycastle.asn1.oiw.OIWObjectIdentifiers; import org.bouncycastle.asn1.pkcs.PKCSObjectIdentifiers; import org.bouncycastle.asn1.x509.AlgorithmIdentifier; import org.bouncycastle.cert.X509CertificateHolder; import org.bouncycastle.cms.CMSAlgorithm; import org.bouncycastle.cms.CMSAuthenticatedDataParser; import org.bouncycastle.cms.CMSAuthenticatedDataStreamGenerator; import org.bouncycastle.cms.OriginatorInfoGenerator; import org.bouncycastle.cms.RecipientInformation; import org.bouncycastle.cms.RecipientInformationStore; import org.bouncycastle.cms.jcajce.JceCMSMacCalculatorBuilder; import org.bouncycastle.cms.jcajce.JceKeyTransAuthenticatedRecipient; import org.bouncycastle.cms.jcajce.JceKeyTransRecipientInfoGenerator; import org.bouncycastle.jce.provider.BouncyCastleProvider; import org.bouncycastle.operator.DigestCalculatorProvider; import org.bouncycastle.operator.jcajce.JcaDigestCalculatorProviderBuilder; public class NewAuthenticatedDataStreamTest extends TestCase { private static final String BC = BouncyCastleProvider.PROVIDER_NAME; private static String _signDN; private static KeyPair _signKP; private static X509Certificate _signCert; private static String _origDN; private static KeyPair _origKP; private static X509Certificate _origCert; private static String _reciDN; private static KeyPair _reciKP; private static X509Certificate _reciCert; private static KeyPair _origEcKP; private static KeyPair _reciEcKP; private static X509Certificate _reciEcCert; private static boolean _initialised = false; public boolean DEBUG = true; private static void init() throws Exception { if (!_initialised) { _initialised = true; _signDN = "O=Bouncy Castle, C=AU"; _signKP = CMSTestUtil.makeKeyPair(); _signCert = CMSTestUtil.makeCertificate(_signKP, _signDN, _signKP, _signDN); _origDN = "CN=Bob, OU=Sales, O=Bouncy Castle, C=AU"; _origKP = CMSTestUtil.makeKeyPair(); _origCert = CMSTestUtil.makeCertificate(_origKP, _origDN, _signKP, _signDN); _reciDN = "CN=Doug, OU=Sales, O=Bouncy Castle, C=AU"; _reciKP = CMSTestUtil.makeKeyPair(); _reciCert = CMSTestUtil.makeCertificate(_reciKP, _reciDN, _signKP, _signDN); _origEcKP = CMSTestUtil.makeEcDsaKeyPair(); _reciEcKP = CMSTestUtil.makeEcDsaKeyPair(); _reciEcCert = CMSTestUtil.makeCertificate(_reciEcKP, _reciDN, _signKP, _signDN); } } public void setUp() throws Exception { init(); } public NewAuthenticatedDataStreamTest(String name) { super(name); } public static void main(String args[]) { junit.textui.TestRunner.run(NewAuthenticatedDataStreamTest.class); } public static Test suite() throws Exception { init(); return new CMSTestSetup(new TestSuite(NewAuthenticatedDataStreamTest.class)); } public void testKeyTransDESede() throws Exception { tryKeyTrans(CMSAlgorithm.DES_EDE3_CBC); } public void testKeyTransDESedeWithDigest() throws Exception { tryKeyTransWithDigest(CMSAlgorithm.DES_EDE3_CBC); } public void testOriginatorInfo() throws Exception { ASN1ObjectIdentifier macAlg = CMSAlgorithm.DES_EDE3_CBC; byte[] data = "Eric H. Echidna".getBytes(); CMSAuthenticatedDataStreamGenerator adGen = new CMSAuthenticatedDataStreamGenerator(); ByteArrayOutputStream bOut = new ByteArrayOutputStream(); X509CertificateHolder origCert = new X509CertificateHolder(_origCert.getEncoded()); adGen.setOriginatorInfo(new OriginatorInfoGenerator(origCert).generate()); adGen.addRecipientInfoGenerator(new JceKeyTransRecipientInfoGenerator(_reciCert).setProvider(BC)); OutputStream aOut = adGen.open(bOut, new JceCMSMacCalculatorBuilder(macAlg).setProvider(BC).build()); aOut.write(data); aOut.close(); CMSAuthenticatedDataParser ad = new CMSAuthenticatedDataParser(bOut.toByteArray()); assertTrue(ad.getOriginatorInfo().getCertificates().getMatches(null).contains(origCert)); RecipientInformationStore recipients = ad.getRecipientInfos(); assertEquals(ad.getMacAlgOID(), macAlg.getId()); Collection c = recipients.getRecipients(); assertEquals(1, c.size()); Iterator it = c.iterator(); while (it.hasNext()) { RecipientInformation recipient = (RecipientInformation)it.next(); assertEquals(recipient.getKeyEncryptionAlgOID(), PKCSObjectIdentifiers.rsaEncryption.getId()); byte[] recData = recipient.getContent(new JceKeyTransAuthenticatedRecipient(_reciKP.getPrivate()).setProvider(BC)); assertTrue(Arrays.equals(data, recData)); assertTrue(Arrays.equals(ad.getMac(), recipient.getMac())); } } private void tryKeyTrans(ASN1ObjectIdentifier macAlg) throws Exception { byte[] data = "Eric H. Echidna".getBytes(); CMSAuthenticatedDataStreamGenerator adGen = new CMSAuthenticatedDataStreamGenerator(); ByteArrayOutputStream bOut = new ByteArrayOutputStream(); adGen.addRecipientInfoGenerator(new JceKeyTransRecipientInfoGenerator(_reciCert).setProvider(BC)); OutputStream aOut = adGen.open(bOut, new JceCMSMacCalculatorBuilder(macAlg).setProvider(BC).build()); aOut.write(data); aOut.close(); CMSAuthenticatedDataParser ad = new CMSAuthenticatedDataParser(bOut.toByteArray()); RecipientInformationStore recipients = ad.getRecipientInfos(); assertEquals(ad.getMacAlgOID(), macAlg.getId()); Collection c = recipients.getRecipients(); assertEquals(1, c.size()); Iterator it = c.iterator(); while (it.hasNext()) { RecipientInformation recipient = (RecipientInformation)it.next(); assertEquals(recipient.getKeyEncryptionAlgOID(), PKCSObjectIdentifiers.rsaEncryption.getId()); byte[] recData = recipient.getContent(new JceKeyTransAuthenticatedRecipient(_reciKP.getPrivate()).setProvider(BC)); assertTrue(Arrays.equals(data, recData)); assertTrue(Arrays.equals(ad.getMac(), recipient.getMac())); } } private void tryKeyTransWithDigest(ASN1ObjectIdentifier macAlg) throws Exception { byte[] data = "Eric H. Echidna".getBytes(); CMSAuthenticatedDataStreamGenerator adGen = new CMSAuthenticatedDataStreamGenerator(); ByteArrayOutputStream bOut = new ByteArrayOutputStream(); DigestCalculatorProvider calcProvider = new JcaDigestCalculatorProviderBuilder().setProvider(BC).build(); adGen.addRecipientInfoGenerator(new JceKeyTransRecipientInfoGenerator(_reciCert).setProvider(BC)); OutputStream aOut = adGen.open(bOut, new JceCMSMacCalculatorBuilder(macAlg).setProvider(BC).build(), calcProvider.get(new AlgorithmIdentifier(OIWObjectIdentifiers.idSHA1))); aOut.write(data); aOut.close(); CMSAuthenticatedDataParser ad = new CMSAuthenticatedDataParser(bOut.toByteArray(), calcProvider); RecipientInformationStore recipients = ad.getRecipientInfos(); assertEquals(ad.getMacAlgOID(), macAlg.getId()); Collection c = recipients.getRecipients(); assertEquals(1, c.size()); Iterator it = c.iterator(); while (it.hasNext()) { RecipientInformation recipient = (RecipientInformation)it.next(); assertEquals(recipient.getKeyEncryptionAlgOID(), PKCSObjectIdentifiers.rsaEncryption.getId()); byte[] recData = recipient.getContent(new JceKeyTransAuthenticatedRecipient(_reciKP.getPrivate()).setProvider(BC)); assertTrue(Arrays.equals(data, recData)); assertTrue(Arrays.equals(ad.getMac(), recipient.getMac())); assertTrue(Arrays.equals(ad.getContentDigest(), recipient.getContentDigest())); } } }bouncycastle-1.49.orig/test/src/org/bouncycastle/cms/test/NullProviderTest.java0000644000175000017500000002202311726257324027362 0ustar ebourgebourgpackage org.bouncycastle.cms.test; import java.io.ByteArrayInputStream; import java.io.ByteArrayOutputStream; import java.io.IOException; import java.io.OutputStream; import java.math.BigInteger; import java.security.GeneralSecurityException; import java.security.KeyPair; import java.security.KeyPairGenerator; import java.security.MessageDigest; import java.security.NoSuchAlgorithmException; import java.security.NoSuchProviderException; import java.security.PrivateKey; import java.security.Provider; import java.security.PublicKey; import java.security.SecureRandom; import java.security.cert.CertStore; import java.security.cert.CollectionCertStoreParameters; import java.security.cert.X509Certificate; import java.util.ArrayList; import java.util.Arrays; import java.util.Collection; import java.util.Date; import java.util.Iterator; import java.util.List; import junit.framework.Test; import junit.framework.TestCase; import junit.framework.TestSuite; import org.bouncycastle.asn1.ASN1InputStream; import org.bouncycastle.asn1.cms.ContentInfo; import org.bouncycastle.asn1.pkcs.PKCSObjectIdentifiers; import org.bouncycastle.asn1.x509.X509Name; import org.bouncycastle.cms.CMSEnvelopedData; import org.bouncycastle.cms.CMSEnvelopedDataGenerator; import org.bouncycastle.cms.CMSProcessable; import org.bouncycastle.cms.CMSProcessableByteArray; import org.bouncycastle.cms.CMSSignedData; import org.bouncycastle.cms.CMSSignedDataGenerator; import org.bouncycastle.cms.CMSSignedDataParser; import org.bouncycastle.cms.CMSSignedDataStreamGenerator; import org.bouncycastle.cms.CMSTypedStream; import org.bouncycastle.cms.RecipientInformation; import org.bouncycastle.cms.RecipientInformationStore; import org.bouncycastle.cms.SignerInformation; import org.bouncycastle.cms.SignerInformationStore; import org.bouncycastle.cms.jcajce.JcaX509CertSelectorConverter; import org.bouncycastle.x509.X509V3CertificateGenerator; public class NullProviderTest extends TestCase { static KeyPair keyPair; static X509Certificate keyCert; private static final String TEST_MESSAGE = "Hello World!"; private JcaX509CertSelectorConverter selectorConverter = new JcaX509CertSelectorConverter(); static { try { keyPair = generateKeyPair(); String origDN = "O=Bouncy Castle, C=AU"; keyCert = makeCertificate(keyPair, origDN, keyPair, origDN); } catch (Exception e) { throw new RuntimeException(e); } } public void testSHA1WithRSAEncapsulated() throws Exception { List certList = new ArrayList(); CMSProcessable msg = new CMSProcessableByteArray(TEST_MESSAGE.getBytes()); certList.add(keyCert); CertStore certsAndCrls = CertStore.getInstance("Collection", new CollectionCertStoreParameters(certList)); CMSSignedDataGenerator gen = new CMSSignedDataGenerator(); gen.addSigner(keyPair.getPrivate(), keyCert, CMSSignedDataGenerator.DIGEST_SHA1); gen.addCertificatesAndCRLs(certsAndCrls); CMSSignedData s = gen.generate(msg, true, (Provider)null); ByteArrayInputStream bIn = new ByteArrayInputStream(s.getEncoded()); ASN1InputStream aIn = new ASN1InputStream(bIn); s = new CMSSignedData(ContentInfo.getInstance(aIn.readObject())); certsAndCrls = s.getCertificatesAndCRLs("Collection", (String)null); // make sure String works as well SignerInformationStore signers = s.getSignerInfos(); Collection c = signers.getSigners(); Iterator it = c.iterator(); while (it.hasNext()) { SignerInformation signer = (SignerInformation)it.next(); Collection certCollection = certsAndCrls.getCertificates(selectorConverter.getCertSelector(signer.getSID())); Iterator certIt = certCollection.iterator(); X509Certificate cert = (X509Certificate)certIt.next(); assertEquals(true, signer.verify(cert, (Provider)null)); } } public void testSHA1WithRSAStream() throws Exception { List certList = new ArrayList(); ByteArrayOutputStream bOut = new ByteArrayOutputStream(); certList.add(keyCert); CertStore certsAndCrls = CertStore.getInstance("Collection", new CollectionCertStoreParameters(certList)); CMSSignedDataStreamGenerator gen = new CMSSignedDataStreamGenerator(); gen.addSigner(keyPair.getPrivate(), keyCert, CMSSignedDataStreamGenerator.DIGEST_SHA1, (String)null); gen.addCertificatesAndCRLs(certsAndCrls); OutputStream sigOut = gen.open(bOut); sigOut.write(TEST_MESSAGE.getBytes()); sigOut.close(); CMSSignedDataParser sp = new CMSSignedDataParser( new CMSTypedStream(new ByteArrayInputStream(TEST_MESSAGE.getBytes())), bOut.toByteArray()); sp.getSignedContent().drain(); // // compute expected content digest // MessageDigest md = MessageDigest.getInstance("SHA1"); byte[] contentDigest = md.digest(TEST_MESSAGE.getBytes()); CertStore certStore = sp.getCertificatesAndCRLs("Collection", (String)null); SignerInformationStore signers = sp.getSignerInfos(); Collection c = signers.getSigners(); Iterator it = c.iterator(); while (it.hasNext()) { SignerInformation signer = (SignerInformation)it.next(); Collection certCollection = certStore.getCertificates(selectorConverter.getCertSelector(signer.getSID())); Iterator certIt = certCollection.iterator(); X509Certificate cert = (X509Certificate)certIt.next(); assertEquals(true, signer.verify(cert, (Provider)null)); if (contentDigest != null) { assertTrue(MessageDigest.isEqual(contentDigest, signer.getContentDigest())); } } } public void testKeyTransDES() throws Exception { testKeyTrans(CMSEnvelopedDataGenerator.DES_EDE3_CBC); } public void testKeyTransAES128() throws Exception { testKeyTrans(CMSEnvelopedDataGenerator.AES128_CBC); } public void testKeyTransAES192() throws Exception { testKeyTrans(CMSEnvelopedDataGenerator.AES192_CBC); } public void testKeyTransAES256() throws Exception { testKeyTrans(CMSEnvelopedDataGenerator.AES256_CBC); } private void testKeyTrans(String algorithm) throws Exception { byte[] data = "WallaWallaWashington".getBytes(); CMSEnvelopedDataGenerator edGen = new CMSEnvelopedDataGenerator(); edGen.addKeyTransRecipient(keyCert); CMSEnvelopedData ed = edGen.generate( new CMSProcessableByteArray(data), algorithm, (String)null); RecipientInformationStore recipients = ed.getRecipientInfos(); assertEquals(ed.getEncryptionAlgOID(), algorithm); Collection c = recipients.getRecipients(); assertEquals(1, c.size()); Iterator it = c.iterator(); while (it.hasNext()) { RecipientInformation recipient = (RecipientInformation)it.next(); assertEquals(recipient.getKeyEncryptionAlgOID(), PKCSObjectIdentifiers.rsaEncryption.getId()); byte[] recData = recipient.getContent(keyPair.getPrivate(), (String)null); assertEquals(true, Arrays.equals(data, recData)); } } private static KeyPair generateKeyPair() throws NoSuchProviderException, NoSuchAlgorithmException { KeyPairGenerator kpg = KeyPairGenerator.getInstance("RSA", "SunRsaSign"); kpg.initialize(512, new SecureRandom()); return kpg.generateKeyPair(); } private static X509Certificate makeCertificate(KeyPair subKP, String _subDN, KeyPair issKP, String _issDN) throws GeneralSecurityException, IOException { PublicKey subPub = subKP.getPublic(); PrivateKey issPriv = issKP.getPrivate(); PublicKey issPub = issKP.getPublic(); X509V3CertificateGenerator v3CertGen = new X509V3CertificateGenerator(); v3CertGen.reset(); v3CertGen.setSerialNumber(BigInteger.valueOf(1)); v3CertGen.setIssuerDN(new X509Name(_issDN)); v3CertGen.setNotBefore(new Date(System.currentTimeMillis())); v3CertGen.setNotAfter(new Date(System.currentTimeMillis() + (1000L * 60 * 60 * 24 * 100))); v3CertGen.setSubjectDN(new X509Name(_subDN)); v3CertGen.setPublicKey(subPub); v3CertGen.setSignatureAlgorithm("SHA1WithRSA"); X509Certificate _cert = v3CertGen.generate(issPriv, "SunRsaSign"); _cert.checkValidity(new Date()); _cert.verify(issPub); return _cert; } public static Test suite() throws Exception { return new TestSuite(NullProviderTest.class); } } bouncycastle-1.49.orig/test/src/org/bouncycastle/cms/test/NewSignedDataTest.java0000644000175000017500000025421512123717126027415 0ustar ebourgebourgpackage org.bouncycastle.cms.test; import java.io.ByteArrayInputStream; import java.io.IOException; import java.security.KeyFactory; import java.security.KeyPair; import java.security.MessageDigest; import java.security.Security; import java.security.cert.CertificateException; import java.security.cert.X509CRL; import java.security.cert.X509Certificate; import java.security.spec.PKCS8EncodedKeySpec; import java.security.spec.X509EncodedKeySpec; import java.util.ArrayList; import java.util.Collection; import java.util.HashMap; import java.util.Iterator; import java.util.List; import java.util.Map; import junit.framework.Test; import junit.framework.TestCase; import junit.framework.TestSuite; import org.bouncycastle.asn1.ASN1EncodableVector; import org.bouncycastle.asn1.ASN1InputStream; import org.bouncycastle.asn1.ASN1ObjectIdentifier; import org.bouncycastle.asn1.ASN1OctetString; import org.bouncycastle.asn1.DEROctetString; import org.bouncycastle.asn1.DERSet; import org.bouncycastle.asn1.cms.Attribute; import org.bouncycastle.asn1.cms.AttributeTable; import org.bouncycastle.asn1.cms.CMSAttributes; import org.bouncycastle.asn1.cms.CMSObjectIdentifiers; import org.bouncycastle.asn1.cms.ContentInfo; import org.bouncycastle.asn1.ocsp.OCSPResponse; import org.bouncycastle.asn1.pkcs.PKCSObjectIdentifiers; import org.bouncycastle.asn1.x509.AlgorithmIdentifier; import org.bouncycastle.cert.X509AttributeCertificateHolder; import org.bouncycastle.cert.X509CertificateHolder; import org.bouncycastle.cert.jcajce.JcaCRLStore; import org.bouncycastle.cert.jcajce.JcaCertStore; import org.bouncycastle.cert.jcajce.JcaX509AttributeCertificateHolder; import org.bouncycastle.cert.jcajce.JcaX509CRLHolder; import org.bouncycastle.cert.jcajce.JcaX509CertificateHolder; import org.bouncycastle.cert.ocsp.OCSPResp; import org.bouncycastle.cms.CMSAbsentContent; import org.bouncycastle.cms.CMSAlgorithm; import org.bouncycastle.cms.CMSProcessableByteArray; import org.bouncycastle.cms.CMSSignedData; import org.bouncycastle.cms.CMSSignedDataGenerator; import org.bouncycastle.cms.CMSSignedDataParser; import org.bouncycastle.cms.CMSTypedData; import org.bouncycastle.cms.DefaultCMSSignatureAlgorithmNameGenerator; import org.bouncycastle.cms.DefaultSignedAttributeTableGenerator; import org.bouncycastle.cms.SignerId; import org.bouncycastle.cms.SignerInfoGeneratorBuilder; import org.bouncycastle.cms.SignerInformation; import org.bouncycastle.cms.SignerInformationStore; import org.bouncycastle.cms.SignerInformationVerifier; import org.bouncycastle.cms.bc.BcRSASignerInfoVerifierBuilder; import org.bouncycastle.cms.jcajce.JcaSignerId; import org.bouncycastle.cms.jcajce.JcaSignerInfoGeneratorBuilder; import org.bouncycastle.cms.jcajce.JcaSimpleSignerInfoGeneratorBuilder; import org.bouncycastle.cms.jcajce.JcaSimpleSignerInfoVerifierBuilder; import org.bouncycastle.crypto.params.AsymmetricKeyParameter; import org.bouncycastle.crypto.util.PrivateKeyFactory; import org.bouncycastle.cms.SignerInformationVerifierProvider; import org.bouncycastle.jce.provider.BouncyCastleProvider; import org.bouncycastle.operator.ContentSigner; import org.bouncycastle.operator.DefaultDigestAlgorithmIdentifierFinder; import org.bouncycastle.operator.DefaultSignatureAlgorithmIdentifierFinder; import org.bouncycastle.operator.DigestCalculatorProvider; import org.bouncycastle.operator.OperatorCreationException; import org.bouncycastle.operator.bc.BcContentSignerBuilder; import org.bouncycastle.operator.bc.BcDigestCalculatorProvider; import org.bouncycastle.operator.bc.BcRSAContentSignerBuilder; import org.bouncycastle.operator.jcajce.JcaContentSignerBuilder; import org.bouncycastle.operator.jcajce.JcaDigestCalculatorProviderBuilder; import org.bouncycastle.util.CollectionStore; import org.bouncycastle.util.Store; import org.bouncycastle.util.encoders.Base64; import org.bouncycastle.util.io.Streams; public class NewSignedDataTest extends TestCase { private static final String BC = BouncyCastleProvider.PROVIDER_NAME; boolean DEBUG = true; private static String _origDN; private static KeyPair _origKP; private static X509Certificate _origCert; private static String _signDN; private static KeyPair _signKP; private static X509Certificate _signCert; private static KeyPair _signGostKP; private static X509Certificate _signGostCert; private static KeyPair _signEcDsaKP; private static X509Certificate _signEcDsaCert; private static KeyPair _signEcGostKP; private static X509Certificate _signEcGostCert; private static KeyPair _signDsaKP; private static X509Certificate _signDsaCert; private static String _reciDN; private static KeyPair _reciKP; private static X509Certificate _reciCert; private static X509CRL _signCrl; private static boolean _initialised = false; private byte[] disorderedMessage = Base64.decode( "SU9fc3RkaW5fdXNlZABfX2xpYmNfc3RhcnRfbWFpbgBnZXRob3N0aWQAX19n" + "bW9uX3M="); private byte[] disorderedSet = Base64.decode( "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" + "gQBpSRdnDb6AcNVaXSmGo6+kVPIBhot1LzJOGaPyDNpGXxd7LV4tMBF1U7gr" + "4k1g9BO6YiMWvw9uiTZmn0CfV8+k4fWEuG/nmafRoGIuay2f+ILuT+C0rnp1" + "4FgMsEhuVNJJAmb12QV0PZII+UneyhAneZuQQzVUkTcVgYxogxdSOzCCAlUw" + "ggHBoAMCAQICBACdekowCgYGKyQDAwECBQAwbzELMAkGA1UEBhMCREUxPTA7" + "BgNVBAoUNFJlZ3VsaWVydW5nc2JlaMhvcmRlIGbIdXIgVGVsZWtvbW11bmlr" + "YXRpb24gdW5kIFBvc3QxITAMBgcCggYBCgcUEwExMBEGA1UEAxQKNlItQ2Eg" + "MTpQTjAiGA8yMDAxMDIwMTEzNDcwN1oYDzIwMDUwMzIyMDg1NTUxWjBvMQsw" + "CQYDVQQGEwJERTE9MDsGA1UEChQ0UmVndWxpZXJ1bmdzYmVoyG9yZGUgZsh1" + "ciBUZWxla29tbXVuaWthdGlvbiB1bmQgUG9zdDEhMAwGBwKCBgEKBxQTATEw" + "EQYDVQQDFAo1Ui1DQSAxOlBOMIGhMA0GCSqGSIb3DQEBAQUAA4GPADCBiwKB" + "gQCKHkFTJx8GmoqFTxEOxpK9XkC3NZ5dBEKiUv0Ife3QMqeGMoCUnyJxwW0k" + "2/53duHxtv2yHSZpFKjrjvE/uGwdOMqBMTjMzkFg19e9JPv061wyADOucOIa" + "NAgha/zFt9XUyrHF21knKCvDNExv2MYIAagkTKajLMAw0bu1J0FadQIFAMAA" + "AAEwCgYGKyQDAwECBQADgYEAV1yTi+2gyB7sUhn4PXmi/tmBxAfe5oBjDW8m" + "gxtfudxKGZ6l/FUPNcrSc5oqBYxKWtLmf3XX87LcblYsch617jtNTkMzhx9e" + "qxiD02ufcrxz2EVt0Akdqiz8mdVeqp3oLcNU/IttpSrcA91CAnoUXtDZYwb/" + "gdQ4FI9l3+qo/0UwggJVMIIBwaADAgECAgQAxIymMAoGBiskAwMBAgUAMG8x" + "CzAJBgNVBAYTAkRFMT0wOwYDVQQKFDRSZWd1bGllcnVuZ3NiZWjIb3JkZSBm" + "yHVyIFRlbGVrb21tdW5pa2F0aW9uIHVuZCBQb3N0MSEwDAYHAoIGAQoHFBMB" + "MTARBgNVBAMUCjZSLUNhIDE6UE4wIhgPMjAwMTEwMTUxMzMxNThaGA8yMDA1" + "MDYwMTA5NTIxN1owbzELMAkGA1UEBhMCREUxPTA7BgNVBAoUNFJlZ3VsaWVy" + "dW5nc2JlaMhvcmRlIGbIdXIgVGVsZWtvbW11bmlrYXRpb24gdW5kIFBvc3Qx" + "ITAMBgcCggYBCgcUEwExMBEGA1UEAxQKN1ItQ0EgMTpQTjCBoTANBgkqhkiG" + "9w0BAQEFAAOBjwAwgYsCgYEAiokD/j6lEP4FexF356OpU5teUpGGfUKjIrFX" + "BHc79G0TUzgVxqMoN1PWnWktQvKo8ETaugxLkP9/zfX3aAQzDW4Zki6x6GDq" + "fy09Agk+RJvhfbbIzRkV4sBBco0n73x7TfG/9NTgVr/96U+I+z/1j30aboM6" + "9OkLEhjxAr0/GbsCBQDAAAABMAoGBiskAwMBAgUAA4GBAHWRqRixt+EuqHhR" + "K1kIxKGZL2vZuakYV0R24Gv/0ZR52FE4ECr+I49o8FP1qiGSwnXB0SwjuH2S" + "iGiSJi+iH/MeY85IHwW1P5e+bOMvEOFhZhQXQixOD7totIoFtdyaj1XGYRef" + "0f2cPOjNJorXHGV8wuBk+/j++sxbd/Net3FtMIICVTCCAcGgAwIBAgIEAMSM" + "pzAKBgYrJAMDAQIFADBvMQswCQYDVQQGEwJERTE9MDsGA1UEChQ0UmVndWxp" + "ZXJ1bmdzYmVoyG9yZGUgZsh1ciBUZWxla29tbXVuaWthdGlvbiB1bmQgUG9z" + "dDEhMAwGBwKCBgEKBxQTATEwEQYDVQQDFAo3Ui1DQSAxOlBOMCIYDzIwMDEx" + "MDE1MTMzNDE0WhgPMjAwNTA2MDEwOTUyMTdaMG8xCzAJBgNVBAYTAkRFMT0w" + "OwYDVQQKFDRSZWd1bGllcnVuZ3NiZWjIb3JkZSBmyHVyIFRlbGVrb21tdW5p" + "a2F0aW9uIHVuZCBQb3N0MSEwDAYHAoIGAQoHFBMBMTARBgNVBAMUCjZSLUNh" + "IDE6UE4wgaEwDQYJKoZIhvcNAQEBBQADgY8AMIGLAoGBAIOiqxUkzVyqnvth" + "ihnltsE5m1Xn5TZKeR/2MQPStc5hJ+V4yptEtIx+Fn5rOoqT5VEVWhcE35wd" + "bPvgJyQFn5msmhPQT/6XSGOlrWRoFummXN9lQzAjCj1sgTcmoLCVQ5s5WpCA" + "OXFwVWu16qndz3sPItn3jJ0F3Kh3w79NglvPAgUAwAAAATAKBgYrJAMDAQIF" + "AAOBgQBi5W96UVDoNIRkCncqr1LLG9vF9SGBIkvFpLDIIbcvp+CXhlvsdCJl" + "0pt2QEPSDl4cmpOet+CxJTdTuMeBNXxhb7Dvualog69w/+K2JbPhZYxuVFZs" + "Zh5BkPn2FnbNu3YbJhE60aIkikr72J4XZsI5DxpZCGh6xyV/YPRdKSljFjCC" + "AlQwggHAoAMCAQICAwyDqzAKBgYrJAMDAQIFADBvMQswCQYDVQQGEwJERTE9" + "MDsGA1UEChQ0UmVndWxpZXJ1bmdzYmVoyG9yZGUgZsh1ciBUZWxla29tbXVu" + "aWthdGlvbiB1bmQgUG9zdDEhMAwGBwKCBgEKBxQTATEwEQYDVQQDFAo1Ui1D" + "QSAxOlBOMCIYDzIwMDAwMzIyMDk0MTI3WhgPMjAwNDAxMjExNjA0NTNaMG8x" + "CzAJBgNVBAYTAkRFMT0wOwYDVQQKFDRSZWd1bGllcnVuZ3NiZWjIb3JkZSBm" + "yHVyIFRlbGVrb21tdW5pa2F0aW9uIHVuZCBQb3N0MSEwDAYHAoIGAQoHFBMB" + "MTARBgNVBAMUCjRSLUNBIDE6UE4wgaEwDQYJKoZIhvcNAQEBBQADgY8AMIGL" + "AoGBAI8x26tmrFJanlm100B7KGlRemCD1R93PwdnG7svRyf5ZxOsdGrDszNg" + "xg6ouO8ZHQMT3NC2dH8TvO65Js+8bIyTm51azF6clEg0qeWNMKiiXbBXa+ph" + "hTkGbXiLYvACZ6/MTJMJ1lcrjpRF7BXtYeYMcEF6znD4pxOqrtbf9z5hAgUA" + "wAAAATAKBgYrJAMDAQIFAAOBgQB99BjSKlGPbMLQAgXlvA9jUsDNhpnVm3a1" + "YkfxSqS/dbQlYkbOKvCxkPGA9NBxisBM8l1zFynVjJoy++aysRmcnLY/sHaz" + "23BF2iU7WERy18H3lMBfYB6sXkfYiZtvQZcWaO48m73ZBySuiV3iXpb2wgs/" + "Cs20iqroAWxwq/W/9jCCAlMwggG/oAMCAQICBDsFZ9UwCgYGKyQDAwECBQAw" + "bzELMAkGA1UEBhMCREUxITAMBgcCggYBCgcUEwExMBEGA1UEAxQKNFItQ0Eg" + "MTpQTjE9MDsGA1UEChQ0UmVndWxpZXJ1bmdzYmVoyG9yZGUgZsh1ciBUZWxl" + "a29tbXVuaWthdGlvbiB1bmQgUG9zdDAiGA8xOTk5MDEyMTE3MzUzNFoYDzIw" + "MDQwMTIxMTYwMDAyWjBvMQswCQYDVQQGEwJERTE9MDsGA1UEChQ0UmVndWxp" + "ZXJ1bmdzYmVoyG9yZGUgZsh1ciBUZWxla29tbXVuaWthdGlvbiB1bmQgUG9z" + "dDEhMAwGBwKCBgEKBxQTATEwEQYDVQQDFAozUi1DQSAxOlBOMIGfMA0GCSqG" + "SIb3DQEBAQUAA4GNADCBiQKBgI4B557mbKQg/AqWBXNJhaT/6lwV93HUl4U8" + "u35udLq2+u9phns1WZkdM3gDfEpL002PeLfHr1ID/96dDYf04lAXQfombils" + "of1C1k32xOvxjlcrDOuPEMxz9/HDAQZA5MjmmYHAIulGI8Qg4Tc7ERRtg/hd" + "0QX0/zoOeXoDSEOBAgTAAAABMAoGBiskAwMBAgUAA4GBAIyzwfT3keHI/n2P" + "LrarRJv96mCohmDZNpUQdZTVjGu5VQjVJwk3hpagU0o/t/FkdzAjOdfEw8Ql" + "3WXhfIbNLv1YafMm2eWSdeYbLcbB5yJ1od+SYyf9+tm7cwfDAcr22jNRBqx8" + "wkWKtKDjWKkevaSdy99sAI8jebHtWz7jzydKMIID9TCCA16gAwIBAgICbMcw" + "DQYJKoZIhvcNAQEFBQAwSzELMAkGA1UEBhMCREUxEjAQBgNVBAoUCVNpZ250" + "cnVzdDEoMAwGBwKCBgEKBxQTATEwGAYDVQQDFBFDQSBTSUdOVFJVU1QgMTpQ" + "TjAeFw0wNDA3MzAxMzAyNDZaFw0wNzA3MzAxMzAyNDZaMDwxETAPBgNVBAMM" + "CFlhY29tOlBOMQ4wDAYDVQRBDAVZYWNvbTELMAkGA1UEBhMCREUxCjAIBgNV" + "BAUTATEwgZ8wDQYJKoZIhvcNAQEBBQADgY0AMIGJAoGBAIWzLlYLQApocXIp" + "pgCCpkkOUVLgcLYKeOd6/bXAnI2dTHQqT2bv7qzfUnYvOqiNgYdF13pOYtKg" + "XwXMTNFL4ZOI6GoBdNs9TQiZ7KEWnqnr2945HYx7UpgTBclbOK/wGHuCdcwO" + "x7juZs1ZQPFG0Lv8RoiV9s6HP7POqh1sO0P/AgMBAAGjggH1MIIB8TCBnAYD" + "VR0jBIGUMIGRgBQcZzNghfnXoXRm8h1+VITC5caNRqFzpHEwbzELMAkGA1UE" + "BhMCREUxPTA7BgNVBAoUNFJlZ3VsaWVydW5nc2JlaMhvcmRlIGbIdXIgVGVs" + "ZWtvbW11bmlrYXRpb24gdW5kIFBvc3QxITAMBgcCggYBCgcUEwExMBEGA1UE" + "AxQKNVItQ0EgMTpQToIEALs8rjAdBgNVHQ4EFgQU2e5KAzkVuKaM9I5heXkz" + "bcAIuR8wDgYDVR0PAQH/BAQDAgZAMBIGA1UdIAQLMAkwBwYFKyQIAQEwfwYD" + "VR0fBHgwdjB0oCygKoYobGRhcDovL2Rpci5zaWdudHJ1c3QuZGUvbz1TaWdu" + "dHJ1c3QsYz1kZaJEpEIwQDEdMBsGA1UEAxMUQ1JMU2lnblNpZ250cnVzdDE6" + "UE4xEjAQBgNVBAoTCVNpZ250cnVzdDELMAkGA1UEBhMCREUwYgYIKwYBBQUH" + "AQEEVjBUMFIGCCsGAQUFBzABhkZodHRwOi8vZGlyLnNpZ250cnVzdC5kZS9T" + "aWdudHJ1c3QvT0NTUC9zZXJ2bGV0L2h0dHBHYXRld2F5LlBvc3RIYW5kbGVy" + "MBgGCCsGAQUFBwEDBAwwCjAIBgYEAI5GAQEwDgYHAoIGAQoMAAQDAQH/MA0G" + "CSqGSIb3DQEBBQUAA4GBAHn1m3GcoyD5GBkKUY/OdtD6Sj38LYqYCF+qDbJR" + "6pqUBjY2wsvXepUppEler+stH8mwpDDSJXrJyuzf7xroDs4dkLl+Rs2x+2tg" + "BjU+ABkBDMsym2WpwgA8LCdymmXmjdv9tULxY+ec2pjSEzql6nEZNEfrU8nt" + "ZCSCavgqW4TtMYIBejCCAXYCAQEwUTBLMQswCQYDVQQGEwJERTESMBAGA1UE" + "ChQJU2lnbnRydXN0MSgwDAYHAoIGAQoHFBMBMTAYBgNVBAMUEUNBIFNJR05U" + "UlVTVCAxOlBOAgJsxzAJBgUrDgMCGgUAoIGAMBgGCSqGSIb3DQEJAzELBgkq" + "hkiG9w0BBwEwIwYJKoZIhvcNAQkEMRYEFIYfhPoyfGzkLWWSSLjaHb4HQmaK" + "MBwGCSqGSIb3DQEJBTEPFw0wNTAzMjQwNzM4MzVaMCEGBSskCAYFMRgWFi92" + "YXIvZmlsZXMvdG1wXzEvdGVzdDEwDQYJKoZIhvcNAQEFBQAEgYA2IvA8lhVz" + "VD5e/itUxbFboKxeKnqJ5n/KuO/uBCl1N14+7Z2vtw1sfkIG+bJdp3OY2Cmn" + "mrQcwsN99Vjal4cXVj8t+DJzFG9tK9dSLvD3q9zT/GQ0kJXfimLVwCa4NaSf" + "Qsu4xtG0Rav6bCcnzabAkKuNNvKtH8amSRzk870DBg=="); public static byte[] xtraCounterSig = Base64.decode( "MIIR/AYJKoZIhvcNAQcCoIIR7TCCEekCAQExCzAJBgUrDgMCGgUAMBoGCSqG" + "SIb3DQEHAaANBAtIZWxsbyB3b3JsZKCCDnkwggTPMIIDt6ADAgECAgRDnYD3" + "MA0GCSqGSIb3DQEBBQUAMFgxCzAJBgNVBAYTAklUMRowGAYDVQQKExFJbi5U" + "ZS5TLkEuIFMucC5BLjEtMCsGA1UEAxMkSW4uVGUuUy5BLiAtIENlcnRpZmlj" + "YXRpb24gQXV0aG9yaXR5MB4XDTA4MDkxMjExNDMxMloXDTEwMDkxMjExNDMx" + "MlowgdgxCzAJBgNVBAYTAklUMSIwIAYDVQQKDBlJbnRlc2EgUy5wLkEuLzA1" + "MjYyODkwMDE0MSowKAYDVQQLDCFCdXNpbmVzcyBDb2xsYWJvcmF0aW9uICYg" + "U2VjdXJpdHkxHjAcBgNVBAMMFU1BU1NJTUlMSUFOTyBaSUNDQVJESTERMA8G" + "A1UEBAwIWklDQ0FSREkxFTATBgNVBCoMDE1BU1NJTUlMSUFOTzEcMBoGA1UE" + "BRMTSVQ6WkNDTVNNNzZIMTRMMjE5WTERMA8GA1UELhMIMDAwMDI1ODUwgaAw" + "DQYJKoZIhvcNAQEBBQADgY4AMIGKAoGBALeJTjmyFgx1SIP6c2AuB/kuyHo5" + "j/prKELTALsFDimre/Hxr3wOSet1TdQfFzU8Lu+EJqgfV9cV+cI1yeH1rZs7" + "lei7L3tX/VR565IywnguX5xwvteASgWZr537Fkws50bvTEMyYOj1Tf3FZvZU" + "z4n4OD39KI4mfR9i1eEVIxR3AgQAizpNo4IBoTCCAZ0wHQYDVR0RBBYwFIES" + "emljY2FyZGlAaW50ZXNhLml0MC8GCCsGAQUFBwEDBCMwITAIBgYEAI5GAQEw" + "CwYGBACORgEDAgEUMAgGBgQAjkYBBDBZBgNVHSAEUjBQME4GBgQAizABATBE" + "MEIGCCsGAQUFBwIBFjZodHRwOi8vZS10cnVzdGNvbS5pbnRlc2EuaXQvY2Ff" + "cHViYmxpY2EvQ1BTX0lOVEVTQS5odG0wDgYDVR0PAQH/BAQDAgZAMIGDBgNV" + "HSMEfDB6gBQZCQOW0bjFWBt+EORuxPagEgkQqKFcpFowWDELMAkGA1UEBhMC" + "SVQxGjAYBgNVBAoTEUluLlRlLlMuQS4gUy5wLkEuMS0wKwYDVQQDEyRJbi5U" + "ZS5TLkEuIC0gQ2VydGlmaWNhdGlvbiBBdXRob3JpdHmCBDzRARMwOwYDVR0f" + "BDQwMjAwoC6gLIYqaHR0cDovL2UtdHJ1c3Rjb20uaW50ZXNhLml0L0NSTC9J" + "TlRFU0EuY3JsMB0GA1UdDgQWBBTf5ItL8KmQh541Dxt7YxcWI1254TANBgkq" + "hkiG9w0BAQUFAAOCAQEAgW+uL1CVWQepbC/wfCmR6PN37Sueb4xiKQj2mTD5" + "UZ5KQjpivy/Hbuf0NrfKNiDEhAvoHSPC31ebGiKuTMFNyZPHfPEUnyYGSxea" + "2w837aXJFr6utPNQGBRi89kH90sZDlXtOSrZI+AzJJn5QK3F9gjcayU2NZXQ" + "MJgRwYmFyn2w4jtox+CwXPQ9E5XgxiMZ4WDL03cWVXDLX00EOJwnDDMUNTRI" + "m9Zv+4SKTNlfFbi9UTBqWBySkDzAelsfB2U61oqc2h1xKmCtkGMmN9iZT+Qz" + "ZC/vaaT+hLEBFGAH2gwFrYc4/jTBKyBYeU1vsAxsibIoTs1Apgl6MH75qPDL" + "BzCCBM8wggO3oAMCAQICBEOdgPcwDQYJKoZIhvcNAQEFBQAwWDELMAkGA1UE" + "BhMCSVQxGjAYBgNVBAoTEUluLlRlLlMuQS4gUy5wLkEuMS0wKwYDVQQDEyRJ" + "bi5UZS5TLkEuIC0gQ2VydGlmaWNhdGlvbiBBdXRob3JpdHkwHhcNMDgwOTEy" + "MTE0MzEyWhcNMTAwOTEyMTE0MzEyWjCB2DELMAkGA1UEBhMCSVQxIjAgBgNV" + "BAoMGUludGVzYSBTLnAuQS4vMDUyNjI4OTAwMTQxKjAoBgNVBAsMIUJ1c2lu" + "ZXNzIENvbGxhYm9yYXRpb24gJiBTZWN1cml0eTEeMBwGA1UEAwwVTUFTU0lN" + "SUxJQU5PIFpJQ0NBUkRJMREwDwYDVQQEDAhaSUNDQVJESTEVMBMGA1UEKgwM" + "TUFTU0lNSUxJQU5PMRwwGgYDVQQFExNJVDpaQ0NNU003NkgxNEwyMTlZMREw" + "DwYDVQQuEwgwMDAwMjU4NTCBoDANBgkqhkiG9w0BAQEFAAOBjgAwgYoCgYEA" + "t4lOObIWDHVIg/pzYC4H+S7IejmP+msoQtMAuwUOKat78fGvfA5J63VN1B8X" + "NTwu74QmqB9X1xX5wjXJ4fWtmzuV6Lsve1f9VHnrkjLCeC5fnHC+14BKBZmv" + "nfsWTCznRu9MQzJg6PVN/cVm9lTPifg4Pf0ojiZ9H2LV4RUjFHcCBACLOk2j" + "ggGhMIIBnTAdBgNVHREEFjAUgRJ6aWNjYXJkaUBpbnRlc2EuaXQwLwYIKwYB" + "BQUHAQMEIzAhMAgGBgQAjkYBATALBgYEAI5GAQMCARQwCAYGBACORgEEMFkG" + "A1UdIARSMFAwTgYGBACLMAEBMEQwQgYIKwYBBQUHAgEWNmh0dHA6Ly9lLXRy" + "dXN0Y29tLmludGVzYS5pdC9jYV9wdWJibGljYS9DUFNfSU5URVNBLmh0bTAO" + "BgNVHQ8BAf8EBAMCBkAwgYMGA1UdIwR8MHqAFBkJA5bRuMVYG34Q5G7E9qAS" + "CRCooVykWjBYMQswCQYDVQQGEwJJVDEaMBgGA1UEChMRSW4uVGUuUy5BLiBT" + "LnAuQS4xLTArBgNVBAMTJEluLlRlLlMuQS4gLSBDZXJ0aWZpY2F0aW9uIEF1" + "dGhvcml0eYIEPNEBEzA7BgNVHR8ENDAyMDCgLqAshipodHRwOi8vZS10cnVz" + "dGNvbS5pbnRlc2EuaXQvQ1JML0lOVEVTQS5jcmwwHQYDVR0OBBYEFN/ki0vw" + "qZCHnjUPG3tjFxYjXbnhMA0GCSqGSIb3DQEBBQUAA4IBAQCBb64vUJVZB6ls" + "L/B8KZHo83ftK55vjGIpCPaZMPlRnkpCOmK/L8du5/Q2t8o2IMSEC+gdI8Lf" + "V5saIq5MwU3Jk8d88RSfJgZLF5rbDzftpckWvq6081AYFGLz2Qf3SxkOVe05" + "Ktkj4DMkmflArcX2CNxrJTY1ldAwmBHBiYXKfbDiO2jH4LBc9D0TleDGIxnh" + "YMvTdxZVcMtfTQQ4nCcMMxQ1NEib1m/7hIpM2V8VuL1RMGpYHJKQPMB6Wx8H" + "ZTrWipzaHXEqYK2QYyY32JlP5DNkL+9ppP6EsQEUYAfaDAWthzj+NMErIFh5" + "TW+wDGyJsihOzUCmCXowfvmo8MsHMIIEzzCCA7egAwIBAgIEQ52A9zANBgkq" + "hkiG9w0BAQUFADBYMQswCQYDVQQGEwJJVDEaMBgGA1UEChMRSW4uVGUuUy5B" + "LiBTLnAuQS4xLTArBgNVBAMTJEluLlRlLlMuQS4gLSBDZXJ0aWZpY2F0aW9u" + "IEF1dGhvcml0eTAeFw0wODA5MTIxMTQzMTJaFw0xMDA5MTIxMTQzMTJaMIHY" + "MQswCQYDVQQGEwJJVDEiMCAGA1UECgwZSW50ZXNhIFMucC5BLi8wNTI2Mjg5" + "MDAxNDEqMCgGA1UECwwhQnVzaW5lc3MgQ29sbGFib3JhdGlvbiAmIFNlY3Vy" + "aXR5MR4wHAYDVQQDDBVNQVNTSU1JTElBTk8gWklDQ0FSREkxETAPBgNVBAQM" + "CFpJQ0NBUkRJMRUwEwYDVQQqDAxNQVNTSU1JTElBTk8xHDAaBgNVBAUTE0lU" + "OlpDQ01TTTc2SDE0TDIxOVkxETAPBgNVBC4TCDAwMDAyNTg1MIGgMA0GCSqG" + "SIb3DQEBAQUAA4GOADCBigKBgQC3iU45shYMdUiD+nNgLgf5Lsh6OY/6ayhC" + "0wC7BQ4pq3vx8a98DknrdU3UHxc1PC7vhCaoH1fXFfnCNcnh9a2bO5Xouy97" + "V/1UeeuSMsJ4Ll+ccL7XgEoFma+d+xZMLOdG70xDMmDo9U39xWb2VM+J+Dg9" + "/SiOJn0fYtXhFSMUdwIEAIs6TaOCAaEwggGdMB0GA1UdEQQWMBSBEnppY2Nh" + "cmRpQGludGVzYS5pdDAvBggrBgEFBQcBAwQjMCEwCAYGBACORgEBMAsGBgQA" + "jkYBAwIBFDAIBgYEAI5GAQQwWQYDVR0gBFIwUDBOBgYEAIswAQEwRDBCBggr" + "BgEFBQcCARY2aHR0cDovL2UtdHJ1c3Rjb20uaW50ZXNhLml0L2NhX3B1YmJs" + "aWNhL0NQU19JTlRFU0EuaHRtMA4GA1UdDwEB/wQEAwIGQDCBgwYDVR0jBHww" + "eoAUGQkDltG4xVgbfhDkbsT2oBIJEKihXKRaMFgxCzAJBgNVBAYTAklUMRow" + "GAYDVQQKExFJbi5UZS5TLkEuIFMucC5BLjEtMCsGA1UEAxMkSW4uVGUuUy5B" + "LiAtIENlcnRpZmljYXRpb24gQXV0aG9yaXR5ggQ80QETMDsGA1UdHwQ0MDIw" + "MKAuoCyGKmh0dHA6Ly9lLXRydXN0Y29tLmludGVzYS5pdC9DUkwvSU5URVNB" + "LmNybDAdBgNVHQ4EFgQU3+SLS/CpkIeeNQ8be2MXFiNdueEwDQYJKoZIhvcN" + "AQEFBQADggEBAIFvri9QlVkHqWwv8Hwpkejzd+0rnm+MYikI9pkw+VGeSkI6" + "Yr8vx27n9Da3yjYgxIQL6B0jwt9XmxoirkzBTcmTx3zxFJ8mBksXmtsPN+2l" + "yRa+rrTzUBgUYvPZB/dLGQ5V7Tkq2SPgMySZ+UCtxfYI3GslNjWV0DCYEcGJ" + "hcp9sOI7aMfgsFz0PROV4MYjGeFgy9N3FlVwy19NBDicJwwzFDU0SJvWb/uE" + "ikzZXxW4vVEwalgckpA8wHpbHwdlOtaKnNodcSpgrZBjJjfYmU/kM2Qv72mk" + "/oSxARRgB9oMBa2HOP40wSsgWHlNb7AMbImyKE7NQKYJejB++ajwywcxggM8" + "MIIDOAIBATBgMFgxCzAJBgNVBAYTAklUMRowGAYDVQQKExFJbi5UZS5TLkEu" + "IFMucC5BLjEtMCsGA1UEAxMkSW4uVGUuUy5BLiAtIENlcnRpZmljYXRpb24g" + "QXV0aG9yaXR5AgRDnYD3MAkGBSsOAwIaBQAwDQYJKoZIhvcNAQEBBQAEgYB+" + "lH2cwLqc91mP8prvgSV+RRzk13dJdZvdoVjgQoFrPhBiZCNIEoHvIhMMA/sM" + "X6euSRZk7EjD24FasCEGYyd0mJVLEy6TSPmuW+wWz/28w3a6IWXBGrbb/ild" + "/CJMkPgLPGgOVD1WDwiNKwfasiQSFtySf5DPn3jFevdLeMmEY6GCAjIwggEV" + "BgkqhkiG9w0BCQYxggEGMIIBAgIBATBgMFgxCzAJBgNVBAYTAklUMRowGAYD" + "VQQKExFJbi5UZS5TLkEuIFMucC5BLjEtMCsGA1UEAxMkSW4uVGUuUy5BLiAt" + "IENlcnRpZmljYXRpb24gQXV0aG9yaXR5AgRDnYD3MAkGBSsOAwIaBQAwDQYJ" + "KoZIhvcNAQEBBQAEgYBHlOULfT5GDigIvxP0qZOy8VbpntmzaPF55VV4buKV" + "35J+uHp98gXKp0LrHM69V5IRKuyuQzHHFBqsXxsRI9o6KoOfgliD9Xc+BeMg" + "dKzQhBhBYoFREq8hQM0nSbqDNHYAQyNHMzUA/ZQUO5dlFuH8Dw3iDYAhNtfd" + "PrlchKJthDCCARUGCSqGSIb3DQEJBjGCAQYwggECAgEBMGAwWDELMAkGA1UE" + "BhMCSVQxGjAYBgNVBAoTEUluLlRlLlMuQS4gUy5wLkEuMS0wKwYDVQQDEyRJ" + "bi5UZS5TLkEuIC0gQ2VydGlmaWNhdGlvbiBBdXRob3JpdHkCBEOdgPcwCQYF" + "Kw4DAhoFADANBgkqhkiG9w0BAQEFAASBgEeU5Qt9PkYOKAi/E/Spk7LxVume" + "2bNo8XnlVXhu4pXfkn64en3yBcqnQusczr1XkhEq7K5DMccUGqxfGxEj2joq" + "g5+CWIP1dz4F4yB0rNCEGEFigVESryFAzSdJuoM0dgBDI0czNQD9lBQ7l2UW" + "4fwPDeINgCE2190+uVyEom2E"); byte[] noSignedAttrSample2 = Base64.decode( "MIIIlAYJKoZIhvcNAQcCoIIIhTCCCIECAQExCzAJBgUrDgMCGgUAMAsGCSqG" + "SIb3DQEHAaCCB3UwggOtMIIDa6ADAgECAgEzMAsGByqGSM44BAMFADCBkDEL" + "MAkGA1UEBhMCVVMxCzAJBgNVBAgTAkNBMRIwEAYDVQQHEwlQYWxvIEFsdG8x" + "HTAbBgNVBAoTFFN1biBNaWNyb3N5c3RlbXMgSW5jMSMwIQYDVQQLExpKYXZh" + "IFNvZnR3YXJlIENvZGUgU2lnbmluZzEcMBoGA1UEAxMTSkNFIENvZGUgU2ln" + "bmluZyBDQTAeFw0wMTA1MjkxNjQ3MTFaFw0wNjA1MjgxNjQ3MTFaMG4xHTAb" + "BgNVBAoTFFN1biBNaWNyb3N5c3RlbXMgSW5jMSMwIQYDVQQLExpKYXZhIFNv" + "ZnR3YXJlIENvZGUgU2lnbmluZzEoMCYGA1UEAxMfVGhlIExlZ2lvbiBvZiB0" + "aGUgQm91bmN5IENhc3RsZTCCAbcwggEsBgcqhkjOOAQBMIIBHwKBgQD9f1OB" + "HXUSKVLfSpwu7OTn9hG3UjzvRADDHj+AtlEmaUVdQCJR+1k9jVj6v8X1ujD2" + "y5tVbNeBO4AdNG/yZmC3a5lQpaSfn+gEexAiwk+7qdf+t8Yb+DtX58aophUP" + "BPuD9tPFHsMCNVQTWhaRMvZ1864rYdcq7/IiAxmd0UgBxwIVAJdgUI8VIwvM" + "spK5gqLrhAvwWBz1AoGBAPfhoIXWmz3ey7yrXDa4V7l5lK+7+jrqgvlXTAs9" + "B4JnUVlXjrrUWU/mcQcQgYC0SRZxI+hMKBYTt88JMozIpuE8FnqLVHyNKOCj" + "rh4rs6Z1kW6jfwv6ITVi8ftiegEkO8yk8b6oUZCJqIPf4VrlnwaSi2ZegHtV" + "JWQBTDv+z0kqA4GEAAKBgBWry/FCAZ6miyy39+ftsa+h9lxoL+JtV0MJcUyQ" + "E4VAhpAwWb8vyjba9AwOylYQTktHX5sAkFvjBiU0LOYDbFSTVZSHMRJgfjxB" + "SHtICjOEvr1BJrrOrdzqdxcOUge5n7El124BCrv91x5Ol8UTwtiO9LrRXF/d" + "SyK+RT5n1klRo3YwdDARBglghkgBhvhCAQEEBAMCAIcwDgYDVR0PAQH/BAQD" + "AgHGMB0GA1UdDgQWBBQwMY4NRcco1AO3w1YsokfDLVseEjAPBgNVHRMBAf8E" + "BTADAQH/MB8GA1UdIwQYMBaAFGXi9IbJ007wkU5Yomr12HhamsGmMAsGByqG" + "SM44BAMFAAMvADAsAhRmigTu6QV0sTfEkVljgij/hhdVfAIUQZvMxAnIHc30" + "y/u0C1T5UEG9glUwggPAMIIDfqADAgECAgEQMAsGByqGSM44BAMFADCBkDEL" + "MAkGA1UEBhMCVVMxCzAJBgNVBAgTAkNBMRIwEAYDVQQHEwlQYWxvIEFsdG8x" + "HTAbBgNVBAoTFFN1biBNaWNyb3N5c3RlbXMgSW5jMSMwIQYDVQQLExpKYXZh" + "IFNvZnR3YXJlIENvZGUgU2lnbmluZzEcMBoGA1UEAxMTSkNFIENvZGUgU2ln" + "bmluZyBDQTAeFw0wMTA0MjUwNzAwMDBaFw0yMDA0MjUwNzAwMDBaMIGQMQsw" + "CQYDVQQGEwJVUzELMAkGA1UECBMCQ0ExEjAQBgNVBAcTCVBhbG8gQWx0bzEd" + "MBsGA1UEChMUU3VuIE1pY3Jvc3lzdGVtcyBJbmMxIzAhBgNVBAsTGkphdmEg" + "U29mdHdhcmUgQ29kZSBTaWduaW5nMRwwGgYDVQQDExNKQ0UgQ29kZSBTaWdu" + "aW5nIENBMIIBtzCCASwGByqGSM44BAEwggEfAoGBAOuvNwQeylEeaV2w8o/2" + "tUkfxqSZBdcpv3S3avUZ2B7kG/gKAZqY/3Cr4kpWhmxTs/zhyIGMMfDE87CL" + "5nAG7PdpaNuDTHIpiSk2F1w7SgegIAIqRpdRHXDICBgLzgxum3b3BePn+9Nh" + "eeFgmiSNBpWDPFEg4TDPOFeCphpyDc7TAhUAhCVF4bq5qWKreehbMLiJaxv/" + "e3UCgYEAq8l0e3Tv7kK1alNNO92QBnJokQ8LpCl2LlU71a5NZVx+KjoEpmem" + "0HGqpde34sFyDaTRqh6SVEwgAAmisAlBGTMAssNcrkL4sYvKfJbYEH83RFuq" + "zHjI13J2N2tAmahVZvqoAx6LShECactMuCUGHKB30sms0j3pChD6dnC3+9wD" + "gYQAAoGALQmYXKy4nMeZfu4gGSo0kPnXq6uu3WtylQ1m+O8nj0Sy7ShEx/6v" + "sKYnbwBnRYJbB6hWVjvSKVFhXmk51y50dxLPGUr1LcjLcmHETm/6R0M/FLv6" + "vBhmKMLZZot6LS/CYJJLFP5YPiF/aGK+bEhJ+aBLXoWdGRD5FUVRG3HU9wuj" + "ZjBkMBEGCWCGSAGG+EIBAQQEAwIABzAPBgNVHRMBAf8EBTADAQH/MB8GA1Ud" + "IwQYMBaAFGXi9IbJ007wkU5Yomr12HhamsGmMB0GA1UdDgQWBBRl4vSGydNO" + "8JFOWKJq9dh4WprBpjALBgcqhkjOOAQDBQADLwAwLAIUKvfPPJdd+Xi2CNdB" + "tNkNRUzktJwCFEXNdWkOIfod1rMpsun3Mx0z/fxJMYHoMIHlAgEBMIGWMIGQ" + "MQswCQYDVQQGEwJVUzELMAkGA1UECBMCQ0ExEjAQBgNVBAcTCVBhbG8gQWx0" + "bzEdMBsGA1UEChMUU3VuIE1pY3Jvc3lzdGVtcyBJbmMxIzAhBgNVBAsTGkph" + "dmEgU29mdHdhcmUgQ29kZSBTaWduaW5nMRwwGgYDVQQDExNKQ0UgQ29kZSBT" + "aWduaW5nIENBAgEzMAkGBSsOAwIaBQAwCwYHKoZIzjgEAQUABC8wLQIVAIGV" + "khm+kbV4a/+EP45PHcq0hIViAhR4M9os6IrJnoEDS3Y3l7O6zrSosA=="); private static final byte[] rawGost = Base64.decode( "MIIEBwYJKoZIhvcNAQcCoIID+DCCA/QCAQExDDAKBgYqhQMCAgkFADAfBgkq" + "hkiG9w0BBwGgEgQQU29tZSBEYXRhIEhFUkUhIaCCAuYwggLiMIICkaADAgEC" + "AgopoLG9AAIAArWeMAgGBiqFAwICAzBlMSAwHgYJKoZIhvcNAQkBFhFpbmZv" + "QGNyeXB0b3Byby5ydTELMAkGA1UEBhMCUlUxEzARBgNVBAoTCkNSWVBUTy1Q" + "Uk8xHzAdBgNVBAMTFlRlc3QgQ2VudGVyIENSWVBUTy1QUk8wHhcNMTIxMDE1" + "MTEwNDIzWhcNMTQxMDA0MDcwOTQxWjAhMRIwEAYDVQQDDAl0ZXN0IGdvc3Qx" + "CzAJBgNVBAYTAlJVMGMwHAYGKoUDAgITMBIGByqFAwICJAAGByqFAwICHgED" + "QwAEQPz/F99AG8wyMQz5uK3vJ3MdHk7ZyFzM4Ofnq8nAmDgI5/Nuzcu791/0" + "hRd+1i+fArRsiPMdQXOF0E7bEMHwWfWjggFjMIIBXzAOBgNVHQ8BAf8EBAMC" + "BPAwEwYDVR0lBAwwCgYIKwYBBQUHAwIwHQYDVR0OBBYEFO353ZD7sLCx6rVR" + "2o/IsSxuE1gAMB8GA1UdIwQYMBaAFG2PXgXZX6yRF5QelZoFMDg3ehAqMFUG" + "A1UdHwROMEwwSqBIoEaGRGh0dHA6Ly93d3cuY3J5cHRvcHJvLnJ1L0NlcnRF" + "bnJvbGwvVGVzdCUyMENlbnRlciUyMENSWVBUTy1QUk8oMikuY3JsMIGgBggr" + "BgEFBQcBAQSBkzCBkDAzBggrBgEFBQcwAYYnaHR0cDovL3d3dy5jcnlwdG9w" + "cm8ucnUvb2NzcG5jL29jc3Auc3JmMFkGCCsGAQUFBzAChk1odHRwOi8vd3d3" + "LmNyeXB0b3Byby5ydS9DZXJ0RW5yb2xsL3BraS1zaXRlX1Rlc3QlMjBDZW50" + "ZXIlMjBDUllQVE8tUFJPKDIpLmNydDAIBgYqhQMCAgMDQQBAR4mr69a62d3l" + "yK/UZ4Yz/Yi3jqURtbnJR2gugdzkG5pYHRwC41BbDaa1ItP+1gDp4s78+EiK" + "AJc17CHGZTz3MYHVMIHSAgEBMHMwZTEgMB4GCSqGSIb3DQEJARYRaW5mb0Bj" + "cnlwdG9wcm8ucnUxCzAJBgNVBAYTAlJVMRMwEQYDVQQKEwpDUllQVE8tUFJP" + "MR8wHQYDVQQDExZUZXN0IENlbnRlciBDUllQVE8tUFJPAgopoLG9AAIAArWe" + "MAoGBiqFAwICCQUAMAoGBiqFAwICEwUABED0Gs9zP9lSz/2/e3BUSpzCI3dx" + "39gfl/pFVkx4p5N/GW5o4gHIST9OhDSmdxwpMSK+39YSRD4R0Ue0faOqWEsj" + "AAAAAAAAAAAAAAAAAAAAAA=="); private static final byte[] noAttrEncData = Base64.decode( "MIIFjwYJKoZIhvcNAQcCoIIFgDCCBXwCAQExDTALBglghkgBZQMEAgEwgdAG" + "CSqGSIb3DQEHAaCBwgSBv01JTUUtVmVyc2lvbjogMS4wCkNvbnRlbnQtVHlw" + "ZTogYXBwbGljYXRpb24vb2N0ZXQtc3RyZWFtCkNvbnRlbnQtVHJhbnNmZXIt" + "RW5jb2Rpbmc6IGJpbmFyeQpDb250ZW50LURpc3Bvc2l0aW9uOiBhdHRhY2ht" + "ZW50OyBmaWxlbmFtZT1kb2MuYmluCgpUaGlzIGlzIGEgdmVyeSBodWdlIHNl" + "Y3JldCwgbWFkZSB3aXRoIG9wZW5zc2wKCgoKoIIDNDCCAzAwggKZoAMCAQIC" + "AQEwDQYJKoZIhvcNAQEFBQAwgawxCzAJBgNVBAYTAkFUMRAwDgYDVQQIEwdB" + "dXN0cmlhMQ8wDQYDVQQHEwZWaWVubmExFTATBgNVBAoTDFRpYW5pIFNwaXJp" + "dDEUMBIGA1UECxMLSlVuaXQgdGVzdHMxGjAYBgNVBAMTEU1hc3NpbWlsaWFu" + "byBNYXNpMTEwLwYJKoZIhvcNAQkBFiJtYXNzaW1pbGlhbm8ubWFzaUB0aWFu" + "aS1zcGlyaXQuY29tMCAXDTEyMDEwMjA5MDAzNVoYDzIxOTEwNjA4MDkwMDM1" + "WjCBjzELMAkGA1UEBhMCQVQxEDAOBgNVBAgTB0F1c3RyaWExFTATBgNVBAoT" + "DFRpYW5pIFNwaXJpdDEUMBIGA1UECxMLSlVuaXQgVGVzdHMxDjAMBgNVBAMT" + "BWNlcnQxMTEwLwYJKoZIhvcNAQkBFiJtYXNzaW1pbGlhbm8ubWFzaUB0aWFu" + "aS1zcGlyaXQuY29tMIGfMA0GCSqGSIb3DQEBAQUAA4GNADCBiQKBgQDYHz8n" + "soeWpILn+5tK8XgJc3k5n0h0MOlRXLbZZVB7yuxKMBIZwl8kqqnehfqxX+hr" + "b2MXSCgKEstnVunJVPUGuNxnQ8Z0R9p1o/9gR0KTXmoJ+Epx5wdEofk4Phsi" + "MxjC8FVvt3sSnzal1/m0/9KntrPWksefumGm5XD3W43e5wIDAQABo3sweTAJ" + "BgNVHRMEAjAAMCwGCWCGSAGG+EIBDQQfFh1PcGVuU1NMIEdlbmVyYXRlZCBD" + "ZXJ0aWZpY2F0ZTAdBgNVHQ4EFgQU8mTZGl0EFv6aHo3bup144d6wYW8wHwYD" + "VR0jBBgwFoAUdHG2RdrchT0PFcUBiIiYcy5hAA4wDQYJKoZIhvcNAQEFBQAD" + "gYEATcc52eo73zEA4wmbyPv0lRrmyAxrHvZGIHiKpM8bP38WUB39lgmS8J0S" + "1ioj21bosiakGj/gXnxlk8M8O+mm4zzpYjy8gqGXiUt20+j3bm7MJYM8ePcq" + "dG/kReNuLUbRgIA6b0T4o+0WCELhrd9IlTk5IBKjHIjsP/GR1h0t//kxggFb" + "MIIBVwIBATCBsjCBrDELMAkGA1UEBhMCQVQxEDAOBgNVBAgTB0F1c3RyaWEx" + "DzANBgNVBAcTBlZpZW5uYTEVMBMGA1UEChMMVGlhbmkgU3Bpcml0MRQwEgYD" + "VQQLEwtKVW5pdCB0ZXN0czEaMBgGA1UEAxMRTWFzc2ltaWxpYW5vIE1hc2kx" + "MTAvBgkqhkiG9w0BCQEWIm1hc3NpbWlsaWFuby5tYXNpQHRpYW5pLXNwaXJp" + "dC5jb20CAQEwCwYJYIZIAWUDBAIBMA0GCSqGSIb3DQEBAQUABIGAEthqA7FK" + "V1i+MzzS4zz4DxT4lwUYkWfHaDtZADUyTD5lnP3Pf+t/ScpBEGkEtI7hDqOO" + "zE0WfkBshTx5B/uxDibc/jqjQpSYSz5cvBTgpocIalbqsErOkDYF1QP6UgaV" + "ZoVGwvGYIuIrFgWqgk08NsPHVVjYseTEhUDwkI1KSxU="); byte[] successResp = Base64.decode( "MIIFnAoBAKCCBZUwggWRBgkrBgEFBQcwAQEEggWCMIIFfjCCARehgZ8wgZwx" + "CzAJBgNVBAYTAklOMRcwFQYDVQQIEw5BbmRocmEgcHJhZGVzaDESMBAGA1UE" + "BxMJSHlkZXJhYmFkMQwwCgYDVQQKEwNUQ1MxDDAKBgNVBAsTA0FUQzEeMBwG" + "A1UEAxMVVENTLUNBIE9DU1AgUmVzcG9uZGVyMSQwIgYJKoZIhvcNAQkBFhVv" + "Y3NwQHRjcy1jYS50Y3MuY28uaW4YDzIwMDMwNDAyMTIzNDU4WjBiMGAwOjAJ" + "BgUrDgMCGgUABBRs07IuoCWNmcEl1oHwIak1BPnX8QQUtGyl/iL9WJ1VxjxF" + "j0hAwJ/s1AcCAQKhERgPMjAwMjA4MjkwNzA5MjZaGA8yMDAzMDQwMjEyMzQ1" + "OFowDQYJKoZIhvcNAQEFBQADgYEAfbN0TCRFKdhsmvOdUoiJ+qvygGBzDxD/" + "VWhXYA+16AphHLIWNABR3CgHB3zWtdy2j7DJmQ/R7qKj7dUhWLSqclAiPgFt" + "QQ1YvSJAYfEIdyHkxv4NP0LSogxrumANcDyC9yt/W9yHjD2ICPBIqCsZLuLk" + "OHYi5DlwWe9Zm9VFwCGgggPMMIIDyDCCA8QwggKsoAMCAQICAQYwDQYJKoZI" + "hvcNAQEFBQAwgZQxFDASBgNVBAMTC1RDUy1DQSBPQ1NQMSYwJAYJKoZIhvcN" + "AQkBFhd0Y3MtY2FAdGNzLWNhLnRjcy5jby5pbjEMMAoGA1UEChMDVENTMQww" + "CgYDVQQLEwNBVEMxEjAQBgNVBAcTCUh5ZGVyYWJhZDEXMBUGA1UECBMOQW5k" + "aHJhIHByYWRlc2gxCzAJBgNVBAYTAklOMB4XDTAyMDgyOTA3MTE0M1oXDTAz" + "MDgyOTA3MTE0M1owgZwxCzAJBgNVBAYTAklOMRcwFQYDVQQIEw5BbmRocmEg" + "cHJhZGVzaDESMBAGA1UEBxMJSHlkZXJhYmFkMQwwCgYDVQQKEwNUQ1MxDDAK" + "BgNVBAsTA0FUQzEeMBwGA1UEAxMVVENTLUNBIE9DU1AgUmVzcG9uZGVyMSQw" + "IgYJKoZIhvcNAQkBFhVvY3NwQHRjcy1jYS50Y3MuY28uaW4wgZ8wDQYJKoZI" + "hvcNAQEBBQADgY0AMIGJAoGBAM+XWW4caMRv46D7L6Bv8iwtKgmQu0SAybmF" + "RJiz12qXzdvTLt8C75OdgmUomxp0+gW/4XlTPUqOMQWv463aZRv9Ust4f8MH" + "EJh4ekP/NS9+d8vEO3P40ntQkmSMcFmtA9E1koUtQ3MSJlcs441JjbgUaVnm" + "jDmmniQnZY4bU3tVAgMBAAGjgZowgZcwDAYDVR0TAQH/BAIwADALBgNVHQ8E" + "BAMCB4AwEwYDVR0lBAwwCgYIKwYBBQUHAwkwNgYIKwYBBQUHAQEEKjAoMCYG" + "CCsGAQUFBzABhhpodHRwOi8vMTcyLjE5LjQwLjExMDo3NzAwLzAtBgNVHR8E" + "JjAkMCKgIKAehhxodHRwOi8vMTcyLjE5LjQwLjExMC9jcmwuY3JsMA0GCSqG" + "SIb3DQEBBQUAA4IBAQB6FovM3B4VDDZ15o12gnADZsIk9fTAczLlcrmXLNN4" + "PgmqgnwF0Ymj3bD5SavDOXxbA65AZJ7rBNAguLUo+xVkgxmoBH7R2sBxjTCc" + "r07NEadxM3HQkt0aX5XYEl8eRoifwqYAI9h0ziZfTNes8elNfb3DoPPjqq6V" + "mMg0f0iMS4W8LjNPorjRB+kIosa1deAGPhq0eJ8yr0/s2QR2/WFD5P4aXc8I" + "KWleklnIImS3zqiPrq6tl2Bm8DZj7vXlTOwmraSQxUwzCKwYob1yGvNOUQTq" + "pG6jxn7jgDawHU1+WjWQe4Q34/pWeGLysxTraMa+Ug9kPe+jy/qRX2xwvKBZ"); public NewSignedDataTest(String name) { super(name); } public static void main(String args[]) { junit.textui.TestRunner.run(NewSignedDataTest.class); } public static Test suite() throws Exception { init(); return new CMSTestSetup(new TestSuite(NewSignedDataTest.class)); } private static void init() throws Exception { if (!_initialised) { _initialised = true; if (Security.getProvider(BC) == null) { Security.addProvider(new org.bouncycastle.jce.provider.BouncyCastleProvider()); } _origDN = "O=Bouncy Castle, C=AU"; _origKP = CMSTestUtil.makeKeyPair(); _origCert = CMSTestUtil.makeCertificate(_origKP, _origDN, _origKP, _origDN); _signDN = "CN=Bob, OU=Sales, O=Bouncy Castle, C=AU"; _signKP = CMSTestUtil.makeKeyPair(); _signCert = CMSTestUtil.makeCertificate(_signKP, _signDN, _origKP, _origDN); _signGostKP = CMSTestUtil.makeGostKeyPair(); _signGostCert = CMSTestUtil.makeCertificate(_signGostKP, _signDN, _origKP, _origDN); _signDsaKP = CMSTestUtil.makeDsaKeyPair(); _signDsaCert = CMSTestUtil.makeCertificate(_signDsaKP, _signDN, _origKP, _origDN); _signEcDsaKP = CMSTestUtil.makeEcDsaKeyPair(); _signEcDsaCert = CMSTestUtil.makeCertificate(_signEcDsaKP, _signDN, _origKP, _origDN); _signEcGostKP = CMSTestUtil.makeEcGostKeyPair(); _signEcGostCert = CMSTestUtil.makeCertificate(_signEcGostKP, _signDN, _origKP, _origDN); _reciDN = "CN=Doug, OU=Sales, O=Bouncy Castle, C=AU"; _reciKP = CMSTestUtil.makeKeyPair(); _reciCert = CMSTestUtil.makeCertificate(_reciKP, _reciDN, _signKP, _signDN); _signCrl = CMSTestUtil.makeCrl(_signKP); } } private void verifyRSASignatures(CMSSignedData s, byte[] contentDigest) throws Exception { Store certStore = s.getCertificates(); SignerInformationStore signers = s.getSignerInfos(); Collection c = signers.getSigners(); Iterator it = c.iterator(); while (it.hasNext()) { SignerInformation signer = (SignerInformation)it.next(); Collection certCollection = certStore.getMatches(signer.getSID()); Iterator certIt = certCollection.iterator(); X509CertificateHolder cert = (X509CertificateHolder)certIt.next(); assertEquals(true, signer.verify(new BcRSASignerInfoVerifierBuilder(new DefaultCMSSignatureAlgorithmNameGenerator(), new DefaultSignatureAlgorithmIdentifierFinder(), new DefaultDigestAlgorithmIdentifierFinder(), new BcDigestCalculatorProvider()).build(cert))); if (contentDigest != null) { assertTrue(MessageDigest.isEqual(contentDigest, signer.getContentDigest())); } } } private void verifySignatures(CMSSignedData s, byte[] contentDigest) throws Exception { Store certStore = s.getCertificates(); Store crlStore = s.getCRLs(); SignerInformationStore signers = s.getSignerInfos(); Collection c = signers.getSigners(); Iterator it = c.iterator(); while (it.hasNext()) { SignerInformation signer = (SignerInformation)it.next(); Collection certCollection = certStore.getMatches(signer.getSID()); Iterator certIt = certCollection.iterator(); X509CertificateHolder cert = (X509CertificateHolder)certIt.next(); assertEquals(true, signer.verify(new JcaSimpleSignerInfoVerifierBuilder().setProvider(BC).build(cert))); if (contentDigest != null) { assertTrue(MessageDigest.isEqual(contentDigest, signer.getContentDigest())); } } Collection certColl = certStore.getMatches(null); Collection crlColl = crlStore.getMatches(null); assertEquals(certColl.size(), s.getCertificates().getMatches(null).size()); assertEquals(crlColl.size(), s.getCRLs().getMatches(null).size()); } private void verifySignatures(CMSSignedData s) throws Exception { verifySignatures(s, null); } public void testDetachedVerification() throws Exception { byte[] data = "Hello World!".getBytes(); List certList = new ArrayList(); CMSTypedData msg = new CMSProcessableByteArray(data); certList.add(_origCert); certList.add(_signCert); Store certs = new JcaCertStore(certList); CMSSignedDataGenerator gen = new CMSSignedDataGenerator(); DigestCalculatorProvider digProvider = new JcaDigestCalculatorProviderBuilder().setProvider(BC).build(); JcaSignerInfoGeneratorBuilder signerInfoGeneratorBuilder = new JcaSignerInfoGeneratorBuilder(digProvider); ContentSigner sha1Signer = new JcaContentSignerBuilder("SHA1withRSA").setProvider(BC).build(_origKP.getPrivate()); ContentSigner md5Signer = new JcaContentSignerBuilder("MD5withRSA").setProvider(BC).build(_origKP.getPrivate()); gen.addSignerInfoGenerator(signerInfoGeneratorBuilder.build(sha1Signer, _origCert)); gen.addSignerInfoGenerator(signerInfoGeneratorBuilder.build(md5Signer, _origCert)); gen.addCertificates(certs); CMSSignedData s = gen.generate(msg); MessageDigest sha1 = MessageDigest.getInstance("SHA1", BC); MessageDigest md5 = MessageDigest.getInstance("MD5", BC); Map hashes = new HashMap(); byte[] sha1Hash = sha1.digest(data); byte[] md5Hash = md5.digest(data); hashes.put(CMSAlgorithm.SHA1, sha1Hash); hashes.put(CMSAlgorithm.MD5, md5Hash); s = new CMSSignedData(hashes, s.getEncoded()); verifySignatures(s, null); } public void testSHA1AndMD5WithRSAEncapsulatedRepeated() throws Exception { List certList = new ArrayList(); CMSTypedData msg = new CMSProcessableByteArray("Hello World!".getBytes()); certList.add(_origCert); certList.add(_signCert); Store certs = new JcaCertStore(certList); CMSSignedDataGenerator gen = new CMSSignedDataGenerator(); DigestCalculatorProvider digCalcProv = new JcaDigestCalculatorProviderBuilder().setProvider(BC).build(); gen.addSignerInfoGenerator(new JcaSignerInfoGeneratorBuilder(digCalcProv).build(new JcaContentSignerBuilder("SHA1withRSA").setProvider(BC).build(_origKP.getPrivate()), _origCert)); gen.addSignerInfoGenerator(new JcaSignerInfoGeneratorBuilder(digCalcProv).build(new JcaContentSignerBuilder("MD5withRSA").setProvider(BC).build(_origKP.getPrivate()), _origCert)); gen.addCertificates(certs); CMSSignedData s = gen.generate(msg, true); ByteArrayInputStream bIn = new ByteArrayInputStream(s.getEncoded()); ASN1InputStream aIn = new ASN1InputStream(bIn); s = new CMSSignedData(ContentInfo.getInstance(aIn.readObject())); certs = s.getCertificates(); SignerInformationStore signers = s.getSignerInfos(); assertEquals(2, signers.size()); Collection c = signers.getSigners(); Iterator it = c.iterator(); SignerId sid = null; while (it.hasNext()) { SignerInformation signer = (SignerInformation)it.next(); Collection certCollection = certs.getMatches(signer.getSID()); Iterator certIt = certCollection.iterator(); X509CertificateHolder cert = (X509CertificateHolder)certIt.next(); sid = signer.getSID(); assertEquals(true, signer.verify(new JcaSimpleSignerInfoVerifierBuilder().setProvider(BC).build(cert))); // // check content digest // byte[] contentDigest = (byte[])gen.getGeneratedDigests().get(signer.getDigestAlgOID()); AttributeTable table = signer.getSignedAttributes(); Attribute hash = table.get(CMSAttributes.messageDigest); assertTrue(MessageDigest.isEqual(contentDigest, ((ASN1OctetString)hash.getAttrValues().getObjectAt(0)).getOctets())); } c = signers.getSigners(sid); assertEquals(2, c.size()); // // try using existing signer // gen = new CMSSignedDataGenerator(); gen.addSigners(s.getSignerInfos()); gen.addCertificates(s.getCertificates()); s = gen.generate(msg, true); bIn = new ByteArrayInputStream(s.getEncoded()); aIn = new ASN1InputStream(bIn); s = new CMSSignedData(ContentInfo.getInstance(aIn.readObject())); certs = s.getCertificates(); signers = s.getSignerInfos(); c = signers.getSigners(); it = c.iterator(); assertEquals(2, c.size()); while (it.hasNext()) { SignerInformation signer = (SignerInformation)it.next(); Collection certCollection = certs.getMatches(signer.getSID()); Iterator certIt = certCollection.iterator(); X509CertificateHolder cert = (X509CertificateHolder)certIt.next(); assertEquals(true, signer.verify(new JcaSimpleSignerInfoVerifierBuilder().setProvider(BC).build(cert))); } checkSignerStoreReplacement(s, signers); } public void testSHA1WithRSANoAttributes() throws Exception { List certList = new ArrayList(); CMSTypedData msg = new CMSProcessableByteArray("Hello world!".getBytes()); certList.add(_origCert); certList.add(_signCert); Store certs = new JcaCertStore(certList); CMSSignedDataGenerator gen = new CMSSignedDataGenerator(); ContentSigner sha1Signer = new JcaContentSignerBuilder("SHA1withRSA").setProvider(BC).build(_origKP.getPrivate()); JcaSignerInfoGeneratorBuilder builder = new JcaSignerInfoGeneratorBuilder(new JcaDigestCalculatorProviderBuilder().setProvider(BC).build()); builder.setDirectSignature(true); gen.addSignerInfoGenerator(builder.build(sha1Signer, _origCert)); gen.addCertificates(certs); CMSSignedData s = gen.generate(msg, false); // // compute expected content digest // MessageDigest md = MessageDigest.getInstance("SHA1", BC); verifySignatures(s, md.digest("Hello world!".getBytes())); } public void testSHA1WithRSANoAttributesSimple() throws Exception { List certList = new ArrayList(); CMSTypedData msg = new CMSProcessableByteArray("Hello world!".getBytes()); certList.add(_origCert); certList.add(_signCert); Store certs = new JcaCertStore(certList); CMSSignedDataGenerator gen = new CMSSignedDataGenerator(); JcaSimpleSignerInfoGeneratorBuilder builder = new JcaSimpleSignerInfoGeneratorBuilder().setProvider(BC).setDirectSignature(true); gen.addSignerInfoGenerator(builder.build("SHA1withRSA", _origKP.getPrivate(), _origCert)); gen.addCertificates(certs); CMSSignedData s = gen.generate(msg, false); // // compute expected content digest // MessageDigest md = MessageDigest.getInstance("SHA1", BC); verifySignatures(s, md.digest("Hello world!".getBytes())); } public void testSHA1WithRSAAndOtherRevocation() throws Exception { List certList = new ArrayList(); CMSTypedData msg = new CMSProcessableByteArray("Hello world!".getBytes()); certList.add(_origCert); certList.add(_signCert); Store certs = new JcaCertStore(certList); CMSSignedDataGenerator gen = new CMSSignedDataGenerator(); ContentSigner sha1Signer = new JcaContentSignerBuilder("SHA1withRSA").setProvider(BC).build(_origKP.getPrivate()); gen.addSignerInfoGenerator(new JcaSignerInfoGeneratorBuilder(new JcaDigestCalculatorProviderBuilder().setProvider(BC).build()).build(sha1Signer, _origCert)); gen.addCertificates(certs); List otherInfo = new ArrayList(); OCSPResp response = new OCSPResp(successResp); otherInfo.add(response.toASN1Structure()); gen.addOtherRevocationInfo(CMSObjectIdentifiers.id_ri_ocsp_response, new CollectionStore(otherInfo)); CMSSignedData s; s = gen.generate(msg, false); // // check version // assertEquals(5, s.getVersion()); // // compute expected content digest // MessageDigest md = MessageDigest.getInstance("SHA1", BC); verifySignatures(s, md.digest("Hello world!".getBytes())); Store dataOtherInfo = s.getOtherRevocationInfo(CMSObjectIdentifiers.id_ri_ocsp_response); assertEquals(1, dataOtherInfo.getMatches(null).size()); OCSPResp dataResponse = new OCSPResp(OCSPResponse.getInstance(dataOtherInfo.getMatches(null).iterator().next())); assertEquals(response, dataResponse); } public void testSHA1WithRSAAndAttributeTableSimple() throws Exception { MessageDigest md = MessageDigest.getInstance("SHA1", BC); List certList = new ArrayList(); CMSTypedData msg = new CMSProcessableByteArray("Hello world!".getBytes()); certList.add(_origCert); certList.add(_signCert); Store certs = new JcaCertStore(certList); CMSSignedDataGenerator gen = new CMSSignedDataGenerator(); Attribute attr = new Attribute(CMSAttributes.messageDigest, new DERSet( new DEROctetString( md.digest("Hello world!".getBytes())))); ASN1EncodableVector v = new ASN1EncodableVector(); v.add(attr); JcaSimpleSignerInfoGeneratorBuilder builder = new JcaSimpleSignerInfoGeneratorBuilder().setProvider(BC).setSignedAttributeGenerator(new DefaultSignedAttributeTableGenerator(new AttributeTable(v))); gen.addSignerInfoGenerator(builder.build("SHA1withRSA", _origKP.getPrivate(), _origCert)); gen.addCertificates(certs); CMSSignedData s = gen.generate(new CMSAbsentContent(), false); // // the signature is detached, so need to add msg before passing on // s = new CMSSignedData(msg, s.getEncoded()); // // compute expected content digest // verifySignatures(s, md.digest("Hello world!".getBytes())); verifyRSASignatures(s, md.digest("Hello world!".getBytes())); } public void testSHA1WithRSAAndAttributeTable() throws Exception { MessageDigest md = MessageDigest.getInstance("SHA1", BC); List certList = new ArrayList(); CMSTypedData msg = new CMSProcessableByteArray("Hello world!".getBytes()); certList.add(_origCert); certList.add(_signCert); Store certs = new JcaCertStore(certList); CMSSignedDataGenerator gen = new CMSSignedDataGenerator(); Attribute attr = new Attribute(CMSAttributes.messageDigest, new DERSet( new DEROctetString( md.digest("Hello world!".getBytes())))); ASN1EncodableVector v = new ASN1EncodableVector(); v.add(attr); JcaSignerInfoGeneratorBuilder builder = new JcaSignerInfoGeneratorBuilder(new JcaDigestCalculatorProviderBuilder().setProvider(BC).build()); builder.setSignedAttributeGenerator(new DefaultSignedAttributeTableGenerator(new AttributeTable(v))); ContentSigner sha1Signer = new JcaContentSignerBuilder("SHA1withRSA").setProvider(BC).build(_origKP.getPrivate()); gen.addSignerInfoGenerator(builder.build(sha1Signer, _origCert)); gen.addCertificates(certs); CMSSignedData s = gen.generate(new CMSAbsentContent(), false); // // the signature is detached, so need to add msg before passing on // s = new CMSSignedData(msg, s.getEncoded()); // // compute expected content digest // verifySignatures(s, md.digest("Hello world!".getBytes())); verifyRSASignatures(s, md.digest("Hello world!".getBytes())); } public void testLwSHA1WithRSAAndAttributeTable() throws Exception { MessageDigest md = MessageDigest.getInstance("SHA1", BC); List certList = new ArrayList(); CMSTypedData msg = new CMSProcessableByteArray("Hello world!".getBytes()); certList.add(_origCert); certList.add(_signCert); Store certs = new JcaCertStore(certList); CMSSignedDataGenerator gen = new CMSSignedDataGenerator(); Attribute attr = new Attribute(CMSAttributes.messageDigest, new DERSet( new DEROctetString( md.digest("Hello world!".getBytes())))); ASN1EncodableVector v = new ASN1EncodableVector(); v.add(attr); AsymmetricKeyParameter privKey = PrivateKeyFactory.createKey(_origKP.getPrivate().getEncoded()); AlgorithmIdentifier sigAlgId = new DefaultSignatureAlgorithmIdentifierFinder().find("SHA1withRSA"); AlgorithmIdentifier digAlgId = new DefaultDigestAlgorithmIdentifierFinder().find(sigAlgId); BcContentSignerBuilder contentSignerBuilder = new BcRSAContentSignerBuilder(sigAlgId, digAlgId); gen.addSignerInfoGenerator( new SignerInfoGeneratorBuilder(new BcDigestCalculatorProvider()) .setSignedAttributeGenerator(new DefaultSignedAttributeTableGenerator(new AttributeTable(v))) .build(contentSignerBuilder.build(privKey), new JcaX509CertificateHolder(_origCert))); gen.addCertificates(certs); CMSSignedData s = gen.generate(new CMSAbsentContent(), false); // // the signature is detached, so need to add msg before passing on // s = new CMSSignedData(msg, s.getEncoded()); // // compute expected content digest // verifySignatures(s, md.digest("Hello world!".getBytes())); verifyRSASignatures(s, md.digest("Hello world!".getBytes())); } public void testSHA1WithRSAEncapsulated() throws Exception { encapsulatedTest(_signKP, _signCert, "SHA1withRSA"); } public void testSHA1WithRSAEncapsulatedSubjectKeyID() throws Exception { subjectKeyIDTest(_signKP, _signCert, "SHA1withRSA"); } public void testSHA1WithRSAPSS() throws Exception { rsaPSSTest("SHA1withRSAandMGF1"); } public void testSHA224WithRSAPSS() throws Exception { rsaPSSTest("SHA224withRSAandMGF1"); } public void testSHA256WithRSAPSS() throws Exception { rsaPSSTest("SHA256withRSAandMGF1"); } public void testSHA384WithRSAPSS() throws Exception { rsaPSSTest("SHA384withRSAandMGF1"); } public void testSHA224WithRSAEncapsulated() throws Exception { encapsulatedTest(_signKP, _signCert, "SHA224withRSA"); } public void testSHA256WithRSAEncapsulated() throws Exception { encapsulatedTest(_signKP, _signCert, "SHA256withRSA"); } public void testRIPEMD128WithRSAEncapsulated() throws Exception { encapsulatedTest(_signKP, _signCert, "RIPEMD128withRSA"); } public void testRIPEMD160WithRSAEncapsulated() throws Exception { encapsulatedTest(_signKP, _signCert, "RIPEMD160withRSA"); } public void testRIPEMD256WithRSAEncapsulated() throws Exception { encapsulatedTest(_signKP, _signCert, "RIPEMD256withRSA"); } public void testECDSAEncapsulated() throws Exception { encapsulatedTest(_signEcDsaKP, _signEcDsaCert, "SHA1withECDSA"); } public void testECDSAEncapsulatedSubjectKeyID() throws Exception { subjectKeyIDTest(_signEcDsaKP, _signEcDsaCert, "SHA1withECDSA"); } public void testECDSASHA224Encapsulated() throws Exception { encapsulatedTest(_signEcDsaKP, _signEcDsaCert, "SHA224withECDSA"); } public void testECDSASHA256Encapsulated() throws Exception { encapsulatedTest(_signEcDsaKP, _signEcDsaCert, "SHA256withECDSA"); } public void testECDSASHA384Encapsulated() throws Exception { encapsulatedTest(_signEcDsaKP, _signEcDsaCert, "SHA384withECDSA"); } public void testECDSASHA512Encapsulated() throws Exception { encapsulatedTest(_signEcDsaKP, _signEcDsaCert, "SHA512withECDSA"); } public void testECDSASHA512EncapsulatedWithKeyFactoryAsEC() throws Exception { X509EncodedKeySpec pubSpec = new X509EncodedKeySpec(_signEcDsaKP.getPublic().getEncoded()); PKCS8EncodedKeySpec privSpec = new PKCS8EncodedKeySpec(_signEcDsaKP.getPrivate().getEncoded()); KeyFactory keyFact = KeyFactory.getInstance("EC", BC); KeyPair kp = new KeyPair(keyFact.generatePublic(pubSpec), keyFact.generatePrivate(privSpec)); encapsulatedTest(kp, _signEcDsaCert, "SHA512withECDSA"); } public void testDSAEncapsulated() throws Exception { encapsulatedTest(_signDsaKP, _signDsaCert, "SHA1withDSA"); } public void testDSAEncapsulatedSubjectKeyID() throws Exception { subjectKeyIDTest(_signDsaKP, _signDsaCert, "SHA1withDSA"); } public void testGOST3411WithGOST3410Encapsulated() throws Exception { encapsulatedTest(_signGostKP, _signGostCert, "GOST3411withGOST3410"); } public void testGOST3411WithECGOST3410Encapsulated() throws Exception { encapsulatedTest(_signEcGostKP, _signEcGostCert, "GOST3411withECGOST3410"); } public void testGostNoAttributesEncapsulated() throws Exception { CMSSignedData data = new CMSSignedData(rawGost); Store certStore = data.getCertificates(); SignerInformationStore signers = data.getSignerInfos(); Collection c = signers.getSigners(); Iterator it = c.iterator(); while (it.hasNext()) { SignerInformation signer = (SignerInformation)it.next(); Collection certCollection = certStore.getMatches(signer.getSID()); Iterator certIt = certCollection.iterator(); X509CertificateHolder cert = (X509CertificateHolder)certIt.next(); assertEquals(true, signer.verify(new JcaSimpleSignerInfoVerifierBuilder().setProvider("BC").build(cert))); } } public void testSHA1WithRSACounterSignature() throws Exception { List certList = new ArrayList(); List crlList = new ArrayList(); CMSTypedData msg = new CMSProcessableByteArray("Hello World!".getBytes()); certList.add(_signCert); certList.add(_origCert); crlList.add(_signCrl); Store certStore = new JcaCertStore(certList); Store crlStore = new JcaCRLStore(crlList); CMSSignedDataGenerator gen = new CMSSignedDataGenerator(); ContentSigner sha1Signer = new JcaContentSignerBuilder("SHA1withRSA").setProvider(BC).build(_signKP.getPrivate()); gen.addSignerInfoGenerator(new JcaSignerInfoGeneratorBuilder(new JcaDigestCalculatorProviderBuilder().setProvider(BC).build()).build(sha1Signer, _signCert)); gen.addCertificates(certStore); gen.addCRLs(crlStore); CMSSignedData s = gen.generate(msg, true); SignerInformation origSigner = (SignerInformation)s.getSignerInfos().getSigners().toArray()[0]; SignerInformationStore counterSigners1 = gen.generateCounterSigners(origSigner); SignerInformationStore counterSigners2 = gen.generateCounterSigners(origSigner); SignerInformation signer1 = SignerInformation.addCounterSigners(origSigner, counterSigners1); SignerInformation signer2 = SignerInformation.addCounterSigners(signer1, counterSigners2); SignerInformationStore cs = signer2.getCounterSignatures(); Collection csSigners = cs.getSigners(); assertEquals(2, csSigners.size()); Iterator it = csSigners.iterator(); while (it.hasNext()) { SignerInformation cSigner = (SignerInformation)it.next(); Collection certCollection = certStore.getMatches(cSigner.getSID()); Iterator certIt = certCollection.iterator(); X509CertificateHolder cert = (X509CertificateHolder)certIt.next(); assertTrue(cSigner.isCounterSignature()); assertNull(cSigner.getSignedAttributes().get(PKCSObjectIdentifiers.pkcs_9_at_contentType)); assertEquals(true, cSigner.verify(new JcaSimpleSignerInfoVerifierBuilder().setProvider(BC).build(cert))); } } public void testSHA1WithRSACounterSignatureAndVerifierProvider() throws Exception { List certList = new ArrayList(); List crlList = new ArrayList(); CMSTypedData msg = new CMSProcessableByteArray("Hello World!".getBytes()); certList.add(_signCert); certList.add(_origCert); crlList.add(_signCrl); Store certStore = new JcaCertStore(certList); Store crlStore = new JcaCRLStore(crlList); CMSSignedDataGenerator gen = new CMSSignedDataGenerator(); ContentSigner sha1Signer = new JcaContentSignerBuilder("SHA1withRSA").setProvider(BC).build(_signKP.getPrivate()); gen.addSignerInfoGenerator(new JcaSignerInfoGeneratorBuilder(new JcaDigestCalculatorProviderBuilder().setProvider(BC).build()).build(sha1Signer, _signCert)); gen.addCertificates(certStore); gen.addCRLs(crlStore); CMSSignedData s = gen.generate(msg, true); SignerInformationVerifierProvider vProv = new SignerInformationVerifierProvider() { public SignerInformationVerifier get(SignerId signerId) throws OperatorCreationException { return new JcaSimpleSignerInfoVerifierBuilder().setProvider(BC).build(_signCert); } }; assertTrue(s.verifySignatures(vProv)); SignerInformation origSigner = (SignerInformation)s.getSignerInfos().getSigners().toArray()[0]; gen = new CMSSignedDataGenerator(); sha1Signer = new JcaContentSignerBuilder("SHA1withRSA").setProvider(BC).build(_origKP.getPrivate()); gen.addSignerInfoGenerator(new JcaSignerInfoGeneratorBuilder(new JcaDigestCalculatorProviderBuilder().setProvider(BC).build()).build(sha1Signer, _origCert)); SignerInformationStore counterSigners = gen.generateCounterSigners(origSigner); SignerInformation signer1 = SignerInformation.addCounterSigners(origSigner, counterSigners); List signers = new ArrayList(); signers.add(signer1); s = CMSSignedData.replaceSigners(s, new SignerInformationStore(signers)); assertTrue(s.verifySignatures(vProv, true)); // provider can't handle counter sig assertFalse(s.verifySignatures(vProv, false)); vProv = new SignerInformationVerifierProvider() { public SignerInformationVerifier get(SignerId signerId) throws OperatorCreationException { if (_signCert.getSerialNumber().equals(signerId.getSerialNumber())) { return new JcaSimpleSignerInfoVerifierBuilder().setProvider(BC).build(_signCert); } else { return new JcaSimpleSignerInfoVerifierBuilder().setProvider(BC).build(_origCert); } } }; // verify sig and counter sig. assertFalse(s.verifySignatures(vProv, false)); } private void rsaPSSTest(String signatureAlgorithmName) throws Exception { List certList = new ArrayList(); CMSTypedData msg = new CMSProcessableByteArray("Hello world!".getBytes()); certList.add(_origCert); certList.add(_signCert); Store certs = new JcaCertStore(certList); CMSSignedDataGenerator gen = new CMSSignedDataGenerator(); ContentSigner contentSigner = new JcaContentSignerBuilder(signatureAlgorithmName).setProvider(BC).build(_origKP.getPrivate()); JcaSignerInfoGeneratorBuilder siBuilder = new JcaSignerInfoGeneratorBuilder(new JcaDigestCalculatorProviderBuilder().setProvider(BC).build()); siBuilder.setDirectSignature(true); gen.addSignerInfoGenerator(siBuilder.build(contentSigner, _origCert)); gen.addCertificates(certs); CMSSignedData s = gen.generate(msg, false); // // compute expected content digest // String digestName = signatureAlgorithmName.substring(0, signatureAlgorithmName.indexOf('w')); MessageDigest md = MessageDigest.getInstance(digestName, BC); verifySignatures(s, md.digest("Hello world!".getBytes())); } private void subjectKeyIDTest( KeyPair signaturePair, X509Certificate signatureCert, String signatureAlgorithm) throws Exception { List certList = new ArrayList(); List crlList = new ArrayList(); CMSTypedData msg = new CMSProcessableByteArray("Hello World!".getBytes()); certList.add(signatureCert); certList.add(_origCert); crlList.add(_signCrl); Store certStore = new JcaCertStore(certList); Store crlStore = new JcaCRLStore(crlList); CMSSignedDataGenerator gen = new CMSSignedDataGenerator(); ContentSigner contentSigner = new JcaContentSignerBuilder(signatureAlgorithm).setProvider(BC).build(signaturePair.getPrivate()); gen.addSignerInfoGenerator(new JcaSignerInfoGeneratorBuilder(new JcaDigestCalculatorProviderBuilder().setProvider(BC).build()).build(contentSigner, CMSTestUtil.createSubjectKeyId(signatureCert.getPublicKey()).getKeyIdentifier())); gen.addCertificates(certStore); gen.addCRLs(crlStore); CMSSignedData s = gen.generate(msg, true); assertEquals(3, s.getVersion()); ByteArrayInputStream bIn = new ByteArrayInputStream(s.getEncoded()); ASN1InputStream aIn = new ASN1InputStream(bIn); s = new CMSSignedData(ContentInfo.getInstance(aIn.readObject())); certStore = s.getCertificates(); SignerInformationStore signers = s.getSignerInfos(); Collection c = signers.getSigners(); Iterator it = c.iterator(); while (it.hasNext()) { SignerInformation signer = (SignerInformation)it.next(); Collection certCollection = certStore.getMatches(signer.getSID()); Iterator certIt = certCollection.iterator(); X509CertificateHolder cert = (X509CertificateHolder)certIt.next(); assertEquals(true, signer.verify(new JcaSimpleSignerInfoVerifierBuilder().setProvider(BC).build(cert))); } // // check for CRLs // Collection crls = crlStore.getMatches(null); assertEquals(1, crls.size()); assertTrue(crls.contains(new JcaX509CRLHolder(_signCrl))); // // try using existing signer // gen = new CMSSignedDataGenerator(); gen.addSigners(s.getSignerInfos()); gen.addCertificates(s.getCertificates()); s = gen.generate(msg, true); bIn = new ByteArrayInputStream(s.getEncoded()); aIn = new ASN1InputStream(bIn); s = new CMSSignedData(ContentInfo.getInstance(aIn.readObject())); certStore = s.getCertificates(); signers = s.getSignerInfos(); c = signers.getSigners(); it = c.iterator(); while (it.hasNext()) { SignerInformation signer = (SignerInformation)it.next(); Collection certCollection = certStore.getMatches(signer.getSID()); Iterator certIt = certCollection.iterator(); X509CertificateHolder cert = (X509CertificateHolder)certIt.next(); assertEquals(true, signer.verify(new JcaSimpleSignerInfoVerifierBuilder().setProvider(BC).build(cert))); } checkSignerStoreReplacement(s, signers); } private void encapsulatedTest( KeyPair signaturePair, X509Certificate signatureCert, String signatureAlgorithm) throws Exception { List certList = new ArrayList(); List crlList = new ArrayList(); CMSTypedData msg = new CMSProcessableByteArray("Hello World!".getBytes()); certList.add(signatureCert); certList.add(_origCert); crlList.add(_signCrl); Store certs = new JcaCertStore(certList); Store crlStore = new JcaCRLStore(crlList); CMSSignedDataGenerator gen = new CMSSignedDataGenerator(); ContentSigner contentSigner = new JcaContentSignerBuilder(signatureAlgorithm).setProvider(BC).build(signaturePair.getPrivate()); gen.addSignerInfoGenerator(new JcaSignerInfoGeneratorBuilder(new JcaDigestCalculatorProviderBuilder().setProvider(BC).build()).build(contentSigner, signatureCert)); gen.addCertificates(certs); CMSSignedData s = gen.generate(msg, true); ByteArrayInputStream bIn = new ByteArrayInputStream(s.getEncoded()); ASN1InputStream aIn = new ASN1InputStream(bIn); s = new CMSSignedData(ContentInfo.getInstance(aIn.readObject())); certs = s.getCertificates(); SignerInformationStore signers = s.getSignerInfos(); Collection c = signers.getSigners(); Iterator it = c.iterator(); while (it.hasNext()) { SignerInformation signer = (SignerInformation)it.next(); Collection certCollection = certs.getMatches(signer.getSID()); Iterator certIt = certCollection.iterator(); X509CertificateHolder cert = (X509CertificateHolder)certIt.next(); assertEquals(true, signer.verify(new JcaSimpleSignerInfoVerifierBuilder().setProvider(BC).build(cert))); } // // check signer information lookup // SignerId sid = new JcaSignerId(signatureCert); Collection collection = signers.getSigners(sid); assertEquals(1, collection.size()); assertTrue(collection.iterator().next() instanceof SignerInformation); // // check for CRLs // Collection crls = crlStore.getMatches(null); assertEquals(1, crls.size()); assertTrue(crls.contains(new JcaX509CRLHolder(_signCrl))); // // try using existing signer // gen = new CMSSignedDataGenerator(); gen.addSigners(s.getSignerInfos()); gen.addCertificates(s.getCertificates()); s = gen.generate(msg, true); bIn = new ByteArrayInputStream(s.getEncoded()); aIn = new ASN1InputStream(bIn); s = new CMSSignedData(ContentInfo.getInstance(aIn.readObject())); certs = s.getCertificates(); signers = s.getSignerInfos(); c = signers.getSigners(); it = c.iterator(); while (it.hasNext()) { SignerInformation signer = (SignerInformation)it.next(); Collection certCollection = certs.getMatches(signer.getSID()); Iterator certIt = certCollection.iterator(); X509CertificateHolder cert = (X509CertificateHolder)certIt.next(); assertEquals(true, signer.verify(new JcaSimpleSignerInfoVerifierBuilder().setProvider(BC).build(cert))); } checkSignerStoreReplacement(s, signers); } // // signerInformation store replacement test. // private void checkSignerStoreReplacement( CMSSignedData orig, SignerInformationStore signers) throws Exception { CMSSignedData s = CMSSignedData.replaceSigners(orig, signers); Store certs = s.getCertificates(); signers = s.getSignerInfos(); Collection c = signers.getSigners(); Iterator it = c.iterator(); while (it.hasNext()) { SignerInformation signer = (SignerInformation)it.next(); Collection certCollection = certs.getMatches(signer.getSID()); Iterator certIt = certCollection.iterator(); X509CertificateHolder cert = (X509CertificateHolder)certIt.next(); assertEquals(true, signer.verify(new JcaSimpleSignerInfoVerifierBuilder().setProvider(BC).build(cert))); } } public void testUnsortedAttributes() throws Exception { CMSSignedData s = new CMSSignedData(new CMSProcessableByteArray(disorderedMessage), disorderedSet); Store certs = s.getCertificates(); SignerInformationStore signers = s.getSignerInfos(); Collection c = signers.getSigners(); Iterator it = c.iterator(); while (it.hasNext()) { SignerInformation signer = (SignerInformation)it.next(); Collection certCollection = certs.getMatches(signer.getSID()); Iterator certIt = certCollection.iterator(); X509CertificateHolder cert = (X509CertificateHolder)certIt.next(); assertEquals(true, signer.verify(new JcaSimpleSignerInfoVerifierBuilder().setProvider(BC).build(cert))); } } public void testNullContentWithSigner() throws Exception { List certList = new ArrayList(); certList.add(_origCert); certList.add(_signCert); Store certs = new JcaCertStore(certList); CMSSignedDataGenerator gen = new CMSSignedDataGenerator(); ContentSigner sha1Signer = new JcaContentSignerBuilder("SHA1withRSA").setProvider(BC).build(_origKP.getPrivate()); gen.addSignerInfoGenerator(new JcaSignerInfoGeneratorBuilder(new JcaDigestCalculatorProviderBuilder().setProvider(BC).build()).build(sha1Signer, _origCert)); gen.addCertificates(certs); CMSSignedData s = gen.generate(new CMSAbsentContent(), false); ByteArrayInputStream bIn = new ByteArrayInputStream(s.getEncoded()); ASN1InputStream aIn = new ASN1InputStream(bIn); s = new CMSSignedData(ContentInfo.getInstance(aIn.readObject())); verifySignatures(s); } public void testWithAttributeCertificate() throws Exception { List certList = new ArrayList(); CMSTypedData msg = new CMSProcessableByteArray("Hello World!".getBytes()); certList.add(_signDsaCert); Store certs = new JcaCertStore(certList); CMSSignedDataGenerator gen = new CMSSignedDataGenerator(); JcaSignerInfoGeneratorBuilder builder = new JcaSignerInfoGeneratorBuilder(new JcaDigestCalculatorProviderBuilder().setProvider(BC).build()); ContentSigner sha1Signer = new JcaContentSignerBuilder("SHA1withRSA").setProvider(BC).build(_origKP.getPrivate()); gen.addSignerInfoGenerator(builder.build(sha1Signer, _origCert)); gen.addCertificates(certs); X509AttributeCertificateHolder attrCert = new JcaX509AttributeCertificateHolder(CMSTestUtil.getAttributeCertificate()); List attrList = new ArrayList(); attrList.add(new X509AttributeCertificateHolder(attrCert.getEncoded())); Store store = new CollectionStore(attrList); gen.addAttributeCertificates(store); CMSSignedData sd = gen.generate(msg); assertEquals(4, sd.getVersion()); store = sd.getAttributeCertificates(); Collection coll = store.getMatches(null); assertEquals(1, coll.size()); assertTrue(coll.contains(new X509AttributeCertificateHolder(attrCert.getEncoded()))); // // create new certstore // certList = new ArrayList(); certList.add(_origCert); certList.add(_signCert); certs = new JcaCertStore(certList); // // replace certs // sd = CMSSignedData.replaceCertificatesAndCRLs(sd, certs, null, null); verifySignatures(sd); } public void testCertStoreReplacement() throws Exception { List certList = new ArrayList(); CMSTypedData msg = new CMSProcessableByteArray("Hello World!".getBytes()); certList.add(_signDsaCert); Store certs = new JcaCertStore(certList); CMSSignedDataGenerator gen = new CMSSignedDataGenerator(); ContentSigner sha1Signer = new JcaContentSignerBuilder("SHA1withRSA").setProvider(BC).build(_origKP.getPrivate()); gen.addSignerInfoGenerator(new JcaSignerInfoGeneratorBuilder(new JcaDigestCalculatorProviderBuilder().setProvider(BC).build()).build(sha1Signer, _origCert)); gen.addCertificates(certs); CMSSignedData sd = gen.generate(msg); // // create new certstore // certList = new ArrayList(); certList.add(_origCert); certList.add(_signCert); certs = new JcaCertStore(certList); // // replace certs // sd = CMSSignedData.replaceCertificatesAndCRLs(sd, certs, null, null); verifySignatures(sd); } public void testEncapsulatedCertStoreReplacement() throws Exception { List certList = new ArrayList(); CMSTypedData msg = new CMSProcessableByteArray("Hello World!".getBytes()); certList.add(_signDsaCert); Store certs = new JcaCertStore(certList); CMSSignedDataGenerator gen = new CMSSignedDataGenerator(); ContentSigner sha1Signer = new JcaContentSignerBuilder("SHA1withRSA").setProvider(BC).build(_origKP.getPrivate()); gen.addSignerInfoGenerator(new JcaSignerInfoGeneratorBuilder(new JcaDigestCalculatorProviderBuilder().setProvider(BC).build()).build(sha1Signer, _origCert)); gen.addCertificates(certs); CMSSignedData sd = gen.generate(msg, true); // // create new certstore // certList = new ArrayList(); certList.add(_origCert); certList.add(_signCert); certs = new JcaCertStore(certList); // // replace certs // sd = CMSSignedData.replaceCertificatesAndCRLs(sd, certs, null, null); verifySignatures(sd); } public void testCertOrdering1() throws Exception { List certList = new ArrayList(); CMSTypedData msg = new CMSProcessableByteArray("Hello World!".getBytes()); certList.add(_origCert); certList.add(_signCert); certList.add(_signDsaCert); Store certs = new JcaCertStore(certList); CMSSignedDataGenerator gen = new CMSSignedDataGenerator(); ContentSigner sha1Signer = new JcaContentSignerBuilder("SHA1withRSA").setProvider(BC).build(_origKP.getPrivate()); gen.addSignerInfoGenerator(new JcaSignerInfoGeneratorBuilder(new JcaDigestCalculatorProviderBuilder().setProvider(BC).build()).build(sha1Signer, _origCert)); gen.addCertificates(certs); CMSSignedData sd = gen.generate(msg, true); certs = sd.getCertificates(); Iterator it = certs.getMatches(null).iterator(); assertEquals(new JcaX509CertificateHolder(_origCert), it.next()); assertEquals(new JcaX509CertificateHolder(_signCert), it.next()); assertEquals(new JcaX509CertificateHolder(_signDsaCert), it.next()); } public void testCertOrdering2() throws Exception { List certList = new ArrayList(); CMSTypedData msg = new CMSProcessableByteArray("Hello World!".getBytes()); certList.add(_signCert); certList.add(_signDsaCert); certList.add(_origCert); Store certs = new JcaCertStore(certList); CMSSignedDataGenerator gen = new CMSSignedDataGenerator(); ContentSigner sha1Signer = new JcaContentSignerBuilder("SHA1withRSA").setProvider(BC).build(_origKP.getPrivate()); gen.addSignerInfoGenerator(new JcaSignerInfoGeneratorBuilder(new JcaDigestCalculatorProviderBuilder().setProvider(BC).build()).build(sha1Signer, _origCert)); gen.addCertificates(certs); CMSSignedData sd = gen.generate(msg, true); certs = sd.getCertificates(); Iterator it = certs.getMatches(null).iterator(); assertEquals(new JcaX509CertificateHolder(_signCert), it.next()); assertEquals(new JcaX509CertificateHolder(_signDsaCert), it.next()); assertEquals(new JcaX509CertificateHolder(_origCert), it.next()); } public void testSignerStoreReplacement() throws Exception { List certList = new ArrayList(); CMSTypedData msg = new CMSProcessableByteArray("Hello World!".getBytes()); certList.add(_origCert); certList.add(_signCert); Store certs = new JcaCertStore(certList); CMSSignedDataGenerator gen = new CMSSignedDataGenerator(); ContentSigner sha1Signer = new JcaContentSignerBuilder("SHA1withRSA").setProvider(BC).build(_origKP.getPrivate()); gen.addSignerInfoGenerator(new JcaSignerInfoGeneratorBuilder(new JcaDigestCalculatorProviderBuilder().setProvider(BC).build()).build(sha1Signer, _origCert)); gen.addCertificates(certs); CMSSignedData original = gen.generate(msg, true); // // create new Signer // gen = new CMSSignedDataGenerator(); ContentSigner sha224Signer = new JcaContentSignerBuilder("SHA224withRSA").setProvider(BC).build(_origKP.getPrivate()); gen.addSignerInfoGenerator(new JcaSignerInfoGeneratorBuilder(new JcaDigestCalculatorProviderBuilder().setProvider(BC).build()).build(sha224Signer, _origCert)); gen.addCertificates(certs); CMSSignedData newSD = gen.generate(msg, true); // // replace signer // CMSSignedData sd = CMSSignedData.replaceSigners(original, newSD.getSignerInfos()); SignerInformation signer = (SignerInformation)sd.getSignerInfos().getSigners().iterator().next(); assertEquals(CMSAlgorithm.SHA224.getId(), signer.getDigestAlgOID()); // we use a parser here as it requires the digests to be correct in the digest set, if it // isn't we'll get a NullPointerException CMSSignedDataParser sp = new CMSSignedDataParser(new JcaDigestCalculatorProviderBuilder().setProvider(BC).build(), sd.getEncoded()); sp.getSignedContent().drain(); verifySignatures(sp); } public void testEncapsulatedSamples() throws Exception { testSample("PSSSignDataSHA1Enc.sig"); testSample("PSSSignDataSHA256Enc.sig"); testSample("PSSSignDataSHA512Enc.sig"); } public void testSamples() throws Exception { testSample("PSSSignData.data", "PSSSignDataSHA1.sig"); testSample("PSSSignData.data", "PSSSignDataSHA256.sig"); testSample("PSSSignData.data", "PSSSignDataSHA512.sig"); } public void testNoAttrEncapsulatedSample() throws Exception { CMSSignedData s = new CMSSignedData(noAttrEncData); Store certStore = s.getCertificates(); assertNotNull(certStore); SignerInformationStore signers = s.getSignerInfos(); assertNotNull(signers); Collection c = signers.getSigners(); Iterator it = c.iterator(); while (it.hasNext()) { SignerInformation signer = (SignerInformation)it.next(); Collection certCollection = certStore.getMatches(signer.getSID()); Iterator certIt = certCollection.iterator(); X509CertificateHolder cert = (X509CertificateHolder)certIt.next(); if (!signer.verify(new JcaSimpleSignerInfoVerifierBuilder().setProvider(BC).build(cert))) { fail("Verification FAILED! "); } } } public void testCounterSig() throws Exception { CMSSignedData sig = new CMSSignedData(getInput("counterSig.p7m")); SignerInformationStore ss = sig.getSignerInfos(); Collection signers = ss.getSigners(); SignerInformationStore cs = ((SignerInformation)signers.iterator().next()).getCounterSignatures(); Collection csSigners = cs.getSigners(); assertEquals(1, csSigners.size()); Iterator it = csSigners.iterator(); while (it.hasNext()) { SignerInformation cSigner = (SignerInformation)it.next(); Collection certCollection = sig.getCertificates().getMatches(cSigner.getSID()); Iterator certIt = certCollection.iterator(); X509CertificateHolder cert = (X509CertificateHolder)certIt.next(); assertTrue(cSigner.isCounterSignature()); assertNull(cSigner.getSignedAttributes().get(PKCSObjectIdentifiers.pkcs_9_at_contentType)); assertEquals(true, cSigner.verify(new JcaSimpleSignerInfoVerifierBuilder().setProvider(BC).build(cert))); } verifySignatures(sig); } public void testCertificateManagement() throws Exception { CMSSignedDataGenerator sGen = new CMSSignedDataGenerator(); List certList = new ArrayList(); certList.add(_origCert); certList.add(_signCert); Store certs = new JcaCertStore(certList); sGen.addCertificates(certs); CMSSignedData sData = sGen.generate(new CMSAbsentContent(), true); CMSSignedData rsData = new CMSSignedData(sData.getEncoded()); assertEquals(2, rsData.getCertificates().getMatches(null).size()); } private void testSample(String sigName) throws Exception { CMSSignedData sig = new CMSSignedData(getInput(sigName)); verifySignatures(sig); } private void testSample(String messageName, String sigName) throws Exception { CMSSignedData sig = new CMSSignedData(new CMSProcessableByteArray(getInput(messageName)), getInput(sigName)); verifySignatures(sig); } private byte[] getInput(String name) throws IOException { return Streams.readAll(getClass().getResourceAsStream(name)); } public void testForMultipleCounterSignatures() throws Exception { CMSSignedData sd = new CMSSignedData(xtraCounterSig); for (Iterator sI = sd.getSignerInfos().getSigners().iterator(); sI.hasNext();) { SignerInformation sigI = (SignerInformation)sI.next(); SignerInformationStore counter = sigI.getCounterSignatures(); List sigs = new ArrayList(counter.getSigners()); assertEquals(2, sigs.size()); } } private void verifySignatures(CMSSignedDataParser sp) throws Exception { Store certs = sp.getCertificates(); SignerInformationStore signers = sp.getSignerInfos(); Collection c = signers.getSigners(); Iterator it = c.iterator(); while (it.hasNext()) { SignerInformation signer = (SignerInformation)it.next(); Collection certCollection = certs.getMatches(signer.getSID()); Iterator certIt = certCollection.iterator(); X509CertificateHolder cert = (X509CertificateHolder)certIt.next(); assertEquals(true, signer.verify(new JcaSimpleSignerInfoVerifierBuilder().setProvider(BC).build(cert))); } } private class TestCMSSignatureAlgorithmNameGenerator extends DefaultCMSSignatureAlgorithmNameGenerator { void setDigestAlgorithmMapping(ASN1ObjectIdentifier oid, String algName) { super.setSigningDigestAlgorithmMapping(oid, algName); } void setEncryptionAlgorithmMapping(ASN1ObjectIdentifier oid, String algName) { super.setSigningEncryptionAlgorithmMapping(oid, algName); } } } bouncycastle-1.49.orig/test/src/org/bouncycastle/cms/test/MiscDataStreamTest.java0000644000175000017500000002047612053027274027601 0ustar ebourgebourgpackage org.bouncycastle.cms.test; import java.io.ByteArrayInputStream; import java.io.ByteArrayOutputStream; import java.io.OutputStream; import java.security.KeyPair; import java.security.MessageDigest; import java.security.cert.CertStore; import java.security.cert.CollectionCertStoreParameters; import java.security.cert.X509CRL; import java.security.cert.X509Certificate; import java.util.ArrayList; import java.util.Collection; import java.util.Iterator; import java.util.List; import junit.framework.Test; import junit.framework.TestCase; import junit.framework.TestSuite; import org.bouncycastle.cms.CMSCompressedDataStreamGenerator; import org.bouncycastle.cms.CMSDigestedData; import org.bouncycastle.cms.CMSSignedDataParser; import org.bouncycastle.cms.CMSSignedDataStreamGenerator; import org.bouncycastle.cms.CMSTypedStream; import org.bouncycastle.cms.SignerInformation; import org.bouncycastle.cms.SignerInformationStore; import org.bouncycastle.cms.jcajce.JcaX509CertSelectorConverter; import org.bouncycastle.jce.provider.BouncyCastleProvider; import org.bouncycastle.operator.jcajce.JcaDigestCalculatorProviderBuilder; import org.bouncycastle.util.Arrays; import org.bouncycastle.util.encoders.Base64; public class MiscDataStreamTest extends TestCase { private static final String BC = BouncyCastleProvider.PROVIDER_NAME; private static byte[] data = Base64.decode( "TUlNRS1WZXJzaW9uOiAxLjAKQ29udGVudC1UeXBlOiBhcHBsaWNhdGlvbi9v" + "Y3RldC1zdHJlYW0KQ29udGVudC1UcmFuc2Zlci1FbmNvZGluZzogYmluYXJ5" + "CkNvbnRlbnQtRGlzcG9zaXRpb246IGF0dGFjaG1lbnQ7IGZpbGVuYW1lPWRv" + "Yy5iaW4KClRoaXMgaXMgYSB2ZXJ5IGh1Z2Ugc2VjcmV0LCBtYWRlIHdpdGgg" + "b3BlbnNzbAoKCgo="); private static byte[] digestedData = Base64.decode( "MIIBGAYJKoZIhvcNAQcFoIIBCTCCAQUCAQAwCwYJYIZIAWUDBAIBMIHQBgkq" + "hkiG9w0BBwGggcIEgb9NSU1FLVZlcnNpb246IDEuMApDb250ZW50LVR5cGU6" + "IGFwcGxpY2F0aW9uL29jdGV0LXN0cmVhbQpDb250ZW50LVRyYW5zZmVyLUVu" + "Y29kaW5nOiBiaW5hcnkKQ29udGVudC1EaXNwb3NpdGlvbjogYXR0YWNobWVu" + "dDsgZmlsZW5hbWU9ZG9jLmJpbgoKVGhpcyBpcyBhIHZlcnkgaHVnZSBzZWNy" + "ZXQsIG1hZGUgd2l0aCBvcGVuc3NsCgoKCgQgHLG72tSYW0LgcxOA474iwdCv" + "KyhnaV4RloWTAvkq+do="); private static final String TEST_MESSAGE = "Hello World!"; private static String _signDN; private static KeyPair _signKP; private static X509Certificate _signCert; private static String _origDN; private static KeyPair _origKP; private static X509Certificate _origCert; private static String _reciDN; private static KeyPair _reciKP; private static X509Certificate _reciCert; private static KeyPair _origDsaKP; private static X509Certificate _origDsaCert; private static X509CRL _signCrl; private static X509CRL _origCrl; private static boolean _initialised = false; private static final JcaX509CertSelectorConverter selectorConverter = new JcaX509CertSelectorConverter(); public MiscDataStreamTest(String name) { super(name); } private static void init() throws Exception { if (!_initialised) { _initialised = true; _signDN = "O=Bouncy Castle, C=AU"; _signKP = CMSTestUtil.makeKeyPair(); _signCert = CMSTestUtil.makeCertificate(_signKP, _signDN, _signKP, _signDN); _origDN = "CN=Bob, OU=Sales, O=Bouncy Castle, C=AU"; _origKP = CMSTestUtil.makeKeyPair(); _origCert = CMSTestUtil.makeCertificate(_origKP, _origDN, _signKP, _signDN); _origDsaKP = CMSTestUtil.makeDsaKeyPair(); _origDsaCert = CMSTestUtil.makeCertificate(_origDsaKP, _origDN, _signKP, _signDN); _reciDN = "CN=Doug, OU=Sales, O=Bouncy Castle, C=AU"; _reciKP = CMSTestUtil.makeKeyPair(); _reciCert = CMSTestUtil.makeCertificate(_reciKP, _reciDN, _signKP, _signDN); _signCrl = CMSTestUtil.makeCrl(_signKP); _origCrl = CMSTestUtil.makeCrl(_origKP); } } private void verifySignatures(CMSSignedDataParser sp, byte[] contentDigest) throws Exception { CertStore certStore = sp.getCertificatesAndCRLs("Collection", BC); SignerInformationStore signers = sp.getSignerInfos(); Collection c = signers.getSigners(); Iterator it = c.iterator(); while (it.hasNext()) { SignerInformation signer = (SignerInformation)it.next(); Collection certCollection = certStore.getCertificates(selectorConverter.getCertSelector(signer.getSID())); Iterator certIt = certCollection.iterator(); X509Certificate cert = (X509Certificate)certIt.next(); assertEquals(true, signer.verify(cert, BC)); if (contentDigest != null) { assertTrue(MessageDigest.isEqual(contentDigest, signer.getContentDigest())); } } Collection certColl = certStore.getCertificates(null); Collection crlColl = certStore.getCRLs(null); assertEquals(certColl.size(), sp.getCertificates("Collection", BC).getMatches(null).size()); assertEquals(crlColl.size(), sp.getCRLs("Collection", BC).getMatches(null).size()); } private void verifySignatures(CMSSignedDataParser sp) throws Exception { verifySignatures(sp, null); } private void verifyEncodedData(ByteArrayOutputStream bOut) throws Exception { CMSSignedDataParser sp; sp = new CMSSignedDataParser(bOut.toByteArray()); sp.getSignedContent().drain(); verifySignatures(sp); sp.close(); } private void checkSigParseable(byte[] sig) throws Exception { CMSSignedDataParser sp = new CMSSignedDataParser(sig); sp.getVersion(); CMSTypedStream sc = sp.getSignedContent(); if (sc != null) { sc.drain(); } sp.getCertificatesAndCRLs("Collection", BC); sp.getSignerInfos(); sp.close(); } public void testSHA1WithRSA() throws Exception { List certList = new ArrayList(); ByteArrayOutputStream bOut = new ByteArrayOutputStream(); certList.add(_origCert); certList.add(_signCert); certList.add(_signCrl); certList.add(_origCrl); CertStore certsAndCrls = CertStore.getInstance("Collection", new CollectionCertStoreParameters(certList), BC); CMSSignedDataStreamGenerator gen = new CMSSignedDataStreamGenerator(); gen.addSigner(_origKP.getPrivate(), _origCert, CMSSignedDataStreamGenerator.DIGEST_SHA1, BC); gen.addCertificatesAndCRLs(certsAndCrls); OutputStream sigOut = gen.open(bOut); CMSCompressedDataStreamGenerator cGen = new CMSCompressedDataStreamGenerator(); OutputStream cOut = cGen.open(sigOut, CMSCompressedDataStreamGenerator.ZLIB); cOut.write(TEST_MESSAGE.getBytes()); cOut.close(); sigOut.close(); checkSigParseable(bOut.toByteArray()); // generate compressed stream ByteArrayOutputStream cDataOut = new ByteArrayOutputStream(); cOut = cGen.open(cDataOut, CMSCompressedDataStreamGenerator.ZLIB); cOut.write(TEST_MESSAGE.getBytes()); cOut.close(); CMSSignedDataParser sp = new CMSSignedDataParser( new CMSTypedStream(new ByteArrayInputStream(cDataOut.toByteArray())), bOut.toByteArray()); sp.getSignedContent().drain(); // // compute expected content digest // MessageDigest md = MessageDigest.getInstance("SHA1", BC); verifySignatures(sp, md.digest(cDataOut.toByteArray())); } public void testDigestedData() throws Exception { CMSDigestedData digData = new CMSDigestedData(digestedData); assertTrue(Arrays.areEqual(data, (byte[])digData.getDigestedContent().getContent())); assertTrue(digData.verify(new JcaDigestCalculatorProviderBuilder().setProvider(BC).build())); } public static Test suite() throws Exception { init(); return new CMSTestSetup(new TestSuite(MiscDataStreamTest.class)); } }bouncycastle-1.49.orig/test/src/org/bouncycastle/cms/test/CMSTestSetup.java0000644000175000017500000000070412116547407026400 0ustar ebourgebourgpackage org.bouncycastle.cms.test; import junit.extensions.TestSetup; import junit.framework.Test; import java.security.Security; class CMSTestSetup extends TestSetup { public CMSTestSetup(Test test) { super(test); } protected void setUp() { Security.addProvider(new org.bouncycastle.jce.provider.BouncyCastleProvider()); } protected void tearDown() { Security.removeProvider("BC"); } } bouncycastle-1.49.orig/test/src/org/bouncycastle/cms/test/CMSSampleMessages.java0000644000175000017500000002435610622746521027360 0ustar ebourgebourgpackage org.bouncycastle.cms.test; import org.bouncycastle.util.encoders.Base64; public class CMSSampleMessages { static byte[] originatorMessage = Base64.decode( "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" + "k9HhGwwsgiR+"); } bouncycastle-1.49.orig/test/src/org/bouncycastle/cms/test/package.html0000644000175000017500000000027710330633061025504 0ustar ebourgebourg Regression tests for the org.bouncycastle.cms package.

    Note: The classes in this package are also a useful source of example code. bouncycastle-1.49.orig/test/src/org/bouncycastle/cms/test/SHA1DigestCalculator.java0000644000175000017500000000176711725014572027752 0ustar ebourgebourgpackage org.bouncycastle.cms.test; import java.io.ByteArrayOutputStream; import java.io.OutputStream; import org.bouncycastle.asn1.oiw.OIWObjectIdentifiers; import org.bouncycastle.asn1.x509.AlgorithmIdentifier; import org.bouncycastle.crypto.Digest; import org.bouncycastle.crypto.digests.SHA1Digest; import org.bouncycastle.operator.DigestCalculator; class SHA1DigestCalculator implements DigestCalculator { private ByteArrayOutputStream bOut = new ByteArrayOutputStream(); public AlgorithmIdentifier getAlgorithmIdentifier() { return new AlgorithmIdentifier(OIWObjectIdentifiers.idSHA1); } public OutputStream getOutputStream() { return bOut; } public byte[] getDigest() { byte[] bytes = bOut.toByteArray(); bOut.reset(); Digest sha1 = new SHA1Digest(); sha1.update(bytes, 0, bytes.length); byte[] digest = new byte[sha1.getDigestSize()]; sha1.doFinal(digest, 0); return digest; } } bouncycastle-1.49.orig/test/src/org/bouncycastle/tsp/0000755000175000017500000000000012152033550022263 5ustar ebourgebourgbouncycastle-1.49.orig/test/src/org/bouncycastle/tsp/TimeStampTokenInfoUnitTest.java0000644000175000017500000001133511724256421030361 0ustar ebourgebourgpackage org.bouncycastle.tsp; import java.io.IOException; import java.math.BigInteger; import junit.framework.TestCase; import org.bouncycastle.asn1.ASN1InputStream; import org.bouncycastle.asn1.tsp.TSTInfo; import org.bouncycastle.util.Arrays; import org.bouncycastle.util.encoders.Hex; public class TimeStampTokenInfoUnitTest extends TestCase { private static final byte[] tstInfo1 = Hex.decode( "303e02010106022a033021300906052b0e03021a050004140000000000000000000000000000000000000000" + "020118180f32303035313130313038313732315a"); private static final byte[] tstInfo2 = Hex.decode( "304c02010106022a033021300906052b0e03021a05000414ffffffffffffffffffffffffffffffffffffffff" + "020117180f32303035313130313038323934355a3009020103800101810102020164"); private static final byte[] tstInfo3 = Hex.decode( "304f02010106022a033021300906052b0e03021a050004140000000000000000000000000000000000000000" + "020117180f32303035313130313038343733355a30090201038001018101020101ff020164"); private static final byte[] tstInfoDudDate = Hex.decode( "303e02010106022a033021300906052b0e03021a050004140000000000000000000000000000000000000000" + "020118180f32303056313130313038313732315a"); public void testTstInfo1() throws Exception { TimeStampTokenInfo tstInfo = getTimeStampTokenInfo(tstInfo1); // // verify // GenTimeAccuracy accuracy = tstInfo.getGenTimeAccuracy(); assertNull(accuracy); assertEquals(new BigInteger("24"), tstInfo.getSerialNumber()); assertEquals(1130833041000L, tstInfo.getGenTime().getTime()); assertEquals("1.2.3", tstInfo.getPolicy().getId()); assertEquals(false, tstInfo.isOrdered()); assertNull(tstInfo.getNonce()); assertEquals(TSPAlgorithms.SHA1, tstInfo.getMessageImprintAlgOID()); assertTrue(Arrays.areEqual(new byte[20], tstInfo.getMessageImprintDigest())); assertTrue(Arrays.areEqual(tstInfo1, tstInfo.getEncoded())); } public void testTstInfo2() throws Exception { TimeStampTokenInfo tstInfo = getTimeStampTokenInfo(tstInfo2); // // verify // GenTimeAccuracy accuracy = tstInfo.getGenTimeAccuracy(); assertEquals(3, accuracy.getSeconds()); assertEquals(1, accuracy.getMillis()); assertEquals(2, accuracy.getMicros()); assertEquals(new BigInteger("23"), tstInfo.getSerialNumber()); assertEquals(1130833785000L, tstInfo.getGenTime().getTime()); assertEquals("1.2.3", tstInfo.getPolicy().getId()); assertEquals(false, tstInfo.isOrdered()); assertEquals(tstInfo.getNonce(), BigInteger.valueOf(100)); assertTrue(Arrays.areEqual(Hex.decode("ffffffffffffffffffffffffffffffffffffffff"), tstInfo.getMessageImprintDigest())); assertTrue(Arrays.areEqual(tstInfo2, tstInfo.getEncoded())); } public void testTstInfo3() throws Exception { TimeStampTokenInfo tstInfo = getTimeStampTokenInfo(tstInfo3); // // verify // GenTimeAccuracy accuracy = tstInfo.getGenTimeAccuracy(); assertEquals(3, accuracy.getSeconds()); assertEquals(1, accuracy.getMillis()); assertEquals(2, accuracy.getMicros()); assertEquals(new BigInteger("23"), tstInfo.getSerialNumber()); assertEquals(1130834855000L, tstInfo.getGenTime().getTime()); assertEquals("1.2.3", tstInfo.getPolicy().getId()); assertEquals(true, tstInfo.isOrdered()); assertEquals(tstInfo.getNonce(), BigInteger.valueOf(100)); assertEquals(TSPAlgorithms.SHA1, tstInfo.getMessageImprintAlgOID()); assertTrue(Arrays.areEqual(new byte[20], tstInfo.getMessageImprintDigest())); assertTrue(Arrays.areEqual(tstInfo3, tstInfo.getEncoded())); } public void testTstInfoDudDate() throws Exception { try { getTimeStampTokenInfo(tstInfoDudDate); fail("dud date not detected."); } catch (TSPException e) { // expected } } private TimeStampTokenInfo getTimeStampTokenInfo( byte[] tstInfo) throws IOException, TSPException { ASN1InputStream aIn = new ASN1InputStream(tstInfo); TSTInfo info = TSTInfo.getInstance(aIn.readObject()); return new TimeStampTokenInfo(info); } } bouncycastle-1.49.orig/test/src/org/bouncycastle/tsp/GenTimeAccuracyUnitTest.java0000644000175000017500000000637011625364337027655 0ustar ebourgebourgpackage org.bouncycastle.tsp; import junit.framework.TestCase; import org.bouncycastle.asn1.ASN1Integer; import org.bouncycastle.asn1.tsp.Accuracy; public class GenTimeAccuracyUnitTest extends TestCase { private static final ASN1Integer ZERO_VALUE = new ASN1Integer(0); private static final ASN1Integer ONE_VALUE = new ASN1Integer(1); private static final ASN1Integer TWO_VALUE = new ASN1Integer(2); private static final ASN1Integer THREE_VALUE = new ASN1Integer(3); public void testOneTwoThree() { GenTimeAccuracy accuracy = new GenTimeAccuracy(new Accuracy(ONE_VALUE, TWO_VALUE, THREE_VALUE)); checkValues(accuracy, ONE_VALUE, TWO_VALUE, THREE_VALUE); checkToString(accuracy, "1.002003"); } public void testThreeTwoOne() { GenTimeAccuracy accuracy = new GenTimeAccuracy(new Accuracy(THREE_VALUE, TWO_VALUE, ONE_VALUE)); checkValues(accuracy, THREE_VALUE, TWO_VALUE, ONE_VALUE); checkToString(accuracy, "3.002001"); } public void testTwoThreeTwo() { GenTimeAccuracy accuracy = new GenTimeAccuracy(new Accuracy(TWO_VALUE, THREE_VALUE, TWO_VALUE)); checkValues(accuracy, TWO_VALUE, THREE_VALUE, TWO_VALUE); checkToString(accuracy, "2.003002"); } public void testZeroTwoThree() { GenTimeAccuracy accuracy = new GenTimeAccuracy(new Accuracy(ZERO_VALUE, TWO_VALUE, THREE_VALUE)); checkValues(accuracy, ZERO_VALUE, TWO_VALUE, THREE_VALUE); checkToString(accuracy, "0.002003"); } public void testThreeTwoNull() { GenTimeAccuracy accuracy = new GenTimeAccuracy(new Accuracy(THREE_VALUE, TWO_VALUE, null)); checkValues(accuracy, THREE_VALUE, TWO_VALUE, ZERO_VALUE); checkToString(accuracy, "3.002000"); } public void testOneNullOne() { GenTimeAccuracy accuracy = new GenTimeAccuracy(new Accuracy(ONE_VALUE, null, ONE_VALUE)); checkValues(accuracy, ONE_VALUE, ZERO_VALUE, ONE_VALUE); checkToString(accuracy, "1.000001"); } public void testZeroNullNull() { GenTimeAccuracy accuracy = new GenTimeAccuracy(new Accuracy(ZERO_VALUE, null, null)); checkValues(accuracy, ZERO_VALUE, ZERO_VALUE, ZERO_VALUE); checkToString(accuracy, "0.000000"); } public void testNullNullNull() { GenTimeAccuracy accuracy = new GenTimeAccuracy(new Accuracy(null, null, null)); checkValues(accuracy, ZERO_VALUE, ZERO_VALUE, ZERO_VALUE); checkToString(accuracy, "0.000000"); } private void checkValues( GenTimeAccuracy accuracy, ASN1Integer secs, ASN1Integer millis, ASN1Integer micros) { assertEquals(secs.getValue().intValue(), accuracy.getSeconds()); assertEquals(millis.getValue().intValue(), accuracy.getMillis()); assertEquals(micros.getValue().intValue(), accuracy.getMicros()); } private void checkToString( GenTimeAccuracy accuracy, String expected) { assertEquals(expected, accuracy.toString()); } } bouncycastle-1.49.orig/test/src/org/bouncycastle/tsp/test/0000755000175000017500000000000012152033550023242 5ustar ebourgebourgbouncycastle-1.49.orig/test/src/org/bouncycastle/tsp/test/TSPTestUtil.java0000644000175000017500000001450311737300607026264 0ustar ebourgebourgpackage org.bouncycastle.tsp.test; import java.io.IOException; import java.math.BigInteger; import java.security.GeneralSecurityException; import java.security.KeyPair; import java.security.KeyPairGenerator; import java.security.PrivateKey; import java.security.PublicKey; import java.security.SecureRandom; import java.security.cert.X509Certificate; import java.util.Date; import javax.crypto.KeyGenerator; import javax.crypto.SecretKey; import org.bouncycastle.asn1.DERObjectIdentifier; import org.bouncycastle.asn1.x509.AuthorityKeyIdentifier; import org.bouncycastle.asn1.x509.BasicConstraints; import org.bouncycastle.asn1.x509.ExtendedKeyUsage; import org.bouncycastle.asn1.x509.Extension; import org.bouncycastle.asn1.x509.KeyPurposeId; import org.bouncycastle.asn1.x509.SubjectKeyIdentifier; import org.bouncycastle.asn1.x509.X509Name; import org.bouncycastle.cert.jcajce.JcaX509ExtensionUtils; import org.bouncycastle.util.encoders.Base64; import org.bouncycastle.x509.X509V3CertificateGenerator; public class TSPTestUtil { public static SecureRandom rand = new SecureRandom(); public static KeyPairGenerator kpg; public static KeyGenerator desede128kg; public static KeyGenerator desede192kg; public static KeyGenerator rc240kg; public static KeyGenerator rc264kg; public static KeyGenerator rc2128kg; public static BigInteger serialNumber = BigInteger.ONE; public static final boolean DEBUG = true; public static DERObjectIdentifier EuroPKI_TSA_Test_Policy = new DERObjectIdentifier( "1.3.6.1.4.1.5255.5.1"); public static JcaX509ExtensionUtils extUtils; static { try { rand = new SecureRandom(); kpg = KeyPairGenerator.getInstance("RSA", "BC"); kpg.initialize(1024, rand); desede128kg = KeyGenerator.getInstance("DESEDE", "BC"); desede128kg.init(112, rand); desede192kg = KeyGenerator.getInstance("DESEDE", "BC"); desede192kg.init(168, rand); rc240kg = KeyGenerator.getInstance("RC2", "BC"); rc240kg.init(40, rand); rc264kg = KeyGenerator.getInstance("RC2", "BC"); rc264kg.init(64, rand); rc2128kg = KeyGenerator.getInstance("RC2", "BC"); rc2128kg.init(128, rand); serialNumber = new BigInteger("1"); extUtils = new JcaX509ExtensionUtils(); } catch (Exception ex) { throw new RuntimeException(ex.toString()); } } public static String dumpBase64(byte[] data) { StringBuffer buf = new StringBuffer(); data = Base64.encode(data); for (int i = 0; i < data.length; i += 64) { if (i + 64 < data.length) { buf.append(new String(data, i, 64)); } else { buf.append(new String(data, i, data.length - i)); } buf.append('\n'); } return buf.toString(); } public static KeyPair makeKeyPair() { return kpg.generateKeyPair(); } public static SecretKey makeDesede128Key() { return desede128kg.generateKey(); } public static SecretKey makeDesede192Key() { return desede192kg.generateKey(); } public static SecretKey makeRC240Key() { return rc240kg.generateKey(); } public static SecretKey makeRC264Key() { return rc264kg.generateKey(); } public static SecretKey makeRC2128Key() { return rc2128kg.generateKey(); } public static X509Certificate makeCertificate(KeyPair _subKP, String _subDN, KeyPair _issKP, String _issDN) throws GeneralSecurityException, IOException { return makeCertificate(_subKP, _subDN, _issKP, _issDN, false); } public static X509Certificate makeCACertificate(KeyPair _subKP, String _subDN, KeyPair _issKP, String _issDN) throws GeneralSecurityException, IOException { return makeCertificate(_subKP, _subDN, _issKP, _issDN, true); } public static X509Certificate makeCertificate(KeyPair _subKP, String _subDN, KeyPair _issKP, String _issDN, boolean _ca) throws GeneralSecurityException, IOException { PublicKey _subPub = _subKP.getPublic(); PrivateKey _issPriv = _issKP.getPrivate(); PublicKey _issPub = _issKP.getPublic(); X509V3CertificateGenerator _v3CertGen = new X509V3CertificateGenerator(); _v3CertGen.reset(); _v3CertGen.setSerialNumber(allocateSerialNumber()); _v3CertGen.setIssuerDN(new X509Name(_issDN)); _v3CertGen.setNotBefore(new Date(System.currentTimeMillis())); _v3CertGen.setNotAfter(new Date(System.currentTimeMillis() + (1000L * 60 * 60 * 24 * 100))); _v3CertGen.setSubjectDN(new X509Name(_subDN)); _v3CertGen.setPublicKey(_subPub); _v3CertGen.setSignatureAlgorithm("MD5WithRSAEncryption"); _v3CertGen.addExtension(Extension.subjectKeyIdentifier, false, createSubjectKeyId(_subPub)); _v3CertGen.addExtension(Extension.authorityKeyIdentifier, false, createAuthorityKeyId(_issPub)); if (_ca) { _v3CertGen.addExtension(Extension.basicConstraints, false, new BasicConstraints(_ca)); } else { _v3CertGen.addExtension(Extension.extendedKeyUsage, true, new ExtendedKeyUsage(KeyPurposeId.id_kp_timeStamping)); } X509Certificate _cert = _v3CertGen.generate(_issPriv); _cert.checkValidity(new Date()); _cert.verify(_issPub); return _cert; } /* * * INTERNAL METHODS * */ private static AuthorityKeyIdentifier createAuthorityKeyId(PublicKey _pubKey) throws IOException { return extUtils.createAuthorityKeyIdentifier(_pubKey); } private static SubjectKeyIdentifier createSubjectKeyId(PublicKey _pubKey) throws IOException { return extUtils.createSubjectKeyIdentifier(_pubKey); } private static BigInteger allocateSerialNumber() { BigInteger _tmp = serialNumber; serialNumber = serialNumber.add(BigInteger.ONE); return _tmp; } } bouncycastle-1.49.orig/test/src/org/bouncycastle/tsp/test/CMSTimeStampedDataTest.java0000644000175000017500000000501612151552117030324 0ustar ebourgebourgpackage org.bouncycastle.tsp.test; import java.io.ByteArrayOutputStream; import java.io.InputStream; import junit.framework.TestCase; import org.bouncycastle.operator.DigestCalculator; import org.bouncycastle.operator.DigestCalculatorProvider; import org.bouncycastle.operator.bc.BcDigestCalculatorProvider; import org.bouncycastle.tsp.TimeStampToken; import org.bouncycastle.tsp.cms.CMSTimeStampedData; public class CMSTimeStampedDataTest extends TestCase { CMSTimeStampedData cmsTimeStampedData = null; String fileInput = "FileDaFirmare.txt.tsd.der"; String fileOutput = fileInput.substring(0, fileInput.indexOf(".tsd")); private byte[] baseData; protected void setUp() throws Exception { ByteArrayOutputStream origStream = new ByteArrayOutputStream(); InputStream in = this.getClass().getResourceAsStream(fileInput); int ch; while ((ch = in.read()) >= 0) { origStream.write(ch); } origStream.close(); this.baseData = origStream.toByteArray(); cmsTimeStampedData = new CMSTimeStampedData(baseData); } protected void tearDown() throws Exception { cmsTimeStampedData = null; } public void testGetTimeStampTokens() throws Exception { TimeStampToken[] tokens = cmsTimeStampedData.getTimeStampTokens(); assertEquals(3, tokens.length); } public void testValidateAllTokens() throws Exception { DigestCalculatorProvider digestCalculatorProvider = new BcDigestCalculatorProvider(); DigestCalculator imprintCalculator = cmsTimeStampedData.getMessageImprintDigestCalculator(digestCalculatorProvider); imprintCalculator.getOutputStream().write(cmsTimeStampedData.getContent()); byte[] digest = imprintCalculator.getDigest(); TimeStampToken[] tokens = cmsTimeStampedData.getTimeStampTokens(); for (int i = 0; i < tokens.length; i++) { cmsTimeStampedData.validate(digestCalculatorProvider, digest, tokens[i]); } } public void testValidate() throws Exception { DigestCalculatorProvider digestCalculatorProvider = new BcDigestCalculatorProvider(); DigestCalculator imprintCalculator = cmsTimeStampedData.getMessageImprintDigestCalculator(digestCalculatorProvider); imprintCalculator.getOutputStream().write(cmsTimeStampedData.getContent()); cmsTimeStampedData.validate(digestCalculatorProvider, imprintCalculator.getDigest()); } } bouncycastle-1.49.orig/test/src/org/bouncycastle/tsp/test/CMSTimeStampedDataGeneratorTest.java0000644000175000017500000003037412151552117032200 0ustar ebourgebourgpackage org.bouncycastle.tsp.test; import java.io.ByteArrayInputStream; import java.io.ByteArrayOutputStream; import java.io.InputStream; import java.math.BigInteger; import java.security.KeyPair; import java.security.PrivateKey; import java.security.Security; import java.security.cert.X509Certificate; import java.util.ArrayList; import java.util.Date; import java.util.List; import junit.framework.TestCase; import org.bouncycastle.asn1.ASN1ObjectIdentifier; import org.bouncycastle.asn1.nist.NISTObjectIdentifiers; import org.bouncycastle.asn1.x509.AlgorithmIdentifier; import org.bouncycastle.cert.jcajce.JcaCertStore; import org.bouncycastle.cms.jcajce.JcaSimpleSignerInfoGeneratorBuilder; import org.bouncycastle.jce.provider.BouncyCastleProvider; import org.bouncycastle.operator.DigestCalculator; import org.bouncycastle.operator.DigestCalculatorProvider; import org.bouncycastle.operator.bc.BcDigestCalculatorProvider; import org.bouncycastle.tsp.TSPAlgorithms; import org.bouncycastle.tsp.TimeStampRequest; import org.bouncycastle.tsp.TimeStampRequestGenerator; import org.bouncycastle.tsp.TimeStampResponse; import org.bouncycastle.tsp.TimeStampResponseGenerator; import org.bouncycastle.tsp.TimeStampToken; import org.bouncycastle.tsp.TimeStampTokenGenerator; import org.bouncycastle.tsp.cms.CMSTimeStampedData; import org.bouncycastle.tsp.cms.CMSTimeStampedDataGenerator; import org.bouncycastle.tsp.cms.CMSTimeStampedDataParser; import org.bouncycastle.util.Arrays; import org.bouncycastle.util.Store; import org.bouncycastle.util.io.Streams; public class CMSTimeStampedDataGeneratorTest extends TestCase { BouncyCastleProvider bouncyCastleProvider; CMSTimeStampedDataGenerator cmsTimeStampedDataGenerator = null; String fileInput = "FileDaFirmare.data"; byte[] baseData; protected void setUp() throws Exception { bouncyCastleProvider = new BouncyCastleProvider(); if (Security.getProvider(bouncyCastleProvider.getName()) == null) { Security.addProvider(bouncyCastleProvider); } cmsTimeStampedDataGenerator = new CMSTimeStampedDataGenerator(); ByteArrayOutputStream origStream = new ByteArrayOutputStream(); InputStream in = this.getClass().getResourceAsStream(fileInput); int ch; while ((ch = in.read()) >= 0) { origStream.write(ch); } origStream.close(); this.baseData = origStream.toByteArray(); } protected void tearDown() throws Exception { cmsTimeStampedDataGenerator = null; Security.removeProvider(bouncyCastleProvider.getName()); } public void testGenerate() throws Exception { BcDigestCalculatorProvider calculatorProvider = new BcDigestCalculatorProvider(); String algOID = "2.16.840.1.101.3.4.2.1"; // SHA-256 DigestCalculator hashCalculator = calculatorProvider.get(new AlgorithmIdentifier(algOID)); cmsTimeStampedDataGenerator.initialiseMessageImprintDigestCalculator(hashCalculator); hashCalculator.getOutputStream().write(baseData); hashCalculator.getOutputStream().close(); TimeStampToken timeStampToken = createTimeStampToken(hashCalculator.getDigest(), NISTObjectIdentifiers.id_sha256); CMSTimeStampedData cmsTimeStampedData = cmsTimeStampedDataGenerator.generate(timeStampToken, baseData); for (int i = 0; i < 3; i++) { byte[] newRequestData = cmsTimeStampedData.calculateNextHash(hashCalculator); TimeStampToken newTimeStampToken = createTimeStampToken(newRequestData, NISTObjectIdentifiers.id_sha256); cmsTimeStampedData = cmsTimeStampedData.addTimeStamp(newTimeStampToken); } byte[] timeStampedData = cmsTimeStampedData.getEncoded(); // verify DigestCalculatorProvider newCalculatorProvider = new BcDigestCalculatorProvider(); DigestCalculator imprintCalculator = cmsTimeStampedData.getMessageImprintDigestCalculator(newCalculatorProvider); CMSTimeStampedData newCMSTimeStampedData = new CMSTimeStampedData(timeStampedData); byte[] newContent = newCMSTimeStampedData.getContent(); assertEquals("Content expected and verified are different", true, Arrays.areEqual(newContent, baseData)); imprintCalculator.getOutputStream().write(newContent); byte[] digest = imprintCalculator.getDigest(); TimeStampToken[] tokens = cmsTimeStampedData.getTimeStampTokens(); assertEquals("TimeStampToken expected and verified are different", 4, tokens.length); for (int i = 0; i < tokens.length; i++) { cmsTimeStampedData.validate(newCalculatorProvider, digest, tokens[i]); } } public void testGenerateWithMetadata() throws Exception { cmsTimeStampedDataGenerator.setMetaData(true, fileInput, "TXT"); BcDigestCalculatorProvider calculatorProvider = new BcDigestCalculatorProvider(); String algOID = "2.16.840.1.101.3.4.2.1"; // SHA-256 DigestCalculator hashCalculator = calculatorProvider.get(new AlgorithmIdentifier(algOID)); cmsTimeStampedDataGenerator.initialiseMessageImprintDigestCalculator(hashCalculator); hashCalculator.getOutputStream().write(baseData); hashCalculator.getOutputStream().close(); TimeStampToken timeStampToken = createTimeStampToken(hashCalculator.getDigest(), NISTObjectIdentifiers.id_sha256); CMSTimeStampedData cmsTimeStampedData = cmsTimeStampedDataGenerator.generate(timeStampToken, baseData); for (int i = 0; i < 3; i++) { byte[] newRequestData = cmsTimeStampedData.calculateNextHash(hashCalculator); TimeStampToken newTimeStampToken = createTimeStampToken(newRequestData, NISTObjectIdentifiers.id_sha256); cmsTimeStampedData = cmsTimeStampedData.addTimeStamp(newTimeStampToken); } byte[] timeStampedData = cmsTimeStampedData.getEncoded(); metadataCheck(timeStampedData); metadataParserCheck(timeStampedData); } public void testGenerateWithMetadataAndDifferentAlgorithmIdentifier() throws Exception { cmsTimeStampedDataGenerator.setMetaData(true, fileInput, "TXT"); BcDigestCalculatorProvider calculatorProvider = new BcDigestCalculatorProvider(); ASN1ObjectIdentifier algIdentifier = NISTObjectIdentifiers.id_sha224; DigestCalculator hashCalculator = calculatorProvider.get(new AlgorithmIdentifier(algIdentifier)); cmsTimeStampedDataGenerator.initialiseMessageImprintDigestCalculator(hashCalculator); hashCalculator.getOutputStream().write(baseData); hashCalculator.getOutputStream().close(); byte[] requestData = hashCalculator.getDigest(); TimeStampToken timeStampToken = createTimeStampToken(requestData, algIdentifier); CMSTimeStampedData cmsTimeStampedData = cmsTimeStampedDataGenerator.generate(timeStampToken, baseData); for (int i = 0; i < 3; i++) { switch (i) { case 0: algIdentifier = NISTObjectIdentifiers.id_sha224; break; case 1: algIdentifier = NISTObjectIdentifiers.id_sha256; break; case 2: algIdentifier = NISTObjectIdentifiers.id_sha384; break; case 3: algIdentifier = NISTObjectIdentifiers.id_sha512; break; } hashCalculator = calculatorProvider.get(new AlgorithmIdentifier(algIdentifier)); byte[] newRequestData = cmsTimeStampedData.calculateNextHash(hashCalculator); TimeStampToken newTimeStampToken = createTimeStampToken(newRequestData, algIdentifier); cmsTimeStampedData = cmsTimeStampedData.addTimeStamp(newTimeStampToken); } byte[] timeStampedData = cmsTimeStampedData.getEncoded(); metadataCheck(timeStampedData); metadataParserCheck(timeStampedData); } private void metadataCheck(byte[] timeStampedData) throws Exception { CMSTimeStampedData cmsTspData = new CMSTimeStampedData(timeStampedData); DigestCalculatorProvider newCalculatorProvider = new BcDigestCalculatorProvider(); DigestCalculator imprintCalculator = cmsTspData.getMessageImprintDigestCalculator(newCalculatorProvider); byte[] newContent = cmsTspData.getContent(); assertEquals("Content expected and verified are different", true, Arrays.areEqual(newContent, baseData)); imprintCalculator.getOutputStream().write(newContent); assertEquals(fileInput, cmsTspData.getFileName()); assertEquals("TXT", cmsTspData.getMediaType()); byte[] digest = imprintCalculator.getDigest(); TimeStampToken[] tokens = cmsTspData.getTimeStampTokens(); assertEquals("TimeStampToken expected and verified are different", 4, tokens.length); for (int i = 0; i < tokens.length; i++) { cmsTspData.validate(newCalculatorProvider, digest, tokens[i]); } } private void metadataParserCheck(byte[] timeStampedData) throws Exception { CMSTimeStampedDataParser cmsTspData = new CMSTimeStampedDataParser(timeStampedData); DigestCalculatorProvider newCalculatorProvider = new BcDigestCalculatorProvider(); InputStream input = cmsTspData.getContent(); ByteArrayOutputStream bOut = new ByteArrayOutputStream(); Streams.pipeAll(input, bOut); assertEquals("Content expected and verified are different", true, Arrays.areEqual(bOut.toByteArray(), baseData)); DigestCalculator imprintCalculator = cmsTspData.getMessageImprintDigestCalculator(newCalculatorProvider); Streams.pipeAll(new ByteArrayInputStream(bOut.toByteArray()), imprintCalculator.getOutputStream()); assertEquals(fileInput, cmsTspData.getFileName()); assertEquals("TXT", cmsTspData.getMediaType()); byte[] digest = imprintCalculator.getDigest(); TimeStampToken[] tokens = cmsTspData.getTimeStampTokens(); assertEquals("TimeStampToken expected and verified are different", 4, tokens.length); for (int i = 0; i < tokens.length; i++) { cmsTspData.validate(newCalculatorProvider, digest, tokens[i]); } } private TimeStampToken createTimeStampToken(byte[] hash, ASN1ObjectIdentifier hashAlg) throws Exception { String algorithmName = null; if (hashAlg.equals(NISTObjectIdentifiers.id_sha224)) { algorithmName = "SHA224withRSA"; } else if (hashAlg.equals(NISTObjectIdentifiers.id_sha256)) { algorithmName = "SHA256withRSA"; } else if (hashAlg.equals(NISTObjectIdentifiers.id_sha384)) { algorithmName = "SHA384withRSA"; } else if (hashAlg.equals(NISTObjectIdentifiers.id_sha512)) { algorithmName = "SHA512withRSA"; } String signDN = "O=Bouncy Castle, C=AU"; KeyPair signKP = TSPTestUtil.makeKeyPair(); X509Certificate signCert = TSPTestUtil.makeCACertificate(signKP, signDN, signKP, signDN); String origDN = "CN=Eric H. Echidna, E=eric@bouncycastle.org, O=Bouncy Castle, C=AU"; KeyPair origKP = TSPTestUtil.makeKeyPair(); X509Certificate cert = TSPTestUtil.makeCertificate(origKP, origDN, signKP, signDN); PrivateKey privateKey = origKP.getPrivate(); List certList = new ArrayList(); certList.add(cert); certList.add(signCert); Store certs = new JcaCertStore(certList); TimeStampTokenGenerator tsTokenGen = new TimeStampTokenGenerator( new JcaSimpleSignerInfoGeneratorBuilder().build(algorithmName, privateKey, cert), new ASN1ObjectIdentifier("1.2")); tsTokenGen.addCertificates(certs); TimeStampRequestGenerator reqGen = new TimeStampRequestGenerator(); TimeStampRequest request = reqGen.generate(hashAlg, hash); TimeStampResponseGenerator tsRespGen = new TimeStampResponseGenerator(tsTokenGen, TSPAlgorithms.ALLOWED); TimeStampResponse tsResp = tsRespGen.generate(request, new BigInteger("23"), new Date()); tsResp = new TimeStampResponse(tsResp.getEncoded()); return tsResp.getTimeStampToken(); } } bouncycastle-1.49.orig/test/src/org/bouncycastle/tsp/test/AllTests.java0000644000175000017500000000161111527063731025650 0ustar ebourgebourgpackage org.bouncycastle.tsp.test; import java.security.Security; import junit.framework.Test; import junit.framework.TestCase; import junit.framework.TestSuite; import org.bouncycastle.jce.provider.BouncyCastleProvider; public class AllTests extends TestCase { public static void main (String[] args) { junit.textui.TestRunner.run(suite()); } public static Test suite() { Security.addProvider(new BouncyCastleProvider()); TestSuite suite = new TestSuite("TSP Tests"); suite.addTestSuite(ParseTest.class); suite.addTestSuite(TSPTest.class); suite.addTestSuite(NewTSPTest.class); suite.addTestSuite(CMSTimeStampedDataTest.class); suite.addTestSuite(CMSTimeStampedDataParserTest.class); suite.addTestSuite(CMSTimeStampedDataGeneratorTest.class); return suite; } } bouncycastle-1.49.orig/test/src/org/bouncycastle/tsp/test/TSPTest.java0000644000175000017500000004764611724240404025436 0ustar ebourgebourgpackage org.bouncycastle.tsp.test; import java.math.BigInteger; import java.security.KeyPair; import java.security.PrivateKey; import java.security.cert.CertStore; import java.security.cert.CollectionCertStoreParameters; import java.security.cert.X509Certificate; import java.util.ArrayList; import java.util.Collection; import java.util.Date; import java.util.HashSet; import java.util.List; import junit.framework.TestCase; import org.bouncycastle.asn1.cmp.PKIFailureInfo; import org.bouncycastle.asn1.cms.AttributeTable; import org.bouncycastle.asn1.pkcs.PKCSObjectIdentifiers; import org.bouncycastle.tsp.GenTimeAccuracy; import org.bouncycastle.tsp.TSPAlgorithms; import org.bouncycastle.tsp.TSPValidationException; import org.bouncycastle.tsp.TimeStampRequest; import org.bouncycastle.tsp.TimeStampRequestGenerator; import org.bouncycastle.tsp.TimeStampResponse; import org.bouncycastle.tsp.TimeStampResponseGenerator; import org.bouncycastle.tsp.TimeStampToken; import org.bouncycastle.tsp.TimeStampTokenGenerator; import org.bouncycastle.tsp.TimeStampTokenInfo; import org.bouncycastle.util.Arrays; public class TSPTest extends TestCase { public void testGeneral() throws Exception { String signDN = "O=Bouncy Castle, C=AU"; KeyPair signKP = TSPTestUtil.makeKeyPair(); X509Certificate signCert = TSPTestUtil.makeCACertificate(signKP, signDN, signKP, signDN); String origDN = "CN=Eric H. Echidna, E=eric@bouncycastle.org, O=Bouncy Castle, C=AU"; KeyPair origKP = TSPTestUtil.makeKeyPair(); X509Certificate origCert = TSPTestUtil.makeCertificate(origKP, origDN, signKP, signDN); List certList = new ArrayList(); certList.add(origCert); certList.add(signCert); CertStore certs = CertStore.getInstance("Collection", new CollectionCertStoreParameters(certList), "BC"); basicTest(origKP.getPrivate(), origCert, certs); responseValidationTest(origKP.getPrivate(), origCert, certs); incorrectHashTest(origKP.getPrivate(), origCert, certs); badAlgorithmTest(origKP.getPrivate(), origCert, certs); timeNotAvailableTest(origKP.getPrivate(), origCert, certs); badPolicyTest(origKP.getPrivate(), origCert, certs); tokenEncodingTest(origKP.getPrivate(), origCert, certs); certReqTest(origKP.getPrivate(), origCert, certs); testAccuracyZeroCerts(origKP.getPrivate(), origCert, certs); testAccuracyWithCertsAndOrdering(origKP.getPrivate(), origCert, certs); testNoNonse(origKP.getPrivate(), origCert, certs); } private void basicTest( PrivateKey privateKey, X509Certificate cert, CertStore certs) throws Exception { TimeStampTokenGenerator tsTokenGen = new TimeStampTokenGenerator( privateKey, cert, TSPAlgorithms.SHA1, "1.2"); tsTokenGen.setCertificatesAndCRLs(certs); TimeStampRequestGenerator reqGen = new TimeStampRequestGenerator(); TimeStampRequest request = reqGen.generate(TSPAlgorithms.SHA1, new byte[20], BigInteger.valueOf(100)); TimeStampResponseGenerator tsRespGen = new TimeStampResponseGenerator(tsTokenGen, TSPAlgorithms.ALLOWED); TimeStampResponse tsResp = tsRespGen.generate(request, new BigInteger("23"), new Date(), "BC"); tsResp = new TimeStampResponse(tsResp.getEncoded()); TimeStampToken tsToken = tsResp.getTimeStampToken(); tsToken.validate(cert, "BC"); AttributeTable table = tsToken.getSignedAttributes(); assertNotNull("no signingCertificate attribute found", table.get(PKCSObjectIdentifiers.id_aa_signingCertificate)); } private void responseValidationTest( PrivateKey privateKey, X509Certificate cert, CertStore certs) throws Exception { TimeStampTokenGenerator tsTokenGen = new TimeStampTokenGenerator( privateKey, cert, TSPAlgorithms.MD5, "1.2"); tsTokenGen.setCertificatesAndCRLs(certs); TimeStampRequestGenerator reqGen = new TimeStampRequestGenerator(); TimeStampRequest request = reqGen.generate(TSPAlgorithms.SHA1, new byte[20], BigInteger.valueOf(100)); TimeStampResponseGenerator tsRespGen = new TimeStampResponseGenerator(tsTokenGen, TSPAlgorithms.ALLOWED); TimeStampResponse tsResp = tsRespGen.generate(request, new BigInteger("23"), new Date(), "BC"); tsResp = new TimeStampResponse(tsResp.getEncoded()); TimeStampToken tsToken = tsResp.getTimeStampToken(); tsToken.validate(cert, "BC"); // // check validation // tsResp.validate(request); try { request = reqGen.generate(TSPAlgorithms.SHA1, new byte[20], BigInteger.valueOf(101)); tsResp.validate(request); fail("response validation failed on invalid nonce."); } catch (TSPValidationException e) { // ignore } try { request = reqGen.generate(TSPAlgorithms.SHA1, new byte[22], BigInteger.valueOf(100)); tsResp.validate(request); fail("response validation failed on wrong digest."); } catch (TSPValidationException e) { // ignore } try { request = reqGen.generate(TSPAlgorithms.MD5, new byte[20], BigInteger.valueOf(100)); tsResp.validate(request); fail("response validation failed on wrong digest."); } catch (TSPValidationException e) { // ignore } } private void incorrectHashTest( PrivateKey privateKey, X509Certificate cert, CertStore certs) throws Exception { TimeStampTokenGenerator tsTokenGen = new TimeStampTokenGenerator( privateKey, cert, TSPAlgorithms.SHA1, "1.2"); tsTokenGen.setCertificatesAndCRLs(certs); TimeStampRequestGenerator reqGen = new TimeStampRequestGenerator(); TimeStampRequest request = reqGen.generate(TSPAlgorithms.SHA1, new byte[16]); TimeStampResponseGenerator tsRespGen = new TimeStampResponseGenerator(tsTokenGen, TSPAlgorithms.ALLOWED); TimeStampResponse tsResp = tsRespGen.generate(request, new BigInteger("23"), new Date(), "BC"); tsResp = new TimeStampResponse(tsResp.getEncoded()); TimeStampToken tsToken = tsResp.getTimeStampToken(); if (tsToken != null) { fail("incorrectHash - token not null."); } PKIFailureInfo failInfo = tsResp.getFailInfo(); if (failInfo == null) { fail("incorrectHash - failInfo set to null."); } if (failInfo.intValue() != PKIFailureInfo.badDataFormat) { fail("incorrectHash - wrong failure info returned."); } } private void badAlgorithmTest( PrivateKey privateKey, X509Certificate cert, CertStore certs) throws Exception { TimeStampTokenGenerator tsTokenGen = new TimeStampTokenGenerator( privateKey, cert, TSPAlgorithms.SHA1, "1.2"); tsTokenGen.setCertificatesAndCRLs(certs); TimeStampRequestGenerator reqGen = new TimeStampRequestGenerator(); TimeStampRequest request = reqGen.generate("1.2.3.4.5", new byte[20]); TimeStampResponseGenerator tsRespGen = new TimeStampResponseGenerator(tsTokenGen, TSPAlgorithms.ALLOWED); TimeStampResponse tsResp = tsRespGen.generate(request, new BigInteger("23"), new Date(), "BC"); tsResp = new TimeStampResponse(tsResp.getEncoded()); TimeStampToken tsToken = tsResp.getTimeStampToken(); if (tsToken != null) { fail("badAlgorithm - token not null."); } PKIFailureInfo failInfo = tsResp.getFailInfo(); if (failInfo == null) { fail("badAlgorithm - failInfo set to null."); } if (failInfo.intValue() != PKIFailureInfo.badAlg) { fail("badAlgorithm - wrong failure info returned."); } } private void timeNotAvailableTest( PrivateKey privateKey, X509Certificate cert, CertStore certs) throws Exception { TimeStampTokenGenerator tsTokenGen = new TimeStampTokenGenerator( privateKey, cert, TSPAlgorithms.SHA1, "1.2"); tsTokenGen.setCertificatesAndCRLs(certs); TimeStampRequestGenerator reqGen = new TimeStampRequestGenerator(); TimeStampRequest request = reqGen.generate("1.2.3.4.5", new byte[20]); TimeStampResponseGenerator tsRespGen = new TimeStampResponseGenerator(tsTokenGen, TSPAlgorithms.ALLOWED); TimeStampResponse tsResp = tsRespGen.generate(request, new BigInteger("23"), null, "BC"); tsResp = new TimeStampResponse(tsResp.getEncoded()); TimeStampToken tsToken = tsResp.getTimeStampToken(); if (tsToken != null) { fail("timeNotAvailable - token not null."); } PKIFailureInfo failInfo = tsResp.getFailInfo(); if (failInfo == null) { fail("timeNotAvailable - failInfo set to null."); } if (failInfo.intValue() != PKIFailureInfo.timeNotAvailable) { fail("timeNotAvailable - wrong failure info returned."); } } private void badPolicyTest( PrivateKey privateKey, X509Certificate cert, CertStore certs) throws Exception { TimeStampTokenGenerator tsTokenGen = new TimeStampTokenGenerator( privateKey, cert, TSPAlgorithms.SHA1, "1.2"); tsTokenGen.setCertificatesAndCRLs(certs); TimeStampRequestGenerator reqGen = new TimeStampRequestGenerator(); reqGen.setReqPolicy("1.1"); TimeStampRequest request = reqGen.generate(TSPAlgorithms.SHA1, new byte[20]); TimeStampResponseGenerator tsRespGen = new TimeStampResponseGenerator(tsTokenGen, TSPAlgorithms.ALLOWED, new HashSet()); TimeStampResponse tsResp = tsRespGen.generate(request, new BigInteger("23"), new Date(), "BC"); tsResp = new TimeStampResponse(tsResp.getEncoded()); TimeStampToken tsToken = tsResp.getTimeStampToken(); if (tsToken != null) { fail("badPolicy - token not null."); } PKIFailureInfo failInfo = tsResp.getFailInfo(); if (failInfo == null) { fail("badPolicy - failInfo set to null."); } if (failInfo.intValue() != PKIFailureInfo.unacceptedPolicy) { fail("badPolicy - wrong failure info returned."); } } private void certReqTest( PrivateKey privateKey, X509Certificate cert, CertStore certs) throws Exception { TimeStampTokenGenerator tsTokenGen = new TimeStampTokenGenerator( privateKey, cert, TSPAlgorithms.MD5, "1.2"); tsTokenGen.setCertificatesAndCRLs(certs); TimeStampRequestGenerator reqGen = new TimeStampRequestGenerator(); // // request with certReq false // reqGen.setCertReq(false); TimeStampRequest request = reqGen.generate(TSPAlgorithms.SHA1, new byte[20], BigInteger.valueOf(100)); TimeStampResponseGenerator tsRespGen = new TimeStampResponseGenerator(tsTokenGen, TSPAlgorithms.ALLOWED); TimeStampResponse tsResp = tsRespGen.generate(request, new BigInteger("23"), new Date(), "BC"); tsResp = new TimeStampResponse(tsResp.getEncoded()); TimeStampToken tsToken = tsResp.getTimeStampToken(); assertNull(tsToken.getTimeStampInfo().getGenTimeAccuracy()); // check for abscence of accuracy assertEquals("1.2", tsToken.getTimeStampInfo().getPolicy().getId()); try { tsToken.validate(cert, "BC"); } catch (TSPValidationException e) { fail("certReq(false) verification of token failed."); } CertStore respCerts = tsToken.getCertificatesAndCRLs("Collection", "BC"); Collection certsColl = respCerts.getCertificates(null); if (!certsColl.isEmpty()) { fail("certReq(false) found certificates in response."); } } private void tokenEncodingTest( PrivateKey privateKey, X509Certificate cert, CertStore certs) throws Exception { TimeStampTokenGenerator tsTokenGen = new TimeStampTokenGenerator( privateKey, cert, TSPAlgorithms.SHA1, "1.2.3.4.5.6"); tsTokenGen.setCertificatesAndCRLs(certs); TimeStampRequestGenerator reqGen = new TimeStampRequestGenerator(); TimeStampRequest request = reqGen.generate(TSPAlgorithms.SHA1, new byte[20], BigInteger.valueOf(100)); TimeStampResponseGenerator tsRespGen = new TimeStampResponseGenerator(tsTokenGen, TSPAlgorithms.ALLOWED); TimeStampResponse tsResp = tsRespGen.generate(request, new BigInteger("23"), new Date(), "BC"); tsResp = new TimeStampResponse(tsResp.getEncoded()); TimeStampResponse tsResponse = new TimeStampResponse(tsResp.getEncoded()); if (!Arrays.areEqual(tsResponse.getEncoded(), tsResp.getEncoded()) || !Arrays.areEqual(tsResponse.getTimeStampToken().getEncoded(), tsResp.getTimeStampToken().getEncoded())) { fail(); } } private void testAccuracyZeroCerts( PrivateKey privateKey, X509Certificate cert, CertStore certs) throws Exception { TimeStampTokenGenerator tsTokenGen = new TimeStampTokenGenerator( privateKey, cert, TSPAlgorithms.MD5, "1.2"); tsTokenGen.setCertificatesAndCRLs(certs); tsTokenGen.setAccuracySeconds(1); tsTokenGen.setAccuracyMillis(2); tsTokenGen.setAccuracyMicros(3); TimeStampRequestGenerator reqGen = new TimeStampRequestGenerator(); TimeStampRequest request = reqGen.generate(TSPAlgorithms.SHA1, new byte[20], BigInteger.valueOf(100)); TimeStampResponseGenerator tsRespGen = new TimeStampResponseGenerator(tsTokenGen, TSPAlgorithms.ALLOWED); TimeStampResponse tsResp = tsRespGen.generate(request, new BigInteger("23"), new Date(), "BC"); tsResp = new TimeStampResponse(tsResp.getEncoded()); TimeStampToken tsToken = tsResp.getTimeStampToken(); tsToken.validate(cert, "BC"); // // check validation // tsResp.validate(request); // // check tstInfo // TimeStampTokenInfo tstInfo = tsToken.getTimeStampInfo(); // // check accuracy // GenTimeAccuracy accuracy = tstInfo.getGenTimeAccuracy(); assertEquals(1, accuracy.getSeconds()); assertEquals(2, accuracy.getMillis()); assertEquals(3, accuracy.getMicros()); assertEquals(new BigInteger("23"), tstInfo.getSerialNumber()); assertEquals("1.2", tstInfo.getPolicy().getId()); // // test certReq // CertStore store = tsToken.getCertificatesAndCRLs("Collection", "BC"); Collection certificates = store.getCertificates(null); assertEquals(0, certificates.size()); } private void testAccuracyWithCertsAndOrdering( PrivateKey privateKey, X509Certificate cert, CertStore certs) throws Exception { TimeStampTokenGenerator tsTokenGen = new TimeStampTokenGenerator( privateKey, cert, TSPAlgorithms.MD5, "1.2.3"); tsTokenGen.setCertificatesAndCRLs(certs); tsTokenGen.setAccuracySeconds(3); tsTokenGen.setAccuracyMillis(1); tsTokenGen.setAccuracyMicros(2); tsTokenGen.setOrdering(true); TimeStampRequestGenerator reqGen = new TimeStampRequestGenerator(); reqGen.setCertReq(true); TimeStampRequest request = reqGen.generate(TSPAlgorithms.SHA1, new byte[20], BigInteger.valueOf(100)); assertTrue(request.getCertReq()); TimeStampResponseGenerator tsRespGen = new TimeStampResponseGenerator(tsTokenGen, TSPAlgorithms.ALLOWED); TimeStampResponse tsResp = tsRespGen.generate(request, new BigInteger("23"), new Date(), "BC"); tsResp = new TimeStampResponse(tsResp.getEncoded()); TimeStampToken tsToken = tsResp.getTimeStampToken(); tsToken.validate(cert, "BC"); // // check validation // tsResp.validate(request); // // check tstInfo // TimeStampTokenInfo tstInfo = tsToken.getTimeStampInfo(); // // check accuracy // GenTimeAccuracy accuracy = tstInfo.getGenTimeAccuracy(); assertEquals(3, accuracy.getSeconds()); assertEquals(1, accuracy.getMillis()); assertEquals(2, accuracy.getMicros()); assertEquals(new BigInteger("23"), tstInfo.getSerialNumber()); assertEquals("1.2.3", tstInfo.getPolicy().getId()); assertEquals(true, tstInfo.isOrdered()); assertEquals(tstInfo.getNonce(), BigInteger.valueOf(100)); // // test certReq // CertStore store = tsToken.getCertificatesAndCRLs("Collection", "BC"); Collection certificates = store.getCertificates(null); assertEquals(2, certificates.size()); } private void testNoNonse( PrivateKey privateKey, X509Certificate cert, CertStore certs) throws Exception { TimeStampTokenGenerator tsTokenGen = new TimeStampTokenGenerator( privateKey, cert, TSPAlgorithms.MD5, "1.2.3"); tsTokenGen.setCertificatesAndCRLs(certs); TimeStampRequestGenerator reqGen = new TimeStampRequestGenerator(); TimeStampRequest request = reqGen.generate(TSPAlgorithms.SHA1, new byte[20]); assertFalse(request.getCertReq()); TimeStampResponseGenerator tsRespGen = new TimeStampResponseGenerator(tsTokenGen, TSPAlgorithms.ALLOWED); TimeStampResponse tsResp = tsRespGen.generate(request, new BigInteger("24"), new Date(), "BC"); tsResp = new TimeStampResponse(tsResp.getEncoded()); TimeStampToken tsToken = tsResp.getTimeStampToken(); tsToken.validate(cert, "BC"); // // check validation // tsResp.validate(request); // // check tstInfo // TimeStampTokenInfo tstInfo = tsToken.getTimeStampInfo(); // // check accuracy // GenTimeAccuracy accuracy = tstInfo.getGenTimeAccuracy(); assertNull(accuracy); assertEquals(new BigInteger("24"), tstInfo.getSerialNumber()); assertEquals("1.2.3", tstInfo.getPolicy().getId()); assertEquals(false, tstInfo.isOrdered()); assertNull(tstInfo.getNonce()); // // test certReq // CertStore store = tsToken.getCertificatesAndCRLs("Collection", "BC"); Collection certificates = store.getCertificates(null); assertEquals(0, certificates.size()); } } bouncycastle-1.49.orig/test/src/org/bouncycastle/tsp/test/NewTSPTest.java0000644000175000017500000007667612132663446026126 0ustar ebourgebourgpackage org.bouncycastle.tsp.test; import java.io.OutputStream; import java.math.BigInteger; import java.security.KeyPair; import java.security.PrivateKey; import java.security.cert.X509Certificate; import java.util.ArrayList; import java.util.Collection; import java.util.Date; import java.util.HashSet; import java.util.List; import java.util.Map; import junit.framework.TestCase; import org.bouncycastle.asn1.ASN1ObjectIdentifier; import org.bouncycastle.asn1.cmp.PKIFailureInfo; import org.bouncycastle.asn1.cmp.PKIStatus; import org.bouncycastle.asn1.cms.AttributeTable; import org.bouncycastle.asn1.ess.ESSCertID; import org.bouncycastle.asn1.ess.ESSCertIDv2; import org.bouncycastle.asn1.ess.SigningCertificate; import org.bouncycastle.asn1.ess.SigningCertificateV2; import org.bouncycastle.asn1.pkcs.PKCSObjectIdentifiers; import org.bouncycastle.asn1.x500.X500Name; import org.bouncycastle.asn1.x509.GeneralName; import org.bouncycastle.asn1.x509.GeneralNames; import org.bouncycastle.asn1.x509.IssuerSerial; import org.bouncycastle.cert.X509CertificateHolder; import org.bouncycastle.cert.jcajce.JcaCertStore; import org.bouncycastle.cms.CMSAttributeTableGenerationException; import org.bouncycastle.cms.CMSAttributeTableGenerator; import org.bouncycastle.cms.DefaultSignedAttributeTableGenerator; import org.bouncycastle.cms.jcajce.JcaSignerInfoGeneratorBuilder; import org.bouncycastle.cms.jcajce.JcaSimpleSignerInfoGeneratorBuilder; import org.bouncycastle.cms.jcajce.JcaSimpleSignerInfoVerifierBuilder; import org.bouncycastle.jce.provider.BouncyCastleProvider; import org.bouncycastle.operator.DigestCalculator; import org.bouncycastle.operator.jcajce.JcaContentSignerBuilder; import org.bouncycastle.operator.jcajce.JcaDigestCalculatorProviderBuilder; import org.bouncycastle.tsp.GenTimeAccuracy; import org.bouncycastle.tsp.TSPAlgorithms; import org.bouncycastle.tsp.TSPException; import org.bouncycastle.tsp.TSPValidationException; import org.bouncycastle.tsp.TimeStampRequest; import org.bouncycastle.tsp.TimeStampRequestGenerator; import org.bouncycastle.tsp.TimeStampResponse; import org.bouncycastle.tsp.TimeStampResponseGenerator; import org.bouncycastle.tsp.TimeStampToken; import org.bouncycastle.tsp.TimeStampTokenGenerator; import org.bouncycastle.tsp.TimeStampTokenInfo; import org.bouncycastle.util.Arrays; import org.bouncycastle.util.Store; public class NewTSPTest extends TestCase { private static final String BC = BouncyCastleProvider.PROVIDER_NAME; public void testGeneral() throws Exception { String signDN = "O=Bouncy Castle, C=AU"; KeyPair signKP = TSPTestUtil.makeKeyPair(); X509Certificate signCert = TSPTestUtil.makeCACertificate(signKP, signDN, signKP, signDN); String origDN = "CN=Eric H. Echidna, E=eric@bouncycastle.org, O=Bouncy Castle, C=AU"; KeyPair origKP = TSPTestUtil.makeKeyPair(); X509Certificate origCert = TSPTestUtil.makeCertificate(origKP, origDN, signKP, signDN); List certList = new ArrayList(); certList.add(origCert); certList.add(signCert); Store certs = new JcaCertStore(certList); basicTest(origKP.getPrivate(), origCert, certs); basicSha256Test(origKP.getPrivate(), origCert, certs); basicTestWithTSA(origKP.getPrivate(), origCert, certs); overrideAttrsTest(origKP.getPrivate(), origCert, certs); responseValidationTest(origKP.getPrivate(), origCert, certs); incorrectHashTest(origKP.getPrivate(), origCert, certs); badAlgorithmTest(origKP.getPrivate(), origCert, certs); timeNotAvailableTest(origKP.getPrivate(), origCert, certs); badPolicyTest(origKP.getPrivate(), origCert, certs); tokenEncodingTest(origKP.getPrivate(), origCert, certs); certReqTest(origKP.getPrivate(), origCert, certs); testAccuracyZeroCerts(origKP.getPrivate(), origCert, certs); testAccuracyWithCertsAndOrdering(origKP.getPrivate(), origCert, certs); testNoNonse(origKP.getPrivate(), origCert, certs); } private void basicTest( PrivateKey privateKey, X509Certificate cert, Store certs) throws Exception { TimeStampTokenGenerator tsTokenGen = new TimeStampTokenGenerator( new JcaSimpleSignerInfoGeneratorBuilder().build("SHA1withRSA", privateKey, cert), new SHA1DigestCalculator(), new ASN1ObjectIdentifier("1.2")); tsTokenGen.addCertificates(certs); TimeStampRequestGenerator reqGen = new TimeStampRequestGenerator(); TimeStampRequest request = reqGen.generate(TSPAlgorithms.SHA1, new byte[20], BigInteger.valueOf(100)); TimeStampResponseGenerator tsRespGen = new TimeStampResponseGenerator(tsTokenGen, TSPAlgorithms.ALLOWED); TimeStampResponse tsResp = tsRespGen.generate(request, new BigInteger("23"), new Date()); tsResp = new TimeStampResponse(tsResp.getEncoded()); TimeStampToken tsToken = tsResp.getTimeStampToken(); tsToken.validate(new JcaSimpleSignerInfoVerifierBuilder().setProvider(BC).build(cert)); AttributeTable table = tsToken.getSignedAttributes(); assertNotNull("no signingCertificate attribute found", table.get(PKCSObjectIdentifiers.id_aa_signingCertificate)); } private void basicSha256Test( PrivateKey privateKey, X509Certificate cert, Store certs) throws Exception { TimeStampTokenGenerator tsTokenGen = new TimeStampTokenGenerator( new JcaSimpleSignerInfoGeneratorBuilder().build("SHA256withRSA", privateKey, cert), new SHA256DigestCalculator(), new ASN1ObjectIdentifier("1.2")); tsTokenGen.addCertificates(certs); TimeStampRequestGenerator reqGen = new TimeStampRequestGenerator(); TimeStampRequest request = reqGen.generate(TSPAlgorithms.SHA256, new byte[32], BigInteger.valueOf(100)); TimeStampResponseGenerator tsRespGen = new TimeStampResponseGenerator(tsTokenGen, TSPAlgorithms.ALLOWED); TimeStampResponse tsResp = tsRespGen.generate(request, new BigInteger("23"), new Date()); assertEquals(PKIStatus.GRANTED, tsResp.getStatus()); tsResp = new TimeStampResponse(tsResp.getEncoded()); TimeStampToken tsToken = tsResp.getTimeStampToken(); tsToken.validate(new JcaSimpleSignerInfoVerifierBuilder().setProvider(BC).build(cert)); AttributeTable table = tsToken.getSignedAttributes(); assertNotNull("no signingCertificate attribute found", table.get(PKCSObjectIdentifiers.id_aa_signingCertificateV2)); DigestCalculator digCalc = new SHA256DigestCalculator(); OutputStream dOut = digCalc.getOutputStream(); dOut.write(cert.getEncoded()); dOut.close(); byte[] certHash = digCalc.getDigest(); SigningCertificateV2 sigCertV2 = SigningCertificateV2.getInstance(table.get(PKCSObjectIdentifiers.id_aa_signingCertificateV2).getAttributeValues()[0]); assertTrue(Arrays.areEqual(certHash, sigCertV2.getCerts()[0].getCertHash())); } private void overrideAttrsTest( PrivateKey privateKey, X509Certificate cert, Store certs) throws Exception { JcaSimpleSignerInfoGeneratorBuilder signerInfoGenBuilder = new JcaSimpleSignerInfoGeneratorBuilder().setProvider("BC"); IssuerSerial issuerSerial = new IssuerSerial(new GeneralNames(new GeneralName(new X509CertificateHolder(cert.getEncoded()).getIssuer())), cert.getSerialNumber()); DigestCalculator digCalc = new SHA1DigestCalculator(); OutputStream dOut = digCalc.getOutputStream(); dOut.write(cert.getEncoded()); dOut.close(); byte[] certHash = digCalc.getDigest(); digCalc = new SHA256DigestCalculator(); dOut = digCalc.getOutputStream(); dOut.write(cert.getEncoded()); dOut.close(); byte[] certHash256 = digCalc.getDigest(); final ESSCertID essCertid = new ESSCertID(certHash, issuerSerial); final ESSCertIDv2 essCertidV2 = new ESSCertIDv2(certHash256, issuerSerial); signerInfoGenBuilder.setSignedAttributeGenerator(new CMSAttributeTableGenerator() { public AttributeTable getAttributes(Map parameters) throws CMSAttributeTableGenerationException { CMSAttributeTableGenerator attrGen = new DefaultSignedAttributeTableGenerator(); AttributeTable table = attrGen.getAttributes(parameters); table = table.add(PKCSObjectIdentifiers.id_aa_signingCertificate, new SigningCertificate(essCertid)); table = table.add(PKCSObjectIdentifiers.id_aa_signingCertificateV2, new SigningCertificateV2(new ESSCertIDv2[]{essCertidV2})); return table; } }); TimeStampTokenGenerator tsTokenGen = new TimeStampTokenGenerator(signerInfoGenBuilder.build("SHA1withRSA", privateKey, cert), new SHA1DigestCalculator(), new ASN1ObjectIdentifier("1.2")); tsTokenGen.addCertificates(certs); TimeStampRequestGenerator reqGen = new TimeStampRequestGenerator(); TimeStampRequest request = reqGen.generate(TSPAlgorithms.SHA1, new byte[20], BigInteger.valueOf(100)); TimeStampResponseGenerator tsRespGen = new TimeStampResponseGenerator(tsTokenGen, TSPAlgorithms.ALLOWED); TimeStampResponse tsResp = tsRespGen.generate(request, new BigInteger("23"), new Date()); tsResp = new TimeStampResponse(tsResp.getEncoded()); TimeStampToken tsToken = tsResp.getTimeStampToken(); tsToken.validate(new JcaSimpleSignerInfoVerifierBuilder().setProvider(BC).build(cert)); AttributeTable table = tsToken.getSignedAttributes(); assertNotNull("no signingCertificate attribute found", table.get(PKCSObjectIdentifiers.id_aa_signingCertificate)); assertNotNull("no signingCertificateV2 attribute found", table.get(PKCSObjectIdentifiers.id_aa_signingCertificateV2)); SigningCertificate sigCert = SigningCertificate.getInstance(table.get(PKCSObjectIdentifiers.id_aa_signingCertificate).getAttributeValues()[0]); assertEquals(new X509CertificateHolder(cert.getEncoded()).getIssuer(), sigCert.getCerts()[0].getIssuerSerial().getIssuer().getNames()[0].getName()); assertEquals(cert.getSerialNumber(), sigCert.getCerts()[0].getIssuerSerial().getSerial().getValue()); assertTrue(Arrays.areEqual(certHash, sigCert.getCerts()[0].getCertHash())); SigningCertificateV2 sigCertV2 = SigningCertificateV2.getInstance(table.get(PKCSObjectIdentifiers.id_aa_signingCertificateV2).getAttributeValues()[0]); assertEquals(new X509CertificateHolder(cert.getEncoded()).getIssuer(), sigCertV2.getCerts()[0].getIssuerSerial().getIssuer().getNames()[0].getName()); assertEquals(cert.getSerialNumber(), sigCertV2.getCerts()[0].getIssuerSerial().getSerial().getValue()); assertTrue(Arrays.areEqual(certHash256, sigCertV2.getCerts()[0].getCertHash())); } private void basicTestWithTSA( PrivateKey privateKey, X509Certificate cert, Store certs) throws Exception { TimeStampTokenGenerator tsTokenGen = new TimeStampTokenGenerator( new JcaSimpleSignerInfoGeneratorBuilder().build("SHA1withRSA", privateKey, cert), new SHA1DigestCalculator(), new ASN1ObjectIdentifier("1.2")); tsTokenGen.addCertificates(certs); tsTokenGen.setTSA(new GeneralName(new X500Name("CN=Test"))); TimeStampRequestGenerator reqGen = new TimeStampRequestGenerator(); TimeStampRequest request = reqGen.generate(TSPAlgorithms.SHA1, new byte[20], BigInteger.valueOf(100)); TimeStampResponseGenerator tsRespGen = new TimeStampResponseGenerator(tsTokenGen, TSPAlgorithms.ALLOWED); TimeStampResponse tsResp = tsRespGen.generate(request, new BigInteger("23"), new Date()); tsResp = new TimeStampResponse(tsResp.getEncoded()); TimeStampToken tsToken = tsResp.getTimeStampToken(); tsToken.validate(new JcaSimpleSignerInfoVerifierBuilder().setProvider(BC).build(cert)); AttributeTable table = tsToken.getSignedAttributes(); assertNotNull("no signingCertificate attribute found", table.get(PKCSObjectIdentifiers.id_aa_signingCertificate)); } private void responseValidationTest( PrivateKey privateKey, X509Certificate cert, Store certs) throws Exception { JcaSignerInfoGeneratorBuilder infoGeneratorBuilder = new JcaSignerInfoGeneratorBuilder(new JcaDigestCalculatorProviderBuilder().setProvider(BC).build()); TimeStampTokenGenerator tsTokenGen = new TimeStampTokenGenerator( infoGeneratorBuilder.build(new JcaContentSignerBuilder("MD5withRSA").setProvider(BC).build(privateKey), cert), new SHA1DigestCalculator(), new ASN1ObjectIdentifier("1.2")); tsTokenGen.addCertificates(certs); TimeStampRequestGenerator reqGen = new TimeStampRequestGenerator(); TimeStampRequest request = reqGen.generate(TSPAlgorithms.SHA1, new byte[20], BigInteger.valueOf(100)); TimeStampResponseGenerator tsRespGen = new TimeStampResponseGenerator(tsTokenGen, TSPAlgorithms.ALLOWED); TimeStampResponse tsResp = tsRespGen.generate(request, new BigInteger("23"), new Date()); tsResp = new TimeStampResponse(tsResp.getEncoded()); TimeStampToken tsToken = tsResp.getTimeStampToken(); tsToken.validate(new JcaSimpleSignerInfoVerifierBuilder().setProvider("BC").build(cert)); // // check validation // tsResp.validate(request); try { request = reqGen.generate(TSPAlgorithms.SHA1, new byte[20], BigInteger.valueOf(101)); tsResp.validate(request); fail("response validation failed on invalid nonce."); } catch (TSPValidationException e) { // ignore } try { request = reqGen.generate(TSPAlgorithms.SHA1, new byte[22], BigInteger.valueOf(100)); tsResp.validate(request); fail("response validation failed on wrong digest."); } catch (TSPValidationException e) { // ignore } try { request = reqGen.generate(TSPAlgorithms.MD5, new byte[20], BigInteger.valueOf(100)); tsResp.validate(request); fail("response validation failed on wrong digest."); } catch (TSPValidationException e) { // ignore } } private void incorrectHashTest( PrivateKey privateKey, X509Certificate cert, Store certs) throws Exception { JcaSignerInfoGeneratorBuilder infoGeneratorBuilder = new JcaSignerInfoGeneratorBuilder(new JcaDigestCalculatorProviderBuilder().setProvider(BC).build()); TimeStampTokenGenerator tsTokenGen = new TimeStampTokenGenerator(infoGeneratorBuilder.build(new JcaContentSignerBuilder("SHA1withRSA").setProvider(BC).build(privateKey), cert), new SHA1DigestCalculator(), new ASN1ObjectIdentifier("1.2")); tsTokenGen.addCertificates(certs); TimeStampRequestGenerator reqGen = new TimeStampRequestGenerator(); TimeStampRequest request = reqGen.generate(TSPAlgorithms.SHA1, new byte[16]); TimeStampResponseGenerator tsRespGen = new TimeStampResponseGenerator(tsTokenGen, TSPAlgorithms.ALLOWED); TimeStampResponse tsResp = tsRespGen.generate(request, new BigInteger("23"), new Date()); tsResp = new TimeStampResponse(tsResp.getEncoded()); TimeStampToken tsToken = tsResp.getTimeStampToken(); if (tsToken != null) { fail("incorrectHash - token not null."); } PKIFailureInfo failInfo = tsResp.getFailInfo(); if (failInfo == null) { fail("incorrectHash - failInfo set to null."); } if (failInfo.intValue() != PKIFailureInfo.badDataFormat) { fail("incorrectHash - wrong failure info returned."); } } private void badAlgorithmTest( PrivateKey privateKey, X509Certificate cert, Store certs) throws Exception { JcaSimpleSignerInfoGeneratorBuilder infoGeneratorBuilder = new JcaSimpleSignerInfoGeneratorBuilder().setProvider(BC); TimeStampTokenGenerator tsTokenGen = new TimeStampTokenGenerator(infoGeneratorBuilder.build("SHA1withRSA", privateKey, cert), new SHA1DigestCalculator(), new ASN1ObjectIdentifier("1.2")); tsTokenGen.addCertificates(certs); TimeStampRequestGenerator reqGen = new TimeStampRequestGenerator(); TimeStampRequest request = reqGen.generate(new ASN1ObjectIdentifier("1.2.3.4.5"), new byte[20]); TimeStampResponseGenerator tsRespGen = new TimeStampResponseGenerator(tsTokenGen, TSPAlgorithms.ALLOWED); TimeStampResponse tsResp = tsRespGen.generate(request, new BigInteger("23"), new Date()); tsResp = new TimeStampResponse(tsResp.getEncoded()); TimeStampToken tsToken = tsResp.getTimeStampToken(); if (tsToken != null) { fail("badAlgorithm - token not null."); } PKIFailureInfo failInfo = tsResp.getFailInfo(); if (failInfo == null) { fail("badAlgorithm - failInfo set to null."); } if (failInfo.intValue() != PKIFailureInfo.badAlg) { fail("badAlgorithm - wrong failure info returned."); } } private void timeNotAvailableTest( PrivateKey privateKey, X509Certificate cert, Store certs) throws Exception { JcaSignerInfoGeneratorBuilder infoGeneratorBuilder = new JcaSignerInfoGeneratorBuilder(new JcaDigestCalculatorProviderBuilder().setProvider(BC).build()); TimeStampTokenGenerator tsTokenGen = new TimeStampTokenGenerator(infoGeneratorBuilder.build(new JcaContentSignerBuilder("SHA1withRSA").setProvider(BC).build(privateKey), cert), new SHA1DigestCalculator(), new ASN1ObjectIdentifier("1.2")); tsTokenGen.addCertificates(certs); TimeStampRequestGenerator reqGen = new TimeStampRequestGenerator(); TimeStampRequest request = reqGen.generate(new ASN1ObjectIdentifier("1.2.3.4.5"), new byte[20]); TimeStampResponseGenerator tsRespGen = new TimeStampResponseGenerator(tsTokenGen, TSPAlgorithms.ALLOWED); TimeStampResponse tsResp; try { tsResp = tsRespGen.generateGrantedResponse(request, new BigInteger("23"), null); } catch (TSPException e) { tsResp = tsRespGen.generateRejectedResponse(e); } tsResp = new TimeStampResponse(tsResp.getEncoded()); TimeStampToken tsToken = tsResp.getTimeStampToken(); if (tsToken != null) { fail("timeNotAvailable - token not null."); } PKIFailureInfo failInfo = tsResp.getFailInfo(); if (failInfo == null) { fail("timeNotAvailable - failInfo set to null."); } if (failInfo.intValue() != PKIFailureInfo.timeNotAvailable) { fail("timeNotAvailable - wrong failure info returned."); } } private void badPolicyTest( PrivateKey privateKey, X509Certificate cert, Store certs) throws Exception { JcaSignerInfoGeneratorBuilder infoGeneratorBuilder = new JcaSignerInfoGeneratorBuilder(new JcaDigestCalculatorProviderBuilder().setProvider(BC).build()); TimeStampTokenGenerator tsTokenGen = new TimeStampTokenGenerator(infoGeneratorBuilder.build(new JcaContentSignerBuilder("SHA1withRSA").setProvider(BC).build(privateKey), cert), new SHA1DigestCalculator(), new ASN1ObjectIdentifier("1.2")); tsTokenGen.addCertificates(certs); TimeStampRequestGenerator reqGen = new TimeStampRequestGenerator(); reqGen.setReqPolicy(new ASN1ObjectIdentifier("1.1")); TimeStampRequest request = reqGen.generate(TSPAlgorithms.SHA1, new byte[20]); TimeStampResponseGenerator tsRespGen = new TimeStampResponseGenerator(tsTokenGen, TSPAlgorithms.ALLOWED, new HashSet()); TimeStampResponse tsResp; try { tsResp = tsRespGen.generateGrantedResponse(request, new BigInteger("23"), new Date()); } catch (TSPException e) { tsResp = tsRespGen.generateRejectedResponse(e); } tsResp = new TimeStampResponse(tsResp.getEncoded()); TimeStampToken tsToken = tsResp.getTimeStampToken(); if (tsToken != null) { fail("badPolicy - token not null."); } PKIFailureInfo failInfo = tsResp.getFailInfo(); if (failInfo == null) { fail("badPolicy - failInfo set to null."); } if (failInfo.intValue() != PKIFailureInfo.unacceptedPolicy) { fail("badPolicy - wrong failure info returned."); } } private void certReqTest( PrivateKey privateKey, X509Certificate cert, Store certs) throws Exception { JcaSignerInfoGeneratorBuilder infoGeneratorBuilder = new JcaSignerInfoGeneratorBuilder(new JcaDigestCalculatorProviderBuilder().setProvider(BC).build()); TimeStampTokenGenerator tsTokenGen = new TimeStampTokenGenerator(infoGeneratorBuilder.build(new JcaContentSignerBuilder("MD5withRSA").setProvider(BC).build(privateKey), cert), new SHA1DigestCalculator(), new ASN1ObjectIdentifier("1.2")); tsTokenGen.addCertificates(certs); TimeStampRequestGenerator reqGen = new TimeStampRequestGenerator(); // // request with certReq false // reqGen.setCertReq(false); TimeStampRequest request = reqGen.generate(TSPAlgorithms.SHA1, new byte[20], BigInteger.valueOf(100)); TimeStampResponseGenerator tsRespGen = new TimeStampResponseGenerator(tsTokenGen, TSPAlgorithms.ALLOWED); TimeStampResponse tsResp = tsRespGen.generateGrantedResponse(request, new BigInteger("23"), new Date()); tsResp = new TimeStampResponse(tsResp.getEncoded()); TimeStampToken tsToken = tsResp.getTimeStampToken(); assertNull(tsToken.getTimeStampInfo().getGenTimeAccuracy()); // check for abscence of accuracy assertEquals("1.2", tsToken.getTimeStampInfo().getPolicy().getId()); try { tsToken.validate(new JcaSimpleSignerInfoVerifierBuilder().setProvider(BC).build(cert)); } catch (TSPValidationException e) { fail("certReq(false) verification of token failed."); } Store respCerts = tsToken.getCertificates(); Collection certsColl = respCerts.getMatches(null); if (!certsColl.isEmpty()) { fail("certReq(false) found certificates in response."); } } private void tokenEncodingTest( PrivateKey privateKey, X509Certificate cert, Store certs) throws Exception { JcaSignerInfoGeneratorBuilder infoGeneratorBuilder = new JcaSignerInfoGeneratorBuilder(new JcaDigestCalculatorProviderBuilder().setProvider(BC).build()); TimeStampTokenGenerator tsTokenGen = new TimeStampTokenGenerator(infoGeneratorBuilder.build(new JcaContentSignerBuilder("SHA1withRSA").setProvider(BC).build(privateKey), cert), new SHA1DigestCalculator(), new ASN1ObjectIdentifier("1.2.3.4.5.6")); tsTokenGen.addCertificates(certs); TimeStampRequestGenerator reqGen = new TimeStampRequestGenerator(); TimeStampRequest request = reqGen.generate(TSPAlgorithms.SHA1, new byte[20], BigInteger.valueOf(100)); TimeStampResponseGenerator tsRespGen = new TimeStampResponseGenerator(tsTokenGen, TSPAlgorithms.ALLOWED); TimeStampResponse tsResp = tsRespGen.generate(request, new BigInteger("23"), new Date()); tsResp = new TimeStampResponse(tsResp.getEncoded()); TimeStampResponse tsResponse = new TimeStampResponse(tsResp.getEncoded()); if (!Arrays.areEqual(tsResponse.getEncoded(), tsResp.getEncoded()) || !Arrays.areEqual(tsResponse.getTimeStampToken().getEncoded(), tsResp.getTimeStampToken().getEncoded())) { fail(); } } private void testAccuracyZeroCerts( PrivateKey privateKey, X509Certificate cert, Store certs) throws Exception { JcaSignerInfoGeneratorBuilder infoGeneratorBuilder = new JcaSignerInfoGeneratorBuilder(new JcaDigestCalculatorProviderBuilder().setProvider(BC).build()); TimeStampTokenGenerator tsTokenGen = new TimeStampTokenGenerator(infoGeneratorBuilder.build(new JcaContentSignerBuilder("MD5withRSA").setProvider(BC).build(privateKey), cert), new SHA1DigestCalculator(), new ASN1ObjectIdentifier("1.2")); tsTokenGen.addCertificates(certs); tsTokenGen.setAccuracySeconds(1); tsTokenGen.setAccuracyMillis(2); tsTokenGen.setAccuracyMicros(3); TimeStampRequestGenerator reqGen = new TimeStampRequestGenerator(); TimeStampRequest request = reqGen.generate(TSPAlgorithms.SHA1, new byte[20], BigInteger.valueOf(100)); TimeStampResponseGenerator tsRespGen = new TimeStampResponseGenerator(tsTokenGen, TSPAlgorithms.ALLOWED); TimeStampResponse tsResp = tsRespGen.generate(request, new BigInteger("23"), new Date()); tsResp = new TimeStampResponse(tsResp.getEncoded()); TimeStampToken tsToken = tsResp.getTimeStampToken(); tsToken.validate(new JcaSimpleSignerInfoVerifierBuilder().setProvider("BC").build(cert)); // // check validation // tsResp.validate(request); // // check tstInfo // TimeStampTokenInfo tstInfo = tsToken.getTimeStampInfo(); // // check accuracy // GenTimeAccuracy accuracy = tstInfo.getGenTimeAccuracy(); assertEquals(1, accuracy.getSeconds()); assertEquals(2, accuracy.getMillis()); assertEquals(3, accuracy.getMicros()); assertEquals(new BigInteger("23"), tstInfo.getSerialNumber()); assertEquals("1.2", tstInfo.getPolicy().getId()); // // test certReq // Store store = tsToken.getCertificates(); Collection certificates = store.getMatches(null); assertEquals(0, certificates.size()); } private void testAccuracyWithCertsAndOrdering( PrivateKey privateKey, X509Certificate cert, Store certs) throws Exception { JcaSignerInfoGeneratorBuilder infoGeneratorBuilder = new JcaSignerInfoGeneratorBuilder(new JcaDigestCalculatorProviderBuilder().setProvider(BC).build()); TimeStampTokenGenerator tsTokenGen = new TimeStampTokenGenerator(infoGeneratorBuilder.build(new JcaContentSignerBuilder("MD5withRSA").setProvider(BC).build(privateKey), cert), new SHA1DigestCalculator(), new ASN1ObjectIdentifier("1.2.3")); tsTokenGen.addCertificates(certs); tsTokenGen.setAccuracySeconds(3); tsTokenGen.setAccuracyMillis(1); tsTokenGen.setAccuracyMicros(2); tsTokenGen.setOrdering(true); TimeStampRequestGenerator reqGen = new TimeStampRequestGenerator(); reqGen.setCertReq(true); TimeStampRequest request = reqGen.generate(TSPAlgorithms.SHA1, new byte[20], BigInteger.valueOf(100)); assertTrue(request.getCertReq()); TimeStampResponseGenerator tsRespGen = new TimeStampResponseGenerator(tsTokenGen, TSPAlgorithms.ALLOWED); TimeStampResponse tsResp; try { tsResp = tsRespGen.generateGrantedResponse(request, new BigInteger("23"), new Date()); } catch (TSPException e) { tsResp = tsRespGen.generateRejectedResponse(e); } tsResp = new TimeStampResponse(tsResp.getEncoded()); TimeStampToken tsToken = tsResp.getTimeStampToken(); tsToken.validate(cert, "BC"); // // check validation // tsResp.validate(request); // // check tstInfo // TimeStampTokenInfo tstInfo = tsToken.getTimeStampInfo(); // // check accuracy // GenTimeAccuracy accuracy = tstInfo.getGenTimeAccuracy(); assertEquals(3, accuracy.getSeconds()); assertEquals(1, accuracy.getMillis()); assertEquals(2, accuracy.getMicros()); assertEquals(new BigInteger("23"), tstInfo.getSerialNumber()); assertEquals("1.2.3", tstInfo.getPolicy().getId()); assertEquals(true, tstInfo.isOrdered()); assertEquals(tstInfo.getNonce(), BigInteger.valueOf(100)); // // test certReq // Store store = tsToken.getCertificates(); Collection certificates = store.getMatches(null); assertEquals(2, certificates.size()); } private void testNoNonse( PrivateKey privateKey, X509Certificate cert, Store certs) throws Exception { JcaSignerInfoGeneratorBuilder infoGeneratorBuilder = new JcaSignerInfoGeneratorBuilder(new JcaDigestCalculatorProviderBuilder().setProvider(BC).build()); TimeStampTokenGenerator tsTokenGen = new TimeStampTokenGenerator(infoGeneratorBuilder.build(new JcaContentSignerBuilder("MD5withRSA").setProvider(BC).build(privateKey), cert), new ASN1ObjectIdentifier("1.2.3")); tsTokenGen.addCertificates(certs); TimeStampRequestGenerator reqGen = new TimeStampRequestGenerator(); TimeStampRequest request = reqGen.generate(TSPAlgorithms.SHA1, new byte[20]); assertFalse(request.getCertReq()); TimeStampResponseGenerator tsRespGen = new TimeStampResponseGenerator(tsTokenGen, TSPAlgorithms.ALLOWED); TimeStampResponse tsResp = tsRespGen.generate(request, new BigInteger("24"), new Date()); tsResp = new TimeStampResponse(tsResp.getEncoded()); TimeStampToken tsToken = tsResp.getTimeStampToken(); tsToken.validate(cert, "BC"); // // check validation // tsResp.validate(request); // // check tstInfo // TimeStampTokenInfo tstInfo = tsToken.getTimeStampInfo(); // // check accuracy // GenTimeAccuracy accuracy = tstInfo.getGenTimeAccuracy(); assertNull(accuracy); assertEquals(new BigInteger("24"), tstInfo.getSerialNumber()); assertEquals("1.2.3", tstInfo.getPolicy().getId()); assertEquals(false, tstInfo.isOrdered()); assertNull(tstInfo.getNonce()); // // test certReq // Store store = tsToken.getCertificates(); Collection certificates = store.getMatches(null); assertEquals(0, certificates.size()); } } bouncycastle-1.49.orig/test/src/org/bouncycastle/tsp/test/ParseTest.java0000644000175000017500000005074511726265472026052 0ustar ebourgebourgpackage org.bouncycastle.tsp.test; import java.io.ByteArrayInputStream; import java.io.IOException; import java.security.cert.CertificateFactory; import java.security.cert.X509Certificate; import junit.framework.TestCase; import org.bouncycastle.asn1.ASN1ObjectIdentifier; import org.bouncycastle.asn1.cmp.PKIFailureInfo; import org.bouncycastle.asn1.cmp.PKIStatus; import org.bouncycastle.cert.X509CertificateHolder; import org.bouncycastle.cms.jcajce.JcaSimpleSignerInfoVerifierBuilder; import org.bouncycastle.tsp.TSPAlgorithms; import org.bouncycastle.tsp.TimeStampRequest; import org.bouncycastle.tsp.TimeStampResponse; import org.bouncycastle.util.Arrays; import org.bouncycastle.util.Store; import org.bouncycastle.util.encoders.Base64; /** * Test Cases */ public class ParseTest extends TestCase { private byte[] sha1Request = Base64.decode( "MDACAQEwITAJBgUrDgMCGgUABBT5UbEBmJssO3RxcQtOePxNvfoMpgIIC+Gv" + "YW2mtZQ="); private byte[] sha1noNonse = Base64.decode( "MCYCAQEwITAJBgUrDgMCGgUABBT5UbEBmJssO3RxcQtOePxNvfoMpg=="); private byte[] md5Request = Base64.decode( "MDoCAQEwIDAMBggqhkiG9w0CBQUABBDIl9FBCvjyx0+6EbHbUR6eBgkrBgEE" + "AakHBQECCDQluayIxIzn"); private byte[] ripemd160Request = Base64.decode( "MD8CAQEwITAJBgUrJAMCAQUABBSq03a/mk50Yd9lMF+BSqOp/RHGQQYJKwYB" + "BAGpBwUBAgkA4SZs9NfqISMBAf8="); private byte[] sha1Response = Base64.decode( "MIICbDADAgEAMIICYwYJKoZIhvcNAQcCoIICVDCCAlACAQMxCzAJBgUrDgMC" + "GgUAMIHaBgsqhkiG9w0BCRABBKCBygSBxzCBxAIBAQYEKgMEATAhMAkGBSsO" + "AwIaBQAEFPlRsQGYmyw7dHFxC054/E29+gymAgEEGA8yMDA0MTIwOTA3NTIw" + "NVowCgIBAYACAfSBAWQBAf8CCAvhr2FtprWUoGmkZzBlMRgwFgYDVQQDEw9F" + "cmljIEguIEVjaGlkbmExJDAiBgkqhkiG9w0BCQEWFWVyaWNAYm91bmN5Y2Fz" + "dGxlLm9yZzEWMBQGA1UEChMNQm91bmN5IENhc3RsZTELMAkGA1UEBhMCQVUx" + "ggFfMIIBWwIBATAqMCUxFjAUBgNVBAoTDUJvdW5jeSBDYXN0bGUxCzAJBgNV" + "BAYTAkFVAgECMAkGBSsOAwIaBQCggYwwGgYJKoZIhvcNAQkDMQ0GCyqGSIb3" + "DQEJEAEEMBwGCSqGSIb3DQEJBTEPFw0wNDEyMDkwNzUyMDVaMCMGCSqGSIb3" + "DQEJBDEWBBTGR1cbm94tWbcpDWrH+bD8UYePsTArBgsqhkiG9w0BCRACDDEc" + "MBowGDAWBBS37aLzFcheqeJ5cla0gjNWHGKbRzANBgkqhkiG9w0BAQEFAASB" + "gBrc9CJ3xlcTQuWQXJUqPEn6f6vfJAINKsn22z8LIfS/2p/CTFU6+W/bz8j8" + "j+8uWEJe8okTsI0FflljIsspqOPTB/RrnXteajbkuk/rLmz1B2g/qWBGAzPI" + "D214raBc1a7Bpd76PkvSSdjqrEaaskd+7JJiPr9l9yeSoh1AIt0N"); private byte[] sha1noNonseResponse = Base64.decode( "MIICYjADAgEAMIICWQYJKoZIhvcNAQcCoIICSjCCAkYCAQMxCzAJBgUrDgMC" + "GgUAMIHQBgsqhkiG9w0BCRABBKCBwASBvTCBugIBAQYEKgMEATAhMAkGBSsO" + "AwIaBQAEFPlRsQGYmyw7dHFxC054/E29+gymAgECGA8yMDA0MTIwOTA3MzQx" + "MlowCgIBAYACAfSBAWQBAf+gaaRnMGUxGDAWBgNVBAMTD0VyaWMgSC4gRWNo" + "aWRuYTEkMCIGCSqGSIb3DQEJARYVZXJpY0Bib3VuY3ljYXN0bGUub3JnMRYw" + "FAYDVQQKEw1Cb3VuY3kgQ2FzdGxlMQswCQYDVQQGEwJBVTGCAV8wggFbAgEB" + "MCowJTEWMBQGA1UEChMNQm91bmN5IENhc3RsZTELMAkGA1UEBhMCQVUCAQIw" + "CQYFKw4DAhoFAKCBjDAaBgkqhkiG9w0BCQMxDQYLKoZIhvcNAQkQAQQwHAYJ" + "KoZIhvcNAQkFMQ8XDTA0MTIwOTA3MzQxMlowIwYJKoZIhvcNAQkEMRYEFMNA" + "xlscHYiByHL9DIEh3FewIhgSMCsGCyqGSIb3DQEJEAIMMRwwGjAYMBYEFLft" + "ovMVyF6p4nlyVrSCM1YcYptHMA0GCSqGSIb3DQEBAQUABIGAaj46Tarrg7V7" + "z13bbetrGv+xy159eE8kmIW9nPegru3DuK/GmbMx9W3l0ydx0zdXRwYi6NZc" + "nNqbEZQZ2L1biJVTflgWq4Nxu4gPGjH/BGHKdH/LyW4eDcXZR39AkNBMnDAK" + "EmhhJo1/Tc+S/WkV9lnHJCPIn+TAijBUO6EiTik="); private byte[] md5Response = Base64.decode( "MIICcDADAgEAMIICZwYJKoZIhvcNAQcCoIICWDCCAlQCAQMxCzAJBgUrDgMC" + "GgUAMIHeBgsqhkiG9w0BCRABBKCBzgSByzCByAIBAQYJKwYBBAGpBwUBMCAw" + "DAYIKoZIhvcNAgUFAAQQyJfRQQr48sdPuhGx21EengIBAxgPMjAwNDEyMDkw" + "NzQ2MTZaMAoCAQGAAgH0gQFkAQH/Agg0JbmsiMSM56BppGcwZTEYMBYGA1UE" + "AxMPRXJpYyBILiBFY2hpZG5hMSQwIgYJKoZIhvcNAQkBFhVlcmljQGJvdW5j" + "eWNhc3RsZS5vcmcxFjAUBgNVBAoTDUJvdW5jeSBDYXN0bGUxCzAJBgNVBAYT" + "AkFVMYIBXzCCAVsCAQEwKjAlMRYwFAYDVQQKEw1Cb3VuY3kgQ2FzdGxlMQsw" + "CQYDVQQGEwJBVQIBAjAJBgUrDgMCGgUAoIGMMBoGCSqGSIb3DQEJAzENBgsq" + "hkiG9w0BCRABBDAcBgkqhkiG9w0BCQUxDxcNMDQxMjA5MDc0NjE2WjAjBgkq" + "hkiG9w0BCQQxFgQUFpRpaiRUUjiY7EbefbWLKDIY0XMwKwYLKoZIhvcNAQkQ" + "AgwxHDAaMBgwFgQUt+2i8xXIXqnieXJWtIIzVhxim0cwDQYJKoZIhvcNAQEB" + "BQAEgYBTwKsLLrQm+bvKV7Jwto/cMQh0KsVB5RoEeGn5CI9XyF2Bm+JRcvQL" + "Nm7SgSOBVt4A90TqujxirNeyQnXRiSnFvXd09Wet9WIQNpwpiGlE7lCrAhuq" + "/TAUe79VIpoQZDtyhbh0Vzxl24yRoechabC0zuPpOWOzrA4YC3Hv1J2tAA=="); private byte[] signingCert = Base64.decode( "MIICWjCCAcOgAwIBAgIBAjANBgkqhkiG9w0BAQQFADAlMRYwFAYDVQQKEw1Cb3Vu" + "Y3kgQ2FzdGxlMQswCQYDVQQGEwJBVTAeFw0wNDEyMDkwNzEzMTRaFw0wNTAzMTkw" + "NzEzMTRaMGUxGDAWBgNVBAMTD0VyaWMgSC4gRWNoaWRuYTEkMCIGCSqGSIb3DQEJ" + "ARYVZXJpY0Bib3VuY3ljYXN0bGUub3JnMRYwFAYDVQQKEw1Cb3VuY3kgQ2FzdGxl" + "MQswCQYDVQQGEwJBVTCBnzANBgkqhkiG9w0BAQEFAAOBjQAwgYkCgYEAqGAFO3dK" + "jB7Ca7u5Z3CabsbGr2Exg+3sztSPiRCIba03es4295EhtDF5bXQvrW2R1Bg72vED" + "5tWaQjVDetvDfCzVC3ErHLTVk3OgpLIP1gf2T0LcOH2pTh2LP9c5Ceta+uggK8zK" + "9sYUUnzGPSAZxrqHIIAlPIgqk0BMV+KApyECAwEAAaNaMFgwHQYDVR0OBBYEFO4F" + "YoqogtB9MjD0NB5x5HN3TrGUMB8GA1UdIwQYMBaAFPXAecuwLqNkCxYVLE/ngFQR" + "7RLIMBYGA1UdJQEB/wQMMAoGCCsGAQUFBwMIMA0GCSqGSIb3DQEBBAUAA4GBADGi" + "D5/qmGvcBgswEM/z2dF4lOxbTNKUW31ZHiU8CXlN0IkFtNbBLBTbJOQIAUnNEabL" + "T7aYgj813OZKUbJTx4MuGChhot/TEP7hKo/xz9OnXLsqYDKbqbo8iLOode+SI7II" + "+yYghOtqvx32cL2Qmffi1LaMbhJP+8NbsIxowdRC"); private byte[] unacceptablePolicy = Base64.decode( "MDAwLgIBAjAkDCJSZXF1ZXN0ZWQgcG9saWN5IGlzIG5vdCBzdXBwb3J0ZWQu" + "AwMAAAE="); private byte[] generalizedTime = Base64.decode( "MIIKPTADAgEAMIIKNAYJKoZIhvcNAQcCoIIKJTCCCiECAQMxCzAJBgUrDgMC" + "GgUAMIIBGwYLKoZIhvcNAQkQAQSgggEKBIIBBjCCAQICAQEGCisGAQQBhFkK" + "AwEwITAJBgUrDgMCGgUABBQAAAAAAAAAAAAAAAAAAAAAAAAAAAICUC8YEzIw" + "MDUwMzEwMTA1ODQzLjkzM1owBIACAfQBAf8CAWSggaikgaUwgaIxCzAJBgNV" + "BAYTAkdCMRcwFQYDVQQIEw5DYW1icmlkZ2VzaGlyZTESMBAGA1UEBxMJQ2Ft" + "YnJpZGdlMSQwIgYDVQQKExtuQ2lwaGVyIENvcnBvcmF0aW9uIExpbWl0ZWQx" + "JzAlBgNVBAsTHm5DaXBoZXIgRFNFIEVTTjozMjJBLUI1REQtNzI1QjEXMBUG" + "A1UEAxMOZGVtby1kc2UyMDAtMDGgggaFMIID2TCCA0KgAwIBAgICAIswDQYJ" + "KoZIhvcNAQEFBQAwgYwxCzAJBgNVBAYTAkdCMRcwFQYDVQQIEw5DYW1icmlk" + "Z2VzaGlyZTESMBAGA1UEBxMJQ2FtYnJpZGdlMSQwIgYDVQQKExtuQ2lwaGVy" + "IENvcnBvcmF0aW9uIExpbWl0ZWQxGDAWBgNVBAsTD1Byb2R1Y3Rpb24gVEVT" + "VDEQMA4GA1UEAxMHVEVTVCBDQTAeFw0wNDA2MTQxNDIzNTlaFw0wNTA2MTQx" + "NDIzNTlaMIGiMQswCQYDVQQGEwJHQjEXMBUGA1UECBMOQ2FtYnJpZGdlc2hp" + "cmUxEjAQBgNVBAcTCUNhbWJyaWRnZTEkMCIGA1UEChMbbkNpcGhlciBDb3Jw" + "b3JhdGlvbiBMaW1pdGVkMScwJQYDVQQLEx5uQ2lwaGVyIERTRSBFU046MzIy" + "QS1CNURELTcyNUIxFzAVBgNVBAMTDmRlbW8tZHNlMjAwLTAxMIGfMA0GCSqG" + "SIb3DQEBAQUAA4GNADCBiQKBgQC7zUamCeLIApddx1etW5YEFrL1WXnlCd7j" + "mMFI6RpSq056LBkF1z5LgucLY+e/c3u2Nw+XJuS3a2fKuBD7I1s/6IkVtIb/" + "KLDjjafOnottKhprH8K41siJUeuK3PRzfZ5kF0vwB3rNvWPCBJmp7kHtUQw3" + "RhIsJTYs7Wy8oVFHVwIDAQABo4IBMDCCASwwCQYDVR0TBAIwADAWBgNVHSUB" + "Af8EDDAKBggrBgEFBQcDCDAsBglghkgBhvhCAQ0EHxYdT3BlblNTTCBHZW5l" + "cmF0ZWQgQ2VydGlmaWNhdGUwHQYDVR0OBBYEFDlEe9Pd0WwQrtnEmFRI2Vmt" + "b+lCMIG5BgNVHSMEgbEwga6AFNy1VPweOQLC65bs6/0RcUYB19vJoYGSpIGP" + "MIGMMQswCQYDVQQGEwJHQjEXMBUGA1UECBMOQ2FtYnJpZGdlc2hpcmUxEjAQ" + "BgNVBAcTCUNhbWJyaWRnZTEkMCIGA1UEChMbbkNpcGhlciBDb3Jwb3JhdGlv" + "biBMaW1pdGVkMRgwFgYDVQQLEw9Qcm9kdWN0aW9uIFRFU1QxEDAOBgNVBAMT" + "B1RFU1QgQ0GCAQAwDQYJKoZIhvcNAQEFBQADgYEASEMlrpRE1RYZPxP3530e" + "hOYUDjgQbw0dwpPjQtLWkeJrePMzDBAbuWwpRI8dOzKP3Rnrm5rxJ7oLY2S0" + "A9ZfV+iwFKagEHFytfnPm2Y9AeNR7a3ladKd7NFMw+5Tbk7Asbetbb+NJfCl" + "9YzHwxLGiQbpKxgc+zYOjq74eGLKtcKhggKkMIICDQIBATCB0qGBqKSBpTCB" + "ojELMAkGA1UEBhMCR0IxFzAVBgNVBAgTDkNhbWJyaWRnZXNoaXJlMRIwEAYD" + "VQQHEwlDYW1icmlkZ2UxJDAiBgNVBAoTG25DaXBoZXIgQ29ycG9yYXRpb24g" + "TGltaXRlZDEnMCUGA1UECxMebkNpcGhlciBEU0UgRVNOOjMyMkEtQjVERC03" + "MjVCMRcwFQYDVQQDEw5kZW1vLWRzZTIwMC0wMaIlCgEBMAkGBSsOAwIaBQAD" + "FQDaLe88TQvM+iMKmIXMmDSyPCZ/+KBmMGSkYjBgMQswCQYDVQQGEwJVUzEk" + "MCIGA1UEChMbbkNpcGhlciBDb3Jwb3JhdGlvbiBMaW1pdGVkMRgwFgYDVQQL" + "Ew9Qcm9kdWN0aW9uIFRlc3QxETAPBgNVBAMTCFRlc3QgVE1DMA0GCSqGSIb3" + "DQEBBQUAAgjF2jVbAAAAADAiGA8yMDA1MDMxMDAyNTQxOVoYDzIwMDUwMzEz" + "MDI1NDE5WjCBjTBLBgorBgEEAYRZCgQBMT0wOzAMAgTF2jVbAgQAAAAAMA8C" + "BAAAAAACBAAAaLkCAf8wDAIEAAAAAAIEAAKV/DAMAgTF3inbAgQAAAAAMD4G" + "CisGAQQBhFkKBAIxMDAuMAwGCisGAQQBhFkKAwGgDjAMAgQAAAAAAgQAB6Eg" + "oQ4wDAIEAAAAAAIEAAPQkDANBgkqhkiG9w0BAQUFAAOBgQB1q4d3GNWk7oAT" + "WkpYmZaTFvapMhTwAmAtSGgFmNOZhs21iHWl/X990/HEBsduwxohfrd8Pz64" + "hV/a76rpeJCVUfUNmbRIrsurFx6uKwe2HUHKW8grZWeCD1L8Y1pKQdrD41gu" + "v0msfOXzLWW+xe5BcJguKclN8HmT7s2odtgiMTGCAmUwggJhAgEBMIGTMIGM" + "MQswCQYDVQQGEwJHQjEXMBUGA1UECBMOQ2FtYnJpZGdlc2hpcmUxEjAQBgNV" + "BAcTCUNhbWJyaWRnZTEkMCIGA1UEChMbbkNpcGhlciBDb3Jwb3JhdGlvbiBM" + "aW1pdGVkMRgwFgYDVQQLEw9Qcm9kdWN0aW9uIFRFU1QxEDAOBgNVBAMTB1RF" + "U1QgQ0ECAgCLMAkGBSsOAwIaBQCgggEnMBoGCSqGSIb3DQEJAzENBgsqhkiG" + "9w0BCRABBDAjBgkqhkiG9w0BCQQxFgQUi1iYx5H3ACnvngWZTPfdxGswkSkw" + "geMGCyqGSIb3DQEJEAIMMYHTMIHQMIHNMIGyBBTaLe88TQvM+iMKmIXMmDSy" + "PCZ/+DCBmTCBkqSBjzCBjDELMAkGA1UEBhMCR0IxFzAVBgNVBAgTDkNhbWJy" + "aWRnZXNoaXJlMRIwEAYDVQQHEwlDYW1icmlkZ2UxJDAiBgNVBAoTG25DaXBo" + "ZXIgQ29ycG9yYXRpb24gTGltaXRlZDEYMBYGA1UECxMPUHJvZHVjdGlvbiBU" + "RVNUMRAwDgYDVQQDEwdURVNUIENBAgIAizAWBBSpS/lH6bN/wf3E2z2X29vF" + "2U7YHTANBgkqhkiG9w0BAQUFAASBgGvDVsgsG5I5WKjEDVHvdRwUx+8Cp10l" + "zGF8o1h7aK5O3zQ4jLayYHea54E5+df35gG7Z3eoOy8E350J7BvHiwDLTqe8" + "SoRlGs9VhL6LMmCcERfGSlSn61Aa15iXZ8eHMSc5JTeJl+kqy4I3FPP4m2ai" + "8wy2fQhn7hUM8Ntg7Y2s"); private byte[] v2SigningCertResponse = Base64.decode( "MIIPPTADAgEAMIIPNAYJKoZIhvcNAQcCoIIPJTCCDyECAQMxDzANBglghkgBZQMEAgEFADCB6QYL" + "KoZIhvcNAQkQAQSggdkEgdYwgdMCAQEGBgQAj2cBATAxMA0GCWCGSAFlAwQCAQUABCBcU0GN08TA" + "LUFi7AAwQwVkSXqGu9tAzvJ7EXW7SMXHHQIRAM7Fa7g6tMvZI3dgllwMfpcYDzIwMDcxMjExMTAy" + "MTU5WjADAgEBAgYBFsi5OlmgYqRgMF4xCzAJBgNVBAYTAkRFMSQwIgYDVQQKDBtEZXV0c2NoZSBS" + "ZW50ZW52ZXJzaWNoZXJ1bmcxEzARBgNVBAsMClFDIFJvb3QgQ0ExFDASBgNVBAMMC1FDIFJvb3Qg" + "VFNQoIILQjCCBwkwggXxoAMCAQICAwN1pjANBgkqhkiG9w0BAQsFADBIMQswCQYDVQQGEwJERTEk" + "MCIGA1UECgwbRGV1dHNjaGUgUmVudGVudmVyc2ljaGVydW5nMRMwEQYDVQQLDApRQyBSb290IENB" + "MB4XDTA3MTEyMDE2MDcyMFoXDTEyMDcyNzIwMjExMVowXjELMAkGA1UEBhMCREUxJDAiBgNVBAoM" + "G0RldXRzY2hlIFJlbnRlbnZlcnNpY2hlcnVuZzETMBEGA1UECwwKUUMgUm9vdCBDQTEUMBIGA1UE" + "AwwLUUMgUm9vdCBUU1AwggEkMA0GCSqGSIb3DQEBAQUAA4IBEQAwggEMAoIBAQCv1vO+EtGnJNs0" + "atv76BAJXs4bmO8yzVwe3RUtgeu5z9iefh8P46i1g3EL2CD15NcTfoHksr5KudNY30olfjHG7lIu" + "MO3R5sAcrGDPP7riZJnaI6VD/e6kVR569VBid5z105fJAB7mID7+Bn7pdRwDW3Fy2CzfofXGuvrO" + "GPNEWq8x8kqqf75DB5nAs5QP8H41obkdkap2ttHkkPZCiMghTs8iHfpJ0STn47MKq+QrUmuATMZi" + "XrdEfb7f3TBMjO0UVJF64Mh+kC9GtUEHlcm0Tq2Pk5XIUxWEyL94rZ4UWcVdSVE7IjggV2MifMNx" + "geZO3SwsDZk71AhDBy30CSzBAgUAx3HB5aOCA+IwggPeMBYGA1UdJQEB/wQMMAoGCCsGAQUFBwMI" + "MBMGA1UdIwQMMAqACECefuBmflfeMBgGCCsGAQUFBwEDBAwwCjAIBgYEAI5GAQEwUAYIKwYBBQUH" + "AQEERDBCMEAGCCsGAQUFBzABhjRodHRwOi8vb2NzcC1yb290cWMudGMuZGV1dHNjaGUtcmVudGVu" + "dmVyc2ljaGVydW5nLmRlMHcGA1UdIARwMG4wbAYNKwYBBAGBrTwBCAEBAzBbMFkGCCsGAQUFBwIB" + "Fk1odHRwOi8vd3d3LmRldXRzY2hlLXJlbnRlbnZlcnNpY2hlcnVuZy1idW5kLmRlL3N0YXRpYy90" + "cnVzdGNlbnRlci9wb2xpY3kuaHRtbDCCATwGA1UdHwSCATMwggEvMHygeqB4hnZsZGFwOi8vZGly" + "LnRjLmRldXRzY2hlLXJlbnRlbnZlcnNpY2hlcnVuZy5kZS9vdT1RQyUyMFJvb3QlMjBDQSxjbj1Q" + "dWJsaWMsbz1EUlYsYz1ERT9hdHRybmFtZT1jZXJ0aWZpY2F0ZVJldm9jYXRpb25MaXN0MIGuoIGr" + "oIGohoGlaHR0cDovL2Rpci50Yy5kZXV0c2NoZS1yZW50ZW52ZXJzaWNoZXJ1bmcuZGU6ODA4OS9z" + "ZXJ2bGV0L0Rpclh3ZWIvQ2EveC5jcmw/ZG49b3UlM0RRQyUyMFJvb3QlMjBDQSUyQ2NuJTNEUHVi" + "bGljJTJDbyUzRERSViUyQ2MlM0RERSZhdHRybmFtZT1jZXJ0aWZpY2F0ZVJldm9jYXRpb25MaXN0" + "MIIBLQYDVR0SBIIBJDCCASCGdGxkYXA6Ly9kaXIudGMuZGV1dHNjaGUtcmVudGVudmVyc2ljaGVy" + "dW5nLmRlL2NuPTE0NTUxOCxvdT1RQyUyMFJvb3QlMjBDQSxjbj1QdWJsaWMsbz1EUlYsYz1ERT9h" + "dHRybmFtZT1jQUNlcnRpZmljYXRlhoGnaHR0cDovL2Rpci50Yy5kZXV0c2NoZS1yZW50ZW52ZXJz" + "aWNoZXJ1bmcuZGU6ODA4OS9zZXJ2bGV0L0Rpclh3ZWIvQ2EveC5jZXI/ZG49Y24lM0QxNDU1MTgl" + "MkNvdSUzRFFDJTIwUm9vdCUyMENBJTJDY24lM0RQdWJsaWMlMkNvJTNERFJWJTJDYyUzRERFJmF0" + "dHJuYW1lPWNBQ2VydGlmaWNhdGUwDgYDVR0PAQH/BAQDAgZAMDsGA1UdCQQ0MDIwMAYDVQQDMSkT" + "J1FDIFRTUCBEZXV0c2NoZSBSZW50ZW52ZXJzaWNoZXJ1bmcgMTpQTjAMBgNVHRMBAf8EAjAAMA0G" + "CSqGSIb3DQEBCwUAA4IBAQCCrWe3Pd3ioX7d8phXvVAa859Rvgf0k3pZ6R4GMj8h/k6MNjNIrdAs" + "wgUVkBbXMLLBk0smsvTdFIVtTBdp1urb9l7vXjDA4MckXBOXPcz4fN8Oswk92d+fM9XU1jKVPsFG" + "PV6j8lAqfq5jwaRxOnS96UBGLKG+NdcrEyiMp/ZkpqnEQZZfu2mkeq6CPahnbBTZqsE0jgY351gU" + "9T6SFVvLIFH7cOxJqsoxPqv5YEcgiXPpOyyu2rpQqKYBYcnerF6/zx5hmWHxTd7MWaTHm0gJI/Im" + "d8esbW+xyaJuAVUcBA+sDmSe8AAoRVxwBRY+xi9ApaJHpmwT+0n2K2GsL3wIMIIEMTCCAxmgAwIB" + "AgIDAjhuMA0GCSqGSIb3DQEBCwUAMEgxCzAJBgNVBAYTAkRFMSQwIgYDVQQKDBtEZXV0c2NoZSBS" + "ZW50ZW52ZXJzaWNoZXJ1bmcxEzARBgNVBAsMClFDIFJvb3QgQ0EwHhcNMDcwNzI3MjAyMTExWhcN" + "MTIwNzI3MjAyMTExWjBIMQswCQYDVQQGEwJERTEkMCIGA1UECgwbRGV1dHNjaGUgUmVudGVudmVy" + "c2ljaGVydW5nMRMwEQYDVQQLDApRQyBSb290IENBMIIBJDANBgkqhkiG9w0BAQEFAAOCAREAMIIB" + "DAKCAQEAzuhBdo9c84DdzsggjWOgfC4jJ2jYqpsOpBo3DVyem+5R26QK4feZdyFnaGvyG+TLcdLO" + "iCecGmrRGD+ey4IhjCONb7hsQQhJWTyDEtBblzYB0yjY8+9fnNeR61W+M/KlMgC6Rw/w+zwzklTM" + "MWwIbxLHm8l9jTSKFjAWTwjE8bCzpUCwN8+4JbFTwjwOJ5lsVA5Xa34wpgr6lgL3WrVTV1NSprqR" + "ZYDWg477tht0KkyOJt3guF3RONKBBuTO2qCbpUeI8m4v3tznoopYbV5Gp5wu5gqd6lTfgju3ldql" + "bxtuCLZd0nAI5rLEOPItDKl4vPXllmmtGIrtDZlwr86cbwIFAJvMJpGjggEgMIIBHDAPBgNVHRMB" + "Af8EBTADAQH/MBEGA1UdDgQKBAhAnn7gZn5X3jB3BgNVHSAEcDBuMGwGDSsGAQQBga08AQgBAQEw" + "WzBZBggrBgEFBQcCARZNaHR0cDovL3d3dy5kZXV0c2NoZS1yZW50ZW52ZXJzaWNoZXJ1bmctYnVu" + "ZC5kZS9zdGF0aWMvdHJ1c3RjZW50ZXIvcG9saWN5Lmh0bWwwUwYDVR0JBEwwSjBIBgNVBAMxQRM/" + "UUMgV3VyemVsemVydGlmaXppZXJ1bmdzc3RlbGxlIERldXRzY2hlIFJlbnRlbnZlcnNpY2hlcnVu" + "ZyAxOlBOMBgGCCsGAQUFBwEDBAwwCjAIBgYEAI5GAQEwDgYDVR0PAQH/BAQDAgIEMA0GCSqGSIb3" + "DQEBCwUAA4IBAQBNGs7Dnc1yzzpZrkuC+oLv+NhbORTEYNgpaOetB1JQ1EbUBoPuNN4ih0ngy/uJ" + "D2O+h4JsNkmELgaehLWyFwATqCYZY4cTAGVoEwgn93x3aW8JbMDQf+YEJDSDsXcm4oIDFPqv5M6o" + "HZUWfsPka3mxKivfKtWhooTz1/+BEGReVQ2oOAvlwXlkEab9e3GOqXQUcLPYDTl8BQxiYhtQtf3d" + "kORiUkuGiGX1YJ5JnZnG3ElMjPgOl8rOiYU7oj9uv1HVb5sdAwuVw0BR/eiMVDBT8DNyfoJmPeQQ" + "A9pXtoAYO0Ya7wNNmCY2Y63YfBlRCF+9VQv2RZ4TdO1KGWwxR98OMYIC1zCCAtMCAQEwTzBIMQsw" + "CQYDVQQGEwJERTEkMCIGA1UECgwbRGV1dHNjaGUgUmVudGVudmVyc2ljaGVydW5nMRMwEQYDVQQL" + "DApRQyBSb290IENBAgMDdaYwDQYJYIZIAWUDBAIBBQCgggFZMBoGCSqGSIb3DQEJAzENBgsqhkiG" + "9w0BCRABBDAvBgkqhkiG9w0BCQQxIgQgO7FFODWWwF5RUjo6wjIkgkD5u7dH+NICiCpSgRRqd/Aw" + "ggEIBgsqhkiG9w0BCRACLzGB+DCB9TCB8jB3BCAMMZqK/5pZxOb3ruCbcgxStaTDwDHaf2glEo6P" + "+89t8TBTMEykSjBIMQswCQYDVQQGEwJERTEkMCIGA1UECgwbRGV1dHNjaGUgUmVudGVudmVyc2lj" + "aGVydW5nMRMwEQYDVQQLDApRQyBSb290IENBAgMDdaYwdwQgl7vwI+P47kpxhWLoIdEco7UfGwZ2" + "X4el3jaZ67q5/9IwUzBMpEowSDELMAkGA1UEBhMCREUxJDAiBgNVBAoMG0RldXRzY2hlIFJlbnRl" + "bnZlcnNpY2hlcnVuZzETMBEGA1UECwwKUUMgUm9vdCBDQQIDAjhuMA0GCSqGSIb3DQEBCwUABIIB" + "AIOYgpDI0BaeG4RF/EB5QzkUqAZ9nX6w895+m2hHyRKrAKdj3913j5QI+aEVIG3DVbFaAfdKeKfn" + "xsTW48aWs6aARtPAc+1OXwoGUSYElOFqqVpSeTaXe+kjY5bsLSQeETB+EPvXl8EcKTaxTRCNOqJU" + "XbnyYRgWTI55A2jH6IsQQVHc5DaIcmbdI8iATaRTHY5eUeVuI+Q/3RMVBFAb5qRhM61Ddcrjq058" + "C0uiH9G2IB5QRyu6RsCUgrkeMTMBqlIBlnDBy+EgLouDU4Dehxy5uzEl5DBKZEewZpQZOTO/kAgL" + "WruAAg/Lj4r0f9vN12wRlHoS2UKDjrE1DnUBbrM="); /* (non-Javadoc) * @see org.bouncycastle.util.test.Test#getName() */ public String getName() { return "ParseTest"; } private void requestParse( byte[] request, ASN1ObjectIdentifier algorithm) throws IOException { TimeStampRequest req = new TimeStampRequest(request); if (!req.getMessageImprintAlgOID().equals(algorithm)) { fail("failed to get expected algorithm - got " + req.getMessageImprintAlgOID() + " not " + algorithm); } if (request != sha1Request && request != sha1noNonse) { if (!req.getReqPolicy().equals(TSPTestUtil.EuroPKI_TSA_Test_Policy)) { fail("" + algorithm + " failed policy check."); } if (request == ripemd160Request) { if (!req.getCertReq()) { fail("" + algorithm + " failed certReq check."); } } } assertEquals("version not 1", 1, req.getVersion()); assertEquals("critical extensions found when none expected", 0, req.getCriticalExtensionOIDs().size()); assertEquals("non-critical extensions found when none expected", 0, req.getNonCriticalExtensionOIDs().size()); if (request != sha1noNonse) { if (req.getNonce() == null) { fail("" + algorithm + " nonse not found when one expected."); } } else { if (req.getNonce() != null) { fail("" + algorithm + " nonse not found when one not expected."); } } try { req.validate(TSPAlgorithms.ALLOWED, null, null, "BC"); } catch (Exception e) { fail("validation exception."); } if (!Arrays.areEqual(req.getEncoded(), request)) { fail("" + algorithm + " failed encode check."); } } private void responseParse( byte[] request, byte[] response, ASN1ObjectIdentifier algorithm) throws Exception { TimeStampRequest req = new TimeStampRequest(request); TimeStampResponse resp = new TimeStampResponse(response); CertificateFactory fact = CertificateFactory.getInstance("X.509", "BC"); X509Certificate cert = (X509Certificate)fact.generateCertificate(new ByteArrayInputStream(signingCert)); resp.validate(req); resp.getTimeStampToken().validate(cert, "BC"); } private void unacceptableResponseParse( byte[] response) throws Exception { TimeStampResponse resp = new TimeStampResponse(response); if (resp.getStatus() != PKIStatus.REJECTION) { fail("request not rejected."); } if (resp.getFailInfo().intValue() != PKIFailureInfo.unacceptedPolicy) { fail("request not rejected."); } } private void generalizedTimeParse( byte[] response) throws Exception { TimeStampResponse resp = new TimeStampResponse(response); if (resp.getStatus() != PKIStatus.GRANTED) { fail("request not rejected."); } } public void testParsing() throws Exception { requestParse(sha1Request, TSPAlgorithms.SHA1); requestParse(sha1noNonse, TSPAlgorithms.SHA1); requestParse(md5Request, TSPAlgorithms.MD5); requestParse(ripemd160Request, TSPAlgorithms.RIPEMD160); responseParse(sha1Request, sha1Response, TSPAlgorithms.SHA1); responseParse(sha1noNonse, sha1noNonseResponse, TSPAlgorithms.SHA1); responseParse(md5Request, md5Response, TSPAlgorithms.MD5); unacceptableResponseParse(unacceptablePolicy); generalizedTimeParse(generalizedTime); v2SigningResponseParse(v2SigningCertResponse); } private void v2SigningResponseParse( byte[] encoded) throws Exception { TimeStampResponse response = new TimeStampResponse(encoded); Store store = response.getTimeStampToken().getCertificates(); X509CertificateHolder cert = (X509CertificateHolder)store.getMatches(response.getTimeStampToken().getSID()).iterator().next(); response.getTimeStampToken().validate(new JcaSimpleSignerInfoVerifierBuilder().setProvider("BC").build(cert)); } public void parse( byte[] encoded, boolean tokenPresent) throws Exception { TimeStampResponse response = new TimeStampResponse(encoded); if (tokenPresent && response.getTimeStampToken() == null) { fail("token not found when expected."); } } } bouncycastle-1.49.orig/test/src/org/bouncycastle/tsp/test/CMSTimeStampedDataParserTest.java0000644000175000017500000000553712151552117031511 0ustar ebourgebourgpackage org.bouncycastle.tsp.test; import java.io.ByteArrayInputStream; import java.io.ByteArrayOutputStream; import java.io.InputStream; import junit.framework.TestCase; import org.bouncycastle.operator.DigestCalculator; import org.bouncycastle.operator.DigestCalculatorProvider; import org.bouncycastle.operator.bc.BcDigestCalculatorProvider; import org.bouncycastle.tsp.TimeStampToken; import org.bouncycastle.tsp.cms.CMSTimeStampedDataParser; import org.bouncycastle.util.io.Streams; public class CMSTimeStampedDataParserTest extends TestCase { CMSTimeStampedDataParser cmsTimeStampedData = null; String fileInput = "FileDaFirmare.txt.tsd.der"; private byte[] baseData; protected void setUp() throws Exception { ByteArrayOutputStream origStream = new ByteArrayOutputStream(); InputStream in = this.getClass().getResourceAsStream(fileInput); int ch; while ((ch = in.read()) >= 0) { origStream.write(ch); } origStream.close(); this.baseData = origStream.toByteArray(); cmsTimeStampedData = new CMSTimeStampedDataParser(baseData); } protected void tearDown() throws Exception { cmsTimeStampedData = null; } public void testGetTimeStampTokens() throws Exception { TimeStampToken[] tokens = cmsTimeStampedData.getTimeStampTokens(); assertEquals(3, tokens.length); } public void testValidateAllTokens() throws Exception { DigestCalculatorProvider digestCalculatorProvider = new BcDigestCalculatorProvider(); ByteArrayOutputStream bOut = new ByteArrayOutputStream(); Streams.pipeAll(cmsTimeStampedData.getContent(), bOut); DigestCalculator imprintCalculator = cmsTimeStampedData.getMessageImprintDigestCalculator(digestCalculatorProvider); Streams.pipeAll(new ByteArrayInputStream(bOut.toByteArray()), imprintCalculator.getOutputStream()); byte[] digest = imprintCalculator.getDigest(); TimeStampToken[] tokens = cmsTimeStampedData.getTimeStampTokens(); for (int i = 0; i < tokens.length; i++) { cmsTimeStampedData.validate(digestCalculatorProvider, digest, tokens[i]); } } public void testValidate() throws Exception { DigestCalculatorProvider digestCalculatorProvider = new BcDigestCalculatorProvider(); ByteArrayOutputStream bOut = new ByteArrayOutputStream(); Streams.pipeAll(cmsTimeStampedData.getContent(), bOut); DigestCalculator imprintCalculator = cmsTimeStampedData.getMessageImprintDigestCalculator(digestCalculatorProvider); Streams.pipeAll(new ByteArrayInputStream(bOut.toByteArray()), imprintCalculator.getOutputStream()); cmsTimeStampedData.validate(digestCalculatorProvider, imprintCalculator.getDigest()); } } bouncycastle-1.49.orig/test/src/org/bouncycastle/tsp/test/SHA256DigestCalculator.java0000644000175000017500000000201312151274433030131 0ustar ebourgebourgpackage org.bouncycastle.tsp.test; import java.io.ByteArrayOutputStream; import java.io.OutputStream; import org.bouncycastle.asn1.nist.NISTObjectIdentifiers; import org.bouncycastle.asn1.x509.AlgorithmIdentifier; import org.bouncycastle.crypto.Digest; import org.bouncycastle.crypto.digests.SHA256Digest; import org.bouncycastle.operator.DigestCalculator; class SHA256DigestCalculator implements DigestCalculator { private ByteArrayOutputStream bOut = new ByteArrayOutputStream(); public AlgorithmIdentifier getAlgorithmIdentifier() { return new AlgorithmIdentifier(NISTObjectIdentifiers.id_sha256); } public OutputStream getOutputStream() { return bOut; } public byte[] getDigest() { byte[] bytes = bOut.toByteArray(); bOut.reset(); Digest sha256 = new SHA256Digest(); sha256.update(bytes, 0, bytes.length); byte[] digest = new byte[sha256.getDigestSize()]; sha256.doFinal(digest, 0); return digest; } } bouncycastle-1.49.orig/test/src/org/bouncycastle/tsp/test/SHA1DigestCalculator.java0000644000175000017500000000176712117456162027777 0ustar ebourgebourgpackage org.bouncycastle.tsp.test; import java.io.ByteArrayOutputStream; import java.io.OutputStream; import org.bouncycastle.asn1.oiw.OIWObjectIdentifiers; import org.bouncycastle.asn1.x509.AlgorithmIdentifier; import org.bouncycastle.crypto.Digest; import org.bouncycastle.crypto.digests.SHA1Digest; import org.bouncycastle.operator.DigestCalculator; class SHA1DigestCalculator implements DigestCalculator { private ByteArrayOutputStream bOut = new ByteArrayOutputStream(); public AlgorithmIdentifier getAlgorithmIdentifier() { return new AlgorithmIdentifier(OIWObjectIdentifiers.idSHA1); } public OutputStream getOutputStream() { return bOut; } public byte[] getDigest() { byte[] bytes = bOut.toByteArray(); bOut.reset(); Digest sha1 = new SHA1Digest(); sha1.update(bytes, 0, bytes.length); byte[] digest = new byte[sha1.getDigestSize()]; sha1.doFinal(digest, 0); return digest; } } bouncycastle-1.49.orig/test/src/org/bouncycastle/eac/0000755000175000017500000000000012152033550022205 5ustar ebourgebourgbouncycastle-1.49.orig/test/src/org/bouncycastle/eac/test/0000755000175000017500000000000012152033550023164 5ustar ebourgebourgbouncycastle-1.49.orig/test/src/org/bouncycastle/eac/test/EACTestSetup.java0000644000175000017500000000104311643456456026320 0ustar ebourgebourg package org.bouncycastle.eac.test; import java.security.Security; import junit.extensions.TestSetup; import junit.framework.Test; import org.bouncycastle.jce.provider.BouncyCastleProvider; class EACTestSetup extends TestSetup { public EACTestSetup(Test test) { super(test); } protected void setUp() { Security.addProvider(new org.bouncycastle.jce.provider.BouncyCastleProvider()); } protected void tearDown() { Security.removeProvider(BouncyCastleProvider.PROVIDER_NAME); } } bouncycastle-1.49.orig/test/src/org/bouncycastle/eac/test/AllTests.java0000644000175000017500000001711012151552117025566 0ustar ebourgebourgpackage org.bouncycastle.eac.test; import java.io.IOException; import java.security.InvalidAlgorithmParameterException; import java.security.KeyPair; import java.security.KeyPairGenerator; import java.security.NoSuchAlgorithmException; import java.security.NoSuchProviderException; import java.security.PublicKey; import java.security.SecureRandom; import java.security.Security; import junit.framework.Test; import junit.framework.TestCase; import junit.framework.TestSuite; import org.bouncycastle.asn1.eac.CertificateHolderAuthorization; import org.bouncycastle.asn1.eac.CertificateHolderReference; import org.bouncycastle.asn1.eac.CertificationAuthorityReference; import org.bouncycastle.asn1.eac.EACObjectIdentifiers; import org.bouncycastle.asn1.eac.PackedDate; import org.bouncycastle.eac.EACCertificateBuilder; import org.bouncycastle.eac.EACCertificateHolder; import org.bouncycastle.eac.EACCertificateRequestHolder; import org.bouncycastle.eac.jcajce.JcaPublicKeyConverter; import org.bouncycastle.eac.operator.EACSignatureVerifier; import org.bouncycastle.eac.operator.EACSigner; import org.bouncycastle.eac.operator.jcajce.JcaEACSignatureVerifierBuilder; import org.bouncycastle.eac.operator.jcajce.JcaEACSignerBuilder; import org.bouncycastle.jce.ECNamedCurveTable; import org.bouncycastle.jce.provider.BouncyCastleProvider; import org.bouncycastle.jce.spec.ECParameterSpec; import org.bouncycastle.util.io.Streams; public class AllTests extends TestCase { private static final String BC = BouncyCastleProvider.PROVIDER_NAME; public void setUp() { if (Security.getProvider(BC) != null) { Security.addProvider(new BouncyCastleProvider()); } } public void testLoadCertificate() throws Exception { EACCertificateHolder certHolder = new EACCertificateHolder(getInput("Belgique CVCA-02032010.7816.cvcert")); PublicKey pubKey = new JcaPublicKeyConverter().setProvider(BC).getKey(certHolder.getPublicKeyDataObject()); EACSignatureVerifier verifier = new JcaEACSignatureVerifierBuilder().build(certHolder.getPublicKeyDataObject().getUsage(), pubKey); if (!certHolder.isSignatureValid(verifier)) { fail("signature test failed"); } } private byte[] getInput(String name) throws IOException { return Streams.readAll(getClass().getResourceAsStream(name)); } public void testLoadInvalidRequest() throws Exception { // this request contains invalid unsigned integers (see D 2.1.1) EACCertificateRequestHolder requestHolder = new EACCertificateRequestHolder(getInput("REQ_18102010.csr")); PublicKey pubKey = new JcaPublicKeyConverter().setProvider(BC).getKey(requestHolder.getPublicKeyDataObject()); EACSignatureVerifier verifier = new JcaEACSignatureVerifierBuilder().build(requestHolder.getPublicKeyDataObject().getUsage(), pubKey); if (requestHolder.isInnerSignatureValid(verifier)) { fail("signature test failed"); } } public void testLoadRefCert() throws Exception { EACCertificateHolder certHolder = new EACCertificateHolder(getInput("at_cert_19a.cvcert")); } public void testGenerateEC() throws Exception { ECParameterSpec ecSpec = ECNamedCurveTable.getParameterSpec("prime256v1"); KeyPair kp = generateECKeyPair(ecSpec); JcaEACSignerBuilder signerBuilder = new JcaEACSignerBuilder().setProvider(BC); EACSigner signer = signerBuilder.build("SHA256withECDSA", kp.getPrivate()); int role = CertificateHolderAuthorization.CVCA; int rights = CertificateHolderAuthorization.RADG3 | CertificateHolderAuthorization.RADG4; EACCertificateBuilder certBuilder = new EACCertificateBuilder( new CertificationAuthorityReference("AU", "BC TEST", "12345"), new JcaPublicKeyConverter().getPublicKeyDataObject(signer.getUsageIdentifier(), kp.getPublic()), new CertificateHolderReference("AU", "BC TEST", "12345"), new CertificateHolderAuthorization(EACObjectIdentifiers.id_EAC_ePassport, role | rights), new PackedDate("110101"), new PackedDate("120101")); EACCertificateHolder certHolder = certBuilder.build(signer); EACSignatureVerifier verifier = new JcaEACSignatureVerifierBuilder().build(certHolder.getPublicKeyDataObject().getUsage(), kp.getPublic()); if (!certHolder.isSignatureValid(verifier)) { fail("first signature test failed"); } PublicKey pubKey = new JcaPublicKeyConverter().setProvider(BC).getKey(certHolder.getPublicKeyDataObject()); verifier = new JcaEACSignatureVerifierBuilder().build(certHolder.getPublicKeyDataObject().getUsage(), pubKey); if (!certHolder.isSignatureValid(verifier)) { fail("first signature test failed"); } } public void testGenerateRSA() throws Exception { KeyPair kp = generateRSAKeyPair(); JcaEACSignerBuilder signerBuilder = new JcaEACSignerBuilder().setProvider(BC); EACSigner signer = signerBuilder.build("SHA256withRSA", kp.getPrivate()); int role = CertificateHolderAuthorization.CVCA; int rights = CertificateHolderAuthorization.RADG3 | CertificateHolderAuthorization.RADG4; EACCertificateBuilder certBuilder = new EACCertificateBuilder( new CertificationAuthorityReference("AU", "BC TEST", "12345"), new JcaPublicKeyConverter().getPublicKeyDataObject(signer.getUsageIdentifier(), kp.getPublic()), new CertificateHolderReference("AU", "BC TEST", "12345"), new CertificateHolderAuthorization(EACObjectIdentifiers.id_EAC_ePassport, role | rights), new PackedDate("110101"), new PackedDate("120101")); EACCertificateHolder certHolder = certBuilder.build(signer); EACSignatureVerifier verifier = new JcaEACSignatureVerifierBuilder().build(certHolder.getPublicKeyDataObject().getUsage(), kp.getPublic()); if (!certHolder.isSignatureValid(verifier)) { fail("first signature test failed"); } PublicKey pubKey = new JcaPublicKeyConverter().setProvider(BC).getKey(certHolder.getPublicKeyDataObject()); verifier = new JcaEACSignatureVerifierBuilder().build(certHolder.getPublicKeyDataObject().getUsage(), pubKey); if (!certHolder.isSignatureValid(verifier)) { fail("first signature test failed"); } } private KeyPair generateECKeyPair(ECParameterSpec spec) throws NoSuchAlgorithmException, NoSuchProviderException, InvalidAlgorithmParameterException { KeyPairGenerator gen = KeyPairGenerator.getInstance("ECDSA",BC); gen.initialize(spec, new SecureRandom()); KeyPair generatedKeyPair = gen.generateKeyPair(); return generatedKeyPair; } private KeyPair generateRSAKeyPair() throws NoSuchAlgorithmException, NoSuchProviderException, InvalidAlgorithmParameterException { KeyPairGenerator gen = KeyPairGenerator.getInstance("RSA",BC); gen.initialize(1024, new SecureRandom()); KeyPair generatedKeyPair = gen.generateKeyPair(); return generatedKeyPair; } public static void main(String[] args) throws Exception { Security.addProvider(new BouncyCastleProvider()); junit.textui.TestRunner.run(suite()); } public static Test suite() throws Exception { TestSuite suite= new TestSuite("EAC tests"); suite.addTestSuite(AllTests.class); return new EACTestSetup(suite); } } bouncycastle-1.49.orig/test/src/org/bouncycastle/math/0000755000175000017500000000000012152033550022406 5ustar ebourgebourgbouncycastle-1.49.orig/test/src/org/bouncycastle/math/ec/0000755000175000017500000000000012152033550022775 5ustar ebourgebourgbouncycastle-1.49.orig/test/src/org/bouncycastle/math/ec/test/0000755000175000017500000000000012152033550023754 5ustar ebourgebourgbouncycastle-1.49.orig/test/src/org/bouncycastle/math/ec/test/F2mProofer.java0000644000175000017500000001525410611652432026613 0ustar ebourgebourgpackage org.bouncycastle.math.ec.test; import java.io.FileInputStream; import java.io.FileOutputStream; import java.io.IOException; import java.math.BigInteger; import java.security.NoSuchAlgorithmException; import java.security.SecureRandom; import java.util.Iterator; import java.util.Properties; import java.util.Set; import org.bouncycastle.asn1.sec.SECNamedCurves; import org.bouncycastle.asn1.x9.X9ECParameters; import org.bouncycastle.math.ec.ECFieldElement; import org.bouncycastle.math.ec.ECPoint; public class F2mProofer { private static final int NUM_SAMPLES = 1000; private static final String PATH = "crypto/test/src/org/bouncycastle/math/ec/test/samples/"; private static final String INPUT_FILE_NAME_PREFIX = "Input_"; private static final String RESULT_FILE_NAME_PREFIX = "Output_"; /** * The standard curves on which the tests are done */ public static final String[] CURVES = { "sect163r2", "sect233r1", "sect283r1", "sect409r1", "sect571r1" }; private String pointToString(ECPoint.F2m p) { ECFieldElement.F2m x = (ECFieldElement.F2m) p.getX(); ECFieldElement.F2m y = (ECFieldElement.F2m) p.getY(); int m = x.getM(); int len = m / 2 + 5; StringBuffer sb = new StringBuffer(len); sb.append('('); sb.append(x.toBigInteger().toString(16)); sb.append(", "); sb.append(y.toBigInteger().toString(16)); sb.append(')'); return sb.toString(); } private void generateRandomInput(X9ECParameters x9ECParameters) throws NoSuchAlgorithmException, IOException { ECPoint.F2m g = (ECPoint.F2m) x9ECParameters.getG(); int m = ((ECFieldElement.F2m) (g.getX())).getM(); SecureRandom secRand = SecureRandom.getInstance("SHA1PRNG"); Properties inputProps = new Properties(); for (int i = 0; i < NUM_SAMPLES; i++) { BigInteger rand = new BigInteger(m, secRand); inputProps.put(Integer.toString(i), rand.toString(16)); } String bits = Integer.toString(m); FileOutputStream fos = new FileOutputStream(PATH + INPUT_FILE_NAME_PREFIX + bits + ".properties"); inputProps.store(fos, "Input Samples of length" + bits); } private void multiplyPoints(X9ECParameters x9ECParameters, String classPrefix) throws IOException { ECPoint.F2m g = (ECPoint.F2m) x9ECParameters.getG(); int m = ((ECFieldElement.F2m) (g.getX())).getM(); String inputFileName = PATH + INPUT_FILE_NAME_PREFIX + m + ".properties"; Properties inputProps = new Properties(); inputProps.load(new FileInputStream(inputFileName)); Properties outputProps = new Properties(); for (int i = 0; i < NUM_SAMPLES; i++) { BigInteger rand = new BigInteger(inputProps.getProperty(Integer .toString(i)), 16); ECPoint.F2m result = (ECPoint.F2m) g.multiply(rand); String resultStr = pointToString(result); outputProps.setProperty(Integer.toString(i), resultStr); } String outputFileName = PATH + RESULT_FILE_NAME_PREFIX + classPrefix + "_" + m + ".properties"; FileOutputStream fos = new FileOutputStream(outputFileName); outputProps.store(fos, "Output Samples of length" + m); } private Properties loadResults(String classPrefix, int m) throws IOException { FileInputStream fis = new FileInputStream(PATH + RESULT_FILE_NAME_PREFIX + classPrefix + "_" + m + ".properties"); Properties res = new Properties(); res.load(fis); return res; } private void compareResult(X9ECParameters x9ECParameters, String classPrefix1, String classPrefix2) throws IOException { ECPoint.F2m g = (ECPoint.F2m) x9ECParameters.getG(); int m = ((ECFieldElement.F2m) (g.getX())).getM(); Properties res1 = loadResults(classPrefix1, m); Properties res2 = loadResults(classPrefix2, m); Set keys = res1.keySet(); Iterator iter = keys.iterator(); while (iter.hasNext()) { String key = (String) iter.next(); String result1 = res1.getProperty(key); String result2 = res2.getProperty(key); if (!(result1.equals(result2))) { System.err.println("Difference found: m = " + m + ", " + result1 + " does not equal " + result2); } } } private static void usage() { System.err.println("Usage: F2mProofer [-init | -multiply " + "| -compare ]"); } public static void main(String[] args) throws Exception { if (args.length == 0) { usage(); return; } F2mProofer proofer = new F2mProofer(); if (args[0].equals("-init")) { System.out.println("Generating random input..."); for (int i = 0; i < CURVES.length; i++) { X9ECParameters x9ECParameters = SECNamedCurves .getByName(CURVES[i]); proofer.generateRandomInput(x9ECParameters); } System.out .println("Successfully generated random input in " + PATH); } else if (args[0].equals("-compare")) { if (args.length < 3) { usage(); return; } String classPrefix1 = args[1]; String classPrefix2 = args[2]; System.out.println("Comparing results..."); for (int i = 0; i < CURVES.length; i++) { X9ECParameters x9ECParameters = SECNamedCurves .getByName(CURVES[i]); proofer.compareResult(x9ECParameters, classPrefix1, classPrefix2); } System.out.println("Successfully compared results in " + PATH); } else if (args[0].equals("-multiply")) { if (args.length < 2) { usage(); return; } String classPrefix = args[1]; System.out.println("Multiplying points..."); for (int i = 0; i < CURVES.length; i++) { X9ECParameters x9ECParameters = SECNamedCurves .getByName(CURVES[i]); proofer.multiplyPoints(x9ECParameters, classPrefix); } System.out.println("Successfully generated multiplied points in " + PATH); } else { usage(); } } } bouncycastle-1.49.orig/test/src/org/bouncycastle/math/ec/test/ECPointTest.java0000644000175000017500000003410710621311037026763 0ustar ebourgebourgpackage org.bouncycastle.math.ec.test; import java.math.BigInteger; import java.security.SecureRandom; import java.util.Enumeration; import junit.framework.Test; import junit.framework.TestCase; import junit.framework.TestSuite; import org.bouncycastle.asn1.sec.SECNamedCurves; import org.bouncycastle.asn1.x9.X9ECParameters; import org.bouncycastle.math.ec.ECCurve; import org.bouncycastle.math.ec.ECFieldElement; import org.bouncycastle.math.ec.ECPoint; /** * Test class for {@link org.bouncycastle.math.ec.ECPoint ECPoint}. All * literature values are taken from "Guide to elliptic curve cryptography", * Darrel Hankerson, Alfred J. Menezes, Scott Vanstone, 2004, Springer-Verlag * New York, Inc. */ public class ECPointTest extends TestCase { /** * Random source used to generate random points */ private SecureRandom secRand = new SecureRandom(); private ECPointTest.Fp fp = null; private ECPointTest.F2m f2m = null; /** * Nested class containing sample literature values for Fp. */ public static class Fp { private final BigInteger q = new BigInteger("29"); private final BigInteger a = new BigInteger("4"); private final BigInteger b = new BigInteger("20"); private final ECCurve.Fp curve = new ECCurve.Fp(q, a, b); private final ECPoint.Fp infinity = (ECPoint.Fp) curve.getInfinity(); private final int[] pointSource = { 5, 22, 16, 27, 13, 6, 14, 6 }; private ECPoint.Fp[] p = new ECPoint.Fp[pointSource.length / 2]; /** * Creates the points on the curve with literature values. */ private void createPoints() { for (int i = 0; i < pointSource.length / 2; i++) { ECFieldElement.Fp x = new ECFieldElement.Fp(q, new BigInteger( Integer.toString(pointSource[2 * i]))); ECFieldElement.Fp y = new ECFieldElement.Fp(q, new BigInteger( Integer.toString(pointSource[2 * i + 1]))); p[i] = new ECPoint.Fp(curve, x, y); } } } /** * Nested class containing sample literature values for F2m. */ public static class F2m { // Irreducible polynomial for TPB z^4 + z + 1 private final int m = 4; private final int k1 = 1; // a = z^3 private final ECFieldElement.F2m aTpb = new ECFieldElement.F2m(m, k1, new BigInteger("1000", 2)); // b = z^3 + 1 private final ECFieldElement.F2m bTpb = new ECFieldElement.F2m(m, k1, new BigInteger("1001", 2)); private final ECCurve.F2m curve = new ECCurve.F2m(m, k1, aTpb .toBigInteger(), bTpb.toBigInteger()); private final ECPoint.F2m infinity = (ECPoint.F2m) curve.getInfinity(); private final String[] pointSource = { "0010", "1111", "1100", "1100", "0001", "0001", "1011", "0010" }; private ECPoint.F2m[] p = new ECPoint.F2m[pointSource.length / 2]; /** * Creates the points on the curve with literature values. */ private void createPoints() { for (int i = 0; i < pointSource.length / 2; i++) { ECFieldElement.F2m x = new ECFieldElement.F2m(m, k1, new BigInteger(pointSource[2 * i], 2)); ECFieldElement.F2m y = new ECFieldElement.F2m(m, k1, new BigInteger(pointSource[2 * i + 1], 2)); p[i] = new ECPoint.F2m(curve, x, y); } } } public void setUp() { fp = new ECPointTest.Fp(); fp.createPoints(); f2m = new ECPointTest.F2m(); f2m.createPoints(); } /** * Tests, if inconsistent points can be created, i.e. points with exactly * one null coordinate (not permitted). */ public void testPointCreationConsistency() { try { ECPoint.Fp bad = new ECPoint.Fp(fp.curve, new ECFieldElement.Fp( fp.q, new BigInteger("12")), null); fail(); } catch (IllegalArgumentException expected) { } try { ECPoint.Fp bad = new ECPoint.Fp(fp.curve, null, new ECFieldElement.Fp(fp.q, new BigInteger("12"))); fail(); } catch (IllegalArgumentException expected) { } try { ECPoint.F2m bad = new ECPoint.F2m(f2m.curve, new ECFieldElement.F2m( f2m.m, f2m.k1, new BigInteger("1011")), null); fail(); } catch (IllegalArgumentException expected) { } try { ECPoint.F2m bad = new ECPoint.F2m(f2m.curve, null, new ECFieldElement.F2m(f2m.m, f2m.k1, new BigInteger("1011"))); fail(); } catch (IllegalArgumentException expected) { } } /** * Tests ECPoint.add() against literature values. * * @param p * The array of literature values. * @param infinity * The point at infinity on the respective curve. */ private void implTestAdd(ECPoint[] p, ECPoint infinity) { assertEquals("p0 plus p1 does not equal p2", p[2], p[0].add(p[1])); assertEquals("p1 plus p0 does not equal p2", p[2], p[1].add(p[0])); for (int i = 0; i < p.length; i++) { assertEquals("Adding infinity failed", p[i], p[i].add(infinity)); assertEquals("Adding to infinity failed", p[i], infinity.add(p[i])); } } /** * Calls implTestAdd() for Fp and * F2m. */ public void testAdd() { implTestAdd(fp.p, fp.infinity); implTestAdd(f2m.p, f2m.infinity); } /** * Tests ECPoint.twice() against literature values. * * @param p * The array of literature values. */ private void implTestTwice(ECPoint[] p) { assertEquals("Twice incorrect", p[3], p[0].twice()); assertEquals("Add same point incorrect", p[3], p[0].add(p[0])); } /** * Calls implTestTwice() for Fp and * F2m. */ public void testTwice() { implTestTwice(fp.p); implTestTwice(f2m.p); } /** * Goes through all points on an elliptic curve and checks, if adding a * point k-times is the same as multiplying the point by * k, for all k. Should be called for points * on very small elliptic curves only. * * @param p * The base point on the elliptic curve. * @param infinity * The point at infinity on the elliptic curve. */ private void implTestAllPoints(ECPoint p, ECPoint infinity) { ECPoint adder = infinity; ECPoint multiplier = infinity; int i = 1; do { adder = adder.add(p); multiplier = p.multiply(new BigInteger(Integer.toString(i))); assertEquals("Results of add() and multiply() are inconsistent " + i, adder, multiplier); i++; } while (!(adder.equals(infinity))); } /** * Calls implTestAllPoints() for the small literature curves, * both for Fp and F2m. */ public void testAllPoints() { for (int i = 0; i < fp.p.length; i++) { implTestAllPoints(fp.p[0], fp.infinity); } for (int i = 0; i < f2m.p.length; i++) { implTestAllPoints(f2m.p[0], f2m.infinity); } } /** * Simple shift-and-add multiplication. Serves as reference implementation * to verify (possibly faster) implementations in * {@link org.bouncycastle.math.ec.ECPoint ECPoint}. * * @param p * The point to multiply. * @param k * The multiplier. * @return The result of the point multiplication kP. */ private ECPoint multiply(ECPoint p, BigInteger k) { ECPoint q = p.getCurve().getInfinity(); int t = k.bitLength(); for (int i = 0; i < t; i++) { if (k.testBit(i)) { q = q.add(p); } p = p.twice(); } return q; } /** * Checks, if the point multiplication algorithm of the given point yields * the same result as point multiplication done by the reference * implementation given in multiply(). This method chooses a * random number by which the given point p is multiplied. * * @param p * The point to be multiplied. * @param numBits * The bitlength of the random number by which p * is multiplied. */ private void implTestMultiply(ECPoint p, int numBits) { BigInteger k = new BigInteger(numBits, secRand); ECPoint ref = multiply(p, k); ECPoint q = p.multiply(k); assertEquals("ECPoint.multiply is incorrect", ref, q); } /** * Checks, if the point multiplication algorithm of the given point yields * the same result as point multiplication done by the reference * implementation given in multiply(). This method tests * multiplication of p by every number of bitlength * numBits or less. * * @param p * The point to be multiplied. * @param numBits * Try every multiplier up to this bitlength */ private void implTestMultiplyAll(ECPoint p, int numBits) { BigInteger bound = BigInteger.valueOf(2).pow(numBits); BigInteger k = BigInteger.ZERO; do { ECPoint ref = multiply(p, k); ECPoint q = p.multiply(k); assertEquals("ECPoint.multiply is incorrect", ref, q); k = k.add(BigInteger.ONE); } while (k.compareTo(bound) < 0); } /** * Tests ECPoint.add() and ECPoint.subtract() * for the given point and the given point at infinity. * * @param p * The point on which the tests are performed. * @param infinity * The point at infinity on the same curve as p. */ private void implTestAddSubtract(ECPoint p, ECPoint infinity) { assertEquals("Twice and Add inconsistent", p.twice(), p.add(p)); assertEquals("Twice p - p is not p", p, p.twice().subtract(p)); assertEquals("p - p is not infinity", infinity, p.subtract(p)); assertEquals("p plus infinity is not p", p, p.add(infinity)); assertEquals("infinity plus p is not p", p, infinity.add(p)); assertEquals("infinity plus infinity is not infinity ", infinity, infinity.add(infinity)); } /** * Calls implTestAddSubtract() for literature values, both * for Fp and F2m. */ public void testAddSubtractMultiplySimple() { for (int iFp = 0; iFp < fp.pointSource.length / 2; iFp++) { implTestAddSubtract(fp.p[iFp], fp.infinity); // Could be any numBits, 6 is chosen at will implTestMultiplyAll(fp.p[iFp], 6); implTestMultiplyAll(fp.infinity, 6); } for (int iF2m = 0; iF2m < f2m.pointSource.length / 2; iF2m++) { implTestAddSubtract(f2m.p[iF2m], f2m.infinity); // Could be any numBits, 6 is chosen at will implTestMultiplyAll(f2m.p[iF2m], 6); implTestMultiplyAll(f2m.infinity, 6); } } /** * Test encoding with and without point compression. * * @param p * The point to be encoded and decoded. */ private void implTestEncoding(ECPoint p) { // Not Point Compression ECPoint unCompP; // Point compression ECPoint compP; if (p instanceof ECPoint.Fp) { unCompP = new ECPoint.Fp(p.getCurve(), p.getX(), p.getY(), false); compP = new ECPoint.Fp(p.getCurve(), p.getX(), p.getY(), true); } else { unCompP = new ECPoint.F2m(p.getCurve(), p.getX(), p.getY(), false); compP = new ECPoint.F2m(p.getCurve(), p.getX(), p.getY(), true); } byte[] unCompBarr = unCompP.getEncoded(); ECPoint decUnComp = p.getCurve().decodePoint(unCompBarr); assertEquals("Error decoding uncompressed point", p, decUnComp); byte[] compBarr = compP.getEncoded(); ECPoint decComp = p.getCurve().decodePoint(compBarr); assertEquals("Error decoding compressed point", p, decComp); } /** * Calls implTestAddSubtract(), * implTestMultiply and implTestEncoding for * the standard elliptic curves as given in SECNamedCurves. */ public void testAddSubtractMultiplyTwiceEncoding() { Enumeration curveEnum = SECNamedCurves.getNames(); while (curveEnum.hasMoreElements()) { String name = (String) curveEnum.nextElement(); X9ECParameters x9ECParameters = SECNamedCurves.getByName(name); BigInteger n = x9ECParameters.getN(); // The generator is multiplied by random b to get random q BigInteger b = new BigInteger(n.bitLength(), secRand); ECPoint g = x9ECParameters.getG(); ECPoint q = g.multiply(b); // Get point at infinity on the curve ECPoint infinity = x9ECParameters.getCurve().getInfinity(); implTestAddSubtract(q, infinity); implTestMultiply(q, n.bitLength()); implTestMultiply(infinity, n.bitLength()); implTestEncoding(q); } } public static Test suite() { return new TestSuite(ECPointTest.class); } } bouncycastle-1.49.orig/test/src/org/bouncycastle/math/ec/test/TnafTest.java0000644000175000017500000001521610662310170026354 0ustar ebourgebourg//package org.bouncycastle.math.ec.test; // //import java.math.BigInteger; //import java.util.Random; // //import junit.framework.TestCase; // //import org.bouncycastle.asn1.sec.SECNamedCurves; //import org.bouncycastle.asn1.x9.X9ECParameters; //import org.bouncycastle.math.ec.ECCurve; //import org.bouncycastle.math.ec.ECPoint; //import org.bouncycastle.math.ec.FpNafMultiplier; //import org.bouncycastle.math.ec.ReferenceMultiplier; //import org.bouncycastle.math.ec.WNafMultiplier; //import org.bouncycastle.math.ec.WTauNafMultiplier; // //public class TnafTest extends TestCase //{ // private Random m_rand = new Random(); // // private String ecPointToString(ECPoint p) { // StringBuffer sb = new StringBuffer("x = "); // sb.append(p.getX().toBigInteger().toString()); // sb.append("; y = "); // sb.append(p.getY().toBigInteger().toString()); // return sb.toString(); // } // // private ECPoint repeatedMultiply(ECPoint p, BigInteger k) // { // ECPoint result = p.multiply(k); // for (int i = 1; i < 10; ++i) // { // ECPoint check = p.multiply(k); // assertEquals(result, check); // } // return result; // } // // private void implTestMultiplyTnaf(String curveName) { // X9ECParameters x9ECParameters = SECNamedCurves.getByName(curveName); // // ECCurve.F2m curve = (ECCurve.F2m)x9ECParameters.getCurve(); // BigInteger n = curve.getN(); // // // The generator is multiplied by random b to get random q // BigInteger b = new BigInteger(n.bitLength(), m_rand); // ECPoint g = x9ECParameters.getG(); // ECPoint.F2m p = (ECPoint.F2m)g.multiply(b); // // BigInteger k = new BigInteger(n.bitLength(), m_rand); // long now1 = System.currentTimeMillis(); // p.setECMultiplier(new WTauNafMultiplier()); // ECPoint refRWTnaf = repeatedMultiply(p, k); // long now2 = System.currentTimeMillis(); // p.setECMultiplier(new WNafMultiplier()); // ECPoint refWnaf = repeatedMultiply(p, k); // long now3 = System.currentTimeMillis(); // p.setECMultiplier(new FpNafMultiplier()); // ECPoint refFpNaf = repeatedMultiply(p, k); // long now4 = System.currentTimeMillis(); // p.setECMultiplier(new ReferenceMultiplier()); // ECPoint reference = repeatedMultiply(p, k); // long now5 = System.currentTimeMillis(); // // assertEquals("WTNAF multiplication is incorrect", refRWTnaf, reference); // assertEquals("FPNAF multiplication is incorrect", refFpNaf, reference); // assertEquals("WNAF multiplication is incorrect", refWnaf, reference); // // System.out.println(curveName + ": Multiply WTNAF took millis: " + (now2 - now1)); // System.out.println(curveName + ": Multiply WNAF took millis: " + (now3 - now2)); // System.out.println(curveName + ": Multiply FPNAF took millis: " + (now4 - now3)); // System.out.println(curveName + ": Multiply REFE took millis: " + (now5 - now4)); // //// System.out.println(curveName + ": refRWTnaf = " + ecPointToString(refRWTnaf)); //// System.out.println(curveName + ": refWnaf = " + ecPointToString(refWnaf)); //// System.out.println(curveName + ": refFpNaf = " + ecPointToString(refFpNaf)); //// System.out.println(curveName + ": reference = " + ecPointToString(reference) + "\n"); // System.out.println(); // } // // public void testMultiplyTnaf() { // System.out.println("\n\n\n***** Start test multiplications on F2m (Koblitz) *****"); // implTestMultiplyTnaf("sect163k1"); // implTestMultiplyTnaf("sect233k1"); // implTestMultiplyTnaf("sect239k1"); // implTestMultiplyTnaf("sect283k1"); // implTestMultiplyTnaf("sect409k1"); // implTestMultiplyTnaf("sect571k1"); // } // // private void implTestMultiplyWnaf(String curveName) { // X9ECParameters x9ECParameters = SECNamedCurves.getByName(curveName); // // BigInteger r = x9ECParameters.getN(); // // // The generator is multiplied by random b to get random q // BigInteger b = new BigInteger(r.bitLength(), m_rand); // ECPoint g = x9ECParameters.getG(); // ECPoint p = g.multiply(b); // // BigInteger k = new BigInteger(r.bitLength(), m_rand); // long now1 = System.currentTimeMillis(); // p.setECMultiplier(new WNafMultiplier()); // ECPoint refWnaf = repeatedMultiply(p, k); // long now2 = System.currentTimeMillis(); // p.setECMultiplier(new FpNafMultiplier()); // ECPoint refFpNaf = repeatedMultiply(p, k); // long now3 = System.currentTimeMillis(); // p.setECMultiplier(new ReferenceMultiplier()); // ECPoint reference = repeatedMultiply(p, k); // long now4 = System.currentTimeMillis(); // // assertEquals("WNAF multiplication is incorrect", refWnaf, reference); // assertEquals("FPNAF multiplication is incorrect", refFpNaf, reference); // // System.out.println(curveName + ": Multiply WNAF took millis: " + (now2 - now1)); // System.out.println(curveName + ": Multiply FPNAF took millis: " + (now3 - now2)); // System.out.println(curveName + ": Multiply REFE took millis: " + (now4 - now3)); // //// System.out.println(curveName + ": refWnaf = " + ecPointToString(refWnaf)); //// System.out.println(curveName + ": refFpNaf = " + ecPointToString(refFpNaf)); //// System.out.println(curveName + ": reference = " + ecPointToString(reference)); // System.out.println(); // } // // public void testMultiplyWnaf() { // System.out.println("\n\n\n***** Start test multiplications on F2m *****"); // implTestMultiplyWnaf("sect113r1"); // implTestMultiplyWnaf("sect113r2"); // implTestMultiplyWnaf("sect131r1"); // implTestMultiplyWnaf("sect131r2"); // implTestMultiplyWnaf("sect163r1"); // implTestMultiplyWnaf("sect163r2"); // implTestMultiplyWnaf("sect193r1"); // implTestMultiplyWnaf("sect193r2"); // implTestMultiplyWnaf("sect233r1"); // implTestMultiplyWnaf("sect283r1"); // implTestMultiplyWnaf("sect409r1"); // implTestMultiplyWnaf("sect571r1"); // // System.out.println("\n\n\n***** Start test multiplications on Fp *****"); // implTestMultiplyWnaf("secp112r1"); // implTestMultiplyWnaf("secp128r1"); // implTestMultiplyWnaf("secp160r1"); // implTestMultiplyWnaf("secp192r1"); // implTestMultiplyWnaf("secp224r1"); // implTestMultiplyWnaf("secp256r1"); // implTestMultiplyWnaf("secp384r1"); // implTestMultiplyWnaf("secp521r1"); // } //} bouncycastle-1.49.orig/test/src/org/bouncycastle/math/ec/test/AllTests.java0000644000175000017500000000071610422362075026363 0ustar ebourgebourgpackage org.bouncycastle.math.ec.test; import junit.framework.Test; import junit.framework.TestSuite; public class AllTests { public static void main (String[] args) throws Exception { junit.textui.TestRunner.run(suite()); } public static Test suite() throws Exception { TestSuite suite = new TestSuite("EC Math tests"); suite.addTest(ECPointTest.suite()); return suite; } } bouncycastle-1.49.orig/test/src/org/bouncycastle/math/ec/test/ECPointPerformanceTest.java0000644000175000017500000000404211357214332031147 0ustar ebourgebourgpackage org.bouncycastle.math.ec.test; import java.math.BigInteger; import java.security.SecureRandom; import junit.framework.TestCase; import org.bouncycastle.asn1.sec.SECNamedCurves; import org.bouncycastle.asn1.x9.X9ECParameters; import org.bouncycastle.math.ec.ECPoint; /** * Compares the performance of the the window NAF point multiplication against * conventional point multiplication. */ public class ECPointPerformanceTest extends TestCase { public static final int NUM_ROUNDS = 100; private void randMult(final String curveName) throws Exception { final X9ECParameters spec = SECNamedCurves.getByName(curveName); final BigInteger n = spec.getN(); final ECPoint g = (ECPoint) spec.getG(); final SecureRandom random = SecureRandom.getInstance("SHA1PRNG", "SUN"); final BigInteger k = new BigInteger(n.bitLength() - 1, random); ECPoint qMultiply = null; long startTime = System.currentTimeMillis(); for (int i = 0; i < NUM_ROUNDS; i++) { qMultiply = g.multiply(k); } long endTime = System.currentTimeMillis(); double avgDuration = (double) (endTime - startTime) / NUM_ROUNDS; System.out.println(curveName); System.out.print("Millis : "); System.out.println(avgDuration); System.out.println(); } public void testMultiply() throws Exception { randMult("sect163k1"); randMult("sect163r2"); randMult("sect233k1"); randMult("sect233r1"); randMult("sect283k1"); randMult("sect283r1"); randMult("sect409k1"); randMult("sect409r1"); randMult("sect571k1"); randMult("sect571r1"); randMult("secp224k1"); randMult("secp224r1"); randMult("secp256k1"); randMult("secp256r1"); randMult("secp521r1"); } // public static void main(String argv[]) throws Exception // { // ECMultiplyPerformanceTest test = new ECMultiplyPerformanceTest(); // test.testMultiply(); // } } bouncycastle-1.49.orig/test/src/org/bouncycastle/jcajce/0000755000175000017500000000000012152033550022674 5ustar ebourgebourgbouncycastle-1.49.orig/test/src/org/bouncycastle/jcajce/provider/0000755000175000017500000000000012152033550024526 5ustar ebourgebourgbouncycastle-1.49.orig/test/src/org/bouncycastle/jcajce/provider/test/0000755000175000017500000000000012152033550025505 5ustar ebourgebourgbouncycastle-1.49.orig/test/src/org/bouncycastle/jcajce/provider/test/AllTests.java0000644000175000017500000000076212115013454030110 0ustar ebourgebourgpackage org.bouncycastle.jcajce.provider.test; import junit.framework.Test; import junit.framework.TestCase; import junit.framework.TestSuite; public class AllTests extends TestCase { public static void main (String[] args) { junit.textui.TestRunner.run(suite()); } public static Test suite() { TestSuite suite = new TestSuite("JCAJCE Provider Tests"); suite.addTestSuite(PrivateConstructorTest.class); return suite; } } bouncycastle-1.49.orig/test/src/org/bouncycastle/jcajce/provider/test/PrivateConstructorTest.java0000644000175000017500000001344212114015761033076 0ustar ebourgebourgpackage org.bouncycastle.jcajce.provider.test; import java.lang.reflect.Constructor; import java.lang.reflect.InvocationTargetException; import java.lang.reflect.Modifier; import junit.framework.Assert; import junit.framework.TestCase; import org.bouncycastle.jcajce.provider.digest.GOST3411; import org.bouncycastle.jcajce.provider.digest.MD2; import org.bouncycastle.jcajce.provider.digest.MD4; import org.bouncycastle.jcajce.provider.digest.MD5; import org.bouncycastle.jcajce.provider.digest.RIPEMD128; import org.bouncycastle.jcajce.provider.digest.RIPEMD160; import org.bouncycastle.jcajce.provider.digest.RIPEMD256; import org.bouncycastle.jcajce.provider.digest.RIPEMD320; import org.bouncycastle.jcajce.provider.digest.SHA1; import org.bouncycastle.jcajce.provider.digest.SHA224; import org.bouncycastle.jcajce.provider.digest.SHA256; import org.bouncycastle.jcajce.provider.digest.SHA3; import org.bouncycastle.jcajce.provider.digest.SHA384; import org.bouncycastle.jcajce.provider.digest.SHA512; import org.bouncycastle.jcajce.provider.digest.Tiger; import org.bouncycastle.jcajce.provider.digest.Whirlpool; import org.bouncycastle.jcajce.provider.symmetric.AES; import org.bouncycastle.jcajce.provider.symmetric.ARC4; import org.bouncycastle.jcajce.provider.symmetric.Blowfish; import org.bouncycastle.jcajce.provider.symmetric.CAST5; import org.bouncycastle.jcajce.provider.symmetric.CAST6; import org.bouncycastle.jcajce.provider.symmetric.Camellia; import org.bouncycastle.jcajce.provider.symmetric.DES; import org.bouncycastle.jcajce.provider.symmetric.DESede; import org.bouncycastle.jcajce.provider.symmetric.GOST28147; import org.bouncycastle.jcajce.provider.symmetric.Grain128; import org.bouncycastle.jcajce.provider.symmetric.Grainv1; import org.bouncycastle.jcajce.provider.symmetric.HC128; import org.bouncycastle.jcajce.provider.symmetric.HC256; import org.bouncycastle.jcajce.provider.symmetric.IDEA; import org.bouncycastle.jcajce.provider.symmetric.Noekeon; import org.bouncycastle.jcajce.provider.symmetric.PBEPBKDF2; import org.bouncycastle.jcajce.provider.symmetric.PBEPKCS12; import org.bouncycastle.jcajce.provider.symmetric.RC2; import org.bouncycastle.jcajce.provider.symmetric.RC5; import org.bouncycastle.jcajce.provider.symmetric.RC6; import org.bouncycastle.jcajce.provider.symmetric.Rijndael; import org.bouncycastle.jcajce.provider.symmetric.SEED; import org.bouncycastle.jcajce.provider.symmetric.Salsa20; import org.bouncycastle.jcajce.provider.symmetric.Serpent; import org.bouncycastle.jcajce.provider.symmetric.Skipjack; import org.bouncycastle.jcajce.provider.symmetric.TEA; import org.bouncycastle.jcajce.provider.symmetric.Twofish; import org.bouncycastle.jcajce.provider.symmetric.VMPC; import org.bouncycastle.jcajce.provider.symmetric.VMPCKSA3; import org.bouncycastle.jcajce.provider.symmetric.XTEA; public class PrivateConstructorTest extends TestCase { public void testSymmetric() throws Exception { evilNoConstructionTest(AES.class); evilNoConstructionTest(ARC4.class); evilNoConstructionTest(Blowfish.class); evilNoConstructionTest(Camellia.class); evilNoConstructionTest(CAST5.class); evilNoConstructionTest(CAST6.class); evilNoConstructionTest(DESede.class); evilNoConstructionTest(DES.class); evilNoConstructionTest(GOST28147.class); evilNoConstructionTest(Grain128.class); evilNoConstructionTest(Grainv1.class); evilNoConstructionTest(HC128.class); evilNoConstructionTest(HC256.class); evilNoConstructionTest(IDEA.class); evilNoConstructionTest(Noekeon.class); evilNoConstructionTest(PBEPBKDF2.class); evilNoConstructionTest(PBEPKCS12.class); evilNoConstructionTest(RC2.class); evilNoConstructionTest(RC5.class); evilNoConstructionTest(RC6.class); evilNoConstructionTest(Rijndael.class); evilNoConstructionTest(Salsa20.class); evilNoConstructionTest(SEED.class); evilNoConstructionTest(Serpent.class); evilNoConstructionTest(Skipjack.class); evilNoConstructionTest(TEA.class); evilNoConstructionTest(Twofish.class); evilNoConstructionTest(VMPC.class); evilNoConstructionTest(VMPCKSA3.class); evilNoConstructionTest(XTEA.class); } public void testDigest() throws Exception { evilNoConstructionTest(GOST3411.class); evilNoConstructionTest(MD2.class); evilNoConstructionTest(MD4.class); evilNoConstructionTest(MD5.class); evilNoConstructionTest(RIPEMD128.class); evilNoConstructionTest(RIPEMD160.class); evilNoConstructionTest(RIPEMD256.class); evilNoConstructionTest(RIPEMD320.class); evilNoConstructionTest(SHA1.class); evilNoConstructionTest(SHA224.class); evilNoConstructionTest(SHA256.class); evilNoConstructionTest(SHA384.class); evilNoConstructionTest(SHA3.class); evilNoConstructionTest(SHA512.class); evilNoConstructionTest(Tiger.class); evilNoConstructionTest(Whirlpool.class); } private static void evilNoConstructionTest(Class clazz) throws InvocationTargetException, IllegalAccessException, InstantiationException { Constructor[] constructors = clazz.getDeclaredConstructors(); Assert.assertEquals("Class should only have one constructor", 1, constructors.length); Constructor constructor = constructors[0]; Assert.assertEquals("Constructor should be private", Modifier.PRIVATE, constructor.getModifiers()); Assert.assertFalse("Constructor should be inaccessible", constructor.isAccessible()); constructor.setAccessible(true); // don't try this at home Assert.assertEquals("Constructor return type wrong!!", clazz, constructor.newInstance().getClass()); } } bouncycastle-1.49.orig/test/src/org/bouncycastle/mozilla/0000755000175000017500000000000012152033550023124 5ustar ebourgebourgbouncycastle-1.49.orig/test/src/org/bouncycastle/mozilla/test/0000755000175000017500000000000012152033550024103 5ustar ebourgebourgbouncycastle-1.49.orig/test/src/org/bouncycastle/mozilla/test/AllTests.java0000644000175000017500000000203410354623145026507 0ustar ebourgebourgpackage org.bouncycastle.mozilla.test; import java.security.Security; import org.bouncycastle.jce.provider.BouncyCastleProvider; import org.bouncycastle.util.test.SimpleTestResult; import junit.framework.*; public class AllTests extends TestCase { public void testMozilla() { Security.addProvider(new BouncyCastleProvider()); org.bouncycastle.util.test.Test[] tests = new org.bouncycastle.util.test.Test[] { new SPKACTest() }; for (int i = 0; i != tests.length; i++) { SimpleTestResult result = (SimpleTestResult)tests[i].perform(); if (!result.isSuccessful()) { fail(result.toString()); } } } public static void main (String[] args) { junit.textui.TestRunner.run(suite()); } public static Test suite() { TestSuite suite = new TestSuite("Mozilla Tests"); suite.addTestSuite(AllTests.class); return suite; } } bouncycastle-1.49.orig/test/src/org/bouncycastle/mozilla/test/package.html0000644000175000017500000000015010330633061026357 0ustar ebourgebourg Test class for mozilla signed public key and challenge. bouncycastle-1.49.orig/test/src/org/bouncycastle/mozilla/test/SPKACTest.java0000644000175000017500000000646311625103071026460 0ustar ebourgebourgpackage org.bouncycastle.mozilla.test; import java.io.ByteArrayInputStream; import java.io.ByteArrayOutputStream; import java.security.PublicKey; import java.security.Security; import org.bouncycastle.asn1.ASN1InputStream; import org.bouncycastle.asn1.ASN1Primitive; import org.bouncycastle.asn1.DERIA5String; import org.bouncycastle.asn1.DEROutputStream; import org.bouncycastle.asn1.mozilla.PublicKeyAndChallenge; import org.bouncycastle.asn1.x509.SubjectPublicKeyInfo; import org.bouncycastle.jce.provider.BouncyCastleProvider; import org.bouncycastle.mozilla.SignedPublicKeyAndChallenge; import org.bouncycastle.util.encoders.Base64; import org.bouncycastle.util.test.SimpleTest; public class SPKACTest extends SimpleTest { byte[] spkac = Base64.decode( "MIIBOjCBpDCBnzANBgkqhkiG9w0BAQEFAAOBjQAwgYkCgYEApne7ti0ibPhV8Iht"+ "7Pws5iRckM7x4mtZYxEpeX5/IO8tDsBFdY86ewuY2f2KCca0oMWr43kdkZbPyzf4"+ "CSV+0fZm9MJyNMywygZjoOCC+rS8kr0Ef31iHChhYsyejJnjw116Jnn96syhdHY6"+ "lVD1rK0nn5ZkHjxU74gjoZu6BJMCAwEAARYAMA0GCSqGSIb3DQEBBAUAA4GBAKFL"+ "g/luv0C7gMTI8ZKfFoSyi7Q7kiSQcmSj1WJgT56ouIRJO5NdvB/1n4GNik8VOAU0"+ "NRztvGy3ZGqgbSav7lrxcNEvXH+dLbtS97s7yiaozpsOcEHqsBribpLOTRzYa8ci"+ "CwkPmIiYqcby11diKLpd+W9RFYNme2v0rrbM2CyV"); public String getName() { return "SignedPubicKeyAndChallenge"; } public void spkacTest(String testName, byte[] req) throws Exception { SignedPublicKeyAndChallenge spkac; spkac = new SignedPublicKeyAndChallenge(req); PublicKeyAndChallenge pkac = spkac.getPublicKeyAndChallenge(); PublicKey pubKey = spkac.getPublicKey("BC"); ASN1Primitive obj = pkac.toASN1Primitive(); if (obj == null) { fail("Error - " + testName + " PKAC ASN1Primitive was null."); } obj = spkac.toASN1Primitive(); if (obj == null) { fail("Error - "+testName+ " SPKAC ASN1Primitive was null."); } SubjectPublicKeyInfo spki = pkac.getSubjectPublicKeyInfo(); if (spki == null) { fail("Error - "+testName + " SubjectPublicKeyInfo was null."); } DERIA5String challenge = pkac.getChallenge(); // Most cases this will be a string of length zero. if (challenge == null) { fail(":Error - "+testName+ " challenge was null."); } ByteArrayInputStream bIn = new ByteArrayInputStream(req); ASN1InputStream dIn = new ASN1InputStream(bIn); ByteArrayOutputStream bOut = new ByteArrayOutputStream(); DEROutputStream dOut = new DEROutputStream(bOut); dOut.writeObject(spkac.toASN1Primitive()); byte[] bytes = bOut.toByteArray(); if (bytes.length != req.length) { fail(testName + " failed length test"); } for (int i = 0; i != req.length; i++) { if (bytes[i] != req[i]) { fail(testName + " failed comparison test"); } } if (!spkac.verify("BC")) { fail(testName + " verification failed"); } } public void performTest() throws Exception { spkacTest("spkac", spkac); } public static void main(String[] args) { Security.addProvider(new BouncyCastleProvider()); runTest(new SPKACTest()); } } bouncycastle-1.49.orig/test/src/org/bouncycastle/pkcs/0000755000175000017500000000000012152033550022415 5ustar ebourgebourgbouncycastle-1.49.orig/test/src/org/bouncycastle/pkcs/test/0000755000175000017500000000000012152033550023374 5ustar ebourgebourgbouncycastle-1.49.orig/test/src/org/bouncycastle/pkcs/test/PKCS10Test.java0000644000175000017500000000710012116547320026003 0ustar ebourgebourgpackage org.bouncycastle.pkcs.test; import java.math.BigInteger; import java.security.KeyFactory; import java.security.PrivateKey; import java.security.PublicKey; import java.security.spec.RSAPrivateCrtKeySpec; import java.security.spec.RSAPublicKeySpec; import junit.framework.Test; import junit.framework.TestCase; import junit.framework.TestSuite; import org.bouncycastle.asn1.pkcs.CertificationRequest; import org.bouncycastle.asn1.x500.X500Name; import org.bouncycastle.operator.jcajce.JcaContentSignerBuilder; import org.bouncycastle.pkcs.PKCS10CertificationRequest; import org.bouncycastle.pkcs.PKCS10CertificationRequestBuilder; import org.bouncycastle.pkcs.jcajce.JcaPKCS10CertificationRequestBuilder; public class PKCS10Test extends TestCase { // // personal keys // private static final RSAPublicKeySpec pubKeySpec = new RSAPublicKeySpec( new BigInteger("b4a7e46170574f16a97082b22be58b6a2a629798419be12872a4bdba626cfae9900f76abfb12139dce5de56564fab2b6543165a040c606887420e33d91ed7ed7", 16), new BigInteger("11", 16)); private static final RSAPrivateCrtKeySpec privKeySpec = new RSAPrivateCrtKeySpec( new BigInteger("b4a7e46170574f16a97082b22be58b6a2a629798419be12872a4bdba626cfae9900f76abfb12139dce5de56564fab2b6543165a040c606887420e33d91ed7ed7", 16), new BigInteger("11", 16), new BigInteger("9f66f6b05410cd503b2709e88115d55daced94d1a34d4e32bf824d0dde6028ae79c5f07b580f5dce240d7111f7ddb130a7945cd7d957d1920994da389f490c89", 16), new BigInteger("c0a0758cdf14256f78d4708c86becdead1b50ad4ad6c5c703e2168fbf37884cb", 16), new BigInteger("f01734d7960ea60070f1b06f2bb81bfac48ff192ae18451d5e56c734a5aab8a5", 16), new BigInteger("b54bb9edff22051d9ee60f9351a48591b6500a319429c069a3e335a1d6171391", 16), new BigInteger("d3d83daf2a0cecd3367ae6f8ae1aeb82e9ac2f816c6fc483533d8297dd7884cd", 16), new BigInteger("b8f52fc6f38593dabb661d3f50f8897f8106eee68b1bce78a95b132b4e5b5d19", 16)); public void testLeaveOffEmpty() throws Exception { KeyFactory keyFact = KeyFactory.getInstance("RSA", "BC"); PublicKey pubKey = keyFact.generatePublic(pubKeySpec); PrivateKey privKey = keyFact.generatePrivate(privKeySpec); PKCS10CertificationRequestBuilder pkcs10Builder = new JcaPKCS10CertificationRequestBuilder(new X500Name("CN=Test"), pubKey); PKCS10CertificationRequest request = pkcs10Builder.build(new JcaContentSignerBuilder("SHA1withRSA").setProvider("BC").build(privKey)); assertEquals(0, request.getAttributes().length); assertNotNull(CertificationRequest.getInstance(request.getEncoded()).getCertificationRequestInfo().getAttributes()); pkcs10Builder.setLeaveOffEmptyAttributes(true); request = pkcs10Builder.build(new JcaContentSignerBuilder("SHA1withRSA").setProvider("BC").build(privKey)); assertEquals(0, request.getAttributes().length); assertNull(CertificationRequest.getInstance(request.getEncoded()).getCertificationRequestInfo().getAttributes()); pkcs10Builder.setLeaveOffEmptyAttributes(false); request = pkcs10Builder.build(new JcaContentSignerBuilder("SHA1withRSA").setProvider("BC").build(privKey)); assertEquals(0, request.getAttributes().length); assertNotNull(CertificationRequest.getInstance(request.getEncoded()).getCertificationRequestInfo().getAttributes()); } public static void main(String args[]) { junit.textui.TestRunner.run(suite()); } public static Test suite() { return new BCTestSetup(new TestSuite(PKCS10Test.class)); } } bouncycastle-1.49.orig/test/src/org/bouncycastle/pkcs/test/AllTests.java0000644000175000017500000000101712132652246026000 0ustar ebourgebourgpackage org.bouncycastle.pkcs.test; import junit.framework.Test; import junit.framework.TestCase; import junit.framework.TestSuite; public class AllTests extends TestCase { public static void main (String[] args) { junit.textui.TestRunner.run(suite()); } public static Test suite() { TestSuite suite = new TestSuite("PKCS Tests"); suite.addTestSuite(PfxPduTest.class); suite.addTestSuite(PKCS10Test.class); return new BCTestSetup(suite); } } bouncycastle-1.49.orig/test/src/org/bouncycastle/pkcs/test/PfxPduTest.java0000644000175000017500000015705712116551172026331 0ustar ebourgebourgpackage org.bouncycastle.pkcs.test; import java.io.ByteArrayInputStream; import java.io.IOException; import java.math.BigInteger; import java.security.KeyFactory; import java.security.KeyStore; import java.security.NoSuchAlgorithmException; import java.security.PrivateKey; import java.security.PublicKey; import java.security.cert.Certificate; import java.security.cert.X509Certificate; import java.security.spec.RSAPrivateCrtKeySpec; import java.security.spec.RSAPublicKeySpec; import java.util.Date; import junit.framework.TestCase; import org.bouncycastle.asn1.ASN1Encodable; import org.bouncycastle.asn1.ASN1Encoding; import org.bouncycastle.asn1.DERBMPString; import org.bouncycastle.asn1.DERSequence; import org.bouncycastle.asn1.nist.NISTObjectIdentifiers; import org.bouncycastle.asn1.pkcs.Attribute; import org.bouncycastle.asn1.pkcs.ContentInfo; import org.bouncycastle.asn1.pkcs.PKCSObjectIdentifiers; import org.bouncycastle.asn1.pkcs.PrivateKeyInfo; import org.bouncycastle.asn1.x500.X500Name; import org.bouncycastle.asn1.x500.X500NameBuilder; import org.bouncycastle.asn1.x500.style.BCStyle; import org.bouncycastle.asn1.x509.BasicConstraints; import org.bouncycastle.asn1.x509.Extension; import org.bouncycastle.asn1.x509.SubjectKeyIdentifier; import org.bouncycastle.cert.X509CertificateHolder; import org.bouncycastle.cert.X509v1CertificateBuilder; import org.bouncycastle.cert.X509v3CertificateBuilder; import org.bouncycastle.cert.jcajce.JcaX500NameUtil; import org.bouncycastle.cert.jcajce.JcaX509CertificateConverter; import org.bouncycastle.cert.jcajce.JcaX509ExtensionUtils; import org.bouncycastle.cert.jcajce.JcaX509v1CertificateBuilder; import org.bouncycastle.cert.jcajce.JcaX509v3CertificateBuilder; import org.bouncycastle.crypto.engines.DESedeEngine; import org.bouncycastle.crypto.engines.RC2Engine; import org.bouncycastle.crypto.modes.CBCBlockCipher; import org.bouncycastle.jce.provider.BouncyCastleProvider; import org.bouncycastle.operator.InputDecryptorProvider; import org.bouncycastle.operator.OutputEncryptor; import org.bouncycastle.operator.bc.BcDefaultDigestProvider; import org.bouncycastle.operator.jcajce.JcaContentSignerBuilder; import org.bouncycastle.pkcs.PKCS12PfxPdu; import org.bouncycastle.pkcs.PKCS12PfxPduBuilder; import org.bouncycastle.pkcs.PKCS12SafeBag; import org.bouncycastle.pkcs.PKCS12SafeBagBuilder; import org.bouncycastle.pkcs.PKCS12SafeBagFactory; import org.bouncycastle.pkcs.PKCS8EncryptedPrivateKeyInfo; import org.bouncycastle.pkcs.PKCS8EncryptedPrivateKeyInfoBuilder; import org.bouncycastle.pkcs.PKCSException; import org.bouncycastle.pkcs.bc.BcPKCS12MacCalculatorBuilder; import org.bouncycastle.pkcs.bc.BcPKCS12MacCalculatorBuilderProvider; import org.bouncycastle.pkcs.bc.BcPKCS12PBEInputDecryptorProviderBuilder; import org.bouncycastle.pkcs.bc.BcPKCS12PBEOutputEncryptorBuilder; import org.bouncycastle.pkcs.jcajce.JcaPKCS12SafeBagBuilder; import org.bouncycastle.pkcs.jcajce.JcaPKCS8EncryptedPrivateKeyInfoBuilder; import org.bouncycastle.pkcs.jcajce.JcePKCS12MacCalculatorBuilder; import org.bouncycastle.pkcs.jcajce.JcePKCS12MacCalculatorBuilderProvider; import org.bouncycastle.pkcs.jcajce.JcePKCSPBEInputDecryptorProviderBuilder; import org.bouncycastle.pkcs.jcajce.JcePKCSPBEOutputEncryptorBuilder; import org.bouncycastle.util.Arrays; import org.bouncycastle.util.encoders.Base64; public class PfxPduTest extends TestCase { private static final String BC = BouncyCastleProvider.PROVIDER_NAME; private static final char[] passwd = {'h', 'e', 'l', 'l', 'o', ' ', 'w', 'o', 'r', 'l', 'd'}; // // personal keys // private static final RSAPublicKeySpec pubKeySpec = new RSAPublicKeySpec( new BigInteger("b4a7e46170574f16a97082b22be58b6a2a629798419be12872a4bdba626cfae9900f76abfb12139dce5de56564fab2b6543165a040c606887420e33d91ed7ed7", 16), new BigInteger("11", 16)); private static final RSAPrivateCrtKeySpec privKeySpec = new RSAPrivateCrtKeySpec( new BigInteger("b4a7e46170574f16a97082b22be58b6a2a629798419be12872a4bdba626cfae9900f76abfb12139dce5de56564fab2b6543165a040c606887420e33d91ed7ed7", 16), new BigInteger("11", 16), new BigInteger("9f66f6b05410cd503b2709e88115d55daced94d1a34d4e32bf824d0dde6028ae79c5f07b580f5dce240d7111f7ddb130a7945cd7d957d1920994da389f490c89", 16), new BigInteger("c0a0758cdf14256f78d4708c86becdead1b50ad4ad6c5c703e2168fbf37884cb", 16), new BigInteger("f01734d7960ea60070f1b06f2bb81bfac48ff192ae18451d5e56c734a5aab8a5", 16), new BigInteger("b54bb9edff22051d9ee60f9351a48591b6500a319429c069a3e335a1d6171391", 16), new BigInteger("d3d83daf2a0cecd3367ae6f8ae1aeb82e9ac2f816c6fc483533d8297dd7884cd", 16), new BigInteger("b8f52fc6f38593dabb661d3f50f8897f8106eee68b1bce78a95b132b4e5b5d19", 16)); // // intermediate keys. // private static final RSAPublicKeySpec intPubKeySpec = new RSAPublicKeySpec( new BigInteger("8de0d113c5e736969c8d2b047a243f8fe18edad64cde9e842d3669230ca486f7cfdde1f8eec54d1905fff04acc85e61093e180cadc6cea407f193d44bb0e9449b8dbb49784cd9e36260c39e06a947299978c6ed8300724e887198cfede20f3fbde658fa2bd078be946a392bd349f2b49c486e20c405588e306706c9017308e69", 16), new BigInteger("ffff", 16)); private static final RSAPrivateCrtKeySpec intPrivKeySpec = new RSAPrivateCrtKeySpec( new BigInteger("8de0d113c5e736969c8d2b047a243f8fe18edad64cde9e842d3669230ca486f7cfdde1f8eec54d1905fff04acc85e61093e180cadc6cea407f193d44bb0e9449b8dbb49784cd9e36260c39e06a947299978c6ed8300724e887198cfede20f3fbde658fa2bd078be946a392bd349f2b49c486e20c405588e306706c9017308e69", 16), new BigInteger("ffff", 16), new BigInteger("7deb1b194a85bcfd29cf871411468adbc987650903e3bacc8338c449ca7b32efd39ffc33bc84412fcd7df18d23ce9d7c25ea910b1ae9985373e0273b4dca7f2e0db3b7314056ac67fd277f8f89cf2fd73c34c6ca69f9ba477143d2b0e2445548aa0b4a8473095182631da46844c356f5e5c7522eb54b5a33f11d730ead9c0cff", 16), new BigInteger("ef4cede573cea47f83699b814de4302edb60eefe426c52e17bd7870ec7c6b7a24fe55282ebb73775f369157726fcfb988def2b40350bdca9e5b418340288f649", 16), new BigInteger("97c7737d1b9a0088c3c7b528539247fd2a1593e7e01cef18848755be82f4a45aa093276cb0cbf118cb41117540a78f3fc471ba5d69f0042274defc9161265721", 16), new BigInteger("6c641094e24d172728b8da3c2777e69adfd0839085be7e38c7c4a2dd00b1ae969f2ec9d23e7e37090fcd449a40af0ed463fe1c612d6810d6b4f58b7bfa31eb5f", 16), new BigInteger("70b7123e8e69dfa76feb1236d0a686144b00e9232ed52b73847e74ef3af71fb45ccb24261f40d27f98101e230cf27b977a5d5f1f15f6cf48d5cb1da2a3a3b87f", 16), new BigInteger("e38f5750d97e270996a286df2e653fd26c242106436f5bab0f4c7a9e654ce02665d5a281f2c412456f2d1fa26586ef04a9adac9004ca7f913162cb28e13bf40d", 16)); // // ca keys // private static final RSAPublicKeySpec caPubKeySpec = new RSAPublicKeySpec( new BigInteger("b259d2d6e627a768c94be36164c2d9fc79d97aab9253140e5bf17751197731d6f7540d2509e7b9ffee0a70a6e26d56e92d2edd7f85aba85600b69089f35f6bdbf3c298e05842535d9f064e6b0391cb7d306e0a2d20c4dfb4e7b49a9640bdea26c10ad69c3f05007ce2513cee44cfe01998e62b6c3637d3fc0391079b26ee36d5", 16), new BigInteger("11", 16)); private static final RSAPrivateCrtKeySpec caPrivKeySpec = new RSAPrivateCrtKeySpec( new BigInteger("b259d2d6e627a768c94be36164c2d9fc79d97aab9253140e5bf17751197731d6f7540d2509e7b9ffee0a70a6e26d56e92d2edd7f85aba85600b69089f35f6bdbf3c298e05842535d9f064e6b0391cb7d306e0a2d20c4dfb4e7b49a9640bdea26c10ad69c3f05007ce2513cee44cfe01998e62b6c3637d3fc0391079b26ee36d5", 16), new BigInteger("11", 16), new BigInteger("92e08f83cc9920746989ca5034dcb384a094fb9c5a6288fcc4304424ab8f56388f72652d8fafc65a4b9020896f2cde297080f2a540e7b7ce5af0b3446e1258d1dd7f245cf54124b4c6e17da21b90a0ebd22605e6f45c9f136d7a13eaac1c0f7487de8bd6d924972408ebb58af71e76fd7b012a8d0e165f3ae2e5077a8648e619", 16), new BigInteger("f75e80839b9b9379f1cf1128f321639757dba514642c206bbbd99f9a4846208b3e93fbbe5e0527cc59b1d4b929d9555853004c7c8b30ee6a213c3d1bb7415d03", 16), new BigInteger("b892d9ebdbfc37e397256dd8a5d3123534d1f03726284743ddc6be3a709edb696fc40c7d902ed804c6eee730eee3d5b20bf6bd8d87a296813c87d3b3cc9d7947", 16), new BigInteger("1d1a2d3ca8e52068b3094d501c9a842fec37f54db16e9a67070a8b3f53cc03d4257ad252a1a640eadd603724d7bf3737914b544ae332eedf4f34436cac25ceb5", 16), new BigInteger("6c929e4e81672fef49d9c825163fec97c4b7ba7acb26c0824638ac22605d7201c94625770984f78a56e6e25904fe7db407099cad9b14588841b94f5ab498dded", 16), new BigInteger("dae7651ee69ad1d081ec5e7188ae126f6004ff39556bde90e0b870962fa7b926d070686d8244fe5a9aa709a95686a104614834b0ada4b10f53197a5cb4c97339", 16)); // // pkcs-12 pfx-pdu // private String pkcs12Pass = "hello world"; private byte[] pkcs12 = Base64.decode( "MIACAQMwgAYJKoZIhvcNAQcBoIAkgAQBMAQBgAQBMAQBgAQBBgQBCQQJKoZI" + "hvcNAQcBBAGgBAGABAEkBAGABAEEBAEBBAEwBAEEBAEDBAOCAzQEAQQEAQEE" + "ATAEAQQEAQMEA4IDMAQBBAQBAQQBBgQBBAQBAQQBCwQBBAQBCwQLKoZIhvcN" + "AQwKAQIEAQQEAQEEAaAEAQQEAQMEA4ICpQQBBAQBAQQBMAQBBAQBAwQDggKh" + "BAEEBAEBBAEwBAEEBAEBBAEbBAEEBAEBBAEGBAEEBAEBBAEKBAEEBAEKBAoq" + "hkiG9w0BDAEDBAEEBAEPBA8wDQQIoagiwNZPJR4CAQEEAQQEAQEEAQQEAQQE" + "AQMEA4ICgAQBBAQDggKABIICgEPG0XlhMFyrs4ZWDrvEzl51ICfXd6K2ql2l" + "nnxhszUbigtSj6x49VEx4PfOB9fQFeidc5L5An+nKp646NBMIY0UwXGs8BLQ" + "au59jtOs987+l7QYIvl6fdGUIuLPhVSnZZDyqD+HQjU/0/ccKFHRif4tlEQq" + "aErvZbFeH0pg4ijf1HfgX6gBJGRKdO+msa4qKGnZdHCSLZehyyxvxAmURetg" + "yhtEl7RmedTB+4TDs7atekqxkNlD9tfwDUX6sb0IH6qbEA6P/DlVMdaD54Cl" + "QDxRzOfIIjklZhv5OMFWtPK0aYPcqyxzLpw1qRAyoTVXpidkj/hpIpgCVBP/" + "k5s2+WdGbLgA/4/zSrF6feRCE5llzM2IGxiHVq4oPzzngl3R+Fi5VCPDMcuW" + "NRuIOzJA+RNV2NPOE/P3knThDnwiImq+rfxmvZ1u6T06s20RmWK6cxp7fTEw" + "lQ9BOsv+mmyV8dr6cYJq4IlRzHdFOyEUBDwfHThyribNKKobO50xh2f93xYj" + "Rn5UMOQBJIe3b7OKZt5HOIMrJSZO02IZgvImi9yQWi96PnWa419D1cAsLWvM" + "xiN0HqZMbDFfxVM2BZmsxiexLhkHWKwLqfQDzRjJfmVww8fnXpWZhFXKyut9" + "gMGEyCNoba4RU3QI/wHKWYaK74qtJpsucuLWBH6UcsHsCry6VZkwRxWwC0lb" + "/F3Bm5UKHax5n9JHJ2amQm9zW3WJ0S5stpPObfmg5ArhbPY+pVOsTqBRlop1" + "bYJLD/X8Qbs468Bwzej0FhoEU59ZxFrbjLSBsMUYrVrwD83JE9kEazMLVchc" + "uCB9WT1g0hxYb7VA0BhOrWhL8F5ZH72RMCYLPI0EAQQEAQEEATEEAQQEAQEE" + "AXgEAQQEAQEEATAEAQQEAQEEAVEEAQQEAQEEAQYEAQQEAQEEAQkEAQQEAQkE" + "CSqGSIb3DQEJFAQBBAQBAQQBMQQBBAQBAQQBRAQBBAQBAQQBHgQBBAQBAQQB" + "QgQBBAQBQgRCAEQAYQB2AGkAZAAgAEcALgAgAEgAbwBvAGsAJwBzACAAVgBl" + "AHIAaQBTAGkAZwBuACwAIABJAG4AYwAuACAASQBEBAEEBAEBBAEwBAEEBAEB" + "BAEjBAEEBAEBBAEGBAEEBAEBBAEJBAEEBAEJBAkqhkiG9w0BCRUEAQQEAQEE" + "ATEEAQQEAQEEARYEAQQEAQEEAQQEAQQEAQEEARQEAQQEARQEFKEcMJ798oZL" + "FkH0OnpbUBnrTLgWBAIAAAQCAAAEAgAABAEwBAGABAEGBAEJBAkqhkiG9w0B" + "BwYEAaAEAYAEATAEAYAEAQIEAQEEAQAEATAEAYAEAQYEAQkECSqGSIb3DQEH" + "AQQBMAQBGwQBBgQBCgQKKoZIhvcNAQwBBgQPMA0ECEE7euvmxxwYAgEBBAGg" + "BAGABAEEBAEIBAgQIWDGlBWxnwQBBAQBCAQI2WsMhavhSCcEAQQEAQgECPol" + "uHJy9bm/BAEEBAEQBBCiRxtllKXkJS2anKD2q3FHBAEEBAEIBAjKy6BRFysf" + "7gQBBAQDggMwBIIDMJWRGu2ZLZild3oz7UBdpBDUVMOA6eSoWiRIfVTo4++l" + "RUBm8TpmmGrVkV32PEoLkoV+reqlyWCvqqSjRzi3epQiVwPQ6PV+ccLqxDhV" + "pGWDRQ5UttDBC2+u4fUQVZi2Z1i1g2tsk6SzB3MKUCrjoWKvaDUUwXo5k9Vz" + "qSLWCLTZCjs3RaY+jg3NbLZYtfMDdYovhCU2jMYV9adJ8MxxmJRz+zPWAJph" + "LH8hhfkKG+wJOSszqk9BqGZUa/mnZyzeQSMTEFga1ZB/kt2e8SZFWrTZEBgJ" + "oszsL5MObbwMDowNurnZsnS+Mf7xi01LeG0VT1fjd6rn9BzVwuMwhoqyoCNo" + "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"); private String sha256Pass = "D317F8D5191F2602C527F8E6E0E8855C4517EC9512F7A06A7A588ACF0B3A6325"; private byte[] sha256Pfx = Base64.decode( "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"); private String pkcs5Pass = "hello"; private byte[] pkcs5Aes128Pfx = Base64.decode( "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" + "gw8dRrSS4gQISYYYgNAwxl0CAggA"); private byte[] pkcs5Aes192Pfx = Base64.decode( "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" + "4EPgRMGPtQQItR+KgKM/oRMCAggA"); private byte[] pkcs5Camellia128Pfx = Base64.decode( "MIIFswIBAzCCBXkGCSqGSIb3DQEHAaCCBWoEggVmMIIFYjCCAxcGCSqGSIb3" + "DQEHBqCCAwgwggMEAgEAMIIC/QYJKoZIhvcNAQcBMBwGCiqGSIb3DQEMAQYw" + "DgQIq+wFOOOtSokCAggAgIIC0IWDRpk4L/tSSMfwWx0mN3ecbaL+m2XZWvN9" + "hK1K5PghAYquCs36l603cYSV9pypOkGC5rn1d2fyZCFhUMOObSC7V/mpkitr" + "OfOYpaW7tU1JJecpONgIHlbd8N4fbBtH73E7vdmi6X/tg4Tl7yJf40fruYVq" + "yzqfJCO2aGJIFv6JWsFivjCwehBa+6ppCHBnNcj4SsVlozj1y2B0Wl2TVi3r" + "joBIsK2RQ+RMjM55k3pS57mV+jXtd29wb2q9utDKogvpBCboTk8dPMFcFGWz" + "2D41onJoEJKizAEIgXiS7UvqHddhIL9O/rSZ68j2d2GcFi1Oxer1PyZoCI61" + "CpZdk2QeNeVaVFTPJ26We6J34w2ivZwHOhn+iUZ7q0Sm9gcYa1QRG79LA/AC" + "nE3Xxzl4nEjRRi5AKb6IOnMKBbr0povesS8tL323x91uPZc0jMctC6Q+vegX" + "tIZ7dZPuNxhqRHqb62LSm11cpYQWibj16rRQ0ulOFSQGIr514PvfbIig6oo8" + "niwHuefp/ey/Zvl/dAl+um2UkVdR9Mwn8vTM8oMF+ptJfpWyZEIrP785Rpu3" + "oyBMyEYA2djX7JsFvoCxKxGCC5VK3C/9EFv9xUGmiV0zrTPcHb1P4sK1AJyI" + "vhSY+Tgv+Fjq5KoPCa4ZXP+Y+vSzkttcP8u7x0wt9cblvgzdBy9Ee1xqCdJd" + "F67U6vbQ6ErDrdVAwtRqc0TsPKG1XH5NFtxTwILyCeh8XzdYMIaHkEnTuITQ" + "eeICaUJ2YPZrADLxXTNHI9e6dVcDvhjf/JfBXZfiiqFH8XmbCIMqyGSGTmQr" + "8uwb8cquLMS78RbXSHLNcv+f/DmPOClNjmWgVAYxaDuw5lZBaU+YDyZaKEy2" + "Mdjd+lR/g2LZhvAEfcM3V4bzr17s0GOSwJ5/5yzczPKZZ8auMwML+Bcmoggt" + "EJgubVFHg/3l11xVe2djfg78CTCCAkMGCSqGSIb3DQEHAaCCAjQEggIwMIIC" + "LDCCAigGCyqGSIb3DQEMCgECoIIBtTCCAbEwSwYJKoZIhvcNAQUNMD4wGwYJ" + "KoZIhvcNAQUMMA4ECInc03N3q5vSAgIIADAfBgsqgwiMmks9AQEBAgQQR+Uo" + "WVvmSL5AcwwRq6vtOQSCAWD0Ms1i2wHGaFi6qUWLqA5EnmYFwqwQQlfz5To+" + "FwVEpHQHrqd0pehOt1J9vyDVYwfjU8DUOJDovCiBIzRsopyf0Qp5hcZnaTDw" + "YJSNd3pIAYiEUAzfdtC7tQw2v0aLt5X/7zthEcoRtTe061dK8DhbV4fALWa9" + "VF2E91L35+wq52DblvpJHBw28PHTbuhfJZsNshXKO7qU7uk+UR6V/Pwc7rsp" + "x/TQ35fVfm7v53rapdHlMVyY4Bx/4fdEWV9aK1cV3qOfiBMByxt8WD0xBLoc" + "Yy3qo3+k/N7q6t4hqjus3LPVrmCbpgAe5S5EkDgnjy7Mpz19tf7hhzL957p2" + "ecWregvR9rQHoWZNOaxS2e2hdOiZUPSxIJ46nOJyCnoZQHG0CFVEwwJkGcWf" + "Thjz38U203IRzuCPgsO1f8wjSXXMp4xJQtJW2TqMm+5/aaDtuXAsUGqQzGiH" + "DQfUs4z/PCKyMWAwIwYJKoZIhvcNAQkVMRYEFKm5GgFnzYtYLITaZeZPkaaT" + "XG/4MDkGCSqGSIb3DQEJFDEsHioAdABlAHMAdABAAGIAbwB1AG4AYwB5AGMA" + "YQBzAHQAbABlAC4AbwByAGcwMTAhMAkGBSsOAwIaBQAEFHIzAiyzoVOmPvLE" + "XCD2HHG5MC23BAhhHlFnklHZYgICCAA="); private byte[] pkcs5Camellia256Pfx = Base64.decode( "MIIFswIBAzCCBXkGCSqGSIb3DQEHAaCCBWoEggVmMIIFYjCCAxcGCSqGSIb3" + "DQEHBqCCAwgwggMEAgEAMIIC/QYJKoZIhvcNAQcBMBwGCiqGSIb3DQEMAQYw" + "DgQIq+wFOOOtSokCAggAgIIC0IWDRpk4L/tSSMfwWx0mN3ecbaL+m2XZWvN9" + "hK1K5PghAYquCs36l603cYSV9pypOkGC5rn1d2fyZCFhUMOObSC7V/mpkitr" + "OfOYpaW7tU1JJecpONgIHlbd8N4fbBtH73E7vdmi6X/tg4Tl7yJf40fruYVq" + "yzqfJCO2aGJIFv6JWsFivjCwehBa+6ppCHBnNcj4SsVlozj1y2B0Wl2TVi3r" + "joBIsK2RQ+RMjM55k3pS57mV+jXtd29wb2q9utDKogvpBCboTk8dPMFcFGWz" + "2D41onJoEJKizAEIgXiS7UvqHddhIL9O/rSZ68j2d2GcFi1Oxer1PyZoCI61" + "CpZdk2QeNeVaVFTPJ26We6J34w2ivZwHOhn+iUZ7q0Sm9gcYa1QRG79LA/AC" + "nE3Xxzl4nEjRRi5AKb6IOnMKBbr0povesS8tL323x91uPZc0jMctC6Q+vegX" + "tIZ7dZPuNxhqRHqb62LSm11cpYQWibj16rRQ0ulOFSQGIr514PvfbIig6oo8" + "niwHuefp/ey/Zvl/dAl+um2UkVdR9Mwn8vTM8oMF+ptJfpWyZEIrP785Rpu3" + "oyBMyEYA2djX7JsFvoCxKxGCC5VK3C/9EFv9xUGmiV0zrTPcHb1P4sK1AJyI" + "vhSY+Tgv+Fjq5KoPCa4ZXP+Y+vSzkttcP8u7x0wt9cblvgzdBy9Ee1xqCdJd" + "F67U6vbQ6ErDrdVAwtRqc0TsPKG1XH5NFtxTwILyCeh8XzdYMIaHkEnTuITQ" + "eeICaUJ2YPZrADLxXTNHI9e6dVcDvhjf/JfBXZfiiqFH8XmbCIMqyGSGTmQr" + "8uwb8cquLMS78RbXSHLNcv+f/DmPOClNjmWgVAYxaDuw5lZBaU+YDyZaKEy2" + "Mdjd+lR/g2LZhvAEfcM3V4bzr17s0GOSwJ5/5yzczPKZZ8auMwML+Bcmoggt" + "EJgubVFHg/3l11xVe2djfg78CTCCAkMGCSqGSIb3DQEHAaCCAjQEggIwMIIC" + "LDCCAigGCyqGSIb3DQEMCgECoIIBtTCCAbEwSwYJKoZIhvcNAQUNMD4wGwYJ" + "KoZIhvcNAQUMMA4ECInc03N3q5vSAgIIADAfBgsqgwiMmks9AQEBAgQQR+Uo" + "WVvmSL5AcwwRq6vtOQSCAWD0Ms1i2wHGaFi6qUWLqA5EnmYFwqwQQlfz5To+" + "FwVEpHQHrqd0pehOt1J9vyDVYwfjU8DUOJDovCiBIzRsopyf0Qp5hcZnaTDw" + "YJSNd3pIAYiEUAzfdtC7tQw2v0aLt5X/7zthEcoRtTe061dK8DhbV4fALWa9" + "VF2E91L35+wq52DblvpJHBw28PHTbuhfJZsNshXKO7qU7uk+UR6V/Pwc7rsp" + "x/TQ35fVfm7v53rapdHlMVyY4Bx/4fdEWV9aK1cV3qOfiBMByxt8WD0xBLoc" + "Yy3qo3+k/N7q6t4hqjus3LPVrmCbpgAe5S5EkDgnjy7Mpz19tf7hhzL957p2" + "ecWregvR9rQHoWZNOaxS2e2hdOiZUPSxIJ46nOJyCnoZQHG0CFVEwwJkGcWf" + "Thjz38U203IRzuCPgsO1f8wjSXXMp4xJQtJW2TqMm+5/aaDtuXAsUGqQzGiH" + "DQfUs4z/PCKyMWAwIwYJKoZIhvcNAQkVMRYEFKm5GgFnzYtYLITaZeZPkaaT" + "XG/4MDkGCSqGSIb3DQEJFDEsHioAdABlAHMAdABAAGIAbwB1AG4AYwB5AGMA" + "YQBzAHQAbABlAC4AbwByAGcwMTAhMAkGBSsOAwIaBQAEFHIzAiyzoVOmPvLE" + "XCD2HHG5MC23BAhhHlFnklHZYgICCAA="); private byte[] pkcs5Cast5Pfx = Base64.decode( "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" + "CKHZUIQsQX9hAgIIAA=="); /** * we generate the CA's certificate */ public static X509Certificate createMasterCert( PublicKey pubKey, PrivateKey privKey) throws Exception { // // signers name // String issuer = "C=AU, O=The Legion of the Bouncy Castle, OU=Bouncy Primary Certificate"; // // subjects name - the same as we are self signed. // String subject = "C=AU, O=The Legion of the Bouncy Castle, OU=Bouncy Primary Certificate"; // // create the certificate - version 1 // X509v1CertificateBuilder v1CertBuilder = new JcaX509v1CertificateBuilder( new X500Name(issuer), BigInteger.valueOf(1), new Date(System.currentTimeMillis() - 1000L * 60 * 60 * 24 * 30), new Date(System.currentTimeMillis() + (1000L * 60 * 60 * 24 * 30)), new X500Name(subject), pubKey); X509CertificateHolder cert = v1CertBuilder.build(new JcaContentSignerBuilder("SHA1withRSA").setProvider(BC).build(privKey)); return new JcaX509CertificateConverter().setProvider(BC).getCertificate(cert); } /** * we generate an intermediate certificate signed by our CA */ public static X509Certificate createIntermediateCert( PublicKey pubKey, PrivateKey caPrivKey, X509Certificate caCert) throws Exception { // // subject name builder. // X500NameBuilder subjectBuilder = new X500NameBuilder(BCStyle.INSTANCE); subjectBuilder.addRDN(BCStyle.C, "AU"); subjectBuilder.addRDN(BCStyle.O, "The Legion of the Bouncy Castle"); subjectBuilder.addRDN(BCStyle.OU, "Bouncy Intermediate Certificate"); subjectBuilder.addRDN(BCStyle.EmailAddress, "feedback-crypto@bouncycastle.org"); // // create the certificate - version 3 // X509v3CertificateBuilder v3CertBuilder = new JcaX509v3CertificateBuilder( JcaX500NameUtil.getIssuer(caCert), BigInteger.valueOf(2), new Date(System.currentTimeMillis() - 1000L * 60 * 60 * 24 * 30), new Date(System.currentTimeMillis() + (1000L * 60 * 60 * 24 * 30)), subjectBuilder.build(), pubKey); // // extensions // JcaX509ExtensionUtils utils = new JcaX509ExtensionUtils(); v3CertBuilder.addExtension( Extension.subjectKeyIdentifier, false, utils.createSubjectKeyIdentifier(pubKey)); v3CertBuilder.addExtension( Extension.authorityKeyIdentifier, false, utils.createAuthorityKeyIdentifier(caCert)); v3CertBuilder.addExtension( Extension.basicConstraints, true, new BasicConstraints(0)); X509CertificateHolder cert = v3CertBuilder.build(new JcaContentSignerBuilder("SHA1withRSA").setProvider(BC).build(caPrivKey)); return new JcaX509CertificateConverter().setProvider(BC).getCertificate(cert); } /** * we generate a certificate signed by our CA's intermediate certficate */ public static X509Certificate createCert( PublicKey pubKey, PrivateKey caPrivKey, PublicKey caPubKey) throws Exception { // // signer name builder. // X500NameBuilder issuerBuilder = new X500NameBuilder(BCStyle.INSTANCE); issuerBuilder.addRDN(BCStyle.C, "AU"); issuerBuilder.addRDN(BCStyle.O, "The Legion of the Bouncy Castle"); issuerBuilder.addRDN(BCStyle.OU, "Bouncy Intermediate Certificate"); issuerBuilder.addRDN(BCStyle.EmailAddress, "feedback-crypto@bouncycastle.org"); // // subject name builder // X500NameBuilder subjectBuilder = new X500NameBuilder(BCStyle.INSTANCE); subjectBuilder.addRDN(BCStyle.C, "AU"); subjectBuilder.addRDN(BCStyle.O, "The Legion of the Bouncy Castle"); subjectBuilder.addRDN(BCStyle.L, "Melbourne"); subjectBuilder.addRDN(BCStyle.CN, "Eric H. Echidna"); subjectBuilder.addRDN(BCStyle.EmailAddress, "feedback-crypto@bouncycastle.org"); // // create the certificate - version 3 // // // create the certificate - version 3 // X509v3CertificateBuilder v3CertBuilder = new JcaX509v3CertificateBuilder( issuerBuilder.build(), BigInteger.valueOf(3), new Date(System.currentTimeMillis() - 1000L * 60 * 60 * 24 * 30), new Date(System.currentTimeMillis() + (1000L * 60 * 60 * 24 * 30)), subjectBuilder.build(), pubKey); // // add the extensions // JcaX509ExtensionUtils utils = new JcaX509ExtensionUtils(); v3CertBuilder.addExtension( Extension.subjectKeyIdentifier, false, utils.createSubjectKeyIdentifier(pubKey)); v3CertBuilder.addExtension( Extension.authorityKeyIdentifier, false, utils.createAuthorityKeyIdentifier(caPubKey)); X509CertificateHolder cert = v3CertBuilder.build(new JcaContentSignerBuilder("SHA1withRSA").setProvider(BC).build(caPrivKey)); return new JcaX509CertificateConverter().setProvider(BC).getCertificate(cert); } public void testPfxPdu() throws Exception { // // set up the keys // KeyFactory fact = KeyFactory.getInstance("RSA", BC); PrivateKey privKey = fact.generatePrivate(privKeySpec); PublicKey pubKey = fact.generatePublic(pubKeySpec); X509Certificate[] chain = createCertChain(fact, pubKey); PKCS12PfxPdu pfx = createPfx(privKey, pubKey, chain); // // now try reading our object // KeyStore store = KeyStore.getInstance("PKCS12", "BC"); store.load(new ByteArrayInputStream(pfx.toASN1Structure().getEncoded()), passwd); PrivateKey recPrivKey = (PrivateKey)store.getKey("Eric's Key", passwd); if (!privKey.equals(recPrivKey)) { fail("private key extraction failed"); } Certificate[] certChain = store.getCertificateChain("Eric's Key"); for (int i = 0; i != certChain.length; i++) { if (!certChain[i].equals(chain[i])) { fail("certificate recovery failed"); } } } public void testPfxPduMac() throws Exception { // // set up the keys // KeyFactory fact = KeyFactory.getInstance("RSA", BC); PrivateKey privKey = fact.generatePrivate(privKeySpec); PublicKey pubKey = fact.generatePublic(pubKeySpec); X509Certificate[] chain = createCertChain(fact, pubKey); PKCS12PfxPdu pfx = createPfx(privKey, pubKey, chain); assertTrue(pfx.hasMac()); assertTrue(pfx.isMacValid(new BcPKCS12MacCalculatorBuilderProvider(BcDefaultDigestProvider.INSTANCE), passwd)); assertFalse(pfx.isMacValid(new BcPKCS12MacCalculatorBuilderProvider(BcDefaultDigestProvider.INSTANCE), "not right".toCharArray())); } public void testBcEncryptedPrivateKeyInfo() throws Exception { KeyFactory fact = KeyFactory.getInstance("RSA", BC); PrivateKey privKey = fact.generatePrivate(privKeySpec); PKCS8EncryptedPrivateKeyInfoBuilder builder = new JcaPKCS8EncryptedPrivateKeyInfoBuilder(privKey); PKCS8EncryptedPrivateKeyInfo priv = builder.build(new BcPKCS12PBEOutputEncryptorBuilder(PKCSObjectIdentifiers.pbeWithSHAAnd3_KeyTripleDES_CBC, new CBCBlockCipher(new DESedeEngine())).build(passwd)); PrivateKeyInfo info = priv.decryptPrivateKeyInfo(new BcPKCS12PBEInputDecryptorProviderBuilder().build(passwd)); assertTrue(Arrays.areEqual(info.getEncoded(), privKey.getEncoded())); } public void testEncryptedPrivateKeyInfo() throws Exception { KeyFactory fact = KeyFactory.getInstance("RSA", BC); PrivateKey privKey = fact.generatePrivate(privKeySpec); PKCS8EncryptedPrivateKeyInfoBuilder builder = new JcaPKCS8EncryptedPrivateKeyInfoBuilder(privKey); PKCS8EncryptedPrivateKeyInfo priv = builder.build(new JcePKCSPBEOutputEncryptorBuilder(PKCSObjectIdentifiers.pbeWithSHAAnd3_KeyTripleDES_CBC).build(passwd)); PrivateKeyInfo info = priv.decryptPrivateKeyInfo(new JcePKCSPBEInputDecryptorProviderBuilder().build(passwd)); assertTrue(Arrays.areEqual(info.getEncoded(), privKey.getEncoded())); } public void testEncryptedPrivateKeyInfoPKCS5() throws Exception { KeyFactory fact = KeyFactory.getInstance("RSA", BC); PrivateKey privKey = fact.generatePrivate(privKeySpec); PKCS8EncryptedPrivateKeyInfoBuilder builder = new JcaPKCS8EncryptedPrivateKeyInfoBuilder(privKey); PKCS8EncryptedPrivateKeyInfo priv = builder.build(new JcePKCSPBEOutputEncryptorBuilder(NISTObjectIdentifiers.id_aes256_CBC).build(passwd)); PrivateKeyInfo info = priv.decryptPrivateKeyInfo(new JcePKCSPBEInputDecryptorProviderBuilder().build(passwd)); assertTrue(Arrays.areEqual(info.getEncoded(), privKey.getEncoded())); } public void testKeyBag() throws Exception { OutputEncryptor encOut = new BcPKCS12PBEOutputEncryptorBuilder(PKCSObjectIdentifiers.pbeWithSHAAnd3_KeyTripleDES_CBC, new CBCBlockCipher(new DESedeEngine())).build(passwd); InputDecryptorProvider inputDecryptorProvider = new BcPKCS12PBEInputDecryptorProviderBuilder().build(passwd); KeyFactory fact = KeyFactory.getInstance("RSA", BC); PrivateKey privKey = fact.generatePrivate(privKeySpec); PKCS12SafeBagBuilder keyBagBuilder = new JcaPKCS12SafeBagBuilder(privKey); keyBagBuilder.addBagAttribute(PKCSObjectIdentifiers.pkcs_9_at_friendlyName, new DERBMPString("Eric's Key")); PKCS12PfxPduBuilder builder = new PKCS12PfxPduBuilder(); builder.addEncryptedData(encOut, keyBagBuilder.build()); PKCS12PfxPdu pfx = builder.build(new BcPKCS12MacCalculatorBuilder(), passwd); assertTrue(pfx.hasMac()); assertTrue(pfx.isMacValid(new BcPKCS12MacCalculatorBuilderProvider(BcDefaultDigestProvider.INSTANCE), passwd)); ContentInfo[] infos = pfx.getContentInfos(); for (int i = 0; i != infos.length; i++) { if (infos[i].getContentType().equals(PKCSObjectIdentifiers.encryptedData)) { PKCS12SafeBagFactory dataFact = new PKCS12SafeBagFactory(infos[i], inputDecryptorProvider); PKCS12SafeBag[] bags = dataFact.getSafeBags(); assertEquals(1, bags.length); assertEquals(PKCSObjectIdentifiers.keyBag, bags[0].getType()); assertTrue(Arrays.areEqual(privKey.getEncoded(), ((PrivateKeyInfo)bags[0].getBagValue()).getEncoded())); Attribute[] attributes = bags[0].getAttributes(); assertEquals(1, attributes.length); assertEquals(PKCSObjectIdentifiers.pkcs_9_at_friendlyName, attributes[0].getAttrType()); ASN1Encodable[] attrValues = attributes[0].getAttributeValues(); assertEquals(1, attrValues.length); assertEquals(new DERBMPString("Eric's Key"), attrValues[0]); } else { fail("unknown bag encountered"); } } } public void testSafeBagRecovery() throws Exception { InputDecryptorProvider inputDecryptorProvider = new BcPKCS12PBEInputDecryptorProviderBuilder().build(passwd); KeyFactory fact = KeyFactory.getInstance("RSA", BC); PrivateKey privKey = fact.generatePrivate(privKeySpec); PublicKey pubKey = fact.generatePublic(pubKeySpec); X509Certificate[] chain = createCertChain(fact, pubKey); PKCS12PfxPdu pfx = createPfx(privKey, pubKey, chain); ContentInfo[] infos = pfx.getContentInfos(); for (int i = 0; i != infos.length; i++) { if (infos[i].getContentType().equals(PKCSObjectIdentifiers.encryptedData)) { PKCS12SafeBagFactory dataFact = new PKCS12SafeBagFactory(infos[i], inputDecryptorProvider); PKCS12SafeBag[] bags = dataFact.getSafeBags(); assertEquals(3, bags.length); assertEquals(PKCSObjectIdentifiers.certBag, bags[0].getType()); for (int j = 0; j != bags.length; j++) { assertTrue(Arrays.areEqual(chain[j].getEncoded(), ((X509CertificateHolder)bags[j].getBagValue()).getEncoded())); } } else { PKCS12SafeBagFactory dataFact = new PKCS12SafeBagFactory(infos[i]); PKCS12SafeBag[] bags = dataFact.getSafeBags(); assertEquals(1, bags.length); assertEquals(PKCSObjectIdentifiers.pkcs8ShroudedKeyBag, bags[0].getType()); PKCS8EncryptedPrivateKeyInfo encInfo = (PKCS8EncryptedPrivateKeyInfo)bags[0].getBagValue(); PrivateKeyInfo info = encInfo.decryptPrivateKeyInfo(inputDecryptorProvider); assertTrue(Arrays.areEqual(info.getEncoded(), privKey.getEncoded())); } } } public void testExceptions() throws Exception { PKCS12SafeBagFactory dataFact; try { dataFact = new PKCS12SafeBagFactory(new ContentInfo(PKCSObjectIdentifiers.data, new DERSequence()), null); } catch (IllegalArgumentException e) { } try { dataFact = new PKCS12SafeBagFactory(new ContentInfo(PKCSObjectIdentifiers.encryptedData, new DERSequence())); } catch (IllegalArgumentException e) { } } public void testBasicPKCS12() throws Exception { InputDecryptorProvider inputDecryptorProvider = new JcePKCSPBEInputDecryptorProviderBuilder() .setProvider("BC").build(pkcs12Pass.toCharArray()); PKCS12PfxPdu pfx = new PKCS12PfxPdu(pkcs12); ContentInfo[] infos = pfx.getContentInfos(); for (int i = 0; i != infos.length; i++) { if (infos[i].getContentType().equals(PKCSObjectIdentifiers.encryptedData)) { PKCS12SafeBagFactory dataFact = new PKCS12SafeBagFactory(infos[i], inputDecryptorProvider); PKCS12SafeBag[] bags = dataFact.getSafeBags(); // TODO: finish! // assertEquals(3, bags.length); // assertEquals(PKCSObjectIdentifiers.certBag, bags[0].getType()); } else { PKCS12SafeBagFactory dataFact = new PKCS12SafeBagFactory(infos[i]); PKCS12SafeBag[] bags = dataFact.getSafeBags(); assertEquals(1, bags.length); assertEquals(PKCSObjectIdentifiers.pkcs8ShroudedKeyBag, bags[0].getType()); PKCS8EncryptedPrivateKeyInfo encInfo = (PKCS8EncryptedPrivateKeyInfo)bags[0].getBagValue(); PrivateKeyInfo info = encInfo.decryptPrivateKeyInfo(inputDecryptorProvider); } } } public void testSHA256withPKCS5() throws Exception { InputDecryptorProvider inputDecryptorProvider = new JcePKCSPBEInputDecryptorProviderBuilder() .setProvider("BC").build(sha256Pass.toCharArray()); PKCS12PfxPdu pfx = new PKCS12PfxPdu(sha256Pfx); ContentInfo[] infos = pfx.getContentInfos(); for (int i = 0; i != infos.length; i++) { if (infos[i].getContentType().equals(PKCSObjectIdentifiers.encryptedData)) { PKCS12SafeBagFactory dataFact = new PKCS12SafeBagFactory(infos[i], inputDecryptorProvider); PKCS12SafeBag[] bags = dataFact.getSafeBags(); // TODO: finish! // assertEquals(3, bags.length); // assertEquals(PKCSObjectIdentifiers.certBag, bags[0].getType()); } else { PKCS12SafeBagFactory dataFact = new PKCS12SafeBagFactory(infos[i]); PKCS12SafeBag[] bags = dataFact.getSafeBags(); assertEquals(1, bags.length); assertEquals(PKCSObjectIdentifiers.pkcs8ShroudedKeyBag, bags[0].getType()); PKCS8EncryptedPrivateKeyInfo encInfo = (PKCS8EncryptedPrivateKeyInfo)bags[0].getBagValue(); PrivateKeyInfo info = encInfo.decryptPrivateKeyInfo(inputDecryptorProvider); } } } public void testCreateAES256andSHA256() throws Exception { OutputEncryptor encOut = new JcePKCSPBEOutputEncryptorBuilder(NISTObjectIdentifiers.id_aes256_CBC).setProvider("BC").build(passwd); KeyFactory fact = KeyFactory.getInstance("RSA", BC); PrivateKey privKey = fact.generatePrivate(privKeySpec); PublicKey pubKey = fact.generatePublic(pubKeySpec); X509Certificate[] chain = createCertChain(fact, pubKey); PKCS12SafeBagBuilder taCertBagBuilder = new JcaPKCS12SafeBagBuilder(chain[2]); taCertBagBuilder.addBagAttribute(PKCS12SafeBag.friendlyNameAttribute, new DERBMPString("Bouncy Primary Certificate")); PKCS12SafeBagBuilder caCertBagBuilder = new JcaPKCS12SafeBagBuilder(chain[1]); caCertBagBuilder.addBagAttribute(PKCS12SafeBag.friendlyNameAttribute, new DERBMPString("Bouncy Intermediate Certificate")); JcaX509ExtensionUtils extUtils = new JcaX509ExtensionUtils(); PKCS12SafeBagBuilder eeCertBagBuilder = new JcaPKCS12SafeBagBuilder(chain[0]); eeCertBagBuilder.addBagAttribute(PKCS12SafeBag.friendlyNameAttribute, new DERBMPString("Eric's Key")); SubjectKeyIdentifier pubKeyId = extUtils.createSubjectKeyIdentifier(chain[0].getPublicKey()); eeCertBagBuilder.addBagAttribute(PKCS12SafeBag.localKeyIdAttribute, pubKeyId); PKCS12SafeBagBuilder keyBagBuilder = new JcaPKCS12SafeBagBuilder(privKey, encOut); keyBagBuilder.addBagAttribute(PKCS12SafeBag.friendlyNameAttribute, new DERBMPString("Eric's Key")); keyBagBuilder.addBagAttribute(PKCS12SafeBag.localKeyIdAttribute, pubKeyId); PKCS12PfxPduBuilder builder = new PKCS12PfxPduBuilder(); builder.addData(keyBagBuilder.build()); builder.addEncryptedData(new JcePKCSPBEOutputEncryptorBuilder(PKCSObjectIdentifiers.pbeWithSHAAnd128BitRC2_CBC).setProvider("BC").build(passwd), new PKCS12SafeBag[] { eeCertBagBuilder.build(), caCertBagBuilder.build(), taCertBagBuilder.build() }); PKCS12PfxPdu pfx = builder.build(new JcePKCS12MacCalculatorBuilder(NISTObjectIdentifiers.id_sha256), passwd); assertTrue(pfx.hasMac()); assertTrue(pfx.isMacValid(new JcePKCS12MacCalculatorBuilderProvider().setProvider("BC"), passwd)); InputDecryptorProvider inputDecryptorProvider = new JcePKCSPBEInputDecryptorProviderBuilder() .setProvider("BC").build(passwd); pfx = new PKCS12PfxPdu(pfx.toASN1Structure().getEncoded()); ContentInfo[] infos = pfx.getContentInfos(); boolean encDataFound = false; boolean pkcs8Found = false; for (int i = 0; i != infos.length; i++) { if (infos[i].getContentType().equals(PKCSObjectIdentifiers.encryptedData)) { encDataFound = true; PKCS12SafeBagFactory dataFact = new PKCS12SafeBagFactory(infos[i], inputDecryptorProvider); PKCS12SafeBag[] bags = dataFact.getSafeBags(); assertEquals(3, bags.length); assertEquals(PKCSObjectIdentifiers.certBag, bags[0].getType()); } else { pkcs8Found = true; PKCS12SafeBagFactory dataFact = new PKCS12SafeBagFactory(infos[i]); PKCS12SafeBag[] bags = dataFact.getSafeBags(); assertEquals(1, bags.length); assertEquals(PKCSObjectIdentifiers.pkcs8ShroudedKeyBag, bags[0].getType()); PKCS8EncryptedPrivateKeyInfo encInfo = (PKCS8EncryptedPrivateKeyInfo)bags[0].getBagValue(); PrivateKeyInfo info = encInfo.decryptPrivateKeyInfo(inputDecryptorProvider); } } assertTrue(encDataFound); assertTrue(pkcs8Found); KeyStore ks = KeyStore.getInstance("PKCS12", "BC"); ks.load(new ByteArrayInputStream(pfx.getEncoded(ASN1Encoding.DL)), passwd); assertTrue(ks.containsAlias("Eric's Key")); } public void testPKCS5() throws Exception { doPKCS5Test(pkcs5Aes128Pfx); doPKCS5Test(pkcs5Aes192Pfx); doPKCS5Test(pkcs5Camellia128Pfx); doPKCS5Test(pkcs5Camellia256Pfx); doPKCS5Test(pkcs5Cast5Pfx); } private void doPKCS5Test(byte[] keyStore) throws Exception { InputDecryptorProvider inputDecryptorProvider = new JcePKCSPBEInputDecryptorProviderBuilder() .setProvider("BC").build(pkcs5Pass.toCharArray()); PKCS12PfxPdu pfx = new PKCS12PfxPdu(keyStore); ContentInfo[] infos = pfx.getContentInfos(); for (int i = 0; i != infos.length; i++) { if (infos[i].getContentType().equals(PKCSObjectIdentifiers.encryptedData)) { PKCS12SafeBagFactory dataFact = new PKCS12SafeBagFactory(infos[i], inputDecryptorProvider); PKCS12SafeBag[] bags = dataFact.getSafeBags(); // TODO: finish! // assertEquals(3, bags.length); // assertEquals(PKCSObjectIdentifiers.certBag, bags[0].getType()); } else { PKCS12SafeBagFactory dataFact = new PKCS12SafeBagFactory(infos[i]); PKCS12SafeBag[] bags = dataFact.getSafeBags(); assertEquals(1, bags.length); assertEquals(PKCSObjectIdentifiers.pkcs8ShroudedKeyBag, bags[0].getType()); PKCS8EncryptedPrivateKeyInfo encInfo = (PKCS8EncryptedPrivateKeyInfo)bags[0].getBagValue(); PrivateKeyInfo info = encInfo.decryptPrivateKeyInfo(inputDecryptorProvider); } } } private X509Certificate[] createCertChain(KeyFactory fact, PublicKey pubKey) throws Exception { PrivateKey caPrivKey = fact.generatePrivate(caPrivKeySpec); PublicKey caPubKey = fact.generatePublic(caPubKeySpec); PrivateKey intPrivKey = fact.generatePrivate(intPrivKeySpec); PublicKey intPubKey = fact.generatePublic(intPubKeySpec); X509Certificate[] chain = new X509Certificate[3]; chain[2] = createMasterCert(caPubKey, caPrivKey); chain[1] = createIntermediateCert(intPubKey, caPrivKey, chain[2]); chain[0] = createCert(pubKey, intPrivKey, intPubKey); return chain; } private PKCS12PfxPdu createPfx(PrivateKey privKey, PublicKey pubKey, X509Certificate[] chain) throws NoSuchAlgorithmException, IOException, PKCSException { JcaX509ExtensionUtils extUtils = new JcaX509ExtensionUtils(); PKCS12SafeBagBuilder taCertBagBuilder = new JcaPKCS12SafeBagBuilder(chain[2]); taCertBagBuilder.addBagAttribute(PKCSObjectIdentifiers.pkcs_9_at_friendlyName, new DERBMPString("Bouncy Primary Certificate")); PKCS12SafeBagBuilder caCertBagBuilder = new JcaPKCS12SafeBagBuilder(chain[1]); caCertBagBuilder.addBagAttribute(PKCSObjectIdentifiers.pkcs_9_at_friendlyName, new DERBMPString("Bouncy Intermediate Certificate")); PKCS12SafeBagBuilder eeCertBagBuilder = new JcaPKCS12SafeBagBuilder(chain[0]); eeCertBagBuilder.addBagAttribute(PKCSObjectIdentifiers.pkcs_9_at_friendlyName, new DERBMPString("Eric's Key")); eeCertBagBuilder.addBagAttribute(PKCSObjectIdentifiers.pkcs_9_at_localKeyId, extUtils.createSubjectKeyIdentifier(pubKey)); PKCS12SafeBagBuilder keyBagBuilder = new JcaPKCS12SafeBagBuilder(privKey, new BcPKCS12PBEOutputEncryptorBuilder(PKCSObjectIdentifiers.pbeWithSHAAnd3_KeyTripleDES_CBC, new CBCBlockCipher(new DESedeEngine())).build(passwd)); keyBagBuilder.addBagAttribute(PKCSObjectIdentifiers.pkcs_9_at_friendlyName, new DERBMPString("Eric's Key")); keyBagBuilder.addBagAttribute(PKCSObjectIdentifiers.pkcs_9_at_localKeyId, extUtils.createSubjectKeyIdentifier(pubKey)); // // construct the actual key store // PKCS12PfxPduBuilder pfxPduBuilder = new PKCS12PfxPduBuilder(); PKCS12SafeBag[] certs = new PKCS12SafeBag[3]; certs[0] = eeCertBagBuilder.build(); certs[1] = caCertBagBuilder.build(); certs[2] = taCertBagBuilder.build(); pfxPduBuilder.addEncryptedData(new BcPKCS12PBEOutputEncryptorBuilder(PKCSObjectIdentifiers.pbeWithSHAAnd40BitRC2_CBC, new CBCBlockCipher(new RC2Engine())).build(passwd), certs); pfxPduBuilder.addData(keyBagBuilder.build()); return pfxPduBuilder.build(new BcPKCS12MacCalculatorBuilder(), passwd); } } bouncycastle-1.49.orig/test/src/org/bouncycastle/pkcs/test/BCTestSetup.java0000644000175000017500000000103312116546761026416 0ustar ebourgebourg// Copyright (c) 2005 The Legion Of The Bouncy Castle (http://www.bouncycastle.org) package org.bouncycastle.pkcs.test; import java.security.Security; import junit.extensions.TestSetup; import junit.framework.Test; class BCTestSetup extends TestSetup { public BCTestSetup(Test test) { super(test); } protected void setUp() { Security.addProvider(new org.bouncycastle.jce.provider.BouncyCastleProvider()); } protected void tearDown() { Security.removeProvider("BC"); } } bouncycastle-1.49.orig/test/src/org/bouncycastle/jce/0000755000175000017500000000000012152033550022216 5ustar ebourgebourgbouncycastle-1.49.orig/test/src/org/bouncycastle/jce/provider/0000755000175000017500000000000012152033550024050 5ustar ebourgebourgbouncycastle-1.49.orig/test/src/org/bouncycastle/jce/provider/test/0000755000175000017500000000000012152033550025027 5ustar ebourgebourgbouncycastle-1.49.orig/test/src/org/bouncycastle/jce/provider/test/NoekeonTest.java0000644000175000017500000000750210632663750030150 0ustar ebourgebourgpackage org.bouncycastle.jce.provider.test; import org.bouncycastle.jce.provider.BouncyCastleProvider; import org.bouncycastle.util.encoders.Hex; import javax.crypto.Cipher; import javax.crypto.CipherInputStream; import javax.crypto.CipherOutputStream; import javax.crypto.spec.SecretKeySpec; import java.io.ByteArrayInputStream; import java.io.ByteArrayOutputStream; import java.io.DataInputStream; import java.io.IOException; import java.security.Key; import java.security.Security; /** * basic test class for SEED */ public class NoekeonTest extends BaseBlockCipherTest { static String[] cipherTests = { "128", "b1656851699e29fa24b70148503d2dfc", "2a78421b87c7d0924f26113f1d1349b2", "e2f687e07b75660ffc372233bc47532c" }; public NoekeonTest() { super("Noekeon"); } public void test( int strength, byte[] keyBytes, byte[] input, byte[] output) throws Exception { Key key; Cipher in, out; CipherInputStream cIn; CipherOutputStream cOut; ByteArrayInputStream bIn; ByteArrayOutputStream bOut; key = new SecretKeySpec(keyBytes, "Noekeon"); in = Cipher.getInstance("Noekeon/ECB/NoPadding", "BC"); out = Cipher.getInstance("Noekeon/ECB/NoPadding", "BC"); try { out.init(Cipher.ENCRYPT_MODE, key); } catch (Exception e) { fail("Noekeon failed initialisation - " + e.toString(), e); } try { in.init(Cipher.DECRYPT_MODE, key); } catch (Exception e) { fail("Noekeoen failed initialisation - " + e.toString(), e); } // // encryption pass // bOut = new ByteArrayOutputStream(); cOut = new CipherOutputStream(bOut, out); try { for (int i = 0; i != input.length / 2; i++) { cOut.write(input[i]); } cOut.write(input, input.length / 2, input.length - input.length / 2); cOut.close(); } catch (IOException e) { fail("Noekeon failed encryption - " + e.toString(), e); } byte[] bytes; bytes = bOut.toByteArray(); if (!areEqual(bytes, output)) { fail("Noekeon failed encryption - expected " + new String(Hex.encode(output)) + " got " + new String(Hex.encode(bytes))); } // // decryption pass // bIn = new ByteArrayInputStream(bytes); cIn = new CipherInputStream(bIn, in); try { DataInputStream dIn = new DataInputStream(cIn); bytes = new byte[input.length]; for (int i = 0; i != input.length / 2; i++) { bytes[i] = (byte)dIn.read(); } dIn.readFully(bytes, input.length / 2, bytes.length - input.length / 2); } catch (Exception e) { fail("Noekeon failed encryption - " + e.toString(), e); } if (!areEqual(bytes, input)) { fail("Noekeon failed decryption - expected " + new String(Hex.encode(input)) + " got " + new String(Hex.encode(bytes))); } } public void performTest() throws Exception { for (int i = 0; i != cipherTests.length; i += 4) { test(Integer.parseInt(cipherTests[i]), Hex.decode(cipherTests[i + 1]), Hex.decode(cipherTests[i + 2]), Hex.decode(cipherTests[i + 3])); } } public static void main( String[] args) { Security.addProvider(new BouncyCastleProvider()); runTest(new NoekeonTest()); } } bouncycastle-1.49.orig/test/src/org/bouncycastle/jce/provider/test/KeyStoreTest.java0000644000175000017500000003301712115751674030320 0ustar ebourgebourgpackage org.bouncycastle.jce.provider.test; import java.io.ByteArrayInputStream; import java.io.ByteArrayOutputStream; import java.io.IOException; import java.math.BigInteger; import java.security.Key; import java.security.KeyFactory; import java.security.KeyPair; import java.security.KeyPairGenerator; import java.security.KeyStore; import java.security.PrivateKey; import java.security.PublicKey; import java.security.SecureRandom; import java.security.Security; import java.security.cert.Certificate; import java.security.cert.CertificateFactory; import java.security.cert.X509Certificate; import java.security.interfaces.RSAPrivateKey; import java.security.interfaces.RSAPublicKey; import java.security.spec.PKCS8EncodedKeySpec; import java.security.spec.X509EncodedKeySpec; import java.util.Date; import java.util.Hashtable; import java.util.Vector; import org.bouncycastle.jce.X509Principal; import org.bouncycastle.jce.provider.BouncyCastleProvider; import org.bouncycastle.jce.spec.ECParameterSpec; import org.bouncycastle.math.ec.ECCurve; import org.bouncycastle.util.encoders.Base64; import org.bouncycastle.util.encoders.Hex; import org.bouncycastle.util.test.SimpleTest; import org.bouncycastle.x509.X509V3CertificateGenerator; /** * Exercise the various key stores, making sure we at least get back what we put in! *

    * This tests both the BKS, and the UBER key store. */ public class KeyStoreTest extends SimpleTest { static char[] passwd = { 'h', 'e', 'l', 'l', 'o', ' ', 'w', 'o', 'r', 'l', 'd' }; byte[] v1BKS = Base64.decode( "AAAAAQAAABTqZbNMyPjsFazhFplWWDMBLPRdRAAABcYEAAdhbmRyb2lkAAAB" + "NOifkPwAAAAAAAAAPAAAABTZOLhcyhB0gKyfoDvyQbpzftB7GgAABEYPrZP8" + "q20AJLETjDv0K9C5rIl1erpyvpv20bqcbghK6wD0b8OP5/XzOz/8knhxmqJZ" + "3yRJMw=="); byte[] v2BKS = Base64.decode( "AAAAAgAAABSkmTXz4VIznO1SSUqsIHdxWcxsuQAABFMEAAdhbmRyb2lkAAABN" + "OifkPwAAAAAAAAAPAAAABTZOLhcyhB0gKyfoDvyQbpzftB7GgAABEYPrZP8q2" + "0AJLETjDv0K9C5rIl1erpyvpv20bqcbghK6wBO59KOGPvSrmJpd32P6ZAh9qLZJw=="); byte[] v1UBER = Base64.decode( "AAAAAQAAABRP0F6p2p3FyQKqyJiJt3NbvdybiwAAB2znqrO779YIW5gMtbt+" + "NUs96VPPcfZiKJPg7RKH7Yu3CQB0/g9nYsvgFB0fQ05mHcW3KjntN2/31A6G" + "i00n4ZnUTjJL16puZnQrloeGXxFy58tjwkFuwJ7V7ELYgiZlls0beHSdDGQW" + "iyYECwWs1la/"); byte[] v2UBER = Base64.decode( "AAAAAgAAABQ/D9k3376OG/REg4Ams9Up332tLQAABujoVcsRcKWwhlo4mMg5" + "lF2vJfK+okIYecJGWCvdykF5r8kDn68llt52IDXDkpRXVXcNJ0/aD7sa7iZ0" + "SL0TAwcfp/9v4j/w8slj/qgO0i/76+zROrP0NGFIa5k/iOg5Z0Tj77muMaJf" + "n3vLlIHa4IsX"); byte[] negSaltBKS = Base64.decode( "AAAAAv////+WnyglO06djy6JgCxGiIemnZdcOwAAB2AEAAdhbmRyb2lkAAAB" + "NOifkPwAAAAAAAAAPAAAABTZOLhcyhB0gKyfoDvyQbpzftB7GgAABEYPrZP8" + "q20AJLETjDv0K9C5rIl1erpyvpv20bqcbghK6wDrg6gUHsh27wNjUwkR+REe" + "NeFYBg=="); char[] oldStorePass = "fredfred".toCharArray(); public void ecStoreTest( String storeName) throws Exception { ECCurve curve = new ECCurve.Fp( new BigInteger("883423532389192164791648750360308885314476597252960362792450860609699839"), // q new BigInteger("7fffffffffffffffffffffff7fffffffffff8000000000007ffffffffffc", 16), // a new BigInteger("6b016c3bdcf18941d0d654921475ca71a9db2fb27d1d37796185c2942c0a", 16)); // b ECParameterSpec ecSpec = new ECParameterSpec( curve, curve.decodePoint(Hex.decode("020ffa963cdca8816ccc33b8642bedf905c3d358573d3f27fbbd3b3cb9aaaf")), // G new BigInteger("883423532389192164791648750360308884807550341691627752275345424702807307")); // n KeyPairGenerator g = KeyPairGenerator.getInstance("ECDSA", "BC"); g.initialize(ecSpec, new SecureRandom()); KeyPair keyPair = g.generateKeyPair(); PublicKey pubKey = keyPair.getPublic(); PrivateKey privKey = keyPair.getPrivate(); // // distinguished name table. // Hashtable attrs = new Hashtable(); Vector order = new Vector(); attrs.put(X509Principal.C, "AU"); attrs.put(X509Principal.O, "The Legion of the Bouncy Castle"); attrs.put(X509Principal.L, "Melbourne"); attrs.put(X509Principal.ST, "Victoria"); attrs.put(X509Principal.E, "feedback-crypto@bouncycastle.org"); order.addElement(X509Principal.C); order.addElement(X509Principal.O); order.addElement(X509Principal.L); order.addElement(X509Principal.ST); order.addElement(X509Principal.E); // // create the certificate - version 3 // X509V3CertificateGenerator certGen = new X509V3CertificateGenerator(); certGen.setSerialNumber(BigInteger.valueOf(1)); certGen.setIssuerDN(new X509Principal(order, attrs)); certGen.setNotBefore(new Date(System.currentTimeMillis() - 50000)); certGen.setNotAfter(new Date(System.currentTimeMillis() + 50000)); certGen.setSubjectDN(new X509Principal(order, attrs)); certGen.setPublicKey(pubKey); certGen.setSignatureAlgorithm("ECDSAwithSHA1"); Certificate[] chain = new Certificate[1]; try { X509Certificate cert = certGen.generate(privKey); cert.checkValidity(new Date()); cert.verify(pubKey); ByteArrayInputStream bIn = new ByteArrayInputStream(cert.getEncoded()); CertificateFactory fact = CertificateFactory.getInstance("X.509", "BC"); cert = (X509Certificate)fact.generateCertificate(bIn); chain[0] = cert; } catch (Exception e) { fail("error generating cert - " + e.toString()); } KeyStore store = KeyStore.getInstance(storeName, "BC"); store.load(null, null); store.setKeyEntry("private", privKey, passwd, chain); // // write out and read back store // ByteArrayOutputStream bOut = new ByteArrayOutputStream(); store.store(bOut, passwd); ByteArrayInputStream bIn = new ByteArrayInputStream(bOut.toByteArray()); // // start with a new key store // store = KeyStore.getInstance(storeName, "BC"); store.load(bIn, passwd); // // load the private key // privKey = (PrivateKey)store.getKey("private", passwd); // // double public key encoding test // byte[] pubEnc = pubKey.getEncoded(); KeyFactory keyFac = KeyFactory.getInstance(pubKey.getAlgorithm(), "BC"); X509EncodedKeySpec pubX509 = new X509EncodedKeySpec(pubEnc); pubKey = (PublicKey)keyFac.generatePublic(pubX509); pubEnc = pubKey.getEncoded(); keyFac = KeyFactory.getInstance(pubKey.getAlgorithm(), "BC"); pubX509 = new X509EncodedKeySpec(pubEnc); pubKey = (PublicKey)keyFac.generatePublic(pubX509); // // double private key encoding test // byte[] privEnc = privKey.getEncoded(); keyFac = KeyFactory.getInstance(privKey.getAlgorithm(), "BC"); PKCS8EncodedKeySpec privPKCS8 = new PKCS8EncodedKeySpec(privEnc); privKey = (PrivateKey)keyFac.generatePrivate(privPKCS8); keyFac = KeyFactory.getInstance(privKey.getAlgorithm(), "BC"); privPKCS8 = new PKCS8EncodedKeySpec(privEnc); privKey = (PrivateKey)keyFac.generatePrivate(privPKCS8); } public void keyStoreTest( String storeName) throws Exception { KeyStore store = KeyStore.getInstance(storeName, "BC"); store.load(null, null); KeyPairGenerator gen = KeyPairGenerator.getInstance("RSA", "BC"); gen.initialize(1024, new SecureRandom()); KeyPair pair = gen.generateKeyPair(); RSAPrivateKey privKey = (RSAPrivateKey)pair.getPrivate(); RSAPublicKey pubKey = (RSAPublicKey)pair.getPublic(); BigInteger modulus = privKey.getModulus(); BigInteger privateExponent = privKey.getPrivateExponent(); // // distinguished name table. // Hashtable attrs = new Hashtable(); Vector order = new Vector(); attrs.put(X509Principal.C, "AU"); attrs.put(X509Principal.O, "The Legion of the Bouncy Castle"); attrs.put(X509Principal.L, "Melbourne"); attrs.put(X509Principal.ST, "Victoria"); attrs.put(X509Principal.EmailAddress, "feedback-crypto@bouncycastle.org"); order.addElement(X509Principal.C); order.addElement(X509Principal.O); order.addElement(X509Principal.L); order.addElement(X509Principal.ST); order.addElement(X509Principal.EmailAddress); // // extensions // // // create the certificate. // X509V3CertificateGenerator certGen = new X509V3CertificateGenerator(); certGen.setSerialNumber(BigInteger.valueOf(1)); certGen.setIssuerDN(new X509Principal(order, attrs)); certGen.setNotBefore(new Date(System.currentTimeMillis() - 50000)); certGen.setNotAfter(new Date(System.currentTimeMillis() + 50000)); certGen.setSubjectDN(new X509Principal(order, attrs)); certGen.setPublicKey(pubKey); certGen.setSignatureAlgorithm("MD5WithRSAEncryption"); Certificate[] chain = new Certificate[1]; try { X509Certificate cert = certGen.generate(privKey); cert.checkValidity(new Date()); cert.verify(pubKey); ByteArrayInputStream bIn = new ByteArrayInputStream(cert.getEncoded()); CertificateFactory fact = CertificateFactory.getInstance("X.509", "BC"); cert = (X509Certificate)fact.generateCertificate(bIn); chain[0] = cert; } catch (Exception e) { fail("error generating cert - " + e.toString()); } store.setKeyEntry("private", privKey, passwd, chain); // // write out and read back store // ByteArrayOutputStream bOut = new ByteArrayOutputStream(); store.store(bOut, passwd); ByteArrayInputStream bIn = new ByteArrayInputStream(bOut.toByteArray()); // // start with a new key store // store = KeyStore.getInstance(storeName, "BC"); store.load(bIn, passwd); // // verify public key // privKey = (RSAPrivateKey)store.getKey("private", passwd); if (!privKey.getModulus().equals(modulus)) { fail("private key modulus wrong"); } else if (!privKey.getPrivateExponent().equals(privateExponent)) { fail("private key exponent wrong"); } // // verify certificate // Certificate cert = store.getCertificateChain("private")[0]; cert.verify(pubKey); } private void oldStoreTest() throws Exception { checkStore(KeyStore.getInstance("BKS", "BC"), v1BKS); checkStore(KeyStore.getInstance("BKS", "BC"), v2BKS); checkStore(KeyStore.getInstance("UBER", "BC"), v1UBER); checkStore(KeyStore.getInstance("UBER", "BC"), v2UBER); checkOldStore(KeyStore.getInstance("BKS-V1", "BC"), v1BKS); checkOldStore(KeyStore.getInstance("BKS-V1", "BC"), v2BKS); } private void checkStore(KeyStore ks, byte[] data) throws Exception { ks.load(new ByteArrayInputStream(data), oldStorePass); if (!ks.containsAlias("android")) { fail("cannot find alias"); } Key key = ks.getKey("android", oldStorePass); if (key == null) { fail("cannot find key"); } ByteArrayOutputStream bOut = new ByteArrayOutputStream(); ks.store(bOut, oldStorePass); } private void checkOldStore(KeyStore ks, byte[] data) throws Exception { ks.load(new ByteArrayInputStream(data), oldStorePass); if (!ks.containsAlias("android")) { fail("cannot find alias"); } Key key = ks.getKey("android", oldStorePass); if (key == null) { fail("cannot find key"); } ByteArrayOutputStream bOut = new ByteArrayOutputStream(); ks.store(bOut, oldStorePass); if (data.length != bOut.toByteArray().length) { fail("Old version key store write incorrect"); } } private void checkException() throws Exception { KeyStore ks = KeyStore.getInstance("BKS", "BC"); try { ks.load(new ByteArrayInputStream(negSaltBKS), oldStorePass); } catch (IOException e) { if (!e.getMessage().equals("Invalid salt detected")) { fail("negative salt length not detected"); } } } public String getName() { return "KeyStore"; } public void performTest() throws Exception { keyStoreTest("BKS"); keyStoreTest("UBER"); keyStoreTest("BKS-V1"); ecStoreTest("BKS"); oldStoreTest(); checkException(); } public static void main( String[] args) { Security.addProvider(new BouncyCastleProvider()); runTest(new KeyStoreTest()); } } bouncycastle-1.49.orig/test/src/org/bouncycastle/jce/provider/test/SHA3Test.java0000644000175000017500000001066212101745071027237 0ustar ebourgebourgpackage org.bouncycastle.jce.provider.test; import java.security.MessageDigest; import java.security.Security; import org.bouncycastle.jce.provider.BouncyCastleProvider; import org.bouncycastle.util.encoders.Hex; import org.bouncycastle.util.test.SimpleTest; public class SHA3Test extends SimpleTest { final static String provider = "BC"; static private byte[] nullMsg = new byte[0]; static private String[][] nullVectors = { { "SHA3-224", "f71837502ba8e10837bdd8d365adb85591895602fc552b48b7390abd" }, { "SHA3-256", "c5d2460186f7233c927e7db2dcc703c0e500b653ca82273b7bfad8045d85a470" }, { "SHA3-384", "2c23146a63a29acf99e73b88f8c24eaa7dc60aa771780ccc006afbfa8fe2479b2dd2b21362337441ac12b515911957ff" }, { "SHA3-512", "0eab42de4c3ceb9235fc91acffe746b29c29a8c366b7c60e4e67c466f36a4304c00fa9caf9d87976ba469bcbe06713b435f091ef2769fb160cdab33d3670680e" }, }; static private byte[] shortMsg = Hex.decode("54686520717569636b2062726f776e20666f78206a756d7073206f76657220746865206c617a7920646f67"); static private String[][] shortVectors = { { "SHA3-224", "310aee6b30c47350576ac2873fa89fd190cdc488442f3ef654cf23fe" }, { "SHA3-256", "4d741b6f1eb29cb2a9b9911c82f56fa8d73b04959d3d9d222895df6c0b28aa15" }, { "SHA3-384", "283990fa9d5fb731d786c5bbee94ea4db4910f18c62c03d173fc0a5e494422e8a0b3da7574dae7fa0baf005e504063b3" }, { "SHA3-512", "d135bb84d0439dbac432247ee573a23ea7d3c9deb2a968eb31d47c4fb45f1ef4422d6c531b5b9bd6f449ebcc449ea94d0a8f05f62130fda612da53c79659f609" }, }; public String getName() { return "SHA3"; } void test(String algorithm, byte[] message, String expected) throws Exception { MessageDigest digest = MessageDigest.getInstance(algorithm, provider); byte[] result = digest.digest(message); byte[] result2 = digest.digest(message); // test zero results valid if (!MessageDigest.isEqual(result, Hex.decode(expected))) { fail("null result not equal for " + algorithm); } // test one digest the same message with the same instance if (!MessageDigest.isEqual(result, result2)) { fail("Result object 1 not equal"); } if (!MessageDigest.isEqual(result, Hex.decode(expected))) { fail("Result object 1 not equal"); } // test two, single byte updates for (int i = 0; i < message.length; i++) { digest.update(message[i]); } result2 = digest.digest(); if (!MessageDigest.isEqual(result, result2)) { fail("Result object 2 not equal"); } // test three, two half updates digest.update(message, 0, message.length/2); digest.update(message, message.length/2, message.length-message.length/2); result2 = digest.digest(); if (!MessageDigest.isEqual(result, result2)) { fail("Result object 3 not equal"); } // test four, clone test digest.update(message, 0, message.length/2); MessageDigest d = (MessageDigest)digest.clone(); digest.update(message, message.length/2, message.length-message.length/2); result2 = digest.digest(); if (!MessageDigest.isEqual(result, result2)) { fail("Result object 4(a) not equal"); } d.update(message, message.length/2, message.length-message.length/2); result2 = d.digest(); if (!MessageDigest.isEqual(result, result2)) { fail("Result object 4(b) not equal"); } // test five, check reset() method digest.update(message, 0, message.length/2); digest.reset(); digest.update(message, 0, message.length/2); digest.update(message, message.length/2, message.length-message.length/2); result2 = digest.digest(); if (!MessageDigest.isEqual(result, result2)) { fail("Result object 5 not equal"); } } public void performTest() throws Exception { for (int i = 0; i != nullVectors.length; i++) { test(nullVectors[i][0], nullMsg, nullVectors[i][1]); test(shortVectors[i][0], shortMsg, shortVectors[i][1]); } } public static void main(String[] args) { Security.addProvider(new BouncyCastleProvider()); runTest(new SHA3Test()); } } bouncycastle-1.49.orig/test/src/org/bouncycastle/jce/provider/test/X509LDAPCertStoreTest.java0000644000175000017500000005322210526271007031503 0ustar ebourgebourgpackage org.bouncycastle.jce.provider.test; import org.bouncycastle.jce.PrincipalUtil; import org.bouncycastle.jce.X509LDAPCertStoreParameters; import org.bouncycastle.jce.X509Principal; import org.bouncycastle.jce.provider.BouncyCastleProvider; import org.bouncycastle.util.encoders.Base64; import org.bouncycastle.util.test.SimpleTest; import org.bouncycastle.x509.X509CRLStoreSelector; import org.bouncycastle.x509.X509CertStoreSelector; import org.bouncycastle.x509.X509Store; import java.io.ByteArrayInputStream; import java.security.Security; import java.security.cert.CRLException; import java.security.cert.CertStore; import java.security.cert.CertificateEncodingException; import java.security.cert.CertificateFactory; import java.security.cert.X509CRL; import java.security.cert.X509CRLSelector; import java.security.cert.X509CertSelector; import java.security.cert.X509Certificate; import java.util.Collection; import java.util.Collections; import java.util.Iterator; public class X509LDAPCertStoreTest extends SimpleTest { private static final byte cert1[] = Base64 .decode("MIIDyTCCAzKgAwIBAgIEL64+8zANBgkqhkiG9w0BAQUFADBVMQswCQYDVQQGEwJE" + "RTEcMBoGA1UEChQTRGV1dHNjaGUgVGVsZWtvbSBBRzEoMAwGBwKCBgEKBxQTATEw" + "GAYDVQQDFBFUVEMgVGVzdCBDQSAxMTpQTjAeFw0wMzAzMjUxNDM1MzFaFw0wNjAz" + "MjUxNDM1MzFaMGIxCzAJBgNVBAYTAkRFMRswGQYDVQQKDBJHRlQgU29sdXRpb25z" + "IEdtYkgxEjAQBgNVBAsMCUhZUEFSQ0hJVjEWMBQGA1UEAwwNRGllZ2UsIFNpbW9u" + "ZTEKMAgGA1UEBRMBMTCBoDANBgkqhkiG9w0BAQEFAAOBjgAwgYoCgYEAiEYsFbs4" + "FesQpMjBkzJB92c0p8tJ02nbCNA5l17VVbbrv6/twnQHW4kgA+9lZlXfzI8iunT1" + "KuiwVupWObHgFaGPkelIN/qIbuwbQzh7T+IUKdKETE12Lc+xk9YvQ6mJVgosmwpr" + "nMMjezymh8DjPhe7MC7/H3AotrHVNM3mEJcCBEAAAIGjggGWMIIBkjAfBgNVHSME" + "GDAWgBTQc8wTeltcAM3iTE63fk/wTA+IJTAdBgNVHQ4EFgQUq6ChBvXPiqhMHLS3" + "kiKpSeGWDz4wDgYDVR0PAQH/BAQDAgQwMB8GA1UdEQQYMBaBFHNpbW9uZS5kaWVn" + "ZUBnZnQuY29tMIHoBgNVHR8EgeAwgd0wgdqgaqBohjVsZGFwOi8vcGtzbGRhcC50" + "dHRjLmRlOjM4OS9jPWRlLG89RGV1dHNjaGUgVGVsZWtvbSBBR4YvaHR0cDovL3d3" + "dy50dHRjLmRlL3RlbGVzZWMvc2VydmxldC9kb3dubG9hZF9jcmyibKRqMGgxCzAJ" + "BgNVBAYTAkRFMRwwGgYDVQQKFBNEZXV0c2NoZSBUZWxla29tIEFHMTswDAYHAoIG" + "AQoHFBMBMTArBgNVBAMUJFRlbGVTZWMgRGlyZWN0b3J5IFNlcnZpY2UgU2lnRyAx" + "MDpQTjA0BggrBgEFBQcBAQQoMCYwJAYIKwYBBQUHMAGGGGh0dHA6Ly93d3cudHR0" + "Yy5kZS9vY3NwcjANBgkqhkiG9w0BAQUFAAOBgQBCPudAtrP9Bx7GRhHQgYS6kaoN" + "vYb/yDss86pyn0uiFuwT+mT1popcAfxPo2yxL0jqqlsDNFBC2hJob5rjihsKPmqV" + "rSaW0VJu/zBihsX7hLKOVMf5gvUYMS5ulq/bp8jOj8a+5SmxVY+WWZVFghWjISse" + "T3WABdTS9S3zjnQiyg=="); private static final byte[] directCRL = Base64 .decode("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" + "MQ=="); private static final String ldapURL1 = "ldap://pksldap.tttc.de:389"; private static final X509LDAPCertStoreParameters params1 = new X509LDAPCertStoreParameters.Builder( ldapURL1, "o=Deutsche Telekom AG, c=DE"). setAACertificateSubjectAttributeName("ou cn"). setAttributeAuthorityRevocationListIssuerAttributeName("cn"). setAttributeCertificateAttributeSubjectAttributeName("cn"). setAttributeCertificateRevocationListIssuerAttributeName("cn"). setAttributeDescriptorCertificateSubjectAttributeName("ou cn"). setAuthorityRevocationListIssuerAttributeName("cn"). setCACertificateSubjectAttributeName("ou cn"). setCertificateRevocationListIssuerAttributeName("cn"). setCrossCertificateSubjectAttributeName("cn"). setDeltaRevocationListIssuerAttributeName("cn"). setSearchForSerialNumberIn("cn") .build(); private static final String ldapURL2 = "ldap://directory.d-trust.de:389"; private static final X509LDAPCertStoreParameters params2 = new X509LDAPCertStoreParameters.Builder( ldapURL2, "o=D-Trust GmbH, c=DE"). setAACertificateSubjectAttributeName("cn o"). setAttributeAuthorityRevocationListIssuerAttributeName("cn"). setAttributeCertificateAttributeSubjectAttributeName("cn"). setAttributeCertificateRevocationListIssuerAttributeName("cn"). setAttributeDescriptorCertificateSubjectAttributeName("cn o"). setAuthorityRevocationListIssuerAttributeName("cn"). setCACertificateSubjectAttributeName("cn o"). setCertificateRevocationListIssuerAttributeName("cn"). setCrossCertificateSubjectAttributeName("cn o"). setDeltaRevocationListIssuerAttributeName("cn"). setSearchForSerialNumberIn("uid") .build(); private static final byte[] cert2 = Base64 .decode("MIIEADCCAuigAwIBAgIDAJ/QMA0GCSqGSIb3DQEBBQUAMD8xCzAJBgNVBAYTAkRF" + "MRUwEwYDVQQKDAxELVRydXN0IEdtYkgxGTAXBgNVBAMMEEQtVFJVU1QgRGVtbyBD" + "QTEwHhcNMDYwMzAyMTYxNTU3WhcNMDgwMzEyMTYxNTU3WjB+MQswCQYDVQQGEwJE" + "RTEUMBIGA1UECgwLTXVzdGVyIEdtYkgxFzAVBgNVBAMMDk1heCBNdXN0ZXJtYW5u" + "MRMwEQYDVQQEDApNdXN0ZXJtYW5uMQwwCgYDVQQqDANNYXgxHTAbBgNVBAUTFERU" + "UldFMTQxMjk5NDU1MTgwMTIxMIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKC" + "AQEAjLDFeviSZDEZgLzTdptU4biPgNV7SvLqsNholfqkyQm2r5WSghGZSjhKYIne" + "qKmZ08W59a51bGqDEsifYR7Tw9JC/AhH19fyK01+1ZAXHalgVthaRtLw31lcoTVJ" + "R7j9fvrnW0sMPVP4m5gePb3P5/pYHVmN1MjdPIm38us5aJOytOO5Li2IwQIG0t4M" + "bEC6/1horBR5TgRl7ACamrdaPHOvO1QVweOqYU7uVxLgDTK4mSV6heyrisFMfkbj" + "7jT/c44kXM7dtgNcmESINudu6bnqaB1CxOFTJ/Jzv81R5lf7pBX2LOG1Bu94Yw2x" + "cHUVROs2UWY8kQrNUozsBHzQ0QIDAKq5o4HFMIHCMBMGA1UdIwQMMAqACEITKrPL" + "WuYiMDMGCCsGAQUFBwEBBCcwJTAjBggrBgEFBQcwAYYXaHR0cDovL29jc3AuZC10" + "cnVzdC5uZXQwEAYDVR0gBAkwBzAFBgMqAwQwEQYDVR0OBAoECEvE8bXFHkFLMA4G" + "A1UdDwEB/wQEAwIGQDAPBgUrJAgDCAQGDARUZXN0MB8GA1UdEQQYMBaBFG0ubXVz" + "dGVybWFubkB0ZXN0LmRlMA8GBSskCAMPBAYMBFRlc3QwDQYJKoZIhvcNAQEFBQAD" + "ggEBADD/X+UZZN30nCBDzJ7MtmgwvMBVDAU6HkPlzfyn9pxIKFrq3uR9wcY2pedM" + "yQQk0NpTDCIhAYIjAHysMue0ViQnW5qq8uUCFn0+fsgMqqTQNRmE4NIqUrnYO40g" + "WjcepCEApkTqGf3RFaDMf9zpRvj9qUx18De+V0GC22uD2vPKpqRcvS2dSw6pHBW2" + "NwEU+RgNhoPXrHt332PEYdwO0zOL7eSLBD9AmkpP2uDjpMQ02Lu9kXG6OOfanwfS" + "jHioCvDXyl5pwSHwrHNWQRb5dLF12Fg41LMapDwR7awAKE9h6qHBonvCMBPMvqrr" + "NktqQcoQkluR9MItONJI5XHADtU="); private static final String ldapURL3 = "ldap://dir.signtrust.de:389"; private static final X509LDAPCertStoreParameters params3 = new X509LDAPCertStoreParameters.Builder( ldapURL3, "o=Deutsche Post AG, c=de"). setAACertificateSubjectAttributeName("ou"). setAttributeAuthorityRevocationListIssuerAttributeName("cn"). setAttributeCertificateAttributeSubjectAttributeName("cn"). setAttributeCertificateRevocationListIssuerAttributeName("o"). setAttributeDescriptorCertificateSubjectAttributeName("ou"). setAuthorityRevocationListIssuerAttributeName("o"). setCACertificateSubjectAttributeName("ou"). setCertificateRevocationListIssuerAttributeName("o"). setCrossCertificateSubjectAttributeName("o"). setDeltaRevocationListIssuerAttributeName("o"). setSearchForSerialNumberIn("serialNumber") .build(); private static final byte[] cert3 = Base64 .decode("MIICwDCCAimgAwIBAgIBKzANBgkqhkiG9w0BAQUFADA6MRAwDgYDVQQDEwdQQ0Ex" + "OlBOMRkwFwYDVQQKExBEZXV0c2NoZSBQb3N0IEFHMQswCQYDVQQGEwJERTAeFw0w" + "MDA0MTkyMjAwMDBaFw0wMzA0MTkyMjAwMDBaMIGOMRAwDgYDVQQEFAdN5G5jaGVy" + "MQ4wDAYDVQQqEwVLbGF1czEWMBQGA1UEAxQNS2xhdXMgTeRuY2hlcjEVMBMGA1UE" + "CRMMV2llc2Vuc3RyLiAzMQ4wDAYDVQQREwU2MzMyOTESMBAGA1UEBxMJRWdlbHNi" + "YWNoMQswCQYDVQQGEwJERTEKMAgGA1UEBRMBMTCBnzANBgkqhkiG9w0BAQEFAAOB" + "jQAwgYkCgYEAn7z6Ba9wpv/mNBIaricY/d0KpxGpqGAXdqKlvqkk/seJEoBLvmL7" + "wZz88RPELQqzDhc4oXYohS2dh3NHus9FpSPMq0JzKAcE3ArrVDxwtXtlcwN2v7iS" + "TcHurgLOb9C/r8JdsMHNgwHMkkdp96cJk/sioyP5sLPYmgWxg1JH0vMCAwEAAaOB" + "gDB+MAwGA1UdEwEB/wQCMAAwDwYDVR0PAQH/BAUDAwfAADBKBgNVHSMEQzBBoTyk" + "OjEQMA4GA1UEAxMHUENBMTpQTjEZMBcGA1UEChMQRGV1dHNjaGUgUG9zdCBBRzEL" + "MAkGA1UEBhMCREWCAQEwEQYDVR0OBAoECEAeJ6R3USjxMA0GCSqGSIb3DQEBBQUA" + "A4GBADMRtdiQJF2fg7IcedTjnAW+QGl/wNSKy7A4oaBQeahcruo+hzH+ZU+DsiSu" + "TJZaf2X1eUUEPmV+5zZlopGa3HvFfgmIYIXBw9ZO3Qb/HWGsPNgW0yg5eXEGwNEt" + "vV85BTMGuMjiuDw841IuAZaMKqOKnVXHmd2pLJz7Wv0MLJhw"); private static final byte[] caCert3 = Base64 .decode("MIICUjCCAb6gAwIBAgIDD2ptMAoGBiskAwMBAgUAMG8xCzAJBgNVBAYTAkRFMT0w" + "OwYDVQQKFDRSZWd1bGllcnVuZ3NiZWjIb3JkZSBmyHVyIFRlbGVrb21tdW5pa2F0" + "aW9uIHVuZCBQb3N0MSEwDAYHAoIGAQoHFBMBMTARBgNVBAMUCjRSLUNBIDE6UE4w" + "IhgPMjAwMDA0MTIwODIyMDNaGA8yMDA0MDQxMjA4MjIwM1owWzELMAkGA1UEBhMC" + "REUxGTAXBgNVBAoUEERldXRzY2hlIFBvc3QgQUcxMTAMBgcCggYBCgcUEwExMCEG" + "A1UEAxQaQ0EgREVSIERFVVRTQ0hFTiBQT1NUIDU6UE4wgZ8wDQYJKoZIhvcNAQEB" + "BQADgY0AMIGJAoGBAIH3c+gig1KkY5ceR6n/AMq+xz7hi3f0PMdpwIe2v2w6Hu5k" + "jipe++NvU3r6wakIY2royHl3gKWrExOisBico9aQmn8lMJnWZ7SUbB+WpRn0mAWN" + "ZM9YT+/U5hRCffeeuLWClzrbScaWnAeaaI0G+N/QKnSSjrV/l64jogyADWCTAgMB" + "AAGjEjAQMA4GA1UdDwEB/wQEAwIBBjAKBgYrJAMDAQIFAAOBgQAaV5WClEneXk9s" + "LO8zTQAsf4KvDaLd1BFcFeYM7kLLRHKeWQ0MAd0xkuAMme5NVwWNpNZP74B4HX7Q" + "/Q0h/wo/9LTgQaxw52lLs4Ml0HUyJbSFjoQ+sqgjg2fGNGw7aGkVNY5dQTAy8oSv" + "iG8mxTsQ7Fxaush3cIB0qDDwXar/hg=="); private static final byte[] crossCert3 = Base64 .decode("MIICVDCCAcCgAwIBAgIDDIOsMAoGBiskAwMBAgUAMG8xCzAJBgNVBAYTAkRFMT0w" + "OwYDVQQKFDRSZWd1bGllcnVuZ3NiZWjIb3JkZSBmyHVyIFRlbGVrb21tdW5pa2F0" + "aW9uIHVuZCBQb3N0MSEwDAYHAoIGAQoHFBMBMTARBgNVBAMUCjRSLUNBIDE6UE4w" + "IhgPMjAwMDAzMjIwOTQzNTBaGA8yMDA0MDEyMTE2MDQ1M1owbzELMAkGA1UEBhMC" + "REUxPTA7BgNVBAoUNFJlZ3VsaWVydW5nc2JlaMhvcmRlIGbIdXIgVGVsZWtvbW11" + "bmlrYXRpb24gdW5kIFBvc3QxITAMBgcCggYBCgcUEwExMBEGA1UEAxQKNVItQ0Eg" + "MTpQTjCBoTANBgkqhkiG9w0BAQEFAAOBjwAwgYsCgYEAih5BUycfBpqKhU8RDsaS" + "vV5AtzWeXQRColL9CH3t0DKnhjKAlJ8iccFtJNv+d3bh8bb9sh0maRSo647xP7hs" + "HTjKgTE4zM5BYNfXvST79OtcMgAzrnDiGjQIIWv8xbfV1MqxxdtZJygrwzRMb9jG" + "CAGoJEymoyzAMNG7tSdBWnUCBQDAAAABMAoGBiskAwMBAgUAA4GBAIBWrl6aEy4d" + "2d6U/924YK8Tv9oChmaKVhklkiTzcKv1N8dhLnLTibq4/stop03CY3rKU4X5aTfu" + "0J77FIV1Poy9jLT5Tm1NBpi71m4uO3AUoSeyhJXGQGsYFjAc3URqkznbTL/nr9re" + "IoBhf6u9cX+idnN6Uy1q+j/LOrcy3zgj"); public void performTest() throws Exception { certStoretest(); x509StoreTest(); } private void certStoretest() throws Exception { CertStore cs = CertStore.getInstance("X509LDAP", params1, "BC"); X509CertSelector sl = new X509CertSelector(); CertificateFactory cf = CertificateFactory.getInstance("X.509", "BC"); X509Certificate xcert = (X509Certificate)cf .generateCertificate(new ByteArrayInputStream(cert1)); sl.setCertificate(xcert); Collection coll = cs.getCertificates(sl); if (coll.isEmpty() || !coll.iterator().next().equals(xcert)) { fail("certificate could not be picked from LDAP directory."); } // System.out.println(coll.toArray()[0]); sl.setCertificate(null); sl.setSubject(getSubject(xcert).getEncoded()); coll = cs.getCertificates(sl); if (coll.isEmpty() || !coll.iterator().next().equals(xcert)) { fail("certificate could not be picked from LDAP directory."); } X509CRLSelector sl2 = new X509CRLSelector(); X509CRL crl = (X509CRL)cf.generateCRL(new ByteArrayInputStream(directCRL)); sl2.addIssuerName(getCRLIssuer(crl).getEncoded()); coll = cs.getCRLs(sl2); if (!coll.iterator().hasNext()) { fail("CRL could not be picked from LDAP directory."); } // System.out.println(coll.toArray()[0]); cs = CertStore.getInstance("X509LDAP", params2, "BC"); sl = new X509CertSelector(); xcert = (X509Certificate)cf .generateCertificate(new ByteArrayInputStream(cert2)); sl.setCertificate(xcert); coll = cs.getCertificates(sl); if (coll.isEmpty() || !coll.iterator().next().equals(xcert)) { fail("Certificate could not be picked from LDAP directory."); } // System.out.println(coll.toArray()[0]); cs = CertStore.getInstance("X509LDAP", params3, "BC"); sl = new X509CertSelector(); xcert = (X509Certificate)cf .generateCertificate(new ByteArrayInputStream(cert3)); sl.setCertificate(xcert); coll = cs.getCertificates(sl); if (coll.isEmpty() || !coll.iterator().next().equals(xcert)) { fail("Certificate could not be picked from LDAP directory."); } // System.out.println(coll.toArray()[0]); xcert = (X509Certificate)cf .generateCertificate(new ByteArrayInputStream(caCert3)); sl = new X509CertSelector(); sl.setSubject(getSubject(xcert).getEncoded()); coll = cs.getCertificates(sl); boolean found = false; if (coll.isEmpty()) { fail("Certificate could not be picked from LDAP directory."); } for (Iterator it = coll.iterator(); it.hasNext();) { if (it.next().equals(xcert)) { found = true; break; } } if (!found) { fail("Certificate could not be picked from LDAP directory."); } // System.out.println(coll.toArray()[0]); sl = new X509CertSelector(); xcert = (X509Certificate)cf .generateCertificate(new ByteArrayInputStream(crossCert3)); sl = new X509CertSelector(); sl.setSubject(getSubject(xcert).getEncoded()); coll = cs.getCertificates(sl); if (coll.isEmpty()) { fail("Cross certificate pair could not be picked from LDAP directory."); } found = false; for (Iterator it = coll.iterator(); it.hasNext();) { if (it.next().equals(xcert)) { found = true; break; } } if (!found) { fail("Cross certificate pair could not be picked from LDAP directory."); } // System.out.println(coll.toArray()[0]); } private void x509StoreTest() throws Exception { X509Store cs = X509Store.getInstance("CERTIFICATE/LDAP", params1, "BC"); X509CertStoreSelector sl = new X509CertStoreSelector(); CertificateFactory cf = CertificateFactory.getInstance("X.509", "BC"); X509Certificate xcert = (X509Certificate)cf .generateCertificate(new ByteArrayInputStream(cert1)); sl.setCertificate(xcert); Collection coll = cs.getMatches(sl); if (coll.isEmpty() || !coll.iterator().next().equals(xcert)) { fail("certificate could not be picked from LDAP directory."); } // System.out.println(coll.toArray()[0]); sl.setCertificate(null); sl.setSubject(getSubject(xcert).getEncoded()); coll = cs.getMatches(sl); if (coll.isEmpty() || !coll.iterator().next().equals(xcert)) { fail("certificate could not be picked from LDAP directory."); } X509CRLStoreSelector sl2 = new X509CRLStoreSelector(); X509CRL crl = (X509CRL)cf.generateCRL(new ByteArrayInputStream(directCRL)); sl2.setIssuers(Collections.singleton(crl.getIssuerX500Principal())); cs = X509Store.getInstance("CRL/LDAP", params1, "BC"); coll = cs.getMatches(sl2); if (!coll.iterator().hasNext()) { fail("CRL could not be picked from LDAP directory."); } // System.out.println(coll.toArray()[0]); cs = X509Store.getInstance("CERTIFICATE/LDAP", params2, "BC"); sl = new X509CertStoreSelector(); xcert = (X509Certificate)cf .generateCertificate(new ByteArrayInputStream(cert2)); sl.setCertificate(xcert); coll = cs.getMatches(sl); if (coll.isEmpty() || !coll.iterator().next().equals(xcert)) { fail("Certificate could not be picked from LDAP directory."); } // System.out.println(coll.toArray()[0]); cs = X509Store.getInstance("CERTIFICATE/LDAP", params3, "BC"); sl = new X509CertStoreSelector(); xcert = (X509Certificate)cf .generateCertificate(new ByteArrayInputStream(cert3)); sl.setCertificate(xcert); coll = cs.getMatches(sl); if (coll.isEmpty() || !coll.iterator().next().equals(xcert)) { fail("Certificate could not be picked from LDAP directory."); } // System.out.println(coll.toArray()[0]); xcert = (X509Certificate)cf .generateCertificate(new ByteArrayInputStream(caCert3)); sl = new X509CertStoreSelector(); sl.setSubject(getSubject(xcert).getEncoded()); coll = cs.getMatches(sl); boolean found = false; if (coll.isEmpty()) { fail("Certificate could not be picked from LDAP directory."); } for (Iterator it = coll.iterator(); it.hasNext();) { if (it.next().equals(xcert)) { found = true; break; } } if (!found) { fail("Certificate could not be picked from LDAP directory."); } // System.out.println(coll.toArray()[0]); sl = new X509CertStoreSelector(); xcert = (X509Certificate)cf .generateCertificate(new ByteArrayInputStream(crossCert3)); sl.setSubject(getSubject(xcert).getEncoded()); coll = cs.getMatches(sl); if (coll.isEmpty()) { fail("Cross certificate pair could not be picked from LDAP directory."); } found = false; for (Iterator it = coll.iterator(); it.hasNext();) { if (it.next().equals(xcert)) { found = true; break; } } if (!found) { fail("Cross certificate pair could not be picked from LDAP directory."); } // System.out.println(coll.toArray()[0]); } private X509Principal getSubject(X509Certificate cert) throws CertificateEncodingException { return PrincipalUtil.getSubjectX509Principal(cert); } private X509Principal getCRLIssuer(X509CRL crl) throws CRLException { return PrincipalUtil.getIssuerX509Principal(crl); } public String getName() { return "LDAPCertStoreTest"; } public static void main(String[] args) { Security.addProvider(new BouncyCastleProvider()); runTest(new X509LDAPCertStoreTest()); } } bouncycastle-1.49.orig/test/src/org/bouncycastle/jce/provider/test/AttrCertTest.java0000644000175000017500000006241511625362145030303 0ustar ebourgebourgpackage org.bouncycastle.jce.provider.test; import java.io.ByteArrayInputStream; import java.io.IOException; import java.math.BigInteger; import java.security.KeyFactory; import java.security.Principal; import java.security.PrivateKey; import java.security.PublicKey; import java.security.Security; import java.security.cert.CertStore; import java.security.cert.CertificateFactory; import java.security.cert.CollectionCertStoreParameters; import java.security.cert.X509Certificate; import java.security.spec.RSAPrivateCrtKeySpec; import java.security.spec.RSAPublicKeySpec; import java.util.ArrayList; import java.util.Collection; import java.util.Date; import java.util.List; import java.util.Set; import org.bouncycastle.asn1.ASN1Encodable; import org.bouncycastle.asn1.ASN1EncodableVector; import org.bouncycastle.asn1.ASN1String; import org.bouncycastle.asn1.DEROctetString; import org.bouncycastle.asn1.DERSequence; import org.bouncycastle.asn1.x509.GeneralName; import org.bouncycastle.asn1.x509.GeneralNames; import org.bouncycastle.jce.X509Principal; import org.bouncycastle.jce.provider.BouncyCastleProvider; import org.bouncycastle.util.encoders.Base64; import org.bouncycastle.util.test.SimpleTest; import org.bouncycastle.x509.AttributeCertificateHolder; import org.bouncycastle.x509.AttributeCertificateIssuer; import org.bouncycastle.x509.X509Attribute; import org.bouncycastle.x509.X509AttributeCertificate; import org.bouncycastle.x509.X509V2AttributeCertificate; import org.bouncycastle.x509.X509V2AttributeCertificateGenerator; import org.bouncycastle.x509.extension.X509ExtensionUtil; public class AttrCertTest extends SimpleTest { private static final RSAPrivateCrtKeySpec RSA_PRIVATE_KEY_SPEC = new RSAPrivateCrtKeySpec( new BigInteger("b4a7e46170574f16a97082b22be58b6a2a629798419be12872a4bdba626cfae9900f76abfb12139dce5de56564fab2b6543165a040c606887420e33d91ed7ed7", 16), new BigInteger("11", 16), new BigInteger("9f66f6b05410cd503b2709e88115d55daced94d1a34d4e32bf824d0dde6028ae79c5f07b580f5dce240d7111f7ddb130a7945cd7d957d1920994da389f490c89", 16), new BigInteger("c0a0758cdf14256f78d4708c86becdead1b50ad4ad6c5c703e2168fbf37884cb", 16), new BigInteger("f01734d7960ea60070f1b06f2bb81bfac48ff192ae18451d5e56c734a5aab8a5", 16), new BigInteger("b54bb9edff22051d9ee60f9351a48591b6500a319429c069a3e335a1d6171391", 16), new BigInteger("d3d83daf2a0cecd3367ae6f8ae1aeb82e9ac2f816c6fc483533d8297dd7884cd", 16), new BigInteger("b8f52fc6f38593dabb661d3f50f8897f8106eee68b1bce78a95b132b4e5b5d19", 16)); public static byte[] attrCert = Base64.decode( "MIIHQDCCBqkCAQEwgZChgY2kgYowgYcxHDAaBgkqhkiG9w0BCQEWDW1sb3JjaEB2" + "dC5lZHUxHjAcBgNVBAMTFU1hcmt1cyBMb3JjaCAobWxvcmNoKTEbMBkGA1UECxMS" + "VmlyZ2luaWEgVGVjaCBVc2VyMRAwDgYDVQQLEwdDbGFzcyAyMQswCQYDVQQKEwJ2" + "dDELMAkGA1UEBhMCVVMwgYmkgYYwgYMxGzAZBgkqhkiG9w0BCQEWDHNzaGFoQHZ0" + "LmVkdTEbMBkGA1UEAxMSU3VtaXQgU2hhaCAoc3NoYWgpMRswGQYDVQQLExJWaXJn" + "aW5pYSBUZWNoIFVzZXIxEDAOBgNVBAsTB0NsYXNzIDExCzAJBgNVBAoTAnZ0MQsw" + "CQYDVQQGEwJVUzANBgkqhkiG9w0BAQQFAAIBBTAiGA8yMDAzMDcxODE2MDgwMloY" + "DzIwMDMwNzI1MTYwODAyWjCCBU0wggVJBgorBgEEAbRoCAEBMYIFORaCBTU8UnVs" + "ZSBSdWxlSWQ9IkZpbGUtUHJpdmlsZWdlLVJ1bGUiIEVmZmVjdD0iUGVybWl0Ij4K" + "IDxUYXJnZXQ+CiAgPFN1YmplY3RzPgogICA8U3ViamVjdD4KICAgIDxTdWJqZWN0" + "TWF0Y2ggTWF0Y2hJZD0idXJuOm9hc2lzOm5hbWVzOnRjOnhhY21sOjEuMDpmdW5j" + "dGlvbjpzdHJpbmctZXF1YWwiPgogICAgIDxBdHRyaWJ1dGVWYWx1ZSBEYXRhVHlw" + "ZT0iaHR0cDovL3d3dy53My5vcmcvMjAwMS9YTUxTY2hlbWEjc3RyaW5nIj4KICAg" + "ICAgIENOPU1hcmt1cyBMb3JjaDwvQXR0cmlidXRlVmFsdWU+CiAgICAgPFN1Ympl" + "Y3RBdHRyaWJ1dGVEZXNpZ25hdG9yIEF0dHJpYnV0ZUlkPSJ1cm46b2FzaXM6bmFt" + "ZXM6dGM6eGFjbWw6MS4wOnN1YmplY3Q6c3ViamVjdC1pZCIgRGF0YVR5cGU9Imh0" + "dHA6Ly93d3cudzMub3JnLzIwMDEvWE1MU2NoZW1hI3N0cmluZyIgLz4gCiAgICA8" + "L1N1YmplY3RNYXRjaD4KICAgPC9TdWJqZWN0PgogIDwvU3ViamVjdHM+CiAgPFJl" + "c291cmNlcz4KICAgPFJlc291cmNlPgogICAgPFJlc291cmNlTWF0Y2ggTWF0Y2hJ" + "ZD0idXJuOm9hc2lzOm5hbWVzOnRjOnhhY21sOjEuMDpmdW5jdGlvbjpzdHJpbmct" + "ZXF1YWwiPgogICAgIDxBdHRyaWJ1dGVWYWx1ZSBEYXRhVHlwZT0iaHR0cDovL3d3" + "dy53My5vcmcvMjAwMS9YTUxTY2hlbWEjYW55VVJJIj4KICAgICAgaHR0cDovL3p1" + "bmkuY3MudnQuZWR1PC9BdHRyaWJ1dGVWYWx1ZT4KICAgICA8UmVzb3VyY2VBdHRy" + "aWJ1dGVEZXNpZ25hdG9yIEF0dHJpYnV0ZUlkPSJ1cm46b2FzaXM6bmFtZXM6dGM6" + "eGFjbWw6MS4wOnJlc291cmNlOnJlc291cmNlLWlkIiBEYXRhVHlwZT0iaHR0cDov" + "L3d3dy53My5vcmcvMjAwMS9YTUxTY2hlbWEjYW55VVJJIiAvPiAKICAgIDwvUmVz" + "b3VyY2VNYXRjaD4KICAgPC9SZXNvdXJjZT4KICA8L1Jlc291cmNlcz4KICA8QWN0" + "aW9ucz4KICAgPEFjdGlvbj4KICAgIDxBY3Rpb25NYXRjaCBNYXRjaElkPSJ1cm46" + "b2FzaXM6bmFtZXM6dGM6eGFjbWw6MS4wOmZ1bmN0aW9uOnN0cmluZy1lcXVhbCI+" + "CiAgICAgPEF0dHJpYnV0ZVZhbHVlIERhdGFUeXBlPSJodHRwOi8vd3d3LnczLm9y" + "Zy8yMDAxL1hNTFNjaGVtYSNzdHJpbmciPgpEZWxlZ2F0ZSBBY2Nlc3MgICAgIDwv" + "QXR0cmlidXRlVmFsdWU+CgkgIDxBY3Rpb25BdHRyaWJ1dGVEZXNpZ25hdG9yIEF0" + "dHJpYnV0ZUlkPSJ1cm46b2FzaXM6bmFtZXM6dGM6eGFjbWw6MS4wOmFjdGlvbjph" + "Y3Rpb24taWQiIERhdGFUeXBlPSJodHRwOi8vd3d3LnczLm9yZy8yMDAxL1hNTFNj" + "aGVtYSNzdHJpbmciIC8+IAogICAgPC9BY3Rpb25NYXRjaD4KICAgPC9BY3Rpb24+" + "CiAgPC9BY3Rpb25zPgogPC9UYXJnZXQ+CjwvUnVsZT4KMA0GCSqGSIb3DQEBBAUA" + "A4GBAGiJSM48XsY90HlYxGmGVSmNR6ZW2As+bot3KAfiCIkUIOAqhcphBS23egTr" + "6asYwy151HshbPNYz+Cgeqs45KkVzh7bL/0e1r8sDVIaaGIkjHK3CqBABnfSayr3" + "Rd1yBoDdEv8Qb+3eEPH6ab9021AsLEnJ6LWTmybbOpMNZ3tv"); byte[] signCert = Base64.decode( "MIIGjTCCBXWgAwIBAgICAPswDQYJKoZIhvcNAQEEBQAwaTEdMBsGCSqGSIb3DQEJ" + "ARYOaXJtaGVscEB2dC5lZHUxLjAsBgNVBAMTJVZpcmdpbmlhIFRlY2ggQ2VydGlm" + "aWNhdGlvbiBBdXRob3JpdHkxCzAJBgNVBAoTAnZ0MQswCQYDVQQGEwJVUzAeFw0w" + "MzAxMzExMzUyMTRaFw0wNDAxMzExMzUyMTRaMIGDMRswGQYJKoZIhvcNAQkBFgxz" + "c2hhaEB2dC5lZHUxGzAZBgNVBAMTElN1bWl0IFNoYWggKHNzaGFoKTEbMBkGA1UE" + "CxMSVmlyZ2luaWEgVGVjaCBVc2VyMRAwDgYDVQQLEwdDbGFzcyAxMQswCQYDVQQK" + "EwJ2dDELMAkGA1UEBhMCVVMwgZ8wDQYJKoZIhvcNAQEBBQADgY0AMIGJAoGBAPDc" + "scgSKmsEp0VegFkuitD5j5PUkDuzLjlfaYONt2SN8WeqU4j2qtlCnsipa128cyKS" + "JzYe9duUdNxquh5BPIkMkHBw4jHoQA33tk0J/sydWdN74/AHPpPieK5GHwhU7GTG" + "rCCS1PJRxjXqse79ExAlul+gjQwHeldAC+d4A6oZAgMBAAGjggOmMIIDojAMBgNV" + "HRMBAf8EAjAAMBEGCWCGSAGG+EIBAQQEAwIFoDAOBgNVHQ8BAf8EBAMCA/gwHQYD" + "VR0lBBYwFAYIKwYBBQUHAwIGCCsGAQUFBwMEMB0GA1UdDgQWBBRUIoWAzlXbzBYE" + "yVTjQFWyMMKo1jCBkwYDVR0jBIGLMIGIgBTgc3Fm+TGqKDhen+oKfbl+xVbj2KFt" + "pGswaTEdMBsGCSqGSIb3DQEJARYOaXJtaGVscEB2dC5lZHUxLjAsBgNVBAMTJVZp" + "cmdpbmlhIFRlY2ggQ2VydGlmaWNhdGlvbiBBdXRob3JpdHkxCzAJBgNVBAoTAnZ0" + "MQswCQYDVQQGEwJVU4IBADCBiwYJYIZIAYb4QgENBH4WfFZpcmdpbmlhIFRlY2gg" + "Q2VydGlmaWNhdGlvbiBBdXRob3JpdHkgZGlnaXRhbCBjZXJ0aWZpY2F0ZXMgYXJl" + "IHN1YmplY3QgdG8gcG9saWNpZXMgbG9jYXRlZCBhdCBodHRwOi8vd3d3LnBraS52" + "dC5lZHUvY2EvY3BzLy4wFwYDVR0RBBAwDoEMc3NoYWhAdnQuZWR1MBkGA1UdEgQS" + "MBCBDmlybWhlbHBAdnQuZWR1MEMGCCsGAQUFBwEBBDcwNTAzBggrBgEFBQcwAoYn" + "aHR0cDovL2JveDE3Ny5jYy52dC5lZHUvY2EvaXNzdWVycy5odG1sMEQGA1UdHwQ9" + "MDswOaA3oDWGM2h0dHA6Ly9ib3gxNzcuY2MudnQuZWR1L2h0ZG9jcy1wdWJsaWMv" + "Y3JsL2NhY3JsLmNybDBUBgNVHSAETTBLMA0GCysGAQQBtGgFAQEBMDoGCysGAQQB" + "tGgFAQEBMCswKQYIKwYBBQUHAgEWHWh0dHA6Ly93d3cucGtpLnZ0LmVkdS9jYS9j" + "cHMvMD8GCWCGSAGG+EIBBAQyFjBodHRwOi8vYm94MTc3LmNjLnZ0LmVkdS9jZ2kt" + "cHVibGljL2NoZWNrX3Jldl9jYT8wPAYJYIZIAYb4QgEDBC8WLWh0dHA6Ly9ib3gx" + "NzcuY2MudnQuZWR1L2NnaS1wdWJsaWMvY2hlY2tfcmV2PzBLBglghkgBhvhCAQcE" + "PhY8aHR0cHM6Ly9ib3gxNzcuY2MudnQuZWR1L35PcGVuQ0E4LjAxMDYzMC9jZ2kt" + "cHVibGljL3JlbmV3YWw/MCwGCWCGSAGG+EIBCAQfFh1odHRwOi8vd3d3LnBraS52" + "dC5lZHUvY2EvY3BzLzANBgkqhkiG9w0BAQQFAAOCAQEAHJ2ls9yjpZVcu5DqiE67" + "r7BfkdMnm7IOj2v8cd4EAlPp6OPBmjwDMwvKRBb/P733kLBqFNWXWKTpT008R0KB" + "8kehbx4h0UPz9vp31zhGv169+5iReQUUQSIwTGNWGLzrT8kPdvxiSAvdAJxcbRBm" + "KzDic5I8PoGe48kSCkPpT1oNmnivmcu5j1SMvlx0IS2BkFMksr0OHiAW1elSnE/N" + "RuX2k73b3FucwVxB3NRo3vgoHPCTnh9r4qItAHdxFlF+pPtbw2oHESKRfMRfOIHz" + "CLQWSIa6Tvg4NIV3RRJ0sbCObesyg08lymalQMdkXwtRn5eGE00SHWwEUjSXP2gR" + "3g=="); static byte[] certWithBaseCertificateID = Base64.decode( "MIIBqzCCARQCAQEwSKBGMD6kPDA6MQswCQYDVQQGEwJJVDEOMAwGA1UEChMFVU5JVE4xDDAKBgNV" + "BAsTA0RJVDENMAsGA1UEAxMEcm9vdAIEAVMVjqB6MHikdjB0MQswCQYDVQQGEwJBVTEoMCYGA1UE" + "ChMfVGhlIExlZ2lvbiBvZiB0aGUgQm91bmN5IENhc3RsZTEjMCEGA1UECxMaQm91bmN5IFByaW1h" + "cnkgQ2VydGlmaWNhdGUxFjAUBgNVBAMTDUJvdW5jeSBDYXN0bGUwDQYJKoZIhvcNAQEFBQACBQKW" + "RhnHMCIYDzIwMDUxMjEyMTIwMDQyWhgPMjAwNTEyMTkxMjAxMzJaMA8wDQYDVRhIMQaBBGVWSVAw" + "DQYJKoZIhvcNAQEFBQADgYEAUAVin9StDaA+InxtXq/av6rUQLI9p1X6louBcj4kYJnxRvTrHpsr" + "N3+i9Uq/uk5lRdAqmPFvcmSbuE3TRAsjrXON5uFiBBKZ1AouLqcr8nHbwcdwjJ9TyUNO9I4hfpSH" + "UHHXMtBKgp4MOkhhX8xTGyWg3hp23d3GaUeg/IYlXBI="); byte[] holderCertWithBaseCertificateID = Base64.decode( "MIIBwDCCASmgAwIBAgIEAVMVjjANBgkqhkiG9w0BAQUFADA6MQswCQYDVQQGEwJJVDEOMAwGA1UE" + "ChMFVU5JVE4xDDAKBgNVBAsTA0RJVDENMAsGA1UEAxMEcm9vdDAeFw0wNTExMTExMjAxMzJaFw0w" + "NjA2MTYxMjAxMzJaMD4xCzAJBgNVBAYTAklUMQ4wDAYDVQQKEwVVTklUTjEMMAoGA1UECxMDRElU" + "MREwDwYDVQQDEwhMdWNhQm9yejBaMA0GCSqGSIb3DQEBAQUAA0kAMEYCQQC0p+RhcFdPFqlwgrIr" + "5YtqKmKXmEGb4ShypL26Ymz66ZAPdqv7EhOdzl3lZWT6srZUMWWgQMYGiHQg4z2R7X7XAgERoxUw" + "EzARBglghkgBhvhCAQEEBAMCBDAwDQYJKoZIhvcNAQEFBQADgYEAsX50VPQQCWmHvPq9y9DeCpmS" + "4szcpFAhpZyn6gYRwY9CRZVtmZKH8713XhkGDWcIEMcG0u3oTz3tdKgPU5uyIPrDEWr6w8ClUj4x" + "5aVz5c2223+dVY7KES//JSB2bE/KCIchN3kAioQ4K8O3e0OL6oDVjsqKGw5bfahgKuSIk/Q="); public String getName() { return "AttrCertTest"; } private void testCertWithBaseCertificateID() throws Exception { X509AttributeCertificate attrCert = new X509V2AttributeCertificate(certWithBaseCertificateID); CertificateFactory fact = CertificateFactory.getInstance("X.509", "BC"); X509Certificate cert = (X509Certificate)fact.generateCertificate(new ByteArrayInputStream(holderCertWithBaseCertificateID)); AttributeCertificateHolder holder = attrCert.getHolder(); if (holder.getEntityNames() != null) { fail("entity names set when none expected"); } if (!holder.getSerialNumber().equals(cert.getSerialNumber())) { fail("holder serial number doesn't match"); } if (!holder.getIssuer()[0].equals(cert.getIssuerX500Principal())) { fail("holder issuer doesn't match"); } if (!holder.match(cert)) { fail("holder not matching holder certificate"); } if (!holder.equals(holder.clone())) { fail("holder clone test failed"); } if (!attrCert.getIssuer().equals(attrCert.getIssuer().clone())) { fail("issuer clone test failed"); } //equalityAndHashCodeTest(attrCert, certWithBaseCertificateID); } private void equalityAndHashCodeTest(X509AttributeCertificate attrCert, byte[] encoding) throws IOException { if (!attrCert.equals(attrCert)) { fail("same certificate not equal"); } if (!attrCert.getHolder().equals(attrCert.getHolder())) { fail("same holder not equal"); } if (!attrCert.getIssuer().equals(attrCert.getIssuer())) { fail("same issuer not equal"); } if (attrCert.getHolder().equals(attrCert.getIssuer())) { fail("wrong holder equal"); } if (attrCert.getIssuer().equals(attrCert.getHolder())) { fail("wrong issuer equal"); } X509AttributeCertificate attrCert2 = new X509V2AttributeCertificate(encoding); if (attrCert2.getHolder().hashCode() != attrCert.getHolder().hashCode()) { fail("holder hashCode test failed"); } if (!attrCert2.getHolder().equals(attrCert.getHolder())) { fail("holder equals test failed"); } if (attrCert2.getIssuer().hashCode() != attrCert.getIssuer().hashCode()) { fail("issuer hashCode test failed"); } if (!attrCert2.getIssuer().equals(attrCert.getIssuer())) { fail("issuer equals test failed"); } } private void testGenerateWithCert() throws Exception { CertificateFactory fact = CertificateFactory.getInstance("X.509","BC"); X509Certificate iCert = (X509Certificate)fact.generateCertificate(new ByteArrayInputStream(signCert)); // // a sample key pair. // RSAPublicKeySpec pubKeySpec = new RSAPublicKeySpec( new BigInteger("b4a7e46170574f16a97082b22be58b6a2a629798419be12872a4bdba626cfae9900f76abfb12139dce5de56564fab2b6543165a040c606887420e33d91ed7ed7", 16), new BigInteger("11", 16)); // // set up the keys // PrivateKey privKey; PublicKey pubKey; KeyFactory kFact = KeyFactory.getInstance("RSA", "BC"); privKey = kFact.generatePrivate(RSA_PRIVATE_KEY_SPEC); pubKey = kFact.generatePublic(pubKeySpec); X509V2AttributeCertificateGenerator gen = new X509V2AttributeCertificateGenerator(); // the actual attributes GeneralName roleName = new GeneralName(GeneralName.rfc822Name, "DAU123456789"); ASN1EncodableVector roleSyntax = new ASN1EncodableVector(); roleSyntax.add(roleName); // roleSyntax OID: 2.5.24.72 X509Attribute attributes = new X509Attribute("2.5.24.72", new DERSequence(roleSyntax)); gen.addAttribute(attributes); gen.setHolder(new AttributeCertificateHolder(iCert)); gen.setIssuer(new AttributeCertificateIssuer(new X509Principal("cn=test"))); gen.setNotBefore(new Date(System.currentTimeMillis() - 50000)); gen.setNotAfter(new Date(System.currentTimeMillis() + 50000)); gen.setSerialNumber(BigInteger.ONE); gen.setSignatureAlgorithm("SHA1WithRSAEncryption"); X509AttributeCertificate aCert = gen.generate(privKey, "BC"); aCert.checkValidity(); aCert.verify(pubKey, "BC"); AttributeCertificateHolder holder = aCert.getHolder(); if (holder.getEntityNames() != null) { fail("entity names set when none expected"); } if (!holder.getSerialNumber().equals(iCert.getSerialNumber())) { fail("holder serial number doesn't match"); } if (!holder.getIssuer()[0].equals(iCert.getIssuerX500Principal())) { fail("holder issuer doesn't match"); } if (!holder.match(iCert)) { fail("generated holder not matching holder certificate"); } X509Attribute[] attrs = aCert.getAttributes("2.5.24.72"); if (attrs == null) { fail("attributes related to 2.5.24.72 not found"); } X509Attribute attr = attrs[0]; if (!attr.getOID().equals("2.5.24.72")) { fail("attribute oid mismatch"); } ASN1Encodable[] values = attr.getValues(); GeneralName role = GeneralNames.getInstance(values[0]).getNames()[0]; if (role.getTagNo() != GeneralName.rfc822Name) { fail("wrong general name type found in role"); } if (!((ASN1String)role.getName()).getString().equals("DAU123456789")) { fail("wrong general name value found in role"); } X509Certificate sCert = (X509Certificate)fact.generateCertificate(new ByteArrayInputStream(holderCertWithBaseCertificateID)); if (holder.match(sCert)) { fail("generated holder matching wrong certificate"); } equalityAndHashCodeTest(aCert, aCert.getEncoded()); } private void testGenerateWithPrincipal() throws Exception { CertificateFactory fact = CertificateFactory.getInstance("X.509","BC"); X509Certificate iCert = (X509Certificate)fact.generateCertificate(new ByteArrayInputStream(signCert)); // // a sample key pair. // RSAPublicKeySpec pubKeySpec = new RSAPublicKeySpec( new BigInteger("b4a7e46170574f16a97082b22be58b6a2a629798419be12872a4bdba626cfae9900f76abfb12139dce5de56564fab2b6543165a040c606887420e33d91ed7ed7", 16), new BigInteger("11", 16)); // // set up the keys // PrivateKey privKey; PublicKey pubKey; KeyFactory kFact = KeyFactory.getInstance("RSA", "BC"); privKey = kFact.generatePrivate(RSA_PRIVATE_KEY_SPEC); pubKey = kFact.generatePublic(pubKeySpec); X509V2AttributeCertificateGenerator gen = new X509V2AttributeCertificateGenerator(); // the actual attributes GeneralName roleName = new GeneralName(GeneralName.rfc822Name, "DAU123456789"); ASN1EncodableVector roleSyntax = new ASN1EncodableVector(); roleSyntax.add(roleName); // roleSyntax OID: 2.5.24.72 X509Attribute attributes = new X509Attribute("2.5.24.72", new DERSequence(roleSyntax)); gen.addAttribute(attributes); gen.setHolder(new AttributeCertificateHolder(iCert.getSubjectX500Principal())); gen.setIssuer(new AttributeCertificateIssuer(new X509Principal("cn=test"))); gen.setNotBefore(new Date(System.currentTimeMillis() - 50000)); gen.setNotAfter(new Date(System.currentTimeMillis() + 50000)); gen.setSerialNumber(BigInteger.ONE); gen.setSignatureAlgorithm("SHA1WithRSAEncryption"); X509AttributeCertificate aCert = gen.generate(privKey, "BC"); aCert.checkValidity(); aCert.verify(pubKey, "BC"); AttributeCertificateHolder holder = aCert.getHolder(); if (holder.getEntityNames() == null) { fail("entity names not set when expected"); } if (holder.getSerialNumber() != null) { fail("holder serial number found when none expected"); } if (holder.getIssuer() != null) { fail("holder issuer found when none expected"); } if (!holder.match(iCert)) { fail("generated holder not matching holder certificate"); } X509Certificate sCert = (X509Certificate)fact.generateCertificate(new ByteArrayInputStream(holderCertWithBaseCertificateID)); if (holder.match(sCert)) { fail("principal generated holder matching wrong certificate"); } equalityAndHashCodeTest(aCert, aCert.getEncoded()); } public void performTest() throws Exception { X509AttributeCertificate aCert = new X509V2AttributeCertificate(attrCert); CertificateFactory fact = CertificateFactory.getInstance("X.509","BC"); X509Certificate sCert = (X509Certificate)fact.generateCertificate(new ByteArrayInputStream(signCert)); aCert.verify(sCert.getPublicKey(), "BC"); // // search test // List list = new ArrayList(); list.add(sCert); CollectionCertStoreParameters ccsp = new CollectionCertStoreParameters(list); CertStore store = CertStore.getInstance("Collection", ccsp); Collection certs = store.getCertificates(aCert.getIssuer()); if (certs.size() != 1 || !certs.contains(sCert)) { fail("sCert not found by issuer"); } X509Attribute[] attrs = aCert.getAttributes("1.3.6.1.4.1.6760.8.1.1"); if (attrs == null || attrs.length != 1) { fail("attribute not found"); } // // reencode test // aCert = new X509V2AttributeCertificate(aCert.getEncoded()); aCert.verify(sCert.getPublicKey(), "BC"); X509AttributeCertificate saCert = new X509V2AttributeCertificate(new ByteArrayInputStream(aCert.getEncoded())); if (!aCert.getNotAfter().equals(saCert.getNotAfter())) { fail("failed date comparison"); } // base generator test // // a sample key pair. // RSAPublicKeySpec pubKeySpec = new RSAPublicKeySpec( new BigInteger("b4a7e46170574f16a97082b22be58b6a2a629798419be12872a4bdba626cfae9900f76abfb12139dce5de56564fab2b6543165a040c606887420e33d91ed7ed7", 16), new BigInteger("11", 16)); RSAPrivateCrtKeySpec privKeySpec = RSA_PRIVATE_KEY_SPEC; // // set up the keys // PrivateKey privKey; PublicKey pubKey; KeyFactory kFact = KeyFactory.getInstance("RSA", "BC"); privKey = kFact.generatePrivate(privKeySpec); pubKey = kFact.generatePublic(pubKeySpec); X509V2AttributeCertificateGenerator gen = new X509V2AttributeCertificateGenerator(); gen.addAttribute(attrs[0]); gen.setHolder(aCert.getHolder()); gen.setIssuer(aCert.getIssuer()); gen.setNotBefore(new Date(System.currentTimeMillis() - 50000)); gen.setNotAfter(new Date(System.currentTimeMillis() + 50000)); gen.setSerialNumber(aCert.getSerialNumber()); gen.setSignatureAlgorithm("SHA1WithRSAEncryption"); aCert = gen.generate(privKey, "BC"); aCert.checkValidity(); aCert.verify(pubKey, "BC"); // as the issuer is the same this should still work (even though it is not // technically correct certs = store.getCertificates(aCert.getIssuer()); if (certs.size() != 1 || !certs.contains(sCert)) { fail("sCert not found by issuer"); } attrs = aCert.getAttributes("1.3.6.1.4.1.6760.8.1.1"); if (attrs == null || attrs.length != 1) { fail("attribute not found"); } // // reencode test // aCert = new X509V2AttributeCertificate(aCert.getEncoded()); aCert.verify(pubKey, "BC"); AttributeCertificateIssuer issuer = aCert.getIssuer(); Principal[] principals = issuer.getPrincipals(); // // test holder // AttributeCertificateHolder holder = aCert.getHolder(); if (holder.getEntityNames() == null) { fail("entity names not set"); } if (holder.getSerialNumber() != null) { fail("holder serial number set when none expected"); } if (holder.getIssuer() != null) { fail("holder issuer set when none expected"); } principals = holder.getEntityNames(); if (!principals[0].toString().equals("C=US, O=vt, OU=Class 2, OU=Virginia Tech User, CN=Markus Lorch (mlorch), EMAILADDRESS=mlorch@vt.edu")) { fail("principal[0] for entity names don't match"); } // // extension test // if (aCert.hasUnsupportedCriticalExtension()) { fail("unsupported extensions found with no extensions"); } gen.addExtension("1.1", true, new DEROctetString(new byte[10])); gen.addExtension("2.2", false, new DEROctetString(new byte[20])); aCert = gen.generate(privKey, "BC"); Set exts = aCert.getCriticalExtensionOIDs(); if (exts.size() != 1 || !exts.contains("1.1")) { fail("critical extension test failed"); } exts = aCert.getNonCriticalExtensionOIDs(); if (exts.size() != 1 || !exts.contains("2.2")) { fail("non-critical extension test failed"); } if (!aCert.hasUnsupportedCriticalExtension()) { fail("unsupported extensions not found"); } byte[] extString = aCert.getExtensionValue("1.1"); ASN1Encodable extValue = X509ExtensionUtil.fromExtensionValue(extString); if (!extValue.equals(new DEROctetString(new byte[10]))) { fail("wrong extension value found for 1.1"); } testCertWithBaseCertificateID(); testGenerateWithCert(); testGenerateWithPrincipal(); } public static void main( String[] args) { Security.addProvider(new BouncyCastleProvider()); runTest(new AttrCertTest()); } } bouncycastle-1.49.orig/test/src/org/bouncycastle/jce/provider/test/DigestTest.java0000644000175000017500000001212012110613172027743 0ustar ebourgebourgpackage org.bouncycastle.jce.provider.test; import java.security.MessageDigest; import java.security.Security; import org.bouncycastle.jce.provider.BouncyCastleProvider; import org.bouncycastle.util.encoders.Hex; import org.bouncycastle.util.test.SimpleTest; public class DigestTest extends SimpleTest { final static String provider = "BC"; static private String[][] abcVectors = { { "MD2", "da853b0d3f88d99b30283a69e6ded6bb" }, { "MD4", "a448017aaf21d8525fc10ae87aa6729d" }, { "MD5", "900150983cd24fb0d6963f7d28e17f72"}, { "SHA-1", "a9993e364706816aba3e25717850c26c9cd0d89d" }, { "SHA-224", "23097d223405d8228642a477bda255b32aadbce4bda0b3f7e36c9da7" }, { "SHA-256", "ba7816bf8f01cfea414140de5dae2223b00361a396177a9cb410ff61f20015ad" }, { "SHA-384", "cb00753f45a35e8bb5a03d699ac65007272c32ab0eded1631a8b605a43ff5bed8086072ba1e7cc2358baeca134c825a7" }, { "SHA-512", "ddaf35a193617abacc417349ae20413112e6fa4e89a97ea20a9eeee64b55d39a2192992a274fc1a836ba3c23a3feebbd454d4423643ce80e2a9ac94fa54ca49f" }, { "SHA-512/224", "4634270F707B6A54DAAE7530460842E20E37ED265CEEE9A43E8924AA" }, { "SHA-512/256", "53048E2681941EF99B2E29B76B4C7DABE4C2D0C634FC6D46E0E2F13107E7AF23" }, { "RIPEMD128", "c14a12199c66e4ba84636b0f69144c77" }, { "RIPEMD160", "8eb208f7e05d987a9b044a8e98c6b087f15a0bfc" }, { "RIPEMD256", "afbd6e228b9d8cbbcef5ca2d03e6dba10ac0bc7dcbe4680e1e42d2e975459b65" }, { "RIPEMD320", "de4c01b3054f8930a79d09ae738e92301e5a17085beffdc1b8d116713e74f82fa942d64cdbc4682d" }, { "Tiger", "2AAB1484E8C158F2BFB8C5FF41B57A525129131C957B5F93" }, { "GOST3411", "b285056dbf18d7392d7677369524dd14747459ed8143997e163b2986f92fd42c" }, { "WHIRLPOOL", "4E2448A4C6F486BB16B6562C73B4020BF3043E3A731BCE721AE1B303D97E6D4C7181EEBDB6C57E277D0E34957114CBD6C797FC9D95D8B582D225292076D4EEF5" } }; public String getName() { return "Digest"; } void test(String algorithm) throws Exception { byte[] message = "hello world".getBytes(); MessageDigest digest = MessageDigest.getInstance(algorithm, provider); byte[] result = digest.digest(message); byte[] result2 = digest.digest(message); // test one digest the same message with the same instance if (!MessageDigest.isEqual(result, result2)) { fail("Result object 1 not equal"); } // test two, single byte updates for (int i = 0; i < message.length; i++) { digest.update(message[i]); } result2 = digest.digest(); if (!MessageDigest.isEqual(result, result2)) { fail("Result object 2 not equal"); } // test three, two half updates digest.update(message, 0, message.length/2); digest.update(message, message.length/2, message.length-message.length/2); result2 = digest.digest(); if (!MessageDigest.isEqual(result, result2)) { fail("Result object 3 not equal"); } // test four, clone test digest.update(message, 0, message.length/2); MessageDigest d = (MessageDigest)digest.clone(); digest.update(message, message.length/2, message.length-message.length/2); result2 = digest.digest(); if (!MessageDigest.isEqual(result, result2)) { fail("Result object 4(a) not equal"); } d.update(message, message.length/2, message.length-message.length/2); result2 = d.digest(); if (!MessageDigest.isEqual(result, result2)) { fail("Result object 4(b) not equal"); } // test five, check reset() method digest.update(message, 0, message.length/2); digest.reset(); digest.update(message, 0, message.length/2); digest.update(message, message.length/2, message.length-message.length/2); result2 = digest.digest(); if (!MessageDigest.isEqual(result, result2)) { fail("Result object 5 not equal"); } } /** * Test the hash against a standard value for the string "abc" * * @param algorithm algorithm to test * @param hash expected value * @return the test result. */ void abcTest( String algorithm, String hash) throws Exception { byte[] abc = { (byte)0x61, (byte)0x62, (byte)0x63 }; MessageDigest digest = MessageDigest.getInstance(algorithm, provider); byte[] result = digest.digest(abc); if (!MessageDigest.isEqual(result, Hex.decode(hash))) { fail("abc result not equal for " + algorithm); } } public void performTest() throws Exception { for (int i = 0; i != abcVectors.length; i++) { test(abcVectors[i][0]); abcTest(abcVectors[i][0], abcVectors[i][1]); } } public static void main(String[] args) { Security.addProvider(new BouncyCastleProvider()); runTest(new DigestTest()); } } bouncycastle-1.49.orig/test/src/org/bouncycastle/jce/provider/test/X509CertificatePairTest.java0000644000175000017500000001003410524605517032165 0ustar ebourgebourgpackage org.bouncycastle.jce.provider.test; import org.bouncycastle.jce.provider.BouncyCastleProvider; import org.bouncycastle.util.test.SimpleTest; import org.bouncycastle.x509.X509CertificatePair; import java.io.ByteArrayInputStream; import java.security.Security; import java.security.cert.CertificateEncodingException; import java.security.cert.CertificateFactory; import java.security.cert.X509Certificate; public class X509CertificatePairTest extends SimpleTest { public void performTest() throws Exception { CertificateFactory cf = CertificateFactory.getInstance("X.509", "BC"); X509Certificate rootCert = (X509Certificate)cf.generateCertificate( new ByteArrayInputStream(CertPathTest.rootCertBin)); X509Certificate interCert = (X509Certificate)cf.generateCertificate( new ByteArrayInputStream(CertPathTest.interCertBin)); X509Certificate finalCert = (X509Certificate)cf.generateCertificate( new ByteArrayInputStream(CertPathTest.finalCertBin)); X509CertificatePair pair1 = new X509CertificatePair(rootCert, interCert); X509CertificatePair pair2 = new X509CertificatePair(rootCert, interCert); X509CertificatePair pair3 = new X509CertificatePair(interCert, finalCert); X509CertificatePair pair4 = new X509CertificatePair(rootCert, finalCert); X509CertificatePair pair5 = new X509CertificatePair(rootCert, null); X509CertificatePair pair6 = new X509CertificatePair(rootCert, null); X509CertificatePair pair7 = new X509CertificatePair(null, rootCert); X509CertificatePair pair8 = new X509CertificatePair(null, rootCert); if (!pair1.equals(pair2)) { fail("pair1 pair2 equality test"); } if (!pair5.equals(pair6)) { fail("pair1 pair2 equality test"); } if (!pair7.equals(pair8)) { fail("pair1 pair2 equality test"); } if (pair1.equals(null)) { fail("pair1 null equality test"); } if (pair1.hashCode() != pair2.hashCode()) { fail("pair1 pair2 hashCode equality test"); } if (pair1.equals(pair3)) { fail("pair1 pair3 inequality test"); } if (pair1.equals(pair4)) { fail("pair1 pair4 inequality test"); } if (pair1.equals(pair5)) { fail("pair1 pair5 inequality test"); } if (pair1.equals(pair7)) { fail("pair1 pair7 inequality test"); } if (pair5.equals(pair1)) { fail("pair5 pair1 inequality test"); } if (pair7.equals(pair1)) { fail("pair7 pair1 inequality test"); } if (pair1.getForward() != rootCert) { fail("pair1 forward test"); } if (pair1.getReverse() != interCert) { fail("pair1 reverse test"); } if (!areEqual(pair1.getEncoded(), pair2.getEncoded())) { fail("encoding check"); } pair4 = new X509CertificatePair(rootCert, TestUtils.createExceptionCertificate(false)); try { pair4.getEncoded(); fail("no exception on bad getEncoded()"); } catch (CertificateEncodingException e) { // expected } pair4 = new X509CertificatePair(rootCert, TestUtils.createExceptionCertificate(true)); try { pair4.getEncoded(); fail("no exception on exception getEncoded()"); } catch (CertificateEncodingException e) { // expected } } public String getName() { return "X509CertificatePair"; } public static void main(String[] args) { Security.addProvider(new BouncyCastleProvider()); runTest(new X509CertificatePairTest()); } } bouncycastle-1.49.orig/test/src/org/bouncycastle/jce/provider/test/PKCS12StoreTest.java0000644000175000017500000014120312132450311030447 0ustar ebourgebourgpackage org.bouncycastle.jce.provider.test; import java.io.ByteArrayInputStream; import java.io.ByteArrayOutputStream; import java.math.BigInteger; import java.security.Key; import java.security.KeyFactory; import java.security.KeyPair; import java.security.KeyPairGenerator; import java.security.KeyStore; import java.security.PrivateKey; import java.security.PublicKey; import java.security.Security; import java.security.cert.Certificate; import java.security.cert.X509Certificate; import java.security.interfaces.RSAPrivateKey; import java.security.spec.RSAPrivateCrtKeySpec; import java.security.spec.RSAPublicKeySpec; import java.util.Date; import java.util.Enumeration; import java.util.Hashtable; import java.util.Vector; import org.bouncycastle.asn1.ASN1Encodable; import org.bouncycastle.asn1.ASN1InputStream; import org.bouncycastle.asn1.ASN1OctetString; import org.bouncycastle.asn1.ASN1Sequence; import org.bouncycastle.asn1.ASN1StreamParser; import org.bouncycastle.asn1.DERBMPString; import org.bouncycastle.asn1.DERSequenceParser; import org.bouncycastle.asn1.pkcs.ContentInfo; import org.bouncycastle.asn1.pkcs.EncryptedData; import org.bouncycastle.asn1.pkcs.EncryptedPrivateKeyInfo; import org.bouncycastle.asn1.pkcs.PKCSObjectIdentifiers; import org.bouncycastle.asn1.pkcs.Pfx; import org.bouncycastle.asn1.pkcs.SafeBag; import org.bouncycastle.jcajce.provider.config.PKCS12StoreParameter; import org.bouncycastle.jce.PKCS12Util; import org.bouncycastle.jce.X509Principal; import org.bouncycastle.jce.interfaces.PKCS12BagAttributeCarrier; import org.bouncycastle.jce.provider.BouncyCastleProvider; import org.bouncycastle.jce.provider.JDKPKCS12StoreParameter; import org.bouncycastle.jce.provider.X509CertificateObject; import org.bouncycastle.util.encoders.Base64; import org.bouncycastle.util.encoders.Hex; import org.bouncycastle.util.test.SimpleTest; import org.bouncycastle.x509.X509V3CertificateGenerator; /** * Exercise the various key stores, making sure we at least get back what we put in! *

    * This tests both the PKCS12 key store. */ public class PKCS12StoreTest extends SimpleTest { static char[] passwd = { 'h', 'e', 'l', 'l', 'o', ' ', 'w', 'o', 'r', 'l', 'd' }; // // pkcs-12 pfx-pdu // byte[] pkcs12 = Base64.decode( "MIACAQMwgAYJKoZIhvcNAQcBoIAkgAQBMAQBgAQBMAQBgAQBBgQBCQQJKoZI" + "hvcNAQcBBAGgBAGABAEkBAGABAEEBAEBBAEwBAEEBAEDBAOCAzQEAQQEAQEE" + "ATAEAQQEAQMEA4IDMAQBBAQBAQQBBgQBBAQBAQQBCwQBBAQBCwQLKoZIhvcN" + "AQwKAQIEAQQEAQEEAaAEAQQEAQMEA4ICpQQBBAQBAQQBMAQBBAQBAwQDggKh" + "BAEEBAEBBAEwBAEEBAEBBAEbBAEEBAEBBAEGBAEEBAEBBAEKBAEEBAEKBAoq" + "hkiG9w0BDAEDBAEEBAEPBA8wDQQIoagiwNZPJR4CAQEEAQQEAQEEAQQEAQQE" + "AQMEA4ICgAQBBAQDggKABIICgEPG0XlhMFyrs4ZWDrvEzl51ICfXd6K2ql2l" + "nnxhszUbigtSj6x49VEx4PfOB9fQFeidc5L5An+nKp646NBMIY0UwXGs8BLQ" + "au59jtOs987+l7QYIvl6fdGUIuLPhVSnZZDyqD+HQjU/0/ccKFHRif4tlEQq" + "aErvZbFeH0pg4ijf1HfgX6gBJGRKdO+msa4qKGnZdHCSLZehyyxvxAmURetg" + "yhtEl7RmedTB+4TDs7atekqxkNlD9tfwDUX6sb0IH6qbEA6P/DlVMdaD54Cl" + "QDxRzOfIIjklZhv5OMFWtPK0aYPcqyxzLpw1qRAyoTVXpidkj/hpIpgCVBP/" + "k5s2+WdGbLgA/4/zSrF6feRCE5llzM2IGxiHVq4oPzzngl3R+Fi5VCPDMcuW" + "NRuIOzJA+RNV2NPOE/P3knThDnwiImq+rfxmvZ1u6T06s20RmWK6cxp7fTEw" + "lQ9BOsv+mmyV8dr6cYJq4IlRzHdFOyEUBDwfHThyribNKKobO50xh2f93xYj" + "Rn5UMOQBJIe3b7OKZt5HOIMrJSZO02IZgvImi9yQWi96PnWa419D1cAsLWvM" + "xiN0HqZMbDFfxVM2BZmsxiexLhkHWKwLqfQDzRjJfmVww8fnXpWZhFXKyut9" + "gMGEyCNoba4RU3QI/wHKWYaK74qtJpsucuLWBH6UcsHsCry6VZkwRxWwC0lb" + "/F3Bm5UKHax5n9JHJ2amQm9zW3WJ0S5stpPObfmg5ArhbPY+pVOsTqBRlop1" + "bYJLD/X8Qbs468Bwzej0FhoEU59ZxFrbjLSBsMUYrVrwD83JE9kEazMLVchc" + "uCB9WT1g0hxYb7VA0BhOrWhL8F5ZH72RMCYLPI0EAQQEAQEEATEEAQQEAQEE" + "AXgEAQQEAQEEATAEAQQEAQEEAVEEAQQEAQEEAQYEAQQEAQEEAQkEAQQEAQkE" + "CSqGSIb3DQEJFAQBBAQBAQQBMQQBBAQBAQQBRAQBBAQBAQQBHgQBBAQBAQQB" + "QgQBBAQBQgRCAEQAYQB2AGkAZAAgAEcALgAgAEgAbwBvAGsAJwBzACAAVgBl" + "AHIAaQBTAGkAZwBuACwAIABJAG4AYwAuACAASQBEBAEEBAEBBAEwBAEEBAEB" + "BAEjBAEEBAEBBAEGBAEEBAEBBAEJBAEEBAEJBAkqhkiG9w0BCRUEAQQEAQEE" + "ATEEAQQEAQEEARYEAQQEAQEEAQQEAQQEAQEEARQEAQQEARQEFKEcMJ798oZL" + "FkH0OnpbUBnrTLgWBAIAAAQCAAAEAgAABAEwBAGABAEGBAEJBAkqhkiG9w0B" + "BwYEAaAEAYAEATAEAYAEAQIEAQEEAQAEATAEAYAEAQYEAQkECSqGSIb3DQEH" + "AQQBMAQBGwQBBgQBCgQKKoZIhvcNAQwBBgQPMA0ECEE7euvmxxwYAgEBBAGg" + "BAGABAEEBAEIBAgQIWDGlBWxnwQBBAQBCAQI2WsMhavhSCcEAQQEAQgECPol" + "uHJy9bm/BAEEBAEQBBCiRxtllKXkJS2anKD2q3FHBAEEBAEIBAjKy6BRFysf" + "7gQBBAQDggMwBIIDMJWRGu2ZLZild3oz7UBdpBDUVMOA6eSoWiRIfVTo4++l" + "RUBm8TpmmGrVkV32PEoLkoV+reqlyWCvqqSjRzi3epQiVwPQ6PV+ccLqxDhV" + "pGWDRQ5UttDBC2+u4fUQVZi2Z1i1g2tsk6SzB3MKUCrjoWKvaDUUwXo5k9Vz" + "qSLWCLTZCjs3RaY+jg3NbLZYtfMDdYovhCU2jMYV9adJ8MxxmJRz+zPWAJph" + "LH8hhfkKG+wJOSszqk9BqGZUa/mnZyzeQSMTEFga1ZB/kt2e8SZFWrTZEBgJ" + "oszsL5MObbwMDowNurnZsnS+Mf7xi01LeG0VT1fjd6rn9BzVwuMwhoqyoCNo" + "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"); byte[] certUTF = Base64.decode( "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" + "RgICCAA="); byte[] pkcs12noFriendly = Base64.decode( "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" + "tTy3wnQisALy9aYECKiM2gZrLi+fAAA="); static char[] noFriendlyPassword = "sschette12".toCharArray(); byte[] pkcs12StorageIssue = Base64.decode( "MIIO8QIBAzCCDrEGCSqGSIb3DQEHAaCCDqIEgg6eMIIOmjCCBBMGCSqGSIb3" + "DQEHAaCCBAQEggQAMIID/DCCA/gGCyqGSIb3DQEMCgECoIICtjCCArIwHAYK" + "KoZIhvcNAQwBAzAOBAgURJ+/5hA2pgICB9AEggKQYZ4POE8clgH9Bjd1XO8m" + "sr6NiRBiA08CllHSOn2RzyAgHTa+cKaWrEVVJ9mCd9XveSUCoBF9E1C3jSl0" + "XIqLNgYd6mWK9BpeMRImM/5crjy///K4ab9kymzkc5qc0pIpdCQCZ04YmtFP" + "B80VCgyaoh2xoxqgjBCIgdSg5XdepdA5nXkG9EsQ1oVUyCykv20lKgKKRseG" + "Jo23AX8YUYR7ANqP2gz9lvlX6RBczuoZ62ujopUexiQgt5SZx97sgo3o/b/C" + "px17A2L4wLdeAYCMCsZhC2UeaqnZCHSsvnPZfRGiuSEGbV5gHLmXszLDaEdQ" + "Bo873GTpKTTzBfRFzNCtYtZRqh2AUsInWZWQUcCeX6Ogwa0wTonkp18/tqsh" + "Fj1fVpnsRmjJTTXFxkPtUw5GPJnDAM0t1xqV7kOjN76XnZrMyk2azQ1Mf3Hn" + "sGpF+VRGH6JtxbM0Jm5zD9uHcmkSfNR3tP/+vHOB1mkIR9tD2cHvBg7pAlPD" + "RfDVWynhS+UBNlQ0SEM/pgR7PytRSUoKc/hhe3N8VerF7VL3BwWfBLlZFYZH" + "FvPQg4coxF7+We7nrSQfXvdVBP9Zf0PTdf3pbZelGCPVjOzbzY/o/cB23IwC" + "ONxlY8SC1nJDXrPZ5sY51cg/qUqor056YqipRlI6I+FoTMmMDKPAiV1V5ibo" + "DNQJkyv/CAbTX4+oFlxgddTwYcPZgd/GoGjiP9yBHHdRISatHwMcM06CzXJS" + "s3MhzXWD4aNxvvSpXAngDLdlB7cm4ja2klmMzL7IuxzLXFQFFvYf7IF5I1pC" + "YZOmTlJgp0efL9bHjuHFnh0S0lPtlGDOjJ/4YpWvSKDplcPiXhaFVjsUtclE" + "oxCC5xppRm8QWS8xggEtMA0GCSsGAQQBgjcRAjEAMBMGCSqGSIb3DQEJFTEG" + "BAQBAAAAMGkGCSsGAQQBgjcRATFcHloATQBpAGMAcgBvAHMAbwBmAHQAIABS" + "AFMAQQAgAFMAQwBoAGEAbgBuAGUAbAAgAEMAcgB5AHAAdABvAGcAcgBhAHAA" + "aABpAGMAIABQAHIAbwB2AGkAZABlAHIwgZsGCSqGSIb3DQEJFDGBjR6BigA3" + "AGQAZQBmADUAYgA0ADMANgBjAGEAYgBkADAAMAAyAGQAZAAyADkAMAAzAGIA" + "MQA2ADgANgBjADcAOQA0ADgAXwA0ADYAZgAyADYAZgBkADQALQA4ADEAMgBk" + "AC0ANABlAGYAYgAtADgAMAA4ADgALQA0ADUAYQBiADkAMQA5ADEAMAA3AGMA" + "YzCCCn8GCSqGSIb3DQEHBqCCCnAwggpsAgEAMIIKZQYJKoZIhvcNAQcBMBwG" + "CiqGSIb3DQEMAQYwDgQIbr2xdnQ9inMCAgfQgIIKOHg9VKz+jlM+3abi3cp6" + "/XMathxDSEJLrxJs6j5DAVX17S4sw1Q/1pptjdMdd8QtTfUB6JpfgJ5Kpn+h" + "gZMf6M8wWue0U/RZN0D9w7o+2n+X3ItdEXu80eJVDOm7I2p8qiXtijbMbXRL" + "Cup1lgfPM5uv2D63/hmWRXLeG8eySrJnKENngpM559V8TI2JcTUBy1ZP3kcH" + "KbcJ/tVPnIIe4qguxfsTmDtAQviGvWUohbt+RGFmtqfgntK7o6b+S8uRSwEs" + "fOU/pnVE9M1ugtNJZI/xeGJq6umZWXA/OrAcK7feWUwqRvfivDGQJEoggByd" + "4/g92PhK1JGkwlCb1HdfhOOKKChowQ4zVvSOm+uBxARGhk2i5uW9I20I0vSJ" + "px42O2VFVJweOchfp+wBtSHBKYP1ZXyXWMvOtULClosSeesbYMAwvyBfpYEz" + "3rQt/1iZkqDmEisXk8X1aEKG1KSWaSPyb/+6glWikDm+YdQw3Khu7IZt1l/H" + "qWGecccel+R9mT4YjRzHlahUYk4U+RNVasVpH1Kxz2j3CZqL+b3jQOwSAPd/" + "hKI+S/pjIpBPfiC4WxORAzGZzY2j+a79B70h1DO1D9jGur3vJDbdmGBNgs6d" + "nonE1B527SICcGeXY1MtnZCLOPvySih0AvOekbN9x2CJg+Hp9e7A3Fxni53/" + "oMLr9wGRRDki72eXCXW98mU8VJofoWYS1/VBLXGf/f+tJ9J02PpzxleqPH9T" + "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" + "g141BQ=="); static char[] storagePassword = "pass".toCharArray(); byte[] pkcs12nopass = Base64.decode( "MIIMvgIBAzCCDIQGCSqGSIb3DQEHAaCCDHUEggxxMIIMbTCCCS8GCSqGSIb3" + "DQEHBqCCCSAwggkcAgEAMIIJFQYJKoZIhvcNAQcBMBwGCiqGSIb3DQEMAQYw" + "DgQIfnlhuZRR6/YCAggAgIII6DYgeRwq5n9kzvohZ3JuK+fB+9jZ7Or6EGBA" + "GDxtBfHmSNUBWJEV/I8wV1zrKKoW/CaoZfA61pyrVZRd/roaqBx/koTFoh/g" + "woyyWTRV9gYTXSVqPQgCH+e2dISAa6UGO+/YOWOOwG2X3t8tS+3FduFQFLt5" + "cvUP98zENdm57Aef5pKpBSZDLIAoTASfmqwszWABRh2p/wKOHcCQ9Aj2e2vs" + "pls/ntIv81MqPuxHttwX8e+3dKWGFrJRztLpCD2aua8VkSsHFsPxEHkezX4O" + "6/VCjMCRFGophTS4dgKKtQIhZ9i/ESlr6sGKgIpyG99ALFpNEhtTKe+T3boE" + "sEkhGDquSpu4PGz2m0W5sej1DyFkKX4zIbeMDAb1y3O7aP0F+Llo9QSeGsOA" + "aCwND3NUAKBMOHzwdyNQcuCGCqY8j5rrSt99A5FMs3UVW3XU6hRCx7JlzO05" + "PNCkcPRSnKSNzBhIR5W0qj4PAZnQTfX+wbtUaDLIqsObX4Muh2l3gl+JmdpO" + "53U7ILqN8PAPly1eT+fIrUmlMmFhvo6LbTB7B2K728wsA/5wROlud/mOQz4s" + "quS288YsnVc9ExSZKodWa3Pqcdb/cgKNJYDxrR6/eBHOj+0RLK/1yTK9ghj7" + "IPYHoEqQbw768WK92RjM+RFGlXASkQhR9y4weWj/388uAWMIbQ+R2Zi4nb31" + "knjqRPFThysG1bsRL04/9PgysaasfS9KYOeAlLqp+Ar4gJrof5fytBuY+6wm" + "/J8eEdNw7VPV1cz/4rhrd2sfJQwDEN/iZoy8rTwe7wozpwZI0lwH11BBbav+" + "1AMfI79jjxhqOeo7uxE2NzUmSd05JYI7a94tcRzGQyGEKpGxYCRamzFW23qb" + "vG5Hcqi7Tdd7eTxw4c60l/vQLSo38g6ST5yZrK3URLiAtpioPyjrq2jnVfie" + "QLsiAHhpHF01+t+OcKv3UjwdEyBmQ34h9klwiG7iwBFXZaPXFCF2Np1TqFVG" + "jjBzmB+hRddEiYwN+XGCKB2Cvgc5ZMQ8LG9jQmEKLmOjuumz1ciAVY2qtl1s" + "HYSvfNsIAV/gGzHshOVF19JmGtcQt3pMtupoRh+sh8jY2/x5eIKrj2Jx6HPd" + "p/6IPUr54j0xSd6j7gWuXMj/eKp/utMNuBzAhkydnhXYedvTDYIj7SyPPIHa" + "qtam8rxTDWn2AOxp7OXTgPmo1GU2zW1OLL1D3MFlS+oaRMfhgNrhW+QP5ay6" + "ge4QLijpnSM+p0CbFAOClwzgdJV56bBVV09sDqSBXnG9MeEv5nDaH3I+GpPA" + "UgDkaI4zT61kaGgk0uNMf3czy2ycoQzTx0iHDTXSdSqvUC1yFza8UG4AYaKz" + "14gtSL7StvZtK0Y8oI084BINI1LgrWyrOLj7vkds4WrKhXm21BtM1GbN/pFh" + "XI41h+XoD8KnEPqJ36rAgBo1uHqTNJCC7YikDE/dEvq6MkOx+Nug1YZRHEyi" + "3AHry5u1HJHtxT34HXBwRXvnstuFhvU6cjc1WY1dJhu1p82TGnx7OBo/QbcM" + "8MRrWmWuU5eW4jWbriGNGYfvZy+tHnGwy0bIeqrsHOG6/JwvfmYYXe64sryH" + "5Qo96SZtcTJZaNFwuBY+bFUuOWm8YrT1L7Gl2Muf3pEVtNHLeYARBo1jEAym" + "Cb4jw0oodZqbPKdyyzUZu69fdTJiQkMUcKDfHJEGK0Li9SvtdqJLiiJs57Tb" + "YfOvn+TIuC40ssJFtmtlGCVH/0vtKLWYeW1NYAMzgI/nlhQ7W6Aroh8sZnqv" + "SwxeQmRJaVLxiV6YveTKuVlCbqNVLeEtKYAujgnJtPemGCPbwZpwlBw6V+Dz" + "oXveOBcUqATztWJeNv7RbU0Mk7k057+DNxXBIU+eHRGquyHQSBXxBbA+OFuu" + "4SPfEAyoYed0HEaoKN9lIsBW1xTROI30MZvaJXvPdLsa8izXGPLnTGmoI+fv" + "tJ644HtBCCCr3Reu82ZsTSDMxspZ9aa4ro9Oza+R5eULXDhVXedbhJBYiPPo" + "J37El5lRqOgu2SEilhhVQq3ZCugsinCaY9P/RtWG4CFnH1IcIT5+/mivB48I" + "2XfH6Xq6ziJdj2/r86mhEnz9sKunNvYPBDGlOvI7xucEf9AiEQoTR1xyFDbW" + "ljL4BsJqgsHN02LyUzLwqMstwv+/JH1wUuXSK40Kik/N7+jEFW2C+/N8tN7l" + "RPKSLaTjxVuTfdv/BH1dkV4iGFgpQrdWkWgkb+VZP9xE2mLz715eIAg13x6+" + "n97tc9Hh375xZJqwr3QyYTXWpsK/vx04RThv8p0qMdqKvf3jVQWwnCnoeBv2" + "L4h/uisOLY18qka/Y48ttympG+6DpmzXTwD1LycoG2SOWckCMmJhZK40+zr3" + "NVmWf6iJtbLGMxI/kzTqbTaOfXc2MroertyM1rILRSpgnJFxJfai5Enspr9b" + "SCwlP718jG2lQsnYlw8CuxoZAiaNy4MmC5Y3qNl3hlcggcHeLodyGkSyRsBg" + "cEiKSL7JNvqr0X/nUeW28zVxkmQsWlp3KmST8agf+r+sQvw52fXNLdYznGZV" + "rJrwgNOoRj0Z70MwTns3s/tCqDEsy5Sv/5dZW2uQEe7/wvmsP2WLu73Rwplg" + "1dwi/Uo9lO9dkEzmoIK5wMPCDINxL1K+0Y79q0tIAEMDgaIxmtRpEh8/TEsA" + "UwyEErkDsQqgGviH+ePmawJ/yehYHTRfYUgdUflwApJxRx65pDeSYkiYboMU" + "8WSAQY2nh/p9hLlS4zbz9dCK2tzVyRkJgqNy/c4IpiHEx2l1iipW9vENglqx" + "dYP4uqD8e3OOLjDQKizWx2t1u7GRwoEVQ3d3QzzOvsRcv7h+6vNsmYqE6phe" + "wKFZLctpSn21zkyut444ij4sSr1OG68dEXLY0t0mATfTmXXy5GJBsdK/lLfk" + "YTIPYYeDMle9aEicDqaKqkZUuYPnVchGp8UFMJ3M0n48OMDdDvpzBLTxxZeW" + "cK5v/m3OEo3jgxy9wXfZdz//J3zXXqvX8LpMy1K9X0uCBTz6ERlawviMQhg1" + "1okD5zCCAzYGCSqGSIb3DQEHAaCCAycEggMjMIIDHzCCAxsGCyqGSIb3DQEM" + "CgECoIICpjCCAqIwHAYKKoZIhvcNAQwBAzAOBAj3QoojTSbZqgICCAAEggKA" + "YOSp5XGdnG1pdm9CfvlAaUSHRCOyNLndoUTqteTZjHTEM9bGwNXAx4/R5H2Q" + "PnPm5HB/ynVSXX0uKdW6YlbqUyAdV3eqE4X3Nl+K7ZoXmgAFnMr0tveBhT1b" + "7rTi0TN4twjJzBTkKcxT8XKjvpVizUxGo+Ss5Wk8FrWLHAiC5dZvgRemtGcM" + "w5S09Pwj+qXpjUhX1pB5/63qWPrjVf+Bfmlz4bWcqogGk0i7eg+OdTeWMrW0" + "KR9nD1+/uNEyc4FdGtdIPnM+ax0E+vcco0ExQpTXe0xoX4JW7O71d550Wp89" + "hAVPNrJA5eUbSWNsuz+38gjUJ+4XaAEhcA7HZIp6ZyxtzSJUoh7oqpRktoxu" + "3cSVqVxIqAEqlNn6j0vbKfW91Od5DI5L+BIxY4xqXS7fdwipj9r6qWA8t9QU" + "C2r1A+xXpZ4jEh6inHW9qlfACBBrYf8pSDakSR6yTbaA07LExw0IXz5oiQYt" + "s7yx231CZlOH88bBmruLOIZsJjeg/lf63zI7Gg4F85QG3RqEJnY2pinLUTP7" + "R62VErFZPc2a85r2dbFH1mSQIj/rT1IKe32zIW8xoHC4VwrPkT3bcLFAu2TH" + "5k5zSI/gZUKjPDxb2dwLM4pvsj3gJ9vcFZp6BCuLkZc5rd7CyD8HK9PrBLKd" + "H3Yngy4A08W4U3XUtIux95WE+5O/UEmSF7fr2vT//DwZArGUpBPq4Bikb8cv" + "0wpOwUv8r0DXveeaPsxdipXlt29Ayywcs6KIidLtCaCX6/0u/XtMsGNFS+ah" + "OlumTGBFpbLnagvIf0GKNhbg2lTjflACnxIj8d+QWsnrIU1uC1JRRKCnhpi2" + "veeWd1m8GUb3aTFiMCMGCSqGSIb3DQEJFTEWBBS9g+Xmq/8B462FWFfaLWd/" + "rlFxOTA7BgkqhkiG9w0BCRQxLh4sAEMAZQByAHQAeQBmAGkAawBhAHQAIAB1" + "AHoAeQB0AGsAbwB3AG4AaQBrAGEwMTAhMAkGBSsOAwIaBQAEFKJpUOIj0OtI" + "j2CPp38YIFBEqvjsBAi8G+yhJe3A/wICCAA="); /** * we generate a self signed certificate for the sake of testing - RSA */ public Certificate createCert( PublicKey pubKey, PrivateKey privKey, String issuerEmail, String subjectEmail) throws Exception { // // distinguished name table. // Hashtable issuerAttrs = new Hashtable(); issuerAttrs.put(X509Principal.C, "AU"); issuerAttrs.put(X509Principal.O, "The Legion of the Bouncy Castle"); issuerAttrs.put(X509Principal.L, "Melbourne"); issuerAttrs.put(X509Principal.ST, "Victoria"); issuerAttrs.put(X509Principal.EmailAddress, issuerEmail); Hashtable subjectAttrs = new Hashtable(); subjectAttrs.put(X509Principal.C, "AU"); subjectAttrs.put(X509Principal.O, "The Legion of the Bouncy Castle"); subjectAttrs.put(X509Principal.L, "Melbourne"); subjectAttrs.put(X509Principal.ST, "Victoria"); subjectAttrs.put(X509Principal.EmailAddress, subjectEmail); Vector order = new Vector(); order.add(X509Principal.C); order.add(X509Principal.O); order.add(X509Principal.L); order.add(X509Principal.ST); order.add(X509Principal.EmailAddress); // // extensions // // // create the certificate - version 3 // X509V3CertificateGenerator certGen = new X509V3CertificateGenerator(); certGen.setSerialNumber(BigInteger.valueOf(1)); certGen.setIssuerDN(new X509Principal(order, issuerAttrs)); certGen.setNotBefore(new Date(System.currentTimeMillis() - 1000L * 60 * 60 * 24 * 30)); certGen.setNotAfter(new Date(System.currentTimeMillis() + (1000L * 60 * 60 * 24 * 30))); certGen.setSubjectDN(new X509Principal(order, subjectAttrs)); certGen.setPublicKey(pubKey); certGen.setSignatureAlgorithm("MD5WithRSAEncryption"); return certGen.generate(privKey); } public void testPKCS12Store() throws Exception { BigInteger mod = new BigInteger("bb1be8074e4787a8d77967f1575ef72dd7582f9b3347724413c021beafad8f32dba5168e280cbf284df722283dad2fd4abc750e3d6487c2942064e2d8d80641aa5866d1f6f1f83eec26b9b46fecb3b1c9856a303148a5cc899c642fb16f3d9d72f52526c751dc81622c420c82e2cfda70fe8d13f16cc7d6a613a5b2a2b5894d1", 16); KeyStore store = KeyStore.getInstance("PKCS12", "BC"); ByteArrayInputStream stream = new ByteArrayInputStream(pkcs12); store.load(stream, passwd); Enumeration en = store.aliases(); String pName = null; while (en.hasMoreElements()) { String n = (String)en.nextElement(); if (store.isKeyEntry(n)) { pName = n; } else { // the store's we're using here are consistent so this test will pass - it's actually // possible for this test to fail in other circumstances as PKCS#12 allows certificates // to be stored multiple times under different aliases. X509Certificate cert = (X509Certificate)store.getCertificate(n); if (!store.getCertificateAlias(cert).equals(n)) { fail("certificate alias check fails"); } } } PrivateKey key = (PrivateKey)store.getKey(pName, null); if (!((RSAPrivateKey)key).getModulus().equals(mod)) { fail("Modulus doesn't match."); } Certificate[] ch = store.getCertificateChain(pName); if (ch.length != 3) { fail("chain was wrong length"); } if (!((X509Certificate)ch[0]).getSerialNumber().equals(new BigInteger("96153094170511488342715101755496684211"))) { fail("chain[0] wrong certificate."); } if (!((X509Certificate)ch[1]).getSerialNumber().equals(new BigInteger("279751514312356623147411505294772931957"))) { fail("chain[1] wrong certificate."); } if (!((X509Certificate)ch[2]).getSerialNumber().equals(new BigInteger("11341398017"))) { fail("chain[2] wrong certificate."); } // // save test // ByteArrayOutputStream bOut = new ByteArrayOutputStream(); store.store(bOut, passwd); stream = new ByteArrayInputStream(bOut.toByteArray()); store.load(stream, passwd); key = (PrivateKey)store.getKey(pName, null); if (!((RSAPrivateKey)key).getModulus().equals(mod)) { fail("Modulus doesn't match."); } // // save test using LoadStoreParameter // bOut = new ByteArrayOutputStream(); PKCS12StoreParameter storeParam = new PKCS12StoreParameter(bOut, passwd, true); store.store(storeParam); byte[] data = bOut.toByteArray(); stream = new ByteArrayInputStream(data); store.load(stream, passwd); key = (PrivateKey)store.getKey(pName, null); if (!((RSAPrivateKey)key).getModulus().equals(mod)) { fail("Modulus doesn't match."); } ASN1Encodable outer = new ASN1StreamParser(data).readObject(); if (!(outer instanceof DERSequenceParser)) { fail("Failed DER encoding test."); } // // save test using LoadStoreParameter // bOut = new ByteArrayOutputStream(); JDKPKCS12StoreParameter oldParam = new JDKPKCS12StoreParameter(); oldParam.setOutputStream(bOut); oldParam.setPassword(passwd); oldParam.setUseDEREncoding(true); store.store(oldParam); data = bOut.toByteArray(); stream = new ByteArrayInputStream(data); store.load(stream, passwd); key = (PrivateKey)store.getKey(pName, null); if (!((RSAPrivateKey)key).getModulus().equals(mod)) { fail("Modulus doesn't match."); } outer = new ASN1StreamParser(data).readObject(); if (!(outer instanceof DERSequenceParser)) { fail("Failed DER encoding test."); } // // delete test // store.deleteEntry(pName); if (store.getKey(pName, null) != null) { fail("Failed deletion test."); } // cert chain test // store.setCertificateEntry("testCert", ch[2]); if (store.getCertificateChain("testCert") != null) { fail("Failed null chain test."); } // // UTF 8 single cert test // store = KeyStore.getInstance("PKCS12", "BC"); stream = new ByteArrayInputStream(certUTF); store.load(stream, "user".toCharArray()); if (store.getCertificate("37") == null) { fail("Failed to find UTF cert."); } // // try for a self generated certificate // RSAPublicKeySpec pubKeySpec = new RSAPublicKeySpec( new BigInteger("b4a7e46170574f16a97082b22be58b6a2a629798419be12872a4bdba626cfae9900f76abfb12139dce5de56564fab2b6543165a040c606887420e33d91ed7ed7", 16), new BigInteger("11", 16)); RSAPrivateCrtKeySpec privKeySpec = new RSAPrivateCrtKeySpec( new BigInteger("b4a7e46170574f16a97082b22be58b6a2a629798419be12872a4bdba626cfae9900f76abfb12139dce5de56564fab2b6543165a040c606887420e33d91ed7ed7", 16), new BigInteger("11", 16), new BigInteger("9f66f6b05410cd503b2709e88115d55daced94d1a34d4e32bf824d0dde6028ae79c5f07b580f5dce240d7111f7ddb130a7945cd7d957d1920994da389f490c89", 16), new BigInteger("c0a0758cdf14256f78d4708c86becdead1b50ad4ad6c5c703e2168fbf37884cb", 16), new BigInteger("f01734d7960ea60070f1b06f2bb81bfac48ff192ae18451d5e56c734a5aab8a5", 16), new BigInteger("b54bb9edff22051d9ee60f9351a48591b6500a319429c069a3e335a1d6171391", 16), new BigInteger("d3d83daf2a0cecd3367ae6f8ae1aeb82e9ac2f816c6fc483533d8297dd7884cd", 16), new BigInteger("b8f52fc6f38593dabb661d3f50f8897f8106eee68b1bce78a95b132b4e5b5d19", 16)); // // set up the keys // PrivateKey privKey = null; PublicKey pubKey = null; try { KeyFactory fact = KeyFactory.getInstance("RSA", "BC"); privKey = fact.generatePrivate(privKeySpec); pubKey = fact.generatePublic(pubKeySpec); } catch (Exception e) { fail("error setting up keys - " + e.toString()); } Certificate[] chain = new Certificate[1]; chain[0] = createCert(pubKey, privKey, "issuer@bouncycastle.org", "subject@bouncycastle.org"); testSupportedTypes(privKey, chain); store = KeyStore.getInstance("PKCS12", "BC"); store.load(null, null); store.setKeyEntry("privateKey", privKey, null, chain); if (!store.containsAlias("privateKey") || !store.containsAlias("PRIVATEKEY")) { fail("couldn't find alias privateKey"); } if (store.isCertificateEntry("privateKey")) { fail("key identified as certificate entry"); } if (!store.isKeyEntry("privateKey") || !store.isKeyEntry("PRIVATEKEY")) { fail("key not identified as key entry"); } if (!"privateKey".equals(store.getCertificateAlias(chain[0]))) { fail("Did not return alias for key certificate privateKey"); } ByteArrayOutputStream store1Stream = new ByteArrayOutputStream(); store.store(store1Stream, passwd); testNoExtraLocalKeyID(store1Stream.toByteArray()); // // no friendly name test // store = KeyStore.getInstance("PKCS12", "BC"); stream = new ByteArrayInputStream(pkcs12noFriendly); store.load(stream, noFriendlyPassword); en = store.aliases(); pName = null; while (en.hasMoreElements()) { String n = (String)en.nextElement(); if (store.isKeyEntry(n)) { pName = n; } } ch = store.getCertificateChain(pName); for (int i = 0; i != ch.length; i++) { //System.out.println(ch[i]); } if (ch.length != 1) { fail("no cert found in pkcs12noFriendly"); } // // failure tests // ch = store.getCertificateChain("dummy"); store.getCertificateChain("DUMMY"); store.getCertificate("dummy"); store.getCertificate("DUMMY"); // // storage test // store = KeyStore.getInstance("PKCS12", "BC"); stream = new ByteArrayInputStream(pkcs12StorageIssue); store.load(stream, storagePassword); en = store.aliases(); pName = null; while (en.hasMoreElements()) { String n = (String)en.nextElement(); if (store.isKeyEntry(n)) { pName = n; } } ch = store.getCertificateChain(pName); if (ch.length != 2) { fail("Certificate chain wrong length"); } store.store(new ByteArrayOutputStream(), storagePassword); // // basic certificate check // store.setCertificateEntry("cert", ch[1]); if (!store.containsAlias("cert") || !store.containsAlias("CERT")) { fail("couldn't find alias cert"); } if (!store.isCertificateEntry("cert") || !store.isCertificateEntry("CERT")) { fail("cert not identified as certificate entry"); } if (store.isKeyEntry("cert") || store.isKeyEntry("CERT")) { fail("cert identified as key entry"); } if (!store.entryInstanceOf("cert", KeyStore.TrustedCertificateEntry.class)) { fail("cert not identified as TrustedCertificateEntry"); } if (!store.entryInstanceOf("CERT", KeyStore.TrustedCertificateEntry.class)) { fail("CERT not identified as TrustedCertificateEntry"); } if (store.entryInstanceOf("cert", KeyStore.PrivateKeyEntry.class)) { fail("cert identified as key entry via PrivateKeyEntry"); } if (!"cert".equals(store.getCertificateAlias(ch[1]))) { fail("Did not return alias for certificate entry"); } // // test restoring of a certificate with private key originally as a ca certificate // store = KeyStore.getInstance("PKCS12", "BC"); store.load(null, null); store.setCertificateEntry("cert", ch[0]); if (!store.containsAlias("cert") || !store.containsAlias("CERT")) { fail("restore: couldn't find alias cert"); } if (!store.isCertificateEntry("cert") || !store.isCertificateEntry("CERT")) { fail("restore: cert not identified as certificate entry"); } if (store.isKeyEntry("cert") || store.isKeyEntry("CERT")) { fail("restore: cert identified as key entry"); } if (store.entryInstanceOf("cert", KeyStore.PrivateKeyEntry.class)) { fail("restore: cert identified as key entry via PrivateKeyEntry"); } if (store.entryInstanceOf("CERT", KeyStore.PrivateKeyEntry.class)) { fail("restore: cert identified as key entry via PrivateKeyEntry"); } if (!store.entryInstanceOf("cert", KeyStore.TrustedCertificateEntry.class)) { fail("restore: cert not identified as TrustedCertificateEntry"); } // // test of reading incorrect zero-length encoding // store = KeyStore.getInstance("PKCS12", "BC"); stream = new ByteArrayInputStream(pkcs12nopass); store.load(stream, "".toCharArray()); } private void testSupportedTypes(PrivateKey privKey, Certificate[] chain) throws Exception { basicStoreTest(privKey, chain, "PKCS12"); basicStoreTest(privKey, chain, "BCPKCS12"); basicStoreTest(privKey, chain, "PKCS12-DEF"); basicStoreTest(privKey, chain, "PKCS12-3DES-40RC2"); basicStoreTest(privKey, chain, "PKCS12-3DES-3DES"); basicStoreTest(privKey, chain, "PKCS12-DEF-3DES-40RC2"); basicStoreTest(privKey, chain, "PKCS12-DEF-3DES-3DES"); } private void basicStoreTest(PrivateKey privKey, Certificate[] chain, String type) throws Exception { KeyStore store = KeyStore.getInstance(type, "BC"); store.load(null, null); store.setKeyEntry("key", privKey, null, chain); ByteArrayOutputStream bOut = new ByteArrayOutputStream(); store.store(bOut, passwd); store.load(new ByteArrayInputStream(bOut.toByteArray()), passwd); Key k = store.getKey("key", null); if (!k.equals(privKey)) { fail("private key didn't match"); } Certificate[] c = store.getCertificateChain("key"); if (c.length != chain.length || !c[0].equals(chain[0])) { fail("certificates didn't match"); } if (type.contains("DEF")) { if (c[0] instanceof X509CertificateObject) { fail("wrong certificate type found"); } } // check attributes PKCS12BagAttributeCarrier b1 = (PKCS12BagAttributeCarrier)k; PKCS12BagAttributeCarrier b2 = (PKCS12BagAttributeCarrier)chain[0]; if (b1.getBagAttribute(PKCSObjectIdentifiers.pkcs_9_at_friendlyName) != null) { DERBMPString name = (DERBMPString)b1.getBagAttribute(PKCSObjectIdentifiers.pkcs_9_at_friendlyName); if (!name.equals(new DERBMPString("key"))) { fail("friendly name wrong"); } } else { fail("no friendly name found on key"); } if (b1.getBagAttribute(PKCSObjectIdentifiers.pkcs_9_at_localKeyId) != null) { ASN1OctetString id = (ASN1OctetString)b1.getBagAttribute(PKCSObjectIdentifiers.pkcs_9_at_localKeyId); if (!id.equals(b2.getBagAttribute(PKCSObjectIdentifiers.pkcs_9_at_localKeyId))) { fail("local key id mismatch"); } } else { fail("no local key id found"); } // // check algorithm types. // ASN1InputStream aIn = new ASN1InputStream(bOut.toByteArray()); Pfx pfx = Pfx.getInstance(aIn.readObject()); ContentInfo cInfo = pfx.getAuthSafe(); ASN1OctetString auth = (ASN1OctetString)cInfo.getContent(); aIn = new ASN1InputStream(auth.getOctets()); ASN1Sequence s1 = (ASN1Sequence)aIn.readObject(); ContentInfo c1 = ContentInfo.getInstance(s1.getObjectAt(0)); ContentInfo c2 = ContentInfo.getInstance(s1.getObjectAt(1)); aIn = new ASN1InputStream(((ASN1OctetString)c1.getContent()).getOctets()); SafeBag sb = SafeBag.getInstance((((ASN1Sequence)aIn.readObject()).getObjectAt(0))); EncryptedPrivateKeyInfo encInfo = EncryptedPrivateKeyInfo.getInstance(sb.getBagValue()); if (!encInfo.getEncryptionAlgorithm().getAlgorithm().equals(PKCSObjectIdentifiers.pbeWithSHAAnd3_KeyTripleDES_CBC)) { fail("key encryption algorithm wrong"); } // check the key encryption // check the certificate encryption EncryptedData cb = EncryptedData.getInstance(c2.getContent()); if (type.endsWith("3DES")) { if (!cb.getEncryptionAlgorithm().getAlgorithm().equals(PKCSObjectIdentifiers.pbeWithSHAAnd3_KeyTripleDES_CBC)) { fail("expected 3DES found: " + cb.getEncryptionAlgorithm().getAlgorithm()); } } else if (type.endsWith("40RC2")) { if (!cb.getEncryptionAlgorithm().getAlgorithm().equals(PKCSObjectIdentifiers.pbeWithSHAAnd40BitRC2_CBC)) { fail("expected 40 bit RC2 found: " + cb.getEncryptionAlgorithm().getAlgorithm()); } } else { if (!cb.getEncryptionAlgorithm().getAlgorithm().equals(PKCSObjectIdentifiers.pbeWithSHAAnd40BitRC2_CBC)) { fail("expected 40 bit RC2 found: " + cb.getEncryptionAlgorithm().getAlgorithm()); } } } private void testNoExtraLocalKeyID(byte[] store1data) throws Exception { KeyPairGenerator kpg = KeyPairGenerator.getInstance("RSA", "BC"); kpg.initialize(512); KeyPair newPair = kpg.genKeyPair(); KeyStore store1 = KeyStore.getInstance("PKCS12", "BC"); store1.load(new ByteArrayInputStream(store1data), passwd); KeyStore store2 = KeyStore.getInstance("PKCS12", "BC"); store2.load(null, null); PrivateKey k1 = (PrivateKey)store1.getKey("privatekey", null); Certificate[] chain1 = store1.getCertificateChain("privatekey"); Certificate[] chain2 = new Certificate[chain1.length + 1]; System.arraycopy(chain1, 0, chain2, 1, chain1.length); chain2[0] = createCert(newPair.getPublic(), k1, "subject@bouncycastle.org", "extra@bouncycaste.org"); if (((PKCS12BagAttributeCarrier)chain1[0]).getBagAttribute(PKCSObjectIdentifiers.pkcs_9_at_localKeyId) == null) { fail("localKeyID not found initially"); } store2.setKeyEntry("new", newPair.getPrivate(), null, chain2); ByteArrayOutputStream bOut = new ByteArrayOutputStream(); store2.store(bOut, passwd); store2.load(new ByteArrayInputStream(bOut.toByteArray()), passwd); chain2 = store2.getCertificateChain("new"); if (((PKCS12BagAttributeCarrier)chain2[1]).getBagAttribute(PKCSObjectIdentifiers.pkcs_9_at_localKeyId) != null) { fail("localKeyID found after save"); } } public String getName() { return "PKCS12Store"; } public void performTest() throws Exception { testPKCS12Store(); // converter tests KeyStore kS = KeyStore.getInstance("PKCS12", "BC"); byte[] data = PKCS12Util.convertToDefiniteLength(pkcs12); kS.load(new ByteArrayInputStream(data), passwd); // check MAC ASN1Encodable obj = new ASN1StreamParser(data).readObject(); if (!(obj instanceof DERSequenceParser)) { fail("Failed DER conversion test."); } data = PKCS12Util.convertToDefiniteLength(pkcs12, passwd, "BC"); kS.load(new ByteArrayInputStream(data), passwd); //check MAC obj = new ASN1StreamParser(data).readObject(); if (!(obj instanceof DERSequenceParser)) { fail("Failed deep DER conversion test - outer."); } Pfx pfx = Pfx.getInstance(obj); obj = new ASN1StreamParser(ASN1OctetString.getInstance(pfx.getAuthSafe().getContent()).getOctets()).readObject(); if (!(obj instanceof DERSequenceParser)) { fail("Failed deep DER conversion test - inner."); } } public static void main( String[] args) { Security.addProvider(new BouncyCastleProvider()); runTest(new PKCS12StoreTest()); } } bouncycastle-1.49.orig/test/src/org/bouncycastle/jce/provider/test/NamedCurveTest.java0000644000175000017500000002516611444257104030603 0ustar ebourgebourgpackage org.bouncycastle.jce.provider.test; import org.bouncycastle.asn1.nist.NISTNamedCurves; import org.bouncycastle.asn1.sec.SECNamedCurves; import org.bouncycastle.asn1.teletrust.TeleTrusTNamedCurves; import org.bouncycastle.asn1.x9.X962NamedCurves; import org.bouncycastle.asn1.cryptopro.ECGOST3410NamedCurves; import org.bouncycastle.jce.provider.BouncyCastleProvider; import org.bouncycastle.jce.spec.ECNamedCurveSpec; import org.bouncycastle.util.test.SimpleTest; import javax.crypto.KeyAgreement; import java.math.BigInteger; import java.security.KeyFactory; import java.security.KeyPair; import java.security.KeyPairGenerator; import java.security.PrivateKey; import java.security.PublicKey; import java.security.SecureRandom; import java.security.Security; import java.security.Signature; import java.security.interfaces.ECPrivateKey; import java.security.interfaces.ECPublicKey; import java.security.spec.ECGenParameterSpec; import java.security.spec.PKCS8EncodedKeySpec; import java.security.spec.X509EncodedKeySpec; import java.util.Enumeration; import java.util.Hashtable; import java.util.Set; import java.util.HashSet; public class NamedCurveTest extends SimpleTest { private static Hashtable CURVE_NAMES = new Hashtable(); private static Hashtable CURVE_ALIASES = new Hashtable(); static { CURVE_NAMES.put("prime192v1", "prime192v1"); // X9.62 CURVE_NAMES.put("sect571r1", "sect571r1"); // sec CURVE_NAMES.put("secp224r1", "secp224r1"); CURVE_NAMES.put("B-409", SECNamedCurves.getName(NISTNamedCurves.getOID("B-409"))); // nist CURVE_NAMES.put("P-521", SECNamedCurves.getName(NISTNamedCurves.getOID("P-521"))); CURVE_NAMES.put("brainpoolp160r1", "brainpoolp160r1"); // TeleTrusT CURVE_ALIASES.put("secp192r1", "prime192v1"); CURVE_ALIASES.put("secp256r1", "prime256v1"); } public void testCurve( String name) throws Exception { ECGenParameterSpec ecSpec = new ECGenParameterSpec(name); KeyPairGenerator g = KeyPairGenerator.getInstance("ECDH", "BC"); g.initialize(ecSpec, new SecureRandom()); // // a side // KeyPair aKeyPair = g.generateKeyPair(); KeyAgreement aKeyAgree = KeyAgreement.getInstance("ECDHC", "BC"); aKeyAgree.init(aKeyPair.getPrivate()); // // b side // KeyPair bKeyPair = g.generateKeyPair(); KeyAgreement bKeyAgree = KeyAgreement.getInstance("ECDHC", "BC"); bKeyAgree.init(bKeyPair.getPrivate()); // // agreement // aKeyAgree.doPhase(bKeyPair.getPublic(), true); bKeyAgree.doPhase(aKeyPair.getPublic(), true); BigInteger k1 = new BigInteger(aKeyAgree.generateSecret()); BigInteger k2 = new BigInteger(bKeyAgree.generateSecret()); if (!k1.equals(k2)) { fail("2-way test failed"); } // // public key encoding test // byte[] pubEnc = aKeyPair.getPublic().getEncoded(); KeyFactory keyFac = KeyFactory.getInstance("ECDH", "BC"); X509EncodedKeySpec pubX509 = new X509EncodedKeySpec(pubEnc); ECPublicKey pubKey = (ECPublicKey)keyFac.generatePublic(pubX509); if (!pubKey.getW().equals(((ECPublicKey)aKeyPair.getPublic()).getW())) { fail("public key encoding (Q test) failed"); } if (!(pubKey.getParams() instanceof ECNamedCurveSpec)) { fail("public key encoding not named curve"); } // // private key encoding test // byte[] privEnc = aKeyPair.getPrivate().getEncoded(); PKCS8EncodedKeySpec privPKCS8 = new PKCS8EncodedKeySpec(privEnc); ECPrivateKey privKey = (ECPrivateKey)keyFac.generatePrivate(privPKCS8); if (!privKey.getS().equals(((ECPrivateKey)aKeyPair.getPrivate()).getS())) { fail("private key encoding (S test) failed"); } if (!(privKey.getParams() instanceof ECNamedCurveSpec)) { fail("private key encoding not named curve"); } ECNamedCurveSpec privSpec = (ECNamedCurveSpec)privKey.getParams(); if (!(privSpec.getName().equals(name) || privSpec.getName().equals(CURVE_NAMES.get(name)))) { fail("private key encoding wrong named curve. Expected: " + CURVE_NAMES.get(name) + " got " + privSpec.getName()); } } public void testECDSA( String name) throws Exception { ECGenParameterSpec ecSpec = new ECGenParameterSpec(name); KeyPairGenerator g = KeyPairGenerator.getInstance("ECDSA", "BC"); g.initialize(ecSpec, new SecureRandom()); Signature sgr = Signature.getInstance("ECDSA", "BC"); KeyPair pair = g.generateKeyPair(); PrivateKey sKey = pair.getPrivate(); PublicKey vKey = pair.getPublic(); sgr.initSign(sKey); byte[] message = new byte[] { (byte)'a', (byte)'b', (byte)'c' }; sgr.update(message); byte[] sigBytes = sgr.sign(); sgr.initVerify(vKey); sgr.update(message); if (!sgr.verify(sigBytes)) { fail(name + " verification failed"); } // // public key encoding test // byte[] pubEnc = vKey.getEncoded(); KeyFactory keyFac = KeyFactory.getInstance("ECDH", "BC"); X509EncodedKeySpec pubX509 = new X509EncodedKeySpec(pubEnc); ECPublicKey pubKey = (ECPublicKey)keyFac.generatePublic(pubX509); if (!pubKey.getW().equals(((ECPublicKey)vKey).getW())) { fail("public key encoding (Q test) failed"); } if (!(pubKey.getParams() instanceof ECNamedCurveSpec)) { fail("public key encoding not named curve"); } // // private key encoding test // byte[] privEnc = sKey.getEncoded(); PKCS8EncodedKeySpec privPKCS8 = new PKCS8EncodedKeySpec(privEnc); ECPrivateKey privKey = (ECPrivateKey)keyFac.generatePrivate(privPKCS8); if (!privKey.getS().equals(((ECPrivateKey)sKey).getS())) { fail("private key encoding (S test) failed"); } if (!(privKey.getParams() instanceof ECNamedCurveSpec)) { fail("private key encoding not named curve"); } ECNamedCurveSpec privSpec = (ECNamedCurveSpec)privKey.getParams(); if (!privSpec.getName().equalsIgnoreCase(name) && !privSpec.getName().equalsIgnoreCase((String)CURVE_ALIASES.get(name))) { fail("private key encoding wrong named curve. Expected: " + name + " got " + privSpec.getName()); } } public void testECGOST( String name) throws Exception { ECGenParameterSpec ecSpec = new ECGenParameterSpec(name); KeyPairGenerator g = KeyPairGenerator.getInstance("ECGOST3410", "BC"); g.initialize(ecSpec, new SecureRandom()); Signature sgr = Signature.getInstance("ECGOST3410", "BC"); KeyPair pair = g.generateKeyPair(); PrivateKey sKey = pair.getPrivate(); PublicKey vKey = pair.getPublic(); sgr.initSign(sKey); byte[] message = new byte[] { (byte)'a', (byte)'b', (byte)'c' }; sgr.update(message); byte[] sigBytes = sgr.sign(); sgr.initVerify(vKey); sgr.update(message); if (!sgr.verify(sigBytes)) { fail(name + " verification failed"); } // // public key encoding test // byte[] pubEnc = vKey.getEncoded(); KeyFactory keyFac = KeyFactory.getInstance("ECGOST3410", "BC"); X509EncodedKeySpec pubX509 = new X509EncodedKeySpec(pubEnc); ECPublicKey pubKey = (ECPublicKey)keyFac.generatePublic(pubX509); if (!pubKey.getW().equals(((ECPublicKey)vKey).getW())) { fail("public key encoding (Q test) failed"); } if (!(pubKey.getParams() instanceof ECNamedCurveSpec)) { fail("public key encoding not named curve"); } // // private key encoding test // byte[] privEnc = sKey.getEncoded(); PKCS8EncodedKeySpec privPKCS8 = new PKCS8EncodedKeySpec(privEnc); ECPrivateKey privKey = (ECPrivateKey)keyFac.generatePrivate(privPKCS8); if (!privKey.getS().equals(((ECPrivateKey)sKey).getS())) { fail("GOST private key encoding (S test) failed"); } if (!(privKey.getParams() instanceof ECNamedCurveSpec)) { fail("GOST private key encoding not named curve"); } ECNamedCurveSpec privSpec = (ECNamedCurveSpec)privKey.getParams(); if (!privSpec.getName().equalsIgnoreCase(name) && !privSpec.getName().equalsIgnoreCase((String)CURVE_ALIASES.get(name))) { fail("GOST private key encoding wrong named curve. Expected: " + name + " got " + privSpec.getName()); } } public String getName() { return "NamedCurve"; } public void performTest() throws Exception { testCurve("prime192v1"); // X9.62 testCurve("sect571r1"); // sec testCurve("secp224r1"); testCurve("B-409"); // nist testCurve("P-521"); testCurve("brainpoolp160r1"); // TeleTrusT for (Enumeration en = X962NamedCurves.getNames(); en.hasMoreElements();) { testECDSA((String)en.nextElement()); } // these curves can't be used under JDK 1.5 Set problemCurves = new HashSet(); problemCurves.add("secp256k1"); problemCurves.add("secp160k1"); problemCurves.add("secp224k1"); problemCurves.add("secp192k1"); for (Enumeration en = SECNamedCurves.getNames(); en.hasMoreElements();) { String curveName = (String)en.nextElement(); if (!problemCurves.contains(curveName)) { testECDSA(curveName); } } for (Enumeration en = TeleTrusTNamedCurves.getNames(); en.hasMoreElements();) { testECDSA((String)en.nextElement()); } for (Enumeration en = ECGOST3410NamedCurves.getNames(); en.hasMoreElements();) { testECGOST((String)en.nextElement()); } } public static void main( String[] args) { Security.addProvider(new BouncyCastleProvider()); runTest(new NamedCurveTest()); } } bouncycastle-1.49.orig/test/src/org/bouncycastle/jce/provider/test/AESSICTest.java0000644000175000017500000001316111570167620027514 0ustar ebourgebourgpackage org.bouncycastle.jce.provider.test; import java.security.Key; import java.security.Security; import javax.crypto.Cipher; import javax.crypto.spec.IvParameterSpec; import javax.crypto.spec.SecretKeySpec; import org.bouncycastle.jce.provider.BouncyCastleProvider; import org.bouncycastle.jce.spec.RepeatedSecretKeySpec; import org.bouncycastle.util.encoders.Hex; import org.bouncycastle.util.test.SimpleTest; /** * test vectors based on NIST Special Publication 800-38A, * "Recommendation for Block Cipher Modes of Operation" */ public class AESSICTest extends SimpleTest { private byte[][] keys = { Hex.decode("2b7e151628aed2a6abf7158809cf4f3c"), Hex.decode("8e73b0f7da0e6452c810f32b809079e562f8ead2522c6b7b"), Hex.decode("603deb1015ca71be2b73aef0857d77811f352c073b6108d72d9810a30914dff4") }; private byte[][] plain = { Hex.decode("6bc1bee22e409f96e93d7e117393172a"), Hex.decode("ae2d8a571e03ac9c9eb76fac45af8e51"), Hex.decode("30c81c46a35ce411e5fbc1191a0a52ef"), Hex.decode("f69f2445df4f9b17ad2b417be66c3710") }; private byte[][][] cipher = { { Hex.decode("874d6191b620e3261bef6864990db6ce"), Hex.decode("9806f66b7970fdff8617187bb9fffdff"), Hex.decode("5ae4df3edbd5d35e5b4f09020db03eab"), Hex.decode("1e031dda2fbe03d1792170a0f3009cee") }, { Hex.decode("1abc932417521ca24f2b0459fe7e6e0b"), Hex.decode("090339ec0aa6faefd5ccc2c6f4ce8e94"), Hex.decode("1e36b26bd1ebc670d1bd1d665620abf7"), Hex.decode("4f78a7f6d29809585a97daec58c6b050") }, { Hex.decode("601ec313775789a5b7a7f504bbf3d228"), Hex.decode("f443e3ca4d62b59aca84e990cacaf5c5"), Hex.decode("2b0930daa23de94ce87017ba2d84988d"), Hex.decode("dfc9c58db67aada613c2dd08457941a6") } }; public String getName() { return "AESSIC"; } public void performTest() throws Exception { Cipher c = Cipher.getInstance("AES/SIC/NoPadding", "BC"); // // NIST vectors // for (int i = 0; i != keys.length; i++) { Key sk = new SecretKeySpec(keys[i], "AES"); c.init( Cipher.ENCRYPT_MODE, sk, new IvParameterSpec(Hex.decode("F0F1F2F3F4F5F6F7F8F9FAFBFCFDFEFF"))); for (int j = 0; j != plain.length; j++) { byte[] crypt = c.update(plain[j]); if (!areEqual(crypt, cipher[i][j])) { fail("AESSIC encrypt failed: key " + i + " block " + j); } } c.init( Cipher.DECRYPT_MODE, sk, new IvParameterSpec(Hex.decode("F0F1F2F3F4F5F6F7F8F9FAFBFCFDFEFF"))); for (int j = 0; j != plain.length; j++) { byte[] crypt = c.update(cipher[i][j]); if (!areEqual(crypt, plain[j])) { fail("AESSIC decrypt failed: key " + i + " block " + j); } } } // // check CTR also recognised. // c = Cipher.getInstance("AES/CTR/NoPadding", "BC"); Key sk = new SecretKeySpec(Hex.decode("2B7E151628AED2A6ABF7158809CF4F3C"), "AES"); c.init( Cipher.ENCRYPT_MODE, sk, new IvParameterSpec(Hex.decode("F0F1F2F3F4F5F6F7F8F9FAFBFCFD0001"))); byte[] crypt = c.doFinal(Hex.decode("00000000000000000000000000000000")); if (!areEqual(crypt, Hex.decode("D23513162B02D0F72A43A2FE4A5F97AB"))) { fail("AESSIC failed test 2"); } // // check partial block processing // c = Cipher.getInstance("AES/CTR/NoPadding", "BC"); sk = new SecretKeySpec(Hex.decode("2B7E151628AED2A6ABF7158809CF4F3C"), "AES"); c.init( Cipher.ENCRYPT_MODE, sk, new IvParameterSpec(Hex.decode("F0F1F2F3F4F5F6F7F8F9FAFBFCFD0001"))); crypt = c.doFinal(Hex.decode("12345678")); c.init( Cipher.DECRYPT_MODE, sk, new IvParameterSpec(Hex.decode("F0F1F2F3F4F5F6F7F8F9FAFBFCFD0001"))); crypt = c.doFinal(crypt); if (!areEqual(crypt, Hex.decode("12345678"))) { fail("AESSIC failed partial test"); } // null key test sk = new RepeatedSecretKeySpec("AES"); c.init( Cipher.ENCRYPT_MODE, sk, new IvParameterSpec(Hex.decode("F0F1F2F3F4F5F6F7F8F9FAFBFCFDFEFF"))); for (int j = 0; j != plain.length; j++) { crypt = c.update(plain[j]); if (!areEqual(crypt, cipher[0][j])) { fail("AESSIC encrypt failed: key " + 0 + " block " + j); } } } public static void main( String[] args) { Security.addProvider(new BouncyCastleProvider()); runTest(new AESSICTest()); } } bouncycastle-1.49.orig/test/src/org/bouncycastle/jce/provider/test/IESTest.java0000644000175000017500000001532110336346330027161 0ustar ebourgebourgpackage org.bouncycastle.jce.provider.test; import java.math.BigInteger; import java.security.AlgorithmParameters; import java.security.KeyPair; import java.security.KeyPairGenerator; import java.security.PrivateKey; import java.security.PublicKey; import java.security.SecureRandom; import java.security.Security; import javax.crypto.Cipher; import javax.crypto.spec.DHParameterSpec; import org.bouncycastle.jce.provider.BouncyCastleProvider; import org.bouncycastle.jce.spec.ECParameterSpec; import org.bouncycastle.jce.spec.IEKeySpec; import org.bouncycastle.jce.spec.IESParameterSpec; import org.bouncycastle.math.ec.ECCurve; import org.bouncycastle.util.encoders.Hex; import org.bouncycastle.util.test.SimpleTest; /** * test for ECIES - Elliptic Curve Integrated Encryption Scheme */ public class IESTest extends SimpleTest { private BigInteger g512 = new BigInteger("153d5d6172adb43045b68ae8e1de1070b6137005686d29d3d73a7749199681ee5b212c9b96bfdcfa5b20cd5e3fd2044895d609cf9b410b7a0f12ca1cb9a428cc", 16); private BigInteger p512 = new BigInteger("9494fec095f3b85ee286542b3836fc81a5dd0a0349b4c239dd38744d488cf8e31db8bcb7d33b41abb9e5a33cca9144b1cef332c94bf0573bf047a3aca98cdf3b", 16); IESTest() { } public String getName() { return "IES"; } public void performTest() throws Exception { KeyPairGenerator g = KeyPairGenerator.getInstance("ECIES", "BC"); ECCurve curve = new ECCurve.Fp( new BigInteger("883423532389192164791648750360308885314476597252960362792450860609699839"), // q new BigInteger("7fffffffffffffffffffffff7fffffffffff8000000000007ffffffffffc", 16), // a new BigInteger("6b016c3bdcf18941d0d654921475ca71a9db2fb27d1d37796185c2942c0a", 16)); // b ECParameterSpec ecSpec = new ECParameterSpec( curve, curve.decodePoint(Hex.decode("020ffa963cdca8816ccc33b8642bedf905c3d358573d3f27fbbd3b3cb9aaaf")), // G new BigInteger("883423532389192164791648750360308884807550341691627752275345424702807307")); // n g.initialize(ecSpec, new SecureRandom()); Cipher c1 = Cipher.getInstance("ECIES", "BC"); Cipher c2 = Cipher.getInstance("ECIES", "BC"); doTest(g, c1, c2); g = KeyPairGenerator.getInstance("ECIES", "BC"); g.initialize(192, new SecureRandom()); doTest(g, c1, c2); g = KeyPairGenerator.getInstance("ECIES", "BC"); g.initialize(239, new SecureRandom()); doTest(g, c1, c2); g = KeyPairGenerator.getInstance("ECIES", "BC"); g.initialize(256, new SecureRandom()); doTest(g, c1, c2); doDefTest(g, c1, c2); DHParameterSpec dhParams = new DHParameterSpec(p512, g512); c1 = Cipher.getInstance("IES", "BC"); c2 = Cipher.getInstance("IES", "BC"); g = KeyPairGenerator.getInstance("DH", "BC"); g.initialize(dhParams); doTest(g, c1, c2); doDefTest(g, c1, c2); } public void doTest( KeyPairGenerator g, Cipher c1, Cipher c2) throws Exception { // // a side // KeyPair aKeyPair = g.generateKeyPair(); PublicKey aPub = aKeyPair.getPublic(); PrivateKey aPriv = aKeyPair.getPrivate(); // // b side // KeyPair bKeyPair = g.generateKeyPair(); PublicKey bPub = bKeyPair.getPublic(); PrivateKey bPriv = bKeyPair.getPrivate(); // // stream test // IEKeySpec c1Key = new IEKeySpec(aPriv, bPub); IEKeySpec c2Key = new IEKeySpec(bPriv, aPub); byte[] d = new byte[] { 1, 2, 3, 4, 5, 6, 7, 8 }; byte[] e = new byte[] { 8, 7, 6, 5, 4, 3, 2, 1 }; IESParameterSpec param = new IESParameterSpec(d, e, 128); c1.init(Cipher.ENCRYPT_MODE, c1Key, param); c2.init(Cipher.DECRYPT_MODE, c2Key, param); byte[] message = Hex.decode("1234567890abcdef"); byte[] out1 = c1.doFinal(message, 0, message.length); byte[] out2 = c2.doFinal(out1, 0, out1.length); if (!areEqual(out2, message)) { fail("stream cipher test failed"); } } public void doDefTest( KeyPairGenerator g, Cipher c1, Cipher c2) throws Exception { // // a side // KeyPair aKeyPair = g.generateKeyPair(); PublicKey aPub = aKeyPair.getPublic(); PrivateKey aPriv = aKeyPair.getPrivate(); // // b side // KeyPair bKeyPair = g.generateKeyPair(); PublicKey bPub = bKeyPair.getPublic(); PrivateKey bPriv = bKeyPair.getPrivate(); // // stream test // IEKeySpec c1Key = new IEKeySpec(aPriv, bPub); IEKeySpec c2Key = new IEKeySpec(bPriv, aPub); c1.init(Cipher.ENCRYPT_MODE, c1Key); AlgorithmParameters param = c1.getParameters(); c2.init(Cipher.DECRYPT_MODE, c2Key, param); byte[] message = Hex.decode("1234567890abcdef"); byte[] out1 = c1.doFinal(message, 0, message.length); byte[] out2 = c2.doFinal(out1, 0, out1.length); if (!areEqual(out2, message)) { fail("stream cipher test failed"); } // // int doFinal // int len1 = c1.doFinal(message, 0, message.length, out1, 0); if (len1 != out1.length) { fail("encryption length wrong"); } int len2 = c2.doFinal(out1, 0, out1.length, out2, 0); if (len2 != out2.length) { fail("decryption length wrong"); } if (!areEqual(out2, message)) { fail("stream cipher test failed"); } // // int doFinal with update // len1 = c1.update(message, 0, 2, out1, 0); len1 += c1.doFinal(message, 2, message.length - 2, out1, len1); if (len1 != out1.length) { fail("update encryption length wrong"); } len2 = c2.update(out1, 0, 2, out2, 0); len2 += c2.doFinal(out1, 2, out1.length - 2, out2, len2); if (len2 != out2.length) { fail("update decryption length wrong"); } if (!areEqual(out2, message)) { fail("update stream cipher test failed"); } } public static void main( String[] args) { Security.addProvider(new BouncyCastleProvider()); runTest(new IESTest()); } } bouncycastle-1.49.orig/test/src/org/bouncycastle/jce/provider/test/FIPSDESTest.java0000644000175000017500000001455310330633061027636 0ustar ebourgebourgpackage org.bouncycastle.jce.provider.test; import java.io.ByteArrayInputStream; import java.io.ByteArrayOutputStream; import java.io.DataInputStream; import java.io.IOException; import java.security.InvalidAlgorithmParameterException; import java.security.Key; import java.security.KeyException; import java.security.Security; import javax.crypto.Cipher; import javax.crypto.CipherInputStream; import javax.crypto.CipherOutputStream; import javax.crypto.spec.IvParameterSpec; import javax.crypto.spec.SecretKeySpec; import org.bouncycastle.jce.provider.BouncyCastleProvider; import org.bouncycastle.util.encoders.Hex; import org.bouncycastle.util.test.SimpleTestResult; import org.bouncycastle.util.test.Test; import org.bouncycastle.util.test.TestResult; /** * basic FIPS test class for a block cipher, just to make sure ECB/CBC/OFB/CFB are behaving * correctly. Tests from FIPS 81. */ public class FIPSDESTest implements Test { static String[] fips1Tests = { "DES/ECB/NoPadding", "3fa40e8a984d48156a271787ab8883f9893d51ec4b563b53", "DES/CBC/NoPadding", "e5c7cdde872bf27c43e934008c389c0f683788499a7c05f6", "DES/CFB/NoPadding", "f3096249c7f46e51a69e839b1a92f78403467133898ea622" }; static String[] fips2Tests = { "DES/CFB8/NoPadding", "f31fda07011462ee187f", "DES/OFB8/NoPadding", "f34a2850c9c64985d684" }; static byte[] input1 = Hex.decode("4e6f77206973207468652074696d6520666f7220616c6c20"); static byte[] input2 = Hex.decode("4e6f7720697320746865"); public String getName() { return "FIPSDESTest"; } private boolean equalArray( byte[] a, byte[] b) { if (a.length != b.length) { return false; } for (int i = 0; i != a.length; i++) { if (a[i] != b[i]) { return false; } } return true; } public TestResult test( String algorithm, byte[] input, byte[] output) { Key key; Cipher in, out; CipherInputStream cIn; CipherOutputStream cOut; ByteArrayInputStream bIn; ByteArrayOutputStream bOut; IvParameterSpec spec = new IvParameterSpec(Hex.decode("1234567890abcdef")); try { String baseAlgorithm; key = new SecretKeySpec(Hex.decode("0123456789abcdef"), "DES"); in = Cipher.getInstance(algorithm, "BC"); out = Cipher.getInstance(algorithm, "BC"); if (algorithm.startsWith("DES/ECB")) { out.init(Cipher.ENCRYPT_MODE, key); } else { out.init(Cipher.ENCRYPT_MODE, key, spec); } } catch (Exception e) { return new SimpleTestResult(false, getName() + ": " + algorithm + " failed initialisation - " + e.toString(), e); } try { if (algorithm.startsWith("DES/ECB")) { in.init(Cipher.DECRYPT_MODE, key); } else { in.init(Cipher.DECRYPT_MODE, key, spec); } } catch (Exception e) { return new SimpleTestResult(false, getName() + ": " + algorithm + " failed initialisation - " + e.toString(), e); } // // encryption pass // bOut = new ByteArrayOutputStream(); cOut = new CipherOutputStream(bOut, out); try { for (int i = 0; i != input.length / 2; i++) { cOut.write(input[i]); } cOut.write(input, input.length / 2, input.length - input.length / 2); cOut.close(); } catch (IOException e) { return new SimpleTestResult(false, getName() + ": " + algorithm + " failed encryption - " + e.toString()); } byte[] bytes; bytes = bOut.toByteArray(); if (!equalArray(bytes, output)) { return new SimpleTestResult(false, getName() + ": " + algorithm + " failed encryption - expected " + new String(Hex.encode(output)) + " got " + new String(Hex.encode(bytes))); } // // decryption pass // bIn = new ByteArrayInputStream(bytes); cIn = new CipherInputStream(bIn, in); try { DataInputStream dIn = new DataInputStream(cIn); bytes = new byte[input.length]; for (int i = 0; i != input.length / 2; i++) { bytes[i] = (byte)dIn.read(); } dIn.readFully(bytes, input.length / 2, bytes.length - input.length / 2); } catch (Exception e) { return new SimpleTestResult(false, getName() + ": " + algorithm + " failed encryption - " + e.toString()); } if (!equalArray(bytes, input)) { return new SimpleTestResult(false, getName() + ": " + algorithm + " failed decryption - expected " + new String(Hex.encode(input)) + " got " + new String(Hex.encode(bytes))); } return new SimpleTestResult(true, getName() + ": " + algorithm + " Okay"); } public TestResult perform() { for (int i = 0; i != fips1Tests.length; i += 2) { TestResult result; result = test(fips1Tests[i], input1, Hex.decode(fips1Tests[i + 1])); if (!result.isSuccessful()) { return result; } } for (int i = 0; i != fips2Tests.length; i += 2) { TestResult result; result = test(fips2Tests[i], input2, Hex.decode(fips2Tests[i + 1])); if (!result.isSuccessful()) { return result; } } return new SimpleTestResult(true, getName() + ": Okay"); } public static void main( String[] args) throws KeyException, InvalidAlgorithmParameterException { Security.addProvider(new BouncyCastleProvider()); Test test = new FIPSDESTest(); TestResult result = test.perform(); System.out.println(result.toString()); } } bouncycastle-1.49.orig/test/src/org/bouncycastle/jce/provider/test/CamelliaTest.java0000644000175000017500000001232210565525753030262 0ustar ebourgebourgpackage org.bouncycastle.jce.provider.test; import org.bouncycastle.asn1.ntt.NTTObjectIdentifiers; import org.bouncycastle.jce.provider.BouncyCastleProvider; import org.bouncycastle.util.encoders.Hex; import javax.crypto.Cipher; import javax.crypto.CipherInputStream; import javax.crypto.CipherOutputStream; import javax.crypto.spec.SecretKeySpec; import java.io.ByteArrayInputStream; import java.io.ByteArrayOutputStream; import java.io.DataInputStream; import java.io.IOException; import java.security.Key; import java.security.Security; /** * basic test class for Camellia */ public class CamelliaTest extends BaseBlockCipherTest { static String[] cipherTests = { "128", "0123456789abcdeffedcba9876543210", "0123456789abcdeffedcba9876543210", "67673138549669730857065648eabe43", "192", "0123456789abcdeffedcba98765432100011223344556677", "0123456789abcdeffedcba9876543210", "b4993401b3e996f84ee5cee7d79b09b9", "256", "0123456789abcdeffedcba987654321000112233445566778899aabbccddeeff", "0123456789abcdeffedcba9876543210", "9acc237dff16d76c20ef7c919e3a7509", }; public CamelliaTest() { super("Camellia"); } public void test( int strength, byte[] keyBytes, byte[] input, byte[] output) throws Exception { Key key; Cipher in, out; CipherInputStream cIn; CipherOutputStream cOut; ByteArrayInputStream bIn; ByteArrayOutputStream bOut; key = new SecretKeySpec(keyBytes, "Camellia"); in = Cipher.getInstance("Camellia/ECB/NoPadding", "BC"); out = Cipher.getInstance("Camellia/ECB/NoPadding", "BC"); try { out.init(Cipher.ENCRYPT_MODE, key); } catch (Exception e) { fail("Camellia failed initialisation - " + e.toString(), e); } try { in.init(Cipher.DECRYPT_MODE, key); } catch (Exception e) { fail("Camellia failed initialisation - " + e.toString(), e); } // // encryption pass // bOut = new ByteArrayOutputStream(); cOut = new CipherOutputStream(bOut, out); try { for (int i = 0; i != input.length / 2; i++) { cOut.write(input[i]); } cOut.write(input, input.length / 2, input.length - input.length / 2); cOut.close(); } catch (IOException e) { fail("Camellia failed encryption - " + e.toString(), e); } byte[] bytes; bytes = bOut.toByteArray(); if (!areEqual(bytes, output)) { fail("Camellia failed encryption - expected " + new String(Hex.encode(output)) + " got " + new String(Hex.encode(bytes))); } // // decryption pass // bIn = new ByteArrayInputStream(bytes); cIn = new CipherInputStream(bIn, in); try { DataInputStream dIn = new DataInputStream(cIn); bytes = new byte[input.length]; for (int i = 0; i != input.length / 2; i++) { bytes[i] = (byte)dIn.read(); } dIn.readFully(bytes, input.length / 2, bytes.length - input.length / 2); } catch (Exception e) { fail("Camellia failed encryption - " + e.toString(), e); } if (!areEqual(bytes, input)) { fail("Camellia failed decryption - expected " + new String(Hex.encode(input)) + " got " + new String(Hex.encode(bytes))); } } public void performTest() throws Exception { for (int i = 0; i != cipherTests.length; i += 4) { test(Integer.parseInt(cipherTests[i]), Hex.decode(cipherTests[i + 1]), Hex.decode(cipherTests[i + 2]), Hex.decode(cipherTests[i + 3])); } byte[] kek1 = Hex.decode("000102030405060708090a0b0c0d0e0f"); byte[] in1 = Hex.decode("00112233445566778899aabbccddeeff"); byte[] out1 = Hex.decode("635d6ac46eedebd3a7f4a06421a4cbd1746b24795ba2f708"); wrapTest(1, "CamelliaWrap", kek1, in1, out1); String[] oids = { NTTObjectIdentifiers.id_camellia128_cbc.getId(), NTTObjectIdentifiers.id_camellia192_cbc.getId(), NTTObjectIdentifiers.id_camellia256_cbc.getId() }; String[] names = { "Camellia/CBC/PKCS7Padding", "Camellia/CBC/PKCS7Padding", "Camellia/CBC/PKCS7Padding" }; oidTest(oids, names, 1); String[] wrapOids = { NTTObjectIdentifiers.id_camellia128_wrap.getId(), NTTObjectIdentifiers.id_camellia192_wrap.getId(), NTTObjectIdentifiers.id_camellia256_wrap.getId() }; wrapOidTest(wrapOids, "CamelliaWrap"); } public static void main( String[] args) { Security.addProvider(new BouncyCastleProvider()); runTest(new CamelliaTest()); } } bouncycastle-1.49.orig/test/src/org/bouncycastle/jce/provider/test/MultiCertStoreTest.java0000644000175000017500000000635610623745117031503 0ustar ebourgebourgpackage org.bouncycastle.jce.provider.test; import org.bouncycastle.jce.MultiCertStoreParameters; import org.bouncycastle.jce.provider.BouncyCastleProvider; import org.bouncycastle.util.test.SimpleTest; import java.io.ByteArrayInputStream; import java.security.Security; import java.security.cert.CertStore; import java.security.cert.CertificateFactory; import java.security.cert.CollectionCertStoreParameters; import java.security.cert.X509CRL; import java.security.cert.X509CertSelector; import java.security.cert.X509Certificate; import java.util.ArrayList; import java.util.Collection; import java.util.List; public class MultiCertStoreTest extends SimpleTest { public void performTest() throws Exception { basicTest(); } private void basicTest() throws Exception { CertificateFactory cf = CertificateFactory.getInstance("X.509", "BC"); X509Certificate rootCert = (X509Certificate)cf .generateCertificate(new ByteArrayInputStream( CertPathTest.rootCertBin)); X509Certificate interCert = (X509Certificate)cf .generateCertificate(new ByteArrayInputStream( CertPathTest.interCertBin)); X509Certificate finalCert = (X509Certificate)cf .generateCertificate(new ByteArrayInputStream( CertPathTest.finalCertBin)); X509CRL rootCrl = (X509CRL)cf.generateCRL(new ByteArrayInputStream( CertPathTest.rootCrlBin)); X509CRL interCrl = (X509CRL)cf .generateCRL(new ByteArrayInputStream( CertPathTest.interCrlBin)); // Testing CollectionCertStore generation from List List list = new ArrayList(); list.add(rootCert); list.add(interCert); list.add(finalCert); list.add(rootCrl); list.add(interCrl); CollectionCertStoreParameters ccsp = new CollectionCertStoreParameters(list); CertStore store1 = CertStore.getInstance("Collection", ccsp, "BC"); CertStore store2 = CertStore.getInstance("Collection", ccsp, "BC"); List storeList = new ArrayList(); storeList.add(store1); storeList.add(store2); CertStore store = CertStore.getInstance("Multi", new MultiCertStoreParameters(storeList)); // Searching for rootCert by subjectDN X509CertSelector targetConstraints = new X509CertSelector(); targetConstraints.setSubject(rootCert.getSubjectX500Principal().getName()); Collection certs = store.getCertificates(targetConstraints); if (certs.size() != 2 || !certs.contains(rootCert)) { fail("2 rootCerts not found by subjectDN"); } store = CertStore.getInstance("Multi", new MultiCertStoreParameters(storeList, false)); certs = store.getCertificates(targetConstraints); if (certs.size() != 1 || !certs.contains(rootCert)) { fail("1 rootCert not found by subjectDN"); } } public String getName() { return "MultiCertStore"; } public static void main(String[] args) { Security.addProvider(new BouncyCastleProvider()); runTest(new MultiCertStoreTest()); } } bouncycastle-1.49.orig/test/src/org/bouncycastle/jce/provider/test/rsa3/0000755000175000017500000000000012152033550025677 5ustar ebourgebourgbouncycastle-1.49.orig/test/src/org/bouncycastle/jce/provider/test/rsa3/RSA3CertTest.java0000644000175000017500000000546711730513343030750 0ustar ebourgebourgpackage org.bouncycastle.jce.provider.test.rsa3; import java.security.Security; import java.security.Signature; import java.security.cert.CertificateFactory; import java.security.cert.X509Certificate; import junit.framework.Test; import junit.framework.TestCase; import junit.framework.TestSuite; /** * Marius Schilder's Bleichenbacher's Forgery Attack Tests */ public class RSA3CertTest extends TestCase { public void setUp() { if (Security.getProvider("BC") == null) { Security.addProvider(new org.bouncycastle.jce.provider.BouncyCastleProvider()); } } public void testA() throws Exception { doTest("self-testcase-A.pem"); } public void testB() throws Exception { doTest("self-testcase-B.pem"); } public void testC() throws Exception { doTest("self-testcase-C.pem"); } public void testD() throws Exception { doTest("self-testcase-D.pem"); } public void testE() throws Exception { doTest("self-testcase-E.pem"); } public void testF() throws Exception { doTest("self-testcase-F.pem"); } public void testG() throws Exception { doTest("self-testcase-G.pem"); } public void testH() throws Exception { doTest("self-testcase-H.pem"); } public void testI() throws Exception { doTest("self-testcase-I.pem"); } public void testJ() throws Exception { doTest("self-testcase-J.pem"); } public void testL() throws Exception { doTest("self-testcase-L.pem"); } private void doTest( String certName) throws Exception { X509Certificate cert = loadCert(certName); byte[] tbs = cert.getTBSCertificate(); Signature sig = Signature.getInstance(cert.getSigAlgName(), "BC"); sig.initVerify(cert.getPublicKey()); sig.update(tbs); assertFalse(sig.verify(cert.getSignature())); } private X509Certificate loadCert( String certName) throws Exception { CertificateFactory rd = CertificateFactory.getInstance("X.509", "BC"); return (X509Certificate)rd.generateCertificate(getClass().getResourceAsStream(certName)); } public static void main (String[] args) throws Exception { junit.textui.TestRunner.run(suite()); } public static Test suite() throws Exception { TestSuite suite = new TestSuite("Bleichenbacher's Forgery Attack Tests"); suite.addTestSuite(RSA3CertTest.class); return suite; } } bouncycastle-1.49.orig/test/src/org/bouncycastle/jce/provider/test/CMacTest.java0000644000175000017500000002056611376621376027366 0ustar ebourgebourgpackage org.bouncycastle.jce.provider.test; import java.security.Security; import javax.crypto.Mac; import javax.crypto.spec.SecretKeySpec; import org.bouncycastle.jce.provider.BouncyCastleProvider; import org.bouncycastle.util.encoders.Hex; import org.bouncycastle.util.test.SimpleTest; /** * CMAC tester - AES Official Test Vectors. */ public class CMacTest extends SimpleTest { private static final byte[] keyBytes128 = Hex.decode("2b7e151628aed2a6abf7158809cf4f3c"); private static final byte[] keyBytes192 = Hex.decode( "8e73b0f7da0e6452c810f32b809079e5" + "62f8ead2522c6b7b"); private static final byte[] keyBytes256 = Hex.decode( "603deb1015ca71be2b73aef0857d7781" + "1f352c073b6108d72d9810a30914dff4"); private static final byte[] input0 = Hex.decode(""); private static final byte[] input16 = Hex.decode("6bc1bee22e409f96e93d7e117393172a"); private static final byte[] input40 = Hex.decode( "6bc1bee22e409f96e93d7e117393172a" + "ae2d8a571e03ac9c9eb76fac45af8e5130c81c46a35ce411"); private static final byte[] input64 = Hex.decode( "6bc1bee22e409f96e93d7e117393172a" + "ae2d8a571e03ac9c9eb76fac45af8e51" + "30c81c46a35ce411e5fbc1191a0a52ef" + "f69f2445df4f9b17ad2b417be66c3710"); private static final byte[] output_k128_m0 = Hex.decode("bb1d6929e95937287fa37d129b756746"); private static final byte[] output_k128_m16 = Hex.decode("070a16b46b4d4144f79bdd9dd04a287c"); private static final byte[] output_k128_m40 = Hex.decode("dfa66747de9ae63030ca32611497c827"); private static final byte[] output_k128_m64 = Hex.decode("51f0bebf7e3b9d92fc49741779363cfe"); private static final byte[] output_k192_m0 = Hex.decode("d17ddf46adaacde531cac483de7a9367"); private static final byte[] output_k192_m16 = Hex.decode("9e99a7bf31e710900662f65e617c5184"); private static final byte[] output_k192_m40 = Hex.decode("8a1de5be2eb31aad089a82e6ee908b0e"); private static final byte[] output_k192_m64 = Hex.decode("a1d5df0eed790f794d77589659f39a11"); private static final byte[] output_k256_m0 = Hex.decode("028962f61b7bf89efc6b551f4667d983"); private static final byte[] output_k256_m16 = Hex.decode("28a7023f452e8f82bd4bf28d8c37c35c"); private static final byte[] output_k256_m40 = Hex.decode("aaf3d8f1de5640c232f5b169b9c911e6"); private static final byte[] output_k256_m64 = Hex.decode("e1992190549f6ed5696a2c056c315410"); private final byte[] output_des_ede = Hex.decode("1ca670dea381d37c"); public CMacTest() { } public void performTest() throws Exception { Mac mac = Mac.getInstance("AESCMAC", "BC"); //128 bytes key SecretKeySpec key = new SecretKeySpec(keyBytes128, "AES"); // 0 bytes message - 128 bytes key mac.init(key); mac.update(input0, 0, input0.length); byte[] out = new byte[mac.getMacLength()]; mac.doFinal(out, 0); if (!areEqual(out, output_k128_m0)) { fail("Failed - expected " + new String(Hex.encode(output_k128_m0)) + " got " + new String(Hex.encode(out))); } // 16 bytes message - 128 bytes key mac.init(key); mac.update(input16, 0, input16.length); out = new byte[mac.getMacLength()]; mac.doFinal(out, 0); if (!areEqual(out, output_k128_m16)) { fail("Failed - expected " + new String(Hex.encode(output_k128_m16)) + " got " + new String(Hex.encode(out))); } // 40 bytes message - 128 bytes key mac.init(key); mac.update(input40, 0, input40.length); out = new byte[mac.getMacLength()]; mac.doFinal(out, 0); if (!areEqual(out, output_k128_m40)) { fail("Failed - expected " + new String(Hex.encode(output_k128_m40)) + " got " + new String(Hex.encode(out))); } // 64 bytes message - 128 bytes key mac.init(key); mac.update(input64, 0, input64.length); out = new byte[mac.getMacLength()]; mac.doFinal(out, 0); if (!areEqual(out, output_k128_m64)) { fail("Failed - expected " + new String(Hex.encode(output_k128_m64)) + " got " + new String(Hex.encode(out))); } //192 bytes key key = new SecretKeySpec(keyBytes192, "AES"); // 0 bytes message - 192 bytes key mac.init(key); mac.update(input0, 0, input0.length); out = new byte[mac.getMacLength()]; mac.doFinal(out, 0); if (!areEqual(out, output_k192_m0)) { fail("Failed - expected " + new String(Hex.encode(output_k192_m0)) + " got " + new String(Hex.encode(out))); } // 16 bytes message - 192 bytes key mac.init(key); mac.update(input16, 0, input16.length); out = new byte[mac.getMacLength()]; mac.doFinal(out, 0); if (!areEqual(out, output_k192_m16)) { fail("Failed - expected " + new String(Hex.encode(output_k192_m16)) + " got " + new String(Hex.encode(out))); } // 40 bytes message - 192 bytes key mac.init(key); mac.update(input40, 0, input40.length); out = new byte[mac.getMacLength()]; mac.doFinal(out, 0); if (!areEqual(out, output_k192_m40)) { fail("Failed - expected " + new String(Hex.encode(output_k192_m40)) + " got " + new String(Hex.encode(out))); } // 64 bytes message - 192 bytes key mac.init(key); mac.update(input64, 0, input64.length); out = new byte[mac.getMacLength()]; mac.doFinal(out, 0); if (!areEqual(out, output_k192_m64)) { fail("Failed - expected " + new String(Hex.encode(output_k192_m64)) + " got " + new String(Hex.encode(out))); } //256 bytes key key = new SecretKeySpec(keyBytes256, "AES"); // 0 bytes message - 256 bytes key mac.init(key); mac.update(input0, 0, input0.length); out = new byte[mac.getMacLength()]; mac.doFinal(out, 0); if (!areEqual(out, output_k256_m0)) { fail("Failed - expected " + new String(Hex.encode(output_k256_m0)) + " got " + new String(Hex.encode(out))); } // 16 bytes message - 256 bytes key mac.init(key); mac.update(input16, 0, input16.length); out = new byte[mac.getMacLength()]; mac.doFinal(out, 0); if (!areEqual(out, output_k256_m16)) { fail("Failed - expected " + new String(Hex.encode(output_k256_m16)) + " got " + new String(Hex.encode(out))); } // 40 bytes message - 256 bytes key mac.init(key); mac.update(input40, 0, input40.length); out = new byte[mac.getMacLength()]; mac.doFinal(out, 0); if (!areEqual(out, output_k256_m40)) { fail("Failed - expected " + new String(Hex.encode(output_k256_m40)) + " got " + new String(Hex.encode(out))); } // 64 bytes message - 256 bytes key mac.init(key); mac.update(input64, 0, input64.length); out = new byte[mac.getMacLength()]; mac.doFinal(out, 0); if (!areEqual(out, output_k256_m64)) { fail("Failed - expected " + new String(Hex.encode(output_k256_m64)) + " got " + new String(Hex.encode(out))); } mac = Mac.getInstance("DESedeCMAC", "BC"); //DESede key = new SecretKeySpec(keyBytes128, "DESede"); // 0 bytes message - 128 bytes key mac.init(key); mac.update(input0, 0, input0.length); out = new byte[mac.getMacLength()]; mac.doFinal(out, 0); if (!areEqual(out, output_des_ede)) { fail("Failed - expected " + new String(Hex.encode(output_des_ede)) + " got " + new String(Hex.encode(out))); } } public String getName() { return "CMac"; } public static void main(String[] args) { Security.addProvider(new BouncyCastleProvider()); runTest(new CMacTest()); } } bouncycastle-1.49.orig/test/src/org/bouncycastle/jce/provider/test/GOST28147Test.java0000644000175000017500000001640710330633061027723 0ustar ebourgebourgpackage org.bouncycastle.jce.provider.test; import java.io.ByteArrayInputStream; import java.io.ByteArrayOutputStream; import java.io.DataInputStream; import java.security.Key; import java.security.Security; import javax.crypto.Cipher; import javax.crypto.CipherInputStream; import javax.crypto.CipherOutputStream; import javax.crypto.KeyGenerator; import javax.crypto.SecretKey; import javax.crypto.spec.SecretKeySpec; import javax.crypto.spec.IvParameterSpec; import org.bouncycastle.asn1.cryptopro.CryptoProObjectIdentifiers; import org.bouncycastle.jce.provider.BouncyCastleProvider; import org.bouncycastle.util.encoders.Hex; import org.bouncycastle.util.test.SimpleTest; /** * basic test class for the GOST28147 cipher */ public class GOST28147Test extends SimpleTest { static String[] cipherTests = { "256", "0123456789abcdef0123456789abcdef0123456789abcdef0123456789abcdef", "4e6f77206973207468652074696d6520666f7220616c6c20", "281630d0d5770030068c252d841e84149ccc1912052dbc02", "256", "0123456789abcdef0123456789abcdef0123456789abcdef0123456789abcdef", "4e6f77206973207468652074696d65208a920c6ed1a804f5", "88e543dfc04dc4f764fa7b624741cec07de49b007bf36065" }; public String getName() { return "GOST28147"; } public void testECB( int strength, byte[] keyBytes, byte[] input, byte[] output) throws Exception { Key key; Cipher in, out; CipherInputStream cIn; CipherOutputStream cOut; ByteArrayInputStream bIn; ByteArrayOutputStream bOut; key = new SecretKeySpec(keyBytes, "GOST28147"); in = Cipher.getInstance("GOST28147/ECB/NoPadding", "BC"); out = Cipher.getInstance("GOST28147/ECB/NoPadding", "BC"); out.init(Cipher.ENCRYPT_MODE, key); in.init(Cipher.DECRYPT_MODE, key); // // encryption pass // bOut = new ByteArrayOutputStream(); cOut = new CipherOutputStream(bOut, out); for (int i = 0; i != input.length / 2; i++) { cOut.write(input[i]); } cOut.write(input, input.length / 2, input.length - input.length / 2); cOut.close(); byte[] bytes; bytes = bOut.toByteArray(); if (!areEqual(bytes, output)) { fail("GOST28147 failed encryption - expected " + new String(Hex.encode(output)) + " got " + new String(Hex.encode(bytes))); } // // decryption pass // bIn = new ByteArrayInputStream(bytes); cIn = new CipherInputStream(bIn, in); DataInputStream dIn = new DataInputStream(cIn); bytes = new byte[input.length]; for (int i = 0; i != input.length / 2; i++) { bytes[i] = (byte)dIn.read(); } dIn.readFully(bytes, input.length / 2, bytes.length - input.length / 2); if (!areEqual(bytes, input)) { fail("GOST28147 failed decryption - expected " + new String(Hex.encode(input)) + " got " + new String(Hex.encode(bytes))); } } public void testCFB( int strength, byte[] keyBytes, byte[] input, byte[] output) throws Exception { Key key; Cipher in, out; CipherInputStream cIn; CipherOutputStream cOut; ByteArrayInputStream bIn; ByteArrayOutputStream bOut; key = new SecretKeySpec(keyBytes, "GOST28147"); in = Cipher.getInstance("GOST28147/CFB8/NoPadding", "BC"); out = Cipher.getInstance("GOST28147/CFB8/NoPadding", "BC"); byte[] iv = {1,2,3,4,5,6,7,8}; out.init(Cipher.ENCRYPT_MODE, key, new IvParameterSpec(iv)); in.init(Cipher.DECRYPT_MODE, key, new IvParameterSpec(iv)); // // encryption pass // bOut = new ByteArrayOutputStream(); cOut = new CipherOutputStream(bOut, out); for (int i = 0; i != input.length / 2; i++) { cOut.write(input[i]); } cOut.write(input, input.length / 2, input.length - input.length / 2); cOut.close(); byte[] bytes; bytes = bOut.toByteArray(); if (!areEqual(bytes, output)) { fail("GOST28147 failed encryption - expected " + new String(Hex.encode(output)) + " got " + new String(Hex.encode(bytes))); } // // decryption pass // bIn = new ByteArrayInputStream(bytes); cIn = new CipherInputStream(bIn, in); DataInputStream dIn = new DataInputStream(cIn); bytes = new byte[input.length]; for (int i = 0; i != input.length / 2; i++) { bytes[i] = (byte)dIn.read(); } dIn.readFully(bytes, input.length / 2, bytes.length - input.length / 2); if (!areEqual(bytes, input)) { fail("GOST28147 failed decryption - expected " + new String(Hex.encode(input)) + " got " + new String(Hex.encode(bytes))); } } private void oidTest() { String[] oids = { CryptoProObjectIdentifiers.gostR28147_cbc.getId(), }; String[] names = { "GOST28147/CBC/PKCS7Padding" }; try { byte[] data = { 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16 }; IvParameterSpec ivSpec = new IvParameterSpec(new byte[8]); for (int i = 0; i != oids.length; i++) { Cipher c1 = Cipher.getInstance(oids[i], "BC"); Cipher c2 = Cipher.getInstance(names[i], "BC"); KeyGenerator kg = KeyGenerator.getInstance(oids[i], "BC"); SecretKey k = kg.generateKey(); c1.init(Cipher.ENCRYPT_MODE, k, ivSpec); c2.init(Cipher.DECRYPT_MODE, k, ivSpec); byte[] result = c2.doFinal(c1.doFinal(data)); if (!areEqual(data, result)) { fail("failed OID test"); } } } catch (Exception ex) { fail("failed exception " + ex.toString(), ex); } } public void performTest() throws Exception { for (int i = 0; i != cipherTests.length; i += 8) { testECB(Integer.parseInt(cipherTests[i]), Hex.decode(cipherTests[i + 1]), Hex.decode(cipherTests[i + 2]), Hex.decode(cipherTests[i + 3])); testCFB(Integer.parseInt(cipherTests[i + 4]), Hex.decode(cipherTests[i + 4 + 1]), Hex.decode(cipherTests[i + 4 + 2]), Hex.decode(cipherTests[i + 4 + 3])); oidTest(); } } public static void main( String[] args) { Security.addProvider(new BouncyCastleProvider()); runTest(new GOST28147Test()); } } bouncycastle-1.49.orig/test/src/org/bouncycastle/jce/provider/test/CertPathTest.java0000644000175000017500000004136611402451711030256 0ustar ebourgebourgpackage org.bouncycastle.jce.provider.test; import java.io.ByteArrayInputStream; import java.io.ByteArrayOutputStream; import java.io.ObjectOutputStream; import java.security.InvalidKeyException; import java.security.NoSuchAlgorithmException; import java.security.NoSuchProviderException; import java.security.PublicKey; import java.security.Security; import java.security.SignatureException; import java.security.cert.CertPath; import java.security.cert.CertPathBuilder; import java.security.cert.CertPathBuilderException; import java.security.cert.CertPathBuilderResult; import java.security.cert.CertStore; import java.security.cert.Certificate; import java.security.cert.CertificateEncodingException; import java.security.cert.CertificateException; import java.security.cert.CertificateFactory; import java.security.cert.CollectionCertStoreParameters; import java.security.cert.PKIXBuilderParameters; import java.security.cert.TrustAnchor; import java.security.cert.X509CertSelector; import java.security.cert.X509Certificate; import java.util.ArrayList; import java.util.Collections; import java.util.HashSet; import java.util.Iterator; import java.util.List; import java.util.Set; import java.util.Vector; import org.bouncycastle.jce.provider.BouncyCastleProvider; import org.bouncycastle.util.encoders.Base64; import org.bouncycastle.util.test.SimpleTest; public class CertPathTest extends SimpleTest { public static byte[] rootCertBin = Base64.decode( "MIIBqzCCARQCAQEwDQYJKoZIhvcNAQEFBQAwHjEcMBoGA1UEAxMTVGVzdCBDQSBDZXJ0aWZpY2F0ZTAeFw0wODA5MDQwNDQ1MDhaFw0wODA5MTEwNDQ1MDhaMB4xHDAaBgNVBAMTE1Rlc3QgQ0EgQ2VydGlmaWNhdGUwgZ8wDQYJKoZIhvcNAQEBBQADgY0AMIGJAoGBAMRLUjhPe4YUdLo6EcjKcWUOG7CydFTH53Pr1lWjOkbmszYDpkhCTT9LOsI+disk18nkBxSl8DAHTqV+VxtuTPt64iyi10YxyDeep+DwZG/f8cVQv97U3hA9cLurZ2CofkMLGr6JpSGCMZ9FcstcTdHB4lbErIJ54YqfF4pNOs4/AgMBAAEwDQYJKoZIhvcNAQEFBQADgYEAgyrTEFY7ALpeY59jL6xFOLpuPqoBOWrUWv6O+zy5BCU0qiX71r3BpigtxRj+DYcfLIM9FNERDoHu3TthD3nwYWUBtFX8N0QUJIdJabxqAMhLjSC744koiFpCYse5Ye3ZvEdFwDzgAQsJTp5eFGgTZPkPzcdhkFJ2p9+OWs+cb24="); static byte[] interCertBin = Base64.decode( "MIICSzCCAbSgAwIBAgIBATANBgkqhkiG9w0BAQUFADAeMRwwGgYDVQQDExNUZXN0IENBIENlcnRpZmljYXRlMB4XDTA4MDkwNDA0NDUwOFoXDTA4MDkxMTA0NDUwOFowKDEmMCQGA1UEAxMdVGVzdCBJbnRlcm1lZGlhdGUgQ2VydGlmaWNhdGUwgZ8wDQYJKoZIhvcNAQEBBQADgY0AMIGJAoGBAISS9OOZ2wxzdWny9aVvk4Joq+dwSJ+oqvHUxX3PflZyuiLiCBUOUE4q59dGKdtNX5fIfwyK3cpV0e73Y/0fwfM3m9rOWFrCKOhfeswNTes0w/2PqPVVDDsF/nj7NApuqXwioeQlgTL251RDF4sVoxXqAU7lRkcqwZt3mwqS4KTJAgMBAAGjgY4wgYswRgYDVR0jBD8wPYAUhv8BOT27EB9JaCccJD4YASPP5XWhIqQgMB4xHDAaBgNVBAMTE1Rlc3QgQ0EgQ2VydGlmaWNhdGWCAQEwHQYDVR0OBBYEFL/IwAGOkHzaQyPZegy79CwM5oTFMBIGA1UdEwEB/wQIMAYBAf8CAQAwDgYDVR0PAQH/BAQDAgGGMA0GCSqGSIb3DQEBBQUAA4GBAE4TRgUz4sUvZyVdZxqV+XyNRnqXAeLOOqFGYv2D96tQrS+zjd0elVlT6lFrtchZdOmmX7R6/H/tjMWMcTBICZyRYrvK8cCAmDOI+EIdq5p6lj2Oq6Pbw/wruojAqNrpaR6IkwNpWtdOSSupv4IJL+YU9q2YFTh4R1j3tOkPoFGr"); static byte[] finalCertBin = Base64.decode( "MIICRjCCAa+gAwIBAgIBATANBgkqhkiG9w0BAQUFADAoMSYwJAYDVQQDEx1UZXN0IEludGVybWVkaWF0ZSBDZXJ0aWZpY2F0ZTAeFw0wODA5MDQwNDQ1MDhaFw0wODA5MTEwNDQ1MDhaMB8xHTAbBgNVBAMTFFRlc3QgRW5kIENlcnRpZmljYXRlMIGfMA0GCSqGSIb3DQEBAQUAA4GNADCBiQKBgQChpUeo0tPYywWKiLlbWKNJBcCpSaLSlaZ+4+yer1AxI5yJIVHP6SAlBghlbD5Qne5ImnN/15cz1xwYAiul6vGKJkVPlFEe2Mr+g/J/WJPQQPsjbZ1G+vxbAwXEDA4KaQrnpjRZFq+CdKHwOjuPLYS/MYQNgdIvDVEQcTbPQ8GaiQIDAQABo4GIMIGFMEYGA1UdIwQ/MD2AFL/IwAGOkHzaQyPZegy79CwM5oTFoSKkIDAeMRwwGgYDVQQDExNUZXN0IENBIENlcnRpZmljYXRlggEBMB0GA1UdDgQWBBSVkw+VpqBf3zsLc/9GdkK9TzHPwDAMBgNVHRMBAf8EAjAAMA4GA1UdDwEB/wQEAwIFoDANBgkqhkiG9w0BAQUFAAOBgQBLv/0bVDjzTs/y1vN3FUiZNknEbzupIZduTuXJjqv/vBX+LDPjUfu/+iOCXOSKoRn6nlOWhwB1z6taG2usQkFG8InMkRcPREi2uVgFdhJ/1C3dAWhsdlubjdL926bftXvxnx/koDzyrePW5U96RlOQM2qLvbaky2Giz6hrc3Wl+w=="); public static byte[] rootCrlBin = Base64.decode( "MIIBYjCBzAIBATANBgkqhkiG9w0BAQsFADAeMRwwGgYDVQQDExNUZXN0IENBIENlcnRpZmljYXRlFw0wODA5MDQwNDQ1MDhaFw0wODA5MDQwNzMxNDhaMCIwIAIBAhcNMDgwOTA0MDQ0NTA4WjAMMAoGA1UdFQQDCgEJoFYwVDBGBgNVHSMEPzA9gBSG/wE5PbsQH0loJxwkPhgBI8/ldaEipCAwHjEcMBoGA1UEAxMTVGVzdCBDQSBDZXJ0aWZpY2F0ZYIBATAKBgNVHRQEAwIBATANBgkqhkiG9w0BAQsFAAOBgQCAbaFCo0BNG4AktVf6jjBLeawP1u0ELYkOCEGvYZE0mBpQ+OvFg7subZ6r3lRIj030nUli28sPFtu5ZQMBNcpE4nS1ziF44RfT3Lp5UgHx9x17Krz781iEyV+7zU8YxYMY9wULD+DCuK294kGKIssVNbmTYXZatBNoXQN5CLIocA=="); static byte[] interCrlBin = Base64.decode( "MIIBbDCB1gIBATANBgkqhkiG9w0BAQsFADAoMSYwJAYDVQQDEx1UZXN0IEludGVybWVkaWF0ZSBDZXJ0aWZpY2F0ZRcNMDgwOTA0MDQ0NTA4WhcNMDgwOTA0MDczMTQ4WjAiMCACAQIXDTA4MDkwNDA0NDUwOFowDDAKBgNVHRUEAwoBCaBWMFQwRgYDVR0jBD8wPYAUv8jAAY6QfNpDI9l6DLv0LAzmhMWhIqQgMB4xHDAaBgNVBAMTE1Rlc3QgQ0EgQ2VydGlmaWNhdGWCAQEwCgYDVR0UBAMCAQEwDQYJKoZIhvcNAQELBQADgYEAEVCr5TKs5yguGgLH+dBzmSPoeSIWJFLsgWwJEit/iUDJH3dgYmaczOcGxIDtbYYHLWIHM+P2YRyQz3MEkCXEgm/cx4y7leAmux5l+xQWgmxFPz+197vaphPeCZo+B7V1CWtm518gcq4mrs9ovfgNqgyFj7KGjcBpWdJE32KMt50="); /* * certpath with a circular reference */ static byte[] certA = Base64.decode( "MIIC6jCCAlOgAwIBAgIBBTANBgkqhkiG9w0BAQUFADCBjTEPMA0GA1UEAxMGSW50" + "ZXIzMQswCQYDVQQGEwJDSDEPMA0GA1UEBxMGWnVyaWNoMQswCQYDVQQIEwJaSDEX" + "MBUGA1UEChMOUHJpdmFzcGhlcmUgQUcxEDAOBgNVBAsTB1Rlc3RpbmcxJDAiBgkq" + "hkiG9w0BCQEWFWFybWluQHByaXZhc3BoZXJlLmNvbTAeFw0wNzA0MDIwODQ2NTda" + "Fw0xNzAzMzAwODQ0MDBaMIGlMScwJQYDVQQDHh4AQQByAG0AaQBuACAASADkAGIA" + "ZQByAGwAaQBuAGcxCzAJBgNVBAYTAkNIMQ8wDQYDVQQHEwZadXJpY2gxCzAJBgNV" + "BAgTAlpIMRcwFQYDVQQKEw5Qcml2YXNwaGVyZSBBRzEQMA4GA1UECxMHVGVzdGlu" + "ZzEkMCIGCSqGSIb3DQEJARYVYXJtaW5AcHJpdmFzcGhlcmUuY29tMIGfMA0GCSqG" + "SIb3DQEBAQUAA4GNADCBiQKBgQCfHfyVs5dbxG35H/Thd29qR4NZU88taCu/OWA1" + "GdACI02lXWYpmLWiDgnU0ULP+GG8OnVp1IES9fz2zcrXKQ19xZzsen/To3h5sNte" + "cJpS00XMM24q/jDwy5NvkBP9YIfFKQ1E/0hFHXcqwlw+b/y/v6YGsZCU2h6QDzc4" + "5m0+BwIDAQABo0AwPjAMBgNVHRMBAf8EAjAAMA4GA1UdDwEB/wQEAwIE8DAeBglg" + "hkgBhvhCAQ0EERYPeGNhIGNlcnRpZmljYXRlMA0GCSqGSIb3DQEBBQUAA4GBAJEu" + "KiSfIwsY7SfobMLrv2v/BtLhGLi4RnmjiwzBhuv5rn4rRfBpq1ppmqQMJ2pmA67v" + "UWCY+mNwuyjHyivpCCyJGsZ9d5H09g2vqxzkDBMz7X9VNMZYFH8j/R3/Cfvqks31" + "z0OFslJkeKLa1I0P/dfVHsRKNkLRT3Ws5LKksErQ"); static byte[] certB = Base64.decode( "MIICtTCCAh6gAwIBAgIBBDANBgkqhkiG9w0BAQQFADCBjTEPMA0GA1UEAxMGSW50" + "ZXIyMQswCQYDVQQGEwJDSDEPMA0GA1UEBxMGWnVyaWNoMQswCQYDVQQIEwJaSDEX" + "MBUGA1UEChMOUHJpdmFzcGhlcmUgQUcxEDAOBgNVBAsTB1Rlc3RpbmcxJDAiBgkq" + "hkiG9w0BCQEWFWFybWluQHByaXZhc3BoZXJlLmNvbTAeFw0wNzA0MDIwODQ2Mzha" + "Fw0xNzAzMzAwODQ0MDBaMIGNMQ8wDQYDVQQDEwZJbnRlcjMxCzAJBgNVBAYTAkNI" + "MQ8wDQYDVQQHEwZadXJpY2gxCzAJBgNVBAgTAlpIMRcwFQYDVQQKEw5Qcml2YXNw" + "aGVyZSBBRzEQMA4GA1UECxMHVGVzdGluZzEkMCIGCSqGSIb3DQEJARYVYXJtaW5A" + "cHJpdmFzcGhlcmUuY29tMIGfMA0GCSqGSIb3DQEBAQUAA4GNADCBiQKBgQCxCXIB" + "QRnmVvl2h7Q+0SsRxDLnyM1dJG9jMa+UCCmHy0k/ZHs5VirSbjEJSjkQ9BGeh9SC" + "7JwbMpXO7UE+gcVc2RnWUY+MA+fWIeTV4KtkYA8WPu8wVGCXbN8wwh/StOocszxb" + "g+iLvGeh8CYSRqg6QN3S/02etH3o8H4e7Z0PZwIDAQABoyMwITAPBgNVHRMBAf8E" + "BTADAQH/MA4GA1UdDwEB/wQEAwIB9jANBgkqhkiG9w0BAQQFAAOBgQCtWdirSsmt" + "+CBBCNn6ZnbU3QqQfiiQIomjenNEHESJgaS/+PvPE5i3xWFXsunTHLW321/Km16I" + "7+ZvT8Su1cqHg79NAT8QB0yke1saKSy2C0Pic4HwrNqVBWFNSxMU0hQzpx/ZXDbZ" + "DqIXAp5EfyRYBy2ul+jm6Rot6aFgzuopKg=="); static byte[] certC = Base64.decode( "MIICtTCCAh6gAwIBAgIBAjANBgkqhkiG9w0BAQQFADCBjTEPMA0GA1UEAxMGSW50" + "ZXIxMQswCQYDVQQGEwJDSDEPMA0GA1UEBxMGWnVyaWNoMQswCQYDVQQIEwJaSDEX" + "MBUGA1UEChMOUHJpdmFzcGhlcmUgQUcxEDAOBgNVBAsTB1Rlc3RpbmcxJDAiBgkq" + "hkiG9w0BCQEWFWFybWluQHByaXZhc3BoZXJlLmNvbTAeFw0wNzA0MDIwODQ0Mzla" + "Fw0xNzAzMzAwODQ0MDBaMIGNMQ8wDQYDVQQDEwZJbnRlcjIxCzAJBgNVBAYTAkNI" + "MQ8wDQYDVQQHEwZadXJpY2gxCzAJBgNVBAgTAlpIMRcwFQYDVQQKEw5Qcml2YXNw" + "aGVyZSBBRzEQMA4GA1UECxMHVGVzdGluZzEkMCIGCSqGSIb3DQEJARYVYXJtaW5A" + "cHJpdmFzcGhlcmUuY29tMIGfMA0GCSqGSIb3DQEBAQUAA4GNADCBiQKBgQD0rLr6" + "f2/ONeJzTb0q9M/NNX+MnAFMSqiQGVBkT76u5nOH4KLkpHXkzI82JI7GuQMzoT3a" + "+RP1hO6FneO92ms2soC6xiOFb4EC69Dfhh87Nww5O35JxVF0bzmbmIAWd6P/7zGh" + "nd2S4tKkaZcubps+C0j9Fgi0hipVicAOUVVoDQIDAQABoyMwITAPBgNVHRMBAf8E" + "BTADAQH/MA4GA1UdDwEB/wQEAwIB9jANBgkqhkiG9w0BAQQFAAOBgQCLPvc1IMA4" + "YP+PmnEldyUoRWRnvPWjBGeu0WheBP7fdcnGBf93Nmc5j68ZN+eTZ5VMuZ99YdvH" + "CXGNX6oodONLU//LlFKdLl5xjLAS5X9p1RbOEGytnalqeiEpjk4+C/7rIBG1kllO" + "dItmI6LlEMV09Hkpg6ZRAUmRkb8KrM4X7A=="); static byte[] certD = Base64.decode( "MIICtTCCAh6gAwIBAgIBBjANBgkqhkiG9w0BAQQFADCBjTEPMA0GA1UEAxMGSW50" + "ZXIzMQswCQYDVQQGEwJDSDEPMA0GA1UEBxMGWnVyaWNoMQswCQYDVQQIEwJaSDEX" + "MBUGA1UEChMOUHJpdmFzcGhlcmUgQUcxEDAOBgNVBAsTB1Rlc3RpbmcxJDAiBgkq" + "hkiG9w0BCQEWFWFybWluQHByaXZhc3BoZXJlLmNvbTAeFw0wNzA0MDIwODQ5NTNa" + "Fw0xNzAzMzAwODQ0MDBaMIGNMQ8wDQYDVQQDEwZJbnRlcjExCzAJBgNVBAYTAkNI" + "MQ8wDQYDVQQHEwZadXJpY2gxCzAJBgNVBAgTAlpIMRcwFQYDVQQKEw5Qcml2YXNw" + "aGVyZSBBRzEQMA4GA1UECxMHVGVzdGluZzEkMCIGCSqGSIb3DQEJARYVYXJtaW5A" + "cHJpdmFzcGhlcmUuY29tMIGfMA0GCSqGSIb3DQEBAQUAA4GNADCBiQKBgQCae3TP" + "jIVKeASqvNabaiUHAMGUgFxB7L0yUsIj39azLcLtUj4S7XkDf7SMGtYV0JY1XNaQ" + "sHJAsnJivDZc50oiYvqDYfgFZx5+AsN5l5X5rjRzs/OX+Jo+k1OgsIyu6+mf9Kfb" + "5IdWOVB2EcOg4f9tPjLM8CIj9Pp7RbKLyqUUgwIDAQABoyMwITAPBgNVHRMBAf8E" + "BTADAQH/MA4GA1UdDwEB/wQEAwIB9jANBgkqhkiG9w0BAQQFAAOBgQCgr9kUdWUT" + "Lt9UcztSzR3pnHRsyvS0E/z850OKQKS5/VxLEalpFvhj+3EcZ7Y6mFxaaS2B7vXg" + "2YWyqV1PRb6iF7/u9EXkpSTKGrJahwANirCa3V/HTUuPdCE2GITlnWI8h3eVA+xQ" + "D4LF0PXHOkXbwmhXRSb10lW1bSGkUxE9jg=="); private void testExceptions() throws Exception { byte[] enc = { (byte)0, (byte)2, (byte)3, (byte)4, (byte)5 }; MyCertPath mc = new MyCertPath(enc); ByteArrayOutputStream os = new ByteArrayOutputStream(); ByteArrayInputStream is; byte[] arr; ObjectOutputStream oOut = new ObjectOutputStream(os); oOut.writeObject(mc); oOut.flush(); oOut.close(); try { CertificateFactory cFac = CertificateFactory.getInstance("X.509", "BC"); arr = os.toByteArray(); is = new ByteArrayInputStream(arr); cFac.generateCertPath(is); } catch (CertificateException e) { // ignore okay } CertificateFactory cf = CertificateFactory.getInstance("X.509"); List certCol = new ArrayList(); certCol.add(cf.generateCertificate(new ByteArrayInputStream(certA))); certCol.add(cf.generateCertificate(new ByteArrayInputStream(certB))); certCol.add(cf.generateCertificate(new ByteArrayInputStream(certC))); certCol.add(cf.generateCertificate(new ByteArrayInputStream(certD))); CertPathBuilder pathBuilder = CertPathBuilder.getInstance("PKIX", "BC"); X509CertSelector select = new X509CertSelector(); select.setSubject(((X509Certificate)certCol.get(0)).getSubjectX500Principal().getEncoded()); Set trustanchors = new HashSet(); trustanchors.add(new TrustAnchor((X509Certificate)cf.generateCertificate(new ByteArrayInputStream(rootCertBin)), null)); CertStore certStore = CertStore.getInstance("Collection", new CollectionCertStoreParameters(certCol)); PKIXBuilderParameters params = new PKIXBuilderParameters(trustanchors, select); params.addCertStore(certStore); try { CertPathBuilderResult result = pathBuilder.build(params); CertPath path = result.getCertPath(); fail("found cert path in circular set"); } catch (CertPathBuilderException e) { // expected } } public void performTest() throws Exception { CertificateFactory cf = CertificateFactory.getInstance("X.509", "BC"); X509Certificate rootCert = (X509Certificate)cf.generateCertificate(new ByteArrayInputStream(rootCertBin)); X509Certificate interCert = (X509Certificate)cf.generateCertificate(new ByteArrayInputStream(interCertBin)); X509Certificate finalCert = (X509Certificate)cf.generateCertificate(new ByteArrayInputStream(finalCertBin)); //Testing CertPath generation from List List list = new ArrayList(); list.add(interCert); CertPath certPath1 = cf.generateCertPath(list); //Testing CertPath encoding as PkiPath byte[] encoded = certPath1.getEncoded("PkiPath"); //Testing CertPath generation from InputStream ByteArrayInputStream inStream = new ByteArrayInputStream(encoded); CertPath certPath2 = cf.generateCertPath(inStream, "PkiPath"); //Comparing both CertPathes if (!certPath2.equals(certPath1)) { fail("CertPath differ after encoding and decoding."); } encoded = certPath1.getEncoded("PKCS7"); //Testing CertPath generation from InputStream inStream = new ByteArrayInputStream(encoded); certPath2 = cf.generateCertPath(inStream, "PKCS7"); //Comparing both CertPathes if (!certPath2.equals(certPath1)) { fail("CertPath differ after encoding and decoding."); } encoded = certPath1.getEncoded("PEM"); //Testing CertPath generation from InputStream inStream = new ByteArrayInputStream(encoded); certPath2 = cf.generateCertPath(inStream, "PEM"); //Comparing both CertPathes if (!certPath2.equals(certPath1)) { fail("CertPath differ after encoding and decoding."); } // // empty list test // list = new ArrayList(); CertPath certPath = CertificateFactory.getInstance("X.509","BC").generateCertPath(list); if (certPath.getCertificates().size() != 0) { fail("list wrong size."); } // // exception tests // testExceptions(); } public String getName() { return "CertPath"; } public static void main( String[] args) { Security.addProvider(new BouncyCastleProvider()); runTest(new CertPathTest()); } private static class MyCertificate extends Certificate { private final byte[] encoding; public MyCertificate(String type, byte[] encoding) { super(type); // don't copy to allow null parameter in test this.encoding = encoding; } public byte[] getEncoded() throws CertificateEncodingException { // do copy to force NPE in test return (byte[])encoding.clone(); } public void verify(PublicKey key) throws CertificateException, NoSuchAlgorithmException, InvalidKeyException, NoSuchProviderException, SignatureException { } public void verify(PublicKey key, String sigProvider) throws CertificateException, NoSuchAlgorithmException, InvalidKeyException, NoSuchProviderException, SignatureException { } public String toString() { return "[My test Certificate, type: " + getType() + "]"; } public PublicKey getPublicKey() { return new PublicKey() { public String getAlgorithm() { return "TEST"; } public byte[] getEncoded() { return new byte[] { (byte)1, (byte)2, (byte)3 }; } public String getFormat() { return "TEST_FORMAT"; } }; } } private static class MyCertPath extends CertPath { private final Vector certificates; private final Vector encodingNames; private final byte[] encoding; public MyCertPath(byte[] encoding) { super("MyEncoding"); this.encoding = encoding; certificates = new Vector(); certificates.add(new MyCertificate("MyEncoding", encoding)); encodingNames = new Vector(); encodingNames.add("MyEncoding"); } public List getCertificates() { return Collections.unmodifiableList(certificates); } public byte[] getEncoded() throws CertificateEncodingException { return (byte[])encoding.clone(); } public byte[] getEncoded(String encoding) throws CertificateEncodingException { if (getType().equals(encoding)) { return (byte[])this.encoding.clone(); } throw new CertificateEncodingException("Encoding not supported: " + encoding); } public Iterator getEncodings() { return Collections.unmodifiableCollection(encodingNames).iterator(); } } } bouncycastle-1.49.orig/test/src/org/bouncycastle/jce/provider/test/DESedeTest.java0000644000175000017500000002223612143616032027632 0ustar ebourgebourgpackage org.bouncycastle.jce.provider.test; import java.io.ByteArrayInputStream; import java.io.ByteArrayOutputStream; import java.io.DataInputStream; import java.io.IOException; import java.security.Key; import java.security.SecureRandom; import java.security.Security; import javax.crypto.Cipher; import javax.crypto.CipherInputStream; import javax.crypto.CipherOutputStream; import javax.crypto.KeyGenerator; import javax.crypto.SecretKey; import javax.crypto.SecretKeyFactory; import javax.crypto.spec.DESedeKeySpec; import javax.crypto.spec.IvParameterSpec; import javax.crypto.spec.SecretKeySpec; import org.bouncycastle.jce.provider.BouncyCastleProvider; import org.bouncycastle.util.encoders.Hex; import org.bouncycastle.util.test.SimpleTest; /** * basic test class for key generation for a DES-EDE block cipher, basically * this just exercises the provider, and makes sure we are behaving sensibly, * correctness of the implementation is shown in the lightweight test classes. */ public class DESedeTest extends SimpleTest { static String[] cipherTests1 = { "112", "2f4bc6b30c893fa549d82c560d61cf3eb088aed020603de249d82c560d61cf3e529e95ecd8e05394", "128", "2f4bc6b30c893fa549d82c560d61cf3eb088aed020603de249d82c560d61cf3e529e95ecd8e05394", "168", "50ddb583a25c21e6c9233f8e57a86d40bb034af421c03096c9233f8e57a86d402fce91e8eb639f89", "192", "50ddb583a25c21e6c9233f8e57a86d40bb034af421c03096c9233f8e57a86d402fce91e8eb639f89", }; static byte[] input1 = Hex.decode("000102030405060708090a0b0c0d0e0fff0102030405060708090a0b0c0d0e0f"); /** * a fake random number generator - we just want to make sure the random numbers * aren't random so that we get the same output, while still getting to test the * key generation facilities. */ private class FixedSecureRandom extends SecureRandom { byte[] seed = { (byte)0xaa, (byte)0xfd, (byte)0x12, (byte)0xf6, (byte)0x59, (byte)0xca, (byte)0xe6, (byte)0x34, (byte)0x89, (byte)0xb4, (byte)0x79, (byte)0xe5, (byte)0x07, (byte)0x6d, (byte)0xde, (byte)0xc2, (byte)0xf0, (byte)0x6c, (byte)0xb5, (byte)0x8f }; public void nextBytes( byte[] bytes) { int offset = 0; while ((offset + seed.length) < bytes.length) { System.arraycopy(seed, 0, bytes, offset, seed.length); offset += seed.length; } System.arraycopy(seed, 0, bytes, offset, bytes.length - offset); } } public String getName() { return "DESEDE"; } private boolean equalArray( byte[] a, byte[] b) { if (a.length != b.length) { return false; } for (int i = 0; i != a.length; i++) { if (a[i] != b[i]) { return false; } } return true; } private boolean equalArray( byte[] a, byte[] b, int length) { if (a.length < length) { return false; } if (b.length < length) { return false; } for (int i = 0; i != length; i++) { if (a[i] != b[i]) { return false; } } return true; } private void wrapTest( String alg, int id, byte[] kek, byte[] iv, byte[] in, byte[] out) { try { Cipher wrapper = Cipher.getInstance(alg + "Wrap", "BC"); wrapper.init(Cipher.WRAP_MODE, new SecretKeySpec(kek, alg), new IvParameterSpec(iv)); try { byte[] cText = wrapper.wrap(new SecretKeySpec(in, alg)); if (!equalArray(cText, out)) { fail("failed wrap test " + id + " expected " + new String(Hex.encode(out)) + " got " + new String(Hex.encode(cText))); } } catch (Exception e) { fail("failed wrap test exception " + e.toString()); } wrapper.init(Cipher.UNWRAP_MODE, new SecretKeySpec(kek, alg)); try { Key pText = wrapper.unwrap(out, alg, Cipher.SECRET_KEY); if (!equalArray(pText.getEncoded(), in)) { fail("failed unwrap test " + id + " expected " + new String(Hex.encode(in)) + " got " + new String(Hex.encode(pText.getEncoded()))); } } catch (Exception e) { fail("failed unwrap test exception " + e.toString()); } } catch (Exception ex) { fail("failed exception " + ex.toString()); } } public void test( String alg, int strength, byte[] input, byte[] output) { Key key = null; KeyGenerator keyGen; SecureRandom rand; Cipher in = null; Cipher out = null; CipherInputStream cIn; CipherOutputStream cOut; ByteArrayInputStream bIn; ByteArrayOutputStream bOut; rand = new FixedSecureRandom(); try { keyGen = KeyGenerator.getInstance(alg, "BC"); keyGen.init(strength, rand); key = keyGen.generateKey(); in = Cipher.getInstance(alg + "/ECB/PKCS7Padding", "BC"); out = Cipher.getInstance(alg + "/ECB/PKCS7Padding", "BC"); out.init(Cipher.ENCRYPT_MODE, key, rand); } catch (Exception e) { fail(alg + " failed initialisation - " + e.toString()); } try { in.init(Cipher.DECRYPT_MODE, key); } catch (Exception e) { fail(alg + " failed initialisation - " + e.toString()); } // // encryption pass // bOut = new ByteArrayOutputStream(); cOut = new CipherOutputStream(bOut, out); try { for (int i = 0; i != input.length / 2; i++) { cOut.write(input[i]); } cOut.write(input, input.length / 2, input.length - input.length / 2); cOut.close(); } catch (IOException e) { fail(alg + " failed encryption - " + e.toString()); } byte[] bytes; bytes = bOut.toByteArray(); if (!equalArray(bytes, output)) { fail(alg + " failed encryption - expected " + new String(Hex.encode(output)) + " got " + new String(Hex.encode(bytes))); } // // decryption pass // bIn = new ByteArrayInputStream(bytes); cIn = new CipherInputStream(bIn, in); try { DataInputStream dIn = new DataInputStream(cIn); bytes = new byte[input.length]; for (int i = 0; i != input.length / 2; i++) { bytes[i] = (byte)dIn.read(); } dIn.readFully(bytes, input.length / 2, bytes.length - input.length / 2); } catch (Exception e) { fail(alg + " failed encryption - " + e.toString()); } if (!equalArray(bytes, input)) { fail(alg + " failed decryption - expected " + new String(Hex.encode(input)) + " got " + new String(Hex.encode(bytes))); } // // keyspec test // try { SecretKeyFactory keyFactory = SecretKeyFactory.getInstance(alg, "BC"); DESedeKeySpec keySpec = (DESedeKeySpec)keyFactory.getKeySpec((SecretKey)key, DESedeKeySpec.class); if (!equalArray(key.getEncoded(), keySpec.getKey(), 16)) { fail(alg + " KeySpec does not match key."); } } catch (Exception e) { fail(alg + " failed keyspec - " + e.toString()); } } public void performTest() { for (int i = 0; i != cipherTests1.length; i += 2) { test("DESEDE", Integer.parseInt(cipherTests1[i]), input1, Hex.decode(cipherTests1[i + 1])); } for (int i = 0; i != cipherTests1.length; i += 2) { test("TDEA", Integer.parseInt(cipherTests1[i]), input1, Hex.decode(cipherTests1[i + 1])); } byte[] kek1 = Hex.decode("255e0d1c07b646dfb3134cc843ba8aa71f025b7c0838251f"); byte[] iv1 = Hex.decode("5dd4cbfc96f5453b"); byte[] in1 = Hex.decode("2923bf85e06dd6ae529149f1f1bae9eab3a7da3d860d3e98"); byte[] out1 = Hex.decode("690107618ef092b3b48ca1796b234ae9fa33ebb4159604037db5d6a84eb3aac2768c632775a467d4"); wrapTest("DESEDE", 1, kek1, iv1, in1, out1); wrapTest("TDEA", 1, kek1, iv1, in1, out1); } public static void main( String[] args) { Security.addProvider(new BouncyCastleProvider()); runTest(new DESedeTest()); } } bouncycastle-1.49.orig/test/src/org/bouncycastle/jce/provider/test/X509StreamParserTest.java0000644000175000017500000002652610530414466031552 0ustar ebourgebourgpackage org.bouncycastle.jce.provider.test; import org.bouncycastle.asn1.ASN1EncodableVector; import org.bouncycastle.asn1.ASN1InputStream; import org.bouncycastle.asn1.DERSet; import org.bouncycastle.asn1.DERTaggedObject; import org.bouncycastle.asn1.cms.CMSObjectIdentifiers; import org.bouncycastle.asn1.cms.ContentInfo; import org.bouncycastle.asn1.cms.SignedData; import org.bouncycastle.jce.provider.BouncyCastleProvider; import org.bouncycastle.util.encoders.Base64; import org.bouncycastle.util.test.SimpleTest; import org.bouncycastle.x509.X509AttributeCertificate; import org.bouncycastle.x509.X509CertificatePair; import org.bouncycastle.x509.X509StreamParser; import java.io.ByteArrayInputStream; import java.io.ByteArrayOutputStream; import java.security.Security; import java.security.cert.X509CRL; import java.security.cert.X509Certificate; import java.util.Collection; public class X509StreamParserTest extends SimpleTest { byte[] attrCert = Base64.decode( "MIIHQDCCBqkCAQEwgZChgY2kgYowgYcxHDAaBgkqhkiG9w0BCQEWDW1sb3JjaEB2" + "dC5lZHUxHjAcBgNVBAMTFU1hcmt1cyBMb3JjaCAobWxvcmNoKTEbMBkGA1UECxMS" + "VmlyZ2luaWEgVGVjaCBVc2VyMRAwDgYDVQQLEwdDbGFzcyAyMQswCQYDVQQKEwJ2" + "dDELMAkGA1UEBhMCVVMwgYmkgYYwgYMxGzAZBgkqhkiG9w0BCQEWDHNzaGFoQHZ0" + "LmVkdTEbMBkGA1UEAxMSU3VtaXQgU2hhaCAoc3NoYWgpMRswGQYDVQQLExJWaXJn" + "aW5pYSBUZWNoIFVzZXIxEDAOBgNVBAsTB0NsYXNzIDExCzAJBgNVBAoTAnZ0MQsw" + "CQYDVQQGEwJVUzANBgkqhkiG9w0BAQQFAAIBBTAiGA8yMDAzMDcxODE2MDgwMloY" + "DzIwMDMwNzI1MTYwODAyWjCCBU0wggVJBgorBgEEAbRoCAEBMYIFORaCBTU8UnVs" + "ZSBSdWxlSWQ9IkZpbGUtUHJpdmlsZWdlLVJ1bGUiIEVmZmVjdD0iUGVybWl0Ij4K" + "IDxUYXJnZXQ+CiAgPFN1YmplY3RzPgogICA8U3ViamVjdD4KICAgIDxTdWJqZWN0" + "TWF0Y2ggTWF0Y2hJZD0idXJuOm9hc2lzOm5hbWVzOnRjOnhhY21sOjEuMDpmdW5j" + "dGlvbjpzdHJpbmctZXF1YWwiPgogICAgIDxBdHRyaWJ1dGVWYWx1ZSBEYXRhVHlw" + "ZT0iaHR0cDovL3d3dy53My5vcmcvMjAwMS9YTUxTY2hlbWEjc3RyaW5nIj4KICAg" + "ICAgIENOPU1hcmt1cyBMb3JjaDwvQXR0cmlidXRlVmFsdWU+CiAgICAgPFN1Ympl" + "Y3RBdHRyaWJ1dGVEZXNpZ25hdG9yIEF0dHJpYnV0ZUlkPSJ1cm46b2FzaXM6bmFt" + "ZXM6dGM6eGFjbWw6MS4wOnN1YmplY3Q6c3ViamVjdC1pZCIgRGF0YVR5cGU9Imh0" + "dHA6Ly93d3cudzMub3JnLzIwMDEvWE1MU2NoZW1hI3N0cmluZyIgLz4gCiAgICA8" + "L1N1YmplY3RNYXRjaD4KICAgPC9TdWJqZWN0PgogIDwvU3ViamVjdHM+CiAgPFJl" + "c291cmNlcz4KICAgPFJlc291cmNlPgogICAgPFJlc291cmNlTWF0Y2ggTWF0Y2hJ" + "ZD0idXJuOm9hc2lzOm5hbWVzOnRjOnhhY21sOjEuMDpmdW5jdGlvbjpzdHJpbmct" + "ZXF1YWwiPgogICAgIDxBdHRyaWJ1dGVWYWx1ZSBEYXRhVHlwZT0iaHR0cDovL3d3" + "dy53My5vcmcvMjAwMS9YTUxTY2hlbWEjYW55VVJJIj4KICAgICAgaHR0cDovL3p1" + "bmkuY3MudnQuZWR1PC9BdHRyaWJ1dGVWYWx1ZT4KICAgICA8UmVzb3VyY2VBdHRy" + "aWJ1dGVEZXNpZ25hdG9yIEF0dHJpYnV0ZUlkPSJ1cm46b2FzaXM6bmFtZXM6dGM6" + "eGFjbWw6MS4wOnJlc291cmNlOnJlc291cmNlLWlkIiBEYXRhVHlwZT0iaHR0cDov" + "L3d3dy53My5vcmcvMjAwMS9YTUxTY2hlbWEjYW55VVJJIiAvPiAKICAgIDwvUmVz" + "b3VyY2VNYXRjaD4KICAgPC9SZXNvdXJjZT4KICA8L1Jlc291cmNlcz4KICA8QWN0" + "aW9ucz4KICAgPEFjdGlvbj4KICAgIDxBY3Rpb25NYXRjaCBNYXRjaElkPSJ1cm46" + "b2FzaXM6bmFtZXM6dGM6eGFjbWw6MS4wOmZ1bmN0aW9uOnN0cmluZy1lcXVhbCI+" + "CiAgICAgPEF0dHJpYnV0ZVZhbHVlIERhdGFUeXBlPSJodHRwOi8vd3d3LnczLm9y" + "Zy8yMDAxL1hNTFNjaGVtYSNzdHJpbmciPgpEZWxlZ2F0ZSBBY2Nlc3MgICAgIDwv" + "QXR0cmlidXRlVmFsdWU+CgkgIDxBY3Rpb25BdHRyaWJ1dGVEZXNpZ25hdG9yIEF0" + "dHJpYnV0ZUlkPSJ1cm46b2FzaXM6bmFtZXM6dGM6eGFjbWw6MS4wOmFjdGlvbjph" + "Y3Rpb24taWQiIERhdGFUeXBlPSJodHRwOi8vd3d3LnczLm9yZy8yMDAxL1hNTFNj" + "aGVtYSNzdHJpbmciIC8+IAogICAgPC9BY3Rpb25NYXRjaD4KICAgPC9BY3Rpb24+" + "CiAgPC9BY3Rpb25zPgogPC9UYXJnZXQ+CjwvUnVsZT4KMA0GCSqGSIb3DQEBBAUA" + "A4GBAGiJSM48XsY90HlYxGmGVSmNR6ZW2As+bot3KAfiCIkUIOAqhcphBS23egTr" + "6asYwy151HshbPNYz+Cgeqs45KkVzh7bL/0e1r8sDVIaaGIkjHK3CqBABnfSayr3" + "Rd1yBoDdEv8Qb+3eEPH6ab9021AsLEnJ6LWTmybbOpMNZ3tv"); public void performTest() throws Exception { X509StreamParser parser = X509StreamParser.getInstance("Certificate", "BC"); parser.init(new ByteArrayInputStream(CertPathTest.rootCertBin)); X509Certificate rootCert = (X509Certificate)parser.read(); parser = X509StreamParser.getInstance("CRL", "BC"); parser.init(new ByteArrayInputStream(CertPathTest.rootCrlBin)); X509CRL rootCrl = (X509CRL)parser.read(); parser = X509StreamParser.getInstance("AttributeCertificate", "BC"); parser.init(new ByteArrayInputStream(attrCert)); X509AttributeCertificate aCert = (X509AttributeCertificate)parser.read(); ByteArrayOutputStream bOut = new ByteArrayOutputStream(); bOut.write(CertPathTest.rootCertBin); bOut.write(CertPathTest.interCertBin); bOut.write(CertPathTest.finalCertBin); parser = X509StreamParser.getInstance("Certificate", "BC"); parser.init(bOut.toByteArray()); Collection res = parser.readAll(); if (res.size() != 3) { fail("wrong number of certificates found"); } bOut = new ByteArrayOutputStream(); bOut.write(CertPathTest.rootCrlBin); bOut.write(CertPathTest.interCrlBin); parser = X509StreamParser.getInstance("CRL", "BC"); parser.init(bOut.toByteArray()); res = parser.readAll(); if (res.size() != 2) { fail("wrong number of CRLs found"); } bOut = new ByteArrayOutputStream(); bOut.write(attrCert); bOut.write(attrCert); parser = X509StreamParser.getInstance("AttributeCertificate", "BC"); parser.init(bOut.toByteArray()); res = parser.readAll(); if (res.size() != 2) { fail("wrong number of Attribute Certificates found"); } // // PEM tests // parser = X509StreamParser.getInstance("Certificate", "BC"); parser.init(PEMData.CERTIFICATE_1.getBytes("US-ASCII")); res = parser.readAll(); if (res.size() != 1) { fail("wrong number of Certificates found"); } parser = X509StreamParser.getInstance("Certificate", "BC"); parser.init(PEMData.CERTIFICATE_2.getBytes("US-ASCII")); res = parser.readAll(); if (res.size() != 1) { fail("wrong number of Certificates found"); } parser = X509StreamParser.getInstance("CRL", "BC"); parser.init(PEMData.CRL_1.getBytes("US-ASCII")); res = parser.readAll(); if (res.size() != 1) { fail("wrong number of CRLs found"); } parser = X509StreamParser.getInstance("CRL", "BC"); parser.init(PEMData.CRL_2.getBytes("US-ASCII")); res = parser.readAll(); if (res.size() != 1) { fail("wrong number of CRLs found"); } parser = X509StreamParser.getInstance("AttributeCertificate", "BC"); parser.init(PEMData.ATTRIBUTE_CERTIFICATE_1.getBytes("US-ASCII")); res = parser.readAll(); if (res.size() != 1) { fail("wrong number of Attribute Certificates found"); } parser = X509StreamParser.getInstance("AttributeCertificate", "BC"); parser.init(PEMData.ATTRIBUTE_CERTIFICATE_2.getBytes("US-ASCII")); res = parser.readAll(); if (res.size() != 1) { fail("wrong number of Attribute Certificates found"); } ASN1EncodableVector certs = new ASN1EncodableVector(); certs.add(new ASN1InputStream(CertPathTest.rootCertBin).readObject()); certs.add(new DERTaggedObject(false, 2, new ASN1InputStream(attrCert).readObject())); ASN1EncodableVector crls = new ASN1EncodableVector(); crls.add(new ASN1InputStream(CertPathTest.rootCrlBin).readObject()); // // cross certificate pairs // parser = X509StreamParser.getInstance("CertificatePair", "BC"); parser.init(new X509CertificatePair(rootCert, rootCert).getEncoded()); res = parser.readAll(); if (res.size() != 1) { fail("wrong number of CertificatePairs found"); } // // PKCS7 // SignedData sigData = new SignedData(new DERSet(), new ContentInfo(CMSObjectIdentifiers.data, null), new DERSet(certs), new DERSet(crls), new DERSet()); ContentInfo info = new ContentInfo(CMSObjectIdentifiers.signedData, sigData); parser = X509StreamParser.getInstance("Certificate", "BC"); parser.init(info.getEncoded()); res = parser.readAll(); if (res.size() != 1) { fail("wrong number of Certificates found"); } parser = X509StreamParser.getInstance("CRL", "BC"); parser.init(info.getEncoded()); res = parser.readAll(); if (res.size() != 1) { fail("wrong number of CRLs found"); } parser = X509StreamParser.getInstance("AttributeCertificate", "BC"); parser.init(info.getEncoded()); res = parser.readAll(); if (res.size() != 1) { fail("wrong number of Attribute Certificates found"); } // data with no certificates or CRLs sigData = new SignedData(new DERSet(), new ContentInfo(CMSObjectIdentifiers.data, null), new DERSet(), new DERSet(), new DERSet()); info = new ContentInfo(CMSObjectIdentifiers.signedData, sigData); parser = X509StreamParser.getInstance("Certificate", "BC"); parser.init(info.getEncoded()); res = parser.readAll(); if (res.size() != 0) { fail("wrong number of Certificates found - expected 0"); } parser = X509StreamParser.getInstance("CRL", "BC"); parser.init(info.getEncoded()); res = parser.readAll(); if (res.size() != 0) { fail("wrong number of CRLs found - expected 0"); } parser = X509StreamParser.getInstance("AttributeCertificate", "BC"); parser.init(info.getEncoded()); res = parser.readAll(); if (res.size() != 0) { fail("wrong number of Attribute Certificates found - expected 0"); } // data with absent certificates and CRLs sigData = new SignedData(new DERSet(), new ContentInfo(CMSObjectIdentifiers.data, null), null, null, new DERSet()); info = new ContentInfo(CMSObjectIdentifiers.signedData, sigData); parser = X509StreamParser.getInstance("Certificate", "BC"); parser.init(info.getEncoded()); res = parser.readAll(); if (res.size() != 0) { fail("wrong number of Certificates found - expected 0"); } parser = X509StreamParser.getInstance("CRL", "BC"); parser.init(info.getEncoded()); res = parser.readAll(); if (res.size() != 0) { fail("wrong number of CRLs found - expected 0"); } parser = X509StreamParser.getInstance("AttributeCertificate", "BC"); parser.init(info.getEncoded()); res = parser.readAll(); if (res.size() != 0) { fail("wrong number of Attribute Certificates found - expected 0"); } } public String getName() { return "X509StreamParser"; } public static void main(String[] args) { Security.addProvider(new BouncyCastleProvider()); runTest(new X509StreamParserTest()); } } bouncycastle-1.49.orig/test/src/org/bouncycastle/jce/provider/test/ElGamalTest.java0000644000175000017500000004072111727760670030061 0ustar ebourgebourgpackage org.bouncycastle.jce.provider.test; import java.io.ByteArrayInputStream; import java.io.ByteArrayOutputStream; import java.io.ObjectInputStream; import java.io.ObjectOutputStream; import java.math.BigInteger; import java.security.AlgorithmParameterGenerator; import java.security.AlgorithmParameters; import java.security.KeyFactory; import java.security.KeyPair; import java.security.KeyPairGenerator; import java.security.SecureRandom; import java.security.Security; import java.security.spec.PKCS8EncodedKeySpec; import java.security.spec.X509EncodedKeySpec; import javax.crypto.Cipher; import javax.crypto.interfaces.DHPrivateKey; import javax.crypto.interfaces.DHPublicKey; import javax.crypto.spec.DHParameterSpec; import org.bouncycastle.jcajce.provider.config.ConfigurableProvider; import org.bouncycastle.jce.interfaces.PKCS12BagAttributeCarrier; import org.bouncycastle.jce.provider.BouncyCastleProvider; import org.bouncycastle.util.encoders.Hex; import org.bouncycastle.util.test.SimpleTest; public class ElGamalTest extends SimpleTest { private BigInteger g512 = new BigInteger("153d5d6172adb43045b68ae8e1de1070b6137005686d29d3d73a7749199681ee5b212c9b96bfdcfa5b20cd5e3fd2044895d609cf9b410b7a0f12ca1cb9a428cc", 16); private BigInteger p512 = new BigInteger("9494fec095f3b85ee286542b3836fc81a5dd0a0349b4c239dd38744d488cf8e31db8bcb7d33b41abb9e5a33cca9144b1cef332c94bf0573bf047a3aca98cdf3b", 16); private BigInteger g768 = new BigInteger("7c240073c1316c621df461b71ebb0cdcc90a6e5527e5e126633d131f87461c4dc4afc60c2cb0f053b6758871489a69613e2a8b4c8acde23954c08c81cbd36132cfd64d69e4ed9f8e51ed6e516297206672d5c0a69135df0a5dcf010d289a9ca1", 16); private BigInteger p768 = new BigInteger("8c9dd223debed1b80103b8b309715be009d48860ed5ae9b9d5d8159508efd802e3ad4501a7f7e1cfec78844489148cd72da24b21eddd01aa624291c48393e277cfc529e37075eccef957f3616f962d15b44aeab4039d01b817fde9eaa12fd73f", 16); private BigInteger g1024 = new BigInteger("1db17639cdf96bc4eabba19454f0b7e5bd4e14862889a725c96eb61048dcd676ceb303d586e30f060dbafd8a571a39c4d823982117da5cc4e0f89c77388b7a08896362429b94a18a327604eb7ff227bffbc83459ade299e57b5f77b50fb045250934938efa145511166e3197373e1b5b1e52de713eb49792bedde722c6717abf", 16); private BigInteger p1024 = new BigInteger("a00e283b3c624e5b2b4d9fbc2653b5185d99499b00fd1bf244c6f0bb817b4d1c451b2958d62a0f8a38caef059fb5ecd25d75ed9af403f5b5bdab97a642902f824e3c13789fed95fa106ddfe0ff4a707c85e2eb77d49e68f2808bcea18ce128b178cd287c6bc00efa9a1ad2a673fe0dceace53166f75b81d6709d5f8af7c66bb7", 16); public String getName() { return "ElGamal"; } private void testGP( int size, int privateValueSize, BigInteger g, BigInteger p) throws Exception { DHParameterSpec elParams = new DHParameterSpec(p, g, privateValueSize); KeyPairGenerator keyGen = KeyPairGenerator.getInstance("ElGamal", "BC"); byte[] in = "This is a test".getBytes(); keyGen.initialize(elParams); KeyPair keyPair = keyGen.generateKeyPair(); SecureRandom rand = new SecureRandom(); checkKeySize(privateValueSize, keyPair); Cipher cipher = Cipher.getInstance("ElGamal", "BC"); cipher.init(Cipher.ENCRYPT_MODE, keyPair.getPublic(), rand); if (cipher.getOutputSize(in.length) != (size / 8) * 2) { fail("getOutputSize wrong on encryption"); } byte[] out = cipher.doFinal(in); cipher.init(Cipher.DECRYPT_MODE, keyPair.getPrivate()); if (cipher.getOutputSize(out.length) != (size / 8) - 1) { fail("getOutputSize wrong on decryption"); } // // No Padding - maximum length // byte[] modBytes = ((DHPublicKey)keyPair.getPublic()).getParams().getP().toByteArray(); byte[] maxInput = new byte[modBytes.length - 1]; maxInput[0] |= 0x7f; cipher.init(Cipher.ENCRYPT_MODE, keyPair.getPublic(), rand); out = cipher.doFinal(maxInput); cipher.init(Cipher.DECRYPT_MODE, keyPair.getPrivate()); out = cipher.doFinal(out); if (!areEqual(out, maxInput)) { fail("NoPadding test failed on decrypt expected " + new String(Hex.encode(maxInput)) + " got " + new String(Hex.encode(out))); } // // encrypt/decrypt // Cipher c1 = Cipher.getInstance("ElGamal", "BC"); Cipher c2 = Cipher.getInstance("ElGamal", "BC"); c1.init(Cipher.ENCRYPT_MODE, keyPair.getPublic(), rand); byte[] out1 = c1.doFinal(in); c2.init(Cipher.DECRYPT_MODE, keyPair.getPrivate()); byte[] out2 = c2.doFinal(out1); if (!areEqual(in, out2)) { fail(size + " encrypt test failed"); } // // encrypt/decrypt with update // int outLen = c1.update(in, 0, 2, out1, 0); outLen += c1.doFinal(in, 2, in.length - 2, out1, outLen); outLen = c2.update(out1, 0, 2, out2, 0); outLen += c2.doFinal(out1, 2, out1.length - 2, out2, outLen); if (!areEqual(in, out2)) { fail(size + " encrypt with update test failed"); } // // public key encoding test // byte[] pubEnc = keyPair.getPublic().getEncoded(); KeyFactory keyFac = KeyFactory.getInstance("ElGamal", "BC"); X509EncodedKeySpec pubX509 = new X509EncodedKeySpec(pubEnc); DHPublicKey pubKey = (DHPublicKey)keyFac.generatePublic(pubX509); DHParameterSpec spec = pubKey.getParams(); if (!spec.getG().equals(elParams.getG()) || !spec.getP().equals(elParams.getP())) { fail(size + " bit public key encoding/decoding test failed on parameters"); } if (!((DHPublicKey)keyPair.getPublic()).getY().equals(pubKey.getY())) { fail(size + " bit public key encoding/decoding test failed on y value"); } // // public key serialisation test // pubKey = (DHPublicKey)serializeDeserialize(keyPair.getPublic()); spec = pubKey.getParams(); if (!spec.getG().equals(elParams.getG()) || !spec.getP().equals(elParams.getP())) { fail(size + " bit public key serialisation test failed on parameters"); } if (!((DHPublicKey)keyPair.getPublic()).getY().equals(pubKey.getY())) { fail(size + " bit public key serialisation test failed on y value"); } if (!keyPair.getPublic().equals(pubKey)) { fail("equals test failed"); } if (keyPair.getPublic().hashCode() != pubKey.hashCode()) { fail("hashCode test failed"); } // // private key encoding test // byte[] privEnc = keyPair.getPrivate().getEncoded(); PKCS8EncodedKeySpec privPKCS8 = new PKCS8EncodedKeySpec(privEnc); DHPrivateKey privKey = (DHPrivateKey)keyFac.generatePrivate(privPKCS8); spec = privKey.getParams(); if (!spec.getG().equals(elParams.getG()) || !spec.getP().equals(elParams.getP())) { fail(size + " bit private key encoding/decoding test failed on parameters"); } if (!((DHPrivateKey)keyPair.getPrivate()).getX().equals(privKey.getX())) { fail(size + " bit private key encoding/decoding test failed on y value"); } // // private key serialisation test // privKey = (DHPrivateKey)serializeDeserialize(keyPair.getPrivate()); spec = privKey.getParams(); if (!spec.getG().equals(elParams.getG()) || !spec.getP().equals(elParams.getP())) { fail(size + " bit private key serialisation test failed on parameters"); } if (!((DHPrivateKey)keyPair.getPrivate()).getX().equals(privKey.getX())) { fail(size + " bit private key serialisation test failed on y value"); } if (!keyPair.getPrivate().equals(privKey)) { fail("equals test failed"); } if (keyPair.getPrivate().hashCode() != privKey.hashCode()) { fail("hashCode test failed"); } if (!(privKey instanceof PKCS12BagAttributeCarrier)) { fail("private key not implementing PKCS12 attribute carrier"); } } private Object serializeDeserialize(Object o) throws Exception { ByteArrayOutputStream bOut = new ByteArrayOutputStream(); ObjectOutputStream oOut = new ObjectOutputStream(bOut); oOut.writeObject(o); oOut.close(); ObjectInputStream oIn = new ObjectInputStream(new ByteArrayInputStream(bOut.toByteArray())); return oIn.readObject(); } private void checkKeySize(int privateValueSize, KeyPair aKeyPair) { if (privateValueSize != 0) { DHPrivateKey key = (DHPrivateKey)aKeyPair.getPrivate(); if (key.getX().bitLength() != privateValueSize) { fail("limited key check failed for key size " + privateValueSize); } } } private void testRandom( int size) throws Exception { AlgorithmParameterGenerator a = AlgorithmParameterGenerator.getInstance("ElGamal", "BC"); a.init(size, new SecureRandom()); AlgorithmParameters params = a.generateParameters(); byte[] encodeParams = params.getEncoded(); AlgorithmParameters a2 = AlgorithmParameters.getInstance("ElGamal", "BC"); a2.init(encodeParams); // a and a2 should be equivalent! byte[] encodeParams_2 = a2.getEncoded(); if (!areEqual(encodeParams, encodeParams_2)) { fail(this.getName() + ": encode/decode parameters failed"); } DHParameterSpec elP = (DHParameterSpec)params.getParameterSpec(DHParameterSpec.class); testGP(size, 0, elP.getG(), elP.getP()); } private void testDefault( int privateValueSize, BigInteger g, BigInteger p) throws Exception { DHParameterSpec elParams = new DHParameterSpec(p, g, privateValueSize); int size = p.bitLength(); new BouncyCastleProvider().setParameter(ConfigurableProvider.DH_DEFAULT_PARAMS, elParams); KeyPairGenerator keyGen = KeyPairGenerator.getInstance("ElGamal", "BC"); byte[] in = "This is a test".getBytes(); keyGen.initialize(p.bitLength()); KeyPair keyPair = keyGen.generateKeyPair(); new BouncyCastleProvider().setParameter(ConfigurableProvider.DH_DEFAULT_PARAMS, elParams); SecureRandom rand = new SecureRandom(); checkKeySize(privateValueSize, keyPair); Cipher cipher = Cipher.getInstance("ElGamal", "BC"); cipher.init(Cipher.ENCRYPT_MODE, keyPair.getPublic(), rand); if (cipher.getOutputSize(in.length) != (size / 8) * 2) { fail("getOutputSize wrong on encryption"); } byte[] out = cipher.doFinal(in); cipher.init(Cipher.DECRYPT_MODE, keyPair.getPrivate()); if (cipher.getOutputSize(out.length) != (size / 8) - 1) { fail("getOutputSize wrong on decryption"); } // // No Padding - maximum length // byte[] modBytes = ((DHPublicKey)keyPair.getPublic()).getParams().getP().toByteArray(); byte[] maxInput = new byte[modBytes.length - 1]; maxInput[0] |= 0x7f; cipher.init(Cipher.ENCRYPT_MODE, keyPair.getPublic(), rand); out = cipher.doFinal(maxInput); cipher.init(Cipher.DECRYPT_MODE, keyPair.getPrivate()); out = cipher.doFinal(out); if (!areEqual(out, maxInput)) { fail("NoPadding test failed on decrypt expected " + new String(Hex.encode(maxInput)) + " got " + new String(Hex.encode(out))); } // // encrypt/decrypt // Cipher c1 = Cipher.getInstance("ElGamal", "BC"); Cipher c2 = Cipher.getInstance("ElGamal", "BC"); c1.init(Cipher.ENCRYPT_MODE, keyPair.getPublic(), rand); byte[] out1 = c1.doFinal(in); c2.init(Cipher.DECRYPT_MODE, keyPair.getPrivate()); byte[] out2 = c2.doFinal(out1); if (!areEqual(in, out2)) { fail(size + " encrypt test failed"); } // // encrypt/decrypt with update // int outLen = c1.update(in, 0, 2, out1, 0); outLen += c1.doFinal(in, 2, in.length - 2, out1, outLen); outLen = c2.update(out1, 0, 2, out2, 0); outLen += c2.doFinal(out1, 2, out1.length - 2, out2, outLen); if (!areEqual(in, out2)) { fail(size + " encrypt with update test failed"); } // // public key encoding test // byte[] pubEnc = keyPair.getPublic().getEncoded(); KeyFactory keyFac = KeyFactory.getInstance("ElGamal", "BC"); X509EncodedKeySpec pubX509 = new X509EncodedKeySpec(pubEnc); DHPublicKey pubKey = (DHPublicKey)keyFac.generatePublic(pubX509); DHParameterSpec spec = pubKey.getParams(); if (!spec.getG().equals(elParams.getG()) || !spec.getP().equals(elParams.getP())) { fail(size + " bit public key encoding/decoding test failed on parameters"); } if (!((DHPublicKey)keyPair.getPublic()).getY().equals(pubKey.getY())) { fail(size + " bit public key encoding/decoding test failed on y value"); } // // public key serialisation test // ByteArrayOutputStream bOut = new ByteArrayOutputStream(); ObjectOutputStream oOut = new ObjectOutputStream(bOut); oOut.writeObject(keyPair.getPublic()); ByteArrayInputStream bIn = new ByteArrayInputStream(bOut.toByteArray()); ObjectInputStream oIn = new ObjectInputStream(bIn); pubKey = (DHPublicKey)oIn.readObject(); spec = pubKey.getParams(); if (!spec.getG().equals(elParams.getG()) || !spec.getP().equals(elParams.getP())) { fail(size + " bit public key serialisation test failed on parameters"); } if (!((DHPublicKey)keyPair.getPublic()).getY().equals(pubKey.getY())) { fail(size + " bit public key serialisation test failed on y value"); } // // private key encoding test // byte[] privEnc = keyPair.getPrivate().getEncoded(); PKCS8EncodedKeySpec privPKCS8 = new PKCS8EncodedKeySpec(privEnc); DHPrivateKey privKey = (DHPrivateKey)keyFac.generatePrivate(privPKCS8); spec = privKey.getParams(); if (!spec.getG().equals(elParams.getG()) || !spec.getP().equals(elParams.getP())) { fail(size + " bit private key encoding/decoding test failed on parameters"); } if (!((DHPrivateKey)keyPair.getPrivate()).getX().equals(privKey.getX())) { fail(size + " bit private key encoding/decoding test failed on y value"); } // // private key serialisation test // bOut = new ByteArrayOutputStream(); oOut = new ObjectOutputStream(bOut); oOut.writeObject(keyPair.getPrivate()); bIn = new ByteArrayInputStream(bOut.toByteArray()); oIn = new ObjectInputStream(bIn); privKey = (DHPrivateKey)oIn.readObject(); spec = privKey.getParams(); if (!spec.getG().equals(elParams.getG()) || !spec.getP().equals(elParams.getP())) { fail(size + " bit private key serialisation test failed on parameters"); } if (!((DHPrivateKey)keyPair.getPrivate()).getX().equals(privKey.getX())) { fail(size + " bit private key serialisation test failed on y value"); } } public void performTest() throws Exception { testDefault(64, g512, p512); testGP(512, 0, g512, p512); testGP(768, 0, g768, p768); testGP(1024, 0, g1024, p1024); testGP(512, 64, g512, p512); testGP(768, 128, g768, p768); testGP(1024, 256, g1024, p1024); testRandom(256); } public static void main( String[] args) { Security.addProvider(new BouncyCastleProvider()); runTest(new ElGamalTest()); } } bouncycastle-1.49.orig/test/src/org/bouncycastle/jce/provider/test/ECEncodingTest.java0000644000175000017500000002265411634012123030476 0ustar ebourgebourgpackage org.bouncycastle.jce.provider.test; import java.io.ByteArrayInputStream; import java.math.BigInteger; import java.security.InvalidKeyException; import java.security.KeyPair; import java.security.KeyPairGenerator; import java.security.KeyStore; import java.security.PrivateKey; import java.security.PublicKey; import java.security.Security; import java.security.SignatureException; import java.security.cert.Certificate; import java.security.cert.X509Certificate; import java.util.Date; import org.bouncycastle.asn1.ASN1InputStream; import org.bouncycastle.asn1.x9.X9ECParameters; import org.bouncycastle.jce.X509Principal; import org.bouncycastle.jce.interfaces.ECPointEncoder; import org.bouncycastle.jce.interfaces.ECPrivateKey; import org.bouncycastle.jce.interfaces.ECPublicKey; import org.bouncycastle.jce.provider.BouncyCastleProvider; import org.bouncycastle.jce.spec.ECParameterSpec; import org.bouncycastle.math.ec.ECCurve; import org.bouncycastle.util.encoders.Hex; import org.bouncycastle.util.test.SimpleTest; import org.bouncycastle.x509.X509V3CertificateGenerator; public class ECEncodingTest extends SimpleTest { public String getName() { return "ECEncodingTest"; } /** J.4.7 An Example with m = 304 */ private int m = 304; /** f = 010000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000807 */ private int k1 = 1; private int k2 = 2; private int k3 = 11; private byte hexa[] = {(byte)0xFD, 0x0D, 0x69, 0x31, 0x49, (byte)0xA1, 0x18, (byte)0xF6, 0x51 , (byte)0xE6, (byte)0xDC, (byte)0xE6, (byte)0x80, 0x20, (byte)0x85, 0x37, 0x7E, 0x5F, (byte)0x88, 0x2D, 0x1B, 0x51 , 0x0B, 0x44, 0x16, 0x00, 0x74, (byte)0xC1, 0x28, (byte)0x80, 0x78, 0x36, 0x5A, 0x03 , (byte)0x96, (byte)0xC8, (byte)0xE6, (byte)0x81}; private byte hexb[] = {(byte)0xBD, (byte)0xDB, (byte)0x97, (byte)0xE5, (byte)0x55 , (byte)0xA5, (byte)0x0A, (byte)0x90, (byte)0x8E, (byte)0x43, (byte)0xB0 , (byte)0x1C, (byte)0x79, (byte)0x8E, (byte)0xA5, (byte)0xDA, (byte)0xA6 , (byte)0x78, (byte)0x8F, (byte)0x1E, (byte)0xA2, (byte)0x79 , (byte)0x4E, (byte)0xFC, (byte)0xF5, (byte)0x71, (byte)0x66, (byte)0xB8 , (byte)0xC1, (byte)0x40, (byte)0x39, (byte)0x60, (byte)0x1E , (byte)0x55, (byte)0x82, (byte)0x73, (byte)0x40, (byte)0xBE}; private BigInteger a = new BigInteger(1, hexa); private BigInteger b = new BigInteger(1, hexb); /** Base point G (with point compression) */ private byte enc[] = {0x02, 0x19, 0x7B, 0x07, (byte)0x84, 0x5E, (byte)0x9B, (byte)0xE2, (byte)0xD9, 0x6A, (byte)0xDB, 0x0F , 0x5F, 0x3C, 0x7F, 0x2C, (byte)0xFF, (byte)0xBD, 0x7A, 0x3E, (byte)0xB8, (byte)0xB6, (byte)0xFE, (byte)0xC3, 0x5C, 0x7F, (byte)0xD6, 0x7F, 0x26, (byte)0xDD, (byte)0xF6 , 0x28, 0x5A, 0x64, 0x4F, 0x74, 0x0A, 0x26, 0x14}; private void testPointCompression() throws Exception { ECCurve curve = new ECCurve.F2m(m, k1, k2, k3, a, b); curve.decodePoint(enc); int ks[] = new int[3]; ks[0] = k3; ks[1] = k2; ks[2] = k1; } public void performTest() throws Exception { byte[] ecParams = Hex.decode("3081C8020101302806072A8648CE3D0101021D00D7C134AA264366862A18302575D1D787B09F075797DA89F57EC8C0FF303C041C68A5E62CA9CE6C1C299803A6C1530B514E182AD8B0042A59CAD29F43041C2580F63CCFE44138870713B1A92369E33E2135D266DBB372386C400B0439040D9029AD2C7E5CF4340823B2A87DC68C9E4CE3174C1E6EFDEE12C07D58AA56F772C0726F24C6B89E4ECDAC24354B9E99CAA3F6D3761402CD021D00D7C134AA264366862A18302575D0FB98D116BC4B6DDEBCA3A5A7939F020101"); testParams(ecParams, true); testParams(ecParams, false); ecParams = Hex.decode("3081C8020101302806072A8648CE3D0101021D00D7C134AA264366862A18302575D1D787B09F075797DA89F57EC8C0FF303C041C56E6C7E4F11A7B4B961A4DCB5BD282EB22E42E9BCBE3E7B361F18012041C4BE3E7B361F18012F2353D22975E02D8D05D2C6F3342DD8F57D4C76F0439048D127A0C27E0DE207ED3B7FB98F83C8BD5A2A57C827F4B97874DEB2C1BAEB0C006958CE61BB1FC81F5389E288CB3E86E2ED91FB47B08FCCA021D00D7C134AA264366862A18302575D11A5F7AABFBA3D897FF5CA727AF53020101"); testParams(ecParams, true); testParams(ecParams, false); ecParams = Hex.decode("30820142020101303c06072a8648ce3d0101023100fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffeffffffff0000000000000000ffffffff3066043100fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffeffffffff0000000000000000fffffffc043100b3312fa7e23ee7e4988e056be3f82d19181d9c6efe8141120314088f5013875ac656398d8a2ed19d2a85c8edd3ec2aef046104aa87ca22be8b05378eb1c71ef320ad746e1d3b628ba79b9859f741e082542a385502f25dbf55296c3a545e3872760ab73617de4a96262c6f5d9e98bf9292dc29f8f41dbd289a147ce9da3113b5f0b8c00a60b1ce1d7e819d7a431d7c90ea0e5f023100ffffffffffffffffffffffffffffffffffffffffffffffffc7634d81f4372ddf581a0db248b0a77aecec196accc52973020101"); testParams(ecParams, true); testParams(ecParams, false); testPointCompression(); } private void testParams(byte[] ecParameterEncoded, boolean compress) throws Exception { String keyStorePass = "myPass"; ASN1InputStream in = new ASN1InputStream(new ByteArrayInputStream( ecParameterEncoded)); X9ECParameters params = X9ECParameters.getInstance(in .readObject()); KeyPair kp = null; boolean success = false; while (!success) { KeyPairGenerator kpg = KeyPairGenerator.getInstance("ECDSA"); kpg.initialize(new ECParameterSpec(params.getCurve(), params.getG(), params.getN(), params.getH(), params .getSeed())); kp = kpg.generateKeyPair(); // The very old Problem... we need a certificate chain to // save a private key... ECPublicKey pubKey = (ECPublicKey)kp.getPublic(); if (!compress) { ((ECPointEncoder)pubKey).setPointFormat("UNCOMPRESSED"); } byte[] x = pubKey.getQ().getX().toBigInteger().toByteArray(); byte[] y = pubKey.getQ().getY().toBigInteger().toByteArray(); if (x.length == y.length) { success = true; } } // The very old Problem... we need a certificate chain to // save a private key... Certificate[] chain = new Certificate[] { generateSelfSignedSoftECCert( kp, compress) }; KeyStore keyStore = KeyStore.getInstance("BKS"); keyStore.load(null, keyStorePass.toCharArray()); keyStore.setCertificateEntry("ECCert", chain[0]); ECPrivateKey privateECKey = (ECPrivateKey)kp.getPrivate(); keyStore.setKeyEntry("ECPrivKey", privateECKey, keyStorePass .toCharArray(), chain); // Test ec sign / verify ECPublicKey pub = (ECPublicKey)kp.getPublic(); String oldPrivateKey = new String(Hex.encode(privateECKey.getEncoded())); String oldPublicKey = new String(Hex.encode(pub.getEncoded())); ECPrivateKey newKey = (ECPrivateKey)keyStore.getKey("ECPrivKey", keyStorePass.toCharArray()); ECPublicKey newPubKey = (ECPublicKey)keyStore.getCertificate( "ECCert").getPublicKey(); if (!compress) { ((ECPointEncoder)newKey).setPointFormat("UNCOMPRESSED"); ((ECPointEncoder)newPubKey).setPointFormat("UNCOMPRESSED"); } String newPrivateKey = new String(Hex.encode(newKey.getEncoded())); String newPublicKey = new String(Hex.encode(newPubKey.getEncoded())); if (!oldPrivateKey.equals(newPrivateKey)) { fail("failed private key comparison"); } if (!oldPublicKey.equals(newPublicKey)) { fail("failed public key comparison"); } } /** * Create a self signed cert for our software emulation * * @param kp * is the keypair for our certificate * @return a self signed cert for our software emulation * @throws InvalidKeyException * on error * @throws SignatureException * on error */ private X509Certificate generateSelfSignedSoftECCert(KeyPair kp, boolean compress) throws Exception { X509V3CertificateGenerator certGen = new X509V3CertificateGenerator(); ECPrivateKey privECKey = (ECPrivateKey)kp.getPrivate(); ECPublicKey pubECKey = (ECPublicKey)kp.getPublic(); if (!compress) { ((ECPointEncoder)privECKey).setPointFormat("UNCOMPRESSED"); ((ECPointEncoder)pubECKey).setPointFormat("UNCOMPRESSED"); } certGen.setSignatureAlgorithm("ECDSAwithSHA1"); certGen.setSerialNumber(BigInteger.valueOf(1)); certGen.setIssuerDN(new X509Principal("CN=Software emul (EC Cert)")); certGen.setNotBefore(new Date(System.currentTimeMillis() - 50000)); certGen.setNotAfter(new Date(System.currentTimeMillis() + 50000000)); certGen.setSubjectDN(new X509Principal("CN=Software emul (EC Cert)")); certGen.setPublicKey((PublicKey)pubECKey); return certGen.generate((PrivateKey)privECKey); } public static void main( String[] args) { Security.addProvider(new BouncyCastleProvider()); runTest(new ECEncodingTest()); } } bouncycastle-1.49.orig/test/src/org/bouncycastle/jce/provider/test/SipHashTest.java0000644000175000017500000000425312123725215030101 0ustar ebourgebourgpackage org.bouncycastle.jce.provider.test; import java.security.Security; import javax.crypto.Mac; import javax.crypto.spec.SecretKeySpec; import org.bouncycastle.jce.provider.BouncyCastleProvider; import org.bouncycastle.util.Arrays; import org.bouncycastle.util.encoders.Hex; import org.bouncycastle.util.test.SimpleTest; public class SipHashTest extends SimpleTest { public void performTest() throws Exception { byte[] key = Hex.decode("000102030405060708090a0b0c0d0e0f"); byte[] input = Hex.decode("000102030405060708090a0b0c0d0e"); byte[] expected = Hex.decode("e545be4961ca29a1"); Mac mac = Mac.getInstance("SipHash", "BC"); mac.init(new SecretKeySpec(key, "SipHash")); mac.update(input, 0, input.length); byte[] result = mac.doFinal(); if (!Arrays.areEqual(expected, result)) { fail("Result does not match expected value for doFinal()"); } mac.init(new SecretKeySpec(key, "SipHash-2-4")); mac.update(input, 0, input.length); result = mac.doFinal(); if (!Arrays.areEqual(expected, result)) { fail("Result does not match expected value for second doFinal()"); } mac = Mac.getInstance("SipHash-2-4", "BC"); mac.init(new SecretKeySpec(key, "SipHash-2-4")); mac.update(input, 0, input.length); result = mac.doFinal(); if (!Arrays.areEqual(expected, result)) { fail("Result does not match expected value for alias"); } // SipHash 4-8 expected = Hex.decode("e0a6a97dd589d383"); mac = Mac.getInstance("SipHash-4-8", "BC"); mac.init(new SecretKeySpec(key, "SipHash")); mac.update(input, 0, input.length); result = mac.doFinal(); if (!Arrays.areEqual(expected, result)) { fail("Result does not match expected value for SipHash 4-8"); } } public String getName() { return "SipHash"; } public static void main( String[] args) { Security.addProvider(new BouncyCastleProvider()); runTest(new SipHashTest()); } } bouncycastle-1.49.orig/test/src/org/bouncycastle/jce/provider/test/TestUtils.java0000644000175000017500000002236411725030156027645 0ustar ebourgebourgpackage org.bouncycastle.jce.provider.test; import java.math.BigInteger; import java.security.InvalidKeyException; import java.security.KeyPair; import java.security.KeyPairGenerator; import java.security.NoSuchAlgorithmException; import java.security.NoSuchProviderException; import java.security.Principal; import java.security.PrivateKey; import java.security.PublicKey; import java.security.SecureRandom; import java.security.SignatureException; import java.security.cert.CertificateEncodingException; import java.security.cert.CertificateException; import java.security.cert.CertificateExpiredException; import java.security.cert.CertificateNotYetValidException; import java.security.cert.X509CRL; import java.security.cert.X509Certificate; import java.util.Date; import java.util.Set; import org.bouncycastle.asn1.x509.BasicConstraints; import org.bouncycastle.asn1.x509.CRLNumber; import org.bouncycastle.asn1.x509.CRLReason; import org.bouncycastle.asn1.x509.KeyUsage; import org.bouncycastle.asn1.x509.X509Extensions; import org.bouncycastle.jce.PrincipalUtil; import org.bouncycastle.jce.X509Principal; import org.bouncycastle.x509.X509V1CertificateGenerator; import org.bouncycastle.x509.X509V2CRLGenerator; import org.bouncycastle.x509.X509V3CertificateGenerator; import org.bouncycastle.x509.extension.AuthorityKeyIdentifierStructure; import org.bouncycastle.x509.extension.SubjectKeyIdentifierStructure; /** * Test Utils */ class TestUtils { /** * Create a random 1024 bit RSA key pair */ public static KeyPair generateRSAKeyPair() throws Exception { KeyPairGenerator kpGen = KeyPairGenerator.getInstance("RSA", "BC"); kpGen.initialize(1024, new SecureRandom()); return kpGen.generateKeyPair(); } public static X509Certificate generateRootCert(KeyPair pair) throws Exception { X509V1CertificateGenerator certGen = new X509V1CertificateGenerator(); certGen.setSerialNumber(BigInteger.valueOf(1)); certGen.setIssuerDN(new X509Principal("CN=Test CA Certificate")); certGen.setNotBefore(new Date(System.currentTimeMillis() - 50000)); certGen.setNotAfter(new Date(System.currentTimeMillis() + 50000)); certGen.setSubjectDN(new X509Principal("CN=Test CA Certificate")); certGen.setPublicKey(pair.getPublic()); certGen.setSignatureAlgorithm("SHA256WithRSAEncryption"); return certGen.generate(pair.getPrivate(), "BC"); } public static X509Certificate generateIntermediateCert(PublicKey intKey, PrivateKey caKey, X509Certificate caCert) throws Exception { X509V3CertificateGenerator certGen = new X509V3CertificateGenerator(); certGen.setSerialNumber(BigInteger.valueOf(1)); certGen.setIssuerDN(PrincipalUtil.getSubjectX509Principal(caCert)); certGen.setNotBefore(new Date(System.currentTimeMillis() - 50000)); certGen.setNotAfter(new Date(System.currentTimeMillis() + 50000)); certGen.setSubjectDN(new X509Principal("CN=Test Intermediate Certificate")); certGen.setPublicKey(intKey); certGen.setSignatureAlgorithm("SHA256WithRSAEncryption"); certGen.addExtension(X509Extensions.AuthorityKeyIdentifier, false, new AuthorityKeyIdentifierStructure(caCert)); certGen.addExtension(X509Extensions.SubjectKeyIdentifier, false, new SubjectKeyIdentifierStructure(intKey)); certGen.addExtension(X509Extensions.BasicConstraints, true, new BasicConstraints(0)); certGen.addExtension(X509Extensions.KeyUsage, true, new KeyUsage(KeyUsage.digitalSignature | KeyUsage.keyCertSign | KeyUsage.cRLSign)); return certGen.generate(caKey, "BC"); } public static X509Certificate generateEndEntityCert(PublicKey entityKey, PrivateKey caKey, X509Certificate caCert) throws Exception { X509V3CertificateGenerator certGen = new X509V3CertificateGenerator(); certGen.setSerialNumber(BigInteger.valueOf(1)); certGen.setIssuerDN(PrincipalUtil.getSubjectX509Principal(caCert)); certGen.setNotBefore(new Date(System.currentTimeMillis() - 50000)); certGen.setNotAfter(new Date(System.currentTimeMillis() + 50000)); certGen.setSubjectDN(new X509Principal("CN=Test End Certificate")); certGen.setPublicKey(entityKey); certGen.setSignatureAlgorithm("SHA256WithRSAEncryption"); certGen.addExtension(X509Extensions.AuthorityKeyIdentifier, false, new AuthorityKeyIdentifierStructure(caCert)); certGen.addExtension(X509Extensions.SubjectKeyIdentifier, false, new SubjectKeyIdentifierStructure(entityKey)); certGen.addExtension(X509Extensions.BasicConstraints, true, new BasicConstraints(false)); certGen.addExtension(X509Extensions.KeyUsage, true, new KeyUsage(KeyUsage.digitalSignature | KeyUsage.keyEncipherment)); return certGen.generate(caKey, "BC"); } public static X509CRL createCRL( X509Certificate caCert, PrivateKey caKey, BigInteger serialNumber) throws Exception { X509V2CRLGenerator crlGen = new X509V2CRLGenerator(); Date now = new Date(); BigInteger revokedSerialNumber = BigInteger.valueOf(2); crlGen.setIssuerDN(PrincipalUtil.getSubjectX509Principal(caCert)); crlGen.setThisUpdate(now); crlGen.setNextUpdate(new Date(now.getTime() + 100000)); crlGen.setSignatureAlgorithm("SHA256WithRSAEncryption"); crlGen.addCRLEntry(serialNumber, now, CRLReason.privilegeWithdrawn); crlGen.addExtension(X509Extensions.AuthorityKeyIdentifier, false, new AuthorityKeyIdentifierStructure(caCert)); crlGen.addExtension(X509Extensions.CRLNumber, false, new CRLNumber(BigInteger.valueOf(1))); return crlGen.generate(caKey, "BC"); } public static X509Certificate createExceptionCertificate(boolean exceptionOnEncode) { return new ExceptionCertificate(exceptionOnEncode); } private static class ExceptionCertificate extends X509Certificate { private boolean _exceptionOnEncode; public ExceptionCertificate(boolean exceptionOnEncode) { _exceptionOnEncode = exceptionOnEncode; } public void checkValidity() throws CertificateExpiredException, CertificateNotYetValidException { throw new CertificateNotYetValidException(); } public void checkValidity(Date date) throws CertificateExpiredException, CertificateNotYetValidException { throw new CertificateExpiredException(); } public int getVersion() { return 0; } public BigInteger getSerialNumber() { return null; } public Principal getIssuerDN() { return null; } public Principal getSubjectDN() { return null; } public Date getNotBefore() { return null; } public Date getNotAfter() { return null; } public byte[] getTBSCertificate() throws CertificateEncodingException { throw new CertificateEncodingException(); } public byte[] getSignature() { return new byte[0]; } public String getSigAlgName() { return null; } public String getSigAlgOID() { return null; } public byte[] getSigAlgParams() { return new byte[0]; } public boolean[] getIssuerUniqueID() { return new boolean[0]; } public boolean[] getSubjectUniqueID() { return new boolean[0]; } public boolean[] getKeyUsage() { return new boolean[0]; } public int getBasicConstraints() { return 0; } public byte[] getEncoded() throws CertificateEncodingException { if (_exceptionOnEncode) { throw new CertificateEncodingException(); } return new byte[0]; } public void verify(PublicKey key) throws CertificateException, NoSuchAlgorithmException, InvalidKeyException, NoSuchProviderException, SignatureException { throw new CertificateException(); } public void verify(PublicKey key, String sigProvider) throws CertificateException, NoSuchAlgorithmException, InvalidKeyException, NoSuchProviderException, SignatureException { throw new CertificateException(); } public String toString() { return null; } public PublicKey getPublicKey() { return null; } public boolean hasUnsupportedCriticalExtension() { return false; } public Set getCriticalExtensionOIDs() { return null; } public Set getNonCriticalExtensionOIDs() { return null; } public byte[] getExtensionValue(String oid) { return new byte[0]; } } } bouncycastle-1.49.orig/test/src/org/bouncycastle/jce/provider/test/CipherStreamTest.java0000644000175000017500000002455511165251312031134 0ustar ebourgebourgpackage org.bouncycastle.jce.provider.test; import org.bouncycastle.jce.provider.BouncyCastleProvider; import org.bouncycastle.util.encoders.Hex; import org.bouncycastle.util.test.SimpleTest; import javax.crypto.Cipher; import javax.crypto.CipherInputStream; import javax.crypto.CipherOutputStream; import javax.crypto.KeyGenerator; import javax.crypto.SecretKey; import javax.crypto.ShortBufferException; import javax.crypto.spec.IvParameterSpec; import javax.crypto.spec.SecretKeySpec; import java.io.ByteArrayInputStream; import java.io.ByteArrayOutputStream; import java.security.InvalidKeyException; import java.security.Key; import java.security.PrivateKey; import java.security.PublicKey; import java.security.Security; /** * check that cipher input/output streams are working correctly */ public class CipherStreamTest extends SimpleTest { private static byte[] RK = Hex.decode("0123456789ABCDEF"); private static byte[] RIN = Hex.decode("4e6f772069732074"); private static byte[] ROUT = Hex.decode("3afbb5c77938280d"); private static byte[] SIN = Hex.decode( "00000000000000000000000000000000" + "00000000000000000000000000000000" + "00000000000000000000000000000000" + "00000000000000000000000000000000"); private static final byte[] SK = Hex.decode("80000000000000000000000000000000"); private static final byte[] SIV = Hex.decode("0000000000000000"); private static final byte[] SOUT = Hex.decode( "4DFA5E481DA23EA09A31022050859936" + "DA52FCEE218005164F267CB65F5CFD7F" + "2B4F97E0FF16924A52DF269515110A07" + "F9E460BC65EF95DA58F740B7D1DBB0AA"); private static final byte[] HCIN = new byte[64]; private static final byte[] HCIV = new byte[32]; private static final byte[] HCK256A = new byte[32]; private static final byte[] HC256A = Hex.decode( "5B078985D8F6F30D42C5C02FA6B67951" + "53F06534801F89F24E74248B720B4818" + "CD9227ECEBCF4DBF8DBF6977E4AE14FA" + "E8504C7BC8A9F3EA6C0106F5327E6981"); private static final byte[] HCK128A = new byte[16]; private static final byte[] HC128A = Hex.decode( "82001573A003FD3B7FD72FFB0EAF63AA" + "C62F12DEB629DCA72785A66268EC758B" + "1EDB36900560898178E0AD009ABF1F49" + "1330DC1C246E3D6CB264F6900271D59C"); private static final byte[] GRAIN_V1 = Hex.decode("0123456789abcdef1234"); private static final byte[] GRAIN_V1_IV = Hex.decode("0123456789abcdef"); private static final byte[] GRAIN_V1_IN = new byte[10]; private static final byte[] GRAIN_V1_OUT = Hex.decode("7f362bd3f7abae203664"); private static final byte[] GRAIN_128 = Hex.decode("0123456789abcdef123456789abcdef0"); private static final byte[] GRAIN_128_IV = Hex.decode("0123456789abcdef12345678"); private static final byte[] GRAIN_128_IN = new byte[16]; private static final byte[] GRAIN_128_OUT = Hex.decode("afb5babfa8de896b4b9c6acaf7c4fbfd"); public CipherStreamTest() { } private void runTest( String name) throws Exception { String lCode = "ABCDEFGHIJKLMNOPQRSTUVWXY0123456789"; KeyGenerator kGen; if (name.indexOf('/') < 0) { kGen = KeyGenerator.getInstance(name, "BC"); } else { kGen = KeyGenerator.getInstance(name.substring(0, name.indexOf('/')), "BC"); } Cipher in = Cipher.getInstance(name, "BC"); Cipher out = Cipher.getInstance(name, "BC"); Key key = kGen.generateKey(); ByteArrayInputStream bIn = new ByteArrayInputStream(lCode.getBytes()); ByteArrayOutputStream bOut = new ByteArrayOutputStream(); in.init(Cipher.ENCRYPT_MODE, key); if (in.getIV() != null) { out.init(Cipher.DECRYPT_MODE, key, new IvParameterSpec(in.getIV())); } else { out.init(Cipher.DECRYPT_MODE, key); } CipherInputStream cIn = new CipherInputStream(bIn, in); CipherOutputStream cOut = new CipherOutputStream(bOut, out); int c; while ((c = cIn.read()) >= 0) { cOut.write(c); } cIn.close(); cOut.flush(); cOut.close(); String res = new String(bOut.toByteArray()); if (!res.equals(lCode)) { fail("Failed - decrypted data doesn't match."); } } private void testAlgorithm(String name, byte[] keyBytes, byte[] iv, byte[] plainText, byte[] cipherText) throws Exception { SecretKey key = new SecretKeySpec(keyBytes, name); Cipher in = Cipher.getInstance(name, "BC"); Cipher out = Cipher.getInstance(name, "BC"); if (iv != null) { in.init(Cipher.ENCRYPT_MODE, key, new IvParameterSpec(iv)); out.init(Cipher.DECRYPT_MODE, key, new IvParameterSpec(iv)); } else { in.init(Cipher.ENCRYPT_MODE, key); out.init(Cipher.DECRYPT_MODE, key); } byte[] enc = in.doFinal(plainText); if (!areEqual(enc, cipherText)) { fail(name + ": cipher text doesn't match"); } byte[] dec = out.doFinal(enc); if (!areEqual(dec, plainText)) { fail(name + ": plain text doesn't match"); } } private void testException( String name) { try { byte[] key128 = { (byte)128, (byte)131, (byte)133, (byte)134, (byte)137, (byte)138, (byte)140, (byte)143, (byte)128, (byte)131, (byte)133, (byte)134, (byte)137, (byte)138, (byte)140, (byte)143 }; byte[] key256 = { (byte)128, (byte)131, (byte)133, (byte)134, (byte)137, (byte)138, (byte)140, (byte)143, (byte)128, (byte)131, (byte)133, (byte)134, (byte)137, (byte)138, (byte)140, (byte)143, (byte)128, (byte)131, (byte)133, (byte)134, (byte)137, (byte)138, (byte)140, (byte)143, (byte)128, (byte)131, (byte)133, (byte)134, (byte)137, (byte)138, (byte)140, (byte)143 }; byte[] keyBytes; if (name.equals("HC256")) { keyBytes = key256; } else { keyBytes = key128; } SecretKeySpec cipherKey = new SecretKeySpec(keyBytes, name); Cipher ecipher = Cipher.getInstance(name, "BC"); ecipher.init(Cipher.ENCRYPT_MODE, cipherKey); byte[] cipherText = new byte[0]; try { // According specification Method engineUpdate(byte[] input, // int inputOffset, int inputLen, byte[] output, int // outputOffset) // throws ShortBufferException - if the given output buffer is // too // small to hold the result ecipher.update(new byte[20], 0, 20, cipherText); fail("failed exception test - no ShortBufferException thrown"); } catch (ShortBufferException e) { // ignore } try { Cipher c = Cipher.getInstance(name, "BC"); Key k = new PublicKey() { public String getAlgorithm() { return "STUB"; } public String getFormat() { return null; } public byte[] getEncoded() { return null; } }; c.init(Cipher.ENCRYPT_MODE, k); fail("failed exception test - no InvalidKeyException thrown for public key"); } catch (InvalidKeyException e) { // okay } try { Cipher c = Cipher.getInstance(name, "BC"); Key k = new PrivateKey() { public String getAlgorithm() { return "STUB"; } public String getFormat() { return null; } public byte[] getEncoded() { return null; } }; c.init(Cipher.DECRYPT_MODE, k); fail("failed exception test - no InvalidKeyException thrown for private key"); } catch (InvalidKeyException e) { // okay } } catch (Exception e) { fail("unexpected exception.", e); } } public void performTest() throws Exception { runTest("RC4"); testException("RC4"); testAlgorithm("RC4", RK, null, RIN, ROUT); runTest("Salsa20"); testException("Salsa20"); testAlgorithm("Salsa20", SK, SIV, SIN, SOUT); runTest("HC128"); testException("HC128"); testAlgorithm("HC128", HCK128A, HCIV, HCIN, HC128A); runTest("HC256"); testException("HC256"); testAlgorithm("HC256", HCK256A, HCIV, HCIN, HC256A); runTest("VMPC"); testException("VMPC"); //testAlgorithm("VMPC", a, iv, in, a); runTest("VMPC-KSA3"); testException("VMPC-KSA3"); //testAlgorithm("VMPC-KSA3", a, iv, in, a); testAlgorithm("Grainv1", GRAIN_V1, GRAIN_V1_IV, GRAIN_V1_IN, GRAIN_V1_OUT); testAlgorithm("Grain128", GRAIN_128, GRAIN_128_IV, GRAIN_128_IN, GRAIN_128_OUT); runTest("DES/ECB/PKCS7Padding"); runTest("DES/CFB8/NoPadding"); } public String getName() { return "CipherStreamTest"; } public static void main( String[] args) { Security.addProvider(new BouncyCastleProvider()); runTest(new CipherStreamTest()); } } bouncycastle-1.49.orig/test/src/org/bouncycastle/jce/provider/test/ECNRTest.java0000644000175000017500000002416612132445646027305 0ustar ebourgebourgpackage org.bouncycastle.jce.provider.test; import java.io.ByteArrayInputStream; import java.io.IOException; import java.math.BigInteger; import java.security.KeyFactory; import java.security.PrivateKey; import java.security.PublicKey; import java.security.SecureRandom; import java.security.Security; import java.security.Signature; import org.bouncycastle.asn1.ASN1InputStream; import org.bouncycastle.asn1.ASN1Sequence; import org.bouncycastle.asn1.DERInteger; import org.bouncycastle.jce.provider.BouncyCastleProvider; import org.bouncycastle.jce.spec.ECParameterSpec; import org.bouncycastle.jce.spec.ECPrivateKeySpec; import org.bouncycastle.jce.spec.ECPublicKeySpec; import org.bouncycastle.math.ec.ECCurve; import org.bouncycastle.util.BigIntegers; import org.bouncycastle.util.encoders.Hex; import org.bouncycastle.util.test.FixedSecureRandom; import org.bouncycastle.util.test.SimpleTest; public class ECNRTest extends SimpleTest { byte[] k1 = Hex.decode("d5014e4b60ef2ba8b6211b4062ba3224e0427dd3"); byte[] k2 = Hex.decode("345e8d05c075c3a508df729a1685690e68fcfb8c8117847e89063bca1f85d968fd281540b6e13bd1af989a1fbf17e06462bf511f9d0b140fb48ac1b1baa5bded"); SecureRandom random = new FixedSecureRandom(new byte[][] { k1, k2 }); /** * X9.62 - 1998,
    * J.3.2, Page 155, ECDSA over the field Fp
    * an example with 239 bit prime */ private void testECNR239bitPrime() throws Exception { BigInteger r = new BigInteger("308636143175167811492623515537541734843573549327605293463169625072911693"); BigInteger s = new BigInteger("852401710738814635664888632022555967400445256405412579597015412971797143"); byte[] kData = BigIntegers.asUnsignedByteArray(new BigInteger("700000017569056646655505781757157107570501575775705779575555657156756655")); SecureRandom k = new FixedSecureRandom(kData); ECCurve curve = new ECCurve.Fp( new BigInteger("883423532389192164791648750360308885314476597252960362792450860609699839"), // q new BigInteger("7fffffffffffffffffffffff7fffffffffff8000000000007ffffffffffc", 16), // a new BigInteger("6b016c3bdcf18941d0d654921475ca71a9db2fb27d1d37796185c2942c0a", 16)); // b ECParameterSpec spec = new ECParameterSpec( curve, curve.decodePoint(Hex.decode("020ffa963cdca8816ccc33b8642bedf905c3d358573d3f27fbbd3b3cb9aaaf")), // G new BigInteger("883423532389192164791648750360308884807550341691627752275345424702807307")); // n ECPrivateKeySpec priKey = new ECPrivateKeySpec( new BigInteger("876300101507107567501066130761671078357010671067781776716671676178726717"), // d spec); ECPublicKeySpec pubKey = new ECPublicKeySpec( curve.decodePoint(Hex.decode("025b6dc53bc61a2548ffb0f671472de6c9521a9d2d2534e65abfcbd5fe0c70")), // Q spec); Signature sgr = Signature.getInstance("SHA1withECNR", "BC"); KeyFactory f = KeyFactory.getInstance("ECDSA", "BC"); byte[] message = new byte[] { (byte)'a', (byte)'b', (byte)'c' }; checkSignature(239, priKey, pubKey, sgr, k, message, r, s); } // ------------------------------------------------------------------------- /** * X9.62 - 1998,
    * Page 104-105, ECDSA over the field Fp
    * an example with 192 bit prime */ private void testECNR192bitPrime() throws Exception { BigInteger r = new BigInteger("2474388605162950674935076940284692598330235697454145648371"); BigInteger s = new BigInteger("2997192822503471356158280167065034437828486078932532073836"); byte[] kData = BigIntegers.asUnsignedByteArray(new BigInteger("dcc5d1f1020906df2782360d36b2de7a17ece37d503784af", 16)); SecureRandom k = new FixedSecureRandom(kData); ECCurve.Fp curve = new ECCurve.Fp( new BigInteger("6277101735386680763835789423207666416083908700390324961279"), // q (or p) new BigInteger("FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEFFFFFFFFFFFFFFFC", 16), // a new BigInteger("64210519E59C80E70FA7E9AB72243049FEB8DEECC146B9B1", 16)); // b ECParameterSpec spec = new ECParameterSpec( curve, curve.decodePoint(Hex.decode("03188DA80EB03090F67CBF20EB43A18800F4FF0AFD82FF1012")), // G new BigInteger("6277101735386680763835789423176059013767194773182842284081")); // n ECPrivateKeySpec priKey = new ECPrivateKeySpec( new BigInteger("651056770906015076056810763456358567190100156695615665659"), // d spec); ECPublicKeySpec pubKey = new ECPublicKeySpec( curve.decodePoint(Hex.decode("0262B12D60690CDCF330BABAB6E69763B471F994DD702D16A5")), // Q spec); Signature sgr = Signature.getInstance("SHA1withECNR", "BC"); KeyFactory f = KeyFactory.getInstance("ECDSA", "BC"); byte[] message = new byte[] { (byte)'a', (byte)'b', (byte)'c' }; checkSignature(192, priKey, pubKey, sgr, k, message, r, s); } // ------------------------------------------------------------------------- /** * SEC 2: Recommended Elliptic Curve Domain Parameters - September 2000,
    * Page 17-19, Recommended 521-bit Elliptic Curve Domain Parameters over Fp
    * an ECC example with a 521 bit prime and a 512 bit hash */ private void testECNR521bitPrime() throws Exception { BigInteger r = new BigInteger("1820641608112320695747745915744708800944302281118541146383656165330049339564439316345159057453301092391897040509935100825960342573871340486684575368150970954"); BigInteger s = new BigInteger("6358277176448326821136601602749690343031826490505780896013143436153111780706227024847359990383467115737705919410755190867632280059161174165591324242446800763"); byte[] kData = BigIntegers.asUnsignedByteArray(new BigInteger("cdef1234567890abcdef1234567890abcdef1234567890abcdef1234567890abcdef1234567890abcdef1234567890abcdef1234567890abcdef1234567890abcdef", 16)); SecureRandom k = new FixedSecureRandom(kData); ECCurve.Fp curve = new ECCurve.Fp( new BigInteger("6864797660130609714981900799081393217269435300143305409394463459185543183397656052122559640661454554977296311391480858037121987999716643812574028291115057151"), // q (or p) new BigInteger("01FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFC", 16), // a new BigInteger("0051953EB9618E1C9A1F929A21A0B68540EEA2DA725B99B315F3B8B489918EF109E156193951EC7E937B1652C0BD3BB1BF073573DF883D2C34F1EF451FD46B503F00", 16)); // b ECParameterSpec spec = new ECParameterSpec( curve, curve.decodePoint(Hex.decode("0200C6858E06B70404E9CD9E3ECB662395B4429C648139053FB521F828AF606B4D3DBAA14B5E77EFE75928FE1DC127A2FFA8DE3348B3C1856A429BF97E7E31C2E5BD66")), // G new BigInteger("01FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFA51868783BF2F966B7FCC0148F709A5D03BB5C9B8899C47AEBB6FB71E91386409", 16)); // n ECPrivateKeySpec priKey = new ECPrivateKeySpec( new BigInteger("5769183828869504557786041598510887460263120754767955773309066354712783118202294874205844512909370791582896372147797293913785865682804434049019366394746072023"), // d spec); ECPublicKeySpec pubKey = new ECPublicKeySpec( curve.decodePoint(Hex.decode("02006BFDD2C9278B63C92D6624F151C9D7A822CC75BD983B17D25D74C26740380022D3D8FAF304781E416175EADF4ED6E2B47142D2454A7AC7801DD803CF44A4D1F0AC")), // Q spec); Signature sgr = Signature.getInstance("SHA512withECNR", "BC"); byte[] message = new byte[] { (byte)'a', (byte)'b', (byte)'c' }; checkSignature(521, priKey, pubKey, sgr, k, message, r, s); } private void checkSignature( int size, ECPrivateKeySpec priKey, ECPublicKeySpec pubKey, Signature sgr, SecureRandom k, byte[] message, BigInteger r, BigInteger s) throws Exception { KeyFactory f = KeyFactory.getInstance("ECDSA", "BC"); PrivateKey sKey = f.generatePrivate(priKey); PublicKey vKey = f.generatePublic(pubKey); sgr.initSign(sKey, k); sgr.update(message); byte[] sigBytes = sgr.sign(); sgr.initVerify(vKey); sgr.update(message); if (!sgr.verify(sigBytes)) { fail(size + " bit EC verification failed"); } BigInteger[] sig = derDecode(sigBytes); if (!r.equals(sig[0])) { fail(size + "bit" + ": r component wrong." + System.getProperty("line.separator") + " expecting: " + r + System.getProperty("line.separator") + " got : " + sig[0]); } if (!s.equals(sig[1])) { fail(size + "bit" + ": s component wrong." + System.getProperty("line.separator") + " expecting: " + s + System.getProperty("line.separator") + " got : " + sig[1]); } } protected BigInteger[] derDecode( byte[] encoding) throws IOException { ByteArrayInputStream bIn = new ByteArrayInputStream(encoding); ASN1InputStream aIn = new ASN1InputStream(bIn); ASN1Sequence s = (ASN1Sequence)aIn.readObject(); BigInteger[] sig = new BigInteger[2]; sig[0] = ((DERInteger)s.getObjectAt(0)).getValue(); sig[1] = ((DERInteger)s.getObjectAt(1)).getValue(); return sig; } public String getName() { return "ECNR"; } public void performTest() throws Exception { testECNR192bitPrime(); testECNR239bitPrime(); testECNR521bitPrime(); } public static void main( String[] args) { Security.addProvider(new BouncyCastleProvider()); runTest(new ECNRTest()); } } bouncycastle-1.49.orig/test/src/org/bouncycastle/jce/provider/test/CRL5Test.java0000644000175000017500000004175210510121740027243 0ustar ebourgebourgpackage org.bouncycastle.jce.provider.test; import java.io.ByteArrayInputStream; import java.security.Security; import java.security.cert.CertificateFactory; import java.security.cert.X509CRL; import java.security.cert.X509CRLEntry; import java.util.Iterator; import java.util.Set; import org.bouncycastle.jce.provider.BouncyCastleProvider; import org.bouncycastle.util.encoders.Base64; import org.bouncycastle.util.test.SimpleTest; public class CRL5Test extends SimpleTest { byte[] inDirectCrl = Base64.decode( "MIIdXjCCHMcCAQEwDQYJKoZIhvcNAQEFBQAwdDELMAkGA1UEBhMCREUxHDAaBgNV" +"BAoUE0RldXRzY2hlIFRlbGVrb20gQUcxFzAVBgNVBAsUDlQtVGVsZVNlYyBUZXN0" +"MS4wDAYHAoIGAQoHFBMBMTAeBgNVBAMUF1QtVGVsZVNlYyBUZXN0IERJUiA4OlBO" +"Fw0wNjA4MDQwODQ1MTRaFw0wNjA4MDQxNDQ1MTRaMIIbfzB+AgQvrj/pFw0wMzA3" +"MjIwNTQxMjhaMGcwZQYDVR0dAQH/BFswWaRXMFUxCzAJBgNVBAYTAkRFMRwwGgYD" +"VQQKFBNEZXV0c2NoZSBUZWxla29tIEFHMSgwDAYHAoIGAQoHFBMBMTAYBgNVBAMU" +"EVNpZ0cgVGVzdCBDQSA0OlBOMH4CBC+uP+oXDTAzMDcyMjA1NDEyOFowZzBlBgNV" +"HR0BAf8EWzBZpFcwVTELMAkGA1UEBhMCREUxHDAaBgNVBAoUE0RldXRzY2hlIFRl" +"bGVrb20gQUcxKDAMBgcCggYBCgcUEwExMBgGA1UEAxQRU2lnRyBUZXN0IENBIDQ6" +"UE4wfgIEL64/5xcNMDQwNDA1MTMxODE3WjBnMGUGA1UdHQEB/wRbMFmkVzBVMQsw" +"CQYDVQQGEwJERTEcMBoGA1UEChQTRGV1dHNjaGUgVGVsZWtvbSBBRzEoMAwGBwKC" +"BgEKBxQTATEwGAYDVQQDFBFTaWdHIFRlc3QgQ0EgNDpQTjB+AgQvrj/oFw0wNDA0" +"MDUxMzE4MTdaMGcwZQYDVR0dAQH/BFswWaRXMFUxCzAJBgNVBAYTAkRFMRwwGgYD" +"VQQKFBNEZXV0c2NoZSBUZWxla29tIEFHMSgwDAYHAoIGAQoHFBMBMTAYBgNVBAMU" +"EVNpZ0cgVGVzdCBDQSA0OlBOMH4CBC+uP+UXDTAzMDExMzExMTgxMVowZzBlBgNV" +"HR0BAf8EWzBZpFcwVTELMAkGA1UEBhMCREUxHDAaBgNVBAoUE0RldXRzY2hlIFRl" +"bGVrb20gQUcxKDAMBgcCggYBCgcUEwExMBgGA1UEAxQRU2lnRyBUZXN0IENBIDQ6" +"UE4wfgIEL64/5hcNMDMwMTEzMTExODExWjBnMGUGA1UdHQEB/wRbMFmkVzBVMQsw" +"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"); byte[] directCRL = Base64.decode( "MIIGXTCCBckCAQEwCgYGKyQDAwECBQAwdDELMAkGA1UEBhMCREUxHDAaBgNVBAoU" +"E0RldXRzY2hlIFRlbGVrb20gQUcxFzAVBgNVBAsUDlQtVGVsZVNlYyBUZXN0MS4w" +"DAYHAoIGAQoHFBMBMTAeBgNVBAMUF1QtVGVsZVNlYyBUZXN0IERJUiA4OlBOFw0w" +"NjA4MDQwODQ1MTRaFw0wNjA4MDQxNDQ1MTRaMIIElTAVAgQvrj/pFw0wMzA3MjIw" +"NTQxMjhaMBUCBC+uP+oXDTAzMDcyMjA1NDEyOFowFQIEL64/5xcNMDQwNDA1MTMx" +"ODE3WjAVAgQvrj/oFw0wNDA0MDUxMzE4MTdaMBUCBC+uP+UXDTAzMDExMzExMTgx" +"MVowFQIEL64/5hcNMDMwMTEzMTExODExWjAVAgQvrj/jFw0wMzAxMTMxMTI2NTZa" +"MBUCBC+uP+QXDTAzMDExMzExMjY1NlowFQIEL64/4hcNMDQwNzEzMDc1ODM4WjAV" +"AgQvrj/eFw0wMzAyMTcwNjMzMjVaMBUCBC+uP98XDTAzMDIxNzA2MzMyNVowFQIE" +"L64/0xcNMDMwMjE3MDYzMzI1WjAVAgQvrj/dFw0wMzAxMTMxMTI4MTRaMBUCBC+u" +"P9cXDTAzMDExMzExMjcwN1owFQIEL64/2BcNMDMwMTEzMTEyNzA3WjAVAgQvrj/V" +"Fw0wMzA0MzAxMjI3NTNaMBUCBC+uP9YXDTAzMDQzMDEyMjc1M1owFQIEL64/xhcN" +"MDMwMjEyMTM0NTQwWjAVAgQvrj/FFw0wMzAyMTIxMzQ1NDBaMBUCBC+uP8IXDTAz" +"MDIxMjEzMDkxNlowFQIEL64/wRcNMDMwMjEyMTMwODQwWjAVAgQvrj++Fw0wMzAy" +"MTcwNjM3MjVaMBUCBC+uP70XDTAzMDIxNzA2MzcyNVowFQIEL64/sBcNMDMwMjEy" +"MTMwODU5WjAVAgQvrj+vFw0wMzAyMTcwNjM3MjVaMBUCBC+uP5MXDTAzMDQxMDA1" +"MjYyOFowFQIEL64/khcNMDMwNDEwMDUyNjI4WjAVAgQvrj8/Fw0wMzAyMjYxMTA0" +"NDRaMBUCBC+uPz4XDTAzMDIyNjExMDQ0NFowFQIEL64+zRcNMDMwNTIwMDUyNzM2" +"WjAVAgQvrj7MFw0wMzA1MjAwNTI3MzZaMBUCBC+uPjwXDTAzMDYxNzEwMzQxNlow" +"FQIEL64+OxcNMDMwNjE3MTAzNDE2WjAVAgQvrj46Fw0wMzA2MTcxMDM0MTZaMBUC" +"BC+uPjkXDTAzMDYxNzEzMDEwMFowFQIEL64+OBcNMDMwNjE3MTMwMTAwWjAVAgQv" +"rj43Fw0wMzA2MTcxMzAxMDBaMBUCBC+uPjYXDTAzMDYxNzEzMDEwMFowFQIEL64+" +"MxcNMDMwNjE3MTAzNzQ5WjAVAgQvrj4xFw0wMzA2MTcxMDQyNThaMBUCBC+uPjAX" +"DTAzMDYxNzEwNDI1OFowFQIEL649qRcNMDMxMDIyMTEzMjI0WjAVAgQvrjyyFw0w" +"NTAzMTEwNjQ0MjRaMBUCBC+uPKsXDTA0MDQwMjA3NTQ1M1owFQIEL6466BcNMDUw" +"MTI3MTIwMzI0WjAVAgQvrjq+Fw0wNTAyMTYwNzU3MTZaMBUCBC+uOqcXDTA1MDMx" +"MDA1NTkzNVowFQIEL646PBcNMDUwNTExMTA0OTQ2WjAVAgQvrG3VFw0wNTExMTEx" +"MDAzMjFaMBUCBC+uLmgXDTA2MDEyMzEwMjU1NVowFQIEL64mxxcNMDYwODAxMDk0" +"ODQ0WqCBijCBhzALBgNVHRQEBAICEQwwHwYDVR0jBBgwFoAUA1vI26YMj3njkfCU" +"IXbo244kLjkwVwYDVR0SBFAwToZMbGRhcDovL3Brc2xkYXAudHR0Yy5kZS9vdT1U" +"LVRlbGVTZWMgVGVzdCBESVIgODpQTixvPURldXRzY2hlIFRlbGVrb20gQUcsYz1k" +"ZTAKBgYrJAMDAQIFAAOBgQArj4eMlbAwuA2aS5O4UUUHQMKKdK/dtZi60+LJMiMY" +"ojrMIf4+ZCkgm1Ca0Cd5T15MJxVHhh167Ehn/Hd48pdnAP6Dfz/6LeqkIHGWMHR+" +"z6TXpwWB+P4BdUec1ztz04LypsznrHcLRa91ixg9TZCb1MrOG+InNhleRs1ImXk8" +"MQ=="); public String getName() { return "CRL5"; } public void indirectCRLTest() throws Exception { CertificateFactory cf = CertificateFactory.getInstance("X.509", "BC"); ByteArrayInputStream in = new ByteArrayInputStream(inDirectCrl); X509CRL crl = (X509CRL) cf.generateCRL(in); Set set = crl.getRevokedCertificates(); Iterator it = set.iterator(); while (it.hasNext()) { if (((X509CRLEntry)it.next()).getCertificateIssuer() == null) { fail("certificate issuer CRL entry extension is null"); } } } public void directCRLTest() throws Exception { CertificateFactory cf = CertificateFactory.getInstance("X.509", "BC"); ByteArrayInputStream in = new ByteArrayInputStream(directCRL); X509CRL crl = (X509CRL) cf.generateCRL(in); Set set = crl.getRevokedCertificates(); Iterator it = set.iterator(); while (it.hasNext()) { if (((X509CRLEntry)it.next()).getCertificateIssuer() != null) { fail("certificate issuer CRL entry extension is not null"); } } } public void performTest() throws Exception { indirectCRLTest(); directCRLTest(); } public static void main( String[] args) { Security.addProvider(new BouncyCastleProvider()); runTest(new CRL5Test()); } } bouncycastle-1.49.orig/test/src/org/bouncycastle/jce/provider/test/WrapTest.java0000644000175000017500000000435611631267433027465 0ustar ebourgebourgpackage org.bouncycastle.jce.provider.test; import java.security.Key; import java.security.KeyPair; import java.security.KeyPairGenerator; import java.security.MessageDigest; import java.security.PrivateKey; import java.security.PublicKey; import java.security.SecureRandom; import java.security.Security; import javax.crypto.Cipher; import javax.crypto.KeyGenerator; import org.bouncycastle.jce.provider.BouncyCastleProvider; import org.bouncycastle.util.test.SimpleTestResult; import org.bouncycastle.util.test.Test; import org.bouncycastle.util.test.TestResult; public class WrapTest implements Test { public TestResult perform() { try { Cipher cipher = Cipher.getInstance("DES/ECB/PKCS5Padding", "BC"); KeyPairGenerator fact = KeyPairGenerator.getInstance("RSA", "BC"); fact.initialize(512, new SecureRandom()); KeyPair keyPair = fact.generateKeyPair(); PrivateKey priKey = keyPair.getPrivate(); PublicKey pubKey = keyPair.getPublic(); KeyGenerator keyGen = KeyGenerator.getInstance("DES", "BC"); Key wrapKey = keyGen.generateKey(); cipher.init(Cipher.WRAP_MODE, wrapKey); byte[] wrappedKey = cipher.wrap(priKey); cipher.init(Cipher.UNWRAP_MODE, wrapKey); Key key = cipher.unwrap(wrappedKey, "RSA", Cipher.PRIVATE_KEY); if (!MessageDigest.isEqual(priKey.getEncoded(), key.getEncoded())) { return new SimpleTestResult(false, "Unwrapped key does not match"); } return new SimpleTestResult(true, getName() + ": Okay"); } catch (Exception e) { return new SimpleTestResult(false, getName() + ": exception - " + e.toString(), e); } } public String getName() { return "WrapTest"; } public static void main( String[] args) { Security.addProvider(new BouncyCastleProvider()); Test test = new WrapTest(); TestResult result = test.perform(); System.out.println(result.toString()); if (result.getException() != null) { result.getException().printStackTrace(); } } } bouncycastle-1.49.orig/test/src/org/bouncycastle/jce/provider/test/ImplicitlyCaTest.java0000644000175000017500000002612011701463553031127 0ustar ebourgebourgpackage org.bouncycastle.jce.provider.test; import java.math.BigInteger; import java.security.KeyFactory; import java.security.KeyPair; import java.security.KeyPairGenerator; import java.security.SecureRandom; import java.security.Security; import java.security.Signature; import java.security.interfaces.ECKey; import java.security.spec.ECFieldFp; import java.security.spec.EllipticCurve; import java.security.spec.PKCS8EncodedKeySpec; import java.security.spec.X509EncodedKeySpec; import org.bouncycastle.asn1.ASN1InputStream; import org.bouncycastle.asn1.DERNull; import org.bouncycastle.asn1.pkcs.PrivateKeyInfo; import org.bouncycastle.asn1.x509.SubjectPublicKeyInfo; import org.bouncycastle.jcajce.provider.config.ConfigurableProvider; import org.bouncycastle.jce.ECPointUtil; import org.bouncycastle.jce.interfaces.ECPrivateKey; import org.bouncycastle.jce.interfaces.ECPublicKey; import org.bouncycastle.jce.provider.BouncyCastleProvider; import org.bouncycastle.jce.spec.ECParameterSpec; import org.bouncycastle.jce.spec.ECPrivateKeySpec; import org.bouncycastle.jce.spec.ECPublicKeySpec; import org.bouncycastle.math.ec.ECCurve; import org.bouncycastle.util.encoders.Hex; import org.bouncycastle.util.test.FixedSecureRandom; import org.bouncycastle.util.test.SimpleTest; public class ImplicitlyCaTest extends SimpleTest { byte[] k1 = Hex.decode("d5014e4b60ef2ba8b6211b4062ba3224e0427dd3"); byte[] k2 = Hex.decode("345e8d05c075c3a508df729a1685690e68fcfb8c8117847e89063bca1f85d968fd281540b6e13bd1af989a1fbf17e06462bf511f9d0b140fb48ac1b1baa5bded"); SecureRandom random = new FixedSecureRandom(new byte[][] { k1, k2 }); public void performTest() throws Exception { testBCAPI(); testJDKAPI(); testKeyFactory(); testBasicThreadLocal(); } private void testBCAPI() throws Exception { KeyPairGenerator g = KeyPairGenerator.getInstance("ECDSA", "BC"); ECCurve curve = new ECCurve.Fp( new BigInteger("883423532389192164791648750360308885314476597252960362792450860609699839"), // q new BigInteger("7fffffffffffffffffffffff7fffffffffff8000000000007ffffffffffc", 16), // a new BigInteger("6b016c3bdcf18941d0d654921475ca71a9db2fb27d1d37796185c2942c0a", 16)); // b ECParameterSpec ecSpec = new ECParameterSpec( curve, curve.decodePoint(Hex.decode("020ffa963cdca8816ccc33b8642bedf905c3d358573d3f27fbbd3b3cb9aaaf")), // G new BigInteger("883423532389192164791648750360308884807550341691627752275345424702807307")); // n ConfigurableProvider config = (ConfigurableProvider)Security.getProvider("BC"); config.setParameter(ConfigurableProvider.EC_IMPLICITLY_CA, ecSpec); g.initialize(null, new SecureRandom()); KeyPair p = g.generateKeyPair(); ECPrivateKey sKey = (ECPrivateKey)p.getPrivate(); ECPublicKey vKey = (ECPublicKey)p.getPublic(); testECDSA(sKey, vKey); testBCParamsAndQ(sKey, vKey); testEC5Params(sKey, vKey); testEncoding(sKey, vKey); } private void testKeyFactory() throws Exception { KeyPairGenerator g = KeyPairGenerator.getInstance("ECDSA", "BC"); ECCurve curve = new ECCurve.Fp( new BigInteger("883423532389192164791648750360308885314476597252960362792450860609699839"), // q new BigInteger("7fffffffffffffffffffffff7fffffffffff8000000000007ffffffffffc", 16), // a new BigInteger("6b016c3bdcf18941d0d654921475ca71a9db2fb27d1d37796185c2942c0a", 16)); // b ECParameterSpec ecSpec = new ECParameterSpec( curve, curve.decodePoint(Hex.decode("020ffa963cdca8816ccc33b8642bedf905c3d358573d3f27fbbd3b3cb9aaaf")), // G new BigInteger("883423532389192164791648750360308884807550341691627752275345424702807307")); // n ConfigurableProvider config = (ConfigurableProvider)Security.getProvider("BC"); config.setParameter(ConfigurableProvider.EC_IMPLICITLY_CA, ecSpec); g.initialize(null, new SecureRandom()); KeyPair p = g.generateKeyPair(); ECPrivateKey sKey = (ECPrivateKey)p.getPrivate(); ECPublicKey vKey = (ECPublicKey)p.getPublic(); KeyFactory fact = KeyFactory.getInstance("ECDSA", "BC"); vKey = (ECPublicKey)fact.generatePublic(new ECPublicKeySpec(vKey.getQ(), null)); sKey = (ECPrivateKey)fact.generatePrivate(new ECPrivateKeySpec(sKey.getD(), null)); testECDSA(sKey, vKey); testBCParamsAndQ(sKey, vKey); testEC5Params(sKey, vKey); testEncoding(sKey, vKey); ECPublicKey vKey2 = (ECPublicKey)fact.generatePublic(new ECPublicKeySpec(vKey.getQ(), ecSpec)); ECPrivateKey sKey2 = (ECPrivateKey)fact.generatePrivate(new ECPrivateKeySpec(sKey.getD(), ecSpec)); if (!vKey.equals(vKey2) || vKey.hashCode() != vKey2.hashCode()) { fail("private equals/hashCode failed"); } if (!sKey.equals(sKey2) || sKey.hashCode() != sKey2.hashCode()) { fail("private equals/hashCode failed"); } // check we can get specs. fact.getKeySpec(vKey, java.security.spec.ECPublicKeySpec.class); fact.getKeySpec(sKey, java.security.spec.ECPrivateKeySpec.class); } private void testJDKAPI() throws Exception { KeyPairGenerator g = KeyPairGenerator.getInstance("ECDSA", "BC"); EllipticCurve curve = new EllipticCurve( new ECFieldFp(new BigInteger("883423532389192164791648750360308885314476597252960362792450860609699839")), // q new BigInteger("7fffffffffffffffffffffff7fffffffffff8000000000007ffffffffffc", 16), // a new BigInteger("6b016c3bdcf18941d0d654921475ca71a9db2fb27d1d37796185c2942c0a", 16)); // b java.security.spec.ECParameterSpec ecSpec = new java.security.spec.ECParameterSpec( curve, ECPointUtil.decodePoint(curve, Hex.decode("020ffa963cdca8816ccc33b8642bedf905c3d358573d3f27fbbd3b3cb9aaaf")), // G new BigInteger("883423532389192164791648750360308884807550341691627752275345424702807307"), // n 1); // h ConfigurableProvider config = (ConfigurableProvider)Security.getProvider("BC"); config.setParameter(ConfigurableProvider.EC_IMPLICITLY_CA, ecSpec); g.initialize(null, new SecureRandom()); KeyPair p = g.generateKeyPair(); ECPrivateKey sKey = (ECPrivateKey)p.getPrivate(); ECPublicKey vKey = (ECPublicKey)p.getPublic(); testECDSA(sKey, vKey); testBCParamsAndQ(sKey, vKey); testEC5Params(sKey, vKey); testEncoding(sKey, vKey); } private void testBasicThreadLocal() throws Exception { KeyPairGenerator g = KeyPairGenerator.getInstance("ECDSA", "BC"); EllipticCurve curve = new EllipticCurve( new ECFieldFp(new BigInteger("883423532389192164791648750360308885314476597252960362792450860609699839")), // q new BigInteger("7fffffffffffffffffffffff7fffffffffff8000000000007ffffffffffc", 16), // a new BigInteger("6b016c3bdcf18941d0d654921475ca71a9db2fb27d1d37796185c2942c0a", 16)); // b java.security.spec.ECParameterSpec ecSpec = new java.security.spec.ECParameterSpec( curve, ECPointUtil.decodePoint(curve, Hex.decode("020ffa963cdca8816ccc33b8642bedf905c3d358573d3f27fbbd3b3cb9aaaf")), // G new BigInteger("883423532389192164791648750360308884807550341691627752275345424702807307"), // n 1); // h ConfigurableProvider config = (ConfigurableProvider)Security.getProvider("BC"); config.setParameter(ConfigurableProvider.THREAD_LOCAL_EC_IMPLICITLY_CA, ecSpec); g.initialize(null, new SecureRandom()); KeyPair p = g.generateKeyPair(); ECPrivateKey sKey = (ECPrivateKey)p.getPrivate(); ECPublicKey vKey = (ECPublicKey)p.getPublic(); testECDSA(sKey, vKey); testBCParamsAndQ(sKey, vKey); testEC5Params(sKey, vKey); testEncoding(sKey, vKey); } private void testECDSA( ECPrivateKey sKey, ECPublicKey vKey) throws Exception { byte[] data = { 1, 2, 3, 4, 5, 6, 7, 8, 9, 0 }; Signature s = Signature.getInstance("ECDSA", "BC"); s.initSign(sKey); s.update(data); byte[] sigBytes = s.sign(); s = Signature.getInstance("ECDSA", "BC"); s.initVerify(vKey); s.update(data); if (!s.verify(sigBytes)) { fail("ECDSA verification failed"); } } private void testEncoding( ECPrivateKey privKey, ECPublicKey pubKey) throws Exception { KeyFactory kFact = KeyFactory.getInstance("ECDSA", "BC"); byte[] bytes = privKey.getEncoded(); PrivateKeyInfo sInfo = PrivateKeyInfo.getInstance(new ASN1InputStream(bytes).readObject()); if (!sInfo.getPrivateKeyAlgorithm().getParameters().equals(DERNull.INSTANCE)) { fail("private key parameters wrong"); } ECPrivateKey sKey = (ECPrivateKey)kFact.generatePrivate(new PKCS8EncodedKeySpec(bytes)); if (!sKey.equals(privKey)) { fail("private equals failed"); } if (sKey.hashCode() != privKey.hashCode()) { fail("private hashCode failed"); } bytes = pubKey.getEncoded(); SubjectPublicKeyInfo vInfo = SubjectPublicKeyInfo.getInstance(new ASN1InputStream(bytes).readObject()); if (!vInfo.getAlgorithm().getParameters().equals(DERNull.INSTANCE)) { fail("public key parameters wrong"); } ECPublicKey vKey = (ECPublicKey)kFact.generatePublic(new X509EncodedKeySpec(bytes)); if (!vKey.equals(pubKey) || vKey.hashCode() != pubKey.hashCode()) { fail("public equals/hashCode failed"); } testBCParamsAndQ(sKey, vKey); testEC5Params(sKey, vKey); testECDSA(sKey, vKey); } private void testBCParamsAndQ( ECPrivateKey sKey, ECPublicKey vKey) { if (sKey.getParameters() != null) { fail("parameters exposed in private key"); } if (vKey.getParameters() != null) { fail("parameters exposed in public key"); } if (vKey.getQ().getCurve() != null) { fail("curve exposed in public point"); } } private void testEC5Params( ECPrivateKey sKey, ECPublicKey vKey) { java.security.interfaces.ECKey k = (java.security.interfaces.ECKey)sKey; if (k.getParams() != null) { fail("parameters exposed in private key"); } k = (ECKey)vKey; if (k.getParams() != null) { fail("parameters exposed in public key"); } } public String getName() { return "ImplicitlyCA"; } public static void main( String[] args) { Security.addProvider(new BouncyCastleProvider()); runTest(new ImplicitlyCaTest()); } } bouncycastle-1.49.orig/test/src/org/bouncycastle/jce/provider/test/RSATest.java0000644000175000017500000010054412103437527027173 0ustar ebourgebourgpackage org.bouncycastle.jce.provider.test; import java.io.ByteArrayInputStream; import java.io.ByteArrayOutputStream; import java.io.IOException; import java.io.ObjectInputStream; import java.io.ObjectOutputStream; import java.math.BigInteger; import java.security.AlgorithmParameters; import java.security.KeyFactory; import java.security.KeyPair; import java.security.KeyPairGenerator; import java.security.MessageDigest; import java.security.NoSuchAlgorithmException; import java.security.PrivateKey; import java.security.PublicKey; import java.security.SecureRandom; import java.security.Security; import java.security.Signature; import java.security.interfaces.RSAPrivateCrtKey; import java.security.interfaces.RSAPublicKey; import java.security.spec.MGF1ParameterSpec; import java.security.spec.PKCS8EncodedKeySpec; import java.security.spec.RSAKeyGenParameterSpec; import java.security.spec.RSAPrivateCrtKeySpec; import java.security.spec.RSAPrivateKeySpec; import java.security.spec.RSAPublicKeySpec; import java.security.spec.X509EncodedKeySpec; import javax.crypto.Cipher; import javax.crypto.NoSuchPaddingException; import javax.crypto.spec.OAEPParameterSpec; import javax.crypto.spec.PSource; import org.bouncycastle.asn1.ASN1Encoding; import org.bouncycastle.asn1.ASN1ObjectIdentifier; import org.bouncycastle.asn1.DERNull; import org.bouncycastle.asn1.DEROctetString; import org.bouncycastle.asn1.nist.NISTObjectIdentifiers; import org.bouncycastle.asn1.oiw.OIWObjectIdentifiers; import org.bouncycastle.asn1.pkcs.PKCSObjectIdentifiers; import org.bouncycastle.asn1.pkcs.RSAESOAEPparams; import org.bouncycastle.asn1.teletrust.TeleTrusTObjectIdentifiers; import org.bouncycastle.asn1.x509.AlgorithmIdentifier; import org.bouncycastle.asn1.x509.DigestInfo; import org.bouncycastle.asn1.x509.X509ObjectIdentifiers; import org.bouncycastle.jce.provider.BouncyCastleProvider; import org.bouncycastle.util.Arrays; import org.bouncycastle.util.encoders.Hex; import org.bouncycastle.util.test.SimpleTest; public class RSATest extends SimpleTest { /** * a fake random number generator - we just want to make sure the random numbers * aren't random so that we get the same output, while still getting to test the * key generation facilities. */ private class FixedSecureRandom extends SecureRandom { byte[] seed = { (byte)0xaa, (byte)0xfd, (byte)0x12, (byte)0xf6, (byte)0x59, (byte)0xca, (byte)0xe6, (byte)0x34, (byte)0x89, (byte)0xb4, (byte)0x79, (byte)0xe5, (byte)0x07, (byte)0x6d, (byte)0xde, (byte)0xc2, (byte)0xf0, (byte)0x6c, (byte)0xb5, (byte)0x8f }; public void nextBytes( byte[] bytes) { int offset = 0; while ((offset + seed.length) < bytes.length) { System.arraycopy(seed, 0, bytes, offset, seed.length); offset += seed.length; } System.arraycopy(seed, 0, bytes, offset, bytes.length - offset); } } private RSAPublicKeySpec pubKeySpec = new RSAPublicKeySpec( new BigInteger("b4a7e46170574f16a97082b22be58b6a2a629798419be12872a4bdba626cfae9900f76abfb12139dce5de56564fab2b6543165a040c606887420e33d91ed7ed7", 16), new BigInteger("11", 16)); private RSAPrivateCrtKeySpec privKeySpec = new RSAPrivateCrtKeySpec( new BigInteger("b4a7e46170574f16a97082b22be58b6a2a629798419be12872a4bdba626cfae9900f76abfb12139dce5de56564fab2b6543165a040c606887420e33d91ed7ed7", 16), new BigInteger("11", 16), new BigInteger("9f66f6b05410cd503b2709e88115d55daced94d1a34d4e32bf824d0dde6028ae79c5f07b580f5dce240d7111f7ddb130a7945cd7d957d1920994da389f490c89", 16), new BigInteger("c0a0758cdf14256f78d4708c86becdead1b50ad4ad6c5c703e2168fbf37884cb", 16), new BigInteger("f01734d7960ea60070f1b06f2bb81bfac48ff192ae18451d5e56c734a5aab8a5", 16), new BigInteger("b54bb9edff22051d9ee60f9351a48591b6500a319429c069a3e335a1d6171391", 16), new BigInteger("d3d83daf2a0cecd3367ae6f8ae1aeb82e9ac2f816c6fc483533d8297dd7884cd", 16), new BigInteger("b8f52fc6f38593dabb661d3f50f8897f8106eee68b1bce78a95b132b4e5b5d19", 16)); private RSAPublicKeySpec isoPubKeySpec = new RSAPublicKeySpec( new BigInteger("0100000000000000000000000000000000bba2d15dbb303c8a21c5ebbcbae52b7125087920dd7cdf358ea119fd66fb064012ec8ce692f0a0b8e8321b041acd40b7", 16), new BigInteger("03", 16)); private RSAPrivateKeySpec isoPrivKeySpec = new RSAPrivateKeySpec( new BigInteger("0100000000000000000000000000000000bba2d15dbb303c8a21c5ebbcbae52b7125087920dd7cdf358ea119fd66fb064012ec8ce692f0a0b8e8321b041acd40b7", 16), new BigInteger("2aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaac9f0783a49dd5f6c5af651f4c9d0dc9281c96a3f16a85f9572d7cc3f2d0f25a9dbf1149e4cdc32273faadd3fda5dcda7", 16)); static RSAPublicKeySpec pub2048KeySpec = new RSAPublicKeySpec( new BigInteger("a7295693155b1813bb84877fb45343556e0568043de5910872a3a518cc11e23e2db74eaf4545068c4e3d258a2718fbacdcc3eafa457695b957e88fbf110aed049a992d9c430232d02f3529c67a3419935ea9b569f85b1bcd37de6b899cd62697e843130ff0529d09c97d813cb15f293751ff56f943fbdabb63971cc7f4f6d5bff1594416b1f5907bde5a84a44f9802ef29b43bda1960f948f8afb8766c1ab80d32eec88ed66d0b65aebe44a6d0b3c5e0ab051aaa1b912fbcc17b8e751ddecc5365b6db6dab0020c3057db4013a51213a5798a3aab67985b0f4d88627a54a0f3f0285fbcb4afdfeb65cb153af66825656d43238b75503231500753f4e421e3c57", 16), new BigInteger("10001", 16)); static RSAPrivateCrtKeySpec priv2048KeySpec = new RSAPrivateCrtKeySpec( new BigInteger("a7295693155b1813bb84877fb45343556e0568043de5910872a3a518cc11e23e2db74eaf4545068c4e3d258a2718fbacdcc3eafa457695b957e88fbf110aed049a992d9c430232d02f3529c67a3419935ea9b569f85b1bcd37de6b899cd62697e843130ff0529d09c97d813cb15f293751ff56f943fbdabb63971cc7f4f6d5bff1594416b1f5907bde5a84a44f9802ef29b43bda1960f948f8afb8766c1ab80d32eec88ed66d0b65aebe44a6d0b3c5e0ab051aaa1b912fbcc17b8e751ddecc5365b6db6dab0020c3057db4013a51213a5798a3aab67985b0f4d88627a54a0f3f0285fbcb4afdfeb65cb153af66825656d43238b75503231500753f4e421e3c57", 16), new BigInteger("10001", 16), new BigInteger("65dad56ac7df7abb434e4cb5eeadb16093aa6da7f0033aad3815289b04757d32bfee6ade7749c8e4a323b5050a2fb9e2a99e23469e1ed4ba5bab54336af20a5bfccb8b3424cc6923db2ffca5787ed87aa87aa614cd04cedaebc8f623a2d2063017910f436dff18bb06f01758610787f8b258f0a8efd8bd7de30007c47b2a1031696c7d6523bc191d4d918927a7e0b09584ed205bd2ff4fc4382678df82353f7532b3bbb81d69e3f39070aed3fb64fce032a089e8e64955afa5213a6eb241231bd98d702fba725a9b205952fda186412d9e0d9344d2998c455ad8c2bae85ee672751466d5288304032b5b7e02f7e558c7af82c7fbf58eea0bb4ef0f001e6cd0a9", 16), new BigInteger("d4fd9ac3474fb83aaf832470643609659e511b322632b239b688f3cd2aad87527d6cf652fb9c9ca67940e84789444f2e99b0cb0cfabbd4de95396106c865f38e2fb7b82b231260a94df0e01756bf73ce0386868d9c41645560a81af2f53c18e4f7cdf3d51d80267372e6e0216afbf67f655c9450769cca494e4f6631b239ce1b", 16), new BigInteger("c8eaa0e2a1b3a4412a702bccda93f4d150da60d736c99c7c566fdea4dd1b401cbc0d8c063daaf0b579953d36343aa18b33dbf8b9eae94452490cc905245f8f7b9e29b1a288bc66731a29e1dd1a45c9fd7f8238ff727adc49fff73991d0dc096206b9d3a08f61e7462e2b804d78cb8c5eccdb9b7fbd2ad6a8fea46c1053e1be75", 16), new BigInteger("10edcb544421c0f9e123624d1099feeb35c72a8b34e008ac6fa6b90210a7543f293af4e5299c8c12eb464e70092805c7256e18e5823455ba0f504d36f5ccacac1b7cd5c58ff710f9c3f92646949d88fdd1e7ea5fed1081820bb9b0d2a8cd4b093fecfdb96dabd6e28c3a6f8c186dc86cddc89afd3e403e0fcf8a9e0bcb27af0b", 16), new BigInteger("97fc25484b5a415eaa63c03e6efa8dafe9a1c8b004d9ee6e80548fefd6f2ce44ee5cb117e77e70285798f57d137566ce8ea4503b13e0f1b5ed5ca6942537c4aa96b2a395782a4cb5b58d0936e0b0fa63b1192954d39ced176d71ef32c6f42c84e2e19f9d4dd999c2151b032b97bd22aa73fd8c5bcd15a2dca4046d5acc997021", 16), new BigInteger("4bb8064e1eff7e9efc3c4578fcedb59ca4aef0993a8312dfdcb1b3decf458aa6650d3d0866f143cbf0d3825e9381181170a0a1651eefcd7def786b8eb356555d9fa07c85b5f5cbdd74382f1129b5e36b4166b6cc9157923699708648212c484958351fdc9cf14f218dbe7fbf7cbd93a209a4681fe23ceb44bab67d66f45d1c9d", 16)); public void performTest() throws Exception { KeyFactory fact; byte[] input = new byte[] { (byte)0x54, (byte)0x85, (byte)0x9b, (byte)0x34, (byte)0x2c, (byte)0x49, (byte)0xea, (byte)0x2a }; byte[][] output = new byte[][] { Hex.decode("8b427f781a2e59dd9def386f1956b996ee07f48c96880e65a368055ed8c0a8831669ef7250b40918b2b1d488547e72c84540e42bd07b03f14e226f04fbc2d929"), Hex.decode("2ec6e1a1711b6c7b8cd3f6a25db21ab8bb0a5f1d6df2ef375fa708a43997730ffc7c98856dbbe36edddcdd1b2d2a53867d8355af94fea3aeec128da908e08f4c"), Hex.decode("0850ac4e5a8118323200c8ed1e5aaa3d5e635172553ccac66a8e4153d35c79305c4440f11034ab147fccce21f18a50cf1c0099c08a577eb68237a91042278965"), Hex.decode("1c9649bdccb51056751fe43837f4eb43bada472accf26f65231666d5de7d11950d8379b3596dfdf75c6234274896fa8d18ad0865d3be2ac4d6687151abdf01e93941dcef18fa63186c9351d1506c89d09733c5ff4304208c812bdd21a50f56fde115e629e0e973721c9fcc87e89295a79853dee613962a0b2f2fc57163fd99057a3c776f13c20c26407eb8863998d7e53b543ba8d0a295a9a68d1a149833078c9809ad6a6dad7fc22a95ad615a73138c54c018f40d99bf8eeecd45f5be526f2d6b01aeb56381991c1ab31a2e756f15e052b9cd5638b2eff799795c5bae493307d5eb9f8c21d438de131fe505a4e7432547ab19224094f9e4be1968bd0793b79d"), Hex.decode("4c4afc0c24dddaedd4f9a3b23be30d35d8e005ffd36b3defc5d18acc830c3ed388ce20f43a00e614fd087c814197bc9fc2eff9ad4cc474a7a2ef3ed9c0f0a55eb23371e41ee8f2e2ed93ea3a06ca482589ab87e0d61dcffda5eea1241408e43ea1108726cdb87cc3aa5e9eaaa9f72507ca1352ac54a53920c94dccc768147933d8c50aefd9d1da10522a40133cd33dbc0524669e70f771a88d65c4716d471cd22b08b9f01f24e4e9fc7ffbcfa0e0a7aed47b345826399b26a73be112eb9c5e06fc6742fc3d0ef53d43896403c5105109cfc12e6deeaf4a48ba308e039774b9bdb31a9b9e133c81c321630cf0b4b2d1f90717b24c3268e1fea681ea9cdc709342"), Hex.decode("06b5b26bd13515f799e5e37ca43cace15cd82fd4bf36b25d285a6f0998d97c8cb0755a28f0ae66618b1cd03e27ac95eaaa4882bc6dc0078cd457d4f7de4154173a9c7a838cfc2ac2f74875df462aae0cfd341645dc51d9a01da9bdb01507f140fa8a016534379d838cc3b2a53ac33150af1b242fc88013cb8d914e66c8182864ee6de88ce2879d4c05dd125409620a96797c55c832fb2fb31d4310c190b8ed2c95fdfda2ed87f785002faaec3f35ec05cf70a3774ce185e4882df35719d582dd55ac31257344a9cba95189dcbea16e8c6cb7a235a0384bc83b6183ca8547e670fe33b1b91725ae0c250c9eca7b5ba78bd77145b70270bf8ac31653006c02ca9c"), Hex.decode("135f1be3d045526235bf9d5e43499d4ee1bfdf93370769ae56e85dbc339bc5b7ea3bee49717497ee8ac3f7cd6adb6fc0f17812390dcd65ac7b87fef7970d9ff9"), Hex.decode("03c05add1e030178c352face07cafc9447c8f369b8f95125c0d311c16b6da48ca2067104cce6cd21ae7b163cd18ffc13001aecebdc2eb02b9e92681f84033a98"), Hex.decode("00319bb9becb49f3ed1bca26d0fcf09b0b0a508e4d0bd43b350f959b72cd25b3af47d608fdcd248eada74fbe19990dbeb9bf0da4b4e1200243a14e5cab3f7e610c") }; SecureRandom rand = new FixedSecureRandom(); fact = KeyFactory.getInstance("RSA", "BC"); PrivateKey privKey = fact.generatePrivate(privKeySpec); PublicKey pubKey = fact.generatePublic(pubKeySpec); PrivateKey priv2048Key = fact.generatePrivate(priv2048KeySpec); PublicKey pub2048Key = fact.generatePublic(pub2048KeySpec); // // No Padding // Cipher c = Cipher.getInstance("RSA", "BC"); c.init(Cipher.ENCRYPT_MODE, pubKey, rand); byte[] out = c.doFinal(input); if (!areEqual(out, output[0])) { fail("NoPadding test failed on encrypt expected " + new String(Hex.encode(output[0])) + " got " + new String(Hex.encode(out))); } c.init(Cipher.DECRYPT_MODE, privKey); out = c.doFinal(out); if (!areEqual(out, input)) { fail("NoPadding test failed on decrypt expected " + new String(Hex.encode(input)) + " got " + new String(Hex.encode(out))); } // // No Padding - incremental // c = Cipher.getInstance("RSA", "BC"); c.init(Cipher.ENCRYPT_MODE, pubKey, rand); c.update(input); out = c.doFinal(); if (!areEqual(out, output[0])) { fail("NoPadding test failed on encrypt expected " + new String(Hex.encode(output[0])) + " got " + new String(Hex.encode(out))); } c.init(Cipher.DECRYPT_MODE, privKey); out = c.doFinal(out); if (!areEqual(out, input)) { fail("NoPadding test failed on decrypt expected " + new String(Hex.encode(input)) + " got " + new String(Hex.encode(out))); } // // No Padding - incremental - explicit use of NONE in mode. // c = Cipher.getInstance("RSA/NONE/NoPadding", "BC"); c.init(Cipher.ENCRYPT_MODE, pubKey, rand); c.update(input); out = c.doFinal(); if (!areEqual(out, output[0])) { fail("NoPadding test failed on encrypt expected " + new String(Hex.encode(output[0])) + " got " + new String(Hex.encode(out))); } c.init(Cipher.DECRYPT_MODE, privKey); out = c.doFinal(out); if (!areEqual(out, input)) { fail("NoPadding test failed on decrypt expected " + new String(Hex.encode(input)) + " got " + new String(Hex.encode(out))); } // // No Padding - maximum length // c = Cipher.getInstance("RSA", "BC"); byte[] modBytes = ((RSAPublicKey)pubKey).getModulus().toByteArray(); byte[] maxInput = new byte[modBytes.length - 1]; maxInput[0] |= 0x7f; c.init(Cipher.ENCRYPT_MODE, pubKey, rand); out = c.doFinal(maxInput); c.init(Cipher.DECRYPT_MODE, privKey); out = c.doFinal(out); if (!areEqual(out, maxInput)) { fail("NoPadding test failed on decrypt expected " + new String(Hex.encode(maxInput)) + " got " + new String(Hex.encode(out))); } // // PKCS1 V 1.5 // c = Cipher.getInstance("RSA/ECB/PKCS1Padding", "BC"); c.init(Cipher.ENCRYPT_MODE, pubKey, rand); out = c.doFinal(input); if (!areEqual(out, output[1])) { fail("PKCS1 test failed on encrypt expected " + new String(Hex.encode(output[1])) + " got " + new String(Hex.encode(out))); } c.init(Cipher.DECRYPT_MODE, privKey); out = c.doFinal(out); if (!areEqual(out, input)) { fail("PKCS1 test failed on decrypt expected " + new String(Hex.encode(input)) + " got " + new String(Hex.encode(out))); } // // PKCS1 V 1.5 - NONE // c = Cipher.getInstance("RSA/NONE/PKCS1Padding", "BC"); c.init(Cipher.ENCRYPT_MODE, pubKey, rand); out = c.doFinal(input); if (!areEqual(out, output[1])) { fail("PKCS1 test failed on encrypt expected " + new String(Hex.encode(output[1])) + " got " + new String(Hex.encode(out))); } c.init(Cipher.DECRYPT_MODE, privKey); out = c.doFinal(out); if (!areEqual(out, input)) { fail("PKCS1 test failed on decrypt expected " + new String(Hex.encode(input)) + " got " + new String(Hex.encode(out))); } // // OAEP - SHA1 // c = Cipher.getInstance("RSA/NONE/OAEPPadding", "BC"); c.init(Cipher.ENCRYPT_MODE, pubKey, rand); out = c.doFinal(input); if (!areEqual(out, output[2])) { fail("OAEP test failed on encrypt expected " + new String(Hex.encode(output[2])) + " got " + new String(Hex.encode(out))); } c = Cipher.getInstance("RSA/NONE/OAEPWithSHA1AndMGF1Padding", "BC"); c.init(Cipher.DECRYPT_MODE, privKey); out = c.doFinal(out); if (!areEqual(out, input)) { fail("OAEP test failed on decrypt expected " + new String(Hex.encode(input)) + " got " + new String(Hex.encode(out))); } AlgorithmParameters oaepP = c.getParameters(); if (!areEqual(oaepP.getEncoded(), new RSAESOAEPparams( new AlgorithmIdentifier(OIWObjectIdentifiers.idSHA1, DERNull.INSTANCE), new AlgorithmIdentifier(PKCSObjectIdentifiers.id_mgf1, new AlgorithmIdentifier(OIWObjectIdentifiers.idSHA1, DERNull.INSTANCE)), new AlgorithmIdentifier(PKCSObjectIdentifiers.id_pSpecified, new DEROctetString(new byte[0]))).getEncoded())) { fail("OAEP test failed default sha-1 parameters"); } // // OAEP - SHA224 // c = Cipher.getInstance("RSA/NONE/OAEPWithSHA224AndMGF1Padding", "BC"); c.init(Cipher.ENCRYPT_MODE, pub2048Key, rand); out = c.doFinal(input); if (!areEqual(out, output[3])) { fail("OAEP SHA-224 test failed on encrypt expected " + new String(Hex.encode(output[2])) + " got " + new String(Hex.encode(out))); } c.init(Cipher.DECRYPT_MODE, priv2048Key); out = c.doFinal(out); if (!areEqual(out, input)) { fail("OAEP SHA-224 test failed on decrypt expected " + new String(Hex.encode(input)) + " got " + new String(Hex.encode(out))); } oaepP = c.getParameters(); if (!areEqual(oaepP.getEncoded(), new RSAESOAEPparams( new AlgorithmIdentifier(NISTObjectIdentifiers.id_sha224, DERNull.INSTANCE), new AlgorithmIdentifier(PKCSObjectIdentifiers.id_mgf1, new AlgorithmIdentifier(NISTObjectIdentifiers.id_sha224, DERNull.INSTANCE)), new AlgorithmIdentifier(PKCSObjectIdentifiers.id_pSpecified, new DEROctetString(new byte[0]))).getEncoded())) { fail("OAEP test failed default sha-224 parameters"); } // // OAEP - SHA 256 // c = Cipher.getInstance("RSA/NONE/OAEPWithSHA256AndMGF1Padding", "BC"); c.init(Cipher.ENCRYPT_MODE, pub2048Key, rand); out = c.doFinal(input); if (!areEqual(out, output[4])) { fail("OAEP SHA-256 test failed on encrypt expected " + new String(Hex.encode(output[2])) + " got " + new String(Hex.encode(out))); } c.init(Cipher.DECRYPT_MODE, priv2048Key); out = c.doFinal(out); if (!areEqual(out, input)) { fail("OAEP SHA-256 test failed on decrypt expected " + new String(Hex.encode(input)) + " got " + new String(Hex.encode(out))); } oaepP = c.getParameters(); if (!areEqual(oaepP.getEncoded(), new RSAESOAEPparams( new AlgorithmIdentifier(NISTObjectIdentifiers.id_sha256, DERNull.INSTANCE), new AlgorithmIdentifier(PKCSObjectIdentifiers.id_mgf1, new AlgorithmIdentifier(NISTObjectIdentifiers.id_sha256, DERNull.INSTANCE)), new AlgorithmIdentifier(PKCSObjectIdentifiers.id_pSpecified, new DEROctetString(new byte[0]))).getEncoded())) { fail("OAEP test failed default sha-256 parameters"); } // // OAEP - SHA 384 // c = Cipher.getInstance("RSA/NONE/OAEPWithSHA384AndMGF1Padding", "BC"); c.init(Cipher.ENCRYPT_MODE, pub2048Key, rand); out = c.doFinal(input); if (!areEqual(out, output[5])) { fail("OAEP SHA-384 test failed on encrypt expected " + new String(Hex.encode(output[2])) + " got " + new String(Hex.encode(out))); } c.init(Cipher.DECRYPT_MODE, priv2048Key); out = c.doFinal(out); if (!areEqual(out, input)) { fail("OAEP SHA-384 test failed on decrypt expected " + new String(Hex.encode(input)) + " got " + new String(Hex.encode(out))); } oaepP = c.getParameters(); if (!areEqual(oaepP.getEncoded(), new RSAESOAEPparams( new AlgorithmIdentifier(NISTObjectIdentifiers.id_sha384, DERNull.INSTANCE), new AlgorithmIdentifier(PKCSObjectIdentifiers.id_mgf1, new AlgorithmIdentifier(NISTObjectIdentifiers.id_sha384, DERNull.INSTANCE)), new AlgorithmIdentifier(PKCSObjectIdentifiers.id_pSpecified, new DEROctetString(new byte[0]))).getEncoded())) { fail("OAEP test failed default sha-384 parameters"); } // // OAEP - MD5 // c = Cipher.getInstance("RSA/NONE/OAEPWithMD5AndMGF1Padding", "BC"); c.init(Cipher.ENCRYPT_MODE, pubKey, rand); out = c.doFinal(input); if (!areEqual(out, output[6])) { fail("OAEP MD5 test failed on encrypt expected " + new String(Hex.encode(output[2])) + " got " + new String(Hex.encode(out))); } c.init(Cipher.DECRYPT_MODE, privKey); out = c.doFinal(out); if (!areEqual(out, input)) { fail("OAEP MD5 test failed on decrypt expected " + new String(Hex.encode(input)) + " got " + new String(Hex.encode(out))); } oaepP = c.getParameters(); if (!areEqual(oaepP.getEncoded(), new RSAESOAEPparams( new AlgorithmIdentifier(PKCSObjectIdentifiers.md5, DERNull.INSTANCE), new AlgorithmIdentifier(PKCSObjectIdentifiers.id_mgf1, new AlgorithmIdentifier(PKCSObjectIdentifiers.md5, DERNull.INSTANCE)), new AlgorithmIdentifier(PKCSObjectIdentifiers.id_pSpecified, new DEROctetString(new byte[0]))).getEncoded())) { fail("OAEP test failed default md5 parameters"); } // // OAEP - SHA1 with default parameters // c = Cipher.getInstance("RSA/NONE/OAEPPadding", "BC"); c.init(Cipher.ENCRYPT_MODE, pubKey, OAEPParameterSpec.DEFAULT, rand); out = c.doFinal(input); if (!areEqual(out, output[2])) { fail("OAEP test failed on encrypt expected " + new String(Hex.encode(output[2])) + " got " + new String(Hex.encode(out))); } c = Cipher.getInstance("RSA/NONE/OAEPWithSHA1AndMGF1Padding", "BC"); c.init(Cipher.DECRYPT_MODE, privKey); out = c.doFinal(out); if (!areEqual(out, input)) { fail("OAEP test failed on decrypt expected " + new String(Hex.encode(input)) + " got " + new String(Hex.encode(out))); } oaepP = c.getParameters(); if (!areEqual(oaepP.getEncoded(), new byte[] { 0x30, 0x00 })) { fail("OAEP test failed default parameters"); } // // OAEP - SHA1 with specified string // c = Cipher.getInstance("RSA/NONE/OAEPPadding", "BC"); c.init(Cipher.ENCRYPT_MODE, pubKey, new OAEPParameterSpec("SHA1", "MGF1", new MGF1ParameterSpec("SHA1"), new PSource.PSpecified(new byte[] { 1, 2, 3, 4, 5 })), rand); out = c.doFinal(input); oaepP = c.getParameters(); if (!areEqual(oaepP.getEncoded(), new RSAESOAEPparams( new AlgorithmIdentifier(OIWObjectIdentifiers.idSHA1, DERNull.INSTANCE), new AlgorithmIdentifier(PKCSObjectIdentifiers.id_mgf1, new AlgorithmIdentifier(OIWObjectIdentifiers.idSHA1, DERNull.INSTANCE)), new AlgorithmIdentifier(PKCSObjectIdentifiers.id_pSpecified, new DEROctetString(new byte[] { 1, 2, 3, 4, 5 }))).getEncoded())) { fail("OAEP test failed changed sha-1 parameters"); } if (!areEqual(out, output[7])) { fail("OAEP test failed on encrypt expected " + new String(Hex.encode(output[2])) + " got " + new String(Hex.encode(out))); } c = Cipher.getInstance("RSA/NONE/OAEPWithSHA1AndMGF1Padding", "BC"); c.init(Cipher.DECRYPT_MODE, privKey, oaepP); out = c.doFinal(out); if (!areEqual(out, input)) { fail("OAEP test failed on decrypt expected " + new String(Hex.encode(input)) + " got " + new String(Hex.encode(out))); } // // ISO9796-1 // byte[] isoInput = Hex.decode("fedcba9876543210fedcba9876543210fedcba9876543210fedcba9876543210"); PrivateKey isoPrivKey = fact.generatePrivate(isoPrivKeySpec); PublicKey isoPubKey = fact.generatePublic(isoPubKeySpec); c = Cipher.getInstance("RSA/NONE/ISO9796-1Padding", "BC"); c.init(Cipher.ENCRYPT_MODE, isoPrivKey); out = c.doFinal(isoInput); if (!areEqual(out, output[8])) { fail("ISO9796-1 test failed on encrypt expected " + new String(Hex.encode(output[3])) + " got " + new String(Hex.encode(out))); } c.init(Cipher.DECRYPT_MODE, isoPubKey); out = c.doFinal(out); if (!areEqual(out, isoInput)) { fail("ISO9796-1 test failed on decrypt expected " + new String(Hex.encode(input)) + " got " + new String(Hex.encode(out))); } // // // generation with parameters test. // KeyPairGenerator keyPairGen = KeyPairGenerator.getInstance("RSA", "BC"); // // 768 bit RSA with e = 2^16-1 // keyPairGen.initialize( new RSAKeyGenParameterSpec(768, BigInteger.valueOf(65537)), new SecureRandom()); KeyPair kp = keyPairGen.generateKeyPair(); pubKey = kp.getPublic(); privKey = kp.getPrivate(); c.init(Cipher.ENCRYPT_MODE, pubKey, rand); out = c.doFinal(input); c.init(Cipher.DECRYPT_MODE, privKey); out = c.doFinal(out); if (!areEqual(out, input)) { fail("key generation test failed on decrypt expected " + new String(Hex.encode(input)) + " got " + new String(Hex.encode(out))); } // // comparison check // KeyFactory keyFact = KeyFactory.getInstance("RSA", "BC"); RSAPrivateCrtKey crtKey = (RSAPrivateCrtKey)keyFact.translateKey(privKey); if (!privKey.equals(crtKey)) { fail("private key equality check failed"); } crtKey = (RSAPrivateCrtKey)keyFact.generatePrivate(new PKCS8EncodedKeySpec(privKey.getEncoded())); if (!privKey.equals(crtKey)) { fail("private key equality check failed"); } crtKey = (RSAPrivateCrtKey)serializeDeserialize(privKey); if (!privKey.equals(crtKey)) { fail("private key equality check failed"); } if (privKey.hashCode() != crtKey.hashCode()) { fail("private key hashCode check failed"); } RSAPublicKey copyKey = (RSAPublicKey)keyFact.translateKey(pubKey); if (!pubKey.equals(copyKey)) { fail("public key equality check failed"); } copyKey = (RSAPublicKey)keyFact.generatePublic(new X509EncodedKeySpec(pubKey.getEncoded())); if (!pubKey.equals(copyKey)) { fail("public key equality check failed"); } copyKey = (RSAPublicKey)serializeDeserialize(pubKey); if (!pubKey.equals(copyKey)) { fail("public key equality check failed"); } if (pubKey.hashCode() != copyKey.hashCode()) { fail("public key hashCode check failed"); } oaepCompatibilityTest("SHA-1", priv2048Key, pub2048Key); oaepCompatibilityTest("SHA-224", priv2048Key, pub2048Key); oaepCompatibilityTest("SHA-256", priv2048Key, pub2048Key); oaepCompatibilityTest("SHA-384", priv2048Key, pub2048Key); oaepCompatibilityTest("SHA-512", priv2048Key, pub2048Key); SecureRandom random = new SecureRandom(); rawModeTest("SHA1withRSA", X509ObjectIdentifiers.id_SHA1, priv2048Key, pub2048Key, random); rawModeTest("MD5withRSA", PKCSObjectIdentifiers.md5, priv2048Key, pub2048Key, random); rawModeTest("RIPEMD128withRSA", TeleTrusTObjectIdentifiers.ripemd128, priv2048Key, pub2048Key, random); // init reset test c.init(Cipher.ENCRYPT_MODE, pubKey, rand); out = c.update(new byte[40]); c.init(Cipher.ENCRYPT_MODE, pubKey, rand); out = c.update(new byte[40]); } private void oaepCompatibilityTest(String digest, PrivateKey privKey, PublicKey pubKey) throws Exception { if (Security.getProvider("SunJCE") == null || Security.getProvider("SunRsaSign") == null) { return; } KeyFactory fact = KeyFactory.getInstance("RSA", "SunRsaSign"); PrivateKey priv2048Key = fact.generatePrivate(priv2048KeySpec); PublicKey pub2048Key = fact.generatePublic(pub2048KeySpec); byte[] data = new byte[] { 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16 }; Cipher sCipher; try { sCipher = Cipher.getInstance("RSA/ECB/OAEPWith" + digest + "AndMGF1Padding", "SunJCE"); } catch (NoSuchAlgorithmException e) { return; } catch (NoSuchPaddingException e) { return; } sCipher.init(Cipher.ENCRYPT_MODE, pub2048Key); byte[] enctext = sCipher.doFinal(data); Cipher bcCipher = Cipher.getInstance("RSA/ECB/OAEPWith" + digest + "AndMGF1Padding", "BC"); bcCipher.init(Cipher.DECRYPT_MODE, privKey, new OAEPParameterSpec(digest, "MGF1", MGF1ParameterSpec.SHA1, PSource.PSpecified.DEFAULT)); byte[] plaintext = bcCipher.doFinal(enctext); if (!Arrays.areEqual(plaintext, data)) { fail("data did not decrypt first time"); } bcCipher.init(Cipher.ENCRYPT_MODE, pubKey, new OAEPParameterSpec(digest, "MGF1", MGF1ParameterSpec.SHA1, PSource.PSpecified.DEFAULT)); enctext = bcCipher.doFinal(data); sCipher.init(Cipher.DECRYPT_MODE, priv2048Key); plaintext = sCipher.doFinal(enctext); if (!Arrays.areEqual(plaintext, data)) { fail("data did not decrypt second time"); } } private void rawModeTest(String sigName, ASN1ObjectIdentifier digestOID, PrivateKey privKey, PublicKey pubKey, SecureRandom random) throws Exception { byte[] sampleMessage = new byte[1000 + random.nextInt(100)]; random.nextBytes(sampleMessage); Signature normalSig = Signature.getInstance(sigName, "BC"); normalSig.initSign(privKey); normalSig.update(sampleMessage); byte[] normalResult = normalSig.sign(); MessageDigest digest = MessageDigest.getInstance(digestOID.getId(), "BC"); byte[] hash = digest.digest(sampleMessage); byte[] digInfo = derEncode(digestOID, hash); Signature rawSig = Signature.getInstance("RSA", "BC"); rawSig.initSign(privKey); rawSig.update(digInfo); byte[] rawResult = rawSig.sign(); if (!Arrays.areEqual(normalResult, rawResult)) { fail("raw mode signature differs from normal one"); } rawSig.initVerify(pubKey); rawSig.update(digInfo); if (!rawSig.verify(rawResult)) { fail("raw mode signature verification failed"); } } private Object serializeDeserialize(Object o) throws Exception { ByteArrayOutputStream bOut = new ByteArrayOutputStream(); ObjectOutputStream oOut = new ObjectOutputStream(bOut); oOut.writeObject(o); oOut.close(); ObjectInputStream oIn = new ObjectInputStream(new ByteArrayInputStream(bOut.toByteArray())); return oIn.readObject(); } private byte[] derEncode(ASN1ObjectIdentifier oid, byte[] hash) throws IOException { AlgorithmIdentifier algId = new AlgorithmIdentifier(oid, DERNull.INSTANCE); DigestInfo dInfo = new DigestInfo(algId, hash); return dInfo.getEncoded(ASN1Encoding.DER); } public String getName() { return "RSATest"; } public static void main( String[] args) { Security.addProvider(new BouncyCastleProvider()); runTest(new RSATest()); } } bouncycastle-1.49.orig/test/src/org/bouncycastle/jce/provider/test/GOST3410Test.java0000644000175000017500000004067511727762223027647 0ustar ebourgebourgpackage org.bouncycastle.jce.provider.test; import java.io.ByteArrayInputStream; import java.io.ByteArrayOutputStream; import java.io.IOException; import java.io.ObjectInputStream; import java.io.ObjectOutputStream; import java.math.BigInteger; import java.security.InvalidKeyException; import java.security.KeyFactory; import java.security.KeyPair; import java.security.KeyPairGenerator; import java.security.KeyStore; import java.security.KeyStoreException; import java.security.NoSuchAlgorithmException; import java.security.NoSuchProviderException; import java.security.PrivateKey; import java.security.PublicKey; import java.security.SecureRandom; import java.security.Security; import java.security.Signature; import java.security.SignatureException; import java.security.UnrecoverableKeyException; import java.security.cert.Certificate; import java.security.cert.CertificateException; import java.security.cert.X509Certificate; import java.security.spec.PKCS8EncodedKeySpec; import java.security.spec.X509EncodedKeySpec; import java.util.Date; import org.bouncycastle.asn1.cryptopro.CryptoProObjectIdentifiers; import org.bouncycastle.jce.X509Principal; import org.bouncycastle.jce.interfaces.ECPrivateKey; import org.bouncycastle.jce.interfaces.ECPublicKey; import org.bouncycastle.jce.interfaces.GOST3410PrivateKey; import org.bouncycastle.jce.interfaces.GOST3410PublicKey; import org.bouncycastle.jce.interfaces.PKCS12BagAttributeCarrier; import org.bouncycastle.jce.provider.BouncyCastleProvider; import org.bouncycastle.jce.spec.ECNamedCurveGenParameterSpec; import org.bouncycastle.jce.spec.ECParameterSpec; import org.bouncycastle.jce.spec.ECPrivateKeySpec; import org.bouncycastle.jce.spec.ECPublicKeySpec; import org.bouncycastle.jce.spec.GOST3410ParameterSpec; import org.bouncycastle.math.ec.ECCurve; import org.bouncycastle.math.ec.ECFieldElement; import org.bouncycastle.math.ec.ECPoint; import org.bouncycastle.util.BigIntegers; import org.bouncycastle.util.test.FixedSecureRandom; import org.bouncycastle.util.test.SimpleTest; import org.bouncycastle.x509.X509V3CertificateGenerator; public class GOST3410Test extends SimpleTest { private void ecGOST3410Test() throws Exception { BigInteger r = new BigInteger("29700980915817952874371204983938256990422752107994319651632687982059210933395"); BigInteger s = new BigInteger("46959264877825372965922731380059061821746083849389763294914877353246631700866"); byte[] kData = BigIntegers.asUnsignedByteArray(new BigInteger("53854137677348463731403841147996619241504003434302020712960838528893196233395")); SecureRandom k = new FixedSecureRandom(kData); BigInteger mod_p = new BigInteger("57896044618658097711785492504343953926634992332820282019728792003956564821041"); //p ECCurve curve = new ECCurve.Fp( mod_p, // p new BigInteger("7"), // a new BigInteger("43308876546767276905765904595650931995942111794451039583252968842033849580414")); // b ECParameterSpec spec = new ECParameterSpec( curve, new ECPoint.Fp(curve, new ECFieldElement.Fp(mod_p,new BigInteger("2")), // x new ECFieldElement.Fp(mod_p,new BigInteger("4018974056539037503335449422937059775635739389905545080690979365213431566280"))), // y new BigInteger("57896044618658097711785492504343953927082934583725450622380973592137631069619")); // q ECPrivateKeySpec priKey = new ECPrivateKeySpec( new BigInteger("55441196065363246126355624130324183196576709222340016572108097750006097525544"), // d spec); ECPublicKeySpec pubKey = new ECPublicKeySpec( new ECPoint.Fp(curve, new ECFieldElement.Fp(mod_p, new BigInteger("57520216126176808443631405023338071176630104906313632182896741342206604859403")), // x new ECFieldElement.Fp(mod_p, new BigInteger("17614944419213781543809391949654080031942662045363639260709847859438286763994"))), // y spec); Signature sgr = Signature.getInstance("ECGOST3410", "BC"); KeyFactory f = KeyFactory.getInstance("ECGOST3410", "BC"); PrivateKey sKey = f.generatePrivate(priKey); PublicKey vKey = f.generatePublic(pubKey); sgr.initSign(sKey, k); byte[] message = new byte[] { (byte)'a', (byte)'b', (byte)'c' }; sgr.update(message); byte[] sigBytes = sgr.sign(); sgr.initVerify(vKey); sgr.update(message); if (!sgr.verify(sigBytes)) { fail("ECGOST3410 verification failed"); } BigInteger[] sig = decode(sigBytes); if (!r.equals(sig[0])) { fail( ": r component wrong." + System.getProperty("line.separator") + " expecting: " + r + System.getProperty("line.separator") + " got : " + sig[0]); } if (!s.equals(sig[1])) { fail( ": s component wrong." + System.getProperty("line.separator") + " expecting: " + s + System.getProperty("line.separator") + " got : " + sig[1]); } } private void generationTest() throws Exception { Signature s = Signature.getInstance("GOST3410", "BC"); KeyPairGenerator g = KeyPairGenerator.getInstance("GOST3410", "BC"); byte[] data = { 1, 2, 3, 4, 5, 6, 7, 8, 9, 0 }; GOST3410ParameterSpec gost3410P = new GOST3410ParameterSpec(CryptoProObjectIdentifiers.gostR3410_94_CryptoPro_A.getId()); g.initialize(gost3410P, new SecureRandom()); KeyPair p = g.generateKeyPair(); PrivateKey sKey = p.getPrivate(); PublicKey vKey = p.getPublic(); s.initSign(sKey); s.update(data); byte[] sigBytes = s.sign(); s = Signature.getInstance("GOST3410", "BC"); s.initVerify(vKey); s.update(data); if (!s.verify(sigBytes)) { fail("GOST3410 verification failed"); } // // default initialisation test // s = Signature.getInstance("GOST3410", "BC"); g = KeyPairGenerator.getInstance("GOST3410", "BC"); p = g.generateKeyPair(); sKey = p.getPrivate(); vKey = p.getPublic(); s.initSign(sKey); s.update(data); sigBytes = s.sign(); s = Signature.getInstance("GOST3410", "BC"); s.initVerify(vKey); s.update(data); if (!s.verify(sigBytes)) { fail("GOST3410 verification failed"); } // // encoded test // KeyFactory f = KeyFactory.getInstance("GOST3410", "BC"); X509EncodedKeySpec x509s = new X509EncodedKeySpec(vKey.getEncoded()); GOST3410PublicKey k1 = (GOST3410PublicKey)f.generatePublic(x509s); if (!k1.getY().equals(((GOST3410PublicKey)vKey).getY())) { fail("public number not decoded properly"); } if (!k1.getParameters().equals(((GOST3410PublicKey)vKey).getParameters())) { fail("public parameters not decoded properly"); } PKCS8EncodedKeySpec pkcs8 = new PKCS8EncodedKeySpec(sKey.getEncoded()); GOST3410PrivateKey k2 = (GOST3410PrivateKey)f.generatePrivate(pkcs8); if (!k2.getX().equals(((GOST3410PrivateKey)sKey).getX())) { fail("private number not decoded properly"); } if (!k2.getParameters().equals(((GOST3410PrivateKey)sKey).getParameters())) { fail("private number not decoded properly"); } k2 = (GOST3410PrivateKey)serializeDeserialize(sKey); if (!k2.getX().equals(((GOST3410PrivateKey)sKey).getX())) { fail("private number not deserialised properly"); } if (!k2.getParameters().equals(((GOST3410PrivateKey)sKey).getParameters())) { fail("private number not deserialised properly"); } checkEquals(k2, sKey); if (!(k2 instanceof PKCS12BagAttributeCarrier)) { fail("private key not implementing PKCS12 attribute carrier"); } k1 = (GOST3410PublicKey)serializeDeserialize(vKey); if (!k1.getY().equals(((GOST3410PublicKey)vKey).getY())) { fail("public number not deserialised properly"); } if (!k1.getParameters().equals(((GOST3410PublicKey)vKey).getParameters())) { fail("public parameters not deserialised properly"); } checkEquals(k1, vKey); // // ECGOST3410 generation test // s = Signature.getInstance("ECGOST3410", "BC"); g = KeyPairGenerator.getInstance("ECGOST3410", "BC"); // BigInteger mod_p = new BigInteger("57896044618658097711785492504343953926634992332820282019728792003956564821041"); //p // // ECCurve curve = new ECCurve.Fp( // mod_p, // p // new BigInteger("7"), // a // new BigInteger("43308876546767276905765904595650931995942111794451039583252968842033849580414")); // b // // ECParameterSpec ecSpec = new ECParameterSpec( // curve, // new ECPoint.Fp(curve, // new ECFieldElement.Fp(mod_p,new BigInteger("2")), // x // new ECFieldElement.Fp(mod_p,new BigInteger("4018974056539037503335449422937059775635739389905545080690979365213431566280"))), // y // new BigInteger("57896044618658097711785492504343953927082934583725450622380973592137631069619")); // q g.initialize(new ECNamedCurveGenParameterSpec("GostR3410-2001-CryptoPro-A"), new SecureRandom()); p = g.generateKeyPair(); sKey = p.getPrivate(); vKey = p.getPublic(); s.initSign(sKey); s.update(data); sigBytes = s.sign(); s = Signature.getInstance("ECGOST3410", "BC"); s.initVerify(vKey); s.update(data); if (!s.verify(sigBytes)) { fail("ECGOST3410 verification failed"); } // // encoded test // f = KeyFactory.getInstance("ECGOST3410", "BC"); x509s = new X509EncodedKeySpec(vKey.getEncoded()); ECPublicKey eck1 = (ECPublicKey)f.generatePublic(x509s); if (!eck1.getQ().equals(((ECPublicKey)vKey).getQ())) { fail("public number not decoded properly"); } if (!eck1.getParameters().equals(((ECPublicKey)vKey).getParameters())) { fail("public parameters not decoded properly"); } pkcs8 = new PKCS8EncodedKeySpec(sKey.getEncoded()); ECPrivateKey eck2 = (ECPrivateKey)f.generatePrivate(pkcs8); if (!eck2.getD().equals(((ECPrivateKey)sKey).getD())) { fail("private number not decoded properly"); } if (!eck2.getParameters().equals(((ECPrivateKey)sKey).getParameters())) { fail("private number not decoded properly"); } eck2 = (ECPrivateKey)serializeDeserialize(sKey); if (!eck2.getD().equals(((ECPrivateKey)sKey).getD())) { fail("private number not decoded properly"); } if (!eck2.getParameters().equals(((ECPrivateKey)sKey).getParameters())) { fail("private number not decoded properly"); } checkEquals(eck2, sKey); if (!(eck2 instanceof PKCS12BagAttributeCarrier)) { fail("private key not implementing PKCS12 attribute carrier"); } eck1 = (ECPublicKey)serializeDeserialize(vKey); if (!eck1.getQ().equals(((ECPublicKey)vKey).getQ())) { fail("public number not decoded properly"); } if (!eck1.getParameters().equals(((ECPublicKey)vKey).getParameters())) { fail("public parameters not decoded properly"); } checkEquals(eck1, vKey); } private void keyStoreTest(PrivateKey sKey, PublicKey vKey) throws KeyStoreException, IOException, NoSuchAlgorithmException, CertificateException, NoSuchProviderException, SignatureException, InvalidKeyException, UnrecoverableKeyException { // // keystore test // KeyStore ks = KeyStore.getInstance("JKS"); ks.load(null, null); // // create the certificate - version 3 // X509V3CertificateGenerator certGen = new X509V3CertificateGenerator(); certGen.setSerialNumber(BigInteger.valueOf(1)); certGen.setIssuerDN(new X509Principal("CN=Test")); certGen.setNotBefore(new Date(System.currentTimeMillis() - 50000)); certGen.setNotAfter(new Date(System.currentTimeMillis() + 50000)); certGen.setSubjectDN(new X509Principal("CN=Test")); certGen.setPublicKey(vKey); certGen.setSignatureAlgorithm("GOST3411withGOST3410"); X509Certificate cert = certGen.generate(sKey, "BC"); ks.setKeyEntry("gost",sKey, "gost".toCharArray(), new Certificate[] { cert }); ByteArrayOutputStream bOut = new ByteArrayOutputStream(); ks.store(bOut, "gost".toCharArray()); ks = KeyStore.getInstance("JKS"); ks.load(new ByteArrayInputStream(bOut.toByteArray()), "gost".toCharArray()); PrivateKey gKey = (PrivateKey)ks.getKey("gost", "gost".toCharArray()); } private void checkEquals(Object o1, Object o2) { if (!o1.equals(o2)) { fail("comparison test failed"); } if (o1.hashCode() != o2.hashCode()) { fail("hashCode test failed"); } } private void parametersTest() throws Exception { // AlgorithmParameterGenerator a = AlgorithmParameterGenerator.getInstance("GOST3410", "BC"); // a.init(512, random); // AlgorithmParameters params = a.generateParameters(); // // byte[] encodeParams = params.getEncoded(); // // AlgorithmParameters a2 = AlgorithmParameters.getInstance("GOST3410", "BC"); // a2.init(encodeParams); // // // a and a2 should be equivalent! // byte[] encodeParams_2 = a2.getEncoded(); // // if (!arrayEquals(encodeParams, encodeParams_2)) // { // fail("encode/decode parameters failed"); // } GOST3410ParameterSpec gost3410P = new GOST3410ParameterSpec(CryptoProObjectIdentifiers.gostR3410_94_CryptoPro_B.getId()); KeyPairGenerator g = KeyPairGenerator.getInstance("GOST3410", "BC"); g.initialize(gost3410P, new SecureRandom()); KeyPair p = g.generateKeyPair(); PrivateKey sKey = p.getPrivate(); PublicKey vKey = p.getPublic(); Signature s = Signature.getInstance("GOST3410", "BC"); byte[] data = { 1, 2, 3, 4, 5, 6, 7, 8, 9, 0 }; s.initSign(sKey); s.update(data); byte[] sigBytes = s.sign(); s = Signature.getInstance("GOST3410", "BC"); s.initVerify(vKey); s.update(data); if (!s.verify(sigBytes)) { fail("GOST3410 verification failed"); } keyStoreTest(sKey, vKey); } private BigInteger[] decode( byte[] encoding) { byte[] r = new byte[32]; byte[] s = new byte[32]; System.arraycopy(encoding, 0, s, 0, 32); System.arraycopy(encoding, 32, r, 0, 32); BigInteger[] sig = new BigInteger[2]; sig[0] = new BigInteger(1, r); sig[1] = new BigInteger(1, s); return sig; } private Object serializeDeserialize(Object o) throws Exception { ByteArrayOutputStream bOut = new ByteArrayOutputStream(); ObjectOutputStream oOut = new ObjectOutputStream(bOut); oOut.writeObject(o); oOut.close(); ObjectInputStream oIn = new ObjectInputStream(new ByteArrayInputStream(bOut.toByteArray())); return oIn.readObject(); } public String getName() { return "GOST3410/ECGOST3410"; } public void performTest() throws Exception { ecGOST3410Test(); generationTest(); parametersTest(); } public static void main( String[] args) { Security.addProvider(new BouncyCastleProvider()); runTest(new GOST3410Test()); } } bouncycastle-1.49.orig/test/src/org/bouncycastle/jce/provider/test/NetscapeCertRequestTest.java0000644000175000017500000001050310330633061032461 0ustar ebourgebourgpackage org.bouncycastle.jce.provider.test; import java.io.ByteArrayInputStream; import java.io.ByteArrayOutputStream; import java.security.KeyPair; import java.security.KeyPairGenerator; import java.security.Security; import org.bouncycastle.asn1.ASN1InputStream; import org.bouncycastle.asn1.ASN1Sequence; import org.bouncycastle.asn1.DEROutputStream; import org.bouncycastle.asn1.pkcs.PKCSObjectIdentifiers; import org.bouncycastle.asn1.x509.AlgorithmIdentifier; import org.bouncycastle.jce.netscape.NetscapeCertRequest; import org.bouncycastle.jce.provider.BouncyCastleProvider; import org.bouncycastle.util.encoders.Base64; import org.bouncycastle.util.test.SimpleTestResult; import org.bouncycastle.util.test.Test; import org.bouncycastle.util.test.TestResult; /** */ public class NetscapeCertRequestTest implements Test { /* from NS 4.75 */ static final String test1 = "MIIBRzCBsTCBnzANBgkqhkiG9w0BAQEFAAOBjQAwgYkCgYEAmwdh+LJXQ8AtXczo"+ "4EIGfXjpmDwsoIRpPaXEx1CBHhpon/Dpo/o5Vw2WoWNICXj5lmqhftIpCPO9qKxx"+ "85x6k/fuyTPH8P02hkmscAYsgqOgb/1yRCNXFryuFOATqxw1tsuye5Q3lTU9JCLU"+ "UilQ6BV8n3fm2egtPPUaJEuCvcsCAwEAARYNZml4ZWQtZm9yLW5vdzANBgkqhkiG"+ "9w0BAQQFAAOBgQAImbJD6xHbJtXl6kOTbCFoMnDk7U0o6pHy9l56DYVsiluXegiY"+ "6twB4o7OWsrqTb+gVvzK65FfP+NBVVzxY8UzcjbqC51yvO/9wnpUsIBqD/Gvi1gE"+ "qvw7RHwVEhdzsvLwlL22G8CfDxHnWLww39j8uRJsmoNiKJly3BcsZkLd9g=="; public String getName() { return "NetscapeCertRequest"; } public TestResult perform() { try { String challenge = "fixed-for-now"; byte data [] = Base64.decode (test1); ASN1InputStream in = new ASN1InputStream (new ByteArrayInputStream(data)); ASN1Sequence spkac = (ASN1Sequence)in.readObject (); // System.out.println("SPKAC: \n"+DERDump.dumpAsString (spkac)); NetscapeCertRequest nscr = new NetscapeCertRequest (spkac); if (!nscr.verify (challenge)) { return new SimpleTestResult(false, getName() + ": 1 - not verified"); } //now try to generate one KeyPairGenerator kpg = KeyPairGenerator.getInstance (nscr.getKeyAlgorithm().getObjectId ().getId(), "BC"); kpg.initialize (1024); KeyPair kp = kpg.genKeyPair(); nscr.setPublicKey (kp.getPublic()); nscr.sign (kp.getPrivate()); ByteArrayOutputStream baos = new ByteArrayOutputStream(); DEROutputStream deros = new DEROutputStream (baos); deros.writeObject (nscr); deros.close(); ASN1InputStream in2 = new ASN1InputStream (new ByteArrayInputStream(baos.toByteArray())); ASN1Sequence spkac2 = (ASN1Sequence)in2.readObject (); // System.out.println("SPKAC2: \n"+DERDump.dumpAsString (spkac2)); NetscapeCertRequest nscr2 = new NetscapeCertRequest (spkac2); if (!nscr2.verify (challenge)) { return new SimpleTestResult(false, getName() + ": 2 - not verified"); } //lets build it from scratch challenge = "try it"; NetscapeCertRequest nscr3 = new NetscapeCertRequest (challenge, new AlgorithmIdentifier(PKCSObjectIdentifiers.sha1WithRSAEncryption, null), kp.getPublic()); nscr3.sign (kp.getPrivate()); // System.out.println("SPKAC3: \n"+DERDump.dumpAsString (nscr3)); if (nscr3.verify (challenge)) { return new SimpleTestResult(true, getName() + ": Okay"); } else { return new SimpleTestResult(false, getName() + ": 3 - not verified"); } } catch (Exception e) { return new SimpleTestResult(false, getName() + ": exception - " + e.toString()); } } public static void main( String[] args) { Security.addProvider(new BouncyCastleProvider()); Test test = new NetscapeCertRequestTest(); TestResult result = test.perform(); System.out.println(result.toString()); } } bouncycastle-1.49.orig/test/src/org/bouncycastle/jce/provider/test/DSTU4145Test.java0000644000175000017500000001473012151252353027637 0ustar ebourgebourgpackage org.bouncycastle.jce.provider.test; import java.io.IOException; import java.math.BigInteger; import java.security.InvalidAlgorithmParameterException; import java.security.InvalidKeyException; import java.security.KeyFactory; import java.security.KeyPair; import java.security.KeyPairGenerator; import java.security.NoSuchAlgorithmException; import java.security.NoSuchProviderException; import java.security.PrivateKey; import java.security.PublicKey; import java.security.SecureRandom; import java.security.Security; import java.security.Signature; import java.security.interfaces.ECPrivateKey; import java.security.interfaces.ECPublicKey; import org.bouncycastle.asn1.ASN1OctetString; import org.bouncycastle.jce.provider.BouncyCastleProvider; import org.bouncycastle.jce.spec.ECParameterSpec; import org.bouncycastle.jce.spec.ECPrivateKeySpec; import org.bouncycastle.jce.spec.ECPublicKeySpec; import org.bouncycastle.math.ec.ECCurve; import org.bouncycastle.util.encoders.Hex; import org.bouncycastle.util.test.FixedSecureRandom; import org.bouncycastle.util.test.SimpleTest; public class DSTU4145Test extends SimpleTest { public String getName() { return "DSTU4145"; } public void performTest() throws Exception { DSTU4145Test(); generationTest(); //parametersTest(); } public static void main(String[] args) { Security.addProvider(new BouncyCastleProvider()); runTest(new DSTU4145Test()); } static final BigInteger r = new BigInteger("00f2702989366e9569d5092b83ac17f918bf040c487a", 16); static final BigInteger s = new BigInteger("01dd460039db3be70392d7012f2a492d3e59091ab7a6", 16); private void generationTest() throws Exception { ECCurve.F2m curve = new ECCurve.F2m(173, 1, 2, 10, BigInteger.ZERO, new BigInteger("108576C80499DB2FC16EDDF6853BBB278F6B6FB437D9", 16)); ECParameterSpec spec = new ECParameterSpec( curve, curve.createPoint(new BigInteger("BE6628EC3E67A91A4E470894FBA72B52C515F8AEE9", 16), new BigInteger("D9DEEDF655CF5412313C11CA566CDC71F4DA57DB45C", 16), false), new BigInteger("800000000000000000000189B4E67606E3825BB2831", 16)); SecureRandom k = new FixedSecureRandom(Hex.decode("00137449348C1249971759D99C252FFE1E14D8B31F00")); SecureRandom keyRand = new FixedSecureRandom(Hex.decode("0000955CD7E344303D1034E66933DC21C8044D42ADB8")); KeyPairGenerator keyGen = KeyPairGenerator.getInstance("DSTU4145", "BC"); keyGen.initialize(spec, keyRand); KeyPair pair = keyGen.generateKeyPair(); Signature sgr = Signature.getInstance("DSTU4145", "BC"); sgr.initSign(pair.getPrivate(), k); byte[] message = new byte[]{(byte)'a', (byte)'b', (byte)'c'}; sgr.update(message); byte[] sigBytes = sgr.sign(); sgr.initVerify(pair.getPublic()); sgr.update(message); if (!sgr.verify(sigBytes)) { fail("DSTU4145 verification failed"); } BigInteger[] sig = decode(sigBytes); if (!r.equals(sig[0])) { fail( ": r component wrong." + System.getProperty("line.separator") + " expecting: " + r + System.getProperty("line.separator") + " got : " + sig[0].toString(16)); } if (!s.equals(sig[1])) { fail( ": s component wrong." + System.getProperty("line.separator") + " expecting: " + s + System.getProperty("line.separator") + " got : " + sig[1].toString(16)); } } private void DSTU4145Test() throws Exception { SecureRandom k = new FixedSecureRandom(Hex.decode("00137449348C1249971759D99C252FFE1E14D8B31F00")); ECCurve.F2m curve = new ECCurve.F2m(173, 1, 2, 10, BigInteger.ZERO, new BigInteger("108576C80499DB2FC16EDDF6853BBB278F6B6FB437D9", 16)); ECParameterSpec spec = new ECParameterSpec( curve, curve.createPoint(new BigInteger("BE6628EC3E67A91A4E470894FBA72B52C515F8AEE9", 16), new BigInteger("D9DEEDF655CF5412313C11CA566CDC71F4DA57DB45C", 16), false), new BigInteger("800000000000000000000189B4E67606E3825BB2831", 16)); ECPrivateKeySpec priKey = new ECPrivateKeySpec( new BigInteger("955CD7E344303D1034E66933DC21C8044D42ADB8", 16), // d spec); ECPublicKeySpec pubKey = new ECPublicKeySpec( curve.createPoint(new BigInteger("22de541d48a75c1c3b8c7c107b2551c5093c6c096e1", 16), new BigInteger("1e5b602efc0269d61e64d97c9193d2788fa05c4b7fd5", 16), false), spec); Signature sgr = Signature.getInstance("DSTU4145", "BC"); KeyFactory f = KeyFactory.getInstance("DSTU4145", "BC"); PrivateKey sKey = f.generatePrivate(priKey); PublicKey vKey = f.generatePublic(pubKey); sgr.initSign(sKey, k); byte[] message = new byte[]{(byte)'a', (byte)'b', (byte)'c'}; sgr.update(message); byte[] sigBytes = sgr.sign(); sgr.initVerify(vKey); sgr.update(message); if (!sgr.verify(sigBytes)) { fail("DSTU4145 verification failed"); } BigInteger[] sig = decode(sigBytes); if (!r.equals(sig[0])) { fail( ": r component wrong." + System.getProperty("line.separator") + " expecting: " + r + System.getProperty("line.separator") + " got : " + sig[0].toString(16)); } if (!s.equals(sig[1])) { fail( ": s component wrong." + System.getProperty("line.separator") + " expecting: " + s + System.getProperty("line.separator") + " got : " + sig[1].toString(16)); } } private BigInteger[] decode( byte[] encoding) throws IOException { ASN1OctetString octetString = (ASN1OctetString)ASN1OctetString.fromByteArray(encoding); encoding = octetString.getOctets(); byte[] r = new byte[encoding.length / 2]; byte[] s = new byte[encoding.length / 2]; System.arraycopy(encoding, 0, s, 0, encoding.length / 2); System.arraycopy(encoding, encoding.length / 2, r, 0, encoding.length / 2); BigInteger[] sig = new BigInteger[2]; sig[0] = new BigInteger(1, r); sig[1] = new BigInteger(1, s); return sig; } } bouncycastle-1.49.orig/test/src/org/bouncycastle/jce/provider/test/DHIESTest.java0000755000175000017500000001663612151252353027410 0ustar ebourgebourgpackage org.bouncycastle.jce.provider.test; import java.math.BigInteger; import java.security.KeyPair; import java.security.KeyPairGenerator; import java.security.SecureRandom; import java.security.Security; import javax.crypto.Cipher; import javax.crypto.interfaces.DHPrivateKey; import javax.crypto.interfaces.DHPublicKey; import javax.crypto.spec.DHParameterSpec; import org.bouncycastle.crypto.agreement.DHBasicAgreement; import org.bouncycastle.crypto.digests.SHA1Digest; import org.bouncycastle.crypto.engines.DESEngine; import org.bouncycastle.crypto.engines.IESEngine; import org.bouncycastle.crypto.generators.KDF2BytesGenerator; import org.bouncycastle.crypto.macs.HMac; import org.bouncycastle.crypto.paddings.PaddedBufferedBlockCipher; import org.bouncycastle.jce.provider.BouncyCastleProvider; import org.bouncycastle.jcajce.provider.asymmetric.dh.IESCipher; import org.bouncycastle.jce.spec.IESParameterSpec; import org.bouncycastle.util.encoders.Hex; import org.bouncycastle.util.test.SimpleTest; /** * Test for DHIES - Diffie-Hellman Integrated Encryption Scheme */ public class DHIESTest extends SimpleTest { // Oakley group 2 - RFC 5996 BigInteger p1024 = new BigInteger( "FFFFFFFFFFFFFFFFC90FDAA22168C234C4C6628B80DC1CD1" + "29024E088A67CC74020BBEA63B139B22514A08798E3404DD" + "EF9519B3CD3A431B302B0A6DF25F14374FE1356D6D51C245" + "E485B576625E7EC6F44C42E9A637ED6B0BFF5CB6F406B7ED" + "EE386BFB5A899FA5AE9F24117C4B1FE649286651ECE65381" + "FFFFFFFFFFFFFFFF",16); BigInteger g1024 = new BigInteger("2",16); DHParameterSpec param = new DHParameterSpec(p1024, g1024); DHIESTest() { } public String getName() { return "DHIES"; } public void performTest() throws Exception { byte[] derivation = Hex.decode("202122232425262728292a2b2c2d2e2f"); byte[] encoding = Hex.decode("303132333435363738393a3b3c3d3e3f"); IESCipher c1 = new org.bouncycastle.jcajce.provider.asymmetric.dh.IESCipher.IES(); IESCipher c2 = new org.bouncycastle.jcajce.provider.asymmetric.dh.IESCipher.IES(); IESParameterSpec params = new IESParameterSpec(derivation,encoding,128); // Testing DHIES with default prime in streaming mode KeyPairGenerator g = KeyPairGenerator.getInstance("DH", "BC"); g.initialize(param); doTest("DHIES with default", g, "DHIES", params); // Testing DHIES with 512-bit prime in streaming mode g.initialize(512, new SecureRandom()); doTest("DHIES with 512-bit", g, "DHIES", params); // Testing ECIES with 1024-bit prime in streaming mode g.initialize(1024, new SecureRandom()); doTest("DHIES with 1024-bit", g, "DHIES", params); c1 = new IESCipher(new IESEngine(new DHBasicAgreement(), new KDF2BytesGenerator(new SHA1Digest()), new HMac(new SHA1Digest()), new PaddedBufferedBlockCipher(new DESEngine()))); c2 = new IESCipher(new IESEngine(new DHBasicAgreement(), new KDF2BytesGenerator(new SHA1Digest()), new HMac(new SHA1Digest()), new PaddedBufferedBlockCipher(new DESEngine()))); params = new IESParameterSpec(derivation, encoding, 128, 192); // Testing DHIES with default prime using DESEDE g = KeyPairGenerator.getInstance("DH", "BC"); doTest("DHIESwithDES default", g, "DHIESwithDESEDE", params); // Testing DHIES with 512-bit prime using DESEDE g.initialize(512, new SecureRandom()); doTest("DHIESwithDES 512-bit", g, "DHIESwithDESEDE", params); // Testing DHIES with 1024-bit prime using DESEDE g.initialize(1024, new SecureRandom()); doTest("DHIESwithDES 1024-bit", g, "DHIESwithDESEDE", params); g = KeyPairGenerator.getInstance("DH", "BC"); g.initialize(param); c1 = new IESCipher.IESwithAES(); c2 = new IESCipher.IESwithAES(); params = new IESParameterSpec(derivation, encoding, 128, 128); // Testing DHIES with default curve using AES doTest("DHIESwithAES default", g, "DHIESwithAES", params); // Testing DHIES with 512-bit curve using AES g.initialize(512, new SecureRandom()); doTest("DHIESwithAES 512-bit", g, "DHIESwithAES", params); // Testing DHIES with 1024-bit curve using AES g.initialize(1024, new SecureRandom()); doTest("DHIESwithAES 1024-bit", g, "DHIESwithAES", params); } public void doTest( String testname, KeyPairGenerator g, String cipher, IESParameterSpec p) throws Exception { byte[] message = Hex.decode("0102030405060708090a0b0c0d0e0f10111213141516"); byte[] out1, out2; Cipher c1 = Cipher.getInstance(cipher, "BC"); Cipher c2 = Cipher.getInstance(cipher, "BC"); // Generate static key pair KeyPair keyPair = g.generateKeyPair(); DHPublicKey pub = (DHPublicKey)keyPair.getPublic(); DHPrivateKey priv = (DHPrivateKey)keyPair.getPrivate(); // Testing with null parameters and DHAES mode off c1.init(Cipher.ENCRYPT_MODE, pub, new SecureRandom()); c2.init(Cipher.DECRYPT_MODE, priv, new SecureRandom()); out1 = c1.doFinal(message, 0, message.length); out2 = c2.doFinal(out1, 0, out1.length); if (!areEqual(out2, message)) { fail(testname + " test failed with null parameters, DHAES mode false."); } // Testing with given parameters and DHAES mode off c1.init(Cipher.ENCRYPT_MODE, pub, p, new SecureRandom()); c2.init(Cipher.DECRYPT_MODE, priv, p, new SecureRandom()); out1 = c1.doFinal(message, 0, message.length); out2 = c2.doFinal(out1, 0, out1.length); if (!areEqual(out2, message)) fail(testname + " test failed with non-null parameters, DHAES mode false."); // Testing with null parameters and DHAES mode on c1 = Cipher.getInstance(cipher + "/DHAES/PKCS7Padding","BC"); c2 = Cipher.getInstance(cipher + "/DHAES/PKCS7Padding","BC"); c1.init(Cipher.ENCRYPT_MODE, pub, new SecureRandom()); c2.init(Cipher.DECRYPT_MODE, priv, new SecureRandom()); out1 = c1.doFinal(message, 0, message.length); out2 = c2.doFinal(out1, 0, out1.length); if (!areEqual(out2, message)) fail(testname + " test failed with null parameters, DHAES mode true."); // Testing with given parameters and DHAES mode on c1 = Cipher.getInstance(cipher + "/DHAES/PKCS7Padding","BC"); c2 = Cipher.getInstance(cipher + "/DHAES/PKCS7Padding","BC"); c1.init(Cipher.ENCRYPT_MODE, pub, p, new SecureRandom()); c2.init(Cipher.DECRYPT_MODE, priv, p, new SecureRandom()); out1 = c1.doFinal(message, 0, message.length); out2 = c2.doFinal(out1, 0, out1.length); if (!areEqual(out2, message)) fail(testname + " test failed with non-null parameters, DHAES mode true."); } public static void main( String[] args) { Security.addProvider(new BouncyCastleProvider()); runTest(new DHIESTest()); } } bouncycastle-1.49.orig/test/src/org/bouncycastle/jce/provider/test/DSATest.java0000644000175000017500000010236012143620332027143 0ustar ebourgebourgpackage org.bouncycastle.jce.provider.test; import java.io.ByteArrayInputStream; import java.io.ByteArrayOutputStream; import java.io.IOException; import java.io.ObjectInputStream; import java.io.ObjectOutputStream; import java.math.BigInteger; import java.security.AlgorithmParameterGenerator; import java.security.AlgorithmParameters; import java.security.InvalidKeyException; import java.security.KeyFactory; import java.security.KeyPair; import java.security.KeyPairGenerator; import java.security.PrivateKey; import java.security.PublicKey; import java.security.SecureRandom; import java.security.Security; import java.security.Signature; import java.security.SignatureException; import java.security.interfaces.DSAPrivateKey; import java.security.interfaces.DSAPublicKey; import java.security.spec.DSAParameterSpec; import java.security.spec.PKCS8EncodedKeySpec; import java.security.spec.X509EncodedKeySpec; import org.bouncycastle.asn1.ASN1InputStream; import org.bouncycastle.asn1.ASN1Primitive; import org.bouncycastle.asn1.ASN1Sequence; import org.bouncycastle.asn1.DERInteger; import org.bouncycastle.asn1.DERObjectIdentifier; import org.bouncycastle.asn1.eac.EACObjectIdentifiers; import org.bouncycastle.asn1.teletrust.TeleTrusTObjectIdentifiers; import org.bouncycastle.asn1.x9.X9ObjectIdentifiers; import org.bouncycastle.crypto.params.DSAParameters; import org.bouncycastle.crypto.params.DSAPublicKeyParameters; import org.bouncycastle.crypto.signers.DSASigner; import org.bouncycastle.jce.interfaces.PKCS12BagAttributeCarrier; import org.bouncycastle.jce.provider.BouncyCastleProvider; import org.bouncycastle.jce.spec.ECNamedCurveGenParameterSpec; import org.bouncycastle.jce.spec.ECParameterSpec; import org.bouncycastle.jce.spec.ECPrivateKeySpec; import org.bouncycastle.jce.spec.ECPublicKeySpec; import org.bouncycastle.math.ec.ECCurve; import org.bouncycastle.util.Arrays; import org.bouncycastle.util.BigIntegers; import org.bouncycastle.util.encoders.Hex; import org.bouncycastle.util.test.FixedSecureRandom; import org.bouncycastle.util.test.SimpleTest; public class DSATest extends SimpleTest { byte[] k1 = Hex.decode("d5014e4b60ef2ba8b6211b4062ba3224e0427dd3"); byte[] k2 = Hex.decode("345e8d05c075c3a508df729a1685690e68fcfb8c8117847e89063bca1f85d968fd281540b6e13bd1af989a1fbf17e06462bf511f9d0b140fb48ac1b1baa5bded"); SecureRandom random = new FixedSecureRandom(new byte[][] { k1, k2 }); private void testCompat() throws Exception { if (Security.getProvider("SUN") == null) { return; } Signature s = Signature.getInstance("DSA", "SUN"); KeyPairGenerator g = KeyPairGenerator.getInstance("DSA", "SUN"); byte[] data = { 1, 2, 3, 4, 5, 6, 7, 8, 9, 0 }; g.initialize(512, new SecureRandom()); KeyPair p = g.generateKeyPair(); PrivateKey sKey = p.getPrivate(); PublicKey vKey = p.getPublic(); // // sign SUN - verify with BC // s.initSign(sKey); s.update(data); byte[] sigBytes = s.sign(); s = Signature.getInstance("DSA", "BC"); s.initVerify(vKey); s.update(data); if (!s.verify(sigBytes)) { fail("SUN -> BC verification failed"); } // // sign BC - verify with SUN // s.initSign(sKey); s.update(data); sigBytes = s.sign(); s = Signature.getInstance("DSA", "SUN"); s.initVerify(vKey); s.update(data); if (!s.verify(sigBytes)) { fail("BC -> SUN verification failed"); } // // key encoding test - BC decoding Sun keys // KeyFactory f = KeyFactory.getInstance("DSA", "BC"); X509EncodedKeySpec x509s = new X509EncodedKeySpec(vKey.getEncoded()); DSAPublicKey k1 = (DSAPublicKey)f.generatePublic(x509s); checkPublic(k1, vKey); PKCS8EncodedKeySpec pkcs8 = new PKCS8EncodedKeySpec(sKey.getEncoded()); DSAPrivateKey k2 = (DSAPrivateKey)f.generatePrivate(pkcs8); checkPrivateKey(k2, sKey); // // key decoding test - SUN decoding BC keys // f = KeyFactory.getInstance("DSA", "SUN"); x509s = new X509EncodedKeySpec(k1.getEncoded()); vKey = (DSAPublicKey)f.generatePublic(x509s); checkPublic(k1, vKey); pkcs8 = new PKCS8EncodedKeySpec(k2.getEncoded()); sKey = f.generatePrivate(pkcs8); checkPrivateKey(k2, sKey); } private void testNONEwithDSA() throws Exception { byte[] dummySha1 = Hex.decode("01020304050607080910111213141516"); KeyPairGenerator kpGen = KeyPairGenerator.getInstance("DSA", "BC"); kpGen.initialize(512); KeyPair kp = kpGen.generateKeyPair(); Signature sig = Signature.getInstance("NONEwithDSA", "BC"); sig.initSign(kp.getPrivate()); sig.update(dummySha1); byte[] sigBytes = sig.sign(); sig.initVerify(kp.getPublic()); sig.update(dummySha1); sig.verify(sigBytes); // reset test sig.update(dummySha1); if (!sig.verify(sigBytes)) { fail("NONEwithDSA failed to reset"); } // lightweight test DSAPublicKey key = (DSAPublicKey)kp.getPublic(); DSAParameters params = new DSAParameters(key.getParams().getP(), key.getParams().getQ(), key.getParams().getG()); DSAPublicKeyParameters keyParams = new DSAPublicKeyParameters(key.getY(), params); DSASigner signer = new DSASigner(); ASN1Sequence derSig = ASN1Sequence.getInstance(ASN1Primitive.fromByteArray(sigBytes)); signer.init(false, keyParams); if (!signer.verifySignature(dummySha1, DERInteger.getInstance(derSig.getObjectAt(0)).getValue(), DERInteger.getInstance(derSig.getObjectAt(1)).getValue())) { fail("NONEwithDSA not really NONE!"); } } private void checkPublic(DSAPublicKey k1, PublicKey vKey) { if (!k1.getY().equals(((DSAPublicKey)vKey).getY())) { fail("public number not decoded properly"); } if (!k1.getParams().getG().equals(((DSAPublicKey)vKey).getParams().getG())) { fail("public generator not decoded properly"); } if (!k1.getParams().getP().equals(((DSAPublicKey)vKey).getParams().getP())) { fail("public p value not decoded properly"); } if (!k1.getParams().getQ().equals(((DSAPublicKey)vKey).getParams().getQ())) { fail("public q value not decoded properly"); } } private void checkPrivateKey(DSAPrivateKey k2, PrivateKey sKey) { if (!k2.getX().equals(((DSAPrivateKey)sKey).getX())) { fail("private number not decoded properly"); } if (!k2.getParams().getG().equals(((DSAPrivateKey)sKey).getParams().getG())) { fail("private generator not decoded properly"); } if (!k2.getParams().getP().equals(((DSAPrivateKey)sKey).getParams().getP())) { fail("private p value not decoded properly"); } if (!k2.getParams().getQ().equals(((DSAPrivateKey)sKey).getParams().getQ())) { fail("private q value not decoded properly"); } } private Object serializeDeserialize(Object o) throws Exception { ByteArrayOutputStream bOut = new ByteArrayOutputStream(); ObjectOutputStream oOut = new ObjectOutputStream(bOut); oOut.writeObject(o); oOut.close(); ObjectInputStream oIn = new ObjectInputStream(new ByteArrayInputStream(bOut.toByteArray())); return oIn.readObject(); } /** * X9.62 - 1998,
    * J.3.2, Page 155, ECDSA over the field Fp
    * an example with 239 bit prime */ private void testECDSA239bitPrime() throws Exception { BigInteger r = new BigInteger("308636143175167811492622547300668018854959378758531778147462058306432176"); BigInteger s = new BigInteger("323813553209797357708078776831250505931891051755007842781978505179448783"); byte[] kData = BigIntegers.asUnsignedByteArray(new BigInteger("700000017569056646655505781757157107570501575775705779575555657156756655")); SecureRandom k = new FixedSecureRandom(kData); ECCurve curve = new ECCurve.Fp( new BigInteger("883423532389192164791648750360308885314476597252960362792450860609699839"), // q new BigInteger("7fffffffffffffffffffffff7fffffffffff8000000000007ffffffffffc", 16), // a new BigInteger("6b016c3bdcf18941d0d654921475ca71a9db2fb27d1d37796185c2942c0a", 16)); // b ECParameterSpec spec = new ECParameterSpec( curve, curve.decodePoint(Hex.decode("020ffa963cdca8816ccc33b8642bedf905c3d358573d3f27fbbd3b3cb9aaaf")), // G new BigInteger("883423532389192164791648750360308884807550341691627752275345424702807307")); // n ECPrivateKeySpec priKey = new ECPrivateKeySpec( new BigInteger("876300101507107567501066130761671078357010671067781776716671676178726717"), // d spec); ECPublicKeySpec pubKey = new ECPublicKeySpec( curve.decodePoint(Hex.decode("025b6dc53bc61a2548ffb0f671472de6c9521a9d2d2534e65abfcbd5fe0c70")), // Q spec); Signature sgr = Signature.getInstance("ECDSA", "BC"); KeyFactory f = KeyFactory.getInstance("ECDSA", "BC"); PrivateKey sKey = f.generatePrivate(priKey); PublicKey vKey = f.generatePublic(pubKey); sgr.initSign(sKey, k); byte[] message = new byte[] { (byte)'a', (byte)'b', (byte)'c' }; sgr.update(message); byte[] sigBytes = sgr.sign(); sgr.initVerify(vKey); sgr.update(message); if (!sgr.verify(sigBytes)) { fail("239 Bit EC verification failed"); } BigInteger[] sig = derDecode(sigBytes); if (!r.equals(sig[0])) { fail("r component wrong." + System.getProperty("line.separator") + " expecting: " + r + System.getProperty("line.separator") + " got : " + sig[0]); } if (!s.equals(sig[1])) { fail("s component wrong." + System.getProperty("line.separator") + " expecting: " + s + System.getProperty("line.separator") + " got : " + sig[1]); } } private void testNONEwithECDSA239bitPrime() throws Exception { ECCurve curve = new ECCurve.Fp( new BigInteger("883423532389192164791648750360308885314476597252960362792450860609699839"), // q new BigInteger("7fffffffffffffffffffffff7fffffffffff8000000000007ffffffffffc", 16), // a new BigInteger("6b016c3bdcf18941d0d654921475ca71a9db2fb27d1d37796185c2942c0a", 16)); // b ECParameterSpec spec = new ECParameterSpec( curve, curve.decodePoint(Hex.decode("020ffa963cdca8816ccc33b8642bedf905c3d358573d3f27fbbd3b3cb9aaaf")), // G new BigInteger("883423532389192164791648750360308884807550341691627752275345424702807307")); // n ECPrivateKeySpec priKey = new ECPrivateKeySpec( new BigInteger("876300101507107567501066130761671078357010671067781776716671676178726717"), // d spec); ECPublicKeySpec pubKey = new ECPublicKeySpec( curve.decodePoint(Hex.decode("025b6dc53bc61a2548ffb0f671472de6c9521a9d2d2534e65abfcbd5fe0c70")), // Q spec); Signature sgr = Signature.getInstance("NONEwithECDSA", "BC"); KeyFactory f = KeyFactory.getInstance("ECDSA", "BC"); PrivateKey sKey = f.generatePrivate(priKey); PublicKey vKey = f.generatePublic(pubKey); byte[] message = "abc".getBytes(); byte[] sig = Hex.decode("3040021e2cb7f36803ebb9c427c58d8265f11fc5084747133078fc279de874fbecb0021e64cb19604be06c57e761b3de5518f71de0f6e0cd2df677cec8a6ffcb690d"); checkMessage(sgr, sKey, vKey, message, sig); message = "abcdefghijklmnopqrstuvwxyz".getBytes(); sig = Hex.decode("3040021e2cb7f36803ebb9c427c58d8265f11fc5084747133078fc279de874fbecb0021e43fd65b3363d76aabef8630572257dbb67c82818ad9fad31256539b1b02c"); checkMessage(sgr, sKey, vKey, message, sig); message = "a very very long message gauranteed to cause an overflow".getBytes(); sig = Hex.decode("3040021e2cb7f36803ebb9c427c58d8265f11fc5084747133078fc279de874fbecb0021e7d5be84b22937a1691859a3c6fe45ed30b108574431d01b34025825ec17a"); checkMessage(sgr, sKey, vKey, message, sig); } private void checkMessage(Signature sgr, PrivateKey sKey, PublicKey vKey, byte[] message, byte[] sig) throws InvalidKeyException, SignatureException { byte[] kData = BigIntegers.asUnsignedByteArray(new BigInteger("700000017569056646655505781757157107570501575775705779575555657156756655")); SecureRandom k = new FixedSecureRandom(kData); sgr.initSign(sKey, k); sgr.update(message); byte[] sigBytes = sgr.sign(); if (!Arrays.areEqual(sigBytes, sig)) { fail(new String(message) + " signature incorrect"); } sgr.initVerify(vKey); sgr.update(message); if (!sgr.verify(sigBytes)) { fail(new String(message) + " verification failed"); } } /** * X9.62 - 1998,
    * J.2.1, Page 100, ECDSA over the field F2m
    * an example with 191 bit binary field */ private void testECDSA239bitBinary() throws Exception { BigInteger r = new BigInteger("21596333210419611985018340039034612628818151486841789642455876922391552"); BigInteger s = new BigInteger("197030374000731686738334997654997227052849804072198819102649413465737174"); byte[] kData = BigIntegers.asUnsignedByteArray(new BigInteger("171278725565216523967285789236956265265265235675811949404040041670216363")); SecureRandom k = new FixedSecureRandom(kData); ECCurve curve = new ECCurve.F2m( 239, // m 36, // k new BigInteger("32010857077C5431123A46B808906756F543423E8D27877578125778AC76", 16), // a new BigInteger("790408F2EEDAF392B012EDEFB3392F30F4327C0CA3F31FC383C422AA8C16", 16)); // b ECParameterSpec params = new ECParameterSpec( curve, curve.decodePoint(Hex.decode("0457927098FA932E7C0A96D3FD5B706EF7E5F5C156E16B7E7C86038552E91D61D8EE5077C33FECF6F1A16B268DE469C3C7744EA9A971649FC7A9616305")), // G new BigInteger("220855883097298041197912187592864814557886993776713230936715041207411783"), // n BigInteger.valueOf(4)); // h ECPrivateKeySpec priKeySpec = new ECPrivateKeySpec( new BigInteger("145642755521911534651321230007534120304391871461646461466464667494947990"), // d params); ECPublicKeySpec pubKeySpec = new ECPublicKeySpec( curve.decodePoint(Hex.decode("045894609CCECF9A92533F630DE713A958E96C97CCB8F5ABB5A688A238DEED6DC2D9D0C94EBFB7D526BA6A61764175B99CB6011E2047F9F067293F57F5")), // Q params); Signature sgr = Signature.getInstance("ECDSA", "BC"); KeyFactory f = KeyFactory.getInstance("ECDSA", "BC"); PrivateKey sKey = f.generatePrivate(priKeySpec); PublicKey vKey = f.generatePublic(pubKeySpec); byte[] message = new byte[] { (byte)'a', (byte)'b', (byte)'c' }; sgr.initSign(sKey, k); sgr.update(message); byte[] sigBytes = sgr.sign(); sgr.initVerify(vKey); sgr.update(message); if (!sgr.verify(sigBytes)) { fail("239 Bit EC verification failed"); } BigInteger[] sig = derDecode(sigBytes); if (!r.equals(sig[0])) { fail("r component wrong." + System.getProperty("line.separator") + " expecting: " + r + System.getProperty("line.separator") + " got : " + sig[0]); } if (!s.equals(sig[1])) { fail("s component wrong." + System.getProperty("line.separator") + " expecting: " + s + System.getProperty("line.separator") + " got : " + sig[1]); } } private void testECDSA239bitBinary(String algorithm, DERObjectIdentifier oid) throws Exception { byte[] kData = BigIntegers.asUnsignedByteArray(new BigInteger("171278725565216523967285789236956265265265235675811949404040041670216363")); SecureRandom k = new FixedSecureRandom(kData); ECCurve curve = new ECCurve.F2m( 239, // m 36, // k new BigInteger("32010857077C5431123A46B808906756F543423E8D27877578125778AC76", 16), // a new BigInteger("790408F2EEDAF392B012EDEFB3392F30F4327C0CA3F31FC383C422AA8C16", 16)); // b ECParameterSpec params = new ECParameterSpec( curve, curve.decodePoint(Hex.decode("0457927098FA932E7C0A96D3FD5B706EF7E5F5C156E16B7E7C86038552E91D61D8EE5077C33FECF6F1A16B268DE469C3C7744EA9A971649FC7A9616305")), // G new BigInteger("220855883097298041197912187592864814557886993776713230936715041207411783"), // n BigInteger.valueOf(4)); // h ECPrivateKeySpec priKeySpec = new ECPrivateKeySpec( new BigInteger("145642755521911534651321230007534120304391871461646461466464667494947990"), // d params); ECPublicKeySpec pubKeySpec = new ECPublicKeySpec( curve.decodePoint(Hex.decode("045894609CCECF9A92533F630DE713A958E96C97CCB8F5ABB5A688A238DEED6DC2D9D0C94EBFB7D526BA6A61764175B99CB6011E2047F9F067293F57F5")), // Q params); Signature sgr = Signature.getInstance(algorithm, "BC"); KeyFactory f = KeyFactory.getInstance("ECDSA", "BC"); PrivateKey sKey = f.generatePrivate(priKeySpec); PublicKey vKey = f.generatePublic(pubKeySpec); byte[] message = new byte[] { (byte)'a', (byte)'b', (byte)'c' }; sgr.initSign(sKey, k); sgr.update(message); byte[] sigBytes = sgr.sign(); sgr = Signature.getInstance(oid.getId(), "BC"); sgr.initVerify(vKey); sgr.update(message); if (!sgr.verify(sigBytes)) { fail("239 Bit EC RIPEMD160 verification failed"); } } private void testGeneration() throws Exception { Signature s = Signature.getInstance("DSA", "BC"); KeyPairGenerator g = KeyPairGenerator.getInstance("DSA", "BC"); byte[] data = { 1, 2, 3, 4, 5, 6, 7, 8, 9, 0 }; // test exception // try { g.initialize(513, new SecureRandom()); fail("illegal parameter 513 check failed."); } catch (IllegalArgumentException e) { // expected } try { g.initialize(510, new SecureRandom()); fail("illegal parameter 510 check failed."); } catch (IllegalArgumentException e) { // expected } try { g.initialize(1025, new SecureRandom()); fail("illegal parameter 1025 check failed."); } catch (IllegalArgumentException e) { // expected } g.initialize(512, new SecureRandom()); KeyPair p = g.generateKeyPair(); PrivateKey sKey = p.getPrivate(); PublicKey vKey = p.getPublic(); s.initSign(sKey); s.update(data); byte[] sigBytes = s.sign(); s = Signature.getInstance("DSA", "BC"); s.initVerify(vKey); s.update(data); if (!s.verify(sigBytes)) { fail("DSA verification failed"); } // // key decoding test - serialisation test // DSAPublicKey k1 = (DSAPublicKey)serializeDeserialize(vKey); checkPublic(k1, vKey); checkEquals(k1, vKey); DSAPrivateKey k2 = (DSAPrivateKey)serializeDeserialize(sKey); checkPrivateKey(k2, sKey); checkEquals(k2, sKey); if (!(k2 instanceof PKCS12BagAttributeCarrier)) { fail("private key not implementing PKCS12 attribute carrier"); } // // ECDSA Fp generation test // s = Signature.getInstance("ECDSA", "BC"); g = KeyPairGenerator.getInstance("ECDSA", "BC"); ECCurve curve = new ECCurve.Fp( new BigInteger("883423532389192164791648750360308885314476597252960362792450860609699839"), // q new BigInteger("7fffffffffffffffffffffff7fffffffffff8000000000007ffffffffffc", 16), // a new BigInteger("6b016c3bdcf18941d0d654921475ca71a9db2fb27d1d37796185c2942c0a", 16)); // b ECParameterSpec ecSpec = new ECParameterSpec( curve, curve.decodePoint(Hex.decode("020ffa963cdca8816ccc33b8642bedf905c3d358573d3f27fbbd3b3cb9aaaf")), // G new BigInteger("883423532389192164791648750360308884807550341691627752275345424702807307")); // n g.initialize(ecSpec, new SecureRandom()); p = g.generateKeyPair(); sKey = p.getPrivate(); vKey = p.getPublic(); s.initSign(sKey); s.update(data); sigBytes = s.sign(); s = Signature.getInstance("ECDSA", "BC"); s.initVerify(vKey); s.update(data); if (!s.verify(sigBytes)) { fail("ECDSA verification failed"); } // // key decoding test - serialisation test // PublicKey eck1 = (PublicKey)serializeDeserialize(vKey); checkEquals(eck1, vKey); PrivateKey eck2 = (PrivateKey)serializeDeserialize(sKey); checkEquals(eck2, sKey); // Named curve parameter g.initialize(new ECNamedCurveGenParameterSpec("P-256"), new SecureRandom()); p = g.generateKeyPair(); sKey = p.getPrivate(); vKey = p.getPublic(); s.initSign(sKey); s.update(data); sigBytes = s.sign(); s = Signature.getInstance("ECDSA", "BC"); s.initVerify(vKey); s.update(data); if (!s.verify(sigBytes)) { fail("ECDSA verification failed"); } // // key decoding test - serialisation test // eck1 = (PublicKey)serializeDeserialize(vKey); checkEquals(eck1, vKey); eck2 = (PrivateKey)serializeDeserialize(sKey); checkEquals(eck2, sKey); // // ECDSA F2m generation test // s = Signature.getInstance("ECDSA", "BC"); g = KeyPairGenerator.getInstance("ECDSA", "BC"); curve = new ECCurve.F2m( 239, // m 36, // k new BigInteger("32010857077C5431123A46B808906756F543423E8D27877578125778AC76", 16), // a new BigInteger("790408F2EEDAF392B012EDEFB3392F30F4327C0CA3F31FC383C422AA8C16", 16)); // b ecSpec = new ECParameterSpec( curve, curve.decodePoint(Hex.decode("0457927098FA932E7C0A96D3FD5B706EF7E5F5C156E16B7E7C86038552E91D61D8EE5077C33FECF6F1A16B268DE469C3C7744EA9A971649FC7A9616305")), // G new BigInteger("220855883097298041197912187592864814557886993776713230936715041207411783"), // n BigInteger.valueOf(4)); // h g.initialize(ecSpec, new SecureRandom()); p = g.generateKeyPair(); sKey = p.getPrivate(); vKey = p.getPublic(); s.initSign(sKey); s.update(data); sigBytes = s.sign(); s = Signature.getInstance("ECDSA", "BC"); s.initVerify(vKey); s.update(data); if (!s.verify(sigBytes)) { fail("ECDSA verification failed"); } // // key decoding test - serialisation test // eck1 = (PublicKey)serializeDeserialize(vKey); checkEquals(eck1, vKey); eck2 = (PrivateKey)serializeDeserialize(sKey); checkEquals(eck2, sKey); if (!(eck2 instanceof PKCS12BagAttributeCarrier)) { fail("private key not implementing PKCS12 attribute carrier"); } } private void checkEquals(Object o1, Object o2) { if (!o1.equals(o2)) { fail("comparison test failed"); } if (o1.hashCode() != o2.hashCode()) { fail("hashCode test failed"); } } private void testParameters() throws Exception { AlgorithmParameterGenerator a = AlgorithmParameterGenerator.getInstance("DSA", "BC"); a.init(512, random); AlgorithmParameters params = a.generateParameters(); byte[] encodeParams = params.getEncoded(); AlgorithmParameters a2 = AlgorithmParameters.getInstance("DSA", "BC"); a2.init(encodeParams); // a and a2 should be equivalent! byte[] encodeParams_2 = a2.getEncoded(); if (!areEqual(encodeParams, encodeParams_2)) { fail("encode/decode parameters failed"); } DSAParameterSpec dsaP = (DSAParameterSpec)params.getParameterSpec(DSAParameterSpec.class); KeyPairGenerator g = KeyPairGenerator.getInstance("DSA", "BC"); g.initialize(dsaP, new SecureRandom()); KeyPair p = g.generateKeyPair(); PrivateKey sKey = p.getPrivate(); PublicKey vKey = p.getPublic(); Signature s = Signature.getInstance("DSA", "BC"); byte[] data = { 1, 2, 3, 4, 5, 6, 7, 8, 9, 0 }; s.initSign(sKey); s.update(data); byte[] sigBytes = s.sign(); s = Signature.getInstance("DSA", "BC"); s.initVerify(vKey); s.update(data); if (!s.verify(sigBytes)) { fail("DSA verification failed"); } } private void testDSA2Parameters() throws Exception { byte[] seed = Hex.decode("4783081972865EA95D43318AB2EAF9C61A2FC7BBF1B772A09017BDF5A58F4FF0"); AlgorithmParameterGenerator a = AlgorithmParameterGenerator.getInstance("DSA", "BC"); a.init(2048, new DSATestSecureRandom(seed)); AlgorithmParameters params = a.generateParameters(); DSAParameterSpec dsaP = (DSAParameterSpec)params.getParameterSpec(DSAParameterSpec.class); if (!dsaP.getQ().equals(new BigInteger("C24ED361870B61E0D367F008F99F8A1F75525889C89DB1B673C45AF5867CB467", 16))) { fail("Q incorrect"); } if (!dsaP.getP().equals(new BigInteger( "F56C2A7D366E3EBDEAA1891FD2A0D099" + "436438A673FED4D75F594959CFFEBCA7BE0FC72E4FE67D91" + "D801CBA0693AC4ED9E411B41D19E2FD1699C4390AD27D94C" + "69C0B143F1DC88932CFE2310C886412047BD9B1C7A67F8A2" + "5909132627F51A0C866877E672E555342BDF9355347DBD43" + "B47156B2C20BAD9D2B071BC2FDCF9757F75C168C5D9FC431" + "31BE162A0756D1BDEC2CA0EB0E3B018A8B38D3EF2487782A" + "EB9FBF99D8B30499C55E4F61E5C7DCEE2A2BB55BD7F75FCD" + "F00E48F2E8356BDB59D86114028F67B8E07B127744778AFF" + "1CF1399A4D679D92FDE7D941C5C85C5D7BFF91BA69F9489D" + "531D1EBFA727CFDA651390F8021719FA9F7216CEB177BD75", 16))) { fail("P incorrect"); } if (!dsaP.getG().equals(new BigInteger( "8DC6CC814CAE4A1C05A3E186A6FE27EA" + "BA8CDB133FDCE14A963A92E809790CBA096EAA26140550C1" + "29FA2B98C16E84236AA33BF919CD6F587E048C52666576DB" + "6E925C6CBE9B9EC5C16020F9A44C9F1C8F7A8E611C1F6EC2" + "513EA6AA0B8D0F72FED73CA37DF240DB57BBB27431D61869" + "7B9E771B0B301D5DF05955425061A30DC6D33BB6D2A32BD0" + "A75A0A71D2184F506372ABF84A56AEEEA8EB693BF29A6403" + "45FA1298A16E85421B2208D00068A5A42915F82CF0B858C8" + "FA39D43D704B6927E0B2F916304E86FB6A1B487F07D8139E" + "428BB096C6D67A76EC0B8D4EF274B8A2CF556D279AD267CC" + "EF5AF477AFED029F485B5597739F5D0240F67C2D948A6279", 16))) { fail("G incorrect"); } KeyPairGenerator g = KeyPairGenerator.getInstance("DSA", "BC"); g.initialize(dsaP, new FixedSecureRandom(Hex.decode("0CAF2EF547EC49C4F3A6FE6DF4223A174D01F2C115D49A6F73437C29A2A8458C"))); KeyPair p = g.generateKeyPair(); DSAPrivateKey sKey = (DSAPrivateKey)p.getPrivate(); DSAPublicKey vKey = (DSAPublicKey)p.getPublic(); if (!vKey.getY().equals(new BigInteger( "2828003D7C747199143C370FDD07A286" + "1524514ACC57F63F80C38C2087C6B795B62DE1C224BF8D1D" + "1424E60CE3F5AE3F76C754A2464AF292286D873A7A30B7EA" + "CBBC75AAFDE7191D9157598CDB0B60E0C5AA3F6EBE425500" + "C611957DBF5ED35490714A42811FDCDEB19AF2AB30BEADFF" + "2907931CEE7F3B55532CFFAEB371F84F01347630EB227A41" + "9B1F3F558BC8A509D64A765D8987D493B007C4412C297CAF" + "41566E26FAEE475137EC781A0DC088A26C8804A98C23140E" + "7C936281864B99571EE95C416AA38CEEBB41FDBFF1EB1D1D" + "C97B63CE1355257627C8B0FD840DDB20ED35BE92F08C49AE" + "A5613957D7E5C7A6D5A5834B4CB069E0831753ECF65BA02B", 16))) { fail("Y value incorrect"); } if (!sKey.getX().equals( new BigInteger("0CAF2EF547EC49C4F3A6FE6DF4223A174D01F2C115D49A6F73437C29A2A8458C", 16))) { fail("X value incorrect"); } byte[] encodeParams = params.getEncoded(); AlgorithmParameters a2 = AlgorithmParameters.getInstance("DSA", "BC"); a2.init(encodeParams); // a and a2 should be equivalent! byte[] encodeParams_2 = a2.getEncoded(); if (!areEqual(encodeParams, encodeParams_2)) { fail("encode/decode parameters failed"); } Signature s = Signature.getInstance("DSA", "BC"); byte[] data = { 1, 2, 3, 4, 5, 6, 7, 8, 9, 0 }; s.initSign(sKey); s.update(data); byte[] sigBytes = s.sign(); s = Signature.getInstance("DSA", "BC"); s.initVerify(vKey); s.update(data); if (!s.verify(sigBytes)) { fail("DSA verification failed"); } } public void performTest() throws Exception { testCompat(); testNONEwithDSA(); testECDSA239bitPrime(); testNONEwithECDSA239bitPrime(); testECDSA239bitBinary(); testECDSA239bitBinary("RIPEMD160withECDSA", TeleTrusTObjectIdentifiers.ecSignWithRipemd160); testECDSA239bitBinary("SHA1withECDSA", TeleTrusTObjectIdentifiers.ecSignWithSha1); testECDSA239bitBinary("SHA224withECDSA", X9ObjectIdentifiers.ecdsa_with_SHA224); testECDSA239bitBinary("SHA256withECDSA", X9ObjectIdentifiers.ecdsa_with_SHA256); testECDSA239bitBinary("SHA384withECDSA", X9ObjectIdentifiers.ecdsa_with_SHA384); testECDSA239bitBinary("SHA512withECDSA", X9ObjectIdentifiers.ecdsa_with_SHA512); testECDSA239bitBinary("SHA1withCVC-ECDSA", EACObjectIdentifiers.id_TA_ECDSA_SHA_1); testECDSA239bitBinary("SHA224withCVC-ECDSA", EACObjectIdentifiers.id_TA_ECDSA_SHA_224); testECDSA239bitBinary("SHA256withCVC-ECDSA", EACObjectIdentifiers.id_TA_ECDSA_SHA_256); testECDSA239bitBinary("SHA384withCVC-ECDSA", EACObjectIdentifiers.id_TA_ECDSA_SHA_384); testECDSA239bitBinary("SHA512withCVC-ECDSA", EACObjectIdentifiers.id_TA_ECDSA_SHA_512); testGeneration(); testParameters(); testDSA2Parameters(); } protected BigInteger[] derDecode( byte[] encoding) throws IOException { ByteArrayInputStream bIn = new ByteArrayInputStream(encoding); ASN1InputStream aIn = new ASN1InputStream(bIn); ASN1Sequence s = (ASN1Sequence)aIn.readObject(); BigInteger[] sig = new BigInteger[2]; sig[0] = ((DERInteger)s.getObjectAt(0)).getValue(); sig[1] = ((DERInteger)s.getObjectAt(1)).getValue(); return sig; } public String getName() { return "DSA/ECDSA"; } public static void main( String[] args) { Security.addProvider(new BouncyCastleProvider()); runTest(new DSATest()); } private class DSATestSecureRandom extends FixedSecureRandom { private boolean first = true; public DSATestSecureRandom(byte[] value) { super(value); } public void nextBytes(byte[] bytes) { if (first) { super.nextBytes(bytes); first = false; } else { bytes[bytes.length - 1] = 2; } } } } bouncycastle-1.49.orig/test/src/org/bouncycastle/jce/provider/test/GMacTest.java0000644000175000017500000001027712147275200027354 0ustar ebourgebourgpackage org.bouncycastle.jce.provider.test; import java.security.NoSuchAlgorithmException; import java.security.Security; import java.util.ArrayList; import java.util.Collections; import java.util.List; import javax.crypto.Cipher; import javax.crypto.KeyGenerator; import javax.crypto.Mac; import javax.crypto.spec.IvParameterSpec; import javax.crypto.spec.SecretKeySpec; import org.bouncycastle.jce.provider.BouncyCastleProvider; import org.bouncycastle.util.Arrays; import org.bouncycastle.util.encoders.Hex; import org.bouncycastle.util.test.SimpleTest; import org.bouncycastle.util.test.TestFailedException; public class GMacTest extends SimpleTest { public String getName() { return "GMac"; } public void performTest() throws Exception { checkRegistrations(); } private void checkRegistrations() throws Exception { List missingMacs = new ArrayList(); List missingKeyGens = new ArrayList(); String[] ciphers = new String[] { "AES", "NOEKEON", "Twofish", "CAST6", "SEED", "Serpent", "RC6", "CAMELLIA" }; String[] macs = new String[] { "a52308801b32d4770c701ace9b826f12", "cf11dacaf6024a78dba76b256e23caab", "13db7c428e5a7128149b5ec782d07fac", "d13a33e78e48b274bf7d64bf9aecdb82", "d05d550054735c6e7e01b6981fc14b4e", "4a34dfe4f5410afd7c40b1e110377a73", "d9f597c96b41f641da6c83d4760f543b", "371ad8cc920c6bda2a26d8f237bd446b" }; for (int i = 0; i < ciphers.length; i++) { String cipherName = ciphers[i]; Cipher cipher; try { cipher = Cipher.getInstance(cipherName, "BC"); } catch (Exception e) { System.err.println(cipherName + ": " + e.getMessage()); continue; } int blocksize; try { blocksize = cipher.getBlockSize(); } catch (Exception e) { System.err.println(cipherName + ": " + e.getMessage()); continue; } // GCM is defined over 128 bit block ciphers if (blocksize == 16) { String macName = cipherName + "-GMAC"; String macNameAlt = cipherName + "GMAC"; // Check we have a GMAC registered for each name checkMac(macName, missingMacs, missingKeyGens, macs[i]); checkMac(macNameAlt, missingMacs, missingKeyGens, macs[i]); } } if (missingMacs.size() != 0) { fail("Did not find GMAC registrations for the following ciphers: " + missingMacs); } if (missingKeyGens.size() != 0) { fail("Did not find GMAC KeyGenerator registrations for the following macs: " + missingKeyGens); } } private void checkMac(String name, List missingMacs, List missingKeyGens, String macOutput) { try { Mac mac = Mac.getInstance(name); mac.init(new SecretKeySpec(new byte[mac.getMacLength()], mac.getAlgorithm()), new IvParameterSpec( new byte[16])); mac.update(new byte[128]); byte[] bytes = mac.doFinal(); if (!Arrays.areEqual(bytes, Hex.decode(macOutput))) { fail("wrong mac value computed for " + name); } try { KeyGenerator kg = KeyGenerator.getInstance(name); kg.generateKey(); } catch (NoSuchAlgorithmException e) { missingKeyGens.add(name); } } catch (NoSuchAlgorithmException e) { missingMacs.add(name); } catch (TestFailedException e) { throw e; } catch (Exception e) { fail("Unexpected error", e); } } public static void main(String[] args) { Security.addProvider(new BouncyCastleProvider()); runTest(new GMacTest()); } }bouncycastle-1.49.orig/test/src/org/bouncycastle/jce/provider/test/AllTests.java0000644000175000017500000000260411275654512027443 0ustar ebourgebourgpackage org.bouncycastle.jce.provider.test; import java.security.Security; import junit.framework.Test; import junit.framework.TestCase; import junit.framework.TestSuite; import org.bouncycastle.jce.provider.BouncyCastleProvider; import org.bouncycastle.jce.provider.test.rsa3.RSA3CertTest; import org.bouncycastle.util.test.SimpleTestResult; public class AllTests extends TestCase { public void testJCE() { org.bouncycastle.util.test.Test[] tests = RegressionTest.tests; for (int i = 0; i != tests.length; i++) { SimpleTestResult result = (SimpleTestResult)tests[i].perform(); if (!result.isSuccessful()) { if (result.getException() != null) { result.getException().printStackTrace(); } fail(result.toString()); } } } public static void main (String[] args) { junit.textui.TestRunner.run(suite()); } public static Test suite() { TestSuite suite = new TestSuite("JCE Tests"); if (Security.getProvider("BC") == null) { Security.addProvider(new BouncyCastleProvider()); } suite.addTestSuite(RSA3CertTest.class); suite.addTestSuite(AllTests.class); return suite; } } bouncycastle-1.49.orig/test/src/org/bouncycastle/jce/provider/test/ECDSA5Test.java0000644000175000017500000005465112070732317027457 0ustar ebourgebourgpackage org.bouncycastle.jce.provider.test; import java.io.ByteArrayInputStream; import java.io.ByteArrayOutputStream; import java.io.IOException; import java.io.ObjectInputStream; import java.io.ObjectOutputStream; import java.math.BigInteger; import java.security.InvalidAlgorithmParameterException; import java.security.InvalidKeyException; import java.security.KeyFactory; import java.security.KeyPair; import java.security.KeyPairGenerator; import java.security.PrivateKey; import java.security.PublicKey; import java.security.SecureRandom; import java.security.Security; import java.security.Signature; import java.security.interfaces.ECPrivateKey; import java.security.interfaces.ECPublicKey; import java.security.spec.ECFieldF2m; import java.security.spec.ECFieldFp; import java.security.spec.ECGenParameterSpec; import java.security.spec.ECParameterSpec; import java.security.spec.ECPoint; import java.security.spec.ECPrivateKeySpec; import java.security.spec.ECPublicKeySpec; import java.security.spec.EllipticCurve; import org.bouncycastle.asn1.ASN1InputStream; import org.bouncycastle.asn1.ASN1Primitive; import org.bouncycastle.asn1.ASN1Sequence; import org.bouncycastle.asn1.DERInteger; import org.bouncycastle.asn1.pkcs.PrivateKeyInfo; import org.bouncycastle.asn1.sec.SECObjectIdentifiers; import org.bouncycastle.asn1.teletrust.TeleTrusTObjectIdentifiers; import org.bouncycastle.asn1.x509.SubjectPublicKeyInfo; import org.bouncycastle.asn1.x9.X962Parameters; import org.bouncycastle.asn1.x9.X9ObjectIdentifiers; import org.bouncycastle.jce.ECKeyUtil; import org.bouncycastle.jce.ECPointUtil; import org.bouncycastle.jce.provider.BouncyCastleProvider; import org.bouncycastle.util.BigIntegers; import org.bouncycastle.util.encoders.Hex; import org.bouncycastle.util.test.FixedSecureRandom; import org.bouncycastle.util.test.SimpleTest; public class ECDSA5Test extends SimpleTest { byte[] k1 = Hex.decode("d5014e4b60ef2ba8b6211b4062ba3224e0427dd3"); byte[] k2 = Hex.decode("345e8d05c075c3a508df729a1685690e68fcfb8c8117847e89063bca1f85d968fd281540b6e13bd1af989a1fbf17e06462bf511f9d0b140fb48ac1b1baa5bded"); SecureRandom random = new FixedSecureRandom(new byte[][] { k1, k2 }); private void decodeTest() { EllipticCurve curve = new EllipticCurve( new ECFieldFp(new BigInteger("6277101735386680763835789423207666416083908700390324961279")), // q new BigInteger("fffffffffffffffffffffffffffffffefffffffffffffffc", 16), // a new BigInteger("64210519e59c80e70fa7e9ab72243049feb8deecc146b9b1", 16)); // b ECPoint p = ECPointUtil.decodePoint(curve, Hex.decode("03188da80eb03090f67cbf20eb43a18800f4ff0afd82ff1012")); if (!p.getAffineX().equals(new BigInteger("188da80eb03090f67cbf20eb43a18800f4ff0afd82ff1012", 16))) { fail("x uncompressed incorrectly"); } if (!p.getAffineY().equals(new BigInteger("7192b95ffc8da78631011ed6b24cdd573f977a11e794811", 16))) { fail("y uncompressed incorrectly"); } } /** * X9.62 - 1998,
    * J.3.2, Page 155, ECDSA over the field Fp
    * an example with 239 bit prime */ private void testECDSA239bitPrime() throws Exception { BigInteger r = new BigInteger("308636143175167811492622547300668018854959378758531778147462058306432176"); BigInteger s = new BigInteger("323813553209797357708078776831250505931891051755007842781978505179448783"); byte[] kData = BigIntegers.asUnsignedByteArray(new BigInteger("700000017569056646655505781757157107570501575775705779575555657156756655")); SecureRandom k = new FixedSecureRandom(kData); EllipticCurve curve = new EllipticCurve( new ECFieldFp(new BigInteger("883423532389192164791648750360308885314476597252960362792450860609699839")), // q new BigInteger("7fffffffffffffffffffffff7fffffffffff8000000000007ffffffffffc", 16), // a new BigInteger("6b016c3bdcf18941d0d654921475ca71a9db2fb27d1d37796185c2942c0a", 16)); // b ECParameterSpec spec = new ECParameterSpec( curve, ECPointUtil.decodePoint(curve, Hex.decode("020ffa963cdca8816ccc33b8642bedf905c3d358573d3f27fbbd3b3cb9aaaf")), // G new BigInteger("883423532389192164791648750360308884807550341691627752275345424702807307"), // n 1); // h ECPrivateKeySpec priKey = new ECPrivateKeySpec( new BigInteger("876300101507107567501066130761671078357010671067781776716671676178726717"), // d spec); ECPublicKeySpec pubKey = new ECPublicKeySpec( ECPointUtil.decodePoint(curve, Hex.decode("025b6dc53bc61a2548ffb0f671472de6c9521a9d2d2534e65abfcbd5fe0c70")), // Q spec); Signature sgr = Signature.getInstance("ECDSA", "BC"); KeyFactory f = KeyFactory.getInstance("ECDSA", "BC"); PrivateKey sKey = f.generatePrivate(priKey); PublicKey vKey = f.generatePublic(pubKey); sgr.initSign(sKey, k); byte[] message = new byte[] { (byte)'a', (byte)'b', (byte)'c' }; sgr.update(message); byte[] sigBytes = sgr.sign(); sgr.initVerify(vKey); sgr.update(message); if (!sgr.verify(sigBytes)) { fail("239 Bit EC verification failed"); } BigInteger[] sig = derDecode(sigBytes); if (!r.equals(sig[0])) { fail("r component wrong." + System.getProperty("line.separator") + " expecting: " + r + System.getProperty("line.separator") + " got : " + sig[0]); } if (!s.equals(sig[1])) { fail("s component wrong." + System.getProperty("line.separator") + " expecting: " + s + System.getProperty("line.separator") + " got : " + sig[1]); } } /** * X9.62 - 1998,
    * J.2.1, Page 100, ECDSA over the field F2m
    * an example with 191 bit binary field */ private void testECDSA239bitBinary() throws Exception { BigInteger r = new BigInteger("21596333210419611985018340039034612628818151486841789642455876922391552"); BigInteger s = new BigInteger("197030374000731686738334997654997227052849804072198819102649413465737174"); byte[] kData = BigIntegers.asUnsignedByteArray(new BigInteger("171278725565216523967285789236956265265265235675811949404040041670216363")); SecureRandom k = new FixedSecureRandom(kData); EllipticCurve curve = new EllipticCurve( new ECFieldF2m(239, // m new int[] { 36 }), // k new BigInteger("32010857077C5431123A46B808906756F543423E8D27877578125778AC76", 16), // a new BigInteger("790408F2EEDAF392B012EDEFB3392F30F4327C0CA3F31FC383C422AA8C16", 16)); // b ECParameterSpec params = new ECParameterSpec( curve, ECPointUtil.decodePoint(curve, Hex.decode("0457927098FA932E7C0A96D3FD5B706EF7E5F5C156E16B7E7C86038552E91D61D8EE5077C33FECF6F1A16B268DE469C3C7744EA9A971649FC7A9616305")), // G new BigInteger("220855883097298041197912187592864814557886993776713230936715041207411783"), // n 4); // h ECPrivateKeySpec priKeySpec = new ECPrivateKeySpec( new BigInteger("145642755521911534651321230007534120304391871461646461466464667494947990"), // d params); ECPublicKeySpec pubKeySpec = new ECPublicKeySpec( ECPointUtil.decodePoint(curve, Hex.decode("045894609CCECF9A92533F630DE713A958E96C97CCB8F5ABB5A688A238DEED6DC2D9D0C94EBFB7D526BA6A61764175B99CB6011E2047F9F067293F57F5")), // Q params); Signature sgr = Signature.getInstance("ECDSA", "BC"); KeyFactory f = KeyFactory.getInstance("ECDSA", "BC"); PrivateKey sKey = f.generatePrivate(priKeySpec); PublicKey vKey = f.generatePublic(pubKeySpec); byte[] message = new byte[] { (byte)'a', (byte)'b', (byte)'c' }; sgr.initSign(sKey, k); sgr.update(message); byte[] sigBytes = sgr.sign(); sgr.initVerify(vKey); sgr.update(message); if (!sgr.verify(sigBytes)) { fail("239 Bit EC verification failed"); } BigInteger[] sig = derDecode(sigBytes); if (!r.equals(sig[0])) { fail("r component wrong." + System.getProperty("line.separator") + " expecting: " + r + System.getProperty("line.separator") + " got : " + sig[0]); } if (!s.equals(sig[1])) { fail("s component wrong." + System.getProperty("line.separator") + " expecting: " + s + System.getProperty("line.separator") + " got : " + sig[1]); } } private void testGeneration() throws Exception { // // ECDSA generation test // byte[] data = { 1, 2, 3, 4, 5, 6, 7, 8, 9, 0 }; Signature s = Signature.getInstance("ECDSA", "BC"); KeyPairGenerator g = KeyPairGenerator.getInstance("ECDSA", "BC"); EllipticCurve curve = new EllipticCurve( new ECFieldFp(new BigInteger("883423532389192164791648750360308885314476597252960362792450860609699839")), // q new BigInteger("7fffffffffffffffffffffff7fffffffffff8000000000007ffffffffffc", 16), // a new BigInteger("6b016c3bdcf18941d0d654921475ca71a9db2fb27d1d37796185c2942c0a", 16)); // b ECParameterSpec ecSpec = new ECParameterSpec( curve, ECPointUtil.decodePoint(curve, Hex.decode("020ffa963cdca8816ccc33b8642bedf905c3d358573d3f27fbbd3b3cb9aaaf")), // G new BigInteger("883423532389192164791648750360308884807550341691627752275345424702807307"), // n 1); // h g.initialize(ecSpec, new SecureRandom()); KeyPair p = g.generateKeyPair(); PrivateKey sKey = p.getPrivate(); PublicKey vKey = p.getPublic(); s.initSign(sKey); s.update(data); byte[] sigBytes = s.sign(); s = Signature.getInstance("ECDSA", "BC"); s.initVerify(vKey); s.update(data); if (!s.verify(sigBytes)) { fail("ECDSA verification failed"); } testKeyFactory((ECPublicKey)vKey, (ECPrivateKey)sKey); testSerialise((ECPublicKey)vKey, (ECPrivateKey)sKey); } private void testSerialise(ECPublicKey ecPublicKey, ECPrivateKey ecPrivateKey) throws Exception { ByteArrayOutputStream bOut = new ByteArrayOutputStream(); ObjectOutputStream oOut = new ObjectOutputStream(bOut); oOut.writeObject(ecPublicKey); oOut.writeObject(ecPrivateKey); oOut.close(); ObjectInputStream oIn = new ObjectInputStream(new ByteArrayInputStream(bOut.toByteArray())); PublicKey pubKey = (PublicKey)oIn.readObject(); PrivateKey privKey = (PrivateKey)oIn.readObject(); if (!ecPublicKey.equals(pubKey)) { fail("public key serialisation check failed"); } if (!ecPrivateKey.equals(privKey)) { fail("private key serialisation check failed"); } } private void testKeyFactory(ECPublicKey pub, ECPrivateKey priv) throws Exception { KeyFactory ecFact = KeyFactory.getInstance("ECDSA"); ECPublicKeySpec pubSpec = (ECPublicKeySpec)ecFact.getKeySpec(pub, ECPublicKeySpec.class); ECPrivateKeySpec privSpec = (ECPrivateKeySpec)ecFact.getKeySpec(priv, ECPrivateKeySpec.class); if (!pubSpec.getW().equals(pub.getW()) || !pubSpec.getParams().getCurve().equals(pub.getParams().getCurve())) { fail("pubSpec not correct"); } if (!privSpec.getS().equals(priv.getS()) || !privSpec.getParams().getCurve().equals(priv.getParams().getCurve())) { fail("privSpec not correct"); } ECPublicKey pubKey = (ECPublicKey)ecFact.translateKey(pub); ECPrivateKey privKey = (ECPrivateKey)ecFact.translateKey(priv); if (!pubKey.getW().equals(pub.getW()) || !pubKey.getParams().getCurve().equals(pub.getParams().getCurve())) { fail("pubKey not correct"); } if (!privKey.getS().equals(priv.getS()) || !privKey.getParams().getCurve().equals(priv.getParams().getCurve())) { fail("privKey not correct"); } } private void testKeyConversion() throws Exception { KeyPairGenerator kpGen = KeyPairGenerator.getInstance("ECDSA", "BC"); kpGen.initialize(new ECGenParameterSpec("prime192v1")); KeyPair pair = kpGen.generateKeyPair(); PublicKey pubKey = ECKeyUtil.publicToExplicitParameters(pair.getPublic(), "BC"); SubjectPublicKeyInfo info = SubjectPublicKeyInfo.getInstance(ASN1Primitive.fromByteArray(pubKey.getEncoded())); X962Parameters params = X962Parameters.getInstance(info.getAlgorithmId().getParameters()); if (params.isNamedCurve() || params.isImplicitlyCA()) { fail("public key conversion to explicit failed"); } if (!((ECPublicKey)pair.getPublic()).getW().equals(((ECPublicKey)pubKey).getW())) { fail("public key conversion check failed"); } PrivateKey privKey = ECKeyUtil.privateToExplicitParameters(pair.getPrivate(), "BC"); PrivateKeyInfo privInfo = PrivateKeyInfo.getInstance(ASN1Primitive.fromByteArray(privKey.getEncoded())); params = X962Parameters.getInstance(privInfo.getAlgorithmId().getParameters()); if (params.isNamedCurve() || params.isImplicitlyCA()) { fail("private key conversion to explicit failed"); } if (!((ECPrivateKey)pair.getPrivate()).getS().equals(((ECPrivateKey)privKey).getS())) { fail("private key conversion check failed"); } } private void testAdaptiveKeyConversion() throws Exception { KeyPairGenerator kpGen = KeyPairGenerator.getInstance("ECDSA", "BC"); kpGen.initialize(new ECGenParameterSpec("prime192v1")); KeyPair pair = kpGen.generateKeyPair(); final PrivateKey privKey = pair.getPrivate(); final PublicKey pubKey = pair.getPublic(); Signature s = Signature.getInstance("ECDSA", "BC"); // raw interface tests s.initSign(new PrivateKey() { public String getAlgorithm() { return privKey.getAlgorithm(); } public String getFormat() { return privKey.getFormat(); } public byte[] getEncoded() { return privKey.getEncoded(); } }); s.initVerify(new PublicKey() { public String getAlgorithm() { return pubKey.getAlgorithm(); } public String getFormat() { return pubKey.getFormat(); } public byte[] getEncoded() { return pubKey.getEncoded(); } }); s.initSign(new ECPrivateKey() { public String getAlgorithm() { return privKey.getAlgorithm(); } public String getFormat() { return privKey.getFormat(); } public byte[] getEncoded() { return privKey.getEncoded(); } public BigInteger getS() { return ((ECPrivateKey)privKey).getS(); } public ECParameterSpec getParams() { return ((ECPrivateKey)privKey).getParams(); } }); s.initVerify(new ECPublicKey() { public String getAlgorithm() { return pubKey.getAlgorithm(); } public String getFormat() { return pubKey.getFormat(); } public byte[] getEncoded() { return pubKey.getEncoded(); } public ECPoint getW() { return ((ECPublicKey)pubKey).getW(); } public ECParameterSpec getParams() { return ((ECPublicKey)pubKey).getParams(); } }); try { s.initSign(new PrivateKey() { public String getAlgorithm() { return privKey.getAlgorithm(); } public String getFormat() { return privKey.getFormat(); } public byte[] getEncoded() { return null; } }); fail("no exception thrown!!!"); } catch (InvalidKeyException e) { // ignore } try { s.initVerify(new PublicKey() { public String getAlgorithm() { return pubKey.getAlgorithm(); } public String getFormat() { return pubKey.getFormat(); } public byte[] getEncoded() { return null; } }); fail("no exception thrown!!!"); } catch (InvalidKeyException e) { // ignore } // try bogus encoding try { s.initSign(new PrivateKey() { public String getAlgorithm() { return privKey.getAlgorithm(); } public String getFormat() { return privKey.getFormat(); } public byte[] getEncoded() { return new byte[20]; } }); fail("no exception thrown!!!"); } catch (InvalidKeyException e) { // ignore } try { s.initVerify(new PublicKey() { public String getAlgorithm() { return pubKey.getAlgorithm(); } public String getFormat() { return pubKey.getFormat(); } public byte[] getEncoded() { return new byte[20]; } }); fail("no exception thrown!!!"); } catch (InvalidKeyException e) { // ignore } // try encoding of wrong key kpGen = KeyPairGenerator.getInstance("RSA", "BC"); kpGen.initialize(512); pair = kpGen.generateKeyPair(); final PrivateKey privRsa = pair.getPrivate(); final PublicKey pubRsa = pair.getPublic(); try { s.initSign(new PrivateKey() { public String getAlgorithm() { return privRsa.getAlgorithm(); } public String getFormat() { return privRsa.getFormat(); } public byte[] getEncoded() { return privRsa.getEncoded(); } }); fail("no exception thrown!!!"); } catch (InvalidKeyException e) { // ignore } try { s.initVerify(new PublicKey() { public String getAlgorithm() { return pubRsa.getAlgorithm(); } public String getFormat() { return pubRsa.getFormat(); } public byte[] getEncoded() { return pubRsa.getEncoded(); } }); fail("no exception thrown!!!"); } catch (InvalidKeyException e) { // ignore } } private void testKeyPairGenerationWithOIDs() throws Exception { KeyPairGenerator kpGen = KeyPairGenerator.getInstance("ECDSA", "BC"); kpGen.initialize(new ECGenParameterSpec(X9ObjectIdentifiers.prime192v1.getId())); kpGen.initialize(new ECGenParameterSpec(TeleTrusTObjectIdentifiers.brainpoolP160r1.getId())); kpGen.initialize(new ECGenParameterSpec(SECObjectIdentifiers.secp128r1.getId())); try { kpGen.initialize(new ECGenParameterSpec("1.1")); fail("non-existant curve OID failed"); } catch (InvalidAlgorithmParameterException e) { if (!"unknown curve OID: 1.1".equals(e.getMessage())) { fail("OID message check failed"); } } try { kpGen.initialize(new ECGenParameterSpec("flibble")); fail("non-existant curve name failed"); } catch (InvalidAlgorithmParameterException e) { if (!"unknown curve name: flibble".equals(e.getMessage())) { fail("name message check failed"); } } } protected BigInteger[] derDecode( byte[] encoding) throws IOException { ByteArrayInputStream bIn = new ByteArrayInputStream(encoding); ASN1InputStream aIn = new ASN1InputStream(bIn); ASN1Sequence s = (ASN1Sequence)aIn.readObject(); BigInteger[] sig = new BigInteger[2]; sig[0] = ((DERInteger)s.getObjectAt(0)).getValue(); sig[1] = ((DERInteger)s.getObjectAt(1)).getValue(); return sig; } public String getName() { return "ECDSA5"; } public void performTest() throws Exception { testKeyConversion(); testAdaptiveKeyConversion(); decodeTest(); testECDSA239bitPrime(); testECDSA239bitBinary(); testGeneration(); testKeyPairGenerationWithOIDs(); } public static void main( String[] args) { Security.addProvider(new BouncyCastleProvider()); runTest(new ECDSA5Test()); } } bouncycastle-1.49.orig/test/src/org/bouncycastle/jce/provider/test/SealedTest.java0000644000175000017500000000433110330633061027727 0ustar ebourgebourg package org.bouncycastle.jce.provider.test; import java.security.Key; import java.security.Security; import javax.crypto.Cipher; import javax.crypto.KeyGenerator; import javax.crypto.SealedObject; import org.bouncycastle.jce.provider.BouncyCastleProvider; import org.bouncycastle.util.test.SimpleTestResult; import org.bouncycastle.util.test.Test; import org.bouncycastle.util.test.TestResult; public class SealedTest implements Test { final static String provider = "BC"; public String getName() { return "SealedObject"; } public TestResult perform() { try { KeyGenerator keyGen = KeyGenerator.getInstance("DES", provider); Key key = keyGen.generateKey(); Cipher c = Cipher.getInstance("DES/ECB/PKCS5Padding", provider); c.init(Cipher.ENCRYPT_MODE, key); String object = "Hello world"; SealedObject so = new SealedObject(object, c); c.init(Cipher.DECRYPT_MODE, key); Object o = so.getObject(c); if (!o.equals(object)) { return new SimpleTestResult(false, "Result object 1 not equal" + "orig: " + object + " res: " + o); } o = so.getObject(key); if (!o.equals(object)) { return new SimpleTestResult(false, "Result object 2 not equal" + "orig: " + object + " res: " + o); } o = so.getObject(key, provider); if (!o.equals(object)) { return new SimpleTestResult(false, "Result object 3 not equal" + "orig: " + object + " res: " + o); } return new SimpleTestResult(true, getName() + ": Okay"); } catch (Exception e) { return new SimpleTestResult(false, getName() + ": failed excpetion - " + e.toString(), e); } } public static void main(String[] args) { Security.addProvider(new BouncyCastleProvider()); Test test = new SealedTest(); TestResult result = test.perform(); System.out.println(result.toString()); } } bouncycastle-1.49.orig/test/src/org/bouncycastle/jce/provider/test/SigTest.java0000644000175000017500000002155210766577251027305 0ustar ebourgebourgpackage org.bouncycastle.jce.provider.test; import java.math.BigInteger; import java.security.KeyFactory; import java.security.KeyPair; import java.security.KeyPairGenerator; import java.security.MessageDigest; import java.security.PrivateKey; import java.security.PublicKey; import java.security.SecureRandom; import java.security.Security; import java.security.Signature; import java.security.spec.RSAPrivateKeySpec; import java.security.spec.RSAPublicKeySpec; import javax.crypto.Cipher; import org.bouncycastle.jce.provider.BouncyCastleProvider; import org.bouncycastle.util.Arrays; import org.bouncycastle.util.encoders.Hex; import org.bouncycastle.util.test.SimpleTest; public class SigTest extends SimpleTest { /** * signature with a "forged signature" (sig block not at end of plain text) */ private void testBadSig(PrivateKey priv, PublicKey pub) throws Exception { MessageDigest sha1 = MessageDigest.getInstance("SHA1", "BC"); Cipher signer = Cipher.getInstance("RSA/ECB/PKCS1Padding", "BC"); signer.init(Cipher.ENCRYPT_MODE, priv); byte[] block = new byte[signer.getBlockSize()]; sha1.update((byte)0); byte[] sigHeader = Hex.decode("3021300906052b0e03021a05000414"); System.arraycopy(sigHeader, 0, block, 0, sigHeader.length); byte[] dig = sha1.digest(); System.arraycopy(dig, 0, block, sigHeader.length, dig.length); System.arraycopy(sigHeader, 0, block, sigHeader.length + dig.length, sigHeader.length); byte[] sig = signer.doFinal(block); Signature verifier = Signature.getInstance("SHA1WithRSA", "BC"); verifier.initVerify(pub); verifier.update((byte)0); if (verifier.verify(sig)) { fail("bad signature passed"); } } public void performTest() throws Exception { Signature sig = Signature.getInstance("SHA1WithRSAEncryption", "BC"); KeyPairGenerator fact; KeyPair keyPair; byte[] data = { 1, 2, 3, 4, 5, 6, 7, 8, 9, 0 }; fact = KeyPairGenerator.getInstance("RSA", "BC"); fact.initialize(768, new SecureRandom()); keyPair = fact.generateKeyPair(); PrivateKey signingKey = keyPair.getPrivate(); PublicKey verifyKey = keyPair.getPublic(); testBadSig(signingKey, verifyKey); sig.initSign(signingKey); sig.update(data); byte[] sigBytes = sig.sign(); sig.initVerify(verifyKey); sig.update(data); if (!sig.verify(sigBytes)) { fail("SHA1 verification failed"); } sig = Signature.getInstance("MD2WithRSAEncryption", "BC"); sig.initSign(signingKey); sig.update(data); sigBytes = sig.sign(); sig.initVerify(verifyKey); sig.update(data); if (!sig.verify(sigBytes)) { fail("MD2 verification failed"); } sig = Signature.getInstance("MD5WithRSAEncryption", "BC"); sig.initSign(signingKey); sig.update(data); sigBytes = sig.sign(); sig.initVerify(verifyKey); sig.update(data); if (!sig.verify(sigBytes)) { fail("MD5 verification failed"); } sig = Signature.getInstance("RIPEMD160WithRSAEncryption", "BC"); sig.initSign(signingKey); sig.update(data); sigBytes = sig.sign(); sig.initVerify(verifyKey); sig.update(data); if (!sig.verify(sigBytes)) { fail("RIPEMD160 verification failed"); } // // RIPEMD-128 // sig = Signature.getInstance("RIPEMD128WithRSAEncryption", "BC"); sig.initSign(signingKey); sig.update(data); sigBytes = sig.sign(); sig.initVerify(verifyKey); sig.update(data); if (!sig.verify(sigBytes)) { fail("RIPEMD128 verification failed"); } // // RIPEMD256 // sig = Signature.getInstance("RIPEMD256WithRSAEncryption", "BC"); sig.initSign(signingKey); sig.update(data); sigBytes = sig.sign(); sig.initVerify(verifyKey); sig.update(data); if (!sig.verify(sigBytes)) { fail("RIPEMD256 verification failed"); } // // SHA-224 // sig = Signature.getInstance("SHA224WithRSAEncryption", "BC"); sig.initSign(signingKey); sig.update(data); sigBytes = sig.sign(); sig.initVerify(verifyKey); sig.update(data); if (!sig.verify(sigBytes)) { fail("SHA224 verification failed"); } // // SHA-256 // sig = Signature.getInstance("SHA256WithRSAEncryption", "BC"); sig.initSign(signingKey); sig.update(data); sigBytes = sig.sign(); sig.initVerify(verifyKey); sig.update(data); if (!sig.verify(sigBytes)) { fail("SHA256 verification failed"); } // // SHA-384 // sig = Signature.getInstance("SHA384WithRSAEncryption", "BC"); sig.initSign(signingKey); sig.update(data); sigBytes = sig.sign(); sig.initVerify(verifyKey); sig.update(data); if (!sig.verify(sigBytes)) { fail("SHA384 verification failed"); } // // SHA-512 // sig = Signature.getInstance("SHA512WithRSAEncryption", "BC"); sig.initSign(signingKey); sig.update(data); sigBytes = sig.sign(); sig.initVerify(verifyKey); sig.update(data); if (!sig.verify(sigBytes)) { fail("SHA512 verification failed"); } // // ISO Sigs. // sig = Signature.getInstance("MD5WithRSA/ISO9796-2", "BC"); sig.initSign(signingKey); sig.update(data); sigBytes = sig.sign(); sig.initVerify(verifyKey); sig.update(data); if (!sig.verify(sigBytes)) { fail("MD5/ISO verification failed"); } sig = Signature.getInstance("SHA1WithRSA/ISO9796-2", "BC"); sig.initSign(signingKey); sig.update(data); sigBytes = sig.sign(); sig.initVerify(verifyKey); sig.update(data); if (!sig.verify(sigBytes)) { fail("SHA1/ISO verification failed"); } sig = Signature.getInstance("RIPEMD160WithRSA/ISO9796-2", "BC"); sig.initSign(signingKey); sig.update(data); sigBytes = sig.sign(); sig.initVerify(verifyKey); sig.update(data); if (!sig.verify(sigBytes)) { fail("RIPEMD160/ISO verification failed"); } // // standard vector test - B.1.3 RIPEMD160, implicit. // BigInteger mod = new BigInteger("ffffffff78f6c55506c59785e871211ee120b0b5dd644aa796d82413a47b24573f1be5745b5cd9950f6b389b52350d4e01e90009669a8720bf265a2865994190a661dea3c7828e2e7ca1b19651adc2d5", 16); BigInteger pub = new BigInteger("03", 16); BigInteger pri = new BigInteger("2aaaaaaa942920e38120ee965168302fd0301d73a4e60c7143ceb0adf0bf30b9352f50e8b9e4ceedd65343b2179005b2f099915e4b0c37e41314bb0821ad8330d23cba7f589e0f129b04c46b67dfce9d", 16); KeyFactory f = KeyFactory.getInstance("RSA", "BC"); PrivateKey privKey = f.generatePrivate(new RSAPrivateKeySpec(mod, pri)); PublicKey pubKey = f.generatePublic(new RSAPublicKeySpec(mod, pub)); byte[] testSig = Hex.decode("5cf9a01854dbacaec83aae8efc563d74538192e95466babacd361d7c86000fe42dcb4581e48e4feb862d04698da9203b1803b262105104d510b365ee9c660857ba1c001aa57abfd1c8de92e47c275cae"); data = Hex.decode("fedcba9876543210fedcba9876543210fedcba9876543210fedcba9876543210fedcba9876543210fedcba9876543210fedcba9876543210fedcba9876543210fedcba9876543210fedcba9876543210fedcba9876543210fedcba9876543210fedcba9876543210fedcba9876543210"); sig = Signature.getInstance("RIPEMD160WithRSA/ISO9796-2", "BC"); sig.initSign(privKey); sig.update(data); sigBytes = sig.sign(); if (!Arrays.areEqual(testSig, sigBytes)) { fail("SigTest: failed ISO9796-2 generation Test"); } sig.initVerify(pubKey); sig.update(data); if (!sig.verify(sigBytes)) { fail("RIPEMD160/ISO verification failed"); } } public String getName() { return "SigTest"; } public static void main( String[] args) { Security.addProvider(new BouncyCastleProvider()); runTest(new SigTest()); } } bouncycastle-1.49.orig/test/src/org/bouncycastle/jce/provider/test/PKIXNameConstraintsTest.java0000644000175000017500000004450011737273326032360 0ustar ebourgebourgpackage org.bouncycastle.jce.provider.test; import org.bouncycastle.asn1.DEROctetString; import org.bouncycastle.asn1.x509.GeneralName; import org.bouncycastle.asn1.x509.GeneralSubtree; import org.bouncycastle.jce.provider.PKIXNameConstraintValidator; import org.bouncycastle.jce.provider.PKIXNameConstraintValidatorException; import org.bouncycastle.util.test.SimpleTest; /** * Test class for {@link PKIXNameConstraintValidator}. *

    * The field testXYZ is the name to test. *

    * The field testXYZIsConstraint must be tested if it is permitted and excluded. *

    * The field testXYZIsNotConstraint must be tested if it is not permitted and * not excluded. *

    * Furthermore there are tests for the intersection and union of test names. * */ public class PKIXNameConstraintsTest extends SimpleTest { private final static String testEmail = "test@abc.test.com"; private final static String testEmailIsConstraint[] = { "test@abc.test.com", "abc.test.com", ".test.com" }; private final static String testEmailIsNotConstraint[] = { ".abc.test.com", "www.test.com", "test1@abc.test.com", "bc.test.com" }; private final static String email1[] = { "test@test.com", "test@test.com", "test@test.com", "test@abc.test.com", "test@test.com", "test@test.com", ".test.com", ".test.com", ".test.com", ".test.com", "test.com", "abc.test.com", "abc.test1.com", "test.com", "test.com", ".test.com" }; private final static String email2[] = { "test@test.abc.com", "test@test.com", ".test.com", ".test.com", "test.com", "test1.com", "test@test.com", ".test.com", ".test1.com", "test.com", "test.com", ".test.com", ".test.com", "test1.com", ".test.com", "abc.test.com" }; private final static String emailintersect[] = { null, "test@test.com", null, "test@abc.test.com", "test@test.com", null, null, ".test.com", null, null, "test.com", "abc.test.com", null, null, null, "abc.test.com" }; private final static String emailunion[][] = { { "test@test.com", "test@test.abc.com" }, { "test@test.com" }, { "test@test.com", ".test.com" }, { ".test.com" }, { "test.com" }, { "test@test.com", "test1.com" }, { ".test.com", "test@test.com" }, { ".test.com" }, { ".test.com", ".test1.com" }, { ".test.com", "test.com" }, { "test.com" }, { ".test.com" }, { ".test.com", "abc.test1.com" }, { "test1.com", "test.com" }, { ".test.com", "test.com" }, { ".test.com" } }; private final static String[] dn1 = { "O=test org, OU=test org unit, CN=John Doe" }; private final static String[] dn2 = { "O=test org, OU=test org unit" }; private final static String[][] dnUnion = { { "O=test org, OU=test org unit" } }; private final static String[] dnIntersection = { "O=test org, OU=test org unit, CN=John Doe" }; private final static String testDN = "O=test org, OU=test org unit, CN=John Doe"; private final static String testDNIsConstraint[] = { "O=test org, OU=test org unit", "O=test org, OU=test org unit, CN=John Doe" }; private final static String testDNIsNotConstraint[] = { "O=test org, OU=test org unit, CN=John Doe2", "O=test org, OU=test org unit2", "OU=test org unit, O=test org, CN=John Doe", "O=test org, OU=test org unit, CN=John Doe, L=USA" }; private final static String testDNS = "abc.test.com"; private final static String testDNSIsConstraint[] = { "test.com", "abc.test.com", "test.com" }; private final static String testDNSIsNotConstraint[] = { "wwww.test.com", "ww.test.com", "www.test.com" }; private final static String dns1[] = { "www.test.de", "www.test1.de", "www.test.de" }; private final static String dns2[] = { "test.de", "www.test.de", "www.test.de" }; private final static String dnsintersect[] = { "www.test.de", null, null }; private final static String dnsunion[][] = { { "test.de" }, { "www.test1.de", "www.test.de" }, { "www.test.de" } }; private final static String testURI = "http://karsten:password@abc.test.com:8080"; private final static String testURIIsConstraint[] = { "abc.test.com", ".test.com" }; private final static String testURIIsNotConstraint[] = { "xyz.test.com", ".abc.test.com" }; private final static String uri1[] = { "www.test.de", ".test.de", "test1.de", ".test.de" }; private final static String uri2[] = { "test.de", "www.test.de", "test1.de", ".test.de" }; private final static String uriintersect[] = { null, "www.test.de", "test1.de", ".test.de" }; private final static String uriunion[][] = { { "www.test.de", "test.de" }, { ".test.de" }, { "test1.de" }, { ".test.de" } }; private final static byte[] testIP = { (byte) 192, (byte) 168, 1, 2 }; private final static byte[][] testIPIsConstraint = { { (byte) 192, (byte) 168, 1, 1, (byte) 0xFF, (byte) 0xFF, (byte) 0xFF, 0 }, { (byte) 192, (byte) 168, 1, 1, (byte) 0xFF, (byte) 0xFF, (byte) 0xFF, 4 } }; private final static byte[][] testIPIsNotConstraint = { { (byte) 192, (byte) 168, 3, 1, (byte) 0xFF, (byte) 0xFF, (byte) 0xFF, 2 }, { (byte) 192, (byte) 168, 1, 1, (byte) 0xFF, (byte) 0xFF, (byte) 0xFF, 3 } }; private final static byte[][] ip1 = { { (byte) 192, (byte) 168, 1, 1, (byte) 0xFF, (byte) 0xFF, (byte) 0xFE, (byte) 0xFF }, { (byte) 192, (byte) 168, 1, 1, (byte) 0xFF, (byte) 0xFF, (byte) 0xFF, (byte) 0xFF }, { (byte) 192, (byte) 168, 1, 1, (byte) 0xFF, (byte) 0xFF, (byte) 0xFF, (byte) 0x00 } }; private final static byte[][] ip2 = { { (byte) 192, (byte) 168, 0, 1, (byte) 0xFF, (byte) 0xFF, (byte) 0xFC, 3 }, { (byte) 192, (byte) 168, 1, 1, (byte) 0xFF, (byte) 0xFF, (byte) 0xFF, (byte) 0xFF }, { (byte) 192, (byte) 168, 0, 1, (byte) 0xFF, (byte) 0xFF, (byte) 0xFF, (byte) 0x00 } }; private final static byte[][] ipintersect = { { (byte) 192, (byte) 168, 0, 1, (byte) 0xFF, (byte) 0xFF, (byte) 0xFE, (byte) 0xFF }, { (byte) 192, (byte) 168, 1, 1, (byte) 0xFF, (byte) 0xFF, (byte) 0xFF, (byte) 0xFF }, null }; private final static byte[][][] ipunion = { { { (byte) 192, (byte) 168, 1, 1, (byte) 0xFF, (byte) 0xFF, (byte) 0xFE, (byte) 0xFF }, { (byte) 192, (byte) 168, 0, 1, (byte) 0xFF, (byte) 0xFF, (byte) 0xFC, 3 } }, { { (byte) 192, (byte) 168, 1, 1, (byte) 0xFF, (byte) 0xFF, (byte) 0xFF, (byte) 0xFF } }, { { (byte) 192, (byte) 168, 1, 1, (byte) 0xFF, (byte) 0xFF, (byte) 0xFF, (byte) 0x00 }, { (byte) 192, (byte) 168, 0, 1, (byte) 0xFF, (byte) 0xFF, (byte) 0xFF, (byte) 0x00 } } }; public String getName() { return "PKIXNameConstraintsTest"; } public void performTest() throws Exception { testConstraints(GeneralName.rfc822Name, testEmail, testEmailIsConstraint, testEmailIsNotConstraint, email1, email2, emailunion, emailintersect); testConstraints(GeneralName.dNSName, testDNS, testDNSIsConstraint, testDNSIsNotConstraint, dns1, dns2, dnsunion, dnsintersect); testConstraints(GeneralName.directoryName, testDN, testDNIsConstraint, testDNIsNotConstraint, dn1, dn2, dnUnion, dnIntersection); testConstraints(GeneralName.uniformResourceIdentifier, testURI, testURIIsConstraint, testURIIsNotConstraint, uri1, uri2, uriunion, uriintersect); testConstraints(GeneralName.iPAddress, testIP, testIPIsConstraint, testIPIsNotConstraint, ip1, ip2, ipunion, ipintersect); } /** * Tests string based GeneralNames for inclusion or exclusion. * * @param nameType The {@link GeneralName} type to test. * @param testName The name to test. * @param testNameIsConstraint The names where testName must * be included and excluded. * @param testNameIsNotConstraint The names where testName * must not be excluded and included. * @param testNames1 Operand 1 of test names to use for union and * intersection testing. * @param testNames2 Operand 2 of test names to use for union and * intersection testing. * @param testUnion The union results. * @param testInterSection The intersection results. * @throws Exception If an unexpected exception occurs. */ private void testConstraints( int nameType, String testName, String[] testNameIsConstraint, String[] testNameIsNotConstraint, String[] testNames1, String[] testNames2, String[][] testUnion, String[] testInterSection) throws Exception { for (int i = 0; i < testNameIsConstraint.length; i++) { PKIXNameConstraintValidator constraintValidator = new PKIXNameConstraintValidator(); constraintValidator.intersectPermittedSubtree(new GeneralSubtree( new GeneralName(nameType, testNameIsConstraint[i]))); constraintValidator.checkPermitted(new GeneralName(nameType, testName)); } for (int i = 0; i < testNameIsNotConstraint.length; i++) { PKIXNameConstraintValidator constraintValidator = new PKIXNameConstraintValidator(); constraintValidator.intersectPermittedSubtree(new GeneralSubtree( new GeneralName(nameType, testNameIsNotConstraint[i]))); try { constraintValidator.checkPermitted(new GeneralName(nameType, testName)); fail("not permitted name allowed: " + nameType); } catch (PKIXNameConstraintValidatorException e) { // expected } } for (int i = 0; i < testNameIsConstraint.length; i++) { PKIXNameConstraintValidator constraintValidator = new PKIXNameConstraintValidator(); constraintValidator.addExcludedSubtree(new GeneralSubtree(new GeneralName( nameType, testNameIsConstraint[i]))); try { constraintValidator.checkExcluded(new GeneralName(nameType, testName)); fail("excluded name missed: " + nameType); } catch (PKIXNameConstraintValidatorException e) { // expected } } for (int i = 0; i < testNameIsNotConstraint.length; i++) { PKIXNameConstraintValidator constraintValidator = new PKIXNameConstraintValidator(); constraintValidator.addExcludedSubtree(new GeneralSubtree(new GeneralName( nameType, testNameIsNotConstraint[i]))); constraintValidator.checkExcluded(new GeneralName(nameType, testName)); } for (int i = 0; i < testNames1.length; i++) { PKIXNameConstraintValidator constraintValidator = new PKIXNameConstraintValidator(); constraintValidator.addExcludedSubtree(new GeneralSubtree(new GeneralName( nameType, testNames1[i]))); constraintValidator.addExcludedSubtree(new GeneralSubtree(new GeneralName( nameType, testNames2[i]))); PKIXNameConstraintValidator constraints2 = new PKIXNameConstraintValidator(); for (int j = 0; j < testUnion[i].length; j++) { constraints2.addExcludedSubtree(new GeneralSubtree( new GeneralName(nameType, testUnion[i][j]))); } if (!constraints2.equals(constraintValidator)) { fail("union wrong: " + nameType); } constraintValidator = new PKIXNameConstraintValidator(); constraintValidator.intersectPermittedSubtree(new GeneralSubtree( new GeneralName(nameType, testNames1[i]))); constraintValidator.intersectPermittedSubtree(new GeneralSubtree( new GeneralName(nameType, testNames2[i]))); constraints2 = new PKIXNameConstraintValidator(); if (testInterSection[i] != null) { constraints2.intersectPermittedSubtree(new GeneralSubtree( new GeneralName(nameType, testInterSection[i]))); } else { constraints2.intersectEmptyPermittedSubtree(nameType); } if (!constraints2.equals(constraintValidator)) { fail("intersection wrong: " + nameType); } } } /** * Tests byte array based GeneralNames for inclusion or exclusion. * * @param nameType The {@link GeneralName} type to test. * @param testName The name to test. * @param testNameIsConstraint The names where testName must * be included and excluded. * @param testNameIsNotConstraint The names where testName * must not be excluded and included. * @param testNames1 Operand 1 of test names to use for union and * intersection testing. * @param testNames2 Operand 2 of test names to use for union and * intersection testing. * @param testUnion The union results. * @param testInterSection The intersection results. * @throws Exception If an unexpected exception occurs. */ private void testConstraints( int nameType, byte[] testName, byte[][] testNameIsConstraint, byte[][] testNameIsNotConstraint, byte[][] testNames1, byte[][] testNames2, byte[][][] testUnion, byte[][] testInterSection) throws Exception { for (int i = 0; i < testNameIsConstraint.length; i++) { PKIXNameConstraintValidator constraintValidator = new PKIXNameConstraintValidator(); constraintValidator.intersectPermittedSubtree(new GeneralSubtree( new GeneralName(nameType, new DEROctetString( testNameIsConstraint[i])))); constraintValidator.checkPermitted(new GeneralName(nameType, new DEROctetString(testName))); } for (int i = 0; i < testNameIsNotConstraint.length; i++) { PKIXNameConstraintValidator constraintValidator = new PKIXNameConstraintValidator(); constraintValidator.intersectPermittedSubtree(new GeneralSubtree( new GeneralName(nameType, new DEROctetString( testNameIsNotConstraint[i])))); try { constraintValidator.checkPermitted(new GeneralName(nameType, new DEROctetString(testName))); fail("not permitted name allowed: " + nameType); } catch (PKIXNameConstraintValidatorException e) { // expected } } for (int i = 0; i < testNameIsConstraint.length; i++) { PKIXNameConstraintValidator constraintValidator = new PKIXNameConstraintValidator(); constraintValidator.addExcludedSubtree(new GeneralSubtree(new GeneralName( nameType, new DEROctetString(testNameIsConstraint[i])))); try { constraintValidator.checkExcluded(new GeneralName(nameType, new DEROctetString(testName))); fail("excluded name missed: " + nameType); } catch (PKIXNameConstraintValidatorException e) { // expected } } for (int i = 0; i < testNameIsNotConstraint.length; i++) { PKIXNameConstraintValidator constraintValidator = new PKIXNameConstraintValidator(); constraintValidator.addExcludedSubtree(new GeneralSubtree(new GeneralName( nameType, new DEROctetString(testNameIsNotConstraint[i])))); constraintValidator.checkExcluded(new GeneralName(nameType, new DEROctetString(testName))); } for (int i = 0; i < testNames1.length; i++) { PKIXNameConstraintValidator constraintValidator = new PKIXNameConstraintValidator(); constraintValidator.addExcludedSubtree(new GeneralSubtree(new GeneralName( nameType, new DEROctetString(testNames1[i])))); constraintValidator.addExcludedSubtree(new GeneralSubtree(new GeneralName( nameType, new DEROctetString(testNames2[i])))); PKIXNameConstraintValidator constraints2 = new PKIXNameConstraintValidator(); for (int j = 0; j < testUnion[i].length; j++) { constraints2.addExcludedSubtree(new GeneralSubtree( new GeneralName(nameType, new DEROctetString( testUnion[i][j])))); } if (!constraints2.equals(constraintValidator)) { fail("union wrong: " + nameType); } constraintValidator = new PKIXNameConstraintValidator(); constraintValidator.intersectPermittedSubtree(new GeneralSubtree( new GeneralName(nameType, new DEROctetString(testNames1[i])))); constraintValidator.intersectPermittedSubtree(new GeneralSubtree( new GeneralName(nameType, new DEROctetString(testNames2[i])))); constraints2 = new PKIXNameConstraintValidator(); if (testInterSection[i] != null) { constraints2.intersectPermittedSubtree(new GeneralSubtree( new GeneralName(nameType, new DEROctetString( testInterSection[i])))); } else { constraints2.intersectEmptyPermittedSubtree(nameType); } if (!constraints2.equals(constraintValidator)) { fail("intersection wrong: " + nameType); } } } public static void main(String[] args) { runTest(new PKIXNameConstraintsTest()); } } bouncycastle-1.49.orig/test/src/org/bouncycastle/jce/provider/test/X509StoreTest.java0000644000175000017500000003137211057665260030236 0ustar ebourgebourgpackage org.bouncycastle.jce.provider.test; import org.bouncycastle.jce.PrincipalUtil; import org.bouncycastle.jce.X509Principal; import org.bouncycastle.jce.provider.BouncyCastleProvider; import org.bouncycastle.util.test.SimpleTest; import org.bouncycastle.x509.X509AttributeCertStoreSelector; import org.bouncycastle.x509.X509AttributeCertificate; import org.bouncycastle.x509.X509CRLStoreSelector; import org.bouncycastle.x509.X509CertPairStoreSelector; import org.bouncycastle.x509.X509CertStoreSelector; import org.bouncycastle.x509.X509CertificatePair; import org.bouncycastle.x509.X509CollectionStoreParameters; import org.bouncycastle.x509.X509Store; import org.bouncycastle.x509.X509V2AttributeCertificate; import java.io.ByteArrayInputStream; import java.math.BigInteger; import java.security.Security; import java.security.cert.CertificateFactory; import java.security.cert.X509CRL; import java.security.cert.X509Certificate; import java.util.ArrayList; import java.util.Collection; import java.util.Collections; import java.util.Date; import java.util.List; public class X509StoreTest extends SimpleTest { private void certPairTest() throws Exception { CertificateFactory cf = CertificateFactory.getInstance("X.509", "BC"); X509Certificate rootCert = (X509Certificate)cf .generateCertificate(new ByteArrayInputStream( CertPathTest.rootCertBin)); X509Certificate interCert = (X509Certificate)cf .generateCertificate(new ByteArrayInputStream( CertPathTest.interCertBin)); X509Certificate finalCert = (X509Certificate)cf .generateCertificate(new ByteArrayInputStream( CertPathTest.finalCertBin)); // Testing CollectionCertStore generation from List X509CertificatePair pair1 = new X509CertificatePair(rootCert, interCert); List certList = new ArrayList(); certList.add(pair1); certList.add(new X509CertificatePair(interCert, finalCert)); X509CollectionStoreParameters ccsp = new X509CollectionStoreParameters(certList); X509Store certStore = X509Store.getInstance("CertificatePair/Collection", ccsp, "BC"); X509CertPairStoreSelector selector = new X509CertPairStoreSelector(); X509CertStoreSelector fwSelector = new X509CertStoreSelector(); fwSelector.setSerialNumber(rootCert.getSerialNumber()); fwSelector.setSubject(rootCert.getIssuerDN().getName()); selector.setForwardSelector(fwSelector); Collection col = certStore.getMatches(selector); if (col.size() != 1 || !col.contains(pair1)) { fail("failed pair1 test"); } col = certStore.getMatches(null); if (col.size() != 2) { fail("failed null test"); } } public void performTest() throws Exception { CertificateFactory cf = CertificateFactory.getInstance("X.509", "BC"); X509Certificate rootCert = (X509Certificate)cf .generateCertificate(new ByteArrayInputStream( CertPathTest.rootCertBin)); X509Certificate interCert = (X509Certificate)cf .generateCertificate(new ByteArrayInputStream( CertPathTest.interCertBin)); X509Certificate finalCert = (X509Certificate)cf .generateCertificate(new ByteArrayInputStream( CertPathTest.finalCertBin)); X509CRL rootCrl = (X509CRL)cf.generateCRL(new ByteArrayInputStream( CertPathTest.rootCrlBin)); X509CRL interCrl = (X509CRL)cf .generateCRL(new ByteArrayInputStream( CertPathTest.interCrlBin)); // Testing CollectionCertStore generation from List List certList = new ArrayList(); certList.add(rootCert); certList.add(interCert); certList.add(finalCert); X509CollectionStoreParameters ccsp = new X509CollectionStoreParameters(certList); X509Store certStore = X509Store.getInstance("Certificate/Collection", ccsp, "BC"); // set default to be the same as for SUN X500 name X509Principal.DefaultReverse = true; // Searching for rootCert by subjectDN X509CertStoreSelector targetConstraints = new X509CertStoreSelector(); targetConstraints.setSubject(PrincipalUtil.getSubjectX509Principal(rootCert).getEncoded()); Collection certs = certStore.getMatches(targetConstraints); if (certs.size() != 1 || !certs.contains(rootCert)) { fail("rootCert not found by subjectDN"); } // Searching for rootCert by subjectDN encoded as byte targetConstraints = new X509CertStoreSelector(); targetConstraints.setSubject(PrincipalUtil.getSubjectX509Principal(rootCert).getEncoded()); certs = certStore.getMatches(targetConstraints); if (certs.size() != 1 || !certs.contains(rootCert)) { fail("rootCert not found by encoded subjectDN"); } X509Principal.DefaultReverse = false; // Searching for rootCert by public key encoded as byte targetConstraints = new X509CertStoreSelector(); targetConstraints.setSubjectPublicKey(rootCert.getPublicKey().getEncoded()); certs = certStore.getMatches(targetConstraints); if (certs.size() != 1 || !certs.contains(rootCert)) { fail("rootCert not found by encoded public key"); } // Searching for interCert by issuerDN targetConstraints = new X509CertStoreSelector(); targetConstraints.setIssuer(PrincipalUtil.getSubjectX509Principal(rootCert).getEncoded()); certs = certStore.getMatches(targetConstraints); if (certs.size() != 2) { fail("did not found 2 certs"); } if (!certs.contains(rootCert)) { fail("rootCert not found"); } if (!certs.contains(interCert)) { fail("interCert not found"); } // Searching for rootCrl by issuerDN List crlList = new ArrayList(); crlList.add(rootCrl); crlList.add(interCrl); ccsp = new X509CollectionStoreParameters(crlList); X509Store store = X509Store.getInstance("CRL/Collection", ccsp, "BC"); X509CRLStoreSelector targetConstraintsCRL = new X509CRLStoreSelector(); targetConstraintsCRL.setIssuers(Collections.singleton(rootCrl.getIssuerX500Principal())); Collection crls = store.getMatches(targetConstraintsCRL); if (crls.size() != 1 || !crls.contains(rootCrl)) { fail("rootCrl not found"); } crls = certStore.getMatches(targetConstraintsCRL); if (crls.size() != 0) { fail("error using wrong selector (CRL)"); } certs = store.getMatches(targetConstraints); if (certs.size() != 0) { fail("error using wrong selector (certs)"); } // Searching for attribute certificates X509V2AttributeCertificate attrCert = new X509V2AttributeCertificate(AttrCertTest.attrCert); X509AttributeCertificate attrCert2 = new X509V2AttributeCertificate(AttrCertTest.certWithBaseCertificateID); List attrList = new ArrayList(); attrList.add(attrCert); attrList.add(attrCert2); ccsp = new X509CollectionStoreParameters(attrList); store = X509Store.getInstance("AttributeCertificate/Collection", ccsp, "BC"); X509AttributeCertStoreSelector attrSelector = new X509AttributeCertStoreSelector(); attrSelector.setHolder(attrCert.getHolder()); if (!attrSelector.getHolder().equals(attrCert.getHolder())) { fail("holder get not correct"); } Collection attrs = store.getMatches(attrSelector); if (attrs.size() != 1 || !attrs.contains(attrCert)) { fail("attrCert not found on holder"); } attrSelector.setHolder(attrCert2.getHolder()); if (attrSelector.getHolder().equals(attrCert.getHolder())) { fail("holder get not correct"); } attrs = store.getMatches(attrSelector); if (attrs.size() != 1 || !attrs.contains(attrCert2)) { fail("attrCert2 not found on holder"); } attrSelector = new X509AttributeCertStoreSelector(); attrSelector.setIssuer(attrCert.getIssuer()); if (!attrSelector.getIssuer().equals(attrCert.getIssuer())) { fail("issuer get not correct"); } attrs = store.getMatches(attrSelector); if (attrs.size() != 1 || !attrs.contains(attrCert)) { fail("attrCert not found on issuer"); } attrSelector.setIssuer(attrCert2.getIssuer()); if (attrSelector.getIssuer().equals(attrCert.getIssuer())) { fail("issuer get not correct"); } attrs = store.getMatches(attrSelector); if (attrs.size() != 1 || !attrs.contains(attrCert2)) { fail("attrCert2 not found on issuer"); } attrSelector = new X509AttributeCertStoreSelector(); attrSelector.setAttributeCert(attrCert); if (!attrSelector.getAttributeCert().equals(attrCert)) { fail("attrCert get not correct"); } attrs = store.getMatches(attrSelector); if (attrs.size() != 1 || !attrs.contains(attrCert)) { fail("attrCert not found on attrCert"); } attrSelector = new X509AttributeCertStoreSelector(); attrSelector.setSerialNumber(attrCert.getSerialNumber()); if (!attrSelector.getSerialNumber().equals(attrCert.getSerialNumber())) { fail("serial number get not correct"); } attrs = store.getMatches(attrSelector); if (attrs.size() != 1 || !attrs.contains(attrCert)) { fail("attrCert not found on serial number"); } attrSelector = (X509AttributeCertStoreSelector)attrSelector.clone(); if (!attrSelector.getSerialNumber().equals(attrCert.getSerialNumber())) { fail("serial number get not correct"); } attrs = store.getMatches(attrSelector); if (attrs.size() != 1 || !attrs.contains(attrCert)) { fail("attrCert not found on serial number"); } attrSelector = new X509AttributeCertStoreSelector(); attrSelector.setAttributeCertificateValid(attrCert.getNotBefore()); if (!attrSelector.getAttributeCertificateValid().equals(attrCert.getNotBefore())) { fail("valid get not correct"); } attrs = store.getMatches(attrSelector); if (attrs.size() != 1 || !attrs.contains(attrCert)) { fail("attrCert not found on valid"); } attrSelector = new X509AttributeCertStoreSelector(); attrSelector.setAttributeCertificateValid(new Date(attrCert.getNotBefore().getTime() - 100)); attrs = store.getMatches(attrSelector); if (attrs.size() != 0) { fail("attrCert found on before"); } attrSelector.setAttributeCertificateValid(new Date(attrCert.getNotAfter().getTime() + 100)); attrs = store.getMatches(attrSelector); if (attrs.size() != 0) { fail("attrCert found on after"); } attrSelector.setSerialNumber(BigInteger.valueOf(10000)); attrs = store.getMatches(attrSelector); if (attrs.size() != 0) { fail("attrCert found on wrong serial number"); } attrSelector.setAttributeCert(null); attrSelector.setAttributeCertificateValid(null); attrSelector.setHolder(null); attrSelector.setIssuer(null); attrSelector.setSerialNumber(null); if (attrSelector.getAttributeCert() != null) { fail("null attrCert"); } if (attrSelector.getAttributeCertificateValid() != null) { fail("null attrCertValid"); } if (attrSelector.getHolder() != null) { fail("null attrCert holder"); } if (attrSelector.getIssuer() != null) { fail("null attrCert issuer"); } if (attrSelector.getSerialNumber() != null) { fail("null attrCert serial"); } attrs = certStore.getMatches(attrSelector); if (attrs.size() != 0) { fail("error using wrong selector (attrs)"); } certPairTest(); } public String getName() { return "X509Store"; } public static void main(String[] args) { Security.addProvider(new BouncyCastleProvider()); runTest(new X509StoreTest()); } } bouncycastle-1.49.orig/test/src/org/bouncycastle/jce/provider/test/DHTest.java0000644000175000017500000007767712063462040027056 0ustar ebourgebourgpackage org.bouncycastle.jce.provider.test; import java.io.ByteArrayInputStream; import java.io.ByteArrayOutputStream; import java.io.ObjectInputStream; import java.io.ObjectOutputStream; import java.math.BigInteger; import java.security.AlgorithmParameterGenerator; import java.security.AlgorithmParameters; import java.security.Key; import java.security.KeyFactory; import java.security.KeyPair; import java.security.KeyPairGenerator; import java.security.SecureRandom; import java.security.Security; import java.security.interfaces.ECPrivateKey; import java.security.interfaces.ECPublicKey; import java.security.spec.ECFieldFp; import java.security.spec.ECParameterSpec; import java.security.spec.EllipticCurve; import java.security.spec.PKCS8EncodedKeySpec; import java.security.spec.X509EncodedKeySpec; import javax.crypto.KeyAgreement; import javax.crypto.SecretKey; import javax.crypto.interfaces.DHPrivateKey; import javax.crypto.interfaces.DHPublicKey; import javax.crypto.spec.DESKeySpec; import javax.crypto.spec.DESedeKeySpec; import javax.crypto.spec.DHParameterSpec; import org.bouncycastle.asn1.pkcs.PKCSObjectIdentifiers; import org.bouncycastle.jcajce.provider.config.ConfigurableProvider; import org.bouncycastle.jce.ECPointUtil; import org.bouncycastle.jce.interfaces.PKCS12BagAttributeCarrier; import org.bouncycastle.jce.provider.BouncyCastleProvider; import org.bouncycastle.util.Arrays; import org.bouncycastle.util.encoders.Base64; import org.bouncycastle.util.encoders.Hex; import org.bouncycastle.util.test.SimpleTest; public class DHTest extends SimpleTest { private BigInteger g512 = new BigInteger("153d5d6172adb43045b68ae8e1de1070b6137005686d29d3d73a7749199681ee5b212c9b96bfdcfa5b20cd5e3fd2044895d609cf9b410b7a0f12ca1cb9a428cc", 16); private BigInteger p512 = new BigInteger("9494fec095f3b85ee286542b3836fc81a5dd0a0349b4c239dd38744d488cf8e31db8bcb7d33b41abb9e5a33cca9144b1cef332c94bf0573bf047a3aca98cdf3b", 16); private BigInteger g768 = new BigInteger("7c240073c1316c621df461b71ebb0cdcc90a6e5527e5e126633d131f87461c4dc4afc60c2cb0f053b6758871489a69613e2a8b4c8acde23954c08c81cbd36132cfd64d69e4ed9f8e51ed6e516297206672d5c0a69135df0a5dcf010d289a9ca1", 16); private BigInteger p768 = new BigInteger("8c9dd223debed1b80103b8b309715be009d48860ed5ae9b9d5d8159508efd802e3ad4501a7f7e1cfec78844489148cd72da24b21eddd01aa624291c48393e277cfc529e37075eccef957f3616f962d15b44aeab4039d01b817fde9eaa12fd73f", 16); private BigInteger g1024 = new BigInteger("1db17639cdf96bc4eabba19454f0b7e5bd4e14862889a725c96eb61048dcd676ceb303d586e30f060dbafd8a571a39c4d823982117da5cc4e0f89c77388b7a08896362429b94a18a327604eb7ff227bffbc83459ade299e57b5f77b50fb045250934938efa145511166e3197373e1b5b1e52de713eb49792bedde722c6717abf", 16); private BigInteger p1024 = new BigInteger("a00e283b3c624e5b2b4d9fbc2653b5185d99499b00fd1bf244c6f0bb817b4d1c451b2958d62a0f8a38caef059fb5ecd25d75ed9af403f5b5bdab97a642902f824e3c13789fed95fa106ddfe0ff4a707c85e2eb77d49e68f2808bcea18ce128b178cd287c6bc00efa9a1ad2a673fe0dceace53166f75b81d6709d5f8af7c66bb7", 16); // public key with mismatched oid/parameters private byte[] oldPubEnc = Base64.decode( "MIIBnzCCARQGByqGSM4+AgEwggEHAoGBAPxSrN417g43VAM9sZRf1dt6AocAf7D6" + "WVCtqEDcBJrMzt63+g+BNJzhXVtbZ9kp9vw8L/0PHgzv0Ot/kOLX7Khn+JalOECW" + "YlkyBhmOVbjR79TY5u2GAlvG6pqpizieQNBCEMlUuYuK1Iwseil6VoRuA13Zm7uw" + "WO1eZmaJtY7LAoGAQaPRCFKM5rEdkMrV9FNzeSsYRs8m3DqPnnJHpuySpyO9wUcX" + "OOJcJY5qvHbDO5SxHXu/+bMgXmVT6dXI5o0UeYqJR7fj6pR4E6T0FwG55RFr5Ok4" + "3C4cpXmaOu176SyWuoDqGs1RDGmYQjwbZUi23DjaaTFUly9LCYXMliKrQfEDgYQA" + "AoGAQUGCBN4TaBw1BpdBXdTvTfCU69XDB3eyU2FOBE3UWhpx9D8XJlx4f5DpA4Y6" + "6sQMuCbhfmjEph8W7/sbMurM/awR+PSR8tTY7jeQV0OkmAYdGK2nzh0ZSifMO1oE" + "NNhN2O62TLs67msxT28S4/S89+LMtc98mevQ2SX+JF3wEVU="); // bogus key with full PKCS parameter set private byte[] oldFullParams = Base64.decode( "MIIBIzCCARgGByqGSM4+AgEwggELAoGBAP1/U4EddRIpUt9KnC7s5Of2EbdSPO9E" + "AMMeP4C2USZpRV1AIlH7WT2NWPq/xfW6MPbLm1Vs14E7gB00b/JmYLdrmVClpJ+f" + "6AR7ECLCT7up1/63xhv4O1fnxqimFQ8E+4P208UewwI1VBNaFpEy9nXzrith1yrv" + "8iIDGZ3RSAHHAoGBAPfhoIXWmz3ey7yrXDa4V7l5lK+7+jrqgvlXTAs9B4JnUVlX" + "jrrUWU/mcQcQgYC0SRZxI+hMKBYTt88JMozIpuE8FnqLVHyNKOCjrh4rs6Z1kW6j" + "fwv6ITVi8ftiegEkO8yk8b6oUZCJqIPf4VrlnwaSi2ZegHtVJWQBTDv+z0kqAgFk" + "AwUAAgIH0A=="); private byte[] samplePubEnc = Base64.decode( "MIIBpjCCARsGCSqGSIb3DQEDATCCAQwCgYEA/X9TgR11EilS30qcLuzk5/YRt1I8" + "70QAwx4/gLZRJmlFXUAiUftZPY1Y+r/F9bow9subVWzXgTuAHTRv8mZgt2uZUKWk" + "n5/oBHsQIsJPu6nX/rfGG/g7V+fGqKYVDwT7g/bTxR7DAjVUE1oWkTL2dfOuK2HX" + "Ku/yIgMZndFIAccCgYEA9+GghdabPd7LvKtcNrhXuXmUr7v6OuqC+VdMCz0HgmdR" + "WVeOutRZT+ZxBxCBgLRJFnEj6EwoFhO3zwkyjMim4TwWeotUfI0o4KOuHiuzpnWR" + "bqN/C/ohNWLx+2J6ASQ7zKTxvqhRkImog9/hWuWfBpKLZl6Ae1UlZAFMO/7PSSoC" + "AgIAA4GEAAKBgEIiqxoUW6E6GChoOgcfNbVFclW91ITf5MFSUGQwt2R0RHoOhxvO" + "lZhNs++d0VPATLAyXovjfgENT9SGCbuZttYcqqLdKTbMXBWPek+rfnAl9E4iEMED" + "IDd83FJTKs9hQcPAm7zmp0Xm1bGF9CbUFjP5G02265z7eBmHDaT0SNlB"); private byte[] samplePrivEnc = Base64.decode( "MIIBZgIBADCCARsGCSqGSIb3DQEDATCCAQwCgYEA/X9TgR11EilS30qcLuzk5/YR" + "t1I870QAwx4/gLZRJmlFXUAiUftZPY1Y+r/F9bow9subVWzXgTuAHTRv8mZgt2uZ" + "UKWkn5/oBHsQIsJPu6nX/rfGG/g7V+fGqKYVDwT7g/bTxR7DAjVUE1oWkTL2dfOu" + "K2HXKu/yIgMZndFIAccCgYEA9+GghdabPd7LvKtcNrhXuXmUr7v6OuqC+VdMCz0H" + "gmdRWVeOutRZT+ZxBxCBgLRJFnEj6EwoFhO3zwkyjMim4TwWeotUfI0o4KOuHiuz" + "pnWRbqN/C/ohNWLx+2J6ASQ7zKTxvqhRkImog9/hWuWfBpKLZl6Ae1UlZAFMO/7P" + "SSoCAgIABEICQAZYXnBHazxXUUdFP4NIf2Ipu7du0suJPZQKKff81wymi2zfCfHh" + "uhe9gQ9xdm4GpzeNtrQ8/MzpTy+ZVrtd29Q="); public String getName() { return "DH"; } private void testGP( String algName, int size, int privateValueSize, BigInteger g, BigInteger p) throws Exception { DHParameterSpec dhParams = new DHParameterSpec(p, g, privateValueSize); KeyPairGenerator keyGen = KeyPairGenerator.getInstance(algName, "BC"); keyGen.initialize(dhParams); testTwoParty(algName, size, privateValueSize, keyGen); KeyPair aKeyPair = keyGen.generateKeyPair(); // // public key encoding test // byte[] pubEnc = aKeyPair.getPublic().getEncoded(); KeyFactory keyFac = KeyFactory.getInstance(algName, "BC"); X509EncodedKeySpec pubX509 = new X509EncodedKeySpec(pubEnc); DHPublicKey pubKey = (DHPublicKey)keyFac.generatePublic(pubX509); DHParameterSpec spec = pubKey.getParams(); if (!spec.getG().equals(dhParams.getG()) || !spec.getP().equals(dhParams.getP())) { fail(size + " bit public key encoding/decoding test failed on parameters"); } if (!((DHPublicKey)aKeyPair.getPublic()).getY().equals(pubKey.getY())) { fail(size + " bit public key encoding/decoding test failed on y value"); } // // public key serialisation test // pubKey = (DHPublicKey)serializeDeserialize(aKeyPair.getPublic()); spec = pubKey.getParams(); if (!spec.getG().equals(dhParams.getG()) || !spec.getP().equals(dhParams.getP())) { fail(size + " bit public key serialisation test failed on parameters"); } if (!((DHPublicKey)aKeyPair.getPublic()).getY().equals(pubKey.getY())) { fail(size + " bit public key serialisation test failed on y value"); } if (!aKeyPair.getPublic().equals(pubKey)) { fail("equals test failed"); } if (aKeyPair.getPublic().hashCode() != pubKey.hashCode()) { fail("hashCode test failed"); } // // private key encoding test // byte[] privEnc = aKeyPair.getPrivate().getEncoded(); PKCS8EncodedKeySpec privPKCS8 = new PKCS8EncodedKeySpec(privEnc); DHPrivateKey privKey = (DHPrivateKey)keyFac.generatePrivate(privPKCS8); spec = privKey.getParams(); if (!spec.getG().equals(dhParams.getG()) || !spec.getP().equals(dhParams.getP())) { fail(size + " bit private key encoding/decoding test failed on parameters"); } if (!((DHPrivateKey)aKeyPair.getPrivate()).getX().equals(privKey.getX())) { fail(size + " bit private key encoding/decoding test failed on y value"); } // // private key serialisation test // privKey = (DHPrivateKey)serializeDeserialize(aKeyPair.getPrivate()); spec = privKey.getParams(); if (!spec.getG().equals(dhParams.getG()) || !spec.getP().equals(dhParams.getP())) { fail(size + " bit private key serialisation test failed on parameters"); } if (!((DHPrivateKey)aKeyPair.getPrivate()).getX().equals(privKey.getX())) { fail(size + " bit private key serialisation test failed on X value"); } if (!aKeyPair.getPrivate().equals(privKey)) { fail("equals test failed"); } if (aKeyPair.getPrivate().hashCode() != privKey.hashCode()) { fail("hashCode test failed"); } if (!(privKey instanceof PKCS12BagAttributeCarrier)) { fail("private key not implementing PKCS12 attribute carrier"); } // // three party test // KeyPairGenerator aPairGen = KeyPairGenerator.getInstance(algName, "BC"); aPairGen.initialize(spec); KeyPair aPair = aPairGen.generateKeyPair(); KeyPairGenerator bPairGen = KeyPairGenerator.getInstance(algName, "BC"); bPairGen.initialize(spec); KeyPair bPair = bPairGen.generateKeyPair(); KeyPairGenerator cPairGen = KeyPairGenerator.getInstance(algName, "BC"); cPairGen.initialize(spec); KeyPair cPair = cPairGen.generateKeyPair(); KeyAgreement aKeyAgree = KeyAgreement.getInstance(algName, "BC"); aKeyAgree.init(aPair.getPrivate()); KeyAgreement bKeyAgree = KeyAgreement.getInstance(algName, "BC"); bKeyAgree.init(bPair.getPrivate()); KeyAgreement cKeyAgree = KeyAgreement.getInstance(algName, "BC"); cKeyAgree.init(cPair.getPrivate()); Key ac = aKeyAgree.doPhase(cPair.getPublic(), false); Key ba = bKeyAgree.doPhase(aPair.getPublic(), false); Key cb = cKeyAgree.doPhase(bPair.getPublic(), false); aKeyAgree.doPhase(cb, true); bKeyAgree.doPhase(ac, true); cKeyAgree.doPhase(ba, true); BigInteger aShared = new BigInteger(aKeyAgree.generateSecret()); BigInteger bShared = new BigInteger(bKeyAgree.generateSecret()); BigInteger cShared = new BigInteger(cKeyAgree.generateSecret()); if (!aShared.equals(bShared)) { fail(size + " bit 3-way test failed (a and b differ)"); } if (!cShared.equals(bShared)) { fail(size + " bit 3-way test failed (c and b differ)"); } } private void testTwoParty(String algName, int size, int privateValueSize, KeyPairGenerator keyGen) throws Exception { // // a side // KeyPair aKeyPair = keyGen.generateKeyPair(); KeyAgreement aKeyAgree = KeyAgreement.getInstance(algName, "BC"); checkKeySize(privateValueSize, aKeyPair); aKeyAgree.init(aKeyPair.getPrivate()); // // b side // KeyPair bKeyPair = keyGen.generateKeyPair(); KeyAgreement bKeyAgree = KeyAgreement.getInstance(algName, "BC"); checkKeySize(privateValueSize, bKeyPair); bKeyAgree.init(bKeyPair.getPrivate()); // // agreement // aKeyAgree.doPhase(bKeyPair.getPublic(), true); bKeyAgree.doPhase(aKeyPair.getPublic(), true); BigInteger k1 = new BigInteger(aKeyAgree.generateSecret()); BigInteger k2 = new BigInteger(bKeyAgree.generateSecret()); if (!k1.equals(k2)) { fail(size + " bit 2-way test failed"); } } private void testExplicitWrapping( int size, int privateValueSize, BigInteger g, BigInteger p) throws Exception { DHParameterSpec dhParams = new DHParameterSpec(p, g, privateValueSize); KeyPairGenerator keyGen = KeyPairGenerator.getInstance("DH", "BC"); keyGen.initialize(dhParams); // // a side // KeyPair aKeyPair = keyGen.generateKeyPair(); KeyAgreement aKeyAgree = KeyAgreement.getInstance("DH", "BC"); checkKeySize(privateValueSize, aKeyPair); aKeyAgree.init(aKeyPair.getPrivate()); // // b side // KeyPair bKeyPair = keyGen.generateKeyPair(); KeyAgreement bKeyAgree = KeyAgreement.getInstance("DH", "BC"); checkKeySize(privateValueSize, bKeyPair); bKeyAgree.init(bKeyPair.getPrivate()); // // agreement // aKeyAgree.doPhase(bKeyPair.getPublic(), true); bKeyAgree.doPhase(aKeyPair.getPublic(), true); SecretKey k1 = aKeyAgree.generateSecret(PKCSObjectIdentifiers.id_alg_CMS3DESwrap.getId()); SecretKey k2 = bKeyAgree.generateSecret(PKCSObjectIdentifiers.id_alg_CMS3DESwrap.getId()); // TODO Compare k1 and k2? } private Object serializeDeserialize(Object o) throws Exception { ByteArrayOutputStream bOut = new ByteArrayOutputStream(); ObjectOutputStream oOut = new ObjectOutputStream(bOut); oOut.writeObject(o); oOut.close(); ObjectInputStream oIn = new ObjectInputStream(new ByteArrayInputStream(bOut.toByteArray())); return oIn.readObject(); } private void checkKeySize(int privateValueSize, KeyPair aKeyPair) { if (privateValueSize != 0) { DHPrivateKey key = (DHPrivateKey)aKeyPair.getPrivate(); if (key.getX().bitLength() != privateValueSize) { fail("limited key check failed for key size " + privateValueSize); } } } private void testRandom( int size) throws Exception { AlgorithmParameterGenerator a = AlgorithmParameterGenerator.getInstance("DH", "BC"); a.init(size, new SecureRandom()); AlgorithmParameters params = a.generateParameters(); byte[] encodeParams = params.getEncoded(); AlgorithmParameters a2 = AlgorithmParameters.getInstance("DH", "BC"); a2.init(encodeParams); // a and a2 should be equivalent! byte[] encodeParams_2 = a2.getEncoded(); if (!areEqual(encodeParams, encodeParams_2)) { fail("encode/decode parameters failed"); } DHParameterSpec dhP = (DHParameterSpec)params.getParameterSpec(DHParameterSpec.class); testGP("DH", size, 0, dhP.getG(), dhP.getP()); } private void testDefault( int privateValueSize, BigInteger g, BigInteger p) throws Exception { DHParameterSpec dhParams = new DHParameterSpec(p, g, privateValueSize); String algName = "DH"; int size = p.bitLength(); new BouncyCastleProvider().setParameter(ConfigurableProvider.DH_DEFAULT_PARAMS, dhParams); KeyPairGenerator keyGen = KeyPairGenerator.getInstance(algName, "BC"); keyGen.initialize(dhParams.getP().bitLength()); testTwoParty("DH", size, privateValueSize, keyGen); KeyPair aKeyPair = keyGen.generateKeyPair(); new BouncyCastleProvider().setParameter(ConfigurableProvider.DH_DEFAULT_PARAMS, null); // // public key encoding test // byte[] pubEnc = aKeyPair.getPublic().getEncoded(); KeyFactory keyFac = KeyFactory.getInstance(algName, "BC"); X509EncodedKeySpec pubX509 = new X509EncodedKeySpec(pubEnc); DHPublicKey pubKey = (DHPublicKey)keyFac.generatePublic(pubX509); DHParameterSpec spec = pubKey.getParams(); if (!spec.getG().equals(dhParams.getG()) || !spec.getP().equals(dhParams.getP())) { fail(size + " bit public key encoding/decoding test failed on parameters"); } if (!((DHPublicKey)aKeyPair.getPublic()).getY().equals(pubKey.getY())) { fail(size + " bit public key encoding/decoding test failed on y value"); } // // public key serialisation test // ByteArrayOutputStream bOut = new ByteArrayOutputStream(); ObjectOutputStream oOut = new ObjectOutputStream(bOut); oOut.writeObject(aKeyPair.getPublic()); ByteArrayInputStream bIn = new ByteArrayInputStream(bOut.toByteArray()); ObjectInputStream oIn = new ObjectInputStream(bIn); pubKey = (DHPublicKey)oIn.readObject(); spec = pubKey.getParams(); if (!spec.getG().equals(dhParams.getG()) || !spec.getP().equals(dhParams.getP())) { fail(size + " bit public key serialisation test failed on parameters"); } if (!((DHPublicKey)aKeyPair.getPublic()).getY().equals(pubKey.getY())) { fail(size + " bit public key serialisation test failed on y value"); } // // private key encoding test // byte[] privEnc = aKeyPair.getPrivate().getEncoded(); PKCS8EncodedKeySpec privPKCS8 = new PKCS8EncodedKeySpec(privEnc); DHPrivateKey privKey = (DHPrivateKey)keyFac.generatePrivate(privPKCS8); spec = privKey.getParams(); if (!spec.getG().equals(dhParams.getG()) || !spec.getP().equals(dhParams.getP())) { fail(size + " bit private key encoding/decoding test failed on parameters"); } if (!((DHPrivateKey)aKeyPair.getPrivate()).getX().equals(privKey.getX())) { fail(size + " bit private key encoding/decoding test failed on y value"); } // // private key serialisation test // bOut = new ByteArrayOutputStream(); oOut = new ObjectOutputStream(bOut); oOut.writeObject(aKeyPair.getPrivate()); bIn = new ByteArrayInputStream(bOut.toByteArray()); oIn = new ObjectInputStream(bIn); privKey = (DHPrivateKey)oIn.readObject(); spec = privKey.getParams(); if (!spec.getG().equals(dhParams.getG()) || !spec.getP().equals(dhParams.getP())) { fail(size + " bit private key serialisation test failed on parameters"); } if (!((DHPrivateKey)aKeyPair.getPrivate()).getX().equals(privKey.getX())) { fail(size + " bit private key serialisation test failed on y value"); } // // three party test // KeyPairGenerator aPairGen = KeyPairGenerator.getInstance(algName, "BC"); aPairGen.initialize(spec); KeyPair aPair = aPairGen.generateKeyPair(); KeyPairGenerator bPairGen = KeyPairGenerator.getInstance(algName, "BC"); bPairGen.initialize(spec); KeyPair bPair = bPairGen.generateKeyPair(); KeyPairGenerator cPairGen = KeyPairGenerator.getInstance(algName, "BC"); cPairGen.initialize(spec); KeyPair cPair = cPairGen.generateKeyPair(); KeyAgreement aKeyAgree = KeyAgreement.getInstance(algName, "BC"); aKeyAgree.init(aPair.getPrivate()); KeyAgreement bKeyAgree = KeyAgreement.getInstance(algName, "BC"); bKeyAgree.init(bPair.getPrivate()); KeyAgreement cKeyAgree = KeyAgreement.getInstance(algName, "BC"); cKeyAgree.init(cPair.getPrivate()); Key ac = aKeyAgree.doPhase(cPair.getPublic(), false); Key ba = bKeyAgree.doPhase(aPair.getPublic(), false); Key cb = cKeyAgree.doPhase(bPair.getPublic(), false); aKeyAgree.doPhase(cb, true); bKeyAgree.doPhase(ac, true); cKeyAgree.doPhase(ba, true); BigInteger aShared = new BigInteger(aKeyAgree.generateSecret()); BigInteger bShared = new BigInteger(bKeyAgree.generateSecret()); BigInteger cShared = new BigInteger(cKeyAgree.generateSecret()); if (!aShared.equals(bShared)) { fail(size + " bit 3-way test failed (a and b differ)"); } if (!cShared.equals(bShared)) { fail(size + " bit 3-way test failed (c and b differ)"); } } private void testECDH(String algorithm) throws Exception { KeyPairGenerator g = KeyPairGenerator.getInstance(algorithm, "BC"); EllipticCurve curve = new EllipticCurve( new ECFieldFp(new BigInteger("883423532389192164791648750360308885314476597252960362792450860609699839")), // q new BigInteger("7fffffffffffffffffffffff7fffffffffff8000000000007ffffffffffc", 16), // a new BigInteger("6b016c3bdcf18941d0d654921475ca71a9db2fb27d1d37796185c2942c0a", 16)); // b ECParameterSpec ecSpec = new ECParameterSpec( curve, ECPointUtil.decodePoint(curve, Hex.decode("020ffa963cdca8816ccc33b8642bedf905c3d358573d3f27fbbd3b3cb9aaaf")), // G new BigInteger("883423532389192164791648750360308884807550341691627752275345424702807307"), // n 1); // h g.initialize(ecSpec, new SecureRandom()); // // a side // KeyPair aKeyPair = g.generateKeyPair(); KeyAgreement aKeyAgree = KeyAgreement.getInstance(algorithm, "BC"); aKeyAgree.init(aKeyPair.getPrivate()); // // b side // KeyPair bKeyPair = g.generateKeyPair(); KeyAgreement bKeyAgree = KeyAgreement.getInstance(algorithm, "BC"); bKeyAgree.init(bKeyPair.getPrivate()); // // agreement // aKeyAgree.doPhase(bKeyPair.getPublic(), true); bKeyAgree.doPhase(aKeyPair.getPublic(), true); BigInteger k1 = new BigInteger(aKeyAgree.generateSecret()); BigInteger k2 = new BigInteger(bKeyAgree.generateSecret()); if (!k1.equals(k2)) { fail(algorithm + " 2-way test failed"); } // // public key encoding test // byte[] pubEnc = aKeyPair.getPublic().getEncoded(); KeyFactory keyFac = KeyFactory.getInstance(algorithm, "BC"); X509EncodedKeySpec pubX509 = new X509EncodedKeySpec(pubEnc); ECPublicKey pubKey = (ECPublicKey)keyFac.generatePublic(pubX509); if (!pubKey.getW().equals(((ECPublicKey)aKeyPair.getPublic()).getW())) { System.out.println(" expected " + pubKey.getW().getAffineX() + " got " + ((ECPublicKey)aKeyPair.getPublic()).getW().getAffineX()); System.out.println(" expected " + pubKey.getW().getAffineY() + " got " + ((ECPublicKey)aKeyPair.getPublic()).getW().getAffineY()); fail(algorithm + " public key encoding (W test) failed"); } if (!pubKey.getParams().getGenerator().equals(((ECPublicKey)aKeyPair.getPublic()).getParams().getGenerator())) { fail(algorithm + " public key encoding (G test) failed"); } // // private key encoding test // byte[] privEnc = aKeyPair.getPrivate().getEncoded(); PKCS8EncodedKeySpec privPKCS8 = new PKCS8EncodedKeySpec(privEnc); ECPrivateKey privKey = (ECPrivateKey)keyFac.generatePrivate(privPKCS8); if (!privKey.getS().equals(((ECPrivateKey)aKeyPair.getPrivate()).getS())) { fail(algorithm + " private key encoding (S test) failed"); } if (!privKey.getParams().getGenerator().equals(((ECPrivateKey)aKeyPair.getPrivate()).getParams().getGenerator())) { fail(algorithm + " private key encoding (G test) failed"); } } private void testExceptions() { try { KeyAgreement aKeyAgree = KeyAgreement.getInstance("DH", "BC"); aKeyAgree.generateSecret("DES"); } catch (IllegalStateException e) { // okay } catch (Exception e) { fail("Unexpected exception: " + e, e); } } private void testDESAndDESede(BigInteger g, BigInteger p) throws Exception { DHParameterSpec dhParams = new DHParameterSpec(p, g, 256); KeyPairGenerator keyGen = KeyPairGenerator.getInstance("DH", "BC"); keyGen.initialize(dhParams); KeyPair kp = keyGen.generateKeyPair(); KeyAgreement keyAgreement = KeyAgreement.getInstance("DH", "BC"); keyAgreement.init(kp.getPrivate()); keyAgreement.doPhase(kp.getPublic(), true); SecretKey key = keyAgreement.generateSecret("DES"); if (key.getEncoded().length != 8) { fail("DES length wrong"); } if (!DESKeySpec.isParityAdjusted(key.getEncoded(), 0)) { fail("DES parity wrong"); } key = keyAgreement.generateSecret("DESEDE"); if (key.getEncoded().length != 24) { fail("DESEDE length wrong"); } if (!DESedeKeySpec.isParityAdjusted(key.getEncoded(), 0)) { fail("DESEDE parity wrong"); } key = keyAgreement.generateSecret("Blowfish"); if (key.getEncoded().length != 16) { fail("Blowfish length wrong"); } } private void testInitialise() throws Exception { KeyPairGenerator keyGen = KeyPairGenerator.getInstance("DH", "BC"); keyGen.initialize(512); keyGen.generateKeyPair(); testTwoParty("DH", 512, 0, keyGen); } private void testEnc() throws Exception { KeyFactory kFact = KeyFactory.getInstance("DH", "BC"); Key k = kFact.generatePrivate(new PKCS8EncodedKeySpec(samplePrivEnc)); if (!Arrays.areEqual(samplePrivEnc, k.getEncoded())) { fail("private key re-encode failed"); } k = kFact.generatePublic(new X509EncodedKeySpec(samplePubEnc)); if (!Arrays.areEqual(samplePubEnc, k.getEncoded())) { fail("public key re-encode failed"); } k = kFact.generatePublic(new X509EncodedKeySpec(oldPubEnc)); if (!Arrays.areEqual(oldPubEnc, k.getEncoded())) { fail("old public key re-encode failed"); } k = kFact.generatePublic(new X509EncodedKeySpec(oldFullParams)); if (!Arrays.areEqual(oldFullParams, k.getEncoded())) { fail("old full public key re-encode failed"); } } private void testConfig() { ConfigurableProvider prov = new BouncyCastleProvider(); DHParameterSpec dhSpec512 = new DHParameterSpec( new BigInteger("fca682ce8e12caba26efccf7110e526db078b05edecbcd1eb4a208f3ae1617ae01f35b91a47e6df63413c5e12ed0899bcd132acd50d99151bdc43ee737592e17", 16), new BigInteger("678471b27a9cf44ee91a49c5147db1a9aaf244f05a434d6486931d2d14271b9e35030b71fd73da179069b32e2935630e1c2062354d0da20a6c416e50be794ca4", 16), 384); DHParameterSpec dhSpec768 = new DHParameterSpec( new BigInteger("e9e642599d355f37c97ffd3567120b8e25c9cd43e927b3a9670fbec5d890141922d2c3b3ad2480093799869d1e846aab49fab0ad26d2ce6a22219d470bce7d777d4a21fbe9c270b57f607002f3cef8393694cf45ee3688c11a8c56ab127a3daf", 16), new BigInteger("30470ad5a005fb14ce2d9dcd87e38bc7d1b1c5facbaecbe95f190aa7a31d23c4dbbcbe06174544401a5b2c020965d8c2bd2171d3668445771f74ba084d2029d83c1c158547f3a9f1a2715be23d51ae4d3e5a1f6a7064f316933a346d3f529252", 16), 384); DHParameterSpec dhSpec1024 = new DHParameterSpec( new BigInteger("f7e1a085d69b3ddecbbcab5c36b857b97994afbbfa3aea82f9574c0b3d0782675159578ebad4594fe67107108180b449167123e84c281613b7cf09328cc8a6e13c167a8b547c8d28e0a3ae1e2bb3a675916ea37f0bfa213562f1fb627a01243bcca4f1bea8519089a883dfe15ae59f06928b665e807b552564014c3bfecf492a", 16), new BigInteger("fd7f53811d75122952df4a9c2eece4e7f611b7523cef4400c31e3f80b6512669455d402251fb593d8d58fabfc5f5ba30f6cb9b556cd7813b801d346ff26660b76b9950a5a49f9fe8047b1022c24fbba9d7feb7c61bf83b57e7c6a8a6150f04fb83f6d3c51ec3023554135a169132f675f3ae2b61d72aeff22203199dd14801c7", 16), 512); prov.setParameter(ConfigurableProvider.DH_DEFAULT_PARAMS, dhSpec512); if (!dhSpec512.equals(BouncyCastleProvider.CONFIGURATION.getDHDefaultParameters(512))) { fail("config mismatch"); } if (BouncyCastleProvider.CONFIGURATION.getDHDefaultParameters(768) != null) { fail("config found when none expected"); } prov.setParameter(ConfigurableProvider.DH_DEFAULT_PARAMS, new DHParameterSpec[] { dhSpec512, dhSpec768, dhSpec1024 }); if (!dhSpec512.equals(BouncyCastleProvider.CONFIGURATION.getDHDefaultParameters(512))) { fail("512 config mismatch"); } if (!dhSpec768.equals(BouncyCastleProvider.CONFIGURATION.getDHDefaultParameters(768))) { fail("768 config mismatch"); } if (!dhSpec1024.equals(BouncyCastleProvider.CONFIGURATION.getDHDefaultParameters(1024))) { fail("1024 config mismatch"); } prov.setParameter(ConfigurableProvider.DH_DEFAULT_PARAMS, null); if (BouncyCastleProvider.CONFIGURATION.getDHDefaultParameters(512) != null) { fail("config found for 512 when none expected"); } if (BouncyCastleProvider.CONFIGURATION.getDHDefaultParameters(768) != null) { fail("config found for 768 when none expected"); } prov.setParameter(ConfigurableProvider.THREAD_LOCAL_DH_DEFAULT_PARAMS, dhSpec512); if (!dhSpec512.equals(BouncyCastleProvider.CONFIGURATION.getDHDefaultParameters(512))) { fail("config mismatch"); } if (BouncyCastleProvider.CONFIGURATION.getDHDefaultParameters(768) != null) { fail("config found when none expected"); } prov.setParameter(ConfigurableProvider.THREAD_LOCAL_DH_DEFAULT_PARAMS, new DHParameterSpec[] { dhSpec512, dhSpec768, dhSpec1024 }); if (!dhSpec512.equals(BouncyCastleProvider.CONFIGURATION.getDHDefaultParameters(512))) { fail("512 config mismatch"); } if (!dhSpec768.equals(BouncyCastleProvider.CONFIGURATION.getDHDefaultParameters(768))) { fail("768 config mismatch"); } if (!dhSpec1024.equals(BouncyCastleProvider.CONFIGURATION.getDHDefaultParameters(1024))) { fail("1024 config mismatch"); } prov.setParameter(ConfigurableProvider.THREAD_LOCAL_DH_DEFAULT_PARAMS, null); if (BouncyCastleProvider.CONFIGURATION.getDHDefaultParameters(512) != null) { fail("config found for 512 when none expected"); } if (BouncyCastleProvider.CONFIGURATION.getDHDefaultParameters(768) != null) { fail("config found for 768 when none expected"); } } public void performTest() throws Exception { testDefault(64, g512, p512); testEnc(); testGP("DH", 512, 0, g512, p512); testGP("DiffieHellman", 768, 0, g768, p768); testGP("DIFFIEHELLMAN", 1024, 0, g1024, p1024); testGP("DH", 512, 64, g512, p512); testGP("DiffieHellman", 768, 128, g768, p768); testGP("DIFFIEHELLMAN", 1024, 256, g1024, p1024); testExplicitWrapping(512, 0, g512, p512); testRandom(256); testECDH("ECDH"); testECDH("ECDHC"); testExceptions(); testDESAndDESede(g768, p768); testInitialise(); testConfig(); } public static void main( String[] args) { Security.addProvider(new BouncyCastleProvider()); runTest(new DHTest()); } } bouncycastle-1.49.orig/test/src/org/bouncycastle/jce/provider/test/PKIXPolicyMappingTest.java0000644000175000017500000005321411725304160032011 0ustar ebourgebourgpackage org.bouncycastle.jce.provider.test; import java.io.IOException; import java.math.BigInteger; import java.security.InvalidAlgorithmParameterException; import java.security.KeyFactory; import java.security.NoSuchAlgorithmException; import java.security.NoSuchProviderException; import java.security.PrivateKey; import java.security.PublicKey; import java.security.Security; import java.security.cert.CertPathBuilder; import java.security.cert.CertStore; import java.security.cert.CollectionCertStoreParameters; import java.security.cert.PKIXBuilderParameters; import java.security.cert.PKIXCertPathBuilderResult; import java.security.cert.TrustAnchor; import java.security.cert.X509CertSelector; import java.security.cert.X509Certificate; import java.security.spec.RSAPrivateCrtKeySpec; import java.security.spec.RSAPublicKeySpec; import java.util.Date; import java.util.HashSet; import java.util.Hashtable; import java.util.Set; import org.bouncycastle.asn1.ASN1EncodableVector; import org.bouncycastle.asn1.ASN1ObjectIdentifier; import org.bouncycastle.asn1.DERSequence; import org.bouncycastle.asn1.x509.BasicConstraints; import org.bouncycastle.asn1.x509.CertificatePolicies; import org.bouncycastle.asn1.x509.PolicyInformation; import org.bouncycastle.asn1.x509.PolicyMappings; import org.bouncycastle.asn1.x509.X509Extensions; import org.bouncycastle.jce.X509Principal; import org.bouncycastle.jce.provider.BouncyCastleProvider; import org.bouncycastle.util.test.SimpleTest; import org.bouncycastle.util.test.TestFailedException; import org.bouncycastle.x509.X509V3CertificateGenerator; public class PKIXPolicyMappingTest extends SimpleTest { static X509V3CertificateGenerator v3CertGen = new X509V3CertificateGenerator(); public String getName() { return "PKIXPolicyMapping"; } /** * TrustAnchor's Cert */ private X509Certificate createTrustCert( PublicKey pubKey, PrivateKey privKey) throws Exception { String issuer = "C=JP, O=policyMappingAdditionalTest, OU=trustAnchor"; String subject = "C=JP, O=policyMappingAdditionalTest, OU=trustAnchor"; v3CertGen.setSerialNumber(BigInteger.valueOf(10)); v3CertGen.setIssuerDN(new X509Principal(issuer)); v3CertGen.setNotBefore(new Date(System.currentTimeMillis() - 1000L * 60 * 60 * 24 * 30)); v3CertGen.setNotAfter(new Date(System.currentTimeMillis() + (1000L * 60 * 60 * 24 * 30))); v3CertGen.setSubjectDN(new X509Principal(subject)); v3CertGen.setPublicKey(pubKey); v3CertGen.setSignatureAlgorithm("SHA1WithRSAEncryption"); X509Certificate cert = v3CertGen.generate(privKey); return cert; } /** * intermediate cert */ private X509Certificate createIntmedCert( PublicKey pubKey, PrivateKey caPrivKey, PublicKey caPubKey, CertificatePolicies policies, Hashtable policyMap) throws Exception { String issuer = "C=JP, O=policyMappingAdditionalTest, OU=trustAnchor"; String subject = "C=JP, O=policyMappingAdditionalTest, OU=intmedCA"; v3CertGen.reset(); v3CertGen.setSerialNumber(BigInteger.valueOf(20)); v3CertGen.setIssuerDN(new X509Principal(issuer)); v3CertGen.setNotBefore(new Date(System.currentTimeMillis() - 1000L * 60 * 60 * 24 * 30)); v3CertGen.setNotAfter(new Date(System.currentTimeMillis() + (1000L * 60 * 60 * 24 * 30))); v3CertGen.setSubjectDN(new X509Principal(subject)); v3CertGen.setPublicKey(pubKey); v3CertGen.setSignatureAlgorithm("SHA1WithRSAEncryption"); v3CertGen.addExtension(X509Extensions.CertificatePolicies, true, policies); v3CertGen.addExtension(X509Extensions.BasicConstraints, true, new BasicConstraints(true)); v3CertGen.addExtension(X509Extensions.PolicyMappings, true, new PolicyMappings(policyMap)); X509Certificate cert = v3CertGen.generate(caPrivKey); return cert; } /** * endEntity cert */ private X509Certificate createEndEntityCert( PublicKey pubKey, PrivateKey caPrivKey, PublicKey caPubKey, ASN1EncodableVector policies) throws Exception { String issuer = "C=JP, O=policyMappingAdditionalTest, OU=intMedCA"; String subject = "C=JP, O=policyMappingAdditionalTest, OU=endEntity"; v3CertGen.reset(); v3CertGen.setSerialNumber(BigInteger.valueOf(20)); v3CertGen.setIssuerDN(new X509Principal(issuer)); v3CertGen.setNotBefore(new Date(System.currentTimeMillis() - 1000L * 60 * 60 * 24 * 30)); v3CertGen.setNotAfter(new Date(System.currentTimeMillis() + (1000L * 60 * 60 * 24 * 30))); v3CertGen.setSubjectDN(new X509Principal(subject)); v3CertGen.setPublicKey(pubKey); v3CertGen.setSignatureAlgorithm("SHA1WithRSAEncryption"); v3CertGen.addExtension(X509Extensions.CertificatePolicies,true,new DERSequence(policies)); X509Certificate cert = v3CertGen.generate(caPrivKey); return cert; } private String testPolicies( int index, X509Certificate trustCert, X509Certificate intCert, X509Certificate endCert, Set requirePolicies, boolean okay) throws IOException, InvalidAlgorithmParameterException, NoSuchAlgorithmException, NoSuchProviderException { Set trust = new HashSet(); trust.add(new TrustAnchor(trustCert, null)); X509CertSelector targetConstraints = new X509CertSelector(); targetConstraints.setSubject(endCert.getSubjectX500Principal().getEncoded()); PKIXBuilderParameters params = new PKIXBuilderParameters(trust, targetConstraints); Set certs = new HashSet(); certs.add(intCert); certs.add(endCert); CollectionCertStoreParameters pr = new CollectionCertStoreParameters(certs); CertStore store = CertStore.getInstance("Collection",pr); params.addCertStore(store); params.setRevocationEnabled(false); if (requirePolicies != null) { params.setExplicitPolicyRequired(true); params.setInitialPolicies(requirePolicies); } CertPathBuilder cpb = CertPathBuilder.getInstance("PKIX","BC"); // CertPathBuilder cpb = CertPathBuilder.getInstance("PKIX","SUN"); PKIXCertPathBuilderResult result = null; try { result = (PKIXCertPathBuilderResult)cpb.build(params); if (!okay) { fail(index + ": path validated when failure expected."); } // if (result.getPolicyTree() != null) // { // System.out.println("OK"); // System.out.println("policy: " + result.getPolicyTree()); // } // else // { // System.out.println("OK: policy tree = null"); // } return ""; } catch (TestFailedException e) { throw e; } catch (Exception e) { if (okay) { fail(index + ": path failed to validate when success expected."); } Throwable ee = e.getCause(); if (ee != null) { return ee.getMessage(); } return e.getMessage(); } } public void performTest() throws Exception { // // personal keys // RSAPublicKeySpec pubKeySpec = new RSAPublicKeySpec( new BigInteger("b4a7e46170574f16a97082b22be58b6a2a629798419be12872a4bdba626cfae9900f76abfb12139dce5de56564fab2b6543165a040c606887420e33d91ed7ed7", 16), new BigInteger("11", 16)); RSAPrivateCrtKeySpec privKeySpec = new RSAPrivateCrtKeySpec( new BigInteger("b4a7e46170574f16a97082b22be58b6a2a629798419be12872a4bdba626cfae9900f76abfb12139dce5de56564fab2b6543165a040c606887420e33d91ed7ed7", 16), new BigInteger("11", 16), new BigInteger("9f66f6b05410cd503b2709e88115d55daced94d1a34d4e32bf824d0dde6028ae79c5f07b580f5dce240d7111f7ddb130a7945cd7d957d1920994da389f490c89", 16), new BigInteger("c0a0758cdf14256f78d4708c86becdead1b50ad4ad6c5c703e2168fbf37884cb", 16), new BigInteger("f01734d7960ea60070f1b06f2bb81bfac48ff192ae18451d5e56c734a5aab8a5", 16), new BigInteger("b54bb9edff22051d9ee60f9351a48591b6500a319429c069a3e335a1d6171391", 16), new BigInteger("d3d83daf2a0cecd3367ae6f8ae1aeb82e9ac2f816c6fc483533d8297dd7884cd", 16), new BigInteger("b8f52fc6f38593dabb661d3f50f8897f8106eee68b1bce78a95b132b4e5b5d19", 16)); // // intermediate keys. // RSAPublicKeySpec intPubKeySpec = new RSAPublicKeySpec( new BigInteger("8de0d113c5e736969c8d2b047a243f8fe18edad64cde9e842d3669230ca486f7cfdde1f8eec54d1905fff04acc85e61093e180cadc6cea407f193d44bb0e9449b8dbb49784cd9e36260c39e06a947299978c6ed8300724e887198cfede20f3fbde658fa2bd078be946a392bd349f2b49c486e20c405588e306706c9017308e69", 16), new BigInteger("ffff", 16)); RSAPrivateCrtKeySpec intPrivKeySpec = new RSAPrivateCrtKeySpec( new BigInteger("8de0d113c5e736969c8d2b047a243f8fe18edad64cde9e842d3669230ca486f7cfdde1f8eec54d1905fff04acc85e61093e180cadc6cea407f193d44bb0e9449b8dbb49784cd9e36260c39e06a947299978c6ed8300724e887198cfede20f3fbde658fa2bd078be946a392bd349f2b49c486e20c405588e306706c9017308e69", 16), new BigInteger("ffff", 16), new BigInteger("7deb1b194a85bcfd29cf871411468adbc987650903e3bacc8338c449ca7b32efd39ffc33bc84412fcd7df18d23ce9d7c25ea910b1ae9985373e0273b4dca7f2e0db3b7314056ac67fd277f8f89cf2fd73c34c6ca69f9ba477143d2b0e2445548aa0b4a8473095182631da46844c356f5e5c7522eb54b5a33f11d730ead9c0cff", 16), new BigInteger("ef4cede573cea47f83699b814de4302edb60eefe426c52e17bd7870ec7c6b7a24fe55282ebb73775f369157726fcfb988def2b40350bdca9e5b418340288f649", 16), new BigInteger("97c7737d1b9a0088c3c7b528539247fd2a1593e7e01cef18848755be82f4a45aa093276cb0cbf118cb41117540a78f3fc471ba5d69f0042274defc9161265721", 16), new BigInteger("6c641094e24d172728b8da3c2777e69adfd0839085be7e38c7c4a2dd00b1ae969f2ec9d23e7e37090fcd449a40af0ed463fe1c612d6810d6b4f58b7bfa31eb5f", 16), new BigInteger("70b7123e8e69dfa76feb1236d0a686144b00e9232ed52b73847e74ef3af71fb45ccb24261f40d27f98101e230cf27b977a5d5f1f15f6cf48d5cb1da2a3a3b87f", 16), new BigInteger("e38f5750d97e270996a286df2e653fd26c242106436f5bab0f4c7a9e654ce02665d5a281f2c412456f2d1fa26586ef04a9adac9004ca7f913162cb28e13bf40d", 16)); // // ca keys // RSAPublicKeySpec caPubKeySpec = new RSAPublicKeySpec( new BigInteger("b259d2d6e627a768c94be36164c2d9fc79d97aab9253140e5bf17751197731d6f7540d2509e7b9ffee0a70a6e26d56e92d2edd7f85aba85600b69089f35f6bdbf3c298e05842535d9f064e6b0391cb7d306e0a2d20c4dfb4e7b49a9640bdea26c10ad69c3f05007ce2513cee44cfe01998e62b6c3637d3fc0391079b26ee36d5", 16), new BigInteger("11", 16)); RSAPrivateCrtKeySpec caPrivKeySpec = new RSAPrivateCrtKeySpec( new BigInteger("b259d2d6e627a768c94be36164c2d9fc79d97aab9253140e5bf17751197731d6f7540d2509e7b9ffee0a70a6e26d56e92d2edd7f85aba85600b69089f35f6bdbf3c298e05842535d9f064e6b0391cb7d306e0a2d20c4dfb4e7b49a9640bdea26c10ad69c3f05007ce2513cee44cfe01998e62b6c3637d3fc0391079b26ee36d5", 16), new BigInteger("11", 16), new BigInteger("92e08f83cc9920746989ca5034dcb384a094fb9c5a6288fcc4304424ab8f56388f72652d8fafc65a4b9020896f2cde297080f2a540e7b7ce5af0b3446e1258d1dd7f245cf54124b4c6e17da21b90a0ebd22605e6f45c9f136d7a13eaac1c0f7487de8bd6d924972408ebb58af71e76fd7b012a8d0e165f3ae2e5077a8648e619", 16), new BigInteger("f75e80839b9b9379f1cf1128f321639757dba514642c206bbbd99f9a4846208b3e93fbbe5e0527cc59b1d4b929d9555853004c7c8b30ee6a213c3d1bb7415d03", 16), new BigInteger("b892d9ebdbfc37e397256dd8a5d3123534d1f03726284743ddc6be3a709edb696fc40c7d902ed804c6eee730eee3d5b20bf6bd8d87a296813c87d3b3cc9d7947", 16), new BigInteger("1d1a2d3ca8e52068b3094d501c9a842fec37f54db16e9a67070a8b3f53cc03d4257ad252a1a640eadd603724d7bf3737914b544ae332eedf4f34436cac25ceb5", 16), new BigInteger("6c929e4e81672fef49d9c825163fec97c4b7ba7acb26c0824638ac22605d7201c94625770984f78a56e6e25904fe7db407099cad9b14588841b94f5ab498dded", 16), new BigInteger("dae7651ee69ad1d081ec5e7188ae126f6004ff39556bde90e0b870962fa7b926d070686d8244fe5a9aa709a95686a104614834b0ada4b10f53197a5cb4c97339", 16)); // // set up the keys // KeyFactory fact = KeyFactory.getInstance("RSA", "BC"); PrivateKey caPrivKey = fact.generatePrivate(caPrivKeySpec); PublicKey caPubKey = fact.generatePublic(caPubKeySpec); PrivateKey intPrivKey = fact.generatePrivate(intPrivKeySpec); PublicKey intPubKey = fact.generatePublic(intPubKeySpec); PrivateKey privKey = fact.generatePrivate(privKeySpec); PublicKey pubKey = fact.generatePublic(pubKeySpec); X509Certificate trustCert = createTrustCert(caPubKey, caPrivKey); CertificatePolicies intPolicies = null; Hashtable map = null; ASN1EncodableVector policies = null; Set requirePolicies = null; X509Certificate intCert = null; X509Certificate endCert = null; /** * valid test_00 */ intPolicies = new CertificatePolicies(new PolicyInformation(new ASN1ObjectIdentifier("2.5.29.32.0"))); map = new Hashtable(); map.put("2.16.840.1.101.3.2.1.48.1","2.16.840.1.101.3.2.1.48.2"); intCert = createIntmedCert(intPubKey, caPrivKey, caPubKey, intPolicies, map); policies = new ASN1EncodableVector(); policies.add(new PolicyInformation(new ASN1ObjectIdentifier("2.16.840.1.101.3.2.1.48.2"))); endCert = createEndEntityCert(pubKey, intPrivKey, intPubKey, policies); requirePolicies = null; String msg = testPolicies(0, trustCert, intCert, endCert, requirePolicies, true); checkMessage(0, msg, ""); /** * test_01 */ intPolicies = new CertificatePolicies(new PolicyInformation(new ASN1ObjectIdentifier("2.5.29.32.0"))); map = new Hashtable(); map.put("2.16.840.1.101.3.2.1.48.1","2.16.840.1.101.3.2.1.48.2"); intCert = createIntmedCert(intPubKey, caPrivKey, caPubKey, intPolicies, map); policies = new ASN1EncodableVector(); policies.add(new PolicyInformation(new ASN1ObjectIdentifier("2.16.840.1.101.3.2.1.48.2"))); endCert = createEndEntityCert(pubKey, intPrivKey, intPubKey, policies); requirePolicies = new HashSet(); requirePolicies.add("2.16.840.1.101.3.2.1.48.1"); msg = testPolicies(1, trustCert, intCert, endCert, requirePolicies, true); checkMessage(1, msg, ""); /** * test_02 */ intPolicies = new CertificatePolicies(new PolicyInformation(new ASN1ObjectIdentifier("2.5.29.32.0"))); map = new Hashtable(); map.put("2.16.840.1.101.3.2.1.48.1","2.16.840.1.101.3.2.1.48.2"); intCert = createIntmedCert(intPubKey, caPrivKey, caPubKey, intPolicies, map); policies = new ASN1EncodableVector(); policies.add(new PolicyInformation(new ASN1ObjectIdentifier("2.16.840.1.101.3.2.1.48.2"))); endCert = createEndEntityCert(pubKey, intPrivKey, intPubKey, policies); requirePolicies = new HashSet(); requirePolicies.add("2.5.29.32.0"); msg = testPolicies(2, trustCert, intCert, endCert, requirePolicies, true); checkMessage(2, msg, ""); /** * test_03 */ intPolicies = new CertificatePolicies(new PolicyInformation[] { new PolicyInformation(new ASN1ObjectIdentifier("2.16.840.1.101.3.2.1.48.3")), new PolicyInformation(new ASN1ObjectIdentifier("2.5.29.32.0")) }); map = new Hashtable(); map.put("2.16.840.1.101.3.2.1.48.1","2.16.840.1.101.3.2.1.48.2"); intCert = createIntmedCert(intPubKey, caPrivKey, caPubKey, intPolicies, map); policies = new ASN1EncodableVector(); policies.add(new PolicyInformation(new ASN1ObjectIdentifier("2.16.840.1.101.3.2.1.48.2"))); endCert = createEndEntityCert(pubKey, intPrivKey, intPubKey, policies); requirePolicies = new HashSet(); requirePolicies.add("2.16.840.1.101.3.2.1.48.1"); msg = testPolicies(3, trustCert, intCert, endCert, requirePolicies, true); checkMessage(3, msg, ""); /** * test_04 */ intPolicies = new CertificatePolicies(new PolicyInformation[] { new PolicyInformation(new ASN1ObjectIdentifier("2.16.840.1.101.3.2.1.48.3")), new PolicyInformation(new ASN1ObjectIdentifier("2.5.29.32.0")) } ); map = new Hashtable(); map.put("2.16.840.1.101.3.2.1.48.1", "2.16.840.1.101.3.2.1.48.2"); intCert = createIntmedCert(intPubKey, caPrivKey, caPubKey, intPolicies, map); policies = new ASN1EncodableVector(); policies.add(new PolicyInformation(new ASN1ObjectIdentifier("2.16.840.1.101.3.2.1.48.3"))); endCert = createEndEntityCert(pubKey, intPrivKey, intPubKey, policies); requirePolicies = new HashSet(); requirePolicies.add("2.16.840.1.101.3.2.1.48.3"); msg = testPolicies(4, trustCert, intCert, endCert, requirePolicies, true); checkMessage(4, msg, ""); /** * test_05 */ intPolicies = new CertificatePolicies(new PolicyInformation(new ASN1ObjectIdentifier("2.5.29.32.0"))); map = new Hashtable(); map.put("2.16.840.1.101.3.2.1.48.1", "2.16.840.1.101.3.2.1.48.2"); intCert = createIntmedCert(intPubKey, caPrivKey, caPubKey, intPolicies, map); policies = new ASN1EncodableVector(); policies.add(new PolicyInformation(new ASN1ObjectIdentifier("2.16.840.1.101.3.2.1.48.2"))); endCert = createEndEntityCert(pubKey, intPrivKey, intPubKey, policies); requirePolicies = new HashSet(); requirePolicies.add("2.16.840.1.101.3.2.1.48.2"); msg = testPolicies(5, trustCert, intCert, endCert, requirePolicies, false); checkMessage(5, msg, "Path processing failed on policy."); /** * test_06 */ intPolicies = new CertificatePolicies(new PolicyInformation(new ASN1ObjectIdentifier("2.5.29.32.0"))); map = new Hashtable(); map.put("2.16.840.1.101.3.2.1.48.1", "2.16.840.1.101.3.2.1.48.2"); intCert = createIntmedCert(intPubKey, caPrivKey, caPubKey, intPolicies, map); policies = new ASN1EncodableVector(); policies.add(new PolicyInformation(new ASN1ObjectIdentifier("2.16.840.1.101.3.2.1.48.1"))); endCert = createEndEntityCert(pubKey, intPrivKey, intPubKey, policies); requirePolicies = new HashSet(); requirePolicies.add("2.16.840.1.101.3.2.1.48.1"); msg = testPolicies(6, trustCert, intCert, endCert, requirePolicies, true); checkMessage(6, msg, ""); /** * test_07 */ intPolicies = new CertificatePolicies(new PolicyInformation(new ASN1ObjectIdentifier("2.5.29.32.0"))); map = new Hashtable(); map.put("2.16.840.1.101.3.2.1.48.1", "2.16.840.1.101.3.2.1.48.2"); intCert = createIntmedCert(intPubKey, caPrivKey, caPubKey, intPolicies, map); policies = new ASN1EncodableVector(); policies.add(new PolicyInformation(new ASN1ObjectIdentifier("2.16.840.1.101.3.2.1.48.2"))); endCert = createEndEntityCert(pubKey, intPrivKey, intPubKey, policies); requirePolicies = new HashSet(); requirePolicies.add("2.16.840.1.101.3.2.1.48.3"); msg = testPolicies(7, trustCert, intCert, endCert, requirePolicies, false); checkMessage(7, msg, "Path processing failed on policy."); /** * test_08 */ intPolicies = new CertificatePolicies(new PolicyInformation(new ASN1ObjectIdentifier("2.5.29.32.0"))); map = new Hashtable(); map.put("2.16.840.1.101.3.2.1.48.1", "2.16.840.1.101.3.2.1.48.2"); intCert = createIntmedCert(intPubKey, caPrivKey, caPubKey, intPolicies, map); policies = new ASN1EncodableVector(); policies.add(new PolicyInformation(new ASN1ObjectIdentifier("2.16.840.1.101.3.2.1.48.3"))); endCert = createEndEntityCert(pubKey, intPrivKey, intPubKey, policies); requirePolicies = new HashSet(); requirePolicies.add("2.16.840.1.101.3.2.1.48.1"); msg = testPolicies(8, trustCert, intCert, endCert, requirePolicies, false); checkMessage(8, msg, "Path processing failed on policy."); } private void checkMessage( int index, String msg, String expected) { if (!msg.equals(expected)) { fail("test " + index + " failed got: " + msg + " expected: " + expected); } } public static void main( String[] args) { Security.addProvider(new BouncyCastleProvider()); runTest(new PKIXPolicyMappingTest()); } } bouncycastle-1.49.orig/test/src/org/bouncycastle/jce/provider/test/PSSTest.java0000644000175000017500000002466311256062655027226 0ustar ebourgebourgpackage org.bouncycastle.jce.provider.test; import java.math.BigInteger; import java.security.AlgorithmParameters; import java.security.KeyFactory; import java.security.MessageDigest; import java.security.PrivateKey; import java.security.PublicKey; import java.security.SecureRandom; import java.security.Security; import java.security.Signature; import java.security.spec.MGF1ParameterSpec; import java.security.spec.PSSParameterSpec; import java.security.spec.RSAPrivateCrtKeySpec; import java.security.spec.RSAPublicKeySpec; import org.bouncycastle.asn1.DERObjectIdentifier; import org.bouncycastle.asn1.nist.NISTObjectIdentifiers; import org.bouncycastle.asn1.x509.X509ObjectIdentifiers; import org.bouncycastle.jce.provider.BouncyCastleProvider; import org.bouncycastle.util.Arrays; import org.bouncycastle.util.encoders.Hex; import org.bouncycastle.util.test.FixedSecureRandom; import org.bouncycastle.util.test.SimpleTest; public class PSSTest extends SimpleTest { private class FixedRandom extends SecureRandom { byte[] vals; FixedRandom( byte[] vals) { this.vals = vals; } public void nextBytes( byte[] bytes) { System.arraycopy(vals, 0, bytes, 0, vals.length); } } private boolean arrayEquals( byte[] a, byte[] b) { if (a.length != b.length) { return false; } for (int i = 0; i != a.length; i++) { if (a[i] != b[i]) { return false; } } return true; } private RSAPublicKeySpec pubKeySpec = new RSAPublicKeySpec( new BigInteger("a56e4a0e701017589a5187dc7ea841d156f2ec0e36ad52a44dfeb1e61f7ad991d8c51056ffedb162b4c0f283a12a88a394dff526ab7291cbb307ceabfce0b1dfd5cd9508096d5b2b8b6df5d671ef6377c0921cb23c270a70e2598e6ff89d19f105acc2d3f0cb35f29280e1386b6f64c4ef22e1e1f20d0ce8cffb2249bd9a2137",16), new BigInteger("010001",16)); private RSAPrivateCrtKeySpec privKeySpec = new RSAPrivateCrtKeySpec( new BigInteger("a56e4a0e701017589a5187dc7ea841d156f2ec0e36ad52a44dfeb1e61f7ad991d8c51056ffedb162b4c0f283a12a88a394dff526ab7291cbb307ceabfce0b1dfd5cd9508096d5b2b8b6df5d671ef6377c0921cb23c270a70e2598e6ff89d19f105acc2d3f0cb35f29280e1386b6f64c4ef22e1e1f20d0ce8cffb2249bd9a2137",16), new BigInteger("010001",16), new BigInteger("33a5042a90b27d4f5451ca9bbbd0b44771a101af884340aef9885f2a4bbe92e894a724ac3c568c8f97853ad07c0266c8c6a3ca0929f1e8f11231884429fc4d9ae55fee896a10ce707c3ed7e734e44727a39574501a532683109c2abacaba283c31b4bd2f53c3ee37e352cee34f9e503bd80c0622ad79c6dcee883547c6a3b325",16), new BigInteger("e7e8942720a877517273a356053ea2a1bc0c94aa72d55c6e86296b2dfc967948c0a72cbccca7eacb35706e09a1df55a1535bd9b3cc34160b3b6dcd3eda8e6443",16), new BigInteger("b69dca1cf7d4d7ec81e75b90fcca874abcde123fd2700180aa90479b6e48de8d67ed24f9f19d85ba275874f542cd20dc723e6963364a1f9425452b269a6799fd",16), new BigInteger("28fa13938655be1f8a159cbaca5a72ea190c30089e19cd274a556f36c4f6e19f554b34c077790427bbdd8dd3ede2448328f385d81b30e8e43b2fffa027861979",16), new BigInteger("1a8b38f398fa712049898d7fb79ee0a77668791299cdfa09efc0e507acb21ed74301ef5bfd48be455eaeb6e1678255827580a8e4e8e14151d1510a82a3f2e729",16), new BigInteger("27156aba4126d24a81f3a528cbfb27f56886f840a9f6e86e17a44b94fe9319584b8e22fdde1e5a2e3bd8aa5ba8d8584194eb2190acf832b847f13a3d24a79f4d",16)); // PSSExample1.1 private byte[] msg1a = Hex.decode("cdc87da223d786df3b45e0bbbc721326d1ee2af806cc315475cc6f0d9c66e1b62371d45ce2392e1ac92844c310102f156a0d8d52c1f4c40ba3aa65095786cb769757a6563ba958fed0bcc984e8b517a3d5f515b23b8a41e74aa867693f90dfb061a6e86dfaaee64472c00e5f20945729cbebe77f06ce78e08f4098fba41f9d6193c0317e8b60d4b6084acb42d29e3808a3bc372d85e331170fcbf7cc72d0b71c296648b3a4d10f416295d0807aa625cab2744fd9ea8fd223c42537029828bd16be02546f130fd2e33b936d2676e08aed1b73318b750a0167d0"); private byte[] slt1a = Hex.decode("dee959c7e06411361420ff80185ed57f3e6776af"); private byte[] sig1a = Hex.decode("9074308fb598e9701b2294388e52f971faac2b60a5145af185df5287b5ed2887e57ce7fd44dc8634e407c8e0e4360bc226f3ec227f9d9e54638e8d31f5051215df6ebb9c2f9579aa77598a38f914b5b9c1bd83c4e2f9f382a0d0aa3542ffee65984a601bc69eb28deb27dca12c82c2d4c3f66cd500f1ff2b994d8a4e30cbb33c"); private byte[] sig1b = Hex.decode("96ea348db4db2947aee807bd687411a880913706f21b383a1002b97e43656e5450a9d1812efbedd1ed159f8307986adf48bada66a8efd14bd9e2f6f6f458e73b50c8ce6e3079011c5b4bd1600a2601a66198a1582574a43f13e0966c6c2337e6ca0886cd9e1b1037aeadef1382117d22b35e7e4403f90531c8cfccdf223f98e4"); private byte[] sig1c = Hex.decode("9e64cc1062c537b142480bc5af407b55904ead970e20e0f8f6664279c96c6da6b03522160f224a85cc413dfe6bd00621485b665abac6d90ff38c9af06f4ddd6c7c81540439e5795601a1343d9feb465712ff8a5f5150391522fb5a9b8e2225a555f4efaa5e5c0ed7a19b27074c2d9f6dbbd0c893ba02c4a35b115d337bccd7a2"); public void performTest() throws Exception { KeyFactory fact = KeyFactory.getInstance("RSA", "BC"); PrivateKey privKey = fact.generatePrivate(privKeySpec); PublicKey pubKey = fact.generatePublic(pubKeySpec); Signature s = Signature.getInstance("SHA1withRSA/PSS", "BC"); s.initSign(privKey, new FixedRandom(slt1a)); s.update(msg1a); byte[] sig = s.sign(); if (!arrayEquals(sig1a, sig)) { fail("PSS Sign test expected " + new String(Hex.encode(sig1a)) + " got " + new String(Hex.encode(sig))); } s = Signature.getInstance("SHA1withRSAandMGF1", "BC"); s.initVerify(pubKey); s.update(msg1a); if (!s.verify(sig1a)) { fail("SHA1 signature verification failed"); } s = Signature.getInstance("SHA1withRSAandMGF1", "BC"); s.setParameter(PSSParameterSpec.DEFAULT); s.initVerify(pubKey); s.update(msg1a); if (!s.verify(sig1a)) { fail("SHA1 signature verification with default parameters failed"); } AlgorithmParameters pss = s.getParameters(); if (!arrayEquals(pss.getEncoded(), new byte[] { 0x30, 0x00 })) { fail("failed default encoding test."); } s = Signature.getInstance("SHA256withRSA/PSS", "BC"); s.initSign(privKey, new FixedRandom(slt1a)); s.update(msg1a); sig = s.sign(); pss = s.getParameters(); if (!arrayEquals(sig1b, sig)) { fail("PSS Sign test expected " + new String(Hex.encode(sig1b)) + " got " + new String(Hex.encode(sig))); } s = Signature.getInstance("SHA256withRSAandMGF1", "BC"); s.setParameter(pss.getParameterSpec(PSSParameterSpec.class)); s.initVerify(pubKey); s.update(msg1a); if (!s.verify(sig1b)) { fail("SHA256 signature verification failed"); } // // 512 test -with zero salt length // s = Signature.getInstance("SHA512withRSAandMGF1", "BC"); s.setParameter(new PSSParameterSpec("SHA-512", "MGF1", new MGF1ParameterSpec("SHA-512"), 0, 1)); s.initSign(privKey); s.update(msg1a); sig = s.sign(); pss = s.getParameters(); if (!arrayEquals(sig1c, sig)) { fail("PSS Sign test expected " + new String(Hex.encode(sig1c)) + " got " + new String(Hex.encode(sig))); } s = Signature.getInstance("SHA512withRSAandMGF1", "BC"); s.setParameter(pss.getParameterSpec(PSSParameterSpec.class)); s.initVerify(pubKey); s.update(msg1a); if (!s.verify(sig1c)) { fail("SHA512 signature verification failed"); } SecureRandom random = new SecureRandom(); // Note: PSS minimum key size determined by hash/salt lengths PrivateKey priv2048Key = fact.generatePrivate(RSATest.priv2048KeySpec); PublicKey pub2048Key = fact.generatePublic(RSATest.pub2048KeySpec); rawModeTest("SHA1withRSA/PSS", X509ObjectIdentifiers.id_SHA1, priv2048Key, pub2048Key, random); rawModeTest("SHA224withRSA/PSS", NISTObjectIdentifiers.id_sha224, priv2048Key, pub2048Key, random); rawModeTest("SHA256withRSA/PSS", NISTObjectIdentifiers.id_sha256, priv2048Key, pub2048Key, random); rawModeTest("SHA384withRSA/PSS", NISTObjectIdentifiers.id_sha384, priv2048Key, pub2048Key, random); rawModeTest("SHA512withRSA/PSS", NISTObjectIdentifiers.id_sha512, priv2048Key, pub2048Key, random); } private void rawModeTest(String sigName, DERObjectIdentifier digestOID, PrivateKey privKey, PublicKey pubKey, SecureRandom random) throws Exception { byte[] sampleMessage = new byte[1000 + random.nextInt(100)]; random.nextBytes(sampleMessage); Signature normalSig = Signature.getInstance(sigName, "BC"); PSSParameterSpec spec = (PSSParameterSpec)normalSig.getParameters().getParameterSpec(PSSParameterSpec.class); // Make sure we generate the same 'random' salt for both normal and raw signers int saltLen = spec.getSaltLength(); byte[] fixedRandomBytes = new byte[saltLen]; random.nextBytes(fixedRandomBytes); normalSig.initSign(privKey, new FixedSecureRandom(fixedRandomBytes)); normalSig.update(sampleMessage); byte[] normalResult = normalSig.sign(); MessageDigest digest = MessageDigest.getInstance(digestOID.getId(), "BC"); byte[] hash = digest.digest(sampleMessage); Signature rawSig = Signature.getInstance("RAWRSASSA-PSS", "BC"); // Need to init the params explicitly to avoid having a 'raw' variety of every PSS algorithm rawSig.setParameter(spec); rawSig.initSign(privKey, new FixedSecureRandom(fixedRandomBytes)); rawSig.update(hash); byte[] rawResult = rawSig.sign(); if (!Arrays.areEqual(normalResult, rawResult)) { fail("raw mode signature differs from normal one"); } rawSig.initVerify(pubKey); rawSig.update(hash); if (!rawSig.verify(rawResult)) { fail("raw mode signature verification failed"); } } public String getName() { return "PSSTest"; } public static void main( String[] args) { Security.addProvider(new BouncyCastleProvider()); runTest(new PSSTest()); } } bouncycastle-1.49.orig/test/src/org/bouncycastle/jce/provider/test/AESTest.java0000644000175000017500000002714112131447246027157 0ustar ebourgebourgpackage org.bouncycastle.jce.provider.test; import org.bouncycastle.asn1.nist.NISTObjectIdentifiers; import org.bouncycastle.jce.provider.BouncyCastleProvider; import org.bouncycastle.util.encoders.Hex; import javax.crypto.Cipher; import javax.crypto.CipherInputStream; import javax.crypto.CipherOutputStream; import javax.crypto.NoSuchPaddingException; import javax.crypto.spec.IvParameterSpec; import javax.crypto.spec.SecretKeySpec; import java.io.ByteArrayInputStream; import java.io.ByteArrayOutputStream; import java.io.DataInputStream; import java.io.IOException; import java.security.Key; import java.security.Security; /** * basic test class for the AES cipher vectors from FIPS-197 */ public class AESTest extends BaseBlockCipherTest { static String[] cipherTests = { "128", "000102030405060708090a0b0c0d0e0f", "00112233445566778899aabbccddeeff", "69c4e0d86a7b0430d8cdb78070b4c55a", "192", "000102030405060708090a0b0c0d0e0f1011121314151617", "00112233445566778899aabbccddeeff", "dda97ca4864cdfe06eaf70a0ec0d7191", "256", "000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f", "00112233445566778899aabbccddeeff", "8ea2b7ca516745bfeafc49904b496089", }; public AESTest() { super("AES"); } private void test( int strength, byte[] keyBytes, byte[] input, byte[] output) throws Exception { Key key; Cipher in, out; CipherInputStream cIn; CipherOutputStream cOut; ByteArrayInputStream bIn; ByteArrayOutputStream bOut; key = new SecretKeySpec(keyBytes, "AES"); in = Cipher.getInstance("AES/ECB/NoPadding", "BC"); out = Cipher.getInstance("AES/ECB/NoPadding", "BC"); try { out.init(Cipher.ENCRYPT_MODE, key); } catch (Exception e) { fail("AES failed initialisation - " + e.toString(), e); } try { in.init(Cipher.DECRYPT_MODE, key); } catch (Exception e) { fail("AES failed initialisation - " + e.toString(), e); } // // encryption pass // bOut = new ByteArrayOutputStream(); cOut = new CipherOutputStream(bOut, out); try { for (int i = 0; i != input.length / 2; i++) { cOut.write(input[i]); } cOut.write(input, input.length / 2, input.length - input.length / 2); cOut.close(); } catch (IOException e) { fail("AES failed encryption - " + e.toString(), e); } byte[] bytes; bytes = bOut.toByteArray(); if (!areEqual(bytes, output)) { fail("AES failed encryption - expected " + new String(Hex.encode(output)) + " got " + new String(Hex.encode(bytes))); } // // decryption pass // bIn = new ByteArrayInputStream(bytes); cIn = new CipherInputStream(bIn, in); try { DataInputStream dIn = new DataInputStream(cIn); bytes = new byte[input.length]; for (int i = 0; i != input.length / 2; i++) { bytes[i] = (byte)dIn.read(); } dIn.readFully(bytes, input.length / 2, bytes.length - input.length / 2); } catch (Exception e) { fail("AES failed encryption - " + e.toString(), e); } if (!areEqual(bytes, input)) { fail("AES failed decryption - expected " + new String(Hex.encode(input)) + " got " + new String(Hex.encode(bytes))); } } private void eaxTest() throws Exception { byte[] K = Hex.decode("233952DEE4D5ED5F9B9C6D6FF80FF478"); byte[] N = Hex.decode("62EC67F9C3A4A407FCB2A8C49031A8B3"); byte[] P = Hex.decode("68656c6c6f20776f726c642121"); byte[] C = Hex.decode("2f9f76cb7659c70e4be11670a3e193ae1bc6b5762a"); Key key; Cipher in, out; key = new SecretKeySpec(K, "AES"); in = Cipher.getInstance("AES/EAX/NoPadding", "BC"); out = Cipher.getInstance("AES/EAX/NoPadding", "BC"); in.init(Cipher.ENCRYPT_MODE, key, new IvParameterSpec(N)); byte[] enc = in.doFinal(P); if (!areEqual(enc, C)) { fail("ciphertext doesn't match in EAX"); } out.init(Cipher.DECRYPT_MODE, key, new IvParameterSpec(N)); byte[] dec = out.doFinal(C); if (!areEqual(dec, P)) { fail("plaintext doesn't match in EAX"); } try { in = Cipher.getInstance("AES/EAX/PKCS5Padding", "BC"); fail("bad padding missed in EAX"); } catch (NoSuchPaddingException e) { // expected } } private void ccmTest() throws Exception { byte[] K = Hex.decode("404142434445464748494a4b4c4d4e4f"); byte[] N = Hex.decode("10111213141516"); byte[] P = Hex.decode("68656c6c6f20776f726c642121"); byte[] C = Hex.decode("39264f148b54c456035de0a531c8344f46db12b388"); Key key; Cipher in, out; key = new SecretKeySpec(K, "AES"); in = Cipher.getInstance("AES/CCM/NoPadding", "BC"); out = Cipher.getInstance("AES/CCM/NoPadding", "BC"); in.init(Cipher.ENCRYPT_MODE, key, new IvParameterSpec(N)); byte[] enc = in.doFinal(P); if (!areEqual(enc, C)) { fail("ciphertext doesn't match in CCM"); } out.init(Cipher.DECRYPT_MODE, key, new IvParameterSpec(N)); byte[] dec = out.doFinal(C); if (!areEqual(dec, P)) { fail("plaintext doesn't match in CCM"); } try { in = Cipher.getInstance("AES/CCM/PKCS5Padding", "BC"); fail("bad padding missed in CCM"); } catch (NoSuchPaddingException e) { // expected } } private void gcmTest() throws Exception { // Test Case 15 from McGrew/Viega byte[] K = Hex.decode( "feffe9928665731c6d6a8f9467308308" + "feffe9928665731c6d6a8f9467308308"); byte[] P = Hex.decode( "d9313225f88406e5a55909c5aff5269a" + "86a7a9531534f7da2e4c303d8a318a72" + "1c3c0c95956809532fcf0e2449a6b525" + "b16aedf5aa0de657ba637b391aafd255"); byte[] N = Hex.decode("cafebabefacedbaddecaf888"); String T = "b094dac5d93471bdec1a502270e3cc6c"; byte[] C = Hex.decode( "522dc1f099567d07f47f37a32a84427d" + "643a8cdcbfe5c0c97598a2bd2555d1aa" + "8cb08e48590dbb3da7b08b1056828838" + "c5f61e6393ba7a0abcc9f662898015ad" + T); Key key; Cipher in, out; key = new SecretKeySpec(K, "AES"); in = Cipher.getInstance("AES/GCM/NoPadding", "BC"); out = Cipher.getInstance("AES/GCM/NoPadding", "BC"); in.init(Cipher.ENCRYPT_MODE, key, new IvParameterSpec(N)); byte[] enc = in.doFinal(P); if (!areEqual(enc, C)) { fail("ciphertext doesn't match in GCM"); } out.init(Cipher.DECRYPT_MODE, key, new IvParameterSpec(N)); byte[] dec = out.doFinal(C); if (!areEqual(dec, P)) { fail("plaintext doesn't match in GCM"); } try { in = Cipher.getInstance("AES/GCM/PKCS5Padding", "BC"); fail("bad padding missed in GCM"); } catch (NoSuchPaddingException e) { // expected } } private void ocbTest() throws Exception { byte[] K = Hex.decode( "000102030405060708090A0B0C0D0E0F"); byte[] P = Hex.decode( "000102030405060708090A0B0C0D0E0F"); byte[] N = Hex.decode("000102030405060708090A0B"); String T = "4CBB3E4BD6B456AF"; byte[] C = Hex.decode( "BEA5E8798DBE7110031C144DA0B2612213CC8B747807121A" + T); Key key; Cipher in, out; key = new SecretKeySpec(K, "AES"); in = Cipher.getInstance("AES/OCB/NoPadding", "BC"); out = Cipher.getInstance("AES/OCB/NoPadding", "BC"); in.init(Cipher.ENCRYPT_MODE, key, new IvParameterSpec(N)); byte[] enc = in.doFinal(P); if (!areEqual(enc, C)) { fail("ciphertext doesn't match in OCB"); } out.init(Cipher.DECRYPT_MODE, key, new IvParameterSpec(N)); byte[] dec = out.doFinal(C); if (!areEqual(dec, P)) { fail("plaintext doesn't match in OCB"); } try { in = Cipher.getInstance("AES/OCB/PKCS5Padding", "BC"); fail("bad padding missed in OCB"); } catch (NoSuchPaddingException e) { // expected } } public void performTest() throws Exception { for (int i = 0; i != cipherTests.length; i += 4) { test(Integer.parseInt(cipherTests[i]), Hex.decode(cipherTests[i + 1]), Hex.decode(cipherTests[i + 2]), Hex.decode(cipherTests[i + 3])); } byte[] kek1 = Hex.decode("000102030405060708090a0b0c0d0e0f"); byte[] in1 = Hex.decode("00112233445566778899aabbccddeeff"); byte[] out1 = Hex.decode("1fa68b0a8112b447aef34bd8fb5a7b829d3e862371d2cfe5"); wrapTest(1, "AESWrap", kek1, in1, out1); String[] oids = { NISTObjectIdentifiers.id_aes128_ECB.getId(), NISTObjectIdentifiers.id_aes128_CBC.getId(), NISTObjectIdentifiers.id_aes128_OFB.getId(), NISTObjectIdentifiers.id_aes128_CFB.getId(), NISTObjectIdentifiers.id_aes192_ECB.getId(), NISTObjectIdentifiers.id_aes192_CBC.getId(), NISTObjectIdentifiers.id_aes192_OFB.getId(), NISTObjectIdentifiers.id_aes192_CFB.getId(), NISTObjectIdentifiers.id_aes256_ECB.getId(), NISTObjectIdentifiers.id_aes256_CBC.getId(), NISTObjectIdentifiers.id_aes256_OFB.getId(), NISTObjectIdentifiers.id_aes256_CFB.getId() }; String[] names = { "AES/ECB/PKCS7Padding", "AES/CBC/PKCS7Padding", "AES/OFB/NoPadding", "AES/CFB/NoPadding", "AES/ECB/PKCS7Padding", "AES/CBC/PKCS7Padding", "AES/OFB/NoPadding", "AES/CFB/NoPadding", "AES/ECB/PKCS7Padding", "AES/CBC/PKCS7Padding", "AES/OFB/NoPadding", "AES/CFB/NoPadding" }; oidTest(oids, names, 4); String[] wrapOids = { NISTObjectIdentifiers.id_aes128_wrap.getId(), NISTObjectIdentifiers.id_aes192_wrap.getId(), NISTObjectIdentifiers.id_aes256_wrap.getId() }; wrapOidTest(wrapOids, "AESWrap"); eaxTest(); ccmTest(); gcmTest(); ocbTest(); } public static void main( String[] args) { Security.addProvider(new BouncyCastleProvider()); runTest(new AESTest()); } } bouncycastle-1.49.orig/test/src/org/bouncycastle/jce/provider/test/BlockCipherTest.java0000644000175000017500000010374412103434147030733 0ustar ebourgebourgpackage org.bouncycastle.jce.provider.test; import org.bouncycastle.jce.provider.BouncyCastleProvider; import org.bouncycastle.util.encoders.Hex; import org.bouncycastle.util.test.SimpleTest; import javax.crypto.Cipher; import javax.crypto.CipherInputStream; import javax.crypto.CipherOutputStream; import javax.crypto.IllegalBlockSizeException; import javax.crypto.KeyGenerator; import javax.crypto.SecretKey; import javax.crypto.SecretKeyFactory; import javax.crypto.ShortBufferException; import javax.crypto.spec.DESedeKeySpec; import javax.crypto.spec.IvParameterSpec; import javax.crypto.spec.RC2ParameterSpec; import javax.crypto.spec.RC5ParameterSpec; import javax.crypto.spec.SecretKeySpec; import java.io.ByteArrayInputStream; import java.io.ByteArrayOutputStream; import java.io.DataInputStream; import java.io.IOException; import java.security.AlgorithmParameters; import java.security.InvalidAlgorithmParameterException; import java.security.InvalidKeyException; import java.security.InvalidParameterException; import java.security.Key; import java.security.PrivateKey; import java.security.PublicKey; import java.security.SecureRandom; import java.security.Security; import java.security.spec.InvalidKeySpecException; import java.security.spec.KeySpec; /** * basic test class for a block cipher, basically this just exercises the provider, and makes sure we * are behaving sensibly, correctness of the implementation is shown in the lightweight test classes. */ public class BlockCipherTest extends SimpleTest { static String[] cipherTests1 = { "DES", "466da00648ef0e1f9617b1f002e225251a3248d09172f46b9617b1f002e225250112ecb3da61bc99", "DESede", "2f4bc6b30c893fa549d82c560d61cf3eb088aed020603de249d82c560d61cf3e529e95ecd8e05394", "SKIPJACK", "d4de46d52274dbb029f33b076043f8c40089f906751623de29f33b076043f8c4ac99b90f9396cb04", "Blowfish", "7870ebe7f6a52803eb9396ba6c5198216ce81d76d8d4c74beb9396ba6c5198211212473b05214e9f", "Twofish", "70336d9c9718a8a2ced1b19deed973a3c58af7ea71a69e7efc4df082dca581c0839e31468661bcfc57a14899ceeb0253", "RC2", "eb5b889bbcced12eb6b1a3da6a3d965bba66a5edfdd4c8a6b6b1a3da6a3d965b994a5b859e765797", "RC5", "220053543e3eca3bc9503a091ca67b08372560d8a4fdbee8c9503a091ca67b08a796d53bb8a4b7e0", "RC5-64", "e0b4a526ba3bc5f09199c3b1fe3737fe6d248cde70e565b0feea59ebfda375ae1946c386a48d8d8a74d7b1947ff6a788", "RC6", "44c97b67ca8486067f8b6c5b97632f3049e5e52c1d61fdd527dc3da39616540f19a3db39aac1ffd713795cd886cce0c0", "IDEA", "8c9fd56823ffdc523f6ccf7f614aa6173553e594fc7a21b53f6ccf7f614aa61740c54f7a66e95108", "TEA", "fcf45062104fda7c35712368b56dd4216a6ca998dc297b5435712368b56dd421208027ed2923cd0c", "XTEA", "4b427893d3d6aaded2afafabe25f7b233fb5589faa2b6389d2afafabe25f7b239d12979ac67e1c07", "Camellia", "3a68b4ad145bc2c76010669d68f2826359887afce763a78d9994143266adfaec8ba7ee562a1688ef9dfd7f897e5c44dc", "SEED", "d53d4ce1f48b9879420949467bfcbfbe2c6a7d4a8770bee0c71211def898d7c5024ce2007dd85accb3f69d906ae2164d", "Noekeon", "7e68ceb33aad9db04af6b878a16dd6c6b4f880d6c89027ba581884c10690bb6b3dbfd6ed5513e2c4f5670c3528023121", "DES/CBC/NoPadding", "60fa2f8fae5aa2a38e9ac77d0246726beb7511e4515feb12cf99f75cc6e0122a", "DESede/CBC/NoPadding", "4d3d7931875cf25593dc402298add8b914761e4936c9585ae22b2c1441169231", "SKIPJACK/CBC/NoPadding", "ceebcc2e5e2b847f9ed797b4930b95f115b9e6cf49c457fc2ea0df79ad5c8334", "Blowfish/CBC/NoPadding", "80823abbabc109733e7ebf3ce3344d67fc387c306b782086b452f7fbe8e844ce", "Twofish/CBC/NoPadding", "f819694251a00bdd403928745cd1d8a094de61f49ddf8e7692e9d81a83812943", "RC2/CBC/NoPadding", "a51facdb3933c9676795cd38cc3146fd4694722b468b1a979a399c77606abf99", "RC5/CBC/NoPadding", "9ee7517eab0280445f3a7c60c90c0f75029d65bca8b1af83ace5399d388c83c3", "RC6/CBC/NoPadding", "c44695633c07010f3a0d8f7ea046a642d4a96bf4e44f89fd91b46830bc95b130", "IDEA/CBC/NoPadding", "30cd990ebdae80fe12b6c6e4fcd1c064a27d985c276b3d7097351c8684e4c4d9", "DES/CBC/PKCS5Padding", "60fa2f8fae5aa2a38e9ac77d0246726beb7511e4515feb12cf99f75cc6e0122afdc70484fb9c0232", "DES/CBC/ISO10126Padding", "60fa2f8fae5aa2a38e9ac77d0246726beb7511e4515feb12cf99f75cc6e0122a980639850a2cc3e8", "DES/CBC/ISO7816-4Padding", "60fa2f8fae5aa2a38e9ac77d0246726beb7511e4515feb12cf99f75cc6e0122a1f80b9b0f1be49ac", "DES/CBC/X9.23Padding", "60fa2f8fae5aa2a38e9ac77d0246726beb7511e4515feb12cf99f75cc6e0122a980639850a2cc3e8", "DESede/CBC/PKCS7Padding", "4d3d7931875cf25593dc402298add8b914761e4936c9585ae22b2c1441169231a41e40695f1cff84", "SKIPJACK/CBC/PKCS7Padding", "ceebcc2e5e2b847f9ed797b4930b95f115b9e6cf49c457fc2ea0df79ad5c8334df7042de5db89c96", "Blowfish/CBC/PKCS7Padding", "80823abbabc109733e7ebf3ce3344d67fc387c306b782086b452f7fbe8e844cef986562ab1a675e8", "Twofish/CBC/PKCS7Padding", "f819694251a00bdd403928745cd1d8a094de61f49ddf8e7692e9d81a838129433e5f1343d6cdb0b41838619da1541f04", "RC2/CBC/PKCS7Padding", "a51facdb3933c9676795cd38cc3146fd4694722b468b1a979a399c77606abf9958435525f770f137", "RC5/CBC/PKCS7Padding", "9ee7517eab0280445f3a7c60c90c0f75029d65bca8b1af83ace5399d388c83c3edd95ff49be76651", "RC5-64/CBC/PKCS7Padding", "e479fd11f89dab22d2f3dd062b1d2abd5b5962553421a5c562dc7214c3b23b8e21949fda87f2f820e5f032c552c6ec78", "RC6/CBC/PKCS7Padding", "c44695633c07010f3a0d8f7ea046a642d4a96bf4e44f89fd91b46830bc95b130824b972c9019a69d2dd05ef2d36b37ac", "IDEA/CBC/PKCS7Padding", "30cd990ebdae80fe12b6c6e4fcd1c064a27d985c276b3d7097351c8684e4c4d9e584751325ef7c32", "IDEA/CBC/ISO10126Padding", "30cd990ebdae80fe12b6c6e4fcd1c064a27d985c276b3d7097351c8684e4c4d978b3fd73135f033b", "IDEA/CBC/X9.23Padding", "30cd990ebdae80fe12b6c6e4fcd1c064a27d985c276b3d7097351c8684e4c4d978b3fd73135f033b", "AES/CBC/PKCS7Padding", "cf87f4d8bb9d1abb36cdd9f44ead7d046db2f802d99e1ef0a5940f306079e08389a44c4a8cc1a47cbaee1128da55bbb7", "AES/CBC/ISO7816-4Padding", "cf87f4d8bb9d1abb36cdd9f44ead7d046db2f802d99e1ef0a5940f306079e08306d84876508a33efec701118d8eeaf6d", "Rijndael/CBC/PKCS7Padding", "cf87f4d8bb9d1abb36cdd9f44ead7d046db2f802d99e1ef0a5940f306079e08389a44c4a8cc1a47cbaee1128da55bbb7", "Serpent/CBC/PKCS7Padding", "f8940ca31aba8ce1e0693b1ae0b1e08daef6de03c80f019774280052f824ac44540bb8dd74dfad47f83f9c7ec268ca68", "CAST5/CBC/PKCS7Padding", "87b6dc0c5a1d23d42fa740b0548be0b298112000544610d889d6361994cf8e670a19d6af72d7289f", "CAST6/CBC/PKCS7Padding", "943445569cfdda174118e433828f84e137faee38cac5c827d87a3c9a5a46a07dd64e7ad8accd921f248eea627cd6826f", "DES/CBC/WithCTS", "60fa2f8fae5aa2a38e9ac77d0246726bcf99f75cc6e0122aeb7511e4515feb12", "IDEA/CBC/PKCS7Padding", "30cd990ebdae80fe12b6c6e4fcd1c064a27d985c276b3d7097351c8684e4c4d9e584751325ef7c32", "DES/CBC/ZeroBytePadding", "60fa2f8fae5aa2a38e9ac77d0246726beb7511e4515feb12cf99f75cc6e0122ad3b3f002c927f1fd", "DES/CTS/NoPadding", // official style "60fa2f8fae5aa2a38e9ac77d0246726bcf99f75cc6e0122aeb7511e4515feb12", "DESede/CTS/NoPadding", "4d3d7931875cf25593dc402298add8b9e22b2c144116923114761e4936c9585a", "SKIPJACK/CTS/NoPadding", "ceebcc2e5e2b847f9ed797b4930b95f12ea0df79ad5c833415b9e6cf49c457fc", "Blowfish/CTS/NoPadding", "80823abbabc109733e7ebf3ce3344d67b452f7fbe8e844cefc387c306b782086", "Twofish/CTS/NoPadding", "94de61f49ddf8e7692e9d81a83812943f819694251a00bdd403928745cd1d8a0", "AES/CTS/NoPadding", "6db2f802d99e1ef0a5940f306079e083cf87f4d8bb9d1abb36cdd9f44ead7d04", "Rijndael/CTS/NoPadding", "6db2f802d99e1ef0a5940f306079e083cf87f4d8bb9d1abb36cdd9f44ead7d04", "Serpent/CTS/NoPadding", "aef6de03c80f019774280052f824ac44f8940ca31aba8ce1e0693b1ae0b1e08d", "CAST5/CTS/NoPadding", "87b6dc0c5a1d23d42fa740b0548be0b289d6361994cf8e6798112000544610d8", "CAST6/CTS/NoPadding", "37faee38cac5c827d87a3c9a5a46a07d943445569cfdda174118e433828f84e1", "RC2/CTS/NoPadding", "a51facdb3933c9676795cd38cc3146fd9a399c77606abf994694722b468b1a97", "RC5/CTS/NoPadding", "9ee7517eab0280445f3a7c60c90c0f75ace5399d388c83c3029d65bca8b1af83", "RC6/CTS/NoPadding", "d4a96bf4e44f89fd91b46830bc95b130c44695633c07010f3a0d8f7ea046a642", "IDEA/CTS/NoPadding", "30cd990ebdae80fe12b6c6e4fcd1c06497351c8684e4c4d9a27d985c276b3d70", "DES/CBC/WithCTS", // older style "60fa2f8fae5aa2a38e9ac77d0246726bcf99f75cc6e0122aeb7511e4515feb12", "DESede/CBC/WithCTS", "4d3d7931875cf25593dc402298add8b9e22b2c144116923114761e4936c9585a", "SKIPJACK/CBC/WithCTS", "ceebcc2e5e2b847f9ed797b4930b95f12ea0df79ad5c833415b9e6cf49c457fc", "Blowfish/CBC/WithCTS", "80823abbabc109733e7ebf3ce3344d67b452f7fbe8e844cefc387c306b782086", "Twofish/CBC/WithCTS", "94de61f49ddf8e7692e9d81a83812943f819694251a00bdd403928745cd1d8a0", "AES/CBC/WithCTS", "6db2f802d99e1ef0a5940f306079e083cf87f4d8bb9d1abb36cdd9f44ead7d04", "Rijndael/CBC/WithCTS", "6db2f802d99e1ef0a5940f306079e083cf87f4d8bb9d1abb36cdd9f44ead7d04", "Serpent/CBC/WithCTS", "aef6de03c80f019774280052f824ac44f8940ca31aba8ce1e0693b1ae0b1e08d", "CAST5/CBC/WithCTS", "87b6dc0c5a1d23d42fa740b0548be0b289d6361994cf8e6798112000544610d8", "CAST6/CBC/WithCTS", "37faee38cac5c827d87a3c9a5a46a07d943445569cfdda174118e433828f84e1", "RC2/CBC/WithCTS", "a51facdb3933c9676795cd38cc3146fd9a399c77606abf994694722b468b1a97", "RC5/CBC/WithCTS", "9ee7517eab0280445f3a7c60c90c0f75ace5399d388c83c3029d65bca8b1af83", "RC6/CBC/WithCTS", "d4a96bf4e44f89fd91b46830bc95b130c44695633c07010f3a0d8f7ea046a642", "IDEA/CBC/WithCTS", "30cd990ebdae80fe12b6c6e4fcd1c06497351c8684e4c4d9a27d985c276b3d70", "DES/OFB/NoPadding", "537572e480c1714f5c9a4f3b874df824dc6681b1fd6c11982debcad91e3f78b7", "DESede/OFB/NoPadding", "481e9872acea7fcf8e29a453242da774e5f6a28f15f7723659a73e4ff4939f80", "SKIPJACK/OFB/NoPadding", "71143a124e3a0cde753b60fe9b200e559018b6a0fe0682659f7c13feb9df995c", "Blowfish/OFB/NoPadding", "6cd6f7c5d2c655556d7a9e98a1696d1875e9f1b2fc991e28a2d55b56861e80bd", "Twofish/OFB/NoPadding", "821c54b1b54ae113cf74595eefe10c83b61c9682fc81f92c52f39a3a693f88b8", "RC2/OFB/NoPadding", "0a07cb78537cb04c0c74e28a7b86b80f80acadf87d6ef32792f1a8cf74b39f74", "RC5/OFB/NoPadding", "c62b233df296283b918a2b4cc53a54fbf061850e781b97332ed1bd78b88d9670", "IDEA/OFB/NoPadding", "dd447da3cbdcf81f4053fb446596261cb00a3c49a66085485af5f7c10ba20dad", "DES/OFB8/NoPadding", "53cb5010d189f94cf584e5ff1c4a9d86443c45ddb6fa3c2d1a5dadfcdf01db8a", "DESede/OFB8/NoPadding", "482c0c1ccd0e6d218e1cffb0a295352c2357ffaa673f2257ef5c77b6c04f03b5", "SKIPJACK/OFB8/NoPadding", "719ea1b432b3d2c8011e5aa873f95978420022b5e2c9c1a1c1082cd1f4999da2", "Blowfish/OFB8/NoPadding", "6ca6078755b263f09787d830b6fda7b7748494634bdc73ab68540cf9f6b7eccf", "Twofish/OFB8/NoPadding", "825dcec234ad52253d6e064b0d769bc04b1142435933f4a510ffc20d70095a88", "RC2/OFB8/NoPadding", "0aa26c6f6a820fe7d38da97085995ad62e2e293323a76300fcd4eb572810f7c6", "RC5/OFB8/NoPadding", "c601a9074dbd874f4d3293f6a32d93d9f0a4f5685d8597f0102fcc96d444f976", "IDEA/OFB8/NoPadding", "dd7897b6ced43d060a518bb38d570308b83b4de577eb208130daabf619e9b1fb", "DES/CFB/NoPadding", "537572e480c1714fec3c7424f88d4202219244c5ca8f5e4361d64f08fe747bb2", "DESede/CFB/NoPadding", "481e9872acea7fcfb75bb58670fe64c59123265139e357d161cd4ddb5eba042a", "SKIPJACK/CFB/NoPadding", "71143a124e3a0cde70a69ede4ceb14376b1e6a80bafde0a6330508dfa86a7c41", "Blowfish/CFB/NoPadding", "6cd6f7c5d2c6555561167fe9b10665102206869339122f1ed89efa4a985397f6", "Twofish/CFB/NoPadding", "821c54b1b54ae113cf74595eefe10c8308b7a438277de4f40948ac2d172d53d2", "RC2/CFB/NoPadding", "0a07cb78537cb04ca1401450d5cd411c7da7fa5b6baaa17bb2137bd95c9f26a5", "RC5/CFB/NoPadding", "c62b233df296283b989352bbebf616a19e11503ac737f9e0eaf19049cde05d34", "IDEA/CFB/NoPadding", "dd447da3cbdcf81fcbe4661dcbed88aed899f87585118384bd0565067fa6c13a", "DES/CFB8/NoPadding", "53cb0cdff712a825eb283b23c31e7323aa12495e7e751428b5c4eb89b28a25d4", "DESede/CFB8/NoPadding", "482cd5bf87ca4cee0b573d66a077231bfea93843ce2d1f948550a1d208e18279", "SKIPJACK/CFB8/NoPadding", "719eef3906bef23f7b63599285437d8e34183b165acf3e855b4e160d4f036508", "Blowfish/CFB8/NoPadding", "6ca63aaada9188d2410c07513cc0736b9888770768c25a5befc776beea5bdc4c", "Twofish/CFB8/NoPadding", "825d12af040721cf5ed4a4798647837ac5eb14d752aace28728aeb37b2010abd", "RC2/CFB8/NoPadding", "0aa227f94be3a32ff927c5d25647ea41d7c2a1e94012fc7f2ad6767b9664bce5", "RC5/CFB8/NoPadding", "c601cf88725411f119965b9cd38d6c313b91128ed7c98c7604cc62d9b210be79", "IDEA/CFB8/NoPadding", "dd7839d2525420d10f95eec23dbaf3463302c445972a28c563c2635191bc19af", "IDEA/PGPCFB/NoPadding", "dd447da3cbdcf81fcbe4661dcbed88aed899f87585118384bd0565067fa6c13a", "IDEA/PGPCFBwithIv/NoPadding", "ed5adbac0e730cc0f00df7e4f6fef672ab042673106435faf3ecf3996a72a0e127b440ba9e5313501de3", "Twofish/ECB/TBCPadding", "70336d9c9718a8a2ced1b19deed973a3c58af7ea71a69e7efc4df082dca581c019d7daa58d02b89aab6e8c0d17202439", "RC2/ECB/TBCPadding", "eb5b889bbcced12eb6b1a3da6a3d965bba66a5edfdd4c8a6b6b1a3da6a3d965b6b5359ba5e69b179" }; static String[] cipherTests2 = { "DES/OFB64/NoPadding", "537572e480c1714f5c9a4f3b874df824dc6681b1fd6c11982debcad91e", "DES/CFB64/NoPadding", "537572e480c1714fec3c7424f88d4202219244c5ca8f5e4361d64f08fe", "DES/CTR/NoPadding", "537572e480c1714fb47081d35eb18eaca9e0a5aee982f105438a0db6ce", "DES/CTS/NoPadding", "60fa2f8fae5aa2a38e9ac77d0246726b32df660db51a710ceb7511e451" }; static byte[] input1 = Hex.decode("000102030405060708090a0b0c0d0e0fff0102030405060708090a0b0c0d0e0f"); static byte[] input2 = Hex.decode("000102030405060708090a0b0c0d0e0fff0102030405060708090a0b0c"); static RC2ParameterSpec rc2Spec = new RC2ParameterSpec(128, Hex.decode("0123456789abcdef")); static RC5ParameterSpec rc5Spec = new RC5ParameterSpec(16, 16, 32, Hex.decode("0123456789abcdef")); static RC5ParameterSpec rc564Spec = new RC5ParameterSpec(16, 16, 64, Hex.decode("0123456789abcdef0123456789abcdef")); /** * a fake random number generator - we just want to make sure the random numbers * aren't random so that we get the same output, while still getting to test the * key generation facilities. */ private class FixedSecureRandom extends SecureRandom { byte[] seed = { (byte)0xaa, (byte)0xfd, (byte)0x12, (byte)0xf6, (byte)0x59, (byte)0xca, (byte)0xe6, (byte)0x34, (byte)0x89, (byte)0xb4, (byte)0x79, (byte)0xe5, (byte)0x07, (byte)0x6d, (byte)0xde, (byte)0xc2, (byte)0xf0, (byte)0x6c, (byte)0xb5, (byte)0x8f }; public void nextBytes( byte[] bytes) { int offset = 0; while ((offset + seed.length) < bytes.length) { System.arraycopy(seed, 0, bytes, offset, seed.length); offset += seed.length; } System.arraycopy(seed, 0, bytes, offset, bytes.length - offset); } } public String getName() { return "BlockCipher"; } public void test( String algorithm, byte[] input, byte[] output) { Key key = null; KeyGenerator keyGen; SecureRandom rand; Cipher in = null; Cipher out = null; CipherInputStream cIn; CipherOutputStream cOut; ByteArrayInputStream bIn; ByteArrayOutputStream bOut; rand = new FixedSecureRandom(); try { String baseAlgorithm; int index = algorithm.indexOf('/'); if (index > 0) { baseAlgorithm = algorithm.substring(0, index); } else { baseAlgorithm = algorithm; } if (baseAlgorithm.equals("IDEA") & noIDEA()) { return; } keyGen = KeyGenerator.getInstance(baseAlgorithm, "BC"); if (!keyGen.getAlgorithm().equals(baseAlgorithm)) { fail("wrong key generator returned!"); } keyGen.init(rand); key = keyGen.generateKey(); in = Cipher.getInstance(algorithm, "BC"); out = Cipher.getInstance(algorithm, "BC"); if (!in.getAlgorithm().startsWith(baseAlgorithm)) { fail("wrong cipher returned!"); } if (algorithm.startsWith("RC2")) { out.init(Cipher.ENCRYPT_MODE, key, rc2Spec, rand); } else if (algorithm.startsWith("RC5")) { if (algorithm.startsWith("RC5-64")) { out.init(Cipher.ENCRYPT_MODE, key, rc564Spec, rand); } else { out.init(Cipher.ENCRYPT_MODE, key, rc5Spec, rand); } } else { out.init(Cipher.ENCRYPT_MODE, key, rand); } } catch (Exception e) { fail("" + algorithm + " failed initialisation - " + e.toString(), e); } // // grab the iv if there is one // try { if (algorithm.startsWith("RC2")) { in.init(Cipher.DECRYPT_MODE, key, rc2Spec); } else if (algorithm.startsWith("RC5")) { if (algorithm.startsWith("RC5-64")) { in.init(Cipher.DECRYPT_MODE, key, rc564Spec, rand); } else { in.init(Cipher.DECRYPT_MODE, key, rc5Spec, rand); } } else { byte[] iv; iv = out.getIV(); if (iv != null) { try { byte[] nIv = new byte[iv.length - 1]; in.init(Cipher.DECRYPT_MODE, key, new IvParameterSpec(nIv)); fail("failed to pick up short IV"); } catch (InvalidAlgorithmParameterException e) { // ignore - this is what we want... } IvParameterSpec spec; spec = new IvParameterSpec(iv); in.init(Cipher.DECRYPT_MODE, key, spec); } else { in.init(Cipher.DECRYPT_MODE, key); } } } catch (Exception e) { fail("" + algorithm + " failed initialisation - " + e.toString()); } // // encryption pass // bOut = new ByteArrayOutputStream(); cOut = new CipherOutputStream(bOut, out); try { for (int i = 0; i != input.length / 2; i++) { cOut.write(input[i]); } cOut.write(input, input.length / 2, input.length - input.length / 2); cOut.close(); } catch (IOException e) { fail("" + algorithm + " failed encryption - " + e.toString()); } byte[] bytes; bytes = bOut.toByteArray(); if (!areEqual(bytes, output)) { fail("" + algorithm + " failed encryption - expected " + new String(Hex.encode(output)) + " got " + new String(Hex.encode(bytes))); } // // decryption pass // bIn = new ByteArrayInputStream(bytes); cIn = new CipherInputStream(bIn, in); try { DataInputStream dIn = new DataInputStream(cIn); bytes = new byte[input.length]; for (int i = 0; i != input.length / 2; i++) { bytes[i] = (byte)dIn.read(); } dIn.readFully(bytes, input.length / 2, bytes.length - input.length / 2); } catch (Exception e) { fail("" + algorithm + " failed decryption - " + e.toString()); } if (!areEqual(bytes, input)) { fail("" + algorithm + " failed decryption - expected " + new String(Hex.encode(input)) + " got " + new String(Hex.encode(bytes))); } } private boolean noIDEA() { try { Cipher.getInstance("IDEA", "BC"); return false; } catch (Exception e) { return true; } } private void testExceptions() { SecretKeyFactory skF = null; try { skF = SecretKeyFactory.getInstance("DESede", "BC"); } catch (Exception e) { fail("unexpected exception.", e); } KeySpec ks = null; SecretKey secKey = null; byte[] bb = new byte[24]; try { skF.getKeySpec(null, null); fail("failed exception test - no exception thrown"); } catch (InvalidKeySpecException e) { // ignore okay } catch (Exception e) { fail("failed exception test.", e); } try { ks = (KeySpec)new DESedeKeySpec(bb); skF.getKeySpec(null, ks.getClass()); fail("failed exception test - no exception thrown"); } catch (InvalidKeySpecException e) { // ignore okay; } catch (Exception e) { fail("failed exception test.", e); } try { skF.getKeySpec(secKey, null); } catch (InvalidKeySpecException e) { // ignore okay } catch (Exception e) { fail("failed exception test.", e); } try { KeyGenerator kg = KeyGenerator.getInstance("DESede", "BC"); try { kg.init(Integer.MIN_VALUE, new SecureRandom()); fail("failed exception test - no exception thrown"); } catch (InvalidParameterException e) { // ignore okay } catch (Exception e) { fail("failed exception test.", e); } } catch (Exception e) { fail("unexpected exception.", e); } try { skF = SecretKeyFactory.getInstance("DESede", "BC"); try { skF.translateKey(null); fail("failed exception test - no exception thrown"); } catch (InvalidKeyException e) { // ignore okay } catch (Exception e) { fail("failed exception test.", e); } } catch (Exception e) { fail("unexpected exception.", e); } try { byte[] rawDESKey = { (byte)128, (byte)131, (byte)133, (byte)134, (byte)137, (byte)138, (byte)140, (byte)143 }; SecretKeySpec cipherKey = new SecretKeySpec(rawDESKey, "DES"); Cipher cipher = Cipher.getInstance("DES/CBC/NoPadding", "BC"); try { // According specification engineInit(int opmode, Key key, // SecureRandom random) throws InvalidKeyException if this // cipher is being // initialized for decryption and requires algorithm parameters // that cannot be determined from the given key cipher.init(Cipher.DECRYPT_MODE, cipherKey, (SecureRandom)null); fail("failed exception test - no InvalidKeyException thrown"); } catch (InvalidKeyException e) { // ignore } } catch (Exception e) { fail("unexpected exception.", e); } try { byte[] rawDESKey = { -128, -125, -123, -122, -119, -118 }; SecretKeySpec cipherKey = new SecretKeySpec(rawDESKey, "DES"); Cipher cipher = Cipher.getInstance("DES/ECB/NoPadding", "BC"); try { // According specification engineInit(int opmode, Key key, // SecureRandom random) throws InvalidKeyException if the given // key is inappropriate for initializing this cipher cipher.init(Cipher.ENCRYPT_MODE, cipherKey); fail("failed exception test - no InvalidKeyException thrown"); } catch (InvalidKeyException e) { // ignore } } catch (Exception e) { fail("unexpected exception.", e); } try { byte[] rawDESKey = { -128, -125, -123, -122, -119, -118, -117, -115, -114 }; SecretKeySpec cipherKey = new SecretKeySpec(rawDESKey, "DES"); Cipher cipher = Cipher.getInstance("DES/ECB/NoPadding", "BC"); try { // According specification engineInit(int opmode, Key key, // SecureRandom random) throws InvalidKeyException if the given // key is inappropriate for initializing this cipher cipher.init(Cipher.ENCRYPT_MODE, cipherKey); fail("failed exception test - no InvalidKeyException thrown"); } catch (InvalidKeyException e) { // ignore } } catch (Exception e) { fail("unexpected exception.", e); } try { byte[] rawDESKey = { (byte)128, (byte)131, (byte)133, (byte)134, (byte)137, (byte)138, (byte)140, (byte)143 }; SecretKeySpec cipherKey = new SecretKeySpec(rawDESKey, "DES"); Cipher ecipher = Cipher.getInstance("DES/ECB/PKCS5Padding", "BC"); ecipher.init(Cipher.ENCRYPT_MODE, cipherKey); byte[] cipherText = new byte[0]; try { // According specification Method engineUpdate(byte[] input, // int inputOffset, int inputLen, byte[] output, int // outputOffset) // throws ShortBufferException - if the given output buffer is // too // small to hold the result ecipher.update(new byte[20], 0, 20, cipherText); fail("failed exception test - no ShortBufferException thrown"); } catch (ShortBufferException e) { // ignore } } catch (Exception e) { fail("unexpected exception.", e); } try { byte[] rawDESKey = { (byte)128, (byte)131, (byte)133, (byte)134, (byte)137, (byte)138, (byte)140, (byte)143 }; SecretKeySpec cipherKey = new SecretKeySpec(rawDESKey, "DES"); Cipher ecipher = Cipher.getInstance("DES/ECB/PKCS5Padding", "BC"); ecipher.init(Cipher.ENCRYPT_MODE, cipherKey); byte[] cipherText = new byte[0]; try { // According specification Method enginedoFinal(byte[] input, // int inputOffset, int inputLen, byte[] output, int // outputOffset) // throws ShortBufferException - if the given output buffer is // too // small to hold the result ecipher.doFinal(new byte[20], 0, 20, cipherText); fail("failed exception test - no ShortBufferException thrown"); } catch (ShortBufferException e) { // ignore } } catch (Exception e) { fail("unexpected exception.", e); } try { KeyGenerator keyGen = KeyGenerator.getInstance("DES", "BC"); keyGen.init((SecureRandom)null); // According specification engineGenerateKey() doesn't throw any exceptions. SecretKey key = keyGen.generateKey(); if (key == null) { fail("key is null!"); } } catch (Exception e) { fail("unexpected exception.", e); } try { AlgorithmParameters algParams = AlgorithmParameters.getInstance("DES", "BC"); algParams.init(new IvParameterSpec(new byte[8])); // According specification engineGetEncoded() returns // the parameters in their primary encoding format. The primary // encoding // format for parameters is ASN.1, if an ASN.1 specification for // this type // of parameters exists. byte[] iv = algParams.getEncoded(); if (iv.length != 10) { fail("parameters encoding wrong length - " + iv.length); } } catch (Exception e) { fail("unexpected exception.", e); } try { try { AlgorithmParameters algParams = AlgorithmParameters.getInstance("DES", "BC"); byte[] encoding = new byte[10]; encoding[0] = 3; encoding[1] = 8; // According specification engineInit(byte[] params, String format) // throws // IOException on decoding errors, but BC throws ClassCastException. algParams.init(encoding, "ASN.1"); fail("failed exception test - no IOException thrown"); } catch (IOException e) { // okay } try { Cipher c = Cipher.getInstance("DES", "BC"); Key k = new PublicKey() { public String getAlgorithm() { return "STUB"; } public String getFormat() { return null; } public byte[] getEncoded() { return null; } }; c.init(Cipher.ENCRYPT_MODE, k); fail("failed exception test - no InvalidKeyException thrown for public key"); } catch (InvalidKeyException e) { // okay } try { Cipher c = Cipher.getInstance("DES", "BC"); Key k = new PrivateKey() { public String getAlgorithm() { return "STUB"; } public String getFormat() { return null; } public byte[] getEncoded() { return null; } }; c.init(Cipher.DECRYPT_MODE, k); fail("failed exception test - no InvalidKeyException thrown for private key"); } catch (InvalidKeyException e) { // okay } } catch (Exception e) { fail("unexpected exception.", e); } } public void performTest() { for (int i = 0; i != cipherTests1.length; i += 2) { test(cipherTests1[i], input1, Hex.decode(cipherTests1[i + 1])); } for (int i = 0; i != cipherTests2.length; i += 2) { test(cipherTests2[i], input2, Hex.decode(cipherTests2[i + 1])); } // // check for less than a block // try { Cipher c = Cipher.getInstance("AES/CTS/NoPadding", "BC"); c.init(Cipher.ENCRYPT_MODE, new SecretKeySpec(new byte[16], "AES")); c.doFinal(new byte[4]); fail("CTS failed to throw exception"); } catch (Exception e) { if (!(e instanceof IllegalBlockSizeException)) { fail("CTS exception test - " + e, e); } } testExceptions(); } public static void main( String[] args) { Security.addProvider(new BouncyCastleProvider()); runTest(new BlockCipherTest()); } } bouncycastle-1.49.orig/test/src/org/bouncycastle/jce/provider/test/SigNameTest.java0000644000175000017500000000456310766620345030102 0ustar ebourgebourgpackage org.bouncycastle.jce.provider.test; import java.security.NoSuchAlgorithmException; import java.security.NoSuchProviderException; import java.security.Security; import java.security.Signature; import org.bouncycastle.jce.provider.BouncyCastleProvider; import org.bouncycastle.util.test.SimpleTest; public class SigNameTest extends SimpleTest { private void checkName(String name) throws NoSuchProviderException, NoSuchAlgorithmException { if (!name.equals(Signature.getInstance(name, "BC").getAlgorithm())) { fail("name misatch on " + name); } } public void performTest() throws Exception { checkName("SHA1withRSA"); checkName("SHA224withRSA"); checkName("SHA256withRSA"); checkName("SHA384withRSA"); checkName("SHA512withRSA"); checkName("MD2withRSA"); checkName("MD4withRSA"); checkName("MD5withRSA"); checkName("RIPEMD160withRSA"); checkName("RIPEMD128withRSA"); checkName("RIPEMD256withRSA"); checkName("SHA1withDSA"); checkName("SHA224withDSA"); checkName("SHA256withDSA"); checkName("SHA384withDSA"); checkName("SHA512withDSA"); checkName("NONEwithDSA"); checkName("SHA1withECDSA"); checkName("SHA224withECDSA"); checkName("SHA256withECDSA"); checkName("SHA384withECDSA"); checkName("SHA512withECDSA"); checkName("RIPEMD160withECDSA"); checkName("SHA1withECNR"); checkName("SHA224withECNR"); checkName("SHA256withECNR"); checkName("SHA384withECNR"); checkName("SHA512withECNR"); checkName("SHA1withRSAandMGF1"); checkName("SHA1withRSAandMGF1"); checkName("SHA224withRSAandMGF1"); checkName("SHA256withRSAandMGF1"); checkName("SHA384withRSAandMGF1"); checkName("SHA512withRSAandMGF1"); checkName("GOST3411withGOST3410"); checkName("GOST3411withECGOST3410"); checkName("SHA1withRSA/ISO9796-2"); checkName("MD5withRSA/ISO9796-2"); checkName("RIPEMD160withRSA/ISO9796-2"); } public String getName() { return "SigNameTest"; } public static void main( String[] args) { Security.addProvider(new BouncyCastleProvider()); runTest(new SigNameTest()); } }bouncycastle-1.49.orig/test/src/org/bouncycastle/jce/provider/test/CertStoreTest.java0000644000175000017500000001720410574433106030457 0ustar ebourgebourgpackage org.bouncycastle.jce.provider.test; import org.bouncycastle.jce.provider.BouncyCastleProvider; import org.bouncycastle.util.test.SimpleTest; import java.io.ByteArrayInputStream; import java.security.Security; import java.security.cert.CertStore; import java.security.cert.CertificateFactory; import java.security.cert.CollectionCertStoreParameters; import java.security.cert.X509CRL; import java.security.cert.X509CRLSelector; import java.security.cert.X509CertSelector; import java.security.cert.X509Certificate; import java.util.ArrayList; import java.util.Collection; import java.util.Iterator; import java.util.List; public class CertStoreTest extends SimpleTest { public void performTest() throws Exception { basicTest(); orderTest(); } private void basicTest() throws Exception { CertificateFactory cf = CertificateFactory.getInstance("X.509", "BC"); X509Certificate rootCert = (X509Certificate)cf .generateCertificate(new ByteArrayInputStream( CertPathTest.rootCertBin)); X509Certificate interCert = (X509Certificate)cf .generateCertificate(new ByteArrayInputStream( CertPathTest.interCertBin)); X509Certificate finalCert = (X509Certificate)cf .generateCertificate(new ByteArrayInputStream( CertPathTest.finalCertBin)); X509CRL rootCrl = (X509CRL)cf.generateCRL(new ByteArrayInputStream( CertPathTest.rootCrlBin)); X509CRL interCrl = (X509CRL)cf .generateCRL(new ByteArrayInputStream( CertPathTest.interCrlBin)); // Testing CollectionCertStore generation from List List list = new ArrayList(); list.add(rootCert); list.add(interCert); list.add(finalCert); list.add(rootCrl); list.add(interCrl); CollectionCertStoreParameters ccsp = new CollectionCertStoreParameters(list); CertStore store = CertStore.getInstance("Collection", ccsp, "BC"); // Searching for rootCert by subjectDN X509CertSelector targetConstraints = new X509CertSelector(); targetConstraints.setSubject(rootCert.getSubjectX500Principal().getName()); Collection certs = store.getCertificates(targetConstraints); if (certs.size() != 1 || !certs.contains(rootCert)) { fail("rootCert not found by subjectDN"); } // Searching for rootCert by subjectDN encoded as byte targetConstraints = new X509CertSelector(); targetConstraints.setSubject(rootCert.getSubjectX500Principal() .getEncoded()); certs = store.getCertificates(targetConstraints); if (certs.size() != 1 || !certs.contains(rootCert)) { fail("rootCert not found by encoded subjectDN"); } // Searching for rootCert by public key encoded as byte targetConstraints = new X509CertSelector(); targetConstraints.setSubjectPublicKey(rootCert.getPublicKey() .getEncoded()); certs = store.getCertificates(targetConstraints); if (certs.size() != 1 || !certs.contains(rootCert)) { fail("rootCert not found by encoded public key"); } // Searching for interCert by issuerDN targetConstraints = new X509CertSelector(); targetConstraints.setIssuer(rootCert.getSubjectX500Principal() .getEncoded()); certs = store.getCertificates(targetConstraints); if (certs.size() != 2) { fail("did not found 2 certs"); } if (!certs.contains(rootCert)) { fail("rootCert not found"); } if (!certs.contains(interCert)) { fail("interCert not found"); } // Searching for rootCrl by issuerDN X509CRLSelector targetConstraintsCRL = new X509CRLSelector(); targetConstraintsCRL.addIssuerName(rootCrl.getIssuerX500Principal() .getEncoded()); Collection crls = store.getCRLs(targetConstraintsCRL); if (crls.size() != 1 || !crls.contains(rootCrl)) { fail("rootCrl not found"); } } private void orderTest() throws Exception { CertificateFactory cf = CertificateFactory.getInstance("X.509", "BC"); X509Certificate rootCert = (X509Certificate)cf .generateCertificate(new ByteArrayInputStream( CertPathTest.rootCertBin)); X509Certificate interCert = (X509Certificate)cf .generateCertificate(new ByteArrayInputStream( CertPathTest.interCertBin)); X509Certificate finalCert = (X509Certificate)cf .generateCertificate(new ByteArrayInputStream( CertPathTest.finalCertBin)); List list = new ArrayList(); list.add(rootCert); list.add(interCert); list.add(finalCert); CollectionCertStoreParameters ccsp = new CollectionCertStoreParameters(list); CertStore store = CertStore.getInstance("Collection", ccsp, "BC"); Iterator certs = store.getCertificates(null).iterator(); if (!certs.next().equals(rootCert)) { fail("root ordering wrong"); } if (!certs.next().equals(interCert)) { fail("mid ordering wrong"); } if (!certs.next().equals(finalCert)) { fail("final ordering wrong"); } list = new ArrayList(); list.add(finalCert); list.add(interCert); list.add(rootCert); ccsp = new CollectionCertStoreParameters(list); store = CertStore.getInstance("Collection", ccsp, "BC"); certs = store.getCertificates(null).iterator(); if (!certs.next().equals(finalCert)) { fail("reverse final ordering wrong"); } if (!certs.next().equals(interCert)) { fail("reverse mid ordering wrong"); } if (!certs.next().equals(rootCert)) { fail("reverse root ordering wrong"); } X509CRL rootCrl = (X509CRL)cf.generateCRL(new ByteArrayInputStream( CertPathTest.rootCrlBin)); X509CRL interCrl = (X509CRL)cf .generateCRL(new ByteArrayInputStream( CertPathTest.interCrlBin)); list = new ArrayList(); list.add(finalCert); list.add(rootCrl); list.add(interCrl); ccsp = new CollectionCertStoreParameters(list); store = CertStore.getInstance("Collection", ccsp, "BC"); Iterator crls = store.getCRLs(null).iterator(); if (!crls.next().equals(rootCrl)) { fail("root crl ordering wrong"); } if (!crls.next().equals(interCrl)) { fail("mid crl ordering wrong"); } list = new ArrayList(); list.add(finalCert); list.add(interCrl); list.add(rootCrl); ccsp = new CollectionCertStoreParameters(list); store = CertStore.getInstance("Collection", ccsp, "BC"); crls = store.getCRLs(null).iterator(); if (!crls.next().equals(interCrl)) { fail("reverse mid crl ordering wrong"); } if (!crls.next().equals(rootCrl)) { fail("reverse root crl ordering wrong"); } } public String getName() { return "CertStore"; } public static void main(String[] args) { Security.addProvider(new BouncyCastleProvider()); runTest(new CertStoreTest()); } } bouncycastle-1.49.orig/test/src/org/bouncycastle/jce/provider/test/PBETest.java0000644000175000017500000005363012152002101027133 0ustar ebourgebourgpackage org.bouncycastle.jce.provider.test; import java.security.AlgorithmParameters; import java.security.SecureRandom; import java.security.Security; import java.security.spec.InvalidParameterSpecException; import java.security.spec.KeySpec; import javax.crypto.Cipher; import javax.crypto.KeyGenerator; import javax.crypto.Mac; import javax.crypto.SecretKey; import javax.crypto.SecretKeyFactory; import javax.crypto.spec.IvParameterSpec; import javax.crypto.spec.PBEKeySpec; import javax.crypto.spec.PBEParameterSpec; import javax.crypto.spec.SecretKeySpec; import org.bouncycastle.asn1.bc.BCObjectIdentifiers; import org.bouncycastle.crypto.Digest; import org.bouncycastle.crypto.PBEParametersGenerator; import org.bouncycastle.crypto.digests.SHA1Digest; import org.bouncycastle.crypto.digests.SHA256Digest; import org.bouncycastle.crypto.generators.OpenSSLPBEParametersGenerator; import org.bouncycastle.crypto.generators.PKCS12ParametersGenerator; import org.bouncycastle.crypto.params.KeyParameter; import org.bouncycastle.crypto.params.ParametersWithIV; import org.bouncycastle.jce.provider.BouncyCastleProvider; import org.bouncycastle.util.Arrays; import org.bouncycastle.util.encoders.Hex; import org.bouncycastle.util.test.SimpleTest; /** * test out the various PBE modes, making sure the JCE implementations * are compatible woth the light weight ones. */ public class PBETest extends SimpleTest { private class OpenSSLTest extends SimpleTest { char[] password; String baseAlgorithm; String algorithm; int keySize; int ivSize; OpenSSLTest( String baseAlgorithm, String algorithm, int keySize, int ivSize) { this.password = algorithm.toCharArray(); this.baseAlgorithm = baseAlgorithm; this.algorithm = algorithm; this.keySize = keySize; this.ivSize = ivSize; } public String getName() { return "OpenSSLPBE"; } public void performTest() throws Exception { byte[] salt = new byte[16]; int iCount = 100; for (int i = 0; i != salt.length; i++) { salt[i] = (byte)i; } OpenSSLPBEParametersGenerator pGen = new OpenSSLPBEParametersGenerator(); pGen.init( PBEParametersGenerator.PKCS5PasswordToBytes(password), salt, iCount); ParametersWithIV params = (ParametersWithIV)pGen.generateDerivedParameters(keySize, ivSize); SecretKeySpec encKey = new SecretKeySpec(((KeyParameter)params.getParameters()).getKey(), baseAlgorithm); Cipher c; if (baseAlgorithm.equals("RC4")) { c = Cipher.getInstance(baseAlgorithm, "BC"); c.init(Cipher.ENCRYPT_MODE, encKey); } else { c = Cipher.getInstance(baseAlgorithm + "/CBC/PKCS7Padding", "BC"); c.init(Cipher.ENCRYPT_MODE, encKey, new IvParameterSpec(params.getIV())); } byte[] enc = c.doFinal(salt); c = Cipher.getInstance(algorithm, "BC"); PBEKeySpec keySpec = new PBEKeySpec(password, salt, iCount); SecretKeyFactory fact = SecretKeyFactory.getInstance(algorithm, "BC"); c.init(Cipher.DECRYPT_MODE, fact.generateSecret(keySpec)); byte[] dec = c.doFinal(enc); if (!Arrays.areEqual(salt, dec)) { fail("" + algorithm + "failed encryption/decryption test"); } } } private class PKCS12Test extends SimpleTest { char[] password; String baseAlgorithm; String algorithm; Digest digest; int keySize; int ivSize; PKCS12Test( String baseAlgorithm, String algorithm, Digest digest, int keySize, int ivSize) { this.password = algorithm.toCharArray(); this.baseAlgorithm = baseAlgorithm; this.algorithm = algorithm; this.digest = digest; this.keySize = keySize; this.ivSize = ivSize; } public String getName() { return "PKCS12PBE"; } public void performTest() throws Exception { byte[] salt = new byte[digest.getDigestSize()]; int iCount = 100; digest.doFinal(salt, 0); PKCS12ParametersGenerator pGen = new PKCS12ParametersGenerator(digest); pGen.init( PBEParametersGenerator.PKCS12PasswordToBytes(password), salt, iCount); ParametersWithIV params = (ParametersWithIV)pGen.generateDerivedParameters(keySize, ivSize); SecretKeySpec encKey = new SecretKeySpec(((KeyParameter)params.getParameters()).getKey(), baseAlgorithm); Cipher c; if (baseAlgorithm.equals("RC4")) { c = Cipher.getInstance(baseAlgorithm, "BC"); c.init(Cipher.ENCRYPT_MODE, encKey); } else { c = Cipher.getInstance(baseAlgorithm + "/CBC/PKCS7Padding", "BC"); c.init(Cipher.ENCRYPT_MODE, encKey, new IvParameterSpec(params.getIV())); } byte[] enc = c.doFinal(salt); c = Cipher.getInstance(algorithm, "BC"); PBEKeySpec keySpec = new PBEKeySpec(password, salt, iCount); SecretKeyFactory fact = SecretKeyFactory.getInstance(algorithm, "BC"); c.init(Cipher.DECRYPT_MODE, fact.generateSecret(keySpec)); byte[] dec = c.doFinal(enc); if (!Arrays.areEqual(salt, dec)) { fail("" + algorithm + "failed encryption/decryption test"); } // // get the parameters // AlgorithmParameters param = checkParameters(c, salt, iCount); // // try using parameters // c = Cipher.getInstance(algorithm, "BC"); keySpec = new PBEKeySpec(password); c.init(Cipher.DECRYPT_MODE, fact.generateSecret(keySpec), param); checkParameters(c, salt, iCount); dec = c.doFinal(enc); if (!Arrays.areEqual(salt, dec)) { fail("" + algorithm + "failed encryption/decryption test"); } // // try using PBESpec // c = Cipher.getInstance(algorithm, "BC"); keySpec = new PBEKeySpec(password); c.init(Cipher.DECRYPT_MODE, fact.generateSecret(keySpec), param.getParameterSpec(PBEParameterSpec.class)); checkParameters(c, salt, iCount); dec = c.doFinal(enc); if (!Arrays.areEqual(salt, dec)) { fail("" + algorithm + "failed encryption/decryption test"); } } private AlgorithmParameters checkParameters(Cipher c, byte[] salt, int iCount) throws InvalidParameterSpecException { AlgorithmParameters param = c.getParameters(); PBEParameterSpec spec = (PBEParameterSpec)param.getParameterSpec(PBEParameterSpec.class); if (!Arrays.areEqual(salt, spec.getSalt())) { fail("" + algorithm + "failed salt test"); } if (iCount != spec.getIterationCount()) { fail("" + algorithm + "failed count test"); } return param; } } private PKCS12Test[] pkcs12Tests = { new PKCS12Test("DESede", "PBEWITHSHAAND3-KEYTRIPLEDES-CBC", new SHA1Digest(), 192, 64), new PKCS12Test("DESede", "PBEWITHSHAAND2-KEYTRIPLEDES-CBC", new SHA1Digest(), 128, 64), new PKCS12Test("RC4", "PBEWITHSHAAND128BITRC4", new SHA1Digest(), 128, 0), new PKCS12Test("RC4", "PBEWITHSHAAND40BITRC4", new SHA1Digest(), 40, 0), new PKCS12Test("RC2", "PBEWITHSHAAND128BITRC2-CBC", new SHA1Digest(), 128, 64), new PKCS12Test("RC2", "PBEWITHSHAAND40BITRC2-CBC", new SHA1Digest(), 40, 64), new PKCS12Test("AES", "PBEWithSHA1And128BitAES-CBC-BC", new SHA1Digest(), 128, 128), new PKCS12Test("AES", "PBEWithSHA1And192BitAES-CBC-BC", new SHA1Digest(), 192, 128), new PKCS12Test("AES", "PBEWithSHA1And256BitAES-CBC-BC", new SHA1Digest(), 256, 128), new PKCS12Test("AES", "PBEWithSHA256And128BitAES-CBC-BC", new SHA256Digest(), 128, 128), new PKCS12Test("AES", "PBEWithSHA256And192BitAES-CBC-BC", new SHA256Digest(), 192, 128), new PKCS12Test("AES", "PBEWithSHA256And256BitAES-CBC-BC", new SHA256Digest(), 256, 128), new PKCS12Test("Twofish","PBEWithSHAAndTwofish-CBC", new SHA1Digest(), 256, 128), new PKCS12Test("IDEA", "PBEWithSHAAndIDEA-CBC", new SHA1Digest(), 128, 64), new PKCS12Test("AES", BCObjectIdentifiers.bc_pbe_sha1_pkcs12_aes128_cbc.getId(), new SHA1Digest(), 128, 128), new PKCS12Test("AES", BCObjectIdentifiers.bc_pbe_sha1_pkcs12_aes192_cbc.getId(), new SHA1Digest(), 192, 128), new PKCS12Test("AES", BCObjectIdentifiers.bc_pbe_sha1_pkcs12_aes256_cbc.getId(), new SHA1Digest(), 256, 128), new PKCS12Test("AES", BCObjectIdentifiers.bc_pbe_sha256_pkcs12_aes128_cbc.getId(), new SHA256Digest(), 128, 128), new PKCS12Test("AES", BCObjectIdentifiers.bc_pbe_sha256_pkcs12_aes192_cbc.getId(), new SHA256Digest(), 192, 128), new PKCS12Test("AES", BCObjectIdentifiers.bc_pbe_sha256_pkcs12_aes256_cbc.getId(), new SHA256Digest(), 256, 128), }; private OpenSSLTest openSSLTests[] = { new OpenSSLTest("AES", "PBEWITHMD5AND128BITAES-CBC-OPENSSL", 128, 128), new OpenSSLTest("AES", "PBEWITHMD5AND192BITAES-CBC-OPENSSL", 192, 128), new OpenSSLTest("AES", "PBEWITHMD5AND256BITAES-CBC-OPENSSL", 256, 128) }; static byte[] message = Hex.decode("4869205468657265"); private byte[] hMac1 = Hex.decode("bcc42174ccb04f425d9a5c8c4a95d6fd7c372911"); private byte[] hMac2 = Hex.decode("cb1d8bdb6aca9e3fa8980d6eb41ab28a7eb2cfd6"); private byte[] hMac3 = Hex.decode("514aa173a302c770689269aac08eb8698e5879ac"); private Cipher makePBECipherUsingParam( String algorithm, int mode, char[] password, byte[] salt, int iterationCount) throws Exception { PBEKeySpec pbeSpec = new PBEKeySpec(password); SecretKeyFactory keyFact = SecretKeyFactory.getInstance(algorithm, "BC"); PBEParameterSpec defParams = new PBEParameterSpec(salt, iterationCount); Cipher cipher = Cipher.getInstance(algorithm, "BC"); cipher.init(mode, keyFact.generateSecret(pbeSpec), defParams); return cipher; } private Cipher makePBECipherWithoutParam( String algorithm, int mode, char[] password, byte[] salt, int iterationCount) throws Exception { PBEKeySpec pbeSpec = new PBEKeySpec(password, salt, iterationCount); SecretKeyFactory keyFact = SecretKeyFactory.getInstance(algorithm, "BC"); Cipher cipher = Cipher.getInstance(algorithm, "BC"); cipher.init(mode, keyFact.generateSecret(pbeSpec)); return cipher; } public void testPBEHMac( String hmacName, byte[] output) { SecretKey key; byte[] out; Mac mac; try { SecretKeyFactory fact = SecretKeyFactory.getInstance(hmacName, "BC"); key = fact.generateSecret(new PBEKeySpec("hello".toCharArray())); mac = Mac.getInstance(hmacName, "BC"); } catch (Exception e) { fail("Failed - exception " + e.toString(), e); return; } try { mac.init(key, new PBEParameterSpec(new byte[20], 100)); } catch (Exception e) { fail("Failed - exception " + e.toString(), e); return; } mac.reset(); mac.update(message, 0, message.length); out = mac.doFinal(); if (!Arrays.areEqual(out, output)) { fail("Failed - expected " + new String(Hex.encode(output)) + " got " + new String(Hex.encode(out))); } } public void testPBEonSecretKeyHmac( String hmacName, byte[] output) { SecretKey key; byte[] out; Mac mac; try { SecretKeyFactory fact = SecretKeyFactory.getInstance(hmacName, "BC"); key = fact.generateSecret(new PBEKeySpec("hello".toCharArray(), new byte[20], 100, 160)); mac = Mac.getInstance("HMAC-SHA1", "BC"); } catch (Exception e) { fail("Failed - exception " + e.toString(), e); return; } try { mac.init(key); } catch (Exception e) { fail("Failed - exception " + e.toString(), e); return; } mac.reset(); mac.update(message, 0, message.length); out = mac.doFinal(); if (!Arrays.areEqual(out, output)) { fail("Failed - expected " + new String(Hex.encode(output)) + " got " + new String(Hex.encode(out))); } } private void testCipherNameWithWrap(String name, String simpleName) throws Exception { KeyGenerator kg = KeyGenerator.getInstance("AES"); kg.init(new SecureRandom()); SecretKey key = kg.generateKey(); byte[] salt = { (byte)0xc7, (byte)0x73, (byte)0x21, (byte)0x8c, (byte)0x7e, (byte)0xc8, (byte)0xee, (byte)0x99 }; char[] password = { 'p','a','s','s','w','o','r','d' }; PBEParameterSpec pbeParamSpec = new PBEParameterSpec(salt, 20); PBEKeySpec pbeKeySpec = new PBEKeySpec(password); SecretKeyFactory keyFac = SecretKeyFactory.getInstance(name); SecretKey pbeKey = keyFac.generateSecret(pbeKeySpec); Cipher pbeEncryptCipher = Cipher.getInstance(name, "BC"); pbeEncryptCipher.init(Cipher.WRAP_MODE, pbeKey, pbeParamSpec); byte[] symKeyBytes = pbeEncryptCipher.wrap(key); Cipher simpleCipher = Cipher.getInstance(simpleName, "BC"); simpleCipher.init(Cipher.UNWRAP_MODE, pbeKey, pbeParamSpec); SecretKey unwrappedKey = (SecretKey)simpleCipher.unwrap(symKeyBytes, "AES", Cipher.SECRET_KEY); if (!Arrays.areEqual(unwrappedKey.getEncoded(), key.getEncoded())) { fail("key mismatch on unwrapping"); } } public void performTest() throws Exception { byte[] input = Hex.decode("1234567890abcdefabcdef1234567890fedbca098765"); // // DES // Cipher cEnc = Cipher.getInstance("DES/CBC/PKCS7Padding", "BC"); cEnc.init(Cipher.ENCRYPT_MODE, new SecretKeySpec(Hex.decode("30e69252758e5346"), "DES"), new IvParameterSpec(Hex.decode("7c1c1ab9c454a688"))); byte[] out = cEnc.doFinal(input); char[] password = { 'p', 'a', 's', 's', 'w', 'o', 'r', 'd' }; Cipher cDec = makePBECipherUsingParam( "PBEWithSHA1AndDES", Cipher.DECRYPT_MODE, password, Hex.decode("7d60435f02e9e0ae"), 2048); byte[] in = cDec.doFinal(out); if (!Arrays.areEqual(input, in)) { fail("DES failed"); } cDec = makePBECipherWithoutParam( "PBEWithSHA1AndDES", Cipher.DECRYPT_MODE, password, Hex.decode("7d60435f02e9e0ae"), 2048); in = cDec.doFinal(out); if (!Arrays.areEqual(input, in)) { fail("DES failed without param"); } // // DESede // cEnc = Cipher.getInstance("DESede/CBC/PKCS7Padding", "BC"); cEnc.init(Cipher.ENCRYPT_MODE, new SecretKeySpec(Hex.decode("732f2d33c801732b7206756cbd44f9c1c103ddd97c7cbe8e"), "DES"), new IvParameterSpec(Hex.decode("b07bf522c8d608b8"))); out = cEnc.doFinal(input); cDec = makePBECipherUsingParam( "PBEWithSHAAnd3-KeyTripleDES-CBC", Cipher.DECRYPT_MODE, password, Hex.decode("7d60435f02e9e0ae"), 2048); in = cDec.doFinal(out); if (!Arrays.areEqual(input, in)) { fail("DESede failed"); } // // 40Bit RC2 // cEnc = Cipher.getInstance("RC2/CBC/PKCS7Padding", "BC"); cEnc.init(Cipher.ENCRYPT_MODE, new SecretKeySpec(Hex.decode("732f2d33c8"), "RC2"), new IvParameterSpec(Hex.decode("b07bf522c8d608b8"))); out = cEnc.doFinal(input); cDec = makePBECipherUsingParam( "PBEWithSHAAnd40BitRC2-CBC", Cipher.DECRYPT_MODE, password, Hex.decode("7d60435f02e9e0ae"), 2048); in = cDec.doFinal(out); if (!Arrays.areEqual(input, in)) { fail("RC2 failed"); } // // 128bit RC4 // cEnc = Cipher.getInstance("RC4", "BC"); cEnc.init(Cipher.ENCRYPT_MODE, new SecretKeySpec(Hex.decode("732f2d33c801732b7206756cbd44f9c1"), "RC4")); out = cEnc.doFinal(input); cDec = makePBECipherUsingParam( "PBEWithSHAAnd128BitRC4", Cipher.DECRYPT_MODE, password, Hex.decode("7d60435f02e9e0ae"), 2048); in = cDec.doFinal(out); if (!Arrays.areEqual(input, in)) { fail("RC4 failed"); } cDec = makePBECipherWithoutParam( "PBEWithSHAAnd128BitRC4", Cipher.DECRYPT_MODE, password, Hex.decode("7d60435f02e9e0ae"), 2048); in = cDec.doFinal(out); if (!Arrays.areEqual(input, in)) { fail("RC4 failed without param"); } for (int i = 0; i != pkcs12Tests.length; i++) { pkcs12Tests[i].perform(); } for (int i = 0; i != openSSLTests.length; i++) { openSSLTests[i].perform(); } testPBEHMac("PBEWithHMacSHA1", hMac1); testPBEHMac("PBEWithHMacRIPEMD160", hMac2); testPBEonSecretKeyHmac("PBKDF2WithHmacSHA1", hMac3); testCipherNameWithWrap("PBEWITHSHA256AND128BITAES-CBC-BC", "AES/CBC/PKCS5Padding"); testCipherNameWithWrap("PBEWITHSHAAND40BITRC4", "RC4"); testCipherNameWithWrap("PBEWITHSHAAND128BITRC4", "RC4"); checkPBE("PBKDF2WithHmacSHA1", true, "f14687fc31a66e2f7cc01d0a65f687961bd27e20", "6f6579193d6433a3e4600b243bb390674f04a615"); } private void checkPBE(String baseAlg, boolean defIsUTF8, String utf8, String eightBit) throws Exception { byte[] utf8K = Hex.decode(utf8); byte[] ascK = Hex.decode(eightBit); SecretKeyFactory f = SecretKeyFactory.getInstance(baseAlg, "BC"); KeySpec ks1 = new PBEKeySpec("\u0141\u0142".toCharArray(), new byte[20], 4096, 160); if (!Arrays.areEqual((defIsUTF8) ? utf8K : ascK, f.generateSecret(ks1).getEncoded())) { fail(baseAlg + " wrong PBKDF2 k1 key generated, got : " + new String(Hex.encode(f.generateSecret(ks1).getEncoded()))); } KeySpec ks2 = new PBEKeySpec("\u0041\u0042".toCharArray(), new byte[20], 4096, 160); if (!Arrays.areEqual(ascK, f.generateSecret(ks2).getEncoded())) { fail(baseAlg + " wrong PBKDF2 k2 key generated"); } f = SecretKeyFactory.getInstance(baseAlg + "AndUTF8", "BC"); ks1 = new PBEKeySpec("\u0141\u0142".toCharArray(), new byte[20], 4096, 160); if (!Arrays.areEqual(utf8K, f.generateSecret(ks1).getEncoded())) { fail(baseAlg + " wrong PBKDF2 k1 utf8 key generated"); } ks2 = new PBEKeySpec("\u0041\u0042".toCharArray(), new byte[20], 4096, 160); if (!Arrays.areEqual(ascK, f.generateSecret(ks2).getEncoded())) { fail(baseAlg + " wrong PBKDF2 k2 utf8 key generated"); } f = SecretKeyFactory.getInstance(baseAlg + "And8BIT", "BC"); ks1 = new PBEKeySpec("\u0141\u0142".toCharArray(), new byte[20], 4096, 160); if (!Arrays.areEqual(ascK, f.generateSecret(ks1).getEncoded())) { fail(baseAlg + " wrong PBKDF2 k1 8bit key generated"); } ks2 = new PBEKeySpec("\u0041\u0042".toCharArray(), new byte[20], 4096, 160); if (!Arrays.areEqual(ascK, f.generateSecret(ks2).getEncoded())) { fail(baseAlg + " wrong PBKDF2 k2 8bit key generated"); } } public String getName() { return "PBETest"; } public static void main( String[] args) { Security.addProvider(new BouncyCastleProvider()); runTest(new PBETest()); } } bouncycastle-1.49.orig/test/src/org/bouncycastle/jce/provider/test/CertPathBuilderTest.java0000644000175000017500000001260111057664613031570 0ustar ebourgebourgpackage org.bouncycastle.jce.provider.test; import java.io.ByteArrayInputStream; import java.math.BigInteger; import java.security.KeyPair; import java.security.Security; import java.security.cert.CertPath; import java.security.cert.CertPathBuilder; import java.security.cert.CertStore; import java.security.cert.CertificateFactory; import java.security.cert.CollectionCertStoreParameters; import java.security.cert.PKIXBuilderParameters; import java.security.cert.PKIXCertPathBuilderResult; import java.security.cert.TrustAnchor; import java.security.cert.X509CRL; import java.security.cert.X509CertSelector; import java.security.cert.X509Certificate; import java.util.ArrayList; import java.util.Calendar; import java.util.Collections; import java.util.Date; import java.util.HashSet; import java.util.List; import java.util.Set; import org.bouncycastle.jce.provider.BouncyCastleProvider; import org.bouncycastle.util.test.SimpleTest; public class CertPathBuilderTest extends SimpleTest { private void baseTest() throws Exception { CertificateFactory cf = CertificateFactory.getInstance("X.509", "BC"); // initialise CertStore X509Certificate rootCert = (X509Certificate)cf.generateCertificate(new ByteArrayInputStream(CertPathTest.rootCertBin)); X509Certificate interCert = (X509Certificate)cf.generateCertificate(new ByteArrayInputStream(CertPathTest.interCertBin)); X509Certificate finalCert = (X509Certificate)cf.generateCertificate(new ByteArrayInputStream(CertPathTest.finalCertBin)); X509CRL rootCrl = (X509CRL)cf.generateCRL(new ByteArrayInputStream(CertPathTest.rootCrlBin)); X509CRL interCrl = (X509CRL)cf.generateCRL(new ByteArrayInputStream(CertPathTest.interCrlBin)); List list = new ArrayList(); list.add(rootCert); list.add(interCert); list.add(finalCert); list.add(rootCrl); list.add(interCrl); CollectionCertStoreParameters ccsp = new CollectionCertStoreParameters(list); CertStore store = CertStore.getInstance("Collection", ccsp, "BC"); Calendar validDate = Calendar.getInstance(); validDate.set(2008,8,4,14,49,10); //Searching for rootCert by subjectDN without CRL Set trust = new HashSet(); trust.add(new TrustAnchor(rootCert, null)); CertPathBuilder cpb = CertPathBuilder.getInstance("PKIX","BC"); X509CertSelector targetConstraints = new X509CertSelector(); targetConstraints.setSubject(finalCert.getSubjectX500Principal().getEncoded()); PKIXBuilderParameters params = new PKIXBuilderParameters(trust, targetConstraints); params.addCertStore(store); params.setDate(validDate.getTime()); PKIXCertPathBuilderResult result = (PKIXCertPathBuilderResult) cpb.build(params); CertPath path = result.getCertPath(); if (path.getCertificates().size() != 2) { fail("wrong number of certs in baseTest path"); } } private void v0Test() throws Exception { // create certificates and CRLs KeyPair rootPair = TestUtils.generateRSAKeyPair(); KeyPair interPair = TestUtils.generateRSAKeyPair(); KeyPair endPair = TestUtils.generateRSAKeyPair(); X509Certificate rootCert = TestUtils.generateRootCert(rootPair); X509Certificate interCert = TestUtils.generateIntermediateCert(interPair.getPublic(), rootPair.getPrivate(), rootCert); X509Certificate endCert = TestUtils.generateEndEntityCert(endPair.getPublic(), interPair.getPrivate(), interCert); BigInteger revokedSerialNumber = BigInteger.valueOf(2); X509CRL rootCRL = TestUtils.createCRL(rootCert, rootPair.getPrivate(), revokedSerialNumber); X509CRL interCRL = TestUtils.createCRL(interCert, interPair.getPrivate(), revokedSerialNumber); // create CertStore to support path building List list = new ArrayList(); list.add(rootCert); list.add(interCert); list.add(endCert); list.add(rootCRL); list.add(interCRL); CollectionCertStoreParameters params = new CollectionCertStoreParameters(list); CertStore store = CertStore.getInstance("Collection", params); // build the path CertPathBuilder builder = CertPathBuilder.getInstance("PKIX", "BC"); X509CertSelector pathConstraints = new X509CertSelector(); pathConstraints.setSubject(endCert.getSubjectX500Principal().getEncoded()); PKIXBuilderParameters buildParams = new PKIXBuilderParameters(Collections.singleton(new TrustAnchor(rootCert, null)), pathConstraints); buildParams.addCertStore(store); buildParams.setDate(new Date()); PKIXCertPathBuilderResult result = (PKIXCertPathBuilderResult)builder.build(buildParams); CertPath path = result.getCertPath(); if (path.getCertificates().size() != 2) { fail("wrong number of certs in v0Test path"); } } public void performTest() throws Exception { baseTest(); v0Test(); } public String getName() { return "CertPathBuilder"; } public static void main( String[] args) { Security.addProvider(new BouncyCastleProvider()); runTest(new CertPathBuilderTest()); } } bouncycastle-1.49.orig/test/src/org/bouncycastle/jce/provider/test/SerialisationTest.java0000644000175000017500000004166610634146665031374 0ustar ebourgebourgpackage org.bouncycastle.jce.provider.test; import org.bouncycastle.jce.interfaces.ElGamalPrivateKey; import org.bouncycastle.jce.interfaces.ElGamalPublicKey; import org.bouncycastle.util.encoders.Base64; import org.bouncycastle.util.test.SimpleTest; import javax.crypto.interfaces.DHPrivateKey; import javax.crypto.interfaces.DHPublicKey; import java.io.ByteArrayInputStream; import java.io.IOException; import java.io.ObjectInputStream; import java.math.BigInteger; import java.security.interfaces.DSAPrivateKey; import java.security.interfaces.DSAPublicKey; import java.security.interfaces.RSAPrivateCrtKey; import java.security.interfaces.RSAPublicKey; public class SerialisationTest extends SimpleTest { private static BigInteger mod = new BigInteger("69919157209851583596607278525201743749468350078269839551939850344506918649679"); private static BigInteger pubExp = new BigInteger("65537"); private static BigInteger privExp = new BigInteger("6387323103214694462561419908301918608189256611651974386490887304224030221257"); private static BigInteger crtExp = new BigInteger("49050879172577973803420172068797326635"); private static BigInteger p = new BigInteger("272712035519670228866910009292918035133"); private static BigInteger q = new BigInteger("256384567247338962716621434774670631163"); private static BigInteger expP = new BigInteger("121540093892892992427860713054115232161"); private static BigInteger expQ = new BigInteger("169333445127196347119779037859859594883"); private static byte[] rsaPub = Base64.decode( "rO0ABXNyAC1vcmcuYm91bmN5Y2FzdGxlLmpjZS5wcm92aWRlci5KQ0VSU0FQdWJsaWNLZXklImoOW/pshAIAAkwAB21vZHV" + "sdXN0ABZMamF2YS9tYXRoL0JpZ0ludGVnZXI7TAAOcHVibGljRXhwb25lbnRxAH4AAXhwc3IAFGphdmEubWF0aC5CaWdJbn" + "RlZ2VyjPyfH6k7+x0DAAZJAAhiaXRDb3VudEkACWJpdExlbmd0aEkAE2ZpcnN0Tm9uemVyb0J5dGVOdW1JAAxsb3dlc3RTZ" + "XRCaXRJAAZzaWdudW1bAAltYWduaXR1ZGV0AAJbQnhyABBqYXZhLmxhbmcuTnVtYmVyhqyVHQuU4IsCAAB4cP//////////" + "/////v////4AAAABdXIAAltCrPMX+AYIVOACAAB4cAAAACCalNcvvJNMM944KWzzuH2MXkKbiW10OEzGQb9B9MM/T3hzcQB" + "+AAP///////////////7////+AAAAAXVxAH4ABwAAAAMBAAF4"); private static byte[] rsaPriv = Base64.decode( "rO0ABXNyADFvcmcuYm91bmN5Y2FzdGxlLmpjZS5wcm92aWRlci5KQ0VSU0FQcml2YXRlQ3J0S2V5bLqHzgJzVS4CAAZMAA5" + "jcnRDb2VmZmljaWVudHQAFkxqYXZhL21hdGgvQmlnSW50ZWdlcjtMAA5wcmltZUV4cG9uZW50UHEAfgABTAAOcHJpbWVFeH" + "BvbmVudFFxAH4AAUwABnByaW1lUHEAfgABTAAGcHJpbWVRcQB+AAFMAA5wdWJsaWNFeHBvbmVudHEAfgABeHIALm9yZy5ib" + "3VuY3ljYXN0bGUuamNlLnByb3ZpZGVyLkpDRVJTQVByaXZhdGVLZXlG6wnAB89BHAMABEwAB21vZHVsdXNxAH4AAUwAEHBr" + "Y3MxMkF0dHJpYnV0ZXN0ABVMamF2YS91dGlsL0hhc2h0YWJsZTtMAA5wa2NzMTJPcmRlcmluZ3QAEkxqYXZhL3V0aWwvVmV" + "jdG9yO0wAD3ByaXZhdGVFeHBvbmVudHEAfgABeHBzcgAUamF2YS5tYXRoLkJpZ0ludGVnZXKM/J8fqTv7HQMABkkACGJpdE" + "NvdW50SQAJYml0TGVuZ3RoSQATZmlyc3ROb256ZXJvQnl0ZU51bUkADGxvd2VzdFNldEJpdEkABnNpZ251bVsACW1hZ25pd" + "HVkZXQAAltCeHIAEGphdmEubGFuZy5OdW1iZXKGrJUdC5TgiwIAAHhw///////////////+/////gAAAAF1cgACW0Ks8xf4" + "BghU4AIAAHhwAAAAIJqU1y+8k0wz3jgpbPO4fYxeQpuJbXQ4TMZBv0H0wz9PeHNyABNqYXZhLnV0aWwuSGFzaHRhYmxlE7s" + "PJSFK5LgDAAJGAApsb2FkRmFjdG9ySQAJdGhyZXNob2xkeHA/QAAAAAAACHcIAAAACwAAAAB4c3IAEGphdmEudXRpbC5WZW" + "N0b3LZl31bgDuvAQMAA0kAEWNhcGFjaXR5SW5jcmVtZW50SQAMZWxlbWVudENvdW50WwALZWxlbWVudERhdGF0ABNbTGphd" + "mEvbGFuZy9PYmplY3Q7eHAAAAAAAAAAAHVyABNbTGphdmEubGFuZy5PYmplY3Q7kM5YnxBzKWwCAAB4cAAAAApwcHBwcHBw" + "cHBweHNxAH4ABv///////////////v////4AAAABdXEAfgAKAAAAIA4fGMVoocAtYNiamDRvnzBmMv/l8FibkQsOUJjxrmP" + "JeHhzcQB+AAb///////////////7////+AAAAAXVxAH4ACgAAABAk5tsPIq2YfF0nfLPvAKUreHNxAH4ABv////////////" + "///v////4AAAABdXEAfgAKAAAAEFtvxUfS67k0bWmAU9/geaF4c3EAfgAG///////////////+/////gAAAAF1cQB+AAoAA" + "AAQf2RvbOpsxhCjGK1vhd7+g3hzcQB+AAb///////////////7////+AAAAAXVxAH4ACgAAABDNKm1zRn/cYal03dRjdxK9" + "eHNxAH4ABv///////////////v////4AAAABdXEAfgAKAAAAEMDh3xza3MJ4XNak/35BYPt4c3EAfgAG///////////////" + "+/////gAAAAF1cQB+AAoAAAADAQABeA=="); private static BigInteger elGamalY = new BigInteger("89822212135401014750127909969755994242838935150891306006689219384134393835581"); private static BigInteger elGamalX = new BigInteger("23522982289275336984843296896007818700866293719703239515258104457243931686357"); private static BigInteger elGamalG = new BigInteger("29672625807664138507782226105202719390719480236799714903174779490259822385963"); private static BigInteger elGamalP = new BigInteger("98263422916834911205348180460395783697757584103849580149025105739079617780363"); private static byte[] elGamalPub = Base64.decode( "rO0ABXNyADFvcmcuYm91bmN5Y2FzdGxlLmpjZS5wcm92aWRlci5KQ0VFbEdhbWFsUHVibGljS2V5eOnUVVUsZjQDAAJMAAZ" + "lbFNwZWN0ADBMb3JnL2JvdW5jeWNhc3RsZS9qY2Uvc3BlYy9FbEdhbWFsUGFyYW1ldGVyU3BlYztMAAF5dAAWTGphdmEvbW" + "F0aC9CaWdJbnRlZ2VyO3hwc3IAFGphdmEubWF0aC5CaWdJbnRlZ2VyjPyfH6k7+x0DAAZJAAhiaXRDb3VudEkACWJpdExlb" + "md0aEkAE2ZpcnN0Tm9uemVyb0J5dGVOdW1JAAxsb3dlc3RTZXRCaXRJAAZzaWdudW1bAAltYWduaXR1ZGV0AAJbQnhyABBq" + "YXZhLmxhbmcuTnVtYmVyhqyVHQuU4IsCAAB4cP///////////////v////4AAAABdXIAAltCrPMX+AYIVOACAAB4cAAAACD" + "GlZIJNbVQCnj4wiR0o8gGbKtJEWJBllz8NAELXcqwPXhzcQB+AAT///////////////7////+AAAAAXVxAH4ACAAAACDZPy" + "BetQ1Ed8NUnTfXb+MBhFVK1KRe2LzQP7oVz2Kai3hzcQB+AAT///////////////7////+AAAAAXVxAH4ACAAAACBBmhxth" + "0FhU4SsG01Wjyi1dlZFZvOy1zFC12XRGO8bK3h4"); private static byte[] elGamalPriv = Base64.decode( "rO0ABXNyADJvcmcuYm91bmN5Y2FzdGxlLmpjZS5wcm92aWRlci5KQ0VFbEdhbWFsUHJpdmF0ZUtleULhxV+2vMBOAwAETAA" + "GZWxTcGVjdAAwTG9yZy9ib3VuY3ljYXN0bGUvamNlL3NwZWMvRWxHYW1hbFBhcmFtZXRlclNwZWM7TAAQcGtjczEyQXR0cm" + "lidXRlc3QAFUxqYXZhL3V0aWwvSGFzaHRhYmxlO0wADnBrY3MxMk9yZGVyaW5ndAASTGphdmEvdXRpbC9WZWN0b3I7TAABe" + "HQAFkxqYXZhL21hdGgvQmlnSW50ZWdlcjt4cHNyABRqYXZhLm1hdGguQmlnSW50ZWdlcoz8nx+pO/sdAwAGSQAIYml0Q291" + "bnRJAAliaXRMZW5ndGhJABNmaXJzdE5vbnplcm9CeXRlTnVtSQAMbG93ZXN0U2V0Qml0SQAGc2lnbnVtWwAJbWFnbml0dWR" + "ldAACW0J4cgAQamF2YS5sYW5nLk51bWJlcoaslR0LlOCLAgAAeHD///////////////7////+AAAAAXVyAAJbQqzzF/gGCF" + "TgAgAAeHAAAAAgNAGJQeYfM6ToYoA3ePFdEe7yh8hKecr+WZA0AwxrtdV4c3EAfgAG///////////////+/////gAAAAF1c" + "QB+AAoAAAAg2T8gXrUNRHfDVJ0312/jAYRVStSkXti80D+6Fc9imot4c3EAfgAG///////////////+/////gAAAAF1cQB+" + "AAoAAAAgQZocbYdBYVOErBtNVo8otXZWRWbzstcxQtdl0RjvGyt4eA=="); private static BigInteger dhY = new BigInteger("1925747248304483170395506065378568192931506039297732684689153183373019672434"); private static BigInteger dhX = new BigInteger("3"); private static BigInteger dhG = new BigInteger("3493483775405590747011712302510626058005717040655777294576367636428413099058"); private static BigInteger dhP = new BigInteger("106557663805518855012633095511067237673895862256610675920943888960856082029127"); private static byte[] dhPub = Base64.decode( "rO0ABXNyACxvcmcuYm91bmN5Y2FzdGxlLmpjZS5wcm92aWRlci5KQ0VESFB1YmxpY0tlefz+KCkPI+T8AwACTAAGZGhTcGV" + "jdAAjTGphdmF4L2NyeXB0by9zcGVjL0RIUGFyYW1ldGVyU3BlYztMAAF5dAAWTGphdmEvbWF0aC9CaWdJbnRlZ2VyO3hwc3" + "IAFGphdmEubWF0aC5CaWdJbnRlZ2VyjPyfH6k7+x0DAAZJAAhiaXRDb3VudEkACWJpdExlbmd0aEkAE2ZpcnN0Tm9uemVyb" + "0J5dGVOdW1JAAxsb3dlc3RTZXRCaXRJAAZzaWdudW1bAAltYWduaXR1ZGV0AAJbQnhyABBqYXZhLmxhbmcuTnVtYmVyhqyV" + "HQuU4IsCAAB4cP///////////////v////4AAAABdXIAAltCrPMX+AYIVOACAAB4cAAAACAEQe8vYXxZPS5oAUy0e0yRYxK" + "EAO3GjhMWZKNw8flvcnhzcQB+AAT///////////////7////+AAAAAXVxAH4ACAAAACDrlYAb5zOABHPgsK6oIKtMFgPD3v" + "nbTosOnokaSVsaR3hzcQB+AAT///////////////7////+AAAAAXVxAH4ACAAAACAHuT3jEhOVRGfaKdFOX6J2vDYxiMPQW" + "ljjL/3Xz85cMnh3BAAAAAB4"); private static byte[] dhPriv = Base64.decode( "rO0ABXNyAC1vcmcuYm91bmN5Y2FzdGxlLmpjZS5wcm92aWRlci5KQ0VESFByaXZhdGVLZXkEURpYQRlitAMABEwABmRoU3B" + "lY3QAI0xqYXZheC9jcnlwdG8vc3BlYy9ESFBhcmFtZXRlclNwZWM7TAAQcGtjczEyQXR0cmlidXRlc3QAFUxqYXZhL3V0aW" + "wvSGFzaHRhYmxlO0wADnBrY3MxMk9yZGVyaW5ndAASTGphdmEvdXRpbC9WZWN0b3I7TAABeHQAFkxqYXZhL21hdGgvQmlnS" + "W50ZWdlcjt4cHNyABRqYXZhLm1hdGguQmlnSW50ZWdlcoz8nx+pO/sdAwAGSQAIYml0Q291bnRJAAliaXRMZW5ndGhJABNm" + "aXJzdE5vbnplcm9CeXRlTnVtSQAMbG93ZXN0U2V0Qml0SQAGc2lnbnVtWwAJbWFnbml0dWRldAACW0J4cgAQamF2YS5sYW5" + "nLk51bWJlcoaslR0LlOCLAgAAeHD///////////////7////+AAAAAXVyAAJbQqzzF/gGCFTgAgAAeHAAAAABA3hzcQB+AA" + "b///////////////7////+AAAAAXVxAH4ACgAAACDrlYAb5zOABHPgsK6oIKtMFgPD3vnbTosOnokaSVsaR3hzcQB+AAb//" + "/////////////7////+AAAAAXVxAH4ACgAAACAHuT3jEhOVRGfaKdFOX6J2vDYxiMPQWljjL/3Xz85cMnh3BAAAAAB4"); private static BigInteger dsaY = new BigInteger("6189794363048388077684611193598066807847399153242870209962581468350882042922904596556915269714052441467859854436813271130403014368908908961326314287317209"); private static BigInteger dsaX = new BigInteger("45673695048287886591258561084679393738177012644"); private static BigInteger dsaG = new BigInteger("3245524385217980657302535456606469153364622623109429686740209357408427939040123729832874550911504858612362156241316117434271994372338032643547044203024422"); private static BigInteger dsaP = new BigInteger("8836853285188714261909188099204635517862922237850722644742752953058083563923137941667883080809922365262319540202714582925718707421743492259382127680083261"); private static byte[] dsaPub = Base64.decode( "rO0ABXNyAC1vcmcuYm91bmN5Y2FzdGxlLmpjZS5wcm92aWRlci5KREtEU0FQdWJsaWNLZXkYUfY34kLIBwMAAkwAB2RzYVN" + "wZWN0ACRMamF2YS9zZWN1cml0eS9pbnRlcmZhY2VzL0RTQVBhcmFtcztMAAF5dAAWTGphdmEvbWF0aC9CaWdJbnRlZ2VyO3" + "hwc3IAFGphdmEubWF0aC5CaWdJbnRlZ2VyjPyfH6k7+x0DAAZJAAhiaXRDb3VudEkACWJpdExlbmd0aEkAE2ZpcnN0Tm9ue" + "mVyb0J5dGVOdW1JAAxsb3dlc3RTZXRCaXRJAAZzaWdudW1bAAltYWduaXR1ZGV0AAJbQnhyABBqYXZhLmxhbmcuTnVtYmVy" + "hqyVHQuU4IsCAAB4cP///////////////v////4AAAABdXIAAltCrPMX+AYIVOACAAB4cAAAAEB2LxWpG2UqKz0HcWZwDii" + "fO0+3sXqWwmnAnHw8HbPRbtJUozr0As4FX7loWxvWyV+CJDse2KwdxISyMmq6hMDZeHNxAH4ABP///////////////v////" + "4AAAABdXEAfgAIAAAAQKi5o5xNZaCAFFAV6dWnHHjG0TVoA7d34RUNF0GhquH6BH/W3BvW4fy428+NPnCgUvJM9iLBTpuBn" + "oepupEE1T14c3EAfgAE///////////////+/////gAAAAF1cQB+AAgAAAAU/tVyr5rbnY4WkK7C6NK21c9jn8V4c3EAfgAE" + "///////////////+/////gAAAAF1cQB+AAgAAABAPffK8RBcfUspb5PsGDyjZf4Tqcmo5UhuaABmUnq8Vqb3P7jc1+LNaTh" + "mUJSnjWQ4+kyCeeJgPH9d3iBd5blQJnh4"); private static byte[] dsaPriv = Base64.decode( "rO0ABXNyAC5vcmcuYm91bmN5Y2FzdGxlLmpjZS5wcm92aWRlci5KREtEU0FQcml2YXRlS2V5vxcJOSU9rboDAANMAAthdHR" + "yQ2FycmllcnQAPUxvcmcvYm91bmN5Y2FzdGxlL2pjZS9wcm92aWRlci9QS0NTMTJCYWdBdHRyaWJ1dGVDYXJyaWVySW1wbD" + "tMAAdkc2FTcGVjdAAkTGphdmEvc2VjdXJpdHkvaW50ZXJmYWNlcy9EU0FQYXJhbXM7TAABeHQAFkxqYXZhL21hdGgvQmlnS" + "W50ZWdlcjt4cHNyABRqYXZhLm1hdGguQmlnSW50ZWdlcoz8nx+pO/sdAwAGSQAIYml0Q291bnRJAAliaXRMZW5ndGhJABNm" + "aXJzdE5vbnplcm9CeXRlTnVtSQAMbG93ZXN0U2V0Qml0SQAGc2lnbnVtWwAJbWFnbml0dWRldAACW0J4cgAQamF2YS5sYW5" + "nLk51bWJlcoaslR0LlOCLAgAAeHD///////////////7////+AAAAAXVyAAJbQqzzF/gGCFTgAgAAeHAAAAAUCAAUTkau3a" + "uChEXbN4isGH4aY6R4c3EAfgAF///////////////+/////gAAAAF1cQB+AAkAAABAqLmjnE1loIAUUBXp1acceMbRNWgDt" + "3fhFQ0XQaGq4foEf9bcG9bh/Ljbz40+cKBS8kz2IsFOm4Geh6m6kQTVPXhzcQB+AAX///////////////7////+AAAAAXVx" + "AH4ACQAAABT+1XKvmtudjhaQrsLo0rbVz2OfxXhzcQB+AAX///////////////7////+AAAAAXVxAH4ACQAAAEA998rxEFx" + "9Sylvk+wYPKNl/hOpyajlSG5oAGZSerxWpvc/uNzX4s1pOGZQlKeNZDj6TIJ54mA8f13eIF3luVAmeHNyABNqYXZhLnV0aW" + "wuSGFzaHRhYmxlE7sPJSFK5LgDAAJGAApsb2FkRmFjdG9ySQAJdGhyZXNob2xkeHA/QAAAAAAACHcIAAAACwAAAAB4c3IAE" + "GphdmEudXRpbC5WZWN0b3LZl31bgDuvAQMAA0kAEWNhcGFjaXR5SW5jcmVtZW50SQAMZWxlbWVudENvdW50WwALZWxlbWVu" + "dERhdGF0ABNbTGphdmEvbGFuZy9PYmplY3Q7eHAAAAAAAAAAAHVyABNbTGphdmEubGFuZy5PYmplY3Q7kM5YnxBzKWwCAAB" + "4cAAAAApwcHBwcHBwcHBweHg="); public String getName() { return "Serialisation"; } public void performTest() throws Exception { rsaTest(); elGamalTest(); dhTest(); dsaTest(); } private void rsaTest() throws IOException, ClassNotFoundException { RSAPublicKey pub = (RSAPublicKey)readObject(rsaPub); if (!mod.equals(pub.getModulus())) { fail("public key modulus mismatch"); } if (!pubExp.equals(pub.getPublicExponent())) { fail("public key exponent mismatch"); } RSAPrivateCrtKey priv = (RSAPrivateCrtKey)readObject(rsaPriv); if (!mod.equals(priv.getModulus())) { fail("private key modulus mismatch"); } if (!privExp.equals(priv.getPrivateExponent())) { fail("private key exponent mismatch"); } if (!p.equals(priv.getPrimeP())) { fail("private key p mismatch"); } if (!q.equals(priv.getPrimeQ())) { fail("private key q mismatch"); } if (!expP.equals(priv.getPrimeExponentP())) { fail("private key p exponent mismatch"); } if (!expQ.equals(priv.getPrimeExponentQ())) { fail("private key q exponent mismatch"); } if (!crtExp.equals(priv.getCrtCoefficient())) { fail("private key crt exponent mismatch"); } } private void elGamalTest() throws IOException, ClassNotFoundException { ElGamalPublicKey pub = (ElGamalPublicKey)readObject(elGamalPub); if (!elGamalY.equals(pub.getY())) { fail("public key y mismatch"); } if (!elGamalG.equals(pub.getParameters().getG())) { fail("public key g mismatch"); } if (!elGamalP.equals(pub.getParameters().getP())) { fail("public key p mismatch"); } ElGamalPrivateKey priv = (ElGamalPrivateKey)readObject(elGamalPriv); if (!elGamalX.equals(priv.getX())) { fail("private key x mismatch"); } if (!elGamalG.equals(priv.getParameters().getG())) { fail("private key g mismatch"); } if (!elGamalP.equals(priv.getParameters().getP())) { fail("private key p mismatch"); } } private void dhTest() throws IOException, ClassNotFoundException { DHPublicKey pub = (DHPublicKey)readObject(dhPub); if (!dhY.equals(pub.getY())) { fail("dh public key y mismatch"); } if (!dhG.equals(pub.getParams().getG())) { fail("dh public key g mismatch"); } if (!dhP.equals(pub.getParams().getP())) { fail("dh public key p mismatch"); } if (0 != pub.getParams().getL()) { fail("dh public key l mismatch"); } DHPrivateKey priv = (DHPrivateKey)readObject(dhPriv); if (!dhX.equals(priv.getX())) { fail("dh private key x mismatch"); } if (!dhG.equals(priv.getParams().getG())) { fail("dh private key g mismatch"); } if (!dhP.equals(priv.getParams().getP())) { fail("dh private key p mismatch"); } if (0 != priv.getParams().getL()) { fail("dh private key l mismatch"); } } private void dsaTest() throws IOException, ClassNotFoundException { DSAPublicKey pub = (DSAPublicKey)readObject(dsaPub); if (!dsaY.equals(pub.getY())) { fail("dsa public key y mismatch"); } if (!dsaG.equals(pub.getParams().getG())) { fail("dsa public key g mismatch"); } if (!dsaP.equals(pub.getParams().getP())) { fail("dsa public key p mismatch"); } DSAPrivateKey priv = (DSAPrivateKey)readObject(dsaPriv); if (!dsaX.equals(priv.getX())) { fail("dsa private key x mismatch"); } if (!dsaG.equals(priv.getParams().getG())) { fail("dsa private key g mismatch"); } if (!dsaP.equals(priv.getParams().getP())) { fail("dsa private key p mismatch"); } } private Object readObject(byte[] key) throws IOException, ClassNotFoundException { ObjectInputStream oIn = new ObjectInputStream(new ByteArrayInputStream(key)); return oIn.readObject(); } public static void main( String[] args) { runTest(new SerialisationTest()); } } bouncycastle-1.49.orig/test/src/org/bouncycastle/jce/provider/test/SlotTwoTest.java0000644000175000017500000000471510350737442030165 0ustar ebourgebourgpackage org.bouncycastle.jce.provider.test; import java.security.Key; import java.security.SecureRandom; import java.security.Security; import javax.crypto.Cipher; import javax.crypto.KeyGenerator; import javax.crypto.spec.IvParameterSpec; import org.bouncycastle.jce.provider.BouncyCastleProvider; import org.bouncycastle.util.test.SimpleTest; public class SlotTwoTest extends SimpleTest { byte[] plainData = "abcdefghijklmnopqrstuvwxyz".getBytes(); public String getName() { return "SlotTwo"; } public void performTest() throws Exception { Security.removeProvider("BC"); Security.insertProviderAt(new BouncyCastleProvider(), 2); KeyGenerator keyGen = KeyGenerator.getInstance("DESede", "BC"); keyGen.init(new SecureRandom()); Key key = keyGen.generateKey(); testDesEde(key, "ECB", "PKCS7Padding"); testDesEde(key, "CBC", "PKCS7Padding"); testDesEde(key, "CTR", "NoPadding"); testDesEde(key, "CTR", "PKCS7Padding"); testDesEde(key, "OFB", "PKCS7Padding"); testDesEde(key, "CFB", "PKCS7Padding"); Security.removeProvider("BC"); Security.addProvider(new BouncyCastleProvider()); } private void testDesEde( Key key, String mode, String padding) throws Exception { Cipher encrypt = Cipher.getInstance("DESede/" + mode + "/" + padding, "BC"); Cipher decrypt = Cipher.getInstance("DESede/" + mode + "/" + padding); if (!decrypt.getProvider().getName().equals("BC")) { fail("BC provider not returned for DESede/" + mode + "/" + padding + " got " + decrypt.getProvider().getName()); } encrypt.init(Cipher.ENCRYPT_MODE, key); byte[] encryptedBytes = encrypt.doFinal(plainData); byte[] ivBytes = encrypt.getIV(); if (ivBytes != null) { IvParameterSpec ivp = new IvParameterSpec(ivBytes); decrypt.init(Cipher.DECRYPT_MODE, key, ivp); } else { decrypt.init(Cipher.DECRYPT_MODE, key); } byte[] plainBytes = decrypt.doFinal(encryptedBytes, 0, encryptedBytes.length); if (!areEqual(plainData, plainBytes)) { fail("decryption test failed."); } } public static void main( String[] args) { runTest(new SlotTwoTest()); } } bouncycastle-1.49.orig/test/src/org/bouncycastle/jce/provider/test/CertPathValidatorTest.java0000644000175000017500000004561111321523421032117 0ustar ebourgebourgpackage org.bouncycastle.jce.provider.test; import java.io.ByteArrayInputStream; import java.security.PublicKey; import java.security.Security; import java.security.cert.CertPath; import java.security.cert.CertPathValidator; import java.security.cert.CertPathValidatorException; import java.security.cert.CertStore; import java.security.cert.CertStoreParameters; import java.security.cert.Certificate; import java.security.cert.CertificateFactory; import java.security.cert.CollectionCertStoreParameters; import java.security.cert.PKIXBuilderParameters; import java.security.cert.PKIXCertPathChecker; import java.security.cert.PKIXCertPathValidatorResult; import java.security.cert.PKIXParameters; import java.security.cert.PolicyNode; import java.security.cert.TrustAnchor; import java.security.cert.X509CRL; import java.security.cert.X509CertSelector; import java.security.cert.X509Certificate; import java.util.ArrayList; import java.util.Calendar; import java.util.Collection; import java.util.HashSet; import java.util.List; import java.util.Set; import org.bouncycastle.jce.provider.BouncyCastleProvider; import org.bouncycastle.util.encoders.Base64; import org.bouncycastle.util.test.SimpleTest; public class CertPathValidatorTest extends SimpleTest { private byte[] AC_PR = Base64.decode( "LS0tLS1CRUdJTiBDRVJUSUZJQ0FURS0tLS0tDQpNSUlFU1RDQ0F6R2dBd0lC" + "QWdJQkJUQU5CZ2txaGtpRzl3MEJBUVVGQURDQnRERUxNQWtHQTFVRUJoTUNR" + "bEl4DQpFekFSQmdOVkJBb1RDa2xEVUMxQ2NtRnphV3d4UFRBN0JnTlZCQXNU" + "TkVsdWMzUnBkSFYwYnlCT1lXTnBiMjVoDQpiQ0JrWlNCVVpXTnViMnh2WjJs" + "aElHUmhJRWx1Wm05eWJXRmpZVzhnTFNCSlZFa3hFVEFQQmdOVkJBY1RDRUp5" + "DQpZWE5wYkdsaE1Rc3dDUVlEVlFRSUV3SkVSakV4TUM4R0ExVUVBeE1vUVhW" + "MGIzSnBaR0ZrWlNCRFpYSjBhV1pwDQpZMkZrYjNKaElGSmhhWG9nUW5KaGMy" + "bHNaV2x5WVRBZUZ3MHdNakEwTURReE9UTTVNREJhRncwd05UQTBNRFF5DQpN" + "elU1TURCYU1HRXhDekFKQmdOVkJBWVRBa0pTTVJNd0VRWURWUVFLRXdwSlEx" + "QXRRbkpoYzJsc01UMHdPd1lEDQpWUVFERXpSQmRYUnZjbWxrWVdSbElFTmxj" + "blJwWm1sallXUnZjbUVnWkdFZ1VISmxjMmxrWlc1amFXRWdaR0VnDQpVbVZ3" + "ZFdKc2FXTmhNSUlCSWpBTkJna3Foa2lHOXcwQkFRRUZBQU9DQVE4QU1JSUJD" + "Z0tDQVFFQXMwc0t5NGsrDQp6b016aldyMTQxeTVYQ045UGJMZERFQXN2cjZ4" + "Z0NCN1l5bEhIQ1NBYmpGR3dOQ0R5NlVxN1h0VjZ6UHdIMXpGDQpFWENlS3Jm" + "UUl5YXBXSEZ4V1VKajBMblFrY1RZM1FOR1huK0JuVk9EVTZDV3M1c3NoZktH" + "RXZyVlQ1Z214V1NmDQp4OFlsdDgzY1dwUE1QZzg3VDlCaHVIbHQzazh2M2Ev" + "NmRPbmF2dytOYTAyZExBaDBlNzZqcCtQUS9LK0pHZlBuDQphQjVVWURrZkd0" + "em5uTTNBV01tY3VJK0o0ek5OMDZaa3ZnbDFsdEo2UU1qcnZEUFlSak9ndDlT" + "cklpY1NmbEo4DQptVDdHWGRRaXJnQUNXc3g1QURBSklRK253TU1vNHlyTUtx" + "SlFhNFFDMHhhT0QvdkdVcG9SaDQzT0FTZFp3c3YvDQpPWFlybmVJeVAwVCs4" + "UUlEQVFBQm80RzNNSUcwTUQwR0ExVWRId1EyTURRd01xQXdvQzZHTEdoMGRI" + "QTZMeTloDQpZM0poYVhvdWFXTndZbkpoYzJsc0xtZHZkaTVpY2k5TVExSmhZ" + "M0poYVhvdVkzSnNNQklHQTFVZElBUUxNQWt3DQpCd1lGWUV3QkFRRXdIUVlE" + "VlIwT0JCWUVGREpUVFlKNE9TWVB5T09KZkVMZXhDaHppK2hiTUI4R0ExVWRJ" + "d1FZDQpNQmFBRklyNjhWZUVFUk0xa0VMNlYwbFVhUTJreFBBM01BNEdBMVVk" + "RHdFQi93UUVBd0lCQmpBUEJnTlZIUk1CDQpBZjhFQlRBREFRSC9NQTBHQ1Nx" + "R1NJYjNEUUVCQlFVQUE0SUJBUUJRUFNoZ1lidnFjaWV2SDVVb3ZMeXhkbkYr" + "DQpFcjlOeXF1SWNkMnZ3Y0N1SnpKMkQ3WDBUcWhHQ0JmUEpVVkdBVWorS0NP" + "SDFCVkgva1l1OUhsVHB1MGtKWFBwDQpBQlZkb2hJUERqRHhkbjhXcFFSL0Yr" + "ejFDaWtVcldIMDR4eTd1N1p6UUpLSlBuR0loY1FpOElyRm1PYkllMEc3DQpY" + "WTZPTjdPRUZxY21KTFFHWWdtRzFXMklXcytQd1JwWTdENGhLVEFoVjFSNkVv" + "amE1L3BPcmVDL09kZXlQWmVxDQo1SUZTOUZZZk02U0Npd2hrK3l2Q1FHbVo0" + "YzE5SjM0ZjVFYkRrK1NQR2tEK25EQ0E3L3VMUWNUMlJURE14SzBaDQpuZlo2" + "Nm1Sc0ZjcXRGaWdScjVFcmtKZDdoUVV6eHNOV0VrNzJEVUFIcVgvNlNjeWtt" + "SkR2V0plSUpqZlcNCi0tLS0tRU5EIENFUlRJRklDQVRFLS0tLS0NCg=="); private byte[] AC_RAIZ_ICPBRASIL = Base64.decode( "LS0tLS1CRUdJTiBDRVJUSUZJQ0FURS0tLS0tDQpNSUlFdURDQ0E2Q2dBd0lC" + "QWdJQkJEQU5CZ2txaGtpRzl3MEJBUVVGQURDQnRERUxNQWtHQTFVRUJoTUNR" + "bEl4DQpFekFSQmdOVkJBb1RDa2xEVUMxQ2NtRnphV3d4UFRBN0JnTlZCQXNU" + "TkVsdWMzUnBkSFYwYnlCT1lXTnBiMjVoDQpiQ0JrWlNCVVpXTnViMnh2WjJs" + "aElHUmhJRWx1Wm05eWJXRmpZVzhnTFNCSlZFa3hFVEFQQmdOVkJBY1RDRUp5" + "DQpZWE5wYkdsaE1Rc3dDUVlEVlFRSUV3SkVSakV4TUM4R0ExVUVBeE1vUVhW" + "MGIzSnBaR0ZrWlNCRFpYSjBhV1pwDQpZMkZrYjNKaElGSmhhWG9nUW5KaGMy" + "bHNaV2x5WVRBZUZ3MHdNVEV4TXpBeE1qVTRNREJhRncweE1URXhNekF5DQpN" + "elU1TURCYU1JRzBNUXN3Q1FZRFZRUUdFd0pDVWpFVE1CRUdBMVVFQ2hNS1NV" + "TlFMVUp5WVhOcGJERTlNRHNHDQpBMVVFQ3hNMFNXNXpkR2wwZFhSdklFNWhZ" + "Mmx2Ym1Gc0lHUmxJRlJsWTI1dmJHOW5hV0VnWkdFZ1NXNW1iM0p0DQpZV05o" + "YnlBdElFbFVTVEVSTUE4R0ExVUVCeE1JUW5KaGMybHNhV0V4Q3pBSkJnTlZC" + "QWdUQWtSR01URXdMd1lEDQpWUVFERXloQmRYUnZjbWxrWVdSbElFTmxjblJw" + "Wm1sallXUnZjbUVnVW1GcGVpQkNjbUZ6YVd4bGFYSmhNSUlCDQpJakFOQmdr" + "cWhraUc5dzBCQVFFRkFBT0NBUThBTUlJQkNnS0NBUUVBd1BNdWR3WC9odm0r" + "VWgyYi9sUUFjSFZBDQppc2FtYUxrV2Rrd1A5L1MvdE9LSWdSckw2T3krWklH" + "bE9VZGQ2dVl0azlNYS8zcFVwZ2NmTkFqMHZZbTVnc3lqDQpRbzllbXNjK3g2" + "bTRWV3drOWlxTVpTQ0s1RVFrQXEvVXQ0bjdLdUxFMStnZGZ0d2RJZ3hmVXNQ" + "dDRDeU5yWTUwDQpRVjU3S00yVVQ4eDVycm16RWpyN1RJQ0dwU1VBbDJnVnFl" + "NnhhaWkrYm1ZUjFRcm1XYUJTQUc1OUxya3Jqcll0DQpiUmhGYm9VRGUxREsr" + "NlQ4czVMNms4Yzhva3BiSHBhOXZlTXp0RFZDOXNQSjYwTVdYaDZhblZLbzFV" + "Y0xjYlVSDQp5RWVOdlpuZVZSS0FBVTZvdXdkakR2d2xzYUt5ZEZLd2VkMFRv" + "UTQ3Ym1VS2djbSt3VjNlVFJrMzZVT25Ud0lEDQpBUUFCbzRIU01JSFBNRTRH" + "QTFVZElBUkhNRVV3UXdZRllFd0JBUUF3T2pBNEJnZ3JCZ0VGQlFjQ0FSWXNh" + "SFIwDQpjRG92TDJGamNtRnBlaTVwWTNCaWNtRnphV3d1WjI5MkxtSnlMMFJR" + "UTJGamNtRnBlaTV3WkdZd1BRWURWUjBmDQpCRFl3TkRBeW9EQ2dMb1lzYUhS" + "MGNEb3ZMMkZqY21GcGVpNXBZM0JpY21GemFXd3VaMjkyTG1KeUwweERVbUZq" + "DQpjbUZwZWk1amNtd3dIUVlEVlIwT0JCWUVGSXI2OFZlRUVSTTFrRUw2VjBs" + "VWFRMmt4UEEzTUE4R0ExVWRFd0VCDQovd1FGTUFNQkFmOHdEZ1lEVlIwUEFR" + "SC9CQVFEQWdFR01BMEdDU3FHU0liM0RRRUJCUVVBQTRJQkFRQVpBNWMxDQpV" + "L2hnSWg2T2NnTEFmaUpnRldwdm1EWldxbFYzMC9iSEZwajhpQm9iSlNtNXVE" + "cHQ3VGlyWWgxVXhlM2ZRYUdsDQpZakplKzl6ZCtpelBSYkJxWFBWUUEzNEVY" + "Y3drNHFwV3VmMWhIcmlXZmRyeDhBY3FTcXI2Q3VRRndTcjc1Rm9zDQpTemx3" + "REFEYTcwbVQ3d1pqQW1RaG5aeDJ4SjZ3ZldsVDlWUWZTLy9KWWVJYzdGdWUy" + "Sk5MZDAwVU9TTU1haUsvDQp0NzllbktOSEVBMmZ1cEgzdkVpZ2Y1RWg0YlZB" + "TjVWb2hyVG02TVk1M3g3WFFaWnIxTUU3YTU1bEZFblNlVDB1DQptbE9BalIy" + "bUFidlNNNVg1b1NaTnJtZXRkenlUajJmbENNOENDN01MYWIwa2tkbmdSSWxV" + "QkdIRjEvUzVubVBiDQpLKzlBNDZzZDMzb3FLOG44DQotLS0tLUVORCBDRVJU" + "SUZJQ0FURS0tLS0tDQo="); private byte[] schefer = Base64.decode( "MIIEnDCCBAWgAwIBAgICIPAwDQYJKoZIhvcNAQEEBQAwgcAxCzAJBgNVBAYT" + "AkRFMQ8wDQYDVQQIEwZIRVNTRU4xGDAWBgNVBAcTDzY1MDA4IFdpZXNiYWRl" + "bjEaMBgGA1UEChMRU0NIVUZBIEhPTERJTkcgQUcxGjAYBgNVBAsTEVNDSFVG" + "QSBIT0xESU5HIEFHMSIwIAYDVQQDExlJbnRlcm5ldCBCZW51dHplciBTZXJ2" + "aWNlMSowKAYJKoZIhvcNAQkBFht6ZXJ0aWZpa2F0QHNjaHVmYS1vbmxpbmUu" + "ZGUwHhcNMDQwMzMwMTEwODAzWhcNMDUwMzMwMTEwODAzWjCBnTELMAkGA1UE" + "BhMCREUxCjAIBgNVBAcTASAxIzAhBgNVBAoTGlNIUyBJbmZvcm1hdGlvbnNz" + "eXN0ZW1lIEFHMRwwGgYDVQQLExM2MDAvMDU5NDktNjAwLzA1OTQ5MRgwFgYD" + "VQQDEw9TY2hldHRlciBTdGVmYW4xJTAjBgkqhkiG9w0BCQEWFlN0ZWZhbi5T" + "Y2hldHRlckBzaHMuZGUwgZ8wDQYJKoZIhvcNAQEBBQADgY0AMIGJAoGBAJD0" + "95Bi76fkAMjJNTGPDiLPHmZXNsmakngDeS0juzKMeJA+TjXFouhYh6QyE4Bl" + "Nf18fT4mInlgLefwf4t6meIWbiseeTo7VQdM+YrbXERMx2uHsRcgZMsiMYHM" + "kVfYMK3SMJ4nhCmZxrBkoTRed4gXzVA1AA8YjjTqMyyjvt4TAgMBAAGjggHE" + "MIIBwDAJBgNVHRMEAjAAMBEGCWCGSAGG+EIBAQQEAwIEsDALBgNVHQ8EBAMC" + "BNAwOQYJYIZIAYb4QgENBCwWKlplcnRpZmlrYXQgbnVyIGZ1ZXIgU0NIVUZB" + "LU9ubGluZSBndWVsdGlnLjAdBgNVHQ4EFgQUXReirhBfg0Yhf6MsBWoo/nPa" + "hGwwge0GA1UdIwSB5TCB4oAUf2UyCaBV9JUeG9lS1Yo6OFBUdEKhgcakgcMw" + "gcAxCzAJBgNVBAYTAkRFMQ8wDQYDVQQIEwZIRVNTRU4xGDAWBgNVBAcTDzY1" + "MDA4IFdpZXNiYWRlbjEaMBgGA1UEChMRU0NIVUZBIEhPTERJTkcgQUcxGjAY" + "BgNVBAsTEVNDSFVGQSBIT0xESU5HIEFHMSIwIAYDVQQDExlJbnRlcm5ldCBC" + "ZW51dHplciBTZXJ2aWNlMSowKAYJKoZIhvcNAQkBFht6ZXJ0aWZpa2F0QHNj" + "aHVmYS1vbmxpbmUuZGWCAQAwIQYDVR0RBBowGIEWU3RlZmFuLlNjaGV0dGVy" + "QHNocy5kZTAmBgNVHRIEHzAdgRt6ZXJ0aWZpa2F0QHNjaHVmYS1vbmxpbmUu" + "ZGUwDQYJKoZIhvcNAQEEBQADgYEAWzZtN9XQ9uyrFXqSy3hViYwV751+XZr0" + "YH5IFhIS+9ixNAu8orP3bxqTaMhpwoU7T/oSsyGGSkb3fhzclgUADbA2lrOI" + "GkeB/m+FArTwRbwpqhCNTwZywOp0eDosgPjCX1t53BB/m/2EYkRiYdDGsot0" + "kQPOVGSjQSQ4+/D+TM8="); // circular dependency certificates private static final byte[] circCA = Base64.decode( "MIIDTzCCAjegAwIBAgIDARAAMA0GCSqGSIb3DQEBBQUAMDkxCzAJBgNVBAYT" + "AkZSMRAwDgYDVQQKEwdHSVAtQ1BTMRgwFgYDVQQLEw9HSVAtQ1BTIEFOT05Z" + "TUUwHhcNMDQxMDExMDAwMDAxWhcNMTQxMjMxMjM1OTU5WjA5MQswCQYDVQQG" + "EwJGUjEQMA4GA1UEChMHR0lQLUNQUzEYMBYGA1UECxMPR0lQLUNQUyBBTk9O" + "WU1FMIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEA3WyWDwcM58aU" + "hPX4ueI1mwETt3WdQtMfIdRiCXeBrjCkYCc7nIgCmGbnfTzXSplHRgKColWh" + "q/Z+1rHYayje1gjAEU2+4/r1P2pnBmPgquDuguktCIbDtCcGZu0ylyKeHh37" + "aeIKzkcmRSLRzvGf/eO3RdFksrvaPaSjqCVfGRXVDKK2uftE8rIFJE+bCqow" + "6+WiaAaDDiJaSJPuu5hC1NA5jw0/BFodlCuAvl1GJ8A+TICkYWcSpKS9bkSC" + "0i8xdGbSSk94shA1PdDvRdFMfFys8g4aupBXV8yqqEAUkBYmOtZSJckc3W4y" + "2Gx53y7vY07Xh63mcgtJs2T82WJICwIDAQABo2AwXjAdBgNVHQ4EFgQU8c/P" + "NNJaL0srd9SwHwgtvwPB/3cwDgYDVR0PAQH/BAQDAgIEMBkGA1UdIAQSMBAw" + "DgYMKoF6AUcDBwgAAAABMBIGA1UdEwEB/wQIMAYBAf8CAQEwDQYJKoZIhvcN" + "AQEFBQADggEBAHRjYDPJKlfUzID0YzajZpgR/i2ngJrJqYeaWCmwzBgNUPad" + "uBKSGHmPVg21sfULMSnirnR+e90i/D0EVzLwQzcbjPDD/85rp9QDCeMxqqPe" + "9ZCHGs2BpE/HOQMP0QfQ3/Kpk7SvOH/ZcpIf6+uE6lLBQYAGs5cxvtTGOzZk" + "jCVFG+TrAnF4V5sNkn3maCWiYLmyqcnxtKEFSONy2bYqqudx/dBBlRrDbRfZ" + "9XsCBdiXAHY1hFHldbfDs8rslmkXJi3fJC028HZYB6oiBX/JE7BbMk7bRnUf" + "HSpP7Sjxeso2SY7Yit+hQDVAlqTDGmh6kLt/hQMpsOMry4vgBL6XHKw="); private static final byte[] circCRLCA = Base64.decode( "MIIDXDCCAkSgAwIBAgIDASAAMA0GCSqGSIb3DQEBBQUAMDkxCzAJBgNVBAYT" + "AkZSMRAwDgYDVQQKEwdHSVAtQ1BTMRgwFgYDVQQLEw9HSVAtQ1BTIEFOT05Z" + "TUUwHhcNMDQxMDExMDAwMDAxWhcNMTQxMjMxMjM1OTU5WjA5MQswCQYDVQQG" + "EwJGUjEQMA4GA1UEChMHR0lQLUNQUzEYMBYGA1UECxMPR0lQLUNQUyBBTk9O" + "WU1FMIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEAwfEcFK0g7Kfo" + "o5f2IBF7VEd/AG+RVGSds0Yg+u2kNYu4k04HR/+tOdBQtJvyr4W5jrQKsC5X" + "skeFWMyWaFKzAjZDWB52HWp/kiMivGcxnYDuYf5piukSC+d2+vL8YaAphDzV" + "HPnxEKqoM/J66uUussDTqfcL3JC/Bc7kBwn4srrsZOsamMWTQQtEqVQxNN7A" + "ROSRsdiTt3hMOKditc9/NBNmjZWxgc7Twr/SaZ8CfN5wf2wuOl23knWL0QsJ" + "0lSMBSBTzTcfAke4/jIT7d4nVMp3t7dsna8rt56pFK4wpRFGuCt+1P5gi51x" + "xVSdI+JoNXv6zGO4o8YVaRpC5rQeGQIDAQABo20wazAfBgNVHSMEGDAWgBTx" + "z8800lovSyt31LAfCC2/A8H/dzAdBgNVHQ4EFgQUGa3SbBrJx/wa2MQwhWPl" + "dwLw1+IwDgYDVR0PAQH/BAQDAgECMBkGA1UdIAQSMBAwDgYMKoF6AUcDBwgA" + "AAABMA0GCSqGSIb3DQEBBQUAA4IBAQAPDpYe2WPYnXTLsXSIUREBNMLmg+/7" + "4Yhq9uOm5Hb5LVkDuHoEHGfmpXXEvucx5Ehu69hw+F4YSrd9wPjOiG8G6GXi" + "RcrK8nE8XDvvV+E1HpJ7NKN4fSAoSb+0gliiq3aF15bvXP8nfespdd/x1xWQ" + "mpYCx/mJeuqONQv2/D/7hfRKYoDBaAkWGodenPFPVs6FxwnEuH2R+KWCUdA9" + "L04v8JBeL3kZiALkU7+DCCm7A0imUAgeeArbAbfIPu6eDygm+XndZ9qi7o4O" + "AntPxrqbeXFIbDrQ4GV1kpxnW+XpSGDd96SWKe715gxkkDBppR5IKYJwRb6O" + "1TRQIf2F+muQ"); private static final byte[] circCRL = Base64.decode( "MIIB1DCBvQIBATANBgkqhkiG9w0BAQUFADA5MQswCQYDVQQGEwJGUjEQMA4G" + "A1UEChMHR0lQLUNQUzEYMBYGA1UECxMPR0lQLUNQUyBBTk9OWU1FFw0xMDAx" + "MDcwMzAwMTVaFw0xMDAxMTMwMzAwMTVaMACgTjBMMB8GA1UdIwQYMBaAFBmt" + "0mwaycf8GtjEMIVj5XcC8NfiMAsGA1UdFAQEAgILgzAcBgNVHRIEFTATgRFh" + "Yy1naXBAZ2lwLWNwcy5mcjANBgkqhkiG9w0BAQUFAAOCAQEAtF1DdFl1MQvf" + "vNkbrCPuppNYcHen4+za/ZDepKuwHsH/OpKuaDJc4LndRgd5IwzfpCHkQGzt" + "shK50bakN8oaYJgthKIOIJzR+fn6NMjftfR2a27Hdk2o3eQXRHQ360qMbpSy" + "qPb3WfuBhxO2/DlLChJP+OxZIHtT/rNYgE0tlIv7swYi81Gq+DafzaZ9+A5t" + "I0L2Gp/NUDsp5dF6PllAGiXQzl27qkcu+r50w+u0gul3nobXgbwPcMSYuWUz" + "1lhA+uDn/EUWV4RSiJciCGSS10WCkFh1/YPo++mV15KDB0m+8chscrSu/bAl" + "B19LxL/pCX3qr5iLE9ss3olVImyFZg=="); private void checkCircProcessing() throws Exception { CertificateFactory cf = CertificateFactory.getInstance("X.509", "BC"); X509Certificate caCert = (X509Certificate)cf.generateCertificate(new ByteArrayInputStream(circCA)); X509Certificate crlCaCert = (X509Certificate)cf.generateCertificate(new ByteArrayInputStream(circCRLCA)); X509CRL crl = (X509CRL)cf.generateCRL(new ByteArrayInputStream(circCRL)); List list = new ArrayList(); list.add(caCert); list.add(crlCaCert); list.add(crl); CertStoreParameters ccsp = new CollectionCertStoreParameters(list); CertStore store = CertStore.getInstance("Collection", ccsp); Calendar validDate = Calendar.getInstance(); validDate.set(2010,0,8,2,21,10); //validating path List certchain = new ArrayList(); certchain.add(crlCaCert); CertPath cp = CertificateFactory.getInstance("X.509","BC").generateCertPath(certchain); Set trust = new HashSet(); trust.add(new TrustAnchor(caCert, null)); CertPathValidator cpv = CertPathValidator.getInstance("PKIX","BC"); //PKIXParameters param = new PKIXParameters(trust); PKIXBuilderParameters param = new PKIXBuilderParameters(trust, null); X509CertSelector certSelector = new X509CertSelector(); certSelector.setCertificate(crlCaCert); param.setTargetCertConstraints(certSelector); param.addCertStore(store); param.setRevocationEnabled(true); param.setDate(validDate.getTime()); PKIXCertPathValidatorResult result = (PKIXCertPathValidatorResult)cpv.validate(cp, param); } public void performTest() throws Exception { CertificateFactory cf = CertificateFactory.getInstance("X.509", "BC"); // initialise CertStore X509Certificate rootCert = (X509Certificate)cf.generateCertificate(new ByteArrayInputStream(CertPathTest.rootCertBin)); X509Certificate interCert = (X509Certificate)cf.generateCertificate(new ByteArrayInputStream(CertPathTest.interCertBin)); X509Certificate finalCert = (X509Certificate)cf.generateCertificate(new ByteArrayInputStream(CertPathTest.finalCertBin)); X509CRL rootCrl = (X509CRL)cf.generateCRL(new ByteArrayInputStream(CertPathTest.rootCrlBin)); X509CRL interCrl = (X509CRL)cf.generateCRL(new ByteArrayInputStream(CertPathTest.interCrlBin)); List list = new ArrayList(); list.add(rootCert); list.add(interCert); list.add(finalCert); list.add(rootCrl); list.add(interCrl); CollectionCertStoreParameters ccsp = new CollectionCertStoreParameters(list); CertStore store = CertStore.getInstance("Collection", ccsp, "BC"); Calendar validDate = Calendar.getInstance(); validDate.set(2008,8,4,14,49,10); //validating path List certchain = new ArrayList(); certchain.add(finalCert); certchain.add(interCert); CertPath cp = CertificateFactory.getInstance("X.509","BC").generateCertPath(certchain); Set trust = new HashSet(); trust.add(new TrustAnchor(rootCert, null)); CertPathValidator cpv = CertPathValidator.getInstance("PKIX","BC"); PKIXParameters param = new PKIXParameters(trust); param.addCertStore(store); param.setDate(validDate.getTime()); MyChecker checker = new MyChecker(); param.addCertPathChecker(checker); PKIXCertPathValidatorResult result = (PKIXCertPathValidatorResult) cpv.validate(cp, param); PolicyNode policyTree = result.getPolicyTree(); PublicKey subjectPublicKey = result.getPublicKey(); if (checker.getCount() != 2) { fail("checker not evaluated for each certificate"); } if (!subjectPublicKey.equals(finalCert.getPublicKey())) { fail("wrong public key returned"); } // // invalid path containing a valid one test // try { // initialise CertStore rootCert = (X509Certificate)cf.generateCertificate(new ByteArrayInputStream(AC_RAIZ_ICPBRASIL)); interCert = (X509Certificate)cf.generateCertificate(new ByteArrayInputStream(AC_PR)); finalCert = (X509Certificate)cf.generateCertificate(new ByteArrayInputStream(schefer)); list = new ArrayList(); list.add(rootCert); list.add(interCert); list.add(finalCert); ccsp = new CollectionCertStoreParameters(list); store = CertStore.getInstance("Collection", ccsp); validDate = Calendar.getInstance(); validDate.set(2004,2,21,2,21,10); //validating path certchain = new ArrayList(); certchain.add(finalCert); certchain.add(interCert); cp = CertificateFactory.getInstance("X.509","BC").generateCertPath(certchain); trust = new HashSet(); trust.add(new TrustAnchor(rootCert, null)); cpv = CertPathValidator.getInstance("PKIX","BC"); param = new PKIXParameters(trust); param.addCertStore(store); param.setRevocationEnabled(false); param.setDate(validDate.getTime()); result =(PKIXCertPathValidatorResult) cpv.validate(cp, param); policyTree = result.getPolicyTree(); subjectPublicKey = result.getPublicKey(); fail("Invalid path validated"); } catch (Exception e) { if (!(e instanceof CertPathValidatorException && e.getMessage().startsWith("Could not validate certificate signature."))) { fail("unexpected exception", e); } } checkCircProcessing(); } public String getName() { return "CertPathValidator"; } public static void main( String[] args) { Security.addProvider(new BouncyCastleProvider()); runTest(new CertPathValidatorTest()); } private static class MyChecker extends PKIXCertPathChecker { private static int count; public void init(boolean forward) throws CertPathValidatorException { //To change body of implemented methods use File | Settings | File Templates. } public boolean isForwardCheckingSupported() { return true; } public Set getSupportedExtensions() { return null; } public void check(Certificate cert, Collection unresolvedCritExts) throws CertPathValidatorException { count++; } public int getCount() { return count; } } } bouncycastle-1.49.orig/test/src/org/bouncycastle/jce/provider/test/nist/0000755000175000017500000000000012152033550026004 5ustar ebourgebourg././@LongLink0000000000000000000000000000014600000000000011566 Lustar rootrootbouncycastle-1.49.orig/test/src/org/bouncycastle/jce/provider/test/nist/NistCertPathReviewerTest.javabouncycastle-1.49.orig/test/src/org/bouncycastle/jce/provider/test/nist/NistCertPathReviewerTest.jav0000644000175000017500000006600411723556416033453 0ustar ebourgebourgpackage org.bouncycastle.jce.provider.test.nist; import java.io.FileInputStream; import java.io.InputStream; import java.security.Security; import java.security.cert.CertPath; import java.security.cert.CertStore; import java.security.cert.CertificateFactory; import java.security.cert.CollectionCertStoreParameters; import java.security.cert.PKIXParameters; import java.security.cert.TrustAnchor; import java.security.cert.X509CRL; import java.security.cert.X509Certificate; import java.util.ArrayList; import java.util.Arrays; import java.util.Collections; import java.util.GregorianCalendar; import java.util.HashMap; import java.util.HashSet; import java.util.List; import java.util.Locale; import java.util.Map; import java.util.Set; import java.util.TimeZone; import junit.framework.Test; import junit.framework.TestCase; import junit.framework.TestSuite; import org.bouncycastle.asn1.ASN1Encoding; import org.bouncycastle.asn1.ASN1Primitive; import org.bouncycastle.asn1.x509.X509Extension; import org.bouncycastle.i18n.ErrorBundle; import org.bouncycastle.x509.PKIXCertPathReviewer; import org.bouncycastle.x509.extension.X509ExtensionUtil; /** * NIST CertPath test data for RFC 3280 */ public class NistCertPathReviewerTest extends TestCase { private static final String TEST_DATA_HOME = "bc.test.data.home"; private static final String GOOD_CA_CERT = "GoodCACert"; private static final String GOOD_CA_CRL = "GoodCACRL"; private static final String TRUST_ANCHOR_ROOT_CRL = "TrustAnchorRootCRL"; private static final String TRUST_ANCHOR_ROOT_CERTIFICATE = "TrustAnchorRootCertificate"; private static final char[] PKCS12_PASSWORD = "password".toCharArray(); private static String NIST_TEST_POLICY_1 = "2.16.840.1.101.3.2.1.48.1"; private static String NIST_TEST_POLICY_2 = "2.16.840.1.101.3.2.1.48.2"; private static String NIST_TEST_POLICY_3 = "2.16.840.1.101.3.2.1.48.3"; private static Map certs = new HashMap(); private static Map crls = new HashMap(); private static Set noPolicies = Collections.EMPTY_SET; private static Set nistTestPolicy1 = Collections.singleton(NIST_TEST_POLICY_1); private static Set nistTestPolicy2 = Collections.singleton(NIST_TEST_POLICY_2); private static Set nistTestPolicy3 = Collections.singleton(NIST_TEST_POLICY_3); private static Set nistTestPolicy1And2 = new HashSet(Arrays.asList(new String[] { NIST_TEST_POLICY_1, NIST_TEST_POLICY_2 })); public void testValidSignaturesTest1() throws Exception { doAcceptingTest(TRUST_ANCHOR_ROOT_CERTIFICATE, new String[] { "ValidCertificatePathTest1EE", GOOD_CA_CERT}, new String[] { GOOD_CA_CRL, TRUST_ANCHOR_ROOT_CRL }); } public void testInvalidCASignatureTest2() throws Exception { doErrorTest(TRUST_ANCHOR_ROOT_CERTIFICATE, new String[] { "ValidCertificatePathTest1EE", "BadSignedCACert" }, new String[] { "BadSignedCACRL", TRUST_ANCHOR_ROOT_CRL}, 1, "CertPathReviewer.signatureNotVerified", "The certificate signature is invalid. A java.security.SignatureException occurred."); } public void testInvalidEESignatureTest3() throws Exception { doErrorTest(TRUST_ANCHOR_ROOT_CERTIFICATE, new String[] { GOOD_CA_CERT, "InvalidEESignatureTest3EE" }, new String[] { TRUST_ANCHOR_ROOT_CRL, GOOD_CA_CRL }, 0, "CertPathReviewer.signatureNotVerified", "The certificate signature is invalid. A java.security.SignatureException occurred."); } public void testValidDSASignaturesTest4() throws Exception { doAcceptingTest(TRUST_ANCHOR_ROOT_CERTIFICATE, new String[] { "DSACACert", "ValidDSASignaturesTest4EE" }, new String[] { TRUST_ANCHOR_ROOT_CRL, "DSACACRL" }); } /* public void testValidDSAParameterInheritanceTest5() throws Exception { doTest(TRUST_ANCHOR_ROOT_CERTIFICATE, new String[] { "DSACACert", "DSAParametersInheritedCACert", "ValidDSAParameterInheritanceTest5EE" }, new String[] { TRUST_ANCHOR_ROOT_CRL, "DSACACRL", "DSAParametersInheritedCACRL" }); } */ public void testInvalidDSASignaturesTest6() throws Exception { doErrorTest(TRUST_ANCHOR_ROOT_CERTIFICATE, new String[] { "DSACACert", "InvalidDSASignatureTest6EE" }, new String[] { TRUST_ANCHOR_ROOT_CRL, "DSACACRL" }, 0, "CertPathReviewer.signatureNotVerified", "The certificate signature is invalid. A java.security.SignatureException occurred."); } public void testCANotBeforeDateTest1() throws Exception { doErrorTest(TRUST_ANCHOR_ROOT_CERTIFICATE, new String[] { "BadnotBeforeDateCACert", "InvalidCAnotBeforeDateTest1EE" }, new String[] { TRUST_ANCHOR_ROOT_CRL, "BadnotBeforeDateCACRL" }, 1, "CertPathReviewer.certificateNotYetValid", "Could not validate the certificate. Certificate is not valid until Jan 1, 2047 12:01:00 PM GMT."); } public void testInvalidEENotBeforeDateTest2() throws Exception { doErrorTest(TRUST_ANCHOR_ROOT_CERTIFICATE, new String[] { GOOD_CA_CERT, "InvalidEEnotBeforeDateTest2EE" }, new String[] { TRUST_ANCHOR_ROOT_CRL, GOOD_CA_CRL }, 0, "CertPathReviewer.certificateNotYetValid", "Could not validate the certificate. Certificate is not valid until Jan 1, 2047 12:01:00 PM GMT."); } public void testValidPre2000UTCNotBeforeDateTest3() throws Exception { doAcceptingTest(TRUST_ANCHOR_ROOT_CERTIFICATE, new String[] { GOOD_CA_CERT, "Validpre2000UTCnotBeforeDateTest3EE" }, new String[] { TRUST_ANCHOR_ROOT_CRL, GOOD_CA_CRL }); } public void testValidGeneralizedTimeNotBeforeDateTest4() throws Exception { doAcceptingTest(TRUST_ANCHOR_ROOT_CERTIFICATE, new String[] { GOOD_CA_CERT, "ValidGeneralizedTimenotBeforeDateTest4EE" }, new String[] { TRUST_ANCHOR_ROOT_CRL, GOOD_CA_CRL }); } public void testInvalidCANotAfterDateTest5() throws Exception { doErrorTest(TRUST_ANCHOR_ROOT_CERTIFICATE, new String[] { "BadnotAfterDateCACert", "InvalidCAnotAfterDateTest5EE" }, new String[] { TRUST_ANCHOR_ROOT_CRL, "BadnotAfterDateCACRL" }, 1, "CertPathReviewer.certificateExpired", "Could not validate the certificate. Certificate expired on Jan 1, 2002 12:01:00 PM GMT."); } public void testInvalidEENotAfterDateTest6() throws Exception { doErrorTest(TRUST_ANCHOR_ROOT_CERTIFICATE, new String[] { GOOD_CA_CERT, "InvalidEEnotAfterDateTest6EE" }, new String[] { TRUST_ANCHOR_ROOT_CRL, GOOD_CA_CRL }, 0, "CertPathReviewer.certificateExpired", "Could not validate the certificate. Certificate expired on Jan 1, 2002 12:01:00 PM GMT."); } public void testInvalidValidPre2000UTCNotAfterDateTest7() throws Exception { doErrorTest(TRUST_ANCHOR_ROOT_CERTIFICATE, new String[] { GOOD_CA_CERT, "Invalidpre2000UTCEEnotAfterDateTest7EE" }, new String[] { TRUST_ANCHOR_ROOT_CRL, GOOD_CA_CRL }, 0, "CertPathReviewer.certificateExpired", "Could not validate the certificate. Certificate expired on Jan 1, 1999 12:01:00 PM GMT."); } public void testInvalidNegativeSerialNumberTest15() throws Exception { doErrorTest(TRUST_ANCHOR_ROOT_CERTIFICATE, new String[] { "NegativeSerialNumberCACert", "InvalidNegativeSerialNumberTest15EE" }, new String[] { TRUST_ANCHOR_ROOT_CRL, "NegativeSerialNumberCACRL" }, 0, "CertPathReviewer.certRevoked", "The certificate was revoked at Apr 19, 2001 2:57:20 PM GMT. Reason: Key Compromise."); } // // 4.8 Certificate Policies // public void testAllCertificatesSamePolicyTest1() throws Exception { String[] certList = new String[] { GOOD_CA_CERT, "ValidCertificatePathTest1EE" }; String[] crlList = new String[] { TRUST_ANCHOR_ROOT_CRL, GOOD_CA_CRL }; doAcceptingTest(TRUST_ANCHOR_ROOT_CERTIFICATE, certList, crlList, noPolicies); doAcceptingTest(TRUST_ANCHOR_ROOT_CERTIFICATE, certList, crlList, nistTestPolicy1); doErrorTest(TRUST_ANCHOR_ROOT_CERTIFICATE, certList, crlList, nistTestPolicy2, -1, "CertPathReviewer.invalidPolicy", "Path processing failed on policy."); doAcceptingTest(TRUST_ANCHOR_ROOT_CERTIFICATE, certList, crlList, nistTestPolicy1And2); } public void testAllCertificatesNoPoliciesTest2() throws Exception { doAcceptingTest(TRUST_ANCHOR_ROOT_CERTIFICATE, new String[] { "NoPoliciesCACert", "AllCertificatesNoPoliciesTest2EE" }, new String[] { TRUST_ANCHOR_ROOT_CRL, "NoPoliciesCACRL" }); doErrorTest(TRUST_ANCHOR_ROOT_CERTIFICATE, new String[] { "NoPoliciesCACert", "AllCertificatesNoPoliciesTest2EE" }, new String[] { TRUST_ANCHOR_ROOT_CRL, "NoPoliciesCACRL" }, noPolicies, -1, "CertPathReviewer.noValidPolicyTree", "Policy checking failed: no valid policy tree found when one expected."); } public void testDifferentPoliciesTest3() throws Exception { doAcceptingTest(TRUST_ANCHOR_ROOT_CERTIFICATE, new String[] { GOOD_CA_CERT, "PoliciesP2subCACert", "DifferentPoliciesTest3EE" }, new String[] { TRUST_ANCHOR_ROOT_CRL, GOOD_CA_CRL, "PoliciesP2subCACRL" }); doErrorTest(TRUST_ANCHOR_ROOT_CERTIFICATE, new String[] { GOOD_CA_CERT, "PoliciesP2subCACert", "DifferentPoliciesTest3EE" }, new String[] { TRUST_ANCHOR_ROOT_CRL, GOOD_CA_CRL, "PoliciesP2subCACRL" }, noPolicies, -1, "CertPathReviewer.noValidPolicyTree", "Policy checking failed: no valid policy tree found when one expected."); doErrorTest(TRUST_ANCHOR_ROOT_CERTIFICATE, new String[] { GOOD_CA_CERT, "PoliciesP2subCACert", "DifferentPoliciesTest3EE" }, new String[] { TRUST_ANCHOR_ROOT_CRL, GOOD_CA_CRL, "PoliciesP2subCACRL" }, nistTestPolicy1And2, -1, "CertPathReviewer.noValidPolicyTree", "Policy checking failed: no valid policy tree found when one expected."); } public void testDifferentPoliciesTest4() throws Exception { doErrorTest(TRUST_ANCHOR_ROOT_CERTIFICATE, new String[] { GOOD_CA_CERT, "GoodsubCACert", "DifferentPoliciesTest4EE" }, new String[] { TRUST_ANCHOR_ROOT_CRL, GOOD_CA_CRL, "GoodsubCACRL" }, -1, "CertPathReviewer.noValidPolicyTree", "Policy checking failed: no valid policy tree found when one expected."); } public void testDifferentPoliciesTest5() throws Exception { doErrorTest(TRUST_ANCHOR_ROOT_CERTIFICATE, new String[] { GOOD_CA_CERT, "PoliciesP2subCA2Cert", "DifferentPoliciesTest5EE" }, new String[] { TRUST_ANCHOR_ROOT_CRL, GOOD_CA_CRL, "PoliciesP2subCA2CRL" }, -1, "CertPathReviewer.noValidPolicyTree", "Policy checking failed: no valid policy tree found when one expected."); } public void testOverlappingPoliciesTest6() throws Exception { String[] certList = new String[] { "PoliciesP1234CACert", "PoliciesP1234subCAP123Cert", "PoliciesP1234subsubCAP123P12Cert", "OverlappingPoliciesTest6EE" }; String[] crlList = new String[] { TRUST_ANCHOR_ROOT_CRL, "PoliciesP1234CACRL", "PoliciesP1234subCAP123CRL", "PoliciesP1234subsubCAP123P12CRL" }; doAcceptingTest(TRUST_ANCHOR_ROOT_CERTIFICATE, certList, crlList); doAcceptingTest(TRUST_ANCHOR_ROOT_CERTIFICATE, certList, crlList, nistTestPolicy1); doErrorTest(TRUST_ANCHOR_ROOT_CERTIFICATE, certList, crlList, nistTestPolicy2, -1, "CertPathReviewer.invalidPolicy", "Path processing failed on policy."); } public void testDifferentPoliciesTest7() throws Exception { String[] certList = new String[] { "PoliciesP123CACert", "PoliciesP123subCAP12Cert", "PoliciesP123subsubCAP12P1Cert", "DifferentPoliciesTest7EE" }; String[] crlList = new String[] { TRUST_ANCHOR_ROOT_CRL, "PoliciesP123CACRL", "PoliciesP123subCAP12CRL", "PoliciesP123subsubCAP12P1CRL" }; doErrorTest(TRUST_ANCHOR_ROOT_CERTIFICATE, certList, crlList, -1, "CertPathReviewer.noValidPolicyTree", "Policy checking failed: no valid policy tree found when one expected."); } public void testDifferentPoliciesTest8() throws Exception { String[] certList = new String[] { "PoliciesP12CACert", "PoliciesP12subCAP1Cert", "PoliciesP12subsubCAP1P2Cert", "DifferentPoliciesTest8EE" }; String[] crlList = new String[] { TRUST_ANCHOR_ROOT_CRL, "PoliciesP12CACRL", "PoliciesP12subCAP1CRL", "PoliciesP12subsubCAP1P2CRL" }; doErrorTest(TRUST_ANCHOR_ROOT_CERTIFICATE, certList, crlList, -1, "CertPathReviewer.noValidPolicyTree", "Policy checking failed: no valid policy tree found when one expected."); } public void testDifferentPoliciesTest9() throws Exception { String[] certList = new String[] { "PoliciesP123CACert", "PoliciesP123subCAP12Cert", "PoliciesP123subsubCAP12P2Cert", "PoliciesP123subsubsubCAP12P2P1Cert", "DifferentPoliciesTest9EE" }; String[] crlList = new String[] { TRUST_ANCHOR_ROOT_CRL, "PoliciesP123CACRL", "PoliciesP123subCAP12CRL", "PoliciesP123subsubCAP2P2CRL", "PoliciesP123subsubsubCAP12P2P1CRL" }; doErrorTest(TRUST_ANCHOR_ROOT_CERTIFICATE, certList, crlList, -1, "CertPathReviewer.noValidPolicyTree", "Policy checking failed: no valid policy tree found when one expected."); } public void testAllCertificatesSamePoliciesTest10() throws Exception { String[] certList = new String[] { "PoliciesP12CACert", "AllCertificatesSamePoliciesTest10EE" }; String[] crlList = new String[] { TRUST_ANCHOR_ROOT_CRL, "PoliciesP12CACRL" }; doAcceptingTest(TRUST_ANCHOR_ROOT_CERTIFICATE, certList, crlList); doAcceptingTest(TRUST_ANCHOR_ROOT_CERTIFICATE, certList, crlList, nistTestPolicy1); doAcceptingTest(TRUST_ANCHOR_ROOT_CERTIFICATE, certList, crlList, nistTestPolicy2); } public void testAllCertificatesAnyPolicyTest11() throws Exception { String[] certList = new String[] { "anyPolicyCACert", "AllCertificatesanyPolicyTest11EE" }; String[] crlList = new String[] { TRUST_ANCHOR_ROOT_CRL, "anyPolicyCACRL" }; doAcceptingTest(TRUST_ANCHOR_ROOT_CERTIFICATE, certList, crlList); doAcceptingTest(TRUST_ANCHOR_ROOT_CERTIFICATE, certList, crlList, nistTestPolicy1); } public void testDifferentPoliciesTest12() throws Exception { String[] certList = new String[] { "PoliciesP3CACert", "DifferentPoliciesTest12EE" }; String[] crlList = new String[] { TRUST_ANCHOR_ROOT_CRL, "PoliciesP3CACRL" }; doErrorTest(TRUST_ANCHOR_ROOT_CERTIFICATE, certList, crlList, -1, "CertPathReviewer.noValidPolicyTree", "Policy checking failed: no valid policy tree found when one expected."); } public void testAllCertificatesSamePoliciesTest13() throws Exception { String[] certList = new String[] { "PoliciesP123CACert", "AllCertificatesSamePoliciesTest13EE" }; String[] crlList = new String[] { TRUST_ANCHOR_ROOT_CRL, "PoliciesP123CACRL" }; doAcceptingTest(TRUST_ANCHOR_ROOT_CERTIFICATE, certList, crlList, nistTestPolicy1); doAcceptingTest(TRUST_ANCHOR_ROOT_CERTIFICATE, certList, crlList, nistTestPolicy2); doAcceptingTest(TRUST_ANCHOR_ROOT_CERTIFICATE, certList, crlList, nistTestPolicy3); } public void testAnyPolicyTest14() throws Exception { String[] certList = new String[] { "anyPolicyCACert", "AnyPolicyTest14EE" }; String[] crlList = new String[] { TRUST_ANCHOR_ROOT_CRL, "anyPolicyCACRL" }; doAcceptingTest(TRUST_ANCHOR_ROOT_CERTIFICATE, certList, crlList, nistTestPolicy1); doErrorTest(TRUST_ANCHOR_ROOT_CERTIFICATE, certList, crlList, nistTestPolicy2, -1, "CertPathReviewer.invalidPolicy", "Path processing failed on policy."); } public void testUserNoticeQualifierTest15() throws Exception { String[] certList = new String[] { "UserNoticeQualifierTest15EE" }; String[] crlList = new String[] { TRUST_ANCHOR_ROOT_CRL }; doAcceptingTest(TRUST_ANCHOR_ROOT_CERTIFICATE, certList, crlList); doAcceptingTest(TRUST_ANCHOR_ROOT_CERTIFICATE, certList, crlList, nistTestPolicy1); doErrorTest(TRUST_ANCHOR_ROOT_CERTIFICATE, certList, crlList, nistTestPolicy2, -1, "CertPathReviewer.invalidPolicy", "Path processing failed on policy."); } public void testUserNoticeQualifierTest16() throws Exception { String[] certList = new String[] { GOOD_CA_CERT, "UserNoticeQualifierTest16EE" }; String[] crlList = new String[] { TRUST_ANCHOR_ROOT_CRL, GOOD_CA_CRL }; doAcceptingTest(TRUST_ANCHOR_ROOT_CERTIFICATE, certList, crlList); doAcceptingTest(TRUST_ANCHOR_ROOT_CERTIFICATE, certList, crlList, nistTestPolicy1); doErrorTest(TRUST_ANCHOR_ROOT_CERTIFICATE, certList, crlList, nistTestPolicy2, -1, "CertPathReviewer.invalidPolicy", "Path processing failed on policy."); } public void testUserNoticeQualifierTest17() throws Exception { String[] certList = new String[] { GOOD_CA_CERT, "UserNoticeQualifierTest17EE" }; String[] crlList = new String[] { TRUST_ANCHOR_ROOT_CRL, GOOD_CA_CRL }; doAcceptingTest(TRUST_ANCHOR_ROOT_CERTIFICATE, certList, crlList); doAcceptingTest(TRUST_ANCHOR_ROOT_CERTIFICATE, certList, crlList, nistTestPolicy1); doErrorTest(TRUST_ANCHOR_ROOT_CERTIFICATE, certList, crlList, nistTestPolicy2, -1, "CertPathReviewer.invalidPolicy", "Path processing failed on policy."); } public void testUserNoticeQualifierTest18() throws Exception { String[] certList = new String[] { "PoliciesP12CACert", "UserNoticeQualifierTest18EE" }; String[] crlList = new String[] { TRUST_ANCHOR_ROOT_CRL, "PoliciesP12CACRL" }; doAcceptingTest(TRUST_ANCHOR_ROOT_CERTIFICATE, certList, crlList, nistTestPolicy1); doAcceptingTest(TRUST_ANCHOR_ROOT_CERTIFICATE, certList, crlList, nistTestPolicy2); } public void testUserNoticeQualifierTest19() throws Exception { String[] certList = new String[] { "UserNoticeQualifierTest19EE" }; String[] crlList = new String[] { TRUST_ANCHOR_ROOT_CRL }; doAcceptingTest(TRUST_ANCHOR_ROOT_CERTIFICATE, certList, crlList, nistTestPolicy1); doErrorTest(TRUST_ANCHOR_ROOT_CERTIFICATE, certList, crlList, nistTestPolicy2, -1, "CertPathReviewer.invalidPolicy", "Path processing failed on policy."); } private void doAcceptingTest( String trustAnchor, String[] certs, String[] crls) throws Exception { PKIXCertPathReviewer result = doTest(trustAnchor,certs,crls); if (!result.isValidCertPath()) { fail("path rejected when should be accepted"); } } private void doAcceptingTest( String trustAnchor, String[] certs, String[] crls, Set policies) throws Exception { PKIXCertPathReviewer result = doTest(trustAnchor,certs,crls,policies); if (!result.isValidCertPath()) { fail("path rejected when should be accepted"); } } private void doErrorTest( String trustAnchor, String[] certs, String[] crls, int index, String messageId, String message) throws Exception { PKIXCertPathReviewer result = doTest(trustAnchor, certs, crls); if (result.isValidCertPath()) { fail("path accepted when should be rejected"); } else { ErrorBundle msg = (ErrorBundle) result.getErrors(index).iterator().next(); assertEquals(messageId,msg.getId()); assertEquals(message,msg.getText(Locale.ENGLISH,TimeZone.getTimeZone("GMT"))); } } private void doErrorTest( String trustAnchor, String[] certs, String[] crls, Set policies, int index, String messageId, String message) throws Exception { PKIXCertPathReviewer result = doTest(trustAnchor, certs, crls, policies); if (result.isValidCertPath()) { fail("path accepted when should be rejected"); } else { ErrorBundle msg = (ErrorBundle) result.getErrors(index).iterator().next(); assertEquals(messageId,msg.getId()); assertEquals(message,msg.getText(Locale.ENGLISH,TimeZone.getTimeZone("GMT"))); } } private PKIXCertPathReviewer doTest( String trustAnchor, String[] certs, String[] crls) throws Exception { return doTest(trustAnchor, certs, crls, null); } private PKIXCertPathReviewer doTest( String trustAnchor, String[] certs, String[] crls, Set policies) throws Exception { Set trustedSet = Collections.singleton(getTrustAnchor(trustAnchor)); List certsAndCrls = new ArrayList(); X509Certificate endCert = loadCert(certs[certs.length - 1]); for (int i = 0; i != certs.length - 1; i++) { certsAndCrls.add(loadCert(certs[i])); } certsAndCrls.add(endCert); CertPath certPath = CertificateFactory.getInstance("X.509","BC").generateCertPath(certsAndCrls); for (int i = 0; i != crls.length; i++) { certsAndCrls.add(loadCrl(crls[i])); } CertStore store = CertStore.getInstance("Collection", new CollectionCertStoreParameters(certsAndCrls), "BC"); //CertPathValidator validator = CertPathValidator.getInstance("PKIX","BC"); PKIXCertPathReviewer reviewer; PKIXParameters params = new PKIXParameters(trustedSet); params.addCertStore(store); params.setRevocationEnabled(true); params.setDate(new GregorianCalendar(2010, 1, 1).getTime()); if (policies != null) { params.setExplicitPolicyRequired(true); params.setInitialPolicies(policies); } reviewer = new PKIXCertPathReviewer(certPath,params); return reviewer; } private X509Certificate loadCert( String certName) { X509Certificate cert = (X509Certificate)certs.get(certName); if (cert != null) { return cert; } try { InputStream in = new FileInputStream(getPkitsHome() + "/certs/" + certName + ".crt"); CertificateFactory fact = CertificateFactory.getInstance("X.509", "BC"); cert = (X509Certificate)fact.generateCertificate(in); certs.put(certName, cert); return cert; } catch (Exception e) { throw new IllegalStateException("exception loading certificate " + certName + ": " + e); } } private X509CRL loadCrl( String crlName) throws Exception { X509CRL crl = (X509CRL)certs.get(crlName); if (crl != null) { return crl; } try { InputStream in = new FileInputStream(getPkitsHome() + "/crls/" + crlName + ".crl"); CertificateFactory fact = CertificateFactory.getInstance("X.509", "BC"); crl = (X509CRL)fact.generateCRL(in); crls.put(crlName, crl); return crl; } catch (Exception e) { throw new IllegalStateException("exception loading CRL: " + crlName); } } private TrustAnchor getTrustAnchor(String trustAnchorName) throws Exception { X509Certificate cert = loadCert(trustAnchorName); byte[] extBytes = cert.getExtensionValue(X509Extension.nameConstraints.getId()); if (extBytes != null) { ASN1Primitive extValue = X509ExtensionUtil.fromExtensionValue(extBytes); return new TrustAnchor(cert, extValue.getEncoded(ASN1Encoding.DER)); } return new TrustAnchor(cert, null); } private String getPkitsHome() { String dataHome = System.getProperty(TEST_DATA_HOME); if (dataHome == null) { throw new IllegalStateException(TEST_DATA_HOME + " property not set"); } return dataHome + "/PKITS"; } public static void main (String[] args) throws Exception { junit.textui.TestRunner.run(suite()); } public void setUp() { if (Security.getProvider("BC") == null) { Security.addProvider(new org.bouncycastle.jce.provider.BouncyCastleProvider()); } } public static Test suite() throws Exception { TestSuite suite = new TestSuite("NIST CertPath Tests"); suite.addTestSuite(NistCertPathReviewerTest.class); return suite; } } bouncycastle-1.49.orig/test/src/org/bouncycastle/jce/provider/test/nist/NistCertPathTest.java0000644000175000017500000010100611640254300032054 0ustar ebourgebourgpackage org.bouncycastle.jce.provider.test.nist; import java.io.FileInputStream; import java.io.InputStream; import java.security.Security; import java.security.cert.CertPath; import java.security.cert.CertPathBuilder; import java.security.cert.CertPathBuilderException; import java.security.cert.CertPathValidator; import java.security.cert.CertPathValidatorException; import java.security.cert.CertStore; import java.security.cert.CertificateFactory; import java.security.cert.CollectionCertStoreParameters; import java.security.cert.PKIXBuilderParameters; import java.security.cert.PKIXCertPathBuilderResult; import java.security.cert.PKIXCertPathValidatorResult; import java.security.cert.PKIXParameters; import java.security.cert.TrustAnchor; import java.security.cert.X509CRL; import java.security.cert.X509CertSelector; import java.security.cert.X509Certificate; import java.util.ArrayList; import java.util.Arrays; import java.util.Collections; import java.util.GregorianCalendar; import java.util.HashMap; import java.util.HashSet; import java.util.List; import java.util.Map; import java.util.Set; import junit.framework.Test; import junit.framework.TestCase; import junit.framework.TestSuite; import org.bouncycastle.asn1.ASN1Encodable; import org.bouncycastle.asn1.ASN1Encoding; import org.bouncycastle.asn1.x509.X509Extension; import org.bouncycastle.x509.extension.X509ExtensionUtil; /** * NIST CertPath test data for RFC 3280 */ public class NistCertPathTest extends TestCase { private static final String TEST_DATA_HOME = "bc.test.data.home"; private static final String GOOD_CA_CERT = "GoodCACert"; private static final String GOOD_CA_CRL = "GoodCACRL"; private static final String TRUST_ANCHOR_ROOT_CRL = "TrustAnchorRootCRL"; private static final String TRUST_ANCHOR_ROOT_CERTIFICATE = "TrustAnchorRootCertificate"; private static final char[] PKCS12_PASSWORD = "password".toCharArray(); private static final String ANY_POLICY = "2.5.29.32.0"; private static final String NIST_TEST_POLICY_1 = "2.16.840.1.101.3.2.1.48.1"; private static final String NIST_TEST_POLICY_2 = "2.16.840.1.101.3.2.1.48.2"; private static final String NIST_TEST_POLICY_3 = "2.16.840.1.101.3.2.1.48.3"; private static Map certs = new HashMap(); private static Map crls = new HashMap(); private static Set noPolicies = Collections.EMPTY_SET; private static Set anyPolicy = Collections.singleton(ANY_POLICY); private static Set nistTestPolicy1 = Collections.singleton(NIST_TEST_POLICY_1); private static Set nistTestPolicy2 = Collections.singleton(NIST_TEST_POLICY_2); private static Set nistTestPolicy3 = Collections.singleton(NIST_TEST_POLICY_3); private static Set nistTestPolicy1And2 = new HashSet(Arrays.asList(new String[] { NIST_TEST_POLICY_1, NIST_TEST_POLICY_2 })); public void setUp() { if (Security.getProvider("BC") == null) { Security.addProvider(new org.bouncycastle.jce.provider.BouncyCastleProvider()); } } public void testValidSignaturesTest1() throws Exception { doTest(TRUST_ANCHOR_ROOT_CERTIFICATE, new String[] { "ValidCertificatePathTest1EE", GOOD_CA_CERT}, new String[] { GOOD_CA_CRL, TRUST_ANCHOR_ROOT_CRL }); } public void testInvalidCASignatureTest2() throws Exception { doExceptionTest(TRUST_ANCHOR_ROOT_CERTIFICATE, new String[] { "ValidCertificatePathTest1EE", "BadSignedCACert" }, new String[] { "BadSignedCACRL", TRUST_ANCHOR_ROOT_CRL}, 1, "TrustAnchor found but certificate validation failed."); } public void testInvalidEESignatureTest3() throws Exception { doExceptionTest(TRUST_ANCHOR_ROOT_CERTIFICATE, new String[] { GOOD_CA_CERT, "InvalidEESignatureTest3EE" }, new String[] { TRUST_ANCHOR_ROOT_CRL, GOOD_CA_CRL }, 0, "Could not validate certificate signature."); } public void testValidDSASignaturesTest4() throws Exception { doTest(TRUST_ANCHOR_ROOT_CERTIFICATE, new String[] { "DSACACert", "ValidDSASignaturesTest4EE" }, new String[] { TRUST_ANCHOR_ROOT_CRL, "DSACACRL" }); } // 4.1.5 public void testValidDSAParameterInheritanceTest5() throws Exception { doTest(TRUST_ANCHOR_ROOT_CERTIFICATE, new String[] { "DSACACert", "DSAParametersInheritedCACert", "ValidDSAParameterInheritanceTest5EE" }, new String[] { TRUST_ANCHOR_ROOT_CRL, "DSACACRL", "DSAParametersInheritedCACRL" }); } public void testInvalidDSASignaturesTest6() throws Exception { doExceptionTest(TRUST_ANCHOR_ROOT_CERTIFICATE, new String[] { "DSACACert", "InvalidDSASignatureTest6EE" }, new String[] { TRUST_ANCHOR_ROOT_CRL, "DSACACRL" }, 0, "Could not validate certificate signature."); } public void testCANotBeforeDateTest1() throws Exception { doExceptionTest(TRUST_ANCHOR_ROOT_CERTIFICATE, new String[] { "BadnotBeforeDateCACert", "InvalidCAnotBeforeDateTest1EE" }, new String[] { TRUST_ANCHOR_ROOT_CRL, "BadnotBeforeDateCACRL" }, 1, "Could not validate certificate: certificate not valid till 20470101120100GMT+00:00"); } public void testInvalidEENotBeforeDateTest2() throws Exception { doExceptionTest(TRUST_ANCHOR_ROOT_CERTIFICATE, new String[] { GOOD_CA_CERT, "InvalidEEnotBeforeDateTest2EE" }, new String[] { TRUST_ANCHOR_ROOT_CRL, GOOD_CA_CRL }, 0, "Could not validate certificate: certificate not valid till 20470101120100GMT+00:00"); } public void testValidPre2000UTCNotBeforeDateTest3() throws Exception { doTest(TRUST_ANCHOR_ROOT_CERTIFICATE, new String[] { GOOD_CA_CERT, "Validpre2000UTCnotBeforeDateTest3EE" }, new String[] { TRUST_ANCHOR_ROOT_CRL, GOOD_CA_CRL }); } public void testValidGeneralizedTimeNotBeforeDateTest4() throws Exception { doTest(TRUST_ANCHOR_ROOT_CERTIFICATE, new String[] { GOOD_CA_CERT, "ValidGeneralizedTimenotBeforeDateTest4EE" }, new String[] { TRUST_ANCHOR_ROOT_CRL, GOOD_CA_CRL }); } public void testInvalidCANotAfterDateTest5() throws Exception { doExceptionTest(TRUST_ANCHOR_ROOT_CERTIFICATE, new String[] { "BadnotAfterDateCACert", "InvalidCAnotAfterDateTest5EE" }, new String[] { TRUST_ANCHOR_ROOT_CRL, "BadnotAfterDateCACRL" }, 1, "Could not validate certificate: certificate expired on 20020101120100GMT+00:00"); } public void testInvalidEENotAfterDateTest6() throws Exception { doExceptionTest(TRUST_ANCHOR_ROOT_CERTIFICATE, new String[] { GOOD_CA_CERT, "InvalidEEnotAfterDateTest6EE" }, new String[] { TRUST_ANCHOR_ROOT_CRL, GOOD_CA_CRL }, 0, "Could not validate certificate: certificate expired on 20020101120100GMT+00:00"); } public void testInvalidValidPre2000UTCNotAfterDateTest7() throws Exception { doExceptionTest(TRUST_ANCHOR_ROOT_CERTIFICATE, new String[] { GOOD_CA_CERT, "Invalidpre2000UTCEEnotAfterDateTest7EE" }, new String[] { TRUST_ANCHOR_ROOT_CRL, GOOD_CA_CRL }, 0, "Could not validate certificate: certificate expired on 19990101120100GMT+00:00"); } public void testInvalidNegativeSerialNumberTest15() throws Exception { doExceptionTest(TRUST_ANCHOR_ROOT_CERTIFICATE, new String[] { "NegativeSerialNumberCACert", "InvalidNegativeSerialNumberTest15EE" }, new String[] { TRUST_ANCHOR_ROOT_CRL, "NegativeSerialNumberCACRL" }, 0, "Certificate revocation after Fri Apr 20 00:57:20", "reason: keyCompromise"); } // // 4.8 Certificate Policies // public void testAllCertificatesSamePolicyTest1() throws Exception { String[] certList = new String[] { GOOD_CA_CERT, "ValidCertificatePathTest1EE" }; String[] crlList = new String[] { TRUST_ANCHOR_ROOT_CRL, GOOD_CA_CRL }; doTest(TRUST_ANCHOR_ROOT_CERTIFICATE, certList, crlList, noPolicies); doTest(TRUST_ANCHOR_ROOT_CERTIFICATE, certList, crlList, nistTestPolicy1); doExceptionTest(TRUST_ANCHOR_ROOT_CERTIFICATE, certList, crlList, nistTestPolicy2, -1, "Path processing failed on policy."); doTest(TRUST_ANCHOR_ROOT_CERTIFICATE, certList, crlList, nistTestPolicy1And2); } public void testAllCertificatesNoPoliciesTest2() throws Exception { doTest(TRUST_ANCHOR_ROOT_CERTIFICATE, new String[] { "NoPoliciesCACert", "AllCertificatesNoPoliciesTest2EE" }, new String[] { TRUST_ANCHOR_ROOT_CRL, "NoPoliciesCACRL" }); doExceptionTest(TRUST_ANCHOR_ROOT_CERTIFICATE, new String[] { "NoPoliciesCACert", "AllCertificatesNoPoliciesTest2EE" }, new String[] { TRUST_ANCHOR_ROOT_CRL, "NoPoliciesCACRL" }, noPolicies, 1, "No valid policy tree found when one expected."); } public void testDifferentPoliciesTest3() throws Exception { doTest(TRUST_ANCHOR_ROOT_CERTIFICATE, new String[] { GOOD_CA_CERT, "PoliciesP2subCACert", "DifferentPoliciesTest3EE" }, new String[] { TRUST_ANCHOR_ROOT_CRL, GOOD_CA_CRL, "PoliciesP2subCACRL" }); doExceptionTest(TRUST_ANCHOR_ROOT_CERTIFICATE, new String[] { GOOD_CA_CERT, "PoliciesP2subCACert", "DifferentPoliciesTest3EE" }, new String[] { TRUST_ANCHOR_ROOT_CRL, GOOD_CA_CRL, "PoliciesP2subCACRL" }, noPolicies, 1, "No valid policy tree found when one expected."); doExceptionTest(TRUST_ANCHOR_ROOT_CERTIFICATE, new String[] { GOOD_CA_CERT, "PoliciesP2subCACert", "DifferentPoliciesTest3EE" }, new String[] { TRUST_ANCHOR_ROOT_CRL, GOOD_CA_CRL, "PoliciesP2subCACRL" }, nistTestPolicy1And2, 1, "No valid policy tree found when one expected."); } public void testDifferentPoliciesTest4() throws Exception { doExceptionTest(TRUST_ANCHOR_ROOT_CERTIFICATE, new String[] { GOOD_CA_CERT, "GoodsubCACert", "DifferentPoliciesTest4EE" }, new String[] { TRUST_ANCHOR_ROOT_CRL, GOOD_CA_CRL, "GoodsubCACRL" }, 0, "No valid policy tree found when one expected."); } public void testDifferentPoliciesTest5() throws Exception { doExceptionTest(TRUST_ANCHOR_ROOT_CERTIFICATE, new String[] { GOOD_CA_CERT, "PoliciesP2subCA2Cert", "DifferentPoliciesTest5EE" }, new String[] { TRUST_ANCHOR_ROOT_CRL, GOOD_CA_CRL, "PoliciesP2subCA2CRL" }, 0, "No valid policy tree found when one expected."); } public void testOverlappingPoliciesTest6() throws Exception { String[] certList = new String[] { "PoliciesP1234CACert", "PoliciesP1234subCAP123Cert", "PoliciesP1234subsubCAP123P12Cert", "OverlappingPoliciesTest6EE" }; String[] crlList = new String[] { TRUST_ANCHOR_ROOT_CRL, "PoliciesP1234CACRL", "PoliciesP1234subCAP123CRL", "PoliciesP1234subsubCAP123P12CRL" }; doTest(TRUST_ANCHOR_ROOT_CERTIFICATE, certList, crlList); doTest(TRUST_ANCHOR_ROOT_CERTIFICATE, certList, crlList, nistTestPolicy1); doExceptionTest(TRUST_ANCHOR_ROOT_CERTIFICATE, certList, crlList, nistTestPolicy2, -1, "Path processing failed on policy."); } public void testDifferentPoliciesTest7() throws Exception { String[] certList = new String[] { "PoliciesP123CACert", "PoliciesP123subCAP12Cert", "PoliciesP123subsubCAP12P1Cert", "DifferentPoliciesTest7EE" }; String[] crlList = new String[] { TRUST_ANCHOR_ROOT_CRL, "PoliciesP123CACRL", "PoliciesP123subCAP12CRL", "PoliciesP123subsubCAP12P1CRL" }; doExceptionTest(TRUST_ANCHOR_ROOT_CERTIFICATE, certList, crlList, 0, "No valid policy tree found when one expected."); } public void testDifferentPoliciesTest8() throws Exception { String[] certList = new String[] { "PoliciesP12CACert", "PoliciesP12subCAP1Cert", "PoliciesP12subsubCAP1P2Cert", "DifferentPoliciesTest8EE" }; String[] crlList = new String[] { TRUST_ANCHOR_ROOT_CRL, "PoliciesP12CACRL", "PoliciesP12subCAP1CRL", "PoliciesP12subsubCAP1P2CRL" }; doExceptionTest(TRUST_ANCHOR_ROOT_CERTIFICATE, certList, crlList, 1, "No valid policy tree found when one expected."); } public void testDifferentPoliciesTest9() throws Exception { String[] certList = new String[] { "PoliciesP123CACert", "PoliciesP123subCAP12Cert", "PoliciesP123subsubCAP12P2Cert", "PoliciesP123subsubsubCAP12P2P1Cert", "DifferentPoliciesTest9EE" }; String[] crlList = new String[] { TRUST_ANCHOR_ROOT_CRL, "PoliciesP123CACRL", "PoliciesP123subCAP12CRL", "PoliciesP123subsubCAP2P2CRL", "PoliciesP123subsubsubCAP12P2P1CRL" }; doExceptionTest(TRUST_ANCHOR_ROOT_CERTIFICATE, certList, crlList, 1, "No valid policy tree found when one expected."); } public void testAllCertificatesSamePoliciesTest10() throws Exception { String[] certList = new String[] { "PoliciesP12CACert", "AllCertificatesSamePoliciesTest10EE" }; String[] crlList = new String[] { TRUST_ANCHOR_ROOT_CRL, "PoliciesP12CACRL" }; doTest(TRUST_ANCHOR_ROOT_CERTIFICATE, certList, crlList); doTest(TRUST_ANCHOR_ROOT_CERTIFICATE, certList, crlList, nistTestPolicy1); doTest(TRUST_ANCHOR_ROOT_CERTIFICATE, certList, crlList, nistTestPolicy2); } public void testAllCertificatesAnyPolicyTest11() throws Exception { String[] certList = new String[] { "anyPolicyCACert", "AllCertificatesanyPolicyTest11EE" }; String[] crlList = new String[] { TRUST_ANCHOR_ROOT_CRL, "anyPolicyCACRL" }; PKIXCertPathValidatorResult result = doTest(TRUST_ANCHOR_ROOT_CERTIFICATE, certList, crlList); result = doTest(TRUST_ANCHOR_ROOT_CERTIFICATE, certList, crlList, nistTestPolicy1); } public void testDifferentPoliciesTest12() throws Exception { String[] certList = new String[] { "PoliciesP3CACert", "DifferentPoliciesTest12EE" }; String[] crlList = new String[] { TRUST_ANCHOR_ROOT_CRL, "PoliciesP3CACRL" }; doExceptionTest(TRUST_ANCHOR_ROOT_CERTIFICATE, certList, crlList, 0, "No valid policy tree found when one expected."); } public void testAllCertificatesSamePoliciesTest13() throws Exception { String[] certList = new String[] { "PoliciesP123CACert", "AllCertificatesSamePoliciesTest13EE" }; String[] crlList = new String[] { TRUST_ANCHOR_ROOT_CRL, "PoliciesP123CACRL" }; doTest(TRUST_ANCHOR_ROOT_CERTIFICATE, certList, crlList, nistTestPolicy1); doTest(TRUST_ANCHOR_ROOT_CERTIFICATE, certList, crlList, nistTestPolicy2); doTest(TRUST_ANCHOR_ROOT_CERTIFICATE, certList, crlList, nistTestPolicy3); } public void testAnyPolicyTest14() throws Exception { String[] certList = new String[] { "anyPolicyCACert", "AnyPolicyTest14EE" }; String[] crlList = new String[] { TRUST_ANCHOR_ROOT_CRL, "anyPolicyCACRL" }; doTest(TRUST_ANCHOR_ROOT_CERTIFICATE, certList, crlList, nistTestPolicy1); doExceptionTest(TRUST_ANCHOR_ROOT_CERTIFICATE, certList, crlList, nistTestPolicy2, -1, "Path processing failed on policy."); } public void testUserNoticeQualifierTest15() throws Exception { String[] certList = new String[] { "UserNoticeQualifierTest15EE" }; String[] crlList = new String[] { TRUST_ANCHOR_ROOT_CRL }; doTest(TRUST_ANCHOR_ROOT_CERTIFICATE, certList, crlList); doTest(TRUST_ANCHOR_ROOT_CERTIFICATE, certList, crlList, nistTestPolicy1); doExceptionTest(TRUST_ANCHOR_ROOT_CERTIFICATE, certList, crlList, nistTestPolicy2, -1, "Path processing failed on policy."); } public void testUserNoticeQualifierTest16() throws Exception { String[] certList = new String[] { GOOD_CA_CERT, "UserNoticeQualifierTest16EE" }; String[] crlList = new String[] { TRUST_ANCHOR_ROOT_CRL, GOOD_CA_CRL }; PKIXCertPathValidatorResult result = doTest(TRUST_ANCHOR_ROOT_CERTIFICATE, certList, crlList); result = doTest(TRUST_ANCHOR_ROOT_CERTIFICATE, certList, crlList, nistTestPolicy1); doExceptionTest(TRUST_ANCHOR_ROOT_CERTIFICATE, certList, crlList, nistTestPolicy2, -1, "Path processing failed on policy."); } public void testUserNoticeQualifierTest17() throws Exception { String[] certList = new String[] { GOOD_CA_CERT, "UserNoticeQualifierTest17EE" }; String[] crlList = new String[] { TRUST_ANCHOR_ROOT_CRL, GOOD_CA_CRL }; doTest(TRUST_ANCHOR_ROOT_CERTIFICATE, certList, crlList); doTest(TRUST_ANCHOR_ROOT_CERTIFICATE, certList, crlList, nistTestPolicy1); doExceptionTest(TRUST_ANCHOR_ROOT_CERTIFICATE, certList, crlList, nistTestPolicy2, -1, "Path processing failed on policy."); } public void testUserNoticeQualifierTest18() throws Exception { String[] certList = new String[] { "PoliciesP12CACert", "UserNoticeQualifierTest18EE" }; String[] crlList = new String[] { TRUST_ANCHOR_ROOT_CRL, "PoliciesP12CACRL" }; doTest(TRUST_ANCHOR_ROOT_CERTIFICATE, certList, crlList, nistTestPolicy1); doTest(TRUST_ANCHOR_ROOT_CERTIFICATE, certList, crlList, nistTestPolicy2); } public void testUserNoticeQualifierTest19() throws Exception { String[] certList = new String[] { "UserNoticeQualifierTest19EE" }; String[] crlList = new String[] { TRUST_ANCHOR_ROOT_CRL }; doTest(TRUST_ANCHOR_ROOT_CERTIFICATE, certList, crlList, nistTestPolicy1); doExceptionTest(TRUST_ANCHOR_ROOT_CERTIFICATE, certList, crlList, nistTestPolicy2, -1, "Path processing failed on policy."); } public void testInvalidInhibitPolicyMappingTest1() throws Exception { String[] certList = new String[] { "inhibitPolicyMapping0CACert", "inhibitPolicyMapping0subCACert", "InvalidinhibitPolicyMappingTest1EE" }; String[] crlList = new String[] { TRUST_ANCHOR_ROOT_CRL, "inhibitPolicyMapping0CACRL", "inhibitPolicyMapping0subCACRL" }; doExceptionTest(TRUST_ANCHOR_ROOT_CERTIFICATE, certList, crlList, null, 0, "No valid policy tree found when one expected."); } public void testValidinhibitPolicyMappingTest2() throws Exception { String[] certList = new String[] { "inhibitPolicyMapping1P12CACert", "inhibitPolicyMapping1P12subCACert", "ValidinhibitPolicyMappingTest2EE" }; String[] crlList = new String[] { TRUST_ANCHOR_ROOT_CRL, "inhibitPolicyMapping1P12CACRL", "inhibitPolicyMapping1P12subCACRL" }; doTest(TRUST_ANCHOR_ROOT_CERTIFICATE, certList, crlList, nistTestPolicy1); } // 4.12.7 public void testValidSelfIssuedinhibitAnyPolicyTest7() throws Exception { String[] certList = new String[] { "inhibitAnyPolicy1CACert", "inhibitAnyPolicy1SelfIssuedCACert", "inhibitAnyPolicy1subCA2Cert", "ValidSelfIssuedinhibitAnyPolicyTest7EE" }; String[] crlList = new String[] { TRUST_ANCHOR_ROOT_CRL, "inhibitAnyPolicy1CACRL", "inhibitAnyPolicy1subCA2CRL" }; doBuilderTest(TRUST_ANCHOR_ROOT_CERTIFICATE, certList, crlList, null, false, false); } // 4.4.19 public void testValidSeparateCertificateandCRLKeysTest19() throws Exception { String[] certList = new String[] { "SeparateCertificateandCRLKeysCertificateSigningCACert", "SeparateCertificateandCRLKeysCRLSigningCert", "ValidSeparateCertificateandCRLKeysTest19EE" }; String[] crlList = new String[] { TRUST_ANCHOR_ROOT_CRL, "SeparateCertificateandCRLKeysCRL" }; doBuilderTest(TRUST_ANCHOR_ROOT_CERTIFICATE, certList, crlList, null, false, false); } public void testValidpathLenConstraintTest13() throws Exception { String[] certList = new String[] { "pathLenConstraint6CACert", "pathLenConstraint6subCA4Cert", "pathLenConstraint6subsubCA41Cert", "pathLenConstraint6subsubsubCA41XCert", "ValidpathLenConstraintTest13EE" }; String[] crlList = new String[] { TRUST_ANCHOR_ROOT_CRL, "pathLenConstraint6CACRL", "pathLenConstraint6subCA4CRL", "pathLenConstraint6subsubCA41CRL", "pathLenConstraint6subsubsubCA41XCRL" }; doTest(TRUST_ANCHOR_ROOT_CERTIFICATE, certList, crlList, null); } // 4.4.10 public void testInvalidUnknownCRLExtensionTest10() throws Exception { String[] certList = new String[] { "UnknownCRLExtensionCACert", "InvalidUnknownCRLExtensionTest10EE" }; String[] crlList = new String[] { TRUST_ANCHOR_ROOT_CRL, "UnknownCRLExtensionCACRL" }; doExceptionTest(TRUST_ANCHOR_ROOT_CERTIFICATE, certList, crlList, null, 0, "CRL contains unsupported critical extensions."); } // 4.14.3 public void testInvaliddistributionPointTest3() throws Exception { String[] certList = new String[] { "distributionPoint1CACert", "InvaliddistributionPointTest3EE" }; String[] crlList = new String[] { TRUST_ANCHOR_ROOT_CRL, "distributionPoint1CACRL" }; doExceptionTest(TRUST_ANCHOR_ROOT_CERTIFICATE, certList, crlList, null, 0, "No match for certificate CRL issuing distribution point name to cRLIssuer CRL distribution point."); } // 4.14.5 public void testValiddistributionPointTest5() throws Exception { String[] certList = new String[] { "distributionPoint2CACert", "ValiddistributionPointTest5EE" }; String[] crlList = new String[] { TRUST_ANCHOR_ROOT_CRL, "distributionPoint2CACRL" }; doTest(TRUST_ANCHOR_ROOT_CERTIFICATE, certList, crlList, null); } // 4.14.8 public void testInvaliddistributionPointTest8() throws Exception { String[] certList = new String[] { "distributionPoint2CACert", "InvaliddistributionPointTest8EE" }; String[] crlList = new String[] { TRUST_ANCHOR_ROOT_CRL, "distributionPoint2CACRL" }; doExceptionTest(TRUST_ANCHOR_ROOT_CERTIFICATE, certList, crlList, null, 0, "No match for certificate CRL issuing distribution point name to cRLIssuer CRL distribution point."); } // 4.14.9 public void testInvaliddistributionPointTest9() throws Exception { String[] certList = new String[] { "distributionPoint2CACert", "InvaliddistributionPointTest9EE" }; String[] crlList = new String[] { TRUST_ANCHOR_ROOT_CRL, "distributionPoint2CACRL" }; doExceptionTest(TRUST_ANCHOR_ROOT_CERTIFICATE, certList, crlList, null, 0, "No match for certificate CRL issuing distribution point name to cRLIssuer CRL distribution point."); } // 4.14.17 public void testInvalidonlySomeReasonsTest17() throws Exception { String[] certList = new String[] { "onlySomeReasonsCA2Cert", "InvalidonlySomeReasonsTest17EE" }; String[] crlList = new String[] { TRUST_ANCHOR_ROOT_CRL, "onlySomeReasonsCA2CRL1", "onlySomeReasonsCA2CRL2" }; doExceptionTest(TRUST_ANCHOR_ROOT_CERTIFICATE, certList, crlList, null, 0, "Certificate status could not be determined."); } // section 4.14: tests 17, 24, 25, 30, 31, 32, 33, 35 // section 4.15: tests 5, 7 private void doExceptionTest( String trustAnchor, String[] certs, String[] crls, int index, String message) throws Exception { try { doTest(trustAnchor, certs, crls); fail("path accepted when should be rejected"); } catch (CertPathValidatorException e) { assertEquals(index, e.getIndex()); assertEquals(message, e.getMessage()); } } private void doExceptionTest( String trustAnchor, String[] certs, String[] crls, Set policies, int index, String message) throws Exception { try { doTest(trustAnchor, certs, crls, policies); fail("path accepted when should be rejected"); } catch (CertPathValidatorException e) { assertEquals(index, e.getIndex()); assertEquals(message, e.getMessage()); } } private void doExceptionTest( String trustAnchor, String[] certs, String[] crls, int index, String mesStart, String mesEnd) throws Exception { try { doTest(trustAnchor, certs, crls); fail("path accepted when should be rejected"); } catch (CertPathValidatorException e) { assertEquals(index, e.getIndex()); assertTrue(e.getMessage().startsWith(mesStart)); assertTrue(e.getMessage().endsWith(mesEnd)); } } private PKIXCertPathValidatorResult doTest( String trustAnchor, String[] certs, String[] crls) throws Exception { return doTest(trustAnchor, certs, crls, null); } private PKIXCertPathValidatorResult doTest( String trustAnchor, String[] certs, String[] crls, Set policies) throws Exception { Set trustedSet = Collections.singleton(getTrustAnchor(trustAnchor)); List certsAndCrls = new ArrayList(); X509Certificate endCert = loadCert(certs[certs.length - 1]); for (int i = 0; i != certs.length - 1; i++) { certsAndCrls.add(loadCert(certs[i])); } certsAndCrls.add(endCert); CertPath certPath = CertificateFactory.getInstance("X.509","BC").generateCertPath(certsAndCrls); for (int i = 0; i != crls.length; i++) { certsAndCrls.add(loadCrl(crls[i])); } CertStore store = CertStore.getInstance("Collection", new CollectionCertStoreParameters(certsAndCrls), "BC"); CertPathValidator validator = CertPathValidator.getInstance("PKIX","BC"); PKIXParameters params = new PKIXParameters(trustedSet); params.addCertStore(store); params.setRevocationEnabled(true); params.setDate(new GregorianCalendar(2010, 1, 1).getTime()); if (policies != null) { params.setExplicitPolicyRequired(true); params.setInitialPolicies(policies); } return (PKIXCertPathValidatorResult)validator.validate(certPath, params); } private PKIXCertPathBuilderResult doBuilderTest( String trustAnchor, String[] certs, String[] crls, Set initialPolicies, boolean policyMappingInhibited, boolean anyPolicyInhibited) throws Exception { Set trustedSet = Collections.singleton(getTrustAnchor(trustAnchor)); List certsAndCrls = new ArrayList(); X509Certificate endCert = loadCert(certs[certs.length - 1]); for (int i = 0; i != certs.length - 1; i++) { certsAndCrls.add(loadCert(certs[i])); } certsAndCrls.add(endCert); for (int i = 0; i != crls.length; i++) { certsAndCrls.add(loadCrl(crls[i])); } CertStore store = CertStore.getInstance("Collection", new CollectionCertStoreParameters(certsAndCrls), "BC"); CertPathBuilder builder = CertPathBuilder.getInstance("PKIX", "BC"); X509CertSelector endSelector = new X509CertSelector(); endSelector.setCertificate(endCert); PKIXBuilderParameters builderParams = new PKIXBuilderParameters(trustedSet, endSelector); if (initialPolicies != null) { builderParams.setInitialPolicies(initialPolicies); builderParams.setExplicitPolicyRequired(true); } if (policyMappingInhibited) { builderParams.setPolicyMappingInhibited(policyMappingInhibited); } if (anyPolicyInhibited) { builderParams.setAnyPolicyInhibited(anyPolicyInhibited); } builderParams.addCertStore(store); builderParams.setDate(new GregorianCalendar(2010, 1, 1).getTime()); try { return (PKIXCertPathBuilderResult)builder.build(builderParams); } catch (CertPathBuilderException e) { throw (Exception)e.getCause(); } } private X509Certificate loadCert( String certName) { X509Certificate cert = (X509Certificate)certs.get(certName); if (cert != null) { return cert; } try { InputStream in = new FileInputStream(getPkitsHome() + "/certs/" + certName + ".crt"); CertificateFactory fact = CertificateFactory.getInstance("X.509", "BC"); cert = (X509Certificate)fact.generateCertificate(in); certs.put(certName, cert); return cert; } catch (Exception e) { throw new IllegalStateException("exception loading certificate " + certName + ": " + e); } } private X509CRL loadCrl( String crlName) throws Exception { X509CRL crl = (X509CRL)certs.get(crlName); if (crl != null) { return crl; } try { InputStream in = new FileInputStream(getPkitsHome() + "/crls/" + crlName + ".crl"); CertificateFactory fact = CertificateFactory.getInstance("X.509", "BC"); crl = (X509CRL)fact.generateCRL(in); crls.put(crlName, crl); return crl; } catch (Exception e) { throw new IllegalStateException("exception loading CRL: " + crlName); } } private TrustAnchor getTrustAnchor(String trustAnchorName) throws Exception { X509Certificate cert = loadCert(trustAnchorName); byte[] extBytes = cert.getExtensionValue(X509Extension.nameConstraints.getId()); if (extBytes != null) { ASN1Encodable extValue = X509ExtensionUtil.fromExtensionValue(extBytes); return new TrustAnchor(cert, extValue.toASN1Primitive().getEncoded(ASN1Encoding.DER)); } return new TrustAnchor(cert, null); } private String getPkitsHome() { String dataHome = System.getProperty(TEST_DATA_HOME); if (dataHome == null) { throw new IllegalStateException(TEST_DATA_HOME + " property not set"); } return dataHome + "/PKITS"; } public static void main (String[] args) throws Exception { junit.textui.TestRunner.run(suite()); } public static Test suite() throws Exception { TestSuite suite = new TestSuite("NIST CertPath Tests"); suite.addTestSuite(NistCertPathTest.class); return suite; } } bouncycastle-1.49.orig/test/src/org/bouncycastle/jce/provider/test/AlgorithmParametersTest.java0000644000175000017500000000560110544114001032500 0ustar ebourgebourgpackage org.bouncycastle.jce.provider.test; import org.bouncycastle.jce.provider.BouncyCastleProvider; import org.bouncycastle.util.encoders.Base64; import org.bouncycastle.util.test.SimpleTest; import java.io.IOException; import java.security.AlgorithmParameters; import java.security.Security; import java.security.spec.AlgorithmParameterSpec; import java.security.spec.DSAParameterSpec; import java.security.spec.InvalidParameterSpecException; public class AlgorithmParametersTest extends SimpleTest { private byte[] dsaParams = Base64.decode( "MIGcAkEAjfKklEkidqo9JXWbsGhpy+rA2Dr7jQz3y7gyTw14guXQdi/FtyEOr8Lprawyq3qsSWk9+/g3J" + "MLsBzbuMcgCkQIVAMdzIYxzfsjumTtPLe0w9I7azpFfAkBP3Z9K7oNeZMXEXYpqvrMUgVdFjq4lnWJoV8" + "Rwe+TERStHTkqSO7sp0lq7EEggVMcuXtarKNsxaJ+qyYv/n1t6"); private void basicTest(String algorithm, Class algorithmParameterSpec, byte[] asn1Encoded) throws Exception { AlgorithmParameters alg = AlgorithmParameters.getInstance(algorithm, "BC"); alg.init(asn1Encoded); try { alg.init(asn1Encoded); fail("encoded re-initialization not detected"); } catch (IOException e) { // expected already initialized } AlgorithmParameterSpec spec = alg.getParameterSpec(algorithmParameterSpec); try { alg.init(spec); fail("spec re-initialization not detected"); } catch (InvalidParameterSpecException e) { // expected already initialized } try { spec = alg.getParameterSpec(AlgorithmParameterSpec.class); fail("wrong spec not detected"); } catch (InvalidParameterSpecException e) { // expected unknown object } try { spec = alg.getParameterSpec(null); fail("null spec not detected"); } catch (NullPointerException e) { // expected unknown object } alg = AlgorithmParameters.getInstance(algorithm, "BC"); alg.init(asn1Encoded, "ASN.1"); alg = AlgorithmParameters.getInstance(algorithm, "BC"); alg.init(asn1Encoded, null); alg = AlgorithmParameters.getInstance(algorithm, "BC"); try { alg.init(asn1Encoded, "FRED"); fail("unknown spec not detected"); } catch (IOException e) { // expected already initialized } } public void performTest() throws Exception { basicTest("DSA", DSAParameterSpec.class, dsaParams); } public String getName() { return "AlgorithmParameters"; } public static void main( String[] args) { Security.addProvider(new BouncyCastleProvider()); runTest(new AlgorithmParametersTest()); } } bouncycastle-1.49.orig/test/src/org/bouncycastle/jce/provider/test/BaseBlockCipherTest.java0000644000175000017500000001010410565525753031527 0ustar ebourgebourgpackage org.bouncycastle.jce.provider.test; import org.bouncycastle.util.encoders.Hex; import org.bouncycastle.util.test.SimpleTest; import org.bouncycastle.util.test.TestFailedException; import javax.crypto.Cipher; import javax.crypto.KeyGenerator; import javax.crypto.SecretKey; import javax.crypto.spec.IvParameterSpec; import javax.crypto.spec.SecretKeySpec; import java.security.Key; public abstract class BaseBlockCipherTest extends SimpleTest { String algorithm; BaseBlockCipherTest( String algorithm) { this.algorithm = algorithm; } public String getName() { return algorithm; } protected void oidTest(String[] oids, String[] names, int groupSize) throws Exception { byte[] data = {1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16}; IvParameterSpec ivSpec = new IvParameterSpec(new byte[16]); for (int i = 0; i != oids.length; i++) { Cipher c1 = Cipher.getInstance(oids[i], "BC"); Cipher c2 = Cipher.getInstance(names[i], "BC"); KeyGenerator kg = KeyGenerator.getInstance(oids[i], "BC"); SecretKey k = kg.generateKey(); if (names[i].indexOf("/ECB/") > 0) { c1.init(Cipher.ENCRYPT_MODE, k); c2.init(Cipher.DECRYPT_MODE, k); } else { c1.init(Cipher.ENCRYPT_MODE, k, ivSpec); c2.init(Cipher.DECRYPT_MODE, k, ivSpec); } byte[] result = c2.doFinal(c1.doFinal(data)); if (!areEqual(data, result)) { fail("failed OID test"); } if (k.getEncoded().length != (16 + ((i / groupSize) * 8))) { fail("failed key length test"); } } } protected void wrapOidTest(String[] oids, String name) throws Exception { byte[] data = {1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16}; for (int i = 0; i != oids.length; i++) { Cipher c1 = Cipher.getInstance(oids[i], "BC"); Cipher c2 = Cipher.getInstance(name, "BC"); KeyGenerator kg = KeyGenerator.getInstance(oids[i], "BC"); SecretKey k = kg.generateKey(); c1.init(Cipher.WRAP_MODE, k); c2.init(Cipher.UNWRAP_MODE, k); Key wKey = c2.unwrap(c1.wrap(new SecretKeySpec(data, algorithm)), algorithm, Cipher.SECRET_KEY); if (!areEqual(data, wKey.getEncoded())) { fail("failed wrap OID test"); } if (k.getEncoded().length != (16 + (i * 8))) { fail("failed key length test"); } } } protected void wrapTest( int id, String wrappingAlgorithm, byte[] kek, byte[] in, byte[] out) throws Exception { Cipher wrapper = Cipher.getInstance(wrappingAlgorithm, "BC"); wrapper.init(Cipher.WRAP_MODE, new SecretKeySpec(kek, algorithm)); try { byte[] cText = wrapper.wrap(new SecretKeySpec(in, algorithm)); if (!areEqual(cText, out)) { fail("failed wrap test " + id + " expected " + new String(Hex.encode(out)) + " got " + new String(Hex.encode(cText))); } } catch (TestFailedException e) { throw e; } catch (Exception e) { fail("failed wrap test exception " + e.toString(), e); } wrapper.init(Cipher.UNWRAP_MODE, new SecretKeySpec(kek, algorithm)); try { Key pText = wrapper.unwrap(out, algorithm, Cipher.SECRET_KEY); if (!areEqual(pText.getEncoded(), in)) { fail("failed unwrap test " + id + " expected " + new String(Hex.encode(in)) + " got " + new String(Hex.encode(pText.getEncoded()))); } } catch (Exception e) { fail("failed unwrap test exception " + e.toString(), e); } } } bouncycastle-1.49.orig/test/src/org/bouncycastle/jce/provider/test/HMacTest.java0000644000175000017500000001467412110630056027354 0ustar ebourgebourgpackage org.bouncycastle.jce.provider.test; import java.security.InvalidAlgorithmParameterException; import java.security.InvalidKeyException; import java.security.Security; import javax.crypto.KeyGenerator; import javax.crypto.Mac; import javax.crypto.SecretKey; import javax.crypto.spec.RC5ParameterSpec; import javax.crypto.spec.SecretKeySpec; import org.bouncycastle.jce.provider.BouncyCastleProvider; import org.bouncycastle.util.encoders.Hex; import org.bouncycastle.util.test.SimpleTest; import org.bouncycastle.asn1.iana.IANAObjectIdentifiers; import org.bouncycastle.asn1.pkcs.PKCSObjectIdentifiers; /** * HMAC tester */ public class HMacTest extends SimpleTest { static byte[] keyBytes = Hex.decode("0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b"); static byte[] message = "Hi There".getBytes(); static byte[] output1 = Hex.decode("b617318655057264e28bc0b6fb378c8ef146be00"); static byte[] outputMD5 = Hex.decode("5ccec34ea9656392457fa1ac27f08fbc"); static byte[] outputMD2 = Hex.decode("dc1923ef5f161d35bef839ca8c807808"); static byte[] outputMD4 = Hex.decode("5570ce964ba8c11756cdc3970278ff5a"); static byte[] output224 = Hex.decode("896fb1128abbdf196832107cd49df33f47b4b1169912ba4f53684b22"); static byte[] output256 = Hex.decode("b0344c61d8db38535ca8afceaf0bf12b881dc200c9833da726e9376c2e32cff7"); static byte[] output384 = Hex.decode("afd03944d84895626b0825f4ab46907f15f9dadbe4101ec682aa034c7cebc59cfaea9ea9076ede7f4af152e8b2fa9cb6"); static byte[] output512 = Hex.decode("87aa7cdea5ef619d4ff0b4241a1d6cb02379f4e2ce4ec2787ad0b30545e17cdedaa833b7d6b8a702038b274eaea3f4e4be9d914eeb61f1702e696c203a126854"); static byte[] output512_224 = Hex.decode("b244ba01307c0e7a8ccaad13b1067a4cf6b961fe0c6a20bda3d92039"); static byte[] output512_256 = Hex.decode("9f9126c3d9c3c330d760425ca8a217e31feae31bfe70196ff81642b868402eab"); static byte[] outputRipeMD128 = Hex.decode("fda5717fb7e20cf05d30bb286a44b05d"); static byte[] outputRipeMD160 = Hex.decode("24cb4bd67d20fc1a5d2ed7732dcc39377f0a5668"); static byte[] outputTiger = Hex.decode("1d7a658c75f8f004916e7b07e2a2e10aec7de2ae124d3647"); static byte[] outputOld384 = Hex.decode("0a046aaa0255e432912228f8ccda437c8a8363fb160afb0570ab5b1fd5ddc20eb1888b9ed4e5b6cb5bc034cd9ef70e40"); static byte[] outputOld512 = Hex.decode("9656975ee5de55e75f2976ecce9a04501060b9dc22a6eda2eaef638966280182477fe09f080b2bf564649cad42af8607a2bd8d02979df3a980f15e2326a0a22a"); public HMacTest() { } public void testHMac( String hmacName, byte[] output) throws Exception { SecretKey key = new SecretKeySpec(keyBytes, hmacName); byte[] out; Mac mac; mac = Mac.getInstance(hmacName, "BC"); mac.init(key); mac.reset(); mac.update(message, 0, message.length); out = mac.doFinal(); if (!areEqual(out, output)) { fail("Failed - expected " + new String(Hex.encode(output)) + " got " + new String(Hex.encode(out))); } // no key generator for the old algorithms if (hmacName.startsWith("Old")) { return; } KeyGenerator kGen = KeyGenerator.getInstance(hmacName, "BC"); mac.init(kGen.generateKey()); mac.update(message); out = mac.doFinal(); } private void testExceptions() throws Exception { Mac mac = null; mac = Mac.getInstance("HmacSHA1", "BC"); byte [] b = {(byte)1, (byte)2, (byte)3, (byte)4, (byte)5}; SecretKeySpec sks = new SecretKeySpec(b, "HmacSHA1"); RC5ParameterSpec algPS = new RC5ParameterSpec(100, 100, 100); try { mac.init(sks, algPS); } catch (InvalidAlgorithmParameterException e) { // ignore okay } try { mac.init(null, null); } catch (InvalidKeyException e) { // ignore okay } catch (InvalidAlgorithmParameterException e) { // ignore okay } try { mac.init(null); } catch (InvalidKeyException e) { // ignore okay } } public void performTest() throws Exception { testHMac("HMac-SHA1", output1); testHMac("HMac-MD5", outputMD5); testHMac("HMac-MD4", outputMD4); testHMac("HMac-MD2", outputMD2); testHMac("HMac-SHA224", output224); testHMac("HMac-SHA256", output256); testHMac("HMac-SHA384", output384); testHMac("HMac-SHA512", output512); testHMac("HMac-SHA512/224", output512_224); testHMac("HMac-SHA512/256", output512_256); testHMac("HMac-RIPEMD128", outputRipeMD128); testHMac("HMac-RIPEMD160", outputRipeMD160); testHMac("HMac-TIGER", outputTiger); testHMac("HMac/SHA1", output1); testHMac("HMac/MD5", outputMD5); testHMac("HMac/MD4", outputMD4); testHMac("HMac/MD2", outputMD2); testHMac("HMac/SHA224", output224); testHMac("HMac/SHA256", output256); testHMac("HMac/SHA384", output384); testHMac("HMac/SHA512", output512); testHMac("HMac/RIPEMD128", outputRipeMD128); testHMac("HMac/RIPEMD160", outputRipeMD160); testHMac("HMac/TIGER", outputTiger); testHMac(PKCSObjectIdentifiers.id_hmacWithSHA1.getId(), output1); testHMac(PKCSObjectIdentifiers.id_hmacWithSHA224.getId(), output224); testHMac(PKCSObjectIdentifiers.id_hmacWithSHA256.getId(), output256); testHMac(PKCSObjectIdentifiers.id_hmacWithSHA384.getId(), output384); testHMac(PKCSObjectIdentifiers.id_hmacWithSHA512.getId(), output512); testHMac(IANAObjectIdentifiers.hmacSHA1.getId(), output1); testHMac(IANAObjectIdentifiers.hmacMD5.getId(), outputMD5); testHMac(IANAObjectIdentifiers.hmacRIPEMD160.getId(), outputRipeMD160); testHMac(IANAObjectIdentifiers.hmacTIGER.getId(), outputTiger); // test for compatibility with broken HMac. testHMac("OldHMacSHA384", outputOld384); testHMac("OldHMacSHA512", outputOld512); testExceptions(); } public String getName() { return "HMac"; } public static void main( String[] args) { Security.addProvider(new BouncyCastleProvider()); runTest(new HMacTest()); } } bouncycastle-1.49.orig/test/src/org/bouncycastle/jce/provider/test/NISTCertPathTest.java0000644000175000017500000122473611251142567030771 0ustar ebourgebourgpackage org.bouncycastle.jce.provider.test; import java.io.ByteArrayInputStream; import java.security.GeneralSecurityException; import java.security.Security; import java.security.cert.CertPathBuilder; import java.security.cert.CertPathBuilderResult; import java.security.cert.CertStore; import java.security.cert.CertificateFactory; import java.security.cert.CollectionCertStoreParameters; import java.security.cert.PKIXBuilderParameters; import java.security.cert.TrustAnchor; import java.security.cert.X509CRL; import java.security.cert.X509CertSelector; import java.security.cert.X509Certificate; import java.util.HashSet; import java.util.Set; import java.util.Vector; import org.bouncycastle.asn1.ASN1InputStream; import org.bouncycastle.asn1.ASN1OctetString; import org.bouncycastle.jce.provider.BouncyCastleProvider; import org.bouncycastle.util.encoders.Base64; import org.bouncycastle.util.test.SimpleTest; /* * These tests are taken from the NIST X.509 Validation Test Suite * available at: http://csrc.nist.gov/pki/testing/x509paths.html * * Only the relevant certificate and crl data has been kept, in order * to keep the class size to a minimum. * */ public class NISTCertPathTest extends SimpleTest { private static final String TEST_POLICY_1 = "2.16.840.1.101.3.1.48.1"; private static final String TEST_POLICY_2 = "2.16.840.1.101.3.1.48.2"; private static final String TEST_POLICY_3 = "2.16.840.1.101.3.1.48.3"; private static final String TEST_POLICY_4 = "2.16.840.1.101.3.1.48.4"; private static final String TEST_POLICY_5 = "2.16.840.1.101.3.1.48.5"; private static Set ANY; private static Set TP1; private static Set TP2; private static Set TP3; private static Set TP4; private static Set TP1_TP2; static { ANY = new HashSet(); TP1 = new HashSet(); TP1.add(TEST_POLICY_1); TP2 = new HashSet(); TP2.add(TEST_POLICY_2); TP3 = new HashSet(); TP3.add(TEST_POLICY_3); TP4 = new HashSet(); TP4.add(TEST_POLICY_4); TP1_TP2 = new HashSet(); TP1_TP2.add(TEST_POLICY_1); TP1_TP2.add(TEST_POLICY_2); } /* * * FIELDS * */ private CertificateFactory fact; private X509Certificate trustedCert; private X509CRL trustedCRL; private Set trustedSet; private int testCount; private Vector testFail; private StringBuffer resultBuf; public String getName() { return "NISTCertPathTest"; } public void performTest() { init(); test(" 1", TEST_1_DATA , true , false); test(" 2", TEST_2_DATA , false, false); test(" 3", TEST_3_DATA , false, false); test(" 4", TEST_4_DATA , true , false); test(" 5", TEST_5_DATA , false, false); test(" 6", TEST_6_DATA , false, false); test(" 7", TEST_7_DATA , true , false); test(" 8", TEST_8_DATA , false, false); test(" 9", TEST_9_DATA , false, false); test("10", TEST_10_DATA, false, false); test("11", TEST_11_DATA, false, false); test("12", TEST_12_DATA, true , false); test("13", TEST_13_DATA, false, false); test("14", TEST_14_DATA, false, false); test("15", TEST_15_DATA, true , false); test("16", TEST_16_DATA, true , false); test("17", TEST_17_DATA, true , false); test("18", TEST_18_DATA, true , false); test("19", TEST_19_DATA, false, false); test("20", TEST_20_DATA, false, false); test("21", TEST_21_DATA, false, false); test("22", TEST_22_DATA, false, false); test("23", TEST_23_DATA, false, false); test("24", TEST_24_DATA, true , false); test("25", TEST_25_DATA, false, false); test("26", TEST_26_DATA, true , false); test("27", TEST_27_DATA, true , false); test("28", TEST_28_DATA, false, false); test("29", TEST_29_DATA, false, false); test("30", TEST_30_DATA, true , false); test("31", TEST_31_DATA, false, false); test("32", TEST_32_DATA, false, false); test("33", TEST_33_DATA, true , false); test("34a", TEST_34_DATA, ANY , true , true , false); test("34b", TEST_34_DATA, ANY , false, true , false); test("34c", TEST_34_DATA, TP1 , true , true , false); test("34d", TEST_34_DATA, TP1 , false, true , false); test("34e", TEST_34_DATA, TP2 , true , false, false); test("34f", TEST_34_DATA, TP2 , false, true , false); test("35a", TEST_35_DATA, false, true , false); test("35b", TEST_35_DATA, true , false, false); test("36a", TEST_36_DATA, false, true , false); test("36b", TEST_36_DATA, true , false, false); test("37a", TEST_37_DATA, false, true , false); test("37b", TEST_37_DATA, true , false, false); test("38a", TEST_38_DATA, false, true , false); test("38b", TEST_38_DATA, true , false, false); test("39a", TEST_39_DATA, ANY , true , true , false); test("39b", TEST_39_DATA, ANY , false, true , false); test("39c", TEST_39_DATA, TP1 , true , true , false); test("39d", TEST_39_DATA, TP1 , false, true , false); test("39e", TEST_39_DATA, TP2 , true , false, false); test("39f", TEST_39_DATA, TP2 , false, true , false); test("40a", TEST_40_DATA, false, true , false); test("40b", TEST_40_DATA, true , false, false); test("41a", TEST_41_DATA, false, true , false); test("41b", TEST_41_DATA, true , false, false); test("42a", TEST_42_DATA, false, true , false); test("42b", TEST_42_DATA, true , false, false); test("43a", TEST_43_DATA, false, true , false); test("43b", TEST_43_DATA, true , false, false); test("44a", TEST_44_DATA, false, true , false); test("44b", TEST_44_DATA, true , false, false); test("45a", TEST_45_DATA, false, false, false); test("45b", TEST_45_DATA, true , false, false); test("46a", TEST_46_DATA, ANY , false, true , false); test("46b", TEST_46_DATA, ANY , true , true , false); test("46c", TEST_46_DATA, TP1 , true , true , false); test("46d", TEST_46_DATA, TP1 , false, true , false); test("46e", TEST_46_DATA, TP2 , true , false, false); test("46f", TEST_46_DATA, TP2 , false, false, false); test("47a", TEST_47_DATA, false, false, false); test("47b", TEST_47_DATA, true , false, false); test("48a", TEST_48_DATA, TP1 , false, true , false); test("48b", TEST_48_DATA, TP1 , true , true , false); test("48c", TEST_48_DATA, ANY , false, true , false); test("48d", TEST_48_DATA, ANY , true , true , false); test("48e", TEST_48_DATA, TP2 , false, true , false); test("48f", TEST_48_DATA, TP2 , true , false, false); test("49a", TEST_49_DATA, TP1 , false, true , false); test("49b", TEST_49_DATA, TP1 , true , true , false); test("49c", TEST_49_DATA, TP3 , false, true , false); test("49d", TEST_49_DATA, TP3 , true , false, false); test("49e", TEST_49_DATA, ANY , false, true , false); test("49f", TEST_49_DATA, ANY , true , true , false); test("50a", TEST_50_DATA, TP1 , false, true , false); test("50b", TEST_50_DATA, TP1 , true , true , false); test("50c", TEST_50_DATA, TP1_TP2 , false, true , false); test("50d", TEST_50_DATA, TP1_TP2 , true , true , false); test("50e", TEST_50_DATA, ANY , false, true , false); test("50f", TEST_50_DATA, ANY , true , true , false); test("51a", TEST_51_DATA, false, true , false); test("51b", TEST_51_DATA, true , false, false); test("52a", TEST_52_DATA, TP1 , false, true , false); test("52b", TEST_52_DATA, TP1 , true , false, false); test("52c", TEST_52_DATA, TP1_TP2 , false, true , false); test("52d", TEST_52_DATA, TP1_TP2 , true , false, false); test("52e", TEST_52_DATA, ANY , false, true , false); test("52f", TEST_52_DATA, ANY , true , true , false); test("53a", TEST_53_DATA, TP1 , false, true , false); test("53b", TEST_53_DATA, TP1 , true , true , false); test("53c", TEST_53_DATA, TP1_TP2 , false, true , false); test("53d", TEST_53_DATA, TP1_TP2 , true , true , false); test("53e", TEST_53_DATA, TP4 , false, true , false); test("53f", TEST_53_DATA, TP4 , true , false, false); test("53g", TEST_53_DATA, ANY , false, true , false); test("53h", TEST_53_DATA, ANY , true , true , false); test("54", TEST_54_DATA, false, false); test("55", TEST_55_DATA, false, false); test("56", TEST_56_DATA, true , false); test("57", TEST_57_DATA, true , false); test("58", TEST_58_DATA, false, false); test("59", TEST_59_DATA, false, false); test("60", TEST_60_DATA, false, false); test("61", TEST_61_DATA, false, false); test("62", TEST_62_DATA, true , false); test("63", TEST_63_DATA, true , false); test("64", TEST_64_DATA, false, false); test("65", TEST_65_DATA, false, false); test("66", TEST_66_DATA, false, false); test("67", TEST_67_DATA, true , false); test("68", TEST_68_DATA, false, false); test("69", TEST_69_DATA, false, false); test("70", TEST_70_DATA, false, false); test("71", TEST_71_DATA, false, false); test("72", TEST_72_DATA, false, false); test("73", TEST_73_DATA, false, false); test("74", TEST_74_DATA, true , false); test("75", TEST_75_DATA, false, false); test("76", TEST_76_DATA, false, false); resultBuf.append("NISTCertPathTest -- Failed: ").append(testFail.size()).append('/').append(testCount).append('\n'); if (!testFail.isEmpty()) { fail(resultBuf.toString()); } } private void init() { try { fact = CertificateFactory.getInstance("X.509", "BC"); trustedCert = (X509Certificate)fact .generateCertificate(new ByteArrayInputStream(Base64 .decode(Trust_Anchor_CP_01_01_crt))); trustedCRL = (X509CRL)fact.generateCRL(new ByteArrayInputStream( Base64.decode(Trust_Anchor_CRL_CP_01_01_crl))); trustedSet = new HashSet(); byte[] _ncBytes = null; byte[] _octBytes = trustedCert.getExtensionValue("2.5.29.30"); if (_octBytes != null) { ASN1InputStream _ais = new ASN1InputStream( new ByteArrayInputStream(_octBytes)); ASN1OctetString _oct = ASN1OctetString.getInstance(_ais .readObject()); _ais.close(); _ncBytes = _oct.getOctets(); } trustedSet.add(new TrustAnchor(trustedCert, _ncBytes)); testCount = 0; testFail = new Vector(); resultBuf = new StringBuffer(); } catch (Exception ex) { throw new RuntimeException(ex.getMessage()); } } private X509Certificate decodeCertificate(String _str) throws GeneralSecurityException { return (X509Certificate)fact .generateCertificate(new ByteArrayInputStream(Base64 .decode(_str))); } private X509CRL decodeCRL(String _str) throws GeneralSecurityException { return (X509CRL)fact.generateCRL(new ByteArrayInputStream(Base64 .decode(_str))); } private CertStore makeCertStore(String[] _strs) throws GeneralSecurityException { Vector _vec = new Vector(); _vec.addElement(trustedCRL); for (int i = 0; i < _strs.length; i++) { if (_strs[i].startsWith("MIIC")) { _vec.addElement(fact .generateCertificate(new ByteArrayInputStream(Base64 .decode(_strs[i])))); } else if (_strs[i].startsWith("MIIB")) { _vec.addElement(fact.generateCRL(new ByteArrayInputStream( Base64.decode(_strs[i])))); } else { throw new IllegalArgumentException("Invalid certificate or crl"); } } // Insert elements backwards to muck up forward ordering dependency Vector _vec2 = new Vector(); for (int i = _vec.size() - 1; i >= 0; i--) { _vec2.add(_vec.elementAt(i)); } return CertStore.getInstance("Collection", new CollectionCertStoreParameters(_vec2), "BC"); } private void test(String _name, String[] _data, boolean _accept, boolean _debug) { test(_name, _data, null, false, _accept, _debug); } private void test(String _name, String[] _data, boolean _explicit, boolean _accept, boolean _debug) { test(_name, _data, null, _explicit, _accept, _debug); } private void test(String _name, String[] _data, Set _ipolset, boolean _explicit, boolean _accept, boolean _debug) { testCount++; boolean _pass = true; try { CertPathBuilder _cpb = CertPathBuilder.getInstance("PKIX", "BC"); X509Certificate _ee = decodeCertificate(_data[_data.length - 1]); X509CertSelector _select = new X509CertSelector(); _select.setSubject(_ee.getSubjectX500Principal().getEncoded()); PKIXBuilderParameters _param = new PKIXBuilderParameters( trustedSet, _select); _param.setExplicitPolicyRequired(_explicit); _param.addCertStore(makeCertStore(_data)); _param.setRevocationEnabled(true); if (_ipolset != null) { _param.setInitialPolicies(_ipolset); } CertPathBuilderResult _result = _cpb.build(_param); if (!_accept) { System.out.println("Accept when it should reject"); _pass = false; testFail.addElement(_name); } } catch (Exception ex) { if (_accept) { System.out.println("Reject when it should accept"); _pass = false; testFail.addElement(_name); } } resultBuf.append("NISTCertPathTest -- ").append(_name).append(": ") .append(_pass ? "\n" : "Failed.\n"); } public static void main( String[] args) { Security.addProvider(new BouncyCastleProvider()); runTest(new NISTCertPathTest()); } /* * Trust Anchor * */ public static final String Trust_Anchor_CP_01_01_crt = "MIICbDCCAdWgAwIBAgIDAYafMA0GCSqGSIb3DQEBBQUAMF4xCzAJBgNVBAYTAlVTMRgwFg" + "YDVQQKEw9VLlMuIEdvdmVybm1lbnQxDDAKBgNVBAsTA0RvRDEQMA4GA1UECxMHVGVzdGlu" + "ZzEVMBMGA1UEAxMMVHJ1c3QgQW5jaG9yMB4XDTk5MDEwMTEyMDEwMFoXDTQ4MDEwMTEyMD" + "EwMFowXjELMAkGA1UEBhMCVVMxGDAWBgNVBAoTD1UuUy4gR292ZXJubWVudDEMMAoGA1UE" + "CxMDRG9EMRAwDgYDVQQLEwdUZXN0aW5nMRUwEwYDVQQDEwxUcnVzdCBBbmNob3IwgZ8wDQ" + "YJKoZIhvcNAQEBBQADgY0AMIGJAoGBANPzucEztz+nJ/ZBHVyceZ2q0pUQt4TO2qPlWAw+" + "TotWvz6qIS1QE/7zGS56yxHP89O4X1efnZeArx2VVxLfNNS9865N53ymINQETtpjYT49Ko" + "03z8U8yfn68DlIBHi9sN31JEYzoUafF58Eu883lAwTQ6qQrJF4HbrzGIQqgitHAgMBAAGj" + "ODA2MBEGA1UdDgQKBAirmuv5wudUjzAMBgNVHRMEBTADAQH/MBMGA1UdIwQMMAqACKua6/" + "nC51SPMA0GCSqGSIb3DQEBBQUAA4GBABZWD2Gsh4tP62QSG8OFWUpo4TulIcFZLpGsaP4T" + "/2Nt7lXUoIJMN7wWjqkmYf5/Rvo4HxNcimq3EkeYcrm1VoDueJUYGvRjcCY5mxkghI27Yl" + "/fLKE9/BvQOrvYzBs2EqKrrT7m4VK0dRMR7CeVpmPP08z0Tti6uK2tzBplp1pF"; public static final String Trust_Anchor_CRL_CP_01_01_crl = "MIIBbzCB2QIBATANBgkqhkiG9w0BAQUFADBeMQswCQYDVQQGEwJVUzEYMBYGA1UEChMPVS" + "5TLiBHb3Zlcm5tZW50MQwwCgYDVQQLEwNEb0QxEDAOBgNVBAsTB1Rlc3RpbmcxFTATBgNV" + "BAMTDFRydXN0IEFuY2hvchcNOTkwMTAxMTIwMTAwWhcNNDgwMTAxMTIwMTAwWjAiMCACAS" + "cXDTk5MDEwMTEyMDAwMFowDDAKBgNVHRUEAwoBAaAjMCEwCgYDVR0UBAMCAQEwEwYDVR0j" + "BAwwCoAIq5rr+cLnVI8wDQYJKoZIhvcNAQEFBQADgYEAC7lqZwejJRW7QvzH11/7cYcL3r" + "acgMxH3PSU/ufvyLk7ahR++RtHary/WeCvRdyznLiIOA8ZBiguWtVPqsNysNn7WLofQIVa" + "+/TD3T+lece4e1NwGQvj5Q+e2wRtGXg+gCuTjTKUFfKRnWz7O7RyiJKKim0jtAF4RkCpLe" + "bNChY="; /* * test1 * */ public static final String End_Certificate_CP_01_01_crt = "MIIChjCCAe+gAwIBAgIBATANBgkqhkiG9w0BAQUFADBeMQswCQYDVQQGEwJVUzEYMBYGA1" + "UEChMPVS5TLiBHb3Zlcm5tZW50MQwwCgYDVQQLEwNEb0QxEDAOBgNVBAsTB1Rlc3Rpbmcx" + "FTATBgNVBAMTDFRydXN0IEFuY2hvcjAeFw05ODAxMDExMjAxMDBaFw00ODAxMDExMjAxMD" + "BaMGAxCzAJBgNVBAYTAlVTMRgwFgYDVQQKEw9VLlMuIEdvdmVybm1lbnQxDDAKBgNVBAsT" + "A0RvRDEQMA4GA1UECxMHVGVzdGluZzEXMBUGA1UEAxMOVXNlcjEtQ1AuMDEuMDEwgZ8wDQ" + "YJKoZIhvcNAQEBBQADgY0AMIGJAoGBAMY07G8M4FkOvF+6LpO7BKcDuXCKudfl1+bKSowj" + "2GCza8uIiMfYSH5k+fYb43lGQeRh9yVHcfNQlE7yfGo3tgxGv5yWpeKvDMqL8Iy6Q0oIjm" + "qH80ZOz21dUkermcckzTEOfe/R2fNpJPv8M24pq29SdYAqu+CpLDHFtws9O+q1AgMBAAGj" + "UjBQMA4GA1UdDwEB/wQEAwIF4DAWBgNVHSAEDzANMAsGCWCGSAFlAwEwATARBgNVHQ4ECg" + "QIrNv88bwFLtIwEwYDVR0jBAwwCoAIq5rr+cLnVI8wDQYJKoZIhvcNAQEFBQADgYEAK4hP" + "goWtZbHf6qWfRfmrPrz9hDH1644NrJop2Y7MXzuTtpo1zp4NCG4+ii0CSOfvhugc8yOmq3" + "I6olgE0V16VtC5br2892UHYZ55Q4oQ9BWouVVlOyY9rogOB160BnsqBELFhT0Wf6mnbsdD" + "G+BB5fFyeK61aYDWV84kS7cSX5w="; public static final String[] TEST_1_DATA = new String[] { End_Certificate_CP_01_01_crt, }; /* * test2 * */ public static final String Intermediate_Certificate_CP_01_02_crt = "MIIClTCCAf6gAwIBAgIBAjANBgkqhkiG9w0BAQUFADBeMQswCQYDVQQGEwJVUzEYMBYGA1" + "UEChMPVS5TLiBHb3Zlcm5tZW50MQwwCgYDVQQLEwNEb0QxEDAOBgNVBAsTB1Rlc3Rpbmcx" + "FTATBgNVBAMTDFRydXN0IEFuY2hvcjAeFw05ODAxMDExMjAxMDBaFw00ODAxMDExMjAxMD" + "BaMF4xCzAJBgNVBAYTAlVTMRgwFgYDVQQKEw9VLlMuIEdvdmVybm1lbnQxDDAKBgNVBAsT" + "A0RvZDEQMA4GA1UECxMHVGVzdGluZzEVMBMGA1UEAxMMQ0ExLUNQLjAxLjAyMIGfMA0GCS" + "qGSIb3DQEBAQUAA4GNADCBiQKBgQDWOZ4hk+K6NX/l+OiHC4pfKCWFt+XM2n/TxwkqY+mt" + "j9Co77rPPPtVA7mDKU4OiYT74mIWH52HQBZr+PRmOFh0Z9S1oTpLbxNLCDc6OmQKBo6iex" + "SIt/jOatFFmzmTZ78Kq9s3nfrOVA83ggmPDTPkuG5GwcxPgFq0vRmAJ0CESQIDAQABo2Mw" + "YTAPBgNVHRMBAf8EBTADAQH/MA4GA1UdDwEB/wQEAwIBBjAWBgNVHSAEDzANMAsGCWCGSA" + "FlAwEwATARBgNVHQ4ECgQI5o5Am09NlOYwEwYDVR0jBAwwCoAIq5rr+cLnVI8wDQYJKoZI" + "hvcNAQEFBQADgYEA3C7Ye5/Te14LIwo/LK2fnpobbQA3dhOn5UgqZ8lKbQ/HV1D8/eU9dK" + "2v5gW43XvFq4whK0WKLBvBFchKtp9T1QX3CI2WCqdJRyqla6TkQsS36T17/ww2nzy1853Y" + "hfDYNsge5XW8YZNfNjjVxcR3RnyFxPax1YIlISiGdI0dnag="; public static final String Intermediate_CRL_CP_01_02_crl = "MIIBSzCBtQIBATANBgkqhkiG9w0BAQUFADBeMQswCQYDVQQGEwJVUzEYMBYGA1UEChMPVS" + "5TLiBHb3Zlcm5tZW50MQwwCgYDVQQLEwNEb2QxEDAOBgNVBAsTB1Rlc3RpbmcxFTATBgNV" + "BAMTDENBMS1DUC4wMS4wMhcNOTkwMTAxMTIwMTAwWhcNNDgwMTAxMTIwMTAwWqAjMCEwCg" + "YDVR0UBAMCAQEwEwYDVR0jBAwwCoAI5o5Am09NlOYwDQYJKoZIhvcNAQEFBQADgYEAl26W" + "g1Gqq3R93XPjghABVocfeIi8zcSJ0YAKqbifh5V3JCC8Piy19GzZdL244GqBDls44IAhKj" + "YuXN2mSohdqwULbye4agAgfl37XhhwsBDTYwaJiv3njFQ6Ml7KJ3STmoIpmlLvrXibDuHX" + "ocuNGo72ckhOdBpXd+PhgGuoTis="; public static final String End_Certificate_CP_01_02_crt = "MIIChjCCAe+gAwIBAgIBAzANBgkqhkiG9w0BAQUFADBeMQswCQYDVQQGEwJVUzEYMBYGA1" + "UEChMPVS5TLiBHb3Zlcm5tZW50MQwwCgYDVQQLEwNEb2QxEDAOBgNVBAsTB1Rlc3Rpbmcx" + "FTATBgNVBAMTDENBMS1DUC4wMS4wMjAeFw05ODAxMDExMjAxMDBaFw00ODAxMDExMjAxMD" + "BaMGAxCzAJBgNVBAYTAlVTMRgwFgYDVQQKEw9VLlMuIEdvdmVybm1lbnQxDDAKBgNVBAsT" + "A0RvRDEQMA4GA1UECxMHVGVzdGluZzEXMBUGA1UEAxMOVXNlcjEtQ1AuMDEuMDIwgZ8wDQ" + "YJKoZIhvcNAQEBBQADgY0AMIGJAoGBALwJrZT6bJXQnZzc3socZ/mNsEag4BTdym99ZCP2" + "3PGsTCfV2z7+p4DehIFrn/N/a1d1nvyqRqpQGPU86tl1CWgFtXS+zCctDR71P76bjd6yef" + "5vxxdO/SBIRHfQTjM8F3BTLkrC+PVl5wbaLcEXRORXrFvBvsj0oqwZ4C8ZObh/AgMBAAGj" + "UjBQMA4GA1UdDwEB/wQEAwIF4DAWBgNVHSAEDzANMAsGCWCGSAFlAwEwATARBgNVHQ4ECg" + "QIf5mSjuNhs/gwEwYDVR0jBAwwCoAI5o5Am09NlOYwDQYJKoZIhvcNAQEFBQADgYEAK7wd" + "MyLlIZ/Qsqj3/A3Gat0d5BORtFTZH0VdlVVOWN1JCZxrnjeIFB92NNzUROemxgBxzneuWN" + "SlYlcpTk25pAbs6RMdbT8dovKQkQkF2TXeQ+4qktFaLQntVT8UsEzHR4Diw0/gH8tseGqF" + "F7FyiW8ni6zInSO+embUKiibj9I="; public static final String[] TEST_2_DATA = new String[] { Intermediate_Certificate_CP_01_02_crt, Intermediate_CRL_CP_01_02_crl, End_Certificate_CP_01_02_crt }; /* * test3 * */ public static final String Intermediate_Certificate_CP_01_03_crt = "MIIClTCCAf6gAwIBAgIBBDANBgkqhkiG9w0BAQUFADBeMQswCQYDVQQGEwJVUzEYMBYGA1" + "UEChMPVS5TLiBHb3Zlcm5tZW50MQwwCgYDVQQLEwNEb0QxEDAOBgNVBAsTB1Rlc3Rpbmcx" + "FTATBgNVBAMTDFRydXN0IEFuY2hvcjAeFw05ODAxMDExMjAxMDBaFw00ODAxMDExMjAxMD" + "BaMF4xCzAJBgNVBAYTAlVTMRgwFgYDVQQKEw9VLlMuIEdvdmVybm1lbnQxDDAKBgNVBAsT" + "A0RvZDEQMA4GA1UECxMHVGVzdGluZzEVMBMGA1UEAxMMQ0ExLUNQLjAxLjAzMIGfMA0GCS" + "qGSIb3DQEBAQUAA4GNADCBiQKBgQC4RZ0R82sA+BfyynFeoIDG7c5IlZ8HorEv+O4Ij3Oy" + "7FR1MB4no8hDEBPBf5fCrAR/8PVxCZjVj2HOwnSAqUQgxo6WPcmkabux12k8kK6yeKq3b7" + "u5fL6tb7eKElQzsz8Je4z4rCDkI10vV+X0VZ5Ip/Es428dw2KoN8eyGmw3+QIDAQABo2Mw" + "YTAPBgNVHRMBAf8EBTADAQH/MA4GA1UdDwEB/wQEAwIBBjAWBgNVHSAEDzANMAsGCWCGSA" + "FlAwEwATARBgNVHQ4ECgQIz08WhMpG2JswEwYDVR0jBAwwCoAIq5rr+cLnVI8wDQYJKoZI" + "hvcNAQEFBQADgYEAQ+iqlFvbvDejO/m+RCHh2UuUau1FuABObkPOu2Tv9yTWvTSWDRygdO" + "LQRiOLsjgrdXPdbDutVGjllBoTN8cdz3SWjCpampg5TBikArxmNEYMDQvL6n2lkUcetRJR" + "gQ7TYLvFj9+SycKXfM5CUXAyCfcU/QwDghhZgc99AuDZtJc="; public static final String Intermediate_CRL_CP_01_03_crl = "MIIBSzCBtQIBATANBgkqhkiG9w0BAQUFADBeMQswCQYDVQQGEwJVUzEYMBYGA1UEChMPVS" + "5TLiBHb3Zlcm5tZW50MQwwCgYDVQQLEwNEb2QxEDAOBgNVBAsTB1Rlc3RpbmcxFTATBgNV" + "BAMTDENBMS1DUC4wMS4wMxcNOTkwMTAxMTIwMTAwWhcNNDgwMTAxMTIwMTAwWqAjMCEwCg" + "YDVR0UBAMCAQEwEwYDVR0jBAwwCoAIz08WhMpG2JswDQYJKoZIhvcNAQEFBQADgYEAoyO/" + "xcpJ0Obj4rTXhHFd7XMzslt79njkEgdwnon9BaYB3xSmkEXCMwLMurrjVYKaB6SWAiPeUv" + "G7ScDHJE6UFVJwIt4vP/M7gTOJ7uak33aWi9e5DeIuLqE6pFqTGu+uoBkkd82SHg2GhJhZ" + "VXDtJ3UcO/3JQPbslc02s9HiRBg="; public static final String End_Certificate_CP_01_03_crt = "MIIChjCCAe+gAwIBAgIBBTANBgkqhkiG9w0BAQUFADBeMQswCQYDVQQGEwJVUzEYMBYGA1" + "UEChMPVS5TLiBHb3Zlcm5tZW50MQwwCgYDVQQLEwNEb2QxEDAOBgNVBAsTB1Rlc3Rpbmcx" + "FTATBgNVBAMTDENBMS1DUC4wMS4wMzAeFw05ODAxMDExMjAxMDBaFw00ODAxMDExMjAxMD" + "BaMGAxCzAJBgNVBAYTAlVTMRgwFgYDVQQKEw9VLlMuIEdvdmVybm1lbnQxDDAKBgNVBAsT" + "A0RvRDEQMA4GA1UECxMHVGVzdGluZzEXMBUGA1UEAxMOVXNlcjEtQ1AuMDEuMDMwgZ8wDQ" + "YJKoZIhvcNAQEBBQADgY0AMIGJAoGBANAD1vQj//4BGEXW1Q7HX/AUyFJFyHoYcvg5y4u/" + "8Sj6okriXj3knnBKDiJLpKfcsO5p5MQS5QzAc+lxErXD+duiw8lm61hj0StsRzhDFsaC1g" + "akjzU70R2Tmz/djUnqO3aa2wICc4NVAXnIMMsH/b6XXFZpC0/C32TPTv9aa9mrAgMBAAGj" + "UjBQMA4GA1UdDwEB/wQEAwIF4DAWBgNVHSAEDzANMAsGCWCGSAFlAwEwATARBgNVHQ4ECg" + "QIPw2wltiRqz4wEwYDVR0jBAwwCoAIz08WhMpG2JswDQYJKoZIhvcNAQEFBQADgYEAln42" + "iR3eHyazF8CRjS9Jnas/26MaBtjUyDtcSjTVDWFlccwrQ7TgtzjkNm9fCmgSyvryDnUYGM" + "DoEjwYNLIgtCAkVIEBTmJvlqiPHH+tV5oJvIav+Fn8okHpuuK44umDcdKiFWlOyxrShxzV" + "3Bez/eHklaPTw/VsVhyh+Uru5zM="; public static final String[] TEST_3_DATA = new String[] { Intermediate_Certificate_CP_01_03_crt, Intermediate_CRL_CP_01_03_crl, End_Certificate_CP_01_03_crt }; /* * test4 * */ public static final String Intermediate_Certificate_1_CP_02_01_crt = "MIIClTCCAf6gAwIBAgIBBjANBgkqhkiG9w0BAQUFADBeMQswCQYDVQQGEwJVUzEYMBYGA1" + "UEChMPVS5TLiBHb3Zlcm5tZW50MQwwCgYDVQQLEwNEb0QxEDAOBgNVBAsTB1Rlc3Rpbmcx" + "FTATBgNVBAMTDFRydXN0IEFuY2hvcjAeFw05OTAxMDExMjAxMDBaFw00ODAxMDExMjAxMD" + "BaMF4xCzAJBgNVBAYTAlVTMRgwFgYDVQQKEw9VLlMuIEdvdmVybm1lbnQxDDAKBgNVBAsT" + "A0RvZDEQMA4GA1UECxMHVGVzdGluZzEVMBMGA1UEAxMMQ0ExLUNQLjAyLjAxMIGfMA0GCS" + "qGSIb3DQEBAQUAA4GNADCBiQKBgQC/lQLtWKzklgYuzhjMiK2CzFmzODsEY/JIVNdn9T8M" + "W4ufpGwnfIV62EUHCFeMYydKBm8Hyjbjrz1otINJmrGL5WSAX1/UPtHy1chgXOsFYD6nAH" + "jZAJJGw74nUbKw5+L1wUHU8qXABaaTrRpS1UdKSq4TCZ18NCjC4Oxcf/yDdQIDAQABo2Mw" + "YTAPBgNVHRMBAf8EBTADAQH/MA4GA1UdDwEB/wQEAwIBBjAWBgNVHSAEDzANMAsGCWCGSA" + "FlAwEwATARBgNVHQ4ECgQINsJcxaBqdugwEwYDVR0jBAwwCoAIq5rr+cLnVI8wDQYJKoZI" + "hvcNAQEFBQADgYEAOQP3iUX7FtJlL9nvu4F+8o/N5vr+OB28OsbYtW+Q1FzEfjkUGtT9Ri" + "teradpN/xUnS/oj3BfqFtNANkYKrBeqRtm2VeOC3kdCVFnWFME2aoRAQZbWvOwCFc3yLA7" + "JBdENtDNI54yYHMHPA4/2CuNQq1Iu1ektAS95DIe7ddxL18="; public static final String Intermediate_Certificate_2_CP_02_01_crt = "MIIClTCCAf6gAwIBAgIBBzANBgkqhkiG9w0BAQUFADBeMQswCQYDVQQGEwJVUzEYMBYGA1" + "UEChMPVS5TLiBHb3Zlcm5tZW50MQwwCgYDVQQLEwNEb2QxEDAOBgNVBAsTB1Rlc3Rpbmcx" + "FTATBgNVBAMTDENBMS1DUC4wMi4wMTAeFw05OTAxMDExMjAxMDBaFw00ODAxMDExMjAxMD" + "BaMF4xCzAJBgNVBAYTAlVTMRgwFgYDVQQKEw9VLlMuIEdvdmVybm1lbnQxDDAKBgNVBAsT" + "A0RvZDEQMA4GA1UECxMHVGVzdGluZzEVMBMGA1UEAxMMQ0EyLUNQLjAyLjAxMIGfMA0GCS" + "qGSIb3DQEBAQUAA4GNADCBiQKBgQCx/mIo1Ma/IN8OR7KOjclvIwsv0JFXD/T258DruDZU" + "uGoYiEbAc/ZN7R8OHI7dnv9pBfsvyEl7m2DVoLZnP0eXJTHjdZxb1TwPHoSIysi9u3xWlP" + "Rg+v+GGfKLB9pL0m8SZh97SngerZI14w7vQy0kkXziGatSpBoXtWNmsHJNuQIDAQABo2Mw" + "YTAPBgNVHRMBAf8EBTADAQH/MA4GA1UdDwEB/wQEAwIBBjAWBgNVHSAEDzANMAsGCWCGSA" + "FlAwEwATARBgNVHQ4ECgQIoI0mSmDmzZUwEwYDVR0jBAwwCoAINsJcxaBqdugwDQYJKoZI" + "hvcNAQEFBQADgYEAcfs1pH12Qwdhv4NOJO2xxgMZZo8+A9Zl9c7RxsvuoZOOyCxoE9wT/l" + "PdUpGoGxtIPoWQs1qXEXnAlXJCXjLCJUHIG1/E6gQUXW0Ty6Ztpc5Dz06pPTN2gt+41B3J" + "sL/Klqc4iyCaWr8sYgEPQ8nColWRmIwk9gAasPNkNhyxA3Y="; public static final String Intermediate_CRL_1_CP_02_01_crl = "MIIBSzCBtQIBATANBgkqhkiG9w0BAQUFADBeMQswCQYDVQQGEwJVUzEYMBYGA1UEChMPVS" + "5TLiBHb3Zlcm5tZW50MQwwCgYDVQQLEwNEb2QxEDAOBgNVBAsTB1Rlc3RpbmcxFTATBgNV" + "BAMTDENBMS1DUC4wMi4wMRcNOTkwMTAxMTIwMTAwWhcNNDgwMTAxMTIwMTAwWqAjMCEwCg" + "YDVR0UBAMCAQEwEwYDVR0jBAwwCoAINsJcxaBqdugwDQYJKoZIhvcNAQEFBQADgYEAlBaV" + "VfrZqvyRhGXNYFik169nBHiNfKpw8k1YgFAQeNYdmfScq1KHmKzDhsx9kQteczBL7ltviK" + "TN3CKlZW82c16mfd4yYx0l5tkU80lwKCHSUzx92+qrvYjSMup+bqSsi8JhqByBf6b0JbKf" + "yx53Vpw1OCzjxrVHcfHPx8Q/vR4="; public static final String Intermediate_CRL_2_CP_02_01_crl = "MIIBSzCBtQIBATANBgkqhkiG9w0BAQUFADBeMQswCQYDVQQGEwJVUzEYMBYGA1UEChMPVS" + "5TLiBHb3Zlcm5tZW50MQwwCgYDVQQLEwNEb2QxEDAOBgNVBAsTB1Rlc3RpbmcxFTATBgNV" + "BAMTDENBMi1DUC4wMi4wMRcNOTkwMTAxMTIwMTAwWhcNNDgwMTAxMTIwMTAwWqAjMCEwCg" + "YDVR0UBAMCAQEwEwYDVR0jBAwwCoAIoI0mSmDmzZUwDQYJKoZIhvcNAQEFBQADgYEAhAHP" + "QxpcrTTN0GXeOwoMXuQUoHMvezEpM0BYOVLzI3KbRXWa9iWZINr99cRQvonMtOGkhIH3iS" + "wSNbsjmF9HX5UvNzrofOWataVP+macpCuNlK0NS3xxJjKRWOB9C1Ib7tiSSrQqIPcchlF6" + "vofy2ALEL6Usa1UTVYMhzGYnVZU="; public static final String End_Certificate_CP_02_01_crt = "MIIChjCCAe+gAwIBAgIBCDANBgkqhkiG9w0BAQUFADBeMQswCQYDVQQGEwJVUzEYMBYGA1" + "UEChMPVS5TLiBHb3Zlcm5tZW50MQwwCgYDVQQLEwNEb2QxEDAOBgNVBAsTB1Rlc3Rpbmcx" + "FTATBgNVBAMTDENBMi1DUC4wMi4wMTAeFw05OTAxMDExMjAxMDBaFw00ODAxMDExMjAxMD" + "BaMGAxCzAJBgNVBAYTAlVTMRgwFgYDVQQKEw9VLlMuIEdvdmVybm1lbnQxDDAKBgNVBAsT" + "A0RvRDEQMA4GA1UECxMHVGVzdGluZzEXMBUGA1UEAxMOVXNlcjEtQ1AuMDIuMDEwgZ8wDQ" + "YJKoZIhvcNAQEBBQADgY0AMIGJAoGBAOzYq2murB5ZjQd4wReI51Lc1F5VwK90OMGRfi71" + "YvwdRjgCudeDXZGW5ayid82y+eTDKFSzo1Li/BPTUXMpeqHHMCmLeefqxAWmz3aDoilF8I" + "Q53PlejnXJdntsal44w6WdP6ssiXlwzcZDnobAfuDTPgsnWWfzAkr1/LqEw/QZAgMBAAGj" + "UjBQMA4GA1UdDwEB/wQEAwIF4DAWBgNVHSAEDzANMAsGCWCGSAFlAwEwATARBgNVHQ4ECg" + "QIP5tVdEyxotcwEwYDVR0jBAwwCoAIoI0mSmDmzZUwDQYJKoZIhvcNAQEFBQADgYEAkVx9" + "S/20Hir8qMnfMpMGTgMKoVeWoljxim83IkNs1Xqe1oLGHdyDUA66uF8wPkoTqGrfDYvgBa" + "5Mi0iJREnMWoiWvCe467+L1b2gtvRBMl9bcRj40bvelk0Wn4lBl3VuKXarP5M0PKT5OWvN" + "2cPLNeXHvV6ZIrC4rmK2ISpIXX4="; public static final String[] TEST_4_DATA = new String[] { Intermediate_Certificate_1_CP_02_01_crt, Intermediate_Certificate_2_CP_02_01_crt, Intermediate_CRL_1_CP_02_01_crl, Intermediate_CRL_2_CP_02_01_crl, End_Certificate_CP_02_01_crt }; /* * test5 * */ public static final String Intermediate_Certificate_CP_02_02_crt = "MIIClTCCAf6gAwIBAgIBCTANBgkqhkiG9w0BAQUFADBeMQswCQYDVQQGEwJVUzEYMBYGA1" + "UEChMPVS5TLiBHb3Zlcm5tZW50MQwwCgYDVQQLEwNEb0QxEDAOBgNVBAsTB1Rlc3Rpbmcx" + "FTATBgNVBAMTDFRydXN0IEFuY2hvcjAeFw00NzAxMDExMjAxMDBaFw00ODAxMDExMjAxMD" + "BaMF4xCzAJBgNVBAYTAlVTMRgwFgYDVQQKEw9VLlMuIEdvdmVybm1lbnQxDDAKBgNVBAsT" + "A0RvZDEQMA4GA1UECxMHVGVzdGluZzEVMBMGA1UEAxMMQ0ExLUNQLjAyLjAyMIGfMA0GCS" + "qGSIb3DQEBAQUAA4GNADCBiQKBgQDHJmlRKb+mjc61iiqGe9gx/VUMLNmGrXGRYKMmYSxO" + "Q5sGLoztd2XtEgtZEPwvzd9KLKGP3XmgTrc4BGohqoFoG9Qb+w2ZGFwVC22GpeSoXc+J2u" + "2t3uRKYgboHpB0Jk42XLy+2wSEtS+/er7cFu2ufdPsvT4J1AqiuZSco96vtQIDAQABo2Mw" + "YTAPBgNVHRMBAf8EBTADAQH/MA4GA1UdDwEB/wQEAwIBBjAWBgNVHSAEDzANMAsGCWCGSA" + "FlAwEwATARBgNVHQ4ECgQIBvoP1E6PGiMwEwYDVR0jBAwwCoAIq5rr+cLnVI8wDQYJKoZI" + "hvcNAQEFBQADgYEAmOyFq2vZrUNDVWRcyzYvZhs1uQ4zgXtfqnPE0V19RgaYffCrSCI86z" + "5kyDUyZwbGABMxBaVxEw536MesyDTdZdEVw6lN5RRtxr8/WEiSH6oI6t0xNxuNOkSNpz4d" + "28HA4UfUvtXK8RK2YZnPAd6UXsRUPBPXKEpzy4v/9RyihSg="; public static final String Intermediate_CRL_CP_02_02_crl = "MIIBSzCBtQIBATANBgkqhkiG9w0BAQUFADBeMQswCQYDVQQGEwJVUzEYMBYGA1UEChMPVS" + "5TLiBHb3Zlcm5tZW50MQwwCgYDVQQLEwNEb2QxEDAOBgNVBAsTB1Rlc3RpbmcxFTATBgNV" + "BAMTDENBMS1DUC4wMi4wMhcNOTkwMTAxMTIwMTAwWhcNNDgwMTAxMTIwMTAwWqAjMCEwCg" + "YDVR0UBAMCAQEwEwYDVR0jBAwwCoAIBvoP1E6PGiMwDQYJKoZIhvcNAQEFBQADgYEAALlA" + "f3IDWexcdkMQHWTdGeFe+bG5dBvVPL5ZyQUw9DWbLwrjw/Jm4v9t+HLjETLSymsFT4bW21" + "OwnEiAAdaKT96k5t+sTyU5QQ6HL/jRXLHLGdCQgMFCglm5iNqaCLIFoMAVCaFkYtFUE3m/" + "iVt+319JOh5UyshMuWrAEW0IGGQ="; public static final String End_Certificate_CP_02_02_crt = "MIIChjCCAe+gAwIBAgIBCjANBgkqhkiG9w0BAQUFADBeMQswCQYDVQQGEwJVUzEYMBYGA1" + "UEChMPVS5TLiBHb3Zlcm5tZW50MQwwCgYDVQQLEwNEb2QxEDAOBgNVBAsTB1Rlc3Rpbmcx" + "FTATBgNVBAMTDENBMS1DUC4wMi4wMjAeFw05ODAxMDExMjAxMDBaFw00ODAxMDExMjAxMD" + "BaMGAxCzAJBgNVBAYTAlVTMRgwFgYDVQQKEw9VLlMuIEdvdmVybm1lbnQxDDAKBgNVBAsT" + "A0RvRDEQMA4GA1UECxMHVGVzdGluZzEXMBUGA1UEAxMOVXNlcjEtQ1AuMDIuMDIwgZ8wDQ" + "YJKoZIhvcNAQEBBQADgY0AMIGJAoGBAL/Src6e8qXwL+KJs5+v+JsakZdSDqMAFJUMfA2O" + "OO2TIqcvDFHzqesX+G+28MUwy6++ux07CD3FCaapgzBN4zO4RfKcamxFReKMKcEvNVVCOO" + "wO4Lvku1Sad14oYyGLOMzZwZFjRp8paaz5g87k70EOPBLeDlFMcch36czw53sLAgMBAAGj" + "UjBQMA4GA1UdDwEB/wQEAwIF4DAWBgNVHSAEDzANMAsGCWCGSAFlAwEwATARBgNVHQ4ECg" + "QIPoHc2Sfk6XUwEwYDVR0jBAwwCoAIBvoP1E6PGiMwDQYJKoZIhvcNAQEFBQADgYEAFHhm" + "o6QRFdO1x1wp7Jb1QQAlChFfP8MrGVNK04Ur8f+wfkwIypTDifJ0AoFpjcM3Ohu9Ixvb9q" + "3kCSIWKDnWtDWw1/dN8mPL5If5gGqPA0+wRbUKVKvduOg7hKr4mWjKw7oYiaJuIIoN9RRZ" + "ejzltd0NEaODNPW/JaKeQUVgZbY="; public static final String[] TEST_5_DATA = new String[] { Intermediate_Certificate_CP_02_02_crt, Intermediate_CRL_CP_02_02_crl, End_Certificate_CP_02_02_crt }; /* * test6 * */ public static final String Intermediate_Certificate_CP_02_03_crt = "MIIClTCCAf6gAwIBAgIBCzANBgkqhkiG9w0BAQUFADBeMQswCQYDVQQGEwJVUzEYMBYGA1" + "UEChMPVS5TLiBHb3Zlcm5tZW50MQwwCgYDVQQLEwNEb0QxEDAOBgNVBAsTB1Rlc3Rpbmcx" + "FTATBgNVBAMTDFRydXN0IEFuY2hvcjAeFw05ODAxMDExMjAxMDBaFw00ODAxMDExMjAxMD" + "BaMF4xCzAJBgNVBAYTAlVTMRgwFgYDVQQKEw9VLlMuIEdvdmVybm1lbnQxDDAKBgNVBAsT" + "A0RvZDEQMA4GA1UECxMHVGVzdGluZzEVMBMGA1UEAxMMQ0ExLUNQLjAyLjAzMIGfMA0GCS" + "qGSIb3DQEBAQUAA4GNADCBiQKBgQCaJ7NcOvb22F6HjMF1R/AORa4+pKFfFfd9teXPpVWC" + "9InTq+alY11QaSj27Qg0znOIItmf2W/8Dub9sjnbg+SgAkoV5+CAkplodRNC8AbD4x8rh/" + "fioQ8lb0Qb4Dn9I0n2wjOgitmMRdE2uW4uwVpH52vsMyenbDVxVI7jA4NS/wIDAQABo2Mw" + "YTAPBgNVHRMBAf8EBTADAQH/MA4GA1UdDwEB/wQEAwIBBjAWBgNVHSAEDzANMAsGCWCGSA" + "FlAwEwATARBgNVHQ4ECgQIC2T+/BkG93AwEwYDVR0jBAwwCoAIq5rr+cLnVI8wDQYJKoZI" + "hvcNAQEFBQADgYEApr6kDXVY5jYt23wC9n3LmhoxDoWh8cBQxcWmr1wpVxIrCbaP0/y00a" + "29wbewKfucUoh/W2OfjNcohjpKRrnVmOpi5vN7SmbZIHaxbKLzyQ7JwF17aznyCSZVrGpF" + "A/S49T5rlCm8KDBcc2ym7gRJzwUApbC0Wws4Pg46czrpQlg="; public static final String Intermediate_CRL_CP_02_03_crl = "MIIBSzCBtQIBATANBgkqhkiG9w0BAQUFADBeMQswCQYDVQQGEwJVUzEYMBYGA1UEChMPVS" + "5TLiBHb3Zlcm5tZW50MQwwCgYDVQQLEwNEb2QxEDAOBgNVBAsTB1Rlc3RpbmcxFTATBgNV" + "BAMTDENBMS1DUC4wMi4wMxcNOTkwMTAxMTIwMTAwWhcNNDgwMTAxMTIwMTAwWqAjMCEwCg" + "YDVR0UBAMCAQEwEwYDVR0jBAwwCoAIC2T+/BkG93AwDQYJKoZIhvcNAQEFBQADgYEAlBFY" + "vPxhFYsjFOIfQkd7MwKIi7vgPgoWTP5f+QlI0ison5n4N3rYJv31hTZRRRP99JZce1hY6J" + "Qiv1OtkpG7VfQIhr0FAGxTNaJD6F6rLbGjG8cap4+VibFQf5gZv0XQcyW4akYiRqSXImYn" + "NVlNyaxiJja+5GA9XVqvWOjjz4o="; public static final String End_Certificate_CP_02_03_crt = "MIIChjCCAe+gAwIBAgIBDDANBgkqhkiG9w0BAQUFADBeMQswCQYDVQQGEwJVUzEYMBYGA1" + "UEChMPVS5TLiBHb3Zlcm5tZW50MQwwCgYDVQQLEwNEb2QxEDAOBgNVBAsTB1Rlc3Rpbmcx" + "FTATBgNVBAMTDENBMS1DUC4wMi4wMzAeFw00NzAxMDExMjAxMDBaFw00ODAxMDExMjAxMD" + "BaMGAxCzAJBgNVBAYTAlVTMRgwFgYDVQQKEw9VLlMuIEdvdmVybm1lbnQxDDAKBgNVBAsT" + "A0RvRDEQMA4GA1UECxMHVGVzdGluZzEXMBUGA1UEAxMOVXNlcjEtQ1AuMDIuMDMwgZ8wDQ" + "YJKoZIhvcNAQEBBQADgY0AMIGJAoGBAMlW6FOLwhRsKZM6p0ww4QEWjQzjpjYhKnz3BnLw" + "SdGZqMe4wzZnDWc/0eyDOMCSYXIWQhlDMqQn2zCVPbDKzMRkdEeRSvE6ghhYP/hn3ipjSw" + "D8QwaqofCp0sFkbDPke+xD2tMhLdUyNKynPjpSQmYtfoA98PD7so3cSAtrYuSDAgMBAAGj" + "UjBQMA4GA1UdDwEB/wQEAwIF4DAWBgNVHSAEDzANMAsGCWCGSAFlAwEwATARBgNVHQ4ECg" + "QIc/X6kp7teCQwEwYDVR0jBAwwCoAIC2T+/BkG93AwDQYJKoZIhvcNAQEFBQADgYEAStub" + "g3DzhJgzYO+ZmRc0acldZGwZFm6F1Ckc1JzQDgVHU0bnCANgBcJj49UV2MwbNKPQdVzdwo" + "c91rfwrSY/PrvVQ9tUonZ28y/esFRBAdJTLf4u++p/gI3vfCvEXa5xVTIz1Hc+iKzAGKrI" + "cveDHy3ZZluQ3J6tbHs2BhnQFXM="; public static final String[] TEST_6_DATA = new String[] { Intermediate_Certificate_CP_02_03_crt, Intermediate_CRL_CP_02_03_crl, End_Certificate_CP_02_03_crt }; /* * test7 * */ public static final String Intermediate_Certificate_CP_02_04_crt = "MIIClTCCAf6gAwIBAgIBDTANBgkqhkiG9w0BAQUFADBeMQswCQYDVQQGEwJVUzEYMBYGA1" + "UEChMPVS5TLiBHb3Zlcm5tZW50MQwwCgYDVQQLEwNEb0QxEDAOBgNVBAsTB1Rlc3Rpbmcx" + "FTATBgNVBAMTDFRydXN0IEFuY2hvcjAeFw05ODAxMDExMjAxMDBaFw00ODAxMDExMjAxMD" + "BaMF4xCzAJBgNVBAYTAlVTMRgwFgYDVQQKEw9VLlMuIEdvdmVybm1lbnQxDDAKBgNVBAsT" + "A0RvZDEQMA4GA1UECxMHVGVzdGluZzEVMBMGA1UEAxMMQ0ExLUNQLjAyLjA0MIGfMA0GCS" + "qGSIb3DQEBAQUAA4GNADCBiQKBgQDgZy2Xs5pIoJrT7GuagmKLrn8F9rj8p8w2wELorGhM" + "1HJMVOurH+o+y6RXd0oMGJkKNrhjEnbHKm3PBYiLgpCjVEcFNhQF1OOxJ7RdahvA9ifsuw" + "jV1TxTGq35jeaJYASRXb2TiNfzuPWSVm0MWr5zz+YB6NNuvjxwEBgZvNiV8QIDAQABo2Mw" + "YTAPBgNVHRMBAf8EBTADAQH/MA4GA1UdDwEB/wQEAwIBBjAWBgNVHSAEDzANMAsGCWCGSA" + "FlAwEwATARBgNVHQ4ECgQIWAOnkHkwSVkwEwYDVR0jBAwwCoAIq5rr+cLnVI8wDQYJKoZI" + "hvcNAQEFBQADgYEAMiHozz92EOhSXU/krwQVs0GNEWoAUH3LHt70Zr01dFzEF6QhA/wUa4" + "+V4XwbMob+q4zGnTHj+tL9ChGWi3NDGELQ4cN64OMPsToGKkepLy+sDwdm9LaUP1bDvPxd" + "v2hjlskJ7TEu4+6ltXSG/k36Jk8C0/I/ayNGbYcEcLyes3s="; public static final String Intermediate_CRL_CP_02_04_crl = "MIIBSzCBtQIBATANBgkqhkiG9w0BAQUFADBeMQswCQYDVQQGEwJVUzEYMBYGA1UEChMPVS" + "5TLiBHb3Zlcm5tZW50MQwwCgYDVQQLEwNEb2QxEDAOBgNVBAsTB1Rlc3RpbmcxFTATBgNV" + "BAMTDENBMS1DUC4wMi4wNBcNOTkwMTAxMTIwMTAwWhcNNDgwMTAxMTIwMTAwWqAjMCEwCg" + "YDVR0UBAMCAQEwEwYDVR0jBAwwCoAIWAOnkHkwSVkwDQYJKoZIhvcNAQEFBQADgYEAVtCi" + "IocktnWOwWiaOc7tTUJvvH5+IYVyB/XhmMhF7cDbL292gyrnuh1+3+lHwZQBPoF9kzF0vt" + "WaweG7mDvYKxENQODdph/VcnypgUiFTWRTIPB1ZXfCTMWYf2QSalpHRDR4vVsqF748QbcG" + "E9mbzvLUz6NDA+Vf8wEwZehqSDM="; public static final String End_Certificate_CP_02_04_crt = "MIIChjCCAe+gAwIBAgIBDjANBgkqhkiG9w0BAQUFADBeMQswCQYDVQQGEwJVUzEYMBYGA1" + "UEChMPVS5TLiBHb3Zlcm5tZW50MQwwCgYDVQQLEwNEb2QxEDAOBgNVBAsTB1Rlc3Rpbmcx" + "FTATBgNVBAMTDENBMS1DUC4wMi4wNDAeFw01MDAxMDExMjAxMDBaFw00ODAxMDExMjAxMD" + "BaMGAxCzAJBgNVBAYTAlVTMRgwFgYDVQQKEw9VLlMuIEdvdmVybm1lbnQxDDAKBgNVBAsT" + "A0RvRDEQMA4GA1UECxMHVGVzdGluZzEXMBUGA1UEAxMOVXNlcjEtQ1AuMDIuMDQwgZ8wDQ" + "YJKoZIhvcNAQEBBQADgY0AMIGJAoGBALBX5GIQtvwswWwMDDPnphIk1rJSbcq7iClXLM2E" + "kgvBu+hbOzb0v9mtl0KJB71TWJCfwceVQiXc3Gk+YduujAbZRVTkROf9UOWD9bfrI7g+52" + "g4ms2n7evCO33b+kGEf4I014xl8dJDWtHK9Bhr+569RW9TzO06IeVeTD7whxMXAgMBAAGj" + "UjBQMA4GA1UdDwEB/wQEAwIF4DAWBgNVHSAEDzANMAsGCWCGSAFlAwEwATARBgNVHQ4ECg" + "QIuKXv5WkUTWAwEwYDVR0jBAwwCoAIWAOnkHkwSVkwDQYJKoZIhvcNAQEFBQADgYEAiu0B" + "yR5Ru8qVsgRqkOpCvrJnkqBAImbbR6+BUYH0juRxxKzKnbFOjU6a9WvkKpEBB8Q2xLynPN" + "68ecLpnOynx3xj2sWWSVbsRKPy0iOesQblKrq3yHAm4lhzoWA8t1Xz29Ko1WxylDhyxGpR" + "QAWsyGVCfJFlsZE0ibw3erlWTnA="; public static final String[] TEST_7_DATA = new String[] { Intermediate_Certificate_CP_02_04_crt, Intermediate_CRL_CP_02_04_crl, End_Certificate_CP_02_04_crt }; /* * test8 * */ public static final String Intermediate_Certificate_CP_02_05_crt = "MIIClTCCAf6gAwIBAgIBDzANBgkqhkiG9w0BAQUFADBeMQswCQYDVQQGEwJVUzEYMBYGA1" + "UEChMPVS5TLiBHb3Zlcm5tZW50MQwwCgYDVQQLEwNEb0QxEDAOBgNVBAsTB1Rlc3Rpbmcx" + "FTATBgNVBAMTDFRydXN0IEFuY2hvcjAeFw05ODAxMDExMjAxMDBaFw00ODAxMDExMjAxMD" + "BaMF4xCzAJBgNVBAYTAlVTMRgwFgYDVQQKEw9VLlMuIEdvdmVybm1lbnQxDDAKBgNVBAsT" + "A0RvZDEQMA4GA1UECxMHVGVzdGluZzEVMBMGA1UEAxMMQ0ExLUNQLjAyLjA1MIGfMA0GCS" + "qGSIb3DQEBAQUAA4GNADCBiQKBgQC2d80bD1RounqjKizkZJYPFUuVWZQ8W2nZDkEp8qR9" + "fRWCAGOZGs84tgHj5gasmxy1mxJc9ogyQ2mcZhJRitRm5LVNuGevO6JmfqYtJxbW54aZGE" + "5AWSRXqjJKJEih4VmPjA3vjQaSZSZJnu0DSnO82qWfu1ZUDlvIG6dfKJWRQQIDAQABo2Mw" + "YTAPBgNVHRMBAf8EBTADAQH/MA4GA1UdDwEB/wQEAwIBBjAWBgNVHSAEDzANMAsGCWCGSA" + "FlAwEwATARBgNVHQ4ECgQI3uNhI+QuI4owEwYDVR0jBAwwCoAIq5rr+cLnVI8wDQYJKoZI" + "hvcNAQEFBQADgYEAG/+Rpk8dYrSFdaEO8Ch5tuvvKTOMi7W/DRA4B4xR7WyRJmosPB+37c" + "teGKVzqFND22Xc8xQH/b/nxYW08sCSLAfN0cRusoSWwWSRtPO2f9fyC/BqCy2B2kQLFNPM" + "Bk22jNFwLqPUeZn1UHN05RFAqVx325kpl2m1V7tw/mrXATI="; public static final String Intermediate_CRL_CP_02_05_crl = "MIIBSzCBtQIBATANBgkqhkiG9w0BAQUFADBeMQswCQYDVQQGEwJVUzEYMBYGA1UEChMPVS" + "5TLiBHb3Zlcm5tZW50MQwwCgYDVQQLEwNEb2QxEDAOBgNVBAsTB1Rlc3RpbmcxFTATBgNV" + "BAMTDENBMS1DUC4wMi4wNRcNOTkwMTAxMTIwMTAwWhcNNDgwMTAxMTIwMTAwWqAjMCEwCg" + "YDVR0UBAMCAQEwEwYDVR0jBAwwCoAI3uNhI+QuI4owDQYJKoZIhvcNAQEFBQADgYEAWZUI" + "2VGY4pak0kICONP/CKvamYFs5txJfR69AC5tEJ+Fy3PmSeHkLUZf/oc9d8EEyr0MsIjRHj" + "N4X4MquMlk4FflZcc8GblQK8LdXBK4Dy1SiXHA5GB3U1AmgzAzEQGwGRZnzWP5+rJ65upX" + "vksAYyPQmruRM0O5sElctPn6B+Y="; public static final String End_Certificate_CP_02_05_crt = "MIICiDCCAfGgAwIBAgIBEDANBgkqhkiG9w0BAQUFADBeMQswCQYDVQQGEwJVUzEYMBYGA1" + "UEChMPVS5TLiBHb3Zlcm5tZW50MQwwCgYDVQQLEwNEb2QxEDAOBgNVBAsTB1Rlc3Rpbmcx" + "FTATBgNVBAMTDENBMS1DUC4wMi4wNTAgGA8yMDUwMDEwMTEyMDEwMFoXDTQ4MDEwMTEyMD" + "EwMFowYDELMAkGA1UEBhMCVVMxGDAWBgNVBAoTD1UuUy4gR292ZXJubWVudDEMMAoGA1UE" + "CxMDRG9EMRAwDgYDVQQLEwdUZXN0aW5nMRcwFQYDVQQDEw5Vc2VyMS1DUC4wMi4wNTCBnz" + "ANBgkqhkiG9w0BAQEFAAOBjQAwgYkCgYEAviLKpW4iblWNLQfmBJJ+ruMgygmjRWfoFGya" + "Ndv2ma0Ugqm5xXq8c0orbnezwSp+tnzZZhG5KDNZr5+z3krCkqOGGzuUvVLqeJxPOLu7Js" + "y472nAA7+FhwfZrXUI+Vg9F4qF+Ye81ivDrYVAEmalCpCyHOAKdvwkwQjRucifu90CAwEA" + "AaNSMFAwDgYDVR0PAQH/BAQDAgXgMBYGA1UdIAQPMA0wCwYJYIZIAWUDATABMBEGA1UdDg" + "QKBAjgph7BA5L7dzATBgNVHSMEDDAKgAje42Ej5C4jijANBgkqhkiG9w0BAQUFAAOBgQBr" + "MDMv9NWCTIQ3blMEqPiEyjiBhSJl88Cu797P4lIn+gc6E+0vZp61X7B2k5CHgsnxyVLK5e" + "bwl0bYAPKwRI9yzHLrj71RNw8HA7PCRPn1GNrtBBbIpLE0/sqLo51UPu/377+CnzYhIycL" + "tvS0KDLUTDSY/OowDcplF6Xwnt8cUQ=="; public static final String[] TEST_8_DATA = new String[] { Intermediate_Certificate_CP_02_05_crt, Intermediate_CRL_CP_02_05_crl, End_Certificate_CP_02_05_crt }; /* * test9 * */ public static final String Intermediate_Certificate_CP_03_01_crt = "MIIClTCCAf6gAwIBAgIBETANBgkqhkiG9w0BAQUFADBeMQswCQYDVQQGEwJVUzEYMBYGA1" + "UEChMPVS5TLiBHb3Zlcm5tZW50MQwwCgYDVQQLEwNEb0QxEDAOBgNVBAsTB1Rlc3Rpbmcx" + "FTATBgNVBAMTDFRydXN0IEFuY2hvcjAeFw05ODAxMDExMjAxMDBaFw0wMDAxMDExMjAxMD" + "BaMF4xCzAJBgNVBAYTAlVTMRgwFgYDVQQKEw9VLlMuIEdvdmVybm1lbnQxDDAKBgNVBAsT" + "A0RvZDEQMA4GA1UECxMHVGVzdGluZzEVMBMGA1UEAxMMQ0ExLUNQLjAzLjAxMIGfMA0GCS" + "qGSIb3DQEBAQUAA4GNADCBiQKBgQCuF8mub5cgUYZytrRjJ5Rhc2fgazGxWIj6EIKzeSpo" + "FwScItRX9KxnTIXEBTguBk7eQUsbN8yu49/Mlq45EAnemyZRBWzLFLYLPCco7pyTsWm7Ps" + "2FAGJ3vE9pC9xaZC+KrwF3Ho+DZNDwhj5InXTP8pChAIPfB8/7V/2mk0lN0wIDAQABo2Mw" + "YTAPBgNVHRMBAf8EBTADAQH/MA4GA1UdDwEB/wQEAwIBBjAWBgNVHSAEDzANMAsGCWCGSA" + "FlAwEwATARBgNVHQ4ECgQI4mI6Ojs0onswEwYDVR0jBAwwCoAIq5rr+cLnVI8wDQYJKoZI" + "hvcNAQEFBQADgYEAMVGzU6f4YOHpHla+YuGCjHOUZYrA9J25G3UFFoPr2JZEG+Fb5hRQUh" + "4S1qUQKXn6dpVua+qTJDk3Tg2N8OdIHG/gy0hvYHsxhLCSDQBsfPN7p3FClM7r/VHOqgAN" + "vzT+KYvxx6gwn6O+n7ERkrBIfkyrGFhnmjx3+VOCc9P4SDE="; public static final String Intermediate_CRL_CP_03_01_crl = "MIIBSzCBtQIBATANBgkqhkiG9w0BAQUFADBeMQswCQYDVQQGEwJVUzEYMBYGA1UEChMPVS" + "5TLiBHb3Zlcm5tZW50MQwwCgYDVQQLEwNEb2QxEDAOBgNVBAsTB1Rlc3RpbmcxFTATBgNV" + "BAMTDENBMS1DUC4wMy4wMRcNOTkwMTAxMTIwMTAwWhcNNDgwMTAxMTIwMTAwWqAjMCEwCg" + "YDVR0UBAMCAQEwEwYDVR0jBAwwCoAI4mI6Ojs0onswDQYJKoZIhvcNAQEFBQADgYEAfwYf" + "4kAG4srB2VxWimJs1HwXTaPDooellQclZ5hP/EluT7oe03+ReFef6uXbHt/xRdeaoQhJGy" + "SP8dWf6UIbL82oaSYqChIvAZD6zTMavEgSET0PlUsK1aEMTpMEtKPvedFSOTNBaMNvMzSW" + "t5xwurn63qyXTOxHf4m2L4w8+i0="; public static final String End_Certificate_CP_03_01_crt = "MIIChjCCAe+gAwIBAgIBEjANBgkqhkiG9w0BAQUFADBeMQswCQYDVQQGEwJVUzEYMBYGA1" + "UEChMPVS5TLiBHb3Zlcm5tZW50MQwwCgYDVQQLEwNEb2QxEDAOBgNVBAsTB1Rlc3Rpbmcx" + "FTATBgNVBAMTDENBMS1DUC4wMy4wMTAeFw05ODAxMDExMjAxMDBaFw00ODAxMDExMjAxMD" + "BaMGAxCzAJBgNVBAYTAlVTMRgwFgYDVQQKEw9VLlMuIEdvdmVybm1lbnQxDDAKBgNVBAsT" + "A0RvRDEQMA4GA1UECxMHVGVzdGluZzEXMBUGA1UEAxMOVXNlcjEtQ1AuMDMuMDEwgZ8wDQ" + "YJKoZIhvcNAQEBBQADgY0AMIGJAoGBAJ/ALaZ+MdNxKDH49+7jUm+17DII5QQEfjk8IaEU" + "syApOhsByOG06HPItiBEnnfDDxU5kjsZDtw/9LlouBocNXAJt+ZmL3QYyOgeH4SQ4f21rw" + "7j8fw57gUkP5oWhEc0loXr/hB92hoKbsBoRpv8F1zPZcPNLUnyUzqLH5+CeIibAgMBAAGj" + "UjBQMA4GA1UdDwEB/wQEAwIF4DAWBgNVHSAEDzANMAsGCWCGSAFlAwEwATARBgNVHQ4ECg" + "QI822isg/wPCowEwYDVR0jBAwwCoAI4mI6Ojs0onswDQYJKoZIhvcNAQEFBQADgYEAilIn" + "OD0iQrLrHRkO4zr9S9VXAJXJV3l9wfbLBweXM3q/zt4HGKBw4Wq1Yn+AfDxXrBtJA5hP5e" + "d7CDd4eM93yeKozdZCLNZfUM8sJ2/MRh07tvwJ19e2STklED8b/ndmr5my8H8jjJDaaYww" + "qTSnXqpcqsUsj+kV4Mk0DvVWT3w="; public static final String[] TEST_9_DATA = new String[] { Intermediate_Certificate_CP_03_01_crt, Intermediate_CRL_CP_03_01_crl, End_Certificate_CP_03_01_crt }; /* * test10 * */ public static final String Intermediate_Certificate_CP_03_02_crt = "MIIClTCCAf6gAwIBAgIBEzANBgkqhkiG9w0BAQUFADBeMQswCQYDVQQGEwJVUzEYMBYGA1" + "UEChMPVS5TLiBHb3Zlcm5tZW50MQwwCgYDVQQLEwNEb0QxEDAOBgNVBAsTB1Rlc3Rpbmcx" + "FTATBgNVBAMTDFRydXN0IEFuY2hvcjAeFw05ODAxMDExMjAxMDBaFw00ODAxMDExMjAxMD" + "BaMF4xCzAJBgNVBAYTAlVTMRgwFgYDVQQKEw9VLlMuIEdvdmVybm1lbnQxDDAKBgNVBAsT" + "A0RvZDEQMA4GA1UECxMHVGVzdGluZzEVMBMGA1UEAxMMQ0ExLUNQLjAzLjAyMIGfMA0GCS" + "qGSIb3DQEBAQUAA4GNADCBiQKBgQC4AbP8gDUUcIa8w4pEsGgbYH2sz08QMUXd4xwx691i" + "9QCcyWSovQO4Jozeb9JwtyN2+f3T+JqZL/gwUHuLO2IEXpzE2C8FzQg6Ma+TiSrlvGJfec" + "TlSooFmEtD3Xh6I6N5PM1fpyyY2sOOhARN5S6qR9BOuxkBAqrAT0fgqD2TswIDAQABo2Mw" + "YTAPBgNVHRMBAf8EBTADAQH/MA4GA1UdDwEB/wQEAwIBBjAWBgNVHSAEDzANMAsGCWCGSA" + "FlAwEwATARBgNVHQ4ECgQI97nJCqq6+kIwEwYDVR0jBAwwCoAIq5rr+cLnVI8wDQYJKoZI" + "hvcNAQEFBQADgYEAWwpfh9oOOvj9xHS0zcczaUIHTkpjgk09I+pERlu0Z0+rHvpZGge4Ov" + "NDFtMc4TgthGcydbIwiKogjtGBM2/sNHIO2jcpNeOtNKLxrzD4Y0Ve164kXBu9Mmsxx4sG" + "7XUXZWgiOPfu/HmyPVdzbIReJdQO515SNx7JdgVyUkyhBxM="; public static final String Intermediate_CRL_CP_03_02_crl = "MIIBSzCBtQIBATANBgkqhkiG9w0BAQUFADBeMQswCQYDVQQGEwJVUzEYMBYGA1UEChMPVS" + "5TLiBHb3Zlcm5tZW50MQwwCgYDVQQLEwNEb2QxEDAOBgNVBAsTB1Rlc3RpbmcxFTATBgNV" + "BAMTDENBMS1DUC4wMy4wMhcNOTkwMTAxMTIwMTAwWhcNNDgwMTAxMTIwMTAwWqAjMCEwCg" + "YDVR0UBAMCAQEwEwYDVR0jBAwwCoAI97nJCqq6+kIwDQYJKoZIhvcNAQEFBQADgYEAC9Hv" + "NevV6/Oz3wcgEbDgZYRKJRdr4OW4Es7R4ahjz3sH6GXZ1HiEjx2+frmp8LMshQ4D+hpjRk" + "drSPko1M4a/fQCYxbonZ0xjpYw067dwLmr56+GPJAxkzcSmFKXx+ejyQpG+9+qCR+zm98V" + "lop6besAaGUjZKnYShIQOfNzDZk="; public static final String End_Certificate_CP_03_02_crt = "MIIChjCCAe+gAwIBAgIBFDANBgkqhkiG9w0BAQUFADBeMQswCQYDVQQGEwJVUzEYMBYGA1" + "UEChMPVS5TLiBHb3Zlcm5tZW50MQwwCgYDVQQLEwNEb2QxEDAOBgNVBAsTB1Rlc3Rpbmcx" + "FTATBgNVBAMTDENBMS1DUC4wMy4wMjAeFw05ODAxMDExMjAxMDBaFw0wMDAxMDExMjAxMD" + "BaMGAxCzAJBgNVBAYTAlVTMRgwFgYDVQQKEw9VLlMuIEdvdmVybm1lbnQxDDAKBgNVBAsT" + "A0RvRDEQMA4GA1UECxMHVGVzdGluZzEXMBUGA1UEAxMOVXNlcjEtQ1AuMDMuMDIwgZ8wDQ" + "YJKoZIhvcNAQEBBQADgY0AMIGJAoGBAMJMiW+G4bgoRaYz2OUu/+PQ/yp4JgFOB3Vegf5/" + "vIrF4gsnoQxOCCsO5JTLrbS5fi3COjvM5w9/SZpNHtSfyWb9afmx4DdrT1bNjma7I6PCid" + "yxMzX4iTLeaMRnqBk4A+/0Wf2+4VzCqr8aViIiQ7u2JfZiTQ4dZxDoUW6G8lrbAgMBAAGj" + "UjBQMA4GA1UdDwEB/wQEAwIF4DAWBgNVHSAEDzANMAsGCWCGSAFlAwEwATARBgNVHQ4ECg" + "QIEjny2GzFXGQwEwYDVR0jBAwwCoAI97nJCqq6+kIwDQYJKoZIhvcNAQEFBQADgYEAJw3T" + "3aL3pYbZhswgshOvJ9Y1qv65R6rClSxB5lqBw6+Qki4ZpW57NK8LwaGS03XzDUPaDi4/9R" + "hGCHpP24fIskS4n4jNZgKpGtt6VEVorUH7cOLNCw2cuwMlKbkyZnNdx2JqTMMlHzNJ3cmy" + "aX3F70IY0OZbwCKdUo/uMVC6hss="; public static final String[] TEST_10_DATA = new String[] { Intermediate_Certificate_CP_03_02_crt, Intermediate_CRL_CP_03_02_crl, End_Certificate_CP_03_02_crt }; /* * test11 * */ public static final String Intermediate_Certificate_CP_03_03_crt = "MIIClTCCAf6gAwIBAgIBFTANBgkqhkiG9w0BAQUFADBeMQswCQYDVQQGEwJVUzEYMBYGA1" + "UEChMPVS5TLiBHb3Zlcm5tZW50MQwwCgYDVQQLEwNEb0QxEDAOBgNVBAsTB1Rlc3Rpbmcx" + "FTATBgNVBAMTDFRydXN0IEFuY2hvcjAeFw05ODAxMDExMjAxMDBaFw00ODAxMDExMjAxMD" + "BaMF4xCzAJBgNVBAYTAlVTMRgwFgYDVQQKEw9VLlMuIEdvdmVybm1lbnQxDDAKBgNVBAsT" + "A0RvZDEQMA4GA1UECxMHVGVzdGluZzEVMBMGA1UEAxMMQ0ExLUNQLjAzLjAzMIGfMA0GCS" + "qGSIb3DQEBAQUAA4GNADCBiQKBgQCjLYKGKEMJgC/r0NH7vubQZ5qPEFEEN6QdLUWWqf/O" + "Yqo9hboQq6S8dFHp3DVR5x/4NOdNRjsTABbXsnz8U+L7+4CorhDhXj29weGMYIIfJ3XSIb" + "T7sE/GOPmXeGhrTv2zucI1j80sN5nTEoiGFm10LQqAgoyV46BxDltf3/D7wwIDAQABo2Mw" + "YTAPBgNVHRMBAf8EBTADAQH/MA4GA1UdDwEB/wQEAwIBBjAWBgNVHSAEDzANMAsGCWCGSA" + "FlAwEwATARBgNVHQ4ECgQIhCIOyzfScpAwEwYDVR0jBAwwCoAIq5rr+cLnVI8wDQYJKoZI" + "hvcNAQEFBQADgYEAA18kQijoJebmTQS7n/q/fQx2iblOJaJAWQLHeGCCGqKxCjUpOxuD+y" + "xMspmTKdQqEkqQ5vpHdFYQ5MYuecqAdp6woWUNQGVd4HHPmHsAW3Oppwb0yLggYs8IVHjm" + "dNO1pYb+YYciCKBtX8D1OnedIRcrQmDMJUjbfmAEv/4b0EM="; public static final String Intermediate_CRL_CP_03_03_crl = "MIIBSzCBtQIBATANBgkqhkiG9w0BAQUFADBeMQswCQYDVQQGEwJVUzEYMBYGA1UEChMPVS" + "5TLiBHb3Zlcm5tZW50MQwwCgYDVQQLEwNEb2QxEDAOBgNVBAsTB1Rlc3RpbmcxFTATBgNV" + "BAMTDENBMS1DUC4wMy4wMxcNOTkwMTAxMTIwMTAwWhcNNDgwMTAxMTIwMTAwWqAjMCEwCg" + "YDVR0UBAMCAQEwEwYDVR0jBAwwCoAIhCIOyzfScpAwDQYJKoZIhvcNAQEFBQADgYEAk34j" + "SxMr8p1h1qJWlfoh4er9pu1AkkHujovan6Ctx89VwFdOS5Kw82OCvD+nmJAHrFuncNlClf" + "51G8FCEAFLhMNwic4WAxrBX15hcUTaWk8Wj00dfUFwjG8/Kv3QUCDBN8f3KC8/oBeORRX9" + "dHW5ei2IUKuD1ITCeIoyRDBxQIg="; public static final String End_Certificate_CP_03_03_crt = "MIIChjCCAe+gAwIBAgIBFjANBgkqhkiG9w0BAQUFADBeMQswCQYDVQQGEwJVUzEYMBYGA1" + "UEChMPVS5TLiBHb3Zlcm5tZW50MQwwCgYDVQQLEwNEb2QxEDAOBgNVBAsTB1Rlc3Rpbmcx" + "FTATBgNVBAMTDENBMS1DUC4wMy4wMzAeFw05ODAxMDExMjAxMDBaFw01MDA3MDExMjAxMD" + "BaMGAxCzAJBgNVBAYTAlVTMRgwFgYDVQQKEw9VLlMuIEdvdmVybm1lbnQxDDAKBgNVBAsT" + "A0RvRDEQMA4GA1UECxMHVGVzdGluZzEXMBUGA1UEAxMOVXNlcjEtQ1AuMDMuMDMwgZ8wDQ" + "YJKoZIhvcNAQEBBQADgY0AMIGJAoGBALSw1Ey7kzFzzjMS4oTSrZH/95NMHLxtUSaVGMCy" + "0q2iLfGZ79eTS9megQUranYlIuK411yvFtskbFKf0idMKBtM8nX3Rxubm5EnbnpgvNrBEg" + "0FbOPqpSaR+8pxZ6lweB45tkzLU3OZeAZSpGOY1UvT/htn6Ae8JQAVajSvYyfNAgMBAAGj" + "UjBQMA4GA1UdDwEB/wQEAwIF4DAWBgNVHSAEDzANMAsGCWCGSAFlAwEwATARBgNVHQ4ECg" + "QIF014kOHikvcwEwYDVR0jBAwwCoAIhCIOyzfScpAwDQYJKoZIhvcNAQEFBQADgYEAdLMM" + "zGPPvBLgPbhn2tba/7HiaZaayHIxTXmpW0KAhP+8hwapOitrtLGPwqVtxQ3GoSMZJPMDCV" + "WsrT3OZm27G6ytqqNZ2ZO49UC7WwQ49TVlN79Ui9RZIBnRzlMIDNKsyuohfSRhFZTkWdoH" + "/y8ulY8k4xBThV8e8IRgtYj3nhc="; public static final String[] TEST_11_DATA = new String[] { Intermediate_Certificate_CP_03_03_crt, Intermediate_CRL_CP_03_03_crl, End_Certificate_CP_03_03_crt }; /* * test12 * */ public static final String Intermediate_Certificate_CP_03_04_crt = "MIIClTCCAf6gAwIBAgIBFzANBgkqhkiG9w0BAQUFADBeMQswCQYDVQQGEwJVUzEYMBYGA1" + "UEChMPVS5TLiBHb3Zlcm5tZW50MQwwCgYDVQQLEwNEb0QxEDAOBgNVBAsTB1Rlc3Rpbmcx" + "FTATBgNVBAMTDFRydXN0IEFuY2hvcjAeFw05ODAxMDExMjAxMDBaFw00ODAxMDExMjAxMD" + "BaMF4xCzAJBgNVBAYTAlVTMRgwFgYDVQQKEw9VLlMuIEdvdmVybm1lbnQxDDAKBgNVBAsT" + "A0RvZDEQMA4GA1UECxMHVGVzdGluZzEVMBMGA1UEAxMMQ0ExLUNQLjAzLjA0MIGfMA0GCS" + "qGSIb3DQEBAQUAA4GNADCBiQKBgQDbUii3czeUQ2zNlxvrhnJ0LcBGxCDHFr3xx+plDg3f" + "uasDKCY/VjCLEfQ5a2oqcovvGKsd2CPXbCFJtimW1R7Dvt+a0y95fppsdseorYDikiBlOj" + "ja6LR3Cz3bslYc133C+W/MKHMJ0tdvtTk+SJrq7lqs+iv/b/xHC3k/gDjIswIDAQABo2Mw" + "YTAPBgNVHRMBAf8EBTADAQH/MA4GA1UdDwEB/wQEAwIBBjAWBgNVHSAEDzANMAsGCWCGSA" + "FlAwEwATARBgNVHQ4ECgQIFNw3o1kc4XkwEwYDVR0jBAwwCoAIq5rr+cLnVI8wDQYJKoZI" + "hvcNAQEFBQADgYEAn/pr7/noYyjXSKEe/eLk3l4Rb6PEhNAnzySmxGkjIjWKAgh5IVYSGV" + "KFO/FaNOiYkRFHwXZFNj71q7gbM+HwALurN0Mr/MUA1TSpPy7YhFL0SWq3C3XsC/dVJ50b" + "HmTW+dGcxboX0h9HeKFxp3VyOY/dUut2oc+s/TnmqQII1CU="; public static final String Intermediate_CRL_CP_03_04_crl = "MIIBSzCBtQIBATANBgkqhkiG9w0BAQUFADBeMQswCQYDVQQGEwJVUzEYMBYGA1UEChMPVS" + "5TLiBHb3Zlcm5tZW50MQwwCgYDVQQLEwNEb2QxEDAOBgNVBAsTB1Rlc3RpbmcxFTATBgNV" + "BAMTDENBMS1DUC4wMy4wNBcNOTkwMTAxMTIwMTAwWhcNNDgwMTAxMTIwMTAwWqAjMCEwCg" + "YDVR0UBAMCAQEwEwYDVR0jBAwwCoAIFNw3o1kc4XkwDQYJKoZIhvcNAQEFBQADgYEAMoJ5" + "jGE1AxxfluixG8Sk7H4W2rqSEkQyNHfnlKSMbh9KZA3evI8HGKGGfkbBNoe4/HauZ4NVFw" + "FXgllCp+TI8Qd+HafFoDv6ff1K7T86p6r7tE3AEM1XmbnfohP3/ivpIzustv/f2rqjxILK" + "Ldvrth2/OlNygwY+D54lcWH1DX8="; public static final String End_Certificate_CP_03_04_crt = "MIICiDCCAfGgAwIBAgIBGDANBgkqhkiG9w0BAQUFADBeMQswCQYDVQQGEwJVUzEYMBYGA1" + "UEChMPVS5TLiBHb3Zlcm5tZW50MQwwCgYDVQQLEwNEb2QxEDAOBgNVBAsTB1Rlc3Rpbmcx" + "FTATBgNVBAMTDENBMS1DUC4wMy4wNDAgFw05ODAxMDExMjAxMDBaGA8yMDUwMDEwMTEyMD" + "EwMFowYDELMAkGA1UEBhMCVVMxGDAWBgNVBAoTD1UuUy4gR292ZXJubWVudDEMMAoGA1UE" + "CxMDRG9EMRAwDgYDVQQLEwdUZXN0aW5nMRcwFQYDVQQDEw5Vc2VyMS1DUC4wMy4wNDCBnz" + "ANBgkqhkiG9w0BAQEFAAOBjQAwgYkCgYEAuSL9tB1JW6JPUO2Xw6TMYkPX41lru3EPyYko" + "YgXy4giy6LGoqbgtskHehD22v3rfWjqOd9iV2PBio/vYE4zEz0H0n84dpnBvog6A1AlE19" + "PkQ1txjzIA52FQIRwRfZ38LaulQEfJ0a+fiRHQiM960O3YvHXV+GEbNcw4jo8b0sUCAwEA" + "AaNSMFAwDgYDVR0PAQH/BAQDAgXgMBYGA1UdIAQPMA0wCwYJYIZIAWUDATABMBEGA1UdDg" + "QKBAh9/WgM+UT6bTATBgNVHSMEDDAKgAgU3DejWRzheTANBgkqhkiG9w0BAQUFAAOBgQDR" + "I6PKUGg876/fSljtqxXCR4CoGAAurNFOcM4EWeoc6ZvuDOi3P7rNYiYAXXlmp7epOAgvZP" + "EV4vS16ODaJO6qIMR1YsaGEPo0ecT2pEStvP37X6pb5TdyjyKYF3586IN6TJdFMFsW/Lqg" + "tucl9bGlWmfTVwxTexq6+D8diK48KQ=="; public static final String[] TEST_12_DATA = new String[] { Intermediate_Certificate_CP_03_04_crt, Intermediate_CRL_CP_03_04_crl, End_Certificate_CP_03_04_crt }; /* * test13 * */ public static final String Intermediate_Certificate_CP_04_01_crt = "MIIClTCCAf6gAwIBAgIBGTANBgkqhkiG9w0BAQUFADBeMQswCQYDVQQGEwJVUzEYMBYGA1" + "UEChMPVS5TLiBHb3Zlcm5tZW50MQwwCgYDVQQLEwNEb0QxEDAOBgNVBAsTB1Rlc3Rpbmcx" + "FTATBgNVBAMTDFRydXN0IEFuY2hvcjAeFw05ODAxMDExMjAxMDBaFw00ODAxMDExMjAxMD" + "BaMF4xCzAJBgNVBAYTAlVTMRgwFgYDVQQKEw9VLlMuIEdvdmVybm1lbnQxDDAKBgNVBAsT" + "A0RvZDEQMA4GA1UECxMHVGVzdGluZzEVMBMGA1UEAxMMQ0ExLUNQLjA0LjAxMIGfMA0GCS" + "qGSIb3DQEBAQUAA4GNADCBiQKBgQC5UJ+KMj8tAmzr3OGYL2gSFcNTf8ik+ZVxlaPVGHyS" + "KjYQBAEbefhfg5Ps2aIuqBwYkbtFXuHif5GEhgObA4InCyESeRjYLGcVMqwSZzAOFAR0dP" + "1LzgzQs3ZgG9JX5MO5wEZ8IMnVN4Otu4XIlWSgIpUNS2vyet8Zi7t9fX+JewIDAQABo2Mw" + "YTAPBgNVHRMBAf8EBTADAQH/MA4GA1UdDwEB/wQEAwIBBjAWBgNVHSAEDzANMAsGCWCGSA" + "FlAwEwATARBgNVHQ4ECgQIOZvfph4Uu9YwEwYDVR0jBAwwCoAIq5rr+cLnVI8wDQYJKoZI" + "hvcNAQEFBQADgYEAXMyscmGpKSLG3hQltMQLegy0+g5wzgOrbFOWxZmiVNR+zSsHDD3UAH" + "H4SyTozlooC0jAY4yAhZ5RX6SSJKx9fHsOZD9ldCmst14qLk3pkI+M0QiPBZkVTx5/7dR2" + "wGkuNKSVWH6woOq7BbEzpO7xMlrUr6tgHt4Dc6Evt1pVZls="; public static final String Intermediate_CRL_CP_04_01_crl = "MIIBSzCBtQIBATANBgkqhkiG9w0BAQUFADBeMQswCQYDVQQGEwJVUzEYMBYGA1UEChMPVS" + "5TLiBHb3Zlcm5tZW50MQwwCgYDVQQLEwNEb2QxEDAOBgNVBAsTB1Rlc3RpbmcxFTATBgNV" + "BAMTDENBMS1DUC4wNC4wMRcNOTkwMTAxMTIwMTAwWhcNNDgwMTAxMTIwMTAwWqAjMCEwCg" + "YDVR0UBAMCAQEwEwYDVR0jBAwwCoAIOZvfph4Uu9YwDQYJKoZIhvcNAQEFBQADgYEAe79z" + "iEUgP/mvouJ9ufit1y4SjnHQWik75W65eGn/XGArRrBqJ8jZVJE4/rpDBbzm2V0hQoWU8z" + "zchZFlesUyqQZ9KUlT0YGR0YPcNw/V+58RonWWfmU3M2DvWDrXgCOXPm61+AYq4+kTowsG" + "0stmeML6NxjDzWpfAgI/MpXqe80="; public static final String End_Certificate_CP_04_01_crt = "MIIChjCCAe+gAwIBAgIBGjANBgkqhkiG9w0BAQUFADBeMQswCQYDVQQGEwJVUzEYMBYGA1" + "UEChMPVS5TLiBHb3Zlcm5tZW50MQwwCgYDVQQLEwNEb2QxEDAOBgNVBAsTB1Rlc3Rpbmcx" + "FTATBgNVBAMTDENBMS1DUC45OS45OTAeFw05ODAxMDExMjAxMDBaFw00ODAxMDExMjAxMD" + "BaMGAxCzAJBgNVBAYTAlVTMRgwFgYDVQQKEw9VLlMuIEdvdmVybm1lbnQxDDAKBgNVBAsT" + "A0RvRDEQMA4GA1UECxMHVGVzdGluZzEXMBUGA1UEAxMOVXNlcjEtQ1AuMDQuMDEwgZ8wDQ" + "YJKoZIhvcNAQEBBQADgY0AMIGJAoGBAPiAZKXPjK8jvaNj34VynyKPK7dQtFysBPKFW5Y1" + "Bc+OMsyd2pPpQoJYcQTMMomlAqoBvSXUJCMNly/BxVuvn7l6I9crtx6PjBBUlEzdcsscaa" + "EaHuCCVl+Msnr66cSV3GqVGAhujun81+lyurcTEog3ftsohwbQnfA76qNU/N3/AgMBAAGj" + "UjBQMA4GA1UdDwEB/wQEAwIF4DAWBgNVHSAEDzANMAsGCWCGSAFlAwEwATARBgNVHQ4ECg" + "QIJZPDbf2xNv8wEwYDVR0jBAwwCoAIOZvfph4Uu9YwDQYJKoZIhvcNAQEFBQADgYEAZf4L" + "1RDHDXwwA2CgcIhM4CAfZ72CR2zOan0at38VVFB3u9vs4VLwFcrOQCIjDbdLijc0XWLima" + "4vCD1qrsv6Hk5+6113HfFNmD8mp6X5jAwoNPa/I4kmFOA8iIm4TTk7M75vQyCQTPG0VzbU" + "Nu3uwTbXKm5ME9C5MFMf7z347CM="; public static final String[] TEST_13_DATA = new String[] { Intermediate_Certificate_CP_04_01_crt, Intermediate_CRL_CP_04_01_crl, End_Certificate_CP_04_01_crt }; /* * test14 * */ public static final String Intermediate_Certificate_CP_04_02_crt = "MIIClTCCAf6gAwIBAgIBGzANBgkqhkiG9w0BAQUFADBeMQswCQYDVQQGEwJVUzEYMBYGA1" + "UEChMPVS5TLiBHb3Zlcm5tZW50MQwwCgYDVQQLEwNEb0QxEDAOBgNVBAsTB1Rlc3Rpbmcx" + "FTATBgNVBAMTDFRydXN0IEFuY2hvcjAeFw05ODAxMDExMjAxMDBaFw00ODAxMDExMjAxMD" + "BaMF4xCzAJBgNVBAYTAlVTMRgwFgYDVQQKEw9VLlMuIEdvdmVybm1lbnQxDDAKBgNVBAsT" + "A0RvRDEQMA4GA1UECxMHVGVzdGluZzEVMBMGA1UEAxMMQ0ExLUNQLjA0LjAyMIGfMA0GCS" + "qGSIb3DQEBAQUAA4GNADCBiQKBgQCteErspc5ekSOel/wmjn/XQ0HUy4XzxB5Zj0nGn9FD" + "PbjF2LERCHOn5aBnIMHYhyr7PDynwbvSx2egzGC6wGe9Zrri1MteirQ9Ppw7062IIleloy" + "UAiuwvD+s0npKsvboarQsCMfOB1hOB1tGG1bjXP6B5B187SZXuR3KawggyJwIDAQABo2Mw" + "YTAPBgNVHRMBAf8EBTADAQH/MA4GA1UdDwEB/wQEAwIBBjAWBgNVHSAEDzANMAsGCWCGSA" + "FlAwEwATARBgNVHQ4ECgQIUjnGp96itUMwEwYDVR0jBAwwCoAIq5rr+cLnVI8wDQYJKoZI" + "hvcNAQEFBQADgYEAR6fmN+9p5AWy/asEAiVBnbY9q7EQXyB8WuZK9FtFmupe3hlfcTq84E" + "A+TGvXOlNr05/1iLRv82GsWXDif7DlGVPN8CS1+0kb5Ve8Pmv2ziiWVREqWx916ioPjDRp" + "wvdGcCNC26+fyvv5TrP8uzojurl1ZlVRRqi2sIbopVX5r8w="; public static final String Intermediate_CRL_CP_04_02_crl = "MIIBSzCBtQIBATANBgkqhkiG9w0BAQUFADBeMQswCQYDVQQGEwJVUzEYMBYGA1UEChMPVS" + "5TLiBHb3Zlcm5tZW50MQwwCgYDVQQLEwNEb0QxEDAOBgNVBAsTB1Rlc3RpbmcxFTATBgNV" + "BAMTDENBMS1DUC4wNC4wMhcNOTkwMTAxMTIwMTAwWhcNNDgwMTAxMTIwMTAwWqAjMCEwCg" + "YDVR0UBAMCAQEwEwYDVR0jBAwwCoAIUjnGp96itUMwDQYJKoZIhvcNAQEFBQADgYEAZkXJ" + "aJG4QDE02wFURwaxWuv2VyD7m+N/2B0/9KR+6UKVpsMd2XHq+G3SlFOa6dA/fHUdhtUs2D" + "gpx3SfQYbcgKFrryZHqJDK230eP3F41S9g5XJTRaNR5iZvxvh4bmSf4l6a5MXsKEoBoJoT" + "j8cU4qg6j7Xk4NpIR1JbWiSIYQc="; public static final String End_Certificate_CP_04_02_crt = "MIIChjCCAe+gAwIBAgIBHDANBgkqhkiG9w0BAQUFADBeMQswCQYDVQQGEwJVUzEYMBYGA1" + "UEChMPVS5TLiBHb3Zlcm5tZW50MRAwDgYDVQQLEwdUZXN0aW5nMQwwCgYDVQQLEwNEb0Qx" + "FTATBgNVBAMTDENBMS1DUC4wNC4wMjAeFw05ODAxMDExMjAxMDBaFw00ODAxMDExMjAxMD" + "BaMGAxCzAJBgNVBAYTAlVTMRgwFgYDVQQKEw9VLlMuIEdvdmVybm1lbnQxDDAKBgNVBAsT" + "A0RvRDEQMA4GA1UECxMHVGVzdGluZzEXMBUGA1UEAxMOVXNlcjEtQ1AuMDQuMDIwgZ8wDQ" + "YJKoZIhvcNAQEBBQADgY0AMIGJAoGBALM7mfq+hpLfvQdqZUJfIx/2gFcgHS2AsgZn0An+" + "Yn61WtG8K2+lt/a8aypa/q+J93RVkRYKWKFQcJHiRgx7DMlXElVnfQbSFuLX46ng4hqmQL" + "sSOKmXDld2BlyMZ41B3rfdhJT8P12RMR6uAwvc9CH3b0UTcsc498Kj+JeaRbzxAgMBAAGj" + "UjBQMA4GA1UdDwEB/wQEAwIF4DAWBgNVHSAEDzANMAsGCWCGSAFlAwEwATARBgNVHQ4ECg" + "QIo7S64S6t5nswEwYDVR0jBAwwCoAIUjnGp96itUMwDQYJKoZIhvcNAQEFBQADgYEApNT5" + "Y+9Jc28m5Qwjm+/8SKk83iCPnIW3BsAvQUB9Wmd1+kMZvqLySQjm1tBBbcGYuSERMJ2Et5" + "eoTdL9B6EG2CZYnPqu1vk0TVugRxs7IJm4h5z4MCInf2g1KTt0AMEasQW6ZTj7DIkkU48Z" + "EKLPoBGXfD9t9Y9cmdj1e1RQbog="; public static final String[] TEST_14_DATA = new String[] { Intermediate_Certificate_CP_04_02_crt, Intermediate_CRL_CP_04_02_crl, End_Certificate_CP_04_02_crt }; /* * test15 * */ public static final String Intermediate_Certificate_CP_04_03_crt = "MIICmzCCAgSgAwIBAgIBHTANBgkqhkiG9w0BAQUFADBeMQswCQYDVQQGEwJVUzEYMBYGA1" + "UEChMPVS5TLiBHb3Zlcm5tZW50MQwwCgYDVQQLEwNEb0QxEDAOBgNVBAsTB1Rlc3Rpbmcx" + "FTATBgNVBAMTDFRydXN0IEFuY2hvcjAeFw05ODAxMDExMjAxMDBaFw00ODAxMDExMjAxMD" + "BaMGQxCzAJBgNVBAYTAlVTMRgwFgYDVQQKEw9VLlMuIEdvdmVybm1lbnQxDDAKBgNVBAsT" + "A0RvZDEQMA4GA1UECxMHVGVzdGluZzEbMBkGA1UEAxMSICBDQTEgLSAgIENQLjA0LjAzMI" + "GfMA0GCSqGSIb3DQEBAQUAA4GNADCBiQKBgQD11QBcw4P2rTUfPmbVNYqdo0AMmcB3Yxsx" + "Iz5me/S1I2PJLtRh9KP7lUV20SMEFsFKtE1C+9O7ODtOUCJA/6ECeXbyj20SbG1E2oQrZe" + "gkcn7IQDUgnuedzdFj4kTevok6ao9hycg+qeZrL6oeBD2XQCd9nqMmzhihNu/QOSnp5wID" + "AQABo2MwYTAPBgNVHRMBAf8EBTADAQH/MA4GA1UdDwEB/wQEAwIBBjAWBgNVHSAEDzANMA" + "sGCWCGSAFlAwEwATARBgNVHQ4ECgQInx+ELo31rJMwEwYDVR0jBAwwCoAIq5rr+cLnVI8w" + "DQYJKoZIhvcNAQEFBQADgYEAriYMoRDpSPI4HWrxN1rjqWIzggz8p1wpbEFgK5o/Fi2KT3" + "jCd6bfCcIFDpoXNqlsc+dvzc4XB1Eg/Qbcror8HP8LSxrbFw/y7VhC+wCaDCmhcqQn3rp/" + "WaOWnR7/H7HlKM9m1u7MBtwlxHINnLKwPHIA1XwmAnItAXIL2yHRJhU="; public static final String Intermediate_CRL_CP_04_03_crl = "MIIBUTCBuwIBATANBgkqhkiG9w0BAQUFADBkMQswCQYDVQQGEwJVUzEYMBYGA1UEChMPVS" + "5TLiBHb3Zlcm5tZW50MQwwCgYDVQQLEwNEb2QxEDAOBgNVBAsTB1Rlc3RpbmcxGzAZBgNV" + "BAMTEiAgQ0ExIC0gICBDUC4wNC4wMxcNOTkwMTAxMTIwMTAwWhcNNDgwMTAxMTIwMTAwWq" + "AjMCEwCgYDVR0UBAMCAQEwEwYDVR0jBAwwCoAInx+ELo31rJMwDQYJKoZIhvcNAQEFBQAD" + "gYEAvJgOX6tewnRbC9Ch+Fe4KjkB9IAhe5anQKGfnDHuLfga6JEjOzyfhonWZeppJwvYpl" + "1rZbsKICNphMDkd/eaWnn8Q9w02ah4kzIb0LuzrNBrxpFv9AAidfGU2VeF0gRi02jtAZsh" + "gUNbrdC+ovA8mAsBigy+HMzCi61+wrumwvo="; public static final String End_Certificate_CP_04_03_crt = "MIICijCCAfOgAwIBAgIBHjANBgkqhkiG9w0BAQUFADBiMQswCQYDVQQGEwJVUzEYMBYGA1" + "UEChMPVS5TLiBHb3Zlcm5tZW50MQwwCgYDVQQLEwNEb2QxEDAOBgNVBAsTB1Rlc3Rpbmcx" + "GTAXBgNVBAMTEGNhMSAtIENQLjA0LjAzICAwHhcNOTgwMTAxMTIwMTAwWhcNNDgwMTAxMT" + "IwMTAwWjBgMQswCQYDVQQGEwJVUzEYMBYGA1UEChMPVS5TLiBHb3Zlcm5tZW50MQwwCgYD" + "VQQLEwNEb0QxEDAOBgNVBAsTB1Rlc3RpbmcxFzAVBgNVBAMTDlVzZXIxLUNQLjA0LjAzMI" + "GfMA0GCSqGSIb3DQEBAQUAA4GNADCBiQKBgQC2Rd0VKnTIrME7hzpnpIPGXGXZCjpf5lSO" + "19zvB3WdZumLGdwUBXpIQTrl5teYgL62PpOwNC93URZDEUt+rqoqvs8E7MpF3IulStp2+H" + "/xa6Ihf4OmkgKjpHNTWOIFXeRJ4sVgWuH6cqQ+6GL+0fa1sed1crsEgTTAGYNhFi6ebwID" + "AQABo1IwUDAOBgNVHQ8BAf8EBAMCBeAwFgYDVR0gBA8wDTALBglghkgBZQMBMAEwEQYDVR" + "0OBAoECBNwCFdDgPCqMBMGA1UdIwQMMAqACJ8fhC6N9ayTMA0GCSqGSIb3DQEBBQUAA4GB" + "ABAjSPg794yiVz9RqdNxic8TGnApNrZui/vwr1U8ZkETZfx8W1fWgQ0z7KjryML5IOmvps" + "zycM7by6jb2kMmxI1SQCwjiNQ1fb1osrNAj2bRfpp2YgjjbHx1XkddommtVc0V8kvyQBcb" + "7NdxfbwKr8AtpiWTWIajc2uqUlELsLzr"; public static final String[] TEST_15_DATA = new String[] { Intermediate_Certificate_CP_04_03_crt, Intermediate_CRL_CP_04_03_crl, End_Certificate_CP_04_03_crt }; /* * test16 * */ public static final String Intermediate_Certificate_CP_04_04_crt = "MIIClzCCAgCgAwIBAgIBHzANBgkqhkiG9w0BAQUFADBeMQswCQYDVQQGEwJVUzEYMBYGA1" + "UEChMPVS5TLiBHb3Zlcm5tZW50MQwwCgYDVQQLEwNEb0QxEDAOBgNVBAsTB1Rlc3Rpbmcx" + "FTATBgNVBAMTDFRydXN0IEFuY2hvcjAeFw05ODAxMDExMjAxMDBaFw00ODAxMDExMjAxMD" + "BaMGAxCzAJBgNVBAYTAlVTMRgwFgYDVQQKEw9VLlMuIEdvdmVybm1lbnQxDDAKBgNVBAsT" + "A0RvZDEQMA4GA1UECxMHVGVzdGluZzEXMBUGA1UEAxMOQ0ExIC0gQ1AuMDQuMDQwgZ8wDQ" + "YJKoZIhvcNAQEBBQADgY0AMIGJAoGBAOFf5hr4R8IqTp53qQSiBEjOFQ3Q3ICcafl+FLzm" + "K3xIFqERjyXARsTM4gDQ9yntFeNp2TiIi98xBrz7D8TlrbTAmxO/PUfAQ68tXpz9Id/XrU" + "WeAKxMZULPL9nPFcGQoh0qq3JKpFRSb3Iobryfysblm7cCDDCJOI7uK14XZtTFAgMBAAGj" + "YzBhMA8GA1UdEwEB/wQFMAMBAf8wDgYDVR0PAQH/BAQDAgEGMBYGA1UdIAQPMA0wCwYJYI" + "ZIAWUDATABMBEGA1UdDgQKBAjior7qCuLBljATBgNVHSMEDDAKgAirmuv5wudUjzANBgkq" + "hkiG9w0BAQUFAAOBgQBhh55gTy5htqjxW1Ch2hRrRikhBH7LJz1PmDuzwiIOtnWL+EiQOY" + "T6h3NV1j8Kn5S4KhUOrhnvrPXRi22HdqRzEPl7y/wXm6G0XcgYlyy2ofZKdYVWCVStKAMW" + "5SwV2wC5RPK2KphdhnlEqss6QVRUsliDDjnf9Saiey9nzJAfNw=="; public static final String Intermediate_CRL_CP_04_04_crl = "MIIBTTCBtwIBATANBgkqhkiG9w0BAQUFADBgMQswCQYDVQQGEwJVUzEYMBYGA1UEChMPVS" + "5TLiBHb3Zlcm5tZW50MQwwCgYDVQQLEwNEb2QxEDAOBgNVBAsTB1Rlc3RpbmcxFzAVBgNV" + "BAMTDkNBMSAtIENQLjA0LjA0Fw05OTAxMDExMjAxMDBaFw00ODAxMDExMjAxMDBaoCMwIT" + "AKBgNVHRQEAwIBATATBgNVHSMEDDAKgAjior7qCuLBljANBgkqhkiG9w0BAQUFAAOBgQBI" + "VlXD5FnIiO8tavLJ8qo/qRhbBNgUbFBdAgAY6yVnFNP6YN4qPineYPN6NV1XdqNDrZh2Nz" + "GHzX3YDo1Uv9yABVR0NvXCaMIW5/raqZp/on6bPuQLgJe9UisOPKunzehTm/NmO1RW9dwU" + "37UzC0XnVHyVipDVh07DrTKBUtQJQw=="; public static final String End_Certificate_CP_04_04_crt = "MIICjTCCAfagAwIBAgIBIDANBgkqhkiG9w0BAQUFADBlMQswCQYDVQQGEwJVUzEZMBcGA1" + "UEChMQVS5TLiAgR292ZXJubWVudDEMMAoGA1UECxMDRG9EMRAwDgYDVQQLEwdUZXN0aW5n" + "MRswGQYDVQQDExJDQTEgICAgLSAgQ1AuMDQuMDQwHhcNOTgwMTAxMTIwMTAwWhcNNDgwMT" + "AxMTIwMTAwWjBgMQswCQYDVQQGEwJVUzEYMBYGA1UEChMPVS5TLiBHb3Zlcm5tZW50MQww" + "CgYDVQQLEwNEb0QxEDAOBgNVBAsTB1Rlc3RpbmcxFzAVBgNVBAMTDlVzZXIxLUNQLjA0Lj" + "A0MIGfMA0GCSqGSIb3DQEBAQUAA4GNADCBiQKBgQCegy6qOnM14CS7+enBElgh2DLtF5bn" + "ah0yfA18/hbqnmUaWOWJQllyXa8QFawnvdXOOEXJm1ErIm3rDYihkbUTP+ybOBH9dprWtl" + "1cSGL9CkoxwzkJRLQTu5xG72EhET3S3kwqZsmYbgy4MduGKv9VGFbv75Wr17Vo9K4Lz6QK" + "vQIDAQABo1IwUDAOBgNVHQ8BAf8EBAMCBeAwFgYDVR0gBA8wDTALBglghkgBZQMBMAEwEQ" + "YDVR0OBAoECEc4b3BP059HMBMGA1UdIwQMMAqACOKivuoK4sGWMA0GCSqGSIb3DQEBBQUA" + "A4GBADj73jXpPLev5crwZIoXCJd/nXXp1fJzEEbByWggsR9cFHN4wnp7N6gpIxQbLQwjmo" + "cLPC1pHQ3A5VHVrCbxAk6nifmSvnKFWHTBftZGpfTGkrXbURFF64T/CB4O+JXr1eBUGheN" + "Q0T8L17UNgi3oBENKjASWnpjxvD2QrOnH0rb"; public static final String[] TEST_16_DATA = new String[] { Intermediate_Certificate_CP_04_04_crt, Intermediate_CRL_CP_04_04_crl, End_Certificate_CP_04_04_crt }; /* * test17 * */ public static final String Intermediate_Certificate_CP_04_05_crt = "MIIClzCCAgCgAwIBAgIBITANBgkqhkiG9w0BAQUFADBeMQswCQYDVQQGEwJVUzEYMBYGA1" + "UEChMPVS5TLiBHb3Zlcm5tZW50MQwwCgYDVQQLEwNEb0QxEDAOBgNVBAsTB1Rlc3Rpbmcx" + "FTATBgNVBAMTDFRydXN0IEFuY2hvcjAeFw05ODAxMDExMjAxMDBaFw00ODAxMDExMjAxMD" + "BaMGAxCzAJBgNVBAYTAlVTMRgwFgYDVQQKEw9VLlMuIEdvdmVybm1lbnQxDDAKBgNVBAsT" + "A0RvZDEQMA4GA1UECxMHVGVzdGluZzEXMBUGA1UEAxMOICBDQTEtQ1AuMDQuMDUwgZ8wDQ" + "YJKoZIhvcNAQEBBQADgY0AMIGJAoGBAMBsWmrcKH0J9bkI3zHthZ0S3904f3fMUSasY5qp" + "7CSQ0sbXTwP947sfAPK4Dso6Bpwl0WExRCdFHd6qfY9wR+NtfuI/DkFEY8WveoqM4Vskpi" + "cutWghCx14PiPY5YGFn8VvXu7wbuHp4TnHtUCMEUt3EfYO5oqm+/I8y0eTKMNHAgMBAAGj" + "YzBhMA8GA1UdEwEB/wQFMAMBAf8wDgYDVR0PAQH/BAQDAgEGMBYGA1UdIAQPMA0wCwYJYI" + "ZIAWUDATABMBEGA1UdDgQKBAjOoKlp+BfGqTATBgNVHSMEDDAKgAirmuv5wudUjzANBgkq" + "hkiG9w0BAQUFAAOBgQDLhQ/RJFqMDNRonAHZ30DYyphf8do4q6ARikhhXSSa6G2G/PzbpS" + "x3T+3G8ot+NnFhtf9ZWo7KfwmFEbUA/B/X2vJaJbNImkMDT1aTY5sPXtA69B3QKQVz7HST" + "f5XH6DjuoV0/m1M153A4vf1Z783dOPw1MzOq19t+6tYFeELEHQ=="; public static final String Intermediate_CRL_CP_04_05_crl = "MIIBTTCBtwIBATANBgkqhkiG9w0BAQUFADBgMQswCQYDVQQGEwJVUzEYMBYGA1UEChMPVS" + "5TLiBHb3Zlcm5tZW50MQwwCgYDVQQLEwNEb2QxEDAOBgNVBAsTB1Rlc3RpbmcxFzAVBgNV" + "BAMTDiAgQ0ExLUNQLjA0LjA1Fw05OTAxMDExMjAxMDBaFw00ODAxMDExMjAxMDBaoCMwIT" + "AKBgNVHRQEAwIBATATBgNVHSMEDDAKgAjOoKlp+BfGqTANBgkqhkiG9w0BAQUFAAOBgQAp" + "6gLCdPQw7Hisnr1i3QbD7GybqfD6b1s10GQ3c/j59RYDe1Fk47Srs9ol/baleasWjcdt8M" + "SlTc66KvK9YPFAqIdYoOW4FidpJBF/1cvSc2hGYwVsxLnXKr9CJ5Py5vBCCjovIRiLdzoL" + "ZoteOKFIEHkV7V8V2OTFawxpW9hkiA=="; public static final String End_Certificate_CP_04_05_crt = "MIICiDCCAfGgAwIBAgIBIjANBgkqhkiG9w0BAQUFADBgMQswCQYDVQQGEwJVUzEYMBYGA1" + "UEChMPVS5TLiBHb3Zlcm5tZW50MQwwCgYDVQQLEwNEb2QxEDAOBgNVBAsTB1Rlc3Rpbmcx" + "FzAVBgNVBAMTDkNBMS1DUC4wNC4wNSAgMB4XDTk4MDEwMTEyMDEwMFoXDTQ4MDEwMTEyMD" + "EwMFowYDELMAkGA1UEBhMCVVMxGDAWBgNVBAoTD1UuUy4gR292ZXJubWVudDEMMAoGA1UE" + "CxMDRG9EMRAwDgYDVQQLEwdUZXN0aW5nMRcwFQYDVQQDEw5Vc2VyMS1DUC4wNC4wNTCBnz" + "ANBgkqhkiG9w0BAQEFAAOBjQAwgYkCgYEAwZsiUhXiFHN9dfJb0Yyy+rYtV8gx+d0+8WkW" + "5C68nQgSqqk2uSTpvZbx0bpHF+s+LKppj2M2tt/AfZgVQHTsp5rO0IftZE2iLwqejj0rYU" + "Poprq1PE3vVhs818ZlDS0PTUP97YxLysQjq2jS/d/9lF5pS3sMlP4Usp24gXX0vG0CAwEA" + "AaNSMFAwDgYDVR0PAQH/BAQDAgXgMBYGA1UdIAQPMA0wCwYJYIZIAWUDATABMBEGA1UdDg" + "QKBAjpC0ZvCXrvBTATBgNVHSMEDDAKgAjOoKlp+BfGqTANBgkqhkiG9w0BAQUFAAOBgQB7" + "YwJWcx+PU1sUZUOVleoB5amHFu0GT+Hy7cRa82UJMHFkz0bmnyEV8CBNcnn0xa5iVfwe2y" + "5ZKwy61DLR3MPTar9eKITL67uZag9w+1tnIf594XRbEiUzn20uxuDFX3oPoZCemtWdVanj" + "2T+9TVQKfrp15+qzOCObNNRHZw29EA=="; public static final String[] TEST_17_DATA = new String[] { Intermediate_Certificate_CP_04_05_crt, Intermediate_CRL_CP_04_05_crl, End_Certificate_CP_04_05_crt }; /* * test18 * */ public static final String Intermediate_Certificate_CP_04_06_crt = "MIIClTCCAf6gAwIBAgIBIzANBgkqhkiG9w0BAQUFADBeMQswCQYDVQQGEwJVUzEYMBYGA1" + "UEChMPVS5TLiBHb3Zlcm5tZW50MQwwCgYDVQQLEwNEb0QxEDAOBgNVBAsTB1Rlc3Rpbmcx" + "FTATBgNVBAMTDFRydXN0IEFuY2hvcjAeFw05ODAxMDExMjAxMDBaFw00ODAxMDExMjAxMD" + "BaMF4xCzAJBgNVBAYTAlVTMRgwFgYDVQQKEw9VLlMuIEdvdmVybm1lbnQxDDAKBgNVBAsT" + "A0RvZDEQMA4GA1UECxMHVGVzdGluZzEVMBMGA1UEAxMMQ0ExLUNQLjA0LjA2MIGfMA0GCS" + "qGSIb3DQEBAQUAA4GNADCBiQKBgQD0t0dfe82Su58bJdn4dh7E3OCam1AUPTzPnt7DwT2w" + "1XwD76OCUYP7SBBjsLYDDfUCb2ek96pSK4jpzyE6/4IOtfObe7OW+iBT9YAB5WeW+SmvEO" + "TIX+xo13sbz6rG6j9svcOxtth98yv7mxzV/ZwTNBSO72CcfDXIIq20TVunlwIDAQABo2Mw" + "YTAPBgNVHRMBAf8EBTADAQH/MA4GA1UdDwEB/wQEAwIBBjAWBgNVHSAEDzANMAsGCWCGSA" + "FlAwEwATARBgNVHQ4ECgQI0AufZEn1f9AwEwYDVR0jBAwwCoAIq5rr+cLnVI8wDQYJKoZI" + "hvcNAQEFBQADgYEAbfhxuNBYizxfMZNcyiN61j+7LXZZo3SmMU21UmOhPBTmdTbIkuVCI+" + "F1jSWdu3eGShVNJ3jmkidDvojMm+E8ZZ1YGHYfgeG16dDQudaGUjGmOfYzzlkFmsaf0paG" + "4y4sBerPsZCmhN7BanGh3qYPFvadSmp3OapGfEmDtS+BbVQ="; public static final String Intermediate_CRL_CP_04_06_crl = "MIIBSzCBtQIBATANBgkqhkiG9w0BAQUFADBeMQswCQYDVQQGEwJVUzEYMBYGA1UEChMPVS" + "5TLiBHb3Zlcm5tZW50MQwwCgYDVQQLEwNEb2QxEDAOBgNVBAsTB1Rlc3RpbmcxFTATBgNV" + "BAMTDENBMS1DUC4wNC4wNhcNOTkwMTAxMTIwMTAwWhcNNDgwMTAxMTIwMTAwWqAjMCEwCg" + "YDVR0UBAMCAQEwEwYDVR0jBAwwCoAI0AufZEn1f9AwDQYJKoZIhvcNAQEFBQADgYEAIAI7" + "W6K69twJZnHx6CoIMs5+P9DrJ2yKHptmntlOCTSJirC/xdj0Zv2k5FW84VrTtdCSZDT1Ce" + "4Dh69fT2sUUexJb/4IcDtzloiuASSJzKWCeVIj9A8e6+coNUJVKtRKRX8bHJ5Un7xpFrY6" + "t1hdxt8gUecAAdXEFGuZ3QEHHN0="; public static final String End_Certificate_CP_04_06_crt = "MIIChjCCAe+gAwIBAgIBJDANBgkqhkiG9w0BAQUFADBeMQswCQYDVQQGEwJVUzEYMBYGA1" + "UEChMPdS5zLiBHT1ZFUk5NRU5UMQwwCgYDVQQLEwNEb0QxEDAOBgNVBAsTB1RFU1RJTkcx" + "FTATBgNVBAMTDGNhMS1DUC4wNC4wNjAeFw05ODAxMDExMjAxMDBaFw00ODAxMDExMjAxMD" + "BaMGAxCzAJBgNVBAYTAlVTMRgwFgYDVQQKEw9VLlMuIEdvdmVybm1lbnQxDDAKBgNVBAsT" + "A0RvRDEQMA4GA1UECxMHVGVzdGluZzEXMBUGA1UEAxMOVXNlcjEtQ1AuMDQuMDYwgZ8wDQ" + "YJKoZIhvcNAQEBBQADgY0AMIGJAoGBAKq8rAPXsu1RVm3vT7od7CDLn8k/C3x3wvfzoWrm" + "W0cmlhp9xRy5a3HWiJATD8yCKY1psBgnrOpv37sdtUX4P2kf668HrYOaGo365fKPeT5Wjm" + "gp0pL3sXKNNsCuJPd3wKAXGHAi1R9arZFYPsKJlfQl1774dwAvzxSOMr5+pbnzAgMBAAGj" + "UjBQMA4GA1UdDwEB/wQEAwIF4DAWBgNVHSAEDzANMAsGCWCGSAFlAwEwATARBgNVHQ4ECg" + "QI33MEYdo5YX4wEwYDVR0jBAwwCoAI0AufZEn1f9AwDQYJKoZIhvcNAQEFBQADgYEAo8Ge" + "ADBoJFEIRzdO37uasuyIBhClTUgyFhEKemMBN6aelYeiJMX6FZIL3DgZOce4dg7Zg3Ak/w" + "B5m8XlGQLW9xIbpEzY/Iq9kr+qK6k9YmvtcOiHFbnudCFNZngTQZpxjiDaj4eA48uqKIxs" + "51taC5gOv9LYWPnugN8TsUUFZ1s="; public static final String[] TEST_18_DATA = new String[] { Intermediate_Certificate_CP_04_06_crt, Intermediate_CRL_CP_04_06_crl, End_Certificate_CP_04_06_crt }; /* * test19 * */ public static final String Intermediate_Certificate_CP_05_01_crt = "MIIClTCCAf6gAwIBAgIBJTANBgkqhkiG9w0BAQUFADBeMQswCQYDVQQGEwJVUzEYMBYGA1" + "UEChMPVS5TLiBHb3Zlcm5tZW50MQwwCgYDVQQLEwNEb0QxEDAOBgNVBAsTB1Rlc3Rpbmcx" + "FTATBgNVBAMTDFRydXN0IEFuY2hvcjAeFw05ODAxMDExMjAxMDBaFw00ODAxMDExMjAxMD" + "BaMF4xCzAJBgNVBAYTAlVTMRgwFgYDVQQKEw9VLlMuIEdvdmVybm1lbnQxDDAKBgNVBAsT" + "A0RvZDEQMA4GA1UECxMHVGVzdGluZzEVMBMGA1UEAxMMQ0ExLUNQLjA1LjAxMIGfMA0GCS" + "qGSIb3DQEBAQUAA4GNADCBiQKBgQCshocJtyGsxeEd2ouVTVKp+HuhDjnDk9eXtaLQIKaB" + "7aTODHYbq1mC+1LO5DmRV5PBVd8NuuCA+1DmzFrfYl+nMCjjgOkC0//Gf9O85Hi/n21q0T" + "F+oVa1j9fc7nAgLIziexaXrflYSbaeNWkwHHftGUninKPuNGM2re0krEeurQIDAQABo2Mw" + "YTAPBgNVHRMBAf8EBTADAQH/MA4GA1UdDwEB/wQEAwIBBjAWBgNVHSAEDzANMAsGCWCGSA" + "FlAwEwATARBgNVHQ4ECgQIaUi/P20o4LcwEwYDVR0jBAwwCoAIq5rr+cLnVI8wDQYJKoZI" + "hvcNAQEFBQADgYEAWBLeJl4qlAPKxmBM5QZ2JYsbCV3VBeYGAKQ+4L7ehS63VQMCwIjBCI" + "LaHGIFfCqecDNd6cpYIArdx4tY7X2/Zxm3j5ocngpI1Tv8zydQcFeraILglsHf2UZUuK/N" + "6jKGjwL68C8YwmA+u6ZhcQFD2Xg4wSMC/xxzAs9zEAQGBPo="; public static final String End_Certificate_CP_05_01_crt = "MIIChjCCAe+gAwIBAgIBJjANBgkqhkiG9w0BAQUFADBeMQswCQYDVQQGEwJVUzEYMBYGA1" + "UEChMPVS5TLiBHb3Zlcm5tZW50MQwwCgYDVQQLEwNEb2QxEDAOBgNVBAsTB1Rlc3Rpbmcx" + "FTATBgNVBAMTDENBMS1DUC4wNS4wMTAeFw05ODAxMDExMjAxMDBaFw00ODAxMDExMjAxMD" + "BaMGAxCzAJBgNVBAYTAlVTMRgwFgYDVQQKEw9VLlMuIEdvdmVybm1lbnQxDDAKBgNVBAsT" + "A0RvRDEQMA4GA1UECxMHVGVzdGluZzEXMBUGA1UEAxMOVXNlcjEtQ1AuMDUuMDEwgZ8wDQ" + "YJKoZIhvcNAQEBBQADgY0AMIGJAoGBAO9ODA12Fky/Md5AELkaOvOwB31UlfZq3SHAOvs0" + "Y4NYoA7Q5KDIwW8RNzMSKD30z51VlgOAaBVR6HLo6rkcWB4wGiV7EPelewdSOdk72IrnYR" + "npJEm2KEuLkHB+gejgk+paw8CejxMsrvT6loN8Pz0btBKxWaCfknTIyXVyQsolAgMBAAGj" + "UjBQMA4GA1UdDwEB/wQEAwIF4DAWBgNVHSAEDzANMAsGCWCGSAFlAwEwATARBgNVHQ4ECg" + "QI5LtSKs/inGMwEwYDVR0jBAwwCoAIaUi/P20o4LcwDQYJKoZIhvcNAQEFBQADgYEAOMrC" + "38uzHckKMkiawXhPUHtDQfyR7bLweS2qro7GyndfxPpeMJwjzVxqvQBtMuHON+al8jyXpy" + "BsEryV6qvdFC1vczLzJHAJZmLe5np27zQIXOObsyYcOG+aPq727/pKoD90DAlBvrxNW0ox" + "x7citflEYpmOEv9Do5xiO3MuCFw="; public static final String[] TEST_19_DATA = new String[] { Intermediate_Certificate_CP_05_01_crt, End_Certificate_CP_05_01_crt }; /* * test20 * */ public static final String Intermediate_Certificate_CP_06_01_crt = "MIIClTCCAf6gAwIBAgIBJzANBgkqhkiG9w0BAQUFADBeMQswCQYDVQQGEwJVUzEYMBYGA1" + "UEChMPVS5TLiBHb3Zlcm5tZW50MQwwCgYDVQQLEwNEb0QxEDAOBgNVBAsTB1Rlc3Rpbmcx" + "FTATBgNVBAMTDFRydXN0IEFuY2hvcjAeFw05ODAxMDExMjAxMDBaFw00ODAxMDExMjAxMD" + "BaMF4xCzAJBgNVBAYTAlVTMRgwFgYDVQQKEw9VLlMuIEdvdmVybm1lbnQxDDAKBgNVBAsT" + "A0RvZDEQMA4GA1UECxMHVGVzdGluZzEVMBMGA1UEAxMMQ0ExLUNQLjA2LjAxMIGfMA0GCS" + "qGSIb3DQEBAQUAA4GNADCBiQKBgQDI4MXZB08BfUHxo//4Re7Ax0qWkHgy6nb+/XaLQ2Fw" + "Pbvpb5mkhLhqDZBSX3KQL0YiJ8p81tmdvRQH/LbFzX/3OKBTUfV5imYy979A2NEb4otFp6" + "EDSskZhttY3d2IzUICoCWUXhObnmkHJ2jEc81bggFkK5Lir1m/tKq2IOPFJQIDAQABo2Mw" + "YTAPBgNVHRMBAf8EBTADAQH/MA4GA1UdDwEB/wQEAwIBBjAWBgNVHSAEDzANMAsGCWCGSA" + "FlAwEwATARBgNVHQ4ECgQICIAmlz6+Cc0wEwYDVR0jBAwwCoAIq5rr+cLnVI8wDQYJKoZI" + "hvcNAQEFBQADgYEA0ZvIG2cnk32p6uxqGw8Bu40NrfHu9gNkJL5MhDHJXA6OxU5BX5bWZp" + "LnKXLoHiqSdtEdmy5cLZw3kggxndxjsnRFMyCawaYupJBhlgquFbuvBtA8rMtkc5H4zudP" + "ZcOcvXu7Xw58K+1caSGURL+A6uXFPnMUBd1+k+ejbtO8Pto="; public static final String Intermediate_CRL_CP_06_01_crl = "MIIBSzCBtQIBATANBgkqhkiG9w0BAQUFADBeMQswCQYDVQQGEwJVUzEYMBYGA1UEChMPVS" + "5TLiBHb3Zlcm5tZW50MQwwCgYDVQQLEwNEb2QxEDAOBgNVBAsTB1Rlc3RpbmcxFTATBgNV" + "BAMTDENBMS1DUC4wNi4wMRcNOTkwMTAxMTIwMTAwWhcNNDgwMTAxMTIwMTAwWqAjMCEwCg" + "YDVR0UBAMCAQEwEwYDVR0jBAwwCoAICIAmlz6+Cc0wDQYJKoZIhvcNAQEFBQADgYEAbkJe" + "jfc1rztCbtC6xJZ3iZEDDMW2CxFvOvSwhmCjPqVY3lrCPNSQzdjmqepioCnu7ongP+HAA7" + "hM7bm+SoN7KzXKufQ7C2ONoAwvoPZgnoidg7RVECxUByD6AJu04yd2wCLYRpCfS2tDtXLh" + "HEDpe+ELwv35pbkCMlCO2u7J+Tc="; public static final String End_Certificate_CP_06_01_crt = "MIIChjCCAe+gAwIBAgIBKDANBgkqhkiG9w0BAQUFADBeMQswCQYDVQQGEwJVUzEYMBYGA1" + "UEChMPVS5TLiBHb3Zlcm5tZW50MQwwCgYDVQQLEwNEb2QxEDAOBgNVBAsTB1Rlc3Rpbmcx" + "FTATBgNVBAMTDENBMS1DUC4wNi4wMTAeFw05ODAxMDExMjAxMDBaFw00ODAxMDExMjAxMD" + "BaMGAxCzAJBgNVBAYTAlVTMRgwFgYDVQQKEw9VLlMuIEdvdmVybm1lbnQxDDAKBgNVBAsT" + "A0RvRDEQMA4GA1UECxMHVGVzdGluZzEXMBUGA1UEAxMOVXNlcjEtQ1AuMDYuMDEwgZ8wDQ" + "YJKoZIhvcNAQEBBQADgY0AMIGJAoGBAOh7lUwMRet7t/ABI6mo27CsnRzQ64Xx7f1dqxrJ" + "NuuSRslVShaWnwiGHjc+5/TS7Urfj9VO0dseBCzPsyYFoIX1q7Q5zlArwy24qpXTGMmlpE" + "GByzi7jkXO8w5+wqh3+8RFrQQzr71zLtAVV/qPUyleuF8M8jzkwfPvawunmwdLAgMBAAGj" + "UjBQMA4GA1UdDwEB/wQEAwIF4DAWBgNVHSAEDzANMAsGCWCGSAFlAwEwATARBgNVHQ4ECg" + "QIayC0PPU9zyswEwYDVR0jBAwwCoAICIAmlz6+Cc0wDQYJKoZIhvcNAQEFBQADgYEAPz7b" + "UvaEV7Myjhe8LJO/soj84X71rvVPtBPrhYjWTJ6p69GCfJRyho3vAUIt8RFal1GFb72c45" + "DQGkcVzLLJw8cDP3ajtWac5HZ9dNPJkW+Kh12l9gqjn061XAjQ4XnbbwQDYCuXhguPE9v3" + "kzDbimwVwIEOB/4SARX37y7TUWk="; public static final String[] TEST_20_DATA = new String[] { Intermediate_Certificate_CP_06_01_crt, Intermediate_CRL_CP_06_01_crl, End_Certificate_CP_06_01_crt }; /* * test21 * */ public static final String Intermediate_Certificate_CP_06_02_crt = "MIIClTCCAf6gAwIBAgIBKTANBgkqhkiG9w0BAQUFADBeMQswCQYDVQQGEwJVUzEYMBYGA1" + "UEChMPVS5TLiBHb3Zlcm5tZW50MQwwCgYDVQQLEwNEb0QxEDAOBgNVBAsTB1Rlc3Rpbmcx" + "FTATBgNVBAMTDFRydXN0IEFuY2hvcjAeFw05ODAxMDExMjAxMDBaFw00ODAxMDExMjAxMD" + "BaMF4xCzAJBgNVBAYTAlVTMRgwFgYDVQQKEw9VLlMuIEdvdmVybm1lbnQxDDAKBgNVBAsT" + "A0RvZDEQMA4GA1UECxMHVGVzdGluZzEVMBMGA1UEAxMMQ0ExLUNQLjA2LjAyMIGfMA0GCS" + "qGSIb3DQEBAQUAA4GNADCBiQKBgQC/IejV3DmeaLW8OwMfAGyr5+8NOxM1C+UBYslbOfWj" + "KUGdhlX6TxFc5AOJVJBpS/QjeA+RWoUCxnxKb9QSlOrBmADrcnGz8zV0/c0JDLaU3oSgsV" + "EWZE0SexBVWrKcl1j7wN0RuxMeAp342/YoyvBwea3VeqJkmSCc7Y2TjruWEQIDAQABo2Mw" + "YTAPBgNVHRMBAf8EBTADAQH/MA4GA1UdDwEB/wQEAwIBBjAWBgNVHSAEDzANMAsGCWCGSA" + "FlAwEwATARBgNVHQ4ECgQIaHxWOdHsLbUwEwYDVR0jBAwwCoAIq5rr+cLnVI8wDQYJKoZI" + "hvcNAQEFBQADgYEAuzeq/lqp0qs62krK6EA81Silhy42l/KmynE3mVu9GPBgQS0BUDi7+r" + "QQ+m0UxYElzj2SNO4J5aBYeC98lVJFCHX7QE8yVOoPBQd5rA+rrz4HD9QoP7glxTqLU6Tc" + "9VFd+iaFpqsVtSh2bxH2BtUB2ARgebTklaNl5VPbu0+yc2I="; public static final String Intermediate_CRL_CP_06_02_crl = "MIIBbzCB2QIBATANBgkqhkiG9w0BAQUFADBeMQswCQYDVQQGEwJVUzEYMBYGA1UEChMPVS" + "5TLiBHb3Zlcm5tZW50MQwwCgYDVQQLEwNEb2QxEDAOBgNVBAsTB1Rlc3RpbmcxFTATBgNV" + "BAMTDENBMS1DUC4wNi4wMhcNOTkwMTAxMTIwMTAwWhcNNDgwMTAxMTIwMTAwWjAiMCACAS" + "oXDTk5MDEwMTEyMDAwMFowDDAKBgNVHRUEAwoBAaAjMCEwCgYDVR0UBAMCAQEwEwYDVR0j" + "BAwwCoAIaHxWOdHsLbUwDQYJKoZIhvcNAQEFBQADgYEAYGaAzVoUdlSZ3uGKiRPfHAFIoK" + "T79hNOvtOxaGA0aIek9OypDrDqYAh/s2jsXSheL0pr/v9WRIHvtCt7ytXDxVyn4Nxjpfv7" + "BkAMMiccdUx1OH1VElTRkmmtMe7ROzUeHUGzXJNPex1Bc9BvSChH18bWYckyOZdYJBjctC" + "KJFgw="; public static final String End_Certificate_CP_06_02_crt = "MIIChjCCAe+gAwIBAgIBKjANBgkqhkiG9w0BAQUFADBeMQswCQYDVQQGEwJVUzEYMBYGA1" + "UEChMPVS5TLiBHb3Zlcm5tZW50MQwwCgYDVQQLEwNEb2QxEDAOBgNVBAsTB1Rlc3Rpbmcx" + "FTATBgNVBAMTDENBMS1DUC4wNi4wMjAeFw05ODAxMDExMjAxMDBaFw00ODAxMDExMjAxMD" + "BaMGAxCzAJBgNVBAYTAlVTMRgwFgYDVQQKEw9VLlMuIEdvdmVybm1lbnQxDDAKBgNVBAsT" + "A0RvRDEQMA4GA1UECxMHVGVzdGluZzEXMBUGA1UEAxMOVXNlcjEtQ1AuMDYuMDIwgZ8wDQ" + "YJKoZIhvcNAQEBBQADgY0AMIGJAoGBAK4D9H8JxeIrFuOmx0cSkIYNS0p7cDSBlcc57Na3" + "+1k7lJD7mE9ZP6/47YsDVK2bwe4aTKCTXtPk/kGQ6bsLswJXbyW4k4+f5LeAYoXgbmZXjA" + "WF+BKIl8uKetsqC3HkCeqhBaY1AGUqef4oOAkakEP+1jYFumNYtMaB+9x/0ncBAgMBAAGj" + "UjBQMA4GA1UdDwEB/wQEAwIF4DAWBgNVHSAEDzANMAsGCWCGSAFlAwEwATARBgNVHQ4ECg" + "QIC9MiJNI71RMwEwYDVR0jBAwwCoAIaHxWOdHsLbUwDQYJKoZIhvcNAQEFBQADgYEAo/ib" + "mIxteityjZlszjCc/s7yM/0snL78pYpMOZ3P2TPKkYh2Th4+Bw8JqX10+M/zwFBj5Bw7Im" + "zCIRfS3GFuKmcVcyHB4OZLMcQZtXWA8GOZ94YvWq5TBINlVtThQtusQj15KBq2TJNNFUyD" + "pBdvyo05AnEsRY0HbIQu6ZhNQ40="; public static final String[] TEST_21_DATA = new String[] { Intermediate_Certificate_CP_06_02_crt, Intermediate_CRL_CP_06_02_crl, End_Certificate_CP_06_02_crt }; /* * test22 * */ public static final String Intermediate_Certificate_IC_01_01_crt = "MIIChDCCAe2gAwIBAgIBKzANBgkqhkiG9w0BAQUFADBeMQswCQYDVQQGEwJVUzEYMBYGA1" + "UEChMPVS5TLiBHb3Zlcm5tZW50MQwwCgYDVQQLEwNEb0QxEDAOBgNVBAsTB1Rlc3Rpbmcx" + "FTATBgNVBAMTDFRydXN0IEFuY2hvcjAeFw05ODAxMDExMjAxMDBaFw00ODAxMDExMjAxMD" + "BaMF4xCzAJBgNVBAYTAlVTMRgwFgYDVQQKEw9VLlMuIEdvdmVybm1lbnQxDDAKBgNVBAsT" + "A0RvZDEQMA4GA1UECxMHVGVzdGluZzEVMBMGA1UEAxMMQ0ExLUlDLjAxLjAxMIGfMA0GCS" + "qGSIb3DQEBAQUAA4GNADCBiQKBgQDDOu1J/VIzbB4VcS2Dwf2fsHOmIj3iatM8y61V7CrN" + "RCxCWTJ1Os8e/mFWOi/zN+0afizA0UzJDTe8L++/RlP68IFg5Ju2OhXqQC3HbUZmQ7ve9g" + "QdWTfur3oEJV6/XoVE4WG0Ic7D1p7BENb3LUT+8MJdSboTvAggA1CiOI6zRQIDAQABo1Iw" + "UDAOBgNVHQ8BAf8EBAMCAQYwFgYDVR0gBA8wDTALBglghkgBZQMBMAEwEQYDVR0OBAoECP" + "RyRiSV+4XrMBMGA1UdIwQMMAqACKua6/nC51SPMA0GCSqGSIb3DQEBBQUAA4GBAJlmJ9EW" + "9ujUosqHZyZkniu2vX8VOL52OnxtLxw3LqxLyuxivjyYCaMAaJNr7/xfm3C2ozh9mQyZTQ" + "6TpBapLFUH8QsEKUhy57MDUgIvZsyOvvjJh3AXfSkXDaMZ3ncLg6x0wwjN/Hxu9i+IhX1W" + "1E7/5foGx7AEVfwY7Fo9S82d"; public static final String Intermediate_CRL_IC_01_01_crl = "MIIBSzCBtQIBATANBgkqhkiG9w0BAQUFADBeMQswCQYDVQQGEwJVUzEYMBYGA1UEChMPVS" + "5TLiBHb3Zlcm5tZW50MQwwCgYDVQQLEwNEb2QxEDAOBgNVBAsTB1Rlc3RpbmcxFTATBgNV" + "BAMTDENBMS1JQy4wMS4wMRcNOTkwMTAxMTIwMTAwWhcNNDgwMTAxMTIwMTAwWqAjMCEwCg" + "YDVR0UBAMCAQEwEwYDVR0jBAwwCoAI9HJGJJX7heswDQYJKoZIhvcNAQEFBQADgYEAV4DM" + "F5gU8MZ6E/mnjAWS+dIRKUBJV1GZJ+hOysdbmK1hD0mj5Pd5qTzlcvLjuatIoIsB5DCpYd" + "AcNRLVvF5EJFhVjqsPzRlfUZth0Xqa+U/DeHjVxHxYsLEOSt+v2bLkbGh88SmOAk6F8xj1" + "l7YIfPX5cIkUBTVZlsUt51slMXc="; public static final String End_Certificate_IC_01_01_crt = "MIIChjCCAe+gAwIBAgIBLDANBgkqhkiG9w0BAQUFADBeMQswCQYDVQQGEwJVUzEYMBYGA1" + "UEChMPVS5TLiBHb3Zlcm5tZW50MQwwCgYDVQQLEwNEb2QxEDAOBgNVBAsTB1Rlc3Rpbmcx" + "FTATBgNVBAMTDENBMS1JQy4wMS4wMTAeFw05ODAxMDExMjAxMDBaFw00ODAxMDExMjAxMD" + "BaMGAxCzAJBgNVBAYTAlVTMRgwFgYDVQQKEw9VLlMuIEdvdmVybm1lbnQxDDAKBgNVBAsT" + "A0RvRDEQMA4GA1UECxMHVGVzdGluZzEXMBUGA1UEAxMOVXNlcjEtSUMuMDEuMDEwgZ8wDQ" + "YJKoZIhvcNAQEBBQADgY0AMIGJAoGBAPrk1fosBu0hemIKgTDCeV/RoFbbsm02X4LfZonX" + "KeGRGYZXz4tpWgbNpjKBq1e/2bOO1DCn9I8I2kjvZdOkabk4MLeuRDo/sqlNndu4Ar5502" + "pAo4A2V0QLR4IDHAJoDpxtSFrqELOiiyCx9O9V19ywe5pcBFrxVEWDqTnBUeDJAgMBAAGj" + "UjBQMA4GA1UdDwEB/wQEAwIF4DAWBgNVHSAEDzANMAsGCWCGSAFlAwEwATARBgNVHQ4ECg" + "QIbI6BhABrmQ8wEwYDVR0jBAwwCoAI9HJGJJX7heswDQYJKoZIhvcNAQEFBQADgYEAYzYy" + "M0wbzNhZftAWz7TfFi64uA9WmTmd4MeK9vga4ChswT4H1zlaV1Sr+3hqpGmOoP5AUd9XIq" + "O/ui+/gFaeuOLI+ATmK+V2KHGAneMwzcw9qbXRc+xZqGGjbXMb3Bowe3qrj3mhyowfa1n7" + "x5xB7XEOqO6sfWxLdDjLVo4sn88="; public static final String[] TEST_22_DATA = new String[] { Intermediate_Certificate_IC_01_01_crt, Intermediate_CRL_IC_01_01_crl, End_Certificate_IC_01_01_crt }; /* * test23 * */ public static final String Intermediate_Certificate_IC_02_01_crt = "MIICkjCCAfugAwIBAgIBLTANBgkqhkiG9w0BAQUFADBeMQswCQYDVQQGEwJVUzEYMBYGA1" + "UEChMPVS5TLiBHb3Zlcm5tZW50MQwwCgYDVQQLEwNEb0QxEDAOBgNVBAsTB1Rlc3Rpbmcx" + "FTATBgNVBAMTDFRydXN0IEFuY2hvcjAeFw05ODAxMDExMjAxMDBaFw00ODAxMDExMjAxMD" + "BaMF4xCzAJBgNVBAYTAlVTMRgwFgYDVQQKEw9VLlMuIEdvdmVybm1lbnQxDDAKBgNVBAsT" + "A0RvZDEQMA4GA1UECxMHVGVzdGluZzEVMBMGA1UEAxMMQ0ExLUlDLjAyLjAxMIGfMA0GCS" + "qGSIb3DQEBAQUAA4GNADCBiQKBgQDemJgZnOzXOwNGqRA3Xq9aMrAWQU4oFuhSELsEYfLZ" + "GO3ntBjJLqCn+rs3FjR9N94cu63TduOAgqlXqrNbvyO1+SF9m35JXreqn/OS6KrK6c8W2I" + "pDAWJcr89nGyyCXMoJeaOOtj8m2NjZblmCZvtAl5UMOew73GE7Z5fE+jtA2wIDAQABo2Aw" + "XjAMBgNVHRMBAf8EAjAAMA4GA1UdDwEB/wQEAwIBBjAWBgNVHSAEDzANMAsGCWCGSAFlAw" + "EwATARBgNVHQ4ECgQIhT9GjaaHj68wEwYDVR0jBAwwCoAIq5rr+cLnVI8wDQYJKoZIhvcN" + "AQEFBQADgYEAWhKJUujLapxpz/DoD/w48HMzkL6UQCxQPOAjwwHicX8wFcKmcrWLVBdVC3" + "0+ywrzMraWhaq+QCOqsgtxCwTZrfUxbCNqhKS0lZijCMgNN4Jht+PAZ22tzEsw7nCwiMM2" + "n1jeKF/3btoDEUvZn9SuzhkIyxy7Q8l2tbNOsANqpxE="; public static final String Intermediate_CRL_IC_02_01_crl = "MIIBSzCBtQIBATANBgkqhkiG9w0BAQUFADBeMQswCQYDVQQGEwJVUzEYMBYGA1UEChMPVS" + "5TLiBHb3Zlcm5tZW50MQwwCgYDVQQLEwNEb2QxEDAOBgNVBAsTB1Rlc3RpbmcxFTATBgNV" + "BAMTDENBMS1JQy4wMi4wMRcNOTkwMTAxMTIwMTAwWhcNNDgwMTAxMTIwMTAwWqAjMCEwCg" + "YDVR0UBAMCAQEwEwYDVR0jBAwwCoAIhT9GjaaHj68wDQYJKoZIhvcNAQEFBQADgYEAJsjf" + "oS3F1KMpcVBOC1Z6P5N20TYLCCHG6KETlBA3Rjf8ehNxJKJW0lGd7qHpVHp4BGvkSfaOAa" + "OrC0G59wjDEY+Ci4QS46OYzBcHXMFX5HF2xMq+y5SfQnyV6MQUVVkxJRjgsTLrYwP2JaYm" + "BK/zExhqQgPfgcR+56swBPXqogo="; public static final String End_Certificate_IC_02_01_crt = "MIIChjCCAe+gAwIBAgIBLjANBgkqhkiG9w0BAQUFADBeMQswCQYDVQQGEwJVUzEYMBYGA1" + "UEChMPVS5TLiBHb3Zlcm5tZW50MQwwCgYDVQQLEwNEb2QxEDAOBgNVBAsTB1Rlc3Rpbmcx" + "FTATBgNVBAMTDENBMS1JQy4wMi4wMTAeFw05ODAxMDExMjAxMDBaFw00ODAxMDExMjAxMD" + "BaMGAxCzAJBgNVBAYTAlVTMRgwFgYDVQQKEw9VLlMuIEdvdmVybm1lbnQxDDAKBgNVBAsT" + "A0RvRDEQMA4GA1UECxMHVGVzdGluZzEXMBUGA1UEAxMOVXNlcjEtSUMuMDIuMDEwgZ8wDQ" + "YJKoZIhvcNAQEBBQADgY0AMIGJAoGBANbTVeAxOibAO3KGqxxY3VqKXDr9tKJN+igpKb4w" + "goR0ZnWGDusSVm4pvneZ9qfmi8A0sM0E91+B2hAwsU6Y9RoA7nPsTkFYi5F+hHGIF46Op6" + "8blGrZraGf9bsWXCZFoLoxcgltwjGPQqyZ5mnnm8cxUbtaWmgo28MK1yBH/sS5AgMBAAGj" + "UjBQMA4GA1UdDwEB/wQEAwIF4DAWBgNVHSAEDzANMAsGCWCGSAFlAwEwATARBgNVHQ4ECg" + "QI3gkBNo/SISMwEwYDVR0jBAwwCoAIhT9GjaaHj68wDQYJKoZIhvcNAQEFBQADgYEAQGl1" + "7uT2xxYDks6HolrQIpesIoPqEiZ8TkizEBuLG3sUKsC7klHwy2iyVvA6nRUDwf/XzDLpGW" + "/Gn0KTW6ZYIX6snOC1+7HX5OJglQx8tDpDvcAgyocK8PvCrHfu9o33J49aSeLAVpoCHwne" + "tTtJxVfTMmjYWKeDbHHHi8a2YTI="; public static final String[] TEST_23_DATA = new String[] { Intermediate_Certificate_IC_02_01_crt, Intermediate_CRL_IC_02_01_crl, End_Certificate_IC_02_01_crt }; /* * test24 * */ public static final String Intermediate_Certificate_IC_02_02_crt = "MIIClTCCAf6gAwIBAgIBLzANBgkqhkiG9w0BAQUFADBeMQswCQYDVQQGEwJVUzEYMBYGA1" + "UEChMPVS5TLiBHb3Zlcm5tZW50MQwwCgYDVQQLEwNEb0QxEDAOBgNVBAsTB1Rlc3Rpbmcx" + "FTATBgNVBAMTDFRydXN0IEFuY2hvcjAeFw05ODAxMDExMjAxMDBaFw00ODAxMDExMjAxMD" + "BaMF4xCzAJBgNVBAYTAlVTMRgwFgYDVQQKEw9VLlMuIEdvdmVybm1lbnQxDDAKBgNVBAsT" + "A0RvZDEQMA4GA1UECxMHVGVzdGluZzEVMBMGA1UEAxMMQ0ExLUlDLjAyLjAyMIGfMA0GCS" + "qGSIb3DQEBAQUAA4GNADCBiQKBgQDoeA32BPwgq8pLJoR/tbOSjHtAz6fmzvzJrhJMvl64" + "ccVuIzGxzOneYsO/ZYWy3ZGtlCoMZJRnS83tw0ikU9vQUwBw7DEcfRlLKYkY68rp25N1V5" + "JEjnlHw+RvubdGkonWzUNJFbY1GA24J3no2GZHiLPgWmGb1jsA8Ag32MUrCQIDAQABo2Mw" + "YTAPBgNVHRMBAf8EBTADAQH/MA4GA1UdDwEB/wQEAwIBBjAWBgNVHSAEDzANMAsGCWCGSA" + "FlAwEwATARBgNVHQ4ECgQIKx4Ybzu2PaYwEwYDVR0jBAwwCoAIq5rr+cLnVI8wDQYJKoZI" + "hvcNAQEFBQADgYEAotGeNFzmktvcxpCRcpuARHkv1lW+LegvbDBnSPvGnr1+Cn9rZcuLup" + "u8ex6VJ7KWtgWBtzdOelerO6ytfWQ67uNpTOuc0SDdk/f3tCagdx44LBVQywuq/Kj57ZuN" + "jpe4J8UPZSBFFK+P3gTX3S/lIKsDi6xjRnqFLSQYGX2XiIE="; public static final String Intermediate_CRL_IC_02_02_crl = "MIIBSzCBtQIBATANBgkqhkiG9w0BAQUFADBeMQswCQYDVQQGEwJVUzEYMBYGA1UEChMPVS" + "5TLiBHb3Zlcm5tZW50MQwwCgYDVQQLEwNEb2QxEDAOBgNVBAsTB1Rlc3RpbmcxFTATBgNV" + "BAMTDENBMS1JQy4wMi4wMhcNOTkwMTAxMTIwMTAwWhcNNDgwMTAxMTIwMTAwWqAjMCEwCg" + "YDVR0UBAMCAQEwEwYDVR0jBAwwCoAIKx4Ybzu2PaYwDQYJKoZIhvcNAQEFBQADgYEAOfuX" + "wRv4skbPZAbOH/LVXdc/cA7vCSTAnWecN3ZKm/eCsxbyRxqn7fcDyHmqg5H3Ac5UOlMHR4" + "FMe0Dp+Yu4Xg8xg3zRvE/3M/5jyRILGGi7olh4ikkOMD+UlreysvYvUX2MVP1iM9qAkXh8" + "E8n/LZIlABN2GGkFEMRMJA6KTXg="; public static final String End_Certificate_IC_02_02_crt = "MIIChjCCAe+gAwIBAgIBMDANBgkqhkiG9w0BAQUFADBeMQswCQYDVQQGEwJVUzEYMBYGA1" + "UEChMPVS5TLiBHb3Zlcm5tZW50MQwwCgYDVQQLEwNEb2QxEDAOBgNVBAsTB1Rlc3Rpbmcx" + "FTATBgNVBAMTDENBMS1JQy4wMi4wMjAeFw05ODAxMDExMjAxMDBaFw00ODAxMDExMjAxMD" + "BaMGAxCzAJBgNVBAYTAlVTMRgwFgYDVQQKEw9VLlMuIEdvdmVybm1lbnQxDDAKBgNVBAsT" + "A0RvRDEQMA4GA1UECxMHVGVzdGluZzEXMBUGA1UEAxMOVXNlcjEtSUMuMDIuMDIwgZ8wDQ" + "YJKoZIhvcNAQEBBQADgY0AMIGJAoGBAKogqWGx9EpJ/0G7ORopyIQ4IZXYKKTE48WqOJbu" + "nLD3txGjMUb5Xefl/QyTfd6J758ddGzPiKs1zWO6riffJLIBoOFDmt8tchPBJuIM3gKgXe" + "VcZMyF5mebm5/GZekMOjbs8P/zbLdrlu1D9CZWZMXONYitdluSg2moMGbewS2NAgMBAAGj" + "UjBQMA4GA1UdDwEB/wQEAwIF4DAWBgNVHSAEDzANMAsGCWCGSAFlAwEwATARBgNVHQ4ECg" + "QIP8N7OmNGshEwEwYDVR0jBAwwCoAIKx4Ybzu2PaYwDQYJKoZIhvcNAQEFBQADgYEAwkpF" + "j6Kv+OcKrUtOgnH9QddB0Ej0oU6B5/5Hhhf3liAPKtllDHnhUj6nqfh4APNq/iqYFOkKMR" + "RUZoaj6kakJNSOlgvRIiQfuFIgv3CqLZnhr85YFRnKgoluZE1pq3TvunoiKyJbCjbmyCos" + "Rd32gVcJq024xvY2eVBTl6tfn5A="; public static final String[] TEST_24_DATA = new String[] { Intermediate_Certificate_IC_02_02_crt, Intermediate_CRL_IC_02_02_crl, End_Certificate_IC_02_02_crt }; /* * test25 * */ public static final String Intermediate_Certificate_IC_02_03_crt = "MIICjzCCAfigAwIBAgIBMTANBgkqhkiG9w0BAQUFADBeMQswCQYDVQQGEwJVUzEYMBYGA1" + "UEChMPVS5TLiBHb3Zlcm5tZW50MQwwCgYDVQQLEwNEb0QxEDAOBgNVBAsTB1Rlc3Rpbmcx" + "FTATBgNVBAMTDFRydXN0IEFuY2hvcjAeFw05ODAxMDExMjAxMDBaFw00ODAxMDExMjAxMD" + "BaMF4xCzAJBgNVBAYTAlVTMRgwFgYDVQQKEw9VLlMuIEdvdmVybm1lbnQxDDAKBgNVBAsT" + "A0RvZDEQMA4GA1UECxMHVGVzdGluZzEVMBMGA1UEAxMMQ0ExLUlDLjAyLjAzMIGfMA0GCS" + "qGSIb3DQEBAQUAA4GNADCBiQKBgQC7LFt+yGItQFqSEPi03ICIr5ydWnFPQHZdEMNu2tRU" + "3XiOpfam1wl0xgAPGBkQK768OfidpP/i1hgYOU/isOB5dyALscvIQ9XJG1OWQXBBLgKuCb" + "MS5fuDhBNa4KiFuGMbJ3/UjluRsD9qaXwGUavc436JwbRHvW8FomaBYYY1hQIDAQABo10w" + "WzAJBgNVHRMEAjAAMA4GA1UdDwEB/wQEAwIBBjAWBgNVHSAEDzANMAsGCWCGSAFlAwEwAT" + "ARBgNVHQ4ECgQIPsBg9tMABhAwEwYDVR0jBAwwCoAIq5rr+cLnVI8wDQYJKoZIhvcNAQEF" + "BQADgYEANZcayTTX+FGhtRUJ+XuYA7jR14CJL6qTHPvdSMgHNw9mGXI/7sO5I4v1vayOCI" + "YQ9luBvrTYlMPmuej8+bhM8YTYpiiOjVFANwvSKArI9U2CAGBcoBMXydykkm8qYw4gtYQT" + "neiOz7VqI9plLWA111IRMgayD3CAt4Ntpzd1VSE="; public static final String Intermediate_CRL_IC_02_03_crl = "MIIBSzCBtQIBATANBgkqhkiG9w0BAQUFADBeMQswCQYDVQQGEwJVUzEYMBYGA1UEChMPVS" + "5TLiBHb3Zlcm5tZW50MQwwCgYDVQQLEwNEb2QxEDAOBgNVBAsTB1Rlc3RpbmcxFTATBgNV" + "BAMTDENBMS1JQy4wMi4wMxcNOTkwMTAxMTIwMTAwWhcNNDgwMTAxMTIwMTAwWqAjMCEwCg" + "YDVR0UBAMCAQEwEwYDVR0jBAwwCoAIPsBg9tMABhAwDQYJKoZIhvcNAQEFBQADgYEAVeQi" + "tT1FRUaJlhfpkfjZr6VHmvGnqYapdo4DRT/pm8tsp1LbZZXpYW638ztwgZNgeBRPFlcb+x" + "8naQjEkoaYzLbCYfdY+PPVDv7ym15PE48Kve8ImvANY0YnTGS8pcKdK1dpNKBnYYMOG9JN" + "+H5K/4cSm/WMCKIuKdsiAWFYauE="; public static final String End_Certificate_IC_02_03_crt = "MIIChjCCAe+gAwIBAgIBMjANBgkqhkiG9w0BAQUFADBeMQswCQYDVQQGEwJVUzEYMBYGA1" + "UEChMPVS5TLiBHb3Zlcm5tZW50MQwwCgYDVQQLEwNEb2QxEDAOBgNVBAsTB1Rlc3Rpbmcx" + "FTATBgNVBAMTDENBMS1JQy4wMi4wMzAeFw05ODAxMDExMjAxMDBaFw00ODAxMDExMjAxMD" + "BaMGAxCzAJBgNVBAYTAlVTMRgwFgYDVQQKEw9VLlMuIEdvdmVybm1lbnQxDDAKBgNVBAsT" + "A0RvRDEQMA4GA1UECxMHVGVzdGluZzEXMBUGA1UEAxMOVXNlcjEtSUMuMDIuMDMwgZ8wDQ" + "YJKoZIhvcNAQEBBQADgY0AMIGJAoGBALGbo9yEujZ9RFU+Vmxb5+Rx1VdIG/3E/5hXV/xI" + "OFu4mEfYh2tBhP2qIMH2KbrR1tiW5t4DvTCBM3NKKqp75wpiuu7E3q6imt1pLbGW13NVL+" + "81gYWXnCnzHpxYjMTIqqCkPIAeOG+SBJ1MgERbL+NBl+AK3WG4TeQ8vw7r2CGrAgMBAAGj" + "UjBQMA4GA1UdDwEB/wQEAwIF4DAWBgNVHSAEDzANMAsGCWCGSAFlAwEwATARBgNVHQ4ECg" + "QIS/HbII+ki/kwEwYDVR0jBAwwCoAIPsBg9tMABhAwDQYJKoZIhvcNAQEFBQADgYEAWHy4" + "sHrTkqY1XjDBY5XpNEyhP6htcnjYD9bos4wjxPlJUyxdIWACWrLDE+R5iRCOYsh/nDAJEt" + "CUcVASukvP6VLJaFjyxUOaCp6JCVV+txk7Fh0S/Ur3Zyysfp5LllP1plOA3N/k1Hliljp0" + "+bnSiDhA1+3hJh0gDMjWUdRq9yM="; public static final String[] TEST_25_DATA = new String[] { Intermediate_Certificate_IC_02_03_crt, Intermediate_CRL_IC_02_03_crl, End_Certificate_IC_02_03_crt }; /* * test26 * */ public static final String Intermediate_Certificate_IC_02_04_crt = "MIICkjCCAfugAwIBAgIBMzANBgkqhkiG9w0BAQUFADBeMQswCQYDVQQGEwJVUzEYMBYGA1" + "UEChMPVS5TLiBHb3Zlcm5tZW50MQwwCgYDVQQLEwNEb0QxEDAOBgNVBAsTB1Rlc3Rpbmcx" + "FTATBgNVBAMTDFRydXN0IEFuY2hvcjAeFw05ODAxMDExMjAxMDBaFw00ODAxMDExMjAxMD" + "BaMF4xCzAJBgNVBAYTAlVTMRgwFgYDVQQKEw9VLlMuIEdvdmVybm1lbnQxDDAKBgNVBAsT" + "A0RvZDEQMA4GA1UECxMHVGVzdGluZzEVMBMGA1UEAxMMQ0ExLUlDLjAyLjA0MIGfMA0GCS" + "qGSIb3DQEBAQUAA4GNADCBiQKBgQDf5u5ouGQlQmdNfc4ell3RXKWmtq+ar9VKMme3kp8D" + "cbDbUaVwlvhWTkOKxb9I208wfGG2nQiArezIwutlASf7sWo16EPapmGdCF+rp1dpjAPBUu" + "fruEyCZ8nu2ITD52wuPY9OAcKHQE2/bBpCJWkw97fYX6Q9PPW5uobWoUJtOwIDAQABo2Aw" + "XjAMBgNVHRMEBTADAQH/MA4GA1UdDwEB/wQEAwIBBjAWBgNVHSAEDzANMAsGCWCGSAFlAw" + "EwATARBgNVHQ4ECgQIjDm8K5YcGakwEwYDVR0jBAwwCoAIq5rr+cLnVI8wDQYJKoZIhvcN" + "AQEFBQADgYEAEQIJeZj/HE3HvjjJV7PdU+2Ze8OeCYeeWDocxrA647xpeOksVXBXKmq2OV" + "NqoFk7YNtlSUqiS2TlqjGqLtKYetk7a17qS/8EIQct+H5KWdvkLkYMkfIAAMJvJZHPGxEv" + "j+oVPAi9FITRbFdN8Jvdo9MAuU2q8d2x8MF236RmEds="; public static final String Intermediate_CRL_IC_02_04_crl = "MIIBSzCBtQIBATANBgkqhkiG9w0BAQUFADBeMQswCQYDVQQGEwJVUzEYMBYGA1UEChMPVS" + "5TLiBHb3Zlcm5tZW50MQwwCgYDVQQLEwNEb2QxEDAOBgNVBAsTB1Rlc3RpbmcxFTATBgNV" + "BAMTDENBMS1JQy4wMi4wNBcNOTkwMTAxMTIwMTAwWhcNNDgwMTAxMTIwMTAwWqAjMCEwCg" + "YDVR0UBAMCAQEwEwYDVR0jBAwwCoAIjDm8K5YcGakwDQYJKoZIhvcNAQEFBQADgYEAV5bX" + "7WsT8sWeA0iQ7V/+ZQESDzvyHA7Ziju0iRsvTL7qOVF/Nl5v+zND+ZNPhdJDKEM/Q0lEaA" + "ybe0E73NMmM1qRX1daAwE++jHukF9TMeNl750HJaS667H6jcjeRrHUJDD0+AgqrZY52dL6" + "CPM3V4QSvdfc1/xtKmNIZWSSoqY="; public static final String End_Certificate_IC_02_04_crt = "MIIChjCCAe+gAwIBAgIBNDANBgkqhkiG9w0BAQUFADBeMQswCQYDVQQGEwJVUzEYMBYGA1" + "UEChMPVS5TLiBHb3Zlcm5tZW50MQwwCgYDVQQLEwNEb2QxEDAOBgNVBAsTB1Rlc3Rpbmcx" + "FTATBgNVBAMTDENBMS1JQy4wMi4wNDAeFw05ODAxMDExMjAxMDBaFw00ODAxMDExMjAxMD" + "BaMGAxCzAJBgNVBAYTAlVTMRgwFgYDVQQKEw9VLlMuIEdvdmVybm1lbnQxDDAKBgNVBAsT" + "A0RvRDEQMA4GA1UECxMHVGVzdGluZzEXMBUGA1UEAxMOVXNlcjEtSUMuMDIuMDQwgZ8wDQ" + "YJKoZIhvcNAQEBBQADgY0AMIGJAoGBAMW45d5dPrzUJbuRIDeQ5gIJRYxi80PxPvxSmJe8" + "ScG1A+l75SAtgLGWAxBqxPSzL+teBBUsnmf2Xsc8/qQHHev74uat0lxq9YrZ3npLW2YNo2" + "CfxLK0M7F1/bhkHK2f9ttIvOrrKI67BeEjfACULdJEhl431uWINWV0pY+fHq+pAgMBAAGj" + "UjBQMA4GA1UdDwEB/wQEAwIF4DAWBgNVHSAEDzANMAsGCWCGSAFlAwEwATARBgNVHQ4ECg" + "QII61NnUvgvjYwEwYDVR0jBAwwCoAIjDm8K5YcGakwDQYJKoZIhvcNAQEFBQADgYEAjwgL" + "6qMnnqUvNspsDaYpPQzTCqXkqshZhsy5G/nLk621H/YbNGlnZ6asHGljYVYMzjmcny16y6" + "ntiv9QPB7YorAx27WT7pQPFla96s+nM/rfwWHPWI6QGDsquPriwJm/MwQC+1oDXEFKvdIL" + "0urejfd5hgiXYbRRwMI7km97iHg="; public static final String[] TEST_26_DATA = new String[] { Intermediate_Certificate_IC_02_04_crt, Intermediate_CRL_IC_02_04_crl, End_Certificate_IC_02_04_crt }; /* * test27 * */ public static final String Intermediate_Certificate_IC_04_01_crt = "MIICjzCCAfigAwIBAgIBNTANBgkqhkiG9w0BAQUFADBeMQswCQYDVQQGEwJVUzEYMBYGA1" + "UEChMPVS5TLiBHb3Zlcm5tZW50MQwwCgYDVQQLEwNEb0QxEDAOBgNVBAsTB1Rlc3Rpbmcx" + "FTATBgNVBAMTDFRydXN0IEFuY2hvcjAeFw05ODAxMDExMjAxMDBaFw00ODAxMDExMjAxMD" + "BaMF4xCzAJBgNVBAYTAlVTMRgwFgYDVQQKEw9VLlMuIEdvdmVybm1lbnQxDDAKBgNVBAsT" + "A0RvZDEQMA4GA1UECxMHVGVzdGluZzEVMBMGA1UEAxMMQ0ExLUlDLjA0LjAxMIGfMA0GCS" + "qGSIb3DQEBAQUAA4GNADCBiQKBgQDBtNwpr9LZBF2LRtAp9Tb1FZnfM3b/Jv2sdO5zc/Bk" + "sO4ByUgY+Mux9dEvFrkVWBK110TvXn+dj+85TuboILv4MDKlu+tI/rtuadXGwwDIg8TQnz" + "uyC7LWhxM5JZs1/Is+sPKUY4PTCHs3+EHPBWf2tFiP3l6ZftkySEiL6+2LSQIDAQABo10w" + "WzAMBgNVHRMEBTADAQH/MAsGA1UdDwQEAwIBBjAWBgNVHSAEDzANMAsGCWCGSAFlAwEwAT" + "ARBgNVHQ4ECgQIbMuZ73onuZswEwYDVR0jBAwwCoAIq5rr+cLnVI8wDQYJKoZIhvcNAQEF" + "BQADgYEAhaTSc2xafdP/QceMm9YJ/rZJ5gTgBR/SlmKQwd2BclHabG+Fozdg4delDjtRXS" + "FKY3sFWBFZHVeprh4T93Oj6IVA5X4DIuUeBpprtS+psCnWZxdtcUWmbyYQwZNCifG5C5D0" + "lRwxlMlv40xT2oCM1zPZpfmqemBDUPJ2OhkCjvo="; public static final String Intermediate_CRL_IC_04_01_crl = "MIIBSzCBtQIBATANBgkqhkiG9w0BAQUFADBeMQswCQYDVQQGEwJVUzEYMBYGA1UEChMPVS" + "5TLiBHb3Zlcm5tZW50MQwwCgYDVQQLEwNEb2QxEDAOBgNVBAsTB1Rlc3RpbmcxFTATBgNV" + "BAMTDENBMS1JQy4wNC4wMRcNOTkwMTAxMTIwMTAwWhcNNDgwMTAxMTIwMTAwWqAjMCEwCg" + "YDVR0UBAMCAQEwEwYDVR0jBAwwCoAIbMuZ73onuZswDQYJKoZIhvcNAQEFBQADgYEAMk6D" + "Rztz1AyFnFr1KAlbjLLwxtQplf2eIc//zUkDFVUHtX5TrEC/ijUaItjdkOoPGQfpnL0w8x" + "wyqWndMh593QPCqIJTtv/iACoiJNZ90ZJS0adcdZ+AEmQpa0Zv0e1JOqRrPoAfTq4HrOfR" + "vhBwhvKQNtTExupW/EBudznKC6Q="; public static final String End_Certificate_IC_04_01_crt = "MIIChjCCAe+gAwIBAgIBNjANBgkqhkiG9w0BAQUFADBeMQswCQYDVQQGEwJVUzEYMBYGA1" + "UEChMPVS5TLiBHb3Zlcm5tZW50MQwwCgYDVQQLEwNEb2QxEDAOBgNVBAsTB1Rlc3Rpbmcx" + "FTATBgNVBAMTDENBMS1JQy4wNC4wMTAeFw05ODAxMDExMjAxMDBaFw00ODAxMDExMjAxMD" + "BaMGAxCzAJBgNVBAYTAlVTMRgwFgYDVQQKEw9VLlMuIEdvdmVybm1lbnQxDDAKBgNVBAsT" + "A0RvRDEQMA4GA1UECxMHVGVzdGluZzEXMBUGA1UEAxMOVXNlcjEtSUMuMDQuMDEwgZ8wDQ" + "YJKoZIhvcNAQEBBQADgY0AMIGJAoGBAM2dGkraKGdIi6EXxAu6/ekMqDloX5YSVBGh4Hp2" + "faujr1u4j8Lp8afqjngRxFUpTqGbqH0ETgm4cVPXmc9rUvUzYTMdxTUmIZ+iW+ULZEvzNB" + "712kxRPCD2kDFN2fH2ai8miXr434w+weLm8VQN4jJGo4nswhSs2w1gsUmWyn/ZAgMBAAGj" + "UjBQMA4GA1UdDwEB/wQEAwIF4DAWBgNVHSAEDzANMAsGCWCGSAFlAwEwATARBgNVHQ4ECg" + "QITsLx/sO1edwwEwYDVR0jBAwwCoAIbMuZ73onuZswDQYJKoZIhvcNAQEFBQADgYEAeKft" + "0RM8/b3zQodaKrTdWiFyLg5fzoOsTecSfdFPXoqz9J5ejLVkvJevSmfXJrIUhKXySzsQi+" + "GazuTh/hvWjwUTIvmupi+EiFudnMpXCro8bgi48+NkepNjXvjsSmOfzlrK3SxtpH5dqonL" + "6LHjGyg+Xp0Nor1m5g1rLHyrcEk="; public static final String[] TEST_27_DATA = new String[] { Intermediate_Certificate_IC_04_01_crt, Intermediate_CRL_IC_04_01_crl, End_Certificate_IC_04_01_crt }; /* * test28 * */ public static final String Intermediate_Certificate_IC_05_01_crt = "MIIClTCCAf6gAwIBAgIBNzANBgkqhkiG9w0BAQUFADBeMQswCQYDVQQGEwJVUzEYMBYGA1" + "UEChMPVS5TLiBHb3Zlcm5tZW50MQwwCgYDVQQLEwNEb0QxEDAOBgNVBAsTB1Rlc3Rpbmcx" + "FTATBgNVBAMTDFRydXN0IEFuY2hvcjAeFw05ODAxMDExMjAxMDBaFw00ODAxMDExMjAxMD" + "BaMF4xCzAJBgNVBAYTAlVTMRgwFgYDVQQKEw9VLlMuIEdvdmVybm1lbnQxDDAKBgNVBAsT" + "A0RvZDEQMA4GA1UECxMHVGVzdGluZzEVMBMGA1UEAxMMQ0ExLUlDLjA1LjAxMIGfMA0GCS" + "qGSIb3DQEBAQUAA4GNADCBiQKBgQDM3aWmgX3OzAaBg6lnWjpFQ9ufeTOia3+lIUqn+Ypf" + "5OH/s9dLRqg1ZynV3YIUyzaJPP/YlUEmrhheJn3Bjw25bHeIKdge73pfEbuBAugbUMS75D" + "csBV7Ze9D+sVw8w/LtT3ZPcvM3Vju4d+c14Ip/8pC15jlgQPhwVQSf0x3V2QIDAQABo2Mw" + "YTAPBgNVHRMBAf8EBTADAQH/MA4GA1UdDwEB/wQEAwIBAjAWBgNVHSAEDzANMAsGCWCGSA" + "FlAwEwATARBgNVHQ4ECgQIJ2DFtxoQnXkwEwYDVR0jBAwwCoAIq5rr+cLnVI8wDQYJKoZI" + "hvcNAQEFBQADgYEASvdcfBOh2d1dC10pGLZLI3T+oSPCup/U9riynIR3RxZsIaS/+Q2s81" + "oeg++WQV6pyYvCLneZIp0efvqh5DThNV9lhBcJjlYwm/T8Hi2IaRGsSMwIvzrFN7zxA/zu" + "tW98wigAKM2myk/nlYxmholgbQkQ7ZxYM3lD1TDRl69N66Q="; public static final String Intermediate_CRL_IC_05_01_crl = "MIIBSzCBtQIBATANBgkqhkiG9w0BAQUFADBeMQswCQYDVQQGEwJVUzEYMBYGA1UEChMPVS" + "5TLiBHb3Zlcm5tZW50MQwwCgYDVQQLEwNEb2QxEDAOBgNVBAsTB1Rlc3RpbmcxFTATBgNV" + "BAMTDENBMS1JQy4wNS4wMRcNOTkwMTAxMTIwMTAwWhcNNDgwMTAxMTIwMTAwWqAjMCEwCg" + "YDVR0UBAMCAQEwEwYDVR0jBAwwCoAIJ2DFtxoQnXkwDQYJKoZIhvcNAQEFBQADgYEAK7Ym" + "Y9PjX5CpVewe2E9PNxj3dLYElghaQyapYoVtNq3jDqLMWspdmHdNdeaQoXsjlSJe0Zy8xH" + "ZvpimwifnFZ5hq4yByzHjzNMpcA2yFtg2MtPWGEia+BmaZYZi3X0lR+OShKpNLFc4CfVM/" + "aWG6W2BulHjIAThZhTg3uRekDzs="; public static final String End_Certificate_IC_05_01_crt = "MIIChjCCAe+gAwIBAgIBODANBgkqhkiG9w0BAQUFADBeMQswCQYDVQQGEwJVUzEYMBYGA1" + "UEChMPVS5TLiBHb3Zlcm5tZW50MQwwCgYDVQQLEwNEb2QxEDAOBgNVBAsTB1Rlc3Rpbmcx" + "FTATBgNVBAMTDENBMS1JQy4wNS4wMTAeFw05ODAxMDExMjAxMDBaFw00ODAxMDExMjAxMD" + "BaMGAxCzAJBgNVBAYTAlVTMRgwFgYDVQQKEw9VLlMuIEdvdmVybm1lbnQxDDAKBgNVBAsT" + "A0RvRDEQMA4GA1UECxMHVGVzdGluZzEXMBUGA1UEAxMOVXNlcjEtSUMuMDUuMDEwgZ8wDQ" + "YJKoZIhvcNAQEBBQADgY0AMIGJAoGBALlcUtceuxDznvI3pVM7YddPcBOrNvrOtpuLOa1L" + "Lj9LeNH6+8CzRZnMsUtt+bRGqCKMEJLUIIstWwGg4SskXWk2m+nDKm5Ai6Kyx4nldpgtgQ" + "xZSEwNcwRhpy7TtmLkxDVM9DoTbIbK0dZ7aWw4bXVHPK/lnOMtOaJbFDq0sLfxAgMBAAGj" + "UjBQMA4GA1UdDwEB/wQEAwIF4DAWBgNVHSAEDzANMAsGCWCGSAFlAwEwATARBgNVHQ4ECg" + "QIiXgrRBVcDf0wEwYDVR0jBAwwCoAIJ2DFtxoQnXkwDQYJKoZIhvcNAQEFBQADgYEAhyO6" + "SP6brWDDKZwdQGULno4Om5+DuilJKamyEcvSqE666z1KhvOCdLicqwVa6tQiAL6akrt5Kv" + "R+TT0xqHR4JGosGLGolvK4DLrMeD+PRK7m1a+nJl44luo5Mn48HrKI7jn7n8Lp9bNdCHvr" + "NHaQksCIR/Q8xoucPa+8sCTVSj4="; public static final String[] TEST_28_DATA = new String[] { Intermediate_Certificate_IC_05_01_crt, Intermediate_CRL_IC_05_01_crl, End_Certificate_IC_05_01_crt }; /* * test29 * */ public static final String Intermediate_Certificate_IC_05_02_crt = "MIICkjCCAfugAwIBAgIBOTANBgkqhkiG9w0BAQUFADBeMQswCQYDVQQGEwJVUzEYMBYGA1" + "UEChMPVS5TLiBHb3Zlcm5tZW50MQwwCgYDVQQLEwNEb0QxEDAOBgNVBAsTB1Rlc3Rpbmcx" + "FTATBgNVBAMTDFRydXN0IEFuY2hvcjAeFw05ODAxMDExMjAxMDBaFw00ODAxMDExMjAxMD" + "BaMF4xCzAJBgNVBAYTAlVTMRgwFgYDVQQKEw9VLlMuIEdvdmVybm1lbnQxDDAKBgNVBAsT" + "A0RvZDEQMA4GA1UECxMHVGVzdGluZzEVMBMGA1UEAxMMQ0ExLUlDLjA1LjAyMIGfMA0GCS" + "qGSIb3DQEBAQUAA4GNADCBiQKBgQCrtIYqo2Is8Cd6Ld+fyWC755oA6hQiiruooaR/6O4z" + "ikyhOUztnHkOGMF5H4CKWafwwVrfFtqe7iop3N6AToEIpNlJLVy3cj14A/IASVYSSNFeHd" + "O44Id1NWhPiKx3paPTWslMEdKQV9BlXb7gu8pQpvqTa/38hNQ9vdil/4QZbQIDAQABo2Aw" + "XjAPBgNVHRMBAf8EBTADAQH/MAsGA1UdDwQEAwIBAjAWBgNVHSAEDzANMAsGCWCGSAFlAw" + "EwATARBgNVHQ4ECgQI9P78RavuWW8wEwYDVR0jBAwwCoAIq5rr+cLnVI8wDQYJKoZIhvcN" + "AQEFBQADgYEA0sAEmWBYSazUav6RtuNFtZgNrlQ2i5i138VzRHoF/kq/CxeR/lINQqgJhC" + "ZlUnlslUuM86g8OQGlR8SS0Wsi0MdCQCtPCKA2hStlTx9MMux2IZAGoyHy6P95UE9qINHE" + "fYZUYjO9rh96fzNyJ5Oy2kJdJWdhFXtSh3BSOe0ZD+Y="; public static final String Intermediate_CRL_IC_05_02_crl = "MIIBSzCBtQIBATANBgkqhkiG9w0BAQUFADBeMQswCQYDVQQGEwJVUzEYMBYGA1UEChMPVS" + "5TLiBHb3Zlcm5tZW50MQwwCgYDVQQLEwNEb2QxEDAOBgNVBAsTB1Rlc3RpbmcxFTATBgNV" + "BAMTDENBMS1JQy4wNS4wMhcNOTkwMTAxMTIwMTAwWhcNNDgwMTAxMTIwMTAwWqAjMCEwCg" + "YDVR0UBAMCAQEwEwYDVR0jBAwwCoAI9P78RavuWW8wDQYJKoZIhvcNAQEFBQADgYEAlPLh" + "+CMqRcbLgUKEAL2UlSY5tjsF8At0hf000kec93TnBf7f1NKYVJ5eyeoh/WK4s+k4paAA5E" + "/P2C8JMlGXNTrqKZXMy2zIlufE1ymXAZCKLOLC5ezXRSpwIsBWxko2nfw8Bz/mZO/bCSCT" + "nDwkH8BJIbFV51vJFlyyOmZnCz4="; public static final String End_Certificate_IC_05_02_crt = "MIIChjCCAe+gAwIBAgIBOjANBgkqhkiG9w0BAQUFADBeMQswCQYDVQQGEwJVUzEYMBYGA1" + "UEChMPVS5TLiBHb3Zlcm5tZW50MQwwCgYDVQQLEwNEb2QxEDAOBgNVBAsTB1Rlc3Rpbmcx" + "FTATBgNVBAMTDENBMS1JQy4wNS4wMjAeFw05ODAxMDExMjAxMDBaFw00ODAxMDExMjAxMD" + "BaMGAxCzAJBgNVBAYTAlVTMRgwFgYDVQQKEw9VLlMuIEdvdmVybm1lbnQxDDAKBgNVBAsT" + "A0RvRDEQMA4GA1UECxMHVGVzdGluZzEXMBUGA1UEAxMOVXNlcjEtSUMuMDUuMDIwgZ8wDQ" + "YJKoZIhvcNAQEBBQADgY0AMIGJAoGBAMPsWBfT8HqaiLnoUCPAFniq502odL4uVqzOOxkx" + "evZtjh7NaFlRjuYjTofdkj/IAgg7lkkBEW3auK47Td3TvqnHO401PqvOFNTlbhr5wDLmXS" + "WWcR6XrvgYL3Z3wx15/z6eojcSgu07kdvKqzuLzcDs+noG8lbcruokX0A186pVAgMBAAGj" + "UjBQMA4GA1UdDwEB/wQEAwIF4DAWBgNVHSAEDzANMAsGCWCGSAFlAwEwATARBgNVHQ4ECg" + "QImgomUTkzwbEwEwYDVR0jBAwwCoAI9P78RavuWW8wDQYJKoZIhvcNAQEFBQADgYEATAEq" + "YVV0iYdYomPqxbTapSCJFAMQO/WZhN9brCXP88+jRfk6cAHzTodQOYTOAVe8YXa904505e" + "RA11NNTViP3s/AseGWuqbWjsom9mbR+tVkvufGqPQtm1JhfLgR/68e29AI7tj7zIJyFVYD" + "nLRXGwMGnosqSHDle+WYyfok6a8="; public static final String[] TEST_29_DATA = new String[] { Intermediate_Certificate_IC_05_02_crt, Intermediate_CRL_IC_05_02_crl, End_Certificate_IC_05_02_crt }; /* * test30 * */ public static final String Intermediate_Certificate_IC_05_03_crt = "MIICkjCCAfugAwIBAgIBOzANBgkqhkiG9w0BAQUFADBeMQswCQYDVQQGEwJVUzEYMBYGA1" + "UEChMPVS5TLiBHb3Zlcm5tZW50MQwwCgYDVQQLEwNEb0QxEDAOBgNVBAsTB1Rlc3Rpbmcx" + "FTATBgNVBAMTDFRydXN0IEFuY2hvcjAeFw05ODAxMDExMjAxMDBaFw00ODAxMDExMjAxMD" + "BaMF4xCzAJBgNVBAYTAlVTMRgwFgYDVQQKEw9VLlMuIEdvdmVybm1lbnQxDDAKBgNVBAsT" + "A0RvZDEQMA4GA1UECxMHVGVzdGluZzEVMBMGA1UEAxMMQ0ExLUlDLjA1LjAzMIGfMA0GCS" + "qGSIb3DQEBAQUAA4GNADCBiQKBgQCajRjoRNL9HFTytLLx7C8WYouW0uONGsrtGS5tKMiW" + "oLlQUkohqB2a2PhA1InNGQqnbDtNdqKbR1k6EzD6MyegvXK1sXs0ZE8gt0LZYio7Xp3k+Q" + "7i4Rk5iTruAUrV8bFMYmeIXHXL/9rl5LQV8YRp/Ut3Bg3VECzfhQG4EavMlwIDAQABo2Aw" + "XjAPBgNVHRMBAf8EBTADAQH/MAsGA1UdDwQEAwIBBjAWBgNVHSAEDzANMAsGCWCGSAFlAw" + "EwATARBgNVHQ4ECgQI9041oiwvHsgwEwYDVR0jBAwwCoAIq5rr+cLnVI8wDQYJKoZIhvcN" + "AQEFBQADgYEAYwGYwLsA/kxYZG/RM+kvoH+mUebrBVZRBxjovYsYzNznD26fssjBFfiTmg" + "zwZJfG7MZRsgDSRsS+bxuTlXMVeGRKH8fVj7PNq05sS18QZQOF0CCKzg9DLkCzkzkEWBxc" + "5ersciPrL90UarOIPIJWUxQ/5sdMS/wZtYTU34rNNWE="; public static final String Intermediate_CRL_IC_05_03_crl = "MIIBSzCBtQIBATANBgkqhkiG9w0BAQUFADBeMQswCQYDVQQGEwJVUzEYMBYGA1UEChMPVS" + "5TLiBHb3Zlcm5tZW50MQwwCgYDVQQLEwNEb2QxEDAOBgNVBAsTB1Rlc3RpbmcxFTATBgNV" + "BAMTDENBMS1JQy4wNS4wMxcNOTkwMTAxMTIwMTAwWhcNNDgwMTAxMTIwMTAwWqAjMCEwCg" + "YDVR0UBAMCAQEwEwYDVR0jBAwwCoAI9041oiwvHsgwDQYJKoZIhvcNAQEFBQADgYEAJHTp" + "k+RRsD0dUv59J1GQMWjQTjVz39Xaonx2sk38WHcrHBB78L0W6Skjvt082PwZg32sb7FQBt" + "boAQ3PIKpXMnFnkjnkyaFihrnMdfa0abCPtQhFl3yra+w+1a2RDjQBZOOdq3xlFcLi9unT" + "YYome7eS93wchIvNWFpgwF5A5XY="; public static final String End_Certificate_IC_05_03_crt = "MIIChjCCAe+gAwIBAgIBPDANBgkqhkiG9w0BAQUFADBeMQswCQYDVQQGEwJVUzEYMBYGA1" + "UEChMPVS5TLiBHb3Zlcm5tZW50MQwwCgYDVQQLEwNEb2QxEDAOBgNVBAsTB1Rlc3Rpbmcx" + "FTATBgNVBAMTDENBMS1JQy4wNS4wMzAeFw05ODAxMDExMjAxMDBaFw00ODAxMDExMjAxMD" + "BaMGAxCzAJBgNVBAYTAlVTMRgwFgYDVQQKEw9VLlMuIEdvdmVybm1lbnQxDDAKBgNVBAsT" + "A0RvRDEQMA4GA1UECxMHVGVzdGluZzEXMBUGA1UEAxMOVXNlcjEtSUMuMDUuMDMwgZ8wDQ" + "YJKoZIhvcNAQEBBQADgY0AMIGJAoGBAMYxdSZq7qRBdPOz6H+l0GGAtymAWTshfZZCubHK" + "lQjbVq98qudORfhCOZgOy83j/mo2KAecBhxaxB9YA5ggWNAgaKtFvknvjFemtBCZwt6cVK" + "8LCyUGKzStwAV1+HSDlHxdWo7pRwP0beXFvFECrX418osGt6E/v7Cz++ZtvaDhAgMBAAGj" + "UjBQMA4GA1UdDwEB/wQEAwIF4DAWBgNVHSAEDzANMAsGCWCGSAFlAwEwATARBgNVHQ4ECg" + "QIgTuCLfTVa+QwEwYDVR0jBAwwCoAI9041oiwvHsgwDQYJKoZIhvcNAQEFBQADgYEAQRuC" + "rAx9zzu9QwOq9weNit9PNgFHBpo3Gh9jPVYGJjOQxeSqqou503xi82H3W30FT/3ESCO7IF" + "hfpr/uQZVEmUQnvDsVwbKvED1QF9qkTp6ILk38ITJJgfb+sdSL3bsUeNqVXd0C9wzVoErc" + "OuoCulwkZzfoIOlO2YAjAnR1nUc="; public static final String[] TEST_30_DATA = new String[] { Intermediate_Certificate_IC_05_03_crt, Intermediate_CRL_IC_05_03_crl, End_Certificate_IC_05_03_crt }; /* * test31 * */ public static final String Intermediate_Certificate_IC_06_01_crt = "MIIClTCCAf6gAwIBAgIBPTANBgkqhkiG9w0BAQUFADBeMQswCQYDVQQGEwJVUzEYMBYGA1" + "UEChMPVS5TLiBHb3Zlcm5tZW50MQwwCgYDVQQLEwNEb0QxEDAOBgNVBAsTB1Rlc3Rpbmcx" + "FTATBgNVBAMTDFRydXN0IEFuY2hvcjAeFw05ODAxMDExMjAxMDBaFw00ODAxMDExMjAxMD" + "BaMF4xCzAJBgNVBAYTAlVTMRgwFgYDVQQKEw9VLlMuIEdvdmVybm1lbnQxDDAKBgNVBAsT" + "A0RvZDEQMA4GA1UECxMHVGVzdGluZzEVMBMGA1UEAxMMQ0ExLUlDLjA2LjAxMIGfMA0GCS" + "qGSIb3DQEBAQUAA4GNADCBiQKBgQDmutL9PY/BLXvXMEDQLQnWE7dCOsrLNvJiuSjDdznF" + "vBz6WS/RqUr9zsDFknpOWB3Epo2syV4ZFto+v4VWNo61uaClIEsw5x1y0saG19px34KVpQ" + "wkpvLeRZySdCydKdE1rptYR/JbHvPo5TU4mxOo6L7JeEwAvjSI4tK4rwJ4MwIDAQABo2Mw" + "YTAPBgNVHRMBAf8EBTADAQH/MA4GA1UdDwEB/wQEAwICBDAWBgNVHSAEDzANMAsGCWCGSA" + "FlAwEwATARBgNVHQ4ECgQI1BB9j6Jyny4wEwYDVR0jBAwwCoAIq5rr+cLnVI8wDQYJKoZI" + "hvcNAQEFBQADgYEAajWMbY8zL8jS2VUjCPBMuIjUvBfy55+92EXg5pZnyNNwN1diZfJFiB" + "rrPWEg3Fa4NMLgaDKWZsYkOcDDo8I+Qb9FsU9LphCzQ1ubIEuxu6KPX9X29BscFOxUnZCz" + "yuzVfadACxi5Y7Bz5pN5LfC/jEb2iXjkdN5Rm8AqT81syIo="; public static final String Intermediate_CRL_IC_06_01_crl = "MIIBSzCBtQIBATANBgkqhkiG9w0BAQUFADBeMQswCQYDVQQGEwJVUzEYMBYGA1UEChMPVS" + "5TLiBHb3Zlcm5tZW50MQwwCgYDVQQLEwNEb2QxEDAOBgNVBAsTB1Rlc3RpbmcxFTATBgNV" + "BAMTDENBMS1JQy4wNi4wMRcNOTkwMTAxMTIwMTAwWhcNNDgwMTAxMTIwMTAwWqAjMCEwCg" + "YDVR0UBAMCAQEwEwYDVR0jBAwwCoAI1BB9j6Jyny4wDQYJKoZIhvcNAQEFBQADgYEAxH4/" + "mgACT847PyufmF1nob9TSqBj+cM5ye2bgv83gTVd3B1Gopr75Tnu4iP10d0PpSXjySWCjB" + "0HPJ7BdxzkKxSrcM5vcb/jLdk9PqMUS30ohexsx1xK+E38pDJdLX4kbJ3E62AgyXm9WQlD" + "9xsDk7TMXwuxHT4fX070HL6lWGI="; public static final String End_Certificate_IC_06_01_crt = "MIIChjCCAe+gAwIBAgIBPjANBgkqhkiG9w0BAQUFADBeMQswCQYDVQQGEwJVUzEYMBYGA1" + "UEChMPVS5TLiBHb3Zlcm5tZW50MQwwCgYDVQQLEwNEb2QxEDAOBgNVBAsTB1Rlc3Rpbmcx" + "FTATBgNVBAMTDENBMS1JQy4wNi4wMTAeFw05ODAxMDExMjAxMDBaFw00ODAxMDExMjAxMD" + "BaMGAxCzAJBgNVBAYTAlVTMRgwFgYDVQQKEw9VLlMuIEdvdmVybm1lbnQxDDAKBgNVBAsT" + "A0RvRDEQMA4GA1UECxMHVGVzdGluZzEXMBUGA1UEAxMOVXNlcjEtSUMuMDYuMDEwgZ8wDQ" + "YJKoZIhvcNAQEBBQADgY0AMIGJAoGBAO1VOl25MTf068LOgzmQOmyh8MXunBrQ4t6UYuEj" + "H7v+owR9JTDXpfzLPcYfkR+BH2jjISSHIJsUDesKVhpmhABNXcOI5tiRNkeDlV2zKCBXKC" + "wFi5qkhrE8FUCP0hL8YzbybOrYZYSVEP8GgIgMSQcTvhN/Tor0o1jdJvRLmevXAgMBAAGj" + "UjBQMA4GA1UdDwEB/wQEAwIF4DAWBgNVHSAEDzANMAsGCWCGSAFlAwEwATARBgNVHQ4ECg" + "QIFJA9XGd9UZUwEwYDVR0jBAwwCoAI1BB9j6Jyny4wDQYJKoZIhvcNAQEFBQADgYEApRQC" + "OTU9cp16BHM2n0TdZThgj9kSAQ4wHk/dKNOjYNEWu6n/GQ0alxy1dyRzpsr058FOvft23Z" + "Kp0YhdKG/7F1hkcoNvC2yN+Re44n7S+F/jcEPTWnOX6h1Nkw8OS7Uz2fZ8t61iHjqjX4sv" + "M/cKP+AkC8g7p2tfdkP1fQ6ww5E="; public static final String[] TEST_31_DATA = new String[] { Intermediate_Certificate_IC_06_01_crt, Intermediate_CRL_IC_06_01_crl, End_Certificate_IC_06_01_crt }; /* * test32 * */ public static final String Intermediate_Certificate_IC_06_02_crt = "MIICkjCCAfugAwIBAgIBPzANBgkqhkiG9w0BAQUFADBeMQswCQYDVQQGEwJVUzEYMBYGA1" + "UEChMPVS5TLiBHb3Zlcm5tZW50MQwwCgYDVQQLEwNEb0QxEDAOBgNVBAsTB1Rlc3Rpbmcx" + "FTATBgNVBAMTDFRydXN0IEFuY2hvcjAeFw05ODAxMDExMjAxMDBaFw00ODAxMDExMjAxMD" + "BaMF4xCzAJBgNVBAYTAlVTMRgwFgYDVQQKEw9VLlMuIEdvdmVybm1lbnQxDDAKBgNVBAsT" + "A0RvZDEQMA4GA1UECxMHVGVzdGluZzEVMBMGA1UEAxMMQ0ExLUlDLjA2LjAyMIGfMA0GCS" + "qGSIb3DQEBAQUAA4GNADCBiQKBgQC0JoTnPaI/HT2eAqCW1204nRNjcA8EQSp87tvHLpWy" + "5aafmxeJxvk5V9Ba7Ye8eY8yX9losbNUpHJFNdE46fD5qp/oS7Cn3NXA0dwIDQEn1X9vaz" + "nqtZtMjt1S/yGv2xDOb2LKT9zRrqSvxGszCHFUBcJ4HDFJMAdhXPUZiLyXVQIDAQABo2Aw" + "XjAPBgNVHRMBAf8EBTADAQH/MAsGA1UdDwQEAwICBDAWBgNVHSAEDzANMAsGCWCGSAFlAw" + "EwATARBgNVHQ4ECgQI7j2LO1CcsE4wEwYDVR0jBAwwCoAIq5rr+cLnVI8wDQYJKoZIhvcN" + "AQEFBQADgYEAfXIh0oYlM2pagAWzTuYqTl0NavtfqibPgolvhgIG/XmmjswHOg/JVCLb7O" + "jIYtEG2MAD0xQXwu0mc9Deufed2embP/wc0qVG7rj7lxUq6p0aMQJNndBw4m9KlSnjdzyG" + "lwE9pNd2BgEeD516J2k7dspCZHDw3qLer4i2JYoCo2Y="; public static final String Intermediate_CRL_IC_06_02_crl = "MIIBSzCBtQIBATANBgkqhkiG9w0BAQUFADBeMQswCQYDVQQGEwJVUzEYMBYGA1UEChMPVS" + "5TLiBHb3Zlcm5tZW50MQwwCgYDVQQLEwNEb2QxEDAOBgNVBAsTB1Rlc3RpbmcxFTATBgNV" + "BAMTDENBMS1JQy4wNi4wMhcNOTkwMTAxMTIwMTAwWhcNNDgwMTAxMTIwMTAwWqAjMCEwCg" + "YDVR0UBAMCAQEwEwYDVR0jBAwwCoAI7j2LO1CcsE4wDQYJKoZIhvcNAQEFBQADgYEAJej7" + "23qVtwkcvCTPb6afTosYMnVppPXWbtvqn0N5mAFHQfE27x1YPOXOQHBrpQuTyiUdUmPXiH" + "xMKbuR5o2lfdQgew9hbYVk6GegSu+DBC1JKv2YSTgzgRAlJfyByDZ7mbJwZWHVHys08oGk" + "adG6zstavg5EkEeRuAp47T+7cZc="; public static final String End_Certificate_IC_06_02_crt = "MIIChjCCAe+gAwIBAgIBQDANBgkqhkiG9w0BAQUFADBeMQswCQYDVQQGEwJVUzEYMBYGA1" + "UEChMPVS5TLiBHb3Zlcm5tZW50MQwwCgYDVQQLEwNEb2QxEDAOBgNVBAsTB1Rlc3Rpbmcx" + "FTATBgNVBAMTDENBMS1JQy4wNi4wMjAeFw05ODAxMDExMjAxMDBaFw00ODAxMDExMjAxMD" + "BaMGAxCzAJBgNVBAYTAlVTMRgwFgYDVQQKEw9VLlMuIEdvdmVybm1lbnQxDDAKBgNVBAsT" + "A0RvRDEQMA4GA1UECxMHVGVzdGluZzEXMBUGA1UEAxMOVXNlcjEtSUMuMDYuMDIwgZ8wDQ" + "YJKoZIhvcNAQEBBQADgY0AMIGJAoGBAMkIzl9+NRTZf/xaA8noiHRt65Zo6Zp57YvCKUe+" + "YfoC8koMq12MBgrc0IyIfJoqEDEMfD1WbitZdGZMQZ7D9BP2Bk09NXLEAAuj+waFhYk0bW" + "vHBH90O7HpMGmxwHmzOjDV3JHYsU8hq77/5gRFDNRkSCJe2A1Maj8Gcqi6tYf5AgMBAAGj" + "UjBQMA4GA1UdDwEB/wQEAwIF4DAWBgNVHSAEDzANMAsGCWCGSAFlAwEwATARBgNVHQ4ECg" + "QIYDfThEjNL28wEwYDVR0jBAwwCoAI7j2LO1CcsE4wDQYJKoZIhvcNAQEFBQADgYEAJiHT" + "CjLGZK5Lyw+7ICDHs3eS1OGJH/wfsLcBP5sLER41qJfrXGTl2XdKvBMIpriUmJYzjkjof4" + "bvS/VPDNlhI9AJadicW8LM4L3qpy7/YV4Dd/C/BJphJ6cZcT+hjaRKeC7gQVjMeC/npu/p" + "jLgIgzf7HC4WYnaS3h9oYl0cMJk="; public static final String[] TEST_32_DATA = new String[] { Intermediate_Certificate_IC_06_02_crt, Intermediate_CRL_IC_06_02_crl, End_Certificate_IC_06_02_crt }; /* * test33 * */ public static final String Intermediate_Certificate_IC_06_03_crt = "MIICkjCCAfugAwIBAgIBQTANBgkqhkiG9w0BAQUFADBeMQswCQYDVQQGEwJVUzEYMBYGA1" + "UEChMPVS5TLiBHb3Zlcm5tZW50MQwwCgYDVQQLEwNEb0QxEDAOBgNVBAsTB1Rlc3Rpbmcx" + "FTATBgNVBAMTDFRydXN0IEFuY2hvcjAeFw05ODAxMDExMjAxMDBaFw00ODAxMDExMjAxMD" + "BaMF4xCzAJBgNVBAYTAlVTMRgwFgYDVQQKEw9VLlMuIEdvdmVybm1lbnQxDDAKBgNVBAsT" + "A0RvZDEQMA4GA1UECxMHVGVzdGluZzEVMBMGA1UEAxMMQ0ExLUlDLjA2LjAzMIGfMA0GCS" + "qGSIb3DQEBAQUAA4GNADCBiQKBgQCuUtIYFbVjg8VLLUqIEQ6r7hjTaqYVs8DJnJPHUWPA" + "JW9HEIV+d6hj/so76Bff4KJRX7MgoXbvq4ivmn8656N7YSGk9GPuJ25SXK7RJyoqzG/x2R" + "AVUCx/wG99VXVDZhd5ZAVBG2JCkHImsWAei6/Tz8UgXmmLBM8rZNJ/hNtTBwIDAQABo2Aw" + "XjAPBgNVHRMBAf8EBTADAQH/MAsGA1UdDwQEAwIBBjAWBgNVHSAEDzANMAsGCWCGSAFlAw" + "EwATARBgNVHQ4ECgQIpwUlwG1W+sMwEwYDVR0jBAwwCoAIq5rr+cLnVI8wDQYJKoZIhvcN" + "AQEFBQADgYEAqJhUfgar10fl5qG+oH34s/JS3ku0dRm4cTQvqUNOWA9ALnBhSkmOpoMMzH" + "sE9FXXcZ072a8/ecpviP04X5mt5QSLreh3hPVvgWv1LiZ9YkS4Z2kcr+3Gx7zj4gQgT5vG" + "QPpbIBAtBRH5xNHIYQsk6kOe2+t7b0Q82Wnj8UoznmQ="; public static final String Intermediate_CRL_IC_06_03_crl = "MIIBSzCBtQIBATANBgkqhkiG9w0BAQUFADBeMQswCQYDVQQGEwJVUzEYMBYGA1UEChMPVS" + "5TLiBHb3Zlcm5tZW50MQwwCgYDVQQLEwNEb2QxEDAOBgNVBAsTB1Rlc3RpbmcxFTATBgNV" + "BAMTDENBMS1JQy4wNi4wMxcNOTkwMTAxMTIwMTAwWhcNNDgwMTAxMTIwMTAwWqAjMCEwCg" + "YDVR0UBAMCAQEwEwYDVR0jBAwwCoAIpwUlwG1W+sMwDQYJKoZIhvcNAQEFBQADgYEAKCp7" + "ViY1cajXpbjCIqe8yo/98SQRIxoTNgp7EUaaV17FeHZ59nJhRtsF1XnLP4cK0lPBkKFhHK" + "2XyDEWx2hK3X7Z3lSAtn12WFJHOP5T5i0DmYfMJYAFbuPD0JQEWCM3aYsgbXKbbFH1BURh" + "L/uy3arVBP4FaJB8gH678K4J1p4="; public static final String End_Certificate_IC_06_03_crt = "MIIChjCCAe+gAwIBAgIBQjANBgkqhkiG9w0BAQUFADBeMQswCQYDVQQGEwJVUzEYMBYGA1" + "UEChMPVS5TLiBHb3Zlcm5tZW50MQwwCgYDVQQLEwNEb2QxEDAOBgNVBAsTB1Rlc3Rpbmcx" + "FTATBgNVBAMTDENBMS1JQy4wNi4wMzAeFw05ODAxMDExMjAxMDBaFw00ODAxMDExMjAxMD" + "BaMGAxCzAJBgNVBAYTAlVTMRgwFgYDVQQKEw9VLlMuIEdvdmVybm1lbnQxDDAKBgNVBAsT" + "A0RvRDEQMA4GA1UECxMHVGVzdGluZzEXMBUGA1UEAxMOVXNlcjEtSUMuMDYuMDMwgZ8wDQ" + "YJKoZIhvcNAQEBBQADgY0AMIGJAoGBALZw+GpvdleGlmdqZ/zEO2DUGhwgrsselBUNnEzR" + "bcuzr5O1WwiG6aLjrPxIXeL1wLS1/u9AD9p3CQU0XFhi+bEI9+LLnt2y3707O+AQxy1PnQ" + "6qmYE4jMwqDGHn8WVanN2joFT3isLH5wJD0Jh74eoG0tqCHUyOiXaZNo78qgB3AgMBAAGj" + "UjBQMA4GA1UdDwEB/wQEAwIF4DAWBgNVHSAEDzANMAsGCWCGSAFlAwEwATARBgNVHQ4ECg" + "QIJOeyCnvfJtAwEwYDVR0jBAwwCoAIpwUlwG1W+sMwDQYJKoZIhvcNAQEFBQADgYEAJbz1" + "RipbW6uu7B+f2Ol1iq4AVOUuET2S9vi9ojReyAIka3q1XUceZCm5Et0KqpOoOLiu8IRuNB" + "bvKwRcZ4hcVEXv5bRMqaPEK2B0VrRAV/Llj5A+RGn6yc1ZdkJeBRhoSsaHn5whfICaiJX6" + "j3lMpo/CiMRViL+gZLU3SdKqvdY="; public static final String[] TEST_33_DATA = new String[] { Intermediate_Certificate_IC_06_03_crt, Intermediate_CRL_IC_06_03_crl, End_Certificate_IC_06_03_crt }; /* * test34 * */ public static final String Intermediate_Certificate_PP_01_01_crt = "MIIClTCCAf6gAwIBAgIBQzANBgkqhkiG9w0BAQUFADBeMQswCQYDVQQGEwJVUzEYMBYGA1" + "UEChMPVS5TLiBHb3Zlcm5tZW50MQwwCgYDVQQLEwNEb0QxEDAOBgNVBAsTB1Rlc3Rpbmcx" + "FTATBgNVBAMTDFRydXN0IEFuY2hvcjAeFw05ODAxMDExMjAxMDBaFw00ODAxMDExMjAxMD" + "BaMF4xCzAJBgNVBAYTAlVTMRgwFgYDVQQKEw9VLlMuIEdvdmVybm1lbnQxDDAKBgNVBAsT" + "A0RvZDEQMA4GA1UECxMHVGVzdGluZzEVMBMGA1UEAxMMQ0ExLVBQLjAxLjAxMIGfMA0GCS" + "qGSIb3DQEBAQUAA4GNADCBiQKBgQDRkBhJJVgOXHjydAHAnokd/XfEiW+bnWd2ZPJrMBmP" + "7TlvVpxOGqLd6lGdbelbSyAzut1i8lyYn9NSDR0PcyehCSS+MsKS2uNKsTEuH3mlMK/7C5" + "B1qggKqE8f7opyl9+U+Qyi1WQj01gY6XYXaCxksCB0Oqx2737d7QWMvl15dQIDAQABo2Mw" + "YTAPBgNVHRMBAf8EBTADAQH/MA4GA1UdDwEB/wQEAwIBBjAWBgNVHSAEDzANMAsGCWCGSA" + "FlAwEwATARBgNVHQ4ECgQIO1U69B4DBHQwEwYDVR0jBAwwCoAIq5rr+cLnVI8wDQYJKoZI" + "hvcNAQEFBQADgYEAcHWV4Q4z7C+IC4bWgIf1+BzkszCN+LSb4JquR7GgICESbwF2JzR+xL" + "7yoKvB/NBcCqtMY4Hi1DHACbIGJwRe68vVHzz4CmYEK50UUCbAtiAiy9Od6wwrTyFyacBd" + "CBjiO6mkFEp6jOsoIgXRfxK4kDNcMkGUUwMbSR/wZKFuImc="; public static final String Intermediate_CRL_PP_01_01_crl = "MIIBSzCBtQIBATANBgkqhkiG9w0BAQUFADBeMQswCQYDVQQGEwJVUzEYMBYGA1UEChMPVS" + "5TLiBHb3Zlcm5tZW50MQwwCgYDVQQLEwNEb2QxEDAOBgNVBAsTB1Rlc3RpbmcxFTATBgNV" + "BAMTDENBMS1QUC4wMS4wMRcNOTkwMTAxMTIwMTAwWhcNNDgwMTAxMTIwMTAwWqAjMCEwCg" + "YDVR0UBAMCAQEwEwYDVR0jBAwwCoAIO1U69B4DBHQwDQYJKoZIhvcNAQEFBQADgYEAHtbX" + "MUofQlCnbJhgLQw96jsBRu0Kdx/Rk4LWxEbZQOWNaD7aukASjEv63d1qZIDgpefuUNTz5s" + "3eascdtI6iyWFtBO3r6tihtkkSbxocN2Rz7OlR4rW9VwuUirxP0145nMd5CEL03/CNABP5" + "zUo1bNgswHW3z/RaH6h0j0yTkbo="; public static final String End_Certificate_PP_01_01_crt = "MIIChjCCAe+gAwIBAgIBRDANBgkqhkiG9w0BAQUFADBeMQswCQYDVQQGEwJVUzEYMBYGA1" + "UEChMPVS5TLiBHb3Zlcm5tZW50MQwwCgYDVQQLEwNEb2QxEDAOBgNVBAsTB1Rlc3Rpbmcx" + "FTATBgNVBAMTDENBMS1QUC4wMS4wMTAeFw05ODAxMDExMjAxMDBaFw00ODAxMDExMjAxMD" + "BaMGAxCzAJBgNVBAYTAlVTMRgwFgYDVQQKEw9VLlMuIEdvdmVybm1lbnQxDDAKBgNVBAsT" + "A0RvRDEQMA4GA1UECxMHVGVzdGluZzEXMBUGA1UEAxMOVXNlcjEtUFAuMDEuMDEwgZ8wDQ" + "YJKoZIhvcNAQEBBQADgY0AMIGJAoGBALQaTS1wvv551g3BP9JYBMM+KXXLzxtOwPlO5NR4" + "LwuJJB2WuO4vmbn8AG35in/0JqwjZeroLQvbCPxZseXsyA0+7cMO0qcjRJ5l5WdFsahT6g" + "z1YW8pYYY5i2eDUkIRsM7roHMiNjt3zpkuUGX0xZQfAxhuWnRIvlGg5J4r7UOdAgMBAAGj" + "UjBQMA4GA1UdDwEB/wQEAwIF4DAWBgNVHSAEDzANMAsGCWCGSAFlAwEwATARBgNVHQ4ECg" + "QIeyLSANVaTpQwEwYDVR0jBAwwCoAIO1U69B4DBHQwDQYJKoZIhvcNAQEFBQADgYEAvZ4a" + "SQMNl+Q++D9yVaGr+37XJyxs4yow5e5YM9LXn1qBASQ+GNfqPWoe2cPCPYKj32yulxyFEu" + "RHrbhpEQe+nrKWJgO9W1bmfwgQDin29ne/JCQPlznhd3EPFvCkmPLnTyJmSLR6B2VxvndM" + "GO8JEbj3KCf51uf3VnC/Qj11mX8="; public static final String[] TEST_34_DATA = new String[] { Intermediate_Certificate_PP_01_01_crt, Intermediate_CRL_PP_01_01_crl, End_Certificate_PP_01_01_crt }; /* * test35 * */ public static final String Intermediate_Certificate_PP_01_02_crt = "MIICfTCCAeagAwIBAgIBRTANBgkqhkiG9w0BAQUFADBeMQswCQYDVQQGEwJVUzEYMBYGA1" + "UEChMPVS5TLiBHb3Zlcm5tZW50MQwwCgYDVQQLEwNEb0QxEDAOBgNVBAsTB1Rlc3Rpbmcx" + "FTATBgNVBAMTDFRydXN0IEFuY2hvcjAeFw05ODAxMDExMjAxMDBaFw00ODAxMDExMjAxMD" + "BaMF4xCzAJBgNVBAYTAlVTMRgwFgYDVQQKEw9VLlMuIEdvdmVybm1lbnQxDDAKBgNVBAsT" + "A0RvZDEQMA4GA1UECxMHVGVzdGluZzEVMBMGA1UEAxMMQ0ExLVBQLjAxLjAyMIGfMA0GCS" + "qGSIb3DQEBAQUAA4GNADCBiQKBgQCkQQXRO+dnU2v7EbaqQNmfPD8v0s5Wa50hl9M1Gfr5" + "5nuVUZs/RI//1VksTNrW10MVh11nsxpA/XRPntEIbHiH1OoECd4dnZBiA/2xEueM02fTjj" + "fb/t7g+pr9dSU/TzCVZDVWFBcPn4VNz7BBqIrTAOXaJkyBZ8hh7vyiE1Y2VQIDAQABo0sw" + "STAPBgNVHRMBAf8EBTADAQH/MA4GA1UdDwEB/wQEAwIBBjARBgNVHQ4ECgQIoTKVlZ8YCR" + "AwEwYDVR0jBAwwCoAIq5rr+cLnVI8wDQYJKoZIhvcNAQEFBQADgYEADhtnd6ifr6kyfC5D" + "UWuAXLtoccMj8Jaur/1YT1DgnH1XbBsEeZwm9Jkzr1a3cXPIHgaHYgXvBeGUtZ3XhbCSGp" + "8U6clJz3lm3qKPKkb5rdDrpdTaPnEJJjS3C4ZK1L7UZtQga2Enlelm5vIkhjsF3Sexe1kY" + "mzqiLZZ8yLxJ/Tg="; public static final String Intermediate_CRL_PP_01_02_crl = "MIIBSzCBtQIBATANBgkqhkiG9w0BAQUFADBeMQswCQYDVQQGEwJVUzEYMBYGA1UEChMPVS" + "5TLiBHb3Zlcm5tZW50MQwwCgYDVQQLEwNEb2QxEDAOBgNVBAsTB1Rlc3RpbmcxFTATBgNV" + "BAMTDENBMS1QUC4wMS4wMhcNOTkwMTAxMTIwMTAwWhcNNDgwMTAxMTIwMTAwWqAjMCEwCg" + "YDVR0UBAMCAQEwEwYDVR0jBAwwCoAIoTKVlZ8YCRAwDQYJKoZIhvcNAQEFBQADgYEAn94u" + "sT8ZYNzfHIdnx0+fV0jglL0Kn1duz+ehKHow+RGqH+J9opMYuXVD+rVQnLdZl5LbFBcv+5" + "TSP9WR9QtyoXar4/jmY2FFdBjfgO9w7p7OHD4WxblJmfPVOvrzFm/slZE39Oe5Qn4KlS03" + "9tttEFTKDH3qREQbT6g4k4ExxYM="; public static final String End_Certificate_PP_01_02_crt = "MIICbjCCAdegAwIBAgIBRjANBgkqhkiG9w0BAQUFADBeMQswCQYDVQQGEwJVUzEYMBYGA1" + "UEChMPVS5TLiBHb3Zlcm5tZW50MQwwCgYDVQQLEwNEb2QxEDAOBgNVBAsTB1Rlc3Rpbmcx" + "FTATBgNVBAMTDENBMS1QUC4wMS4wMjAeFw05ODAxMDExMjAxMDBaFw00ODAxMDExMjAxMD" + "BaMGAxCzAJBgNVBAYTAlVTMRgwFgYDVQQKEw9VLlMuIEdvdmVybm1lbnQxDDAKBgNVBAsT" + "A0RvRDEQMA4GA1UECxMHVGVzdGluZzEXMBUGA1UEAxMOVXNlcjEtUFAuMDEuMDIwgZ8wDQ" + "YJKoZIhvcNAQEBBQADgY0AMIGJAoGBANBwkwTWdZ977UAx6CCpXc9T4MX9T3/Tt6LbtY9I" + "eXxI9W15eXm/aqrKiXhULB+oF9/qNeUi2fAtrURZ7hgHbTaswr8CZ3Uwc6Rbkyj2GGiM6Z" + "8sKFztYZfFyGBiNEwfTT0yaUUQ6etIFqPuL/6qLvqXmvNPxFb9gjTH/azs/MdNAgMBAAGj" + "OjA4MA4GA1UdDwEB/wQEAwIF4DARBgNVHQ4ECgQIW1/BRCbe3c0wEwYDVR0jBAwwCoAIoT" + "KVlZ8YCRAwDQYJKoZIhvcNAQEFBQADgYEAPJg24q7wCU8CVlxFLchoe7txhkzApkVMIJ9G" + "+QTnraHDn0CZS6undCsJw8mrTNBQPHFn2Ixa5lrPfJvwW4Med1bcJKbwR4TveL1WeYYq6+" + "9k1kS/7KmqyKAKC/s504jAc7qgMd4b08oLxbGVfFVjWG/ZMbO770FrsyRHHs2rTOU="; public static final String[] TEST_35_DATA = new String[] { Intermediate_Certificate_PP_01_02_crt, Intermediate_CRL_PP_01_02_crl, End_Certificate_PP_01_02_crt }; /* * test36 * */ public static final String Intermediate_Certificate_1_PP_01_03_crt = "MIIClTCCAf6gAwIBAgIBRzANBgkqhkiG9w0BAQUFADBeMQswCQYDVQQGEwJVUzEYMBYGA1" + "UEChMPVS5TLiBHb3Zlcm5tZW50MQwwCgYDVQQLEwNEb0QxEDAOBgNVBAsTB1Rlc3Rpbmcx" + "FTATBgNVBAMTDFRydXN0IEFuY2hvcjAeFw05ODAxMDExMjAxMDBaFw00ODAxMDExMjAxMD" + "BaMF4xCzAJBgNVBAYTAlVTMRgwFgYDVQQKEw9VLlMuIEdvdmVybm1lbnQxDDAKBgNVBAsT" + "A0RvZDEQMA4GA1UECxMHVGVzdGluZzEVMBMGA1UEAxMMQ0ExLVBQLjAxLjAzMIGfMA0GCS" + "qGSIb3DQEBAQUAA4GNADCBiQKBgQDL/XgMvoeszcAzZqMYnv1At5u83Gb/CEX3fv6O1jL4" + "W3XbdvBNIZpuTwQhTH4Iofk9rIuQdkR7xOmbk4AqZINuas3Y1CPdzss7teraK0CNralNl1" + "jPYK+ClDBHt32Iw3bAl7RqWX73hl3YH6/7cvG4XCo1HqeeFFHUGa7HXGXq9QIDAQABo2Mw" + "YTAPBgNVHRMBAf8EBTADAQH/MA4GA1UdDwEB/wQEAwIBBjAWBgNVHSAEDzANMAsGCWCGSA" + "FlAwEwAjARBgNVHQ4ECgQITMu5Qbn1Cm4wEwYDVR0jBAwwCoAIq5rr+cLnVI8wDQYJKoZI" + "hvcNAQEFBQADgYEAuCnzXbHg87PIYYRbCCiXKDKA3MOcEKuxpNaSbtm12DQWpnvzmaK5nB" + "D/Ebko97CS7u9Tpwa7TmTyi39bYzY0dmVaotCDzfSTpzw6qHZl/w8riS+cKr0mimnjW1cq" + "kGPyHf0zBBqh0liGbd7EOLIBln0ASrn8V+G4Tj0Q6aQVcko="; public static final String Intermediate_Certificate_2_PP_01_03_crt = "MIIClTCCAf6gAwIBAgIBSDANBgkqhkiG9w0BAQUFADBeMQswCQYDVQQGEwJVUzEYMBYGA1" + "UEChMPVS5TLiBHb3Zlcm5tZW50MQwwCgYDVQQLEwNEb2QxEDAOBgNVBAsTB1Rlc3Rpbmcx" + "FTATBgNVBAMTDENBMS1QUC4wMS4wMzAeFw05ODAxMDExMjAxMDBaFw00ODAxMDExMjAxMD" + "BaMF4xCzAJBgNVBAYTAlVTMRgwFgYDVQQKEw9VLlMuIEdvdmVybm1lbnQxDDAKBgNVBAsT" + "A0RvZDEQMA4GA1UECxMHVGVzdGluZzEVMBMGA1UEAxMMQ0EyLVBQLjAxLjAzMIGfMA0GCS" + "qGSIb3DQEBAQUAA4GNADCBiQKBgQCu1Fq+gBJsBf5EjKKtNIxgdtgPMObby7tKH7fTJxYE" + "5LPyPi/IiWQ5Mi/8BCG3zmQhu9ZdBbpal350qCGVTbaMlnpi98D4WwXSw7e8oHIJIK689p" + "Q6Z5cf8hgwPnwDpYLeEaqxwhd4bu0x1lG1fUISA0ZZIQaEeNSJfdh15IkAswIDAQABo2Mw" + "YTAPBgNVHRMBAf8EBTADAQH/MA4GA1UdDwEB/wQEAwIBBjAWBgNVHSAEDzANMAsGCWCGSA" + "FlAwEwATARBgNVHQ4ECgQILRhQwULcyPYwEwYDVR0jBAwwCoAITMu5Qbn1Cm4wDQYJKoZI" + "hvcNAQEFBQADgYEAlEVOqXcdeTU7wT0l+/BJhlG5iaAcanAsOaJFZsXPjLMSjhldQe11/z" + "BsrrqjcpdctcmBarKO4MnwqVU9DN2RZ/v5Gps6OcPxj3T8wlrCGe4l6s9d1FncBMJ0RAUe" + "QEn2JLkQW5JWRBQ00+RXJYFuIM6Ger2MipWj1oOciv9MMoc="; public static final String Intermediate_CRL_1_PP_01_03_crl = "MIIBSzCBtQIBATANBgkqhkiG9w0BAQUFADBeMQswCQYDVQQGEwJVUzEYMBYGA1UEChMPVS" + "5TLiBHb3Zlcm5tZW50MQwwCgYDVQQLEwNEb2QxEDAOBgNVBAsTB1Rlc3RpbmcxFTATBgNV" + "BAMTDENBMS1QUC4wMS4wMxcNOTkwMTAxMTIwMTAwWhcNNDgwMTAxMTIwMTAwWqAjMCEwCg" + "YDVR0UBAMCAQEwEwYDVR0jBAwwCoAITMu5Qbn1Cm4wDQYJKoZIhvcNAQEFBQADgYEAycux" + "rzvy2IiYfFkTw7QgGuBhxIQPbSIbfudqyUumuviHJkIMZpPwYj2wltjyiRaozrDAWq8mlc" + "PsFYNr2lUYN5Cj4BhNQCNZlyBw7LLdzRgza55zVjmYkHWedyZm3kPWe7Y0w8xc/XIvi3iC" + "qlwV+X85cgHNJarx3GEYdb7Yos4="; public static final String Intermediate_CRL_2_PP_01_03_crl = "MIIBSzCBtQIBATANBgkqhkiG9w0BAQUFADBeMQswCQYDVQQGEwJVUzEYMBYGA1UEChMPVS" + "5TLiBHb3Zlcm5tZW50MQwwCgYDVQQLEwNEb2QxEDAOBgNVBAsTB1Rlc3RpbmcxFTATBgNV" + "BAMTDENBMi1QUC4wMS4wMxcNOTkwMTAxMTIwMTAwWhcNNDgwMTAxMTIwMTAwWqAjMCEwCg" + "YDVR0UBAMCAQEwEwYDVR0jBAwwCoAILRhQwULcyPYwDQYJKoZIhvcNAQEFBQADgYEAbcjU" + "+8l6pSik8PcuIzWndAg/w8uRfAgR5W9hPSXZChlx7uM+48wK98DGEXuTkJcbeclZia+Mpi" + "J5u3qG1zhoL1aHr+RqyJrjiWKC4/rDBuiUk/ftU54mrYn0qev3aSjf/GLtpcC8kC3gpqD+" + "20bvxLjBG3Vc9ZrxDvzfj8cD9K4="; public static final String End_Certificate_PP_01_03_crt = "MIIChjCCAe+gAwIBAgIBSTANBgkqhkiG9w0BAQUFADBeMQswCQYDVQQGEwJVUzEYMBYGA1" + "UEChMPVS5TLiBHb3Zlcm5tZW50MQwwCgYDVQQLEwNEb2QxEDAOBgNVBAsTB1Rlc3Rpbmcx" + "FTATBgNVBAMTDENBMi1QUC4wMS4wMzAeFw05ODAxMDExMjAxMDBaFw00ODAxMDExMjAxMD" + "BaMGAxCzAJBgNVBAYTAlVTMRgwFgYDVQQKEw9VLlMuIEdvdmVybm1lbnQxDDAKBgNVBAsT" + "A0RvRDEQMA4GA1UECxMHVGVzdGluZzEXMBUGA1UEAxMOVXNlcjEtUFAuMDEuMDMwgZ8wDQ" + "YJKoZIhvcNAQEBBQADgY0AMIGJAoGBAMO0l0+X6jfT8cY4DumtseTryyIJ7h+nraogXmYo" + "uhFGvMUWEAZVGD4x9QTTVEL/UCqNfzpI//Pp/uZpDudSgOX0ZdAbykObqCAEO85msK+eie" + "8baS1cW1XGjCuWDqNZko3Uo3c5lLPlRMbZ3hjvA1zmYh3prYnOh032GZAArVcVAgMBAAGj" + "UjBQMA4GA1UdDwEB/wQEAwIF4DAWBgNVHSAEDzANMAsGCWCGSAFlAwEwATARBgNVHQ4ECg" + "QIMh2aWvtm0mgwEwYDVR0jBAwwCoAILRhQwULcyPYwDQYJKoZIhvcNAQEFBQADgYEAigVE" + "FlCgbgKLR9FWIiwnz1bZ0MKsfhytllCI+jGx0Q3o3CxCGXs9PvL6BPDdMOxNIT/oU2uG64" + "EhZEjcZCnUknGx9OkkSSVq44P/pGuUx1g4Kx4i8gsJ/UPrPpYv/3heuMcKWCr92l33cxPT" + "IU+kmAtqy0MBvBKL4p635+MSIVA="; public static final String[] TEST_36_DATA = new String[] { Intermediate_Certificate_1_PP_01_03_crt, Intermediate_Certificate_2_PP_01_03_crt, Intermediate_CRL_1_PP_01_03_crl, Intermediate_CRL_2_PP_01_03_crl, End_Certificate_PP_01_03_crt }; /* * test37 * */ public static final String Intermediate_Certificate_1_PP_01_04_crt = "MIIClTCCAf6gAwIBAgIBSjANBgkqhkiG9w0BAQUFADBeMQswCQYDVQQGEwJVUzEYMBYGA1" + "UEChMPVS5TLiBHb3Zlcm5tZW50MQwwCgYDVQQLEwNEb0QxEDAOBgNVBAsTB1Rlc3Rpbmcx" + "FTATBgNVBAMTDFRydXN0IEFuY2hvcjAeFw05ODAxMDExMjAxMDBaFw00ODAxMDExMjAxMD" + "BaMF4xCzAJBgNVBAYTAlVTMRgwFgYDVQQKEw9VLlMuIEdvdmVybm1lbnQxDDAKBgNVBAsT" + "A0RvZDEQMA4GA1UECxMHVGVzdGluZzEVMBMGA1UEAxMMQ0ExLVBQLjAxLjA0MIGfMA0GCS" + "qGSIb3DQEBAQUAA4GNADCBiQKBgQC9gxMP8j4L+ISffY9wkislQ/V5sO9LzZOncYK93lZf" + "HXJG1MPSQzFPNzDLSc2zsilA03v6q+zr4NRrRWwWGmB34NGM4aqkoxox/7ngTn0MIq5gZ2" + "eOx0FbjA9W9DHEceVDS6kgs9lFcN2W+muCG2/fGqQUED9Fzl9JSM/tE8XAKwIDAQABo2Mw" + "YTAPBgNVHRMBAf8EBTADAQH/MA4GA1UdDwEB/wQEAwIBBjAWBgNVHSAEDzANMAsGCWCGSA" + "FlAwEwATARBgNVHQ4ECgQIgdUt9H4i6kwwEwYDVR0jBAwwCoAIq5rr+cLnVI8wDQYJKoZI" + "hvcNAQEFBQADgYEAxPe0vM0BvormJLF5HxkyFcTtoombfDGANoLoyj+PTWRD6z1/AcAx5K" + "rn/0J1sZo13M2ezaZUABbbpNH9X0OS225IJF4mXNpfkYhsz/+jNPGjRpN2p0K+DhMSawUw" + "QfGv2x6f31k6WCdy/769i1mwKP6Rpph2nkRyYW8MwO0N5HU="; public static final String Intermediate_Certificate_2_PP_01_04_crt = "MIIClTCCAf6gAwIBAgIBSzANBgkqhkiG9w0BAQUFADBeMQswCQYDVQQGEwJVUzEYMBYGA1" + "UEChMPVS5TLiBHb3Zlcm5tZW50MQwwCgYDVQQLEwNEb2QxEDAOBgNVBAsTB1Rlc3Rpbmcx" + "FTATBgNVBAMTDENBMS1QUC4wMS4wNDAeFw05ODAxMDExMjAxMDBaFw00ODAxMDExMjAxMD" + "BaMF4xCzAJBgNVBAYTAlVTMRgwFgYDVQQKEw9VLlMuIEdvdmVybm1lbnQxDDAKBgNVBAsT" + "A0RvZDEQMA4GA1UECxMHVGVzdGluZzEVMBMGA1UEAxMMQ0EyLVBQLjAxLjA0MIGfMA0GCS" + "qGSIb3DQEBAQUAA4GNADCBiQKBgQC7YCtN67S/ItOzaSGqTvfEE483HoQGiQZ0ob3+0beK" + "kmbSGADBQVBKe/sLJEKddyV2Gl8S4x+cKaKBWUI8lMZViJwWqVnyAFd8ZiAB/BpXaKKgP5" + "pFsg10Yo/EtsxGlLSTLurst0azNnFv7ca5Hb8te3T91eaI6y59IjbsRgilSQIDAQABo2Mw" + "YTAPBgNVHRMBAf8EBTADAQH/MA4GA1UdDwEB/wQEAwIBBjAWBgNVHSAEDzANMAsGCWCGSA" + "FlAwEwATARBgNVHQ4ECgQIGazrt+QRNCkwEwYDVR0jBAwwCoAIgdUt9H4i6kwwDQYJKoZI" + "hvcNAQEFBQADgYEAUIz/MSc6K5eaIAg8skaAgm6rSPvcU/711b9G0qsIs6YqvEz4zhGi5X" + "nalYYXfaSQzomuRuABNvuR1Ydaw/B9OdPMro0DhX8VpY6NzCL5Qj60/I4is5a+Hzgk82ck" + "eAC3okPHbVMd7R9kdFsWNE3Capnv7rriqXO3vwFw8b9vXD4="; public static final String Intermediate_CRL_1_PP_01_04_crl = "MIIBSzCBtQIBATANBgkqhkiG9w0BAQUFADBeMQswCQYDVQQGEwJVUzEYMBYGA1UEChMPVS" + "5TLiBHb3Zlcm5tZW50MQwwCgYDVQQLEwNEb2QxEDAOBgNVBAsTB1Rlc3RpbmcxFTATBgNV" + "BAMTDENBMS1QUC4wMS4wNBcNOTkwMTAxMTIwMTAwWhcNNDgwMTAxMTIwMTAwWqAjMCEwCg" + "YDVR0UBAMCAQEwEwYDVR0jBAwwCoAIgdUt9H4i6kwwDQYJKoZIhvcNAQEFBQADgYEAkR24" + "ebKfvEhDA0C7sawukQbv/q8mjSS3CrhA/oqeb8bML1IlW8rjHSXuRU/n3oeyAZuxLCAQMU" + "TPG6Vq4dOu8XC1RY74xIm8ps4mE0xB8/nI5kadHUSDPtUZhNzc8tv+z7fUGRaVGL7CBEpq" + "ICyQKYytCwxyf4xu2Ip71Uy2tuo="; public static final String Intermediate_CRL_2_PP_01_04_crl = "MIIBSzCBtQIBATANBgkqhkiG9w0BAQUFADBeMQswCQYDVQQGEwJVUzEYMBYGA1UEChMPVS" + "5TLiBHb3Zlcm5tZW50MQwwCgYDVQQLEwNEb2QxEDAOBgNVBAsTB1Rlc3RpbmcxFTATBgNV" + "BAMTDENBMi1QUC4wMS4wNBcNOTkwMTAxMTIwMTAwWhcNNDgwMTAxMTIwMTAwWqAjMCEwCg" + "YDVR0UBAMCAQEwEwYDVR0jBAwwCoAIGazrt+QRNCkwDQYJKoZIhvcNAQEFBQADgYEAjpUo" + "XSj0HX7Wm4w1FiRBBazInGOhSQX9VP2GcGb5lfr3GKt75Y+C+C9qd5X25DVkA4M1gPBK+u" + "XjSMQoHAmFJychQG23rcGcuDJlzRMyfvPCF9dOGLFdmkuHSo5hQUyYsxnXV8cWLIkR1AUz" + "PtUbTJL9g98R/OJFsCBiPi+By6w="; public static final String End_Certificate_PP_01_04_crt = "MIIChjCCAe+gAwIBAgIBTDANBgkqhkiG9w0BAQUFADBeMQswCQYDVQQGEwJVUzEYMBYGA1" + "UEChMPVS5TLiBHb3Zlcm5tZW50MQwwCgYDVQQLEwNEb2QxEDAOBgNVBAsTB1Rlc3Rpbmcx" + "FTATBgNVBAMTDENBMi1QUC4wMS4wNDAeFw05ODAxMDExMjAxMDBaFw00ODAxMDExMjAxMD" + "BaMGAxCzAJBgNVBAYTAlVTMRgwFgYDVQQKEw9VLlMuIEdvdmVybm1lbnQxDDAKBgNVBAsT" + "A0RvRDEQMA4GA1UECxMHVGVzdGluZzEXMBUGA1UEAxMOVXNlcjEtUFAuMDEuMDQwgZ8wDQ" + "YJKoZIhvcNAQEBBQADgY0AMIGJAoGBAOtf65MaydWM3bmMT8tAGCX8gZkx1JlgQyBlJT67" + "2APIkfmKRFK/dBtSwwCVGHZG4JYBrrwMpzUPrkGKYI6ZVIvvPnPfadZns9i5SM5LZFS+a5" + "JfbRnSJd8dXhZsKHxqkxIWwG6+VgnRKXE/Uc4m8TePQJZEOra5ezna5yhvqUwPAgMBAAGj" + "UjBQMA4GA1UdDwEB/wQEAwIF4DAWBgNVHSAEDzANMAsGCWCGSAFlAwEwAjARBgNVHQ4ECg" + "QI4iNoMjKiXMkwEwYDVR0jBAwwCoAIGazrt+QRNCkwDQYJKoZIhvcNAQEFBQADgYEAmOjp" + "2EupE1AmgjGfiGK1fk9kf39yQXK1EDsyO6KLdWL/bmWeYi/G7ZE57/+yVVADJuHI8xVIDZ" + "LAC0u5p35OLgbcmmA5bs52KWJJfa0nbgGpVaUSMg9SkEGS997OsgExWMvYhdFIKXlq4Rwc" + "ca89Hg1GlXdrpfD2OCDNBvcWB5Y="; public static final String[] TEST_37_DATA = new String[] { Intermediate_Certificate_1_PP_01_04_crt, Intermediate_Certificate_2_PP_01_04_crt, Intermediate_CRL_1_PP_01_04_crl, Intermediate_CRL_2_PP_01_04_crl, End_Certificate_PP_01_04_crt }; /* * test38 * */ public static final String Intermediate_Certificate_1_PP_01_05_crt = "MIIClTCCAf6gAwIBAgIBTTANBgkqhkiG9w0BAQUFADBeMQswCQYDVQQGEwJVUzEYMBYGA1" + "UEChMPVS5TLiBHb3Zlcm5tZW50MQwwCgYDVQQLEwNEb0QxEDAOBgNVBAsTB1Rlc3Rpbmcx" + "FTATBgNVBAMTDFRydXN0IEFuY2hvcjAeFw05ODAxMDExMjAxMDBaFw00ODAxMDExMjAxMD" + "BaMF4xCzAJBgNVBAYTAlVTMRgwFgYDVQQKEw9VLlMuIEdvdmVybm1lbnQxDDAKBgNVBAsT" + "A0RvZDEQMA4GA1UECxMHVGVzdGluZzEVMBMGA1UEAxMMQ0ExLVBQLjAxLjA1MIGfMA0GCS" + "qGSIb3DQEBAQUAA4GNADCBiQKBgQDFzEEzV/yUEORIOufyqpZzKpYz5aPyBbcDf8AMMCM5" + "tEz7j39cf1f227cbrTcAaUfYFwkrb07RU4bTS2X+U2Ak7Q5OROz5rrZBbsfwF3yHhwHxCg" + "KLjbwz7D+OJdNfv7x2HRckwfMUkmP4cEuJIIPwj1ieBbsnUi9dkWZePwl80QIDAQABo2Mw" + "YTAPBgNVHRMBAf8EBTADAQH/MA4GA1UdDwEB/wQEAwIBBjAWBgNVHSAEDzANMAsGCWCGSA" + "FlAwEwATARBgNVHQ4ECgQIjsCjmszYCHMwEwYDVR0jBAwwCoAIq5rr+cLnVI8wDQYJKoZI" + "hvcNAQEFBQADgYEAWMUBdOdHMB/SV5kPUk+zut9g/1v/GyxyB60mq9jGqjrIsk4a9JRqa5" + "MWju+6kVfSLelAOCR24EQsXnZM/5Qqg3Wb/SFJXWDcBnfWQWgh8UmJfmPhD7jViG5QVIxn" + "iALNCYtz373L+IDECLMO6S3wcTPsHdYv14jl6BKtabwIpE4="; public static final String Intermediate_Certificate_2_PP_01_05_crt = "MIIClTCCAf6gAwIBAgIBTjANBgkqhkiG9w0BAQUFADBeMQswCQYDVQQGEwJVUzEYMBYGA1" + "UEChMPVS5TLiBHb3Zlcm5tZW50MQwwCgYDVQQLEwNEb2QxEDAOBgNVBAsTB1Rlc3Rpbmcx" + "FTATBgNVBAMTDENBMS1QUC4wMS4wNTAeFw05ODAxMDExMjAxMDBaFw00ODAxMDExMjAxMD" + "BaMF4xCzAJBgNVBAYTAlVTMRgwFgYDVQQKEw9VLlMuIEdvdmVybm1lbnQxDDAKBgNVBAsT" + "A0RvZDEQMA4GA1UECxMHVGVzdGluZzEVMBMGA1UEAxMMQ0EyLVBQLjAxLjA1MIGfMA0GCS" + "qGSIb3DQEBAQUAA4GNADCBiQKBgQCZzdj+ixWCuxJGMjcoHUwSNqI9Wt9gYwXUTl+dWg/E" + "lg2SPJP7lrBOibAhSmaTorhunUSEf2adhdxhuGrd5Ucp6G0oZAa6ZDWaID4rKYWsI7d5kv" + "mrUhDEEdzk2s4PCoPiQm4dKwRg2rIvA5Dv+W1ldqSVSG376zVrQ5xdjDUX5QIDAQABo2Mw" + "YTAPBgNVHRMBAf8EBTADAQH/MA4GA1UdDwEB/wQEAwIBBjAWBgNVHSAEDzANMAsGCWCGSA" + "FlAwEwAjARBgNVHQ4ECgQIUASviIKBmJgwEwYDVR0jBAwwCoAIjsCjmszYCHMwDQYJKoZI" + "hvcNAQEFBQADgYEAa3c+0Drcq7iWP7K+gE6Mz/0ATQoiG87irXWfWBUGWtYnsh6K+1THMl" + "ibmZjYhsztK1P5rm6qL6HAyw0PhrRE9imqZ16cgiMomh65BWQImOeiXx9YWIPvjXWsE6iV" + "E31XShr9b9OZBA2+Zpydc3ID/SQzy9PiTAfL5yJiW/JZvFw="; public static final String Intermediate_CRL_1_PP_01_05_crl = "MIIBSzCBtQIBATANBgkqhkiG9w0BAQUFADBeMQswCQYDVQQGEwJVUzEYMBYGA1UEChMPVS" + "5TLiBHb3Zlcm5tZW50MQwwCgYDVQQLEwNEb2QxEDAOBgNVBAsTB1Rlc3RpbmcxFTATBgNV" + "BAMTDENBMS1QUC4wMS4wNRcNOTkwMTAxMTIwMTAwWhcNNDgwMTAxMTIwMTAwWqAjMCEwCg" + "YDVR0UBAMCAQEwEwYDVR0jBAwwCoAIjsCjmszYCHMwDQYJKoZIhvcNAQEFBQADgYEAZIzN" + "pXT89MplQgcXcA/K7YKlf62QCbw3rE+bUQiumJMlNGiVdaNJ8T66ObyoOWE+s+KN/Oetlu" + "HglQ7r6RG68gHYtZZiO6kmxq+wor65dFGQyRggpD+D47yioEgR12wUUksL/8oBW1pfGW2B" + "dR4sNWjzV5k5EWbLYu7wxj2/ubo="; public static final String Intermediate_CRL_2_PP_01_05_crl = "MIIBSzCBtQIBATANBgkqhkiG9w0BAQUFADBeMQswCQYDVQQGEwJVUzEYMBYGA1UEChMPVS" + "5TLiBHb3Zlcm5tZW50MQwwCgYDVQQLEwNEb2QxEDAOBgNVBAsTB1Rlc3RpbmcxFTATBgNV" + "BAMTDENBMi1QUC4wMS4wNRcNOTkwMTAxMTIwMTAwWhcNNDgwMTAxMTIwMTAwWqAjMCEwCg" + "YDVR0UBAMCAQEwEwYDVR0jBAwwCoAIUASviIKBmJgwDQYJKoZIhvcNAQEFBQADgYEAlZ06" + "h2L/89GvCtU1K1VtbHPMN/LAUYJrWFID1Eo+Cf/5wKEGBr8hxRtvshTK436zqVQRQN/XTq" + "7u0SLxvIixNRErlmUlGByi5vumN2OA77SxOyqYLCnBXTd5tWbFGz/udjaNk1MxOK0MQxPV" + "9R+HHUUVojRnAIQvlcqx/sMzU5o="; public static final String End_Certificate_PP_01_05_crt = "MIIChjCCAe+gAwIBAgIBTzANBgkqhkiG9w0BAQUFADBeMQswCQYDVQQGEwJVUzEYMBYGA1" + "UEChMPVS5TLiBHb3Zlcm5tZW50MQwwCgYDVQQLEwNEb2QxEDAOBgNVBAsTB1Rlc3Rpbmcx" + "FTATBgNVBAMTDENBMi1QUC4wMS4wNTAeFw05ODAxMDExMjAxMDBaFw00ODAxMDExMjAxMD" + "BaMGAxCzAJBgNVBAYTAlVTMRgwFgYDVQQKEw9VLlMuIEdvdmVybm1lbnQxDDAKBgNVBAsT" + "A0RvRDEQMA4GA1UECxMHVGVzdGluZzEXMBUGA1UEAxMOVXNlcjEtUFAuMDEuMDUwgZ8wDQ" + "YJKoZIhvcNAQEBBQADgY0AMIGJAoGBALyBn2GKvoKNHcu3AEJRCbWOyUpCc/onvRoQgWRr" + "wE7vMI7vjqnoR8mXdWDW5u9DFu9V5pb/yHBWn1zpgFGNnLrqn8irwR9i6Q+qlu4lXL5WSr" + "DqBqEKxrOBDPgkVz8Ldjt/Hy57qEukBarvpAwTc4XEJPAmxNrboMeGCEn2UShbAgMBAAGj" + "UjBQMA4GA1UdDwEB/wQEAwIF4DAWBgNVHSAEDzANMAsGCWCGSAFlAwEwATARBgNVHQ4ECg" + "QIaV3Cd/83r08wEwYDVR0jBAwwCoAIUASviIKBmJgwDQYJKoZIhvcNAQEFBQADgYEAVJXz" + "gooT1qd6rdehnLxJMf1HZ6JuqpyoQjzWF1jA3SkJmBDMXvAkMmIcQ7r5CZHaVF0iMQl5JW" + "fxPtM9Bws6jZhVL0TkwJHmbnSvbzUkJYeXPCP7ags4bu5I32co1nFVF6wf3aQDZeLFj/TU" + "1GCQ4rh80T5oknuazD4xXAYx9sE="; public static final String[] TEST_38_DATA = new String[] { Intermediate_Certificate_1_PP_01_05_crt, Intermediate_Certificate_2_PP_01_05_crt, Intermediate_CRL_1_PP_01_05_crl, Intermediate_CRL_2_PP_01_05_crl, End_Certificate_PP_01_05_crt }; /* * test39 * */ public static final String Intermediate_Certificate_1_PP_01_06_crt = "MIICvjCCAiegAwIBAgIBUDANBgkqhkiG9w0BAQUFADBeMQswCQYDVQQGEwJVUzEYMBYGA1" + "UEChMPVS5TLiBHb3Zlcm5tZW50MQwwCgYDVQQLEwNEb0QxEDAOBgNVBAsTB1Rlc3Rpbmcx" + "FTATBgNVBAMTDFRydXN0IEFuY2hvcjAeFw05ODAxMDExMjAxMDBaFw00ODAxMDExMjAxMD" + "BaMF4xCzAJBgNVBAYTAlVTMRgwFgYDVQQKEw9VLlMuIEdvdmVybm1lbnQxDDAKBgNVBAsT" + "A0RvZDEQMA4GA1UECxMHVGVzdGluZzEVMBMGA1UEAxMMQ0ExLVBQLjAxLjA2MIGfMA0GCS" + "qGSIb3DQEBAQUAA4GNADCBiQKBgQCjeJAwaZ0cw6O76hu15XadwJiTsIJcXZxGAETq8H9p" + "VJs7kJh57oLpO/lG8zG89QS9g1ozxaaGDWsSyXsDzv1eqDVZg3ISQu6XcKdDu8EwgQDY3S" + "EGkJ2AidFue3l0kEwR9+rtsuVKd/P+ULF1hWcoyLB/sQD5z8GvIiDKyRBiFwIDAQABo4GL" + "MIGIMA8GA1UdEwEB/wQFMAMBAf8wDgYDVR0PAQH/BAQDAgEGMD0GA1UdIAQ2MDQwCwYJYI" + "ZIAWUDATABMAsGCWCGSAFlAwEwAjALBglghkgBZQMBMAMwCwYJYIZIAWUDATAEMBEGA1Ud" + "DgQKBAh9i6tKUsPTgTATBgNVHSMEDDAKgAirmuv5wudUjzANBgkqhkiG9w0BAQUFAAOBgQ" + "B/Gxsb5lxSTN21CrjBp2aE+U1oTP2MpIFWUD1q8KWhZZF1iCQ7orcDVITqJPdPxDu1YwKk" + "zOegc4YBSJzHZqF/W4Kw4wisMfnWLTsUAeP/Ucz4vXk5rsf7IRssFG6PLxVmtRZizoxl9a" + "DO9abTM/jV8Mgi1IB6LdWgmtosBGBzbQ=="; public static final String Intermediate_Certificate_2_PP_01_06_crt = "MIICrzCCAhigAwIBAgIBUTANBgkqhkiG9w0BAQUFADBeMQswCQYDVQQGEwJVUzEYMBYGA1" + "UEChMPVS5TLiBHb3Zlcm5tZW50MQwwCgYDVQQLEwNEb2QxEDAOBgNVBAsTB1Rlc3Rpbmcx" + "FTATBgNVBAMTDENBMS1QUC4wMS4wNjAeFw05ODAxMDExMjAxMDBaFw00ODAxMDExMjAxMD" + "BaMF4xCzAJBgNVBAYTAlVTMRgwFgYDVQQKEw9VLlMuIEdvdmVybm1lbnQxDDAKBgNVBAsT" + "A0RvZDEQMA4GA1UECxMHVGVzdGluZzEVMBMGA1UEAxMMQ0EyLVBQLjAxLjA2MIGfMA0GCS" + "qGSIb3DQEBAQUAA4GNADCBiQKBgQC8DbqYUf437toWlRkOQA5PloqYQjWYpiR67yGSjQHp" + "j/HlduTYFS4qfUbLCjH4qsNUH8yQDvogImQw5M1IQOsUAqO6mYFxjqUWccuOaHT6XfUaOs" + "DDHr/tQUvhz3LJryaILiPlNcQF8QiYpujM1utVRyFpmUrMAlOvWUB93c/xUQIDAQABo30w" + "ezAPBgNVHRMBAf8EBTADAQH/MA4GA1UdDwEB/wQEAwIBBjAwBgNVHSAEKTAnMAsGCWCGSA" + "FlAwEwATALBglghkgBZQMBMAIwCwYJYIZIAWUDATADMBEGA1UdDgQKBAgQxGVMTJml1TAT" + "BgNVHSMEDDAKgAh9i6tKUsPTgTANBgkqhkiG9w0BAQUFAAOBgQALJtPqY5uROJ+2QYTekn" + "fSUc0gC7j3/cngIvxGT385xDLTrd6TjYSi+12+vU7RNd3MIZoz1o7RpWQV6C751WtOFuZi" + "iXeQ758aLqfhjYSVW/NHkO8vjrAMUzUbgjqb03k7q5JgtT6udB+9ySmou2/RxYW5p/IT17" + "euMVGmQb/RFg=="; public static final String Intermediate_Certificate_3_PP_01_06_crt = "MIICojCCAgugAwIBAgIBUjANBgkqhkiG9w0BAQUFADBeMQswCQYDVQQGEwJVUzEYMBYGA1" + "UEChMPVS5TLiBHb3Zlcm5tZW50MQwwCgYDVQQLEwNEb2QxEDAOBgNVBAsTB1Rlc3Rpbmcx" + "FTATBgNVBAMTDENBMi1QUC4wMS4wNjAeFw05ODAxMDExMjAxMDBaFw00ODAxMDExMjAxMD" + "BaMF4xCzAJBgNVBAYTAlVTMRgwFgYDVQQKEw9VLlMuIEdvdmVybm1lbnQxDDAKBgNVBAsT" + "A0RvZDEQMA4GA1UECxMHVGVzdGluZzEVMBMGA1UEAxMMQ0EzLVBQLjAxLjA2MIGfMA0GCS" + "qGSIb3DQEBAQUAA4GNADCBiQKBgQCsQqIx0ayxpIE8NduclvK1ubbNkXyvr0RDqnGOoyTj" + "yMtnfnwRbclkFCNBdalZYofuTWP0reqvqGqsBj+RS3uazvDBqVmn0J0AGRiLILummgEFRJ" + "ow8IB1hduDYJpDMrHRpfXpbG2H3fzN1XeX/B0hUZgdQ86GyK2qrmyIcyqZXwIDAQABo3Aw" + "bjAPBgNVHRMBAf8EBTADAQH/MA4GA1UdDwEB/wQEAwIBBjAjBgNVHSAEHDAaMAsGCWCGSA" + "FlAwEwATALBglghkgBZQMBMAIwEQYDVR0OBAoECNKJMmEWCA+jMBMGA1UdIwQMMAqACBDE" + "ZUxMmaXVMA0GCSqGSIb3DQEBBQUAA4GBAKv9F3+Y4N8RX4bRZ4fFTKri2rrB4BsVrBFpOr" + "SLzKnuyO1O5gg45d70pSHUAVBn3pz0f/6WwWLECq9tB7/Fphi0TyqeFmkRnysygZGlvLgs" + "L19bpIgVPkjFFziMGuzdAFIGy8vnV19yJ2euMygEHr20yiGBUaHHnKyuOGbDg4i7"; public static final String Intermediate_CRL_1_PP_01_06_crl = "MIIBSzCBtQIBATANBgkqhkiG9w0BAQUFADBeMQswCQYDVQQGEwJVUzEYMBYGA1UEChMPVS" + "5TLiBHb3Zlcm5tZW50MQwwCgYDVQQLEwNEb2QxEDAOBgNVBAsTB1Rlc3RpbmcxFTATBgNV" + "BAMTDENBMS1QUC4wMS4wNhcNOTkwMTAxMTIwMTAwWhcNNDgwMTAxMTIwMTAwWqAjMCEwCg" + "YDVR0UBAMCAQEwEwYDVR0jBAwwCoAIfYurSlLD04EwDQYJKoZIhvcNAQEFBQADgYEARL4u" + "DZvfcQDYanTfwU/hWAJDdDO7m7oQZLy3o0PTqXkk2Jd2v3+M2U8UN2PcuqZXT1lwS/piiW" + "Sc1x1YndD0qUtV4bOZ9SESPhCeOc1lQTk5mMf/zqFxQqYv8rfDB5O3QY4bjS7QQzSsvmal" + "TGCnoHmUJ4skmZJrQAzYnXyD9G4="; public static final String Intermediate_CRL_2_PP_01_06_crl = "MIIBSzCBtQIBATANBgkqhkiG9w0BAQUFADBeMQswCQYDVQQGEwJVUzEYMBYGA1UEChMPVS" + "5TLiBHb3Zlcm5tZW50MQwwCgYDVQQLEwNEb2QxEDAOBgNVBAsTB1Rlc3RpbmcxFTATBgNV" + "BAMTDENBMi1QUC4wMS4wNhcNOTkwMTAxMTIwMTAwWhcNNDgwMTAxMTIwMTAwWqAjMCEwCg" + "YDVR0UBAMCAQEwEwYDVR0jBAwwCoAIEMRlTEyZpdUwDQYJKoZIhvcNAQEFBQADgYEAcEyr" + "sgLhVq0L6N5fww/U6TW4lqaVAEtjqxluWRyZnL3AJLEHfwh1lllCG5dNM5fahGDOW/53fV" + "+gW5l92bsi2D/lAkDfNUdQdi5ZpQG9y2zhTArUlx9z1+KXklCi2Gg1X22gi+cYbK2hfzk6" + "kNGP1v42bjrkF/ECczpy3e41rEg="; public static final String Intermediate_CRL_3_PP_01_06_crl = "MIIBSzCBtQIBATANBgkqhkiG9w0BAQUFADBeMQswCQYDVQQGEwJVUzEYMBYGA1UEChMPVS" + "5TLiBHb3Zlcm5tZW50MQwwCgYDVQQLEwNEb2QxEDAOBgNVBAsTB1Rlc3RpbmcxFTATBgNV" + "BAMTDENBMy1QUC4wMS4wNhcNOTkwMTAxMTIwMTAwWhcNNDgwMTAxMTIwMTAwWqAjMCEwCg" + "YDVR0UBAMCAQEwEwYDVR0jBAwwCoAI0okyYRYID6MwDQYJKoZIhvcNAQEFBQADgYEAp3uQ" + "Tn2HC65TFmSjzvjuStIJwJcVahNcTWiGdtfTalZrMtuC9vUgQq0K1QIa7QNC9C3hQlzb5e" + "bO7JhJDs+5GZnnsqHN3pvdKEoueRfWBjUGpPnSGFD61ysf9aDFY2j9Amf3zcBFsXZs4+DM" + "dIENndbjkwqCV4zRTajAqCsIy20="; public static final String End_Certificate_PP_01_06_crt = "MIIClTCCAf6gAwIBAgIBUzANBgkqhkiG9w0BAQUFADBeMQswCQYDVQQGEwJVUzEYMBYGA1" + "UEChMPVS5TLiBHb3Zlcm5tZW50MQwwCgYDVQQLEwNEb2QxEDAOBgNVBAsTB1Rlc3Rpbmcx" + "FTATBgNVBAMTDENBMy1QUC4wMS4wNjAeFw05ODAxMDExMjAxMDBaFw00ODAxMDExMjAxMD" + "BaMF4xCzAJBgNVBAYTAlVTMRgwFgYDVQQKEw9VLlMuIEdvdmVybm1lbnQxDDAKBgNVBAsT" + "A0RvZDEQMA4GA1UECxMHVGVzdGluZzEVMBMGA1UEAxMMQ0E0LVBQLjAxLjA2MIGfMA0GCS" + "qGSIb3DQEBAQUAA4GNADCBiQKBgQC+IxiNJMOQG2gx1xd9ELNuzs9LrVJVRLvgP0lpWrx2" + "2HTEXPDB6YmrEg/YgyptmQ5Z4K6CEgJz3EdDOarCSGcL7DmcSEwEw46MV3piS5DrHwQ4GH" + "a2/ENSh3lF+6dliBwbQR2necmQ5g8ekqkWNb65pLl6RCNGkntJpdu8w5GWbwIDAQABo2Mw" + "YTAPBgNVHRMBAf8EBTADAQH/MA4GA1UdDwEB/wQEAwIF4DAWBgNVHSAEDzANMAsGCWCGSA" + "FlAwEwATARBgNVHQ4ECgQIMf/eRyakKwgwEwYDVR0jBAwwCoAI0okyYRYID6MwDQYJKoZI" + "hvcNAQEFBQADgYEADgpHRDgyPuK4dc+m2p0IELHUAK3qsdTZzBXsaA0rkkk1aRjI6DQ2qg" + "b4crRU3spQgYwBC7KQYd/hp8Lk17iX6fdV/9wol0DxTGhamOJA0uRl768awRArf4cEUElF" + "uWPN8D3wJEfL6BWgReUJWg8V9HEtdvXZZgzFN/CgHRkQ2RM="; public static final String[] TEST_39_DATA = new String[] { Intermediate_Certificate_1_PP_01_06_crt, Intermediate_Certificate_2_PP_01_06_crt, Intermediate_Certificate_3_PP_01_06_crt, Intermediate_CRL_1_PP_01_06_crl, Intermediate_CRL_2_PP_01_06_crl, Intermediate_CRL_3_PP_01_06_crl, End_Certificate_PP_01_06_crt }; /* * test40 * */ public static final String Intermediate_Certificate_1_PP_01_07_crt = "MIICrzCCAhigAwIBAgIBVDANBgkqhkiG9w0BAQUFADBeMQswCQYDVQQGEwJVUzEYMBYGA1" + "UEChMPVS5TLiBHb3Zlcm5tZW50MQwwCgYDVQQLEwNEb0QxEDAOBgNVBAsTB1Rlc3Rpbmcx" + "FTATBgNVBAMTDFRydXN0IEFuY2hvcjAeFw05ODAxMDExMjAxMDBaFw00ODAxMDExMjAxMD" + "BaMF4xCzAJBgNVBAYTAlVTMRgwFgYDVQQKEw9VLlMuIEdvdmVybm1lbnQxDDAKBgNVBAsT" + "A0RvZDEQMA4GA1UECxMHVGVzdGluZzEVMBMGA1UEAxMMQ0ExLVBQLjAxLjA3MIGfMA0GCS" + "qGSIb3DQEBAQUAA4GNADCBiQKBgQDs3Z/FfgJOyKp+Ds8xiQBM053cWylYbD+g+zuWDz3d" + "nD0eF77TLPITL7hwI058Pn3tXHlveuKMFqbvzWUgFXaBoHmmRohIj1eqfJQhlmKLjlSYyC" + "N4xhLVi7vg71ZjFdRk1k8ME1HDfpb2WXqXh9LyRYY8b/aqL+NHe1PUDbT6FQIDAQABo30w" + "ezAPBgNVHRMBAf8EBTADAQH/MA4GA1UdDwEB/wQEAwIBBjAwBgNVHSAEKTAnMAsGCWCGSA" + "FlAwEwATALBglghkgBZQMBMAIwCwYJYIZIAWUDATADMBEGA1UdDgQKBAgvehPxsTfSBDAT" + "BgNVHSMEDDAKgAirmuv5wudUjzANBgkqhkiG9w0BAQUFAAOBgQBpdMBEONGcpFitMN1ihf" + "W441E4HVTQwtF+h56aagVFndUF1gQsVEdDNmvvN/jdlzXotcfdEj1lOahmcwWbPOlNx3PB" + "LUPAcaNM9SCrXWi1gKJK3gXC2OAxj0mT5XhfPlAdfhZXTBZLqMqebmk6kVwa+VyPPZFHGy" + "BW0fV2ClJ69Q=="; public static final String Intermediate_Certificate_2_PP_01_07_crt = "MIICojCCAgugAwIBAgIBVTANBgkqhkiG9w0BAQUFADBeMQswCQYDVQQGEwJVUzEYMBYGA1" + "UEChMPVS5TLiBHb3Zlcm5tZW50MQwwCgYDVQQLEwNEb2QxEDAOBgNVBAsTB1Rlc3Rpbmcx" + "FTATBgNVBAMTDENBMS1QUC4wMS4wNzAeFw05ODAxMDExMjAxMDBaFw00ODAxMDExMjAxMD" + "BaMF4xCzAJBgNVBAYTAlVTMRgwFgYDVQQKEw9VLlMuIEdvdmVybm1lbnQxDDAKBgNVBAsT" + "A0RvZDEQMA4GA1UECxMHVGVzdGluZzEVMBMGA1UEAxMMQ0EyLVBQLjAxLjA3MIGfMA0GCS" + "qGSIb3DQEBAQUAA4GNADCBiQKBgQCrO/98w96Bg5YTTmtdc9sL8AOABGcYx5J8E1Y7/GhU" + "2sInc/j0dtBbE0Tj4KFIKpVLD0m2mTyHVCUA0/QGiS1Tq6DzmZW/V36Clya3CoX9rDTJyU" + "cKHpgntV19fFAK58aksyKCdP9jjLpbSspzOlIc+mVW+hkjgw3NcuY6fAOQvQIDAQABo3Aw" + "bjAPBgNVHRMBAf8EBTADAQH/MA4GA1UdDwEB/wQEAwIBBjAjBgNVHSAEHDAaMAsGCWCGSA" + "FlAwEwATALBglghkgBZQMBMAIwEQYDVR0OBAoECEmeATXRkM5EMBMGA1UdIwQMMAqACC96" + "E/GxN9IEMA0GCSqGSIb3DQEBBQUAA4GBAG/Qv60jyImedUXtCYl0QpQ1Ne2ZLxvUHRLms8" + "B1nXC/Rze7zfz5cwiyQn+6XN2rhuYFdTMDEFZDIjeeCLNllfan4GUAdRGtoJnfoLOGLlQf" + "RW1ONc80cxd1NTxHqxOtqpWdoJQEn8070WLqQPACEs88XYKBZ00sF9ZdSg5vhHUu"; public static final String Intermediate_Certificate_3_PP_01_07_crt = "MIIClTCCAf6gAwIBAgIBVjANBgkqhkiG9w0BAQUFADBeMQswCQYDVQQGEwJVUzEYMBYGA1" + "UEChMPVS5TLiBHb3Zlcm5tZW50MQwwCgYDVQQLEwNEb2QxEDAOBgNVBAsTB1Rlc3Rpbmcx" + "FTATBgNVBAMTDENBMi1QUC4wMS4wNzAeFw05ODAxMDExMjAxMDBaFw00ODAxMDExMjAxMD" + "BaMF4xCzAJBgNVBAYTAlVTMRgwFgYDVQQKEw9VLlMuIEdvdmVybm1lbnQxDDAKBgNVBAsT" + "A0RvZDEQMA4GA1UECxMHVGVzdGluZzEVMBMGA1UEAxMMQ0EzLVBQLjAxLjA3MIGfMA0GCS" + "qGSIb3DQEBAQUAA4GNADCBiQKBgQC+5b7o4iWl80ntDMKGcnquLQDTGlf6Gy/8y34Vw08/" + "8ij+nuHMiKpo6UCF0OpDcnkJ2ovvMsY5dAb5ErhH64UbnMlKbghnGv0sVidtipoC8u7ey1" + "YUIzDCdmbNvTfho6IXKzH8ev//K+FJd3qBuKHl9u2Kk5+igsyb+bPSid7d/QIDAQABo2Mw" + "YTAPBgNVHRMBAf8EBTADAQH/MA4GA1UdDwEB/wQEAwIBBjAWBgNVHSAEDzANMAsGCWCGSA" + "FlAwEwATARBgNVHQ4ECgQIUDKu7h5EQ70wEwYDVR0jBAwwCoAISZ4BNdGQzkQwDQYJKoZI" + "hvcNAQEFBQADgYEAnKhR3OvdgtVtmio7ikCvjxlSoKVbUleazxONOxHUAKdXEv0/mSOTwp" + "hPPIoE2xAqPOOHvXPmzmJpPADjrfhU6afJ7ThDRFTMk4ZLOkT1SvRlymK7uWhj5bhUgi6S" + "UQ2LUmrY2hIN4cTrrzZvDw2Q/6UIuqpmySXEOHDL5T5MXEo="; public static final String Intermediate_CRL_1_PP_01_07_crl = "MIIBSzCBtQIBATANBgkqhkiG9w0BAQUFADBeMQswCQYDVQQGEwJVUzEYMBYGA1UEChMPVS" + "5TLiBHb3Zlcm5tZW50MQwwCgYDVQQLEwNEb2QxEDAOBgNVBAsTB1Rlc3RpbmcxFTATBgNV" + "BAMTDENBMS1QUC4wMS4wNxcNOTkwMTAxMTIwMTAwWhcNNDgwMTAxMTIwMTAwWqAjMCEwCg" + "YDVR0UBAMCAQEwEwYDVR0jBAwwCoAIL3oT8bE30gQwDQYJKoZIhvcNAQEFBQADgYEA4gZR" + "71wRXNdxWe7kaQPAw44UUw+cN1bDBU0RV7nwYAFDYxDIaDGOfjhUVTMBq4rb51S7uqIqYS" + "F6j7BdLXl9WVRJobfkRH0t0cBnuSeQRz3ckrZrCuvyxb3PEL3pbf0UH1i/BfoG+EHJAY7R" + "OVOL/dyoXeX6ehH6ImGhucDixS0="; public static final String Intermediate_CRL_2_PP_01_07_crl = "MIIBSzCBtQIBATANBgkqhkiG9w0BAQUFADBeMQswCQYDVQQGEwJVUzEYMBYGA1UEChMPVS" + "5TLiBHb3Zlcm5tZW50MQwwCgYDVQQLEwNEb2QxEDAOBgNVBAsTB1Rlc3RpbmcxFTATBgNV" + "BAMTDENBMi1QUC4wMS4wNxcNOTkwMTAxMTIwMTAwWhcNNDgwMTAxMTIwMTAwWqAjMCEwCg" + "YDVR0UBAMCAQEwEwYDVR0jBAwwCoAISZ4BNdGQzkQwDQYJKoZIhvcNAQEFBQADgYEAfzKw" + "NHrl10PJDHa3olBYXYzXi94zxDsEQSIb+W4pPXUfDZijPqL1NzapLqc/uL1Sl28GmLDrbm" + "nCrlMn1Kt/gI6XndOnSyC9Sg6WDxAI3HTHxlG5MHLBn9Lb36CHobnwep1BMo8zl2clh0Kz" + "PIxQSGXM1BDpHkwF5eoFAolDih4="; public static final String Intermediate_CRL_3_PP_01_07_crl = "MIIBSzCBtQIBATANBgkqhkiG9w0BAQUFADBeMQswCQYDVQQGEwJVUzEYMBYGA1UEChMPVS" + "5TLiBHb3Zlcm5tZW50MQwwCgYDVQQLEwNEb2QxEDAOBgNVBAsTB1Rlc3RpbmcxFTATBgNV" + "BAMTDENBMy1QUC4wMS4wNxcNOTkwMTAxMTIwMTAwWhcNNDgwMTAxMTIwMTAwWqAjMCEwCg" + "YDVR0UBAMCAQEwEwYDVR0jBAwwCoAIUDKu7h5EQ70wDQYJKoZIhvcNAQEFBQADgYEAj7+M" + "EeIe1GmJpbRUFqbNrDvT5tHjKQMNdbe5Y8F920U5t0ig1Up60kc7hs7LH57i6R/quPOpym" + "a9Eo9Bql+P2Bg9FELih5/a4B021TZBmmdSI5fwQZ6Q5PjgG58Zl2cJitNYvGi7tVUBojA5" + "CSN7KBMyipia9ivxm9a/llJPrQY="; public static final String End_Certificate_PP_01_07_crt = "MIIClTCCAf6gAwIBAgIBVzANBgkqhkiG9w0BAQUFADBeMQswCQYDVQQGEwJVUzEYMBYGA1" + "UEChMPVS5TLiBHb3Zlcm5tZW50MQwwCgYDVQQLEwNEb2QxEDAOBgNVBAsTB1Rlc3Rpbmcx" + "FTATBgNVBAMTDENBMy1QUC4wMS4wNzAeFw05ODAxMDExMjAxMDBaFw00ODAxMDExMjAxMD" + "BaMF4xCzAJBgNVBAYTAlVTMRgwFgYDVQQKEw9VLlMuIEdvdmVybm1lbnQxDDAKBgNVBAsT" + "A0RvZDEQMA4GA1UECxMHVGVzdGluZzEVMBMGA1UEAxMMQ0E0LVBQLjAxLjA3MIGfMA0GCS" + "qGSIb3DQEBAQUAA4GNADCBiQKBgQC/RmUcYHxgQRHCUh5cMug/J2o8DzYbT+2pIehJkNCr" + "zfqemV3qshLdMct5GV73oEkG5b6n7tj3/hI1TLh/A3LQpKROAGZybdo9fk4Pa0+6V6ql/U" + "NnSpcAKct/f3IvchGo9nBGdi9aE+j+xKhMM6E8xj1+Jc7Z0xz7zE4+qRbeZQIDAQABo2Mw" + "YTAPBgNVHRMBAf8EBTADAQH/MA4GA1UdDwEB/wQEAwIF4DAWBgNVHSAEDzANMAsGCWCGSA" + "FlAwEwAjARBgNVHQ4ECgQI/y572lfRyH4wEwYDVR0jBAwwCoAIUDKu7h5EQ70wDQYJKoZI" + "hvcNAQEFBQADgYEANl9zdMKbaq14OP45PeK9D4ftOSuliW2di1qAX38FQoWPYLLoaDU0Q1" + "9I54PDY/UYRR9jKDl1WPhV6cD+65eadtiOZVr/h1CaW/HxTloouzN4z1zCXMC7AxZKo+EI" + "XLN8f4w7hKLFYgf6gP9+iVi+T2gKfH5Ch2zjRhlmGFRgsBQ="; public static final String[] TEST_40_DATA = new String[] { Intermediate_Certificate_1_PP_01_07_crt, Intermediate_Certificate_2_PP_01_07_crt, Intermediate_Certificate_3_PP_01_07_crt, Intermediate_CRL_1_PP_01_07_crl, Intermediate_CRL_2_PP_01_07_crl, Intermediate_CRL_3_PP_01_07_crl, End_Certificate_PP_01_07_crt }; /* * test41 * */ public static final String Intermediate_Certificate_1_PP_01_08_crt = "MIICojCCAgugAwIBAgIBWDANBgkqhkiG9w0BAQUFADBeMQswCQYDVQQGEwJVUzEYMBYGA1" + "UEChMPVS5TLiBHb3Zlcm5tZW50MQwwCgYDVQQLEwNEb0QxEDAOBgNVBAsTB1Rlc3Rpbmcx" + "FTATBgNVBAMTDFRydXN0IEFuY2hvcjAeFw05ODAxMDExMjAxMDBaFw00ODAxMDExMjAxMD" + "BaMF4xCzAJBgNVBAYTAlVTMRgwFgYDVQQKEw9VLlMuIEdvdmVybm1lbnQxDDAKBgNVBAsT" + "A0RvZDEQMA4GA1UECxMHVGVzdGluZzEVMBMGA1UEAxMMQ0ExLVBQLjAxLjA4MIGfMA0GCS" + "qGSIb3DQEBAQUAA4GNADCBiQKBgQDDe20HLq7R8b0fWTsEiNV3Z5IbQseZ8QCW+1cb6yM+" + "ArKLJDnXx8zmTHSHQCpw3G7xhGsxA1btm0cSC5P/1bw/kFWsSLRe2NFF6oKU+7c+cgIUMB" + "kzyXk+kpWAQRb7hcb50iKdKFtO8gMNGMAxlHRI05/1tThyAs9suI4TrxTS9QIDAQABo3Aw" + "bjAPBgNVHRMBAf8EBTADAQH/MA4GA1UdDwEB/wQEAwIBBjAjBgNVHSAEHDAaMAsGCWCGSA" + "FlAwEwATALBglghkgBZQMBMAIwEQYDVR0OBAoECFxr9vgF31fKMBMGA1UdIwQMMAqACKua" + "6/nC51SPMA0GCSqGSIb3DQEBBQUAA4GBABaX7TYfmSyVmzGCVbTFweUuPilo4wzy7z/w0x" + "y4uSaM/YMtixUdDPpTHOJNYDdeV85v+w9oezdL2ZYAaGn7tldC6k8ouq/6hOGGST+ziHJS" + "gTOD8UVBQPRPvWEwgmDIprnzrVRz8rG6uqslXNiBDnO9BMGpRo4dy8YpOmV6BPCD"; public static final String Intermediate_Certificate_2_PP_01_08_crt = "MIIClTCCAf6gAwIBAgIBWTANBgkqhkiG9w0BAQUFADBeMQswCQYDVQQGEwJVUzEYMBYGA1" + "UEChMPVS5TLiBHb3Zlcm5tZW50MQwwCgYDVQQLEwNEb2QxEDAOBgNVBAsTB1Rlc3Rpbmcx" + "FTATBgNVBAMTDENBMS1QUC4wMS4wODAeFw05ODAxMDExMjAxMDBaFw00ODAxMDExMjAxMD" + "BaMF4xCzAJBgNVBAYTAlVTMRgwFgYDVQQKEw9VLlMuIEdvdmVybm1lbnQxDDAKBgNVBAsT" + "A0RvZDEQMA4GA1UECxMHVGVzdGluZzEVMBMGA1UEAxMMQ0EyLVBQLjAxLjA4MIGfMA0GCS" + "qGSIb3DQEBAQUAA4GNADCBiQKBgQC8nLZcMLHYKxVqbhwJiqQbAYhf7S6ck2O9AhNor935" + "Bfm7/8qVZbBAotQy1PoCjSW0UYdknDolWvi8aAtO0f9XVrAv6BZVVW9j3osIGN/XUThaN+" + "9dZ83kGpyjeoitpGK4wbFNDteuBFYp+8gFNupnX7JQwUK3aGwBUucbe7puRQIDAQABo2Mw" + "YTAPBgNVHRMBAf8EBTADAQH/MA4GA1UdDwEB/wQEAwIBBjAWBgNVHSAEDzANMAsGCWCGSA" + "FlAwEwATARBgNVHQ4ECgQIL0xyFYBk4OcwEwYDVR0jBAwwCoAIXGv2+AXfV8owDQYJKoZI" + "hvcNAQEFBQADgYEAPk+Lys0Ueoyhp544EH9Hqy9+gY+l/+N99v7KvBlZWKuhkwZDE+qAYT" + "P/SOPsWe8ADZE2iQ4pOlpK8jSqtJSdK69RgGL9omLnR04L9c/zKLArBE+VmoV7mohcQp8x" + "aB4q/g3QnAqwfFYDjIWW3H6gRAeQ5MOtKdz/4042fJxc5L8="; public static final String Intermediate_Certificate_3_PP_01_08_crt = "MIIClTCCAf6gAwIBAgIBWjANBgkqhkiG9w0BAQUFADBeMQswCQYDVQQGEwJVUzEYMBYGA1" + "UEChMPVS5TLiBHb3Zlcm5tZW50MQwwCgYDVQQLEwNEb2QxEDAOBgNVBAsTB1Rlc3Rpbmcx" + "FTATBgNVBAMTDENBMi1QUC4wMS4wODAeFw05ODAxMDExMjAxMDBaFw00ODAxMDExMjAxMD" + "BaMF4xCzAJBgNVBAYTAlVTMRgwFgYDVQQKEw9VLlMuIEdvdmVybm1lbnQxDDAKBgNVBAsT" + "A0RvZDEQMA4GA1UECxMHVGVzdGluZzEVMBMGA1UEAxMMQ0EzLVBQLjAxLjA4MIGfMA0GCS" + "qGSIb3DQEBAQUAA4GNADCBiQKBgQCvy6bNOyVaP8JTwiySFa3Sj+rdSqzkalK5gA7DLk4q" + "AyvnAK64HgbCsb8dpnSi94WBDsocrQ4C1Ltoahc/AZyRVLA/REsAh1r3/0FALZgYiIxvSF" + "m3ihKb3P9URBbotzhl1ahRZPSrcxKwNXEmxB0gjixGW7GZTARq3Il5ressRwIDAQABo2Mw" + "YTAPBgNVHRMBAf8EBTADAQH/MA4GA1UdDwEB/wQEAwIBBjAWBgNVHSAEDzANMAsGCWCGSA" + "FlAwEwAjARBgNVHQ4ECgQIwFtfZBe/KqUwEwYDVR0jBAwwCoAIL0xyFYBk4OcwDQYJKoZI" + "hvcNAQEFBQADgYEAeZhpIDEYyV/LkOtUf1TryemJExQ1jdfirJ3AUtoFIoWz1p9aqnV6Po" + "GAMozjtdyotfSA2O8c065DwD+CvUXPmdD+2vWpX/2hJPj+x++UvvntAokD2UE9HCeEvBHK" + "rr59hvKKd6GChyhAjLris202eTLIiMEoyZy9X/Wt1nXF8/g="; public static final String Intermediate_CRL_1_PP_01_08_crl = "MIIBSzCBtQIBATANBgkqhkiG9w0BAQUFADBeMQswCQYDVQQGEwJVUzEYMBYGA1UEChMPVS" + "5TLiBHb3Zlcm5tZW50MQwwCgYDVQQLEwNEb2QxEDAOBgNVBAsTB1Rlc3RpbmcxFTATBgNV" + "BAMTDENBMS1QUC4wMS4wOBcNOTkwMTAxMTIwMTAwWhcNNDgwMTAxMTIwMTAwWqAjMCEwCg" + "YDVR0UBAMCAQEwEwYDVR0jBAwwCoAIXGv2+AXfV8owDQYJKoZIhvcNAQEFBQADgYEAhkwT" + "E/EGAe32J883qVrh1wG5xQzO/GGfp/zuDYGL2k1zZ2zq7MajKfzBoXXQ3WPh5dTK1sy5o5" + "boPHG0pge0B4/2JvuDVS539+9HAPansUNsrMXzOblg1acjdKtuk4oS8PIYkM/lbA6yJl6F" + "QMbdIthWqa2gjaWKll3R8fVUjxI="; public static final String Intermediate_CRL_2_PP_01_08_crl = "MIIBSzCBtQIBATANBgkqhkiG9w0BAQUFADBeMQswCQYDVQQGEwJVUzEYMBYGA1UEChMPVS" + "5TLiBHb3Zlcm5tZW50MQwwCgYDVQQLEwNEb2QxEDAOBgNVBAsTB1Rlc3RpbmcxFTATBgNV" + "BAMTDENBMi1QUC4wMS4wOBcNOTkwMTAxMTIwMTAwWhcNNDgwMTAxMTIwMTAwWqAjMCEwCg" + "YDVR0UBAMCAQEwEwYDVR0jBAwwCoAIL0xyFYBk4OcwDQYJKoZIhvcNAQEFBQADgYEAN6BQ" + "sEQT5YCvs9vlUSdG4gjTgNkyQTCdmSIcufpK4MG/AoW/Fn5zJXxiMyHmvT/dkk/UOf82/s" + "41YI/Inz4qRmGF4IL7jo+l7V+OI1n+Vf4ClgZU6ocb9d1dFoBkJu3xI9dcWK6ExpzaBUXw" + "rPJilV4M5luGbszdDCs9cLjmiRA="; public static final String Intermediate_CRL_3_PP_01_08_crl = "MIIBSzCBtQIBATANBgkqhkiG9w0BAQUFADBeMQswCQYDVQQGEwJVUzEYMBYGA1UEChMPVS" + "5TLiBHb3Zlcm5tZW50MQwwCgYDVQQLEwNEb2QxEDAOBgNVBAsTB1Rlc3RpbmcxFTATBgNV" + "BAMTDENBMy1QUC4wMS4wOBcNOTkwMTAxMTIwMTAwWhcNNDgwMTAxMTIwMTAwWqAjMCEwCg" + "YDVR0UBAMCAQEwEwYDVR0jBAwwCoAIwFtfZBe/KqUwDQYJKoZIhvcNAQEFBQADgYEAkmDx" + "t+r59llppKmm9mSTof9/BX2rNyG9LfIH7wweoDi9be2vYOLy0NU1kJ8f3/muEw2v7hWDri" + "k9ROLDFnb/S8MYVT0l4rymRhpshPF1uMTOZmfJUCfTX9jIaShztSScqcGSP0a3EUfDD14R" + "1yMu2pdlMM35llE0lV3uf/eUNr0="; public static final String End_Certificate_PP_01_08_crt = "MIIClTCCAf6gAwIBAgIBWzANBgkqhkiG9w0BAQUFADBeMQswCQYDVQQGEwJVUzEYMBYGA1" + "UEChMPVS5TLiBHb3Zlcm5tZW50MQwwCgYDVQQLEwNEb2QxEDAOBgNVBAsTB1Rlc3Rpbmcx" + "FTATBgNVBAMTDENBMy1QUC4wMS4wODAeFw05ODAxMDExMjAxMDBaFw00ODAxMDExMjAxMD" + "BaMF4xCzAJBgNVBAYTAlVTMRgwFgYDVQQKEw9VLlMuIEdvdmVybm1lbnQxDDAKBgNVBAsT" + "A0RvZDEQMA4GA1UECxMHVGVzdGluZzEVMBMGA1UEAxMMQ0E0LVBQLjAxLjA4MIGfMA0GCS" + "qGSIb3DQEBAQUAA4GNADCBiQKBgQDTWNp6Oz39wwU8AFDzYVs3UfVvXg+t6j/qFavnvllI" + "NO6aU1o4Hnk1wfmTPZPErc00/MfizMSumTYYRl21hEZWhjNO5uQIHrF9V/4OToo2iOfsPd" + "gxwpSokwxcl7CJyadwUxhRDYCLhSORXoCK1CPQZjwb+uQz799O5ozb0WVNYQIDAQABo2Mw" + "YTAPBgNVHRMBAf8EBTADAQH/MA4GA1UdDwEB/wQEAwIF4DAWBgNVHSAEDzANMAsGCWCGSA" + "FlAwEwAjARBgNVHQ4ECgQIO1TNJtWwaiIwEwYDVR0jBAwwCoAIwFtfZBe/KqUwDQYJKoZI" + "hvcNAQEFBQADgYEANmP9hyFnYvi8gdtRe8ERoEG90NwoyPTsB8sXd40f+Sm1QxKqMPzKPL" + "7bOtY12JGwZ55a6HFVgpw4PnU+0iOcCMHS5OQQLtyirxX2HfioiXEmcmRJT6FvLHrGIHGv" + "KNcfc3rUiksdOb6+j2k8x4IwQ6pBEHQwY8U4Y4DgqALlqM0="; public static final String[] TEST_41_DATA = new String[] { Intermediate_Certificate_1_PP_01_08_crt, Intermediate_Certificate_2_PP_01_08_crt, Intermediate_Certificate_3_PP_01_08_crt, Intermediate_CRL_1_PP_01_08_crl, Intermediate_CRL_2_PP_01_08_crl, Intermediate_CRL_3_PP_01_08_crl, End_Certificate_PP_01_08_crt }; /* * test42 * */ public static final String Intermediate_Certificate_1_PP_01_09_crt = "MIICrzCCAhigAwIBAgIBXDANBgkqhkiG9w0BAQUFADBeMQswCQYDVQQGEwJVUzEYMBYGA1" + "UEChMPVS5TLiBHb3Zlcm5tZW50MQwwCgYDVQQLEwNEb0QxEDAOBgNVBAsTB1Rlc3Rpbmcx" + "FTATBgNVBAMTDFRydXN0IEFuY2hvcjAeFw05ODAxMDExMjAxMDBaFw00ODAxMDExMjAxMD" + "BaMF4xCzAJBgNVBAYTAlVTMRgwFgYDVQQKEw9VLlMuIEdvdmVybm1lbnQxDDAKBgNVBAsT" + "A0RvZDEQMA4GA1UECxMHVGVzdGluZzEVMBMGA1UEAxMMQ0ExLVBQLjAxLjA5MIGfMA0GCS" + "qGSIb3DQEBAQUAA4GNADCBiQKBgQDJqSSqGjgI3JUJfA/XkloAOg2QtZeAGp2nCq1Oiply" + "MTjJpMpEOSRYrEIgKMGnBPq33seP7X/obCT2jgexmbFT2TmPirM+h1aqbGQ7QAqsx80BdE" + "ofdcfiNosLbbzli9qFrbarO7fJfBhzraBFGDJj3N8nLi2YtP9IieFYJ/MhKwIDAQABo30w" + "ezAPBgNVHRMBAf8EBTADAQH/MA4GA1UdDwEB/wQEAwIBBjAwBgNVHSAEKTAnMAsGCWCGSA" + "FlAwEwATALBglghkgBZQMBMAIwCwYJYIZIAWUDATADMBEGA1UdDgQKBAiVRMrZuHQ7VjAT" + "BgNVHSMEDDAKgAirmuv5wudUjzANBgkqhkiG9w0BAQUFAAOBgQCetZy9JMzUVveSPE2fQY" + "4fRVChyvIc9nCE4wbzhnRl3zduBGmAwTFr7dRWSFTnEq1c2b6B5nJtCzmt4Ovapf69sIlM" + "s3iV16eBB1WTNCY8YlAsnmZ7q/AR0t0vX+hh6QV6zN5xqulOM4Y8csZEx3RWJzV/LjE5w7" + "mKvofBEUoqQA=="; public static final String Intermediate_Certificate_2_PP_01_09_crt = "MIICojCCAgugAwIBAgIBXTANBgkqhkiG9w0BAQUFADBeMQswCQYDVQQGEwJVUzEYMBYGA1" + "UEChMPVS5TLiBHb3Zlcm5tZW50MQwwCgYDVQQLEwNEb2QxEDAOBgNVBAsTB1Rlc3Rpbmcx" + "FTATBgNVBAMTDENBMS1QUC4wMS4wOTAeFw05ODAxMDExMjAxMDBaFw00ODAxMDExMjAxMD" + "BaMF4xCzAJBgNVBAYTAlVTMRgwFgYDVQQKEw9VLlMuIEdvdmVybm1lbnQxDDAKBgNVBAsT" + "A0RvZDEQMA4GA1UECxMHVGVzdGluZzEVMBMGA1UEAxMMQ0EyLVBQLjAxLjA5MIGfMA0GCS" + "qGSIb3DQEBAQUAA4GNADCBiQKBgQDWUTlTieoi7aLGUYOAgqUC2J/6JarOWfv4vobpwjAA" + "DjvQGqg/GCZP7FgD/72Z4YefZKJEFZTDnYfmy2qh6iBYxcvLsJ+PJGzPCObNSmyq8gpeXy" + "KKEeCZtEev1tSywTT6E5Dhee4dX0QHE4ydZEliMMXGRW/8ffT6x54CPwVylQIDAQABo3Aw" + "bjAPBgNVHRMBAf8EBTADAQH/MA4GA1UdDwEB/wQEAwIBBjAjBgNVHSAEHDAaMAsGCWCGSA" + "FlAwEwATALBglghkgBZQMBMAIwEQYDVR0OBAoECAMhmGN8+qXoMBMGA1UdIwQMMAqACJVE" + "ytm4dDtWMA0GCSqGSIb3DQEBBQUAA4GBALNjokGrTnWsPn5KrlO+g3R8tAGM90JQDjfrap" + "xWM+nN+dUVVdGU6w2pAOAq2UhfySiP42qiFChnPK9oOqPF2Or7/kcmXZzBfZkE/FnJGNUA" + "gs9je1nZvTPQYsF094OqE7QdJi2k3seA1tqejA1kihMHpwQNmIp8bFpqn4dPO6ys"; public static final String Intermediate_Certificate_3_PP_01_09_crt = "MIIClTCCAf6gAwIBAgIBXjANBgkqhkiG9w0BAQUFADBeMQswCQYDVQQGEwJVUzEYMBYGA1" + "UEChMPVS5TLiBHb3Zlcm5tZW50MQwwCgYDVQQLEwNEb2QxEDAOBgNVBAsTB1Rlc3Rpbmcx" + "FTATBgNVBAMTDENBMi1QUC4wMS4wOTAeFw05ODAxMDExMjAxMDBaFw00ODAxMDExMjAxMD" + "BaMF4xCzAJBgNVBAYTAlVTMRgwFgYDVQQKEw9VLlMuIEdvdmVybm1lbnQxDDAKBgNVBAsT" + "A0RvZDEQMA4GA1UECxMHVGVzdGluZzEVMBMGA1UEAxMMQ0EzLVBQLjAxLjA5MIGfMA0GCS" + "qGSIb3DQEBAQUAA4GNADCBiQKBgQDHUpHhF4ANNLOywnvpqyDgzLMtatW3ZxgLBBRYk6TE" + "jMgTVKmRasVRTA9uatGG4b2f70YWs9cOd4ylQDqPEDdKNZ47bqZdX6RAU3j1dO9LBwWDbp" + "NvZ3zuDBRDoCZClIcBESDYweaZ9nUgKl/WxTeCnMwqkfSJGYBBcHIonRPnGwIDAQABo2Mw" + "YTAPBgNVHRMBAf8EBTADAQH/MA4GA1UdDwEB/wQEAwIBBjAWBgNVHSAEDzANMAsGCWCGSA" + "FlAwEwAjARBgNVHQ4ECgQIyppef22OmjEwEwYDVR0jBAwwCoAIAyGYY3z6pegwDQYJKoZI" + "hvcNAQEFBQADgYEAOySUCY+PZxomhWgTRSKRodOIe/QSfCMSC+0iw24a2TuJzFLjN9pSm9" + "0C2PqWbfwD1uDjrteO1NK+1yhtIDySiptR9GmR/fhL7NJ+z7M4fEJBjjeeI9/aEIuHuBFT" + "TVHfwsJxnZtjujtOdl56B825LsKW8Otumd2A43N9wIgSyBg="; public static final String Intermediate_Certificate_4_PP_01_09_crt = "MIIClTCCAf6gAwIBAgIBXzANBgkqhkiG9w0BAQUFADBeMQswCQYDVQQGEwJVUzEYMBYGA1" + "UEChMPVS5TLiBHb3Zlcm5tZW50MQwwCgYDVQQLEwNEb2QxEDAOBgNVBAsTB1Rlc3Rpbmcx" + "FTATBgNVBAMTDENBMy1QUC4wMS4wOTAeFw05ODAxMDExMjAxMDBaFw00ODAxMDExMjAxMD" + "BaMF4xCzAJBgNVBAYTAlVTMRgwFgYDVQQKEw9VLlMuIEdvdmVybm1lbnQxDDAKBgNVBAsT" + "A0RvZDEQMA4GA1UECxMHVGVzdGluZzEVMBMGA1UEAxMMQ0E0LVBQLjAxLjA5MIGfMA0GCS" + "qGSIb3DQEBAQUAA4GNADCBiQKBgQDR8/c35YqAswoRMgQswlTbKB9oYEzrFSC0G4dt8ydP" + "O4PyQs+J8wUVrRVMiVDTLO9rUnzR1T3iA0dqM+SvWMIA8pMWKyNV58f73ZPJIejhxMmOZa" + "sSLHceMmmMRy1zyk38i3ZJP3YhvxffTjWyTZ9k2xSDX+6KNnkiKkJSKpl6nwIDAQABo2Mw" + "YTAPBgNVHRMBAf8EBTADAQH/MA4GA1UdDwEB/wQEAwIBBjAWBgNVHSAEDzANMAsGCWCGSA" + "FlAwEwATARBgNVHQ4ECgQIpcWcVIIu63kwEwYDVR0jBAwwCoAIyppef22OmjEwDQYJKoZI" + "hvcNAQEFBQADgYEAckgV11ND/D1vfPEMUbDGUvtmsziHiSuEoDLJqSAhOmcX+evKWOfoVo" + "f7og+0ajuul7yuB+7YX1AakOw+33k++Rsgg4o+ImZq3+VScpgnIQ037OOhgH3umwFRC0r3" + "NpWqhmQuz+mHnKiK3X+IDsQOFkhnpNs06CQSZzmrzbYlQU0="; public static final String Intermediate_CRL_1_PP_01_09_crl = "MIIBSzCBtQIBATANBgkqhkiG9w0BAQUFADBeMQswCQYDVQQGEwJVUzEYMBYGA1UEChMPVS" + "5TLiBHb3Zlcm5tZW50MQwwCgYDVQQLEwNEb2QxEDAOBgNVBAsTB1Rlc3RpbmcxFTATBgNV" + "BAMTDENBMS1QUC4wMS4wORcNOTkwMTAxMTIwMTAwWhcNNDgwMTAxMTIwMTAwWqAjMCEwCg" + "YDVR0UBAMCAQEwEwYDVR0jBAwwCoAIlUTK2bh0O1YwDQYJKoZIhvcNAQEFBQADgYEAkEc6" + "qHGOWZXYTQ5fsWyJgEtuJyl8uJ+gMcikcMut5SIJTTtOz+q3wclYDevT8z1MM25kNdgwyg" + "b1bwHNAG8I72eIDtGfLrChFwU3qpvVMTG9gPYJb05Q8On56nsBu/PnnzJervzxjViaeOuv" + "kjwwfmWqGkyiK433WxzgPqE48eA="; public static final String Intermediate_CRL_2_PP_01_09_crl = "MIIBSzCBtQIBATANBgkqhkiG9w0BAQUFADBeMQswCQYDVQQGEwJVUzEYMBYGA1UEChMPVS" + "5TLiBHb3Zlcm5tZW50MQwwCgYDVQQLEwNEb2QxEDAOBgNVBAsTB1Rlc3RpbmcxFTATBgNV" + "BAMTDENBMi1QUC4wMS4wORcNOTkwMTAxMTIwMTAwWhcNNDgwMTAxMTIwMTAwWqAjMCEwCg" + "YDVR0UBAMCAQEwEwYDVR0jBAwwCoAIAyGYY3z6pegwDQYJKoZIhvcNAQEFBQADgYEAV9Md" + "8PaNoIlT7WIwnelqrbwsR66vAaT8w3gu8XDYXu+MOYThfyERUvtH6AUrHWfiRvWEzKljHH" + "3BQB0Zsa9Zz3U5cLzJcqtqDc1lH53aIA8MflrfMVrYSF684s28FikcukmA5Fw3+7S3TJ18" + "Hq7plHwTCidVD6yG35hsPwcjTrE="; public static final String Intermediate_CRL_3_PP_01_09_crl = "MIIBSzCBtQIBATANBgkqhkiG9w0BAQUFADBeMQswCQYDVQQGEwJVUzEYMBYGA1UEChMPVS" + "5TLiBHb3Zlcm5tZW50MQwwCgYDVQQLEwNEb2QxEDAOBgNVBAsTB1Rlc3RpbmcxFTATBgNV" + "BAMTDENBMy1QUC4wMS4wORcNOTkwMTAxMTIwMTAwWhcNNDgwMTAxMTIwMTAwWqAjMCEwCg" + "YDVR0UBAMCAQEwEwYDVR0jBAwwCoAIyppef22OmjEwDQYJKoZIhvcNAQEFBQADgYEAjBaP" + "V/TFQtDLxQFIBCbfqhlgpOfvJBatjNuvB0TuD2rsGS1eaLNfTfyVKlOLpxoKwKYMu36kIO" + "l/+KEPDq+ofy7uDZ6GLK3KZ/WiJyriqBQjFCvlhNTW1cjA7Ejk2lOM/A46mrUS9xC+aITh" + "d+/UYGt6O/e256cOwQCUaF2z328="; public static final String Intermediate_CRL_4_PP_01_09_crl = "MIIBSzCBtQIBATANBgkqhkiG9w0BAQUFADBeMQswCQYDVQQGEwJVUzEYMBYGA1UEChMPVS" + "5TLiBHb3Zlcm5tZW50MQwwCgYDVQQLEwNEb2QxEDAOBgNVBAsTB1Rlc3RpbmcxFTATBgNV" + "BAMTDENBNC1QUC4wMS4wORcNOTkwMTAxMTIwMTAwWhcNNDgwMTAxMTIwMTAwWqAjMCEwCg" + "YDVR0UBAMCAQEwEwYDVR0jBAwwCoAIpcWcVIIu63kwDQYJKoZIhvcNAQEFBQADgYEApZ1l" + "w5SJoU8zeKwX5jpVWiFFFomDgKsNlkkX5mF88l0B6MiYbGqJIowJRfeIlxvPOf20imN7Z8" + "l38DRXFacDQP4y5kxM420dp+ljQL5q9RsrC1+OS7I7TGgGwPoZTO4mHVk8nx9MyT+kW1OU" + "x9qRYWN0CLmP22kutYBndny222Y="; public static final String End_Certificate_PP_01_09_crt = "MIIChjCCAe+gAwIBAgIBYDANBgkqhkiG9w0BAQUFADBeMQswCQYDVQQGEwJVUzEYMBYGA1" + "UEChMPVS5TLiBHb3Zlcm5tZW50MQwwCgYDVQQLEwNEb2QxEDAOBgNVBAsTB1Rlc3Rpbmcx" + "FTATBgNVBAMTDENBNC1QUC4wMS4wOTAeFw05ODAxMDExMjAxMDBaFw00ODAxMDExMjAxMD" + "BaMGAxCzAJBgNVBAYTAlVTMRgwFgYDVQQKEw9VLlMuIEdvdmVybm1lbnQxDDAKBgNVBAsT" + "A0RvRDEQMA4GA1UECxMHVGVzdGluZzEXMBUGA1UEAxMOVXNlcjEtUFAuMDEuMDkwgZ8wDQ" + "YJKoZIhvcNAQEBBQADgY0AMIGJAoGBALiOjwwwUk1HNwf2rdzPL2okKTgL+lMdzhC7cbq3" + "6A409EY7iipPCcsDsheo9EaTNOHV9xjWDqOhqjA38h4hGNkRUVOlTW2r8SoHISn3gDXfrh" + "aHbU3owscAmt1nuA7rzo7L1eBPsisIIxAY16uAmVN5RdiAAaP8VUdshcNI4/1jAgMBAAGj" + "UjBQMA4GA1UdDwEB/wQEAwIF4DAWBgNVHSAEDzANMAsGCWCGSAFlAwEwATARBgNVHQ4ECg" + "QIGZIY3nffEXowEwYDVR0jBAwwCoAIpcWcVIIu63kwDQYJKoZIhvcNAQEFBQADgYEA0Svm" + "aqjaeQx/lnF223xlCTsU7XzOxbHetRWfeCTw0QrWQaTrKjWTS/TNyzLhGuPBFg+NTTvWML" + "gzteo/WWdF8+d2rOis9FVRCe/Euok6ZCL/xgzaE86ZSQg0jj6458TpuC2cszSaifRSlhL5" + "ogy4ADWgJxdVcBrgADo6QZXkXXw="; public static final String[] TEST_42_DATA = new String[] { Intermediate_Certificate_1_PP_01_09_crt, Intermediate_Certificate_2_PP_01_09_crt, Intermediate_Certificate_3_PP_01_09_crt, Intermediate_Certificate_4_PP_01_09_crt, Intermediate_CRL_1_PP_01_09_crl, Intermediate_CRL_2_PP_01_09_crl, Intermediate_CRL_3_PP_01_09_crl, Intermediate_CRL_4_PP_01_09_crl, End_Certificate_PP_01_09_crt }; /* * test43 * */ public static final String Intermediate_Certificate_1_PP_06_01_crt = "MIICozCCAgygAwIBAgIBYTANBgkqhkiG9w0BAQUFADBeMQswCQYDVQQGEwJVUzEYMBYGA1" + "UEChMPVS5TLiBHb3Zlcm5tZW50MQwwCgYDVQQLEwNEb0QxEDAOBgNVBAsTB1Rlc3Rpbmcx" + "FTATBgNVBAMTDFRydXN0IEFuY2hvcjAeFw05ODAxMDExMjAxMDBaFw00ODAxMDExMjAxMD" + "BaMF4xCzAJBgNVBAYTAlVTMRgwFgYDVQQKEw9VLlMuIEdvdmVybm1lbnQxDDAKBgNVBAsT" + "A0RvZDEQMA4GA1UECxMHVGVzdGluZzEVMBMGA1UEAxMMQ0ExLVBQLjA2LjAxMIGfMA0GCS" + "qGSIb3DQEBAQUAA4GNADCBiQKBgQC4mu1oBHB9BeorCFJIuSw5tszmmYBD4bjTklsAfjrz" + "OknQsYxEoHfifpdgivh1fMUk+mK5YWUz0G8/edquKbJhPBTTWp8opsGzTATsTLSEzkKbVM" + "DQ84ttxrhJWlrVRlouZTnD5HoLUvujY4EdydmKsjj6UBt/tGL5EKodymcEtwIDAQABo3Ew" + "bzAPBgNVHRMBAf8EBTADAQH/MA4GA1UdDwEB/wQEAwIBBjAWBgNVHSAEDzANMAsGCWCGSA" + "FlAwEwATAMBgNVHSQEBTADgAEKMBEGA1UdDgQKBAiGRi8YRte8PzATBgNVHSMEDDAKgAir" + "muv5wudUjzANBgkqhkiG9w0BAQUFAAOBgQDHOaIki9TogVJn54FRPl+7FyzBJ2DnR4RTM/" + "q1K3COWRdtvmGqtBBtAccxWziQJ5TnAQn1XA0cFPoCgymGPRcUz+0+C+3VhJ/m9LggVP3/" + "pjJEG0fsmJtUYPyphUlXeUzf4qSj34SlJws3DIHTR8ozAR75HZmlMRnxyZBLl+jAng=="; public static final String Intermediate_Certificate_2_PP_06_01_crt = "MIIClTCCAf6gAwIBAgIBYjANBgkqhkiG9w0BAQUFADBeMQswCQYDVQQGEwJVUzEYMBYGA1" + "UEChMPVS5TLiBHb3Zlcm5tZW50MQwwCgYDVQQLEwNEb2QxEDAOBgNVBAsTB1Rlc3Rpbmcx" + "FTATBgNVBAMTDENBMS1QUC4wNi4wMTAeFw05ODAxMDExMjAxMDBaFw00ODAxMDExMjAxMD" + "BaMF4xCzAJBgNVBAYTAlVTMRgwFgYDVQQKEw9VLlMuIEdvdmVybm1lbnQxDDAKBgNVBAsT" + "A0RvZDEQMA4GA1UECxMHVGVzdGluZzEVMBMGA1UEAxMMQ0EyLVBQLjA2LjAxMIGfMA0GCS" + "qGSIb3DQEBAQUAA4GNADCBiQKBgQC2rptuREzhGfEJ3U8ILPBq+z0s+aafMvBRHpqkipDq" + "bC7v9zpwg1K18F4MYiATpPAEfdEeprKs0mWfdusF93BoMBVm1y0zRgDRUNdyB5GFO8g8+2" + "yNEO6L37c1PwrMLnvJakaqwbbnwlcMcKtLHoX19fyveQQg5DNj8WcKZj397wIDAQABo2Mw" + "YTAPBgNVHRMBAf8EBTADAQH/MA4GA1UdDwEB/wQEAwIBBjAWBgNVHSAEDzANMAsGCWCGSA" + "FlAwEwATARBgNVHQ4ECgQIJPt6qKdFeYEwEwYDVR0jBAwwCoAIhkYvGEbXvD8wDQYJKoZI" + "hvcNAQEFBQADgYEAkFJGNze9/6YX7Rv8FR9obFGACIJ7Om4YQQRW9WM9pEDgKls7g9b9El" + "dJxLKOlWoRoYZIrbEam19traE2O3dxqRevPoYvfAqkR089BkxH/cFYyfqw64IpjDG84dsY" + "XieajI/Ov/HjgF0VQKF3+Y1ZiDjb2OHNgMkqs9VmUHaE+94="; public static final String Intermediate_Certificate_3_PP_06_01_crt = "MIIClTCCAf6gAwIBAgIBYzANBgkqhkiG9w0BAQUFADBeMQswCQYDVQQGEwJVUzEYMBYGA1" + "UEChMPVS5TLiBHb3Zlcm5tZW50MQwwCgYDVQQLEwNEb2QxEDAOBgNVBAsTB1Rlc3Rpbmcx" + "FTATBgNVBAMTDENBMi1QUC4wNi4wMTAeFw05ODAxMDExMjAxMDBaFw00ODAxMDExMjAxMD" + "BaMF4xCzAJBgNVBAYTAlVTMRgwFgYDVQQKEw9VLlMuIEdvdmVybm1lbnQxDDAKBgNVBAsT" + "A0RvZDEQMA4GA1UECxMHVGVzdGluZzEVMBMGA1UEAxMMQ0EzLVBQLjA2LjAxMIGfMA0GCS" + "qGSIb3DQEBAQUAA4GNADCBiQKBgQCzxfyi52gw/5tt6/9aNAXdY3wZYH1GifzGoN4cg8Mt" + "++5xmTdrc2A9/5biaTUVC0x/Ml6mm940NA9mM/EoEu4SdnP2crNCIFHWNlYz3cJtYJ68rE" + "rEU+S0gnYaYRiwNGhVpAjV+FPDr0Ghgp5rYQ61evAhmRuNAFwYocUw80G6JQIDAQABo2Mw" + "YTAPBgNVHRMBAf8EBTADAQH/MA4GA1UdDwEB/wQEAwIBBjAWBgNVHSAEDzANMAsGCWCGSA" + "FlAwEwATARBgNVHQ4ECgQIZ9yMlboxCIEwEwYDVR0jBAwwCoAIJPt6qKdFeYEwDQYJKoZI" + "hvcNAQEFBQADgYEATNnRMQmvTxRcSMUL4pa5bejuX2Ixy/OfZIAlJWt9AfLW2tHmdAaGpD" + "GhTHKfyQQ+HrIMQ+lXau8Yu6nzWXAY8pKpKD1Hbd355VE4dYZ7aPvcAulZHeV0F2EFn09x" + "qQ1frHDRoCOc11B5qV5hnwgDE/ByZh1+OWUcR4tBQKyEF4g="; public static final String Intermediate_Certificate_4_PP_06_01_crt = "MIIClTCCAf6gAwIBAgIBZDANBgkqhkiG9w0BAQUFADBeMQswCQYDVQQGEwJVUzEYMBYGA1" + "UEChMPVS5TLiBHb3Zlcm5tZW50MQwwCgYDVQQLEwNEb2QxEDAOBgNVBAsTB1Rlc3Rpbmcx" + "FTATBgNVBAMTDENBMy1QUC4wNi4wMTAeFw05ODAxMDExMjAxMDBaFw00ODAxMDExMjAxMD" + "BaMF4xCzAJBgNVBAYTAlVTMRgwFgYDVQQKEw9VLlMuIEdvdmVybm1lbnQxDDAKBgNVBAsT" + "A0RvZDEQMA4GA1UECxMHVGVzdGluZzEVMBMGA1UEAxMMQ0E0LVBQLjA2LjAxMIGfMA0GCS" + "qGSIb3DQEBAQUAA4GNADCBiQKBgQDB66hLZx1WGcCqmOxHK/rotXOpccJQOB2L3kpWP1M2" + "ZiWufUguLw45XShdqu31OgmGw0/w9ugwy96aRL+Tiluj4xjIAxJCav5cXF8Dt2Ex7hjIHm" + "XV0rHbJUiduHEh3fQphgtzlR4QxG6i/i4SbcsoJzsws8x3qOqRPaWDtyWs0QIDAQABo2Mw" + "YTAPBgNVHRMBAf8EBTADAQH/MA4GA1UdDwEB/wQEAwIBBjAWBgNVHSAEDzANMAsGCWCGSA" + "FlAwEwATARBgNVHQ4ECgQIyZsLNvyyIZEwEwYDVR0jBAwwCoAIZ9yMlboxCIEwDQYJKoZI" + "hvcNAQEFBQADgYEAc7G4BAUsQeqNp/Kv8TKJckfxWygz54PrkBICNw/eGuGamVJMRkYCP3" + "yJ8NW4jY/rfxzKKyjVB09XuNBLDwYdR5Z5UHSg6Ijes3j8tehZ+9DwEQrR+WQf/adHIsxn" + "/347MHrSQF7CJzE9tAu6AOu53lKxLeH6C/5YI611or2Ql1I="; public static final String Intermediate_CRL_1_PP_06_01_crl = "MIIBSzCBtQIBATANBgkqhkiG9w0BAQUFADBeMQswCQYDVQQGEwJVUzEYMBYGA1UEChMPVS" + "5TLiBHb3Zlcm5tZW50MQwwCgYDVQQLEwNEb2QxEDAOBgNVBAsTB1Rlc3RpbmcxFTATBgNV" + "BAMTDENBMS1QUC4wNi4wMRcNOTkwMTAxMTIwMTAwWhcNNDgwMTAxMTIwMTAwWqAjMCEwCg" + "YDVR0UBAMCAQEwEwYDVR0jBAwwCoAIhkYvGEbXvD8wDQYJKoZIhvcNAQEFBQADgYEAC7ev" + "Pqe0veUX+zF51d/NiG6VwgEwOP1HlzD/saDn/FYXStTQDwoIyFjmZ9z0yLGIaVI1O9BWVD" + "CTU3bCU1dBg61Blo3rI3TlNqmGrYRUSJ857QM9c/G+/+V0XJ/HgId39Pufd9Tob150XNMs" + "9h0PvqjhYjG1bARMRa8JB4KTBU4="; public static final String Intermediate_CRL_2_PP_06_01_crl = "MIIBSzCBtQIBATANBgkqhkiG9w0BAQUFADBeMQswCQYDVQQGEwJVUzEYMBYGA1UEChMPVS" + "5TLiBHb3Zlcm5tZW50MQwwCgYDVQQLEwNEb2QxEDAOBgNVBAsTB1Rlc3RpbmcxFTATBgNV" + "BAMTDENBMi1QUC4wNi4wMRcNOTkwMTAxMTIwMTAwWhcNNDgwMTAxMTIwMTAwWqAjMCEwCg" + "YDVR0UBAMCAQEwEwYDVR0jBAwwCoAIJPt6qKdFeYEwDQYJKoZIhvcNAQEFBQADgYEAiUbi" + "qQ3X/hTgjhpQGDZi/7EnZcqSgiAFMreV30/mav2NtXDITE9DqZzCS9x1vHBp4BBsQwYVvp" + "XvLVSgns4pFwR+0Whc+tPo2j9ScePq3sICsqleWTN1DvuoP9rBe8w7pDN4guA59Kbeku75" + "5CMA5YjiTUomK4UaqI3htwkBlWo="; public static final String Intermediate_CRL_3_PP_06_01_crl = "MIIBSzCBtQIBATANBgkqhkiG9w0BAQUFADBeMQswCQYDVQQGEwJVUzEYMBYGA1UEChMPVS" + "5TLiBHb3Zlcm5tZW50MQwwCgYDVQQLEwNEb2QxEDAOBgNVBAsTB1Rlc3RpbmcxFTATBgNV" + "BAMTDENBMy1QUC4wNi4wMRcNOTkwMTAxMTIwMTAwWhcNNDgwMTAxMTIwMTAwWqAjMCEwCg" + "YDVR0UBAMCAQEwEwYDVR0jBAwwCoAIZ9yMlboxCIEwDQYJKoZIhvcNAQEFBQADgYEANowv" + "f/scWT6FFT393XEpWcTnA18hBT5Nkddw6mHjKBq7ndtBQkydMO8Wym1IeQ2qYbAqu3ifNZ" + "SKF3PfgJjYPBKImzJdHTKfcclMC5H8Y9JDN0voeyONr9NiXcoj+p24YNYjb+PFI6avRYo7" + "Xyrqvwnvng/IY9zLtc7SYYUIODk="; public static final String Intermediate_CRL_4_PP_06_01_crl = "MIIBSzCBtQIBATANBgkqhkiG9w0BAQUFADBeMQswCQYDVQQGEwJVUzEYMBYGA1UEChMPVS" + "5TLiBHb3Zlcm5tZW50MQwwCgYDVQQLEwNEb2QxEDAOBgNVBAsTB1Rlc3RpbmcxFTATBgNV" + "BAMTDENBNC1QUC4wNi4wMRcNOTkwMTAxMTIwMTAwWhcNNDgwMTAxMTIwMTAwWqAjMCEwCg" + "YDVR0UBAMCAQEwEwYDVR0jBAwwCoAIyZsLNvyyIZEwDQYJKoZIhvcNAQEFBQADgYEAsnA9" + "ERwsi2mK540oPL45mLdOjGnet7+HhNk14q0hvALTYGB1vEjijc+Yvf6mHJGRbiG207BpJ1" + "DWeWBY8TLe4YJXlSrWwx1jD46rCt7gdqXAdLpMo+i35yfQ19ZqeWcRLkspmczoUJLJaJza" + "eLRrnjv62GLJ09KVKpZBGhV3SUM="; public static final String End_Certificate_PP_06_01_crt = "MIICbjCCAdegAwIBAgIBZTANBgkqhkiG9w0BAQUFADBeMQswCQYDVQQGEwJVUzEYMBYGA1" + "UEChMPVS5TLiBHb3Zlcm5tZW50MQwwCgYDVQQLEwNEb2QxEDAOBgNVBAsTB1Rlc3Rpbmcx" + "FTATBgNVBAMTDENBNC1QUC4wNi4wMTAeFw05ODAxMDExMjAxMDBaFw00ODAxMDExMjAxMD" + "BaMGAxCzAJBgNVBAYTAlVTMRgwFgYDVQQKEw9VLlMuIEdvdmVybm1lbnQxDDAKBgNVBAsT" + "A0RvRDEQMA4GA1UECxMHVGVzdGluZzEXMBUGA1UEAxMOVXNlcjEtUFAuMDYuMDEwgZ8wDQ" + "YJKoZIhvcNAQEBBQADgY0AMIGJAoGBAKrLB7XA0PKY0qtSC5lMBvvIvbyjBM8XmANrN9Wx" + "66QxEuloRAz0D5uAu7TnJBv6qNuIPGFl74yusKCSkjEkBMdVpBCfDvpG1/Tz3sALSlxmnz" + "xbK2ytOncbYuYrzvXttx6wkhLrBLlnfuwpZwGZOr/Pt6WwQJWjXxgTNJ6dcgXbAgMBAAGj" + "OjA4MA4GA1UdDwEB/wQEAwIF4DARBgNVHQ4ECgQIv0gg7LxDM+swEwYDVR0jBAwwCoAIyZ" + "sLNvyyIZEwDQYJKoZIhvcNAQEFBQADgYEAgzlxBGGOBvHw20eOzSswMqrHopNMcvwuEO+Z" + "Mr0h8U2/HIiRqKWQaxMyM8A0oULGJny3B/0WtkfVQ2EIibZGiKIjC1RPAB3QmL0vgSyUmF" + "s/LZbzugpJW6jvfov7N4O+u0J5rYniRxa4bgrXa89TY9kwDMbr6/z4oiI8bq3gEsw="; public static final String[] TEST_43_DATA = new String[] { Intermediate_Certificate_1_PP_06_01_crt, Intermediate_Certificate_2_PP_06_01_crt, Intermediate_Certificate_3_PP_06_01_crt, Intermediate_Certificate_4_PP_06_01_crt, Intermediate_CRL_1_PP_06_01_crl, Intermediate_CRL_2_PP_06_01_crl, Intermediate_CRL_3_PP_06_01_crl, Intermediate_CRL_4_PP_06_01_crl, End_Certificate_PP_06_01_crt }; /* * test44 * */ public static final String Intermediate_Certificate_1_PP_06_02_crt = "MIICozCCAgygAwIBAgIBZjANBgkqhkiG9w0BAQUFADBeMQswCQYDVQQGEwJVUzEYMBYGA1" + "UEChMPVS5TLiBHb3Zlcm5tZW50MQwwCgYDVQQLEwNEb0QxEDAOBgNVBAsTB1Rlc3Rpbmcx" + "FTATBgNVBAMTDFRydXN0IEFuY2hvcjAeFw05ODAxMDExMjAxMDBaFw00ODAxMDExMjAxMD" + "BaMF4xCzAJBgNVBAYTAlVTMRgwFgYDVQQKEw9VLlMuIEdvdmVybm1lbnQxDDAKBgNVBAsT" + "A0RvZDEQMA4GA1UECxMHVGVzdGluZzEVMBMGA1UEAxMMQ0ExLVBQLjA2LjAyMIGfMA0GCS" + "qGSIb3DQEBAQUAA4GNADCBiQKBgQDjg5+XWZwW1gLAOldsRshbCXmUCmt1Vs+oZsvyH+6d" + "2PwKs8ydrz+oD0/D8V7cRXucj7q7cJSLhEY1wJoTTgrWeRg1hQioAXzPW3ZkaZuzhpi+cC" + "qeZzN5nPvqK18GWvpffNbUUVfOuaHzzHmhmhgQyZaNG7JHwpWM10UMzMawOwIDAQABo3Ew" + "bzAPBgNVHRMBAf8EBTADAQH/MA4GA1UdDwEB/wQEAwIBBjAWBgNVHSAEDzANMAsGCWCGSA" + "FlAwEwATAMBgNVHSQEBTADgAEFMBEGA1UdDgQKBAh5am+tkndt5zATBgNVHSMEDDAKgAir" + "muv5wudUjzANBgkqhkiG9w0BAQUFAAOBgQAF0h1iaxxZUp43AjP5gSvbW6JfFRW/ugH9SU" + "n3e1B29LMH3F/ML0joVhPx5CIVpX4nfaYzdeje9+E2/bHMBGSCFeHz9S/KoBLLiI0GNhzh" + "I6MytvPMPRx7hkuROouQ69TnslJiGCcoo+MD0fA2YwO1bCtyLdeVHYhJZWQ2Sg8PHQ=="; public static final String Intermediate_Certificate_2_PP_06_02_crt = "MIIClTCCAf6gAwIBAgIBZzANBgkqhkiG9w0BAQUFADBeMQswCQYDVQQGEwJVUzEYMBYGA1" + "UEChMPVS5TLiBHb3Zlcm5tZW50MQwwCgYDVQQLEwNEb2QxEDAOBgNVBAsTB1Rlc3Rpbmcx" + "FTATBgNVBAMTDENBMS1QUC4wNi4wMjAeFw05ODAxMDExMjAxMDBaFw00ODAxMDExMjAxMD" + "BaMF4xCzAJBgNVBAYTAlVTMRgwFgYDVQQKEw9VLlMuIEdvdmVybm1lbnQxDDAKBgNVBAsT" + "A0RvZDEQMA4GA1UECxMHVGVzdGluZzEVMBMGA1UEAxMMQ0EyLVBQLjA2LjAyMIGfMA0GCS" + "qGSIb3DQEBAQUAA4GNADCBiQKBgQDF4KSKxo8HvQ59E77LcuLpZ7ujNDjb30KB+EbIuRmy" + "khXAkhq2Rp2Iqd3OhC0AXmhSF+enJq3h0dqyxNWP08SIuK5ia3OIeatl1UgEyukuAnrLuI" + "A7PFUQAGZmDG4OuHv28zza4n/SwfCaKfi8qatIwpwF/29ycB8wYBrHThQD0wIDAQABo2Mw" + "YTAPBgNVHRMBAf8EBTADAQH/MA4GA1UdDwEB/wQEAwIBBjAWBgNVHSAEDzANMAsGCWCGSA" + "FlAwEwATARBgNVHQ4ECgQIKFZV4vjfOOQwEwYDVR0jBAwwCoAIeWpvrZJ3becwDQYJKoZI" + "hvcNAQEFBQADgYEAuj8P5ga8Xv9eFjk4AdRMx/Fj/doRAOLZfs+OnrduRXPLe7CFKDxhFx" + "xYOma8In08cgXVVnRR+2nZ54h5qjCYpskGNx+yZRY8+HW3XXE3KpS7QgTnc/1XshUy9VGm" + "2qX0k661f2d3KnSKiKVKtM/y/j/nNyxPugDz1Yy50NtzQOE="; public static final String Intermediate_Certificate_3_PP_06_02_crt = "MIIClTCCAf6gAwIBAgIBaDANBgkqhkiG9w0BAQUFADBeMQswCQYDVQQGEwJVUzEYMBYGA1" + "UEChMPVS5TLiBHb3Zlcm5tZW50MQwwCgYDVQQLEwNEb2QxEDAOBgNVBAsTB1Rlc3Rpbmcx" + "FTATBgNVBAMTDENBMi1QUC4wNi4wMjAeFw05ODAxMDExMjAxMDBaFw00ODAxMDExMjAxMD" + "BaMF4xCzAJBgNVBAYTAlVTMRgwFgYDVQQKEw9VLlMuIEdvdmVybm1lbnQxDDAKBgNVBAsT" + "A0RvZDEQMA4GA1UECxMHVGVzdGluZzEVMBMGA1UEAxMMQ0EzLVBQLjA2LjAyMIGfMA0GCS" + "qGSIb3DQEBAQUAA4GNADCBiQKBgQCitrzXkbO4hAQpBRQE880MFBPq84umX9pyKbV3iMqK" + "Z7HBYwZOvEwGQxG+TX1PIj0Jz27oyvoqpLeMkbn9L3K0BuS0AZKlWIOGPPHWpYTDoQCCs9" + "Mba1evVT/1CMxESsv2kgf49YHMs/6TtxQX0qj5TQzXrkM6CMBc5zyPBDWORQIDAQABo2Mw" + "YTAPBgNVHRMBAf8EBTADAQH/MA4GA1UdDwEB/wQEAwIBBjAWBgNVHSAEDzANMAsGCWCGSA" + "FlAwEwATARBgNVHQ4ECgQIxLES0WIVZQYwEwYDVR0jBAwwCoAIKFZV4vjfOOQwDQYJKoZI" + "hvcNAQEFBQADgYEAdQeDAOFys//2xUFwBilhqr32/jh4gT/ijxRjG0msKTYXmWcCQv9Tms" + "smtIMtiwwnByhjTdQAtOmEyDm/CFW0/NBnxlRvqZKt+PRtscpExVy7xnnm2MBITTa+9xkC" + "A361jSDPnRPEOZoKdMRRzNnW4f59m0huibeFNRYJ7y8BnHs="; public static final String Intermediate_Certificate_4_PP_06_02_crt = "MIIClTCCAf6gAwIBAgIBaTANBgkqhkiG9w0BAQUFADBeMQswCQYDVQQGEwJVUzEYMBYGA1" + "UEChMPVS5TLiBHb3Zlcm5tZW50MQwwCgYDVQQLEwNEb2QxEDAOBgNVBAsTB1Rlc3Rpbmcx" + "FTATBgNVBAMTDENBMy1QUC4wNi4wMjAeFw05ODAxMDExMjAxMDBaFw00ODAxMDExMjAxMD" + "BaMF4xCzAJBgNVBAYTAlVTMRgwFgYDVQQKEw9VLlMuIEdvdmVybm1lbnQxDDAKBgNVBAsT" + "A0RvZDEQMA4GA1UECxMHVGVzdGluZzEVMBMGA1UEAxMMQ0E0LVBQLjA2LjAyMIGfMA0GCS" + "qGSIb3DQEBAQUAA4GNADCBiQKBgQCg0yQG7oewLD2eFfPuj2DPBgT47iEri2IVeS/r5hUD" + "nZhxzT2/+UsQfiS+ufdC2Xq+QAcXFcAifPbvRs9xo2q0uLz26mwSq1TH8ilHLKatKwJ/Yf" + "hcRAfEWDwhLJGRhZ7YrKu8xczZgyxwaeu5m38lEaLIRyaVfVSrw8WhN4z4ewIDAQABo2Mw" + "YTAPBgNVHRMBAf8EBTADAQH/MA4GA1UdDwEB/wQEAwIBBjAWBgNVHSAEDzANMAsGCWCGSA" + "FlAwEwATARBgNVHQ4ECgQI/dKmuI1u6I0wEwYDVR0jBAwwCoAIxLES0WIVZQYwDQYJKoZI" + "hvcNAQEFBQADgYEAOEcMpdSAVKUzQ1A7LJnWOh5Tul6yXw6qMsdZNGOZ3vYBXH3vHnSHvp" + "MqJQ1JIX/4XSiKF8En5dVI/ooNabgyORpPnLGDvrshvO/09iaDlQXxWRsoGAFhcIe7Ibp+" + "3g6hnBO5U+0pbInioKVYf/1VyZSUK1QQMutshMIye/8gyZw="; public static final String Intermediate_CRL_1_PP_06_02_crl = "MIIBSzCBtQIBATANBgkqhkiG9w0BAQUFADBeMQswCQYDVQQGEwJVUzEYMBYGA1UEChMPVS" + "5TLiBHb3Zlcm5tZW50MQwwCgYDVQQLEwNEb2QxEDAOBgNVBAsTB1Rlc3RpbmcxFTATBgNV" + "BAMTDENBMS1QUC4wNi4wMhcNOTkwMTAxMTIwMTAwWhcNNDgwMTAxMTIwMTAwWqAjMCEwCg" + "YDVR0UBAMCAQEwEwYDVR0jBAwwCoAIeWpvrZJ3becwDQYJKoZIhvcNAQEFBQADgYEAEJ28" + "g5iyw3ZOqs5ly7O2X0YWtgKK3BnPztxygCUWO1xVy/QbMM5ybAU/UPbJC2pUnkOZMX+h30" + "RYp/kV9w2o15V1hxj2M0tR8fQ0WXudwi20pZO56uHb+WSaETOmPVoNH5efeXsTvtbHQR5w" + "95L2vNeEzJEy1l7S/sasUUoQvqY="; public static final String Intermediate_CRL_2_PP_06_02_crl = "MIIBSzCBtQIBATANBgkqhkiG9w0BAQUFADBeMQswCQYDVQQGEwJVUzEYMBYGA1UEChMPVS" + "5TLiBHb3Zlcm5tZW50MQwwCgYDVQQLEwNEb2QxEDAOBgNVBAsTB1Rlc3RpbmcxFTATBgNV" + "BAMTDENBMi1QUC4wNi4wMhcNOTkwMTAxMTIwMTAwWhcNNDgwMTAxMTIwMTAwWqAjMCEwCg" + "YDVR0UBAMCAQEwEwYDVR0jBAwwCoAIKFZV4vjfOOQwDQYJKoZIhvcNAQEFBQADgYEApLIK" + "X/YJYhSfn7yLTAlKjnhpH1QDlFeaE6/+uj6j7ZgpK6HBjHOvfwbrjurl+L3ZTLrY1FCL4/" + "SUgXrJxbAyMANlg4Z8u6o73F9cur2gi3sgv5d6FjJ8VwuKYWY2dwZNeXwlWE/W0h01Vd9H" + "QVuctFxzQaJQdQBadw/XqzvLlyw="; public static final String Intermediate_CRL_3_PP_06_02_crl = "MIIBSzCBtQIBATANBgkqhkiG9w0BAQUFADBeMQswCQYDVQQGEwJVUzEYMBYGA1UEChMPVS" + "5TLiBHb3Zlcm5tZW50MQwwCgYDVQQLEwNEb2QxEDAOBgNVBAsTB1Rlc3RpbmcxFTATBgNV" + "BAMTDENBMy1QUC4wNi4wMhcNOTkwMTAxMTIwMTAwWhcNNDgwMTAxMTIwMTAwWqAjMCEwCg" + "YDVR0UBAMCAQEwEwYDVR0jBAwwCoAIxLES0WIVZQYwDQYJKoZIhvcNAQEFBQADgYEAE5J9" + "wJKAb3veF4GhHeoIgy6JvMsrjv7d7dhT+ZIKq+wPNk1909X/Zo1GXxJSjMaMgkLlXa0QN6" + "LtSJxbyMRCKSJfqTKOezFXirZ7MEQ04FT0z6Hp0m+E2Q7dGs52ZOV3YZBhQUlH+aQ8WNu2" + "6clf4VqBiUYgGhkE95PhN5AAnOU="; public static final String Intermediate_CRL_4_PP_06_02_crl = "MIIBSzCBtQIBATANBgkqhkiG9w0BAQUFADBeMQswCQYDVQQGEwJVUzEYMBYGA1UEChMPVS" + "5TLiBHb3Zlcm5tZW50MQwwCgYDVQQLEwNEb2QxEDAOBgNVBAsTB1Rlc3RpbmcxFTATBgNV" + "BAMTDENBNC1QUC4wNi4wMhcNOTkwMTAxMTIwMTAwWhcNNDgwMTAxMTIwMTAwWqAjMCEwCg" + "YDVR0UBAMCAQEwEwYDVR0jBAwwCoAI/dKmuI1u6I0wDQYJKoZIhvcNAQEFBQADgYEAKgk1" + "HJ7OW203z9H7jNGxoLCN9bGDKOFcWlWuruzXWOAn+AomjSZpqZkZU1qyKrFaKM320sfn8C" + "ZJPnVWaVMLBLNddDRWUjJrUHtNdnnZEuYPYlRVb0MmwaxHHR0ZBUIaniqoLuvtQIB9N++T" + "bu4cjx33mN6MX0oWr4Bbq7ovPnE="; public static final String End_Certificate_PP_06_02_crt = "MIICbjCCAdegAwIBAgIBajANBgkqhkiG9w0BAQUFADBeMQswCQYDVQQGEwJVUzEYMBYGA1" + "UEChMPVS5TLiBHb3Zlcm5tZW50MQwwCgYDVQQLEwNEb2QxEDAOBgNVBAsTB1Rlc3Rpbmcx" + "FTATBgNVBAMTDENBNC1QUC4wNi4wMjAeFw05ODAxMDExMjAxMDBaFw00ODAxMDExMjAxMD" + "BaMGAxCzAJBgNVBAYTAlVTMRgwFgYDVQQKEw9VLlMuIEdvdmVybm1lbnQxDDAKBgNVBAsT" + "A0RvRDEQMA4GA1UECxMHVGVzdGluZzEXMBUGA1UEAxMOVXNlcjEtUFAuMDYuMDIwgZ8wDQ" + "YJKoZIhvcNAQEBBQADgY0AMIGJAoGBANAr4hFku3Y6jI+vD6JTRFc7ZLL9tIxT7Mq+QcDd" + "rRHgSEXhPL3MM//3ZFXca3w4rXOUVQyANQncywNM3uwl7T9jC0MD2kJ9PsNGQL2bQcSajX" + "jrxT403PVFsa6ZrLMU0hwomSO4nJBLCJj3i1rlX9esYbRNCqzep2OMWgAWRUsrAgMBAAGj" + "OjA4MA4GA1UdDwEB/wQEAwIF4DARBgNVHQ4ECgQIMBvQP4Q8w2UwEwYDVR0jBAwwCoAI/d" + "KmuI1u6I0wDQYJKoZIhvcNAQEFBQADgYEAnmNf+3jJp4mo4YDznASTMnrBBdXuskhnRXSQ" + "Gj5dNq6PxEXM+CmBhaNlnFYcr7UCtcD8XwampfyO52tvAZW5kWQKsxyowVtsxtwkAtj6/f" + "trIeulIM0B1xjyXJshmVST5u6gZ3OegsAyuqyAbo9B1IvkNFOldt624aEG43jq7ho="; public static final String[] TEST_44_DATA = new String[] { Intermediate_Certificate_1_PP_06_02_crt, Intermediate_Certificate_2_PP_06_02_crt, Intermediate_Certificate_3_PP_06_02_crt, Intermediate_Certificate_4_PP_06_02_crt, Intermediate_CRL_1_PP_06_02_crl, Intermediate_CRL_2_PP_06_02_crl, Intermediate_CRL_3_PP_06_02_crl, Intermediate_CRL_4_PP_06_02_crl, End_Certificate_PP_06_02_crt }; /* * test45 * */ public static final String Intermediate_Certificate_1_PP_06_03_crt = "MIICozCCAgygAwIBAgIBazANBgkqhkiG9w0BAQUFADBeMQswCQYDVQQGEwJVUzEYMBYGA1" + "UEChMPVS5TLiBHb3Zlcm5tZW50MQwwCgYDVQQLEwNEb0QxEDAOBgNVBAsTB1Rlc3Rpbmcx" + "FTATBgNVBAMTDFRydXN0IEFuY2hvcjAeFw05ODAxMDExMjAxMDBaFw00ODAxMDExMjAxMD" + "BaMF4xCzAJBgNVBAYTAlVTMRgwFgYDVQQKEw9VLlMuIEdvdmVybm1lbnQxDDAKBgNVBAsT" + "A0RvZDEQMA4GA1UECxMHVGVzdGluZzEVMBMGA1UEAxMMQ0ExLVBQLjA2LjAzMIGfMA0GCS" + "qGSIb3DQEBAQUAA4GNADCBiQKBgQCrUMqMxZ4sSrH6sKv2y6nYKagLvUHaforCnf4z/5O1" + "PeldaW4ANtNPA8SkVBES/zoKgvrLJUmqRi4b+BGhCVqLU77PvWyiPOS40tpJfw7m9pPK53" + "aeaLC9M6rarjdOvF8MkdtytCMU/Ef1NsuJULwEP+XB90k4lHr9EzbgKhXvoQIDAQABo3Ew" + "bzAPBgNVHRMBAf8EBTADAQH/MA4GA1UdDwEB/wQEAwIBBjAWBgNVHSAEDzANMAsGCWCGSA" + "FlAwEwATAMBgNVHSQEBTADgAEEMBEGA1UdDgQKBAhF0iXZmlIKsTATBgNVHSMEDDAKgAir" + "muv5wudUjzANBgkqhkiG9w0BAQUFAAOBgQCmab7noekyx5TzxAqWoQiC9S/aZJtvLkuH1p" + "KiZnclMpRvIL1CVOukkzLTZXY0EcCHnXuVGjw+9vmiQWGGw8t6TGCXo/CtCo934HGBxOfQ" + "MVysEjst7L7TDQsqxk4j9O8cU/TFWsghW9Ihu7SVIn8RJmknKMB2xkIhcDe8S8dmxw=="; public static final String Intermediate_Certificate_2_PP_06_03_crt = "MIIClTCCAf6gAwIBAgIBbDANBgkqhkiG9w0BAQUFADBeMQswCQYDVQQGEwJVUzEYMBYGA1" + "UEChMPVS5TLiBHb3Zlcm5tZW50MQwwCgYDVQQLEwNEb2QxEDAOBgNVBAsTB1Rlc3Rpbmcx" + "FTATBgNVBAMTDENBMS1QUC4wNi4wMzAeFw05ODAxMDExMjAxMDBaFw00ODAxMDExMjAxMD" + "BaMF4xCzAJBgNVBAYTAlVTMRgwFgYDVQQKEw9VLlMuIEdvdmVybm1lbnQxDDAKBgNVBAsT" + "A0RvZDEQMA4GA1UECxMHVGVzdGluZzEVMBMGA1UEAxMMQ0EyLVBQLjA2LjAzMIGfMA0GCS" + "qGSIb3DQEBAQUAA4GNADCBiQKBgQCmT7wL9WwWBr1oY9bHIq4IrJOkbOARK3zOeyZSbBBB" + "zxcky5kjC9pamMpyZjga+q0CGd2rq9eUjQ2FXZsBSgf/X9B0/g9trNMebYgGnYmHHX2JK+" + "doyAX+h3afDbZzZ696S0Hw7yRx00+teQe/Gx4h4qKPwbJIW5Bep9SBysikJQIDAQABo2Mw" + "YTAPBgNVHRMBAf8EBTADAQH/MA4GA1UdDwEB/wQEAwIBBjAWBgNVHSAEDzANMAsGCWCGSA" + "FlAwEwATARBgNVHQ4ECgQInXHgY/+onu4wEwYDVR0jBAwwCoAIRdIl2ZpSCrEwDQYJKoZI" + "hvcNAQEFBQADgYEAhlboR5gzYWluWIaFM5R1Ko0/rprrv5BHONRiXjLfAPkzZmd7FLDE2j" + "BlU7s7IenICeST4c7HG5zqBigK1814GG75nq5htCGUnM6pn8/gvc58+ckKeWgbJxC5I/0u" + "olCCs8ORbWIEGWmghGg1USxeI1RQwXGgE8XwtabVibJOVBk="; public static final String Intermediate_Certificate_3_PP_06_03_crt = "MIIClTCCAf6gAwIBAgIBbTANBgkqhkiG9w0BAQUFADBeMQswCQYDVQQGEwJVUzEYMBYGA1" + "UEChMPVS5TLiBHb3Zlcm5tZW50MQwwCgYDVQQLEwNEb2QxEDAOBgNVBAsTB1Rlc3Rpbmcx" + "FTATBgNVBAMTDENBMi1QUC4wNi4wMzAeFw05ODAxMDExMjAxMDBaFw00ODAxMDExMjAxMD" + "BaMF4xCzAJBgNVBAYTAlVTMRgwFgYDVQQKEw9VLlMuIEdvdmVybm1lbnQxDDAKBgNVBAsT" + "A0RvZDEQMA4GA1UECxMHVGVzdGluZzEVMBMGA1UEAxMMQ0EzLVBQLjA2LjAzMIGfMA0GCS" + "qGSIb3DQEBAQUAA4GNADCBiQKBgQDEouRlqTFQiJQSwc+yhjpvA0dUIbRrNwLF+EPfUWq0" + "FV1UV0a5lb5BGPW4RGUEbFwsgGCHsfLiY7WmUpC1e6332PZPnrnoJbf28paeiZ8KqcAKZE" + "pGPWKCmFBwBW23q1w/v/CxcXJoBx5OC1yxG3fGH7CZSzc+4Z/+PxLk9yoASwIDAQABo2Mw" + "YTAPBgNVHRMBAf8EBTADAQH/MA4GA1UdDwEB/wQEAwIBBjAWBgNVHSAEDzANMAsGCWCGSA" + "FlAwEwATARBgNVHQ4ECgQIc24GzUM6/LswEwYDVR0jBAwwCoAInXHgY/+onu4wDQYJKoZI" + "hvcNAQEFBQADgYEANLxcLvJqjyu94HN+X6tTxGcN1s43kQh8yRGotW2ptuA2jmGlAhI8QQ" + "sXHO0o0bFLBC/Uv0L0YlEJhK1w0ct7Awwn4UYgqupxug2f84yamcvFa1es3osIMJoi0GPz" + "1WDBM711efRtbzvK6t/4fJ01nG2BlMeEbctVqrehuAip4p4="; public static final String Intermediate_Certificate_4_PP_06_03_crt = "MIIClTCCAf6gAwIBAgIBbjANBgkqhkiG9w0BAQUFADBeMQswCQYDVQQGEwJVUzEYMBYGA1" + "UEChMPVS5TLiBHb3Zlcm5tZW50MQwwCgYDVQQLEwNEb2QxEDAOBgNVBAsTB1Rlc3Rpbmcx" + "FTATBgNVBAMTDENBMy1QUC4wNi4wMzAeFw05ODAxMDExMjAxMDBaFw00ODAxMDExMjAxMD" + "BaMF4xCzAJBgNVBAYTAlVTMRgwFgYDVQQKEw9VLlMuIEdvdmVybm1lbnQxDDAKBgNVBAsT" + "A0RvZDEQMA4GA1UECxMHVGVzdGluZzEVMBMGA1UEAxMMQ0E0LVBQLjA2LjAzMIGfMA0GCS" + "qGSIb3DQEBAQUAA4GNADCBiQKBgQDNuzSN3BiT84M3Dy6KeTQkMqWNuYGTENWPP8WvQ0Ot" + "ggue/lemC+IqYBtIEYtk3A30eKKnF28WIbPlB3oSykrPVV5dMhYGF9ysOtp4wyETHtzdv0" + "7HyqlMHOCPiFplbwjUSo0uEIRVgS3luBJi9onTpcn97/i0S7VsM2nooooaowIDAQABo2Mw" + "YTAPBgNVHRMBAf8EBTADAQH/MA4GA1UdDwEB/wQEAwIBBjAWBgNVHSAEDzANMAsGCWCGSA" + "FlAwEwATARBgNVHQ4ECgQIDjpr8w0dRq0wEwYDVR0jBAwwCoAIc24GzUM6/LswDQYJKoZI" + "hvcNAQEFBQADgYEArE6qUMnjXiB5eKiAFc9Elw1dYsQArtnDQAfFGtShDulxYKq9+pxory" + "4kTMUZZCJc7awEC11tdJp7xJGcpjCJl4I2wBcHiCcVcnwQijqM719PqoQKydXB9MSrXqmU" + "2CyakSzBpb82VooVNx0IZ3h0nXQSE3V0qSXXCaImJcOIGMo="; public static final String Intermediate_CRL_1_PP_06_03_crl = "MIIBSzCBtQIBATANBgkqhkiG9w0BAQUFADBeMQswCQYDVQQGEwJVUzEYMBYGA1UEChMPVS" + "5TLiBHb3Zlcm5tZW50MQwwCgYDVQQLEwNEb2QxEDAOBgNVBAsTB1Rlc3RpbmcxFTATBgNV" + "BAMTDENBMS1QUC4wNi4wMxcNOTkwMTAxMTIwMTAwWhcNNDgwMTAxMTIwMTAwWqAjMCEwCg" + "YDVR0UBAMCAQEwEwYDVR0jBAwwCoAIRdIl2ZpSCrEwDQYJKoZIhvcNAQEFBQADgYEAQrHK" + "VV2MJPJLNdPoEuqFXRTEclSmYhUWC5lthK0JnKUbCUj2cMAku2UdN5sRgVG0475dXV2nvn" + "huxy+IQVt5OJ+PNZ9MYZlC2CfYsBiW9DEYMA603XhVvX/bxx80MwxNby18oyo/V9ycSyJw" + "XzUmzYRUtohHk39r3eUSAt5H7zM="; public static final String Intermediate_CRL_2_PP_06_03_crl = "MIIBSzCBtQIBATANBgkqhkiG9w0BAQUFADBeMQswCQYDVQQGEwJVUzEYMBYGA1UEChMPVS" + "5TLiBHb3Zlcm5tZW50MQwwCgYDVQQLEwNEb2QxEDAOBgNVBAsTB1Rlc3RpbmcxFTATBgNV" + "BAMTDENBMi1QUC4wNi4wMxcNOTkwMTAxMTIwMTAwWhcNNDgwMTAxMTIwMTAwWqAjMCEwCg" + "YDVR0UBAMCAQEwEwYDVR0jBAwwCoAInXHgY/+onu4wDQYJKoZIhvcNAQEFBQADgYEADOEh" + "jV8V8y17mFstkVwigOAKURbi7sD24RkLd1QG0Bn21JiwpkGY8Z4vetQps+VX586xKzz6v6" + "Sj+TJk3jfHCiEAk6a7PLxRcVCCi6y70mzEBCwn6fS5NDfxzxYYLgq+dlUiVwqXsHksEvUz" + "2Z5dpuLhbUGxHiqazNE9iq9pEEE="; public static final String Intermediate_CRL_3_PP_06_03_crl = "MIIBSzCBtQIBATANBgkqhkiG9w0BAQUFADBeMQswCQYDVQQGEwJVUzEYMBYGA1UEChMPVS" + "5TLiBHb3Zlcm5tZW50MQwwCgYDVQQLEwNEb2QxEDAOBgNVBAsTB1Rlc3RpbmcxFTATBgNV" + "BAMTDENBMy1QUC4wNi4wMxcNOTkwMTAxMTIwMTAwWhcNNDgwMTAxMTIwMTAwWqAjMCEwCg" + "YDVR0UBAMCAQEwEwYDVR0jBAwwCoAIc24GzUM6/LswDQYJKoZIhvcNAQEFBQADgYEAK/zi" + "r7ASgtWA0xGQVrqhHsXH9bdaj+FceW6ivoXo3z6xCFLvzu2uenEu5g849+YI0KMomHsDAY" + "tX8qO3XEaLGchbhIfywgRVDlSF8ytMKhJTS05R/vZSZAl+eoT3mC92Grihsd3wublyNZ7a" + "d925Py/oFp3J+geUkKJQK+RVu4M="; public static final String Intermediate_CRL_4_PP_06_03_crl = "MIIBSzCBtQIBATANBgkqhkiG9w0BAQUFADBeMQswCQYDVQQGEwJVUzEYMBYGA1UEChMPVS" + "5TLiBHb3Zlcm5tZW50MQwwCgYDVQQLEwNEb2QxEDAOBgNVBAsTB1Rlc3RpbmcxFTATBgNV" + "BAMTDENBNC1QUC4wNi4wMxcNOTkwMTAxMTIwMTAwWhcNNDgwMTAxMTIwMTAwWqAjMCEwCg" + "YDVR0UBAMCAQEwEwYDVR0jBAwwCoAIDjpr8w0dRq0wDQYJKoZIhvcNAQEFBQADgYEAcBag" + "81RFYMBAf8aRP5VXPcfu0OxgJvVE25ZHGLCkLD4TPKAXMjZMHWrf34+5FW7aigDO1YhGA+" + "2zVtVj8k71DichiCCGXQvH50AqFgeNXNQwn9WcpQ8rRkfmyhlccfeM+MzHI1giRw/RjvCN" + "0dfJL9g3c7peW+VCKn85REZ1ne4="; public static final String End_Certificate_PP_06_03_crt = "MIICbjCCAdegAwIBAgIBbzANBgkqhkiG9w0BAQUFADBeMQswCQYDVQQGEwJVUzEYMBYGA1" + "UEChMPVS5TLiBHb3Zlcm5tZW50MQwwCgYDVQQLEwNEb2QxEDAOBgNVBAsTB1Rlc3Rpbmcx" + "FTATBgNVBAMTDENBNC1QUC4wNi4wMzAeFw05ODAxMDExMjAxMDBaFw00ODAxMDExMjAxMD" + "BaMGAxCzAJBgNVBAYTAlVTMRgwFgYDVQQKEw9VLlMuIEdvdmVybm1lbnQxDDAKBgNVBAsT" + "A0RvRDEQMA4GA1UECxMHVGVzdGluZzEXMBUGA1UEAxMOVXNlcjEtUFAuMDYuMDMwgZ8wDQ" + "YJKoZIhvcNAQEBBQADgY0AMIGJAoGBAKBSOacrUg5H5yuISkqmJuQcK2ao+Ib0FmIKCuek" + "8mm2HEiux+K5/yIAYsQnz9eDKzKWaS73exPniKOXABHaL6dxsptbdBqWB6II2kIl0BFz9P" + "82qjz6DMwpUhj5Pwfy5q0Bz8grTe31ZYP19y8AHgcWna+eiY4fNVXVkIEJOJ6tAgMBAAGj" + "OjA4MA4GA1UdDwEB/wQEAwIF4DARBgNVHQ4ECgQIaZQ3Q55so58wEwYDVR0jBAwwCoAIDj" + "pr8w0dRq0wDQYJKoZIhvcNAQEFBQADgYEAnNYKc2pSFZ9PtR4gQyVI3j+gQ97tcWu6Alxm" + "4T48fSb2KtFGuozJyCv0aYjtuZ9ava9r4v04lyFPoAjWYbALHC9F+vz7JLNr4VstuMdy5O" + "ax+PvJjKGACSXD7QjXJ48qvm+v8OnMbkzf8+rY3LoTJ2KhXo9Ey4+UmU/YuZ0PXuY="; public static final String[] TEST_45_DATA = new String[] { Intermediate_Certificate_1_PP_06_03_crt, Intermediate_Certificate_2_PP_06_03_crt, Intermediate_Certificate_3_PP_06_03_crt, Intermediate_Certificate_4_PP_06_03_crt, Intermediate_CRL_1_PP_06_03_crl, Intermediate_CRL_2_PP_06_03_crl, Intermediate_CRL_3_PP_06_03_crl, Intermediate_CRL_4_PP_06_03_crl, End_Certificate_PP_06_03_crt }; /* * test46 * */ public static final String Intermediate_Certificate_1_PP_06_04_crt = "MIICozCCAgygAwIBAgIBcDANBgkqhkiG9w0BAQUFADBeMQswCQYDVQQGEwJVUzEYMBYGA1" + "UEChMPVS5TLiBHb3Zlcm5tZW50MQwwCgYDVQQLEwNEb0QxEDAOBgNVBAsTB1Rlc3Rpbmcx" + "FTATBgNVBAMTDFRydXN0IEFuY2hvcjAeFw05ODAxMDExMjAxMDBaFw00ODAxMDExMjAxMD" + "BaMF4xCzAJBgNVBAYTAlVTMRgwFgYDVQQKEw9VLlMuIEdvdmVybm1lbnQxDDAKBgNVBAsT" + "A0RvZDEQMA4GA1UECxMHVGVzdGluZzEVMBMGA1UEAxMMQ0ExLVBQLjA2LjA0MIGfMA0GCS" + "qGSIb3DQEBAQUAA4GNADCBiQKBgQDFoR/YTJlGYenu2IRsTiT6jwIA7yOnFbM9JXcqYIP5" + "jSgtn/wVztPHgVWP+582foXJ+oEcThQVZ+RBXYt6VU5o7eVCsGJjqMd0DbRzTO+poelVoY" + "1UEJMrKG0xSEex0T6XLQ+jPU9o5tlXoLYsXvpvbIrCJ0o8kuk4MWTzenDKJwIDAQABo3Ew" + "bzAPBgNVHRMBAf8EBTADAQH/MA4GA1UdDwEB/wQEAwIBBjAWBgNVHSAEDzANMAsGCWCGSA" + "FlAwEwATAMBgNVHSQEBTADgAEAMBEGA1UdDgQKBAgVwXynYDSYEDATBgNVHSMEDDAKgAir" + "muv5wudUjzANBgkqhkiG9w0BAQUFAAOBgQC6MnYM9cY3CNb7/KKZvoaSwF/Se5iZYnbdPn" + "WCnKydnN1AhlDN3kEw0gjTmZo/MkvPqku2aPzg5EiZ0eyeJaR6a4aiICU9z/Hiet19mBF6" + "BtAUdt0fJ7aL5WPAc4BKXUbONd6vkQNv8uLcBmsqZ4wXDj7ZVBMGKcuDq7uClb0xYw=="; public static final String Intermediate_Certificate_2_PP_06_04_crt = "MIIClTCCAf6gAwIBAgIBcTANBgkqhkiG9w0BAQUFADBeMQswCQYDVQQGEwJVUzEYMBYGA1" + "UEChMPVS5TLiBHb3Zlcm5tZW50MQwwCgYDVQQLEwNEb2QxEDAOBgNVBAsTB1Rlc3Rpbmcx" + "FTATBgNVBAMTDENBMS1QUC4wNi4wNDAeFw05ODAxMDExMjAxMDBaFw00ODAxMDExMjAxMD" + "BaMF4xCzAJBgNVBAYTAlVTMRgwFgYDVQQKEw9VLlMuIEdvdmVybm1lbnQxDDAKBgNVBAsT" + "A0RvZDEQMA4GA1UECxMHVGVzdGluZzEVMBMGA1UEAxMMQ0EyLVBQLjA2LjA0MIGfMA0GCS" + "qGSIb3DQEBAQUAA4GNADCBiQKBgQDHqX/4IZpOCsHWgdJ6mICN94nXz/KqsXPNymadVdZA" + "nVU0fHdMcxehAvsBKju5d791Psly1Xyyda8KQ0BKPgGed6jNKb89JzuEtPBov0VMzskqwR" + "irjaDCwYKtibiDe+T/kEN9Sq5pbexHcaTbAIeQrAIoSUmGdQ/Up6PYplb0jwIDAQABo2Mw" + "YTAPBgNVHRMBAf8EBTADAQH/MA4GA1UdDwEB/wQEAwIBBjAWBgNVHSAEDzANMAsGCWCGSA" + "FlAwEwATARBgNVHQ4ECgQISKcQDqdBecUwEwYDVR0jBAwwCoAIFcF8p2A0mBAwDQYJKoZI" + "hvcNAQEFBQADgYEAkAQaOoZYAZOCk881Ro+SIclAj2lp+arAkWPP/gwN4/0lpH62eWqlmY" + "okWRBjk6+iwCgRxQ56uUjJhE08p5juZ5V32ie3RW+S1ZBPtL/T/+Tqp9HNQQ3GjW1yc/yI" + "sWQxrd7QKzTER37HBiOr5WjEjn+dzuWlJtClcQetqMLtMgM="; public static final String Intermediate_Certificate_3_PP_06_04_crt = "MIIClTCCAf6gAwIBAgIBcjANBgkqhkiG9w0BAQUFADBeMQswCQYDVQQGEwJVUzEYMBYGA1" + "UEChMPVS5TLiBHb3Zlcm5tZW50MQwwCgYDVQQLEwNEb2QxEDAOBgNVBAsTB1Rlc3Rpbmcx" + "FTATBgNVBAMTDENBMi1QUC4wNi4wNDAeFw05ODAxMDExMjAxMDBaFw00ODAxMDExMjAxMD" + "BaMF4xCzAJBgNVBAYTAlVTMRgwFgYDVQQKEw9VLlMuIEdvdmVybm1lbnQxDDAKBgNVBAsT" + "A0RvZDEQMA4GA1UECxMHVGVzdGluZzEVMBMGA1UEAxMMQ0EzLVBQLjA2LjA0MIGfMA0GCS" + "qGSIb3DQEBAQUAA4GNADCBiQKBgQC2tnVj8KHGCm8XBPvDYWZMp3yOKQxuORze6a764qIC" + "hkdO7hQbgJ9YiuAF/y62W17FnbhKPX6ninaZG0N77bznKvivSC3+T1jIVhw+kpxRh9MRya" + "L2p+zHJEyO/9JaKWzJZiVi4kebW+hwNgSZc7FSYsAbW7lr4ujDei/yn/AJEwIDAQABo2Mw" + "YTAPBgNVHRMBAf8EBTADAQH/MA4GA1UdDwEB/wQEAwIBBjAWBgNVHSAEDzANMAsGCWCGSA" + "FlAwEwATARBgNVHQ4ECgQIaAEiWf4JpfQwEwYDVR0jBAwwCoAISKcQDqdBecUwDQYJKoZI" + "hvcNAQEFBQADgYEAHNsZDCWtOqt741IJNA9OwpymTA4ES1BRJquEvGj5+4RH2pxi67bYd1" + "kWTPF1qFC2R1sugSNhbU0wOBMdKUJtKWNacPsK0HbD7CPqt4THOcMXFO36b/2gqHqy9rc/" + "slWuIwbtT/tEC+Mk67GEATWNPifoPT7TjWHM3RhsDnagZXw="; public static final String Intermediate_Certificate_4_PP_06_04_crt = "MIIClTCCAf6gAwIBAgIBczANBgkqhkiG9w0BAQUFADBeMQswCQYDVQQGEwJVUzEYMBYGA1" + "UEChMPVS5TLiBHb3Zlcm5tZW50MQwwCgYDVQQLEwNEb2QxEDAOBgNVBAsTB1Rlc3Rpbmcx" + "FTATBgNVBAMTDENBMy1QUC4wNi4wNDAeFw05ODAxMDExMjAxMDBaFw00ODAxMDExMjAxMD" + "BaMF4xCzAJBgNVBAYTAlVTMRgwFgYDVQQKEw9VLlMuIEdvdmVybm1lbnQxDDAKBgNVBAsT" + "A0RvZDEQMA4GA1UECxMHVGVzdGluZzEVMBMGA1UEAxMMQ0E0LVBQLjA2LjA0MIGfMA0GCS" + "qGSIb3DQEBAQUAA4GNADCBiQKBgQDgdk/smDJ5yZYJDH4SG7pIDCzGNZeLO9RI3ybOx4/B" + "M3YQu3DDFSOv8kq6PgL8ThC8Dk6t1jSbT8QVzaGgx0KMV3p6pIMdaVNkOjVjUb+L0nXVfr" + "XYpFLON6tZLgh8oIbiz4KznKmsxo6VdYwyUeHmkpGcL5y+8qLspCNdRJnDGwIDAQABo2Mw" + "YTAPBgNVHRMBAf8EBTADAQH/MA4GA1UdDwEB/wQEAwIBBjAWBgNVHSAEDzANMAsGCWCGSA" + "FlAwEwATARBgNVHQ4ECgQIgSY376EamQowEwYDVR0jBAwwCoAIaAEiWf4JpfQwDQYJKoZI" + "hvcNAQEFBQADgYEAEztvmGSVnDGGeNlIoR+wfRM8ndJogvUxLBZm4N96mDZ9Y+Nr99Dqvw" + "+mMI3BU0miA5kDO9aFrKIgow3cpruoedhnBUsxTfhrNaFEwp+ORUb3tWn7sSxLfnTim4Vq" + "y6j/EfUK2CS4ZAy7J5BADWSqDezPnrb5UaY1JFKMuLyGRac="; public static final String Intermediate_CRL_1_PP_06_04_crl = "MIIBSzCBtQIBATANBgkqhkiG9w0BAQUFADBeMQswCQYDVQQGEwJVUzEYMBYGA1UEChMPVS" + "5TLiBHb3Zlcm5tZW50MQwwCgYDVQQLEwNEb2QxEDAOBgNVBAsTB1Rlc3RpbmcxFTATBgNV" + "BAMTDENBMS1QUC4wNi4wNBcNOTkwMTAxMTIwMTAwWhcNNDgwMTAxMTIwMTAwWqAjMCEwCg" + "YDVR0UBAMCAQEwEwYDVR0jBAwwCoAIFcF8p2A0mBAwDQYJKoZIhvcNAQEFBQADgYEAPlIW" + "SxwW2LE8qxeD+M+HypNwai7j9XxUA2MhBbGVnsrhH+DKX5VeyP/nyZn2hBoGWhs05IpG2P" + "S0odnyhbgGSXSj+IOfkZkVT0BmuEJmqv75R15LBzeyONks+eSEhoOIGAaIN4WgJ5mzjSrI" + "ddDu3c4s6QO/OFVrNF1F6e4laSU="; public static final String Intermediate_CRL_2_PP_06_04_crl = "MIIBSzCBtQIBATANBgkqhkiG9w0BAQUFADBeMQswCQYDVQQGEwJVUzEYMBYGA1UEChMPVS" + "5TLiBHb3Zlcm5tZW50MQwwCgYDVQQLEwNEb2QxEDAOBgNVBAsTB1Rlc3RpbmcxFTATBgNV" + "BAMTDENBMi1QUC4wNi4wNBcNOTkwMTAxMTIwMTAwWhcNNDgwMTAxMTIwMTAwWqAjMCEwCg" + "YDVR0UBAMCAQEwEwYDVR0jBAwwCoAISKcQDqdBecUwDQYJKoZIhvcNAQEFBQADgYEAE5wt" + "y3+jVnr8de/Yi0LV70v3JDHimwG2pQcuDRhR1NLPr4oC+2uxMqwxVzdHITDb3yI2ZT9pVh" + "PV3UvX85avMdA0/JyaMWSKNpbSah1eNfMwMBY2vzh1Q7f5n+7HYYM+I2kz7HARPvwsLP9d" + "j4mY7Kq7uiOFdnQzJ6LWjm8qEMs="; public static final String Intermediate_CRL_3_PP_06_04_crl = "MIIBSzCBtQIBATANBgkqhkiG9w0BAQUFADBeMQswCQYDVQQGEwJVUzEYMBYGA1UEChMPVS" + "5TLiBHb3Zlcm5tZW50MQwwCgYDVQQLEwNEb2QxEDAOBgNVBAsTB1Rlc3RpbmcxFTATBgNV" + "BAMTDENBMy1QUC4wNi4wNBcNOTkwMTAxMTIwMTAwWhcNNDgwMTAxMTIwMTAwWqAjMCEwCg" + "YDVR0UBAMCAQEwEwYDVR0jBAwwCoAIaAEiWf4JpfQwDQYJKoZIhvcNAQEFBQADgYEAOm2f" + "m3IdcDnIS915tEZzDmIbTFPBkIn0wjUreZKb9uNxE2a8Jixq+UP2uiyYWiWmXnRdVB1Gsb" + "ofc5f8ctNgSPVTSYB0U5apIauXjV0y7WMUrLNrDFa5m9lxLRhF9kvXVL8zPhVfMpujnXre" + "A8WS4UjDMuveyQL6yASGoZvB+Ps="; public static final String Intermediate_CRL_4_PP_06_04_crl = "MIIBSzCBtQIBATANBgkqhkiG9w0BAQUFADBeMQswCQYDVQQGEwJVUzEYMBYGA1UEChMPVS" + "5TLiBHb3Zlcm5tZW50MQwwCgYDVQQLEwNEb2QxEDAOBgNVBAsTB1Rlc3RpbmcxFTATBgNV" + "BAMTDENBNC1QUC4wNi4wNBcNOTkwMTAxMTIwMTAwWhcNNDgwMTAxMTIwMTAwWqAjMCEwCg" + "YDVR0UBAMCAQEwEwYDVR0jBAwwCoAIgSY376EamQowDQYJKoZIhvcNAQEFBQADgYEAznK9" + "ekskl4uWU+2Xqp3Pj14wvXuzfPAqFlHR0jl5By7T82JRiRa6LGX6T953vcwwJBsYG1hMqH" + "pgbnUGB8APQ6YNXN+7ZkudaG6fMVX6bCr8zT+nVSj7PHIK2VFsC1Jpm5SoQMHH6DFit/oH" + "tm4tdV8+nupMBQn1ZtxQHgUUF14="; public static final String End_Certificate_PP_06_04_crt = "MIIChjCCAe+gAwIBAgIBdDANBgkqhkiG9w0BAQUFADBeMQswCQYDVQQGEwJVUzEYMBYGA1" + "UEChMPVS5TLiBHb3Zlcm5tZW50MQwwCgYDVQQLEwNEb2QxEDAOBgNVBAsTB1Rlc3Rpbmcx" + "FTATBgNVBAMTDENBNC1QUC4wNi4wNDAeFw05ODAxMDExMjAxMDBaFw00ODAxMDExMjAxMD" + "BaMGAxCzAJBgNVBAYTAlVTMRgwFgYDVQQKEw9VLlMuIEdvdmVybm1lbnQxDDAKBgNVBAsT" + "A0RvRDEQMA4GA1UECxMHVGVzdGluZzEXMBUGA1UEAxMOVXNlcjEtUFAuMDYuMDQwgZ8wDQ" + "YJKoZIhvcNAQEBBQADgY0AMIGJAoGBAOCVJmtrW8Z2WGGRNjEgyp2NJn1xaIVDwlxL4C0n" + "UAPpo1WM/rarQTYejT2Yo8H39TdRfiAlggF0Qsce0W//atey8WewGsFlUem6a4OFwg1X2h" + "CN/COL0eC4a6lwkdOKmqgxSyWNWeKxXRTM8+EYQIem78uY7A8XuzVUmOpzYWoLAgMBAAGj" + "UjBQMA4GA1UdDwEB/wQEAwIF4DAWBgNVHSAEDzANMAsGCWCGSAFlAwEwATARBgNVHQ4ECg" + "QION6UOZ2Eky4wEwYDVR0jBAwwCoAIgSY376EamQowDQYJKoZIhvcNAQEFBQADgYEAXota" + "1N1UrMxj2a/vdII92Wi8uEetcHo9vmiJVYxwPFkp+qo1q93Ww8Qnfp7xzaZwLgVoUOAF8U" + "TRUVnzqoSwmRrfyEMfrgej3eiBjcU+zS9mNlx9mUUSLmlY+xMeejyVDCntRn6YJWWLesVq" + "eFOjyNux97/XnGT3T1w0J+wShu4="; public static final String[] TEST_46_DATA = new String[] { Intermediate_Certificate_1_PP_06_04_crt, Intermediate_Certificate_2_PP_06_04_crt, Intermediate_Certificate_3_PP_06_04_crt, Intermediate_Certificate_4_PP_06_04_crt, Intermediate_CRL_1_PP_06_04_crl, Intermediate_CRL_2_PP_06_04_crl, Intermediate_CRL_3_PP_06_04_crl, Intermediate_CRL_4_PP_06_04_crl, End_Certificate_PP_06_04_crt }; /* * test47 * */ public static final String Intermediate_Certificate_1_PP_06_05_crt = "MIICozCCAgygAwIBAgIBdTANBgkqhkiG9w0BAQUFADBeMQswCQYDVQQGEwJVUzEYMBYGA1" + "UEChMPVS5TLiBHb3Zlcm5tZW50MQwwCgYDVQQLEwNEb0QxEDAOBgNVBAsTB1Rlc3Rpbmcx" + "FTATBgNVBAMTDFRydXN0IEFuY2hvcjAeFw05ODAxMDExMjAxMDBaFw00ODAxMDExMjAxMD" + "BaMF4xCzAJBgNVBAYTAlVTMRgwFgYDVQQKEw9VLlMuIEdvdmVybm1lbnQxDDAKBgNVBAsT" + "A0RvZDEQMA4GA1UECxMHVGVzdGluZzEVMBMGA1UEAxMMQ0ExLVBQLjA2LjA1MIGfMA0GCS" + "qGSIb3DQEBAQUAA4GNADCBiQKBgQDMIUtQ/CgudxHAwAAn8jUsdAY8u7WDslOC4nNbWn5C" + "tILgZ2hGIZhEnhzP+VCV8ke8zLo1DX0hCRYAgzk5XTGAimExHFv/yDdhpJWEnqMRljkCHx" + "Hg3XE1439qutBdmWvGUlRF0hQrd9Q/Ubr+PjEzP3a0EUmXo7LYuQKMcFsC4wIDAQABo3Ew" + "bzAPBgNVHRMBAf8EBTADAQH/MA4GA1UdDwEB/wQEAwIBBjAWBgNVHSAEDzANMAsGCWCGSA" + "FlAwEwATAMBgNVHSQEBTADgAEHMBEGA1UdDgQKBAgha8GqGbO1nDATBgNVHSMEDDAKgAir" + "muv5wudUjzANBgkqhkiG9w0BAQUFAAOBgQAEG5C3P1A/MYpNJ0qvi26v04GGUWDQWRW1q9" + "1392XpAxDdv7kODf1FUMpfBpcUblagxrX7Npthv6/6W8poBTjvJuq5BfnnOMQrCwnsNfRy" + "Y7b1mAZIvcOBhWe+bFVqRLUqZ+JseWkw0YgZIGtX41Znwl0VcFQKJ4lNkuaBgXXdGw=="; public static final String Intermediate_Certificate_2_PP_06_05_crt = "MIICozCCAgygAwIBAgIBdjANBgkqhkiG9w0BAQUFADBeMQswCQYDVQQGEwJVUzEYMBYGA1" + "UEChMPVS5TLiBHb3Zlcm5tZW50MQwwCgYDVQQLEwNEb2QxEDAOBgNVBAsTB1Rlc3Rpbmcx" + "FTATBgNVBAMTDENBMS1QUC4wNi4wNTAeFw05ODAxMDExMjAxMDBaFw00ODAxMDExMjAxMD" + "BaMF4xCzAJBgNVBAYTAlVTMRgwFgYDVQQKEw9VLlMuIEdvdmVybm1lbnQxDDAKBgNVBAsT" + "A0RvZDEQMA4GA1UECxMHVGVzdGluZzEVMBMGA1UEAxMMQ0EyLVBQLjA2LjA1MIGfMA0GCS" + "qGSIb3DQEBAQUAA4GNADCBiQKBgQC36j0YkXZZSw3qQaxD0g2BfrKYperkGjVAfLwOtOxB" + "0A3Ufx2ECl/MqNOvi/QWlTkKwnrqw0aEnD25iS1DFM4jMZBmdfJg80oa+y6TJoZcIb+3bv" + "SK5o3ArCFWkhTHHggIIY3H9dQOgAeYQF57Vb0iu59GPfnYJO8y8ZpxGIYcjQIDAQABo3Ew" + "bzAPBgNVHRMBAf8EBTADAQH/MA4GA1UdDwEB/wQEAwIBBjAWBgNVHSAEDzANMAsGCWCGSA" + "FlAwEwATAMBgNVHSQEBTADgAECMBEGA1UdDgQKBAhUpoGZzfV7EjATBgNVHSMEDDAKgAgh" + "a8GqGbO1nDANBgkqhkiG9w0BAQUFAAOBgQAjrFHzC1FLvssJTfV5YsGfw7Luj4EqLDQd6b" + "MgtBSwPnXqMTUAZpDETyeYvcgM+L2tasB26MSy6IttSKsaJpHPCP+BIs0jji5xosuCX6Cs" + "wI2gE/LjF85rjZnldrlDShw01DlcmWlWwudit/ieO71Xc8i0F4EhSaTUJX12po5Xkg=="; public static final String Intermediate_Certificate_3_PP_06_05_crt = "MIICozCCAgygAwIBAgIBdzANBgkqhkiG9w0BAQUFADBeMQswCQYDVQQGEwJVUzEYMBYGA1" + "UEChMPVS5TLiBHb3Zlcm5tZW50MQwwCgYDVQQLEwNEb2QxEDAOBgNVBAsTB1Rlc3Rpbmcx" + "FTATBgNVBAMTDENBMi1QUC4wNi4wNTAeFw05ODAxMDExMjAxMDBaFw00ODAxMDExMjAxMD" + "BaMF4xCzAJBgNVBAYTAlVTMRgwFgYDVQQKEw9VLlMuIEdvdmVybm1lbnQxDDAKBgNVBAsT" + "A0RvZDEQMA4GA1UECxMHVGVzdGluZzEVMBMGA1UEAxMMQ0EzLVBQLjA2LjA1MIGfMA0GCS" + "qGSIb3DQEBAQUAA4GNADCBiQKBgQDFWhChPQNFYQpLBmVmXSGF2py1wcfhZgZurv0E5AgE" + "BZwBo2bxSeC36lBQyR3OABGI4nQoEegSQWwuS2Pk3+emG2MZ8R5QINAkMlAKTp5Gj7KTlm" + "3VVJRx7/VduoFx8sZPjkpvF1bSL+KOH4UZny1xqqTj4bJ+oGu58INeSNVa+wIDAQABo3Ew" + "bzAPBgNVHRMBAf8EBTADAQH/MA4GA1UdDwEB/wQEAwIBBjAWBgNVHSAEDzANMAsGCWCGSA" + "FlAwEwATAMBgNVHSQEBTADgAEEMBEGA1UdDgQKBAjN4PvsHY9+YzATBgNVHSMEDDAKgAhU" + "poGZzfV7EjANBgkqhkiG9w0BAQUFAAOBgQA8KmWbAQOnM59zry9TNtLbA2P5y8R/sO771S" + "yQYcu6undt9t7UEiOepDp/z3CGsITm9RdtXAobZ5ZqhW+3Ll+UnML1itiCytOPbfC7iiUO" + "S5jviQnpgJncZD2Lp65yNAB7lMmMleFO15Bsk8VNmzMDMsFtzo508Bs6T33ZW69/vg=="; public static final String Intermediate_Certificate_4_PP_06_05_crt = "MIIClTCCAf6gAwIBAgIBeDANBgkqhkiG9w0BAQUFADBeMQswCQYDVQQGEwJVUzEYMBYGA1" + "UEChMPVS5TLiBHb3Zlcm5tZW50MQwwCgYDVQQLEwNEb2QxEDAOBgNVBAsTB1Rlc3Rpbmcx" + "FTATBgNVBAMTDENBMy1QUC4wNi4wNTAeFw05ODAxMDExMjAxMDBaFw00ODAxMDExMjAxMD" + "BaMF4xCzAJBgNVBAYTAlVTMRgwFgYDVQQKEw9VLlMuIEdvdmVybm1lbnQxDDAKBgNVBAsT" + "A0RvZDEQMA4GA1UECxMHVGVzdGluZzEVMBMGA1UEAxMMQ0E0LVBQLjA2LjA1MIGfMA0GCS" + "qGSIb3DQEBAQUAA4GNADCBiQKBgQDxx57R4j64xdbjpTl7reLby/T2ym4rESC90aBkC2/E" + "/YUSjsuGG9GiHEVgoGzoQGQNQV0v9ZMIvuoI6q7Fd6VZhIVGE0MGzTFNA9QEEDGPc10ZxC" + "Gyh9mZYp77PMuhQ12Iv3aDW9KNTr09+HyhK7d3Se7toXLwjE5pKt+A4ZvBFQIDAQABo2Mw" + "YTAPBgNVHRMBAf8EBTADAQH/MA4GA1UdDwEB/wQEAwIBBjAWBgNVHSAEDzANMAsGCWCGSA" + "FlAwEwATARBgNVHQ4ECgQIwmq0fugIX0kwEwYDVR0jBAwwCoAIzeD77B2PfmMwDQYJKoZI" + "hvcNAQEFBQADgYEAbAbRorTyh6zfAmdg0lfeZyCyW9k4NWfhUs46iSOl6lkZH8c1eoAF5/" + "q0pOF+CtI3F9VMhfUXChEbVj7QENctU7kDiFe8300OWD5h1VUi+WTK4CG7B36/BjkrVOuG" + "Os76P9l1WaC+/WRZdcqgFMfPjpn3R179dImBDwZiCMMbVqc="; public static final String Intermediate_CRL_1_PP_06_05_crl = "MIIBSzCBtQIBATANBgkqhkiG9w0BAQUFADBeMQswCQYDVQQGEwJVUzEYMBYGA1UEChMPVS" + "5TLiBHb3Zlcm5tZW50MQwwCgYDVQQLEwNEb2QxEDAOBgNVBAsTB1Rlc3RpbmcxFTATBgNV" + "BAMTDENBMS1QUC4wNi4wNRcNOTkwMTAxMTIwMTAwWhcNNDgwMTAxMTIwMTAwWqAjMCEwCg" + "YDVR0UBAMCAQEwEwYDVR0jBAwwCoAIIWvBqhmztZwwDQYJKoZIhvcNAQEFBQADgYEADX3u" + "wxpN+p8N2HqmhFw8w9LCeoR3Xa/uaqgqh4i/VkDuAC4Bi7VbIO6rcxDO2uAdZgNhb/hnRq" + "cvKLcy0vrovCa2EPHcFo7dJl7si2q09EeuHT4+lZt/Ek/VOkwHhvh2o6yEvKOGXCnF9hZr" + "8YbOIknboEz+tRfxoJArRBwpJkE="; public static final String Intermediate_CRL_2_PP_06_05_crl = "MIIBSzCBtQIBATANBgkqhkiG9w0BAQUFADBeMQswCQYDVQQGEwJVUzEYMBYGA1UEChMPVS" + "5TLiBHb3Zlcm5tZW50MQwwCgYDVQQLEwNEb2QxEDAOBgNVBAsTB1Rlc3RpbmcxFTATBgNV" + "BAMTDENBMi1QUC4wNi4wNRcNOTkwMTAxMTIwMTAwWhcNNDgwMTAxMTIwMTAwWqAjMCEwCg" + "YDVR0UBAMCAQEwEwYDVR0jBAwwCoAIVKaBmc31exIwDQYJKoZIhvcNAQEFBQADgYEAQz7u" + "dfU4yAHFLH5BgeZkYh0l2lZ95af+E/67MSCjQSF7RWWWTffbDMc4HmiRlZLvQdltyGCKmi" + "kuzcPP8vyYOBQmoIKQ6c2LItBjXVavLdpe91yCOhCWXVVlnMFq5ztrvBEpfO0GVUOnPWfG" + "1Ugit3SEd4DbhYFTBYHbbOKRWsU="; public static final String Intermediate_CRL_3_PP_06_05_crl = "MIIBSzCBtQIBATANBgkqhkiG9w0BAQUFADBeMQswCQYDVQQGEwJVUzEYMBYGA1UEChMPVS" + "5TLiBHb3Zlcm5tZW50MQwwCgYDVQQLEwNEb2QxEDAOBgNVBAsTB1Rlc3RpbmcxFTATBgNV" + "BAMTDENBMy1QUC4wNi4wNRcNOTkwMTAxMTIwMTAwWhcNNDgwMTAxMTIwMTAwWqAjMCEwCg" + "YDVR0UBAMCAQEwEwYDVR0jBAwwCoAIzeD77B2PfmMwDQYJKoZIhvcNAQEFBQADgYEAkiW6" + "h9a8v+IITd+p0jxukj2FYfmED59ZXAlYhQdQAGlPE71rOXn6ZPURYoGf7qlmBwQffpksOb" + "Byb+PX+CBTUNXzhgTzD7ifM9xOhCEKVKai9acQfvokU56OHwfq5AnkRykLZ7IdvdYCP57k" + "ynrNNV35dsMZXg23/PpreumlOkE="; public static final String Intermediate_CRL_4_PP_06_05_crl = "MIIBSzCBtQIBATANBgkqhkiG9w0BAQUFADBeMQswCQYDVQQGEwJVUzEYMBYGA1UEChMPVS" + "5TLiBHb3Zlcm5tZW50MQwwCgYDVQQLEwNEb2QxEDAOBgNVBAsTB1Rlc3RpbmcxFTATBgNV" + "BAMTDENBNC1QUC4wNi4wNRcNOTkwMTAxMTIwMTAwWhcNNDgwMTAxMTIwMTAwWqAjMCEwCg" + "YDVR0UBAMCAQEwEwYDVR0jBAwwCoAIwmq0fugIX0kwDQYJKoZIhvcNAQEFBQADgYEAnTbS" + "MBWyoPaslaLpAMmJ+D6kmmKAdRYurA0okU/QP+0W+YNPV4DducAQUDy8Cg3RkpRK2ze0ad" + "l6TUW8g83hj9TXSBp+XZuVvzerMCjOeBqhskZN4Ly8101ZZmMmdYdSc3PEhqkme6iZzjwB" + "ZooAN2dIYjuBj1c1/t5qH80CMAI="; public static final String End_Certificate_PP_06_05_crt = "MIICbjCCAdegAwIBAgIBeTANBgkqhkiG9w0BAQUFADBeMQswCQYDVQQGEwJVUzEYMBYGA1" + "UEChMPVS5TLiBHb3Zlcm5tZW50MQwwCgYDVQQLEwNEb2QxEDAOBgNVBAsTB1Rlc3Rpbmcx" + "FTATBgNVBAMTDENBNC1QUC4wNi4wNTAeFw05ODAxMDExMjAxMDBaFw00ODAxMDExMjAxMD" + "BaMGAxCzAJBgNVBAYTAlVTMRgwFgYDVQQKEw9VLlMuIEdvdmVybm1lbnQxDDAKBgNVBAsT" + "A0RvRDEQMA4GA1UECxMHVGVzdGluZzEXMBUGA1UEAxMOVXNlcjEtUFAuMDYuMDUwgZ8wDQ" + "YJKoZIhvcNAQEBBQADgY0AMIGJAoGBALyVMklPv3uwTPzLG70sXIwKSEt65yiU71ibHyhH" + "wJ/6dXy3HK2UETkRBK7UVSOYq005EbO9s/3oR3zt7QTFifvRTsIjl1L4TCLC2a8ApBr3BH" + "xmBWcJDf427Pk1fm5qDdEmZnpyIlpKaKIiBcdtwZfjr0lROL8RNcvgtJPdu/ndAgMBAAGj" + "OjA4MA4GA1UdDwEB/wQEAwIF4DARBgNVHQ4ECgQISjAUfyAwSA0wEwYDVR0jBAwwCoAIwm" + "q0fugIX0kwDQYJKoZIhvcNAQEFBQADgYEAC6Af3cJUh/IQgWdbC2Vmk96sYjDlAsbA2keY" + "J0bgBcNaIVoJ/W0B3rSawqSU+Vv64p7kcuAl6cbvIXPB++19V23jj6HUs1JxtPJZ9IWkS/" + "FRakv6lD7+j1OdzJvDR8AMZWmPFHJdQnJwQ+I1YOU/O/ShawOnGCmihpIULUINFhk="; public static final String[] TEST_47_DATA = new String[] { Intermediate_Certificate_1_PP_06_05_crt, Intermediate_Certificate_2_PP_06_05_crt, Intermediate_Certificate_3_PP_06_05_crt, Intermediate_Certificate_4_PP_06_05_crt, Intermediate_CRL_1_PP_06_05_crl, Intermediate_CRL_2_PP_06_05_crl, Intermediate_CRL_3_PP_06_05_crl, Intermediate_CRL_4_PP_06_05_crl, End_Certificate_PP_06_05_crt }; /* * test48 * */ public static final String Intermediate_Certificate_PP_08_01_crt = "MIIClTCCAf6gAwIBAgIBejANBgkqhkiG9w0BAQUFADBeMQswCQYDVQQGEwJVUzEYMBYGA1" + "UEChMPVS5TLiBHb3Zlcm5tZW50MQwwCgYDVQQLEwNEb0QxEDAOBgNVBAsTB1Rlc3Rpbmcx" + "FTATBgNVBAMTDFRydXN0IEFuY2hvcjAeFw05ODAxMDExMjAxMDBaFw00ODAxMDExMjAxMD" + "BaMF4xCzAJBgNVBAYTAlVTMRgwFgYDVQQKEw9VLlMuIEdvdmVybm1lbnQxDDAKBgNVBAsT" + "A0RvZDEQMA4GA1UECxMHVGVzdGluZzEVMBMGA1UEAxMMQ0ExLVBQLjA4LjAxMIGfMA0GCS" + "qGSIb3DQEBAQUAA4GNADCBiQKBgQCp2vHVX08nyKe+S8NPkNJOZ9Xng22TbYXhUHtXw9yv" + "ZmPkRhwDrZfBLXZcdZFixidkky3kCzv8Q3aPyPByM2ozH+AHJzEMbwifhyvUbANcS+Jts3" + "lsZHarN7VyiXO+8J2OtYqX9qzmrAOHGleB2cJopEcmAMdrzgt1JIo98SUs4wIDAQABo2Mw" + "YTAPBgNVHRMBAf8EBTADAQH/MA4GA1UdDwEB/wQEAwIBBjAWBgNVHSAEDzANMAsGCWCGSA" + "FlAwEwATARBgNVHQ4ECgQIoRYqHNcbLacwEwYDVR0jBAwwCoAIq5rr+cLnVI8wDQYJKoZI" + "hvcNAQEFBQADgYEAXchRFC94Pl25d3Kl4wBcueQLyWPRuH9zS0ZPLAqKLcWVdcg3fYMuJ5" + "SypMMpxLaVjN7xq0KjML1gLiPQPk18iA2TOAUMblvjUl1uFzDdD6SqQidEZh2h3wxFtbLP" + "U7qBBki7i1+Xn072Bpn2paw/vlh4K+ut0tFQ2BAhqVnQGJ8="; public static final String Intermediate_CRL_PP_08_01_crl = "MIIBSzCBtQIBATANBgkqhkiG9w0BAQUFADBeMQswCQYDVQQGEwJVUzEYMBYGA1UEChMPVS" + "5TLiBHb3Zlcm5tZW50MQwwCgYDVQQLEwNEb2QxEDAOBgNVBAsTB1Rlc3RpbmcxFTATBgNV" + "BAMTDENBMS1QUC4wOC4wMRcNOTkwMTAxMTIwMTAwWhcNNDgwMTAxMTIwMTAwWqAjMCEwCg" + "YDVR0UBAMCAQEwEwYDVR0jBAwwCoAIoRYqHNcbLacwDQYJKoZIhvcNAQEFBQADgYEARyX9" + "2+LoXD2fIAACBMPDgds6m3Equ+Aawlr0kuppPO4ydCU4kiEgtVGK+kY5GzP6fUpAKjC8mh" + "BrozojhAbkJekDoN0BIJ42Iab70VmdWXRQhPsUDhQwEt+9eSgy+HfiFfpcL1VJx8uY4XMh" + "VB3hmapIe99P/T2QkZ+Pl8j0MgY="; public static final String End_Certificate_PP_08_01_crt = "MIIChjCCAe+gAwIBAgIBezANBgkqhkiG9w0BAQUFADBeMQswCQYDVQQGEwJVUzEYMBYGA1" + "UEChMPVS5TLiBHb3Zlcm5tZW50MQwwCgYDVQQLEwNEb2QxEDAOBgNVBAsTB1Rlc3Rpbmcx" + "FTATBgNVBAMTDENBMS1QUC4wOC4wMTAeFw05ODAxMDExMjAxMDBaFw00ODAxMDExMjAxMD" + "BaMGAxCzAJBgNVBAYTAlVTMRgwFgYDVQQKEw9VLlMuIEdvdmVybm1lbnQxDDAKBgNVBAsT" + "A0RvRDEQMA4GA1UECxMHVGVzdGluZzEXMBUGA1UEAxMOVXNlcjEtUFAuMDguMDEwgZ8wDQ" + "YJKoZIhvcNAQEBBQADgY0AMIGJAoGBANYtrtpgxNl+9jF3TN1B9bSEGQci+cQOKpFsmrtF" + "AyiGBxKONgGSgSFFuFIhyBKZF5ROaKX1P8lsQkrpnuybUi+Z9ADdyoaLUDD/z/kp5sebAZ" + "ujmF8HVlqHYj5Ls2smS9EdSN1zgPTXIOTeZd/lv1iFppRZv6cBqlaoapQJsb1JAgMBAAGj" + "UjBQMA4GA1UdDwEB/wQEAwIF4DAWBgNVHSAEDzANMAsGCWCGSAFlAwEwATARBgNVHQ4ECg" + "QIZjcOdw0ZTCYwEwYDVR0jBAwwCoAIoRYqHNcbLacwDQYJKoZIhvcNAQEFBQADgYEAarsn" + "13/g0vOKxy0okOp2JXEsPdsP7aWnCfR8N4+7gFD6dVnkgCIyc5Kbs7MbhB9gtIxYhHOV9W" + "MaW9QAcBH+eXciFDfQBfaMBkL34ssE/TsZ92r/bhBwKRcH54f96G0QWUnoNMt4U/1j2mKn" + "faFirltqEPUu9mv4FiQ0pNT9yH0="; public static final String[] TEST_48_DATA = new String[] { Intermediate_Certificate_PP_08_01_crt, Intermediate_CRL_PP_08_01_crl, End_Certificate_PP_08_01_crt }; /* * test49 * */ public static final String Intermediate_Certificate_PP_08_02_crt = "MIICojCCAgugAwIBAgIBfDANBgkqhkiG9w0BAQUFADBeMQswCQYDVQQGEwJVUzEYMBYGA1" + "UEChMPVS5TLiBHb3Zlcm5tZW50MQwwCgYDVQQLEwNEb0QxEDAOBgNVBAsTB1Rlc3Rpbmcx" + "FTATBgNVBAMTDFRydXN0IEFuY2hvcjAeFw05ODAxMDExMjAxMDBaFw00ODAxMDExMjAxMD" + "BaMF4xCzAJBgNVBAYTAlVTMRgwFgYDVQQKEw9VLlMuIEdvdmVybm1lbnQxDDAKBgNVBAsT" + "A0RvZDEQMA4GA1UECxMHVGVzdGluZzEVMBMGA1UEAxMMQ0ExLVBQLjA4LjAyMIGfMA0GCS" + "qGSIb3DQEBAQUAA4GNADCBiQKBgQCmAgNA68ABUEppM9Oo3guiGvguvtrWQzsQIJfMBrE4" + "/Scwc4SPK4PiJD+kVwtXinXpVclBMQge10uZ48lSJTihfZscJw3RSHt70H4CpPQm44QS7P" + "7fQqpcZKZvMWmY6A8jju3Phbuq2WgJCIxxVw886GNIAXW8C4ZFmXCjwiGGHwIDAQABo3Aw" + "bjAPBgNVHRMBAf8EBTADAQH/MA4GA1UdDwEB/wQEAwIBBjAjBgNVHSAEHDAaMAsGCWCGSA" + "FlAwEwATALBglghkgBZQMBMAIwEQYDVR0OBAoECOhZ4RAlqGGcMBMGA1UdIwQMMAqACKua" + "6/nC51SPMA0GCSqGSIb3DQEBBQUAA4GBAGEVSOcNaUu50f6AgGBtz1MDdRiHe08W/nzCNn" + "0K1/UqrIXVJ7IYgbOLkL3cdHy4PdngCyEblzl5Cwp9chh2zL0PTUbV1uJIBW32ks1HuAVQ" + "FTZqx0iuopY5AqRCJVDJt4HB5PKObwnmLPNWicI4Juap13j/Tcnw1EP7E7n6OejC"; public static final String Intermediate_CRL_PP_08_02_crl = "MIIBSzCBtQIBATANBgkqhkiG9w0BAQUFADBeMQswCQYDVQQGEwJVUzEYMBYGA1UEChMPVS" + "5TLiBHb3Zlcm5tZW50MQwwCgYDVQQLEwNEb2QxEDAOBgNVBAsTB1Rlc3RpbmcxFTATBgNV" + "BAMTDENBMS1QUC4wOC4wMhcNOTkwMTAxMTIwMTAwWhcNNDgwMTAxMTIwMTAwWqAjMCEwCg" + "YDVR0UBAMCAQEwEwYDVR0jBAwwCoAI6FnhECWoYZwwDQYJKoZIhvcNAQEFBQADgYEACLHw" + "iDARFoF4GauIHnoZlfj6nlOHAFfNSXq06Vvl713bsoAiOSV+2goZjRG62uxhampE+gCdXx" + "1nwhKQ5R5jOGGOxgLtBFNZwKmD0KiDOSvfIVJ0kYCcaB4mSm0a/7pcCPrrE5ofvkmTW6Wx" + "k/YIuBZdDoqZC91v4tnu0fSch9Q="; public static final String End_Certificate_PP_08_02_crt = "MIICkzCCAfygAwIBAgIBfTANBgkqhkiG9w0BAQUFADBeMQswCQYDVQQGEwJVUzEYMBYGA1" + "UEChMPVS5TLiBHb3Zlcm5tZW50MQwwCgYDVQQLEwNEb2QxEDAOBgNVBAsTB1Rlc3Rpbmcx" + "FTATBgNVBAMTDENBMS1QUC4wOC4wMjAeFw05ODAxMDExMjAxMDBaFw00ODAxMDExMjAxMD" + "BaMGAxCzAJBgNVBAYTAlVTMRgwFgYDVQQKEw9VLlMuIEdvdmVybm1lbnQxDDAKBgNVBAsT" + "A0RvRDEQMA4GA1UECxMHVGVzdGluZzEXMBUGA1UEAxMOVXNlcjEtUFAuMDguMDIwgZ8wDQ" + "YJKoZIhvcNAQEBBQADgY0AMIGJAoGBAOJsz8ys71e8UB+VDTBAocVQvADiqh0LjdML3pET" + "B6VvikiHgbB1PJufxDses+v0WD74ChZEa/octNcMFqMgBlhVBEfvbyGTjiN97LzdZ7SPyd" + "DsDulqwBG9sACryUGHqwHYnUbjOqsThOXFB8Sg/CGGawpZAosm2AuH2gqNvNuJAgMBAAGj" + "XzBdMA4GA1UdDwEB/wQEAwIF4DAjBgNVHSAEHDAaMAsGCWCGSAFlAwEwATALBglghkgBZQ" + "MBMAIwEQYDVR0OBAoECOiMLE2l5u16MBMGA1UdIwQMMAqACOhZ4RAlqGGcMA0GCSqGSIb3" + "DQEBBQUAA4GBAFf4BCbNtduwn5InkfdtFbQOqhPLAn/5eIhxhVhUu7TekWT7ktdaVQFzGF" + "G2h1+gXgFP+YKjJy7kGzEVQjlWtuC0l74EwybNHnYAoDg4itKe+0OSNNXdyOmn+i0tE0nx" + "sWN19VvhLGFC8p38gd0oDr1ziYdg0z2Mx4IlMDxl7QhT"; public static final String[] TEST_49_DATA = new String[] { Intermediate_Certificate_PP_08_02_crt, Intermediate_CRL_PP_08_02_crl, End_Certificate_PP_08_02_crt }; /* * test50 * */ public static final String Intermediate_Certificate_PP_08_03_crt = "MIICkDCCAfmgAwIBAgIBfjANBgkqhkiG9w0BAQUFADBeMQswCQYDVQQGEwJVUzEYMBYGA1" + "UEChMPVS5TLiBHb3Zlcm5tZW50MQwwCgYDVQQLEwNEb0QxEDAOBgNVBAsTB1Rlc3Rpbmcx" + "FTATBgNVBAMTDFRydXN0IEFuY2hvcjAeFw05ODAxMDExMjAxMDBaFw00ODAxMDExMjAxMD" + "BaMF4xCzAJBgNVBAYTAlVTMRgwFgYDVQQKEw9VLlMuIEdvdmVybm1lbnQxDDAKBgNVBAsT" + "A0RvZDEQMA4GA1UECxMHVGVzdGluZzEVMBMGA1UEAxMMQ0ExLVBQLjA4LjAzMIGfMA0GCS" + "qGSIb3DQEBAQUAA4GNADCBiQKBgQDKZDgBum5Ud5i8HWlCKInJ1x9goZ7TQJ+LdfA9iGU1" + "47xJL5eFcERWy4dr5wM5GNRW/DHXlnA/qsRVE29EuRh6qAVgcPGAfmJxz7s5yhmErfmiQ3" + "0rh6+pma/EhcjntXqwIqnk1qt6mEk7x9UKO3ksFCVsDEA67/dvownjcZB59wIDAQABo14w" + "XDAPBgNVHRMBAf8EBTADAQH/MA4GA1UdDwEB/wQEAwIBBjARBgNVHSAECjAIMAYGBFUdIA" + "AwEQYDVR0OBAoECGtTrZIwYYHbMBMGA1UdIwQMMAqACKua6/nC51SPMA0GCSqGSIb3DQEB" + "BQUAA4GBAM3t13xJJraRiJDAwZFxhTNR570wMdSRiF3yWSRtOjEv8NTVFj/T1oJJ8h9Gqh" + "hMpTTHU7uGCyVB9S1HCelmS+1zteKr0B+WVzBl9yuhvku3farz6zgIVK3v5hQ6xC4H4Lac" + "NDhTTKBkRfDf9KskFoxJ/AGxPdZtIEC92DFSblQB"; public static final String Intermediate_CRL_PP_08_03_crl = "MIIBSzCBtQIBATANBgkqhkiG9w0BAQUFADBeMQswCQYDVQQGEwJVUzEYMBYGA1UEChMPVS" + "5TLiBHb3Zlcm5tZW50MQwwCgYDVQQLEwNEb2QxEDAOBgNVBAsTB1Rlc3RpbmcxFTATBgNV" + "BAMTDENBMS1QUC4wOC4wMxcNOTkwMTAxMTIwMTAwWhcNNDgwMTAxMTIwMTAwWqAjMCEwCg" + "YDVR0UBAMCAQEwEwYDVR0jBAwwCoAIa1OtkjBhgdswDQYJKoZIhvcNAQEFBQADgYEAcUHo" + "D00X/pd3D5KGa5C6dY18RsnUovkjUkegGTpbhQfmYZIdBatj7Kv75FeUJ9UpqCUjxHgdiE" + "EVy60NLVGP2VRuJ1m8vfDz8hu5PaiVjneQoRw2M9ieBnz3PjSETDdBGJLWHyCBZbp/W2+0" + "iqcZK7Fm9O5EL4PUO6QIwuH76q0="; public static final String End_Certificate_PP_08_03_crt = "MIICgTCCAeqgAwIBAgIBfzANBgkqhkiG9w0BAQUFADBeMQswCQYDVQQGEwJVUzEYMBYGA1" + "UEChMPVS5TLiBHb3Zlcm5tZW50MQwwCgYDVQQLEwNEb2QxEDAOBgNVBAsTB1Rlc3Rpbmcx" + "FTATBgNVBAMTDENBMS1QUC4wOC4wMzAeFw05ODAxMDExMjAxMDBaFw00ODAxMDExMjAxMD" + "BaMGAxCzAJBgNVBAYTAlVTMRgwFgYDVQQKEw9VLlMuIEdvdmVybm1lbnQxDDAKBgNVBAsT" + "A0RvRDEQMA4GA1UECxMHVGVzdGluZzEXMBUGA1UEAxMOVXNlcjEtUFAuMDguMDMwgZ8wDQ" + "YJKoZIhvcNAQEBBQADgY0AMIGJAoGBALsXEPrCg91CObTl5OrHIB5GshIDXgqBmjzxfWPK" + "ih4STWeBe2eIFO9pONXcM5lstEu2XLBPP6QBMUMWOrphJejrJ3eDQHs404bBnt95O/x17i" + "665CZtg1jUqoO1kOBOComx2AJGZ46RdBExbfd0tTtdHWtRhMsnQchI+WtEyotdAgMBAAGj" + "TTBLMA4GA1UdDwEB/wQEAwIF4DARBgNVHSAECjAIMAYGBFUdIAAwEQYDVR0OBAoECEWZkJ" + "TYQ3z5MBMGA1UdIwQMMAqACGtTrZIwYYHbMA0GCSqGSIb3DQEBBQUAA4GBAHki/TrpHiKW" + "gvERhguQ/uOqHHZNXsog+fgGVFFMOWwJ9bq4aHKd1fDZpyZF4vBxW7llbhuSt+ob2TNlkR" + "wkqzfGL+3xOTKNRgzDwJcil8akC1N5uBftrQk+eL7rM1PezWRM7fIbpmv5ZieIVswtTPF5" + "1Rl3G+JXUBy9E95espls"; public static final String[] TEST_50_DATA = new String[] { Intermediate_Certificate_PP_08_03_crt, Intermediate_CRL_PP_08_03_crl, End_Certificate_PP_08_03_crt }; /* * test51 * */ public static final String Intermediate_Certificate_PP_08_04_crt = "MIICljCCAf+gAwIBAgICAIAwDQYJKoZIhvcNAQEFBQAwXjELMAkGA1UEBhMCVVMxGDAWBg" + "NVBAoTD1UuUy4gR292ZXJubWVudDEMMAoGA1UECxMDRG9EMRAwDgYDVQQLEwdUZXN0aW5n" + "MRUwEwYDVQQDEwxUcnVzdCBBbmNob3IwHhcNOTgwMTAxMTIwMTAwWhcNNDgwMTAxMTIwMT" + "AwWjBeMQswCQYDVQQGEwJVUzEYMBYGA1UEChMPVS5TLiBHb3Zlcm5tZW50MQwwCgYDVQQL" + "EwNEb2QxEDAOBgNVBAsTB1Rlc3RpbmcxFTATBgNVBAMTDENBMS1QUC4wOC4wNDCBnzANBg" + "kqhkiG9w0BAQEFAAOBjQAwgYkCgYEAsrM3A06j1zDz6VuZh+O2UrAPcKtwSA6KxTShUpgr" + "t9UB5iIAEvxcDTwDlubEv/cJjDcFj9N57otzW4ppnuT2ztE4ROmkNb0xL6u00deS1yGjXB" + "wy1G9g8bYDdAXOJlv0tjHOBqXlyKoMny82BOBL2vsCstiqxl14Q3/wBD1w29MCAwEAAaNj" + "MGEwDwYDVR0TAQH/BAUwAwEB/zAOBgNVHQ8BAf8EBAMCAQYwFgYDVR0gBA8wDTALBglghk" + "gBZQMBMAMwEQYDVR0OBAoECJiAkexK6/c7MBMGA1UdIwQMMAqACKua6/nC51SPMA0GCSqG" + "SIb3DQEBBQUAA4GBAL4xwcpXZQPTTPYIQ8CMoVla/5P1x6BPmPqSkvh1D/o4ds9Ll9kHBz" + "//X1ZM8SzYcEO+1r75JUzoHsvDw9yYAk2oclLsCORAPqD8Owhv3jv0QQtYSmf0Sxt5FLx0" + "MRP9keY/DURRf9KitO4glOawtRtYMq2BeeJk1xusY0KqEnQr"; public static final String Intermediate_CRL_PP_08_04_crl = "MIIBSzCBtQIBATANBgkqhkiG9w0BAQUFADBeMQswCQYDVQQGEwJVUzEYMBYGA1UEChMPVS" + "5TLiBHb3Zlcm5tZW50MQwwCgYDVQQLEwNEb2QxEDAOBgNVBAsTB1Rlc3RpbmcxFTATBgNV" + "BAMTDENBMS1QUC4wOC4wNBcNOTkwMTAxMTIwMTAwWhcNNDgwMTAxMTIwMTAwWqAjMCEwCg" + "YDVR0UBAMCAQEwEwYDVR0jBAwwCoAImICR7Err9zswDQYJKoZIhvcNAQEFBQADgYEAcN3a" + "jIEcXsQatb0fvVcFnO7d7lzNtgbqL3MtaqJ/PjkRJ/rO7JAXQRwdajUZF4ECHylZKE2HUG" + "Dk+vidV98T8mNmb0TEuuLV+J1G0q8ezMXRJtDt/2m3y1VBireXlEMd1DdgpsDdCQ4va+XJ" + "qv0TvVhfxWry+LrVb6Bf5ItexXg="; public static final String End_Certificate_PP_08_04_crt = "MIIChzCCAfCgAwIBAgICAIEwDQYJKoZIhvcNAQEFBQAwXjELMAkGA1UEBhMCVVMxGDAWBg" + "NVBAoTD1UuUy4gR292ZXJubWVudDEMMAoGA1UECxMDRG9kMRAwDgYDVQQLEwdUZXN0aW5n" + "MRUwEwYDVQQDEwxDQTEtUFAuMDguMDQwHhcNOTgwMTAxMTIwMTAwWhcNNDgwMTAxMTIwMT" + "AwWjBgMQswCQYDVQQGEwJVUzEYMBYGA1UEChMPVS5TLiBHb3Zlcm5tZW50MQwwCgYDVQQL" + "EwNEb0QxEDAOBgNVBAsTB1Rlc3RpbmcxFzAVBgNVBAMTDlVzZXIxLVBQLjA4LjA0MIGfMA" + "0GCSqGSIb3DQEBAQUAA4GNADCBiQKBgQDPJWa/cB7WW7tkGxFhcwxqE+BycXe3Ru2qGbun" + "NPQZ/j44UT2C6rl1wZwugCY0sR6mXR/P/NR7czZvg4Tt6lwcNtc8PeafFMUeu0u0Kg9uWn" + "fzQQKeIgRVcEzGTGMPGWXS0ed6X/1+Dj8A+T/tqXKUtM3Jpe0pCmm9CIrYCXLPRQIDAQAB" + "o1IwUDAOBgNVHQ8BAf8EBAMCBeAwFgYDVR0gBA8wDTALBglghkgBZQMBMAQwEQYDVR0OBA" + "oECKm9IOyOM1h+MBMGA1UdIwQMMAqACJiAkexK6/c7MA0GCSqGSIb3DQEBBQUAA4GBAEXy" + "dlTkkZaYK6sUJCiPeCPxfj5cdo/G4RGBImMJbTeDyVTvXSH9G2yWUMqBGnYLrwdJJeXjF3" + "89miJgnJ+1r/r3r2/NeAUuJDsOHRMFh0KXFmgubyw/kGsZBe3279hDnND8ZjfQBmKQD17f" + "PycWTTAC5p6GM8tGERiDSnMc5rmm"; public static final String[] TEST_51_DATA = new String[] { Intermediate_Certificate_PP_08_04_crt, Intermediate_CRL_PP_08_04_crl, End_Certificate_PP_08_04_crt }; /* * test52 * */ public static final String Intermediate_Certificate_PP_08_05_crt = "MIICljCCAf+gAwIBAgICAIIwDQYJKoZIhvcNAQEFBQAwXjELMAkGA1UEBhMCVVMxGDAWBg" + "NVBAoTD1UuUy4gR292ZXJubWVudDEMMAoGA1UECxMDRG9EMRAwDgYDVQQLEwdUZXN0aW5n" + "MRUwEwYDVQQDEwxUcnVzdCBBbmNob3IwHhcNOTgwMTAxMTIwMTAwWhcNNDgwMTAxMTIwMT" + "AwWjBeMQswCQYDVQQGEwJVUzEYMBYGA1UEChMPVS5TLiBHb3Zlcm5tZW50MQwwCgYDVQQL" + "EwNEb2QxEDAOBgNVBAsTB1Rlc3RpbmcxFTATBgNVBAMTDENBMS1QUC4wOC4wNTCBnzANBg" + "kqhkiG9w0BAQEFAAOBjQAwgYkCgYEAwH2d+D0pH8y4QJAPpE0s2oWucV1jlE4pBMGNNPJ5" + "FIRmyRCt90IpzmK/EuqT6iSZYd9hIB9wa180ByN67PK1z4loLFMUL2RmbWeAFlGy5eEFOy" + "4d479qfy6JCOzt0TKhYzhukLUqGLa4DDTzvnnUx0o86aLvGq0K5s6DRlNyc08CAwEAAaNj" + "MGEwDwYDVR0TAQH/BAUwAwEB/zAOBgNVHQ8BAf8EBAMCAQYwFgYDVR0gBA8wDTALBglghk" + "gBZQMBMAMwEQYDVR0OBAoECDSeuxr4EVgaMBMGA1UdIwQMMAqACKua6/nC51SPMA0GCSqG" + "SIb3DQEBBQUAA4GBAKoGi6qlODB8Lc86PtGXfBhW769jB8xzgmENE59sqNBEvYa/oK9Xxm" + "1JX1OGEQMq/mqwZXg6hSczpexCIO4tUH8QKTU68yvqcZoZCDV8FLM8aEUPtUoPIpluhAtN" + "scGfb3uXoV9fg7q1Pi5YlKMnNrDIq1tH1CAGKMDRrjW63Q8C"; public static final String Intermediate_CRL_PP_08_05_crl = "MIIBSzCBtQIBATANBgkqhkiG9w0BAQUFADBeMQswCQYDVQQGEwJVUzEYMBYGA1UEChMPVS" + "5TLiBHb3Zlcm5tZW50MQwwCgYDVQQLEwNEb2QxEDAOBgNVBAsTB1Rlc3RpbmcxFTATBgNV" + "BAMTDENBMS1QUC4wOC4wNRcNOTkwMTAxMTIwMTAwWhcNNDgwMTAxMTIwMTAwWqAjMCEwCg" + "YDVR0UBAMCAQEwEwYDVR0jBAwwCoAINJ67GvgRWBowDQYJKoZIhvcNAQEFBQADgYEAv5Hs" + "nYPZO1fGC/Z2lIbbUKjIv0+BrR9HbG+b76wXeJTVxfXMlZe0cpOR/KD29DyxI3G4IedHRy" + "zL8iCDWYbA86arJzl5GZJ1MC2A586vNn/6wiiT6nP3iMj2z/nyvan8L30KNBm9IDXQExOu" + "PNE/wOWYBxxCjg551fpXfJKqDIo="; public static final String End_Certificate_PP_08_05_crt = "MIIChzCCAfCgAwIBAgICAIMwDQYJKoZIhvcNAQEFBQAwXjELMAkGA1UEBhMCVVMxGDAWBg" + "NVBAoTD1UuUy4gR292ZXJubWVudDEMMAoGA1UECxMDRG9kMRAwDgYDVQQLEwdUZXN0aW5n" + "MRUwEwYDVQQDEwxDQTEtUFAuMDguMDUwHhcNOTgwMTAxMTIwMTAwWhcNNDgwMTAxMTIwMT" + "AwWjBgMQswCQYDVQQGEwJVUzEYMBYGA1UEChMPVS5TLiBHb3Zlcm5tZW50MQwwCgYDVQQL" + "EwNEb0QxEDAOBgNVBAsTB1Rlc3RpbmcxFzAVBgNVBAMTDlVzZXIxLVBQLjA4LjA1MIGfMA" + "0GCSqGSIb3DQEBAQUAA4GNADCBiQKBgQC4BZFTwOqI+71v8CdiYbe7x0qYveN524h6+iLh" + "oEqvzuVKVqvQgVSaSLPcMhoCGDv3nqyP57Znl/3I09vLU6F4HKLtjO9E0PZu8EXOKLjeWP" + "XmJQkdHfODj/TrrWSsrdorl7s7gdWEUFlbiWvUVUtkqLNbGLJZ5Q1xZvBRLS7loQIDAQAB" + "o1IwUDAOBgNVHQ8BAf8EBAMCBeAwFgYDVR0gBA8wDTALBglghkgBZQMBMAMwEQYDVR0OBA" + "oECBDaTXbN11BBMBMGA1UdIwQMMAqACDSeuxr4EVgaMA0GCSqGSIb3DQEBBQUAA4GBAGVa" + "QNtd4LgoVZQ+Uy1lSr6sog4fsGaoQJCZcvrMJwGpMF0FJsGtOb0R2mfwHi1YXqPF5qZY2I" + "7cVbwVtRQzbXunk1z12k0iIesMtYUncxb/SBstC7VNS8HNZm9ese+YM6Ac8mGT+IUZsPcP" + "gI9fQ1L/2u+/3L4fweca1R45xm5M"; public static final String[] TEST_52_DATA = new String[] { Intermediate_Certificate_PP_08_05_crt, Intermediate_CRL_PP_08_05_crl, End_Certificate_PP_08_05_crt }; /* * test53 * */ public static final String Intermediate_Certificate_PP_08_06_crt = "MIICsDCCAhmgAwIBAgICAIQwDQYJKoZIhvcNAQEFBQAwXjELMAkGA1UEBhMCVVMxGDAWBg" + "NVBAoTD1UuUy4gR292ZXJubWVudDEMMAoGA1UECxMDRG9EMRAwDgYDVQQLEwdUZXN0aW5n" + "MRUwEwYDVQQDEwxUcnVzdCBBbmNob3IwHhcNOTgwMTAxMTIwMTAwWhcNNDgwMTAxMTIwMT" + "AwWjBeMQswCQYDVQQGEwJVUzEYMBYGA1UEChMPVS5TLiBHb3Zlcm5tZW50MQwwCgYDVQQL" + "EwNEb2QxEDAOBgNVBAsTB1Rlc3RpbmcxFTATBgNVBAMTDENBMS1QUC4wOC4wNjCBnzANBg" + "kqhkiG9w0BAQEFAAOBjQAwgYkCgYEAlSIH/+6DEL1P9tkgbsI2PcW0w9dmqMTLP3jKYPsr" + "sSWI5bcv55sk6RItVr3hGgkaskZoHeamUBAiGPksVyrqmRwSCJzQDLnLdMnjjudvPjp1ZZ" + "9UCufTtMPFvnEuVBx5e8A13AQ4OyHqaJgWRVoRJd6vwTa5jzfYCCMJZHHKpcUCAwEAAaN9" + "MHswDwYDVR0TAQH/BAUwAwEB/zAOBgNVHQ8BAf8EBAMCAQYwMAYDVR0gBCkwJzALBglghk" + "gBZQMBMAEwCwYJYIZIAWUDATACMAsGCWCGSAFlAwEwAzARBgNVHQ4ECgQI8837JGF7vMAw" + "EwYDVR0jBAwwCoAIq5rr+cLnVI8wDQYJKoZIhvcNAQEFBQADgYEAKmgbxzWI6V2twYDp65" + "Gu8zn883CnI08s2FEVupvrKduxYmg+ZDkTBE3ZJFxcOuxJf58MRfDWy8C4jJhLnT3JSSSg" + "sY3n93jzc0s2h5y2wd1bUTDLqhqWCshisDG/88rpv938O8luiUEwltolzKTa+ScA6nXSQt" + "LT4I6O3vbTx2g="; public static final String Intermediate_CRL_PP_08_06_crl = "MIIBSzCBtQIBATANBgkqhkiG9w0BAQUFADBeMQswCQYDVQQGEwJVUzEYMBYGA1UEChMPVS" + "5TLiBHb3Zlcm5tZW50MQwwCgYDVQQLEwNEb2QxEDAOBgNVBAsTB1Rlc3RpbmcxFTATBgNV" + "BAMTDENBMS1QUC4wOC4wNhcNOTkwMTAxMTIwMTAwWhcNNDgwMTAxMTIwMTAwWqAjMCEwCg" + "YDVR0UBAMCAQEwEwYDVR0jBAwwCoAI8837JGF7vMAwDQYJKoZIhvcNAQEFBQADgYEAHua+" + "lC3wP4G6796jjr6wuu7xEQqY1azsLVsGtL7YL8fm42rl7hgU40SuFIc7Kc+A7oEEkKgvmu" + "SLMIv7q5O8J26fQOuduGWQAncPYB8w7sNWjCZbdjVbjp1XIApcAL3djCbLZ8/NYsCoOuwx" + "hRQKX1hIn+rNDi1DMD4H99QdDGE="; public static final String End_Certificate_PP_08_06_crt = "MIICoTCCAgqgAwIBAgICAIUwDQYJKoZIhvcNAQEFBQAwXjELMAkGA1UEBhMCVVMxGDAWBg" + "NVBAoTD1UuUy4gR292ZXJubWVudDEMMAoGA1UECxMDRG9kMRAwDgYDVQQLEwdUZXN0aW5n" + "MRUwEwYDVQQDEwxDQTEtUFAuMDguMDYwHhcNOTgwMTAxMTIwMTAwWhcNNDgwMTAxMTIwMT" + "AwWjBgMQswCQYDVQQGEwJVUzEYMBYGA1UEChMPVS5TLiBHb3Zlcm5tZW50MQwwCgYDVQQL" + "EwNEb0QxEDAOBgNVBAsTB1Rlc3RpbmcxFzAVBgNVBAMTDlVzZXIxLVBQLjA4LjA2MIGfMA" + "0GCSqGSIb3DQEBAQUAA4GNADCBiQKBgQDnaYU/lu+u+LmLQwyACSsRyxQEEvgriE7ApmHj" + "sNBcd3lovFQMfw9MyOOMsInOgQZU8p/invnhx11/pwi77ViQQ780unhHt5H/tteaYwcsDR" + "cUxR/8jK0DBnbVWvm8S/NGb8BxfbRmDHBTWGZ70hDSCJypWRfHQj0I/SAqAW/VuwIDAQAB" + "o2wwajAOBgNVHQ8BAf8EBAMCBeAwMAYDVR0gBCkwJzALBglghkgBZQMBMAEwCwYJYIZIAW" + "UDATACMAsGCWCGSAFlAwEwAzARBgNVHQ4ECgQIhh/KikcKA7EwEwYDVR0jBAwwCoAI8837" + "JGF7vMAwDQYJKoZIhvcNAQEFBQADgYEAbHK3lkqbGy61lu9d22uO2H3hzwvjmlccZo8pro" + "ord45d2nRIxw2ag4dS1YRFrefVdxZtKeR9+5o+tQtvmTcDOer4u6NZ/sVVElTb1d6axtL0" + "i4cmqv6bGWYECEwtwmPGqAavp9pPZjNRbkBGy9qhVNTXfDQYpA8yzXWO/xUrwNU="; public static final String[] TEST_53_DATA = new String[] { Intermediate_Certificate_PP_08_06_crt, Intermediate_CRL_PP_08_06_crl, End_Certificate_PP_08_06_crt }; /* * test54 * */ public static final String Intermediate_Certificate_1_PL_01_01_crt = "MIICmTCCAgKgAwIBAgICAIYwDQYJKoZIhvcNAQEFBQAwXjELMAkGA1UEBhMCVVMxGDAWBg" + "NVBAoTD1UuUy4gR292ZXJubWVudDEMMAoGA1UECxMDRG9EMRAwDgYDVQQLEwdUZXN0aW5n" + "MRUwEwYDVQQDEwxUcnVzdCBBbmNob3IwHhcNOTgwMTAxMTIwMTAwWhcNNDgwMTAxMTIwMT" + "AwWjBeMQswCQYDVQQGEwJVUzEYMBYGA1UEChMPVS5TLiBHb3Zlcm5tZW50MQwwCgYDVQQL" + "EwNEb2QxEDAOBgNVBAsTB1Rlc3RpbmcxFTATBgNVBAMTDENBMS1QTC4wMS4wMTCBnzANBg" + "kqhkiG9w0BAQEFAAOBjQAwgYkCgYEAxDV2d7qXbpCvOzBimskBLsgexpEYaHv0s7gOaqhC" + "4A3K8sxdjyW6QdGZhKX8tCMqnlPp9CNbpY4tQQ5oTSk5pj6HwAsTfGcDwXJnjKWx1FJ7rD" + "meZZ8c2K7a8voBl6FoPGn8CMhO0WmM9Eyb/vDUPdCZzScb+z/BxTcV1BPFdq0CAwEAAaNm" + "MGQwEgYDVR0TAQH/BAgwBgEB/wIBADAOBgNVHQ8BAf8EBAMCAQYwFgYDVR0gBA8wDTALBg" + "lghkgBZQMBMAEwEQYDVR0OBAoECBpj0+Gcq32oMBMGA1UdIwQMMAqACKua6/nC51SPMA0G" + "CSqGSIb3DQEBBQUAA4GBAB/9veHrkLeu8jkwXggJtwqPTmkrIBcX+pz85BTSETYeLOzF46" + "onk+qt+IHptlrm3D7ny2Y5M0dQQ6tPzhGZxCEg9RoDibZGtsx+qeAh1ZjeEpEcQyp/idWY" + "asH+EIuEIOZA9c1ySxI/3v3ZfzaSGS8jsgSDkLB4JumrE9ZkLNd1"; public static final String Intermediate_Certificate_2_PL_01_01_crt = "MIICljCCAf+gAwIBAgICAIcwDQYJKoZIhvcNAQEFBQAwXjELMAkGA1UEBhMCVVMxGDAWBg" + "NVBAoTD1UuUy4gR292ZXJubWVudDEMMAoGA1UECxMDRG9kMRAwDgYDVQQLEwdUZXN0aW5n" + "MRUwEwYDVQQDEwxDQTEtUEwuMDEuMDEwHhcNOTgwMTAxMTIwMTAwWhcNNDgwMTAxMTIwMT" + "AwWjBeMQswCQYDVQQGEwJVUzEYMBYGA1UEChMPVS5TLiBHb3Zlcm5tZW50MQwwCgYDVQQL" + "EwNEb2QxEDAOBgNVBAsTB1Rlc3RpbmcxFTATBgNVBAMTDENBMi1QTC4wMS4wMTCBnzANBg" + "kqhkiG9w0BAQEFAAOBjQAwgYkCgYEA3B3UKG3tEL6FQz6dL6iqSvzgGsm1Fg5uzK8npkEq" + "g2caUM7huYFfXeur1mu6iKiROcGX8ZYxrPi9Orh39YVrSu2EUWvqQui4QScf4dIlzAOunv" + "0gAa/lIVTHgZhIomKND6/tZLU251dJiFhoV6bXx2tor83vWFVPx2oVd5LL5S0CAwEAAaNj" + "MGEwDwYDVR0TAQH/BAUwAwEB/zAOBgNVHQ8BAf8EBAMCAQYwFgYDVR0gBA8wDTALBglghk" + "gBZQMBMAEwEQYDVR0OBAoECJmK3jFTIl6lMBMGA1UdIwQMMAqACBpj0+Gcq32oMA0GCSqG" + "SIb3DQEBBQUAA4GBADkYLTg4RncTpAFmpUy7WGOMvoFV15nDoi91OMxhxVkbGSE0DJFxi3" + "hPKcfUNvzy0bEUUTaqOXdbIkoLTG77NTckJxurSRyam0jA0+6SUYZ6F9fVotwMul2EiVl9" + "XP5oCt7LkgqVgMASuwfzMnQozB6Oi/YP2OdSPXLipI6rl2dx"; public static final String Intermediate_CRL_1_PL_01_01_crl = "MIIBSzCBtQIBATANBgkqhkiG9w0BAQUFADBeMQswCQYDVQQGEwJVUzEYMBYGA1UEChMPVS" + "5TLiBHb3Zlcm5tZW50MQwwCgYDVQQLEwNEb2QxEDAOBgNVBAsTB1Rlc3RpbmcxFTATBgNV" + "BAMTDENBMS1QTC4wMS4wMRcNOTkwMTAxMTIwMTAwWhcNNDgwMTAxMTIwMTAwWqAjMCEwCg" + "YDVR0UBAMCAQEwEwYDVR0jBAwwCoAIGmPT4ZyrfagwDQYJKoZIhvcNAQEFBQADgYEAd8YZ" + "8jibr8yjcGYSDicJuyUvHBZntTVQ1sP5XVmtCZcYcQCVjbC0auYTEP5snXbGPW5qeEaaXB" + "MhekMr776hP4Kl3g4AjguFl3XQGcURlgNd8LsTpMMdNWC7XwooOF2FzFjD1ru0BSEWabzW" + "NNaVeuMMbu2N0lc6NDJvRC8LkhA="; public static final String Intermediate_CRL_2_PL_01_01_crl = "MIIBSzCBtQIBATANBgkqhkiG9w0BAQUFADBeMQswCQYDVQQGEwJVUzEYMBYGA1UEChMPVS" + "5TLiBHb3Zlcm5tZW50MQwwCgYDVQQLEwNEb2QxEDAOBgNVBAsTB1Rlc3RpbmcxFTATBgNV" + "BAMTDENBMi1QTC4wMS4wMRcNOTkwMTAxMTIwMTAwWhcNNDgwMTAxMTIwMTAwWqAjMCEwCg" + "YDVR0UBAMCAQEwEwYDVR0jBAwwCoAImYreMVMiXqUwDQYJKoZIhvcNAQEFBQADgYEAZFec" + "GtjOfp8pT0n1dMF/x9n8y5tM+G3LLnZvDJspLc/sqP3E3B/sHBiis81caEkQQAOTBU5goJ" + "0KOFAUOfEq+IX5uvNhuPuinx0OsSak+2Annvi12zodMQKPNm1uMVt2bMHHHZVEVTqcv36g" + "xgdbp0YKTmuvSy6s8NtGFpkNmnU="; public static final String End_Certificate_PL_01_01_crt = "MIIChzCCAfCgAwIBAgICAIgwDQYJKoZIhvcNAQEFBQAwXjELMAkGA1UEBhMCVVMxGDAWBg" + "NVBAoTD1UuUy4gR292ZXJubWVudDEMMAoGA1UECxMDRG9kMRAwDgYDVQQLEwdUZXN0aW5n" + "MRUwEwYDVQQDEwxDQTItUEwuMDEuMDEwHhcNOTgwMTAxMTIwMTAwWhcNNDgwMTAxMTIwMT" + "AwWjBgMQswCQYDVQQGEwJVUzEYMBYGA1UEChMPVS5TLiBHb3Zlcm5tZW50MQwwCgYDVQQL" + "EwNEb0QxEDAOBgNVBAsTB1Rlc3RpbmcxFzAVBgNVBAMTDlVzZXIxLVBMLjAxLjAxMIGfMA" + "0GCSqGSIb3DQEBAQUAA4GNADCBiQKBgQDCAUPp5j4V5XTA44Ra1EWkp9HgS4w3uXJ7/Vhi" + "K5bARFrDOOxjV8nmr5hoUYr4jwdi2Rl+60TQK/F08gdcGxdyc9p/yiU5HyAP6i+4iqmvaW" + "9b2egNyZ5tOmpl/Q9FSFWa9d/PYBKM5Sj/r73RtA+/chc4uq3uyLekSRQGh1MieQIDAQAB" + "o1IwUDAOBgNVHQ8BAf8EBAMCBeAwFgYDVR0gBA8wDTALBglghkgBZQMBMAEwEQYDVR0OBA" + "oECAiL3A4CkaFyMBMGA1UdIwQMMAqACJmK3jFTIl6lMA0GCSqGSIb3DQEBBQUAA4GBAJtH" + "mNNvCt/0uFbHdvUvCuBeZ9cggfpTyUS4X8zgcLDPFbw6VvX65umOZpceZI6hwcre+LZahi" + "gUEPvXppncEObkeVTcYdOTSDoxh5tZyee1P4sbD9H+suGWeewqUDvFs2ymHtxlkpOttitR" + "xQc2U6VlCuZ4XU8SwucyhW0z51e4"; public static final String[] TEST_54_DATA = new String[] { Intermediate_Certificate_1_PL_01_01_crt, Intermediate_Certificate_2_PL_01_01_crt, Intermediate_CRL_1_PL_01_01_crl, Intermediate_CRL_2_PL_01_01_crl, End_Certificate_PL_01_01_crt }; /* * test55 * */ public static final String Intermediate_Certificate_1_PL_01_02_crt = "MIICmTCCAgKgAwIBAgICAIkwDQYJKoZIhvcNAQEFBQAwXjELMAkGA1UEBhMCVVMxGDAWBg" + "NVBAoTD1UuUy4gR292ZXJubWVudDEMMAoGA1UECxMDRG9EMRAwDgYDVQQLEwdUZXN0aW5n" + "MRUwEwYDVQQDEwxUcnVzdCBBbmNob3IwHhcNOTgwMTAxMTIwMTAwWhcNNDgwMTAxMTIwMT" + "AwWjBeMQswCQYDVQQGEwJVUzEYMBYGA1UEChMPVS5TLiBHb3Zlcm5tZW50MQwwCgYDVQQL" + "EwNEb2QxEDAOBgNVBAsTB1Rlc3RpbmcxFTATBgNVBAMTDENBMS1QTC4wMS4wMjCBnzANBg" + "kqhkiG9w0BAQEFAAOBjQAwgYkCgYEA4QmGXEeVKCn1aQx27r+EBuQqfi8fP7gyV5JLkaSu" + "DOUrqXg8dQxHsBNCf3XilGIvjNFZjVUPdS8FNqC+if9D164VyGQlv/JUor/GlvwVfyotUO" + "U1PqSzFrAALYTmfm/ZqhMvGYloStSDxlzjDmyKadskzOxZZDNSe5s8dvUpYn0CAwEAAaNm" + "MGQwEgYDVR0TAQH/BAgwBgEB/wIBADAOBgNVHQ8BAf8EBAMCAQYwFgYDVR0gBA8wDTALBg" + "lghkgBZQMBMAEwEQYDVR0OBAoECGk7qDbbBgRbMBMGA1UdIwQMMAqACKua6/nC51SPMA0G" + "CSqGSIb3DQEBBQUAA4GBAD+eI+jg4jmeC3pJRGEF/hbPPYvL6aocjqqbZyNKN5FWItccQo" + "PWg/GK1GpusDZadesZBDo6fLIUJzL+OumrIYJLB3HxQsmyOXB1gRg1hcva71RWFJYzx01U" + "eB8lCbk8Zu24HzLzqjfVuwKOFFELWDEq7bd6Re/aKSHtNnDbsgSE"; public static final String Intermediate_Certificate_2_PL_01_02_crt = "MIICljCCAf+gAwIBAgICAIowDQYJKoZIhvcNAQEFBQAwXjELMAkGA1UEBhMCVVMxGDAWBg" + "NVBAoTD1UuUy4gR292ZXJubWVudDEMMAoGA1UECxMDRG9kMRAwDgYDVQQLEwdUZXN0aW5n" + "MRUwEwYDVQQDEwxDQTEtUEwuMDEuMDIwHhcNOTgwMTAxMTIwMTAwWhcNNDgwMTAxMTIwMT" + "AwWjBeMQswCQYDVQQGEwJVUzEYMBYGA1UEChMPVS5TLiBHb3Zlcm5tZW50MQwwCgYDVQQL" + "EwNEb2QxEDAOBgNVBAsTB1Rlc3RpbmcxFTATBgNVBAMTDENBMi1QTC4wMS4wMjCBnzANBg" + "kqhkiG9w0BAQEFAAOBjQAwgYkCgYEAl/HiHoos7eHaDIFhMmvIPk63UT33Z+0iiCIuKLW7" + "tgkT8ia1Yg++np1pC3oqYVeKkXqMcjgonPGQhcek12vLt3/+2PYyYirOTVZaiO9pKQ5An8" + "ZMWXIJmCEAMHabPO1RnetvRv5JZFxZY9jIUnD2fUADzzUh/eHN6Pur0DDrI6sCAwEAAaNj" + "MGEwDwYDVR0TAQH/BAUwAwEB/zAOBgNVHQ8BAf8EBAMCAQYwFgYDVR0gBA8wDTALBglghk" + "gBZQMBMAEwEQYDVR0OBAoECPk0C10KQLZuMBMGA1UdIwQMMAqACGk7qDbbBgRbMA0GCSqG" + "SIb3DQEBBQUAA4GBAMJ4+BZQxpxWhNbo8bpGkbbcKT3kfKYrHjHsZADC+/gAJSVL854b1W" + "VKsGr1YcCX10V1Gcqb6Jgziy+AzRLhcJngszcz0A7LxrMH+FIyWEPgZnOyQCa8B/9bnsh9" + "bC1gEmXGOVtWboIFOEdGghEbm/ENnQyj+HbIk3jhF3QYbXhw"; public static final String Intermediate_CRL_1_PL_01_02_crl = "MIIBSzCBtQIBATANBgkqhkiG9w0BAQUFADBeMQswCQYDVQQGEwJVUzEYMBYGA1UEChMPVS" + "5TLiBHb3Zlcm5tZW50MQwwCgYDVQQLEwNEb2QxEDAOBgNVBAsTB1Rlc3RpbmcxFTATBgNV" + "BAMTDENBMS1QTC4wMS4wMhcNOTkwMTAxMTIwMTAwWhcNNDgwMTAxMTIwMTAwWqAjMCEwCg" + "YDVR0UBAMCAQEwEwYDVR0jBAwwCoAIaTuoNtsGBFswDQYJKoZIhvcNAQEFBQADgYEAZEt+" + "FjRuXgnOZg70geqS4hVsF1VWWawlAVGmjPsbRH7rADXPUE2bYL54wLdwt/6QYwHqy2KwCf" + "d4OkWkwn9xwGS4j+XBCw9Y4nbWI+wrsZ9W7vgbeIaVUUUZu6hoin1GxrGDcfbM+bhYzQAA" + "gNmKIWdlJ4tKD2KNgg0KmZPoj/k="; public static final String Intermediate_CRL_2_PL_01_02_crl = "MIIBSzCBtQIBATANBgkqhkiG9w0BAQUFADBeMQswCQYDVQQGEwJVUzEYMBYGA1UEChMPVS" + "5TLiBHb3Zlcm5tZW50MQwwCgYDVQQLEwNEb2QxEDAOBgNVBAsTB1Rlc3RpbmcxFTATBgNV" + "BAMTDENBMi1QTC4wMS4wMhcNOTkwMTAxMTIwMTAwWhcNNDgwMTAxMTIwMTAwWqAjMCEwCg" + "YDVR0UBAMCAQEwEwYDVR0jBAwwCoAI+TQLXQpAtm4wDQYJKoZIhvcNAQEFBQADgYEAXwZO" + "wr9mrO6yUOoopNjcIcDssCUksYco1PFgWx9O/hGq9ktdoGoGcECGhdkHTLe2ab3WFl9jzW" + "1/lkysD9Jl3VjbnbRB3dPQlrSfiv7cYBLnfKvyF/CxQg/wCtWo46GJJQgOx/WHzi9aF08m" + "tQuJEtl7RgoByUSvLtmvKjQWEnc="; public static final String End_Certificate_PL_01_02_crt = "MIICljCCAf+gAwIBAgICAIswDQYJKoZIhvcNAQEFBQAwXjELMAkGA1UEBhMCVVMxGDAWBg" + "NVBAoTD1UuUy4gR292ZXJubWVudDEMMAoGA1UECxMDRG9kMRAwDgYDVQQLEwdUZXN0aW5n" + "MRUwEwYDVQQDEwxDQTItUEwuMDEuMDIwHhcNOTgwMTAxMTIwMTAwWhcNNDgwMTAxMTIwMT" + "AwWjBeMQswCQYDVQQGEwJVUzEYMBYGA1UEChMPVS5TLiBHb3Zlcm5tZW50MQwwCgYDVQQL" + "EwNEb2QxEDAOBgNVBAsTB1Rlc3RpbmcxFTATBgNVBAMTDENBMy1QTC4wMS4wMjCBnzANBg" + "kqhkiG9w0BAQEFAAOBjQAwgYkCgYEA0/rXOZwUebRaHcPPFeKTB2OWIzIAgavqb5HerPAe" + "c3sJCdNOSLc0OX0dFblso97WR8uueF9I7QeGg3ayQjzDVqm5Tu77ZaCuyb6UU8+fY2eqwD" + "5lCVuLfJr9U2JD5b2TcdvAD9RqfhefclVjDj9rObLjvzLg3AefO3drsfBtAIMCAwEAAaNj" + "MGEwDwYDVR0TAQH/BAUwAwEB/zAOBgNVHQ8BAf8EBAMCAeYwFgYDVR0gBA8wDTALBglghk" + "gBZQMBMAEwEQYDVR0OBAoECDBWCFTOp3evMBMGA1UdIwQMMAqACPk0C10KQLZuMA0GCSqG" + "SIb3DQEBBQUAA4GBAI/JpU3gHo8Izsbjlx6bkQo/e/hD634N5lSMtVHIGnoVLu99dvroRu" + "2DO8Fhnv6VZpMvYoAc5oEgUqx9hw3bfS/XN9GXaeMssjwN/qM6lzCsvMG7DA9sf59xjf4Y" + "2+u4KTye4PdpmWaseDDJ1wAihTHEaofnQdaoUffxQgw5UcAf"; public static final String[] TEST_55_DATA = new String[] { Intermediate_Certificate_1_PL_01_02_crt, Intermediate_Certificate_2_PL_01_02_crt, Intermediate_CRL_1_PL_01_02_crl, Intermediate_CRL_2_PL_01_02_crl, End_Certificate_PL_01_02_crt }; /* * test56 * */ public static final String Intermediate_Certificate_PL_01_03_crt = "MIICmTCCAgKgAwIBAgICAIwwDQYJKoZIhvcNAQEFBQAwXjELMAkGA1UEBhMCVVMxGDAWBg" + "NVBAoTD1UuUy4gR292ZXJubWVudDEMMAoGA1UECxMDRG9EMRAwDgYDVQQLEwdUZXN0aW5n" + "MRUwEwYDVQQDEwxUcnVzdCBBbmNob3IwHhcNOTgwMTAxMTIwMTAwWhcNNDgwMTAxMTIwMT" + "AwWjBeMQswCQYDVQQGEwJVUzEYMBYGA1UEChMPVS5TLiBHb3Zlcm5tZW50MQwwCgYDVQQL" + "EwNEb2QxEDAOBgNVBAsTB1Rlc3RpbmcxFTATBgNVBAMTDENBMS1QTC4wMS4wMzCBnzANBg" + "kqhkiG9w0BAQEFAAOBjQAwgYkCgYEA60y6V2WkNCB34dcGfu+Jo3YHQZXzgp76+HgnyFmP" + "DLj9DjZHqifD3gW8Zk7L+yK4PfLDSHjbrXM9GY1ser6XwhaJQDPUBBYW5X3XTOmDWmV63J" + "YeRF5r7cfF2h3eEZ460GRLK5tt0Zr8V+hA9oOvwqynrIhDYC/tCzE28ciqA+sCAwEAAaNm" + "MGQwEgYDVR0TAQH/BAgwBgEB/wIBADAOBgNVHQ8BAf8EBAMCAQYwFgYDVR0gBA8wDTALBg" + "lghkgBZQMBMAEwEQYDVR0OBAoECPE2FCetVerZMBMGA1UdIwQMMAqACKua6/nC51SPMA0G" + "CSqGSIb3DQEBBQUAA4GBABUOUWwyfyrRIw7dRIVfLlWyp5R1I+Kmq5e8st0AEMVpPAmLoy" + "0s+46Xf+THXZy5em1P3bSVTSUhTs+XD6tbFFUcTrX0mQJlshR7yD/A0siMDUNzzt9LJQvP" + "dwNjQSA2keOrV9q/2CAGce4daL4Wz54jfh33YVqJ8sHT4E8CxQb7"; public static final String Intermediate_CRL_PL_01_03_crl = "MIIBSzCBtQIBATANBgkqhkiG9w0BAQUFADBeMQswCQYDVQQGEwJVUzEYMBYGA1UEChMPVS" + "5TLiBHb3Zlcm5tZW50MQwwCgYDVQQLEwNEb2QxEDAOBgNVBAsTB1Rlc3RpbmcxFTATBgNV" + "BAMTDENBMS1QTC4wMS4wMxcNOTkwMTAxMTIwMTAwWhcNNDgwMTAxMTIwMTAwWqAjMCEwCg" + "YDVR0UBAMCAQEwEwYDVR0jBAwwCoAI8TYUJ61V6tkwDQYJKoZIhvcNAQEFBQADgYEA6FnB" + "LXWt4B/3oP0PXERYh7ZV39yu/tm9DHBQGcGDF8JIspU7F+mH/+37U/lT6BQxpKOpgOgGeP" + "nTQeQzN9sRsXxFO22SkHbdPCao84qvv485epgzqFcVsCRBwBBLcnNLMg891q0EYsTW9vSw" + "Dx7V4CawyYAYGz1MqYuY6SSs6Q0="; public static final String End_Certificate_PL_01_03_crt = "MIIChzCCAfCgAwIBAgICAI0wDQYJKoZIhvcNAQEFBQAwXjELMAkGA1UEBhMCVVMxGDAWBg" + "NVBAoTD1UuUy4gR292ZXJubWVudDEMMAoGA1UECxMDRG9kMRAwDgYDVQQLEwdUZXN0aW5n" + "MRUwEwYDVQQDEwxDQTEtUEwuMDEuMDMwHhcNOTgwMTAxMTIwMTAwWhcNNDgwMTAxMTIwMT" + "AwWjBgMQswCQYDVQQGEwJVUzEYMBYGA1UEChMPVS5TLiBHb3Zlcm5tZW50MQwwCgYDVQQL" + "EwNEb0QxEDAOBgNVBAsTB1Rlc3RpbmcxFzAVBgNVBAMTDlVzZXIxLVBMLjAxLjAzMIGfMA" + "0GCSqGSIb3DQEBAQUAA4GNADCBiQKBgQCwt6B9gpDz/x/vnowXf1MdkAPeaCWZ3pYikgxE" + "ZLrMuulFaI1UDnAzgSuSvoHE80VKGKjSkrzIX9OFfeilW5rNZAXoZrjtkaJd1Q8l5AtjFn" + "0tlLytDzIMYo5Tiq/n3IiTdbEzGYzEOCcSyVaQdB7K1WgYI/z/UAaWV/GbqCX1zQIDAQAB" + "o1IwUDAOBgNVHQ8BAf8EBAMCBeAwFgYDVR0gBA8wDTALBglghkgBZQMBMAEwEQYDVR0OBA" + "oECMQHLiufEm0IMBMGA1UdIwQMMAqACPE2FCetVerZMA0GCSqGSIb3DQEBBQUAA4GBAD5/" + "vGn/rpoHvny/mfh6n2zVNNQLTEBiddfAdCWpeBFcwxS5lpxfm4dAWgHhprZTMirF9yS+wO" + "wWQ4G9/wiqfAtoaNN1qkHMlUMOAPsOSff6ClgP+1uzKVqQa9NTd5HAeMdYfYjMa/fcF/37" + "plCs5ZsJjb9lhEjNd/tq4/aALQmt"; public static final String[] TEST_56_DATA = new String[] { Intermediate_Certificate_PL_01_03_crt, Intermediate_CRL_PL_01_03_crl, End_Certificate_PL_01_03_crt }; /* * test57 * */ public static final String Intermediate_Certificate_PL_01_04_crt = "MIICmTCCAgKgAwIBAgICAI4wDQYJKoZIhvcNAQEFBQAwXjELMAkGA1UEBhMCVVMxGDAWBg" + "NVBAoTD1UuUy4gR292ZXJubWVudDEMMAoGA1UECxMDRG9EMRAwDgYDVQQLEwdUZXN0aW5n" + "MRUwEwYDVQQDEwxUcnVzdCBBbmNob3IwHhcNOTgwMTAxMTIwMTAwWhcNNDgwMTAxMTIwMT" + "AwWjBeMQswCQYDVQQGEwJVUzEYMBYGA1UEChMPVS5TLiBHb3Zlcm5tZW50MQwwCgYDVQQL" + "EwNEb2QxEDAOBgNVBAsTB1Rlc3RpbmcxFTATBgNVBAMTDENBMS1QTC4wMS4wNDCBnzANBg" + "kqhkiG9w0BAQEFAAOBjQAwgYkCgYEA06yd2NQEAgpv0kQQEOzhHHU4YqHgtvJgkdLYxb2W" + "Zordrm4b/43UDnLmsI0790V76y9Aa+Y8SIMBBRBJgnlppFJrFsPaOMO98M3/mXkQotVbY1" + "59P/AjWMxpzP9h8Bs8KuoPqnl5jN0UZAF4kRoNXHzyS445VBp4DtWz/jcCPm8CAwEAAaNm" + "MGQwEgYDVR0TAQH/BAgwBgEB/wIBADAOBgNVHQ8BAf8EBAMCAQYwFgYDVR0gBA8wDTALBg" + "lghkgBZQMBMAEwEQYDVR0OBAoECHxLORDZ1KKNMBMGA1UdIwQMMAqACKua6/nC51SPMA0G" + "CSqGSIb3DQEBBQUAA4GBACHmDOaoC0Hr2cmfuQvdyGDF7/RlvTUJ7cvGypCa724SwAZGZk" + "Tf5GwxgjVcLHY5RlX2kDm9vjneDzP88U3587qA2ZRwxhheK0RGp1kudNQ5y2gAGKZ7YSc0" + "SENMDxUAa6HUkn9Rfo4rf5ULuGNJZXQZ3DtP+lZSwzkUeCVjKhyQ"; public static final String Intermediate_CRL_PL_01_04_crl = "MIIBSzCBtQIBATANBgkqhkiG9w0BAQUFADBeMQswCQYDVQQGEwJVUzEYMBYGA1UEChMPVS" + "5TLiBHb3Zlcm5tZW50MQwwCgYDVQQLEwNEb2QxEDAOBgNVBAsTB1Rlc3RpbmcxFTATBgNV" + "BAMTDENBMS1QTC4wMS4wNBcNOTkwMTAxMTIwMTAwWhcNNDgwMTAxMTIwMTAwWqAjMCEwCg" + "YDVR0UBAMCAQEwEwYDVR0jBAwwCoAIfEs5ENnUoo0wDQYJKoZIhvcNAQEFBQADgYEAb8lX" + "19SlVNRkc9SKNpRLZQom67djZfMSIPIDkBALfMepdevbquzgO7AufTuiDn5Zqe6J6odTv6" + "RrQReo64XB4+Lx2pXOe8bZEbzZk0HvzLl9DjN7zxyNglNK+Hd2xS4yT4ps4fBdvXvWAXEx" + "6DfvWHbGFDoH2auomCKJtCVXxCI="; public static final String End_Certificate_PL_01_04_crt = "MIICljCCAf+gAwIBAgICAI8wDQYJKoZIhvcNAQEFBQAwXjELMAkGA1UEBhMCVVMxGDAWBg" + "NVBAoTD1UuUy4gR292ZXJubWVudDEMMAoGA1UECxMDRG9kMRAwDgYDVQQLEwdUZXN0aW5n" + "MRUwEwYDVQQDEwxDQTEtUEwuMDEuMDQwHhcNOTgwMTAxMTIwMTAwWhcNNDgwMTAxMTIwMT" + "AwWjBeMQswCQYDVQQGEwJVUzEYMBYGA1UEChMPVS5TLiBHb3Zlcm5tZW50MQwwCgYDVQQL" + "EwNEb2QxEDAOBgNVBAsTB1Rlc3RpbmcxFTATBgNVBAMTDENBMi1QTC4wMS4wNDCBnzANBg" + "kqhkiG9w0BAQEFAAOBjQAwgYkCgYEA14bXc39XiWvb4r1jzbADzrpfbg2Y9sGBkefSQHsM" + "QZ1SRLR7uexWD7MuDYh4ZYBL+WPhaJJr3a1jnAIp54h68m8mwS13DgrxBF2/hrVKEm9IRG" + "s13hoM4Mjjogn/Lvc1xLvB5lctHjZrNRZjyrt+PqDDmqZqgCOmcD61PhrfAoECAwEAAaNj" + "MGEwDwYDVR0TAQH/BAUwAwEB/zAOBgNVHQ8BAf8EBAMCAeYwFgYDVR0gBA8wDTALBglghk" + "gBZQMBMAEwEQYDVR0OBAoECB9hXgJfzBvTMBMGA1UdIwQMMAqACHxLORDZ1KKNMA0GCSqG" + "SIb3DQEBBQUAA4GBAB0HgiURRd/REVfc5DenIPhMu8riVcwVgTUwatsCWragUhXpCtvJmf" + "z4vGo1rKYai2dltVX6am+NDvN5tROcM0bvC8lOCc/iPfI5eWTy9SJ2nxvs1+q809Rj0rno" + "zS77TIE8rD7Q8ZUd3qNUiBwdjBoc9misgyN7zUulg4Ueebvv"; public static final String[] TEST_57_DATA = new String[] { Intermediate_Certificate_PL_01_04_crt, Intermediate_CRL_PL_01_04_crl, End_Certificate_PL_01_04_crt }; /* * test58 * */ public static final String Intermediate_Certificate_1_PL_01_05_crt = "MIICmTCCAgKgAwIBAgICAJAwDQYJKoZIhvcNAQEFBQAwXjELMAkGA1UEBhMCVVMxGDAWBg" + "NVBAoTD1UuUy4gR292ZXJubWVudDEMMAoGA1UECxMDRG9EMRAwDgYDVQQLEwdUZXN0aW5n" + "MRUwEwYDVQQDEwxUcnVzdCBBbmNob3IwHhcNOTgwMTAxMTIwMTAwWhcNNDgwMTAxMTIwMT" + "AwWjBeMQswCQYDVQQGEwJVUzEYMBYGA1UEChMPVS5TLiBHb3Zlcm5tZW50MQwwCgYDVQQL" + "EwNEb2QxEDAOBgNVBAsTB1Rlc3RpbmcxFTATBgNVBAMTDENBMS1QTC4wMS4wNTCBnzANBg" + "kqhkiG9w0BAQEFAAOBjQAwgYkCgYEA/rVBEGZ4jibDhREeRGV3jPnv05esRL8/En1Bu35y" + "QrAHi32+kBu42vwwDbeuiTZd/B90bn5srJZoW83rxXxNnpxqbnjN3GgIcRiUVyaVRTp9/U" + "IT8B9h09b9yT8gpQ5qR0+JDcOHCfJwpogAsyJJa6AM5p/q3TeF39ugfVOWt/cCAwEAAaNm" + "MGQwEgYDVR0TAQH/BAgwBgEB/wIBBjAOBgNVHQ8BAf8EBAMCAQYwFgYDVR0gBA8wDTALBg" + "lghkgBZQMBMAEwEQYDVR0OBAoECJ7/mkuLuEIGMBMGA1UdIwQMMAqACKua6/nC51SPMA0G" + "CSqGSIb3DQEBBQUAA4GBADC0A2KMMSSmGI9p85WG7XZVMBX/xdDYOHO0e3ORTRFS3kj9rK" + "a0yUjc1X+p22AA8kUyOLpYIulfDjPrLKN2E/hWSf3+XWMiC7JfX01F+BBl/avEZoymaZB4" + "dkH1Hym4IMJoSaEOgf5HFKBnFEA6aUcr+oDYGUP+Sc1dmJMjBW72"; public static final String Intermediate_Certificate_2_PL_01_05_crt = "MIICmTCCAgKgAwIBAgICAJEwDQYJKoZIhvcNAQEFBQAwXjELMAkGA1UEBhMCVVMxGDAWBg" + "NVBAoTD1UuUy4gR292ZXJubWVudDEMMAoGA1UECxMDRG9kMRAwDgYDVQQLEwdUZXN0aW5n" + "MRUwEwYDVQQDEwxDQTEtUEwuMDEuMDUwHhcNOTgwMTAxMTIwMTAwWhcNNDgwMTAxMTIwMT" + "AwWjBeMQswCQYDVQQGEwJVUzEYMBYGA1UEChMPVS5TLiBHb3Zlcm5tZW50MQwwCgYDVQQL" + "EwNEb2QxEDAOBgNVBAsTB1Rlc3RpbmcxFTATBgNVBAMTDENBMi1QTC4wMS4wNTCBnzANBg" + "kqhkiG9w0BAQEFAAOBjQAwgYkCgYEArir4GaS6r0Tv9PMbaOXYdPKADNpVbJe79G5t/F6x" + "7Tz1rwUR+m10E+Jq9RsV+fU/nUzzjJXHbPLZnfodUVVmrXgzvQ8+B2N4jJtdNLG66j2PZG" + "+P8GQzVK9drDh54VHXdvxAYCXs7GaIprWmCQsxZOKjhFU3YDiRRK8qJGpBG/cCAwEAAaNm" + "MGQwEgYDVR0TAQH/BAgwBgEB/wIBADAOBgNVHQ8BAf8EBAMCAQYwFgYDVR0gBA8wDTALBg" + "lghkgBZQMBMAEwEQYDVR0OBAoECMmrFr30fUzZMBMGA1UdIwQMMAqACJ7/mkuLuEIGMA0G" + "CSqGSIb3DQEBBQUAA4GBAI4qJF6STCi+elUbpZIP7YmcaQsS0PE4G3+LJoMg1LT3rSeobK" + "Aj/yUetmA7y0B5i0svKjRChLOpfClNPVPCx/+mc75+LG+dh1eVG/qk2UH/lrqLN0XLl8tA" + "IwZeoPaegBQAIp9oEjhDN1fWtKIkOe6A6wYdH2VPvsqC8g02VcwD"; public static final String Intermediate_Certificate_3_PL_01_05_crt = "MIICmTCCAgKgAwIBAgICAJIwDQYJKoZIhvcNAQEFBQAwXjELMAkGA1UEBhMCVVMxGDAWBg" + "NVBAoTD1UuUy4gR292ZXJubWVudDEMMAoGA1UECxMDRG9kMRAwDgYDVQQLEwdUZXN0aW5n" + "MRUwEwYDVQQDEwxDQTItUEwuMDEuMDUwHhcNOTgwMTAxMTIwMTAwWhcNNDgwMTAxMTIwMT" + "AwWjBeMQswCQYDVQQGEwJVUzEYMBYGA1UEChMPVS5TLiBHb3Zlcm5tZW50MQwwCgYDVQQL" + "EwNEb2QxEDAOBgNVBAsTB1Rlc3RpbmcxFTATBgNVBAMTDENBMy1QTC4wMS4wNTCBnzANBg" + "kqhkiG9w0BAQEFAAOBjQAwgYkCgYEAtRC2/PDG3kx8LpzfWC0yJph5h3LXZJZW0W2voss1" + "HYPP1/MBoQY067dfbALilVRh9asCNL4F45uu0lT24qS9vjW8SzBOLA18GsVYRmWO7EP+Cd" + "9f3mgPIMJ5n+UjW+yhBwh0Z2pzVElkX9CxECrs1Mt2ulyuwWA1lR8nRMaTUeMCAwEAAaNm" + "MGQwEgYDVR0TAQH/BAgwBgEB/wIBADAOBgNVHQ8BAf8EBAMCAQYwFgYDVR0gBA8wDTALBg" + "lghkgBZQMBMAEwEQYDVR0OBAoECAlV3mzXYPyuMBMGA1UdIwQMMAqACMmrFr30fUzZMA0G" + "CSqGSIb3DQEBBQUAA4GBAG28iHdlA+nTs/b9pi+m9eMy7niELjIWL9fMgn1r4iXQ0TsPYi" + "tgpoip+BB4G/jz7MPx/N4nwyAPV+C9wN8cAHALf/ka2MxAORYFVFI+5PDgXzm78ILqj91f" + "vOFN4jemizTES4/dHxfmdctnsTRpU9ALQgfJLhxEQISOPwuemKB0"; public static final String Intermediate_CRL_1_PL_01_05_crl = "MIIBSzCBtQIBATANBgkqhkiG9w0BAQUFADBeMQswCQYDVQQGEwJVUzEYMBYGA1UEChMPVS" + "5TLiBHb3Zlcm5tZW50MQwwCgYDVQQLEwNEb2QxEDAOBgNVBAsTB1Rlc3RpbmcxFTATBgNV" + "BAMTDENBMS1QTC4wMS4wNRcNOTkwMTAxMTIwMTAwWhcNNDgwMTAxMTIwMTAwWqAjMCEwCg" + "YDVR0UBAMCAQEwEwYDVR0jBAwwCoAInv+aS4u4QgYwDQYJKoZIhvcNAQEFBQADgYEA5i45" + "gETFAw6l9Awex9IAVIqYTA1dnbDyrUYDRdzd0x6OxSPODvNfQCwqwlTJXrHidCPO8jRhMS" + "Zcdn/MTlIeHa6OERFcjOiwOpeTgtchvpTdDchs5ve8Ik+myue+cfgpEVKOE+ZQ2T2tcyz/" + "+DbeMptECfJ0lVfCKIY7ZOzBPaQ="; public static final String Intermediate_CRL_2_PL_01_05_crl = "MIIBSzCBtQIBATANBgkqhkiG9w0BAQUFADBeMQswCQYDVQQGEwJVUzEYMBYGA1UEChMPVS" + "5TLiBHb3Zlcm5tZW50MQwwCgYDVQQLEwNEb2QxEDAOBgNVBAsTB1Rlc3RpbmcxFTATBgNV" + "BAMTDENBMi1QTC4wMS4wNRcNOTkwMTAxMTIwMTAwWhcNNDgwMTAxMTIwMTAwWqAjMCEwCg" + "YDVR0UBAMCAQEwEwYDVR0jBAwwCoAIyasWvfR9TNkwDQYJKoZIhvcNAQEFBQADgYEAdsNe" + "ugM8sd8bmIDkYXce2WmS5Zx6QUQ0yT6Ij4OR5/F4CG4Vl+k3JkNPuAiNSs2Z9HeML+F/W8" + "3yEPe/mdLV4nLw4B/b1/8DmgZN4r1ojaWuHAg+KrA3Zz3Rc/hwQfvBy49mf4NGtY4ArbeB" + "DYKz5sVlrwR+gOCR5jm4IC7WEDs="; public static final String Intermediate_CRL_3_PL_01_05_crl = "MIIBSzCBtQIBATANBgkqhkiG9w0BAQUFADBeMQswCQYDVQQGEwJVUzEYMBYGA1UEChMPVS" + "5TLiBHb3Zlcm5tZW50MQwwCgYDVQQLEwNEb2QxEDAOBgNVBAsTB1Rlc3RpbmcxFTATBgNV" + "BAMTDENBMy1QTC4wMS4wNRcNOTkwMTAxMTIwMTAwWhcNNDgwMTAxMTIwMTAwWqAjMCEwCg" + "YDVR0UBAMCAQEwEwYDVR0jBAwwCoAICVXebNdg/K4wDQYJKoZIhvcNAQEFBQADgYEAqYex" + "FaIykZo17O2URpofe8x04L/VsfA9jV28zUgNFruAGld/kUh4rYvgwrdbNZ8NmEFDp9J9aL" + "93af3bzoNvWCik2VrQLd5nccCFiC04B+LUH9Y2p+7vV2ojrtBks5SMW0q4HaNyPSQu8Fst" + "4mYVf+QIYZC3iVAF4rsKnaxwzIU="; public static final String End_Certificate_PL_01_05_crt = "MIIChzCCAfCgAwIBAgICAJMwDQYJKoZIhvcNAQEFBQAwXjELMAkGA1UEBhMCVVMxGDAWBg" + "NVBAoTD1UuUy4gR292ZXJubWVudDEMMAoGA1UECxMDRG9kMRAwDgYDVQQLEwdUZXN0aW5n" + "MRUwEwYDVQQDEwxDQTMtUEwuMDEuMDUwHhcNOTgwMTAxMTIwMTAwWhcNNDgwMTAxMTIwMT" + "AwWjBgMQswCQYDVQQGEwJVUzEYMBYGA1UEChMPVS5TLiBHb3Zlcm5tZW50MQwwCgYDVQQL" + "EwNEb0QxEDAOBgNVBAsTB1Rlc3RpbmcxFzAVBgNVBAMTDlVzZXIxLVBMLjAxLjA1MIGfMA" + "0GCSqGSIb3DQEBAQUAA4GNADCBiQKBgQDCXJjzKGcLyONTyOa6sQHvIKZIAh0pWdteUiXf" + "b7yjCn6Z52SCHxB9GZERHwR7fbJpoE3oDcYUY+8pH65bIVm1p3zr5deo4v85DEZQ50cU9a" + "WEUAO/5X57P7pYb9/47abu0cdsLIWeE+O94HpZS8vz8mxRQKLj27gPY1KzzTbrZQIDAQAB" + "o1IwUDAOBgNVHQ8BAf8EBAMCBeAwFgYDVR0gBA8wDTALBglghkgBZQMBMAEwEQYDVR0OBA" + "oECG8ILlM9oqZwMBMGA1UdIwQMMAqACAlV3mzXYPyuMA0GCSqGSIb3DQEBBQUAA4GBAF6S" + "x3aunfgnDmo42aPOzDh536WSkTTbX9bmUNyg3IQHl/3xhVqjS76bMqreYhx5nh4VNx/Z3N" + "LD0W75XmASCk0wtW9S1MoxzJMFIozRruaE3oykrbyMMOt0Br5CV12ofUd0WybDkXfNAIze" + "IRgps3nORHWjV1GwXe8uNoUn6/z7"; public static final String[] TEST_58_DATA = new String[] { Intermediate_Certificate_1_PL_01_05_crt, Intermediate_Certificate_2_PL_01_05_crt, Intermediate_Certificate_3_PL_01_05_crt, Intermediate_CRL_1_PL_01_05_crl, Intermediate_CRL_2_PL_01_05_crl, Intermediate_CRL_3_PL_01_05_crl, End_Certificate_PL_01_05_crt }; /* * test59 * */ public static final String Intermediate_Certificate_1_PL_01_06_crt = "MIICmTCCAgKgAwIBAgICAJQwDQYJKoZIhvcNAQEFBQAwXjELMAkGA1UEBhMCVVMxGDAWBg" + "NVBAoTD1UuUy4gR292ZXJubWVudDEMMAoGA1UECxMDRG9EMRAwDgYDVQQLEwdUZXN0aW5n" + "MRUwEwYDVQQDEwxUcnVzdCBBbmNob3IwHhcNOTgwMTAxMTIwMTAwWhcNNDgwMTAxMTIwMT" + "AwWjBeMQswCQYDVQQGEwJVUzEYMBYGA1UEChMPVS5TLiBHb3Zlcm5tZW50MQwwCgYDVQQL" + "EwNEb2QxEDAOBgNVBAsTB1Rlc3RpbmcxFTATBgNVBAMTDENBMS1QTC4wMS4wNjCBnzANBg" + "kqhkiG9w0BAQEFAAOBjQAwgYkCgYEAweCAiEGMLycmodjrUMIWEEFshkvhX2r90wGl+/pU" + "Ia9NSdT23zYzE4Uo8Is1ywyV+YfvgR22j/RXF6j8OK+XZ8jlgfjVTAhjCnTWY9LDR7qAyk" + "8zuuITxJrYpiPoxqZs9BXLfGkDbye5VpVJXvQdbJNxgKO0hkBBDfe+T9+qw6ECAwEAAaNm" + "MGQwEgYDVR0TAQH/BAgwBgEB/wIBBjAOBgNVHQ8BAf8EBAMCAQYwFgYDVR0gBA8wDTALBg" + "lghkgBZQMBMAEwEQYDVR0OBAoECG1DiuoAwV6aMBMGA1UdIwQMMAqACKua6/nC51SPMA0G" + "CSqGSIb3DQEBBQUAA4GBAMFvtFiMDMP6n3CrqQLSzhpK5Qu0uxa56ARXIKSIqi0OUZAu9v" + "sCXxMvaG/R5bElwi7ybYZ5KUSN+PnDmlUxWWL5Ib5RZdXgj7L83oyLTQmbDMvka6rSWHgw" + "Jq8qHVslhh+l+YNOb4fzs8x9ctCrs/BgjX8wkORpQbigU0BUJ9sX"; public static final String Intermediate_Certificate_2_PL_01_06_crt = "MIICmTCCAgKgAwIBAgICAJUwDQYJKoZIhvcNAQEFBQAwXjELMAkGA1UEBhMCVVMxGDAWBg" + "NVBAoTD1UuUy4gR292ZXJubWVudDEMMAoGA1UECxMDRG9kMRAwDgYDVQQLEwdUZXN0aW5n" + "MRUwEwYDVQQDEwxDQTEtUEwuMDEuMDYwHhcNOTgwMTAxMTIwMTAwWhcNNDgwMTAxMTIwMT" + "AwWjBeMQswCQYDVQQGEwJVUzEYMBYGA1UEChMPVS5TLiBHb3Zlcm5tZW50MQwwCgYDVQQL" + "EwNEb2QxEDAOBgNVBAsTB1Rlc3RpbmcxFTATBgNVBAMTDENBMi1QTC4wMS4wNjCBnzANBg" + "kqhkiG9w0BAQEFAAOBjQAwgYkCgYEAwf6Nf0+r7JvE6BO4MbDbS1T1SCzn78haBAmqGZLS" + "Ac4xQTydvmzr9PwiWlU0xjFfKItqRMt7rfzTTPfvvnwxsAfQNPtxKzi30yCNq/VotMA7j5" + "iQYaVe2OWVHu13agbXLEZ0pL/ZkmQ3Gvo6UhF4dRmCnjFbd5cMTxQVHUrwgyECAwEAAaNm" + "MGQwEgYDVR0TAQH/BAgwBgEB/wIBADAOBgNVHQ8BAf8EBAMCAQYwFgYDVR0gBA8wDTALBg" + "lghkgBZQMBMAEwEQYDVR0OBAoECE3tS4AYmwZDMBMGA1UdIwQMMAqACG1DiuoAwV6aMA0G" + "CSqGSIb3DQEBBQUAA4GBADcBTKbhx8PCunjRVJkcLBCcVGHs9HfkChDafwBO51fe5uhHE2" + "QBpW3J8ZsevuFQiEZvuy2RVFktE6ZoKD8wxwBFhs+OIxe2mergQPy6jHuxoSUiPzr3CVXZ" + "UsNxe7j3IcJLqbJ15UqGFH5yph7Sa4Ym6x747miF6W9knNkjcx3K"; public static final String Intermediate_Certificate_3_PL_01_06_crt = "MIICmTCCAgKgAwIBAgICAJYwDQYJKoZIhvcNAQEFBQAwXjELMAkGA1UEBhMCVVMxGDAWBg" + "NVBAoTD1UuUy4gR292ZXJubWVudDEMMAoGA1UECxMDRG9kMRAwDgYDVQQLEwdUZXN0aW5n" + "MRUwEwYDVQQDEwxDQTItUEwuMDEuMDYwHhcNOTgwMTAxMTIwMTAwWhcNNDgwMTAxMTIwMT" + "AwWjBeMQswCQYDVQQGEwJVUzEYMBYGA1UEChMPVS5TLiBHb3Zlcm5tZW50MQwwCgYDVQQL" + "EwNEb2QxEDAOBgNVBAsTB1Rlc3RpbmcxFTATBgNVBAMTDENBMy1QTC4wMS4wNjCBnzANBg" + "kqhkiG9w0BAQEFAAOBjQAwgYkCgYEAwq2YlDLHX4KktKnzLCYjnk079IDgXENrkRBuZHTB" + "IQyZoiBH4ZWHreZKs3LvznP8uSd8eEL8keNw4PwZ6aT1LF/Jr/UlrFQNnpLzQVXwGGAuzh" + "tFJYRlOfI5cCZYAcpjnyUV4GW+MuwBdoqDycMjmqIv/8A8vupjahffcmBAassCAwEAAaNm" + "MGQwEgYDVR0TAQH/BAgwBgEB/wIBADAOBgNVHQ8BAf8EBAMCAQYwFgYDVR0gBA8wDTALBg" + "lghkgBZQMBMAEwEQYDVR0OBAoECB+qYFJjEkJ5MBMGA1UdIwQMMAqACE3tS4AYmwZDMA0G" + "CSqGSIb3DQEBBQUAA4GBADiXredACtRQTV2TKgu5SDdPlczj7cZZUARJiJKiRfjmxHCc1q" + "m/Oh7sHkqRvlHqjoX8qp4iSchoZWdOAE5O/q4Ef6rViejDFVyN2ZmlhP6KIiRxznrvYfF1" + "n08K7CHgHWvDaumm4pNmWeF03nuasHrY0W9h1uk5poVuzaWDpx3A"; public static final String Intermediate_CRL_1_PL_01_06_crl = "MIIBSzCBtQIBATANBgkqhkiG9w0BAQUFADBeMQswCQYDVQQGEwJVUzEYMBYGA1UEChMPVS" + "5TLiBHb3Zlcm5tZW50MQwwCgYDVQQLEwNEb2QxEDAOBgNVBAsTB1Rlc3RpbmcxFTATBgNV" + "BAMTDENBMS1QTC4wMS4wNhcNOTkwMTAxMTIwMTAwWhcNNDgwMTAxMTIwMTAwWqAjMCEwCg" + "YDVR0UBAMCAQEwEwYDVR0jBAwwCoAIbUOK6gDBXpowDQYJKoZIhvcNAQEFBQADgYEAiHM1" + "xFuYt6tDscqzwj0mLHPHULnR44/vNyPUg0KnV03Dd4XbFHz0FtwDKgVTBZ8x7ybp83ubJH" + "tE/p8nPW5kN25WQOlYkZoAcMpEXjTzlo9evU0W3nyzJjmlT8YEI7vnmWFz/ahzy6WFwPue" + "h862EKh2zVO4hoqZYEuDQI33fOc="; public static final String Intermediate_CRL_2_PL_01_06_crl = "MIIBSzCBtQIBATANBgkqhkiG9w0BAQUFADBeMQswCQYDVQQGEwJVUzEYMBYGA1UEChMPVS" + "5TLiBHb3Zlcm5tZW50MQwwCgYDVQQLEwNEb2QxEDAOBgNVBAsTB1Rlc3RpbmcxFTATBgNV" + "BAMTDENBMi1QTC4wMS4wNhcNOTkwMTAxMTIwMTAwWhcNNDgwMTAxMTIwMTAwWqAjMCEwCg" + "YDVR0UBAMCAQEwEwYDVR0jBAwwCoAITe1LgBibBkMwDQYJKoZIhvcNAQEFBQADgYEAuDSF" + "W1KOc4x41HGvdRaw/NtipD2y6zSh3mtRoo7Q6J2BvJvunymZNEziozBOiUgT8zMgbdbm4a" + "PEwlHRaoJP8+yxJIlKaHa9Hc7Yz4SOwSrLicf7EnBSct3Mze0b48UYqbn1q+lf/zKaUGrP" + "M6oqtE8Fam06T+WUfutU53zTtSs="; public static final String Intermediate_CRL_3_PL_01_06_crl = "MIIBSzCBtQIBATANBgkqhkiG9w0BAQUFADBeMQswCQYDVQQGEwJVUzEYMBYGA1UEChMPVS" + "5TLiBHb3Zlcm5tZW50MQwwCgYDVQQLEwNEb2QxEDAOBgNVBAsTB1Rlc3RpbmcxFTATBgNV" + "BAMTDENBMy1QTC4wMS4wNhcNOTkwMTAxMTIwMTAwWhcNNDgwMTAxMTIwMTAwWqAjMCEwCg" + "YDVR0UBAMCAQEwEwYDVR0jBAwwCoAIH6pgUmMSQnkwDQYJKoZIhvcNAQEFBQADgYEAcPfO" + "+Rj2KmO1CxjuKLEiOUAIq5YmR4U06IcCBGMxlrdHVXHM3vepBKUlMDaT4UGcleABMPX9Iz" + "/31ofyXlZ/fQJOoTZt0CI7SOPQE5ZkUsR3BDuUqf1+sWwBYyBHkrC95JhJkM4LfGS5K19p" + "fp0j0bguzNCXSBRTfjSZhy80tcs="; public static final String End_Certificate_PL_01_06_crt = "MIICljCCAf+gAwIBAgICAJcwDQYJKoZIhvcNAQEFBQAwXjELMAkGA1UEBhMCVVMxGDAWBg" + "NVBAoTD1UuUy4gR292ZXJubWVudDEMMAoGA1UECxMDRG9kMRAwDgYDVQQLEwdUZXN0aW5n" + "MRUwEwYDVQQDEwxDQTMtUEwuMDEuMDYwHhcNOTgwMTAxMTIwMTAwWhcNNDgwMTAxMTIwMT" + "AwWjBeMQswCQYDVQQGEwJVUzEYMBYGA1UEChMPVS5TLiBHb3Zlcm5tZW50MQwwCgYDVQQL" + "EwNEb2QxEDAOBgNVBAsTB1Rlc3RpbmcxFTATBgNVBAMTDENBNC1QTC4wMS4wNjCBnzANBg" + "kqhkiG9w0BAQEFAAOBjQAwgYkCgYEA3asAqJcjXngEuyM/W3+TAE+Qr4JtNUdwBtmrpGlo" + "fAvJdmXHARyiN/Zn6Si8bGI8Wz8J4Y+Ll7zLdaMU4MCZo6hwZiaQwkh9a+ZecCpLpjs4mz" + "MSf5zHSwTYiXKMazlmnGEITVyKLmAiLSyGeeJvOJVqVo/NZXRGVlmnPxZFfgsCAwEAAaNj" + "MGEwDwYDVR0TAQH/BAUwAwEB/zAOBgNVHQ8BAf8EBAMCAeYwFgYDVR0gBA8wDTALBglghk" + "gBZQMBMAEwEQYDVR0OBAoECLZuS770NcDsMBMGA1UdIwQMMAqACB+qYFJjEkJ5MA0GCSqG" + "SIb3DQEBBQUAA4GBAGM18aR2i8vSywsWhcLrRN1Xckl/HiBPNphobfKoER4NG29cFjUPQX" + "zukjQcJl2clAXNCVtcsKCoYRP3YUyAB6At+yskuuJXtES7FIzM3rt/UpDS5ktVC3gh+jgE" + "pPhMILYIXFzYY1hifkpagfO+mkcr7RqHU3tHAr6LCWjqrB9g"; public static final String[] TEST_59_DATA = new String[] { Intermediate_Certificate_1_PL_01_06_crt, Intermediate_Certificate_2_PL_01_06_crt, Intermediate_Certificate_3_PL_01_06_crt, Intermediate_CRL_1_PL_01_06_crl, Intermediate_CRL_2_PL_01_06_crl, Intermediate_CRL_3_PL_01_06_crl, End_Certificate_PL_01_06_crt }; /* * test60 * */ public static final String Intermediate_Certificate_1_PL_01_07_crt = "MIICmTCCAgKgAwIBAgICAJgwDQYJKoZIhvcNAQEFBQAwXjELMAkGA1UEBhMCVVMxGDAWBg" + "NVBAoTD1UuUy4gR292ZXJubWVudDEMMAoGA1UECxMDRG9EMRAwDgYDVQQLEwdUZXN0aW5n" + "MRUwEwYDVQQDEwxUcnVzdCBBbmNob3IwHhcNOTgwMTAxMTIwMTAwWhcNNDgwMTAxMTIwMT" + "AwWjBeMQswCQYDVQQGEwJVUzEYMBYGA1UEChMPVS5TLiBHb3Zlcm5tZW50MQwwCgYDVQQL" + "EwNEb2QxEDAOBgNVBAsTB1Rlc3RpbmcxFTATBgNVBAMTDENBMS1QTC4wMS4wNzCBnzANBg" + "kqhkiG9w0BAQEFAAOBjQAwgYkCgYEA5HkS45NLuqq9ZwF79+pTGtQnGWO7DFdetYeQTbeD" + "sisjZMsK0sCCR5xAKYQsJSS4v/8LQUdxlQR30LMV0SQUKFMJyFsMiSsO8subb6sVINWn8A" + "tL4zcQK0WiASUZOEkybAFJtP31PahzI5wfD1cikE1M4BlDij5WeaIjt/RTHKUCAwEAAaNm" + "MGQwEgYDVR0TAQH/BAgwBgEB/wIBBjAOBgNVHQ8BAf8EBAMCAQYwFgYDVR0gBA8wDTALBg" + "lghkgBZQMBMAEwEQYDVR0OBAoECLSUEn5d8YywMBMGA1UdIwQMMAqACKua6/nC51SPMA0G" + "CSqGSIb3DQEBBQUAA4GBANLO+kEiswkGzEh4ZcF5LtfnPZlnG4gTPSNugeWJc+Xedqmttp" + "jZ35fr1hiRe2Q1UcyTd4ThkPknawwZednbsZVPqw8u1mo7kuAeL9KrCk199vL4bV8Ag/kj" + "HJ8TAy40UDB6hMm7l4j8mEKwV03THVrz1Vvz59CQXj+iseH6yUNO"; public static final String Intermediate_Certificate_2_PL_01_07_crt = "MIICmTCCAgKgAwIBAgICAJkwDQYJKoZIhvcNAQEFBQAwXjELMAkGA1UEBhMCVVMxGDAWBg" + "NVBAoTD1UuUy4gR292ZXJubWVudDEMMAoGA1UECxMDRG9kMRAwDgYDVQQLEwdUZXN0aW5n" + "MRUwEwYDVQQDEwxDQTEtUEwuMDEuMDcwHhcNOTgwMTAxMTIwMTAwWhcNNDgwMTAxMTIwMT" + "AwWjBeMQswCQYDVQQGEwJVUzEYMBYGA1UEChMPVS5TLiBHb3Zlcm5tZW50MQwwCgYDVQQL" + "EwNEb2QxEDAOBgNVBAsTB1Rlc3RpbmcxFTATBgNVBAMTDENBMi1QTC4wMS4wNzCBnzANBg" + "kqhkiG9w0BAQEFAAOBjQAwgYkCgYEAu78gmT5HwmBHEe+K8fLLgGaPpcv13ZjrgL4twTBS" + "OkZn5LL9GcfkPuA5WIAZkVYfCWSDPqcAGoOWUIDADfBfdcyLteUH+xI01rHKiLDVexMvU9" + "vqCmcBKhxK3S6wraW5YhOO0bx4oPrZXVIjyG8fh4e5WTEykzvUWJ8ZbzSJ9JsCAwEAAaNm" + "MGQwEgYDVR0TAQH/BAgwBgEB/wIBATAOBgNVHQ8BAf8EBAMCAQYwFgYDVR0gBA8wDTALBg" + "lghkgBZQMBMAEwEQYDVR0OBAoECCT+fDEaN7GaMBMGA1UdIwQMMAqACLSUEn5d8YywMA0G" + "CSqGSIb3DQEBBQUAA4GBANpKr98PiXAdcXlbgSgif0213H+tg3WwUNKZTw8MpqPyrN2/DZ" + "HBi6e2KWXLTxttV9AZBRvcKwsveS6oc31eulMe8nHxRNRfadvF6dL3Tsig6HAQkartcJMI" + "yfW4V3EhXbCdziQkre7XcR9WK5bpQoX04HWeew6YTxjG/cL9MIJR"; public static final String Intermediate_Certificate_3_PL_01_07_crt = "MIICmTCCAgKgAwIBAgICAJowDQYJKoZIhvcNAQEFBQAwXjELMAkGA1UEBhMCVVMxGDAWBg" + "NVBAoTD1UuUy4gR292ZXJubWVudDEMMAoGA1UECxMDRG9kMRAwDgYDVQQLEwdUZXN0aW5n" + "MRUwEwYDVQQDEwxDQTItUEwuMDEuMDcwHhcNOTgwMTAxMTIwMTAwWhcNNDgwMTAxMTIwMT" + "AwWjBeMQswCQYDVQQGEwJVUzEYMBYGA1UEChMPVS5TLiBHb3Zlcm5tZW50MQwwCgYDVQQL" + "EwNEb2QxEDAOBgNVBAsTB1Rlc3RpbmcxFTATBgNVBAMTDENBMy1QTC4wMS4wNzCBnzANBg" + "kqhkiG9w0BAQEFAAOBjQAwgYkCgYEAr7YezMXvnkSuNCdXch2HRAEVuCqfzpVRCj6laJI9" + "Q+NxgXwzaOwnImvwER3Hblh1l0MAt5/I/9hhqCN+918ueME50MkoM1wPbcmrRIlwWLGSVZ" + "yBKeyPHrLbdPqVIexUlQk7PasLm/Qx4SvRGVe9IMLrEzPV3MFJtrJoWaMobQkCAwEAAaNm" + "MGQwEgYDVR0TAQH/BAgwBgEB/wIBATAOBgNVHQ8BAf8EBAMCAQYwFgYDVR0gBA8wDTALBg" + "lghkgBZQMBMAEwEQYDVR0OBAoECKw8JlHMvVfuMBMGA1UdIwQMMAqACCT+fDEaN7GaMA0G" + "CSqGSIb3DQEBBQUAA4GBAA5JEDEDyqfZzTGzOoMV+8RVke+a4qgOo7rnOEdletgGFEwz8A" + "tiMHBxR+UMxuHS82Hz3+F8XlyYIwlrG9wWVcB/tOyzgVyA28Yux9Q/meU7T6dco/AnmOdr" + "2XL6Xm5iLnARG+PkUPHOsxuweyB/sSUSA8ZJPowNRWTik57ul/bO"; public static final String Intermediate_Certificate_4_PL_01_07_crt = "MIICljCCAf+gAwIBAgICAJswDQYJKoZIhvcNAQEFBQAwXjELMAkGA1UEBhMCVVMxGDAWBg" + "NVBAoTD1UuUy4gR292ZXJubWVudDEMMAoGA1UECxMDRG9kMRAwDgYDVQQLEwdUZXN0aW5n" + "MRUwEwYDVQQDEwxDQTMtUEwuMDEuMDcwHhcNOTgwMTAxMTIwMTAwWhcNNDgwMTAxMTIwMT" + "AwWjBeMQswCQYDVQQGEwJVUzEYMBYGA1UEChMPVS5TLiBHb3Zlcm5tZW50MQwwCgYDVQQL" + "EwNEb2QxEDAOBgNVBAsTB1Rlc3RpbmcxFTATBgNVBAMTDENBNC1QTC4wMS4wNzCBnzANBg" + "kqhkiG9w0BAQEFAAOBjQAwgYkCgYEA7mNS8dGz0gkXDbBRzP2ypdNMahJbM3cSMHO0hYpn" + "uRsiXGUhIB0K4WVbnz6tr7Hch3yltK4H1Y12Lf8cXEETR2sE9lCY2A3r8/VM5OUbou5Y8k" + "wIf03VhP7cGKonaFtlj/WD77fidDePVp1Nk28gV0T2F/l4pM5TEJrq5C9PSUcCAwEAAaNj" + "MGEwDwYDVR0TAQH/BAUwAwEB/zAOBgNVHQ8BAf8EBAMCAQYwFgYDVR0gBA8wDTALBglghk" + "gBZQMBMAEwEQYDVR0OBAoECJBEcZsMRq6CMBMGA1UdIwQMMAqACKw8JlHMvVfuMA0GCSqG" + "SIb3DQEBBQUAA4GBACfbHKpuRJnZ5UU0sih8RuywhUo6Getwl/p6fsi87wYI61pvYru+hm" + "4R4eAMZvg7MrAarS3Iu3zKBU1HKeq1i+hpwTIXrngR8eL2fU/X6GPzdte3+3tjhah38bqF" + "zDon+N6ap4MKWRk033SsFYo1K88Mena2tGuFForJlV9DOF1l"; public static final String Intermediate_CRL_1_PL_01_07_crl = "MIIBSzCBtQIBATANBgkqhkiG9w0BAQUFADBeMQswCQYDVQQGEwJVUzEYMBYGA1UEChMPVS" + "5TLiBHb3Zlcm5tZW50MQwwCgYDVQQLEwNEb2QxEDAOBgNVBAsTB1Rlc3RpbmcxFTATBgNV" + "BAMTDENBMS1QTC4wMS4wNxcNOTkwMTAxMTIwMTAwWhcNNDgwMTAxMTIwMTAwWqAjMCEwCg" + "YDVR0UBAMCAQEwEwYDVR0jBAwwCoAItJQSfl3xjLAwDQYJKoZIhvcNAQEFBQADgYEAJtaE" + "I1+PCNL1/bgEVKWUIwvh58ugnWhxzbFW6hNJwNEz9/yt+FLZfNrT/Ezort4VVQFLQg7+Gj" + "KrkIujqfRJG4LXrXAV8ZsvSPuwyQ+hM1GdHGDPhj9x6DkjFusxJYUEs5BzlX7ovpnaIPSW" + "RPsatheSzu48pMOCmyTKE3MpuZg="; public static final String Intermediate_CRL_2_PL_01_07_crl = "MIIBSzCBtQIBATANBgkqhkiG9w0BAQUFADBeMQswCQYDVQQGEwJVUzEYMBYGA1UEChMPVS" + "5TLiBHb3Zlcm5tZW50MQwwCgYDVQQLEwNEb2QxEDAOBgNVBAsTB1Rlc3RpbmcxFTATBgNV" + "BAMTDENBMi1QTC4wMS4wNxcNOTkwMTAxMTIwMTAwWhcNNDgwMTAxMTIwMTAwWqAjMCEwCg" + "YDVR0UBAMCAQEwEwYDVR0jBAwwCoAIJP58MRo3sZowDQYJKoZIhvcNAQEFBQADgYEALiV+" + "BFpXhgTjiMZBYLVuc/fqhHcXeXOGOmJZoKUnIXjETH3rzkkt5k4tMN00ycZVgpRwn3ZyQs" + "cFLcW8taau1J7iQOmGY/7qIT0eFx2OlgNmxqirmwx4OM5VSH5mEpnp9NOr1rfut1GDRzw0" + "tZ+nhD/PGDXYPu+QPX6jii0vdHo="; public static final String Intermediate_CRL_3_PL_01_07_crl = "MIIBSzCBtQIBATANBgkqhkiG9w0BAQUFADBeMQswCQYDVQQGEwJVUzEYMBYGA1UEChMPVS" + "5TLiBHb3Zlcm5tZW50MQwwCgYDVQQLEwNEb2QxEDAOBgNVBAsTB1Rlc3RpbmcxFTATBgNV" + "BAMTDENBMy1QTC4wMS4wNxcNOTkwMTAxMTIwMTAwWhcNNDgwMTAxMTIwMTAwWqAjMCEwCg" + "YDVR0UBAMCAQEwEwYDVR0jBAwwCoAIrDwmUcy9V+4wDQYJKoZIhvcNAQEFBQADgYEASY47" + "p94jEh9FZ1TrPS82nWC3Z6ZKdaD9pUbaJpRnAId59QdBaD2Cxq+SfM3HTlz8grCAPKwulv" + "jDDhXhp4H/m63Q/pJbyl3bbMxnphMOoDwB9wwKIUQPM5wagMovF/UYtC8MoC++m2kuZ1eb" + "fR/OIJuQr+k/kD5Axhw/xolKPdE="; public static final String Intermediate_CRL_4_PL_01_07_crl = "MIIBSzCBtQIBATANBgkqhkiG9w0BAQUFADBeMQswCQYDVQQGEwJVUzEYMBYGA1UEChMPVS" + "5TLiBHb3Zlcm5tZW50MQwwCgYDVQQLEwNEb2QxEDAOBgNVBAsTB1Rlc3RpbmcxFTATBgNV" + "BAMTDENBNC1QTC4wMS4wNxcNOTkwMTAxMTIwMTAwWhcNNDgwMTAxMTIwMTAwWqAjMCEwCg" + "YDVR0UBAMCAQEwEwYDVR0jBAwwCoAIkERxmwxGroIwDQYJKoZIhvcNAQEFBQADgYEAMhIQ" + "lE+BdCO6NBz+YgcH+tjP0n4OCdQ+7uxUxUYmPtPbsLwbDDEEZUjykgwiA6P47Cqh5fXB6G" + "tfInh1cmQi3y2IEHK+bRSx321qczOh34Yx2hw5vp+JFttbQAEl/BHixklrFBrXjN0UsWGC" + "ibXcZy0YjerWTp/yceoABz9p94U="; public static final String End_Certificate_PL_01_07_crt = "MIIChzCCAfCgAwIBAgICAJwwDQYJKoZIhvcNAQEFBQAwXjELMAkGA1UEBhMCVVMxGDAWBg" + "NVBAoTD1UuUy4gR292ZXJubWVudDEMMAoGA1UECxMDRG9kMRAwDgYDVQQLEwdUZXN0aW5n" + "MRUwEwYDVQQDEwxDQTQtUEwuMDEuMDcwHhcNOTgwMTAxMTIwMTAwWhcNNDgwMTAxMTIwMT" + "AwWjBgMQswCQYDVQQGEwJVUzEYMBYGA1UEChMPVS5TLiBHb3Zlcm5tZW50MQwwCgYDVQQL" + "EwNEb0QxEDAOBgNVBAsTB1Rlc3RpbmcxFzAVBgNVBAMTDlVzZXIxLVBMLjAxLjA3MIGfMA" + "0GCSqGSIb3DQEBAQUAA4GNADCBiQKBgQCdH60mBM1eInACvOB83zLrtiebq9B5UBlAAVS8" + "9ucDwGx1HOJwhwk2AmvhN7pYuDc+BFzuNtgHojqZSDpRMA3rVsGlgOkZ3sOQzvxB73w+/X" + "XmCYpwcEGLpK4egl8r1aOYm0Zm4OxqWhNu9+Do7nrJczDLi8k/qh8/+Rfdtvt4kwIDAQAB" + "o1IwUDAOBgNVHQ8BAf8EBAMCBeAwFgYDVR0gBA8wDTALBglghkgBZQMBMAEwEQYDVR0OBA" + "oECEmVurZ+7UXFMBMGA1UdIwQMMAqACJBEcZsMRq6CMA0GCSqGSIb3DQEBBQUAA4GBAANe" + "AbvpAHwBu9+FlI4DOb65Z+h5f2Ok59FVbVqAj3zkMRkawppngK3CMY/1BQlGXOlHvE+CGz" + "x/7DsiV0O3rxOUjutt00PNxCyIM2pcOZeGUaAu5DJWn0SRwzTMJa4M5K+7wh/4sSPWyxKi" + "ueDq2VXvIgAfEVC8Lv44sxcOduSZ"; public static final String[] TEST_60_DATA = new String[] { Intermediate_Certificate_1_PL_01_07_crt, Intermediate_Certificate_2_PL_01_07_crt, Intermediate_Certificate_3_PL_01_07_crt, Intermediate_Certificate_4_PL_01_07_crt, Intermediate_CRL_1_PL_01_07_crl, Intermediate_CRL_2_PL_01_07_crl, Intermediate_CRL_3_PL_01_07_crl, Intermediate_CRL_4_PL_01_07_crl, End_Certificate_PL_01_07_crt }; /* * test61 * */ public static final String Intermediate_Certificate_1_PL_01_08_crt = "MIICmTCCAgKgAwIBAgICAJ0wDQYJKoZIhvcNAQEFBQAwXjELMAkGA1UEBhMCVVMxGDAWBg" + "NVBAoTD1UuUy4gR292ZXJubWVudDEMMAoGA1UECxMDRG9EMRAwDgYDVQQLEwdUZXN0aW5n" + "MRUwEwYDVQQDEwxUcnVzdCBBbmNob3IwHhcNOTgwMTAxMTIwMTAwWhcNNDgwMTAxMTIwMT" + "AwWjBeMQswCQYDVQQGEwJVUzEYMBYGA1UEChMPVS5TLiBHb3Zlcm5tZW50MQwwCgYDVQQL" + "EwNEb2QxEDAOBgNVBAsTB1Rlc3RpbmcxFTATBgNVBAMTDENBMS1QTC4wMS4wODCBnzANBg" + "kqhkiG9w0BAQEFAAOBjQAwgYkCgYEAsr+i9HxgO6LnOa6xOHfe9BeLVTo4iZd8rp6UTc02" + "C0MmsSjvIgn3UiayU7aoHcTH8tAXSV5bn0CIH4B46qLym//oE69hUFImy6d1kKgNoaUKWB" + "HztKVtswSSPjIUf7pbyp0wasYMN6fIKYyLpLXUxzA2DrD0kP2Y8ElQJKl2HocCAwEAAaNm" + "MGQwEgYDVR0TAQH/BAgwBgEB/wIBBjAOBgNVHQ8BAf8EBAMCAQYwFgYDVR0gBA8wDTALBg" + "lghkgBZQMBMAEwEQYDVR0OBAoECPMW3WMPtaowMBMGA1UdIwQMMAqACKua6/nC51SPMA0G" + "CSqGSIb3DQEBBQUAA4GBAH2N6S9ggfmRJkzhs82uOPXaHF62YEg1pbNxaCyJJbSt2iIIyy" + "NPSlE1OufPPH3pO7p5xcYi90LCI//0tlUL8y7aULFNygbshFY3B8MSgCz3KPA3UKdtIZYe" + "7lqP9/ob5wmkjtLpx6oZ4/38jxqe37pH1IwVjaUnoeElSo3EkCI5"; public static final String Intermediate_Certificate_2_PL_01_08_crt = "MIICmTCCAgKgAwIBAgICAJ4wDQYJKoZIhvcNAQEFBQAwXjELMAkGA1UEBhMCVVMxGDAWBg" + "NVBAoTD1UuUy4gR292ZXJubWVudDEMMAoGA1UECxMDRG9kMRAwDgYDVQQLEwdUZXN0aW5n" + "MRUwEwYDVQQDEwxDQTEtUEwuMDEuMDgwHhcNOTgwMTAxMTIwMTAwWhcNNDgwMTAxMTIwMT" + "AwWjBeMQswCQYDVQQGEwJVUzEYMBYGA1UEChMPVS5TLiBHb3Zlcm5tZW50MQwwCgYDVQQL" + "EwNEb2QxEDAOBgNVBAsTB1Rlc3RpbmcxFTATBgNVBAMTDENBMi1QTC4wMS4wODCBnzANBg" + "kqhkiG9w0BAQEFAAOBjQAwgYkCgYEAqZZolrig33i1rEwdP1pin8a5PgzSk7fT+qhrJRCg" + "UTOW5WyPtakrLTUipDcR07t8tIe0NsjRoph7+fAwbjWBfbJdydndHHGx5BqWg8Xi4zFhFd" + "6Mc5O6KO7Yqxs8lmthv/RAdL4Eiir9d9hqskKOtQKbLWz+Bz3+9NwfLGzwzPcCAwEAAaNm" + "MGQwEgYDVR0TAQH/BAgwBgEB/wIBATAOBgNVHQ8BAf8EBAMCAQYwFgYDVR0gBA8wDTALBg" + "lghkgBZQMBMAEwEQYDVR0OBAoECFjxM3RkbbhNMBMGA1UdIwQMMAqACPMW3WMPtaowMA0G" + "CSqGSIb3DQEBBQUAA4GBAJOJKBubTS/kLnfXN5YbQfggxbO2c7DTxx2LhrnPiyVDEow+Xf" + "lMv4YK5olH6UUm02D8cv6Wxg4NeTtBBnwKQG/GV4Ssgc/rrpEzM7jFRQcUzPu0jfya2fX8" + "ZNBnSDjovlN6vmZHtiksjh66h3a0aVusEuOQXD29ogMR8qAGYQaZ"; public static final String Intermediate_Certificate_3_PL_01_08_crt = "MIICmTCCAgKgAwIBAgICAJ8wDQYJKoZIhvcNAQEFBQAwXjELMAkGA1UEBhMCVVMxGDAWBg" + "NVBAoTD1UuUy4gR292ZXJubWVudDEMMAoGA1UECxMDRG9kMRAwDgYDVQQLEwdUZXN0aW5n" + "MRUwEwYDVQQDEwxDQTItUEwuMDEuMDgwHhcNOTgwMTAxMTIwMTAwWhcNNDgwMTAxMTIwMT" + "AwWjBeMQswCQYDVQQGEwJVUzEYMBYGA1UEChMPVS5TLiBHb3Zlcm5tZW50MQwwCgYDVQQL" + "EwNEb2QxEDAOBgNVBAsTB1Rlc3RpbmcxFTATBgNVBAMTDENBMy1QTC4wMS4wODCBnzANBg" + "kqhkiG9w0BAQEFAAOBjQAwgYkCgYEAogLtEcWxzzkkIYe+KrwKhaQjjGQqy2KDsW00U5lx" + "+XJoT8eKd5pxFdCa0SPn/jkNILVeh07mIHec1WF8SOeveVT4Ewd3nG/6ZGoVVq6l0j+3RM" + "jpJbp26BPR69nFn6rmFUMoSNq0VG8Zl+UBqnjq83G3umJCJMMRekUTULSFEGUCAwEAAaNm" + "MGQwEgYDVR0TAQH/BAgwBgEB/wIBATAOBgNVHQ8BAf8EBAMCAQYwFgYDVR0gBA8wDTALBg" + "lghkgBZQMBMAEwEQYDVR0OBAoECGAFYeJIhrRzMBMGA1UdIwQMMAqACFjxM3RkbbhNMA0G" + "CSqGSIb3DQEBBQUAA4GBABHamiW7sPLQ83nXt3LZemcAp4QaDB8X94EuJGBwshEcKLoOHb" + "/3cZkPRbOiRQUh/YdpfyApndGFSi0DtwM2Z7yup+MzdrR0wzQoNS95A51nHE7XdCuVFemc" + "LTJ5rdd2BLK3OB5lQagVLzAY9Bs1vaeXKT2Cy+gSUkTIekWcsH3K"; public static final String Intermediate_Certificate_4_PL_01_08_crt = "MIICljCCAf+gAwIBAgICAKAwDQYJKoZIhvcNAQEFBQAwXjELMAkGA1UEBhMCVVMxGDAWBg" + "NVBAoTD1UuUy4gR292ZXJubWVudDEMMAoGA1UECxMDRG9kMRAwDgYDVQQLEwdUZXN0aW5n" + "MRUwEwYDVQQDEwxDQTMtUEwuMDEuMDgwHhcNOTgwMTAxMTIwMTAwWhcNNDgwMTAxMTIwMT" + "AwWjBeMQswCQYDVQQGEwJVUzEYMBYGA1UEChMPVS5TLiBHb3Zlcm5tZW50MQwwCgYDVQQL" + "EwNEb2QxEDAOBgNVBAsTB1Rlc3RpbmcxFTATBgNVBAMTDENBNC1QTC4wMS4wODCBnzANBg" + "kqhkiG9w0BAQEFAAOBjQAwgYkCgYEAxVjjKlLlZzeZhamPO2NDnRtWM1oWZ3/kdwdBRn50" + "o1NRXb60Ir2HjniK1dRdbijAvR5uItLe9tmj4nusBiaPUGM0HNlEdQWSzble8rvUsP0apw" + "uJusV7zLvzwwbgLbMYT+8lMhxWXM34xszP+dgjWASQOVao1Uqs/MLLibOuueUCAwEAAaNj" + "MGEwDwYDVR0TAQH/BAUwAwEB/zAOBgNVHQ8BAf8EBAMCAQYwFgYDVR0gBA8wDTALBglghk" + "gBZQMBMAEwEQYDVR0OBAoECFMFrvh2hQ18MBMGA1UdIwQMMAqACGAFYeJIhrRzMA0GCSqG" + "SIb3DQEBBQUAA4GBAFsCOJ4DzuMOKti5PvF71ZKOtcTHSv123ZNdPIbK6OatT9YhVuUOYB" + "AjMavggywrb+QOXOFfJMctQlS3y/JE9YyoNNt/4UTdx1jQ3I2ablonmzjt8eN5GJ9jUXth" + "fHjxnmGUeWlAvwMjEdzdigkyuWCi9LJfjyHtTjSf9n7w2rU+"; public static final String Intermediate_CRL_1_PL_01_08_crl = "MIIBSzCBtQIBATANBgkqhkiG9w0BAQUFADBeMQswCQYDVQQGEwJVUzEYMBYGA1UEChMPVS" + "5TLiBHb3Zlcm5tZW50MQwwCgYDVQQLEwNEb2QxEDAOBgNVBAsTB1Rlc3RpbmcxFTATBgNV" + "BAMTDENBMS1QTC4wMS4wOBcNOTkwMTAxMTIwMTAwWhcNNDgwMTAxMTIwMTAwWqAjMCEwCg" + "YDVR0UBAMCAQEwEwYDVR0jBAwwCoAI8xbdYw+1qjAwDQYJKoZIhvcNAQEFBQADgYEAG2Aq" + "R1oelnrTgh56m6Mm+Lsm0Sf+Ot1W7LzZmMDwoZgmGLcTduVktx+XrtiDDWsf58hmneT1q0" + "5wl4yNH8y/VCAA3SM/gOq4ddOEiS8GbuEYo5P/julH/U3g6M0vfPUZ5y+7V0s35jIbTkjX" + "76n3Rhf88nvTscYvMdqrYyUhAmg="; public static final String Intermediate_CRL_2_PL_01_08_crl = "MIIBSzCBtQIBATANBgkqhkiG9w0BAQUFADBeMQswCQYDVQQGEwJVUzEYMBYGA1UEChMPVS" + "5TLiBHb3Zlcm5tZW50MQwwCgYDVQQLEwNEb2QxEDAOBgNVBAsTB1Rlc3RpbmcxFTATBgNV" + "BAMTDENBMi1QTC4wMS4wOBcNOTkwMTAxMTIwMTAwWhcNNDgwMTAxMTIwMTAwWqAjMCEwCg" + "YDVR0UBAMCAQEwEwYDVR0jBAwwCoAIWPEzdGRtuE0wDQYJKoZIhvcNAQEFBQADgYEAX/+I" + "DkAx7PLTi2x6aYbLacPRaUSjMne84MDaEkYiA64Vo3eL6FbKe14z2mBsM2W7x8xDnxjZ0N" + "RbhcFZ2E6A1ct6HMunuKxjoROIsdWhrYMqJfKKMTWMviz1UjtupsGUWS0dVQCquAr6DJmr" + "W88P8wgiVH2VZsc+edDmCGDunrI="; public static final String Intermediate_CRL_3_PL_01_08_crl = "MIIBSzCBtQIBATANBgkqhkiG9w0BAQUFADBeMQswCQYDVQQGEwJVUzEYMBYGA1UEChMPVS" + "5TLiBHb3Zlcm5tZW50MQwwCgYDVQQLEwNEb2QxEDAOBgNVBAsTB1Rlc3RpbmcxFTATBgNV" + "BAMTDENBMy1QTC4wMS4wOBcNOTkwMTAxMTIwMTAwWhcNNDgwMTAxMTIwMTAwWqAjMCEwCg" + "YDVR0UBAMCAQEwEwYDVR0jBAwwCoAIYAVh4kiGtHMwDQYJKoZIhvcNAQEFBQADgYEASw1+" + "6rGDKgpUtXcCziQCjy8mHFD2zV6x/Ppxm2Gj0U+5eFnIbMPmr4TUYwfSOROUycsiJX/Wa8" + "HEuqWJhIdcsHMA7TYf0iSXK597Bljjg4F/1Rgz0wqLjgMuA59eFbKjJ6zP1E6Sv2Ck0Ea9" + "HJsv5zFA1ljVnNWoQwoHsuLk/wk="; public static final String Intermediate_CRL_4_PL_01_08_crl = "MIIBSzCBtQIBATANBgkqhkiG9w0BAQUFADBeMQswCQYDVQQGEwJVUzEYMBYGA1UEChMPVS" + "5TLiBHb3Zlcm5tZW50MQwwCgYDVQQLEwNEb2QxEDAOBgNVBAsTB1Rlc3RpbmcxFTATBgNV" + "BAMTDENBNC1QTC4wMS4wOBcNOTkwMTAxMTIwMTAwWhcNNDgwMTAxMTIwMTAwWqAjMCEwCg" + "YDVR0UBAMCAQEwEwYDVR0jBAwwCoAIUwWu+HaFDXwwDQYJKoZIhvcNAQEFBQADgYEAHHKd" + "U1SccTsK99BUDrvF930ejNRAvHQM9xv80wcUAy18x+TLwBH8vDTmP210/C5Zk9pQs+rLDd" + "doQQbWJrQkznyB1OSK0T41KZ9L0UE+YmFGJjz0PEzYHV0Kc57j5uc7Fsi8Xu20Y8JeTaJs" + "FUXVsvnCuoSxYmwY1futFWHJG7Q="; public static final String End_Certificate_PL_01_08_crt = "MIICljCCAf+gAwIBAgICAKEwDQYJKoZIhvcNAQEFBQAwXjELMAkGA1UEBhMCVVMxGDAWBg" + "NVBAoTD1UuUy4gR292ZXJubWVudDEMMAoGA1UECxMDRG9kMRAwDgYDVQQLEwdUZXN0aW5n" + "MRUwEwYDVQQDEwxDQTQtUEwuMDEuMDgwHhcNOTgwMTAxMTIwMTAwWhcNNDgwMTAxMTIwMT" + "AwWjBeMQswCQYDVQQGEwJVUzEYMBYGA1UEChMPVS5TLiBHb3Zlcm5tZW50MQwwCgYDVQQL" + "EwNEb2QxEDAOBgNVBAsTB1Rlc3RpbmcxFTATBgNVBAMTDENBNS1QTC4wMS4wODCBnzANBg" + "kqhkiG9w0BAQEFAAOBjQAwgYkCgYEAwgNkhQrcqmjhkES6DNAW3uQLKILcFlrFvOlWfDPo" + "ngXzCKeed85npqL+Enxo4sLarEiywuDLrDgPf0gKnZXQWBmzWViZhvTsiAemH7iNsNS68s" + "hhb0vnLzlPpDUJDv7KVKW8VbM7nvplKptlEE6g5kmj3iEmM4l2u8Z/pmQoTsMCAwEAAaNj" + "MGEwDwYDVR0TAQH/BAUwAwEB/zAOBgNVHQ8BAf8EBAMCAeYwFgYDVR0gBA8wDTALBglghk" + "gBZQMBMAEwEQYDVR0OBAoECLfApJ09y/ZNMBMGA1UdIwQMMAqACFMFrvh2hQ18MA0GCSqG" + "SIb3DQEBBQUAA4GBAG2ANLc/ib9ayz0B0L6/XQf/xuwETEq8kb5vWml/PbcFD1b/uwRHI8" + "vTvM559nZgtzkhS5ZAvNBTh1CB9Ox/nugHc4srbH6/Wcd94pMQx/sfCB/C6zZ5Tbm7Y4jp" + "hkjnxwGUYTvgNzxmaAPLyCfqY7KwhCSzns2M+yuncEKqlzuT"; public static final String[] TEST_61_DATA = new String[] { Intermediate_Certificate_1_PL_01_08_crt, Intermediate_Certificate_2_PL_01_08_crt, Intermediate_Certificate_3_PL_01_08_crt, Intermediate_Certificate_4_PL_01_08_crt, Intermediate_CRL_1_PL_01_08_crl, Intermediate_CRL_2_PL_01_08_crl, Intermediate_CRL_3_PL_01_08_crl, Intermediate_CRL_4_PL_01_08_crl, End_Certificate_PL_01_08_crt }; /* * test62 * */ public static final String Intermediate_Certificate_1_PL_01_09_crt = "MIICmTCCAgKgAwIBAgICAKIwDQYJKoZIhvcNAQEFBQAwXjELMAkGA1UEBhMCVVMxGDAWBg" + "NVBAoTD1UuUy4gR292ZXJubWVudDEMMAoGA1UECxMDRG9EMRAwDgYDVQQLEwdUZXN0aW5n" + "MRUwEwYDVQQDEwxUcnVzdCBBbmNob3IwHhcNOTgwMTAxMTIwMTAwWhcNNDgwMTAxMTIwMT" + "AwWjBeMQswCQYDVQQGEwJVUzEYMBYGA1UEChMPVS5TLiBHb3Zlcm5tZW50MQwwCgYDVQQL" + "EwNEb2QxEDAOBgNVBAsTB1Rlc3RpbmcxFTATBgNVBAMTDENBMS1QTC4wMS4wOTCBnzANBg" + "kqhkiG9w0BAQEFAAOBjQAwgYkCgYEA4slldx8rhfz5l2i0rwib2McrCyQkadTjJRoEGQCV" + "xT0dmw7GhDa6wJg2ozXLLk5y7ZCwlmBOTEoNbigHvcKSnJT8R/S+F4KqBz5d5dbRMNEKYz" + "jdbD7Sm7id+eyfq1s5cpmta2lBJ5gTaC9YPSOY2mucGcJ1muYzdOc6h+PCCNMCAwEAAaNm" + "MGQwEgYDVR0TAQH/BAgwBgEB/wIBBjAOBgNVHQ8BAf8EBAMCAQYwFgYDVR0gBA8wDTALBg" + "lghkgBZQMBMAEwEQYDVR0OBAoECO7tq4dJC8OgMBMGA1UdIwQMMAqACKua6/nC51SPMA0G" + "CSqGSIb3DQEBBQUAA4GBAHbth0HjAygIoWVrz59ZBPntOn5nzgUGpH60aSDOS6i9ZOKSoC" + "7wCOEt6IpKO7M7SNznxaX2uhFTYotneyq3qENvqZVXKhE6wQRsdK4kG10cxSB5AXPHJRgk" + "W9+p+Nb0iYVKwHdDCW8KHYIroGhSkKxuflwxhK6DcwQuA7y5q7r7"; public static final String Intermediate_Certificate_2_PL_01_09_crt = "MIICmTCCAgKgAwIBAgICAKMwDQYJKoZIhvcNAQEFBQAwXjELMAkGA1UEBhMCVVMxGDAWBg" + "NVBAoTD1UuUy4gR292ZXJubWVudDEMMAoGA1UECxMDRG9kMRAwDgYDVQQLEwdUZXN0aW5n" + "MRUwEwYDVQQDEwxDQTEtUEwuMDEuMDkwHhcNOTgwMTAxMTIwMTAwWhcNNDgwMTAxMTIwMT" + "AwWjBeMQswCQYDVQQGEwJVUzEYMBYGA1UEChMPVS5TLiBHb3Zlcm5tZW50MQwwCgYDVQQL" + "EwNEb2QxEDAOBgNVBAsTB1Rlc3RpbmcxFTATBgNVBAMTDENBMi1QTC4wMS4wOTCBnzANBg" + "kqhkiG9w0BAQEFAAOBjQAwgYkCgYEA70v7BFxmToZHF5M29JK6N0Ha6n729cv1U912mH9O" + "NTz9tafa+jv4W7njScv21CJbNlUO5rlAFcTlXY0U9vbqHEufhtwRQqi7+pkfa+Ig8bwl26" + "4U8L5rgmSvZJpEiiKfkmF2Rz9+zPPhHjk58ZcKoAcyhOdZ60KqmaaU/TVtEq8CAwEAAaNm" + "MGQwEgYDVR0TAQH/BAgwBgEB/wIBBDAOBgNVHQ8BAf8EBAMCAQYwFgYDVR0gBA8wDTALBg" + "lghkgBZQMBMAEwEQYDVR0OBAoECKOwR13+P/BlMBMGA1UdIwQMMAqACO7tq4dJC8OgMA0G" + "CSqGSIb3DQEBBQUAA4GBAN71oLHr0+uf6zCOC5L7oeCOGMUwvZyROu8eTztZrPYGjaamSm" + "Z0ZmUPOJP3g5nO6tHf34Tb9CTkwPdPicEaXuxflkSbJBV3mUFQ1BUDlyYTuaL8uT2N61dg" + "xt5RgYTIGsW3/2XrRvXsH91gSiEkccoUyjKnQcX3oZmEeITb6H8m"; public static final String Intermediate_Certificate_3_PL_01_09_crt = "MIICmTCCAgKgAwIBAgICAKQwDQYJKoZIhvcNAQEFBQAwXjELMAkGA1UEBhMCVVMxGDAWBg" + "NVBAoTD1UuUy4gR292ZXJubWVudDEMMAoGA1UECxMDRG9kMRAwDgYDVQQLEwdUZXN0aW5n" + "MRUwEwYDVQQDEwxDQTItUEwuMDEuMDkwHhcNOTgwMTAxMTIwMTAwWhcNNDgwMTAxMTIwMT" + "AwWjBeMQswCQYDVQQGEwJVUzEYMBYGA1UEChMPVS5TLiBHb3Zlcm5tZW50MQwwCgYDVQQL" + "EwNEb2QxEDAOBgNVBAsTB1Rlc3RpbmcxFTATBgNVBAMTDENBMy1QTC4wMS4wOTCBnzANBg" + "kqhkiG9w0BAQEFAAOBjQAwgYkCgYEAwMLmDs63ai7i4xC/1ufMFWeigJAlbKWMti/PeEKi" + "7LBfNJDRaO+1kde6QIo1vhkhKtokNu9ue3Rfo1+xGuZVohjRbHnmamEm5G3jihegPQgGCR" + "fDZoJDI9HMbwBa0RWw1Nes5igIVjdSHQKO/XTul1yyF2Dt03K2qeLwes+2FyECAwEAAaNm" + "MGQwEgYDVR0TAQH/BAgwBgEB/wIBATAOBgNVHQ8BAf8EBAMCAQYwFgYDVR0gBA8wDTALBg" + "lghkgBZQMBMAEwEQYDVR0OBAoECPEAjG80q0FoMBMGA1UdIwQMMAqACKOwR13+P/BlMA0G" + "CSqGSIb3DQEBBQUAA4GBAN9eiZXma2n0XgzdvYrlV/IEqBIhpcZ7gycjDumVBVITZJD2sJ" + "bkBi+N8dg7uovgxGxWGsyxqgAboLhMgbpbFzGh+HyIhQu/CeAx93PWYc5rP2l2Y8d7KJvk" + "p1GZEcG/nTakpjxTQ5MQYFsOHVsnDDOyaZYvqPuMrwGYsfoUa1wq"; public static final String Intermediate_Certificate_4_PL_01_09_crt = "MIICljCCAf+gAwIBAgICAKUwDQYJKoZIhvcNAQEFBQAwXjELMAkGA1UEBhMCVVMxGDAWBg" + "NVBAoTD1UuUy4gR292ZXJubWVudDEMMAoGA1UECxMDRG9kMRAwDgYDVQQLEwdUZXN0aW5n" + "MRUwEwYDVQQDEwxDQTMtUEwuMDEuMDkwHhcNOTgwMTAxMTIwMTAwWhcNNDgwMTAxMTIwMT" + "AwWjBeMQswCQYDVQQGEwJVUzEYMBYGA1UEChMPVS5TLiBHb3Zlcm5tZW50MQwwCgYDVQQL" + "EwNEb2QxEDAOBgNVBAsTB1Rlc3RpbmcxFTATBgNVBAMTDENBNC1QTC4wMS4wOTCBnzANBg" + "kqhkiG9w0BAQEFAAOBjQAwgYkCgYEAo4L9QEqzq2VXzkZI3cvUWR5v6vreKKQPfJPfEwNH" + "nMS0cgDjC4Fnw9ySI7Eb4A/OJGLIyg84mzTl6JX3kGoYr9/bJ8jOD7pN6CljXuHpwwmd7L" + "6Nf5Hy0ltjAIr5s67e33OWdPi4gApS4FN6nPSDkZotY73d1xqJYQQZWuNEsGUCAwEAAaNj" + "MGEwDwYDVR0TAQH/BAUwAwEB/zAOBgNVHQ8BAf8EBAMCAQYwFgYDVR0gBA8wDTALBglghk" + "gBZQMBMAEwEQYDVR0OBAoECLfU7BuxzXeCMBMGA1UdIwQMMAqACPEAjG80q0FoMA0GCSqG" + "SIb3DQEBBQUAA4GBABmQZOvwRpVsTD8uazfQpLJUZkuTap4OOPHie5xJsvOhGend2k+LiP" + "7btGoFrqmkyVV/+dNA8+45SRsnoOtgctiF2ubeqIvd7xf/J5C9Cmo+T89Mt7WEBEuDmEZm" + "JPXvOvyh6lRcYVSBnvVW5ZSstNAQKa/8xuyN0OrE1hJWbucn"; public static final String Intermediate_CRL_1_PL_01_09_crl = "MIIBSzCBtQIBATANBgkqhkiG9w0BAQUFADBeMQswCQYDVQQGEwJVUzEYMBYGA1UEChMPVS" + "5TLiBHb3Zlcm5tZW50MQwwCgYDVQQLEwNEb2QxEDAOBgNVBAsTB1Rlc3RpbmcxFTATBgNV" + "BAMTDENBMS1QTC4wMS4wORcNOTkwMTAxMTIwMTAwWhcNNDgwMTAxMTIwMTAwWqAjMCEwCg" + "YDVR0UBAMCAQEwEwYDVR0jBAwwCoAI7u2rh0kLw6AwDQYJKoZIhvcNAQEFBQADgYEAbXc1" + "QgR2TAvOPqJmRFFrDQkPVIVyEEDTwZy5aNnoAKK+AmJ5FZkBtbPJ8qt9UeYRh8lbX8+EIk" + "tyrAKw/1Kc3h7RDqAQ/p8t8kFwVQh2l4KTIukV8hYcj5sMKlt5f49ZwzWPyoOaLDomiUfI" + "OY/jaDMw293AjQXxGCDtnaTvh0o="; public static final String Intermediate_CRL_2_PL_01_09_crl = "MIIBSzCBtQIBATANBgkqhkiG9w0BAQUFADBeMQswCQYDVQQGEwJVUzEYMBYGA1UEChMPVS" + "5TLiBHb3Zlcm5tZW50MQwwCgYDVQQLEwNEb2QxEDAOBgNVBAsTB1Rlc3RpbmcxFTATBgNV" + "BAMTDENBMi1QTC4wMS4wORcNOTkwMTAxMTIwMTAwWhcNNDgwMTAxMTIwMTAwWqAjMCEwCg" + "YDVR0UBAMCAQEwEwYDVR0jBAwwCoAIo7BHXf4/8GUwDQYJKoZIhvcNAQEFBQADgYEAq6en" + "XtvIdh/DifGzWn11hqJIZxLQDGJZPoMmwSOLyB6OzsPrIg1xkOWZYEOELTR8+qP6emmx+D" + "CaEbUDLj60rso0gRQCBwTgHgjeMRpv8fGnV8MJgMv5BdzsGAGQbLSSY9FxtqeCPfZ6olHC" + "iUIopdZJZP8ZvGKQ6QGaMnLpJ78="; public static final String Intermediate_CRL_3_PL_01_09_crl = "MIIBSzCBtQIBATANBgkqhkiG9w0BAQUFADBeMQswCQYDVQQGEwJVUzEYMBYGA1UEChMPVS" + "5TLiBHb3Zlcm5tZW50MQwwCgYDVQQLEwNEb2QxEDAOBgNVBAsTB1Rlc3RpbmcxFTATBgNV" + "BAMTDENBMy1QTC4wMS4wORcNOTkwMTAxMTIwMTAwWhcNNDgwMTAxMTIwMTAwWqAjMCEwCg" + "YDVR0UBAMCAQEwEwYDVR0jBAwwCoAI8QCMbzSrQWgwDQYJKoZIhvcNAQEFBQADgYEAraCx" + "ruxopFbKvxOx/CIF4niG27ABB2ZwU6n4NBGYHo1Y9NjuytjjMZvQjMHyoayqpnF5TA1vXL" + "jXjI3VgQcK7A4ah/0FNLFGtczyY8kXXrpbmdg8+xdNJEG3/e5rDW5VSf7OY1XqU85ySUJQ" + "ZR5uiy8LxlDdaIT4WT7X5ezs3wk="; public static final String Intermediate_CRL_4_PL_01_09_crl = "MIIBSzCBtQIBATANBgkqhkiG9w0BAQUFADBeMQswCQYDVQQGEwJVUzEYMBYGA1UEChMPVS" + "5TLiBHb3Zlcm5tZW50MQwwCgYDVQQLEwNEb2QxEDAOBgNVBAsTB1Rlc3RpbmcxFTATBgNV" + "BAMTDENBNC1QTC4wMS4wORcNOTkwMTAxMTIwMTAwWhcNNDgwMTAxMTIwMTAwWqAjMCEwCg" + "YDVR0UBAMCAQEwEwYDVR0jBAwwCoAIt9TsG7HNd4IwDQYJKoZIhvcNAQEFBQADgYEATtjA" + "BdSZYnIbv1bCL+aSiioJg9S9yWGD1mjsA/CDzvkzSffeSpvqaSy+Zwwf+NDMMG6Cs+SgU+" + "sxQdJALAbb4sYGEyXj/Exh9BYHvgoVahH4NWuhm6LIN8RTcMDAtGoGYFNGXGuT8XRBUJZ/" + "tH9re3gpWaE1rjWeB/2ZBR5ONcM="; public static final String End_Certificate_PL_01_09_crt = "MIIChzCCAfCgAwIBAgICAKYwDQYJKoZIhvcNAQEFBQAwXjELMAkGA1UEBhMCVVMxGDAWBg" + "NVBAoTD1UuUy4gR292ZXJubWVudDEMMAoGA1UECxMDRG9kMRAwDgYDVQQLEwdUZXN0aW5n" + "MRUwEwYDVQQDEwxDQTQtUEwuMDEuMDkwHhcNOTgwMTAxMTIwMTAwWhcNNDgwMTAxMTIwMT" + "AwWjBgMQswCQYDVQQGEwJVUzEYMBYGA1UEChMPVS5TLiBHb3Zlcm5tZW50MQwwCgYDVQQL" + "EwNEb0QxEDAOBgNVBAsTB1Rlc3RpbmcxFzAVBgNVBAMTDlVzZXIxLVBMLjAxLjA5MIGfMA" + "0GCSqGSIb3DQEBAQUAA4GNADCBiQKBgQC+g1Puqjn+/Of35mqVVUricIV5x+bpZRCAgBDh" + "VYcmZFXLB/XnRd/mYTu0RR4ISEerC1km5tjGeCN2k3NGdZwz/wEh9kEL8WikSqpxUSUD/N" + "vQbliz4f3YECLcpNXKzkCvszeB5ZGHa0sLYDg3r62wy+1y2rtcrHzFEoMFgnnruwIDAQAB" + "o1IwUDAOBgNVHQ8BAf8EBAMCBeAwFgYDVR0gBA8wDTALBglghkgBZQMBMAEwEQYDVR0OBA" + "oECANGcL2klYf7MBMGA1UdIwQMMAqACLfU7BuxzXeCMA0GCSqGSIb3DQEBBQUAA4GBAHm+" + "/vQ7VxDry3VqiqKnNoOhAHTTIUphNWF4jddRqVc32IsjVaeTbcGwCIRflRm/lUplRvXXxb" + "JEbW9mP3nfTCREUdm49hjmo/szsPjgosFoEmuEKXThC81/y2vQkb4/jqRoOHEknU++38EU" + "Juv6Y6psZNa37x8Yn3i7S+b3TM2q"; public static final String[] TEST_62_DATA = new String[] { Intermediate_Certificate_1_PL_01_09_crt, Intermediate_Certificate_2_PL_01_09_crt, Intermediate_Certificate_3_PL_01_09_crt, Intermediate_Certificate_4_PL_01_09_crt, Intermediate_CRL_1_PL_01_09_crl, Intermediate_CRL_2_PL_01_09_crl, Intermediate_CRL_3_PL_01_09_crl, Intermediate_CRL_4_PL_01_09_crl, End_Certificate_PL_01_09_crt }; /* * test63 * */ public static final String Intermediate_Certificate_1_PL_01_10_crt = "MIICmTCCAgKgAwIBAgICAKcwDQYJKoZIhvcNAQEFBQAwXjELMAkGA1UEBhMCVVMxGDAWBg" + "NVBAoTD1UuUy4gR292ZXJubWVudDEMMAoGA1UECxMDRG9EMRAwDgYDVQQLEwdUZXN0aW5n" + "MRUwEwYDVQQDEwxUcnVzdCBBbmNob3IwHhcNOTgwMTAxMTIwMTAwWhcNNDgwMTAxMTIwMT" + "AwWjBeMQswCQYDVQQGEwJVUzEYMBYGA1UEChMPVS5TLiBHb3Zlcm5tZW50MQwwCgYDVQQL" + "EwNEb2QxEDAOBgNVBAsTB1Rlc3RpbmcxFTATBgNVBAMTDENBMS1QTC4wMS4xMDCBnzANBg" + "kqhkiG9w0BAQEFAAOBjQAwgYkCgYEAr4LmuvhSms70CnuAHIHwz45csKvBPVtcDjA1tWNb" + "NIvvNHBzyt6G8U4CTVKmsFAZOzrWJem3b/ZywM1WlDarGJAAa/SRIYZ/jQwaOIoPW4OUfK" + "ZQI6MO7uAPcIQ4ugtPth10viVqZYLZn/6O26Q905YsFltuPFl64KrJVJJBlLECAwEAAaNm" + "MGQwEgYDVR0TAQH/BAgwBgEB/wIBBjAOBgNVHQ8BAf8EBAMCAQYwFgYDVR0gBA8wDTALBg" + "lghkgBZQMBMAEwEQYDVR0OBAoECGRn9ckrcsEdMBMGA1UdIwQMMAqACKua6/nC51SPMA0G" + "CSqGSIb3DQEBBQUAA4GBANK+1qalm7Nl+PJHT9nQLVJ3ruQNAoMlH9fN52Q9BZCr30iWCd" + "+GhQIPRjxZ4GWojMnqbWzYQsxIR2PLdFc6SwjQrq+i2ES/LePDtaLQddS44/+GP/+qDpM9" + "Mqp3/Nbe1MfOKRBT57qgrxa8eUVieysoKeYX6yQpa8bab3qDwOTH"; public static final String Intermediate_Certificate_2_PL_01_10_crt = "MIICmTCCAgKgAwIBAgICAKgwDQYJKoZIhvcNAQEFBQAwXjELMAkGA1UEBhMCVVMxGDAWBg" + "NVBAoTD1UuUy4gR292ZXJubWVudDEMMAoGA1UECxMDRG9kMRAwDgYDVQQLEwdUZXN0aW5n" + "MRUwEwYDVQQDEwxDQTEtUEwuMDEuMTAwHhcNOTgwMTAxMTIwMTAwWhcNNDgwMTAxMTIwMT" + "AwWjBeMQswCQYDVQQGEwJVUzEYMBYGA1UEChMPVS5TLiBHb3Zlcm5tZW50MQwwCgYDVQQL" + "EwNEb2QxEDAOBgNVBAsTB1Rlc3RpbmcxFTATBgNVBAMTDENBMi1QTC4wMS4xMDCBnzANBg" + "kqhkiG9w0BAQEFAAOBjQAwgYkCgYEAx5tMLJ3LRxi9jAzCSNkj8zyrSO0cImNGf6ZCIzEU" + "V8LrmXjgiZboPTh9LWQ3msWDLpzaxVxDLBXG3eMO8ys46TfJKciyeoiB8wfuNGMKAccm8u" + "43XjWs1KAdNikWEZupYPgdmA92oRlVcHshG9PqP4+xA6sydpu3V18Nyfa0n3MCAwEAAaNm" + "MGQwEgYDVR0TAQH/BAgwBgEB/wIBBDAOBgNVHQ8BAf8EBAMCAQYwFgYDVR0gBA8wDTALBg" + "lghkgBZQMBMAEwEQYDVR0OBAoECDE3dDXkS7TxMBMGA1UdIwQMMAqACGRn9ckrcsEdMA0G" + "CSqGSIb3DQEBBQUAA4GBAE+8cyOUQ7y4atc4BlZNZvGNRZ63dbGDCM2AItTEAf4ETM9v7j" + "biUWTirJyoWsGxm2eIUk1V+EKxcuO3FotFUe7lS6thmVd6OYOSW+02RXMNklmptzK9I3AK" + "DZNh82ugLNyrrd06BSiED+0MoGVVI4gi3wdFtRiai+MgQVeWIB4i"; public static final String Intermediate_Certificate_3_PL_01_10_crt = "MIICmTCCAgKgAwIBAgICAKkwDQYJKoZIhvcNAQEFBQAwXjELMAkGA1UEBhMCVVMxGDAWBg" + "NVBAoTD1UuUy4gR292ZXJubWVudDEMMAoGA1UECxMDRG9kMRAwDgYDVQQLEwdUZXN0aW5n" + "MRUwEwYDVQQDEwxDQTItUEwuMDEuMTAwHhcNOTgwMTAxMTIwMTAwWhcNNDgwMTAxMTIwMT" + "AwWjBeMQswCQYDVQQGEwJVUzEYMBYGA1UEChMPVS5TLiBHb3Zlcm5tZW50MQwwCgYDVQQL" + "EwNEb2QxEDAOBgNVBAsTB1Rlc3RpbmcxFTATBgNVBAMTDENBMy1QTC4wMS4xMDCBnzANBg" + "kqhkiG9w0BAQEFAAOBjQAwgYkCgYEAsmSUL/UZBYMdqU0PecjCd+9U+1Ld3mKkH303Fido" + "K6k5S4ZObxVHKhYDJyp3CcVT2+nENjzIfQQQaA11UK7Uf/jmVs0IC8e2scWzq0W2BeOLef" + "jVgNgXGsXyfLi9T4KJPPyGsKlIU2R2xKxgHmAOt/tw6OYX/OaEfM1jiQza5lkCAwEAAaNm" + "MGQwEgYDVR0TAQH/BAgwBgEB/wIBATAOBgNVHQ8BAf8EBAMCAQYwFgYDVR0gBA8wDTALBg" + "lghkgBZQMBMAEwEQYDVR0OBAoECHYI07i4owpIMBMGA1UdIwQMMAqACDE3dDXkS7TxMA0G" + "CSqGSIb3DQEBBQUAA4GBAK23Kx99Y9HtFBVnHWW/NfvNro7I5Wx/ZCko6ulHm84FPAjhnL" + "tvc4jmfAZd0wYPKQKWwUKUDWNEwIU1qkxyJYACckue35GLzj8aLY/z+h037vGonFmNutMM" + "rcRdiV7gVD17dYLVTt0RgxsDVDtut+twqHgIaKtKyJnl9dSgFFv1"; public static final String Intermediate_Certificate_4_PL_01_10_crt = "MIICljCCAf+gAwIBAgICAKowDQYJKoZIhvcNAQEFBQAwXjELMAkGA1UEBhMCVVMxGDAWBg" + "NVBAoTD1UuUy4gR292ZXJubWVudDEMMAoGA1UECxMDRG9kMRAwDgYDVQQLEwdUZXN0aW5n" + "MRUwEwYDVQQDEwxDQTMtUEwuMDEuMTAwHhcNOTgwMTAxMTIwMTAwWhcNNDgwMTAxMTIwMT" + "AwWjBeMQswCQYDVQQGEwJVUzEYMBYGA1UEChMPVS5TLiBHb3Zlcm5tZW50MQwwCgYDVQQL" + "EwNEb2QxEDAOBgNVBAsTB1Rlc3RpbmcxFTATBgNVBAMTDENBNC1QTC4wMS4xMDCBnzANBg" + "kqhkiG9w0BAQEFAAOBjQAwgYkCgYEArgBnLCnqI6Sa7gXkZOvIKH4EL5i3CoG6eGG2R8aA" + "kjBs78IKGYj9gY7rRajAKSpf19zvfcW8+2gBDDj5AoCy6uDnBICmqdu+hkdokVi8dJHiTU" + "9LdS2TeuvFv47eiXoEBjMEAquCuSyHvW3lNrA+ESTnK3s7V4lBoO+o5mZD6dsCAwEAAaNj" + "MGEwDwYDVR0TAQH/BAUwAwEB/zAOBgNVHQ8BAf8EBAMCAQYwFgYDVR0gBA8wDTALBglghk" + "gBZQMBMAEwEQYDVR0OBAoECLTgYziQC9zmMBMGA1UdIwQMMAqACHYI07i4owpIMA0GCSqG" + "SIb3DQEBBQUAA4GBAEx8wgBjBglU98rocddKAEKXkt4MNzrpUMq75C9HtnuOtFgM2oY/OC" + "x67aZSTEph9ag6Hc+MyxWB5rzGD9j0y7OLsasE9AX8vjplUq50wq1xAFkGi1GnqRK/Oe7D" + "S6R66+UFHW/3KAeNe96aaJuMcx0TRbfkGbW1ASSi/ixMd9Gi"; public static final String Intermediate_CRL_1_PL_01_10_crl = "MIIBSzCBtQIBATANBgkqhkiG9w0BAQUFADBeMQswCQYDVQQGEwJVUzEYMBYGA1UEChMPVS" + "5TLiBHb3Zlcm5tZW50MQwwCgYDVQQLEwNEb2QxEDAOBgNVBAsTB1Rlc3RpbmcxFTATBgNV" + "BAMTDENBMS1QTC4wMS4xMBcNOTkwMTAxMTIwMTAwWhcNNDgwMTAxMTIwMTAwWqAjMCEwCg" + "YDVR0UBAMCAQEwEwYDVR0jBAwwCoAIZGf1yStywR0wDQYJKoZIhvcNAQEFBQADgYEAjkY5" + "nXjLst8CMz0fyEM7Ft2d9TOOJXV4TMAfSAP9QCnit8qzrdVdJ6TJIsJNZYBz9Ryr5K/iSw" + "KbYk0g6y/pskcMoHG3vJwNAxBbkf+fV7Eyve+90Z6oWDXHKLGCQQpdZ0a0wAqYeiScok8+" + "YHypEVLfbjWARR9fsci2Ps3tdvA="; public static final String Intermediate_CRL_2_PL_01_10_crl = "MIIBSzCBtQIBATANBgkqhkiG9w0BAQUFADBeMQswCQYDVQQGEwJVUzEYMBYGA1UEChMPVS" + "5TLiBHb3Zlcm5tZW50MQwwCgYDVQQLEwNEb2QxEDAOBgNVBAsTB1Rlc3RpbmcxFTATBgNV" + "BAMTDENBMi1QTC4wMS4xMBcNOTkwMTAxMTIwMTAwWhcNNDgwMTAxMTIwMTAwWqAjMCEwCg" + "YDVR0UBAMCAQEwEwYDVR0jBAwwCoAIMTd0NeRLtPEwDQYJKoZIhvcNAQEFBQADgYEAdpTU" + "xcywBjX2rD8Gu6zkDqlDmZfRXHDPtnf2RB4bHDx77kDEib6nH6DGoJdx8WnRTZsTjly3MG" + "62LfVmjp/bJyKHUQqBDrilv21EWsaI9JOr673Nk5iTZa/645GdgyLzSmxvcVDN40BAH0py" + "/2gvBQTPNzp2W1IR2mebuLdHwTI="; public static final String Intermediate_CRL_3_PL_01_10_crl = "MIIBSzCBtQIBATANBgkqhkiG9w0BAQUFADBeMQswCQYDVQQGEwJVUzEYMBYGA1UEChMPVS" + "5TLiBHb3Zlcm5tZW50MQwwCgYDVQQLEwNEb2QxEDAOBgNVBAsTB1Rlc3RpbmcxFTATBgNV" + "BAMTDENBMy1QTC4wMS4xMBcNOTkwMTAxMTIwMTAwWhcNNDgwMTAxMTIwMTAwWqAjMCEwCg" + "YDVR0UBAMCAQEwEwYDVR0jBAwwCoAIdgjTuLijCkgwDQYJKoZIhvcNAQEFBQADgYEATVf2" + "cEEGphsIe0AsqNJ5rENLe8DeDAV8R4XCKdeP5qmHmLMm9Z4pX8bIfU7bCoXiNIwGvIU6ag" + "FmHPNHEj70cQFVqCX/ZESc02hit+Os9g7pcl7s9QgwVUCMZdCiF/+pSEp3eCL5tFoKmAZe" + "nxkL0KOSuKmBzuqRtZufbhDvmbw="; public static final String Intermediate_CRL_4_PL_01_10_crl = "MIIBSzCBtQIBATANBgkqhkiG9w0BAQUFADBeMQswCQYDVQQGEwJVUzEYMBYGA1UEChMPVS" + "5TLiBHb3Zlcm5tZW50MQwwCgYDVQQLEwNEb2QxEDAOBgNVBAsTB1Rlc3RpbmcxFTATBgNV" + "BAMTDENBNC1QTC4wMS4xMBcNOTkwMTAxMTIwMTAwWhcNNDgwMTAxMTIwMTAwWqAjMCEwCg" + "YDVR0UBAMCAQEwEwYDVR0jBAwwCoAItOBjOJAL3OYwDQYJKoZIhvcNAQEFBQADgYEAbG2B" + "BhvRQ1pY/8VFeiCRFD8mBzq5iW5hWv2P7Zdp9zEbQo0fI4Kbis3OGemEttCxvAc/UPfogr" + "UudImf3s8sLV9BS59xQUGQlxZ5XBNlripY8EjHNWrwgy7/x4hzlZ9yYBbqoNOqnHLy/gbM" + "XZWoCbIK0co70lh1soOQ6eqLDKM="; public static final String End_Certificate_PL_01_10_crt = "MIICljCCAf+gAwIBAgICAKswDQYJKoZIhvcNAQEFBQAwXjELMAkGA1UEBhMCVVMxGDAWBg" + "NVBAoTD1UuUy4gR292ZXJubWVudDEMMAoGA1UECxMDRG9kMRAwDgYDVQQLEwdUZXN0aW5n" + "MRUwEwYDVQQDEwxDQTQtUEwuMDEuMTAwHhcNOTgwMTAxMTIwMTAwWhcNNDgwMTAxMTIwMT" + "AwWjBeMQswCQYDVQQGEwJVUzEYMBYGA1UEChMPVS5TLiBHb3Zlcm5tZW50MQwwCgYDVQQL" + "EwNEb2QxEDAOBgNVBAsTB1Rlc3RpbmcxFTATBgNVBAMTDENBNS1QTC4wMS4xMDCBnzANBg" + "kqhkiG9w0BAQEFAAOBjQAwgYkCgYEA3bx0qx8s4Zse6Ri6NqkLEKUPLIOhTFj/9Dh7sxvE" + "HpemBlTjbp2in08WTxEb9n8iAIWuGs3Vqm82ttBQmayjIaWD5oE/BE0oV/e91NAv/aRLsl" + "f7VtOb6vi8Ef6muOAjI2dUaUD6QONkqkJhnZ353uR3LZnsAEAW+InePGFNEGkCAwEAAaNj" + "MGEwDwYDVR0TAQH/BAUwAwEB/zAOBgNVHQ8BAf8EBAMCAeYwFgYDVR0gBA8wDTALBglghk" + "gBZQMBMAEwEQYDVR0OBAoECIokB8m8Vi4QMBMGA1UdIwQMMAqACLTgYziQC9zmMA0GCSqG" + "SIb3DQEBBQUAA4GBAKBGQwZQLQFXb+/kjP5xAtq+1rRtrblytjpv3ujJrKH1v2VB2+9boB" + "0YYYGJTy2Wuj0ZBEMeTzMO8Hol4Mq9pnYv5DCmfnZN3FuDidgnRsCjM3ZL7NcXXG9YwlKF" + "G2SXj0YfkSwN9gnyN11W8i+F/OSjlm+TDKHB3ePMcY8EnnXy"; public static final String[] TEST_63_DATA = new String[] { Intermediate_Certificate_1_PL_01_10_crt, Intermediate_Certificate_2_PL_01_10_crt, Intermediate_Certificate_3_PL_01_10_crt, Intermediate_Certificate_4_PL_01_10_crt, Intermediate_CRL_1_PL_01_10_crl, Intermediate_CRL_2_PL_01_10_crl, Intermediate_CRL_3_PL_01_10_crl, Intermediate_CRL_4_PL_01_10_crl, End_Certificate_PL_01_10_crt }; /* * test64 * */ public static final String Intermediate_Certificate_RL_02_01_crt = "MIICljCCAf+gAwIBAgICAKwwDQYJKoZIhvcNAQEFBQAwXjELMAkGA1UEBhMCVVMxGDAWBg" + "NVBAoTD1UuUy4gR292ZXJubWVudDEMMAoGA1UECxMDRG9EMRAwDgYDVQQLEwdUZXN0aW5n" + "MRUwEwYDVQQDEwxUcnVzdCBBbmNob3IwHhcNOTgwMTAxMTIwMTAwWhcNNDgwMTAxMTIwMT" + "AwWjBeMQswCQYDVQQGEwJVUzEYMBYGA1UEChMPVS5TLiBHb3Zlcm5tZW50MQwwCgYDVQQL" + "EwNEb2QxEDAOBgNVBAsTB1Rlc3RpbmcxFTATBgNVBAMTDENBMS1STC4wMi4wMTCBnzANBg" + "kqhkiG9w0BAQEFAAOBjQAwgYkCgYEA3AN+Y3Hl/9V0nKXHQotb/cA2VfZc5vrRu+ZjwKgK" + "6KasGegAorKSTybYX/fTbnaPwykDPfSscAnzAW5WdF9+wTLmvYc+6pkcx1ryKkGmofFMXi" + "bZ5LUO/oK0iuNjBKfLdWoi+hpciKyPb9Bs8SO/svKSNqTEbn9ts3q6tpbngoECAwEAAaNj" + "MGEwDwYDVR0TAQH/BAUwAwEB/zAOBgNVHQ8BAf8EBAMCAQYwFgYDVR0gBA8wDTALBglghk" + "gBZQMBMAEwEQYDVR0OBAoECGXQ07qiAqv2MBMGA1UdIwQMMAqACKua6/nC51SPMA0GCSqG" + "SIb3DQEBBQUAA4GBADKtN3OOaRdte0X4xLC6nTGaK/u7IEKQ0DjduDHwJR5w27zefrx48Z" + "dlq8t5lAfQJqWmfk7iCIW1QJPLcZOouWDP2S9Cb0YooGQRIEkMjpBn3Xufx0XUphtCDs3W" + "9LAMVXqfuce1tpZ6Dvrh6/H2X8rJMU29Czsz949bh6tcsHJi"; public static final String Intermediate_CRL_RL_02_01_crl = "MIIBSzCBtQIBATANBgkqhkiG9w0BAQUFADBeMQswCQYDVQQGEwJVUzEYMBYGA1UEChMPVS" + "5TLiBHb3Zlcm5tZW50MQwwCgYDVQQLEwNEb2QxEDAOBgNVBAsTB1Rlc3RpbmcxFTATBgNV" + "BAMTDENBMS1STC4wMi4wMRcNOTkwMTAxMTIwMTAwWhcNNDgwMTAxMTIwMTAwWqAjMCEwCg" + "YDVR0UBAMCAQEwEwYDVR0jBAwwCoAIZdDTuqICq/YwDQYJKoZIhvcNAQEFBQADgYEAxrDH" + "zKno1mkJqPTub0c9To6jC3CGTilV1E12oD0kFjkXqL40+W251qQ2wMC+G7ZrzBIc5dRuJ9" + "3feHZ7cc03/s3TziXDvSyfNOYpHzkPwT48HuSgBYgJ3uswwk+tDiA64NzbOJqssxxhFRok" + "9OpwC8eQkzgpA3a6816v2I3XL9s="; public static final String End_Certificate_RL_02_01_crt = "MIIChzCCAfCgAwIBAgICAK0wDQYJKoZIhvcNAQEFBQAwXjELMAkGA1UEBhMCVVMxGDAWBg" + "NVBAoTD1UuUy4gR292ZXJubWVudDEMMAoGA1UECxMDRG9kMRAwDgYDVQQLEwdUZXN0aW5n" + "MRUwEwYDVQQDEwxDQTEtUkwuMDIuMDEwHhcNOTgwMTAxMTIwMTAwWhcNNDgwMTAxMTIwMT" + "AwWjBgMQswCQYDVQQGEwJVUzEYMBYGA1UEChMPVS5TLiBHb3Zlcm5tZW50MQwwCgYDVQQL" + "EwNEb0QxEDAOBgNVBAsTB1Rlc3RpbmcxFzAVBgNVBAMTDlVzZXIxLVJMLjAyLjAxMIGfMA" + "0GCSqGSIb3DQEBAQUAA4GNADCBiQKBgQCykRGcIKuxia47yRmJT8XpNNi2LTTbUUTteIBp" + "DZBfz2ExeWLruO9Rn1/oB/EP+4apx4r9rQ2tGsvr/7qQYeQK8W7eJzZgvxFadY57IMfUNq" + "1nEnj0ZvuWrOSf+K9v6FWX5Y2uyZS5Uvb1VVQv0Ev890+yXTtthPTjepk3JkkouwIDAQAB" + "o1IwUDAOBgNVHQ8BAf8EBAMCBeAwFgYDVR0gBA8wDTALBglghkgBZQMBMAEwEQYDVR0OBA" + "oECFIkVrx7NRAdMBMGA1UdIwQMMAqACGXQ07qiAqv2MA0GCSqGSIb3DQEBBQUAA4GBAI+B" + "T6bFZruoeFHXsYVjkQ42jSdYB9JuQkG7JLKte5gGlhyR+jMlJBzxBgNIfvlmYSnbRFPbE8" + "eqsGm90hJJoUuVMkm0i03H13uddlS494O6HhTGpaKcYwp3hbLhVcaY3wFTqTCuZk1T7Oxq" + "ggTrCDYvNH+/ZpQuy6nB/FH3SAHS"; public static final String[] TEST_64_DATA = new String[] { Intermediate_Certificate_RL_02_01_crt, Intermediate_CRL_RL_02_01_crl, End_Certificate_RL_02_01_crt }; /* * test65 * */ public static final String Intermediate_Certificate_1_RL_03_01_crt = "MIICljCCAf+gAwIBAgICAK4wDQYJKoZIhvcNAQEFBQAwXjELMAkGA1UEBhMCVVMxGDAWBg" + "NVBAoTD1UuUy4gR292ZXJubWVudDEMMAoGA1UECxMDRG9EMRAwDgYDVQQLEwdUZXN0aW5n" + "MRUwEwYDVQQDEwxUcnVzdCBBbmNob3IwHhcNOTgwMTAxMTIwMTAwWhcNNDgwMTAxMTIwMT" + "AwWjBeMQswCQYDVQQGEwJVUzEYMBYGA1UEChMPVS5TLiBHb3Zlcm5tZW50MQwwCgYDVQQL" + "EwNEb2QxEDAOBgNVBAsTB1Rlc3RpbmcxFTATBgNVBAMTDENBMS1STC4wMy4wMTCBnzANBg" + "kqhkiG9w0BAQEFAAOBjQAwgYkCgYEAsZG8wsV3Kuo+jtnKxLYGBuAqQwUh6Cs7ioDTNUFI" + "UDDJ0lOP1HVTMBA7DEcyTCGvnQ02dEVVuCddBTQvG5RvW7G7cCEW37cS56/3yPsU1bD/cp" + "3C1pPJpoun04va91Sxtgcmx7jnz69QPVrucu6aI1sZyeOlvzb8K7DceaAfR98CAwEAAaNj" + "MGEwDwYDVR0TAQH/BAUwAwEB/zAOBgNVHQ8BAf8EBAMCAQYwFgYDVR0gBA8wDTALBglghk" + "gBZQMBMAEwEQYDVR0OBAoECMNzJ3SpyOLxMBMGA1UdIwQMMAqACKua6/nC51SPMA0GCSqG" + "SIb3DQEBBQUAA4GBABo7oKmQilgji3w1tGz1cMrWxZxqGJqOAKcHywli+oxFo2oxSfEuFS" + "tN2aEd2Ja5HU5a0ySztvByXF1TTNurGez7ARxmcS2kpoQtQXTloywza4A5N7iQwk0yyo/E" + "J4lrXUfVRwZHr7FwA7qMODtFb0+Zivv9JLaq19GhnRhzZyWp"; public static final String Intermediate_Certificate_2_RL_03_01_crt = "MIICljCCAf+gAwIBAgICAK8wDQYJKoZIhvcNAQEFBQAwXjELMAkGA1UEBhMCVVMxGDAWBg" + "NVBAoTD1UuUy4gR292ZXJubWVudDEMMAoGA1UECxMDRG9EMRAwDgYDVQQLEwdUZXN0aW5n" + "MRUwEwYDVQQDEwxUcnVzdCBBbmNob3IwHhcNOTgwMTAxMTIwMTAwWhcNNDgwMTAxMTIwMT" + "AwWjBeMQswCQYDVQQGEwJVUzEYMBYGA1UEChMPVS5TLiBHb3Zlcm5tZW50MQwwCgYDVQQL" + "EwNEb2QxEDAOBgNVBAsTB1Rlc3RpbmcxFTATBgNVBAMTDENBMi1STC4wMy4wMTCBnzANBg" + "kqhkiG9w0BAQEFAAOBjQAwgYkCgYEAt7yNq1QZsV3p7OR8rgPuY7x7Bvs+nPhcLR7zFOgR" + "+plQUwpWQ2PhuzReVV4jNasKtNK9MIWoeV+eV3pEiso5obb9+Byvha1F6gkYNZMPs9Iv86" + "cJSMtownNJVGVAL9FEpof1QKLp7kfn08EjkoGmGy85xy9uFytd2S8n5TlrBqcCAwEAAaNj" + "MGEwDwYDVR0TAQH/BAUwAwEB/zAOBgNVHQ8BAf8EBAMCAQYwFgYDVR0gBA8wDTALBglghk" + "gBZQMBMAEwEQYDVR0OBAoECAVwoCPFqMtqMBMGA1UdIwQMMAqACKua6/nC51SPMA0GCSqG" + "SIb3DQEBBQUAA4GBAL9GufFieduzBJaMtsXtKHMf64O/KAGLSh1YDXS+a7Ku+EFw+WteKU" + "Ob6+c1m7VH9P711eATQoACotCdKusPECqeYDEmT9keqA4f7cP4VcvGwhvSVQJsPuB3LL3S" + "LIILE4zhT+O9G+5v+mkG/pEDirRYk6ZkdM91bsUuzsX40uyn"; public static final String Intermediate_CRL_RL_03_01_crl = "MIIBSzCBtQIBATANBgkqhkiG9w0BAQUFADBeMQswCQYDVQQGEwJVUzEYMBYGA1UEChMPVS" + "5TLiBHb3Zlcm5tZW50MQwwCgYDVQQLEwNEb2QxEDAOBgNVBAsTB1Rlc3RpbmcxFTATBgNV" + "BAMTDENBMi1STC4wMy4wMRcNOTkwMTAxMTIwMTAwWhcNNDgwMTAxMTIwMTAwWqAjMCEwCg" + "YDVR0UBAMCAQEwEwYDVR0jBAwwCoAIBXCgI8Woy2owDQYJKoZIhvcNAQEFBQADgYEAkwyA" + "I1rrz6tOmEpBHDzuJfqY2nbXCIXFN6dVuaKNZWHJ4ZNIc4/t29Wa5GgXYrVXyXRcXP/u5k" + "NEhOX2/NwCm6vL8+tclYP5qPLrh/Dk4v3nvcTFLKCvclAbf4Il0zfMQx+RRnO5PPqPDu5i" + "1tHHwOtA8Q+oO71lZEwPE+pX1Sc="; public static final String End_Certificate_RL_03_01_crt = "MIIChzCCAfCgAwIBAgICALAwDQYJKoZIhvcNAQEFBQAwXjELMAkGA1UEBhMCVVMxGDAWBg" + "NVBAoTD1UuUy4gR292ZXJubWVudDEMMAoGA1UECxMDRG9kMRAwDgYDVQQLEwdUZXN0aW5n" + "MRUwEwYDVQQDEwxDQTEtUkwuMDMuMDEwHhcNOTgwMTAxMTIwMTAwWhcNNDgwMTAxMTIwMT" + "AwWjBgMQswCQYDVQQGEwJVUzEYMBYGA1UEChMPVS5TLiBHb3Zlcm5tZW50MQwwCgYDVQQL" + "EwNEb0QxEDAOBgNVBAsTB1Rlc3RpbmcxFzAVBgNVBAMTDlVzZXIxLVJMLjAzLjAxMIGfMA" + "0GCSqGSIb3DQEBAQUAA4GNADCBiQKBgQDPGLfi8/T5p63cbGE98mqO5VzkeI1r2/2TLgvY" + "RpL1h8i+CVYKoX37yYwNXf+HkHhj1OXJSNrm7853ctmDf2h1fv3f1+qJLg4VRVzlEgErNq" + "74OR7XLXV77kGOmhip2g5BF5VKeqAdj0pCo1E5ZFHpRPFq/0DDmSda6GKJ6Dl8hwIDAQAB" + "o1IwUDAOBgNVHQ8BAf8EBAMCBeAwFgYDVR0gBA8wDTALBglghkgBZQMBMAEwEQYDVR0OBA" + "oECOHM3uWxFmcrMBMGA1UdIwQMMAqACMNzJ3SpyOLxMA0GCSqGSIb3DQEBBQUAA4GBAFBu" + "doX0TZK/yoUcrSkP8AtFiv5c7QvyEtigFZTT+lbW/g4RX/oJGNZCu78yAxCczl+Z6ft+0V" + "wInwahjyyAgw4QXxtw3b9CfqvT7HH7hcQ6r9ZA/NA9XpzNtxKfmXjzCZWdfmLJrd8KCnU/" + "utKRAObRBKiaTGa178SEWvtkoIXd"; public static final String[] TEST_65_DATA = new String[] { Intermediate_Certificate_1_RL_03_01_crt, Intermediate_Certificate_2_RL_03_01_crt, Intermediate_CRL_RL_03_01_crl, End_Certificate_RL_03_01_crt }; /* * test66 * */ public static final String Intermediate_Certificate_RL_03_02_crt = "MIICljCCAf+gAwIBAgICALEwDQYJKoZIhvcNAQEFBQAwXjELMAkGA1UEBhMCVVMxGDAWBg" + "NVBAoTD1UuUy4gR292ZXJubWVudDEMMAoGA1UECxMDRG9EMRAwDgYDVQQLEwdUZXN0aW5n" + "MRUwEwYDVQQDEwxUcnVzdCBBbmNob3IwHhcNOTgwMTAxMTIwMTAwWhcNNDgwMTAxMTIwMT" + "AwWjBeMQswCQYDVQQGEwJVUzEYMBYGA1UEChMPVS5TLiBHb3Zlcm5tZW50MQwwCgYDVQQL" + "EwNEb2QxEDAOBgNVBAsTB1Rlc3RpbmcxFTATBgNVBAMTDENBMS1STC4wMy4wMjCBnzANBg" + "kqhkiG9w0BAQEFAAOBjQAwgYkCgYEAvoTuc2LYBOhziBe02f6F8l9MwX74O1lknBcJjGvq" + "JcirQx/6hQgBQT4hz4RRXNy7DSBr3swEw4eDNSeyd6kvG0h9oI3+SVmVyPPVi5eKDL1roI" + "OBzmfx1+Nn/CnwOf8VroKDutBBQ0gJ24IEjwp6er/8hEAVN/yIjIi/MTFeoRkCAwEAAaNj" + "MGEwDwYDVR0TAQH/BAUwAwEB/zAOBgNVHQ8BAf8EBAMCAQYwFgYDVR0gBA8wDTALBglghk" + "gBZQMBMAEwEQYDVR0OBAoECKtCUOlmMPu6MBMGA1UdIwQMMAqACKua6/nC51SPMA0GCSqG" + "SIb3DQEBBQUAA4GBAI9x8O/JgJuZV/s4OBUy3AvcW9QP3HWWBQSdxUdjSosT2schjn7wrR" + "gttL7vWjT1djsbATAHa5C3inG+VjGIq/NqWaPoHAucRNMs4oZX2ACZFuBLOb/qhywsKh5+" + "bjv4QgtqkUedzEratY6yQiJSiMSJVJSMzHosTVMX7oOp+cll"; public static final String Intermediate_CRL_RL_03_02_crl = "MIIBcDCB2gIBATANBgkqhkiG9w0BAQUFADBeMQswCQYDVQQGEwJVUzEYMBYGA1UEChMPVS" + "5TLiBHb3Zlcm5tZW50MQwwCgYDVQQLEwNEb2QxEDAOBgNVBAsTB1Rlc3RpbmcxFTATBgNV" + "BAMTDENBMS1STC4wMi4wMRcNOTkwMTAxMTIwMTAwWhcNNDgwMTAxMTIwMTAwWjAjMCECAg" + "CyFw05OTAxMDExMjAwMDBaMAwwCgYDVR0VBAMKAQGgIzAhMAoGA1UdFAQDAgEBMBMGA1Ud" + "IwQMMAqACKtCUOlmMPu6MA0GCSqGSIb3DQEBBQUAA4GBAAEZ0Hg6sKiVXIeK6zbQrKtMMz" + "Vz2K68+SqN1LAjlNW6u+HSTlAvhRIFO1Hv5Zj7qbO226rLxas/X2XWXpMlm84NHN8T4dZU" + "4Yo5rhhpCHckRxNYn3AFcfcV4ra1rrTtdx8e7e7/m0Ghog9Ny52ZuQThasL9caF0JxUx6d" + "zbBHPm"; public static final String End_Certificate_RL_03_02_crt = "MIIChzCCAfCgAwIBAgICALIwDQYJKoZIhvcNAQEFBQAwXjELMAkGA1UEBhMCVVMxGDAWBg" + "NVBAoTD1UuUy4gR292ZXJubWVudDEMMAoGA1UECxMDRG9kMRAwDgYDVQQLEwdUZXN0aW5n" + "MRUwEwYDVQQDEwxDQTEtUkwuMDMuMDIwHhcNOTgwMTAxMTIwMTAwWhcNNDgwMTAxMTIwMT" + "AwWjBgMQswCQYDVQQGEwJVUzEYMBYGA1UEChMPVS5TLiBHb3Zlcm5tZW50MQwwCgYDVQQL" + "EwNEb0QxEDAOBgNVBAsTB1Rlc3RpbmcxFzAVBgNVBAMTDlVzZXIxLVJMLjAzLjAyMIGfMA" + "0GCSqGSIb3DQEBAQUAA4GNADCBiQKBgQDNb6HGPRDulLMCCyCq6w2X8rHPtm1gN68JXFkX" + "j/BZsHhu29Z9hXj76hO//7O775EPVMSLyRy8t15yzYpXfZRHFaGB5bs8U2R5ClvsD2FR0H" + "t0JVfU6Ggn1lhO+jOiguJtXVRjofsfvHuiOe75ctaJ9lBpgwiV8tk4VRKz2e5xVwIDAQAB" + "o1IwUDAOBgNVHQ8BAf8EBAMCBeAwFgYDVR0gBA8wDTALBglghkgBZQMBMAEwEQYDVR0OBA" + "oECI3Gy0TgXMrwMBMGA1UdIwQMMAqACKtCUOlmMPu6MA0GCSqGSIb3DQEBBQUAA4GBAISQ" + "Qh9+7D6nk3FL5YQOzyZ0BSHQYjpbIVykJ+Lr4jBPKyGgCqW6jqWNg7X4waB77J2z/OkavY" + "A6qtpsk8r2wmG9thi8JyZZNhYMxAszHzFbBmSoxGRMvI0XarxgIu8Ky6V7jKVDLz12C3o9" + "H0yd+nZXilCD+p9BTjjg5bGUogJS"; public static final String[] TEST_66_DATA = new String[] { Intermediate_Certificate_RL_03_02_crt, Intermediate_CRL_RL_03_02_crl, End_Certificate_RL_03_02_crt }; /* * test67 * */ public static final String Intermediate_Certificate_RL_03_03_crt = "MIICljCCAf+gAwIBAgICALMwDQYJKoZIhvcNAQEFBQAwXjELMAkGA1UEBhMCVVMxGDAWBg" + "NVBAoTD1UuUy4gR292ZXJubWVudDEMMAoGA1UECxMDRG9EMRAwDgYDVQQLEwdUZXN0aW5n" + "MRUwEwYDVQQDEwxUcnVzdCBBbmNob3IwHhcNOTgwMTAxMTIwMTAwWhcNNDgwMTAxMTIwMT" + "AwWjBeMQswCQYDVQQGEwJVUzEYMBYGA1UEChMPVS5TLiBHb3Zlcm5tZW50MQwwCgYDVQQL" + "EwNEb2QxEDAOBgNVBAsTB1Rlc3RpbmcxFTATBgNVBAMTDENBMS1STC4wMy4wMzCBnzANBg" + "kqhkiG9w0BAQEFAAOBjQAwgYkCgYEAu/o0uxgTrAvNDrMNuG2eTla+AmkLVCIXBbsIo0gs" + "tLm29tLwfBh/8l5OC0y6Xeh5lx+NLdelsiZGRNaaWmWHj9Ji5V6rclr8sXRDUjxe12zLeh" + "0G+a0TfpL380cx9RItqQyA1ZRiUNymmJHnm13hwrf7LPirR9BMrtyTT2EI3cMCAwEAAaNj" + "MGEwDwYDVR0TAQH/BAUwAwEB/zAOBgNVHQ8BAf8EBAMCAQYwFgYDVR0gBA8wDTALBglghk" + "gBZQMBMAEwEQYDVR0OBAoECHYt39LYdEn0MBMGA1UdIwQMMAqACKua6/nC51SPMA0GCSqG" + "SIb3DQEBBQUAA4GBAIoSGa7MxnOuHoWM/BoJKsCeBmBHYCYDKmQ19JfsDHW8z8oAFiikFb" + "Gtw1Qpc0GFfJgN0cppaXfe5lDS6BWL2dPorhu3URfXKu84ATLwGmNhqLDY7zh/zPvLtG2m" + "izaMLC6ZwZL5KELpYpcP15EHPDquyP1xpV3fT17GjpG9IH8k"; public static final String Intermediate_CRL_1_RL_03_03_crl = "MIIBcDCB2gIBATANBgkqhkiG9w0BAQUFADBeMQswCQYDVQQGEwJVUzEYMBYGA1UEChMPVS" + "5TLiBHb3Zlcm5tZW50MQwwCgYDVQQLEwNEb2QxEDAOBgNVBAsTB1Rlc3RpbmcxFTATBgNV" + "BAMTDENBMS1STC4wMi4wMRcNOTkwMTAxMTIwMTAwWhcNNDgwMTAxMTIwMTAwWjAjMCECAg" + "C0Fw05OTAxMDExMjAwMDBaMAwwCgYDVR0VBAMKAQGgIzAhMAoGA1UdFAQDAgEBMBMGA1Ud" + "IwQMMAqACHYt39LYdEn0MA0GCSqGSIb3DQEBBQUAA4GBAI3HsXanos/N6uO3QVUaBZzmCt" + "w1HCHMrLVG614YlUQiEedQ/oEc7dwCeD1rUbGNVkFPIRvMkmUQo1klhKAlEUmrtW+aH+If" + "6oqumifqxvaycWidacbgNLIAMQtlQmniPF6Pq0dv8sNeKq4CE0gjRHOPJ2zIqy3kJ3tZYB" + "pTguwO"; public static final String Intermediate_CRL_2_RL_03_03_crl = "MIIBSzCBtQIBATANBgkqhkiG9w0BAQUFADBeMQswCQYDVQQGEwJVUzEYMBYGA1UEChMPVS" + "5TLiBHb3Zlcm5tZW50MQwwCgYDVQQLEwNEb2QxEDAOBgNVBAsTB1Rlc3RpbmcxFTATBgNV" + "BAMTDENBMS1STC4wMy4wMxcNOTkwMTAxMTIwMTAwWhcNNDgwMTAxMTIwMTAwWqAjMCEwCg" + "YDVR0UBAMCAQEwEwYDVR0jBAwwCoAIdi3f0th0SfQwDQYJKoZIhvcNAQEFBQADgYEAXZSZ" + "ySsD7U6ETy9ZRmiKUCJMUV9CIhCY0mEihHjW0DhFTyV1Hr01yN5zUr/IFVuP/Xcx36IX4l" + "dVv6/MgR1GeM/BUGZhm4z6YwfAosZ1N3zayIy/pP3fa1rVRl8cgCxc/8qxg9nH9p6yPpxM" + "AOOu6TLYquk/dA7wJPEW7MPixXY="; public static final String End_Certificate_RL_03_03_crt = "MIIChzCCAfCgAwIBAgICALQwDQYJKoZIhvcNAQEFBQAwXjELMAkGA1UEBhMCVVMxGDAWBg" + "NVBAoTD1UuUy4gR292ZXJubWVudDEMMAoGA1UECxMDRG9kMRAwDgYDVQQLEwdUZXN0aW5n" + "MRUwEwYDVQQDEwxDQTEtUkwuMDMuMDMwHhcNOTgwMTAxMTIwMTAwWhcNNDgwMTAxMTIwMT" + "AwWjBgMQswCQYDVQQGEwJVUzEYMBYGA1UEChMPVS5TLiBHb3Zlcm5tZW50MQwwCgYDVQQL" + "EwNEb0QxEDAOBgNVBAsTB1Rlc3RpbmcxFzAVBgNVBAMTDlVzZXIxLVJMLjAzLjAzMIGfMA" + "0GCSqGSIb3DQEBAQUAA4GNADCBiQKBgQC5LNxAB+lm514Hk2ykrFUb7fCX0ryIEMg0mgeT" + "/z8Iw7xisht57koK4PTXY863aunfNNh+8oFTHZnoLB5dbkROj1nFRgcWPezzv1wNkZEpxn" + "NINtTPBogW22NPznoZ/rSk9JRFe0sCOVazkW9tZbY2ARqyJsYU1ez5tQIkDS47kQIDAQAB" + "o1IwUDAOBgNVHQ8BAf8EBAMCBeAwFgYDVR0gBA8wDTALBglghkgBZQMBMAEwEQYDVR0OBA" + "oECMWddsi+qmxKMBMGA1UdIwQMMAqACHYt39LYdEn0MA0GCSqGSIb3DQEBBQUAA4GBAAv8" + "nrJaqEycAyIKdPBYTUqaxjkv4SmonDDJG9OqvD78/o9hUKKteoMkNUp8eexTkWk0L72L4N" + "/eXB30+m65E841V+Dy8L4bXh15n4qz4cyMt8Kvm7nbCqcgpiyBJmBxzfaXDLSthlmhcJ4X" + "zDFnav1LEw5fZklt7cnMl4YvLD8d"; public static final String[] TEST_67_DATA = new String[] { Intermediate_Certificate_RL_03_03_crt, Intermediate_CRL_1_RL_03_03_crl, Intermediate_CRL_2_RL_03_03_crl, End_Certificate_RL_03_03_crt }; /* * test68 * */ public static final String Intermediate_Certificate_1_RL_05_01_crt = "MIICljCCAf+gAwIBAgICALUwDQYJKoZIhvcNAQEFBQAwXjELMAkGA1UEBhMCVVMxGDAWBg" + "NVBAoTD1UuUy4gR292ZXJubWVudDEMMAoGA1UECxMDRG9EMRAwDgYDVQQLEwdUZXN0aW5n" + "MRUwEwYDVQQDEwxUcnVzdCBBbmNob3IwHhcNOTgwMTAxMTIwMTAwWhcNNDgwMTAxMTIwMT" + "AwWjBeMQswCQYDVQQGEwJVUzEYMBYGA1UEChMPVS5TLiBHb3Zlcm5tZW50MQwwCgYDVQQL" + "EwNEb2QxEDAOBgNVBAsTB1Rlc3RpbmcxFTATBgNVBAMTDENBMS1STC4wNS4wMTCBnzANBg" + "kqhkiG9w0BAQEFAAOBjQAwgYkCgYEA59vHTe5A9AcT237mW7HdSfh8Pu4P2wJNLT7RXczN" + "7DD/P6mAkugSgPTXwwlE1oSB/hCxAtEPhwONYZFYlRClFJidHDdVApalB7UbosTghsUzAg" + "Lqw7NL+w9i3Un2G7JM2oWwugozQn/1hzr2Cii2TIB6K0RWKoPBJvaWUURS/G8CAwEAAaNj" + "MGEwDwYDVR0TAQH/BAUwAwEB/zAOBgNVHQ8BAf8EBAMCAQYwFgYDVR0gBA8wDTALBglghk" + "gBZQMBMAEwEQYDVR0OBAoECP55Cc4eBca8MBMGA1UdIwQMMAqACKua6/nC51SPMA0GCSqG" + "SIb3DQEBBQUAA4GBALX594y5uF4Rt7CoRHeKZ5h8QiG7mc+kQDMjaSU4KJwNVVL0mJatQG" + "w90yFfhvprlgDt9UIAvpF6z5gysbrjHXJaEhVlXeg9D5mcxsL4THEc8f6oU1GjfT/SOD9l" + "QrT/keX3D9lcFEaTOgi0HIZ7aFIJgoWjXF/9kNNMEAs8sJNI"; public static final String Intermediate_Certificate_2_RL_05_01_crt = "MIICljCCAf+gAwIBAgICALYwDQYJKoZIhvcNAQEFBQAwXjELMAkGA1UEBhMCVVMxGDAWBg" + "NVBAoTD1UuUy4gR292ZXJubWVudDEMMAoGA1UECxMDRG9kMRAwDgYDVQQLEwdUZXN0aW5n" + "MRUwEwYDVQQDEwxDQTEtUkwuMDUuMDEwHhcNOTgwMTAxMTIwMTAwWhcNNDgwMTAxMTIwMT" + "AwWjBeMQswCQYDVQQGEwJVUzEYMBYGA1UEChMPVS5TLiBHb3Zlcm5tZW50MQwwCgYDVQQL" + "EwNEb2QxEDAOBgNVBAsTB1Rlc3RpbmcxFTATBgNVBAMTDENBMi1STC4wNS4wMTCBnzANBg" + "kqhkiG9w0BAQEFAAOBjQAwgYkCgYEAtl4hX6HlF0M+lSBTG8jHiB06hOy87LL81yAE2JQt" + "/6F+LZjuOBTCIc2yO2bVM3XzUnjyYDBYGnBFp/7XpRoiADuPJSfmkzmezpyJc+hm96UR1g" + "Bpo+pPKbRTWuM+FYy+vPtaDk5wKOrmyNx440PwbzxTN3JeWz17xeYE98bXMc0CAwEAAaNj" + "MGEwDwYDVR0TAQH/BAUwAwEB/zAOBgNVHQ8BAf8EBAMCAQYwFgYDVR0gBA8wDTALBglghk" + "gBZQMBMAEwEQYDVR0OBAoECJOjtwEYV9VSMBMGA1UdIwQMMAqACP55Cc4eBca8MA0GCSqG" + "SIb3DQEBBQUAA4GBAFbkOffoIjWSfxEuKszoK7Fj27Hf5jlV92xqXtBLURjNGi9jCLUIUd" + "QLnONZLJYo70Z6XaGjpAK1EtZKVWsz11JDq5egE1zNES//9Tz8xDtJ7Lcq0mwneVFxmBuL" + "gxkw4GKbBFKz10FoSP7VJWaeW080WwKnp96Me5GtZRe260N1"; public static final String Intermediate_CRL_1_RL_05_01_crl = "MIIBhTCB7wIBATANBgkqhkiG9w0BAQUFADBeMQswCQYDVQQGEwJVUzEYMBYGA1UEChMPVS" + "5TLiBHb3Zlcm5tZW50MQwwCgYDVQQLEwNEb2QxEDAOBgNVBAsTB1Rlc3RpbmcxFTATBgNV" + "BAMTDENBMS1STC4wNS4wMRcNOTkwMTAxMTIwMTAwWhcNNDgwMTAxMTIwMTAwWjA4MDYCAg" + "C2Fw05OTAxMDExMjAwMDBaMCEwCgYDVR0VBAMKAQEwEwYJYIZIAWUCAQwCAQH/BAMCAQCg" + "IzAhMAoGA1UdFAQDAgEBMBMGA1UdIwQMMAqACP55Cc4eBca8MA0GCSqGSIb3DQEBBQUAA4" + "GBAIdOaBfpAEKWLrSvepVjk3UTfEfsSP6y+kFMl33YXy18xUvVpLarGu6YjQIpXiL+ulkP" + "eF8TAc9AarUjvDf0kcslIOt3NhdMxR4/F614Ds/rPEXs4c7n4kCkvAlFg/19iIFeCaynx3" + "X0s/v1SwzgAUHi3P+OwAGDApDTyKbnmzvt"; public static final String Intermediate_CRL_2_RL_05_01_crl = "MIIBSzCBtQIBATANBgkqhkiG9w0BAQUFADBeMQswCQYDVQQGEwJVUzEYMBYGA1UEChMPVS" + "5TLiBHb3Zlcm5tZW50MQwwCgYDVQQLEwNEb2QxEDAOBgNVBAsTB1Rlc3RpbmcxFTATBgNV" + "BAMTDENBMi1STC4wNS4wMRcNOTkwMTAxMTIwMTAwWhcNNDgwMTAxMTIwMTAwWqAjMCEwCg" + "YDVR0UBAMCAQEwEwYDVR0jBAwwCoAIk6O3ARhX1VIwDQYJKoZIhvcNAQEFBQADgYEAfOOd" + "JiLUCFSurAafQEBfxE9KVrgFC+W9m64cmERicO1QL9aDVIDGJAIY1pdvWVdhLBIKwSugwB" + "ZH3ToptY+VizvFN1gkKGL2OuvDsXPHn1+QgmqvxYFPmvwDcwuxZ/3zD1VeHgEIKo9ugRnW" + "F8G2Ph6SWUxJCjJQpB7WIbydowI="; public static final String End_Certificate_RL_05_01_crt = "MIIChzCCAfCgAwIBAgICALcwDQYJKoZIhvcNAQEFBQAwXjELMAkGA1UEBhMCVVMxGDAWBg" + "NVBAoTD1UuUy4gR292ZXJubWVudDEMMAoGA1UECxMDRG9kMRAwDgYDVQQLEwdUZXN0aW5n" + "MRUwEwYDVQQDEwxDQTItUkwuMDUuMDEwHhcNOTgwMTAxMTIwMTAwWhcNNDgwMTAxMTIwMT" + "AwWjBgMQswCQYDVQQGEwJVUzEYMBYGA1UEChMPVS5TLiBHb3Zlcm5tZW50MQwwCgYDVQQL" + "EwNEb0QxEDAOBgNVBAsTB1Rlc3RpbmcxFzAVBgNVBAMTDlVzZXIxLVJMLjA1LjAxMIGfMA" + "0GCSqGSIb3DQEBAQUAA4GNADCBiQKBgQC9NWkW/mia20c5gM3DpcTsBWTNC/d/Cob+OVrS" + "lYytMjK4htO3MavavMZNTLAYFCXWhZ+Uo/uiAF0ddE4HaFI418eKJMSSbQyed0TG5Udw/t" + "3dhYeLzLEmVc0r00q5v+CLINsCNQAKaPV71UvoHrE092zZjmtacuAetBS1Q2ufpwIDAQAB" + "o1IwUDAOBgNVHQ8BAf8EBAMCBeAwFgYDVR0gBA8wDTALBglghkgBZQMBMAEwEQYDVR0OBA" + "oECGNPOXdCLpZ3MBMGA1UdIwQMMAqACJOjtwEYV9VSMA0GCSqGSIb3DQEBBQUAA4GBALTo" + "hfBEPdzZ6A9QNStakOhmhHYox70xOPuWqzSbIugZv4chKXNQGiUAoOGImTw1mcun/uPNtd" + "0bT+O+a9yX5gzW55CSmR/teHkTkND1mJhOMuYOmaCaBHnqgIIe1iEhMZQgag70+/tSmmQm" + "UpWGpxeK2c02tBK6gEmnqk75bKRT"; public static final String[] TEST_68_DATA = new String[] { Intermediate_Certificate_1_RL_05_01_crt, Intermediate_Certificate_2_RL_05_01_crt, Intermediate_CRL_1_RL_05_01_crl, Intermediate_CRL_2_RL_05_01_crl, End_Certificate_RL_05_01_crt }; /* * test69 * */ public static final String Intermediate_Certificate_RL_05_02_crt = "MIICljCCAf+gAwIBAgICALgwDQYJKoZIhvcNAQEFBQAwXjELMAkGA1UEBhMCVVMxGDAWBg" + "NVBAoTD1UuUy4gR292ZXJubWVudDEMMAoGA1UECxMDRG9EMRAwDgYDVQQLEwdUZXN0aW5n" + "MRUwEwYDVQQDEwxUcnVzdCBBbmNob3IwHhcNOTgwMTAxMTIwMTAwWhcNNDgwMTAxMTIwMT" + "AwWjBeMQswCQYDVQQGEwJVUzEYMBYGA1UEChMPVS5TLiBHb3Zlcm5tZW50MQwwCgYDVQQL" + "EwNEb2QxEDAOBgNVBAsTB1Rlc3RpbmcxFTATBgNVBAMTDENBMS1STC4wNS4wMjCBnzANBg" + "kqhkiG9w0BAQEFAAOBjQAwgYkCgYEAouNcO1wHvKHPR15L7Fohr/QbTkPWGr9QYp2MXEDy" + "BRGHt63Ob+yNvsP/C74GJA+PzvcRELSnJxmBVbdRN5y/u4S6Zt4yTTcrvp4vl//luoGLOX" + "NHhCXbrGavyoP/iKpbfP7fy948AN34i95HuZENoGPjG5stX0uk12P087S2tPcCAwEAAaNj" + "MGEwDwYDVR0TAQH/BAUwAwEB/zAOBgNVHQ8BAf8EBAMCAQYwFgYDVR0gBA8wDTALBglghk" + "gBZQMBMAEwEQYDVR0OBAoECFi86MGPmMsXMBMGA1UdIwQMMAqACKua6/nC51SPMA0GCSqG" + "SIb3DQEBBQUAA4GBAFVZVMZEsaVuL0qX5Ls94+x8gBklxPfxgfG5LeBR2/YcqW+7BhsVA1" + "GQhjBtwqCU9SOL16oTrqgw2+YeWBjaYuNYVlxfdifd0pQydpE1iDQWxmoKLzSDmtWgRYhz" + "v0TB6j8q+0x5Q0OOrHX0jdIiBnHrLmReCK8dY1x6fb6I0tTH"; public static final String Intermediate_CRL_RL_05_02_crl = "MIIBhTCB7wIBATANBgkqhkiG9w0BAQUFADBeMQswCQYDVQQGEwJVUzEYMBYGA1UEChMPVS" + "5TLiBHb3Zlcm5tZW50MQwwCgYDVQQLEwNEb2QxEDAOBgNVBAsTB1Rlc3RpbmcxFTATBgNV" + "BAMTDENBMS1STC4wNS4wMhcNOTkwMTAxMTIwMTAwWhcNNDgwMTAxMTIwMTAwWjA4MDYCAg" + "C5Fw05OTAxMDExMjAwMDBaMCEwCgYDVR0VBAMKAQEwEwYJYIZIAWUCAQwCAQH/BAMCAQCg" + "IzAhMAoGA1UdFAQDAgEBMBMGA1UdIwQMMAqACFi86MGPmMsXMA0GCSqGSIb3DQEBBQUAA4" + "GBAFMN6PWjz2bA1RRySYNXde2rKiYkZYghbtT4ig2yDJBKOiPnjdx+jriFJxGYpt7BvcNx" + "cDfijmDZ1clzprIvz0lFO6IwsQiWtLxOz4Doj6K2AD+7IxuGLceaXmubvi4e6VVC3xXGsu" + "OYsNgFzsdUXIazi74+eOcj4dqrHAepbhXT"; public static final String End_Certificate_RL_05_02_crt = "MIIChzCCAfCgAwIBAgICALkwDQYJKoZIhvcNAQEFBQAwXjELMAkGA1UEBhMCVVMxGDAWBg" + "NVBAoTD1UuUy4gR292ZXJubWVudDEMMAoGA1UECxMDRG9kMRAwDgYDVQQLEwdUZXN0aW5n" + "MRUwEwYDVQQDEwxDQTEtUkwuMDUuMDIwHhcNOTgwMTAxMTIwMTAwWhcNNDgwMTAxMTIwMT" + "AwWjBgMQswCQYDVQQGEwJVUzEYMBYGA1UEChMPVS5TLiBHb3Zlcm5tZW50MQwwCgYDVQQL" + "EwNEb0QxEDAOBgNVBAsTB1Rlc3RpbmcxFzAVBgNVBAMTDlVzZXIxLVJMLjA1LjAyMIGfMA" + "0GCSqGSIb3DQEBAQUAA4GNADCBiQKBgQCuWE1aFx3Zjk6gM0Wy6ijcUegbiGvhjBgqIGwv" + "YissT0v3KGAKoh5wGeKC+rePQNbZ91j4XDLvUNUdNw8HVNdNG/igIwsuaJ9teKSbqrAw9X" + "aD2YjJz/I6X6WXFd/eQ+g9lY3eidOXJkglYSwWMxUV62RUZbGyqjR1so+XpmYxCQIDAQAB" + "o1IwUDAOBgNVHQ8BAf8EBAMCBeAwFgYDVR0gBA8wDTALBglghkgBZQMBMAEwEQYDVR0OBA" + "oECLLbuNyVkkK9MBMGA1UdIwQMMAqACFi86MGPmMsXMA0GCSqGSIb3DQEBBQUAA4GBACKt" + "GgxIRXYHZGZgwYHjNzquM1pUJTbxxm3qYA4U6r44oAo1UzQTDpHOalflreGFvG05l1BCnQ" + "olQ8rcXU25v/CDfyww7cl8l7IxjYz7PNht7R97vjfMVqqButbn+BmU6D5kR9YXDCDPzaQ5" + "DrKNk+3tIjJNj6YhxhqC2tPG9RIN"; public static final String[] TEST_69_DATA = new String[] { Intermediate_Certificate_RL_05_02_crt, Intermediate_CRL_RL_05_02_crl, End_Certificate_RL_05_02_crt }; /* * test70 * */ public static final String Intermediate_Certificate_1_RL_06_01_crt = "MIICljCCAf+gAwIBAgICALowDQYJKoZIhvcNAQEFBQAwXjELMAkGA1UEBhMCVVMxGDAWBg" + "NVBAoTD1UuUy4gR292ZXJubWVudDEMMAoGA1UECxMDRG9EMRAwDgYDVQQLEwdUZXN0aW5n" + "MRUwEwYDVQQDEwxUcnVzdCBBbmNob3IwHhcNOTgwMTAxMTIwMTAwWhcNNDgwMTAxMTIwMT" + "AwWjBeMQswCQYDVQQGEwJVUzEYMBYGA1UEChMPVS5TLiBHb3Zlcm5tZW50MQwwCgYDVQQL" + "EwNEb2QxEDAOBgNVBAsTB1Rlc3RpbmcxFTATBgNVBAMTDENBMS1STC4wNi4wMTCBnzANBg" + "kqhkiG9w0BAQEFAAOBjQAwgYkCgYEAmhxr4ckU5C3E57odZjgcxl46ZF2QVy+K86YoLOGT" + "mq34NSHTFxP93mrNqMYdFKFedUTNI68HkecFVvVKoXsDNBnhyyCTQ3xXhBcMUXFByB+55k" + "W5LeQ8l1G2ugsyZ7Z+P8uylrpeGJt4RjOTilhcI2mnfZ7S+arFGe4KYgnsaFUCAwEAAaNj" + "MGEwDwYDVR0TAQH/BAUwAwEB/zAOBgNVHQ8BAf8EBAMCAQYwFgYDVR0gBA8wDTALBglghk" + "gBZQMBMAEwEQYDVR0OBAoECOS4X3XqhyJYMBMGA1UdIwQMMAqACKua6/nC51SPMA0GCSqG" + "SIb3DQEBBQUAA4GBALCPtNwXGxVSUNGErkBHSYCHyqlA55jKQQvZ4P0PznWEQ/gBJx34hq" + "LxiBO2G+iDomzHszeM77TXkQBpNxCUw26Jxv2HuvyBXuSprgjw5F1tvLqwsBAnD5vsb0uD" + "NrkKIzJSIBFQ1SRhuCObaXnamfPJHBmkP25t4QqEvoXMtVHB"; public static final String Intermediate_Certificate_2_RL_06_01_crt = "MIICljCCAf+gAwIBAgICALswDQYJKoZIhvcNAQEFBQAwXjELMAkGA1UEBhMCVVMxGDAWBg" + "NVBAoTD1UuUy4gR292ZXJubWVudDEMMAoGA1UECxMDRG9kMRAwDgYDVQQLEwdUZXN0aW5n" + "MRUwEwYDVQQDEwxDQTEtUkwuMDYuMDEwHhcNOTgwMTAxMTIwMTAwWhcNNDgwMTAxMTIwMT" + "AwWjBeMQswCQYDVQQGEwJVUzEYMBYGA1UEChMPVS5TLiBHb3Zlcm5tZW50MQwwCgYDVQQL" + "EwNEb2QxEDAOBgNVBAsTB1Rlc3RpbmcxFTATBgNVBAMTDENBMi1STC4wNi4wMTCBnzANBg" + "kqhkiG9w0BAQEFAAOBjQAwgYkCgYEA2IKrW6HDZJVFw3e4cC7v/jPGXAexI4B88707NhAc" + "qxSVfGTPJBdfWo5pkptZKN5/L5n6+rixLItHnei/uwBCHvhwzeEIGo1yVCgz6R2MoNB966" + "Q5CHWfT43BUjp0rZLJkK4hVKNyXB78NVv2Fly+XWBDEnzQvgVPWbGOvzE3zh0CAwEAAaNj" + "MGEwDwYDVR0TAQH/BAUwAwEB/zAOBgNVHQ8BAf8EBAMCAQYwFgYDVR0gBA8wDTALBglghk" + "gBZQMBMAEwEQYDVR0OBAoECK/1z9Xbu2jGMBMGA1UdIwQMMAqACOS4X3XqhyJYMA0GCSqG" + "SIb3DQEBBQUAA4GBAAa/MVC+8ozm9py40a4o/kHbkkmFNQr4s9yi3KXXuVxsNvquFMXm4a" + "gC8GPoNjvV+RPRmU8wOM6I2/PPl2JEQRb7NDM8LkY/m/Au4GHVeln6FKlldiRm0A+YIr19" + "ip2RHOldikAjUUYv7JT3SP34sjtq2e8bsXfWEPG5BA/wxtm7"; public static final String Intermediate_CRL_1_RL_06_01_crl = "MIIBhTCB7wIBATANBgkqhkiG9w0BAQUFADBeMQswCQYDVQQGEwJVUzEYMBYGA1UEChMPVS" + "5TLiBHb3Zlcm5tZW50MQwwCgYDVQQLEwNEb2QxEDAOBgNVBAsTB1Rlc3RpbmcxFTATBgNV" + "BAMTDENBMS1STC4wNi4wMRcNOTkwMTAxMTIwMTAwWhcNNDgwMTAxMTIwMTAwWjAjMCECAg" + "C7Fw05OTAxMDExMjAwMDBaMAwwCgYDVR0VBAMKAQGgODA2MAoGA1UdFAQDAgEBMBMGCWCG" + "SAFlAgEMAgEB/wQDAgEAMBMGA1UdIwQMMAqACOS4X3XqhyJYMA0GCSqGSIb3DQEBBQUAA4" + "GBAJSexboWDaqLVY6iiWt8ZX5GwuNwDBN1R2TgM95H7JqjMgoWML887dKk24p4eKACFMWI" + "Ji9nwsqdZ/h1FtPhYpSoJ8l8vo4imMKr+tTnMngDNpMMZPQyRY1AK1jSrLhEtUdjiEtrTY" + "rG56RNt4YyUtNxxfkEymvwJxmO/4YcAz/l"; public static final String Intermediate_CRL_2_RL_06_01_crl = "MIIBSzCBtQIBATANBgkqhkiG9w0BAQUFADBeMQswCQYDVQQGEwJVUzEYMBYGA1UEChMPVS" + "5TLiBHb3Zlcm5tZW50MQwwCgYDVQQLEwNEb2QxEDAOBgNVBAsTB1Rlc3RpbmcxFTATBgNV" + "BAMTDENBMi1STC4wNi4wMRcNOTkwMTAxMTIwMTAwWhcNNDgwMTAxMTIwMTAwWqAjMCEwCg" + "YDVR0UBAMCAQEwEwYDVR0jBAwwCoAIr/XP1du7aMYwDQYJKoZIhvcNAQEFBQADgYEAImRg" + "n9A7px9exOJL4Se9jsSHzZ3sAd3y16LdAb+HLtYLl1swNB4KPE+OebtzEoYiSzVVwezdlm" + "5WseZjfbd0q01srZI4FeACZe99iBSpKymdKxw2gRvfYZ8ZMwFpK2mQq9cmygFn53iOwP7j" + "3KE+lllielu7sYyEnkliF9wsaG0="; public static final String End_Certificate_RL_06_01_crt = "MIIChzCCAfCgAwIBAgICALwwDQYJKoZIhvcNAQEFBQAwXjELMAkGA1UEBhMCVVMxGDAWBg" + "NVBAoTD1UuUy4gR292ZXJubWVudDEMMAoGA1UECxMDRG9kMRAwDgYDVQQLEwdUZXN0aW5n" + "MRUwEwYDVQQDEwxDQTItUkwuMDYuMDEwHhcNOTgwMTAxMTIwMTAwWhcNNDgwMTAxMTIwMT" + "AwWjBgMQswCQYDVQQGEwJVUzEYMBYGA1UEChMPVS5TLiBHb3Zlcm5tZW50MQwwCgYDVQQL" + "EwNEb0QxEDAOBgNVBAsTB1Rlc3RpbmcxFzAVBgNVBAMTDlVzZXIxLVJMLjA2LjAxMIGfMA" + "0GCSqGSIb3DQEBAQUAA4GNADCBiQKBgQDZVBNzD7LZW6mC2GSbVPjpcJ7sWISYsL2eHqXb" + "/PuxtbOneOjYqx0GeL9pxDGSSNl2NrlG0G1HTU2MaEOVA6h96W9e5ADV/pzGPMr97z+3BV" + "unxLX+ciM3T7rUQm/LueQTEC2Ww19T6QOg2i8rEadYT0OoW6OcvyuomemspxgClQIDAQAB" + "o1IwUDAOBgNVHQ8BAf8EBAMCBeAwFgYDVR0gBA8wDTALBglghkgBZQMBMAEwEQYDVR0OBA" + "oECK5pHDrhL7xjMBMGA1UdIwQMMAqACK/1z9Xbu2jGMA0GCSqGSIb3DQEBBQUAA4GBAF3J" + "Kskjs4jp+BBoei9YWYtmOupn9w3oGyhknNh2jz7api5Gtgk2SyKfYFvN6EhWZJEab0hPFe" + "WuYwO7zNCLGHw0cFXT/R48ogd6JkH6xDwj4afZDkWVTu8oaVD4h1rTYS6WPRzizAozOzhi" + "tmIo+MV/lCG8+jdVtFgeKycI8aX7"; public static final String[] TEST_70_DATA = new String[] { Intermediate_Certificate_1_RL_06_01_crt, Intermediate_Certificate_2_RL_06_01_crt, Intermediate_CRL_1_RL_06_01_crl, Intermediate_CRL_2_RL_06_01_crl, End_Certificate_RL_06_01_crt }; /* * test71 * */ public static final String Intermediate_Certificate_RL_06_02_crt = "MIICljCCAf+gAwIBAgICAL0wDQYJKoZIhvcNAQEFBQAwXjELMAkGA1UEBhMCVVMxGDAWBg" + "NVBAoTD1UuUy4gR292ZXJubWVudDEMMAoGA1UECxMDRG9EMRAwDgYDVQQLEwdUZXN0aW5n" + "MRUwEwYDVQQDEwxUcnVzdCBBbmNob3IwHhcNOTgwMTAxMTIwMTAwWhcNNDgwMTAxMTIwMT" + "AwWjBeMQswCQYDVQQGEwJVUzEYMBYGA1UEChMPVS5TLiBHb3Zlcm5tZW50MQwwCgYDVQQL" + "EwNEb2QxEDAOBgNVBAsTB1Rlc3RpbmcxFTATBgNVBAMTDENBMS1STC4wNi4wMjCBnzANBg" + "kqhkiG9w0BAQEFAAOBjQAwgYkCgYEAxMlJ0vbkMRGzuEDTDGuPmwDzU1xn3dFDZ1Tx6ONP" + "fwNN5gk6r9kYl5TZ8f5TbkQSnOzyhDSqX8dGumCSgukETXtYBU2+KiIAtliu5NJRbXe3La" + "vn102HxaHDLGsR0FFLiFM9GVhOOXryJoXoGZqUwvqbWyaQQEzrV4RWmuOv7xMCAwEAAaNj" + "MGEwDwYDVR0TAQH/BAUwAwEB/zAOBgNVHQ8BAf8EBAMCAQYwFgYDVR0gBA8wDTALBglghk" + "gBZQMBMAEwEQYDVR0OBAoECFNaMo88Vb5MMBMGA1UdIwQMMAqACKua6/nC51SPMA0GCSqG" + "SIb3DQEBBQUAA4GBAJsjJG4/U1OWCJPB1u7UD3TPKRgOR9hT5l3LzFw5s0CEGt2Beg25LP" + "GEGcr0sEdosVQI5m5CuPolpmlQv0FkZv5M1W+uXX+F/6edtMDEquDpdR97ihQSLZjFFqjE" + "ytuaD4gqtL/BKBbz3e93mOmR9Wi+kWlXOYl0j8wpU9ePSjDV"; public static final String Intermediate_CRL_RL_06_02_crl = "MIIBhTCB7wIBATANBgkqhkiG9w0BAQUFADBeMQswCQYDVQQGEwJVUzEYMBYGA1UEChMPVS" + "5TLiBHb3Zlcm5tZW50MQwwCgYDVQQLEwNEb2QxEDAOBgNVBAsTB1Rlc3RpbmcxFTATBgNV" + "BAMTDENBMS1STC4wNi4wMhcNOTkwMTAxMTIwMTAwWhcNNDgwMTAxMTIwMTAwWjAjMCECAg" + "C+Fw05OTAxMDExMjAwMDBaMAwwCgYDVR0VBAMKAQGgODA2MAoGA1UdFAQDAgEBMBMGCWCG" + "SAFlAgEMAgEB/wQDAgEAMBMGA1UdIwQMMAqACFNaMo88Vb5MMA0GCSqGSIb3DQEBBQUAA4" + "GBAAKNj5xmtE7wzO1p5igiAmCDV6KuYsiPAQPHPEBlmo85vzvWv2hpEtmk4nDhehogl0QX" + "rhvRRqR+cPE5vBLB8mAStW+ZR6FXQPnmU5qGHqCQ4Wh6TWZesd7oyftoS7bJD5Xdf5ErA9" + "qijWoz8FgxZHVnAFmjA0rUINkdQ5JfE5oj"; public static final String End_Certificate_RL_06_02_crt = "MIIChzCCAfCgAwIBAgICAL4wDQYJKoZIhvcNAQEFBQAwXjELMAkGA1UEBhMCVVMxGDAWBg" + "NVBAoTD1UuUy4gR292ZXJubWVudDEMMAoGA1UECxMDRG9kMRAwDgYDVQQLEwdUZXN0aW5n" + "MRUwEwYDVQQDEwxDQTEtUkwuMDYuMDIwHhcNOTgwMTAxMTIwMTAwWhcNNDgwMTAxMTIwMT" + "AwWjBgMQswCQYDVQQGEwJVUzEYMBYGA1UEChMPVS5TLiBHb3Zlcm5tZW50MQwwCgYDVQQL" + "EwNEb0QxEDAOBgNVBAsTB1Rlc3RpbmcxFzAVBgNVBAMTDlVzZXIxLVJMLjA2LjAyMIGfMA" + "0GCSqGSIb3DQEBAQUAA4GNADCBiQKBgQD3UzwrnwKRlP00Pn49iI35S0wLn7c1I3rsmzdm" + "YFicetxHNeOKXLg1CN1bqkbAJ+N39fKjrkusqb2T+R3zhAV5LeLT4fzbHYdU7f4r6xgW2/" + "b2WLv+QVR+ldTsVxgPp/ZUgYi4/vAow4Q/6IT+zWtlawMBob/nLjVl+jQ9N4coFwIDAQAB" + "o1IwUDAOBgNVHQ8BAf8EBAMCBeAwFgYDVR0gBA8wDTALBglghkgBZQMBMAEwEQYDVR0OBA" + "oECPhq75noL+9WMBMGA1UdIwQMMAqACFNaMo88Vb5MMA0GCSqGSIb3DQEBBQUAA4GBAIU2" + "5bLX/NyDC8dKUxRwVn8oc3YPQjK0zXGdUr15Ib+cLdRyFVCuAyxVdpTf/csuga6tDhGuTL" + "B18mTE/fAjhUOiKiOLD6m4P77Nj67l2NTi86RimsI/Z6r5+bU31ahrls/7kr788+f4oEIY" + "TyOJecojsJUOG3qzK9J50iszclxg"; public static final String[] TEST_71_DATA = new String[] { Intermediate_Certificate_RL_06_02_crt, Intermediate_CRL_RL_06_02_crl, End_Certificate_RL_06_02_crt }; /* * test72 * */ public static final String Intermediate_Certificate_RL_07_01_crt = "MIICljCCAf+gAwIBAgICAL8wDQYJKoZIhvcNAQEFBQAwXjELMAkGA1UEBhMCVVMxGDAWBg" + "NVBAoTD1UuUy4gR292ZXJubWVudDEMMAoGA1UECxMDRG9EMRAwDgYDVQQLEwdUZXN0aW5n" + "MRUwEwYDVQQDEwxUcnVzdCBBbmNob3IwHhcNOTgwMTAxMTIwMTAwWhcNNDgwMTAxMTIwMT" + "AwWjBeMQswCQYDVQQGEwJVUzEYMBYGA1UEChMPVS5TLiBHb3Zlcm5tZW50MQwwCgYDVQQL" + "EwNEb2QxEDAOBgNVBAsTB1Rlc3RpbmcxFTATBgNVBAMTDENBMS1STC4wNy4wMTCBnzANBg" + "kqhkiG9w0BAQEFAAOBjQAwgYkCgYEAxjHxSRwJjEkLG9Al5uSQ22QI8N/hJ8hhkhh9qlaJ" + "mHusM8sWpAp2vnuumlThTA2zZbptXZ8Krb7i/Kpym4wo3ZkEThwi/ijsM5QCunQJmESRGD" + "yPZJjfhWjoC+lCjbmzsOGLMETpgSEMy+EyoXkRCnKmXcmCMS8HjLrqdnwiWBUCAwEAAaNj" + "MGEwDwYDVR0TAQH/BAUwAwEB/zAOBgNVHQ8BAf8EBAMCAQYwFgYDVR0gBA8wDTALBglghk" + "gBZQMBMAEwEQYDVR0OBAoECHPEkeIs8GuwMBMGA1UdIwQMMAqACKua6/nC51SPMA0GCSqG" + "SIb3DQEBBQUAA4GBABCmgEnb8dfnG9lWQKT5BmQm459WqRQAiqdfqf9w0qRMuVrdfLMwqx" + "oq4uh10A3d+auHohgT2fT9RzNaWnRoNaH9K6qLQsdCUZdqjbEGdyiIFzvWP9MkV9nhDlo2" + "GgiU68HfnpKO/WA9EaRHyEzwT9o4SA7hAbz+3L12hB2WLSOg"; public static final String Intermediate_CRL_RL_07_01_crl = "MIIBSzCBtQIBATANBgkqhkiG9w0BAQUFADBeMQswCQYDVQQGEwJVUzEYMBYGA1UEChMPVS" + "5TLiBHb3Zlcm5tZW50MQwwCgYDVQQLEwNEb2QxEDAOBgNVBAsTB1Rlc3RpbmcxFTATBgNV" + "BAMTDENBMS1STC4wNy4wMRcNOTgwMTAxMDYwMTAwWhcNOTgwMTAxMTIwMTAwWqAjMCEwCg" + "YDVR0UBAMCAQEwEwYDVR0jBAwwCoAIc8SR4izwa7AwDQYJKoZIhvcNAQEFBQADgYEAOyZr" + "f1tRnuzoq7dgQo+eOYhb5JyRyrNaSwNnRy82wOP+/G3NH8V3NGonDFOOcd9SoLTbeW4o71" + "vdOrKZgom5H2MZK5M4wTdfPAfXB1wBxOMzW5jXzsRtaha4l6EPI+GVL0eXN+aW3k/pscdA" + "ToI+OxTmRRnCYS6yW3qL9RoTIXQ="; public static final String End_Certificate_RL_07_01_crt = "MIIChzCCAfCgAwIBAgICAMAwDQYJKoZIhvcNAQEFBQAwXjELMAkGA1UEBhMCVVMxGDAWBg" + "NVBAoTD1UuUy4gR292ZXJubWVudDEMMAoGA1UECxMDRG9kMRAwDgYDVQQLEwdUZXN0aW5n" + "MRUwEwYDVQQDEwxDQTEtUkwuMDcuMDEwHhcNOTgwMTAxMTIwMTAwWhcNNDgwMTAxMTIwMT" + "AwWjBgMQswCQYDVQQGEwJVUzEYMBYGA1UEChMPVS5TLiBHb3Zlcm5tZW50MQwwCgYDVQQL" + "EwNEb0QxEDAOBgNVBAsTB1Rlc3RpbmcxFzAVBgNVBAMTDlVzZXIxLVJMLjA3LjAxMIGfMA" + "0GCSqGSIb3DQEBAQUAA4GNADCBiQKBgQCrm/Zem9Tt2UJFUKdAhTNwvhLo03uOax74ZgbV" + "YNTCpKeEWkV5d5d7DRC4mCTX1yjIlg6K4l7T+sRGI4XAcDRgYLuoyG1X958XCXSdIPTdbK" + "Hxs/tFv4mrCwi1kU+zjyzDoqgjT6kUxgM39rfcvDMH6qSzHQKgTFp7Tj/DHiELqwIDAQAB" + "o1IwUDAOBgNVHQ8BAf8EBAMCBeAwFgYDVR0gBA8wDTALBglghkgBZQMBMAEwEQYDVR0OBA" + "oECGFR8c6rRbhcMBMGA1UdIwQMMAqACHPEkeIs8GuwMA0GCSqGSIb3DQEBBQUAA4GBAANZ" + "TVR288mKpDDzm9XZMZ9+K1kPZ+eQYX+vUul11luVw27AIJGR8Fb4PIGl4+ALvqU3NQP/6v" + "d+zvS7IfiR6q7aLS3w111BUCgDhTJAp3oSo12qfcp+2DB1M9QfjrM9nKgmh5bBJigdJwJM" + "W8HHKStUMLdxg+qkZJgZpnyowCFM"; public static final String[] TEST_72_DATA = new String[] { Intermediate_Certificate_RL_07_01_crt, Intermediate_CRL_RL_07_01_crl, End_Certificate_RL_07_01_crt }; /* * test73 * */ public static final String Intermediate_Certificate_RL_07_02_crt = "MIICljCCAf+gAwIBAgICAMEwDQYJKoZIhvcNAQEFBQAwXjELMAkGA1UEBhMCVVMxGDAWBg" + "NVBAoTD1UuUy4gR292ZXJubWVudDEMMAoGA1UECxMDRG9EMRAwDgYDVQQLEwdUZXN0aW5n" + "MRUwEwYDVQQDEwxUcnVzdCBBbmNob3IwHhcNNTAwMTAxMDYwMDMwWhcNNDgwMTAxMTIwMT" + "AwWjBeMQswCQYDVQQGEwJVUzEYMBYGA1UEChMPVS5TLiBHb3Zlcm5tZW50MQwwCgYDVQQL" + "EwNEb2QxEDAOBgNVBAsTB1Rlc3RpbmcxFTATBgNVBAMTDENBMS1STC4wNy4wMjCBnzANBg" + "kqhkiG9w0BAQEFAAOBjQAwgYkCgYEA0CvEneaAPtxZOTqlh/TXBM6V0bQgKbO58yEyURcO" + "Zi7jzYsmNtN9Tsr0wAlD41/ZONsW4MMzZ13UCc0aGa+eE8XRULBe5cgaGxJKwVnEqz3W8z" + "v1MjOk7Anb8TkxMSlWlptC6V3eRA85p5Id9gXbIrP3E3NuSfyx6246oLjNnbECAwEAAaNj" + "MGEwDwYDVR0TAQH/BAUwAwEB/zAOBgNVHQ8BAf8EBAMCAQYwFgYDVR0gBA8wDTALBglghk" + "gBZQMBMAEwEQYDVR0OBAoECIb5Ia6wKcHtMBMGA1UdIwQMMAqACKua6/nC51SPMA0GCSqG" + "SIb3DQEBBQUAA4GBAAYEHQY+Z4qv4bYLmd+sz4aNGwZF7FT6ZIQ43OSeb+t+ibL7rZ0X0y" + "4SCTMs1mAB44IA6RFurmeCFk0ladRCn3A1xaVI1HlHen13ovzDA9ogL4CWbYXvCUv/znQY" + "yVSQCTKwT8iVam8xS1MsNCe408iVjhRfR6u9Hi31M+Pf+AUe"; public static final String Intermediate_CRL_RL_07_02_crl = "MIIBSzCBtQIBATANBgkqhkiG9w0BAQUFADBeMQswCQYDVQQGEwJVUzEYMBYGA1UEChMPVS" + "5TLiBHb3Zlcm5tZW50MQwwCgYDVQQLEwNEb2QxEDAOBgNVBAsTB1Rlc3RpbmcxFTATBgNV" + "BAMTDENBMS1STC4wNy4wMhcNNTAwMTAxMDYwMTAwWhcNNTAwMTAxMTIwMTAwWqAjMCEwCg" + "YDVR0UBAMCAQEwEwYDVR0jBAwwCoAIhvkhrrApwe0wDQYJKoZIhvcNAQEFBQADgYEALVUq" + "3Wq/Opvp9ifmQ4VXz4dgLNR+5Nz3muJ4RZt5R5b4R3RYllhgXNYw2EbEVCFjnfm97z73Ke" + "wzVV+fo/u5GbqJHN2cAVEHarOpasLxySktNA1Cwq5OTzUF0dYISqYbyBvVcaOQBvU/Lwj7" + "MQJJVVq96iDKnAJYBX03EHKbBeg="; public static final String End_Certificate_RL_07_02_crt = "MIIChzCCAfCgAwIBAgICAMIwDQYJKoZIhvcNAQEFBQAwXjELMAkGA1UEBhMCVVMxGDAWBg" + "NVBAoTD1UuUy4gR292ZXJubWVudDEMMAoGA1UECxMDRG9kMRAwDgYDVQQLEwdUZXN0aW5n" + "MRUwEwYDVQQDEwxDQTEtUkwuMDcuMDIwHhcNOTgwMTAxMTIwMTAwWhcNNDgwMTAxMTIwMT" + "AwWjBgMQswCQYDVQQGEwJVUzEYMBYGA1UEChMPVS5TLiBHb3Zlcm5tZW50MQwwCgYDVQQL" + "EwNEb0QxEDAOBgNVBAsTB1Rlc3RpbmcxFzAVBgNVBAMTDlVzZXIxLVJMLjA3LjAyMIGfMA" + "0GCSqGSIb3DQEBAQUAA4GNADCBiQKBgQD6YgsbjW9IL7/SBORKssFUZBUxmluOpxJK/7d7" + "JA2pxbg7L96xHFPWN36CYDJzTscNpbGrD3G2MPkg4GqoTo0rU28NYVzj4SwqYoSLIbXB+r" + "SVgWcxNgbJ+4x9bK3YccNLR1PWEFxz1NckhCLBmb5pI4E34MCxQ6PvFO02I19FwQIDAQAB" + "o1IwUDAOBgNVHQ8BAf8EBAMCBeAwFgYDVR0gBA8wDTALBglghkgBZQMBMAEwEQYDVR0OBA" + "oECIutV9ItCIbZMBMGA1UdIwQMMAqACIb5Ia6wKcHtMA0GCSqGSIb3DQEBBQUAA4GBALQE" + "cBr31h3jKUHcuf3yztr9NWUkGMDM0NCXHOpQl7JbV3P5BjvaiRYWlUrN7+92G8EaUFORto" + "zp8GG+d/MvFooVQOvpOzyhautYWyqq3AWpZLppnxNk1mRAdjUAvJaONtv37eLsma0bhtLM" + "j62sQQ6CdoKbMtIEGuJgpwWqHYwY"; public static final String[] TEST_73_DATA = new String[] { Intermediate_Certificate_RL_07_02_crt, Intermediate_CRL_RL_07_02_crl, End_Certificate_RL_07_02_crt }; /* * test74 * */ public static final String Intermediate_Certificate_RL_07_03_crt = "MIICljCCAf+gAwIBAgICAMMwDQYJKoZIhvcNAQEFBQAwXjELMAkGA1UEBhMCVVMxGDAWBg" + "NVBAoTD1UuUy4gR292ZXJubWVudDEMMAoGA1UECxMDRG9EMRAwDgYDVQQLEwdUZXN0aW5n" + "MRUwEwYDVQQDEwxUcnVzdCBBbmNob3IwHhcNOTgwMTAxMTIwMTAwWhcNNDgwMTAxMTIwMT" + "AwWjBeMQswCQYDVQQGEwJVUzEYMBYGA1UEChMPVS5TLiBHb3Zlcm5tZW50MQwwCgYDVQQL" + "EwNEb2QxEDAOBgNVBAsTB1Rlc3RpbmcxFTATBgNVBAMTDENBMS1STC4wNy4wMzCBnzANBg" + "kqhkiG9w0BAQEFAAOBjQAwgYkCgYEA8QzGjV0NVTNrOgkeqTkQFCOvl7M0qmjmYJjuw4R3" + "YfQIXDN0m9HR2JKp5WKTSUedmWviGS7NbGSzLR7+6OkLwSoxN9PkA/fMko7O0KWBfduhvn" + "jymlDMb2GPb1hBjScbq8fVJHwzqUm+BtEO2MXwXKYY2hZr+OEyEGhSEThp90MCAwEAAaNj" + "MGEwDwYDVR0TAQH/BAUwAwEB/zAOBgNVHQ8BAf8EBAMCAQYwFgYDVR0gBA8wDTALBglghk" + "gBZQMBMAEwEQYDVR0OBAoECFwl2XphEZRSMBMGA1UdIwQMMAqACKua6/nC51SPMA0GCSqG" + "SIb3DQEBBQUAA4GBAAb5GERgYVGuOb62gVZAAnhuk5K7CCkWZucOv6iI7pAgI6S7pvool/" + "dXHC0tzgQ+/MkuWcr+22k/ya7f+iSfiYokjnQkgoYFYk3PkjyOXA3mzs5qhF0nOP6Gvmz4" + "asONA+qZSqa4pjxF9Kn8L64f9yeyEXnckmbzdmbjAFCveQIP"; public static final String Intermediate_CRL_RL_07_03_crl = "MIIBTTCBtwIBATANBgkqhkiG9w0BAQUFADBeMQswCQYDVQQGEwJVUzEYMBYGA1UEChMPVS" + "5TLiBHb3Zlcm5tZW50MQwwCgYDVQQLEwNEb2QxEDAOBgNVBAsTB1Rlc3RpbmcxFTATBgNV" + "BAMTDENBMS1STC4wNy4wMxcNOTkwMTAxMDYwMTAwWhgPMjA1MDAxMDExMjAxMDBaoCMwIT" + "AKBgNVHRQEAwIBATATBgNVHSMEDDAKgAhcJdl6YRGUUjANBgkqhkiG9w0BAQUFAAOBgQAz" + "DMl8P16hylNkUEw4z9//PJFObNPZCYdmzBfp0K3tNRrOAouUVegyX0gDHi8O+bmmJNgcnC" + "tMRXx+D4qP7bx5fDS2MVQhSsncf6u4UZ8pxbRc0JmwR5oGZLPQabrctgmEmg8ZKGApKtsf" + "pGyvvTwaAzM+GaWXD68bBEN3VfVdeQ=="; public static final String End_Certificate_RL_07_03_crt = "MIIChzCCAfCgAwIBAgICAMQwDQYJKoZIhvcNAQEFBQAwXjELMAkGA1UEBhMCVVMxGDAWBg" + "NVBAoTD1UuUy4gR292ZXJubWVudDEMMAoGA1UECxMDRG9kMRAwDgYDVQQLEwdUZXN0aW5n" + "MRUwEwYDVQQDEwxDQTEtUkwuMDcuMDMwHhcNOTgwMTAxMTIwMTAwWhcNNDgwMTAxMTIwMT" + "AwWjBgMQswCQYDVQQGEwJVUzEYMBYGA1UEChMPVS5TLiBHb3Zlcm5tZW50MQwwCgYDVQQL" + "EwNEb0QxEDAOBgNVBAsTB1Rlc3RpbmcxFzAVBgNVBAMTDlVzZXIxLVJMLjA3LjAzMIGfMA" + "0GCSqGSIb3DQEBAQUAA4GNADCBiQKBgQDU6mec24uBaVip7fFWHas+o/lpZBOfj/IPHXQ9" + "QaRZwmJZBB81AX3BJ60DD12o/+RXdHl7B2Eh9kYv/QEXOKmyhJFSPa0Lv7MQ/hCIcL4m1U" + "FDGtJ3SUixZMqVBP0xjwXoNS88zzaCBL+co2TxhBrYMzeNQOX1eEkXMT4pvULmAwIDAQAB" + "o1IwUDAOBgNVHQ8BAf8EBAMCBeAwFgYDVR0gBA8wDTALBglghkgBZQMBMAEwEQYDVR0OBA" + "oECBBgFdYLuvk9MBMGA1UdIwQMMAqACFwl2XphEZRSMA0GCSqGSIb3DQEBBQUAA4GBAAof" + "dPOGa4ZxRPcLw6zWM/NLzF3XYDqXAsZBsC75r0GRrogqEYn07tVUDNaQczDtjRLBRNmxWE" + "+qCkJwc+wOBJqOFUxcuhK9oag6OE94+UIHdh3Td9i2ELZXj9RSNchnjyFohj5gk1dJSO41" + "86Ls3mCT9JcssR0dSxxkF0ENfZCG"; public static final String[] TEST_74_DATA = new String[] { Intermediate_Certificate_RL_07_03_crt, Intermediate_CRL_RL_07_03_crl, End_Certificate_RL_07_03_crt }; /* * test75 * */ public static final String Intermediate_Certificate_RL_08_01_crt = "MIICljCCAf+gAwIBAgICAMUwDQYJKoZIhvcNAQEFBQAwXjELMAkGA1UEBhMCVVMxGDAWBg" + "NVBAoTD1UuUy4gR292ZXJubWVudDEMMAoGA1UECxMDRG9EMRAwDgYDVQQLEwdUZXN0aW5n" + "MRUwEwYDVQQDEwxUcnVzdCBBbmNob3IwHhcNOTgwMTAxMTIwMTAwWhcNNDgwMTAxMTIwMT" + "AwWjBeMQswCQYDVQQGEwJVUzEYMBYGA1UEChMPVS5TLiBHb3Zlcm5tZW50MQwwCgYDVQQL" + "EwNEb2QxEDAOBgNVBAsTB1Rlc3RpbmcxFTATBgNVBAMTDENBMS1STC4wOC4wMTCBnzANBg" + "kqhkiG9w0BAQEFAAOBjQAwgYkCgYEAs2YRTEl3C1TmmneJ6K110nSACn+KXxSOTGAGN5xv" + "XW751StpE2iEQIbRVPQdMzmcQX0bcg/WpdrewPQld9NRjFj7it+9YNQh7vMKhZwoAPoDmv" + "TnTdTEuV0c1FLVDVhiaAD9KMBa4fBLRfTKVzgzAr+oNqLhm3YBd2JWRHg+fA8CAwEAAaNj" + "MGEwDwYDVR0TAQH/BAUwAwEB/zAOBgNVHQ8BAf8EBAMCAQYwFgYDVR0gBA8wDTALBglghk" + "gBZQMBMAEwEQYDVR0OBAoECB4we8+hIrkKMBMGA1UdIwQMMAqACKua6/nC51SPMA0GCSqG" + "SIb3DQEBBQUAA4GBABTQI82uCMwQ4bgUWr9lawSI5DyWg3KY13F45rAlmKyckgne9SHbCH" + "+Lvm3XkkIqKmeHfJ3QTf7bpz6eErn3CxRrGm5JWblcYbVT+smjboJ9A0BXifqINYLy3qGc" + "AnNRkPq8OUREj2sU1qWKagUIgA/Vk2WyZhcUiApJPHI4fwv9"; public static final String Intermediate_CRL_RL_08_01_crl = "MIIBWjCBxAIBATANBgkqhkiG9w0BAQUFADBeMQswCQYDVQQGEwJVUzEYMBYGA1UEChMPVS" + "5TLiBHb3Zlcm5tZW50MQwwCgYDVQQLEwNEb2QxEDAOBgNVBAsTB1Rlc3RpbmcxFTATBgNV" + "BAMTDENBMS1STC4wOC4wMRcNOTkwMTAxMTIwMTAwWhcNNDgwMTAxMTIwMTAwWqAyMDAwCg" + "YDVR0UBAMCAQEwDQYDVR0bAQH/BAMCAQEwEwYDVR0jBAwwCoAIHjB7z6EiuQowDQYJKoZI" + "hvcNAQEFBQADgYEAkjF0oERt5XW2i70gyspkEYIHyGCHnqngky5yuwQSRrlW7t0vGdKV7W" + "50evTeSVV41uhi1MBcccpx1MdRcB5vsatFSSKcKx4NF3PuHXxXCm2HkfXQy4K5zftE3jOZ" + "5s+yTHiw3s/QSErtHRca+TQcEZwamI+p402TEa6e82l6xHI="; public static final String End_Certificate_RL_08_01_crt = "MIIChzCCAfCgAwIBAgICAMYwDQYJKoZIhvcNAQEFBQAwXjELMAkGA1UEBhMCVVMxGDAWBg" + "NVBAoTD1UuUy4gR292ZXJubWVudDEMMAoGA1UECxMDRG9kMRAwDgYDVQQLEwdUZXN0aW5n" + "MRUwEwYDVQQDEwxDQTEtUkwuMDguMDEwHhcNOTgwMTAxMTIwMTAwWhcNNDgwMTAxMTIwMT" + "AwWjBgMQswCQYDVQQGEwJVUzEYMBYGA1UEChMPVS5TLiBHb3Zlcm5tZW50MQwwCgYDVQQL" + "EwNEb0QxEDAOBgNVBAsTB1Rlc3RpbmcxFzAVBgNVBAMTDlVzZXIxLVJMLjA4LjAxMIGfMA" + "0GCSqGSIb3DQEBAQUAA4GNADCBiQKBgQDfEMqWMqk3Rre5m4ILtQIz45JImvU379Al/S6t" + "2y/TzimJc4nhIKQp80VaZA/gwu/DcvMgJPM+FFz5U5rRkDaYASsc34tZUESF5LC6ZbtGqf" + "J96IKdajvkGLsHyI7dseuwaQ0FlOwcmKMSR898MGNNbKxaQNLEXsIFypRDsN6JhwIDAQAB" + "o1IwUDAOBgNVHQ8BAf8EBAMCBeAwFgYDVR0gBA8wDTALBglghkgBZQMBMAEwEQYDVR0OBA" + "oECMT22ARjB1ABMBMGA1UdIwQMMAqACB4we8+hIrkKMA0GCSqGSIb3DQEBBQUAA4GBAIaP" + "EqI7oHl/+h3MszG4VB1Va9NTN0kaysTyjQSVBi9jhOlPkzuXc2wI1bymBhatHEn6OrgP13" + "vsOiH2BiyudYcYjKpwI4FUiyKLIc0CXzM0VYFoMzb91QtsK1EnvAPDKNYVVFXrL7ABVIK4" + "hU6HfMMUbnpKWBxT5274iHScX8tL"; public static final String[] TEST_75_DATA = new String[] { Intermediate_Certificate_RL_08_01_crt, Intermediate_CRL_RL_08_01_crl, End_Certificate_RL_08_01_crt }; /* * test76 * */ public static final String Intermediate_Certificate_RL_09_01_crt = "MIICljCCAf+gAwIBAgICAMcwDQYJKoZIhvcNAQEFBQAwXjELMAkGA1UEBhMCVVMxGDAWBg" + "NVBAoTD1UuUy4gR292ZXJubWVudDEMMAoGA1UECxMDRG9EMRAwDgYDVQQLEwdUZXN0aW5n" + "MRUwEwYDVQQDEwxUcnVzdCBBbmNob3IwHhcNOTgwMTAxMTIwMTAwWhcNNDgwMTAxMTIwMT" + "AwWjBeMQswCQYDVQQGEwJVUzEYMBYGA1UEChMPVS5TLiBHb3Zlcm5tZW50MQwwCgYDVQQL" + "EwNEb2QxEDAOBgNVBAsTB1Rlc3RpbmcxFTATBgNVBAMTDENBMS1STC4wOS4wMTCBnzANBg" + "kqhkiG9w0BAQEFAAOBjQAwgYkCgYEAsvkvLv5fMFYvohaXO8a7GgU4rDHe9iL7LP1VeNUg" + "GIdJGqPEnuggQ/guhrBHafGh1NtmlEbmPJ4WQ99dBbPHHeO8sfCgkmWC0SqPODoI+t3qJE" + "kf2z9dWoAij15RXPliywZz+S6bTtcEQAREyBQ6M8/HJ83wRXp/uCpdPOSxVPkCAwEAAaNj" + "MGEwDwYDVR0TAQH/BAUwAwEB/zAOBgNVHQ8BAf8EBAMCAQYwFgYDVR0gBA8wDTALBglghk" + "gBZQMBMAEwEQYDVR0OBAoECISY4bvGMEBTMBMGA1UdIwQMMAqACKua6/nC51SPMA0GCSqG" + "SIb3DQEBBQUAA4GBAAd7g+dWso4V/Vr+QIoNLueCBAYWdOF+Yz3VeomcsDAs2V8E+xcZaq" + "jo2LrMygYCeMxVfXx/ZdhLPOaZ+ahNAbk+nWRwj35JdTNAAbMMWFdZUgR6N+uzx1v7i86p" + "AWUpRJ9IYPgUoQ5pmjdf3Ru1nrLfRt4yp+kNHWp6IL/+MwcM"; public static final String Intermediate_CRL_RL_09_01_crl = "MIIBXDCBxgIBATANBgkqhkiG9w0BAQUFADBeMQswCQYDVQQGEwJVUzEYMBYGA1UEChMPVS" + "5TLiBHb3Zlcm5tZW50MQwwCgYDVQQLEwNEb2QxEDAOBgNVBAsTB1Rlc3RpbmcxFTATBgNV" + "BAMTDENBMS1STC4wOS4wMRcNOTkwMTAxMTIwMTAwWhcNNDgwMTAxMTIwMTAwWqA0MDIwCg" + "YDVR0UBAMCAQEwDwYDVR0cAQH/BAUwA4IB/zATBgNVHSMEDDAKgAiEmOG7xjBAUzANBgkq" + "hkiG9w0BAQUFAAOBgQAKTXYgqlP+upFIwOSpdaVKDT8aqFzY9nSIsxHg5Wdl43U7p44LvQ" + "lW8XKhw74oQl1ExU5s7mDaEqB0JIozGzmoNyKsErgWKNW+lpKSxR5+1EHOB6Oo2KijpTsv" + "GFrHFCnF09f9JaTaMRIXOljx3rMO1UZsftKy/L9z3aUz8hQRnQ=="; public static final String End_Certificate_RL_09_01_crt = "MIIChzCCAfCgAwIBAgICAMgwDQYJKoZIhvcNAQEFBQAwXjELMAkGA1UEBhMCVVMxGDAWBg" + "NVBAoTD1UuUy4gR292ZXJubWVudDEMMAoGA1UECxMDRG9kMRAwDgYDVQQLEwdUZXN0aW5n" + "MRUwEwYDVQQDEwxDQTEtUkwuMDkuMDEwHhcNOTgwMTAxMTIwMTAwWhcNNDgwMTAxMTIwMT" + "AwWjBgMQswCQYDVQQGEwJVUzEYMBYGA1UEChMPVS5TLiBHb3Zlcm5tZW50MQwwCgYDVQQL" + "EwNEb0QxEDAOBgNVBAsTB1Rlc3RpbmcxFzAVBgNVBAMTDlVzZXIxLVJMLjA5LjAxMIGfMA" + "0GCSqGSIb3DQEBAQUAA4GNADCBiQKBgQDpz09VCXzAhH4/ifMk0RAzaBqJCXaHHqAdO/TW" + "6uvOVtl+fGvWXhXmSSCUfzg5xBqdUXrqcyxOME3vdgF1uOFZ4q2K6+Zuxmm+GCOCIpe+Gl" + "Jzqz4WKXG0iaXXQOYa56itNc/6Z6D/aAjNJavI19w0lmb9l6U2WBfn3LywxHp4dwIDAQAB" + "o1IwUDAOBgNVHQ8BAf8EBAMCBeAwFgYDVR0gBA8wDTALBglghkgBZQMBMAEwEQYDVR0OBA" + "oECOri1JgnJfLjMBMGA1UdIwQMMAqACISY4bvGMEBTMA0GCSqGSIb3DQEBBQUAA4GBADmV" + "Ee0xy25Z0HtmWwprKPjJDr/p7TgzbmNC58pUPkgtxnJFP4yrzNB9FQBWSfnjZpzQkLSU7i" + "7O6cf5HkqjQqoPErDnJLWgGzjbF80v2IIyZk7rEpAAM4MwjIk7hFvJK8QkTht9F4N1zj2X" + "0TQkmlbo9Z4SFj/3fsbl9h2GdKuU"; public static final String[] TEST_76_DATA = new String[] { Intermediate_Certificate_RL_09_01_crt, Intermediate_CRL_RL_09_01_crl, End_Certificate_RL_09_01_crt }; } bouncycastle-1.49.orig/test/src/org/bouncycastle/jce/provider/test/MQVTest.java0000644000175000017500000000561211275506021027204 0ustar ebourgebourgpackage org.bouncycastle.jce.provider.test; import java.math.BigInteger; import java.security.KeyPair; import java.security.KeyPairGenerator; import java.security.SecureRandom; import java.security.Security; import java.security.spec.ECFieldFp; import java.security.spec.ECParameterSpec; import java.security.spec.EllipticCurve; import javax.crypto.KeyAgreement; import org.bouncycastle.jce.ECPointUtil; import org.bouncycastle.jce.provider.BouncyCastleProvider; import org.bouncycastle.jce.spec.MQVPrivateKeySpec; import org.bouncycastle.jce.spec.MQVPublicKeySpec; import org.bouncycastle.util.encoders.Hex; import org.bouncycastle.util.test.SimpleTest; public class MQVTest extends SimpleTest { public String getName() { return "MQV"; } public void performTest() throws Exception { testECMQV(); } private void testECMQV() throws Exception { KeyPairGenerator g = KeyPairGenerator.getInstance("ECMQV", "BC"); EllipticCurve curve = new EllipticCurve( new ECFieldFp(new BigInteger("883423532389192164791648750360308885314476597252960362792450860609699839")), // q new BigInteger("7fffffffffffffffffffffff7fffffffffff8000000000007ffffffffffc", 16), // a new BigInteger("6b016c3bdcf18941d0d654921475ca71a9db2fb27d1d37796185c2942c0a", 16)); // b ECParameterSpec ecSpec = new ECParameterSpec( curve, ECPointUtil.decodePoint(curve, Hex.decode("020ffa963cdca8816ccc33b8642bedf905c3d358573d3f27fbbd3b3cb9aaaf")), // G new BigInteger("883423532389192164791648750360308884807550341691627752275345424702807307"), // n 1); // h g.initialize(ecSpec, new SecureRandom()); // // U side // KeyPair U1 = g.generateKeyPair(); KeyPair U2 = g.generateKeyPair(); KeyAgreement uAgree = KeyAgreement.getInstance("ECMQV", "BC"); uAgree.init(new MQVPrivateKeySpec(U1.getPrivate(), U2.getPrivate(), U2.getPublic())); // // V side // KeyPair V1 = g.generateKeyPair(); KeyPair V2 = g.generateKeyPair(); KeyAgreement vAgree = KeyAgreement.getInstance("ECMQV", "BC"); vAgree.init(new MQVPrivateKeySpec(V1.getPrivate(), V2.getPrivate(), V2.getPublic())); // // agreement // uAgree.doPhase(new MQVPublicKeySpec(V1.getPublic(), V2.getPublic()), true); vAgree.doPhase(new MQVPublicKeySpec(U1.getPublic(), U2.getPublic()), true); BigInteger ux = new BigInteger(uAgree.generateSecret()); BigInteger vx = new BigInteger(vAgree.generateSecret()); if (!ux.equals(vx)) { fail("Agreement failed"); } } public static void main( String[] args) { Security.addProvider(new BouncyCastleProvider()); runTest(new MQVTest()); } } bouncycastle-1.49.orig/test/src/org/bouncycastle/jce/provider/test/SEEDTest.java0000644000175000017500000001073010565527063027270 0ustar ebourgebourgpackage org.bouncycastle.jce.provider.test; import org.bouncycastle.asn1.kisa.KISAObjectIdentifiers; import org.bouncycastle.jce.provider.BouncyCastleProvider; import org.bouncycastle.util.encoders.Hex; import javax.crypto.Cipher; import javax.crypto.CipherInputStream; import javax.crypto.CipherOutputStream; import javax.crypto.spec.SecretKeySpec; import java.io.ByteArrayInputStream; import java.io.ByteArrayOutputStream; import java.io.DataInputStream; import java.io.IOException; import java.security.Key; import java.security.Security; /** * basic test class for SEED */ public class SEEDTest extends BaseBlockCipherTest { static String[] cipherTests = { "128", "28DBC3BC49FFD87DCFA509B11D422BE7", "B41E6BE2EBA84A148E2EED84593C5EC7", "9B9B7BFCD1813CB95D0B3618F40F5122" }; public SEEDTest() { super("SEED"); } public void test( int strength, byte[] keyBytes, byte[] input, byte[] output) throws Exception { Key key; Cipher in, out; CipherInputStream cIn; CipherOutputStream cOut; ByteArrayInputStream bIn; ByteArrayOutputStream bOut; key = new SecretKeySpec(keyBytes, "SEED"); in = Cipher.getInstance("SEED/ECB/NoPadding", "BC"); out = Cipher.getInstance("SEED/ECB/NoPadding", "BC"); try { out.init(Cipher.ENCRYPT_MODE, key); } catch (Exception e) { fail("SEED failed initialisation - " + e.toString(), e); } try { in.init(Cipher.DECRYPT_MODE, key); } catch (Exception e) { fail("SEED failed initialisation - " + e.toString(), e); } // // encryption pass // bOut = new ByteArrayOutputStream(); cOut = new CipherOutputStream(bOut, out); try { for (int i = 0; i != input.length / 2; i++) { cOut.write(input[i]); } cOut.write(input, input.length / 2, input.length - input.length / 2); cOut.close(); } catch (IOException e) { fail("SEED failed encryption - " + e.toString(), e); } byte[] bytes; bytes = bOut.toByteArray(); if (!areEqual(bytes, output)) { fail("SEED failed encryption - expected " + new String(Hex.encode(output)) + " got " + new String(Hex.encode(bytes))); } // // decryption pass // bIn = new ByteArrayInputStream(bytes); cIn = new CipherInputStream(bIn, in); try { DataInputStream dIn = new DataInputStream(cIn); bytes = new byte[input.length]; for (int i = 0; i != input.length / 2; i++) { bytes[i] = (byte)dIn.read(); } dIn.readFully(bytes, input.length / 2, bytes.length - input.length / 2); } catch (Exception e) { fail("SEED failed encryption - " + e.toString(), e); } if (!areEqual(bytes, input)) { fail("SEED failed decryption - expected " + new String(Hex.encode(input)) + " got " + new String(Hex.encode(bytes))); } } public void performTest() throws Exception { for (int i = 0; i != cipherTests.length; i += 4) { test(Integer.parseInt(cipherTests[i]), Hex.decode(cipherTests[i + 1]), Hex.decode(cipherTests[i + 2]), Hex.decode(cipherTests[i + 3])); } byte[] kek1 = Hex.decode("000102030405060708090a0b0c0d0e0f"); byte[] in1 = Hex.decode("00112233445566778899aabbccddeeff"); byte[] out1 = Hex.decode("bf71f77138b5afea05232a8dad54024e812dc8dd7d132559"); wrapTest(1, "SEEDWrap", kek1, in1, out1); String[] oids = { KISAObjectIdentifiers.id_seedCBC.getId() }; String[] names = { "SEED/CBC/PKCS7Padding" }; oidTest(oids, names, 1); String[] wrapOids = { KISAObjectIdentifiers.id_npki_app_cmsSeed_wrap.getId() }; wrapOidTest(wrapOids, "SEEDWrap"); } public static void main( String[] args) { Security.addProvider(new BouncyCastleProvider()); runTest(new SEEDTest()); } } bouncycastle-1.49.orig/test/src/org/bouncycastle/jce/provider/test/CertUniqueIDTest.java0000644000175000017500000001367711347003362031054 0ustar ebourgebourgpackage org.bouncycastle.jce.provider.test; import java.math.BigInteger; import java.security.KeyFactory; import java.security.PrivateKey; import java.security.PublicKey; import java.security.Security; import java.security.cert.X509Certificate; import java.security.spec.RSAPrivateCrtKeySpec; import java.security.spec.RSAPublicKeySpec; import java.util.Date; import java.util.Set; import java.util.Vector; import org.bouncycastle.jce.X509Principal; import org.bouncycastle.jce.provider.BouncyCastleProvider; import org.bouncycastle.util.Arrays; import org.bouncycastle.util.test.SimpleTest; import org.bouncycastle.x509.X509V3CertificateGenerator; public class CertUniqueIDTest extends SimpleTest { public String getName() { return "CertUniqueID"; } public void performTest() throws Exception { checkCreation1(); } /** * we generate a self signed certificate for the sake of testing - RSA */ public void checkCreation1() throws Exception { // // a sample key pair. // RSAPublicKeySpec pubKeySpec = new RSAPublicKeySpec( new BigInteger("b4a7e46170574f16a97082b22be58b6a2a629798419be12872a4bdba626cfae9900f76abfb12139dce5de56564fab2b6543165a040c606887420e33d91ed7ed7", 16), new BigInteger("11", 16)); RSAPrivateCrtKeySpec privKeySpec = new RSAPrivateCrtKeySpec( new BigInteger("b4a7e46170574f16a97082b22be58b6a2a629798419be12872a4bdba626cfae9900f76abfb12139dce5de56564fab2b6543165a040c606887420e33d91ed7ed7", 16), new BigInteger("11", 16), new BigInteger("9f66f6b05410cd503b2709e88115d55daced94d1a34d4e32bf824d0dde6028ae79c5f07b580f5dce240d7111f7ddb130a7945cd7d957d1920994da389f490c89", 16), new BigInteger("c0a0758cdf14256f78d4708c86becdead1b50ad4ad6c5c703e2168fbf37884cb", 16), new BigInteger("f01734d7960ea60070f1b06f2bb81bfac48ff192ae18451d5e56c734a5aab8a5", 16), new BigInteger("b54bb9edff22051d9ee60f9351a48591b6500a319429c069a3e335a1d6171391", 16), new BigInteger("d3d83daf2a0cecd3367ae6f8ae1aeb82e9ac2f816c6fc483533d8297dd7884cd", 16), new BigInteger("b8f52fc6f38593dabb661d3f50f8897f8106eee68b1bce78a95b132b4e5b5d19", 16)); // // set up the keys // PrivateKey privKey; PublicKey pubKey; KeyFactory fact = KeyFactory.getInstance("RSA", "BC"); privKey = fact.generatePrivate(privKeySpec); pubKey = fact.generatePublic(pubKeySpec); // // distinguished name table. // Vector ord = new Vector(); Vector values = new Vector(); ord.addElement(X509Principal.C); ord.addElement(X509Principal.O); ord.addElement(X509Principal.L); ord.addElement(X509Principal.ST); ord.addElement(X509Principal.E); values.addElement("AU"); values.addElement("The Legion of the Bouncy Castle"); values.addElement("Melbourne"); values.addElement("Victoria"); values.addElement("feedback-crypto@bouncycastle.org"); // // extensions // // // create the certificate - version 3 - without subject unique ID // X509V3CertificateGenerator certGen = new X509V3CertificateGenerator(); certGen.setSerialNumber(BigInteger.valueOf(1)); certGen.setIssuerDN(new X509Principal(ord, values)); certGen.setNotBefore(new Date(System.currentTimeMillis() - 50000)); certGen.setNotAfter(new Date(System.currentTimeMillis() + 50000)); certGen.setSubjectDN(new X509Principal(ord, values)); certGen.setPublicKey(pubKey); certGen.setSignatureAlgorithm("SHA256WithRSAEncryption"); X509Certificate cert = certGen.generate(privKey); cert.checkValidity(new Date()); cert.verify(pubKey); Set dummySet = cert.getNonCriticalExtensionOIDs(); if (dummySet != null) { fail("non-critical oid set should be null"); } dummySet = cert.getCriticalExtensionOIDs(); if (dummySet != null) { fail("critical oid set should be null"); } // // create the certificate - version 3 - with subject unique ID // certGen = new X509V3CertificateGenerator(); certGen.setSerialNumber(BigInteger.valueOf(1)); certGen.setIssuerDN(new X509Principal(ord, values)); certGen.setNotBefore(new Date(System.currentTimeMillis() - 50000)); certGen.setNotAfter(new Date(System.currentTimeMillis() + 50000)); certGen.setSubjectDN(new X509Principal(ord, values)); certGen.setPublicKey(pubKey); certGen.setSignatureAlgorithm("MD5WithRSAEncryption"); boolean[] subjectUniqID = {true, false, false, false, true, false, false, true, false, true, true}; certGen.setSubjectUniqueID(subjectUniqID); boolean[] issuerUniqID = {false, false, true, false, true, false, false, false, true, false, false, true, false, true, true}; certGen.setIssuerUniqueID(issuerUniqID); cert = certGen.generate(privKey); cert.checkValidity(new Date()); cert.verify(pubKey); boolean[] subjectUniqueId = cert.getSubjectUniqueID(); if (!Arrays.areEqual(subjectUniqID, subjectUniqueId)) { fail("Subject unique id is not correct, original: "+arrayToString(subjectUniqID)+", from cert: "+arrayToString(subjectUniqueId)); } boolean[] issuerUniqueId = cert.getIssuerUniqueID(); if (!Arrays.areEqual(issuerUniqID, issuerUniqueId)) { fail("Issuer unique id is not correct, original: "+arrayToString(issuerUniqID)+", from cert: "+arrayToString(subjectUniqueId)); } } private String arrayToString(boolean[] array) { StringBuffer b = new StringBuffer(); for (int i = 0; i != array.length; i++) { b.append(array[i] ? "1" : "0"); } return b.toString(); } public static void main( String[] args) { Security.addProvider(new BouncyCastleProvider()); runTest(new CertUniqueIDTest()); } } bouncycastle-1.49.orig/test/src/org/bouncycastle/jce/provider/test/PEMData.java0000644000175000017500000001604311421463621027115 0ustar ebourgebourgpackage org.bouncycastle.jce.provider.test; public class PEMData { public static String CERTIFICATE_1 = "-----BEGIN X509 CERTIFICATE-----\r" + "MIIDXjCCAsegAwIBAgIBBzANBgkqhkiG9w0BAQQFADCBtzELMAkGA1UEBhMCQVUx\r" + "ETAPBgNVBAgTCFZpY3RvcmlhMRgwFgYDVQQHEw9Tb3V0aCBNZWxib3VybmUxGjAY\r" + "BgNVBAoTEUNvbm5lY3QgNCBQdHkgTHRkMR4wHAYDVQQLExVDZXJ0aWZpY2F0ZSBB\r" + "dXRob3JpdHkxFTATBgNVBAMTDENvbm5lY3QgNCBDQTEoMCYGCSqGSIb3DQEJARYZ\r" + "d2VibWFzdGVyQGNvbm5lY3Q0LmNvbS5hdTAeFw0wMDA2MDIwNzU2MjFaFw0wMTA2\r" + "MDIwNzU2MjFaMIG4MQswCQYDVQQGEwJBVTERMA8GA1UECBMIVmljdG9yaWExGDAW\r" + "BgNVBAcTD1NvdXRoIE1lbGJvdXJuZTEaMBgGA1UEChMRQ29ubmVjdCA0IFB0eSBM\r" + "dGQxFzAVBgNVBAsTDldlYnNlcnZlciBUZWFtMR0wGwYDVQQDExR3d3cyLmNvbm5l\r" + "Y3Q0LmNvbS5hdTEoMCYGCSqGSIb3DQEJARYZd2VibWFzdGVyQGNvbm5lY3Q0LmNv\r" + "bS5hdTCBnzANBgkqhkiG9w0BAQEFAAOBjQAwgYkCgYEArvDxclKAhyv7Q/Wmr2re\r" + "Gw4XL9Cnh9e+6VgWy2AWNy/MVeXdlxzd7QAuc1eOWQkGQEiLPy5XQtTY+sBUJ3AO\r" + "Rvd2fEVJIcjf29ey7bYua9J/vz5MG2KYo9/WCHIwqD9mmG9g0xLcfwq/s8ZJBswE\r" + "7sb85VU+h94PTvsWOsWuKaECAwEAAaN3MHUwJAYDVR0RBB0wG4EZd2VibWFzdGVy\r" + "QGNvbm5lY3Q0LmNvbS5hdTA6BglghkgBhvhCAQ0ELRYrbW9kX3NzbCBnZW5lcmF0\r" + "ZWQgY3VzdG9tIHNlcnZlciBjZXJ0aWZpY2F0ZTARBglghkgBhvhCAQEEBAMCBkAw\r" + "DQYJKoZIhvcNAQEEBQADgYEAotccfKpwSsIxM1Hae8DR7M/Rw8dg/RqOWx45HNVL\r" + "iBS4/3N/TO195yeQKbfmzbAA2jbPVvIvGgTxPgO1MP4ZgvgRhasaa0qCJCkWvpM4\r" + "yQf33vOiYQbpv4rTwzU8AmRlBG45WdjyNIigGV+oRc61aKCTnLq7zB8N3z1TF/bF\r" + "5/8=\r" + "-----END X509 CERTIFICATE-----\r"; public static String CERTIFICATE_2 = "-----BEGIN CERTIFICATE-----\n" + "MIIDXjCCAsegAwIBAgIBBzANBgkqhkiG9w0BAQQFADCBtzELMAkGA1UEBhMCQVUx\n" + "ETAPBgNVBAgTCFZpY3RvcmlhMRgwFgYDVQQHEw9Tb3V0aCBNZWxib3VybmUxGjAY\n" + "BgNVBAoTEUNvbm5lY3QgNCBQdHkgTHRkMR4wHAYDVQQLExVDZXJ0aWZpY2F0ZSBB\n" + "dXRob3JpdHkxFTATBgNVBAMTDENvbm5lY3QgNCBDQTEoMCYGCSqGSIb3DQEJARYZ\n" + "d2VibWFzdGVyQGNvbm5lY3Q0LmNvbS5hdTAeFw0wMDA2MDIwNzU2MjFaFw0wMTA2\n" + "MDIwNzU2MjFaMIG4MQswCQYDVQQGEwJBVTERMA8GA1UECBMIVmljdG9yaWExGDAW\n" + "BgNVBAcTD1NvdXRoIE1lbGJvdXJuZTEaMBgGA1UEChMRQ29ubmVjdCA0IFB0eSBM\n" + "dGQxFzAVBgNVBAsTDldlYnNlcnZlciBUZWFtMR0wGwYDVQQDExR3d3cyLmNvbm5l\n" + "Y3Q0LmNvbS5hdTEoMCYGCSqGSIb3DQEJARYZd2VibWFzdGVyQGNvbm5lY3Q0LmNv\n" + "bS5hdTCBnzANBgkqhkiG9w0BAQEFAAOBjQAwgYkCgYEArvDxclKAhyv7Q/Wmr2re\n" + "Gw4XL9Cnh9e+6VgWy2AWNy/MVeXdlxzd7QAuc1eOWQkGQEiLPy5XQtTY+sBUJ3AO\n" + "Rvd2fEVJIcjf29ey7bYua9J/vz5MG2KYo9/WCHIwqD9mmG9g0xLcfwq/s8ZJBswE\n" + "7sb85VU+h94PTvsWOsWuKaECAwEAAaN3MHUwJAYDVR0RBB0wG4EZd2VibWFzdGVy\n" + "QGNvbm5lY3Q0LmNvbS5hdTA6BglghkgBhvhCAQ0ELRYrbW9kX3NzbCBnZW5lcmF0\n" + "ZWQgY3VzdG9tIHNlcnZlciBjZXJ0aWZpY2F0ZTARBglghkgBhvhCAQEEBAMCBkAw\n" + "DQYJKoZIhvcNAQEEBQADgYEAotccfKpwSsIxM1Hae8DR7M/Rw8dg/RqOWx45HNVL\n" + "iBS4/3N/TO195yeQKbfmzbAA2jbPVvIvGgTxPgO1MP4ZgvgRhasaa0qCJCkWvpM4\n" + "yQf33vOiYQbpv4rTwzU8AmRlBG45WdjyNIigGV+oRc61aKCTnLq7zB8N3z1TF/bF\n" + "5/8=\n" + "-----END CERTIFICATE-----\n"; public static String CRL_1 = "-----BEGIN X509 CRL-----\r\n" + "MIICjTCCAfowDQYJKoZIhvcNAQECBQAwXzELMAkGA1UEBhMCVVMxIDAeBgNVBAoT\r\n" + "F1JTQSBEYXRhIFNlY3VyaXR5LCBJbmMuMS4wLAYDVQQLEyVTZWN1cmUgU2VydmVy\r\n" + "IENlcnRpZmljYXRpb24gQXV0aG9yaXR5Fw05NTA1MDIwMjEyMjZaFw05NTA2MDEw\r\n" + "MDAxNDlaMIIBaDAWAgUCQQAABBcNOTUwMjAxMTcyNDI2WjAWAgUCQQAACRcNOTUw\r\n" + "MjEwMDIxNjM5WjAWAgUCQQAADxcNOTUwMjI0MDAxMjQ5WjAWAgUCQQAADBcNOTUw\r\n" + "MjI1MDA0NjQ0WjAWAgUCQQAAGxcNOTUwMzEzMTg0MDQ5WjAWAgUCQQAAFhcNOTUw\r\n" + "MzE1MTkxNjU0WjAWAgUCQQAAGhcNOTUwMzE1MTk0MDQxWjAWAgUCQQAAHxcNOTUw\r\n" + "MzI0MTk0NDMzWjAWAgUCcgAABRcNOTUwMzI5MjAwNzExWjAWAgUCcgAAERcNOTUw\r\n" + "MzMwMDIzNDI2WjAWAgUCQQAAIBcNOTUwNDA3MDExMzIxWjAWAgUCcgAAHhcNOTUw\r\n" + "NDA4MDAwMjU5WjAWAgUCcgAAQRcNOTUwNDI4MTcxNzI0WjAWAgUCcgAAOBcNOTUw\r\n" + "NDI4MTcyNzIxWjAWAgUCcgAATBcNOTUwNTAyMDIxMjI2WjANBgkqhkiG9w0BAQIF\r\n" + "AAN+AHqOEJXSDejYy0UwxxrH/9+N2z5xu/if0J6qQmK92W0hW158wpJg+ovV3+wQ\r\n" + "wvIEPRL2rocL0tKfAsVq1IawSJzSNgxG0lrcla3MrJBnZ4GaZDu4FutZh72MR3Gt\r\n" + "JaAL3iTJHJD55kK2D/VoyY1djlsPuNh6AEgdVwFAyp0v\r\n" + "-----END X509 CRL-----\r\n"; public static String CRL_2 = "-----BEGIN CRL-----\r\n" + "MIICjTCCAfowDQYJKoZIhvcNAQECBQAwXzELMAkGA1UEBhMCVVMxIDAeBgNVBAoT\r\n" + "F1JTQSBEYXRhIFNlY3VyaXR5LCBJbmMuMS4wLAYDVQQLEyVTZWN1cmUgU2VydmVy\r\n" + "IENlcnRpZmljYXRpb24gQXV0aG9yaXR5Fw05NTA1MDIwMjEyMjZaFw05NTA2MDEw\r\n" + "MDAxNDlaMIIBaDAWAgUCQQAABBcNOTUwMjAxMTcyNDI2WjAWAgUCQQAACRcNOTUw\r\n" + "MjEwMDIxNjM5WjAWAgUCQQAADxcNOTUwMjI0MDAxMjQ5WjAWAgUCQQAADBcNOTUw\r\n" + "MjI1MDA0NjQ0WjAWAgUCQQAAGxcNOTUwMzEzMTg0MDQ5WjAWAgUCQQAAFhcNOTUw\r\n" + "MzE1MTkxNjU0WjAWAgUCQQAAGhcNOTUwMzE1MTk0MDQxWjAWAgUCQQAAHxcNOTUw\r\n" + "MzI0MTk0NDMzWjAWAgUCcgAABRcNOTUwMzI5MjAwNzExWjAWAgUCcgAAERcNOTUw\r\n" + "MzMwMDIzNDI2WjAWAgUCQQAAIBcNOTUwNDA3MDExMzIxWjAWAgUCcgAAHhcNOTUw\r\n" + "NDA4MDAwMjU5WjAWAgUCcgAAQRcNOTUwNDI4MTcxNzI0WjAWAgUCcgAAOBcNOTUw\r\n" + "NDI4MTcyNzIxWjAWAgUCcgAATBcNOTUwNTAyMDIxMjI2WjANBgkqhkiG9w0BAQIF\r\n" + "AAN+AHqOEJXSDejYy0UwxxrH/9+N2z5xu/if0J6qQmK92W0hW158wpJg+ovV3+wQ\r\n" + "wvIEPRL2rocL0tKfAsVq1IawSJzSNgxG0lrcla3MrJBnZ4GaZDu4FutZh72MR3Gt\r\n" + "JaAL3iTJHJD55kK2D/VoyY1djlsPuNh6AEgdVwFAyp0v\r\n" + "-----END CRL-----\r\n"; static String ATTRIBUTE_CERTIFICATE_1 = "-----BEGIN X509 ATTRIBUTE CERTIFICATE-----\r\n" + "MIIBuDCCASECAQEwZ6BlMGCkXjBcMQswCQYDVQQGEwJBVTEoMCYGA1UEChMfVGhl\r\n" + "IExlZ2lvbiBvZiB0aGUgQm91bmN5IENhc3RsZTEjMCEGA1UECxMaQm91bmN5IFBy\r\n" + "aW1hcnkgQ2VydGlmaWNhdGUCARSgYjBgpF4wXDELMAkGA1UEBhMCQVUxKDAmBgNV\r\n" + "BAoTH1RoZSBMZWdpb24gb2YgdGhlIEJvdW5jeSBDYXN0bGUxIzAhBgNVBAsTGkJv\r\n" + "dW5jeSBQcmltYXJ5IENlcnRpZmljYXRlMA0GCSqGSIb3DQEBBQUAAgEBMCIYDzIw\r\n" + "MDUwNjEwMDI0MTMzWhgPMjAwNTA2MTAwMjQzMTNaMBkwFwYDVRhIMRAwDoEMREFV\r\n" + "MTIzNDU2Nzg5MA0GCSqGSIb3DQEBBQUAA4GBALAYXT9zdxSR5zdPLAon1xIPehgI\r\n" + "NZhjM7w0uu3OdzSV5sC31X1Kx9vi5RIWiM9VimRTwbQIod9POttD5QMXCwQb/fm7\r\n" + "eiJqL2YBIXOeClB19VrQe8xQtMFbyuFpDiM7QdvIam9ShZZMEMGjv9QHI64M4b0G\r\n" + "odUBlSsJwPPQjZSU\r\n" + "-----END X509 ATTRIBUTE CERTIFICATE-----\r\n"; static String ATTRIBUTE_CERTIFICATE_2 = "-----BEGIN ATTRIBUTE CERTIFICATE-----\r\n" + "MIIBuDCCASECAQEwZ6BlMGCkXjBcMQswCQYDVQQGEwJBVTEoMCYGA1UEChMfVGhl\r\n" + "IExlZ2lvbiBvZiB0aGUgQm91bmN5IENhc3RsZTEjMCEGA1UECxMaQm91bmN5IFBy\r\n" + "aW1hcnkgQ2VydGlmaWNhdGUCARSgYjBgpF4wXDELMAkGA1UEBhMCQVUxKDAmBgNV\r\n" + "BAoTH1RoZSBMZWdpb24gb2YgdGhlIEJvdW5jeSBDYXN0bGUxIzAhBgNVBAsTGkJv\r\n" + "dW5jeSBQcmltYXJ5IENlcnRpZmljYXRlMA0GCSqGSIb3DQEBBQUAAgEBMCIYDzIw\r\n" + "MDUwNjEwMDI0MTMzWhgPMjAwNTA2MTAwMjQzMTNaMBkwFwYDVRhIMRAwDoEMREFV\r\n" + "MTIzNDU2Nzg5MA0GCSqGSIb3DQEBBQUAA4GBALAYXT9zdxSR5zdPLAon1xIPehgI\r\n" + "NZhjM7w0uu3OdzSV5sC31X1Kx9vi5RIWiM9VimRTwbQIod9POttD5QMXCwQb/fm7\r\n" + "eiJqL2YBIXOeClB19VrQe8xQtMFbyuFpDiM7QdvIam9ShZZMEMGjv9QHI64M4b0G\r\n" + "odUBlSsJwPPQjZSU\r\n" + "-----END ATTRIBUTE CERTIFICATE-----\r\n"; } bouncycastle-1.49.orig/test/src/org/bouncycastle/jce/provider/test/JceTestUtil.java0000644000175000017500000000247512146276065030116 0ustar ebourgebourgpackage org.bouncycastle.jce.provider.test; import java.security.Security; import java.util.ArrayList; import java.util.Enumeration; import java.util.List; import org.bouncycastle.jce.provider.BouncyCastleProvider; abstract class JceTestUtil { private JceTestUtil() { } static String[] getRegisteredAlgorithms(String prefix, String[] exclusionPatterns) { final BouncyCastleProvider prov = (BouncyCastleProvider)Security.getProvider("BC"); List matches = new ArrayList(); Enumeration algos = prov.keys(); while (algos.hasMoreElements()) { String algo = (String)algos.nextElement(); if (!algo.startsWith(prefix)) { continue; } String algoName = algo.substring(prefix.length()); if (!isExcluded(algoName, exclusionPatterns)) { matches.add(algoName); } } return (String[])matches.toArray(new String[matches.size()]); } private static boolean isExcluded(String algoName, String[] exclusionPatterns) { for (int i = 0; i < exclusionPatterns.length; i++) { if (algoName.contains(exclusionPatterns[i])) { return true; } } return false; } } bouncycastle-1.49.orig/test/src/org/bouncycastle/jce/provider/test/EncryptedPrivateKeyInfoTest.java0000644000175000017500000001075510330633061033316 0ustar ebourgebourgpackage org.bouncycastle.jce.provider.test; import java.security.AlgorithmParameters; import java.security.KeyPair; import java.security.KeyPairGenerator; import java.security.MessageDigest; import java.security.PrivateKey; import java.security.PublicKey; import java.security.SecureRandom; import java.security.Security; import java.security.spec.PKCS8EncodedKeySpec; import javax.crypto.Cipher; import javax.crypto.EncryptedPrivateKeyInfo; import javax.crypto.SecretKeyFactory; import javax.crypto.spec.PBEKeySpec; import javax.crypto.spec.PBEParameterSpec; import org.bouncycastle.jce.provider.BouncyCastleProvider; import org.bouncycastle.util.test.SimpleTestResult; import org.bouncycastle.util.test.Test; import org.bouncycastle.util.test.TestResult; public class EncryptedPrivateKeyInfoTest implements Test { String alg = "1.2.840.113549.1.12.1.3"; // 3 key triple DES with SHA-1 public TestResult perform() { try { KeyPairGenerator fact = KeyPairGenerator.getInstance("RSA", "BC"); fact.initialize(512, new SecureRandom()); KeyPair keyPair = fact.generateKeyPair(); PrivateKey priKey = keyPair.getPrivate(); PublicKey pubKey = keyPair.getPublic(); // // set up the parameters // byte[] salt = { 1, 2, 3, 4, 5, 6, 7, 8, 9, 10 }; int iterationCount = 100; PBEParameterSpec defParams = new PBEParameterSpec(salt, iterationCount); AlgorithmParameters params = AlgorithmParameters.getInstance(alg, "BC"); params.init(defParams); // // set up the key // char[] password1 = { 'h', 'e', 'l', 'l', 'o' }; PBEKeySpec pbeSpec = new PBEKeySpec(password1); SecretKeyFactory keyFact = SecretKeyFactory.getInstance(alg, "BC"); Cipher cipher = Cipher.getInstance(alg, "BC"); cipher.init(Cipher.WRAP_MODE, keyFact.generateSecret(pbeSpec), params); byte[] wrappedKey = cipher.wrap(priKey); // // create encrypted object // EncryptedPrivateKeyInfo pInfo = new EncryptedPrivateKeyInfo(params, wrappedKey); // // decryption step // char[] password2 = { 'h', 'e', 'l', 'l', 'o' }; pbeSpec = new PBEKeySpec(password2); cipher = Cipher.getInstance(pInfo.getAlgName(), "BC"); cipher.init(Cipher.DECRYPT_MODE, keyFact.generateSecret(pbeSpec), pInfo.getAlgParameters()); PKCS8EncodedKeySpec keySpec = pInfo.getKeySpec(cipher); if (!MessageDigest.isEqual(priKey.getEncoded(), keySpec.getEncoded())) { return new SimpleTestResult(false, "Private key does not match"); } // // using Cipher parameters test // pbeSpec = new PBEKeySpec(password1); keyFact = SecretKeyFactory.getInstance(alg, "BC"); cipher = Cipher.getInstance(alg, "BC"); cipher.init(Cipher.WRAP_MODE, keyFact.generateSecret(pbeSpec), params); wrappedKey = cipher.wrap(priKey); // // create encrypted object // pInfo = new EncryptedPrivateKeyInfo(cipher.getParameters(), wrappedKey); // // decryption step // pbeSpec = new PBEKeySpec(password2); cipher = Cipher.getInstance(pInfo.getAlgName(), "BC"); cipher.init(Cipher.DECRYPT_MODE, keyFact.generateSecret(pbeSpec), pInfo.getAlgParameters()); keySpec = pInfo.getKeySpec(cipher); if (!MessageDigest.isEqual(priKey.getEncoded(), keySpec.getEncoded())) { return new SimpleTestResult(false, "Private key does not match"); } return new SimpleTestResult(true, getName() + ": Okay"); } catch (Exception e) { return new SimpleTestResult(false, getName() + ": exception - " + e.toString(), e); } } public String getName() { return "EncryptedPrivateKeyInfoTest"; } public static void main( String[] args) { Security.addProvider(new BouncyCastleProvider()); Test test = new EncryptedPrivateKeyInfoTest(); TestResult result = test.perform(); System.out.println(result.toString()); } } bouncycastle-1.49.orig/test/src/org/bouncycastle/jce/provider/test/MacTest.java0000644000175000017500000001214211550724442027242 0ustar ebourgebourgpackage org.bouncycastle.jce.provider.test; import java.security.Security; import javax.crypto.Mac; import javax.crypto.SecretKey; import javax.crypto.spec.IvParameterSpec; import javax.crypto.spec.SecretKeySpec; import org.bouncycastle.jce.provider.BouncyCastleProvider; import org.bouncycastle.util.encoders.Hex; import org.bouncycastle.util.test.SimpleTest; /** * MAC tester - vectors from * FIP 81 and * FIP 113. */ public class MacTest extends SimpleTest { static byte[] keyBytes = Hex.decode("0123456789abcdef"); static byte[] ivBytes = Hex.decode("1234567890abcdef"); static byte[] input = Hex.decode("37363534333231204e6f77206973207468652074696d6520666f7220"); static byte[] output1 = Hex.decode("f1d30f68"); static byte[] output2 = Hex.decode("58d2e77e"); static byte[] output3 = Hex.decode("cd647403"); static byte[] keyBytesISO9797 = Hex.decode("7CA110454A1A6E570131D9619DC1376E"); static byte[] inputISO9797 = "Hello World !!!!".getBytes(); static byte[] outputISO9797 = Hex.decode("F09B856213BAB83B"); static byte[] inputDesEDE64 = "Hello World !!!!".getBytes(); static byte[] outputDesEDE64 = Hex.decode("862304d33af01096"); public MacTest() { } private void aliasTest(SecretKey key, String primary, String[] aliases) throws Exception { Mac mac = Mac.getInstance(primary, "BC"); // // standard DAC - zero IV // mac.init(key); mac.update(input, 0, input.length); byte[] ref = mac.doFinal(); for (int i = 0; i != aliases.length; i++) { mac = Mac.getInstance(aliases[i], "BC"); mac.init(key); mac.update(input, 0, input.length); byte[] out = mac.doFinal(); if (!areEqual(out, ref)) { fail("Failed - expected " + new String(Hex.encode(ref)) + " got " + new String(Hex.encode(out))); } } } public void performTest() throws Exception { SecretKey key = new SecretKeySpec(keyBytes, "DES"); byte[] out; Mac mac; mac = Mac.getInstance("DESMac", "BC"); // // standard DAC - zero IV // mac.init(key); mac.update(input, 0, input.length); out = mac.doFinal(); if (!areEqual(out, output1)) { fail("Failed - expected " + new String(Hex.encode(output1)) + " got " + new String(Hex.encode(out))); } // // mac with IV. // mac.init(key, new IvParameterSpec(ivBytes)); mac.update(input, 0, input.length); out = mac.doFinal(); if (!areEqual(out, output2)) { fail("Failed - expected " + new String(Hex.encode(output2)) + " got " + new String(Hex.encode(out))); } // // CFB mac with IV - 8 bit CFB mode // mac = Mac.getInstance("DESMac/CFB8", "BC"); mac.init(key, new IvParameterSpec(ivBytes)); mac.update(input, 0, input.length); out = mac.doFinal(); if (!areEqual(out, output3)) { fail("Failed - expected " + new String(Hex.encode(output3)) + " got " + new String(Hex.encode(out))); } // // ISO9797 algorithm 3 using DESEDE // key = new SecretKeySpec(keyBytesISO9797, "DESEDE"); mac = Mac.getInstance("ISO9797ALG3", "BC"); mac.init(key); mac.update(inputISO9797, 0, inputISO9797.length); out = mac.doFinal(); if (!areEqual(out, outputISO9797)) { fail("Failed - expected " + new String(Hex.encode(outputISO9797)) + " got " + new String(Hex.encode(out))); } // // 64bit DESede Mac // key = new SecretKeySpec(keyBytesISO9797, "DESEDE"); mac = Mac.getInstance("DESEDE64", "BC"); mac.init(key); mac.update(inputDesEDE64, 0, inputDesEDE64.length); out = mac.doFinal(); if (!areEqual(out, outputDesEDE64)) { fail("Failed - expected " + new String(Hex.encode(outputDesEDE64)) + " got " + new String(Hex.encode(out))); } aliasTest(new SecretKeySpec(keyBytesISO9797, "DESede"), "DESedeMac64withISO7816-4Padding", new String[] { "DESEDE64WITHISO7816-4PADDING", "DESEDEISO9797ALG1MACWITHISO7816-4PADDING", "DESEDEISO9797ALG1WITHISO7816-4PADDING" }); aliasTest(new SecretKeySpec(keyBytesISO9797, "DESede"), "ISO9797ALG3WITHISO7816-4PADDING", new String[] { "ISO9797ALG3MACWITHISO7816-4PADDING" }); aliasTest(new SecretKeySpec(keyBytes, "DES"), "DES64", new String[] { "DESMAC64" }); } public String getName() { return "Mac"; } public static void main( String[] args) { Security.addProvider(new BouncyCastleProvider()); runTest(new MacTest()); } } bouncycastle-1.49.orig/test/src/org/bouncycastle/jce/provider/test/PKIXTest.java0000644000175000017500000003141410330633061027307 0ustar ebourgebourg package org.bouncycastle.jce.provider.test; import java.io.ByteArrayInputStream; import java.security.Security; import java.security.cert.CertificateFactory; import java.security.cert.X509CRL; import java.security.cert.X509Certificate; import org.bouncycastle.jce.provider.BouncyCastleProvider; import org.bouncycastle.util.encoders.Hex; import org.bouncycastle.util.test.SimpleTestResult; import org.bouncycastle.util.test.Test; import org.bouncycastle.util.test.TestResult; public class PKIXTest implements Test { /* * The following certs and crls are described in: * http://www.ietf.org/internet-drafts/draft-ietf-pkix-new-part1-08.txt * * This section contains four examples: three certificates and a CRL. * The first two certificates and the CRL comprise a minimal * certification path. * * Section C.1 contains an annotated hex dump of a "self-signed" * certificate issued by a CA whose distinguished name is * cn=us,o=gov,ou=nist. The certificate contains a DSA public key with * parameters, and is signed by the corresponding DSA private key. * * Section C.2 contains an annotated hex dump of an end entity * certificate. The end entity certificate contains a DSA public key, * and is signed by the private key corresponding to the "self-signed" * certificate in section C.1. * * Section C.3 contains a dump of an end entity certificate which * contains an RSA public key and is signed with RSA and MD5. This * certificate is not part of the minimal certification path. * * Section C.4 contains an annotated hex dump of a CRL. The CRL is * issued by the CA whose distinguished name is cn=us,o=gov,ou=nist and * the list of revoked certificates includes the end entity certificate * presented in C.2. */ /** * C.1 Certificate * * This section contains an annotated hex dump of a 699 byte version 3 * certificate. The certificate contains the following information: * (a) the serial number is 23 (17 hex); * (b) the certificate is signed with DSA and the SHA-1 hash algorithm; * (c) the issuer's distinguished name is OU=NIST; O=gov; C=US * (d) and the subject's distinguished name is OU=NIST; O=gov; C=US * (e) the certificate was issued on June 30, 1997 and will expire on * December 31, 1997; * (f) the certificate contains a 1024 bit DSA public key with * parameters; * (g) the certificate contains a subject key identifier extension * generated using method (1) of section 4.2.1.2; and * (h) the certificate is a CA certificate (as indicated through the * basic constraints extension.) */ static byte[] rootCertBin = Hex.decode( "308202bb3082027ba003020102020111300906072a8648ce380403302a310b30" + "09060355040613025553310c300a060355040a1303676f76310d300b06035504" + "0b13044e495354301e170d3937303633303030303030305a170d393731323331" + "3030303030305a302a310b3009060355040613025553310c300a060355040a13" + "03676f76310d300b060355040b13044e495354308201b83082012c06072a8648" + "ce3804013082011f02818100b68b0f942b9acea525c6f2edfcfb9532ac011233" + "b9e01cad909bbc48549ef394773c2c713555e6fe4f22cbd5d83e8993334dfcbd" + "4f41643ea29870ec31b450deebf198280ac93e44b3fd22979683d018a3e3bd35" + "5bffeea321726a7b96dab93f1e5a90af24d620f00d21a7d402b91afcac21fb9e" + "949e4b42459e6ab24863fe43021500b20db0b101df0c6624fc1392ba55f77d57" + "7481e5028181009abf46b1f53f443dc9a565fb91c08e47f10ac30147c2444236" + "a99281de57c5e0688658007b1ff99b77a1c510a580917851513cf6fcfccc46c6" + "817892843df4933d0c387e1a5b994eab1464f60c21224e28089c92b9669f40e8" + "95f6d5312aef39a262c7b26d9e58c43aa81181846daff8b419b4c211aed0223b" + "aa207fee1e57180381850002818100b59e1f490447d1dbf53addca0475e8dd75" + "f69b8ab197d6596982d3034dfd3b365f4af2d14ec107f5d12ad378776356ea96" + "614d420b7a1dfbab91a4cedeef77c8e5ef20aea62848afbe69c36aa530f2c2b9" + "d9822b7dd9c4841fde0de854d71b992eb3d088f6d6639ba7e20e82d43b8a681b" + "065631590b49eb99a5d581417bc955a3323030301d0603551d0e0416041486ca" + "a5228162efad0a89bcad72412c2949f48656300f0603551d130101ff04053003" + "0101ff300906072a8648ce380403032f00302c0214431bcf292545c04e52e77d" + "d6fcb1664c83cf2d7702140b5b9a241198e8f3869004f608a9e18da5cc3ad4"); /** * C.2 Certificate * * This section contains an annotated hex dump of a 730 byte version 3 * certificate. The certificate contains the following information: * (a the serial number is 18 (12 hex); * (b) the certificate is signed with DSA and the SHA-1 hash algorithm; * (c) the issuer's distinguished name is OU=nist; O=gov; C=US * (d) and the subject's distinguished name is CN=Tim Polk; OU=nist; * O=gov; C=US * (e) the certificate was valid from July 30, 1997 through December 1, * 1997; * (f) the certificate contains a 1024 bit DSA public key; * (g) the certificate is an end entity certificate, as the basic * constraints extension is not present; * (h) the certificate contains an authority key identifier extension * matching the subject key identifier of the certificate in Appendix * C.1; and * (i) the certificate includes one alternative name - an RFC 822 * address of "wpolk@nist.gov". */ static byte[] userCert1Bin = Hex.decode( "308202da30820299a003020102020112300906072a8648ce380403302a310b30" + "09060355040613025553310c300a060355040a1303676f76310d300b06035504" + "0b13044e495354301e170d3937303733303030303030305a170d393731323031" + "3030303030305a303d310b3009060355040613025553310c300a060355040a13" + "03676f76310d300b060355040b13044e4953543111300f060355040313085469" + "6d20506f6c6b308201b73082012c06072a8648ce3804013082011f02818100b6" + "8b0f942b9acea525c6f2edfcfb9532ac011233b9e01cad909bbc48549ef39477" + "3c2c713555e6fe4f22cbd5d83e8993334dfcbd4f41643ea29870ec31b450deeb" + "f198280ac93e44b3fd22979683d018a3e3bd355bffeea321726a7b96dab93f1e" + "5a90af24d620f00d21a7d402b91afcac21fb9e949e4b42459e6ab24863fe4302" + "1500b20db0b101df0c6624fc1392ba55f77d577481e5028181009abf46b1f53f" + "443dc9a565fb91c08e47f10ac30147c2444236a99281de57c5e0688658007b1f" + "f99b77a1c510a580917851513cf6fcfccc46c6817892843df4933d0c387e1a5b" + "994eab1464f60c21224e28089c92b9669f40e895f6d5312aef39a262c7b26d9e" + "58c43aa81181846daff8b419b4c211aed0223baa207fee1e5718038184000281" + "8030b675f77c2031ae38bb7e0d2baba09c4bdf20d524133ccd98e55f6cb7c1ba" + "4abaa9958053f00d72dc3337f4010bf5041f9d2e1f62d8843a9b25095a2dc846" + "8e2bd4f50d3bc72dc66cb998c1253a444e8eca9561357cce15315c23131ea205" + "d17a241ccbd3720990ff9b9d28c0a10aec469f0db8d0dcd018a62b5ef98fb595" + "bea33e303c30190603551d1104123010810e77706f6c6b406e6973742e676f76" + "301f0603551d2304183016801486caa5228162efad0a89bcad72412c2949f486" + "56300906072a8648ce380403033000302d02143697cbe3b42ce1bb61a9d3cc24" + "cc22929ff4f587021500abc979afd2161ca9e368a91410b4a02eff225a73"); /** * C.3 End Entity Certificate Using RSA * * This section contains an annotated hex dump of a 654 byte version 3 * certificate. The certificate contains the following information: * (a) the serial number is 256; * (b) the certificate is signed with RSA and the SHA-1 hash algorithm; * (c) the issuer's distinguished name is OU=NIST; O=gov; C=US * (d) and the subject's distinguished name is CN=Tim Polk; OU=NIST; * O=gov; C=US * (e) the certificate was issued on May 21, 1996 at 09:58:26 and * expired on May 21, 1997 at 09:58:26; * (f) the certificate contains a 1024 bit RSA public key; * (g) the certificate is an end entity certificate (not a CA * certificate); * (h) the certificate includes an alternative subject name of * "" and an * alternative issuer name of "" - both are URLs; * (i) the certificate include an authority key identifier extension * and a certificate policies extension psecifying the policy OID * 2.16.840.1.101.3.2.1.48.9; and * (j) the certificate includes a critical key usage extension * specifying that the public key is intended for verification of * digital signatures. */ static byte[] userCert2Bin = Hex.decode( "3082028e308201f7a00302010202020100300d06092a864886f70d0101050500" + "302a310b3009060355040613025553310c300a060355040b1303676f76310d30" + "0b060355040a13044e495354301e170d3936303532313039353832365a170d39" + "37303532313039353832365a303d310b3009060355040613025553310c300a06" + "0355040b1303676f76310d300b060355040a13044e4953543111300f06035504" + "03130854696d20506f6c6b30819f300d06092a864886f70d010101050003818d" + "0030818902818100e16ae4033097023cf410f3b51e4d7f147bf6f5d078e9a48a" + "f0a375ecedb656967f8899859af23e687787eb9ed19fc0b417dcab8923a41d7e" + "16234c4fa84df531b87caae31a4909f44b26db2767308212014ae91ab6c10c53" + "8b6cfc2f7a43ec33367e32b27bd5aacf0114c612ec13f22d147a8b215814134c" + "46a39af21695ff230203010001a381af3081ac303f0603551d11043830368634" + "687474703a2f2f7777772e69746c2e6e6973742e676f762f6469763839332f73" + "746166662f706f6c6b2f696e6465782e68746d6c301f0603551d120418301686" + "14687474703a2f2f7777772e6e6973742e676f762f301f0603551d2304183016" + "80140868af8533c8394a7af882938e706a4a20842c3230170603551d20041030" + "0e300c060a60864801650302013009300e0603551d0f0101ff04040302078030" + "0d06092a864886f70d0101050500038181008e8e3656788bbfa13975172ee310" + "dc832b6834521cf66c1d525e5420105e4ca940f94b729e82b961dceb32a5bdb1" + "b148f99b01bbebaf9b83f6528cb06d7cd09a39543e6d206fcdd0debe275f204f" + "b6ab0df5b7e1bab4dfdf3dd4f6ed01fb6ecb9859ac41fb489c1ff65b46e029e2" + "76ecc43a0afc92c5c0d2a9c9d32952876533"); /** * This section contains an annotated hex dump of a version 2 CRL with * one extension (cRLNumber). The CRL was issued by OU=NIST; O=gov; C=US * on August 7, 1997; the next scheduled issuance was September 7, 1997. * The CRL includes one revoked certificates: serial number 18 (12 hex), * which was revoked on July 31, 1997 due to keyCompromise. The CRL * itself is number 18, and it was signed with DSA and SHA-1. */ static byte[] crlBin = Hex.decode( "3081cb30818c020101300906072a8648ce380403302a310b3009060355040613025553310c300a060355040a1303676f76310d300b060355040b13044e495354170d3937303830373030303030305a170d3937303930373030303030305a30223020020112170d3937303733313030303030305a300c300a0603551d1504030a0101a00e300c300a0603551d14040302010c300906072a8648ce380403032f00302c0214224e9f43ba950634f2bb5e65dba68005c03a29470214591a57c982d7022114c3d40b321b9616b11f465a"); public TestResult perform() { try { CertificateFactory cf = CertificateFactory.getInstance("X.509", "BC"); X509Certificate rootCert = (X509Certificate)cf.generateCertificate(new ByteArrayInputStream(rootCertBin)); X509Certificate userCert1 = (X509Certificate)cf.generateCertificate(new ByteArrayInputStream(userCert1Bin)); X509Certificate userCert2 = (X509Certificate)cf.generateCertificate(new ByteArrayInputStream(userCert2Bin)); X509CRL crl = (X509CRL)cf.generateCRL(new ByteArrayInputStream(crlBin)); rootCert.verify(rootCert.getPublicKey(), "BC"); userCert1.verify(rootCert.getPublicKey(), "BC"); crl.verify(rootCert.getPublicKey(), "BC"); if (!crl.isRevoked(userCert1)) { return new SimpleTestResult(false, this.getName() + ": usercert1 not revoked."); } if (crl.isRevoked(userCert2)) { return new SimpleTestResult(false, this.getName() + ": usercert2 revoked."); } } catch (Exception e) { return new SimpleTestResult(false, this.getName() + ": exception - " + e.toString()); } return new SimpleTestResult(true, this.getName() + ": Okay"); } public String getName() { return "PKIX"; } public static void main( String[] args) { Security.addProvider(new BouncyCastleProvider()); Test test = new PKIXTest(); TestResult result = test.perform(); System.out.println(result.toString()); } } bouncycastle-1.49.orig/test/src/org/bouncycastle/jce/provider/test/RegressionTest.java0000644000175000017500000000517612146276065030700 0ustar ebourgebourgpackage org.bouncycastle.jce.provider.test; import java.security.Security; import org.bouncycastle.jce.provider.BouncyCastleProvider; import org.bouncycastle.util.test.Test; import org.bouncycastle.util.test.TestResult; public class RegressionTest { public static Test[] tests = { new FIPSDESTest(), new DESedeTest(), new AESTest(), new CamelliaTest(), new SEEDTest(), new AESSICTest(), new GOST28147Test(), new PBETest(), new BlockCipherTest(), new MacTest(), new HMacTest(), new SealedTest(), new RSATest(), new DHTest(), new DHIESTest(), new DSATest(), new ImplicitlyCaTest(), new ECNRTest(), new ECIESTest(), new ECDSA5Test(), new GOST3410Test(), new ElGamalTest(), new IESTest(), new SigTest(), new AttrCertTest(), new CertTest(), new PKCS10CertRequestTest(), new EncryptedPrivateKeyInfoTest(), new KeyStoreTest(), new PKCS12StoreTest(), new DigestTest(), new PSSTest(), new WrapTest(), new DoFinalTest(), new CipherStreamTest(), new NamedCurveTest(), new PKIXTest(), new NetscapeCertRequestTest(), new X509StoreTest(), new X509StreamParserTest(), new X509CertificatePairTest(), new CertPathTest(), new CertStoreTest(), new CertPathValidatorTest(), new CertPathBuilderTest(), new ECEncodingTest(), new AlgorithmParametersTest(), new NISTCertPathTest(), new PKIXPolicyMappingTest(), new SlotTwoTest(), new PKIXNameConstraintsTest(), new MultiCertStoreTest(), new NoekeonTest(), new AttrCertSelectorTest(), new SerialisationTest(), new SigNameTest(), new MQVTest(), new CMacTest(), new GMacTest(), new DSTU4145Test(), new CRL5Test(), new SipHashTest(), new SHA3Test() }; public static void main( String[] args) { Security.addProvider(new BouncyCastleProvider()); System.out.println("Testing " + Security.getProvider("BC").getInfo() + " version: " + Security.getProvider("BC").getVersion()); for (int i = 0; i != tests.length; i++) { TestResult result = tests[i].perform(); if (result.getException() != null) { result.getException().printStackTrace(); } System.out.println(result); } } } bouncycastle-1.49.orig/test/src/org/bouncycastle/jce/provider/test/CertTest.java0000644000175000017500000042746412151252353027453 0ustar ebourgebourgpackage org.bouncycastle.jce.provider.test; import java.io.ByteArrayInputStream; import java.io.IOException; import java.io.InputStream; import java.io.UnsupportedEncodingException; import java.math.BigInteger; import java.security.KeyFactory; import java.security.KeyPair; import java.security.KeyPairGenerator; import java.security.NoSuchAlgorithmException; import java.security.NoSuchProviderException; import java.security.PrivateKey; import java.security.PublicKey; import java.security.SecureRandom; import java.security.Security; import java.security.Signature; import java.security.cert.CRL; import java.security.cert.Certificate; import java.security.cert.CertificateException; import java.security.cert.CertificateFactory; import java.security.cert.CertificateParsingException; import java.security.cert.X509CRL; import java.security.cert.X509CRLEntry; import java.security.cert.X509Certificate; import java.security.spec.InvalidKeySpecException; import java.security.spec.RSAPrivateCrtKeySpec; import java.security.spec.RSAPublicKeySpec; import java.util.Collection; import java.util.Date; import java.util.Hashtable; import java.util.Iterator; import java.util.List; import java.util.Set; import java.util.Vector; import javax.security.auth.x500.X500Principal; import org.bouncycastle.asn1.ASN1Encodable; import org.bouncycastle.asn1.ASN1EncodableVector; import org.bouncycastle.asn1.ASN1InputStream; import org.bouncycastle.asn1.ASN1Primitive; import org.bouncycastle.asn1.DEREnumerated; import org.bouncycastle.asn1.DERObjectIdentifier; import org.bouncycastle.asn1.DEROctetString; import org.bouncycastle.asn1.DERSequence; import org.bouncycastle.asn1.DERSet; import org.bouncycastle.asn1.DERTaggedObject; import org.bouncycastle.asn1.cms.CMSObjectIdentifiers; import org.bouncycastle.asn1.cms.ContentInfo; import org.bouncycastle.asn1.cms.SignedData; import org.bouncycastle.asn1.x500.X500Name; import org.bouncycastle.asn1.x509.AlgorithmIdentifier; import org.bouncycastle.asn1.x509.AuthorityKeyIdentifier; import org.bouncycastle.asn1.x509.CRLReason; import org.bouncycastle.asn1.x509.Extension; import org.bouncycastle.asn1.x509.GeneralName; import org.bouncycastle.asn1.x509.GeneralNames; import org.bouncycastle.asn1.x509.KeyPurposeId; import org.bouncycastle.asn1.x509.X509CertificateStructure; import org.bouncycastle.asn1.x509.X509Extension; import org.bouncycastle.asn1.x509.X509Extensions; import org.bouncycastle.asn1.x9.X9ObjectIdentifiers; import org.bouncycastle.jce.X509KeyUsage; import org.bouncycastle.jce.X509Principal; import org.bouncycastle.jce.interfaces.ECPointEncoder; import org.bouncycastle.jce.provider.BouncyCastleProvider; import org.bouncycastle.jce.spec.ECParameterSpec; import org.bouncycastle.jce.spec.ECPrivateKeySpec; import org.bouncycastle.jce.spec.ECPublicKeySpec; import org.bouncycastle.jce.spec.GOST3410ParameterSpec; import org.bouncycastle.math.ec.ECCurve; import org.bouncycastle.util.Integers; import org.bouncycastle.util.encoders.Base64; import org.bouncycastle.util.encoders.Hex; import org.bouncycastle.util.io.Streams; import org.bouncycastle.util.test.SimpleTest; import org.bouncycastle.x509.X509V1CertificateGenerator; import org.bouncycastle.x509.X509V2CRLGenerator; import org.bouncycastle.x509.X509V3CertificateGenerator; import org.bouncycastle.x509.extension.AuthorityKeyIdentifierStructure; import org.bouncycastle.x509.extension.X509ExtensionUtil; public class CertTest extends SimpleTest { // // server.crt // byte[] cert1 = Base64.decode( "MIIDXjCCAsegAwIBAgIBBzANBgkqhkiG9w0BAQQFADCBtzELMAkGA1UEBhMCQVUx" + "ETAPBgNVBAgTCFZpY3RvcmlhMRgwFgYDVQQHEw9Tb3V0aCBNZWxib3VybmUxGjAY" + "BgNVBAoTEUNvbm5lY3QgNCBQdHkgTHRkMR4wHAYDVQQLExVDZXJ0aWZpY2F0ZSBB" + "dXRob3JpdHkxFTATBgNVBAMTDENvbm5lY3QgNCBDQTEoMCYGCSqGSIb3DQEJARYZ" + "d2VibWFzdGVyQGNvbm5lY3Q0LmNvbS5hdTAeFw0wMDA2MDIwNzU2MjFaFw0wMTA2" + "MDIwNzU2MjFaMIG4MQswCQYDVQQGEwJBVTERMA8GA1UECBMIVmljdG9yaWExGDAW" + "BgNVBAcTD1NvdXRoIE1lbGJvdXJuZTEaMBgGA1UEChMRQ29ubmVjdCA0IFB0eSBM" + "dGQxFzAVBgNVBAsTDldlYnNlcnZlciBUZWFtMR0wGwYDVQQDExR3d3cyLmNvbm5l" + "Y3Q0LmNvbS5hdTEoMCYGCSqGSIb3DQEJARYZd2VibWFzdGVyQGNvbm5lY3Q0LmNv" + "bS5hdTCBnzANBgkqhkiG9w0BAQEFAAOBjQAwgYkCgYEArvDxclKAhyv7Q/Wmr2re" + "Gw4XL9Cnh9e+6VgWy2AWNy/MVeXdlxzd7QAuc1eOWQkGQEiLPy5XQtTY+sBUJ3AO" + "Rvd2fEVJIcjf29ey7bYua9J/vz5MG2KYo9/WCHIwqD9mmG9g0xLcfwq/s8ZJBswE" + "7sb85VU+h94PTvsWOsWuKaECAwEAAaN3MHUwJAYDVR0RBB0wG4EZd2VibWFzdGVy" + "QGNvbm5lY3Q0LmNvbS5hdTA6BglghkgBhvhCAQ0ELRYrbW9kX3NzbCBnZW5lcmF0" + "ZWQgY3VzdG9tIHNlcnZlciBjZXJ0aWZpY2F0ZTARBglghkgBhvhCAQEEBAMCBkAw" + "DQYJKoZIhvcNAQEEBQADgYEAotccfKpwSsIxM1Hae8DR7M/Rw8dg/RqOWx45HNVL" + "iBS4/3N/TO195yeQKbfmzbAA2jbPVvIvGgTxPgO1MP4ZgvgRhasaa0qCJCkWvpM4" + "yQf33vOiYQbpv4rTwzU8AmRlBG45WdjyNIigGV+oRc61aKCTnLq7zB8N3z1TF/bF" + "5/8="); // // ca.crt // byte[] cert2 = Base64.decode( "MIIDbDCCAtWgAwIBAgIBADANBgkqhkiG9w0BAQQFADCBtzELMAkGA1UEBhMCQVUx" + "ETAPBgNVBAgTCFZpY3RvcmlhMRgwFgYDVQQHEw9Tb3V0aCBNZWxib3VybmUxGjAY" + "BgNVBAoTEUNvbm5lY3QgNCBQdHkgTHRkMR4wHAYDVQQLExVDZXJ0aWZpY2F0ZSBB" + "dXRob3JpdHkxFTATBgNVBAMTDENvbm5lY3QgNCBDQTEoMCYGCSqGSIb3DQEJARYZ" + "d2VibWFzdGVyQGNvbm5lY3Q0LmNvbS5hdTAeFw0wMDA2MDIwNzU1MzNaFw0wMTA2" + "MDIwNzU1MzNaMIG3MQswCQYDVQQGEwJBVTERMA8GA1UECBMIVmljdG9yaWExGDAW" + "BgNVBAcTD1NvdXRoIE1lbGJvdXJuZTEaMBgGA1UEChMRQ29ubmVjdCA0IFB0eSBM" + "dGQxHjAcBgNVBAsTFUNlcnRpZmljYXRlIEF1dGhvcml0eTEVMBMGA1UEAxMMQ29u" + "bmVjdCA0IENBMSgwJgYJKoZIhvcNAQkBFhl3ZWJtYXN0ZXJAY29ubmVjdDQuY29t" + "LmF1MIGfMA0GCSqGSIb3DQEBAQUAA4GNADCBiQKBgQDgs5ptNG6Qv1ZpCDuUNGmv" + "rhjqMDPd3ri8JzZNRiiFlBA4e6/ReaO1U8ASewDeQMH6i9R6degFdQRLngbuJP0s" + "xcEE+SksEWNvygfzLwV9J/q+TQDyJYK52utb++lS0b48A1KPLwEsyL6kOAgelbur" + "ukwxowprKUIV7Knf1ajetQIDAQABo4GFMIGCMCQGA1UdEQQdMBuBGXdlYm1hc3Rl" + "ckBjb25uZWN0NC5jb20uYXUwDwYDVR0TBAgwBgEB/wIBADA2BglghkgBhvhCAQ0E" + "KRYnbW9kX3NzbCBnZW5lcmF0ZWQgY3VzdG9tIENBIGNlcnRpZmljYXRlMBEGCWCG" + "SAGG+EIBAQQEAwICBDANBgkqhkiG9w0BAQQFAAOBgQCsGvfdghH8pPhlwm1r3pQk" + "msnLAVIBb01EhbXm2861iXZfWqGQjrGAaA0ZpXNk9oo110yxoqEoSJSzniZa7Xtz" + "soTwNUpE0SLHvWf/SlKdFWlzXA+vOZbzEv4UmjeelekTm7lc01EEa5QRVzOxHFtQ" + "DhkaJ8VqOMajkQFma2r9iA=="); // // testx509.pem // byte[] cert3 = Base64.decode( "MIIBWzCCAQYCARgwDQYJKoZIhvcNAQEEBQAwODELMAkGA1UEBhMCQVUxDDAKBgNV" + "BAgTA1FMRDEbMBkGA1UEAxMSU1NMZWF5L3JzYSB0ZXN0IENBMB4XDTk1MDYxOTIz" + "MzMxMloXDTk1MDcxNzIzMzMxMlowOjELMAkGA1UEBhMCQVUxDDAKBgNVBAgTA1FM" + "RDEdMBsGA1UEAxMUU1NMZWF5L3JzYSB0ZXN0IGNlcnQwXDANBgkqhkiG9w0BAQEF" + "AANLADBIAkEAqtt6qS5GTxVxGZYWa0/4u+IwHf7p2LNZbcPBp9/OfIcYAXBQn8hO" + "/Re1uwLKXdCjIoaGs4DLdG88rkzfyK5dPQIDAQABMAwGCCqGSIb3DQIFBQADQQAE" + "Wc7EcF8po2/ZO6kNCwK/ICH6DobgLekA5lSLr5EvuioZniZp5lFzAw4+YzPQ7XKJ" + "zl9HYIMxATFyqSiD9jsx"); // // v3-cert1.pem // byte[] cert4 = Base64.decode( "MIICjTCCAfigAwIBAgIEMaYgRzALBgkqhkiG9w0BAQQwRTELMAkGA1UEBhMCVVMx" + "NjA0BgNVBAoTLU5hdGlvbmFsIEFlcm9uYXV0aWNzIGFuZCBTcGFjZSBBZG1pbmlz" + "dHJhdGlvbjAmFxE5NjA1MjgxMzQ5MDUrMDgwMBcROTgwNTI4MTM0OTA1KzA4MDAw" + "ZzELMAkGA1UEBhMCVVMxNjA0BgNVBAoTLU5hdGlvbmFsIEFlcm9uYXV0aWNzIGFu" + "ZCBTcGFjZSBBZG1pbmlzdHJhdGlvbjEgMAkGA1UEBRMCMTYwEwYDVQQDEwxTdGV2" + "ZSBTY2hvY2gwWDALBgkqhkiG9w0BAQEDSQAwRgJBALrAwyYdgxmzNP/ts0Uyf6Bp" + "miJYktU/w4NG67ULaN4B5CnEz7k57s9o3YY3LecETgQ5iQHmkwlYDTL2fTgVfw0C" + "AQOjgaswgagwZAYDVR0ZAQH/BFowWDBWMFQxCzAJBgNVBAYTAlVTMTYwNAYDVQQK" + "Ey1OYXRpb25hbCBBZXJvbmF1dGljcyBhbmQgU3BhY2UgQWRtaW5pc3RyYXRpb24x" + "DTALBgNVBAMTBENSTDEwFwYDVR0BAQH/BA0wC4AJODMyOTcwODEwMBgGA1UdAgQR" + "MA8ECTgzMjk3MDgyM4ACBSAwDQYDVR0KBAYwBAMCBkAwCwYJKoZIhvcNAQEEA4GB" + "AH2y1VCEw/A4zaXzSYZJTTUi3uawbbFiS2yxHvgf28+8Js0OHXk1H1w2d6qOHH21" + "X82tZXd/0JtG0g1T9usFFBDvYK8O0ebgz/P5ELJnBL2+atObEuJy1ZZ0pBDWINR3" + "WkDNLCGiTkCKp0F5EWIrVDwh54NNevkCQRZita+z4IBO"); // // v3-cert2.pem // byte[] cert5 = Base64.decode( "MIICiTCCAfKgAwIBAgIEMeZfHzANBgkqhkiG9w0BAQQFADB9MQswCQYDVQQGEwJD" + "YTEPMA0GA1UEBxMGTmVwZWFuMR4wHAYDVQQLExVObyBMaWFiaWxpdHkgQWNjZXB0" + "ZWQxHzAdBgNVBAoTFkZvciBEZW1vIFB1cnBvc2VzIE9ubHkxHDAaBgNVBAMTE0Vu" + "dHJ1c3QgRGVtbyBXZWIgQ0EwHhcNOTYwNzEyMTQyMDE1WhcNOTYxMDEyMTQyMDE1" + "WjB0MSQwIgYJKoZIhvcNAQkBExVjb29rZUBpc3NsLmF0bC5ocC5jb20xCzAJBgNV" + "BAYTAlVTMScwJQYDVQQLEx5IZXdsZXR0IFBhY2thcmQgQ29tcGFueSAoSVNTTCkx" + "FjAUBgNVBAMTDVBhdWwgQS4gQ29va2UwXDANBgkqhkiG9w0BAQEFAANLADBIAkEA" + "6ceSq9a9AU6g+zBwaL/yVmW1/9EE8s5you1mgjHnj0wAILuoB3L6rm6jmFRy7QZT" + "G43IhVZdDua4e+5/n1ZslwIDAQABo2MwYTARBglghkgBhvhCAQEEBAMCB4AwTAYJ" + "YIZIAYb4QgENBD8WPVRoaXMgY2VydGlmaWNhdGUgaXMgb25seSBpbnRlbmRlZCBm" + "b3IgZGVtb25zdHJhdGlvbiBwdXJwb3Nlcy4wDQYJKoZIhvcNAQEEBQADgYEAi8qc" + "F3zfFqy1sV8NhjwLVwOKuSfhR/Z8mbIEUeSTlnH3QbYt3HWZQ+vXI8mvtZoBc2Fz" + "lexKeIkAZXCesqGbs6z6nCt16P6tmdfbZF3I3AWzLquPcOXjPf4HgstkyvVBn0Ap" + "jAFN418KF/Cx4qyHB4cjdvLrRjjQLnb2+ibo7QU="); // // pem encoded pkcs7 // byte[] cert6 = Base64.decode( "MIAGCSqGSIb3DQEHAqCAMIACAQExCzAJBgUrDgMCGgUAMIAGCSqGSIb3DQEHAQAAoIIJbzCCAj0w" + "ggGmAhEAzbp/VvDf5LxU/iKss3KqVTANBgkqhkiG9w0BAQIFADBfMQswCQYDVQQGEwJVUzEXMBUG" + "A1UEChMOVmVyaVNpZ24sIEluYy4xNzA1BgNVBAsTLkNsYXNzIDEgUHVibGljIFByaW1hcnkgQ2Vy" + "dGlmaWNhdGlvbiBBdXRob3JpdHkwHhcNOTYwMTI5MDAwMDAwWhcNMjgwODAxMjM1OTU5WjBfMQsw" + "CQYDVQQGEwJVUzEXMBUGA1UEChMOVmVyaVNpZ24sIEluYy4xNzA1BgNVBAsTLkNsYXNzIDEgUHVi" + "bGljIFByaW1hcnkgQ2VydGlmaWNhdGlvbiBBdXRob3JpdHkwgZ8wDQYJKoZIhvcNAQEBBQADgY0A" + "MIGJAoGBAOUZv22jVmEtmUhx9mfeuY3rt56GgAqRDvo4Ja9GiILlc6igmyRdDR/MZW4MsNBWhBiH" + "mgabEKFz37RYOWtuwfYV1aioP6oSBo0xrH+wNNePNGeICc0UEeJORVZpH3gCgNrcR5EpuzbJY1zF" + "4Ncth3uhtzKwezC6Ki8xqu6jZ9rbAgMBAAEwDQYJKoZIhvcNAQECBQADgYEATD+4i8Zo3+5DMw5d" + "6abLB4RNejP/khv0Nq3YlSI2aBFsfELM85wuxAc/FLAPT/+Qknb54rxK6Y/NoIAK98Up8YIiXbix" + "3YEjo3slFUYweRb46gVLlH8dwhzI47f0EEA8E8NfH1PoSOSGtHuhNbB7Jbq4046rPzidADQAmPPR" + "cZQwggMuMIICl6ADAgECAhEA0nYujRQMPX2yqCVdr+4NdTANBgkqhkiG9w0BAQIFADBfMQswCQYD" + "VQQGEwJVUzEXMBUGA1UEChMOVmVyaVNpZ24sIEluYy4xNzA1BgNVBAsTLkNsYXNzIDEgUHVibGlj" + "IFByaW1hcnkgQ2VydGlmaWNhdGlvbiBBdXRob3JpdHkwHhcNOTgwNTEyMDAwMDAwWhcNMDgwNTEy" + "MjM1OTU5WjCBzDEXMBUGA1UEChMOVmVyaVNpZ24sIEluYy4xHzAdBgNVBAsTFlZlcmlTaWduIFRy" + "dXN0IE5ldHdvcmsxRjBEBgNVBAsTPXd3dy52ZXJpc2lnbi5jb20vcmVwb3NpdG9yeS9SUEEgSW5j" + "b3JwLiBCeSBSZWYuLExJQUIuTFREKGMpOTgxSDBGBgNVBAMTP1ZlcmlTaWduIENsYXNzIDEgQ0Eg" + "SW5kaXZpZHVhbCBTdWJzY3JpYmVyLVBlcnNvbmEgTm90IFZhbGlkYXRlZDCBnzANBgkqhkiG9w0B" + "AQEFAAOBjQAwgYkCgYEAu1pEigQWu1X9A3qKLZRPFXg2uA1Ksm+cVL+86HcqnbnwaLuV2TFBcHqB" + "S7lIE1YtxwjhhEKrwKKSq0RcqkLwgg4C6S/7wju7vsknCl22sDZCM7VuVIhPh0q/Gdr5FegPh7Yc" + "48zGmo5/aiSS4/zgZbqnsX7vyds3ashKyAkG5JkCAwEAAaN8MHowEQYJYIZIAYb4QgEBBAQDAgEG" + "MEcGA1UdIARAMD4wPAYLYIZIAYb4RQEHAQEwLTArBggrBgEFBQcCARYfd3d3LnZlcmlzaWduLmNv" + "bS9yZXBvc2l0b3J5L1JQQTAPBgNVHRMECDAGAQH/AgEAMAsGA1UdDwQEAwIBBjANBgkqhkiG9w0B" + "AQIFAAOBgQCIuDc73dqUNwCtqp/hgQFxHpJqbS/28Z3TymQ43BuYDAeGW4UVag+5SYWklfEXfWe0" + "fy0s3ZpCnsM+tI6q5QsG3vJWKvozx74Z11NMw73I4xe1pElCY+zCphcPXVgaSTyQXFWjZSAA/Rgg" + "5V+CprGoksVYasGNAzzrw80FopCubjCCA/gwggNhoAMCAQICEBbbn/1G1zppD6KsP01bwywwDQYJ" + "KoZIhvcNAQEEBQAwgcwxFzAVBgNVBAoTDlZlcmlTaWduLCBJbmMuMR8wHQYDVQQLExZWZXJpU2ln" + "biBUcnVzdCBOZXR3b3JrMUYwRAYDVQQLEz13d3cudmVyaXNpZ24uY29tL3JlcG9zaXRvcnkvUlBB" + "IEluY29ycC4gQnkgUmVmLixMSUFCLkxURChjKTk4MUgwRgYDVQQDEz9WZXJpU2lnbiBDbGFzcyAx" + "IENBIEluZGl2aWR1YWwgU3Vic2NyaWJlci1QZXJzb25hIE5vdCBWYWxpZGF0ZWQwHhcNMDAxMDAy" + "MDAwMDAwWhcNMDAxMjAxMjM1OTU5WjCCAQcxFzAVBgNVBAoTDlZlcmlTaWduLCBJbmMuMR8wHQYD" + "VQQLExZWZXJpU2lnbiBUcnVzdCBOZXR3b3JrMUYwRAYDVQQLEz13d3cudmVyaXNpZ24uY29tL3Jl" + "cG9zaXRvcnkvUlBBIEluY29ycC4gYnkgUmVmLixMSUFCLkxURChjKTk4MR4wHAYDVQQLExVQZXJz" + "b25hIE5vdCBWYWxpZGF0ZWQxJzAlBgNVBAsTHkRpZ2l0YWwgSUQgQ2xhc3MgMSAtIE1pY3Jvc29m" + "dDETMBEGA1UEAxQKRGF2aWQgUnlhbjElMCMGCSqGSIb3DQEJARYWZGF2aWRAbGl2ZW1lZGlhLmNv" + "bS5hdTCBnzANBgkqhkiG9w0BAQEFAAOBjQAwgYkCgYEAqxBsdeNmSvFqhMNwhQgNzM8mdjX9eSXb" + "DawpHtQHjmh0AKJSa3IwUY0VIsyZHuXWktO/CgaMBVPt6OVf/n0R2sQigMP6Y+PhEiS0vCJBL9aK" + "0+pOo2qXrjVBmq+XuCyPTnc+BOSrU26tJsX0P9BYorwySiEGxGanBNATdVL4NdUCAwEAAaOBnDCB" + "mTAJBgNVHRMEAjAAMEQGA1UdIAQ9MDswOQYLYIZIAYb4RQEHAQgwKjAoBggrBgEFBQcCARYcaHR0" + "cHM6Ly93d3cudmVyaXNpZ24uY29tL3JwYTARBglghkgBhvhCAQEEBAMCB4AwMwYDVR0fBCwwKjAo" + "oCagJIYiaHR0cDovL2NybC52ZXJpc2lnbi5jb20vY2xhc3MxLmNybDANBgkqhkiG9w0BAQQFAAOB" + "gQBC8yIIdVGpFTf8/YiL14cMzcmL0nIRm4kGR3U59z7UtcXlfNXXJ8MyaeI/BnXwG/gD5OKYqW6R" + "yca9vZOxf1uoTBl82gInk865ED3Tej6msCqFzZffnSUQvOIeqLxxDlqYRQ6PmW2nAnZeyjcnbI5Y" + "syQSM2fmo7n6qJFP+GbFezGCAkUwggJBAgEBMIHhMIHMMRcwFQYDVQQKEw5WZXJpU2lnbiwgSW5j" + "LjEfMB0GA1UECxMWVmVyaVNpZ24gVHJ1c3QgTmV0d29yazFGMEQGA1UECxM9d3d3LnZlcmlzaWdu" + "LmNvbS9yZXBvc2l0b3J5L1JQQSBJbmNvcnAuIEJ5IFJlZi4sTElBQi5MVEQoYyk5ODFIMEYGA1UE" + "AxM/VmVyaVNpZ24gQ2xhc3MgMSBDQSBJbmRpdmlkdWFsIFN1YnNjcmliZXItUGVyc29uYSBOb3Qg" + "VmFsaWRhdGVkAhAW25/9Rtc6aQ+irD9NW8MsMAkGBSsOAwIaBQCggbowGAYJKoZIhvcNAQkDMQsG" + "CSqGSIb3DQEHATAcBgkqhkiG9w0BCQUxDxcNMDAxMDAyMTczNTE4WjAjBgkqhkiG9w0BCQQxFgQU" + "gZjSaBEY2oxGvlQUIMnxSXhivK8wWwYJKoZIhvcNAQkPMU4wTDAKBggqhkiG9w0DBzAOBggqhkiG" + "9w0DAgICAIAwDQYIKoZIhvcNAwICAUAwBwYFKw4DAgcwDQYIKoZIhvcNAwICASgwBwYFKw4DAh0w" + "DQYJKoZIhvcNAQEBBQAEgYAzk+PU91/ZFfoiuKOECjxEh9fDYE2jfDCheBIgh5gdcCo+sS1WQs8O" + "HreQ9Nop/JdJv1DQMBK6weNBBDoP0EEkRm1XCC144XhXZC82jBZohYmi2WvDbbC//YN58kRMYMyy" + "srrfn4Z9I+6kTriGXkrpGk9Q0LSGjmG2BIsqiF0dvwAAAAAAAA=="); // // dsaWithSHA1 cert // byte[] cert7 = Base64.decode( "MIIEXAYJKoZIhvcNAQcCoIIETTCCBEkCAQExCzAJBgUrDgMCGgUAMAsGCSqG" + "SIb3DQEHAaCCAsMwggK/MIIB4AIBADCBpwYFKw4DAhswgZ0CQQEkJRHP+mN7" + "d8miwTMN55CUSmo3TO8WGCxgY61TX5k+7NU4XPf1TULjw3GobwaJX13kquPh" + "fVXk+gVy46n4Iw3hAhUBSe/QF4BUj+pJOF9ROBM4u+FEWA8CQQD4mSJbrABj" + "TUWrlnAte8pS22Tq4/FPO7jHSqjijUHfXKTrHL1OEqV3SVWcFy5j/cqBgX/z" + "m8Q12PFp/PjOhh+nMA4xDDAKBgNVBAMTA0lEMzAeFw05NzEwMDEwMDAwMDBa" + "Fw0zODAxMDEwMDAwMDBaMA4xDDAKBgNVBAMTA0lEMzCB8DCBpwYFKw4DAhsw" + "gZ0CQQEkJRHP+mN7d8miwTMN55CUSmo3TO8WGCxgY61TX5k+7NU4XPf1TULj" + "w3GobwaJX13kquPhfVXk+gVy46n4Iw3hAhUBSe/QF4BUj+pJOF9ROBM4u+FE" + "WA8CQQD4mSJbrABjTUWrlnAte8pS22Tq4/FPO7jHSqjijUHfXKTrHL1OEqV3" + "SVWcFy5j/cqBgX/zm8Q12PFp/PjOhh+nA0QAAkEAkYkXLYMtGVGWj9OnzjPn" + "sB9sefSRPrVegZJCZbpW+Iv0/1RP1u04pHG9vtRpIQLjzUiWvLMU9EKQTThc" + "eNMmWDCBpwYFKw4DAhswgZ0CQQEkJRHP+mN7d8miwTMN55CUSmo3TO8WGCxg" + "Y61TX5k+7NU4XPf1TULjw3GobwaJX13kquPhfVXk+gVy46n4Iw3hAhUBSe/Q" + "F4BUj+pJOF9ROBM4u+FEWA8CQQD4mSJbrABjTUWrlnAte8pS22Tq4/FPO7jH" + "SqjijUHfXKTrHL1OEqV3SVWcFy5j/cqBgX/zm8Q12PFp/PjOhh+nAy8AMCwC" + "FBY3dBSdeprGcqpr6wr3xbG+6WW+AhRMm/facKJNxkT3iKgJbp7R8Xd3QTGC" + "AWEwggFdAgEBMBMwDjEMMAoGA1UEAxMDSUQzAgEAMAkGBSsOAwIaBQCgXTAY" + "BgkqhkiG9w0BCQMxCwYJKoZIhvcNAQcBMBwGCSqGSIb3DQEJBTEPFw0wMjA1" + "MjQyMzEzMDdaMCMGCSqGSIb3DQEJBDEWBBS4WMsoJhf7CVbZYCFcjoTRzPkJ" + "xjCBpwYFKw4DAhswgZ0CQQEkJRHP+mN7d8miwTMN55CUSmo3TO8WGCxgY61T" + "X5k+7NU4XPf1TULjw3GobwaJX13kquPhfVXk+gVy46n4Iw3hAhUBSe/QF4BU" + "j+pJOF9ROBM4u+FEWA8CQQD4mSJbrABjTUWrlnAte8pS22Tq4/FPO7jHSqji" + "jUHfXKTrHL1OEqV3SVWcFy5j/cqBgX/zm8Q12PFp/PjOhh+nBC8wLQIVALID" + "dt+MHwawrDrwsO1Z6sXBaaJsAhRaKssrpevmLkbygKPV07XiAKBG02Zvb2Jh" + "cg=="); // // testcrl.pem // byte[] crl1 = Base64.decode( "MIICjTCCAfowDQYJKoZIhvcNAQECBQAwXzELMAkGA1UEBhMCVVMxIDAeBgNVBAoT" + "F1JTQSBEYXRhIFNlY3VyaXR5LCBJbmMuMS4wLAYDVQQLEyVTZWN1cmUgU2VydmVy" + "IENlcnRpZmljYXRpb24gQXV0aG9yaXR5Fw05NTA1MDIwMjEyMjZaFw05NTA2MDEw" + "MDAxNDlaMIIBaDAWAgUCQQAABBcNOTUwMjAxMTcyNDI2WjAWAgUCQQAACRcNOTUw" + "MjEwMDIxNjM5WjAWAgUCQQAADxcNOTUwMjI0MDAxMjQ5WjAWAgUCQQAADBcNOTUw" + "MjI1MDA0NjQ0WjAWAgUCQQAAGxcNOTUwMzEzMTg0MDQ5WjAWAgUCQQAAFhcNOTUw" + "MzE1MTkxNjU0WjAWAgUCQQAAGhcNOTUwMzE1MTk0MDQxWjAWAgUCQQAAHxcNOTUw" + "MzI0MTk0NDMzWjAWAgUCcgAABRcNOTUwMzI5MjAwNzExWjAWAgUCcgAAERcNOTUw" + "MzMwMDIzNDI2WjAWAgUCQQAAIBcNOTUwNDA3MDExMzIxWjAWAgUCcgAAHhcNOTUw" + "NDA4MDAwMjU5WjAWAgUCcgAAQRcNOTUwNDI4MTcxNzI0WjAWAgUCcgAAOBcNOTUw" + "NDI4MTcyNzIxWjAWAgUCcgAATBcNOTUwNTAyMDIxMjI2WjANBgkqhkiG9w0BAQIF" + "AAN+AHqOEJXSDejYy0UwxxrH/9+N2z5xu/if0J6qQmK92W0hW158wpJg+ovV3+wQ" + "wvIEPRL2rocL0tKfAsVq1IawSJzSNgxG0lrcla3MrJBnZ4GaZDu4FutZh72MR3Gt" + "JaAL3iTJHJD55kK2D/VoyY1djlsPuNh6AEgdVwFAyp0v"); // // ecdsa cert with extra octet string. // byte[] oldEcdsa = Base64.decode( "MIICljCCAkCgAwIBAgIBATALBgcqhkjOPQQBBQAwgY8xCzAJBgNVBAYTAkFVMSgwJ" + "gYDVQQKEx9UaGUgTGVnaW9uIG9mIHRoZSBCb3VuY3kgQ2FzdGxlMRIwEAYDVQQHEw" + "lNZWxib3VybmUxETAPBgNVBAgTCFZpY3RvcmlhMS8wLQYJKoZIhvcNAQkBFiBmZWV" + "kYmFjay1jcnlwdG9AYm91bmN5Y2FzdGxlLm9yZzAeFw0wMTEyMDcwMTAwMDRaFw0w" + "MTEyMDcwMTAxNDRaMIGPMQswCQYDVQQGEwJBVTEoMCYGA1UEChMfVGhlIExlZ2lvb" + "iBvZiB0aGUgQm91bmN5IENhc3RsZTESMBAGA1UEBxMJTWVsYm91cm5lMREwDwYDVQ" + "QIEwhWaWN0b3JpYTEvMC0GCSqGSIb3DQEJARYgZmVlZGJhY2stY3J5cHRvQGJvdW5" + "jeWNhc3RsZS5vcmcwgeQwgb0GByqGSM49AgEwgbECAQEwKQYHKoZIzj0BAQIef///" + "////////////f///////gAAAAAAAf///////MEAEHn///////////////3///////" + "4AAAAAAAH///////AQeawFsO9zxiUHQ1lSSFHXKcanbL7J9HTd5YYXClCwKBB8CD/" + "qWPNyogWzMM7hkK+35BcPTWFc9Pyf7vTs8uaqvAh5///////////////9///+eXpq" + "fXZBx+9FSJoiQnQsDIgAEHwJbbcU7xholSP+w9nFHLebJUhqdLSU05lq/y9X+DHAw" + "CwYHKoZIzj0EAQUAA0MAMEACHnz6t4UNoVROp74ma4XNDjjGcjaqiIWPZLK8Bdw3G" + "QIeLZ4j3a6ividZl344UH+UPUE7xJxlYGuy7ejTsqRR"); byte[] uncompressedPtEC = Base64.decode( "MIIDKzCCAsGgAwIBAgICA+kwCwYHKoZIzj0EAQUAMGYxCzAJBgNVBAYTAkpQ" + "MRUwEwYDVQQKEwxuaXRlY2guYWMuanAxDjAMBgNVBAsTBWFpbGFiMQ8wDQYD" + "VQQDEwZ0ZXN0Y2ExHzAdBgkqhkiG9w0BCQEWEHRlc3RjYUBsb2NhbGhvc3Qw" + "HhcNMDExMDEzMTE1MzE3WhcNMjAxMjEyMTE1MzE3WjBmMQswCQYDVQQGEwJK" + "UDEVMBMGA1UEChMMbml0ZWNoLmFjLmpwMQ4wDAYDVQQLEwVhaWxhYjEPMA0G" + "A1UEAxMGdGVzdGNhMR8wHQYJKoZIhvcNAQkBFhB0ZXN0Y2FAbG9jYWxob3N0" + "MIIBczCCARsGByqGSM49AgEwggEOAgEBMDMGByqGSM49AQECKEdYWnajFmnZ" + "tzrukK2XWdle2v+GsD9l1ZiR6g7ozQDbhFH/bBiMDQcwVAQoJ5EQKrI54/CT" + "xOQ2pMsd/fsXD+EX8YREd8bKHWiLz8lIVdD5cBNeVwQoMKSc6HfI7vKZp8Q2" + "zWgIFOarx1GQoWJbMcSt188xsl30ncJuJT2OoARRBAqJ4fD+q6hbqgNSjTQ7" + "htle1KO3eiaZgcJ8rrnyN8P+5A8+5K+H9aQ/NbBR4Gs7yto5PXIUZEUgodHA" + "TZMSAcSq5ZYt4KbnSYaLY0TtH9CqAigEwZ+hglbT21B7ZTzYX2xj0x+qooJD" + "hVTLtIPaYJK2HrMPxTw6/zfrAgEPA1IABAnvfFcFDgD/JicwBGn6vR3N8MIn" + "mptZf/mnJ1y649uCF60zOgdwIyI7pVSxBFsJ7ohqXEHW0x7LrGVkdSEiipiH" + "LYslqh3xrqbAgPbl93GUo0IwQDAPBgNVHRMBAf8EBTADAQH/MA4GA1UdDwEB" + "/wQEAwIBxjAdBgNVHQ4EFgQUAEo62Xm9H6DcsE0zUDTza4BRG90wCwYHKoZI" + "zj0EAQUAA1cAMFQCKAQsCHHSNOqfJXLgt3bg5+k49hIBGVr/bfG0B9JU3rNt" + "Ycl9Y2zfRPUCKAK2ccOQXByAWfsasDu8zKHxkZv7LVDTFjAIffz3HaCQeVhD" + "z+fauEg="); byte[] keyUsage = Base64.decode( "MIIE7TCCBFagAwIBAgIEOAOR7jANBgkqhkiG9w0BAQQFADCByTELMAkGA1UE" + "BhMCVVMxFDASBgNVBAoTC0VudHJ1c3QubmV0MUgwRgYDVQQLFD93d3cuZW50" + "cnVzdC5uZXQvQ2xpZW50X0NBX0luZm8vQ1BTIGluY29ycC4gYnkgcmVmLiBs" + "aW1pdHMgbGlhYi4xJTAjBgNVBAsTHChjKSAxOTk5IEVudHJ1c3QubmV0IExp" + "bWl0ZWQxMzAxBgNVBAMTKkVudHJ1c3QubmV0IENsaWVudCBDZXJ0aWZpY2F0" + "aW9uIEF1dGhvcml0eTAeFw05OTEwMTIxOTI0MzBaFw0xOTEwMTIxOTU0MzBa" + "MIHJMQswCQYDVQQGEwJVUzEUMBIGA1UEChMLRW50cnVzdC5uZXQxSDBGBgNV" + "BAsUP3d3dy5lbnRydXN0Lm5ldC9DbGllbnRfQ0FfSW5mby9DUFMgaW5jb3Jw" + "LiBieSByZWYuIGxpbWl0cyBsaWFiLjElMCMGA1UECxMcKGMpIDE5OTkgRW50" + "cnVzdC5uZXQgTGltaXRlZDEzMDEGA1UEAxMqRW50cnVzdC5uZXQgQ2xpZW50" + "IENlcnRpZmljYXRpb24gQXV0aG9yaXR5MIGdMA0GCSqGSIb3DQEBAQUAA4GL" + "ADCBhwKBgQDIOpleMRffrCdvkHvkGf9FozTC28GoT/Bo6oT9n3V5z8GKUZSv" + "x1cDR2SerYIbWtp/N3hHuzeYEpbOxhN979IMMFGpOZ5V+Pux5zDeg7K6PvHV" + "iTs7hbqqdCz+PzFur5GVbgbUB01LLFZHGARS2g4Qk79jkJvh34zmAqTmT173" + "iwIBA6OCAeAwggHcMBEGCWCGSAGG+EIBAQQEAwIABzCCASIGA1UdHwSCARkw" + "ggEVMIHkoIHhoIHepIHbMIHYMQswCQYDVQQGEwJVUzEUMBIGA1UEChMLRW50" + "cnVzdC5uZXQxSDBGBgNVBAsUP3d3dy5lbnRydXN0Lm5ldC9DbGllbnRfQ0Ff" + "SW5mby9DUFMgaW5jb3JwLiBieSByZWYuIGxpbWl0cyBsaWFiLjElMCMGA1UE" + "CxMcKGMpIDE5OTkgRW50cnVzdC5uZXQgTGltaXRlZDEzMDEGA1UEAxMqRW50" + "cnVzdC5uZXQgQ2xpZW50IENlcnRpZmljYXRpb24gQXV0aG9yaXR5MQ0wCwYD" + "VQQDEwRDUkwxMCygKqAohiZodHRwOi8vd3d3LmVudHJ1c3QubmV0L0NSTC9D" + "bGllbnQxLmNybDArBgNVHRAEJDAigA8xOTk5MTAxMjE5MjQzMFqBDzIwMTkx" + "MDEyMTkyNDMwWjALBgNVHQ8EBAMCAQYwHwYDVR0jBBgwFoAUxPucKXuXzUyW" + "/O5bs8qZdIuV6kwwHQYDVR0OBBYEFMT7nCl7l81MlvzuW7PKmXSLlepMMAwG" + "A1UdEwQFMAMBAf8wGQYJKoZIhvZ9B0EABAwwChsEVjQuMAMCBJAwDQYJKoZI" + "hvcNAQEEBQADgYEAP66K8ddmAwWePvrqHEa7pFuPeJoSSJn59DXeDDYHAmsQ" + "OokUgZwxpnyyQbJq5wcBoUv5nyU7lsqZwz6hURzzwy5E97BnRqqS5TvaHBkU" + "ODDV4qIxJS7x7EU47fgGWANzYrAQMY9Av2TgXD7FTx/aEkP/TOYGJqibGapE" + "PHayXOw="); byte[] nameCert = Base64.decode( "MIIEFjCCA3+gAwIBAgIEdS8BozANBgkqhkiG9w0BAQUFADBKMQswCQYDVQQGEwJE"+ "RTERMA8GA1UEChQIREFURVYgZUcxKDAMBgcCggYBCgcUEwExMBgGA1UEAxQRQ0Eg"+ "REFURVYgRDAzIDE6UE4wIhgPMjAwMTA1MTAxMDIyNDhaGA8yMDA0MDUwOTEwMjI0"+ "OFowgYQxCzAJBgNVBAYTAkRFMQ8wDQYDVQQIFAZCYXllcm4xEjAQBgNVBAcUCU7I"+ "dXJuYmVyZzERMA8GA1UEChQIREFURVYgZUcxHTAbBgNVBAUTFDAwMDAwMDAwMDA4"+ "OTU3NDM2MDAxMR4wHAYDVQQDFBVEaWV0bWFyIFNlbmdlbmxlaXRuZXIwgaEwDQYJ"+ "KoZIhvcNAQEBBQADgY8AMIGLAoGBAJLI/LJLKaHoMk8fBECW/od8u5erZi6jI8Ug"+ "C0a/LZyQUO/R20vWJs6GrClQtXB+AtfiBSnyZOSYzOdfDI8yEKPEv8qSuUPpOHps"+ "uNCFdLZF1vavVYGEEWs2+y+uuPmg8q1oPRyRmUZ+x9HrDvCXJraaDfTEd9olmB/Z"+ "AuC/PqpjAgUAwAAAAaOCAcYwggHCMAwGA1UdEwEB/wQCMAAwDwYDVR0PAQH/BAUD"+ "AwdAADAxBgNVHSAEKjAoMCYGBSskCAEBMB0wGwYIKwYBBQUHAgEWD3d3dy56cy5k"+ "YXRldi5kZTApBgNVHREEIjAggR5kaWV0bWFyLnNlbmdlbmxlaXRuZXJAZGF0ZXYu"+ "ZGUwgYQGA1UdIwR9MHuhc6RxMG8xCzAJBgNVBAYTAkRFMT0wOwYDVQQKFDRSZWd1"+ "bGllcnVuZ3NiZWjIb3JkZSBmyHVyIFRlbGVrb21tdW5pa2F0aW9uIHVuZCBQb3N0"+ "MSEwDAYHAoIGAQoHFBMBMTARBgNVBAMUCjVSLUNBIDE6UE6CBACm8LkwDgYHAoIG"+ "AQoMAAQDAQEAMEcGA1UdHwRAMD4wPKAUoBKGEHd3dy5jcmwuZGF0ZXYuZGWiJKQi"+ "MCAxCzAJBgNVBAYTAkRFMREwDwYDVQQKFAhEQVRFViBlRzAWBgUrJAgDBAQNMAsT"+ "A0VVUgIBBQIBATAdBgNVHQ4EFgQUfv6xFP0xk7027folhy+ziZvBJiwwLAYIKwYB"+ "BQUHAQEEIDAeMBwGCCsGAQUFBzABhhB3d3cuZGlyLmRhdGV2LmRlMA0GCSqGSIb3"+ "DQEBBQUAA4GBAEOVX6uQxbgtKzdgbTi6YLffMftFr2mmNwch7qzpM5gxcynzgVkg"+ "pnQcDNlm5AIbS6pO8jTCLfCd5TZ5biQksBErqmesIl3QD+VqtB+RNghxectZ3VEs"+ "nCUtcE7tJ8O14qwCb3TxS9dvIUFiVi4DjbxX46TdcTbTaK8/qr6AIf+l"); byte[] probSelfSignedCert = Base64.decode( "MIICxTCCAi6gAwIBAgIQAQAAAAAAAAAAAAAAAAAAATANBgkqhkiG9w0BAQUFADBF" + "MScwJQYDVQQKEx4gRElSRUNUSU9OIEdFTkVSQUxFIERFUyBJTVBPVFMxGjAYBgNV" + "BAMTESBBQyBNSU5FRkkgQiBURVNUMB4XDTA0MDUwNzEyMDAwMFoXDTE0MDUwNzEy" + "MDAwMFowRTEnMCUGA1UEChMeIERJUkVDVElPTiBHRU5FUkFMRSBERVMgSU1QT1RT" + "MRowGAYDVQQDExEgQUMgTUlORUZJIEIgVEVTVDCBnzANBgkqhkiG9w0BAQEFAAOB" + "jQAwgYkCgYEAveoCUOAukZdcFCs2qJk76vSqEX0ZFzHqQ6faBPZWjwkgUNwZ6m6m" + "qWvvyq1cuxhoDvpfC6NXILETawYc6MNwwxsOtVVIjuXlcF17NMejljJafbPximEt" + "DQ4LcQeSp4K7FyFlIAMLyt3BQ77emGzU5fjFTvHSUNb3jblx0sV28c0CAwEAAaOB" + "tTCBsjAfBgNVHSMEGDAWgBSEJ4bLbvEQY8cYMAFKPFD1/fFXlzAdBgNVHQ4EFgQU" + "hCeGy27xEGPHGDABSjxQ9f3xV5cwDgYDVR0PAQH/BAQDAgEGMBEGCWCGSAGG+EIB" + "AQQEAwIBBjA8BgNVHR8ENTAzMDGgL6AthitodHRwOi8vYWRvbmlzLnBrNy5jZXJ0" + "cGx1cy5uZXQvZGdpLXRlc3QuY3JsMA8GA1UdEwEB/wQFMAMBAf8wDQYJKoZIhvcN" + "AQEFBQADgYEAmToHJWjd3+4zknfsP09H6uMbolHNGG0zTS2lrLKpzcmkQfjhQpT9" + "LUTBvfs1jdjo9fGmQLvOG+Sm51Rbjglb8bcikVI5gLbclOlvqLkm77otjl4U4Z2/" + "Y0vP14Aov3Sn3k+17EfReYUZI4liuB95ncobC4e8ZM++LjQcIM0s+Vs="); byte[] gost34102001base = Base64.decode( "MIIB1DCCAYECEEjpVKXP6Wn1yVz3VeeDQa8wCgYGKoUDAgIDBQAwbTEfMB0G" + "A1UEAwwWR29zdFIzNDEwLTIwMDEgZXhhbXBsZTESMBAGA1UECgwJQ3J5cHRv" + "UHJvMQswCQYDVQQGEwJSVTEpMCcGCSqGSIb3DQEJARYaR29zdFIzNDEwLTIw" + "MDFAZXhhbXBsZS5jb20wHhcNMDUwMjAzMTUxNjQ2WhcNMTUwMjAzMTUxNjQ2" + "WjBtMR8wHQYDVQQDDBZHb3N0UjM0MTAtMjAwMSBleGFtcGxlMRIwEAYDVQQK" + "DAlDcnlwdG9Qcm8xCzAJBgNVBAYTAlJVMSkwJwYJKoZIhvcNAQkBFhpHb3N0" + "UjM0MTAtMjAwMUBleGFtcGxlLmNvbTBjMBwGBiqFAwICEzASBgcqhQMCAiQA" + "BgcqhQMCAh4BA0MABECElWh1YAIaQHUIzROMMYks/eUFA3pDXPRtKw/nTzJ+" + "V4/rzBa5lYgD0Jp8ha4P5I3qprt+VsfLsN8PZrzK6hpgMAoGBiqFAwICAwUA" + "A0EAHw5dw/aw/OiNvHyOE65kvyo4Hp0sfz3csM6UUkp10VO247ofNJK3tsLb" + "HOLjUaqzefrlGb11WpHYrvWFg+FcLA=="); byte[] gost341094base = Base64.decode( "MIICDzCCAbwCEBcxKsIb0ghYvAQeUjfQdFAwCgYGKoUDAgIEBQAwaTEdMBsG" + "A1UEAwwUR29zdFIzNDEwLTk0IGV4YW1wbGUxEjAQBgNVBAoMCUNyeXB0b1By" + "bzELMAkGA1UEBhMCUlUxJzAlBgkqhkiG9w0BCQEWGEdvc3RSMzQxMC05NEBl" + "eGFtcGxlLmNvbTAeFw0wNTAyMDMxNTE2NTFaFw0xNTAyMDMxNTE2NTFaMGkx" + "HTAbBgNVBAMMFEdvc3RSMzQxMC05NCBleGFtcGxlMRIwEAYDVQQKDAlDcnlw" + "dG9Qcm8xCzAJBgNVBAYTAlJVMScwJQYJKoZIhvcNAQkBFhhHb3N0UjM0MTAt" + "OTRAZXhhbXBsZS5jb20wgaUwHAYGKoUDAgIUMBIGByqFAwICIAIGByqFAwIC" + "HgEDgYQABIGAu4Rm4XmeWzTYLIB/E6gZZnFX/oxUJSFHbzALJ3dGmMb7R1W+" + "t7Lzk2w5tUI3JoTiDRCKJA4fDEJNKzsRK6i/ZjkyXJSLwaj+G2MS9gklh8x1" + "G/TliYoJgmjTXHemD7aQEBON4z58nJHWrA0ILD54wbXCtrcaqCqLRYGTMjJ2" + "+nswCgYGKoUDAgIEBQADQQBxKNhOmjgz/i5CEgLOyKyz9pFGkDcaymsWYQWV" + "v7CZ0pTM8IzMzkUBW3GHsUjCFpanFZDfg2zuN+3kT+694n9B"); byte[] gost341094A = Base64.decode( "MIICSDCCAfWgAwIBAgIBATAKBgYqhQMCAgQFADCBgTEXMBUGA1UEAxMOZGVmYXVsdDM0MTAtOTQx" + "DTALBgNVBAoTBERpZ3QxDzANBgNVBAsTBkNyeXB0bzEOMAwGA1UEBxMFWS1vbGExDDAKBgNVBAgT" + "A01FTDELMAkGA1UEBhMCcnUxGzAZBgkqhkiG9w0BCQEWDHRlc3RAdGVzdC5ydTAeFw0wNTAzMjkx" + "MzExNTdaFw0wNjAzMjkxMzExNTdaMIGBMRcwFQYDVQQDEw5kZWZhdWx0MzQxMC05NDENMAsGA1UE" + "ChMERGlndDEPMA0GA1UECxMGQ3J5cHRvMQ4wDAYDVQQHEwVZLW9sYTEMMAoGA1UECBMDTUVMMQsw" + "CQYDVQQGEwJydTEbMBkGCSqGSIb3DQEJARYMdGVzdEB0ZXN0LnJ1MIGlMBwGBiqFAwICFDASBgcq" + "hQMCAiACBgcqhQMCAh4BA4GEAASBgIQACDLEuxSdRDGgdZxHmy30g/DUYkRxO9Mi/uSHX5NjvZ31" + "b7JMEMFqBtyhql1HC5xZfUwZ0aT3UnEFDfFjLP+Bf54gA+LPkQXw4SNNGOj+klnqgKlPvoqMGlwa" + "+hLPKbS561WpvB2XSTgbV+pqqXR3j6j30STmybelEV3RdS2Now8wDTALBgNVHQ8EBAMCB4AwCgYG" + "KoUDAgIEBQADQQBCFy7xWRXtNVXflKvDs0pBdBuPzjCMeZAXVxK8vUxsxxKu76d9CsvhgIFknFRi" + "wWTPiZenvNoJ4R1uzeX+vREm"); byte[] gost341094B = Base64.decode( "MIICSDCCAfWgAwIBAgIBATAKBgYqhQMCAgQFADCBgTEXMBUGA1UEAxMOcGFyYW0xLTM0MTAtOTQx" + "DTALBgNVBAoTBERpZ3QxDzANBgNVBAsTBkNyeXB0bzEOMAwGA1UEBxMFWS1PbGExDDAKBgNVBAgT" + "A01lbDELMAkGA1UEBhMCcnUxGzAZBgkqhkiG9w0BCQEWDHRlc3RAdGVzdC5ydTAeFw0wNTAzMjkx" + "MzEzNTZaFw0wNjAzMjkxMzEzNTZaMIGBMRcwFQYDVQQDEw5wYXJhbTEtMzQxMC05NDENMAsGA1UE" + "ChMERGlndDEPMA0GA1UECxMGQ3J5cHRvMQ4wDAYDVQQHEwVZLU9sYTEMMAoGA1UECBMDTWVsMQsw" + "CQYDVQQGEwJydTEbMBkGCSqGSIb3DQEJARYMdGVzdEB0ZXN0LnJ1MIGlMBwGBiqFAwICFDASBgcq" + "hQMCAiADBgcqhQMCAh4BA4GEAASBgEa+AAcZmijWs1M9x5Pn9efE8D9ztG1NMoIt0/hNZNqln3+j" + "lMZjyqPt+kTLIjtmvz9BRDmIDk6FZz+4LhG2OTL7yGpWfrMxMRr56nxomTN9aLWRqbyWmn3brz9Y" + "AUD3ifnwjjIuW7UM84JNlDTOdxx0XRUfLQIPMCXe9cO02Xskow8wDTALBgNVHQ8EBAMCB4AwCgYG" + "KoUDAgIEBQADQQBzFcnuYc/639OTW+L5Ecjw9KxGr+dwex7lsS9S1BUgKa3m1d5c+cqI0B2XUFi5" + "4iaHHJG0dCyjtQYLJr0OZjRw"); byte[] gost34102001A = Base64.decode( "MIICCzCCAbigAwIBAgIBATAKBgYqhQMCAgMFADCBhDEaMBgGA1UEAxMRZGVmYXVsdC0zNDEwLTIw" + "MDExDTALBgNVBAoTBERpZ3QxDzANBgNVBAsTBkNyeXB0bzEOMAwGA1UEBxMFWS1PbGExDDAKBgNV" + "BAgTA01lbDELMAkGA1UEBhMCcnUxGzAZBgkqhkiG9w0BCQEWDHRlc3RAdGVzdC5ydTAeFw0wNTAz" + "MjkxMzE4MzFaFw0wNjAzMjkxMzE4MzFaMIGEMRowGAYDVQQDExFkZWZhdWx0LTM0MTAtMjAwMTEN" + "MAsGA1UEChMERGlndDEPMA0GA1UECxMGQ3J5cHRvMQ4wDAYDVQQHEwVZLU9sYTEMMAoGA1UECBMD" + "TWVsMQswCQYDVQQGEwJydTEbMBkGCSqGSIb3DQEJARYMdGVzdEB0ZXN0LnJ1MGMwHAYGKoUDAgIT" + "MBIGByqFAwICIwEGByqFAwICHgEDQwAEQG/4c+ZWb10IpeHfmR+vKcbpmSOClJioYmCVgnojw0Xn" + "ned0KTg7TJreRUc+VX7vca4hLQaZ1o/TxVtfEApK/O6jDzANMAsGA1UdDwQEAwIHgDAKBgYqhQMC" + "AgMFAANBAN8y2b6HuIdkD3aWujpfQbS1VIA/7hro4vLgDhjgVmev/PLzFB8oTh3gKhExpDo82IEs" + "ZftGNsbbyp1NFg7zda0="); byte[] gostCA1 = Base64.decode( "MIIDNDCCAuGgAwIBAgIQZLcKDcWcQopF+jp4p9jylDAKBgYqhQMCAgQFADBm" + "MQswCQYDVQQGEwJSVTEPMA0GA1UEBxMGTW9zY293MRcwFQYDVQQKEw5PT08g" + "Q3J5cHRvLVBybzEUMBIGA1UECxMLRGV2ZWxvcG1lbnQxFzAVBgNVBAMTDkNQ" + "IENTUCBUZXN0IENBMB4XDTAyMDYwOTE1NTIyM1oXDTA5MDYwOTE1NTkyOVow" + "ZjELMAkGA1UEBhMCUlUxDzANBgNVBAcTBk1vc2NvdzEXMBUGA1UEChMOT09P" + "IENyeXB0by1Qcm8xFDASBgNVBAsTC0RldmVsb3BtZW50MRcwFQYDVQQDEw5D" + "UCBDU1AgVGVzdCBDQTCBpTAcBgYqhQMCAhQwEgYHKoUDAgIgAgYHKoUDAgIe" + "AQOBhAAEgYAYglywKuz1nMc9UiBYOaulKy53jXnrqxZKbCCBSVaJ+aCKbsQm" + "glhRFrw6Mwu8Cdeabo/ojmea7UDMZd0U2xhZFRti5EQ7OP6YpqD0alllo7za" + "4dZNXdX+/ag6fOORSLFdMpVx5ganU0wHMPk67j+audnCPUj/plbeyccgcdcd" + "WaOCASIwggEeMAsGA1UdDwQEAwIBxjAPBgNVHRMBAf8EBTADAQH/MB0GA1Ud" + "DgQWBBTe840gTo4zt2twHilw3PD9wJaX0TCBygYDVR0fBIHCMIG/MDygOqA4" + "hjYtaHR0cDovL2ZpZXdhbGwvQ2VydEVucm9sbC9DUCUyMENTUCUyMFRlc3Ql" + "MjBDQSgzKS5jcmwwRKBCoECGPmh0dHA6Ly93d3cuY3J5cHRvcHJvLnJ1L0Nl" + "cnRFbnJvbGwvQ1AlMjBDU1AlMjBUZXN0JTIwQ0EoMykuY3JsMDmgN6A1hjMt" + "ZmlsZTovL1xcZmlld2FsbFxDZXJ0RW5yb2xsXENQIENTUCBUZXN0IENBKDMp" + "LmNybC8wEgYJKwYBBAGCNxUBBAUCAwMAAzAKBgYqhQMCAgQFAANBAIJi7ni7" + "9rwMR5rRGTFftt2k70GbqyUEfkZYOzrgdOoKiB4IIsIstyBX0/ne6GsL9Xan" + "G2IN96RB7KrowEHeW+k="); byte[] gostCA2 = Base64.decode( "MIIC2DCCAoWgAwIBAgIQe9ZCugm42pRKNcHD8466zTAKBgYqhQMCAgMFADB+" + "MRowGAYJKoZIhvcNAQkBFgtzYmFAZGlndC5ydTELMAkGA1UEBhMCUlUxDDAK" + "BgNVBAgTA01FTDEUMBIGA1UEBxMLWW9zaGthci1PbGExDTALBgNVBAoTBERp" + "Z3QxDzANBgNVBAsTBkNyeXB0bzEPMA0GA1UEAxMGc2JhLUNBMB4XDTA0MDgw" + "MzEzMzE1OVoXDTE0MDgwMzEzNDAxMVowfjEaMBgGCSqGSIb3DQEJARYLc2Jh" + "QGRpZ3QucnUxCzAJBgNVBAYTAlJVMQwwCgYDVQQIEwNNRUwxFDASBgNVBAcT" + "C1lvc2hrYXItT2xhMQ0wCwYDVQQKEwREaWd0MQ8wDQYDVQQLEwZDcnlwdG8x" + "DzANBgNVBAMTBnNiYS1DQTBjMBwGBiqFAwICEzASBgcqhQMCAiMBBgcqhQMC" + "Ah4BA0MABEDMSy10CuOH+i8QKG2UWA4XmCt6+BFrNTZQtS6bOalyDY8Lz+G7" + "HybyipE3PqdTB4OIKAAPsEEeZOCZd2UXGQm5o4HaMIHXMBMGCSsGAQQBgjcU" + "AgQGHgQAQwBBMAsGA1UdDwQEAwIBhjAPBgNVHRMBAf8EBTADAQH/MB0GA1Ud" + "DgQWBBRJJl3LcNMxkZI818STfoi3ng1xoDBxBgNVHR8EajBoMDGgL6Athito" + "dHRwOi8vc2JhLmRpZ3QubG9jYWwvQ2VydEVucm9sbC9zYmEtQ0EuY3JsMDOg" + "MaAvhi1maWxlOi8vXFxzYmEuZGlndC5sb2NhbFxDZXJ0RW5yb2xsXHNiYS1D" + "QS5jcmwwEAYJKwYBBAGCNxUBBAMCAQAwCgYGKoUDAgIDBQADQQA+BRJHbc/p" + "q8EYl6iJqXCuR+ozRmH7hPAP3c4KqYSC38TClCgBloLapx/3/WdatctFJW/L" + "mcTovpq088927shE"); byte[] inDirectCrl = Base64.decode( "MIIdXjCCHMcCAQEwDQYJKoZIhvcNAQEFBQAwdDELMAkGA1UEBhMCREUxHDAaBgNV" +"BAoUE0RldXRzY2hlIFRlbGVrb20gQUcxFzAVBgNVBAsUDlQtVGVsZVNlYyBUZXN0" +"MS4wDAYHAoIGAQoHFBMBMTAeBgNVBAMUF1QtVGVsZVNlYyBUZXN0IERJUiA4OlBO" +"Fw0wNjA4MDQwODQ1MTRaFw0wNjA4MDQxNDQ1MTRaMIIbfzB+AgQvrj/pFw0wMzA3" +"MjIwNTQxMjhaMGcwZQYDVR0dAQH/BFswWaRXMFUxCzAJBgNVBAYTAkRFMRwwGgYD" +"VQQKFBNEZXV0c2NoZSBUZWxla29tIEFHMSgwDAYHAoIGAQoHFBMBMTAYBgNVBAMU" +"EVNpZ0cgVGVzdCBDQSA0OlBOMH4CBC+uP+oXDTAzMDcyMjA1NDEyOFowZzBlBgNV" +"HR0BAf8EWzBZpFcwVTELMAkGA1UEBhMCREUxHDAaBgNVBAoUE0RldXRzY2hlIFRl" +"bGVrb20gQUcxKDAMBgcCggYBCgcUEwExMBgGA1UEAxQRU2lnRyBUZXN0IENBIDQ6" +"UE4wfgIEL64/5xcNMDQwNDA1MTMxODE3WjBnMGUGA1UdHQEB/wRbMFmkVzBVMQsw" +"CQYDVQQGEwJERTEcMBoGA1UEChQTRGV1dHNjaGUgVGVsZWtvbSBBRzEoMAwGBwKC" +"BgEKBxQTATEwGAYDVQQDFBFTaWdHIFRlc3QgQ0EgNDpQTjB+AgQvrj/oFw0wNDA0" +"MDUxMzE4MTdaMGcwZQYDVR0dAQH/BFswWaRXMFUxCzAJBgNVBAYTAkRFMRwwGgYD" +"VQQKFBNEZXV0c2NoZSBUZWxla29tIEFHMSgwDAYHAoIGAQoHFBMBMTAYBgNVBAMU" +"EVNpZ0cgVGVzdCBDQSA0OlBOMH4CBC+uP+UXDTAzMDExMzExMTgxMVowZzBlBgNV" +"HR0BAf8EWzBZpFcwVTELMAkGA1UEBhMCREUxHDAaBgNVBAoUE0RldXRzY2hlIFRl" +"bGVrb20gQUcxKDAMBgcCggYBCgcUEwExMBgGA1UEAxQRU2lnRyBUZXN0IENBIDQ6" +"UE4wfgIEL64/5hcNMDMwMTEzMTExODExWjBnMGUGA1UdHQEB/wRbMFmkVzBVMQsw" +"CQYDVQQGEwJERTEcMBoGA1UEChQTRGV1dHNjaGUgVGVsZWtvbSBBRzEoMAwGBwKC" +"BgEKBxQTATEwGAYDVQQDFBFTaWdHIFRlc3QgQ0EgNDpQTjB+AgQvrj/jFw0wMzAx" +"MTMxMTI2NTZaMGcwZQYDVR0dAQH/BFswWaRXMFUxCzAJBgNVBAYTAkRFMRwwGgYD" +"VQQKFBNEZXV0c2NoZSBUZWxla29tIEFHMSgwDAYHAoIGAQoHFBMBMTAYBgNVBAMU" +"EVNpZ0cgVGVzdCBDQSA0OlBOMH4CBC+uP+QXDTAzMDExMzExMjY1NlowZzBlBgNV" +"HR0BAf8EWzBZpFcwVTELMAkGA1UEBhMCREUxHDAaBgNVBAoUE0RldXRzY2hlIFRl" +"bGVrb20gQUcxKDAMBgcCggYBCgcUEwExMBgGA1UEAxQRU2lnRyBUZXN0IENBIDQ6" +"UE4wfgIEL64/4hcNMDQwNzEzMDc1ODM4WjBnMGUGA1UdHQEB/wRbMFmkVzBVMQsw" +"CQYDVQQGEwJERTEcMBoGA1UEChQTRGV1dHNjaGUgVGVsZWtvbSBBRzEoMAwGBwKC" +"BgEKBxQTATEwGAYDVQQDFBFTaWdHIFRlc3QgQ0EgNDpQTjB+AgQvrj/eFw0wMzAy" +"MTcwNjMzMjVaMGcwZQYDVR0dAQH/BFswWaRXMFUxCzAJBgNVBAYTAkRFMRwwGgYD" +"VQQKFBNEZXV0c2NoZSBUZWxla29tIEFHMSgwDAYHAoIGAQoHFBMBMTAYBgNVBAMU" +"EVNpZ0cgVGVzdCBDQSA0OlBOMH4CBC+uP98XDTAzMDIxNzA2MzMyNVowZzBlBgNV" +"HR0BAf8EWzBZpFcwVTELMAkGA1UEBhMCREUxHDAaBgNVBAoUE0RldXRzY2hlIFRl" +"bGVrb20gQUcxKDAMBgcCggYBCgcUEwExMBgGA1UEAxQRU2lnRyBUZXN0IENBIDQ6" +"UE4wfgIEL64/0xcNMDMwMjE3MDYzMzI1WjBnMGUGA1UdHQEB/wRbMFmkVzBVMQsw" +"CQYDVQQGEwJERTEcMBoGA1UEChQTRGV1dHNjaGUgVGVsZWtvbSBBRzEoMAwGBwKC" +"BgEKBxQTATEwGAYDVQQDFBFTaWdHIFRlc3QgQ0EgNDpQTjB+AgQvrj/dFw0wMzAx" +"MTMxMTI4MTRaMGcwZQYDVR0dAQH/BFswWaRXMFUxCzAJBgNVBAYTAkRFMRwwGgYD" +"VQQKFBNEZXV0c2NoZSBUZWxla29tIEFHMSgwDAYHAoIGAQoHFBMBMTAYBgNVBAMU" +"EVNpZ0cgVGVzdCBDQSA0OlBOMH4CBC+uP9cXDTAzMDExMzExMjcwN1owZzBlBgNV" +"HR0BAf8EWzBZpFcwVTELMAkGA1UEBhMCREUxHDAaBgNVBAoUE0RldXRzY2hlIFRl" +"bGVrb20gQUcxKDAMBgcCggYBCgcUEwExMBgGA1UEAxQRU2lnRyBUZXN0IENBIDQ6" +"UE4wfgIEL64/2BcNMDMwMTEzMTEyNzA3WjBnMGUGA1UdHQEB/wRbMFmkVzBVMQsw" +"CQYDVQQGEwJERTEcMBoGA1UEChQTRGV1dHNjaGUgVGVsZWtvbSBBRzEoMAwGBwKC" +"BgEKBxQTATEwGAYDVQQDFBFTaWdHIFRlc3QgQ0EgNDpQTjB+AgQvrj/VFw0wMzA0" +"MzAxMjI3NTNaMGcwZQYDVR0dAQH/BFswWaRXMFUxCzAJBgNVBAYTAkRFMRwwGgYD" +"VQQKFBNEZXV0c2NoZSBUZWxla29tIEFHMSgwDAYHAoIGAQoHFBMBMTAYBgNVBAMU" +"EVNpZ0cgVGVzdCBDQSA0OlBOMH4CBC+uP9YXDTAzMDQzMDEyMjc1M1owZzBlBgNV" +"HR0BAf8EWzBZpFcwVTELMAkGA1UEBhMCREUxHDAaBgNVBAoUE0RldXRzY2hlIFRl" +"bGVrb20gQUcxKDAMBgcCggYBCgcUEwExMBgGA1UEAxQRU2lnRyBUZXN0IENBIDQ6" +"UE4wfgIEL64/xhcNMDMwMjEyMTM0NTQwWjBnMGUGA1UdHQEB/wRbMFmkVzBVMQsw" +"CQYDVQQGEwJERTEcMBoGA1UEChQTRGV1dHNjaGUgVGVsZWtvbSBBRzEoMAwGBwKC" +"BgEKBxQTATEwGAYDVQQDFBFUVEMgVGVzdCBDQSAxMTpQTjCBkAIEL64/xRcNMDMw" +"MjEyMTM0NTQwWjB5MHcGA1UdHQEB/wRtMGukaTBnMQswCQYDVQQGEwJERTEcMBoG" +"A1UEChQTRGV1dHNjaGUgVGVsZWtvbSBBRzEQMA4GA1UECxQHVGVsZVNlYzEoMAwG" +"BwKCBgEKBxQTATEwGAYDVQQDFBFTaWdHIFRlc3QgQ0EgNTpQTjB+AgQvrj/CFw0w" +"MzAyMTIxMzA5MTZaMGcwZQYDVR0dAQH/BFswWaRXMFUxCzAJBgNVBAYTAkRFMRww" +"GgYDVQQKFBNEZXV0c2NoZSBUZWxla29tIEFHMSgwDAYHAoIGAQoHFBMBMTAYBgNV" +"BAMUEVRUQyBUZXN0IENBIDExOlBOMIGQAgQvrj/BFw0wMzAyMTIxMzA4NDBaMHkw" +"dwYDVR0dAQH/BG0wa6RpMGcxCzAJBgNVBAYTAkRFMRwwGgYDVQQKFBNEZXV0c2No" +"ZSBUZWxla29tIEFHMRAwDgYDVQQLFAdUZWxlU2VjMSgwDAYHAoIGAQoHFBMBMTAY" +"BgNVBAMUEVNpZ0cgVGVzdCBDQSA1OlBOMH4CBC+uP74XDTAzMDIxNzA2MzcyNVow" +"ZzBlBgNVHR0BAf8EWzBZpFcwVTELMAkGA1UEBhMCREUxHDAaBgNVBAoUE0RldXRz" +"Y2hlIFRlbGVrb20gQUcxKDAMBgcCggYBCgcUEwExMBgGA1UEAxQRVFRDIFRlc3Qg" +"Q0EgMTE6UE4wgZACBC+uP70XDTAzMDIxNzA2MzcyNVoweTB3BgNVHR0BAf8EbTBr" +"pGkwZzELMAkGA1UEBhMCREUxHDAaBgNVBAoUE0RldXRzY2hlIFRlbGVrb20gQUcx" +"EDAOBgNVBAsUB1RlbGVTZWMxKDAMBgcCggYBCgcUEwExMBgGA1UEAxQRU2lnRyBU" +"ZXN0IENBIDU6UE4wgZACBC+uP7AXDTAzMDIxMjEzMDg1OVoweTB3BgNVHR0BAf8E" +"bTBrpGkwZzELMAkGA1UEBhMCREUxHDAaBgNVBAoUE0RldXRzY2hlIFRlbGVrb20g" +"QUcxEDAOBgNVBAsUB1RlbGVTZWMxKDAMBgcCggYBCgcUEwExMBgGA1UEAxQRU2ln" +"RyBUZXN0IENBIDU6UE4wgZACBC+uP68XDTAzMDIxNzA2MzcyNVoweTB3BgNVHR0B" +"Af8EbTBrpGkwZzELMAkGA1UEBhMCREUxHDAaBgNVBAoUE0RldXRzY2hlIFRlbGVr" +"b20gQUcxEDAOBgNVBAsUB1RlbGVTZWMxKDAMBgcCggYBCgcUEwExMBgGA1UEAxQR" +"U2lnRyBUZXN0IENBIDU6UE4wfgIEL64/kxcNMDMwNDEwMDUyNjI4WjBnMGUGA1Ud" +"HQEB/wRbMFmkVzBVMQswCQYDVQQGEwJERTEcMBoGA1UEChQTRGV1dHNjaGUgVGVs" +"ZWtvbSBBRzEoMAwGBwKCBgEKBxQTATEwGAYDVQQDFBFUVEMgVGVzdCBDQSAxMTpQ" +"TjCBkAIEL64/khcNMDMwNDEwMDUyNjI4WjB5MHcGA1UdHQEB/wRtMGukaTBnMQsw" +"CQYDVQQGEwJERTEcMBoGA1UEChQTRGV1dHNjaGUgVGVsZWtvbSBBRzEQMA4GA1UE" +"CxQHVGVsZVNlYzEoMAwGBwKCBgEKBxQTATEwGAYDVQQDFBFTaWdHIFRlc3QgQ0Eg" +"NTpQTjB+AgQvrj8/Fw0wMzAyMjYxMTA0NDRaMGcwZQYDVR0dAQH/BFswWaRXMFUx" +"CzAJBgNVBAYTAkRFMRwwGgYDVQQKFBNEZXV0c2NoZSBUZWxla29tIEFHMSgwDAYH" +"AoIGAQoHFBMBMTAYBgNVBAMUEVRUQyBUZXN0IENBIDExOlBOMIGQAgQvrj8+Fw0w" +"MzAyMjYxMTA0NDRaMHkwdwYDVR0dAQH/BG0wa6RpMGcxCzAJBgNVBAYTAkRFMRww" +"GgYDVQQKFBNEZXV0c2NoZSBUZWxla29tIEFHMRAwDgYDVQQLFAdUZWxlU2VjMSgw" +"DAYHAoIGAQoHFBMBMTAYBgNVBAMUEVNpZ0cgVGVzdCBDQSA1OlBOMH4CBC+uPs0X" +"DTAzMDUyMDA1MjczNlowZzBlBgNVHR0BAf8EWzBZpFcwVTELMAkGA1UEBhMCREUx" +"HDAaBgNVBAoUE0RldXRzY2hlIFRlbGVrb20gQUcxKDAMBgcCggYBCgcUEwExMBgG" +"A1UEAxQRVFRDIFRlc3QgQ0EgMTE6UE4wgZACBC+uPswXDTAzMDUyMDA1MjczNlow" +"eTB3BgNVHR0BAf8EbTBrpGkwZzELMAkGA1UEBhMCREUxHDAaBgNVBAoUE0RldXRz" +"Y2hlIFRlbGVrb20gQUcxEDAOBgNVBAsUB1RlbGVTZWMxKDAMBgcCggYBCgcUEwEx" +"MBgGA1UEAxQRU2lnRyBUZXN0IENBIDY6UE4wfgIEL64+PBcNMDMwNjE3MTAzNDE2" +"WjBnMGUGA1UdHQEB/wRbMFmkVzBVMQswCQYDVQQGEwJERTEcMBoGA1UEChQTRGV1" +"dHNjaGUgVGVsZWtvbSBBRzEoMAwGBwKCBgEKBxQTATEwGAYDVQQDFBFUVEMgVGVz" +"dCBDQSAxMTpQTjCBkAIEL64+OxcNMDMwNjE3MTAzNDE2WjB5MHcGA1UdHQEB/wRt" +"MGukaTBnMQswCQYDVQQGEwJERTEcMBoGA1UEChQTRGV1dHNjaGUgVGVsZWtvbSBB" +"RzEQMA4GA1UECxQHVGVsZVNlYzEoMAwGBwKCBgEKBxQTATEwGAYDVQQDFBFTaWdH" +"IFRlc3QgQ0EgNjpQTjCBkAIEL64+OhcNMDMwNjE3MTAzNDE2WjB5MHcGA1UdHQEB" +"/wRtMGukaTBnMQswCQYDVQQGEwJERTEcMBoGA1UEChQTRGV1dHNjaGUgVGVsZWtv" +"bSBBRzEQMA4GA1UECxQHVGVsZVNlYzEoMAwGBwKCBgEKBxQTATEwGAYDVQQDFBFT" +"aWdHIFRlc3QgQ0EgNjpQTjB+AgQvrj45Fw0wMzA2MTcxMzAxMDBaMGcwZQYDVR0d" +"AQH/BFswWaRXMFUxCzAJBgNVBAYTAkRFMRwwGgYDVQQKFBNEZXV0c2NoZSBUZWxl" +"a29tIEFHMSgwDAYHAoIGAQoHFBMBMTAYBgNVBAMUEVRUQyBUZXN0IENBIDExOlBO" +"MIGQAgQvrj44Fw0wMzA2MTcxMzAxMDBaMHkwdwYDVR0dAQH/BG0wa6RpMGcxCzAJ" +"BgNVBAYTAkRFMRwwGgYDVQQKFBNEZXV0c2NoZSBUZWxla29tIEFHMRAwDgYDVQQL" +"FAdUZWxlU2VjMSgwDAYHAoIGAQoHFBMBMTAYBgNVBAMUEVNpZ0cgVGVzdCBDQSA2" +"OlBOMIGQAgQvrj43Fw0wMzA2MTcxMzAxMDBaMHkwdwYDVR0dAQH/BG0wa6RpMGcx" +"CzAJBgNVBAYTAkRFMRwwGgYDVQQKFBNEZXV0c2NoZSBUZWxla29tIEFHMRAwDgYD" +"VQQLFAdUZWxlU2VjMSgwDAYHAoIGAQoHFBMBMTAYBgNVBAMUEVNpZ0cgVGVzdCBD" +"QSA2OlBOMIGQAgQvrj42Fw0wMzA2MTcxMzAxMDBaMHkwdwYDVR0dAQH/BG0wa6Rp" +"MGcxCzAJBgNVBAYTAkRFMRwwGgYDVQQKFBNEZXV0c2NoZSBUZWxla29tIEFHMRAw" +"DgYDVQQLFAdUZWxlU2VjMSgwDAYHAoIGAQoHFBMBMTAYBgNVBAMUEVNpZ0cgVGVz" +"dCBDQSA2OlBOMIGQAgQvrj4zFw0wMzA2MTcxMDM3NDlaMHkwdwYDVR0dAQH/BG0w" +"a6RpMGcxCzAJBgNVBAYTAkRFMRwwGgYDVQQKFBNEZXV0c2NoZSBUZWxla29tIEFH" +"MRAwDgYDVQQLFAdUZWxlU2VjMSgwDAYHAoIGAQoHFBMBMTAYBgNVBAMUEVNpZ0cg" +"VGVzdCBDQSA2OlBOMH4CBC+uPjEXDTAzMDYxNzEwNDI1OFowZzBlBgNVHR0BAf8E" +"WzBZpFcwVTELMAkGA1UEBhMCREUxHDAaBgNVBAoUE0RldXRzY2hlIFRlbGVrb20g" +"QUcxKDAMBgcCggYBCgcUEwExMBgGA1UEAxQRVFRDIFRlc3QgQ0EgMTE6UE4wgZAC" +"BC+uPjAXDTAzMDYxNzEwNDI1OFoweTB3BgNVHR0BAf8EbTBrpGkwZzELMAkGA1UE" +"BhMCREUxHDAaBgNVBAoUE0RldXRzY2hlIFRlbGVrb20gQUcxEDAOBgNVBAsUB1Rl" +"bGVTZWMxKDAMBgcCggYBCgcUEwExMBgGA1UEAxQRU2lnRyBUZXN0IENBIDY6UE4w" +"gZACBC+uPakXDTAzMTAyMjExMzIyNFoweTB3BgNVHR0BAf8EbTBrpGkwZzELMAkG" +"A1UEBhMCREUxHDAaBgNVBAoUE0RldXRzY2hlIFRlbGVrb20gQUcxEDAOBgNVBAsU" +"B1RlbGVTZWMxKDAMBgcCggYBCgcUEwExMBgGA1UEAxQRU2lnRyBUZXN0IENBIDY6" +"UE4wgZACBC+uPLIXDTA1MDMxMTA2NDQyNFoweTB3BgNVHR0BAf8EbTBrpGkwZzEL" +"MAkGA1UEBhMCREUxHDAaBgNVBAoUE0RldXRzY2hlIFRlbGVrb20gQUcxEDAOBgNV" +"BAsUB1RlbGVTZWMxKDAMBgcCggYBCgcUEwExMBgGA1UEAxQRU2lnRyBUZXN0IENB" +"IDY6UE4wgZACBC+uPKsXDTA0MDQwMjA3NTQ1M1oweTB3BgNVHR0BAf8EbTBrpGkw" +"ZzELMAkGA1UEBhMCREUxHDAaBgNVBAoUE0RldXRzY2hlIFRlbGVrb20gQUcxEDAO" +"BgNVBAsUB1RlbGVTZWMxKDAMBgcCggYBCgcUEwExMBgGA1UEAxQRU2lnRyBUZXN0" +"IENBIDY6UE4wgZACBC+uOugXDTA1MDEyNzEyMDMyNFoweTB3BgNVHR0BAf8EbTBr" +"pGkwZzELMAkGA1UEBhMCREUxHDAaBgNVBAoUE0RldXRzY2hlIFRlbGVrb20gQUcx" +"EDAOBgNVBAsUB1RlbGVTZWMxKDAMBgcCggYBCgcUEwExMBgGA1UEAxQRU2lnRyBU" +"ZXN0IENBIDY6UE4wgZACBC+uOr4XDTA1MDIxNjA3NTcxNloweTB3BgNVHR0BAf8E" +"bTBrpGkwZzELMAkGA1UEBhMCREUxHDAaBgNVBAoUE0RldXRzY2hlIFRlbGVrb20g" +"QUcxEDAOBgNVBAsUB1RlbGVTZWMxKDAMBgcCggYBCgcUEwExMBgGA1UEAxQRU2ln" +"RyBUZXN0IENBIDY6UE4wgZACBC+uOqcXDTA1MDMxMDA1NTkzNVoweTB3BgNVHR0B" +"Af8EbTBrpGkwZzELMAkGA1UEBhMCREUxHDAaBgNVBAoUE0RldXRzY2hlIFRlbGVr" +"b20gQUcxEDAOBgNVBAsUB1RlbGVTZWMxKDAMBgcCggYBCgcUEwExMBgGA1UEAxQR" +"U2lnRyBUZXN0IENBIDY6UE4wgZACBC+uOjwXDTA1MDUxMTEwNDk0NloweTB3BgNV" +"HR0BAf8EbTBrpGkwZzELMAkGA1UEBhMCREUxHDAaBgNVBAoUE0RldXRzY2hlIFRl" +"bGVrb20gQUcxEDAOBgNVBAsUB1RlbGVTZWMxKDAMBgcCggYBCgcUEwExMBgGA1UE" +"AxQRU2lnRyBUZXN0IENBIDY6UE4wgaoCBC+sbdUXDTA1MTExMTEwMDMyMVowgZIw" +"gY8GA1UdHQEB/wSBhDCBgaR/MH0xCzAJBgNVBAYTAkRFMRwwGgYDVQQKFBNEZXV0" +"c2NoZSBUZWxla29tIEFHMR8wHQYDVQQLFBZQcm9kdWt0emVudHJ1bSBUZWxlU2Vj" +"MS8wDAYHAoIGAQoHFBMBMTAfBgNVBAMUGFRlbGVTZWMgUEtTIFNpZ0cgQ0EgMTpQ" +"TjCBlQIEL64uaBcNMDYwMTIzMTAyNTU1WjB+MHwGA1UdHQEB/wRyMHCkbjBsMQsw" +"CQYDVQQGEwJERTEcMBoGA1UEChQTRGV1dHNjaGUgVGVsZWtvbSBBRzEWMBQGA1UE" +"CxQNWmVudHJhbGUgQm9ubjEnMAwGBwKCBgEKBxQTATEwFwYDVQQDFBBUVEMgVGVz" +"dCBDQSA5OlBOMIGVAgQvribHFw0wNjA4MDEwOTQ4NDRaMH4wfAYDVR0dAQH/BHIw" +"cKRuMGwxCzAJBgNVBAYTAkRFMRwwGgYDVQQKFBNEZXV0c2NoZSBUZWxla29tIEFH" +"MRYwFAYDVQQLFA1aZW50cmFsZSBCb25uMScwDAYHAoIGAQoHFBMBMTAXBgNVBAMU" +"EFRUQyBUZXN0IENBIDk6UE6ggZswgZgwCwYDVR0UBAQCAhEMMB8GA1UdIwQYMBaA" +"FANbyNumDI9545HwlCF26NuOJC45MA8GA1UdHAEB/wQFMAOEAf8wVwYDVR0SBFAw" +"ToZMbGRhcDovL3Brc2xkYXAudHR0Yy5kZS9vdT1ULVRlbGVTZWMgVGVzdCBESVIg" +"ODpQTixvPURldXRzY2hlIFRlbGVrb20gQUcsYz1kZTANBgkqhkiG9w0BAQUFAAOB" +"gQBewL5gLFHpeOWO07Vk3Gg7pRDuAlvaovBH4coCyCWpk5jEhUfFSYEDuaQB7do4" +"IlJmeTHvkI0PIZWJ7bwQ2PVdipPWDx0NVwS/Cz5jUKiS3BbAmZQZOueiKLFpQq3A" +"b8aOHA7WHU4078/1lM+bgeu33Ln1CGykEbmSjA/oKPi/JA=="); byte[] directCRL = Base64.decode( "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" +"MQ=="); private final byte[] pkcs7CrlProblem = Base64.decode( "MIIwSAYJKoZIhvcNAQcCoIIwOTCCMDUCAQExCzAJBgUrDgMCGgUAMAsGCSqG" + "SIb3DQEHAaCCEsAwggP4MIIC4KADAgECAgF1MA0GCSqGSIb3DQEBBQUAMEUx" + "CzAJBgNVBAYTAlVTMRYwFAYDVQQKEw1HZW9UcnVzdCBJbmMuMR4wHAYDVQQD" + "ExVHZW9UcnVzdCBDQSBmb3IgQWRvYmUwHhcNMDQxMjAyMjEyNTM5WhcNMDYx" + "MjMwMjEyNTM5WjBMMQswCQYDVQQGEwJVUzEVMBMGA1UEChMMR2VvVHJ1c3Qg" + "SW5jMSYwJAYDVQQDEx1HZW9UcnVzdCBBZG9iZSBPQ1NQIFJlc3BvbmRlcjCB" + "nzANBgkqhkiG9w0BAQEFAAOBjQAwgYkCgYEA4gnNYhtw7U6QeVXZODnGhHMj" + "+OgZ0DB393rEk6a2q9kq129IA2e03yKBTfJfQR9aWKc2Qj90dsSqPjvTDHFG" + "Qsagm2FQuhnA3fb1UWhPzeEIdm6bxDsnQ8nWqKqxnWZzELZbdp3I9bBLizIq" + "obZovzt60LNMghn/unvvuhpeVSsCAwEAAaOCAW4wggFqMA4GA1UdDwEB/wQE" + "AwIE8DCB5QYDVR0gAQH/BIHaMIHXMIHUBgkqhkiG9y8BAgEwgcYwgZAGCCsG" + "AQUFBwICMIGDGoGAVGhpcyBjZXJ0aWZpY2F0ZSBoYXMgYmVlbiBpc3N1ZWQg" + "aW4gYWNjb3JkYW5jZSB3aXRoIHRoZSBBY3JvYmF0IENyZWRlbnRpYWxzIENQ" + "UyBsb2NhdGVkIGF0IGh0dHA6Ly93d3cuZ2VvdHJ1c3QuY29tL3Jlc291cmNl" + "cy9jcHMwMQYIKwYBBQUHAgEWJWh0dHA6Ly93d3cuZ2VvdHJ1c3QuY29tL3Jl" + "c291cmNlcy9jcHMwEwYDVR0lBAwwCgYIKwYBBQUHAwkwOgYDVR0fBDMwMTAv" + "oC2gK4YpaHR0cDovL2NybC5nZW90cnVzdC5jb20vY3Jscy9hZG9iZWNhMS5j" + "cmwwHwYDVR0jBBgwFoAUq4BZw2WDbR19E70Zw+wajw1HaqMwDQYJKoZIhvcN" + "AQEFBQADggEBAENJf1BD7PX5ivuaawt90q1OGzXpIQL/ClzEeFVmOIxqPc1E" + "TFRq92YuxG5b6+R+k+tGkmCwPLcY8ipg6ZcbJ/AirQhohzjlFuT6YAXsTfEj" + "CqEZfWM2sS7crK2EYxCMmKE3xDfPclYtrAoz7qZvxfQj0TuxHSstHZv39wu2" + "ZiG1BWiEcyDQyTgqTOXBoZmfJtshuAcXmTpgkrYSrS37zNlPTGh+pMYQ0yWD" + "c8OQRJR4OY5ZXfdna01mjtJTOmj6/6XPoLPYTq2gQrc2BCeNJ4bEhLb7sFVB" + "PbwPrpzTE/HRbQHDrzj0YimDxeOUV/UXctgvYwHNtEkcBLsOm/uytMYwggSh" + "MIIDiaADAgECAgQ+HL0oMA0GCSqGSIb3DQEBBQUAMGkxCzAJBgNVBAYTAlVT" + "MSMwIQYDVQQKExpBZG9iZSBTeXN0ZW1zIEluY29ycG9yYXRlZDEdMBsGA1UE" + "CxMUQWRvYmUgVHJ1c3QgU2VydmljZXMxFjAUBgNVBAMTDUFkb2JlIFJvb3Qg" + "Q0EwHhcNMDMwMTA4MjMzNzIzWhcNMjMwMTA5MDAwNzIzWjBpMQswCQYDVQQG" + "EwJVUzEjMCEGA1UEChMaQWRvYmUgU3lzdGVtcyBJbmNvcnBvcmF0ZWQxHTAb" + "BgNVBAsTFEFkb2JlIFRydXN0IFNlcnZpY2VzMRYwFAYDVQQDEw1BZG9iZSBS" + "b290IENBMIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEAzE9UhPen" + "ouczU38/nBKIayyZR2d+Dx65rRSI+cMQ2B3w8NWfaQovWTWwzGypTJwVoJ/O" + "IL+gz1Ti4CBmRT85hjh+nMSOByLGJPYBErA131XqaZCw24U3HuJOB7JCoWoT" + "aaBm6oCREVkqmwh5WiBELcm9cziLPC/gQxtdswvwrzUaKf7vppLdgUydPVmO" + "rTE8QH6bkTYG/OJcjdGNJtVcRc+vZT+xqtJilvSoOOq6YEL09BxKNRXO+E4i" + "Vg+VGMX4lp+f+7C3eCXpgGu91grwxnSUnfMPUNuad85LcIMjjaDKeCBEXDxU" + "ZPHqojAZn+pMBk0GeEtekt8i0slns3rSAQIDAQABo4IBTzCCAUswEQYJYIZI" + "AYb4QgEBBAQDAgAHMIGOBgNVHR8EgYYwgYMwgYCgfqB8pHoweDELMAkGA1UE" + "BhMCVVMxIzAhBgNVBAoTGkFkb2JlIFN5c3RlbXMgSW5jb3Jwb3JhdGVkMR0w" + "GwYDVQQLExRBZG9iZSBUcnVzdCBTZXJ2aWNlczEWMBQGA1UEAxMNQWRvYmUg" + "Um9vdCBDQTENMAsGA1UEAxMEQ1JMMTArBgNVHRAEJDAigA8yMDAzMDEwODIz" + "MzcyM1qBDzIwMjMwMTA5MDAwNzIzWjALBgNVHQ8EBAMCAQYwHwYDVR0jBBgw" + "FoAUgrc4SpOqmxDvgLvZVOLxD/uAnN4wHQYDVR0OBBYEFIK3OEqTqpsQ74C7" + "2VTi8Q/7gJzeMAwGA1UdEwQFMAMBAf8wHQYJKoZIhvZ9B0EABBAwDhsIVjYu" + "MDo0LjADAgSQMA0GCSqGSIb3DQEBBQUAA4IBAQAy2p9DdcH6b8lv26sdNjc+" + "vGEZNrcCPB0jWZhsnu5NhedUyCAfp9S74r8Ad30ka3AvXME6dkm10+AjhCpx" + "aiLzwScpmBX2NZDkBEzDjbyfYRzn/SSM0URDjBa6m02l1DUvvBHOvfdRN42f" + "kOQU8Rg/vulZEjX5M5LznuDVa5pxm5lLyHHD4bFhCcTl+pHwQjo3fTT5cujN" + "qmIcIenV9IIQ43sFti1oVgt+fpIsb01yggztVnSynbmrLSsdEF/bJ3Vwj/0d" + "1+ICoHnlHOX/r2RAUS2em0fbQqV8H8KmSLDXvpJpTaT2KVfFeBEY3IdRyhOy" + "Yp1PKzK9MaXB+lKrBYjIMIIEyzCCA7OgAwIBAgIEPhy9tTANBgkqhkiG9w0B" + "AQUFADBpMQswCQYDVQQGEwJVUzEjMCEGA1UEChMaQWRvYmUgU3lzdGVtcyBJ" + "bmNvcnBvcmF0ZWQxHTAbBgNVBAsTFEFkb2JlIFRydXN0IFNlcnZpY2VzMRYw" + "FAYDVQQDEw1BZG9iZSBSb290IENBMB4XDTA0MDExNzAwMDMzOVoXDTE1MDEx" + "NTA4MDAwMFowRTELMAkGA1UEBhMCVVMxFjAUBgNVBAoTDUdlb1RydXN0IElu" + "Yy4xHjAcBgNVBAMTFUdlb1RydXN0IENBIGZvciBBZG9iZTCCASIwDQYJKoZI" + "hvcNAQEBBQADggEPADCCAQoCggEBAKfld+BkeFrnOYW8r9L1WygTDlTdSfrO" + "YvWS/Z6Ye5/l+HrBbOHqQCXBcSeCpz7kB2WdKMh1FOE4e9JlmICsHerBLdWk" + "emU+/PDb69zh8E0cLoDfxukF6oVPXj6WSThdSG7H9aXFzRr6S3XGCuvgl+Qw" + "DTLiLYW+ONF6DXwt3TQQtKReJjOJZk46ZZ0BvMStKyBaeB6DKZsmiIo89qso" + "13VDZINH2w1KvXg0ygDizoNtbvgAPFymwnsINS1klfQlcvn0x0RJm9bYQXK3" + "5GNZAgL3M7Lqrld0jMfIUaWvuHCLyivytRuzq1dJ7E8rmidjDEk/G+27pf13" + "fNZ7vR7M+IkCAwEAAaOCAZ0wggGZMBIGA1UdEwEB/wQIMAYBAf8CAQEwUAYD" + "VR0gBEkwRzBFBgkqhkiG9y8BAgEwODA2BggrBgEFBQcCARYqaHR0cHM6Ly93" + "d3cuYWRvYmUuY29tL21pc2MvcGtpL2Nkc19jcC5odG1sMBQGA1UdJQQNMAsG" + "CSqGSIb3LwEBBTCBsgYDVR0fBIGqMIGnMCKgIKAehhxodHRwOi8vY3JsLmFk" + "b2JlLmNvbS9jZHMuY3JsMIGAoH6gfKR6MHgxCzAJBgNVBAYTAlVTMSMwIQYD" + "VQQKExpBZG9iZSBTeXN0ZW1zIEluY29ycG9yYXRlZDEdMBsGA1UECxMUQWRv" + "YmUgVHJ1c3QgU2VydmljZXMxFjAUBgNVBAMTDUFkb2JlIFJvb3QgQ0ExDTAL" + "BgNVBAMTBENSTDEwCwYDVR0PBAQDAgEGMB8GA1UdIwQYMBaAFIK3OEqTqpsQ" + "74C72VTi8Q/7gJzeMB0GA1UdDgQWBBSrgFnDZYNtHX0TvRnD7BqPDUdqozAZ" + "BgkqhkiG9n0HQQAEDDAKGwRWNi4wAwIEkDANBgkqhkiG9w0BAQUFAAOCAQEA" + "PzlZLqIAjrFeEWEs0uC29YyJhkXOE9mf3YSaFGsITF+Gl1j0pajTjyH4R35Q" + "r3floW2q3HfNzTeZ90Jnr1DhVERD6zEMgJpCtJqVuk0sixuXJHghS/KicKf4" + "YXJJPx9epuIRF1siBRnznnF90svmOJMXApc0jGnYn3nQfk4kaShSnDaYaeYR" + "DJKcsiWhl6S5zfwS7Gg8hDeyckhMQKKWnlG1CQrwlSFisKCduoodwRtWgft8" + "kx13iyKK3sbalm6vnVc+5nufS4vI+TwMXoV63NqYaSroafBWk0nL53zGXPEy" + "+A69QhzEViJKn2Wgqt5gt++jMMNImbRObIqgfgF1VjCCBUwwggQ0oAMCAQIC" + "AgGDMA0GCSqGSIb3DQEBBQUAMEUxCzAJBgNVBAYTAlVTMRYwFAYDVQQKEw1H" + "ZW9UcnVzdCBJbmMuMR4wHAYDVQQDExVHZW9UcnVzdCBDQSBmb3IgQWRvYmUw" + "HhcNMDYwMzI0MTU0MjI5WhcNMDkwNDA2MTQ0MjI5WjBzMQswCQYDVQQGEwJV" + "UzELMAkGA1UECBMCTUExETAPBgNVBAoTCEdlb1RydXN0MR0wGwYDVQQDExRN" + "YXJrZXRpbmcgRGVwYXJ0bWVudDElMCMGCSqGSIb3DQEJARYWbWFya2V0aW5n" + "QGdlb3RydXN0LmNvbTCCASIwDQYJKoZIhvcNAQEBBQADggEPADCCAQoCggEB" + "ANmvajTO4XJvAU2nVcLmXeCnAQX7RZt+7+ML3InmqQ3LCGo1weop09zV069/" + "1x/Nmieol7laEzeXxd2ghjGzwfXafqQEqHn6+vBCvqdNPoSi63fSWhnuDVWp" + "KVDOYgxOonrXl+Cc43lu4zRSq+Pi5phhrjDWcH74a3/rdljUt4c4GFezFXfa" + "w2oTzWkxj2cTSn0Szhpr17+p66UNt8uknlhmu4q44Speqql2HwmCEnpLYJrK" + "W3fOq5D4qdsvsLR2EABLhrBezamLI3iGV8cRHOUTsbTMhWhv/lKfHAyf4XjA" + "z9orzvPN5jthhIfICOFq/nStTgakyL4Ln+nFAB/SMPkCAwEAAaOCAhYwggIS" + "MA4GA1UdDwEB/wQEAwIF4DCB5QYDVR0gAQH/BIHaMIHXMIHUBgkqhkiG9y8B" + "AgEwgcYwgZAGCCsGAQUFBwICMIGDGoGAVGhpcyBjZXJ0aWZpY2F0ZSBoYXMg" + "YmVlbiBpc3N1ZWQgaW4gYWNjb3JkYW5jZSB3aXRoIHRoZSBBY3JvYmF0IENy" + "ZWRlbnRpYWxzIENQUyBsb2NhdGVkIGF0IGh0dHA6Ly93d3cuZ2VvdHJ1c3Qu" + "Y29tL3Jlc291cmNlcy9jcHMwMQYIKwYBBQUHAgEWJWh0dHA6Ly93d3cuZ2Vv" + "dHJ1c3QuY29tL3Jlc291cmNlcy9jcHMwOgYDVR0fBDMwMTAvoC2gK4YpaHR0" + "cDovL2NybC5nZW90cnVzdC5jb20vY3Jscy9hZG9iZWNhMS5jcmwwHwYDVR0j" + "BBgwFoAUq4BZw2WDbR19E70Zw+wajw1HaqMwRAYIKwYBBQUHAQEEODA2MDQG" + "CCsGAQUFBzABhihodHRwOi8vYWRvYmUtb2NzcC5nZW90cnVzdC5jb20vcmVz" + "cG9uZGVyMBQGA1UdJQQNMAsGCSqGSIb3LwEBBTA8BgoqhkiG9y8BAQkBBC4w" + "LAIBAYYnaHR0cDovL2Fkb2JlLXRpbWVzdGFtcC5nZW90cnVzdC5jb20vdHNh" + "MBMGCiqGSIb3LwEBCQIEBTADAgEBMAwGA1UdEwQFMAMCAQAwDQYJKoZIhvcN" + "AQEFBQADggEBAAOhy6QxOo+i3h877fvDvTa0plGD2bIqK7wMdNqbMDoSWied" + "FIcgcBOIm2wLxOjZBAVj/3lDq59q2rnVeNnfXM0/N0MHI9TumHRjU7WNk9e4" + "+JfJ4M+c3anrWOG3NE5cICDVgles+UHjXetHWql/LlP04+K2ZOLb6LE2xGnI" + "YyLW9REzCYNAVF+/WkYdmyceHtaBZdbyVAJq0NAJPsfgY1pWcBo31Mr1fpX9" + "WrXNTYDCqMyxMImJTmN3iI68tkXlNrhweQoArKFqBysiBkXzG/sGKYY6tWKU" + "pzjLc3vIp/LrXC5zilROes8BSvwu1w9qQrJNcGwo7O4uijoNtyYil1Exgh1Q" + "MIIdTAIBATBLMEUxCzAJBgNVBAYTAlVTMRYwFAYDVQQKEw1HZW9UcnVzdCBJ" + "bmMuMR4wHAYDVQQDExVHZW9UcnVzdCBDQSBmb3IgQWRvYmUCAgGDMAkGBSsO" + "AwIaBQCgggxMMBgGCSqGSIb3DQEJAzELBgkqhkiG9w0BBwEwIwYJKoZIhvcN" + "AQkEMRYEFP4R6qIdpQJzWyzrqO8X1ZfJOgChMIIMCQYJKoZIhvcvAQEIMYIL" + "+jCCC/agggZ5MIIGdTCCA6gwggKQMA0GCSqGSIb3DQEBBQUAMEUxCzAJBgNV" + "BAYTAlVTMRYwFAYDVQQKEw1HZW9UcnVzdCBJbmMuMR4wHAYDVQQDExVHZW9U" + "cnVzdCBDQSBmb3IgQWRvYmUXDTA2MDQwNDE3NDAxMFoXDTA2MDQwNTE3NDAx" + "MFowggIYMBMCAgC5Fw0wNTEwMTEyMDM2MzJaMBICAVsXDTA0MTEwNDE1MDk0" + "MVowEwICALgXDTA1MTIxMjIyMzgzOFowEgIBWhcNMDQxMTA0MTUwOTMzWjAT" + "AgIA5hcNMDUwODI3MDQwOTM4WjATAgIAtxcNMDYwMTE2MTc1NTEzWjATAgIA" + "hhcNMDUxMjEyMjIzODU1WjATAgIAtRcNMDUwNzA2MTgzODQwWjATAgIA4BcN" + "MDYwMzIwMDc0ODM0WjATAgIAgRcNMDUwODAyMjIzMTE1WjATAgIA3xcNMDUx" + "MjEyMjIzNjUwWjASAgFKFw0wNDExMDQxNTA5MTZaMBICAUQXDTA0MTEwNDE1" + "MDg1M1owEgIBQxcNMDQxMDAzMDEwMDQwWjASAgFsFw0wNDEyMDYxOTQ0MzFa" + "MBMCAgEoFw0wNjAzMDkxMjA3MTJaMBMCAgEkFw0wNjAxMTYxNzU1MzRaMBIC" + "AWcXDTA1MDMxODE3NTYxNFowEwICAVEXDTA2MDEzMTExMjcxMVowEgIBZBcN" + "MDQxMTExMjI0ODQxWjATAgIA8RcNMDUwOTE2MTg0ODAxWjATAgIBThcNMDYw" + "MjIxMjAxMDM2WjATAgIAwRcNMDUxMjEyMjIzODE2WjASAgFiFw0wNTAxMTAx" + "NjE5MzRaMBICAWAXDTA1MDExMDE5MDAwNFowEwICAL4XDTA1MDUxNzE0NTYx" + "MFowDQYJKoZIhvcNAQEFBQADggEBAEKhRMS3wVho1U3EvEQJZC8+JlUngmZQ" + "A78KQbHPWNZWFlNvPuf/b0s7Lu16GfNHXh1QAW6Y5Hi1YtYZ3YOPyMd4Xugt" + "gCdumbB6xtKsDyN5RvTht6ByXj+CYlYqsL7RX0izJZ6mJn4fjMkqzPKNOjb8" + "kSn5T6rn93BjlATtCE8tPVOM8dnqGccRE0OV59+nDBXc90UMt5LdEbwaUOap" + "snVB0oLcNm8d/HnlVH6RY5LnDjrT4vwfe/FApZtTecEWsllVUXDjSpwfcfD/" + "476/lpGySB2otALqzImlA9R8Ok3hJ8dnF6hhQ5Oe6OJMnGYgdhkKbxsKkdib" + "tTVl3qmH5QAwggLFMIIBrQIBATANBgkqhkiG9w0BAQUFADBpMQswCQYDVQQG" + "EwJVUzEjMCEGA1UEChMaQWRvYmUgU3lzdGVtcyBJbmNvcnBvcmF0ZWQxHTAb" + "BgNVBAsTFEFkb2JlIFRydXN0IFNlcnZpY2VzMRYwFAYDVQQDEw1BZG9iZSBS" + "b290IENBFw0wNjAxMjcxODMzMzFaFw0wNzAxMjcwMDAwMDBaMIHeMCMCBD4c" + "vUAXDTAzMDEyMTIzNDY1NlowDDAKBgNVHRUEAwoBBDAjAgQ+HL1BFw0wMzAx" + "MjEyMzQ3MjJaMAwwCgYDVR0VBAMKAQQwIwIEPhy9YhcNMDMwMTIxMjM0NzQy" + "WjAMMAoGA1UdFQQDCgEEMCMCBD4cvWEXDTA0MDExNzAxMDg0OFowDDAKBgNV" + "HRUEAwoBBDAjAgQ+HL2qFw0wNDAxMTcwMTA5MDVaMAwwCgYDVR0VBAMKAQQw" + "IwIEPhy9qBcNMDQwMTE3MDEzOTI5WjAMMAoGA1UdFQQDCgEEoC8wLTAKBgNV" + "HRQEAwIBDzAfBgNVHSMEGDAWgBSCtzhKk6qbEO+Au9lU4vEP+4Cc3jANBgkq" + "hkiG9w0BAQUFAAOCAQEAwtXF9042wG39icUlsotn5tpE3oCusLb/hBpEONhx" + "OdfEQOq0w5hf/vqaxkcf71etA+KpbEUeSVaHMHRPhx/CmPrO9odE139dJdbt" + "9iqbrC9iZokFK3h/es5kg73xujLKd7C/u5ngJ4mwBtvhMLjFjF2vJhPKHL4C" + "IgMwdaUAhrcNzy16v+mw/VGJy3Fvc6oCESW1K9tvFW58qZSNXrMlsuidgunM" + "hPKG+z0SXVyCqL7pnqKiaGddcgujYGOSY4S938oVcfZeZQEODtSYGlzldojX" + "C1U1hCK5+tHAH0Ox/WqRBIol5VCZQwJftf44oG8oviYq52aaqSejXwmfT6zb" + "76GCBXUwggVxMIIFbQoBAKCCBWYwggViBgkrBgEFBQcwAQEEggVTMIIFTzCB" + "taIWBBS+8EpykfXdl4h3z7m/NZfdkAQQERgPMjAwNjA0MDQyMDIwMTVaMGUw" + "YzA7MAkGBSsOAwIaBQAEFEb4BuZYkbjBjOjT6VeA/00fBvQaBBT3fTSQniOp" + "BbHBSkz4xridlX0bsAICAYOAABgPMjAwNjA0MDQyMDIwMTVaoBEYDzIwMDYw" + "NDA1MDgyMDE1WqEjMCEwHwYJKwYBBQUHMAECBBIEEFqooq/R2WltD7TposkT" + "BhMwDQYJKoZIhvcNAQEFBQADgYEAMig6lty4b0JDsT/oanfQG5x6jVKPACpp" + "1UA9SJ0apJJa7LeIdDFmu5C2S/CYiKZm4A4P9cAu0YzgLHxE4r6Op+HfVlAG" + "6bzUe1P/hi1KCJ8r8wxOZAktQFPSzs85RAZwkHMfB0lP2e/h666Oye+Zf8VH" + "RaE+/xZ7aswE89HXoumgggQAMIID/DCCA/gwggLgoAMCAQICAXUwDQYJKoZI" + "hvcNAQEFBQAwRTELMAkGA1UEBhMCVVMxFjAUBgNVBAoTDUdlb1RydXN0IElu" + "Yy4xHjAcBgNVBAMTFUdlb1RydXN0IENBIGZvciBBZG9iZTAeFw0wNDEyMDIy" + "MTI1MzlaFw0wNjEyMzAyMTI1MzlaMEwxCzAJBgNVBAYTAlVTMRUwEwYDVQQK" + "EwxHZW9UcnVzdCBJbmMxJjAkBgNVBAMTHUdlb1RydXN0IEFkb2JlIE9DU1Ag" + "UmVzcG9uZGVyMIGfMA0GCSqGSIb3DQEBAQUAA4GNADCBiQKBgQDiCc1iG3Dt" + "TpB5Vdk4OcaEcyP46BnQMHf3esSTprar2SrXb0gDZ7TfIoFN8l9BH1pYpzZC" + "P3R2xKo+O9MMcUZCxqCbYVC6GcDd9vVRaE/N4Qh2bpvEOydDydaoqrGdZnMQ" + "tlt2ncj1sEuLMiqhtmi/O3rQs0yCGf+6e++6Gl5VKwIDAQABo4IBbjCCAWow" + "DgYDVR0PAQH/BAQDAgTwMIHlBgNVHSABAf8EgdowgdcwgdQGCSqGSIb3LwEC" + "ATCBxjCBkAYIKwYBBQUHAgIwgYMagYBUaGlzIGNlcnRpZmljYXRlIGhhcyBi" + "ZWVuIGlzc3VlZCBpbiBhY2NvcmRhbmNlIHdpdGggdGhlIEFjcm9iYXQgQ3Jl" + "ZGVudGlhbHMgQ1BTIGxvY2F0ZWQgYXQgaHR0cDovL3d3dy5nZW90cnVzdC5j" + "b20vcmVzb3VyY2VzL2NwczAxBggrBgEFBQcCARYlaHR0cDovL3d3dy5nZW90" + "cnVzdC5jb20vcmVzb3VyY2VzL2NwczATBgNVHSUEDDAKBggrBgEFBQcDCTA6" + "BgNVHR8EMzAxMC+gLaArhilodHRwOi8vY3JsLmdlb3RydXN0LmNvbS9jcmxz" + "L2Fkb2JlY2ExLmNybDAfBgNVHSMEGDAWgBSrgFnDZYNtHX0TvRnD7BqPDUdq" + "ozANBgkqhkiG9w0BAQUFAAOCAQEAQ0l/UEPs9fmK+5prC33SrU4bNekhAv8K" + "XMR4VWY4jGo9zURMVGr3Zi7Eblvr5H6T60aSYLA8txjyKmDplxsn8CKtCGiH" + "OOUW5PpgBexN8SMKoRl9YzaxLtysrYRjEIyYoTfEN89yVi2sCjPupm/F9CPR" + "O7EdKy0dm/f3C7ZmIbUFaIRzINDJOCpM5cGhmZ8m2yG4BxeZOmCSthKtLfvM" + "2U9MaH6kxhDTJYNzw5BElHg5jlld92drTWaO0lM6aPr/pc+gs9hOraBCtzYE" + "J40nhsSEtvuwVUE9vA+unNMT8dFtAcOvOPRiKYPF45RX9Rdy2C9jAc20SRwE" + "uw6b+7K0xjANBgkqhkiG9w0BAQEFAASCAQC7a4yICFGCEMPlJbydK5qLG3rV" + "sip7Ojjz9TB4nLhC2DgsIHds8jjdq2zguInluH2nLaBCVS+qxDVlTjgbI2cB" + "TaWS8nglC7nNjzkKAsa8vThA8FZUVXTW0pb74jNJJU2AA27bb4g+4WgunCrj" + "fpYp+QjDyMmdrJVqRmt5eQN+dpVxMS9oq+NrhOSEhyIb4/rejgNg9wnVK1ms" + "l5PxQ4x7kpm7+Ua41//owkJVWykRo4T1jo4eHEz1DolPykAaKie2VKH/sMqR" + "Spjh4E5biKJLOV9fKivZWKAXByXfwUbbMsJvz4v/2yVHFy9xP+tqB5ZbRoDK" + "k8PzUyCprozn+/22oYIPijCCD4YGCyqGSIb3DQEJEAIOMYIPdTCCD3EGCSqG" + "SIb3DQEHAqCCD2Iwgg9eAgEDMQswCQYFKw4DAhoFADCB+gYLKoZIhvcNAQkQ" + "AQSggeoEgecwgeQCAQEGAikCMCEwCQYFKw4DAhoFAAQUoT97qeCv3FXYaEcS" + "gY8patCaCA8CAiMHGA8yMDA2MDQwNDIwMjA1N1owAwIBPAEB/wIIO0yRre3L" + "8/6ggZCkgY0wgYoxCzAJBgNVBAYTAlVTMRYwFAYDVQQIEw1NYXNzYWNodXNl" + "dHRzMRAwDgYDVQQHEwdOZWVkaGFtMRUwEwYDVQQKEwxHZW9UcnVzdCBJbmMx" + "EzARBgNVBAsTClByb2R1Y3Rpb24xJTAjBgNVBAMTHGFkb2JlLXRpbWVzdGFt" + "cC5nZW90cnVzdC5jb22gggzJMIIDUTCCAjmgAwIBAgICAI8wDQYJKoZIhvcN" + "AQEFBQAwRTELMAkGA1UEBhMCVVMxFjAUBgNVBAoTDUdlb1RydXN0IEluYy4x" + "HjAcBgNVBAMTFUdlb1RydXN0IENBIGZvciBBZG9iZTAeFw0wNTAxMTAwMTI5" + "MTBaFw0xNTAxMTUwODAwMDBaMIGKMQswCQYDVQQGEwJVUzEWMBQGA1UECBMN" + "TWFzc2FjaHVzZXR0czEQMA4GA1UEBxMHTmVlZGhhbTEVMBMGA1UEChMMR2Vv" + "VHJ1c3QgSW5jMRMwEQYDVQQLEwpQcm9kdWN0aW9uMSUwIwYDVQQDExxhZG9i" + "ZS10aW1lc3RhbXAuZ2VvdHJ1c3QuY29tMIGfMA0GCSqGSIb3DQEBAQUAA4GN" + "ADCBiQKBgQDRbxJotLFPWQuuEDhKtOMaBUJepGxIvWxeahMbq1DVmqnk88+j" + "w/5lfPICPzQZ1oHrcTLSAFM7Mrz3pyyQKQKMqUyiemzuG/77ESUNfBNSUfAF" + "PdtHuDMU8Is8ABVnFk63L+wdlvvDIlKkE08+VTKCRdjmuBVltMpQ6QcLFQzm" + "AQIDAQABo4GIMIGFMDoGA1UdHwQzMDEwL6AtoCuGKWh0dHA6Ly9jcmwuZ2Vv" + "dHJ1c3QuY29tL2NybHMvYWRvYmVjYTEuY3JsMB8GA1UdIwQYMBaAFKuAWcNl" + "g20dfRO9GcPsGo8NR2qjMA4GA1UdDwEB/wQEAwIGwDAWBgNVHSUBAf8EDDAK" + "BggrBgEFBQcDCDANBgkqhkiG9w0BAQUFAAOCAQEAmnyXjdtX+F79Nf0KggTd" + "6YC2MQD9s09IeXTd8TP3rBmizfM+7f3icggeCGakNfPRmIUMLoa0VM5Kt37T" + "2X0TqzBWusfbKx7HnX4v1t/G8NJJlT4SShSHv+8bjjU4lUoCmW2oEcC5vXwP" + "R5JfjCyois16npgcO05ZBT+LLDXyeBijE6qWmwLDfEpLyILzVRmyU4IE7jvm" + "rgb3GXwDUvd3yQXGRRHbPCh3nj9hBGbuzyt7GnlqnEie3wzIyMG2ET/wvTX5" + "4BFXKNe7lDLvZj/MXvd3V7gMTSVW0kAszKao56LfrVTgp1VX3UBQYwmQqaoA" + "UwFezih+jEvjW6cYJo/ErDCCBKEwggOJoAMCAQICBD4cvSgwDQYJKoZIhvcN" + "AQEFBQAwaTELMAkGA1UEBhMCVVMxIzAhBgNVBAoTGkFkb2JlIFN5c3RlbXMg" + "SW5jb3Jwb3JhdGVkMR0wGwYDVQQLExRBZG9iZSBUcnVzdCBTZXJ2aWNlczEW" + "MBQGA1UEAxMNQWRvYmUgUm9vdCBDQTAeFw0wMzAxMDgyMzM3MjNaFw0yMzAx" + "MDkwMDA3MjNaMGkxCzAJBgNVBAYTAlVTMSMwIQYDVQQKExpBZG9iZSBTeXN0" + "ZW1zIEluY29ycG9yYXRlZDEdMBsGA1UECxMUQWRvYmUgVHJ1c3QgU2Vydmlj" + "ZXMxFjAUBgNVBAMTDUFkb2JlIFJvb3QgQ0EwggEiMA0GCSqGSIb3DQEBAQUA" + "A4IBDwAwggEKAoIBAQDMT1SE96ei5zNTfz+cEohrLJlHZ34PHrmtFIj5wxDY" + "HfDw1Z9pCi9ZNbDMbKlMnBWgn84gv6DPVOLgIGZFPzmGOH6cxI4HIsYk9gES" + "sDXfVeppkLDbhTce4k4HskKhahNpoGbqgJERWSqbCHlaIEQtyb1zOIs8L+BD" + "G12zC/CvNRop/u+mkt2BTJ09WY6tMTxAfpuRNgb84lyN0Y0m1VxFz69lP7Gq" + "0mKW9Kg46rpgQvT0HEo1Fc74TiJWD5UYxfiWn5/7sLd4JemAa73WCvDGdJSd" + "8w9Q25p3zktwgyONoMp4IERcPFRk8eqiMBmf6kwGTQZ4S16S3yLSyWezetIB" + "AgMBAAGjggFPMIIBSzARBglghkgBhvhCAQEEBAMCAAcwgY4GA1UdHwSBhjCB" + "gzCBgKB+oHykejB4MQswCQYDVQQGEwJVUzEjMCEGA1UEChMaQWRvYmUgU3lz" + "dGVtcyBJbmNvcnBvcmF0ZWQxHTAbBgNVBAsTFEFkb2JlIFRydXN0IFNlcnZp" + "Y2VzMRYwFAYDVQQDEw1BZG9iZSBSb290IENBMQ0wCwYDVQQDEwRDUkwxMCsG" + "A1UdEAQkMCKADzIwMDMwMTA4MjMzNzIzWoEPMjAyMzAxMDkwMDA3MjNaMAsG" + "A1UdDwQEAwIBBjAfBgNVHSMEGDAWgBSCtzhKk6qbEO+Au9lU4vEP+4Cc3jAd" + "BgNVHQ4EFgQUgrc4SpOqmxDvgLvZVOLxD/uAnN4wDAYDVR0TBAUwAwEB/zAd" + "BgkqhkiG9n0HQQAEEDAOGwhWNi4wOjQuMAMCBJAwDQYJKoZIhvcNAQEFBQAD" + "ggEBADLan0N1wfpvyW/bqx02Nz68YRk2twI8HSNZmGye7k2F51TIIB+n1Lvi" + "vwB3fSRrcC9cwTp2SbXT4COEKnFqIvPBJymYFfY1kOQETMONvJ9hHOf9JIzR" + "REOMFrqbTaXUNS+8Ec6991E3jZ+Q5BTxGD++6VkSNfkzkvOe4NVrmnGbmUvI" + "ccPhsWEJxOX6kfBCOjd9NPly6M2qYhwh6dX0ghDjewW2LWhWC35+kixvTXKC" + "DO1WdLKduastKx0QX9sndXCP/R3X4gKgeeUc5f+vZEBRLZ6bR9tCpXwfwqZI" + "sNe+kmlNpPYpV8V4ERjch1HKE7JinU8rMr0xpcH6UqsFiMgwggTLMIIDs6AD" + "AgECAgQ+HL21MA0GCSqGSIb3DQEBBQUAMGkxCzAJBgNVBAYTAlVTMSMwIQYD" + "VQQKExpBZG9iZSBTeXN0ZW1zIEluY29ycG9yYXRlZDEdMBsGA1UECxMUQWRv" + "YmUgVHJ1c3QgU2VydmljZXMxFjAUBgNVBAMTDUFkb2JlIFJvb3QgQ0EwHhcN" + "MDQwMTE3MDAwMzM5WhcNMTUwMTE1MDgwMDAwWjBFMQswCQYDVQQGEwJVUzEW" + "MBQGA1UEChMNR2VvVHJ1c3QgSW5jLjEeMBwGA1UEAxMVR2VvVHJ1c3QgQ0Eg" + "Zm9yIEFkb2JlMIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEAp+V3" + "4GR4Wuc5hbyv0vVbKBMOVN1J+s5i9ZL9nph7n+X4esFs4epAJcFxJ4KnPuQH" + "ZZ0oyHUU4Th70mWYgKwd6sEt1aR6ZT788Nvr3OHwTRwugN/G6QXqhU9ePpZJ" + "OF1Ibsf1pcXNGvpLdcYK6+CX5DANMuIthb440XoNfC3dNBC0pF4mM4lmTjpl" + "nQG8xK0rIFp4HoMpmyaIijz2qyjXdUNkg0fbDUq9eDTKAOLOg21u+AA8XKbC" + "ewg1LWSV9CVy+fTHREmb1thBcrfkY1kCAvczsuquV3SMx8hRpa+4cIvKK/K1" + "G7OrV0nsTyuaJ2MMST8b7bul/Xd81nu9Hsz4iQIDAQABo4IBnTCCAZkwEgYD" + "VR0TAQH/BAgwBgEB/wIBATBQBgNVHSAESTBHMEUGCSqGSIb3LwECATA4MDYG" + "CCsGAQUFBwIBFipodHRwczovL3d3dy5hZG9iZS5jb20vbWlzYy9wa2kvY2Rz" + "X2NwLmh0bWwwFAYDVR0lBA0wCwYJKoZIhvcvAQEFMIGyBgNVHR8Egaowgacw" + "IqAgoB6GHGh0dHA6Ly9jcmwuYWRvYmUuY29tL2Nkcy5jcmwwgYCgfqB8pHow" + "eDELMAkGA1UEBhMCVVMxIzAhBgNVBAoTGkFkb2JlIFN5c3RlbXMgSW5jb3Jw" + "b3JhdGVkMR0wGwYDVQQLExRBZG9iZSBUcnVzdCBTZXJ2aWNlczEWMBQGA1UE" + "AxMNQWRvYmUgUm9vdCBDQTENMAsGA1UEAxMEQ1JMMTALBgNVHQ8EBAMCAQYw" + "HwYDVR0jBBgwFoAUgrc4SpOqmxDvgLvZVOLxD/uAnN4wHQYDVR0OBBYEFKuA" + "WcNlg20dfRO9GcPsGo8NR2qjMBkGCSqGSIb2fQdBAAQMMAobBFY2LjADAgSQ" + "MA0GCSqGSIb3DQEBBQUAA4IBAQA/OVkuogCOsV4RYSzS4Lb1jImGRc4T2Z/d" + "hJoUawhMX4aXWPSlqNOPIfhHflCvd+Whbarcd83NN5n3QmevUOFUREPrMQyA" + "mkK0mpW6TSyLG5ckeCFL8qJwp/hhckk/H16m4hEXWyIFGfOecX3Sy+Y4kxcC" + "lzSMadifedB+TiRpKFKcNphp5hEMkpyyJaGXpLnN/BLsaDyEN7JySExAopae" + "UbUJCvCVIWKwoJ26ih3BG1aB+3yTHXeLIorextqWbq+dVz7me59Li8j5PAxe" + "hXrc2phpKuhp8FaTScvnfMZc8TL4Dr1CHMRWIkqfZaCq3mC376Mww0iZtE5s" + "iqB+AXVWMYIBgDCCAXwCAQEwSzBFMQswCQYDVQQGEwJVUzEWMBQGA1UEChMN" + "R2VvVHJ1c3QgSW5jLjEeMBwGA1UEAxMVR2VvVHJ1c3QgQ0EgZm9yIEFkb2Jl" + "AgIAjzAJBgUrDgMCGgUAoIGMMBoGCSqGSIb3DQEJAzENBgsqhkiG9w0BCRAB" + "BDAcBgkqhkiG9w0BCQUxDxcNMDYwNDA0MjAyMDU3WjAjBgkqhkiG9w0BCQQx" + "FgQUp7AnXBqoNcarvO7fMJut1og2U5AwKwYLKoZIhvcNAQkQAgwxHDAaMBgw" + "FgQU1dH4eZTNhgxdiSABrat6zsPdth0wDQYJKoZIhvcNAQEBBQAEgYCinr/F" + "rMiQz/MRm9ZD5YGcC0Qo2dRTPd0Aop8mZ4g1xAhKFLnp7lLsjCbkSDpVLDBh" + "cnCk7CV+3FT5hlvt8OqZlR0CnkSnCswLFhrppiWle6cpxlwGqyAteC8uKtQu" + "wjE5GtBKLcCOAzQYyyuNZZeB6oCZ+3mPhZ62FxrvvEGJCgAAAAAAAAAAAAAA" + "AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA" + "AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA" + "AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA" + "AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA" + "AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA" + "AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA" + "AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA" + "AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA" + "AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA=="); private final byte[] emptyDNCert = Base64.decode( "MIICfTCCAeagAwIBAgIBajANBgkqhkiG9w0BAQQFADB8MQswCQYDVQQGEwJVUzEMMAoGA1UEChMD" + "Q0RXMQkwBwYDVQQLEwAxCTAHBgNVBAcTADEJMAcGA1UECBMAMRowGAYDVQQDExFUZW1wbGFyIFRl" + "c3QgMTAyNDEiMCAGCSqGSIb3DQEJARYTdGVtcGxhcnRlc3RAY2R3LmNvbTAeFw0wNjA1MjIwNTAw" + "MDBaFw0xMDA1MjIwNTAwMDBaMHwxCzAJBgNVBAYTAlVTMQwwCgYDVQQKEwNDRFcxCTAHBgNVBAsT" + "ADEJMAcGA1UEBxMAMQkwBwYDVQQIEwAxGjAYBgNVBAMTEVRlbXBsYXIgVGVzdCAxMDI0MSIwIAYJ" + "KoZIhvcNAQkBFhN0ZW1wbGFydGVzdEBjZHcuY29tMIGfMA0GCSqGSIb3DQEBAQUAA4GNADCBiQKB" + "gQDH3aJpJBfM+A3d84j5YcU6zEQaQ76u5xO9NSBmHjZykKS2kCcUqPpvVOPDA5WgV22dtKPh+lYV" + "iUp7wyCVwAKibq8HIbihHceFqMKzjwC639rMoDJ7bi/yzQWz1Zg+075a4FGPlUKn7Yfu89wKkjdW" + "wDpRPXc/agqBnrx5pJTXzQIDAQABow8wDTALBgNVHQ8EBAMCALEwDQYJKoZIhvcNAQEEBQADgYEA" + "RRsRsjse3i2/KClFVd6YLZ+7K1BE0WxFyY2bbytkwQJSxvv3vLSuweFUbhNxutb68wl/yW4GLy4b" + "1QdyswNxrNDXTuu5ILKhRDDuWeocz83aG2KGtr3JlFyr3biWGEyn5WUOE6tbONoQDJ0oPYgI6CAc" + "EHdUp0lioOCt6UOw7Cs="); private final byte[] gostRFC4491_94 = Base64.decode( "MIICCzCCAboCECMO42BGlSTOxwvklBgufuswCAYGKoUDAgIEMGkxHTAbBgNVBAMM" + "FEdvc3RSMzQxMC05NCBleGFtcGxlMRIwEAYDVQQKDAlDcnlwdG9Qcm8xCzAJBgNV" + "BAYTAlJVMScwJQYJKoZIhvcNAQkBFhhHb3N0UjM0MTAtOTRAZXhhbXBsZS5jb20w" + "HhcNMDUwODE2MTIzMjUwWhcNMTUwODE2MTIzMjUwWjBpMR0wGwYDVQQDDBRHb3N0" + "UjM0MTAtOTQgZXhhbXBsZTESMBAGA1UECgwJQ3J5cHRvUHJvMQswCQYDVQQGEwJS" + "VTEnMCUGCSqGSIb3DQEJARYYR29zdFIzNDEwLTk0QGV4YW1wbGUuY29tMIGlMBwG" + "BiqFAwICFDASBgcqhQMCAiACBgcqhQMCAh4BA4GEAASBgLuEZuF5nls02CyAfxOo" + "GWZxV/6MVCUhR28wCyd3RpjG+0dVvrey85NsObVCNyaE4g0QiiQOHwxCTSs7ESuo" + "v2Y5MlyUi8Go/htjEvYJJYfMdRv05YmKCYJo01x3pg+2kBATjeM+fJyR1qwNCCw+" + "eMG1wra3Gqgqi0WBkzIydvp7MAgGBiqFAwICBANBABHHCH4S3ALxAiMpR3aPRyqB" + "g1DjB8zy5DEjiULIc+HeIveF81W9lOxGkZxnrFjXBSqnjLeFKgF1hffXOAP7zUM="); private final byte[] gostRFC4491_2001 = Base64.decode( "MIIB0DCCAX8CECv1xh7CEb0Xx9zUYma0LiEwCAYGKoUDAgIDMG0xHzAdBgNVBAMM" + "Fkdvc3RSMzQxMC0yMDAxIGV4YW1wbGUxEjAQBgNVBAoMCUNyeXB0b1BybzELMAkG" + "A1UEBhMCUlUxKTAnBgkqhkiG9w0BCQEWGkdvc3RSMzQxMC0yMDAxQGV4YW1wbGUu" + "Y29tMB4XDTA1MDgxNjE0MTgyMFoXDTE1MDgxNjE0MTgyMFowbTEfMB0GA1UEAwwW" + "R29zdFIzNDEwLTIwMDEgZXhhbXBsZTESMBAGA1UECgwJQ3J5cHRvUHJvMQswCQYD" + "VQQGEwJSVTEpMCcGCSqGSIb3DQEJARYaR29zdFIzNDEwLTIwMDFAZXhhbXBsZS5j" + "b20wYzAcBgYqhQMCAhMwEgYHKoUDAgIkAAYHKoUDAgIeAQNDAARAhJVodWACGkB1" + "CM0TjDGJLP3lBQN6Q1z0bSsP508yfleP68wWuZWIA9CafIWuD+SN6qa7flbHy7Df" + "D2a8yuoaYDAIBgYqhQMCAgMDQQA8L8kJRLcnqeyn1en7U23Sw6pkfEQu3u0xFkVP" + "vFQ/3cHeF26NG+xxtZPz3TaTVXdoiYkXYiD02rEx1bUcM97i"); private final byte[] uaczo1 = Base64.decode( "MIIFWzCCBNegAwIBAgIUMAR1He8seK4BAAAAAQAAAAEAAAAwDQYLKoYkAgEBAQED" + "AQEwgfoxPzA9BgNVBAoMNtCc0ZbQvdGW0YHRgtC10YDRgdGC0LLQviDRjtGB0YLQ" + "uNGG0ZbRlyDQo9C60YDQsNGX0L3QuDExMC8GA1UECwwo0JDQtNC80ZbQvdGW0YHR" + "gtGA0LDRgtC+0YAg0IbQotChINCm0JfQnjFJMEcGA1UEAwxA0KbQtdC90YLRgNCw" + "0LvRjNC90LjQuSDQt9Cw0YHQstGW0LTRh9GD0LLQsNC70YzQvdC40Lkg0L7RgNCz" + "0LDQvTEZMBcGA1UEBQwQVUEtMDAwMTU2MjItMjAxMjELMAkGA1UEBhMCVUExETAP" + "BgNVBAcMCNCa0LjRl9CyMB4XDTEyMDkyODE5NTMwMFoXDTIyMDkyODE5NTMwMFow" + "gfoxPzA9BgNVBAoMNtCc0ZbQvdGW0YHRgtC10YDRgdGC0LLQviDRjtGB0YLQuNGG" + "0ZbRlyDQo9C60YDQsNGX0L3QuDExMC8GA1UECwwo0JDQtNC80ZbQvdGW0YHRgtGA" + "0LDRgtC+0YAg0IbQotChINCm0JfQnjFJMEcGA1UEAwxA0KbQtdC90YLRgNCw0LvR" + "jNC90LjQuSDQt9Cw0YHQstGW0LTRh9GD0LLQsNC70YzQvdC40Lkg0L7RgNCz0LDQ" + "vTEZMBcGA1UEBQwQVUEtMDAwMTU2MjItMjAxMjELMAkGA1UEBhMCVUExETAPBgNV" + "BAcMCNCa0LjRl9CyMIIBUTCCARIGCyqGJAIBAQEBAwEBMIIBATCBvDAPAgIBrzAJ" + "AgEBAgEDAgEFAgEBBDbzykDGaaTaFzFJyhLDLa4Ya1Osa8Y2WZferq6K0tiI+b/V" + "NAFpTvnEJz2M/m3Cj3BqD0kQzgMCNj//////////////////////////////////" + "/7oxdUWACajApyTwL4Gqih/Lr4DZDHqVEQUEzwQ2fIV8lMVDO/2ZHhfCJoQGWFCp" + "oknte8JJrlpOh4aJ+HLvetUkCC7DA46a7ee6a6Ezgdl5umIaBECp1utF8TxwgoDE" + "lnsjH16t9ljrpMA3KR042WvwJcpOF/jpcg3GFbQ6KJdfC8Heo2Q4tWTqLBef0BI+" + "bbj6xXkEAzkABDa2G/m9S2LKqyw5UPXFHV+oDXB+AHtSW3BnZ9zlzRuvbido2tDG" + "qE/CL5kFHZE0NfTrHrGa1USjggE6MIIBNjApBgNVHQ4EIgQgMAR1He8seK4VC6vv" + "vv8Nq9v4LOVonutO0xCl+xM4+wowKwYDVR0jBCQwIoAgMAR1He8seK4VC6vvvv8N" + "q9v4LOVonutO0xCl+xM4+wowDgYDVR0PAQH/BAQDAgEGMBkGA1UdIAEB/wQPMA0w" + "CwYJKoYkAgEBAQICMBIGA1UdEwEB/wQIMAYBAf8CAQIwHgYIKwYBBQUHAQMBAf8E" + "DzANMAsGCSqGJAIBAQECATA9BgNVHR8ENjA0MDKgMKAuhixodHRwOi8vY3pvLmdv" + "di51YS9kb3dubG9hZC9jcmxzL0NaTy1GdWxsLmNybDA+BgNVHS4ENzA1MDOgMaAv" + "hi1odHRwOi8vY3pvLmdvdi51YS9kb3dubG9hZC9jcmxzL0NaTy1EZWx0YS5jcmww" + "DQYLKoYkAgEBAQEDAQEDbwAEbPF4bx7drDxzzYABhB33Y0MQ+/N5FuPl7faVx/es" + "V5n5DXg5TzZovzZeICB5JHPLcbdeCq6aGwvXsgybt34zqf7LKmfq0rFNYfXJVWFH" + "4Tg5sPA+fCQ+T0O35VN873BLgTGz7bnHH9o8bnjwMA=="); private final byte[] uaczo2 = Base64.decode( "MIIEvTCCBDmgAwIBAgIDAYhwMA0GCyqGJAIBAQEBAwEBMIIBHjELMAkGA1UEBhMC" + "VUExKDAmBgNVBAgMH9Ca0LjRl9Cy0YHRjNC60LAg0L7QsdC70LDRgdGC0YwxETAP" + "BgNVBAcMCNCa0LjRl9CyMUkwRwYDVQQKDEDQptC10L3RgtGA0LDQu9GM0L3QuNC5" + "INC30LDRgdCy0ZbQtNGH0YPQstCw0LvRjNC90LjQuSDQvtGA0LPQsNC9MTUwMwYD" + "VQQLDCzQotC10YXQvdC+0LvQvtCz0ZbRh9C90LjQuSDRhtC10L3RgtGAINCm0JfQ" + "njE1MDMGA1UEAwws0KPQutGA0LDRl9C90LAsINCm0JfQniAvIFVrcmFpbmUsIENl" + "bnRyYWwgQ0ExGTAXBgNVBAUTEFVBLTM3MjAwMzAzLTIwMTAwHhcNMDYxMjI1MDc0" + "MDU4WhcNMTExMjI0MDc0MDU4WjCCAR4xCzAJBgNVBAYTAlVBMSgwJgYDVQQIDB/Q" + "mtC40ZfQstGB0YzQutCwINC+0LHQu9Cw0YHRgtGMMREwDwYDVQQHDAjQmtC40ZfQ" + "sjFJMEcGA1UECgxA0KbQtdC90YLRgNCw0LvRjNC90LjQuSDQt9Cw0YHQstGW0LTR" + "h9GD0LLQsNC70YzQvdC40Lkg0L7RgNCz0LDQvTE1MDMGA1UECwws0KLQtdGF0L3Q" + "vtC70L7Qs9GW0YfQvdC40Lkg0YbQtdC90YLRgCDQptCX0J4xNTAzBgNVBAMMLNCj" + "0LrRgNCw0ZfQvdCwLCDQptCX0J4gLyBVa3JhaW5lLCBDZW50cmFsIENBMRkwFwYD" + "VQQFExBVQS0zNzIwMDMwMy0yMDEwMIGdMGAGCyqGJAIBAQEBAwEBMFEGDSqGJAIB" + "AQEBAwEBAgkEQKnW60XxPHCCgMSWeyMfXq32WOukwDcpHTjZa/Alyk4X+OlyDcYV" + "tDool18Lwd6jZDi1ZOosF5/QEj5tuPrFeQQDOQAENlMfji/H5gxxL5TKtLMFv2X3" + "0EJrj3orwGV0zEz+EgSChr+I8bsOrnfkr5UwMQIjGJOg1G/nYKOCARgwggEUMA8G" + "A1UdEwEB/wQFMAMBAf8weQYDVR0gAQH/BG8wbTBeBgkqhiQCAQEBAgEwUTBPBggr" + "BgEFBQcCARZDaHR0cDovL2N6by5nb3YudWEvY29udGVudC9ub3JtYXRpdmVfZG9j" + "dW1lbnQvZ2VuZXJhbF9kb2MvcmVnQ1pPLnppcDALBgkqhiQCAQEBAgIwHgYIKwYB" + "BQUHAQMBAf8EDzANMAsGCSqGJAIBAQECATAOBgNVHQ8BAf8EBAMCAcYwKQYDVR0O" + "BCIEIPqbNt55OgWdLCn8hfuY9HJE3d3+DTTBlTJBN0nxog+mMCsGA1UdIwQkMCKA" + "IPqbNt55OgWdLCn8hfuY9HJE3d3+DTTBlTJBN0nxog+mMA0GCyqGJAIBAQEBAwEB" + "A28ABGx8QNaWcy0admsBt6iB0Vi+kAargzsQuoc/BThskYdxGNftLvYDPYxkEM2N" + "GQ+9f1RJgCSNVRj3NhWoHhkqcL5R3gxAHie+a+zMqsX0258hGdT3MXkm0Syn/cNo" + "sga4XzzvnVaas9vsPKMrZTQ="); private final byte[] uaczo3 = Base64.decode( "MIIEtTCCBDGgAwIBAgIDAYisMA0GCyqGJAIBAQEBAwEBMIIBGjELMAkGA1UEBhMC" + "VUExKDAmBgNVBAgMH9Ca0LjRl9Cy0YHRjNC60LAg0L7QsdC70LDRgdGC0YwxETAP" + "BgNVBAcMCNCa0LjRl9CyMUkwRwYDVQQKDEDQptC10L3RgtGA0LDQu9GM0L3QuNC5" + "INC30LDRgdCy0ZbQtNGH0YPQstCw0LvRjNC90LjQuSDQvtGA0LPQsNC9MTEwLwYD" + "VQQLDCjQkNC00LzRltC90ZbRgdGC0YDQsNGC0L7RgCDQhtCi0KEg0KbQl9CeMTUw" + "MwYDVQQDDCzQo9C60YDQsNGX0L3QsCwg0KbQl9CeIC8gVWtyYWluZSwgQ2VudHJh" + "bCBDQTEZMBcGA1UEBRMQVUEtMDAwMTU2MjItMjAxMTAeFw0wNzEyMjAxMDAwMDBa" + "Fw0xMjEyMTgxMDAwMDBaMIIBGjELMAkGA1UEBhMCVUExKDAmBgNVBAgMH9Ca0LjR" + "l9Cy0YHRjNC60LAg0L7QsdC70LDRgdGC0YwxETAPBgNVBAcMCNCa0LjRl9CyMUkw" + "RwYDVQQKDEDQptC10L3RgtGA0LDQu9GM0L3QuNC5INC30LDRgdCy0ZbQtNGH0YPQ" + "stCw0LvRjNC90LjQuSDQvtGA0LPQsNC9MTEwLwYDVQQLDCjQkNC00LzRltC90ZbR" + "gdGC0YDQsNGC0L7RgCDQhtCi0KEg0KbQl9CeMTUwMwYDVQQDDCzQo9C60YDQsNGX" + "0L3QsCwg0KbQl9CeIC8gVWtyYWluZSwgQ2VudHJhbCBDQTEZMBcGA1UEBRMQVUEt" + "MDAwMTU2MjItMjAxMTCBnTBgBgsqhiQCAQEBAQMBATBRBg0qhiQCAQEBAQMBAQIJ" + "BECp1utF8TxwgoDElnsjH16t9ljrpMA3KR042WvwJcpOF/jpcg3GFbQ6KJdfC8He" + "o2Q4tWTqLBef0BI+bbj6xXkEAzkABDajkfNBomH27xjY1N7wklRvY5E0ZFaU53Fh" + "y4jUY+G4AUhEHHCkTvUja8CUxPqtb9KyfuZELVOjggEYMIIBFDAPBgNVHRMBAf8E" + "BTADAQH/MHkGA1UdIAEB/wRvMG0wXgYJKoYkAgEBAQIBMFEwTwYIKwYBBQUHAgEW" + "Q2h0dHA6Ly9jem8uZ292LnVhL2NvbnRlbnQvbm9ybWF0aXZlX2RvY3VtZW50L2dl" + "bmVyYWxfZG9jL3JlZ0NaTy56aXAwCwYJKoYkAgEBAQICMB4GCCsGAQUFBwEDAQH/" + "BA8wDTALBgkqhiQCAQEBAgEwDgYDVR0PAQH/BAQDAgHGMCkGA1UdDgQiBCC+e+cA" + "bIdAgQkh6q3dUAZjPrNhwDDGrVnLNP6telmoCjArBgNVHSMEJDAigCC+e+cAbIdA" + "gQkh6q3dUAZjPrNhwDDGrVnLNP6telmoCjANBgsqhiQCAQEBAQMBAQNvAARsyq9i" + "ajEgdBh5mPUZefcLY56AIRWqmsJsWuZuUbCa5oQXRH5iCRa4PSvs8v6zHAKKlMgK" + "gaoY6jywqmwiMlylbSgo/A0HKdCFnUUl7S8yjE4054MSSIjb2R0c2pmqmwtU25JB" + "/MkNbe77Uzka"); private final byte[] uaczo4 = Base64.decode( "MIIEKzCCA6egAwIBAgIBATANBgsqhiQCAQEBAQMBATCBzDFJMEcGA1UECwxA0KbQ" + "tdC90YLRgNCw0LvRjNC90LjQuSDQt9Cw0YHQstGW0LTRh9GD0LLQsNC70YzQvdC4" + "0Lkg0L7RgNCz0LDQvTE1MDMGA1UEAwws0KPQutGA0LDRl9C90LAsINCm0JfQniAv" + "IFVrcmFpbmUsIENlbnRyYWwgQ0ExCzAJBgNVBAYTAlVBMREwDwYDVQQHDAjQmtC4" + "0ZfQsjEoMCYGA1UECAwf0JrQuNGX0LLRgdGM0LrQsCDQvtCx0LvQsNGB0YLRjDAe" + "Fw0wNTEyMjMyMzAxMDFaFw0xMDEyMjMyMzAxMDFaMIHMMUkwRwYDVQQLDEDQptC1" + "0L3RgtGA0LDQu9GM0L3QuNC5INC30LDRgdCy0ZbQtNGH0YPQstCw0LvRjNC90LjQ" + "uSDQvtGA0LPQsNC9MTUwMwYDVQQDDCzQo9C60YDQsNGX0L3QsCwg0KbQl9CeIC8g" + "VWtyYWluZSwgQ2VudHJhbCBDQTELMAkGA1UEBhMCVUExETAPBgNVBAcMCNCa0LjR" + "l9CyMSgwJgYDVQQIDB/QmtC40ZfQstGB0YzQutCwINC+0LHQu9Cw0YHRgtGMMIIB" + "UTCCARIGCyqGJAIBAQEBAwEBMIIBATCBvDAPAgIBrzAJAgEBAgEDAgEFAgEBBDbz" + "ykDGaaTaFzFJyhLDLa4Ya1Osa8Y2WZferq6K0tiI+b/VNAFpTvnEJz2M/m3Cj3Bq" + "D0kQzgMCNj///////////////////////////////////7oxdUWACajApyTwL4Gq" + "ih/Lr4DZDHqVEQUEzwQ2lqAgR9+skUI33jGNgj2Qsh9+3x7so5koelwr4fy89k/x" + "5eqNSvFZ/1fPHfXz+iz7PmFIhr15BECLwhftNllK8B904j3LmmBY/teFIBSrw2lL" + "CKc1nWIez+h/01q0GSxgeuwU0oOw9WmwlkGuj13DJ8cSmm70jTULAzkABDa6vb3U" + "VIxZr2cXcVSvKkPM65Ii2+8biqyoH8i9e0NKJu+IhjDvUrvzlr8U+ywuf5bpSj4N" + "fEmjezB5MA4GA1UdDwEB/wQEAwIBxjAPBgNVHRMBAf8EBTADAQH/MCsGA1UdIwQk" + "MCKAIOPEn/xcXE6VGFNB8vbfXS1XMYYzAa4ML8opsOslTHJNMCkGA1UdDgQiBCDj" + "xJ/8XFxOlRhTQfL2310tVzGGMwGuDC/KKbDrJUxyTTANBgsqhiQCAQEBAQMBAQNv" + "AARsh0unjBfQoINx2rXAJggrBdoRsCouw8lN771DhcuUrlQUuEEQHTaZrQoYbECu" + "AGfsxfTyldQDEOVzD/Uq8Xh4gIHuSqki9mRSjMR19MQtTKRmI9TRHIeTdIZ6l3P7" + "jFfGJvTP0E9NYSolx+kM"); private PublicKey dudPublicKey = new PublicKey() { public String getAlgorithm() { return null; } public String getFormat() { return null; } public byte[] getEncoded() { return null; } }; public String getName() { return "CertTest"; } public void checkCertificate( int id, byte[] bytes) { ByteArrayInputStream bIn; String dump = ""; try { bIn = new ByteArrayInputStream(bytes); CertificateFactory fact = CertificateFactory.getInstance("X.509", "BC"); Certificate cert = fact.generateCertificate(bIn); PublicKey k = cert.getPublicKey(); // System.out.println(cert); } catch (Exception e) { fail(dump + System.getProperty("line.separator") + getName() + ": "+ id + " failed - exception " + e.toString(), e); } } public void checkNameCertificate( int id, byte[] bytes) { ByteArrayInputStream bIn; String dump = ""; try { bIn = new ByteArrayInputStream(bytes); CertificateFactory fact = CertificateFactory.getInstance("X.509", "BC"); X509Certificate cert = (X509Certificate)fact.generateCertificate(bIn); PublicKey k = cert.getPublicKey(); if (!cert.getIssuerDN().toString().equals("C=DE,O=DATEV eG,0.2.262.1.10.7.20=1+CN=CA DATEV D03 1:PN")) { fail(id + " failed - name test."); } // System.out.println(cert); } catch (Exception e) { fail(dump + System.getProperty("line.separator") + getName() + ": "+ id + " failed - exception " + e.toString(), e); } } public void checkKeyUsage( int id, byte[] bytes) { ByteArrayInputStream bIn; String dump = ""; try { bIn = new ByteArrayInputStream(bytes); CertificateFactory fact = CertificateFactory.getInstance("X.509", "BC"); X509Certificate cert = (X509Certificate)fact.generateCertificate(bIn); PublicKey k = cert.getPublicKey(); if (cert.getKeyUsage()[7]) { fail("error generating cert - key usage wrong."); } // System.out.println(cert); } catch (Exception e) { fail(dump + System.getProperty("line.separator") + getName() + ": "+ id + " failed - exception " + e.toString(), e); } } public void checkSelfSignedCertificate( int id, byte[] bytes) { ByteArrayInputStream bIn; String dump = ""; try { bIn = new ByteArrayInputStream(bytes); CertificateFactory fact = CertificateFactory.getInstance("X.509", "BC"); Certificate cert = fact.generateCertificate(bIn); PublicKey k = cert.getPublicKey(); cert.verify(k); // System.out.println(cert); } catch (Exception e) { fail(dump + System.getProperty("line.separator") + getName() + ": "+ id + " failed - exception " + e.toString(), e); } } /** * we generate a self signed certificate for the sake of testing - RSA */ public void checkCreation1() throws Exception { // // a sample key pair. // RSAPublicKeySpec pubKeySpec = new RSAPublicKeySpec( new BigInteger("b4a7e46170574f16a97082b22be58b6a2a629798419be12872a4bdba626cfae9900f76abfb12139dce5de56564fab2b6543165a040c606887420e33d91ed7ed7", 16), new BigInteger("11", 16)); RSAPrivateCrtKeySpec privKeySpec = new RSAPrivateCrtKeySpec( new BigInteger("b4a7e46170574f16a97082b22be58b6a2a629798419be12872a4bdba626cfae9900f76abfb12139dce5de56564fab2b6543165a040c606887420e33d91ed7ed7", 16), new BigInteger("11", 16), new BigInteger("9f66f6b05410cd503b2709e88115d55daced94d1a34d4e32bf824d0dde6028ae79c5f07b580f5dce240d7111f7ddb130a7945cd7d957d1920994da389f490c89", 16), new BigInteger("c0a0758cdf14256f78d4708c86becdead1b50ad4ad6c5c703e2168fbf37884cb", 16), new BigInteger("f01734d7960ea60070f1b06f2bb81bfac48ff192ae18451d5e56c734a5aab8a5", 16), new BigInteger("b54bb9edff22051d9ee60f9351a48591b6500a319429c069a3e335a1d6171391", 16), new BigInteger("d3d83daf2a0cecd3367ae6f8ae1aeb82e9ac2f816c6fc483533d8297dd7884cd", 16), new BigInteger("b8f52fc6f38593dabb661d3f50f8897f8106eee68b1bce78a95b132b4e5b5d19", 16)); // // set up the keys // PrivateKey privKey; PublicKey pubKey; KeyFactory fact = KeyFactory.getInstance("RSA", "BC"); privKey = fact.generatePrivate(privKeySpec); pubKey = fact.generatePublic(pubKeySpec); // // distinguished name table. // Vector ord = new Vector(); Vector values = new Vector(); ord.addElement(X509Principal.C); ord.addElement(X509Principal.O); ord.addElement(X509Principal.L); ord.addElement(X509Principal.ST); ord.addElement(X509Principal.E); values.addElement("AU"); values.addElement("The Legion of the Bouncy Castle"); values.addElement("Melbourne"); values.addElement("Victoria"); values.addElement("feedback-crypto@bouncycastle.org"); // // extensions // // // create the certificate - version 3 - without extensions // X509V3CertificateGenerator certGen = new X509V3CertificateGenerator(); certGen.setSerialNumber(BigInteger.valueOf(1)); certGen.setIssuerDN(new X509Principal(ord, values)); certGen.setNotBefore(new Date(System.currentTimeMillis() - 50000)); certGen.setNotAfter(new Date(System.currentTimeMillis() + 50000)); certGen.setSubjectDN(new X509Principal(ord, values)); certGen.setPublicKey(pubKey); certGen.setSignatureAlgorithm("SHA256WithRSAEncryption"); X509Certificate cert = certGen.generate(privKey); cert.checkValidity(new Date()); cert.verify(pubKey); Set dummySet = cert.getNonCriticalExtensionOIDs(); if (dummySet != null) { fail("non-critical oid set should be null"); } dummySet = cert.getCriticalExtensionOIDs(); if (dummySet != null) { fail("critical oid set should be null"); } // // create the certificate - version 3 - with extensions // certGen = new X509V3CertificateGenerator(); certGen.setSerialNumber(BigInteger.valueOf(1)); certGen.setIssuerDN(new X509Principal(ord, values)); certGen.setNotBefore(new Date(System.currentTimeMillis() - 50000)); certGen.setNotAfter(new Date(System.currentTimeMillis() + 50000)); certGen.setSubjectDN(new X509Principal(ord, values)); certGen.setPublicKey(pubKey); certGen.setSignatureAlgorithm("MD5WithRSAEncryption"); certGen.addExtension("2.5.29.15", true, new X509KeyUsage(X509KeyUsage.encipherOnly)); certGen.addExtension("2.5.29.37", true, new DERSequence(KeyPurposeId.anyExtendedKeyUsage)); certGen.addExtension("2.5.29.17", true, new GeneralNames(new GeneralName(GeneralName.rfc822Name, "test@test.test"))); cert = certGen.generate(privKey); cert.checkValidity(new Date()); cert.verify(pubKey); ByteArrayInputStream sbIn = new ByteArrayInputStream(cert.getEncoded()); ASN1InputStream sdIn = new ASN1InputStream(sbIn); ByteArrayInputStream bIn = new ByteArrayInputStream(cert.getEncoded()); CertificateFactory certFact = CertificateFactory.getInstance("X.509", "BC"); cert = (X509Certificate)certFact.generateCertificate(bIn); if (!cert.getKeyUsage()[7]) { fail("error generating cert - key usage wrong."); } List l = cert.getExtendedKeyUsage(); if (!l.get(0).equals(KeyPurposeId.anyExtendedKeyUsage.getId())) { fail("failed extended key usage test"); } Collection c = cert.getSubjectAlternativeNames(); Iterator it = c.iterator(); while (it.hasNext()) { List gn = (List)it.next(); if (!gn.get(1).equals("test@test.test")) { fail("failed subject alternative names test"); } } // System.out.println(cert); // // create the certificate - version 1 // X509V1CertificateGenerator certGen1 = new X509V1CertificateGenerator(); certGen1.setSerialNumber(BigInteger.valueOf(1)); certGen1.setIssuerDN(new X509Principal(ord, values)); certGen1.setNotBefore(new Date(System.currentTimeMillis() - 50000)); certGen1.setNotAfter(new Date(System.currentTimeMillis() + 50000)); certGen1.setSubjectDN(new X509Principal(ord, values)); certGen1.setPublicKey(pubKey); certGen1.setSignatureAlgorithm("MD5WithRSAEncryption"); cert = certGen1.generate(privKey); cert.checkValidity(new Date()); cert.verify(pubKey); bIn = new ByteArrayInputStream(cert.getEncoded()); certFact = CertificateFactory.getInstance("X.509", "BC"); cert = (X509Certificate)certFact.generateCertificate(bIn); // System.out.println(cert); if (!cert.getIssuerDN().equals(cert.getSubjectDN())) { fail("name comparison fails"); } } /** * we generate a self signed certificate for the sake of testing - DSA */ public void checkCreation2() { // // set up the keys // PrivateKey privKey; PublicKey pubKey; try { KeyPairGenerator g = KeyPairGenerator.getInstance("DSA", "SUN"); g.initialize(512, new SecureRandom()); KeyPair p = g.generateKeyPair(); privKey = p.getPrivate(); pubKey = p.getPublic(); } catch (Exception e) { fail("error setting up keys - " + e.toString()); return; } // // distinguished name table. // Vector ord = new Vector(); Vector values = new Vector(); ord.addElement(X509Principal.C); ord.addElement(X509Principal.O); ord.addElement(X509Principal.L); ord.addElement(X509Principal.ST); ord.addElement(X509Principal.E); values.addElement("AU"); values.addElement("The Legion of the Bouncy Castle"); values.addElement("Melbourne"); values.addElement("Victoria"); values.addElement("feedback-crypto@bouncycastle.org"); // // extensions // // // create the certificate - version 3 // X509V3CertificateGenerator certGen = new X509V3CertificateGenerator(); certGen.setSerialNumber(BigInteger.valueOf(1)); certGen.setIssuerDN(new X509Principal(ord, values)); certGen.setNotBefore(new Date(System.currentTimeMillis() - 50000)); certGen.setNotAfter(new Date(System.currentTimeMillis() + 50000)); certGen.setSubjectDN(new X509Principal(ord, values)); certGen.setPublicKey(pubKey); certGen.setSignatureAlgorithm("SHA1withDSA"); try { X509Certificate cert = certGen.generate(privKey); cert.checkValidity(new Date()); cert.verify(pubKey); ByteArrayInputStream bIn = new ByteArrayInputStream(cert.getEncoded()); CertificateFactory fact = CertificateFactory.getInstance("X.509", "BC"); cert = (X509Certificate)fact.generateCertificate(bIn); // System.out.println(cert); } catch (Exception e) { fail("error setting generating cert - " + e.toString()); } // // create the certificate - version 1 // X509V1CertificateGenerator certGen1 = new X509V1CertificateGenerator(); certGen1.setSerialNumber(BigInteger.valueOf(1)); certGen1.setIssuerDN(new X509Principal(ord, values)); certGen1.setNotBefore(new Date(System.currentTimeMillis() - 50000)); certGen1.setNotAfter(new Date(System.currentTimeMillis() + 50000)); certGen1.setSubjectDN(new X509Principal(ord, values)); certGen1.setPublicKey(pubKey); certGen1.setSignatureAlgorithm("SHA1withDSA"); try { X509Certificate cert = certGen1.generate(privKey); cert.checkValidity(new Date()); cert.verify(pubKey); ByteArrayInputStream bIn = new ByteArrayInputStream(cert.getEncoded()); CertificateFactory fact = CertificateFactory.getInstance("X.509", "BC"); cert = (X509Certificate)fact.generateCertificate(bIn); //System.out.println(cert); } catch (Exception e) { fail("error setting generating cert - " + e.toString()); } // // exception test // try { certGen.setPublicKey(dudPublicKey); fail("key without encoding not detected in v1"); } catch (IllegalArgumentException e) { // expected } } /** * we generate a self signed certificate for the sake of testing - ECDSA */ public void checkCreation3() { ECCurve curve = new ECCurve.Fp( new BigInteger("883423532389192164791648750360308885314476597252960362792450860609699839"), // q new BigInteger("7fffffffffffffffffffffff7fffffffffff8000000000007ffffffffffc", 16), // a new BigInteger("6b016c3bdcf18941d0d654921475ca71a9db2fb27d1d37796185c2942c0a", 16)); // b ECParameterSpec spec = new ECParameterSpec( curve, curve.decodePoint(Hex.decode("020ffa963cdca8816ccc33b8642bedf905c3d358573d3f27fbbd3b3cb9aaaf")), // G new BigInteger("883423532389192164791648750360308884807550341691627752275345424702807307")); // n ECPrivateKeySpec privKeySpec = new ECPrivateKeySpec( new BigInteger("876300101507107567501066130761671078357010671067781776716671676178726717"), // d spec); ECPublicKeySpec pubKeySpec = new ECPublicKeySpec( curve.decodePoint(Hex.decode("025b6dc53bc61a2548ffb0f671472de6c9521a9d2d2534e65abfcbd5fe0c70")), // Q spec); // // set up the keys // PrivateKey privKey; PublicKey pubKey; try { KeyFactory fact = KeyFactory.getInstance("ECDSA", "BC"); privKey = fact.generatePrivate(privKeySpec); pubKey = fact.generatePublic(pubKeySpec); } catch (Exception e) { fail("error setting up keys - " + e.toString()); return; } // // distinguished name table. // Hashtable attrs = new Hashtable(); Vector order = new Vector(); attrs.put(X509Principal.C, "AU"); attrs.put(X509Principal.O, "The Legion of the Bouncy Castle"); attrs.put(X509Principal.L, "Melbourne"); attrs.put(X509Principal.ST, "Victoria"); attrs.put(X509Principal.E, "feedback-crypto@bouncycastle.org"); order.addElement(X509Principal.C); order.addElement(X509Principal.O); order.addElement(X509Principal.L); order.addElement(X509Principal.ST); order.addElement(X509Principal.E); // // toString test // X509Principal p = new X509Principal(order, attrs); String s = p.toString(); if (!s.equals("C=AU,O=The Legion of the Bouncy Castle,L=Melbourne,ST=Victoria,E=feedback-crypto@bouncycastle.org")) { fail("ordered X509Principal test failed - s = " + s + "."); } // p = new X509Principal(attrs); // s = p.toString(); // // // // // we need two of these as the hash code for strings changed... // // // if (!s.equals("O=The Legion of the Bouncy Castle,E=feedback-crypto@bouncycastle.org,ST=Victoria,L=Melbourne,C=AU") && !s.equals("ST=Victoria,L=Melbourne,C=AU,E=feedback-crypto@bouncycastle.org,O=The Legion of the Bouncy Castle")) // { // fail("unordered X509Principal test failed."); // } // // create the certificate - version 3 // X509V3CertificateGenerator certGen = new X509V3CertificateGenerator(); certGen.setSerialNumber(BigInteger.valueOf(1)); certGen.setIssuerDN(new X509Principal(order, attrs)); certGen.setNotBefore(new Date(System.currentTimeMillis() - 50000)); certGen.setNotAfter(new Date(System.currentTimeMillis() + 50000)); certGen.setSubjectDN(new X509Principal(order, attrs)); certGen.setPublicKey(pubKey); certGen.setSignatureAlgorithm("SHA1withECDSA"); try { X509Certificate cert = certGen.generate(privKey); cert.checkValidity(new Date()); cert.verify(pubKey); ByteArrayInputStream bIn = new ByteArrayInputStream(cert.getEncoded()); CertificateFactory fact = CertificateFactory.getInstance("X.509", "BC"); cert = (X509Certificate)fact.generateCertificate(bIn); // // try with point compression turned off // ((ECPointEncoder)pubKey).setPointFormat("UNCOMPRESSED"); certGen.setPublicKey(pubKey); cert = certGen.generate(privKey, "BC"); cert.checkValidity(new Date()); cert.verify(pubKey); bIn = new ByteArrayInputStream(cert.getEncoded()); fact = CertificateFactory.getInstance("X.509", "BC"); cert = (X509Certificate)fact.generateCertificate(bIn); // System.out.println(cert); } catch (Exception e) { fail("error setting generating cert - " + e.toString()); } X509Principal pr = new X509Principal("O=\"The Bouncy Castle, The Legion of\",E=feedback-crypto@bouncycastle.org,ST=Victoria,L=Melbourne,C=AU"); if (!pr.toString().equals("O=The Bouncy Castle\\, The Legion of,E=feedback-crypto@bouncycastle.org,ST=Victoria,L=Melbourne,C=AU")) { fail("string based X509Principal test failed."); } pr = new X509Principal("O=The Bouncy Castle\\, The Legion of,E=feedback-crypto@bouncycastle.org,ST=Victoria,L=Melbourne,C=AU"); if (!pr.toString().equals("O=The Bouncy Castle\\, The Legion of,E=feedback-crypto@bouncycastle.org,ST=Victoria,L=Melbourne,C=AU")) { fail("string based X509Principal test failed."); } } /** * we generate a self signed certificate for the sake of testing - SHA224withECDSA */ private void createECCert(String algorithm, DERObjectIdentifier algOid) throws Exception { ECCurve.Fp curve = new ECCurve.Fp( new BigInteger("6864797660130609714981900799081393217269435300143305409394463459185543183397656052122559640661454554977296311391480858037121987999716643812574028291115057151"), // q (or p) new BigInteger("01FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFC", 16), // a new BigInteger("0051953EB9618E1C9A1F929A21A0B68540EEA2DA725B99B315F3B8B489918EF109E156193951EC7E937B1652C0BD3BB1BF073573DF883D2C34F1EF451FD46B503F00", 16)); // b ECParameterSpec spec = new ECParameterSpec( curve, curve.decodePoint(Hex.decode("0200C6858E06B70404E9CD9E3ECB662395B4429C648139053FB521F828AF606B4D3DBAA14B5E77EFE75928FE1DC127A2FFA8DE3348B3C1856A429BF97E7E31C2E5BD66")), // G new BigInteger("01FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFA51868783BF2F966B7FCC0148F709A5D03BB5C9B8899C47AEBB6FB71E91386409", 16)); // n ECPrivateKeySpec privKeySpec = new ECPrivateKeySpec( new BigInteger("5769183828869504557786041598510887460263120754767955773309066354712783118202294874205844512909370791582896372147797293913785865682804434049019366394746072023"), // d spec); ECPublicKeySpec pubKeySpec = new ECPublicKeySpec( curve.decodePoint(Hex.decode("02006BFDD2C9278B63C92D6624F151C9D7A822CC75BD983B17D25D74C26740380022D3D8FAF304781E416175EADF4ED6E2B47142D2454A7AC7801DD803CF44A4D1F0AC")), // Q spec); // // set up the keys // PrivateKey privKey; PublicKey pubKey; KeyFactory fact = KeyFactory.getInstance("ECDSA", "BC"); privKey = fact.generatePrivate(privKeySpec); pubKey = fact.generatePublic(pubKeySpec); // // distinguished name table. // Hashtable attrs = new Hashtable(); Vector order = new Vector(); attrs.put(X509Principal.C, "AU"); attrs.put(X509Principal.O, "The Legion of the Bouncy Castle"); attrs.put(X509Principal.L, "Melbourne"); attrs.put(X509Principal.ST, "Victoria"); attrs.put(X509Principal.E, "feedback-crypto@bouncycastle.org"); order.addElement(X509Principal.C); order.addElement(X509Principal.O); order.addElement(X509Principal.L); order.addElement(X509Principal.ST); order.addElement(X509Principal.E); // // create the certificate - version 3 // X509V3CertificateGenerator certGen = new X509V3CertificateGenerator(); certGen.setSerialNumber(BigInteger.valueOf(1)); certGen.setIssuerDN(new X509Principal(order, attrs)); certGen.setNotBefore(new Date(System.currentTimeMillis() - 50000)); certGen.setNotAfter(new Date(System.currentTimeMillis() + 50000)); certGen.setSubjectDN(new X509Principal(order, attrs)); certGen.setPublicKey(pubKey); certGen.setSignatureAlgorithm(algorithm); X509Certificate cert = certGen.generate(privKey, "BC"); cert.checkValidity(new Date()); cert.verify(pubKey); ByteArrayInputStream bIn = new ByteArrayInputStream(cert.getEncoded()); CertificateFactory certFact = CertificateFactory.getInstance("X.509", "BC"); cert = (X509Certificate)certFact.generateCertificate(bIn); // // try with point compression turned off // ((ECPointEncoder)pubKey).setPointFormat("UNCOMPRESSED"); certGen.setPublicKey(pubKey); cert = certGen.generate(privKey, "BC"); cert.checkValidity(new Date()); cert.verify(pubKey); bIn = new ByteArrayInputStream(cert.getEncoded()); certFact = CertificateFactory.getInstance("X.509", "BC"); cert = (X509Certificate)certFact.generateCertificate(bIn); if (!cert.getSigAlgOID().equals(algOid.toString())) { fail("ECDSA oid incorrect."); } if (cert.getSigAlgParams() != null) { fail("sig parameters present"); } Signature sig = Signature.getInstance(algorithm, "BC"); sig.initVerify(pubKey); sig.update(cert.getTBSCertificate()); if (!sig.verify(cert.getSignature())) { fail("EC certificate signature not mapped correctly."); } // System.out.println(cert); } private void checkCRL( int id, byte[] bytes) { ByteArrayInputStream bIn; String dump = ""; try { bIn = new ByteArrayInputStream(bytes); CertificateFactory fact = CertificateFactory.getInstance("X.509", "BC"); CRL cert = fact.generateCRL(bIn); // System.out.println(cert); } catch (Exception e) { fail(dump + System.getProperty("line.separator") + getName() + ": "+ id + " failed - exception " + e.toString(), e); } } public void checkCRLCreation1() throws Exception { KeyPairGenerator kpGen = KeyPairGenerator.getInstance("RSA", "BC"); X509V2CRLGenerator crlGen = new X509V2CRLGenerator(); Date now = new Date(); KeyPair pair = kpGen.generateKeyPair(); crlGen.setIssuerDN(new X500Principal("CN=Test CA")); crlGen.setThisUpdate(now); crlGen.setNextUpdate(new Date(now.getTime() + 100000)); crlGen.setSignatureAlgorithm("SHA256WithRSAEncryption"); crlGen.addCRLEntry(BigInteger.ONE, now, CRLReason.privilegeWithdrawn); crlGen.addExtension(X509Extensions.AuthorityKeyIdentifier, false, new AuthorityKeyIdentifierStructure(pair.getPublic())); X509CRL crl = crlGen.generate(pair.getPrivate(), "BC"); if (!crl.getIssuerX500Principal().equals(new X500Principal("CN=Test CA"))) { fail("failed CRL issuer test"); } byte[] authExt = crl.getExtensionValue(X509Extensions.AuthorityKeyIdentifier.getId()); if (authExt == null) { fail("failed to find CRL extension"); } AuthorityKeyIdentifier authId = new AuthorityKeyIdentifierStructure(authExt); X509CRLEntry entry = crl.getRevokedCertificate(BigInteger.ONE); if (entry == null) { fail("failed to find CRL entry"); } if (!entry.getSerialNumber().equals(BigInteger.ONE)) { fail("CRL cert serial number does not match"); } if (!entry.hasExtensions()) { fail("CRL entry extension not found"); } byte[] ext = entry.getExtensionValue(X509Extensions.ReasonCode.getId()); if (ext != null) { DEREnumerated reasonCode = (DEREnumerated)X509ExtensionUtil.fromExtensionValue(ext); if (reasonCode.getValue().intValue() != CRLReason.privilegeWithdrawn) { fail("CRL entry reasonCode wrong"); } } else { fail("CRL entry reasonCode not found"); } } public void checkCRLCreation2() throws Exception { KeyPairGenerator kpGen = KeyPairGenerator.getInstance("RSA", "BC"); X509V2CRLGenerator crlGen = new X509V2CRLGenerator(); Date now = new Date(); KeyPair pair = kpGen.generateKeyPair(); crlGen.setIssuerDN(new X500Principal("CN=Test CA")); crlGen.setThisUpdate(now); crlGen.setNextUpdate(new Date(now.getTime() + 100000)); crlGen.setSignatureAlgorithm("SHA256WithRSAEncryption"); Vector extOids = new Vector(); Vector extValues = new Vector(); CRLReason crlReason = CRLReason.lookup(CRLReason.privilegeWithdrawn); try { extOids.addElement(X509Extensions.ReasonCode); extValues.addElement(new X509Extension(false, new DEROctetString(crlReason.getEncoded()))); } catch (IOException e) { throw new IllegalArgumentException("error encoding reason: " + e); } X509Extensions entryExtensions = new X509Extensions(extOids, extValues); crlGen.addCRLEntry(BigInteger.ONE, now, entryExtensions); crlGen.addExtension(X509Extensions.AuthorityKeyIdentifier, false, new AuthorityKeyIdentifierStructure(pair.getPublic())); X509CRL crl = crlGen.generate(pair.getPrivate(), "BC"); if (!crl.getIssuerX500Principal().equals(new X500Principal("CN=Test CA"))) { fail("failed CRL issuer test"); } byte[] authExt = crl.getExtensionValue(X509Extensions.AuthorityKeyIdentifier.getId()); if (authExt == null) { fail("failed to find CRL extension"); } AuthorityKeyIdentifier authId = new AuthorityKeyIdentifierStructure(authExt); X509CRLEntry entry = crl.getRevokedCertificate(BigInteger.ONE); if (entry == null) { fail("failed to find CRL entry"); } if (!entry.getSerialNumber().equals(BigInteger.ONE)) { fail("CRL cert serial number does not match"); } if (!entry.hasExtensions()) { fail("CRL entry extension not found"); } byte[] ext = entry.getExtensionValue(X509Extensions.ReasonCode.getId()); if (ext != null) { DEREnumerated reasonCode = (DEREnumerated)X509ExtensionUtil.fromExtensionValue(ext); if (reasonCode.getValue().intValue() != CRLReason.privilegeWithdrawn) { fail("CRL entry reasonCode wrong"); } } else { fail("CRL entry reasonCode not found"); } } public void checkCRLCreation3() throws Exception { KeyPairGenerator kpGen = KeyPairGenerator.getInstance("RSA", "BC"); X509V2CRLGenerator crlGen = new X509V2CRLGenerator(); Date now = new Date(); KeyPair pair = kpGen.generateKeyPair(); crlGen.setIssuerDN(new X500Principal("CN=Test CA")); crlGen.setThisUpdate(now); crlGen.setNextUpdate(new Date(now.getTime() + 100000)); crlGen.setSignatureAlgorithm("SHA256WithRSAEncryption"); Vector extOids = new Vector(); Vector extValues = new Vector(); CRLReason crlReason = CRLReason.lookup(CRLReason.privilegeWithdrawn); try { extOids.addElement(X509Extensions.ReasonCode); extValues.addElement(new X509Extension(false, new DEROctetString(crlReason.getEncoded()))); } catch (IOException e) { throw new IllegalArgumentException("error encoding reason: " + e); } X509Extensions entryExtensions = new X509Extensions(extOids, extValues); crlGen.addCRLEntry(BigInteger.ONE, now, entryExtensions); crlGen.addExtension(X509Extensions.AuthorityKeyIdentifier, false, new AuthorityKeyIdentifierStructure(pair.getPublic())); X509CRL crl = crlGen.generate(pair.getPrivate(), "BC"); if (!crl.getIssuerX500Principal().equals(new X500Principal("CN=Test CA"))) { fail("failed CRL issuer test"); } byte[] authExt = crl.getExtensionValue(X509Extensions.AuthorityKeyIdentifier.getId()); if (authExt == null) { fail("failed to find CRL extension"); } AuthorityKeyIdentifier authId = new AuthorityKeyIdentifierStructure(authExt); X509CRLEntry entry = crl.getRevokedCertificate(BigInteger.ONE); if (entry == null) { fail("failed to find CRL entry"); } if (!entry.getSerialNumber().equals(BigInteger.ONE)) { fail("CRL cert serial number does not match"); } if (!entry.hasExtensions()) { fail("CRL entry extension not found"); } byte[] ext = entry.getExtensionValue(X509Extensions.ReasonCode.getId()); if (ext != null) { DEREnumerated reasonCode = (DEREnumerated)X509ExtensionUtil.fromExtensionValue(ext); if (reasonCode.getValue().intValue() != CRLReason.privilegeWithdrawn) { fail("CRL entry reasonCode wrong"); } } else { fail("CRL entry reasonCode not found"); } // // check loading of existing CRL // crlGen = new X509V2CRLGenerator(); now = new Date(); crlGen.setIssuerDN(new X500Principal("CN=Test CA")); crlGen.setThisUpdate(now); crlGen.setNextUpdate(new Date(now.getTime() + 100000)); crlGen.setSignatureAlgorithm("SHA256WithRSAEncryption"); crlGen.addCRL(crl); crlGen.addCRLEntry(BigInteger.valueOf(2), now, entryExtensions); crlGen.addExtension(X509Extensions.AuthorityKeyIdentifier, false, new AuthorityKeyIdentifierStructure(pair.getPublic())); X509CRL newCrl = crlGen.generate(pair.getPrivate(), "BC"); int count = 0; boolean oneFound = false; boolean twoFound = false; Iterator it = newCrl.getRevokedCertificates().iterator(); while (it.hasNext()) { X509CRLEntry crlEnt = (X509CRLEntry)it.next(); if (crlEnt.getSerialNumber().intValue() == 1) { oneFound = true; } else if (crlEnt.getSerialNumber().intValue() == 2) { twoFound = true; } count++; } if (count != 2) { fail("wrong number of CRLs found"); } if (!oneFound || !twoFound) { fail("wrong CRLs found in copied list"); } // // check factory read back // CertificateFactory cFact = CertificateFactory.getInstance("X.509", "BC"); X509CRL readCrl = (X509CRL)cFact.generateCRL(new ByteArrayInputStream(newCrl.getEncoded())); if (readCrl == null) { fail("crl not returned!"); } Collection col = cFact.generateCRLs(new ByteArrayInputStream(newCrl.getEncoded())); if (col.size() != 1) { fail("wrong number of CRLs found in collection"); } } /** * we generate a self signed certificate for the sake of testing - GOST3410 */ public void checkCreation4() throws Exception { // // set up the keys // PrivateKey privKey; PublicKey pubKey; KeyPairGenerator g = KeyPairGenerator.getInstance("GOST3410", "BC"); GOST3410ParameterSpec gost3410P = new GOST3410ParameterSpec("GostR3410-94-CryptoPro-A"); g.initialize(gost3410P, new SecureRandom()); KeyPair p = g.generateKeyPair(); privKey = p.getPrivate(); pubKey = p.getPublic(); // // distinguished name table. // Hashtable attrs = new Hashtable(); Vector order = new Vector(); attrs.put(X509Principal.C, "AU"); attrs.put(X509Principal.O, "The Legion of the Bouncy Castle"); attrs.put(X509Principal.L, "Melbourne"); attrs.put(X509Principal.ST, "Victoria"); attrs.put(X509Principal.E, "feedback-crypto@bouncycastle.org"); order.addElement(X509Principal.C); order.addElement(X509Principal.O); order.addElement(X509Principal.L); order.addElement(X509Principal.ST); order.addElement(X509Principal.E); // // extensions // // // create the certificate - version 3 // X509V3CertificateGenerator certGen = new X509V3CertificateGenerator(); certGen.setSerialNumber(BigInteger.valueOf(1)); certGen.setIssuerDN(new X509Principal(order, attrs)); certGen.setNotBefore(new Date(System.currentTimeMillis() - 50000)); certGen.setNotAfter(new Date(System.currentTimeMillis() + 50000)); certGen.setSubjectDN(new X509Principal(order, attrs)); certGen.setPublicKey(pubKey); certGen.setSignatureAlgorithm("GOST3411withGOST3410"); X509Certificate cert = certGen.generate(privKey, "BC"); cert.checkValidity(new Date()); // // check verifies in general // cert.verify(pubKey); // // check verifies with contained key // cert.verify(cert.getPublicKey()); ByteArrayInputStream bIn = new ByteArrayInputStream(cert.getEncoded()); CertificateFactory fact = CertificateFactory.getInstance("X.509", "BC"); cert = (X509Certificate)fact.generateCertificate(bIn); //System.out.println(cert); //check getEncoded() byte[] bytesch = cert.getEncoded(); } public void checkCreation5() throws Exception { // // a sample key pair. // RSAPublicKeySpec pubKeySpec = new RSAPublicKeySpec( new BigInteger("b4a7e46170574f16a97082b22be58b6a2a629798419be12872a4bdba626cfae9900f76abfb12139dce5de56564fab2b6543165a040c606887420e33d91ed7ed7", 16), new BigInteger("11", 16)); RSAPrivateCrtKeySpec privKeySpec = new RSAPrivateCrtKeySpec( new BigInteger("b4a7e46170574f16a97082b22be58b6a2a629798419be12872a4bdba626cfae9900f76abfb12139dce5de56564fab2b6543165a040c606887420e33d91ed7ed7", 16), new BigInteger("11", 16), new BigInteger("9f66f6b05410cd503b2709e88115d55daced94d1a34d4e32bf824d0dde6028ae79c5f07b580f5dce240d7111f7ddb130a7945cd7d957d1920994da389f490c89", 16), new BigInteger("c0a0758cdf14256f78d4708c86becdead1b50ad4ad6c5c703e2168fbf37884cb", 16), new BigInteger("f01734d7960ea60070f1b06f2bb81bfac48ff192ae18451d5e56c734a5aab8a5", 16), new BigInteger("b54bb9edff22051d9ee60f9351a48591b6500a319429c069a3e335a1d6171391", 16), new BigInteger("d3d83daf2a0cecd3367ae6f8ae1aeb82e9ac2f816c6fc483533d8297dd7884cd", 16), new BigInteger("b8f52fc6f38593dabb661d3f50f8897f8106eee68b1bce78a95b132b4e5b5d19", 16)); // // set up the keys // SecureRandom rand = new SecureRandom(); PrivateKey privKey; PublicKey pubKey; KeyFactory fact = KeyFactory.getInstance("RSA", "BC"); privKey = fact.generatePrivate(privKeySpec); pubKey = fact.generatePublic(pubKeySpec); // // distinguished name table. // Vector ord = new Vector(); Vector values = new Vector(); ord.addElement(X509Principal.C); ord.addElement(X509Principal.O); ord.addElement(X509Principal.L); ord.addElement(X509Principal.ST); ord.addElement(X509Principal.E); values.addElement("AU"); values.addElement("The Legion of the Bouncy Castle"); values.addElement("Melbourne"); values.addElement("Victoria"); values.addElement("feedback-crypto@bouncycastle.org"); // // create base certificate - version 3 // X509V3CertificateGenerator certGen = new X509V3CertificateGenerator(); certGen.setSerialNumber(BigInteger.valueOf(1)); certGen.setIssuerDN(new X509Principal(ord, values)); certGen.setNotBefore(new Date(System.currentTimeMillis() - 50000)); certGen.setNotAfter(new Date(System.currentTimeMillis() + 50000)); certGen.setSubjectDN(new X509Principal(ord, values)); certGen.setPublicKey(pubKey); certGen.setSignatureAlgorithm("MD5WithRSAEncryption"); certGen.addExtension("2.5.29.15", true, new X509KeyUsage(X509KeyUsage.encipherOnly)); certGen.addExtension("2.5.29.37", true, new DERSequence(KeyPurposeId.anyExtendedKeyUsage)); certGen.addExtension("2.5.29.17", true, new GeneralNames(new GeneralName(GeneralName.rfc822Name, "test@test.test"))); X509Certificate baseCert = certGen.generate(privKey, "BC"); // // copy certificate // certGen = new X509V3CertificateGenerator(); certGen.setSerialNumber(BigInteger.valueOf(1)); certGen.setIssuerDN(new X509Principal(ord, values)); certGen.setNotBefore(new Date(System.currentTimeMillis() - 50000)); certGen.setNotAfter(new Date(System.currentTimeMillis() + 50000)); certGen.setSubjectDN(new X509Principal(ord, values)); certGen.setPublicKey(pubKey); certGen.setSignatureAlgorithm("MD5WithRSAEncryption"); certGen.copyAndAddExtension(new DERObjectIdentifier("2.5.29.15"), true, baseCert); certGen.copyAndAddExtension("2.5.29.37", false, baseCert); X509Certificate cert = certGen.generate(privKey, "BC"); cert.checkValidity(new Date()); cert.verify(pubKey); if (!areEqual(baseCert.getExtensionValue("2.5.29.15"), cert.getExtensionValue("2.5.29.15"))) { fail("2.5.29.15 differs"); } if (!areEqual(baseCert.getExtensionValue("2.5.29.37"), cert.getExtensionValue("2.5.29.37"))) { fail("2.5.29.37 differs"); } // // exception test // try { certGen.copyAndAddExtension("2.5.99.99", true, baseCert); fail("exception not thrown on dud extension copy"); } catch (CertificateParsingException e) { // expected } try { certGen.setPublicKey(dudPublicKey); certGen.generate(privKey, "BC"); fail("key without encoding not detected in v3"); } catch (IllegalArgumentException e) { // expected } } private void testForgedSignature() throws Exception { String cert = "MIIBsDCCAVoCAQYwDQYJKoZIhvcNAQEFBQAwYzELMAkGA1UEBhMCQVUxEzARBgNV" + "BAgTClF1ZWVuc2xhbmQxGjAYBgNVBAoTEUNyeXB0U29mdCBQdHkgTHRkMSMwIQYD" + "VQQDExpTZXJ2ZXIgdGVzdCBjZXJ0ICg1MTIgYml0KTAeFw0wNjA5MTEyMzU4NTVa" + "Fw0wNjEwMTEyMzU4NTVaMGMxCzAJBgNVBAYTAkFVMRMwEQYDVQQIEwpRdWVlbnNs" + "YW5kMRowGAYDVQQKExFDcnlwdFNvZnQgUHR5IEx0ZDEjMCEGA1UEAxMaU2VydmVy" + "IHRlc3QgY2VydCAoNTEyIGJpdCkwXDANBgkqhkiG9w0BAQEFAANLADBIAkEAn7PD" + "hCeV/xIxUg8V70YRxK2A5jZbD92A12GN4PxyRQk0/lVmRUNMaJdq/qigpd9feP/u" + "12S4PwTLb/8q/v657QIDAQABMA0GCSqGSIb3DQEBBQUAA0EAbynCRIlUQgaqyNgU" + "DF6P14yRKUtX8akOP2TwStaSiVf/akYqfLFm3UGka5XbPj4rifrZ0/sOoZEEBvHQ" + "e20sRA=="; CertificateFactory certFact = CertificateFactory.getInstance("X.509", "BC"); X509Certificate x509 = (X509Certificate)certFact.generateCertificate(new ByteArrayInputStream(Base64.decode(cert))); try { x509.verify(x509.getPublicKey()); fail("forged RSA signature passed"); } catch (Exception e) { // expected } } private void pemTest() throws Exception { CertificateFactory cf = CertificateFactory.getInstance("X.509", "BC"); Certificate cert = readPEMCert(cf, PEMData.CERTIFICATE_1); if (cert == null) { fail("PEM cert not read"); } cert = readPEMCert(cf, "-----BEGIN CERTIFICATE-----" + PEMData.CERTIFICATE_2); if (cert == null) { fail("PEM cert with extraneous header not read"); } CRL crl = cf.generateCRL(new ByteArrayInputStream(PEMData.CRL_1.getBytes("US-ASCII"))); if (crl == null) { fail("PEM crl not read"); } Collection col = cf.generateCertificates(new ByteArrayInputStream(PEMData.CERTIFICATE_2.getBytes("US-ASCII"))); if (col.size() != 1 || !col.contains(cert)) { fail("PEM cert collection not right"); } col = cf.generateCRLs(new ByteArrayInputStream(PEMData.CRL_2.getBytes("US-ASCII"))); if (col.size() != 1 || !col.contains(crl)) { fail("PEM crl collection not right"); } } private static Certificate readPEMCert(CertificateFactory cf, String pemData) throws CertificateException, UnsupportedEncodingException { return cf.generateCertificate(new ByteArrayInputStream(pemData.getBytes("US-ASCII"))); } private void pkcs7Test() throws Exception { ASN1EncodableVector certs = new ASN1EncodableVector(); certs.add(new ASN1InputStream(CertPathTest.rootCertBin).readObject()); certs.add(new DERTaggedObject(false, 2, new ASN1InputStream(AttrCertTest.attrCert).readObject())); ASN1EncodableVector crls = new ASN1EncodableVector(); crls.add(new ASN1InputStream(CertPathTest.rootCrlBin).readObject()); SignedData sigData = new SignedData(new DERSet(), new ContentInfo(CMSObjectIdentifiers.data, null), new DERSet(certs), new DERSet(crls), new DERSet()); ContentInfo info = new ContentInfo(CMSObjectIdentifiers.signedData, sigData); CertificateFactory cf = CertificateFactory.getInstance("X.509", "BC"); X509Certificate cert = (X509Certificate)cf.generateCertificate(new ByteArrayInputStream(info.getEncoded())); if (cert == null || !areEqual(cert.getEncoded(), certs.get(0).toASN1Primitive().getEncoded())) { fail("PKCS7 cert not read"); } X509CRL crl = (X509CRL)cf.generateCRL(new ByteArrayInputStream(info.getEncoded())); if (crl == null || !areEqual(crl.getEncoded(), crls.get(0).toASN1Primitive().getEncoded())) { fail("PKCS7 crl not read"); } Collection col = cf.generateCertificates(new ByteArrayInputStream(info.getEncoded())); if (col.size() != 1 || !col.contains(cert)) { fail("PKCS7 cert collection not right"); } col = cf.generateCRLs(new ByteArrayInputStream(info.getEncoded())); if (col.size() != 1 || !col.contains(crl)) { fail("PKCS7 crl collection not right"); } // data with no certificates or CRLs sigData = new SignedData(new DERSet(), new ContentInfo(CMSObjectIdentifiers.data, null), new DERSet(), new DERSet(), new DERSet()); info = new ContentInfo(CMSObjectIdentifiers.signedData, sigData); cert = (X509Certificate)cf.generateCertificate(new ByteArrayInputStream(info.getEncoded())); if (cert != null) { fail("PKCS7 cert present"); } crl = (X509CRL)cf.generateCRL(new ByteArrayInputStream(info.getEncoded())); if (crl != null) { fail("PKCS7 crl present"); } // data with absent certificates and CRLS sigData = new SignedData(new DERSet(), new ContentInfo(CMSObjectIdentifiers.data, null), null, null, new DERSet()); info = new ContentInfo(CMSObjectIdentifiers.signedData, sigData); cert = (X509Certificate)cf.generateCertificate(new ByteArrayInputStream(info.getEncoded())); if (cert != null) { fail("PKCS7 cert present"); } crl = (X509CRL)cf.generateCRL(new ByteArrayInputStream(info.getEncoded())); if (crl != null) { fail("PKCS7 crl present"); } // // sample message // InputStream in = new ByteArrayInputStream(pkcs7CrlProblem); Collection certCol = cf.generateCertificates(in); Collection crlCol = cf.generateCRLs(in); if (crlCol.size() != 0) { fail("wrong number of CRLs: " + crlCol.size()); } if (certCol.size() != 4) { fail("wrong number of Certs: " + certCol.size()); } } private void createPSSCert(String algorithm) throws Exception { KeyPair pair = generateLongFixedKeys(); PrivateKey privKey = pair.getPrivate(); PublicKey pubKey = pair.getPublic(); // // distinguished name table. // Vector ord = new Vector(); Vector values = new Vector(); ord.addElement(X509Principal.C); ord.addElement(X509Principal.O); ord.addElement(X509Principal.L); ord.addElement(X509Principal.ST); ord.addElement(X509Principal.E); values.addElement("AU"); values.addElement("The Legion of the Bouncy Castle"); values.addElement("Melbourne"); values.addElement("Victoria"); values.addElement("feedback-crypto@bouncycastle.org"); // // create base certificate - version 3 // X509V3CertificateGenerator certGen = new X509V3CertificateGenerator(); certGen.setSerialNumber(BigInteger.valueOf(1)); certGen.setIssuerDN(new X509Principal(ord, values)); certGen.setNotBefore(new Date(System.currentTimeMillis() - 50000)); certGen.setNotAfter(new Date(System.currentTimeMillis() + 50000)); certGen.setSubjectDN(new X509Principal(ord, values)); certGen.setPublicKey(pubKey); certGen.setSignatureAlgorithm(algorithm); certGen.addExtension("2.5.29.15", true, new X509KeyUsage(X509KeyUsage.encipherOnly)); certGen.addExtension("2.5.29.37", true, new DERSequence(KeyPurposeId.anyExtendedKeyUsage)); certGen.addExtension(Extension.subjectAlternativeName.getId(), true, new GeneralNames(new GeneralName(GeneralName.rfc822Name, "test@test.test"))); certGen.addExtension(Extension.issuerAlternativeName, false, new GeneralNames(new GeneralName(GeneralName.directoryName, new X500Name("O=Test, OU=Testing, C=AU")))); X509Certificate baseCert = certGen.generate(privKey, "BC"); Collection names = baseCert.getSubjectAlternativeNames(); if (names.size() != 1) { fail("subject alt names size incorrect"); } List name = (List)names.iterator().next(); if(!name.get(0).equals(Integers.valueOf(GeneralName.rfc822Name))) { fail("subject alt name type incorrect"); } names = baseCert.getIssuerAlternativeNames(); if (names.size() != 1) { fail("issuer alt names size incorrect"); } name = (List)names.iterator().next(); if(!name.get(0).equals(Integers.valueOf(GeneralName.directoryName))) { fail("issuer alt name type incorrect"); } // check IETF output (reverse of default BC) if (!name.get(1).equals("c=AU,ou=Testing,o=Test")) { fail("issuer alt name dir string incorrect"); } baseCert.verify(pubKey); } private KeyPair generateLongFixedKeys() throws NoSuchAlgorithmException, NoSuchProviderException, InvalidKeySpecException { RSAPublicKeySpec pubKeySpec = new RSAPublicKeySpec( new BigInteger("a56e4a0e701017589a5187dc7ea841d156f2ec0e36ad52a44dfeb1e61f7ad991d8c51056ffedb162b4c0f283a12a88a394dff526ab7291cbb307ceabfce0b1dfd5cd9508096d5b2b8b6df5d671ef6377c0921cb23c270a70e2598e6ff89d19f105acc2d3f0cb35f29280e1386b6f64c4ef22e1e1f20d0ce8cffb2249bd9a2137",16), new BigInteger("010001",16)); RSAPrivateCrtKeySpec privKeySpec = new RSAPrivateCrtKeySpec( new BigInteger("a56e4a0e701017589a5187dc7ea841d156f2ec0e36ad52a44dfeb1e61f7ad991d8c51056ffedb162b4c0f283a12a88a394dff526ab7291cbb307ceabfce0b1dfd5cd9508096d5b2b8b6df5d671ef6377c0921cb23c270a70e2598e6ff89d19f105acc2d3f0cb35f29280e1386b6f64c4ef22e1e1f20d0ce8cffb2249bd9a2137",16), new BigInteger("010001",16), new BigInteger("33a5042a90b27d4f5451ca9bbbd0b44771a101af884340aef9885f2a4bbe92e894a724ac3c568c8f97853ad07c0266c8c6a3ca0929f1e8f11231884429fc4d9ae55fee896a10ce707c3ed7e734e44727a39574501a532683109c2abacaba283c31b4bd2f53c3ee37e352cee34f9e503bd80c0622ad79c6dcee883547c6a3b325",16), new BigInteger("e7e8942720a877517273a356053ea2a1bc0c94aa72d55c6e86296b2dfc967948c0a72cbccca7eacb35706e09a1df55a1535bd9b3cc34160b3b6dcd3eda8e6443",16), new BigInteger("b69dca1cf7d4d7ec81e75b90fcca874abcde123fd2700180aa90479b6e48de8d67ed24f9f19d85ba275874f542cd20dc723e6963364a1f9425452b269a6799fd",16), new BigInteger("28fa13938655be1f8a159cbaca5a72ea190c30089e19cd274a556f36c4f6e19f554b34c077790427bbdd8dd3ede2448328f385d81b30e8e43b2fffa027861979",16), new BigInteger("1a8b38f398fa712049898d7fb79ee0a77668791299cdfa09efc0e507acb21ed74301ef5bfd48be455eaeb6e1678255827580a8e4e8e14151d1510a82a3f2e729",16), new BigInteger("27156aba4126d24a81f3a528cbfb27f56886f840a9f6e86e17a44b94fe9319584b8e22fdde1e5a2e3bd8aa5ba8d8584194eb2190acf832b847f13a3d24a79f4d",16)); KeyFactory fact = KeyFactory.getInstance("RSA", "BC"); return new KeyPair(fact.generatePublic(pubKeySpec), fact.generatePrivate(privKeySpec)); } private void rfc4491Test() throws Exception { CertificateFactory certFact = CertificateFactory.getInstance("X.509", "BC"); X509Certificate x509 = (X509Certificate)certFact.generateCertificate(new ByteArrayInputStream(gostRFC4491_94)); x509.verify(x509.getPublicKey(), "BC"); x509 = (X509Certificate)certFact.generateCertificate(new ByteArrayInputStream(gostRFC4491_2001)); x509.verify(x509.getPublicKey(), "BC"); } private void testNullDerNullCert() throws Exception { KeyPair pair = generateLongFixedKeys(); PublicKey pubKey = pair.getPublic(); PrivateKey privKey = pair.getPrivate(); X509V3CertificateGenerator certGen = new X509V3CertificateGenerator(); certGen.setSerialNumber(BigInteger.valueOf(1)); certGen.setIssuerDN(new X509Principal("CN=Test")); certGen.setNotBefore(new Date(System.currentTimeMillis() - 50000)); certGen.setNotAfter(new Date(System.currentTimeMillis() + 50000)); certGen.setSubjectDN(new X509Principal("CN=Test")); certGen.setPublicKey(pubKey); certGen.setSignatureAlgorithm("MD5WithRSAEncryption"); X509Certificate cert = certGen.generate(privKey, "BC"); X509CertificateStructure struct = X509CertificateStructure.getInstance(ASN1Primitive.fromByteArray(cert.getEncoded())); ASN1Encodable tbsCertificate = struct.getTBSCertificate(); AlgorithmIdentifier sig = struct.getSignatureAlgorithm(); ASN1EncodableVector v = new ASN1EncodableVector(); v.add(tbsCertificate); v.add(new AlgorithmIdentifier(sig.getObjectId())); v.add(struct.getSignature()); // verify ByteArrayInputStream bIn; String dump = ""; try { bIn = new ByteArrayInputStream(new DERSequence(v).getEncoded()); CertificateFactory fact = CertificateFactory.getInstance("X.509", "BC"); cert = (X509Certificate)fact.generateCertificate(bIn); cert.verify(cert.getPublicKey()); } catch (Exception e) { fail(dump + System.getProperty("line.separator") + getName() + ": testNullDerNull failed - exception " + e.toString(), e); } } private void checkComparison(byte[] encCert) throws NoSuchProviderException, CertificateException { CertificateFactory bcFact = CertificateFactory.getInstance("X.509", "BC"); CertificateFactory sunFact = CertificateFactory.getInstance("X.509", "SUN"); X509Certificate bcCert = (X509Certificate)bcFact.generateCertificate(new ByteArrayInputStream(encCert)); X509Certificate sunCert = (X509Certificate)sunFact.generateCertificate(new ByteArrayInputStream(encCert)); if (!bcCert.equals(sunCert) || !sunCert.equals(bcCert)) { fail("BC/Sun equals test failed"); } if (bcCert.hashCode() != sunCert.hashCode()) { fail("BC/Sun hashCode test failed"); } } private void testV1CRL() throws Exception { byte[] certData = Streams.readAll(this.getClass().getResourceAsStream("ThawteSGCCA.cer")); byte[] crlData = Streams.readAll(this.getClass().getResourceAsStream("ThawteSGCCA.crl")); // verify CRL with default (JCE) provider CertificateFactory jceFac = CertificateFactory.getInstance("X.509"); X509Certificate jceIssuer = (X509Certificate) jceFac.generateCertificate(new ByteArrayInputStream(certData)); X509CRL jceCRL = (X509CRL)jceFac.generateCRL(new ByteArrayInputStream(crlData)); jceCRL.verify(jceIssuer.getPublicKey()); // verify CRL with BC provider CertificateFactory bcFac = CertificateFactory.getInstance("X.509", "BC"); X509Certificate bcIssuer = (X509Certificate) bcFac.generateCertificate(new ByteArrayInputStream(certData)); X509CRL bcCRL = (X509CRL)bcFac.generateCRL(new ByteArrayInputStream(crlData)); jceCRL.verify(bcIssuer.getPublicKey()); bcCRL.verify(bcIssuer.getPublicKey()); } private void testCertPathEncAvailableTest() throws Exception { CertificateFactory certFact = CertificateFactory.getInstance("X.509", "BC"); Iterator it = certFact.getCertPathEncodings(); if (!"PkiPath".equals(it.next())) { fail("available enc 1 wrong"); } if (!"PEM".equals(it.next())) { fail("available enc 2 wrong"); } if (!"PKCS7".equals(it.next())) { fail("available enc 3 wrong"); } if (it.hasNext()) { fail("wrong number of encodings"); } } public void performTest() throws Exception { testV1CRL(); checkCertificate(1, cert1); checkCertificate(2, cert2); checkCertificate(3, cert3); checkCertificate(4, cert4); checkCertificate(5, cert5); checkCertificate(6, oldEcdsa); checkCertificate(7, cert7); checkComparison(cert1); checkKeyUsage(8, keyUsage); checkSelfSignedCertificate(9, uncompressedPtEC); checkNameCertificate(10, nameCert); checkSelfSignedCertificate(11, probSelfSignedCert); checkSelfSignedCertificate(12, gostCA1); checkSelfSignedCertificate(13, gostCA2); checkSelfSignedCertificate(14, gost341094base); checkSelfSignedCertificate(15, gost34102001base); checkSelfSignedCertificate(16, gost341094A); checkSelfSignedCertificate(17, gost341094B); checkSelfSignedCertificate(18, gost34102001A); try { checkSelfSignedCertificate(19, uaczo1); checkSelfSignedCertificate(20, uaczo2); checkSelfSignedCertificate(21, uaczo3); checkSelfSignedCertificate(22, uaczo4); } catch (Exception e) { if (e instanceof NoSuchAlgorithmException) { // ignore - only valid for jdk1.5+ } } checkCRL(1, crl1); checkCreation1(); checkCreation2(); checkCreation3(); checkCreation4(); checkCreation5(); createECCert("SHA1withECDSA", X9ObjectIdentifiers.ecdsa_with_SHA1); createECCert("SHA224withECDSA", X9ObjectIdentifiers.ecdsa_with_SHA224); createECCert("SHA256withECDSA", X9ObjectIdentifiers.ecdsa_with_SHA256); createECCert("SHA384withECDSA", X9ObjectIdentifiers.ecdsa_with_SHA384); createECCert("SHA512withECDSA", X9ObjectIdentifiers.ecdsa_with_SHA512); createPSSCert("SHA1withRSAandMGF1"); createPSSCert("SHA224withRSAandMGF1"); createPSSCert("SHA256withRSAandMGF1"); createPSSCert("SHA384withRSAandMGF1"); checkCRLCreation1(); checkCRLCreation2(); checkCRLCreation3(); pemTest(); pkcs7Test(); rfc4491Test(); testForgedSignature(); testNullDerNullCert(); checkCertificate(18, emptyDNCert); testCertPathEncAvailableTest(); } public static void main( String[] args) { Security.addProvider(new BouncyCastleProvider()); runTest(new CertTest()); } } bouncycastle-1.49.orig/test/src/org/bouncycastle/jce/provider/test/PKCS10CertRequestTest.java0000644000175000017500000005337612132450635031645 0ustar ebourgebourgpackage org.bouncycastle.jce.provider.test; import java.math.BigInteger; import java.security.KeyFactory; import java.security.KeyPair; import java.security.KeyPairGenerator; import java.security.PrivateKey; import java.security.PublicKey; import java.security.SecureRandom; import java.security.Security; import java.security.Signature; import java.security.spec.RSAPrivateCrtKeySpec; import java.security.spec.RSAPublicKeySpec; import java.util.Hashtable; import java.util.Vector; import org.bouncycastle.asn1.DERObjectIdentifier; import org.bouncycastle.asn1.DEROctetString; import org.bouncycastle.asn1.DERSet; import org.bouncycastle.asn1.cryptopro.CryptoProObjectIdentifiers; import org.bouncycastle.asn1.pkcs.Attribute; import org.bouncycastle.asn1.pkcs.PKCSObjectIdentifiers; import org.bouncycastle.asn1.x509.BasicConstraints; import org.bouncycastle.asn1.x509.KeyUsage; import org.bouncycastle.asn1.x509.SubjectKeyIdentifier; import org.bouncycastle.asn1.x509.X509Extension; import org.bouncycastle.asn1.x509.X509Extensions; import org.bouncycastle.asn1.x509.X509Name; import org.bouncycastle.asn1.x9.X9ObjectIdentifiers; import org.bouncycastle.jce.ECGOST3410NamedCurveTable; import org.bouncycastle.jce.ECNamedCurveTable; import org.bouncycastle.jce.PKCS10CertificationRequest; import org.bouncycastle.jce.X509Principal; import org.bouncycastle.jce.interfaces.ECPointEncoder; import org.bouncycastle.jce.provider.BouncyCastleProvider; import org.bouncycastle.jce.spec.ECNamedCurveParameterSpec; import org.bouncycastle.jce.spec.ECParameterSpec; import org.bouncycastle.jce.spec.ECPrivateKeySpec; import org.bouncycastle.jce.spec.ECPublicKeySpec; import org.bouncycastle.math.ec.ECCurve; import org.bouncycastle.util.encoders.Base64; import org.bouncycastle.util.encoders.Hex; import org.bouncycastle.util.test.SimpleTest; import org.bouncycastle.x509.extension.SubjectKeyIdentifierStructure; /** **/ public class PKCS10CertRequestTest extends SimpleTest { private byte[] gost3410EC_A = Base64.decode( "MIIBOzCB6wIBADB/MQ0wCwYDVQQDEwR0ZXN0MRUwEwYDVQQKEwxEZW1vcyBDbyBMdGQxHjAcBgNV" +"BAsTFUNyeXB0b2dyYXBoeSBkaXZpc2lvbjEPMA0GA1UEBxMGTW9zY293MQswCQYDVQQGEwJydTEZ" +"MBcGCSqGSIb3DQEJARYKc2RiQGRvbC5ydTBjMBwGBiqFAwICEzASBgcqhQMCAiMBBgcqhQMCAh4B" +"A0MABEBYx0P2D7YuuZo5HgdIAUKAXcLBDZ+4LYFgbKjrfStVfH59lc40BQ2FZ7M703hLpXK8GiBQ" +"GEYpKaAuQZnMIpByoAAwCAYGKoUDAgIDA0EAgXMcTrhdOY2Er2tHOSAgnMezqrYxocZTWhxmW5Rl" +"JY6lbXH5rndCn4swFzXU+YhgAsJv1wQBaoZEWRl5WV4/nA=="); private byte[] gost3410EC_B = Base64.decode( "MIIBPTCB7QIBADCBgDENMAsGA1UEAxMEdGVzdDEWMBQGA1UEChMNRGVtb3MgQ28gTHRkLjEeMBwG" +"A1UECxMVQ3J5cHRvZ3JhcGh5IGRpdmlzaW9uMQ8wDQYDVQQHEwZNb3Njb3cxCzAJBgNVBAYTAnJ1" +"MRkwFwYJKoZIhvcNAQkBFgpzZGJAZG9sLnJ1MGMwHAYGKoUDAgITMBIGByqFAwICIwIGByqFAwIC" +"HgEDQwAEQI5SLoWT7dZVilbV9j5B/fyIDuDs6x4pjqNC2TtFYbpRHrk/Wc5g/mcHvD80tsm5o1C7" +"7cizNzkvAVUM4VT4Dz6gADAIBgYqhQMCAgMDQQAoT5TwJ8o+bSrxckymyo3diwG7ZbSytX4sRiKy" +"wXPWRS9LlBvPO2NqwpS2HUnxSU8rzfL9fJcybATf7Yt1OEVq"); private byte[] gost3410EC_C = Base64.decode( "MIIBRDCB9AIBADCBhzEVMBMGA1UEAxMMdGVzdCByZXF1ZXN0MRUwEwYDVQQKEwxEZW1vcyBDbyBM" +"dGQxHjAcBgNVBAsTFUNyeXB0b2dyYXBoeSBkaXZpc2lvbjEPMA0GA1UEBxMGTW9zY293MQswCQYD" +"VQQGEwJydTEZMBcGCSqGSIb3DQEJARYKc2RiQGRvbC5ydTBjMBwGBiqFAwICEzASBgcqhQMCAiMD" +"BgcqhQMCAh4BA0MABEBcmGh7OmR4iqqj+ycYo1S1fS7r5PhisSQU2Ezuz8wmmmR2zeTZkdMYCOBa" +"UTMNms0msW3wuYDho7nTDNscHTB5oAAwCAYGKoUDAgIDA0EAVoOMbfyo1Un4Ss7WQrUjHJoiaYW8" +"Ime5LeGGU2iW3ieAv6es/FdMrwTKkqn5dhd3aL/itFg5oQbhyfXw5yw/QQ=="); private byte[] gost3410EC_ExA = Base64.decode( "MIIBOzCB6wIBADB/MQ0wCwYDVQQDEwR0ZXN0MRUwEwYDVQQKEwxEZW1vcyBDbyBMdGQxHjAcBgNV" + "BAsTFUNyeXB0b2dyYXBoeSBkaXZpc2lvbjEPMA0GA1UEBxMGTW9zY293MQswCQYDVQQGEwJydTEZ" + "MBcGCSqGSIb3DQEJARYKc2RiQGRvbC5ydTBjMBwGBiqFAwICEzASBgcqhQMCAiQABgcqhQMCAh4B" + "A0MABEDkqNT/3f8NHj6EUiWnK4JbVZBh31bEpkwq9z3jf0u8ZndG56Vt+K1ZB6EpFxLT7hSIos0w" + "weZ2YuTZ4w43OgodoAAwCAYGKoUDAgIDA0EASk/IUXWxoi6NtcUGVF23VRV1L3undB4sRZLp4Vho" + "gQ7m3CMbZFfJ2cPu6QyarseXGYHmazoirH5lGjEo535c1g=="); private byte[] gost3410EC_ExB = Base64.decode( "MIIBPTCB7QIBADCBgDENMAsGA1UEAxMEdGVzdDEWMBQGA1UEChMNRGVtb3MgQ28gTHRkLjEeMBwG" + "A1UECxMVQ3J5cHRvZ3JhcGh5IGRpdmlzaW9uMQ8wDQYDVQQHEwZNb3Njb3cxCzAJBgNVBAYTAnJ1" + "MRkwFwYJKoZIhvcNAQkBFgpzZGJAZG9sLnJ1MGMwHAYGKoUDAgITMBIGByqFAwICJAEGByqFAwIC" + "HgEDQwAEQMBWYUKPy/1Kxad9ChAmgoSWSYOQxRnXo7KEGLU5RNSXA4qMUvArWzvhav+EYUfTbWLh" + "09nELDyHt2XQcvgQHnSgADAIBgYqhQMCAgMDQQAdaNhgH/ElHp64mbMaEo1tPCg9Q22McxpH8rCz" + "E0QBpF4H5mSSQVGI5OAXHToetnNuh7gHHSynyCupYDEHTbkZ"); public String getName() { return "PKCS10CertRequest"; } private void generationTest(int keySize, String keyName, String sigName, String provider) throws Exception { KeyPairGenerator kpg = KeyPairGenerator.getInstance(keyName, "BC"); kpg.initialize(keySize); KeyPair kp = kpg.genKeyPair(); Hashtable attrs = new Hashtable(); attrs.put(X509Principal.C, "AU"); attrs.put(X509Principal.O, "The Legion of the Bouncy Castle"); attrs.put(X509Principal.L, "Melbourne"); attrs.put(X509Principal.ST, "Victoria"); attrs.put(X509Principal.EmailAddress, "feedback-crypto@bouncycastle.org"); Vector order = new Vector(); order.addElement(X509Principal.C); order.addElement(X509Principal.O); order.addElement(X509Principal.L); order.addElement(X509Principal.ST); order.addElement(X509Principal.EmailAddress); X509Name subject = new X509Name(order, attrs); PKCS10CertificationRequest req1 = new PKCS10CertificationRequest( sigName, subject, kp.getPublic(), null, kp.getPrivate(), provider); byte[] bytes = req1.getEncoded(); PKCS10CertificationRequest req2 = new PKCS10CertificationRequest(bytes); if (!req2.verify(provider)) { fail(sigName + ": Failed verify check."); } if (!req2.getPublicKey(provider).equals(req1.getPublicKey(provider))) { fail(keyName + ": Failed public key check."); } } /* * we generate a self signed certificate for the sake of testing - SHA224withECDSA */ private void createECRequest(String algorithm, DERObjectIdentifier algOid, DERObjectIdentifier curveOid) throws Exception { ECNamedCurveParameterSpec spec = ECNamedCurveTable.getParameterSpec(curveOid.getId()); KeyPairGenerator ecGen = KeyPairGenerator.getInstance("ECDSA", "BC"); ecGen.initialize(spec); // // set up the keys // PrivateKey privKey; PublicKey pubKey; KeyPair pair = ecGen.generateKeyPair(); privKey = pair.getPrivate(); pubKey = pair.getPublic(); PKCS10CertificationRequest req = new PKCS10CertificationRequest( algorithm, new X509Name("CN=XXX"), pubKey, null, privKey); if (!req.verify()) { fail("Failed verify check EC."); } req = new PKCS10CertificationRequest(req.getEncoded()); if (!req.verify()) { fail("Failed verify check EC encoded."); } // // try with point compression turned off // ((ECPointEncoder)pubKey).setPointFormat("UNCOMPRESSED"); req = new PKCS10CertificationRequest( algorithm, new X509Name("CN=XXX"), pubKey, null, privKey); if (!req.verify()) { fail("Failed verify check EC uncompressed."); } req = new PKCS10CertificationRequest(req.getEncoded()); if (!req.verify()) { fail("Failed verify check EC uncompressed encoded."); } if (!req.getSignatureAlgorithm().getObjectId().equals(algOid)) { fail("ECDSA oid incorrect."); } if (req.getSignatureAlgorithm().getParameters() != null) { fail("ECDSA parameters incorrect."); } Signature sig = Signature.getInstance(algorithm, "BC"); sig.initVerify(pubKey); sig.update(req.getCertificationRequestInfo().getEncoded()); if (!sig.verify(req.getSignature().getBytes())) { fail("signature not mapped correctly."); } } private void createECRequest(String algorithm, DERObjectIdentifier algOid) throws Exception { ECCurve.Fp curve = new ECCurve.Fp( new BigInteger("6864797660130609714981900799081393217269435300143305409394463459185543183397656052122559640661454554977296311391480858037121987999716643812574028291115057151"), // q (or p) new BigInteger("01FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFC", 16), // a new BigInteger("0051953EB9618E1C9A1F929A21A0B68540EEA2DA725B99B315F3B8B489918EF109E156193951EC7E937B1652C0BD3BB1BF073573DF883D2C34F1EF451FD46B503F00", 16)); // b ECParameterSpec spec = new ECParameterSpec( curve, curve.decodePoint(Hex.decode("0200C6858E06B70404E9CD9E3ECB662395B4429C648139053FB521F828AF606B4D3DBAA14B5E77EFE75928FE1DC127A2FFA8DE3348B3C1856A429BF97E7E31C2E5BD66")), // G new BigInteger("01FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFA51868783BF2F966B7FCC0148F709A5D03BB5C9B8899C47AEBB6FB71E91386409", 16)); // n ECPrivateKeySpec privKeySpec = new ECPrivateKeySpec( new BigInteger("5769183828869504557786041598510887460263120754767955773309066354712783118202294874205844512909370791582896372147797293913785865682804434049019366394746072023"), // d spec); ECPublicKeySpec pubKeySpec = new ECPublicKeySpec( curve.decodePoint(Hex.decode("02006BFDD2C9278B63C92D6624F151C9D7A822CC75BD983B17D25D74C26740380022D3D8FAF304781E416175EADF4ED6E2B47142D2454A7AC7801DD803CF44A4D1F0AC")), // Q spec); // // set up the keys // PrivateKey privKey; PublicKey pubKey; KeyFactory fact = KeyFactory.getInstance("ECDSA", "BC"); privKey = fact.generatePrivate(privKeySpec); pubKey = fact.generatePublic(pubKeySpec); PKCS10CertificationRequest req = new PKCS10CertificationRequest( algorithm, new X509Name("CN=XXX"), pubKey, null, privKey); if (!req.verify()) { fail("Failed verify check EC."); } req = new PKCS10CertificationRequest(req.getEncoded()); if (!req.verify()) { fail("Failed verify check EC encoded."); } // // try with point compression turned off // ((ECPointEncoder)pubKey).setPointFormat("UNCOMPRESSED"); req = new PKCS10CertificationRequest( algorithm, new X509Name("CN=XXX"), pubKey, null, privKey); if (!req.verify()) { fail("Failed verify check EC uncompressed."); } req = new PKCS10CertificationRequest(req.getEncoded()); if (!req.verify()) { fail("Failed verify check EC uncompressed encoded."); } if (!req.getSignatureAlgorithm().getObjectId().equals(algOid)) { fail("ECDSA oid incorrect."); } if (req.getSignatureAlgorithm().getParameters() != null) { fail("ECDSA parameters incorrect."); } Signature sig = Signature.getInstance(algorithm, "BC"); sig.initVerify(pubKey); sig.update(req.getCertificationRequestInfo().getEncoded()); if (!sig.verify(req.getSignature().getBytes())) { fail("signature not mapped correctly."); } } private void createECGOSTRequest() throws Exception { String algorithm = "GOST3411withECGOST3410"; KeyPairGenerator ecGostKpg = KeyPairGenerator.getInstance("ECGOST3410", "BC"); ecGostKpg.initialize(ECGOST3410NamedCurveTable.getParameterSpec("GostR3410-2001-CryptoPro-A"), new SecureRandom()); // // set up the keys // KeyPair pair = ecGostKpg.generateKeyPair(); PrivateKey privKey = pair.getPrivate(); PublicKey pubKey = pair.getPublic(); PKCS10CertificationRequest req = new PKCS10CertificationRequest( algorithm, new X509Name("CN=XXX"), pubKey, null, privKey); if (!req.verify()) { fail("Failed verify check EC."); } req = new PKCS10CertificationRequest(req.getEncoded()); if (!req.verify()) { fail("Failed verify check EC encoded."); } if (!req.getSignatureAlgorithm().getObjectId().equals(CryptoProObjectIdentifiers.gostR3411_94_with_gostR3410_2001)) { fail("ECGOST oid incorrect."); } if (req.getSignatureAlgorithm().getParameters() != null) { fail("ECGOST parameters incorrect."); } Signature sig = Signature.getInstance(algorithm, "BC"); sig.initVerify(pubKey); sig.update(req.getCertificationRequestInfo().getEncoded()); if (!sig.verify(req.getSignature().getBytes())) { fail("signature not mapped correctly."); } } private void createPSSTest(String algorithm) throws Exception { RSAPublicKeySpec pubKeySpec = new RSAPublicKeySpec( new BigInteger("a56e4a0e701017589a5187dc7ea841d156f2ec0e36ad52a44dfeb1e61f7ad991d8c51056ffedb162b4c0f283a12a88a394dff526ab7291cbb307ceabfce0b1dfd5cd9508096d5b2b8b6df5d671ef6377c0921cb23c270a70e2598e6ff89d19f105acc2d3f0cb35f29280e1386b6f64c4ef22e1e1f20d0ce8cffb2249bd9a2137",16), new BigInteger("010001",16)); RSAPrivateCrtKeySpec privKeySpec = new RSAPrivateCrtKeySpec( new BigInteger("a56e4a0e701017589a5187dc7ea841d156f2ec0e36ad52a44dfeb1e61f7ad991d8c51056ffedb162b4c0f283a12a88a394dff526ab7291cbb307ceabfce0b1dfd5cd9508096d5b2b8b6df5d671ef6377c0921cb23c270a70e2598e6ff89d19f105acc2d3f0cb35f29280e1386b6f64c4ef22e1e1f20d0ce8cffb2249bd9a2137",16), new BigInteger("010001",16), new BigInteger("33a5042a90b27d4f5451ca9bbbd0b44771a101af884340aef9885f2a4bbe92e894a724ac3c568c8f97853ad07c0266c8c6a3ca0929f1e8f11231884429fc4d9ae55fee896a10ce707c3ed7e734e44727a39574501a532683109c2abacaba283c31b4bd2f53c3ee37e352cee34f9e503bd80c0622ad79c6dcee883547c6a3b325",16), new BigInteger("e7e8942720a877517273a356053ea2a1bc0c94aa72d55c6e86296b2dfc967948c0a72cbccca7eacb35706e09a1df55a1535bd9b3cc34160b3b6dcd3eda8e6443",16), new BigInteger("b69dca1cf7d4d7ec81e75b90fcca874abcde123fd2700180aa90479b6e48de8d67ed24f9f19d85ba275874f542cd20dc723e6963364a1f9425452b269a6799fd",16), new BigInteger("28fa13938655be1f8a159cbaca5a72ea190c30089e19cd274a556f36c4f6e19f554b34c077790427bbdd8dd3ede2448328f385d81b30e8e43b2fffa027861979",16), new BigInteger("1a8b38f398fa712049898d7fb79ee0a77668791299cdfa09efc0e507acb21ed74301ef5bfd48be455eaeb6e1678255827580a8e4e8e14151d1510a82a3f2e729",16), new BigInteger("27156aba4126d24a81f3a528cbfb27f56886f840a9f6e86e17a44b94fe9319584b8e22fdde1e5a2e3bd8aa5ba8d8584194eb2190acf832b847f13a3d24a79f4d",16)); KeyFactory fact = KeyFactory.getInstance("RSA", "BC"); PrivateKey privKey = fact.generatePrivate(privKeySpec); PublicKey pubKey = fact.generatePublic(pubKeySpec); PKCS10CertificationRequest req = new PKCS10CertificationRequest( algorithm, new X509Name("CN=XXX"), pubKey, null, privKey); if (!req.verify()) { fail("Failed verify check PSS."); } req = new PKCS10CertificationRequest(req.getEncoded()); if (!req.verify()) { fail("Failed verify check PSS encoded."); } if (!req.getSignatureAlgorithm().getObjectId().equals(PKCSObjectIdentifiers.id_RSASSA_PSS)) { fail("PSS oid incorrect."); } if (req.getSignatureAlgorithm().getParameters() == null) { fail("PSS parameters incorrect."); } Signature sig = Signature.getInstance(algorithm, "BC"); sig.initVerify(pubKey); sig.update(req.getCertificationRequestInfo().getEncoded()); if (!sig.verify(req.getSignature().getBytes())) { fail("signature not mapped correctly."); } } // previous code found to cause a NullPointerException private void nullPointerTest() throws Exception { KeyPairGenerator keyGen = KeyPairGenerator.getInstance("RSA", "BC"); keyGen.initialize(1024, new SecureRandom()); KeyPair pair = keyGen.generateKeyPair(); Vector oids = new Vector(); Vector values = new Vector(); oids.add(X509Extensions.BasicConstraints); values.add(new X509Extension(true, new DEROctetString(new BasicConstraints(true)))); oids.add(X509Extensions.KeyUsage); values.add(new X509Extension(true, new DEROctetString( new KeyUsage(KeyUsage.keyCertSign | KeyUsage.cRLSign)))); SubjectKeyIdentifier subjectKeyIdentifier = new SubjectKeyIdentifierStructure(pair.getPublic()); X509Extension ski = new X509Extension(false, new DEROctetString(subjectKeyIdentifier)); oids.add(X509Extensions.SubjectKeyIdentifier); values.add(ski); Attribute attribute = new Attribute(PKCSObjectIdentifiers.pkcs_9_at_extensionRequest, new DERSet(new X509Extensions(oids, values))); PKCS10CertificationRequest p1 = new PKCS10CertificationRequest( "SHA1WithRSA", new X509Principal("cn=csr"), pair.getPublic(), new DERSet(attribute), pair.getPrivate(), "BC"); PKCS10CertificationRequest p2 = new PKCS10CertificationRequest( "SHA1WithRSA", new X509Principal("cn=csr"), pair.getPublic(), new DERSet(attribute), pair.getPrivate(), "BC"); if (!p1.equals(p2)) { fail("cert request comparison failed"); } } public void performTest() throws Exception { generationTest(512, "RSA", "SHA1withRSA", "BC"); generationTest(512, "GOST3410", "GOST3411withGOST3410", "BC"); if (Security.getProvider("SunRsaSign") != null) { generationTest(512, "RSA", "SHA1withRSA", "SunRsaSign"); } // elliptic curve GOST A parameter set PKCS10CertificationRequest req = new PKCS10CertificationRequest(gost3410EC_A); if (!req.verify()) { fail("Failed verify check gost3410EC_A."); } // elliptic curve GOST B parameter set req = new PKCS10CertificationRequest(gost3410EC_B); if (!req.verify()) { fail("Failed verify check gost3410EC_B."); } // elliptic curve GOST C parameter set req = new PKCS10CertificationRequest(gost3410EC_C); if (!req.verify()) { fail("Failed verify check gost3410EC_C."); } // elliptic curve GOST ExA parameter set req = new PKCS10CertificationRequest(gost3410EC_ExA); if (!req.verify()) { fail("Failed verify check gost3410EC_ExA."); } // elliptic curve GOST ExB parameter set req = new PKCS10CertificationRequest(gost3410EC_ExB); if (!req.verify()) { fail("Failed verify check gost3410EC_ExA."); } // elliptic curve openSSL KeyPairGenerator g = KeyPairGenerator.getInstance("ECDSA", "BC"); ECCurve curve = new ECCurve.Fp( new BigInteger("883423532389192164791648750360308885314476597252960362792450860609699839"), // q new BigInteger("7fffffffffffffffffffffff7fffffffffff8000000000007ffffffffffc", 16), // a new BigInteger("6b016c3bdcf18941d0d654921475ca71a9db2fb27d1d37796185c2942c0a", 16)); // b ECParameterSpec ecSpec = new ECParameterSpec( curve, curve.decodePoint(Hex.decode("020ffa963cdca8816ccc33b8642bedf905c3d358573d3f27fbbd3b3cb9aaaf")), // G new BigInteger("883423532389192164791648750360308884807550341691627752275345424702807307")); // n g.initialize(ecSpec, new SecureRandom()); KeyPair kp = g.generateKeyPair(); req = new PKCS10CertificationRequest( "ECDSAWITHSHA1", new X509Name("CN=XXX"), kp.getPublic(), null, kp.getPrivate()); if (!req.verify()) { fail("Failed verify check EC."); } createECRequest("SHA1withECDSA", X9ObjectIdentifiers.ecdsa_with_SHA1); createECRequest("SHA224withECDSA", X9ObjectIdentifiers.ecdsa_with_SHA224); createECRequest("SHA256withECDSA", X9ObjectIdentifiers.ecdsa_with_SHA256); createECRequest("SHA384withECDSA", X9ObjectIdentifiers.ecdsa_with_SHA384); createECRequest("SHA512withECDSA", X9ObjectIdentifiers.ecdsa_with_SHA512); createECRequest("SHA1withECDSA", X9ObjectIdentifiers.ecdsa_with_SHA1, new DERObjectIdentifier("1.3.132.0.34")); createECGOSTRequest(); createPSSTest("SHA1withRSAandMGF1"); createPSSTest("SHA224withRSAandMGF1"); createPSSTest("SHA256withRSAandMGF1"); createPSSTest("SHA384withRSAandMGF1"); nullPointerTest(); } public static void main( String[] args) { Security.addProvider(new BouncyCastleProvider()); runTest(new PKCS10CertRequestTest()); } } bouncycastle-1.49.orig/test/src/org/bouncycastle/jce/provider/test/AttrCertSelectorTest.java0000644000175000017500000002435211731467176032012 0ustar ebourgebourgpackage org.bouncycastle.jce.provider.test; import java.io.ByteArrayInputStream; import java.math.BigInteger; import java.security.KeyFactory; import java.security.PrivateKey; import java.security.Security; import java.security.cert.CertificateFactory; import java.security.cert.X509Certificate; import java.security.spec.RSAPrivateCrtKeySpec; import java.util.Date; import org.bouncycastle.asn1.ASN1EncodableVector; import org.bouncycastle.asn1.DERSequence; import org.bouncycastle.asn1.x509.GeneralName; import org.bouncycastle.asn1.x509.Target; import org.bouncycastle.asn1.x509.TargetInformation; import org.bouncycastle.asn1.x509.X509Extensions; import org.bouncycastle.jce.X509Principal; import org.bouncycastle.jce.PrincipalUtil; import org.bouncycastle.jce.provider.BouncyCastleProvider; import org.bouncycastle.util.encoders.Base64; import org.bouncycastle.util.test.SimpleTest; import org.bouncycastle.util.test.Test; import org.bouncycastle.util.test.TestResult; import org.bouncycastle.x509.AttributeCertificateHolder; import org.bouncycastle.x509.AttributeCertificateIssuer; import org.bouncycastle.x509.X509Attribute; import org.bouncycastle.x509.X509AttributeCertStoreSelector; import org.bouncycastle.x509.X509AttributeCertificate; import org.bouncycastle.x509.X509V2AttributeCertificateGenerator; public class AttrCertSelectorTest extends SimpleTest { static final RSAPrivateCrtKeySpec RSA_PRIVATE_KEY_SPEC = new RSAPrivateCrtKeySpec( new BigInteger( "b4a7e46170574f16a97082b22be58b6a2a629798419be12872a4bdba626cfae9900f76abfb12139dce5de56564fab2b6543165a040c606887420e33d91ed7ed7", 16), new BigInteger("11", 16), new BigInteger( "9f66f6b05410cd503b2709e88115d55daced94d1a34d4e32bf824d0dde6028ae79c5f07b580f5dce240d7111f7ddb130a7945cd7d957d1920994da389f490c89", 16), new BigInteger( "c0a0758cdf14256f78d4708c86becdead1b50ad4ad6c5c703e2168fbf37884cb", 16), new BigInteger( "f01734d7960ea60070f1b06f2bb81bfac48ff192ae18451d5e56c734a5aab8a5", 16), new BigInteger( "b54bb9edff22051d9ee60f9351a48591b6500a319429c069a3e335a1d6171391", 16), new BigInteger( "d3d83daf2a0cecd3367ae6f8ae1aeb82e9ac2f816c6fc483533d8297dd7884cd", 16), new BigInteger( "b8f52fc6f38593dabb661d3f50f8897f8106eee68b1bce78a95b132b4e5b5d19", 16)); static final byte[] holderCert = Base64 .decode("MIIGjTCCBXWgAwIBAgICAPswDQYJKoZIhvcNAQEEBQAwaTEdMBsGCSqGSIb3DQEJ" + "ARYOaXJtaGVscEB2dC5lZHUxLjAsBgNVBAMTJVZpcmdpbmlhIFRlY2ggQ2VydGlm" + "aWNhdGlvbiBBdXRob3JpdHkxCzAJBgNVBAoTAnZ0MQswCQYDVQQGEwJVUzAeFw0w" + "MzAxMzExMzUyMTRaFw0wNDAxMzExMzUyMTRaMIGDMRswGQYJKoZIhvcNAQkBFgxz" + "c2hhaEB2dC5lZHUxGzAZBgNVBAMTElN1bWl0IFNoYWggKHNzaGFoKTEbMBkGA1UE" + "CxMSVmlyZ2luaWEgVGVjaCBVc2VyMRAwDgYDVQQLEwdDbGFzcyAxMQswCQYDVQQK" + "EwJ2dDELMAkGA1UEBhMCVVMwgZ8wDQYJKoZIhvcNAQEBBQADgY0AMIGJAoGBAPDc" + "scgSKmsEp0VegFkuitD5j5PUkDuzLjlfaYONt2SN8WeqU4j2qtlCnsipa128cyKS" + "JzYe9duUdNxquh5BPIkMkHBw4jHoQA33tk0J/sydWdN74/AHPpPieK5GHwhU7GTG" + "rCCS1PJRxjXqse79ExAlul+gjQwHeldAC+d4A6oZAgMBAAGjggOmMIIDojAMBgNV" + "HRMBAf8EAjAAMBEGCWCGSAGG+EIBAQQEAwIFoDAOBgNVHQ8BAf8EBAMCA/gwHQYD" + "VR0lBBYwFAYIKwYBBQUHAwIGCCsGAQUFBwMEMB0GA1UdDgQWBBRUIoWAzlXbzBYE" + "yVTjQFWyMMKo1jCBkwYDVR0jBIGLMIGIgBTgc3Fm+TGqKDhen+oKfbl+xVbj2KFt" + "pGswaTEdMBsGCSqGSIb3DQEJARYOaXJtaGVscEB2dC5lZHUxLjAsBgNVBAMTJVZp" + "cmdpbmlhIFRlY2ggQ2VydGlmaWNhdGlvbiBBdXRob3JpdHkxCzAJBgNVBAoTAnZ0" + "MQswCQYDVQQGEwJVU4IBADCBiwYJYIZIAYb4QgENBH4WfFZpcmdpbmlhIFRlY2gg" + "Q2VydGlmaWNhdGlvbiBBdXRob3JpdHkgZGlnaXRhbCBjZXJ0aWZpY2F0ZXMgYXJl" + "IHN1YmplY3QgdG8gcG9saWNpZXMgbG9jYXRlZCBhdCBodHRwOi8vd3d3LnBraS52" + "dC5lZHUvY2EvY3BzLy4wFwYDVR0RBBAwDoEMc3NoYWhAdnQuZWR1MBkGA1UdEgQS" + "MBCBDmlybWhlbHBAdnQuZWR1MEMGCCsGAQUFBwEBBDcwNTAzBggrBgEFBQcwAoYn" + "aHR0cDovL2JveDE3Ny5jYy52dC5lZHUvY2EvaXNzdWVycy5odG1sMEQGA1UdHwQ9" + "MDswOaA3oDWGM2h0dHA6Ly9ib3gxNzcuY2MudnQuZWR1L2h0ZG9jcy1wdWJsaWMv" + "Y3JsL2NhY3JsLmNybDBUBgNVHSAETTBLMA0GCysGAQQBtGgFAQEBMDoGCysGAQQB" + "tGgFAQEBMCswKQYIKwYBBQUHAgEWHWh0dHA6Ly93d3cucGtpLnZ0LmVkdS9jYS9j" + "cHMvMD8GCWCGSAGG+EIBBAQyFjBodHRwOi8vYm94MTc3LmNjLnZ0LmVkdS9jZ2kt" + "cHVibGljL2NoZWNrX3Jldl9jYT8wPAYJYIZIAYb4QgEDBC8WLWh0dHA6Ly9ib3gx" + "NzcuY2MudnQuZWR1L2NnaS1wdWJsaWMvY2hlY2tfcmV2PzBLBglghkgBhvhCAQcE" + "PhY8aHR0cHM6Ly9ib3gxNzcuY2MudnQuZWR1L35PcGVuQ0E4LjAxMDYzMC9jZ2kt" + "cHVibGljL3JlbmV3YWw/MCwGCWCGSAGG+EIBCAQfFh1odHRwOi8vd3d3LnBraS52" + "dC5lZHUvY2EvY3BzLzANBgkqhkiG9w0BAQQFAAOCAQEAHJ2ls9yjpZVcu5DqiE67" + "r7BfkdMnm7IOj2v8cd4EAlPp6OPBmjwDMwvKRBb/P733kLBqFNWXWKTpT008R0KB" + "8kehbx4h0UPz9vp31zhGv169+5iReQUUQSIwTGNWGLzrT8kPdvxiSAvdAJxcbRBm" + "KzDic5I8PoGe48kSCkPpT1oNmnivmcu5j1SMvlx0IS2BkFMksr0OHiAW1elSnE/N" + "RuX2k73b3FucwVxB3NRo3vgoHPCTnh9r4qItAHdxFlF+pPtbw2oHESKRfMRfOIHz" + "CLQWSIa6Tvg4NIV3RRJ0sbCObesyg08lymalQMdkXwtRn5eGE00SHWwEUjSXP2gR" + "3g=="); public String getName() { return "AttrCertSelector"; } private X509AttributeCertificate createAttrCert() throws Exception { CertificateFactory fact = CertificateFactory.getInstance("X.509", "BC"); X509Certificate iCert = (X509Certificate) fact .generateCertificate(new ByteArrayInputStream(holderCert)); // // a sample key pair. // // RSAPublicKeySpec pubKeySpec = new RSAPublicKeySpec( // new BigInteger( // "b4a7e46170574f16a97082b22be58b6a2a629798419be12872a4bdba626cfae9900f76abfb12139dce5de56564fab2b6543165a040c606887420e33d91ed7ed7", // 16), new BigInteger("11", 16)); // // set up the keys // PrivateKey privKey; KeyFactory kFact = KeyFactory.getInstance("RSA", "BC"); privKey = kFact.generatePrivate(RSA_PRIVATE_KEY_SPEC); X509V2AttributeCertificateGenerator gen = new X509V2AttributeCertificateGenerator(); // the actual attributes GeneralName roleName = new GeneralName(GeneralName.rfc822Name, "DAU123456789@test.com"); ASN1EncodableVector roleSyntax = new ASN1EncodableVector(); roleSyntax.add(roleName); // roleSyntax OID: 2.5.24.72 X509Attribute attributes = new X509Attribute("2.5.24.72", new DERSequence(roleSyntax)); gen.addAttribute(attributes); gen.setHolder(new AttributeCertificateHolder(PrincipalUtil.getSubjectX509Principal(iCert))); gen.setIssuer(new AttributeCertificateIssuer(new X509Principal( "cn=test"))); gen.setNotBefore(new Date(System.currentTimeMillis() - 50000)); gen.setNotAfter(new Date(System.currentTimeMillis() + 50000)); gen.setSerialNumber(BigInteger.valueOf(1)); gen.setSignatureAlgorithm("SHA1WithRSAEncryption"); Target targetName = new Target(Target.targetName, new GeneralName(GeneralName.dNSName, "www.test.com")); Target targetGroup = new Target(Target.targetGroup, new GeneralName( GeneralName.directoryName, "o=Test, ou=Test")); Target[] targets = new Target[2]; targets[0] = targetName; targets[1] = targetGroup; TargetInformation targetInformation = new TargetInformation(targets); gen.addExtension(X509Extensions.TargetInformation.getId(), true, targetInformation); return gen.generate(privKey, "BC"); } public void testSelector() throws Exception { X509AttributeCertificate aCert = createAttrCert(); X509AttributeCertStoreSelector sel = new X509AttributeCertStoreSelector(); sel.setAttributeCert(aCert); boolean match = sel.match(aCert); if (!match) { fail("Selector does not match attribute certificate."); } sel.setAttributeCert(null); match = sel.match(aCert); if (!match) { fail("Selector does not match attribute certificate."); } sel.setHolder(aCert.getHolder()); match = sel.match(aCert); if (!match) { fail("Selector does not match attribute certificate holder."); } sel.setHolder(null); sel.setIssuer(aCert.getIssuer()); match = sel.match(aCert); if (!match) { fail("Selector does not match attribute certificate issuer."); } sel.setIssuer(null); CertificateFactory fact = CertificateFactory.getInstance("X.509", "BC"); X509Certificate iCert = (X509Certificate) fact .generateCertificate(new ByteArrayInputStream(holderCert)); match = aCert.getHolder().match(iCert); if (!match) { fail("Issuer holder does not match signing certificate of attribute certificate."); } sel.setSerialNumber(aCert.getSerialNumber()); match = sel.match(aCert); if (!match) { fail("Selector does not match attribute certificate serial number."); } sel.setAttributeCertificateValid(new Date()); match = sel.match(aCert); if (!match) { fail("Selector does not match attribute certificate time."); } sel.addTargetName(new GeneralName(2, "www.test.com")); match = sel.match(aCert); if (!match) { fail("Selector does not match attribute certificate target name."); } sel.setTargetNames(null); sel.addTargetGroup(new GeneralName(4, "o=Test, ou=Test")); match = sel.match(aCert); if (!match) { fail("Selector does not match attribute certificate target group."); } sel.setTargetGroups(null); } public void performTest() throws Exception { Security.addProvider(new BouncyCastleProvider()); testSelector(); } public static void main(String[] args) { Test test = new AttrCertSelectorTest(); TestResult result = test.perform(); System.out.println(result); } } bouncycastle-1.49.orig/test/src/org/bouncycastle/jce/provider/test/DoFinalTest.java0000644000175000017500000001123510330633061030047 0ustar ebourgebourgpackage org.bouncycastle.jce.provider.test; import java.security.Key; import java.security.Security; import javax.crypto.Cipher; import javax.crypto.KeyGenerator; import org.bouncycastle.jce.provider.BouncyCastleProvider; import org.bouncycastle.util.test.SimpleTestResult; import org.bouncycastle.util.test.Test; import org.bouncycastle.util.test.TestResult; /** * check that doFinal is properly reseting the cipher. */ public class DoFinalTest implements Test { public DoFinalTest() { } private boolean equalArray( byte[] a, int aOff, byte[] b, int length) { if (aOff + a.length < length) { return false; } if (b.length < length) { return false; } for (int i = 0; i != length; i++) { if (a[aOff + i] != b[i]) { return false; } } return true; } public TestResult checkCipher( String cipherName) { String lCode = "ABCDEFGHIJKLMNOPQRSTUVWXY0123456789"; String baseAlgorithm; int index = cipherName.indexOf('/'); if (index > 0) { baseAlgorithm = cipherName.substring(0, index); } else { baseAlgorithm = cipherName; } try { KeyGenerator kGen = KeyGenerator.getInstance(baseAlgorithm, "BC"); Cipher cipher = Cipher.getInstance(cipherName, "BC"); Key key = kGen.generateKey(); cipher.init(Cipher.ENCRYPT_MODE, key); byte[] encrypted = cipher.doFinal(lCode.getBytes()); // 2nd try byte[] encrypted2 = cipher.doFinal(lCode.getBytes()); if (encrypted.length != encrypted2.length) { return new SimpleTestResult(false, getName() + ": Failed " + cipherName + " - expected length " + encrypted.length + " got " + encrypted2.length); } if (!equalArray(encrypted, 0, encrypted2, encrypted.length)) { return new SimpleTestResult(false, getName() + ": Failed " + cipherName + " - first two arrays not equal"); } // 3rd try byte[] enc1 = cipher.update(lCode.getBytes()); byte[] enc2 = cipher.doFinal(); if ((enc1.length + enc2.length) != encrypted.length) { return new SimpleTestResult(false, getName() + ": Failed " + cipherName + " - expected length " + encrypted.length + " got " + (enc1.length + enc2.length)); } if (!equalArray(encrypted, 0, enc1, enc1.length)) { return new SimpleTestResult(false, getName() + ": Failed " + cipherName + " - enc1 array not equal"); } if (!equalArray(encrypted, enc1.length, enc2, enc2.length)) { return new SimpleTestResult(false, getName() + ": Failed " + cipherName + " - enc1 array not equal"); } enc1 = cipher.update(lCode.getBytes()); if (!equalArray(encrypted, 0, enc1, enc1.length)) { return new SimpleTestResult(false, getName() + ": Failed " + cipherName + " - 2nd enc1 array not equal"); } int len = cipher.doFinal(enc1, 0); if ((enc1.length + len) != encrypted.length) { return new SimpleTestResult(false, getName() + ": Failed " + cipherName + " - expected length " + encrypted.length + " got " + (enc1.length + len)); } } catch (Exception e) { return new SimpleTestResult(false, getName() + ": Failed " + cipherName + " - exception " + e.toString()); } return new SimpleTestResult(true, getName() + ": Okay"); } public TestResult perform() { TestResult result = checkCipher("RC4"); if (!result.isSuccessful()) { return result; } result = checkCipher("DES/CBC/PKCS5Padding"); if (!result.isSuccessful()) { return result; } return checkCipher("Rijndael"); } public String getName() { return "DoFinalTest"; } public static void main( String[] args) { Security.addProvider(new BouncyCastleProvider()); Test test = new DoFinalTest(); TestResult result = test.perform(); System.out.println(result.toString()); } } bouncycastle-1.49.orig/test/src/org/bouncycastle/jce/provider/test/ECIESTest.java0000755000175000017500000001532312151252353027374 0ustar ebourgebourgpackage org.bouncycastle.jce.provider.test; import java.security.KeyPair; import java.security.KeyPairGenerator; import java.security.SecureRandom; import java.security.Security; import javax.crypto.Cipher; import org.bouncycastle.crypto.agreement.ECDHBasicAgreement; import org.bouncycastle.crypto.digests.SHA1Digest; import org.bouncycastle.crypto.engines.DESEngine; import org.bouncycastle.crypto.engines.IESEngine; import org.bouncycastle.crypto.generators.KDF2BytesGenerator; import org.bouncycastle.crypto.macs.HMac; import org.bouncycastle.crypto.paddings.PaddedBufferedBlockCipher; import org.bouncycastle.jcajce.provider.asymmetric.ec.IESCipher; import org.bouncycastle.jce.interfaces.ECPrivateKey; import org.bouncycastle.jce.interfaces.ECPublicKey; import org.bouncycastle.jce.provider.BouncyCastleProvider; import org.bouncycastle.jce.spec.IESParameterSpec; import org.bouncycastle.util.encoders.Hex; import org.bouncycastle.util.test.SimpleTest; /** * Test for ECIES - Elliptic Curve Integrated Encryption Scheme */ public class ECIESTest extends SimpleTest { ECIESTest() { } public String getName() { return "ECIES"; } public void performTest() throws Exception { byte[] derivation = Hex.decode("202122232425262728292a2b2c2d2e2f"); byte[] encoding = Hex.decode("303132333435363738393a3b3c3d3e3f"); IESCipher c1 = new org.bouncycastle.jcajce.provider.asymmetric.ec.IESCipher.ECIES(); IESCipher c2 = new org.bouncycastle.jcajce.provider.asymmetric.ec.IESCipher.ECIES(); IESParameterSpec params = new IESParameterSpec(derivation,encoding,128); // Testing ECIES with default curve in streaming mode KeyPairGenerator g = KeyPairGenerator.getInstance("EC", "BC"); doTest("ECIES with default", g, "ECIES", params); // Testing ECIES with 192-bit curve in streaming mode g.initialize(192, new SecureRandom()); doTest("ECIES with 192-bit", g, "ECIES", params); // Testing ECIES with 256-bit curve in streaming mode g.initialize(256, new SecureRandom()); doTest("ECIES with 256-bit", g, "ECIES", params); c1 = new IESCipher(new IESEngine(new ECDHBasicAgreement(), new KDF2BytesGenerator(new SHA1Digest()), new HMac(new SHA1Digest()), new PaddedBufferedBlockCipher(new DESEngine()))); c2 = new IESCipher(new IESEngine(new ECDHBasicAgreement(), new KDF2BytesGenerator(new SHA1Digest()), new HMac(new SHA1Digest()), new PaddedBufferedBlockCipher(new DESEngine()))); params = new IESParameterSpec(derivation, encoding, 128, 128); // Testing ECIES with default curve using DES g = KeyPairGenerator.getInstance("EC", "BC"); doTest("default", g, "ECIESwithDESEDE", params); // Testing ECIES with 192-bit curve using DES g.initialize(192, new SecureRandom()); doTest("192-bit", g, "ECIESwithDESEDE", params); // Testing ECIES with 256-bit curve using DES g.initialize(256, new SecureRandom()); doTest("256-bit", g, "ECIESwithDESEDE", params); c1 = new org.bouncycastle.jcajce.provider.asymmetric.ec.IESCipher.ECIESwithAES(); c2 = new org.bouncycastle.jcajce.provider.asymmetric.ec.IESCipher.ECIESwithAES(); params = new IESParameterSpec(derivation, encoding, 128, 128); // Testing ECIES with default curve using AES g = KeyPairGenerator.getInstance("EC", "BC"); doTest("default", g, "ECIESwithAES", params); // Testing ECIES with 192-bit curve using AES g.initialize(192, new SecureRandom()); doTest("192-bit", g, "ECIESwithAES", params); // Testing ECIES with 256-bit curve using AES g.initialize(256, new SecureRandom()); doTest("256-bit", g, "ECIESwithAES", params); } public void doTest( String testname, KeyPairGenerator g, String cipher, IESParameterSpec p) throws Exception { byte[] message = Hex.decode("0102030405060708090a0b0c0d0e0f10111213141516"); byte[] out1, out2; // Generate static key pair KeyPair KeyPair = g.generateKeyPair(); ECPublicKey Pub = (ECPublicKey) KeyPair.getPublic(); ECPrivateKey Priv = (ECPrivateKey) KeyPair.getPrivate(); Cipher c1 = Cipher.getInstance(cipher); Cipher c2 = Cipher.getInstance(cipher); // Testing with null parameters and DHAES mode off c1.init(Cipher.ENCRYPT_MODE, Pub, new SecureRandom()); c2.init(Cipher.DECRYPT_MODE, Priv, new SecureRandom()); out1 = c1.doFinal(message, 0, message.length); out2 = c2.doFinal(out1, 0, out1.length); if (!areEqual(out2, message)) fail(testname + " test failed with null parameters, DHAES mode false."); // Testing with given parameters and DHAES mode off c1.init(Cipher.ENCRYPT_MODE, Pub, p, new SecureRandom()); c2.init(Cipher.DECRYPT_MODE, Priv, p, new SecureRandom()); out1 = c1.doFinal(message, 0, message.length); out2 = c2.doFinal(out1, 0, out1.length); if (!areEqual(out2, message)) fail(testname + " test failed with non-null parameters, DHAES mode false."); c1 = Cipher.getInstance(cipher + "/DHAES/PKCS7Padding","BC"); c2 = Cipher.getInstance(cipher + "/DHAES/PKCS7Padding","BC"); // Testing with null parameters and DHAES mode on c1.init(Cipher.ENCRYPT_MODE, Pub, new SecureRandom()); c2.init(Cipher.DECRYPT_MODE, Priv, new SecureRandom()); out1 = c1.doFinal(message, 0, message.length); out2 = c2.doFinal(out1, 0, out1.length); if (!areEqual(out2, message)) fail(testname + " test failed with null parameters, DHAES mode true."); c1 = Cipher.getInstance(cipher + "/DHAES/PKCS7Padding"); c2 = Cipher.getInstance(cipher + "/DHAES/PKCS7Padding"); // Testing with given parameters and DHAES mode on c1.init(Cipher.ENCRYPT_MODE, Pub, p, new SecureRandom()); c2.init(Cipher.DECRYPT_MODE, Priv, p, new SecureRandom()); out1 = c1.doFinal(message, 0, message.length); out2 = c2.doFinal(out1, 0, out1.length); if (!areEqual(out2, message)) fail(testname + " test failed with non-null parameters, DHAES mode true."); } public static void main( String[] args) { Security.addProvider(new BouncyCastleProvider()); runTest(new ECIESTest()); } } bouncycastle-1.49.orig/test/src/org/bouncycastle/openssl/0000755000175000017500000000000012152033550023140 5ustar ebourgebourgbouncycastle-1.49.orig/test/src/org/bouncycastle/openssl/test/0000755000175000017500000000000012152033550024117 5ustar ebourgebourgbouncycastle-1.49.orig/test/src/org/bouncycastle/openssl/test/extratest.pem0000644000175000017500000001315011571364344026661 0ustar ebourgebourg 0:d=0 hl=4 l= 862 cons: SEQUENCE 4:d=1 hl=4 l= 711 cons: SEQUENCE 8:d=2 hl=2 l= 3 cons: cont [ 0 ] 10:d=3 hl=2 l= 1 prim: INTEGER :02 13:d=2 hl=2 l= 1 prim: INTEGER :07 16:d=2 hl=2 l= 13 cons: SEQUENCE 18:d=3 hl=2 l= 9 prim: OBJECT :md5WithRSAEncryption 29:d=3 hl=2 l= 0 prim: NULL 31:d=2 hl=3 l= 183 cons: SEQUENCE 34:d=3 hl=2 l= 11 cons: SET 36:d=4 hl=2 l= 9 cons: SEQUENCE 38:d=5 hl=2 l= 3 prim: OBJECT :countryName 43:d=5 hl=2 l= 2 prim: PRINTABLESTRING :AU 47:d=3 hl=2 l= 17 cons: SET 49:d=4 hl=2 l= 15 cons: SEQUENCE 51:d=5 hl=2 l= 3 prim: OBJECT :stateOrProvinceName 56:d=5 hl=2 l= 8 prim: PRINTABLESTRING :Victoria 66:d=3 hl=2 l= 24 cons: SET 68:d=4 hl=2 l= 22 cons: SEQUENCE 70:d=5 hl=2 l= 3 prim: OBJECT :localityName 75:d=5 hl=2 l= 15 prim: PRINTABLESTRING :South Melbourne 92:d=3 hl=2 l= 26 cons: SET 94:d=4 hl=2 l= 24 cons: SEQUENCE 96:d=5 hl=2 l= 3 prim: OBJECT :organizationName 101:d=5 hl=2 l= 17 prim: PRINTABLESTRING :Connect 4 Pty Ltd 120:d=3 hl=2 l= 30 cons: SET 122:d=4 hl=2 l= 28 cons: SEQUENCE 124:d=5 hl=2 l= 3 prim: OBJECT :organizationalUnitName 129:d=5 hl=2 l= 21 prim: PRINTABLESTRING :Certificate Authority 152:d=3 hl=2 l= 21 cons: SET 154:d=4 hl=2 l= 19 cons: SEQUENCE 156:d=5 hl=2 l= 3 prim: OBJECT :commonName 161:d=5 hl=2 l= 12 prim: PRINTABLESTRING :Connect 4 CA 175:d=3 hl=2 l= 40 cons: SET 177:d=4 hl=2 l= 38 cons: SEQUENCE 179:d=5 hl=2 l= 9 prim: OBJECT :emailAddress 190:d=5 hl=2 l= 25 prim: IA5STRING :webmaster@connect4.com.au 217:d=2 hl=2 l= 30 cons: SEQUENCE 219:d=3 hl=2 l= 13 prim: UTCTIME :000602075621Z 234:d=3 hl=2 l= 13 prim: UTCTIME :010602075621Z 249:d=2 hl=3 l= 184 cons: SEQUENCE 252:d=3 hl=2 l= 11 cons: SET 254:d=4 hl=2 l= 9 cons: SEQUENCE 256:d=5 hl=2 l= 3 prim: OBJECT :countryName 261:d=5 hl=2 l= 2 prim: PRINTABLESTRING :AU 265:d=3 hl=2 l= 17 cons: SET 267:d=4 hl=2 l= 15 cons: SEQUENCE 269:d=5 hl=2 l= 3 prim: OBJECT :stateOrProvinceName 274:d=5 hl=2 l= 8 prim: PRINTABLESTRING :Victoria 284:d=3 hl=2 l= 24 cons: SET 286:d=4 hl=2 l= 22 cons: SEQUENCE 288:d=5 hl=2 l= 3 prim: OBJECT :localityName 293:d=5 hl=2 l= 15 prim: PRINTABLESTRING :South Melbourne 310:d=3 hl=2 l= 26 cons: SET 312:d=4 hl=2 l= 24 cons: SEQUENCE 314:d=5 hl=2 l= 3 prim: OBJECT :organizationName 319:d=5 hl=2 l= 17 prim: PRINTABLESTRING :Connect 4 Pty Ltd 338:d=3 hl=2 l= 23 cons: SET 340:d=4 hl=2 l= 21 cons: SEQUENCE 342:d=5 hl=2 l= 3 prim: OBJECT :organizationalUnitName 347:d=5 hl=2 l= 14 prim: PRINTABLESTRING :Webserver Team 363:d=3 hl=2 l= 29 cons: SET 365:d=4 hl=2 l= 27 cons: SEQUENCE 367:d=5 hl=2 l= 3 prim: OBJECT :commonName 372:d=5 hl=2 l= 20 prim: PRINTABLESTRING :www2.connect4.com.au 394:d=3 hl=2 l= 40 cons: SET 396:d=4 hl=2 l= 38 cons: SEQUENCE 398:d=5 hl=2 l= 9 prim: OBJECT :emailAddress 409:d=5 hl=2 l= 25 prim: IA5STRING :webmaster@connect4.com.au 436:d=2 hl=3 l= 159 cons: SEQUENCE 439:d=3 hl=2 l= 13 cons: SEQUENCE 441:d=4 hl=2 l= 9 prim: OBJECT :rsaEncryption 452:d=4 hl=2 l= 0 prim: NULL 454:d=3 hl=3 l= 141 prim: BIT STRING 598:d=2 hl=2 l= 119 cons: cont [ 3 ] 600:d=3 hl=2 l= 117 cons: SEQUENCE 602:d=4 hl=2 l= 36 cons: SEQUENCE 604:d=5 hl=2 l= 3 prim: OBJECT :X509v3 Subject Alternative Name 609:d=5 hl=2 l= 29 prim: OCTET STRING [HEX DUMP]:301B81197765626D617374657240636F6E6E656374342E636F6D2E6175 640:d=4 hl=2 l= 58 cons: SEQUENCE 642:d=5 hl=2 l= 9 prim: OBJECT :Netscape Comment 653:d=5 hl=2 l= 45 prim: OCTET STRING [HEX DUMP]:162B6D6F645F73736C2067656E65726174656420637573746F6D20736572766572206365727469666963617465 700:d=4 hl=2 l= 17 cons: SEQUENCE 702:d=5 hl=2 l= 9 prim: OBJECT :Netscape Cert Type 713:d=5 hl=2 l= 4 prim: OCTET STRING [HEX DUMP]:03020640 719:d=1 hl=2 l= 13 cons: SEQUENCE 721:d=2 hl=2 l= 9 prim: OBJECT :md5WithRSAEncryption 732:d=2 hl=2 l= 0 prim: NULL 734:d=1 hl=3 l= 129 prim: BIT STRING -----BEGIN X509 CERTIFICATE----- MIIDXjCCAsegAwIBAgIBBzANBgkqhkiG9w0BAQQFADCBtzELMAkGA1UEBhMCQVUx ETAPBgNVBAgTCFZpY3RvcmlhMRgwFgYDVQQHEw9Tb3V0aCBNZWxib3VybmUxGjAY BgNVBAoTEUNvbm5lY3QgNCBQdHkgTHRkMR4wHAYDVQQLExVDZXJ0aWZpY2F0ZSBB dXRob3JpdHkxFTATBgNVBAMTDENvbm5lY3QgNCBDQTEoMCYGCSqGSIb3DQEJARYZ d2VibWFzdGVyQGNvbm5lY3Q0LmNvbS5hdTAeFw0wMDA2MDIwNzU2MjFaFw0wMTA2 MDIwNzU2MjFaMIG4MQswCQYDVQQGEwJBVTERMA8GA1UECBMIVmljdG9yaWExGDAW BgNVBAcTD1NvdXRoIE1lbGJvdXJuZTEaMBgGA1UEChMRQ29ubmVjdCA0IFB0eSBM dGQxFzAVBgNVBAsTDldlYnNlcnZlciBUZWFtMR0wGwYDVQQDExR3d3cyLmNvbm5l Y3Q0LmNvbS5hdTEoMCYGCSqGSIb3DQEJARYZd2VibWFzdGVyQGNvbm5lY3Q0LmNv bS5hdTCBnzANBgkqhkiG9w0BAQEFAAOBjQAwgYkCgYEArvDxclKAhyv7Q/Wmr2re Gw4XL9Cnh9e+6VgWy2AWNy/MVeXdlxzd7QAuc1eOWQkGQEiLPy5XQtTY+sBUJ3AO Rvd2fEVJIcjf29ey7bYua9J/vz5MG2KYo9/WCHIwqD9mmG9g0xLcfwq/s8ZJBswE 7sb85VU+h94PTvsWOsWuKaECAwEAAaN3MHUwJAYDVR0RBB0wG4EZd2VibWFzdGVy QGNvbm5lY3Q0LmNvbS5hdTA6BglghkgBhvhCAQ0ELRYrbW9kX3NzbCBnZW5lcmF0 ZWQgY3VzdG9tIHNlcnZlciBjZXJ0aWZpY2F0ZTARBglghkgBhvhCAQEEBAMCBkAw DQYJKoZIhvcNAQEEBQADgYEAotccfKpwSsIxM1Hae8DR7M/Rw8dg/RqOWx45HNVL iBS4/3N/TO195yeQKbfmzbAA2jbPVvIvGgTxPgO1MP4ZgvgRhasaa0qCJCkWvpM4 yQf33vOiYQbpv4rTwzU8AmRlBG45WdjyNIigGV+oRc61aKCTnLq7zB8N3z1TF/bF 5/8= -----END X509 CERTIFICATE-----bouncycastle-1.49.orig/test/src/org/bouncycastle/openssl/test/ReaderTest.java0000644000175000017500000003055511703727736027055 0ustar ebourgebourgpackage org.bouncycastle.openssl.test; import java.io.BufferedReader; import java.io.ByteArrayInputStream; import java.io.ByteArrayOutputStream; import java.io.IOException; import java.io.InputStream; import java.io.InputStreamReader; import java.io.OutputStreamWriter; import java.io.Reader; import java.math.BigInteger; import java.security.KeyPair; import java.security.KeyPairGenerator; import java.security.PrivateKey; import java.security.PublicKey; import java.security.SecureRandom; import java.security.Security; import java.security.Signature; import java.security.cert.X509Certificate; import java.security.interfaces.DSAPrivateKey; import java.security.interfaces.RSAPrivateCrtKey; import java.security.interfaces.RSAPrivateKey; import org.bouncycastle.asn1.cms.CMSObjectIdentifiers; import org.bouncycastle.asn1.cms.ContentInfo; import org.bouncycastle.jce.provider.BouncyCastleProvider; import org.bouncycastle.jce.spec.ECNamedCurveParameterSpec; import org.bouncycastle.openssl.PEMReader; import org.bouncycastle.openssl.PEMWriter; import org.bouncycastle.openssl.PasswordFinder; import org.bouncycastle.util.test.SimpleTest; /** * basic class for reading test.pem - the password is "secret" */ public class ReaderTest extends SimpleTest { private static class Password implements PasswordFinder { char[] password; Password( char[] word) { this.password = word; } public char[] getPassword() { return password; } } public String getName() { return "PEMReaderTest"; } private PEMReader openPEMResource( String fileName, PasswordFinder pGet) { InputStream res = this.getClass().getResourceAsStream(fileName); Reader fRd = new BufferedReader(new InputStreamReader(res)); return new PEMReader(fRd, pGet); } public void performTest() throws Exception { PasswordFinder pGet = new Password("secret".toCharArray()); PEMReader pemRd = openPEMResource("test.pem", pGet); Object o; KeyPair pair; while ((o = pemRd.readObject()) != null) { if (o instanceof KeyPair) { //pair = (KeyPair)o; //System.out.println(pair.getPublic()); //System.out.println(pair.getPrivate()); } else { //System.out.println(o.toString()); } } // test bogus lines before begin are ignored. pemRd = openPEMResource("extratest.pem", pGet); while ((o = pemRd.readObject()) != null) { if (!(o instanceof X509Certificate)) { fail("wrong object found"); } } // // pkcs 7 data // pemRd = openPEMResource("pkcs7.pem", null); ContentInfo d = (ContentInfo)pemRd.readObject(); if (!d.getContentType().equals(CMSObjectIdentifiers.envelopedData)) { fail("failed envelopedData check"); } // // ECKey // pemRd = openPEMResource("eckey.pem", null); ECNamedCurveParameterSpec spec = (ECNamedCurveParameterSpec)pemRd.readObject(); pair = (KeyPair)pemRd.readObject(); Signature sgr = Signature.getInstance("ECDSA", "BC"); sgr.initSign(pair.getPrivate()); byte[] message = new byte[] { (byte)'a', (byte)'b', (byte)'c' }; sgr.update(message); byte[] sigBytes = sgr.sign(); sgr.initVerify(pair.getPublic()); sgr.update(message); if (!sgr.verify(sigBytes)) { fail("EC verification failed"); } if (!pair.getPublic().getAlgorithm().equals("ECDSA")) { fail("wrong algorithm name on public got: " + pair.getPublic().getAlgorithm()); } if (!pair.getPrivate().getAlgorithm().equals("ECDSA")) { fail("wrong algorithm name on private"); } // // writer/parser test // KeyPairGenerator kpGen = KeyPairGenerator.getInstance("RSA", "BC"); pair = kpGen.generateKeyPair(); keyPairTest("RSA", pair); kpGen = KeyPairGenerator.getInstance("DSA", "BC"); kpGen.initialize(512, new SecureRandom()); pair = kpGen.generateKeyPair(); keyPairTest("DSA", pair); // // PKCS7 // ByteArrayOutputStream bOut = new ByteArrayOutputStream(); PEMWriter pWrt = new PEMWriter(new OutputStreamWriter(bOut)); pWrt.writeObject(d); pWrt.close(); pemRd = new PEMReader(new InputStreamReader(new ByteArrayInputStream(bOut.toByteArray()))); d = (ContentInfo)pemRd.readObject(); if (!d.getContentType().equals(CMSObjectIdentifiers.envelopedData)) { fail("failed envelopedData recode check"); } // OpenSSL test cases (as embedded resources) doOpenSslDsaTest("unencrypted"); doOpenSslRsaTest("unencrypted"); doOpenSslTests("aes128"); doOpenSslTests("aes192"); doOpenSslTests("aes256"); doOpenSslTests("blowfish"); doOpenSslTests("des1"); doOpenSslTests("des2"); doOpenSslTests("des3"); doOpenSslTests("rc2_128"); doOpenSslDsaTest("rc2_40_cbc"); doOpenSslRsaTest("rc2_40_cbc"); doOpenSslDsaTest("rc2_64_cbc"); doOpenSslRsaTest("rc2_64_cbc"); doDudPasswordTest("7fd98", 0, "corrupted stream - out of bounds length found"); doDudPasswordTest("ef677", 1, "corrupted stream - out of bounds length found"); doDudPasswordTest("800ce", 2, "unknown tag 26 encountered"); doDudPasswordTest("b6cd8", 3, "DEF length 81 object truncated by 56"); doDudPasswordTest("28ce09", 4, "DEF length 110 object truncated by 28"); doDudPasswordTest("2ac3b9", 5, "DER length more than 4 bytes: 11"); doDudPasswordTest("2cba96", 6, "DEF length 100 object truncated by 35"); doDudPasswordTest("2e3354", 7, "DEF length 42 object truncated by 9"); doDudPasswordTest("2f4142", 8, "DER length more than 4 bytes: 14"); doDudPasswordTest("2fe9bb", 9, "DER length more than 4 bytes: 65"); doDudPasswordTest("3ee7a8", 10, "DER length more than 4 bytes: 57"); doDudPasswordTest("41af75", 11, "unknown tag 16 encountered"); doDudPasswordTest("1704a5", 12, "corrupted stream detected"); doDudPasswordTest("1c5822", 13, "unknown object in getInstance: org.bouncycastle.asn1.DERUTF8String"); doDudPasswordTest("5a3d16", 14, "corrupted stream detected"); doDudPasswordTest("8d0c97", 15, "corrupted stream detected"); doDudPasswordTest("bc0daf", 16, "corrupted stream detected"); doDudPasswordTest("aaf9c4d",17, "corrupted stream - out of bounds length found"); doNoPasswordTest(); // encrypted private key test pGet = new Password("password".toCharArray()); pemRd = openPEMResource("enckey.pem", pGet); RSAPrivateCrtKey privKey = (RSAPrivateCrtKey)pemRd.readObject(); if (!privKey.getPublicExponent().equals(new BigInteger("10001", 16))) { fail("decryption of private key data check failed"); } // general PKCS8 test pGet = new Password("password".toCharArray()); pemRd = openPEMResource("pkcs8test.pem", pGet); while ((privKey = (RSAPrivateCrtKey)pemRd.readObject()) != null) { if (!privKey.getPublicExponent().equals(new BigInteger("10001", 16))) { fail("decryption of private key data check failed"); } } } private void keyPairTest( String name, KeyPair pair) throws IOException { PEMReader pemRd; ByteArrayOutputStream bOut = new ByteArrayOutputStream(); PEMWriter pWrt = new PEMWriter(new OutputStreamWriter(bOut)); pWrt.writeObject(pair.getPublic()); pWrt.close(); pemRd = new PEMReader(new InputStreamReader(new ByteArrayInputStream(bOut.toByteArray()))); PublicKey k = (PublicKey)pemRd.readObject(); if (!k.equals(pair.getPublic())) { fail("Failed public key read: " + name); } bOut = new ByteArrayOutputStream(); pWrt = new PEMWriter(new OutputStreamWriter(bOut)); pWrt.writeObject(pair.getPrivate()); pWrt.close(); pemRd = new PEMReader(new InputStreamReader(new ByteArrayInputStream(bOut.toByteArray()))); KeyPair kPair = (KeyPair)pemRd.readObject(); if (!kPair.getPrivate().equals(pair.getPrivate())) { fail("Failed private key read: " + name); } if (!kPair.getPublic().equals(pair.getPublic())) { fail("Failed private key public read: " + name); } } private void doOpenSslTests( String baseName) throws IOException { doOpenSslDsaModesTest(baseName); doOpenSslRsaModesTest(baseName); } private void doOpenSslDsaModesTest( String baseName) throws IOException { doOpenSslDsaTest(baseName + "_cbc"); doOpenSslDsaTest(baseName + "_cfb"); doOpenSslDsaTest(baseName + "_ecb"); doOpenSslDsaTest(baseName + "_ofb"); } private void doOpenSslRsaModesTest( String baseName) throws IOException { doOpenSslRsaTest(baseName + "_cbc"); doOpenSslRsaTest(baseName + "_cfb"); doOpenSslRsaTest(baseName + "_ecb"); doOpenSslRsaTest(baseName + "_ofb"); } private void doOpenSslDsaTest( String name) throws IOException { String fileName = "dsa/openssl_dsa_" + name + ".pem"; doOpenSslTestFile(fileName, DSAPrivateKey.class); } private void doOpenSslRsaTest( String name) throws IOException { String fileName = "rsa/openssl_rsa_" + name + ".pem"; doOpenSslTestFile(fileName, RSAPrivateKey.class); } private void doOpenSslTestFile( String fileName, Class expectedPrivKeyClass) throws IOException { PEMReader pr = openPEMResource("data/" + fileName, new Password("changeit".toCharArray())); Object o = pr.readObject(); if (o == null || !(o instanceof KeyPair)) { fail("Didn't find OpenSSL key"); } KeyPair kp = (KeyPair) o; PrivateKey privKey = kp.getPrivate(); if (!expectedPrivKeyClass.isInstance(privKey)) { fail("Returned key not of correct type"); } } private void doDudPasswordTest(String password, int index, String message) { // illegal state exception check - in this case the wrong password will // cause an underlying class cast exception. try { PasswordFinder pGet = new Password(password.toCharArray()); PEMReader pemRd = openPEMResource("test.pem", pGet); Object o; while ((o = pemRd.readObject()) != null) { } fail("issue not detected: " + index); } catch (IOException e) { if (e.getCause() != null && !e.getCause().getMessage().equals(message)) { e.printStackTrace(); fail("issue " + index + " exception thrown, but wrong message"); } else if (e.getCause() == null && !e.getMessage().equals(message)) { e.printStackTrace(); fail("issue " + index + " exception thrown, but wrong message"); } } } private void doNoPasswordTest() throws IOException { PasswordFinder pGet = new Password("".toCharArray()); PEMReader pemRd = openPEMResource("smimenopw.pem", pGet); Object o; PrivateKey key = null; while ((o = pemRd.readObject()) != null) { key = (PrivateKey)o; } if (key == null) { fail("private key not detected"); } } public static void main( String[] args) { Security.addProvider(new BouncyCastleProvider()); runTest(new ReaderTest()); } } bouncycastle-1.49.orig/test/src/org/bouncycastle/openssl/test/ParserTest.java0000644000175000017500000003705712147611256027103 0ustar ebourgebourgpackage org.bouncycastle.openssl.test; import java.io.BufferedReader; import java.io.ByteArrayInputStream; import java.io.ByteArrayOutputStream; import java.io.IOException; import java.io.InputStream; import java.io.InputStreamReader; import java.io.OutputStreamWriter; import java.io.Reader; import java.math.BigInteger; import java.security.KeyPair; import java.security.KeyPairGenerator; import java.security.PrivateKey; import java.security.PublicKey; import java.security.SecureRandom; import java.security.Security; import java.security.Signature; import java.security.interfaces.DSAPrivateKey; import java.security.interfaces.RSAPrivateCrtKey; import java.security.interfaces.RSAPrivateKey; import org.bouncycastle.asn1.ASN1ObjectIdentifier; import org.bouncycastle.asn1.cms.CMSObjectIdentifiers; import org.bouncycastle.asn1.cms.ContentInfo; import org.bouncycastle.asn1.pkcs.PrivateKeyInfo; import org.bouncycastle.asn1.x509.SubjectPublicKeyInfo; import org.bouncycastle.asn1.x9.ECNamedCurveTable; import org.bouncycastle.asn1.x9.X9ECParameters; import org.bouncycastle.cert.X509CertificateHolder; import org.bouncycastle.jce.provider.BouncyCastleProvider; import org.bouncycastle.openssl.PEMDecryptorProvider; import org.bouncycastle.openssl.PEMEncryptedKeyPair; import org.bouncycastle.openssl.PEMKeyPair; import org.bouncycastle.openssl.PEMParser; import org.bouncycastle.openssl.PEMWriter; import org.bouncycastle.openssl.PasswordFinder; import org.bouncycastle.openssl.jcajce.JcaPEMKeyConverter; import org.bouncycastle.openssl.jcajce.JceOpenSSLPKCS8DecryptorProviderBuilder; import org.bouncycastle.openssl.jcajce.JcePEMDecryptorProviderBuilder; import org.bouncycastle.operator.InputDecryptorProvider; import org.bouncycastle.pkcs.PKCS8EncryptedPrivateKeyInfo; import org.bouncycastle.util.test.SimpleTest; /** * basic class for reading test.pem - the password is "secret" */ public class ParserTest extends SimpleTest { private static class Password implements PasswordFinder { char[] password; Password( char[] word) { this.password = word; } public char[] getPassword() { return password; } } public String getName() { return "PEMParserTest"; } private PEMParser openPEMResource( String fileName) { InputStream res = this.getClass().getResourceAsStream(fileName); Reader fRd = new BufferedReader(new InputStreamReader(res)); return new PEMParser(fRd); } public void performTest() throws Exception { PEMParser pemRd = openPEMResource("test.pem"); Object o; PEMKeyPair pemPair; KeyPair pair; while ((o = pemRd.readObject()) != null) { if (o instanceof KeyPair) { //pair = (KeyPair)o; //System.out.println(pair.getPublic()); //System.out.println(pair.getPrivate()); } else { //System.out.println(o.toString()); } } // test bogus lines before begin are ignored. pemRd = openPEMResource("extratest.pem"); while ((o = pemRd.readObject()) != null) { if (!(o instanceof X509CertificateHolder)) { fail("wrong object found"); } } // // pkcs 7 data // pemRd = openPEMResource("pkcs7.pem"); ContentInfo d = (ContentInfo)pemRd.readObject(); if (!d.getContentType().equals(CMSObjectIdentifiers.envelopedData)) { fail("failed envelopedData check"); } // // ECKey // pemRd = openPEMResource("eckey.pem"); ASN1ObjectIdentifier ecOID = (ASN1ObjectIdentifier)pemRd.readObject(); X9ECParameters ecSpec = ECNamedCurveTable.getByOID(ecOID); if (ecSpec == null) { fail("ecSpec not found for named curve"); } pemPair = (PEMKeyPair)pemRd.readObject(); pair = new JcaPEMKeyConverter().setProvider("BC").getKeyPair(pemPair); Signature sgr = Signature.getInstance("ECDSA", "BC"); sgr.initSign(pair.getPrivate()); byte[] message = new byte[] { (byte)'a', (byte)'b', (byte)'c' }; sgr.update(message); byte[] sigBytes = sgr.sign(); sgr.initVerify(pair.getPublic()); sgr.update(message); if (!sgr.verify(sigBytes)) { fail("EC verification failed"); } if (!pair.getPublic().getAlgorithm().equals("ECDSA")) { fail("wrong algorithm name on public got: " + pair.getPublic().getAlgorithm()); } if (!pair.getPrivate().getAlgorithm().equals("ECDSA")) { fail("wrong algorithm name on private"); } // // ECKey -- explicit parameters // pemRd = openPEMResource("ecexpparam.pem"); ecSpec = (X9ECParameters)pemRd.readObject(); pemPair = (PEMKeyPair)pemRd.readObject(); pair = new JcaPEMKeyConverter().setProvider("BC").getKeyPair(pemPair); sgr = Signature.getInstance("ECDSA", "BC"); sgr.initSign(pair.getPrivate()); message = new byte[] { (byte)'a', (byte)'b', (byte)'c' }; sgr.update(message); sigBytes = sgr.sign(); sgr.initVerify(pair.getPublic()); sgr.update(message); if (!sgr.verify(sigBytes)) { fail("EC verification failed"); } if (!pair.getPublic().getAlgorithm().equals("ECDSA")) { fail("wrong algorithm name on public got: " + pair.getPublic().getAlgorithm()); } if (!pair.getPrivate().getAlgorithm().equals("ECDSA")) { fail("wrong algorithm name on private"); } // // writer/parser test // KeyPairGenerator kpGen = KeyPairGenerator.getInstance("RSA", "BC"); pair = kpGen.generateKeyPair(); keyPairTest("RSA", pair); kpGen = KeyPairGenerator.getInstance("DSA", "BC"); kpGen.initialize(512, new SecureRandom()); pair = kpGen.generateKeyPair(); keyPairTest("DSA", pair); // // PKCS7 // ByteArrayOutputStream bOut = new ByteArrayOutputStream(); PEMWriter pWrt = new PEMWriter(new OutputStreamWriter(bOut)); pWrt.writeObject(d); pWrt.close(); pemRd = new PEMParser(new InputStreamReader(new ByteArrayInputStream(bOut.toByteArray()))); d = (ContentInfo)pemRd.readObject(); if (!d.getContentType().equals(CMSObjectIdentifiers.envelopedData)) { fail("failed envelopedData recode check"); } // OpenSSL test cases (as embedded resources) doOpenSslDsaTest("unencrypted"); doOpenSslRsaTest("unencrypted"); doOpenSslTests("aes128"); doOpenSslTests("aes192"); doOpenSslTests("aes256"); doOpenSslTests("blowfish"); doOpenSslTests("des1"); doOpenSslTests("des2"); doOpenSslTests("des3"); doOpenSslTests("rc2_128"); doOpenSslDsaTest("rc2_40_cbc"); doOpenSslRsaTest("rc2_40_cbc"); doOpenSslDsaTest("rc2_64_cbc"); doOpenSslRsaTest("rc2_64_cbc"); doDudPasswordTest("7fd98", 0, "corrupted stream - out of bounds length found"); doDudPasswordTest("ef677", 1, "corrupted stream - out of bounds length found"); doDudPasswordTest("800ce", 2, "unknown tag 26 encountered"); doDudPasswordTest("b6cd8", 3, "DEF length 81 object truncated by 56"); doDudPasswordTest("28ce09", 4, "DEF length 110 object truncated by 28"); doDudPasswordTest("2ac3b9", 5, "DER length more than 4 bytes: 11"); doDudPasswordTest("2cba96", 6, "DEF length 100 object truncated by 35"); doDudPasswordTest("2e3354", 7, "DEF length 42 object truncated by 9"); doDudPasswordTest("2f4142", 8, "DER length more than 4 bytes: 14"); doDudPasswordTest("2fe9bb", 9, "DER length more than 4 bytes: 65"); doDudPasswordTest("3ee7a8", 10, "DER length more than 4 bytes: 57"); doDudPasswordTest("41af75", 11, "unknown tag 16 encountered"); doDudPasswordTest("1704a5", 12, "corrupted stream detected"); doDudPasswordTest("1c5822", 13, "unknown object in getInstance: org.bouncycastle.asn1.DERUTF8String"); doDudPasswordTest("5a3d16", 14, "corrupted stream detected"); doDudPasswordTest("8d0c97", 15, "corrupted stream detected"); doDudPasswordTest("bc0daf", 16, "corrupted stream detected"); doDudPasswordTest("aaf9c4d",17, "corrupted stream - out of bounds length found"); doNoPasswordTest(); // encrypted private key test InputDecryptorProvider pkcs8Prov = new JceOpenSSLPKCS8DecryptorProviderBuilder().build("password".toCharArray()); pemRd = openPEMResource("enckey.pem"); PKCS8EncryptedPrivateKeyInfo encPrivKeyInfo = (PKCS8EncryptedPrivateKeyInfo)pemRd.readObject(); JcaPEMKeyConverter converter = new JcaPEMKeyConverter().setProvider("BC"); RSAPrivateCrtKey privKey = (RSAPrivateCrtKey)converter.getPrivateKey(encPrivKeyInfo.decryptPrivateKeyInfo(pkcs8Prov)); if (!privKey.getPublicExponent().equals(new BigInteger("10001", 16))) { fail("decryption of private key data check failed"); } // general PKCS8 test pemRd = openPEMResource("pkcs8test.pem"); Object privInfo; while ((privInfo = pemRd.readObject()) != null) { if (privInfo instanceof PrivateKeyInfo) { privKey = (RSAPrivateCrtKey)converter.getPrivateKey(PrivateKeyInfo.getInstance(privInfo)); } else { privKey = (RSAPrivateCrtKey)converter.getPrivateKey(((PKCS8EncryptedPrivateKeyInfo)privInfo).decryptPrivateKeyInfo(pkcs8Prov)); } if (!privKey.getPublicExponent().equals(new BigInteger("10001", 16))) { fail("decryption of private key data check failed"); } } } private void keyPairTest( String name, KeyPair pair) throws IOException { PEMParser pemRd; ByteArrayOutputStream bOut = new ByteArrayOutputStream(); PEMWriter pWrt = new PEMWriter(new OutputStreamWriter(bOut)); pWrt.writeObject(pair.getPublic()); pWrt.close(); pemRd = new PEMParser(new InputStreamReader(new ByteArrayInputStream(bOut.toByteArray()))); SubjectPublicKeyInfo pub = SubjectPublicKeyInfo.getInstance(pemRd.readObject()); JcaPEMKeyConverter converter = new JcaPEMKeyConverter().setProvider("BC"); PublicKey k = converter.getPublicKey(pub); if (!k.equals(pair.getPublic())) { fail("Failed public key read: " + name); } bOut = new ByteArrayOutputStream(); pWrt = new PEMWriter(new OutputStreamWriter(bOut)); pWrt.writeObject(pair.getPrivate()); pWrt.close(); pemRd = new PEMParser(new InputStreamReader(new ByteArrayInputStream(bOut.toByteArray()))); KeyPair kPair = converter.getKeyPair((PEMKeyPair)pemRd.readObject()); if (!kPair.getPrivate().equals(pair.getPrivate())) { fail("Failed private key read: " + name); } if (!kPair.getPublic().equals(pair.getPublic())) { fail("Failed private key public read: " + name); } } private void doOpenSslTests( String baseName) throws IOException { doOpenSslDsaModesTest(baseName); doOpenSslRsaModesTest(baseName); } private void doOpenSslDsaModesTest( String baseName) throws IOException { doOpenSslDsaTest(baseName + "_cbc"); doOpenSslDsaTest(baseName + "_cfb"); doOpenSslDsaTest(baseName + "_ecb"); doOpenSslDsaTest(baseName + "_ofb"); } private void doOpenSslRsaModesTest( String baseName) throws IOException { doOpenSslRsaTest(baseName + "_cbc"); doOpenSslRsaTest(baseName + "_cfb"); doOpenSslRsaTest(baseName + "_ecb"); doOpenSslRsaTest(baseName + "_ofb"); } private void doOpenSslDsaTest( String name) throws IOException { String fileName = "dsa/openssl_dsa_" + name + ".pem"; doOpenSslTestFile(fileName, DSAPrivateKey.class); } private void doOpenSslRsaTest( String name) throws IOException { String fileName = "rsa/openssl_rsa_" + name + ".pem"; doOpenSslTestFile(fileName, RSAPrivateKey.class); } private void doOpenSslTestFile( String fileName, Class expectedPrivKeyClass) throws IOException { JcaPEMKeyConverter converter = new JcaPEMKeyConverter().setProvider("BC"); PEMDecryptorProvider decProv = new JcePEMDecryptorProviderBuilder().setProvider("BC").build("changeit".toCharArray()); PEMParser pr = openPEMResource("data/" + fileName); Object o = pr.readObject(); if (o == null || !((o instanceof PEMKeyPair) || (o instanceof PEMEncryptedKeyPair))) { fail("Didn't find OpenSSL key"); } KeyPair kp = (o instanceof PEMEncryptedKeyPair) ? converter.getKeyPair(((PEMEncryptedKeyPair)o).decryptKeyPair(decProv)) : converter.getKeyPair((PEMKeyPair)o); PrivateKey privKey = kp.getPrivate(); if (!expectedPrivKeyClass.isInstance(privKey)) { fail("Returned key not of correct type"); } } private void doDudPasswordTest(String password, int index, String message) { // illegal state exception check - in this case the wrong password will // cause an underlying class cast exception. try { PEMDecryptorProvider decProv = new JcePEMDecryptorProviderBuilder().setProvider("BC").build(password.toCharArray()); PEMParser pemRd = openPEMResource("test.pem"); Object o; while ((o = pemRd.readObject()) != null) { if (o instanceof PEMEncryptedKeyPair) { ((PEMEncryptedKeyPair)o).decryptKeyPair(decProv); } } fail("issue not detected: " + index); } catch (IOException e) { if (e.getCause() != null && !e.getCause().getMessage().endsWith(message)) { fail("issue " + index + " exception thrown, but wrong message"); } else if (e.getCause() == null && !e.getMessage().equals(message)) { e.printStackTrace(); fail("issue " + index + " exception thrown, but wrong message"); } } } private void doNoPasswordTest() throws IOException { PEMDecryptorProvider decProv = new JcePEMDecryptorProviderBuilder().setProvider("BC").build("".toCharArray()); PEMParser pemRd = openPEMResource("smimenopw.pem"); Object o; PrivateKeyInfo key = null; while ((o = pemRd.readObject()) != null) { key = (PrivateKeyInfo)o; } if (key == null) { fail("private key not detected"); } } public static void main( String[] args) { Security.addProvider(new BouncyCastleProvider()); runTest(new ParserTest()); } } bouncycastle-1.49.orig/test/src/org/bouncycastle/openssl/test/ecexpparam.pem0000644000175000017500000000240112147574245026763 0ustar ebourgebourg-----BEGIN EC PARAMETERS----- MIIBVwIBATA8BgcqhkjOPQEBAjEA//////////////////////////////////// //////7/////AAAAAAAAAAD/////MHsEMP////////////////////////////// ///////////+/////wAAAAAAAAAA/////AQwszEvp+I+5+SYjgVr4/gtGRgdnG7+ gUESAxQIj1ATh1rGVjmNii7RnSqFyO3T7CrvAxUAozWSaqMZonodAIlqZ3OkgnrN rHMEYQSqh8oivosFN46xxx7zIK10bh07Younm5hZ90HgglQqOFUC8l2/VSlsOlRe OHJ2Crc2F95KliYsb12emL+Sktwp+PQdvSiaFHzp2jETtfC4wApgsc4dfoGdekMd fJDqDl8CMQD////////////////////////////////HY02B9Dct31gaDbJIsKd6 7OwZaszFKXMCAQE= -----END EC PARAMETERS----- -----BEGIN EC PRIVATE KEY----- MIIB+gIBAQQwQqOzUTcWWPBe9Kzj6uouD+1KZdEZRPWaTLFTXF8JGOoz+5SRAe3I ButvUDWYahuToIIBWzCCAVcCAQEwPAYHKoZIzj0BAQIxAP////////////////// ///////////////////////+/////wAAAAAAAAAA/////zB7BDD///////////// /////////////////////////////v////8AAAAAAAAAAP////wEMLMxL6fiPufk mI4Fa+P4LRkYHZxu/oFBEgMUCI9QE4daxlY5jYou0Z0qhcjt0+wq7wMVAKM1kmqj GaJ6HQCJamdzpIJ6zaxzBGEEqofKIr6LBTeOscce8yCtdG4dO2KLp5uYWfdB4IJU KjhVAvJdv1UpbDpUXjhydgq3NhfeSpYmLG9dnpi/kpLcKfj0Hb0omhR86doxE7Xw uMAKYLHOHX6BnXpDHXyQ6g5fAjEA////////////////////////////////x2NN gfQ3Ld9YGg2ySLCneuzsGWrMxSlzAgEBoWQDYgAEsnHT26mFzKjQEBo5yAt4n0b7 CdnrEDW0OUTnu7010BIpvbvBK0oVzGrdD9dsgAF2e4zkZN5TllLqY3nXvaVnWeJ9 KypglBwFvo1O3BrTtrsEe/oSe7b0mJm5YWZEg8in -----END EC PRIVATE KEY----- bouncycastle-1.49.orig/test/src/org/bouncycastle/openssl/test/test.pem0000644000175000017500000001622211341121201025572 0ustar ebourgebourg-----BEGIN DSA PRIVATE KEY----- Proc-Type: 4,ENCRYPTED DEK-Info: DES-EDE3-CBC,079DD7CA8A9BAA19 jIqIT0DIvUlwvkREv6gnCTVFdOsoVwUS9nxcVuQ8JOwg+TB42GnhgZ5x6MFczgNd Dw9L60zono+ethYfYB91CdIcVULzvg61/DCAFDjIFPgOIYTVNmteUq75Dmt6wDTV 4A07iMwjwBk+0YHaeVwcr0AkdvXEcVySOGdGrwy10K8Eq/kSndzm1Sm6tUCJ45+v zSUelLlT9fgRTmAbeowT1/tlt/q52bGTcXJzIWBxDuOxK5ASCTjk28kri9WeRUb/ iCnXn+cqR3BvkDCdlhk2A6A6Q8U9vo0m1MPtwwsolz76jnxbtBNr6Sc+zcny0brP jCPMP1qF+IIk01N3YsAZ9mbJmXYoFf9B0VwNUjPudWlSqhvmzzanatevgZ9TID8G Mnltd2XsqIgdvu0JhhEJRC6n7hBvn+l7iwYKtBoK+rJmEWWttkoP82UGgjzjzqKa rEtdaZPUCEiBLqHPyiIaDWm5Pe4sZZqrV8Ix8vDLKK59ZUkgmYXyCul2yL/cfO5T gjMqh9EeQCrNsu3hJGuEEE3MlskQkCpEspm9qDGbKPkMno7CE37plVopx0o0oovE S8MZn0v2lIzV8yZ6krtcEA== -----END DSA PRIVATE KEY----- -----BEGIN RSA PRIVATE KEY----- Proc-Type: 4,ENCRYPTED DEK-Info: DES-EDE3-CBC,9AC3CD3B4ED42426 AzAvQsDkxXGdPMlFjqO0lYXSlypkfGJWIMqij00cZI1B6K7pMnBHo3wIYStlKDg2 SMMTYwJfsbFA8+cyCyzsqVBQC63ZgEnStMrDOt/U0SGXNb/C4mFsf1ksnAI6y/3J 3lhuPAZbMKCmANslivbj9gp4hSe828btXDhvIPKKJgKHhwHveeW9JDulySAN5KYn s4aeasvSWVBOYtefFaS+NzrXjDnPtOMX6TQDxd9CE8es1RQbU9Ze2CEa9S7l4coj 0abWVTjxu55foDCDzbukkQm+eU0aaI4OoydoOCz6bcOfADgRx3/fJ9Z9IuS5w73O BiF8Z4S8e7GYpgsPVEqj06PuNH7t6bwzKC9U2FTiNcejZIYPqz21d9iA4hsEfFDd 0DlXqYUKMazE+TjU8goss5cEqyLNDQmWLYLKUE2p8QmSZC/UqEsZ9pu1VZz3xpFT k2sju26HCV14XPG5oi9LpxDQaVRmXBMFxz5b+RmUwPfZuWntTzHQXuNyH2J3B9FN el8gaskt4hxHI28hB/eF0h7pOIBUDiR9n/BB+feOrNW8y7/ThSkdI3OK0+dyOzLg go9s7SGz5WLyy8FWevw0k2Is4IpCueTwclDrOAPixW+paHhDGIasnvvCsz5jGqQz 4F4JPmA2ZYg/Z8dYob/ZeF/3KuJqFZAm9gseGS19sT7UzVvvmSf5IXOFfpb7VdRn ScFMRVr8PY9ANGh7zYg/8w+G3JJj4C7djA3RB/yOhK4KwbTz/2cnEDI26VREjKs0 7/WPQXxr/oQ+XEBTnYuJZfa7o7orGL+6wA0Vk/GJqjA= -----END RSA PRIVATE KEY----- -----BEGIN CERTIFICATE REQUEST----- MIIBkDCB+gIBADAlMSMwIQYDVQQDExpSZXF1ZXN0ZWQgVGVzdCBDZXJ0aWZpY2F0 ZTCBnzANBgkqhkiG9w0BAQEFAAOBjQAwgYkCgYEAsO4slP/KdZQsZyYn3asTWDtX E1YN+QQbbHELK7boPQa91YHv5DV/SgucThoXXCtSA45d3dQhrEbZ2+HRBarZIylk Nc+VmcV1qFX5KsD9wCYPMtdAYYog6jz259yCOKPDXPm787Q5t9h2zV3Ml1i0eWhC cdRYiWHQ5g20W4Bq3GsCAwEAAaAsMCoGCSqGSIb3DQEJDjEdMBswGQYDVR0RBBIw EIEOdGVzdEB0ZXN0LnRlc3QwDQYJKoZIhvcNAQELBQADgYEAZGPA0Jyw49cHPJjG bloqKAPNlBO200AiRFsHnkOQ1DopJff3mW+FdszAc9g6rTB4/YAiM4r0E314e0vm XSlW2q8sp+c2XJO7PUIdJIuAUnvSmMb/uwXFP2SzLdjLcmymMsnFfjvwkht0K2it O5HuUDuhLnxEimGlUEBrfkdrsH0= -----END CERTIFICATE REQUEST----- -----BEGIN NEW CERTIFICATE REQUEST----- MIIBkDCB+gIBADAlMSMwIQYDVQQDExpSZXF1ZXN0ZWQgVGVzdCBDZXJ0aWZpY2F0 ZTCBnzANBgkqhkiG9w0BAQEFAAOBjQAwgYkCgYEAsO4slP/KdZQsZyYn3asTWDtX E1YN+QQbbHELK7boPQa91YHv5DV/SgucThoXXCtSA45d3dQhrEbZ2+HRBarZIylk Nc+VmcV1qFX5KsD9wCYPMtdAYYog6jz259yCOKPDXPm787Q5t9h2zV3Ml1i0eWhC cdRYiWHQ5g20W4Bq3GsCAwEAAaAsMCoGCSqGSIb3DQEJDjEdMBswGQYDVR0RBBIw EIEOdGVzdEB0ZXN0LnRlc3QwDQYJKoZIhvcNAQELBQADgYEAZGPA0Jyw49cHPJjG bloqKAPNlBO200AiRFsHnkOQ1DopJff3mW+FdszAc9g6rTB4/YAiM4r0E314e0vm XSlW2q8sp+c2XJO7PUIdJIuAUnvSmMb/uwXFP2SzLdjLcmymMsnFfjvwkht0K2it O5HuUDuhLnxEimGlUEBrfkdrsH0= -----END NEW CERTIFICATE REQUEST----- -----BEGIN CERTIFICATE----- MIIDXjCCAsegAwIBAgIBBzANBgkqhkiG9w0BAQQFADCBtzELMAkGA1UEBhMCQVUx ETAPBgNVBAgTCFZpY3RvcmlhMRgwFgYDVQQHEw9Tb3V0aCBNZWxib3VybmUxGjAY BgNVBAoTEUNvbm5lY3QgNCBQdHkgTHRkMR4wHAYDVQQLExVDZXJ0aWZpY2F0ZSBB dXRob3JpdHkxFTATBgNVBAMTDENvbm5lY3QgNCBDQTEoMCYGCSqGSIb3DQEJARYZ d2VibWFzdGVyQGNvbm5lY3Q0LmNvbS5hdTAeFw0wMDA2MDIwNzU2MjFaFw0wMTA2 MDIwNzU2MjFaMIG4MQswCQYDVQQGEwJBVTERMA8GA1UECBMIVmljdG9yaWExGDAW BgNVBAcTD1NvdXRoIE1lbGJvdXJuZTEaMBgGA1UEChMRQ29ubmVjdCA0IFB0eSBM dGQxFzAVBgNVBAsTDldlYnNlcnZlciBUZWFtMR0wGwYDVQQDExR3d3cyLmNvbm5l Y3Q0LmNvbS5hdTEoMCYGCSqGSIb3DQEJARYZd2VibWFzdGVyQGNvbm5lY3Q0LmNv bS5hdTCBnzANBgkqhkiG9w0BAQEFAAOBjQAwgYkCgYEArvDxclKAhyv7Q/Wmr2re Gw4XL9Cnh9e+6VgWy2AWNy/MVeXdlxzd7QAuc1eOWQkGQEiLPy5XQtTY+sBUJ3AO Rvd2fEVJIcjf29ey7bYua9J/vz5MG2KYo9/WCHIwqD9mmG9g0xLcfwq/s8ZJBswE 7sb85VU+h94PTvsWOsWuKaECAwEAAaN3MHUwJAYDVR0RBB0wG4EZd2VibWFzdGVy QGNvbm5lY3Q0LmNvbS5hdTA6BglghkgBhvhCAQ0ELRYrbW9kX3NzbCBnZW5lcmF0 ZWQgY3VzdG9tIHNlcnZlciBjZXJ0aWZpY2F0ZTARBglghkgBhvhCAQEEBAMCBkAw DQYJKoZIhvcNAQEEBQADgYEAotccfKpwSsIxM1Hae8DR7M/Rw8dg/RqOWx45HNVL iBS4/3N/TO195yeQKbfmzbAA2jbPVvIvGgTxPgO1MP4ZgvgRhasaa0qCJCkWvpM4 yQf33vOiYQbpv4rTwzU8AmRlBG45WdjyNIigGV+oRc61aKCTnLq7zB8N3z1TF/bF 5/8= -----END CERTIFICATE----- -----BEGIN X509 CERTIFICATE----- MIIDXjCCAsegAwIBAgIBBzANBgkqhkiG9w0BAQQFADCBtzELMAkGA1UEBhMCQVUx ETAPBgNVBAgTCFZpY3RvcmlhMRgwFgYDVQQHEw9Tb3V0aCBNZWxib3VybmUxGjAY BgNVBAoTEUNvbm5lY3QgNCBQdHkgTHRkMR4wHAYDVQQLExVDZXJ0aWZpY2F0ZSBB dXRob3JpdHkxFTATBgNVBAMTDENvbm5lY3QgNCBDQTEoMCYGCSqGSIb3DQEJARYZ d2VibWFzdGVyQGNvbm5lY3Q0LmNvbS5hdTAeFw0wMDA2MDIwNzU2MjFaFw0wMTA2 MDIwNzU2MjFaMIG4MQswCQYDVQQGEwJBVTERMA8GA1UECBMIVmljdG9yaWExGDAW BgNVBAcTD1NvdXRoIE1lbGJvdXJuZTEaMBgGA1UEChMRQ29ubmVjdCA0IFB0eSBM dGQxFzAVBgNVBAsTDldlYnNlcnZlciBUZWFtMR0wGwYDVQQDExR3d3cyLmNvbm5l Y3Q0LmNvbS5hdTEoMCYGCSqGSIb3DQEJARYZd2VibWFzdGVyQGNvbm5lY3Q0LmNv bS5hdTCBnzANBgkqhkiG9w0BAQEFAAOBjQAwgYkCgYEArvDxclKAhyv7Q/Wmr2re Gw4XL9Cnh9e+6VgWy2AWNy/MVeXdlxzd7QAuc1eOWQkGQEiLPy5XQtTY+sBUJ3AO Rvd2fEVJIcjf29ey7bYua9J/vz5MG2KYo9/WCHIwqD9mmG9g0xLcfwq/s8ZJBswE 7sb85VU+h94PTvsWOsWuKaECAwEAAaN3MHUwJAYDVR0RBB0wG4EZd2VibWFzdGVy QGNvbm5lY3Q0LmNvbS5hdTA6BglghkgBhvhCAQ0ELRYrbW9kX3NzbCBnZW5lcmF0 ZWQgY3VzdG9tIHNlcnZlciBjZXJ0aWZpY2F0ZTARBglghkgBhvhCAQEEBAMCBkAw DQYJKoZIhvcNAQEEBQADgYEAotccfKpwSsIxM1Hae8DR7M/Rw8dg/RqOWx45HNVL iBS4/3N/TO195yeQKbfmzbAA2jbPVvIvGgTxPgO1MP4ZgvgRhasaa0qCJCkWvpM4 yQf33vOiYQbpv4rTwzU8AmRlBG45WdjyNIigGV+oRc61aKCTnLq7zB8N3z1TF/bF 5/8= -----END X509 CERTIFICATE----- -----BEGIN ATTRIBUTE CERTIFICATE----- MIIBuDCCASECAQEwZ6BlMGCkXjBcMQswCQYDVQQGEwJBVTEoMCYGA1UEChMfVGhl IExlZ2lvbiBvZiB0aGUgQm91bmN5IENhc3RsZTEjMCEGA1UECxMaQm91bmN5IFBy aW1hcnkgQ2VydGlmaWNhdGUCARSgYjBgpF4wXDELMAkGA1UEBhMCQVUxKDAmBgNV BAoTH1RoZSBMZWdpb24gb2YgdGhlIEJvdW5jeSBDYXN0bGUxIzAhBgNVBAsTGkJv dW5jeSBQcmltYXJ5IENlcnRpZmljYXRlMA0GCSqGSIb3DQEBBQUAAgEBMCIYDzIw MDUwNjEwMDI0MTMzWhgPMjAwNTA2MTAwMjQzMTNaMBkwFwYDVRhIMRAwDoEMREFV MTIzNDU2Nzg5MA0GCSqGSIb3DQEBBQUAA4GBALAYXT9zdxSR5zdPLAon1xIPehgI NZhjM7w0uu3OdzSV5sC31X1Kx9vi5RIWiM9VimRTwbQIod9POttD5QMXCwQb/fm7 eiJqL2YBIXOeClB19VrQe8xQtMFbyuFpDiM7QdvIam9ShZZMEMGjv9QHI64M4b0G odUBlSsJwPPQjZSU -----END ATTRIBUTE CERTIFICATE----- -----BEGIN X509 CRL----- MIICjTCCAfowDQYJKoZIhvcNAQECBQAwXzELMAkGA1UEBhMCVVMxIDAeBgNVBAoT F1JTQSBEYXRhIFNlY3VyaXR5LCBJbmMuMS4wLAYDVQQLEyVTZWN1cmUgU2VydmVy IENlcnRpZmljYXRpb24gQXV0aG9yaXR5Fw05NTA1MDIwMjEyMjZaFw05NTA2MDEw MDAxNDlaMIIBaDAWAgUCQQAABBcNOTUwMjAxMTcyNDI2WjAWAgUCQQAACRcNOTUw MjEwMDIxNjM5WjAWAgUCQQAADxcNOTUwMjI0MDAxMjQ5WjAWAgUCQQAADBcNOTUw MjI1MDA0NjQ0WjAWAgUCQQAAGxcNOTUwMzEzMTg0MDQ5WjAWAgUCQQAAFhcNOTUw MzE1MTkxNjU0WjAWAgUCQQAAGhcNOTUwMzE1MTk0MDQxWjAWAgUCQQAAHxcNOTUw MzI0MTk0NDMzWjAWAgUCcgAABRcNOTUwMzI5MjAwNzExWjAWAgUCcgAAERcNOTUw MzMwMDIzNDI2WjAWAgUCQQAAIBcNOTUwNDA3MDExMzIxWjAWAgUCcgAAHhcNOTUw NDA4MDAwMjU5WjAWAgUCcgAAQRcNOTUwNDI4MTcxNzI0WjAWAgUCcgAAOBcNOTUw NDI4MTcyNzIxWjAWAgUCcgAATBcNOTUwNTAyMDIxMjI2WjANBgkqhkiG9w0BAQIF AAN+AHqOEJXSDejYy0UwxxrH/9+N2z5xu/if0J6qQmK92W0hW158wpJg+ovV3+wQ wvIEPRL2rocL0tKfAsVq1IawSJzSNgxG0lrcla3MrJBnZ4GaZDu4FutZh72MR3Gt JaAL3iTJHJD55kK2D/VoyY1djlsPuNh6AEgdVwFAyp0v -----END X509 CRL----- -----BEGIN EC PRIVATE KEY----- Proc-Type: 4,ENCRYPTED DEK-Info: DES-EDE3-CBC,ADBCD679C6C6363E MmYmhTgKNKwwnA4AIskePMy+gp3Ch7Pn/UqRGjQypIyibbp/UFY+aSbQmvQNG2R9 6Zj6cbBJGt/C2EYXk9UonUTA9Q+FVytkpR8ON6NHlSc2twrvDpqi7lpeSB9ywlH7 WLffwNZMNsNHfcNK2slHf4RCmpqcGsXffHe45dQG0CI= -----END EC PRIVATE KEY----- bouncycastle-1.49.orig/test/src/org/bouncycastle/openssl/test/enckey.pem0000644000175000017500000000350211341121153026074 0ustar ebourgebourg-----BEGIN ENCRYPTED PRIVATE KEY----- MIIFHzBJBgkqhkiG9w0BBQ0wPDAbBgkqhkiG9w0BBQwwDgQIpII67Pp5Vs8CAggA MB0GCWCGSAFlAwQBKgQQBpkbyKLxdtlBlp6tm6lZoASCBND/h43o5NNNmTXWHN2+ N9ncoFknxohgShAc8WHKMHt0SCEJab8E2IAxVkYFMOMpvi1KVldcveLlg7hcMIDm 74pJmvXOW6b0bENvPMOxFadzr9NjO7j5ZT81dwNLz2pBLyiUMYElWl0LVnxKThQF qijJTDPcmTpFwDiUyTxzHxMx4DsoFYQulRBsZbRCAjsFpPM+OrOekSAyQHKMSbHU LvcdWCrSDRtKOyCeCPbBA4OzPJFyzep6trhbQii6rkddf9o54/oJut+LMuUblrHE 2yMStfW0G5ZyI7AeOxAy1gKG/CQrvFHn/yhtyjkvPa0sYVGtR4pGew+cs9iIsdFk nXOf9frJMA2agQZKc4+rf66NPv+dxVecm40HIR3omk7EnxR8s6msXOOn4qnY7qae aq1M7pKNqCu6eW5560mW6buLpOkpm/kDbr4v9rfCX41b5rIRzOdfAt71FSJcHp6K FNojK86YsNJWYh9pnfDbjEk7346cCIeJVgICGTmL8Tg6TUy9wIB6eKUXmIG3fKjI Ep8OzYAU3/ae8vdmZqD12l3v75muRPs4bP1RdjaVrux5Xlq8TkzU21ixWG6Odj7I 1jusSUjz16iR29XhLP/HI80GKYQMc2yHWcYQ1YVXyLzhnHYydrqjW5OTKZW01rbe 9BC8XlRzKZJ4IOQMfSiZxcdERtImO86Kprl4du7gvWaTUGTyiQ721Q08GfFdVuAn OO/J8stTLv2Ee7ugTeAFA2+qpz2vAo5JIPOmqjNqI2ytPjLRb80B3tSVXT41OodT D4v5YbNpySMDpw2F052Wx37hl2wNxIP98U6aw3ZjJdM/YfLdGOJhdoRTBDAvygRU Di6F56sDvX8bdXDUZURMg+iMx3Noc5G3TB3JpYunm3BL9lwGWesrkDzg3Vs1J/6c 4AMhAsw9+5tzvyGEDHnGZRg07K0eyWskDK0/Qb+vjSLOj8+QphM+EPCmugNnXRNo AdslIFoVfrcKruS1/DeSIesXvMd7sj2RH/xYDcAIGzmwbc+Ki4JTPuoZlF3pGMYE YkkYj2KHjJeX7CeUjCmU9Y7/jHp+fzlKsQAMQLVm8bRjDpvLA84RDJRoCPav333F YqRciZzMjfx2f6AJTCT+/8nv+DBiWcRtab1u6f+p1iDUa8bVt0Y8PB71gwAyonmY gp4A3fSilIlKEGsP2Hb4aU9V5vy1EZT0K0PuAY4yxGPmhedLCKdBqOuwQBxsLDP2 YmXR5wQOsI0dVE8zogpgOGOEE9RXNAf7QV7pBOPNu4HQLNuZi22dKi+wkyMLsIR5 dGEz7uDIaGQMvlprtOA02RON3gBnQTJAp7E/YMd7OldSBShRRGeIDw7yTrLoHwLI YnA5+ZwFLBPnOrnBC47CwgB2X/+ooL8/+yigoajZIIE5RvzuKRQGjC/ZgSHXSHrt mJKGerOR/3+OYYCTctTa3wTPVRc/vB1hZac9OPmnKpeywCJ4Q+jX+ZOhHOM671H6 h9fLPd0tSE75gIkSuJqBuLV2TB1cp7BTnrZxLywCxC779lZBTVLctXu60kiIoW46 zgEz1dyf22vfMN5ss0ybvBVCl8ROmrVr8ZWObzkj1MUyifDM8Tayd3uZ3SdHPo8L 2G24+4bjyVdFjUvrBdzB5dNzAQ== -----END ENCRYPTED PRIVATE KEY----- bouncycastle-1.49.orig/test/src/org/bouncycastle/openssl/test/data/0000755000175000017500000000000012152033550025030 5ustar ebourgebourgbouncycastle-1.49.orig/test/src/org/bouncycastle/openssl/test/data/rsa/0000755000175000017500000000000012152033550025615 5ustar ebourgebourgbouncycastle-1.49.orig/test/src/org/bouncycastle/openssl/test/data/rsa/openssl_rsa_blowfish_ofb.pem0000644000175000017500000000331110556327510033401 0ustar ebourgebourg-----BEGIN RSA PRIVATE KEY----- Proc-Type: 4,ENCRYPTED DEK-Info: BF-OFB,B9F95E282FEAA06D StEkcUPp3txNaJlYBP+eVabWYcEzAkX64aj8vaDX64i7bVl4ospAs2stac7uXtXG IZLTqNNACoqC0jWWTDJca9vTEoqjDRKjN9yjXYfrovj5oKi79wfsSU29oH1dcKG8 G4y8qNsA9TexRQDWTBxYO6EiQFVie9O3oXzjhO1hYwxldSWOV5ZRWoVmg16vAOxX Gx2W1twtjQXG/hp0HxosPkZteUDdhMZLWonYuqEw1oBC4iDG1Tjp0p5uSnb1gaIr pzZScikP0Z4/8CxiKV9/C1VNE70EHdAUYKjUx2PAbPaMFyO/sAXOy1INI7Wis7jh U2wKeXgCMRxmca4OMITcjDp6OGmKf41uWyTFwjO1scMvjSJsOZxNjAjcrZW1PPRA tvnhRpU9h1G9BOH2rM7VUI6zJ2FSNKG9R6M0WOQqxRegJzvK+YNLhw5lUzrbWOR0 RdkKL15gfnuXqLTDTMuLX+aCDS1Mu/ZRmDqLWkJH4W1HJ4l2rBojX5fcbamueMyf Sbd1S7QtmF/B9LaGDEPMT12kOQHZkRBUYpyolK6BoMuRPYnGS0RkUwvIuPZA8uJU vHHuYRZsOA45YFEipyB/sek61bvqYy+8TaPxzpfj0fkh7AUSQmbk3qQRkQbltzqq /MkFShIzS7SUkyiowOet8fVjXDJPsw2bS3uOHC4zy2QQmhVKzCYWd4yCFl+WtJnZ eEkrZH2BpoCDEzKlex/NQlH9KBLOor221nJEVd5tkdWWZt71eGld20eFL3ewtDqV GJX8jFmR51vQL6NZ2Ehp/5zhearuBJ8VKJfFxIKSrbPjyCbEwUgYOyVHHyvYyMR/ 6hcflrUu1IFFwFhryg2bucAkdX9AhsO1dimxSgZKEFlZbihPBysCdUw3WRea57iS n/zqLrOm786KiWh0ndBgJ973g1x+OeuUvbNl/0yiO4Vjny6PkXcBOORu+ILEflzf UiEKyG8+cYzoYZjeiCFBxsA2+gZMdgjxVYF/lKzTqFkfpwYV+tF2K5N8W51cL8Is yhz5OHiENobjx3QeFCZ4LWDEXg1H8cA34i9oELbXtyG7W+hkZp0B9tRDrXcDwVWk 4oYqWLNCQXqr1lL6cCuctKLdXbc1ibLt1nYGpJrPkPCbOshsI+iCMmulT23s+jqW TMW0RNb3wFjR5z9A1YTWfiqMKEcyzRhP6bEM/+WNmHE5LRefx+dnvZrVJzGZA/3k JAOpsxEPKv7YNR8N9yoAopRfFEOH4HYtLbsAA2sZfD6iVAXAAeiZ2Ehn+Bvek5lV 5zIOtsXswRgzXvxXCPy0V5GWqMglbkUS2HGsWaHpxDSMbvBJuaSi2blZ16p3IICM 7YcCLolKUaWqpXjhb3UypoYRwJs+40EiXid7aJ8rKoeId1SeETOwVWkz95NMiVK9 5K37/OMvxOAdjAUxtmz/+v+twKfrUhYqP3Qkapy6FgA+qxnzpCFZZXrMKjpr99Pc QVNcvM/SKWB34jZGTo+Styc7d+iXDC1BUS/43Pvbka/Aa2IV/LPQA2pD44aP5l3V /tOfQFQWI0wCqpBPV8aXqGuqZU2ES0yc9DJ974a8NvS1cNWfsMcvNg== -----END RSA PRIVATE KEY----- bouncycastle-1.49.orig/test/src/org/bouncycastle/openssl/test/data/rsa/openssl_rsa_blowfish_ecb.pem0000644000175000017500000000332110556327510033365 0ustar ebourgebourg-----BEGIN RSA PRIVATE KEY----- Proc-Type: 4,ENCRYPTED DEK-Info: BF-ECB,1E15270A7DD42BA2 zz3p7Ml80hSdlJsI5RyvOScQlsGC1GLg3AK0dC/Hh0IKPTDF7a2OITL6H/y/3txz LJ6jAcobjRfVMWGAJUwFaSlE5QF5W1+RauV+M8oMmv+Mf2K/Urha6m63EauLEVWu IDtxj74qfQgyd//qWHU+XmWhhNEGk5MrH163VITZqpG3Qe9dYHdalh4TB/ILJqfN URKLjdz8L4YbL48dwK6UxargixQ3tfrvIdTr4mkMiquNlayTk9g5qXWnEXy+I1DB HweXveJeSUHhYRXdx37y2I8Bz8HcuZF5wODEDJJuYXy7a8Q+Ar0Ll/uQ4NXE3iI0 NA8RA0caAlc+Du/xfzKdUgIPQaLt/sjhM4gPBDLlASUmO+PJfb1VYgDIbNbXiR9x 92ePzennPnbhKsPcuZzXoc/jH2BiQwwRT2gLscZ86n9O1FNoaPAnYERlyNIVrQoC 0Ll6NnGBM9Ls5k1royQQtZU2x5Yu5Q7DGcNqX2yI14AZrI4e9/Y0nEa+17WRD6eO fdaIC5dVrv8HZxlfzwFs33FpufovP2vlINWM3IqDjMf4FIQsoLdnmTsgoLRYm4JK zfcyiImXPt2iUrcybZHKa0EXYjrcoIVBS8YP1UTcG8WHnj3ploMxXOw0AmpXcznf sbLsaehbs4ugM5G358PMeWFXTv8K2YXRtArXHtkIYzA45zqWzpta5E7LiTQJfBRL VNtLja40a0gaajvROCekEzWhezZc7bu6RQ/XZXxBYHx9m7nhzKRkDlBrrJVpWSW7 QmS0ptXblyt2tbaUtNLsi2SP7gP9ggTlc5hCpwygT+lxrcr6j18CiPgMYOgDmFY7 gZ3jZ+HHd2+8GnimOai+r8wh1aW06/tLfIZxpIn4T9yGh/EMW/R1RTJjN0xe6oqw wC+TPUM2bMvDtAvdn8bYh3pVVLXnFa6LjhhgNvnx6wBoiBCJ4E9R1Ec0QA4jF/97 B4e8TEv7PAFB+VGhIPnQqfsAqRfM88FwgZqSfZrBXKMVWA7I4fBeVD0cJQq8TwCz TY9Fi1YnomqTfacH1hf9KiX3j8OkfrhIM3+w26nE553/wOcO42YJ55NgnNXlQL2e e1s4uJ9lroATY2WqvgLy5Th8n5y6kVkjuODb/8hk3KXqiLqbUOmZCYLuT4ZHZ+Rk xtWuFpmFiuWgbg6Nr2t2KYXwD39pjGBRmmwMX1mBxmUD9NK28yO4HEgiPVzfn7sU 1PWC7HpgPf797M2/N1gyUfrBbfw4OXWpycvmtJLXHEJi/p/H1bz0MuMJvPtNhzUO CP4jq0xbu9nT5eW9rD7kgvv10W+aUf314RcWKaLkOxkk2dTENjbviASce5X3ZU4l eGG2wtoHvCvHnNVj2ImKf0jbAL7dymVJlA1XwsLANAmk+9RGyVJgHn7ZkOfRVJmW VMfZ6AVeFY5BeJ0LCq1uE6QMClVx8fLN2iBEqamBNekcZ62Qz3b1R7ZbN2tlPKee JnLSouju6Mu8U9twVI2tr63OTh/a0XAjtlO0OAXuVcOmYOHT9fSjPdAAt3Rp50Sj PDvgN8s+qSkQKpx7C2OA9Wisrr71UrBrCfBhCOmN5gyWFg24PwwRKUnc1a8mT5Zx -----END RSA PRIVATE KEY----- bouncycastle-1.49.orig/test/src/org/bouncycastle/openssl/test/data/rsa/openssl_rsa_des1_cfb.pem0000644000175000017500000000331210556327510032405 0ustar ebourgebourg-----BEGIN RSA PRIVATE KEY----- Proc-Type: 4,ENCRYPTED DEK-Info: DES-CFB,07BD7DC7BB2EAC98 yH7T+ZIRWmzcMociF5wV3YjHWCUMs9C/GUrnBP37vvJrBDBB3x0u6aQMaOs0U1Ih xbGOweaw7cMag1HhafjVK9ZFZlYsCfXRZk6JdOvzPchDctQrnjkDxnwpOllmp0w4 Mg9mYLuEvN968Tx2TS26va/rPAu3xxA8mrcCuSfyt6O9HteT1axwDpZzOktmnbYy xHQDRcpDXaXspP2sVTaZJ3oq/AMGfrFXCu2m9jFHcyZKmEm/DW2aLmfOI5I7gCLP 1KMekkauODnQZEE2Iyi1SVbTBKH5DPp7yXAXWOtugBcWNHbMF9QHqKlMs5Hd2MYg doXtBSRRBc9pLdF1FMwHHjPFI+GZL3hurqcD+YyZJqYvzEgnI9dls2K8MzQKYKDn 6VpDCNbEf8aC0QmvCLIjqei5fH2RVYeV2M4Db1GDmpRAIRJEq0fXf5ojAD0Mhv6p DZYsz+f/MLTGwce+HCWxZyAyfptdK2ScfvaH8mUr1OHd5IdvRudh5+9sCtch5xQL DFIp1eBRd+2gvLBMja7gBE/xHXoFZtTR8xORCwgYXVrLLf4wG27XLdKQVQiS8dpi E+xCtiZmZfxb/1Ly9yHP/ehWD9DmxRRr/n1QeGMjSlLSzffuLgt/0tftK5yOSZri Xc1T83n5rLqhBglNEvwR1ewsTgeIxkgZo7q/LFajrnGh4L62cIoLkLX3lG0jaEC5 VTa06i0b7U1nJ6kiqjHuXzkZWjTim4V7p7r/SQtAGuK3s8AmqJH53EMmiK0zFq9Q ao1ewixzD4NplA2HY4kAAVRQMR7WWIRrV2wXRTqoKwITMbZ8Yio8PwgSjsYhuzwv Mct1CmTc2FcCH/+AZOqc2HNS4qwQVmwLnOLmsr7L9kgf9aPIl1hkn9KzC6GAU+fZ F+N0Ti7d+ZkNAtAUg8fi2Bf/rtPvxmyJp6QICI4Tj4MFpGIRWP5rLwU6XXNch0l1 nAcIYFvzLNL1v0TDnDz/CFW7XSp4IaDl0OLyAt+JxnPuFOAo1wJOhUWHheGynEBP U3K4u+761XMdqHb1n14OSgfyynIuLM6WtnBDoevKX8v0dYjO6PnvcuZoRqs1sYKr D93XsV8uMv79Oo84xQPHpJrUIJVLDeE5GLFimD7rUPvMURg1IrFnGyfcMGTvsv9O us/B1dNmOHjG7eZwJ/8MDNsYcpwm7CQsTOJUZkQDN7MZOKJZJr2gQK659eULJwaZ lEkR2p6A51etvlSPZ2pjy2Mgxk/T0mX/mVprEvCkxFWGlAxys1UFWKHDOOP4rUZs iE7nxBMyW+4zHAcco4Nly5gryqWiW0gn99/I7+qQHkb5X6ydP+GKOHmUdcb8RPIH Ec3bV7mBtfYxDC/ouStuQdVC7jWGwU7PeQqoz4d3mhK8dfeOvpudiTD1BLw30LKE Dt8/tob6zIHMEA5NTu6g5cbfa0lhRH1tD+O/7RejWPwOTc1LbY2igvHoh5uWTo8G ufvYO41PElmJoujef4njSZHcMvHArinYdlWlvMIg52d7Y3lQTTztY2UeO6DKRHx8 Qjda5g8SDiqgFktkl5r9FYfqMQFqheSgKnHaJ2oPPbwuJyuNdy2Rug== -----END RSA PRIVATE KEY----- bouncycastle-1.49.orig/test/src/org/bouncycastle/openssl/test/data/rsa/openssl_rsa_des1_ofb.pem0000644000175000017500000000331210556327510032421 0ustar ebourgebourg-----BEGIN RSA PRIVATE KEY----- Proc-Type: 4,ENCRYPTED DEK-Info: DES-OFB,62D0879F9BE636D0 +iyQyk6TcPldmHOJyjJjsJ4BgdDqqdQYRzQWC/WfDLJyw3CXLquWDciAw5aCof3k b6R4PvJHzvG6j9jdlcv+yD5M3j9ZVHYkLL0fTZA/LEODUOTX74gNZfoz3FGarYIV TabFLgwQh4YJ0+Nb5N/oISaNszC+wxf20D4N445kvuHKbak7o2j+5ZzGId9zYIPU Jat1HygggKh9PtE4NildizyVVK5h8ws8qPWbe2/m00Hf5R2oP2YC3Afn6kqMuueJ RrvP9l26WboAKFED91xY3gJy8r3KkkLOJq9856BlndtgkA3USqRM31W6RvLqHUDy 3l4ZY3wSTCdZIX+iHV6Qm3xYaIHNzYjHRcPQKdOVmEYiUSmAZmcavcsPC7sEfD7d OMEbrYrztF8iO90Myey/lJxo9RaL5PfWbtXqnXKUZtbcudEQd1fXM6gzdMm8AT4F eUSayg1/3AGEEHq2PH8kKtxnWAb7xBOgLbjTuC68f38dFw2P8iWZerG5lbLsFuwD YZ5eItuDhL8+dbFxisBX6H0lzcm0pwK1HCHOvSCcYfpWC4QrU08WbtI7NCqIuRWv 4QOHU6SoNGW99BSnUlsqgLdIcsWsyTwiotZqusZV9AusdsGqU5ixwal4YX/8JRg+ 93EwnFnl1Y0Bj/yoAwNfvPlZhtjevsMnPEbrXbFEm0Xw1kdhOYokrx0hQWUmdt7m cFdmFBYQGsiKucvRpmInylrS41VQNbNySqQ5iGa+vDaPBMKZusvgPgwWSchotkzT qTQ7HNjszwR4eIjBOiBSvY5YXoa9H3irdmLn76mOyDMjaQyC9o/0tbAagLKADuF1 Ui4Z/3WV67SuUoawqDJsYEWbOaNFX04wFby0k7oACoNxqoGFM3ITRzmxnz3ZyiPE DV/grOZICMLfTQ81VvE8/w+w697F6EJ8rY1yOznglP4GXrtIiXAaJbxEOhosyuN7 HikpDQ3GRnPzXeg/Yngzpp8JMVdxKdEItcXnWd9uhB2Ok1vXH8LjhVkhrL76bJe7 bhagz+LphPaLnkE5BPHKLUwL8bQQguz7ITfxsEFpWIHG5zCtpaQwdMEj2ePVubN8 sfZ3qhDRNG8DdwXgCbCot16SKGuOawMMC5tsoeg3DFQ4MBDrKUv3C9nF8izTs1Zr 3J7kWYrZg6+hVcJDgLS3t/lbFIhaNAULmep6wl4Vcp6nBqr395r8/uDroOpoBxoa BNjvFaztkRy3XmNHp3TOYLg5HZPWsK3KXOs0FvdTMEEsnoj3PXz6+hw0gMV6huYp o24r34gKiwdbrkbwLRnyh0oF6d3bPOZ9WnPgA2y2MB+slulA47+hOMcP9+WiQxE/ eGd6TTRjMPopQXJw7/tZEf6qyVYLWfKJmI0tljsea48NocZdsek+e4ZsTW/iP0oZ wPDYNt95V64APcDZfNtfzydp0516KY7p624TanOXsxNNiBV6Nuqmd0dGhbmcRC8Q KNgGNvgjF3rhqrXZyFpnZNQewE7a87bgmO1O772QU6GmPUZr3nzPRwE/8+TNA9AP hHL9HtItZ3arx7eJ42obFrxj3uzpQ8WQo/cGLgQT0lz6u91xJyWi2A== -----END RSA PRIVATE KEY----- bouncycastle-1.49.orig/test/src/org/bouncycastle/openssl/test/data/rsa/openssl_rsa_rc2_128_ecb.pem0000644000175000017500000000332210556327510032631 0ustar ebourgebourg-----BEGIN RSA PRIVATE KEY----- Proc-Type: 4,ENCRYPTED DEK-Info: RC2-ECB,270AFD04879E8434 u8jYUJhoDMDNI5cHXhnJJ7Pm0lF+MrOl84maQOwfwZ5hBbjpx9s+z5SMYpWfz0yQ WlgBuGkaY1UNBDrwH6baA9/eqUzem9ZK+mYmjKC30OaumjKVJIB7cJfJf6Itcaom SH1W0kJYeDn7ANdmstOGxbr2TDCr0BXa+7j8cTo2TZX1rfsXcdmjQ+8Qa8zfQ3Q5 FbrO+VNmAQwO7HeFjms38+ukJRW30EPibmbzx/YTCZ7XtCsXt6t6ggYja9Kvk/eI khwvFFk4g6Dv9YU+x2pyrkquIiTUo+jm3Vqhz2m0cGcqfynVEYn4fNPc27Ekw3uj CrprMgnfaX8QVx/EkpDYp7gpjcLYJObpUTcBo5iA7R3lpQ8itY1Ky7u6MMwQ2VHd XZcsS6b06mp2EW1CO951ZaPyma4AqoLl2gZ3zH4qPygp7uxrGdFdFSqrapVkDee/ lLtj8Z+/g1IyVSIW2FP/SCoustCHcqeDDq70GKY9qiahNFybWn49vZAPB3HPM22f mCcw4ALiKr0S9oofxrb8PKxmDQMZAJqjc8qRMLktYh9rJLMoUG2bmQqpKmLLpx5q 3CaKi3wofc005VcILyRgjumscAcpbTEz4vcR4jTwMPNP+WI8+AHtg0OcF+7hE8qc a9KTSsx3eJNbqq5UYxVjV/DcttNx9ENllnG+jEdttkaf+T9rJiayc0WPd+Eg0XlN ByBG0RCPQVJ9YH1Yke9HGE0FXv7FV6x4c22ePePcyE6VUNBoxdmXw+KRhRlvtXtM 1fFMwUrY//jEpfbf193avTVVctDTLxDSmwY6eAMBm81uDTlpUm0q7l2rRuKzdgFd bG/MTOd/j7wtKJbQpbUfUNFtF6zjssPdGhJ3l+8Rg4xZyHWHgU5FYGodp9RsxUhm 8AzoPDcVbbvu5YlPP+XvyEO1860fX6iSZKuOV+owjh2i51CPzsgX6OrOEb6/1rc3 M5AkLVl4insmetdTqb9PHCgfD6bLYcDBj7Qnf4HEDQUGcRFe+jogOoSH40C5UgPq F83nXv6WYBb2Y97lhb44x7d1MzE1kkzQXlyf3QuZ0ZjOvm+LuOWkbQWmLj5JhFJv 9CqY2MBL39EFamKjmmBmjrRsI9XMLHvB7VvT1hJPzxbF3UwDZ5BsA8IXSps0EjXR rZXSwo+vqTa3NlvysgvuJJUjwyf6mN2SVrNaKnZZ1OGFY1oQ3bmOgdI+SW9cpGzY Y8eFpaG2RAiOfBZ0JIyBUoHUH1MMMPw+Mh7KzIknP7O9htwiAWEvkcjWr7X6jpG8 sBdBmszX3TMDTToQ6DvyjVRP7mJ39dV83bLI3EA+N8bJcTOcHijCvbzQM50WzMu1 2UA9e6rG+ouQAgwaAHdR6bwm+Zr3e7MswZ0Q8/Snd1UdpyMyJ9nb031NSRSvkEyB ipu85/738J/g7tAIOJwwHeVWjL4lnrLC3CwbtvWAQ9Ox8Sjv848608GzQxFwHBHJ 0NWgt/AfLYsq4bmmFWtqvqTjWeAeUsM+67UY8m6/kxhfRNNN3zZcckq2zlF7TRNU 5AL/3KbVVLQl/7fD36m8AK5eImR+Gvom8ryzNacbNCL55ks0sycbICulXbdb0Jgm -----END RSA PRIVATE KEY----- bouncycastle-1.49.orig/test/src/org/bouncycastle/openssl/test/data/rsa/openssl_rsa_aes256_ofb.pem0000644000175000017500000000333610556327510032600 0ustar ebourgebourg-----BEGIN RSA PRIVATE KEY----- Proc-Type: 4,ENCRYPTED DEK-Info: AES-256-OFB,E6AB8D4FECB44185E26505049A97B0D6 Fg8Nq9CxyVZmBNEiN9vBI+gsZL4lvWqCPaR5E+Po7acLxYGos4zIcmLCBa2X8lvM UInn087k98OAClm+0PvhZ64/AdDE952UclD/xiNvQCH25HGQy7wk/BxuOM5/FT0S rlV6RGMibelHpnv+yploYoHD8CSo77N4RHdEuepPwod2fGTKu5Cbbt1FBGU5LXWJ BrDMOlSN8P/rD5ePADhDsYnh86g4cBVHTb3MkrteLa0m1Szt47E6d3s+Ued8Cg5S 7tiJOTFnXkmG87LsLZ0HDp6yML3g2gpTL/1Zhn9zS9lZc3cnkBfRJmttLBPjVCiB mStjlXnuJTDBdgQhJPJ4+2xJiR/ucFbCnUF/VICsl0hdz2Hd0PCOdhzj6U3jbRk4 uI2sv5TV/E+e/Ppvdh2W8LISSBdIwp9CJf3se8RFz1dUXwTMGM50LKr/dpvy3T4m NMO/Cf/LyA7HBFJxjqf++wi5LPDXzROm1QHncvXNUjypNPND3RhP53pMeQ/Ffd04 dw29zrmbyQKQOOac5Ss9Lj33Q/WzBgw5UxxxMxwRVDyfFpdz6JRfMrnj2c97auLI RI3euI9A9yRNxneBKTobS0EjYyqAiU6b5MbNwrybqvavbA/+ZMEg9Ylg7vtBOXpW YLLYFYPhWNEambOfNJi4tHcX8znGACxO/W7v3Ir+QFhw2IzSvntcMODKGaNKMGys HJ6mqKbmYidjhtKen1qHB5u2bukaGWUj2kjkv7jjuDK3ExsvB2PjEV5d0foPEwW7 9QQeKc5pY4tOxFVA4qCq1tTzUhWr0mBkPhnFjc7XOLbu0sHYdr6ArZ3SadaNT12w LG2yg5r8BgmaUVTTQAzIiHhAQYZoCHAq+ohNocIikIh7lPE58DL2GPpEdXZsgzTi T+EUSkSw4VtIMmnWw5GNE3zCOxvx5qzhKiXVcnB+2+IF3nlHkQqFXcYNGhezZjnJ 4FlR4FPzumRmMj1x0zmdbp7eTFpipUpKqJtC8iuea29pEl8opXDNhvmpmrT4/429 7x8eJOjZhm8WL1dVpV2/Ikc9boEsYzHcBkY7kuaTqT8I9tdQ08ODo8UE5aReaFuZ vlBY4J+A4lltQ7qQ+sAk6gUMvlY8h/9L9gZiGbLe438Ndizskuwy+jAZAEx0f0cK YnTsZxBHPkWQXgBHMhe3BAAA+CZaXPps0SjD0yMQs7lkAgag6zBXW2vqttoJLU9R f6uP+BLwZCFDF1NtkROLV1oROnaGvMbHWcar2tw5qNe3BAsPQqGk8XnqwILz4IwX MN6QrjzbBC2jcL5jsxPZ/Tis9+wfI3t1Ke0EljYqA9RVWuC2KtRK+X3xOK6tWEK+ QlagHRDI0Z0u0slCLjpB/ev9Ajqwlr0h25T5ucdsLd3FFEKZbzspdfsJuOXPM5la Uv9gpYIcuFrKcVbvuBPzt6NX/rp9gozZv7ZOnujjor6RDorHsfbgbEfcerydvJGu PRk788TkAB0LOE2wD2J2UO8+Ufp1qK9GWmtr0WFCazqFfeiorTh71iS7pwUt08so 0BRkqfrfP6pXEcnh4p+LKh+dnbgIBD+KH0qHsyc0ci43byoOSDDHnQ== -----END RSA PRIVATE KEY----- bouncycastle-1.49.orig/test/src/org/bouncycastle/openssl/test/data/rsa/openssl_rsa_aes192_cbc.pem0000644000175000017500000000334610556327510032561 0ustar ebourgebourg-----BEGIN RSA PRIVATE KEY----- Proc-Type: 4,ENCRYPTED DEK-Info: AES-192-CBC,51C73DF9487965B976234C88321E3F30 6yLkX7C2XTX5AE6KqWsB2Lmt+TMGsoHIH5BDl+o7Yjx7aBSzB9X9KPTsVoPmTCOg +yhhV6am/yBImCdyuY8d9Q0A1kPIJTEkshgk5vc2KpW08blLCHSCjokEVbQ4TJDH bMtrEBVMU1g9KBTMuBpbu6MLVaFth2GTsqExX2gu7FB5EAKvEGhkmLudo1jKkgvR aiiyMd2CH2MTdatZtw5PrJmkhV/6RMZRKP8r9wkez8NN14ehmk5QDY2s/hj5uaEf xK0GXY6OcwoRo85PsOYhmOeFDqHKGRo9a0pPBy5ZaV4udj0QZekE1fziOxiPf6K8 0BL50UUzQBW+3n0dIZbzlOiJQScQkjoxi0kc088FHXHf74VBoJUo6pckAu4OwpXW L4XLIGAr2Kv4OMiFSJOcaihyawE312B2URcAzVCO7skhTYHaC0fMYDJCGTc2D9rR +V5tVfT1dG4xdB+p/b9TQyAu8PE10jT+tVNJqGsZRI8I3iOtyWsBcn4sQInpYFYU R/v2tgG4hDdq1beEY5N/ZaLsoSyFYZmwbzB+BVhPg0W/9s91/nYAQgOL6XrExQjF lZxS28ujAq1LDNzg0NDA2KsDGJF2TuST2stnxyvf23h8+KV2nZLOZXjhlVl/Nr5O WPm3gCmuPf8F6FPqM+zI4YBBRtvLRkXafUNuvc7PYVNiaPyuMh7I7U1EUUzTpkqi OI/YD4xv6DpDand/WEtLHaYfVYU6PAapLV0T28BoFITp/qxHYYnXVfhn4htSgiwW R1btcxWyNjsIedjb1LJ2EwEfuXqZmzDz51uDLBq3XQ/dbvDkDzfZR3O1KGaACxAT tAeAdnTnAVliWYQiJ7BHn4LTJZ0ERGL/R1xpQs4quki4WHtEBRRzP6BbmUYYhigO QwvTK9darP1Ev7miF5BkRnrzWqCQHNTlDB3i/RzIfIDChQbSZtrpZH/V/quPuPlO 1353Q6D221UiChhw0+8GmIszbLwBkDq+Zr7/poUBAqHmTaA3LeiahACM55ATbg1+ FKf0nvUL0SaEBAqFxSdQ1mnW83VCMlCE7Luh49BDl4/nufCdF+iv3cYRW2SDHPrU HELYYLz+b4QLl+XO2SgUYEkU9s1Z+eCKcVUXGzz6vZUsA8UwvYIy8b/1cz4Y5sZ4 MLpEXnQRMwAjArh4fvmosAG+diC18H2asLWpUS5HBBrSb8lAqKPLl+n72SlZkFjE WP+qq3koz3EyJsjwH2qbpx5BLhTPcEVHl3DZ1eOQmCXcpSm/cqKp2MKQFubCC4rr nphTD8uYKCP3mJXB8vqIIO9ho7+GVlCHJdZGu+3bw1L89O6ZG6WClbY56eGz2xUn DBmikb9sppeYSs0eX+yQ9kjQRf/BGnRab2dSTGtDT7jp6cL+zWUUOawLHWS72XtN 3XYSEvvAWPygwbBuAuw17pwPPmTXduRiJosR1lRk28FGsMwzbj4byXm77IO3vD80 cyrAQ/bmSpvlmYEHvmRn9N7QT7SFANY4a03aBK2iuqZQUz/zeo3eyrJudBXIiwUz /ZRteBa6SQagqDsmfeuGCjgTFGVnutCokh9lajm9BZ1pZtCmHEDd7yz4Odx5CmxG -----END RSA PRIVATE KEY----- bouncycastle-1.49.orig/test/src/org/bouncycastle/openssl/test/data/rsa/openssl_rsa_aes256_ecb.pem0000644000175000017500000000334610556327510032564 0ustar ebourgebourg-----BEGIN RSA PRIVATE KEY----- Proc-Type: 4,ENCRYPTED DEK-Info: AES-256-ECB,C5DF56EE3F83A1F8C1AC805EA73D4D24 ac22chm8+bxXpppAKfsrFJwCY0S4VPnXmFRqlAPZRuqBH9ylFcG+F8TuHdIsLeof q6s8yxkXa8y+/3hyqIZeMwN5Ai1Cas4P1iMwEtMUCMeaip5t0nf+yeCyx433hDSW dVnsdeuiFCiBUPUXfp6dCGO9kOLUEwu4wM4lIJkJ4QVyauO0/DwObQ6s6xEMFvQH GF1AFFTfW39CpZuS1rguG4hTxW6aNxjEaSKHJnzWu+kduMLJEaLUiL5+i/tUw937 V8DhGdWU//1Q6KKLMr+5w0k9i/FhVxAGJZoZ5j79ToYORGr4jpkDPOvHaCydM6Iv JH0epC0wfG8L/dArNGLEftTpVVlvqHMpAlc0Rgvn+LtqstfyWFXqbQ90NBxC5Fs5 xiGxKFGpkX4stoKIaOvFVw/hoCI/oxs8Eihz8u4QjBsl/3TdYQ6AUyfBGEWImy/y hh+QKCVOfzAmVGcffXYf7fvZETVgpo6tynxKVlSRXO9ZuzANJCC8jkUEOjc7jSKl jyMKQMNnQxyplgaFxnWIfs/snvlLQW8DlpMPH8xSkHkUgLKMWrSLB9Cisv0N7V5t Zl7Xxm3tOteLG73JxJKJkSZ9djlhkPvlvS///mvLQc6jse8EzY8peQMI1pYQu87U CvHVDOYn56SFVJmo2koER8FG8a1910NqdCKpNkzjqTl1Qbz7Z2VwghTslM7sUA2L AJP6PgdCkiGbi3oU8moPy3Nyg908j/17Bj9VyCXiegMAOxI6Kefim5Nn/sq+2/7Z MHIucQX6ka8KjEp9jvf7jvNC5WYxJkKIl+yzwAzqRQ395Lp1sun6jPfngnPQmkXY toeOeFvKlxaQu3QgNY7Hq9wwGbK/uo+rLK+Jbnt/75w7x5aGHQF3kf36epr3O/0l MyZPPx6sLblYcNQhBV8rnSey1WeO6105h61xTXdKV6To/m+RDZYvt+qs4z5SNQlj oKTezoQUh4J4QMg0EPhghyCS+/+cPMdnVnwX6Ds6nD2feX2CpN27xieGEp5ZhioG qWi6/59B38kBW2e60eQyL5f53bhWvywBg3HeUsXCD0ujtXBqPMuNnO6FU+/5Ohg5 BAJ/bXaWiOkobmppBeaViidGv3NytL48ZIuQ1PZsYQajFb/k1SkyLebmeC2NYdO8 VBWxAz5glgIKP11K9DJMD3n6PVl+ZyvlYZUGXjfUhOxHKVmNDHv2o5Pv8jf3WEhs yuWEoRECvfNlkDrmda0MxMhEYjeTysbxeX6fvwD2InzuFKhfzwh49p5LdZLurEm8 DI8KBIXUx8g3svArJRvbVLyW0deMlXBY7h8Yc/2y7c5qBwfYrYhgazxVBfRqS3lt EsO2sa0V0GaGhPh7LUt+n1qDDYmaOfxOdpZoSLm/surciEQIQVNXt264YuFJS+ot vHWWVHzS1AZIgizu7NHRVeUmu4XEgT8vRsJYeogyG9o3U27L/lF1L5ysvYQjtvkd q5idZxCnY5RctE2wa5gjxPjmgbt1sUN23KOiPyz2cmXGBh/dwqEhIV6j7+WeS4/r SFBZBeGRHi8tACblT/6G9UB6FcycyD3hf317Zb3jXZLve17ozwRZRQ8aBkz07+iy -----END RSA PRIVATE KEY----- bouncycastle-1.49.orig/test/src/org/bouncycastle/openssl/test/data/rsa/openssl_rsa_des3_ecb.pem0000644000175000017500000000332310556327510032410 0ustar ebourgebourg-----BEGIN RSA PRIVATE KEY----- Proc-Type: 4,ENCRYPTED DEK-Info: DES-EDE3,9675E5342C359F94 aqJHsie4Ls1x3Tk73mbL7VyTembpkhx/a8Mc345TuZOZEkU9XYrkFMvhEB+jcVoo 9ydosCL2d8xjDusry+vn5yF3iwE9HFHQ52M0/a5IH3sTtJ18BzAOi72ykGb2r6ly FzTq7xdXNihN19wHHnI98GKdxdQmNR9uITx8VRBbZdbRNGdJopS8zT96+AV1QAE6 lyKKLA7qbATHR7JWQN2OYz05vGt48Vmq+da+qs5liEtx+GtNUxS5x8lAC6Llmq2s /Xv8X6kjYmxHSYWM2JyxsznGfdXKXe9f4Xxwyhedei6JgrTHa/JN/+tvgh5NWODK er1tLBRRA7atlSoB2AAegJC7gJRVOxRF4hiKX/19cfEpq8hF9+6EHGYm/IQRSI/J F0RGcnSdiddYbEb667qTkbLZi/d3Ih3KwKGww6ZzkHe/qPi230/cDR8tac26jmG8 qoCwj+XCNOe9IUJsCN6RmLcFp4Tr4UVSsswxReN+xs5Ui+S3AY8IKscLSo+bB8gq DVBvVFUBTiF5/zO8q8H8Xv2c0aA3S9UQla+l3yoZygiUym+Q204Li+tDXiM602kr GGDA5/cGpQuit/7O51KF2OSwnnvLdu96qz0f9X+rq4QVNAy5PXcr2pj/y88UfSXN GAbogEXqpQzn0rmV1OWM8hsnOpN2DLcuZICCJFJc/BHO4elt65OfBjAvbxjhFU6s nJLUcR5EopLex46WwuucR6W6wjAuO8ET3cDV5L9wQI6DT+XItotk+yJyYawNPda7 wfmxZ0o3qdcpRp7aw0ohfshRGJMuLnGVgLczU4hwO2/1LgRMnCywldacAfo8Ot8s WnC7d0jVOre2K67Omh4gLQTzikvFoxg5kjmFFxF+QOFakT/B3RMa9mgjtOlX0boK HepTxOtCaS+cZnL/fUCbWdnPxqooKid2DnVTNIXXBg3S97ReediwpSn6v6gU8QXI O0X/+syPkCRAOKLjCdgxFXRB1UA13v6iqeja9aXgzbUnk/MrT6G4ivAMsNS1cEdA KVKVpbiKchEpiiSiPyo7buZN6t3m4JnupU+UvcJAEFgdbPvP/kFvxywpPBcAycAM HgujJ9bE3OR1lfyHHTGF/f5lXGDzB0/ND8h7Pm+Bd0AFde79rCswhnR4oJsPLuij Uy499ouKhoxFTn3WMF6at2QLf36rfLHl41uSN0tky8trT9SE1PjX6yQUjl48bJh3 MWUFPYBDfDPGTddENYo7hDmwoSLbE5WFxbAeJa86wgV/P4/QcDF0IPVa/wsDTPKR RIy7eNqxXBYhFeOBCkTKHMJ0XCawi4q2CAwo7RNuAmTrHOBN2hZOwYd6yoEQ4ALq 70cflG8+rITJHOdAjXYAlcuuB1FjDWJjO1E3P9MwMfiFZBnJBsYkDT6ablfwgpaQ z9ngnzRqxIjqAxrRY9GdR3BEWgRIiKXljUgkk8qFSRIS1i3w+nHAipreOwizTVUw otTU++EjpQBracFsuGP6w9vcyhHOp3K+RzGYEQoh2vJm25lzUWBHvmVpCw5BBTms RgurNRdm1IlN+qSzriotjPuHr9Ucit7VFV/gXtmyJiNNPjTLpLQEZOUpz15eaFs+ -----END RSA PRIVATE KEY----- bouncycastle-1.49.orig/test/src/org/bouncycastle/openssl/test/data/rsa/openssl_rsa_des2_ecb.pem0000644000175000017500000000332210556327510032406 0ustar ebourgebourg-----BEGIN RSA PRIVATE KEY----- Proc-Type: 4,ENCRYPTED DEK-Info: DES-EDE,8B0E5396F9D19442 Ym7x4lqzxkC0K7f3nTtR7/ZVi0Vj36NLORWiJig0qvSmH1rhkkmMjssQqc17kWRT ttLj4D4s1ueQBlDFaumMrXloVp8c4zQS5jbHNmf+bUsom+HXGFHbjPC0usHm9TAl pPBWMCON5uUxoqJhw2mvrGSlkQhkkh3+Oiag6fxNxnN8Te/yTPC1XXCqIh7zRjCN q3wjkh8+0QP8ui2jK/2zrlbwvCyggs4q1YhVzWYiecFro1llb+CDCz0mzKEXj1MM MLyMdcooxXTb4t5PhkW87N8PSWXeJEJTxcWYbZ7bf+Bf68iHm6JChc/HTXZRLUfo 3lACV21KTTI/614rLl44l/Ftg4HDSE4UV/J2JoenbRecljKXneeVj48Lmurc3zZa rj46e/pXEGfeEGmkuVnriWhRBcK8Mq33XfY870RsP+4bfxd2ykJYyxFZyoTT0sAU LJ4KIVZVc3/jB58CRBZDV4s6/cA0uHPhprtzEHSxp7vI9N4dQAWaUBMnDtPVC999 QjVGYKRUUNp2S4XVLtMH3+jZ5ntvCTTabjuie/4TAxoUY45CwKjEFpWtDBEWBbXe zmIQYCE+o8hSVtt8DFWdz8+PGqF9QgWZ5iQtnp5hUKA4rVeaxF7+ktumTrwguZcZ 6ZK+K3t4lcHyPZMQBoiWijmBLoRsoQ7NIFEE3sn9muV0XUz3hMCRapWsqS4fd3N0 LRXrBmZuizqzaNBcDku7lBbembdW7EI9flzY/0Q0xRl7WjOdK6Nj4V2A2MblQoh1 J+pvV9Tc4PANApNLcFZSPawOJVyUtmpX8QZYTe7QlXQrVIQE4HX4od1S3/ZlydfT DL8Atfec1sabrRFs1M86lJGnYxsvismLVH0VmkigWe+4sClAl5QrtCfGQepYmsYi jyVruF3FzbOCjcv04x4a4HyKRHeCVlsRlSq/njqCh0WSc7OMacpQJZVvsUYRCaS1 7WhmzeiVNjgKXg5lPwta78Kh+XbQUtUGryQQrwOnbj0SDsho2hBTt/gbWDpxoQjL LGPHVxwqm0GZ4bw+4IXwltfei7MG/ceWxLZYk8ZTkc6r+w0+5HQFKZ3JuSKB3OLm rK0m87IybLY/Zfap/WLAmreRMUz/FbsY9Vjh3gt6NqrDhqLFYCyyUKZyKrWnVlIj j5vohFGbq968UYVavCZ2eqmtwWywsBXLOabypgrIUQhmCxOUBM7Mi2NVrTqn8uIO G5+mwzsy8imChv3Zk2/LafxPpajlu1MuC6CtMdZjV+zrGxJBEUxADaTJU7tTAWef lUjlZ4l/XO3vxSvv/F3yONmgKp1t3naS0ZxxYalcMRi6xTznW24r5voOAsVqIz5y Nl5FtPMSCBE4FONoUI4Gq1GAen2h2/Dz1Q3CMYAvJz/QfpZFu4DZ+jAUISU7URfL 7P/lXQhg3onHVy5tgXhiXDhCCxY4pUPSy57eE32F+sIGeltoXU2Okx5/ey8ijr+i 5URStFLeFp90ke/EhdOuhDoE++7G826ky3twqtSBTt4jU9IemH0agFU3PWIJffm3 +Ezce6LusooS8Bqs9rYXHHGe2q0oUNY3ipggOzx4Th4mwg1HzBQnD6FU33M/WyCw -----END RSA PRIVATE KEY----- bouncycastle-1.49.orig/test/src/org/bouncycastle/openssl/test/data/rsa/openssl_rsa_des3_cfb.pem0000644000175000017500000000331710556327510032414 0ustar ebourgebourg-----BEGIN RSA PRIVATE KEY----- Proc-Type: 4,ENCRYPTED DEK-Info: DES-EDE3-CFB,B99E3DD88C3A9D7B 4Dsk+pNUGsgEqelOveMyrkoDb+khouKf83Yt4/qxX8CHs5q6i70NLViQWwqvIqQP g3h8Gs8cYKZfkEAFKP6BRFPy8EttnBCzhAdvLKrKFCZoDmhxC5ia+FxPLtNaDEb5 6bgSoZ07KUMvfMZdnG5Kogex4DedqENVHBi2Rl3Dck1pAgxwzMntgHsluT4ht3id SgyUT/xAaMSwIklsjclR998N6V8Nilu8TDDf5X12RHOq/MSqGZ7yJC3Wb/dsirNs 7jsEQwg9tIg5B/5hxjN12E4Ov7orIuO/WHNVtLznx1w1t/umPjLFn100Kln8GvfN jiGSB5TUz4t8r3deN7oDrGjoyr5OMnKWSsIwKcMsNSh9aTdkjIJBUUhIB2PStdX7 WbeNXicNMQeteIrY+ZDDPpMbjsH1Kqcz5y9OWnvaXso5lSHLBp1IamCv/XbQcAPR zbnbN8DCOYAMcUiwcRAt0U+BNc1edX8VmCB0d4RQq5BTFbjGKqzo6yFVUOVLhiFg E8G3v8sTqUhJyH4Dmjn0oDMtfdplk30Ywg2wZAahnI9w+cZFvzqXshL3mGdu+rbb h7PkiJE5vS6/4VKA7pngsVanCRQa3btL43ekShth+DXwsziQixGD9HhTb2iYeF+u 9niDPI5gzi9IfxIpb3QjR1xDJYAzKDDBA4gHhbEBSObByMsVzjS0+dwP9N6DV60v 3x7RfO094FXxlVWSh2SMvz/sB9fsD9dCp/gadqHxhk2aJf7lfSU1C7EmM9hxGZku vR3J1QcSu2FMrvHyRzFZGKozSHq3QunOLno/KmY0ja1754NEkntGvPuB7LhGBNB6 14NvQsl7qFw5wJxmEdY5rhVdz4PxLfjnMyvCiWlku83QIC51I5DbhRP7eG9rJSMw b7KFSQwmp2yzDeX+Ipd0JAgd14GvtmICKJVushO352O7mVnx3Jy1ZtJsonhzySz6 1fGIvJI8jxZOdO7q1OD0bfrXS/kwdXnxoxn4pkjw3ZN3hdFTfAerVQ+qYJ7zIez5 0lUihHNw1C/KRsggraOl9rTUNppcNtMYwKXCJOGXI2UEn8p3JIxEHLwXyOjTDfg/ 5oK2nPAmBdGsLb5ivJLPivmaqDXf7fdn0XBQQmtYUQRotlGmfpztujt/b2pL5YSE Uqginw65zyedjL6Aff3crvP8/CUR0JARx9vF12R+v2iAnDqVk/yqYpRqOp5elm1t yGB/PtpoRFsNU1hDnPZDu7kZV9oSeXaBDFOnHmX09qE2r869Aye1xOVmxiG5tm/u KGA+zlJVVpQSwnPc/qk17S0dvNAlgt6MH+vYlhKw8zk1nDCuavUK3hTFT+9w31cQ yjPdV4/K8seK4zIqpH4LZrC306/1/7BT5JXL6ZChATHaI68xwEY2GsEl/Ze0JrQv WpWSN/I269rUfaBDE6eFaiSDzq1xY+qyApHSTNPSPDHbFeCXz+puqv9lw0bJFnRJ nLsK2fUAKNvyCF18IydyhiGz42LYbwwjlEWuVsfWtgvftDebZRIfQFlj7DJwXfZU zcEOI5YyuQs+wFK/8b/bknF4xRpaXwt9Il7tcV07h96TDJV05illig== -----END RSA PRIVATE KEY----- bouncycastle-1.49.orig/test/src/org/bouncycastle/openssl/test/data/rsa/openssl_rsa_blowfish_cbc.pem0000644000175000017500000000332110556327510033363 0ustar ebourgebourg-----BEGIN RSA PRIVATE KEY----- Proc-Type: 4,ENCRYPTED DEK-Info: BF-CBC,E59962EBB3DD3C74 1FpslA4+P9E8HcUUGpkIMWeZYV2XxCgOiSgCe2NAUiutcRkVAg9nPbzwnsQTbckx d5uOE/w53BURpxPkz3nNcike0sr3fa/MzaoRUDo0P4MU5bmAihjnZqhRllqvw4Zt BsyxjHVn54RaqZC4RNQUqwIHYZwJmHUi7Zk3+Sw7fivMZBr/AWqa66I2hk20+obB y5ubRjtjw6uaciPLIoMZksxoEwi5xv4KnQHAQnaihQ558RPpUwweqHXyOZPEC1Kx gNQPrTGc4Zm+CKqR4CceACSYzcYtechZpSQqn61emmtyhowDqXpqqjG2nimNihcI hbp5O+O3fKZFkJllB20xuaj0rK1NFF4aLiS3BK6aWeCZ6aXFawSvbQb6vGx+pQmP eQemfllRXXkT43CHUmMTaf6gKnz5DaxDBqdVP73dBa6UoWnxTrZcUNKiPUCvB3g1 ciJePjBnsijb2Bh6jIwr7yghIbS65AYE/0V+5Duw360Fa1OqJkMuz5pKeJIUcYEZ 3yuI22CZeorkvymKhrt1hUn5xLIKRZkWg7UbXG1WXCrGtPdJ+CxnwupHMdL8iMLi 1haNeJ3E/PeMjehQRzSEEFwDljn/b1JtoWsEwnQPTPKY3505OWIhYRwRXLEo5n1y QEfktZ9UtIsJcIpfi7hMvbpp/7Njlu2MJKZ/1ZtvwVLoaXFTSivqcAkDdP7u5enb OJ4EaDWrRXS3Zj31fpYTV5p0fRaejFPevRNnYvMLRiSoFobd5MUrKjxpxPRCLiW7 24BF9QY7C2Nso9yR7gNkzLw5x/725lGxa2ZD16nJmiECOaEB8ORVlilmjX2OQi66 hpGVtjHMaoGr5IvBrtc7Q9aM0bdoFZD5I2mOm0hniNHG9es2IMByHWRAQFzOOLGH IFoIyW3OIuzK3cz8lMLsh/Hlbzo/3bpX0rbrn1XZULWAJ1oNzRJRi6a3Sw2YoIMh 656IJB/fGRbG9CMVMl0T7onDUhZYLA/mV+xy2CjkQdPBjFpQUTn5YHu6zMU7gejo YSV/4esuUfhogLiqw7sPuCDqLL2UftN29xloQDTY6MlrkFb9jCciAwn02DAmsN4h 7Utus3Z2N7gJnxt1dRecqr2o/agIINm3tMh0LK3/CydmlthZQNpsxMD7IqaWFfQR Uq7zQUfYZi0l2J6iy6FUHUokskqwgiNhMP2Z+uZ1xHUnoP7E0IZMHnVWEKBIQZ0d ddDucux1jOBlMwLqom3jYPjPkxoeSU2E0ozVNSOqsPnoKkz2qKnEHhea2sAPg4eX lsZ9ENQyQMZVapjic41BU/32pbrE/+JkK2Cc+dcLlrnHo+JpFeTdbleJhZ2JgXHW 8r04vZHA7tQOc0KNR522Niu7dvOW302lwmfp7D5xfon62/AxVhos1DSZuNpVClm3 V59lqeCBDm1yJwdM/946Eq45YJiTNTzYsPPFl25KNv+3+GKkhZ20GuLiaqprel3S MC5XbMJg4nc0LiAfDT/q1jO/EKZ5LzRRtkVvx1D8To6DAptyFoJSMKyFu79tQdfN 371+sXEX1VjpEGxO2t/DUmuERIBdc9X7rPNOXSl31QxsXy4s73zcAhI94X8xrqYZ -----END RSA PRIVATE KEY----- bouncycastle-1.49.orig/test/src/org/bouncycastle/openssl/test/data/rsa/openssl_rsa_des2_cfb.pem0000644000175000017500000000331610556327510032412 0ustar ebourgebourg-----BEGIN RSA PRIVATE KEY----- Proc-Type: 4,ENCRYPTED DEK-Info: DES-EDE-CFB,36E0C8A965F07E25 L0GHzT9XVnA03q7rlchpiD4JCgzISj+B9GxKCrKSJJBC8bRTgjgrwySMQyhdX1nw DiCtb9q7UCxQ/j0VvHuoA3OS1/Q95mwCsnjUXYAPiXeR0NMJkLgv1hFU8EjAJHY8 ZenlgfC1RNoUONucq7v3F7jpsqBWrxjyDXFnWwe3edSfUzkfkG27NK6LPScjqdY6 kJWAkHGpoGog7cYVBJ78LbYYHSBR+xfeFzhVMqB78mH8/Y/CGlKvXnPFpiJCY7Af zpd4/PJRVubXVyANc42k+0/E2oPOSKiwiKV79BxFw8g+NxkhRzXeCDuzvExKL457 cuPNB0CQLSVNmOWKr6mA1bIBiJXgASzijsjkyoH62D/QoBo+kBT8W3hiHooSzJ89 flhyknT+rVuAbFdPGqriS8siN/r4Qq/gbQIFhNe9jsSQesfr7lM3oK2EPGpDxstf eKc+EhHBlT4S9X+AilnjK5il2X5szyhOFZQ7RdAiqZ7X2KPNNqbeS2L530ZvlL+W Yw4qco88cilN276QQWCcrp3YcWv+MzawlNvfOOAb4GfUlR+njPxRAxM3rGVXiMn+ 6UL3X1SqZfADJOn57S4cDoP/A0i3FUfoPTwQW77LOAIzLSeMi7brQkZi5J9s5Izm OMcEi+GwBrkbPl67fKMnt3cHeFGJmOftrLZCt8HpGEdiQzP5iiC828XvLLxby5Ue BGoBILGIHL3OqkTVjBbSODKFZTIOQdVkqrWKyXlrfoI1meATptP7/GhdQP2DTW8B ppmNgtwIbGLg/AwNmGPdpL2mP5SZLIDJHd81BL00xPJFCR9wxXLk3hgm6auzAsZV FYjaIQ0Qza5kBCKNqu8ad8edqgp5Rj1/ZzfCWEkPRHD/lZ7nj9vuC/dMnPphohKz q8/L1+gbp8dwER7sEVBiWDE5u3lpSbx+1qkk2CwOjE9eBh2Mr6qLL2WIFb4YUvYI OAWIU1ftenOEjgjvYZcdeEOYT0UF6/avfHDPvkTIwl52UUhunbnqCjQM3qr18rbV 8vB1bC64DxetUPhDymLqJCe4QVQajdO5BxQ2wwRjHlBi94nlAS/uOFV+WwqtFKZD TakruYhw3VjGxtnjukruMzNjDSqxd8Jabp1oTHY57C+aYQcBo34XAr+j+PQTPXEj GNL19MUMHJo/yk05NZfkyf3/+YtAV+/Gle7TlWWCV1nvEwrHPE4yCGi8j6qtCzBC TgpXl/lxJendZgVzIGGzMDemJgyrLNV6ar8TbOz6d5GDV3S84g2S7cToMVHX4Z8M bR53pt/KfH27Wdn68z3Zd7sT8R0g7yCVIc0BJgRrZ1aLnyKLSUk7iJULg3+B5NwK JNucRiU6mT5SUiyS5WjD6vZVDjggAx7H74DP04rzgzcHvTB2gzx1hFzw6WW9wcCk 7+RiY0j13M/nD8UjW+pp/Ugk4Oc/bvxsA2tWQ1BeyF+KSNj/zjHMwN/sp1/of43X D+lcWS1hCwMiy79KQudrkc2DiYKWSIiXEFlblSJGiQz7SxybtO+D0PpVmlEYWiDF AAMz3hM+CrWcXIFNw86mHSsJHvYsSjbCB3ydG8L9OdATYsS3tZo38g== -----END RSA PRIVATE KEY----- bouncycastle-1.49.orig/test/src/org/bouncycastle/openssl/test/data/rsa/openssl_rsa_des2_cbc.pem0000644000175000017500000000332610556327510032410 0ustar ebourgebourg-----BEGIN RSA PRIVATE KEY----- Proc-Type: 4,ENCRYPTED DEK-Info: DES-EDE-CBC,A48C2683D96452DF dRu5UKxN6kr8aSBwZnynPwIA2y8Dgu6Xf2vCf0JswuFMJAwFGjiHoZTmIHuAjArK GWhiMl6ak552D/Nugz2SNgC3eJo/LOP/g2NIJnG09GuWOGXkiagjDKNbPCiIBPww STIBg5ilKV07lryS0FxQSUWsjI/2c0yxk/6MGSzQ6rrAWB4Cf843u482w6Hidr/E euPsqXJDtlQrKQ1gaMTJiOY9Y2H81b485MBN9BnKfDH4WHp49b/akcditst59fty FtzwyUTee9SGY6u7oKaUUe6sRzFOeeRR2TgWG5Bs5sne1AFFen2/q59Va/7/iXRd TOKKUGR4yj9gA+9EIpDF3n8Vn3G9LnTDFK0Xh1m61C1mQmXgEOqJGLVreFq4u1xq 0J1yEZKoXreZJH95+gYAW5lmG+jNCMy0RO5PsTClx7G4XcIGFZAXi8sXfk3FYLT8 nboMgQ8IXFjqO85FIVMt+xCpov+S8yOfPMOU63zxrynaXD2eGv7y2dTpeF3Mf4Ek be0YrQEWpCtYUdZ9AwA4N0/vkdp84/WZ3Aw/i+KUqYKtK2agkJYtarqj6iUweUvW GgWvZqNiTAd3sGcxffSbcdSRpuNttnBG77qAFgFiPXtvJu4wRkGlaxhwVTyUWK2E HvCEsssbzX4tZ6GUXScXv4zg3YaDP6HXsnBENl5SGXK8Uelett6PJhwH7bfpWysG Z1TD75uk6twThhtPURGG4GUaQ6cZ1RUsL9/y06v3ZmfUBxeVGLKwyMzlr2FTYenU +LcvzriycweTLMO6llLVQH8XwlbAZ7JgndCjZodtFXhjhrS5Iu0sO6J2D7xFvL3q /Ym8PhhRStcVjijX+5+9aiA8AkXK3khP14T3yhPLu7iayl836Lh1+O1BHiYgr9Z6 DdhCmO2Esa822yxyOdiwVlF+mYQylEZQy3D3kqqJytO9pn87cSvR3WbPtFOStlcs Htms8SdqLAamuWLGZiycPr87mSH2By2JED//80fNHdR1D7cvPU7oL/ClFMX/F3EW UJAwSXswmUxqccBR2hOJ6K3OvSIULoUn3awM/qPNTQL7rg++dSzUDbIiUywxuU9N nXkqfBVjoJTjafgWd39G3RdoK0ohf9QFj1nqYfaQGKy90cPVw/FdjRyszJWDUBTq jlKXnap6ZS9PGztjEoLqmFaFT75RUR49NnNtmcKmH0i6anjwFWEYBM61jox7gH+g W0r+0R2yijAspXHVpuibx9vdgkq/WR4A36t6DEMajOHM3SVzbPzkHTV5HyYQKnaw SZLSdUk8VwYkGSylm3f64PJLxBl7TNtrQhFLgR/9QXkhN7U2Qc7WxRQzhLQsLbtL qcBLGH34SGQarQZ5dfo3t+B6IIW2HvHNOiT9HQsIJTz4Er1SbLNH6bco7hud6aOA eSifKkWLp3SXXS6wjQZzsSGZ7Mws1DRcL9gEhb4tgIvopQK773AbQ1SJDEcmBpD1 NmxrTbb1TngaW6u/79Nng84YEUiWNDKu3ovoe/HLVZoDr3tGmy5ch0jfA6NOxEn3 KXZCiu/PjU005SLyLql5dcGzagjnnURDi7TLue/97xtpI/ac0vL868Cqfm0+e26H -----END RSA PRIVATE KEY----- bouncycastle-1.49.orig/test/src/org/bouncycastle/openssl/test/data/rsa/openssl_rsa_rc2_128_cbc.pem0000644000175000017500000000332210556327510032627 0ustar ebourgebourg-----BEGIN RSA PRIVATE KEY----- Proc-Type: 4,ENCRYPTED DEK-Info: RC2-CBC,C9CEE2FFE7D795D6 hcUF0vilpOxap0mbziQfS/5kPdXsFb59D6myNYdLDAvBWUVAuu5g8iDDJIS8KPb2 xvmWdXRhbsnfeQGcGWM1rMc7brutqefFp/OAJVymI0TpILMgef0abf49PEqNUa/N rYs2dd39fsyrJ0rcEWT2lBA/+GTLATB+16/9aCwjHjQ4L7d4Soh1laMo2K2Us6Eq pB8f6an5Y/vSIlnljl4upKOlcLItd//2ehQnkuEhI2Vafz+kX08Z3+OCLZfdNEq0 +8b5GbOvygEZbG+amZDB/tXnR1HB+AI7lR94PmM+h24COWAelatj2uPOGov54gXc iO7NDGoouysqfkfcMpuy5SkLVW4FoCAxfOl+LOU9p4x8+iaJt7Np+TO16dvX8MOL 4WcIz4huaT125V38Q4UiB+WbsvQXrHRM4WCyJBGBhakr+FpNFdH1UPb9Unb+8UQL BeddEGT0l9AiSebT/JMKgFUOInQdKxOjg4NBp3asVEUeTGLeTN3o06zUoopzT0S3 CHrpgvpZLf+4NATrFMw0HkcUK4GHZl/Q68C67qNGTc4B37eGcxzGo8QOyjXzKxL8 Lh+Ry3eJpEXae5xDUn9yt8eqYI2vdwjA/3+XE6mRhu1sbPNJCcWo2kLZ0ibYgqdB FLsXBT8aoeKrW2p82OpehslbmswOKZgrPRYmNh1GAPz2jwBFfCEOLQYXAjCFViiL ipFLKLGt2dhjk5RbCraN6eYRn2XcIai/7dnaYxXkjOsNH4mmPzlzjhvRh/2E/r2Z hbTOoa2uFUtZHWtDXUz7ZzCJErJaA00ont37BksfHDdDw1HIt4z6Ut8Jm1cR5zPO pC7s7ohOS5j8Vr8j947bEXITC2ozcvVVZOCcHwF/PnUE1zx48HBp2m9NAZ8Bz3LS Zn799/RrNtJLnkheG0wIrizk72M5L9PZQ4FXlupfJ9c9XniaQ23GQFszagceDN8j z/MR4tTfdWRy/889lqZ6ccNmPAXdwwijC6Tw6V9HooN9m3++ZlbPfHpboQUp6+V0 Wwq8gdnlYW/i++9n251xBsR7mQtFNXaYwFmLUTt9C8OobyWSsX/OaeQGbWiVnmAv vPkr7mh6g0ha/x+1vKgEOjqItJsGdspf8ePHQ3FaTkfFwhQ4eN9w4QR3uzM/7fnj ql3yA+G8ftpaU9omFbs+VqIVNej5tvjODQ02BbjSuRklAGxnReCS14vLwjg9BV6t Ow74oIttwlZof21BWsCISgybkPmMhkIhUNAAkHexzY3AiqjAtEGnpmvfZAX9zN8+ +Kg58DxudjHQwUO4cwP9p50NndrilBShkotdYIqekXn6h0frYuhspJVWwIVswNjX BuEZE5B+Otswbt/caj9C5tfsyKmnGToG4fpDdk0ItxRq2126crKQd49zZybyR3zR phLeduyS5h0oYNwTjq+Fg2Z+f6d/iyCAE8ynfqcAPK1WpM/02DBoLsOmve5BCSPB YYKdrKfkGbj4J2klrptGmqgctyW5jKGddE6NO4XFYV174rsdPoErNWWcfptHEMLR BWfopqdN/HMrpRLTkjx9rIeBJ0F+wQEEH1JehnWExSSSAhm/gzQc1kU/wihOStU4 -----END RSA PRIVATE KEY----- bouncycastle-1.49.orig/test/src/org/bouncycastle/openssl/test/data/rsa/openssl_rsa_aes256_cfb.pem0000644000175000017500000000333610556327510032564 0ustar ebourgebourg-----BEGIN RSA PRIVATE KEY----- Proc-Type: 4,ENCRYPTED DEK-Info: AES-256-CFB,37639E4753C0E4CD43EEDEEA18AA66D7 HKuYoKfUqTRf4sW12EzTuIFK5J1FkeJAD+ajYnKeKYneNiDbmDlQv0kIk12qBv6l LA0oBH62QKjUDKi/sg8NAO5CqYkN2ZB0gQurTgGT/jrvMkkkkwE0x1n69bGNScCN mkqMnAnjQqbo1xERzwqX5OWNTTb4iDLiPyjiUlQDONl14pe4x6zGpVziCVCQh8Q6 rAPDryZBg/wQtPXNhNpk8MiTiSwe03wq10QP6W5TmUIKp3kD4OVfBxpW1N4znyIu unJDVcRdBf6XA+aL7plAsETL6F9Tx3Mxm5GaeaJcSOWWzKMvqYhAcEYwM01lx0w8 LMMRUogny67ZqaLywXZWH6FCJGCnJK5oaJE+jlnKZ6xhbwAxMyxWRCZC9pF22ocI 3IY602+shDOWZQDoihhddwPJejh+o3mVFEglco3YEByL7Cy6GvqxhctEEH7uKvlQ gXGb7srmOpeHHfP76N9afF2hn0mqyToakdZqgnlgT2jm4UDHJ1vQ+onIksV56I07 tVMEmPhXQCIHhfKdzEgI/v8CiLL3W/g8r+20/5qyKCL5vPBLAxmRudYKbGkhm5pq GkzaSp1cKe4ipUfVc5OEUikOMCuadal0TUQZ+h658aBCxLWHNPdZCzNdY/bZLN9z XPhAzml/H6VOZyIxb9hm+FNESvqNKdlU2NaE7HW0ILKaDif7gsZhvogP4qNDp2P9 xPANQh9UxpA16AUTUNOqk78t9aQVpbjZfAeGmcw6AxJ77uK649JgkEnKqcuxcDSi zn/8NGeaKow/bTW6jJJj7b4cMys32uxRjeeeClC0moQiy28OIJpRRCRJIs7Muka+ dMBoNyftBnCONH+oqj+F5au3QPMwKH4v/4VpO3hcByXcqxegH+BPEZzzYJ1OnI3u dh9VlpTdC/CD+Gn3ZRqYbguSaqow1ZF+nlpD0xcs0IQjNEe2BVR7CULUFVXIgF44 pTv96/LvbG1J9b0VuBr+iIp30FG9azd2xyn4O3lW2xk1uzvo/Wf1vDGvT6AYyXNG DQS1dGtIm3+sy975sNTlba5gWgh0YNHjeiQq19I6ZzLFhkvLKfh7zpx+R53YcqSY lXj62N0u2s4KUygqg14oiIUoEnNr+n7Pq0es/gYs34mY/KvlqA8Prax91BaoqqLW qHN5bEv90KdKaJlvdWsCUjA3wReeaQa+U737GMXaON9/oOJ02bWC8/OIzUPgfGRH v/8YL7kMnTd+Col0f+XxnebWSfJsAzT7mjfly+An9EjccTeiOon8submd+L8WySK lVvWzBD3l4HKjQkr/3/YtmpuymVZyeTzngVuSdw+iXWPmOOuXHyjyD2Htn5iNWch Zlw37a5sHhiFtpNZtOnhpmDbX9sgt68KJMB/E9Mh3JuWCaKZZ3Cv/22KA4KQRlNB FSvDDKJBrM1m599A6GPJisR+iC7g7asJQ8hI1OqaY69v8nP0Fo+Qk8+Ac1L/n/Vm RjksignkKjvqgWENNn5Bf9A9+zZrLLu9wJJLae7wIiw4UgsNob68sGjWdLyg+tab QTxd15H5VUIuD6pkeAI2qC+0sSw9V6LKm6pmEIIbp188CzApcsGBXA== -----END RSA PRIVATE KEY----- bouncycastle-1.49.orig/test/src/org/bouncycastle/openssl/test/data/rsa/openssl_rsa_aes128_ofb.pem0000644000175000017500000000333610556327510032576 0ustar ebourgebourg-----BEGIN RSA PRIVATE KEY----- Proc-Type: 4,ENCRYPTED DEK-Info: AES-128-OFB,271025C313E6EFC0403320C73382F15B /L1xK2Hx7pYQBTuhHX1P/mkXqLAlbSSz58hL1E4oxsDJODiVH+ueTSKajA8+tbxG eBK4p0s5j1fp7SJ9m4QXBwvhCnis992H9kQws6U9gGFrofrYAniRFhX6yzvm86ee deQ2Pfcv+evGRPigkoeRSQGxSa40fJ+5cBs4G22cfrKabaEKxnLtQpqPG17JQ4/f LdrHz64IyJTgvV6LCzJxShO7vxwIXaA82HNR6Qp09WUXxLB1/pfQ8oQfZbTUkvWi CBdXWT42VZklPl7StNiAN9U85K/USIYkKG47CpJvWMYbWJ3Dt1EFiEFi/wmYTinv b2K0xUrVUKxAMfmVtr1wGSJA9P9AT0/sBO2vTn5ibXVVHibtAET+vGXLtpGqf89/ RmcqNEFYxvLzoTyR2FONtVluAC2yk10cKHY/pzZwQyVfjcgMlbnrZz9Pp1Y6ntR5 AfXpVR/qyYOaQ8BeMCXkfR79GPyCPV6txy3KE2mbajwamvL7eR0+0R3Q0lhVcWGp g91D1nbgVFkHGOugO+2yb8vLq9k7K84Za+TY9NCqCG6g0S46yAgZD2rqrAAO4UIf 6+nno8TS41W5wmsdEarbRoIg7iIKaPKzEmRRurSdlj/s7MKHgQFoet/OdZuAQkV6 FumyDmqekmPAgIIJEO2NdrWo87RWKCzc61Yl52qmWsqrJIHrPORMGdjdlLVxXXIE XZQot33Rx7/f0VZktYB5fWk08kjWQ0sKTDiHEp8Xobq/RDyMTm9TFIkeFm4rLkl6 Zt2bzp7ssoKeYuJgpoRzUmGP83wgl+AaJZpupARdz5MlqXd5knuPTETFPaFIf98d r/sl/V4E1nh0x83HNOBrLlpKbeWocVV4zv22q4zemALPCOQKUPWulINQWAYiTPDA lBQhFRnJXSZYFUqFWpxjp3yIWCvTZd4wgX5IQpaJvG+ehRn0H4FR0hJukMG7Pn5y ye0M0XlvVYWfxhLRDK23iNkRzVIbIxZfxqaInpGvatcTHyb2vnVFateSGlXIk0wU GxgytnTGW2fZtCDOqeQxCL66nIkpqKhB2hJKaD5WIG7SUikjBblvVcN+gkj9IWML 7LB7xjE+4cyt27Rt9QHuLchdgSScPnPTZhdX0iK1LVELlJQFx8WPZpfXwpQR/xz8 tqAKOfyhOX2XxYYOoaNN+ffQ3mEnsVFx2uQOp7PvNjL06XdYP4p/AruzVnbqsDsG BIo+oo7PfepNw1jRxcmeoaMotIZ8Feq8H8QEARqQSnzRWAJZhV5D9ztmUtaeqyy4 QDbgxBxdV0nLAWG7e54FMn5yJfjqq2pkBl69ZvR3N+F+L5/eWlEpalIoq2l8AffY gDxlGgp030MAyFYSLJNYj+UUwq8k5INaC0QKjARbBMblf0HOX4U6RBqrpzn2xyvU mlM6pTiO+mOpG9WLgQS9XTUk2te8n0vAVUTk4Camj94Vdl8JWFNsfJIgwE59hprg a3Pz4FosIcBbj1pYtlA9Lz3kIGe9U3z9rHeQHNxJ8agW8NKGvlzY/YBdb115UhnM WOVp5TkpF2MyE+TGWqXzwNo3GutaNVs5YO5nX3Mtx4ClRrsmQYVTMg== -----END RSA PRIVATE KEY----- bouncycastle-1.49.orig/test/src/org/bouncycastle/openssl/test/data/rsa/openssl_rsa_aes192_ecb.pem0000644000175000017500000000334610556327510032563 0ustar ebourgebourg-----BEGIN RSA PRIVATE KEY----- Proc-Type: 4,ENCRYPTED DEK-Info: AES-192-ECB,A3A4C4B92548B906A635B84B3D67591E E4I7KvCs0qknDw8D9ISQev5oQCNiHskfB/SvuKJ/qJoJP52qk+ajN9pNMp+011R+ MRaMlK7tANTrQ0L/Yc6QNUZW2aHyiex0aoC4ien4ojgvqHfaP12dMxFhOoLctN+N zrAPSuQg2OEBiWxEoDqpgA7FTUbxPiJ3QdtwwOXS5kqAKIEIoNnCPCL+45uKBrP8 encSI+nrZIXLFqGEukKZuFH9qzdF2leOKSmEW1kmwxMOfQLMVQMJyVzd19cCxU/1 FZtPRRIzFlx4PlNYLKDpypSUavgo5V/o3UHk6vbP/Wd+Wy1ERwNliV7CTCCpOrBH qJezvhkbktiHQQ7+5zU0jsTzTlZcxATdm2ktyfEa5GKrCNfrmUYNwNSi8DC2Dn1x 4z9r6OfKV3dKcSkgmFS3ZI97ZhrnMqpvo0h1kg8tuiboI9pPWp8OsLIvw5+jz707 GLsl6hI0EX61YFc7bqeetnObgiaJMJxQJXHi0U+Z01GjZ+qgGb6USmQ1D8r34nuj 4l88VYW4jBhxa/IFpzUoxIioKG58xQT+OK2Fi7BF/OJLQpj+3RA3YLqry0D+AOT+ f+nDJepwrQ/CZtoQl53ssct+mDY0D1IU6u7ah9WdIuuptV7+WxutFfDpXsmErKcZ eILXaH5zK9iNVnVNQDmnVacjQt0x0Rm28wrjI5N7M8jGWKWi9PMLElx3BTo9EbON pJ6x6xshjmdCR3gOLo86CZGkoUM1eNGhJuihrl6HelcZxeFnuiNYnLb5hIaqDd1v NpFUQBRC6Q3jz85zIvVsiN2vIyak2OGDRs7r5dqb1x9QVz5tMjxuKe3t+rfX1FN1 vCusACQQzOl6NdTgmm5Of+pMniOL/kRF78e7zva8vM1Qf31/z8wtq3gemt+pZstW WV/kRhIvY/p2Nm41TtltlctThbYquFTEy8gxhB/Cot2k7Z494+8UBVIn7SjsdDpU X+N24itXM9/sd1LHrXBSbBT5PzSBJFC5MS4Nt6qpvSKIRbyWINjUoTvbbUwoCo6g soYBPJR9KeAcQ8YdBOEXtFScq7c5ZPOGCj/+3p++Pk7yMmlxNPvs6HLjdHchjAYz jycK/uWYNLOwKS/AMxwi4R3i45pPgIRuwGdRyi17Z8kOKATdyQwScbPOShW9/066 OA0rEORx3C9gMoKa9QYo3O9YLjA7NS1ERSY9c3X9anSgR7eSs+DLRwFiB3EHoCba ULqd3n7qBKgkQpVF60p34yKb3K8o5s0cIE7oAm3VdoI/O/RSs87rDmUbpuYzAA24 mXRwBvPpwEhke5PoPeFIYmcWa4wUZOJWuF78U/tZw047vcLKgr60Z1s+DlQJvFXI tXkV3qS45f9UDaWQ15YNev9fq+x/1JDO1LjQ9AHANBjRQSzE9K6YpyIw/SZlbo1O xuFrE077EL3hrRNh00O2rtcrK53mAOKMX9D5xifIcN4/uD9AdwU24YvC44gij47m hSg5wz0RokMNGLKTXaJxJGs4+ZK8JWQs/Kf/V9j6j/i4iDWuy5Ra7+/dIU/Qy1ZW cc8Uo2ji4i2z+QyzbpbR/jBqO++lcV2byEVDy8Xp/0X2G9mY0ymIbm7ATTlzE2/b -----END RSA PRIVATE KEY----- bouncycastle-1.49.orig/test/src/org/bouncycastle/openssl/test/data/rsa/openssl_rsa_aes256_cbc.pem0000644000175000017500000000334610556327510032562 0ustar ebourgebourg-----BEGIN RSA PRIVATE KEY----- Proc-Type: 4,ENCRYPTED DEK-Info: AES-256-CBC,1876F5A50C9046D504D47B2BF8951875 BAPOppBjFxMrMU+NI00PbmXXutKdPAiP+If8JqX5xGQDB9bSt5Q9R2QkaMx8Z94f trVbp82iERyPYnwcnA1Av+pcZhKi/mYFgDBPP+dDLp8qKRFAWil0zc0U2jkfo0U7 v8cpO5+oipkJ9RtjaTg3/XmrwCUFZH4KA6G+SUFc4Oxj8/dzQ5YUDtJ5iyArRlnr v4nsvP4OvsI5UFYwp/T97ks0KSmo6YLMpJwUBwcleX2vOhX8fd3thk9I+EbVVt/f +JztCTwr4EsLxWe4XVmit9AKfLU0AhmcA20j2YXE1VFvRJdyr+gOGPD2SDoRgiZH rRBhfi7cou3QmZ5d43jFYoYCBc98blEV07umH0DXMTL8XSrfWNIjZf8uQR3+ZbHt W60jVdhOCEb40KoRTHQAMBQdgVVkrbXCFyc9NeVzzhPqyKXElGxLBjRB9u0h15DV WCJUdc9UGuHzFpVFzpEaehdm/7vl+SZXUzAOgAQDtL+ATsvZglyMx5y2UA+5L1eZ grA6e3tQFdBcv8w+WgYW37oAY2VkHKjoHs1TnR8z1t+OpVovnpcklawybh9Avv5J kXyZGc+lbbb2gvUw33VeYR8yIE4zBoePuhTFM3K4NfkBbKavBBXMjQlsdRzlt48r RqdFnpYc1XB4ZLP2VparhG+Q1UueVML8uBcd5F6X/0u9n78LfIITwRUpVoaLXRzs 94Us0pbzWFDxqxtqKPZHLAVJOYvEOwZD5Haw/bwho73EHEx38MY7mk9T5PonsBko 7Op6aEmKK1qfpJ1aPvy74UmIlVDHu5WEMkYx7nQL67gnFXHY0yKjmP6dc2y3+nfR qNK95RTaS9VbACRS+re+P9+Z3aAsQGvj3MA+4Q+qlscUmb8uk+M7tg9ADk0VSe1u Ts2x7UZroI61c+WzgsQzMAwm2QLPoKQcvv2b+iGD82enAtleTTHL9rkoS+KmNNU6 hWL+AJ7HP9s/5+FJ7/4CD84pcLECXQ+f185vvE42TfdZmoq6NgSKrGVZPLxYnyjO qa2sTRzImZrXPtsnFEL9OBflWA+ZHaAGo4HJNxZW4Z90HJlAZN3isSZnE3jPToKP YFdHsPv5m/KpNa5luh4L3K41QWzLmPlRR0aygWM7/0fYkgxI8PnBeCp4OjoK6qHx VYTWMKJQTLyji3YwMr4CufFAVty3InUZzm+ALMFHqEORB6JqPTR9mtnR145FHtxE 1z0LnEoDFEdGuLjtC57yR+lYS/vgMbtj4EqQ2zK93JaXvI2HxxOiZCZEDww262Bx QZo0vBoAd5vkMKmz5eAMpRVkguF1wN1RPvao7I2auJIHp/3zoaUowpZgtbmDHZFA Kddfc927GQRxtUH3QQVe1R6FFAa7JBHNeJsBvZu3bj3l/7BATzcne5OPhjZ/t8Sl hMqEBZuo0svrEc0w+e8dpbPEjuj8UwBmHYZWlALby5N+YJ1NEtLYmyHe2PFNXwK0 2fo45CCSyl7YJrHD1ONJ0M804ML4nMwmYq6fOAaV9ufQBFqQQj/hyyE93blB8f2E I8LMN/SUKN06YU0nErN0PRdm7CkrS+kutn/Pz2H4oSbUZ67z4Ee1tpnVQjoDYdQU -----END RSA PRIVATE KEY----- bouncycastle-1.49.orig/test/src/org/bouncycastle/openssl/test/data/rsa/openssl_rsa_aes192_ofb.pem0000644000175000017500000000333610556327510032577 0ustar ebourgebourg-----BEGIN RSA PRIVATE KEY----- Proc-Type: 4,ENCRYPTED DEK-Info: AES-192-OFB,9797077D8AC3052C37DE4D719CA8FC00 SU3g1XmkcVhlJpQSWXdeHcHI8IQCQBg0oenT/35NKgWnFBlysqwGwl/pwgdDBmm4 jLsPaE5Vanm4aqWv9DNhItOQokIbIkxF6qKeV3wNSNbTsSaG2LNphwMiLs9rw4G9 3aFV+0THPLAy3BDTsB3NPuRqlOSVcwVrfaeMXQGhCOPGmsGDeczai1xH7eq1C1no KUqNMGdf8g1NuCmQnvswuTF9BCi6rIO0JRqLPTxoz/1emKfHhJFefpSj88zg3ucm cz6ZOAlsmWm1MQrktXd+odzpmjHtd1vNsgr4GSYUeVxxWQX4o8pVFqWqiQXii+HS ubtMARXAuFIGoM1RCMN8o7sJG00RbG7zNxfhHqe4wSkKgx3qEuusUDewXkDeYhHJ HGQCD1epByGHCZkLwBntccOqbCQoSNB0/PcFU6vJrtgVFl8N4VsNMRuLj2ZJ7uuL /EZ3qkLTk/Ek68++m2dtAdyj2KF1O4z2SFROSh7MCqWl2rYh4zZcBtGEfmQe5Pwz +kPycc76ayzHO8Bjg6rl/16Ua5Wx7d6vy4Hg7JYb5eDmj2UGJ8p/z83KBdQnb1ku 84ZjpYgmtjZ1vY8Z5iZqfZro9JBjWM4wFZIKNXcBniC7kBV9fRC5nzpjs6qWTPRb bd7PLMuyRZz9PO6cRuhqYlP5tYSGYYVhAMVutIqSrQVRDV8AnmblfPiOtT5lHC48 GR/xPTIFxxVqsDmeyBzyXn9gzAJKgjTVCXNksXojM/ZMfDDvAF6m/Ntz/izp2CbI f2lcHgsm7SwVn2fvHikAugA9B6ixMCXygO0L5OEUDJW1e1fB7FMasjrwRorDsxsj JUNDW0KhUXWt/U8lNyfRm3oNUjQQU3x1iEymjQZV10ZO9DTn28fZOF70moUWnl0y ffELY1vLtLNP7Y5tcGNtJARSGnMUW99P7OKpLNXkhL8zE3DGEL1N+gDS1n81kzTH 7hPjM6yR6gJQVsQrQmXrEpIlHQeGA99LYchzyVog14qMhvQItDlCsr5UIPwVwhMP LTA2LITZOYieRAqrv3vn+yFHYG4k9/C/xHwKHE/4pDw8bLn1o8thGv5ZW4yDsHGx n6F6vqJrkPW6vXkmwcgO5jK8JBbEpyzAPc6aSsibH3JF0ufsfs2hQ4bwb96OmU6v mukMLjQoi3BJC70Op1bpe7wtCELJw1oFvbZDoXLYsa3c06HK1M4rmzJQTIEBjqxd vs3g4L4CQ4RHAzlkjLrCF+wcBHt33586bDrt03qBEA7GSyAUu1NSM3UKjjM0OydG u8echgFIz6XetqDICHdN0r3ZWyICM/FgnVQhs39fCgafVJsy9C4p5jByUuDPvebP +gvvVqkb+DGwfkKT3RUFAcYiNHdtIob3kmp8OJKTFk/nwdUwqUTEu3VFCmWog9ps oe/0KOL7j1Kn1xEFkOt5MdSFCcpbsYjQNi7F1gWAr1vMXDDPsSizsniGSvXZIYBt Pk5AH4MflqbHFofWClhGczSLi0FRiVPqWyudoU7LOesQhhN74Dn5IzkeAGtDL8r6 4vC+G61PZdFXhLXQfOEL99hgJ2mjQP4rVqwdz143YE4/CUHmpq6d8g== -----END RSA PRIVATE KEY----- bouncycastle-1.49.orig/test/src/org/bouncycastle/openssl/test/data/rsa/openssl_rsa_des1_ecb.pem0000644000175000017500000000332210556327510032405 0ustar ebourgebourg-----BEGIN RSA PRIVATE KEY----- Proc-Type: 4,ENCRYPTED DEK-Info: DES-ECB,451BC59702897B57 lYkflQyHR1brYuUKx2oj0+L9fRwOhpKR6NMeH2nlLEMz1yntUt9DGuBRwP4RJs8o AHo7amQ1YzGpQCEZx3p+tMmk/hHRcRmU3ZeuP3SlGwpUmbMe3NI8I2dvh/qDL3Rb QParp+YK2vH/u/N2VPB11NvgwoUQpfS35vOhoLk3GUcupSKfbsbl/gn398DsgfoI d0qD5VSxNutst5I05pl4JFnL5+DBv1s9w68TdvAvBqWmsfhb4ei/mSp81e6ndxOR VLF5hgXauJjEHvI+c/ITF0roIyyxiMMjFd8IuIHbeznIjOWn4P5YcNcSswSG2wOz 1wB0e8dlskukcUGqFS6W6mJzqb2TK1Eo+l0w2B2rNGX/MlGV9f6r7e0DQQFH0nCI nLS76C+WB5G6RA/7OMOWtsMnYSLldvXBxxZktcD1CNjyvuCOI5NK1KmG/Kajho6S /+A1mTs274pI6sIsCNl4ay2pfgwjZSWh95l8+YNt7o0C5lHudZ4hZHCDT8U2uCoe 7dhj+KTuIS3VPI7lzruMZBGAj+haZ/cAEdqYGXizOle4MwKM5+lS8E5gEviTABua 7jqhqbBE7CkN05Y3QmyE48yzi58hzSmiTOuAJ6jhB47A6Vsp/FpKFzfsK4BoD0Zh 0ujT2BeJhtsFmPY6+RLtGITnl1498j9FTfy8ZNdrXEMxvp8SnEzlIKytLQyNoz7a tPCe1od1w+MUz0PHqDO/Av3YMULGLCUgnuZc0YjZv3P54FdC6si6KFEEqotIGD0j C24TXqlBpn8Qqkht/0TmzVHq6U7jynOjD1VUeB/gudPlHGLs468c7HzEzbpE5h0G 1e5o6D5u9Nh1ItMObNrjt8NUxbi2/FX/Nkm3J1Ogno0ngzh15jZUfWFPAGkI1nho 12F8Sf7YTBizPW+sd5hDbVejJURyoj/jt6UfiVKUg9iUgOW+ZzgkbD8RvC207xis QoF+2Lr8mPsNabUaFbsXmQ+6F0Pn05BzyBN2fyTxRt6u0CKmLE1fqkIuQywk83UD hBJfeewGoOGvoXDSy0ggIkjaRCsk//Xvntt5HEmKwc/wy/1Nzuu9H3C6n7qLqyNJ mPhrOGXt6C4LG1JscqS87z4VmhV7mol/Umdg00HRHs7l9qKRTePdlq52JL7oUws2 CJs/UTaBHdbV2vh06qmymtEyNmQ+PrweEL5U/neyeYyrx6DsyUDdY1h1n+aKSEyR eittKv/pouPSLlIiMeY/DzQwN1ifoGsfYgJRst9Ry4MdlahpCTX+K7X6ryEOoJ/H 1IEOm2aSlC3qEABUGo50IqiNF/PWugS7Qf/JzXAyjtcgQdW3cskNDCR7JVJDtATu 0817ST0QXBL8qT1C3z843LcY1HpnQ1MiQvM3maDHCxuoEoUrRILWc59mc14gmowq g5XLMOLC/y5mX5LDqkxoKhoED9eM9/9EGSSy83dWWVZlGNLzu/JHBiWa3tVhas0U LytNa+kN8UfTC8KPe6i8euhauunLIKkq+MUBWy6agFR+jflE0zd0Av7Ox8HPbGe5 0fraChwokeFM44fy5cOH7zENfng0jVUUreTpDtcfp390QW5Ca59J5/5P2aUBLZHi -----END RSA PRIVATE KEY----- bouncycastle-1.49.orig/test/src/org/bouncycastle/openssl/test/data/rsa/openssl_rsa_des3_cbc.pem0000644000175000017500000000332710556327510032412 0ustar ebourgebourg-----BEGIN RSA PRIVATE KEY----- Proc-Type: 4,ENCRYPTED DEK-Info: DES-EDE3-CBC,6D7B3D8B829964B1 mw05Vw0Y4gDohoiqd0xLN6ZKCalPCK2F0QFSyAVeoPY39y1RyKdsg8xt/qDx73jZ rgZb/fQLKs/W6SqCAAk/7EIBNTCWf+yD5TTdG9n8viNDSNXWdyq172rEnRV1CWGe beo+YjNDh6UlZ1FcXLj82TpZ9EokUKLabzNkY/coVPLlytqTSO5oZmbdreuUxOyJ ktQJUmGBmBY0aHJmV2wCkOFAXbzoSfo+SNPntEUNTa8i0cSIgmZd4/QS2Xfa8qRZ c2R2hNyVZygru5t8eckKj6uvj/Yszg6XqQby4ktK/cYfveS85CNlu03WfjfI5V78 vY5efs3+NVJi2+ush4p4TfgT0PAKTWjXwpMEiGVlmxBoPoFGtTXY3Xp+64QICgTa MdrxPDDBw2yxmWAOpm58eeRqAN7Jd42qBxerJFiOUZxYPyRrQvro6fkldUlbPNon 53Hzb+zHXv9xM5aUqfEjMO4HyprhKT/8aZgQiDE8fHgJhI/S2Ho6Fzqz2/uOHzBB gx0m8fM8puQ11eRxO+oSE4OSKbEQG0Uj66cHXY6FbJUhsLkGo9HdjLSGW67vx7RY Q3PQApOCFcXLecfkXrUaAEeRPNqZXjCkF6s8bfCOXD1cr9BulaGpiGxdspu5Tk9Q bLtoX5VHnW9VoIoFsIWs1G0h3WILs7ynCE2ttDSnIjYZhE6pRBiDHRs3J6dH/oOh c4dFaapkisk0BANJduvB7vLvvbJ0Xs42q+sRUCWzHNnJ3BqQZtL5f0dqu1AXafji qwxcbrEqJc1kOQ+iRAZ83nVlVkI/UgWzTceYPR24Q0PnAux1LkoIO/FWbhm62j3u xS669GX+GS9urX8oC3JUYT2n9dnPL8ouB77KfP6c0GVxR2hhiLYmyP2600C5q5DU 6rdNm6fb75nrAmD0cgPxbdOB8zbgVvQuPXG8QnTO5Vvhp5ETgifIXPCIWwNHg5xL o2zrAdrNaio8FZUVPHOvMKE6Wl9QDMqnnShH+8VhLk7+LQpVDewBnWaMd8pK8qGn robl+i4HWtn20uZIDFyI4ioSa0S3Kanvd9TkchEbDjKAVi1QXdcD+q9O0AYt/X6n ygx2DGhkNYMrQmc+AIt7dAPa6RdZv50AAc0R3S0DBaxtd36pWugT4WIEexmuYj8S NbRNLuyjQMYCeFs/Ff4df0gmfeyH88YSlafnLyFhvv041LAbU52e/yExCEUvKr5J Oj2qVHJVe3eVW+FX8hsoUAte/a5foVe067dThfZDVp0TirozHAycgfKI600VF3Rh rvQiHzmXRoMptt5g/yLsTVYiKAF1n2hU9556sJPARFrG1xXoFFwhpzCS5t8ywniN 6wwV+V0s4LSJFQJBFjLrreu9ZkYMdEOrekzqBohF5wG/BJILkN8hBmnD5gckbLIM QUzGTGxu+BIUi8JNkso0hwZDAKnYit+FVAs+5yU0NVQU6e3fW/+m48YI5gqFI+k0 gIGmAyU6zaUJBJJQ4wc3+dOsy8sokqRhVmA59Tv20IKHh54zWq4ouFAg4Yc0bwK0 1ua9GJMGTXN0+Trb7MKZQVKokyNA0RVCDN9AIfwCA5hDhJTahsO8Lp4Eolz2TFaQ -----END RSA PRIVATE KEY----- bouncycastle-1.49.orig/test/src/org/bouncycastle/openssl/test/data/rsa/openssl_rsa_des2_ofb.pem0000644000175000017500000000331610556327510032426 0ustar ebourgebourg-----BEGIN RSA PRIVATE KEY----- Proc-Type: 4,ENCRYPTED DEK-Info: DES-EDE-OFB,0A4E382F6060AA1B hIbY73AFUCWIkdT7MEKMhr7+uSoSMO9wihHjhiHn01cq6kTe66Vy/z9dmTcgbK2q edRngIRyiTqyul1dhQ2ezVDisowHAtdiD7O2/Z+YiXc1hsuC/uELnYV1hTUg73Qb v760pWyH5AXNpqGsx2LLw+hstiiWVO+/Hs+CqtM/RgONfvUCzbyOQknDfSTDoVXB W4gEDKSDj+ydXm0ZmMS17DLCXgk4HBsJxyiK666l2TzB9pnzj6EDA6hDsiHfy3z4 +MxfcnLxWw9TJPxdLYVdw8WNWsXQd1JHQz/BQ/Hum4eNoYxLGgsV/hWQmkFil1XO GkPjF2z44fxN4FJjvQskrQox+5/gvnG+KamfvQt62qN16Z6ROZu5buPijxmXoecq gW6SyeFbnYFn27hglllax9awEEUtcJwi6OxKAkWD3REjqCfNAwcqoFqwkxlPN3IH 00Rksn3P7cN5IqePVjSdwIhZtCfeBW2267oNxb870CDon7OlrUdK8KIjp/x5jKUs Pjehw1Ovtvn2YUQnTPvIYQsgdq3BMb9ETcnPDneCVweSxHxpb8ao2hyBMyYtQG8f LNqvLnjh7FUyRenf3XRbqka2w8B1CFTTErkMm9E0OPD8tMtDyakI+8fMJDkGhGI5 jMwY2q98Z+Ef4wDifOi6qNklBlJwjvvybeqhqWOoXKbQMhnQPqFnLGjp5GQMczII m9a0anYSvmNKjRtD1LBL0KDMUgIx35U+7GKQfjrRTURYtAK8EITKUqYoWJWXUevR t9cikdwQ2yDuDH/C+a2eaEHJITerdW7ba/Rxzh50VdPq03uUNkN21VZEMjcU+GPB sLQ50j+gSFRMMzMfDx0G3wHoEJNAul8x2+umCUSpzPfC5D6kjbyREm/fWEuQkvL6 AUCheoD7ouRR66R8syjIbeCKhjZEXUOvxxNYHSySrxHyiCGE5xCSVDlTzAutvcOn kivQqRlO1C6ZoEWbGr1SPoIoi0iMoh+TKZDgMy6/pRWVbELW5P9JnH8K+IreOIXd IgnCsqKZBVN4qRPrW8HtEwiWW7MsoXGjhpVl8wer8cNmcfPTo3x2l2+mjV2r0xEZ Xmv2LEtjDfIUP6yXuID4OrV6kpqSDax+wmujr8jlETKf0uEi4PZAXqhrgh/fgH2p VE+Ey0vnDaXcEhS0ketOGmBIYaKzWbMH9iX46YSkA++5/PavhlbCqZZN+906jwEW 6MS7Nq1UBoUiql1Xa8AL0p/7QKZH2mgxpFcBeCHF4q6HhebbQbCpveJgBSR7/12H fJOIubovV6AOx2kBRAf27bii5iwMjfzC9IBE+GLCX3CXR+BLfOWutTcqbaBRdmQv K4yJqB/WHYcjlLKf/Q8+B6elmMc59NVUfStMszkIGlTzMFIkObLHH1NYPSC700rH ZkrdbRGfcncT2OcyFbWZ/tIvUER/aHjh/BvZ9s8UyEVEZzsFJI8HA66sJzZ3fKaM 8P7nXXagyarILIzO90JIwkX+ip//QtpSDPkrUtii6Wj7n7RO0REe5N5+NA3A7WUs Aret+KXgmsOi2fnTmCFjVN2QgmQvOg8PGx0yYx8gxWog/NAmLCVMjw== -----END RSA PRIVATE KEY----- bouncycastle-1.49.orig/test/src/org/bouncycastle/openssl/test/data/rsa/openssl_rsa_aes192_cfb.pem0000644000175000017500000000333610556327510032563 0ustar ebourgebourg-----BEGIN RSA PRIVATE KEY----- Proc-Type: 4,ENCRYPTED DEK-Info: AES-192-CFB,58F8574921C585278A50F7A2EA529595 RQtPMTKDNttPq1R+DiwHrEK33FOfxK1Cst5x1jrDhXe5MObLhqbz4Ft2idjtG/vC pemznnZqQYKsuJl/Th6Ydsthkg7HH1pYLRstc/tWQTESa0RseHDtdw3e/Wxhm6DH pSqymOfRq8R7PQKPxboj9fjxeooWlA+RQxGdyRJ6gki6PljOD29C2hxZV4HuL2II tUn/cdzaGu6bCvpFDvDuFja3TRtIrHSbCq01uZg6XrFui7BuwJxxR5lERsauJ6RX +lAvhwXqN4nsEQefvZc/GeTFzklsoJ+c3HJy7pN15nyfwNzmmH5EK7C4CdBJQymv MRwe9hY/LGXB5IFEgXvop9bh2qYk9tb/zb8aAHcLS9rwFsGOo+5+Yib3ds4GC5fx ILKH234g+hkhutao530kmWXFf7qup8lvTlBZueAWcIFdmBCsWjm8ejxQUZaPCqEY sZ1UMDw1HPX7/4TXdVNZWrxHisv0VWnhwJNflEcI/k/GR0/qUgkHnUPycWTtg0W2 7ivs7D0EkIJy2OyFj5swWs+eqhsSDmd0BgGL0VduLB0voi1eU908Af3PllsTwf4D UaLFvOkllIbul+YweImT9TinmkWIFMZuNDR/PHjpbLN/39YkvSub6oS4LOgKEu1Y Xr779QOZHMcIP+PXoaxqOWls9hgI6M3PAH+gAjwF77OWIQIh8JZCibR6HWYcr/qo iFTzJGNN7P06s3IOek+YoHG1c0GoPsNungPOzthNnaAUcRyvZ1Yg8cy/nhrA8Eeo A4G/I241jr/Ex5jooykpeotV1/AMIF7qxFeTARQgObRi/fiR0r9rjaSMbOt4PlRv Ln0ZBqedtkkRBPRGO0VViSbUAUOq0oSb98FWqPFpcFl8tXRyqe9m/W2zACczZplz OySvRuASdKYpGk4DmMlQtS8wjzMYTesBx68OiZfw9W2nkH+Xapc4cH8hyb3+aXXb b53nbp59+mx4UwPOcrdzVHdKhDT3BjYrJTv9kHAY8yA4Nr08ZsO5tOeI7vF+bUKx kWu4AIEccB030iu87/xHXUEOBzsV6HzzT1TrZ5GKSh43vhRwoasYON2xlO6RuKCD Yv6GbcPd4lv2mv4lAaDXk5IThABHUL8yhqfwru4L43av5AwdslRKIvBM7UWrlXFe A/Hipy6jjcusGiOyH7WfWBFV2/f6NtX6lGuna03F/yMZcHI/HEK5RyhqOYOmcxfw A1eGKSqOnq9IJ6vXnF8PuRYKB9i8Ha0z5JmWkh/dX5dhTzwH6wOz4+bLgkgXBdhY jptSs5zsvrxGiLCbENPTjArsBbT5NISh+VTrrUtmA5BLPWx6d4NNJ5eBXTnpOIJr rxA0halZtFYKj0mp1ZgnVylHC45QDiwzDnhXra83RVrcgQjcX4npjKOaYZRQ5cKR 2F1QdvoLvE9YqhjH0QFQWMWfvmLHGIDIDkSB6EyFsgzWdv6kIaiYsmdir5FzE8c5 SvHvu28j1X4OL62AquOFKMXQVns1/jLp0KERx1EhrQChHUxpA/cbqNJbhjHoRQK6 0zXWP9gNlyrSIKY4egyQmjcTDvNXVcSDu2o7EfnprNCYirFgsAbw5A== -----END RSA PRIVATE KEY----- bouncycastle-1.49.orig/test/src/org/bouncycastle/openssl/test/data/rsa/openssl_rsa_rc2_128_ofb.pem0000644000175000017500000000331210556327510032645 0ustar ebourgebourg-----BEGIN RSA PRIVATE KEY----- Proc-Type: 4,ENCRYPTED DEK-Info: RC2-OFB,E5989634C878E65D 6o45POmHfE72UAdMBQrRIm2+oZCd8GmkmrFZMXYnVWP8ciNiGVQqUxVJS9j5Rx17 8qxpNrzvcWEGWcgs9AOqog7YXHkxo/s/RIOKjUu0WhY59UrYcbkN7Rjyn3wSSD8X kN4Z2tz3iR8LnfljD2ApbR3yEYz2NvmifZzsac58R3LvuFg3Tsl0QetPSC7PfMUh B7dezaycDcx8QJy+nRPcqpGzeL/VVk3F4Hppc15gfdWtVellGcYsT0Z2Iu42I5nx HYFajRliBukH98M1d905lk1aNLDj54BBcq08JsDJN/V6DY+mUpJCFOK4DfP5WLJb /HCQg0wqsUmRHK3dVo09ilZa4OfrrRD5qTWr5boDngAqyD1r1fiHxcv7uU/HOSvt PU53frz38BA+w1pHtlE0TSG0oBe/+741kJtpvj/1Ts7nUeYJ/DGR4vmLpg4rnbZJ Yky5TaDV2LVLFR4syqombb3eiK5xbnjePCQFLwxYLQKZFINiS5zDr5mdjhWbIhpA 7wg9BKNpUeXRDtntWXvEH9FmyIicbk670riEYEo/EniwrxW9f7MFhPUpOb9ktE56 RnaU0EK9zUx1sIvcu7LVq1G2EVG8IrOKGcj4LHysBtg6PQW5mvN4AA5PZlc2Sux4 L5Z6mJfwgBbBB4OuRXAYxHZbnfMTs75vL3d/HIcvSPcvb+7nfvNLiwlaBxaUfBFh fyDurHkMG6tBgE6OORgWraNEINJeOYcG2WK60qC4E8YfYCmc9V+28A//bsyRWyku xIDup68r+Os5RMRAaZrkIqaH+h4Oyd5RqcjLnAFF/wLGnNwSttYT8o7WwCf9ZCCy NFvHDWyWMUxonaWgvuSm9YPfh9/9CEsHkKh2RqBffFcZ1ktEiYaI+dGyty12QW2Y 909pnCZkKsm1Lt3ts/xie20/gcwfsnvUC8OveKPaiCnJxDv3r9pMCNFPdcXo0GuR oadhn9r2CqNCDo+l6JWVRka2t8+yCAskZC7bKJnSeKlEDyn7A/2SLb196G2k9cve V2qQenhzuHmG5PEVfhLWQ7fL1BmJcRDuQlSmMGrdmOD4Zb0Truq0zpFL2qaMBQvb 58hG5YkYehE25j8PpJYovOQA2hih6v9RytR2VKlTeYNFbREf1sdLfeIphB9tlHlp qZ7eOFAjjVzLsC4LmoCzWMaQuwNO1f3WiNdGVvulHkWqFnGS9bBBTahUUWI5SYiQ 90vhSmJ7R7461rqWwn34Om5jlgRV4+2LhUbp+XdOyklujQYviHsOs8/wlg3lKr76 SwrU5oYqlJ7FJoDq4IPpOnJaxsRjkr9foecgdqrU4SJKyJJDbkHNfoYq9r/aZJ21 ruPFv5t021gJmWa87199GlhBZD8dxeXo0PT298Y3pmaaSdQIWLPeDAtc1R9EJLwD 6+ydhg3ZVtSgXU0zQ2SRVMGhqoEXHDUrMtjKzuaZsYL57tqH6At6vWS+xA0CJBCw 7GkDpM/lLGjyisFEQL73F0YmJPpb5s4izzCLUMxZQZ3u4T3f9OPRvAIUf8MiFJxh RJq2Is1gD7M8+dySkFeAbQ1STvLy29uIxKTE6BgNng5NrY03GuK/5A== -----END RSA PRIVATE KEY----- bouncycastle-1.49.orig/test/src/org/bouncycastle/openssl/test/data/rsa/openssl_rsa_des3_ofb.pem0000644000175000017500000000331710556327510032430 0ustar ebourgebourg-----BEGIN RSA PRIVATE KEY----- Proc-Type: 4,ENCRYPTED DEK-Info: DES-EDE3-OFB,C8F1482CB09D61BF 0GfYpcSxvnnRri3s5PutcESsHTuupx6UcprKRS+B1neyPR7Ga0Z3mZ2/X0trJVpM cxJW4g/cU4TknCZLjIJlClYQenpPRH69yw6BTi6/pgUhKeGmQK9Oob6G1RMjS9lO MTb8DKz8P9GmDR4/3SvJwPU0aEM1EAmwGJV2beB2QWRhaPkAZBzeijYf+uYn0mgm hZwjU8tdwnNnCdUXdaHeRkeqFcL6OjJHV+U5SZaMbaky1U9lyIJL+GUQZkRfZzJD 41Qt6yVtetTgzljtCtd4ix+RX6EYsWfZ3OVtwHGYpg28IdfJ3LVE//O9EkLZoBeg DyU9c0gDnQ8Dxl9VHGFwQvgdSEyJLvWDv+6RXvCX4Kb2Spy847yxqcfqDpjUhzgv C7FoBwswS0pkQzGXKgdM+WlBe9/GYOrzW08IYwrX88aihf50jXi472th6ILIkFHD 6m419YsrmOeEMXGW/VIKxk8H8MGHwdvK82xewu8Ftgfx0WihfA70EyI28VLMQTAE MMHxxCWtdWWnmd1xiHQSX6vedPLXQKKt2AYxYmHQYfqNFMcvDc5uM5uM+mNkX0qt VL5PeYRYtdDtT5Xj4/acZD7X7DhqcOwvNll3J7PRdadNXKfjHR7iRP62YkIiESE5 sCHhYXmtQqK2JUJr8a9M1QPhmAIF3FYr8wSFu/eWw8ooBaTxVoGCw70lT8LNHVql TYdW9sOnvUjz36oz6H+z55CNldor0tS/Bu5jNPOZ8F6j5r4xpTWi3d/UWLW7uBbw VTAG25EiFvQBXpJFqgRCBdD1Gcfoc+ZefLXQ1l0RJpRf1jJMkfSWvUWDRNm87PSs qTeDBzuLNx4A1wYcJ1H+R7ds5QK4moNlvv0hJrsqbOESpLv/XPcYrFgzms0b+Q1d uJEWjz38AgIJQxBxmoglzDSRx9OBh9D8HQ+aJLSVcz0dBmEOEtPjZn2AmxxccwCc NkMnAxXyNPEJhecTp2/lOOupQqMYTGe8aoiee3m01QPzfgL6m5p6IJdKzOKi0TGJ xNW6fD486B7i8d+VOnst6vnd4xiQ03gNNA654mrXIM881X5elqmoFWyup+Ct9lw5 lxllAJGh7w+hf8P6mIsezOkZGieGhzrFnuLVM2srRDEId+shTV/0lZi4LhfDYroN VAbZ6bySn9fmP4Pn42zu4XjoZJffF74u8gFPo8oSFYg88tzjbPN9KAPInNxD6lBA cwp3vc1n71CEepmfeZFR6pm1wKRSupkOZNL/PV9rqsyP1pmPE3AEU7WYjNbf2ah0 GE9f6dtLWcDP/3SssoSnZGy5SdqcNPymG9vOR+QD12YNxn7yA87HM3+swparlSYy Mhg1BuDXb5Q5XFVFdajFwAnXJblAIbuJAeHQ/mNCAnR3HNv/Qic2GF7X757MA+dP z86gFzJJtb7dtZ0WDQzzEVHgnfVHP5buXnHdepFLsETw9fp4ZjqPfHjLXIOvp9/9 G9pmSzB1JL8kK8sexWgsMRnl2j2hUDYiVJ/LQjMzk2YLF5I0D5msNTAJvb/gFBdv ynVKUpIoJEfRaY7pxR3tufbzADNiqa8OUCGxZ8jo26j7XWDkunfGAw== -----END RSA PRIVATE KEY----- bouncycastle-1.49.orig/test/src/org/bouncycastle/openssl/test/data/rsa/openssl_rsa_blowfish_cfb.pem0000644000175000017500000000331110556327510033365 0ustar ebourgebourg-----BEGIN RSA PRIVATE KEY----- Proc-Type: 4,ENCRYPTED DEK-Info: BF-CFB,A6C793D28C38F56A sjmmZGwl3qF65MFuXEtiTkltbaXuionUsMtzc/XzyPPaIxcdl/03iR5Fix0hTY2Y /W9BntQGcycH7uNcoYwOUScTRr2BJncyoDXZaUx/WOQ6cDHuhRWWwpLpmitfsn1B SRvLdKddL1GE2nfG2xhCdN4N7pVPUwIahHye1AkaSJ4gur8tU0++mJQTjDo63xKB oTh3mZB0OCnelXtoYFKGFXNh5ouAPZgcE84breDJBoGReH6f4elkigtSx/J2QhgN vXERboYz/HHhHSRCtMSp0qLEQo+uLcFxZcSMQE12eglOOucht877V5n5RMLFT/3c DeZdg6D1b52UzaSjTvLm/jJCdkYqZf4SFuBgLHF/rEALQ1vBqDiKQ7QxuWz5ApPm P0ntscETngWuJ2g2M1EoxGehwNiJJEslYE/CB0Aky1XeUmUAUm++Q3QVfUA3G3C7 pP7whQSr1Y7gL44EmttFCX+dX8GWXuZDXa399wijphVw+6bl0gp/hWRWriTern1D +/4S78ddrci4slA+/Kkq423wjLNGZtOoy9cXRmFdbQlMfVaeu5U7LmrTQRrgGVM6 GQjgNanXYhkCNubQ+v2Q6FflAdri8Ac8ZvFXxSIGZ3JG14cm072vOdp0/rCNkzSb fmtyzXUGgNgKzfp/GFvIXD04lLfeipzlUhNvDK8AKUNIctrMHZegpbfSm6HD6BiV rUFNLvr58WDK0eLeRxg4pFTCf9QXr9Q1v4MWehkn+LOTconhJtRictdlj+G2ymOQ LYgSRPPdXVNxlBI6u5WRtMxzZM6G3N8jkEvFfFsyeMtE+R0OsXiIwvGzdksnI/1F deQJzav9uMBj4A0bJuMQ3Ls8ydZNFU2RDofSU84bP/g6TzU8MpT7QXQXPD2jKdLp JouxtbRw+YY+9p0sk5PFYxti+T17jZN//pqiBrZUzvspwr5sWoa8BbA3bWE2gnXT cmx98wREJ3wWRx+t0k44084kD5/cvVH7MsAQ75XxGa0ofVj3crMCL29c+/QaUnhR GrdJ0sVJeIthiOQZZ5zBqG+IhJfG/jkKpweA9fkQ5gm+FoasTfDnAdSJjah7WfoO C6LKzNBB1FaOHqy4X6LUN5wraEOP+0OI3hKPdOB47yUzPF6FGneGk4BajDHG4RyT F2ZnG1aa+FRfakQ6l7ok4j+VPtDlCPY2jnT7muj2F78G69abNOS7ASXg5+PJzso0 liaWo1d8TDfEazlDQvglDAKpzYw2mSbpJVmmbPSaVZxUARcIIaBqxu6xWepfdN8v qZGrOp7vTOuGu8f2YmWKd3+lcNm2CwwGYIPpuTFjtUuF7guKEdTffyj5tpOdo942 RAy/F3tCy5zfZrI8SkSkx+wfZAnkUnI3xQNdKKVLCXcpBtQWht2UGO1G9W84OmFy eg21zeITIwPJZfUif9WHihdINSlfm0CiS+gDRzXukS4HgniPfS3NPo6HAepc2Gzr QUGF/ENern3v85DCEE/AebRaQN7liM+6Z55UZ4GOT3Tj64+Nth7MNQXqBYEmCS8P ndWvlalOs+vlj2Rl13IcSUOK8OOr6S7jeZhoutej1b4lbw8RwYBXGg== -----END RSA PRIVATE KEY----- bouncycastle-1.49.orig/test/src/org/bouncycastle/openssl/test/data/rsa/openssl_rsa_rc2_40_cbc.pem0000644000175000017500000000332510556327510032543 0ustar ebourgebourg-----BEGIN RSA PRIVATE KEY----- Proc-Type: 4,ENCRYPTED DEK-Info: RC2-40-CBC,BA10EF99A1862AB2 /CfoFtIX0zgNckXzuODWoCYVY6NoXOvu1jt7J5/BfSZUydRWKa2lpR3SWAUAesQX H/IK9Wkz4um0QgrHy2fmVaAS1G3ifwgQ9dhW1EMiCEAmuNwPsT2YBatSyxnzWjHa dv4eZ0Snk4DsS/Ajwn+Oc9uZ3u5gKnfYk3tXoZ9BDPQbgIz01UI/AyGHttB43brl e1C+zKgCSa5WB8wfxCJsKHDSEHx+qlipVvDk/pntc9m4AM0sp5wsHRw3i1iirQOw AG6qRs3Ro3jwajlEWPmJolhbRQWyA2rUfSIajElYFlFgxPLI10m0tO5M55VYXpWe cprQNe/TxK+YJTcBvyhFmP4Ha9NeC0Vq6aHiECpZ1uObH1brZ1bdYUsSGodRzGMC ucOkFDpsp9We48TAHqEGArCsKexxe1dDe8b+cxdvyv33ZI7dyr7DfHek3X7B2rHv tZYjgx0cKn8SNl9qdRync9wLqjL2R99sHgphkXUA7qLP7ZdvZEeAGs5NEuq5oyDj 4aybPFJu/xvByOEZBwEtrixVJ/2h4KYF6g2vK5CgmnYrq8SUNGobt+oLv3FywKhQ AK/YvDt97wXNdPNqPciqCP9LIeo0B0cgxFIbOOE3mvYgPaUoTtZ48B/hpkY4flKR U7opVqbNl/pnh1OCI1ce/K5KPw0rvYgsEQ8Q04+dipPdmvONYGhcgHflS52xju6s RbosS+iET3a6BB8ydRS8V4oezbr7AgzoSv7Od6geru87fYpVW3WbGag4w+Xgil7u C22epy/AX8naBOsMa2QMCZ97avi/qhMFIERzhQJcxULff0lHQBq+HMGsSI8jMEiH d2OIERTWasAEPdoBnELO3l4oywb4NmSp09m9imihdgocDAQEXyLkjmRqkm5H3Tdm ALFIaSwU5SE/dk3T+BTmnfl+Anx7QNWTdg+ykfH8VHbs10A/K2zt6RyJGLdStfKq VWORUG7gYcVGIQrcJllxt3Jt4sG3t3rSKA5dukM7+D1d54ExiJN5DrnaQ4kX/v7O nENonLRtV1KqrH32R+tIuBVA8rbmyseVequTBQpkHbG/IczTG1k6p0Qye17XlnPl kEPE3CG8+1RMLvflA1rTimSh1WafHsDwvwmTAgdkG5btLlfTpPnoKDy2hPS4Pd0P mF7OPVfA0Hl/oEqP7bqyUxuwFrz7pZXQrKDS02nXaqVAP02nKsiEUZNo2kprAO2v 9ceOhXP3M+ItlWeNcX5jKRaaLddQvj1ntOKqDMfRk4yWm9ro8/E56Fkrq7GpKrXL FCJJTdrWk6EcSfI6grVjPbZGBJiA+21G4IPQWskPkr9gLuE0E9I1UAdliYKXOrPK F1lZ1ZBpG1ZBe9H8Gr2sK42pzJoFJsOvGRjCxlHpf/gBoOADH/hcxvQqBGizEr0F kKraZWJnlL8qhDzfJ7YLMqzFsOu7uYQRqfOcv+66FqT/by9rD7dR/M03YJReupoL lynJfffGCG6aeM8hLZ8iizjIc/RzCY0QS4lLPkRVSRNt3Z8RNX/nFuYhYgOx38pu 6dflN059kTC5iyjsI5Ka/Xzq69kR21qCcHOoq6IQqZ7q5RM4Cj0SCXw8/4jeT2xY -----END RSA PRIVATE KEY----- bouncycastle-1.49.orig/test/src/org/bouncycastle/openssl/test/data/rsa/openssl_rsa_rc2_128_cfb.pem0000644000175000017500000000331210556327510032631 0ustar ebourgebourg-----BEGIN RSA PRIVATE KEY----- Proc-Type: 4,ENCRYPTED DEK-Info: RC2-CFB,AEA62B1564D645C9 NX4iex15O1Dwp6ADN+uFIycPB1ELvBDVRGh+OZnisNU9h+8dPO1cb3j2tkwLFK4i Pml4zz797d4I4GqdF2Y23dz2AoBrl2Lj0N0W01AlOGagh92pZ9dKjjU+S5N85OBw buDbADh16fSPW6Y88guWFXYBlGJ6HZFK/9D4CZmEfI2Pt9AwEIZ/JvWrs/zW5eGP YMFsLslsNu9TOIKF8iDnfcWM9MFpgwcFCIqTwyQ/+dka0hw33WsBREhFcNleLxhW NKBIMC6jNjpW916IClH5sBu7T8ps/7JVw4DUfpl8NAOaqJSicPGpZrGIZ9N9cfLp KD1XEy+yWc9ahV0mfiyOuzNnP2x9IEBdrk5uqJwIT9RuiFZixIH9MRuqAtrA5BIP dc2kw50AbXRghE0JdUEFfUm9zcRKdG366SgADnteNk/77gqI0OZJDD0XL9R/N3Tn uh3EI9joJciWDbEX0/751MfcLaa/EkI7quKMEyFGWvox9sKLLEKRUV6SfO/YX8ZM RV7ebJdW+Mxya/beG3Yb9TAYkrG2TT2+uhRqZlZllJQFnX7k5MxyfN5I+WJP7SEs Uy5PAkNv3h7DTV7dBFMy/gPYAooY4JzBnbq33af+w/VbhyhVid/hn9UAONahw7H/ 1Ao24IlYMza2fJ9yOn+ejLhjvwYIP5992cmElneqMdBfV+oaQTHtWUuVF6g4gJBw 9QucqxH4JbYccwA1UiKIqkmOlePm5I57RbBw1OG/Un3SiPcAwiAW/UpI5yv8kNwq kZeWnD79kMBEW2pU1CTvf5f8aBmcgQykC0M8H25Jj2kVvj0EsRGx1LuQx3ZCSM9y sZejgZouYA1WuZaIsz+3t4fgYFiOHDxmSvPt6VtZAMJGmLB/Xa/PVI4rsyNv99wB UinlINhzeGKpYYHnUgN0PrRQl0LBR0TdrJ0eG1djEvflXsuAQVP7+gP+oCckkT2c pIVm2IzplT2wzsza6+o1SA5BF7RKI3A6IxySFEBJTeaiZnYeeJHxE2DJvU1Fe29G ML/lM02waLJNbIs0Vk/i+hyE1wtMwZetptG+En5TDzTkWlVSLSqW6LXVJ53J2E+q wypuz4akL8CaYRm4XTmIH3Tom3qSf7rdbL9gk8llZacFNqAl7x1C9zDUzKU0DAOg qPKAtD1s7Rtg+4p+5cIEAWD0TKX6DlXKC/EdYO1w0vmavGSvQrr+KENE4+/gIRst qlTCiEW2U+PPyOgpZAFF0g5y5Xw0Fea/0HwBBLfCiPKRmDHQIzWIEW7RkkNfQlHC iCTBoMRFDbwXJEI9XUu2N4RdmlP+84i6fSRWuzZGUACvzEnRJEc6H0FaaN+fX0wM Op5O2hcdA0YTGGmTLUAeajiQnqGRobC8jQL/WQRVwOiFU9rgy1K4Cu2T6eBubvVh gk/R12LezvD/KwLgQz1+vXa5Vgjp0xhpnLnJVzPqLG0Fmj3V4uRDc1Lvvl4uLJiR VFjFYlqxP6w+ToRqnrfbmUCuiq6pS9FQi2Tghd02P5TnZcyS2xF2X7o45gegMplS skPzTCON8140xpx6Flep3bHwzEI0CEwO8goVMc6x4a2Ggekjn/Nz2A== -----END RSA PRIVATE KEY----- bouncycastle-1.49.orig/test/src/org/bouncycastle/openssl/test/data/rsa/openssl_rsa_aes128_cfb.pem0000644000175000017500000000333610556327510032562 0ustar ebourgebourg-----BEGIN RSA PRIVATE KEY----- Proc-Type: 4,ENCRYPTED DEK-Info: AES-128-CFB,2F7AF90B0C0A420FFD62214EBEFC4CD5 hciElffC9lqjzOx+aBT3DYY0/oZrI0Q34xfQg7IOTUPUAxrrT/UjHlToX56VIbRm PH2M5yoF88Ji7BI2V/Y2QRAjAYRFVjZvPO9ke4IGYI8xfnKRivfxLtW/YfaiKnqc 7VyyO2UI2tYGm27+JJbGLR+GdaHmcnLmencGdS4Hn3KDQ9IK4eLLXrBPWyzGnxEZ qA2OWdzqodjppFCjlx892YJUsq+w3BXu5lkPoooTEoxB5RywZfngUY9Y+raN60S6 zhjkaaJTEqAfnAsdVMUvzpkYpoH5LCO1vl4+XpKdeUu3wJ5p3D9TVc4kt6/V/MeL rHJVN8FKJKYddTlaP7xOmh4bivrJao6LzRUdnyxGL6SkVQ4ipitgWcSwFGgRQc1m /MzFmTATtC8tocSqXMY8nblp0/sabGhUSTGG+uBGddDr16D/8J5rb8cMCfR0KLPF 3uwV89PbbqpS73IUKkolRjxslO74TPDT5ds0i+UV+J+AJM+9CnyY7WI3FgMlVvRn KwYJuihDzFjozJfe386XWYs2Joa3Eo0vbaVvp4hbHq5Gh7S2iiBpqy2uN0xxuZA9 QB1XpLd+rOC0y5l1usuVc9kBlGsTiFVyBoZo/pWVlTU3z8Hzgv8p1TAJN6jgqVH7 oMVgubXsz1XPHrrjjgZEEpxqzXtKJw3DKchGDfAn4VLTSrOINwMC5sR8l30OZVtD IdlmftUBhv2AeVUqkLsSMKGdeagfwoqOlfL4FKvSt4n8Vq+Hn9lY/S7n3cjM17YE YAgpBjX4PJqXsp8K5KmBHPQMB08jW+NQFABOprdes5bwflrERogdLZmQH4vxqUvs DFhHVJxo1wxeRDOftVgtxnmHzU+SaB9MgdWWhC/4pxx5uzqYi0Q2kSOZ27EXZNdh MgVX16W6jLUw9zaR1wJIJZU7SmhJOL1fxvt85RytaD28+JvPTNs2ffDpjPu0sXh9 n0gYiWztuBNUv1m+LMpi1SPtHvtoZLhc++9g4BXoZevtgNl+FqvHs2Ob9w3yXqkT lyJQbqju674MaKXDoQ+3+tnXad8MRGCvIgmIUzmMZj3O7QcrBbDY/pbcxoEDOaKI SygvYvKfrBIKq6PuGsN1KHSMrjc2A4+wuTYy75xsai9YtwwT1tyIIeCv5NXbbtJq vW+nbSNYW+khIicBc+Ye+GFfUh2MXj+iC1lK+5i+1leKo4zLNFDmnXKgZ4jOOPMa FMYPZkwANQ6//tyP/qzLWGyBucIC/Ym9hUvi0HlYjjU3Z+Zv92vM+2+li4mtMy7M tdcm72bqsT3+1rtJKKRaYG/FiQizOGTDyhgV+JX9MEVwJPa+61V9jwkIPPR6iBrl u7NoFfSp666XbD+LurRh82vlS7KYOB2zimHFxI6nOHBsypJynqtgIzLg5N1+LhVz t+cxucW9eFvkEEXmjZwofqlxq9BDso587kKY+EpOkXrlnG/ha9XeZcyUipn+jQ0Q 64Cb7LfvcU5UEXTcMh6BKkoeNP07O1ecpD1LXMGYFn2HsfYHigwwcZ7sm9oCCC9q vF/rjXg/oIMagmc6MZOjRE2eT9tpLRAaMynLiln7XS5u+Q8O3RexEw== -----END RSA PRIVATE KEY----- bouncycastle-1.49.orig/test/src/org/bouncycastle/openssl/test/data/rsa/openssl_rsa_rc2_64_cbc.pem0000644000175000017500000000332510556327510032551 0ustar ebourgebourg-----BEGIN RSA PRIVATE KEY----- Proc-Type: 4,ENCRYPTED DEK-Info: RC2-64-CBC,DA39EAD05DD48A5B mil5OpL9dVqnEoKF7dNjIRYLgDjCBmTDZ//Bmkd4aqkPszHaCoQqgyGYOuqWXdT2 FAluu/fHMLDTizyr2Jh00ekcR3nmnGM3B0oDiEtq84YMHPWYopWkpId1ZaoqluUe 6NP6Zew4DZ8mEQvOxIxBEZqk0ye6srtLszByw/dTy4i9S7l4oR8hx1i6Jj9lLXS1 y24lC68igFNeIecggG8uwZBVmnHCldZGn6DBBqcC0b415+59vwGuvc+POy0Hog/4 ADPuZcXEO2whVGyOjCF7CjhEFfo0CO2niwS9PiUIYNsUluwfS+y1qhw4VJ61sQ/q 7cNHrD4NfZHGwpIRXk4c27YHS+JsxH8Kh61e/dQPoeTf5NBQs3PthFcx+hzlTBAq VK/4TtRRlnqTVFKRydpKo3cNGp8qm9Kvz6fr/yLb7CJvdoGDyHVO7JvT8nYL5gC0 dvN2RySKXMrgmPS7uMAWjpnDCdNoOX4pRTRPEdBw8WsdXqnBqXM8tvrkolF9n3// lldN3sSGLiYM1cwD4dXlYJEJNaarelHk6vpJIU4A6gYyN9MQnv061jd7sibrTAjZ Rx06R0FrYFbfkp4yAmUbrPO5gdwZPBGS9XzkZmZr+S4u1fH7tTFxIlWNgxwSzsZJ P9LXM8Iy408gDn1AJlbT7WbdWfcFzqIsmauRIXE66TloS+485ro9zX7O27MumF8S hjD+cRMieUEREuAAlpNxZj5kcT3SpxfSdaAZtJv8OKeRHz796LRxlLmx3ZDAjgN5 0H37gSCXJDP2a4YnsiI7th5fNba84t1Qt4Q36v6EZT2kscv0TB04ov1+4UX9jCQI zn2zxzJk42kkxRSEBP3BnZf/qV5t6/+BKmg1QGCmS5AkIIlCDjTPpAom3n7YH9LV ykAQ6Wcdo/7dGtghgaHbPGl3cXR1u7BI97GCU4vzRbW58ULh7KSC1xptDJrP7tPE 6OwwYk5YZ6lmg54cLbQcxeFwYQg1dc4pYAgBppUFUB/uWeQrbJP8/FN/GlW0HTOU kUIz5pbI7nstb2hHrRMTtG4c0oGO1ACD2LigQo5Cl7jR0sBC3I2MB/JcBBwAHPVP tePpIdSAZjAYI+x7LFxxXvT7eXe+BU4ZLGLcTISGJjtsbJG1oJ/e7dPP5bLL+zjJ MrwoE6awH5GKOOxB0iUGce8jg8566qY4e2vbmVL4a2qRiKyLowr7Lcz01VzzE/RX 0Ec1I8noUmsystH/57UMBuhZNFjW3LtTaw6vuTrrmFtdmJcGwars9tBtH0LPip9X xQbwIiTJZCyDjql7Ecgu2ncw7zHZzbHrmoEF7VEdPT4z21utXgzJ3HubvB7Agvyz sB+EXeUqwZHnyN0GdGd6sqlHkW7TP1XxMrjewUHjXuY4SvsosJ/GqMY7uKJXK/Lt 0kqYrV/YDIVsJ2JqyxwXYYIqmZfQ2xXTLuESuesT7omKFh4cgwbYHd33YWRCsZJB 7Og8d3ciguWDutd1LOgx7da2ZA+3UVz8X601GRpFD8YoZTo8QOayXFvv7L1F3oeK b0w11lT0npxstmeMQUkbxAyCnKrwpQagiwBzKlr9ymJvh/ot6sJ5bAFDvZBBKkQU -----END RSA PRIVATE KEY----- bouncycastle-1.49.orig/test/src/org/bouncycastle/openssl/test/data/rsa/openssl_rsa_aes128_cbc.pem0000644000175000017500000000334610556327510032560 0ustar ebourgebourg-----BEGIN RSA PRIVATE KEY----- Proc-Type: 4,ENCRYPTED DEK-Info: AES-128-CBC,8DA91D5A71988E3D4431D9C2C009F249 ZUo4tso7YF0+ayrQpLsgM4TN2H31b5g5ryj//QqqVG/WmvYgl56Vu7fDbYXytgnb PQoJLo+8iUI1d51nirw3RrtAx7Z9lrBu6mX+JBE7nwCVsjBVVlAx1B6d6Jwc20wj 935VaUkwT3n0zZ1dwb9HLjEGUp82TIbiZ3KjWKnfER2AhFXJl3SzswA5Fvwe0AYm KTAEYaaxigTTPgltiEQDIvA/Pnh9ZHjh6rbM816Fa2hdk30wjU4U/KkTYbg4hdoV vLeQpYnMT2uICCuvNXq0cXXetfbgdMFsLTxvVElUZrjyMTsw1QtjijeM+gj1dbDj HGzR0k97Xj3q+84m+SoNW29zPLZzSaFDX4KdKKG2cHs9BTYJmzb0h7qP4pCXjGgF 8V2iUDMs7BQlgNnOa9gwT7x7DN4HM6J0MIlNIiYQZnupqqYQTDR0rd+fhdIsXHkA qNZKI/4ep7voVIufSS8ZyoISES3f7dvs5nnM2C+QAtL+l/yaaqRdfUyn9BL1djaP akSRPXmHrmed8s8YamuhLHyf+GPL2uYpd4i1voA2KKYSx4PnfjH/F/8fXPZr3dNh sDtcjhgXHTNAEVVek9VOaHtlUNZEY0UcbP5uqBZta+wP2rBTC94DxIbN+k8A2SlP cKGkaRltjnPJAXWmwKMRm1J7vXngXYq0r5VUvnGPiUhFlQwAW5TUml4+1SMEUirZ y/Oh3AjhOus67uiAXAQoqlr9KykueXobFrhZjLCgRf7iDmP/t1eK40UyV83w85yz cORi8FNfqvCARz05qXwfhf2NBMTRbLNzKCGjS4iY0dLNk+QYNgJGoM4nFVkHYgbM pTThzpYgtRnxQf1mYTZFtqr8hRJqiRfexzCyk2JC3rDtEO8WUmNdvdKNN0KwCd4+ dcVS8KzNov9fYMqiiol0dL89WBN1RN+hs7HnOJkNZZgaNVspOLCT4+SN5fLgtbJI BzbAgTK1ILrSom5fyzZcRkYwzIqNc97YhRYnxDp7vJFlgsBqySJgtdGUkTPrrzAO CCYyi/ukSVphPe+qRsvj9L4syZgpLRgDdZaW+BR0pbTUg2WQvZuKL5iMhfB8cbAC +FjoKeSlxI68jukrAYHBNcco+qaAYrUaHsJFUsbf7j85DzHxnaA3M+P0i+LWJwOI 3G751QR2CrjgK+QD7XUtUjBMrsVGlJmfaQsEm7+rtuPynXq+ArJrvgha4lc0GRD6 yNDCTTMafuBnJ72wop1UEE8zGOsqERsgvOAL10J1s5KCcPHGwrDhjhr3/x1GI6/e H80zp/E9mPgzYQMfhl06s9SwyvsxFCIZAfrKIhq7lVqeEDiusYbe15kCLmTVNZ6C c/BhDc76vwek05AOLaZLGbdpMRwevbOn4WvUHV0o5Yr1h1IGZKx9BQYwFS65SDCg uxfM+dKulE6MWD2hPUP9s47+R812cBnHu5BVV+Cq52YygAiAP1+nfFw7TBKzqczo fnIsoL69JthqtkZiwl36uMmcoWwZM621ZqYFJI53WO57uhW0uuoyidQj8HoNG/re o3OyAgVO6sTFsw/Dwxo4WX2AKuIt9W2IJMFNC7aS7lH0iPrtiVC3FFXvuY5agipH -----END RSA PRIVATE KEY----- bouncycastle-1.49.orig/test/src/org/bouncycastle/openssl/test/data/rsa/openssl_rsa_des1_cbc.pem0000644000175000017500000000332210556327510032403 0ustar ebourgebourg-----BEGIN RSA PRIVATE KEY----- Proc-Type: 4,ENCRYPTED DEK-Info: DES-CBC,4629ADA1FF55BE00 2093wYtiVZThSK/Ecf2pxfukmymwYi+yaWhMDfxz/O001tbrlC/emwfU7iprUPeD NJyyAV4GLjUBA51tfDqia3ATKaBfUtMQoC48+q/Lkr5KhLZEU0LLVuGrfvmDXmPb Ne9Ud8XZGnrDmvAFkguzK7cF4PFWUX3l5oYKinm8he7pA+t9RJ6QX7+BHKQHlWcR cT9e1iN7MykRD2Hh7YjSxg1uRlJ+1H5zIJBDjQ/WIUMj4EdNJriurt7eYY2XrP9M fyvTOBgYRHn6uQU0tdV0619j5yjEBpPTRf2M4RGOeNYGfvmk4RcyZPdnccDq5bWT w2XhhBPZMdCHmDPTCOwgfSvqBBX6OtH2EKd1aJQmtudMATPjA49Q2v9ZrgIQQxmA ZXIXuYH8wNPlzpm+abolucwIQhWJqr5TP5q7IKfYLD7FIjyrPBJecGoDuPB/Qp8x D9G73DKYgu3aYEFxcjs7tWwWe93pn7glEPmuybK2HP0iD5/YhXy9OUElAUZVBHXb WNyFdcdmyP/hcex5nI3Q27yM1auTS4Wpmvg9I5Psr1NN5ilWFNiJ0fr/YcOMpVsz NqQPuSLqxX5sg7X6m7MkE0/k8PfFO+tpy1cC/K18nnka8WgH4SJ+R1I8WXLKFznU X+mWcOaci2YBUHT7TWRzJ9/5bL0CEWlheabTjqbaV/4kiE5L0Wcbh/am56c2YAzi 6MzassP58vp4hHXTyda94+Kj4ymYFbRBLqh9CVspolwDhy6e7ydcspGz/RRbuWrN Xc+lsExkvnLkYvkfmaAU/C5ME5PNjgM0kH0qXLyXPPtdKmwWrkGjElzaY2iajzpP XEmnYu4E8AsNdNg3HVcQfoUU7jFq1NeB4uibFrq8vh6VLmqGvK6XCul0gxJsfsh+ j/38B1+5I97I0oplDZrAQMgek3BXegw6HZVqADC2KH4Jir50rYNCFrN1un9aohHG BdTzB1wGkjW2fJ/yrU5nkkTYcNhl9zU0D09XvFvXyeRdLzJL5eFqqZluwsPPw/TM CSwjTZbbeS2LvvstAsoYGfQTUr/E+BOXVpFmNg+94DBxwM7lCy57nG2Y6oIy8Qcb IfmF+wKMZEVJxy8O2uaCYUwU7qpucq1tz8l4bTo8wUctxw80Iflq7WYg/8V2ilro F1nSJ7gF0bn33KwlLxLy7akXiol8Rg6aOg+cAiMi2Apfg+5DXWrKf9YOwebDLOX3 LWvDuMYRVccwVWsA+X4zUezGjVNuxjnjtsDfeiScf9QyliK8kjlMP/r+chrhFFzc LXARzcVfYCQhF6heOOY9YTHvcySV4NmgRKC/dlzvN4NMGh8VxWiEFDo7Vu8XTXpN 7OiSd/BvmOism6emrC8zRMD8c1ZgCxuY1MOMVXRir/Qy1IWZXiYmI71mmJmRhE79 Gn5JJ3aZ9xZmr34l296CWOBY/suTRvkrfyMRoSTC8Z9K5nbd+cm0MLzWMgiT5PAg cy6PHN9zVWInz/2z00qf+3lx45ZmMeVj2+2h1PFapXaCwvek3VgsXL2HUV/mKNcU ZH7mV8imvIopRSS4YQXB0Ophiv6i7lJWdKrSYd/Ac+Bt2E4z7q7y4wFNlZBvsBoO -----END RSA PRIVATE KEY----- bouncycastle-1.49.orig/test/src/org/bouncycastle/openssl/test/data/rsa/openssl_rsa_unencrypted.pem0000644000175000017500000000321710556327510033303 0ustar ebourgebourg-----BEGIN RSA PRIVATE KEY----- MIIEpAIBAAKCAQEAyGOvloI+jKnRHWKuhYB+cTIEwZhagKJ0f3rIY8WNgujB7Plp gpjUg4pNjYGViGjg7zhfbjhCtlNGXyRBti3GcaHiBIIP5nyCNn+Ay8tSWGo5v5Zc 8BQcwHf0ZHLN6sD9m2uVSp/6UqjS5ZyhzF5FzvvUo3xw8fecdnStXQfHhkBnLpTj HE5t7iu1JVjTuE0pcBvah2dWqDNxiIOQtXyKW8Sag1YxaunxQGqRNykSFiEJindx OSAnAxK6q/wGqcZ3zvFBTcVVkji1u2QH4rOMP3PPxAIMkB8ONkdHTco1DmbE6BfD HArDqUYxqJUlPGlMqrKb3fCFiT3eXehwR7nlzQIDAQABAoIBAFd6vTKVVT0O/U04 wTtiptA/p7fkDM5PHVBxh32Wxno5pj8PerIaiduKyuRVh7PvJRMJpw903BrAK95o 847WWOVOaF7TcKGMBURJUS6maiJS7TboK1ZbUVnsg/I99ArhiVUKGDhlsl/Xd4np YPDYztzXLzLXpm7bS6CiuvP762x9dfVu8K+afP8cjH8pfXLq55ghZOUKidRQaYz1 mNOTQyAQlCQdLRgKlYgqcRHlj0pb28XBJaln3W7Z7GFMWFPojkxx6LaCp8+Jyx2C tv54zIZQhMjF37tQyTnfK4Ocl3sCRb+jYV4FkrUnsQE9W2dey0Tms1XB31gfUJlx dRZu7zkCgYEA/nWcTwzot2OIAhXoJ2fnqTcpdmj05LHhGcayKjyix7BsVH2I0KpF 9kXX066tr3+LxZTergl4UpWSl3yx/4kPBQM6np4VVRytn7+cQdEhOczZnBw6x7IZ fv81DSNruQDBRAlTtklW4KBY74JKLhaJSvF1F3x32+H+99i1MmCNJRMCgYEAyZpF h4c3pM9z+YlmgLdUh/G2abdoamugcQOFbzHbZowsRAxEzdEW9wj2McN6mt8Rn1tc tY/+PcYuIK+vcmk9k23GuzxRlJlkaDicHwlAebgVIulFcrStfTlSkXjpuOuusfD9 2DuHMcUiPx3qElNB0dZJF/axpq7BjTIFENefhZ8CgYACn+vw1M1BtwEcJGW0olm9 YRhIZGTCRyNvRKFp1h5HuQYlCPZ0UI1QMQA86rxX5xTmANcbLHXVRD2y2lJrtFo3 TwU3xaGqsxUHZM6TzzhshDRqa9AfZzLkIHXHoOnnip5zuTTn2HHQ91ZzggCJ4Smh YEQ47cu+tOIQZGfaESzjiQKBgQCCfnZlDJRq/NFwA40y4fg4arANa+eNgw7+OC5F 1HrUvQTmIx7iLmZ0Dvv1KDgTSTLJ+MRgzczexYoUJEQnhZGS/Wq2xYt06XlBsOr1 d/KhFxOvXllSrzrhJJqaiS6YQQ36JijZr2aKQ7UwL7fUlsmy/safWVKStumX8Hmw 9jFOtwKBgQDmtirdNQ8aKolokD/3bDHPcDsNcybEpiCu8BIltxZAs/LsN1IIxfcp mGP2AFt3mbblKbsRM8hDW/X9taeG9s2KGe5wlKOE5lV8YAo4hFoJYN2/0d8Y0K9X QAAYU3iPG1zL+a/7TFLJ0u/biqsBg9hnNbMnN/tOeSuKnH2Rx9F1rg== -----END RSA PRIVATE KEY----- bouncycastle-1.49.orig/test/src/org/bouncycastle/openssl/test/data/rsa/openssl_rsa_aes128_ecb.pem0000644000175000017500000000334610556327510032562 0ustar ebourgebourg-----BEGIN RSA PRIVATE KEY----- Proc-Type: 4,ENCRYPTED DEK-Info: AES-128-ECB,3E3ACDA483AAD613760CC55C7DBFE582 PJupElZP0QC92uiYotAm/CG6i8ypU5SXxc3zmrk7sBdxVU9JQXsIE/oIUK40AlFW cGuHWxxYkdYNtTpuwG/CVlsrq20YfpxQrl525f4pz8ETWt/P5+aLQ0TemEKr+LVE 921o6LNstZpftQJbe3yMz0cFTjSfsxsHbadfUZUQzobr1XcbazPyhr5rrSntgIMy rJ5M4G6QrOEAIHfVVZ1oizlFnd4vjGOKk1i6APgEEqJTIyFWoCXEzDtaMcl97GEI EWGusd8DJrqpJKnohVoTZdOzLrnerJXEUEJ0cz+UjvljAYg2MBSJk5v6HCp8aWcc CCoWUbJp2933n4nLBq7EXTVmJ1pwbB4cjNM1oL2BznW/pdznrSRcw8qut35ikEKW mB97+IMVr03orl0uFjHBIch6cPLYkXKi5w7CO4vvJeqqPK+mCtckzgIlzsdTL7Pp tp+wrMBtG2Ibh2HeJuvvlFCgoYBY482aPu/4NMei2eqfs0p5g0bf67R/BiG2Sxxr 4o8hmR14v+dzLsQeoKrr3RnMqfmrbqgdkUfgBomlsunHUu9u7jB70TuYsZk/COPn SgMM0T1pxEuHdXfyZPSS9u2SFGEhbW4zIuVz79Lo7h3sKdYJqmwmgOk1P3IL/nra YpcacWzmV0g/GK8O+2CSGvEh1+m0ffQac1Pd2Abjzg9jghshsBTVTpkcFI0UfkIm gpP/hwLONl5a1KJn7u/ltFPdZkJ5CWPe0ZQ1mqjhDaPnc8j7iuFzUilsWITLRof0 KHUDsAZSV7gZ5G/Lh6DGZdlwfkD4b+2GOPayQ44mr4p2hdOque6Z/LEXtOv+UvvF kR9azOu2RXVTiDLL4c/ntltS6laT/nCg0goMs5NAis+3cxKd7Uk/yXBAulwR6wmy MIZuSM4gk2pqbt6TJWIfxl4ZtPwp+jYIpMZc47XQ7w5m7YSquJzjilaj+IDVPkhF TWTMf+Ucb4duBD39HZjBWAoLkF487M8KDtcxL60uHuhVJsKyYsb8b20ukA++c6aH 0VqU3NB8VXH7De3pA08G51P+XLurlLUUr118STaEd4r7GR8FddFmSh5x+PSuVXut D2p2W7pfvS8OTuaMF0PZo0KkUq/TbTpvMcTax+G0DgGJqFFhqxNur6WoJyYbQE0M nX8USnuJhS+BRNPEXc5i14dWmZEeE8i2KGm8RlL3KZfyrpBk2zwnGs+WM8xAlBSY KnGO6bLvRaUl+8IT1nKfY30HLr2tX+F0fEM9Tn443VgsXkYnMoaPDU0aW6+J0lLE lTeqJn8MPVRbU0Ss/0Q2PQLpayHrR+ly6yxJPOY6Nc1eLkhXoB1DwiGh5Mp7J6+V R5UL4nRr40hZy+35sH1lf/+1mY95Rb1hAYP9r5K9dAvqkdUMSPz8rtzb/4gevLi2 rxB5XyOHM/qZL9ySpJWjFPBwOtJ/EJioRTvnG+/8jdxXWBiGKdkGLKV8k1z7gOee ewq2/8n4HnzMm5YKdTesy6LuaO5TaOAUe89Eo/CxPgdM5YnxSxRsxunrPR8JMLYI V6xyNRRHLOy2ffGdJZ3nqbSOxCNiHW+Glh5I2jyrKG5Bs0S1jbt3l0hZKWSU8k5k -----END RSA PRIVATE KEY----- bouncycastle-1.49.orig/test/src/org/bouncycastle/openssl/test/data/dsa/0000755000175000017500000000000012152033550025577 5ustar ebourgebourgbouncycastle-1.49.orig/test/src/org/bouncycastle/openssl/test/data/dsa/openssl_dsa_des2_ecb.pem0000644000175000017500000000235310556327511032356 0ustar ebourgebourg-----BEGIN DSA PRIVATE KEY----- Proc-Type: 4,ENCRYPTED DEK-Info: DES-EDE,3D3D716B17DFBD33 XDCVsv17xsOpLWONR8xKRYxnxvWs+bdU+2XCqoqH+cM/vR4+g4lqSPSAco0/LkyX q0/C7/BE7mN6fzUMiECYUKS2c739CBVwDJZJBVGbMNFexaQRmlSxqhmbQ60oalaG HZfpCLLHQvrOZ3O82aYuEfsbqJTEPkGm4lUn/5psQwudmu4qyv8GFR4wVpNcg9JB rDzesxi1aU6dgHSlLHrG5ot+lAITh40SCBQdwkcvixyDIi6l4FX2AyNrcQYmFGp1 C3XaOn74ADLyo31Iy6rCb0KId6J+S+1aPUW2r1Xb6irI13/QYzIe8/fDfuyV7Ofq BKtHdu/oIfzl2X8BkuxJ0CEFxyyEE9majfItPnUEjX0Sn2PfOEwzq5LYYExpNuxe pHr9gtB+hSXC5t1b6ifv9PHErMNmBLdgLX/FT4PuL6URrn3LtydPcfW6XMkHtGgH zD/nnn8Kl1qXmkRbWHbREcOJB/O/Q53UwD26BsX+Sjwn2cfsgwQvZFzvmq/RwsCg Ej9FK80Tvn3ce+Kdt7LGUc9+KaH1OIn7qLcYu0Fhid/TzPCBPQffxpUJ1HylDaUz v1txJe3C//rg/42e5GUlKqf+/nzCmQeoaqZDG+VU3UKlngIYitlpwEq5fq/E8V35 JeuHzFjYj0k9VNsOHY/4AqmEm9qi1yxb7WGINsysO+29RvfRD1bm2Zqhi/Mg7YBo 8K1GowhW6uGFf+VCPORihMIxoT6xBU4xn2kX09EKrVdekrAi23QzslZXM6Ze0fxH 7LlktJwah4/QFHwB5qXwmHq3lN4Nj1id+CElVZXjvbKvc4+mRd7VSn++05IFjTK5 2r4FHifwpkGASJtVbF/7ZseaoOz9sHARx/MFSUp8kRZjOCzstWj6I0Fou51BTtRn 1ZCey4e1eKVnV4F1XNdo27Aw9aZjF4Zn5hZfUPuUYBwN3W33l8FXRdYEoT/JpiQO 8LS36SSZGVA0c6nanZoeDZsrPNtPJa8ANHR0QMwBDOwNr22uuJEG/nLvBfquG4HL Iy7nxBebe/0MXvsxK4OjjDzmYQL2msMlYffOABOVLCbtaPC/HBKUcmcpZ28WAzdN ArkPEcJFTgzI+hCAVG//uV59MkDnUZ+e -----END DSA PRIVATE KEY----- bouncycastle-1.49.orig/test/src/org/bouncycastle/openssl/test/data/dsa/openssl_dsa_des3_cfb.pem0000644000175000017500000000235010556327511032355 0ustar ebourgebourg-----BEGIN DSA PRIVATE KEY----- Proc-Type: 4,ENCRYPTED DEK-Info: DES-EDE3-CFB,DDDE26F919588654 ulZ1WOcK/yY3ugpb4uN9s8ejFImurz+p4en3zaCfEMdv93V0JT2T/49e+OvIMaOz 4ShAD3AO5zOXkZd5AUDI5Oi7mMIH2sUmhiJ+0xZMWITbAduYvt69lCGFchpQ/YRD G4jT1PY4WQX9o7nN1EYyPnH/vx4Rk6lnOZz7UNpK51SBSBk9lkF/d3bH3J2+pYaN G8VET28OIVTs4nqNdu8nxoE8u/Y3aW3FVsFCA/ZhmBD81Odb4rHAHCqJl00ApW91 nvpTkTjfF9+EfdOE3mfLA4R7CEVWaqnfzvNrVCOILs3qSFGKbIBPBBBJbc4d4pEm G+8g5gimV+oL/Q6njSi8s8yV1WWf/nqK6EKd2JJglW700V8dbGHjhGChNTM4Px+C RfTF+kXcQZpcsax5ULUz+4KKD2Ub5EcWumg+LAe36VVTz/zDTxhTzsm0/iN68KTM jzKjIY9PkVIhZikVkp4s8pL97rL9Tota4OGMacPx3C58MSwJSg7fdUehAcnj+GC6 Nfi+iHxVpJP4QnFi4BotFxlb2FoVhoh51YdaUehqD0IsoBxrQCmT8nVaz9asJMCY CRXNO/2pUpNJY0iGjHfvdmT/aRf+gmat41bX/1r6Xxujf09JF1iS5v/fpYQsshZc N+xysjZ8Bps2Kx57XSUTz3NrwMuliJgw6ZbDYBHGSSl2lueUanNArE4iLakuf5BK zuf7iVNTZEww904RhnA3HnivRH2b+Q1mWxTezSYZTs2Qr62mJ5ewiFjOlv6hPUfx T8/ka54Am8dHsgc3LUDK4pFFR0Nk82yU52FJPbGsggKZAde2tUnDgup6gNmzEjA7 rSWxEfg53fHda79SQzrKaPGsuWr5b+cl20rGycqN54qZafKFah2tfCzgGdVZG+Yn Wq5wvZK7Elmjz+URvKitFhw39yscj4TLlEQ3K/jZVu5/lsyyu3imiUholwMCSuhV fg667XbT1qSw8KPWoloOSDQr60d2cK8Olg9DjfMgqmDxVHMuALB+O/dhJq4Jaa9c e6ycERign27Fv6j09/aAGrsaB9gMXCOmMhYGSoBUptjb2dx8mN/z3fEG9ykvaDiq i1+9GnfRKIYzfxTa3PCpA0B+ -----END DSA PRIVATE KEY----- bouncycastle-1.49.orig/test/src/org/bouncycastle/openssl/test/data/dsa/openssl_dsa_rc2_128_cbc.pem0000644000175000017500000000235310556327511032577 0ustar ebourgebourg-----BEGIN DSA PRIVATE KEY----- Proc-Type: 4,ENCRYPTED DEK-Info: RC2-CBC,B0CBF8975CC514AC eH3gBb3Shpdi9fkBr66H3xWR0XnIrKhPU1KABtoaYxE3N7su3duXHlx4zpc3YyO3 s2YwjN64PdGYgFdwrznf97SjdI+MSJgu2wMxxTwJwOltEPBdbvNWEpq8SLdfdlDv +zndoR7YnMIhQPp5Hch07dhwpY0hn3RELxYf32ALEbe4+xG8/LZWUBoKdgOn+trk 1Oh0VB3eupjtsdxDWMMN3Ar+l/1AfdBoaQcHg3UdO52U+mTc38QAaMA+9Gplkz+Z YwjWz4tyltvTDWGAYGuhxTPVt3IoSewGVHWxKezFujNEhj6wuJBTlpN5T1pALfbD JUiGEmBXOPcxwa3QKmVKJFcA+p5eOYY15sqsIhcaXxPgzjO6JQWMErkaOnyB9sHg fQTXHwMau2HqzjOM8Qa/lQyv9nf45IFupKoTT6Kja2WzAVxd9KGW+NZSAa+okRSr GQrsXrJBFl3+wKpXN3alj94GK6aqCBiyd3d+pp2NyM9TorZhfWxbQamPmQVaU4aF +nJjB+lW30wPZM6Ik4UqsgXolYXZCtV4cOaZ7g9ub2AYmYCA6yIagRFfjuEs0/f2 MNN+qu1Z0sg0oCCpqO9kVcnnC4jIaXvU0egZVlGZ51GP7iR5VsLmi3VTbebnsvT7 x8XYI1WHYuANsSBNRJj7vmrolzVErsX90FInNcnc7o43KQGyeR4E+vSdqoLHbk3A 2HL9YLDV5cdvGafL6faVKFxUaA5CWCFVtrV6MPJAm/xWs5nu3wr6aNsDk/0R4mqi vzQe9EjkMprrihpXqFGpTaehJQFgLaE3FwnxPeUFawqdKIqaKf+stx3i24LkDSPs ukLiYS7cPcDYXN9kI6a0fqGtT/gL7NVa/jxsrl5+da/alvm/Ai7TJsUUi8dMzqIy 85Hv6xWyPrwCbar4Ehq1CopxWvINo1AnvajIkBHvh4EtK7B51stOO6yNEV7spYxb nze92IMAtRNWO/yp/p/nccy9PB8/e2v41T8EN4MJuDxGX4k4cG0k2IGzBDcBM1pC YfmkHzMBGPsq3CQ85balLEWQTgR5nr/8+TabxyloED/Sw7mLM4gqMmn2KukzMxT6 qeiFiGtmv2TbD7OWkaLj1Mth/ns1Of8U -----END DSA PRIVATE KEY----- bouncycastle-1.49.orig/test/src/org/bouncycastle/openssl/test/data/dsa/openssl_dsa_aes128_ecb.pem0000644000175000017500000000241310556327511032521 0ustar ebourgebourg-----BEGIN DSA PRIVATE KEY----- Proc-Type: 4,ENCRYPTED DEK-Info: AES-128-ECB,174C8C70B397BCF00CAECA7AAF7A0A73 wzs0bJqGg+Scn00TgtgXyV6hopQKVWMEFnMpu6R/Sp1tbPVlr+m5+SppJFVyW3WJ YeFSwXzuVAsnbD9qIZpAlco1ZYpmRXaY6IfXJKYf58v2IrqkxVd6AwjGN2FloSNp b/DinJXJe807tNAkuBLQ/7QlkCv/BmZMeYBl60XYIH8LDF/T/ON2hREl49zr/GLY bwmVzgRpfl3c8QIt6Yl9uKOqCFJmMHD3YS+dT2RwuQwqY+U3DNzVoCci6Zjd+gL3 eb/S6VstodSR55qF8Fkwt+sy5yL6XmhQaGWEgCwDwArN40MWIEpx4NaBxCcqHF7g o26bg6CZwY7Rv42RTHKHNPETegZneAMK+e1lNassSijak+A3ng9bxiBquWSKHe0i s265Rptr/GvQX0hLxmfjEjvL98dKVDZpvdBaWRqV2lS26jDPiFAHtVsXvF8uo25J 1aS8FDHaD2DghC5aXTQRaVy1jlMTm2YZeVfiU6+7HVXBkLsVbShqEHxKylxgtB/1 OAui+st60+o8lvRmn5dT2xnxLn81Bt4qron4pz0LdzC2xl0DqjhXyRsf7kdxr44h YN1YzmdU3fYFzQw+VmE8xECIjPukp+0HSb4n7BTGsWvqzntFIrzWGeRmNhjtMcwy YJoWGnz+WbxP3DJqSGNdFME7mNI/kaybIkOpbHLLlmgD7XWpeyGYtsU/rzrh5NXN YRj6Nf3TWI1zwS2xx95+/5vc5Df+sb1+/33J4hbGOx9KdfqoVlJZ16puvdTq97dF x8TVYxk2PfBJpvpChCsFlYBOB29F+kY2qoBKPbrvmFPsPCgI2q4gFuJ9pq1qyDbK pq9d1oewOOxR22VMQNGG7tL0tMmtXJ/z0n3Y1UE3aYiSG7apOhooBAQ8grpuwqbn mGTz6sYB8fHdCnedcxEUxxuFjXupmBcT2ulUjFZgFrG0SEMElgTDjtG21eurqPKh ZgxfkW+tM251WTi6sqjiQO8WYHlU7+XyO3BKfH5v3kz4qXxsmvKfh4UOfRy5f9YT Ft5oi1bos0soTvms0d8ckLt9Tph2wgoz3Sc++4DRcF53Ks9N6iUgtTpkEtmd/Uc2 5+xewYmlfYO2qfiqiF/6dSVfDPjJYR/YLx8KBZ40/e0= -----END DSA PRIVATE KEY----- bouncycastle-1.49.orig/test/src/org/bouncycastle/openssl/test/data/dsa/openssl_dsa_des1_cfb.pem0000644000175000017500000000234310556327511032355 0ustar ebourgebourg-----BEGIN DSA PRIVATE KEY----- Proc-Type: 4,ENCRYPTED DEK-Info: DES-CFB,6215481F0FAE54A9 4ZA2xcGT6hS0kQObPwTWmluIl2wTnoL2jRMbxrr7usOZSLYISprcATZWieEKLsu0 kNNzIptFCmRDt0b8VlothTS2jBIh5nlu9LqvaUlIrVuMEn7umslWrLK8JWnHVKOO dMfqNcgmYlkbEfmmXLtlCbfQHT2kVlopD58yxf26FTQ+27l+hSX4wn2uD+xFUAcn +9ZxAWQDhi2PYVKqTTPfhCPaKW7hjYdocADnIZg+1mhH++8fPxlDmBQBmMOid53Q WV9LI4Fps90d7GumX7qSUFZTkBKN3v+E2ahnoP2bTBQGkqWamKFTc/4uLCEGlSWU qXaGCy1AwPa9As1+B/jLkTstoslJppqvOooWW2R1o7JHqN44luXXQPZ+BcA7dSdf zRcMCpudB0AwHBy3mnUNuBlUjsf4rEpq51HPSS8duYow2I127uI8m8OCoZCaUVid msxVMSJIiDCiBi18EfCjMfGLtQVxJefMv2hmcAXQXSRDJTEw8Lrtm0Mtp7XK2B0A v8Kqpf3x+VBc770Xoy0K1/fe5oLdvJrJOLO5PVcVXIS9B/DTqIQ8ObABJPZ1sCKA sV8XebteS8fNXmFrVKBTmHBpUY8H5Z++VfDtKZZUBYSOqbFT+UU/+xJKlKICzFTo YWsmPTgFsu0Z7/PMyg/rccrb9fMWRXa8et0JGoF2NlYu+lkRb/nYPe84oS8RzZT1 dtWJMiiom4xRgENDhV6/AmA9IuyXT3QbDfFB+ntdyk94U+Ms0ODNcdA4JmEa/f2k zFjtEGWHPH8Quit+zUt+8JnWSSFp0mjyA2ZtEj/6Qg5rqAZMdlpTo7rcuYOTHScn ic/H7V43SuMlRAM+xx1bGrNzjWUugHrVb7Kar56pSRPtSOQ00Dmz7gB8V5LU63n1 YX3faatiPUNRG1dArcW36o9dZ5x8O5TErPHRJNYG+96UNoAzHMXoi5thuRyVbzne FpOqgxsryobcht7fwHuYgUq92QoY2qG6qMwHc2A3NrVFi8lJ0R83SN0lOzLebulu +zDvrvkkRyH14uoAWi/o5IGBv1yIkO9vYApntrSO2aLnbevht9MuDJqW/Lkb579Y LG/sVwxTmBT6jdCgTdpd1ExE -----END DSA PRIVATE KEY----- bouncycastle-1.49.orig/test/src/org/bouncycastle/openssl/test/data/dsa/openssl_dsa_rc2_128_ofb.pem0000644000175000017500000000234310556327511032615 0ustar ebourgebourg-----BEGIN DSA PRIVATE KEY----- Proc-Type: 4,ENCRYPTED DEK-Info: RC2-OFB,F01B181DC9520301 azqFQnexfYYO2tX4qlC6XLU2tPX5EdwOHsruz4uzVJmYFyRLlrgG57KkahVjWupu AHkkjhr9d9m/0/t2vFy5JEnF9WWcNA1nxqzfsaIKmnuCULzYzMWu1cFfTV2DZoAn npdxa/eYmcGRZ0u3aZHRGpGtP1y2sKvWmUInYCc69oigiEn1qyDkRE/tDAREh7C6 DWRcva94GLj1igIHc61lBugZKBlchv+q8t02Ga1slM10QRg2dgAlF8uCPZe+NLUk 8uOifATkKTsA8OsUgn9nRK9dH4FuZeD64NMCszOw7mYtjJ7YW0J0wYgC9BuEUcNm QTxellBcs/qSdi4pZWsO9JXxvoc0lTmvoiS0rL+JlB/UfubVQYq+C7ScVJeTUNKL 6fF8hvfQzqDDjqx+qP4SgboAmIbL7tTJBeABnnhCOtaY5vSuT0l96rIQm/EZdlWD hXKcrhawaq6pqh/mV2S16e2gDRQyUX+jKvumTQhjN1+AkIb7EMR1ZLJFX1l343Fj 5/V4D2+H3EZhbCdkz4uI6I0swDasUjtigcn19kOy5t1r49zpTJ3wxQptLRx4AXUZ zjVXVebGyFYSdu+Lks1VC9WDeisBW18kCg5IpOz3eo9ULBBQZnzSKS30OXlyO000 /1Em8FPKSKYeST3SmI1aDObXOG/s4tyKTCj+e2VKROq8hDhJQUYUP0AgYkAnwURR +XylYEfUrW9v758Kk3u82ZhEen/lLUQhWeXkzhVi44Lgih3Bjsm3jP5f7KO/5KfM UqECKIHR/p/H/klXPNmdFo919AFGcnxFjQCyhlv0Bl8FSc5FUkRl9TTLu+h5m/p2 ONV63odsVGt2q/HmL+3hojX/BxSEP/8Mq1JHR4Dk0qqUpSxRtDw0XE9/LU6s9NZp zm6lkr5E2U6EN677bmem5QoxObNvc88EXGr0EvoWPnhh20lD3vQok7GBucnycoj0 9NMmRUIflnj47quAGXI6LuTSzKqOOCZC4yNvdyRdil3DgyLLefr99m2WEe0HolDu pIyUsgHMlZC/YRVzqP/6DklhKDcvgWbBeqqhV1r/30rRkegHdsWiAEjmJadlBrJF szJZpa9obMH/q0xUH3AXXCkS -----END DSA PRIVATE KEY----- bouncycastle-1.49.orig/test/src/org/bouncycastle/openssl/test/data/dsa/openssl_dsa_aes256_cfb.pem0000644000175000017500000000236710556327511032534 0ustar ebourgebourg-----BEGIN DSA PRIVATE KEY----- Proc-Type: 4,ENCRYPTED DEK-Info: AES-256-CFB,337D3978222A1367F5CFE08611416E9C GVmy9WG3oR1Vpfxnfpv1hFvXGzBgE+c4jplSw2BAlKnbznCPbZLc3WF/ZMv2851O iE/8sdcetzoAlm3jGPoDi6Y/FqMFmcbqtro7vUz/SVgi1HDI0FXjOTPtFe6xfzhv 84qt5lz5VAUueTKFXEZHqM9tV7lHt1FX86VutNObn8pE7nAWVX/Xvq+qWUsEx0ik YjZjLY696pyz61hnxZE4jKZLRx/9a6vWYaVfzsEi2FLw9qAsw6ILp+xDaAeKa+Il YVkgDPi62NPr7cRX1WCiw+/feNYPgUfGiBNkd2mOnAr1yOXFM+YALw5V+q8I6ZKN k8R7skAzRZkwTJ9WaaFGD/UypYmhe2b9Jp2n0BMEn5RpW4o1DTIHmfMSUmUPp5w3 HjbtdDUWIiuplrz7mUE2sez/3bMbcoiO2Ym9SInJKBrMFSvyasg403u4QESYQhC2 Lwcocb5ixXoczHjef3CogL6BhL2oZwXCl3OBqpMOJJJKXUPRhN8bvgV41UIsiGtN TFUXqYdpbmMkxJNMGiD3mKWpSm2MMdQYnRlxNh0wXLi5sHckD/WS4yFrNsCIMVDT W094liK/Z7BmplY4TyqKhsRlFVQ4VOo/W0WNh7Ayp0siIfo8vHDyoQsnUkn/EUER UZG1lIy6/y1RSg15GWpdi1bvT9URjElh/U944LSYD28K2VU8aPKaRBokk+K3AyR6 YhZRCBr6uIVZ8HDkBL5OW0eP69/jdbyc4MnWRa6C0d0boA7N639j+NQz9erYT6wu RkInmBbVfxQD6HLkMwiuU23qLP+QQTLkH7rQJmnRPSwAKEE8RiXWi4/TnYW7d0AC Bj8oaK6DO+J9t1pdj0IGluf52iUwAOf2Pxwvu44ovaF+yb2n3P7S5maDGLTV/xBW D6nEAct9cYj22/aRDTLdpOfG0L242vjQLnjrgezBLraa9eTy29hR5FU5ACH5sB72 rxUSwoCHCJuNFSxC27QwZqeCFw51epwXxLv1CjqsQi2So12qH+vFVtL/1YrFBct0 dzwbdNk0S6UyPRqfiOE/+Iszzahmb/GgskPJdfT5Y03FnpDWfOotpaAebrY4t6kz /gs8pxupvdKw4eWsxVCL9KOP -----END DSA PRIVATE KEY----- bouncycastle-1.49.orig/test/src/org/bouncycastle/openssl/test/data/dsa/openssl_dsa_des2_ofb.pem0000644000175000017500000000234710556327511032376 0ustar ebourgebourg-----BEGIN DSA PRIVATE KEY----- Proc-Type: 4,ENCRYPTED DEK-Info: DES-EDE-OFB,0472499818A0CFA5 A+t7NfS0c6IsREc9+AzXRaMGW5GR2Ao+WBBxXdxNJZ2n6DWTcNHYL1VZsnVOoc9z N2PBfTjYQkNtehp4LDnypbooUI8gJ98T33PLkJ0/L03fs5iEiULcrpBLGc9gsNoO +f0JcI4xNfE7bGvtveliBWBsn6KeCdwrdcOXziWGQCge0pftf7m4HZ/t/0ISfjXK x3ftgiwrvLSnCHfp50xXdN4FGRaIj/V+C50efu/hkAaZ4rCcTxgEcvi+TKdDjmcy MfxWmUmeGiT0MRongCZB7XH6g4sI3nwiDASLzvZ2dBysLD0wOhR+g8yumSH2RW5V rTr7JQANZzdZm4MpOv2fMCHzDcKEtPd+OlYMHegwE3p0y4CLeYByT4IdyKHVLiWx lwAKtZ15VlREgXqBIgrtG5ooEIIjdlabIckAhRc5yOX9sXsMePRyPgQSnG+nSbQ7 6Y1l+3XueWXjsnr6SIXI5wbszM+TFbZAU6d9tb7B63R8ancHHSUgAbmSL7QpYZxD oNYseUzgPv62oMbX9VxiWJ5ZgwzS+D0zGALw3Tb/YVTxI+/VZ58ITZ59I1cg26HT H3P1thNPIee0zz3zewMdILgQLh5RWkJhn8/oawDhVVPBba72uw2nGF2aXwbLWx7G eJ94GeikGHOJby/J4G+0D2lLlI90jP8KB2fVqHxENGKSMLjZFERGvpiPTgHxWcgI SS3ORTxuJDzqG3qFfMhFwQnq6tbOsny27scEQZeNMGecfqGLWE+oclqfKKDQDm11 JUQnsnFAT3cNFyd2bKefeN9co9NS1UTUw1m3gDH29kwmggFLwSccTFobrIoh5/le qiaHdEdmd1Fvp2nMAVufwmb6G1dizT37benyr5Gzc8CHZUMibFEIhjkmG8RQ4dyb Byai6j2gf6rzsbKiVtKqgCgMCw5LG8xypzitCBc0+DsYBnlAyS4hXYm41eqMtMsF vrP5uS50iDbAMBjuIpWdlRewjxEqiLPZofjbMGwbrvDu45LQ76rwLww5OUj6567b FJRcXQdyt/bWqB47GnAZq8NABCtY9HG77nTgqstOqYOOsdkuZC33JHAwTwa+b8tq 2Y7Zo35CmITqLxfjr2IT5Yeu -----END DSA PRIVATE KEY----- bouncycastle-1.49.orig/test/src/org/bouncycastle/openssl/test/data/dsa/openssl_dsa_aes128_cfb.pem0000644000175000017500000000236710556327511032532 0ustar ebourgebourg-----BEGIN DSA PRIVATE KEY----- Proc-Type: 4,ENCRYPTED DEK-Info: AES-128-CFB,C0CCB782DF620FA388D9A356F8B7C346 DftIvr+HZuCHBanw4n8P5ZajHAw1ldQkSgLxtxY0ZYhhVDLEqEqh6z+4ySjZz5SR KY7kYFo6yJnURurg3DAGvJ55s6jgyrRHQZkhiO1fBxhyarOfcBjJauJKDT4uhFtC LWZ7dqft3PlcHi09mFKjK+BYjULe1QkdrKQlV5FBpCj7ENuHqtfx//bV+IWWVnbu QRx4ec2nNCiS2qiI9Qg7fgMdXWrpJlr8Zvfmn0Mta3Dn9SWR9hK5J4d3xiBtaF0F +BNuszy9poxnsRaORZYAsBh2vdLaQyn1gGdehlsWG4J2Zb5RHApYczJcp2AoPX4K j9wAzlfLRSZ4Lt5edShd1zf/iDxegBKQFFHTfPA6uu+fe38qckdxVyBdGaCCBvUz Quu2DjjXdCWWo8To5C28LVoVyAy+qJaX86vn7yw03/6n0y2dkydiB3u6wnucsom2 HfLX+pdyarFoNvtCeSW3Y/1Eqd54dDhz3GrSTh6c7G+wiRziKpTduEmoZ+l+CIrl tWxmh59YTSeX4mi48+fxTA8xaVwD/j3VuA/jTOQWDW+DXU2z6OcAQ9rlOnT6Jad6 P2El+vgLrIFbC4eJs2ry6bszqFJ4wieBVnazPCUADLSsXVwbFuO9oB4129y3Yg+U dE+lN24KV0kC/YIdO7c2PghaFY98CVrBX/oocHy4j122fHfboiPNh7S7n6cqJHh2 JKKQK1qTdfULAN5ypecl27gWeM2i3ib2C5jJiOFUlwiAkZWLRJlsiJOk+b/rI5FD tM7yFanhEtcYumRRoSzKII3tF0h+z2AwzPdsyJDdASCzo/DmhB0fg0O8G0q/isNi VV2zL+w7mNmf79QsrGVA39Y+G/uKS2QPf3bGFthzYZwKH1M9hTN/do8wCCJJv7MR Ejnd32srumBOvGXnYtGuHnT3qRA1mj82B00bdfwCd09GGUr6mEQwfvsDOR3q4OfH eGCn9NkWKYvf/QAxCG9Vh7u62sUlXKS08hJcVAgBOzN10wFISTIOAvedt/q5GMvm nRuF/ixs6f6LNy/VgyztHoQ4vN4HBf8teDsbWSMDvlLkU6tQZjyuu8JkTjeDaqMv GbCzrRBldS3zMXX2OaWpZohi -----END DSA PRIVATE KEY----- bouncycastle-1.49.orig/test/src/org/bouncycastle/openssl/test/data/dsa/openssl_dsa_aes192_ofb.pem0000644000175000017500000000236710556327511032547 0ustar ebourgebourg-----BEGIN DSA PRIVATE KEY----- Proc-Type: 4,ENCRYPTED DEK-Info: AES-192-OFB,7E4DC037A44E5DEE4E005CED36B18C16 hvLtWTLg0+cMFDo3jN0yZc8S7fE6cDdZcBK0aRy+Eg+9kWlnmR/VYqG4xaich3VQ wkyhNpBSAoUHY8OKkB8hYsqbGkuKxQ6Db4IJlahCTFgb0yO2C7pUrtGDTvmXVq2n qJ4c+4CILeyzIp5yfy0dE8CAsZZcLEdSpPvaNK0VPZEPhelm4WdqqLozYVibR0KS 2BbVO+E7yHGC/G3xtdbduuYpID1pLwyaebUCNgblggn6FJ0G2+Iu7lndmMU4B1Wr phvb+Fd1kL5421u8OOKRVLS2yMtlzbK2Mz7NclEzEs1m6K/xJUzztxImAxElBiiB YfOw5WLy278DuD1GCBkSuAKB4XWUtlq0+tJnCzAG0yrdMloKH1m+XF3MXFiRTXgE k08PcZchoNgGP51Rcg77skATP9OMamcjnkMx1B8YxTx9O5Vv/oSIjGQrr+t2np2t JU1dHTr9QrCeadSz+My0sjlZrL3ZisAwBbu6C0Zta1P1eB+i8ORZvm9HvmadcyyE y5oQWv7XwSfAQup/4uuAJ8bQBunIH/ajMF1WmD8rzLcUjG8W0rnBWUtjaxxBdkWv xBzgMPm7Q+L/5yhL/TMH3dkUBq+Cg5VQSe9EspNRGKBUgfKYk67Y343Mv91xKtX8 8Tmh/WlnYXDv8QBnFJZXVnf8HeSFHsHDzfTgAmWHdhisTNwmgSFvBK5ghvhvkbXI UIPi+FgeB7P3ccFYnmoMq5qgK0Ki4lU6v57soDrjRl/NttfXdQEhLfWO1zXNANLk lqEhJSvBPZY4/FiOW4kNaZg2oRswz/+Bmp3amsK5TwBcI72rnH6SW5ADqPCcTP+h IrH4L9wnhOXw7QLk/h58JwiEc8suj5n0PJPQeHKajizd/EpUzVAuRTAl4GMvxLCY rALxeRaEXfJH5i/0UQydEvdU3ZP/LTibAqStXyVlSBZmKOg0GNQ+aAiHZyBnI3oq QuD0KuJi84ETMLU2baRydTbVlQDr8O0vxnCNlPkFFOqVpWyOyBgMctUfFJiM5c0l 1UT6dc2F7NF5WOuoDCVw+Jp974CJuBSRGpdQKGms1Dvjwrtnf0ycstswXHvp2ZhV IVeCbT4WWh4f9bp6STkdquSc -----END DSA PRIVATE KEY----- bouncycastle-1.49.orig/test/src/org/bouncycastle/openssl/test/data/dsa/openssl_dsa_des1_ofb.pem0000644000175000017500000000234310556327511032371 0ustar ebourgebourg-----BEGIN DSA PRIVATE KEY----- Proc-Type: 4,ENCRYPTED DEK-Info: DES-OFB,BB20E846FFFBD3EF WeRgcZKkDTSxqvtZvx9WwUZYqXUUpY7siLG1Vm5jXPaEFOEQhmvGuNYn2cwwUYKD RMN5+sE51urDgI/xk6jdS9oZE6IlfkGeQSUoEOOfPVyVD/0/E2G0QTcKAAWB56K3 setBb2ORbM2ZhetYUp1scaLObMEMQ5LrZaqtA/jUd2Pbs9D2MqafEH0Gde8e7mXy 1fGNJWlj8XtAdmi2BeDKZHx5Hu0r/BOTic++L0Sv66wbjHw7RDji9Rdv/vyq6DIi 0v0ZCexiNVed4mqD/3+8eGQ2z02UD7aZPy6T7E+b8kBuBi2ouB4HqgexVtz1L9x8 VBBOBdpOLefwCZlNaeceg2kSIP9mMK919hlH472BO615YB4ugaCilUNLpvv9T85K s4hTB5oDcQH6W68mz44vWqSwED8JcdMYvivWY+3/zBSUvkyI8+8AErnVr8tvTX29 aBhfegKV0MbRRRirj/EcxhUhtfgbAtllZ/Wpo0LWpIsHT0GeUfWdUerbFyh/8Tfr OQzC14xoLHdACDz5IDrLaLd87hZrKDJOELvzoSugg2W9NAzGbfoWJGVlvZ0miZcO teULyYcK/A7Wcba+jmFaXMrKVhNH0IuGcU+Pf1lYcchjAsdnrFMVRsNJ99QWlN0F +dTyRgaiCInnmJqT83fI58dMmaJPpMeW26jItPWZWAA0vlQB1RgZ8C7i7V4keuVc 0PYolX8WpLrrpUpJKOTdW6rmeHokJC46gOZoXEwZCSKUUgreROLgRN79RMBHKjoj 0vSZWowgH82fNWYWQbJk5z4ldulWEVye3tQhRNsZarAWPFEteiKDTSkawmBpaA6q dJWiA+EdrVvnNmw5+xkbciMX0nj4xKsjRgPawdMFZaZNE3xu2LkrfGKDa1ne3JdL nDeyygGRDsl93oJ799maHaTLDyub0CMdyf2MssPLFklJdxwbtxNzbI0gt0NhZu43 FDg91Z3hlAjg/Q2h1dVM22m3pnju2ygF11HUQdNExHlv5w8LWMeqWQ5j7WhSbM4c s2v5JURZ+jXFEf3jCs9h6pLlQNaipDkUQA/6DKHf0VbZJzKxBiRCwSP/YuQ6H3yP dHGRAd5CQnNc3Vv+yyRqQT56 -----END DSA PRIVATE KEY----- bouncycastle-1.49.orig/test/src/org/bouncycastle/openssl/test/data/dsa/openssl_dsa_des1_ecb.pem0000644000175000017500000000235310556327511032355 0ustar ebourgebourg-----BEGIN DSA PRIVATE KEY----- Proc-Type: 4,ENCRYPTED DEK-Info: DES-ECB,1040C4105685E404 66Uasevd2pON2SFWljlVyWqmErfZn4XomzLHlUoagIwnQUEgCBCCpUscES98fini roGF/iaY59JnUCMieugke7/GZF1C0aXbIReqds7S6VFfu4Ni1OQTkL4rIauHrWab vgoE4+18OlWw6Rc0wwJ8NT/NCOmb397yTeb0w8VYERyzpwSLXxQ0BCOq4vOUX7BT 2ABX0moazjUSyTO9BQZpABF2SshxaWFbAc3QRwH4QnO1bm7Pv7b1rvjrvPZ9LxgN fwjXG+yfHFBBojbEtFvgXRsSSyV5WCmAgYLgk5/nIDFSnRQGty0OuP+itX7SUK1I PH/ZjdIwezMKbyuon9D1AvdOEC1xiKEdmJCWSokm0djIVNmYbv4dtfrQE6hYdMtt C0LbsT7ef+jl0xG3k+WK24OsBVhTaqj8axIPZIVLELOPlx4EMfaFQgUjgqf5vPhO x6RSSRy+poFwtjI6ip/xu7ygqmcY9COXCcSffk1vpw9v+6WcMaYmDLwBTrTCNsdI 7i6VJa1GiCrsn5o6ydGgdRNkF0N0sUfGnSzRUgd3BGd/fvxhBmcxHUnr8srrHYm7 D54VL0EUsP33F1VF2ELl94GlWqfAj8NGBDkTbpUcqOeL/ERxdUWfX5IEc3h7fprs UjjjQ+d3GRliRs27m4ZuLtGeDEhDtlTC6qtKyqgVziPMwG46tcqyFzhbLCErHNW1 07JcoDRc1LkXImSeWgjjhskUX8nc2/q5giTVtGmiWMQwEc7aYQ1wPbVAIGPQ4PE2 XB8zvvPEaj0wXs0JjicrfzUBo6cRbdfmWIfp+ZoTUfr+gS/aZm+VYt1G7v6u7Qel AtoSdpN623OvqIP5ZDjOKROmAdMbXkxwwusVNQhkbdTzDYNy/yJnJqUUlhsN0VTQ y+O8Fz7Q7fEYIk8Euz3Uf/BTVGbLSNSA9n++CJYg1nam1S51WhCXRDckDLR0c4C8 v3zpJvaQYW+xZUmlzrYRQgxkfzv4+j9W+kZLgvitQizXfTsuDyO8gwIt2csfGkaL EgX2+oITD/sGoaSoGknY42ePI3pPXHlhBjPq6ZWZ7uh6Ia90nV1j/PAcOEoAspAh pEdIAkFJA76qN9JBnK7lRMFXu/EWtBjD -----END DSA PRIVATE KEY----- bouncycastle-1.49.orig/test/src/org/bouncycastle/openssl/test/data/dsa/openssl_dsa_rc2_128_cfb.pem0000644000175000017500000000234310556327511032601 0ustar ebourgebourg-----BEGIN DSA PRIVATE KEY----- Proc-Type: 4,ENCRYPTED DEK-Info: RC2-CFB,CB9482EEE6EC0DA2 Bo62wJPRVVYQKoP0egdW3dLX4yU/Dbkx8TtIsNxNFhdwpGWtEGzervoU73+6aaWF LME/HVPUh+iZPKh9HuwSiP0GtwJzCv8arDp09mxGJ7XFcqz3AS7T+K9A1OclVa5o LwQ6ynBtCsmgiVlS/haNjeONqCtpy0kERgathUclwQCLTnQBZmu/l2Pk8Gdtc1Tc osmKc6BDlPOyofTt/UnrhVuZxasrS7tKEnVn/iZr5mjUZAqmC2mJcWT5YNahJpfO rawRjukIUOm0feFwov45+joTSIGDsNTYD3OV/+BF4ZgBMm33ApAE31JFoweUcI03 2l+WS5qtmcwuOYGp0Np0BWg09KVwNbIghfiVUEjnqy55PCVOFH1RZrmHhPndCvHQ BwAaac0yAtd5vFWjeUf+pTbDmkA44g5f5aO9uQuB58WWkB8JCFpGZLizK4ISy5ay dE8+SjVGiMSZBDfAmiEokoYymc7L8bkTIl5Jo4TuMmtFcHnfohZd6Nue3aRzNZHJ E/V81IxIytHRlMl/dZjSujPw9FgmXSip/U1s8ESIVOVoy93HnaifgRfkkGggxp4l S8QqBvJTAJrQ9ygO3PBjgdKGi1XWvhH1Y5EwPJ6Wor4zzltftELEs1O9xfBT/zeV GENfUZZU+5V5ICm4K844WoiTkH5OIWAi/ZLK9XRqchaGWvMpv9UwBy3c0KOx1O4f j1/8pbXDv1iey2USNL/Nbw3nanIG0dIbUZ2g2U/FeKtfCfVHu5LJY+v6njKl58X4 mthqvCZyyJy2U31MYUUDN/lgNffwLnzFc1AxYyxDZwviKmAIN+Ylh5jbxuElCS1T bpVd1+4aber+qv9Ar9G/PJEt9ZdHR3RB/tsEXv7ORke+fVzlKFQu9PKo4k25U/mn qfBcwlut9rMu19xsjbowqHyYJbenyrF55d00pp6P037cOKLStJECtpgir6HgTpo2 Oyavx3OIH7ypvcyaqhFUqZI2EiGOdBwbSBp/jCqOrnAwTKo9uMcnmrsKj6EpjJzO VGK0DoieTEQ9VzGbqZKK34NHidE4j/MYW9lGKAADSy7Ey0CllvumHiICWOn9aJYy ObB64C3p8NFEcW5SrTzPtXeD -----END DSA PRIVATE KEY----- bouncycastle-1.49.orig/test/src/org/bouncycastle/openssl/test/data/dsa/openssl_dsa_unencrypted.pem0000644000175000017500000000225010556327511033244 0ustar ebourgebourg-----BEGIN DSA PRIVATE KEY----- MIIDPgIBAAKCAQEAyKItMopMK218pcmy6PkrMVXAv5dt07TdGBuNhVWpQ52ldK9X mL7CPKpo4Dy85EZRPvRNyOnhe+LRJZ+ReKntpEkEiar/ZsKVkUthPsiUMpoM5S79 JK8iT8F9HdFjIFKaXGySBZ4xcrj8HQ/v75iolYCso+66Ybgjs9/nsWS0UQyGE6rc ibx7xPAtcbaGZUBaBtdkNER7+P2ueJwej89aNZxj+AKuvrWrArq6/5zOIhGR12wQ EQQjj7FQ66ZFivJ/AYsv1yXDS7mZBNp5eMuxk8Kmis/++HKcP7tdbVRnlfTGdBuN BMyOcBTIsE11jwikcI+KIbr9cEZoaikkm4KyuwIVAP4DZEC+/JZJ0PHSEtJTt6uz yn1hAoIBAHhLbqDib7zqaFBrNnbaBSNiltY3GxWM6uQT88NH9YWz3wXRb6i4KJFH 9NtLbK0RF7MoQVprJY6LuGQHZ/e61Fs2EabDwT4vB2HT619fVUvDndbuSW6qfUR4 y9kbG7zLkE4Mnym/ikmUwLABLA67cZUS9yjtcRXGpOkiTAQfCGBeUH6nWOFEaWjI fGNMQ5awKvZhIvGyN4Zvd+mE+199s/kAsCKFux2Sq9tYw3qS0Tw2IEebHsHvX7A3 bvxV6p7czVxlO9+O0w7bBTekPpw1BnCYmPyy0H36g/7aF2V70UCWzER8zT1Pfh7d 3P0hLqHYzX375l/7oxuDawtcDAV++iwCggEASajPdllHVQ8JvKdPH6qDkjC5XJTZ RK46mYm1cCu8Q9Dy9ZfL67CcJBpwKVHNC3sXmk4XPfs91AZf/t01qbMJvCrR8NHs jRyJkNIaMyDeWcFmO0KmMi374BQpFyIDQ6mK1y9BilneZ6gHDdfHMsKniLFW+SQf 9hlwlArIPYuELu7riJhNcuRUTJEfybDHwM4/ht0IFbyUIFl00mMdTrozk+e/esEs QdWbx2UBjNs8meZPivFbT2HpQF1I0qZhtn3e7jcR5YatBQ3e4abnu1RrDc73q7d4 g2SYQK3PmIWwxiFhJQTzeiQtl5rKzEn76knAydOtPVRgjXWzHUoW6Az0qwIVAMvw thRrEZxNdxELdnwW3rpYBm6B -----END DSA PRIVATE KEY----- bouncycastle-1.49.orig/test/src/org/bouncycastle/openssl/test/data/dsa/openssl_dsa_des3_cbc.pem0000644000175000017500000000236010556327511032353 0ustar ebourgebourg-----BEGIN DSA PRIVATE KEY----- Proc-Type: 4,ENCRYPTED DEK-Info: DES-EDE3-CBC,9BF24F7ACA100D50 71AQTQlq7BkcUMR0+Ghc8O2ykT347aaFUD9BYHXBW7SzEq4th3itEQQ4QxflbgR0 2XZQE+dNK+s891XnEkf+8ZIIQc4LKr4m3P1t8UeAQvMbHRfAQ1u2/fMf5xwYMqsW BscjoQ0lFOcb69nb24E4taRu+MRDF2+eah2hlbHGbsTezIm1VzFRX2C4mnWyfffX 2WyJQPlZpvOY4kkv8tRvW+nbZ0P7bRjjxrSbCeUVI8X3m0fiCJ0fMVg1MMaj8JxD AgIKBBIJV8SYRw3NqiGk/mIlMq4Qtl8PWEFBRf30DRD8RIqOO0yV9Czu/u1hcmxN x1/ZExbwOFAFwE/GU+NMegFRXC4toNIU2Xo1C84URpAvVAwwe6SiqWFTSTEHnRu2 N/tfJlaL2yFrfRnp6mcNN3T8Rk376skXk1zml8Deh6rNU254yK2CFRgm+79W+CeR Gb1wxDw0GQ07Zr6/hNBfpAND4qEdyxYAfJQYOCufXiFFxWp+99TGKN4T/+Ab5D2j zKmpYFPJj2vuULLPGIJPnCVNjM5v2KwbFY/95Jh3JEF255TORfj2P6HETcjZr0pD TCk13jxgKs3mq98Vr5LGEJ4nUcm4GoZayIbeaM7heJTWmvQyP6PRZIDWi5mHs7K2 wGUrutGZcxzLtaQkavQPf79xt+0CI9D8Nuz4FrKMS2ng+rWLzT3be46f6hJaX1KP cy8RLQfaWpFGBPHr8UKhicOpdbGjxxfBUM7Jlg2o1hQIWmSuj53SygZ/EQnqBV7E GG+Gf3RDl1Ab9ncOr2WAA5TOQ/yVBEYXy2W3TDmxuwf/fWvwF2z4DLq/J7pieEM1 b1IuOlcDWNu6eKAhsrq0t6I/wYNB/7qOmIcMxn1dzDHjic3uO65IMH2swXmk7tuZ ExdHGutPDZKYG3TgMyMYk3W9YeoEZAjF3TodOYNpmtaDmftjIuxlaYzmtkQCFHGh cRlnPXJwaExSYrySX+1zsuqU2QaLB0AyTlAgkUdiLQOzfmHtiHt4Pgyv/o1z/PgJ VTVyu2IFh75H6CnSQGgNHIH6QGN3mcMIZQ5G0U2r46X+7+nnodOky09H2Gq71nQf vSk1M2ZoaOuo437zG8SlEuPKimz/d+PH -----END DSA PRIVATE KEY----- bouncycastle-1.49.orig/test/src/org/bouncycastle/openssl/test/data/dsa/openssl_dsa_rc2_128_ecb.pem0000644000175000017500000000235310556327511032601 0ustar ebourgebourg-----BEGIN DSA PRIVATE KEY----- Proc-Type: 4,ENCRYPTED DEK-Info: RC2-ECB,4C5CF049EFF2E116 M9XRNeRQW2K6U0bfpl3axdvsuTmsiFLkZ4C/76MLePY0HxePs3icSW82+t6awIpG gHfei8zevNlF331hGPW81XZAl8OaXWi+iGhIfKAInLKY//DBVI5dMTQUKTwBa87k oby7hLD+V4lVKr9o/tf2A43QjEkScVlxcofEnWUG84LkgXalsloaIAt7iu4qUMTA C1gTbkwex6bId97wvPQLvhFiOyrpsi5Nm98vEeJwMdb6dMNfLAd3Stjvhh5dGGaR BsRwDqgrkycYj6pOT0Zvg9fBxwLYeMk7PPo0bTEdY4itvpHXaRHcogsBJ62qnsFM mxk1opz6U0W9xKSNTCwLzg9xinRPXGDP5jz0zqE1nlQ1lrsPcsY+omKdaL/SGYlN vxDbm725eOoi1H0jsTGJsgcKJ7sKd6LTUEIAEsUvRAN+ro2zLhxteDP+gpCxTNRr ElOLddlDm6TB55lBkZVrH/0k/QQQ+L0lBi5Kgg/hE6oanMRGeKQvxhxRuBbK6tZB e0b0lffgZR0m49i3A+fTxa68lb6Lexggp6LAkheh6qOVAzSDWbk00fJ9SWNWO4oC 9FNqu1yafLt3Xiyqv7iD1EOyGhYF8NDvbMpu+gM7qwbTPMjgXf9N9g+AxSbvrmHR 5zGtJd+8BtU+139ZlsEv+cux1yxkYEypKm5MHfaa783b2zKuyOTMgOStvSOUgGhz c9dlWYPkgdgRkAMHzfIigHr9rQssde7pR7ZMlw75PxI7BI2ZF1Vj4weIkwH0SKFE fui/C67Uf78OHx4cVPANDk6cf4Ow8buH/vWjEX0p/jpOfNT9ZA6Otj0CyIQ56MjU L4nwFU7GqCbVkJtsHLI4sZmP4kH/3zuqVtwRTzQbQAWeTi6RCSwa8/amAStTPcX2 WPRezgAtNzS1MBhileGuTP+opGdGOOp4AeCCJdFBzkEacRXylxdY7PUsCZI7mRSZ 7AL1n9jbUbbgnl6zmqn7fybigjaTpLNSkVPOvVBxnNXxOW4n2HD4vA+q3a4d212X fWI+/y7mbYLLRs1LPPgjSLfPQ7Ye1Cj4KWy45Z9YBUtjdsEbaaHNp8TidgJKJuMJ +sDQ3lvtJdIZZy26tzLf3ryE/+2KMTwG -----END DSA PRIVATE KEY----- bouncycastle-1.49.orig/test/src/org/bouncycastle/openssl/test/data/dsa/openssl_dsa_des1_cbc.pem0000644000175000017500000000235310556327511032353 0ustar ebourgebourg-----BEGIN DSA PRIVATE KEY----- Proc-Type: 4,ENCRYPTED DEK-Info: DES-CBC,7D7F5AED62DF7398 PvrGaVyP4qWxH3LR5bOjrjTZN9KEZ7eujPyBYWV8pE7+kBc01RKaHuOfntMncXPj cTvtvPq4z/Odrme5s5fem88QAoxB2BqM0VNviUMcCcAG+hgsYjYWjUDdSY+piAD5 dhPcTHfSwgkA16c9pd+vNojdDKHEXzIci/gdrkJQXi9z+Orfb++NluGFUjAvQNlh n+wi72AVwFaSPfguwAtWAZNmL37dZO8VzuCTkhciHaJSZFtS1G5rLBIo4JzW6AZI PLEENN8fE9C60WYkfQB0PI27ksTS2xPF2b7MeaBwdPRU++hwZ2QwXH7nYlCWn522 8wg3/QWuFIMdqtKaOjjlwvQxApV7OouRCxIFnolM8HvpZ7HvEVVT6oqcsJG339FJ Ru60QxuVsnz6ykuP2OoGTtGZNYo5cgBSpXrpUSmOp8HHblWa6+FSatNkBf5MxJvv pMRxcYJ7ftFCGgpKI38GgeBPkpv9Rr8PUplZlgnXkZl8trhjb0hzAAJrMqPkMQ2m rOgsIWF+gK6MdnZdSnY1DktPYSFCkfJt0BZMGBDXcbr8RKHeV1vJNWAPOcmTsV/y nwzv9EA1KHeMnT+wQ54q7jkRtDLIS+zSWt3qW0fJQzNR3BrMBrsij6GfRZ++PL3v 4y9D+cDFVX6LMXUDLK8kxZ11A5rSuL4HROtNnIQf/MItKNK4Y5c4PAKAMGLQpPS+ 5dgmKiu6jAIKUVT4BOEjMJ0P03JZKQkPxVB9GgLQLGCq77vz6NaTWhJmz+qTdZoL JCvAAShdkVa5gl4hzuvKnmY9VftsPVlOUthuO4NYimnjZs6p0sXZKnxQ4J4BpbkX mX5Fs6RU0YTQphu2v+NFhcPpYwRiwn15CVUDW61Sb87HZ5xAzwQrlpFY0LI4TqE9 6ITUYzgpVVAlslKHNePMcjTj78V2MImHlq7xHSVPEGkkPlsDWxG0snZRkmM9aAu2 g8kqf8MVngWbWhxqXHA35wunnaBhpBxAgqE4r2yAhyfCJNF3B01zwjt4LeTnduj7 1ZA6EPechsSQUGQNGBoSbO5zVbIQaRZvAl2MwPU1YWCCbjaiDDRp9bHhX8vQbI/v 4TRfKX8FUSai83qORQ+Ncshg+gYkeCJc -----END DSA PRIVATE KEY----- bouncycastle-1.49.orig/test/src/org/bouncycastle/openssl/test/data/dsa/openssl_dsa_aes192_ecb.pem0000644000175000017500000000241310556327511032522 0ustar ebourgebourg-----BEGIN DSA PRIVATE KEY----- Proc-Type: 4,ENCRYPTED DEK-Info: AES-192-ECB,C625A2E97BCB192B31A8E33CB0CD857C jM0PVjU2r063OACSZgLkaS9ppOj4idZ9hgkdMi58Oi+C5bfhZavbjROyxCG0EMGz HnAIRJ4pkJeZTnGElmOEFbaNPb42NAvcrYXAP4XNu5FbZ2SqGKwRnjjN8z7s8+Ip MrCyJsWycYy2BNaksJRaDNgazjKgqQxGFlQPJ+j99E4dk5QaduOCrf6YQ2G+1Q+m 2/uqVujTwmverPnHDNhQI0ZYMY+l8+oVcPHIY3TR3ufecvrGkjFgKH0B+/L7gWSd ASvldEnWuFtPMiYnqCPtLgJNKSXO2nlumLc4Gz2ruvYKI1qGPXsVLIGnxISVLUzT VQz7NrRYwlvSLWdQNqbrEPvEu4q1KstqIkiPRoC98vG4+VRkf9AXAGqxA+vKYktP 2Ui/SLhoC/seh9pxYXLsmqP+8bxcNM3VsJQoUUFM2PtfyvzBtuQ7mJQTSFSXgBym qXvzx749S4xOot+H6r/bCh8753MMEsgsM39jBsRm1zbaBjaNFG0UBdfFigHWh1zx 4I44pIHu1AQDexjnfaUVrZFbys0CtM/Wy/3y0I3+mar1Wg3Rc1XL1PJzwDqBoZst vg1h0L5OPV1c4CekFnAEx+VI6ImxENoYtZCpbpt90kz3GxRY/eS8roS/SRJ7KizC p9bWEsUMwJ4Jl+xvV/VtVG96nKzlU13gkI6lMATYzImK4Fh7hH/LBy/UhNVL8X76 3fo64CCwE3YkrWEmBDdxt/K8Knj4MUPjBgy/ETVRC7ziG0rUwRSd7zLOoEALMHig AtNX+juPvPU7yARw317Q9lZXeytf1AmGiFGjYZR/mduAa9M415uWm6zutIJEz+q8 KV93bm18JUaQSrX4D6m8IgNhX0EfmRYAIFnB3rv+1rsb61q+4USk0L/1vKT/fGGm yvXMCA10N50wGS4wovMYQIl/giMEU8e88f+gqImU1kporgESIOUYUm9tOZ80w4R6 ITlKCzRuoptMQBGZeJIWfWNLxwYq7NXKpvjNeSOeOqQ4fxhkzEetFERG/2hnszmM pqwoZBZQ8bb+T6cmJD1GuxoO3ev258WIUkEZTkFYK2Q/+QKymPZO4ATSAO4N2UqQ 4TXRqUs4i+1f/BJU0ahnSgmzrynGmskUonKxt6T87lE= -----END DSA PRIVATE KEY----- bouncycastle-1.49.orig/test/src/org/bouncycastle/openssl/test/data/dsa/openssl_dsa_aes256_ofb.pem0000644000175000017500000000236710556327511032550 0ustar ebourgebourg-----BEGIN DSA PRIVATE KEY----- Proc-Type: 4,ENCRYPTED DEK-Info: AES-256-OFB,A2D4D65382905DF6EEE7A315B10CF2D9 CpLeywQMv8uZGrgJYM8rZ01awWHJWH/ZKkNi1rpQhaI1BAShQbIUvpY1IsMLa0/E g2+oj+Aa1UE4UDsAlzcfsKG9QHS8nOYWuLpU7VAyjC6wUPn0yI0sxxKRd4dmPIgW w3r0xO187yqLAjIZCj4y+3ANCjw+rLpZ5Zq8KAN4j6H1NEmzNoNVQbwY0hpsyxwE Tg7TkI5IyNKQSQC48EuZh16cJR48l36gzFOmZKr47gzS0zivvED4Vxdaey+WZkoF 1XW4VbQGHRnLEn/I8rziic9E5pvvcZt6K2NwvzXrkS53ufFYZcgxNRxrdM4yLz+r 20Unn2F2KqumB1RAliKo/PtudO7XfsPNc7rbF/stGhlxDWTyPU2HMX9tw3JkWDfG rRsG4RJOQgsx0Q73/7XPhgu1J2Wp39a/QI/IHwZ+rWIerdUPhs/MRRPoduAfSSZo r2z8OPJAlMWLwAjmmKDGhpTp/21n9xLo8tbvqmy8Frz+kAxAHXeHCTWUbxA+URKb s5NKQALX3wYHT9Xq0A27A/Zrqs5elqc/IQL58nU/Da3a3OfPB4+MNWeWU781ohhi VkBgMRbnQNCC8OPoeMd/At9GDEEj1rDxx49pJdMMwxXS04P43LiuNSmndCei2cQh /7cho8YTbdgjKF2kVCZvYXBVsu7Nn834kJw7eMH6slU+VM45jTkOTr2uLzKWrBL6 YONiK2xdD9NlDcTsX4YRkt+dByJEcDAuvprVdnLKpFXAOWDLW6e0o0siuFIGBtgX NR5vA5llpOkladJk+j+dxX4u5Ql9KFPtD9uM05ik5VQCZN8pxy6On3GUeSdoAE9i i+rtgZofs39mZOTxhYr+Djnq3WiWntV91GImwhqiXxUBI/fs91+yy+FWphpGORaT +Rab+cyvauBsdTAoSjjd5cNXXsztfDxEhLnZ1yWMQZxVgV7tcLevVo7e75pSZrN0 /gMQAH1Fcxtbrdzg1fehLiqTEWp14lFyDCkqAqQ5C9niCqwyf8+6Axaukk4ImmP5 n9eIykRezLizjA+GCe2oC1jXpVEEYVzOJpbBAwZqk/jlyNd0m01URxvhOaW1/M41 uWDeQp7ljJrtiyMqD5P3STGR -----END DSA PRIVATE KEY----- bouncycastle-1.49.orig/test/src/org/bouncycastle/openssl/test/data/dsa/openssl_dsa_des3_ofb.pem0000644000175000017500000000235010556327511032371 0ustar ebourgebourg-----BEGIN DSA PRIVATE KEY----- Proc-Type: 4,ENCRYPTED DEK-Info: DES-EDE3-OFB,BB994897E99A8F6F Gx0S/6H98EIJK9lM7TBQrFejxjBVE0kcbBTVNTCJCuJ1Ik0s6+OqG1OFOLdXJWva M+k0WEWKhTAXtrrbzPiu01u+OVpIQ3xhgzt0rcU8UigfLLvMdqXoyuUTzCYHBraA ByJ0+Z9nK5r/OAJkq4gnRfhsDajZgOy8rZAdyIui9rom5emcx1GsnpW8WdRCuu5l kHEyaG5nHtUyZobZk1kNbkqelByCAFndV/eook4kycEytZWNPpFP+tUaXma92vDV sg3h2qODMr9ElrbvKYujOuFoO77BYM4oxlE/WtWpD29hmxaIgmnlvwUI7HerpZg8 DbKYV/8ncRolxoE1GqO2dM2nLKaNKra+n5REJBpUDjwe/eV6dwcj5Uvk9nocEt55 3qtmPbevuXga9mL5iTN8dm5RgrkzCX4LBu5fB3WviuseUBAqpKgq73RCutNM2gDm 5CkV7Iar6tV+LgiUcgoo8RAnJbysFT6jQkGPYhABFKzdzrFFDDQUBpcLo6hgHpyb uQqjVXR69JFxdQpJSuc6cH60jzRQOvgwpCzpRiJL0mgXNXv51K87ucEzM81Z0UpG O4GYnsbo7PQfeLAE1PjP2B3xj8kgcRxWbHkQ/vIHTEAtJcXmAquULi+mNKAFb578 qlBs77sLICgtpqBUzfoiH1ozcKHOJ3XB3yPYt7WKIxn3/rwqrgRDrPbyrrDmV+FC veepr8m8ZssbZjKy3z1js+jcvjKJOY6U/7Uc7IfZ6AjBXrkJIDEtn9RPoexG+av/ P/LDsCF0ChhP44KZi5q5TLNvAmbvNL/7oogaSq9nw5hJYLiu2gScOAAv1h/j9yhE f2mz/xTHjr35m3Ax6wLPk2yS53PATS7XXQtWY8E0LJz7gOkSDvolwnyc5aRgS9WF H8DyqWi8vYzVLNd1qM1mAR55qrVhWnmlDmw+f2OJmP+6MNAoptW9nsUaeOk5xJVy QNSwJCjzp6ujIn5UhmrS2u59HW3hiW0J/O7aalBXYQxUv/qllKkrNmX8HlB/1r2C IniTw/Rd33TsNTBx8tqq9IpnAG4s51xHBeXT0+Sd4zNh+fIqAYLNuMllHMlM/oFu A7+h4TYAxEccchEha3GD6CMl -----END DSA PRIVATE KEY----- bouncycastle-1.49.orig/test/src/org/bouncycastle/openssl/test/data/dsa/openssl_dsa_blowfish_ecb.pem0000644000175000017500000000235210556327511033335 0ustar ebourgebourg-----BEGIN DSA PRIVATE KEY----- Proc-Type: 4,ENCRYPTED DEK-Info: BF-ECB,6105920EB281329C ungL+71R1VG+DP1CKuROEP1pESqlLeGoX/vupWbGTWR9VoK4v/9e1Bh96r+hEobm LvgsV1xhWrnyRMMw+W5bSJCfBH627SxqHltgxPhyKCNAf76cTIAdxxXgLZAxjtJi mjuBDTNHdJ8NiAxJKLL6dr/hh+Vt1Lk9Gr/x7UdocQnhxG+IZLDSOFdXnFb8EBtK kmAXXyOL14Rerywi6pmbxaculi/CihuFm4u6GXvunFjtP33eObzKLRub5ktbCtol 97rbDoAAUsPPm4efu6Fs/3CE/BfvjUf+cmOYu6pIKQil9VHtxXloXwkeykI9Kl92 uZVT+e9WEn6oZslAzCnjT/r69+V0Bf06AP0zkdTK7lRNBhmcR9fAgHpxz52GC2Bt xsqEzU7d+adCy1M73tT+bA2RBUnbA6BoCDHkvtmZTGV4mkAv11tVxU9Zqeglvi/w 6QVDQYo/b9U8GVkQFo0oh4xNaAUNdT/i1OIy7d+6UR8k1S9+r6SGVwS3er20trWN 8mAJ3dWiy3yLreggSqEvwHSpwrUQP8uxdTZOlFAy+xmwuEb3AgT4/sHQN7sJjAN9 ISdzp+B5tBbM3kQgvEXUZckVykM7jgyv7SJ9DoDaYXvlfOVFo1oM3aWf57DcB8KH WIV94r4USVElJERYHH9sR61YtTi2lIi1zuAQZKCf3ShJcgU+vh2ZZ3vRPQhAMXjZ 0Doi5uxi7HK/MVenO1CzNmsc6XQtyTtONqlJVmBoSq3Il8phMkMXnaOeNrQsT/1X PzbQ6MpWEr2WkKsQn5hNA9b8BIZ+cwk9zeFbhwLH5ewjO25BWJkFra4gGFJl+HZf vMNFjlnxuMjqM+Fjn3YH/O08P3nF/3ZGezqTCV8OJigB4Cdfbf9OrNtJSvCVsH1q YB/3+KOO5mKObH0Y+k1pvwZsXMkj7exAEHh+nFLldjo7tBAycqUHK0RaZ29TOjqH J6/4SSzMTJL5PF9Ayjtx0Vai4sFrjRGgnvdd8tddA/bWq6JC5i0yWIWjCEu0+b1q q8EHdE39+gbANJn2lKsEAOOt242bsjKR+bblijaaEgZXHZyALOThcEXxn1RaFFgC 4Iv+DftZrU8lOiEvN8w00K6GDy9gbByG -----END DSA PRIVATE KEY----- bouncycastle-1.49.orig/test/src/org/bouncycastle/openssl/test/data/dsa/openssl_dsa_des2_cfb.pem0000644000175000017500000000234710556327511032362 0ustar ebourgebourg-----BEGIN DSA PRIVATE KEY----- Proc-Type: 4,ENCRYPTED DEK-Info: DES-EDE-CFB,AC1BA482ADC9EB3E tPu6t71kZlKyKaRiXgAMCmyxL/P6dVH/sPVY3KDFI0FsAGoPZaD8s7BkLLOy30Y1 66kmaaWiaPjQN2g5zMrszrXh4AXazrjMrmIJ2NksNXz7aiySFafyYjyCPA+LIu/n KnfoE42KYEmENgMSUV9sh/nlwYS8I6LWva384BIWaG3qnFgfZ4gwgiI/R+1/lPXa olOpnI5szYMiV+som2E+I8lgd+Ahf2rempMnuwyWTDmUvYWwst7F5bz9XbmJyeWY HDDaTPy2Q1yRYBRvLTm64iA0J9j1TpJnSNm0uIRTVOEIZfOwOx20tFjo7RREunAx mEm+kmn4AIYhw5RQE5XQQvD42X4MLyc0M94k5pQHvgJFypXeJ4VsH8pkd4bqfy91 qiPiKdA7nWnbedExwiwSPOhjOLkmQrXjsMVmoqqexhckJfmNOaXYtnQ8cZc50HjB 6ccsjyLdQbLx1KT3e/NgfH4VxW4/hbbt3p0HMIxTnwt2lNG3AoKmLlOYSecuA4PB EE6oOauIKyJM8pwMV0hfBQ/MUQOnhHG+dbTn0kW91fRZiVPPvJiJ4NmEwD3ks3jM pLYZRot1Cd2ksJ79G4NXDFakB2bZ8EwtlQUrQHwW/ykPwiwpqCCha1PUzgsmG3hK U8bDWWQMqXtpSmItno1mF0H2TZzdbLpRAZe2lu8/mwww1qZfPE+MLPnCp050+BCw Hbq8fF1WVpJvsE5CKzi7Ll7bSrJ6BslrlzL4mFnnGmuz/mbBIL0MO24FNyVGKQlI hEzGu8lgp53pG4oSUZ+79CWBkn8mesk6iEOWcFojLKrlhnxZ7mDxBYfDp/2Bmna4 lFt53zmQHJeYiO4J2TEXOQxvDWvcOK/SnAoLXEhUCRP9vTQm2Ahj1QMmEVvEybOd mRpcaJXUOgirS7Ulwc6ZhW7MoFFnS3UluI+gS0oXRW6hCm6l9poDem4etU+IsG2m 4k6MoMLrak9lSheB1uL+xC0S9k20CZH0X8Hj5atb4R7T5+lTle/fVw1RGdfil1NK /ytD+CLpSV15Z6VGVGlzfXTIXYgCIgbZpFxOZk2tsdUm0dPBjR/ZhdUh4ofaxA8K jE8HLuW7kCkvmEfdsJxuRVVQ -----END DSA PRIVATE KEY----- bouncycastle-1.49.orig/test/src/org/bouncycastle/openssl/test/data/dsa/openssl_dsa_aes256_cbc.pem0000644000175000017500000000241310556327511032521 0ustar ebourgebourg-----BEGIN DSA PRIVATE KEY----- Proc-Type: 4,ENCRYPTED DEK-Info: AES-256-CBC,307CEE18F79CA333A38CA90E75B248C5 qyg9Q1cX/FGOoP0NFzrCRLwmR6bai7JzDiCLFCthciYkMIWLIVzvyTg850YD3dw3 Wusli8EQJig8DEpFSM0WBc1Rne8U4168nKuRnFUaP+VWuD4UpNDt66cT6dMoqATD kZGdd+p8ReO9TK9gO/ZZU4R+q3OUpjxX44szxj/EIVSgphi8R0rRSxl/yFRnGHyO xfpM9NxgMvBYlyxl5w1Lp/ictuF3D505nF/uuhzGL5a+WWhSnssMFHF9vxXTu21/ 3Cy0C3Qah9eV/C2oyAU7GGsXHIfqFqsgMjQN+cTFqMyFeg6g0J7hytDAgZVBXIFw UuzMbxUUZU9VHcZzwqstkg5BmUI3sgW6gibBUzuJrmo7uLrCvHyj9oehSMqeuPUC EXFqhw6Nb+jZMkvW9J9qFYG9eg3PQsDErIdVK8aWdLrLyc+O4gycOdMbR8aq/3Z4 TlV7Ye650EvQ13bwZghZyKel6Rjt4P1MagGriNqCcLVVsyrRXAiqjq8cyJgYtoXF 1VMBZz8ob2FH9+kvk2sb4+T22sTYwiqAVaLnCsuJ4dmS5wdBrhfF4oyHYV2KOVgG 64GqxiF9/whvbAWSM4cU+KslKnWGZwz53LKleafrgeFJ2P1ldqnl0on5EQ/m9bzt +GSGwzZGRmhf5NoyhaH+OCkq/h1UP+LZ5kDJCqH/l1JZbvJQkGNKzt1OroW17GnQ EgihXAmhy/xOAIZkz1XKa3bNvgS1F9yreAxJAvBHB0QzZ1HrablsaTKsZOtY1Qvq e2OdpJFm+SrI7RUtbp787Yl9pH2cLEdto+WH8gtgXloS+b11Q7broE42w9MIJrno kzs6eDWafSExTvpi+29OJEtK4PNezmhOxzTUIsG0/8d9Vd2WYqrLD34ze68X8qUa CoIXYP8VsQLoXVzX7VnMBYTQ+YOR0Ntq6pRj07RbJrNiOt8qcWGslzE17ERuCr0+ ZFTGy77KOksKjLksvRj4oshQjRhVYZscPNnwKODFDvOPsGFjDoU2Sg+W8kcfE6Bc 1RQwk4N0cjkC2JXXk61QQjh+efWRBqPN6va+ixUcsZSxndCIoBk4qtqtsyTFEcC7 LdfCC96RGnXlvroiPHvrmJYN69JAyyRrnhiYfaaC98s= -----END DSA PRIVATE KEY----- bouncycastle-1.49.orig/test/src/org/bouncycastle/openssl/test/data/dsa/openssl_dsa_blowfish_cbc.pem0000644000175000017500000000235210556327511033333 0ustar ebourgebourg-----BEGIN DSA PRIVATE KEY----- Proc-Type: 4,ENCRYPTED DEK-Info: BF-CBC,B23E9DCDF6361CCB BTPCHNUVRgsKo1up9Ktshx00vDANb05S4S0LPU/wzG8sj60db3bX7Uzr0PPy7ShH 1zPv0PECYla1dh9nVBPOS4EQE3uHyzuDMTg0AsiR8TpysuI+a4y8XJeAhkU1DTD6 YzmaodjbCrhautYUCzvcui/sWWXTUSWH/yrFOxaaxLpccacCssGlPc3Tmr5brPmO xaZvO32ii6z7WAP/WmyRoYH+BSqmUBhObolifBD5kg1ilPfCk3xMtz4lbJRWANsS r6YWPwo+qh1TIQWw40Kz4oQOteVNiwh/dvYGxMkd9Gs4J9nY5deKYExoWlYcci6N VOrGA6HBWzfFx/QWWGK77xE8yQ8HeeZUgkWwYoSyAmxjPWgCj+BT5gbYV3W9E6UR T3lsKGtI/lMW9N0DVcLdur0lLIBFiVbzxoUAL1SteLJ0mbu/Vnk4VhI5z5mOmSxo bU/HElXdjIhk7hdTU5PMNSKiAsxNh03NiPsTpEASMhz+oP8BuJZh6Zi/K3qMYH3u 6BYmA+Ua23fFYd/kz2TclVwiQ1HQjO3+9l0aSgLhHFb3t0spYbx1Ld5+bAb8b30Q 9w/fNab1mB6hFgaqruPErfI0K8BZ845oAiakZBfKnTRQxAlKNY5gWvSiPDWlkfIb uSBW6csh62iQM1/bcW0voR21NGS+WdQ3eg16vv0HMhmEXmEvtAuCGb6ZMqY117s/ VciBymZzwdLKFjCqrLn6enYrT7uneOoq/8PaXD1rdMuKGL4W2LqGH+Q0RU+1hyBJ 7ipTQqystqi6HUU2R1/PI4K73X0MMTB0Jfkd81S6GmjkMYCFCHmHXCdNULjbjzT4 gppgVW5joIbLKNPHJ78lw4BuMxcAgptmtQBADnWZQNF/pBnIVAY/pdHgreIBTQ7R KL1/ATp3+gtGd37FOGZilhq8C4ML+w18M0iTUUfGg5svUvmtw+NpNWMijTJpu3Uo KqjMj3NbwCwu2b9qxwalC3qWOgAJf4Z784+i2GOvACk2Mw2QyXoZV8Qm520M+idR rj6DIfzEf/86TWH9IrGukDbJNB74QHgdXd9upyt4sL6uHMxPwz4nnhBB7I8B/Q59 oB+3CBpYIANihDscUbiNSsw5/AXNtMuA -----END DSA PRIVATE KEY----- bouncycastle-1.49.orig/test/src/org/bouncycastle/openssl/test/data/dsa/openssl_dsa_rc2_64_cbc.pem0000644000175000017500000000235610556327511032521 0ustar ebourgebourg-----BEGIN DSA PRIVATE KEY----- Proc-Type: 4,ENCRYPTED DEK-Info: RC2-64-CBC,6646FC6A291EFE41 KWLSTeo6nX30rQ3WbgL/13WAEMCtaC32ksYorVhlN4ijjiDu5gEnmfLRNYK4c3LH IUJawIdZvHSVxjrKNjmKA18w+4kedYCCL9NbNswd5eO18wldFR5NlSI2FGggzANN OwJoHUOXggYxhc2/xbYHpQpl7gvJqZtAjyewyTDYeTC3VDFoB/JywQ/8vv1MN8Ce Zx1k6preAQrnqo/LEIm+GPUa9flzWZlCGTIC+obNkjJGZPuUKLM/1TqNsrum33aa gFwnz//khQULylIRwxfuOMCHTslFmrs/7MLLbJQyTa99S9kc+s2VDlaKWUn0BVe/ MoCseykcuIcskavuj01SYySJU1YHBTu7RvhuYO8AQmnsAP3gWQUMvKy9aXmzsoC2 0Nk3QCZiG+1hN423So4NPOh42OWbqrDls9PKhXvQ8H+58rAxW2s7OTN29Klo39ek w8SFjMEtt9kLNpwBCJrIlolXvhD5WQu6XbqI0CtoOrh2Ote1c4uN88HyIUi1Y2Op QsfLkKyx7yJcJrz356Ab5lbJKVpKJW+frEHI7rLlfJrj88uzsh1B7oPL/4fhaj84 vNUfadRJ25ZivBiHHdUTrKk9CLsIDS/1DWM6sDclYjXiA7kgGNwJupOb2L6VEKPv eimiJ9ooKq00E96Dc8s23FteQqySNaUAcqDnAkS+ck6pXQECZs4uD79k4pck1SX4 O20OIPo79pzcWrmYOrTIXH6ttOcB3lUQtB1fmcMT5RSJYVSKtgBxLPKhLcL18xfb 1HbDkpdUqS0R/nK7ecMd/LP+UmMKPUyMUTfTUnlXZzsNsgIBkm1eDn9RkOGaV+oc wau6FWmxVSPs9Inb+7A+B/2bP0qyYnciKX41I/PClKGitm52ScJyrEN0XJhQ0O+C mPp9weJI3IwpDn/Mc46NQO9uk4rC2P9o1zfJXC38PlEDEC66a1Y6SEQOVN6iYkYm rVytxWjD4o5vC+GwYJPYrmkOg/SQK1AlK8TSpNC5TeRcZ8YIbPLRfKRUQvUVtFS0 fyPK9zdariwubkiG1a9/NWCF9gN1/DPKFYy+p5Au2ICD0iTtOND9I/Yw8dqsjzsF 4jhYQ+No+ytLYc4Zo+8s1RO7yduFz7XQ -----END DSA PRIVATE KEY----- bouncycastle-1.49.orig/test/src/org/bouncycastle/openssl/test/data/dsa/openssl_dsa_aes256_ecb.pem0000644000175000017500000000241310556327511032523 0ustar ebourgebourg-----BEGIN DSA PRIVATE KEY----- Proc-Type: 4,ENCRYPTED DEK-Info: AES-256-ECB,267E98B92F05ECECABF28790E81DCFA0 MkVFB5/gKxAksBI/g96MmN+ujdt0XFXC+7MI+0/OJ/H0LXlHlLpwfGlx/Je73Imt rOZveXf4I8sBCF1Z0Fhzb3TTTDxcastJGKWAVKaPzKkWdxNeUjx0kinbrkM7Spfa yG+wW+Srtfyi6LzEsbCduDK7hzfDnLbgKymdDeP0TVeJzEdXgXcV09a01GA+CEVX aHesQLNHyYm9nxFxK0fAnKo5r1I2JsozSWNTG3VNbiItxtfoJdXTn25I16qXjKzn MOn/A+RBpO+P01j4uk0q0SPJMlIYIX+RjgAoPiI5R5vSeucsdUJo1sWnSfqLc4yP vUG5wD/+lYrxsXiW61KdwIg3vy/ty5+GqwNgNvN0FZM8DvK+NQ9K/IpoW5RE4ioS ZNm1JpeGJiywsBf3Pi9mwR44tTVY0Jwa/TTQp1kEYGjhYXMIEvf+LUHwG5KO2wmD kDediMDUPaUx9K34eSpgIUln5d+1viMpC2VcDIg4tYjAODtGRxzgDUr3mbuoVl8f GqusTAdsNoIyilY44XxA2odHa4S8yXsx1f54P8fRYbA4Xo179LY1Nh7PwQPm+rI2 mERkCsvns9jP1zJRuS1lYW1Dqjtxxq8Nt5RAsEwKQYLO4DfsuMZPblEXPAwSGb/N 69xNs8ZFHm3KT1r7FdUrVpHk2vmqsetNa/g2wRTEuBmRCgrtTtEDWgdBNtDoHlBR pDIWgwNvt7oJIU0EbQkUgW8bmg1p7jxXN8Bk2QKZoOytxA4TB3fR1p92VkXzrkxn l+Z815BNfqnNCU5nNzLwk3jLgksZrDnLu4sXykIBC/bpP5fubnT7iJYh9h6ZGFeY QLUP//ssuZM2auNjTVykWUtAiglROzxnFZjMXEbujOKbm70Uj3YvAHjoKalkti9x MTj/vpR0xBv/iDtTFl12HIg+IEGL1PfX4xy2avvJO+XGFD4zcnrLfTMwtUJQjdQH dUMWP8VI266u+B6wGfcrhdCYqtvuLVUvbISU3YD/tP+esXh563kPnXd2UuaS3ErE /7Y/hzyUkDjJ2g37Hq3M4wbaEg/a6osDtfg73thDMadsbTLIDjHKgAgBv4umNtA8 +EaP0stzRH3ayHL/f4I5bHC8bMIAumKM6zap6tBiork= -----END DSA PRIVATE KEY----- bouncycastle-1.49.orig/test/src/org/bouncycastle/openssl/test/data/dsa/openssl_dsa_des2_cbc.pem0000644000175000017500000000235710556327511032360 0ustar ebourgebourg-----BEGIN DSA PRIVATE KEY----- Proc-Type: 4,ENCRYPTED DEK-Info: DES-EDE-CBC,89A720DEE88FA71E ozUacsBZx7E1NCxbVYJJHQ0VTWl8RX0z/JzYNP58zcCIi3Cab2qlUshZP+Zb0Na9 vlHabEqQCGsP8uLzneN6LDDaLmf+ucxKvCRrx5h8wl7DQcA5cAQhGofZuqChPqLj 1lExS4ZaAi9lRL6aZhf6rgI/apkj+9Ky89sOqJxNhj66NgoOOh9XH1Uvrffv3jT9 RxeVv5qYcAgfX4aIAM6KjC6iTZ8NyWmIoc8izYQycOsSAn6cqtdjmyc/264OZUd/ 1Tj5PG0q/Kinh9UBJ2F+pQgU4pDlWczXEIwtnmJ2mWyHBe2zuGWtP1uQFUIfwkEz KDTTFB0lm/00Xts+vGXgy2q+IvhqlOXfCkJGcP+OArLoyE8cu2xU4KS4qXUITSr0 i3seUuTrda4aqrfyjNuM0tL/cUSEuT7aSlKdqSmRtYl9fTsmbCbndLKKuDJnxUrB ocXfuCEZNMQ/q/8DvwIX3l7RRIiJwqEg5+Ue/s2FTFJh4Iar/1gNQSApwToFHHhV XOU0pLY899B+1z10Nop7ELgJEKBK5+zMMBhB2t6nlMU3YojAH5qWEPa6D2Wr0Wu7 x4DHqk0wEB6cDZ0PZGlWNOBP5bDB85GehAWKy73A73wYZCi9eCQnLh1Zjcjl+6T4 fli2K+944sUKaUnY8sVT/20aXm1CRqNvgLknZMsg/eGZWX5F9+Jn/MviXmsH3LfE 6VShEkNTFEsRUqF44Tvd2BZ6pObDPRDOkMgapzqdubujUesvb7LU3yNCRPBPngRT ZTXQynnbH0yfnFm6+0BYWtD5NeIzILwZfS6IRMSsCBMas5rCc7O2Iv0yhk/8K0f1 Og1YH7pctbz1oAPmN/EgKZ1K36GTt33zfrwHpmKZ0jOWF90BQMgZ9dL+VyOMJYjL MiyetxwDdiP5TUUAKxXdr9t3AvxVPxL8aVjLb86kJ9HD+IgWUDqiROe88sD30Vww 7R3sQhhl7drDGwUBj5MLCVhtE8Uli7HdaYC5CvuvlCAQN871whhk2gN27eqp81ou RB4kNaDK8qSn83ISnueg1jsQhUGy6B2Rx+rePxx3QwDsrMGf/u/tFJ1VcLlhmOJa svVKTMq88OAnZA1Hg6QlB03obSF9U6lJ -----END DSA PRIVATE KEY----- bouncycastle-1.49.orig/test/src/org/bouncycastle/openssl/test/data/dsa/openssl_dsa_blowfish_cfb.pem0000644000175000017500000000234210556327511033335 0ustar ebourgebourg-----BEGIN DSA PRIVATE KEY----- Proc-Type: 4,ENCRYPTED DEK-Info: BF-CFB,A39496D20CA5F694 A9ZO/WPm319cQ3hoxaEsmuGVDkMVhCuRzFfSWC4hVBsxKHd3FIw8xZpGSkEI7+aL cMtcyxTQn4jVV71Sw3vyb4N1+2i+DAd+63l8LztpTBQi1o2gTBqmqL9esV3shqWB JV7uyOi94olPea0Rf5PMRXx1bAZs9U0TV+5XHAQxM04lXRJajxiN9LBZ1OMRiUVu SdoHdXh077ylUQmgDaGQktWYuVH6leq7Yc9CF3nre6njFiUrpk61iPki7+/FgWzq vToqiYaWffy+1lB7sXcL88BtFaMWAOV5A48Mv05miTb00VbJqdKL+SDmu6j2Soxi Qk3k6Le0heXFHqqkURMKOrr6tepqKEjmy8WTELwMnuT5vNngMqDKpNyhdsIEJW69 +L0imi4fWIelCd7PMI1bbPAp2QsB8Rndjlfj3irVm0AtubL/rbep3JT0ezukoScd wLYNTlDdaLfEggry/1kYvPBMolU4xqDxg7C0quwYxLuycEFzU2QmWNtRn0xkfx+j ruApr4getT6q2fJznW7coiW+OE9Ik7JgtYUGEZuWFUeydDHa9PiJ34w9t/aw50Sk arATzKH66zM//g1zgzg31SmziKeE375skyQr2+1S9RajmdZzEUDL5ajsdrbALflf UPQNr0YEF92DRHsI4O39L/+k5fesiiU38u0NoKv5DDRb5T1lQeesDZCZBowQP5KP +6o6lnj8kCeccpGX/eUukPXFl6mdddAJ/vLptHC1zaRp2dlKPRfedZkRm4Wduplh vQ+6oGqkjep0Q/LSRcVP69m91CZot86lAn9Ct0jfJu8o7Ua7KBeOB2k/rx1nUaZG BOjHQRaSvPA7FVKCP1UlT0GR2hTb/VcW3UQJ7fCY8E4hc1kPfoa/T+mf0JrHtlMm 364YQh6KLgcsgVjsPBXnTN1+POH0Qy0xp/0VwQIQFWKwU7gsXprfs/uYx0uD2Ev1 w9kIWLovIGmBh6HKptqTnjtdwhqueez5kb3MkrCMi3kqVmV1TEQoklz6eBbloXbX SyR5jivLmuaoCJOA3oQ/A+75bwcvUP4iULZbdTpM2rnURyljKNU9Hwxim0neZ0Zv 4kiOZuhQKkGfj0gv5bRkDAZC -----END DSA PRIVATE KEY----- bouncycastle-1.49.orig/test/src/org/bouncycastle/openssl/test/data/dsa/openssl_dsa_blowfish_ofb.pem0000644000175000017500000000234210556327511033351 0ustar ebourgebourg-----BEGIN DSA PRIVATE KEY----- Proc-Type: 4,ENCRYPTED DEK-Info: BF-OFB,56A8F965C6533468 91TyUkVkBxdl1ZXkXezMngH3YsE2cuXhiEFySx+dWZqFWcOQ3S6izXXqvk9B5sZg O95SFlZ917dU+SFACzB8dqwYo0QmxvH0zaAIMBguuYib6YZVCd8/ElX0vyEEo68O 9V856HAks6w5WZk4zTC/75skb3tdLRWgG42oBlXHW7GsL6y29Dy3xvaWHJ3vpKXF HygbvR/TiSzhWj/jJB6V4kCQAAm99yyMxpmo3e4Wis5AwGgf9XyHJx0gUCeyNqez i6UJMGnYsHl1H67ltpN13trIXRcXTUDhFTadRz/suaR1R8IEefkpsnBEPnJwBuPY tUQzlolPKuwbPXFukpJrhi7It7dLsDsw5DUYvyOnHkDXJ4vFAIplCKdG0+KLaYKJ pXI8FH6X4M1YbIPTF+k1dhCAz7Cz+cEBA5hfJfSA4p7L6f9NBPWso3DDsyAbdPx9 JJkVPtu0ofZHzYuD9nIhRsXjK9zaQXU0szLBdtGw7rfmPp3ftXeBcXDnO2ZdXL+j PK6CJm0ktjnUMKY8gpWahUUfImwebQ8+uQYv+NNn61rtfCaGQWMStXaNYgq54YLs D5ImRdvWm936tNUCeoik0yhPVlriNC4gKswRSUxD/nNIetsPl4FB4DIS/W5fvWZf WYKwW1UlpC/HagbUVIuZcOrAMFTG+zLYS617lzZh7Y7K87GJH+jVwgbYSbHHFWCp V215NLfofwlV5pFwq8djbeEnBhKi9SbGlZUyaZKKyDoIIEnwaxg8BoModBEWHyWp OUmw/v81TQu6RwJYxl1C1U9n5w4yjtXr5oowgu6WRYXwWXZtevtLkHrhcuWt21ud Cq42ojFrb0GqIcYWDXF3Wjp4nLZ4pIqg5kadpJpcFYx+fcL++Jnxs9l8Ohqwn1br /UvY+gTmTwnICapIwovVjN6p6cT6MAok82oemWPZNPYXVwVkGewCH3DWqfeRYsdg 6gDWeIwyk2Eqn4bxFz40NrNZaLqcmQPaJVRReCV7Y0jQuQWqSYKkBHgFodf2GPMg DRqs7doN2MW7Is6qjyc8CDDzPcSuaqUz0gzohupDfD1vAtuoC0X6U+m/8NM3yuE5 CKE8rofcKcxmFAr52CUUsJBL -----END DSA PRIVATE KEY----- bouncycastle-1.49.orig/test/src/org/bouncycastle/openssl/test/data/dsa/openssl_dsa_aes192_cfb.pem0000644000175000017500000000236710556327511032533 0ustar ebourgebourg-----BEGIN DSA PRIVATE KEY----- Proc-Type: 4,ENCRYPTED DEK-Info: AES-192-CFB,3E445502677C77AC6ED115F8EFD9BBB7 fJXVVcgxhZJXZANfEWDbVmz75ocICvntATRNVgt92sHgl1B2c4cgQC4Xmu7WM/Bc ocUlcSpWnoHtWRDumw2cwB+fDb5k3e9qb+aL2juzHkK+kYd2mkRjW8KSG6D8HIwq fpvV6NQmVrxI5+n+uabwfil8Ecg9V7GD6ta0QSgt0lc8clp01se+VDacX1uCB7zG NtJsr1wUM0SQbEWPEcpLUoYfK0qSO0h8fpnagKrNQLfzFbk85arkpD9XBzxpNO2p 2fYsc3xZ0RkFauSZGt6ehu0jh1TZNPYDURvSn3uVrseLyR0Gt8LWp+hjIUp9Kpo2 fLUVaH/7wxpdCAYzo4Ub/gHPfbxo2E5qYmE1oTJyAHplaDqSg8pbwJofiXl12gMM IyIC3SCHZJph7xqbKa+W/X4ChxYuN23ZMZ72cmqH4tH/j9IpKrpWEeqjxaj0EwDs R06Sz/qAqs9iDMKTkuFTMxGhc09DV9sN4NYczEIEas7gploOdryJGMCM96RtMDS1 gjW21w0wyfqa7ogsDJJ2/HqKL73Zfn7l0jzmqya7YwcToEfKOSP+a2Q/y3Exr4KO FY5PLwKvpBaFcFzJoYhAaPphUzzAQuQFgXj34f4JU9bAXbf7ol7Swcv9JP9tN/mF n7z55BbPfC1EiyGyDjeUDWw4XIYF6LtRK3lnvn4uSZFXLmYMJJthwwC/yS+D65LW vsW9uuQ2qEfEC3hVbMPP+1KMgRkb9CVbSXBH+B7UoaUkGsJYzdSDeHZHbwiHgxqH jb6WcjtUjh7W2VO/MnHBrLg8dnC77OnR4IiqJq/6TenuSu0N/4mm73SH7BtYAugu ok/2H7GYfGfWjOnd+QvG/Vjsb+l9gtB6SXYFiWuThjB/sU4kHH8LUUOmGRlC3NDz w4pv+cR3tS1zX+evPL0BsZ3ynDSGRbMpss7xVooxIPacFwDN8kHUnWvIBpQKAizq blt1owc97vidf9OnZxUMpzw28/PZ+y/vRYSPQrde3kH8mJmu1FC6tLZnqzuCSsgR SJSr3/8qqSj3XrAW+nj0Y2P8lItNdFXex7j/RuX3eV5QIyK7uY+z8ZP4gf5q9w54 p+dQi7Vx8acRjbsU+r85+MRR -----END DSA PRIVATE KEY----- bouncycastle-1.49.orig/test/src/org/bouncycastle/openssl/test/data/dsa/openssl_dsa_aes128_cbc.pem0000644000175000017500000000241310556327511032517 0ustar ebourgebourg-----BEGIN DSA PRIVATE KEY----- Proc-Type: 4,ENCRYPTED DEK-Info: AES-128-CBC,3D7028A746BE6B09694E16A222C543CB RkTEJRJjGfaMfNc876Tx1hD92cblJRj7TvUafRKnH0J3Zv7l67MSG/6rY5HD91HP s9i9Se+H8Sjn/HaUl3QTZv04egloNlL3MPSkI5fusR6maZGPVLRJBLfVKYQZVDja 9YRe+ZhXMS8jTe/IhYMcTlQLBnnwmmgZC09Y9Wm39idu7lytOl3JBMgz0aUNA+P6 lN2MtaQyIBXHbaqfNDGFn/r7+MH4CGw6MtrPzGqRJgGMHhV6T5o/x0nEU+loQVOK mPkSZTxBbn7xUb4JvFPnLTbsI4Cnre3QmfmDwkCAklQXqAIT9Ex1Slq8qaCc6TEf mWJQCYPUkpQOqyinR8o1VbYm3DFFvE5F+CktJrppqkQvAct0dQNjMTBFxUjCkZum qGfAslGPBREmmnsExm5GThYqA5LN+qo2prBtvt6Eso0i2jNiXA8bi5OfDzDr24R5 /RKUdFPf7keaAjg9jSArwp6EfM3y3sj2riibwZlty2ckPJw3SwxIe6QSMwKRbKlh GJoi05/cO0NxQYhMmlwVN9v5+YpvWmT3CsFvCA+Zb5rXPx2AZpFv8YoHdQb0qyEs b5YuVoavL58+BWIPQpeYy/jttR5pEPpgM+C/6/1o4Cae4lwppP2OYFl1fsqyqbKh iadErB6QRaJCnfnhG6511CxY+vZtQE5EM36blOl/op+6G+36ApuqDtfA0C074daV uHfcqA/g5dODEJP+ps6yoWtM5lbd5bZZVidWhrU6Skbt0faF9w5ECF0qkYDGqF85 qqFcaoimq+NP7EtUEFSneOee72zYALXyzjoEU9InktzDi0Oufojzc1gjhh7LbObw UBANPHTsbaL6FPTEs4a3JYSyat9m/R5GAaT0EBynHxvdQRGNhtEWFPkpGYUrAz9W 0A9mNX1as8Jsxkh9wqjgOR6Xpbqh0aFHNnkodwV72H5ROga5EN8/bbuCBxInNzy8 o9z19AnajR7vCW/p42QwsGfSolQgE3KBdqWsle81LcCPVQPQshXzcjgBHZbH9/mY M4bX4iEsC9yeNgoMcHtIagOKipsqd4nuPskutf07Mh71OXFuxsVyGcOBVhhdZCb0 3ZYzVi+nzORPRZ93nPXipy3+NmoARk7mhXDgX9p1bPI= -----END DSA PRIVATE KEY----- bouncycastle-1.49.orig/test/src/org/bouncycastle/openssl/test/data/dsa/openssl_dsa_des3_ecb.pem0000644000175000017500000000235410556327511032360 0ustar ebourgebourg-----BEGIN DSA PRIVATE KEY----- Proc-Type: 4,ENCRYPTED DEK-Info: DES-EDE3,695F5DA31042DDE2 dzOyRB2M6CfzgilwOWNhrea/0Zt1EmJSCDPXO7kQz0LpP3/keHgFL14NqxQU6puh gYn8TKE+H2f+l8xoNhT6kdRI5OZP85NlC/RvzcIPJkriBgMeLwsRCvhxg0EujRa8 popm8yF2E8N9YPdz2CcrUW0mttVYeSy2YO/pi5rTJBeqqIjqFYjHPEmlnoNqboQk aflRKFw/rZgsE4gzoMKR/yso/GmSIXj48h9G9CyLWPFIDi8LdiiBG62wxK1TDFDI FIcU4KY8QyHSYc3DdYJJM2kXxvSy5BxbvWkD9cZS9+CuAvDyGI9dfF6g60f2tCA2 AxIHRn78StCNbRN1xBfkqw0BremGo8G3H8w6FrdeS1rKzzYqAe3XhDO/uN/0aRAz Yact4CIYbZgMRhTJh6YhWma9UfYtxslmTNkxmMptS2SvOVSbhPFSQJFIVWaN105f HGmLwoRwV+Xd7nLX5hcR0Sozr58m/1FYun4c4797/bcGA5nDKQ9+u/GvOtqGhIU4 EY5mkMhqt4MdDdKozQvATqWeSlESIFBZgG5sAQWuRJ9g2Pn1N2GTveY0ofIXV575 WsharLOALP87zUur0E92LoBrbFAS7/nJ7T7F1Ye8ZoG88qs+vJy8SUVCrDjUqfgL 90YHTKvmq3fJ+DO+40pLU+aiRBPin65h+5J0jW7f+eGpJV1S5dxIYKW0D1+PgcP5 URVYuN+cGWROH4DN7zyIFPh1lls0GtAf1to+zBy9QYUFAjt2lB/oL/d8RRso4rHG 8cUdXilKzAApI63nq0pKN2k9hAH5wGzxg3vWJCbsrXuqExsgZ0EFLR1IOX5ISCCZ g6TKiLDDSFBfWKTsix169JzCCptFwE+u8lY1b0A2ApCClXeS5+HvWlC/vtkuqCKj V51xSR7ltzosktG/gSc6wesbp0RlldK3Ee1l5Ld3sgoxFZd8aBuMVVfvqz0Li0ac 883Yr9+nSvc9WspdytrfjcbUxmWtBxsDtVqhuIM4eNusUPY/L6FJhfX2kgjc8RNf MNJXiMOaTmQfVCTmKZDF1EN+4IZfdrudL+UoesTzasdlDXGKc5gCecWiQpn/hKto 6YwKToh84r1R4gDcQGM+DL6wa1W5bVbD -----END DSA PRIVATE KEY----- bouncycastle-1.49.orig/test/src/org/bouncycastle/openssl/test/data/dsa/openssl_dsa_aes192_cbc.pem0000644000175000017500000000241310556327511032520 0ustar ebourgebourg-----BEGIN DSA PRIVATE KEY----- Proc-Type: 4,ENCRYPTED DEK-Info: AES-192-CBC,7FA13403627D9E1FA02FF88F6D594679 hZYB09uY4gjQFEHX8KGI33EzcJijYhBMNJCR9v8UK8IcQIITOfZxYV2BmrfQhuVh Kcar1JrQdnc4S7+UDFIjlLV9ErBCvIUQEflP2ByDhxl892EtVcoMKB3BJ2Rgi9mk 32KhayXo5V2bu2kOv2nTAjp91LebDz/ylmhhJhI86BL0DLjnjTEl99v9OHQsMtb9 cXZb51mwIynmqU7Wf+PchH83Yw0WOKs4MOrCtsqO9lL7Mf/MiSSiE+S/rpKLPXY0 4aBxP6fw+HG57gPlNAvv/qKtJu8YgZDqVXhIKNDZRTSRX+B9R1Yo1tgmJVPhk/7x mmYUxIb7w9nqa5OrxzFHyNvo1U5dJcXyCEhvUZ3ImR1DZt/oGJYgrPd/8YcYbsNP LKmTLUKI5CARZ5KcOjfM8vpKqlfpCg3Yl1FaNIjM0eAhD6XrepLj3faAJW4/YEoZ SGMO5atbM0ERT9sNDJTG0iMW6xGL5l/6pzfsTKI/2yMaAeWAyvg1PySNoSH7s6CC CfqF0w0VpQEiOPb+qjtmjBDB/VW5kNrRiBQqZAgpO6mED0jAdg9o31tyuuaFDWzX 41C2viVvxTx5A/xOtPvaDo9EMecc+7MpPLM2VhWhPDiDBYb8PCKqBOEwIyH119MN gQEC0IN/itc/J9ybHLCjrF1Rp83T3/XhAaXNVU9msBBpKNjawnwsUUj8gI0JRbx/ 5ehO32sQm8wkMyP/8iKDAqBRkDT3RIEmLi8ms+ZZRmLwGBkSZZzvOK3A5Dder4bp dIhOOetvoN6Bs9l1i6Dds64pwsy8IcnLLeNmOag+Qh8+pVUBNZ1zUV3KSizRKh5U dyT6VMILd2EAUJYLXs9HNFTtHZglRb96jQ3rkHGmAepeIVnJlNGKByvDUsJQDGl/ bGNk5Ejz93ylY8JzR1GaYyFVIUU0qY8khbo7bSn/o6II+KjyTTyTkV28jTSD5dYe upGHOzmqpGi3Pzaz3DXpbLcMzwYrMP9FuXuqkVWToDs87DCfGqskKtko+zlTV7/P eBILwUawtXMJfYntkV247FffKgS3/BNkgEE+iNthOsFMSoqX/3ESBKJdJDfKRH0J BkYL8O0I7OwYzfU3gCWVZ8AvAhd+nSqp4H3QUK0QM2w= -----END DSA PRIVATE KEY----- bouncycastle-1.49.orig/test/src/org/bouncycastle/openssl/test/data/dsa/openssl_dsa_rc2_40_cbc.pem0000644000175000017500000000235610556327511032513 0ustar ebourgebourg-----BEGIN DSA PRIVATE KEY----- Proc-Type: 4,ENCRYPTED DEK-Info: RC2-40-CBC,7AFE1927D7FEE9F6 WgKt23n2XggL+3rzABzjmOq8sdOYfFuuYUzP6UNH3zdXRt/fh24/WRgRw+WCa5/l 3Tt0/spkkMsgkkDwPPVLu0MUhfoUQyErK0F+8HeEdA82C7uGIgst4E2MS4bRXPR6 w9U2R88xdUaljjahEbSMUG7JXecjL0WG+zLVDpDqMdlKNcMz1tnQbO1JNLZCJlfX ZlVPslMmTTxs1sqYgDhkAgh3FwSsKMj51nvedVCq2bAtSmgnz/bFDLT4c6N4iLf5 MXP5ZUMUtWCac1hXayVw4koOkuPELKi2/1vWe7qDWJfqhKmRT2DV0Z1GKPjQp3Q6 kGnD8oVxbKfCQDI6PSMOeBcWu40Y1yTbBHBFJO5+MdWsNOQI6CZGJCHNu2ZbOd+w tIcxZZjy5d4uY869PxxVxO8TmCRUn9hham6qfTw5Mmh7bOyxqID3fXlyrcE7KRel dlL9eQuLcA7wtH5vqpy6V28yWculvP7qmXAGUd1gqSYHUs8kipf46ecFwieCNPEH x/6hDl38UsuixchyyJTp5u9L5cKPy5PWXv773xcPguk01YhlmqrpTNZsdoJ/CTBg gal+o01rXd6snhp7IwSAppCPwh4YJumwdPjF6jUlmB/2AStF6kGaOA6BbJ/lQlCa cHAUaVlTZEyzSGShBGJUAN2AughiOq+2POgr5IgeoC0NL8ieMg7bMYjn7+Np4yZN KGmT1jZo7OmyVdh9mheahXTT4Axihfmy+uPTECuGjq4X3DVv79OvSFRpHXIXLnX9 QkizsJKZc6v3FM6o5tbMDbJyelzaj8Xn8ANrugYMC1R4XImDSel6Bgxni2gHuTEc WrrILWnNSmNjz/yziFdu5VuQmYaJ1e50uenmOxiSQhL+53UzhhGCrw4ooAOSF5or s87oY1HO2aYq784A5UZVYGA6mYFjDDQSsbwp1LYomjoTrwoJML3P9x5SnaSrkEEC 3Gm0R/t7SkdMmJhRc28uYarO2qdwyBuhoYRxw9Z6bXeaUN2WhJ7hILCL0KKZE4vB DuKxE/KgD8ijKpkUn+6fizWau6Lm5mqxyMyEDnCDkvlvv7DMoqZRJvVWSddNMd6t T94SaIiCDOY3SuQCi1361GGbVH2dXH+X -----END DSA PRIVATE KEY----- bouncycastle-1.49.orig/test/src/org/bouncycastle/openssl/test/data/dsa/openssl_dsa_aes128_ofb.pem0000644000175000017500000000236710556327511032546 0ustar ebourgebourg-----BEGIN DSA PRIVATE KEY----- Proc-Type: 4,ENCRYPTED DEK-Info: AES-128-OFB,B32C602DACAACE3A4C55B4600D974E5F w1+kMXURdxpREW3giZg+PooayvatT1Pf1bY/h0Wcm8z0w7zRtQOyjCOdEPNxsdd5 ZYn3qEIOO+wkw0v0PdK1AaegJfYMbMpSp/iEyFXU/LHS0FpO7o8zmUiAvdeEKAFt Qk90gFBiyQyvWEWsp32KQH1/eDSeSLeQbfRfDbh70DkB4nUjYMW/eFL9E/cHCmdw 0LKUpEycc4s8i/mWCYJF+cQd4J8RHK+Ose2+5z86kHTrbFSlTBEZEXPDRHl8ZsZE 477A6/Ndy0Mq3+NgMLSl8xacs2v3itdza3AJREVOzvnRmV+NmWtYQ4MQrJrLg2yv wfAf4b2r+k8Igbpzn3NCEYolecGfyEWftzTsqTutlFO7RfeW8go4v2MvEsmHTphQ k2qaQkdSTFaA7a2O4PKezJap4RRCJhq1d5bw7RwkCpbRshsvrKQqGdTGJxEZZfGY 6pOt/qRL9LVCGUVdTTdje7fx9okx0LvKo62eKcUBh/AwZGE+ue28g6/77iABuVtQ 6kgJ3lQK3AQwKislF5cBC9MAkiIomsoVOKiP6+yX74XIa7T+3aWXlsY1oX13+kMW zijwOrc114Sus2eS3xSCOWLYN+0GECMrh2NDGDW6tx7i3R20BuEF/IwHob1qjbkz hnS8KrRY+174avQDeF1lMSBz4Wfi0O1IDuxWRDRT2z31E4E8EIoJh+73NZr7w6JA 8usK8RkiJ4ypoOPtRegXX6GBG5UYgI5bn1Ms2X5xSUGIXgG8IwjHDbAAd5xLSWp+ 01HzUsR+6wA3MxYiybTU4eOKNMviM1G4gGsKeuGrDsNnidrHfSzVyOGVVHr51xRI 9Xie4FX/VX8/7Q5RMsA8Y2eN/yeVwXup65JRhDD5LjILVMy7aA90KX7y/s8KIYae n6lB7PtcpRWwhdYSYtnlrJmYmrl55d6ZQtJm2/xjnOBd+igY4YKNjh11xBL8YNo3 wBjW4/lgrlvC7kbLxO6JIWipPr/6F3bjvmeLclTAZxjM1NU5HhTScGaEA8A4bq4+ 6Jiw9ZUw+TDCOmntkgEublcCMjcAxrawWYO/5EWuOAOkyBsa7BbfsUv3pgPugz70 qa/CEkshP5e/1VZgFq/BNFtb -----END DSA PRIVATE KEY----- bouncycastle-1.49.orig/test/src/org/bouncycastle/openssl/test/data/README.txt0000644000175000017500000000052311334402756026537 0ustar ebourgebourgSome OpenSSL-generated files, all containing the same DSA or RSA key, with various types of encryption applied (as well as the unencrypted version). The password used for all the encrypted files is "changeit". The PKCS#8 files which contain ENCRYPTED PRIVATE KEY use this password for the EncryptedPrivateKeyInfo object stored in them. bouncycastle-1.49.orig/test/src/org/bouncycastle/openssl/test/data/pkcs8/0000755000175000017500000000000012152033550026060 5ustar ebourgebourgbouncycastle-1.49.orig/test/src/org/bouncycastle/openssl/test/data/pkcs8/openssl_pkcs8_rsa_enc.pem0000644000175000017500000000345211333227737033070 0ustar ebourgebourg-----BEGIN ENCRYPTED PRIVATE KEY----- MIIFDjBABgkqhkiG9w0BBQ0wMzAbBgkqhkiG9w0BBQwwDgQIleYNcQVMEocCAggA MBQGCCqGSIb3DQMHBAjb8ZXri5RWRwSCBMjR3ICOxCzBu74U87lV1QXPNlnlHD2v TlRv2LNLPseEBAMiJkgP47rYwpzMmJjW5bNzCLxT0pYv2Z3/pXPUqy6aNJmOgCmU HvVGdz2jS+WYBtfijc1J6MkuvkhRIBxL4CYJidVurc5X/ebRu3BHbj9Kg/j5Hjx7 DV4qTxZR8vbRFH+ETdnVqj3pCYNOeYXvV+S0W7IN3rKmEk2su3u19YhbwnZH7Ny2 YMjAn9FaYT8bK+zlPBZBiQ8TuZxm/jxvW2ScQPLk1pRUs8WkDsaYY1gdg5XuKDND xA+mq5xskAMUliQmhJaYxlmv83QZ89JzSd44lLvnNeiaP2xjAhj10ZSVQ8eOXP63 NfHr9Ehqne5k0CI2fGg78pp8vIihw5D4WjHR46NvmbL1KIlxuYi4nFMtc9aK1zgq 3rhDL9m3fZZ9Rdd6lb1LN3ZOL8e54tL4KKVkl5jxhrThHujACB94remv6da2z6K1 LZPuDwI0njzC6Y6LgyGgAP75NKNAH0UzbpPncZxBdhyI5mOgRZnTMNt1XoToXOHP CMR5JfKqpczhoJnfcQJhFy44E1NH+qBOsNQTpypDe7Qiz878e6ebfcmXID0OyU/j o8czO+1BVT1S2LoN+xpeWcyNYoT+BnRVC99G7vKUoOeo90zNzQQOAEyoAjAg/52Y JWnOqnaxDqa0uJ/BPmESFvxeYZypJtoTd/g7n45J4fGBSwiH05TB9PbLHD3YcfxR NorFiq/RVXMXkgOGv+2ovJ/A6GK5mS/r1xr4qKnnO44zqwaie/xdZpXuQfQ8ZS7H XLVWgbdGP7fbTW72mAG5UzUr6c6gwPo8g6aiOaOnRU32SswhLp4CFgiKFhhgZ4YW tLmWc1Lz92D8ctTMvXhV+z8NEPF+livmfANpyhXl6ErCr8jEnhGgj4r7BA19dUXC Tttq+Gpo05tMXqom8/6PbQ3Cg2iCT8RGk6v0p2ne3Dg1LlbnklEfV8/DbYO5tUD/ +BXZhF1otr/ZaSdz/jJ+GzmD9KvhheQHBikj1/KicYp1KHYfo9oZJT5ulBO1UX/w JbpLaarntLOqb5im6OdjkPFkklVV9m6EByrfd35BTEfowNaasEvrj/VpchGPo7yf eFB6HGeIFHNloG7xXn9rv4npJLJOleqmBgyb4cQAk2KwjEJ38LHOyXQL/+tfI5DK NKzoFH33dtHnP2ZwaAE5ffMYv284y06n09yOFqPi8YkeFs+UiFeV4Kcht1gUNkPo IOLhwfVxoc9H5CbIBC3emckvbpnuBT9+EefGU3pU9e9et60mQ8sp28vtx16rN/e9 CiXhRXcLyQZxucmoLKXnyXgJbf3+nXcr4zMkNurqUisc+YVMALePkJCCsqRWPCvo vDqwMl8rkG3jAqmMJbtZCx7+vvnRnFQSE4BXOlzEQNPZK+EdlfvY5uvksIt93FF+ E6CIPHW4ki/X6gTIR6piDKiNEle+2e/fJpYqk/pFuVfmiN50QXzrnLrPCznhzQ9V GN2j9/b8iKzBk5y4wMNkOS8LT2qdcJoJRzZBb4VV981GwFxhAagwM29wko4sdNG/ vU4hrrm8WAfmp6d3/UdG6VdQj0O57z7BX6Vr91OBNw5RZKRkQvMu3Q5vCH7ZfYEj +YM= -----END ENCRYPTED PRIVATE KEY----- bouncycastle-1.49.orig/test/src/org/bouncycastle/openssl/test/data/pkcs8/openssl_pkcs8_rsa.pem0000644000175000017500000000325011333227737032237 0ustar ebourgebourg-----BEGIN PRIVATE KEY----- MIIEvgIBADANBgkqhkiG9w0BAQEFAASCBKgwggSkAgEAAoIBAQDIY6+Wgj6MqdEd Yq6FgH5xMgTBmFqAonR/eshjxY2C6MHs+WmCmNSDik2NgZWIaODvOF9uOEK2U0Zf JEG2LcZxoeIEgg/mfII2f4DLy1JYajm/llzwFBzAd/Rkcs3qwP2ba5VKn/pSqNLl nKHMXkXO+9SjfHDx95x2dK1dB8eGQGculOMcTm3uK7UlWNO4TSlwG9qHZ1aoM3GI g5C1fIpbxJqDVjFq6fFAapE3KRIWIQmKd3E5ICcDErqr/AapxnfO8UFNxVWSOLW7 ZAfis4w/c8/EAgyQHw42R0dNyjUOZsToF8McCsOpRjGolSU8aUyqspvd8IWJPd5d 6HBHueXNAgMBAAECggEAV3q9MpVVPQ79TTjBO2Km0D+nt+QMzk8dUHGHfZbGejmm Pw96shqJ24rK5FWHs+8lEwmnD3TcGsAr3mjzjtZY5U5oXtNwoYwFRElRLqZqIlLt NugrVltRWeyD8j30CuGJVQoYOGWyX9d3ielg8NjO3NcvMtembttLoKK68/vrbH11 9W7wr5p8/xyMfyl9curnmCFk5QqJ1FBpjPWY05NDIBCUJB0tGAqViCpxEeWPSlvb xcElqWfdbtnsYUxYU+iOTHHotoKnz4nLHYK2/njMhlCEyMXfu1DJOd8rg5yXewJF v6NhXgWStSexAT1bZ17LROazVcHfWB9QmXF1Fm7vOQKBgQD+dZxPDOi3Y4gCFegn Z+epNyl2aPTkseEZxrIqPKLHsGxUfYjQqkX2RdfTrq2vf4vFlN6uCXhSlZKXfLH/ iQ8FAzqenhVVHK2fv5xB0SE5zNmcHDrHshl+/zUNI2u5AMFECVO2SVbgoFjvgkou FolK8XUXfHfb4f732LUyYI0lEwKBgQDJmkWHhzekz3P5iWaAt1SH8bZpt2hqa6Bx A4VvMdtmjCxEDETN0Rb3CPYxw3qa3xGfW1y1j/49xi4gr69yaT2Tbca7PFGUmWRo OJwfCUB5uBUi6UVytK19OVKReOm4666x8P3YO4cxxSI/HeoSU0HR1kkX9rGmrsGN MgUQ15+FnwKBgAKf6/DUzUG3ARwkZbSiWb1hGEhkZMJHI29EoWnWHke5BiUI9nRQ jVAxADzqvFfnFOYA1xssddVEPbLaUmu0WjdPBTfFoaqzFQdkzpPPOGyENGpr0B9n MuQgdceg6eeKnnO5NOfYcdD3VnOCAInhKaFgRDjty7604hBkZ9oRLOOJAoGBAIJ+ dmUMlGr80XADjTLh+DhqsA1r542DDv44LkXUetS9BOYjHuIuZnQO+/UoOBNJMsn4 xGDNzN7FihQkRCeFkZL9arbFi3TpeUGw6vV38qEXE69eWVKvOuEkmpqJLphBDfom KNmvZopDtTAvt9SWybL+xp9ZUpK26ZfwebD2MU63AoGBAOa2Kt01DxoqiWiQP/ds Mc9wOw1zJsSmIK7wEiW3FkCz8uw3UgjF9ymYY/YAW3eZtuUpuxEzyENb9f21p4b2 zYoZ7nCUo4TmVXxgCjiEWglg3b/R3xjQr1dAABhTeI8bXMv5r/tMUsnS79uKqwGD 2Gc1syc3+055K4qcfZHH0XWu -----END PRIVATE KEY----- bouncycastle-1.49.orig/test/src/org/bouncycastle/openssl/test/AllTests.java0000644000175000017500000001415412104054266026526 0ustar ebourgebourgpackage org.bouncycastle.openssl.test; import java.io.ByteArrayInputStream; import java.io.ByteArrayOutputStream; import java.io.IOException; import java.io.InputStreamReader; import java.io.OutputStreamWriter; import java.security.KeyPairGenerator; import java.security.NoSuchAlgorithmException; import java.security.NoSuchProviderException; import java.security.PrivateKey; import java.security.Security; import junit.framework.Test; import junit.framework.TestCase; import junit.framework.TestSuite; import org.bouncycastle.asn1.ASN1ObjectIdentifier; import org.bouncycastle.jce.provider.BouncyCastleProvider; import org.bouncycastle.openssl.PEMReader; import org.bouncycastle.openssl.PEMWriter; import org.bouncycastle.openssl.PKCS8Generator; import org.bouncycastle.openssl.PasswordFinder; import org.bouncycastle.openssl.jcajce.JcaPKCS8Generator; import org.bouncycastle.openssl.jcajce.JceOpenSSLPKCS8EncryptorBuilder; import org.bouncycastle.operator.OperatorCreationException; import org.bouncycastle.util.test.SimpleTestResult; public class AllTests extends TestCase { public void testOpenSSL() { Security.addProvider(new BouncyCastleProvider()); org.bouncycastle.util.test.Test[] tests = new org.bouncycastle.util.test.Test[] { new ReaderTest(), new WriterTest(), new ParserTest() }; for (int i = 0; i != tests.length; i++) { SimpleTestResult result = (SimpleTestResult)tests[i].perform(); if (!result.isSuccessful()) { fail(result.toString()); } } } public void testPKCS8Encrypted() throws Exception { KeyPairGenerator kpGen = KeyPairGenerator.getInstance("RSA", "BC"); kpGen.initialize(1024); PrivateKey key = kpGen.generateKeyPair().getPrivate(); encryptedTest(key, PKCS8Generator.AES_256_CBC); encryptedTest(key, PKCS8Generator.DES3_CBC); encryptedTest(key, PKCS8Generator.PBE_SHA1_3DES); encryptedTestNew(key, PKCS8Generator.AES_256_CBC); encryptedTestNew(key, PKCS8Generator.DES3_CBC); encryptedTestNew(key, PKCS8Generator.PBE_SHA1_3DES); } private void encryptedTest(PrivateKey key, ASN1ObjectIdentifier algorithm) throws NoSuchProviderException, NoSuchAlgorithmException, IOException { ByteArrayOutputStream bOut = new ByteArrayOutputStream(); PEMWriter pWrt = new PEMWriter(new OutputStreamWriter(bOut), "BC"); PKCS8Generator pkcs8 = new PKCS8Generator(key, algorithm, "BC"); pkcs8.setPassword("hello".toCharArray()); pWrt.writeObject(pkcs8); pWrt.close(); PEMReader pRd = new PEMReader(new InputStreamReader(new ByteArrayInputStream(bOut.toByteArray())), new PasswordFinder() { public char[] getPassword() { return "hello".toCharArray(); } }); PrivateKey rdKey = (PrivateKey)pRd.readObject(); assertEquals(key, rdKey); } private void encryptedTestNew(PrivateKey key, ASN1ObjectIdentifier algorithm) throws NoSuchProviderException, NoSuchAlgorithmException, IOException, OperatorCreationException { ByteArrayOutputStream bOut = new ByteArrayOutputStream(); PEMWriter pWrt = new PEMWriter(new OutputStreamWriter(bOut), "BC"); JceOpenSSLPKCS8EncryptorBuilder encryptorBuilder = new JceOpenSSLPKCS8EncryptorBuilder(algorithm); encryptorBuilder.setProvider("BC"); encryptorBuilder.setPasssword("hello".toCharArray()); PKCS8Generator pkcs8 = new JcaPKCS8Generator(key, encryptorBuilder.build()); pWrt.writeObject(pkcs8); pWrt.close(); PEMReader pRd = new PEMReader(new InputStreamReader(new ByteArrayInputStream(bOut.toByteArray())), new PasswordFinder() { public char[] getPassword() { return "hello".toCharArray(); } }); PrivateKey rdKey = (PrivateKey)pRd.readObject(); assertEquals(key, rdKey); } public void testPKCS8Plain() throws Exception { KeyPairGenerator kpGen = KeyPairGenerator.getInstance("RSA", "BC"); kpGen.initialize(1024); PrivateKey key = kpGen.generateKeyPair().getPrivate(); ByteArrayOutputStream bOut = new ByteArrayOutputStream(); PEMWriter pWrt = new PEMWriter(new OutputStreamWriter(bOut)); PKCS8Generator pkcs8 = new PKCS8Generator(key); pWrt.writeObject(pkcs8); pWrt.close(); PEMReader pRd = new PEMReader(new InputStreamReader(new ByteArrayInputStream(bOut.toByteArray())), new PasswordFinder() { public char[] getPassword() { return "hello".toCharArray(); } }); PrivateKey rdKey = (PrivateKey)pRd.readObject(); assertEquals(key, rdKey); } public void testPKCS8PlainNew() throws Exception { KeyPairGenerator kpGen = KeyPairGenerator.getInstance("RSA", "BC"); kpGen.initialize(1024); PrivateKey key = kpGen.generateKeyPair().getPrivate(); ByteArrayOutputStream bOut = new ByteArrayOutputStream(); PEMWriter pWrt = new PEMWriter(new OutputStreamWriter(bOut)); PKCS8Generator pkcs8 = new JcaPKCS8Generator(key, null); pWrt.writeObject(pkcs8); pWrt.close(); PEMReader pRd = new PEMReader(new InputStreamReader(new ByteArrayInputStream(bOut.toByteArray())), new PasswordFinder() { public char[] getPassword() { return "hello".toCharArray(); } }); PrivateKey rdKey = (PrivateKey)pRd.readObject(); assertEquals(key, rdKey); } public static void main (String[] args) { Security.addProvider(new BouncyCastleProvider()); junit.textui.TestRunner.run(suite()); } public static Test suite() { TestSuite suite = new TestSuite("OpenSSL Tests"); suite.addTestSuite(AllTests.class); return suite; } } bouncycastle-1.49.orig/test/src/org/bouncycastle/openssl/test/pkcs8test.pem0000644000175000017500000002476711341637535026606 0ustar ebourgebourg-----BEGIN PRIVATE KEY----- MIIEvQIBADANBgkqhkiG9w0BAQEFAASCBKcwggSjAgEAAoIBAQDBvYyk4LsBVS3S 34GZc8uuddHq7cUJx1lZaxWK7C6nnTNKJmJEhxW80VIukpo2RODL1hPFlgCJY3ch /4437UoG8ZNAE1BfuVMIkS1AX/l/KAyqUIX/bsXgvZch0Joo92KaPfDB7QA8VCGd NCcRaOnusDdsFDdF4/Mrd7/x+Ipkd56FXVEk14QGizFc86aNJrzXjy9ent34PTcS uGPXUX7pbiZj8gK9f77pDuH+JymqXdfBKz/x0T54i8N4QFfVp2LbGzeRnduaX4Ff 79ikdo/XQYTPOYoDwgdiAR+n0+mvDNkI5rbukSLcz+xbWdkJ1ReHW/QQAiqQWK37 4D1fFNrZAgMBAAECggEAGbH+GVAE/WRCs5kZIzUMapMNyE7It0dNPmLJdKdmeKyM xOTaW6Re6bAJakvfUBtKhT5bWPVQFOiwQD4Yqqo6Czm3AeSN4GQ/8v7uNX+FI6w4 Ic6UNxCGBgyfIsj76TsGRNa6O74nLdkqrCLim5iCjjmo4Bi+S/Kzqaw0NO91y2Um 9XyCzM7Oh4LukmF94pd5gZBQjjVEkEsw3+oQlOznm3rCNIhYSjfStnFZT5stvcIw BscQg386Wo+UvXV8zDI0qrAi0pNepVGsdpGGGUIHkogaF9HHElcSIAVBOQLhxvf5 S27j3bvHBzWmmR/MgOsBH5+ZqQCTzVGJdzIzXkCRUQKBgQDkQIQNsRv0V44UriNr nageBkbjVFxczl5k2qN193qb0GalSOoeKcT9jsBO32mcaBd84vuueSNS69rGlj8+ 7rKyMsRAnjhbMJ0FCWv2muQjxZWEcTWV38wgXkbzos4fon19wQo3JPg0ikOjmGbK Z4EIJE0PIw6hjGrTXqc9wK4kgwKBgQDZSv2KVaTX80ZyLIOlbs5+CTAzlEde8+u+ 7LcFOvrrzeo86i6+65yvu395Dlm6PAhz0KocaUECeEDakdQHEDfvEf29BsU+p7fU kfNPotacAD7kNo2WenzH0mIhtBWchSUz1P3cIbq4Rxm4XPlAzMEXcDtFRqf+4wVV d8Thcjl8cwKBgQCKVGczfRC6Bo3/DoI86DFI8PjpMOlA/XjLmo3SIofWAnkS1pu8 aAgQuwDlTBTPS25gq5doZ9X2nSXbkJcH5tW5lXbGypzQ9ydSNCGQNNLqswYoXAvj ptwpCbnqUdKl7W4sVl+AiBE8lkbj0KsLI6tZadahw9dMJLNhIk4s6KchTQKBgB4f PCh6GODq04AuVY2QX8WvBmSQEJjEHZEZBYIPHAumPut010gWJ2FhD5m7eIrNmapc aciIer+Z5fumrYrRH7/fcZpLnvpBi8VG+kC25SM5EX7XZSdQEY4txva/HSPWfULD KvHiJx02lgUttkvaVoYmQ8Elu1IlLG8drEhIalmrAoGAKLjcIIAcAhuE0QkstS/z ZiFhp7tCCrH5sVvXPJfxuKtEC3iTfgOoMywaX3SQGkOP5kVngziGemv1b493Vmek T8JLbnNbkooCvPsbMlMgcqZcb/5ckymabMaJBTqhYP4w/uRETNyjmb0uxX2CqXk0 RoIdgWsw0IiLCNMn16z5O5w= -----END PRIVATE KEY----- -----BEGIN ENCRYPTED PRIVATE KEY----- MIIFHzBJBgkqhkiG9w0BBQ0wPDAbBgkqhkiG9w0BBQwwDgQIGQp1RhqLV50CAggA MB0GCWCGSAFlAwQBAgQQhMfC5lWjUndHWVmSgLGLMgSCBNBZEZlGvXV9XjzWo0di IJof42XSh+mrOdRvUPUS0uPzctmnXZjhKdu42v5jrbyNdruqZsMXTnnQC/UW7Fox fp3JzOM5w7wEmgrJybOZgA5spNkiWDdlnmqKme34wEPKv+GPEuHj7w+Z4hc7MSdg T6Q3CJFLJDCEvfK70Gyxp6X90HN1riQQVxFOTSg9TJsnsvkOJ9Ju3VCTOqt3jlW0 FEzrC3lV4AcxfWZct7tkqOTXygWMGinz7OqLxIcmlrF3oc0bLxEQzQuGCJIzrhKo 3Lb73Xto/kC/uqbCdU+v1zafdKLI/0Uj3/GOGLUu/PeMo7VaHbAj/AOX63Yvj3zm WOgJwnOis5iP5rqL3lfdeJrkmE1w7xTLn9fUWXXr+qcVBLeZY30TE9wW9gRCDCka 09ZVw9MnrodTgvWVSI3xHxjYin8GcxQ+VZTxQMQFHA2cyR60yMG+eGm5t3TZNHVW h3uqVxjbN7tMYbjUo1NdbINntOQZhqMje39ai3mWIhGPO09yfsw7ZRX9hhKlrIYo UQ4LcEgMZsZDDtAY+Mol7pYB7KpM2iftBT8KSkBLSlqpndl4PJHLUaNBgbNDP6py PB8FjPO49qPybeVCIgg3AswxJwGE9bXtO9SLcf/p6S0IWvVcWn+VV5sX+9Bav0eZ nCO0WJYrWcjUBzYJLWIDcPviYkoMkFrsFGUP0DA7OneLlW84YUh3AeqqJppb/qve UeUXZipLEHf+Z/ToGW+RzPQmFTVDqIx0FdQCi3EefBr3CbN/KtLdRjbP4kyeRGlw CUS+BWQ+W/NtVUfVmBvsSLtVfW1pevemt4FE9rP9qUa8KeRpOJIzF4kHUmHyDfp6 rvQTSS6d3a+N1GyJA5/N4UM6g7FbVnbngPvM1hMNfK6xbIcxQJudBQa/bHqf8DXu 61npKQYir+TmgDXlc9iD23M+TH2VgeunrFKuVMNVl4igH3+mcHyXpZ/EGM0KyIhq PJjPRKD0qcCvs4mPRiOx1wJbCYMdYfEF7sIlkQgKjbQZQyRlDKLkLl4pGWXxaqUm iyo6VpK2phKcA/hPYz10isRfy1WrKdNHW0B5DPyreko2H0akapfqMjROE0JHtVGs gKg0FrbZXUP+QuKm0V91ShA7c3mRfN2XNbxEc9JFzkDJs4JBxj2H7MxvPQyRrWE3 sKsQWtr5AFpFb5p5kqCtyyu7ag9pGicqlaFuLda/PR0ykMrhMU4RBO0OulOGl8ZP 9RC1GCArbSSUYH9xvwthGdaDylONVmHwunFMHs8pblTyo6FiKn1q7lIVXYO3AJ/5 NfKgryp50SXq0p41i8Dtu+4R6CKx4xTMilPYKYDiDPCRtnwvckI/PshGMA/CHLzr LLZUlRt1iup5SDjqRIjquw/aDRe+Wy4AXXniHOnlSrNynHcJRWz+pnLT3Bi6Z2nQ ERY4pCIQ/ZdhAHHldFZ7WJ2wrwhf4MQ7sF20HLgXeUN3qj4xYcwR3CykU8f7dfI7 TIo26asqsVDsVL02tr4dUrtm4J8yQsH8jD0nCpvGwJ9gswUBPmo9YreN82Kt/LSy YZISyo2BnoowEcAEGnZBf+PLwBeePeXC2/vrxHlMl7JPkPesEHtTuET034woXELi wO/DuStXmiIydT29G1n81zmdVw== -----END ENCRYPTED PRIVATE KEY----- -----BEGIN ENCRYPTED PRIVATE KEY----- MIIFDjBABgkqhkiG9w0BBQ0wMzAbBgkqhkiG9w0BBQwwDgQI7ITJ8AdDrO0CAggA MBQGCCqGSIb3DQMHBAinsLeB93eJ2QSCBMhi3oBwLoE4PNYkIpp3FVk6VHzs7SGQ u/KcyYQk0Shjbe/ykNJx72OVfzYemlcNpr4p9Jt3VbXxisiZyRs2m1Edqxzdt3zb AcRSVNIbph8V9mSZNBl2hR3GAsrbSTkwM4xzXCQRvA50z1DIABlVFR9AB/52JQ/f IQx9NrG6SxlzcNjJMzHpR46ELG0Z5EqPLrdyScVX7TEFWl2ue9P/MOhjfZH0/Wgk fFCFNoPsABQ6az/lTj1f7hkYMOIw2tayHAuAXTbqyuOVWhVfAqr3H/XuJvXspjDC SmIr9jIdJKOTNrJD1/rG4wnh9U0OHxceQqf+TJisWd12WVjwMZ1jIqjk0g+BQeId JJvuJTdVVGee1C3enPjG5qBiSJpD+BEsfk7YQFRzW5TzlzELIdkjru3k3cqSp+dX Hp1LT6E8TTcdX4wdhKWf7VV6sayleiaiB+9XufqU7FwnOJbe0sydnn8L7A07qFcs 9WrXmCSCpB2bH0MYDvuauqHjpIZmaHUAUpXYUjjj8EnuhesJAz2bzO7fQ9rZAQ0D 6Gq4SLbjTtOlpS2LZeNio5ibyeQkgNs76Tq0zdS+5fFnL/6tIIsJUbdZdLz/5isq j+SO+7TiGL8a5URZO2pc3Dh/TtjV/lSiI8qb/MMUAmCL0vWe/FKx3xx4dCrRfDX1 GyeclEl4pWFqnwSQyHadr1nvnvGrG4/pcwrcnhNNb+Y80RIw15A/kNjsKP1f3XWr eHAp+YGqDbJ/RuvoVunoAx3PwA56NTQLMmzYakgQFEPtModtvHTQnLkGozg0VjWk TdkB7R8GS87IHpOUyrZcxKYDwOmhR2bHgtosvZ4XK+GAwjIGUzGKtg6MyMh3ynsP 68Vaj4PgkvmItmdZKrvkinophdFqFlqCLLNf6NtaVUMfz3Ap/vmX+EK+2YWxezNa qFMNXO76xoKj+piF47vN7zjGsJ59yLLWZHO9J8hFLqSgArhVcV69j7JVMD3XugbG YEFudiVEwE8Kl190CVP1BX8DXYhMrrDL/4QD+jccgLfK20bWdaCtPOs6SxahhsvU wRX8hwf3QLiuZxfAIlVCn2eL+9QffJYETjfhAuvPK/HwM6+/n+9GpYc4Ezs593KJ 9/mZLuMKc0b9tDc0dQ5ld7aNiWuWyP46Da9FWBdbjoiBOHIUp8h5METE1NuH2d1l THWYaD0OyOgyi2gosRkjJxqDp0IVxIymsKhX0K/EBcYuKiPKZLL8lCTdrzGlhRC7 M7N99j2elk3k6BJYewdiklmWHEXFOFo8NWwLKKQPi/rSQHcJy1o4WBiXV5UOYJ2b 50DAF52281ao7BZhYTt5JKy+KYvP9Znkk/Kklx79SHx/bSrXHZJCLoVJaWRFp332 vQASx042mXMeNDPy7dC9NP3eSyv/niIUWI4t+ktUds1OmWIAMs+2gQqD0Eq7gAfu i8SKjiAXPADx57dg7loU0O9IyErJpY4HrvDLLMQaxLLpJxl3YSrgEVkrkEQvP0vv ktUR9qQbIJ3BGD3YuQ3cxAgKWaaZWdEJjKqalTYACS3mg/RHYAb0xnTUX7nkUch6 D79p6fAhhWe9KG2f8tJVuHfUOnEBi1XR5755Vqt4xgUqMI82z4iqAU8ieBvYpy8G ImM= -----END ENCRYPTED PRIVATE KEY----- -----BEGIN ENCRYPTED PRIVATE KEY----- MIIE6jAcBgoqhkiG9w0BDAEDMA4ECBztmnlgZpEhAgIIAASCBMggv6vLTkuAj/y7 wLaJLezGOWe1JyFmhxfn6FMMNIZruIYUdoVNpsUzeOhedtawTszOOLtDtprsqvNz /oDWQs2B+JqpLjalfRfkjJjtzkkeij3mVNZH69XPabO/QXnHxjeW/S0Ps5gsIpsf 6+eklLo7LI+KgVMWVIdZ5bC0P/FFi+Bf+sI20NQN3RchJMT8lKcV+2PHZQIb7diJ UuYPf3GRg9XtBb0pXssAC8Do84y1kKYj8xil3g4oe27jn1wlQ0+c8DeqXrXAcnIk /tFAfvNyO8EMfaP74vlDC4aATXY1O8UEAStTothbtahFNpFfB/9UbvKG0ac0KC4x 43Ftv1H3xtyn9vVA4qDCmLK0cNDFKCRo+A41kEE6AKYKctbthhC0GMoj69EYPMhE Yg9+1Ev+qI2l8jB9kGbN6YlAkM4bUDHT98fFeS/wrCnzxmmiDD/rsHzv6cdkNw0z G5F+Wvf3cT1sVGd6RexVydmfzjEeP/6z9Xr3oMqW2CVY9mHFlq2dBkR1LR8Kju+l vWspR2YjzggylL8CpCpeCWzd7O0Q3sni3onHFwEen9fQ0GxM9FS0bH7Ty0+gf0jm ZFxwcHnH1mMOS5W4yg00Ri8QDgvz4M9BT+HLu+yId4QwGQFlQqg2+tLKsm9mVAnP 0Ew+dV90r7/cRUCV0kUmbYissi39OHw5sOs0GDMUiNck77E0paBnTb0s+UzBIdnq wy+ojiDxhANB8iabKnfF/9fJ6XB0pxUQkXmKfFJZqpVzEq7ZVQLFPfyjJhQD4vTE jOG3PdamAFOjiBBqtxbBF5s+pLZL3sZhStugqJ1l63E5tgMcJ8w0czifLjjUULtG 8O4V58yAkuqu8ICyhXXOA7Bhmn/vymBIS5VmxvR6NZA9qK9XEh5it1ngNZt3oc/e vclArrVbev8Q+Jz6X6aAbTsDleihsRrugGkWeZCjkFIYPKlA58FKmfB7xRcvkpYn 8iuI1DJCiT99mF0YUjEkKWsbShUElR4ok474SsXt5gHtCtykXrncAPtouYPnXRuY MS9pYhgtoMhNPXotZwMsj+YvoWJBbeBgc7WgxZkcxbum3I3ns3E0+RCz1gAI6u7F ZUfLogdk+Og/wbv7B5NRncRT2UnWfOyyxlGtxrwqXxaOyIF9007F+Xe8NbRO/EAH 1yFMdL1jA40lacQdbxrVDQ1nVXRGL6l0O51zWC2E3HkZMclTdWp1yoV3F4r5EY7b OLjdZ3ip/vWuMcaHpkP1lp41Q00oZpxkfhq6hrw5agpv1o9OTUr260nmHALDZ6dy 2qWNqyFYyDuSSGB7spbBeuLq30WuXNO7kLBW3Z1MGq2AmOimUR8r79OkMBkZzZol IHgfjedxE/1uOmU5vcEnW/rGrFavTu9BvjoDLVV7/5Gc9z/q8CQbYW/cK77qD8ZC J22oFudz2qjl377LRIjmbZp5FvU1fIPy29/7LnuB1b3xfYvFwk/6YSM2FlT57HIL PmAHNYzW+Uwst0khEkzcagqqMDERcD/2WKedXUDNwxAm5AU8v31FYLLjeZfkmeNj NVYXzstYWgLPtUhODf63pGuILuxQFth4YrdZitda3RRCFI2F8NVFTADbwQWKZUMg KSVe9u9LXFxPNijyRpk= -----END ENCRYPTED PRIVATE KEY----- -----BEGIN ENCRYPTED PRIVATE KEY----- MIIE4zAcBgoqhkiG9w0BDAEBMA4ECMpfoO3NymimAgIIAASCBMG1ImpwNjYr+SIa FEBPpj57UpoC8FqFKe4bnFkYK+KVapykY/p6KRlo5GyZZHycWbLhQ6LDwCgsgPcp x/BTghqMvztLDtO+jIaEqcudX/dp0VhDZazeFJ3hYhjgmPCfTSEBYXAKmtdEPCri eRqO1FLw8rAX+n1dJg0wnPly6M8kY4KE331G87+IAynsbieaAVkVAFm4T5+kqLXz dC36WzcrpaXln15ydp4Ok7i0/TLcTCfVh5zGvlujKrogJ4EJyFzThyByrRWYAx+H 3RdtjgL3zoMs7s8qXDVcmActX+PCdDz8w4lqkuG362TTdewDnEc3PQNJPjzWWhWk QZ1vbUa2lszxAnBSxHMEs0pvXy4Owboh/FCRJ+0kpZrnEzdNumn9jWWkFxkhZeZU BD1QHEyuVN4ZzG4Vr28uZham74RQOHZwv3hiLMKXC0K8A4VSfnWZGGXaa39J58N4 LpPwORBJOv5haLzi1VZj/IzfN6oc5PnCS51+MYOFcLYf/2qvoQbB6SNw9PxpNf4E cgPxXMYJQcgSf2uDJwjsRLmAe8ChD2xvo357fhDZ/y+j4viB8pzKhX9uG16c1Wbo 7BHnXdqrcbgeNgk4s9elWSr1kKb0gTSkqIRh42s4d51Zrb6qQjgwM0UfydfWyMu4 y1acFtQPicFoIfvrKxnHEjwDLW3nOhxGL3ORL42U8ICJl8XzLRLYKMQnH6k/Idod thZO6v0habuoPp0ozYml77BmmFkdSoR9CZKweoA5Xb9KjeLGIoQk0Kg9Roxw/KV6 3EBLrP6HLTex/QhhribaHUoz9i9tWKKWGwOl9JXeV/BM3P+JmW05h5LY4THBG68w 7P+kFvmUAXl4SOd7AVMQCJeUKIbif+Wr7UnRM/G3lJtg3VSp3IkINW2WuUgfWSVw T/OUObFOKRZUKqEmPd3HYvlguVJM76jQ0uVi9XiEJtpNVo7UJWw5dk+V8obANxcu qNldaXJCDspJe9Ep0NqkfQIuXMZGQo3hcbirH0y3HlBBXdE40Oc6WA0fu/L2D/Ff sYCEaGZ0mBOuOi9CP9HailwAEL8Bf/3LsYBLSqKR1vjSC8n2bfD+Sy598QQ8Ti7C 7XpuKBCAws+cVUnMQVuqckuEm454tQxlWNnmTqoKnIwlEw7atE3Fi7xd0Yk3xO2Z m/1+jLMfvUsYr9uYFWYt0SV7GTOHyfc9HWFb8Mtz9XvlA7RQ3gx5hNoovJeeK3Ho 3f6h8S0BYFWOOvKXk27ZF9OgEqeRryH+B1y32n6AtgeZspnOLPlMTgmvjvqYiocA 4iaTAoX5PGZuNKRqBhfiCLUT2AI6Coq+LjRdHn1mwLqBnagJFYsaXcTjZNKUr47M 7kbXX5JC12d1lcCxkTqkhV88SZhgvPzt9J/3Kvx6iOMRinWfxGGFQqiTFEwvk5zI 64aA80Z/N0jkhiibbsl/quQqi9Tlvqd1wpHcJ28t25H0eKWfiktvuxWRNj86JzHk ZMKv1ReqWrihQyfwSG4nvMKaSJSlwuzbb7D5g71bMCHdj9ZddgsWdu93mR7xv8Ok tatasiU0x4bZvqaOk7qjgHJCsK0dQHsfF5kIQJ1eC0akqRP1KfDs/Jskefr6e/PX 1hql/nLztg== -----END ENCRYPTED PRIVATE KEY----- -----BEGIN ENCRYPTED PRIVATE KEY----- MIIE6TAbBgkqhkiG9w0BBQowDgQI3TbGvnzF0LACAggABIIEyLCaObV7h//eWCwg detit/l8jaBe2pHs/JPd1qJjnvAjqnSBVQjkbXjxU6ERAXC2IhQzF4ZlW29RrdLC ocxhHHM1Pt2+E2T+wiALFYidQIfawiobru3Tb8FN0QaFoyVZgUHzxeZUdot2ceW5 TrP3PaNSWTnPl2boYy/TBlbw3W5QvmApHvA5RFR0uVqO6kASCPmThVTrutPVPsRo Z5QZCTgZWrPXzQmyUzF5z0uBY2i2jWDwZWso63UZh3A+7Au7hn/NAqKNDeN+TZqc nniJXD8PTJ8eNtrwk758lhbbrh7orAzy85e+WmHnmVWuZ88kULBiDdUFu+uUNaqD gukACGRDe0tGEq/CFKJVkSDvKPKrnBLHo4uBootK+Chj5iY8KMVVJ/IWGjgYL7Bo R5zZYos6qubuzfycRCWXHnR5cp3qqgO6oRubRXvWaYuOx5gf/trCK7dDVptYHSzB dK5CtlgOQY9mVM6THkgzPNKlaoaWXcAz2YdROMkqEvhGHWTnREuDRmqlsCQKSDkS ljyBFHVLEGFrqChnZmIi5x8M8rMQHTjQYYPatIUEr10suWz9So2fSNtrlbzXrk4c rQR3XFedszYSCoBVofW4Nt5iSdRldkYh+DGuKG40UKltCfu3EYl3xKgf6VB0quqI l6CjQY/XlDirwLVOE0zPTqKeMGsi4UW6Tecri07/48JWBZtYPLEj7LWTG59GmLPl LFMZd8JO0au/8UESxFBIg8lBVjGpNV8F3YdI0x/inZFaESKJqK3eNccBMSCIZVxY +gE/8iNIn/bBGFWGxpJSVAjaGMjXnkRtYCcriTKchvWq8gljhRpTt8y/hEvHzmaM rUbY6jJyAJ9Jeso3nzpBetDUImZ89iN9LC6Znz0g2ot1iLEL9Lvtnayn4Aik6wfA Ha7R8qy8JjCpSJtV8/COtRrzbzcuZw5I3Hsm3cTCERP1zmNZbm0MFM7WJVMdXPUi 1OS+vwlUvXt12dfxtABJG+wbsTQ9lPVGph+aixG1QvZVTq7eq0MWo+dJRev2656a 5VcdmtVo1YiNCG2TniZjcIugksxbjwRdmOaxei7VPn0GuD+4oi5fon8IlpjosJJW FEc17IO7rqidXmeFttnnPLooAO5wajNVdAyuCs3HKJsnVLXZK42doWnNm7k+/uca K+ai0RHyQLqWfxcU2U78cVVhdgnmFU/9d/+gHhTfhzpCW029NlIgNuQTgU+mAiug 27Mbrm2Q2f69SNXwWgKw2h6MfMsQxDNZI0vqbA6gvcmkwgbCrrZJr1rSl7dZaZuI ek7l/yG/dqyzUWKcHko6jL2OM16cKkVWTRv7o7Au8RrLA2G7BA+FpHt9ZnthzX6K LMPr6an9LMwjvnxD15YfENWphVqx7r0VYQnL3AfEinuJ9K4jyGZ1nny35jUHg1tF XQbVIBfxoMuSLUjDep9E+iyfL5Qogh2hlZ8HuXcRXb44BucBlwruDuJm8Ft6Q84k +pw93biUrfEm/7SXIjC5+Daf+49fCrJbMQjfGUAxRxB63qkEtNo5AbLZMlujQxFt ByA2F5l6hq5cT97uCDPcYdW+QRr7Q+rFVy8sqxtp3K/D1LHX752yRqBl+pnf1tJA Dud9ALqr+fQhxbd3Hw== -----END ENCRYPTED PRIVATE KEY----- bouncycastle-1.49.orig/test/src/org/bouncycastle/openssl/test/WriterTest.java0000644000175000017500000002021611701176530027104 0ustar ebourgebourgpackage org.bouncycastle.openssl.test; import java.io.ByteArrayOutputStream; import java.io.IOException; import java.io.OutputStreamWriter; import java.io.StringReader; import java.io.StringWriter; import java.math.BigInteger; import java.security.KeyFactory; import java.security.KeyPair; import java.security.KeyPairGenerator; import java.security.PrivateKey; import java.security.SecureRandom; import java.security.Security; import java.security.spec.DSAParameterSpec; import java.security.spec.PKCS8EncodedKeySpec; import java.security.spec.RSAPrivateCrtKeySpec; import java.util.List; import org.bouncycastle.jce.provider.BouncyCastleProvider; import org.bouncycastle.openssl.PEMReader; import org.bouncycastle.openssl.PEMWriter; import org.bouncycastle.openssl.PasswordFinder; import org.bouncycastle.util.encoders.Base64; import org.bouncycastle.util.io.pem.PemHeader; import org.bouncycastle.util.io.pem.PemObject; import org.bouncycastle.util.io.pem.PemReader; import org.bouncycastle.util.test.SimpleTest; public class WriterTest extends SimpleTest { private static final SecureRandom random = new SecureRandom(); // TODO Replace with a randomly generated key each test run? private static final RSAPrivateCrtKeySpec testRsaKeySpec = new RSAPrivateCrtKeySpec( new BigInteger("b4a7e46170574f16a97082b22be58b6a2a629798419be12872a4bdba626cfae9900f76abfb12139dce5de56564fab2b6543165a040c606887420e33d91ed7ed7", 16), new BigInteger("11", 16), new BigInteger("9f66f6b05410cd503b2709e88115d55daced94d1a34d4e32bf824d0dde6028ae79c5f07b580f5dce240d7111f7ddb130a7945cd7d957d1920994da389f490c89", 16), new BigInteger("c0a0758cdf14256f78d4708c86becdead1b50ad4ad6c5c703e2168fbf37884cb", 16), new BigInteger("f01734d7960ea60070f1b06f2bb81bfac48ff192ae18451d5e56c734a5aab8a5", 16), new BigInteger("b54bb9edff22051d9ee60f9351a48591b6500a319429c069a3e335a1d6171391", 16), new BigInteger("d3d83daf2a0cecd3367ae6f8ae1aeb82e9ac2f816c6fc483533d8297dd7884cd", 16), new BigInteger("b8f52fc6f38593dabb661d3f50f8897f8106eee68b1bce78a95b132b4e5b5d19", 16)); private static final DSAParameterSpec testDsaParams = new DSAParameterSpec( new BigInteger("7434410770759874867539421675728577177024889699586189000788950934679315164676852047058354758883833299702695428196962057871264685291775577130504050839126673"), new BigInteger("1138656671590261728308283492178581223478058193247"), new BigInteger("4182906737723181805517018315469082619513954319976782448649747742951189003482834321192692620856488639629011570381138542789803819092529658402611668375788410")); private static final PKCS8EncodedKeySpec testEcDsaKeySpec = new PKCS8EncodedKeySpec( Base64.decode("MIG/AgEAMBAGByqGSM49AgEGBSuBBAAiBIGnMIGkAgEBBDCSBU3vo7ieeKs0ABQamy/ynxlde7Ylr8HmyfLaNnMr" + "jAwPp9R+KMUEhB7zxSAXv9KgBwYFK4EEACKhZANiAQQyyolMpg+TyB4o9kPWqafHIOe8o9K1glus+w2sY8OIPQQWGb5i5LdAyi" + "/SscwU24rZM0yiL3BHodp9ccwyhLrFYgXJUOQcCN2dno1GMols5497in5gL5+zn0yMsRtyv5o=") ); private static final char[] testPassword = "bouncy".toCharArray(); private static final String[] algorithms = new String[] { "AES-128-CBC", "AES-128-CFB", "AES-128-ECB", "AES-128-OFB", "AES-192-CBC", "AES-192-CFB", "AES-192-ECB", "AES-192-OFB", "AES-256-CBC", "AES-256-CFB", "AES-256-ECB", "AES-256-OFB", "BF-CBC", "BF-CFB", "BF-ECB", "BF-OFB", "DES-CBC", "DES-CFB", "DES-ECB", "DES-OFB", "DES-EDE", "DES-EDE-CBC", "DES-EDE-CFB", "DES-EDE-ECB", "DES-EDE-OFB", "DES-EDE3", "DES-EDE3-CBC", "DES-EDE3-CFB", "DES-EDE3-ECB", "DES-EDE3-OFB", "RC2-CBC", "RC2-CFB", "RC2-ECB", "RC2-OFB", "RC2-40-CBC", "RC2-64-CBC", }; private class Password implements PasswordFinder { private final char[] password; public Password( char[] word) { this.password = (char[]) word.clone(); } public char[] getPassword() { return (char[]) password.clone(); } } public String getName() { return "PEMWriterTest"; } public void performTest() throws Exception { final String provider = "BC"; KeyPairGenerator dsaKpg = KeyPairGenerator.getInstance("DSA", provider); dsaKpg.initialize(testDsaParams, random); KeyPair dsaKp = dsaKpg.generateKeyPair(); PrivateKey testDsaKey = dsaKp.getPrivate(); doWriteReadTest(testDsaKey, provider); doWriteReadTests(testDsaKey, provider, algorithms); KeyFactory fact = KeyFactory.getInstance("RSA", provider); PrivateKey testRsaKey = fact.generatePrivate(testRsaKeySpec); doWriteReadTest(testRsaKey, provider); doWriteReadTests(testRsaKey, provider, algorithms); fact = KeyFactory.getInstance("ECDSA", provider); PrivateKey testEcDsaKey = fact.generatePrivate(testEcDsaKeySpec); doWriteReadTest(testEcDsaKey, provider); doWriteReadTests(testEcDsaKey, provider, algorithms); KeyPairGenerator kpGen = KeyPairGenerator.getInstance("ECDSA", "BC"); kpGen.initialize(239); PrivateKey privKey = kpGen.generateKeyPair().getPrivate(); doWriteReadTest(privKey, provider); doWriteReadTests(privKey, "BC", algorithms); // override test PEMWriter pWrt = new PEMWriter(new OutputStreamWriter(new ByteArrayOutputStream())); Object o = new PemObject("FRED", new byte[100]); pWrt.writeObject(o); pWrt.close(); } private void doWriteReadTests( PrivateKey akp, String provider, String[] algorithms) throws IOException { for (int i = 0; i < algorithms.length; ++i) { doWriteReadTest(akp, provider, algorithms[i]); } } private void doWriteReadTest( PrivateKey akp, String provider) throws IOException { StringWriter sw = new StringWriter(); PEMWriter pw = new PEMWriter(sw, provider); pw.writeObject(akp); pw.close(); String data = sw.toString(); PEMReader pr = new PEMReader(new StringReader(data)); Object o = pr.readObject(); if (o == null || !(o instanceof KeyPair)) { fail("Didn't find OpenSSL key"); } KeyPair kp = (KeyPair) o; PrivateKey privKey = kp.getPrivate(); if (!akp.equals(privKey)) { fail("Failed to read back test"); } } private void doWriteReadTest( PrivateKey akp, String provider, String algorithm) throws IOException { StringWriter sw = new StringWriter(); PEMWriter pw = new PEMWriter(sw, provider); pw.writeObject(akp, algorithm, testPassword, random); pw.close(); String data = sw.toString(); PemReader pRaw = new PemReader(new StringReader(data)); PemObject pemObject = pRaw.readPemObject(); List headers = pemObject.getHeaders(); for (int i = 0; i != headers.size(); i++) { PemHeader pemH = (PemHeader)headers.get(i); if (pemH.getName().equals("DEK-Info")) { String v = pemH.getValue(); for (int j = 0; j != v.length(); j++) { if (v.charAt(j) >= 'a' && v.charAt(j) <= 'f') { fail("lower case detected in DEK-Info: " + v); } } } } PEMReader pr = new PEMReader(new StringReader(data), new Password(testPassword), provider); Object o = pr.readObject(); if (o == null || !(o instanceof KeyPair)) { fail("Didn't find OpenSSL key"); } KeyPair kp = (KeyPair) o; PrivateKey privKey = kp.getPrivate(); if (!akp.equals(privKey)) { fail("Failed to read back test key encoded with: " + algorithm); } } public static void main( String[] args) { Security.addProvider(new BouncyCastleProvider()); runTest(new WriterTest()); } } bouncycastle-1.49.orig/test/src/org/bouncycastle/openssl/test/pkcs7.pem0000644000175000017500000000647610330633061025665 0ustar ebourgebourg-----BEGIN PKCS7----- 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 4oX2oNPE9Vr3H9Y8YaVoeUU+Kiqo5g== -----END PKCS7----- bouncycastle-1.49.orig/test/src/org/bouncycastle/openssl/test/smimenopw.pem0000644000175000017500000000325511603245102026643 0ustar ebourgebourg-----BEGIN PRIVATE KEY----- MIIEwAIBADANBgkqhkiG9w0BAQEFAASCBKowggSmAgEAAoIBAQDH3KYztc7w23de H/eCb/a9GcKKJhUMegKaBy8CqEbkMB4ft+JRnkma/z/xZgrcqw3GOjE/iZTV6+8s +FZlMpSY8h0Zqs4c/achV0d1QwI/udNgB83iI4KtoOf4BYDmehp0MntBLL5q/qZ4 QqZdSI4HeNWVSUZPBVqtDjd2qOmYPgxPPg2uqDM2kus1kXaXXrGx7bnNSckwNiMl c270sM7sZBjE0Kfspp78cAHbBkTwUHIGtohwxsC89tShXK9lddkX21MHCsJSm7sJ URdbrrimt/gHeXzHMJ4dJCY/kyMUealAVYgPHGpSzNOqxzrg06rptpwEP5S/Ezqz hxU13QCrAgMBAAECggEBAMOYc6ejxHT/s+CQFGC5RpZmgXdGMc9WEPnBEgbdvRNQ 7ApKodkSuiJQr7mGDhdL6F0ZUl1GPjzle9tc5uB/EeJlAInAGZtRuqDsk+h0vdyz 9ePDf4BTFG7sTFj0uePVl9IkHW/5ZBm+Qhjr0Xj1qtoxLYW+gmqPaOB4S1t7j7EH PGbPeGWEYkMpK6qHuu18/YG52VrEzeYW5QoCzXn5m9tcc3xQH7AlE8dQu9B1oxoB Yiau/FSt3wrjhSWAAf390xDqF+4G9nkpdqv/jjLDxoY2HlFojrc3YysfAHzbVqrW vckvzW/h/kVACghrIZRucRukNuBEewOp5HOdxx5HkDECgYEA9C/PzD8YYfa+CXJ4 a7NbmBuhZ4k1OrCmuoXnVXzhOA0+wWrV/w4sHEb9L753v7hldmr3F2PFBgGzwABY af0COWB0mdICtbBUPjbFdZHZzMyJU2YmmhrwAs6zE6nvDjYLSa5SEAdoT/DgDqMZ P3zE7dTkClriwZDk7LWneOhuEMUCgYEA0YfizrYSFNVcAt4vkncovihKN7JerqAc X0mpPRupR9aUQCylfcTXv/WKT0DAu965asbDNJcsCg+3uZTKWZzJnDmYjHSF4Ulw ZmivTmgroAw7UVDSZN1zKwjSuDhOkFaCtgIeErCbCVegN7NuwBal/YSfydWjQH8A wyxI1ChmAq8CgYEAgLlDnbQVMm9UNr61ZHEkc8b9Cwt1l/7Ppbw4+wPd5iJ1Vpjv PolGD5IMnkKV9edK9WXl49qgXk4/Z5PHB/hsV7rVPNFMxGKzxigxZ4z/d8rLCb/r 0YkpxREZreADOUacJLdUY0bEYn/kXVL1WFZ5qbZ0kFDhAJFVXMNWCZLdktECgYEA pmEIsKvS38gsL/rOO7dzGsxTYra4iGGLJf8P6/4zBWBWiD7rilrsFvmawiPg502M XkVGbFQ+HB8u/KYxp8bgMLVrdNxyEtqF7kviKJh/S69qyr8q0f0mnl17Nd1ARUzs riowRxcFhP2Xs6M/pjhVxmGxoEuMPoKa0GAx1IXfuvECgYEAgu23j5zdu2oR+/3k dcmXd1bs41RS9sQoYrb1lvQILMvKqJG7HUiLs9bKdPjF+9Vd6T7jyf1Ay5CL8ioA NxU3DkmF1fZOByyQJRbGXhMhlN4ldzFiL9TsA4ZUUlH1ZmHHZuZUF2yJwtn8NpIl MuSVFLFRIjw+o2GuDZ6/7cafRfk= -----END PRIVATE KEY----- bouncycastle-1.49.orig/test/src/org/bouncycastle/openssl/test/eckey.pem0000644000175000017500000000054710540143556025737 0ustar ebourgebourg-----BEGIN EC PARAMETERS----- BgUrgQQAIg== -----END EC PARAMETERS----- -----BEGIN EC PRIVATE KEY----- MIGkAgEBBDCSBU3vo7ieeKs0ABQamy/ynxlde7Ylr8HmyfLaNnMrjAwPp9R+KMUE hB7zxSAXv9KgBwYFK4EEACKhZANiAQQyyolMpg+TyB4o9kPWqafHIOe8o9K1glus +w2sY8OIPQQWGb5i5LdAyi/SscwU24rZM0yiL3BHodp9ccwyhLrFYgXJUOQcCN2d no1GMols5497in5gL5+zn0yMsRtyv5o= -----END EC PRIVATE KEY----- bouncycastle-1.49.orig/test/src/org/bouncycastle/openssl/test/package.html0000644000175000017500000000012210330633061026372 0ustar ebourgebourg Test class for OpenSSL PEMReader. bouncycastle-1.49.orig/CONTRIBUTORS.html0000644000175000017500000011346612147602534017273 0ustar ebourgebourg The following organisations and people have contributed to the Bouncy Castle Cryptography Package.

    Thanks, may your castles never deflate!

    Organisations

    • Atlassian Software Systems donation of Confluence and JIRA licences.
    • TU-Darmstadt, Computer Science Department, RBG, for the initial lightweight client side TLS implementation, which is based on MicroTLS. MicroTLS was developed by Erik Tews under the supervision of Dipl.-Ing. Henning Baer and Prof. Max Muehlhaeuser.
    • TU-Darmstadt, Computer Science Department, RBG, for the initial Post Quantum provider, which was based on the FlexiProvider. The FlexiProvider was developed by the Theoretical Computer Science Research Group at TU-Darmstadt, Computer Science Department, RBG under the supervision of Prof. Dr. Johannes Buchmann. More information on the history of FlexiProvider can be found at: http://www.flexiprovider.de/
    • Voxeo Labs - sponsorship of the initial development of APIs for DTLS 1.0 (RFC 4347), DTLS-SRTP key negotiation (RFC 5764), and server side TLS 1.1 (RFC 4346) and tested WebRTC compatibility. More information on Voxeo Labs can be found at http://voxeolabs.com
    People
    • Tito Pena <Fortunato.Pena@AdNovum.CH> - initial RC5 implementation
    • Michael Lee <yfl@mira.net> - initial RC6 implementation, MD2 implementation
    • Nuno Santos <nsantos@student.dei.uc.pt> - finding toString bug in certificate object.
    • Brett Sealey <bretts@mortbay.com> - fixing the missing return problem in JDKKeyFactory (affected SSLeay private keys).
    • Victor A. Salaman <salaman@teknos.com> - fixing the bug in Cipher.java which caused it to ignore specified providers, fixing the bug in RSAKeyGenerator which caused keys to be occasionally produced 1 bit too small.
    • Eran Librach <eranl@valicert.com> - spotting and fixing the classLoader bug that occurs if javax.crypto and the provider aren't sharing the same classpath (occurs in JDK 1.3 and greater).
    • Jonathan Knudsen <jonathan@LearningPatterns.com> - porting information and restrictions when using the lightweight library with the MIDP environment.
    • Markus Niedermann <markus.niedermann@softwired-inc.com> - porting information and restrictions when using the lightweight library with the MIDP environment.
    • Mike Benham <moxie@thoughtcrime.org> - detection and fixing of an incorrect weak key in the DES key generation support classes. Suggestions for simplifying DESedeParameter objects. Optimisations for the Blowfish engine and BufferedBlockCipher class.
    • Soren Hilmer <hilmer@mail.tele.dk> - initial implementation of netscape certificate request classes.
    • Uwe Guenther <uwe@cscc.de> - detection and fixing of 3 incorrect semi-weak keys in the DES key generation support classes.
    • Markus Bradtke <mab@informatik.uni-kiel.de> - fixing of a logic error in the JDKKeyStore class.
    • Waclaw Sierek <waclaw.sierek@tpg.pl> - fix to setOddParity in the DESParameter class. Assistance with adding ordering to X509 names for certificate generation, proper processing of byte strings in the ASN1 package, further simplifications and additional classes to improve pkcs7 support, bug fixes in CertPath API.
    • Ly-Na Phu <lyna.phu@init-consulting.de> - assistance in the addition of ISO 9796-1 padding.
    • Stefan Köpsell <sk13@mail.inf.tu-dresden.de> - making the jdk 1.1 version of the collections API available. For further details see http://sourceforge.net/projects/jcf/
    • Carmen Bastiaans <cbastiaa@microbits.com.au> - fixing the improper null pointer problem in the setting of certificates in the PKCS12 key store.
    • Tomas Gustavsson <tomasg@primekey.se> - initial implementation of the AuthorityInformationAccess, SubjectKeyIdentifier, AuthorityKeyIdentifier, CRLNumber, CRLReason, CertificatePolicies, V2TBSCertListGenerator, and X509V2CRLGenerator classes in the ASN.1 library. Additions to GeneralName class, other bug fixes in the X.509 package. Initial implementation of the CertificationRequest classes. getRevocationReason() patch for OCSP. Patch to SemanticsInformation to prevent ClassCastException.
    • Eugen Kuleshov <euxx@hotmail.com> - optimisations for Blowfish, assistance with PKCS12/keytool interoperability.
    • Megan Woods <meganwoods@sekurafile.com> - initial implementation of ECIES.
    • Christian Geuer-Pollmann <geuerp@apache.org> - adding IV's to the AESWrap implementations. Initial implementation of DESedeWrap.
    • Michael Mühle <michael@mouling.de> - contributing the initial CertPath implementation and compatibility classes, fixing provider bug in JDK 1.1 java.security.cert.CertificateFactory compatibilty class.
    • Michael Mansell <me@michaelmansell.com> - fixing the parsing of the empty DER set in the ASN.1 library.
    • Eike Recker <eike.recker@gmx.de> - fixing misspelling of provider reference for RSA/1 and RSA/2.
    • Chris Southern <CSouthern@baltimore.com> - fixing misuse of specified provider in the PKCS10 certification request class.
    • Sidney Markowitz <sidney@sidney.com> - fixing null pointed exception on unknown OID in X509Name class, initial implementation of the three AES engines.
    • Chris Kerr <ckerr@filonet.ca> - initial implementation of the cms, asn1.cms, and the mail/smime packages, assistance in simplifying the ASN.1 package, miscellaneous other optimisations, NIST CertPath certification test, PKIXPolicyNode class, CertPath subtree validation and policy tree construction. We also wish to acknowledge the generosity of Filonet Corporation for allowing Chris to make the initial cms and mail/smime packages available to us.
    • Mike Bean <mbean@lucentradius.com> - fixing the fall through bug in the IV algorithm parameters class.
    • Martin Petraschek <e9526225@student.tuwien.ac.at> - fixing ASN1 tagging so tag values up to 30 are now supported.
    • Jess Garms <jgarms@yahoo.com> - fixing 112/168 key size bug for DESede key generation.
    • Mike Bremford <mike@big.faceless.org> - contributing the inital PKCS7 implementation.
    • Shankar Srinivasan <ssr002@yahoo.com> - S/Mime interoperability testing and debugging.
    • Stef Hoeben <ilsestef@skynet.be> - adding Montgomery multiplication to the BigInteger class.
    • Klaudiusz Ciosk <kciosk@max.com.pl> - improving the compatibility of the SMIME package with the Sun JCE.
    • Thomas Houtekier <Thomas.Houtekier@tectrade.net> - S/Mime testing and debugging. Interoperability with Biztalk.
    • Don Hillsberry <hillsber@dialcorp.com> - S/Mime testing and debugging.
    • Kazuo Furuya <kfuruya@infoteria.co.jp> - fixing root certificate chaining bug in PKCS12 key store.
    • Jason Novotny <jdnovotny@lbl.gov> - initial work on the openSSL PEM processing.
    • Joel Hockey <joel.hockey@qsipayments.com> - initial work on the openSSL PEM processing.
    • John Steenbruggen <JohnS@geotrust.com> - fixing CertificationRequestInfo to handle cert request info objects without attribute blocks.
    • Justin Chapweske <justin@chapweske.com> - ordering patch for Tiger message digest.
    • John Serock <jserock@hotmail.com> - fixing null pointer exception in constructor for ExtendedKeyUsage. Fixing of base OID bug in KeyPurposeId. Compliance of KeyUsage extension return value with security API.
    • Sascha Weinreuter <Sascha.Weinreuter@cit.de> - fixed SMIME saveChanges() bug.
    • Andre Wehnert <aw5@mail.inf.tu-dresden.de> - fixing key schedule problem in RC5-64, fixing buffer cleaning issue in buffered block cipher.
    • Luigi Lo Iacono <lo_iacono@nue.et-inf.uni-siegen.de> - adding SIC mode to the blockciphers in the provider.
    • Tim Sakach <tsakach@certivo.net> - SMIME v2 compatibility patches.
    • Marcus Povey <mpovey@brookes.ac.uk> - adding the PGP mode to the lightweight API and the provider.
    • Sebastian Clauß <sc2@inf.tu-dresden.de> - adding randomness setting to the certificate and CRL generators.
    • Nicolas Bielza <nicolas.bielza@alligacom.com> - isolating the tagging bug in the ASN.1 library that was misrepresenting some ASN.1 constructed data types. Contributions to the streaming S/MIME classes.
    • Casey Marshall <rsdio@metastatic.org> - fixing the clone problem with Macs in the clean room JCE.
    • Rick Zeldes <rick.zeldes@eds.com> - initial code for CMS/SMIME CompressedData.
    • Jarek Gawor <gawor@mcs.anl.gov> - fixing ASN.1 sequence unpacking in BasicConstraints constructor.
    • Brett Neumeier <random@rnd.cx> - patch to OriginatorIdentifierOrKey object, improvements to encoders package, introduction of UrlBase64.
    • Graham Coles <graham.coles@retail-logic.com> - patch to isParityAdjusted in DESKeySpec.
    • Jörn von Kattchée <J.Kattchee@seeburger.de> - patch to SMIMEGenerator for preventing class cast exceptions with BodyParts containing Multipart objects.
    • Matteo Artuso <matartuso@libero.it> - picking up the possible overead in ASN1InputStream.
    • Julian Morrison <julian@extropy.demon.co.uk> - spotting the slow down in Diffie-Hellman key generation.
    • Elmar Sonnenschein <eso@esomail.de> - fix to long conversion in clean room SecureRandom.
    • Jörn Schwarze <JSchwarze@ulc.de> - Locale fix for the clean room JCE.
    • Bryan Lovquist <bkl@cps.com.au> - Other provider compatibility fixes for CMS signing.
    • Artem Portnoy <Artem_Portnoy@ibi.com> - generalisations for CMSProcessableBodyPart in S/MIME. Header fix for mime messages.
    • Michael Häusler <haeusler@ponton-consulting.de> - missing OID update for SHA1 with RSA Signature.
    • Johan Seland <johans@netfonds.no> - general toString for BigInteger class.
    • Johannes Nicolai <johannes.nicolai@novosec.com> - further enhancements to OCSP response generation, fix to CertificateID issuer.
    • Marc Doberva <marc.doberva@ilex-si.com> - help in isolating the JSSE/BC RSA key issue.
    • Jan Dvorak <jan.dvorak@mathan.cz> - initial implementation of the light weight Null block cipher.
    • Joe Cohen <jcohen@forumsys.com> - converting the ArrayOutOfBoundsException in DERInputStream into what it should have been.
    • Chris Long<aclong@ece.cmu.edu> - adding public key decoding to PEMReader.
    • Hes Siemelink<hes@izecom.com> - findIssuer fix for CertPathBuilder, toMimeMessage converter for Mail API, getSize() fix for zero length messages in SMIMEMessage.
    • Stefan Puiu<stefanpuiuro@yahoo.com> - initial implementation V3 policy mapping, policy qualifier objects in ASN.1 X.509 package.
    • Kaiser Yang <kaiseryang@yahoo.com> - Finding BigInteger loop problem in prime generation.
    • Jiri Urbanec <jiri.urbanec@logicacmg.com> - patch to fix defect in DERBMPString.equals().
    • Justin Kolb <jkolb@pristx.com> - patch to DSA signature generation in OpenPGP. Fix for the unexpected "Unexpected end of ZLIB input stream" exception.
    • Ralf Hauser <ralfhauser@gmx.ch> - patch to exception handling in PublicKeyRing, PEMReader, 1.4 build script, X509 Certificate Factory, CertPathValidatorUtilities.
    • Michal Dvorak <M_Dvorak@kb.cz> - getNextUpdate patch for OCSP SingleResp.
    • Klaus Greve Fiorentini <Klaus@cpqd.com.br> - array fix in PGP PublickKeyEncSessionPacket.
    • Olivier Refalo <Olivier_Refalo@fpl.com> - null pointer exception fix for JDK 1.3 CMSSignedData objects.
    • Mariusz Bandola <mariusz.bandola@cryptotech.com.pl> - patch to DERGeneralizedTime. Compliance patch for OCSP TBSRequest class. Patch to X509Name for delaing with general objects in sequences.
    • Brien Oberstein <brien.oberstein@transacttools.net> - patch to S2K algorithm in OpenPGP, initial PGP version 3 secret key support, initial PGP version 3 signature generation, RIPEMD160 addition to PGPUtil.
    • Ian Haywood <ian@haywood.bpa.nu> - addition of getSignatureType to PGPSignature.
    • Jonathan Edwards <s34gull@mac.com> - initial support for reading multiple rings from a PGP key file.
    • Andrew Thornton <andrew@caret.cam.ac.uk> - patch for RSA PUBLIC KEY in PEMReader.
    • Gregor Leander <gl@bos-bremen.de> - initial parsing of multiple sequence entries in an X.500 Name.
    • Antoon Bosselaers <Antoon.Bosselaers@esat.kuleuven.ac.be> - help with RipeMD320 implementation.
    • Peter Sylvester <Peter.Sylvester@edelweb.fr> - improvements to the ASN.1 BasicConstraints object.
    • Doug <ummmmm@myrealbox.com> - addition of isEncryptionKey method to OpenPGP public keys.
    • Francois Staes <fstaes@netconsult.be> - improvements to DEBitString, DERGeneralizedTime and initial implimentation of DERGeneralString, addition of settable signed content info to CMSSignedDataGenerator, patch to DH key agreement.
    • W.R. Dittmer <wdittmer@cs.vu.nl> - patch to decoding of SignatureCreationTime in BCPG. Patch to PGPKeyPair to fix nullpointer exception.
    • Perez Paz Luis Alberto <laperez@banxico.org.mx> - patch to use of BitString in X.500 name.
    • James Wright <James_Wright@harte-hanks.com> - patches for dealing with "odd" ArmoredInputStreams.
    • Jim Ford <jim@muirford.com> - patch to PGPSecretKey to avoid null pointer exception on encoding secret keys, comments on KeyExpirationTime, getBitStrength for ElGamal keys. Signature creation time patch for newly created v4 signatures.
    • Michael Hausler <haeusler@ponton-consulting.de> - extra aliases for provider.
    • Sai Pullabhotla <psai@linoma.com> - fix to PGP compressed data generator to improve compression levels. Performance improvements for KeyBasedLargeFileProcessor.
    • Joseph Miller <joseph@digiweb.net.nz> - addition of ZeroBytePadding.
    • Lars <xyz@sagemdenmark.dk> - patch to explicit padded mode for CBC block cipher MAC.
    • Jeroen van Vianen <jeroen@vanvianen.nl> - the Signed and Encrypted mail example.
    • Jun Sun <JSun@diversinet.com> - patch to SecureRandom to work around problem in wtk 1.0.4 and wtk 2.1.
    • Petr Dukem <pdukem@email.cz> - patch to CMSSignedDataGenerator to allow it to work with PKCS11 providers.
    • Filipe Silva <filipe.silva@wedoconsulting.com> - patch to fix overead issue in BCPGInputStream.
    • Alpesh Parmar <alps@linuxmail.org> - patch for class cast problem in PGPPublicKey.getSignatures().
    • Jay Gengelbach <jgengelbach@webmethods.com> - patch to fix isSigningKey in PGPSecretKey class, patch to hashedPackets in PGP signatureGenerator, initial cut for indefinite length output.
    • Doug <doug@tigerprivacy.com> - public key ring patches for ElGamal Signatures, problem key ring data.
    • Matthew Mundy <mmundy1@umbc.edu> - infinite loop prevention patch to PKCS5S2ParametersGenerator.
    • Tom Cargill <cargill@profcon.com> - spelling patch in provider.
    • Breitenstrom Christian <C.Breitenstrom@t-systems.com> - compatibility patch to SignaturePacket, DetachedSignatureProcessor.
    • Zanotti Mirko <zanotti@cad.it> - patch to ordered equality test for X509Name.
    • Nicola Scendoni <nscendoni@babelps.it> - patch to add sorting to CertPath validation.
    • Ville Skyttä <ville.skytta@iki.fi> - patch to CRLDistPoint for cRLIssuer field. KeyStore compliance on add patches. DiffieHellman patch for provider compliance. Exception handling patch in PEMReader.
    • Bruce Gordon <bruce.gordon@savvis.net> - patch to secret key creation encoding NullPointerException in OpenPGP, speed up for BCPGInputStream.
    • Miles Whiteley <Miles.Whiteley@savvis.net> - "223" fix for BCPGInputStream new packets.
    • Albert Moliner <amoliner@evintia.com> - initial TSP implementation.
    • Carlos Lozano <carlos@evintia.com> - initial TSP implementation, patch to SignerInformation for supporting repeated signers, initial updates for supporting repeated attributes in CMS.
    • Javier Delgadillo <javi@javi.codewarp.org> - initial Mozilla PublicKeyAndChallenge classes.
    • Joni Hahkala <joni.hahkala@cern.ch> - initial implementations of VOMS Attribute Certificate Validation, IetfAttrSyntax, and ObjectDigestInfo. We also wish to thank the EGEE project for making the work available.
    • Rolf Schillinger<rolf@sir-wum.de> - initial implementation of Attribute Certificate generation.
    • Sergey Bahtin <Sergey_Bahtin@yahoo.com> - fix for recovering certificate aliases in BKS and UBER key stores. Initial implementations of GOST-28147, GOST-3410, EC GOST-3410, GOST OFB mode (GOFB) and GOST-3411.
    • Franck Leroy <Franck.Leroy@keynectis.com> - ANS.1 set sorting. Contributions to TSP implementation. Test vectors for Bleichenbacher's forgery attack.
    • Atsuhiko Yamanaka <ymnk@jcraft.com> - patch for improving use of Montgomery numbers in BigInteger library. Patch to use size of private exponent in DH parameters.
    • Nickolay Bolshackov <tyrex@reksoft.ru> - patch for class cast exception in AuthorityInformationAccess class.
    • Soren Hilmer <soren.hilmer@tietoenator.com> - patches for CertID with issuerSerial set in TSP implementation, additional compliance testing.
    • Steve Mitchell <mitchell@intertrust.com> - patch for stateful path validator fix. Patch to allow BigInteger class to create negative numbers from byte arrays. Additions to allow different providers to be used for asymmetric/symmetric encryption in OpenPGP. Optimisation to avoid redundant verification in path validator. Suggestion to use PKIXParameters.getSigProvider() correctly.
    • Dirk Eisner <D.Eisner@seeburger.de> - initial implementation of ISO 78164-4 padding.
    • Julien Pasquier <julienpasquier@free.fr> - initial implementation of attribute classes from RFC 3126. Fix to KEKIdentifier, OtherKeyAttribute parsing. Initial ContentHints class.
    • Matteo <matartuso@libero.it> - sequence patch to ASN1Dump.
    • Andrew Paterson <andrew.paterson@burnsecs.com> - patches to PGP tools, isRevoked method on PGPPublicKey.
    • Vladimir Molotkov <vladimir.n.molotkov@intel.com> - extensive provider exception handling compliance testing.
    • Florin Kollan <adlocflo@web.de> - fix to ElGamalKeyParameters equality testing.
    • Pavel Vassiliev <paulvas@gmail.com> - Initial GOST28147Mac implementation.
    • Tom Pesman <tom@tnux.net> - addition of DES-EDE encryption for RSAPrivate keys to PEMWriter.
    • Lukasz Kowalczyk <lukasz.b.kowalczyk@gmail.com> - patch to fix parsing issue with OpenSSL PEM based certificate requests.
    • Arndt Hasch <Arndt.Hasch@maxence.de> - additional fix for partial reading with new style PGP packets.
    • Fix Bernd (KCDP 11) <bernd.fix@credit-suisse.com> - fix for 31 byte issue and exception throwing by Whirlpool.
    • David M. Lee <dmlee@Crossroads.com> - code for add and remove secret key in the PGPSecretKeyRing class. Additions to S/MIME and CMS unit tests.
    • Mike Dillon <md5@embody.org> - additional checks for PGP secret and public key construction, patches to copyWithNewPassword.
    • tu-vi cung <t2cung@hotmail.com> - patch for out of bounds problem in getDecoderStream method.
    • Chris Schultz <cschultz@gmail.com> - fix for InputStream constructor for X509V2AttributeCertificate.
    • David M. Lee <dmlee@Crossroads.com> - implementation assistance with streaming CMS classes.
    • Joel Rees <rees@ddcom.co.jp> - fix to correct getOID methods from returning same set on X.509 attribute certificates.
    • Francesc Sau <francesc.sau@partners.netfocus.es> - micro fix for tsp Accuracy class.
    • Larry Bugbee <bugbee@mac.com> - initial ECNR implementation.
    • Remi Blancher <Remi.Blancher@keynectis.com> - Contributions to TSP implementation. Initial implementation of RFC 3739 and ICAO ASN.1 classes.
    • Brian O'Rourke <brianorourke@gmail.com> - patch for signature creation time override in OpenPGP.
    • Andreas Schwier <andreas.schwier@cardcontact.de> - initial implementation of ISO9797 MAC Algorithm 3, addition of DES-EDE 64 MAC to the provider, fix to EC point encoding, addition of EC and RSA-PSS OIDs to CMS, addition of AES-CMAC and DESede-CMAC to JCE provider.
    • David Josse <david.josse@transacttools.net> - Patch for trailer function in version 2 signature packets.
    • Kishimoto Kazuhiko <kazu-k@hi-ho.ne.jp> - RFC 3280 updates to policy processing in the CertPath validator. Additional test data not covered by NIST.
    • Lawrence Tan <lwrnctan@gmail.com> - Large field OID sample test data. Missing key types in JDKKeyFactory.
    • Carlos Valiente <superdupont@gmail.com> - Addition of CRL writing to the PEMWriter class.
    • Keyon AG, Martin Christinat, http://www.keyon.ch - fixing incorrect ASN.1 encoding of field elements in X9FieldElement class.
    • Olaf Keller, <olaf.keller.bc@bluewin.ch> - initial implementation of the elliptic curves over binary fields F2m. Additional tests and modifications to elliptic curve support for both F2m and Fp. Performance improvements to F2m multiplication. Initial implementation of WNAF/WTNAF point multiplication. Improvement to k value generation in ECDSA.
    • Jörg Eichhorn <eichhorn@ponton-consulting.de> - patch to fix EOF read on SharedFileInputStream, support for F2m compression.
    • Karsten Ohme <widerstand@t-online.de> - initial check against for out of range data on non byte aligned RSA keys. Addition of equals/hashCode on ECCurve.Fp. Additional curve type support for Fp, contributions to F2m compression. F2m decoding for ECPointUtil. Infinity fix and prime192v2 fix for Fp. Extra validation for RSA key creation. Fix to name typos for some OpenSSL key generators. RFC-1779 table, improved RFC 2253 compliance for X509Name. Additional constructor validation for X.509/ESS ASN.1 classes. Validation for Printable, IA5, and Numeric Strings. Support for surrogate pairs in DERUTF8String, DER UTF8 test. Additional X.509 name attributes for ISIS-MTT, RFC 3039, addition of indirect CRL support, initial X509 LDAP CertStore implementation, CertificatePair class, and X509CertificatePair class. Contributions to X509Store/Parser infrastructure and design. CertPath support for implicit DSA parameters and a range of NameConstraints. Addition of support for V1 attribute certificates and attribute certificate path validation. Initial classes for ASN.1 ISIS-MTT support. Enhancements for improving compliance with the NIST CertPath tests.
    • Carlos Lozano Ruiz <carlos@tradise.com> - patch for <ctrl><m> only handling in CRLFOutputStream.
    • John Alfred Prufrock <j.a.prufrock@gmail.com> - mods to GOST-3411 and MD2 to support ExtendedDigest.
    • Stefan Neusatz Guilhen <sneusatz@gmail.com> - initial version of RoleSyntax, improvements to AttributeCertificateHolder and AttributeCertificateIssuer.
    • Marzio Lo Giudice <marzio.logiudice@gmail.com> - fix to endianess in KDF2BytesGenerator, additional KDF2 tests.
    • Georg Lippold <georg.lippold@gmx.de> - initial implementation of NaccacheStern cipher.
    • Chris Viles <chris_viles@yahoo.com> - fix to SignatureSubpacket critical bit setting.
    • Pasi Eronen <Pasi.Eronen@nokia.com> - extra toString() support for ASN.1 library. Initial patch for large OID components.
    • Lijun Liao <lijun.liao@rub.de> - performance enhancements for SHA family of digests. Bug report and patch for blank line handling in ArmoredInputStream.
    • Maria Ivanova <maria.ivanova@gmail.com> - support for tags > 30 in ASN.1 parsing.
    • Armin Häberling <arminha@student.ethz.ch> - first cut of internationalisation, initial PKIX validation classes.
    • Marius Schilder <mschilder@google.com> - main set of test vectors for Bleichenbacher's forgery attack.
    • Xavier Le Vourch <xavier@brittanysoftware.com> - general code clean ups.
    • Erik Tews <e_tews@cdc.informatik.tu-darmstadt.de> - initial threaded random seed generator.
    • Thomas Dixon <reikomusha@gmail.com> - initial implementations of TEA/XTEA, Salsa20, ISAAC, and Noekeon. XTEA enhancements.
    • Frank Cornelis <info@frankcornelis.be>- addition of crlAccessMethod in X509ObjectIdentifiers.
    • Rui Joaquim <rjoaquim@cc.isel.ipl.pt> - initial implementation of RSA blinding for signatures.
    • David Stacey <DStacey@allantgroup.com> - addition of trust packet checking on revocation signatures in PGPSecretKeyRing.
    • Martijn Brinkers <list@mitm.nl> - better exception handling in CMS enveloping, "just in time" modifications for CRL and Sequence evaluation.
    • Julius Davies <juliusdavies@gmail.com> - additional modes and algorithm support in PEMReader
    • Matthias <g@rtner.de> - GnuPG compatibility changes for PBEFileProcessor.
    • Olga Käthler <olga.kaethler@hjp-consulting.com> - initial implementation of TeleTrusT EC curves, additional ISO 9797 MACs, contributions to EAC OIDs, addition of EAC algorithms to CMS Signing.
    • Germano Rizzo <germano.rizzo@gmail.com> - initial implementation of CMac, EAX, HC-128, and HC-256, optimisations for Salsa20.
    • Núria Marí <numaa@hotmail.com> - patch for alternate data type recoginition in CMSSignedDataParser.
    • Janis Schuller <js@tzi.de> - addition of NotationData packets for OpenPGP.
    • Michael Samblanet <mike@samblanet.com> - patches towards improved Sun/default provider support in CMS.
    • Mike StJohns <mstjohns@comcast.net> - patches for supporting empty subject in X.509 certificate generation, noneWithECDSA.
    • Ramon Keller <ramon.keller@gmx.ch> - patch to deal with null revocations return from other CRL in X509V2CRLGenerator.
    • Mark Nelson <mark@nbr.com> - correction to excluded DN in name constraints processing for PKIX processing.
    • Eugene Golushkov <eugene_gff@ukr.net> - mask fix to single byte read in TlsInputStream.
    • Julien Pasquier <julienpasquier@free.fr> - additional classes for supporting signature policy and signer certificates in the ASN.1 esf and ess libraries.
    • Peter Knopp <pknopp@mtg.de> - fix for named curve recognition in ECGOST key generation.
    • Jakub Gwozdz <gwozdziu@rpg.pl> - addition of getTsa() to TimeStampTokenInfo.
    • Bartosz Malkowski <bmalkow@tigase.org> - initial implementation of VMPC cipher, VMPCRandomGenerator, VMPCMac.
    • Tal Yacobi <tal.yacobi@octavian-tech.com> - fix for issue in OpenPGP examples [#BJA-55].
    • Massimiliano Ziccardi <massimiliano.ziccardi@gmail.comt> - support for counter signature reading in CMS API, update for multiple counter signature attributes.
    • Andrey Pavlenko <andrey.a.pavlenko@gmail.com> - security manager patch for PKCS1Encoding property check.
    • Mike StJohns <mstjohns@comcast.net> - updates to KeyPurposeId
    • J Ross Nicoll <jrn@jrn.me.uk> - improved exception handling for getInstance() in ASN.1 library.
    • Matthew Stevenson <mavricknz@yahoo.com> - patch to construtor for CRMF CertSequence.
    • Gabriele Contini <gcontini@hotpop.com> - identified a bug in ASN.1 library with handling of unterminated NDEF's.
    • Roelof Naude <roelof.naude@epiuse.com> - patch for TLS client to send empty client certs in response to HP_CERTIFICATE_REQUEST.
    • Patrick Peck <peck@signaturen.at> - identified problem with DERApplicationSpecific and high tag numbers in ASN.1 library.
    • Michael LeMay <lemaymd@lemaymd.com> - identified problem with EAX [#BJA-93].
    • Alex Dupre <ale@FreeBSD.org> - fix to use of Signature rather than SignatureSpi in provider [#BJA-90]. Addition of null provider use to SignedPublicKeyAndChallenge and PKCS10CertificationRequest [#BJA-102]
    • Michael Schoene <michael@sigrid-und-michael.de> - fix of improper handling of null in ExtendedPKIXParameters.setTrustedACIssuers(), check for V2 signingCertificate attribute in TimeStampResponse.validate().
    • Ion Larrañaga <ilarra@s21sec.com> fix to default partial packet generation in BCPGOutputStream.
    • Bob Kerns <bob.kerns@positscience.com> fix to hashCode for X509CertificateObject.
    • Stefan Meyer <stefan.meyer@ewe.de> backport for PKIXCertPathValidotor and SMIMESignedMailReviewer.
    • Robert J. Moore <Robert.J.Moore@allanbank.com> speedups for OpenPGPCFB mode, clean room JCE patches.
    • Rui Hodai <rui@po.ntts.co.jp> speed ups for Camellia implementation, CamelliaLightEngine.
    • Emir Bucalovic <emir.bucalovic@@mail.com> initial implementation of Grain-v1 and Grain-128.
    • Torbjorn Svensson <tobbe79@gmail.com> initial implementation of Grain-v1 and Grain-128.
    • Paul FitzPatrick <bouncycastle_pfitz@fitzpatrick.cc> error message fix to X509LDAPCertStoreSpi, comparison fix to BCStrictStyle.
    • Henrik Andersson <k.henrik.andersson@gmail.com> addition of UniqueIssuerID to certificate generation.
    • Cagdas Cirit <cagdascirit@gmail.com> subjectAlternativeName fix for x509CertStoreSelector.
    • Harakiri <harakiri_23@yahoo.com> datahandler patch for attached parts in SMIME signatures.
    • Pedro Henriques <pmahenriques@gmail.com> explicit bounds checking for DESKeyGenerator, code simplification for OAEPEncoding.
    • Lothar Kimmeringer <job@kimmeringer.de> verbose mode for ASN1Dump, support for DERExternal.
    • Richard Farr <rfarr.se@gmail.com> initial SRP-6a implementation.
    • Thomas Castiglione <castiglione@au.ibm.com> patch to encoding for CRMF OptionalValidity.
    • Elisabetta Romani <eromani@sogei.it> patch for recognising multiple counter signatures.
    • Robin Lundgren <r737lundgren@gmail.com> CMPCertificate constructor from X509CertificateStructure fix.
    • Petr Kadlec <mormegil@centrum.cz> fix to sign extension key and IV problem in HC-128, HC-256.
    • Andreas Antener <antener_a@gmx.ch> fix to buffer reset in AsymmetricBufferedBlockCipher.
    • Harendra Rawat <hsrawat@yahoo.com> fix for BERConstructedOctetString.
    • Rolf Lindemann <lindemann@trustcenter.de> patch for PKCS12 key store to support more flexible attribute specifications [#BMA-42].
    • Alex Artamonov <alexart.home@gmail.com> name look up patch for GOST-2001 parameters.
    • Mike Lyons <mlyons@layer7tech.com> work arounds for EC JDK bug 6738532 and JSSE EC naming conventions.
    • Chris Cole <chris_h_cole@yahoo.com> identified a problem handling null passwords when loading a BKS keystore.
    • Tomas Krivanek <tom@atack.cz> added checking of Sender header to SignedMailValidator.
    • Michael <emfau@t-online.de> correction of field error in getResponse method in CertRepMessage.
    • Trevor Perrin <trevor@cryptography.com> addition of constant time equals to avoid possible timing attacks.
    • Markus Kilås <markus@primekey.se> several enhancements to TimeStampResponseGenerator.
    • Dario Novakovic <darionis@yahoo.com> fix for NPE when checking revocation reason on CRL without extensions.
    • Michael Smith <msmith@cbnco.com> bug fixes and enhancements to the CMP and CRMF classes, initial Master List classes.
    • Andrea Zilio <andrea.zilio@gmail.com> fix for PEM password encryption of private keys.
    • Alex Birkett <alex@birkett.co.uk> added support for EC cipher suites in TLS client (RFC 4492) [#BJA-291].
    • Wayne Grant <waynedgrant@gmail.com> additional OIDs for PCKS10 and certificate generation support.
    • Frank Cornelis <info@frankcornelis.be> additional support classes for CAdES, enhancements to OCSP classes.
    • Jan Dittberner <jan@dittberner.info> addHeader patch for SMIME generator.
    • Bob McGowan <boab.mcgoo@btinternet.com> patch to support different content and mgf digests in PSS signing.
    • Ivo Matheis <i.matheis@seeburger.de> fix to padding verification in ISO-9796-1.
    • Marco Sandrini <nessche@gmail.com> patch to add IV to ISO9797Alg3Mac.
    • Alf Malf <alfilmalf@hotmail.com> removal of unnecessary limit in CMSContentInfoParser.
    • Alfonso Massa <alfonso.massa@insiel.it> contributions to CMS time stamp classes.
    • Giacomo Boccardo <gboccardo@unimaticaspa.it> initial work on CMSTimeStampedDataParser.
    • Arnis Tartu <arnis@ut.ee> patches for dealing with OIDs with specific key sizes associated in CMS.
    • Janusz SikociÅ„ski <J.Sikocinski@gdzie.pl> addition of Features subpacket support to OpenPGP API.
    • Juri Hudolejev <jhudolejev@gmail.com> JavaDoc fix to CMSSignedDataParser.
    • Liane Velten <liane.velten@hjp-consulting.com> fine tuning of code for DHParameters validation.
    • Shawn Willden <swillden@google.com> additional functionality to PGPKeyRing.
    • Atanas Krachev <akrachev@gmail.com> added support for revocation signatures in OpenPGP.
    • Mickael Laiking <mickael.laiking@keynectis.com> initial cut of EAC classes.
    • Tim Buktu <tbuktu@hotmail.com> Initial implementation of NTRU signing and encryption.
    • Bernd <rbernd@gmail.com> Fix for open of PGP literal data stream with UTF-8 naming.
    • Steing Inge Morisbak <stein.inge.morisbak@BEKK.no> Test code for lower case Hex data in PEM headers.
    • Andreas Schmid <andreas.schmid@tngtech.com> Additional expiry time check in PGPPublicKeys.
    • Phil Steitz <phil.steitz@gmail.com> Final patch eliminating JCE dependencies in the OpenPGP BC classes.
    • Ignat Korchagin <ignat.korchagin@gmail.com> Initial implementation of DSTU-4145-2002.
    • Petar Petrov <p.petrov@bers-soft.com> Testing and debugging of UTF-8 OpenPGP passwords.
    • Daniel Fitzpatrick <daniel.f.nwr@gmail.com> Initial implementation of ephemeral key support for IES, initial implementions of RSA-KEM and ECIES-KEM.
    • Andy Neilson <Andy.Neilson@quest.com>a further patches to deal with multiple providers and PEMReader.
    • Ted Shaw <xiao.xj@gmail.com> patch to MiscPEMGenerator for handling new PKCS10CeriticationRequests.
    • Eleriseth <Eleriseth@WPECGLtYbVi8Rl6Y7Vzl2Lvd2EUVW99v3yNV3IWROG8.fms> speed up for SIC/CTR mode. Provider compatibilty generalisations for EC operations.
    • Kenny Root <kenny@the-b.org> patch for issuerAltName, subjectAltName support in X509CertificateObject
    • Marteen Bodewes <maarten.bodewes@gmail.com> initial implementation of HKDF.
    • Philip Clay <pilf_b@gyahoo.com> Initial implementation of J-PAKE.
    • Brian Carlstrom <bdc@carlstrom.com> compliance patches for some JCA/JCE keystore and cipher classes, miscellaneous code quality improvements, intial provider PBKDF2WithHmacSHA1 SecretKeyFactory.
    • Samuel Lidén Borell <samuel@primekey.se> patch to add DSTU-4145 to DefaultSignatureAlgorithmFinder
    • Sergio Demian Lerner <sergiolerner@certimix.com> pointing out isInfinity issue in ECDSASigner signature verification.
    • Tim Whittington <Tim.Whittington@orionhealth.com> patch to remove extra init call in CMac, Additional of Memoable interface for Digest classes, initial implementation of GMAC.
    • Marcus Lundblad <marcus.lundblad@primekey.se> patch for working arnound JDK jarsigner TSP bug.
    • Andrey Zhozhin <zhozhin@xrm.ru> patch for override of TSP SignerInfo attributes.
    • Sergey Tiunov <t5555d@gmail.com> initial cut of DVCS classes.
    • Damian Kolasa <fatfredyy@gmail.com> ASN1Sequence patch for class cast issue in X9Curve.
    • Ash Hughes <ashley.hughes@blueyonder.co.uk> patches for supporting PGPSecretKeyRing/PGPSecretKeys encodings with empty private keys.
    • Daniel Hirscher <dev@daniel-hirscher.de> patch to support parsing of explicit EC parameters in PEM files.
    bouncycastle-1.49.orig/bouncy.xml0000644000175000017500000000245710262753174016471 0ustar ebourgebourg %Common; ]> &Common; bouncycastle-1.49.orig/build1-00000644000175000017500000000720610426123334015674 0ustar ebourgebourg#!/bin/sh - # # build script for 1.0 - this only includes the lightweight API # if a distribution name is given as an argument the build is placed # in a subdirectory. # # Note: this script expects javadoc for jdk 1.2 to be in your path. # JDKPATH=/opt/jdk1.0.2 # JDK 1.0 location base=$1 version=`echo $base | sed -e "s/\([0-9]\)\([0-9a-z]*\)/\1.\2/"` WINDOWTITLE="Bouncy Castle Cryptography $version API Specification" HEADER="Bouncy Castle Cryptography $version" DOCTITLE="Bouncy Castle $version API Specification" echo "making lightweight release" if test "$base" != "" then mkdir lcrypto-jdk10-$base tar cf - index.html LICENSE.html CONTRIBUTORS.html releasenotes.html specifications.html src/org/bouncycastle/crypto src/org/bouncycastle/util src/org/bouncycastle/asn1 | (cd lcrypto-jdk10-$base; tar xf -) (2>&1 find lcrypto-jdk10-$base -name CVS -exec rm -rf \{\} \; ) > /dev/null rm -f lcrypto-jdk10-$base/src/org/bouncycastle/crypto/test/* rm -rf lcrypto-jdk10-$base/src/org/bouncycastle/crypto/examples rm -f lcrypto-jdk10-$base/src/org/bouncycastle/asn1/test/* (cd jdk1.0; tar cf - * | (cd ../lcrypto-jdk10-$base; cd src; tar xf -)) (2>&1 find lcrypto-jdk10-$base -name CVS -exec rm -rf \{\} \; ) > /dev/null (cd lcrypto-jdk10-$base; mkdir docs; mkdir classes; (2>&1 javadoc -windowtitle "$WINDOWTITLE" -doctitle "$DOCTITLE" \ -header "$HEADER" \ -classpath classes \ -d docs -sourcepath src \ -group "Lightweight Crypto Packages" "org.bouncycastle.crypto*" \ -group "ASN.1 Support Packages" "org.bouncycastle.asn1*" \ -group "Math Support Packages" "org.bouncycastle.math*" \ -group "Utility Packages" "org.bouncycastle.util*" \ org.bouncycastle.asn1 \ org.bouncycastle.asn1.cmp \ org.bouncycastle.asn1.cms \ org.bouncycastle.asn1.cryptopro \ org.bouncycastle.asn1.esf \ org.bouncycastle.asn1.esf \ org.bouncycastle.asn1.ess \ org.bouncycastle.asn1.misc \ org.bouncycastle.asn1.mozilla \ org.bouncycastle.asn1.nist \ org.bouncycastle.asn1.ocsp \ org.bouncycastle.asn1.oiw \ org.bouncycastle.asn1.pkcs \ org.bouncycastle.asn1.sec \ org.bouncycastle.asn1.smime \ org.bouncycastle.asn1.teletrust \ org.bouncycastle.asn1.test \ org.bouncycastle.asn1.tsp \ org.bouncycastle.asn1.util \ org.bouncycastle.asn1.x509 \ org.bouncycastle.asn1.x9 \ org.bouncycastle.math.ec \ org.bouncycastle.crypto \ org.bouncycastle.crypto.agreement \ org.bouncycastle.crypto.digests \ org.bouncycastle.crypto.encodings \ org.bouncycastle.crypto.engines \ org.bouncycastle.crypto.generators \ org.bouncycastle.crypto.io \ org.bouncycastle.crypto.macs \ org.bouncycastle.crypto.modes \ org.bouncycastle.crypto.paddings \ org.bouncycastle.crypto.params \ org.bouncycastle.crypto.signers \ org.bouncycastle.crypto.test \ org.bouncycastle.util.encoders \ org.bouncycastle.util.test) > /dev/null \ PATH=$JDKPATH/bin:$PATH export PATH JAVA_HOME=$JDKPATH export JAVA_HOME echo "compiling" (cd src; javac -d ../classes -classpath ../classes:../src:../jdk1.0:$JDKPATH/lib/classes.zip */*/*.java */*/*/*.java ) (cd src; javac -d ../classes -classpath ../classes:../src:../jdk1.0:$JDKPATH/lib/classes.zip */*/[amu]*/*/*.java) (cd src; javac -d ../classes -classpath ../classes:../src:../jdk1.0:$JDKPATH/lib/classes.zip */*/c*/*/*.java) echo "lightweight regression test" java -classpath classes:$JDKPATH/lib/classes.zip org.bouncycastle.crypto.test.RegressionTest java -classpath classes:$JDKPATH/lib/classes.zip java.math.test.RegressionTest ) fi bouncycastle-1.49.orig/build1-10000644000175000017500000006734212152015376015710 0ustar ebourgebourg#!/bin/sh - # # build script for 1.1 # # If it's given a buildname it creates a subdirectory and places a build in it, # otherwise it just creates the docs and class files. # JDK11PATH=/opt/jdk1.1.8 # JDK 1.1 location base=$1 version=`echo $base | sed -e "s/\([0-9]\)\([0-9a-z]*\)/\1.\2/"` WINDOWTITLE="Bouncy Castle Cryptography $version API Specification" HEADER="Bouncy Castle Cryptography $version" DOCTITLE="Bouncy Castle $version API Specification" if test "$base" != "" -a ! -d lcrypto-jdk11-$base then echo "making lightweight release" mkdir lcrypto-jdk11-$base tar cf - index.html LICENSE.html CONTRIBUTORS.html releasenotes.html specifications.html src/org/bouncycastle/LICENSE.java src/org/bouncycastle/math src/org/bouncycastle/crypto src/org/bouncycastle/util src/org/bouncycastle/asn1 src/org/bouncycastle/pqc/math src/org/bouncycastle/pqc/crypto src/org/bouncycastle/pqc/asn1 | (cd lcrypto-jdk11-$base; tar xf -) (cd test; tar cf - src/org/bouncycastle/crypto src/org/bouncycastle/util src/org/bouncycastle/asn1) | (cd lcrypto-jdk11-$base; tar xf -) (cd jdk1.3; tar cf - org/bouncycastle/asn1) | (cd lcrypto-jdk11-$base/src; tar xf -) (cd jdk1.3 && tar cf - org/bouncycastle/crypto) \ | (cd lcrypto-jdk11-$base/src && tar xf -) (cd jdk1.4; tar cf - org/bouncycastle/util) | (cd lcrypto-jdk11-$base/src; tar xf -) (cd jdk1.1 && tar cf - org/bouncycastle/crypto org/bouncycastle/asn1 org/bouncycastle/crypto ) | (cd lcrypto-jdk11-$base/src && tar xf -) rm -f lcrypto-jdk11-$base/src/org/bouncycastle/crypto/test/AESVector* ( cd lcrypto-jdk11-$base; rm -rf src/org/bouncycastle/math/ntru rm -rf src/org/bouncycastle/crypto/test/ntru rm -rf src/org/bouncycastle/crypto/*/NTRU* rm -rf src/org/bouncycastle/crypto/*/BitStringTest* rm -rf src/org/bouncycastle/crypto/*/IndexGenerator* find src -name AllTests.java -exec rm {} \; rm src/org/bouncycastle/asn1/test/GetInstanceTest.java rm src/org/bouncycastle/asn1/test/ASN1SequenceParserTest.java rm src/org/bouncycastle/asn1/test/OctetStringTest.java rm src/org/bouncycastle/asn1/test/ParseTest.java rm src/org/bouncycastle/crypto/test/GCMReorderTest.java rm src/org/bouncycastle/util/CollectionStore.java rm src/org/bouncycastle/util/Store.java rm src/org/bouncycastle/util/StoreException.java rm src/org/bouncycastle/util/Selector.java rm src/org/bouncycastle/util/StreamParser.java rm src/org/bouncycastle/util/StreamParsingException.java rm -rf src/org/bouncycastle/util/utiltest mkdir classes; mkdir docs; (2>&1 javadoc -windowtitle "$WINDOWTITLE" -doctitle "$DOCTITLE" \ -header "$HEADER" \ -classpath classes \ -group "Lightweight Crypto Packages" "org.bouncycastle.crypto*" \ -group "ASN.1 Support Packages" "org.bouncycastle.asn1*" \ -group "Math Support Packages" "org.bouncycastle.math*" \ -group "Utility Packages" "org.bouncycastle.util*" \ -d docs -sourcepath src \ org.bouncycastle.asn1 \ org.bouncycastle.asn1.cmp \ org.bouncycastle.asn1.cms \ org.bouncycastle.asn1.cryptopro \ org.bouncycastle.asn1.esf \ org.bouncycastle.asn1.ess \ org.bouncycastle.asn1.gnu \ org.bouncycastle.asn1.iana \ org.bouncycastle.asn1.icao \ org.bouncycastle.asn1.misc \ org.bouncycastle.asn1.mozilla \ org.bouncycastle.asn1.nist \ org.bouncycastle.asn1.ocsp \ org.bouncycastle.asn1.oiw \ org.bouncycastle.asn1.pkcs \ org.bouncycastle.asn1.sec \ org.bouncycastle.asn1.smime \ org.bouncycastle.asn1.teletrust \ org.bouncycastle.asn1.test \ org.bouncycastle.asn1.tsp \ org.bouncycastle.asn1.util \ org.bouncycastle.asn1.x509 \ org.bouncycastle.asn1.x9 \ org.bouncycastle.math.ec \ org.bouncycastle.pqc.crypto \ org.bouncycastle.pqc.asn1 \ org.bouncycastle.pqc.math \ org.bouncycastle.crypto \ org.bouncycastle.crypto.agreement \ org.bouncycastle.crypto.commitments \ org.bouncycastle.crypto.digests \ org.bouncycastle.crypto.ec \ org.bouncycastle.crypto.encodings \ org.bouncycastle.crypto.engines \ org.bouncycastle.crypto.generators \ org.bouncycastle.crypto.io \ org.bouncycastle.crypto.kems \ org.bouncycastle.crypto.macs \ org.bouncycastle.crypto.modes \ org.bouncycastle.crypto.paddings \ org.bouncycastle.crypto.params \ org.bouncycastle.crypto.signers \ org.bouncycastle.crypto.tls \ org.bouncycastle.crypto.test \ org.bouncycastle.crypto.examples \ org.bouncycastle.util.encoders \ org.bouncycastle.util.test) > /dev/null \ PATH=$JDK11PATH/bin:$PATH export PATH JAVA_HOME=$JDK11PATH export JAVA_HOME echo "compiling" (cd src/org/bouncycastle; javac -d ../../../classes -classpath ../../../classes:../../../src:$JDK11PATH/lib/classes.zip *.java ; javac -d ../../../classes -classpath ../../../classes:../../../src:$JDK11PATH/lib/classes.zip */*.java; javac -d ../../../classes -classpath ../../../classes:../../../src:$JDK11PATH/lib/classes.zip */p*/*.java javac -d ../../../classes -classpath ../../../classes:../../../src:$JDK11PATH/lib/classes.zip */a*/*.java javac -d ../../../classes -classpath ../../../classes:../../../src:$JDK11PATH/lib/classes.zip */d*/*.java javac -d ../../../classes -classpath ../../../classes:../../../src:$JDK11PATH/lib/classes.zip */e*/*.java javac -d ../../../classes -classpath ../../../classes:../../../src:$JDK11PATH/lib/classes.zip */g*/*.java javac -d ../../../classes -classpath ../../../classes:../../../src:$JDK11PATH/lib/classes.zip */i*/*.java javac -d ../../../classes -classpath ../../../classes:../../../src:$JDK11PATH/lib/classes.zip */m*/*.java javac -d ../../../classes -classpath ../../../classes:../../../src:$JDK11PATH/lib/classes.zip */s*/*.java javac -d ../../../classes -classpath ../../../classes:../../../src:$JDK11PATH/lib/classes.zip a*/t*/*.java javac -d ../../../classes -classpath ../../../classes:../../../src:$JDK11PATH/lib/classes.zip c*/t*/*.java javac -d ../../../classes -classpath ../../../classes:../../../src:$JDK11PATH/lib/classes.zip u*/t*/*.java javac -d ../../../classes -classpath ../../../classes:../../../src:$JDK11PATH/lib/classes.zip */u*/*.java ) echo "lightweight regression test" java -mx512m -classpath classes:$JDK11PATH/lib/classes.zip -Dbc.test.data.home=/home/dgh/bc/java/crypto/test/data org.bouncycastle.crypto.test.RegressionTest ) (2>&1 find lcrypto-jdk11-$base -name CVS -exec rm -rf \{\} \; ) > /dev/null fi if test "$base" != "" -a ! -d jce-jdk11-$base then echo "making JCE release" mkdir jce-jdk11-$base tar cf - index.html LICENSE.html CONTRIBUTORS.html releasenotes.html specifications.html src | (cd jce-jdk11-$base; tar xf -) (cd jce && tar cf - src | (cd ../jce-jdk11-$base; tar xf -)) (cd test/src && tar cf - * | (cd ../../jce-jdk11-$base/src; tar xf -)) (cd test/data && tar cf - org/bouncycastle/asn1 | (cd ../../jce-jdk11-$base/src; tar xf -)) (cd jdk1.4 && tar cf - * | (cd ../jce-jdk11-$base/src; tar xf -)) (cd test/jdk1.4 && tar cf - * | (cd ../../jce-jdk11-$base/src; tar xf -)) (cd jdk1.3 && tar cf - * | (cd ../jce-jdk11-$base/src; tar xf -)) (cd test/jdk1.3 && tar cf - * | (cd ../../jce-jdk11-$base/src; tar xf -)) (cd jdk1.2 && tar cf - * | (cd ../jce-jdk11-$base/src; tar xf -)) (cd jdk1.1 && tar cf - * | (cd ../jce-jdk11-$base/src; tar xf -)) (cd src; tar cf - org/bouncycastle/jce/exception | (cd ../jce-jdk11-$base/src; tar xf -)) (cd src; tar cf - org/bouncycastle/x509/*Exception.java | (cd ../jce-jdk11-$base/src; tar xf -)) ( cd jce-jdk11-$base; mkdir classes; mkdir docs; rm -rf src/org/bouncycastle/crypto/test/ntru rm -rf src/org/bouncycastle/pqc/math/ntru rm -rf src/org/bouncycastle/pqc/crypto/ntru rm -rf src/org/bouncycastle/pqc/crypto/*/NTRU* rm -rf src/org/bouncycastle/pqc/crypto/*/EncryptionKey* rm -rf src/org/bouncycastle/pqc/crypto/*/BitStringT* rm -rf src/org/bouncycastle/jce/cert rm -rf src/org/bouncycastle/math/ntru rm -rf src/org/bouncycastle/crypto/test/ntru rm -rf src/org/bouncycastle/crypto/*/NTRU* rm -rf src/org/bouncycastle/crypto/*/test rm -rf src/org/bouncycastle/crypto/*/IndexGenerator* rm src/org/bouncycastle/jcajce/provider/config/*Permission.java rm -rf src/org/bouncycastle/jcajce/provider/asymmetric/dstu rm src/org/bouncycastle/jcajce/provider/asymmetric/DSTU* rm src/org/bouncycastle/jce/provider/test/DHTest.java rm src/org/bouncycastle/jce/provider/test/DSATest.java rm src/org/bouncycastle/jce/provider/test/ECIESTest.java rm src/org/bouncycastle/jce/provider/test/ElGamalTest.java rm src/org/bouncycastle/jce/provider/test/NamedCurveTest.java rm src/org/bouncycastle/jce/provider/test/PSSTest.java rm src/org/bouncycastle/jce/provider/test/NIST*.java rm src/org/bouncycastle/jce/provider/test/GOST3410Test.java rm src/org/bouncycastle/jce/provider/test/JceTestUtil.java rm src/org/bouncycastle/crypto/test/GCMReorderTest.java rm -rf src/org/bouncycastle/asn1/test/GetInstanceTest.java rm -rf src/org/bouncycastle/i18n/test rm -rf src/org/bouncycastle/i18n/filter/test rm -rf src/org/bouncycastle/voms rm -rf src/org/bouncycastle/jce/ECPointUtil.java rm -rf src/org/bouncycastle/jce/X509LDAP*.java rm -rf src/org/bouncycastle/jce/provider/JCEEC5*.java rm -rf src/org/bouncycastle/jce/provider/JCEEC*.java rm -rf src/org/bouncycastle/jce/provider/CertPathValidatorUtilities.java rm -rf src/org/bouncycastle/jce/provider/test/CRL5Test.java rm -rf src/org/bouncycastle/jcajce/provider/asymmetric/ec/EC5*.java rm -rf src/org/bouncycastle/jce/provider/asymmetric/ec/EC5*.java rm -rf src/org/bouncycastle/jce/provider/EC5*.java rm -rf src/org/bouncycastle/jce/provider/X509LDAP*.java rm -rf src/org/bouncycastle/jce/provider/test/X509LDAP*.java rm -rf src/org/bouncycastle/jce/provider/test/ECDSA5Test.java rm -rf src/org/bouncycastle/jce/provider/test/ECEncodingTest.java rm -rf src/org/bouncycastle/jce/provider/test/ECNRTest.java rm -rf src/org/bouncycastle/jce/provider/test/IESTest.java rm -rf src/org/bouncycastle/jce/provider/test/AttrCertTest.java rm -rf src/org/bouncycastle/jce/provider/test/PKIXPolicyMappingTest.java rm -rf src/org/bouncycastle/jce/provider/test/nist rm -rf src/org/bouncycastle/jce/provider/test/rsa3 rm -rf src/org/bouncycastle/jce/provider/test/DSTU* rm -rf src/org/bouncycastle/jce/spec/ECNamedCurveSpec.java rm -rf src/org/bouncycastle/mail rm -rf src/org/bouncycastle/math/ec/test rm -rf src/org/bouncycastle/cms rm -rf src/org/bouncycastle/ocsp rm -rf src/org/bouncycastle/eac rm -rf src/org/bouncycastle/cert rm -rf src/org/bouncycastle/bcpg rm -rf src/org/bouncycastle/pkcs rm -rf src/org/bouncycastle/operator rm -rf src/org/bouncycastle/openpgp rm -rf src/org/bouncycastle/openssl rm -rf src/org/bouncycastle/mozilla rm -rf src/org/bouncycastle/voms rm -rf src/org/bouncycastle/sasn1 rm -rf src/org/bouncycastle/tsp rm -rf src/org/bouncycastle/util/encoders/test rm -rf src/org/bouncycastle/util/utiltest rm -rf src/org/bouncycastle/x509/PKIXCertPathReviewer.java rm -rf src/org/bouncycastle/x509/CertPathReviewerException.java rm -rf src/org/bouncycastle/x509/ExtendedPKIX*.java rm -rf src/org/bouncycastle/x509/util/LDAPStoreHelper.java rm -rf src/org/bouncycastle/jce/provider/PKIXAttrCert*.java rm -rf src/org/bouncycastle/jce/provider/PKIXNameConstraints*.java rm -rf src/org/bouncycastle/jce/provider/test/PKIXNameConstraintsTest.java rm -rf src/org/bouncycastle/jce/provider/test/AttrCertSelectorTest.java rm -rf src/org/bouncycastle/jce/provider/test/MQVTest.java rm -rf src/org/bouncycastle/x509/ExtendedPKIX*.java rm -rf src/org/bouncycastle/jce/provider/PKIXCRL*.java rm -rf src/org/bouncycastle/jce/provider/RFC3281*.java rm -rf src/org/bouncycastle/jce/provider/JDKPKCS12StoreParameter.java rm -rf src/org/bouncycastle/jce/provider/CertPathValidatorUtilities.java rm -rf src/org/bouncycastle/jce/ProviderConfigurationPermission.java rm -rf src/org/bouncycastle/jce/provider/X509StoreLDAPAttrCerts.java rm -rf src/org/bouncycastle/jce/provider/X509StoreLDAPCertPairs.java rm -rf src/org/bouncycastle/jce/provider/X509StoreLDAPCerts.java rm -rf src/org/bouncycastle/jce/provider/X509StoreLDAPCRLs.java rm -rf src/org/bouncycastle/jce/provider/PKIXNameConstraint*.java rm -rf src/org/bouncycastle/openssl/test/WriterTest.java rm -rf src/org/bouncycastle/jcajce/provider/config/PKCS12StoreParameter.java rm -rf src/org/bouncycastle/jcajce/provider/asymmetric/util/EC5Util.java rm -rf src/org/bouncycastle/jcajce/provider/test/PrivateConstructorTest.java find src -name AllTests.java -exec rm {} \; rm src/org/bouncycastle/asn1/test/ASN1SequenceParserTest.java rm src/org/bouncycastle/asn1/test/OctetStringTest.java rm src/org/bouncycastle/asn1/test/ParseTest.java rm src/org/bouncycastle/jce/provider/test/ImplicitlyCaTest.java rm src/org/bouncycastle/jce/provider/test/X509StoreTest.java rm src/org/bouncycastle/jce/provider/test/DHIESTest.java rm -rf src/org/bouncycastle/pqc/jcajce rm -rf src/org/bouncycastle/crypto/tls/test (2>&1 javadoc -windowtitle "$WINDOWTITLE" -doctitle "$DOCTITLE" \ -header "$HEADER" \ -group "Cleanroom JCE" "javax.crypto*" \ -group "JCE Utility and Extension Packages" "org.bouncycastle.jce*" \ -group "OCSP Support Packages" "org.bouncycastle.ocsp*" \ -group "ASN.1 Support Packages" "org.bouncycastle.asn1*" \ -group "Lightweight Crypto Packages" "org.bouncycastle.crypto*" \ -group "Utility Packages" "org.bouncycastle.util*:org.bouncycastle.math*" \ -group "JCE Provider and Test Classes" "org.bouncycastle.jce.provider*" \ -classpath classes \ -d docs -sourcepath src \ java.lang \ java.security \ java.security.cert \ java.security.interfaces \ java.security.spec \ java.util \ javax.crypto \ javax.crypto.interfaces \ javax.crypto.spec \ org.bouncycastle.pqc \ org.bouncycastle.math \ org.bouncycastle.crypto \ org.bouncycastle.asn1 \ org.bouncycastle.jce \ org.bouncycastle.asn1 \ org.bouncycastle.asn1.cmp \ org.bouncycastle.asn1.cms \ org.bouncycastle.asn1.cryptopro \ org.bouncycastle.asn1.esf \ org.bouncycastle.asn1.ess \ org.bouncycastle.asn1.gnu \ org.bouncycastle.asn1.iana \ org.bouncycastle.asn1.icao \ org.bouncycastle.asn1.misc \ org.bouncycastle.asn1.mozilla \ org.bouncycastle.asn1.nist \ org.bouncycastle.asn1.ocsp \ org.bouncycastle.asn1.oiw \ org.bouncycastle.asn1.pkcs \ org.bouncycastle.asn1.sec \ org.bouncycastle.asn1.smime \ org.bouncycastle.asn1.teletrust \ org.bouncycastle.asn1.test \ org.bouncycastle.asn1.tsp \ org.bouncycastle.asn1.util \ org.bouncycastle.asn1.x509 \ org.bouncycastle.asn1.x9 \ org.bouncycastle.math.ec \ org.bouncycastle.crypto \ org.bouncycastle.crypto.agreement \ org.bouncycastle.crypto.commitments \ org.bouncycastle.crypto.digests \ org.bouncycastle.crypto.ec \ org.bouncycastle.crypto.encodings \ org.bouncycastle.crypto.engines \ org.bouncycastle.crypto.generators \ org.bouncycastle.crypto.io \ org.bouncycastle.crypto.kems \ org.bouncycastle.crypto.macs \ org.bouncycastle.crypto.modes \ org.bouncycastle.crypto.paddings \ org.bouncycastle.crypto.params \ org.bouncycastle.crypto.signers \ org.bouncycastle.crypto.test \ org.bouncycastle.crypto.tls \ org.bouncycastle.crypto.examples \ org.bouncycastle.jce.interfaces \ org.bouncycastle.jce.spec \ org.bouncycastle.jce.examples \ org.bouncycastle.jce.provider \ org.bouncycastle.jce.provider.symmetric \ org.bouncycastle.jce.provider.asymmetric \ org.bouncycastle.jce.provider.asymmetric.ec \ org.bouncycastle.jce.provider.test \ org.bouncycastle.x509 \ org.bouncycastle.x509.examples \ org.bouncycastle.x509.extension \ org.bouncycastle.ocsp \ org.bouncycastle.ocsp.test \ org.bouncycastle.util.encoders \ org.bouncycastle.util.test) > /dev/null \ PATH=$JDK11PATH/bin:$PATH export PATH JAVA_HOME=$JDK11PATH export JAVA_HOME echo "compiling" (cd src/java/; javac -d ../../classes -classpath ../../classes:../../src:$JDK11PATH/lib/classes.zip */*.java */*/*.java ) (cd src/javax/crypto; javac -d ../../../classes -classpath ../../../classes:../../../src:$JDK11PATH/lib/classes.zip *.java */*.java) (cd src/org/bouncycastle; javac -d ../../../classes -classpath ../../../classes:../../../src:$JDK11PATH/lib/classes.zip asn1/*.java) (cd src/org/bouncycastle; javac -d ../../../classes -classpath ../../../classes:../../../src:$JDK11PATH/lib/classes.zip crypto/*.java) (cd src/org/bouncycastle; javac -d ../../../classes -classpath ../../../classes:../../../src:$JDK11PATH/lib/classes.zip *.java pqc/*/*.java) (cd src/org/bouncycastle; javac -d ../../../classes -classpath ../../../classes:../../../src:$JDK11PATH/lib/classes.zip *.java [opqrstuv]*/*.java) (cd src/org/bouncycastle; javac -d ../../../classes -classpath ../../../classes:../../../src:$JDK11PATH/lib/classes.zip *.java [ijklmn]*/*.java) (cd src/org/bouncycastle; javac -d ../../../classes -classpath ../../../classes:../../../src:$JDK11PATH/lib/classes.zip asn1/*/*.java) (cd src/org/bouncycastle; javac -d ../../../classes -classpath ../../../classes:../../../src:$JDK11PATH/lib/classes.zip crypto/[ade]*/*.java) (cd src/org/bouncycastle; javac -d ../../../classes -classpath ../../../classes:../../../src:$JDK11PATH/lib/classes.zip crypto/[gimpsu]*/*.java) (cd src/org/bouncycastle; javac -d ../../../classes -classpath ../../../classes:../../../src:$JDK11PATH/lib/classes.zip crypto/t*/*.java) (cd src/org/bouncycastle; javac -d ../../../classes -classpath ../../../classes:../../../src:$JDK11PATH/lib/classes.zip jcajce/*.java) (cd src/org/bouncycastle; javac -d ../../../classes -classpath ../../../classes:../../../src:$JDK11PATH/lib/classes.zip jcajce/*/*.java) (cd src/org/bouncycastle; javac -d ../../../classes -classpath ../../../classes:../../../src:$JDK11PATH/lib/classes.zip jcajce/*/*/*.java) (cd src/org/bouncycastle; javac -d ../../../classes -classpath ../../../classes:../../../src:$JDK11PATH/lib/classes.zip jcajce/provider/digest/*.java) (cd src/org/bouncycastle; javac -d ../../../classes -classpath ../../../classes:../../../src:$JDK11PATH/lib/classes.zip jcajce/provider/symmetric/*.java) (cd src/org/bouncycastle; javac -d ../../../classes -classpath ../../../classes:../../../src:$JDK11PATH/lib/classes.zip jcajce/*/*/*/*.java) (cd src/org/bouncycastle; javac -d ../../../classes -classpath ../../../classes:../../../src:$JDK11PATH/lib/classes.zip jce/*/*/*.java) (cd src/org/bouncycastle; javac -d ../../../classes -classpath ../../../classes:../../../src:$JDK11PATH/lib/classes.zip jce/*/*.java) (cd src/org/bouncycastle; javac -d ../../../classes -classpath ../../../classes:../../../src:$JDK11PATH/lib/classes.zip util/*/*.java) (cd src/org/bouncycastle; javac -d ../../../classes -classpath ../../../classes:../../../src:$JDK11PATH/lib/classes.zip [abc]*/*/*/*.java) (cd src/org/bouncycastle; javac -d ../../../classes -classpath ../../../classes:../../../src:$JDK11PATH/lib/classes.zip [ijm]*/*/*/*.java) (cd src/org/bouncycastle; javac -d ../../../classes -classpath ../../../classes:../../../src:$JDK11PATH/lib/classes.zip [ptuvx]*/*/*/*.java) (cd src/org/bouncycastle; javac -d ../../../classes -classpath ../../../classes:../../../src:$JDK11PATH/lib/classes.zip x509/*.java x509/*/*.java) rm -rf classes/org/bouncycastle/crypto/test echo "provider regression test" java -classpath classes:$JDK11PATH/lib/classes.zip org.bouncycastle.jce.provider.test.RegressionTest java -classpath classes:$JDK11PATH/lib/classes.zip org.bouncycastle.asn1.test.RegressionTest ) ( 2>&1 find jce-jdk11-$base -name CVS -exec rm -rf \{\} \;) > /dev/null fi if test "$base" != "" then echo "making PKIX release" mkdir bcpkix-jdk11-$base tar cf - index.html LICENSE.html CONTRIBUTORS.html releasenotes.html specifications.html src/org/bouncycastle/cert src/org/bouncycastle/mozilla src/org/bouncycastle/voms src/org/bouncycastle/openssl src/org/bouncycastle/pkcs src/org/bouncycastle/cms src/org/bouncycastle/eac src/org/bouncycastle/tsp src/org/bouncycastle/operator | (cd bcpkix-jdk11-$base; tar xf -) (cd test/src; tar cf - org/bouncycastle/cert org/bouncycastle/ocsp/test/OCSPTestUtil.java org/bouncycastle/openssl org/bouncycastle/tsp | (cd ../../bcpkix-jdk11-$base/src; tar xf -)) (cd test/jdk1.3; tar cf - org/bouncycastle/cert org/bouncycastle/tsp | (cd ../../bcpkix-jdk11-$base/src; tar xf -)) (cd jdk1.4; tar cf - org/bouncycastle/cms org/bouncycastle/eac | (cd ../bcpkix-jdk11-$base/src; tar xf -)) (cd jdk1.3; tar cf - org/bouncycastle/cert org/bouncycastle/pkcs org/bouncycastle/cms org/bouncycastle/eac org/bouncycastle/tsp | (cd ../bcpkix-jdk11-$base/src; tar xf -)) (cd jdk1.2; tar cf - org/bouncycastle/cert org/bouncycastle/cms | (cd ../bcpkix-jdk11-$base/src; tar xf -)) (cd jdk1.1; tar cf - org/bouncycastle/cert org/bouncycastle/operator org/bouncycastle/tsp org/bouncycastle/openssl org/bouncycastle/cms | (cd ../bcpkix-jdk11-$base/src; tar xf -)) ( cd bcpkix-jdk11-$base; mkdir classes; mkdir docs; PATH=$JDK11PATH/bin:$PATH export PATH JAVA_HOME=$JDK11PATH export JAVA_HOME rm -rf src/java rm -rf src/org/bouncycastle/jce rm -rf src/org/bouncycastle/bcpg rm -rf src/org/bouncycastle/x509 rm -rf src/org/bouncycastle/mail rm -rf src/org/bouncycastle/openpgp rm -rf src/org/bouncycastle/asn1 rm -rf src/org/bouncycastle/i18n rm -rf src/org/bouncycastle/pqc rm -rf src/org/bouncycastle/jcajce rm -rf src/org/bouncycastle/cert/test/ConverterTest* rm -rf src/org/bouncycastle/cert/test/Bc* rm -rf src/org/bouncycastle/tsp/test rm -rf src/org/bouncycastle/tsp/GenTimeAccuracyUnit* rm -rf src/org/bouncycastle/tsp/TimeStampTokenInfoUnit* rm src/org/bouncycastle/openssl/test/ParserTest* rm src/org/bouncycastle/openssl/test/ReaderTest* rm src/org/bouncycastle/openssl/test/WriterTest* find src -name AllTests.java -exec rm {} \; javadoc -windowtitle "$WINDOWTITLE" -doctitle "$DOCTITLE" \ -header "$HEADER" \ -group "Basic Signing And Encryption" "org.bouncycastle.operator*" \ -group "Certificate Generation And Handling Support Packages" "org.bouncycastle.cert*" \ -group "CMS Support Packages" "org.bouncycastle.cms*" \ -group "EAC Support Packages" "org.bouncycastle.eac*" \ -group "TSP Support Packages" "org.bouncycastle.tsp*" \ -group "PKCS Support Packages" "org.bouncycastle.pkcs*" \ -group "OpenSSL PEM Support Packages" "org.bouncycastle.openssl*" \ -classpath classes:../jce-ext-jdk11-146.jar \ -d docs -sourcepath src \ org.bouncycastle.openssl \ org.bouncycastle.voms \ org.bouncycastle.mozilla \ org.bouncycastle.pkcs \ org.bouncycastle.pkcs.bc \ org.bouncycastle.pkcs.jcajce \ org.bouncycastle.cert \ org.bouncycastle.cert.cmp \ org.bouncycastle.cert.crmf \ org.bouncycastle.cert.jcajce \ org.bouncycastle.cert.ocsp \ org.bouncycastle.cert.selector \ org.bouncycastle.cms \ org.bouncycastle.cms.bc \ org.bouncycastle.cms.jcajce \ org.bouncycastle.cert.test > /dev/null \ echo "compiling" (cd src/org/bouncycastle; javac -d ../../../classes -classpath ../../../classes:../../../src:../../../../jce-jdk11-$base/classes:$JDK11PATH/lib/classes.zip */*.java ) (cd src/org/bouncycastle; javac -d ../../../classes -classpath ../../../classes:../../../src:../../../../jce-jdk11-$base/classes:$JDK11PATH/lib/classes.zip */*/*.java ) (cd src/org/bouncycastle; javac -d ../../../classes -classpath ../../../classes:../../../src:../../../../jce-jdk11-$base/classes:$JDK11PATH/lib/classes.zip */*/*/*.java ) java -mx512m -classpath ../jce-jdk11-$base/classes:classes:$JDK11PATH/lib/classes.zip org.bouncycastle.cert.test.CertTest java -mx512m -classpath ../jce-jdk11-$base/classes:classes:$JDK11PATH/lib/classes.zip org.bouncycastle.cert.test.AttrCertTest java -mx512m -classpath ../jce-jdk11-$base/classes:classes:$JDK11PATH/lib/classes.zip org.bouncycastle.cert.test.PKCS10Test # java -classpath ../jce-jdk11-$base/classes:classes:$JDK11PATH/lib/classes.zip org.bouncycastle.openssl.test.ReaderTest ) (2>&1 find bcpkix-jdk11-$base -name CVS -exec rm -rf \{\} \;) > /dev/null fi if test "$base" != "" then echo "making OpenPGP release" mkdir bcpg-jdk11-$base tar cf - index.html LICENSE.html CONTRIBUTORS.html releasenotes.html specifications.html src/org/bouncycastle/bcpg src/org/bouncycastle/openpgp | (cd bcpg-jdk11-$base; tar xf -) (cd test/src; tar cf - org/bouncycastle/openpgp | (cd ../../bcpg-jdk11-$base/src; tar xf -)) (cd bzip2 && tar cf - src | (cd ../bcpg-jdk11-$base; tar xf -)) (cd jdk1.1; tar cf - org/bouncycastle/openpgp | (cd ../bcpg-jdk11-$base/src; tar xf -)) ( cd bcpg-jdk11-$base; mkdir classes; mkdir docs; PATH=$JDK11PATH/bin:$PATH export PATH JAVA_HOME=$JDK11PATH export JAVA_HOME rm src/org/bouncycastle/openpgp/examples/DSAElGamalKeyRingGenerator.java rm src/org/bouncycastle/openpgp/examples/test/AllTests.java rm -f src/org/bouncycastle/openpgp/test/DSA2Test.java rm -f src/org/bouncycastle/openpgp/test/PGPUnicodeTest.java javadoc -windowtitle "$WINDOWTITLE" -doctitle "$DOCTITLE" \ -header "$HEADER" \ -group "BCPG Support Packages" "org.bouncycastle.bcpg*" \ -group "OpenPGP Packages" "org.bouncycastle.openpgp*" \ -classpath classes:../jce-jdk11-$base/classes:$JDK11PATH/lib/classes.zip \ -d docs -sourcepath src \ org.bouncycastle.bcpg \ org.bouncycastle.bcpg.attr \ org.bouncycastle.bcpg.sig \ org.bouncycastle.openpgp \ org.bouncycastle.openpgp.examples \ org.bouncycastle.openpgp.operator \ org.bouncycastle.openpgp.operator.jcajce \ org.bouncycastle.openpgp.operator.bc \ org.bouncycastle.openpgp.test > /dev/null \ rm -rf src/org/bouncycastle/openpgp/test/AllTests.java ed src/org/bouncycastle/bcpg/ArmoredOutputStream.java <<% /@RELEASE_NAME@/s//$version/ w q % echo "compiling" (cd src/org/bouncycastle; javac -d ../../../classes -classpath ../../../classes:../../../src:../../../../jce-jdk11-$base/classes:$JDK11PATH/lib/classes.zip */*.java */*/*.java */*/*/*.java ) java -mx512m -classpath ../jce-jdk11-$base/classes:classes:$JDK11PATH/lib/classes.zip org.bouncycastle.openpgp.test.RegressionTest ) (2>&1 find bcpg-jdk11-$base -name CVS -exec rm -rf \{\} \;) > /dev/null fi bouncycastle-1.49.orig/jdk1.2/0000755000175000017500000000000012152033550015416 5ustar ebourgebourgbouncycastle-1.49.orig/jdk1.2/org/0000755000175000017500000000000012152033550016205 5ustar ebourgebourgbouncycastle-1.49.orig/jdk1.2/org/bouncycastle/0000755000175000017500000000000012152033550020700 5ustar ebourgebourgbouncycastle-1.49.orig/jdk1.2/org/bouncycastle/asn1/0000755000175000017500000000000012152033550021542 5ustar ebourgebourgbouncycastle-1.49.orig/jdk1.2/org/bouncycastle/asn1/test/0000755000175000017500000000000012152033550022521 5ustar ebourgebourgbouncycastle-1.49.orig/jdk1.2/org/bouncycastle/asn1/test/RegressionTest.java0000644000175000017500000000537011524153077026362 0ustar ebourgebourgpackage org.bouncycastle.asn1.test; import org.bouncycastle.util.test.Test; import org.bouncycastle.util.test.TestResult; public class RegressionTest { public static Test[] tests = { new InputStreamTest(), new EqualsAndHashCodeTest(), new TagTest(), new SetTest(), new DERUTF8StringTest(), new CertificateTest(), new GenerationTest(), new CMSTest(), new OCSPTest(), new OIDTest(), new PKCS10Test(), new PKCS12Test(), new X509NameTest(), new X500NameTest(), new X509ExtensionsTest(), new GeneralizedTimeTest(), new BitStringTest(), new MiscTest(), new SMIMETest(), new X9Test(), new MonetaryValueUnitTest(), new BiometricDataUnitTest(), new Iso4217CurrencyCodeUnitTest(), new SemanticsInformationUnitTest(), new QCStatementUnitTest(), new TypeOfBiometricDataUnitTest(), new SignerLocationUnitTest(), new CommitmentTypeQualifierUnitTest(), new CommitmentTypeIndicationUnitTest(), new EncryptedPrivateKeyInfoTest(), new DataGroupHashUnitTest(), new LDSSecurityObjectUnitTest(), // new CscaMasterListTest(), new AttributeTableUnitTest(), new ReasonFlagsTest(), new NetscapeCertTypeTest(), new PKIFailureInfoTest(), new KeyUsageTest(), new StringTest(), new UTCTimeTest(), new RequestedCertificateUnitTest(), new OtherCertIDUnitTest(), new OtherSigningCertificateUnitTest(), new ContentHintsUnitTest(), new CertHashUnitTest(), new AdditionalInformationSyntaxUnitTest(), new AdmissionSyntaxUnitTest(), new AdmissionsUnitTest(), new DeclarationOfMajorityUnitTest(), new ProcurationSyntaxUnitTest(), new ProfessionInfoUnitTest(), new RestrictionUnitTest(), new NamingAuthorityUnitTest(), new MonetaryLimitUnitTest(), new NameOrPseudonymUnitTest(), new PersonalDataUnitTest(), new DERApplicationSpecificTest(), new IssuingDistributionPointUnitTest(), new TargetInformationTest(), new SubjectKeyIdentifierTest(), new ESSCertIDv2UnitTest(), new ParsingTest(), new GeneralNameTest(), new RFC4519Test() }; public static void main( String[] args) { for (int i = 0; i != tests.length; i++) { TestResult result = tests[i].perform(); if (result.getException() != null) { result.getException().printStackTrace(); } System.out.println(result); } } } bouncycastle-1.49.orig/jdk1.2/org/bouncycastle/cert/0000755000175000017500000000000012152033550021635 5ustar ebourgebourgbouncycastle-1.49.orig/jdk1.2/org/bouncycastle/cert/crmf/0000755000175000017500000000000012152033550022564 5ustar ebourgebourgbouncycastle-1.49.orig/jdk1.2/org/bouncycastle/cert/crmf/jcajce/0000755000175000017500000000000012152033550024003 5ustar ebourgebourgbouncycastle-1.49.orig/jdk1.2/org/bouncycastle/cert/crmf/jcajce/JceCRMFEncryptorBuilder.java0000644000175000017500000000754411726307267031265 0ustar ebourgebourgpackage org.bouncycastle.cert.crmf.jcajce; import java.io.OutputStream; import java.security.AlgorithmParameters; import java.security.GeneralSecurityException; import java.security.Provider; import java.security.SecureRandom; import javax.crypto.Cipher; import javax.crypto.CipherOutputStream; import javax.crypto.KeyGenerator; import javax.crypto.SecretKey; import org.bouncycastle.asn1.ASN1ObjectIdentifier; import org.bouncycastle.asn1.x509.AlgorithmIdentifier; import org.bouncycastle.cert.crmf.CRMFException; import org.bouncycastle.jcajce.DefaultJcaJceHelper; import org.bouncycastle.jcajce.NamedJcaJceHelper; import org.bouncycastle.jcajce.ProviderJcaJceHelper; import org.bouncycastle.operator.GenericKey; import org.bouncycastle.operator.OutputEncryptor; public class JceCRMFEncryptorBuilder { private ASN1ObjectIdentifier encryptionOID; private int keySize; private CRMFHelper helper = new CRMFHelper(new DefaultJcaJceHelper()); private SecureRandom random; public JceCRMFEncryptorBuilder(ASN1ObjectIdentifier encryptionOID) { this(encryptionOID, -1); } public JceCRMFEncryptorBuilder(ASN1ObjectIdentifier encryptionOID, int keySize) { this.encryptionOID = encryptionOID; this.keySize = keySize; } public JceCRMFEncryptorBuilder setProvider(Provider provider) { this.helper = new CRMFHelper(new ProviderJcaJceHelper(provider)); return this; } public JceCRMFEncryptorBuilder setProvider(String providerName) { this.helper = new CRMFHelper(new NamedJcaJceHelper(providerName)); return this; } public JceCRMFEncryptorBuilder setSecureRandom(SecureRandom random) { this.random = random; return this; } public OutputEncryptor build() throws CRMFException { return new CRMFOutputEncryptor(encryptionOID, keySize, random); } private class CRMFOutputEncryptor implements OutputEncryptor { private SecretKey encKey; private AlgorithmIdentifier algorithmIdentifier; private Cipher cipher; CRMFOutputEncryptor(ASN1ObjectIdentifier encryptionOID, int keySize, SecureRandom random) throws CRMFException { KeyGenerator keyGen = helper.createKeyGenerator(encryptionOID); if (random == null) { random = new SecureRandom(); } if (keySize < 0) { keyGen.init(random); } else { keyGen.init(keySize, random); } cipher = helper.createCipher(encryptionOID); encKey = keyGen.generateKey(); AlgorithmParameters params = helper.generateParameters(encryptionOID, encKey, random); try { cipher.init(Cipher.ENCRYPT_MODE, encKey, params, random); } catch (GeneralSecurityException e) { throw new CRMFException("unable to initialize cipher: " + e.getMessage(), e); } // // If params are null we try and second guess on them as some providers don't provide // algorithm parameter generation explicity but instead generate them under the hood. // if (params == null) { params = cipher.getParameters(); } algorithmIdentifier = helper.getAlgorithmIdentifier(encryptionOID, params); } public AlgorithmIdentifier getAlgorithmIdentifier() { return algorithmIdentifier; } public OutputStream getOutputStream(OutputStream dOut) { return new CipherOutputStream(dOut, cipher); } public GenericKey getKey() { return new GenericKey(encKey); } } } bouncycastle-1.49.orig/jdk1.2/org/bouncycastle/cert/jcajce/0000755000175000017500000000000012152033550023054 5ustar ebourgebourgbouncycastle-1.49.orig/jdk1.2/org/bouncycastle/cert/jcajce/JcaAttrCertStore.java0000644000175000017500000000336211523670711027115 0ustar ebourgebourgpackage org.bouncycastle.cert.jcajce; import java.io.IOException; import java.util.ArrayList; import java.util.Collection; import java.util.Collections; import java.util.Iterator; import java.util.List; import org.bouncycastle.util.CollectionStore; import org.bouncycastle.x509.X509AttributeCertificate; /** * Class for storing Attribute Certificates for later lookup. *

    * The class will convert X509AttributeCertificate objects into X509AttributeCertificateHolder objects. *

    */ public class JcaAttrCertStore extends CollectionStore { /** * Basic constructor. * * @param collection - initial contents for the store, this is copied. */ public JcaAttrCertStore(Collection collection) throws IOException { super(convertCerts(collection)); } public JcaAttrCertStore(X509AttributeCertificate attrCert) throws IOException { this(convertCert(attrCert)); } private static Collection convertCert(X509AttributeCertificate attrCert) throws IOException { List tmp = new ArrayList(); tmp.add(attrCert); return convertCerts(tmp); } private static Collection convertCerts(Collection collection) throws IOException { List list = new ArrayList(collection.size()); for (Iterator it = collection.iterator(); it.hasNext();) { Object o = it.next(); if (o instanceof X509AttributeCertificate) { X509AttributeCertificate cert = (X509AttributeCertificate)o; list.add(new JcaX509AttributeCertificateHolder(cert)); } else { list.add(o); } } return list; } } bouncycastle-1.49.orig/jdk1.2/org/bouncycastle/i18n/0000755000175000017500000000000012152033550021457 5ustar ebourgebourgbouncycastle-1.49.orig/jdk1.2/org/bouncycastle/i18n/LocalizedMessage.java0000644000175000017500000003507210713310026025541 0ustar ebourgebourgpackage org.bouncycastle.i18n; import org.bouncycastle.i18n.filter.Filter; import org.bouncycastle.i18n.filter.TrustedInput; import org.bouncycastle.i18n.filter.UntrustedInput; import org.bouncycastle.i18n.filter.UntrustedUrlInput; import java.io.UnsupportedEncodingException; import java.text.DateFormat; import java.text.Format; import java.text.MessageFormat; import java.util.Locale; import java.util.MissingResourceException; import java.util.ResourceBundle; import java.util.TimeZone; public class LocalizedMessage { protected static final int NO_FILTER = 0; protected static final int FILTER = 1; protected static final int FILTER_URL = 2; protected String id; protected String resource; // ISO-8859-1 is the default encoding public static final String DEFAULT_ENCODING = "ISO-8859-1"; protected String encoding = DEFAULT_ENCODING; protected FilteredArguments arguments; protected FilteredArguments extraArgs = null; protected Filter filter = null; protected ClassLoader loader = null; /** * Constructs a new LocalizedMessage using resource as the base name for the * RessourceBundle and id as the message bundle id the resource file. * @param resource base name of the resource file * @param id the id of the corresponding bundle in the resource file * @throws NullPointerException if resource or id is null */ public LocalizedMessage(String resource,String id) throws NullPointerException { if (resource == null || id == null) { throw new NullPointerException(); } this.id = id; this.resource = resource; arguments = new FilteredArguments(); } /** * Constructs a new LocalizedMessage using resource as the base name for the * RessourceBundle and id as the message bundle id the resource file. * @param resource base name of the resource file * @param id the id of the corresponding bundle in the resource file * @param encoding the encoding of the resource file * @throws NullPointerException if resource or id is null * @throws UnsupportedEncodingException if the encoding is not supported */ public LocalizedMessage(String resource,String id, String encoding) throws NullPointerException, UnsupportedEncodingException { if (resource == null || id == null) { throw new NullPointerException(); } this.id = id; this.resource = resource; arguments = new FilteredArguments(); this.encoding = encoding; } /** * Constructs a new LocalizedMessage using resource as the base name for the * RessourceBundle and id as the message bundle id the resource file. * @param resource base name of the resource file * @param id the id of the corresponding bundle in the resource file * @param arguments an array containing the arguments for the message * @throws NullPointerException if resource or id is null */ public LocalizedMessage(String resource, String id, Object[] arguments) throws NullPointerException { if (resource == null || id == null || arguments == null) { throw new NullPointerException(); } this.id = id; this.resource = resource; this.arguments = new FilteredArguments(arguments); } /** * Constructs a new LocalizedMessage using resource as the base name for the * RessourceBundle and id as the message bundle id the resource file. * @param resource base name of the resource file * @param id the id of the corresponding bundle in the resource file * @param encoding the encoding of the resource file * @param arguments an array containing the arguments for the message * @throws NullPointerException if resource or id is null * @throws UnsupportedEncodingException if the encoding is not supported */ public LocalizedMessage(String resource, String id, String encoding, Object[] arguments) throws NullPointerException, UnsupportedEncodingException { if (resource == null || id == null || arguments == null) { throw new NullPointerException(); } this.id = id; this.resource = resource; this.arguments = new FilteredArguments(arguments); this.encoding = encoding; } /** * Reads the entry id + "." + key from the resource file and returns a * formated message for the given Locale and TimeZone. * @param key second part of the entry id * @param loc the used {@link Locale} * @param timezone the used {@link TimeZone} * @return a Strng containing the localized message * @throws MissingEntryException if the resource file is not available or the entry does not exist. */ public String getEntry(String key,Locale loc, TimeZone timezone) throws MissingEntryException { String entry = id; if (key != null) { entry += "." + key; } try { ResourceBundle bundle; if (loader == null) { bundle = ResourceBundle.getBundle(resource,loc); } else { bundle = ResourceBundle.getBundle(resource, loc); } String result = bundle.getString(entry); if (!encoding.equals(DEFAULT_ENCODING)) { result = new String(result.getBytes(DEFAULT_ENCODING), encoding); } if (!arguments.isEmpty()) { result = formatWithTimeZone(result,arguments.getFilteredArgs(loc),loc,timezone); } result = addExtraArgs(result, loc); return result; } catch (MissingResourceException mre) { throw new MissingEntryException("Can't find entry " + entry + " in resource file " + resource + ".", resource, entry, loc, loader != null ? loader : this.getClassLoader()); } catch (UnsupportedEncodingException use) { // should never occur - cause we already test this in the constructor throw new RuntimeException(use.toString()); } } protected String formatWithTimeZone( String template, Object[] arguments, Locale locale, TimeZone timezone) { MessageFormat mf = new MessageFormat(" "); mf.setLocale(locale); mf.applyPattern(template); if (!timezone.equals(TimeZone.getDefault())) { Format[] formats = mf.getFormats(); for (int i = 0; i < formats.length; i++) { if (formats[i] instanceof DateFormat) { DateFormat temp = (DateFormat) formats[i]; temp.setTimeZone(timezone); mf.setFormat(i,temp); } } } return mf.format(arguments); } protected String addExtraArgs(String msg, Locale locale) { if (extraArgs != null) { StringBuffer sb = new StringBuffer(msg); Object[] filteredArgs = extraArgs.getFilteredArgs(locale); for (int i = 0; i < filteredArgs.length; i++) { sb.append(filteredArgs[i]); } msg = sb.toString(); } return msg; } /** * Sets the {@link Filter} that is used to filter the arguments of this message * @param filter the {@link Filter} to use. null to disable filtering. */ public void setFilter(Filter filter) { arguments.setFilter(filter); if (extraArgs != null) { extraArgs.setFilter(filter); } this.filter = filter; } /** * Returns the current filter. * @return the current filter */ public Filter getFilter() { return filter; } /** * Set the {@link ClassLoader} which loads the resource files. If it is set to null * then the default {@link ClassLoader} is used. * @param loader the {@link ClassLoader} which loads the resource files */ public void setClassLoader(ClassLoader loader) { this.loader = loader; } /** * Returns the {@link ClassLoader} which loads the resource files or null * if the default ClassLoader is used. * @return the {@link ClassLoader} which loads the resource files */ public ClassLoader getClassLoader() { return loader; } /** * Returns the id of the message in the resource bundle. * @return the id of the message */ public String getId() { return id; } /** * Returns the name of the resource bundle for this message * @return name of the resource file */ public String getResource() { return resource; } /** * Returns an Object[] containing the message arguments. * @return the message arguments */ public Object[] getArguments() { return arguments.getArguments(); } /** * * @param extraArg */ public void setExtraArgument(Object extraArg) { setExtraArguments(new Object[] {extraArg}); } /** * * @param extraArgs */ public void setExtraArguments(Object[] extraArgs) { if (extraArgs != null) { this.extraArgs = new FilteredArguments(extraArgs); this.extraArgs.setFilter(filter); } else { this.extraArgs = null; } } /** * * @return */ public Object[] getExtraArgs() { return (extraArgs == null) ? null : extraArgs.getArguments(); } protected class FilteredArguments { protected Filter filter = null; protected boolean[] isLocaleSpecific; protected int[] argFilterType; protected Object[] arguments; protected Object[] unpackedArgs; protected Object[] filteredArgs; FilteredArguments() { this(new Object[0]); } FilteredArguments(Object[] args) { this.arguments = args; this.unpackedArgs = new Object[args.length]; this.filteredArgs = new Object[args.length]; this.isLocaleSpecific = new boolean[args.length]; this.argFilterType = new int[args.length]; for (int i = 0; i < args.length; i++) { if (args[i] instanceof TrustedInput) { this.unpackedArgs[i] = ((TrustedInput) args[i]).getInput(); argFilterType[i] = NO_FILTER; } else if (args[i] instanceof UntrustedInput) { this.unpackedArgs[i] = ((UntrustedInput) args[i]).getInput(); if (args[i] instanceof UntrustedUrlInput) { argFilterType[i] = FILTER_URL; } else { argFilterType[i] = FILTER; } } else { this.unpackedArgs[i] = args[i]; argFilterType[i] = FILTER; } // locale specific this.isLocaleSpecific[i] = (this.unpackedArgs[i] instanceof LocaleString); } } public boolean isEmpty() { return unpackedArgs.length == 0; } public Object[] getArguments() { return arguments; } public Object[] getFilteredArgs(Locale locale) { Object[] result = new Object[unpackedArgs.length]; for (int i = 0; i < unpackedArgs.length; i++) { Object arg; if (filteredArgs[i] != null) { arg = filteredArgs[i]; } else { arg = unpackedArgs[i]; if (isLocaleSpecific[i]) { // get locale arg = ((LocaleString) arg).getLocaleString(locale); arg = filter(argFilterType[i], arg); } else { arg = filter(argFilterType[i], arg); filteredArgs[i] = arg; } } result[i] = arg; } return result; } private Object filter(int type, Object obj) { if (filter != null) { Object o = (null == obj) ? "null" : obj; switch (type) { case NO_FILTER: return o; case FILTER: return filter.doFilter(o.toString()); case FILTER_URL: return filter.doFilterUrl(o.toString()); default: return null; } } else { return obj; } } public Filter getFilter() { return filter; } public void setFilter(Filter filter) { if (filter != this.filter) { for (int i = 0; i < unpackedArgs.length; i++) { filteredArgs[i] = null; } } this.filter = filter; } } public String toString() { StringBuffer sb = new StringBuffer(); sb.append("Resource: \"").append(resource); sb.append("\" Id: \"").append(id).append("\""); sb.append(" Arguments: ").append(arguments.getArguments().length).append(" normal, ") .append(extraArgs.getArguments().length).append(" extra"); sb.append(" Encoding: ").append(encoding); sb.append(" ClassLoader: ").append(loader); return sb.toString(); } } bouncycastle-1.49.orig/jdk1.2/org/bouncycastle/i18n/MissingEntryException.java0000644000175000017500000000261410713310026026634 0ustar ebourgebourgpackage org.bouncycastle.i18n; import java.net.URL; import java.util.Locale; public class MissingEntryException extends RuntimeException { protected final String resource; protected final String key; protected final ClassLoader loader; protected final Locale locale; private String debugMsg; public MissingEntryException(String message, String resource, String key, Locale locale, ClassLoader loader) { super(message); this.resource = resource; this.key = key; this.locale = locale; this.loader = loader; } public MissingEntryException(String message, Throwable cause, String resource, String key, Locale locale, ClassLoader loader) { super(message + ": " + cause); this.resource = resource; this.key = key; this.locale = locale; this.loader = loader; } public String getKey() { return key; } public String getResource() { return resource; } public ClassLoader getClassLoader() { return loader; } public Locale getLocale() { return locale; } public String getDebugMsg() { if (debugMsg == null) { debugMsg = "Can not find entry " + key + " in resource file " + resource + " for the locale " + locale + "."; } return debugMsg; } } bouncycastle-1.49.orig/jdk1.2/org/bouncycastle/cms/0000755000175000017500000000000012152033550021462 5ustar ebourgebourgbouncycastle-1.49.orig/jdk1.2/org/bouncycastle/cms/bc/0000755000175000017500000000000012152033550022046 5ustar ebourgebourgbouncycastle-1.49.orig/jdk1.2/org/bouncycastle/cms/bc/BcCMSContentEncryptorBuilder.java0000644000175000017500000000724512104713302030355 0ustar ebourgebourgpackage org.bouncycastle.cms.bc; import java.io.OutputStream; import java.security.SecureRandom; import java.util.HashMap; import java.util.Map; import org.bouncycastle.asn1.ASN1ObjectIdentifier; import org.bouncycastle.asn1.x509.AlgorithmIdentifier; import org.bouncycastle.cms.CMSAlgorithm; import org.bouncycastle.cms.CMSException; import org.bouncycastle.crypto.BufferedBlockCipher; import org.bouncycastle.crypto.CipherKeyGenerator; import org.bouncycastle.crypto.StreamCipher; import org.bouncycastle.crypto.io.CipherOutputStream; import org.bouncycastle.crypto.params.KeyParameter; import org.bouncycastle.operator.GenericKey; import org.bouncycastle.operator.OutputEncryptor; import org.bouncycastle.util.Integers; public class BcCMSContentEncryptorBuilder { private static Map keySizes = new HashMap(); static { keySizes.put(CMSAlgorithm.AES128_CBC, Integers.valueOf(128)); keySizes.put(CMSAlgorithm.AES192_CBC, Integers.valueOf(192)); keySizes.put(CMSAlgorithm.AES256_CBC, Integers.valueOf(256)); keySizes.put(CMSAlgorithm.CAMELLIA128_CBC, Integers.valueOf(128)); keySizes.put(CMSAlgorithm.CAMELLIA192_CBC, Integers.valueOf(192)); keySizes.put(CMSAlgorithm.CAMELLIA256_CBC, Integers.valueOf(256)); } private static int getKeySize(ASN1ObjectIdentifier oid) { Integer size = (Integer)keySizes.get(oid); if (size != null) { return size.intValue(); } return -1; } private ASN1ObjectIdentifier encryptionOID; private int keySize; private EnvelopedDataHelper helper = new EnvelopedDataHelper(); private SecureRandom random; public BcCMSContentEncryptorBuilder(ASN1ObjectIdentifier encryptionOID) { this(encryptionOID, getKeySize(encryptionOID)); } public BcCMSContentEncryptorBuilder(ASN1ObjectIdentifier encryptionOID, int keySize) { this.encryptionOID = encryptionOID; this.keySize = keySize; } public BcCMSContentEncryptorBuilder setSecureRandom(SecureRandom random) { this.random = random; return this; } public OutputEncryptor build() throws CMSException { return new CMSOutputEncryptor(encryptionOID, keySize, random); } private class CMSOutputEncryptor implements OutputEncryptor { private KeyParameter encKey; private AlgorithmIdentifier algorithmIdentifier; private Object cipher; CMSOutputEncryptor(ASN1ObjectIdentifier encryptionOID, int keySize, SecureRandom random) throws CMSException { if (random == null) { random = new SecureRandom(); } CipherKeyGenerator keyGen = helper.createKeyGenerator(encryptionOID, random); encKey = new KeyParameter(keyGen.generateKey()); algorithmIdentifier = helper.generateAlgorithmIdentifier(encryptionOID, encKey, random); cipher = helper.createContentCipher(true, encKey, algorithmIdentifier); } public AlgorithmIdentifier getAlgorithmIdentifier() { return algorithmIdentifier; } public OutputStream getOutputStream(OutputStream dOut) { if (cipher instanceof BufferedBlockCipher) { return new CipherOutputStream(dOut, (BufferedBlockCipher)cipher); } else { return new CipherOutputStream(dOut, (StreamCipher)cipher); } } public GenericKey getKey() { return new GenericKey(algorithmIdentifier, encKey.getKey()); } } } bouncycastle-1.49.orig/jdk1.2/org/bouncycastle/cms/jcajce/0000755000175000017500000000000012152033550022701 5ustar ebourgebourgbouncycastle-1.49.orig/jdk1.2/org/bouncycastle/cms/jcajce/JceCMSContentEncryptorBuilder.java0000644000175000017500000001121512103632343031361 0ustar ebourgebourgpackage org.bouncycastle.cms.jcajce; import java.io.OutputStream; import java.security.AlgorithmParameters; import java.security.GeneralSecurityException; import java.security.Provider; import java.security.SecureRandom; import java.util.HashMap; import java.util.Map; import javax.crypto.Cipher; import javax.crypto.CipherOutputStream; import javax.crypto.KeyGenerator; import javax.crypto.SecretKey; import org.bouncycastle.asn1.ASN1ObjectIdentifier; import org.bouncycastle.asn1.x509.AlgorithmIdentifier; import org.bouncycastle.cms.CMSAlgorithm; import org.bouncycastle.cms.CMSException; import org.bouncycastle.operator.GenericKey; import org.bouncycastle.operator.OutputEncryptor; import org.bouncycastle.util.Integers; public class JceCMSContentEncryptorBuilder { private static Map keySizes = new HashMap(); static { keySizes.put(CMSAlgorithm.AES128_CBC, Integers.valueOf(128)); keySizes.put(CMSAlgorithm.AES192_CBC, Integers.valueOf(192)); keySizes.put(CMSAlgorithm.AES256_CBC, Integers.valueOf(256)); keySizes.put(CMSAlgorithm.CAMELLIA128_CBC, Integers.valueOf(128)); keySizes.put(CMSAlgorithm.CAMELLIA192_CBC, Integers.valueOf(192)); keySizes.put(CMSAlgorithm.CAMELLIA256_CBC, Integers.valueOf(256)); } private static int getKeySize(ASN1ObjectIdentifier oid) { Integer size = (Integer)keySizes.get(oid); if (size != null) { return size.intValue(); } return -1; } private ASN1ObjectIdentifier encryptionOID; private int keySize; private EnvelopedDataHelper helper = new EnvelopedDataHelper(new DefaultJcaJceExtHelper()); private SecureRandom random; public JceCMSContentEncryptorBuilder(ASN1ObjectIdentifier encryptionOID) { this(encryptionOID, getKeySize(encryptionOID)); } public JceCMSContentEncryptorBuilder(ASN1ObjectIdentifier encryptionOID, int keySize) { this.encryptionOID = encryptionOID; this.keySize = keySize; } public JceCMSContentEncryptorBuilder setProvider(Provider provider) { this.helper = new EnvelopedDataHelper(new ProviderJcaJceExtHelper(provider)); return this; } public JceCMSContentEncryptorBuilder setProvider(String providerName) { this.helper = new EnvelopedDataHelper(new NamedJcaJceExtHelper(providerName)); return this; } public JceCMSContentEncryptorBuilder setSecureRandom(SecureRandom random) { this.random = random; return this; } public OutputEncryptor build() throws CMSException { return new CMSOutputEncryptor(encryptionOID, keySize, random); } private class CMSOutputEncryptor implements OutputEncryptor { private SecretKey encKey; private AlgorithmIdentifier algorithmIdentifier; private Cipher cipher; CMSOutputEncryptor(ASN1ObjectIdentifier encryptionOID, int keySize, SecureRandom random) throws CMSException { KeyGenerator keyGen = helper.createKeyGenerator(encryptionOID); if (random == null) { random = new SecureRandom(); } if (keySize < 0) { keyGen.init(random); } else { keyGen.init(keySize, random); } cipher = helper.createCipher(encryptionOID); encKey = keyGen.generateKey(); AlgorithmParameters params = helper.generateParameters(encryptionOID, encKey, random); try { cipher.init(Cipher.ENCRYPT_MODE, encKey, params, random); } catch (GeneralSecurityException e) { throw new CMSException("unable to initialize cipher: " + e.getMessage(), e); } // // If params are null we try and second guess on them as some providers don't provide // algorithm parameter generation explicity but instead generate them under the hood. // if (params == null) { params = cipher.getParameters(); } algorithmIdentifier = helper.getAlgorithmIdentifier(encryptionOID, params); } public AlgorithmIdentifier getAlgorithmIdentifier() { return algorithmIdentifier; } public OutputStream getOutputStream(OutputStream dOut) { return new CipherOutputStream(dOut, cipher); } public GenericKey getKey() { return new GenericKey(encKey); } } } bouncycastle-1.49.orig/jdk1.2/org/bouncycastle/cms/jcajce/JceCMSMacCalculatorBuilder.java0000644000175000017500000001043211726307267030571 0ustar ebourgebourgpackage org.bouncycastle.cms.jcajce; import java.io.OutputStream; import java.security.AlgorithmParameterGenerator; import java.security.AlgorithmParameters; import java.security.GeneralSecurityException; import java.security.Provider; import java.security.SecureRandom; import java.security.spec.AlgorithmParameterSpec; import javax.crypto.KeyGenerator; import javax.crypto.Mac; import javax.crypto.SecretKey; import javax.crypto.spec.IvParameterSpec; import javax.crypto.spec.RC2ParameterSpec; import org.bouncycastle.asn1.ASN1ObjectIdentifier; import org.bouncycastle.asn1.pkcs.PKCSObjectIdentifiers; import org.bouncycastle.asn1.x509.AlgorithmIdentifier; import org.bouncycastle.cms.CMSException; import org.bouncycastle.jcajce.io.MacOutputStream; import org.bouncycastle.operator.GenericKey; import org.bouncycastle.operator.MacCalculator; public class JceCMSMacCalculatorBuilder { private ASN1ObjectIdentifier macOID; private int keySize; private EnvelopedDataHelper helper = new EnvelopedDataHelper(new DefaultJcaJceExtHelper()); private SecureRandom random; private MacOutputStream macOutputStream; public JceCMSMacCalculatorBuilder(ASN1ObjectIdentifier macOID) { this(macOID, -1); } public JceCMSMacCalculatorBuilder(ASN1ObjectIdentifier macOID, int keySize) { this.macOID = macOID; this.keySize = keySize; } public JceCMSMacCalculatorBuilder setProvider(Provider provider) { this.helper = new EnvelopedDataHelper(new ProviderJcaJceExtHelper(provider)); return this; } public JceCMSMacCalculatorBuilder setProvider(String providerName) { this.helper = new EnvelopedDataHelper(new NamedJcaJceExtHelper(providerName)); return this; } public JceCMSMacCalculatorBuilder setSecureRandom(SecureRandom random) { this.random = random; return this; } public MacCalculator build() throws CMSException { return new CMSOutputEncryptor(macOID, keySize, random); } private class CMSOutputEncryptor implements MacCalculator { private SecretKey encKey; private AlgorithmIdentifier algorithmIdentifier; private Mac mac; private SecureRandom random; CMSOutputEncryptor(ASN1ObjectIdentifier macOID, int keySize, SecureRandom random) throws CMSException { KeyGenerator keyGen = helper.createKeyGenerator(macOID); if (random == null) { random = new SecureRandom(); } this.random = random; if (keySize < 0) { keyGen.init(random); } else { keyGen.init(keySize, random); } encKey = keyGen.generateKey(); AlgorithmParameterSpec paramSpec = generateParameterSpec(macOID, encKey); algorithmIdentifier = helper.getAlgorithmIdentifier(macOID, paramSpec); mac = helper.createContentMac(encKey, algorithmIdentifier); } public AlgorithmIdentifier getAlgorithmIdentifier() { return algorithmIdentifier; } public OutputStream getOutputStream() { return new MacOutputStream(mac); } public byte[] getMac() { return mac.doFinal(); } public GenericKey getKey() { return new GenericKey(encKey); } protected AlgorithmParameterSpec generateParameterSpec(ASN1ObjectIdentifier macOID, SecretKey encKey) throws CMSException { try { if (macOID.equals(PKCSObjectIdentifiers.RC2_CBC)) { byte[] iv = new byte[8]; random.nextBytes(iv); return new RC2ParameterSpec(encKey.getEncoded().length * 8, iv); } AlgorithmParameterGenerator pGen = helper.createAlgorithmParameterGenerator(macOID); AlgorithmParameters p = pGen.generateParameters(); return p.getParameterSpec(IvParameterSpec.class); } catch (GeneralSecurityException e) { return null; } } } } bouncycastle-1.49.orig/jdk1.2/org/bouncycastle/jce/0000755000175000017500000000000012152033550021441 5ustar ebourgebourgbouncycastle-1.49.orig/jdk1.2/org/bouncycastle/jce/exception/0000755000175000017500000000000012152033550023437 5ustar ebourgebourgbouncycastle-1.49.orig/jdk1.2/org/bouncycastle/jce/exception/ExtCertPathValidatorException.java0000644000175000017500000000126510713307472032236 0ustar ebourgebourgpackage org.bouncycastle.jce.exception; import org.bouncycastle.jce.cert.CertPath; import org.bouncycastle.jce.cert.CertPathValidatorException; public class ExtCertPathValidatorException extends CertPathValidatorException implements ExtException { private Throwable cause; public ExtCertPathValidatorException(String message, Throwable cause) { super(message); this.cause = cause; } public ExtCertPathValidatorException(String msg, Throwable cause, CertPath certPath, int index) { super(msg, cause, certPath, index); this.cause = cause; } public Throwable getCause() { return cause; } } bouncycastle-1.49.orig/jdk1.2/org/bouncycastle/jce/exception/ExtCertPathBuilderException.java0000644000175000017500000000123210713307472031671 0ustar ebourgebourgpackage org.bouncycastle.jce.exception; import org.bouncycastle.jce.cert.CertPath; import org.bouncycastle.jce.cert.CertPathBuilderException; public class ExtCertPathBuilderException extends CertPathBuilderException implements ExtException { private Throwable cause; public ExtCertPathBuilderException(String message, Throwable cause) { super(message); this.cause = cause; } public ExtCertPathBuilderException(String msg, Throwable cause, CertPath certPath, int index) { super(msg, cause); this.cause = cause; } public Throwable getCause() { return cause; } } bouncycastle-1.49.orig/jdk1.2/java/0000755000175000017500000000000012152033550016337 5ustar ebourgebourgbouncycastle-1.49.orig/jdk1.2/java/security/0000755000175000017500000000000012152033550020206 5ustar ebourgebourgbouncycastle-1.49.orig/jdk1.2/java/security/spec/0000755000175000017500000000000012152033550021140 5ustar ebourgebourgbouncycastle-1.49.orig/jdk1.2/java/security/spec/PSSParameterSpec.java0000644000175000017500000000154410262753174025143 0ustar ebourgebourg package java.security.spec; /** * This class specifies a parameter spec for RSA PSS encoding scheme, * as defined in the PKCS#1 v2.1. * * @since 1.4 * @see AlgorithmParameterSpec, Signature */ public class PSSParameterSpec extends Object implements AlgorithmParameterSpec { private int saltLen; /** * Creates a new PSSParameterSpec given the salt length as defined * in PKCS#1. * * @param saltLen - the length of salt in bits to be used in PKCS#1 * PSS encoding. * @throws IllegalArgumentException - if saltLen is less than 0. */ public PSSParameterSpec(int saltLen) { if ( saltLen < 0 ) { throw new IllegalArgumentException("Salt length must be >= 0"); } this.saltLen = saltLen; } /** * Returns the salt length in bits. * * @returns the salt length. */ public int getSaltLength() { return saltLen; } } bouncycastle-1.49.orig/jdk1.2/java/security/spec/RSAMultiPrimePrivateCrtKeySpec.java0000644000175000017500000000740310262753174027747 0ustar ebourgebourg package java.security.spec; import java.math.BigInteger; /** * This class specifies an RSA multi-prime private key, as defined in * the PKCS#1 v2.1, using the Chinese Remainder Theorem (CRT) information * values for efficiency. * * @since 1.4 * @see Key, KeyFactory, KeySpec, PKCS8EncodedKeySpec, RSAPrivateKeySpec, * RSAPublicKeySpec, RSAOtherPrimeInfo */ public class RSAMultiPrimePrivateCrtKeySpec extends RSAPrivateKeySpec { private BigInteger publicExponent; private BigInteger privateExponent; private BigInteger primeP; private BigInteger primeQ; private BigInteger primeExponentP; private BigInteger primeExponentQ; private BigInteger crtCoefficient; private RSAOtherPrimeInfo[] otherPrimeInfo; /** * Creates a new RSAMultiPrimePrivateCrtKeySpec given the modulus, * publicExponent, privateExponent, primeP, primeQ, primeExponentP, * primeExponentQ, crtCoefficient, and otherPrimeInfo as defined in * PKCS#1 v2.1. * * Note that otherPrimeInfo is cloned when constructing this object. * * @param modulus - the modulus n. * @param publicExponent - the public exponent e. * @param privateExponent - the private exponent d. * @param primeP - the prime factor p of n. * @param primeQ - the prime factor q of n. * @param primeExponentP - this is d mod (p-1). * @param primeExponentQ - this is d mod (q-1). * @param crtCoefficient - the Chinese Remainder Theorem coefficient q-1 * mod p. * @param otherPrimeInfo - triplets of the rest of primes, null can be * specified if there are only two prime factors (p and q). * @throws NullPointerException - if any of the parameters, i.e. modulus, * publicExponent, privateExponent, primeP, primeQ, primeExponentP, * primeExponentQ, crtCoefficient, is null. * @throws IllegalArgumentException - if an empty, i.e. 0-length, * otherPrimeInfo is specified. */ public RSAMultiPrimePrivateCrtKeySpec( BigInteger modulus, BigInteger publicExponent, BigInteger privateExponent, BigInteger primeP, BigInteger primeQ, BigInteger primeExponentP, BigInteger primeExponentQ, BigInteger crtCoefficient, RSAOtherPrimeInfo[] otherPrimeInfo) { super(modulus, privateExponent); if ( publicExponent == null || primeP == null || primeQ == null || primeExponentP == null || primeExponentQ == null || crtCoefficient == null ) { throw new NullPointerException("Invalid null argument"); } if ( otherPrimeInfo != null ) { if ( otherPrimeInfo.length == 0 ) { throw new IllegalArgumentException("Invalid length for otherPrimeInfo"); } this.otherPrimeInfo = (RSAOtherPrimeInfo[])otherPrimeInfo.clone(); } } /** * Returns the public exponent. * * @returns the public exponent. */ public BigInteger getPublicExponent() { return publicExponent; } /** * Returns the primeP. * * @returns the primeP. */ public BigInteger getPrimeP() { return primeP; } /** * Returns the primeQ. * * @returns the primeQ. */ public BigInteger getPrimeQ() { return primeQ; } /** * Returns the primeExponentP. * * @returns the primeExponentP. */ public BigInteger getPrimeExponentP() { return primeExponentP; } /** * Returns the primeExponentQ. * * @returns the primeExponentQ. */ public BigInteger getPrimeExponentQ() { return primeExponentQ; } /** * Returns the crtCofficient. * * @returns the crtCofficient. */ public BigInteger getCrtCoefficient() { return crtCoefficient; } /** * Returns a copy of the otherPrimeInfo or null if there are only * two prime factors (p and q). * * @returns the otherPrimeInfo. */ public RSAOtherPrimeInfo[] getOtherPrimeInfo() { if ( otherPrimeInfo != null ) { return (RSAOtherPrimeInfo[])otherPrimeInfo.clone(); } return null; } } bouncycastle-1.49.orig/jdk1.2/java/security/spec/RSAKeyGenParameterSpec.java0000644000175000017500000000135110262753174026222 0ustar ebourgebourgpackage java.security.spec; import java.math.BigInteger; /** * specifies parameters to be used for the generation of * a RSA key pair. */ public class RSAKeyGenParameterSpec implements AlgorithmParameterSpec { static BigInteger F0 = BigInteger.valueOf(3); static BigInteger F4 = BigInteger.valueOf(65537); private int keysize; private BigInteger publicExponent; public RSAKeyGenParameterSpec( int keysize, BigInteger publicExponent) { this.keysize = keysize; this.publicExponent = publicExponent; } public int getKeysize() { return keysize; } public BigInteger getPublicExponent() { return publicExponent; } } bouncycastle-1.49.orig/jdk1.2/java/security/spec/RSAOtherPrimeInfo.java0000644000175000017500000000331710262753174025262 0ustar ebourgebourg package java.security.spec; import java.math.BigInteger; /** * This class represents the triplet (prime, exponent, and coefficient) * inside RSA's OtherPrimeInfo structure, as defined in the PKCS#1 v2.1. * The ASN.1 syntax of RSA's OtherPrimeInfo is as follows: * *
     * OtherPrimeInfo ::= SEQUENCE {
     *    prime INTEGER,
     *    exponent INTEGER,
     *    coefficient INTEGER
     * }
     * 
    */ public class RSAOtherPrimeInfo extends Object { private BigInteger prime; private BigInteger primeExponent; private BigInteger crtCoefficient; /** * Creates a new RSAOtherPrimeInfo given the prime, primeExponent, * and crtCoefficient as defined in PKCS#1. * * @param prime - the prime factor of n. * @param primeExponent - the exponent. * @param crtCoefficient - the Chinese Remainder Theorem coefficient. * @throws NullPointerException - if any of the parameters, i.e. prime, * primeExponent, crtCoefficient, is null. */ public RSAOtherPrimeInfo( BigInteger prime, BigInteger primeExponent, BigInteger crtCoefficient) { if ( prime == null || primeExponent == null || crtCoefficient == null ) { throw new NullPointerException("Null parameter"); } this.prime = prime; this.primeExponent = primeExponent; this.crtCoefficient = crtCoefficient; } /** * Returns the prime. * * @returns the prime. */ public final BigInteger getPrime() { return prime; } /** * Returns the prime's exponent. * * @returns the primeExponent. */ public final BigInteger getExponent() { return primeExponent; } /** * Returns the prime's crtCoefficient. * * @returns the crtCoefficient. */ public final BigInteger getCrtCoefficient() { return crtCoefficient; } } bouncycastle-1.49.orig/jdk1.2/java/security/interfaces/0000755000175000017500000000000012152033550022331 5ustar ebourgebourgbouncycastle-1.49.orig/jdk1.2/java/security/interfaces/RSAMultiPrimePrivateCrtKey.java0000644000175000017500000000245210262753174030324 0ustar ebourgebourg package java.security.interfaces; import java.math.BigInteger; import java.security.spec.RSAOtherPrimeInfo; /** * The interface to an RSA multi-prime private key, as defined in the * PKCS#1 v2.1, using the Chinese Remainder Theorem (CRT) information values. * * @since 1.4 * @see RSAPrivateKeySpec, RSAMultiPrimePrivateCrtKeySpec, RSAPrivateKey, * RSAPrivateCrtKey */ public interface RSAMultiPrimePrivateCrtKey extends RSAPrivateKey { /** * Returns the public exponent. * * @returns the public exponent. */ public BigInteger getPublicExponent(); /** * Returns the primeP. * * @returns the primeP. */ public BigInteger getPrimeP(); /** * Returns the primeQ. * * @returns the primeQ. */ public BigInteger getPrimeQ(); /** * Returns the primeExponentP. * * @returns the primeExponentP. */ public BigInteger getPrimeExponentP(); /** * Returns the primeExponentQ. * * @returns the primeExponentQ. */ public BigInteger getPrimeExponentQ(); /** * Returns the crtCoefficient. * * @returns the crtCoefficient. */ public BigInteger getCrtCoefficient(); /** * Returns the otherPrimeInfo or null if there are only two prime * factors (p and q). * * @returns the otherPrimeInfo. */ public RSAOtherPrimeInfo[] getOtherPrimeInfo(); } bouncycastle-1.49.orig/bzip2/0000755000175000017500000000000012152033551015454 5ustar ebourgebourgbouncycastle-1.49.orig/bzip2/src/0000755000175000017500000000000012152033551016243 5ustar ebourgebourgbouncycastle-1.49.orig/bzip2/src/org/0000755000175000017500000000000012152033551017032 5ustar ebourgebourgbouncycastle-1.49.orig/bzip2/src/org/bouncycastle/0000755000175000017500000000000012152033551021525 5ustar ebourgebourgbouncycastle-1.49.orig/bzip2/src/org/bouncycastle/apache/0000755000175000017500000000000012152033551022746 5ustar ebourgebourgbouncycastle-1.49.orig/bzip2/src/org/bouncycastle/apache/bzip2/0000755000175000017500000000000012152033551023774 5ustar ebourgebourgbouncycastle-1.49.orig/bzip2/src/org/bouncycastle/apache/bzip2/BZip2Constants.java0000644000175000017500000001057011310312565027465 0ustar ebourgebourg/* * Licensed to the Apache Software Foundation (ASF) under one or more * contributor license agreements. See the NOTICE file distributed with * this work for additional information regarding copyright ownership. * The ASF licenses this file to You under the Apache License, Version 2.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.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. * */ /* * This package is based on the work done by Keiron Liddle, Aftex Software * to whom the Ant project is very grateful for his * great code. */ package org.bouncycastle.apache.bzip2; /** * Base class for both the compress and decompress classes. * Holds common arrays, and static data. * * @author Keiron Liddle */ public interface BZip2Constants { int baseBlockSize = 100000; int MAX_ALPHA_SIZE = 258; int MAX_CODE_LEN = 23; int RUNA = 0; int RUNB = 1; int N_GROUPS = 6; int G_SIZE = 50; int N_ITERS = 4; int MAX_SELECTORS = (2 + (900000 / G_SIZE)); int NUM_OVERSHOOT_BYTES = 20; int[] rNums = { 619, 720, 127, 481, 931, 816, 813, 233, 566, 247, 985, 724, 205, 454, 863, 491, 741, 242, 949, 214, 733, 859, 335, 708, 621, 574, 73, 654, 730, 472, 419, 436, 278, 496, 867, 210, 399, 680, 480, 51, 878, 465, 811, 169, 869, 675, 611, 697, 867, 561, 862, 687, 507, 283, 482, 129, 807, 591, 733, 623, 150, 238, 59, 379, 684, 877, 625, 169, 643, 105, 170, 607, 520, 932, 727, 476, 693, 425, 174, 647, 73, 122, 335, 530, 442, 853, 695, 249, 445, 515, 909, 545, 703, 919, 874, 474, 882, 500, 594, 612, 641, 801, 220, 162, 819, 984, 589, 513, 495, 799, 161, 604, 958, 533, 221, 400, 386, 867, 600, 782, 382, 596, 414, 171, 516, 375, 682, 485, 911, 276, 98, 553, 163, 354, 666, 933, 424, 341, 533, 870, 227, 730, 475, 186, 263, 647, 537, 686, 600, 224, 469, 68, 770, 919, 190, 373, 294, 822, 808, 206, 184, 943, 795, 384, 383, 461, 404, 758, 839, 887, 715, 67, 618, 276, 204, 918, 873, 777, 604, 560, 951, 160, 578, 722, 79, 804, 96, 409, 713, 940, 652, 934, 970, 447, 318, 353, 859, 672, 112, 785, 645, 863, 803, 350, 139, 93, 354, 99, 820, 908, 609, 772, 154, 274, 580, 184, 79, 626, 630, 742, 653, 282, 762, 623, 680, 81, 927, 626, 789, 125, 411, 521, 938, 300, 821, 78, 343, 175, 128, 250, 170, 774, 972, 275, 999, 639, 495, 78, 352, 126, 857, 956, 358, 619, 580, 124, 737, 594, 701, 612, 669, 112, 134, 694, 363, 992, 809, 743, 168, 974, 944, 375, 748, 52, 600, 747, 642, 182, 862, 81, 344, 805, 988, 739, 511, 655, 814, 334, 249, 515, 897, 955, 664, 981, 649, 113, 974, 459, 893, 228, 433, 837, 553, 268, 926, 240, 102, 654, 459, 51, 686, 754, 806, 760, 493, 403, 415, 394, 687, 700, 946, 670, 656, 610, 738, 392, 760, 799, 887, 653, 978, 321, 576, 617, 626, 502, 894, 679, 243, 440, 680, 879, 194, 572, 640, 724, 926, 56, 204, 700, 707, 151, 457, 449, 797, 195, 791, 558, 945, 679, 297, 59, 87, 824, 713, 663, 412, 693, 342, 606, 134, 108, 571, 364, 631, 212, 174, 643, 304, 329, 343, 97, 430, 751, 497, 314, 983, 374, 822, 928, 140, 206, 73, 263, 980, 736, 876, 478, 430, 305, 170, 514, 364, 692, 829, 82, 855, 953, 676, 246, 369, 970, 294, 750, 807, 827, 150, 790, 288, 923, 804, 378, 215, 828, 592, 281, 565, 555, 710, 82, 896, 831, 547, 261, 524, 462, 293, 465, 502, 56, 661, 821, 976, 991, 658, 869, 905, 758, 745, 193, 768, 550, 608, 933, 378, 286, 215, 979, 792, 961, 61, 688, 793, 644, 986, 403, 106, 366, 905, 644, 372, 567, 466, 434, 645, 210, 389, 550, 919, 135, 780, 773, 635, 389, 707, 100, 626, 958, 165, 504, 920, 176, 193, 713, 857, 265, 203, 50, 668, 108, 645, 990, 626, 197, 510, 357, 358, 850, 858, 364, 936, 638 }; } bouncycastle-1.49.orig/bzip2/src/org/bouncycastle/apache/bzip2/CRC.java0000644000175000017500000001234511310312627025252 0ustar ebourgebourg/* * Licensed to the Apache Software Foundation (ASF) under one or more * contributor license agreements. See the NOTICE file distributed with * this work for additional information regarding copyright ownership. * The ASF licenses this file to You under the Apache License, Version 2.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.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. * */ /* * This package is based on the work done by Keiron Liddle, Aftex Software * to whom the Ant project is very grateful for his * great code. */ package org.bouncycastle.apache.bzip2; /** * A simple class the hold and calculate the CRC for sanity checking * of the data. * * @author Keiron Liddle */ class CRC { public static int crc32Table[] = { 0x00000000, 0x04c11db7, 0x09823b6e, 0x0d4326d9, 0x130476dc, 0x17c56b6b, 0x1a864db2, 0x1e475005, 0x2608edb8, 0x22c9f00f, 0x2f8ad6d6, 0x2b4bcb61, 0x350c9b64, 0x31cd86d3, 0x3c8ea00a, 0x384fbdbd, 0x4c11db70, 0x48d0c6c7, 0x4593e01e, 0x4152fda9, 0x5f15adac, 0x5bd4b01b, 0x569796c2, 0x52568b75, 0x6a1936c8, 0x6ed82b7f, 0x639b0da6, 0x675a1011, 0x791d4014, 0x7ddc5da3, 0x709f7b7a, 0x745e66cd, 0x9823b6e0, 0x9ce2ab57, 0x91a18d8e, 0x95609039, 0x8b27c03c, 0x8fe6dd8b, 0x82a5fb52, 0x8664e6e5, 0xbe2b5b58, 0xbaea46ef, 0xb7a96036, 0xb3687d81, 0xad2f2d84, 0xa9ee3033, 0xa4ad16ea, 0xa06c0b5d, 0xd4326d90, 0xd0f37027, 0xddb056fe, 0xd9714b49, 0xc7361b4c, 0xc3f706fb, 0xceb42022, 0xca753d95, 0xf23a8028, 0xf6fb9d9f, 0xfbb8bb46, 0xff79a6f1, 0xe13ef6f4, 0xe5ffeb43, 0xe8bccd9a, 0xec7dd02d, 0x34867077, 0x30476dc0, 0x3d044b19, 0x39c556ae, 0x278206ab, 0x23431b1c, 0x2e003dc5, 0x2ac12072, 0x128e9dcf, 0x164f8078, 0x1b0ca6a1, 0x1fcdbb16, 0x018aeb13, 0x054bf6a4, 0x0808d07d, 0x0cc9cdca, 0x7897ab07, 0x7c56b6b0, 0x71159069, 0x75d48dde, 0x6b93dddb, 0x6f52c06c, 0x6211e6b5, 0x66d0fb02, 0x5e9f46bf, 0x5a5e5b08, 0x571d7dd1, 0x53dc6066, 0x4d9b3063, 0x495a2dd4, 0x44190b0d, 0x40d816ba, 0xaca5c697, 0xa864db20, 0xa527fdf9, 0xa1e6e04e, 0xbfa1b04b, 0xbb60adfc, 0xb6238b25, 0xb2e29692, 0x8aad2b2f, 0x8e6c3698, 0x832f1041, 0x87ee0df6, 0x99a95df3, 0x9d684044, 0x902b669d, 0x94ea7b2a, 0xe0b41de7, 0xe4750050, 0xe9362689, 0xedf73b3e, 0xf3b06b3b, 0xf771768c, 0xfa325055, 0xfef34de2, 0xc6bcf05f, 0xc27dede8, 0xcf3ecb31, 0xcbffd686, 0xd5b88683, 0xd1799b34, 0xdc3abded, 0xd8fba05a, 0x690ce0ee, 0x6dcdfd59, 0x608edb80, 0x644fc637, 0x7a089632, 0x7ec98b85, 0x738aad5c, 0x774bb0eb, 0x4f040d56, 0x4bc510e1, 0x46863638, 0x42472b8f, 0x5c007b8a, 0x58c1663d, 0x558240e4, 0x51435d53, 0x251d3b9e, 0x21dc2629, 0x2c9f00f0, 0x285e1d47, 0x36194d42, 0x32d850f5, 0x3f9b762c, 0x3b5a6b9b, 0x0315d626, 0x07d4cb91, 0x0a97ed48, 0x0e56f0ff, 0x1011a0fa, 0x14d0bd4d, 0x19939b94, 0x1d528623, 0xf12f560e, 0xf5ee4bb9, 0xf8ad6d60, 0xfc6c70d7, 0xe22b20d2, 0xe6ea3d65, 0xeba91bbc, 0xef68060b, 0xd727bbb6, 0xd3e6a601, 0xdea580d8, 0xda649d6f, 0xc423cd6a, 0xc0e2d0dd, 0xcda1f604, 0xc960ebb3, 0xbd3e8d7e, 0xb9ff90c9, 0xb4bcb610, 0xb07daba7, 0xae3afba2, 0xaafbe615, 0xa7b8c0cc, 0xa379dd7b, 0x9b3660c6, 0x9ff77d71, 0x92b45ba8, 0x9675461f, 0x8832161a, 0x8cf30bad, 0x81b02d74, 0x857130c3, 0x5d8a9099, 0x594b8d2e, 0x5408abf7, 0x50c9b640, 0x4e8ee645, 0x4a4ffbf2, 0x470cdd2b, 0x43cdc09c, 0x7b827d21, 0x7f436096, 0x7200464f, 0x76c15bf8, 0x68860bfd, 0x6c47164a, 0x61043093, 0x65c52d24, 0x119b4be9, 0x155a565e, 0x18197087, 0x1cd86d30, 0x029f3d35, 0x065e2082, 0x0b1d065b, 0x0fdc1bec, 0x3793a651, 0x3352bbe6, 0x3e119d3f, 0x3ad08088, 0x2497d08d, 0x2056cd3a, 0x2d15ebe3, 0x29d4f654, 0xc5a92679, 0xc1683bce, 0xcc2b1d17, 0xc8ea00a0, 0xd6ad50a5, 0xd26c4d12, 0xdf2f6bcb, 0xdbee767c, 0xe3a1cbc1, 0xe760d676, 0xea23f0af, 0xeee2ed18, 0xf0a5bd1d, 0xf464a0aa, 0xf9278673, 0xfde69bc4, 0x89b8fd09, 0x8d79e0be, 0x803ac667, 0x84fbdbd0, 0x9abc8bd5, 0x9e7d9662, 0x933eb0bb, 0x97ffad0c, 0xafb010b1, 0xab710d06, 0xa6322bdf, 0xa2f33668, 0xbcb4666d, 0xb8757bda, 0xb5365d03, 0xb1f740b4 }; public CRC() { initialiseCRC(); } void initialiseCRC() { globalCrc = 0xffffffff; } int getFinalCRC() { return ~globalCrc; } int getGlobalCRC() { return globalCrc; } void setGlobalCRC(int newCrc) { globalCrc = newCrc; } void updateCRC(int inCh) { int temp = (globalCrc >> 24) ^ inCh; if (temp < 0) { temp = 256 + temp; } globalCrc = (globalCrc << 8) ^ CRC.crc32Table[temp]; } int globalCrc; } bouncycastle-1.49.orig/bzip2/src/org/bouncycastle/apache/bzip2/CBZip2OutputStream.java0000644000175000017500000013304411337356221030300 0ustar ebourgebourg/* * Licensed to the Apache Software Foundation (ASF) under one or more * contributor license agreements. See the NOTICE file distributed with * this work for additional information regarding copyright ownership. * The ASF licenses this file to You under the Apache License, Version 2.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.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. * */ /* * This package is based on the work done by Keiron Liddle, Aftex Software * to whom the Ant project is very grateful for his * great code. */ package org.bouncycastle.apache.bzip2; import java.io.OutputStream; import java.io.IOException; /** * An output stream that compresses into the BZip2 format (with the file * header chars) into another stream. * * @author Keiron Liddle * * TODO: Update to BZip2 1.0.1 * NB: note this class has been modified to add a leading BZ to the * start of the BZIP2 stream to make it compatible with other PGP programs. */ public class CBZip2OutputStream extends OutputStream implements BZip2Constants { protected static final int SETMASK = (1 << 21); protected static final int CLEARMASK = (~SETMASK); protected static final int GREATER_ICOST = 15; protected static final int LESSER_ICOST = 0; protected static final int SMALL_THRESH = 20; protected static final int DEPTH_THRESH = 10; /* If you are ever unlucky/improbable enough to get a stack overflow whilst sorting, increase the following constant and try again. In practice I have never seen the stack go above 27 elems, so the following limit seems very generous. */ protected static final int QSORT_STACK_SIZE = 1000; private boolean finished; private static void panic() { System.out.println("panic"); //throw new CError(); } private void makeMaps() { int i; nInUse = 0; for (i = 0; i < 256; i++) { if (inUse[i]) { seqToUnseq[nInUse] = (char) i; unseqToSeq[i] = (char) nInUse; nInUse++; } } } protected static void hbMakeCodeLengths(char[] len, int[] freq, int alphaSize, int maxLen) { /* Nodes and heap entries run from 1. Entry 0 for both the heap and nodes is a sentinel. */ int nNodes, nHeap, n1, n2, i, j, k; boolean tooLong; int[] heap = new int[MAX_ALPHA_SIZE + 2]; int[] weight = new int[MAX_ALPHA_SIZE * 2]; int[] parent = new int[MAX_ALPHA_SIZE * 2]; for (i = 0; i < alphaSize; i++) { weight[i + 1] = (freq[i] == 0 ? 1 : freq[i]) << 8; } while (true) { nNodes = alphaSize; nHeap = 0; heap[0] = 0; weight[0] = 0; parent[0] = -2; for (i = 1; i <= alphaSize; i++) { parent[i] = -1; nHeap++; heap[nHeap] = i; { int zz, tmp; zz = nHeap; tmp = heap[zz]; while (weight[tmp] < weight[heap[zz >> 1]]) { heap[zz] = heap[zz >> 1]; zz >>= 1; } heap[zz] = tmp; } } if (!(nHeap < (MAX_ALPHA_SIZE + 2))) { panic(); } while (nHeap > 1) { n1 = heap[1]; heap[1] = heap[nHeap]; nHeap--; { int zz = 0, yy = 0, tmp = 0; zz = 1; tmp = heap[zz]; while (true) { yy = zz << 1; if (yy > nHeap) { break; } if (yy < nHeap && weight[heap[yy + 1]] < weight[heap[yy]]) { yy++; } if (weight[tmp] < weight[heap[yy]]) { break; } heap[zz] = heap[yy]; zz = yy; } heap[zz] = tmp; } n2 = heap[1]; heap[1] = heap[nHeap]; nHeap--; { int zz = 0, yy = 0, tmp = 0; zz = 1; tmp = heap[zz]; while (true) { yy = zz << 1; if (yy > nHeap) { break; } if (yy < nHeap && weight[heap[yy + 1]] < weight[heap[yy]]) { yy++; } if (weight[tmp] < weight[heap[yy]]) { break; } heap[zz] = heap[yy]; zz = yy; } heap[zz] = tmp; } nNodes++; parent[n1] = parent[n2] = nNodes; weight[nNodes] = ((weight[n1] & 0xffffff00) + (weight[n2] & 0xffffff00)) | (1 + (((weight[n1] & 0x000000ff) > (weight[n2] & 0x000000ff)) ? (weight[n1] & 0x000000ff) : (weight[n2] & 0x000000ff))); parent[nNodes] = -1; nHeap++; heap[nHeap] = nNodes; { int zz = 0, tmp = 0; zz = nHeap; tmp = heap[zz]; while (weight[tmp] < weight[heap[zz >> 1]]) { heap[zz] = heap[zz >> 1]; zz >>= 1; } heap[zz] = tmp; } } if (!(nNodes < (MAX_ALPHA_SIZE * 2))) { panic(); } tooLong = false; for (i = 1; i <= alphaSize; i++) { j = 0; k = i; while (parent[k] >= 0) { k = parent[k]; j++; } len[i - 1] = (char) j; if (j > maxLen) { tooLong = true; } } if (!tooLong) { break; } for (i = 1; i < alphaSize; i++) { j = weight[i] >> 8; j = 1 + (j / 2); weight[i] = j << 8; } } } /* index of the last char in the block, so the block size == last + 1. */ int last; /* index in zptr[] of original string after sorting. */ int origPtr; /* always: in the range 0 .. 9. The current block size is 100000 * this number. */ int blockSize100k; boolean blockRandomised; int bytesOut; int bsBuff; int bsLive; CRC mCrc = new CRC(); private boolean[] inUse = new boolean[256]; private int nInUse; private char[] seqToUnseq = new char[256]; private char[] unseqToSeq = new char[256]; private char[] selector = new char[MAX_SELECTORS]; private char[] selectorMtf = new char[MAX_SELECTORS]; private char[] block; private int[] quadrant; private int[] zptr; private short[] szptr; private int[] ftab; private int nMTF; private int[] mtfFreq = new int[MAX_ALPHA_SIZE]; /* * Used when sorting. If too many long comparisons * happen, we stop sorting, randomise the block * slightly, and try again. */ private int workFactor; private int workDone; private int workLimit; private boolean firstAttempt; private int nBlocksRandomised; private int currentChar = -1; private int runLength = 0; public CBZip2OutputStream(OutputStream inStream) throws IOException { this(inStream, 9); } public CBZip2OutputStream(OutputStream inStream, int inBlockSize) throws IOException { block = null; quadrant = null; zptr = null; ftab = null; inStream.write('B'); inStream.write('Z'); bsSetStream(inStream); workFactor = 50; if (inBlockSize > 9) { inBlockSize = 9; } if (inBlockSize < 1) { inBlockSize = 1; } blockSize100k = inBlockSize; allocateCompressStructures(); initialize(); initBlock(); } /** * * modified by Oliver Merkel, 010128 * */ public void write(int bv) throws IOException { int b = (256 + bv) % 256; if (currentChar != -1) { if (currentChar == b) { runLength++; if (runLength > 254) { writeRun(); currentChar = -1; runLength = 0; } } else { writeRun(); runLength = 1; currentChar = b; } } else { currentChar = b; runLength++; } } private void writeRun() throws IOException { if (last < allowableBlockSize) { inUse[currentChar] = true; for (int i = 0; i < runLength; i++) { mCrc.updateCRC((char) currentChar); } switch (runLength) { case 1: last++; block[last + 1] = (char) currentChar; break; case 2: last++; block[last + 1] = (char) currentChar; last++; block[last + 1] = (char) currentChar; break; case 3: last++; block[last + 1] = (char) currentChar; last++; block[last + 1] = (char) currentChar; last++; block[last + 1] = (char) currentChar; break; default: inUse[runLength - 4] = true; last++; block[last + 1] = (char) currentChar; last++; block[last + 1] = (char) currentChar; last++; block[last + 1] = (char) currentChar; last++; block[last + 1] = (char) currentChar; last++; block[last + 1] = (char) (runLength - 4); break; } } else { endBlock(); initBlock(); writeRun(); } } boolean closed = false; protected void finalize() throws Throwable { close(); super.finalize(); } public void close() throws IOException { if (closed) { return; } finish(); closed = true; super.close(); bsStream.close(); } public void finish() throws IOException { if (finished) { return; } if (runLength > 0) { writeRun(); } currentChar = -1; endBlock(); endCompression(); finished = true; flush(); } public void flush() throws IOException { super.flush(); bsStream.flush(); } private int blockCRC, combinedCRC; private void initialize() throws IOException { bytesOut = 0; nBlocksRandomised = 0; /* Write `magic' bytes h indicating file-format == huffmanised, followed by a digit indicating blockSize100k. */ bsPutUChar('h'); bsPutUChar('0' + blockSize100k); combinedCRC = 0; } private int allowableBlockSize; private void initBlock() { // blockNo++; mCrc.initialiseCRC(); last = -1; // ch = 0; for (int i = 0; i < 256; i++) { inUse[i] = false; } /* 20 is just a paranoia constant */ allowableBlockSize = baseBlockSize * blockSize100k - 20; } private void endBlock() throws IOException { blockCRC = mCrc.getFinalCRC(); combinedCRC = (combinedCRC << 1) | (combinedCRC >>> 31); combinedCRC ^= blockCRC; /* sort the block and establish posn of original string */ doReversibleTransformation(); /* A 6-byte block header, the value chosen arbitrarily as 0x314159265359 :-). A 32 bit value does not really give a strong enough guarantee that the value will not appear by chance in the compressed datastream. Worst-case probability of this event, for a 900k block, is about 2.0e-3 for 32 bits, 1.0e-5 for 40 bits and 4.0e-8 for 48 bits. For a compressed file of size 100Gb -- about 100000 blocks -- only a 48-bit marker will do. NB: normal compression/ decompression do *not* rely on these statistical properties. They are only important when trying to recover blocks from damaged files. */ bsPutUChar(0x31); bsPutUChar(0x41); bsPutUChar(0x59); bsPutUChar(0x26); bsPutUChar(0x53); bsPutUChar(0x59); /* Now the block's CRC, so it is in a known place. */ bsPutint(blockCRC); /* Now a single bit indicating randomisation. */ if (blockRandomised) { bsW(1, 1); nBlocksRandomised++; } else { bsW(1, 0); } /* Finally, block's contents proper. */ moveToFrontCodeAndSend(); } private void endCompression() throws IOException { /* Now another magic 48-bit number, 0x177245385090, to indicate the end of the last block. (sqrt(pi), if you want to know. I did want to use e, but it contains too much repetition -- 27 18 28 18 28 46 -- for me to feel statistically comfortable. Call me paranoid.) */ bsPutUChar(0x17); bsPutUChar(0x72); bsPutUChar(0x45); bsPutUChar(0x38); bsPutUChar(0x50); bsPutUChar(0x90); bsPutint(combinedCRC); bsFinishedWithStream(); } private void hbAssignCodes (int[] code, char[] length, int minLen, int maxLen, int alphaSize) { int n, vec, i; vec = 0; for (n = minLen; n <= maxLen; n++) { for (i = 0; i < alphaSize; i++) { if (length[i] == n) { code[i] = vec; vec++; } } vec <<= 1; } } private void bsSetStream(OutputStream f) { bsStream = f; bsLive = 0; bsBuff = 0; bytesOut = 0; } private void bsFinishedWithStream() throws IOException { while (bsLive > 0) { int ch = (bsBuff >> 24); try { bsStream.write(ch); // write 8-bit } catch (IOException e) { throw e; } bsBuff <<= 8; bsLive -= 8; bytesOut++; } } private void bsW(int n, int v) throws IOException { while (bsLive >= 8) { int ch = (bsBuff >> 24); try { bsStream.write(ch); // write 8-bit } catch (IOException e) { throw e; } bsBuff <<= 8; bsLive -= 8; bytesOut++; } bsBuff |= (v << (32 - bsLive - n)); bsLive += n; } private void bsPutUChar(int c) throws IOException { bsW(8, c); } private void bsPutint(int u) throws IOException { bsW(8, (u >> 24) & 0xff); bsW(8, (u >> 16) & 0xff); bsW(8, (u >> 8) & 0xff); bsW(8, u & 0xff); } private void bsPutIntVS(int numBits, int c) throws IOException { bsW(numBits, c); } private void sendMTFValues() throws IOException { char len[][] = new char[N_GROUPS][MAX_ALPHA_SIZE]; int v, t, i, j, gs, ge, totc, bt, bc, iter; int nSelectors = 0, alphaSize, minLen, maxLen, selCtr; int nGroups;//, nBytes; alphaSize = nInUse + 2; for (t = 0; t < N_GROUPS; t++) { for (v = 0; v < alphaSize; v++) { len[t][v] = (char) GREATER_ICOST; } } /* Decide how many coding tables to use */ if (nMTF <= 0) { panic(); } if (nMTF < 200) { nGroups = 2; } else if (nMTF < 600) { nGroups = 3; } else if (nMTF < 1200) { nGroups = 4; } else if (nMTF < 2400) { nGroups = 5; } else { nGroups = 6; } /* Generate an initial set of coding tables */ { int nPart, remF, tFreq, aFreq; nPart = nGroups; remF = nMTF; gs = 0; while (nPart > 0) { tFreq = remF / nPart; ge = gs - 1; aFreq = 0; while (aFreq < tFreq && ge < alphaSize - 1) { ge++; aFreq += mtfFreq[ge]; } if (ge > gs && nPart != nGroups && nPart != 1 && ((nGroups - nPart) % 2 == 1)) { aFreq -= mtfFreq[ge]; ge--; } for (v = 0; v < alphaSize; v++) { if (v >= gs && v <= ge) { len[nPart - 1][v] = (char) LESSER_ICOST; } else { len[nPart - 1][v] = (char) GREATER_ICOST; } } nPart--; gs = ge + 1; remF -= aFreq; } } int[][] rfreq = new int[N_GROUPS][MAX_ALPHA_SIZE]; int[] fave = new int[N_GROUPS]; short[] cost = new short[N_GROUPS]; /* Iterate up to N_ITERS times to improve the tables. */ for (iter = 0; iter < N_ITERS; iter++) { for (t = 0; t < nGroups; t++) { fave[t] = 0; } for (t = 0; t < nGroups; t++) { for (v = 0; v < alphaSize; v++) { rfreq[t][v] = 0; } } nSelectors = 0; totc = 0; gs = 0; while (true) { /* Set group start & end marks. */ if (gs >= nMTF) { break; } ge = gs + G_SIZE - 1; if (ge >= nMTF) { ge = nMTF - 1; } /* Calculate the cost of this group as coded by each of the coding tables. */ for (t = 0; t < nGroups; t++) { cost[t] = 0; } if (nGroups == 6) { short cost0, cost1, cost2, cost3, cost4, cost5; cost0 = cost1 = cost2 = cost3 = cost4 = cost5 = 0; for (i = gs; i <= ge; i++) { short icv = szptr[i]; cost0 += len[0][icv]; cost1 += len[1][icv]; cost2 += len[2][icv]; cost3 += len[3][icv]; cost4 += len[4][icv]; cost5 += len[5][icv]; } cost[0] = cost0; cost[1] = cost1; cost[2] = cost2; cost[3] = cost3; cost[4] = cost4; cost[5] = cost5; } else { for (i = gs; i <= ge; i++) { short icv = szptr[i]; for (t = 0; t < nGroups; t++) { cost[t] += len[t][icv]; } } } /* Find the coding table which is best for this group, and record its identity in the selector table. */ bc = 999999999; bt = -1; for (t = 0; t < nGroups; t++) { if (cost[t] < bc) { bc = cost[t]; bt = t; } } totc += bc; fave[bt]++; selector[nSelectors] = (char) bt; nSelectors++; /* Increment the symbol frequencies for the selected table. */ for (i = gs; i <= ge; i++) { rfreq[bt][szptr[i]]++; } gs = ge + 1; } /* Recompute the tables based on the accumulated frequencies. */ for (t = 0; t < nGroups; t++) { hbMakeCodeLengths(len[t], rfreq[t], alphaSize, 20); } } rfreq = null; fave = null; cost = null; if (!(nGroups < 8)) { panic(); } if (!(nSelectors < 32768 && nSelectors <= (2 + (900000 / G_SIZE)))) { panic(); } /* Compute MTF values for the selectors. */ { char[] pos = new char[N_GROUPS]; char ll_i, tmp2, tmp; for (i = 0; i < nGroups; i++) { pos[i] = (char) i; } for (i = 0; i < nSelectors; i++) { ll_i = selector[i]; j = 0; tmp = pos[j]; while (ll_i != tmp) { j++; tmp2 = tmp; tmp = pos[j]; pos[j] = tmp2; } pos[0] = tmp; selectorMtf[i] = (char) j; } } int[][] code = new int[N_GROUPS][MAX_ALPHA_SIZE]; /* Assign actual codes for the tables. */ for (t = 0; t < nGroups; t++) { minLen = 32; maxLen = 0; for (i = 0; i < alphaSize; i++) { if (len[t][i] > maxLen) { maxLen = len[t][i]; } if (len[t][i] < minLen) { minLen = len[t][i]; } } if (maxLen > 20) { panic(); } if (minLen < 1) { panic(); } hbAssignCodes(code[t], len[t], minLen, maxLen, alphaSize); } /* Transmit the mapping table. */ { boolean[] inUse16 = new boolean[16]; for (i = 0; i < 16; i++) { inUse16[i] = false; for (j = 0; j < 16; j++) { if (inUse[i * 16 + j]) { inUse16[i] = true; } } } // nBytes = bytesOut; for (i = 0; i < 16; i++) { if (inUse16[i]) { bsW(1, 1); } else { bsW(1, 0); } } for (i = 0; i < 16; i++) { if (inUse16[i]) { for (j = 0; j < 16; j++) { if (inUse[i * 16 + j]) { bsW(1, 1); } else { bsW(1, 0); } } } } } /* Now the selectors. */ // nBytes = bytesOut; bsW (3, nGroups); bsW (15, nSelectors); for (i = 0; i < nSelectors; i++) { for (j = 0; j < selectorMtf[i]; j++) { bsW(1, 1); } bsW(1, 0); } /* Now the coding tables. */ // nBytes = bytesOut; for (t = 0; t < nGroups; t++) { int curr = len[t][0]; bsW(5, curr); for (i = 0; i < alphaSize; i++) { while (curr < len[t][i]) { bsW(2, 2); curr++; /* 10 */ } while (curr > len[t][i]) { bsW(2, 3); curr--; /* 11 */ } bsW (1, 0); } } /* And finally, the block data proper */ // nBytes = bytesOut; selCtr = 0; gs = 0; while (true) { if (gs >= nMTF) { break; } ge = gs + G_SIZE - 1; if (ge >= nMTF) { ge = nMTF - 1; } for (i = gs; i <= ge; i++) { bsW(len[selector[selCtr]][szptr[i]], code[selector[selCtr]][szptr[i]]); } gs = ge + 1; selCtr++; } if (!(selCtr == nSelectors)) { panic(); } } private void moveToFrontCodeAndSend () throws IOException { bsPutIntVS(24, origPtr); generateMTFValues(); sendMTFValues(); } private OutputStream bsStream; private void simpleSort(int lo, int hi, int d) { int i, j, h, bigN, hp; int v; bigN = hi - lo + 1; if (bigN < 2) { return; } hp = 0; while (incs[hp] < bigN) { hp++; } hp--; for (; hp >= 0; hp--) { h = incs[hp]; i = lo + h; while (true) { /* copy 1 */ if (i > hi) { break; } v = zptr[i]; j = i; while (fullGtU(zptr[j - h] + d, v + d)) { zptr[j] = zptr[j - h]; j = j - h; if (j <= (lo + h - 1)) { break; } } zptr[j] = v; i++; /* copy 2 */ if (i > hi) { break; } v = zptr[i]; j = i; while (fullGtU(zptr[j - h] + d, v + d)) { zptr[j] = zptr[j - h]; j = j - h; if (j <= (lo + h - 1)) { break; } } zptr[j] = v; i++; /* copy 3 */ if (i > hi) { break; } v = zptr[i]; j = i; while (fullGtU(zptr[j - h] + d, v + d)) { zptr[j] = zptr[j - h]; j = j - h; if (j <= (lo + h - 1)) { break; } } zptr[j] = v; i++; if (workDone > workLimit && firstAttempt) { return; } } } } private void vswap(int p1, int p2, int n) { int temp = 0; while (n > 0) { temp = zptr[p1]; zptr[p1] = zptr[p2]; zptr[p2] = temp; p1++; p2++; n--; } } private char med3(char a, char b, char c) { char t; if (a > b) { t = a; a = b; b = t; } if (b > c) { t = b; b = c; c = t; } if (a > b) { b = a; } return b; } private static class StackElem { int ll; int hh; int dd; } private void qSort3(int loSt, int hiSt, int dSt) { int unLo, unHi, ltLo, gtHi, med, n, m; int sp, lo, hi, d; StackElem[] stack = new StackElem[QSORT_STACK_SIZE]; for (int count = 0; count < QSORT_STACK_SIZE; count++) { stack[count] = new StackElem(); } sp = 0; stack[sp].ll = loSt; stack[sp].hh = hiSt; stack[sp].dd = dSt; sp++; while (sp > 0) { if (sp >= QSORT_STACK_SIZE) { panic(); } sp--; lo = stack[sp].ll; hi = stack[sp].hh; d = stack[sp].dd; if (hi - lo < SMALL_THRESH || d > DEPTH_THRESH) { simpleSort(lo, hi, d); if (workDone > workLimit && firstAttempt) { return; } continue; } med = med3(block[zptr[lo] + d + 1], block[zptr[hi ] + d + 1], block[zptr[(lo + hi) >> 1] + d + 1]); unLo = ltLo = lo; unHi = gtHi = hi; while (true) { while (true) { if (unLo > unHi) { break; } n = ((int) block[zptr[unLo] + d + 1]) - med; if (n == 0) { int temp = 0; temp = zptr[unLo]; zptr[unLo] = zptr[ltLo]; zptr[ltLo] = temp; ltLo++; unLo++; continue; } if (n > 0) { break; } unLo++; } while (true) { if (unLo > unHi) { break; } n = ((int) block[zptr[unHi] + d + 1]) - med; if (n == 0) { int temp = 0; temp = zptr[unHi]; zptr[unHi] = zptr[gtHi]; zptr[gtHi] = temp; gtHi--; unHi--; continue; } if (n < 0) { break; } unHi--; } if (unLo > unHi) { break; } int temp = 0; temp = zptr[unLo]; zptr[unLo] = zptr[unHi]; zptr[unHi] = temp; unLo++; unHi--; } if (gtHi < ltLo) { stack[sp].ll = lo; stack[sp].hh = hi; stack[sp].dd = d + 1; sp++; continue; } n = ((ltLo - lo) < (unLo - ltLo)) ? (ltLo - lo) : (unLo - ltLo); vswap(lo, unLo - n, n); m = ((hi - gtHi) < (gtHi - unHi)) ? (hi - gtHi) : (gtHi - unHi); vswap(unLo, hi - m + 1, m); n = lo + unLo - ltLo - 1; m = hi - (gtHi - unHi) + 1; stack[sp].ll = lo; stack[sp].hh = n; stack[sp].dd = d; sp++; stack[sp].ll = n + 1; stack[sp].hh = m - 1; stack[sp].dd = d + 1; sp++; stack[sp].ll = m; stack[sp].hh = hi; stack[sp].dd = d; sp++; } } private void mainSort() { int i, j, ss, sb; int[] runningOrder = new int[256]; int[] copy = new int[256]; boolean[] bigDone = new boolean[256]; int c1, c2; int numQSorted; /* In the various block-sized structures, live data runs from 0 to last+NUM_OVERSHOOT_BYTES inclusive. First, set up the overshoot area for block. */ // if (verbosity >= 4) fprintf ( stderr, " sort initialise ...\n" ); for (i = 0; i < NUM_OVERSHOOT_BYTES; i++) { block[last + i + 2] = block[(i % (last + 1)) + 1]; } for (i = 0; i <= last + NUM_OVERSHOOT_BYTES; i++) { quadrant[i] = 0; } block[0] = (char) (block[last + 1]); if (last < 4000) { /* Use simpleSort(), since the full sorting mechanism has quite a large constant overhead. */ for (i = 0; i <= last; i++) { zptr[i] = i; } firstAttempt = false; workDone = workLimit = 0; simpleSort(0, last, 0); } else { numQSorted = 0; for (i = 0; i <= 255; i++) { bigDone[i] = false; } for (i = 0; i <= 65536; i++) { ftab[i] = 0; } c1 = block[0]; for (i = 0; i <= last; i++) { c2 = block[i + 1]; ftab[(c1 << 8) + c2]++; c1 = c2; } for (i = 1; i <= 65536; i++) { ftab[i] += ftab[i - 1]; } c1 = block[1]; for (i = 0; i < last; i++) { c2 = block[i + 2]; j = (c1 << 8) + c2; c1 = c2; ftab[j]--; zptr[ftab[j]] = i; } j = ((block[last + 1]) << 8) + (block[1]); ftab[j]--; zptr[ftab[j]] = last; /* Now ftab contains the first loc of every small bucket. Calculate the running order, from smallest to largest big bucket. */ for (i = 0; i <= 255; i++) { runningOrder[i] = i; } { int vv; int h = 1; do { h = 3 * h + 1; } while (h <= 256); do { h = h / 3; for (i = h; i <= 255; i++) { vv = runningOrder[i]; j = i; while ((ftab[((runningOrder[j - h]) + 1) << 8] - ftab[(runningOrder[j - h]) << 8]) > (ftab[((vv) + 1) << 8] - ftab[(vv) << 8])) { runningOrder[j] = runningOrder[j - h]; j = j - h; if (j <= (h - 1)) { break; } } runningOrder[j] = vv; } } while (h != 1); } /* The main sorting loop. */ for (i = 0; i <= 255; i++) { /* Process big buckets, starting with the least full. */ ss = runningOrder[i]; /* Complete the big bucket [ss] by quicksorting any unsorted small buckets [ss, j]. Hopefully previous pointer-scanning phases have already completed many of the small buckets [ss, j], so we don't have to sort them at all. */ for (j = 0; j <= 255; j++) { sb = (ss << 8) + j; if (!((ftab[sb] & SETMASK) == SETMASK)) { int lo = ftab[sb] & CLEARMASK; int hi = (ftab[sb + 1] & CLEARMASK) - 1; if (hi > lo) { qSort3(lo, hi, 2); numQSorted += (hi - lo + 1); if (workDone > workLimit && firstAttempt) { return; } } ftab[sb] |= SETMASK; } } /* The ss big bucket is now done. Record this fact, and update the quadrant descriptors. Remember to update quadrants in the overshoot area too, if necessary. The "if (i < 255)" test merely skips this updating for the last bucket processed, since updating for the last bucket is pointless. */ bigDone[ss] = true; if (i < 255) { int bbStart = ftab[ss << 8] & CLEARMASK; int bbSize = (ftab[(ss + 1) << 8] & CLEARMASK) - bbStart; int shifts = 0; while ((bbSize >> shifts) > 65534) { shifts++; } for (j = 0; j < bbSize; j++) { int a2update = zptr[bbStart + j]; int qVal = (j >> shifts); quadrant[a2update] = qVal; if (a2update < NUM_OVERSHOOT_BYTES) { quadrant[a2update + last + 1] = qVal; } } if (!(((bbSize - 1) >> shifts) <= 65535)) { panic(); } } /* Now scan this big bucket so as to synthesise the sorted order for small buckets [t, ss] for all t != ss. */ for (j = 0; j <= 255; j++) { copy[j] = ftab[(j << 8) + ss] & CLEARMASK; } for (j = ftab[ss << 8] & CLEARMASK; j < (ftab[(ss + 1) << 8] & CLEARMASK); j++) { c1 = block[zptr[j]]; if (!bigDone[c1]) { zptr[copy[c1]] = zptr[j] == 0 ? last : zptr[j] - 1; copy[c1]++; } } for (j = 0; j <= 255; j++) { ftab[(j << 8) + ss] |= SETMASK; } } } } private void randomiseBlock() { int i; int rNToGo = 0; int rTPos = 0; for (i = 0; i < 256; i++) { inUse[i] = false; } for (i = 0; i <= last; i++) { if (rNToGo == 0) { rNToGo = (char) rNums[rTPos]; rTPos++; if (rTPos == 512) { rTPos = 0; } } rNToGo--; block[i + 1] ^= ((rNToGo == 1) ? 1 : 0); // handle 16 bit signed numbers block[i + 1] &= 0xFF; inUse[block[i + 1]] = true; } } private void doReversibleTransformation() { int i; workLimit = workFactor * last; workDone = 0; blockRandomised = false; firstAttempt = true; mainSort(); if (workDone > workLimit && firstAttempt) { randomiseBlock(); workLimit = workDone = 0; blockRandomised = true; firstAttempt = false; mainSort(); } origPtr = -1; for (i = 0; i <= last; i++) { if (zptr[i] == 0) { origPtr = i; break; } } if (origPtr == -1) { panic(); } } private boolean fullGtU(int i1, int i2) { int k; char c1, c2; int s1, s2; c1 = block[i1 + 1]; c2 = block[i2 + 1]; if (c1 != c2) { return (c1 > c2); } i1++; i2++; c1 = block[i1 + 1]; c2 = block[i2 + 1]; if (c1 != c2) { return (c1 > c2); } i1++; i2++; c1 = block[i1 + 1]; c2 = block[i2 + 1]; if (c1 != c2) { return (c1 > c2); } i1++; i2++; c1 = block[i1 + 1]; c2 = block[i2 + 1]; if (c1 != c2) { return (c1 > c2); } i1++; i2++; c1 = block[i1 + 1]; c2 = block[i2 + 1]; if (c1 != c2) { return (c1 > c2); } i1++; i2++; c1 = block[i1 + 1]; c2 = block[i2 + 1]; if (c1 != c2) { return (c1 > c2); } i1++; i2++; k = last + 1; do { c1 = block[i1 + 1]; c2 = block[i2 + 1]; if (c1 != c2) { return (c1 > c2); } s1 = quadrant[i1]; s2 = quadrant[i2]; if (s1 != s2) { return (s1 > s2); } i1++; i2++; c1 = block[i1 + 1]; c2 = block[i2 + 1]; if (c1 != c2) { return (c1 > c2); } s1 = quadrant[i1]; s2 = quadrant[i2]; if (s1 != s2) { return (s1 > s2); } i1++; i2++; c1 = block[i1 + 1]; c2 = block[i2 + 1]; if (c1 != c2) { return (c1 > c2); } s1 = quadrant[i1]; s2 = quadrant[i2]; if (s1 != s2) { return (s1 > s2); } i1++; i2++; c1 = block[i1 + 1]; c2 = block[i2 + 1]; if (c1 != c2) { return (c1 > c2); } s1 = quadrant[i1]; s2 = quadrant[i2]; if (s1 != s2) { return (s1 > s2); } i1++; i2++; if (i1 > last) { i1 -= last; i1--; } if (i2 > last) { i2 -= last; i2--; } k -= 4; workDone++; } while (k >= 0); return false; } /* Knuth's increments seem to work better than Incerpi-Sedgewick here. Possibly because the number of elems to sort is usually small, typically <= 20. */ private int[] incs = { 1, 4, 13, 40, 121, 364, 1093, 3280, 9841, 29524, 88573, 265720, 797161, 2391484 }; private void allocateCompressStructures () { int n = baseBlockSize * blockSize100k; block = new char[(n + 1 + NUM_OVERSHOOT_BYTES)]; quadrant = new int[(n + NUM_OVERSHOOT_BYTES)]; zptr = new int[n]; ftab = new int[65537]; if (block == null || quadrant == null || zptr == null || ftab == null) { //int totalDraw = (n + 1 + NUM_OVERSHOOT_BYTES) + (n + NUM_OVERSHOOT_BYTES) + n + 65537; //compressOutOfMemory ( totalDraw, n ); } /* The back end needs a place to store the MTF values whilst it calculates the coding tables. We could put them in the zptr array. However, these values will fit in a short, so we overlay szptr at the start of zptr, in the hope of reducing the number of cache misses induced by the multiple traversals of the MTF values when calculating coding tables. Seems to improve compression speed by about 1%. */ // szptr = zptr; szptr = new short[2 * n]; } private void generateMTFValues() { char[] yy = new char[256]; int i, j; char tmp; char tmp2; int zPend; int wr; int EOB; makeMaps(); EOB = nInUse + 1; for (i = 0; i <= EOB; i++) { mtfFreq[i] = 0; } wr = 0; zPend = 0; for (i = 0; i < nInUse; i++) { yy[i] = (char) i; } for (i = 0; i <= last; i++) { char ll_i; ll_i = unseqToSeq[block[zptr[i]]]; j = 0; tmp = yy[j]; while (ll_i != tmp) { j++; tmp2 = tmp; tmp = yy[j]; yy[j] = tmp2; } yy[0] = tmp; if (j == 0) { zPend++; } else { if (zPend > 0) { zPend--; while (true) { switch (zPend % 2) { case 0: szptr[wr] = (short) RUNA; wr++; mtfFreq[RUNA]++; break; case 1: szptr[wr] = (short) RUNB; wr++; mtfFreq[RUNB]++; break; } if (zPend < 2) { break; } zPend = (zPend - 2) / 2; } zPend = 0; } szptr[wr] = (short) (j + 1); wr++; mtfFreq[j + 1]++; } } if (zPend > 0) { zPend--; while (true) { switch (zPend % 2) { case 0: szptr[wr] = (short) RUNA; wr++; mtfFreq[RUNA]++; break; case 1: szptr[wr] = (short) RUNB; wr++; mtfFreq[RUNB]++; break; } if (zPend < 2) { break; } zPend = (zPend - 2) / 2; } } szptr[wr] = (short) EOB; wr++; mtfFreq[EOB]++; nMTF = wr; } } bouncycastle-1.49.orig/bzip2/src/org/bouncycastle/apache/bzip2/CBZip2InputStream.java0000644000175000017500000005671411337356221030107 0ustar ebourgebourg/* * Licensed to the Apache Software Foundation (ASF) under one or more * contributor license agreements. See the NOTICE file distributed with * this work for additional information regarding copyright ownership. * The ASF licenses this file to You under the Apache License, Version 2.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.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. * */ /* * This package is based on the work done by Keiron Liddle, Aftex Software * to whom the Ant project is very grateful for his * great code. */ package org.bouncycastle.apache.bzip2; import java.io.InputStream; import java.io.IOException; /** * An input stream that decompresses from the BZip2 format (with the file * header chars) to be read as any other stream. * * @author Keiron Liddle * * NB: note this class has been modified to read the leading BZ from the * start of the BZIP2 stream to make it compatible with other PGP programs. */ public class CBZip2InputStream extends InputStream implements BZip2Constants { private static void cadvise() { System.out.println("CRC Error"); //throw new CCoruptionError(); } // private static void badBGLengths() { // cadvise(); // } // // private static void bitStreamEOF() { // cadvise(); // } private static void compressedStreamEOF() { cadvise(); } private void makeMaps() { int i; nInUse = 0; for (i = 0; i < 256; i++) { if (inUse[i]) { seqToUnseq[nInUse] = (char) i; unseqToSeq[i] = (char) nInUse; nInUse++; } } } /* index of the last char in the block, so the block size == last + 1. */ private int last; /* index in zptr[] of original string after sorting. */ private int origPtr; /* always: in the range 0 .. 9. The current block size is 100000 * this number. */ private int blockSize100k; private boolean blockRandomised; private int bsBuff; private int bsLive; private CRC mCrc = new CRC(); private boolean[] inUse = new boolean[256]; private int nInUse; private char[] seqToUnseq = new char[256]; private char[] unseqToSeq = new char[256]; private char[] selector = new char[MAX_SELECTORS]; private char[] selectorMtf = new char[MAX_SELECTORS]; private int[] tt; private char[] ll8; /* freq table collected to save a pass over the data during decompression. */ private int[] unzftab = new int[256]; private int[][] limit = new int[N_GROUPS][MAX_ALPHA_SIZE]; private int[][] base = new int[N_GROUPS][MAX_ALPHA_SIZE]; private int[][] perm = new int[N_GROUPS][MAX_ALPHA_SIZE]; private int[] minLens = new int[N_GROUPS]; private InputStream bsStream; private boolean streamEnd = false; private int currentChar = -1; private static final int START_BLOCK_STATE = 1; private static final int RAND_PART_A_STATE = 2; private static final int RAND_PART_B_STATE = 3; private static final int RAND_PART_C_STATE = 4; private static final int NO_RAND_PART_A_STATE = 5; private static final int NO_RAND_PART_B_STATE = 6; private static final int NO_RAND_PART_C_STATE = 7; private int currentState = START_BLOCK_STATE; private int storedBlockCRC, storedCombinedCRC; private int computedBlockCRC, computedCombinedCRC; int i2, count, chPrev, ch2; int i, tPos; int rNToGo = 0; int rTPos = 0; int j2; char z; public CBZip2InputStream(InputStream zStream) throws IOException { ll8 = null; tt = null; bsSetStream(zStream); initialize(); initBlock(); setupBlock(); } public int read() { if (streamEnd) { return -1; } else { int retChar = currentChar; switch(currentState) { case START_BLOCK_STATE: break; case RAND_PART_A_STATE: break; case RAND_PART_B_STATE: setupRandPartB(); break; case RAND_PART_C_STATE: setupRandPartC(); break; case NO_RAND_PART_A_STATE: break; case NO_RAND_PART_B_STATE: setupNoRandPartB(); break; case NO_RAND_PART_C_STATE: setupNoRandPartC(); break; default: break; } return retChar; } } private void initialize() throws IOException { char magic3, magic4; magic3 = bsGetUChar(); magic4 = bsGetUChar(); if (magic3 != 'B' && magic4 != 'Z') { throw new IOException("Not a BZIP2 marked stream"); } magic3 = bsGetUChar(); magic4 = bsGetUChar(); if (magic3 != 'h' || magic4 < '1' || magic4 > '9') { bsFinishedWithStream(); streamEnd = true; return; } setDecompressStructureSizes(magic4 - '0'); computedCombinedCRC = 0; } private void initBlock() { char magic1, magic2, magic3, magic4; char magic5, magic6; magic1 = bsGetUChar(); magic2 = bsGetUChar(); magic3 = bsGetUChar(); magic4 = bsGetUChar(); magic5 = bsGetUChar(); magic6 = bsGetUChar(); if (magic1 == 0x17 && magic2 == 0x72 && magic3 == 0x45 && magic4 == 0x38 && magic5 == 0x50 && magic6 == 0x90) { complete(); return; } if (magic1 != 0x31 || magic2 != 0x41 || magic3 != 0x59 || magic4 != 0x26 || magic5 != 0x53 || magic6 != 0x59) { badBlockHeader(); streamEnd = true; return; } storedBlockCRC = bsGetInt32(); if (bsR(1) == 1) { blockRandomised = true; } else { blockRandomised = false; } // currBlockNo++; getAndMoveToFrontDecode(); mCrc.initialiseCRC(); currentState = START_BLOCK_STATE; } private void endBlock() { computedBlockCRC = mCrc.getFinalCRC(); /* A bad CRC is considered a fatal error. */ if (storedBlockCRC != computedBlockCRC) { crcError(); } computedCombinedCRC = (computedCombinedCRC << 1) | (computedCombinedCRC >>> 31); computedCombinedCRC ^= computedBlockCRC; } private void complete() { storedCombinedCRC = bsGetInt32(); if (storedCombinedCRC != computedCombinedCRC) { crcError(); } bsFinishedWithStream(); streamEnd = true; } private static void blockOverrun() { cadvise(); } private static void badBlockHeader() { cadvise(); } private static void crcError() { cadvise(); } private void bsFinishedWithStream() { try { if (this.bsStream != null) { if (this.bsStream != System.in) { this.bsStream.close(); this.bsStream = null; } } } catch (IOException ioe) { //ignore } } private void bsSetStream(InputStream f) { bsStream = f; bsLive = 0; bsBuff = 0; } private int bsR(int n) { int v; while (bsLive < n) { int zzi; char thech = 0; try { thech = (char) bsStream.read(); } catch (IOException e) { compressedStreamEOF(); } if (thech == -1) { compressedStreamEOF(); } zzi = thech; bsBuff = (bsBuff << 8) | (zzi & 0xff); bsLive += 8; } v = (bsBuff >> (bsLive - n)) & ((1 << n) - 1); bsLive -= n; return v; } private char bsGetUChar() { return (char) bsR(8); } private int bsGetint() { int u = 0; u = (u << 8) | bsR(8); u = (u << 8) | bsR(8); u = (u << 8) | bsR(8); u = (u << 8) | bsR(8); return u; } private int bsGetIntVS(int numBits) { return (int) bsR(numBits); } private int bsGetInt32() { return (int) bsGetint(); } private void hbCreateDecodeTables(int[] limit, int[] base, int[] perm, char[] length, int minLen, int maxLen, int alphaSize) { int pp, i, j, vec; pp = 0; for (i = minLen; i <= maxLen; i++) { for (j = 0; j < alphaSize; j++) { if (length[j] == i) { perm[pp] = j; pp++; } } } for (i = 0; i < MAX_CODE_LEN; i++) { base[i] = 0; } for (i = 0; i < alphaSize; i++) { base[length[i] + 1]++; } for (i = 1; i < MAX_CODE_LEN; i++) { base[i] += base[i - 1]; } for (i = 0; i < MAX_CODE_LEN; i++) { limit[i] = 0; } vec = 0; for (i = minLen; i <= maxLen; i++) { vec += (base[i + 1] - base[i]); limit[i] = vec - 1; vec <<= 1; } for (i = minLen + 1; i <= maxLen; i++) { base[i] = ((limit[i - 1] + 1) << 1) - base[i]; } } private void recvDecodingTables() { char len[][] = new char[N_GROUPS][MAX_ALPHA_SIZE]; int i, j, t, nGroups, nSelectors, alphaSize; int minLen, maxLen; boolean[] inUse16 = new boolean[16]; /* Receive the mapping table */ for (i = 0; i < 16; i++) { if (bsR(1) == 1) { inUse16[i] = true; } else { inUse16[i] = false; } } for (i = 0; i < 256; i++) { inUse[i] = false; } for (i = 0; i < 16; i++) { if (inUse16[i]) { for (j = 0; j < 16; j++) { if (bsR(1) == 1) { inUse[i * 16 + j] = true; } } } } makeMaps(); alphaSize = nInUse + 2; /* Now the selectors */ nGroups = bsR(3); nSelectors = bsR(15); for (i = 0; i < nSelectors; i++) { j = 0; while (bsR(1) == 1) { j++; } selectorMtf[i] = (char) j; } /* Undo the MTF values for the selectors. */ { char[] pos = new char[N_GROUPS]; char tmp, v; for (v = 0; v < nGroups; v++) { pos[v] = v; } for (i = 0; i < nSelectors; i++) { v = selectorMtf[i]; tmp = pos[v]; while (v > 0) { pos[v] = pos[v - 1]; v--; } pos[0] = tmp; selector[i] = tmp; } } /* Now the coding tables */ for (t = 0; t < nGroups; t++) { int curr = bsR(5); for (i = 0; i < alphaSize; i++) { while (bsR(1) == 1) { if (bsR(1) == 0) { curr++; } else { curr--; } } len[t][i] = (char) curr; } } /* Create the Huffman decoding tables */ for (t = 0; t < nGroups; t++) { minLen = 32; maxLen = 0; for (i = 0; i < alphaSize; i++) { if (len[t][i] > maxLen) { maxLen = len[t][i]; } if (len[t][i] < minLen) { minLen = len[t][i]; } } hbCreateDecodeTables(limit[t], base[t], perm[t], len[t], minLen, maxLen, alphaSize); minLens[t] = minLen; } } private void getAndMoveToFrontDecode() { char[] yy = new char[256]; int i, j, nextSym, limitLast; int EOB, groupNo, groupPos; limitLast = baseBlockSize * blockSize100k; origPtr = bsGetIntVS(24); recvDecodingTables(); EOB = nInUse + 1; groupNo = -1; groupPos = 0; /* Setting up the unzftab entries here is not strictly necessary, but it does save having to do it later in a separate pass, and so saves a block's worth of cache misses. */ for (i = 0; i <= 255; i++) { unzftab[i] = 0; } for (i = 0; i <= 255; i++) { yy[i] = (char) i; } last = -1; { int zt, zn, zvec, zj; if (groupPos == 0) { groupNo++; groupPos = G_SIZE; } groupPos--; zt = selector[groupNo]; zn = minLens[zt]; zvec = bsR(zn); while (zvec > limit[zt][zn]) { zn++; { { while (bsLive < 1) { int zzi; char thech = 0; try { thech = (char) bsStream.read(); } catch (IOException e) { compressedStreamEOF(); } if (thech == -1) { compressedStreamEOF(); } zzi = thech; bsBuff = (bsBuff << 8) | (zzi & 0xff); bsLive += 8; } } zj = (bsBuff >> (bsLive - 1)) & 1; bsLive--; } zvec = (zvec << 1) | zj; } nextSym = perm[zt][zvec - base[zt][zn]]; } while (true) { if (nextSym == EOB) { break; } if (nextSym == RUNA || nextSym == RUNB) { char ch; int s = -1; int N = 1; do { if (nextSym == RUNA) { s = s + (0 + 1) * N; } else if (nextSym == RUNB) { s = s + (1 + 1) * N; } N = N * 2; { int zt, zn, zvec, zj; if (groupPos == 0) { groupNo++; groupPos = G_SIZE; } groupPos--; zt = selector[groupNo]; zn = minLens[zt]; zvec = bsR(zn); while (zvec > limit[zt][zn]) { zn++; { { while (bsLive < 1) { int zzi; char thech = 0; try { thech = (char) bsStream.read(); } catch (IOException e) { compressedStreamEOF(); } if (thech == -1) { compressedStreamEOF(); } zzi = thech; bsBuff = (bsBuff << 8) | (zzi & 0xff); bsLive += 8; } } zj = (bsBuff >> (bsLive - 1)) & 1; bsLive--; } zvec = (zvec << 1) | zj; } nextSym = perm[zt][zvec - base[zt][zn]]; } } while (nextSym == RUNA || nextSym == RUNB); s++; ch = seqToUnseq[yy[0]]; unzftab[ch] += s; while (s > 0) { last++; ll8[last] = ch; s--; } if (last >= limitLast) { blockOverrun(); } continue; } else { char tmp; last++; if (last >= limitLast) { blockOverrun(); } tmp = yy[nextSym - 1]; unzftab[seqToUnseq[tmp]]++; ll8[last] = seqToUnseq[tmp]; /* This loop is hammered during decompression, hence the unrolling. for (j = nextSym-1; j > 0; j--) yy[j] = yy[j-1]; */ j = nextSym - 1; for (; j > 3; j -= 4) { yy[j] = yy[j - 1]; yy[j - 1] = yy[j - 2]; yy[j - 2] = yy[j - 3]; yy[j - 3] = yy[j - 4]; } for (; j > 0; j--) { yy[j] = yy[j - 1]; } yy[0] = tmp; { int zt, zn, zvec, zj; if (groupPos == 0) { groupNo++; groupPos = G_SIZE; } groupPos--; zt = selector[groupNo]; zn = minLens[zt]; zvec = bsR(zn); while (zvec > limit[zt][zn]) { zn++; { { while (bsLive < 1) { int zzi; char thech = 0; try { thech = (char) bsStream.read(); } catch (IOException e) { compressedStreamEOF(); } zzi = thech; bsBuff = (bsBuff << 8) | (zzi & 0xff); bsLive += 8; } } zj = (bsBuff >> (bsLive - 1)) & 1; bsLive--; } zvec = (zvec << 1) | zj; } nextSym = perm[zt][zvec - base[zt][zn]]; } continue; } } } private void setupBlock() { int[] cftab = new int[257]; char ch; cftab[0] = 0; for (i = 1; i <= 256; i++) { cftab[i] = unzftab[i - 1]; } for (i = 1; i <= 256; i++) { cftab[i] += cftab[i - 1]; } for (i = 0; i <= last; i++) { ch = (char) ll8[i]; tt[cftab[ch]] = i; cftab[ch]++; } cftab = null; tPos = tt[origPtr]; count = 0; i2 = 0; ch2 = 256; /* not a char and not EOF */ if (blockRandomised) { rNToGo = 0; rTPos = 0; setupRandPartA(); } else { setupNoRandPartA(); } } private void setupRandPartA() { if (i2 <= last) { chPrev = ch2; ch2 = ll8[tPos]; tPos = tt[tPos]; if (rNToGo == 0) { rNToGo = rNums[rTPos]; rTPos++; if (rTPos == 512) { rTPos = 0; } } rNToGo--; ch2 ^= (int) ((rNToGo == 1) ? 1 : 0); i2++; currentChar = ch2; currentState = RAND_PART_B_STATE; mCrc.updateCRC(ch2); } else { endBlock(); initBlock(); setupBlock(); } } private void setupNoRandPartA() { if (i2 <= last) { chPrev = ch2; ch2 = ll8[tPos]; tPos = tt[tPos]; i2++; currentChar = ch2; currentState = NO_RAND_PART_B_STATE; mCrc.updateCRC(ch2); } else { endBlock(); initBlock(); setupBlock(); } } private void setupRandPartB() { if (ch2 != chPrev) { currentState = RAND_PART_A_STATE; count = 1; setupRandPartA(); } else { count++; if (count >= 4) { z = ll8[tPos]; tPos = tt[tPos]; if (rNToGo == 0) { rNToGo = rNums[rTPos]; rTPos++; if (rTPos == 512) { rTPos = 0; } } rNToGo--; z ^= ((rNToGo == 1) ? 1 : 0); j2 = 0; currentState = RAND_PART_C_STATE; setupRandPartC(); } else { currentState = RAND_PART_A_STATE; setupRandPartA(); } } } private void setupRandPartC() { if (j2 < (int) z) { currentChar = ch2; mCrc.updateCRC(ch2); j2++; } else { currentState = RAND_PART_A_STATE; i2++; count = 0; setupRandPartA(); } } private void setupNoRandPartB() { if (ch2 != chPrev) { currentState = NO_RAND_PART_A_STATE; count = 1; setupNoRandPartA(); } else { count++; if (count >= 4) { z = ll8[tPos]; tPos = tt[tPos]; currentState = NO_RAND_PART_C_STATE; j2 = 0; setupNoRandPartC(); } else { currentState = NO_RAND_PART_A_STATE; setupNoRandPartA(); } } } private void setupNoRandPartC() { if (j2 < (int) z) { currentChar = ch2; mCrc.updateCRC(ch2); j2++; } else { currentState = NO_RAND_PART_A_STATE; i2++; count = 0; setupNoRandPartA(); } } private void setDecompressStructureSizes(int newSize100k) { if (!(0 <= newSize100k && newSize100k <= 9 && 0 <= blockSize100k && blockSize100k <= 9)) { // throw new IOException("Invalid block size"); } blockSize100k = newSize100k; if (newSize100k == 0) { return; } int n = baseBlockSize * newSize100k; ll8 = new char[n]; tt = new int[n]; } } bouncycastle-1.49.orig/jdk15+.xml0000644000175000017500000000753312151121706016150 0ustar ebourgebourg bouncycastle-1.49.orig/build15+0000644000175000017500000000132012062253470015671 0ustar ebourgebourg#!/bin/sh - # # build script for 1.5 # # If it's given a buildname it creates a subdirectory and places a build in it, # otherwise it just creates the docs and class files. # if [ "${JDKPATH}" = "" ] then JDKPATH=/opt/jdk1.5.0 # JDK 1.5 location JAVA_MAIL_HOME=/opt/javamail JAVA_ACTIVATION_HOME=/opt/jaf JUNIT_HOME=/opt/junit fi JAVA_HOME=$JDKPATH export JAVA_HOME PATH=$JDKPATH/bin:$PATH export PATH CLASSPATH=$JAVA_MAIL_HOME/mail.jar:$JAVA_ACTIVATION_HOME/activation.jar:$JUNIT_HOME/junit.jar:$CLASSPATH export CLASSPATH if [ "$1" = "test" ] then ant -f jdk15+.xml test else if ant -f jdk15+.xml build-provider then ant -f jdk15+.xml build ant -f jdk15+.xml zip-src fi fi bouncycastle-1.49.orig/buildj2me0000644000175000017500000002245012150050436016230 0ustar ebourgebourg#!/bin/sh - # # build script for J2ME - this only includes the lightweight API # if a distribution name is given as an argument the build is placed # in a subdirectory - nothing gets compiled as we expect the classes # to be in ./palm # # Note: this script expects javadoc for jdk 1.3 to be in your path. # base=$1 version=`echo $base | sed -e "s/\([0-9]\)\([0-9a-z]*\)/\1.\2/"` WINDOWTITLE="Bouncy Castle Cryptography $version API Specification" HEADER="Bouncy Castle Cryptography $version" DOCTITLE="Bouncy Castle $version API Specification" echo "making j2me lightweight release" if test "$base" != "" then mkdir lcrypto-j2me-$base mkdir lcrypto-j2me-$base/docs tar cf - common.xml midp.xml crypto_env.properties index.html LICENSE.html CONTRIBUTORS.html releasenotes.html specifications.html zips src/org/bouncycastle/LICENSE.java src/org/bouncycastle/math \ src/org/bouncycastle/crypto/*.java \ src/org/bouncycastle/crypto/*.html \ src/org/bouncycastle/crypto/agreement \ src/org/bouncycastle/crypto/commitments \ src/org/bouncycastle/crypto/digests \ src/org/bouncycastle/crypto/encodings \ src/org/bouncycastle/crypto/engines \ src/org/bouncycastle/crypto/kems \ src/org/bouncycastle/crypto/examples \ src/org/bouncycastle/crypto/paddings \ src/org/bouncycastle/crypto/generators \ src/org/bouncycastle/crypto/io \ src/org/bouncycastle/crypto/macs \ src/org/bouncycastle/crypto/modes \ src/org/bouncycastle/crypto/params \ src/org/bouncycastle/crypto/parsers \ src/org/bouncycastle/crypto/signers \ src/org/bouncycastle/crypto/prng \ src/org/bouncycastle/crypto/tls \ src/org/bouncycastle/crypto/util \ src/org/bouncycastle/util \ src/org/bouncycastle/bcpg \ src/org/bouncycastle/asn1 \ src/org/bouncycastle/cert \ src/org/bouncycastle/cms \ src/org/bouncycastle/eac \ src/org/bouncycastle/pqc/math \ src/org/bouncycastle/pqc/crypto \ src/org/bouncycastle/pqc/asn1 \ src/org/bouncycastle/pkcs \ src/org/bouncycastle/tsp \ src/org/bouncycastle/operator \ src/org/bouncycastle/openpgp \ | (cd lcrypto-j2me-$base; tar xf -) (cd test; tar cf - src/org/bouncycastle/crypto/test src/org/bouncycastle/asn1/test | (cd ../lcrypto-j2me-$base; tar xf -)) (cd j2me; tar cf - * | (cd ../lcrypto-j2me-$base; cd src; tar xf -)) rm lcrypto-j2me-$base/src/org/bouncycastle/crypto/test/AllTests.java rm lcrypto-j2me-$base/src/org/bouncycastle/util/StreamParser.java rm lcrypto-j2me-$base/src/org/bouncycastle/util/StreamParsingException.java rm lcrypto-j2me-$base/src/org/bouncycastle/asn1/util/Dump.java rm lcrypto-j2me-$base/src/org/bouncycastle/asn1/test/AllTests.java rm lcrypto-j2me-$base/src/org/bouncycastle/asn1/test/ASN1SequenceParserTest.java rm lcrypto-j2me-$base/src/org/bouncycastle/asn1/test/AttributeTableUnitTest.java rm lcrypto-j2me-$base/src/org/bouncycastle/asn1/test/BiometricDataUnitTest.java rm lcrypto-j2me-$base/src/org/bouncycastle/asn1/test/BitStringConstantTester.java rm lcrypto-j2me-$base/src/org/bouncycastle/asn1/test/CommitmentTypeIndicationUnitTest.java rm lcrypto-j2me-$base/src/org/bouncycastle/asn1/test/CommitmentTypeQualifierUnitTest.java rm lcrypto-j2me-$base/src/org/bouncycastle/asn1/test/DataGroupHashUnitTest.java rm lcrypto-j2me-$base/src/org/bouncycastle/asn1/test/DERUTF8StringTest.java rm lcrypto-j2me-$base/src/org/bouncycastle/asn1/test/EqualsAndHashCodeTest.java rm lcrypto-j2me-$base/src/org/bouncycastle/asn1/test/GeneralizedTimeTest.java rm lcrypto-j2me-$base/src/org/bouncycastle/asn1/test/GenerationTest.java rm lcrypto-j2me-$base/src/org/bouncycastle/asn1/test/InputStreamTest.java rm lcrypto-j2me-$base/src/org/bouncycastle/asn1/test/Iso4217CurrencyCodeUnitTest.java rm lcrypto-j2me-$base/src/org/bouncycastle/asn1/test/KeyUsageTest.java rm lcrypto-j2me-$base/src/org/bouncycastle/asn1/test/LDSSecurityObjectUnitTest.java rm lcrypto-j2me-$base/src/org/bouncycastle/asn1/test/MonetaryValueUnitTest.java rm lcrypto-j2me-$base/src/org/bouncycastle/asn1/test/NameOrPseudonymUnitTest.java rm lcrypto-j2me-$base/src/org/bouncycastle/asn1/test/NetscapeCertTypeTest.java rm lcrypto-j2me-$base/src/org/bouncycastle/asn1/test/OctetStringTest.java rm lcrypto-j2me-$base/src/org/bouncycastle/asn1/test/ParseTest.java rm lcrypto-j2me-$base/src/org/bouncycastle/asn1/test/PersonalDataUnitTest.java rm lcrypto-j2me-$base/src/org/bouncycastle/asn1/test/PKIFailureInfoTest.java rm lcrypto-j2me-$base/src/org/bouncycastle/asn1/test/QCStatementUnitTest.java rm lcrypto-j2me-$base/src/org/bouncycastle/asn1/test/ReasonFlagsTest.java rm lcrypto-j2me-$base/src/org/bouncycastle/asn1/test/SemanticsInformationUnitTest.java rm lcrypto-j2me-$base/src/org/bouncycastle/asn1/test/SetTest.java rm lcrypto-j2me-$base/src/org/bouncycastle/asn1/test/SignerLocationUnitTest.java rm lcrypto-j2me-$base/src/org/bouncycastle/asn1/test/SMIMETest.java rm lcrypto-j2me-$base/src/org/bouncycastle/asn1/test/TagTest.java rm lcrypto-j2me-$base/src/org/bouncycastle/asn1/test/TypeOfBiometricDataUnitTest.java rm lcrypto-j2me-$base/src/org/bouncycastle/asn1/test/UTCTimeTest.java rm lcrypto-j2me-$base/src/org/bouncycastle/crypto/test/AESVectorFileTest.java rm lcrypto-j2me-$base/src/org/bouncycastle/crypto/test/GCMReorderTest.java rm lcrypto-j2me-$base/src/org/bouncycastle/crypto/test/HCFamilyVecTest.java rm lcrypto-j2me-$base/src/org/bouncycastle/crypto/test/RSABlindedTest.java rm lcrypto-j2me-$base/src/org/bouncycastle/crypto/test/SCryptTest.java rm lcrypto-j2me-$base/src/org/bouncycastle/crypto/examples/DESExample.java rm -r lcrypto-j2me-$base/src/org/bouncycastle/util/io/pem (cd lcrypto-j2me-$base; rm -rf src/org/bouncycastle/pqc/math/ntru rm -rf src/org/bouncycastle/pqc/crypto/test/ntru rm -rf src/org/bouncycastle/pqc/crypto/*/NTRU* rm -rf src/org/bouncycastle/pqc/crypto/*/BitStringTest* rm -rf src/org/bouncycastle/pqc/crypto/*/IndexGenerator* find src -name AllTests.java -exec rm {} \; find src -name jcajce -exec rm -r {} \; rm src/org/bouncycastle/asn1/test/GetInstanceTest.java rm src/org/bouncycastle/asn1/test/ASN1SequenceParserTest.java rm src/org/bouncycastle/asn1/test/OctetStringTest.java rm src/org/bouncycastle/asn1/test/ParseTest.java rm src/org/bouncycastle/crypto/test/GCMReorderTest.java ) (2>&1 find lcrypto-j2me-$base -name CVS -exec rm -rf \{\} \; ) > /dev/null ( cd lcrypto-j2me-$base; javadoc -windowtitle "$WINDOWTITLE" -doctitle "$DOCTITLE" \ -header "$HEADER" \ -group "Lightweight Crypto Packages" "org.bouncycastle.crypto*" \ -group "ASN.1 Support Packages" "org.bouncycastle.asn1*" \ -group "OpenPGP Support Packages" "org.bouncycastle.bcpg*:org.bouncycastle.openpgp*" \ -group "Basic Signing And Encryption" "org.bouncycastle.operator*" \ -group "Certificate Generation And Handling Support Packages" "org.bouncycastle.cert*" \ -group "CMS Support Packages" "org.bouncycastle.cms*" \ -group "EAC Support Packages" "org.bouncycastle.eac*" \ -group "TSP Support Packages" "org.bouncycastle.tsp*" \ -group "PKCS Support Packages" "org.bouncycastle.pkcs*" \ -group "Post-Quantum Crypto Packages" "org.bouncycastle.pqc*" \ -group "Utility Packages" "org.bouncycastle.util*:org.bouncycastle.math*" \ -classpath classes \ -d docs -sourcepath src -breakiterator \ org.bouncycastle.asn1 \ org.bouncycastle.asn1.cmp \ org.bouncycastle.asn1.cms \ org.bouncycastle.asn1.cryptopro \ org.bouncycastle.asn1.esf \ org.bouncycastle.asn1.ess \ org.bouncycastle.asn1.gnu \ org.bouncycastle.asn1.iana \ org.bouncycastle.asn1.icao \ org.bouncycastle.asn1.misc \ org.bouncycastle.asn1.mozilla \ org.bouncycastle.asn1.nist \ org.bouncycastle.asn1.ocsp \ org.bouncycastle.asn1.oiw \ org.bouncycastle.asn1.pkcs \ org.bouncycastle.asn1.sec \ org.bouncycastle.asn1.smime \ org.bouncycastle.asn1.teletrust \ org.bouncycastle.asn1.test \ org.bouncycastle.asn1.tsp \ org.bouncycastle.asn1.util \ org.bouncycastle.asn1.x500 \ org.bouncycastle.asn1.x500.style \ org.bouncycastle.asn1.x509 \ org.bouncycastle.asn1.x9 \ org.bouncycastle.bcpg \ org.bouncycastle.bcpg.sig \ org.bouncycastle.math.ec \ org.bouncycastle.crypto \ org.bouncycastle.crypto.agreement \ org.bouncycastle.crypto.commitments \ org.bouncycastle.crypto.digests \ org.bouncycastle.crypto.encodings \ org.bouncycastle.crypto.engines \ org.bouncycastle.crypto.generators \ org.bouncycastle.crypto.io \ org.bouncycastle.crypto.kems \ org.bouncycastle.crypto.macs \ org.bouncycastle.crypto.modes \ org.bouncycastle.crypto.params \ org.bouncycastle.crypto.parsers \ org.bouncycastle.crypto.paddings \ org.bouncycastle.crypto.signers \ org.bouncycastle.crypto.prng \ org.bouncycastle.crypto.tls \ org.bouncycastle.crypto.test \ org.bouncycastle.crypto.util \ org.bouncycastle.crypto.examples \ org.bouncycastle.pqc.asn1 \ org.bouncycastle.pqc.crypto \ org.bouncycastle.pqc.crypto.rainbow \ org.bouncycastle.pqc.crypto.mceliece \ org.bouncycastle.pqc.crypto.gmss \ org.bouncycastle.pqc.math.linearalgebra \ org.bouncycastle.util \ org.bouncycastle.util.encoders \ org.bouncycastle.util.test > /dev/null \ ) fi bouncycastle-1.49.orig/src/0000755000175000017500000000000012152033551015215 5ustar ebourgebourgbouncycastle-1.49.orig/src/org/0000755000175000017500000000000012152033551016004 5ustar ebourgebourgbouncycastle-1.49.orig/src/org/bouncycastle/0000755000175000017500000000000012152033551020477 5ustar ebourgebourgbouncycastle-1.49.orig/src/org/bouncycastle/openpgp/0000755000175000017500000000000012152033551022147 5ustar ebourgebourgbouncycastle-1.49.orig/src/org/bouncycastle/openpgp/PGPSecretKey.java0000644000175000017500000010014012151253000025243 0ustar ebourgebourgpackage org.bouncycastle.openpgp; import java.io.ByteArrayInputStream; import java.io.ByteArrayOutputStream; import java.io.IOException; import java.io.OutputStream; import java.security.NoSuchProviderException; import java.security.PrivateKey; import java.security.Provider; import java.security.PublicKey; import java.security.SecureRandom; import java.util.ArrayList; import java.util.Date; import java.util.Iterator; import java.util.List; import org.bouncycastle.bcpg.BCPGInputStream; import org.bouncycastle.bcpg.BCPGObject; import org.bouncycastle.bcpg.BCPGOutputStream; import org.bouncycastle.bcpg.ContainedPacket; import org.bouncycastle.bcpg.DSASecretBCPGKey; import org.bouncycastle.bcpg.ElGamalSecretBCPGKey; import org.bouncycastle.bcpg.HashAlgorithmTags; import org.bouncycastle.bcpg.PublicKeyPacket; import org.bouncycastle.bcpg.RSASecretBCPGKey; import org.bouncycastle.bcpg.S2K; import org.bouncycastle.bcpg.SecretKeyPacket; import org.bouncycastle.bcpg.SecretSubkeyPacket; import org.bouncycastle.bcpg.SymmetricKeyAlgorithmTags; import org.bouncycastle.bcpg.UserAttributePacket; import org.bouncycastle.bcpg.UserIDPacket; import org.bouncycastle.openpgp.operator.PBESecretKeyDecryptor; import org.bouncycastle.openpgp.operator.PBESecretKeyEncryptor; import org.bouncycastle.openpgp.operator.PGPContentSignerBuilder; import org.bouncycastle.openpgp.operator.PGPDigestCalculator; import org.bouncycastle.openpgp.operator.jcajce.JcaPGPContentSignerBuilder; import org.bouncycastle.openpgp.operator.jcajce.JcaPGPDigestCalculatorProviderBuilder; import org.bouncycastle.openpgp.operator.jcajce.JcePBESecretKeyDecryptorBuilder; import org.bouncycastle.openpgp.operator.jcajce.JcePBESecretKeyEncryptorBuilder; /** * general class to handle a PGP secret key object. */ public class PGPSecretKey { SecretKeyPacket secret; PGPPublicKey pub; PGPSecretKey( SecretKeyPacket secret, PGPPublicKey pub) { this.secret = secret; this.pub = pub; } PGPSecretKey( PGPPrivateKey privKey, PGPPublicKey pubKey, PGPDigestCalculator checksumCalculator, PBESecretKeyEncryptor keyEncryptor) throws PGPException { this(privKey, pubKey, checksumCalculator, false, keyEncryptor); } PGPSecretKey( PGPPrivateKey privKey, PGPPublicKey pubKey, PGPDigestCalculator checksumCalculator, boolean isMasterKey, PBESecretKeyEncryptor keyEncryptor) throws PGPException { this.pub = pubKey; BCPGObject secKey = (BCPGObject)privKey.getPrivateKeyDataPacket(); try { ByteArrayOutputStream bOut = new ByteArrayOutputStream(); BCPGOutputStream pOut = new BCPGOutputStream(bOut); pOut.writeObject(secKey); byte[] keyData = bOut.toByteArray(); pOut.write(checksum(checksumCalculator, keyData, keyData.length)); int encAlgorithm = keyEncryptor.getAlgorithm(); if (encAlgorithm != SymmetricKeyAlgorithmTags.NULL) { keyData = bOut.toByteArray(); // include checksum byte[] encData = keyEncryptor.encryptKeyData(keyData, 0, keyData.length); byte[] iv = keyEncryptor.getCipherIV(); S2K s2k = keyEncryptor.getS2K(); int s2kUsage; if (checksumCalculator != null) { if (checksumCalculator.getAlgorithm() != HashAlgorithmTags.SHA1) { throw new PGPException("only SHA1 supported for key checksum calculations."); } s2kUsage = SecretKeyPacket.USAGE_SHA1; } else { s2kUsage = SecretKeyPacket.USAGE_CHECKSUM; } if (isMasterKey) { this.secret = new SecretKeyPacket(pub.publicPk, encAlgorithm, s2kUsage, s2k, iv, encData); } else { this.secret = new SecretSubkeyPacket(pub.publicPk, encAlgorithm, s2kUsage, s2k, iv, encData); } } else { if (isMasterKey) { this.secret = new SecretKeyPacket(pub.publicPk, encAlgorithm, null, null, bOut.toByteArray()); } else { this.secret = new SecretSubkeyPacket(pub.publicPk, encAlgorithm, null, null, bOut.toByteArray()); } } } catch (PGPException e) { throw e; } catch (Exception e) { throw new PGPException("Exception encrypting key", e); } } /** * @deprecated use method taking PBESecretKeyEncryptor */ public PGPSecretKey( int certificationLevel, PGPKeyPair keyPair, String id, int encAlgorithm, char[] passPhrase, PGPSignatureSubpacketVector hashedPcks, PGPSignatureSubpacketVector unhashedPcks, SecureRandom rand, String provider) throws PGPException, NoSuchProviderException { this(certificationLevel, keyPair, id, encAlgorithm, passPhrase, false, hashedPcks, unhashedPcks, rand, provider); } /** * @deprecated use method taking PBESecretKeyEncryptor */ public PGPSecretKey( int certificationLevel, PGPKeyPair keyPair, String id, int encAlgorithm, char[] passPhrase, boolean useSHA1, PGPSignatureSubpacketVector hashedPcks, PGPSignatureSubpacketVector unhashedPcks, SecureRandom rand, String provider) throws PGPException, NoSuchProviderException { this(certificationLevel, keyPair, id, encAlgorithm, passPhrase, useSHA1, hashedPcks, unhashedPcks, rand, PGPUtil.getProvider(provider)); } public PGPSecretKey( int certificationLevel, PGPKeyPair keyPair, String id, PGPSignatureSubpacketVector hashedPcks, PGPSignatureSubpacketVector unhashedPcks, PGPContentSignerBuilder certificationSignerBuilder, PBESecretKeyEncryptor keyEncryptor) throws PGPException { this(certificationLevel, keyPair, id, null, hashedPcks, unhashedPcks, certificationSignerBuilder, keyEncryptor); } /** * @deprecated use method taking PBESecretKeyEncryptor */ public PGPSecretKey( int certificationLevel, PGPKeyPair keyPair, String id, int encAlgorithm, char[] passPhrase, boolean useSHA1, PGPSignatureSubpacketVector hashedPcks, PGPSignatureSubpacketVector unhashedPcks, SecureRandom rand, Provider provider) throws PGPException { this(keyPair.getPrivateKey(), certifiedPublicKey(certificationLevel, keyPair, id, hashedPcks, unhashedPcks, new JcaPGPContentSignerBuilder(keyPair.getPublicKey().getAlgorithm(), HashAlgorithmTags.SHA1).setProvider(provider)), convertSHA1Flag(useSHA1), true, new JcePBESecretKeyEncryptorBuilder(encAlgorithm, new JcaPGPDigestCalculatorProviderBuilder().build().get(HashAlgorithmTags.SHA1)).setProvider(provider).setSecureRandom(rand).build(passPhrase)); } private static PGPDigestCalculator convertSHA1Flag(boolean useSHA1) throws PGPException { return useSHA1 ? new JcaPGPDigestCalculatorProviderBuilder().build().get(HashAlgorithmTags.SHA1) : null; } public PGPSecretKey( int certificationLevel, PGPKeyPair keyPair, String id, PGPDigestCalculator checksumCalculator, PGPSignatureSubpacketVector hashedPcks, PGPSignatureSubpacketVector unhashedPcks, PGPContentSignerBuilder certificationSignerBuilder, PBESecretKeyEncryptor keyEncryptor) throws PGPException { this(keyPair.getPrivateKey(), certifiedPublicKey(certificationLevel, keyPair, id, hashedPcks, unhashedPcks, certificationSignerBuilder), checksumCalculator, true, keyEncryptor); } private static PGPPublicKey certifiedPublicKey( int certificationLevel, PGPKeyPair keyPair, String id, PGPSignatureSubpacketVector hashedPcks, PGPSignatureSubpacketVector unhashedPcks, PGPContentSignerBuilder certificationSignerBuilder) throws PGPException { PGPSignatureGenerator sGen; try { sGen = new PGPSignatureGenerator(certificationSignerBuilder); } catch (Exception e) { throw new PGPException("creating signature generator: " + e, e); } // // generate the certification // sGen.init(certificationLevel, keyPair.getPrivateKey()); sGen.setHashedSubpackets(hashedPcks); sGen.setUnhashedSubpackets(unhashedPcks); try { PGPSignature certification = sGen.generateCertification(id, keyPair.getPublicKey()); return PGPPublicKey.addCertification(keyPair.getPublicKey(), id, certification); } catch (Exception e) { throw new PGPException("exception doing certification: " + e, e); } } /** * @deprecated use method taking PBESecretKeyEncryptor */ public PGPSecretKey( int certificationLevel, int algorithm, PublicKey pubKey, PrivateKey privKey, Date time, String id, int encAlgorithm, char[] passPhrase, PGPSignatureSubpacketVector hashedPcks, PGPSignatureSubpacketVector unhashedPcks, SecureRandom rand, String provider) throws PGPException, NoSuchProviderException { this(certificationLevel, new PGPKeyPair(algorithm,pubKey, privKey, time), id, encAlgorithm, passPhrase, hashedPcks, unhashedPcks, rand, provider); } /** * @deprecated use method taking PBESecretKeyEncryptor */ public PGPSecretKey( int certificationLevel, int algorithm, PublicKey pubKey, PrivateKey privKey, Date time, String id, int encAlgorithm, char[] passPhrase, boolean useSHA1, PGPSignatureSubpacketVector hashedPcks, PGPSignatureSubpacketVector unhashedPcks, SecureRandom rand, String provider) throws PGPException, NoSuchProviderException { this(certificationLevel, new PGPKeyPair(algorithm, pubKey, privKey, time), id, encAlgorithm, passPhrase, useSHA1, hashedPcks, unhashedPcks, rand, provider); } /** * @deprecated use method taking PGPKeyPair */ public PGPSecretKey( int certificationLevel, int algorithm, PublicKey pubKey, PrivateKey privKey, Date time, String id, PGPDigestCalculator checksumCalculator, PGPSignatureSubpacketVector hashedPcks, PGPSignatureSubpacketVector unhashedPcks, PGPContentSignerBuilder certificationSignerBuilder, PBESecretKeyEncryptor keyEncryptor) throws PGPException { this(certificationLevel, new PGPKeyPair(algorithm, pubKey, privKey, time), id, checksumCalculator, hashedPcks, unhashedPcks, certificationSignerBuilder, keyEncryptor); } /** * @deprecated use method taking PGPKeyPair */ public PGPSecretKey( int certificationLevel, int algorithm, PublicKey pubKey, PrivateKey privKey, Date time, String id, PGPSignatureSubpacketVector hashedPcks, PGPSignatureSubpacketVector unhashedPcks, PGPContentSignerBuilder certificationSignerBuilder, PBESecretKeyEncryptor keyEncryptor) throws PGPException, NoSuchProviderException { this(certificationLevel, new PGPKeyPair(algorithm, pubKey, privKey, time), id, null, hashedPcks, unhashedPcks, certificationSignerBuilder, keyEncryptor); } /** * Return true if this key has an algorithm type that makes it suitable to use for signing. *

    * Note: with version 4 keys KeyFlags subpackets should also be considered when present for * determining the preferred use of the key. * * @return true if this key algorithm is suitable for use with signing. */ public boolean isSigningKey() { int algorithm = pub.getAlgorithm(); return ((algorithm == PGPPublicKey.RSA_GENERAL) || (algorithm == PGPPublicKey.RSA_SIGN) || (algorithm == PGPPublicKey.DSA) || (algorithm == PGPPublicKey.ECDSA) || (algorithm == PGPPublicKey.ELGAMAL_GENERAL)); } /** * Return true if this is a master key. * @return true if a master key. */ public boolean isMasterKey() { return pub.isMasterKey(); } /** * Detect if the Secret Key's Private Key is empty or not * * @return boolean whether or not the private key is empty */ public boolean isPrivateKeyEmpty() { byte[] secKeyData = secret.getSecretKeyData(); return (secKeyData == null || secKeyData.length < 1); } /** * return the algorithm the key is encrypted with. * * @return the algorithm used to encrypt the secret key. */ public int getKeyEncryptionAlgorithm() { return secret.getEncAlgorithm(); } /** * Return the keyID of the public key associated with this key. * * @return the keyID associated with this key. */ public long getKeyID() { return pub.getKeyID(); } /** * Return the public key associated with this key. * * @return the public key for this key. */ public PGPPublicKey getPublicKey() { return pub; } /** * Return any userIDs associated with the key. * * @return an iterator of Strings. */ public Iterator getUserIDs() { return pub.getUserIDs(); } /** * Return any user attribute vectors associated with the key. * * @return an iterator of Strings. */ public Iterator getUserAttributes() { return pub.getUserAttributes(); } private byte[] extractKeyData( PBESecretKeyDecryptor decryptorFactory) throws PGPException { byte[] encData = secret.getSecretKeyData(); byte[] data = null; if (secret.getEncAlgorithm() != SymmetricKeyAlgorithmTags.NULL) { try { if (secret.getPublicKeyPacket().getVersion() == 4) { byte[] key = decryptorFactory.makeKeyFromPassPhrase(secret.getEncAlgorithm(), secret.getS2K()); data = decryptorFactory.recoverKeyData(secret.getEncAlgorithm(), key, secret.getIV(), encData, 0, encData.length); boolean useSHA1 = secret.getS2KUsage() == SecretKeyPacket.USAGE_SHA1; byte[] check = checksum(useSHA1 ? decryptorFactory.getChecksumCalculator(HashAlgorithmTags.SHA1) : null, data, (useSHA1) ? data.length - 20 : data.length - 2); for (int i = 0; i != check.length; i++) { if (check[i] != data[data.length - check.length + i]) { throw new PGPException("checksum mismatch at " + i + " of " + check.length); } } } else // version 2 or 3, RSA only. { byte[] key = decryptorFactory.makeKeyFromPassPhrase(secret.getEncAlgorithm(), secret.getS2K()); data = new byte[encData.length]; byte[] iv = new byte[secret.getIV().length]; System.arraycopy(secret.getIV(), 0, iv, 0, iv.length); // // read in the four numbers // int pos = 0; for (int i = 0; i != 4; i++) { int encLen = (((encData[pos] << 8) | (encData[pos + 1] & 0xff)) + 7) / 8; data[pos] = encData[pos]; data[pos + 1] = encData[pos + 1]; byte[] tmp = decryptorFactory.recoverKeyData(secret.getEncAlgorithm(), key, iv, encData, pos + 2, encLen); System.arraycopy(tmp, 0, data, pos + 2, tmp.length); pos += 2 + encLen; if (i != 3) { System.arraycopy(encData, pos - iv.length, iv, 0, iv.length); } } // // verify and copy checksum // data[pos] = encData[pos]; data[pos + 1] = encData[pos + 1]; int cs = ((encData[pos] << 8) & 0xff00) | (encData[pos + 1] & 0xff); int calcCs = 0; for (int j = 0; j < data.length - 2; j++) { calcCs += data[j] & 0xff; } calcCs &= 0xffff; if (calcCs != cs) { throw new PGPException("checksum mismatch: passphrase wrong, expected " + Integer.toHexString(cs) + " found " + Integer.toHexString(calcCs)); } } } catch (PGPException e) { throw e; } catch (Exception e) { throw new PGPException("Exception decrypting key", e); } } else { data = encData; } return data; } /** * Extract a PGPPrivate key from the SecretKey's encrypted contents. * * @param passPhrase * @param provider * @return PGPPrivateKey * @throws PGPException * @throws NoSuchProviderException * @deprecated use method that takes a PBESecretKeyDecryptor */ public PGPPrivateKey extractPrivateKey( char[] passPhrase, String provider) throws PGPException, NoSuchProviderException { return extractPrivateKey(passPhrase, PGPUtil.getProvider(provider)); } /** * Extract a PGPPrivate key from the SecretKey's encrypted contents. * * @param passPhrase * @param provider * @return PGPPrivateKey * @throws PGPException * @deprecated use method that takes a PBESecretKeyDecryptor */ public PGPPrivateKey extractPrivateKey( char[] passPhrase, Provider provider) throws PGPException { return extractPrivateKey(new JcePBESecretKeyDecryptorBuilder(new JcaPGPDigestCalculatorProviderBuilder().setProvider(provider).build()).setProvider(provider).build(passPhrase)); } /** * Extract a PGPPrivate key from the SecretKey's encrypted contents. * * @param decryptorFactory factory to use to generate a decryptor for the passed in secretKey. * @return PGPPrivateKey the unencrypted private key. * @throws PGPException on failure. */ public PGPPrivateKey extractPrivateKey( PBESecretKeyDecryptor decryptorFactory) throws PGPException { if (isPrivateKeyEmpty()) { return null; } PublicKeyPacket pubPk = secret.getPublicKeyPacket(); try { byte[] data = extractKeyData(decryptorFactory); BCPGInputStream in = new BCPGInputStream(new ByteArrayInputStream(data)); switch (pubPk.getAlgorithm()) { case PGPPublicKey.RSA_ENCRYPT: case PGPPublicKey.RSA_GENERAL: case PGPPublicKey.RSA_SIGN: RSASecretBCPGKey rsaPriv = new RSASecretBCPGKey(in); return new PGPPrivateKey(this.getKeyID(), pubPk, rsaPriv); case PGPPublicKey.DSA: DSASecretBCPGKey dsaPriv = new DSASecretBCPGKey(in); return new PGPPrivateKey(this.getKeyID(), pubPk, dsaPriv); case PGPPublicKey.ELGAMAL_ENCRYPT: case PGPPublicKey.ELGAMAL_GENERAL: ElGamalSecretBCPGKey elPriv = new ElGamalSecretBCPGKey(in); return new PGPPrivateKey(this.getKeyID(), pubPk, elPriv); default: throw new PGPException("unknown public key algorithm encountered"); } } catch (PGPException e) { throw e; } catch (Exception e) { throw new PGPException("Exception constructing key", e); } } private static byte[] checksum(PGPDigestCalculator digCalc, byte[] bytes, int length) throws PGPException { if (digCalc != null) { OutputStream dOut = digCalc.getOutputStream(); try { dOut.write(bytes, 0, length); dOut.close(); } catch (Exception e) { throw new PGPException("checksum digest calculation failed: " + e.getMessage(), e); } return digCalc.getDigest(); } else { int checksum = 0; for (int i = 0; i != length; i++) { checksum += bytes[i] & 0xff; } byte[] check = new byte[2]; check[0] = (byte)(checksum >> 8); check[1] = (byte)checksum; return check; } } public byte[] getEncoded() throws IOException { ByteArrayOutputStream bOut = new ByteArrayOutputStream(); this.encode(bOut); return bOut.toByteArray(); } public void encode( OutputStream outStream) throws IOException { BCPGOutputStream out; if (outStream instanceof BCPGOutputStream) { out = (BCPGOutputStream)outStream; } else { out = new BCPGOutputStream(outStream); } out.writePacket(secret); if (pub.trustPk != null) { out.writePacket(pub.trustPk); } if (pub.subSigs == null) // is not a sub key { for (int i = 0; i != pub.keySigs.size(); i++) { ((PGPSignature)pub.keySigs.get(i)).encode(out); } for (int i = 0; i != pub.ids.size(); i++) { if (pub.ids.get(i) instanceof String) { String id = (String)pub.ids.get(i); out.writePacket(new UserIDPacket(id)); } else { PGPUserAttributeSubpacketVector v = (PGPUserAttributeSubpacketVector)pub.ids.get(i); out.writePacket(new UserAttributePacket(v.toSubpacketArray())); } if (pub.idTrusts.get(i) != null) { out.writePacket((ContainedPacket)pub.idTrusts.get(i)); } List sigs = (ArrayList)pub.idSigs.get(i); for (int j = 0; j != sigs.size(); j++) { ((PGPSignature)sigs.get(j)).encode(out); } } } else { for (int j = 0; j != pub.subSigs.size(); j++) { ((PGPSignature)pub.subSigs.get(j)).encode(out); } } } /** * Return a copy of the passed in secret key, encrypted using a new * password and the passed in algorithm. * * @param key the PGPSecretKey to be copied. * @param oldPassPhrase the current password for key. * @param newPassPhrase the new password for the key. * @param newEncAlgorithm the algorithm to be used for the encryption. * @param rand source of randomness. * @param provider name of the provider to use * @deprecated use method taking PBESecretKeyDecryptor and PBESecretKeyEncryptor */ public static PGPSecretKey copyWithNewPassword( PGPSecretKey key, char[] oldPassPhrase, char[] newPassPhrase, int newEncAlgorithm, SecureRandom rand, String provider) throws PGPException, NoSuchProviderException { return copyWithNewPassword(key, oldPassPhrase, newPassPhrase, newEncAlgorithm, rand, PGPUtil.getProvider(provider)); } /** * Return a copy of the passed in secret key, encrypted using a new * password and the passed in algorithm. * * @param key the PGPSecretKey to be copied. * @param oldKeyDecryptor the current decryptor based on the current password for key. * @param newKeyEncryptor a new encryptor based on a new password for encrypting the secret key material. */ public static PGPSecretKey copyWithNewPassword( PGPSecretKey key, PBESecretKeyDecryptor oldKeyDecryptor, PBESecretKeyEncryptor newKeyEncryptor) throws PGPException { if (key.isPrivateKeyEmpty()) { throw new PGPException("no private key in this SecretKey - public key present only."); } byte[] rawKeyData = key.extractKeyData(oldKeyDecryptor); int s2kUsage = key.secret.getS2KUsage(); byte[] iv = null; S2K s2k = null; byte[] keyData; int newEncAlgorithm = SymmetricKeyAlgorithmTags.NULL; if (newKeyEncryptor == null || newKeyEncryptor.getAlgorithm() == SymmetricKeyAlgorithmTags.NULL) { s2kUsage = SecretKeyPacket.USAGE_NONE; if (key.secret.getS2KUsage() == SecretKeyPacket.USAGE_SHA1) // SHA-1 hash, need to rewrite checksum { keyData = new byte[rawKeyData.length - 18]; System.arraycopy(rawKeyData, 0, keyData, 0, keyData.length - 2); byte[] check = checksum(null, keyData, keyData.length - 2); keyData[keyData.length - 2] = check[0]; keyData[keyData.length - 1] = check[1]; } else { keyData = rawKeyData; } } else { if (key.secret.getPublicKeyPacket().getVersion() < 4) { // Version 2 or 3 - RSA Keys only byte[] encKey = newKeyEncryptor.getKey(); keyData = new byte[rawKeyData.length]; if (newKeyEncryptor.getHashAlgorithm() != HashAlgorithmTags.MD5) { throw new PGPException("MD5 Digest Calculator required for version 3 key encryptor."); } // // process 4 numbers // int pos = 0; for (int i = 0; i != 4; i++) { int encLen = (((rawKeyData[pos] << 8) | (rawKeyData[pos + 1] & 0xff)) + 7) / 8; keyData[pos] = rawKeyData[pos]; keyData[pos + 1] = rawKeyData[pos + 1]; byte[] tmp; if (i == 0) { tmp = newKeyEncryptor.encryptKeyData(encKey, rawKeyData, pos + 2, encLen); iv = newKeyEncryptor.getCipherIV(); } else { byte[] tmpIv = new byte[iv.length]; System.arraycopy(keyData, pos - iv.length, tmpIv, 0, tmpIv.length); tmp = newKeyEncryptor.encryptKeyData(encKey, tmpIv, rawKeyData, pos + 2, encLen); } System.arraycopy(tmp, 0, keyData, pos + 2, tmp.length); pos += 2 + encLen; } // // copy in checksum. // keyData[pos] = rawKeyData[pos]; keyData[pos + 1] = rawKeyData[pos + 1]; s2k = newKeyEncryptor.getS2K(); newEncAlgorithm = newKeyEncryptor.getAlgorithm(); } else { keyData = newKeyEncryptor.encryptKeyData(rawKeyData, 0, rawKeyData.length); iv = newKeyEncryptor.getCipherIV(); s2k = newKeyEncryptor.getS2K(); newEncAlgorithm = newKeyEncryptor.getAlgorithm(); } } SecretKeyPacket secret; if (key.secret instanceof SecretSubkeyPacket) { secret = new SecretSubkeyPacket(key.secret.getPublicKeyPacket(), newEncAlgorithm, s2kUsage, s2k, iv, keyData); } else { secret = new SecretKeyPacket(key.secret.getPublicKeyPacket(), newEncAlgorithm, s2kUsage, s2k, iv, keyData); } return new PGPSecretKey(secret, key.pub); } /** * Return a copy of the passed in secret key, encrypted using a new * password and the passed in algorithm. * * @param key the PGPSecretKey to be copied. * @param oldPassPhrase the current password for key. * @param newPassPhrase the new password for the key. * @param newEncAlgorithm the algorithm to be used for the encryption. * @param rand source of randomness. * @param provider the provider to use * @deprecated use method taking PBESecretKeyDecryptor and PBESecretKeyEncryptor */ public static PGPSecretKey copyWithNewPassword( PGPSecretKey key, char[] oldPassPhrase, char[] newPassPhrase, int newEncAlgorithm, SecureRandom rand, Provider provider) throws PGPException { return copyWithNewPassword(key, new JcePBESecretKeyDecryptorBuilder(new JcaPGPDigestCalculatorProviderBuilder().setProvider(provider).build()).setProvider(provider).build(oldPassPhrase), new JcePBESecretKeyEncryptorBuilder(newEncAlgorithm).setProvider(provider).setSecureRandom(rand).build(newPassPhrase)); } /** * Replace the passed the public key on the passed in secret key. * * @param secretKey secret key to change * @param publicKey new public key. * @return a new secret key. * @throws IllegalArgumentException if keyIDs do not match. */ public static PGPSecretKey replacePublicKey(PGPSecretKey secretKey, PGPPublicKey publicKey) { if (publicKey.getKeyID() != secretKey.getKeyID()) { throw new IllegalArgumentException("keyIDs do not match"); } return new PGPSecretKey(secretKey.secret, publicKey); } } bouncycastle-1.49.orig/src/org/bouncycastle/openpgp/PGPCompressedData.java0000644000175000017500000000763710747222113026276 0ustar ebourgebourgpackage org.bouncycastle.openpgp; import java.io.EOFException; import java.io.IOException; import java.io.InputStream; import java.util.zip.Inflater; import java.util.zip.InflaterInputStream; import org.bouncycastle.bcpg.BCPGInputStream; import org.bouncycastle.bcpg.CompressedDataPacket; import org.bouncycastle.bcpg.CompressionAlgorithmTags; import org.bouncycastle.apache.bzip2.CBZip2InputStream; /** * Compressed data objects. */ public class PGPCompressedData implements CompressionAlgorithmTags { CompressedDataPacket data; public PGPCompressedData( BCPGInputStream pIn) throws IOException { data = (CompressedDataPacket)pIn.readPacket(); } /** * Return the algorithm used for compression * * @return algorithm code */ public int getAlgorithm() { return data.getAlgorithm(); } /** * Return the raw input stream contained in the object. * * @return InputStream */ public InputStream getInputStream() { return data.getInputStream(); } /** * Return an uncompressed input stream which allows reading of the * compressed data. * * @return InputStream * @throws PGPException */ public InputStream getDataStream() throws PGPException { if (this.getAlgorithm() == UNCOMPRESSED) { return this.getInputStream(); } if (this.getAlgorithm() == ZIP) { return new InflaterInputStream(this.getInputStream(), new Inflater(true)) { // If the "nowrap" inflater option is used the stream can // apparently overread - we override fill() and provide // an extra byte for the end of the input stream to get // around this. // // Totally weird... // protected void fill() throws IOException { if (eof) { throw new EOFException("Unexpected end of ZIP input stream"); } len = this.in.read(buf, 0, buf.length); if (len == -1) { buf[0] = 0; len = 1; eof = true; } inf.setInput(buf, 0, len); } private boolean eof = false; }; } if (this.getAlgorithm() == ZLIB) { return new InflaterInputStream(this.getInputStream()) { // If the "nowrap" inflater option is used the stream can // apparently overread - we override fill() and provide // an extra byte for the end of the input stream to get // around this. // // Totally weird... // protected void fill() throws IOException { if (eof) { throw new EOFException("Unexpected end of ZIP input stream"); } len = this.in.read(buf, 0, buf.length); if (len == -1) { buf[0] = 0; len = 1; eof = true; } inf.setInput(buf, 0, len); } private boolean eof = false; }; } if (this.getAlgorithm() == BZIP2) { try { return new CBZip2InputStream(this.getInputStream()); } catch (IOException e) { throw new PGPException("I/O problem with stream: " + e, e); } } throw new PGPException("can't recognise compression algorithm: " + this.getAlgorithm()); } } bouncycastle-1.49.orig/src/org/bouncycastle/openpgp/PGPUtil.java0000644000175000017500000002426411600027126024304 0ustar ebourgebourgpackage org.bouncycastle.openpgp; import java.io.BufferedInputStream; import java.io.File; import java.io.FileInputStream; import java.io.IOException; import java.io.InputStream; import java.io.OutputStream; import java.security.NoSuchProviderException; import java.security.Provider; import java.security.SecureRandom; import java.security.Security; import java.util.Date; import org.bouncycastle.asn1.ASN1InputStream; import org.bouncycastle.asn1.ASN1Sequence; import org.bouncycastle.asn1.DERInteger; import org.bouncycastle.bcpg.ArmoredInputStream; import org.bouncycastle.bcpg.HashAlgorithmTags; import org.bouncycastle.bcpg.MPInteger; import org.bouncycastle.bcpg.PublicKeyAlgorithmTags; import org.bouncycastle.bcpg.SymmetricKeyAlgorithmTags; import org.bouncycastle.util.encoders.Base64; /** * Basic utility class */ public class PGPUtil implements HashAlgorithmTags { private static String defProvider = "BC"; /** * Return the provider that will be used by factory classes in situations * where a provider must be determined on the fly. * * @return String */ public static String getDefaultProvider() { return defProvider; } /** * Set the provider to be used by the package when it is necessary to * find one on the fly. * * @param provider */ public static void setDefaultProvider( String provider) { defProvider = provider; } static MPInteger[] dsaSigToMpi( byte[] encoding) throws PGPException { ASN1InputStream aIn = new ASN1InputStream(encoding); DERInteger i1; DERInteger i2; try { ASN1Sequence s = (ASN1Sequence)aIn.readObject(); i1 = (DERInteger)s.getObjectAt(0); i2 = (DERInteger)s.getObjectAt(1); } catch (IOException e) { throw new PGPException("exception encoding signature", e); } MPInteger[] values = new MPInteger[2]; values[0] = new MPInteger(i1.getValue()); values[1] = new MPInteger(i2.getValue()); return values; } static String getDigestName( int hashAlgorithm) throws PGPException { switch (hashAlgorithm) { case HashAlgorithmTags.SHA1: return "SHA1"; case HashAlgorithmTags.MD2: return "MD2"; case HashAlgorithmTags.MD5: return "MD5"; case HashAlgorithmTags.RIPEMD160: return "RIPEMD160"; case HashAlgorithmTags.SHA256: return "SHA256"; case HashAlgorithmTags.SHA384: return "SHA384"; case HashAlgorithmTags.SHA512: return "SHA512"; case HashAlgorithmTags.SHA224: return "SHA224"; default: throw new PGPException("unknown hash algorithm tag in getDigestName: " + hashAlgorithm); } } static String getSignatureName( int keyAlgorithm, int hashAlgorithm) throws PGPException { String encAlg; switch (keyAlgorithm) { case PublicKeyAlgorithmTags.RSA_GENERAL: case PublicKeyAlgorithmTags.RSA_SIGN: encAlg = "RSA"; break; case PublicKeyAlgorithmTags.DSA: encAlg = "DSA"; break; case PublicKeyAlgorithmTags.ELGAMAL_ENCRYPT: // in some malformed cases. case PublicKeyAlgorithmTags.ELGAMAL_GENERAL: encAlg = "ElGamal"; break; default: throw new PGPException("unknown algorithm tag in signature:" + keyAlgorithm); } return getDigestName(hashAlgorithm) + "with" + encAlg; } public static byte[] makeRandomKey( int algorithm, SecureRandom random) throws PGPException { int keySize = 0; switch (algorithm) { case SymmetricKeyAlgorithmTags.TRIPLE_DES: keySize = 192; break; case SymmetricKeyAlgorithmTags.IDEA: keySize = 128; break; case SymmetricKeyAlgorithmTags.CAST5: keySize = 128; break; case SymmetricKeyAlgorithmTags.BLOWFISH: keySize = 128; break; case SymmetricKeyAlgorithmTags.SAFER: keySize = 128; break; case SymmetricKeyAlgorithmTags.DES: keySize = 64; break; case SymmetricKeyAlgorithmTags.AES_128: keySize = 128; break; case SymmetricKeyAlgorithmTags.AES_192: keySize = 192; break; case SymmetricKeyAlgorithmTags.AES_256: keySize = 256; break; case SymmetricKeyAlgorithmTags.TWOFISH: keySize = 256; break; default: throw new PGPException("unknown symmetric algorithm: " + algorithm); } byte[] keyBytes = new byte[(keySize + 7) / 8]; random.nextBytes(keyBytes); return keyBytes; } /** * write out the passed in file as a literal data packet. * * @param out * @param fileType the LiteralData type for the file. * @param file * * @throws IOException */ public static void writeFileToLiteralData( OutputStream out, char fileType, File file) throws IOException { PGPLiteralDataGenerator lData = new PGPLiteralDataGenerator(); OutputStream pOut = lData.open(out, fileType, file.getName(), file.length(), new Date(file.lastModified())); pipeFileContents(file, pOut, 4096); } /** * write out the passed in file as a literal data packet in partial packet format. * * @param out * @param fileType the LiteralData type for the file. * @param file * @param buffer buffer to be used to chunk the file into partial packets. * * @throws IOException */ public static void writeFileToLiteralData( OutputStream out, char fileType, File file, byte[] buffer) throws IOException { PGPLiteralDataGenerator lData = new PGPLiteralDataGenerator(); OutputStream pOut = lData.open(out, fileType, file.getName(), new Date(file.lastModified()), buffer); pipeFileContents(file, pOut, buffer.length); } private static void pipeFileContents(File file, OutputStream pOut, int bufSize) throws IOException { FileInputStream in = new FileInputStream(file); byte[] buf = new byte[bufSize]; int len; while ((len = in.read(buf)) > 0) { pOut.write(buf, 0, len); } pOut.close(); in.close(); } private static final int READ_AHEAD = 60; private static boolean isPossiblyBase64( int ch) { return (ch >= 'A' && ch <= 'Z') || (ch >= 'a' && ch <= 'z') || (ch >= '0' && ch <= '9') || (ch == '+') || (ch == '/') || (ch == '\r') || (ch == '\n'); } /** * Return either an ArmoredInputStream or a BCPGInputStream based on * whether the initial characters of the stream are binary PGP encodings or not. * * @param in the stream to be wrapped * @return a BCPGInputStream * @throws IOException */ public static InputStream getDecoderStream( InputStream in) throws IOException { if (!in.markSupported()) { in = new BufferedInputStreamExt(in); } in.mark(READ_AHEAD); int ch = in.read(); if ((ch & 0x80) != 0) { in.reset(); return in; } else { if (!isPossiblyBase64(ch)) { in.reset(); return new ArmoredInputStream(in); } byte[] buf = new byte[READ_AHEAD]; int count = 1; int index = 1; buf[0] = (byte)ch; while (count != READ_AHEAD && (ch = in.read()) >= 0) { if (!isPossiblyBase64(ch)) { in.reset(); return new ArmoredInputStream(in); } if (ch != '\n' && ch != '\r') { buf[index++] = (byte)ch; } count++; } in.reset(); // // nothing but new lines, little else, assume regular armoring // if (count < 4) { return new ArmoredInputStream(in); } // // test our non-blank data // byte[] firstBlock = new byte[8]; System.arraycopy(buf, 0, firstBlock, 0, firstBlock.length); byte[] decoded = Base64.decode(firstBlock); // // it's a base64 PGP block. // if ((decoded[0] & 0x80) != 0) { return new ArmoredInputStream(in, false); } return new ArmoredInputStream(in); } } static Provider getProvider(String providerName) throws NoSuchProviderException { Provider prov = Security.getProvider(providerName); if (prov == null) { throw new NoSuchProviderException("provider " + providerName + " not found."); } return prov; } static class BufferedInputStreamExt extends BufferedInputStream { BufferedInputStreamExt(InputStream input) { super(input); } public synchronized int available() throws IOException { int result = super.available(); if (result < 0) { result = Integer.MAX_VALUE; } return result; } } } bouncycastle-1.49.orig/src/org/bouncycastle/openpgp/PGPPBEEncryptedData.java0000644000175000017500000001421411576524035026454 0ustar ebourgebourgpackage org.bouncycastle.openpgp; import java.io.EOFException; import java.io.InputStream; import java.security.NoSuchProviderException; import java.security.Provider; import org.bouncycastle.bcpg.BCPGInputStream; import org.bouncycastle.bcpg.InputStreamPacket; import org.bouncycastle.bcpg.SymmetricEncIntegrityPacket; import org.bouncycastle.bcpg.SymmetricKeyEncSessionPacket; import org.bouncycastle.openpgp.operator.PBEDataDecryptorFactory; import org.bouncycastle.openpgp.operator.PGPDataDecryptor; import org.bouncycastle.openpgp.operator.jcajce.JcaPGPDigestCalculatorProviderBuilder; import org.bouncycastle.openpgp.operator.jcajce.JcePBEDataDecryptorFactoryBuilder; import org.bouncycastle.util.io.TeeInputStream; /** * A password based encryption object. */ public class PGPPBEEncryptedData extends PGPEncryptedData { SymmetricKeyEncSessionPacket keyData; PGPPBEEncryptedData( SymmetricKeyEncSessionPacket keyData, InputStreamPacket encData) { super(encData); this.keyData = keyData; } /** * Return the raw input stream for the data stream. * * @return InputStream */ public InputStream getInputStream() { return encData.getInputStream(); } /** * Return the decrypted input stream, using the passed in passPhrase. * * @param passPhrase * @param provider * @return InputStream * @throws PGPException * @throws NoSuchProviderException * @deprecated use PBEDataDecryptorFactory method */ public InputStream getDataStream( char[] passPhrase, String provider) throws PGPException, NoSuchProviderException { return getDataStream(passPhrase, PGPUtil.getProvider(provider)); } /** * Return the decrypted input stream, using the passed in passPhrase. * * @param passPhrase * @param provider * @return InputStream * @throws PGPException * @deprecated use PBEDataDecryptorFactory method */ public InputStream getDataStream( char[] passPhrase, Provider provider) throws PGPException { return getDataStream(new JcePBEDataDecryptorFactoryBuilder(new JcaPGPDigestCalculatorProviderBuilder().setProvider(provider).build()).setProvider(provider).build(passPhrase)); } /** * Return the symmetric key algorithm required to decrypt the data protected by this object. * * @param dataDecryptorFactory decryptor factory to use to recover the session data. * @return the integer encryption algorithm code. * @throws PGPException if the session data cannot be recovered. */ public int getSymmetricAlgorithm( PBEDataDecryptorFactory dataDecryptorFactory) throws PGPException { byte[] key = dataDecryptorFactory.makeKeyFromPassPhrase(keyData.getEncAlgorithm(), keyData.getS2K()); byte[] sessionData = dataDecryptorFactory.recoverSessionData(keyData.getEncAlgorithm(), key, keyData.getSecKeyData()); return sessionData[0]; } /** * Open an input stream which will provide the decrypted data protected by this object. * * @param dataDecryptorFactory decryptor factory to use to recover the session data and provide the stream. * @return the resulting input stream * @throws PGPException if the session data cannot be recovered or the stream cannot be created. */ public InputStream getDataStream( PBEDataDecryptorFactory dataDecryptorFactory) throws PGPException { try { int keyAlgorithm = keyData.getEncAlgorithm(); byte[] key = dataDecryptorFactory.makeKeyFromPassPhrase(keyAlgorithm, keyData.getS2K()); boolean withIntegrityPacket = encData instanceof SymmetricEncIntegrityPacket; byte[] sessionData = dataDecryptorFactory.recoverSessionData(keyData.getEncAlgorithm(), key, keyData.getSecKeyData()); byte[] sessionKey = new byte[sessionData.length - 1]; System.arraycopy(sessionData, 1, sessionKey, 0, sessionKey.length); PGPDataDecryptor dataDecryptor = dataDecryptorFactory.createDataDecryptor(withIntegrityPacket, sessionData[0] & 0xff, sessionKey); encStream = new BCPGInputStream(dataDecryptor.getInputStream(encData.getInputStream())); if (withIntegrityPacket) { truncStream = new TruncatedStream(encStream); integrityCalculator = dataDecryptor.getIntegrityCalculator(); encStream = new TeeInputStream(truncStream, integrityCalculator.getOutputStream()); } byte[] iv = new byte[dataDecryptor.getBlockSize()]; for (int i = 0; i != iv.length; i++) { int ch = encStream.read(); if (ch < 0) { throw new EOFException("unexpected end of stream."); } iv[i] = (byte)ch; } int v1 = encStream.read(); int v2 = encStream.read(); if (v1 < 0 || v2 < 0) { throw new EOFException("unexpected end of stream."); } // Note: the oracle attack on "quick check" bytes is not deemed // a security risk for PBE (see PGPPublicKeyEncryptedData) boolean repeatCheckPassed = iv[iv.length - 2] == (byte) v1 && iv[iv.length - 1] == (byte) v2; // Note: some versions of PGP appear to produce 0 for the extra // bytes rather than repeating the two previous bytes boolean zeroesCheckPassed = v1 == 0 && v2 == 0; if (!repeatCheckPassed && !zeroesCheckPassed) { throw new PGPDataValidationException("data check failed."); } return encStream; } catch (PGPException e) { throw e; } catch (Exception e) { throw new PGPException("Exception creating cipher", e); } } } bouncycastle-1.49.orig/src/org/bouncycastle/openpgp/PGPKeyRing.java0000644000175000017500000000651711600515571024746 0ustar ebourgebourgpackage org.bouncycastle.openpgp; import java.io.IOException; import java.io.InputStream; import java.io.OutputStream; import java.util.ArrayList; import java.util.Iterator; import java.util.List; import org.bouncycastle.bcpg.BCPGInputStream; import org.bouncycastle.bcpg.Packet; import org.bouncycastle.bcpg.PacketTags; import org.bouncycastle.bcpg.SignaturePacket; import org.bouncycastle.bcpg.TrustPacket; import org.bouncycastle.bcpg.UserAttributePacket; import org.bouncycastle.bcpg.UserIDPacket; public abstract class PGPKeyRing { PGPKeyRing() { } static BCPGInputStream wrap(InputStream in) { if (in instanceof BCPGInputStream) { return (BCPGInputStream)in; } return new BCPGInputStream(in); } static TrustPacket readOptionalTrustPacket( BCPGInputStream pIn) throws IOException { return (pIn.nextPacketTag() == PacketTags.TRUST) ? (TrustPacket) pIn.readPacket() : null; } static List readSignaturesAndTrust( BCPGInputStream pIn) throws IOException { try { List sigList = new ArrayList(); while (pIn.nextPacketTag() == PacketTags.SIGNATURE) { SignaturePacket signaturePacket = (SignaturePacket)pIn.readPacket(); TrustPacket trustPacket = readOptionalTrustPacket(pIn); sigList.add(new PGPSignature(signaturePacket, trustPacket)); } return sigList; } catch (PGPException e) { throw new IOException("can't create signature object: " + e.getMessage() + ", cause: " + e.getUnderlyingException().toString()); } } static void readUserIDs( BCPGInputStream pIn, List ids, List idTrusts, List idSigs) throws IOException { while (pIn.nextPacketTag() == PacketTags.USER_ID || pIn.nextPacketTag() == PacketTags.USER_ATTRIBUTE) { Packet obj = pIn.readPacket(); if (obj instanceof UserIDPacket) { UserIDPacket id = (UserIDPacket)obj; ids.add(id.getID()); } else { UserAttributePacket user = (UserAttributePacket)obj; ids.add(new PGPUserAttributeSubpacketVector(user.getSubpackets())); } idTrusts.add(readOptionalTrustPacket(pIn)); idSigs.add(readSignaturesAndTrust(pIn)); } } /** * Return the first public key in the ring. In the case of a {@link PGPSecretKeyRing} * this is also the public key of the master key pair. * * @return PGPPublicKey */ public abstract PGPPublicKey getPublicKey(); /** * Return an iterator containing all the public keys. * * @return Iterator */ public abstract Iterator getPublicKeys(); /** * Return the public key referred to by the passed in keyID if it * is present. * * @param keyID * @return PGPPublicKey */ public abstract PGPPublicKey getPublicKey(long keyID); public abstract void encode(OutputStream outStream) throws IOException; public abstract byte[] getEncoded() throws IOException; }bouncycastle-1.49.orig/src/org/bouncycastle/openpgp/PGPKeyValidationException.java0000644000175000017500000000043110262753174030013 0ustar ebourgebourgpackage org.bouncycastle.openpgp; /** * Thrown if the key checksum is invalid. */ public class PGPKeyValidationException extends PGPException { /** * @param message */ public PGPKeyValidationException(String message) { super(message); } } bouncycastle-1.49.orig/src/org/bouncycastle/openpgp/PGPSecretKeyRingCollection.java0000644000175000017500000002530511043534405030122 0ustar ebourgebourgpackage org.bouncycastle.openpgp; import org.bouncycastle.bcpg.BCPGOutputStream; import org.bouncycastle.util.Strings; import java.io.ByteArrayInputStream; import java.io.ByteArrayOutputStream; import java.io.IOException; import java.io.InputStream; import java.io.OutputStream; import java.util.ArrayList; import java.util.Collection; import java.util.HashMap; import java.util.Iterator; import java.util.List; import java.util.Map; /** * Often a PGP key ring file is made up of a succession of master/sub-key key rings. * If you want to read an entire secret key file in one hit this is the class for you. */ public class PGPSecretKeyRingCollection { private Map secretRings = new HashMap(); private List order = new ArrayList(); private PGPSecretKeyRingCollection( Map secretRings, List order) { this.secretRings = secretRings; this.order = order; } public PGPSecretKeyRingCollection( byte[] encoding) throws IOException, PGPException { this(new ByteArrayInputStream(encoding)); } /** * Build a PGPSecretKeyRingCollection from the passed in input stream. * * @param in input stream containing data * @throws IOException if a problem parsinh the base stream occurs * @throws PGPException if an object is encountered which isn't a PGPSecretKeyRing */ public PGPSecretKeyRingCollection( InputStream in) throws IOException, PGPException { PGPObjectFactory pgpFact = new PGPObjectFactory(in); Object obj; while ((obj = pgpFact.nextObject()) != null) { if (!(obj instanceof PGPSecretKeyRing)) { throw new PGPException(obj.getClass().getName() + " found where PGPSecretKeyRing expected"); } PGPSecretKeyRing pgpSecret = (PGPSecretKeyRing)obj; Long key = new Long(pgpSecret.getPublicKey().getKeyID()); secretRings.put(key, pgpSecret); order.add(key); } } public PGPSecretKeyRingCollection( Collection collection) throws IOException, PGPException { Iterator it = collection.iterator(); while (it.hasNext()) { PGPSecretKeyRing pgpSecret = (PGPSecretKeyRing)it.next(); Long key = new Long(pgpSecret.getPublicKey().getKeyID()); secretRings.put(key, pgpSecret); order.add(key); } } /** * Return the number of rings in this collection. * * @return size of the collection */ public int size() { return order.size(); } /** * return the secret key rings making up this collection. */ public Iterator getKeyRings() { return secretRings.values().iterator(); } /** * Return an iterator of the key rings associated with the passed in userID. * * @param userID the user ID to be matched. * @return an iterator (possibly empty) of key rings which matched. * @throws PGPException */ public Iterator getKeyRings( String userID) throws PGPException { return getKeyRings(userID, false, false); } /** * Return an iterator of the key rings associated with the passed in userID. *

    * * @param userID the user ID to be matched. * @param matchPartial if true userID need only be a substring of an actual ID string to match. * @return an iterator (possibly empty) of key rings which matched. * @throws PGPException */ public Iterator getKeyRings( String userID, boolean matchPartial) throws PGPException { return getKeyRings(userID, matchPartial, false); } /** * Return an iterator of the key rings associated with the passed in userID. *

    * * @param userID the user ID to be matched. * @param matchPartial if true userID need only be a substring of an actual ID string to match. * @param ignoreCase if true case is ignored in user ID comparisons. * @return an iterator (possibly empty) of key rings which matched. * @throws PGPException */ public Iterator getKeyRings( String userID, boolean matchPartial, boolean ignoreCase) throws PGPException { Iterator it = this.getKeyRings(); List rings = new ArrayList(); if (ignoreCase) { userID = Strings.toLowerCase(userID); } while (it.hasNext()) { PGPSecretKeyRing secRing = (PGPSecretKeyRing)it.next(); Iterator uIt = secRing.getSecretKey().getUserIDs(); while (uIt.hasNext()) { String next = (String)uIt.next(); if (ignoreCase) { next = Strings.toLowerCase(next); } if (matchPartial) { if (next.indexOf(userID) > -1) { rings.add(secRing); } } else { if (next.equals(userID)) { rings.add(secRing); } } } } return rings.iterator(); } /** * Return the PGP secret key associated with the given key id. * * @param keyID * @return the secret key * @throws PGPException */ public PGPSecretKey getSecretKey( long keyID) throws PGPException { Iterator it = this.getKeyRings(); while (it.hasNext()) { PGPSecretKeyRing secRing = (PGPSecretKeyRing)it.next(); PGPSecretKey sec = secRing.getSecretKey(keyID); if (sec != null) { return sec; } } return null; } /** * Return the secret key ring which contains the key referred to by keyID. * * @param keyID * @return the secret key ring * @throws PGPException */ public PGPSecretKeyRing getSecretKeyRing( long keyID) throws PGPException { Long id = new Long(keyID); if (secretRings.containsKey(id)) { return (PGPSecretKeyRing)secretRings.get(id); } Iterator it = this.getKeyRings(); while (it.hasNext()) { PGPSecretKeyRing secretRing = (PGPSecretKeyRing)it.next(); PGPSecretKey secret = secretRing.getSecretKey(keyID); if (secret != null) { return secretRing; } } return null; } /** * Return true if a key matching the passed in key ID is present, false otherwise. * * @param keyID key ID to look for. * @return true if keyID present, false otherwise. */ public boolean contains(long keyID) throws PGPException { return getSecretKey(keyID) != null; } public byte[] getEncoded() throws IOException { ByteArrayOutputStream bOut = new ByteArrayOutputStream(); this.encode(bOut); return bOut.toByteArray(); } public void encode( OutputStream outStream) throws IOException { BCPGOutputStream out; if (outStream instanceof BCPGOutputStream) { out = (BCPGOutputStream)outStream; } else { out = new BCPGOutputStream(outStream); } Iterator it = order.iterator(); while (it.hasNext()) { PGPSecretKeyRing sr = (PGPSecretKeyRing)secretRings.get(it.next()); sr.encode(out); } } /** * Return a new collection object containing the contents of the passed in collection and * the passed in secret key ring. * * @param ringCollection the collection the ring to be added to. * @param secretKeyRing the key ring to be added. * @return a new collection merging the current one with the passed in ring. * @exception IllegalArgumentException if the keyID for the passed in ring is already present. */ public static PGPSecretKeyRingCollection addSecretKeyRing( PGPSecretKeyRingCollection ringCollection, PGPSecretKeyRing secretKeyRing) { Long key = new Long(secretKeyRing.getPublicKey().getKeyID()); if (ringCollection.secretRings.containsKey(key)) { throw new IllegalArgumentException("Collection already contains a key with a keyID for the passed in ring."); } Map newSecretRings = new HashMap(ringCollection.secretRings); List newOrder = new ArrayList(ringCollection.order); newSecretRings.put(key, secretKeyRing); newOrder.add(key); return new PGPSecretKeyRingCollection(newSecretRings, newOrder); } /** * Return a new collection object containing the contents of this collection with * the passed in secret key ring removed. * * @param ringCollection the collection the ring to be removed from. * @param secretKeyRing the key ring to be removed. * @return a new collection merging the current one with the passed in ring. * @exception IllegalArgumentException if the keyID for the passed in ring is not present. */ public static PGPSecretKeyRingCollection removeSecretKeyRing( PGPSecretKeyRingCollection ringCollection, PGPSecretKeyRing secretKeyRing) { Long key = new Long(secretKeyRing.getPublicKey().getKeyID()); if (!ringCollection.secretRings.containsKey(key)) { throw new IllegalArgumentException("Collection does not contain a key with a keyID for the passed in ring."); } Map newSecretRings = new HashMap(ringCollection.secretRings); List newOrder = new ArrayList(ringCollection.order); newSecretRings.remove(key); for (int i = 0; i < newOrder.size(); i++) { Long r = (Long)newOrder.get(i); if (r.longValue() == key.longValue()) { newOrder.remove(i); break; } } return new PGPSecretKeyRingCollection(newSecretRings, newOrder); } } bouncycastle-1.49.orig/src/org/bouncycastle/openpgp/PGPLiteralDataGenerator.java0000644000175000017500000001420511676435312027433 0ustar ebourgebourgpackage org.bouncycastle.openpgp; import java.io.File; import java.io.IOException; import java.io.OutputStream; import java.util.Date; import org.bouncycastle.bcpg.BCPGOutputStream; import org.bouncycastle.bcpg.PacketTags; import org.bouncycastle.util.Strings; /** * Class for producing literal data packets. */ public class PGPLiteralDataGenerator implements StreamGenerator { public static final char BINARY = PGPLiteralData.BINARY; public static final char TEXT = PGPLiteralData.TEXT; public static final char UTF8 = PGPLiteralData.UTF8; /** * The special name indicating a "for your eyes only" packet. */ public static final String CONSOLE = PGPLiteralData.CONSOLE; /** * The special time for a modification time of "now" or * the present time. */ public static final Date NOW = PGPLiteralData.NOW; private BCPGOutputStream pkOut; private boolean oldFormat = false; public PGPLiteralDataGenerator() { } /** * Generates literal data objects in the old format, this is * important if you need compatability with PGP 2.6.x. * * @param oldFormat */ public PGPLiteralDataGenerator( boolean oldFormat) { this.oldFormat = oldFormat; } private void writeHeader( OutputStream out, char format, byte[] encName, long modificationTime) throws IOException { out.write(format); out.write((byte)encName.length); for (int i = 0; i != encName.length; i++) { out.write(encName[i]); } long modDate = modificationTime / 1000; out.write((byte)(modDate >> 24)); out.write((byte)(modDate >> 16)); out.write((byte)(modDate >> 8)); out.write((byte)(modDate)); } /** * Open a literal data packet, returning a stream to store the data inside * the packet. *

    * The stream created can be closed off by either calling close() * on the stream or close() on the generator. Closing the returned * stream does not close off the OutputStream parameter out. * * @param out the stream we want the packet in * @param format the format we are using * @param name the name of the "file" * @param length the length of the data we will write * @param modificationTime the time of last modification we want stored. */ public OutputStream open( OutputStream out, char format, String name, long length, Date modificationTime) throws IOException { if (pkOut != null) { throw new IllegalStateException("generator already in open state"); } byte[] encName = Strings.toUTF8ByteArray(name); pkOut = new BCPGOutputStream(out, PacketTags.LITERAL_DATA, length + 2 + encName.length + 4, oldFormat); writeHeader(pkOut, format, encName, modificationTime.getTime()); return new WrappedGeneratorStream(pkOut, this); } /** * Open a literal data packet, returning a stream to store the data inside * the packet as an indefinite length stream. The stream is written out as a * series of partial packets with a chunk size determined by the size of the * passed in buffer. *

    * The stream created can be closed off by either calling close() * on the stream or close() on the generator. Closing the returned * stream does not close off the OutputStream parameter out. *

    * Note: if the buffer is not a power of 2 in length only the largest power of 2 * bytes worth of the buffer will be used. * * @param out the stream we want the packet in * @param format the format we are using * @param name the name of the "file" * @param modificationTime the time of last modification we want stored. * @param buffer the buffer to use for collecting data to put into chunks. */ public OutputStream open( OutputStream out, char format, String name, Date modificationTime, byte[] buffer) throws IOException { if (pkOut != null) { throw new IllegalStateException("generator already in open state"); } pkOut = new BCPGOutputStream(out, PacketTags.LITERAL_DATA, buffer); byte[] encName = Strings.toUTF8ByteArray(name); writeHeader(pkOut, format, encName, modificationTime.getTime()); return new WrappedGeneratorStream(pkOut, this); } /** * Open a literal data packet for the passed in File object, returning * an output stream for saving the file contents. *

    * The stream created can be closed off by either calling close() * on the stream or close() on the generator. Closing the returned * stream does not close off the OutputStream parameter out. * * @param out * @param format * @param file * @return OutputStream * @throws IOException */ public OutputStream open( OutputStream out, char format, File file) throws IOException { if (pkOut != null) { throw new IllegalStateException("generator already in open state"); } byte[] encName = Strings.toUTF8ByteArray(file.getName()); pkOut = new BCPGOutputStream(out, PacketTags.LITERAL_DATA, file.length() + 2 + encName.length + 4, oldFormat); writeHeader(pkOut, format, encName, file.lastModified()); return new WrappedGeneratorStream(pkOut, this); } /** * Close the literal data packet - this is equivalent to calling close on the stream * returned by the open() method. * * @throws IOException */ public void close() throws IOException { if (pkOut != null) { pkOut.finish(); pkOut.flush(); pkOut = null; } } } bouncycastle-1.49.orig/src/org/bouncycastle/openpgp/PGPOnePassSignature.java0000644000175000017500000001513311600547450026623 0ustar ebourgebourgpackage org.bouncycastle.openpgp; import java.io.ByteArrayOutputStream; import java.io.IOException; import java.io.OutputStream; import java.security.NoSuchProviderException; import java.security.Provider; import java.security.SignatureException; import org.bouncycastle.bcpg.BCPGInputStream; import org.bouncycastle.bcpg.BCPGOutputStream; import org.bouncycastle.bcpg.OnePassSignaturePacket; import org.bouncycastle.openpgp.operator.PGPContentVerifier; import org.bouncycastle.openpgp.operator.PGPContentVerifierBuilder; import org.bouncycastle.openpgp.operator.PGPContentVerifierBuilderProvider; import org.bouncycastle.openpgp.operator.jcajce.JcaPGPContentVerifierBuilderProvider; /** * A one pass signature object. */ public class PGPOnePassSignature { private OnePassSignaturePacket sigPack; private int signatureType; private PGPContentVerifier verifier; private byte lastb; private OutputStream sigOut; PGPOnePassSignature( BCPGInputStream pIn) throws IOException, PGPException { this((OnePassSignaturePacket)pIn.readPacket()); } PGPOnePassSignature( OnePassSignaturePacket sigPack) throws PGPException { this.sigPack = sigPack; this.signatureType = sigPack.getSignatureType(); } /** * Initialise the signature object for verification. * * @param pubKey * @param provider * @throws NoSuchProviderException * @throws PGPException * @deprecated use init() method. */ public void initVerify( PGPPublicKey pubKey, String provider) throws NoSuchProviderException, PGPException { initVerify(pubKey, PGPUtil.getProvider(provider)); } /** * Initialise the signature object for verification. * * @param pubKey * @param provider * @throws NoSuchProviderException * @throws PGPException * @deprecated use init() method. */ public void initVerify( PGPPublicKey pubKey, Provider provider) throws PGPException { init(new JcaPGPContentVerifierBuilderProvider().setProvider(provider), pubKey); } /** * Initialise the signature object for verification. * * @param verifierBuilderProvider provider for a content verifier builder for the signature type of interest. * @param pubKey the public key to use for verification * @throws PGPException if there's an issue with creating the verifier. */ public void init(PGPContentVerifierBuilderProvider verifierBuilderProvider, PGPPublicKey pubKey) throws PGPException { PGPContentVerifierBuilder verifierBuilder = verifierBuilderProvider.get(sigPack.getKeyAlgorithm(), sigPack.getHashAlgorithm()); verifier = verifierBuilder.build(pubKey); lastb = 0; sigOut = verifier.getOutputStream(); } public void update( byte b) throws SignatureException { if (signatureType == PGPSignature.CANONICAL_TEXT_DOCUMENT) { if (b == '\r') { byteUpdate((byte)'\r'); byteUpdate((byte)'\n'); } else if (b == '\n') { if (lastb != '\r') { byteUpdate((byte)'\r'); byteUpdate((byte)'\n'); } } else { byteUpdate(b); } lastb = b; } else { byteUpdate(b); } } public void update( byte[] bytes) throws SignatureException { if (signatureType == PGPSignature.CANONICAL_TEXT_DOCUMENT) { for (int i = 0; i != bytes.length; i++) { this.update(bytes[i]); } } else { blockUpdate(bytes, 0, bytes.length); } } public void update( byte[] bytes, int off, int length) throws SignatureException { if (signatureType == PGPSignature.CANONICAL_TEXT_DOCUMENT) { int finish = off + length; for (int i = off; i != finish; i++) { this.update(bytes[i]); } } else { blockUpdate(bytes, off, length); } } private void byteUpdate(byte b) throws SignatureException { try { sigOut.write(b); } catch (IOException e) { // TODO: we really should get rid of signature exception next.... throw new SignatureException(e.getMessage()); } } private void blockUpdate(byte[] block, int off, int len) throws SignatureException { try { sigOut.write(block, off, len); } catch (IOException e) { throw new IllegalStateException(e.getMessage()); } } /** * Verify the calculated signature against the passed in PGPSignature. * * @param pgpSig * @return boolean * @throws PGPException * @throws SignatureException */ public boolean verify( PGPSignature pgpSig) throws PGPException, SignatureException { try { sigOut.write(pgpSig.getSignatureTrailer()); sigOut.close(); } catch (IOException e) { throw new PGPException("unable to add trailer: " + e.getMessage(), e); } return verifier.verify(pgpSig.getSignature()); } public long getKeyID() { return sigPack.getKeyID(); } public int getSignatureType() { return sigPack.getSignatureType(); } public int getHashAlgorithm() { return sigPack.getHashAlgorithm(); } public int getKeyAlgorithm() { return sigPack.getKeyAlgorithm(); } public byte[] getEncoded() throws IOException { ByteArrayOutputStream bOut = new ByteArrayOutputStream(); this.encode(bOut); return bOut.toByteArray(); } public void encode( OutputStream outStream) throws IOException { BCPGOutputStream out; if (outStream instanceof BCPGOutputStream) { out = (BCPGOutputStream)outStream; } else { out = new BCPGOutputStream(outStream); } out.writePacket(sigPack); } } bouncycastle-1.49.orig/src/org/bouncycastle/openpgp/PGPException.java0000644000175000017500000000115410472271362025327 0ustar ebourgebourgpackage org.bouncycastle.openpgp; /** * generic exception class for PGP encoding/decoding problems */ public class PGPException extends Exception { Exception underlying; public PGPException( String message) { super(message); } public PGPException( String message, Exception underlying) { super(message); this.underlying = underlying; } public Exception getUnderlyingException() { return underlying; } public Throwable getCause() { return underlying; } } bouncycastle-1.49.orig/src/org/bouncycastle/openpgp/PGPMarker.java0000644000175000017500000000132210262753174024612 0ustar ebourgebourg/* * Created on Mar 6, 2004 * * To change this generated comment go to * Window>Preferences>Java>Code Generation>Code and Comments */ package org.bouncycastle.openpgp; import java.io.IOException; import org.bouncycastle.bcpg.BCPGInputStream; import org.bouncycastle.bcpg.MarkerPacket; /** * a PGP marker packet - in general these should be ignored other than where * the idea is to preserve the original input stream. */ public class PGPMarker { private MarkerPacket p; /** * Default constructor. * * @param in * @throws IOException */ public PGPMarker( BCPGInputStream in) throws IOException { p = (MarkerPacket)in.readPacket(); } } bouncycastle-1.49.orig/src/org/bouncycastle/openpgp/PGPSignatureGenerator.java0000644000175000017500000004133711601026206027176 0ustar ebourgebourgpackage org.bouncycastle.openpgp; import java.io.ByteArrayOutputStream; import java.io.IOException; import java.io.OutputStream; import java.math.BigInteger; import java.security.NoSuchAlgorithmException; import java.security.NoSuchProviderException; import java.security.Provider; import java.security.SecureRandom; import java.security.SignatureException; import java.util.Date; import org.bouncycastle.bcpg.MPInteger; import org.bouncycastle.bcpg.OnePassSignaturePacket; import org.bouncycastle.bcpg.PublicKeyAlgorithmTags; import org.bouncycastle.bcpg.SignaturePacket; import org.bouncycastle.bcpg.SignatureSubpacket; import org.bouncycastle.bcpg.SignatureSubpacketTags; import org.bouncycastle.bcpg.UserAttributeSubpacket; import org.bouncycastle.bcpg.sig.IssuerKeyID; import org.bouncycastle.bcpg.sig.SignatureCreationTime; import org.bouncycastle.openpgp.operator.PGPContentSigner; import org.bouncycastle.openpgp.operator.PGPContentSignerBuilder; import org.bouncycastle.openpgp.operator.jcajce.JcaPGPContentSignerBuilder; import org.bouncycastle.util.Strings; /** * Generator for PGP Signatures. */ public class PGPSignatureGenerator { private SignatureSubpacket[] unhashed = new SignatureSubpacket[0]; private SignatureSubpacket[] hashed = new SignatureSubpacket[0]; private OutputStream sigOut; private PGPContentSignerBuilder contentSignerBuilder; private PGPContentSigner contentSigner; private int sigType; private byte lastb; private int providedKeyAlgorithm = -1; /** * Create a generator for the passed in keyAlgorithm and hashAlgorithm codes. * * @param keyAlgorithm keyAlgorithm to use for signing * @param hashAlgorithm algorithm to use for digest * @param provider provider to use for digest algorithm * @throws NoSuchAlgorithmException * @throws NoSuchProviderException * @throws PGPException * @deprecated use method taking a PGPContentSignerBuilder */ public PGPSignatureGenerator( int keyAlgorithm, int hashAlgorithm, String provider) throws NoSuchAlgorithmException, NoSuchProviderException, PGPException { this(keyAlgorithm, provider, hashAlgorithm, provider); } /** * Create a generator for the passed in keyAlgorithm and hashAlgorithm codes. * * @deprecated use method taking a PGPContentSignerBuilder */ public PGPSignatureGenerator( int keyAlgorithm, int hashAlgorithm, Provider provider) throws NoSuchAlgorithmException, PGPException { this(keyAlgorithm, provider, hashAlgorithm, provider); } /** * Create a generator for the passed in keyAlgorithm and hashAlgorithm codes. * * @param keyAlgorithm keyAlgorithm to use for signing * @param sigProvider provider to use for signature generation * @param hashAlgorithm algorithm to use for digest * @param digProvider provider to use for digest algorithm * @throws NoSuchAlgorithmException * @throws NoSuchProviderException * @throws PGPException * @deprecated use method taking a PGPContentSignerBuilder */ public PGPSignatureGenerator( int keyAlgorithm, String sigProvider, int hashAlgorithm, String digProvider) throws NoSuchAlgorithmException, NoSuchProviderException, PGPException { this(keyAlgorithm, PGPUtil.getProvider(sigProvider), hashAlgorithm, PGPUtil.getProvider(digProvider)); } /** * * @param keyAlgorithm * @param sigProvider * @param hashAlgorithm * @param digProvider * @throws NoSuchAlgorithmException * @throws PGPException * @deprecated use constructor taking PGPContentSignerBuilder. */ public PGPSignatureGenerator( int keyAlgorithm, Provider sigProvider, int hashAlgorithm, Provider digProvider) throws NoSuchAlgorithmException, PGPException { this.providedKeyAlgorithm = keyAlgorithm; this.contentSignerBuilder = new JcaPGPContentSignerBuilder(keyAlgorithm, hashAlgorithm).setProvider(sigProvider).setDigestProvider(digProvider); } /** * Create a signature generator built on the passed in contentSignerBuilder. * * @param contentSignerBuilder builder to produce PGPContentSigner objects for generating signatures. */ public PGPSignatureGenerator( PGPContentSignerBuilder contentSignerBuilder) { this.contentSignerBuilder = contentSignerBuilder; } /** * Initialise the generator for signing. * * @param signatureType * @param key * @throws PGPException * @deprecated use init() method */ public void initSign( int signatureType, PGPPrivateKey key) throws PGPException { contentSigner = contentSignerBuilder.build(signatureType, key); sigOut = contentSigner.getOutputStream(); sigType = contentSigner.getType(); lastb = 0; if (providedKeyAlgorithm >= 0 && providedKeyAlgorithm != contentSigner.getKeyAlgorithm()) { throw new PGPException("key algorithm mismatch"); } } /** * Initialise the generator for signing. * * @param signatureType * @param key * @throws PGPException */ public void init( int signatureType, PGPPrivateKey key) throws PGPException { contentSigner = contentSignerBuilder.build(signatureType, key); sigOut = contentSigner.getOutputStream(); sigType = contentSigner.getType(); lastb = 0; if (providedKeyAlgorithm >= 0 && providedKeyAlgorithm != contentSigner.getKeyAlgorithm()) { throw new PGPException("key algorithm mismatch"); } } /** * Initialise the generator for signing. * * @param signatureType * @param key * @param random * @throws PGPException * @deprecated random parameter now ignored. */ public void initSign( int signatureType, PGPPrivateKey key, SecureRandom random) throws PGPException { initSign(signatureType, key); } public void update( byte b) throws SignatureException { if (sigType == PGPSignature.CANONICAL_TEXT_DOCUMENT) { if (b == '\r') { byteUpdate((byte)'\r'); byteUpdate((byte)'\n'); } else if (b == '\n') { if (lastb != '\r') { byteUpdate((byte)'\r'); byteUpdate((byte)'\n'); } } else { byteUpdate(b); } lastb = b; } else { byteUpdate(b); } } public void update( byte[] b) throws SignatureException { this.update(b, 0, b.length); } public void update( byte[] b, int off, int len) throws SignatureException { if (sigType == PGPSignature.CANONICAL_TEXT_DOCUMENT) { int finish = off + len; for (int i = off; i != finish; i++) { this.update(b[i]); } } else { blockUpdate(b, off, len); } } private void byteUpdate(byte b) throws SignatureException { try { sigOut.write(b); } catch (IOException e) { // TODO: we really should get rid of signature exception next.... throw new SignatureException(e.getMessage()); } } private void blockUpdate(byte[] block, int off, int len) throws SignatureException { try { sigOut.write(block, off, len); } catch (IOException e) { throw new IllegalStateException(e.getMessage()); } } public void setHashedSubpackets( PGPSignatureSubpacketVector hashedPcks) { if (hashedPcks == null) { hashed = new SignatureSubpacket[0]; return; } hashed = hashedPcks.toSubpacketArray(); } public void setUnhashedSubpackets( PGPSignatureSubpacketVector unhashedPcks) { if (unhashedPcks == null) { unhashed = new SignatureSubpacket[0]; return; } unhashed = unhashedPcks.toSubpacketArray(); } /** * Return the one pass header associated with the current signature. * * @param isNested * @return PGPOnePassSignature * @throws PGPException */ public PGPOnePassSignature generateOnePassVersion( boolean isNested) throws PGPException { return new PGPOnePassSignature(new OnePassSignaturePacket(sigType, contentSigner.getHashAlgorithm(), contentSigner.getKeyAlgorithm(), contentSigner.getKeyID(), isNested)); } /** * Return a signature object containing the current signature state. * * @return PGPSignature * @throws PGPException * @throws SignatureException */ public PGPSignature generate() throws PGPException, SignatureException { MPInteger[] sigValues; int version = 4; ByteArrayOutputStream sOut = new ByteArrayOutputStream(); SignatureSubpacket[] hPkts, unhPkts; if (!packetPresent(hashed, SignatureSubpacketTags.CREATION_TIME)) { hPkts = insertSubpacket(hashed, new SignatureCreationTime(false, new Date())); } else { hPkts = hashed; } if (!packetPresent(hashed, SignatureSubpacketTags.ISSUER_KEY_ID) && !packetPresent(unhashed, SignatureSubpacketTags.ISSUER_KEY_ID)) { unhPkts = insertSubpacket(unhashed, new IssuerKeyID(false, contentSigner.getKeyID())); } else { unhPkts = unhashed; } try { sOut.write((byte)version); sOut.write((byte)sigType); sOut.write((byte)contentSigner.getKeyAlgorithm()); sOut.write((byte)contentSigner.getHashAlgorithm()); ByteArrayOutputStream hOut = new ByteArrayOutputStream(); for (int i = 0; i != hPkts.length; i++) { hPkts[i].encode(hOut); } byte[] data = hOut.toByteArray(); sOut.write((byte)(data.length >> 8)); sOut.write((byte)data.length); sOut.write(data); } catch (IOException e) { throw new PGPException("exception encoding hashed data.", e); } byte[] hData = sOut.toByteArray(); sOut.write((byte)version); sOut.write((byte)0xff); sOut.write((byte)(hData.length >> 24)); sOut.write((byte)(hData.length >> 16)); sOut.write((byte)(hData.length >> 8)); sOut.write((byte)(hData.length)); byte[] trailer = sOut.toByteArray(); blockUpdate(trailer, 0, trailer.length); if (contentSigner.getKeyAlgorithm() == PublicKeyAlgorithmTags.RSA_SIGN || contentSigner.getKeyAlgorithm() == PublicKeyAlgorithmTags.RSA_GENERAL) // an RSA signature { sigValues = new MPInteger[1]; sigValues[0] = new MPInteger(new BigInteger(1, contentSigner.getSignature())); } else { sigValues = PGPUtil.dsaSigToMpi(contentSigner.getSignature()); } byte[] digest = contentSigner.getDigest(); byte[] fingerPrint = new byte[2]; fingerPrint[0] = digest[0]; fingerPrint[1] = digest[1]; return new PGPSignature(new SignaturePacket(sigType, contentSigner.getKeyID(), contentSigner.getKeyAlgorithm(), contentSigner.getHashAlgorithm(), hPkts, unhPkts, fingerPrint, sigValues)); } /** * Generate a certification for the passed in id and key. * * @param id the id we are certifying against the public key. * @param pubKey the key we are certifying against the id. * @return the certification. * @throws SignatureException * @throws PGPException */ public PGPSignature generateCertification( String id, PGPPublicKey pubKey) throws SignatureException, PGPException { updateWithPublicKey(pubKey); // // hash in the id // updateWithIdData(0xb4, Strings.toUTF8ByteArray(id)); return this.generate(); } /** * Generate a certification for the passed in userAttributes * @param userAttributes the id we are certifying against the public key. * @param pubKey the key we are certifying against the id. * @return the certification. * @throws SignatureException * @throws PGPException */ public PGPSignature generateCertification( PGPUserAttributeSubpacketVector userAttributes, PGPPublicKey pubKey) throws SignatureException, PGPException { updateWithPublicKey(pubKey); // // hash in the attributes // try { ByteArrayOutputStream bOut = new ByteArrayOutputStream(); UserAttributeSubpacket[] packets = userAttributes.toSubpacketArray(); for (int i = 0; i != packets.length; i++) { packets[i].encode(bOut); } updateWithIdData(0xd1, bOut.toByteArray()); } catch (IOException e) { throw new PGPException("cannot encode subpacket array", e); } return this.generate(); } /** * Generate a certification for the passed in key against the passed in * master key. * * @param masterKey the key we are certifying against. * @param pubKey the key we are certifying. * @return the certification. * @throws SignatureException * @throws PGPException */ public PGPSignature generateCertification( PGPPublicKey masterKey, PGPPublicKey pubKey) throws SignatureException, PGPException { updateWithPublicKey(masterKey); updateWithPublicKey(pubKey); return this.generate(); } /** * Generate a certification, such as a revocation, for the passed in key. * * @param pubKey the key we are certifying. * @return the certification. * @throws SignatureException * @throws PGPException */ public PGPSignature generateCertification( PGPPublicKey pubKey) throws SignatureException, PGPException { updateWithPublicKey(pubKey); return this.generate(); } private byte[] getEncodedPublicKey( PGPPublicKey pubKey) throws PGPException { byte[] keyBytes; try { keyBytes = pubKey.publicPk.getEncodedContents(); } catch (IOException e) { throw new PGPException("exception preparing key.", e); } return keyBytes; } private boolean packetPresent( SignatureSubpacket[] packets, int type) { for (int i = 0; i != packets.length; i++) { if (packets[i].getType() == type) { return true; } } return false; } private SignatureSubpacket[] insertSubpacket( SignatureSubpacket[] packets, SignatureSubpacket subpacket) { SignatureSubpacket[] tmp = new SignatureSubpacket[packets.length + 1]; tmp[0] = subpacket; System.arraycopy(packets, 0, tmp, 1, packets.length); return tmp; } private void updateWithIdData(int header, byte[] idBytes) throws SignatureException { this.update((byte)header); this.update((byte)(idBytes.length >> 24)); this.update((byte)(idBytes.length >> 16)); this.update((byte)(idBytes.length >> 8)); this.update((byte)(idBytes.length)); this.update(idBytes); } private void updateWithPublicKey(PGPPublicKey key) throws PGPException, SignatureException { byte[] keyBytes = getEncodedPublicKey(key); this.update((byte)0x99); this.update((byte)(keyBytes.length >> 8)); this.update((byte)(keyBytes.length)); this.update(keyBytes); } } bouncycastle-1.49.orig/src/org/bouncycastle/openpgp/PGPSecretKeyRing.java0000644000175000017500000003452712145535214026117 0ustar ebourgebourgpackage org.bouncycastle.openpgp; import java.io.ByteArrayInputStream; import java.io.ByteArrayOutputStream; import java.io.IOException; import java.io.InputStream; import java.io.OutputStream; import java.security.NoSuchProviderException; import java.security.Provider; import java.security.SecureRandom; import java.util.ArrayList; import java.util.Collections; import java.util.Iterator; import java.util.List; import org.bouncycastle.bcpg.BCPGInputStream; import org.bouncycastle.bcpg.PacketTags; import org.bouncycastle.bcpg.PublicSubkeyPacket; import org.bouncycastle.bcpg.SecretKeyPacket; import org.bouncycastle.bcpg.SecretSubkeyPacket; import org.bouncycastle.bcpg.TrustPacket; import org.bouncycastle.openpgp.operator.KeyFingerPrintCalculator; import org.bouncycastle.openpgp.operator.PBESecretKeyDecryptor; import org.bouncycastle.openpgp.operator.PBESecretKeyEncryptor; import org.bouncycastle.openpgp.operator.jcajce.JcaKeyFingerprintCalculator; /** * Class to hold a single master secret key and its subkeys. *

    * Often PGP keyring files consist of multiple master keys, if you are trying to process * or construct one of these you should use the PGPSecretKeyRingCollection class. */ public class PGPSecretKeyRing extends PGPKeyRing { List keys; List extraPubKeys; PGPSecretKeyRing(List keys) { this(keys, new ArrayList()); } private PGPSecretKeyRing(List keys, List extraPubKeys) { this.keys = keys; this.extraPubKeys = extraPubKeys; } /** * @deprecated use version that takes KeyFingerprintCalculator */ public PGPSecretKeyRing( byte[] encoding) throws IOException, PGPException { this(new ByteArrayInputStream(encoding)); } public PGPSecretKeyRing( byte[] encoding, KeyFingerPrintCalculator fingerPrintCalculator) throws IOException, PGPException { this(new ByteArrayInputStream(encoding), fingerPrintCalculator); } /** * @deprecated use version that takes KeyFingerprintCalculator */ public PGPSecretKeyRing( InputStream in) throws IOException, PGPException { this(in, new JcaKeyFingerprintCalculator()); } public PGPSecretKeyRing( InputStream in, KeyFingerPrintCalculator fingerPrintCalculator) throws IOException, PGPException { this.keys = new ArrayList(); this.extraPubKeys = new ArrayList(); BCPGInputStream pIn = wrap(in); int initialTag = pIn.nextPacketTag(); if (initialTag != PacketTags.SECRET_KEY && initialTag != PacketTags.SECRET_SUBKEY) { throw new IOException( "secret key ring doesn't start with secret key tag: " + "tag 0x" + Integer.toHexString(initialTag)); } SecretKeyPacket secret = (SecretKeyPacket)pIn.readPacket(); // // ignore GPG comment packets if found. // while (pIn.nextPacketTag() == PacketTags.EXPERIMENTAL_2) { pIn.readPacket(); } TrustPacket trust = readOptionalTrustPacket(pIn); // revocation and direct signatures List keySigs = readSignaturesAndTrust(pIn); List ids = new ArrayList(); List idTrusts = new ArrayList(); List idSigs = new ArrayList(); readUserIDs(pIn, ids, idTrusts, idSigs); keys.add(new PGPSecretKey(secret, new PGPPublicKey(secret.getPublicKeyPacket(), trust, keySigs, ids, idTrusts, idSigs, fingerPrintCalculator))); // Read subkeys while (pIn.nextPacketTag() == PacketTags.SECRET_SUBKEY || pIn.nextPacketTag() == PacketTags.PUBLIC_SUBKEY) { if (pIn.nextPacketTag() == PacketTags.SECRET_SUBKEY) { SecretSubkeyPacket sub = (SecretSubkeyPacket)pIn.readPacket(); // // ignore GPG comment packets if found. // while (pIn.nextPacketTag() == PacketTags.EXPERIMENTAL_2) { pIn.readPacket(); } TrustPacket subTrust = readOptionalTrustPacket(pIn); List sigList = readSignaturesAndTrust(pIn); keys.add(new PGPSecretKey(sub, new PGPPublicKey(sub.getPublicKeyPacket(), subTrust, sigList, fingerPrintCalculator))); } else { PublicSubkeyPacket sub = (PublicSubkeyPacket)pIn.readPacket(); TrustPacket subTrust = readOptionalTrustPacket(pIn); List sigList = readSignaturesAndTrust(pIn); extraPubKeys.add(new PGPPublicKey(sub, subTrust, sigList, fingerPrintCalculator)); } } } /** * Return the public key for the master key. * * @return PGPPublicKey */ public PGPPublicKey getPublicKey() { return ((PGPSecretKey)keys.get(0)).getPublicKey(); } /** * Return the public key referred to by the passed in keyID if it * is present. * * @param keyID * @return PGPPublicKey */ public PGPPublicKey getPublicKey( long keyID) { PGPSecretKey key = getSecretKey(keyID); if (key != null) { return key.getPublicKey(); } for (int i = 0; i != extraPubKeys.size(); i++) { PGPPublicKey k = (PGPPublicKey)keys.get(i); if (keyID == k.getKeyID()) { return k; } } return null; } /** * Return an iterator containing all the public keys. * * @return Iterator */ public Iterator getPublicKeys() { List pubKeys = new ArrayList(); for (Iterator it = getSecretKeys(); it.hasNext();) { pubKeys.add(((PGPSecretKey)it.next()).getPublicKey()); } pubKeys.addAll(extraPubKeys); return Collections.unmodifiableList(pubKeys).iterator(); } /** * Return the master private key. * * @return PGPSecretKey */ public PGPSecretKey getSecretKey() { return ((PGPSecretKey)keys.get(0)); } /** * Return an iterator containing all the secret keys. * * @return Iterator */ public Iterator getSecretKeys() { return Collections.unmodifiableList(keys).iterator(); } public PGPSecretKey getSecretKey( long keyId) { for (int i = 0; i != keys.size(); i++) { PGPSecretKey k = (PGPSecretKey)keys.get(i); if (keyId == k.getKeyID()) { return k; } } return null; } /** * Return an iterator of the public keys in the secret key ring that * have no matching private key. At the moment only personal certificate data * appears in this fashion. * * @return iterator of unattached, or extra, public keys. */ public Iterator getExtraPublicKeys() { return extraPubKeys.iterator(); } public byte[] getEncoded() throws IOException { ByteArrayOutputStream bOut = new ByteArrayOutputStream(); this.encode(bOut); return bOut.toByteArray(); } public void encode( OutputStream outStream) throws IOException { for (int i = 0; i != keys.size(); i++) { PGPSecretKey k = (PGPSecretKey)keys.get(i); k.encode(outStream); } for (int i = 0; i != extraPubKeys.size(); i++) { PGPPublicKey k = (PGPPublicKey)extraPubKeys.get(i); k.encode(outStream); } } /** * Replace the public key set on the secret ring with the corresponding key off the public ring. * * @param secretRing secret ring to be changed. * @param publicRing public ring containing the new public key set. */ public static PGPSecretKeyRing replacePublicKeys(PGPSecretKeyRing secretRing, PGPPublicKeyRing publicRing) { List newList = new ArrayList(secretRing.keys.size()); for (Iterator it = secretRing.keys.iterator(); it.hasNext();) { PGPSecretKey sk = (PGPSecretKey)it.next(); PGPPublicKey pk = publicRing.getPublicKey(sk.getKeyID()); newList.add(PGPSecretKey.replacePublicKey(sk, pk)); } return new PGPSecretKeyRing(newList); } /** * Return a copy of the passed in secret key ring, with the master key and sub keys encrypted * using a new password and the passed in algorithm. * * @param ring the PGPSecretKeyRing to be copied. * @param oldPassPhrase the current password for key. * @param newPassPhrase the new password for the key. * @param newEncAlgorithm the algorithm to be used for the encryption. * @param rand source of randomness. * @param provider name of the provider to use * @deprecated use version taking PBESecretKeyEncryptor/PBESecretKeyDecryptor */ public static PGPSecretKeyRing copyWithNewPassword( PGPSecretKeyRing ring, char[] oldPassPhrase, char[] newPassPhrase, int newEncAlgorithm, SecureRandom rand, String provider) throws PGPException, NoSuchProviderException { return copyWithNewPassword(ring, oldPassPhrase, newPassPhrase, newEncAlgorithm, rand, PGPUtil.getProvider(provider)); } /** * Return a copy of the passed in secret key ring, with the master key and sub keys encrypted * using a new password and the passed in algorithm. * * @param ring the PGPSecretKeyRing to be copied. * @param oldPassPhrase the current password for key. * @param newPassPhrase the new password for the key. * @param newEncAlgorithm the algorithm to be used for the encryption. * @param rand source of randomness. * @param provider provider to use * @deprecated use version taking PBESecretKeyEncryptor/PBESecretKeyDecryptor */ public static PGPSecretKeyRing copyWithNewPassword( PGPSecretKeyRing ring, char[] oldPassPhrase, char[] newPassPhrase, int newEncAlgorithm, SecureRandom rand, Provider provider) throws PGPException { List newKeys = new ArrayList(ring.keys.size()); for (Iterator keys = ring.getSecretKeys(); keys.hasNext();) { newKeys.add(PGPSecretKey.copyWithNewPassword((PGPSecretKey)keys.next(), oldPassPhrase, newPassPhrase, newEncAlgorithm, rand, provider)); } return new PGPSecretKeyRing(newKeys, ring.extraPubKeys); } /** * Return a copy of the passed in secret key ring, with the private keys (where present) associated with the master key and sub keys * are encrypted using a new password and the passed in algorithm. * * @param ring the PGPSecretKeyRing to be copied. * @param oldKeyDecryptor the current decryptor based on the current password for key. * @param newKeyEncryptor a new encryptor based on a new password for encrypting the secret key material. * @return the updated key ring. */ public static PGPSecretKeyRing copyWithNewPassword( PGPSecretKeyRing ring, PBESecretKeyDecryptor oldKeyDecryptor, PBESecretKeyEncryptor newKeyEncryptor) throws PGPException { List newKeys = new ArrayList(ring.keys.size()); for (Iterator keys = ring.getSecretKeys(); keys.hasNext();) { PGPSecretKey key = (PGPSecretKey)keys.next(); if (key.isPrivateKeyEmpty()) { newKeys.add(key); } else { newKeys.add(PGPSecretKey.copyWithNewPassword(key, oldKeyDecryptor, newKeyEncryptor)); } } return new PGPSecretKeyRing(newKeys, ring.extraPubKeys); } /** * Returns a new key ring with the secret key passed in either added or * replacing an existing one with the same key ID. * * @param secRing the secret key ring to be modified. * @param secKey the secret key to be added. * @return a new secret key ring. */ public static PGPSecretKeyRing insertSecretKey( PGPSecretKeyRing secRing, PGPSecretKey secKey) { List keys = new ArrayList(secRing.keys); boolean found = false; boolean masterFound = false; for (int i = 0; i != keys.size();i++) { PGPSecretKey key = (PGPSecretKey)keys.get(i); if (key.getKeyID() == secKey.getKeyID()) { found = true; keys.set(i, secKey); } if (key.isMasterKey()) { masterFound = true; } } if (!found) { if (secKey.isMasterKey()) { if (masterFound) { throw new IllegalArgumentException("cannot add a master key to a ring that already has one"); } keys.add(0, secKey); } else { keys.add(secKey); } } return new PGPSecretKeyRing(keys, secRing.extraPubKeys); } /** * Returns a new key ring with the secret key passed in removed from the * key ring. * * @param secRing the secret key ring to be modified. * @param secKey the secret key to be removed. * @return a new secret key ring, or null if secKey is not found. */ public static PGPSecretKeyRing removeSecretKey( PGPSecretKeyRing secRing, PGPSecretKey secKey) { List keys = new ArrayList(secRing.keys); boolean found = false; for (int i = 0; i < keys.size();i++) { PGPSecretKey key = (PGPSecretKey)keys.get(i); if (key.getKeyID() == secKey.getKeyID()) { found = true; keys.remove(i); } } if (!found) { return null; } return new PGPSecretKeyRing(keys, secRing.extraPubKeys); } } bouncycastle-1.49.orig/src/org/bouncycastle/openpgp/PGPSignature.java0000644000175000017500000003570711636750113025344 0ustar ebourgebourgpackage org.bouncycastle.openpgp; import java.io.ByteArrayOutputStream; import java.io.IOException; import java.io.OutputStream; import java.security.NoSuchProviderException; import java.security.Provider; import java.security.SignatureException; import java.util.Date; import org.bouncycastle.asn1.ASN1EncodableVector; import org.bouncycastle.asn1.DERInteger; import org.bouncycastle.asn1.DERSequence; import org.bouncycastle.bcpg.BCPGInputStream; import org.bouncycastle.bcpg.BCPGOutputStream; import org.bouncycastle.bcpg.MPInteger; import org.bouncycastle.bcpg.SignaturePacket; import org.bouncycastle.bcpg.SignatureSubpacket; import org.bouncycastle.bcpg.TrustPacket; import org.bouncycastle.bcpg.UserAttributeSubpacket; import org.bouncycastle.openpgp.operator.PGPContentVerifier; import org.bouncycastle.openpgp.operator.PGPContentVerifierBuilder; import org.bouncycastle.openpgp.operator.PGPContentVerifierBuilderProvider; import org.bouncycastle.openpgp.operator.jcajce.JcaPGPContentVerifierBuilderProvider; import org.bouncycastle.util.BigIntegers; import org.bouncycastle.util.Strings; /** *A PGP signature object. */ public class PGPSignature { public static final int BINARY_DOCUMENT = 0x00; public static final int CANONICAL_TEXT_DOCUMENT = 0x01; public static final int STAND_ALONE = 0x02; public static final int DEFAULT_CERTIFICATION = 0x10; public static final int NO_CERTIFICATION = 0x11; public static final int CASUAL_CERTIFICATION = 0x12; public static final int POSITIVE_CERTIFICATION = 0x13; public static final int SUBKEY_BINDING = 0x18; public static final int PRIMARYKEY_BINDING = 0x19; public static final int DIRECT_KEY = 0x1f; public static final int KEY_REVOCATION = 0x20; public static final int SUBKEY_REVOCATION = 0x28; public static final int CERTIFICATION_REVOCATION = 0x30; public static final int TIMESTAMP = 0x40; private SignaturePacket sigPck; private int signatureType; private TrustPacket trustPck; private PGPContentVerifier verifier; private byte lastb; private OutputStream sigOut; PGPSignature( BCPGInputStream pIn) throws IOException, PGPException { this((SignaturePacket)pIn.readPacket()); } PGPSignature( SignaturePacket sigPacket) throws PGPException { sigPck = sigPacket; signatureType = sigPck.getSignatureType(); trustPck = null; } PGPSignature( SignaturePacket sigPacket, TrustPacket trustPacket) throws PGPException { this(sigPacket); this.trustPck = trustPacket; } /** * Return the OpenPGP version number for this signature. * * @return signature version number. */ public int getVersion() { return sigPck.getVersion(); } /** * Return the key algorithm associated with this signature. * @return signature key algorithm. */ public int getKeyAlgorithm() { return sigPck.getKeyAlgorithm(); } /** * Return the hash algorithm associated with this signature. * @return signature hash algorithm. */ public int getHashAlgorithm() { return sigPck.getHashAlgorithm(); } /** * @deprecated use init(PGPContentVerifierBuilderProvider, PGPPublicKey) */ public void initVerify( PGPPublicKey pubKey, String provider) throws NoSuchProviderException, PGPException { initVerify(pubKey, PGPUtil.getProvider(provider)); } /** * @deprecated use init(PGPContentVerifierBuilderProvider, PGPPublicKey) */ public void initVerify( PGPPublicKey pubKey, Provider provider) throws PGPException { init(new JcaPGPContentVerifierBuilderProvider().setProvider(provider), pubKey); } public void init(PGPContentVerifierBuilderProvider verifierBuilderProvider, PGPPublicKey pubKey) throws PGPException { PGPContentVerifierBuilder verifierBuilder = verifierBuilderProvider.get(sigPck.getKeyAlgorithm(), sigPck.getHashAlgorithm()); verifier = verifierBuilder.build(pubKey); lastb = 0; sigOut = verifier.getOutputStream(); } public void update( byte b) throws SignatureException { if (signatureType == PGPSignature.CANONICAL_TEXT_DOCUMENT) { if (b == '\r') { byteUpdate((byte)'\r'); byteUpdate((byte)'\n'); } else if (b == '\n') { if (lastb != '\r') { byteUpdate((byte)'\r'); byteUpdate((byte)'\n'); } } else { byteUpdate(b); } lastb = b; } else { byteUpdate(b); } } public void update( byte[] bytes) throws SignatureException { this.update(bytes, 0, bytes.length); } public void update( byte[] bytes, int off, int length) throws SignatureException { if (signatureType == PGPSignature.CANONICAL_TEXT_DOCUMENT) { int finish = off + length; for (int i = off; i != finish; i++) { this.update(bytes[i]); } } else { blockUpdate(bytes, off, length); } } private void byteUpdate(byte b) throws SignatureException { try { sigOut.write(b); } catch (IOException e) { // TODO: we really should get rid of signature exception next.... throw new SignatureException(e.getMessage()); } } private void blockUpdate(byte[] block, int off, int len) throws SignatureException { try { sigOut.write(block, off, len); } catch (IOException e) { throw new IllegalStateException(e.getMessage()); } } public boolean verify() throws PGPException, SignatureException { try { sigOut.write(this.getSignatureTrailer()); sigOut.close(); } catch (IOException e) { throw new SignatureException(e.getMessage()); } return verifier.verify(this.getSignature()); } private void updateWithIdData(int header, byte[] idBytes) throws SignatureException { this.update((byte)header); this.update((byte)(idBytes.length >> 24)); this.update((byte)(idBytes.length >> 16)); this.update((byte)(idBytes.length >> 8)); this.update((byte)(idBytes.length)); this.update(idBytes); } private void updateWithPublicKey(PGPPublicKey key) throws PGPException, SignatureException { byte[] keyBytes = getEncodedPublicKey(key); this.update((byte)0x99); this.update((byte)(keyBytes.length >> 8)); this.update((byte)(keyBytes.length)); this.update(keyBytes); } /** * Verify the signature as certifying the passed in public key as associated * with the passed in user attributes. * * @param userAttributes user attributes the key was stored under * @param key the key to be verified. * @return true if the signature matches, false otherwise. * @throws PGPException * @throws SignatureException */ public boolean verifyCertification( PGPUserAttributeSubpacketVector userAttributes, PGPPublicKey key) throws PGPException, SignatureException { if (verifier == null) { throw new PGPException("PGPSignature not initialised - call init()."); } updateWithPublicKey(key); // // hash in the userAttributes // try { ByteArrayOutputStream bOut = new ByteArrayOutputStream(); UserAttributeSubpacket[] packets = userAttributes.toSubpacketArray(); for (int i = 0; i != packets.length; i++) { packets[i].encode(bOut); } updateWithIdData(0xd1, bOut.toByteArray()); } catch (IOException e) { throw new PGPException("cannot encode subpacket array", e); } addTrailer(); return verifier.verify(this.getSignature()); } /** * Verify the signature as certifying the passed in public key as associated * with the passed in id. * * @param id id the key was stored under * @param key the key to be verified. * @return true if the signature matches, false otherwise. * @throws PGPException * @throws SignatureException */ public boolean verifyCertification( String id, PGPPublicKey key) throws PGPException, SignatureException { if (verifier == null) { throw new PGPException("PGPSignature not initialised - call init()."); } updateWithPublicKey(key); // // hash in the id // updateWithIdData(0xb4, Strings.toUTF8ByteArray(id)); addTrailer(); return verifier.verify(this.getSignature()); } /** * Verify a certification for the passed in key against the passed in * master key. * * @param masterKey the key we are verifying against. * @param pubKey the key we are verifying. * @return true if the certification is valid, false otherwise. * @throws SignatureException * @throws PGPException */ public boolean verifyCertification( PGPPublicKey masterKey, PGPPublicKey pubKey) throws SignatureException, PGPException { if (verifier == null) { throw new PGPException("PGPSignature not initialised - call init()."); } updateWithPublicKey(masterKey); updateWithPublicKey(pubKey); addTrailer(); return verifier.verify(this.getSignature()); } private void addTrailer() throws SignatureException { try { sigOut.write(sigPck.getSignatureTrailer()); sigOut.close(); } catch (IOException e) { throw new SignatureException(e.getMessage()); } } /** * Verify a key certification, such as a revocation, for the passed in key. * * @param pubKey the key we are checking. * @return true if the certification is valid, false otherwise. * @throws SignatureException * @throws PGPException */ public boolean verifyCertification( PGPPublicKey pubKey) throws SignatureException, PGPException { if (verifier == null) { throw new PGPException("PGPSignature not initialised - call init()."); } if (this.getSignatureType() != KEY_REVOCATION && this.getSignatureType() != SUBKEY_REVOCATION) { throw new PGPException("signature is not a key signature"); } updateWithPublicKey(pubKey); addTrailer(); return verifier.verify(this.getSignature()); } public int getSignatureType() { return sigPck.getSignatureType(); } /** * Return the id of the key that created the signature. * @return keyID of the signatures corresponding key. */ public long getKeyID() { return sigPck.getKeyID(); } /** * Return the creation time of the signature. * * @return the signature creation time. */ public Date getCreationTime() { return new Date(sigPck.getCreationTime()); } public byte[] getSignatureTrailer() { return sigPck.getSignatureTrailer(); } /** * Return true if the signature has either hashed or unhashed subpackets. * * @return true if either hashed or unhashed subpackets are present, false otherwise. */ public boolean hasSubpackets() { return sigPck.getHashedSubPackets() != null || sigPck.getUnhashedSubPackets() != null; } public PGPSignatureSubpacketVector getHashedSubPackets() { return createSubpacketVector(sigPck.getHashedSubPackets()); } public PGPSignatureSubpacketVector getUnhashedSubPackets() { return createSubpacketVector(sigPck.getUnhashedSubPackets()); } private PGPSignatureSubpacketVector createSubpacketVector(SignatureSubpacket[] pcks) { if (pcks != null) { return new PGPSignatureSubpacketVector(pcks); } return null; } public byte[] getSignature() throws PGPException { MPInteger[] sigValues = sigPck.getSignature(); byte[] signature; if (sigValues != null) { if (sigValues.length == 1) // an RSA signature { signature = BigIntegers.asUnsignedByteArray(sigValues[0].getValue()); } else { try { ASN1EncodableVector v = new ASN1EncodableVector(); v.add(new DERInteger(sigValues[0].getValue())); v.add(new DERInteger(sigValues[1].getValue())); signature = new DERSequence(v).getEncoded(); } catch (IOException e) { throw new PGPException("exception encoding DSA sig.", e); } } } else { signature = sigPck.getSignatureBytes(); } return signature; } public byte[] getEncoded() throws IOException { ByteArrayOutputStream bOut = new ByteArrayOutputStream(); this.encode(bOut); return bOut.toByteArray(); } public void encode( OutputStream outStream) throws IOException { BCPGOutputStream out; if (outStream instanceof BCPGOutputStream) { out = (BCPGOutputStream)outStream; } else { out = new BCPGOutputStream(outStream); } out.writePacket(sigPck); if (trustPck != null) { out.writePacket(trustPck); } } private byte[] getEncodedPublicKey( PGPPublicKey pubKey) throws PGPException { byte[] keyBytes; try { keyBytes = pubKey.publicPk.getEncodedContents(); } catch (IOException e) { throw new PGPException("exception preparing key.", e); } return keyBytes; } } bouncycastle-1.49.orig/src/org/bouncycastle/openpgp/PGPPublicKeyEncryptedData.java0000644000175000017500000002113611576524035027736 0ustar ebourgebourgpackage org.bouncycastle.openpgp; import java.io.EOFException; import java.io.InputStream; import java.security.NoSuchProviderException; import java.security.Provider; import org.bouncycastle.bcpg.BCPGInputStream; import org.bouncycastle.bcpg.InputStreamPacket; import org.bouncycastle.bcpg.PublicKeyEncSessionPacket; import org.bouncycastle.bcpg.SymmetricEncIntegrityPacket; import org.bouncycastle.bcpg.SymmetricKeyAlgorithmTags; import org.bouncycastle.openpgp.operator.PGPDataDecryptor; import org.bouncycastle.openpgp.operator.PublicKeyDataDecryptorFactory; import org.bouncycastle.openpgp.operator.jcajce.JcePublicKeyDataDecryptorFactoryBuilder; import org.bouncycastle.util.io.TeeInputStream; /** * A public key encrypted data object. */ public class PGPPublicKeyEncryptedData extends PGPEncryptedData { PublicKeyEncSessionPacket keyData; PGPPublicKeyEncryptedData( PublicKeyEncSessionPacket keyData, InputStreamPacket encData) { super(encData); this.keyData = keyData; } private boolean confirmCheckSum( byte[] sessionInfo) { int check = 0; for (int i = 1; i != sessionInfo.length - 2; i++) { check += sessionInfo[i] & 0xff; } return (sessionInfo[sessionInfo.length - 2] == (byte)(check >> 8)) && (sessionInfo[sessionInfo.length - 1] == (byte)(check)); } /** * Return the keyID for the key used to encrypt the data. * * @return long */ public long getKeyID() { return keyData.getKeyID(); } /** * Return the algorithm code for the symmetric algorithm used to encrypt the data. * * @return integer algorithm code * @deprecated use the method taking a PublicKeyDataDecryptorFactory */ public int getSymmetricAlgorithm( PGPPrivateKey privKey, String provider) throws PGPException, NoSuchProviderException { return getSymmetricAlgorithm(privKey, PGPUtil.getProvider(provider)); } /** * * @deprecated use the method taking a PublicKeyDataDecryptorFactory */ public int getSymmetricAlgorithm( PGPPrivateKey privKey, Provider provider) throws PGPException, NoSuchProviderException { return getSymmetricAlgorithm(new JcePublicKeyDataDecryptorFactoryBuilder().setProvider(provider).setContentProvider(provider).build(privKey)); } /** * Return the symmetric key algorithm required to decrypt the data protected by this object. * * @param dataDecryptorFactory decryptor factory to use to recover the session data. * @return the integer encryption algorithm code. * @throws PGPException if the session data cannot be recovered. */ public int getSymmetricAlgorithm( PublicKeyDataDecryptorFactory dataDecryptorFactory) throws PGPException { byte[] plain = dataDecryptorFactory.recoverSessionData(keyData.getAlgorithm(), keyData.getEncSessionKey()); return plain[0]; } /** * Return the decrypted data stream for the packet. * * @param privKey private key to use * @param provider provider to use for private key and symmetric key decryption. * @return InputStream * @throws PGPException * @throws NoSuchProviderException * @deprecated use method that takes a PublicKeyDataDecryptorFactory */ public InputStream getDataStream( PGPPrivateKey privKey, String provider) throws PGPException, NoSuchProviderException { return getDataStream(privKey, provider, provider); } /** * * @param privKey * @param provider * @return * @throws PGPException * @deprecated use method that takes a PublicKeyDataDecryptorFactory */ public InputStream getDataStream( PGPPrivateKey privKey, Provider provider) throws PGPException { return getDataStream(privKey, provider, provider); } /** * Return the decrypted data stream for the packet. * * @param privKey private key to use. * @param asymProvider asymetric provider to use with private key. * @param provider provider to use for symmetric algorithm. * @return InputStream * @throws PGPException * @throws NoSuchProviderException * @deprecated use method that takes a PublicKeyDataDecryptorFactory */ public InputStream getDataStream( PGPPrivateKey privKey, String asymProvider, String provider) throws PGPException, NoSuchProviderException { return getDataStream(privKey, PGPUtil.getProvider(asymProvider), PGPUtil.getProvider(provider)); } /** * @deprecated use method that takes a PublicKeyDataDecryptorFactory */ public InputStream getDataStream( PGPPrivateKey privKey, Provider asymProvider, Provider provider) throws PGPException { return getDataStream(new JcePublicKeyDataDecryptorFactoryBuilder().setProvider(asymProvider).setContentProvider(provider).build(privKey)); } /** * Open an input stream which will provide the decrypted data protected by this object. * * @param dataDecryptorFactory decryptor factory to use to recover the session data and provide the stream. * @return the resulting input stream * @throws PGPException if the session data cannot be recovered or the stream cannot be created. */ public InputStream getDataStream( PublicKeyDataDecryptorFactory dataDecryptorFactory) throws PGPException { byte[] sessionData = dataDecryptorFactory.recoverSessionData(keyData.getAlgorithm(), keyData.getEncSessionKey()); if (!confirmCheckSum(sessionData)) { throw new PGPKeyValidationException("key checksum failed"); } if (sessionData[0] != SymmetricKeyAlgorithmTags.NULL) { try { boolean withIntegrityPacket = encData instanceof SymmetricEncIntegrityPacket; byte[] sessionKey = new byte[sessionData.length - 3]; System.arraycopy(sessionData, 1, sessionKey, 0, sessionKey.length); PGPDataDecryptor dataDecryptor = dataDecryptorFactory.createDataDecryptor(withIntegrityPacket, sessionData[0] & 0xff, sessionKey); encStream = new BCPGInputStream(dataDecryptor.getInputStream(encData.getInputStream())); if (withIntegrityPacket) { truncStream = new TruncatedStream(encStream); integrityCalculator = dataDecryptor.getIntegrityCalculator(); encStream = new TeeInputStream(truncStream, integrityCalculator.getOutputStream()); } byte[] iv = new byte[dataDecryptor.getBlockSize()]; for (int i = 0; i != iv.length; i++) { int ch = encStream.read(); if (ch < 0) { throw new EOFException("unexpected end of stream."); } iv[i] = (byte)ch; } int v1 = encStream.read(); int v2 = encStream.read(); if (v1 < 0 || v2 < 0) { throw new EOFException("unexpected end of stream."); } // // some versions of PGP appear to produce 0 for the extra // bytes rather than repeating the two previous bytes // /* * Commented out in the light of the oracle attack. if (iv[iv.length - 2] != (byte)v1 && v1 != 0) { throw new PGPDataValidationException("data check failed."); } if (iv[iv.length - 1] != (byte)v2 && v2 != 0) { throw new PGPDataValidationException("data check failed."); } */ return encStream; } catch (PGPException e) { throw e; } catch (Exception e) { throw new PGPException("Exception starting decryption", e); } } else { return encData.getInputStream(); } } } bouncycastle-1.49.orig/src/org/bouncycastle/openpgp/PGPEncryptedDataList.java0000644000175000017500000000352510324400070026742 0ustar ebourgebourgpackage org.bouncycastle.openpgp; import java.io.IOException; import java.util.ArrayList; import java.util.Iterator; import java.util.List; import org.bouncycastle.bcpg.BCPGInputStream; import org.bouncycastle.bcpg.InputStreamPacket; import org.bouncycastle.bcpg.PacketTags; import org.bouncycastle.bcpg.PublicKeyEncSessionPacket; import org.bouncycastle.bcpg.SymmetricKeyEncSessionPacket; /** * A holder for a list of PGP encryption method packets. */ public class PGPEncryptedDataList { List list = new ArrayList(); InputStreamPacket data; public PGPEncryptedDataList( BCPGInputStream pIn) throws IOException { while (pIn.nextPacketTag() == PacketTags.PUBLIC_KEY_ENC_SESSION || pIn.nextPacketTag() == PacketTags.SYMMETRIC_KEY_ENC_SESSION) { list.add(pIn.readPacket()); } data = (InputStreamPacket)pIn.readPacket(); for (int i = 0; i != list.size(); i++) { if (list.get(i) instanceof SymmetricKeyEncSessionPacket) { list.set(i, new PGPPBEEncryptedData((SymmetricKeyEncSessionPacket)list.get(i), data)); } else { list.set(i, new PGPPublicKeyEncryptedData((PublicKeyEncSessionPacket)list.get(i), data)); } } } public Object get( int index) { return list.get(index); } public int size() { return list.size(); } public boolean isEmpty() { return list.isEmpty(); } /** * @deprecated misspelt - use getEncryptedDataObjects() */ public Iterator getEncyptedDataObjects() { return list.iterator(); } public Iterator getEncryptedDataObjects() { return list.iterator(); } } bouncycastle-1.49.orig/src/org/bouncycastle/openpgp/PGPDataValidationException.java0000644000175000017500000000051510262753174030137 0ustar ebourgebourgpackage org.bouncycastle.openpgp; /** * Thrown if the iv at the start of a data stream indicates the wrong key * is being used. */ public class PGPDataValidationException extends PGPException { /** * @param message */ public PGPDataValidationException(String message) { super(message); } } bouncycastle-1.49.orig/src/org/bouncycastle/openpgp/PGPKeyFlags.java0000644000175000017500000000141710262753174025103 0ustar ebourgebourgpackage org.bouncycastle.openpgp; /** * key flag values for the KeyFlags subpacket. */ public interface PGPKeyFlags { public static final int CAN_CERTIFY = 0x01; // This key may be used to certify other keys. public static final int CAN_SIGN = 0x02; // This key may be used to sign data. public static final int CAN_ENCRYPT_COMMS = 0x04; // This key may be used to encrypt communications. public static final int CAN_ENCRYPT_STORAGE = 0x08; // This key may be used to encrypt storage. public static final int MAYBE_SPLIT = 0x10; // The private component of this key may have been split by a secret-sharing mechanism. public static final int MAYBE_SHARED = 0x80; // The private component of this key may be in the possession of more than one person. } bouncycastle-1.49.orig/src/org/bouncycastle/openpgp/PGPSignatureSubpacketGenerator.java0000644000175000017500000001404611605460221031040 0ustar ebourgebourgpackage org.bouncycastle.openpgp; import java.io.IOException; import java.util.ArrayList; import java.util.Date; import java.util.List; import org.bouncycastle.bcpg.SignatureSubpacket; import org.bouncycastle.bcpg.SignatureSubpacketTags; import org.bouncycastle.bcpg.sig.EmbeddedSignature; import org.bouncycastle.bcpg.sig.Exportable; import org.bouncycastle.bcpg.sig.Features; import org.bouncycastle.bcpg.sig.IssuerKeyID; import org.bouncycastle.bcpg.sig.KeyExpirationTime; import org.bouncycastle.bcpg.sig.KeyFlags; import org.bouncycastle.bcpg.sig.NotationData; import org.bouncycastle.bcpg.sig.PreferredAlgorithms; import org.bouncycastle.bcpg.sig.PrimaryUserID; import org.bouncycastle.bcpg.sig.Revocable; import org.bouncycastle.bcpg.sig.RevocationKey; import org.bouncycastle.bcpg.sig.RevocationKeyTags; import org.bouncycastle.bcpg.sig.RevocationReason; import org.bouncycastle.bcpg.sig.SignatureCreationTime; import org.bouncycastle.bcpg.sig.SignatureExpirationTime; import org.bouncycastle.bcpg.sig.SignerUserID; import org.bouncycastle.bcpg.sig.TrustSignature; /** * Generator for signature subpackets. */ public class PGPSignatureSubpacketGenerator { List list = new ArrayList(); public PGPSignatureSubpacketGenerator() { } public void setRevocable(boolean isCritical, boolean isRevocable) { list.add(new Revocable(isCritical, isRevocable)); } public void setExportable(boolean isCritical, boolean isExportable) { list.add(new Exportable(isCritical, isExportable)); } public void setFeature(boolean isCritical, byte feature) { list.add(new Features(isCritical, feature)); } /** * Add a TrustSignature packet to the signature. The values for depth and trust are * largely installation dependent but there are some guidelines in RFC 4880 - * 5.2.3.13. * * @param isCritical true if the packet is critical. * @param depth depth level. * @param trustAmount trust amount. */ public void setTrust(boolean isCritical, int depth, int trustAmount) { list.add(new TrustSignature(isCritical, depth, trustAmount)); } /** * Set the number of seconds a key is valid for after the time of its creation. A * value of zero means the key never expires. * * @param isCritical true if should be treated as critical, false otherwise. * @param seconds */ public void setKeyExpirationTime(boolean isCritical, long seconds) { list.add(new KeyExpirationTime(isCritical, seconds)); } /** * Set the number of seconds a signature is valid for after the time of its creation. * A value of zero means the signature never expires. * * @param isCritical true if should be treated as critical, false otherwise. * @param seconds */ public void setSignatureExpirationTime(boolean isCritical, long seconds) { list.add(new SignatureExpirationTime(isCritical, seconds)); } /** * Set the creation time for the signature. *

    * Note: this overrides the generation of a creation time when the signature is * generated. */ public void setSignatureCreationTime(boolean isCritical, Date date) { list.add(new SignatureCreationTime(isCritical, date)); } public void setPreferredHashAlgorithms(boolean isCritical, int[] algorithms) { list.add(new PreferredAlgorithms(SignatureSubpacketTags.PREFERRED_HASH_ALGS, isCritical, algorithms)); } public void setPreferredSymmetricAlgorithms(boolean isCritical, int[] algorithms) { list.add(new PreferredAlgorithms(SignatureSubpacketTags.PREFERRED_SYM_ALGS, isCritical, algorithms)); } public void setPreferredCompressionAlgorithms(boolean isCritical, int[] algorithms) { list.add(new PreferredAlgorithms(SignatureSubpacketTags.PREFERRED_COMP_ALGS, isCritical, algorithms)); } public void setKeyFlags(boolean isCritical, int flags) { list.add(new KeyFlags(isCritical, flags)); } public void setSignerUserID(boolean isCritical, String userID) { if (userID == null) { throw new IllegalArgumentException("attempt to set null SignerUserID"); } list.add(new SignerUserID(isCritical, userID)); } public void setEmbeddedSignature(boolean isCritical, PGPSignature pgpSignature) throws IOException { byte[] sig = pgpSignature.getEncoded(); byte[] data; if (sig.length - 1 > 256) { data = new byte[sig.length - 3]; } else { data = new byte[sig.length - 2]; } System.arraycopy(sig, sig.length - data.length, data, 0, data.length); list.add(new EmbeddedSignature(isCritical, data)); } public void setPrimaryUserID(boolean isCritical, boolean isPrimaryUserID) { list.add(new PrimaryUserID(isCritical, isPrimaryUserID)); } public void setNotationData(boolean isCritical, boolean isHumanReadable, String notationName, String notationValue) { list.add(new NotationData(isCritical, isHumanReadable, notationName, notationValue)); } /** * Sets revocation reason sub packet */ public void setRevocationReason(boolean isCritical, byte reason, String description) { list.add(new RevocationReason(isCritical, reason, description)); } /** * Sets revocation key sub packet */ public void setRevocationKey(boolean isCritical, int keyAlgorithm, byte[] fingerprint) { list.add(new RevocationKey(isCritical, RevocationKeyTags.CLASS_DEFAULT, keyAlgorithm, fingerprint)); } /** * Sets issuer key sub packe */ public void setIssuerKeyID(boolean isCritical, long keyID) { list.add(new IssuerKeyID(isCritical, keyID)); } public PGPSignatureSubpacketVector generate() { return new PGPSignatureSubpacketVector( (SignatureSubpacket[])list.toArray(new SignatureSubpacket[list.size()])); } } bouncycastle-1.49.orig/src/org/bouncycastle/openpgp/PGPPrivateKey.java0000644000175000017500000000762512112270320025447 0ustar ebourgebourgpackage org.bouncycastle.openpgp; import java.security.PrivateKey; import java.security.interfaces.DSAPrivateKey; import java.security.interfaces.RSAPrivateCrtKey; import org.bouncycastle.bcpg.BCPGKey; import org.bouncycastle.bcpg.DSASecretBCPGKey; import org.bouncycastle.bcpg.ElGamalSecretBCPGKey; import org.bouncycastle.bcpg.PublicKeyPacket; import org.bouncycastle.bcpg.RSASecretBCPGKey; import org.bouncycastle.jce.interfaces.ElGamalPrivateKey; import org.bouncycastle.openpgp.operator.jcajce.JcaPGPKeyConverter; /** * general class to contain a private key for use with other openPGP * objects. */ public class PGPPrivateKey { private long keyID; private PrivateKey privateKey; private PublicKeyPacket publicKeyPacket; private BCPGKey privateKeyDataPacket; /** * Create a PGPPrivateKey from a regular private key and the keyID of its associated * public key. * * @param privateKey private key tu use. * @param keyID keyID of the corresponding public key. * @deprecated use JcaPGPKeyConverter */ public PGPPrivateKey( PrivateKey privateKey, long keyID) { this.privateKey = privateKey; this.keyID = keyID; if (privateKey instanceof RSAPrivateCrtKey) { RSAPrivateCrtKey rsK = (RSAPrivateCrtKey)privateKey; privateKeyDataPacket = new RSASecretBCPGKey(rsK.getPrivateExponent(), rsK.getPrimeP(), rsK.getPrimeQ()); } else if (privateKey instanceof DSAPrivateKey) { DSAPrivateKey dsK = (DSAPrivateKey)privateKey; privateKeyDataPacket = new DSASecretBCPGKey(dsK.getX()); } else if (privateKey instanceof ElGamalPrivateKey) { ElGamalPrivateKey esK = (ElGamalPrivateKey)privateKey; privateKeyDataPacket = new ElGamalSecretBCPGKey(esK.getX()); } else { throw new IllegalArgumentException("unknown key class"); } } /** * Base constructor. * * Create a PGPPrivateKey from a keyID and the associated public/private data packets needed * to fully describe it. * * @param keyID keyID associated with the public key. * @param publicKeyPacket the public key data packet to be associated with this private key. * @param privateKeyDataPacket the private key data packet to be associate with this private key. */ public PGPPrivateKey( long keyID, PublicKeyPacket publicKeyPacket, BCPGKey privateKeyDataPacket) { this.keyID = keyID; this.publicKeyPacket = publicKeyPacket; this.privateKeyDataPacket = privateKeyDataPacket; } /** * Return the keyID associated with the contained private key. * * @return long */ public long getKeyID() { return keyID; } /** * Return the contained private key. * * @return PrivateKey * @deprecated use a JcaPGPKeyConverter */ public PrivateKey getKey() { if (privateKey != null) { return privateKey; } try { return new JcaPGPKeyConverter().setProvider(PGPUtil.getDefaultProvider()).getPrivateKey(this); } catch (PGPException e) { throw new IllegalStateException("unable to convert key: " + e.toString()); } } /** * Return the public key packet associated with this private key, if available. * * @return associated public key packet, null otherwise. */ public PublicKeyPacket getPublicKeyPacket() { return publicKeyPacket; } /** * Return the private key packet associated with this private key, if available. * * @return associated private key packet, null otherwise. */ public BCPGKey getPrivateKeyDataPacket() { return privateKeyDataPacket; } } bouncycastle-1.49.orig/src/org/bouncycastle/openpgp/PGPUserAttributeSubpacketVectorGenerator.java0000644000175000017500000000136711442065640033073 0ustar ebourgebourgpackage org.bouncycastle.openpgp; import org.bouncycastle.bcpg.UserAttributeSubpacket; import org.bouncycastle.bcpg.attr.ImageAttribute; import java.util.ArrayList; import java.util.List; public class PGPUserAttributeSubpacketVectorGenerator { private List list = new ArrayList(); public void setImageAttribute(int imageType, byte[] imageData) { if (imageData == null) { throw new IllegalArgumentException("attempt to set null image"); } list.add(new ImageAttribute(imageType, imageData)); } public PGPUserAttributeSubpacketVector generate() { return new PGPUserAttributeSubpacketVector((UserAttributeSubpacket[])list.toArray(new UserAttributeSubpacket[list.size()])); } } bouncycastle-1.49.orig/src/org/bouncycastle/openpgp/PGPEncryptedData.java0000644000175000017500000000744011577260475026136 0ustar ebourgebourgpackage org.bouncycastle.openpgp; import java.io.EOFException; import java.io.IOException; import java.io.InputStream; import java.io.OutputStream; import org.bouncycastle.bcpg.InputStreamPacket; import org.bouncycastle.bcpg.SymmetricEncIntegrityPacket; import org.bouncycastle.bcpg.SymmetricKeyAlgorithmTags; import org.bouncycastle.openpgp.operator.PGPDigestCalculator; import org.bouncycastle.util.Arrays; public abstract class PGPEncryptedData implements SymmetricKeyAlgorithmTags { protected class TruncatedStream extends InputStream { int[] lookAhead = new int[22]; int bufPtr; InputStream in; TruncatedStream( InputStream in) throws IOException { for (int i = 0; i != lookAhead.length; i++) { if ((lookAhead[i] = in.read()) < 0) { throw new EOFException(); } } bufPtr = 0; this.in = in; } public int read() throws IOException { int ch = in.read(); if (ch >= 0) { int c = lookAhead[bufPtr]; lookAhead[bufPtr] = ch; bufPtr = (bufPtr + 1) % lookAhead.length; return c; } return -1; } int[] getLookAhead() { int[] tmp = new int[lookAhead.length]; int count = 0; for (int i = bufPtr; i != lookAhead.length; i++) { tmp[count++] = lookAhead[i]; } for (int i = 0; i != bufPtr; i++) { tmp[count++] = lookAhead[i]; } return tmp; } } InputStreamPacket encData; InputStream encStream; TruncatedStream truncStream; PGPDigestCalculator integrityCalculator; PGPEncryptedData( InputStreamPacket encData) { this.encData = encData; } /** * Return the raw input stream for the data stream. * * @return InputStream */ public InputStream getInputStream() { return encData.getInputStream(); } /** * Return true if the message is integrity protected. * @return true if there is a modification detection code package associated with this stream */ public boolean isIntegrityProtected() { return (encData instanceof SymmetricEncIntegrityPacket); } /** * Note: This can only be called after the message has been read. * * @return true if the message verifies, false otherwise. * @throws PGPException if the message is not integrity protected. */ public boolean verify() throws PGPException, IOException { if (!this.isIntegrityProtected()) { throw new PGPException("data not integrity protected."); } // // make sure we are at the end. // while (encStream.read() >= 0) { // do nothing } // // process the MDC packet // int[] lookAhead = truncStream.getLookAhead(); OutputStream dOut = integrityCalculator.getOutputStream(); dOut.write((byte)lookAhead[0]); dOut.write((byte)lookAhead[1]); byte[] digest = integrityCalculator.getDigest(); byte[] streamDigest = new byte[digest.length]; for (int i = 0; i != streamDigest.length; i++) { streamDigest[i] = (byte)lookAhead[i + 2]; } return Arrays.constantTimeAreEqual(digest, streamDigest); } } bouncycastle-1.49.orig/src/org/bouncycastle/openpgp/PGPUserAttributeSubpacketVector.java0000644000175000017500000000407610266707637031240 0ustar ebourgebourgpackage org.bouncycastle.openpgp; import org.bouncycastle.bcpg.UserAttributeSubpacket; import org.bouncycastle.bcpg.UserAttributeSubpacketTags; import org.bouncycastle.bcpg.attr.ImageAttribute; /** * Container for a list of user attribute subpackets. */ public class PGPUserAttributeSubpacketVector { UserAttributeSubpacket[] packets; PGPUserAttributeSubpacketVector( UserAttributeSubpacket[] packets) { this.packets = packets; } public UserAttributeSubpacket getSubpacket( int type) { for (int i = 0; i != packets.length; i++) { if (packets[i].getType() == type) { return packets[i]; } } return null; } public ImageAttribute getImageAttribute() { UserAttributeSubpacket p = this.getSubpacket(UserAttributeSubpacketTags.IMAGE_ATTRIBUTE); if (p == null) { return null; } return (ImageAttribute)p; } UserAttributeSubpacket[] toSubpacketArray() { return packets; } public boolean equals( Object o) { if (o == this) { return true; } if (o instanceof PGPUserAttributeSubpacketVector) { PGPUserAttributeSubpacketVector other = (PGPUserAttributeSubpacketVector)o; if (other.packets.length != packets.length) { return false; } for (int i = 0; i != packets.length; i++) { if (!other.packets[i].equals(packets[i])) { return false; } } return true; } return false; } public int hashCode() { int code = 0; for (int i = 0; i != packets.length; i++) { code ^= packets[i].hashCode(); } return code; } } bouncycastle-1.49.orig/src/org/bouncycastle/openpgp/PGPV3SignatureGenerator.java0000644000175000017500000001763611723273745027435 0ustar ebourgebourgpackage org.bouncycastle.openpgp; import java.io.ByteArrayOutputStream; import java.io.IOException; import java.io.OutputStream; import java.math.BigInteger; import java.security.NoSuchAlgorithmException; import java.security.NoSuchProviderException; import java.security.Provider; import java.security.SecureRandom; import java.security.SignatureException; import java.util.Date; import org.bouncycastle.bcpg.MPInteger; import org.bouncycastle.bcpg.OnePassSignaturePacket; import org.bouncycastle.bcpg.PublicKeyAlgorithmTags; import org.bouncycastle.bcpg.SignaturePacket; import org.bouncycastle.openpgp.operator.PGPContentSigner; import org.bouncycastle.openpgp.operator.PGPContentSignerBuilder; import org.bouncycastle.openpgp.operator.jcajce.JcaPGPContentSignerBuilder; /** * Generator for old style PGP V3 Signatures. */ public class PGPV3SignatureGenerator { private byte lastb; private OutputStream sigOut; private PGPContentSignerBuilder contentSignerBuilder; private PGPContentSigner contentSigner; private int sigType; private int providedKeyAlgorithm = -1; /** * Create a generator for the passed in keyAlgorithm and hashAlgorithm codes. * * @param keyAlgorithm * @param hashAlgorithm * @param provider * @throws NoSuchAlgorithmException * @throws NoSuchProviderException * @throws PGPException * @deprecated use constructor taking PGPContentSignerBuilder. */ public PGPV3SignatureGenerator( int keyAlgorithm, int hashAlgorithm, String provider) throws NoSuchAlgorithmException, NoSuchProviderException, PGPException { this(keyAlgorithm, hashAlgorithm, PGPUtil.getProvider(provider)); } /** * * @param keyAlgorithm * @param hashAlgorithm * @param provider * @throws NoSuchAlgorithmException * @throws PGPException * @deprecated use constructor taking PGPContentSignerBuilder. */ public PGPV3SignatureGenerator( int keyAlgorithm, int hashAlgorithm, Provider provider) throws NoSuchAlgorithmException, PGPException { this.providedKeyAlgorithm = keyAlgorithm; this.contentSignerBuilder = new JcaPGPContentSignerBuilder(keyAlgorithm, hashAlgorithm).setProvider(provider); } /** * Create a signature generator built on the passed in contentSignerBuilder. * * @param contentSignerBuilder builder to produce PGPContentSigner objects for generating signatures. */ public PGPV3SignatureGenerator( PGPContentSignerBuilder contentSignerBuilder) { this.contentSignerBuilder = contentSignerBuilder; } /** * Initialise the generator for signing. * * @param signatureType * @param key * @throws PGPException */ public void init( int signatureType, PGPPrivateKey key) throws PGPException { contentSigner = contentSignerBuilder.build(signatureType, key); sigOut = contentSigner.getOutputStream(); sigType = contentSigner.getType(); lastb = 0; if (providedKeyAlgorithm >= 0 && providedKeyAlgorithm != contentSigner.getKeyAlgorithm()) { throw new PGPException("key algorithm mismatch"); } } /** * Initialise the generator for signing. * * @param signatureType * @param key * @param random * @throws PGPException * @deprecated random now ignored - set random in PGPContentSignerBuilder */ public void initSign( int signatureType, PGPPrivateKey key, SecureRandom random) throws PGPException { init(signatureType, key); } /** * Initialise the generator for signing. * * @param signatureType * @param key * @throws PGPException * @deprecated use init() */ public void initSign( int signatureType, PGPPrivateKey key) throws PGPException { init(signatureType, key); } public void update( byte b) throws SignatureException { if (sigType == PGPSignature.CANONICAL_TEXT_DOCUMENT) { if (b == '\r') { byteUpdate((byte)'\r'); byteUpdate((byte)'\n'); } else if (b == '\n') { if (lastb != '\r') { byteUpdate((byte)'\r'); byteUpdate((byte)'\n'); } } else { byteUpdate(b); } lastb = b; } else { byteUpdate(b); } } public void update( byte[] b) throws SignatureException { this.update(b, 0, b.length); } public void update( byte[] b, int off, int len) throws SignatureException { if (sigType == PGPSignature.CANONICAL_TEXT_DOCUMENT) { int finish = off + len; for (int i = off; i != finish; i++) { this.update(b[i]); } } else { blockUpdate(b, off, len); } } private void byteUpdate(byte b) throws SignatureException { try { sigOut.write(b); } catch (IOException e) { throw new IllegalStateException("unable to update signature"); } } private void blockUpdate(byte[] block, int off, int len) throws SignatureException { try { sigOut.write(block, off, len); } catch (IOException e) { throw new IllegalStateException("unable to update signature"); } } /** * Return the one pass header associated with the current signature. * * @param isNested * @return PGPOnePassSignature * @throws PGPException */ public PGPOnePassSignature generateOnePassVersion( boolean isNested) throws PGPException { return new PGPOnePassSignature(new OnePassSignaturePacket(sigType, contentSigner.getHashAlgorithm(), contentSigner.getKeyAlgorithm(), contentSigner.getKeyID(), isNested)); } /** * Return a V3 signature object containing the current signature state. * * @return PGPSignature * @throws PGPException * @throws SignatureException */ public PGPSignature generate() throws PGPException, SignatureException { long creationTime = new Date().getTime() / 1000; ByteArrayOutputStream sOut = new ByteArrayOutputStream(); sOut.write(sigType); sOut.write((byte)(creationTime >> 24)); sOut.write((byte)(creationTime >> 16)); sOut.write((byte)(creationTime >> 8)); sOut.write((byte)creationTime); byte[] hData = sOut.toByteArray(); blockUpdate(hData, 0, hData.length); MPInteger[] sigValues; if (contentSigner.getKeyAlgorithm() == PublicKeyAlgorithmTags.RSA_SIGN || contentSigner.getKeyAlgorithm() == PublicKeyAlgorithmTags.RSA_GENERAL) // an RSA signature { sigValues = new MPInteger[1]; sigValues[0] = new MPInteger(new BigInteger(1, contentSigner.getSignature())); } else { sigValues = PGPUtil.dsaSigToMpi(contentSigner.getSignature()); } byte[] digest = contentSigner.getDigest(); byte[] fingerPrint = new byte[2]; fingerPrint[0] = digest[0]; fingerPrint[1] = digest[1]; return new PGPSignature(new SignaturePacket(3, contentSigner.getType(), contentSigner.getKeyID(), contentSigner.getKeyAlgorithm(), contentSigner.getHashAlgorithm(), creationTime * 1000, fingerPrint, sigValues)); } } bouncycastle-1.49.orig/src/org/bouncycastle/openpgp/PGPLiteralData.java0000644000175000017500000000404311134712243025551 0ustar ebourgebourgpackage org.bouncycastle.openpgp; import java.io.IOException; import java.io.InputStream; import java.util.Date; import org.bouncycastle.bcpg.BCPGInputStream; import org.bouncycastle.bcpg.LiteralDataPacket; /** * class for processing literal data objects. */ public class PGPLiteralData { public static final char BINARY = 'b'; public static final char TEXT = 't'; public static final char UTF8 = 'u'; /** * The special name indicating a "for your eyes only" packet. */ public static final String CONSOLE = "_CONSOLE"; /** * The special time for a modification time of "now" or * the present time. */ public static final Date NOW = new Date(0L); LiteralDataPacket data; public PGPLiteralData( BCPGInputStream pIn) throws IOException { data = (LiteralDataPacket)pIn.readPacket(); } /** * Return the format of the data stream - BINARY or TEXT. * * @return int */ public int getFormat() { return data.getFormat(); } /** * Return the file name that's associated with the data stream. * * @return String */ public String getFileName() { return data.getFileName(); } /** * Return the file name as an unintrepreted byte array. */ public byte[] getRawFileName() { return data.getRawFileName(); } /** * Return the modification time for the file. * * @return the modification time. */ public Date getModificationTime() { return new Date(data.getModificationTime()); } /** * Return the raw input stream for the data stream. * * @return InputStream */ public InputStream getInputStream() { return data.getInputStream(); } /** * Return the input stream representing the data stream * * @return InputStream */ public InputStream getDataStream() { return this.getInputStream(); } } bouncycastle-1.49.orig/src/org/bouncycastle/openpgp/PGPKeyPair.java0000644000175000017500000001003311732257157024737 0ustar ebourgebourgpackage org.bouncycastle.openpgp; import java.security.KeyPair; import java.security.NoSuchProviderException; import java.security.PrivateKey; import java.security.PublicKey; import java.security.interfaces.DSAPrivateKey; import java.security.interfaces.RSAPrivateCrtKey; import java.util.Date; import org.bouncycastle.bcpg.BCPGKey; import org.bouncycastle.bcpg.DSASecretBCPGKey; import org.bouncycastle.bcpg.ElGamalSecretBCPGKey; import org.bouncycastle.bcpg.RSASecretBCPGKey; import org.bouncycastle.jce.interfaces.ElGamalPrivateKey; /** * General class to handle JCA key pairs and convert them into OpenPGP ones. *

    * A word for the unwary, the KeyID for a OpenPGP public key is calculated from * a hash that includes the time of creation, if you pass a different date to the * constructor below with the same public private key pair the KeyID will not be the * same as for previous generations of the key, so ideally you only want to do * this once. */ public class PGPKeyPair { protected PGPPublicKey pub; protected PGPPrivateKey priv; /** * @deprecated use BcPGPKeyPair or JcaPGPKeyPair as appropriate. */ public PGPKeyPair( int algorithm, KeyPair keyPair, Date time, String provider) throws PGPException, NoSuchProviderException { this(algorithm, keyPair.getPublic(), keyPair.getPrivate(), time, provider); } /** * @deprecated use BcPGPKeyPair or JcaPGPKeyPair as appropriate. */ public PGPKeyPair( int algorithm, KeyPair keyPair, Date time) throws PGPException { this(algorithm, keyPair.getPublic(), keyPair.getPrivate(), time); } /** * @deprecated use BcPGPKeyPair or JcaPGPKeyPair as appropriate. */ public PGPKeyPair( int algorithm, PublicKey pubKey, PrivateKey privKey, Date time, String provider) throws PGPException, NoSuchProviderException { this(algorithm, pubKey, privKey, time); } /** * @deprecated use BcPGPKeyPair or JcaPGPKeyPair as appropriate. */ public PGPKeyPair( int algorithm, PublicKey pubKey, PrivateKey privKey, Date time) throws PGPException { this.pub = new PGPPublicKey(algorithm, pubKey, time); BCPGKey privPk; switch (pub.getAlgorithm()) { case PGPPublicKey.RSA_ENCRYPT: case PGPPublicKey.RSA_SIGN: case PGPPublicKey.RSA_GENERAL: RSAPrivateCrtKey rsK = (RSAPrivateCrtKey)privKey; privPk = new RSASecretBCPGKey(rsK.getPrivateExponent(), rsK.getPrimeP(), rsK.getPrimeQ()); break; case PGPPublicKey.DSA: DSAPrivateKey dsK = (DSAPrivateKey)privKey; privPk = new DSASecretBCPGKey(dsK.getX()); break; case PGPPublicKey.ELGAMAL_ENCRYPT: case PGPPublicKey.ELGAMAL_GENERAL: ElGamalPrivateKey esK = (ElGamalPrivateKey)privKey; privPk = new ElGamalSecretBCPGKey(esK.getX()); break; default: throw new PGPException("unknown key class"); } this.priv = new PGPPrivateKey(pub.getKeyID(), pub.getPublicKeyPacket(), privPk); } /** * Create a key pair from a PGPPrivateKey and a PGPPublicKey. * * @param pub the public key * @param priv the private key */ public PGPKeyPair( PGPPublicKey pub, PGPPrivateKey priv) { this.pub = pub; this.priv = priv; } protected PGPKeyPair() { } /** * Return the keyID associated with this key pair. * * @return keyID */ public long getKeyID() { return pub.getKeyID(); } public PGPPublicKey getPublicKey() { return pub; } public PGPPrivateKey getPrivateKey() { return priv; } } bouncycastle-1.49.orig/src/org/bouncycastle/openpgp/PGPObjectFactory.java0000644000175000017500000001142611605214673026133 0ustar ebourgebourgpackage org.bouncycastle.openpgp; import java.io.ByteArrayInputStream; import java.io.IOException; import java.io.InputStream; import java.util.ArrayList; import java.util.List; import org.bouncycastle.bcpg.BCPGInputStream; import org.bouncycastle.bcpg.PacketTags; import org.bouncycastle.openpgp.operator.KeyFingerPrintCalculator; import org.bouncycastle.openpgp.operator.jcajce.JcaKeyFingerprintCalculator; /** * General class for reading a PGP object stream. *

    * Note: if this class finds a PGPPublicKey or a PGPSecretKey it * will create a PGPPublicKeyRing, or a PGPSecretKeyRing for each * key found. If all you are trying to do is read a key ring file use * either PGPPublicKeyRingCollection or PGPSecretKeyRingCollection. */ public class PGPObjectFactory { private BCPGInputStream in; private KeyFingerPrintCalculator fingerPrintCalculator; public PGPObjectFactory( InputStream in) { this(in, new JcaKeyFingerprintCalculator()); } /** * Create an object factor suitable for reading keys, key rings and key ring collections. * * @param in stream to read from * @param fingerPrintCalculator calculator to use in key finger print calculations. */ public PGPObjectFactory( InputStream in, KeyFingerPrintCalculator fingerPrintCalculator) { this.in = new BCPGInputStream(in); this.fingerPrintCalculator = fingerPrintCalculator; } public PGPObjectFactory( byte[] bytes) { this(new ByteArrayInputStream(bytes)); } /** * Create an object factor suitable for reading keys, key rings and key ring collections. * * @param bytes stream to read from * @param fingerPrintCalculator calculator to use in key finger print calculations. */ public PGPObjectFactory( byte[] bytes, KeyFingerPrintCalculator fingerPrintCalculator) { this(new ByteArrayInputStream(bytes), fingerPrintCalculator); } /** * Return the next object in the stream, or null if the end is reached. * * @return Object * @throws IOException on a parse error */ public Object nextObject() throws IOException { List l; switch (in.nextPacketTag()) { case -1: return null; case PacketTags.SIGNATURE: l = new ArrayList(); while (in.nextPacketTag() == PacketTags.SIGNATURE) { try { l.add(new PGPSignature(in)); } catch (PGPException e) { throw new IOException("can't create signature object: " + e); } } return new PGPSignatureList((PGPSignature[])l.toArray(new PGPSignature[l.size()])); case PacketTags.SECRET_KEY: try { return new PGPSecretKeyRing(in, fingerPrintCalculator); } catch (PGPException e) { throw new IOException("can't create secret key object: " + e); } case PacketTags.PUBLIC_KEY: return new PGPPublicKeyRing(in, fingerPrintCalculator); case PacketTags.PUBLIC_SUBKEY: try { return PGPPublicKeyRing.readSubkey(in, fingerPrintCalculator); } catch (PGPException e) { throw new IOException("processing error: " + e.getMessage()); } case PacketTags.COMPRESSED_DATA: return new PGPCompressedData(in); case PacketTags.LITERAL_DATA: return new PGPLiteralData(in); case PacketTags.PUBLIC_KEY_ENC_SESSION: case PacketTags.SYMMETRIC_KEY_ENC_SESSION: return new PGPEncryptedDataList(in); case PacketTags.ONE_PASS_SIGNATURE: l = new ArrayList(); while (in.nextPacketTag() == PacketTags.ONE_PASS_SIGNATURE) { try { l.add(new PGPOnePassSignature(in)); } catch (PGPException e) { throw new IOException("can't create one pass signature object: " + e); } } return new PGPOnePassSignatureList((PGPOnePassSignature[])l.toArray(new PGPOnePassSignature[l.size()])); case PacketTags.MARKER: return new PGPMarker(in); case PacketTags.EXPERIMENTAL_1: case PacketTags.EXPERIMENTAL_2: case PacketTags.EXPERIMENTAL_3: case PacketTags.EXPERIMENTAL_4: return in.readPacket(); } throw new IOException("unknown object in stream: " + in.nextPacketTag()); } } bouncycastle-1.49.orig/src/org/bouncycastle/openpgp/PGPOnePassSignatureList.java0000644000175000017500000000144110262753174027461 0ustar ebourgebourgpackage org.bouncycastle.openpgp; /** * Holder for a list of PGPOnePassSignatures */ public class PGPOnePassSignatureList { PGPOnePassSignature[] sigs; public PGPOnePassSignatureList( PGPOnePassSignature[] sigs) { this.sigs = new PGPOnePassSignature[sigs.length]; System.arraycopy(sigs, 0, this.sigs, 0, sigs.length); } public PGPOnePassSignatureList( PGPOnePassSignature sig) { this.sigs = new PGPOnePassSignature[1]; this.sigs[0] = sig; } public PGPOnePassSignature get( int index) { return sigs[index]; } public int size() { return sigs.length; } public boolean isEmpty() { return (sigs.length == 0); } } bouncycastle-1.49.orig/src/org/bouncycastle/openpgp/StreamGenerator.java0000644000175000017500000000021310527766126026127 0ustar ebourgebourgpackage org.bouncycastle.openpgp; import java.io.IOException; interface StreamGenerator { void close() throws IOException; } bouncycastle-1.49.orig/src/org/bouncycastle/openpgp/examples/0000755000175000017500000000000012152033551023765 5ustar ebourgebourgbouncycastle-1.49.orig/src/org/bouncycastle/openpgp/examples/DirectKeySignature.java0000644000175000017500000001330611706144241030403 0ustar ebourgebourgpackage org.bouncycastle.openpgp.examples; import java.io.ByteArrayInputStream; import java.io.ByteArrayOutputStream; import java.io.FileInputStream; import java.io.FileOutputStream; import java.io.OutputStream; import java.security.Security; import java.util.Iterator; import org.bouncycastle.bcpg.ArmoredOutputStream; import org.bouncycastle.bcpg.BCPGOutputStream; import org.bouncycastle.bcpg.sig.NotationData; import org.bouncycastle.jce.provider.BouncyCastleProvider; import org.bouncycastle.openpgp.PGPPrivateKey; import org.bouncycastle.openpgp.PGPPublicKey; import org.bouncycastle.openpgp.PGPPublicKeyRing; import org.bouncycastle.openpgp.PGPSecretKey; import org.bouncycastle.openpgp.PGPSecretKeyRing; import org.bouncycastle.openpgp.PGPSignature; import org.bouncycastle.openpgp.PGPSignatureGenerator; import org.bouncycastle.openpgp.PGPSignatureSubpacketGenerator; import org.bouncycastle.openpgp.PGPSignatureSubpacketVector; import org.bouncycastle.openpgp.PGPUtil; import org.bouncycastle.openpgp.operator.jcajce.JcaKeyFingerprintCalculator; import org.bouncycastle.openpgp.operator.jcajce.JcaPGPContentSignerBuilder; import org.bouncycastle.openpgp.operator.jcajce.JcePBESecretKeyDecryptorBuilder; /** * A simple utility class that directly signs a public key and writes the signed key to "SignedKey.asc" in * the current working directory. *

    * To sign a key: DirectKeySignature secretKeyFile secretKeyPass publicKeyFile(key to be signed) NotationName NotationValue.
    *

    * To display a NotationData packet from a publicKey previously signed: DirectKeySignature signedPublicKeyFile.
    *

    * Note: this example will silently overwrite files, nor does it pay any attention to * the specification of "_CONSOLE" in the filename. It also expects that a single pass phrase * will have been used. *

    */ public class DirectKeySignature { public static void main( String[] args) throws Exception { Security.addProvider(new BouncyCastleProvider()); if (args.length == 1) { PGPPublicKeyRing ring = new PGPPublicKeyRing(PGPUtil.getDecoderStream(new FileInputStream(args[0])), new JcaKeyFingerprintCalculator()); PGPPublicKey key = ring.getPublicKey(); // iterate through all direct key signautures and look for NotationData subpackets Iterator iter = key.getSignaturesOfType(PGPSignature.DIRECT_KEY); while(iter.hasNext()) { PGPSignature sig = (PGPSignature)iter.next(); System.out.println("Signature date is: " + sig.getHashedSubPackets().getSignatureCreationTime()); NotationData[] data = sig.getHashedSubPackets().getNotationDataOccurences();//.getSubpacket(SignatureSubpacketTags.NOTATION_DATA); for (int i = 0; i < data.length; i++) { System.out.println("Found Notaion named '"+data[i].getNotationName()+"' with content '"+data[i].getNotationValue()+"'."); } } } else if (args.length == 5) { // gather command line arguments PGPSecretKeyRing secRing = new PGPSecretKeyRing(PGPUtil.getDecoderStream(new FileInputStream(args[0])), new JcaKeyFingerprintCalculator()); String secretKeyPass = args[1]; PGPPublicKeyRing ring = new PGPPublicKeyRing(PGPUtil.getDecoderStream(new FileInputStream(args[2])), new JcaKeyFingerprintCalculator()); String notationName = args[3]; String notationValue = args[4]; // create the signed keyRing PGPPublicKeyRing sRing = new PGPPublicKeyRing(new ByteArrayInputStream(signPublicKey(secRing.getSecretKey(), secretKeyPass, ring.getPublicKey(), notationName, notationValue, true)), new JcaKeyFingerprintCalculator()); ring = sRing; // write the created keyRing to file ArmoredOutputStream out = new ArmoredOutputStream(new FileOutputStream("SignedKey.asc")); sRing.encode(out); out.flush(); out.close(); } else { System.err.println("usage: DirectKeySignature secretKeyFile secretKeyPass publicKeyFile(key to be signed) NotationName NotationValue"); System.err.println("or: DirectKeySignature signedPublicKeyFile"); } } private static byte[] signPublicKey(PGPSecretKey secretKey, String secretKeyPass, PGPPublicKey keyToBeSigned, String notationName, String notationValue, boolean armor) throws Exception { OutputStream out = new ByteArrayOutputStream(); if (armor) { out = new ArmoredOutputStream(out); } PGPPrivateKey pgpPrivKey = secretKey.extractPrivateKey(new JcePBESecretKeyDecryptorBuilder().setProvider("BC").build(secretKeyPass.toCharArray())); PGPSignatureGenerator sGen = new PGPSignatureGenerator(new JcaPGPContentSignerBuilder(secretKey.getPublicKey().getAlgorithm(), PGPUtil.SHA1).setProvider("BC")); sGen.init(PGPSignature.DIRECT_KEY, pgpPrivKey); BCPGOutputStream bOut = new BCPGOutputStream(out); sGen.generateOnePassVersion(false).encode(bOut); PGPSignatureSubpacketGenerator spGen = new PGPSignatureSubpacketGenerator(); boolean isHumanReadable = true; spGen.setNotationData(true, isHumanReadable, notationName, notationValue); PGPSignatureSubpacketVector packetVector = spGen.generate(); sGen.setHashedSubpackets(packetVector); bOut.flush(); if (armor) { out.close(); } return PGPPublicKey.addCertification(keyToBeSigned, sGen.generate()).getEncoded(); } } bouncycastle-1.49.orig/src/org/bouncycastle/openpgp/examples/ClearSignedFileProcessor.java0000644000175000017500000002666411616405633031536 0ustar ebourgebourgpackage org.bouncycastle.openpgp.examples; import java.io.BufferedInputStream; import java.io.BufferedOutputStream; import java.io.ByteArrayOutputStream; import java.io.FileInputStream; import java.io.FileOutputStream; import java.io.IOException; import java.io.InputStream; import java.io.OutputStream; import java.security.NoSuchAlgorithmException; import java.security.NoSuchProviderException; import java.security.Security; import java.security.SignatureException; import java.util.Iterator; import org.bouncycastle.bcpg.ArmoredInputStream; import org.bouncycastle.bcpg.ArmoredOutputStream; import org.bouncycastle.bcpg.BCPGOutputStream; import org.bouncycastle.jce.provider.BouncyCastleProvider; import org.bouncycastle.openpgp.PGPException; import org.bouncycastle.openpgp.PGPObjectFactory; import org.bouncycastle.openpgp.PGPPrivateKey; import org.bouncycastle.openpgp.PGPPublicKey; import org.bouncycastle.openpgp.PGPPublicKeyRingCollection; import org.bouncycastle.openpgp.PGPSecretKey; import org.bouncycastle.openpgp.PGPSignature; import org.bouncycastle.openpgp.PGPSignatureGenerator; import org.bouncycastle.openpgp.PGPSignatureList; import org.bouncycastle.openpgp.PGPSignatureSubpacketGenerator; import org.bouncycastle.openpgp.PGPUtil; import org.bouncycastle.openpgp.operator.jcajce.JcaPGPContentSignerBuilder; import org.bouncycastle.openpgp.operator.jcajce.JcaPGPContentVerifierBuilderProvider; import org.bouncycastle.openpgp.operator.jcajce.JcePBESecretKeyDecryptorBuilder; /** * A simple utility class that creates clear signed files and verifies them. *

    * To sign a file: ClearSignedFileProcessor -s fileName secretKey passPhrase.
    *

    * To decrypt: ClearSignedFileProcessor -v fileName signatureFile publicKeyFile. */ public class ClearSignedFileProcessor { private static int readInputLine(ByteArrayOutputStream bOut, InputStream fIn) throws IOException { bOut.reset(); int lookAhead = -1; int ch; while ((ch = fIn.read()) >= 0) { bOut.write(ch); if (ch == '\r' || ch == '\n') { lookAhead = readPassedEOL(bOut, ch, fIn); break; } } return lookAhead; } private static int readInputLine(ByteArrayOutputStream bOut, int lookAhead, InputStream fIn) throws IOException { bOut.reset(); int ch = lookAhead; do { bOut.write(ch); if (ch == '\r' || ch == '\n') { lookAhead = readPassedEOL(bOut, ch, fIn); break; } } while ((ch = fIn.read()) >= 0); if (ch < 0) { lookAhead = -1; } return lookAhead; } private static int readPassedEOL(ByteArrayOutputStream bOut, int lastCh, InputStream fIn) throws IOException { int lookAhead = fIn.read(); if (lastCh == '\r' && lookAhead == '\n') { bOut.write(lookAhead); lookAhead = fIn.read(); } return lookAhead; } /* * verify a clear text signed file */ private static void verifyFile( InputStream in, InputStream keyIn, String resultName) throws Exception { ArmoredInputStream aIn = new ArmoredInputStream(in); OutputStream out = new BufferedOutputStream(new FileOutputStream(resultName)); // // write out signed section using the local line separator. // note: trailing white space needs to be removed from the end of // each line RFC 4880 Section 7.1 // ByteArrayOutputStream lineOut = new ByteArrayOutputStream(); int lookAhead = readInputLine(lineOut, aIn); byte[] lineSep = getLineSeparator(); if (lookAhead != -1 && aIn.isClearText()) { byte[] line = lineOut.toByteArray(); out.write(line, 0, getLengthWithoutSeparatorOrTrailingWhitespace(line)); out.write(lineSep); while (lookAhead != -1 && aIn.isClearText()) { lookAhead = readInputLine(lineOut, lookAhead, aIn); line = lineOut.toByteArray(); out.write(line, 0, getLengthWithoutSeparatorOrTrailingWhitespace(line)); out.write(lineSep); } } out.close(); PGPPublicKeyRingCollection pgpRings = new PGPPublicKeyRingCollection(keyIn); PGPObjectFactory pgpFact = new PGPObjectFactory(aIn); PGPSignatureList p3 = (PGPSignatureList)pgpFact.nextObject(); PGPSignature sig = p3.get(0); PGPPublicKey publicKey = pgpRings.getPublicKey(sig.getKeyID()); sig.init(new JcaPGPContentVerifierBuilderProvider().setProvider("BC"), publicKey); // // read the input, making sure we ignore the last newline. // InputStream sigIn = new BufferedInputStream(new FileInputStream(resultName)); lookAhead = readInputLine(lineOut, sigIn); processLine(sig, lineOut.toByteArray()); if (lookAhead != -1) { do { lookAhead = readInputLine(lineOut, lookAhead, sigIn); sig.update((byte)'\r'); sig.update((byte)'\n'); processLine(sig, lineOut.toByteArray()); } while (lookAhead != -1); } sigIn.close(); if (sig.verify()) { System.out.println("signature verified."); } else { System.out.println("signature verification failed."); } } private static byte[] getLineSeparator() { String nl = System.getProperty("line.separator"); byte[] nlBytes = new byte[nl.length()]; for (int i = 0; i != nlBytes.length; i++) { nlBytes[i] = (byte)nl.charAt(i); } return nlBytes; } /* * create a clear text signed file. */ private static void signFile( String fileName, InputStream keyIn, OutputStream out, char[] pass, String digestName) throws IOException, NoSuchAlgorithmException, NoSuchProviderException, PGPException, SignatureException { int digest; if (digestName.equals("SHA256")) { digest = PGPUtil.SHA256; } else if (digestName.equals("SHA384")) { digest = PGPUtil.SHA384; } else if (digestName.equals("SHA512")) { digest = PGPUtil.SHA512; } else if (digestName.equals("MD5")) { digest = PGPUtil.MD5; } else if (digestName.equals("RIPEMD160")) { digest = PGPUtil.RIPEMD160; } else { digest = PGPUtil.SHA1; } PGPSecretKey pgpSecKey = PGPExampleUtil.readSecretKey(keyIn); PGPPrivateKey pgpPrivKey = pgpSecKey.extractPrivateKey(new JcePBESecretKeyDecryptorBuilder().setProvider("BC").build(pass)); PGPSignatureGenerator sGen = new PGPSignatureGenerator(new JcaPGPContentSignerBuilder(pgpSecKey.getPublicKey().getAlgorithm(), digest).setProvider("BC")); PGPSignatureSubpacketGenerator spGen = new PGPSignatureSubpacketGenerator(); sGen.init(PGPSignature.CANONICAL_TEXT_DOCUMENT, pgpPrivKey); Iterator it = pgpSecKey.getPublicKey().getUserIDs(); if (it.hasNext()) { spGen.setSignerUserID(false, (String)it.next()); sGen.setHashedSubpackets(spGen.generate()); } InputStream fIn = new BufferedInputStream(new FileInputStream(fileName)); ArmoredOutputStream aOut = new ArmoredOutputStream(out); aOut.beginClearText(digest); // // note the last \n/\r/\r\n in the file is ignored // ByteArrayOutputStream lineOut = new ByteArrayOutputStream(); int lookAhead = readInputLine(lineOut, fIn); processLine(aOut, sGen, lineOut.toByteArray()); if (lookAhead != -1) { do { lookAhead = readInputLine(lineOut, lookAhead, fIn); sGen.update((byte)'\r'); sGen.update((byte)'\n'); processLine(aOut, sGen, lineOut.toByteArray()); } while (lookAhead != -1); } fIn.close(); aOut.endClearText(); BCPGOutputStream bOut = new BCPGOutputStream(aOut); sGen.generate().encode(bOut); aOut.close(); } private static void processLine(PGPSignature sig, byte[] line) throws SignatureException, IOException { int length = getLengthWithoutWhiteSpace(line); if (length > 0) { sig.update(line, 0, length); } } private static void processLine(OutputStream aOut, PGPSignatureGenerator sGen, byte[] line) throws SignatureException, IOException { // note: trailing white space needs to be removed from the end of // each line for signature calculation RFC 4880 Section 7.1 int length = getLengthWithoutWhiteSpace(line); if (length > 0) { sGen.update(line, 0, length); } aOut.write(line, 0, line.length); } private static int getLengthWithoutSeparatorOrTrailingWhitespace(byte[] line) { int end = line.length - 1; while (end >= 0 && isWhiteSpace(line[end])) { end--; } return end + 1; } private static boolean isLineEnding(byte b) { return b == '\r' || b == '\n'; } private static int getLengthWithoutWhiteSpace(byte[] line) { int end = line.length - 1; while (end >= 0 && isWhiteSpace(line[end])) { end--; } return end + 1; } private static boolean isWhiteSpace(byte b) { return isLineEnding(b) || b == '\t' || b == ' '; } public static void main( String[] args) throws Exception { Security.addProvider(new BouncyCastleProvider()); if (args[0].equals("-s")) { InputStream keyIn = PGPUtil.getDecoderStream(new FileInputStream(args[2])); FileOutputStream out = new FileOutputStream(args[1] + ".asc"); if (args.length == 4) { signFile(args[1], keyIn, out, args[3].toCharArray(), "SHA1"); } else { signFile(args[1], keyIn, out, args[3].toCharArray(), args[4]); } } else if (args[0].equals("-v")) { if (args[1].indexOf(".asc") < 0) { System.err.println("file needs to end in \".asc\""); System.exit(1); } FileInputStream in = new FileInputStream(args[1]); InputStream keyIn = PGPUtil.getDecoderStream(new FileInputStream(args[2])); verifyFile(in, keyIn, args[1].substring(0, args[1].length() - 4)); } else { System.err.println("usage: ClearSignedFileProcessor [-s file keyfile passPhrase]|[-v sigFile keyFile]"); } } } bouncycastle-1.49.orig/src/org/bouncycastle/openpgp/examples/RSAKeyPairGenerator.java0000644000175000017500000001024511616402104030411 0ustar ebourgebourgpackage org.bouncycastle.openpgp.examples; import java.io.FileOutputStream; import java.io.IOException; import java.io.OutputStream; import java.security.InvalidKeyException; import java.security.KeyPair; import java.security.KeyPairGenerator; import java.security.NoSuchProviderException; import java.security.PrivateKey; import java.security.PublicKey; import java.security.Security; import java.security.SignatureException; import java.util.Date; import org.bouncycastle.bcpg.ArmoredOutputStream; import org.bouncycastle.bcpg.HashAlgorithmTags; import org.bouncycastle.jce.provider.BouncyCastleProvider; import org.bouncycastle.openpgp.PGPEncryptedData; import org.bouncycastle.openpgp.PGPException; import org.bouncycastle.openpgp.PGPKeyPair; import org.bouncycastle.openpgp.PGPPublicKey; import org.bouncycastle.openpgp.PGPSecretKey; import org.bouncycastle.openpgp.PGPSignature; import org.bouncycastle.openpgp.operator.PGPDigestCalculator; import org.bouncycastle.openpgp.operator.jcajce.JcaPGPContentSignerBuilder; import org.bouncycastle.openpgp.operator.jcajce.JcaPGPDigestCalculatorProviderBuilder; import org.bouncycastle.openpgp.operator.jcajce.JcePBESecretKeyEncryptorBuilder; /** * A simple utility class that generates a RSA PGPPublicKey/PGPSecretKey pair. *

    * usage: RSAKeyPairGenerator [-a] identity passPhrase *

    * Where identity is the name to be associated with the public key. The keys are placed * in the files pub.[asc|bpg] and secret.[asc|bpg]. */ public class RSAKeyPairGenerator { private static void exportKeyPair( OutputStream secretOut, OutputStream publicOut, PublicKey publicKey, PrivateKey privateKey, String identity, char[] passPhrase, boolean armor) throws IOException, InvalidKeyException, NoSuchProviderException, SignatureException, PGPException { if (armor) { secretOut = new ArmoredOutputStream(secretOut); } PGPDigestCalculator sha1Calc = new JcaPGPDigestCalculatorProviderBuilder().build().get(HashAlgorithmTags.SHA1); PGPKeyPair keyPair = new PGPKeyPair(PGPPublicKey.RSA_GENERAL, publicKey, privateKey, new Date()); PGPSecretKey secretKey = new PGPSecretKey(PGPSignature.DEFAULT_CERTIFICATION, keyPair, identity, sha1Calc, null, null, new JcaPGPContentSignerBuilder(keyPair.getPublicKey().getAlgorithm(), HashAlgorithmTags.SHA1), new JcePBESecretKeyEncryptorBuilder(PGPEncryptedData.CAST5, sha1Calc).setProvider("BC").build(passPhrase)); secretKey.encode(secretOut); secretOut.close(); if (armor) { publicOut = new ArmoredOutputStream(publicOut); } PGPPublicKey key = secretKey.getPublicKey(); key.encode(publicOut); publicOut.close(); } public static void main( String[] args) throws Exception { Security.addProvider(new BouncyCastleProvider()); KeyPairGenerator kpg = KeyPairGenerator.getInstance("RSA", "BC"); kpg.initialize(1024); KeyPair kp = kpg.generateKeyPair(); if (args.length < 2) { System.out.println("RSAKeyPairGenerator [-a] identity passPhrase"); System.exit(0); } if (args[0].equals("-a")) { if (args.length < 3) { System.out.println("RSAKeyPairGenerator [-a] identity passPhrase"); System.exit(0); } FileOutputStream out1 = new FileOutputStream("secret.asc"); FileOutputStream out2 = new FileOutputStream("pub.asc"); exportKeyPair(out1, out2, kp.getPublic(), kp.getPrivate(), args[1], args[2].toCharArray(), true); } else { FileOutputStream out1 = new FileOutputStream("secret.bpg"); FileOutputStream out2 = new FileOutputStream("pub.bpg"); exportKeyPair(out1, out2, kp.getPublic(), kp.getPrivate(), args[0], args[1].toCharArray(), false); } } } bouncycastle-1.49.orig/src/org/bouncycastle/openpgp/examples/ByteArrayHandler.java0000644000175000017500000001732111706144241030037 0ustar ebourgebourgpackage org.bouncycastle.openpgp.examples; import java.io.ByteArrayInputStream; import java.io.ByteArrayOutputStream; import java.io.IOException; import java.io.InputStream; import java.io.OutputStream; import java.security.NoSuchProviderException; import java.security.SecureRandom; import java.security.Security; import java.util.Date; import org.bouncycastle.bcpg.ArmoredOutputStream; import org.bouncycastle.bcpg.CompressionAlgorithmTags; import org.bouncycastle.jce.provider.BouncyCastleProvider; import org.bouncycastle.openpgp.PGPCompressedData; import org.bouncycastle.openpgp.PGPCompressedDataGenerator; import org.bouncycastle.openpgp.PGPEncryptedDataGenerator; import org.bouncycastle.openpgp.PGPEncryptedDataList; import org.bouncycastle.openpgp.PGPException; import org.bouncycastle.openpgp.PGPLiteralData; import org.bouncycastle.openpgp.PGPLiteralDataGenerator; import org.bouncycastle.openpgp.PGPObjectFactory; import org.bouncycastle.openpgp.PGPPBEEncryptedData; import org.bouncycastle.openpgp.PGPUtil; import org.bouncycastle.openpgp.operator.jcajce.JcaPGPDigestCalculatorProviderBuilder; import org.bouncycastle.openpgp.operator.jcajce.JcePBEDataDecryptorFactoryBuilder; import org.bouncycastle.openpgp.operator.jcajce.JcePBEKeyEncryptionMethodGenerator; import org.bouncycastle.openpgp.operator.jcajce.JcePGPDataEncryptorBuilder; import org.bouncycastle.util.io.Streams; /** * Simple routine to encrypt and decrypt using a passphrase. * This service routine provides the basic PGP services between * byte arrays. * * Note: this code plays no attention to -CONSOLE in the file name * the specification of "_CONSOLE" in the filename. * It also expects that a single pass phrase will have been used. * */ public class ByteArrayHandler { /** * decrypt the passed in message stream * * @param encrypted The message to be decrypted. * @param passPhrase Pass phrase (key) * * @return Clear text as a byte array. I18N considerations are * not handled by this routine * @exception IOException * @exception PGPException * @exception NoSuchProviderException */ public static byte[] decrypt( byte[] encrypted, char[] passPhrase) throws IOException, PGPException, NoSuchProviderException { InputStream in = new ByteArrayInputStream(encrypted); in = PGPUtil.getDecoderStream(in); PGPObjectFactory pgpF = new PGPObjectFactory(in); PGPEncryptedDataList enc; Object o = pgpF.nextObject(); // // the first object might be a PGP marker packet. // if (o instanceof PGPEncryptedDataList) { enc = (PGPEncryptedDataList)o; } else { enc = (PGPEncryptedDataList)pgpF.nextObject(); } PGPPBEEncryptedData pbe = (PGPPBEEncryptedData)enc.get(0); InputStream clear = pbe.getDataStream(new JcePBEDataDecryptorFactoryBuilder(new JcaPGPDigestCalculatorProviderBuilder().setProvider("BC").build()).setProvider("BC").build(passPhrase)); PGPObjectFactory pgpFact = new PGPObjectFactory(clear); PGPCompressedData cData = (PGPCompressedData)pgpFact.nextObject(); pgpFact = new PGPObjectFactory(cData.getDataStream()); PGPLiteralData ld = (PGPLiteralData)pgpFact.nextObject(); return Streams.readAll(ld.getInputStream()); } /** * Simple PGP encryptor between byte[]. * * @param clearData The test to be encrypted * @param passPhrase The pass phrase (key). This method assumes that the * key is a simple pass phrase, and does not yet support * RSA or more sophisiticated keying. * @param fileName File name. This is used in the Literal Data Packet (tag 11) * which is really inly important if the data is to be * related to a file to be recovered later. Because this * routine does not know the source of the information, the * caller can set something here for file name use that * will be carried. If this routine is being used to * encrypt SOAP MIME bodies, for example, use the file name from the * MIME type, if applicable. Or anything else appropriate. * * @param armor * * @return encrypted data. * @exception IOException * @exception PGPException * @exception NoSuchProviderException */ public static byte[] encrypt( byte[] clearData, char[] passPhrase, String fileName, int algorithm, boolean armor) throws IOException, PGPException, NoSuchProviderException { if (fileName == null) { fileName= PGPLiteralData.CONSOLE; } byte[] compressedData = compress(clearData, fileName, CompressionAlgorithmTags.ZIP); ByteArrayOutputStream bOut = new ByteArrayOutputStream(); OutputStream out = bOut; if (armor) { out = new ArmoredOutputStream(out); } PGPEncryptedDataGenerator encGen = new PGPEncryptedDataGenerator(new JcePGPDataEncryptorBuilder(algorithm).setSecureRandom(new SecureRandom()).setProvider("BC")); encGen.addMethod(new JcePBEKeyEncryptionMethodGenerator(passPhrase).setProvider("BC")); OutputStream encOut = encGen.open(out, compressedData.length); encOut.write(compressedData); encOut.close(); if (armor) { out.close(); } return bOut.toByteArray(); } private static byte[] compress(byte[] clearData, String fileName, int algorithm) throws IOException { ByteArrayOutputStream bOut = new ByteArrayOutputStream(); PGPCompressedDataGenerator comData = new PGPCompressedDataGenerator(algorithm); OutputStream cos = comData.open(bOut); // open it with the final destination PGPLiteralDataGenerator lData = new PGPLiteralDataGenerator(); // we want to generate compressed data. This might be a user option later, // in which case we would pass in bOut. OutputStream pOut = lData.open(cos, // the compressed output stream PGPLiteralData.BINARY, fileName, // "filename" to store clearData.length, // length of clear data new Date() // current time ); pOut.write(clearData); pOut.close(); comData.close(); return bOut.toByteArray(); } public static void main(String[] args) throws Exception { Security.addProvider(new BouncyCastleProvider()); String passPhrase = "Dick Beck"; char[] passArray = passPhrase.toCharArray(); byte[] original = "Hello world".getBytes(); System.out.println("Starting PGP test"); byte[] encrypted = encrypt(original, passArray, "iway", PGPEncryptedDataGenerator.CAST5, true); System.out.println("\nencrypted data = '"+new String(encrypted)+"'"); byte[] decrypted= decrypt(encrypted,passArray); System.out.println("\ndecrypted data = '"+new String(decrypted)+"'"); encrypted = encrypt(original, passArray, "iway", PGPEncryptedDataGenerator.AES_256, false); System.out.println("\nencrypted data = '"+new String(org.bouncycastle.util.encoders.Hex.encode(encrypted))+"'"); decrypted= decrypt(encrypted, passArray); System.out.println("\ndecrypted data = '"+new String(decrypted)+"'"); } } bouncycastle-1.49.orig/src/org/bouncycastle/openpgp/examples/DSAElGamalKeyRingGenerator.java0000644000175000017500000001315312117726764031645 0ustar ebourgebourgpackage org.bouncycastle.openpgp.examples; import java.io.FileOutputStream; import java.io.IOException; import java.io.OutputStream; import java.math.BigInteger; import java.security.InvalidKeyException; import java.security.KeyPair; import java.security.KeyPairGenerator; import java.security.NoSuchProviderException; import java.security.Security; import java.security.SignatureException; import java.util.Date; import org.bouncycastle.bcpg.ArmoredOutputStream; import org.bouncycastle.bcpg.HashAlgorithmTags; import org.bouncycastle.jce.provider.BouncyCastleProvider; import org.bouncycastle.jce.spec.ElGamalParameterSpec; import org.bouncycastle.openpgp.PGPEncryptedData; import org.bouncycastle.openpgp.PGPException; import org.bouncycastle.openpgp.PGPKeyPair; import org.bouncycastle.openpgp.PGPKeyRingGenerator; import org.bouncycastle.openpgp.PGPPublicKey; import org.bouncycastle.openpgp.PGPSignature; import org.bouncycastle.openpgp.operator.PGPDigestCalculator; import org.bouncycastle.openpgp.operator.jcajce.JcaPGPContentSignerBuilder; import org.bouncycastle.openpgp.operator.jcajce.JcaPGPDigestCalculatorProviderBuilder; import org.bouncycastle.openpgp.operator.jcajce.JcaPGPKeyPair; import org.bouncycastle.openpgp.operator.jcajce.JcePBESecretKeyEncryptorBuilder; /** * A simple utility class that generates a public/secret keyring containing a DSA signing * key and an El Gamal key for encryption. *

    * usage: DSAElGamalKeyRingGenerator [-a] identity passPhrase *

    * Where identity is the name to be associated with the public key. The keys are placed * in the files pub.[asc|bpg] and secret.[asc|bpg]. *

    * Note: this example encrypts the secret key using AES_256, many PGP products still * do not support this, if you are having problems importing keys try changing the algorithm * id to PGPEncryptedData.CAST5. CAST5 is more widely supported. */ public class DSAElGamalKeyRingGenerator { private static void exportKeyPair( OutputStream secretOut, OutputStream publicOut, KeyPair dsaKp, KeyPair elgKp, String identity, char[] passPhrase, boolean armor) throws IOException, InvalidKeyException, NoSuchProviderException, SignatureException, PGPException { if (armor) { secretOut = new ArmoredOutputStream(secretOut); } PGPKeyPair dsaKeyPair = new JcaPGPKeyPair(PGPPublicKey.DSA, dsaKp, new Date()); PGPKeyPair elgKeyPair = new JcaPGPKeyPair(PGPPublicKey.ELGAMAL_ENCRYPT, elgKp, new Date()); PGPDigestCalculator sha1Calc = new JcaPGPDigestCalculatorProviderBuilder().build().get(HashAlgorithmTags.SHA1); PGPKeyRingGenerator keyRingGen = new PGPKeyRingGenerator(PGPSignature.POSITIVE_CERTIFICATION, dsaKeyPair, identity, sha1Calc, null, null, new JcaPGPContentSignerBuilder(dsaKeyPair.getPublicKey().getAlgorithm(), HashAlgorithmTags.SHA1), new JcePBESecretKeyEncryptorBuilder(PGPEncryptedData.AES_256, sha1Calc).setProvider("BC").build(passPhrase)); keyRingGen.addSubKey(elgKeyPair); keyRingGen.generateSecretKeyRing().encode(secretOut); secretOut.close(); if (armor) { publicOut = new ArmoredOutputStream(publicOut); } keyRingGen.generatePublicKeyRing().encode(publicOut); publicOut.close(); } public static void main( String[] args) throws Exception { Security.addProvider(new BouncyCastleProvider()); if (args.length < 2) { System.out.println("DSAElGamalKeyRingGenerator [-a] identity passPhrase"); System.exit(0); } KeyPairGenerator dsaKpg = KeyPairGenerator.getInstance("DSA", "BC"); dsaKpg.initialize(1024); // // this takes a while as the key generator has to generate some DSA params // before it generates the key. // KeyPair dsaKp = dsaKpg.generateKeyPair(); KeyPairGenerator elgKpg = KeyPairGenerator.getInstance("ELGAMAL", "BC"); BigInteger g = new BigInteger("153d5d6172adb43045b68ae8e1de1070b6137005686d29d3d73a7749199681ee5b212c9b96bfdcfa5b20cd5e3fd2044895d609cf9b410b7a0f12ca1cb9a428cc", 16); BigInteger p = new BigInteger("9494fec095f3b85ee286542b3836fc81a5dd0a0349b4c239dd38744d488cf8e31db8bcb7d33b41abb9e5a33cca9144b1cef332c94bf0573bf047a3aca98cdf3b", 16); ElGamalParameterSpec elParams = new ElGamalParameterSpec(p, g); elgKpg.initialize(elParams); // // this is quicker because we are using pregenerated parameters. // KeyPair elgKp = elgKpg.generateKeyPair(); if (args[0].equals("-a")) { if (args.length < 3) { System.out.println("DSAElGamalKeyRingGenerator [-a] identity passPhrase"); System.exit(0); } FileOutputStream out1 = new FileOutputStream("secret.asc"); FileOutputStream out2 = new FileOutputStream("pub.asc"); exportKeyPair(out1, out2, dsaKp, elgKp, args[1], args[2].toCharArray(), true); } else { FileOutputStream out1 = new FileOutputStream("secret.bpg"); FileOutputStream out2 = new FileOutputStream("pub.bpg"); exportKeyPair(out1, out2, dsaKp, elgKp, args[0], args[1].toCharArray(), false); } } } bouncycastle-1.49.orig/src/org/bouncycastle/openpgp/examples/PGPExampleUtil.java0000644000175000017500000001212511527114063027434 0ustar ebourgebourgpackage org.bouncycastle.openpgp.examples; import java.io.BufferedInputStream; import java.io.ByteArrayOutputStream; import java.io.File; import java.io.FileInputStream; import java.io.IOException; import java.io.InputStream; import java.security.NoSuchProviderException; import java.util.Iterator; import org.bouncycastle.openpgp.PGPCompressedDataGenerator; import org.bouncycastle.openpgp.PGPException; import org.bouncycastle.openpgp.PGPLiteralData; import org.bouncycastle.openpgp.PGPPrivateKey; import org.bouncycastle.openpgp.PGPPublicKey; import org.bouncycastle.openpgp.PGPPublicKeyRing; import org.bouncycastle.openpgp.PGPPublicKeyRingCollection; import org.bouncycastle.openpgp.PGPSecretKey; import org.bouncycastle.openpgp.PGPSecretKeyRing; import org.bouncycastle.openpgp.PGPSecretKeyRingCollection; import org.bouncycastle.openpgp.PGPUtil; class PGPExampleUtil { static byte[] compressFile(String fileName, int algorithm) throws IOException { ByteArrayOutputStream bOut = new ByteArrayOutputStream(); PGPCompressedDataGenerator comData = new PGPCompressedDataGenerator(algorithm); PGPUtil.writeFileToLiteralData(comData.open(bOut), PGPLiteralData.BINARY, new File(fileName)); comData.close(); return bOut.toByteArray(); } /** * Search a secret key ring collection for a secret key corresponding to keyID if it * exists. * * @param pgpSec a secret key ring collection. * @param keyID keyID we want. * @param pass passphrase to decrypt secret key with. * @return * @throws PGPException * @throws NoSuchProviderException */ static PGPPrivateKey findSecretKey(PGPSecretKeyRingCollection pgpSec, long keyID, char[] pass) throws PGPException, NoSuchProviderException { PGPSecretKey pgpSecKey = pgpSec.getSecretKey(keyID); if (pgpSecKey == null) { return null; } return pgpSecKey.extractPrivateKey(pass, "BC"); } static PGPPublicKey readPublicKey(String fileName) throws IOException, PGPException { InputStream keyIn = new BufferedInputStream(new FileInputStream(fileName)); PGPPublicKey pubKey = readPublicKey(keyIn); keyIn.close(); return pubKey; } /** * A simple routine that opens a key ring file and loads the first available key * suitable for encryption. * * @param input * @return * @throws IOException * @throws PGPException */ static PGPPublicKey readPublicKey(InputStream input) throws IOException, PGPException { PGPPublicKeyRingCollection pgpPub = new PGPPublicKeyRingCollection( PGPUtil.getDecoderStream(input)); // // we just loop through the collection till we find a key suitable for encryption, in the real // world you would probably want to be a bit smarter about this. // Iterator keyRingIter = pgpPub.getKeyRings(); while (keyRingIter.hasNext()) { PGPPublicKeyRing keyRing = (PGPPublicKeyRing)keyRingIter.next(); Iterator keyIter = keyRing.getPublicKeys(); while (keyIter.hasNext()) { PGPPublicKey key = (PGPPublicKey)keyIter.next(); if (key.isEncryptionKey()) { return key; } } } throw new IllegalArgumentException("Can't find encryption key in key ring."); } static PGPSecretKey readSecretKey(String fileName) throws IOException, PGPException { InputStream keyIn = new BufferedInputStream(new FileInputStream(fileName)); PGPSecretKey secKey = readSecretKey(keyIn); keyIn.close(); return secKey; } /** * A simple routine that opens a key ring file and loads the first available key * suitable for signature generation. * * @param input stream to read the secret key ring collection from. * @return a secret key. * @throws IOException on a problem with using the input stream. * @throws PGPException if there is an issue parsing the input stream. */ static PGPSecretKey readSecretKey(InputStream input) throws IOException, PGPException { PGPSecretKeyRingCollection pgpSec = new PGPSecretKeyRingCollection( PGPUtil.getDecoderStream(input)); // // we just loop through the collection till we find a key suitable for encryption, in the real // world you would probably want to be a bit smarter about this. // Iterator keyRingIter = pgpSec.getKeyRings(); while (keyRingIter.hasNext()) { PGPSecretKeyRing keyRing = (PGPSecretKeyRing)keyRingIter.next(); Iterator keyIter = keyRing.getSecretKeys(); while (keyIter.hasNext()) { PGPSecretKey key = (PGPSecretKey)keyIter.next(); if (key.isSigningKey()) { return key; } } } throw new IllegalArgumentException("Can't find signing key in key ring."); } } bouncycastle-1.49.orig/src/org/bouncycastle/openpgp/examples/PBEFileProcessor.java0000644000175000017500000001615411706144225027752 0ustar ebourgebourgpackage org.bouncycastle.openpgp.examples; import java.io.BufferedInputStream; import java.io.BufferedOutputStream; import java.io.FileInputStream; import java.io.FileOutputStream; import java.io.IOException; import java.io.InputStream; import java.io.OutputStream; import java.security.NoSuchProviderException; import java.security.SecureRandom; import java.security.Security; import org.bouncycastle.bcpg.ArmoredOutputStream; import org.bouncycastle.bcpg.CompressionAlgorithmTags; import org.bouncycastle.jce.provider.BouncyCastleProvider; import org.bouncycastle.openpgp.PGPCompressedData; import org.bouncycastle.openpgp.PGPEncryptedData; import org.bouncycastle.openpgp.PGPEncryptedDataGenerator; import org.bouncycastle.openpgp.PGPEncryptedDataList; import org.bouncycastle.openpgp.PGPException; import org.bouncycastle.openpgp.PGPLiteralData; import org.bouncycastle.openpgp.PGPObjectFactory; import org.bouncycastle.openpgp.PGPPBEEncryptedData; import org.bouncycastle.openpgp.PGPUtil; import org.bouncycastle.openpgp.operator.jcajce.JcaPGPDigestCalculatorProviderBuilder; import org.bouncycastle.openpgp.operator.jcajce.JcePBEDataDecryptorFactoryBuilder; import org.bouncycastle.openpgp.operator.jcajce.JcePBEKeyEncryptionMethodGenerator; import org.bouncycastle.openpgp.operator.jcajce.JcePGPDataEncryptorBuilder; import org.bouncycastle.util.io.Streams; /** * A simple utility class that encrypts/decrypts password based * encryption files. *

    * To encrypt a file: PBEFileProcessor -e [-ai] fileName passPhrase.
    * If -a is specified the output file will be "ascii-armored".
    * If -i is specified the output file will be "integrity protected". *

    * To decrypt: PBEFileProcessor -d fileName passPhrase. *

    * Note: this example will silently overwrite files, nor does it pay any attention to * the specification of "_CONSOLE" in the filename. It also expects that a single pass phrase * will have been used. */ public class PBEFileProcessor { private static void decryptFile(String inputFileName, char[] passPhrase) throws IOException, NoSuchProviderException, PGPException { InputStream in = new BufferedInputStream(new FileInputStream(inputFileName)); decryptFile(in, passPhrase); in.close(); } /* * decrypt the passed in message stream */ private static void decryptFile( InputStream in, char[] passPhrase) throws IOException, NoSuchProviderException, PGPException { in = PGPUtil.getDecoderStream(in); PGPObjectFactory pgpF = new PGPObjectFactory(in); PGPEncryptedDataList enc; Object o = pgpF.nextObject(); // // the first object might be a PGP marker packet. // if (o instanceof PGPEncryptedDataList) { enc = (PGPEncryptedDataList)o; } else { enc = (PGPEncryptedDataList)pgpF.nextObject(); } PGPPBEEncryptedData pbe = (PGPPBEEncryptedData)enc.get(0); InputStream clear = pbe.getDataStream(new JcePBEDataDecryptorFactoryBuilder(new JcaPGPDigestCalculatorProviderBuilder().setProvider("BC").build()).setProvider("BC").build(passPhrase)); PGPObjectFactory pgpFact = new PGPObjectFactory(clear); // // if we're trying to read a file generated by someone other than us // the data might not be compressed, so we check the return type from // the factory and behave accordingly. // o = pgpFact.nextObject(); if (o instanceof PGPCompressedData) { PGPCompressedData cData = (PGPCompressedData)o; pgpFact = new PGPObjectFactory(cData.getDataStream()); o = pgpFact.nextObject(); } PGPLiteralData ld = (PGPLiteralData)o; InputStream unc = ld.getInputStream(); OutputStream fOut = new BufferedOutputStream(new FileOutputStream(ld.getFileName())); Streams.pipeAll(unc, fOut); fOut.close(); if (pbe.isIntegrityProtected()) { if (!pbe.verify()) { System.err.println("message failed integrity check"); } else { System.err.println("message integrity check passed"); } } else { System.err.println("no message integrity check"); } } private static void encryptFile( String outputFileName, String inputFileName, char[] passPhrase, boolean armor, boolean withIntegrityCheck) throws IOException, NoSuchProviderException { OutputStream out = new BufferedOutputStream(new FileOutputStream(outputFileName)); encryptFile(out, inputFileName, passPhrase, armor, withIntegrityCheck); out.close(); } private static void encryptFile( OutputStream out, String fileName, char[] passPhrase, boolean armor, boolean withIntegrityCheck) throws IOException, NoSuchProviderException { if (armor) { out = new ArmoredOutputStream(out); } try { byte[] compressedData = PGPExampleUtil.compressFile(fileName, CompressionAlgorithmTags.ZIP); PGPEncryptedDataGenerator encGen = new PGPEncryptedDataGenerator(new JcePGPDataEncryptorBuilder(PGPEncryptedData.CAST5) .setWithIntegrityPacket(withIntegrityCheck).setSecureRandom(new SecureRandom()).setProvider("BC")); encGen.addMethod(new JcePBEKeyEncryptionMethodGenerator(passPhrase).setProvider("BC")); OutputStream encOut = encGen.open(out, compressedData.length); encOut.write(compressedData); encOut.close(); if (armor) { out.close(); } } catch (PGPException e) { System.err.println(e); if (e.getUnderlyingException() != null) { e.getUnderlyingException().printStackTrace(); } } } public static void main( String[] args) throws Exception { Security.addProvider(new BouncyCastleProvider()); if (args[0].equals("-e")) { if (args[1].equals("-a") || args[1].equals("-ai") || args[1].equals("-ia")) { encryptFile(args[2] + ".asc", args[2], args[3].toCharArray(), true, (args[1].indexOf('i') > 0)); } else if (args[1].equals("-i")) { encryptFile(args[2] + ".bpg", args[2], args[3].toCharArray(), false, true); } else { encryptFile(args[1] + ".bpg", args[1], args[2].toCharArray(), false, false); } } else if (args[0].equals("-d")) { decryptFile(args[1], args[2].toCharArray()); } else { System.err.println("usage: PBEFileProcessor -e [-ai]|-d file passPhrase"); } } } bouncycastle-1.49.orig/src/org/bouncycastle/openpgp/examples/KeyBasedFileProcessor.java0000644000175000017500000002314011576531772031040 0ustar ebourgebourgpackage org.bouncycastle.openpgp.examples; import java.io.BufferedInputStream; import java.io.BufferedOutputStream; import java.io.File; import java.io.FileInputStream; import java.io.FileOutputStream; import java.io.IOException; import java.io.InputStream; import java.io.OutputStream; import java.security.NoSuchProviderException; import java.security.SecureRandom; import java.security.Security; import java.util.Iterator; import org.bouncycastle.bcpg.ArmoredOutputStream; import org.bouncycastle.bcpg.CompressionAlgorithmTags; import org.bouncycastle.jce.provider.BouncyCastleProvider; import org.bouncycastle.openpgp.PGPCompressedData; import org.bouncycastle.openpgp.PGPEncryptedData; import org.bouncycastle.openpgp.PGPEncryptedDataGenerator; import org.bouncycastle.openpgp.PGPEncryptedDataList; import org.bouncycastle.openpgp.PGPException; import org.bouncycastle.openpgp.PGPLiteralData; import org.bouncycastle.openpgp.PGPObjectFactory; import org.bouncycastle.openpgp.PGPOnePassSignatureList; import org.bouncycastle.openpgp.PGPPrivateKey; import org.bouncycastle.openpgp.PGPPublicKey; import org.bouncycastle.openpgp.PGPPublicKeyEncryptedData; import org.bouncycastle.openpgp.PGPSecretKeyRingCollection; import org.bouncycastle.openpgp.PGPUtil; import org.bouncycastle.openpgp.operator.jcajce.JcePGPDataEncryptorBuilder; import org.bouncycastle.openpgp.operator.jcajce.JcePublicKeyDataDecryptorFactoryBuilder; import org.bouncycastle.openpgp.operator.jcajce.JcePublicKeyKeyEncryptionMethodGenerator; import org.bouncycastle.util.io.Streams; /** * A simple utility class that encrypts/decrypts public key based * encryption files. *

    * To encrypt a file: KeyBasedFileProcessor -e [-a|-ai] fileName publicKeyFile.
    * If -a is specified the output file will be "ascii-armored". * If -i is specified the output file will be have integrity checking added. *

    * To decrypt: KeyBasedFileProcessor -d fileName secretKeyFile passPhrase. *

    * Note 1: this example will silently overwrite files, nor does it pay any attention to * the specification of "_CONSOLE" in the filename. It also expects that a single pass phrase * will have been used. *

    * Note 2: if an empty file name has been specified in the literal data object contained in the * encrypted packet a file with the name filename.out will be generated in the current working directory. */ public class KeyBasedFileProcessor { private static void decryptFile( String inputFileName, String keyFileName, char[] passwd, String defaultFileName) throws IOException, NoSuchProviderException { InputStream in = new BufferedInputStream(new FileInputStream(inputFileName)); InputStream keyIn = new BufferedInputStream(new FileInputStream(keyFileName)); decryptFile(in, keyIn, passwd, defaultFileName); keyIn.close(); in.close(); } /** * decrypt the passed in message stream */ private static void decryptFile( InputStream in, InputStream keyIn, char[] passwd, String defaultFileName) throws IOException, NoSuchProviderException { in = PGPUtil.getDecoderStream(in); try { PGPObjectFactory pgpF = new PGPObjectFactory(in); PGPEncryptedDataList enc; Object o = pgpF.nextObject(); // // the first object might be a PGP marker packet. // if (o instanceof PGPEncryptedDataList) { enc = (PGPEncryptedDataList)o; } else { enc = (PGPEncryptedDataList)pgpF.nextObject(); } // // find the secret key // Iterator it = enc.getEncryptedDataObjects(); PGPPrivateKey sKey = null; PGPPublicKeyEncryptedData pbe = null; PGPSecretKeyRingCollection pgpSec = new PGPSecretKeyRingCollection( PGPUtil.getDecoderStream(keyIn)); while (sKey == null && it.hasNext()) { pbe = (PGPPublicKeyEncryptedData)it.next(); sKey = PGPExampleUtil.findSecretKey(pgpSec, pbe.getKeyID(), passwd); } if (sKey == null) { throw new IllegalArgumentException("secret key for message not found."); } InputStream clear = pbe.getDataStream(new JcePublicKeyDataDecryptorFactoryBuilder().setProvider("BC").build(sKey)); PGPObjectFactory plainFact = new PGPObjectFactory(clear); Object message = plainFact.nextObject(); if (message instanceof PGPCompressedData) { PGPCompressedData cData = (PGPCompressedData)message; PGPObjectFactory pgpFact = new PGPObjectFactory(cData.getDataStream()); message = pgpFact.nextObject(); } if (message instanceof PGPLiteralData) { PGPLiteralData ld = (PGPLiteralData)message; String outFileName = ld.getFileName(); if (outFileName.length() == 0) { outFileName = defaultFileName; } InputStream unc = ld.getInputStream(); OutputStream fOut = new BufferedOutputStream(new FileOutputStream(outFileName)); Streams.pipeAll(unc, fOut); fOut.close(); } else if (message instanceof PGPOnePassSignatureList) { throw new PGPException("encrypted message contains a signed message - not literal data."); } else { throw new PGPException("message is not a simple encrypted file - type unknown."); } if (pbe.isIntegrityProtected()) { if (!pbe.verify()) { System.err.println("message failed integrity check"); } else { System.err.println("message integrity check passed"); } } else { System.err.println("no message integrity check"); } } catch (PGPException e) { System.err.println(e); if (e.getUnderlyingException() != null) { e.getUnderlyingException().printStackTrace(); } } } private static void encryptFile( String outputFileName, String inputFileName, String encKeyFileName, boolean armor, boolean withIntegrityCheck) throws IOException, NoSuchProviderException, PGPException { OutputStream out = new BufferedOutputStream(new FileOutputStream(outputFileName)); PGPPublicKey encKey = PGPExampleUtil.readPublicKey(encKeyFileName); encryptFile(out, inputFileName, encKey, armor, withIntegrityCheck); out.close(); } private static void encryptFile( OutputStream out, String fileName, PGPPublicKey encKey, boolean armor, boolean withIntegrityCheck) throws IOException, NoSuchProviderException { if (armor) { out = new ArmoredOutputStream(out); } try { byte[] bytes = PGPExampleUtil.compressFile(fileName, CompressionAlgorithmTags.ZIP); PGPEncryptedDataGenerator encGen = new PGPEncryptedDataGenerator( new JcePGPDataEncryptorBuilder(PGPEncryptedData.CAST5).setWithIntegrityPacket(withIntegrityCheck).setSecureRandom(new SecureRandom()).setProvider("BC")); encGen.addMethod(new JcePublicKeyKeyEncryptionMethodGenerator(encKey).setProvider("BC")); OutputStream cOut = encGen.open(out, bytes.length); cOut.write(bytes); cOut.close(); if (armor) { out.close(); } } catch (PGPException e) { System.err.println(e); if (e.getUnderlyingException() != null) { e.getUnderlyingException().printStackTrace(); } } } public static void main( String[] args) throws Exception { Security.addProvider(new BouncyCastleProvider()); if (args.length == 0) { System.err.println("usage: KeyBasedFileProcessor -e|-d [-a|ai] file [secretKeyFile passPhrase|pubKeyFile]"); return; } if (args[0].equals("-e")) { if (args[1].equals("-a") || args[1].equals("-ai") || args[1].equals("-ia")) { encryptFile(args[2] + ".asc", args[2], args[3], true, (args[1].indexOf('i') > 0)); } else if (args[1].equals("-i")) { encryptFile(args[2] + ".bpg", args[2], args[3], false, true); } else { encryptFile(args[1] + ".bpg", args[1], args[2], false, false); } } else if (args[0].equals("-d")) { decryptFile(args[1], args[2], args[3].toCharArray(), new File(args[1]).getName() + ".out"); } else { System.err.println("usage: KeyBasedFileProcessor -d|-e [-a|ai] file [secretKeyFile passPhrase|pubKeyFile]"); } } } bouncycastle-1.49.orig/src/org/bouncycastle/openpgp/examples/PubringDump.java0000644000175000017500000000607310707650230027075 0ustar ebourgebourgpackage org.bouncycastle.openpgp.examples; import java.io.*; import java.security.Security; import java.util.Iterator; import org.bouncycastle.bcpg.PublicKeyAlgorithmTags; import org.bouncycastle.jce.provider.BouncyCastleProvider; import org.bouncycastle.openpgp.PGPPublicKey; import org.bouncycastle.openpgp.PGPPublicKeyRing; import org.bouncycastle.openpgp.PGPPublicKeyRingCollection; import org.bouncycastle.openpgp.PGPUtil; import org.bouncycastle.util.encoders.Hex; /** * Basic class which just lists the contents of the public key file passed * as an argument. If the file contains more than one "key ring" they are * listed in the order found. */ public class PubringDump { public static String getAlgorithm( int algId) { switch (algId) { case PublicKeyAlgorithmTags.RSA_GENERAL: return "RSA_GENERAL"; case PublicKeyAlgorithmTags.RSA_ENCRYPT: return "RSA_ENCRYPT"; case PublicKeyAlgorithmTags.RSA_SIGN: return "RSA_SIGN"; case PublicKeyAlgorithmTags.ELGAMAL_ENCRYPT: return "ELGAMAL_ENCRYPT"; case PublicKeyAlgorithmTags.DSA: return "DSA"; case PublicKeyAlgorithmTags.EC: return "EC"; case PublicKeyAlgorithmTags.ECDSA: return "ECDSA"; case PublicKeyAlgorithmTags.ELGAMAL_GENERAL: return "ELGAMAL_GENERAL"; case PublicKeyAlgorithmTags.DIFFIE_HELLMAN: return "DIFFIE_HELLMAN"; } return "unknown"; } public static void main(String[] args) throws Exception { Security.addProvider(new BouncyCastleProvider()); PGPUtil.setDefaultProvider("BC"); // // Read the public key rings // PGPPublicKeyRingCollection pubRings = new PGPPublicKeyRingCollection( PGPUtil.getDecoderStream(new FileInputStream(args[0]))); Iterator rIt = pubRings.getKeyRings(); while (rIt.hasNext()) { PGPPublicKeyRing pgpPub = (PGPPublicKeyRing)rIt.next(); try { pgpPub.getPublicKey(); } catch (Exception e) { e.printStackTrace(); continue; } Iterator it = pgpPub.getPublicKeys(); boolean first = true; while (it.hasNext()) { PGPPublicKey pgpKey = (PGPPublicKey)it.next(); if (first) { System.out.println("Key ID: " + Long.toHexString(pgpKey.getKeyID())); first = false; } else { System.out.println("Key ID: " + Long.toHexString(pgpKey.getKeyID()) + " (subkey)"); } System.out.println(" Algorithm: " + getAlgorithm(pgpKey.getAlgorithm())); System.out.println(" Fingerprint: " + new String(Hex.encode(pgpKey.getFingerprint()))); } } } } bouncycastle-1.49.orig/src/org/bouncycastle/openpgp/examples/SignedFileProcessor.java0000644000175000017500000001712411706144225030553 0ustar ebourgebourgpackage org.bouncycastle.openpgp.examples; import java.io.File; import java.io.FileInputStream; import java.io.FileOutputStream; import java.io.IOException; import java.io.InputStream; import java.io.OutputStream; import java.security.NoSuchAlgorithmException; import java.security.NoSuchProviderException; import java.security.Security; import java.security.SignatureException; import java.util.Iterator; import org.bouncycastle.bcpg.ArmoredOutputStream; import org.bouncycastle.bcpg.BCPGOutputStream; import org.bouncycastle.jce.provider.BouncyCastleProvider; import org.bouncycastle.openpgp.PGPCompressedData; import org.bouncycastle.openpgp.PGPCompressedDataGenerator; import org.bouncycastle.openpgp.PGPException; import org.bouncycastle.openpgp.PGPLiteralData; import org.bouncycastle.openpgp.PGPLiteralDataGenerator; import org.bouncycastle.openpgp.PGPObjectFactory; import org.bouncycastle.openpgp.PGPOnePassSignature; import org.bouncycastle.openpgp.PGPOnePassSignatureList; import org.bouncycastle.openpgp.PGPPrivateKey; import org.bouncycastle.openpgp.PGPPublicKey; import org.bouncycastle.openpgp.PGPPublicKeyRingCollection; import org.bouncycastle.openpgp.PGPSecretKey; import org.bouncycastle.openpgp.PGPSignature; import org.bouncycastle.openpgp.PGPSignatureGenerator; import org.bouncycastle.openpgp.PGPSignatureList; import org.bouncycastle.openpgp.PGPSignatureSubpacketGenerator; import org.bouncycastle.openpgp.PGPUtil; import org.bouncycastle.openpgp.operator.jcajce.JcaPGPContentSignerBuilder; import org.bouncycastle.openpgp.operator.jcajce.JcaPGPContentVerifierBuilderProvider; import org.bouncycastle.openpgp.operator.jcajce.JcePBESecretKeyDecryptorBuilder; /** * A simple utility class that signs and verifies files. *

    * To sign a file: SignedFileProcessor -s [-a] fileName secretKey passPhrase.
    * If -a is specified the output file will be "ascii-armored". *

    * To decrypt: SignedFileProcessor -v fileName publicKeyFile. *

    * Note: this example will silently overwrite files, nor does it pay any attention to * the specification of "_CONSOLE" in the filename. It also expects that a single pass phrase * will have been used. *

    * Note: the example also makes use of PGP compression. If you are having difficulty getting it * to interoperate with other PGP programs try removing the use of compression first. */ public class SignedFileProcessor { /* * verify the passed in file as being correctly signed. */ private static void verifyFile( InputStream in, InputStream keyIn) throws Exception { in = PGPUtil.getDecoderStream(in); PGPObjectFactory pgpFact = new PGPObjectFactory(in); PGPCompressedData c1 = (PGPCompressedData)pgpFact.nextObject(); pgpFact = new PGPObjectFactory(c1.getDataStream()); PGPOnePassSignatureList p1 = (PGPOnePassSignatureList)pgpFact.nextObject(); PGPOnePassSignature ops = p1.get(0); PGPLiteralData p2 = (PGPLiteralData)pgpFact.nextObject(); InputStream dIn = p2.getInputStream(); int ch; PGPPublicKeyRingCollection pgpRing = new PGPPublicKeyRingCollection(PGPUtil.getDecoderStream(keyIn)); PGPPublicKey key = pgpRing.getPublicKey(ops.getKeyID()); FileOutputStream out = new FileOutputStream(p2.getFileName()); ops.init(new JcaPGPContentVerifierBuilderProvider().setProvider("BC"), key); while ((ch = dIn.read()) >= 0) { ops.update((byte)ch); out.write(ch); } out.close(); PGPSignatureList p3 = (PGPSignatureList)pgpFact.nextObject(); if (ops.verify(p3.get(0))) { System.out.println("signature verified."); } else { System.out.println("signature verification failed."); } } /** * Generate an encapsulated signed file. * * @param fileName * @param keyIn * @param out * @param pass * @param armor * @throws IOException * @throws NoSuchAlgorithmException * @throws NoSuchProviderException * @throws PGPException * @throws SignatureException */ private static void signFile( String fileName, InputStream keyIn, OutputStream out, char[] pass, boolean armor) throws IOException, NoSuchAlgorithmException, NoSuchProviderException, PGPException, SignatureException { if (armor) { out = new ArmoredOutputStream(out); } PGPSecretKey pgpSec = PGPExampleUtil.readSecretKey(keyIn); PGPPrivateKey pgpPrivKey = pgpSec.extractPrivateKey(new JcePBESecretKeyDecryptorBuilder().setProvider("BC").build(pass)); PGPSignatureGenerator sGen = new PGPSignatureGenerator(new JcaPGPContentSignerBuilder(pgpSec.getPublicKey().getAlgorithm(), PGPUtil.SHA1).setProvider("BC")); sGen.init(PGPSignature.BINARY_DOCUMENT, pgpPrivKey); Iterator it = pgpSec.getPublicKey().getUserIDs(); if (it.hasNext()) { PGPSignatureSubpacketGenerator spGen = new PGPSignatureSubpacketGenerator(); spGen.setSignerUserID(false, (String)it.next()); sGen.setHashedSubpackets(spGen.generate()); } PGPCompressedDataGenerator cGen = new PGPCompressedDataGenerator( PGPCompressedData.ZLIB); BCPGOutputStream bOut = new BCPGOutputStream(cGen.open(out)); sGen.generateOnePassVersion(false).encode(bOut); File file = new File(fileName); PGPLiteralDataGenerator lGen = new PGPLiteralDataGenerator(); OutputStream lOut = lGen.open(bOut, PGPLiteralData.BINARY, file); FileInputStream fIn = new FileInputStream(file); int ch; while ((ch = fIn.read()) >= 0) { lOut.write(ch); sGen.update((byte)ch); } lGen.close(); sGen.generate().encode(bOut); cGen.close(); if (armor) { out.close(); } } public static void main( String[] args) throws Exception { Security.addProvider(new BouncyCastleProvider()); if (args[0].equals("-s")) { if (args[1].equals("-a")) { FileInputStream keyIn = new FileInputStream(args[3]); FileOutputStream out = new FileOutputStream(args[2] + ".asc"); signFile(args[2], keyIn, out, args[4].toCharArray(), true); } else { FileInputStream keyIn = new FileInputStream(args[2]); FileOutputStream out = new FileOutputStream(args[1] + ".bpg"); signFile(args[1], keyIn, out, args[3].toCharArray(), false); } } else if (args[0].equals("-v")) { FileInputStream in = new FileInputStream(args[1]); FileInputStream keyIn = new FileInputStream(args[2]); verifyFile(in, keyIn); } else { System.err.println("usage: SignedFileProcessor -v|-s [-a] file keyfile [passPhrase]"); } } }bouncycastle-1.49.orig/src/org/bouncycastle/openpgp/examples/DetachedSignatureProcessor.java0000644000175000017500000001451211616402450032120 0ustar ebourgebourgpackage org.bouncycastle.openpgp.examples; import java.io.BufferedInputStream; import java.io.BufferedOutputStream; import java.io.FileInputStream; import java.io.FileOutputStream; import java.io.IOException; import java.io.InputStream; import java.io.OutputStream; import java.security.GeneralSecurityException; import java.security.Security; import org.bouncycastle.bcpg.ArmoredOutputStream; import org.bouncycastle.bcpg.BCPGOutputStream; import org.bouncycastle.jce.provider.BouncyCastleProvider; import org.bouncycastle.openpgp.PGPCompressedData; import org.bouncycastle.openpgp.PGPException; import org.bouncycastle.openpgp.PGPObjectFactory; import org.bouncycastle.openpgp.PGPPrivateKey; import org.bouncycastle.openpgp.PGPPublicKey; import org.bouncycastle.openpgp.PGPPublicKeyRingCollection; import org.bouncycastle.openpgp.PGPSecretKey; import org.bouncycastle.openpgp.PGPSignature; import org.bouncycastle.openpgp.PGPSignatureGenerator; import org.bouncycastle.openpgp.PGPSignatureList; import org.bouncycastle.openpgp.PGPUtil; import org.bouncycastle.openpgp.operator.jcajce.JcaPGPContentSignerBuilder; import org.bouncycastle.openpgp.operator.jcajce.JcaPGPContentVerifierBuilderProvider; import org.bouncycastle.openpgp.operator.jcajce.JcePBESecretKeyDecryptorBuilder; /** * A simple utility class that creates seperate signatures for files and verifies them. *

    * To sign a file: DetachedSignatureProcessor -s [-a] fileName secretKey passPhrase.
    * If -a is specified the output file will be "ascii-armored". *

    * To decrypt: DetachedSignatureProcessor -v fileName signatureFile publicKeyFile. *

    * Note: this example will silently overwrite files. * It also expects that a single pass phrase * will have been used. */ public class DetachedSignatureProcessor { private static void verifySignature( String fileName, String inputFileName, String keyFileName) throws GeneralSecurityException, IOException, PGPException { InputStream in = new BufferedInputStream(new FileInputStream(inputFileName)); InputStream keyIn = new BufferedInputStream(new FileInputStream(keyFileName)); verifySignature(fileName, in, keyIn); keyIn.close(); in.close(); } /* * verify the signature in in against the file fileName. */ private static void verifySignature( String fileName, InputStream in, InputStream keyIn) throws GeneralSecurityException, IOException, PGPException { in = PGPUtil.getDecoderStream(in); PGPObjectFactory pgpFact = new PGPObjectFactory(in); PGPSignatureList p3; Object o = pgpFact.nextObject(); if (o instanceof PGPCompressedData) { PGPCompressedData c1 = (PGPCompressedData)o; pgpFact = new PGPObjectFactory(c1.getDataStream()); p3 = (PGPSignatureList)pgpFact.nextObject(); } else { p3 = (PGPSignatureList)o; } PGPPublicKeyRingCollection pgpPubRingCollection = new PGPPublicKeyRingCollection(PGPUtil.getDecoderStream(keyIn)); InputStream dIn = new BufferedInputStream(new FileInputStream(fileName)); PGPSignature sig = p3.get(0); PGPPublicKey key = pgpPubRingCollection.getPublicKey(sig.getKeyID()); sig.init(new JcaPGPContentVerifierBuilderProvider().setProvider("BC"), key); int ch; while ((ch = dIn.read()) >= 0) { sig.update((byte)ch); } dIn.close(); if (sig.verify()) { System.out.println("signature verified."); } else { System.out.println("signature verification failed."); } } private static void createSignature( String inputFileName, String keyFileName, String outputFileName, char[] pass, boolean armor) throws GeneralSecurityException, IOException, PGPException { InputStream keyIn = new BufferedInputStream(new FileInputStream(keyFileName)); OutputStream out = new BufferedOutputStream(new FileOutputStream(outputFileName)); createSignature(inputFileName, keyIn, out, pass, armor); out.close(); keyIn.close(); } private static void createSignature( String fileName, InputStream keyIn, OutputStream out, char[] pass, boolean armor) throws GeneralSecurityException, IOException, PGPException { if (armor) { out = new ArmoredOutputStream(out); } PGPSecretKey pgpSec = PGPExampleUtil.readSecretKey(keyIn); PGPPrivateKey pgpPrivKey = pgpSec.extractPrivateKey(new JcePBESecretKeyDecryptorBuilder().setProvider("BC").build(pass)); PGPSignatureGenerator sGen = new PGPSignatureGenerator(new JcaPGPContentSignerBuilder(pgpSec.getPublicKey().getAlgorithm(), PGPUtil.SHA1).setProvider("BC")); sGen.init(PGPSignature.BINARY_DOCUMENT, pgpPrivKey); BCPGOutputStream bOut = new BCPGOutputStream(out); InputStream fIn = new BufferedInputStream(new FileInputStream(fileName)); int ch; while ((ch = fIn.read()) >= 0) { sGen.update((byte)ch); } fIn.close(); sGen.generate().encode(bOut); if (armor) { out.close(); } } public static void main( String[] args) throws Exception { Security.addProvider(new BouncyCastleProvider()); if (args[0].equals("-s")) { if (args[1].equals("-a")) { createSignature(args[2], args[3], args[2] + ".asc", args[4].toCharArray(), true); } else { createSignature(args[1], args[2], args[1] + ".bpg", args[3].toCharArray(), false); } } else if (args[0].equals("-v")) { verifySignature(args[1], args[2], args[3]); } else { System.err.println("usage: DetachedSignatureProcessor [-s [-a] file keyfile passPhrase]|[-v file sigFile keyFile]"); } } } bouncycastle-1.49.orig/src/org/bouncycastle/openpgp/examples/KeyBasedLargeFileProcessor.java0000644000175000017500000002437111576531772032022 0ustar ebourgebourgpackage org.bouncycastle.openpgp.examples; import java.io.BufferedInputStream; import java.io.BufferedOutputStream; import java.io.File; import java.io.FileInputStream; import java.io.FileOutputStream; import java.io.IOException; import java.io.InputStream; import java.io.OutputStream; import java.security.NoSuchProviderException; import java.security.SecureRandom; import java.security.Security; import java.util.Iterator; import org.bouncycastle.bcpg.ArmoredOutputStream; import org.bouncycastle.jce.provider.BouncyCastleProvider; import org.bouncycastle.openpgp.PGPCompressedData; import org.bouncycastle.openpgp.PGPCompressedDataGenerator; import org.bouncycastle.openpgp.PGPEncryptedData; import org.bouncycastle.openpgp.PGPEncryptedDataGenerator; import org.bouncycastle.openpgp.PGPEncryptedDataList; import org.bouncycastle.openpgp.PGPException; import org.bouncycastle.openpgp.PGPLiteralData; import org.bouncycastle.openpgp.PGPObjectFactory; import org.bouncycastle.openpgp.PGPOnePassSignatureList; import org.bouncycastle.openpgp.PGPPrivateKey; import org.bouncycastle.openpgp.PGPPublicKey; import org.bouncycastle.openpgp.PGPPublicKeyEncryptedData; import org.bouncycastle.openpgp.PGPSecretKeyRingCollection; import org.bouncycastle.openpgp.PGPUtil; import org.bouncycastle.openpgp.operator.jcajce.JcePGPDataEncryptorBuilder; import org.bouncycastle.openpgp.operator.jcajce.JcePublicKeyDataDecryptorFactoryBuilder; import org.bouncycastle.openpgp.operator.jcajce.JcePublicKeyKeyEncryptionMethodGenerator; import org.bouncycastle.util.io.Streams; /** * A simple utility class that encrypts/decrypts public key based * encryption large files. *

    * To encrypt a file: KeyBasedLargeFileProcessor -e [-a|-ai] fileName publicKeyFile.
    * If -a is specified the output file will be "ascii-armored". * If -i is specified the output file will be have integrity checking added. *

    * To decrypt: KeyBasedLargeFileProcessor -d fileName secretKeyFile passPhrase. *

    * Note 1: this example will silently overwrite files, nor does it pay any attention to * the specification of "_CONSOLE" in the filename. It also expects that a single pass phrase * will have been used. *

    * Note 2: this example generates partial packets to encode the file, the output it generates * will not be readable by older PGP products or products that don't support partial packet * encoding. *

    * Note 3: if an empty file name has been specified in the literal data object contained in the * encrypted packet a file with the name filename.out will be generated in the current working directory. */ public class KeyBasedLargeFileProcessor { private static void decryptFile( String inputFileName, String keyFileName, char[] passwd, String defaultFileName) throws IOException, NoSuchProviderException { InputStream in = new BufferedInputStream(new FileInputStream(inputFileName)); InputStream keyIn = new BufferedInputStream(new FileInputStream(keyFileName)); decryptFile(in, keyIn, passwd, defaultFileName); keyIn.close(); in.close(); } /** * decrypt the passed in message stream */ private static void decryptFile( InputStream in, InputStream keyIn, char[] passwd, String defaultFileName) throws IOException, NoSuchProviderException { in = PGPUtil.getDecoderStream(in); try { PGPObjectFactory pgpF = new PGPObjectFactory(in); PGPEncryptedDataList enc; Object o = pgpF.nextObject(); // // the first object might be a PGP marker packet. // if (o instanceof PGPEncryptedDataList) { enc = (PGPEncryptedDataList)o; } else { enc = (PGPEncryptedDataList)pgpF.nextObject(); } // // find the secret key // Iterator it = enc.getEncryptedDataObjects(); PGPPrivateKey sKey = null; PGPPublicKeyEncryptedData pbe = null; PGPSecretKeyRingCollection pgpSec = new PGPSecretKeyRingCollection( PGPUtil.getDecoderStream(keyIn)); while (sKey == null && it.hasNext()) { pbe = (PGPPublicKeyEncryptedData)it.next(); sKey = PGPExampleUtil.findSecretKey(pgpSec, pbe.getKeyID(), passwd); } if (sKey == null) { throw new IllegalArgumentException("secret key for message not found."); } InputStream clear = pbe.getDataStream(new JcePublicKeyDataDecryptorFactoryBuilder().setProvider("BC").build(sKey)); PGPObjectFactory plainFact = new PGPObjectFactory(clear); PGPCompressedData cData = (PGPCompressedData)plainFact.nextObject(); InputStream compressedStream = new BufferedInputStream(cData.getDataStream()); PGPObjectFactory pgpFact = new PGPObjectFactory(compressedStream); Object message = pgpFact.nextObject(); if (message instanceof PGPLiteralData) { PGPLiteralData ld = (PGPLiteralData)message; String outFileName = ld.getFileName(); if (outFileName.length() == 0) { outFileName = defaultFileName; } InputStream unc = ld.getInputStream(); OutputStream fOut = new BufferedOutputStream(new FileOutputStream(outFileName)); Streams.pipeAll(unc, fOut); fOut.close(); } else if (message instanceof PGPOnePassSignatureList) { throw new PGPException("encrypted message contains a signed message - not literal data."); } else { throw new PGPException("message is not a simple encrypted file - type unknown."); } if (pbe.isIntegrityProtected()) { if (!pbe.verify()) { System.err.println("message failed integrity check"); } else { System.err.println("message integrity check passed"); } } else { System.err.println("no message integrity check"); } } catch (PGPException e) { System.err.println(e); if (e.getUnderlyingException() != null) { e.getUnderlyingException().printStackTrace(); } } } private static void encryptFile( String outputFileName, String inputFileName, String encKeyFileName, boolean armor, boolean withIntegrityCheck) throws IOException, NoSuchProviderException, PGPException { OutputStream out = new BufferedOutputStream(new FileOutputStream(outputFileName)); PGPPublicKey encKey = PGPExampleUtil.readPublicKey(encKeyFileName); encryptFile(out, inputFileName, encKey, armor, withIntegrityCheck); out.close(); } private static void encryptFile( OutputStream out, String fileName, PGPPublicKey encKey, boolean armor, boolean withIntegrityCheck) throws IOException, NoSuchProviderException { if (armor) { out = new ArmoredOutputStream(out); } try { PGPEncryptedDataGenerator cPk = new PGPEncryptedDataGenerator(new JcePGPDataEncryptorBuilder(PGPEncryptedData.CAST5).setWithIntegrityPacket(withIntegrityCheck).setSecureRandom(new SecureRandom()).setProvider("BC")); cPk.addMethod(new JcePublicKeyKeyEncryptionMethodGenerator(encKey).setProvider("BC")); OutputStream cOut = cPk.open(out, new byte[1 << 16]); PGPCompressedDataGenerator comData = new PGPCompressedDataGenerator( PGPCompressedData.ZIP); PGPUtil.writeFileToLiteralData(comData.open(cOut), PGPLiteralData.BINARY, new File(fileName), new byte[1 << 16]); comData.close(); cOut.close(); if (armor) { out.close(); } } catch (PGPException e) { System.err.println(e); if (e.getUnderlyingException() != null) { e.getUnderlyingException().printStackTrace(); } } } public static void main( String[] args) throws Exception { Security.addProvider(new BouncyCastleProvider()); if (args.length == 0) { System.err.println("usage: KeyBasedLargeFileProcessor -e|-d [-a|ai] file [secretKeyFile passPhrase|pubKeyFile]"); return; } if (args[0].equals("-e")) { if (args[1].equals("-a") || args[1].equals("-ai") || args[1].equals("-ia")) { encryptFile(args[2] + ".asc", args[2], args[3], true, (args[1].indexOf('i') > 0)); } else if (args[1].equals("-i")) { encryptFile(args[2] + ".bpg", args[2], args[3], false, true); } else { encryptFile(args[1] + ".bpg", args[1], args[2], false, false); } } else if (args[0].equals("-d")) { decryptFile(args[1], args[2], args[3].toCharArray(), new File(args[1]).getName() + ".out"); } else { System.err.println("usage: KeyBasedLargeFileProcessor -d|-e [-a|ai] file [secretKeyFile passPhrase|pubKeyFile]"); } } } bouncycastle-1.49.orig/src/org/bouncycastle/openpgp/examples/package.html0000644000175000017500000000015110262753174026255 0ustar ebourgebourg Examples of use of the org.bouncycastle.openpgp package. bouncycastle-1.49.orig/src/org/bouncycastle/openpgp/PGPKeyRingGenerator.java0000644000175000017500000002510111721612235026602 0ustar ebourgebourgpackage org.bouncycastle.openpgp; import java.security.NoSuchProviderException; import java.security.Provider; import java.security.SecureRandom; import java.util.ArrayList; import java.util.Iterator; import java.util.List; import org.bouncycastle.bcpg.HashAlgorithmTags; import org.bouncycastle.bcpg.PublicSubkeyPacket; import org.bouncycastle.openpgp.operator.PBESecretKeyEncryptor; import org.bouncycastle.openpgp.operator.PGPContentSignerBuilder; import org.bouncycastle.openpgp.operator.PGPDigestCalculator; import org.bouncycastle.openpgp.operator.jcajce.JcaPGPContentSignerBuilder; import org.bouncycastle.openpgp.operator.jcajce.JcaPGPDigestCalculatorProviderBuilder; import org.bouncycastle.openpgp.operator.jcajce.JcePBESecretKeyEncryptorBuilder; /** * Generator for a PGP master and subkey ring. This class will generate * both the secret and public key rings */ public class PGPKeyRingGenerator { List keys = new ArrayList(); private PBESecretKeyEncryptor keyEncryptor; private PGPDigestCalculator checksumCalculator; private PGPKeyPair masterKey; private PGPSignatureSubpacketVector hashedPcks; private PGPSignatureSubpacketVector unhashedPcks; private PGPContentSignerBuilder keySignerBuilder; /** * Create a new key ring generator using old style checksumming. It is recommended to use * SHA1 checksumming where possible. * * @param certificationLevel the certification level for keys on this ring. * @param masterKey the master key pair. * @param id the id to be associated with the ring. * @param encAlgorithm the algorithm to be used to protect secret keys. * @param passPhrase the passPhrase to be used to protect secret keys. * @param hashedPcks packets to be included in the certification hash. * @param unhashedPcks packets to be attached unhashed to the certification. * @param rand input secured random * @param provider the provider to use for encryption. * * @throws PGPException * @throws NoSuchProviderException * @deprecated use method taking PBESecretKeyDecryptor */ public PGPKeyRingGenerator( int certificationLevel, PGPKeyPair masterKey, String id, int encAlgorithm, char[] passPhrase, PGPSignatureSubpacketVector hashedPcks, PGPSignatureSubpacketVector unhashedPcks, SecureRandom rand, String provider) throws PGPException, NoSuchProviderException { this(certificationLevel, masterKey, id, encAlgorithm, passPhrase, false, hashedPcks, unhashedPcks, rand, provider); } /** * Create a new key ring generator. * * @param certificationLevel the certification level for keys on this ring. * @param masterKey the master key pair. * @param id the id to be associated with the ring. * @param encAlgorithm the algorithm to be used to protect secret keys. * @param passPhrase the passPhrase to be used to protect secret keys. * @param useSHA1 checksum the secret keys with SHA1 rather than the older 16 bit checksum. * @param hashedPcks packets to be included in the certification hash. * @param unhashedPcks packets to be attached unhashed to the certification. * @param rand input secured random * @param provider the provider to use for encryption. * * @throws PGPException * @throws NoSuchProviderException * @deprecated use method taking PBESecretKeyDecryptor */ public PGPKeyRingGenerator( int certificationLevel, PGPKeyPair masterKey, String id, int encAlgorithm, char[] passPhrase, boolean useSHA1, PGPSignatureSubpacketVector hashedPcks, PGPSignatureSubpacketVector unhashedPcks, SecureRandom rand, String provider) throws PGPException, NoSuchProviderException { this(certificationLevel, masterKey, id, encAlgorithm, passPhrase, useSHA1, hashedPcks, unhashedPcks, rand, PGPUtil.getProvider(provider)); } /** * Create a new key ring generator. * * @param certificationLevel the certification level for keys on this ring. * @param masterKey the master key pair. * @param id the id to be associated with the ring. * @param encAlgorithm the algorithm to be used to protect secret keys. * @param passPhrase the passPhrase to be used to protect secret keys. * @param useSHA1 checksum the secret keys with SHA1 rather than the older 16 bit checksum. * @param hashedPcks packets to be included in the certification hash. * @param unhashedPcks packets to be attached unhashed to the certification. * @param rand input secured random * @param provider the provider to use for encryption. * * @throws PGPException * @throws NoSuchProviderException * @deprecated use method taking PBESecretKeyEncryptor */ public PGPKeyRingGenerator( int certificationLevel, PGPKeyPair masterKey, String id, int encAlgorithm, char[] passPhrase, boolean useSHA1, PGPSignatureSubpacketVector hashedPcks, PGPSignatureSubpacketVector unhashedPcks, SecureRandom rand, Provider provider) throws PGPException, NoSuchProviderException { this.masterKey = masterKey; this.hashedPcks = hashedPcks; this.unhashedPcks = unhashedPcks; this.keyEncryptor = new JcePBESecretKeyEncryptorBuilder(encAlgorithm).setProvider(provider).setSecureRandom(rand).build(passPhrase); this.checksumCalculator = convertSHA1Flag(useSHA1); this.keySignerBuilder = new JcaPGPContentSignerBuilder(masterKey.getPublicKey().getAlgorithm(), HashAlgorithmTags.SHA1); keys.add(new PGPSecretKey(certificationLevel, masterKey, id, checksumCalculator, hashedPcks, unhashedPcks, keySignerBuilder, keyEncryptor)); } /** * Create a new key ring generator. * * @param certificationLevel * @param masterKey * @param id * @param checksumCalculator * @param hashedPcks * @param unhashedPcks * @param keySignerBuilder * @param keyEncryptor * @throws PGPException */ public PGPKeyRingGenerator( int certificationLevel, PGPKeyPair masterKey, String id, PGPDigestCalculator checksumCalculator, PGPSignatureSubpacketVector hashedPcks, PGPSignatureSubpacketVector unhashedPcks, PGPContentSignerBuilder keySignerBuilder, PBESecretKeyEncryptor keyEncryptor) throws PGPException { this.masterKey = masterKey; this.keyEncryptor = keyEncryptor; this.checksumCalculator = checksumCalculator; this.keySignerBuilder = keySignerBuilder; this.hashedPcks = hashedPcks; this.unhashedPcks = unhashedPcks; keys.add(new PGPSecretKey(certificationLevel, masterKey, id, checksumCalculator, hashedPcks, unhashedPcks, keySignerBuilder, keyEncryptor)); } /** * Add a sub key to the key ring to be generated with default certification and inheriting * the hashed/unhashed packets of the master key. * * @param keyPair * @throws PGPException */ public void addSubKey( PGPKeyPair keyPair) throws PGPException { addSubKey(keyPair, hashedPcks, unhashedPcks); } /** * Add a subkey with specific hashed and unhashed packets associated with it and default * certification. * * @param keyPair public/private key pair. * @param hashedPcks hashed packet values to be included in certification. * @param unhashedPcks unhashed packets values to be included in certification. * @throws PGPException */ public void addSubKey( PGPKeyPair keyPair, PGPSignatureSubpacketVector hashedPcks, PGPSignatureSubpacketVector unhashedPcks) throws PGPException { try { // // generate the certification // PGPSignatureGenerator sGen = new PGPSignatureGenerator(keySignerBuilder); sGen.init(PGPSignature.SUBKEY_BINDING, masterKey.getPrivateKey()); sGen.setHashedSubpackets(hashedPcks); sGen.setUnhashedSubpackets(unhashedPcks); List subSigs = new ArrayList(); subSigs.add(sGen.generateCertification(masterKey.getPublicKey(), keyPair.getPublicKey())); keys.add(new PGPSecretKey(keyPair.getPrivateKey(), new PGPPublicKey(keyPair.getPublicKey(), null, subSigs), checksumCalculator, keyEncryptor)); } catch (PGPException e) { throw e; } catch (Exception e) { throw new PGPException("exception adding subkey: ", e); } } /** * Return the secret key ring. * * @return a secret key ring. */ public PGPSecretKeyRing generateSecretKeyRing() { return new PGPSecretKeyRing(keys); } /** * Return the public key ring that corresponds to the secret key ring. * * @return a public key ring. */ public PGPPublicKeyRing generatePublicKeyRing() { Iterator it = keys.iterator(); List pubKeys = new ArrayList(); pubKeys.add(((PGPSecretKey)it.next()).getPublicKey()); while (it.hasNext()) { PGPPublicKey k = new PGPPublicKey(((PGPSecretKey)it.next()).getPublicKey()); k.publicPk = new PublicSubkeyPacket(k.getAlgorithm(), k.getCreationTime(), k.publicPk.getKey()); pubKeys.add(k); } return new PGPPublicKeyRing(pubKeys); } private static PGPDigestCalculator convertSHA1Flag(boolean useSHA1) throws PGPException { return useSHA1 ? new JcaPGPDigestCalculatorProviderBuilder().build().get(HashAlgorithmTags.SHA1) : null; } } bouncycastle-1.49.orig/src/org/bouncycastle/openpgp/PGPEncryptedDataGenerator.java0000644000175000017500000004311512030176043027762 0ustar ebourgebourgpackage org.bouncycastle.openpgp; import java.io.IOException; import java.io.OutputStream; import java.security.NoSuchProviderException; import java.security.Provider; import java.security.SecureRandom; import java.util.ArrayList; import java.util.List; import org.bouncycastle.bcpg.BCPGOutputStream; import org.bouncycastle.bcpg.HashAlgorithmTags; import org.bouncycastle.bcpg.PacketTags; import org.bouncycastle.bcpg.SymmetricKeyAlgorithmTags; import org.bouncycastle.jce.provider.BouncyCastleProvider; import org.bouncycastle.openpgp.operator.PBEKeyEncryptionMethodGenerator; import org.bouncycastle.openpgp.operator.PGPDataEncryptor; import org.bouncycastle.openpgp.operator.PGPDataEncryptorBuilder; import org.bouncycastle.openpgp.operator.PGPDigestCalculator; import org.bouncycastle.openpgp.operator.PGPKeyEncryptionMethodGenerator; import org.bouncycastle.openpgp.operator.jcajce.JcaPGPDigestCalculatorProviderBuilder; import org.bouncycastle.openpgp.operator.jcajce.JcePBEKeyEncryptionMethodGenerator; import org.bouncycastle.openpgp.operator.jcajce.JcePGPDataEncryptorBuilder; import org.bouncycastle.openpgp.operator.jcajce.JcePublicKeyKeyEncryptionMethodGenerator; import org.bouncycastle.util.io.TeeOutputStream; /** * Generator for encrypted objects. */ public class PGPEncryptedDataGenerator implements SymmetricKeyAlgorithmTags, StreamGenerator { /** * Specifier for SHA-1 S2K PBE generator. */ public static final int S2K_SHA1 = HashAlgorithmTags.SHA1; /** * Specifier for SHA-224 S2K PBE generator. */ public static final int S2K_SHA224 = HashAlgorithmTags.SHA224; /** * Specifier for SHA-256 S2K PBE generator. */ public static final int S2K_SHA256 = HashAlgorithmTags.SHA256; /** * Specifier for SHA-384 S2K PBE generator. */ public static final int S2K_SHA384 = HashAlgorithmTags.SHA384; /** * Specifier for SHA-512 S2K PBE generator. */ public static final int S2K_SHA512 = HashAlgorithmTags.SHA512; private BCPGOutputStream pOut; private OutputStream cOut; private boolean oldFormat = false; private PGPDigestCalculator digestCalc; private OutputStream genOut; private PGPDataEncryptorBuilder dataEncryptorBuilder; private List methods = new ArrayList(); private int defAlgorithm; private SecureRandom rand; private static Provider defProvider; /** * Base constructor. * * @param encAlgorithm the symmetric algorithm to use. * @param rand source of randomness * @param provider the provider name to use for encryption algorithms. * @deprecated use constructor that takes a PGPDataEncryptor */ public PGPEncryptedDataGenerator( int encAlgorithm, SecureRandom rand, String provider) { this(new JcePGPDataEncryptorBuilder(encAlgorithm).setSecureRandom(rand).setProvider(provider)); } /** * Base constructor. * * @param encAlgorithm the symmetric algorithm to use. * @param rand source of randomness * @param provider the provider to use for encryption algorithms. * @deprecated use constructor that takes a PGPDataEncryptorBuilder */ public PGPEncryptedDataGenerator( int encAlgorithm, SecureRandom rand, Provider provider) { this(new JcePGPDataEncryptorBuilder(encAlgorithm).setSecureRandom(rand).setProvider(provider)); } /** * Creates a cipher stream which will have an integrity packet * associated with it. * * @param encAlgorithm * @param withIntegrityPacket * @param rand * @param provider * @deprecated use constructor that takes a PGPDataEncryptorBuilder */ public PGPEncryptedDataGenerator( int encAlgorithm, boolean withIntegrityPacket, SecureRandom rand, String provider) { this(new JcePGPDataEncryptorBuilder(encAlgorithm).setWithIntegrityPacket(withIntegrityPacket).setSecureRandom(rand).setProvider(provider)); } /** * Creates a cipher stream which will have an integrity packet * associated with it. * * @param encAlgorithm * @param withIntegrityPacket * @param rand * @param provider * @deprecated use constructor that takes a PGPDataEncryptorBuilder */ public PGPEncryptedDataGenerator( int encAlgorithm, boolean withIntegrityPacket, SecureRandom rand, Provider provider) { this(new JcePGPDataEncryptorBuilder(encAlgorithm).setWithIntegrityPacket(withIntegrityPacket).setSecureRandom(rand).setProvider(provider)); } /** * Base constructor. * * @param encAlgorithm the symmetric algorithm to use. * @param rand source of randomness * @param oldFormat PGP 2.6.x compatibility required. * @param provider the provider to use for encryption algorithms. * @deprecated use constructor that takes a PGPDataEncryptorBuilder */ public PGPEncryptedDataGenerator( int encAlgorithm, SecureRandom rand, boolean oldFormat, String provider) { this(new JcePGPDataEncryptorBuilder(encAlgorithm).setSecureRandom(rand).setProvider(provider), oldFormat); } /** * Base constructor. * * @param encAlgorithm the symmetric algorithm to use. * @param rand source of randomness * @param oldFormat PGP 2.6.x compatibility required. * @param provider the provider to use for encryption algorithms. * @deprecated use constructor that takes a PGPDataEncryptorBuilder */ public PGPEncryptedDataGenerator( int encAlgorithm, SecureRandom rand, boolean oldFormat, Provider provider) { this(new JcePGPDataEncryptorBuilder(encAlgorithm).setSecureRandom(rand).setProvider(provider), oldFormat); } /** * Base constructor. * * @param encryptorBuilder builder to create actual data encryptor. */ public PGPEncryptedDataGenerator(PGPDataEncryptorBuilder encryptorBuilder) { this(encryptorBuilder, false); } /** * Base constructor with the option to turn on formatting for PGP 2.6.x compatibility. * * @param encryptorBuilder builder to create actual data encryptor. * @param oldFormat PGP 2.6.x compatibility required. */ public PGPEncryptedDataGenerator(PGPDataEncryptorBuilder encryptorBuilder, boolean oldFormat) { this.dataEncryptorBuilder = encryptorBuilder; this.oldFormat = oldFormat; this.defAlgorithm = dataEncryptorBuilder.getAlgorithm(); this.rand = dataEncryptorBuilder.getSecureRandom(); } /** * Add a PBE encryption method to the encrypted object using the default algorithm (S2K_SHA1). * * @param passPhrase * @throws NoSuchProviderException * @throws PGPException * @deprecated use addMethod that takes PGPKeyEncryptionMethodGenerator */ public void addMethod( char[] passPhrase) throws NoSuchProviderException, PGPException { addMethod(passPhrase, HashAlgorithmTags.SHA1); } /** * Add a PBE encryption method to the encrypted object. * * @param passPhrase passphrase to use to generate key. * @param s2kDigest digest algorithm to use for S2K calculation * @throws NoSuchProviderException * @throws PGPException * @deprecated use addMethod that takes PGPKeyEncryptionMethodGenerator */ public void addMethod( char[] passPhrase, int s2kDigest) throws NoSuchProviderException, PGPException { if (defProvider == null) { defProvider = new BouncyCastleProvider(); } addMethod(new JcePBEKeyEncryptionMethodGenerator(passPhrase, new JcaPGPDigestCalculatorProviderBuilder().setProvider(defProvider).build().get(s2kDigest)).setProvider(defProvider).setSecureRandom(rand)); } /** * Add a public key encrypted session key to the encrypted object. * * @param key * @throws NoSuchProviderException * @throws PGPException * @deprecated use addMethod that takes PGPKeyEncryptionMethodGenerator */ public void addMethod( PGPPublicKey key) throws NoSuchProviderException, PGPException { if (!key.isEncryptionKey()) { throw new IllegalArgumentException("passed in key not an encryption key!"); } if (defProvider == null) { defProvider = new BouncyCastleProvider(); } addMethod(new JcePublicKeyKeyEncryptionMethodGenerator(key).setProvider(defProvider).setSecureRandom(rand)); } /** * Added a key encryption method to be used to encrypt the session data associated * with this encrypted data. * * @param method key encryption method to use. */ public void addMethod(PGPKeyEncryptionMethodGenerator method) { methods.add(method); } private void addCheckSum( byte[] sessionInfo) { int check = 0; for (int i = 1; i != sessionInfo.length - 2; i++) { check += sessionInfo[i] & 0xff; } sessionInfo[sessionInfo.length - 2] = (byte)(check >> 8); sessionInfo[sessionInfo.length - 1] = (byte)(check); } private byte[] createSessionInfo( int algorithm, byte[] keyBytes) { byte[] sessionInfo = new byte[keyBytes.length + 3]; sessionInfo[0] = (byte) algorithm; System.arraycopy(keyBytes, 0, sessionInfo, 1, keyBytes.length); addCheckSum(sessionInfo); return sessionInfo; } /** * If buffer is non null stream assumed to be partial, otherwise the * length will be used to output a fixed length packet. *

    * The stream created can be closed off by either calling close() * on the stream or close() on the generator. Closing the returned * stream does not close off the OutputStream parameter out. * * @param out * @param length * @param buffer * @return * @throws java.io.IOException * @throws PGPException * @throws IllegalStateException */ private OutputStream open( OutputStream out, long length, byte[] buffer) throws IOException, PGPException, IllegalStateException { if (cOut != null) { throw new IllegalStateException("generator already in open state"); } if (methods.size() == 0) { throw new IllegalStateException("no encryption methods specified"); } byte[] key = null; pOut = new BCPGOutputStream(out); defAlgorithm = dataEncryptorBuilder.getAlgorithm(); rand = dataEncryptorBuilder.getSecureRandom(); if (methods.size() == 1) { if (methods.get(0) instanceof PBEKeyEncryptionMethodGenerator) { PBEKeyEncryptionMethodGenerator m = (PBEKeyEncryptionMethodGenerator)methods.get(0); key = m.getKey(dataEncryptorBuilder.getAlgorithm()); pOut.writePacket(((PGPKeyEncryptionMethodGenerator)methods.get(0)).generate(defAlgorithm, null)); } else { key = PGPUtil.makeRandomKey(defAlgorithm, rand); byte[] sessionInfo = createSessionInfo(defAlgorithm, key); PGPKeyEncryptionMethodGenerator m = (PGPKeyEncryptionMethodGenerator)methods.get(0); pOut.writePacket(m.generate(defAlgorithm, sessionInfo)); } } else // multiple methods { key = PGPUtil.makeRandomKey(defAlgorithm, rand); byte[] sessionInfo = createSessionInfo(defAlgorithm, key); for (int i = 0; i != methods.size(); i++) { PGPKeyEncryptionMethodGenerator m = (PGPKeyEncryptionMethodGenerator)methods.get(i); pOut.writePacket(m.generate(defAlgorithm, sessionInfo)); } } try { PGPDataEncryptor dataEncryptor = dataEncryptorBuilder.build(key); digestCalc = dataEncryptor.getIntegrityCalculator(); if (buffer == null) { // // we have to add block size + 2 for the generated IV and + 1 + 22 if integrity protected // if (digestCalc != null) { pOut = new ClosableBCPGOutputStream(out, PacketTags.SYM_ENC_INTEGRITY_PRO, length + dataEncryptor.getBlockSize() + 2 + 1 + 22); pOut.write(1); // version number } else { pOut = new ClosableBCPGOutputStream(out, PacketTags.SYMMETRIC_KEY_ENC, length + dataEncryptor.getBlockSize() + 2, oldFormat); } } else { if (digestCalc != null) { pOut = new ClosableBCPGOutputStream(out, PacketTags.SYM_ENC_INTEGRITY_PRO, buffer); pOut.write(1); // version number } else { pOut = new ClosableBCPGOutputStream(out, PacketTags.SYMMETRIC_KEY_ENC, buffer); } } genOut = cOut = dataEncryptor.getOutputStream(pOut); if (digestCalc != null) { genOut = new TeeOutputStream(digestCalc.getOutputStream(), cOut); } byte[] inLineIv = new byte[dataEncryptor.getBlockSize() + 2]; rand.nextBytes(inLineIv); inLineIv[inLineIv.length - 1] = inLineIv[inLineIv.length - 3]; inLineIv[inLineIv.length - 2] = inLineIv[inLineIv.length - 4]; genOut.write(inLineIv); return new WrappedGeneratorStream(genOut, this); } catch (Exception e) { throw new PGPException("Exception creating cipher", e); } } /** * Return an outputstream which will encrypt the data as it is written * to it. *

    * The stream created can be closed off by either calling close() * on the stream or close() on the generator. Closing the returned * stream does not close off the OutputStream parameter out. * * @param out * @param length * @return OutputStream * @throws IOException * @throws PGPException */ public OutputStream open( OutputStream out, long length) throws IOException, PGPException { return this.open(out, length, null); } /** * Return an outputstream which will encrypt the data as it is written * to it. The stream will be written out in chunks according to the size of the * passed in buffer. *

    * The stream created can be closed off by either calling close() * on the stream or close() on the generator. Closing the returned * stream does not close off the OutputStream parameter out. *

    * Note: if the buffer is not a power of 2 in length only the largest power of 2 * bytes worth of the buffer will be used. * * @param out * @param buffer the buffer to use. * @return OutputStream * @throws IOException * @throws PGPException */ public OutputStream open( OutputStream out, byte[] buffer) throws IOException, PGPException { return this.open(out, 0, buffer); } /** * Close off the encrypted object - this is equivalent to calling close on the stream * returned by the open() method. *

    * Note: This does not close the underlying output stream, only the stream on top of it created by the open() method. * @throws java.io.IOException */ public void close() throws IOException { if (cOut != null) { if (digestCalc != null) { // // hand code a mod detection packet // BCPGOutputStream bOut = new BCPGOutputStream(genOut, PacketTags.MOD_DETECTION_CODE, 20); bOut.flush(); byte[] dig = digestCalc.getDigest(); cOut.write(dig); } cOut.close(); cOut = null; pOut = null; } } private class ClosableBCPGOutputStream extends BCPGOutputStream { public ClosableBCPGOutputStream(OutputStream out, int symmetricKeyEnc, byte[] buffer) throws IOException { super(out, symmetricKeyEnc, buffer); } public ClosableBCPGOutputStream(OutputStream out, int symmetricKeyEnc, long length, boolean oldFormat) throws IOException { super(out, symmetricKeyEnc, length, oldFormat); } public ClosableBCPGOutputStream(OutputStream out, int symEncIntegrityPro, long length) throws IOException { super(out, symEncIntegrityPro, length); } public void close() throws IOException { this.finish(); } } } bouncycastle-1.49.orig/src/org/bouncycastle/openpgp/operator/0000755000175000017500000000000012152033551024002 5ustar ebourgebourgbouncycastle-1.49.orig/src/org/bouncycastle/openpgp/operator/PGPUtil.java0000644000175000017500000001441512032225603026134 0ustar ebourgebourgpackage org.bouncycastle.openpgp.operator; import java.io.IOException; import java.io.OutputStream; import org.bouncycastle.bcpg.HashAlgorithmTags; import org.bouncycastle.bcpg.S2K; import org.bouncycastle.bcpg.SymmetricKeyAlgorithmTags; import org.bouncycastle.openpgp.PGPException; import org.bouncycastle.util.Strings; /** * Basic utility class */ class PGPUtil implements HashAlgorithmTags { static byte[] makeKeyFromPassPhrase( PGPDigestCalculator digestCalculator, int algorithm, S2K s2k, char[] passPhrase) throws PGPException { String algName = null; int keySize = 0; switch (algorithm) { case SymmetricKeyAlgorithmTags.TRIPLE_DES: keySize = 192; algName = "DES_EDE"; break; case SymmetricKeyAlgorithmTags.IDEA: keySize = 128; algName = "IDEA"; break; case SymmetricKeyAlgorithmTags.CAST5: keySize = 128; algName = "CAST5"; break; case SymmetricKeyAlgorithmTags.BLOWFISH: keySize = 128; algName = "Blowfish"; break; case SymmetricKeyAlgorithmTags.SAFER: keySize = 128; algName = "SAFER"; break; case SymmetricKeyAlgorithmTags.DES: keySize = 64; algName = "DES"; break; case SymmetricKeyAlgorithmTags.AES_128: keySize = 128; algName = "AES"; break; case SymmetricKeyAlgorithmTags.AES_192: keySize = 192; algName = "AES"; break; case SymmetricKeyAlgorithmTags.AES_256: keySize = 256; algName = "AES"; break; case SymmetricKeyAlgorithmTags.TWOFISH: keySize = 256; algName = "Twofish"; break; default: throw new PGPException("unknown symmetric algorithm: " + algorithm); } byte[] pBytes = Strings.toUTF8ByteArray(passPhrase); byte[] keyBytes = new byte[(keySize + 7) / 8]; int generatedBytes = 0; int loopCount = 0; if (s2k != null) { if (s2k.getHashAlgorithm() != digestCalculator.getAlgorithm()) { throw new PGPException("s2k/digestCalculator mismatch"); } } else { if (digestCalculator.getAlgorithm() != HashAlgorithmTags.MD5) { throw new PGPException("digestCalculator not for MD5"); } } OutputStream dOut = digestCalculator.getOutputStream(); try { while (generatedBytes < keyBytes.length) { if (s2k != null) { for (int i = 0; i != loopCount; i++) { dOut.write(0); } byte[] iv = s2k.getIV(); switch (s2k.getType()) { case S2K.SIMPLE: dOut.write(pBytes); break; case S2K.SALTED: dOut.write(iv); dOut.write(pBytes); break; case S2K.SALTED_AND_ITERATED: long count = s2k.getIterationCount(); dOut.write(iv); dOut.write(pBytes); count -= iv.length + pBytes.length; while (count > 0) { if (count < iv.length) { dOut.write(iv, 0, (int)count); break; } else { dOut.write(iv); count -= iv.length; } if (count < pBytes.length) { dOut.write(pBytes, 0, (int)count); count = 0; } else { dOut.write(pBytes); count -= pBytes.length; } } break; default: throw new PGPException("unknown S2K type: " + s2k.getType()); } } else { for (int i = 0; i != loopCount; i++) { dOut.write((byte)0); } dOut.write(pBytes); } dOut.close(); byte[] dig = digestCalculator.getDigest(); if (dig.length > (keyBytes.length - generatedBytes)) { System.arraycopy(dig, 0, keyBytes, generatedBytes, keyBytes.length - generatedBytes); } else { System.arraycopy(dig, 0, keyBytes, generatedBytes, dig.length); } generatedBytes += dig.length; loopCount++; } } catch (IOException e) { throw new PGPException("exception calculating digest: " + e.getMessage(), e); } for (int i = 0; i != pBytes.length; i++) { pBytes[i] = 0; } return keyBytes; } public static byte[] makeKeyFromPassPhrase( PGPDigestCalculatorProvider digCalcProvider, int algorithm, S2K s2k, char[] passPhrase) throws PGPException { PGPDigestCalculator digestCalculator; if (s2k != null) { digestCalculator = digCalcProvider.get(s2k.getHashAlgorithm()); } else { digestCalculator = digCalcProvider.get(HashAlgorithmTags.MD5); } return makeKeyFromPassPhrase(digestCalculator, algorithm, s2k, passPhrase); } } bouncycastle-1.49.orig/src/org/bouncycastle/openpgp/operator/PGPContentVerifier.java0000644000175000017500000000064511600324733030331 0ustar ebourgebourgpackage org.bouncycastle.openpgp.operator; import java.io.OutputStream; public interface PGPContentVerifier { public OutputStream getOutputStream(); int getHashAlgorithm(); int getKeyAlgorithm(); long getKeyID(); /** * @param expected expected value of the signature on the data. * @return true if the signature verifies, false otherwise */ boolean verify(byte[] expected); } bouncycastle-1.49.orig/src/org/bouncycastle/openpgp/operator/PBEDataDecryptorFactory.java0000644000175000017500000000151611576541432031307 0ustar ebourgebourgpackage org.bouncycastle.openpgp.operator; import org.bouncycastle.bcpg.S2K; import org.bouncycastle.openpgp.PGPException; public abstract class PBEDataDecryptorFactory implements PGPDataDecryptorFactory { private char[] passPhrase; private PGPDigestCalculatorProvider calculatorProvider; protected PBEDataDecryptorFactory(char[] passPhrase, PGPDigestCalculatorProvider calculatorProvider) { this.passPhrase = passPhrase; this.calculatorProvider = calculatorProvider; } public byte[] makeKeyFromPassPhrase(int keyAlgorithm, S2K s2k) throws PGPException { return PGPUtil.makeKeyFromPassPhrase(calculatorProvider, keyAlgorithm, s2k, passPhrase); } public abstract byte[] recoverSessionData(int keyAlgorithm, byte[] key, byte[] seckKeyData) throws PGPException; } bouncycastle-1.49.orig/src/org/bouncycastle/openpgp/operator/PGPKeyEncryptionMethodGenerator.java0000644000175000017500000000046311576513664033053 0ustar ebourgebourgpackage org.bouncycastle.openpgp.operator; import org.bouncycastle.bcpg.ContainedPacket; import org.bouncycastle.openpgp.PGPException; public abstract class PGPKeyEncryptionMethodGenerator { public abstract ContainedPacket generate(int encAlgorithm, byte[] sessionInfo) throws PGPException; } bouncycastle-1.49.orig/src/org/bouncycastle/openpgp/operator/PGPDataEncryptorBuilder.java0000644000175000017500000000046311575566551031330 0ustar ebourgebourgpackage org.bouncycastle.openpgp.operator; import java.security.SecureRandom; import org.bouncycastle.openpgp.PGPException; public interface PGPDataEncryptorBuilder { int getAlgorithm(); PGPDataEncryptor build(byte[] keyBytes) throws PGPException; SecureRandom getSecureRandom(); } bouncycastle-1.49.orig/src/org/bouncycastle/openpgp/operator/PGPContentSigner.java0000644000175000017500000000046311600021553027775 0ustar ebourgebourgpackage org.bouncycastle.openpgp.operator; import java.io.OutputStream; public interface PGPContentSigner { public OutputStream getOutputStream(); byte[] getSignature(); byte[] getDigest(); int getType(); int getHashAlgorithm(); int getKeyAlgorithm(); long getKeyID(); } bouncycastle-1.49.orig/src/org/bouncycastle/openpgp/operator/PGPDataDecryptor.java0000644000175000017500000000035311576314732027776 0ustar ebourgebourgpackage org.bouncycastle.openpgp.operator; import java.io.InputStream; public interface PGPDataDecryptor { InputStream getInputStream(InputStream in); int getBlockSize(); PGPDigestCalculator getIntegrityCalculator(); } bouncycastle-1.49.orig/src/org/bouncycastle/openpgp/operator/PGPDataEncryptor.java0000644000175000017500000000036011576336733030013 0ustar ebourgebourgpackage org.bouncycastle.openpgp.operator; import java.io.OutputStream; public interface PGPDataEncryptor { OutputStream getOutputStream(OutputStream out); PGPDigestCalculator getIntegrityCalculator(); int getBlockSize(); } bouncycastle-1.49.orig/src/org/bouncycastle/openpgp/operator/bc/0000755000175000017500000000000012152033551024366 5ustar ebourgebourgbouncycastle-1.49.orig/src/org/bouncycastle/openpgp/operator/bc/BcPGPContentSignerBuilder.java0000644000175000017500000000601111600551411032131 0ustar ebourgebourgpackage org.bouncycastle.openpgp.operator.bc; import java.io.OutputStream; import java.security.SecureRandom; import org.bouncycastle.crypto.CryptoException; import org.bouncycastle.crypto.Signer; import org.bouncycastle.crypto.params.ParametersWithRandom; import org.bouncycastle.openpgp.PGPException; import org.bouncycastle.openpgp.PGPPrivateKey; import org.bouncycastle.openpgp.operator.PGPContentSigner; import org.bouncycastle.openpgp.operator.PGPContentSignerBuilder; import org.bouncycastle.openpgp.operator.PGPDigestCalculator; import org.bouncycastle.util.io.TeeOutputStream; public class BcPGPContentSignerBuilder implements PGPContentSignerBuilder { private BcPGPDigestCalculatorProvider digestCalculatorProvider = new BcPGPDigestCalculatorProvider(); private BcPGPKeyConverter keyConverter = new BcPGPKeyConverter(); private int hashAlgorithm; private SecureRandom random; private int keyAlgorithm; public BcPGPContentSignerBuilder(int keyAlgorithm, int hashAlgorithm) { this.keyAlgorithm = keyAlgorithm; this.hashAlgorithm = hashAlgorithm; } public BcPGPContentSignerBuilder setSecureRandom(SecureRandom random) { this.random = random; return this; } public PGPContentSigner build(final int signatureType, final PGPPrivateKey privateKey) throws PGPException { final PGPDigestCalculator digestCalculator = digestCalculatorProvider.get(hashAlgorithm); final Signer signer = BcImplProvider.createSigner(keyAlgorithm, hashAlgorithm); if (random != null) { signer.init(true, new ParametersWithRandom(keyConverter.getPrivateKey(privateKey), random)); } else { signer.init(true, keyConverter.getPrivateKey(privateKey)); } return new PGPContentSigner() { public int getType() { return signatureType; } public int getHashAlgorithm() { return hashAlgorithm; } public int getKeyAlgorithm() { return keyAlgorithm; } public long getKeyID() { return privateKey.getKeyID(); } public OutputStream getOutputStream() { return new TeeOutputStream(new SignerOutputStream(signer), digestCalculator.getOutputStream()); } public byte[] getSignature() { try { return signer.generateSignature(); } catch (CryptoException e) { // TODO: need a specific runtime exception for PGP operators. throw new IllegalStateException("unable to create signature"); } } public byte[] getDigest() { return digestCalculator.getDigest(); } }; } } ././@LongLink0000000000000000000000000000014700000000000011567 Lustar rootrootbouncycastle-1.49.orig/src/org/bouncycastle/openpgp/operator/bc/BcPBEKeyEncryptionMethodGenerator.javabouncycastle-1.49.orig/src/org/bouncycastle/openpgp/operator/bc/BcPBEKeyEncryptionMethodGenerator.ja0000644000175000017500000000665112057004410033315 0ustar ebourgebourgpackage org.bouncycastle.openpgp.operator.bc; import java.security.SecureRandom; import org.bouncycastle.crypto.BlockCipher; import org.bouncycastle.crypto.BufferedBlockCipher; import org.bouncycastle.crypto.InvalidCipherTextException; import org.bouncycastle.openpgp.PGPException; import org.bouncycastle.openpgp.operator.PBEKeyEncryptionMethodGenerator; import org.bouncycastle.openpgp.operator.PGPDigestCalculator; /** * A BC lightweight method generator for supporting PBE based encryption operations. */ public class BcPBEKeyEncryptionMethodGenerator extends PBEKeyEncryptionMethodGenerator { /** * Create a PBE encryption method generator using the provided calculator for key calculation. * * @param passPhrase the passphrase to use as the primary source of key material. * @param s2kDigestCalculator the digest calculator to use for key calculation. */ public BcPBEKeyEncryptionMethodGenerator(char[] passPhrase, PGPDigestCalculator s2kDigestCalculator) { super(passPhrase, s2kDigestCalculator); } /** * Create a PBE encryption method generator using the default SHA-1 digest calculator for key calculation. * * @param passPhrase the passphrase to use as the primary source of key material. */ public BcPBEKeyEncryptionMethodGenerator(char[] passPhrase) { this(passPhrase, new SHA1PGPDigestCalculator()); } /** * Create a PBE encryption method generator using the provided calculator and S2K count for key calculation. * * @param passPhrase the passphrase to use as the primary source of key material. * @param s2kDigestCalculator the digest calculator to use for key calculation. * @param s2kCount the S2K count to use. */ public BcPBEKeyEncryptionMethodGenerator(char[] passPhrase, PGPDigestCalculator s2kDigestCalculator, int s2kCount) { super(passPhrase, s2kDigestCalculator, s2kCount); } /** * Create a PBE encryption method generator using the default SHA-1 digest calculator and * a S2K count other than the default of 0x60 for key calculation. * * @param passPhrase the passphrase to use as the primary source of key material. * @param s2kCount the S2K count to use. */ public BcPBEKeyEncryptionMethodGenerator(char[] passPhrase, int s2kCount) { super(passPhrase, new SHA1PGPDigestCalculator(), s2kCount); } /** * Provide a user defined source of randomness. * * @param random the secure random to be used. * @return the current generator. */ public PBEKeyEncryptionMethodGenerator setSecureRandom(SecureRandom random) { super.setSecureRandom(random); return this; } protected byte[] encryptSessionInfo(int encAlgorithm, byte[] key, byte[] sessionInfo) throws PGPException { try { BlockCipher engine = BcImplProvider.createBlockCipher(encAlgorithm); BufferedBlockCipher cipher = BcUtil.createSymmetricKeyWrapper(true, engine, key, new byte[engine.getBlockSize()]); byte[] out = new byte[sessionInfo.length]; int len = cipher.processBytes(sessionInfo, 0, sessionInfo.length, out, 0); len += cipher.doFinal(out, len); return out; } catch (InvalidCipherTextException e) { throw new PGPException("encryption failed: " + e.getMessage(), e); } } } bouncycastle-1.49.orig/src/org/bouncycastle/openpgp/operator/bc/BcPBESecretKeyDecryptorBuilder.java0000644000175000017500000000302211577002216033127 0ustar ebourgebourgpackage org.bouncycastle.openpgp.operator.bc; import org.bouncycastle.crypto.BufferedBlockCipher; import org.bouncycastle.crypto.InvalidCipherTextException; import org.bouncycastle.openpgp.PGPException; import org.bouncycastle.openpgp.operator.PBESecretKeyDecryptor; import org.bouncycastle.openpgp.operator.PGPDigestCalculatorProvider; public class BcPBESecretKeyDecryptorBuilder { private PGPDigestCalculatorProvider calculatorProvider; public BcPBESecretKeyDecryptorBuilder(PGPDigestCalculatorProvider calculatorProvider) { this.calculatorProvider = calculatorProvider; } public PBESecretKeyDecryptor build(char[] passPhrase) { return new PBESecretKeyDecryptor(passPhrase, calculatorProvider) { public byte[] recoverKeyData(int encAlgorithm, byte[] key, byte[] iv, byte[] keyData, int keyOff, int keyLen) throws PGPException { try { BufferedBlockCipher c = BcUtil.createSymmetricKeyWrapper(false, BcImplProvider.createBlockCipher(encAlgorithm), key, iv); byte[] out = new byte[keyLen]; int outLen = c.processBytes(keyData, keyOff, keyLen, out, 0); outLen += c.doFinal(out, outLen); return out; } catch (InvalidCipherTextException e) { throw new PGPException("decryption failed: " + e.getMessage(), e); } } }; } } bouncycastle-1.49.orig/src/org/bouncycastle/openpgp/operator/bc/BcPublicKeyDataDecryptorFactory.java0000644000175000017500000000721011721020010033366 0ustar ebourgebourgpackage org.bouncycastle.openpgp.operator.bc; import java.math.BigInteger; import org.bouncycastle.crypto.AsymmetricBlockCipher; import org.bouncycastle.crypto.BlockCipher; import org.bouncycastle.crypto.BufferedAsymmetricBlockCipher; import org.bouncycastle.crypto.InvalidCipherTextException; import org.bouncycastle.crypto.params.AsymmetricKeyParameter; import org.bouncycastle.crypto.params.ElGamalPrivateKeyParameters; import org.bouncycastle.openpgp.PGPException; import org.bouncycastle.openpgp.PGPPrivateKey; import org.bouncycastle.openpgp.PGPPublicKey; import org.bouncycastle.openpgp.operator.PGPDataDecryptor; import org.bouncycastle.openpgp.operator.PublicKeyDataDecryptorFactory; /** * A decryptor factory for handling public key decryption operations. */ public class BcPublicKeyDataDecryptorFactory implements PublicKeyDataDecryptorFactory { private BcPGPKeyConverter keyConverter = new BcPGPKeyConverter(); private PGPPrivateKey privKey; public BcPublicKeyDataDecryptorFactory(PGPPrivateKey privKey) { this.privKey = privKey; } public byte[] recoverSessionData(int keyAlgorithm, BigInteger[] secKeyData) throws PGPException { try { AsymmetricBlockCipher c = BcImplProvider.createPublicKeyCipher(keyAlgorithm); AsymmetricKeyParameter key = keyConverter.getPrivateKey(privKey); BufferedAsymmetricBlockCipher c1 = new BufferedAsymmetricBlockCipher(c); c1.init(false, key); if (keyAlgorithm == PGPPublicKey.RSA_ENCRYPT || keyAlgorithm == PGPPublicKey.RSA_GENERAL) { byte[] bi = secKeyData[0].toByteArray(); if (bi[0] == 0) { c1.processBytes(bi, 1, bi.length - 1); } else { c1.processBytes(bi, 0, bi.length); } } else { BcPGPKeyConverter converter = new BcPGPKeyConverter(); ElGamalPrivateKeyParameters parms = (ElGamalPrivateKeyParameters) converter.getPrivateKey(privKey); int size = (parms.getParameters().getP().bitLength() + 7) / 8; byte[] tmp = new byte[size]; byte[] bi = secKeyData[0].toByteArray(); if (bi.length > size) { c1.processBytes(bi, 1, bi.length - 1); } else { System.arraycopy(bi, 0, tmp, tmp.length - bi.length, bi.length); c1.processBytes(tmp, 0, tmp.length); } bi = secKeyData[1].toByteArray(); for (int i = 0; i != tmp.length; i++) { tmp[i] = 0; } if (bi.length > size) { c1.processBytes(bi, 1, bi.length - 1); } else { System.arraycopy(bi, 0, tmp, tmp.length - bi.length, bi.length); c1.processBytes(tmp, 0, tmp.length); } } return c1.doFinal(); } catch (InvalidCipherTextException e) { throw new PGPException("exception encrypting session info: " + e.getMessage(), e); } } public PGPDataDecryptor createDataDecryptor(boolean withIntegrityPacket, int encAlgorithm, byte[] key) throws PGPException { BlockCipher engine = BcImplProvider.createBlockCipher(encAlgorithm); return BcUtil.createDataDecryptor(withIntegrityPacket, engine, key); } } bouncycastle-1.49.orig/src/org/bouncycastle/openpgp/operator/bc/BcPBEDataDecryptorFactory.java0000644000175000017500000000432711577002306032134 0ustar ebourgebourgpackage org.bouncycastle.openpgp.operator.bc; import org.bouncycastle.crypto.BlockCipher; import org.bouncycastle.crypto.BufferedBlockCipher; import org.bouncycastle.openpgp.PGPException; import org.bouncycastle.openpgp.operator.PBEDataDecryptorFactory; import org.bouncycastle.openpgp.operator.PGPDataDecryptor; /** * A decryptor factory for handling PBE decryption operations. */ public class BcPBEDataDecryptorFactory extends PBEDataDecryptorFactory { /** * Base constructor. * * @param pass the passphrase to use as the primary source of key material. * @param calculatorProvider a digest calculator provider to provide calculators to support the key generation calculation required. */ public BcPBEDataDecryptorFactory(char[] pass, BcPGPDigestCalculatorProvider calculatorProvider) { super(pass, calculatorProvider); } public byte[] recoverSessionData(int keyAlgorithm, byte[] key, byte[] secKeyData) throws PGPException { try { if (secKeyData != null && secKeyData.length > 0) { BlockCipher engine = BcImplProvider.createBlockCipher(keyAlgorithm); BufferedBlockCipher cipher = BcUtil.createSymmetricKeyWrapper(false, engine, key, new byte[engine.getBlockSize()]); byte[] out = new byte[secKeyData.length]; int len = cipher.processBytes(secKeyData, 0, secKeyData.length, out, 0); len += cipher.doFinal(out, len); return out; } else { byte[] keyBytes = new byte[key.length + 1]; keyBytes[0] = (byte)keyAlgorithm; System.arraycopy(key, 0, keyBytes, 1, key.length); return keyBytes; } } catch (Exception e) { throw new PGPException("Exception recovering session info", e); } } public PGPDataDecryptor createDataDecryptor(boolean withIntegrityPacket, int encAlgorithm, byte[] key) throws PGPException { BlockCipher engine = BcImplProvider.createBlockCipher(encAlgorithm); return BcUtil.createDataDecryptor(withIntegrityPacket, engine, key); } } bouncycastle-1.49.orig/src/org/bouncycastle/openpgp/operator/bc/SHA1PGPDigestCalculator.java0000644000175000017500000000261011577255446031470 0ustar ebourgebourgpackage org.bouncycastle.openpgp.operator.bc; import java.io.IOException; import java.io.OutputStream; import org.bouncycastle.bcpg.HashAlgorithmTags; import org.bouncycastle.crypto.Digest; import org.bouncycastle.crypto.digests.SHA1Digest; import org.bouncycastle.openpgp.operator.PGPDigestCalculator; class SHA1PGPDigestCalculator implements PGPDigestCalculator { private Digest digest = new SHA1Digest(); public int getAlgorithm() { return HashAlgorithmTags.SHA1; } public OutputStream getOutputStream() { return new DigestOutputStream(digest); } public byte[] getDigest() { byte[] d = new byte[digest.getDigestSize()]; digest.doFinal(d, 0); return d; } public void reset() { digest.reset(); } private class DigestOutputStream extends OutputStream { private Digest dig; DigestOutputStream(Digest dig) { this.dig = dig; } public void write(byte[] bytes, int off, int len) throws IOException { dig.update(bytes, off, len); } public void write(byte[] bytes) throws IOException { dig.update(bytes, 0, bytes.length); } public void write(int b) throws IOException { dig.update((byte)b); } } } bouncycastle-1.49.orig/src/org/bouncycastle/openpgp/operator/bc/BcPGPKeyConverter.java0000644000175000017500000001626211732242423030477 0ustar ebourgebourgpackage org.bouncycastle.openpgp.operator.bc; import java.util.Date; import org.bouncycastle.bcpg.BCPGKey; import org.bouncycastle.bcpg.DSAPublicBCPGKey; import org.bouncycastle.bcpg.DSASecretBCPGKey; import org.bouncycastle.bcpg.ElGamalPublicBCPGKey; import org.bouncycastle.bcpg.ElGamalSecretBCPGKey; import org.bouncycastle.bcpg.PublicKeyAlgorithmTags; import org.bouncycastle.bcpg.PublicKeyPacket; import org.bouncycastle.bcpg.RSAPublicBCPGKey; import org.bouncycastle.bcpg.RSASecretBCPGKey; import org.bouncycastle.crypto.params.AsymmetricKeyParameter; import org.bouncycastle.crypto.params.DSAParameters; import org.bouncycastle.crypto.params.DSAPrivateKeyParameters; import org.bouncycastle.crypto.params.DSAPublicKeyParameters; import org.bouncycastle.crypto.params.ElGamalParameters; import org.bouncycastle.crypto.params.ElGamalPrivateKeyParameters; import org.bouncycastle.crypto.params.ElGamalPublicKeyParameters; import org.bouncycastle.crypto.params.RSAKeyParameters; import org.bouncycastle.crypto.params.RSAPrivateCrtKeyParameters; import org.bouncycastle.openpgp.PGPException; import org.bouncycastle.openpgp.PGPPrivateKey; import org.bouncycastle.openpgp.PGPPublicKey; public class BcPGPKeyConverter { /** * Create a PGPPublicKey from the passed in JCA one. *

    * Note: the time passed in affects the value of the key's keyID, so you probably only want * to do this once for a JCA key, or make sure you keep track of the time you used. * * @param algorithm asymmetric algorithm type representing the public key. * @param pubKey actual public key to associate. * @param time date of creation. * @throws PGPException on key creation problem. */ public PGPPublicKey getPGPPublicKey(int algorithm, AsymmetricKeyParameter pubKey, Date time) throws PGPException { BCPGKey bcpgKey; if (pubKey instanceof RSAKeyParameters) { RSAKeyParameters rK = (RSAKeyParameters)pubKey; bcpgKey = new RSAPublicBCPGKey(rK.getModulus(), rK.getExponent()); } else if (pubKey instanceof DSAPublicKeyParameters) { DSAPublicKeyParameters dK = (DSAPublicKeyParameters)pubKey; DSAParameters dP = dK.getParameters(); bcpgKey = new DSAPublicBCPGKey(dP.getP(), dP.getQ(), dP.getG(), dK.getY()); } else if (pubKey instanceof ElGamalPublicKeyParameters) { ElGamalPublicKeyParameters eK = (ElGamalPublicKeyParameters)pubKey; ElGamalParameters eS = eK.getParameters(); bcpgKey = new ElGamalPublicBCPGKey(eS.getP(), eS.getG(), eK.getY()); } else { throw new PGPException("unknown key class"); } return new PGPPublicKey(new PublicKeyPacket(algorithm, time, bcpgKey), new BcKeyFingerprintCalculator()); } public PGPPrivateKey getPGPPrivateKey(PGPPublicKey pubKey, AsymmetricKeyParameter privKey) throws PGPException { BCPGKey privPk; switch (pubKey.getAlgorithm()) { case PGPPublicKey.RSA_ENCRYPT: case PGPPublicKey.RSA_SIGN: case PGPPublicKey.RSA_GENERAL: RSAPrivateCrtKeyParameters rsK = (RSAPrivateCrtKeyParameters)privKey; privPk = new RSASecretBCPGKey(rsK.getExponent(), rsK.getP(), rsK.getQ()); break; case PGPPublicKey.DSA: DSAPrivateKeyParameters dsK = (DSAPrivateKeyParameters)privKey; privPk = new DSASecretBCPGKey(dsK.getX()); break; case PGPPublicKey.ELGAMAL_ENCRYPT: case PGPPublicKey.ELGAMAL_GENERAL: ElGamalPrivateKeyParameters esK = (ElGamalPrivateKeyParameters)privKey; privPk = new ElGamalSecretBCPGKey(esK.getX()); break; default: throw new PGPException("unknown key class"); } return new PGPPrivateKey(pubKey.getKeyID(), pubKey.getPublicKeyPacket(), privPk); } public AsymmetricKeyParameter getPublicKey(PGPPublicKey publicKey) throws PGPException { PublicKeyPacket publicPk = publicKey.getPublicKeyPacket(); try { switch (publicPk.getAlgorithm()) { case PublicKeyAlgorithmTags.RSA_ENCRYPT: case PublicKeyAlgorithmTags.RSA_GENERAL: case PublicKeyAlgorithmTags.RSA_SIGN: RSAPublicBCPGKey rsaK = (RSAPublicBCPGKey)publicPk.getKey(); return new RSAKeyParameters(false, rsaK.getModulus(), rsaK.getPublicExponent()); case PublicKeyAlgorithmTags.DSA: DSAPublicBCPGKey dsaK = (DSAPublicBCPGKey)publicPk.getKey(); return new DSAPublicKeyParameters(dsaK.getY(), new DSAParameters(dsaK.getP(), dsaK.getQ(), dsaK.getG())); case PublicKeyAlgorithmTags.ELGAMAL_ENCRYPT: case PublicKeyAlgorithmTags.ELGAMAL_GENERAL: ElGamalPublicBCPGKey elK = (ElGamalPublicBCPGKey)publicPk.getKey(); return new ElGamalPublicKeyParameters(elK.getY(), new ElGamalParameters(elK.getP(), elK.getG())); default: throw new PGPException("unknown public key algorithm encountered"); } } catch (PGPException e) { throw e; } catch (Exception e) { throw new PGPException("exception constructing public key", e); } } public AsymmetricKeyParameter getPrivateKey(PGPPrivateKey privKey) throws PGPException { PublicKeyPacket pubPk = privKey.getPublicKeyPacket(); BCPGKey privPk = privKey.getPrivateKeyDataPacket(); try { switch (pubPk.getAlgorithm()) { case PGPPublicKey.RSA_ENCRYPT: case PGPPublicKey.RSA_GENERAL: case PGPPublicKey.RSA_SIGN: RSAPublicBCPGKey rsaPub = (RSAPublicBCPGKey)pubPk.getKey(); RSASecretBCPGKey rsaPriv = (RSASecretBCPGKey)privPk; return new RSAPrivateCrtKeyParameters(rsaPriv.getModulus(), rsaPub.getPublicExponent(), rsaPriv.getPrivateExponent(), rsaPriv.getPrimeP(), rsaPriv.getPrimeQ(), rsaPriv.getPrimeExponentP(), rsaPriv.getPrimeExponentQ(), rsaPriv.getCrtCoefficient()); case PGPPublicKey.DSA: DSAPublicBCPGKey dsaPub = (DSAPublicBCPGKey)pubPk.getKey(); DSASecretBCPGKey dsaPriv = (DSASecretBCPGKey)privPk; return new DSAPrivateKeyParameters(dsaPriv.getX(), new DSAParameters(dsaPub.getP(), dsaPub.getQ(), dsaPub.getG())); case PGPPublicKey.ELGAMAL_ENCRYPT: case PGPPublicKey.ELGAMAL_GENERAL: ElGamalPublicBCPGKey elPub = (ElGamalPublicBCPGKey)pubPk.getKey(); ElGamalSecretBCPGKey elPriv = (ElGamalSecretBCPGKey)privPk; return new ElGamalPrivateKeyParameters(elPriv.getX(), new ElGamalParameters(elPub.getP(), elPub.getG())); default: throw new PGPException("unknown public key algorithm encountered"); } } catch (PGPException e) { throw e; } catch (Exception e) { throw new PGPException("Exception constructing key", e); } } } bouncycastle-1.49.orig/src/org/bouncycastle/openpgp/operator/bc/BcKeyFingerprintCalculator.java0000644000175000017500000000402511600530175032452 0ustar ebourgebourgpackage org.bouncycastle.openpgp.operator.bc; import java.io.IOException; import org.bouncycastle.bcpg.BCPGKey; import org.bouncycastle.bcpg.MPInteger; import org.bouncycastle.bcpg.PublicKeyPacket; import org.bouncycastle.bcpg.RSAPublicBCPGKey; import org.bouncycastle.crypto.Digest; import org.bouncycastle.crypto.digests.MD5Digest; import org.bouncycastle.crypto.digests.SHA1Digest; import org.bouncycastle.openpgp.PGPException; import org.bouncycastle.openpgp.operator.KeyFingerPrintCalculator; public class BcKeyFingerprintCalculator implements KeyFingerPrintCalculator { public byte[] calculateFingerprint(PublicKeyPacket publicPk) throws PGPException { BCPGKey key = publicPk.getKey(); Digest digest; if (publicPk.getVersion() <= 3) { RSAPublicBCPGKey rK = (RSAPublicBCPGKey)key; try { digest = new MD5Digest(); byte[] bytes = new MPInteger(rK.getModulus()).getEncoded(); digest.update(bytes, 2, bytes.length - 2); bytes = new MPInteger(rK.getPublicExponent()).getEncoded(); digest.update(bytes, 2, bytes.length - 2); } catch (IOException e) { throw new PGPException("can't encode key components: " + e.getMessage(), e); } } else { try { byte[] kBytes = publicPk.getEncodedContents(); digest = new SHA1Digest(); digest.update((byte)0x99); digest.update((byte)(kBytes.length >> 8)); digest.update((byte)kBytes.length); digest.update(kBytes, 0, kBytes.length); } catch (IOException e) { throw new PGPException("can't encode key components: " + e.getMessage(), e); } } byte[] digBuf = new byte[digest.getDigestSize()]; digest.doFinal(digBuf, 0); return digBuf; } } bouncycastle-1.49.orig/src/org/bouncycastle/openpgp/operator/bc/BcPGPDigestCalculatorProvider.java0000644000175000017500000000353111577255351033031 0ustar ebourgebourgpackage org.bouncycastle.openpgp.operator.bc; import java.io.IOException; import java.io.OutputStream; import org.bouncycastle.crypto.Digest; import org.bouncycastle.openpgp.PGPException; import org.bouncycastle.openpgp.operator.PGPDigestCalculator; import org.bouncycastle.openpgp.operator.PGPDigestCalculatorProvider; public class BcPGPDigestCalculatorProvider implements PGPDigestCalculatorProvider { public PGPDigestCalculator get(final int algorithm) throws PGPException { final Digest dig = BcImplProvider.createDigest(algorithm); final DigestOutputStream stream = new DigestOutputStream(dig); return new PGPDigestCalculator() { public int getAlgorithm() { return algorithm; } public OutputStream getOutputStream() { return stream; } public byte[] getDigest() { return stream.getDigest(); } public void reset() { dig.reset(); } }; } private class DigestOutputStream extends OutputStream { private Digest dig; DigestOutputStream(Digest dig) { this.dig = dig; } public void write(byte[] bytes, int off, int len) throws IOException { dig.update(bytes, off, len); } public void write(byte[] bytes) throws IOException { dig.update(bytes, 0, bytes.length); } public void write(int b) throws IOException { dig.update((byte)b); } byte[] getDigest() { byte[] d = new byte[dig.getDigestSize()]; dig.doFinal(d, 0); return d; } } }././@LongLink0000000000000000000000000000015500000000000011566 Lustar rootrootbouncycastle-1.49.orig/src/org/bouncycastle/openpgp/operator/bc/BcPublicKeyKeyEncryptionMethodGenerator.javabouncycastle-1.49.orig/src/org/bouncycastle/openpgp/operator/bc/BcPublicKeyKeyEncryptionMethodGenera0000644000175000017500000000411711576531772033500 0ustar ebourgebourgpackage org.bouncycastle.openpgp.operator.bc; import java.security.SecureRandom; import org.bouncycastle.crypto.AsymmetricBlockCipher; import org.bouncycastle.crypto.InvalidCipherTextException; import org.bouncycastle.crypto.params.AsymmetricKeyParameter; import org.bouncycastle.crypto.params.ParametersWithRandom; import org.bouncycastle.openpgp.PGPException; import org.bouncycastle.openpgp.PGPPublicKey; import org.bouncycastle.openpgp.operator.PublicKeyKeyEncryptionMethodGenerator; /** * A method generator for supporting public key based encryption operations. */ public class BcPublicKeyKeyEncryptionMethodGenerator extends PublicKeyKeyEncryptionMethodGenerator { private SecureRandom random; private BcPGPKeyConverter keyConverter = new BcPGPKeyConverter(); /** * Create a public key encryption method generator with the method to be based on the passed in key. * * @param key the public key to use for encryption. */ public BcPublicKeyKeyEncryptionMethodGenerator(PGPPublicKey key) { super(key); } /** * Provide a user defined source of randomness. * * @param random the secure random to be used. * @return the current generator. */ public BcPublicKeyKeyEncryptionMethodGenerator setSecureRandom(SecureRandom random) { this.random = random; return this; } protected byte[] encryptSessionInfo(PGPPublicKey pubKey, byte[] sessionInfo) throws PGPException { try { AsymmetricBlockCipher c = BcImplProvider.createPublicKeyCipher(pubKey.getAlgorithm()); AsymmetricKeyParameter key = keyConverter.getPublicKey(pubKey); if (random == null) { random = new SecureRandom(); } c.init(true, new ParametersWithRandom(key, random)); return c.processBlock(sessionInfo, 0, sessionInfo.length); } catch (InvalidCipherTextException e) { throw new PGPException("exception encrypting session info: " + e.getMessage(), e); } } } bouncycastle-1.49.orig/src/org/bouncycastle/openpgp/operator/bc/BcPGPDataEncryptorBuilder.java0000644000175000017500000000603711576531772032162 0ustar ebourgebourgpackage org.bouncycastle.openpgp.operator.bc; import java.io.OutputStream; import java.security.SecureRandom; import org.bouncycastle.crypto.BlockCipher; import org.bouncycastle.crypto.BufferedBlockCipher; import org.bouncycastle.crypto.io.CipherOutputStream; import org.bouncycastle.openpgp.PGPException; import org.bouncycastle.openpgp.operator.PGPDataEncryptor; import org.bouncycastle.openpgp.operator.PGPDataEncryptorBuilder; import org.bouncycastle.openpgp.operator.PGPDigestCalculator; public class BcPGPDataEncryptorBuilder implements PGPDataEncryptorBuilder { private SecureRandom random; private boolean withIntegrityPacket; private int encAlgorithm; public BcPGPDataEncryptorBuilder(int encAlgorithm) { this.encAlgorithm = encAlgorithm; if (encAlgorithm == 0) { throw new IllegalArgumentException("null cipher specified"); } } /** * Determine whether or not the resulting encrypted data will be protected using an integrity packet. * * @param withIntegrityPacket true if an integrity packet is to be included, false otherwise. * @return the current builder. */ public BcPGPDataEncryptorBuilder setWithIntegrityPacket(boolean withIntegrityPacket) { this.withIntegrityPacket = withIntegrityPacket; return this; } /** * Provide a user defined source of randomness. * * @param random the secure random to be used. * @return the current builder. */ public BcPGPDataEncryptorBuilder setSecureRandom(SecureRandom random) { this.random = random; return this; } public int getAlgorithm() { return encAlgorithm; } public SecureRandom getSecureRandom() { if (random == null) { random = new SecureRandom(); } return random; } public PGPDataEncryptor build(byte[] keyBytes) throws PGPException { return new MyPGPDataEncryptor(keyBytes); } private class MyPGPDataEncryptor implements PGPDataEncryptor { private final BufferedBlockCipher c; MyPGPDataEncryptor(byte[] keyBytes) throws PGPException { BlockCipher engine = BcImplProvider.createBlockCipher(encAlgorithm); try { c = BcUtil.createStreamCipher(true, engine, withIntegrityPacket, keyBytes); } catch (IllegalArgumentException e) { throw new PGPException("invalid parameters: " + e.getMessage(), e); } } public OutputStream getOutputStream(OutputStream out) { return new CipherOutputStream(out, c); } public PGPDigestCalculator getIntegrityCalculator() { if (withIntegrityPacket) { return new SHA1PGPDigestCalculator(); } return null; } public int getBlockSize() { return c.getBlockSize(); } } } bouncycastle-1.49.orig/src/org/bouncycastle/openpgp/operator/bc/BcPBESecretKeyEncryptorBuilder.java0000644000175000017500000001115712145535231033151 0ustar ebourgebourgpackage org.bouncycastle.openpgp.operator.bc; import java.security.SecureRandom; import org.bouncycastle.crypto.BlockCipher; import org.bouncycastle.crypto.BufferedBlockCipher; import org.bouncycastle.crypto.InvalidCipherTextException; import org.bouncycastle.openpgp.PGPException; import org.bouncycastle.openpgp.operator.PBESecretKeyEncryptor; import org.bouncycastle.openpgp.operator.PGPDigestCalculator; public class BcPBESecretKeyEncryptorBuilder { private int encAlgorithm; private PGPDigestCalculator s2kDigestCalculator; private SecureRandom random; private int s2kCount = 0x60; public BcPBESecretKeyEncryptorBuilder(int encAlgorithm) { this(encAlgorithm, new SHA1PGPDigestCalculator()); } /** * Create an SecretKeyEncryptorBuilder with the S2K count different to the default of 0x60. * * @param encAlgorithm encryption algorithm to use. * @param s2kCount iteration count to use for S2K function. */ public BcPBESecretKeyEncryptorBuilder(int encAlgorithm, int s2kCount) { this(encAlgorithm, new SHA1PGPDigestCalculator(), s2kCount); } /** * Create a builder which will make encryptors using the passed in digest calculator. If a MD5 calculator is * passed in the builder will assume the encryptors are for use with version 3 keys. * * @param encAlgorithm encryption algorithm to use. * @param s2kDigestCalculator digest calculator to use. */ public BcPBESecretKeyEncryptorBuilder(int encAlgorithm, PGPDigestCalculator s2kDigestCalculator) { this(encAlgorithm, s2kDigestCalculator, 0x60); } /** * Create an SecretKeyEncryptorBuilder with the S2k count different to the default of 0x60, and the S2K digest * different from SHA-1. * * @param encAlgorithm encryption algorithm to use. * @param s2kDigestCalculator digest calculator to use. * @param s2kCount iteration count to use for S2K function. */ public BcPBESecretKeyEncryptorBuilder(int encAlgorithm, PGPDigestCalculator s2kDigestCalculator, int s2kCount) { this.encAlgorithm = encAlgorithm; this.s2kDigestCalculator = s2kDigestCalculator; if (s2kCount < 0 || s2kCount > 0xff) { throw new IllegalArgumentException("s2KCount value outside of range 0 to 255."); } this.s2kCount = s2kCount; } /** * Provide a user defined source of randomness. * * @param random the secure random to be used. * @return the current builder. */ public BcPBESecretKeyEncryptorBuilder setSecureRandom(SecureRandom random) { this.random = random; return this; } public PBESecretKeyEncryptor build(char[] passPhrase) { if (this.random == null) { this.random = new SecureRandom(); } return new PBESecretKeyEncryptor(encAlgorithm, s2kDigestCalculator, s2kCount, this.random, passPhrase) { private byte[] iv; public byte[] encryptKeyData(byte[] key, byte[] keyData, int keyOff, int keyLen) throws PGPException { return encryptKeyData(key, null, keyData, keyOff, keyLen); } public byte[] encryptKeyData(byte[] key, byte[] iv, byte[] keyData, int keyOff, int keyLen) throws PGPException { try { BlockCipher engine = BcImplProvider.createBlockCipher(this.encAlgorithm); if (iv != null) { // to deal with V3 key encryption this.iv = iv; } else { if (this.random == null) { this.random = new SecureRandom(); } this.iv = iv = new byte[engine.getBlockSize()]; this.random.nextBytes(iv); } BufferedBlockCipher c = BcUtil.createSymmetricKeyWrapper(true, engine, key, iv); byte[] out = new byte[keyLen]; int outLen = c.processBytes(keyData, keyOff, keyLen, out, 0); outLen += c.doFinal(out, outLen); return out; } catch (InvalidCipherTextException e) { throw new PGPException("decryption failed: " + e.getMessage(), e); } } public byte[] getCipherIV() { return iv; } }; } } ././@LongLink0000000000000000000000000000015100000000000011562 Lustar rootrootbouncycastle-1.49.orig/src/org/bouncycastle/openpgp/operator/bc/BcPGPContentVerifierBuilderProvider.javabouncycastle-1.49.orig/src/org/bouncycastle/openpgp/operator/bc/BcPGPContentVerifierBuilderProvider.0000644000175000017500000000430711600551411033334 0ustar ebourgebourgpackage org.bouncycastle.openpgp.operator.bc; import java.io.OutputStream; import org.bouncycastle.crypto.Signer; import org.bouncycastle.openpgp.PGPException; import org.bouncycastle.openpgp.PGPPublicKey; import org.bouncycastle.openpgp.operator.PGPContentVerifier; import org.bouncycastle.openpgp.operator.PGPContentVerifierBuilder; import org.bouncycastle.openpgp.operator.PGPContentVerifierBuilderProvider; public class BcPGPContentVerifierBuilderProvider implements PGPContentVerifierBuilderProvider { private BcPGPKeyConverter keyConverter = new BcPGPKeyConverter(); public BcPGPContentVerifierBuilderProvider() { } public PGPContentVerifierBuilder get(int keyAlgorithm, int hashAlgorithm) throws PGPException { return new BcPGPContentVerifierBuilder(keyAlgorithm, hashAlgorithm); } private class BcPGPContentVerifierBuilder implements PGPContentVerifierBuilder { private int hashAlgorithm; private int keyAlgorithm; public BcPGPContentVerifierBuilder(int keyAlgorithm, int hashAlgorithm) { this.keyAlgorithm = keyAlgorithm; this.hashAlgorithm = hashAlgorithm; } public PGPContentVerifier build(final PGPPublicKey publicKey) throws PGPException { final Signer signer = BcImplProvider.createSigner(keyAlgorithm, hashAlgorithm); signer.init(false, keyConverter.getPublicKey(publicKey)); return new PGPContentVerifier() { public int getHashAlgorithm() { return hashAlgorithm; } public int getKeyAlgorithm() { return keyAlgorithm; } public long getKeyID() { return publicKey.getKeyID(); } public boolean verify(byte[] expected) { return signer.verifySignature(expected); } public OutputStream getOutputStream() { return new SignerOutputStream(signer); } }; } } } bouncycastle-1.49.orig/src/org/bouncycastle/openpgp/operator/bc/BcUtil.java0000644000175000017500000000451511577002216026424 0ustar ebourgebourgpackage org.bouncycastle.openpgp.operator.bc; import java.io.InputStream; import org.bouncycastle.crypto.BlockCipher; import org.bouncycastle.crypto.BufferedBlockCipher; import org.bouncycastle.crypto.io.CipherInputStream; import org.bouncycastle.crypto.modes.CFBBlockCipher; import org.bouncycastle.crypto.modes.OpenPGPCFBBlockCipher; import org.bouncycastle.crypto.params.KeyParameter; import org.bouncycastle.crypto.params.ParametersWithIV; import org.bouncycastle.openpgp.operator.PGPDataDecryptor; import org.bouncycastle.openpgp.operator.PGPDigestCalculator; class BcUtil { static BufferedBlockCipher createStreamCipher(boolean forEncryption, BlockCipher engine, boolean withIntegrityPacket, byte[] key) { BufferedBlockCipher c; if (withIntegrityPacket) { c = new BufferedBlockCipher(new CFBBlockCipher(engine, engine.getBlockSize() * 8)); } else { c = new BufferedBlockCipher(new OpenPGPCFBBlockCipher(engine)); } KeyParameter keyParameter = new KeyParameter(key); if (withIntegrityPacket) { c.init(forEncryption, new ParametersWithIV(keyParameter, new byte[engine.getBlockSize()])); } else { c.init(forEncryption, keyParameter); } return c; } public static PGPDataDecryptor createDataDecryptor(boolean withIntegrityPacket, BlockCipher engine, byte[] key) { final BufferedBlockCipher c = createStreamCipher(false, engine, withIntegrityPacket, key); return new PGPDataDecryptor() { public InputStream getInputStream(InputStream in) { return new CipherInputStream(in, c); } public int getBlockSize() { return c.getBlockSize(); } public PGPDigestCalculator getIntegrityCalculator() { return new SHA1PGPDigestCalculator(); } }; } public static BufferedBlockCipher createSymmetricKeyWrapper(boolean forEncryption, BlockCipher engine, byte[] key, byte[] iv) { BufferedBlockCipher c = new BufferedBlockCipher(new CFBBlockCipher(engine, engine.getBlockSize() * 8)); c.init(forEncryption, new ParametersWithIV(new KeyParameter(key), iv)); return c; } } bouncycastle-1.49.orig/src/org/bouncycastle/openpgp/operator/bc/BcPGPKeyPair.java0000644000175000017500000000222011732242441027410 0ustar ebourgebourgpackage org.bouncycastle.openpgp.operator.bc; import java.util.Date; import org.bouncycastle.crypto.AsymmetricCipherKeyPair; import org.bouncycastle.crypto.params.AsymmetricKeyParameter; import org.bouncycastle.openpgp.PGPException; import org.bouncycastle.openpgp.PGPKeyPair; import org.bouncycastle.openpgp.PGPPrivateKey; import org.bouncycastle.openpgp.PGPPublicKey; public class BcPGPKeyPair extends PGPKeyPair { private static PGPPublicKey getPublicKey(int algorithm, AsymmetricKeyParameter pubKey, Date date) throws PGPException { return new BcPGPKeyConverter().getPGPPublicKey(algorithm, pubKey, date); } private static PGPPrivateKey getPrivateKey(PGPPublicKey pub, AsymmetricKeyParameter privKey) throws PGPException { return new BcPGPKeyConverter().getPGPPrivateKey(pub, privKey); } public BcPGPKeyPair(int algorithm, AsymmetricCipherKeyPair keyPair, Date date) throws PGPException { this.pub = getPublicKey(algorithm, (AsymmetricKeyParameter)keyPair.getPublic(), date); this.priv = getPrivateKey(this.pub, (AsymmetricKeyParameter)keyPair.getPrivate()); } } bouncycastle-1.49.orig/src/org/bouncycastle/openpgp/operator/bc/BcImplProvider.java0000644000175000017500000001146311600532474030124 0ustar ebourgebourgpackage org.bouncycastle.openpgp.operator.bc; import org.bouncycastle.bcpg.HashAlgorithmTags; import org.bouncycastle.bcpg.PublicKeyAlgorithmTags; import org.bouncycastle.bcpg.SymmetricKeyAlgorithmTags; import org.bouncycastle.crypto.AsymmetricBlockCipher; import org.bouncycastle.crypto.BlockCipher; import org.bouncycastle.crypto.Digest; import org.bouncycastle.crypto.Signer; import org.bouncycastle.crypto.digests.MD2Digest; import org.bouncycastle.crypto.digests.MD5Digest; import org.bouncycastle.crypto.digests.RIPEMD160Digest; import org.bouncycastle.crypto.digests.SHA1Digest; import org.bouncycastle.crypto.digests.SHA224Digest; import org.bouncycastle.crypto.digests.SHA256Digest; import org.bouncycastle.crypto.digests.SHA384Digest; import org.bouncycastle.crypto.digests.SHA512Digest; import org.bouncycastle.crypto.digests.TigerDigest; import org.bouncycastle.crypto.encodings.PKCS1Encoding; import org.bouncycastle.crypto.engines.AESEngine; import org.bouncycastle.crypto.engines.BlowfishEngine; import org.bouncycastle.crypto.engines.CAST5Engine; import org.bouncycastle.crypto.engines.DESEngine; import org.bouncycastle.crypto.engines.DESedeEngine; import org.bouncycastle.crypto.engines.ElGamalEngine; import org.bouncycastle.crypto.engines.RSABlindedEngine; import org.bouncycastle.crypto.engines.TwofishEngine; import org.bouncycastle.crypto.signers.DSADigestSigner; import org.bouncycastle.crypto.signers.DSASigner; import org.bouncycastle.crypto.signers.RSADigestSigner; import org.bouncycastle.openpgp.PGPException; import org.bouncycastle.openpgp.PGPPublicKey; class BcImplProvider { static Digest createDigest(int algorithm) throws PGPException { switch (algorithm) { case HashAlgorithmTags.SHA1: return new SHA1Digest(); case HashAlgorithmTags.SHA224: return new SHA224Digest(); case HashAlgorithmTags.SHA256: return new SHA256Digest(); case HashAlgorithmTags.SHA384: return new SHA384Digest(); case HashAlgorithmTags.SHA512: return new SHA512Digest(); case HashAlgorithmTags.MD2: return new MD2Digest(); case HashAlgorithmTags.MD5: return new MD5Digest(); case HashAlgorithmTags.RIPEMD160: return new RIPEMD160Digest(); case HashAlgorithmTags.TIGER_192: return new TigerDigest(); default: throw new PGPException("cannot recognise digest"); } } static Signer createSigner(int keyAlgorithm, int hashAlgorithm) throws PGPException { switch(keyAlgorithm) { case PublicKeyAlgorithmTags.RSA_GENERAL: case PublicKeyAlgorithmTags.RSA_SIGN: return new RSADigestSigner(createDigest(hashAlgorithm)); case PublicKeyAlgorithmTags.DSA: return new DSADigestSigner(new DSASigner(), createDigest(hashAlgorithm)); default: throw new PGPException("cannot recognise keyAlgorithm"); } } static BlockCipher createBlockCipher(int encAlgorithm) throws PGPException { BlockCipher engine; switch (encAlgorithm) { case SymmetricKeyAlgorithmTags.AES_128: case SymmetricKeyAlgorithmTags.AES_192: case SymmetricKeyAlgorithmTags.AES_256: engine = new AESEngine(); break; case SymmetricKeyAlgorithmTags.BLOWFISH: engine = new BlowfishEngine(); break; case SymmetricKeyAlgorithmTags.CAST5: engine = new CAST5Engine(); break; case SymmetricKeyAlgorithmTags.DES: engine = new DESEngine(); break; case SymmetricKeyAlgorithmTags.TWOFISH: engine = new TwofishEngine(); break; case SymmetricKeyAlgorithmTags.TRIPLE_DES: engine = new DESedeEngine(); break; default: throw new PGPException("cannot recognise cipher"); } return engine; } static AsymmetricBlockCipher createPublicKeyCipher(int encAlgorithm) throws PGPException { AsymmetricBlockCipher c; switch (encAlgorithm) { case PGPPublicKey.RSA_ENCRYPT: case PGPPublicKey.RSA_GENERAL: c = new PKCS1Encoding(new RSABlindedEngine()); break; case PGPPublicKey.ELGAMAL_ENCRYPT: case PGPPublicKey.ELGAMAL_GENERAL: c = new PKCS1Encoding(new ElGamalEngine()); break; case PGPPublicKey.DSA: throw new PGPException("Can't use DSA for encryption."); case PGPPublicKey.ECDSA: throw new PGPException("Can't use ECDSA for encryption."); default: throw new PGPException("unknown asymmetric algorithm: " + encAlgorithm); } return c; } } bouncycastle-1.49.orig/src/org/bouncycastle/openpgp/operator/bc/package.html0000644000175000017500000000034011576524035026657 0ustar ebourgebourg BC lightweight operators for dealing with OpenPGP objects.

    These provide the actual support for encryption and decryption required for the high level OpenPGP classes.

    bouncycastle-1.49.orig/src/org/bouncycastle/openpgp/operator/bc/SignerOutputStream.java0000644000175000017500000000120411600550314031050 0ustar ebourgebourgpackage org.bouncycastle.openpgp.operator.bc; import java.io.IOException; import java.io.OutputStream; import org.bouncycastle.crypto.Signer; class SignerOutputStream extends OutputStream { private Signer sig; SignerOutputStream(Signer sig) { this.sig = sig; } public void write(byte[] bytes, int off, int len) throws IOException { sig.update(bytes, off, len); } public void write(byte[] bytes) throws IOException { sig.update(bytes, 0, bytes.length); } public void write(int b) throws IOException { sig.update((byte)b); } } bouncycastle-1.49.orig/src/org/bouncycastle/openpgp/operator/PGPContentVerifierBuilderProvider.java0000644000175000017500000000037511600326044033350 0ustar ebourgebourgpackage org.bouncycastle.openpgp.operator; import org.bouncycastle.openpgp.PGPException; public interface PGPContentVerifierBuilderProvider { public PGPContentVerifierBuilder get(int keyAlgorithm, int hashAlgorithm) throws PGPException; } bouncycastle-1.49.orig/src/org/bouncycastle/openpgp/operator/PBESecretKeyEncryptor.java0000644000175000017500000000555412151253000031001 0ustar ebourgebourgpackage org.bouncycastle.openpgp.operator; import java.security.SecureRandom; import org.bouncycastle.bcpg.S2K; import org.bouncycastle.openpgp.PGPException; public abstract class PBESecretKeyEncryptor { protected int encAlgorithm; protected char[] passPhrase; protected PGPDigestCalculator s2kDigestCalculator; protected int s2kCount; protected S2K s2k; protected SecureRandom random; protected PBESecretKeyEncryptor(int encAlgorithm, PGPDigestCalculator s2kDigestCalculator, SecureRandom random, char[] passPhrase) { this(encAlgorithm, s2kDigestCalculator, 0x60, random, passPhrase); } protected PBESecretKeyEncryptor(int encAlgorithm, PGPDigestCalculator s2kDigestCalculator, int s2kCount, SecureRandom random, char[] passPhrase) { this.encAlgorithm = encAlgorithm; this.passPhrase = passPhrase; this.random = random; this.s2kDigestCalculator = s2kDigestCalculator; if (s2kCount < 0 || s2kCount > 0xff) { throw new IllegalArgumentException("s2kCount value outside of range 0 to 255."); } this.s2kCount = s2kCount; } public int getAlgorithm() { return encAlgorithm; } public int getHashAlgorithm() { if (s2kDigestCalculator != null) { return s2kDigestCalculator.getAlgorithm(); } return -1; } public byte[] getKey() throws PGPException { return PGPUtil.makeKeyFromPassPhrase(s2kDigestCalculator, encAlgorithm, s2k, passPhrase); } public S2K getS2K() { return s2k; } /** * Key encryption method invoked for V4 keys and greater. * * @param keyData raw key data * @param keyOff offset into rawe key data * @param keyLen length of key data to use. * @return an encryption of the passed in keyData. * @throws PGPException on error in the underlying encryption process. */ public byte[] encryptKeyData(byte[] keyData, int keyOff, int keyLen) throws PGPException { if (s2k == null) { byte[] iv = new byte[8]; random.nextBytes(iv); s2k = new S2K(s2kDigestCalculator.getAlgorithm(), iv, s2kCount); } return encryptKeyData(getKey(), keyData, keyOff, keyLen); } public abstract byte[] encryptKeyData(byte[] key, byte[] keyData, int keyOff, int keyLen) throws PGPException; /** * Encrypt the passed in keyData using the key and the iv provided. *

    * This method is only used for processing version 3 keys. *

    */ public byte[] encryptKeyData(byte[] key, byte[] iv, byte[] keyData, int keyOff, int keyLen) throws PGPException { throw new PGPException("encryption of version 3 keys not supported."); } public abstract byte[] getCipherIV(); } bouncycastle-1.49.orig/src/org/bouncycastle/openpgp/operator/PGPContentVerifierBuilder.java0000644000175000017500000000042711600311225031626 0ustar ebourgebourgpackage org.bouncycastle.openpgp.operator; import org.bouncycastle.openpgp.PGPException; import org.bouncycastle.openpgp.PGPPublicKey; public interface PGPContentVerifierBuilder { public PGPContentVerifier build(final PGPPublicKey publicKey) throws PGPException; } bouncycastle-1.49.orig/src/org/bouncycastle/openpgp/operator/PBESecretKeyDecryptor.java0000644000175000017500000000174511600027102030765 0ustar ebourgebourgpackage org.bouncycastle.openpgp.operator; import org.bouncycastle.bcpg.S2K; import org.bouncycastle.openpgp.PGPException; public abstract class PBESecretKeyDecryptor { private char[] passPhrase; private PGPDigestCalculatorProvider calculatorProvider; protected PBESecretKeyDecryptor(char[] passPhrase, PGPDigestCalculatorProvider calculatorProvider) { this.passPhrase = passPhrase; this.calculatorProvider = calculatorProvider; } public PGPDigestCalculator getChecksumCalculator(int hashAlgorithm) throws PGPException { return calculatorProvider.get(hashAlgorithm); } public byte[] makeKeyFromPassPhrase(int keyAlgorithm, S2K s2k) throws PGPException { return PGPUtil.makeKeyFromPassPhrase(calculatorProvider, keyAlgorithm, s2k, passPhrase); } public abstract byte[] recoverKeyData(int encAlgorithm, byte[] key, byte[] iv, byte[] keyData, int keyOff, int keyLen) throws PGPException; } bouncycastle-1.49.orig/src/org/bouncycastle/openpgp/operator/PGPContentSignerBuilder.java0000644000175000017500000000045711577777740031344 0ustar ebourgebourgpackage org.bouncycastle.openpgp.operator; import org.bouncycastle.openpgp.PGPException; import org.bouncycastle.openpgp.PGPPrivateKey; public interface PGPContentSignerBuilder { public PGPContentSigner build(final int signatureType, final PGPPrivateKey privateKey) throws PGPException; } bouncycastle-1.49.orig/src/org/bouncycastle/openpgp/operator/PublicKeyDataDecryptorFactory.java0000644000175000017500000000050111576514530032560 0ustar ebourgebourgpackage org.bouncycastle.openpgp.operator; import java.math.BigInteger; import org.bouncycastle.openpgp.PGPException; public interface PublicKeyDataDecryptorFactory extends PGPDataDecryptorFactory { public byte[] recoverSessionData(int keyAlgorithm, BigInteger[] secKeyData) throws PGPException; } bouncycastle-1.49.orig/src/org/bouncycastle/openpgp/operator/PGPDataDecryptorFactory.java0000644000175000017500000000042011576541432031320 0ustar ebourgebourgpackage org.bouncycastle.openpgp.operator; import org.bouncycastle.openpgp.PGPException; public interface PGPDataDecryptorFactory { public PGPDataDecryptor createDataDecryptor(boolean withIntegrityPacket, int encAlgorithm, byte[] key) throws PGPException; } bouncycastle-1.49.orig/src/org/bouncycastle/openpgp/operator/PGPDigestCalculator.java0000644000175000017500000000156311577255017030467 0ustar ebourgebourgpackage org.bouncycastle.openpgp.operator; import java.io.OutputStream; public interface PGPDigestCalculator { /** * Return the algorithm number representing the digest implemented by * this calculator. * * @return algorithm number */ int getAlgorithm(); /** * Returns a stream that will accept data for the purpose of calculating * a digest. Use org.bouncycastle.util.io.TeeOutputStream if you want to accumulate * the data on the fly as well. * * @return an OutputStream */ OutputStream getOutputStream(); /** * Return the digest calculated on what has been written to the calculator's output stream. * * @return a digest. */ byte[] getDigest(); /** * Reset the underlying digest calculator */ void reset(); } bouncycastle-1.49.orig/src/org/bouncycastle/openpgp/operator/jcajce/0000755000175000017500000000000012152033551025221 5ustar ebourgebourgbouncycastle-1.49.orig/src/org/bouncycastle/openpgp/operator/jcajce/PGPUtil.java0000644000175000017500000001064011723536614027364 0ustar ebourgebourgpackage org.bouncycastle.openpgp.operator.jcajce; import javax.crypto.SecretKey; import javax.crypto.spec.SecretKeySpec; import org.bouncycastle.bcpg.HashAlgorithmTags; import org.bouncycastle.bcpg.PublicKeyAlgorithmTags; import org.bouncycastle.bcpg.SymmetricKeyAlgorithmTags; import org.bouncycastle.openpgp.PGPException; /** * Basic utility class */ class PGPUtil { static String getDigestName( int hashAlgorithm) throws PGPException { switch (hashAlgorithm) { case HashAlgorithmTags.SHA1: return "SHA1"; case HashAlgorithmTags.MD2: return "MD2"; case HashAlgorithmTags.MD5: return "MD5"; case HashAlgorithmTags.RIPEMD160: return "RIPEMD160"; case HashAlgorithmTags.SHA256: return "SHA256"; case HashAlgorithmTags.SHA384: return "SHA384"; case HashAlgorithmTags.SHA512: return "SHA512"; case HashAlgorithmTags.SHA224: return "SHA224"; case HashAlgorithmTags.TIGER_192: return "TIGER"; default: throw new PGPException("unknown hash algorithm tag in getDigestName: " + hashAlgorithm); } } static String getSignatureName( int keyAlgorithm, int hashAlgorithm) throws PGPException { String encAlg; switch (keyAlgorithm) { case PublicKeyAlgorithmTags.RSA_GENERAL: case PublicKeyAlgorithmTags.RSA_SIGN: encAlg = "RSA"; break; case PublicKeyAlgorithmTags.DSA: encAlg = "DSA"; break; case PublicKeyAlgorithmTags.ELGAMAL_ENCRYPT: // in some malformed cases. case PublicKeyAlgorithmTags.ELGAMAL_GENERAL: encAlg = "ElGamal"; break; default: throw new PGPException("unknown algorithm tag in signature:" + keyAlgorithm); } return getDigestName(hashAlgorithm) + "with" + encAlg; } static String getSymmetricCipherName( int algorithm) { switch (algorithm) { case SymmetricKeyAlgorithmTags.NULL: return null; case SymmetricKeyAlgorithmTags.TRIPLE_DES: return "DESEDE"; case SymmetricKeyAlgorithmTags.IDEA: return "IDEA"; case SymmetricKeyAlgorithmTags.CAST5: return "CAST5"; case SymmetricKeyAlgorithmTags.BLOWFISH: return "Blowfish"; case SymmetricKeyAlgorithmTags.SAFER: return "SAFER"; case SymmetricKeyAlgorithmTags.DES: return "DES"; case SymmetricKeyAlgorithmTags.AES_128: return "AES"; case SymmetricKeyAlgorithmTags.AES_192: return "AES"; case SymmetricKeyAlgorithmTags.AES_256: return "AES"; case SymmetricKeyAlgorithmTags.TWOFISH: return "Twofish"; default: throw new IllegalArgumentException("unknown symmetric algorithm: " + algorithm); } } public static SecretKey makeSymmetricKey( int algorithm, byte[] keyBytes) throws PGPException { String algName; switch (algorithm) { case SymmetricKeyAlgorithmTags.TRIPLE_DES: algName = "DES_EDE"; break; case SymmetricKeyAlgorithmTags.IDEA: algName = "IDEA"; break; case SymmetricKeyAlgorithmTags.CAST5: algName = "CAST5"; break; case SymmetricKeyAlgorithmTags.BLOWFISH: algName = "Blowfish"; break; case SymmetricKeyAlgorithmTags.SAFER: algName = "SAFER"; break; case SymmetricKeyAlgorithmTags.DES: algName = "DES"; break; case SymmetricKeyAlgorithmTags.AES_128: algName = "AES"; break; case SymmetricKeyAlgorithmTags.AES_192: algName = "AES"; break; case SymmetricKeyAlgorithmTags.AES_256: algName = "AES"; break; case SymmetricKeyAlgorithmTags.TWOFISH: algName = "Twofish"; break; default: throw new PGPException("unknown symmetric algorithm: " + algorithm); } return new SecretKeySpec(keyBytes, algName); } } bouncycastle-1.49.orig/src/org/bouncycastle/openpgp/operator/jcajce/JcaPGPKeyPair.java0000644000175000017500000000205111732262004030413 0ustar ebourgebourgpackage org.bouncycastle.openpgp.operator.jcajce; import java.security.KeyPair; import java.security.PrivateKey; import java.security.PublicKey; import java.util.Date; import org.bouncycastle.openpgp.PGPException; import org.bouncycastle.openpgp.PGPKeyPair; import org.bouncycastle.openpgp.PGPPrivateKey; import org.bouncycastle.openpgp.PGPPublicKey; public class JcaPGPKeyPair extends PGPKeyPair { private static PGPPublicKey getPublicKey(int algorithm, PublicKey pubKey, Date date) throws PGPException { return new JcaPGPKeyConverter().getPGPPublicKey(algorithm, pubKey, date); } private static PGPPrivateKey getPrivateKey(PGPPublicKey pub, PrivateKey privKey) throws PGPException { return new JcaPGPKeyConverter().getPGPPrivateKey(pub, privKey); } public JcaPGPKeyPair(int algorithm, KeyPair keyPair, Date date) throws PGPException { this.pub = getPublicKey(algorithm, keyPair.getPublic(), date); this.priv = getPrivateKey(this.pub, keyPair.getPrivate()); } } ././@LongLink0000000000000000000000000000015100000000000011562 Lustar rootrootbouncycastle-1.49.orig/src/org/bouncycastle/openpgp/operator/jcajce/JcePBESecretKeyDecryptorBuilder.javabouncycastle-1.49.orig/src/org/bouncycastle/openpgp/operator/jcajce/JcePBESecretKeyDecryptorBuilder.0000644000175000017500000000655711723537700033321 0ustar ebourgebourgpackage org.bouncycastle.openpgp.operator.jcajce; import java.security.InvalidAlgorithmParameterException; import java.security.InvalidKeyException; import java.security.Provider; import javax.crypto.BadPaddingException; import javax.crypto.Cipher; import javax.crypto.IllegalBlockSizeException; import javax.crypto.spec.IvParameterSpec; import org.bouncycastle.jcajce.DefaultJcaJceHelper; import org.bouncycastle.jcajce.NamedJcaJceHelper; import org.bouncycastle.jcajce.ProviderJcaJceHelper; import org.bouncycastle.openpgp.PGPException; import org.bouncycastle.openpgp.operator.PBESecretKeyDecryptor; import org.bouncycastle.openpgp.operator.PGPDigestCalculatorProvider; public class JcePBESecretKeyDecryptorBuilder { private OperatorHelper helper = new OperatorHelper(new DefaultJcaJceHelper()); private PGPDigestCalculatorProvider calculatorProvider; private JcaPGPDigestCalculatorProviderBuilder calculatorProviderBuilder; public JcePBESecretKeyDecryptorBuilder() { this.calculatorProviderBuilder = new JcaPGPDigestCalculatorProviderBuilder(); } public JcePBESecretKeyDecryptorBuilder(PGPDigestCalculatorProvider calculatorProvider) { this.calculatorProvider = calculatorProvider; } public JcePBESecretKeyDecryptorBuilder setProvider(Provider provider) { this.helper = new OperatorHelper(new ProviderJcaJceHelper(provider)); if (calculatorProviderBuilder != null) { calculatorProviderBuilder.setProvider(provider); } return this; } public JcePBESecretKeyDecryptorBuilder setProvider(String providerName) { this.helper = new OperatorHelper(new NamedJcaJceHelper(providerName)); if (calculatorProviderBuilder != null) { calculatorProviderBuilder.setProvider(providerName); } return this; } public PBESecretKeyDecryptor build(char[] passPhrase) throws PGPException { if (calculatorProvider == null) { calculatorProvider = calculatorProviderBuilder.build(); } return new PBESecretKeyDecryptor(passPhrase, calculatorProvider) { public byte[] recoverKeyData(int encAlgorithm, byte[] key, byte[] iv, byte[] keyData, int keyOff, int keyLen) throws PGPException { try { Cipher c = helper.createCipher(PGPUtil.getSymmetricCipherName(encAlgorithm) + "/CFB/NoPadding"); c.init(Cipher.DECRYPT_MODE, PGPUtil.makeSymmetricKey(encAlgorithm, key), new IvParameterSpec(iv)); return c.doFinal(keyData, keyOff, keyLen); } catch (IllegalBlockSizeException e) { throw new PGPException("illegal block size: " + e.getMessage(), e); } catch (BadPaddingException e) { throw new PGPException("bad padding: " + e.getMessage(), e); } catch (InvalidAlgorithmParameterException e) { throw new PGPException("invalid parameter: " + e.getMessage(), e); } catch (InvalidKeyException e) { throw new PGPException("invalid key: " + e.getMessage(), e); } } }; } } bouncycastle-1.49.orig/src/org/bouncycastle/openpgp/operator/jcajce/SHA1PGPDigestCalculator.java0000644000175000017500000000322712103446476032317 0ustar ebourgebourgpackage org.bouncycastle.openpgp.operator.jcajce; import java.io.IOException; import java.io.OutputStream; import java.security.MessageDigest; import java.security.NoSuchAlgorithmException; import org.bouncycastle.bcpg.HashAlgorithmTags; import org.bouncycastle.openpgp.operator.PGPDigestCalculator; class SHA1PGPDigestCalculator implements PGPDigestCalculator { private MessageDigest digest; SHA1PGPDigestCalculator() { try { digest = MessageDigest.getInstance("SHA1"); } catch (NoSuchAlgorithmException e) { throw new IllegalStateException("cannot find SHA-1: " + e.getMessage()); } } public int getAlgorithm() { return HashAlgorithmTags.SHA1; } public OutputStream getOutputStream() { return new DigestOutputStream(digest); } public byte[] getDigest() { return digest.digest(); } public void reset() { digest.reset(); } private class DigestOutputStream extends OutputStream { private MessageDigest dig; DigestOutputStream(MessageDigest dig) { this.dig = dig; } public void write(byte[] bytes, int off, int len) throws IOException { dig.update(bytes, off, len); } public void write(byte[] bytes) throws IOException { dig.update(bytes); } public void write(int b) throws IOException { dig.update((byte)b); } byte[] getDigest() { return dig.digest(); } } } ././@LongLink0000000000000000000000000000015400000000000011565 Lustar rootrootbouncycastle-1.49.orig/src/org/bouncycastle/openpgp/operator/jcajce/JcePBEKeyEncryptionMethodGenerator.javabouncycastle-1.49.orig/src/org/bouncycastle/openpgp/operator/jcajce/JcePBEKeyEncryptionMethodGenerat0000644000175000017500000001116112057004410033363 0ustar ebourgebourgpackage org.bouncycastle.openpgp.operator.jcajce; import java.security.InvalidAlgorithmParameterException; import java.security.InvalidKeyException; import java.security.Provider; import java.security.SecureRandom; import javax.crypto.BadPaddingException; import javax.crypto.Cipher; import javax.crypto.IllegalBlockSizeException; import javax.crypto.SecretKey; import javax.crypto.spec.IvParameterSpec; import javax.crypto.spec.SecretKeySpec; import org.bouncycastle.jcajce.DefaultJcaJceHelper; import org.bouncycastle.jcajce.NamedJcaJceHelper; import org.bouncycastle.jcajce.ProviderJcaJceHelper; import org.bouncycastle.openpgp.PGPException; import org.bouncycastle.openpgp.operator.PBEKeyEncryptionMethodGenerator; import org.bouncycastle.openpgp.operator.PGPDigestCalculator; /** * JCE based generator for password based encryption (PBE) data protection methods. */ public class JcePBEKeyEncryptionMethodGenerator extends PBEKeyEncryptionMethodGenerator { private OperatorHelper helper = new OperatorHelper(new DefaultJcaJceHelper()); /** * Create a PBE encryption method generator using the provided calculator for key calculation. * * @param passPhrase the passphrase to use as the primary source of key material. * @param s2kDigestCalculator the digest calculator to use for key calculation. */ public JcePBEKeyEncryptionMethodGenerator(char[] passPhrase, PGPDigestCalculator s2kDigestCalculator) { super(passPhrase, s2kDigestCalculator); } /** * Create a PBE encryption method generator using the default SHA-1 digest calculator for key calculation. * * @param passPhrase the passphrase to use as the primary source of key material. */ public JcePBEKeyEncryptionMethodGenerator(char[] passPhrase) { this(passPhrase, new SHA1PGPDigestCalculator()); } /** * Create a PBE encryption method generator using the provided calculator and S2K count for key calculation. * * @param passPhrase the passphrase to use as the primary source of key material. * @param s2kDigestCalculator the digest calculator to use for key calculation. * @param s2kCount the S2K count to use. */ public JcePBEKeyEncryptionMethodGenerator(char[] passPhrase, PGPDigestCalculator s2kDigestCalculator, int s2kCount) { super(passPhrase, s2kDigestCalculator, s2kCount); } /** * Create a PBE encryption method generator using the default SHA-1 digest calculator and * a S2K count other than the default of 0x60 for key calculation * * @param passPhrase the passphrase to use as the primary source of key material. * @param s2kCount the S2K count to use. */ public JcePBEKeyEncryptionMethodGenerator(char[] passPhrase, int s2kCount) { super(passPhrase, new SHA1PGPDigestCalculator(), s2kCount); } public JcePBEKeyEncryptionMethodGenerator setProvider(Provider provider) { this.helper = new OperatorHelper(new ProviderJcaJceHelper(provider)); return this; } public JcePBEKeyEncryptionMethodGenerator setProvider(String providerName) { this.helper = new OperatorHelper(new NamedJcaJceHelper(providerName)); return this; } /** * Provide a user defined source of randomness. * * @param random the secure random to be used. * @return the current generator. */ public PBEKeyEncryptionMethodGenerator setSecureRandom(SecureRandom random) { super.setSecureRandom(random); return this; } protected byte[] encryptSessionInfo(int encAlgorithm, byte[] key, byte[] sessionInfo) throws PGPException { try { String cName = PGPUtil.getSymmetricCipherName(encAlgorithm); Cipher c = helper.createCipher(cName + "/CFB/NoPadding"); SecretKey sKey = new SecretKeySpec(key, PGPUtil.getSymmetricCipherName(encAlgorithm)); c.init(Cipher.ENCRYPT_MODE, sKey, new IvParameterSpec(new byte[c.getBlockSize()])); return c.doFinal(sessionInfo, 0, sessionInfo.length); } catch (IllegalBlockSizeException e) { throw new PGPException("illegal block size: " + e.getMessage(), e); } catch (BadPaddingException e) { throw new PGPException("bad padding: " + e.getMessage(), e); } catch (InvalidAlgorithmParameterException e) { throw new PGPException("IV invalid: " + e.getMessage(), e); } catch (InvalidKeyException e) { throw new PGPException("key invalid: " + e.getMessage(), e); } } } ././@LongLink0000000000000000000000000000015100000000000011562 Lustar rootrootbouncycastle-1.49.orig/src/org/bouncycastle/openpgp/operator/jcajce/JcePBESecretKeyEncryptorBuilder.javabouncycastle-1.49.orig/src/org/bouncycastle/openpgp/operator/jcajce/JcePBESecretKeyEncryptorBuilder.0000644000175000017500000001410312145535041033310 0ustar ebourgebourgpackage org.bouncycastle.openpgp.operator.jcajce; import java.security.InvalidAlgorithmParameterException; import java.security.InvalidKeyException; import java.security.Provider; import java.security.SecureRandom; import javax.crypto.BadPaddingException; import javax.crypto.Cipher; import javax.crypto.IllegalBlockSizeException; import javax.crypto.spec.IvParameterSpec; import org.bouncycastle.jcajce.DefaultJcaJceHelper; import org.bouncycastle.jcajce.NamedJcaJceHelper; import org.bouncycastle.jcajce.ProviderJcaJceHelper; import org.bouncycastle.openpgp.PGPException; import org.bouncycastle.openpgp.operator.PBESecretKeyEncryptor; import org.bouncycastle.openpgp.operator.PGPDigestCalculator; public class JcePBESecretKeyEncryptorBuilder { private OperatorHelper helper = new OperatorHelper(new DefaultJcaJceHelper()); private int encAlgorithm; private PGPDigestCalculator s2kDigestCalculator; private SecureRandom random; private int s2kCount = 0x60; public JcePBESecretKeyEncryptorBuilder(int encAlgorithm) { this(encAlgorithm, new SHA1PGPDigestCalculator()); } /** * Create a SecretKeyEncryptorBuilder with the S2K count different to the default of 0x60. * * @param encAlgorithm encryption algorithm to use. * @param s2kCount iteration count to use for S2K function. */ public JcePBESecretKeyEncryptorBuilder(int encAlgorithm, int s2kCount) { this(encAlgorithm, new SHA1PGPDigestCalculator(), s2kCount); } /** * Create a builder which will make encryptors using the passed in digest calculator. If a MD5 calculator is * passed in the builder will assume the encryptors are for use with version 3 keys. * * @param encAlgorithm encryption algorithm to use. * @param s2kDigestCalculator digest calculator to use. */ public JcePBESecretKeyEncryptorBuilder(int encAlgorithm, PGPDigestCalculator s2kDigestCalculator) { this(encAlgorithm, s2kDigestCalculator, 0x60); } /** * Create an SecretKeyEncryptorBuilder with the S2k count different to the default of 0x60, and the S2K digest * different from SHA-1. * * @param encAlgorithm encryption algorithm to use. * @param s2kDigestCalculator digest calculator to use. * @param s2kCount iteration count to use for S2K function. */ public JcePBESecretKeyEncryptorBuilder(int encAlgorithm, PGPDigestCalculator s2kDigestCalculator, int s2kCount) { this.encAlgorithm = encAlgorithm; this.s2kDigestCalculator = s2kDigestCalculator; if (s2kCount < 0 || s2kCount > 0xff) { throw new IllegalArgumentException("s2KCount value outside of range 0 to 255."); } this.s2kCount = s2kCount; } public JcePBESecretKeyEncryptorBuilder setProvider(Provider provider) { this.helper = new OperatorHelper(new ProviderJcaJceHelper(provider)); return this; } public JcePBESecretKeyEncryptorBuilder setProvider(String providerName) { this.helper = new OperatorHelper(new NamedJcaJceHelper(providerName)); return this; } /** * Provide a user defined source of randomness. * * @param random the secure random to be used. * @return the current builder. */ public JcePBESecretKeyEncryptorBuilder setSecureRandom(SecureRandom random) { this.random = random; return this; } public PBESecretKeyEncryptor build(char[] passPhrase) { if (random == null) { random = new SecureRandom(); } return new PBESecretKeyEncryptor(encAlgorithm, s2kDigestCalculator, s2kCount, random, passPhrase) { private Cipher c; private byte[] iv; public byte[] encryptKeyData(byte[] key, byte[] keyData, int keyOff, int keyLen) throws PGPException { try { c = helper.createCipher(PGPUtil.getSymmetricCipherName(this.encAlgorithm) + "/CFB/NoPadding"); c.init(Cipher.ENCRYPT_MODE, PGPUtil.makeSymmetricKey(this.encAlgorithm, key), this.random); iv = c.getIV(); return c.doFinal(keyData, keyOff, keyLen); } catch (IllegalBlockSizeException e) { throw new PGPException("illegal block size: " + e.getMessage(), e); } catch (BadPaddingException e) { throw new PGPException("bad padding: " + e.getMessage(), e); } catch (InvalidKeyException e) { throw new PGPException("invalid key: " + e.getMessage(), e); } } public byte[] encryptKeyData(byte[] key, byte[] iv, byte[] keyData, int keyOff, int keyLen) throws PGPException { try { c = helper.createCipher(PGPUtil.getSymmetricCipherName(this.encAlgorithm) + "/CFB/NoPadding"); c.init(Cipher.ENCRYPT_MODE, PGPUtil.makeSymmetricKey(this.encAlgorithm, key), new IvParameterSpec(iv)); this.iv = iv; return c.doFinal(keyData, keyOff, keyLen); } catch (IllegalBlockSizeException e) { throw new PGPException("illegal block size: " + e.getMessage(), e); } catch (BadPaddingException e) { throw new PGPException("bad padding: " + e.getMessage(), e); } catch (InvalidKeyException e) { throw new PGPException("invalid key: " + e.getMessage(), e); } catch (InvalidAlgorithmParameterException e) { throw new PGPException("invalid iv: " + e.getMessage(), e); } } public byte[] getCipherIV() { return iv; } }; } } ././@LongLink0000000000000000000000000000015300000000000011564 Lustar rootrootbouncycastle-1.49.orig/src/org/bouncycastle/openpgp/operator/jcajce/JcePBEDataDecryptorFactoryBuilder.javabouncycastle-1.49.orig/src/org/bouncycastle/openpgp/operator/jcajce/JcePBEDataDecryptorFactoryBuilde0000644000175000017500000000720311723537700033351 0ustar ebourgebourgpackage org.bouncycastle.openpgp.operator.jcajce; import java.security.Provider; import javax.crypto.Cipher; import javax.crypto.spec.IvParameterSpec; import javax.crypto.spec.SecretKeySpec; import org.bouncycastle.jcajce.DefaultJcaJceHelper; import org.bouncycastle.jcajce.NamedJcaJceHelper; import org.bouncycastle.jcajce.ProviderJcaJceHelper; import org.bouncycastle.openpgp.PGPException; import org.bouncycastle.openpgp.operator.PBEDataDecryptorFactory; import org.bouncycastle.openpgp.operator.PGPDataDecryptor; import org.bouncycastle.openpgp.operator.PGPDigestCalculatorProvider; public class JcePBEDataDecryptorFactoryBuilder { private OperatorHelper helper = new OperatorHelper(new DefaultJcaJceHelper()); private PGPDigestCalculatorProvider calculatorProvider; /** * Base constructor. * * @param calculatorProvider a digest calculator provider to provide calculators to support the key generation calculation required. */ public JcePBEDataDecryptorFactoryBuilder(PGPDigestCalculatorProvider calculatorProvider) { this.calculatorProvider = calculatorProvider; } /** * Set the provider object to use for creating cryptographic primitives in the resulting factory the builder produces. * * @param provider provider object for cryptographic primitives. * @return the current builder. */ public JcePBEDataDecryptorFactoryBuilder setProvider(Provider provider) { this.helper = new OperatorHelper(new ProviderJcaJceHelper(provider)); return this; } /** * Set the provider name to use for creating cryptographic primitives in the resulting factory the builder produces. * * @param providerName the name of the provider to reference for cryptographic primitives. * @return the current builder. */ public JcePBEDataDecryptorFactoryBuilder setProvider(String providerName) { this.helper = new OperatorHelper(new NamedJcaJceHelper(providerName)); return this; } public PBEDataDecryptorFactory build(char[] passPhrase) { return new PBEDataDecryptorFactory(passPhrase, calculatorProvider) { public byte[] recoverSessionData(int keyAlgorithm, byte[] key, byte[] secKeyData) throws PGPException { try { if (secKeyData != null && secKeyData.length > 0) { String cipherName = PGPUtil.getSymmetricCipherName(keyAlgorithm); Cipher keyCipher = helper.createCipher(cipherName + "/CFB/NoPadding"); keyCipher.init(Cipher.DECRYPT_MODE, new SecretKeySpec(key, cipherName), new IvParameterSpec(new byte[keyCipher.getBlockSize()])); return keyCipher.doFinal(secKeyData); } else { byte[] keyBytes = new byte[key.length + 1]; keyBytes[0] = (byte)keyAlgorithm; System.arraycopy(key, 0, keyBytes, 1, key.length); return keyBytes; } } catch (Exception e) { throw new PGPException("Exception recovering session info", e); } } public PGPDataDecryptor createDataDecryptor(boolean withIntegrityPacket, int encAlgorithm, byte[] key) throws PGPException { return helper.createDataDecryptor(withIntegrityPacket, encAlgorithm, key); } }; } } bouncycastle-1.49.orig/src/org/bouncycastle/openpgp/operator/jcajce/JcaPGPContentSignerBuilder.java0000644000175000017500000001144712111372023033144 0ustar ebourgebourgpackage org.bouncycastle.openpgp.operator.jcajce; import java.io.OutputStream; import java.security.InvalidKeyException; import java.security.PrivateKey; import java.security.Provider; import java.security.SecureRandom; import java.security.Signature; import java.security.SignatureException; import org.bouncycastle.jcajce.DefaultJcaJceHelper; import org.bouncycastle.jcajce.NamedJcaJceHelper; import org.bouncycastle.jcajce.ProviderJcaJceHelper; import org.bouncycastle.openpgp.PGPException; import org.bouncycastle.openpgp.PGPPrivateKey; import org.bouncycastle.openpgp.operator.PGPContentSigner; import org.bouncycastle.openpgp.operator.PGPContentSignerBuilder; import org.bouncycastle.openpgp.operator.PGPDigestCalculator; import org.bouncycastle.util.io.TeeOutputStream; public class JcaPGPContentSignerBuilder implements PGPContentSignerBuilder { private OperatorHelper helper = new OperatorHelper(new DefaultJcaJceHelper()); private JcaPGPDigestCalculatorProviderBuilder digestCalculatorProviderBuilder = new JcaPGPDigestCalculatorProviderBuilder(); private JcaPGPKeyConverter keyConverter = new JcaPGPKeyConverter(); private int hashAlgorithm; private SecureRandom random; private int keyAlgorithm; public JcaPGPContentSignerBuilder(int keyAlgorithm, int hashAlgorithm) { this.keyAlgorithm = keyAlgorithm; this.hashAlgorithm = hashAlgorithm; } public JcaPGPContentSignerBuilder setSecureRandom(SecureRandom random) { this.random = random; return this; } public JcaPGPContentSignerBuilder setProvider(Provider provider) { this.helper = new OperatorHelper(new ProviderJcaJceHelper(provider)); keyConverter.setProvider(provider); digestCalculatorProviderBuilder.setProvider(provider); return this; } public JcaPGPContentSignerBuilder setProvider(String providerName) { this.helper = new OperatorHelper(new NamedJcaJceHelper(providerName)); keyConverter.setProvider(providerName); digestCalculatorProviderBuilder.setProvider(providerName); return this; } public JcaPGPContentSignerBuilder setDigestProvider(Provider provider) { digestCalculatorProviderBuilder.setProvider(provider); return this; } public JcaPGPContentSignerBuilder setDigestProvider(String providerName) { digestCalculatorProviderBuilder.setProvider(providerName); return this; } public PGPContentSigner build(final int signatureType, PGPPrivateKey privateKey) throws PGPException { if (privateKey instanceof JcaPGPPrivateKey) { return build(signatureType, privateKey.getKeyID(), ((JcaPGPPrivateKey)privateKey).getPrivateKey()); } else { return build(signatureType, privateKey.getKeyID(), keyConverter.getPrivateKey(privateKey)); } } public PGPContentSigner build(final int signatureType, final long keyID, final PrivateKey privateKey) throws PGPException { final PGPDigestCalculator digestCalculator = digestCalculatorProviderBuilder.build().get(hashAlgorithm); final Signature signature = helper.createSignature(keyAlgorithm, hashAlgorithm); try { if (random != null) { signature.initSign(privateKey, random); } else { signature.initSign(privateKey); } } catch (InvalidKeyException e) { throw new PGPException("invalid key.", e); } return new PGPContentSigner() { public int getType() { return signatureType; } public int getHashAlgorithm() { return hashAlgorithm; } public int getKeyAlgorithm() { return keyAlgorithm; } public long getKeyID() { return keyID; } public OutputStream getOutputStream() { return new TeeOutputStream(new SignatureOutputStream(signature), digestCalculator.getOutputStream()); } public byte[] getSignature() { try { return signature.sign(); } catch (SignatureException e) { // TODO: need a specific runtime exception for PGP operators. throw new IllegalStateException("unable to create signature"); } } public byte[] getDigest() { return digestCalculator.getDigest(); } }; } } ././@LongLink0000000000000000000000000000015700000000000011570 Lustar rootrootbouncycastle-1.49.orig/src/org/bouncycastle/openpgp/operator/jcajce/JcaPGPDigestCalculatorProviderBuilder.javabouncycastle-1.49.orig/src/org/bouncycastle/openpgp/operator/jcajce/JcaPGPDigestCalculatorProviderBu0000644000175000017500000000613511723537700033401 0ustar ebourgebourgpackage org.bouncycastle.openpgp.operator.jcajce; import java.io.IOException; import java.io.OutputStream; import java.security.GeneralSecurityException; import java.security.MessageDigest; import java.security.Provider; import org.bouncycastle.jcajce.DefaultJcaJceHelper; import org.bouncycastle.jcajce.NamedJcaJceHelper; import org.bouncycastle.jcajce.ProviderJcaJceHelper; import org.bouncycastle.openpgp.PGPException; import org.bouncycastle.openpgp.operator.PGPDigestCalculator; import org.bouncycastle.openpgp.operator.PGPDigestCalculatorProvider; public class JcaPGPDigestCalculatorProviderBuilder { private OperatorHelper helper = new OperatorHelper(new DefaultJcaJceHelper()); public JcaPGPDigestCalculatorProviderBuilder() { } public JcaPGPDigestCalculatorProviderBuilder setProvider(Provider provider) { this.helper = new OperatorHelper(new ProviderJcaJceHelper(provider)); return this; } public JcaPGPDigestCalculatorProviderBuilder setProvider(String providerName) { this.helper = new OperatorHelper(new NamedJcaJceHelper(providerName)); return this; } public PGPDigestCalculatorProvider build() throws PGPException { return new PGPDigestCalculatorProvider() { public PGPDigestCalculator get(final int algorithm) throws PGPException { final DigestOutputStream stream; final MessageDigest dig; try { dig = helper.createDigest(algorithm); stream = new DigestOutputStream(dig); } catch (GeneralSecurityException e) { throw new PGPException("exception on setup: " + e, e); } return new PGPDigestCalculator() { public int getAlgorithm() { return algorithm; } public OutputStream getOutputStream() { return stream; } public byte[] getDigest() { return stream.getDigest(); } public void reset() { dig.reset(); } }; } }; } private class DigestOutputStream extends OutputStream { private MessageDigest dig; DigestOutputStream(MessageDigest dig) { this.dig = dig; } public void write(byte[] bytes, int off, int len) throws IOException { dig.update(bytes, off, len); } public void write(byte[] bytes) throws IOException { dig.update(bytes); } public void write(int b) throws IOException { dig.update((byte)b); } byte[] getDigest() { return dig.digest(); } } } ././@LongLink0000000000000000000000000000015600000000000011567 Lustar rootrootbouncycastle-1.49.orig/src/org/bouncycastle/openpgp/operator/jcajce/JcaPGPContentVerifierBuilderProvider.javabouncycastle-1.49.orig/src/org/bouncycastle/openpgp/operator/jcajce/JcaPGPContentVerifierBuilderProv0000644000175000017500000000677211723537700033441 0ustar ebourgebourgpackage org.bouncycastle.openpgp.operator.jcajce; import java.io.OutputStream; import java.security.InvalidKeyException; import java.security.Provider; import java.security.Signature; import java.security.SignatureException; import org.bouncycastle.jcajce.DefaultJcaJceHelper; import org.bouncycastle.jcajce.NamedJcaJceHelper; import org.bouncycastle.jcajce.ProviderJcaJceHelper; import org.bouncycastle.openpgp.PGPException; import org.bouncycastle.openpgp.PGPPublicKey; import org.bouncycastle.openpgp.operator.PGPContentVerifier; import org.bouncycastle.openpgp.operator.PGPContentVerifierBuilder; import org.bouncycastle.openpgp.operator.PGPContentVerifierBuilderProvider; public class JcaPGPContentVerifierBuilderProvider implements PGPContentVerifierBuilderProvider { private OperatorHelper helper = new OperatorHelper(new DefaultJcaJceHelper()); private JcaPGPKeyConverter keyConverter = new JcaPGPKeyConverter(); public JcaPGPContentVerifierBuilderProvider() { } public JcaPGPContentVerifierBuilderProvider setProvider(Provider provider) { this.helper = new OperatorHelper(new ProviderJcaJceHelper(provider)); keyConverter.setProvider(provider); return this; } public JcaPGPContentVerifierBuilderProvider setProvider(String providerName) { this.helper = new OperatorHelper(new NamedJcaJceHelper(providerName)); keyConverter.setProvider(providerName); return this; } public PGPContentVerifierBuilder get(int keyAlgorithm, int hashAlgorithm) throws PGPException { return new JcaPGPContentVerifierBuilder(keyAlgorithm, hashAlgorithm); } private class JcaPGPContentVerifierBuilder implements PGPContentVerifierBuilder { private int hashAlgorithm; private int keyAlgorithm; public JcaPGPContentVerifierBuilder(int keyAlgorithm, int hashAlgorithm) { this.keyAlgorithm = keyAlgorithm; this.hashAlgorithm = hashAlgorithm; } public PGPContentVerifier build(final PGPPublicKey publicKey) throws PGPException { final Signature signature = helper.createSignature(keyAlgorithm, hashAlgorithm); try { signature.initVerify(keyConverter.getPublicKey(publicKey)); } catch (InvalidKeyException e) { throw new PGPException("invalid key.", e); } return new PGPContentVerifier() { public int getHashAlgorithm() { return hashAlgorithm; } public int getKeyAlgorithm() { return keyAlgorithm; } public long getKeyID() { return publicKey.getKeyID(); } public boolean verify(byte[] expected) { try { return signature.verify(expected); } catch (SignatureException e) { // TODO: need a specific runtime exception for PGP operators. throw new IllegalStateException("unable to verify signature"); } } public OutputStream getOutputStream() { return new SignatureOutputStream(signature); } }; } } } bouncycastle-1.49.orig/src/org/bouncycastle/openpgp/operator/jcajce/JcePGPDataEncryptorBuilder.java0000644000175000017500000000770711723537700033166 0ustar ebourgebourgpackage org.bouncycastle.openpgp.operator.jcajce; import java.io.OutputStream; import java.security.InvalidAlgorithmParameterException; import java.security.InvalidKeyException; import java.security.Provider; import java.security.SecureRandom; import javax.crypto.Cipher; import javax.crypto.CipherOutputStream; import javax.crypto.spec.IvParameterSpec; import org.bouncycastle.jcajce.DefaultJcaJceHelper; import org.bouncycastle.jcajce.NamedJcaJceHelper; import org.bouncycastle.jcajce.ProviderJcaJceHelper; import org.bouncycastle.openpgp.PGPException; import org.bouncycastle.openpgp.operator.PGPDataEncryptor; import org.bouncycastle.openpgp.operator.PGPDataEncryptorBuilder; import org.bouncycastle.openpgp.operator.PGPDigestCalculator; public class JcePGPDataEncryptorBuilder implements PGPDataEncryptorBuilder { private OperatorHelper helper = new OperatorHelper(new DefaultJcaJceHelper()); private SecureRandom random; private boolean withIntegrityPacket; private int encAlgorithm; public JcePGPDataEncryptorBuilder(int encAlgorithm) { this.encAlgorithm = encAlgorithm; if (encAlgorithm == 0) { throw new IllegalArgumentException("null cipher specified"); } } /** * Determine whether or not the resulting encrypted data will be protected using an integrity packet. * * @param withIntegrityPacket true if an integrity packet is to be included, false otherwise. * @return the current builder. */ public JcePGPDataEncryptorBuilder setWithIntegrityPacket(boolean withIntegrityPacket) { this.withIntegrityPacket = withIntegrityPacket; return this; } public JcePGPDataEncryptorBuilder setProvider(Provider provider) { this.helper = new OperatorHelper(new ProviderJcaJceHelper(provider)); return this; } public JcePGPDataEncryptorBuilder setProvider(String providerName) { this.helper = new OperatorHelper(new NamedJcaJceHelper(providerName)); return this; } /** * Provide a user defined source of randomness. * * @param random the secure random to be used. * @return the current builder. */ public JcePGPDataEncryptorBuilder setSecureRandom(SecureRandom random) { this.random = random; return this; } public int getAlgorithm() { return encAlgorithm; } public SecureRandom getSecureRandom() { if (random == null) { random = new SecureRandom(); } return random; } public PGPDataEncryptor build(byte[] keyBytes) throws PGPException { return new MyPGPDataEncryptor(keyBytes); } private class MyPGPDataEncryptor implements PGPDataEncryptor { private final Cipher c; MyPGPDataEncryptor(byte[] keyBytes) throws PGPException { c = helper.createStreamCipher(encAlgorithm, withIntegrityPacket); byte[] iv = new byte[c.getBlockSize()]; try { c.init(Cipher.ENCRYPT_MODE, PGPUtil.makeSymmetricKey(encAlgorithm, keyBytes), new IvParameterSpec(iv)); } catch (InvalidKeyException e) { throw new PGPException("invalid key: " + e.getMessage(), e); } catch (InvalidAlgorithmParameterException e) { throw new PGPException("imvalid algorithm parameter: " + e.getMessage(), e); } } public OutputStream getOutputStream(OutputStream out) { return new CipherOutputStream(out, c); } public PGPDigestCalculator getIntegrityCalculator() { if (withIntegrityPacket) { return new SHA1PGPDigestCalculator(); } return null; } public int getBlockSize() { return c.getBlockSize(); } } } ././@LongLink0000000000000000000000000000016200000000000011564 Lustar rootrootbouncycastle-1.49.orig/src/org/bouncycastle/openpgp/operator/jcajce/JcePublicKeyKeyEncryptionMethodGenerator.javabouncycastle-1.49.orig/src/org/bouncycastle/openpgp/operator/jcajce/JcePublicKeyKeyEncryptionMethodG0000644000175000017500000000540211723537700033462 0ustar ebourgebourgpackage org.bouncycastle.openpgp.operator.jcajce; import java.security.InvalidKeyException; import java.security.Key; import java.security.Provider; import java.security.SecureRandom; import javax.crypto.BadPaddingException; import javax.crypto.Cipher; import javax.crypto.IllegalBlockSizeException; import org.bouncycastle.jcajce.DefaultJcaJceHelper; import org.bouncycastle.jcajce.NamedJcaJceHelper; import org.bouncycastle.jcajce.ProviderJcaJceHelper; import org.bouncycastle.openpgp.PGPException; import org.bouncycastle.openpgp.PGPPublicKey; import org.bouncycastle.openpgp.operator.PublicKeyKeyEncryptionMethodGenerator; public class JcePublicKeyKeyEncryptionMethodGenerator extends PublicKeyKeyEncryptionMethodGenerator { private OperatorHelper helper = new OperatorHelper(new DefaultJcaJceHelper()); private SecureRandom random; private JcaPGPKeyConverter keyConverter = new JcaPGPKeyConverter(); /** * Create a public key encryption method generator with the method to be based on the passed in key. * * @param key the public key to use for encryption. */ public JcePublicKeyKeyEncryptionMethodGenerator(PGPPublicKey key) { super(key); } public JcePublicKeyKeyEncryptionMethodGenerator setProvider(Provider provider) { this.helper = new OperatorHelper(new ProviderJcaJceHelper(provider)); keyConverter.setProvider(provider); return this; } public JcePublicKeyKeyEncryptionMethodGenerator setProvider(String providerName) { this.helper = new OperatorHelper(new NamedJcaJceHelper(providerName)); keyConverter.setProvider(providerName); return this; } /** * Provide a user defined source of randomness. * * @param random the secure random to be used. * @return the current generator. */ public JcePublicKeyKeyEncryptionMethodGenerator setSecureRandom(SecureRandom random) { this.random = random; return this; } protected byte[] encryptSessionInfo(PGPPublicKey pubKey, byte[] sessionInfo) throws PGPException { try { Cipher c = helper.createPublicKeyCipher(pubKey.getAlgorithm()); Key key = keyConverter.getPublicKey(pubKey); c.init(Cipher.ENCRYPT_MODE, key, random); return c.doFinal(sessionInfo); } catch (IllegalBlockSizeException e) { throw new PGPException("illegal block size: " + e.getMessage(), e); } catch (BadPaddingException e) { throw new PGPException("bad padding: " + e.getMessage(), e); } catch (InvalidKeyException e) { throw new PGPException("key invalid: " + e.getMessage(), e); } } } bouncycastle-1.49.orig/src/org/bouncycastle/openpgp/operator/jcajce/JcaPGPPrivateKey.java0000644000175000017500000000143112112270320031124 0ustar ebourgebourgpackage org.bouncycastle.openpgp.operator.jcajce; import java.security.PrivateKey; import org.bouncycastle.openpgp.PGPPrivateKey; import org.bouncycastle.openpgp.PGPPublicKey; /** * A JCA PrivateKey carrier. Use this one if you're dealing with a hardware adapter. */ public class JcaPGPPrivateKey extends PGPPrivateKey { private final PrivateKey privateKey; public JcaPGPPrivateKey(long keyID, PrivateKey privateKey) { super(keyID, null, null); this.privateKey = privateKey; } public JcaPGPPrivateKey(PGPPublicKey pubKey, PrivateKey privateKey) { super(pubKey.getKeyID(), pubKey.getPublicKeyPacket(), null); this.privateKey = privateKey; } public PrivateKey getPrivateKey() { return privateKey; } } bouncycastle-1.49.orig/src/org/bouncycastle/openpgp/operator/jcajce/SignatureOutputStream.java0000644000175000017500000000231411723536614032435 0ustar ebourgebourgpackage org.bouncycastle.openpgp.operator.jcajce; import java.io.IOException; import java.io.OutputStream; import java.security.Signature; import java.security.SignatureException; class SignatureOutputStream extends OutputStream { private Signature sig; SignatureOutputStream(Signature sig) { this.sig = sig; } public void write(byte[] bytes, int off, int len) throws IOException { try { sig.update(bytes, off, len); } catch (SignatureException e) { throw new IOException("signature update caused exception: " + e.getMessage()); } } public void write(byte[] bytes) throws IOException { try { sig.update(bytes); } catch (SignatureException e) { throw new IOException("signature update caused exception: " + e.getMessage()); } } public void write(int b) throws IOException { try { sig.update((byte)b); } catch (SignatureException e) { throw new IOException("signature update caused exception: " + e.getMessage()); } } } bouncycastle-1.49.orig/src/org/bouncycastle/openpgp/operator/jcajce/JcaPGPKeyConverter.java0000644000175000017500000002252412112270320031467 0ustar ebourgebourgpackage org.bouncycastle.openpgp.operator.jcajce; import java.security.KeyFactory; import java.security.PrivateKey; import java.security.Provider; import java.security.PublicKey; import java.security.interfaces.DSAParams; import java.security.interfaces.DSAPrivateKey; import java.security.interfaces.DSAPublicKey; import java.security.interfaces.RSAPrivateCrtKey; import java.security.interfaces.RSAPublicKey; import java.security.spec.DSAPrivateKeySpec; import java.security.spec.DSAPublicKeySpec; import java.security.spec.RSAPrivateCrtKeySpec; import java.security.spec.RSAPublicKeySpec; import java.util.Date; import org.bouncycastle.bcpg.BCPGKey; import org.bouncycastle.bcpg.DSAPublicBCPGKey; import org.bouncycastle.bcpg.DSASecretBCPGKey; import org.bouncycastle.bcpg.ElGamalPublicBCPGKey; import org.bouncycastle.bcpg.ElGamalSecretBCPGKey; import org.bouncycastle.bcpg.PublicKeyAlgorithmTags; import org.bouncycastle.bcpg.PublicKeyPacket; import org.bouncycastle.bcpg.RSAPublicBCPGKey; import org.bouncycastle.bcpg.RSASecretBCPGKey; import org.bouncycastle.jcajce.DefaultJcaJceHelper; import org.bouncycastle.jcajce.NamedJcaJceHelper; import org.bouncycastle.jcajce.ProviderJcaJceHelper; import org.bouncycastle.jce.interfaces.ElGamalPrivateKey; import org.bouncycastle.jce.interfaces.ElGamalPublicKey; import org.bouncycastle.jce.spec.ElGamalParameterSpec; import org.bouncycastle.jce.spec.ElGamalPrivateKeySpec; import org.bouncycastle.jce.spec.ElGamalPublicKeySpec; import org.bouncycastle.openpgp.PGPException; import org.bouncycastle.openpgp.PGPPrivateKey; import org.bouncycastle.openpgp.PGPPublicKey; import org.bouncycastle.openpgp.operator.KeyFingerPrintCalculator; public class JcaPGPKeyConverter { private OperatorHelper helper = new OperatorHelper(new DefaultJcaJceHelper()); private KeyFingerPrintCalculator fingerPrintCalculator = new JcaKeyFingerprintCalculator(); public JcaPGPKeyConverter setProvider(Provider provider) { this.helper = new OperatorHelper(new ProviderJcaJceHelper(provider)); return this; } public JcaPGPKeyConverter setProvider(String providerName) { this.helper = new OperatorHelper(new NamedJcaJceHelper(providerName)); return this; } public PublicKey getPublicKey(PGPPublicKey publicKey) throws PGPException { KeyFactory fact; PublicKeyPacket publicPk = publicKey.getPublicKeyPacket(); try { switch (publicPk.getAlgorithm()) { case PublicKeyAlgorithmTags.RSA_ENCRYPT: case PublicKeyAlgorithmTags.RSA_GENERAL: case PublicKeyAlgorithmTags.RSA_SIGN: RSAPublicBCPGKey rsaK = (RSAPublicBCPGKey)publicPk.getKey(); RSAPublicKeySpec rsaSpec = new RSAPublicKeySpec(rsaK.getModulus(), rsaK.getPublicExponent()); fact = helper.createKeyFactory("RSA"); return fact.generatePublic(rsaSpec); case PublicKeyAlgorithmTags.DSA: DSAPublicBCPGKey dsaK = (DSAPublicBCPGKey)publicPk.getKey(); DSAPublicKeySpec dsaSpec = new DSAPublicKeySpec(dsaK.getY(), dsaK.getP(), dsaK.getQ(), dsaK.getG()); fact = helper.createKeyFactory("DSA"); return fact.generatePublic(dsaSpec); case PublicKeyAlgorithmTags.ELGAMAL_ENCRYPT: case PublicKeyAlgorithmTags.ELGAMAL_GENERAL: ElGamalPublicBCPGKey elK = (ElGamalPublicBCPGKey)publicPk.getKey(); ElGamalPublicKeySpec elSpec = new ElGamalPublicKeySpec(elK.getY(), new ElGamalParameterSpec(elK.getP(), elK.getG())); fact = helper.createKeyFactory("ElGamal"); return fact.generatePublic(elSpec); default: throw new PGPException("unknown public key algorithm encountered"); } } catch (PGPException e) { throw e; } catch (Exception e) { throw new PGPException("exception constructing public key", e); } } /** * Create a PGPPublicKey from the passed in JCA one. *

    * Note: the time passed in affects the value of the key's keyID, so you probably only want * to do this once for a JCA key, or make sure you keep track of the time you used. * * @param algorithm asymmetric algorithm type representing the public key. * @param pubKey actual public key to associate. * @param time date of creation. * @throws PGPException on key creation problem. */ public PGPPublicKey getPGPPublicKey(int algorithm, PublicKey pubKey, Date time) throws PGPException { BCPGKey bcpgKey; if (pubKey instanceof RSAPublicKey) { RSAPublicKey rK = (RSAPublicKey)pubKey; bcpgKey = new RSAPublicBCPGKey(rK.getModulus(), rK.getPublicExponent()); } else if (pubKey instanceof DSAPublicKey) { DSAPublicKey dK = (DSAPublicKey)pubKey; DSAParams dP = dK.getParams(); bcpgKey = new DSAPublicBCPGKey(dP.getP(), dP.getQ(), dP.getG(), dK.getY()); } else if (pubKey instanceof ElGamalPublicKey) { ElGamalPublicKey eK = (ElGamalPublicKey)pubKey; ElGamalParameterSpec eS = eK.getParameters(); bcpgKey = new ElGamalPublicBCPGKey(eS.getP(), eS.getG(), eK.getY()); } else { throw new PGPException("unknown key class"); } return new PGPPublicKey(new PublicKeyPacket(algorithm, time, bcpgKey), fingerPrintCalculator); } public PrivateKey getPrivateKey(PGPPrivateKey privKey) throws PGPException { if (privKey instanceof JcaPGPPrivateKey) { return ((JcaPGPPrivateKey)privKey).getPrivateKey(); } PublicKeyPacket pubPk = privKey.getPublicKeyPacket(); BCPGKey privPk = privKey.getPrivateKeyDataPacket(); try { KeyFactory fact; switch (pubPk.getAlgorithm()) { case PGPPublicKey.RSA_ENCRYPT: case PGPPublicKey.RSA_GENERAL: case PGPPublicKey.RSA_SIGN: RSAPublicBCPGKey rsaPub = (RSAPublicBCPGKey)pubPk.getKey(); RSASecretBCPGKey rsaPriv = (RSASecretBCPGKey)privPk; RSAPrivateCrtKeySpec rsaPrivSpec = new RSAPrivateCrtKeySpec( rsaPriv.getModulus(), rsaPub.getPublicExponent(), rsaPriv.getPrivateExponent(), rsaPriv.getPrimeP(), rsaPriv.getPrimeQ(), rsaPriv.getPrimeExponentP(), rsaPriv.getPrimeExponentQ(), rsaPriv.getCrtCoefficient()); fact = helper.createKeyFactory("RSA"); return fact.generatePrivate(rsaPrivSpec); case PGPPublicKey.DSA: DSAPublicBCPGKey dsaPub = (DSAPublicBCPGKey)pubPk.getKey(); DSASecretBCPGKey dsaPriv = (DSASecretBCPGKey)privPk; DSAPrivateKeySpec dsaPrivSpec = new DSAPrivateKeySpec(dsaPriv.getX(), dsaPub.getP(), dsaPub.getQ(), dsaPub.getG()); fact = helper.createKeyFactory("DSA"); return fact.generatePrivate(dsaPrivSpec); case PGPPublicKey.ELGAMAL_ENCRYPT: case PGPPublicKey.ELGAMAL_GENERAL: ElGamalPublicBCPGKey elPub = (ElGamalPublicBCPGKey)pubPk.getKey(); ElGamalSecretBCPGKey elPriv = (ElGamalSecretBCPGKey)privPk; ElGamalPrivateKeySpec elSpec = new ElGamalPrivateKeySpec(elPriv.getX(), new ElGamalParameterSpec(elPub.getP(), elPub.getG())); fact = helper.createKeyFactory("ElGamal"); return fact.generatePrivate(elSpec); default: throw new PGPException("unknown public key algorithm encountered"); } } catch (PGPException e) { throw e; } catch (Exception e) { throw new PGPException("Exception constructing key", e); } } /** * Convert a PrivateKey into a PGPPrivateKey. * * @param pub the corresponding PGPPublicKey to privKey. * @param privKey the private key for the key in pub. * @return a PGPPrivateKey * @throws PGPException */ public PGPPrivateKey getPGPPrivateKey(PGPPublicKey pub, PrivateKey privKey) throws PGPException { BCPGKey privPk; switch (pub.getAlgorithm()) { case PGPPublicKey.RSA_ENCRYPT: case PGPPublicKey.RSA_SIGN: case PGPPublicKey.RSA_GENERAL: RSAPrivateCrtKey rsK = (RSAPrivateCrtKey)privKey; privPk = new RSASecretBCPGKey(rsK.getPrivateExponent(), rsK.getPrimeP(), rsK.getPrimeQ()); break; case PGPPublicKey.DSA: DSAPrivateKey dsK = (DSAPrivateKey)privKey; privPk = new DSASecretBCPGKey(dsK.getX()); break; case PGPPublicKey.ELGAMAL_ENCRYPT: case PGPPublicKey.ELGAMAL_GENERAL: ElGamalPrivateKey esK = (ElGamalPrivateKey)privKey; privPk = new ElGamalSecretBCPGKey(esK.getX()); break; default: throw new PGPException("unknown key class"); } return new PGPPrivateKey(pub.getKeyID(), pub.getPublicKeyPacket(), privPk); } } ././@LongLink0000000000000000000000000000016100000000000011563 Lustar rootrootbouncycastle-1.49.orig/src/org/bouncycastle/openpgp/operator/jcajce/JcePublicKeyDataDecryptorFactoryBuilder.javabouncycastle-1.49.orig/src/org/bouncycastle/openpgp/operator/jcajce/JcePublicKeyDataDecryptorFactory0000644000175000017500000001344411723537700033511 0ustar ebourgebourgpackage org.bouncycastle.openpgp.operator.jcajce; import java.math.BigInteger; import java.security.InvalidKeyException; import java.security.PrivateKey; import java.security.Provider; import javax.crypto.Cipher; import org.bouncycastle.jcajce.DefaultJcaJceHelper; import org.bouncycastle.jcajce.NamedJcaJceHelper; import org.bouncycastle.jcajce.ProviderJcaJceHelper; import org.bouncycastle.jce.interfaces.ElGamalKey; import org.bouncycastle.openpgp.PGPException; import org.bouncycastle.openpgp.PGPPrivateKey; import org.bouncycastle.openpgp.PGPPublicKey; import org.bouncycastle.openpgp.operator.PGPDataDecryptor; import org.bouncycastle.openpgp.operator.PublicKeyDataDecryptorFactory; public class JcePublicKeyDataDecryptorFactoryBuilder { private OperatorHelper helper = new OperatorHelper(new DefaultJcaJceHelper()); private OperatorHelper contentHelper = new OperatorHelper(new DefaultJcaJceHelper()); private JcaPGPKeyConverter keyConverter = new JcaPGPKeyConverter(); public JcePublicKeyDataDecryptorFactoryBuilder() { } /** * Set the provider object to use for creating cryptographic primitives in the resulting factory the builder produces. * * @param provider provider object for cryptographic primitives. * @return the current builder. */ public JcePublicKeyDataDecryptorFactoryBuilder setProvider(Provider provider) { this.helper = new OperatorHelper(new ProviderJcaJceHelper(provider)); keyConverter.setProvider(provider); this.contentHelper = helper; return this; } /** * Set the provider name to use for creating cryptographic primitives in the resulting factory the builder produces. * * @param providerName the name of the provider to reference for cryptographic primitives. * @return the current builder. */ public JcePublicKeyDataDecryptorFactoryBuilder setProvider(String providerName) { this.helper = new OperatorHelper(new NamedJcaJceHelper(providerName)); keyConverter.setProvider(providerName); this.contentHelper = helper; return this; } public JcePublicKeyDataDecryptorFactoryBuilder setContentProvider(Provider provider) { this.contentHelper = new OperatorHelper(new ProviderJcaJceHelper(provider)); return this; } public JcePublicKeyDataDecryptorFactoryBuilder setContentProvider(String providerName) { this.contentHelper = new OperatorHelper(new NamedJcaJceHelper(providerName)); return this; } public PublicKeyDataDecryptorFactory build(final PrivateKey privKey) { return new PublicKeyDataDecryptorFactory() { public byte[] recoverSessionData(int keyAlgorithm, BigInteger[] secKeyData) throws PGPException { return decryptSessionData(keyAlgorithm, privKey, secKeyData); } public PGPDataDecryptor createDataDecryptor(boolean withIntegrityPacket, int encAlgorithm, byte[] key) throws PGPException { return contentHelper.createDataDecryptor(withIntegrityPacket, encAlgorithm, key); } }; } public PublicKeyDataDecryptorFactory build(final PGPPrivateKey privKey) { return new PublicKeyDataDecryptorFactory() { public byte[] recoverSessionData(int keyAlgorithm, BigInteger[] secKeyData) throws PGPException { return decryptSessionData(keyAlgorithm, keyConverter.getPrivateKey(privKey), secKeyData); } public PGPDataDecryptor createDataDecryptor(boolean withIntegrityPacket, int encAlgorithm, byte[] key) throws PGPException { return contentHelper.createDataDecryptor(withIntegrityPacket, encAlgorithm, key); } }; } private byte[] decryptSessionData(int keyAlgorithm, PrivateKey privKey, BigInteger[] secKeyData) throws PGPException { Cipher c1 = helper.createPublicKeyCipher(keyAlgorithm); try { c1.init(Cipher.DECRYPT_MODE, privKey); } catch (InvalidKeyException e) { throw new PGPException("error setting asymmetric cipher", e); } if (keyAlgorithm == PGPPublicKey.RSA_ENCRYPT || keyAlgorithm == PGPPublicKey.RSA_GENERAL) { byte[] bi = secKeyData[0].toByteArray(); if (bi[0] == 0) { c1.update(bi, 1, bi.length - 1); } else { c1.update(bi); } } else { ElGamalKey k = (ElGamalKey)privKey; int size = (k.getParameters().getP().bitLength() + 7) / 8; byte[] tmp = new byte[size]; byte[] bi = secKeyData[0].toByteArray(); if (bi.length > size) { c1.update(bi, 1, bi.length - 1); } else { System.arraycopy(bi, 0, tmp, tmp.length - bi.length, bi.length); c1.update(tmp); } bi = secKeyData[1].toByteArray(); for (int i = 0; i != tmp.length; i++) { tmp[i] = 0; } if (bi.length > size) { c1.update(bi, 1, bi.length - 1); } else { System.arraycopy(bi, 0, tmp, tmp.length - bi.length, bi.length); c1.update(tmp); } } byte[] plain; try { plain = c1.doFinal(); } catch (Exception e) { throw new PGPException("exception decrypting session data", e); } return plain; } } bouncycastle-1.49.orig/src/org/bouncycastle/openpgp/operator/jcajce/package.html0000644000175000017500000000033711576524034027517 0ustar ebourgebourg JCA/JCE based operators for dealing with OpenPGP objects.

    These provide the actual support for encryption and decryption required for the high level OpenPGP classes.

    bouncycastle-1.49.orig/src/org/bouncycastle/openpgp/operator/jcajce/JcaKeyFingerprintCalculator.java0000644000175000017500000000434411723536614033474 0ustar ebourgebourgpackage org.bouncycastle.openpgp.operator.jcajce; import java.io.IOException; import java.security.MessageDigest; import java.security.NoSuchAlgorithmException; import org.bouncycastle.bcpg.BCPGKey; import org.bouncycastle.bcpg.MPInteger; import org.bouncycastle.bcpg.PublicKeyPacket; import org.bouncycastle.bcpg.RSAPublicBCPGKey; import org.bouncycastle.openpgp.PGPException; import org.bouncycastle.openpgp.operator.KeyFingerPrintCalculator; public class JcaKeyFingerprintCalculator implements KeyFingerPrintCalculator { public byte[] calculateFingerprint(PublicKeyPacket publicPk) throws PGPException { BCPGKey key = publicPk.getKey(); if (publicPk.getVersion() <= 3) { RSAPublicBCPGKey rK = (RSAPublicBCPGKey)key; try { MessageDigest digest = MessageDigest.getInstance("MD5"); byte[] bytes = new MPInteger(rK.getModulus()).getEncoded(); digest.update(bytes, 2, bytes.length - 2); bytes = new MPInteger(rK.getPublicExponent()).getEncoded(); digest.update(bytes, 2, bytes.length - 2); return digest.digest(); } catch (NoSuchAlgorithmException e) { throw new PGPException("can't find MD5", e); } catch (IOException e) { throw new PGPException("can't encode key components: " + e.getMessage(), e); } } else { try { byte[] kBytes = publicPk.getEncodedContents(); MessageDigest digest = MessageDigest.getInstance("SHA1"); digest.update((byte)0x99); digest.update((byte)(kBytes.length >> 8)); digest.update((byte)kBytes.length); digest.update(kBytes); return digest.digest(); } catch (NoSuchAlgorithmException e) { throw new PGPException("can't find SHA1", e); } catch (IOException e) { throw new PGPException("can't encode key components: " + e.getMessage(), e); } } } } bouncycastle-1.49.orig/src/org/bouncycastle/openpgp/operator/jcajce/OperatorHelper.java0000644000175000017500000001160511723537700031032 0ustar ebourgebourgpackage org.bouncycastle.openpgp.operator.jcajce; import java.io.InputStream; import java.security.GeneralSecurityException; import java.security.KeyFactory; import java.security.MessageDigest; import java.security.Signature; import javax.crypto.Cipher; import javax.crypto.CipherInputStream; import javax.crypto.SecretKey; import javax.crypto.spec.IvParameterSpec; import javax.crypto.spec.SecretKeySpec; import org.bouncycastle.bcpg.PublicKeyAlgorithmTags; import org.bouncycastle.jcajce.JcaJceHelper; import org.bouncycastle.openpgp.PGPException; import org.bouncycastle.openpgp.PGPPublicKey; import org.bouncycastle.openpgp.operator.PGPDataDecryptor; import org.bouncycastle.openpgp.operator.PGPDigestCalculator; class OperatorHelper { private JcaJceHelper helper; OperatorHelper(JcaJceHelper helper) { this.helper = helper; } MessageDigest createDigest(int algorithm) throws GeneralSecurityException, PGPException { MessageDigest dig; dig = helper.createDigest(PGPUtil.getDigestName(algorithm)); return dig; } KeyFactory createKeyFactory(String algorithm) throws GeneralSecurityException, PGPException { return helper.createKeyFactory(algorithm); } PGPDataDecryptor createDataDecryptor(boolean withIntegrityPacket, int encAlgorithm, byte[] key) throws PGPException { try { SecretKey secretKey = new SecretKeySpec(key, PGPUtil.getSymmetricCipherName(encAlgorithm)); final Cipher c = createStreamCipher(encAlgorithm, withIntegrityPacket); byte[] iv = new byte[c.getBlockSize()]; c.init(Cipher.DECRYPT_MODE, secretKey, new IvParameterSpec(iv)); return new PGPDataDecryptor() { public InputStream getInputStream(InputStream in) { return new CipherInputStream(in, c); } public int getBlockSize() { return c.getBlockSize(); } public PGPDigestCalculator getIntegrityCalculator() { return new SHA1PGPDigestCalculator(); } }; } catch (PGPException e) { throw e; } catch (Exception e) { throw new PGPException("Exception creating cipher", e); } } Cipher createStreamCipher(int encAlgorithm, boolean withIntegrityPacket) throws PGPException { String mode = (withIntegrityPacket) ? "CFB" : "OpenPGPCFB"; String cName = PGPUtil.getSymmetricCipherName(encAlgorithm) + "/" + mode + "/NoPadding"; return createCipher(cName); } Cipher createCipher(String cipherName) throws PGPException { try { return helper.createCipher(cipherName); } catch (GeneralSecurityException e) { throw new PGPException("cannot create cipher: " + e.getMessage(), e); } } Cipher createPublicKeyCipher(int encAlgorithm) throws PGPException { switch (encAlgorithm) { case PGPPublicKey.RSA_ENCRYPT: case PGPPublicKey.RSA_GENERAL: return createCipher("RSA/ECB/PKCS1Padding"); case PGPPublicKey.ELGAMAL_ENCRYPT: case PGPPublicKey.ELGAMAL_GENERAL: return createCipher("ElGamal/ECB/PKCS1Padding"); case PGPPublicKey.DSA: throw new PGPException("Can't use DSA for encryption."); case PGPPublicKey.ECDSA: throw new PGPException("Can't use ECDSA for encryption."); default: throw new PGPException("unknown asymmetric algorithm: " + encAlgorithm); } } private Signature createSignature(String cipherName) throws PGPException { try { return helper.createSignature(cipherName); } catch (GeneralSecurityException e) { throw new PGPException("cannot create signature: " + e.getMessage(), e); } } public Signature createSignature(int keyAlgorithm, int hashAlgorithm) throws PGPException { String encAlg; switch (keyAlgorithm) { case PublicKeyAlgorithmTags.RSA_GENERAL: case PublicKeyAlgorithmTags.RSA_SIGN: encAlg = "RSA"; break; case PublicKeyAlgorithmTags.DSA: encAlg = "DSA"; break; case PublicKeyAlgorithmTags.ELGAMAL_ENCRYPT: // in some malformed cases. case PublicKeyAlgorithmTags.ELGAMAL_GENERAL: encAlg = "ElGamal"; break; default: throw new PGPException("unknown algorithm tag in signature:" + keyAlgorithm); } return createSignature(PGPUtil.getDigestName(hashAlgorithm) + "with" + encAlg); } } bouncycastle-1.49.orig/src/org/bouncycastle/openpgp/operator/PGPDataDecryptorProvider.java0000644000175000017500000000013211576055702031503 0ustar ebourgebourgpackage org.bouncycastle.openpgp.operator; public interface PGPDataDecryptorProvider { } ././@LongLink0000000000000000000000000000015000000000000011561 Lustar rootrootbouncycastle-1.49.orig/src/org/bouncycastle/openpgp/operator/PublicKeyKeyEncryptionMethodGenerator.javabouncycastle-1.49.orig/src/org/bouncycastle/openpgp/operator/PublicKeyKeyEncryptionMethodGenerator.j0000644000175000017500000000523011576513664033621 0ustar ebourgebourgpackage org.bouncycastle.openpgp.operator; import java.math.BigInteger; import org.bouncycastle.bcpg.ContainedPacket; import org.bouncycastle.bcpg.PublicKeyEncSessionPacket; import org.bouncycastle.openpgp.PGPException; import org.bouncycastle.openpgp.PGPPublicKey; public abstract class PublicKeyKeyEncryptionMethodGenerator extends PGPKeyEncryptionMethodGenerator { private PGPPublicKey pubKey; protected PublicKeyKeyEncryptionMethodGenerator( PGPPublicKey pubKey) { this.pubKey = pubKey; switch (pubKey.getAlgorithm()) { case PGPPublicKey.RSA_ENCRYPT: case PGPPublicKey.RSA_GENERAL: break; case PGPPublicKey.ELGAMAL_ENCRYPT: case PGPPublicKey.ELGAMAL_GENERAL: break; case PGPPublicKey.DSA: throw new IllegalArgumentException("Can't use DSA for encryption."); case PGPPublicKey.ECDSA: throw new IllegalArgumentException("Can't use ECDSA for encryption."); default: throw new IllegalArgumentException("unknown asymmetric algorithm: " + pubKey.getAlgorithm()); } } public BigInteger[] processSessionInfo( byte[] encryptedSessionInfo) throws PGPException { BigInteger[] data; switch (pubKey.getAlgorithm()) { case PGPPublicKey.RSA_ENCRYPT: case PGPPublicKey.RSA_GENERAL: data = new BigInteger[1]; data[0] = new BigInteger(1, encryptedSessionInfo); break; case PGPPublicKey.ELGAMAL_ENCRYPT: case PGPPublicKey.ELGAMAL_GENERAL: byte[] b1 = new byte[encryptedSessionInfo.length / 2]; byte[] b2 = new byte[encryptedSessionInfo.length / 2]; System.arraycopy(encryptedSessionInfo, 0, b1, 0, b1.length); System.arraycopy(encryptedSessionInfo, b1.length, b2, 0, b2.length); data = new BigInteger[2]; data[0] = new BigInteger(1, b1); data[1] = new BigInteger(1, b2); break; default: throw new PGPException("unknown asymmetric algorithm: " + pubKey.getAlgorithm()); } return data; } public ContainedPacket generate(int encAlgorithm, byte[] sessionInfo) throws PGPException { return new PublicKeyEncSessionPacket(pubKey.getKeyID(), pubKey.getAlgorithm(), processSessionInfo(encryptSessionInfo(pubKey, sessionInfo))); } abstract protected byte[] encryptSessionInfo(PGPPublicKey pubKey, byte[] sessionInfo) throws PGPException; } bouncycastle-1.49.orig/src/org/bouncycastle/openpgp/operator/KeyFingerPrintCalculator.java0000644000175000017500000000041611600523513031557 0ustar ebourgebourgpackage org.bouncycastle.openpgp.operator; import org.bouncycastle.bcpg.PublicKeyPacket; import org.bouncycastle.openpgp.PGPException; public interface KeyFingerPrintCalculator { byte[] calculateFingerprint(PublicKeyPacket publicPk) throws PGPException; } bouncycastle-1.49.orig/src/org/bouncycastle/openpgp/operator/package.html0000644000175000017500000000046611576531772026312 0ustar ebourgebourg Interfaces and abstract classes to provide the framework to support operations on the OpenPGP high level classes.

    For examples of actual implementations see the org.bouncycastle.openpgp.operator.bc and org.bouncycastle.openpgp.operator.jcajce packages.

    bouncycastle-1.49.orig/src/org/bouncycastle/openpgp/operator/PBEKeyEncryptionMethodGenerator.java0000644000175000017500000000510212057003314033003 0ustar ebourgebourgpackage org.bouncycastle.openpgp.operator; import java.security.SecureRandom; import org.bouncycastle.bcpg.ContainedPacket; import org.bouncycastle.bcpg.S2K; import org.bouncycastle.bcpg.SymmetricKeyEncSessionPacket; import org.bouncycastle.openpgp.PGPException; public abstract class PBEKeyEncryptionMethodGenerator extends PGPKeyEncryptionMethodGenerator { private char[] passPhrase; private PGPDigestCalculator s2kDigestCalculator; private S2K s2k; private SecureRandom random; private int s2kCount; protected PBEKeyEncryptionMethodGenerator( char[] passPhrase, PGPDigestCalculator s2kDigestCalculator) { this(passPhrase, s2kDigestCalculator, 0x60); } protected PBEKeyEncryptionMethodGenerator( char[] passPhrase, PGPDigestCalculator s2kDigestCalculator, int s2kCount) { this.passPhrase = passPhrase; this.s2kDigestCalculator = s2kDigestCalculator; if (s2kCount < 0 || s2kCount > 0xff) { throw new IllegalArgumentException("s2kCount value outside of range 0 to 255."); } this.s2kCount = s2kCount; } public PBEKeyEncryptionMethodGenerator setSecureRandom(SecureRandom random) { this.random = random; return this; } public byte[] getKey(int encAlgorithm) throws PGPException { if (s2k == null) { byte[] iv = new byte[8]; if (random == null) { random = new SecureRandom(); } random.nextBytes(iv); s2k = new S2K(s2kDigestCalculator.getAlgorithm(), iv, s2kCount); } return PGPUtil.makeKeyFromPassPhrase(s2kDigestCalculator, encAlgorithm, s2k, passPhrase); } public ContainedPacket generate(int encAlgorithm, byte[] sessionInfo) throws PGPException { byte[] key = getKey(encAlgorithm); if (sessionInfo == null) { return new SymmetricKeyEncSessionPacket(encAlgorithm, s2k, null); } // // the passed in session info has the an RSA/ElGamal checksum added to it, for PBE this is not included. // byte[] nSessionInfo = new byte[sessionInfo.length - 2]; System.arraycopy(sessionInfo, 0, nSessionInfo, 0, nSessionInfo.length); return new SymmetricKeyEncSessionPacket(encAlgorithm, s2k, encryptSessionInfo(encAlgorithm, key, nSessionInfo)); } abstract protected byte[] encryptSessionInfo(int encAlgorithm, byte[] key, byte[] sessionInfo) throws PGPException; } bouncycastle-1.49.orig/src/org/bouncycastle/openpgp/operator/PGPDigestCalculatorProvider.java0000644000175000017500000000032411576031602032163 0ustar ebourgebourgpackage org.bouncycastle.openpgp.operator; import org.bouncycastle.openpgp.PGPException; public interface PGPDigestCalculatorProvider { PGPDigestCalculator get(int algorithm) throws PGPException; } bouncycastle-1.49.orig/src/org/bouncycastle/openpgp/PGPPublicKey.java0000644000175000017500000006743312147064414025273 0ustar ebourgebourgpackage org.bouncycastle.openpgp; import java.io.ByteArrayOutputStream; import java.io.IOException; import java.io.OutputStream; import java.security.NoSuchProviderException; import java.security.Provider; import java.security.PublicKey; import java.util.ArrayList; import java.util.Collection; import java.util.Date; import java.util.Iterator; import java.util.List; import org.bouncycastle.bcpg.BCPGKey; import org.bouncycastle.bcpg.BCPGOutputStream; import org.bouncycastle.bcpg.ContainedPacket; import org.bouncycastle.bcpg.DSAPublicBCPGKey; import org.bouncycastle.bcpg.ElGamalPublicBCPGKey; import org.bouncycastle.bcpg.PublicKeyAlgorithmTags; import org.bouncycastle.bcpg.PublicKeyPacket; import org.bouncycastle.bcpg.RSAPublicBCPGKey; import org.bouncycastle.bcpg.TrustPacket; import org.bouncycastle.bcpg.UserAttributePacket; import org.bouncycastle.bcpg.UserIDPacket; import org.bouncycastle.openpgp.operator.KeyFingerPrintCalculator; import org.bouncycastle.openpgp.operator.jcajce.JcaPGPKeyConverter; import org.bouncycastle.util.Arrays; /** * general class to handle a PGP public key object. */ public class PGPPublicKey implements PublicKeyAlgorithmTags { private static final int[] MASTER_KEY_CERTIFICATION_TYPES = new int[] { PGPSignature.POSITIVE_CERTIFICATION, PGPSignature.CASUAL_CERTIFICATION, PGPSignature.NO_CERTIFICATION, PGPSignature.DEFAULT_CERTIFICATION }; PublicKeyPacket publicPk; TrustPacket trustPk; List keySigs = new ArrayList(); List ids = new ArrayList(); List idTrusts = new ArrayList(); List idSigs = new ArrayList(); List subSigs = null; private long keyID; private byte[] fingerprint; private int keyStrength; private void init(KeyFingerPrintCalculator fingerPrintCalculator) throws PGPException { BCPGKey key = publicPk.getKey(); this.fingerprint = fingerPrintCalculator.calculateFingerprint(publicPk); if (publicPk.getVersion() <= 3) { RSAPublicBCPGKey rK = (RSAPublicBCPGKey)key; this.keyID = rK.getModulus().longValue(); this.keyStrength = rK.getModulus().bitLength(); } else { this.keyID = ((long)(fingerprint[fingerprint.length - 8] & 0xff) << 56) | ((long)(fingerprint[fingerprint.length - 7] & 0xff) << 48) | ((long)(fingerprint[fingerprint.length - 6] & 0xff) << 40) | ((long)(fingerprint[fingerprint.length - 5] & 0xff) << 32) | ((long)(fingerprint[fingerprint.length - 4] & 0xff) << 24) | ((long)(fingerprint[fingerprint.length - 3] & 0xff) << 16) | ((long)(fingerprint[fingerprint.length - 2] & 0xff) << 8) | ((fingerprint[fingerprint.length - 1] & 0xff)); if (key instanceof RSAPublicBCPGKey) { this.keyStrength = ((RSAPublicBCPGKey)key).getModulus().bitLength(); } else if (key instanceof DSAPublicBCPGKey) { this.keyStrength = ((DSAPublicBCPGKey)key).getP().bitLength(); } else if (key instanceof ElGamalPublicBCPGKey) { this.keyStrength = ((ElGamalPublicBCPGKey)key).getP().bitLength(); } } } /** * Create a PGPPublicKey from the passed in JCA one. *

    * Note: the time passed in affects the value of the key's keyID, so you probably only want * to do this once for a JCA key, or make sure you keep track of the time you used. * * @param algorithm asymmetric algorithm type representing the public key. * @param pubKey actual public key to associate. * @param time date of creation. * @param provider provider to use for underlying digest calculations. * @throws PGPException on key creation problem. * @throws NoSuchProviderException if the specified provider is required and cannot be found. * @deprecated use JcaPGPKeyConverter.getPGPPublicKey() */ public PGPPublicKey( int algorithm, PublicKey pubKey, Date time, String provider) throws PGPException, NoSuchProviderException { this(new JcaPGPKeyConverter().setProvider(provider).getPGPPublicKey(algorithm, pubKey, time)); } /** * @deprecated use JcaPGPKeyConverter.getPGPPublicKey() */ public PGPPublicKey( int algorithm, PublicKey pubKey, Date time) throws PGPException { this(new JcaPGPKeyConverter().getPGPPublicKey(algorithm, pubKey, time)); } /** * Create a PGP public key from a packet descriptor using the passed in fingerPrintCalculator to do calculate * the fingerprint and keyID. * * @param publicKeyPacket packet describing the public key. * @param fingerPrintCalculator calculator providing the digest support ot create the key fingerprint. * @throws PGPException if the packet is faulty, or the required calculations fail. */ public PGPPublicKey(PublicKeyPacket publicKeyPacket, KeyFingerPrintCalculator fingerPrintCalculator) throws PGPException { this.publicPk = publicKeyPacket; this.ids = new ArrayList(); this.idSigs = new ArrayList(); init(fingerPrintCalculator); } /* * Constructor for a sub-key. */ PGPPublicKey( PublicKeyPacket publicPk, TrustPacket trustPk, List sigs, KeyFingerPrintCalculator fingerPrintCalculator) throws PGPException { this.publicPk = publicPk; this.trustPk = trustPk; this.subSigs = sigs; init(fingerPrintCalculator); } PGPPublicKey( PGPPublicKey key, TrustPacket trust, List subSigs) { this.publicPk = key.publicPk; this.trustPk = trust; this.subSigs = subSigs; this.fingerprint = key.fingerprint; this.keyID = key.keyID; this.keyStrength = key.keyStrength; } /** * Copy constructor. * @param pubKey the public key to copy. */ PGPPublicKey( PGPPublicKey pubKey) { this.publicPk = pubKey.publicPk; this.keySigs = new ArrayList(pubKey.keySigs); this.ids = new ArrayList(pubKey.ids); this.idTrusts = new ArrayList(pubKey.idTrusts); this.idSigs = new ArrayList(pubKey.idSigs.size()); for (int i = 0; i != pubKey.idSigs.size(); i++) { this.idSigs.add(new ArrayList((ArrayList)pubKey.idSigs.get(i))); } if (pubKey.subSigs != null) { this.subSigs = new ArrayList(pubKey.subSigs.size()); for (int i = 0; i != pubKey.subSigs.size(); i++) { this.subSigs.add(pubKey.subSigs.get(i)); } } this.fingerprint = pubKey.fingerprint; this.keyID = pubKey.keyID; this.keyStrength = pubKey.keyStrength; } PGPPublicKey( PublicKeyPacket publicPk, TrustPacket trustPk, List keySigs, List ids, List idTrusts, List idSigs, KeyFingerPrintCalculator fingerPrintCalculator) throws PGPException { this.publicPk = publicPk; this.trustPk = trustPk; this.keySigs = keySigs; this.ids = ids; this.idTrusts = idTrusts; this.idSigs = idSigs; init(fingerPrintCalculator); } /** * @return the version of this key. */ public int getVersion() { return publicPk.getVersion(); } /** * @return creation time of key. */ public Date getCreationTime() { return publicPk.getTime(); } /** * @return number of valid days from creation time - zero means no * expiry. */ public int getValidDays() { if (publicPk.getVersion() > 3) { return (int)(this.getValidSeconds() / (24 * 60 * 60)); } else { return publicPk.getValidDays(); } } /** * Return the trust data associated with the public key, if present. * @return a byte array with trust data, null otherwise. */ public byte[] getTrustData() { if (trustPk == null) { return null; } return Arrays.clone(trustPk.getLevelAndTrustAmount()); } /** * @return number of valid seconds from creation time - zero means no * expiry. */ public long getValidSeconds() { if (publicPk.getVersion() > 3) { if (this.isMasterKey()) { for (int i = 0; i != MASTER_KEY_CERTIFICATION_TYPES.length; i++) { long seconds = getExpirationTimeFromSig(true, MASTER_KEY_CERTIFICATION_TYPES[i]); if (seconds >= 0) { return seconds; } } } else { long seconds = getExpirationTimeFromSig(false, PGPSignature.SUBKEY_BINDING); if (seconds >= 0) { return seconds; } } return 0; } else { return (long)publicPk.getValidDays() * 24 * 60 * 60; } } private long getExpirationTimeFromSig( boolean selfSigned, int signatureType) { Iterator signatures = this.getSignaturesOfType(signatureType); long expiryTime = -1; while (signatures.hasNext()) { PGPSignature sig = (PGPSignature)signatures.next(); if (!selfSigned || sig.getKeyID() == this.getKeyID()) { PGPSignatureSubpacketVector hashed = sig.getHashedSubPackets(); if (hashed != null) { long current = hashed.getKeyExpirationTime(); if (current == 0 || current > expiryTime) { expiryTime = current; } } else { return 0; } } } return expiryTime; } /** * Return the keyID associated with the public key. * * @return long */ public long getKeyID() { return keyID; } /** * Return the fingerprint of the key. * * @return key fingerprint. */ public byte[] getFingerprint() { byte[] tmp = new byte[fingerprint.length]; System.arraycopy(fingerprint, 0, tmp, 0, tmp.length); return tmp; } /** * Return true if this key has an algorithm type that makes it suitable to use for encryption. *

    * Note: with version 4 keys KeyFlags subpackets should also be considered when present for * determining the preferred use of the key. * * @return true if the key algorithm is suitable for encryption. */ public boolean isEncryptionKey() { int algorithm = publicPk.getAlgorithm(); return ((algorithm == RSA_GENERAL) || (algorithm == RSA_ENCRYPT) || (algorithm == ELGAMAL_ENCRYPT) || (algorithm == ELGAMAL_GENERAL)); } /** * Return true if this is a master key. * @return true if a master key. */ public boolean isMasterKey() { return (subSigs == null); } /** * Return the algorithm code associated with the public key. * * @return int */ public int getAlgorithm() { return publicPk.getAlgorithm(); } /** * Return the strength of the key in bits. * * @return bit strenght of key. */ public int getBitStrength() { return keyStrength; } /** * Return the public key contained in the object. * * @param provider provider to construct the key for. * @return a JCE/JCA public key. * @throws PGPException if the key algorithm is not recognised. * @throws NoSuchProviderException if the provider cannot be found. * @deprecated use a JcaPGPKeyConverter */ public PublicKey getKey( String provider) throws PGPException, NoSuchProviderException { return new JcaPGPKeyConverter().setProvider(provider).getPublicKey(this); } /** * Return the public key contained in the object. * * @param provider provider to construct the key for. * @return a JCE/JCA public key. * @throws PGPException if the key algorithm is not recognised. * @deprecated use a JcaPGPKeyConverter */ public PublicKey getKey( Provider provider) throws PGPException { return new JcaPGPKeyConverter().setProvider(provider).getPublicKey(this); } /** * Return any userIDs associated with the key. * * @return an iterator of Strings. */ public Iterator getUserIDs() { List temp = new ArrayList(); for (int i = 0; i != ids.size(); i++) { if (ids.get(i) instanceof String) { temp.add(ids.get(i)); } } return temp.iterator(); } /** * Return any user attribute vectors associated with the key. * * @return an iterator of PGPUserAttributeSubpacketVector objects. */ public Iterator getUserAttributes() { List temp = new ArrayList(); for (int i = 0; i != ids.size(); i++) { if (ids.get(i) instanceof PGPUserAttributeSubpacketVector) { temp.add(ids.get(i)); } } return temp.iterator(); } /** * Return any signatures associated with the passed in id. * * @param id the id to be matched. * @return an iterator of PGPSignature objects. */ public Iterator getSignaturesForID( String id) { for (int i = 0; i != ids.size(); i++) { if (id.equals(ids.get(i))) { return ((ArrayList)idSigs.get(i)).iterator(); } } return null; } /** * Return an iterator of signatures associated with the passed in user attributes. * * @param userAttributes the vector of user attributes to be matched. * @return an iterator of PGPSignature objects. */ public Iterator getSignaturesForUserAttribute( PGPUserAttributeSubpacketVector userAttributes) { for (int i = 0; i != ids.size(); i++) { if (userAttributes.equals(ids.get(i))) { return ((ArrayList)idSigs.get(i)).iterator(); } } return null; } /** * Return signatures of the passed in type that are on this key. * * @param signatureType the type of the signature to be returned. * @return an iterator (possibly empty) of signatures of the given type. */ public Iterator getSignaturesOfType( int signatureType) { List l = new ArrayList(); Iterator it = this.getSignatures(); while (it.hasNext()) { PGPSignature sig = (PGPSignature)it.next(); if (sig.getSignatureType() == signatureType) { l.add(sig); } } return l.iterator(); } /** * Return all signatures/certifications associated with this key. * * @return an iterator (possibly empty) with all signatures/certifications. */ public Iterator getSignatures() { if (subSigs == null) { List sigs = new ArrayList(); sigs.addAll(keySigs); for (int i = 0; i != idSigs.size(); i++) { sigs.addAll((Collection)idSigs.get(i)); } return sigs.iterator(); } else { return subSigs.iterator(); } } public PublicKeyPacket getPublicKeyPacket() { return publicPk; } public byte[] getEncoded() throws IOException { ByteArrayOutputStream bOut = new ByteArrayOutputStream(); this.encode(bOut); return bOut.toByteArray(); } public void encode( OutputStream outStream) throws IOException { BCPGOutputStream out; if (outStream instanceof BCPGOutputStream) { out = (BCPGOutputStream)outStream; } else { out = new BCPGOutputStream(outStream); } out.writePacket(publicPk); if (trustPk != null) { out.writePacket(trustPk); } if (subSigs == null) // not a sub-key { for (int i = 0; i != keySigs.size(); i++) { ((PGPSignature)keySigs.get(i)).encode(out); } for (int i = 0; i != ids.size(); i++) { if (ids.get(i) instanceof String) { String id = (String)ids.get(i); out.writePacket(new UserIDPacket(id)); } else { PGPUserAttributeSubpacketVector v = (PGPUserAttributeSubpacketVector)ids.get(i); out.writePacket(new UserAttributePacket(v.toSubpacketArray())); } if (idTrusts.get(i) != null) { out.writePacket((ContainedPacket)idTrusts.get(i)); } List sigs = (List)idSigs.get(i); for (int j = 0; j != sigs.size(); j++) { ((PGPSignature)sigs.get(j)).encode(out); } } } else { for (int j = 0; j != subSigs.size(); j++) { ((PGPSignature)subSigs.get(j)).encode(out); } } } /** * Check whether this (sub)key has a revocation signature on it. * * @return boolean indicating whether this (sub)key has been revoked. */ public boolean isRevoked() { int ns = 0; boolean revoked = false; if (this.isMasterKey()) // Master key { while (!revoked && (ns < keySigs.size())) { if (((PGPSignature)keySigs.get(ns++)).getSignatureType() == PGPSignature.KEY_REVOCATION) { revoked = true; } } } else // Sub-key { while (!revoked && (ns < subSigs.size())) { if (((PGPSignature)subSigs.get(ns++)).getSignatureType() == PGPSignature.SUBKEY_REVOCATION) { revoked = true; } } } return revoked; } /** * Add a certification for an id to the given public key. * * @param key the key the certification is to be added to. * @param id the id the certification is associated with. * @param certification the new certification. * @return the re-certified key. */ public static PGPPublicKey addCertification( PGPPublicKey key, String id, PGPSignature certification) { return addCert(key, id, certification); } /** * Add a certification for the given UserAttributeSubpackets to the given public key. * * @param key the key the certification is to be added to. * @param userAttributes the attributes the certification is associated with. * @param certification the new certification. * @return the re-certified key. */ public static PGPPublicKey addCertification( PGPPublicKey key, PGPUserAttributeSubpacketVector userAttributes, PGPSignature certification) { return addCert(key, userAttributes, certification); } private static PGPPublicKey addCert( PGPPublicKey key, Object id, PGPSignature certification) { PGPPublicKey returnKey = new PGPPublicKey(key); List sigList = null; for (int i = 0; i != returnKey.ids.size(); i++) { if (id.equals(returnKey.ids.get(i))) { sigList = (List)returnKey.idSigs.get(i); } } if (sigList != null) { sigList.add(certification); } else { sigList = new ArrayList(); sigList.add(certification); returnKey.ids.add(id); returnKey.idTrusts.add(null); returnKey.idSigs.add(sigList); } return returnKey; } /** * Remove any certifications associated with a given user attribute subpacket * on a key. * * @param key the key the certifications are to be removed from. * @param userAttributes the attributes to be removed. * @return the re-certified key, null if the user attribute subpacket was not found on the key. */ public static PGPPublicKey removeCertification( PGPPublicKey key, PGPUserAttributeSubpacketVector userAttributes) { return removeCert(key, userAttributes); } /** * Remove any certifications associated with a given id on a key. * * @param key the key the certifications are to be removed from. * @param id the id that is to be removed. * @return the re-certified key, null if the id was not found on the key. */ public static PGPPublicKey removeCertification( PGPPublicKey key, String id) { return removeCert(key, id); } private static PGPPublicKey removeCert( PGPPublicKey key, Object id) { PGPPublicKey returnKey = new PGPPublicKey(key); boolean found = false; for (int i = 0; i < returnKey.ids.size(); i++) { if (id.equals(returnKey.ids.get(i))) { found = true; returnKey.ids.remove(i); returnKey.idTrusts.remove(i); returnKey.idSigs.remove(i); } } if (!found) { return null; } return returnKey; } /** * Remove a certification associated with a given id on a key. * * @param key the key the certifications are to be removed from. * @param id the id that the certification is to be removed from. * @param certification the certification to be removed. * @return the re-certified key, null if the certification was not found. */ public static PGPPublicKey removeCertification( PGPPublicKey key, String id, PGPSignature certification) { return removeCert(key, id, certification); } /** * Remove a certification associated with a given user attributes on a key. * * @param key the key the certifications are to be removed from. * @param userAttributes the user attributes that the certification is to be removed from. * @param certification the certification to be removed. * @return the re-certified key, null if the certification was not found. */ public static PGPPublicKey removeCertification( PGPPublicKey key, PGPUserAttributeSubpacketVector userAttributes, PGPSignature certification) { return removeCert(key, userAttributes, certification); } private static PGPPublicKey removeCert( PGPPublicKey key, Object id, PGPSignature certification) { PGPPublicKey returnKey = new PGPPublicKey(key); boolean found = false; for (int i = 0; i < returnKey.ids.size(); i++) { if (id.equals(returnKey.ids.get(i))) { found = ((List)returnKey.idSigs.get(i)).remove(certification); } } if (!found) { return null; } return returnKey; } /** * Add a revocation or some other key certification to a key. * * @param key the key the revocation is to be added to. * @param certification the key signature to be added. * @return the new changed public key object. */ public static PGPPublicKey addCertification( PGPPublicKey key, PGPSignature certification) { if (key.isMasterKey()) { if (certification.getSignatureType() == PGPSignature.SUBKEY_REVOCATION) { throw new IllegalArgumentException("signature type incorrect for master key revocation."); } } else { if (certification.getSignatureType() == PGPSignature.KEY_REVOCATION) { throw new IllegalArgumentException("signature type incorrect for sub-key revocation."); } } PGPPublicKey returnKey = new PGPPublicKey(key); if (returnKey.subSigs != null) { returnKey.subSigs.add(certification); } else { returnKey.keySigs.add(certification); } return returnKey; } /** * Remove a certification from the key. * * @param key the key the certifications are to be removed from. * @param certification the certification to be removed. * @return the modified key, null if the certification was not found. */ public static PGPPublicKey removeCertification( PGPPublicKey key, PGPSignature certification) { PGPPublicKey returnKey = new PGPPublicKey(key); boolean found; if (returnKey.subSigs != null) { found = returnKey.subSigs.remove(certification); } else { found = returnKey.keySigs.remove(certification); } if (!found) { for (Iterator it = key.getUserIDs(); it.hasNext();) { String id = (String)it.next(); for (Iterator sIt = key.getSignaturesForID(id); sIt.hasNext();) { if (certification == sIt.next()) { found = true; returnKey = PGPPublicKey.removeCertification(returnKey, id, certification); } } } if (!found) { for (Iterator it = key.getUserAttributes(); it.hasNext();) { PGPUserAttributeSubpacketVector id = (PGPUserAttributeSubpacketVector)it.next(); for (Iterator sIt = key.getSignaturesForUserAttribute(id); sIt.hasNext();) { if (certification == sIt.next()) { found = true; returnKey = PGPPublicKey.removeCertification(returnKey, id, certification); } } } } } return returnKey; } } bouncycastle-1.49.orig/src/org/bouncycastle/openpgp/PGPPublicKeyRingCollection.java0000644000175000017500000002516711043534532030122 0ustar ebourgebourgpackage org.bouncycastle.openpgp; import org.bouncycastle.bcpg.BCPGOutputStream; import org.bouncycastle.util.Strings; import java.io.ByteArrayInputStream; import java.io.ByteArrayOutputStream; import java.io.IOException; import java.io.InputStream; import java.io.OutputStream; import java.util.ArrayList; import java.util.Collection; import java.util.HashMap; import java.util.Iterator; import java.util.List; import java.util.Map; /** * Often a PGP key ring file is made up of a succession of master/sub-key key rings. * If you want to read an entire public key file in one hit this is the class for you. */ public class PGPPublicKeyRingCollection { private Map pubRings = new HashMap(); private List order = new ArrayList(); private PGPPublicKeyRingCollection( Map pubRings, List order) { this.pubRings = pubRings; this.order = order; } public PGPPublicKeyRingCollection( byte[] encoding) throws IOException, PGPException { this(new ByteArrayInputStream(encoding)); } /** * Build a PGPPublicKeyRingCollection from the passed in input stream. * * @param in input stream containing data * @throws IOException if a problem parsing the base stream occurs * @throws PGPException if an object is encountered which isn't a PGPPublicKeyRing */ public PGPPublicKeyRingCollection( InputStream in) throws IOException, PGPException { PGPObjectFactory pgpFact = new PGPObjectFactory(in); Object obj; while ((obj = pgpFact.nextObject()) != null) { if (!(obj instanceof PGPPublicKeyRing)) { throw new PGPException(obj.getClass().getName() + " found where PGPPublicKeyRing expected"); } PGPPublicKeyRing pgpPub = (PGPPublicKeyRing)obj; Long key = new Long(pgpPub.getPublicKey().getKeyID()); pubRings.put(key, pgpPub); order.add(key); } } public PGPPublicKeyRingCollection( Collection collection) throws IOException, PGPException { Iterator it = collection.iterator(); while (it.hasNext()) { PGPPublicKeyRing pgpPub = (PGPPublicKeyRing)it.next(); Long key = new Long(pgpPub.getPublicKey().getKeyID()); pubRings.put(key, pgpPub); order.add(key); } } /** * Return the number of rings in this collection. * * @return size of the collection */ public int size() { return order.size(); } /** * return the public key rings making up this collection. */ public Iterator getKeyRings() { return pubRings.values().iterator(); } /** * Return an iterator of the key rings associated with the passed in userID. * * @param userID the user ID to be matched. * @return an iterator (possibly empty) of key rings which matched. * @throws PGPException */ public Iterator getKeyRings( String userID) throws PGPException { return getKeyRings(userID, false, false); } /** * Return an iterator of the key rings associated with the passed in userID. *

    * * @param userID the user ID to be matched. * @param matchPartial if true userID need only be a substring of an actual ID string to match. * @return an iterator (possibly empty) of key rings which matched. * @throws PGPException */ public Iterator getKeyRings( String userID, boolean matchPartial) throws PGPException { return getKeyRings(userID, matchPartial, false); } /** * Return an iterator of the key rings associated with the passed in userID. *

    * * @param userID the user ID to be matched. * @param matchPartial if true userID need only be a substring of an actual ID string to match. * @param ignoreCase if true case is ignored in user ID comparisons. * @return an iterator (possibly empty) of key rings which matched. * @throws PGPException */ public Iterator getKeyRings( String userID, boolean matchPartial, boolean ignoreCase) throws PGPException { Iterator it = this.getKeyRings(); List rings = new ArrayList(); if (ignoreCase) { userID = Strings.toLowerCase(userID); } while (it.hasNext()) { PGPPublicKeyRing pubRing = (PGPPublicKeyRing)it.next(); Iterator uIt = pubRing.getPublicKey().getUserIDs(); while (uIt.hasNext()) { String next = (String)uIt.next(); if (ignoreCase) { next = Strings.toLowerCase(next); } if (matchPartial) { if (next.indexOf(userID) > -1) { rings.add(pubRing); } } else { if (next.equals(userID)) { rings.add(pubRing); } } } } return rings.iterator(); } /** * Return the PGP public key associated with the given key id. * * @param keyID * @return the PGP public key * @throws PGPException */ public PGPPublicKey getPublicKey( long keyID) throws PGPException { Iterator it = this.getKeyRings(); while (it.hasNext()) { PGPPublicKeyRing pubRing = (PGPPublicKeyRing)it.next(); PGPPublicKey pub = pubRing.getPublicKey(keyID); if (pub != null) { return pub; } } return null; } /** * Return the public key ring which contains the key referred to by keyID. * * @param keyID key ID to match against * @return the public key ring * @throws PGPException */ public PGPPublicKeyRing getPublicKeyRing( long keyID) throws PGPException { Long id = new Long(keyID); if (pubRings.containsKey(id)) { return (PGPPublicKeyRing)pubRings.get(id); } Iterator it = this.getKeyRings(); while (it.hasNext()) { PGPPublicKeyRing pubRing = (PGPPublicKeyRing)it.next(); PGPPublicKey pub = pubRing.getPublicKey(keyID); if (pub != null) { return pubRing; } } return null; } /** * Return true if a key matching the passed in key ID is present, false otherwise. * * @param keyID key ID to look for. * @return true if keyID present, false otherwise. */ public boolean contains(long keyID) throws PGPException { return getPublicKey(keyID) != null; } public byte[] getEncoded() throws IOException { ByteArrayOutputStream bOut = new ByteArrayOutputStream(); this.encode(bOut); return bOut.toByteArray(); } public void encode( OutputStream outStream) throws IOException { BCPGOutputStream out; if (outStream instanceof BCPGOutputStream) { out = (BCPGOutputStream)outStream; } else { out = new BCPGOutputStream(outStream); } Iterator it = order.iterator(); while (it.hasNext()) { PGPPublicKeyRing sr = (PGPPublicKeyRing)pubRings.get(it.next()); sr.encode(out); } } /** * Return a new collection object containing the contents of the passed in collection and * the passed in public key ring. * * @param ringCollection the collection the ring to be added to. * @param publicKeyRing the key ring to be added. * @return a new collection merging the current one with the passed in ring. * @exception IllegalArgumentException if the keyID for the passed in ring is already present. */ public static PGPPublicKeyRingCollection addPublicKeyRing( PGPPublicKeyRingCollection ringCollection, PGPPublicKeyRing publicKeyRing) { Long key = new Long(publicKeyRing.getPublicKey().getKeyID()); if (ringCollection.pubRings.containsKey(key)) { throw new IllegalArgumentException("Collection already contains a key with a keyID for the passed in ring."); } Map newPubRings = new HashMap(ringCollection.pubRings); List newOrder = new ArrayList(ringCollection.order); newPubRings.put(key, publicKeyRing); newOrder.add(key); return new PGPPublicKeyRingCollection(newPubRings, newOrder); } /** * Return a new collection object containing the contents of this collection with * the passed in public key ring removed. * * @param ringCollection the collection the ring to be removed from. * @param publicKeyRing the key ring to be removed. * @return a new collection not containing the passed in ring. * @exception IllegalArgumentException if the keyID for the passed in ring not present. */ public static PGPPublicKeyRingCollection removePublicKeyRing( PGPPublicKeyRingCollection ringCollection, PGPPublicKeyRing publicKeyRing) { Long key = new Long(publicKeyRing.getPublicKey().getKeyID()); if (!ringCollection.pubRings.containsKey(key)) { throw new IllegalArgumentException("Collection does not contain a key with a keyID for the passed in ring."); } Map newPubRings = new HashMap(ringCollection.pubRings); List newOrder = new ArrayList(ringCollection.order); newPubRings.remove(key); for (int i = 0; i < newOrder.size(); i++) { Long r = (Long)newOrder.get(i); if (r.longValue() == key.longValue()) { newOrder.remove(i); break; } } return new PGPPublicKeyRingCollection(newPubRings, newOrder); } } bouncycastle-1.49.orig/src/org/bouncycastle/openpgp/PGPSignatureList.java0000644000175000017500000000140710262753174026172 0ustar ebourgebourgpackage org.bouncycastle.openpgp; /** * A list of PGP signatures - normally in the signature block after literal data. */ public class PGPSignatureList { PGPSignature[] sigs; public PGPSignatureList( PGPSignature[] sigs) { this.sigs = new PGPSignature[sigs.length]; System.arraycopy(sigs, 0, this.sigs, 0, sigs.length); } public PGPSignatureList( PGPSignature sig) { this.sigs = new PGPSignature[1]; this.sigs[0] = sig; } public PGPSignature get( int index) { return sigs[index]; } public int size() { return sigs.length; } public boolean isEmpty() { return (sigs.length == 0); } } bouncycastle-1.49.orig/src/org/bouncycastle/openpgp/PGPSignatureSubpacketVector.java0000644000175000017500000001535111553731772030372 0ustar ebourgebourgpackage org.bouncycastle.openpgp; import java.util.ArrayList; import java.util.Date; import java.util.List; import org.bouncycastle.bcpg.SignatureSubpacket; import org.bouncycastle.bcpg.SignatureSubpacketTags; import org.bouncycastle.bcpg.sig.Features; import org.bouncycastle.bcpg.sig.IssuerKeyID; import org.bouncycastle.bcpg.sig.KeyExpirationTime; import org.bouncycastle.bcpg.sig.KeyFlags; import org.bouncycastle.bcpg.sig.NotationData; import org.bouncycastle.bcpg.sig.PreferredAlgorithms; import org.bouncycastle.bcpg.sig.PrimaryUserID; import org.bouncycastle.bcpg.sig.SignatureCreationTime; import org.bouncycastle.bcpg.sig.SignatureExpirationTime; import org.bouncycastle.bcpg.sig.SignerUserID; /** * Container for a list of signature subpackets. */ public class PGPSignatureSubpacketVector { SignatureSubpacket[] packets; PGPSignatureSubpacketVector( SignatureSubpacket[] packets) { this.packets = packets; } public SignatureSubpacket getSubpacket( int type) { for (int i = 0; i != packets.length; i++) { if (packets[i].getType() == type) { return packets[i]; } } return null; } /** * Return true if a particular subpacket type exists. * * @param type type to look for. * @return true if present, false otherwise. */ public boolean hasSubpacket( int type) { return getSubpacket(type) != null; } /** * Return all signature subpackets of the passed in type. * @param type subpacket type code * @return an array of zero or more matching subpackets. */ public SignatureSubpacket[] getSubpackets( int type) { List list = new ArrayList(); for (int i = 0; i != packets.length; i++) { if (packets[i].getType() == type) { list.add(packets[i]); } } return (SignatureSubpacket[])list.toArray(new SignatureSubpacket[]{}); } public NotationData[] getNotationDataOccurences() { SignatureSubpacket[] notations = getSubpackets(SignatureSubpacketTags.NOTATION_DATA); NotationData[] vals = new NotationData[notations.length]; for (int i = 0; i < notations.length; i++) { vals[i] = (NotationData)notations[i]; } return vals; } public long getIssuerKeyID() { SignatureSubpacket p = this.getSubpacket(SignatureSubpacketTags.ISSUER_KEY_ID); if (p == null) { return 0; } return ((IssuerKeyID)p).getKeyID(); } public Date getSignatureCreationTime() { SignatureSubpacket p = this.getSubpacket(SignatureSubpacketTags.CREATION_TIME); if (p == null) { return null; } return ((SignatureCreationTime)p).getTime(); } /** * Return the number of seconds a signature is valid for after its creation date. A value of zero means * the signature never expires. * * @return seconds a signature is valid for. */ public long getSignatureExpirationTime() { SignatureSubpacket p = this.getSubpacket(SignatureSubpacketTags.EXPIRE_TIME); if (p == null) { return 0; } return ((SignatureExpirationTime)p).getTime(); } /** * Return the number of seconds a key is valid for after its creation date. A value of zero means * the key never expires. * * @return seconds a key is valid for. */ public long getKeyExpirationTime() { SignatureSubpacket p = this.getSubpacket(SignatureSubpacketTags.KEY_EXPIRE_TIME); if (p == null) { return 0; } return ((KeyExpirationTime)p).getTime(); } public int[] getPreferredHashAlgorithms() { SignatureSubpacket p = this.getSubpacket(SignatureSubpacketTags.PREFERRED_HASH_ALGS); if (p == null) { return null; } return ((PreferredAlgorithms)p).getPreferences(); } public int[] getPreferredSymmetricAlgorithms() { SignatureSubpacket p = this.getSubpacket(SignatureSubpacketTags.PREFERRED_SYM_ALGS); if (p == null) { return null; } return ((PreferredAlgorithms)p).getPreferences(); } public int[] getPreferredCompressionAlgorithms() { SignatureSubpacket p = this.getSubpacket(SignatureSubpacketTags.PREFERRED_COMP_ALGS); if (p == null) { return null; } return ((PreferredAlgorithms)p).getPreferences(); } public int getKeyFlags() { SignatureSubpacket p = this.getSubpacket(SignatureSubpacketTags.KEY_FLAGS); if (p == null) { return 0; } return ((KeyFlags)p).getFlags(); } public String getSignerUserID() { SignatureSubpacket p = this.getSubpacket(SignatureSubpacketTags.SIGNER_USER_ID); if (p == null) { return null; } return ((SignerUserID)p).getID(); } public boolean isPrimaryUserID() { PrimaryUserID primaryId = (PrimaryUserID)this.getSubpacket(SignatureSubpacketTags.PRIMARY_USER_ID); if (primaryId != null) { return primaryId.isPrimaryUserID(); } return false; } public int[] getCriticalTags() { int count = 0; for (int i = 0; i != packets.length; i++) { if (packets[i].isCritical()) { count++; } } int[] list = new int[count]; count = 0; for (int i = 0; i != packets.length; i++) { if (packets[i].isCritical()) { list[count++] = packets[i].getType(); } } return list; } public Features getFeatures() { SignatureSubpacket p = this.getSubpacket(SignatureSubpacketTags.FEATURES); if (p == null) { return null; } return new Features(p.isCritical(), p.getData()); } /** * Return the number of packets this vector contains. * * @return size of the packet vector. */ public int size() { return packets.length; } SignatureSubpacket[] toSubpacketArray() { return packets; } } bouncycastle-1.49.orig/src/org/bouncycastle/openpgp/package.html0000644000175000017500000000153110262753174024442 0ustar ebourgebourg High level classes for dealing with OpenPGP objects.

    Note: These are based on the org.bouncycastle.bcpg classes and use a streaming model, so for some objects which have an input stream associated it is necessary to read to the end of the input stream on the object before trying to read another object from the orginal input stream.

    A word on key ring files. For the purpose of this package a PGP key ring is a master key and a collection of sub-keys associated with it. These public and secret key rings are handled by the PGPPublicKey ring class and the PGPSecretKeyRing class respectively. In the case where you are trying to read an key file which has multiple key rings in it, use PGPSecretKeyRingCollection for the secret key file and PGPPublicKeyRingCollection for the public key file. bouncycastle-1.49.orig/src/org/bouncycastle/openpgp/PGPCompressedDataGenerator.java0000644000175000017500000001362511662561660030151 0ustar ebourgebourgpackage org.bouncycastle.openpgp; import org.bouncycastle.apache.bzip2.CBZip2OutputStream; import org.bouncycastle.bcpg.BCPGOutputStream; import org.bouncycastle.bcpg.CompressionAlgorithmTags; import org.bouncycastle.bcpg.PacketTags; import java.io.IOException; import java.io.OutputStream; import java.util.zip.Deflater; import java.util.zip.DeflaterOutputStream; /** *class for producing compressed data packets. */ public class PGPCompressedDataGenerator implements CompressionAlgorithmTags, StreamGenerator { private int algorithm; private int compression; private OutputStream dOut; private BCPGOutputStream pkOut; public PGPCompressedDataGenerator( int algorithm) { this(algorithm, Deflater.DEFAULT_COMPRESSION); } public PGPCompressedDataGenerator( int algorithm, int compression) { switch (algorithm) { case CompressionAlgorithmTags.UNCOMPRESSED: case CompressionAlgorithmTags.ZIP: case CompressionAlgorithmTags.ZLIB: case CompressionAlgorithmTags.BZIP2: break; default: throw new IllegalArgumentException("unknown compression algorithm"); } if (compression != Deflater.DEFAULT_COMPRESSION) { if ((compression < Deflater.NO_COMPRESSION) || (compression > Deflater.BEST_COMPRESSION)) { throw new IllegalArgumentException("unknown compression level: " + compression); } } this.algorithm = algorithm; this.compression = compression; } /** * Return an OutputStream which will save the data being written to * the compressed object. *

    * The stream created can be closed off by either calling close() * on the stream or close() on the generator. Closing the returned * stream does not close off the OutputStream parameter out. * * @param out underlying OutputStream to be used. * @return OutputStream * @throws IOException, IllegalStateException */ public OutputStream open( OutputStream out) throws IOException { if (dOut != null) { throw new IllegalStateException("generator already in open state"); } this.pkOut = new BCPGOutputStream(out, PacketTags.COMPRESSED_DATA); doOpen(); return new WrappedGeneratorStream(dOut, this); } /** * Return an OutputStream which will compress the data as it is written * to it. The stream will be written out in chunks according to the size of the * passed in buffer. *

    * The stream created can be closed off by either calling close() * on the stream or close() on the generator. Closing the returned * stream does not close off the OutputStream parameter out. *

    * Note: if the buffer is not a power of 2 in length only the largest power of 2 * bytes worth of the buffer will be used. *

    *

    * Note: using this may break compatibility with RFC 1991 compliant tools. Only recent OpenPGP * implementations are capable of accepting these streams. *

    * * @param out underlying OutputStream to be used. * @param buffer the buffer to use. * @return OutputStream * @throws IOException * @throws PGPException */ public OutputStream open( OutputStream out, byte[] buffer) throws IOException, PGPException { if (dOut != null) { throw new IllegalStateException("generator already in open state"); } this.pkOut = new BCPGOutputStream(out, PacketTags.COMPRESSED_DATA, buffer); doOpen(); return new WrappedGeneratorStream(dOut, this); } private void doOpen() throws IOException { pkOut.write(algorithm); switch (algorithm) { case CompressionAlgorithmTags.UNCOMPRESSED: dOut = pkOut; break; case CompressionAlgorithmTags.ZIP: dOut = new SafeDeflaterOutputStream(pkOut, compression, true); break; case CompressionAlgorithmTags.ZLIB: dOut = new SafeDeflaterOutputStream(pkOut, compression, false); break; case CompressionAlgorithmTags.BZIP2: dOut = new SafeCBZip2OutputStream(pkOut); break; default: // Constructor should guard against this possibility throw new IllegalStateException(); } } /** * Close the compressed object - this is equivalent to calling close on the stream * returned by the open() method. * * @throws IOException */ public void close() throws IOException { if (dOut != null) { if (dOut != pkOut) { dOut.close(); dOut.flush(); } dOut = null; pkOut.finish(); pkOut.flush(); pkOut = null; } } private static class SafeCBZip2OutputStream extends CBZip2OutputStream { public SafeCBZip2OutputStream(OutputStream output) throws IOException { super(output); } public void close() throws IOException { finish(); } } private class SafeDeflaterOutputStream extends DeflaterOutputStream { public SafeDeflaterOutputStream(OutputStream output, int compression, boolean nowrap) { super(output, new Deflater(compression, nowrap)); } public void close() throws IOException { finish(); def.end(); } } } bouncycastle-1.49.orig/src/org/bouncycastle/openpgp/WrappedGeneratorStream.java0000644000175000017500000000154710527766126027465 0ustar ebourgebourgpackage org.bouncycastle.openpgp; import java.io.IOException; import java.io.OutputStream; class WrappedGeneratorStream extends OutputStream { private final OutputStream _out; private final StreamGenerator _sGen; public WrappedGeneratorStream(OutputStream out, StreamGenerator sGen) { _out = out; _sGen = sGen; } public void write(byte[] bytes) throws IOException { _out.write(bytes); } public void write(byte[] bytes, int offset, int length) throws IOException { _out.write(bytes, offset, length); } public void write(int b) throws IOException { _out.write(b); } public void flush() throws IOException { _out.flush(); } public void close() throws IOException { _sGen.close(); } } bouncycastle-1.49.orig/src/org/bouncycastle/openpgp/PGPPublicKeyRing.java0000644000175000017500000001635611600525371026106 0ustar ebourgebourgpackage org.bouncycastle.openpgp; import java.io.ByteArrayInputStream; import java.io.ByteArrayOutputStream; import java.io.IOException; import java.io.InputStream; import java.io.OutputStream; import java.util.ArrayList; import java.util.Collections; import java.util.Iterator; import java.util.List; import org.bouncycastle.bcpg.BCPGInputStream; import org.bouncycastle.bcpg.PacketTags; import org.bouncycastle.bcpg.PublicKeyPacket; import org.bouncycastle.bcpg.TrustPacket; import org.bouncycastle.openpgp.operator.KeyFingerPrintCalculator; import org.bouncycastle.openpgp.operator.jcajce.JcaKeyFingerprintCalculator; /** * Class to hold a single master public key and its subkeys. *

    * Often PGP keyring files consist of multiple master keys, if you are trying to process * or construct one of these you should use the PGPPublicKeyRingCollection class. */ public class PGPPublicKeyRing extends PGPKeyRing { List keys; /** * @deprecated use version that takes a KeyFingerPrintCalculator */ public PGPPublicKeyRing( byte[] encoding) throws IOException { this(new ByteArrayInputStream(encoding), new JcaKeyFingerprintCalculator()); } public PGPPublicKeyRing( byte[] encoding, KeyFingerPrintCalculator fingerPrintCalculator) throws IOException { this(new ByteArrayInputStream(encoding), fingerPrintCalculator); } /** * @param pubKeys */ PGPPublicKeyRing( List pubKeys) { this.keys = pubKeys; } /** * @deprecated use version that takes a KeyFingerPrintCalculator */ public PGPPublicKeyRing( InputStream in) throws IOException { this(in, new JcaKeyFingerprintCalculator()); } public PGPPublicKeyRing( InputStream in, KeyFingerPrintCalculator fingerPrintCalculator) throws IOException { this.keys = new ArrayList(); BCPGInputStream pIn = wrap(in); int initialTag = pIn.nextPacketTag(); if (initialTag != PacketTags.PUBLIC_KEY && initialTag != PacketTags.PUBLIC_SUBKEY) { throw new IOException( "public key ring doesn't start with public key tag: " + "tag 0x" + Integer.toHexString(initialTag)); } PublicKeyPacket pubPk = (PublicKeyPacket)pIn.readPacket(); TrustPacket trustPk = readOptionalTrustPacket(pIn); // direct signatures and revocations List keySigs = readSignaturesAndTrust(pIn); List ids = new ArrayList(); List idTrusts = new ArrayList(); List idSigs = new ArrayList(); readUserIDs(pIn, ids, idTrusts, idSigs); try { keys.add(new PGPPublicKey(pubPk, trustPk, keySigs, ids, idTrusts, idSigs, fingerPrintCalculator)); // Read subkeys while (pIn.nextPacketTag() == PacketTags.PUBLIC_SUBKEY) { keys.add(readSubkey(pIn, fingerPrintCalculator)); } } catch (PGPException e) { throw new IOException("processing exception: " + e.toString()); } } /** * Return the first public key in the ring. * * @return PGPPublicKey */ public PGPPublicKey getPublicKey() { return (PGPPublicKey)keys.get(0); } /** * Return the public key referred to by the passed in keyID if it * is present. * * @param keyID * @return PGPPublicKey */ public PGPPublicKey getPublicKey( long keyID) { for (int i = 0; i != keys.size(); i++) { PGPPublicKey k = (PGPPublicKey)keys.get(i); if (keyID == k.getKeyID()) { return k; } } return null; } /** * Return an iterator containing all the public keys. * * @return Iterator */ public Iterator getPublicKeys() { return Collections.unmodifiableList(keys).iterator(); } public byte[] getEncoded() throws IOException { ByteArrayOutputStream bOut = new ByteArrayOutputStream(); this.encode(bOut); return bOut.toByteArray(); } public void encode( OutputStream outStream) throws IOException { for (int i = 0; i != keys.size(); i++) { PGPPublicKey k = (PGPPublicKey)keys.get(i); k.encode(outStream); } } /** * Returns a new key ring with the public key passed in * either added or replacing an existing one. * * @param pubRing the public key ring to be modified * @param pubKey the public key to be inserted. * @return a new keyRing */ public static PGPPublicKeyRing insertPublicKey( PGPPublicKeyRing pubRing, PGPPublicKey pubKey) { List keys = new ArrayList(pubRing.keys); boolean found = false; boolean masterFound = false; for (int i = 0; i != keys.size();i++) { PGPPublicKey key = (PGPPublicKey)keys.get(i); if (key.getKeyID() == pubKey.getKeyID()) { found = true; keys.set(i, pubKey); } if (key.isMasterKey()) { masterFound = true; } } if (!found) { if (pubKey.isMasterKey()) { if (masterFound) { throw new IllegalArgumentException("cannot add a master key to a ring that already has one"); } keys.add(0, pubKey); } else { keys.add(pubKey); } } return new PGPPublicKeyRing(keys); } /** * Returns a new key ring with the public key passed in * removed from the key ring. * * @param pubRing the public key ring to be modified * @param pubKey the public key to be removed. * @return a new keyRing, null if pubKey is not found. */ public static PGPPublicKeyRing removePublicKey( PGPPublicKeyRing pubRing, PGPPublicKey pubKey) { List keys = new ArrayList(pubRing.keys); boolean found = false; for (int i = 0; i < keys.size();i++) { PGPPublicKey key = (PGPPublicKey)keys.get(i); if (key.getKeyID() == pubKey.getKeyID()) { found = true; keys.remove(i); } } if (!found) { return null; } return new PGPPublicKeyRing(keys); } static PGPPublicKey readSubkey(BCPGInputStream in, KeyFingerPrintCalculator fingerPrintCalculator) throws IOException, PGPException { PublicKeyPacket pk = (PublicKeyPacket)in.readPacket(); TrustPacket kTrust = readOptionalTrustPacket(in); // PGP 8 actually leaves out the signature. List sigList = readSignaturesAndTrust(in); return new PGPPublicKey(pk, kTrust, sigList, fingerPrintCalculator); } } bouncycastle-1.49.orig/src/org/bouncycastle/crypto/0000755000175000017500000000000012152033551022017 5ustar ebourgebourgbouncycastle-1.49.orig/src/org/bouncycastle/crypto/KeyEncoder.java0000644000175000017500000000027512033452577024731 0ustar ebourgebourgpackage org.bouncycastle.crypto; import org.bouncycastle.crypto.params.AsymmetricKeyParameter; public interface KeyEncoder { byte[] getEncoded(AsymmetricKeyParameter keyParameter); } bouncycastle-1.49.orig/src/org/bouncycastle/crypto/PBEParametersGenerator.java0000644000175000017500000001061212114544760027172 0ustar ebourgebourgpackage org.bouncycastle.crypto; import org.bouncycastle.util.Strings; /** * super class for all Password Based Encryption (PBE) parameter generator classes. */ public abstract class PBEParametersGenerator { protected byte[] password; protected byte[] salt; protected int iterationCount; /** * base constructor. */ protected PBEParametersGenerator() { } /** * initialise the PBE generator. * * @param password the password converted into bytes (see below). * @param salt the salt to be mixed with the password. * @param iterationCount the number of iterations the "mixing" function * is to be applied for. */ public void init( byte[] password, byte[] salt, int iterationCount) { this.password = password; this.salt = salt; this.iterationCount = iterationCount; } /** * return the password byte array. * * @return the password byte array. */ public byte[] getPassword() { return password; } /** * return the salt byte array. * * @return the salt byte array. */ public byte[] getSalt() { return salt; } /** * return the iteration count. * * @return the iteration count. */ public int getIterationCount() { return iterationCount; } /** * generate derived parameters for a key of length keySize. * * @param keySize the length, in bits, of the key required. * @return a parameters object representing a key. */ public abstract CipherParameters generateDerivedParameters(int keySize); /** * generate derived parameters for a key of length keySize, and * an initialisation vector (IV) of length ivSize. * * @param keySize the length, in bits, of the key required. * @param ivSize the length, in bits, of the iv required. * @return a parameters object representing a key and an IV. */ public abstract CipherParameters generateDerivedParameters(int keySize, int ivSize); /** * generate derived parameters for a key of length keySize, specifically * for use with a MAC. * * @param keySize the length, in bits, of the key required. * @return a parameters object representing a key. */ public abstract CipherParameters generateDerivedMacParameters(int keySize); /** * converts a password to a byte array according to the scheme in * PKCS5 (ascii, no padding) * * @param password a character array representing the password. * @return a byte array representing the password. */ public static byte[] PKCS5PasswordToBytes( char[] password) { if (password != null) { byte[] bytes = new byte[password.length]; for (int i = 0; i != bytes.length; i++) { bytes[i] = (byte)password[i]; } return bytes; } else { return new byte[0]; } } /** * converts a password to a byte array according to the scheme in * PKCS5 (UTF-8, no padding) * * @param password a character array representing the password. * @return a byte array representing the password. */ public static byte[] PKCS5PasswordToUTF8Bytes( char[] password) { if (password != null) { return Strings.toUTF8ByteArray(password); } else { return new byte[0]; } } /** * converts a password to a byte array according to the scheme in * PKCS12 (unicode, big endian, 2 zero pad bytes at the end). * * @param password a character array representing the password. * @return a byte array representing the password. */ public static byte[] PKCS12PasswordToBytes( char[] password) { if (password != null && password.length > 0) { // +1 for extra 2 pad bytes. byte[] bytes = new byte[(password.length + 1) * 2]; for (int i = 0; i != password.length; i ++) { bytes[i * 2] = (byte)(password[i] >>> 8); bytes[i * 2 + 1] = (byte)password[i]; } return bytes; } else { return new byte[0]; } } } bouncycastle-1.49.orig/src/org/bouncycastle/crypto/BufferedBlockCipher.java0000644000175000017500000002102312103434231026504 0ustar ebourgebourgpackage org.bouncycastle.crypto; /** * A wrapper class that allows block ciphers to be used to process data in * a piecemeal fashion. The BufferedBlockCipher outputs a block only when the * buffer is full and more data is being added, or on a doFinal. *

    * Note: in the case where the underlying cipher is either a CFB cipher or an * OFB one the last block may not be a multiple of the block size. */ public class BufferedBlockCipher { protected byte[] buf; protected int bufOff; protected boolean forEncryption; protected BlockCipher cipher; protected boolean partialBlockOkay; protected boolean pgpCFB; /** * constructor for subclasses */ protected BufferedBlockCipher() { } /** * Create a buffered block cipher without padding. * * @param cipher the underlying block cipher this buffering object wraps. */ public BufferedBlockCipher( BlockCipher cipher) { this.cipher = cipher; buf = new byte[cipher.getBlockSize()]; bufOff = 0; // // check if we can handle partial blocks on doFinal. // String name = cipher.getAlgorithmName(); int idx = name.indexOf('/') + 1; pgpCFB = (idx > 0 && name.startsWith("PGP", idx)); if (pgpCFB) { partialBlockOkay = true; } else { partialBlockOkay = (idx > 0 && (name.startsWith("CFB", idx) || name.startsWith("OFB", idx) || name.startsWith("OpenPGP", idx) || name.startsWith("SIC", idx) || name.startsWith("GCTR", idx))); } } /** * return the cipher this object wraps. * * @return the cipher this object wraps. */ public BlockCipher getUnderlyingCipher() { return cipher; } /** * initialise the cipher. * * @param forEncryption if true the cipher is initialised for * encryption, if false for decryption. * @param params the key and other data required by the cipher. * @exception IllegalArgumentException if the params argument is * inappropriate. */ public void init( boolean forEncryption, CipherParameters params) throws IllegalArgumentException { this.forEncryption = forEncryption; reset(); cipher.init(forEncryption, params); } /** * return the blocksize for the underlying cipher. * * @return the blocksize for the underlying cipher. */ public int getBlockSize() { return cipher.getBlockSize(); } /** * return the size of the output buffer required for an update * an input of len bytes. * * @param len the length of the input. * @return the space required to accommodate a call to update * with len bytes of input. */ public int getUpdateOutputSize( int len) { int total = len + bufOff; int leftOver; if (pgpCFB) { leftOver = total % buf.length - (cipher.getBlockSize() + 2); } else { leftOver = total % buf.length; } return total - leftOver; } /** * return the size of the output buffer required for an update plus a * doFinal with an input of 'length' bytes. * * @param length the length of the input. * @return the space required to accommodate a call to update and doFinal * with 'length' bytes of input. */ public int getOutputSize( int length) { // Note: Can assume partialBlockOkay is true for purposes of this calculation return length + bufOff; } /** * process a single byte, producing an output block if neccessary. * * @param in the input byte. * @param out the space for any output that might be produced. * @param outOff the offset from which the output will be copied. * @return the number of output bytes copied to out. * @exception DataLengthException if there isn't enough space in out. * @exception IllegalStateException if the cipher isn't initialised. */ public int processByte( byte in, byte[] out, int outOff) throws DataLengthException, IllegalStateException { int resultLen = 0; buf[bufOff++] = in; if (bufOff == buf.length) { resultLen = cipher.processBlock(buf, 0, out, outOff); bufOff = 0; } return resultLen; } /** * process an array of bytes, producing output if necessary. * * @param in the input byte array. * @param inOff the offset at which the input data starts. * @param len the number of bytes to be copied out of the input array. * @param out the space for any output that might be produced. * @param outOff the offset from which the output will be copied. * @return the number of output bytes copied to out. * @exception DataLengthException if there isn't enough space in out. * @exception IllegalStateException if the cipher isn't initialised. */ public int processBytes( byte[] in, int inOff, int len, byte[] out, int outOff) throws DataLengthException, IllegalStateException { if (len < 0) { throw new IllegalArgumentException("Can't have a negative input length!"); } int blockSize = getBlockSize(); int length = getUpdateOutputSize(len); if (length > 0) { if ((outOff + length) > out.length) { throw new OutputLengthException("output buffer too short"); } } int resultLen = 0; int gapLen = buf.length - bufOff; if (len > gapLen) { System.arraycopy(in, inOff, buf, bufOff, gapLen); resultLen += cipher.processBlock(buf, 0, out, outOff); bufOff = 0; len -= gapLen; inOff += gapLen; while (len > buf.length) { resultLen += cipher.processBlock(in, inOff, out, outOff + resultLen); len -= blockSize; inOff += blockSize; } } System.arraycopy(in, inOff, buf, bufOff, len); bufOff += len; if (bufOff == buf.length) { resultLen += cipher.processBlock(buf, 0, out, outOff + resultLen); bufOff = 0; } return resultLen; } /** * Process the last block in the buffer. * * @param out the array the block currently being held is copied into. * @param outOff the offset at which the copying starts. * @return the number of output bytes copied to out. * @exception DataLengthException if there is insufficient space in out for * the output, or the input is not block size aligned and should be. * @exception IllegalStateException if the underlying cipher is not * initialised. * @exception InvalidCipherTextException if padding is expected and not found. * @exception DataLengthException if the input is not block size * aligned. */ public int doFinal( byte[] out, int outOff) throws DataLengthException, IllegalStateException, InvalidCipherTextException { try { int resultLen = 0; if (outOff + bufOff > out.length) { throw new OutputLengthException("output buffer too short for doFinal()"); } if (bufOff != 0) { if (!partialBlockOkay) { throw new DataLengthException("data not block size aligned"); } cipher.processBlock(buf, 0, buf, 0); resultLen = bufOff; bufOff = 0; System.arraycopy(buf, 0, out, outOff, resultLen); } return resultLen; } finally { reset(); } } /** * Reset the buffer and cipher. After resetting the object is in the same * state as it was after the last init (if there was one). */ public void reset() { // // clean the buffer. // for (int i = 0; i < buf.length; i++) { buf[i] = 0; } bufOff = 0; // // reset the underlying cipher. // cipher.reset(); } } bouncycastle-1.49.orig/src/org/bouncycastle/crypto/paddings/0000755000175000017500000000000012152033551023610 5ustar ebourgebourgbouncycastle-1.49.orig/src/org/bouncycastle/crypto/paddings/PaddedBufferedBlockCipher.java0000644000175000017500000002076212103434427031417 0ustar ebourgebourgpackage org.bouncycastle.crypto.paddings; import org.bouncycastle.crypto.BlockCipher; import org.bouncycastle.crypto.BufferedBlockCipher; import org.bouncycastle.crypto.CipherParameters; import org.bouncycastle.crypto.DataLengthException; import org.bouncycastle.crypto.InvalidCipherTextException; import org.bouncycastle.crypto.OutputLengthException; import org.bouncycastle.crypto.params.ParametersWithRandom; /** * A wrapper class that allows block ciphers to be used to process data in * a piecemeal fashion with padding. The PaddedBufferedBlockCipher * outputs a block only when the buffer is full and more data is being added, * or on a doFinal (unless the current block in the buffer is a pad block). * The default padding mechanism used is the one outlined in PKCS5/PKCS7. */ public class PaddedBufferedBlockCipher extends BufferedBlockCipher { BlockCipherPadding padding; /** * Create a buffered block cipher with the desired padding. * * @param cipher the underlying block cipher this buffering object wraps. * @param padding the padding type. */ public PaddedBufferedBlockCipher( BlockCipher cipher, BlockCipherPadding padding) { this.cipher = cipher; this.padding = padding; buf = new byte[cipher.getBlockSize()]; bufOff = 0; } /** * Create a buffered block cipher PKCS7 padding * * @param cipher the underlying block cipher this buffering object wraps. */ public PaddedBufferedBlockCipher( BlockCipher cipher) { this(cipher, new PKCS7Padding()); } /** * initialise the cipher. * * @param forEncryption if true the cipher is initialised for * encryption, if false for decryption. * @param params the key and other data required by the cipher. * @exception IllegalArgumentException if the params argument is * inappropriate. */ public void init( boolean forEncryption, CipherParameters params) throws IllegalArgumentException { this.forEncryption = forEncryption; reset(); if (params instanceof ParametersWithRandom) { ParametersWithRandom p = (ParametersWithRandom)params; padding.init(p.getRandom()); cipher.init(forEncryption, p.getParameters()); } else { padding.init(null); cipher.init(forEncryption, params); } } /** * return the minimum size of the output buffer required for an update * plus a doFinal with an input of len bytes. * * @param len the length of the input. * @return the space required to accommodate a call to update and doFinal * with len bytes of input. */ public int getOutputSize( int len) { int total = len + bufOff; int leftOver = total % buf.length; if (leftOver == 0) { if (forEncryption) { return total + buf.length; } return total; } return total - leftOver + buf.length; } /** * return the size of the output buffer required for an update * an input of len bytes. * * @param len the length of the input. * @return the space required to accommodate a call to update * with len bytes of input. */ public int getUpdateOutputSize( int len) { int total = len + bufOff; int leftOver = total % buf.length; if (leftOver == 0) { return total - buf.length; } return total - leftOver; } /** * process a single byte, producing an output block if neccessary. * * @param in the input byte. * @param out the space for any output that might be produced. * @param outOff the offset from which the output will be copied. * @return the number of output bytes copied to out. * @exception DataLengthException if there isn't enough space in out. * @exception IllegalStateException if the cipher isn't initialised. */ public int processByte( byte in, byte[] out, int outOff) throws DataLengthException, IllegalStateException { int resultLen = 0; if (bufOff == buf.length) { resultLen = cipher.processBlock(buf, 0, out, outOff); bufOff = 0; } buf[bufOff++] = in; return resultLen; } /** * process an array of bytes, producing output if necessary. * * @param in the input byte array. * @param inOff the offset at which the input data starts. * @param len the number of bytes to be copied out of the input array. * @param out the space for any output that might be produced. * @param outOff the offset from which the output will be copied. * @return the number of output bytes copied to out. * @exception DataLengthException if there isn't enough space in out. * @exception IllegalStateException if the cipher isn't initialised. */ public int processBytes( byte[] in, int inOff, int len, byte[] out, int outOff) throws DataLengthException, IllegalStateException { if (len < 0) { throw new IllegalArgumentException("Can't have a negative input length!"); } int blockSize = getBlockSize(); int length = getUpdateOutputSize(len); if (length > 0) { if ((outOff + length) > out.length) { throw new OutputLengthException("output buffer too short"); } } int resultLen = 0; int gapLen = buf.length - bufOff; if (len > gapLen) { System.arraycopy(in, inOff, buf, bufOff, gapLen); resultLen += cipher.processBlock(buf, 0, out, outOff); bufOff = 0; len -= gapLen; inOff += gapLen; while (len > buf.length) { resultLen += cipher.processBlock(in, inOff, out, outOff + resultLen); len -= blockSize; inOff += blockSize; } } System.arraycopy(in, inOff, buf, bufOff, len); bufOff += len; return resultLen; } /** * Process the last block in the buffer. If the buffer is currently * full and padding needs to be added a call to doFinal will produce * 2 * getBlockSize() bytes. * * @param out the array the block currently being held is copied into. * @param outOff the offset at which the copying starts. * @return the number of output bytes copied to out. * @exception DataLengthException if there is insufficient space in out for * the output or we are decrypting and the input is not block size aligned. * @exception IllegalStateException if the underlying cipher is not * initialised. * @exception InvalidCipherTextException if padding is expected and not found. */ public int doFinal( byte[] out, int outOff) throws DataLengthException, IllegalStateException, InvalidCipherTextException { int blockSize = cipher.getBlockSize(); int resultLen = 0; if (forEncryption) { if (bufOff == blockSize) { if ((outOff + 2 * blockSize) > out.length) { reset(); throw new OutputLengthException("output buffer too short"); } resultLen = cipher.processBlock(buf, 0, out, outOff); bufOff = 0; } padding.addPadding(buf, bufOff); resultLen += cipher.processBlock(buf, 0, out, outOff + resultLen); reset(); } else { if (bufOff == blockSize) { resultLen = cipher.processBlock(buf, 0, buf, 0); bufOff = 0; } else { reset(); throw new DataLengthException("last block incomplete in decryption"); } try { resultLen -= padding.padCount(buf); System.arraycopy(buf, 0, out, outOff, resultLen); } finally { reset(); } } return resultLen; } } bouncycastle-1.49.orig/src/org/bouncycastle/crypto/paddings/X923Padding.java0000644000175000017500000000334610262753175026430 0ustar ebourgebourgpackage org.bouncycastle.crypto.paddings; import java.security.SecureRandom; import org.bouncycastle.crypto.InvalidCipherTextException; /** * A padder that adds X9.23 padding to a block - if a SecureRandom is * passed in random padding is assumed, otherwise padding with zeros is used. */ public class X923Padding implements BlockCipherPadding { SecureRandom random = null; /** * Initialise the padder. * * @param random a SecureRandom if one is available. */ public void init(SecureRandom random) throws IllegalArgumentException { this.random = random; } /** * Return the name of the algorithm the padder implements. * * @return the name of the algorithm the padder implements. */ public String getPaddingName() { return "X9.23"; } /** * add the pad bytes to the passed in block, returning the * number of bytes added. */ public int addPadding( byte[] in, int inOff) { byte code = (byte)(in.length - inOff); while (inOff < in.length - 1) { if (random == null) { in[inOff] = 0; } else { in[inOff] = (byte)random.nextInt(); } inOff++; } in[inOff] = code; return code; } /** * return the number of pad bytes present in the block. */ public int padCount(byte[] in) throws InvalidCipherTextException { int count = in[in.length - 1] & 0xff; if (count > in.length) { throw new InvalidCipherTextException("pad block corrupted"); } return count; } } bouncycastle-1.49.orig/src/org/bouncycastle/crypto/paddings/ISO7816d4Padding.java0000644000175000017500000000325010262753175027165 0ustar ebourgebourgpackage org.bouncycastle.crypto.paddings; import java.security.SecureRandom; import org.bouncycastle.crypto.InvalidCipherTextException; /** * A padder that adds the padding according to the scheme referenced in * ISO 7814-4 - scheme 2 from ISO 9797-1. The first byte is 0x80, rest is 0x00 */ public class ISO7816d4Padding implements BlockCipherPadding { /** * Initialise the padder. * * @param random - a SecureRandom if available. */ public void init(SecureRandom random) throws IllegalArgumentException { // nothing to do. } /** * Return the name of the algorithm the padder implements. * * @return the name of the algorithm the padder implements. */ public String getPaddingName() { return "ISO7816-4"; } /** * add the pad bytes to the passed in block, returning the * number of bytes added. */ public int addPadding( byte[] in, int inOff) { int added = (in.length - inOff); in [inOff]= (byte) 0x80; inOff ++; while (inOff < in.length) { in[inOff] = (byte) 0; inOff++; } return added; } /** * return the number of pad bytes present in the block. */ public int padCount(byte[] in) throws InvalidCipherTextException { int count = in.length - 1; while (count > 0 && in[count] == 0) { count--; } if (in[count] != (byte)0x80) { throw new InvalidCipherTextException("pad block corrupted"); } return in.length - count; } } bouncycastle-1.49.orig/src/org/bouncycastle/crypto/paddings/TBCPadding.java0000644000175000017500000000410310262753175026363 0ustar ebourgebourgpackage org.bouncycastle.crypto.paddings; import java.security.SecureRandom; import org.bouncycastle.crypto.InvalidCipherTextException; /** * A padder that adds Trailing-Bit-Compliment padding to a block. *

    * This padding pads the block out with the compliment of the last bit * of the plain text. *

    */ public class TBCPadding implements BlockCipherPadding { /** * Initialise the padder. * * @param random - a SecureRandom if available. */ public void init(SecureRandom random) throws IllegalArgumentException { // nothing to do. } /** * Return the name of the algorithm the padder implements. * * @return the name of the algorithm the padder implements. */ public String getPaddingName() { return "TBC"; } /** * add the pad bytes to the passed in block, returning the * number of bytes added. *

    * Note: this assumes that the last block of plain text is always * passed to it inside in. i.e. if inOff is zero, indicating the * entire block is to be overwritten with padding the value of in * should be the same as the last block of plain text. *

    */ public int addPadding( byte[] in, int inOff) { int count = in.length - inOff; byte code; if (inOff > 0) { code = (byte)((in[inOff - 1] & 0x01) == 0 ? 0xff : 0x00); } else { code = (byte)((in[in.length - 1] & 0x01) == 0 ? 0xff : 0x00); } while (inOff < in.length) { in[inOff] = code; inOff++; } return count; } /** * return the number of pad bytes present in the block. */ public int padCount(byte[] in) throws InvalidCipherTextException { byte code = in[in.length - 1]; int index = in.length - 1; while (index > 0 && in[index - 1] == code) { index--; } return in.length - index; } } bouncycastle-1.49.orig/src/org/bouncycastle/crypto/paddings/BlockCipherPadding.java0000644000175000017500000000272110262753175030144 0ustar ebourgebourgpackage org.bouncycastle.crypto.paddings; import java.security.SecureRandom; import org.bouncycastle.crypto.InvalidCipherTextException; /** * Block cipher padders are expected to conform to this interface */ public interface BlockCipherPadding { /** * Initialise the padder. * * @param random the source of randomness for the padding, if required. */ public void init(SecureRandom random) throws IllegalArgumentException; /** * Return the name of the algorithm the cipher implements. * * @return the name of the algorithm the cipher implements. */ public String getPaddingName(); /** * add the pad bytes to the passed in block, returning the * number of bytes added. *

    * Note: this assumes that the last block of plain text is always * passed to it inside in. i.e. if inOff is zero, indicating the * entire block is to be overwritten with padding the value of in * should be the same as the last block of plain text. The reason * for this is that some modes such as "trailing bit compliment" * base the padding on the last byte of plain text. *

    */ public int addPadding(byte[] in, int inOff); /** * return the number of pad bytes present in the block. * @exception InvalidCipherTextException if the padding is badly formed * or invalid. */ public int padCount(byte[] in) throws InvalidCipherTextException; } bouncycastle-1.49.orig/src/org/bouncycastle/crypto/paddings/ISO10126d2Padding.java0000644000175000017500000000317510262753175027235 0ustar ebourgebourgpackage org.bouncycastle.crypto.paddings; import java.security.SecureRandom; import org.bouncycastle.crypto.InvalidCipherTextException; /** * A padder that adds ISO10126-2 padding to a block. */ public class ISO10126d2Padding implements BlockCipherPadding { SecureRandom random; /** * Initialise the padder. * * @param random a SecureRandom if available. */ public void init(SecureRandom random) throws IllegalArgumentException { if (random != null) { this.random = random; } else { this.random = new SecureRandom(); } } /** * Return the name of the algorithm the padder implements. * * @return the name of the algorithm the padder implements. */ public String getPaddingName() { return "ISO10126-2"; } /** * add the pad bytes to the passed in block, returning the * number of bytes added. */ public int addPadding( byte[] in, int inOff) { byte code = (byte)(in.length - inOff); while (inOff < (in.length - 1)) { in[inOff] = (byte)random.nextInt(); inOff++; } in[inOff] = code; return code; } /** * return the number of pad bytes present in the block. */ public int padCount(byte[] in) throws InvalidCipherTextException { int count = in[in.length - 1] & 0xff; if (count > in.length) { throw new InvalidCipherTextException("pad block corrupted"); } return count; } } bouncycastle-1.49.orig/src/org/bouncycastle/crypto/paddings/PKCS7Padding.java0000644000175000017500000000321011013717032026563 0ustar ebourgebourgpackage org.bouncycastle.crypto.paddings; import java.security.SecureRandom; import org.bouncycastle.crypto.InvalidCipherTextException; /** * A padder that adds PKCS7/PKCS5 padding to a block. */ public class PKCS7Padding implements BlockCipherPadding { /** * Initialise the padder. * * @param random - a SecureRandom if available. */ public void init(SecureRandom random) throws IllegalArgumentException { // nothing to do. } /** * Return the name of the algorithm the padder implements. * * @return the name of the algorithm the padder implements. */ public String getPaddingName() { return "PKCS7"; } /** * add the pad bytes to the passed in block, returning the * number of bytes added. */ public int addPadding( byte[] in, int inOff) { byte code = (byte)(in.length - inOff); while (inOff < in.length) { in[inOff] = code; inOff++; } return code; } /** * return the number of pad bytes present in the block. */ public int padCount(byte[] in) throws InvalidCipherTextException { int count = in[in.length - 1] & 0xff; if (count > in.length || count == 0) { throw new InvalidCipherTextException("pad block corrupted"); } for (int i = 1; i <= count; i++) { if (in[in.length - i] != count) { throw new InvalidCipherTextException("pad block corrupted"); } } return count; } } bouncycastle-1.49.orig/src/org/bouncycastle/crypto/paddings/ZeroBytePadding.java0000644000175000017500000000267610262753175027533 0ustar ebourgebourgpackage org.bouncycastle.crypto.paddings; import java.security.SecureRandom; import org.bouncycastle.crypto.InvalidCipherTextException; /** * A padder that adds NULL byte padding to a block. */ public class ZeroBytePadding implements BlockCipherPadding { /** * Initialise the padder. * * @param random - a SecureRandom if available. */ public void init(SecureRandom random) throws IllegalArgumentException { // nothing to do. } /** * Return the name of the algorithm the padder implements. * * @return the name of the algorithm the padder implements. */ public String getPaddingName() { return "ZeroByte"; } /** * add the pad bytes to the passed in block, returning the * number of bytes added. */ public int addPadding( byte[] in, int inOff) { int added = (in.length - inOff); while (inOff < in.length) { in[inOff] = (byte) 0; inOff++; } return added; } /** * return the number of pad bytes present in the block. */ public int padCount(byte[] in) throws InvalidCipherTextException { int count = in.length; while (count > 0) { if (in[count - 1] != 0) { break; } count--; } return in.length - count; } } bouncycastle-1.49.orig/src/org/bouncycastle/crypto/paddings/package.html0000644000175000017500000000012010262753175026075 0ustar ebourgebourg Paddings for symmetric ciphers. bouncycastle-1.49.orig/src/org/bouncycastle/crypto/Wrapper.java0000644000175000017500000000074110262753175024317 0ustar ebourgebourgpackage org.bouncycastle.crypto; public interface Wrapper { public void init(boolean forWrapping, CipherParameters param); /** * Return the name of the algorithm the wrapper implements. * * @return the name of the algorithm the wrapper implements. */ public String getAlgorithmName(); public byte[] wrap(byte[] in, int inOff, int inLen); public byte[] unwrap(byte[] in, int inOff, int inLen) throws InvalidCipherTextException; } bouncycastle-1.49.orig/src/org/bouncycastle/crypto/tls/0000755000175000017500000000000012152033551022621 5ustar ebourgebourgbouncycastle-1.49.orig/src/org/bouncycastle/crypto/tls/TlsFatalAlert.java0000644000175000017500000000065312146535331026200 0ustar ebourgebourgpackage org.bouncycastle.crypto.tls; import java.io.IOException; public class TlsFatalAlert extends IOException { private static final long serialVersionUID = 3584313123679111168L; private short alertDescription; public TlsFatalAlert(short alertDescription) { this.alertDescription = alertDescription; } public short getAlertDescription() { return alertDescription; } } bouncycastle-1.49.orig/src/org/bouncycastle/crypto/tls/LegacyTlsClient.java0000644000175000017500000000111212146535331026513 0ustar ebourgebourgpackage org.bouncycastle.crypto.tls; import java.io.IOException; /** * A temporary class to use LegacyTlsAuthentication * * @deprecated */ public class LegacyTlsClient extends DefaultTlsClient { /** * @deprecated */ protected CertificateVerifyer verifyer; /** * @deprecated */ public LegacyTlsClient(CertificateVerifyer verifyer) { super(); this.verifyer = verifyer; } public TlsAuthentication getAuthentication() throws IOException { return new LegacyTlsAuthentication(verifyer); } } bouncycastle-1.49.orig/src/org/bouncycastle/crypto/tls/SupplementalDataEntry.java0000644000175000017500000000064512151551725027765 0ustar ebourgebourgpackage org.bouncycastle.crypto.tls; public class SupplementalDataEntry { private int supp_data_type; private byte[] data; public SupplementalDataEntry(int supp_data_type, byte[] data) { this.supp_data_type = supp_data_type; this.data = data; } public int getDataType() { return supp_data_type; } public byte[] getData() { return data; } } bouncycastle-1.49.orig/src/org/bouncycastle/crypto/tls/SecurityParameters.java0000644000175000017500000000174512151551725027335 0ustar ebourgebourgpackage org.bouncycastle.crypto.tls; public class SecurityParameters { int entity = -1; int prfAlgorithm = -1; short compressionAlgorithm = -1; int verifyDataLength = -1; byte[] masterSecret = null; byte[] clientRandom = null; byte[] serverRandom = null; /** * @return {@link ConnectionEnd} */ public int getEntity() { return entity; } /** * @return {@link PRFAlgorithm} */ public int getPrfAlgorithm() { return prfAlgorithm; } /** * @return {@link CompressionMethod} */ public short getCompressionAlgorithm() { return compressionAlgorithm; } public int getVerifyDataLength() { return verifyDataLength; } public byte[] getMasterSecret() { return masterSecret; } public byte[] getClientRandom() { return clientRandom; } public byte[] getServerRandom() { return serverRandom; } } bouncycastle-1.49.orig/src/org/bouncycastle/crypto/tls/TlsHandshakeHash.java0000644000175000017500000000034212151551725026647 0ustar ebourgebourgpackage org.bouncycastle.crypto.tls; import org.bouncycastle.crypto.Digest; interface TlsHandshakeHash extends Digest { void init(TlsContext context); TlsHandshakeHash commit(); TlsHandshakeHash fork(); } bouncycastle-1.49.orig/src/org/bouncycastle/crypto/tls/TlsNullCipher.java0000644000175000017500000000705312151551725026230 0ustar ebourgebourgpackage org.bouncycastle.crypto.tls; import java.io.IOException; import org.bouncycastle.crypto.Digest; import org.bouncycastle.util.Arrays; /** * A NULL CipherSuite with optional MAC */ public class TlsNullCipher implements TlsCipher { protected TlsContext context; protected TlsMac writeMac; protected TlsMac readMac; public TlsNullCipher(TlsContext context) { this.context = context; this.writeMac = null; this.readMac = null; } public TlsNullCipher(TlsContext context, Digest clientWriteDigest, Digest serverWriteDigest) throws IOException { if ((clientWriteDigest == null) != (serverWriteDigest == null)) { throw new TlsFatalAlert(AlertDescription.internal_error); } this.context = context; TlsMac clientWriteMac = null, serverWriteMac = null; if (clientWriteDigest != null) { int key_block_size = clientWriteDigest.getDigestSize() + serverWriteDigest.getDigestSize(); byte[] key_block = TlsUtils.calculateKeyBlock(context, key_block_size); int offset = 0; clientWriteMac = new TlsMac(context, clientWriteDigest, key_block, offset, clientWriteDigest.getDigestSize()); offset += clientWriteDigest.getDigestSize(); serverWriteMac = new TlsMac(context, serverWriteDigest, key_block, offset, serverWriteDigest.getDigestSize()); offset += serverWriteDigest.getDigestSize(); if (offset != key_block_size) { throw new TlsFatalAlert(AlertDescription.internal_error); } } if (context.isServer()) { writeMac = serverWriteMac; readMac = clientWriteMac; } else { writeMac = clientWriteMac; readMac = serverWriteMac; } } public int getPlaintextLimit(int ciphertextLimit) { int result = ciphertextLimit; if (writeMac != null) { result -= writeMac.getSize(); } return result; } public byte[] encodePlaintext(long seqNo, short type, byte[] plaintext, int offset, int len) throws IOException { if (writeMac == null) { return Arrays.copyOfRange(plaintext, offset, offset + len); } byte[] mac = writeMac.calculateMac(seqNo, type, plaintext, offset, len); byte[] ciphertext = new byte[len + mac.length]; System.arraycopy(plaintext, offset, ciphertext, 0, len); System.arraycopy(mac, 0, ciphertext, len, mac.length); return ciphertext; } public byte[] decodeCiphertext(long seqNo, short type, byte[] ciphertext, int offset, int len) throws IOException { if (readMac == null) { return Arrays.copyOfRange(ciphertext, offset, offset + len); } int macSize = readMac.getSize(); if (len < macSize) { throw new TlsFatalAlert(AlertDescription.decode_error); } int macInputLen = len - macSize; byte[] receivedMac = Arrays.copyOfRange(ciphertext, offset + macInputLen, offset + len); byte[] computedMac = readMac.calculateMac(seqNo, type, ciphertext, offset, macInputLen); if (!Arrays.constantTimeAreEqual(receivedMac, computedMac)) { throw new TlsFatalAlert(AlertDescription.bad_record_mac); } return Arrays.copyOfRange(ciphertext, offset, offset + macInputLen); } } bouncycastle-1.49.orig/src/org/bouncycastle/crypto/tls/TlsStreamCipher.java0000644000175000017500000001015612151551725026547 0ustar ebourgebourgpackage org.bouncycastle.crypto.tls; import java.io.IOException; import org.bouncycastle.crypto.CipherParameters; import org.bouncycastle.crypto.Digest; import org.bouncycastle.crypto.StreamCipher; import org.bouncycastle.crypto.params.KeyParameter; import org.bouncycastle.util.Arrays; public class TlsStreamCipher implements TlsCipher { protected TlsContext context; protected StreamCipher encryptCipher; protected StreamCipher decryptCipher; protected TlsMac writeMac; protected TlsMac readMac; public TlsStreamCipher(TlsContext context, StreamCipher clientWriteCipher, StreamCipher serverWriteCipher, Digest clientWriteDigest, Digest serverWriteDigest, int cipherKeySize) throws IOException { boolean isServer = context.isServer(); this.context = context; this.encryptCipher = clientWriteCipher; this.decryptCipher = serverWriteCipher; int key_block_size = (2 * cipherKeySize) + clientWriteDigest.getDigestSize() + serverWriteDigest.getDigestSize(); byte[] key_block = TlsUtils.calculateKeyBlock(context, key_block_size); int offset = 0; // Init MACs TlsMac clientWriteMac = new TlsMac(context, clientWriteDigest, key_block, offset, clientWriteDigest.getDigestSize()); offset += clientWriteDigest.getDigestSize(); TlsMac serverWriteMac = new TlsMac(context, serverWriteDigest, key_block, offset, serverWriteDigest.getDigestSize()); offset += serverWriteDigest.getDigestSize(); // Build keys KeyParameter clientWriteKey = new KeyParameter(key_block, offset, cipherKeySize); offset += cipherKeySize; KeyParameter serverWriteKey = new KeyParameter(key_block, offset, cipherKeySize); offset += cipherKeySize; if (offset != key_block_size) { throw new TlsFatalAlert(AlertDescription.internal_error); } CipherParameters encryptParams, decryptParams; if (isServer) { this.writeMac = serverWriteMac; this.readMac = clientWriteMac; this.encryptCipher = serverWriteCipher; this.decryptCipher = clientWriteCipher; encryptParams = serverWriteKey; decryptParams = clientWriteKey; } else { this.writeMac = clientWriteMac; this.readMac = serverWriteMac; this.encryptCipher = clientWriteCipher; this.decryptCipher = serverWriteCipher; encryptParams = clientWriteKey; decryptParams = serverWriteKey; } this.encryptCipher.init(true, encryptParams); this.decryptCipher.init(false, decryptParams); } public int getPlaintextLimit(int ciphertextLimit) { return ciphertextLimit - writeMac.getSize(); } public byte[] encodePlaintext(long seqNo, short type, byte[] plaintext, int offset, int len) { byte[] mac = writeMac.calculateMac(seqNo, type, plaintext, offset, len); byte[] outbuf = new byte[len + mac.length]; encryptCipher.processBytes(plaintext, offset, len, outbuf, 0); encryptCipher.processBytes(mac, 0, mac.length, outbuf, len); return outbuf; } public byte[] decodeCiphertext(long seqNo, short type, byte[] ciphertext, int offset, int len) throws IOException { int macSize = readMac.getSize(); if (len < macSize) { throw new TlsFatalAlert(AlertDescription.decode_error); } byte[] deciphered = new byte[len]; decryptCipher.processBytes(ciphertext, offset, len, deciphered, 0); int macInputLen = len - macSize; byte[] receivedMac = Arrays.copyOfRange(deciphered, macInputLen, len); byte[] computedMac = readMac.calculateMac(seqNo, type, deciphered, 0, macInputLen); if (!Arrays.constantTimeAreEqual(receivedMac, computedMac)) { throw new TlsFatalAlert(AlertDescription.bad_record_mac); } return Arrays.copyOfRange(deciphered, 0, macInputLen); } } bouncycastle-1.49.orig/src/org/bouncycastle/crypto/tls/DTLSProtocol.java0000644000175000017500000000506312151551725025767 0ustar ebourgebourgpackage org.bouncycastle.crypto.tls; import java.io.ByteArrayInputStream; import java.io.ByteArrayOutputStream; import java.io.IOException; import java.security.SecureRandom; import java.util.Vector; import org.bouncycastle.util.Arrays; public abstract class DTLSProtocol { protected final SecureRandom secureRandom; protected DTLSProtocol(SecureRandom secureRandom) { if (secureRandom == null) { throw new IllegalArgumentException("'secureRandom' cannot be null"); } this.secureRandom = secureRandom; } protected void processFinished(byte[] body, byte[] expected_verify_data) throws IOException { ByteArrayInputStream buf = new ByteArrayInputStream(body); byte[] verify_data = TlsUtils.readFully(expected_verify_data.length, buf); TlsProtocol.assertEmpty(buf); if (!Arrays.constantTimeAreEqual(expected_verify_data, verify_data)) { throw new TlsFatalAlert(AlertDescription.handshake_failure); } } protected static byte[] generateCertificate(Certificate certificate) throws IOException { ByteArrayOutputStream buf = new ByteArrayOutputStream(); certificate.encode(buf); return buf.toByteArray(); } protected static byte[] generateSupplementalData(Vector supplementalData) throws IOException { ByteArrayOutputStream buf = new ByteArrayOutputStream(); TlsProtocol.writeSupplementalData(buf, supplementalData); return buf.toByteArray(); } protected static void validateSelectedCipherSuite(int selectedCipherSuite, short alertDescription) throws IOException { switch (selectedCipherSuite) { case CipherSuite.TLS_RSA_EXPORT_WITH_RC4_40_MD5: case CipherSuite.TLS_RSA_WITH_RC4_128_MD5: case CipherSuite.TLS_RSA_WITH_RC4_128_SHA: case CipherSuite.TLS_DH_anon_EXPORT_WITH_RC4_40_MD5: case CipherSuite.TLS_DH_anon_WITH_RC4_128_MD5: case CipherSuite.TLS_PSK_WITH_RC4_128_SHA: case CipherSuite.TLS_DHE_PSK_WITH_RC4_128_SHA: case CipherSuite.TLS_RSA_PSK_WITH_RC4_128_SHA: case CipherSuite.TLS_ECDH_ECDSA_WITH_RC4_128_SHA: case CipherSuite.TLS_ECDHE_ECDSA_WITH_RC4_128_SHA: case CipherSuite.TLS_ECDH_RSA_WITH_RC4_128_SHA: case CipherSuite.TLS_ECDHE_RSA_WITH_RC4_128_SHA: case CipherSuite.TLS_ECDH_anon_WITH_RC4_128_SHA: // TODO Alert throw new IllegalStateException("RC4 MUST NOT be used with DTLS"); } } } bouncycastle-1.49.orig/src/org/bouncycastle/crypto/tls/TlsRSAUtils.java0000644000175000017500000000347012151551725025630 0ustar ebourgebourgpackage org.bouncycastle.crypto.tls; import java.io.IOException; import java.io.OutputStream; import org.bouncycastle.crypto.InvalidCipherTextException; import org.bouncycastle.crypto.encodings.PKCS1Encoding; import org.bouncycastle.crypto.engines.RSABlindedEngine; import org.bouncycastle.crypto.params.ParametersWithRandom; import org.bouncycastle.crypto.params.RSAKeyParameters; public class TlsRSAUtils { public static byte[] generateEncryptedPreMasterSecret(TlsContext context, RSAKeyParameters rsaServerPublicKey, OutputStream output) throws IOException { /* * Choose a PremasterSecret and send it encrypted to the server */ byte[] premasterSecret = new byte[48]; context.getSecureRandom().nextBytes(premasterSecret); TlsUtils.writeVersion(context.getClientVersion(), premasterSecret, 0); PKCS1Encoding encoding = new PKCS1Encoding(new RSABlindedEngine()); encoding.init(true, new ParametersWithRandom(rsaServerPublicKey, context.getSecureRandom())); try { byte[] encryptedPreMasterSecret = encoding.processBlock(premasterSecret, 0, premasterSecret.length); if (context.getServerVersion().isSSL()) { // TODO Do any SSLv3 servers actually expect the length? output.write(encryptedPreMasterSecret); } else { TlsUtils.writeOpaque16(encryptedPreMasterSecret, output); } } catch (InvalidCipherTextException e) { /* * This should never happen, only during decryption. */ throw new TlsFatalAlert(AlertDescription.internal_error); } return premasterSecret; } } bouncycastle-1.49.orig/src/org/bouncycastle/crypto/tls/ExtensionType.java0000644000175000017500000000203112151551725026305 0ustar ebourgebourgpackage org.bouncycastle.crypto.tls; public class ExtensionType { /* * RFC 6066 1.1. */ public static final int server_name = 0; public static final int max_fragment_length = 1; public static final int client_certificate_url = 2; public static final int trusted_ca_keys = 3; public static final int truncated_hmac = 4; public static final int status_request = 5; /* * RFC 4681 */ public static final int user_mapping = 6; /* * RFC 4492 5.1. */ public static final int elliptic_curves = 10; public static final int ec_point_formats = 11; /* * RFC 5054 2.8.1. */ public static final int srp = 12; /* * RFC 5077 7. */ public static final int session_ticket = 35; /* * RFC 5246 7.4.1.4. */ public static final int signature_algorithms = 13; /* * RFC 5764 9. */ public static final int use_srtp = 14; /* * RFC 5746 3.2. */ public static final int renegotiation_info = 0xff01; } bouncycastle-1.49.orig/src/org/bouncycastle/crypto/tls/TlsECCUtils.java0000644000175000017500000005477712151551725025615 0ustar ebourgebourgpackage org.bouncycastle.crypto.tls; import java.io.ByteArrayInputStream; import java.io.ByteArrayOutputStream; import java.io.IOException; import java.io.InputStream; import java.io.OutputStream; import java.math.BigInteger; import java.security.SecureRandom; import java.util.Hashtable; import org.bouncycastle.asn1.sec.SECNamedCurves; import org.bouncycastle.asn1.x9.X9ECParameters; import org.bouncycastle.crypto.AsymmetricCipherKeyPair; import org.bouncycastle.crypto.agreement.ECDHBasicAgreement; import org.bouncycastle.crypto.generators.ECKeyPairGenerator; import org.bouncycastle.crypto.params.ECDomainParameters; import org.bouncycastle.crypto.params.ECKeyGenerationParameters; import org.bouncycastle.crypto.params.ECPrivateKeyParameters; import org.bouncycastle.crypto.params.ECPublicKeyParameters; import org.bouncycastle.math.ec.ECCurve; import org.bouncycastle.math.ec.ECPoint; import org.bouncycastle.util.BigIntegers; import org.bouncycastle.util.Integers; public class TlsECCUtils { public static final Integer EXT_elliptic_curves = Integers.valueOf(ExtensionType.elliptic_curves); public static final Integer EXT_ec_point_formats = Integers.valueOf(ExtensionType.ec_point_formats); private static final String[] curveNames = new String[]{"sect163k1", "sect163r1", "sect163r2", "sect193r1", "sect193r2", "sect233k1", "sect233r1", "sect239k1", "sect283k1", "sect283r1", "sect409k1", "sect409r1", "sect571k1", "sect571r1", "secp160k1", "secp160r1", "secp160r2", "secp192k1", "secp192r1", "secp224k1", "secp224r1", "secp256k1", "secp256r1", "secp384r1", "secp521r1",}; public static void addSupportedEllipticCurvesExtension(Hashtable extensions, int[] namedCurves) throws IOException { extensions.put(EXT_elliptic_curves, createSupportedEllipticCurvesExtension(namedCurves)); } public static void addSupportedPointFormatsExtension(Hashtable extensions, short[] ecPointFormats) throws IOException { extensions.put(EXT_ec_point_formats, createSupportedPointFormatsExtension(ecPointFormats)); } public static int[] getSupportedEllipticCurvesExtension(Hashtable extensions) throws IOException { if (extensions == null) { return null; } byte[] extensionValue = (byte[])extensions.get(EXT_elliptic_curves); if (extensionValue == null) { return null; } return readSupportedEllipticCurvesExtension(extensionValue); } public static short[] getSupportedPointFormatsExtension(Hashtable extensions) throws IOException { if (extensions == null) { return null; } byte[] extensionValue = (byte[])extensions.get(EXT_ec_point_formats); if (extensionValue == null) { return null; } return readSupportedPointFormatsExtension(extensionValue); } public static byte[] createSupportedEllipticCurvesExtension(int[] namedCurves) throws IOException { if (namedCurves == null || namedCurves.length < 1) { throw new TlsFatalAlert(AlertDescription.internal_error); } ByteArrayOutputStream buf = new ByteArrayOutputStream(); TlsUtils.writeUint16(2 * namedCurves.length, buf); TlsUtils.writeUint16Array(namedCurves, buf); return buf.toByteArray(); } public static byte[] createSupportedPointFormatsExtension(short[] ecPointFormats) throws IOException { if (ecPointFormats == null) { ecPointFormats = new short[]{ECPointFormat.uncompressed}; } else if (!TlsProtocol.arrayContains(ecPointFormats, ECPointFormat.uncompressed)) { /* * RFC 4492 5.1. If the Supported Point Formats Extension is indeed sent, it MUST * contain the value 0 (uncompressed) as one of the items in the list of point formats. */ // NOTE: We add it at the end (lowest preference) short[] tmp = new short[ecPointFormats.length + 1]; System.arraycopy(ecPointFormats, 0, tmp, 0, ecPointFormats.length); tmp[ecPointFormats.length] = ECPointFormat.uncompressed; ecPointFormats = tmp; } ByteArrayOutputStream buf = new ByteArrayOutputStream(); TlsUtils.writeUint8((short)ecPointFormats.length, buf); TlsUtils.writeUint8Array(ecPointFormats, buf); return buf.toByteArray(); } public static int[] readSupportedEllipticCurvesExtension(byte[] extensionValue) throws IOException { if (extensionValue == null) { throw new IllegalArgumentException("'extensionValue' cannot be null"); } ByteArrayInputStream buf = new ByteArrayInputStream(extensionValue); int length = TlsUtils.readUint16(buf); if (length < 2 || (length & 1) != 0) { throw new TlsFatalAlert(AlertDescription.decode_error); } int[] namedCurves = TlsUtils.readUint16Array(length / 2, buf); TlsProtocol.assertEmpty(buf); return namedCurves; } public static short[] readSupportedPointFormatsExtension(byte[] extensionValue) throws IOException { if (extensionValue == null) { throw new IllegalArgumentException("'extensionValue' cannot be null"); } ByteArrayInputStream buf = new ByteArrayInputStream(extensionValue); short length = TlsUtils.readUint8(buf); if (length < 1) { throw new TlsFatalAlert(AlertDescription.decode_error); } short[] ecPointFormats = TlsUtils.readUint8Array(length, buf); TlsProtocol.assertEmpty(buf); if (!TlsProtocol.arrayContains(ecPointFormats, ECPointFormat.uncompressed)) { /* * RFC 4492 5.1. If the Supported Point Formats Extension is indeed sent, it MUST * contain the value 0 (uncompressed) as one of the items in the list of point formats. */ throw new TlsFatalAlert(AlertDescription.illegal_parameter); } return ecPointFormats; } public static String getNameOfNamedCurve(int namedCurve) { return isSupportedNamedCurve(namedCurve) ? curveNames[namedCurve - 1] : null; } public static ECDomainParameters getParametersForNamedCurve(int namedCurve) { String curveName = getNameOfNamedCurve(namedCurve); if (curveName == null) { return null; } // Lazily created the first time a particular curve is accessed X9ECParameters ecP = SECNamedCurves.getByName(curveName); if (ecP == null) { return null; } // It's a bit inefficient to do this conversion every time return new ECDomainParameters(ecP.getCurve(), ecP.getG(), ecP.getN(), ecP.getH(), ecP.getSeed()); } public static boolean hasAnySupportedNamedCurves() { return curveNames.length > 0; } public static boolean containsECCCipherSuites(int[] cipherSuites) { for (int i = 0; i < cipherSuites.length; ++i) { if (isECCCipherSuite(cipherSuites[i])) { return true; } } return false; } public static boolean isECCCipherSuite(int cipherSuite) { switch (cipherSuite) { case CipherSuite.TLS_ECDH_ECDSA_WITH_NULL_SHA: case CipherSuite.TLS_ECDH_ECDSA_WITH_RC4_128_SHA: case CipherSuite.TLS_ECDH_ECDSA_WITH_3DES_EDE_CBC_SHA: case CipherSuite.TLS_ECDH_ECDSA_WITH_AES_128_CBC_SHA: case CipherSuite.TLS_ECDH_ECDSA_WITH_AES_256_CBC_SHA: case CipherSuite.TLS_ECDHE_ECDSA_WITH_NULL_SHA: case CipherSuite.TLS_ECDHE_ECDSA_WITH_RC4_128_SHA: case CipherSuite.TLS_ECDHE_ECDSA_WITH_3DES_EDE_CBC_SHA: case CipherSuite.TLS_ECDHE_ECDSA_WITH_AES_128_CBC_SHA: case CipherSuite.TLS_ECDHE_ECDSA_WITH_AES_256_CBC_SHA: case CipherSuite.TLS_ECDH_RSA_WITH_NULL_SHA: case CipherSuite.TLS_ECDH_RSA_WITH_RC4_128_SHA: case CipherSuite.TLS_ECDH_RSA_WITH_3DES_EDE_CBC_SHA: case CipherSuite.TLS_ECDH_RSA_WITH_AES_128_CBC_SHA: case CipherSuite.TLS_ECDH_RSA_WITH_AES_256_CBC_SHA: case CipherSuite.TLS_ECDHE_RSA_WITH_NULL_SHA: case CipherSuite.TLS_ECDHE_RSA_WITH_RC4_128_SHA: case CipherSuite.TLS_ECDHE_RSA_WITH_3DES_EDE_CBC_SHA: case CipherSuite.TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA: case CipherSuite.TLS_ECDHE_RSA_WITH_AES_256_CBC_SHA: case CipherSuite.TLS_ECDH_anon_WITH_NULL_SHA: case CipherSuite.TLS_ECDH_anon_WITH_RC4_128_SHA: case CipherSuite.TLS_ECDH_anon_WITH_3DES_EDE_CBC_SHA: case CipherSuite.TLS_ECDH_anon_WITH_AES_128_CBC_SHA: case CipherSuite.TLS_ECDH_anon_WITH_AES_256_CBC_SHA: case CipherSuite.TLS_ECDHE_ECDSA_WITH_AES_128_CBC_SHA256: case CipherSuite.TLS_ECDHE_ECDSA_WITH_AES_256_CBC_SHA384: case CipherSuite.TLS_ECDH_ECDSA_WITH_AES_128_CBC_SHA256: case CipherSuite.TLS_ECDH_ECDSA_WITH_AES_256_CBC_SHA384: case CipherSuite.TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA256: case CipherSuite.TLS_ECDHE_RSA_WITH_AES_256_CBC_SHA384: case CipherSuite.TLS_ECDH_RSA_WITH_AES_128_CBC_SHA256: case CipherSuite.TLS_ECDH_RSA_WITH_AES_256_CBC_SHA384: case CipherSuite.TLS_ECDHE_ECDSA_WITH_AES_128_GCM_SHA256: case CipherSuite.TLS_ECDHE_ECDSA_WITH_AES_256_GCM_SHA384: case CipherSuite.TLS_ECDH_ECDSA_WITH_AES_128_GCM_SHA256: case CipherSuite.TLS_ECDH_ECDSA_WITH_AES_256_GCM_SHA384: case CipherSuite.TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256: case CipherSuite.TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384: case CipherSuite.TLS_ECDH_RSA_WITH_AES_128_GCM_SHA256: case CipherSuite.TLS_ECDH_RSA_WITH_AES_256_GCM_SHA384: return true; default: return false; } } public static boolean areOnSameCurve(ECDomainParameters a, ECDomainParameters b) { // TODO Move to ECDomainParameters.equals() or other utility method? return a.getCurve().equals(b.getCurve()) && a.getG().equals(b.getG()) && a.getN().equals(b.getN()) && a.getH().equals(b.getH()); } public static boolean isSupportedNamedCurve(int namedCurve) { return (namedCurve > 0 && namedCurve <= curveNames.length); } public static boolean isCompressionPreferred(short[] ecPointFormats, short compressionFormat) { if (ecPointFormats == null) { return false; } for (int i = 0; i < ecPointFormats.length; ++i) { short ecPointFormat = ecPointFormats[i]; if (ecPointFormat == ECPointFormat.uncompressed) { return false; } if (ecPointFormat == compressionFormat) { return true; } } return false; } public static byte[] serializeECFieldElement(int fieldSize, BigInteger x) throws IOException { int requiredLength = (fieldSize + 7) / 8; return BigIntegers.asUnsignedByteArray(requiredLength, x); } public static byte[] serializeECPoint(short[] ecPointFormats, ECPoint point) throws IOException { ECCurve curve = point.getCurve(); /* * RFC 4492 5.7. ...an elliptic curve point in uncompressed or compressed format. Here, the * format MUST conform to what the server has requested through a Supported Point Formats * Extension if this extension was used, and MUST be uncompressed if this extension was not * used. */ boolean compressed = false; if (curve instanceof ECCurve.F2m) { compressed = isCompressionPreferred(ecPointFormats, ECPointFormat.ansiX962_compressed_char2); } else if (curve instanceof ECCurve.Fp) { compressed = isCompressionPreferred(ecPointFormats, ECPointFormat.ansiX962_compressed_prime); } return point.getEncoded(compressed); } public static byte[] serializeECPublicKey(short[] ecPointFormats, ECPublicKeyParameters keyParameters) throws IOException { return serializeECPoint(ecPointFormats, keyParameters.getQ()); } public static BigInteger deserializeECFieldElement(int fieldSize, byte[] encoding) throws IOException { int requiredLength = (fieldSize + 7) / 8; if (encoding.length != requiredLength) { throw new TlsFatalAlert(AlertDescription.decode_error); } return new BigInteger(1, encoding); } public static ECPoint deserializeECPoint(short[] ecPointFormats, ECCurve curve, byte[] encoding) throws IOException { /* * NOTE: Here we implicitly decode compressed or uncompressed encodings. DefaultTlsClient by * default is set up to advertise that we can parse any encoding so this works fine, but * extra checks might be needed here if that were changed. */ return curve.decodePoint(encoding); } public static ECPublicKeyParameters deserializeECPublicKey(short[] ecPointFormats, ECDomainParameters curve_params, byte[] encoding) throws IOException { try { ECPoint Y = deserializeECPoint(ecPointFormats, curve_params.getCurve(), encoding); return new ECPublicKeyParameters(Y, curve_params); } catch (RuntimeException e) { throw new TlsFatalAlert(AlertDescription.illegal_parameter); } } public static byte[] calculateECDHBasicAgreement(ECPublicKeyParameters publicKey, ECPrivateKeyParameters privateKey) { ECDHBasicAgreement basicAgreement = new ECDHBasicAgreement(); basicAgreement.init(privateKey); BigInteger agreementValue = basicAgreement.calculateAgreement(publicKey); /* * RFC 4492 5.10. Note that this octet string (Z in IEEE 1363 terminology) as output by * FE2OSP, the Field Element to Octet String Conversion Primitive, has constant length for * any given field; leading zeros found in this octet string MUST NOT be truncated. */ return BigIntegers.asUnsignedByteArray(basicAgreement.getFieldSize(), agreementValue); } public static AsymmetricCipherKeyPair generateECKeyPair(SecureRandom random, ECDomainParameters ecParams) { ECKeyPairGenerator keyPairGenerator = new ECKeyPairGenerator(); ECKeyGenerationParameters keyGenerationParameters = new ECKeyGenerationParameters(ecParams, random); keyPairGenerator.init(keyGenerationParameters); return keyPairGenerator.generateKeyPair(); } public static ECPublicKeyParameters validateECPublicKey(ECPublicKeyParameters key) throws IOException { // TODO Check RFC 4492 for validation return key; } public static int readECExponent(int fieldSize, InputStream input) throws IOException { BigInteger K = readECParameter(input); if (K.bitLength() < 32) { int k = K.intValue(); if (k > 0 && k < fieldSize) { return k; } } throw new TlsFatalAlert(AlertDescription.illegal_parameter); } public static BigInteger readECFieldElement(int fieldSize, InputStream input) throws IOException { return deserializeECFieldElement(fieldSize, TlsUtils.readOpaque8(input)); } public static BigInteger readECParameter(InputStream input) throws IOException { // TODO Are leading zeroes okay here? return new BigInteger(1, TlsUtils.readOpaque8(input)); } public static ECDomainParameters readECParameters(int[] namedCurves, short[] ecPointFormats, InputStream input) throws IOException { try { short curveType = TlsUtils.readUint8(input); switch (curveType) { case ECCurveType.explicit_prime: { BigInteger prime_p = readECParameter(input); BigInteger a = readECFieldElement(prime_p.bitLength(), input); BigInteger b = readECFieldElement(prime_p.bitLength(), input); ECCurve curve = new ECCurve.Fp(prime_p, a, b); ECPoint base = deserializeECPoint(ecPointFormats, curve, TlsUtils.readOpaque8(input)); BigInteger order = readECParameter(input); BigInteger cofactor = readECParameter(input); return new ECDomainParameters(curve, base, order, cofactor); } case ECCurveType.explicit_char2: { int m = TlsUtils.readUint16(input); short basis = TlsUtils.readUint8(input); ECCurve curve; switch (basis) { case ECBasisType.ec_basis_trinomial: { int k = readECExponent(m, input); BigInteger a = readECFieldElement(m, input); BigInteger b = readECFieldElement(m, input); curve = new ECCurve.F2m(m, k, a, b); break; } case ECBasisType.ec_basis_pentanomial: { int k1 = readECExponent(m, input); int k2 = readECExponent(m, input); int k3 = readECExponent(m, input); BigInteger a = readECFieldElement(m, input); BigInteger b = readECFieldElement(m, input); curve = new ECCurve.F2m(m, k1, k2, k3, a, b); break; } default: throw new TlsFatalAlert(AlertDescription.illegal_parameter); } ECPoint base = deserializeECPoint(ecPointFormats, curve, TlsUtils.readOpaque8(input)); BigInteger order = readECParameter(input); BigInteger cofactor = readECParameter(input); return new ECDomainParameters(curve, base, order, cofactor); } case ECCurveType.named_curve: { int namedCurve = TlsUtils.readUint16(input); if (!NamedCurve.refersToASpecificNamedCurve(namedCurve)) { /* * RFC 4492 5.4. All those values of NamedCurve are allowed that refer to a * specific curve. Values of NamedCurve that indicate support for a class of * explicitly defined curves are not allowed here [...]. */ throw new TlsFatalAlert(AlertDescription.illegal_parameter); } if (!TlsProtocol.arrayContains(namedCurves, namedCurve)) { /* * RFC 4492 4. [...] servers MUST NOT negotiate the use of an ECC cipher suite * unless they can complete the handshake while respecting the choice of curves * and compression techniques specified by the client. */ throw new TlsFatalAlert(AlertDescription.illegal_parameter); } return TlsECCUtils.getParametersForNamedCurve(namedCurve); } default: throw new TlsFatalAlert(AlertDescription.illegal_parameter); } } catch (RuntimeException e) { throw new TlsFatalAlert(AlertDescription.illegal_parameter); } } public static void writeECExponent(int k, OutputStream output) throws IOException { BigInteger K = BigInteger.valueOf(k); writeECParameter(K, output); } public static void writeECFieldElement(int fieldSize, BigInteger x, OutputStream output) throws IOException { TlsUtils.writeOpaque8(serializeECFieldElement(fieldSize, x), output); } public static void writeECParameter(BigInteger x, OutputStream output) throws IOException { TlsUtils.writeOpaque8(BigIntegers.asUnsignedByteArray(x), output); } public static void writeExplicitECParameters(short[] ecPointFormats, ECDomainParameters ecParameters, OutputStream output) throws IOException { ECCurve curve = ecParameters.getCurve(); if (curve instanceof ECCurve.Fp) { TlsUtils.writeUint8(ECCurveType.explicit_prime, output); ECCurve.Fp fp = (ECCurve.Fp)curve; writeECParameter(fp.getQ(), output); } else if (curve instanceof ECCurve.F2m) { TlsUtils.writeUint8(ECCurveType.explicit_char2, output); ECCurve.F2m f2m = (ECCurve.F2m)curve; TlsUtils.writeUint16(f2m.getM(), output); if (f2m.isTrinomial()) { TlsUtils.writeUint8(ECBasisType.ec_basis_trinomial, output); writeECExponent(f2m.getK1(), output); } else { TlsUtils.writeUint8(ECBasisType.ec_basis_pentanomial, output); writeECExponent(f2m.getK1(), output); writeECExponent(f2m.getK2(), output); writeECExponent(f2m.getK3(), output); } } else { throw new IllegalArgumentException("'ecParameters' not a known curve type"); } writeECFieldElement(curve.getFieldSize(), curve.getA().toBigInteger(), output); writeECFieldElement(curve.getFieldSize(), curve.getB().toBigInteger(), output); TlsUtils.writeOpaque8(serializeECPoint(ecPointFormats, ecParameters.getG()), output); writeECParameter(ecParameters.getN(), output); writeECParameter(ecParameters.getH(), output); } public static void writeNamedECParameters(int namedCurve, OutputStream output) throws IOException { if (!NamedCurve.refersToASpecificNamedCurve(namedCurve)) { /* * RFC 4492 5.4. All those values of NamedCurve are allowed that refer to a specific * curve. Values of NamedCurve that indicate support for a class of explicitly defined * curves are not allowed here [...]. */ throw new TlsFatalAlert(AlertDescription.internal_error); } TlsUtils.writeUint8(ECCurveType.named_curve, output); TlsUtils.writeUint16(namedCurve, output); } } bouncycastle-1.49.orig/src/org/bouncycastle/crypto/tls/ClientCertificateType.java0000644000175000017500000000123312151551725027715 0ustar ebourgebourgpackage org.bouncycastle.crypto.tls; public class ClientCertificateType { /* * RFC 4346 7.4.4 */ public static final short rsa_sign = 1; public static final short dss_sign = 2; public static final short rsa_fixed_dh = 3; public static final short dss_fixed_dh = 4; public static final short rsa_ephemeral_dh_RESERVED = 5; public static final short dss_ephemeral_dh_RESERVED = 6; public static final short fortezza_dms_RESERVED = 20; /* * RFC 4492 5.5 */ public static final short ecdsa_sign = 64; public static final short rsa_fixed_ecdh = 65; public static final short ecdsa_fixed_ecdh = 66; } bouncycastle-1.49.orig/src/org/bouncycastle/crypto/tls/DTLSHandshakeRetransmit.java0000644000175000017500000000031712151551725030122 0ustar ebourgebourgpackage org.bouncycastle.crypto.tls; import java.io.IOException; interface DTLSHandshakeRetransmit { void receivedHandshakeRecord(int epoch, byte[] buf, int off, int len) throws IOException; } bouncycastle-1.49.orig/src/org/bouncycastle/crypto/tls/TlsCredentials.java0000644000175000017500000000015412146534067026417 0ustar ebourgebourgpackage org.bouncycastle.crypto.tls; public interface TlsCredentials { Certificate getCertificate(); } bouncycastle-1.49.orig/src/org/bouncycastle/crypto/tls/TlsSRTPUtils.java0000644000175000017500000000461412151551725025774 0ustar ebourgebourgpackage org.bouncycastle.crypto.tls; import java.io.ByteArrayInputStream; import java.io.ByteArrayOutputStream; import java.io.IOException; import java.util.Hashtable; import org.bouncycastle.util.Integers; /** * RFC 5764 DTLS Extension to Establish Keys for SRTP. */ public class TlsSRTPUtils { public static final Integer EXT_use_srtp = Integers.valueOf(ExtensionType.use_srtp); public static void addUseSRTPExtension(Hashtable extensions, UseSRTPData useSRTPData) throws IOException { extensions.put(EXT_use_srtp, createUseSRTPExtension(useSRTPData)); } public static UseSRTPData getUseSRTPExtension(Hashtable extensions) throws IOException { if (extensions == null) { return null; } byte[] extensionValue = (byte[])extensions.get(EXT_use_srtp); if (extensionValue == null) { return null; } return readUseSRTPExtension(extensionValue); } public static byte[] createUseSRTPExtension(UseSRTPData useSRTPData) throws IOException { if (useSRTPData == null) { throw new IllegalArgumentException("'useSRTPData' cannot be null"); } ByteArrayOutputStream buf = new ByteArrayOutputStream(); // SRTPProtectionProfiles int[] protectionProfiles = useSRTPData.getProtectionProfiles(); TlsUtils.writeUint16(2 * protectionProfiles.length, buf); TlsUtils.writeUint16Array(protectionProfiles, buf); // srtp_mki TlsUtils.writeOpaque8(useSRTPData.getMki(), buf); return buf.toByteArray(); } public static UseSRTPData readUseSRTPExtension(byte[] extensionValue) throws IOException { if (extensionValue == null) { throw new IllegalArgumentException("'extensionValue' cannot be null"); } ByteArrayInputStream buf = new ByteArrayInputStream(extensionValue); // SRTPProtectionProfiles int length = TlsUtils.readUint16(buf); if (length < 2 || (length & 1) != 0) { throw new TlsFatalAlert(AlertDescription.decode_error); } int[] protectionProfiles = TlsUtils.readUint16Array(length / 2, buf); // srtp_mki byte[] mki = TlsUtils.readOpaque8(buf); TlsProtocol.assertEmpty(buf); return new UseSRTPData(protectionProfiles, mki); } } bouncycastle-1.49.orig/src/org/bouncycastle/crypto/tls/TlsBlockCipher.java0000644000175000017500000002333612151551725026352 0ustar ebourgebourgpackage org.bouncycastle.crypto.tls; import java.io.IOException; import java.security.SecureRandom; import org.bouncycastle.crypto.BlockCipher; import org.bouncycastle.crypto.CipherParameters; import org.bouncycastle.crypto.Digest; import org.bouncycastle.crypto.params.KeyParameter; import org.bouncycastle.crypto.params.ParametersWithIV; import org.bouncycastle.util.Arrays; /** * A generic TLS 1.0-1.1 / SSLv3 block cipher. This can be used for AES or 3DES for example. */ public class TlsBlockCipher implements TlsCipher { protected TlsContext context; protected byte[] randomData; protected boolean useExplicitIV; protected BlockCipher encryptCipher; protected BlockCipher decryptCipher; protected TlsMac writeMac; protected TlsMac readMac; public TlsMac getWriteMac() { return writeMac; } public TlsMac getReadMac() { return readMac; } public TlsBlockCipher(TlsContext context, BlockCipher clientWriteCipher, BlockCipher serverWriteCipher, Digest clientWriteDigest, Digest serverWriteDigest, int cipherKeySize) throws IOException { this.context = context; this.randomData = new byte[256]; context.getSecureRandom().nextBytes(randomData); this.useExplicitIV = ProtocolVersion.TLSv11.isEqualOrEarlierVersionOf(context.getServerVersion() .getEquivalentTLSVersion()); int key_block_size = (2 * cipherKeySize) + clientWriteDigest.getDigestSize() + serverWriteDigest.getDigestSize(); // From TLS 1.1 onwards, block ciphers don't need client_write_IV if (!useExplicitIV) { key_block_size += clientWriteCipher.getBlockSize() + serverWriteCipher.getBlockSize(); } byte[] key_block = TlsUtils.calculateKeyBlock(context, key_block_size); int offset = 0; TlsMac clientWriteMac = new TlsMac(context, clientWriteDigest, key_block, offset, clientWriteDigest.getDigestSize()); offset += clientWriteDigest.getDigestSize(); TlsMac serverWriteMac = new TlsMac(context, serverWriteDigest, key_block, offset, serverWriteDigest.getDigestSize()); offset += serverWriteDigest.getDigestSize(); KeyParameter client_write_key = new KeyParameter(key_block, offset, cipherKeySize); offset += cipherKeySize; KeyParameter server_write_key = new KeyParameter(key_block, offset, cipherKeySize); offset += cipherKeySize; byte[] client_write_IV, server_write_IV; if (useExplicitIV) { client_write_IV = new byte[clientWriteCipher.getBlockSize()]; server_write_IV = new byte[serverWriteCipher.getBlockSize()]; } else { client_write_IV = Arrays.copyOfRange(key_block, offset, offset + clientWriteCipher.getBlockSize()); offset += clientWriteCipher.getBlockSize(); server_write_IV = Arrays.copyOfRange(key_block, offset, offset + serverWriteCipher.getBlockSize()); offset += serverWriteCipher.getBlockSize(); } if (offset != key_block_size) { throw new TlsFatalAlert(AlertDescription.internal_error); } CipherParameters encryptParams, decryptParams; if (context.isServer()) { this.writeMac = serverWriteMac; this.readMac = clientWriteMac; this.encryptCipher = serverWriteCipher; this.decryptCipher = clientWriteCipher; encryptParams = new ParametersWithIV(server_write_key, server_write_IV); decryptParams = new ParametersWithIV(client_write_key, client_write_IV); } else { this.writeMac = clientWriteMac; this.readMac = serverWriteMac; this.encryptCipher = clientWriteCipher; this.decryptCipher = serverWriteCipher; encryptParams = new ParametersWithIV(client_write_key, client_write_IV); decryptParams = new ParametersWithIV(server_write_key, server_write_IV); } this.encryptCipher.init(true, encryptParams); this.decryptCipher.init(false, decryptParams); } public int getPlaintextLimit(int ciphertextLimit) { int blockSize = encryptCipher.getBlockSize(); int macSize = writeMac.getSize(); int result = ciphertextLimit - (ciphertextLimit % blockSize) - macSize - 1; if (useExplicitIV) { result -= blockSize; } return result; } public byte[] encodePlaintext(long seqNo, short type, byte[] plaintext, int offset, int len) { int blockSize = encryptCipher.getBlockSize(); int macSize = writeMac.getSize(); ProtocolVersion version = context.getServerVersion(); int padding_length = blockSize - 1 - ((len + macSize) % blockSize); // TODO[DTLS] Consider supporting in DTLS (without exceeding send limit though) if (!version.isDTLS() && !version.isSSL()) { // Add a random number of extra blocks worth of padding int maxExtraPadBlocks = (255 - padding_length) / blockSize; int actualExtraPadBlocks = chooseExtraPadBlocks(context.getSecureRandom(), maxExtraPadBlocks); padding_length += actualExtraPadBlocks * blockSize; } int totalSize = len + macSize + padding_length + 1; if (useExplicitIV) { totalSize += blockSize; } byte[] outbuf = new byte[totalSize]; int outOff = 0; if (useExplicitIV) { byte[] explicitIV = new byte[blockSize]; context.getSecureRandom().nextBytes(explicitIV); encryptCipher.init(true, new ParametersWithIV(null, explicitIV)); System.arraycopy(explicitIV, 0, outbuf, outOff, blockSize); outOff += blockSize; } byte[] mac = writeMac.calculateMac(seqNo, type, plaintext, offset, len); System.arraycopy(plaintext, offset, outbuf, outOff, len); System.arraycopy(mac, 0, outbuf, outOff + len, mac.length); int padOffset = outOff + len + mac.length; for (int i = 0; i <= padding_length; i++) { outbuf[i + padOffset] = (byte)padding_length; } for (int i = outOff; i < totalSize; i += blockSize) { encryptCipher.processBlock(outbuf, i, outbuf, i); } return outbuf; } public byte[] decodeCiphertext(long seqNo, short type, byte[] ciphertext, int offset, int len) throws IOException { int blockSize = decryptCipher.getBlockSize(); int macSize = readMac.getSize(); int minLen = Math.max(blockSize, macSize + 1); if (useExplicitIV) { minLen += blockSize; } if (len < minLen) { throw new TlsFatalAlert(AlertDescription.decode_error); } if (len % blockSize != 0) { throw new TlsFatalAlert(AlertDescription.decryption_failed); } if (useExplicitIV) { decryptCipher.init(false, new ParametersWithIV(null, ciphertext, offset, blockSize)); offset += blockSize; len -= blockSize; } for (int i = 0; i < len; i += blockSize) { decryptCipher.processBlock(ciphertext, offset + i, ciphertext, offset + i); } // If there's anything wrong with the padding, this will return zero int totalPad = checkPaddingConstantTime(ciphertext, offset, len, blockSize, macSize); int macInputLen = len - totalPad - macSize; byte[] decryptedMac = Arrays.copyOfRange(ciphertext, offset + macInputLen, offset + macInputLen + macSize); byte[] calculatedMac = readMac.calculateMacConstantTime(seqNo, type, ciphertext, offset, macInputLen, len - macSize, randomData); boolean badMac = !Arrays.constantTimeAreEqual(calculatedMac, decryptedMac); if (badMac || totalPad == 0) { throw new TlsFatalAlert(AlertDescription.bad_record_mac); } return Arrays.copyOfRange(ciphertext, offset, offset + macInputLen); } protected int checkPaddingConstantTime(byte[] buf, int off, int len, int blockSize, int macSize) { int end = off + len; byte lastByte = buf[end - 1]; int padlen = lastByte & 0xff; int totalPad = padlen + 1; int dummyIndex = 0; byte padDiff = 0; if ((context.getServerVersion().isSSL() && totalPad > blockSize) || (macSize + totalPad > len)) { totalPad = 0; } else { int padPos = end - totalPad; do { padDiff |= (buf[padPos++] ^ lastByte); } while (padPos < end); dummyIndex = totalPad; if (padDiff != 0) { totalPad = 0; } } // Run some extra dummy checks so the number of checks is always constant { byte[] dummyPad = randomData; while (dummyIndex < 256) { padDiff |= (dummyPad[dummyIndex++] ^ lastByte); } // Ensure the above loop is not eliminated dummyPad[0] ^= padDiff; } return totalPad; } protected int chooseExtraPadBlocks(SecureRandom r, int max) { // return r.nextInt(max + 1); int x = r.nextInt(); int n = lowestBitSet(x); return Math.min(n, max); } protected int lowestBitSet(int x) { if (x == 0) { return 32; } int n = 0; while ((x & 1) == 0) { ++n; x >>= 1; } return n; } }bouncycastle-1.49.orig/src/org/bouncycastle/crypto/tls/DTLSServerProtocol.java0000644000175000017500000005621312151551725027161 0ustar ebourgebourgpackage org.bouncycastle.crypto.tls; import java.io.ByteArrayInputStream; import java.io.ByteArrayOutputStream; import java.io.IOException; import java.security.SecureRandom; import java.util.Hashtable; import java.util.Vector; import org.bouncycastle.asn1.x509.SubjectPublicKeyInfo; import org.bouncycastle.crypto.params.AsymmetricKeyParameter; import org.bouncycastle.crypto.util.PublicKeyFactory; import org.bouncycastle.util.Arrays; public class DTLSServerProtocol extends DTLSProtocol { protected boolean verifyRequests = true; public DTLSServerProtocol(SecureRandom secureRandom) { super(secureRandom); } public boolean getVerifyRequests() { return verifyRequests; } public void setVerifyRequests(boolean verifyRequests) { this.verifyRequests = verifyRequests; } public DTLSTransport accept(TlsServer server, DatagramTransport transport) throws IOException { if (server == null) { throw new IllegalArgumentException("'server' cannot be null"); } if (transport == null) { throw new IllegalArgumentException("'transport' cannot be null"); } SecurityParameters securityParameters = new SecurityParameters(); securityParameters.entity = ConnectionEnd.server; securityParameters.serverRandom = TlsProtocol.createRandomBlock(secureRandom); ServerHandshakeState state = new ServerHandshakeState(); state.server = server; state.serverContext = new TlsServerContextImpl(secureRandom, securityParameters); server.init(state.serverContext); DTLSRecordLayer recordLayer = new DTLSRecordLayer(transport, state.serverContext, server, ContentType.handshake); // TODO Need to handle sending of HelloVerifyRequest without entering a full connection try { return serverHandshake(state, recordLayer); } catch (TlsFatalAlert fatalAlert) { recordLayer.fail(fatalAlert.getAlertDescription()); throw fatalAlert; } catch (IOException e) { recordLayer.fail(AlertDescription.internal_error); throw e; } catch (RuntimeException e) { recordLayer.fail(AlertDescription.internal_error); throw new TlsFatalAlert(AlertDescription.internal_error); } } public DTLSTransport serverHandshake(ServerHandshakeState state, DTLSRecordLayer recordLayer) throws IOException { SecurityParameters securityParameters = state.serverContext.getSecurityParameters(); DTLSReliableHandshake handshake = new DTLSReliableHandshake(state.serverContext, recordLayer); DTLSReliableHandshake.Message clientMessage = handshake.receiveMessage(); { // NOTE: After receiving a record from the client, we discover the record layer version ProtocolVersion client_version = recordLayer.getDiscoveredPeerVersion(); // TODO Read RFCs for guidance on the expected record layer version number state.serverContext.setClientVersion(client_version); } if (clientMessage.getType() == HandshakeType.client_hello) { processClientHello(state, clientMessage.getBody()); } else { throw new TlsFatalAlert(AlertDescription.unexpected_message); } byte[] serverHelloBody = generateServerHello(state); handshake.sendMessage(HandshakeType.server_hello, serverHelloBody); // TODO This block could really be done before actually sending the hello { securityParameters.prfAlgorithm = TlsProtocol.getPRFAlgorithm(state.selectedCipherSuite); securityParameters.compressionAlgorithm = state.selectedCompressionMethod; /* * RFC 5264 7.4.9. Any cipher suite which does not explicitly specify verify_data_length * has a verify_data_length equal to 12. This includes all existing cipher suites. */ securityParameters.verifyDataLength = 12; handshake.notifyHelloComplete(); } Vector serverSupplementalData = state.server.getServerSupplementalData(); if (serverSupplementalData != null) { byte[] supplementalDataBody = generateSupplementalData(serverSupplementalData); handshake.sendMessage(HandshakeType.supplemental_data, supplementalDataBody); } state.keyExchange = state.server.getKeyExchange(); state.keyExchange.init(state.serverContext); state.serverCredentials = state.server.getCredentials(); if (state.serverCredentials == null) { state.keyExchange.skipServerCredentials(); } else { state.keyExchange.processServerCredentials(state.serverCredentials); byte[] certificateBody = generateCertificate(state.serverCredentials.getCertificate()); handshake.sendMessage(HandshakeType.certificate, certificateBody); } byte[] serverKeyExchange = state.keyExchange.generateServerKeyExchange(); if (serverKeyExchange != null) { handshake.sendMessage(HandshakeType.server_key_exchange, serverKeyExchange); } if (state.serverCredentials != null) { state.certificateRequest = state.server.getCertificateRequest(); if (state.certificateRequest != null) { state.keyExchange.validateCertificateRequest(state.certificateRequest); byte[] certificateRequestBody = generateCertificateRequest(state, state.certificateRequest); handshake.sendMessage(HandshakeType.certificate_request, certificateRequestBody); } } handshake.sendMessage(HandshakeType.server_hello_done, TlsUtils.EMPTY_BYTES); clientMessage = handshake.receiveMessage(); if (clientMessage.getType() == HandshakeType.supplemental_data) { processClientSupplementalData(state, clientMessage.getBody()); clientMessage = handshake.receiveMessage(); } else { state.server.processClientSupplementalData(null); } if (state.certificateRequest == null) { state.keyExchange.skipClientCredentials(); } else { if (clientMessage.getType() == HandshakeType.certificate) { processClientCertificate(state, clientMessage.getBody()); clientMessage = handshake.receiveMessage(); } else { ProtocolVersion equivalentTLSVersion = state.serverContext.getServerVersion().getEquivalentTLSVersion(); if (ProtocolVersion.TLSv12.isEqualOrEarlierVersionOf(equivalentTLSVersion)) { /* * RFC 5246 If no suitable certificate is available, the client MUST send a * certificate message containing no certificates. * * NOTE: In previous RFCs, this was SHOULD instead of MUST. */ throw new TlsFatalAlert(AlertDescription.unexpected_message); } notifyClientCertificate(state, Certificate.EMPTY_CHAIN); } } if (clientMessage.getType() == HandshakeType.client_key_exchange) { processClientKeyExchange(state, clientMessage.getBody()); } else { throw new TlsFatalAlert(AlertDescription.unexpected_message); } recordLayer.initPendingEpoch(state.server.getCipher()); /* * RFC 5246 7.4.8 This message is only sent following a client certificate that has signing * capability (i.e., all certificates except those containing fixed Diffie-Hellman * parameters). */ if (expectCertificateVerifyMessage(state)) { byte[] certificateVerifyHash = handshake.getCurrentHash(); clientMessage = handshake.receiveMessage(); if (clientMessage.getType() == HandshakeType.certificate_verify) { processCertificateVerify(state, clientMessage.getBody(), certificateVerifyHash); } else { throw new TlsFatalAlert(AlertDescription.unexpected_message); } } // NOTE: Calculated exclusive of the actual Finished message from the client byte[] clientFinishedHash = handshake.getCurrentHash(); clientMessage = handshake.receiveMessage(); if (clientMessage.getType() == HandshakeType.finished) { byte[] expectedClientVerifyData = TlsUtils.calculateVerifyData(state.serverContext, "client finished", clientFinishedHash); processFinished(clientMessage.getBody(), expectedClientVerifyData); } else { throw new TlsFatalAlert(AlertDescription.unexpected_message); } if (state.expectSessionTicket) { NewSessionTicket newSessionTicket = state.server.getNewSessionTicket(); byte[] newSessionTicketBody = generateNewSessionTicket(state, newSessionTicket); handshake.sendMessage(HandshakeType.session_ticket, newSessionTicketBody); } // NOTE: Calculated exclusive of the Finished message itself byte[] serverVerifyData = TlsUtils.calculateVerifyData(state.serverContext, "server finished", handshake.getCurrentHash()); handshake.sendMessage(HandshakeType.finished, serverVerifyData); handshake.finish(); state.server.notifyHandshakeComplete(); return new DTLSTransport(recordLayer); } protected byte[] generateCertificateRequest(ServerHandshakeState state, CertificateRequest certificateRequest) throws IOException { ByteArrayOutputStream buf = new ByteArrayOutputStream(); certificateRequest.encode(buf); return buf.toByteArray(); } protected byte[] generateNewSessionTicket(ServerHandshakeState state, NewSessionTicket newSessionTicket) throws IOException { ByteArrayOutputStream buf = new ByteArrayOutputStream(); newSessionTicket.encode(buf); return buf.toByteArray(); } protected byte[] generateServerHello(ServerHandshakeState state) throws IOException { ByteArrayOutputStream buf = new ByteArrayOutputStream(); ProtocolVersion server_version = state.server.getServerVersion(); if (!server_version.isEqualOrEarlierVersionOf(state.serverContext.getClientVersion())) { throw new TlsFatalAlert(AlertDescription.internal_error); } // TODO Read RFCs for guidance on the expected record layer version number // recordStream.setReadVersion(server_version); // recordStream.setWriteVersion(server_version); // recordStream.setRestrictReadVersion(true); state.serverContext.setServerVersion(server_version); TlsUtils.writeVersion(state.serverContext.getServerVersion(), buf); buf.write(state.serverContext.getSecurityParameters().serverRandom); /* * The server may return an empty session_id to indicate that the session will not be cached * and therefore cannot be resumed. */ TlsUtils.writeOpaque8(TlsUtils.EMPTY_BYTES, buf); state.selectedCipherSuite = state.server.getSelectedCipherSuite(); if (!TlsProtocol.arrayContains(state.offeredCipherSuites, state.selectedCipherSuite) || state.selectedCipherSuite == CipherSuite.TLS_NULL_WITH_NULL_NULL || state.selectedCipherSuite == CipherSuite.TLS_EMPTY_RENEGOTIATION_INFO_SCSV) { throw new TlsFatalAlert(AlertDescription.internal_error); } validateSelectedCipherSuite(state.selectedCipherSuite, AlertDescription.internal_error); state.selectedCompressionMethod = state.server.getSelectedCompressionMethod(); if (!TlsProtocol.arrayContains(state.offeredCompressionMethods, state.selectedCompressionMethod)) { throw new TlsFatalAlert(AlertDescription.internal_error); } TlsUtils.writeUint16(state.selectedCipherSuite, buf); TlsUtils.writeUint8(state.selectedCompressionMethod, buf); state.serverExtensions = state.server.getServerExtensions(); /* * RFC 5746 3.6. Server Behavior: Initial Handshake */ if (state.secure_renegotiation) { boolean noRenegExt = state.serverExtensions == null || !state.serverExtensions.containsKey(TlsProtocol.EXT_RenegotiationInfo); if (noRenegExt) { /* * Note that sending a "renegotiation_info" extension in response to a ClientHello * containing only the SCSV is an explicit exception to the prohibition in RFC 5246, * Section 7.4.1.4, on the server sending unsolicited extensions and is only allowed * because the client is signaling its willingness to receive the extension via the * TLS_EMPTY_RENEGOTIATION_INFO_SCSV SCSV. */ if (state.serverExtensions == null) { state.serverExtensions = new Hashtable(); } /* * If the secure_renegotiation flag is set to TRUE, the server MUST include an empty * "renegotiation_info" extension in the ServerHello message. */ state.serverExtensions.put(TlsProtocol.EXT_RenegotiationInfo, TlsProtocol.createRenegotiationInfo(TlsUtils.EMPTY_BYTES)); } } if (state.serverExtensions != null) { state.expectSessionTicket = state.serverExtensions.containsKey(TlsProtocol.EXT_SessionTicket); TlsProtocol.writeExtensions(buf, state.serverExtensions); } return buf.toByteArray(); } protected void notifyClientCertificate(ServerHandshakeState state, Certificate clientCertificate) throws IOException { if (state.certificateRequest == null) { throw new IllegalStateException(); } if (state.clientCertificate != null) { throw new TlsFatalAlert(AlertDescription.unexpected_message); } state.clientCertificate = clientCertificate; if (clientCertificate.isEmpty()) { state.keyExchange.skipClientCredentials(); } else { /* * TODO RFC 5246 7.4.6. If the certificate_authorities list in the certificate request * message was non-empty, one of the certificates in the certificate chain SHOULD be * issued by one of the listed CAs. */ state.clientCertificateType = TlsUtils.getClientCertificateType(clientCertificate, state.serverCredentials.getCertificate()); state.keyExchange.processClientCertificate(clientCertificate); } /* * RFC 5246 7.4.6. If the client does not send any certificates, the server MAY at its * discretion either continue the handshake without client authentication, or respond with a * fatal handshake_failure alert. Also, if some aspect of the certificate chain was * unacceptable (e.g., it was not signed by a known, trusted CA), the server MAY at its * discretion either continue the handshake (considering the client unauthenticated) or send * a fatal alert. */ state.server.notifyClientCertificate(clientCertificate); } protected void processClientCertificate(ServerHandshakeState state, byte[] body) throws IOException { ByteArrayInputStream buf = new ByteArrayInputStream(body); Certificate clientCertificate = Certificate.parse(buf); TlsProtocol.assertEmpty(buf); notifyClientCertificate(state, clientCertificate); } protected void processCertificateVerify(ServerHandshakeState state, byte[] body, byte[] certificateVerifyHash) throws IOException { ByteArrayInputStream buf = new ByteArrayInputStream(body); byte[] clientCertificateSignature = TlsUtils.readOpaque16(buf); TlsProtocol.assertEmpty(buf); // Verify the CertificateVerify message contains a correct signature. try { TlsSigner tlsSigner = TlsUtils.createTlsSigner(state.clientCertificateType); tlsSigner.init(state.serverContext); org.bouncycastle.asn1.x509.Certificate x509Cert = state.clientCertificate.getCertificateAt(0); SubjectPublicKeyInfo keyInfo = x509Cert.getSubjectPublicKeyInfo(); AsymmetricKeyParameter publicKey = PublicKeyFactory.createKey(keyInfo); tlsSigner.verifyRawSignature(clientCertificateSignature, publicKey, certificateVerifyHash); } catch (Exception e) { throw new TlsFatalAlert(AlertDescription.decrypt_error); } } protected void processClientHello(ServerHandshakeState state, byte[] body) throws IOException { ByteArrayInputStream buf = new ByteArrayInputStream(body); // TODO Read RFCs for guidance on the expected record layer version number ProtocolVersion client_version = TlsUtils.readVersion(buf); if (!client_version.isDTLS()) { throw new TlsFatalAlert(AlertDescription.illegal_parameter); } /* * Read the client random */ byte[] client_random = TlsUtils.readFully(32, buf); byte[] sessionID = TlsUtils.readOpaque8(buf); if (sessionID.length > 32) { throw new TlsFatalAlert(AlertDescription.illegal_parameter); } // TODO RFC 4347 has the cookie length restricted to 32, but not in RFC 6347 byte[] cookie = TlsUtils.readOpaque8(buf); int cipher_suites_length = TlsUtils.readUint16(buf); if (cipher_suites_length < 2 || (cipher_suites_length & 1) != 0) { throw new TlsFatalAlert(AlertDescription.decode_error); } /* * NOTE: "If the session_id field is not empty (implying a session resumption request) this * vector must include at least the cipher_suite from that session." */ state.offeredCipherSuites = TlsUtils.readUint16Array(cipher_suites_length / 2, buf); int compression_methods_length = TlsUtils.readUint8(buf); if (compression_methods_length < 1) { throw new TlsFatalAlert(AlertDescription.illegal_parameter); } state.offeredCompressionMethods = TlsUtils.readUint8Array(compression_methods_length, buf); /* * TODO RFC 3546 2.3 If [...] the older session is resumed, then the server MUST ignore * extensions appearing in the client hello, and send a server hello containing no * extensions. */ state.clientExtensions = TlsProtocol.readExtensions(buf); state.serverContext.setClientVersion(client_version); state.server.notifyClientVersion(client_version); state.serverContext.getSecurityParameters().clientRandom = client_random; state.server.notifyOfferedCipherSuites(state.offeredCipherSuites); state.server.notifyOfferedCompressionMethods(state.offeredCompressionMethods); /* * RFC 5746 3.6. Server Behavior: Initial Handshake */ { /* * RFC 5746 3.4. The client MUST include either an empty "renegotiation_info" extension, * or the TLS_EMPTY_RENEGOTIATION_INFO_SCSV signaling cipher suite value in the * ClientHello. Including both is NOT RECOMMENDED. */ /* * When a ClientHello is received, the server MUST check if it includes the * TLS_EMPTY_RENEGOTIATION_INFO_SCSV SCSV. If it does, set the secure_renegotiation flag * to TRUE. */ if (TlsProtocol.arrayContains(state.offeredCipherSuites, CipherSuite.TLS_EMPTY_RENEGOTIATION_INFO_SCSV)) { state.secure_renegotiation = true; } /* * The server MUST check if the "renegotiation_info" extension is included in the * ClientHello. */ if (state.clientExtensions != null) { byte[] renegExtValue = (byte[])state.clientExtensions.get(TlsProtocol.EXT_RenegotiationInfo); if (renegExtValue != null) { /* * If the extension is present, set secure_renegotiation flag to TRUE. The * server MUST then verify that the length of the "renegotiated_connection" * field is zero, and if it is not, MUST abort the handshake. */ state.secure_renegotiation = true; if (!Arrays.constantTimeAreEqual(renegExtValue, TlsProtocol.createRenegotiationInfo(TlsUtils.EMPTY_BYTES))) { throw new TlsFatalAlert(AlertDescription.handshake_failure); } } } } state.server.notifySecureRenegotiation(state.secure_renegotiation); if (state.clientExtensions != null) { state.server.processClientExtensions(state.clientExtensions); } } protected void processClientKeyExchange(ServerHandshakeState state, byte[] body) throws IOException { ByteArrayInputStream buf = new ByteArrayInputStream(body); state.keyExchange.processClientKeyExchange(buf); TlsProtocol.assertEmpty(buf); TlsProtocol.establishMasterSecret(state.serverContext, state.keyExchange); } protected void processClientSupplementalData(ServerHandshakeState state, byte[] body) throws IOException { ByteArrayInputStream buf = new ByteArrayInputStream(body); Vector clientSupplementalData = TlsProtocol.readSupplementalDataMessage(buf); state.server.processClientSupplementalData(clientSupplementalData); } protected boolean expectCertificateVerifyMessage(ServerHandshakeState state) { return state.clientCertificateType >= 0 && TlsUtils.hasSigningCapability(state.clientCertificateType); } protected static class ServerHandshakeState { TlsServer server = null; TlsServerContextImpl serverContext = null; int[] offeredCipherSuites; short[] offeredCompressionMethods; Hashtable clientExtensions; int selectedCipherSuite = -1; short selectedCompressionMethod = -1; boolean secure_renegotiation = false; boolean expectSessionTicket = false; Hashtable serverExtensions = null; TlsKeyExchange keyExchange = null; TlsCredentials serverCredentials = null; CertificateRequest certificateRequest = null; short clientCertificateType = -1; Certificate clientCertificate = null; } } bouncycastle-1.49.orig/src/org/bouncycastle/crypto/tls/CertificateVerifyer.java0000644000175000017500000000100512146535331027424 0ustar ebourgebourgpackage org.bouncycastle.crypto.tls; /** * This should be implemented by any class which can find out, if a given certificate * chain is being accepted by an client. * * @deprecated Perform certificate verification in TlsAuthentication implementation */ public interface CertificateVerifyer { /** * @param certs The certs, which are part of the chain. * @return True, if the chain is accepted, false otherwise. */ public boolean isValid(org.bouncycastle.asn1.x509.Certificate[] certs); } bouncycastle-1.49.orig/src/org/bouncycastle/crypto/tls/TlsRuntimeException.java0000644000175000017500000000071212146535331027457 0ustar ebourgebourgpackage org.bouncycastle.crypto.tls; public class TlsRuntimeException extends RuntimeException { private static final long serialVersionUID = 1928023487348344086L; Throwable e; public TlsRuntimeException(String message, Throwable e) { super(message); this.e = e; } public TlsRuntimeException(String message) { super(message); } public Throwable getCause() { return e; } } bouncycastle-1.49.orig/src/org/bouncycastle/crypto/tls/HashAlgorithm.java0000644000175000017500000000060312151551725026224 0ustar ebourgebourgpackage org.bouncycastle.crypto.tls; /** * RFC 5246 7.4.1.4.1 */ public class HashAlgorithm { public static final short none = 0; public static final short md5 = 1; public static final short sha1 = 2; public static final short sha224 = 3; public static final short sha256 = 4; public static final short sha384 = 5; public static final short sha512 = 6; } bouncycastle-1.49.orig/src/org/bouncycastle/crypto/tls/CombinedHash.java0000644000175000017500000000525312151551725026024 0ustar ebourgebourgpackage org.bouncycastle.crypto.tls; import org.bouncycastle.crypto.Digest; /** * A combined hash, which implements md5(m) || sha1(m). */ class CombinedHash implements TlsHandshakeHash { protected TlsContext context; protected Digest md5; protected Digest sha1; CombinedHash() { this.md5 = TlsUtils.createHash(HashAlgorithm.md5); this.sha1 = TlsUtils.createHash(HashAlgorithm.sha1); } CombinedHash(CombinedHash t) { this.context = t.context; this.md5 = TlsUtils.cloneHash(HashAlgorithm.md5, t.md5); this.sha1 = TlsUtils.cloneHash(HashAlgorithm.sha1, t.sha1); } public void init(TlsContext context) { this.context = context; } public TlsHandshakeHash commit() { return this; } public TlsHandshakeHash fork() { return new CombinedHash(this); } /** * @see org.bouncycastle.crypto.Digest#getAlgorithmName() */ public String getAlgorithmName() { return md5.getAlgorithmName() + " and " + sha1.getAlgorithmName(); } /** * @see org.bouncycastle.crypto.Digest#getDigestSize() */ public int getDigestSize() { return md5.getDigestSize() + sha1.getDigestSize(); } /** * @see org.bouncycastle.crypto.Digest#update(byte) */ public void update(byte in) { md5.update(in); sha1.update(in); } /** * @see org.bouncycastle.crypto.Digest#update(byte[], int, int) */ public void update(byte[] in, int inOff, int len) { md5.update(in, inOff, len); sha1.update(in, inOff, len); } /** * @see org.bouncycastle.crypto.Digest#doFinal(byte[], int) */ public int doFinal(byte[] out, int outOff) { if (context != null && context.getServerVersion().isSSL()) { ssl3Complete(md5, SSL3Mac.IPAD, SSL3Mac.OPAD, 48); ssl3Complete(sha1, SSL3Mac.IPAD, SSL3Mac.OPAD, 40); } int i1 = md5.doFinal(out, outOff); int i2 = sha1.doFinal(out, outOff + i1); return i1 + i2; } /** * @see org.bouncycastle.crypto.Digest#reset() */ public void reset() { md5.reset(); sha1.reset(); } protected void ssl3Complete(Digest d, byte[] ipad, byte[] opad, int padLength) { byte[] secret = context.getSecurityParameters().masterSecret; d.update(secret, 0, secret.length); d.update(ipad, 0, padLength); byte[] tmp = new byte[d.getDigestSize()]; d.doFinal(tmp, 0); d.update(secret, 0, secret.length); d.update(opad, 0, padLength); d.update(tmp, 0, tmp.length); } } bouncycastle-1.49.orig/src/org/bouncycastle/crypto/tls/CompressionMethod.java0000644000175000017500000000067312146534067027147 0ustar ebourgebourgpackage org.bouncycastle.crypto.tls; /** * RFC 2246 6.1 */ public class CompressionMethod { public static final short _null = 0; /** * @deprecated use '_null' instead */ public static final short NULL = _null; /* * RFC 3749 2 */ public static final short DEFLATE = 1; /* * Values from 224 decimal (0xE0) through 255 decimal (0xFF) * inclusive are reserved for private use. */ } bouncycastle-1.49.orig/src/org/bouncycastle/crypto/tls/ECPointFormat.java0000644000175000017500000000046412146534067026155 0ustar ebourgebourgpackage org.bouncycastle.crypto.tls; /** * RFC 4492 5.1.2 */ public class ECPointFormat { public static final short uncompressed = 0; public static final short ansiX962_compressed_prime = 1; public static final short ansiX962_compressed_char2 = 2; /* * reserved (248..255) */ } bouncycastle-1.49.orig/src/org/bouncycastle/crypto/tls/TlsSRPKeyExchange.java0000644000175000017500000001461312151551725026743 0ustar ebourgebourgpackage org.bouncycastle.crypto.tls; import java.io.IOException; import java.io.InputStream; import java.io.OutputStream; import java.math.BigInteger; import java.util.Vector; import org.bouncycastle.asn1.x509.KeyUsage; import org.bouncycastle.asn1.x509.SubjectPublicKeyInfo; import org.bouncycastle.crypto.CryptoException; import org.bouncycastle.crypto.Signer; import org.bouncycastle.crypto.agreement.srp.SRP6Client; import org.bouncycastle.crypto.agreement.srp.SRP6Util; import org.bouncycastle.crypto.digests.SHA1Digest; import org.bouncycastle.crypto.io.SignerInputStream; import org.bouncycastle.crypto.params.AsymmetricKeyParameter; import org.bouncycastle.crypto.util.PublicKeyFactory; import org.bouncycastle.util.BigIntegers; /** * TLS 1.1 SRP key exchange (RFC 5054). */ public class TlsSRPKeyExchange extends AbstractTlsKeyExchange { protected TlsSigner tlsSigner; protected byte[] identity; protected byte[] password; protected AsymmetricKeyParameter serverPublicKey = null; protected byte[] s = null; protected BigInteger B = null; protected SRP6Client srpClient = new SRP6Client(); public TlsSRPKeyExchange(int keyExchange, Vector supportedSignatureAlgorithms, byte[] identity, byte[] password) { super(keyExchange, supportedSignatureAlgorithms); switch (keyExchange) { case KeyExchangeAlgorithm.SRP: this.tlsSigner = null; break; case KeyExchangeAlgorithm.SRP_RSA: this.tlsSigner = new TlsRSASigner(); break; case KeyExchangeAlgorithm.SRP_DSS: this.tlsSigner = new TlsDSSSigner(); break; default: throw new IllegalArgumentException("unsupported key exchange algorithm"); } this.keyExchange = keyExchange; this.identity = identity; this.password = password; } public void init(TlsContext context) { super.init(context); if (this.tlsSigner != null) { this.tlsSigner.init(context); } } public void skipServerCredentials() throws IOException { if (tlsSigner != null) { throw new TlsFatalAlert(AlertDescription.unexpected_message); } } public void processServerCertificate(Certificate serverCertificate) throws IOException { if (tlsSigner == null) { throw new TlsFatalAlert(AlertDescription.unexpected_message); } if (serverCertificate.isEmpty()) { throw new TlsFatalAlert(AlertDescription.bad_certificate); } org.bouncycastle.asn1.x509.Certificate x509Cert = serverCertificate.getCertificateAt(0); SubjectPublicKeyInfo keyInfo = x509Cert.getSubjectPublicKeyInfo(); try { this.serverPublicKey = PublicKeyFactory.createKey(keyInfo); } catch (RuntimeException e) { throw new TlsFatalAlert(AlertDescription.unsupported_certificate); } if (!tlsSigner.isValidPublicKey(this.serverPublicKey)) { throw new TlsFatalAlert(AlertDescription.certificate_unknown); } TlsUtils.validateKeyUsage(x509Cert, KeyUsage.digitalSignature); super.processServerCertificate(serverCertificate); } public boolean requiresServerKeyExchange() { return true; } public void processServerKeyExchange(InputStream input) throws IOException { SecurityParameters securityParameters = context.getSecurityParameters(); InputStream sigIn = input; Signer signer = null; if (tlsSigner != null) { signer = initVerifyer(tlsSigner, securityParameters); sigIn = new SignerInputStream(input, signer); } byte[] NBytes = TlsUtils.readOpaque16(sigIn); byte[] gBytes = TlsUtils.readOpaque16(sigIn); byte[] sBytes = TlsUtils.readOpaque8(sigIn); byte[] BBytes = TlsUtils.readOpaque16(sigIn); if (signer != null) { byte[] sigByte = TlsUtils.readOpaque16(input); if (!signer.verifySignature(sigByte)) { throw new TlsFatalAlert(AlertDescription.decrypt_error); } } BigInteger N = new BigInteger(1, NBytes); BigInteger g = new BigInteger(1, gBytes); // TODO Validate group parameters (see RFC 5054) // handler.failWithError(AlertLevel.fatal, AlertDescription.insufficient_security); this.s = sBytes; /* * RFC 5054 2.5.3: The client MUST abort the handshake with an "illegal_parameter" alert if * B % N = 0. */ try { this.B = SRP6Util.validatePublicValue(N, new BigInteger(1, BBytes)); } catch (CryptoException e) { throw new TlsFatalAlert(AlertDescription.illegal_parameter); } this.srpClient.init(N, g, new SHA1Digest(), context.getSecureRandom()); } public void validateCertificateRequest(CertificateRequest certificateRequest) throws IOException { throw new TlsFatalAlert(AlertDescription.unexpected_message); } public void processClientCredentials(TlsCredentials clientCredentials) throws IOException { throw new TlsFatalAlert(AlertDescription.internal_error); } public void generateClientKeyExchange(OutputStream output) throws IOException { byte[] keData = BigIntegers.asUnsignedByteArray(srpClient.generateClientCredentials(s, this.identity, this.password)); TlsUtils.writeOpaque16(keData, output); } public byte[] generatePremasterSecret() throws IOException { try { // TODO Check if this needs to be a fixed size return BigIntegers.asUnsignedByteArray(srpClient.calculateSecret(B)); } catch (CryptoException e) { throw new TlsFatalAlert(AlertDescription.illegal_parameter); } } protected Signer initVerifyer(TlsSigner tlsSigner, SecurityParameters securityParameters) { Signer signer = tlsSigner.createVerifyer(this.serverPublicKey); signer.update(securityParameters.clientRandom, 0, securityParameters.clientRandom.length); signer.update(securityParameters.serverRandom, 0, securityParameters.serverRandom.length); return signer; } } bouncycastle-1.49.orig/src/org/bouncycastle/crypto/tls/EncryptionAlgorithm.java0000644000175000017500000000203112151551725027470 0ustar ebourgebourgpackage org.bouncycastle.crypto.tls; /** * RFC 2246 *

    * Note that the values here are implementation-specific and arbitrary. It is recommended not to * depend on the particular values (e.g. serialization). */ public class EncryptionAlgorithm { public static final int NULL = 0; public static final int RC4_40 = 1; public static final int RC4_128 = 2; public static final int RC2_CBC_40 = 3; public static final int IDEA_CBC = 4; public static final int DES40_CBC = 5; public static final int DES_CBC = 6; public static final int _3DES_EDE_CBC = 7; /* * RFC 3268 */ public static final int AES_128_CBC = 8; public static final int AES_256_CBC = 9; /* * RFC 4132 */ public static final int CAMELLIA_128_CBC = 12; public static final int CAMELLIA_256_CBC = 13; /* * RFC 4162 */ public static final int SEED_CBC = 14; /* * RFC 5289 */ public static final int AES_128_GCM = 10; public static final int AES_256_GCM = 11; } bouncycastle-1.49.orig/src/org/bouncycastle/crypto/tls/AbstractTlsSigner.java0000644000175000017500000000034412151551725027072 0ustar ebourgebourgpackage org.bouncycastle.crypto.tls; public abstract class AbstractTlsSigner implements TlsSigner { protected TlsContext context; public void init(TlsContext context) { this.context = context; } } bouncycastle-1.49.orig/src/org/bouncycastle/crypto/tls/PRFAlgorithm.java0000644000175000017500000000077612151551725026003 0ustar ebourgebourgpackage org.bouncycastle.crypto.tls; /** * RFC 5246 *

    * Note that the values here are implementation-specific and arbitrary. It is recommended not to * depend on the particular values (e.g. serialization). */ public class PRFAlgorithm { /* * Placeholder to refer to the legacy TLS algorithm */ public static final int tls_prf_legacy = 0; public static final int tls_prf_sha256 = 1; /* * Implied by RFC 5288 */ public static final int tls_prf_sha384 = 2; } bouncycastle-1.49.orig/src/org/bouncycastle/crypto/tls/TlsProtocolHandler.java0000644000175000017500000000072512151551725027261 0ustar ebourgebourgpackage org.bouncycastle.crypto.tls; import java.io.InputStream; import java.io.OutputStream; import java.security.SecureRandom; /** * @deprecated use TlsClientProtocol instead */ public class TlsProtocolHandler extends TlsClientProtocol { public TlsProtocolHandler(InputStream is, OutputStream os) { super(is, os); } public TlsProtocolHandler(InputStream is, OutputStream os, SecureRandom sr) { super(is, os, sr); } } bouncycastle-1.49.orig/src/org/bouncycastle/crypto/tls/MACAlgorithm.java0000644000175000017500000000115412151551725025743 0ustar ebourgebourgpackage org.bouncycastle.crypto.tls; /** * RFC 2246 *

    * Note that the values here are implementation-specific and arbitrary. It is recommended not to * depend on the particular values (e.g. serialization). */ public class MACAlgorithm { public static final int _null = 0; public static final int md5 = 1; public static final int sha = 2; /* * RFC 5246 */ public static final int hmac_md5 = md5; public static final int hmac_sha1 = sha; public static final int hmac_sha256 = 3; public static final int hmac_sha384 = 4; public static final int hmac_sha512 = 5; } bouncycastle-1.49.orig/src/org/bouncycastle/crypto/tls/CertificateRequest.java0000644000175000017500000001005612147270726027274 0ustar ebourgebourgpackage org.bouncycastle.crypto.tls; import java.io.ByteArrayInputStream; import java.io.IOException; import java.io.InputStream; import java.io.OutputStream; import java.util.Vector; import org.bouncycastle.asn1.ASN1Encoding; import org.bouncycastle.asn1.ASN1Primitive; import org.bouncycastle.asn1.x500.X500Name; /** * Parsing and encoding of a CertificateRequest struct from RFC 4346. *

    *

     * struct {
     *     ClientCertificateType certificate_types<1..2^8-1>;
     *     DistinguishedName certificate_authorities<3..2^16-1>;
     * } CertificateRequest;
     * 
    * * @see ClientCertificateType * @see X500Name */ public class CertificateRequest { private short[] certificateTypes; private Vector certificateAuthorities; /* * TODO RFC 5264 7.4.4 A list of the hash/signature algorithm pairs that the server is able to * verify, listed in descending order of preference. */ /** * @param certificateTypes see {@link ClientCertificateType} for valid constants. * @param certificateAuthorities a {@link Vector} of {@link X500Name}. */ public CertificateRequest(short[] certificateTypes, Vector certificateAuthorities) { this.certificateTypes = certificateTypes; this.certificateAuthorities = certificateAuthorities; } /** * @return an array of certificate types * @see {@link ClientCertificateType} */ public short[] getCertificateTypes() { return certificateTypes; } /** * @return a {@link Vector} of {@link X500Name} */ public Vector getCertificateAuthorities() { return certificateAuthorities; } /** * Encode this {@link CertificateRequest} to an {@link OutputStream}. * * @param output the {@link OutputStream} to encode to. * @throws IOException */ public void encode(OutputStream output) throws IOException { if (certificateTypes == null || certificateTypes.length == 0) { TlsUtils.writeUint8((short)0, output); } else { TlsUtils.writeUint8((short)certificateTypes.length, output); TlsUtils.writeUint8Array(certificateTypes, output); } if (certificateAuthorities == null || certificateAuthorities.isEmpty()) { TlsUtils.writeUint16(0, output); } else { Vector encDNs = new Vector(certificateAuthorities.size()); int totalLength = 0; for (int i = 0; i < certificateAuthorities.size(); ++i) { X500Name authorityDN = (X500Name)certificateAuthorities.elementAt(i); byte[] encDN = authorityDN.getEncoded(ASN1Encoding.DER); encDNs.addElement(encDN); totalLength += encDN.length; } TlsUtils.writeUint16(totalLength, output); for (int i = 0; i < encDNs.size(); ++i) { byte[] encDN = (byte[])encDNs.elementAt(i); output.write(encDN); } } } /** * Parse a {@link CertificateRequest} from an {@link InputStream}. * * @param input the {@link InputStream} to parse from. * @return a {@link CertificateRequest} object. * @throws IOException */ public static CertificateRequest parse(InputStream input) throws IOException { int numTypes = TlsUtils.readUint8(input); short[] certificateTypes = new short[numTypes]; for (int i = 0; i < numTypes; ++i) { certificateTypes[i] = TlsUtils.readUint8(input); } byte[] authorities = TlsUtils.readOpaque16(input); Vector authorityDNs = new Vector(); ByteArrayInputStream bis = new ByteArrayInputStream(authorities); while (bis.available() > 0) { byte[] dnBytes = TlsUtils.readOpaque16(bis); authorityDNs.addElement(X500Name.getInstance(ASN1Primitive.fromByteArray(dnBytes))); } return new CertificateRequest(certificateTypes, authorityDNs); } } bouncycastle-1.49.orig/src/org/bouncycastle/crypto/tls/DatagramTransport.java0000644000175000017500000000064712151551725027137 0ustar ebourgebourgpackage org.bouncycastle.crypto.tls; import java.io.IOException; public interface DatagramTransport { int getReceiveLimit() throws IOException; int getSendLimit() throws IOException; int receive(byte[] buf, int off, int len, int waitMillis) throws IOException; void send(byte[] buf, int off, int len) throws IOException; void close() throws IOException; } bouncycastle-1.49.orig/src/org/bouncycastle/crypto/tls/TlsDHKeyExchange.java0000644000175000017500000001547012151551725026574 0ustar ebourgebourgpackage org.bouncycastle.crypto.tls; import java.io.IOException; import java.io.OutputStream; import java.math.BigInteger; import java.util.Vector; import org.bouncycastle.asn1.x509.KeyUsage; import org.bouncycastle.asn1.x509.SubjectPublicKeyInfo; import org.bouncycastle.crypto.AsymmetricCipherKeyPair; import org.bouncycastle.crypto.params.AsymmetricKeyParameter; import org.bouncycastle.crypto.params.DHParameters; import org.bouncycastle.crypto.params.DHPrivateKeyParameters; import org.bouncycastle.crypto.params.DHPublicKeyParameters; import org.bouncycastle.crypto.util.PublicKeyFactory; /** * TLS 1.0/1.1 DH key exchange. */ public class TlsDHKeyExchange extends AbstractTlsKeyExchange { protected static final BigInteger ONE = BigInteger.valueOf(1); protected static final BigInteger TWO = BigInteger.valueOf(2); protected TlsSigner tlsSigner; protected DHParameters dhParameters; protected AsymmetricKeyParameter serverPublicKey; protected DHPublicKeyParameters dhAgreeServerPublicKey; protected TlsAgreementCredentials agreementCredentials; protected DHPrivateKeyParameters dhAgreeClientPrivateKey; protected DHPublicKeyParameters dhAgreeClientPublicKey; public TlsDHKeyExchange(int keyExchange, Vector supportedSignatureAlgorithms, DHParameters dhParameters) { super(keyExchange, supportedSignatureAlgorithms); switch (keyExchange) { case KeyExchangeAlgorithm.DH_RSA: case KeyExchangeAlgorithm.DH_DSS: this.tlsSigner = null; break; case KeyExchangeAlgorithm.DHE_RSA: this.tlsSigner = new TlsRSASigner(); break; case KeyExchangeAlgorithm.DHE_DSS: this.tlsSigner = new TlsDSSSigner(); break; default: throw new IllegalArgumentException("unsupported key exchange algorithm"); } this.dhParameters = dhParameters; } public void init(TlsContext context) { super.init(context); if (this.tlsSigner != null) { this.tlsSigner.init(context); } } public void skipServerCredentials() throws IOException { throw new TlsFatalAlert(AlertDescription.unexpected_message); } public void processServerCertificate(Certificate serverCertificate) throws IOException { if (serverCertificate.isEmpty()) { throw new TlsFatalAlert(AlertDescription.bad_certificate); } org.bouncycastle.asn1.x509.Certificate x509Cert = serverCertificate.getCertificateAt(0); SubjectPublicKeyInfo keyInfo = x509Cert.getSubjectPublicKeyInfo(); try { this.serverPublicKey = PublicKeyFactory.createKey(keyInfo); } catch (RuntimeException e) { throw new TlsFatalAlert(AlertDescription.unsupported_certificate); } if (tlsSigner == null) { try { this.dhAgreeServerPublicKey = validateDHPublicKey((DHPublicKeyParameters)this.serverPublicKey); } catch (ClassCastException e) { throw new TlsFatalAlert(AlertDescription.certificate_unknown); } TlsUtils.validateKeyUsage(x509Cert, KeyUsage.keyAgreement); } else { if (!tlsSigner.isValidPublicKey(this.serverPublicKey)) { throw new TlsFatalAlert(AlertDescription.certificate_unknown); } TlsUtils.validateKeyUsage(x509Cert, KeyUsage.digitalSignature); } super.processServerCertificate(serverCertificate); } public boolean requiresServerKeyExchange() { switch (keyExchange) { case KeyExchangeAlgorithm.DHE_DSS: case KeyExchangeAlgorithm.DHE_RSA: case KeyExchangeAlgorithm.DH_anon: return true; default: return false; } } public void validateCertificateRequest(CertificateRequest certificateRequest) throws IOException { short[] types = certificateRequest.getCertificateTypes(); for (int i = 0; i < types.length; ++i) { switch (types[i]) { case ClientCertificateType.rsa_sign: case ClientCertificateType.dss_sign: case ClientCertificateType.rsa_fixed_dh: case ClientCertificateType.dss_fixed_dh: case ClientCertificateType.ecdsa_sign: break; default: throw new TlsFatalAlert(AlertDescription.illegal_parameter); } } } public void processClientCredentials(TlsCredentials clientCredentials) throws IOException { if (clientCredentials instanceof TlsAgreementCredentials) { // TODO Validate client cert has matching parameters (see 'areCompatibleParameters')? this.agreementCredentials = (TlsAgreementCredentials)clientCredentials; } else if (clientCredentials instanceof TlsSignerCredentials) { // OK } else { throw new TlsFatalAlert(AlertDescription.internal_error); } } public void generateClientKeyExchange(OutputStream output) throws IOException { /* * RFC 2246 7.4.7.2 If the client certificate already contains a suitable Diffie-Hellman * key, then Yc is implicit and does not need to be sent again. In this case, the Client Key * Exchange message will be sent, but will be empty. */ if (agreementCredentials == null) { this.dhAgreeClientPrivateKey = TlsDHUtils.generateEphemeralClientKeyExchange(context.getSecureRandom(), dhAgreeServerPublicKey.getParameters(), output); } } public byte[] generatePremasterSecret() throws IOException { if (agreementCredentials != null) { return agreementCredentials.generateAgreement(dhAgreeServerPublicKey); } return calculateDHBasicAgreement(dhAgreeServerPublicKey, dhAgreeClientPrivateKey); } protected boolean areCompatibleParameters(DHParameters a, DHParameters b) { return a.getP().equals(b.getP()) && a.getG().equals(b.getG()); } protected byte[] calculateDHBasicAgreement(DHPublicKeyParameters publicKey, DHPrivateKeyParameters privateKey) { return TlsDHUtils.calculateDHBasicAgreement(publicKey, privateKey); } protected AsymmetricCipherKeyPair generateDHKeyPair(DHParameters dhParams) { return TlsDHUtils.generateDHKeyPair(context.getSecureRandom(), dhParams); } protected DHPublicKeyParameters validateDHPublicKey(DHPublicKeyParameters key) throws IOException { return TlsDHUtils.validateDHPublicKey(key); } } bouncycastle-1.49.orig/src/org/bouncycastle/crypto/tls/AlertDescription.java0000644000175000017500000002062412146535331026751 0ustar ebourgebourgpackage org.bouncycastle.crypto.tls; /** * RFC 5246 7.2. */ public class AlertDescription { /** * This message notifies the recipient that the sender will not send any more messages on this * connection. The session becomes unresumable if any connection is terminated without proper * close_notify messages with level equal to warning. */ public static final short close_notify = 0; /** * An inappropriate message was received. This alert is always fatal and should never be * observed in communication between proper implementations. */ public static final short unexpected_message = 10; /** * This alert is returned if a record is received with an incorrect MAC. This alert also MUST be * returned if an alert is sent because a TLSCiphertext decrypted in an invalid way: either it * wasn't an even multiple of the block length, or its padding values, when checked, weren't * correct. This message is always fatal and should never be observed in communication between * proper implementations (except when messages were corrupted in the network). */ public static final short bad_record_mac = 20; /** * This alert was used in some earlier versions of TLS, and may have permitted certain attacks * against the CBC mode [CBCATT]. It MUST NOT be sent by compliant implementations. */ public static final short decryption_failed = 21; /** * A TLSCiphertext record was received that had a length more than 2^14+2048 bytes, or a record * decrypted to a TLSCompressed record with more than 2^14+1024 bytes. This message is always * fatal and should never be observed in communication between proper implementations (except * when messages were corrupted in the network). */ public static final short record_overflow = 22; /** * The decompression function received improper input (e.g., data that would expand to excessive * length). This message is always fatal and should never be observed in communication between * proper implementations. */ public static final short decompression_failure = 30; /** * Reception of a handshake_failure alert message indicates that the sender was unable to * negotiate an acceptable set of security parameters given the options available. This is a * fatal error. */ public static final short handshake_failure = 40; /** * This alert was used in SSLv3 but not any version of TLS. It MUST NOT be sent by compliant * implementations. */ public static final short no_certificate = 41; /** * A certificate was corrupt, contained signatures that did not verify correctly, etc. */ public static final short bad_certificate = 42; /** * A certificate was of an unsupported type. */ public static final short unsupported_certificate = 43; /** * A certificate was revoked by its signer. */ public static final short certificate_revoked = 44; /** * A certificate has expired or is not currently valid. */ public static final short certificate_expired = 45; /** * Some other (unspecified) issue arose in processing the certificate, rendering it * unacceptable. */ public static final short certificate_unknown = 46; /** * A field in the handshake was out of range or inconsistent with other fields. This message is * always fatal. */ public static final short illegal_parameter = 47; /** * A valid certificate chain or partial chain was received, but the certificate was not accepted * because the CA certificate could not be located or couldn't be matched with a known, trusted * CA. This message is always fatal. */ public static final short unknown_ca = 48; /** * A valid certificate was received, but when access control was applied, the sender decided not * to proceed with negotiation. This message is always fatal. */ public static final short access_denied = 49; /** * A message could not be decoded because some field was out of the specified range or the * length of the message was incorrect. This message is always fatal and should never be * observed in communication between proper implementations (except when messages were corrupted * in the network). */ public static final short decode_error = 50; /** * A handshake cryptographic operation failed, including being unable to correctly verify a * signature or validate a Finished message. This message is always fatal. */ public static final short decrypt_error = 51; /** * This alert was used in some earlier versions of TLS. It MUST NOT be sent by compliant * implementations. */ public static final short export_restriction = 60; /** * The protocol version the client has attempted to negotiate is recognized but not supported. * (For example, old protocol versions might be avoided for security reasons.) This message is * always fatal. */ public static final short protocol_version = 70; /** * Returned instead of handshake_failure when a negotiation has failed specifically because the * server requires ciphers more secure than those supported by the client. This message is * always fatal. */ public static final short insufficient_security = 71; /** * An internal error unrelated to the peer or the correctness of the protocol (such as a memory * allocation failure) makes it impossible to continue. This message is always fatal. */ public static final short internal_error = 80; /** * This handshake is being canceled for some reason unrelated to a protocol failure. If the user * cancels an operation after the handshake is complete, just closing the connection by sending * a close_notify is more appropriate. This alert should be followed by a close_notify. This * message is generally a warning. */ public static final short user_canceled = 90; /** * Sent by the client in response to a hello request or by the server in response to a client * hello after initial handshaking. Either of these would normally lead to renegotiation; when * that is not appropriate, the recipient should respond with this alert. At that point, the * original requester can decide whether to proceed with the connection. One case where this * would be appropriate is where a server has spawned a process to satisfy a request; the * process might receive security parameters (key length, authentication, etc.) at startup, and * it might be difficult to communicate changes to these parameters after that point. This * message is always a warning. */ public static final short no_renegotiation = 100; /** * Sent by clients that receive an extended server hello containing an extension that they did * not put in the corresponding client hello. This message is always fatal. */ public static final short unsupported_extension = 110; /* * RFC 3546 */ /** * This alert is sent by servers who are unable to retrieve a certificate chain from the URL * supplied by the client (see Section 3.3). This message MAY be fatal - for example if client * authentication is required by the server for the handshake to continue and the server is * unable to retrieve the certificate chain, it may send a fatal alert. */ public static final short certificate_unobtainable = 111; /** * This alert is sent by servers that receive a server_name extension request, but do not * recognize the server name. This message MAY be fatal. */ public static final short unrecognized_name = 112; /** * This alert is sent by clients that receive an invalid certificate status response (see * Section 3.6). This message is always fatal. */ public static final short bad_certificate_status_response = 113; /** * This alert is sent by servers when a certificate hash does not match a client provided * certificate_hash. This message is always fatal. */ public static final short bad_certificate_hash_value = 114; /* * RFC 4279 */ /** * If the server does not recognize the PSK identity, it MAY respond with an * "unknown_psk_identity" alert message. */ public static final short unknown_psk_identity = 115; } bouncycastle-1.49.orig/src/org/bouncycastle/crypto/tls/TlsMac.java0000644000175000017500000001212112151551725024653 0ustar ebourgebourgpackage org.bouncycastle.crypto.tls; import java.io.ByteArrayOutputStream; import java.io.IOException; import org.bouncycastle.crypto.Digest; import org.bouncycastle.crypto.Mac; import org.bouncycastle.crypto.digests.LongDigest; import org.bouncycastle.crypto.macs.HMac; import org.bouncycastle.crypto.params.KeyParameter; import org.bouncycastle.util.Arrays; /** * A generic TLS MAC implementation, acting as an HMAC based on some underlying Digest. */ public class TlsMac { protected TlsContext context; protected byte[] secret; protected Mac mac; protected int digestBlockSize; protected int digestOverhead; /** * Generate a new instance of an TlsMac. * * @param context the TLS client context * @param digest The digest to use. * @param key A byte-array where the key for this mac is located. * @param keyOff The number of bytes to skip, before the key starts in the buffer. * @param len The length of the key. */ public TlsMac(TlsContext context, Digest digest, byte[] key, int keyOff, int keyLen) { this.context = context; KeyParameter keyParameter = new KeyParameter(key, keyOff, keyLen); this.secret = Arrays.clone(keyParameter.getKey()); // TODO This should check the actual algorithm, not rely on the engine type if (digest instanceof LongDigest) { this.digestBlockSize = 128; this.digestOverhead = 16; } else { this.digestBlockSize = 64; this.digestOverhead = 8; } if (context.getServerVersion().isSSL()) { this.mac = new SSL3Mac(digest); // TODO This should check the actual algorithm, not assume based on the digest size if (digest.getDigestSize() == 20) { /* * NOTE: When SHA-1 is used with the SSL 3.0 MAC, the secret + input pad is not * digest block-aligned. */ this.digestOverhead = 4; } } else { this.mac = new HMac(digest); // NOTE: The input pad for HMAC is always a full digest block } this.mac.init(keyParameter); } /** * @return the MAC write secret */ public byte[] getMACSecret() { return this.secret; } /** * @return The Keysize of the mac. */ public int getSize() { return mac.getMacSize(); } /** * Calculate the MAC for some given data. * * @param type The message type of the message. * @param message A byte-buffer containing the message. * @param offset The number of bytes to skip, before the message starts. * @param length The length of the message. * @return A new byte-buffer containing the MAC value. */ public byte[] calculateMac(long seqNo, short type, byte[] message, int offset, int length) { ProtocolVersion serverVersion = context.getServerVersion(); boolean isSSL = serverVersion.isSSL(); ByteArrayOutputStream bosMac = new ByteArrayOutputStream(isSSL ? 11 : 13); try { TlsUtils.writeUint64(seqNo, bosMac); TlsUtils.writeUint8(type, bosMac); if (!isSSL) { TlsUtils.writeVersion(serverVersion, bosMac); } TlsUtils.writeUint16(length, bosMac); } catch (IOException e) { // This should never happen throw new IllegalStateException("Internal error during mac calculation"); } byte[] macHeader = bosMac.toByteArray(); mac.update(macHeader, 0, macHeader.length); mac.update(message, offset, length); byte[] result = new byte[mac.getMacSize()]; mac.doFinal(result, 0); return result; } public byte[] calculateMacConstantTime(long seqNo, short type, byte[] message, int offset, int length, int fullLength, byte[] dummyData) { /* * Actual MAC only calculated on 'length' bytes... */ byte[] result = calculateMac(seqNo, type, message, offset, length); /* * ...but ensure a constant number of complete digest blocks are processed (as many as would * be needed for 'fullLength' bytes of input). */ int headerLength = context.getServerVersion().isSSL() ? 11 : 13; // How many extra full blocks do we need to calculate? int extra = getDigestBlockCount(headerLength + fullLength) - getDigestBlockCount(headerLength + length); while (--extra >= 0) { mac.update(dummyData, 0, digestBlockSize); } // One more byte in case the implementation is "lazy" about processing blocks mac.update(dummyData[0]); mac.reset(); return result; } private int getDigestBlockCount(int inputLength) { // NOTE: This calculation assumes a minimum of 1 pad byte return (inputLength + digestOverhead) / digestBlockSize; } } bouncycastle-1.49.orig/src/org/bouncycastle/crypto/tls/TlsClientProtocol.java0000644000175000017500000006320012151551725027117 0ustar ebourgebourgpackage org.bouncycastle.crypto.tls; import java.io.ByteArrayInputStream; import java.io.ByteArrayOutputStream; import java.io.IOException; import java.io.InputStream; import java.io.OutputStream; import java.security.SecureRandom; import java.util.Enumeration; import java.util.Hashtable; import java.util.Vector; import org.bouncycastle.crypto.prng.ThreadedSeedGenerator; import org.bouncycastle.util.Arrays; public class TlsClientProtocol extends TlsProtocol { protected TlsClient tlsClient = null; protected TlsClientContextImpl tlsClientContext = null; protected int[] offeredCipherSuites = null; protected short[] offeredCompressionMethods = null; protected Hashtable clientExtensions = null; protected int selectedCipherSuite; protected short selectedCompressionMethod; protected TlsKeyExchange keyExchange = null; protected TlsAuthentication authentication = null; protected CertificateRequest certificateRequest = null; private static SecureRandom createSecureRandom() { /* * We use our threaded seed generator to generate a good random seed. If the user has a * better random seed, he should use the constructor with a SecureRandom. */ ThreadedSeedGenerator tsg = new ThreadedSeedGenerator(); SecureRandom random = new SecureRandom(); /* * Hopefully, 20 bytes in fast mode are good enough. */ random.setSeed(tsg.generateSeed(20, true)); return random; } public TlsClientProtocol(InputStream input, OutputStream output) { this(input, output, createSecureRandom()); } public TlsClientProtocol(InputStream input, OutputStream output, SecureRandom secureRandom) { super(input, output, secureRandom); } /** * Initiates a TLS handshake in the role of client * * @param tlsClient * @throws IOException If handshake was not successful. */ public void connect(TlsClient tlsClient) throws IOException { if (tlsClient == null) { throw new IllegalArgumentException("'tlsClient' cannot be null"); } if (this.tlsClient != null) { throw new IllegalStateException("connect can only be called once"); } this.tlsClient = tlsClient; this.securityParameters = new SecurityParameters(); this.securityParameters.entity = ConnectionEnd.client; this.securityParameters.clientRandom = createRandomBlock(secureRandom); this.tlsClientContext = new TlsClientContextImpl(secureRandom, securityParameters); this.tlsClient.init(tlsClientContext); this.recordStream.init(tlsClientContext); sendClientHelloMessage(); this.connection_state = CS_CLIENT_HELLO; completeHandshake(); this.tlsClient.notifyHandshakeComplete(); } protected AbstractTlsContext getContext() { return tlsClientContext; } protected TlsPeer getPeer() { return tlsClient; } protected void handleChangeCipherSpecMessage() throws IOException { switch (this.connection_state) { case CS_CLIENT_FINISHED: { if (this.expectSessionTicket) { /* * RFC 5077 3.3. This message MUST be sent if the server included a SessionTicket * extension in the ServerHello. */ this.failWithError(AlertLevel.fatal, AlertDescription.handshake_failure); } // NB: Fall through to next case label } case CS_SERVER_SESSION_TICKET: this.connection_state = CS_SERVER_CHANGE_CIPHER_SPEC; break; default: this.failWithError(AlertLevel.fatal, AlertDescription.handshake_failure); } } protected void handleHandshakeMessage(short type, byte[] data) throws IOException { ByteArrayInputStream buf = new ByteArrayInputStream(data); switch (type) { case HandshakeType.certificate: { switch (this.connection_state) { case CS_SERVER_HELLO: { handleSupplementalData(null); // NB: Fall through to next case label } case CS_SERVER_SUPPLEMENTAL_DATA: { // Parse the Certificate message and send to cipher suite Certificate serverCertificate = Certificate.parse(buf); assertEmpty(buf); this.keyExchange.processServerCertificate(serverCertificate); this.authentication = tlsClient.getAuthentication(); this.authentication.notifyServerCertificate(serverCertificate); break; } default: this.failWithError(AlertLevel.fatal, AlertDescription.unexpected_message); } this.connection_state = CS_SERVER_CERTIFICATE; break; } case HandshakeType.finished: switch (this.connection_state) { case CS_SERVER_CHANGE_CIPHER_SPEC: processFinishedMessage(buf); this.connection_state = CS_SERVER_FINISHED; break; default: this.failWithError(AlertLevel.fatal, AlertDescription.unexpected_message); } break; case HandshakeType.server_hello: switch (this.connection_state) { case CS_CLIENT_HELLO: receiveServerHelloMessage(buf); this.connection_state = CS_SERVER_HELLO; securityParameters.prfAlgorithm = getPRFAlgorithm(selectedCipherSuite); securityParameters.compressionAlgorithm = this.selectedCompressionMethod; /* * RFC 5264 7.4.9. Any cipher suite which does not explicitly specify * verify_data_length has a verify_data_length equal to 12. This includes all * existing cipher suites. */ securityParameters.verifyDataLength = 12; recordStream.notifyHelloComplete(); break; default: this.failWithError(AlertLevel.fatal, AlertDescription.unexpected_message); } break; case HandshakeType.supplemental_data: { switch (this.connection_state) { case CS_SERVER_HELLO: handleSupplementalData(readSupplementalDataMessage(buf)); break; default: this.failWithError(AlertLevel.fatal, AlertDescription.unexpected_message); } break; } case HandshakeType.server_hello_done: switch (this.connection_state) { case CS_SERVER_HELLO: { handleSupplementalData(null); // NB: Fall through to next case label } case CS_SERVER_SUPPLEMENTAL_DATA: { // There was no server certificate message; check it's OK this.keyExchange.skipServerCredentials(); this.authentication = null; // NB: Fall through to next case label } case CS_SERVER_CERTIFICATE: // There was no server key exchange message; check it's OK this.keyExchange.skipServerKeyExchange(); // NB: Fall through to next case label case CS_SERVER_KEY_EXCHANGE: case CS_CERTIFICATE_REQUEST: assertEmpty(buf); this.connection_state = CS_SERVER_HELLO_DONE; Vector clientSupplementalData = tlsClient.getClientSupplementalData(); if (clientSupplementalData != null) { sendSupplementalDataMessage(clientSupplementalData); } this.connection_state = CS_CLIENT_SUPPLEMENTAL_DATA; TlsCredentials clientCreds = null; if (certificateRequest == null) { this.keyExchange.skipClientCredentials(); } else { clientCreds = this.authentication.getClientCredentials(certificateRequest); if (clientCreds == null) { this.keyExchange.skipClientCredentials(); /* * RFC 5246 If no suitable certificate is available, the client MUST send a * certificate message containing no certificates. * * NOTE: In previous RFCs, this was SHOULD instead of MUST. */ sendCertificateMessage(Certificate.EMPTY_CHAIN); } else { this.keyExchange.processClientCredentials(clientCreds); sendCertificateMessage(clientCreds.getCertificate()); } } this.connection_state = CS_CLIENT_CERTIFICATE; /* * Send the client key exchange message, depending on the key exchange we are using * in our CipherSuite. */ sendClientKeyExchangeMessage(); establishMasterSecret(getContext(), keyExchange); /* * Initialize our cipher suite */ recordStream.setPendingConnectionState(tlsClient.getCompression(), tlsClient.getCipher()); this.connection_state = CS_CLIENT_KEY_EXCHANGE; if (clientCreds != null && clientCreds instanceof TlsSignerCredentials) { /* * TODO RFC 5246 4.7. digitally-signed element needs SignatureAndHashAlgorithm * prepended from TLS 1.2 */ TlsSignerCredentials signerCreds = (TlsSignerCredentials)clientCreds; byte[] md5andsha1 = recordStream.getCurrentHash(null); byte[] clientCertificateSignature = signerCreds.generateCertificateSignature(md5andsha1); sendCertificateVerifyMessage(clientCertificateSignature); this.connection_state = CS_CERTIFICATE_VERIFY; } sendChangeCipherSpecMessage(); this.connection_state = CS_CLIENT_CHANGE_CIPHER_SPEC; sendFinishedMessage(); this.connection_state = CS_CLIENT_FINISHED; break; default: this.failWithError(AlertLevel.fatal, AlertDescription.handshake_failure); } break; case HandshakeType.server_key_exchange: { switch (this.connection_state) { case CS_SERVER_HELLO: { handleSupplementalData(null); // NB: Fall through to next case label } case CS_SERVER_SUPPLEMENTAL_DATA: { // There was no server certificate message; check it's OK this.keyExchange.skipServerCredentials(); this.authentication = null; // NB: Fall through to next case label } case CS_SERVER_CERTIFICATE: this.keyExchange.processServerKeyExchange(buf); assertEmpty(buf); break; default: this.failWithError(AlertLevel.fatal, AlertDescription.unexpected_message); } this.connection_state = CS_SERVER_KEY_EXCHANGE; break; } case HandshakeType.certificate_request: { switch (this.connection_state) { case CS_SERVER_CERTIFICATE: // There was no server key exchange message; check it's OK this.keyExchange.skipServerKeyExchange(); // NB: Fall through to next case label case CS_SERVER_KEY_EXCHANGE: { if (this.authentication == null) { /* * RFC 2246 7.4.4. It is a fatal handshake_failure alert for an anonymous server * to request client identification. */ this.failWithError(AlertLevel.fatal, AlertDescription.handshake_failure); } this.certificateRequest = CertificateRequest.parse(buf); assertEmpty(buf); this.keyExchange.validateCertificateRequest(this.certificateRequest); break; } default: this.failWithError(AlertLevel.fatal, AlertDescription.unexpected_message); } this.connection_state = CS_CERTIFICATE_REQUEST; break; } case HandshakeType.session_ticket: { switch (this.connection_state) { case CS_CLIENT_FINISHED: if (!this.expectSessionTicket) { /* * RFC 5077 3.3. This message MUST NOT be sent if the server did not include a * SessionTicket extension in the ServerHello. */ this.failWithError(AlertLevel.fatal, AlertDescription.unexpected_message); } receiveNewSessionTicketMessage(buf); this.connection_state = CS_SERVER_SESSION_TICKET; break; default: this.failWithError(AlertLevel.fatal, AlertDescription.unexpected_message); } } case HandshakeType.hello_request: assertEmpty(buf); /* * RFC 2246 7.4.1.1 Hello request This message will be ignored by the client if the * client is currently negotiating a session. This message may be ignored by the client * if it does not wish to renegotiate a session, or the client may, if it wishes, * respond with a no_renegotiation alert. */ if (this.connection_state == CS_SERVER_FINISHED) { String message = "Renegotiation not supported"; raiseWarning(AlertDescription.no_renegotiation, message); } break; case HandshakeType.client_key_exchange: case HandshakeType.certificate_verify: case HandshakeType.client_hello: case HandshakeType.hello_verify_request: default: // We do not support this! this.failWithError(AlertLevel.fatal, AlertDescription.unexpected_message); break; } } protected void handleSupplementalData(Vector serverSupplementalData) throws IOException { this.tlsClient.processServerSupplementalData(serverSupplementalData); this.connection_state = CS_SERVER_SUPPLEMENTAL_DATA; this.keyExchange = tlsClient.getKeyExchange(); this.keyExchange.init(getContext()); } protected void receiveNewSessionTicketMessage(ByteArrayInputStream buf) throws IOException { NewSessionTicket newSessionTicket = NewSessionTicket.parse(buf); TlsProtocol.assertEmpty(buf); tlsClient.notifyNewSessionTicket(newSessionTicket); } protected void receiveServerHelloMessage(ByteArrayInputStream buf) throws IOException { ProtocolVersion server_version = TlsUtils.readVersion(buf); if (server_version.isDTLS()) { this.failWithError(AlertLevel.fatal, AlertDescription.illegal_parameter); } // Check that this matches what the server is sending in the record layer if (!server_version.equals(recordStream.getReadVersion())) { this.failWithError(AlertLevel.fatal, AlertDescription.illegal_parameter); } ProtocolVersion client_version = getContext().getClientVersion(); if (!server_version.isEqualOrEarlierVersionOf(client_version)) { this.failWithError(AlertLevel.fatal, AlertDescription.illegal_parameter); } this.recordStream.setWriteVersion(server_version); getContext().setServerVersion(server_version); this.tlsClient.notifyServerVersion(server_version); /* * Read the server random */ securityParameters.serverRandom = TlsUtils.readFully(32, buf); byte[] sessionID = TlsUtils.readOpaque8(buf); if (sessionID.length > 32) { this.failWithError(AlertLevel.fatal, AlertDescription.illegal_parameter); } this.tlsClient.notifySessionID(sessionID); /* * Find out which CipherSuite the server has chosen and check that it was one of the offered * ones. */ this.selectedCipherSuite = TlsUtils.readUint16(buf); if (!arrayContains(offeredCipherSuites, this.selectedCipherSuite) || this.selectedCipherSuite == CipherSuite.TLS_NULL_WITH_NULL_NULL || this.selectedCipherSuite == CipherSuite.TLS_EMPTY_RENEGOTIATION_INFO_SCSV) { this.failWithError(AlertLevel.fatal, AlertDescription.illegal_parameter); } this.tlsClient.notifySelectedCipherSuite(this.selectedCipherSuite); /* * Find out which CompressionMethod the server has chosen and check that it was one of the * offered ones. */ short selectedCompressionMethod = TlsUtils.readUint8(buf); if (!arrayContains(offeredCompressionMethods, selectedCompressionMethod)) { this.failWithError(AlertLevel.fatal, AlertDescription.illegal_parameter); } this.tlsClient.notifySelectedCompressionMethod(selectedCompressionMethod); /* * RFC3546 2.2 The extended server hello message format MAY be sent in place of the server * hello message when the client has requested extended functionality via the extended * client hello message specified in Section 2.1. ... Note that the extended server hello * message is only sent in response to an extended client hello message. This prevents the * possibility that the extended server hello message could "break" existing TLS 1.0 * clients. */ /* * TODO RFC 3546 2.3 If [...] the older session is resumed, then the server MUST ignore * extensions appearing in the client hello, and send a server hello containing no * extensions. */ // Integer -> byte[] Hashtable serverExtensions = readExtensions(buf); /* * RFC 3546 2.2 Note that the extended server hello message is only sent in response to an * extended client hello message. * * However, see RFC 5746 exception below. We always include the SCSV, so an Extended Server * Hello is always allowed. */ if (serverExtensions != null) { Enumeration e = serverExtensions.keys(); while (e.hasMoreElements()) { Integer extType = (Integer)e.nextElement(); /* * RFC 5746 3.6. Note that sending a "renegotiation_info" extension in response to a * ClientHello containing only the SCSV is an explicit exception to the prohibition * in RFC 5246, Section 7.4.1.4, on the server sending unsolicited extensions and is * only allowed because the client is signaling its willingness to receive the * extension via the TLS_EMPTY_RENEGOTIATION_INFO_SCSV SCSV. */ if (!extType.equals(EXT_RenegotiationInfo) && (clientExtensions == null || clientExtensions.get(extType) == null)) { /* * RFC 5246 7.4.1.4 An extension type MUST NOT appear in the ServerHello unless * the same extension type appeared in the corresponding ClientHello. If a * client receives an extension type in ServerHello that it did not request in * the associated ClientHello, it MUST abort the handshake with an * unsupported_extension fatal alert. */ this.failWithError(AlertLevel.fatal, AlertDescription.unsupported_extension); } } /* * RFC 5746 3.4. Client Behavior: Initial Handshake */ { /* * When a ServerHello is received, the client MUST check if it includes the * "renegotiation_info" extension: */ byte[] renegExtValue = (byte[])serverExtensions.get(EXT_RenegotiationInfo); if (renegExtValue != null) { /* * If the extension is present, set the secure_renegotiation flag to TRUE. The * client MUST then verify that the length of the "renegotiated_connection" * field is zero, and if it is not, MUST abort the handshake (by sending a fatal * handshake_failure alert). */ this.secure_renegotiation = true; if (!Arrays.constantTimeAreEqual(renegExtValue, createRenegotiationInfo(TlsUtils.EMPTY_BYTES))) { this.failWithError(AlertLevel.fatal, AlertDescription.handshake_failure); } } } this.expectSessionTicket = serverExtensions.containsKey(EXT_SessionTicket); } tlsClient.notifySecureRenegotiation(this.secure_renegotiation); if (clientExtensions != null) { tlsClient.processServerExtensions(serverExtensions); } } protected void sendCertificateVerifyMessage(byte[] data) throws IOException { /* * Send signature of handshake messages so far to prove we are the owner of the cert See RFC * 2246 sections 4.7, 7.4.3 and 7.4.8 */ ByteArrayOutputStream bos = new ByteArrayOutputStream(); TlsUtils.writeUint8(HandshakeType.certificate_verify, bos); TlsUtils.writeUint24(data.length + 2, bos); TlsUtils.writeOpaque16(data, bos); byte[] message = bos.toByteArray(); safeWriteRecord(ContentType.handshake, message, 0, message.length); } protected void sendClientHelloMessage() throws IOException { recordStream.setWriteVersion(this.tlsClient.getClientHelloRecordLayerVersion()); ByteArrayOutputStream buf = new ByteArrayOutputStream(); TlsUtils.writeUint8(HandshakeType.client_hello, buf); // Reserve space for length TlsUtils.writeUint24(0, buf); ProtocolVersion client_version = this.tlsClient.getClientVersion(); if (client_version.isDTLS()) { this.failWithError(AlertLevel.fatal, AlertDescription.internal_error); } getContext().setClientVersion(client_version); TlsUtils.writeVersion(client_version, buf); buf.write(securityParameters.clientRandom); // Session id TlsUtils.writeOpaque8(TlsUtils.EMPTY_BYTES, buf); /* * Cipher suites */ this.offeredCipherSuites = this.tlsClient.getCipherSuites(); // Integer -> byte[] this.clientExtensions = this.tlsClient.getClientExtensions(); // Cipher Suites (and SCSV) { /* * RFC 5746 3.4. The client MUST include either an empty "renegotiation_info" extension, * or the TLS_EMPTY_RENEGOTIATION_INFO_SCSV signaling cipher suite value in the * ClientHello. Including both is NOT RECOMMENDED. */ boolean noRenegExt = clientExtensions == null || clientExtensions.get(EXT_RenegotiationInfo) == null; int count = offeredCipherSuites.length; if (noRenegExt) { // Note: 1 extra slot for TLS_EMPTY_RENEGOTIATION_INFO_SCSV ++count; } TlsUtils.writeUint16(2 * count, buf); TlsUtils.writeUint16Array(offeredCipherSuites, buf); if (noRenegExt) { TlsUtils.writeUint16(CipherSuite.TLS_EMPTY_RENEGOTIATION_INFO_SCSV, buf); } } // Compression methods this.offeredCompressionMethods = this.tlsClient.getCompressionMethods(); TlsUtils.writeUint8((short)offeredCompressionMethods.length, buf); TlsUtils.writeUint8Array(offeredCompressionMethods, buf); // Extensions if (clientExtensions != null) { writeExtensions(buf, clientExtensions); } byte[] message = buf.toByteArray(); // Patch actual length back in TlsUtils.writeUint24(message.length - 4, message, 1); safeWriteRecord(ContentType.handshake, message, 0, message.length); } protected void sendClientKeyExchangeMessage() throws IOException { ByteArrayOutputStream bos = new ByteArrayOutputStream(); TlsUtils.writeUint8(HandshakeType.client_key_exchange, bos); // Reserve space for length TlsUtils.writeUint24(0, bos); this.keyExchange.generateClientKeyExchange(bos); byte[] message = bos.toByteArray(); // Patch actual length back in TlsUtils.writeUint24(message.length - 4, message, 1); safeWriteRecord(ContentType.handshake, message, 0, message.length); } } bouncycastle-1.49.orig/src/org/bouncycastle/crypto/tls/KeyExchangeAlgorithm.java0000644000175000017500000000254712146535331027544 0ustar ebourgebourgpackage org.bouncycastle.crypto.tls; /** * RFC 2246 *

    * Note that the values here are implementation-specific and arbitrary. It is recommended not to * depend on the particular values (e.g. serialization). */ public class KeyExchangeAlgorithm { public static final int NULL = 0; public static final int RSA = 1; public static final int RSA_EXPORT = 2; public static final int DHE_DSS = 3; public static final int DHE_DSS_EXPORT = 4; public static final int DHE_RSA = 5; public static final int DHE_RSA_EXPORT = 6; public static final int DH_DSS = 7; public static final int DH_DSS_EXPORT = 8; public static final int DH_RSA = 9; public static final int DH_RSA_EXPORT = 10; public static final int DH_anon = 11; public static final int DH_anon_EXPORT = 12; /* * RFC 4279 */ public static final int PSK = 13; public static final int DHE_PSK = 14; public static final int RSA_PSK = 15; /* * RFC 4429 */ public static final int ECDH_ECDSA = 16; public static final int ECDHE_ECDSA = 17; public static final int ECDH_RSA = 18; public static final int ECDHE_RSA = 19; public static final int ECDH_anon = 20; /* * RFC 5054 */ public static final int SRP = 21; public static final int SRP_DSS = 22; public static final int SRP_RSA = 23; } bouncycastle-1.49.orig/src/org/bouncycastle/crypto/tls/TlsSignerCredentials.java0000644000175000017500000000033712146535331027565 0ustar ebourgebourgpackage org.bouncycastle.crypto.tls; import java.io.IOException; public interface TlsSignerCredentials extends TlsCredentials { byte[] generateCertificateSignature(byte[] md5andsha1) throws IOException; } bouncycastle-1.49.orig/src/org/bouncycastle/crypto/tls/TlsCompression.java0000644000175000017500000000031312146534067026460 0ustar ebourgebourgpackage org.bouncycastle.crypto.tls; import java.io.OutputStream; public interface TlsCompression { OutputStream compress(OutputStream output); OutputStream decompress(OutputStream output); } bouncycastle-1.49.orig/src/org/bouncycastle/crypto/tls/DeferredHash.java0000644000175000017500000000500712151551725026021 0ustar ebourgebourgpackage org.bouncycastle.crypto.tls; import java.io.ByteArrayOutputStream; import org.bouncycastle.crypto.Digest; /** * Buffers input until the hash algorithm is determined. */ class DeferredHash implements TlsHandshakeHash { protected TlsContext context; private ByteArrayOutputStream buf = new ByteArrayOutputStream(); private int prfAlgorithm = -1; private Digest hash = null; DeferredHash() { this.buf = new ByteArrayOutputStream(); this.hash = null; } private DeferredHash(Digest hash) { this.buf = null; this.hash = hash; } public void init(TlsContext context) { this.context = context; } public TlsHandshakeHash commit() { int prfAlgorithm = context.getSecurityParameters().getPrfAlgorithm(); Digest prfHash = TlsUtils.createPRFHash(prfAlgorithm); byte[] data = buf.toByteArray(); prfHash.update(data, 0, data.length); if (prfHash instanceof TlsHandshakeHash) { TlsHandshakeHash tlsPRFHash = (TlsHandshakeHash)prfHash; tlsPRFHash.init(context); return tlsPRFHash.commit(); } this.prfAlgorithm = prfAlgorithm; this.hash = prfHash; this.buf = null; return this; } public TlsHandshakeHash fork() { checkHash(); return new DeferredHash(TlsUtils.clonePRFHash(prfAlgorithm, hash)); } public String getAlgorithmName() { checkHash(); return hash.getAlgorithmName(); } public int getDigestSize() { checkHash(); return hash.getDigestSize(); } public void update(byte input) { if (hash == null) { buf.write(input); } else { hash.update(input); } } public void update(byte[] input, int inOff, int len) { if (hash == null) { buf.write(input, inOff, len); } else { hash.update(input, inOff, len); } } public int doFinal(byte[] output, int outOff) { checkHash(); return hash.doFinal(output, outOff); } public void reset() { if (hash == null) { buf.reset(); } else { hash.reset(); } } protected void checkHash() { if (hash == null) { throw new IllegalStateException("No hash algorithm has been set"); } } } bouncycastle-1.49.orig/src/org/bouncycastle/crypto/tls/TlsPSKIdentity.java0000644000175000017500000000032312146535331026322 0ustar ebourgebourgpackage org.bouncycastle.crypto.tls; public interface TlsPSKIdentity { void skipIdentityHint(); void notifyIdentityHint(byte[] psk_identity_hint); byte[] getPSKIdentity(); byte[] getPSK(); } bouncycastle-1.49.orig/src/org/bouncycastle/crypto/tls/AlwaysValidVerifyer.java0000644000175000017500000000115212146535331027425 0ustar ebourgebourgpackage org.bouncycastle.crypto.tls; /** * A certificate verifyer, that will always return true. *

    *

     * DO NOT USE THIS FILE UNLESS YOU KNOW EXACTLY WHAT YOU ARE DOING.
     * 
    * * @deprecated Perform certificate verification in TlsAuthentication implementation */ public class AlwaysValidVerifyer implements CertificateVerifyer { /** * Return true. * * @see org.bouncycastle.crypto.tls.CertificateVerifyer#isValid(org.bouncycastle.asn1.x509.Certificate[]) */ public boolean isValid(org.bouncycastle.asn1.x509.Certificate[] certs) { return true; } } bouncycastle-1.49.orig/src/org/bouncycastle/crypto/tls/UseSRTPData.java0000644000175000017500000000237312151551725025537 0ustar ebourgebourgpackage org.bouncycastle.crypto.tls; /** * RFC 5764 4.1.1 */ public class UseSRTPData { private int[] protectionProfiles; private byte[] mki; /** * @param protectionProfiles see {@link SRTPProtectionProfile} for valid constants. * @param mki valid lengths from 0 to 255. */ public UseSRTPData(int[] protectionProfiles, byte[] mki) { if (protectionProfiles == null || protectionProfiles.length < 1 || protectionProfiles.length >= (1 << 15)) { throw new IllegalArgumentException( "'protectionProfiles' must have length from 1 to (2^15 - 1)"); } if (mki == null) { mki = TlsUtils.EMPTY_BYTES; } else if (mki.length > 255) { throw new IllegalArgumentException("'mki' cannot be longer than 255 bytes"); } this.protectionProfiles = protectionProfiles; this.mki = mki; } /** * @return see {@link SRTPProtectionProfile} for valid constants. */ public int[] getProtectionProfiles() { return protectionProfiles; } /** * @return valid lengths from 0 to 255. */ public byte[] getMki() { return mki; } } bouncycastle-1.49.orig/src/org/bouncycastle/crypto/tls/TlsDHEKeyExchange.java0000644000175000017500000000776712151551725026713 0ustar ebourgebourgpackage org.bouncycastle.crypto.tls; import java.io.ByteArrayOutputStream; import java.io.IOException; import java.io.InputStream; import java.math.BigInteger; import java.util.Vector; import org.bouncycastle.crypto.AsymmetricCipherKeyPair; import org.bouncycastle.crypto.Digest; import org.bouncycastle.crypto.Signer; import org.bouncycastle.crypto.generators.DHKeyPairGenerator; import org.bouncycastle.crypto.io.SignerInputStream; import org.bouncycastle.crypto.params.DHKeyGenerationParameters; import org.bouncycastle.crypto.params.DHParameters; import org.bouncycastle.crypto.params.DHPublicKeyParameters; public class TlsDHEKeyExchange extends TlsDHKeyExchange { protected TlsSignerCredentials serverCredentials = null; public TlsDHEKeyExchange(int keyExchange, Vector supportedSignatureAlgorithms, DHParameters dhParameters) { super(keyExchange, supportedSignatureAlgorithms, dhParameters); } public void processServerCredentials(TlsCredentials serverCredentials) throws IOException { if (!(serverCredentials instanceof TlsSignerCredentials)) { throw new TlsFatalAlert(AlertDescription.internal_error); } processServerCertificate(serverCredentials.getCertificate()); this.serverCredentials = (TlsSignerCredentials)serverCredentials; } public byte[] generateServerKeyExchange() throws IOException { if (this.dhParameters == null) { throw new TlsFatalAlert(AlertDescription.internal_error); } ByteArrayOutputStream buf = new ByteArrayOutputStream(); DHKeyPairGenerator kpg = new DHKeyPairGenerator(); kpg.init(new DHKeyGenerationParameters(context.getSecureRandom(), this.dhParameters)); AsymmetricCipherKeyPair kp = kpg.generateKeyPair(); BigInteger Ys = ((DHPublicKeyParameters)kp.getPublic()).getY(); TlsDHUtils.writeDHParameter(dhParameters.getP(), buf); TlsDHUtils.writeDHParameter(dhParameters.getG(), buf); TlsDHUtils.writeDHParameter(Ys, buf); byte[] digestInput = buf.toByteArray(); Digest d = new CombinedHash(); SecurityParameters securityParameters = context.getSecurityParameters(); d.update(securityParameters.clientRandom, 0, securityParameters.clientRandom.length); d.update(securityParameters.serverRandom, 0, securityParameters.serverRandom.length); d.update(digestInput, 0, digestInput.length); byte[] hash = new byte[d.getDigestSize()]; d.doFinal(hash, 0); byte[] sigBytes = serverCredentials.generateCertificateSignature(hash); /* * TODO RFC 5246 4.7. digitally-signed element needs SignatureAndHashAlgorithm prepended from TLS 1.2 */ TlsUtils.writeOpaque16(sigBytes, buf); return buf.toByteArray(); } public void processServerKeyExchange(InputStream input) throws IOException { SecurityParameters securityParameters = context.getSecurityParameters(); Signer signer = initVerifyer(tlsSigner, securityParameters); InputStream sigIn = new SignerInputStream(input, signer); BigInteger p = TlsDHUtils.readDHParameter(sigIn); BigInteger g = TlsDHUtils.readDHParameter(sigIn); BigInteger Ys = TlsDHUtils.readDHParameter(sigIn); byte[] sigBytes = TlsUtils.readOpaque16(input); if (!signer.verifySignature(sigBytes)) { throw new TlsFatalAlert(AlertDescription.decrypt_error); } this.dhAgreeServerPublicKey = validateDHPublicKey(new DHPublicKeyParameters(Ys, new DHParameters(p, g))); } protected Signer initVerifyer(TlsSigner tlsSigner, SecurityParameters securityParameters) { Signer signer = tlsSigner.createVerifyer(this.serverPublicKey); signer.update(securityParameters.clientRandom, 0, securityParameters.clientRandom.length); signer.update(securityParameters.serverRandom, 0, securityParameters.serverRandom.length); return signer; } } bouncycastle-1.49.orig/src/org/bouncycastle/crypto/tls/TlsClientContextImpl.java0000644000175000017500000000060212146535331027560 0ustar ebourgebourgpackage org.bouncycastle.crypto.tls; import java.security.SecureRandom; class TlsClientContextImpl extends AbstractTlsContext implements TlsClientContext { TlsClientContextImpl(SecureRandom secureRandom, SecurityParameters securityParameters) { super(secureRandom, securityParameters); } public boolean isServer() { return false; } } bouncycastle-1.49.orig/src/org/bouncycastle/crypto/tls/AbstractTlsClient.java0000644000175000017500000001501712151551725027064 0ustar ebourgebourgpackage org.bouncycastle.crypto.tls; import java.io.IOException; import java.util.Hashtable; import java.util.Vector; public abstract class AbstractTlsClient extends AbstractTlsPeer implements TlsClient { protected TlsCipherFactory cipherFactory; protected TlsClientContext context; protected Vector supportedSignatureAlgorithms; protected int selectedCipherSuite; protected short selectedCompressionMethod; public AbstractTlsClient() { this(new DefaultTlsCipherFactory()); } public AbstractTlsClient(TlsCipherFactory cipherFactory) { this.cipherFactory = cipherFactory; } public void init(TlsClientContext context) { this.context = context; } /** * RFC 5246 E.1. "TLS clients that wish to negotiate with older servers MAY send any value * {03,XX} as the record layer version number. Typical values would be {03,00}, the lowest * version number supported by the client, and the value of ClientHello.client_version. No * single value will guarantee interoperability with all old servers, but this is a complex * topic beyond the scope of this document." */ public ProtocolVersion getClientHelloRecordLayerVersion() { // "{03,00}" // return ProtocolVersion.SSLv3; // "the lowest version number supported by the client" // return getMinimumServerVersion(); // "the value of ClientHello.client_version" return getClientVersion(); } public ProtocolVersion getClientVersion() { return ProtocolVersion.TLSv11; } public Hashtable getClientExtensions() throws IOException { Hashtable clientExtensions = null; ProtocolVersion clientVersion = context.getClientVersion(); /* * RFC 5246 7.4.1.4.1. Note: this extension is not meaningful for TLS versions prior to 1.2. * Clients MUST NOT offer it if they are offering prior versions. */ if (TlsUtils.isSignatureAlgorithmsExtensionAllowed(clientVersion)) { // TODO Provide a way for the user to specify the acceptable hash/signature algorithms. short[] hashAlgorithms = new short[]{HashAlgorithm.sha512, HashAlgorithm.sha384, HashAlgorithm.sha256, HashAlgorithm.sha224, HashAlgorithm.sha1}; // TODO Sort out ECDSA signatures and add them as the preferred option here short[] signatureAlgorithms = new short[]{SignatureAlgorithm.rsa}; this.supportedSignatureAlgorithms = new Vector(); for (int i = 0; i < hashAlgorithms.length; ++i) { for (int j = 0; j < signatureAlgorithms.length; ++j) { this.supportedSignatureAlgorithms.addElement(new SignatureAndHashAlgorithm(hashAlgorithms[i], signatureAlgorithms[j])); } } /* * RFC 5264 7.4.3. Currently, DSA [DSS] may only be used with SHA-1. */ this.supportedSignatureAlgorithms.addElement(new SignatureAndHashAlgorithm(HashAlgorithm.sha1, SignatureAlgorithm.dsa)); if (clientExtensions == null) { clientExtensions = new Hashtable(); } TlsUtils.addSignatureAlgorithmsExtension(clientExtensions, supportedSignatureAlgorithms); } return clientExtensions; } public ProtocolVersion getMinimumVersion() { return ProtocolVersion.TLSv10; } public void notifyServerVersion(ProtocolVersion serverVersion) throws IOException { if (!getMinimumVersion().isEqualOrEarlierVersionOf(serverVersion)) { throw new TlsFatalAlert(AlertDescription.protocol_version); } } public short[] getCompressionMethods() { return new short[]{CompressionMethod._null}; } public void notifySessionID(byte[] sessionID) { // Currently ignored } public void notifySelectedCipherSuite(int selectedCipherSuite) { this.selectedCipherSuite = selectedCipherSuite; } public void notifySelectedCompressionMethod(short selectedCompressionMethod) { this.selectedCompressionMethod = selectedCompressionMethod; } public void notifySecureRenegotiation(boolean secureRenegotiation) throws IOException { if (!secureRenegotiation) { /* * RFC 5746 3.4. In this case, some clients may want to terminate the handshake instead * of continuing; see Section 4.1 for discussion. */ // throw new TlsFatalAlert(AlertDescription.handshake_failure); } } public void processServerExtensions(Hashtable serverExtensions) throws IOException { /* * TlsProtocol implementation validates that any server extensions received correspond to * client extensions sent. By default, we don't send any, and this method is not called. */ if (serverExtensions != null) { /* * RFC 5246 7.4.1.4.1. Servers MUST NOT send this extension. */ if (serverExtensions.containsKey(TlsUtils.EXT_signature_algorithms)) { throw new TlsFatalAlert(AlertDescription.illegal_parameter); } } } public void processServerSupplementalData(Vector serverSupplementalData) throws IOException { if (serverSupplementalData != null) { throw new TlsFatalAlert(AlertDescription.unexpected_message); } } public Vector getClientSupplementalData() throws IOException { return null; } public TlsCompression getCompression() throws IOException { switch (selectedCompressionMethod) { case CompressionMethod._null: return new TlsNullCompression(); default: /* * Note: internal error here; the TlsProtocol implementation verifies that the * server-selected compression method was in the list of client-offered compression * methods, so if we now can't produce an implementation, we shouldn't have offered it! */ throw new TlsFatalAlert(AlertDescription.internal_error); } } public void notifyNewSessionTicket(NewSessionTicket newSessionTicket) throws IOException { } public void notifyHandshakeComplete() throws IOException { } } bouncycastle-1.49.orig/src/org/bouncycastle/crypto/tls/TlsServerProtocol.java0000644000175000017500000006447312151551725027164 0ustar ebourgebourgpackage org.bouncycastle.crypto.tls; import java.io.ByteArrayInputStream; import java.io.ByteArrayOutputStream; import java.io.IOException; import java.io.InputStream; import java.io.OutputStream; import java.security.SecureRandom; import java.util.Hashtable; import java.util.Vector; import org.bouncycastle.asn1.x509.SubjectPublicKeyInfo; import org.bouncycastle.crypto.params.AsymmetricKeyParameter; import org.bouncycastle.crypto.util.PublicKeyFactory; import org.bouncycastle.util.Arrays; public class TlsServerProtocol extends TlsProtocol { protected TlsServer tlsServer = null; protected TlsServerContextImpl tlsServerContext = null; protected int[] offeredCipherSuites; protected short[] offeredCompressionMethods; protected Hashtable clientExtensions; protected int selectedCipherSuite; protected short selectedCompressionMethod; protected Hashtable serverExtensions; protected TlsKeyExchange keyExchange = null; protected TlsCredentials serverCredentials = null; protected CertificateRequest certificateRequest = null; protected short clientCertificateType = -1; protected Certificate clientCertificate = null; protected byte[] certificateVerifyHash = null; public TlsServerProtocol(InputStream input, OutputStream output, SecureRandom secureRandom) { super(input, output, secureRandom); } /** * Receives a TLS handshake in the role of server * * @param tlsServer * @throws IOException If handshake was not successful. */ public void accept(TlsServer tlsServer) throws IOException { if (tlsServer == null) { throw new IllegalArgumentException("'tlsServer' cannot be null"); } if (this.tlsServer != null) { throw new IllegalStateException("accept can only be called once"); } this.tlsServer = tlsServer; this.securityParameters = new SecurityParameters(); this.securityParameters.entity = ConnectionEnd.server; this.securityParameters.serverRandom = createRandomBlock(secureRandom); this.tlsServerContext = new TlsServerContextImpl(secureRandom, securityParameters); this.tlsServer.init(tlsServerContext); this.recordStream.init(tlsServerContext); this.recordStream.setRestrictReadVersion(false); completeHandshake(); this.tlsServer.notifyHandshakeComplete(); } protected AbstractTlsContext getContext() { return tlsServerContext; } protected TlsPeer getPeer() { return tlsServer; } protected void handleChangeCipherSpecMessage() throws IOException { switch (this.connection_state) { case CS_CLIENT_KEY_EXCHANGE: { if (this.certificateVerifyHash != null) { this.failWithError(AlertLevel.fatal, AlertDescription.unexpected_message); } // NB: Fall through to next case label } case CS_CERTIFICATE_VERIFY: { this.connection_state = CS_CLIENT_CHANGE_CIPHER_SPEC; break; } default: { this.failWithError(AlertLevel.fatal, AlertDescription.handshake_failure); } } } protected void handleHandshakeMessage(short type, byte[] data) throws IOException { ByteArrayInputStream buf = new ByteArrayInputStream(data); switch (type) { case HandshakeType.client_hello: { switch (this.connection_state) { case CS_START: { receiveClientHelloMessage(buf); this.connection_state = CS_CLIENT_HELLO; sendServerHelloMessage(); this.connection_state = CS_SERVER_HELLO; // TODO This block could really be done before actually sending the hello { securityParameters.prfAlgorithm = getPRFAlgorithm(selectedCipherSuite); securityParameters.compressionAlgorithm = this.selectedCompressionMethod; /* * RFC 5264 7.4.9. Any cipher suite which does not explicitly specify * verify_data_length has a verify_data_length equal to 12. This includes all * existing cipher suites. */ securityParameters.verifyDataLength = 12; recordStream.notifyHelloComplete(); } Vector serverSupplementalData = tlsServer.getServerSupplementalData(); if (serverSupplementalData != null) { sendSupplementalDataMessage(serverSupplementalData); } this.connection_state = CS_SERVER_SUPPLEMENTAL_DATA; this.keyExchange = tlsServer.getKeyExchange(); this.keyExchange.init(getContext()); this.serverCredentials = tlsServer.getCredentials(); if (this.serverCredentials == null) { this.keyExchange.skipServerCredentials(); } else { this.keyExchange.processServerCredentials(this.serverCredentials); sendCertificateMessage(this.serverCredentials.getCertificate()); } this.connection_state = CS_SERVER_CERTIFICATE; byte[] serverKeyExchange = this.keyExchange.generateServerKeyExchange(); if (serverKeyExchange != null) { sendServerKeyExchangeMessage(serverKeyExchange); } this.connection_state = CS_SERVER_KEY_EXCHANGE; if (this.serverCredentials != null) { this.certificateRequest = tlsServer.getCertificateRequest(); if (this.certificateRequest != null) { this.keyExchange.validateCertificateRequest(certificateRequest); sendCertificateRequestMessage(certificateRequest); } } this.connection_state = CS_CERTIFICATE_REQUEST; sendServerHelloDoneMessage(); this.connection_state = CS_SERVER_HELLO_DONE; break; } default: { this.failWithError(AlertLevel.fatal, AlertDescription.unexpected_message); } } break; } case HandshakeType.supplemental_data: { switch (this.connection_state) { case CS_SERVER_HELLO_DONE: { tlsServer.processClientSupplementalData(readSupplementalDataMessage(buf)); this.connection_state = CS_CLIENT_SUPPLEMENTAL_DATA; break; } default: { this.failWithError(AlertLevel.fatal, AlertDescription.unexpected_message); } } break; } case HandshakeType.certificate: { switch (this.connection_state) { case CS_SERVER_HELLO_DONE: { tlsServer.processClientSupplementalData(null); // NB: Fall through to next case label } case CS_CLIENT_SUPPLEMENTAL_DATA: { if (this.certificateRequest == null) { this.failWithError(AlertLevel.fatal, AlertDescription.unexpected_message); } receiveCertificateMessage(buf); this.connection_state = CS_CLIENT_CERTIFICATE; break; } default: { this.failWithError(AlertLevel.fatal, AlertDescription.unexpected_message); } } break; } case HandshakeType.client_key_exchange: { switch (this.connection_state) { case CS_SERVER_HELLO_DONE: { tlsServer.processClientSupplementalData(null); // NB: Fall through to next case label } case CS_CLIENT_SUPPLEMENTAL_DATA: { if (this.certificateRequest == null) { this.keyExchange.skipClientCredentials(); } else { ProtocolVersion equivalentTLSVersion = getContext().getServerVersion().getEquivalentTLSVersion(); if (ProtocolVersion.TLSv12.isEqualOrEarlierVersionOf(equivalentTLSVersion)) { /* * RFC 5246 If no suitable certificate is available, the client MUST send a * certificate message containing no certificates. * * NOTE: In previous RFCs, this was SHOULD instead of MUST. */ this.failWithError(AlertLevel.fatal, AlertDescription.unexpected_message); } else if (equivalentTLSVersion.isSSL()) { if (clientCertificate == null) { this.failWithError(AlertLevel.fatal, AlertDescription.unexpected_message); } } else { notifyClientCertificate(Certificate.EMPTY_CHAIN); } } // NB: Fall through to next case label } case CS_CLIENT_CERTIFICATE: { receiveClientKeyExchangeMessage(buf); this.connection_state = CS_CLIENT_KEY_EXCHANGE; break; } default: { this.failWithError(AlertLevel.fatal, AlertDescription.unexpected_message); } } break; } case HandshakeType.certificate_verify: { switch (this.connection_state) { case CS_CLIENT_KEY_EXCHANGE: { /* * RFC 5246 7.4.8 This message is only sent following a client certificate that has * signing capability (i.e., all certificates except those containing fixed * Diffie-Hellman parameters). */ if (this.certificateVerifyHash == null) { this.failWithError(AlertLevel.fatal, AlertDescription.unexpected_message); } receiveCertificateVerifyMessage(buf); this.connection_state = CS_CERTIFICATE_VERIFY; break; } default: { this.failWithError(AlertLevel.fatal, AlertDescription.unexpected_message); } } break; } case HandshakeType.finished: { switch (this.connection_state) { case CS_CLIENT_CHANGE_CIPHER_SPEC: processFinishedMessage(buf); this.connection_state = CS_CLIENT_FINISHED; if (expectSessionTicket) { sendNewSessionTicketMessage(tlsServer.getNewSessionTicket()); } this.connection_state = CS_SERVER_SESSION_TICKET; sendChangeCipherSpecMessage(); this.connection_state = CS_SERVER_CHANGE_CIPHER_SPEC; sendFinishedMessage(); this.connection_state = CS_SERVER_FINISHED; break; default: this.failWithError(AlertLevel.fatal, AlertDescription.unexpected_message); } break; } case HandshakeType.hello_request: case HandshakeType.hello_verify_request: case HandshakeType.server_hello: case HandshakeType.server_key_exchange: case HandshakeType.certificate_request: case HandshakeType.server_hello_done: case HandshakeType.session_ticket: default: // We do not support this! this.failWithError(AlertLevel.fatal, AlertDescription.unexpected_message); break; } } protected void handleWarningMessage(short description) throws IOException { switch (description) { case AlertDescription.no_certificate: { /* * SSL 3.0 If the server has sent a certificate request Message, the client must send * either the certificate message or a no_certificate alert. */ if (getContext().getServerVersion().isSSL() && certificateRequest != null) { notifyClientCertificate(Certificate.EMPTY_CHAIN); } break; } default: { super.handleWarningMessage(description); } } } protected void notifyClientCertificate(Certificate clientCertificate) throws IOException { if (certificateRequest == null) { throw new IllegalStateException(); } if (this.clientCertificate != null) { throw new TlsFatalAlert(AlertDescription.unexpected_message); } this.clientCertificate = clientCertificate; if (clientCertificate.isEmpty()) { this.keyExchange.skipClientCredentials(); } else { /* * TODO RFC 5246 7.4.6. If the certificate_authorities list in the certificate request * message was non-empty, one of the certificates in the certificate chain SHOULD be * issued by one of the listed CAs. */ this.clientCertificateType = TlsUtils.getClientCertificateType(clientCertificate, this.serverCredentials.getCertificate()); this.keyExchange.processClientCertificate(clientCertificate); } /* * RFC 5246 7.4.6. If the client does not send any certificates, the server MAY at its * discretion either continue the handshake without client authentication, or respond with a * fatal handshake_failure alert. Also, if some aspect of the certificate chain was * unacceptable (e.g., it was not signed by a known, trusted CA), the server MAY at its * discretion either continue the handshake (considering the client unauthenticated) or send * a fatal alert. */ this.tlsServer.notifyClientCertificate(clientCertificate); } protected void receiveCertificateMessage(ByteArrayInputStream buf) throws IOException { Certificate clientCertificate = Certificate.parse(buf); assertEmpty(buf); notifyClientCertificate(clientCertificate); } protected void receiveCertificateVerifyMessage(ByteArrayInputStream buf) throws IOException { byte[] clientCertificateSignature = TlsUtils.readOpaque16(buf); assertEmpty(buf); // Verify the CertificateVerify message contains a correct signature. try { TlsSigner tlsSigner = TlsUtils.createTlsSigner(this.clientCertificateType); tlsSigner.init(getContext()); org.bouncycastle.asn1.x509.Certificate x509Cert = this.clientCertificate.getCertificateAt(0); SubjectPublicKeyInfo keyInfo = x509Cert.getSubjectPublicKeyInfo(); AsymmetricKeyParameter publicKey = PublicKeyFactory.createKey(keyInfo); tlsSigner.verifyRawSignature(clientCertificateSignature, publicKey, this.certificateVerifyHash); } catch (Exception e) { throw new TlsFatalAlert(AlertDescription.decrypt_error); } } protected void receiveClientHelloMessage(ByteArrayInputStream buf) throws IOException { ProtocolVersion client_version = TlsUtils.readVersion(buf); if (client_version.isDTLS()) { this.failWithError(AlertLevel.fatal, AlertDescription.illegal_parameter); } /* * Read the client random */ byte[] client_random = TlsUtils.readFully(32, buf); byte[] sessionID = TlsUtils.readOpaque8(buf); if (sessionID.length > 32) { this.failWithError(AlertLevel.fatal, AlertDescription.illegal_parameter); } int cipher_suites_length = TlsUtils.readUint16(buf); if (cipher_suites_length < 2 || (cipher_suites_length & 1) != 0) { this.failWithError(AlertLevel.fatal, AlertDescription.decode_error); } /* * NOTE: "If the session_id field is not empty (implying a session resumption request) this * vector must include at least the cipher_suite from that session." */ this.offeredCipherSuites = TlsUtils.readUint16Array(cipher_suites_length / 2, buf); int compression_methods_length = TlsUtils.readUint8(buf); if (compression_methods_length < 1) { this.failWithError(AlertLevel.fatal, AlertDescription.illegal_parameter); } this.offeredCompressionMethods = TlsUtils.readUint8Array(compression_methods_length, buf); /* * TODO RFC 3546 2.3 If [...] the older session is resumed, then the server MUST ignore * extensions appearing in the client hello, and send a server hello containing no * extensions. */ this.clientExtensions = readExtensions(buf); getContext().setClientVersion(client_version); tlsServer.notifyClientVersion(client_version); securityParameters.clientRandom = client_random; tlsServer.notifyOfferedCipherSuites(offeredCipherSuites); tlsServer.notifyOfferedCompressionMethods(offeredCompressionMethods); /* * RFC 5746 3.6. Server Behavior: Initial Handshake */ { /* * RFC 5746 3.4. The client MUST include either an empty "renegotiation_info" extension, * or the TLS_EMPTY_RENEGOTIATION_INFO_SCSV signaling cipher suite value in the * ClientHello. Including both is NOT RECOMMENDED. */ /* * When a ClientHello is received, the server MUST check if it includes the * TLS_EMPTY_RENEGOTIATION_INFO_SCSV SCSV. If it does, set the secure_renegotiation flag * to TRUE. */ if (arrayContains(offeredCipherSuites, CipherSuite.TLS_EMPTY_RENEGOTIATION_INFO_SCSV)) { this.secure_renegotiation = true; } /* * The server MUST check if the "renegotiation_info" extension is included in the * ClientHello. */ if (clientExtensions != null) { byte[] renegExtValue = (byte[])clientExtensions.get(EXT_RenegotiationInfo); if (renegExtValue != null) { /* * If the extension is present, set secure_renegotiation flag to TRUE. The * server MUST then verify that the length of the "renegotiated_connection" * field is zero, and if it is not, MUST abort the handshake. */ this.secure_renegotiation = true; if (!Arrays.constantTimeAreEqual(renegExtValue, createRenegotiationInfo(TlsUtils.EMPTY_BYTES))) { this.failWithError(AlertLevel.fatal, AlertDescription.handshake_failure); } } } } tlsServer.notifySecureRenegotiation(this.secure_renegotiation); if (clientExtensions != null) { tlsServer.processClientExtensions(clientExtensions); } } protected void receiveClientKeyExchangeMessage(ByteArrayInputStream buf) throws IOException { this.keyExchange.processClientKeyExchange(buf); assertEmpty(buf); establishMasterSecret(getContext(), keyExchange); /* * Initialize our cipher suite */ recordStream.setPendingConnectionState(tlsServer.getCompression(), tlsServer.getCipher()); if (expectCertificateVerifyMessage()) { this.certificateVerifyHash = recordStream.getCurrentHash(null); } } protected void sendCertificateRequestMessage(CertificateRequest certificateRequest) throws IOException { ByteArrayOutputStream buf = new ByteArrayOutputStream(); TlsUtils.writeUint8(HandshakeType.certificate_request, buf); // Reserve space for length TlsUtils.writeUint24(0, buf); certificateRequest.encode(buf); byte[] message = buf.toByteArray(); // Patch actual length back in TlsUtils.writeUint24(message.length - 4, message, 1); safeWriteRecord(ContentType.handshake, message, 0, message.length); } protected void sendNewSessionTicketMessage(NewSessionTicket newSessionTicket) throws IOException { if (newSessionTicket == null) { throw new TlsFatalAlert(AlertDescription.internal_error); } ByteArrayOutputStream buf = new ByteArrayOutputStream(); TlsUtils.writeUint8(HandshakeType.session_ticket, buf); // Reserve space for length TlsUtils.writeUint24(0, buf); newSessionTicket.encode(buf); byte[] message = buf.toByteArray(); // Patch actual length back in TlsUtils.writeUint24(message.length - 4, message, 1); safeWriteRecord(ContentType.handshake, message, 0, message.length); } protected void sendServerHelloMessage() throws IOException { ByteArrayOutputStream buf = new ByteArrayOutputStream(); TlsUtils.writeUint8(HandshakeType.server_hello, buf); // Reserve space for length TlsUtils.writeUint24(0, buf); ProtocolVersion server_version = tlsServer.getServerVersion(); if (!server_version.isEqualOrEarlierVersionOf(getContext().getClientVersion())) { this.failWithError(AlertLevel.fatal, AlertDescription.internal_error); } recordStream.setReadVersion(server_version); recordStream.setWriteVersion(server_version); recordStream.setRestrictReadVersion(true); getContext().setServerVersion(server_version); TlsUtils.writeVersion(server_version, buf); buf.write(this.securityParameters.serverRandom); /* * The server may return an empty session_id to indicate that the session will not be cached * and therefore cannot be resumed. */ TlsUtils.writeOpaque8(TlsUtils.EMPTY_BYTES, buf); this.selectedCipherSuite = tlsServer.getSelectedCipherSuite(); if (!arrayContains(this.offeredCipherSuites, this.selectedCipherSuite) || this.selectedCipherSuite == CipherSuite.TLS_NULL_WITH_NULL_NULL || this.selectedCipherSuite == CipherSuite.TLS_EMPTY_RENEGOTIATION_INFO_SCSV) { this.failWithError(AlertLevel.fatal, AlertDescription.internal_error); } this.selectedCompressionMethod = tlsServer.getSelectedCompressionMethod(); if (!arrayContains(this.offeredCompressionMethods, this.selectedCompressionMethod)) { this.failWithError(AlertLevel.fatal, AlertDescription.internal_error); } TlsUtils.writeUint16(this.selectedCipherSuite, buf); TlsUtils.writeUint8(this.selectedCompressionMethod, buf); this.serverExtensions = tlsServer.getServerExtensions(); /* * RFC 5746 3.6. Server Behavior: Initial Handshake */ if (this.secure_renegotiation) { boolean noRenegExt = this.serverExtensions == null || !this.serverExtensions.containsKey(EXT_RenegotiationInfo); if (noRenegExt) { /* * Note that sending a "renegotiation_info" extension in response to a ClientHello * containing only the SCSV is an explicit exception to the prohibition in RFC 5246, * Section 7.4.1.4, on the server sending unsolicited extensions and is only allowed * because the client is signaling its willingness to receive the extension via the * TLS_EMPTY_RENEGOTIATION_INFO_SCSV SCSV. */ if (this.serverExtensions == null) { this.serverExtensions = new Hashtable(); } /* * If the secure_renegotiation flag is set to TRUE, the server MUST include an empty * "renegotiation_info" extension in the ServerHello message. */ this.serverExtensions.put(EXT_RenegotiationInfo, createRenegotiationInfo(TlsUtils.EMPTY_BYTES)); } } if (this.serverExtensions != null) { this.expectSessionTicket = serverExtensions.containsKey(EXT_SessionTicket); writeExtensions(buf, this.serverExtensions); } byte[] message = buf.toByteArray(); // Patch actual length back in TlsUtils.writeUint24(message.length - 4, message, 1); safeWriteRecord(ContentType.handshake, message, 0, message.length); } protected void sendServerHelloDoneMessage() throws IOException { byte[] message = new byte[4]; TlsUtils.writeUint8(HandshakeType.server_hello_done, message, 0); TlsUtils.writeUint24(0, message, 1); safeWriteRecord(ContentType.handshake, message, 0, message.length); } protected void sendServerKeyExchangeMessage(byte[] serverKeyExchange) throws IOException { ByteArrayOutputStream bos = new ByteArrayOutputStream(); TlsUtils.writeUint8(HandshakeType.server_key_exchange, bos); TlsUtils.writeUint24(serverKeyExchange.length, bos); bos.write(serverKeyExchange); byte[] message = bos.toByteArray(); safeWriteRecord(ContentType.handshake, message, 0, message.length); } protected boolean expectCertificateVerifyMessage() { return this.clientCertificateType >= 0 && TlsUtils.hasSigningCapability(this.clientCertificateType); } } bouncycastle-1.49.orig/src/org/bouncycastle/crypto/tls/ECCurveType.java0000644000175000017500000000133612146534067025640 0ustar ebourgebourgpackage org.bouncycastle.crypto.tls; /** * RFC 4492 5.4 */ public class ECCurveType { /** * Indicates the elliptic curve domain parameters are conveyed verbosely, and the * underlying finite field is a prime field. */ public static final short explicit_prime = 1; /** * Indicates the elliptic curve domain parameters are conveyed verbosely, and the * underlying finite field is a characteristic-2 field. */ public static final short explicit_char2 = 2; /** * Indicates that a named curve is used. This option SHOULD be used when applicable. */ public static final short named_curve = 3; /* * Values 248 through 255 are reserved for private use. */ } bouncycastle-1.49.orig/src/org/bouncycastle/crypto/tls/TlsDSSSigner.java0000644000175000017500000000101612146535331025754 0ustar ebourgebourgpackage org.bouncycastle.crypto.tls; import org.bouncycastle.crypto.DSA; import org.bouncycastle.crypto.params.AsymmetricKeyParameter; import org.bouncycastle.crypto.params.DSAPublicKeyParameters; import org.bouncycastle.crypto.signers.DSASigner; public class TlsDSSSigner extends TlsDSASigner { public boolean isValidPublicKey(AsymmetricKeyParameter publicKey) { return publicKey instanceof DSAPublicKeyParameters; } protected DSA createDSAImpl() { return new DSASigner(); } } bouncycastle-1.49.orig/src/org/bouncycastle/crypto/tls/TlsContext.java0000644000175000017500000000171112151551725025602 0ustar ebourgebourgpackage org.bouncycastle.crypto.tls; import java.security.SecureRandom; public interface TlsContext { SecureRandom getSecureRandom(); SecurityParameters getSecurityParameters(); boolean isServer(); ProtocolVersion getClientVersion(); ProtocolVersion getServerVersion(); Object getUserObject(); void setUserObject(Object userObject); /** * Export keying material according to RFC 5705: "Keying Material Exporters for TLS". * * @param asciiLabel indicates which application will use the exported keys. * @param context_value allows the application using the exporter to mix its own data with the TLS PRF for * the exporter output. * @param length the number of bytes to generate * @return a pseudorandom bit string of 'length' bytes generated from the master_secret. */ byte[] exportKeyingMaterial(String asciiLabel, byte[] context_value, int length); } bouncycastle-1.49.orig/src/org/bouncycastle/crypto/tls/TlsPSKKeyExchange.java0000644000175000017500000001453212151551725026734 0ustar ebourgebourgpackage org.bouncycastle.crypto.tls; import java.io.ByteArrayOutputStream; import java.io.IOException; import java.io.InputStream; import java.io.OutputStream; import java.math.BigInteger; import java.util.Vector; import org.bouncycastle.asn1.x509.KeyUsage; import org.bouncycastle.asn1.x509.SubjectPublicKeyInfo; import org.bouncycastle.crypto.params.AsymmetricKeyParameter; import org.bouncycastle.crypto.params.DHParameters; import org.bouncycastle.crypto.params.DHPrivateKeyParameters; import org.bouncycastle.crypto.params.DHPublicKeyParameters; import org.bouncycastle.crypto.params.RSAKeyParameters; import org.bouncycastle.crypto.util.PublicKeyFactory; /** * TLS 1.0 PSK key exchange (RFC 4279). */ public class TlsPSKKeyExchange extends AbstractTlsKeyExchange { protected TlsPSKIdentity pskIdentity; protected byte[] psk_identity_hint = null; protected DHPublicKeyParameters dhAgreeServerPublicKey = null; protected DHPrivateKeyParameters dhAgreeClientPrivateKey = null; protected AsymmetricKeyParameter serverPublicKey = null; protected RSAKeyParameters rsaServerPublicKey = null; protected byte[] premasterSecret; public TlsPSKKeyExchange(int keyExchange, Vector supportedSignatureAlgorithms, TlsPSKIdentity pskIdentity) { super(keyExchange, supportedSignatureAlgorithms); switch (keyExchange) { case KeyExchangeAlgorithm.PSK: case KeyExchangeAlgorithm.RSA_PSK: case KeyExchangeAlgorithm.DHE_PSK: break; default: throw new IllegalArgumentException("unsupported key exchange algorithm"); } this.pskIdentity = pskIdentity; } public void skipServerCredentials() throws IOException { if (keyExchange == KeyExchangeAlgorithm.RSA_PSK) { throw new TlsFatalAlert(AlertDescription.unexpected_message); } } public void processServerCertificate(Certificate serverCertificate) throws IOException { if (keyExchange != KeyExchangeAlgorithm.RSA_PSK) { throw new TlsFatalAlert(AlertDescription.unexpected_message); } if (serverCertificate.isEmpty()) { throw new TlsFatalAlert(AlertDescription.bad_certificate); } org.bouncycastle.asn1.x509.Certificate x509Cert = serverCertificate.getCertificateAt(0); SubjectPublicKeyInfo keyInfo = x509Cert.getSubjectPublicKeyInfo(); try { this.serverPublicKey = PublicKeyFactory.createKey(keyInfo); } catch (RuntimeException e) { throw new TlsFatalAlert(AlertDescription.unsupported_certificate); } // Sanity check the PublicKeyFactory if (this.serverPublicKey.isPrivate()) { throw new TlsFatalAlert(AlertDescription.internal_error); } this.rsaServerPublicKey = validateRSAPublicKey((RSAKeyParameters)this.serverPublicKey); TlsUtils.validateKeyUsage(x509Cert, KeyUsage.keyEncipherment); super.processServerCertificate(serverCertificate); } public boolean requiresServerKeyExchange() { return keyExchange == KeyExchangeAlgorithm.DHE_PSK; } public void processServerKeyExchange(InputStream input) throws IOException { this.psk_identity_hint = TlsUtils.readOpaque16(input); if (this.keyExchange == KeyExchangeAlgorithm.DHE_PSK) { byte[] pBytes = TlsUtils.readOpaque16(input); byte[] gBytes = TlsUtils.readOpaque16(input); byte[] YsBytes = TlsUtils.readOpaque16(input); BigInteger p = new BigInteger(1, pBytes); BigInteger g = new BigInteger(1, gBytes); BigInteger Ys = new BigInteger(1, YsBytes); this.dhAgreeServerPublicKey = TlsDHUtils.validateDHPublicKey(new DHPublicKeyParameters(Ys, new DHParameters(p, g))); } } public void validateCertificateRequest(CertificateRequest certificateRequest) throws IOException { throw new TlsFatalAlert(AlertDescription.unexpected_message); } public void processClientCredentials(TlsCredentials clientCredentials) throws IOException { throw new TlsFatalAlert(AlertDescription.internal_error); } public void generateClientKeyExchange(OutputStream output) throws IOException { if (psk_identity_hint == null) { pskIdentity.skipIdentityHint(); } else { pskIdentity.notifyIdentityHint(psk_identity_hint); } byte[] psk_identity = pskIdentity.getPSKIdentity(); TlsUtils.writeOpaque16(psk_identity, output); if (this.keyExchange == KeyExchangeAlgorithm.RSA_PSK) { this.premasterSecret = TlsRSAUtils.generateEncryptedPreMasterSecret(context, this.rsaServerPublicKey, output); } else if (this.keyExchange == KeyExchangeAlgorithm.DHE_PSK) { this.dhAgreeClientPrivateKey = TlsDHUtils.generateEphemeralClientKeyExchange(context.getSecureRandom(), dhAgreeServerPublicKey.getParameters(), output); } } public byte[] generatePremasterSecret() throws IOException { byte[] psk = pskIdentity.getPSK(); byte[] other_secret = generateOtherSecret(psk.length); ByteArrayOutputStream buf = new ByteArrayOutputStream(4 + other_secret.length + psk.length); TlsUtils.writeOpaque16(other_secret, buf); TlsUtils.writeOpaque16(psk, buf); return buf.toByteArray(); } protected byte[] generateOtherSecret(int pskLength) { if (this.keyExchange == KeyExchangeAlgorithm.DHE_PSK) { return TlsDHUtils.calculateDHBasicAgreement(dhAgreeServerPublicKey, dhAgreeClientPrivateKey); } if (this.keyExchange == KeyExchangeAlgorithm.RSA_PSK) { return this.premasterSecret; } return new byte[pskLength]; } protected RSAKeyParameters validateRSAPublicKey(RSAKeyParameters key) throws IOException { // TODO What is the minimum bit length required? // key.getModulus().bitLength(); if (!key.getExponent().isProbablePrime(2)) { throw new TlsFatalAlert(AlertDescription.illegal_parameter); } return key; } } bouncycastle-1.49.orig/src/org/bouncycastle/crypto/tls/TlsDHUtils.java0000644000175000017500000000713612151551725025501 0ustar ebourgebourgpackage org.bouncycastle.crypto.tls; import java.io.IOException; import java.io.InputStream; import java.io.OutputStream; import java.math.BigInteger; import java.security.SecureRandom; import org.bouncycastle.crypto.AsymmetricCipherKeyPair; import org.bouncycastle.crypto.agreement.DHBasicAgreement; import org.bouncycastle.crypto.generators.DHBasicKeyPairGenerator; import org.bouncycastle.crypto.params.DHKeyGenerationParameters; import org.bouncycastle.crypto.params.DHParameters; import org.bouncycastle.crypto.params.DHPrivateKeyParameters; import org.bouncycastle.crypto.params.DHPublicKeyParameters; import org.bouncycastle.util.BigIntegers; public class TlsDHUtils { static final BigInteger ONE = BigInteger.valueOf(1); static final BigInteger TWO = BigInteger.valueOf(2); public static byte[] calculateDHBasicAgreement(DHPublicKeyParameters publicKey, DHPrivateKeyParameters privateKey) { DHBasicAgreement basicAgreement = new DHBasicAgreement(); basicAgreement.init(privateKey); BigInteger agreementValue = basicAgreement.calculateAgreement(publicKey); /* * RFC 5246 8.1.2. Leading bytes of Z that contain all zero bits are stripped before it is * used as the pre_master_secret. */ return BigIntegers.asUnsignedByteArray(agreementValue); } public static AsymmetricCipherKeyPair generateDHKeyPair(SecureRandom random, DHParameters dhParams) { DHBasicKeyPairGenerator dhGen = new DHBasicKeyPairGenerator(); dhGen.init(new DHKeyGenerationParameters(random, dhParams)); return dhGen.generateKeyPair(); } public static DHPrivateKeyParameters generateEphemeralClientKeyExchange(SecureRandom random, DHParameters dhParams, OutputStream output) throws IOException { AsymmetricCipherKeyPair dhAgreeClientKeyPair = generateDHKeyPair(random, dhParams); DHPrivateKeyParameters dhAgreeClientPrivateKey = (DHPrivateKeyParameters)dhAgreeClientKeyPair .getPrivate(); BigInteger Yc = ((DHPublicKeyParameters)dhAgreeClientKeyPair.getPublic()).getY(); byte[] keData = BigIntegers.asUnsignedByteArray(Yc); TlsUtils.writeOpaque16(keData, output); return dhAgreeClientPrivateKey; } public static DHPublicKeyParameters validateDHPublicKey(DHPublicKeyParameters key) throws IOException { BigInteger Y = key.getY(); DHParameters params = key.getParameters(); BigInteger p = params.getP(); BigInteger g = params.getG(); if (!p.isProbablePrime(2)) { throw new TlsFatalAlert(AlertDescription.illegal_parameter); } if (g.compareTo(TWO) < 0 || g.compareTo(p.subtract(TWO)) > 0) { throw new TlsFatalAlert(AlertDescription.illegal_parameter); } if (Y.compareTo(TWO) < 0 || Y.compareTo(p.subtract(ONE)) > 0) { throw new TlsFatalAlert(AlertDescription.illegal_parameter); } // TODO See RFC 2631 for more discussion of Diffie-Hellman validation return key; } public static BigInteger readDHParameter(InputStream input) throws IOException { return new BigInteger(1, TlsUtils.readOpaque16(input)); } public static void writeDHParameter(BigInteger x, OutputStream output) throws IOException { TlsUtils.writeOpaque16(BigIntegers.asUnsignedByteArray(x), output); } } bouncycastle-1.49.orig/src/org/bouncycastle/crypto/tls/DTLSReliableHandshake.java0000644000175000017500000003341112151551725027512 0ustar ebourgebourgpackage org.bouncycastle.crypto.tls; import java.io.ByteArrayOutputStream; import java.io.IOException; import java.util.Enumeration; import java.util.Hashtable; import java.util.Vector; import org.bouncycastle.util.Integers; class DTLSReliableHandshake { private final static int MAX_RECEIVE_AHEAD = 10; private final DTLSRecordLayer recordLayer; private TlsHandshakeHash hash = new DeferredHash(); private Hashtable currentInboundFlight = new Hashtable(); private Hashtable previousInboundFlight = null; private Vector outboundFlight = new Vector(); private boolean sending = true; private int message_seq = 0, next_receive_seq = 0; DTLSReliableHandshake(TlsContext context, DTLSRecordLayer transport) { this.recordLayer = transport; this.hash.init(context); } void notifyHelloComplete() { this.hash = this.hash.commit(); } byte[] getCurrentHash() { TlsHandshakeHash copyOfHash = hash.fork(); byte[] result = new byte[copyOfHash.getDigestSize()]; copyOfHash.doFinal(result, 0); return result; } void sendMessage(short msg_type, byte[] body) throws IOException { if (!sending) { checkInboundFlight(); sending = true; outboundFlight.removeAllElements(); } Message message = new Message(message_seq++, msg_type, body); outboundFlight.addElement(message); writeMessage(message); updateHandshakeMessagesDigest(message); } Message receiveMessage() throws IOException { if (sending) { sending = false; prepareInboundFlight(); } // Check if we already have the next message waiting { DTLSReassembler next = (DTLSReassembler)currentInboundFlight.get(Integers.valueOf(next_receive_seq)); if (next != null) { byte[] body = next.getBodyIfComplete(); if (body != null) { previousInboundFlight = null; return updateHandshakeMessagesDigest(new Message(next_receive_seq++, next.getType(), body)); } } } byte[] buf = null; // TODO Check the conditions under which we should reset this int readTimeoutMillis = 1000; for (; ; ) { int receiveLimit = recordLayer.getReceiveLimit(); if (buf == null || buf.length < receiveLimit) { buf = new byte[receiveLimit]; } // TODO Handle records containing multiple handshake messages try { for (; ; ) { int received = recordLayer.receive(buf, 0, receiveLimit, readTimeoutMillis); if (received < 0) { break; } if (received < 12) { continue; } int fragment_length = TlsUtils.readUint24(buf, 9); if (received != (fragment_length + 12)) { continue; } int seq = TlsUtils.readUint16(buf, 4); if (seq > (next_receive_seq + MAX_RECEIVE_AHEAD)) { continue; } short msg_type = TlsUtils.readUint8(buf, 0); int length = TlsUtils.readUint24(buf, 1); int fragment_offset = TlsUtils.readUint24(buf, 6); if (fragment_offset + fragment_length > length) { continue; } if (seq < next_receive_seq) { /* * NOTE: If we receive the previous flight of incoming messages in full * again, retransmit our last flight */ if (previousInboundFlight != null) { DTLSReassembler reassembler = (DTLSReassembler)previousInboundFlight.get(Integers .valueOf(seq)); if (reassembler != null) { reassembler.contributeFragment(msg_type, length, buf, 12, fragment_offset, fragment_length); if (checkAll(previousInboundFlight)) { resendOutboundFlight(); /* * TODO[DTLS] implementations SHOULD back off handshake packet * size during the retransmit backoff. */ readTimeoutMillis = Math.min(readTimeoutMillis * 2, 60000); resetAll(previousInboundFlight); } } } } else { DTLSReassembler reassembler = (DTLSReassembler)currentInboundFlight.get(Integers.valueOf(seq)); if (reassembler == null) { reassembler = new DTLSReassembler(msg_type, length); currentInboundFlight.put(Integers.valueOf(seq), reassembler); } reassembler.contributeFragment(msg_type, length, buf, 12, fragment_offset, fragment_length); if (seq == next_receive_seq) { byte[] body = reassembler.getBodyIfComplete(); if (body != null) { previousInboundFlight = null; return updateHandshakeMessagesDigest(new Message(next_receive_seq++, reassembler.getType(), body)); } } } } } catch (IOException e) { // NOTE: Assume this is a timeout for the moment } resendOutboundFlight(); /* * TODO[DTLS] implementations SHOULD back off handshake packet size during the * retransmit backoff. */ readTimeoutMillis = Math.min(readTimeoutMillis * 2, 60000); } } void finish() { DTLSHandshakeRetransmit retransmit = null; if (!sending) { checkInboundFlight(); } else if (currentInboundFlight != null) { /* * RFC 6347 4.2.4. In addition, for at least twice the default MSL defined for [TCP], * when in the FINISHED state, the node that transmits the last flight (the server in an * ordinary handshake or the client in a resumed handshake) MUST respond to a retransmit * of the peer's last flight with a retransmit of the last flight. */ retransmit = new DTLSHandshakeRetransmit() { public void receivedHandshakeRecord(int epoch, byte[] buf, int off, int len) throws IOException { /* * TODO Need to handle the case where the previous inbound flight contains * messages from two epochs. */ if (len < 12) { return; } int fragment_length = TlsUtils.readUint24(buf, off + 9); if (len != (fragment_length + 12)) { return; } int seq = TlsUtils.readUint16(buf, off + 4); if (seq >= next_receive_seq) { return; } short msg_type = TlsUtils.readUint8(buf, off); // TODO This is a hack that only works until we try to support renegotiation int expectedEpoch = msg_type == HandshakeType.finished ? 1 : 0; if (epoch != expectedEpoch) { return; } int length = TlsUtils.readUint24(buf, off + 1); int fragment_offset = TlsUtils.readUint24(buf, off + 6); if (fragment_offset + fragment_length > length) { return; } DTLSReassembler reassembler = (DTLSReassembler)currentInboundFlight.get(Integers.valueOf(seq)); if (reassembler != null) { reassembler.contributeFragment(msg_type, length, buf, off + 12, fragment_offset, fragment_length); if (checkAll(currentInboundFlight)) { resendOutboundFlight(); resetAll(currentInboundFlight); } } } }; } recordLayer.handshakeSuccessful(retransmit); } void resetHandshakeMessagesDigest() { hash.reset(); } /** * Check that there are no "extra" messages left in the current inbound flight */ private void checkInboundFlight() { Enumeration e = currentInboundFlight.keys(); while (e.hasMoreElements()) { Integer key = (Integer)e.nextElement(); if (key.intValue() >= next_receive_seq) { // TODO Should this be considered an error? } } } private void prepareInboundFlight() { resetAll(currentInboundFlight); previousInboundFlight = currentInboundFlight; currentInboundFlight = new Hashtable(); } private void resendOutboundFlight() throws IOException { recordLayer.resetWriteEpoch(); for (int i = 0; i < outboundFlight.size(); ++i) { writeMessage((Message)outboundFlight.elementAt(i)); } } private Message updateHandshakeMessagesDigest(Message message) throws IOException { if (message.getType() != HandshakeType.hello_request) { byte[] body = message.getBody(); byte[] buf = new byte[12]; TlsUtils.writeUint8(message.getType(), buf, 0); TlsUtils.writeUint24(body.length, buf, 1); TlsUtils.writeUint16(message.getSeq(), buf, 4); TlsUtils.writeUint24(0, buf, 6); TlsUtils.writeUint24(body.length, buf, 9); hash.update(buf, 0, buf.length); hash.update(body, 0, body.length); } return message; } private void writeMessage(Message message) throws IOException { int sendLimit = recordLayer.getSendLimit(); int fragmentLimit = sendLimit - 12; // TODO Support a higher minimum fragment size? if (fragmentLimit < 1) { // TODO Should we be throwing an exception here? throw new TlsFatalAlert(AlertDescription.internal_error); } int length = message.getBody().length; // NOTE: Must still send a fragment if body is empty int fragment_offset = 0; do { int fragment_length = Math.min(length - fragment_offset, fragmentLimit); writeHandshakeFragment(message, fragment_offset, fragment_length); fragment_offset += fragment_length; } while (fragment_offset < length); } private void writeHandshakeFragment(Message message, int fragment_offset, int fragment_length) throws IOException { ByteArrayOutputStream buf = new ByteArrayOutputStream(); TlsUtils.writeUint8(message.getType(), buf); TlsUtils.writeUint24(message.getBody().length, buf); TlsUtils.writeUint16(message.getSeq(), buf); TlsUtils.writeUint24(fragment_offset, buf); TlsUtils.writeUint24(fragment_length, buf); buf.write(message.getBody(), fragment_offset, fragment_length); byte[] fragment = buf.toByteArray(); recordLayer.send(fragment, 0, fragment.length); } private static boolean checkAll(Hashtable inboundFlight) { Enumeration e = inboundFlight.elements(); while (e.hasMoreElements()) { if (((DTLSReassembler)e.nextElement()).getBodyIfComplete() == null) { return false; } } return true; } private static void resetAll(Hashtable inboundFlight) { Enumeration e = inboundFlight.elements(); while (e.hasMoreElements()) { ((DTLSReassembler)e.nextElement()).reset(); } } static class Message { private final int message_seq; private final short msg_type; private final byte[] body; private Message(int message_seq, short msg_type, byte[] body) { this.message_seq = message_seq; this.msg_type = msg_type; this.body = body; } public int getSeq() { return message_seq; } public short getType() { return msg_type; } public byte[] getBody() { return body; } } } bouncycastle-1.49.orig/src/org/bouncycastle/crypto/tls/TlsInputStream.java0000644000175000017500000000141012146535331026424 0ustar ebourgebourgpackage org.bouncycastle.crypto.tls; import java.io.IOException; import java.io.InputStream; /** * An InputStream for an TLS 1.0 connection. */ class TlsInputStream extends InputStream { private byte[] buf = new byte[1]; private TlsProtocol handler = null; TlsInputStream(TlsProtocol handler) { this.handler = handler; } public int read(byte[] buf, int offset, int len) throws IOException { return this.handler.readApplicationData(buf, offset, len); } public int read() throws IOException { if (this.read(buf) < 0) { return -1; } return buf[0] & 0xff; } public void close() throws IOException { handler.close(); } } bouncycastle-1.49.orig/src/org/bouncycastle/crypto/tls/RecordStream.java0000644000175000017500000002462412151551725026075 0ustar ebourgebourgpackage org.bouncycastle.crypto.tls; import java.io.ByteArrayOutputStream; import java.io.IOException; import java.io.InputStream; import java.io.OutputStream; import org.bouncycastle.crypto.Digest; /** * An implementation of the TLS 1.0/1.1/1.2 record layer, allowing downgrade to SSLv3. */ class RecordStream { private static int PLAINTEXT_LIMIT = (1 << 14); private static int COMPRESSED_LIMIT = PLAINTEXT_LIMIT + 1024; private static int CIPHERTEXT_LIMIT = COMPRESSED_LIMIT + 1024; private TlsProtocol handler; private InputStream input; private OutputStream output; private TlsCompression pendingCompression = null, readCompression = null, writeCompression = null; private TlsCipher pendingCipher = null, readCipher = null, writeCipher = null; private long readSeqNo = 0, writeSeqNo = 0; private ByteArrayOutputStream buffer = new ByteArrayOutputStream(); private TlsContext context = null; private TlsHandshakeHash hash = null; private ProtocolVersion readVersion = null, writeVersion = null; private boolean restrictReadVersion = true; RecordStream(TlsProtocol handler, InputStream input, OutputStream output) { this.handler = handler; this.input = input; this.output = output; this.readCompression = new TlsNullCompression(); this.writeCompression = this.readCompression; this.readCipher = new TlsNullCipher(context); this.writeCipher = this.readCipher; } void init(TlsContext context) { this.context = context; this.hash = new DeferredHash(); this.hash.init(context); } ProtocolVersion getReadVersion() { return readVersion; } void setReadVersion(ProtocolVersion readVersion) { this.readVersion = readVersion; } void setWriteVersion(ProtocolVersion writeVersion) { this.writeVersion = writeVersion; } /** * RFC 5246 E.1. "Earlier versions of the TLS specification were not fully clear on what the * record layer version number (TLSPlaintext.version) should contain when sending ClientHello * (i.e., before it is known which version of the protocol will be employed). Thus, TLS servers * compliant with this specification MUST accept any value {03,XX} as the record layer version * number for ClientHello." */ void setRestrictReadVersion(boolean enabled) { this.restrictReadVersion = enabled; } void notifyHelloComplete() { this.hash = this.hash.commit(); } void setPendingConnectionState(TlsCompression tlsCompression, TlsCipher tlsCipher) { this.pendingCompression = tlsCompression; this.pendingCipher = tlsCipher; } void sentWriteCipherSpec() throws IOException { if (pendingCompression == null || pendingCipher == null) { throw new TlsFatalAlert(AlertDescription.handshake_failure); } this.writeCompression = this.pendingCompression; this.writeCipher = this.pendingCipher; this.writeSeqNo = 0; } void receivedReadCipherSpec() throws IOException { if (pendingCompression == null || pendingCipher == null) { throw new TlsFatalAlert(AlertDescription.handshake_failure); } this.readCompression = this.pendingCompression; this.readCipher = this.pendingCipher; this.readSeqNo = 0; } void finaliseHandshake() throws IOException { if (readCompression != pendingCompression || writeCompression != pendingCompression || readCipher != pendingCipher || writeCipher != pendingCipher) { throw new TlsFatalAlert(AlertDescription.handshake_failure); } pendingCompression = null; pendingCipher = null; } public void readRecord() throws IOException { short type = TlsUtils.readUint8(input); // TODO In earlier RFCs, it was "SHOULD ignore"; should this be version-dependent? /* * RFC 5246 6. If a TLS implementation receives an unexpected record type, it MUST send an * unexpected_message alert. */ checkType(type, AlertDescription.unexpected_message); if (!restrictReadVersion) { int version = TlsUtils.readVersionRaw(input); if ((version & 0xffffff00) != 0x0300) { throw new TlsFatalAlert(AlertDescription.illegal_parameter); } } else { ProtocolVersion version = TlsUtils.readVersion(input); if (readVersion == null) { readVersion = version; } else if (!version.equals(readVersion)) { throw new TlsFatalAlert(AlertDescription.illegal_parameter); } } int length = TlsUtils.readUint16(input); byte[] plaintext = decodeAndVerify(type, input, length); handler.processRecord(type, plaintext, 0, plaintext.length); } protected byte[] decodeAndVerify(short type, InputStream input, int len) throws IOException { checkLength(len, CIPHERTEXT_LIMIT, AlertDescription.record_overflow); byte[] buf = TlsUtils.readFully(len, input); byte[] decoded = readCipher.decodeCiphertext(readSeqNo++, type, buf, 0, buf.length); checkLength(decoded.length, COMPRESSED_LIMIT, AlertDescription.record_overflow); /* * TODO RFC5264 6.2.2. Implementation note: Decompression functions are responsible for * ensuring that messages cannot cause internal buffer overflows. */ OutputStream cOut = readCompression.decompress(buffer); if (cOut != buffer) { cOut.write(decoded, 0, decoded.length); cOut.flush(); decoded = getBufferContents(); } /* * RFC 5264 6.2.2. If the decompression function encounters a TLSCompressed.fragment that * would decompress to a length in excess of 2^14 bytes, it should report a fatal * decompression failure error. */ checkLength(decoded.length, PLAINTEXT_LIMIT, AlertDescription.decompression_failure); return decoded; } protected void writeRecord(short type, byte[] plaintext, int plaintextOffset, int plaintextLength) throws IOException { /* * RFC 5264 6. Implementations MUST NOT send record types not defined in this document * unless negotiated by some extension. */ checkType(type, AlertDescription.internal_error); /* * RFC 5264 6.2.1 The length should not exceed 2^14. */ checkLength(plaintextLength, PLAINTEXT_LIMIT, AlertDescription.internal_error); /* * RFC 5264 6.2.1 Implementations MUST NOT send zero-length fragments of Handshake, Alert, * or ChangeCipherSpec content types. */ if (plaintextLength < 1 && type != ContentType.application_data) { throw new TlsFatalAlert(AlertDescription.internal_error); } if (type == ContentType.handshake) { updateHandshakeData(plaintext, plaintextOffset, plaintextLength); } OutputStream cOut = writeCompression.compress(buffer); byte[] ciphertext; if (cOut == buffer) { ciphertext = writeCipher.encodePlaintext(writeSeqNo++, type, plaintext, plaintextOffset, plaintextLength); } else { cOut.write(plaintext, plaintextOffset, plaintextLength); cOut.flush(); byte[] compressed = getBufferContents(); /* * RFC5264 6.2.2. Compression must be lossless and may not increase the content length * by more than 1024 bytes. */ checkLength(compressed.length, plaintextLength + 1024, AlertDescription.internal_error); ciphertext = writeCipher.encodePlaintext(writeSeqNo++, type, compressed, 0, compressed.length); } /* * RFC 5264 6.2.3. The length may not exceed 2^14 + 2048. */ checkLength(ciphertext.length, CIPHERTEXT_LIMIT, AlertDescription.internal_error); byte[] record = new byte[ciphertext.length + 5]; TlsUtils.writeUint8(type, record, 0); TlsUtils.writeVersion(writeVersion, record, 1); TlsUtils.writeUint16(ciphertext.length, record, 3); System.arraycopy(ciphertext, 0, record, 5, ciphertext.length); output.write(record); output.flush(); } void updateHandshakeData(byte[] message, int offset, int len) { hash.update(message, offset, len); } /** * 'sender' only relevant to SSLv3 */ byte[] getCurrentHash(byte[] sender) { TlsHandshakeHash d = hash.fork(); if (context.getServerVersion().isSSL()) { if (sender != null) { d.update(sender, 0, sender.length); } } return doFinal(d); } protected void close() throws IOException { IOException e = null; try { input.close(); } catch (IOException ex) { e = ex; } try { output.close(); } catch (IOException ex) { e = ex; } if (e != null) { throw e; } } protected void flush() throws IOException { output.flush(); } private byte[] getBufferContents() { byte[] contents = buffer.toByteArray(); buffer.reset(); return contents; } private static byte[] doFinal(Digest d) { byte[] bs = new byte[d.getDigestSize()]; d.doFinal(bs, 0); return bs; } private static void checkType(short type, short alertDescription) throws IOException { switch (type) { case ContentType.change_cipher_spec: case ContentType.alert: case ContentType.handshake: case ContentType.application_data: break; default: throw new TlsFatalAlert(alertDescription); } } private static void checkLength(int length, int limit, short alertDescription) throws IOException { if (length > limit) { throw new TlsFatalAlert(alertDescription); } } } bouncycastle-1.49.orig/src/org/bouncycastle/crypto/tls/AbstractTlsKeyExchange.java0000644000175000017500000001212112151551725030032 0ustar ebourgebourgpackage org.bouncycastle.crypto.tls; import java.io.IOException; import java.io.InputStream; import java.util.Vector; public abstract class AbstractTlsKeyExchange implements TlsKeyExchange { protected int keyExchange; protected Vector supportedSignatureAlgorithms; protected TlsContext context; protected AbstractTlsKeyExchange(int keyExchange, Vector supportedSignatureAlgorithms) { this.keyExchange = keyExchange; this.supportedSignatureAlgorithms = supportedSignatureAlgorithms; } public void init(TlsContext context) { this.context = context; ProtocolVersion clientVersion = context.getClientVersion(); if (TlsUtils.isSignatureAlgorithmsExtensionAllowed(clientVersion)) { /* * RFC 5264 7.4.1.4.1. If the client does not send the signature_algorithms extension, * the server MUST do the following: * * - If the negotiated key exchange algorithm is one of (RSA, DHE_RSA, DH_RSA, RSA_PSK, * ECDH_RSA, ECDHE_RSA), behave as if client had sent the value {sha1,rsa}. * * - If the negotiated key exchange algorithm is one of (DHE_DSS, DH_DSS), behave as if * the client had sent the value {sha1,dsa}. * * - If the negotiated key exchange algorithm is one of (ECDH_ECDSA, ECDHE_ECDSA), * behave as if the client had sent value {sha1,ecdsa}. */ if (this.supportedSignatureAlgorithms == null) { switch (keyExchange) { case KeyExchangeAlgorithm.DH_DSS: case KeyExchangeAlgorithm.DHE_DSS: case KeyExchangeAlgorithm.SRP_DSS: { this.supportedSignatureAlgorithms = TlsUtils.getDefaultDSSSignatureAlgorithms(); break; } case KeyExchangeAlgorithm.ECDH_ECDSA: case KeyExchangeAlgorithm.ECDHE_ECDSA: { this.supportedSignatureAlgorithms = TlsUtils.getDefaultECDSASignatureAlgorithms(); break; } case KeyExchangeAlgorithm.DH_RSA: case KeyExchangeAlgorithm.DHE_RSA: case KeyExchangeAlgorithm.ECDH_RSA: case KeyExchangeAlgorithm.ECDHE_RSA: case KeyExchangeAlgorithm.RSA: case KeyExchangeAlgorithm.RSA_PSK: case KeyExchangeAlgorithm.SRP_RSA: { this.supportedSignatureAlgorithms = TlsUtils.getDefaultRSASignatureAlgorithms(); break; } default: throw new IllegalStateException("unsupported key exchange algorithm"); } } } else if (this.supportedSignatureAlgorithms != null) { throw new IllegalStateException("supported_signature_algorithms not allowed for " + clientVersion); } } public void processServerCertificate(Certificate serverCertificate) throws IOException { if (supportedSignatureAlgorithms == null) { /* * TODO RFC 2264 7.4.2. Unless otherwise specified, the signing algorithm for the * certificate must be the same as the algorithm for the certificate key. */ } else { /* * TODO RFC 5264 7.4.2. If the client provided a "signature_algorithms" extension, then * all certificates provided by the server MUST be signed by a hash/signature algorithm * pair that appears in that extension. */ } } public void processServerCredentials(TlsCredentials serverCredentials) throws IOException { processServerCertificate(serverCredentials.getCertificate()); } public boolean requiresServerKeyExchange() { return false; } public byte[] generateServerKeyExchange() throws IOException { if (requiresServerKeyExchange()) { throw new TlsFatalAlert(AlertDescription.internal_error); } return null; } public void skipServerKeyExchange() throws IOException { if (requiresServerKeyExchange()) { throw new TlsFatalAlert(AlertDescription.unexpected_message); } } public void processServerKeyExchange(InputStream input) throws IOException { if (!requiresServerKeyExchange()) { throw new TlsFatalAlert(AlertDescription.unexpected_message); } } public void skipClientCredentials() throws IOException { } public void processClientCertificate(Certificate clientCertificate) throws IOException { } public void processClientKeyExchange(InputStream input) throws IOException { // Key exchange implementation MUST support client key exchange throw new TlsFatalAlert(AlertDescription.internal_error); } } bouncycastle-1.49.orig/src/org/bouncycastle/crypto/tls/DefaultTlsServer.java0000644000175000017500000004442312151551725026740 0ustar ebourgebourgpackage org.bouncycastle.crypto.tls; import java.io.IOException; import org.bouncycastle.crypto.agreement.DHStandardGroups; import org.bouncycastle.crypto.params.DHParameters; public abstract class DefaultTlsServer extends AbstractTlsServer { public DefaultTlsServer() { super(); } public DefaultTlsServer(TlsCipherFactory cipherFactory) { super(cipherFactory); } protected TlsEncryptionCredentials getRSAEncryptionCredentials() throws IOException { throw new TlsFatalAlert(AlertDescription.internal_error); } protected TlsSignerCredentials getRSASignerCredentials() throws IOException { throw new TlsFatalAlert(AlertDescription.internal_error); } protected DHParameters getDHParameters() { return DHStandardGroups.rfc5114_1024_160; } protected int[] getCipherSuites() { return new int[]{CipherSuite.TLS_ECDHE_RSA_WITH_AES_256_CBC_SHA, CipherSuite.TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA, CipherSuite.TLS_ECDHE_RSA_WITH_3DES_EDE_CBC_SHA, CipherSuite.TLS_DHE_RSA_WITH_AES_256_CBC_SHA, CipherSuite.TLS_DHE_RSA_WITH_AES_128_CBC_SHA, CipherSuite.TLS_DHE_RSA_WITH_3DES_EDE_CBC_SHA, CipherSuite.TLS_RSA_WITH_AES_256_CBC_SHA, CipherSuite.TLS_RSA_WITH_AES_128_CBC_SHA, CipherSuite.TLS_RSA_WITH_3DES_EDE_CBC_SHA,}; } public TlsCredentials getCredentials() throws IOException { switch (selectedCipherSuite) { case CipherSuite.TLS_RSA_WITH_3DES_EDE_CBC_SHA: case CipherSuite.TLS_RSA_WITH_AES_128_CBC_SHA: case CipherSuite.TLS_RSA_WITH_AES_128_CBC_SHA256: case CipherSuite.TLS_RSA_WITH_AES_128_GCM_SHA256: case CipherSuite.TLS_RSA_WITH_AES_256_CBC_SHA: case CipherSuite.TLS_RSA_WITH_AES_256_CBC_SHA256: case CipherSuite.TLS_RSA_WITH_AES_256_GCM_SHA384: case CipherSuite.TLS_RSA_WITH_CAMELLIA_128_CBC_SHA: case CipherSuite.TLS_RSA_WITH_CAMELLIA_256_CBC_SHA: case CipherSuite.TLS_RSA_WITH_NULL_MD5: case CipherSuite.TLS_RSA_WITH_NULL_SHA: case CipherSuite.TLS_RSA_WITH_NULL_SHA256: case CipherSuite.TLS_RSA_WITH_RC4_128_MD5: case CipherSuite.TLS_RSA_WITH_RC4_128_SHA: case CipherSuite.TLS_RSA_WITH_SEED_CBC_SHA: return getRSAEncryptionCredentials(); case CipherSuite.TLS_DHE_RSA_WITH_3DES_EDE_CBC_SHA: case CipherSuite.TLS_DHE_RSA_WITH_AES_128_CBC_SHA: case CipherSuite.TLS_DHE_RSA_WITH_AES_128_CBC_SHA256: case CipherSuite.TLS_DHE_RSA_WITH_AES_128_GCM_SHA256: case CipherSuite.TLS_DHE_RSA_WITH_AES_256_CBC_SHA: case CipherSuite.TLS_DHE_RSA_WITH_AES_256_CBC_SHA256: case CipherSuite.TLS_DHE_RSA_WITH_AES_256_GCM_SHA384: case CipherSuite.TLS_DHE_RSA_WITH_CAMELLIA_128_CBC_SHA: case CipherSuite.TLS_DHE_RSA_WITH_CAMELLIA_256_CBC_SHA: case CipherSuite.TLS_DHE_RSA_WITH_SEED_CBC_SHA: case CipherSuite.TLS_ECDHE_RSA_WITH_3DES_EDE_CBC_SHA: case CipherSuite.TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA: case CipherSuite.TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA256: case CipherSuite.TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256: case CipherSuite.TLS_ECDHE_RSA_WITH_AES_256_CBC_SHA: case CipherSuite.TLS_ECDHE_RSA_WITH_AES_256_CBC_SHA384: case CipherSuite.TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384: return getRSASignerCredentials(); default: /* * Note: internal error here; selected a key exchange we don't implement! */ throw new TlsFatalAlert(AlertDescription.internal_error); } } public TlsKeyExchange getKeyExchange() throws IOException { switch (selectedCipherSuite) { case CipherSuite.TLS_DH_DSS_WITH_3DES_EDE_CBC_SHA: case CipherSuite.TLS_DH_DSS_WITH_AES_128_CBC_SHA: case CipherSuite.TLS_DH_DSS_WITH_AES_128_CBC_SHA256: case CipherSuite.TLS_DH_DSS_WITH_AES_128_GCM_SHA256: case CipherSuite.TLS_DH_DSS_WITH_AES_256_CBC_SHA: case CipherSuite.TLS_DH_DSS_WITH_AES_256_CBC_SHA256: case CipherSuite.TLS_DH_DSS_WITH_AES_256_GCM_SHA384: case CipherSuite.TLS_DH_DSS_WITH_CAMELLIA_128_CBC_SHA: case CipherSuite.TLS_DH_DSS_WITH_CAMELLIA_256_CBC_SHA: case CipherSuite.TLS_DH_DSS_WITH_SEED_CBC_SHA: return createDHKeyExchange(KeyExchangeAlgorithm.DH_DSS); case CipherSuite.TLS_DH_RSA_WITH_3DES_EDE_CBC_SHA: case CipherSuite.TLS_DH_RSA_WITH_AES_128_CBC_SHA: case CipherSuite.TLS_DH_RSA_WITH_AES_128_CBC_SHA256: case CipherSuite.TLS_DH_RSA_WITH_AES_128_GCM_SHA256: case CipherSuite.TLS_DH_RSA_WITH_AES_256_CBC_SHA: case CipherSuite.TLS_DH_RSA_WITH_AES_256_CBC_SHA256: case CipherSuite.TLS_DH_RSA_WITH_AES_256_GCM_SHA384: case CipherSuite.TLS_DH_RSA_WITH_CAMELLIA_128_CBC_SHA: case CipherSuite.TLS_DH_RSA_WITH_CAMELLIA_256_CBC_SHA: case CipherSuite.TLS_DH_RSA_WITH_SEED_CBC_SHA: return createDHKeyExchange(KeyExchangeAlgorithm.DH_RSA); case CipherSuite.TLS_DHE_DSS_WITH_3DES_EDE_CBC_SHA: case CipherSuite.TLS_DHE_DSS_WITH_AES_128_CBC_SHA: case CipherSuite.TLS_DHE_DSS_WITH_AES_128_CBC_SHA256: case CipherSuite.TLS_DHE_DSS_WITH_AES_128_GCM_SHA256: case CipherSuite.TLS_DHE_DSS_WITH_AES_256_CBC_SHA: case CipherSuite.TLS_DHE_DSS_WITH_AES_256_CBC_SHA256: case CipherSuite.TLS_DHE_DSS_WITH_AES_256_GCM_SHA384: case CipherSuite.TLS_DHE_DSS_WITH_CAMELLIA_128_CBC_SHA: case CipherSuite.TLS_DHE_DSS_WITH_CAMELLIA_256_CBC_SHA: case CipherSuite.TLS_DHE_DSS_WITH_SEED_CBC_SHA: return createDHEKeyExchange(KeyExchangeAlgorithm.DHE_DSS); case CipherSuite.TLS_DHE_RSA_WITH_3DES_EDE_CBC_SHA: case CipherSuite.TLS_DHE_RSA_WITH_AES_128_CBC_SHA: case CipherSuite.TLS_DHE_RSA_WITH_AES_128_CBC_SHA256: case CipherSuite.TLS_DHE_RSA_WITH_AES_128_GCM_SHA256: case CipherSuite.TLS_DHE_RSA_WITH_AES_256_CBC_SHA: case CipherSuite.TLS_DHE_RSA_WITH_AES_256_CBC_SHA256: case CipherSuite.TLS_DHE_RSA_WITH_AES_256_GCM_SHA384: case CipherSuite.TLS_DHE_RSA_WITH_CAMELLIA_128_CBC_SHA: case CipherSuite.TLS_DHE_RSA_WITH_CAMELLIA_256_CBC_SHA: case CipherSuite.TLS_DHE_RSA_WITH_SEED_CBC_SHA: return createDHEKeyExchange(KeyExchangeAlgorithm.DHE_RSA); case CipherSuite.TLS_ECDH_ECDSA_WITH_3DES_EDE_CBC_SHA: case CipherSuite.TLS_ECDH_ECDSA_WITH_AES_128_CBC_SHA: case CipherSuite.TLS_ECDH_ECDSA_WITH_AES_128_CBC_SHA256: case CipherSuite.TLS_ECDH_ECDSA_WITH_AES_128_GCM_SHA256: case CipherSuite.TLS_ECDH_ECDSA_WITH_AES_256_CBC_SHA: case CipherSuite.TLS_ECDH_ECDSA_WITH_AES_256_CBC_SHA384: case CipherSuite.TLS_ECDH_ECDSA_WITH_AES_256_GCM_SHA384: case CipherSuite.TLS_ECDH_ECDSA_WITH_NULL_SHA: case CipherSuite.TLS_ECDH_ECDSA_WITH_RC4_128_SHA: return createECDHKeyExchange(KeyExchangeAlgorithm.ECDH_ECDSA); case CipherSuite.TLS_ECDH_RSA_WITH_3DES_EDE_CBC_SHA: case CipherSuite.TLS_ECDH_RSA_WITH_AES_128_CBC_SHA: case CipherSuite.TLS_ECDH_RSA_WITH_AES_128_CBC_SHA256: case CipherSuite.TLS_ECDH_RSA_WITH_AES_128_GCM_SHA256: case CipherSuite.TLS_ECDH_RSA_WITH_AES_256_CBC_SHA: case CipherSuite.TLS_ECDH_RSA_WITH_AES_256_CBC_SHA384: case CipherSuite.TLS_ECDH_RSA_WITH_AES_256_GCM_SHA384: case CipherSuite.TLS_ECDH_RSA_WITH_NULL_SHA: case CipherSuite.TLS_ECDH_RSA_WITH_RC4_128_SHA: return createECDHKeyExchange(KeyExchangeAlgorithm.ECDH_RSA); case CipherSuite.TLS_ECDHE_ECDSA_WITH_3DES_EDE_CBC_SHA: case CipherSuite.TLS_ECDHE_ECDSA_WITH_AES_128_CBC_SHA: case CipherSuite.TLS_ECDHE_ECDSA_WITH_AES_128_CBC_SHA256: case CipherSuite.TLS_ECDHE_ECDSA_WITH_AES_128_GCM_SHA256: case CipherSuite.TLS_ECDHE_ECDSA_WITH_AES_256_CBC_SHA: case CipherSuite.TLS_ECDHE_ECDSA_WITH_AES_256_CBC_SHA384: case CipherSuite.TLS_ECDHE_ECDSA_WITH_AES_256_GCM_SHA384: case CipherSuite.TLS_ECDHE_ECDSA_WITH_NULL_SHA: case CipherSuite.TLS_ECDHE_ECDSA_WITH_RC4_128_SHA: return createECDHEKeyExchange(KeyExchangeAlgorithm.ECDHE_ECDSA); case CipherSuite.TLS_ECDHE_RSA_WITH_3DES_EDE_CBC_SHA: case CipherSuite.TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA: case CipherSuite.TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA256: case CipherSuite.TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256: case CipherSuite.TLS_ECDHE_RSA_WITH_AES_256_CBC_SHA: case CipherSuite.TLS_ECDHE_RSA_WITH_AES_256_CBC_SHA384: case CipherSuite.TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384: case CipherSuite.TLS_ECDHE_RSA_WITH_NULL_SHA: case CipherSuite.TLS_ECDHE_RSA_WITH_RC4_128_SHA: return createECDHEKeyExchange(KeyExchangeAlgorithm.ECDHE_RSA); case CipherSuite.TLS_RSA_WITH_3DES_EDE_CBC_SHA: case CipherSuite.TLS_RSA_WITH_AES_128_CBC_SHA: case CipherSuite.TLS_RSA_WITH_AES_128_CBC_SHA256: case CipherSuite.TLS_RSA_WITH_AES_128_GCM_SHA256: case CipherSuite.TLS_RSA_WITH_AES_256_CBC_SHA: case CipherSuite.TLS_RSA_WITH_AES_256_CBC_SHA256: case CipherSuite.TLS_RSA_WITH_AES_256_GCM_SHA384: case CipherSuite.TLS_RSA_WITH_CAMELLIA_128_CBC_SHA: case CipherSuite.TLS_RSA_WITH_CAMELLIA_256_CBC_SHA: case CipherSuite.TLS_RSA_WITH_NULL_MD5: case CipherSuite.TLS_RSA_WITH_NULL_SHA: case CipherSuite.TLS_RSA_WITH_NULL_SHA256: case CipherSuite.TLS_RSA_WITH_RC4_128_MD5: case CipherSuite.TLS_RSA_WITH_RC4_128_SHA: case CipherSuite.TLS_RSA_WITH_SEED_CBC_SHA: return createRSAKeyExchange(); default: /* * Note: internal error here; selected a key exchange we don't implement! */ throw new TlsFatalAlert(AlertDescription.internal_error); } } public TlsCipher getCipher() throws IOException { switch (selectedCipherSuite) { case CipherSuite.TLS_DH_DSS_WITH_3DES_EDE_CBC_SHA: case CipherSuite.TLS_DH_RSA_WITH_3DES_EDE_CBC_SHA: case CipherSuite.TLS_DHE_DSS_WITH_3DES_EDE_CBC_SHA: case CipherSuite.TLS_DHE_RSA_WITH_3DES_EDE_CBC_SHA: case CipherSuite.TLS_ECDH_ECDSA_WITH_3DES_EDE_CBC_SHA: case CipherSuite.TLS_ECDH_RSA_WITH_3DES_EDE_CBC_SHA: case CipherSuite.TLS_ECDHE_ECDSA_WITH_3DES_EDE_CBC_SHA: case CipherSuite.TLS_ECDHE_RSA_WITH_3DES_EDE_CBC_SHA: case CipherSuite.TLS_RSA_WITH_3DES_EDE_CBC_SHA: return cipherFactory.createCipher(context, EncryptionAlgorithm._3DES_EDE_CBC, MACAlgorithm.hmac_sha1); case CipherSuite.TLS_DH_DSS_WITH_AES_128_CBC_SHA: case CipherSuite.TLS_DH_RSA_WITH_AES_128_CBC_SHA: case CipherSuite.TLS_DHE_DSS_WITH_AES_128_CBC_SHA: case CipherSuite.TLS_DHE_RSA_WITH_AES_128_CBC_SHA: case CipherSuite.TLS_ECDH_ECDSA_WITH_AES_128_CBC_SHA: case CipherSuite.TLS_ECDH_RSA_WITH_AES_128_CBC_SHA: case CipherSuite.TLS_ECDHE_ECDSA_WITH_AES_128_CBC_SHA: case CipherSuite.TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA: case CipherSuite.TLS_RSA_WITH_AES_128_CBC_SHA: return cipherFactory.createCipher(context, EncryptionAlgorithm.AES_128_CBC, MACAlgorithm.hmac_sha1); case CipherSuite.TLS_DH_DSS_WITH_AES_128_CBC_SHA256: case CipherSuite.TLS_DH_RSA_WITH_AES_128_CBC_SHA256: case CipherSuite.TLS_DHE_DSS_WITH_AES_128_CBC_SHA256: case CipherSuite.TLS_DHE_RSA_WITH_AES_128_CBC_SHA256: case CipherSuite.TLS_ECDH_ECDSA_WITH_AES_128_CBC_SHA256: case CipherSuite.TLS_ECDH_RSA_WITH_AES_128_CBC_SHA256: case CipherSuite.TLS_ECDHE_ECDSA_WITH_AES_128_CBC_SHA256: case CipherSuite.TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA256: case CipherSuite.TLS_RSA_WITH_AES_128_CBC_SHA256: return cipherFactory.createCipher(context, EncryptionAlgorithm.AES_128_CBC, MACAlgorithm.hmac_sha256); case CipherSuite.TLS_DH_DSS_WITH_AES_128_GCM_SHA256: case CipherSuite.TLS_DH_RSA_WITH_AES_128_GCM_SHA256: case CipherSuite.TLS_DHE_DSS_WITH_AES_128_GCM_SHA256: case CipherSuite.TLS_DHE_RSA_WITH_AES_128_GCM_SHA256: case CipherSuite.TLS_ECDH_ECDSA_WITH_AES_128_GCM_SHA256: case CipherSuite.TLS_ECDH_RSA_WITH_AES_128_GCM_SHA256: case CipherSuite.TLS_ECDHE_ECDSA_WITH_AES_128_GCM_SHA256: case CipherSuite.TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256: case CipherSuite.TLS_RSA_WITH_AES_128_GCM_SHA256: return cipherFactory.createCipher(context, EncryptionAlgorithm.AES_128_GCM, MACAlgorithm._null); case CipherSuite.TLS_DH_DSS_WITH_AES_256_CBC_SHA: case CipherSuite.TLS_DH_RSA_WITH_AES_256_CBC_SHA: case CipherSuite.TLS_DHE_DSS_WITH_AES_256_CBC_SHA: case CipherSuite.TLS_DHE_RSA_WITH_AES_256_CBC_SHA: case CipherSuite.TLS_ECDH_ECDSA_WITH_AES_256_CBC_SHA: case CipherSuite.TLS_ECDH_RSA_WITH_AES_256_CBC_SHA: case CipherSuite.TLS_ECDHE_ECDSA_WITH_AES_256_CBC_SHA: case CipherSuite.TLS_ECDHE_RSA_WITH_AES_256_CBC_SHA: case CipherSuite.TLS_RSA_WITH_AES_256_CBC_SHA: return cipherFactory.createCipher(context, EncryptionAlgorithm.AES_256_CBC, MACAlgorithm.hmac_sha1); case CipherSuite.TLS_DH_DSS_WITH_AES_256_CBC_SHA256: case CipherSuite.TLS_DH_RSA_WITH_AES_256_CBC_SHA256: case CipherSuite.TLS_DHE_DSS_WITH_AES_256_CBC_SHA256: case CipherSuite.TLS_DHE_RSA_WITH_AES_256_CBC_SHA256: case CipherSuite.TLS_RSA_WITH_AES_256_CBC_SHA256: return cipherFactory.createCipher(context, EncryptionAlgorithm.AES_256_CBC, MACAlgorithm.hmac_sha256); case CipherSuite.TLS_ECDH_ECDSA_WITH_AES_256_CBC_SHA384: case CipherSuite.TLS_ECDH_RSA_WITH_AES_256_CBC_SHA384: case CipherSuite.TLS_ECDHE_ECDSA_WITH_AES_256_CBC_SHA384: case CipherSuite.TLS_ECDHE_RSA_WITH_AES_256_CBC_SHA384: return cipherFactory.createCipher(context, EncryptionAlgorithm.AES_256_CBC, MACAlgorithm.hmac_sha384); case CipherSuite.TLS_DH_DSS_WITH_AES_256_GCM_SHA384: case CipherSuite.TLS_DH_RSA_WITH_AES_256_GCM_SHA384: case CipherSuite.TLS_DHE_DSS_WITH_AES_256_GCM_SHA384: case CipherSuite.TLS_DHE_RSA_WITH_AES_256_GCM_SHA384: case CipherSuite.TLS_ECDH_ECDSA_WITH_AES_256_GCM_SHA384: case CipherSuite.TLS_ECDH_RSA_WITH_AES_256_GCM_SHA384: case CipherSuite.TLS_ECDHE_ECDSA_WITH_AES_256_GCM_SHA384: case CipherSuite.TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384: case CipherSuite.TLS_RSA_WITH_AES_256_GCM_SHA384: return cipherFactory.createCipher(context, EncryptionAlgorithm.AES_256_GCM, MACAlgorithm._null); case CipherSuite.TLS_DH_DSS_WITH_CAMELLIA_128_CBC_SHA: case CipherSuite.TLS_DH_RSA_WITH_CAMELLIA_128_CBC_SHA: case CipherSuite.TLS_DHE_DSS_WITH_CAMELLIA_128_CBC_SHA: case CipherSuite.TLS_DHE_RSA_WITH_CAMELLIA_128_CBC_SHA: case CipherSuite.TLS_RSA_WITH_CAMELLIA_128_CBC_SHA: return cipherFactory.createCipher(context, EncryptionAlgorithm.CAMELLIA_128_CBC, MACAlgorithm.hmac_sha1); case CipherSuite.TLS_DH_DSS_WITH_CAMELLIA_256_CBC_SHA: case CipherSuite.TLS_DH_RSA_WITH_CAMELLIA_256_CBC_SHA: case CipherSuite.TLS_DHE_DSS_WITH_CAMELLIA_256_CBC_SHA: case CipherSuite.TLS_DHE_RSA_WITH_CAMELLIA_256_CBC_SHA: case CipherSuite.TLS_RSA_WITH_CAMELLIA_256_CBC_SHA: return cipherFactory.createCipher(context, EncryptionAlgorithm.CAMELLIA_256_CBC, MACAlgorithm.hmac_sha1); case CipherSuite.TLS_RSA_WITH_NULL_MD5: return cipherFactory.createCipher(context, EncryptionAlgorithm.NULL, MACAlgorithm.hmac_md5); case CipherSuite.TLS_ECDH_ECDSA_WITH_NULL_SHA: case CipherSuite.TLS_ECDH_RSA_WITH_NULL_SHA: case CipherSuite.TLS_ECDHE_ECDSA_WITH_NULL_SHA: case CipherSuite.TLS_ECDHE_RSA_WITH_NULL_SHA: case CipherSuite.TLS_RSA_WITH_NULL_SHA: return cipherFactory.createCipher(context, EncryptionAlgorithm.NULL, MACAlgorithm.hmac_sha1); case CipherSuite.TLS_RSA_WITH_NULL_SHA256: return cipherFactory.createCipher(context, EncryptionAlgorithm.NULL, MACAlgorithm.hmac_sha256); case CipherSuite.TLS_RSA_WITH_RC4_128_MD5: return cipherFactory.createCipher(context, EncryptionAlgorithm.RC4_128, MACAlgorithm.hmac_md5); case CipherSuite.TLS_ECDH_ECDSA_WITH_RC4_128_SHA: case CipherSuite.TLS_ECDH_RSA_WITH_RC4_128_SHA: case CipherSuite.TLS_ECDHE_ECDSA_WITH_RC4_128_SHA: case CipherSuite.TLS_ECDHE_RSA_WITH_RC4_128_SHA: case CipherSuite.TLS_RSA_WITH_RC4_128_SHA: return cipherFactory.createCipher(context, EncryptionAlgorithm.RC4_128, MACAlgorithm.hmac_sha1); case CipherSuite.TLS_DH_DSS_WITH_SEED_CBC_SHA: case CipherSuite.TLS_DH_RSA_WITH_SEED_CBC_SHA: case CipherSuite.TLS_DHE_DSS_WITH_SEED_CBC_SHA: case CipherSuite.TLS_DHE_RSA_WITH_SEED_CBC_SHA: case CipherSuite.TLS_RSA_WITH_SEED_CBC_SHA: return cipherFactory.createCipher(context, EncryptionAlgorithm.SEED_CBC, MACAlgorithm.hmac_sha1); default: /* * Note: internal error here; selected a cipher suite we don't implement! */ throw new TlsFatalAlert(AlertDescription.internal_error); } } protected TlsKeyExchange createDHKeyExchange(int keyExchange) { return new TlsDHKeyExchange(keyExchange, supportedSignatureAlgorithms, getDHParameters()); } protected TlsKeyExchange createDHEKeyExchange(int keyExchange) { return new TlsDHEKeyExchange(keyExchange, supportedSignatureAlgorithms, getDHParameters()); } protected TlsKeyExchange createECDHKeyExchange(int keyExchange) { return new TlsECDHKeyExchange(keyExchange, supportedSignatureAlgorithms, namedCurves, clientECPointFormats, serverECPointFormats); } protected TlsKeyExchange createECDHEKeyExchange(int keyExchange) { return new TlsECDHEKeyExchange(keyExchange, supportedSignatureAlgorithms, namedCurves, clientECPointFormats, serverECPointFormats); } protected TlsKeyExchange createRSAKeyExchange() { return new TlsRSAKeyExchange(supportedSignatureAlgorithms); } } bouncycastle-1.49.orig/src/org/bouncycastle/crypto/tls/CipherSuite.java0000644000175000017500000002577312151551725025735 0ustar ebourgebourgpackage org.bouncycastle.crypto.tls; /** * RFC 2246 A.5 */ public class CipherSuite { public static final int TLS_NULL_WITH_NULL_NULL = 0x0000; public static final int TLS_RSA_WITH_NULL_MD5 = 0x0001; public static final int TLS_RSA_WITH_NULL_SHA = 0x0002; public static final int TLS_RSA_EXPORT_WITH_RC4_40_MD5 = 0x0003; public static final int TLS_RSA_WITH_RC4_128_MD5 = 0x0004; public static final int TLS_RSA_WITH_RC4_128_SHA = 0x0005; public static final int TLS_RSA_EXPORT_WITH_RC2_CBC_40_MD5 = 0x0006; public static final int TLS_RSA_WITH_IDEA_CBC_SHA = 0x0007; public static final int TLS_RSA_EXPORT_WITH_DES40_CBC_SHA = 0x0008; public static final int TLS_RSA_WITH_DES_CBC_SHA = 0x0009; public static final int TLS_RSA_WITH_3DES_EDE_CBC_SHA = 0x000A; public static final int TLS_DH_DSS_EXPORT_WITH_DES40_CBC_SHA = 0x000B; public static final int TLS_DH_DSS_WITH_DES_CBC_SHA = 0x000C; public static final int TLS_DH_DSS_WITH_3DES_EDE_CBC_SHA = 0x000D; public static final int TLS_DH_RSA_EXPORT_WITH_DES40_CBC_SHA = 0x000E; public static final int TLS_DH_RSA_WITH_DES_CBC_SHA = 0x000F; public static final int TLS_DH_RSA_WITH_3DES_EDE_CBC_SHA = 0x0010; public static final int TLS_DHE_DSS_EXPORT_WITH_DES40_CBC_SHA = 0x0011; public static final int TLS_DHE_DSS_WITH_DES_CBC_SHA = 0x0012; public static final int TLS_DHE_DSS_WITH_3DES_EDE_CBC_SHA = 0x0013; public static final int TLS_DHE_RSA_EXPORT_WITH_DES40_CBC_SHA = 0x0014; public static final int TLS_DHE_RSA_WITH_DES_CBC_SHA = 0x0015; public static final int TLS_DHE_RSA_WITH_3DES_EDE_CBC_SHA = 0x0016; public static final int TLS_DH_anon_EXPORT_WITH_RC4_40_MD5 = 0x0017; public static final int TLS_DH_anon_WITH_RC4_128_MD5 = 0x0018; public static final int TLS_DH_anon_EXPORT_WITH_DES40_CBC_SHA = 0x0019; public static final int TLS_DH_anon_WITH_DES_CBC_SHA = 0x001A; public static final int TLS_DH_anon_WITH_3DES_EDE_CBC_SHA = 0x001B; /* * Note: The cipher suite values { 0x00, 0x1C } and { 0x00, 0x1D } are reserved to avoid * collision with Fortezza-based cipher suites in SSL 3. */ /* * RFC 3268 */ public static final int TLS_RSA_WITH_AES_128_CBC_SHA = 0x002F; public static final int TLS_DH_DSS_WITH_AES_128_CBC_SHA = 0x0030; public static final int TLS_DH_RSA_WITH_AES_128_CBC_SHA = 0x0031; public static final int TLS_DHE_DSS_WITH_AES_128_CBC_SHA = 0x0032; public static final int TLS_DHE_RSA_WITH_AES_128_CBC_SHA = 0x0033; public static final int TLS_DH_anon_WITH_AES_128_CBC_SHA = 0x0034; public static final int TLS_RSA_WITH_AES_256_CBC_SHA = 0x0035; public static final int TLS_DH_DSS_WITH_AES_256_CBC_SHA = 0x0036; public static final int TLS_DH_RSA_WITH_AES_256_CBC_SHA = 0x0037; public static final int TLS_DHE_DSS_WITH_AES_256_CBC_SHA = 0x0038; public static final int TLS_DHE_RSA_WITH_AES_256_CBC_SHA = 0x0039; public static final int TLS_DH_anon_WITH_AES_256_CBC_SHA = 0x003A; /* * RFC 4132 */ public static final int TLS_RSA_WITH_CAMELLIA_128_CBC_SHA = 0x0041; public static final int TLS_DH_DSS_WITH_CAMELLIA_128_CBC_SHA = 0x0042; public static final int TLS_DH_RSA_WITH_CAMELLIA_128_CBC_SHA = 0x0043; public static final int TLS_DHE_DSS_WITH_CAMELLIA_128_CBC_SHA = 0x0044; public static final int TLS_DHE_RSA_WITH_CAMELLIA_128_CBC_SHA = 0x0045; public static final int TLS_DH_anon_WITH_CAMELLIA_128_CBC_SHA = 0x0046; public static final int TLS_RSA_WITH_CAMELLIA_256_CBC_SHA = 0x0084; public static final int TLS_DH_DSS_WITH_CAMELLIA_256_CBC_SHA = 0x0085; public static final int TLS_DH_RSA_WITH_CAMELLIA_256_CBC_SHA = 0x0086; public static final int TLS_DHE_DSS_WITH_CAMELLIA_256_CBC_SHA = 0x0087; public static final int TLS_DHE_RSA_WITH_CAMELLIA_256_CBC_SHA = 0x0088; public static final int TLS_DH_anon_WITH_CAMELLIA_256_CBC_SHA = 0x0089; /* * RFC 4162 */ public static final int TLS_RSA_WITH_SEED_CBC_SHA = 0x0096; public static final int TLS_DH_DSS_WITH_SEED_CBC_SHA = 0x0097; public static final int TLS_DH_RSA_WITH_SEED_CBC_SHA = 0x0098; public static final int TLS_DHE_DSS_WITH_SEED_CBC_SHA = 0x0099; public static final int TLS_DHE_RSA_WITH_SEED_CBC_SHA = 0x009A; public static final int TLS_DH_anon_WITH_SEED_CBC_SHA = 0x009B; /* * RFC 4279 */ public static final int TLS_PSK_WITH_RC4_128_SHA = 0x008A; public static final int TLS_PSK_WITH_3DES_EDE_CBC_SHA = 0x008B; public static final int TLS_PSK_WITH_AES_128_CBC_SHA = 0x008C; public static final int TLS_PSK_WITH_AES_256_CBC_SHA = 0x008D; public static final int TLS_DHE_PSK_WITH_RC4_128_SHA = 0x008E; public static final int TLS_DHE_PSK_WITH_3DES_EDE_CBC_SHA = 0x008F; public static final int TLS_DHE_PSK_WITH_AES_128_CBC_SHA = 0x0090; public static final int TLS_DHE_PSK_WITH_AES_256_CBC_SHA = 0x0091; public static final int TLS_RSA_PSK_WITH_RC4_128_SHA = 0x0092; public static final int TLS_RSA_PSK_WITH_3DES_EDE_CBC_SHA = 0x0093; public static final int TLS_RSA_PSK_WITH_AES_128_CBC_SHA = 0x0094; public static final int TLS_RSA_PSK_WITH_AES_256_CBC_SHA = 0x0095; /* * RFC 4492 */ public static final int TLS_ECDH_ECDSA_WITH_NULL_SHA = 0xC001; public static final int TLS_ECDH_ECDSA_WITH_RC4_128_SHA = 0xC002; public static final int TLS_ECDH_ECDSA_WITH_3DES_EDE_CBC_SHA = 0xC003; public static final int TLS_ECDH_ECDSA_WITH_AES_128_CBC_SHA = 0xC004; public static final int TLS_ECDH_ECDSA_WITH_AES_256_CBC_SHA = 0xC005; public static final int TLS_ECDHE_ECDSA_WITH_NULL_SHA = 0xC006; public static final int TLS_ECDHE_ECDSA_WITH_RC4_128_SHA = 0xC007; public static final int TLS_ECDHE_ECDSA_WITH_3DES_EDE_CBC_SHA = 0xC008; public static final int TLS_ECDHE_ECDSA_WITH_AES_128_CBC_SHA = 0xC009; public static final int TLS_ECDHE_ECDSA_WITH_AES_256_CBC_SHA = 0xC00A; public static final int TLS_ECDH_RSA_WITH_NULL_SHA = 0xC00B; public static final int TLS_ECDH_RSA_WITH_RC4_128_SHA = 0xC00C; public static final int TLS_ECDH_RSA_WITH_3DES_EDE_CBC_SHA = 0xC00D; public static final int TLS_ECDH_RSA_WITH_AES_128_CBC_SHA = 0xC00E; public static final int TLS_ECDH_RSA_WITH_AES_256_CBC_SHA = 0xC00F; public static final int TLS_ECDHE_RSA_WITH_NULL_SHA = 0xC010; public static final int TLS_ECDHE_RSA_WITH_RC4_128_SHA = 0xC011; public static final int TLS_ECDHE_RSA_WITH_3DES_EDE_CBC_SHA = 0xC012; public static final int TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA = 0xC013; public static final int TLS_ECDHE_RSA_WITH_AES_256_CBC_SHA = 0xC014; public static final int TLS_ECDH_anon_WITH_NULL_SHA = 0xC015; public static final int TLS_ECDH_anon_WITH_RC4_128_SHA = 0xC016; public static final int TLS_ECDH_anon_WITH_3DES_EDE_CBC_SHA = 0xC017; public static final int TLS_ECDH_anon_WITH_AES_128_CBC_SHA = 0xC018; public static final int TLS_ECDH_anon_WITH_AES_256_CBC_SHA = 0xC019; /* * RFC 4785 */ public static final int TLS_PSK_WITH_NULL_SHA = 0x002C; public static final int TLS_DHE_PSK_WITH_NULL_SHA = 0x002D; public static final int TLS_RSA_PSK_WITH_NULL_SHA = 0x002E; /* * RFC 5054 */ public static final int TLS_SRP_SHA_WITH_3DES_EDE_CBC_SHA = 0xC01A; public static final int TLS_SRP_SHA_RSA_WITH_3DES_EDE_CBC_SHA = 0xC01B; public static final int TLS_SRP_SHA_DSS_WITH_3DES_EDE_CBC_SHA = 0xC01C; public static final int TLS_SRP_SHA_WITH_AES_128_CBC_SHA = 0xC01D; public static final int TLS_SRP_SHA_RSA_WITH_AES_128_CBC_SHA = 0xC01E; public static final int TLS_SRP_SHA_DSS_WITH_AES_128_CBC_SHA = 0xC01F; public static final int TLS_SRP_SHA_WITH_AES_256_CBC_SHA = 0xC020; public static final int TLS_SRP_SHA_RSA_WITH_AES_256_CBC_SHA = 0xC021; public static final int TLS_SRP_SHA_DSS_WITH_AES_256_CBC_SHA = 0xC022; /* * RFC 5246 */ public static final int TLS_RSA_WITH_NULL_SHA256 = 0x003B; public static final int TLS_RSA_WITH_AES_128_CBC_SHA256 = 0x003C; public static final int TLS_RSA_WITH_AES_256_CBC_SHA256 = 0x003D; public static final int TLS_DH_DSS_WITH_AES_128_CBC_SHA256 = 0x003E; public static final int TLS_DH_RSA_WITH_AES_128_CBC_SHA256 = 0x003F; public static final int TLS_DHE_DSS_WITH_AES_128_CBC_SHA256 = 0x0040; public static final int TLS_DHE_RSA_WITH_AES_128_CBC_SHA256 = 0x0067; public static final int TLS_DH_DSS_WITH_AES_256_CBC_SHA256 = 0x0068; public static final int TLS_DH_RSA_WITH_AES_256_CBC_SHA256 = 0x0069; public static final int TLS_DHE_DSS_WITH_AES_256_CBC_SHA256 = 0x006A; public static final int TLS_DHE_RSA_WITH_AES_256_CBC_SHA256 = 0x006B; public static final int TLS_DH_anon_WITH_AES_128_CBC_SHA256 = 0x006C; public static final int TLS_DH_anon_WITH_AES_256_CBC_SHA256 = 0x006D; /* * RFC 5288 */ public static final int TLS_RSA_WITH_AES_128_GCM_SHA256 = 0x009C; public static final int TLS_RSA_WITH_AES_256_GCM_SHA384 = 0x009D; public static final int TLS_DHE_RSA_WITH_AES_128_GCM_SHA256 = 0x009E; public static final int TLS_DHE_RSA_WITH_AES_256_GCM_SHA384 = 0x009F; public static final int TLS_DH_RSA_WITH_AES_128_GCM_SHA256 = 0x00A0; public static final int TLS_DH_RSA_WITH_AES_256_GCM_SHA384 = 0x00A1; public static final int TLS_DHE_DSS_WITH_AES_128_GCM_SHA256 = 0x00A2; public static final int TLS_DHE_DSS_WITH_AES_256_GCM_SHA384 = 0x00A3; public static final int TLS_DH_DSS_WITH_AES_128_GCM_SHA256 = 0x00A4; public static final int TLS_DH_DSS_WITH_AES_256_GCM_SHA384 = 0x00A5; public static final int TLS_DH_anon_WITH_AES_128_GCM_SHA256 = 0x00A6; public static final int TLS_DH_anon_WITH_AES_256_GCM_SHA384 = 0x00A7; /* * RFC 5289 */ public static final int TLS_ECDHE_ECDSA_WITH_AES_128_CBC_SHA256 = 0xC023; public static final int TLS_ECDHE_ECDSA_WITH_AES_256_CBC_SHA384 = 0xC024; public static final int TLS_ECDH_ECDSA_WITH_AES_128_CBC_SHA256 = 0xC025; public static final int TLS_ECDH_ECDSA_WITH_AES_256_CBC_SHA384 = 0xC026; public static final int TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA256 = 0xC027; public static final int TLS_ECDHE_RSA_WITH_AES_256_CBC_SHA384 = 0xC028; public static final int TLS_ECDH_RSA_WITH_AES_128_CBC_SHA256 = 0xC029; public static final int TLS_ECDH_RSA_WITH_AES_256_CBC_SHA384 = 0xC02A; public static final int TLS_ECDHE_ECDSA_WITH_AES_128_GCM_SHA256 = 0xC02B; public static final int TLS_ECDHE_ECDSA_WITH_AES_256_GCM_SHA384 = 0xC02C; public static final int TLS_ECDH_ECDSA_WITH_AES_128_GCM_SHA256 = 0xC02D; public static final int TLS_ECDH_ECDSA_WITH_AES_256_GCM_SHA384 = 0xC02E; public static final int TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256 = 0xC02F; public static final int TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384 = 0xC030; public static final int TLS_ECDH_RSA_WITH_AES_128_GCM_SHA256 = 0xC031; public static final int TLS_ECDH_RSA_WITH_AES_256_GCM_SHA384 = 0xC032; /* * RFC 5746 */ public static final int TLS_EMPTY_RENEGOTIATION_INFO_SCSV = 0x00FF; } bouncycastle-1.49.orig/src/org/bouncycastle/crypto/tls/TlsUtils.java0000644000175000017500000007302112151551725025261 0ustar ebourgebourgpackage org.bouncycastle.crypto.tls; import java.io.ByteArrayInputStream; import java.io.ByteArrayOutputStream; import java.io.EOFException; import java.io.IOException; import java.io.InputStream; import java.io.OutputStream; import java.util.Hashtable; import java.util.Vector; import org.bouncycastle.asn1.ASN1ObjectIdentifier; import org.bouncycastle.asn1.nist.NISTObjectIdentifiers; import org.bouncycastle.asn1.pkcs.PKCSObjectIdentifiers; import org.bouncycastle.asn1.x509.Extensions; import org.bouncycastle.asn1.x509.KeyUsage; import org.bouncycastle.asn1.x509.SubjectPublicKeyInfo; import org.bouncycastle.asn1.x509.X509ObjectIdentifiers; import org.bouncycastle.crypto.Digest; import org.bouncycastle.crypto.digests.MD5Digest; import org.bouncycastle.crypto.digests.SHA1Digest; import org.bouncycastle.crypto.digests.SHA224Digest; import org.bouncycastle.crypto.digests.SHA256Digest; import org.bouncycastle.crypto.digests.SHA384Digest; import org.bouncycastle.crypto.digests.SHA512Digest; import org.bouncycastle.crypto.macs.HMac; import org.bouncycastle.crypto.params.AsymmetricKeyParameter; import org.bouncycastle.crypto.params.DSAPublicKeyParameters; import org.bouncycastle.crypto.params.ECPublicKeyParameters; import org.bouncycastle.crypto.params.KeyParameter; import org.bouncycastle.crypto.params.RSAKeyParameters; import org.bouncycastle.crypto.util.PublicKeyFactory; import org.bouncycastle.util.Arrays; import org.bouncycastle.util.Integers; import org.bouncycastle.util.Strings; import org.bouncycastle.util.io.Streams; /** * Some helper functions for MicroTLS. */ public class TlsUtils { public static byte[] EMPTY_BYTES = new byte[0]; public static final Integer EXT_signature_algorithms = Integers.valueOf(ExtensionType.signature_algorithms); public static boolean isValidUint8(short i) { return (i & 0xFF) == i; } public static boolean isValidUint16(int i) { return (i & 0xFFFF) == i; } public static boolean isValidUint24(int i) { return (i & 0xFFFFFF) == i; } public static boolean isValidUint32(long i) { return (i & 0xFFFFFFFFL) == i; } public static boolean isValidUint48(long i) { return (i & 0xFFFFFFFFFFFFL) == i; } public static boolean isValidUint64(long i) { return true; } public static void writeUint8(short i, OutputStream output) throws IOException { output.write(i); } public static void writeUint8(short i, byte[] buf, int offset) { buf[offset] = (byte)i; } public static void writeUint16(int i, OutputStream output) throws IOException { output.write(i >> 8); output.write(i); } public static void writeUint16(int i, byte[] buf, int offset) { buf[offset] = (byte)(i >> 8); buf[offset + 1] = (byte)i; } public static void writeUint24(int i, OutputStream output) throws IOException { output.write(i >> 16); output.write(i >> 8); output.write(i); } public static void writeUint24(int i, byte[] buf, int offset) { buf[offset] = (byte)(i >> 16); buf[offset + 1] = (byte)(i >> 8); buf[offset + 2] = (byte)(i); } public static void writeUint32(long i, OutputStream output) throws IOException { output.write((int)(i >> 24)); output.write((int)(i >> 16)); output.write((int)(i >> 8)); output.write((int)(i)); } public static void writeUint32(long i, byte[] buf, int offset) { buf[offset] = (byte)(i >> 24); buf[offset + 1] = (byte)(i >> 16); buf[offset + 2] = (byte)(i >> 8); buf[offset + 3] = (byte)(i); } public static void writeUint48(long i, byte[] buf, int offset) { buf[offset] = (byte)(i >> 40); buf[offset + 1] = (byte)(i >> 32); buf[offset + 2] = (byte)(i >> 24); buf[offset + 3] = (byte)(i >> 16); buf[offset + 4] = (byte)(i >> 8); buf[offset + 5] = (byte)(i); } public static void writeUint64(long i, OutputStream output) throws IOException { output.write((int)(i >> 56)); output.write((int)(i >> 48)); output.write((int)(i >> 40)); output.write((int)(i >> 32)); output.write((int)(i >> 24)); output.write((int)(i >> 16)); output.write((int)(i >> 8)); output.write((int)(i)); } public static void writeUint64(long i, byte[] buf, int offset) { buf[offset] = (byte)(i >> 56); buf[offset + 1] = (byte)(i >> 48); buf[offset + 2] = (byte)(i >> 40); buf[offset + 3] = (byte)(i >> 32); buf[offset + 4] = (byte)(i >> 24); buf[offset + 5] = (byte)(i >> 16); buf[offset + 6] = (byte)(i >> 8); buf[offset + 7] = (byte)(i); } public static void writeOpaque8(byte[] buf, OutputStream output) throws IOException { writeUint8((short)buf.length, output); output.write(buf); } public static void writeOpaque16(byte[] buf, OutputStream output) throws IOException { writeUint16(buf.length, output); output.write(buf); } public static void writeOpaque24(byte[] buf, OutputStream output) throws IOException { writeUint24(buf.length, output); output.write(buf); } public static void writeUint8Array(short[] uints, OutputStream output) throws IOException { for (int i = 0; i < uints.length; ++i) { writeUint8(uints[i], output); } } public static void writeUint16Array(int[] uints, OutputStream output) throws IOException { for (int i = 0; i < uints.length; ++i) { writeUint16(uints[i], output); } } public static short readUint8(InputStream input) throws IOException { int i = input.read(); if (i < 0) { throw new EOFException(); } return (short)i; } public static short readUint8(byte[] buf, int offset) { return (short)buf[offset]; } public static int readUint16(InputStream input) throws IOException { int i1 = input.read(); int i2 = input.read(); if (i2 < 0) { throw new EOFException(); } return i1 << 8 | i2; } public static int readUint16(byte[] buf, int offset) { int n = (buf[offset] & 0xff) << 8; n |= (buf[++offset] & 0xff); return n; } public static int readUint24(InputStream input) throws IOException { int i1 = input.read(); int i2 = input.read(); int i3 = input.read(); if (i3 < 0) { throw new EOFException(); } return (i1 << 16) | (i2 << 8) | i3; } public static int readUint24(byte[] buf, int offset) { int n = (buf[offset] & 0xff) << 16; n |= (buf[++offset] & 0xff) << 8; n |= (buf[++offset] & 0xff); return n; } public static long readUint32(InputStream input) throws IOException { int i1 = input.read(); int i2 = input.read(); int i3 = input.read(); int i4 = input.read(); if (i4 < 0) { throw new EOFException(); } return (((long)i1) << 24) | (((long)i2) << 16) | (((long)i3) << 8) | ((long)i4); } public static long readUint48(InputStream input) throws IOException { int i1 = input.read(); int i2 = input.read(); int i3 = input.read(); int i4 = input.read(); int i5 = input.read(); int i6 = input.read(); if (i6 < 0) { throw new EOFException(); } return (((long)i1) << 40) | (((long)i2) << 32) | (((long)i3) << 24) | (((long)i4) << 16) | (((long)i5) << 8) | ((long)i6); } public static long readUint48(byte[] buf, int offset) { int hi = readUint24(buf, offset); int lo = readUint24(buf, offset + 3); return ((long)(hi & 0xffffffffL) << 24) | (long)(lo & 0xffffffffL); } public static byte[] readFully(int length, InputStream input) throws IOException { if (length < 1) { return EMPTY_BYTES; } byte[] buf = new byte[length]; if (length != Streams.readFully(input, buf)) { throw new EOFException(); } return buf; } public static void readFully(byte[] buf, InputStream input) throws IOException { int length = buf.length; if (length > 0 && length != Streams.readFully(input, buf)) { throw new EOFException(); } } public static byte[] readOpaque8(InputStream input) throws IOException { short length = readUint8(input); return readFully(length, input); } public static byte[] readOpaque16(InputStream input) throws IOException { int length = readUint16(input); return readFully(length, input); } public static byte[] readOpaque24(InputStream input) throws IOException { int length = readUint24(input); return readFully(length, input); } public static short[] readUint8Array(int count, InputStream input) throws IOException { short[] uints = new short[count]; for (int i = 0; i < count; ++i) { uints[i] = readUint8(input); } return uints; } public static int[] readUint16Array(int count, InputStream input) throws IOException { int[] uints = new int[count]; for (int i = 0; i < count; ++i) { uints[i] = readUint16(input); } return uints; } public static ProtocolVersion readVersion(byte[] buf, int offset) throws IOException { return ProtocolVersion.get(buf[offset] & 0xFF, buf[offset + 1] & 0xFF); } public static ProtocolVersion readVersion(InputStream input) throws IOException { int i1 = input.read(); int i2 = input.read(); if (i2 < 0) { throw new EOFException(); } return ProtocolVersion.get(i1, i2); } public static int readVersionRaw(InputStream input) throws IOException { int i1 = input.read(); int i2 = input.read(); if (i2 < 0) { throw new EOFException(); } return (i1 << 8) | i2; } public static void writeGMTUnixTime(byte[] buf, int offset) { int t = (int)(System.currentTimeMillis() / 1000L); buf[offset] = (byte)(t >> 24); buf[offset + 1] = (byte)(t >> 16); buf[offset + 2] = (byte)(t >> 8); buf[offset + 3] = (byte)t; } public static void writeVersion(ProtocolVersion version, OutputStream output) throws IOException { output.write(version.getMajorVersion()); output.write(version.getMinorVersion()); } public static void writeVersion(ProtocolVersion version, byte[] buf, int offset) throws IOException { buf[offset] = (byte)version.getMajorVersion(); buf[offset + 1] = (byte)version.getMinorVersion(); } public static Vector getDefaultDSSSignatureAlgorithms() { return vectorOfOne(new SignatureAndHashAlgorithm(HashAlgorithm.sha1, SignatureAlgorithm.dsa)); } public static Vector getDefaultECDSASignatureAlgorithms() { return vectorOfOne(new SignatureAndHashAlgorithm(HashAlgorithm.sha1, SignatureAlgorithm.ecdsa)); } public static Vector getDefaultRSASignatureAlgorithms() { return vectorOfOne(new SignatureAndHashAlgorithm(HashAlgorithm.sha1, SignatureAlgorithm.rsa)); } public static boolean isSignatureAlgorithmsExtensionAllowed(ProtocolVersion clientVersion) { return ProtocolVersion.TLSv12.isEqualOrEarlierVersionOf(clientVersion.getEquivalentTLSVersion()); } /** * Add a 'signature_algorithms' extension to existing extensions. * * @param extensions A {@link Hashtable} to add the extension to. * @param supportedSignatureAlgorithms {@link Vector} containing at least 1 {@link SignatureAndHashAlgorithm}. * @throws IOException */ public static void addSignatureAlgorithmsExtension(Hashtable extensions, Vector supportedSignatureAlgorithms) throws IOException { extensions.put(EXT_signature_algorithms, createSignatureAlgorithmsExtension(supportedSignatureAlgorithms)); } /** * Get a 'signature_algorithms' extension from extensions. * * @param extensions A {@link Hashtable} to get the extension from, if it is present. * @return A {@link Vector} containing at least 1 {@link SignatureAndHashAlgorithm}, or null. * @throws IOException */ public static Vector getSignatureAlgorithmsExtension(Hashtable extensions) throws IOException { if (extensions == null) { return null; } byte[] extensionValue = (byte[])extensions.get(EXT_signature_algorithms); if (extensionValue == null) { return null; } return readSignatureAlgorithmsExtension(extensionValue); } /** * Create a 'signature_algorithms' extension value. * * @param supportedSignatureAlgorithms A {@link Vector} containing at least 1 {@link SignatureAndHashAlgorithm}. * @return A byte array suitable for use as an extension value. * @throws IOException */ public static byte[] createSignatureAlgorithmsExtension(Vector supportedSignatureAlgorithms) throws IOException { if (supportedSignatureAlgorithms == null || supportedSignatureAlgorithms.size() < 1 || supportedSignatureAlgorithms.size() >= (1 << 15)) { throw new IllegalArgumentException( "'supportedSignatureAlgorithms' must have length from 1 to (2^15 - 1)"); } ByteArrayOutputStream buf = new ByteArrayOutputStream(); // supported_signature_algorithms TlsUtils.writeUint16(2 * supportedSignatureAlgorithms.size(), buf); for (int i = 0; i < supportedSignatureAlgorithms.size(); ++i) { SignatureAndHashAlgorithm entry = (SignatureAndHashAlgorithm)supportedSignatureAlgorithms.elementAt(i); entry.encode(buf); } return buf.toByteArray(); } /** * Read a 'signature_algorithms' extension value. * * @param extensionValue The extension value. * @return A {@link Vector} containing at least 1 {@link SignatureAndHashAlgorithm}. * @throws IOException */ public static Vector readSignatureAlgorithmsExtension(byte[] extensionValue) throws IOException { if (extensionValue == null) { throw new IllegalArgumentException("'extensionValue' cannot be null"); } ByteArrayInputStream buf = new ByteArrayInputStream(extensionValue); // supported_signature_algorithms int length = TlsUtils.readUint16(buf); if (length < 2 || (length & 1) != 0) { throw new TlsFatalAlert(AlertDescription.decode_error); } int count = length / 2; Vector result = new Vector(count); for (int i = 0; i < count; ++i) { SignatureAndHashAlgorithm entry = SignatureAndHashAlgorithm.parse(buf); result.addElement(entry); } TlsProtocol.assertEmpty(buf); return result; } public static byte[] PRF(TlsContext context, byte[] secret, String asciiLabel, byte[] seed, int size) { ProtocolVersion version = context.getServerVersion(); if (version.isSSL()) { throw new IllegalStateException("No PRF available for SSLv3 session"); } byte[] label = Strings.toByteArray(asciiLabel); byte[] labelSeed = concat(label, seed); int prfAlgorithm = context.getSecurityParameters().getPrfAlgorithm(); if (prfAlgorithm == PRFAlgorithm.tls_prf_legacy) { if (!ProtocolVersion.TLSv12.isEqualOrEarlierVersionOf(version.getEquivalentTLSVersion())) { return PRF_legacy(secret, label, labelSeed, size); } prfAlgorithm = PRFAlgorithm.tls_prf_sha256; } Digest prfDigest = createPRFHash(prfAlgorithm); byte[] buf = new byte[size]; hmac_hash(prfDigest, secret, labelSeed, buf); return buf; } static byte[] PRF_legacy(byte[] secret, byte[] label, byte[] labelSeed, int size) { int s_half = (secret.length + 1) / 2; byte[] s1 = new byte[s_half]; byte[] s2 = new byte[s_half]; System.arraycopy(secret, 0, s1, 0, s_half); System.arraycopy(secret, secret.length - s_half, s2, 0, s_half); byte[] b1 = new byte[size]; byte[] b2 = new byte[size]; hmac_hash(new MD5Digest(), s1, labelSeed, b1); hmac_hash(new SHA1Digest(), s2, labelSeed, b2); for (int i = 0; i < size; i++) { b1[i] ^= b2[i]; } return b1; } static byte[] concat(byte[] a, byte[] b) { byte[] c = new byte[a.length + b.length]; System.arraycopy(a, 0, c, 0, a.length); System.arraycopy(b, 0, c, a.length, b.length); return c; } static void hmac_hash(Digest digest, byte[] secret, byte[] seed, byte[] out) { HMac mac = new HMac(digest); KeyParameter param = new KeyParameter(secret); byte[] a = seed; int size = digest.getDigestSize(); int iterations = (out.length + size - 1) / size; byte[] buf = new byte[mac.getMacSize()]; byte[] buf2 = new byte[mac.getMacSize()]; for (int i = 0; i < iterations; i++) { mac.init(param); mac.update(a, 0, a.length); mac.doFinal(buf, 0); a = buf; mac.init(param); mac.update(a, 0, a.length); mac.update(seed, 0, seed.length); mac.doFinal(buf2, 0); System.arraycopy(buf2, 0, out, (size * i), Math.min(size, out.length - (size * i))); } } static void validateKeyUsage(org.bouncycastle.asn1.x509.Certificate c, int keyUsageBits) throws IOException { Extensions exts = c.getTBSCertificate().getExtensions(); if (exts != null) { KeyUsage ku = KeyUsage.fromExtensions(exts); if (ku != null) { int bits = ku.getBytes()[0] & 0xff; if ((bits & keyUsageBits) != keyUsageBits) { throw new TlsFatalAlert(AlertDescription.certificate_unknown); } } } } static byte[] calculateKeyBlock(TlsContext context, int size) { SecurityParameters securityParameters = context.getSecurityParameters(); byte[] master_secret = securityParameters.getMasterSecret(); byte[] seed = concat(securityParameters.getServerRandom(), securityParameters.getClientRandom()); if (context.getServerVersion().isSSL()) { return calculateKeyBlock_SSL(master_secret, seed, size); } return PRF(context, master_secret, ExporterLabel.key_expansion, seed, size); } static byte[] calculateKeyBlock_SSL(byte[] master_secret, byte[] random, int size) { Digest md5 = new MD5Digest(); Digest sha1 = new SHA1Digest(); int md5Size = md5.getDigestSize(); byte[] shatmp = new byte[sha1.getDigestSize()]; byte[] tmp = new byte[size + md5Size]; int i = 0, pos = 0; while (pos < size) { byte[] ssl3Const = SSL3_CONST[i]; sha1.update(ssl3Const, 0, ssl3Const.length); sha1.update(master_secret, 0, master_secret.length); sha1.update(random, 0, random.length); sha1.doFinal(shatmp, 0); md5.update(master_secret, 0, master_secret.length); md5.update(shatmp, 0, shatmp.length); md5.doFinal(tmp, pos); pos += md5Size; ++i; } byte rval[] = new byte[size]; System.arraycopy(tmp, 0, rval, 0, size); return rval; } static byte[] calculateMasterSecret(TlsContext context, byte[] pre_master_secret) { SecurityParameters securityParameters = context.getSecurityParameters(); byte[] seed = concat(securityParameters.getClientRandom(), securityParameters.getServerRandom()); if (context.getServerVersion().isSSL()) { return calculateMasterSecret_SSL(pre_master_secret, seed); } return PRF(context, pre_master_secret, ExporterLabel.master_secret, seed, 48); } static byte[] calculateMasterSecret_SSL(byte[] pre_master_secret, byte[] random) { Digest md5 = new MD5Digest(); Digest sha1 = new SHA1Digest(); int md5Size = md5.getDigestSize(); byte[] shatmp = new byte[sha1.getDigestSize()]; byte[] rval = new byte[md5Size * 3]; int pos = 0; for (int i = 0; i < 3; ++i) { byte[] ssl3Const = SSL3_CONST[i]; sha1.update(ssl3Const, 0, ssl3Const.length); sha1.update(pre_master_secret, 0, pre_master_secret.length); sha1.update(random, 0, random.length); sha1.doFinal(shatmp, 0); md5.update(pre_master_secret, 0, pre_master_secret.length); md5.update(shatmp, 0, shatmp.length); md5.doFinal(rval, pos); pos += md5Size; } return rval; } static byte[] calculateVerifyData(TlsContext context, String asciiLabel, byte[] handshakeHash) { if (context.getServerVersion().isSSL()) { return handshakeHash; } SecurityParameters securityParameters = context.getSecurityParameters(); byte[] master_secret = securityParameters.getMasterSecret(); int verify_data_length = securityParameters.getVerifyDataLength(); return PRF(context, master_secret, asciiLabel, handshakeHash, verify_data_length); } public static final Digest createHash(int hashAlgorithm) { switch (hashAlgorithm) { case HashAlgorithm.md5: return new MD5Digest(); case HashAlgorithm.sha1: return new SHA1Digest(); case HashAlgorithm.sha224: return new SHA224Digest(); case HashAlgorithm.sha256: return new SHA256Digest(); case HashAlgorithm.sha384: return new SHA384Digest(); case HashAlgorithm.sha512: return new SHA512Digest(); default: throw new IllegalArgumentException("unknown HashAlgorithm"); } } public static final Digest cloneHash(int hashAlgorithm, Digest hash) { switch (hashAlgorithm) { case HashAlgorithm.md5: return new MD5Digest((MD5Digest)hash); case HashAlgorithm.sha1: return new SHA1Digest((SHA1Digest)hash); case HashAlgorithm.sha224: return new SHA224Digest((SHA224Digest)hash); case HashAlgorithm.sha256: return new SHA256Digest((SHA256Digest)hash); case HashAlgorithm.sha384: return new SHA384Digest((SHA384Digest)hash); case HashAlgorithm.sha512: return new SHA512Digest((SHA512Digest)hash); default: throw new IllegalArgumentException("unknown HashAlgorithm"); } } public static final Digest createPRFHash(int prfAlgorithm) { switch (prfAlgorithm) { case PRFAlgorithm.tls_prf_legacy: return new CombinedHash(); default: return createHash(getHashAlgorithmForPRFAlgorithm(prfAlgorithm)); } } public static final Digest clonePRFHash(int prfAlgorithm, Digest hash) { switch (prfAlgorithm) { case PRFAlgorithm.tls_prf_legacy: return new CombinedHash((CombinedHash)hash); default: return cloneHash(getHashAlgorithmForPRFAlgorithm(prfAlgorithm), hash); } } public static final short getHashAlgorithmForPRFAlgorithm(int prfAlgorithm) { switch (prfAlgorithm) { case PRFAlgorithm.tls_prf_legacy: throw new IllegalArgumentException("legacy PRF not a valid algorithm"); case PRFAlgorithm.tls_prf_sha256: return HashAlgorithm.sha256; case PRFAlgorithm.tls_prf_sha384: return HashAlgorithm.sha384; default: throw new IllegalArgumentException("unknown PRFAlgorithm"); } } public static ASN1ObjectIdentifier getOIDForHashAlgorithm(int hashAlgorithm) { switch (hashAlgorithm) { case HashAlgorithm.md5: return PKCSObjectIdentifiers.md5; case HashAlgorithm.sha1: return X509ObjectIdentifiers.id_SHA1; case HashAlgorithm.sha224: return NISTObjectIdentifiers.id_sha224; case HashAlgorithm.sha256: return NISTObjectIdentifiers.id_sha256; case HashAlgorithm.sha384: return NISTObjectIdentifiers.id_sha384; case HashAlgorithm.sha512: return NISTObjectIdentifiers.id_sha512; default: throw new IllegalArgumentException("unknown HashAlgorithm"); } } static short getClientCertificateType(Certificate clientCertificate, Certificate serverCertificate) throws IOException { if (clientCertificate.isEmpty()) { return -1; } org.bouncycastle.asn1.x509.Certificate x509Cert = clientCertificate.getCertificateAt(0); SubjectPublicKeyInfo keyInfo = x509Cert.getSubjectPublicKeyInfo(); try { AsymmetricKeyParameter publicKey = PublicKeyFactory.createKey(keyInfo); if (publicKey.isPrivate()) { throw new TlsFatalAlert(AlertDescription.internal_error); } /* * TODO RFC 5246 7.4.6. The certificates MUST be signed using an acceptable hash/ * signature algorithm pair, as described in Section 7.4.4. Note that this relaxes the * constraints on certificate-signing algorithms found in prior versions of TLS. */ /* * RFC 5246 7.4.6. Client Certificate */ /* * RSA public key; the certificate MUST allow the key to be used for signing with the * signature scheme and hash algorithm that will be employed in the certificate verify * message. */ if (publicKey instanceof RSAKeyParameters) { validateKeyUsage(x509Cert, KeyUsage.digitalSignature); return ClientCertificateType.rsa_sign; } /* * DSA public key; the certificate MUST allow the key to be used for signing with the * hash algorithm that will be employed in the certificate verify message. */ if (publicKey instanceof DSAPublicKeyParameters) { validateKeyUsage(x509Cert, KeyUsage.digitalSignature); return ClientCertificateType.dss_sign; } /* * ECDSA-capable public key; the certificate MUST allow the key to be used for signing * with the hash algorithm that will be employed in the certificate verify message; the * public key MUST use a curve and point format supported by the server. */ if (publicKey instanceof ECPublicKeyParameters) { validateKeyUsage(x509Cert, KeyUsage.digitalSignature); // TODO Check the curve and point format return ClientCertificateType.ecdsa_sign; } // TODO Add support for ClientCertificateType.*_fixed_* } catch (Exception e) { } throw new TlsFatalAlert(AlertDescription.unsupported_certificate); } public static boolean hasSigningCapability(short clientCertificateType) { switch (clientCertificateType) { case ClientCertificateType.dss_sign: case ClientCertificateType.ecdsa_sign: case ClientCertificateType.rsa_sign: return true; default: return false; } } public static TlsSigner createTlsSigner(short clientCertificateType) { switch (clientCertificateType) { case ClientCertificateType.dss_sign: return new TlsDSSSigner(); case ClientCertificateType.ecdsa_sign: return new TlsECDSASigner(); case ClientCertificateType.rsa_sign: return new TlsRSASigner(); default: throw new IllegalArgumentException("'clientCertificateType' is not a type with signing capability"); } } static final byte[] SSL_CLIENT = {0x43, 0x4C, 0x4E, 0x54}; static final byte[] SSL_SERVER = {0x53, 0x52, 0x56, 0x52}; // SSL3 magic mix constants ("A", "BB", "CCC", ...) static final byte[][] SSL3_CONST = genConst(); private static byte[][] genConst() { int n = 10; byte[][] arr = new byte[n][]; for (int i = 0; i < n; i++) { byte[] b = new byte[i + 1]; Arrays.fill(b, (byte)('A' + i)); arr[i] = b; } return arr; } private static Vector vectorOfOne(Object obj) { Vector v = new Vector(1); v.addElement(obj); return v; } } bouncycastle-1.49.orig/src/org/bouncycastle/crypto/tls/SignatureAndHashAlgorithm.java0000644000175000017500000000467112151551725030542 0ustar ebourgebourgpackage org.bouncycastle.crypto.tls; import java.io.IOException; import java.io.InputStream; import java.io.OutputStream; /** * RFC 5246 7.4.1.4.1 */ public class SignatureAndHashAlgorithm { private short hash; private short signature; /** * @param hash {@link HashAlgorithm} * @param signature {@link SignatureAlgorithm} */ public SignatureAndHashAlgorithm(short hash, short signature) { if (!TlsUtils.isValidUint8(hash)) { throw new IllegalArgumentException("'hash' should be a uint8"); } if (!TlsUtils.isValidUint8(signature)) { throw new IllegalArgumentException("'signature' should be a uint8"); } if (signature == SignatureAlgorithm.anonymous) { throw new IllegalArgumentException("'signature' MUST NOT be \"anonymous\""); } this.hash = hash; this.signature = signature; } /** * @return {@link HashAlgorithm} */ public short getHash() { return hash; } /** * @return {@link SignatureAlgorithm} */ public short getSignature() { return signature; } public boolean equals(Object obj) { if (!(obj instanceof SignatureAndHashAlgorithm)) { return false; } SignatureAndHashAlgorithm other = (SignatureAndHashAlgorithm)obj; return other.getHash() == getHash() && other.getSignature() == getSignature(); } public int hashCode() { return (getHash() << 8) | getSignature(); } /** * Encode this {@link SignatureAndHashAlgorithm} to an {@link OutputStream}. * * @param output the {@link OutputStream} to encode to. * @throws IOException */ public void encode(OutputStream output) throws IOException { TlsUtils.writeUint8(hash, output); TlsUtils.writeUint8(signature, output); } /** * Parse a {@link SignatureAndHashAlgorithm} from an {@link InputStream}. * * @param input the {@link InputStream} to parse from. * @return a {@link SignatureAndHashAlgorithm} object. * @throws IOException */ public static SignatureAndHashAlgorithm parse(InputStream input) throws IOException { short hash = TlsUtils.readUint8(input); short signature = TlsUtils.readUint8(input); return new SignatureAndHashAlgorithm(hash, signature); } } bouncycastle-1.49.orig/src/org/bouncycastle/crypto/tls/TlsECDHKeyExchange.java0000644000175000017500000001761112151551725027003 0ustar ebourgebourgpackage org.bouncycastle.crypto.tls; import java.io.IOException; import java.io.InputStream; import java.io.OutputStream; import java.util.Vector; import org.bouncycastle.asn1.x509.KeyUsage; import org.bouncycastle.asn1.x509.SubjectPublicKeyInfo; import org.bouncycastle.crypto.AsymmetricCipherKeyPair; import org.bouncycastle.crypto.params.AsymmetricKeyParameter; import org.bouncycastle.crypto.params.ECDomainParameters; import org.bouncycastle.crypto.params.ECPrivateKeyParameters; import org.bouncycastle.crypto.params.ECPublicKeyParameters; import org.bouncycastle.crypto.util.PublicKeyFactory; /** * ECDH key exchange (see RFC 4492) */ public class TlsECDHKeyExchange extends AbstractTlsKeyExchange { protected TlsSigner tlsSigner; protected int[] namedCurves; protected short[] clientECPointFormats, serverECPointFormats; protected AsymmetricKeyParameter serverPublicKey; protected ECPublicKeyParameters ecAgreeServerPublicKey; protected TlsAgreementCredentials agreementCredentials; protected ECPrivateKeyParameters ecAgreeClientPrivateKey; protected ECPrivateKeyParameters ecAgreeServerPrivateKey; protected ECPublicKeyParameters ecAgreeClientPublicKey; public TlsECDHKeyExchange(int keyExchange, Vector supportedSignatureAlgorithms, int[] namedCurves, short[] clientECPointFormats, short[] serverECPointFormats) { super(keyExchange, supportedSignatureAlgorithms); switch (keyExchange) { case KeyExchangeAlgorithm.ECDHE_RSA: this.tlsSigner = new TlsRSASigner(); break; case KeyExchangeAlgorithm.ECDHE_ECDSA: this.tlsSigner = new TlsECDSASigner(); break; case KeyExchangeAlgorithm.ECDH_RSA: case KeyExchangeAlgorithm.ECDH_ECDSA: this.tlsSigner = null; break; default: throw new IllegalArgumentException("unsupported key exchange algorithm"); } this.keyExchange = keyExchange; this.namedCurves = namedCurves; this.clientECPointFormats = clientECPointFormats; this.serverECPointFormats = serverECPointFormats; } public void init(TlsContext context) { super.init(context); if (this.tlsSigner != null) { this.tlsSigner.init(context); } } public void skipServerCredentials() throws IOException { throw new TlsFatalAlert(AlertDescription.unexpected_message); } public void processServerCertificate(Certificate serverCertificate) throws IOException { if (serverCertificate.isEmpty()) { throw new TlsFatalAlert(AlertDescription.bad_certificate); } org.bouncycastle.asn1.x509.Certificate x509Cert = serverCertificate.getCertificateAt(0); SubjectPublicKeyInfo keyInfo = x509Cert.getSubjectPublicKeyInfo(); try { this.serverPublicKey = PublicKeyFactory.createKey(keyInfo); } catch (RuntimeException e) { throw new TlsFatalAlert(AlertDescription.unsupported_certificate); } if (tlsSigner == null) { try { this.ecAgreeServerPublicKey = TlsECCUtils .validateECPublicKey((ECPublicKeyParameters)this.serverPublicKey); } catch (ClassCastException e) { throw new TlsFatalAlert(AlertDescription.certificate_unknown); } TlsUtils.validateKeyUsage(x509Cert, KeyUsage.keyAgreement); } else { if (!tlsSigner.isValidPublicKey(this.serverPublicKey)) { throw new TlsFatalAlert(AlertDescription.certificate_unknown); } TlsUtils.validateKeyUsage(x509Cert, KeyUsage.digitalSignature); } super.processServerCertificate(serverCertificate); } public boolean requiresServerKeyExchange() { switch (keyExchange) { case KeyExchangeAlgorithm.ECDHE_ECDSA: case KeyExchangeAlgorithm.ECDHE_RSA: case KeyExchangeAlgorithm.ECDH_anon: return true; default: return false; } } public void validateCertificateRequest(CertificateRequest certificateRequest) throws IOException { /* * RFC 4492 3. [...] The ECDSA_fixed_ECDH and RSA_fixed_ECDH mechanisms are usable with * ECDH_ECDSA and ECDH_RSA. Their use with ECDHE_ECDSA and ECDHE_RSA is prohibited because * the use of a long-term ECDH client key would jeopardize the forward secrecy property of * these algorithms. */ short[] types = certificateRequest.getCertificateTypes(); for (int i = 0; i < types.length; ++i) { switch (types[i]) { case ClientCertificateType.rsa_sign: case ClientCertificateType.dss_sign: case ClientCertificateType.ecdsa_sign: case ClientCertificateType.rsa_fixed_ecdh: case ClientCertificateType.ecdsa_fixed_ecdh: break; default: throw new TlsFatalAlert(AlertDescription.illegal_parameter); } } } public void processClientCredentials(TlsCredentials clientCredentials) throws IOException { if (clientCredentials instanceof TlsAgreementCredentials) { // TODO Validate client cert has matching parameters (see 'TlsECCUtils.areOnSameCurve')? this.agreementCredentials = (TlsAgreementCredentials)clientCredentials; } else if (clientCredentials instanceof TlsSignerCredentials) { // OK } else { throw new TlsFatalAlert(AlertDescription.internal_error); } } public void generateClientKeyExchange(OutputStream output) throws IOException { if (agreementCredentials != null) { return; } AsymmetricCipherKeyPair ecAgreeClientKeyPair = TlsECCUtils.generateECKeyPair(context.getSecureRandom(), ecAgreeServerPublicKey.getParameters()); this.ecAgreeClientPrivateKey = (ECPrivateKeyParameters)ecAgreeClientKeyPair.getPrivate(); byte[] point = TlsECCUtils.serializeECPublicKey(serverECPointFormats, (ECPublicKeyParameters)ecAgreeClientKeyPair.getPublic()); TlsUtils.writeOpaque8(point, output); } public void processClientCertificate(Certificate clientCertificate) throws IOException { // TODO Extract the public key // TODO If the certificate is 'fixed', take the public key as ecAgreeClientPublicKey } public void processClientKeyExchange(InputStream input) throws IOException { if (ecAgreeClientPublicKey != null) { // For ecdsa_fixed_ecdh and rsa_fixed_ecdh, the key arrived in the client certificate return; } byte[] point = TlsUtils.readOpaque8(input); ECDomainParameters curve_params = this.ecAgreeServerPrivateKey.getParameters(); this.ecAgreeClientPublicKey = TlsECCUtils.validateECPublicKey(TlsECCUtils.deserializeECPublicKey( serverECPointFormats, curve_params, point)); } public byte[] generatePremasterSecret() throws IOException { if (agreementCredentials != null) { return agreementCredentials.generateAgreement(ecAgreeServerPublicKey); } if (ecAgreeServerPrivateKey != null) { return TlsECCUtils.calculateECDHBasicAgreement(ecAgreeClientPublicKey, ecAgreeServerPrivateKey); } if (ecAgreeClientPrivateKey != null) { return TlsECCUtils.calculateECDHBasicAgreement(ecAgreeServerPublicKey, ecAgreeClientPrivateKey); } throw new TlsFatalAlert(AlertDescription.internal_error); } } bouncycastle-1.49.orig/src/org/bouncycastle/crypto/tls/TlsSigner.java0000644000175000017500000000127012146535331025404 0ustar ebourgebourgpackage org.bouncycastle.crypto.tls; import org.bouncycastle.crypto.CryptoException; import org.bouncycastle.crypto.Signer; import org.bouncycastle.crypto.params.AsymmetricKeyParameter; public interface TlsSigner { void init(TlsContext context); byte[] generateRawSignature(AsymmetricKeyParameter privateKey, byte[] md5AndSha1) throws CryptoException; boolean verifyRawSignature(byte[] sigBytes, AsymmetricKeyParameter publicKey, byte[] md5AndSha1) throws CryptoException; Signer createSigner(AsymmetricKeyParameter privateKey); Signer createVerifyer(AsymmetricKeyParameter publicKey); boolean isValidPublicKey(AsymmetricKeyParameter publicKey); } bouncycastle-1.49.orig/src/org/bouncycastle/crypto/tls/ECBasisType.java0000644000175000017500000000033512151551725025607 0ustar ebourgebourgpackage org.bouncycastle.crypto.tls; /** * RFC 4492 5.4. (Errata ID: 2389) */ public class ECBasisType { public static final short ec_basis_trinomial = 1; public static final short ec_basis_pentanomial = 2; } bouncycastle-1.49.orig/src/org/bouncycastle/crypto/tls/TlsServer.java0000644000175000017500000000473312151551725025433 0ustar ebourgebourgpackage org.bouncycastle.crypto.tls; import java.io.IOException; import java.util.Hashtable; import java.util.Vector; public interface TlsServer extends TlsPeer { void init(TlsServerContext context); void notifyClientVersion(ProtocolVersion clientVersion) throws IOException; void notifyOfferedCipherSuites(int[] offeredCipherSuites) throws IOException; void notifyOfferedCompressionMethods(short[] offeredCompressionMethods) throws IOException; void notifySecureRenegotiation(boolean secureNegotiation) throws IOException; // Hashtable is (Integer -> byte[]) void processClientExtensions(Hashtable clientExtensions) throws IOException; ProtocolVersion getServerVersion() throws IOException; int getSelectedCipherSuite() throws IOException; short getSelectedCompressionMethod() throws IOException; // Hashtable is (Integer -> byte[]) Hashtable getServerExtensions() throws IOException; // Vector is (SupplementalDataEntry) Vector getServerSupplementalData() throws IOException; TlsCredentials getCredentials() throws IOException; TlsKeyExchange getKeyExchange() throws IOException; CertificateRequest getCertificateRequest(); // Vector is (SupplementalDataEntry) void processClientSupplementalData(Vector clientSupplementalData) throws IOException; /** * Called by the protocol handler to report the client certificate, only if a Certificate * {@link #getCertificateRequest()} returned non-null. Note: this method is responsible for * certificate verification and validation. * * @param clientCertificate the effective client certificate (may be an empty chain). * @throws IOException */ void notifyClientCertificate(Certificate clientCertificate) throws IOException; TlsCompression getCompression() throws IOException; TlsCipher getCipher() throws IOException; /** * RFC 5077 3.3. NewSessionTicket Handshake Message. *

    * This method will be called (only) if a NewSessionTicket extension was sent by the server. See * RFC 5077 4. Recommended Ticket Construction for recommended format and protection. * * @return The ticket. * @throws IOException */ NewSessionTicket getNewSessionTicket() throws IOException; void notifyHandshakeComplete() throws IOException; } bouncycastle-1.49.orig/src/org/bouncycastle/crypto/tls/AbstractTlsServer.java0000644000175000017500000002365012151551725027116 0ustar ebourgebourgpackage org.bouncycastle.crypto.tls; import java.io.IOException; import java.util.Hashtable; import java.util.Vector; public abstract class AbstractTlsServer extends AbstractTlsPeer implements TlsServer { protected TlsCipherFactory cipherFactory; protected TlsServerContext context; protected ProtocolVersion clientVersion; protected int[] offeredCipherSuites; protected short[] offeredCompressionMethods; protected Hashtable clientExtensions; protected Vector supportedSignatureAlgorithms; protected boolean eccCipherSuitesOffered; protected int[] namedCurves; protected short[] clientECPointFormats, serverECPointFormats; protected ProtocolVersion serverVersion; protected int selectedCipherSuite; protected short selectedCompressionMethod; protected Hashtable serverExtensions; public AbstractTlsServer() { this(new DefaultTlsCipherFactory()); } public AbstractTlsServer(TlsCipherFactory cipherFactory) { this.cipherFactory = cipherFactory; } protected abstract int[] getCipherSuites(); protected short[] getCompressionMethods() { return new short[]{CompressionMethod._null}; } protected ProtocolVersion getMaximumVersion() { return ProtocolVersion.TLSv11; } protected ProtocolVersion getMinimumVersion() { return ProtocolVersion.TLSv10; } protected boolean supportsClientECCCapabilities(int[] namedCurves, short[] ecPointFormats) { // NOTE: BC supports all the current set of point formats so we don't check them here if (namedCurves == null) { /* * RFC 4492 4. A client that proposes ECC cipher suites may choose not to include these * extensions. In this case, the server is free to choose any one of the elliptic curves * or point formats [...]. */ return TlsECCUtils.hasAnySupportedNamedCurves(); } for (int i = 0; i < namedCurves.length; ++i) { int namedCurve = namedCurves[i]; if (!NamedCurve.refersToASpecificNamedCurve(namedCurve) || TlsECCUtils.isSupportedNamedCurve(namedCurve)) { return true; } } return false; } public void init(TlsServerContext context) { this.context = context; } public void notifyClientVersion(ProtocolVersion clientVersion) throws IOException { this.clientVersion = clientVersion; } public void notifyOfferedCipherSuites(int[] offeredCipherSuites) throws IOException { this.offeredCipherSuites = offeredCipherSuites; this.eccCipherSuitesOffered = TlsECCUtils.containsECCCipherSuites(this.offeredCipherSuites); } public void notifyOfferedCompressionMethods(short[] offeredCompressionMethods) throws IOException { this.offeredCompressionMethods = offeredCompressionMethods; } public void notifySecureRenegotiation(boolean secureRenegotiation) throws IOException { if (!secureRenegotiation) { /* * RFC 5746 3.6. In this case, some servers may want to terminate the handshake instead * of continuing; see Section 4.3 for discussion. */ throw new TlsFatalAlert(AlertDescription.handshake_failure); } } public void processClientExtensions(Hashtable clientExtensions) throws IOException { this.clientExtensions = clientExtensions; if (clientExtensions != null) { this.supportedSignatureAlgorithms = TlsUtils.getSignatureAlgorithmsExtension(clientExtensions); if (this.supportedSignatureAlgorithms != null) { /* * RFC 5246 7.4.1.4.1. Note: this extension is not meaningful for TLS versions prior * to 1.2. Clients MUST NOT offer it if they are offering prior versions. */ if (!TlsUtils.isSignatureAlgorithmsExtensionAllowed(clientVersion)) { throw new TlsFatalAlert(AlertDescription.illegal_parameter); } } this.namedCurves = TlsECCUtils.getSupportedEllipticCurvesExtension(clientExtensions); this.clientECPointFormats = TlsECCUtils.getSupportedPointFormatsExtension(clientExtensions); } /* * RFC 4429 4. The client MUST NOT include these extensions in the ClientHello message if it * does not propose any ECC cipher suites. */ if (!this.eccCipherSuitesOffered && (this.namedCurves != null || this.clientECPointFormats != null)) { throw new TlsFatalAlert(AlertDescription.illegal_parameter); } } public ProtocolVersion getServerVersion() throws IOException { if (getMinimumVersion().isEqualOrEarlierVersionOf(clientVersion)) { ProtocolVersion maximumVersion = getMaximumVersion(); if (clientVersion.isEqualOrEarlierVersionOf(maximumVersion)) { return serverVersion = clientVersion; } if (clientVersion.isLaterVersionOf(maximumVersion)) { return serverVersion = maximumVersion; } } throw new TlsFatalAlert(AlertDescription.protocol_version); } public int getSelectedCipherSuite() throws IOException { /* * TODO RFC 5246 7.4.3. In order to negotiate correctly, the server MUST check any candidate * cipher suites against the "signature_algorithms" extension before selecting them. This is * somewhat inelegant but is a compromise designed to minimize changes to the original * cipher suite design. */ /* * RFC 4429 5.1. A server that receives a ClientHello containing one or both of these * extensions MUST use the client's enumerated capabilities to guide its selection of an * appropriate cipher suite. One of the proposed ECC cipher suites must be negotiated only * if the server can successfully complete the handshake while using the curves and point * formats supported by the client [...]. */ boolean eccCipherSuitesEnabled = supportsClientECCCapabilities(this.namedCurves, this.clientECPointFormats); int[] cipherSuites = getCipherSuites(); for (int i = 0; i < cipherSuites.length; ++i) { int cipherSuite = cipherSuites[i]; if (TlsProtocol.arrayContains(this.offeredCipherSuites, cipherSuite) && (eccCipherSuitesEnabled || !TlsECCUtils.isECCCipherSuite(cipherSuite))) { return this.selectedCipherSuite = cipherSuite; } } throw new TlsFatalAlert(AlertDescription.handshake_failure); } public short getSelectedCompressionMethod() throws IOException { short[] compressionMethods = getCompressionMethods(); for (int i = 0; i < compressionMethods.length; ++i) { if (TlsProtocol.arrayContains(offeredCompressionMethods, compressionMethods[i])) { return this.selectedCompressionMethod = compressionMethods[i]; } } throw new TlsFatalAlert(AlertDescription.handshake_failure); } // Hashtable is (Integer -> byte[]) public Hashtable getServerExtensions() throws IOException { if (this.clientECPointFormats != null && TlsECCUtils.isECCCipherSuite(this.selectedCipherSuite)) { /* * RFC 4492 5.2. A server that selects an ECC cipher suite in response to a ClientHello * message including a Supported Point Formats Extension appends this extension (along * with others) to its ServerHello message, enumerating the point formats it can parse. */ this.serverECPointFormats = new short[]{ECPointFormat.ansiX962_compressed_char2, ECPointFormat.ansiX962_compressed_prime, ECPointFormat.uncompressed}; this.serverExtensions = new Hashtable(); TlsECCUtils.addSupportedPointFormatsExtension(serverExtensions, serverECPointFormats); return serverExtensions; } return null; } public Vector getServerSupplementalData() throws IOException { return null; } public CertificateRequest getCertificateRequest() { return null; } public void processClientSupplementalData(Vector clientSupplementalData) throws IOException { if (clientSupplementalData != null) { throw new TlsFatalAlert(AlertDescription.unexpected_message); } } public void notifyClientCertificate(Certificate clientCertificate) throws IOException { throw new TlsFatalAlert(AlertDescription.internal_error); } public TlsCompression getCompression() throws IOException { switch (selectedCompressionMethod) { case CompressionMethod._null: return new TlsNullCompression(); default: /* * Note: internal error here; we selected the compression method, so if we now can't * produce an implementation, we shouldn't have chosen it! */ throw new TlsFatalAlert(AlertDescription.internal_error); } } public NewSessionTicket getNewSessionTicket() throws IOException { /* * RFC 5077 3.3. If the server determines that it does not want to include a ticket after it * has included the SessionTicket extension in the ServerHello, then it sends a zero-length * ticket in the NewSessionTicket handshake message. */ return new NewSessionTicket(0L, TlsUtils.EMPTY_BYTES); } public void notifyHandshakeComplete() throws IOException { } } bouncycastle-1.49.orig/src/org/bouncycastle/crypto/tls/TlsECDHEKeyExchange.java0000644000175000017500000001573212151551725027112 0ustar ebourgebourgpackage org.bouncycastle.crypto.tls; import java.io.ByteArrayOutputStream; import java.io.IOException; import java.io.InputStream; import java.util.Vector; import org.bouncycastle.crypto.AsymmetricCipherKeyPair; import org.bouncycastle.crypto.Digest; import org.bouncycastle.crypto.Signer; import org.bouncycastle.crypto.io.SignerInputStream; import org.bouncycastle.crypto.params.ECDomainParameters; import org.bouncycastle.crypto.params.ECPrivateKeyParameters; import org.bouncycastle.crypto.params.ECPublicKeyParameters; /** * ECDHE key exchange (see RFC 4492) */ public class TlsECDHEKeyExchange extends TlsECDHKeyExchange { protected TlsSignerCredentials serverCredentials = null; public TlsECDHEKeyExchange(int keyExchange, Vector supportedSignatureAlgorithms, int[] namedCurves, short[] clientECPointFormats, short[] serverECPointFormats) { super(keyExchange, supportedSignatureAlgorithms, namedCurves, clientECPointFormats, serverECPointFormats); } public void processServerCredentials(TlsCredentials serverCredentials) throws IOException { if (!(serverCredentials instanceof TlsSignerCredentials)) { throw new TlsFatalAlert(AlertDescription.internal_error); } processServerCertificate(serverCredentials.getCertificate()); this.serverCredentials = (TlsSignerCredentials)serverCredentials; } public byte[] generateServerKeyExchange() throws IOException { /* * First we try to find a supported named curve from the client's list. */ int namedCurve = -1; if (namedCurves == null) { namedCurve = NamedCurve.secp256r1; } else { for (int i = 0; i < namedCurves.length; ++i) { int entry = namedCurves[i]; if (TlsECCUtils.isSupportedNamedCurve(entry)) { namedCurve = entry; break; } } } ECDomainParameters curve_params = null; if (namedCurve >= 0) { curve_params = TlsECCUtils.getParametersForNamedCurve(namedCurve); } else { /* * If no named curves are suitable, check if the client supports explicit curves. */ if (TlsProtocol.arrayContains(namedCurves, NamedCurve.arbitrary_explicit_prime_curves)) { curve_params = TlsECCUtils.getParametersForNamedCurve(NamedCurve.secp256r1); } else if (TlsProtocol.arrayContains(namedCurves, NamedCurve.arbitrary_explicit_char2_curves)) { curve_params = TlsECCUtils.getParametersForNamedCurve(NamedCurve.sect233r1); } } if (curve_params == null) { /* * NOTE: We shouldn't have negotiated ECDHE key exchange since we apparently can't find * a suitable curve. */ throw new TlsFatalAlert(AlertDescription.internal_error); } AsymmetricCipherKeyPair kp = TlsECCUtils.generateECKeyPair(context.getSecureRandom(), curve_params); this.ecAgreeServerPrivateKey = (ECPrivateKeyParameters)kp.getPrivate(); byte[] publicBytes = TlsECCUtils.serializeECPublicKey(clientECPointFormats, (ECPublicKeyParameters)kp.getPublic()); ByteArrayOutputStream buf = new ByteArrayOutputStream(); if (namedCurve < 0) { TlsECCUtils.writeExplicitECParameters(clientECPointFormats, curve_params, buf); } else { TlsECCUtils.writeNamedECParameters(namedCurve, buf); } TlsUtils.writeOpaque8(publicBytes, buf); byte[] digestInput = buf.toByteArray(); Digest d = new CombinedHash(); SecurityParameters securityParameters = context.getSecurityParameters(); d.update(securityParameters.clientRandom, 0, securityParameters.clientRandom.length); d.update(securityParameters.serverRandom, 0, securityParameters.serverRandom.length); d.update(digestInput, 0, digestInput.length); byte[] hash = new byte[d.getDigestSize()]; d.doFinal(hash, 0); byte[] sigBytes = serverCredentials.generateCertificateSignature(hash); /* * TODO RFC 5246 4.7. digitally-signed element needs SignatureAndHashAlgorithm prepended * from TLS 1.2 */ TlsUtils.writeOpaque16(sigBytes, buf); return buf.toByteArray(); } public void processServerKeyExchange(InputStream input) throws IOException { SecurityParameters securityParameters = context.getSecurityParameters(); Signer signer = initVerifyer(tlsSigner, securityParameters); InputStream sigIn = new SignerInputStream(input, signer); ECDomainParameters curve_params = TlsECCUtils.readECParameters(namedCurves, clientECPointFormats, sigIn); byte[] point = TlsUtils.readOpaque8(sigIn); byte[] sigByte = TlsUtils.readOpaque16(input); if (!signer.verifySignature(sigByte)) { throw new TlsFatalAlert(AlertDescription.decrypt_error); } this.ecAgreeServerPublicKey = TlsECCUtils.validateECPublicKey(TlsECCUtils.deserializeECPublicKey( clientECPointFormats, curve_params, point)); } public void validateCertificateRequest(CertificateRequest certificateRequest) throws IOException { /* * RFC 4492 3. [...] The ECDSA_fixed_ECDH and RSA_fixed_ECDH mechanisms are usable with * ECDH_ECDSA and ECDH_RSA. Their use with ECDHE_ECDSA and ECDHE_RSA is prohibited because * the use of a long-term ECDH client key would jeopardize the forward secrecy property of * these algorithms. */ short[] types = certificateRequest.getCertificateTypes(); for (int i = 0; i < types.length; ++i) { switch (types[i]) { case ClientCertificateType.rsa_sign: case ClientCertificateType.dss_sign: case ClientCertificateType.ecdsa_sign: break; default: throw new TlsFatalAlert(AlertDescription.illegal_parameter); } } } public void processClientCredentials(TlsCredentials clientCredentials) throws IOException { if (clientCredentials instanceof TlsSignerCredentials) { // OK } else { throw new TlsFatalAlert(AlertDescription.internal_error); } } protected Signer initVerifyer(TlsSigner tlsSigner, SecurityParameters securityParameters) { Signer signer = tlsSigner.createVerifyer(this.serverPublicKey); signer.update(securityParameters.clientRandom, 0, securityParameters.clientRandom.length); signer.update(securityParameters.serverRandom, 0, securityParameters.serverRandom.length); return signer; } } bouncycastle-1.49.orig/src/org/bouncycastle/crypto/tls/BulkCipherAlgorithm.java0000644000175000017500000000112112151551725027365 0ustar ebourgebourgpackage org.bouncycastle.crypto.tls; /** * RFC 2246 *

    * Note that the values here are implementation-specific and arbitrary. It is recommended not to * depend on the particular values (e.g. serialization). */ public class BulkCipherAlgorithm { public static final int _null = 0; public static final int rc4 = 1; public static final int rc2 = 2; public static final int des = 3; public static final int _3des = 4; public static final int des40 = 5; /* * RFC 4346 */ public static final int aes = 6; public static final int idea = 7; } bouncycastle-1.49.orig/src/org/bouncycastle/crypto/tls/ProtocolVersion.java0000644000175000017500000000565012151551725026650 0ustar ebourgebourgpackage org.bouncycastle.crypto.tls; import java.io.IOException; public final class ProtocolVersion { public static final ProtocolVersion SSLv3 = new ProtocolVersion(0x0300, "SSL 3.0"); public static final ProtocolVersion TLSv10 = new ProtocolVersion(0x0301, "TLS 1.0"); public static final ProtocolVersion TLSv11 = new ProtocolVersion(0x0302, "TLS 1.1"); public static final ProtocolVersion TLSv12 = new ProtocolVersion(0x0303, "TLS 1.2"); public static final ProtocolVersion DTLSv10 = new ProtocolVersion(0xFEFF, "DTLS 1.0"); public static final ProtocolVersion DTLSv12 = new ProtocolVersion(0xFEFD, "DTLS 1.2"); private int version; private String name; private ProtocolVersion(int v, String name) { this.version = v & 0xffff; this.name = name; } public int getFullVersion() { return version; } public int getMajorVersion() { return version >> 8; } public int getMinorVersion() { return version & 0xff; } public boolean isDTLS() { return getMajorVersion() == 0xFE; } public boolean isSSL() { return this == SSLv3; } public ProtocolVersion getEquivalentTLSVersion() { if (!isDTLS()) { return this; } if (this == DTLSv10) { return TLSv11; } return TLSv12; } public boolean isEqualOrEarlierVersionOf(ProtocolVersion version) { if (getMajorVersion() != version.getMajorVersion()) { return false; } int diffMinorVersion = version.getMinorVersion() - getMinorVersion(); return isDTLS() ? diffMinorVersion <= 0 : diffMinorVersion >= 0; } public boolean isLaterVersionOf(ProtocolVersion version) { if (getMajorVersion() != version.getMajorVersion()) { return false; } int diffMinorVersion = version.getMinorVersion() - getMinorVersion(); return isDTLS() ? diffMinorVersion > 0 : diffMinorVersion < 0; } public boolean equals(Object obj) { return this == obj; } public int hashCode() { return version; } public static ProtocolVersion get(int major, int minor) throws IOException { switch (major) { case 0x03: switch (minor) { case 0x00: return SSLv3; case 0x01: return TLSv10; case 0x02: return TLSv11; case 0x03: return TLSv12; } case 0xFE: switch (minor) { case 0xFF: return DTLSv10; case 0xFD: return DTLSv12; } } throw new TlsFatalAlert(AlertDescription.illegal_parameter); } public String toString() { return name; } } bouncycastle-1.49.orig/src/org/bouncycastle/crypto/tls/TlsAEADCipher.java0000644000175000017500000001573112151551725026012 0ustar ebourgebourgpackage org.bouncycastle.crypto.tls; import java.io.IOException; import org.bouncycastle.crypto.modes.AEADBlockCipher; import org.bouncycastle.crypto.params.AEADParameters; import org.bouncycastle.crypto.params.KeyParameter; import org.bouncycastle.util.Arrays; public class TlsAEADCipher implements TlsCipher { protected TlsContext context; protected int macSize; protected int nonce_explicit_length; protected AEADBlockCipher encryptCipher; protected AEADBlockCipher decryptCipher; protected byte[] encryptImplicitNonce, decryptImplicitNonce; public TlsAEADCipher(TlsContext context, AEADBlockCipher clientWriteCipher, AEADBlockCipher serverWriteCipher, int cipherKeySize, int macSize) throws IOException { if (!ProtocolVersion.TLSv12.isEqualOrEarlierVersionOf(context.getServerVersion().getEquivalentTLSVersion())) { throw new TlsFatalAlert(AlertDescription.internal_error); } this.context = context; this.macSize = macSize; // NOTE: Valid for RFC 5288 ciphers but may need review for other AEAD ciphers this.nonce_explicit_length = 8; // TODO SecurityParameters.fixed_iv_length int fixed_iv_length = 4; int key_block_size = (2 * cipherKeySize) + (2 * fixed_iv_length); byte[] key_block = TlsUtils.calculateKeyBlock(context, key_block_size); int offset = 0; KeyParameter client_write_key = new KeyParameter(key_block, offset, cipherKeySize); offset += cipherKeySize; KeyParameter server_write_key = new KeyParameter(key_block, offset, cipherKeySize); offset += cipherKeySize; byte[] client_write_IV = Arrays.copyOfRange(key_block, offset, offset + fixed_iv_length); offset += fixed_iv_length; byte[] server_write_IV = Arrays.copyOfRange(key_block, offset, offset + fixed_iv_length); offset += fixed_iv_length; if (offset != key_block_size) { throw new TlsFatalAlert(AlertDescription.internal_error); } KeyParameter encryptKey, decryptKey; if (context.isServer()) { this.encryptCipher = serverWriteCipher; this.decryptCipher = clientWriteCipher; this.encryptImplicitNonce = server_write_IV; this.decryptImplicitNonce = client_write_IV; encryptKey = server_write_key; decryptKey = client_write_key; } else { this.encryptCipher = clientWriteCipher; this.decryptCipher = serverWriteCipher; this.encryptImplicitNonce = client_write_IV; this.decryptImplicitNonce = server_write_IV; encryptKey = client_write_key; decryptKey = server_write_key; } byte[] dummyNonce = new byte[fixed_iv_length + nonce_explicit_length]; this.encryptCipher.init(true, new AEADParameters(encryptKey, 8 * macSize, dummyNonce)); this.decryptCipher.init(false, new AEADParameters(decryptKey, 8 * macSize, dummyNonce)); } public int getPlaintextLimit(int ciphertextLimit) { // TODO We ought to be able to ask the decryptCipher (independently of it's current state!) return ciphertextLimit - macSize - nonce_explicit_length; } public byte[] encodePlaintext(long seqNo, short type, byte[] plaintext, int offset, int len) throws IOException { byte[] nonce = new byte[this.encryptImplicitNonce.length + nonce_explicit_length]; System.arraycopy(encryptImplicitNonce, 0, nonce, 0, encryptImplicitNonce.length); /* * RFC 5288 The nonce_explicit MAY be the 64-bit sequence number. * * (May need review for other AEAD ciphers). */ TlsUtils.writeUint64(seqNo, nonce, encryptImplicitNonce.length); int plaintextOffset = offset; int plaintextLength = len; int ciphertextLength = encryptCipher.getOutputSize(plaintextLength); byte[] output = new byte[nonce_explicit_length + ciphertextLength]; System.arraycopy(nonce, encryptImplicitNonce.length, output, 0, nonce_explicit_length); int outputPos = nonce_explicit_length; encryptCipher.init(true, new AEADParameters(null, 8 * macSize, nonce, getAdditionalData(seqNo, type, plaintextLength))); outputPos += encryptCipher.processBytes(plaintext, plaintextOffset, plaintextLength, output, outputPos); try { outputPos += encryptCipher.doFinal(output, outputPos); } catch (Exception e) { throw new TlsFatalAlert(AlertDescription.internal_error); } if (outputPos != output.length) { // NOTE: Existing AEAD cipher implementations all give exact output lengths throw new TlsFatalAlert(AlertDescription.internal_error); } return output; } public byte[] decodeCiphertext(long seqNo, short type, byte[] ciphertext, int offset, int len) throws IOException { if (getPlaintextLimit(len) < 0) { throw new TlsFatalAlert(AlertDescription.decode_error); } byte[] nonce = new byte[this.decryptImplicitNonce.length + nonce_explicit_length]; System.arraycopy(decryptImplicitNonce, 0, nonce, 0, decryptImplicitNonce.length); System.arraycopy(ciphertext, offset, nonce, decryptImplicitNonce.length, nonce_explicit_length); int ciphertextOffset = offset + nonce_explicit_length; int ciphertextLength = len - nonce_explicit_length; int plaintextLength = decryptCipher.getOutputSize(ciphertextLength); byte[] output = new byte[plaintextLength]; int outputPos = 0; decryptCipher.init(false, new AEADParameters(null, 8 * macSize, nonce, getAdditionalData(seqNo, type, plaintextLength))); outputPos += decryptCipher.processBytes(ciphertext, ciphertextOffset, ciphertextLength, output, outputPos); try { outputPos += decryptCipher.doFinal(output, outputPos); } catch (Exception e) { throw new TlsFatalAlert(AlertDescription.bad_record_mac); } if (outputPos != output.length) { // NOTE: Existing AEAD cipher implementations all give exact output lengths throw new TlsFatalAlert(AlertDescription.internal_error); } return output; } protected byte[] getAdditionalData(long seqNo, short type, int len) throws IOException { /* * additional_data = seq_num + TLSCompressed.type + TLSCompressed.version + * TLSCompressed.length */ byte[] additional_data = new byte[13]; TlsUtils.writeUint64(seqNo, additional_data, 0); TlsUtils.writeUint8(type, additional_data, 8); TlsUtils.writeVersion(context.getServerVersion(), additional_data, 9); TlsUtils.writeUint16(len, additional_data, 11); return additional_data; } } bouncycastle-1.49.orig/src/org/bouncycastle/crypto/tls/PSKTlsClient.java0000644000175000017500000001130412151551725025751 0ustar ebourgebourgpackage org.bouncycastle.crypto.tls; import java.io.IOException; public abstract class PSKTlsClient extends AbstractTlsClient { protected TlsPSKIdentity pskIdentity; public PSKTlsClient(TlsPSKIdentity pskIdentity) { super(); this.pskIdentity = pskIdentity; } public PSKTlsClient(TlsCipherFactory cipherFactory, TlsPSKIdentity pskIdentity) { super(cipherFactory); this.pskIdentity = pskIdentity; } public int[] getCipherSuites() { return new int[]{CipherSuite.TLS_DHE_PSK_WITH_AES_256_CBC_SHA, CipherSuite.TLS_DHE_PSK_WITH_AES_128_CBC_SHA, CipherSuite.TLS_DHE_PSK_WITH_3DES_EDE_CBC_SHA, CipherSuite.TLS_DHE_PSK_WITH_RC4_128_SHA, CipherSuite.TLS_RSA_PSK_WITH_AES_256_CBC_SHA, CipherSuite.TLS_RSA_PSK_WITH_AES_128_CBC_SHA, CipherSuite.TLS_RSA_PSK_WITH_3DES_EDE_CBC_SHA, CipherSuite.TLS_RSA_PSK_WITH_RC4_128_SHA, CipherSuite.TLS_PSK_WITH_AES_256_CBC_SHA, CipherSuite.TLS_PSK_WITH_AES_128_CBC_SHA, CipherSuite.TLS_PSK_WITH_3DES_EDE_CBC_SHA, CipherSuite.TLS_PSK_WITH_RC4_128_SHA,}; } public TlsKeyExchange getKeyExchange() throws IOException { switch (selectedCipherSuite) { case CipherSuite.TLS_PSK_WITH_3DES_EDE_CBC_SHA: case CipherSuite.TLS_PSK_WITH_AES_128_CBC_SHA: case CipherSuite.TLS_PSK_WITH_AES_256_CBC_SHA: case CipherSuite.TLS_PSK_WITH_NULL_SHA: case CipherSuite.TLS_PSK_WITH_RC4_128_SHA: return createPSKKeyExchange(KeyExchangeAlgorithm.PSK); case CipherSuite.TLS_RSA_PSK_WITH_3DES_EDE_CBC_SHA: case CipherSuite.TLS_RSA_PSK_WITH_AES_128_CBC_SHA: case CipherSuite.TLS_RSA_PSK_WITH_AES_256_CBC_SHA: case CipherSuite.TLS_RSA_PSK_WITH_NULL_SHA: case CipherSuite.TLS_RSA_PSK_WITH_RC4_128_SHA: return createPSKKeyExchange(KeyExchangeAlgorithm.RSA_PSK); case CipherSuite.TLS_DHE_PSK_WITH_3DES_EDE_CBC_SHA: case CipherSuite.TLS_DHE_PSK_WITH_AES_128_CBC_SHA: case CipherSuite.TLS_DHE_PSK_WITH_AES_256_CBC_SHA: case CipherSuite.TLS_DHE_PSK_WITH_NULL_SHA: case CipherSuite.TLS_DHE_PSK_WITH_RC4_128_SHA: return createPSKKeyExchange(KeyExchangeAlgorithm.DHE_PSK); default: /* * Note: internal error here; the TlsProtocol implementation verifies that the * server-selected cipher suite was in the list of client-offered cipher suites, so if * we now can't produce an implementation, we shouldn't have offered it! */ throw new TlsFatalAlert(AlertDescription.internal_error); } } public TlsCipher getCipher() throws IOException { switch (selectedCipherSuite) { case CipherSuite.TLS_PSK_WITH_3DES_EDE_CBC_SHA: case CipherSuite.TLS_RSA_PSK_WITH_3DES_EDE_CBC_SHA: case CipherSuite.TLS_DHE_PSK_WITH_3DES_EDE_CBC_SHA: return cipherFactory.createCipher(context, EncryptionAlgorithm._3DES_EDE_CBC, MACAlgorithm.hmac_sha1); case CipherSuite.TLS_PSK_WITH_AES_128_CBC_SHA: case CipherSuite.TLS_RSA_PSK_WITH_AES_128_CBC_SHA: case CipherSuite.TLS_DHE_PSK_WITH_AES_128_CBC_SHA: return cipherFactory.createCipher(context, EncryptionAlgorithm.AES_128_CBC, MACAlgorithm.hmac_sha1); case CipherSuite.TLS_PSK_WITH_AES_256_CBC_SHA: case CipherSuite.TLS_RSA_PSK_WITH_AES_256_CBC_SHA: case CipherSuite.TLS_DHE_PSK_WITH_AES_256_CBC_SHA: return cipherFactory.createCipher(context, EncryptionAlgorithm.AES_256_CBC, MACAlgorithm.hmac_sha1); case CipherSuite.TLS_PSK_WITH_NULL_SHA: case CipherSuite.TLS_RSA_PSK_WITH_NULL_SHA: case CipherSuite.TLS_DHE_PSK_WITH_NULL_SHA: return cipherFactory.createCipher(context, EncryptionAlgorithm.NULL, MACAlgorithm.hmac_sha1); case CipherSuite.TLS_PSK_WITH_RC4_128_SHA: case CipherSuite.TLS_RSA_PSK_WITH_RC4_128_SHA: case CipherSuite.TLS_DHE_PSK_WITH_RC4_128_SHA: return cipherFactory.createCipher(context, EncryptionAlgorithm.RC4_128, MACAlgorithm.hmac_sha1); default: /* * Note: internal error here; the TlsProtocol implementation verifies that the * server-selected cipher suite was in the list of client-offered cipher suites, so if * we now can't produce an implementation, we shouldn't have offered it! */ throw new TlsFatalAlert(AlertDescription.internal_error); } } protected TlsKeyExchange createPSKKeyExchange(int keyExchange) { return new TlsPSKKeyExchange(keyExchange, supportedSignatureAlgorithms, pskIdentity); } } bouncycastle-1.49.orig/src/org/bouncycastle/crypto/tls/NamedCurve.java0000644000175000017500000000404712151551725025531 0ustar ebourgebourgpackage org.bouncycastle.crypto.tls; /** * RFC 4492 5.1.1 *

    * The named curves defined here are those specified in SEC 2 [13]. Note that many of these curves * are also recommended in ANSI X9.62 [7] and FIPS 186-2 [11]. Values 0xFE00 through 0xFEFF are * reserved for private use. Values 0xFF01 and 0xFF02 indicate that the client supports arbitrary * prime and characteristic-2 curves, respectively (the curve parameters must be encoded explicitly * in ECParameters). */ public class NamedCurve { public static final int sect163k1 = 1; public static final int sect163r1 = 2; public static final int sect163r2 = 3; public static final int sect193r1 = 4; public static final int sect193r2 = 5; public static final int sect233k1 = 6; public static final int sect233r1 = 7; public static final int sect239k1 = 8; public static final int sect283k1 = 9; public static final int sect283r1 = 10; public static final int sect409k1 = 11; public static final int sect409r1 = 12; public static final int sect571k1 = 13; public static final int sect571r1 = 14; public static final int secp160k1 = 15; public static final int secp160r1 = 16; public static final int secp160r2 = 17; public static final int secp192k1 = 18; public static final int secp192r1 = 19; public static final int secp224k1 = 20; public static final int secp224r1 = 21; public static final int secp256k1 = 22; public static final int secp256r1 = 23; public static final int secp384r1 = 24; public static final int secp521r1 = 25; /* * reserved (0xFE00..0xFEFF) */ public static final int arbitrary_explicit_prime_curves = 0xFF01; public static final int arbitrary_explicit_char2_curves = 0xFF02; public static boolean refersToASpecificNamedCurve(int namedCurve) { switch (namedCurve) { case arbitrary_explicit_prime_curves: case arbitrary_explicit_char2_curves: return false; default: return true; } } } bouncycastle-1.49.orig/src/org/bouncycastle/crypto/tls/DTLSTransport.java0000644000175000017500000000361612151551725026164 0ustar ebourgebourgpackage org.bouncycastle.crypto.tls; import java.io.IOException; public class DTLSTransport implements DatagramTransport { private final DTLSRecordLayer recordLayer; DTLSTransport(DTLSRecordLayer recordLayer) { this.recordLayer = recordLayer; } public int getReceiveLimit() throws IOException { return recordLayer.getReceiveLimit(); } public int getSendLimit() throws IOException { return recordLayer.getSendLimit(); } public int receive(byte[] buf, int off, int len, int waitMillis) throws IOException { try { return recordLayer.receive(buf, off, len, waitMillis); } catch (TlsFatalAlert fatalAlert) { recordLayer.fail(fatalAlert.getAlertDescription()); throw fatalAlert; } catch (IOException e) { recordLayer.fail(AlertDescription.internal_error); throw e; } catch (RuntimeException e) { recordLayer.fail(AlertDescription.internal_error); throw new TlsFatalAlert(AlertDescription.internal_error); } } public void send(byte[] buf, int off, int len) throws IOException { try { recordLayer.send(buf, off, len); } catch (TlsFatalAlert fatalAlert) { recordLayer.fail(fatalAlert.getAlertDescription()); throw fatalAlert; } catch (IOException e) { recordLayer.fail(AlertDescription.internal_error); throw e; } catch (RuntimeException e) { recordLayer.fail(AlertDescription.internal_error); throw new TlsFatalAlert(AlertDescription.internal_error); } } public void close() throws IOException { recordLayer.close(); } } bouncycastle-1.49.orig/src/org/bouncycastle/crypto/tls/Certificate.java0000644000175000017500000001043312151551725025716 0ustar ebourgebourgpackage org.bouncycastle.crypto.tls; import java.io.ByteArrayInputStream; import java.io.IOException; import java.io.InputStream; import java.io.OutputStream; import java.util.Vector; import org.bouncycastle.asn1.ASN1Encoding; import org.bouncycastle.asn1.ASN1InputStream; import org.bouncycastle.asn1.ASN1Primitive; /** * Parsing and encoding of a Certificate struct from RFC 4346. *

    *

     * opaque ASN.1Cert<2^24-1>;
     *
     * struct {
     *     ASN.1Cert certificate_list<0..2^24-1>;
     * } Certificate;
     * 
    * * @see org.bouncycastle.asn1.x509.Certificate */ public class Certificate { public static final Certificate EMPTY_CHAIN = new Certificate( new org.bouncycastle.asn1.x509.Certificate[0]); protected org.bouncycastle.asn1.x509.Certificate[] certificateList; public Certificate(org.bouncycastle.asn1.x509.Certificate[] certificateList) { if (certificateList == null) { throw new IllegalArgumentException("'certificateList' cannot be null"); } this.certificateList = certificateList; } /** * @deprecated use {@link #getCertificateList()} instead */ public org.bouncycastle.asn1.x509.Certificate[] getCerts() { return clone(certificateList); } /** * @return an array of {@link org.bouncycastle.asn1.x509.Certificate} representing a certificate * chain. */ public org.bouncycastle.asn1.x509.Certificate[] getCertificateList() { return clone(certificateList); } public org.bouncycastle.asn1.x509.Certificate getCertificateAt(int index) { return certificateList[index]; } public int getLength() { return certificateList.length; } /** * @return true if this certificate chain contains no certificates, or * false otherwise. */ public boolean isEmpty() { return certificateList.length == 0; } /** * Encode this {@link Certificate} to an {@link OutputStream}. * * @param output the {@link OutputStream} to encode to. * @throws IOException */ public void encode(OutputStream output) throws IOException { Vector encCerts = new Vector(this.certificateList.length); int totalLength = 0; for (int i = 0; i < this.certificateList.length; ++i) { byte[] encCert = certificateList[i].getEncoded(ASN1Encoding.DER); encCerts.addElement(encCert); totalLength += encCert.length + 3; } TlsUtils.writeUint24(totalLength, output); for (int i = 0; i < encCerts.size(); ++i) { byte[] encCert = (byte[])encCerts.elementAt(i); TlsUtils.writeOpaque24(encCert, output); } } /** * Parse a {@link Certificate} from an {@link InputStream}. * * @param input the {@link InputStream} to parse from. * @return a {@link Certificate} object. * @throws IOException */ public static Certificate parse(InputStream input) throws IOException { org.bouncycastle.asn1.x509.Certificate[] certs; int left = TlsUtils.readUint24(input); if (left == 0) { return EMPTY_CHAIN; } Vector tmp = new Vector(); while (left > 0) { int size = TlsUtils.readUint24(input); left -= 3 + size; byte[] buf = TlsUtils.readFully(size, input); ByteArrayInputStream bis = new ByteArrayInputStream(buf); ASN1Primitive asn1 = new ASN1InputStream(bis).readObject(); TlsProtocol.assertEmpty(bis); tmp.addElement(org.bouncycastle.asn1.x509.Certificate.getInstance(asn1)); } certs = new org.bouncycastle.asn1.x509.Certificate[tmp.size()]; for (int i = 0; i < tmp.size(); i++) { certs[i] = (org.bouncycastle.asn1.x509.Certificate)tmp.elementAt(i); } return new Certificate(certs); } private org.bouncycastle.asn1.x509.Certificate[] clone(org.bouncycastle.asn1.x509.Certificate[] list) { org.bouncycastle.asn1.x509.Certificate[] rv = new org.bouncycastle.asn1.x509.Certificate[list.length]; System.arraycopy(list, 0, rv, 0, rv.length); return rv; } } bouncycastle-1.49.orig/src/org/bouncycastle/crypto/tls/DefaultTlsAgreementCredentials.java0000644000175000017500000000466412146535331031561 0ustar ebourgebourgpackage org.bouncycastle.crypto.tls; import java.math.BigInteger; import org.bouncycastle.crypto.BasicAgreement; import org.bouncycastle.crypto.agreement.DHBasicAgreement; import org.bouncycastle.crypto.agreement.ECDHBasicAgreement; import org.bouncycastle.crypto.params.AsymmetricKeyParameter; import org.bouncycastle.crypto.params.DHPrivateKeyParameters; import org.bouncycastle.crypto.params.ECPrivateKeyParameters; import org.bouncycastle.util.BigIntegers; public class DefaultTlsAgreementCredentials implements TlsAgreementCredentials { protected Certificate certificate; protected AsymmetricKeyParameter privateKey; protected BasicAgreement basicAgreement; protected boolean truncateAgreement; public DefaultTlsAgreementCredentials(Certificate certificate, AsymmetricKeyParameter privateKey) { if (certificate == null) { throw new IllegalArgumentException("'certificate' cannot be null"); } if (certificate.isEmpty()) { throw new IllegalArgumentException("'certificate' cannot be empty"); } if (privateKey == null) { throw new IllegalArgumentException("'privateKey' cannot be null"); } if (!privateKey.isPrivate()) { throw new IllegalArgumentException("'privateKey' must be private"); } if (privateKey instanceof DHPrivateKeyParameters) { basicAgreement = new DHBasicAgreement(); truncateAgreement = true; } else if (privateKey instanceof ECPrivateKeyParameters) { basicAgreement = new ECDHBasicAgreement(); truncateAgreement = false; } else { throw new IllegalArgumentException("'privateKey' type not supported: " + privateKey.getClass().getName()); } this.certificate = certificate; this.privateKey = privateKey; } public Certificate getCertificate() { return certificate; } public byte[] generateAgreement(AsymmetricKeyParameter peerPublicKey) { basicAgreement.init(privateKey); BigInteger agreementValue = basicAgreement.calculateAgreement(peerPublicKey); if (truncateAgreement) { return BigIntegers.asUnsignedByteArray(agreementValue); } return BigIntegers.asUnsignedByteArray(basicAgreement.getFieldSize(), agreementValue); } } bouncycastle-1.49.orig/src/org/bouncycastle/crypto/tls/TlsCipher.java0000644000175000017500000000060212151551725025366 0ustar ebourgebourgpackage org.bouncycastle.crypto.tls; import java.io.IOException; public interface TlsCipher { int getPlaintextLimit(int ciphertextLimit); byte[] encodePlaintext(long seqNo, short type, byte[] plaintext, int offset, int len) throws IOException; byte[] decodeCiphertext(long seqNo, short type, byte[] ciphertext, int offset, int len) throws IOException; } bouncycastle-1.49.orig/src/org/bouncycastle/crypto/tls/TlsClientContext.java0000644000175000017500000000014312146535331026736 0ustar ebourgebourgpackage org.bouncycastle.crypto.tls; public interface TlsClientContext extends TlsContext { } bouncycastle-1.49.orig/src/org/bouncycastle/crypto/tls/TlsAuthentication.java0000755000175000017500000000151612146535331027142 0ustar ebourgebourgpackage org.bouncycastle.crypto.tls; import java.io.IOException; public interface TlsAuthentication { /** * Called by the protocol handler to report the server certificate * Note: this method is responsible for certificate verification and validation * * @param serverCertificate the server certificate received * @throws IOException */ void notifyServerCertificate(Certificate serverCertificate) throws IOException; /** * Return client credentials in response to server's certificate request * * @param certificateRequest details of the certificate request * @return a TlsCredentials object or null for no client authentication * @throws IOException */ TlsCredentials getClientCredentials(CertificateRequest certificateRequest) throws IOException; } bouncycastle-1.49.orig/src/org/bouncycastle/crypto/tls/AbstractTlsCipherFactory.java0000644000175000017500000000053112151551725030403 0ustar ebourgebourgpackage org.bouncycastle.crypto.tls; import java.io.IOException; public class AbstractTlsCipherFactory implements TlsCipherFactory { public TlsCipher createCipher(TlsContext context, int encryptionAlgorithm, int macAlgorithm) throws IOException { throw new TlsFatalAlert(AlertDescription.internal_error); } } bouncycastle-1.49.orig/src/org/bouncycastle/crypto/tls/DefaultTlsEncryptionCredentials.java0000644000175000017500000000447012151551725032000 0ustar ebourgebourgpackage org.bouncycastle.crypto.tls; import java.io.IOException; import org.bouncycastle.crypto.InvalidCipherTextException; import org.bouncycastle.crypto.encodings.PKCS1Encoding; import org.bouncycastle.crypto.engines.RSABlindedEngine; import org.bouncycastle.crypto.params.AsymmetricKeyParameter; import org.bouncycastle.crypto.params.ParametersWithRandom; import org.bouncycastle.crypto.params.RSAKeyParameters; public class DefaultTlsEncryptionCredentials implements TlsEncryptionCredentials { protected TlsContext context; protected Certificate certificate; protected AsymmetricKeyParameter privateKey; public DefaultTlsEncryptionCredentials(TlsContext context, Certificate certificate, AsymmetricKeyParameter privateKey) { if (certificate == null) { throw new IllegalArgumentException("'certificate' cannot be null"); } if (certificate.isEmpty()) { throw new IllegalArgumentException("'certificate' cannot be empty"); } if (privateKey == null) { throw new IllegalArgumentException("'privateKey' cannot be null"); } if (!privateKey.isPrivate()) { throw new IllegalArgumentException("'privateKey' must be private"); } if (privateKey instanceof RSAKeyParameters) { } else { throw new IllegalArgumentException("'privateKey' type not supported: " + privateKey.getClass().getName()); } this.context = context; this.certificate = certificate; this.privateKey = privateKey; } public Certificate getCertificate() { return certificate; } public byte[] decryptPreMasterSecret(byte[] encryptedPreMasterSecret) throws IOException { PKCS1Encoding encoding = new PKCS1Encoding(new RSABlindedEngine()); encoding.init(false, new ParametersWithRandom(this.privateKey, context.getSecureRandom())); try { return encoding.processBlock(encryptedPreMasterSecret, 0, encryptedPreMasterSecret.length); } catch (InvalidCipherTextException e) { throw new TlsFatalAlert(AlertDescription.illegal_parameter); } } } bouncycastle-1.49.orig/src/org/bouncycastle/crypto/tls/TlsRSAKeyExchange.java0000644000175000017500000002000612151551725026715 0ustar ebourgebourgpackage org.bouncycastle.crypto.tls; import java.io.IOException; import java.io.InputStream; import java.io.OutputStream; import java.util.Vector; import org.bouncycastle.asn1.x509.KeyUsage; import org.bouncycastle.asn1.x509.SubjectPublicKeyInfo; import org.bouncycastle.crypto.params.AsymmetricKeyParameter; import org.bouncycastle.crypto.params.RSAKeyParameters; import org.bouncycastle.crypto.util.PublicKeyFactory; import org.bouncycastle.util.io.Streams; /** * TLS 1.0/1.1 and SSLv3 RSA key exchange. */ public class TlsRSAKeyExchange extends AbstractTlsKeyExchange { protected AsymmetricKeyParameter serverPublicKey = null; protected RSAKeyParameters rsaServerPublicKey = null; protected TlsEncryptionCredentials serverCredentials = null; protected byte[] premasterSecret; public TlsRSAKeyExchange(Vector supportedSignatureAlgorithms) { super(KeyExchangeAlgorithm.RSA, supportedSignatureAlgorithms); } public void skipServerCredentials() throws IOException { throw new TlsFatalAlert(AlertDescription.unexpected_message); } public void processServerCredentials(TlsCredentials serverCredentials) throws IOException { if (!(serverCredentials instanceof TlsEncryptionCredentials)) { throw new TlsFatalAlert(AlertDescription.internal_error); } processServerCertificate(serverCredentials.getCertificate()); this.serverCredentials = (TlsEncryptionCredentials)serverCredentials; } public void processServerCertificate(Certificate serverCertificate) throws IOException { if (serverCertificate.isEmpty()) { throw new TlsFatalAlert(AlertDescription.bad_certificate); } org.bouncycastle.asn1.x509.Certificate x509Cert = serverCertificate.getCertificateAt(0); SubjectPublicKeyInfo keyInfo = x509Cert.getSubjectPublicKeyInfo(); try { this.serverPublicKey = PublicKeyFactory.createKey(keyInfo); } catch (RuntimeException e) { throw new TlsFatalAlert(AlertDescription.unsupported_certificate); } // Sanity check the PublicKeyFactory if (this.serverPublicKey.isPrivate()) { throw new TlsFatalAlert(AlertDescription.internal_error); } this.rsaServerPublicKey = validateRSAPublicKey((RSAKeyParameters)this.serverPublicKey); TlsUtils.validateKeyUsage(x509Cert, KeyUsage.keyEncipherment); super.processServerCertificate(serverCertificate); } public void validateCertificateRequest(CertificateRequest certificateRequest) throws IOException { short[] types = certificateRequest.getCertificateTypes(); for (int i = 0; i < types.length; ++i) { switch (types[i]) { case ClientCertificateType.rsa_sign: case ClientCertificateType.dss_sign: case ClientCertificateType.ecdsa_sign: break; default: throw new TlsFatalAlert(AlertDescription.illegal_parameter); } } } public void processClientCredentials(TlsCredentials clientCredentials) throws IOException { if (!(clientCredentials instanceof TlsSignerCredentials)) { throw new TlsFatalAlert(AlertDescription.internal_error); } } public void generateClientKeyExchange(OutputStream output) throws IOException { this.premasterSecret = TlsRSAUtils.generateEncryptedPreMasterSecret(context, this.rsaServerPublicKey, output); } public void processClientKeyExchange(InputStream input) throws IOException { byte[] encryptedPreMasterSecret; if (context.getServerVersion().isSSL()) { // TODO Do any SSLv3 clients actually include the length? encryptedPreMasterSecret = Streams.readAll(input); } else { encryptedPreMasterSecret = TlsUtils.readOpaque16(input); } ProtocolVersion clientVersion = context.getClientVersion(); /* * RFC 5246 7.4.7.1. */ { // TODO Provide as configuration option? boolean versionNumberCheckDisabled = false; /* * See notes regarding Bleichenbacher/Klima attack. The code here implements the first * construction proposed there, which is RECOMMENDED. */ byte[] R = new byte[48]; this.context.getSecureRandom().nextBytes(R); byte[] M = TlsUtils.EMPTY_BYTES; try { M = serverCredentials.decryptPreMasterSecret(encryptedPreMasterSecret); } catch (Exception e) { /* * In any case, a TLS server MUST NOT generate an alert if processing an * RSA-encrypted premaster secret message fails, or the version number is not as * expected. Instead, it MUST continue the handshake with a randomly generated * premaster secret. */ } if (M.length != 48) { TlsUtils.writeVersion(clientVersion, R, 0); this.premasterSecret = R; } else { /* * If ClientHello.client_version is TLS 1.1 or higher, server implementations MUST * check the version number [..]. */ if (versionNumberCheckDisabled && clientVersion.isEqualOrEarlierVersionOf(ProtocolVersion.TLSv10)) { /* * If the version number is TLS 1.0 or earlier, server implementations SHOULD * check the version number, but MAY have a configuration option to disable the * check. */ } else { /* * Note that explicitly constructing the pre_master_secret with the * ClientHello.client_version produces an invalid master_secret if the client * has sent the wrong version in the original pre_master_secret. */ TlsUtils.writeVersion(clientVersion, M, 0); } this.premasterSecret = M; } } } public byte[] generatePremasterSecret() throws IOException { if (this.premasterSecret == null) { throw new TlsFatalAlert(AlertDescription.internal_error); } byte[] tmp = this.premasterSecret; this.premasterSecret = null; return tmp; } // Would be needed to process RSA_EXPORT server key exchange // protected void processRSAServerKeyExchange(InputStream is, Signer signer) throws IOException // { // InputStream sigIn = is; // if (signer != null) // { // sigIn = new SignerInputStream(is, signer); // } // // byte[] modulusBytes = TlsUtils.readOpaque16(sigIn); // byte[] exponentBytes = TlsUtils.readOpaque16(sigIn); // // if (signer != null) // { // byte[] sigByte = TlsUtils.readOpaque16(is); // // if (!signer.verifySignature(sigByte)) // { // handler.failWithError(AlertLevel.fatal, AlertDescription.bad_certificate); // } // } // // BigInteger modulus = new BigInteger(1, modulusBytes); // BigInteger exponent = new BigInteger(1, exponentBytes); // // this.rsaServerPublicKey = validateRSAPublicKey(new RSAKeyParameters(false, modulus, // exponent)); // } protected RSAKeyParameters validateRSAPublicKey(RSAKeyParameters key) throws IOException { // TODO What is the minimum bit length required? // key.getModulus().bitLength(); if (!key.getExponent().isProbablePrime(2)) { throw new TlsFatalAlert(AlertDescription.illegal_parameter); } return key; } } bouncycastle-1.49.orig/src/org/bouncycastle/crypto/tls/AbstractTlsPeer.java0000644000175000017500000000047412151551725026542 0ustar ebourgebourgpackage org.bouncycastle.crypto.tls; public abstract class AbstractTlsPeer implements TlsPeer { public void notifyAlertRaised(short alertLevel, short alertDescription, String message, Exception cause) { } public void notifyAlertReceived(short alertLevel, short alertDescription) { } } bouncycastle-1.49.orig/src/org/bouncycastle/crypto/tls/SupplementalDataType.java0000644000175000017500000000026212151551725027600 0ustar ebourgebourgpackage org.bouncycastle.crypto.tls; /** * RFC 4680 */ public class SupplementalDataType { /* * RFC 4681 */ public static final int user_mapping_data = 0; } bouncycastle-1.49.orig/src/org/bouncycastle/crypto/tls/TlsKeyExchange.java0000644000175000017500000000253512151551725026356 0ustar ebourgebourgpackage org.bouncycastle.crypto.tls; import java.io.IOException; import java.io.InputStream; import java.io.OutputStream; /** * A generic interface for key exchange implementations in TLS 1.0/1.1. */ public interface TlsKeyExchange { void init(TlsContext context); void skipServerCredentials() throws IOException; void processServerCredentials(TlsCredentials serverCredentials) throws IOException; void processServerCertificate(Certificate serverCertificate) throws IOException; boolean requiresServerKeyExchange(); byte[] generateServerKeyExchange() throws IOException; void skipServerKeyExchange() throws IOException; void processServerKeyExchange(InputStream input) throws IOException; void validateCertificateRequest(CertificateRequest certificateRequest) throws IOException; void skipClientCredentials() throws IOException; void processClientCredentials(TlsCredentials clientCredentials) throws IOException; void processClientCertificate(Certificate clientCertificate) throws IOException; void generateClientKeyExchange(OutputStream output) throws IOException; void processClientKeyExchange(InputStream input) throws IOException; byte[] generatePremasterSecret() throws IOException; } bouncycastle-1.49.orig/src/org/bouncycastle/crypto/tls/TlsECDSASigner.java0000644000175000017500000000102212146535331026137 0ustar ebourgebourgpackage org.bouncycastle.crypto.tls; import org.bouncycastle.crypto.DSA; import org.bouncycastle.crypto.params.AsymmetricKeyParameter; import org.bouncycastle.crypto.params.ECPublicKeyParameters; import org.bouncycastle.crypto.signers.ECDSASigner; public class TlsECDSASigner extends TlsDSASigner { public boolean isValidPublicKey(AsymmetricKeyParameter publicKey) { return publicKey instanceof ECPublicKeyParameters; } protected DSA createDSAImpl() { return new ECDSASigner(); } } bouncycastle-1.49.orig/src/org/bouncycastle/crypto/tls/DTLSEpoch.java0000644000175000017500000000172312151551725025223 0ustar ebourgebourgpackage org.bouncycastle.crypto.tls; class DTLSEpoch { private final DTLSReplayWindow replayWindow = new DTLSReplayWindow(); private final int epoch; private final TlsCipher cipher; private long sequence_number = 0; DTLSEpoch(int epoch, TlsCipher cipher) { if (epoch < 0) { throw new IllegalArgumentException("'epoch' must be >= 0"); } if (cipher == null) { throw new IllegalArgumentException("'cipher' cannot be null"); } this.epoch = epoch; this.cipher = cipher; } long allocateSequenceNumber() { // TODO Check for overflow return sequence_number++; } TlsCipher getCipher() { return cipher; } int getEpoch() { return epoch; } DTLSReplayWindow getReplayWindow() { return replayWindow; } long getSequence_number() { return sequence_number; } } bouncycastle-1.49.orig/src/org/bouncycastle/crypto/tls/LegacyTlsAuthentication.java0000644000175000017500000000126312151551725030264 0ustar ebourgebourgpackage org.bouncycastle.crypto.tls; import java.io.IOException; /** * A temporary class to wrap old CertificateVerifyer stuff for new TlsAuthentication * * @deprecated */ public class LegacyTlsAuthentication extends ServerOnlyTlsAuthentication { protected CertificateVerifyer verifyer; public LegacyTlsAuthentication(CertificateVerifyer verifyer) { this.verifyer = verifyer; } public void notifyServerCertificate(Certificate serverCertificate) throws IOException { if (!this.verifyer.isValid(serverCertificate.getCertificateList())) { throw new TlsFatalAlert(AlertDescription.user_canceled); } } } bouncycastle-1.49.orig/src/org/bouncycastle/crypto/tls/SSL3Mac.java0000644000175000017500000000504612146535331024644 0ustar ebourgebourgpackage org.bouncycastle.crypto.tls; import org.bouncycastle.crypto.CipherParameters; import org.bouncycastle.crypto.Digest; import org.bouncycastle.crypto.Mac; import org.bouncycastle.crypto.params.KeyParameter; import org.bouncycastle.util.Arrays; /** * HMAC implementation based on original internet draft for HMAC (RFC 2104) *

    * The difference is that padding is concatenated versus XORed with the key *

    * H(K + opad, H(K + ipad, text)) */ public class SSL3Mac implements Mac { private final static byte IPAD_BYTE = (byte)0x36; private final static byte OPAD_BYTE = (byte)0x5C; static final byte[] IPAD = genPad(IPAD_BYTE, 48); static final byte[] OPAD = genPad(OPAD_BYTE, 48); private Digest digest; private byte[] secret; private int padLength; /** * Base constructor for one of the standard digest algorithms that the byteLength of * the algorithm is know for. Behaviour is undefined for digests other than MD5 or SHA1. * * @param digest the digest. */ public SSL3Mac(Digest digest) { this.digest = digest; if (digest.getDigestSize() == 20) { this.padLength = 40; } else { this.padLength = 48; } } public String getAlgorithmName() { return digest.getAlgorithmName() + "/SSL3MAC"; } public Digest getUnderlyingDigest() { return digest; } public void init(CipherParameters params) { secret = Arrays.clone(((KeyParameter)params).getKey()); reset(); } public int getMacSize() { return digest.getDigestSize(); } public void update(byte in) { digest.update(in); } public void update(byte[] in, int inOff, int len) { digest.update(in, inOff, len); } public int doFinal(byte[] out, int outOff) { byte[] tmp = new byte[digest.getDigestSize()]; digest.doFinal(tmp, 0); digest.update(secret, 0, secret.length); digest.update(OPAD, 0, padLength); digest.update(tmp, 0, tmp.length); int len = digest.doFinal(out, outOff); reset(); return len; } /** * Reset the mac generator. */ public void reset() { digest.reset(); digest.update(secret, 0, secret.length); digest.update(IPAD, 0, padLength); } private static byte[] genPad(byte b, int count) { byte[] padding = new byte[count]; Arrays.fill(padding, b); return padding; } } bouncycastle-1.49.orig/src/org/bouncycastle/crypto/tls/TlsProtocol.java0000644000175000017500000007140012151551725025761 0ustar ebourgebourgpackage org.bouncycastle.crypto.tls; import java.io.ByteArrayInputStream; import java.io.ByteArrayOutputStream; import java.io.IOException; import java.io.InputStream; import java.io.OutputStream; import java.security.SecureRandom; import java.util.Enumeration; import java.util.Hashtable; import java.util.Vector; import org.bouncycastle.util.Arrays; import org.bouncycastle.util.Integers; /** * An implementation of all high level protocols in TLS 1.0/1.1. */ public abstract class TlsProtocol { protected static final Integer EXT_RenegotiationInfo = Integers.valueOf(ExtensionType.renegotiation_info); protected static final Integer EXT_SessionTicket = Integers.valueOf(ExtensionType.session_ticket); private static final String TLS_ERROR_MESSAGE = "Internal TLS error, this could be an attack"; /* * Our Connection states */ protected static final short CS_START = 0; protected static final short CS_CLIENT_HELLO = 1; protected static final short CS_SERVER_HELLO = 2; protected static final short CS_SERVER_SUPPLEMENTAL_DATA = 3; protected static final short CS_SERVER_CERTIFICATE = 4; protected static final short CS_SERVER_KEY_EXCHANGE = 5; protected static final short CS_CERTIFICATE_REQUEST = 6; protected static final short CS_SERVER_HELLO_DONE = 7; protected static final short CS_CLIENT_SUPPLEMENTAL_DATA = 8; protected static final short CS_CLIENT_CERTIFICATE = 9; protected static final short CS_CLIENT_KEY_EXCHANGE = 10; protected static final short CS_CERTIFICATE_VERIFY = 11; protected static final short CS_CLIENT_CHANGE_CIPHER_SPEC = 12; protected static final short CS_CLIENT_FINISHED = 13; protected static final short CS_SERVER_SESSION_TICKET = 14; protected static final short CS_SERVER_CHANGE_CIPHER_SPEC = 15; protected static final short CS_SERVER_FINISHED = 16; /* * Queues for data from some protocols. */ private ByteQueue applicationDataQueue = new ByteQueue(); private ByteQueue changeCipherSpecQueue = new ByteQueue(); private ByteQueue alertQueue = new ByteQueue(); private ByteQueue handshakeQueue = new ByteQueue(); /* * The Record Stream we use */ protected RecordStream recordStream; protected SecureRandom secureRandom; private TlsInputStream tlsInputStream = null; private TlsOutputStream tlsOutputStream = null; private volatile boolean closed = false; private volatile boolean failedWithError = false; private volatile boolean appDataReady = false; private volatile boolean writeExtraEmptyRecords = true; private byte[] expected_verify_data = null; protected SecurityParameters securityParameters = null; protected short connection_state = CS_START; protected boolean secure_renegotiation = false; protected boolean expectSessionTicket = false; public TlsProtocol(InputStream input, OutputStream output, SecureRandom secureRandom) { this.recordStream = new RecordStream(this, input, output); this.secureRandom = secureRandom; } protected abstract AbstractTlsContext getContext(); protected abstract TlsPeer getPeer(); protected abstract void handleChangeCipherSpecMessage() throws IOException; protected abstract void handleHandshakeMessage(short type, byte[] buf) throws IOException; protected void handleWarningMessage(short description) throws IOException { } protected void completeHandshake() throws IOException { this.expected_verify_data = null; /* * We will now read data, until we have completed the handshake. */ while (this.connection_state != CS_SERVER_FINISHED) { safeReadRecord(); } this.recordStream.finaliseHandshake(); ProtocolVersion version = getContext().getServerVersion(); this.writeExtraEmptyRecords = version.isEqualOrEarlierVersionOf(ProtocolVersion.TLSv10); /* * If this was an initial handshake, we are now ready to send and receive application data. */ if (!appDataReady) { this.appDataReady = true; this.tlsInputStream = new TlsInputStream(this); this.tlsOutputStream = new TlsOutputStream(this); } } protected void processRecord(short protocol, byte[] buf, int offset, int len) throws IOException { /* * Have a look at the protocol type, and add it to the correct queue. */ switch (protocol) { case ContentType.change_cipher_spec: changeCipherSpecQueue.addData(buf, offset, len); processChangeCipherSpec(); break; case ContentType.alert: alertQueue.addData(buf, offset, len); processAlert(); break; case ContentType.handshake: handshakeQueue.addData(buf, offset, len); processHandshake(); break; case ContentType.application_data: if (!appDataReady) { this.failWithError(AlertLevel.fatal, AlertDescription.unexpected_message); } applicationDataQueue.addData(buf, offset, len); processApplicationData(); break; default: /* * Uh, we don't know this protocol. * * RFC2246 defines on page 13, that we should ignore this. */ } } private void processHandshake() throws IOException { boolean read; do { read = false; /* * We need the first 4 bytes, they contain type and length of the message. */ if (handshakeQueue.size() >= 4) { byte[] beginning = new byte[4]; handshakeQueue.read(beginning, 0, 4, 0); ByteArrayInputStream bis = new ByteArrayInputStream(beginning); short type = TlsUtils.readUint8(bis); int len = TlsUtils.readUint24(bis); /* * Check if we have enough bytes in the buffer to read the full message. */ if (handshakeQueue.size() >= (len + 4)) { /* * Read the message. */ byte[] buf = new byte[len]; handshakeQueue.read(buf, 0, len, 4); handshakeQueue.removeData(len + 4); /* * RFC 2246 7.4.9. The value handshake_messages includes all handshake messages * starting at client hello up to, but not including, this finished message. * [..] Note: [Also,] Hello Request messages are omitted from handshake hashes. */ switch (type) { case HandshakeType.hello_request: break; case HandshakeType.finished: { if (this.expected_verify_data == null) { this.expected_verify_data = createVerifyData(!getContext().isServer()); } // NB: Fall through to next case label } default: recordStream.updateHandshakeData(beginning, 0, 4); recordStream.updateHandshakeData(buf, 0, len); break; } /* * Now, parse the message. */ handleHandshakeMessage(type, buf); read = true; } } } while (read); } private void processApplicationData() { /* * There is nothing we need to do here. * * This function could be used for callbacks when application data arrives in the future. */ } private void processAlert() throws IOException { while (alertQueue.size() >= 2) { /* * An alert is always 2 bytes. Read the alert. */ byte[] tmp = new byte[2]; alertQueue.read(tmp, 0, 2, 0); alertQueue.removeData(2); short level = tmp[0]; short description = tmp[1]; getPeer().notifyAlertReceived(level, description); if (level == AlertLevel.fatal) { this.failedWithError = true; this.closed = true; /* * Now try to close the stream, ignore errors. */ try { recordStream.close(); } catch (Exception e) { } throw new IOException(TLS_ERROR_MESSAGE); } else { /* * RFC 5246 7.2.1. The other party MUST respond with a close_notify alert of its own * and close down the connection immediately, discarding any pending writes. */ // TODO Can close_notify be a fatal alert? if (description == AlertDescription.close_notify) { handleClose(false); } /* * If it is just a warning, we continue. */ handleWarningMessage(description); } } } /** * This method is called, when a change cipher spec message is received. * * @throws IOException If the message has an invalid content or the handshake is not in the correct * state. */ private void processChangeCipherSpec() throws IOException { while (changeCipherSpecQueue.size() > 0) { /* * A change cipher spec message is only one byte with the value 1. */ byte[] b = new byte[1]; changeCipherSpecQueue.read(b, 0, 1, 0); changeCipherSpecQueue.removeData(1); if (b[0] != 1) { /* * This should never happen. */ this.failWithError(AlertLevel.fatal, AlertDescription.unexpected_message); } recordStream.receivedReadCipherSpec(); handleChangeCipherSpecMessage(); } } /** * Read data from the network. The method will return immediately, if there is still some data * left in the buffer, or block until some application data has been read from the network. * * @param buf The buffer where the data will be copied to. * @param offset The position where the data will be placed in the buffer. * @param len The maximum number of bytes to read. * @return The number of bytes read. * @throws IOException If something goes wrong during reading data. */ protected int readApplicationData(byte[] buf, int offset, int len) throws IOException { if (len < 1) { return 0; } while (applicationDataQueue.size() == 0) { /* * We need to read some data. */ if (this.closed) { if (this.failedWithError) { /* * Something went terribly wrong, we should throw an IOException */ throw new IOException(TLS_ERROR_MESSAGE); } /* * Connection has been closed, there is no more data to read. */ return -1; } safeReadRecord(); } len = Math.min(len, applicationDataQueue.size()); applicationDataQueue.read(buf, offset, len, 0); applicationDataQueue.removeData(len); return len; } protected void safeReadRecord() throws IOException { try { recordStream.readRecord(); } catch (TlsFatalAlert e) { if (!this.closed) { this.failWithError(AlertLevel.fatal, e.getAlertDescription()); } throw e; } catch (IOException e) { if (!this.closed) { this.failWithError(AlertLevel.fatal, AlertDescription.internal_error); } throw e; } catch (RuntimeException e) { if (!this.closed) { this.failWithError(AlertLevel.fatal, AlertDescription.internal_error); } throw e; } } protected void safeWriteRecord(short type, byte[] buf, int offset, int len) throws IOException { try { recordStream.writeRecord(type, buf, offset, len); } catch (TlsFatalAlert e) { if (!this.closed) { this.failWithError(AlertLevel.fatal, e.getAlertDescription()); } throw e; } catch (IOException e) { if (!closed) { this.failWithError(AlertLevel.fatal, AlertDescription.internal_error); } throw e; } catch (RuntimeException e) { if (!closed) { this.failWithError(AlertLevel.fatal, AlertDescription.internal_error); } throw e; } } /** * Send some application data to the remote system. *

    * The method will handle fragmentation internally. * * @param buf The buffer with the data. * @param offset The position in the buffer where the data is placed. * @param len The length of the data. * @throws IOException If something goes wrong during sending. */ protected void writeData(byte[] buf, int offset, int len) throws IOException { if (this.closed) { if (this.failedWithError) { throw new IOException(TLS_ERROR_MESSAGE); } throw new IOException("Sorry, connection has been closed, you cannot write more data"); } while (len > 0) { /* * RFC 5246 6.2.1. Zero-length fragments of Application data MAY be sent as they are * potentially useful as a traffic analysis countermeasure. */ if (this.writeExtraEmptyRecords) { /* * Protect against known IV attack! * * DO NOT REMOVE THIS LINE, EXCEPT YOU KNOW EXACTLY WHAT YOU ARE DOING HERE. */ safeWriteRecord(ContentType.application_data, TlsUtils.EMPTY_BYTES, 0, 0); } /* * We are only allowed to write fragments up to 2^14 bytes. */ int toWrite = Math.min(len, 1 << 14); safeWriteRecord(ContentType.application_data, buf, offset, toWrite); offset += toWrite; len -= toWrite; } } /** * @return An OutputStream which can be used to send data. */ public OutputStream getOutputStream() { return this.tlsOutputStream; } /** * @return An InputStream which can be used to read data. */ public InputStream getInputStream() { return this.tlsInputStream; } /** * Terminate this connection with an alert. *

    * Can be used for normal closure too. * * @param alertLevel The level of the alert, an be AlertLevel.fatal or AL_warning. * @param alertDescription The exact alert message. * @throws IOException If alert was fatal. */ protected void failWithError(short alertLevel, short alertDescription) throws IOException { /* * Check if the connection is still open. */ if (!closed) { /* * Prepare the message */ this.closed = true; if (alertLevel == AlertLevel.fatal) { /* * This is a fatal message. */ this.failedWithError = true; } raiseAlert(alertLevel, alertDescription, null, null); recordStream.close(); if (alertLevel == AlertLevel.fatal) { throw new IOException(TLS_ERROR_MESSAGE); } } else { throw new IOException(TLS_ERROR_MESSAGE); } } protected void processFinishedMessage(ByteArrayInputStream buf) throws IOException { byte[] verify_data = TlsUtils.readFully(expected_verify_data.length, buf); assertEmpty(buf); /* * Compare both checksums. */ if (!Arrays.constantTimeAreEqual(expected_verify_data, verify_data)) { /* * Wrong checksum in the finished message. */ this.failWithError(AlertLevel.fatal, AlertDescription.decrypt_error); } } protected void raiseAlert(short alertLevel, short alertDescription, String message, Exception cause) throws IOException { getPeer().notifyAlertRaised(alertLevel, alertDescription, message, cause); byte[] error = new byte[2]; error[0] = (byte)alertLevel; error[1] = (byte)alertDescription; safeWriteRecord(ContentType.alert, error, 0, 2); } protected void raiseWarning(short alertDescription, String message) throws IOException { raiseAlert(AlertLevel.warning, alertDescription, message, null); } protected void sendCertificateMessage(Certificate certificate) throws IOException { if (certificate == null) { certificate = Certificate.EMPTY_CHAIN; } if (certificate.getLength() == 0) { TlsContext context = getContext(); if (!context.isServer()) { ProtocolVersion serverVersion = getContext().getServerVersion(); if (serverVersion.isSSL()) { String message = serverVersion.toString() + " client didn't provide credentials"; raiseWarning(AlertDescription.no_certificate, message); return; } } } ByteArrayOutputStream bos = new ByteArrayOutputStream(); TlsUtils.writeUint8(HandshakeType.certificate, bos); // Reserve space for length TlsUtils.writeUint24(0, bos); certificate.encode(bos); byte[] message = bos.toByteArray(); // Patch actual length back in TlsUtils.writeUint24(message.length - 4, message, 1); safeWriteRecord(ContentType.handshake, message, 0, message.length); } protected void sendChangeCipherSpecMessage() throws IOException { byte[] message = new byte[]{1}; safeWriteRecord(ContentType.change_cipher_spec, message, 0, message.length); recordStream.sentWriteCipherSpec(); } protected void sendFinishedMessage() throws IOException { byte[] verify_data = createVerifyData(getContext().isServer()); ByteArrayOutputStream bos = new ByteArrayOutputStream(); TlsUtils.writeUint8(HandshakeType.finished, bos); TlsUtils.writeUint24(verify_data.length, bos); bos.write(verify_data); byte[] message = bos.toByteArray(); safeWriteRecord(ContentType.handshake, message, 0, message.length); } protected void sendSupplementalDataMessage(Vector supplementalData) throws IOException { ByteArrayOutputStream buf = new ByteArrayOutputStream(); TlsUtils.writeUint8(HandshakeType.supplemental_data, buf); // Reserve space for length TlsUtils.writeUint24(0, buf); writeSupplementalData(buf, supplementalData); byte[] message = buf.toByteArray(); // Patch actual length back in TlsUtils.writeUint24(message.length - 4, message, 1); safeWriteRecord(ContentType.handshake, message, 0, message.length); } protected byte[] createVerifyData(boolean isServer) { TlsContext context = getContext(); if (isServer) { return TlsUtils.calculateVerifyData(context, "server finished", recordStream.getCurrentHash(TlsUtils.SSL_SERVER)); } return TlsUtils.calculateVerifyData(context, "client finished", recordStream.getCurrentHash(TlsUtils.SSL_CLIENT)); } /** * Closes this connection. * * @throws IOException If something goes wrong during closing. */ public void close() throws IOException { handleClose(true); } protected void handleClose(boolean user_canceled) throws IOException { if (!closed) { if (user_canceled && !appDataReady) { raiseWarning(AlertDescription.user_canceled, "User canceled handshake"); } this.failWithError(AlertLevel.warning, AlertDescription.close_notify); } } protected void flush() throws IOException { recordStream.flush(); } protected static boolean arrayContains(short[] a, short n) { for (int i = 0; i < a.length; ++i) { if (a[i] == n) { return true; } } return false; } protected static boolean arrayContains(int[] a, int n) { for (int i = 0; i < a.length; ++i) { if (a[i] == n) { return true; } } return false; } /** * Make sure the InputStream 'buf' now empty. Fail otherwise. * * @param buf The InputStream to check. * @throws IOException If 'buf' is not empty. */ protected static void assertEmpty(ByteArrayInputStream buf) throws IOException { if (buf.available() > 0) { throw new TlsFatalAlert(AlertDescription.decode_error); } } protected static byte[] createRandomBlock(SecureRandom random) { byte[] result = new byte[32]; random.nextBytes(result); TlsUtils.writeGMTUnixTime(result, 0); return result; } protected static byte[] createRenegotiationInfo(byte[] renegotiated_connection) throws IOException { ByteArrayOutputStream buf = new ByteArrayOutputStream(); TlsUtils.writeOpaque8(renegotiated_connection, buf); return buf.toByteArray(); } protected static void establishMasterSecret(TlsContext context, TlsKeyExchange keyExchange) throws IOException { byte[] pre_master_secret = keyExchange.generatePremasterSecret(); try { context.getSecurityParameters().masterSecret = TlsUtils.calculateMasterSecret(context, pre_master_secret); } finally { // TODO Is there a way to ensure the data is really overwritten? /* * RFC 2246 8.1. The pre_master_secret should be deleted from memory once the * master_secret has been computed. */ if (pre_master_secret != null) { Arrays.fill(pre_master_secret, (byte)0); } } } protected static Hashtable readExtensions(ByteArrayInputStream input) throws IOException { if (input.available() < 1) { return null; } byte[] extBytes = TlsUtils.readOpaque16(input); assertEmpty(input); ByteArrayInputStream buf = new ByteArrayInputStream(extBytes); // Integer -> byte[] Hashtable extensions = new Hashtable(); while (buf.available() > 0) { Integer extType = Integers.valueOf(TlsUtils.readUint16(buf)); byte[] extValue = TlsUtils.readOpaque16(buf); /* * RFC 3546 2.3 There MUST NOT be more than one extension of the same type. */ if (null != extensions.put(extType, extValue)) { throw new TlsFatalAlert(AlertDescription.illegal_parameter); } } return extensions; } protected static Vector readSupplementalDataMessage(ByteArrayInputStream input) throws IOException { byte[] supp_data = TlsUtils.readOpaque24(input); assertEmpty(input); ByteArrayInputStream buf = new ByteArrayInputStream(supp_data); Vector supplementalData = new Vector(); while (buf.available() > 0) { int supp_data_type = TlsUtils.readUint16(buf); byte[] data = TlsUtils.readOpaque16(buf); supplementalData.addElement(new SupplementalDataEntry(supp_data_type, data)); } return supplementalData; } protected static void writeExtensions(OutputStream output, Hashtable extensions) throws IOException { ByteArrayOutputStream buf = new ByteArrayOutputStream(); Enumeration keys = extensions.keys(); while (keys.hasMoreElements()) { Integer extType = (Integer)keys.nextElement(); byte[] extValue = (byte[])extensions.get(extType); TlsUtils.writeUint16(extType.intValue(), buf); TlsUtils.writeOpaque16(extValue, buf); } byte[] extBytes = buf.toByteArray(); TlsUtils.writeOpaque16(extBytes, output); } protected static void writeSupplementalData(OutputStream output, Vector supplementalData) throws IOException { ByteArrayOutputStream buf = new ByteArrayOutputStream(); for (int i = 0; i < supplementalData.size(); ++i) { SupplementalDataEntry entry = (SupplementalDataEntry)supplementalData.elementAt(i); TlsUtils.writeUint16(entry.getDataType(), buf); TlsUtils.writeOpaque16(entry.getData(), buf); } byte[] supp_data = buf.toByteArray(); TlsUtils.writeOpaque24(supp_data, output); } protected static int getPRFAlgorithm(int ciphersuite) { switch (ciphersuite) { case CipherSuite.TLS_DH_DSS_WITH_AES_128_CBC_SHA256: case CipherSuite.TLS_DH_RSA_WITH_AES_128_CBC_SHA256: case CipherSuite.TLS_DHE_DSS_WITH_AES_128_CBC_SHA256: case CipherSuite.TLS_DHE_RSA_WITH_AES_128_CBC_SHA256: case CipherSuite.TLS_ECDH_ECDSA_WITH_AES_128_CBC_SHA256: case CipherSuite.TLS_ECDH_RSA_WITH_AES_128_CBC_SHA256: case CipherSuite.TLS_ECDHE_ECDSA_WITH_AES_128_CBC_SHA256: case CipherSuite.TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA256: case CipherSuite.TLS_RSA_WITH_AES_128_CBC_SHA256: case CipherSuite.TLS_DH_DSS_WITH_AES_128_GCM_SHA256: case CipherSuite.TLS_DH_RSA_WITH_AES_128_GCM_SHA256: case CipherSuite.TLS_DHE_DSS_WITH_AES_128_GCM_SHA256: case CipherSuite.TLS_DHE_RSA_WITH_AES_128_GCM_SHA256: case CipherSuite.TLS_ECDH_ECDSA_WITH_AES_128_GCM_SHA256: case CipherSuite.TLS_ECDH_RSA_WITH_AES_128_GCM_SHA256: case CipherSuite.TLS_ECDHE_ECDSA_WITH_AES_128_GCM_SHA256: case CipherSuite.TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256: case CipherSuite.TLS_RSA_WITH_AES_128_GCM_SHA256: case CipherSuite.TLS_DH_DSS_WITH_AES_256_CBC_SHA256: case CipherSuite.TLS_DH_RSA_WITH_AES_256_CBC_SHA256: case CipherSuite.TLS_DHE_DSS_WITH_AES_256_CBC_SHA256: case CipherSuite.TLS_DHE_RSA_WITH_AES_256_CBC_SHA256: case CipherSuite.TLS_RSA_WITH_AES_256_CBC_SHA256: case CipherSuite.TLS_RSA_WITH_NULL_SHA256: return PRFAlgorithm.tls_prf_sha256; case CipherSuite.TLS_ECDH_ECDSA_WITH_AES_256_CBC_SHA384: case CipherSuite.TLS_ECDH_RSA_WITH_AES_256_CBC_SHA384: case CipherSuite.TLS_ECDHE_ECDSA_WITH_AES_256_CBC_SHA384: case CipherSuite.TLS_ECDHE_RSA_WITH_AES_256_CBC_SHA384: case CipherSuite.TLS_DH_DSS_WITH_AES_256_GCM_SHA384: case CipherSuite.TLS_DH_RSA_WITH_AES_256_GCM_SHA384: case CipherSuite.TLS_DHE_DSS_WITH_AES_256_GCM_SHA384: case CipherSuite.TLS_DHE_RSA_WITH_AES_256_GCM_SHA384: case CipherSuite.TLS_ECDH_ECDSA_WITH_AES_256_GCM_SHA384: case CipherSuite.TLS_ECDH_RSA_WITH_AES_256_GCM_SHA384: case CipherSuite.TLS_ECDHE_ECDSA_WITH_AES_256_GCM_SHA384: case CipherSuite.TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384: case CipherSuite.TLS_RSA_WITH_AES_256_GCM_SHA384: return PRFAlgorithm.tls_prf_sha384; default: return PRFAlgorithm.tls_prf_legacy; } } } bouncycastle-1.49.orig/src/org/bouncycastle/crypto/tls/SRPTlsClient.java0000644000175000017500000001177712151551725025776 0ustar ebourgebourgpackage org.bouncycastle.crypto.tls; import java.io.ByteArrayOutputStream; import java.io.IOException; import java.util.Hashtable; import org.bouncycastle.util.Arrays; import org.bouncycastle.util.Integers; public abstract class SRPTlsClient extends AbstractTlsClient { public static final Integer EXT_SRP = Integers.valueOf(ExtensionType.srp); protected byte[] identity; protected byte[] password; public SRPTlsClient(byte[] identity, byte[] password) { super(); this.identity = Arrays.clone(identity); this.password = Arrays.clone(password); } public SRPTlsClient(TlsCipherFactory cipherFactory, byte[] identity, byte[] password) { super(cipherFactory); this.identity = Arrays.clone(identity); this.password = Arrays.clone(password); } public int[] getCipherSuites() { return new int[]{CipherSuite.TLS_SRP_SHA_RSA_WITH_AES_256_CBC_SHA, CipherSuite.TLS_SRP_SHA_RSA_WITH_AES_128_CBC_SHA, CipherSuite.TLS_SRP_SHA_RSA_WITH_3DES_EDE_CBC_SHA, CipherSuite.TLS_SRP_SHA_WITH_AES_256_CBC_SHA, CipherSuite.TLS_SRP_SHA_WITH_AES_128_CBC_SHA, CipherSuite.TLS_SRP_SHA_WITH_3DES_EDE_CBC_SHA,}; } public Hashtable getClientExtensions() throws IOException { Hashtable clientExtensions = super.getClientExtensions(); if (clientExtensions == null) { clientExtensions = new Hashtable(); } ByteArrayOutputStream srpData = new ByteArrayOutputStream(); TlsUtils.writeOpaque8(this.identity, srpData); clientExtensions.put(EXT_SRP, srpData.toByteArray()); return clientExtensions; } public void processServerExtensions(Hashtable serverExtensions) throws IOException { // No explicit guidance in RFC 5054 here; we allow an optional empty extension from server if (serverExtensions != null) { byte[] extValue = (byte[])serverExtensions.get(EXT_SRP); if (extValue != null && extValue.length > 0) { throw new TlsFatalAlert(AlertDescription.illegal_parameter); } } } public TlsKeyExchange getKeyExchange() throws IOException { switch (selectedCipherSuite) { case CipherSuite.TLS_SRP_SHA_WITH_3DES_EDE_CBC_SHA: case CipherSuite.TLS_SRP_SHA_WITH_AES_128_CBC_SHA: case CipherSuite.TLS_SRP_SHA_WITH_AES_256_CBC_SHA: return createSRPKeyExchange(KeyExchangeAlgorithm.SRP); case CipherSuite.TLS_SRP_SHA_RSA_WITH_3DES_EDE_CBC_SHA: case CipherSuite.TLS_SRP_SHA_RSA_WITH_AES_128_CBC_SHA: case CipherSuite.TLS_SRP_SHA_RSA_WITH_AES_256_CBC_SHA: return createSRPKeyExchange(KeyExchangeAlgorithm.SRP_RSA); case CipherSuite.TLS_SRP_SHA_DSS_WITH_3DES_EDE_CBC_SHA: case CipherSuite.TLS_SRP_SHA_DSS_WITH_AES_128_CBC_SHA: case CipherSuite.TLS_SRP_SHA_DSS_WITH_AES_256_CBC_SHA: return createSRPKeyExchange(KeyExchangeAlgorithm.SRP_DSS); default: /* * Note: internal error here; the TlsProtocol implementation verifies that the * server-selected cipher suite was in the list of client-offered cipher suites, so if * we now can't produce an implementation, we shouldn't have offered it! */ throw new TlsFatalAlert(AlertDescription.internal_error); } } public TlsCipher getCipher() throws IOException { switch (selectedCipherSuite) { case CipherSuite.TLS_SRP_SHA_WITH_3DES_EDE_CBC_SHA: case CipherSuite.TLS_SRP_SHA_RSA_WITH_3DES_EDE_CBC_SHA: case CipherSuite.TLS_SRP_SHA_DSS_WITH_3DES_EDE_CBC_SHA: return cipherFactory.createCipher(context, EncryptionAlgorithm._3DES_EDE_CBC, MACAlgorithm.hmac_sha1); case CipherSuite.TLS_SRP_SHA_WITH_AES_128_CBC_SHA: case CipherSuite.TLS_SRP_SHA_RSA_WITH_AES_128_CBC_SHA: case CipherSuite.TLS_SRP_SHA_DSS_WITH_AES_128_CBC_SHA: return cipherFactory.createCipher(context, EncryptionAlgorithm.AES_128_CBC, MACAlgorithm.hmac_sha1); case CipherSuite.TLS_SRP_SHA_WITH_AES_256_CBC_SHA: case CipherSuite.TLS_SRP_SHA_RSA_WITH_AES_256_CBC_SHA: case CipherSuite.TLS_SRP_SHA_DSS_WITH_AES_256_CBC_SHA: return cipherFactory.createCipher(context, EncryptionAlgorithm.AES_256_CBC, MACAlgorithm.hmac_sha1); default: /* * Note: internal error here; the TlsProtocol implementation verifies that the * server-selected cipher suite was in the list of client-offered cipher suites, so if * we now can't produce an implementation, we shouldn't have offered it! */ throw new TlsFatalAlert(AlertDescription.internal_error); } } protected TlsKeyExchange createSRPKeyExchange(int keyExchange) { return new TlsSRPKeyExchange(keyExchange, supportedSignatureAlgorithms, identity, password); } } bouncycastle-1.49.orig/src/org/bouncycastle/crypto/tls/DefaultTlsSignerCredentials.java0000755000175000017500000000446712151551725031106 0ustar ebourgebourgpackage org.bouncycastle.crypto.tls; import java.io.IOException; import org.bouncycastle.crypto.CryptoException; import org.bouncycastle.crypto.params.AsymmetricKeyParameter; import org.bouncycastle.crypto.params.DSAPrivateKeyParameters; import org.bouncycastle.crypto.params.ECPrivateKeyParameters; import org.bouncycastle.crypto.params.RSAKeyParameters; public class DefaultTlsSignerCredentials implements TlsSignerCredentials { protected TlsContext context; protected Certificate certificate; protected AsymmetricKeyParameter privateKey; protected TlsSigner signer; public DefaultTlsSignerCredentials(TlsContext context, Certificate certificate, AsymmetricKeyParameter privateKey) { if (certificate == null) { throw new IllegalArgumentException("'certificate' cannot be null"); } if (certificate.isEmpty()) { throw new IllegalArgumentException("'certificate' cannot be empty"); } if (privateKey == null) { throw new IllegalArgumentException("'privateKey' cannot be null"); } if (!privateKey.isPrivate()) { throw new IllegalArgumentException("'privateKey' must be private"); } if (privateKey instanceof RSAKeyParameters) { this.signer = new TlsRSASigner(); } else if (privateKey instanceof DSAPrivateKeyParameters) { this.signer = new TlsDSSSigner(); } else if (privateKey instanceof ECPrivateKeyParameters) { this.signer = new TlsECDSASigner(); } else { throw new IllegalArgumentException("'privateKey' type not supported: " + privateKey.getClass().getName()); } this.signer.init(context); this.context = context; this.certificate = certificate; this.privateKey = privateKey; } public Certificate getCertificate() { return certificate; } public byte[] generateCertificateSignature(byte[] md5andsha1) throws IOException { try { return signer.generateRawSignature(privateKey, md5andsha1); } catch (CryptoException e) { throw new TlsFatalAlert(AlertDescription.internal_error); } } } bouncycastle-1.49.orig/src/org/bouncycastle/crypto/tls/DTLSRecordLayer.java0000644000175000017500000003635312151551725026407 0ustar ebourgebourgpackage org.bouncycastle.crypto.tls; import java.io.IOException; class DTLSRecordLayer implements DatagramTransport { private static final int RECORD_HEADER_LENGTH = 13; private static final int MAX_FRAGMENT_LENGTH = 1 << 14; private static final long TCP_MSL = 1000L * 60 * 2; private static final long RETRANSMIT_TIMEOUT = TCP_MSL * 2; private final DatagramTransport transport; private final TlsContext context; private final TlsPeer peer; private final ByteQueue recordQueue = new ByteQueue(); private volatile boolean closed = false; private volatile boolean failed = false; private volatile ProtocolVersion discoveredPeerVersion = null; private volatile boolean inHandshake; private DTLSEpoch currentEpoch, pendingEpoch; private DTLSEpoch readEpoch, writeEpoch; private DTLSHandshakeRetransmit retransmit = null; private DTLSEpoch retransmitEpoch = null; private long retransmitExpiry = 0; DTLSRecordLayer(DatagramTransport transport, TlsContext context, TlsPeer peer, short contentType) { this.transport = transport; this.context = context; this.peer = peer; this.inHandshake = true; this.currentEpoch = new DTLSEpoch(0, new TlsNullCipher(context)); this.pendingEpoch = null; this.readEpoch = currentEpoch; this.writeEpoch = currentEpoch; } ProtocolVersion getDiscoveredPeerVersion() { return discoveredPeerVersion; } void initPendingEpoch(TlsCipher pendingCipher) { if (pendingEpoch != null) { throw new IllegalStateException(); } /* * TODO "In order to ensure that any given sequence/epoch pair is unique, implementations * MUST NOT allow the same epoch value to be reused within two times the TCP maximum segment * lifetime." */ // TODO Check for overflow this.pendingEpoch = new DTLSEpoch(writeEpoch.getEpoch() + 1, pendingCipher); } void handshakeSuccessful(DTLSHandshakeRetransmit retransmit) { if (readEpoch == currentEpoch || writeEpoch == currentEpoch) { // TODO throw new IllegalStateException(); } if (retransmit != null) { this.retransmit = retransmit; this.retransmitEpoch = currentEpoch; this.retransmitExpiry = System.currentTimeMillis() + RETRANSMIT_TIMEOUT; } this.inHandshake = false; this.currentEpoch = pendingEpoch; this.pendingEpoch = null; } void resetWriteEpoch() { if (retransmitEpoch != null) { this.writeEpoch = retransmitEpoch; } else { this.writeEpoch = currentEpoch; } } public int getReceiveLimit() throws IOException { return Math.min(MAX_FRAGMENT_LENGTH, readEpoch.getCipher().getPlaintextLimit(transport.getReceiveLimit() - RECORD_HEADER_LENGTH)); } public int getSendLimit() throws IOException { return Math.min(MAX_FRAGMENT_LENGTH, writeEpoch.getCipher().getPlaintextLimit(transport.getSendLimit() - RECORD_HEADER_LENGTH)); } public int receive(byte[] buf, int off, int len, int waitMillis) throws IOException { byte[] record = null; for (; ; ) { int receiveLimit = Math.min(len, getReceiveLimit()) + RECORD_HEADER_LENGTH; if (record == null || record.length < receiveLimit) { record = new byte[receiveLimit]; } try { if (retransmit != null && System.currentTimeMillis() > retransmitExpiry) { retransmit = null; retransmitEpoch = null; } int received = receiveRecord(record, 0, receiveLimit, waitMillis); if (received < 0) { return received; } if (received < RECORD_HEADER_LENGTH) { continue; } int length = TlsUtils.readUint16(record, 11); if (received != (length + RECORD_HEADER_LENGTH)) { continue; } short type = TlsUtils.readUint8(record, 0); // TODO Support user-specified custom protocols? switch (type) { case ContentType.alert: case ContentType.application_data: case ContentType.change_cipher_spec: case ContentType.handshake: break; default: // TODO Exception? continue; } int epoch = TlsUtils.readUint16(record, 3); DTLSEpoch recordEpoch = null; if (epoch == readEpoch.getEpoch()) { recordEpoch = readEpoch; } else if (type == ContentType.handshake && retransmitEpoch != null && epoch == retransmitEpoch.getEpoch()) { recordEpoch = retransmitEpoch; } if (recordEpoch == null) { continue; } long seq = TlsUtils.readUint48(record, 5); if (recordEpoch.getReplayWindow().shouldDiscard(seq)) { continue; } ProtocolVersion version = TlsUtils.readVersion(record, 1); if (discoveredPeerVersion != null && !discoveredPeerVersion.equals(version)) { continue; } byte[] plaintext = recordEpoch.getCipher().decodeCiphertext( getMacSequenceNumber(recordEpoch.getEpoch(), seq), type, record, RECORD_HEADER_LENGTH, received - RECORD_HEADER_LENGTH); recordEpoch.getReplayWindow().reportAuthenticated(seq); if (discoveredPeerVersion == null) { discoveredPeerVersion = version; } switch (type) { case ContentType.alert: { if (plaintext.length == 2) { short alertLevel = plaintext[0]; short alertDescription = plaintext[1]; peer.notifyAlertReceived(alertLevel, alertDescription); if (alertLevel == AlertLevel.fatal) { fail(alertDescription); throw new TlsFatalAlert(alertDescription); } // TODO Can close_notify be a fatal alert? if (alertDescription == AlertDescription.close_notify) { closeTransport(); } } else { // TODO What exception? } continue; } case ContentType.application_data: { if (inHandshake) { // TODO Consider buffering application data for new epoch that arrives // out-of-order with the Finished message continue; } break; } case ContentType.change_cipher_spec: { // Implicitly receive change_cipher_spec and change to pending cipher state if (plaintext.length != 1 || plaintext[0] != 1) { continue; } if (pendingEpoch != null) { readEpoch = pendingEpoch; } continue; } case ContentType.handshake: { if (!inHandshake) { if (retransmit != null) { retransmit.receivedHandshakeRecord(epoch, plaintext, 0, plaintext.length); } // TODO Consider support for HelloRequest continue; } } } /* * NOTE: If we receive any non-handshake data in the new epoch implies the peer has * received our final flight. */ if (!inHandshake && retransmit != null) { this.retransmit = null; this.retransmitEpoch = null; } System.arraycopy(plaintext, 0, buf, off, plaintext.length); return plaintext.length; } catch (IOException e) { // NOTE: Assume this is a timeout for the moment throw e; } } } public void send(byte[] buf, int off, int len) throws IOException { short contentType = ContentType.application_data; if (this.inHandshake || this.writeEpoch == this.retransmitEpoch) { contentType = ContentType.handshake; short handshakeType = TlsUtils.readUint8(buf, off); if (handshakeType == HandshakeType.finished) { DTLSEpoch nextEpoch = null; if (this.inHandshake) { nextEpoch = pendingEpoch; } else if (this.writeEpoch == this.retransmitEpoch) { nextEpoch = currentEpoch; } if (nextEpoch == null) { // TODO throw new IllegalStateException(); } // Implicitly send change_cipher_spec and change to pending cipher state // TODO Send change_cipher_spec and finished records in single datagram? byte[] data = new byte[]{1}; sendRecord(ContentType.change_cipher_spec, data, 0, data.length); writeEpoch = nextEpoch; } } sendRecord(contentType, buf, off, len); } public void close() throws IOException { if (!closed) { if (inHandshake) { warn(AlertDescription.user_canceled, "User canceled handshake"); } closeTransport(); } } void fail(short alertDescription) { if (!closed) { try { raiseAlert(AlertLevel.fatal, alertDescription, null, null); } catch (Exception e) { // Ignore } failed = true; closeTransport(); } } void warn(short alertDescription, String message) throws IOException { raiseAlert(AlertLevel.warning, alertDescription, message, null); } private void closeTransport() { if (!closed) { /* * RFC 5246 7.2.1. Unless some other fatal alert has been transmitted, each party is * required to send a close_notify alert before closing the write side of the * connection. The other party MUST respond with a close_notify alert of its own and * close down the connection immediately, discarding any pending writes. */ try { if (!failed) { warn(AlertDescription.close_notify, null); } transport.close(); } catch (Exception e) { // Ignore } closed = true; } } private void raiseAlert(short alertLevel, short alertDescription, String message, Exception cause) throws IOException { peer.notifyAlertRaised(alertLevel, alertDescription, message, cause); byte[] error = new byte[2]; error[0] = (byte)alertLevel; error[1] = (byte)alertDescription; sendRecord(ContentType.alert, error, 0, 2); } private int receiveRecord(byte[] buf, int off, int len, int waitMillis) throws IOException { if (recordQueue.size() > 0) { int length = 0; if (recordQueue.size() >= RECORD_HEADER_LENGTH) { byte[] lengthBytes = new byte[2]; recordQueue.read(lengthBytes, 0, 2, 11); length = TlsUtils.readUint16(lengthBytes, 0); } int received = Math.min(recordQueue.size(), RECORD_HEADER_LENGTH + length); recordQueue.read(buf, off, received, 0); recordQueue.removeData(received); return received; } int received = transport.receive(buf, off, len, waitMillis); if (received >= RECORD_HEADER_LENGTH) { int fragmentLength = TlsUtils.readUint16(buf, off + 11); int recordLength = RECORD_HEADER_LENGTH + fragmentLength; if (received > recordLength) { recordQueue.addData(buf, off + recordLength, received - recordLength); received = recordLength; } } return received; } private void sendRecord(short contentType, byte[] buf, int off, int len) throws IOException { /* * RFC 5264 6.2.1 Implementations MUST NOT send zero-length fragments of Handshake, Alert, * or ChangeCipherSpec content types. */ if (len < 1 && contentType != ContentType.application_data) { throw new TlsFatalAlert(AlertDescription.internal_error); } int recordEpoch = writeEpoch.getEpoch(); long recordSequenceNumber = writeEpoch.allocateSequenceNumber(); byte[] ciphertext = writeEpoch.getCipher().encodePlaintext( getMacSequenceNumber(recordEpoch, recordSequenceNumber), contentType, buf, off, len); if (ciphertext.length > MAX_FRAGMENT_LENGTH) { throw new TlsFatalAlert(AlertDescription.internal_error); } byte[] record = new byte[ciphertext.length + RECORD_HEADER_LENGTH]; TlsUtils.writeUint8(contentType, record, 0); ProtocolVersion version = discoveredPeerVersion != null ? discoveredPeerVersion : context.getClientVersion(); TlsUtils.writeVersion(version, record, 1); TlsUtils.writeUint16(recordEpoch, record, 3); TlsUtils.writeUint48(recordSequenceNumber, record, 5); TlsUtils.writeUint16(ciphertext.length, record, 11); System.arraycopy(ciphertext, 0, record, RECORD_HEADER_LENGTH, ciphertext.length); transport.send(record, 0, record.length); } private static long getMacSequenceNumber(int epoch, long sequence_number) { return ((long)epoch << 48) | sequence_number; } } bouncycastle-1.49.orig/src/org/bouncycastle/crypto/tls/NewSessionTicket.java0000644000175000017500000000177112151551725026742 0ustar ebourgebourgpackage org.bouncycastle.crypto.tls; import java.io.IOException; import java.io.InputStream; import java.io.OutputStream; public class NewSessionTicket { protected long ticketLifetimeHint; protected byte[] ticket; public NewSessionTicket(long ticketLifetimeHint, byte[] ticket) { this.ticketLifetimeHint = ticketLifetimeHint; this.ticket = ticket; } public long getTicketLifetimeHint() { return ticketLifetimeHint; } public byte[] getTicket() { return ticket; } public void encode(OutputStream output) throws IOException { TlsUtils.writeUint32(ticketLifetimeHint, output); TlsUtils.writeOpaque16(ticket, output); } public static NewSessionTicket parse(InputStream input) throws IOException { long ticketLifetimeHint = TlsUtils.readUint32(input); byte[] ticket = TlsUtils.readOpaque16(input); return new NewSessionTicket(ticketLifetimeHint, ticket); } } bouncycastle-1.49.orig/src/org/bouncycastle/crypto/tls/UserMappingType.java0000644000175000017500000000025612151551725026572 0ustar ebourgebourgpackage org.bouncycastle.crypto.tls; /** * RFC 4681 */ public class UserMappingType { /* * RFC 4681 */ public static final short upn_domain_hint = 64; } bouncycastle-1.49.orig/src/org/bouncycastle/crypto/tls/TlsEncryptionCredentials.java0000644000175000017500000000035412151551725030470 0ustar ebourgebourgpackage org.bouncycastle.crypto.tls; import java.io.IOException; public interface TlsEncryptionCredentials extends TlsCredentials { byte[] decryptPreMasterSecret(byte[] encryptedPreMasterSecret) throws IOException; } bouncycastle-1.49.orig/src/org/bouncycastle/crypto/tls/DTLSClientProtocol.java0000644000175000017500000005626612151551725027141 0ustar ebourgebourgpackage org.bouncycastle.crypto.tls; import java.io.ByteArrayInputStream; import java.io.ByteArrayOutputStream; import java.io.IOException; import java.security.SecureRandom; import java.util.Enumeration; import java.util.Hashtable; import java.util.Vector; import org.bouncycastle.util.Arrays; public class DTLSClientProtocol extends DTLSProtocol { public DTLSClientProtocol(SecureRandom secureRandom) { super(secureRandom); } public DTLSTransport connect(TlsClient client, DatagramTransport transport) throws IOException { if (client == null) { throw new IllegalArgumentException("'client' cannot be null"); } if (transport == null) { throw new IllegalArgumentException("'transport' cannot be null"); } SecurityParameters securityParameters = new SecurityParameters(); securityParameters.entity = ConnectionEnd.client; securityParameters.clientRandom = TlsProtocol.createRandomBlock(secureRandom); ClientHandshakeState state = new ClientHandshakeState(); state.client = client; state.clientContext = new TlsClientContextImpl(secureRandom, securityParameters); client.init(state.clientContext); DTLSRecordLayer recordLayer = new DTLSRecordLayer(transport, state.clientContext, client, ContentType.handshake); try { return clientHandshake(state, recordLayer); } catch (TlsFatalAlert fatalAlert) { recordLayer.fail(fatalAlert.getAlertDescription()); throw fatalAlert; } catch (IOException e) { recordLayer.fail(AlertDescription.internal_error); throw e; } catch (RuntimeException e) { recordLayer.fail(AlertDescription.internal_error); throw new TlsFatalAlert(AlertDescription.internal_error); } } protected DTLSTransport clientHandshake(ClientHandshakeState state, DTLSRecordLayer recordLayer) throws IOException { SecurityParameters securityParameters = state.clientContext.getSecurityParameters(); DTLSReliableHandshake handshake = new DTLSReliableHandshake(state.clientContext, recordLayer); byte[] clientHelloBody = generateClientHello(state, state.client); handshake.sendMessage(HandshakeType.client_hello, clientHelloBody); DTLSReliableHandshake.Message serverMessage = handshake.receiveMessage(); { // NOTE: After receiving a record from the server, we discover the record layer version ProtocolVersion server_version = recordLayer.getDiscoveredPeerVersion(); ProtocolVersion client_version = state.clientContext.getClientVersion(); if (!server_version.isEqualOrEarlierVersionOf(client_version)) { throw new TlsFatalAlert(AlertDescription.illegal_parameter); } state.clientContext.setServerVersion(server_version); state.client.notifyServerVersion(server_version); } while (serverMessage.getType() == HandshakeType.hello_verify_request) { byte[] cookie = parseHelloVerifyRequest(state.clientContext, serverMessage.getBody()); byte[] patched = patchClientHelloWithCookie(clientHelloBody, cookie); handshake.resetHandshakeMessagesDigest(); handshake.sendMessage(HandshakeType.client_hello, patched); serverMessage = handshake.receiveMessage(); } if (serverMessage.getType() == HandshakeType.server_hello) { processServerHello(state, serverMessage.getBody()); serverMessage = handshake.receiveMessage(); } else { throw new TlsFatalAlert(AlertDescription.unexpected_message); } securityParameters.prfAlgorithm = TlsProtocol.getPRFAlgorithm(state.selectedCipherSuite); securityParameters.compressionAlgorithm = state.selectedCompressionMethod; /* * RFC 5264 7.4.9. Any cipher suite which does not explicitly specify verify_data_length has * a verify_data_length equal to 12. This includes all existing cipher suites. */ securityParameters.verifyDataLength = 12; handshake.notifyHelloComplete(); if (serverMessage.getType() == HandshakeType.supplemental_data) { processServerSupplementalData(state, serverMessage.getBody()); serverMessage = handshake.receiveMessage(); } else { state.client.processServerSupplementalData(null); } state.keyExchange = state.client.getKeyExchange(); state.keyExchange.init(state.clientContext); if (serverMessage.getType() == HandshakeType.certificate) { processServerCertificate(state, serverMessage.getBody()); serverMessage = handshake.receiveMessage(); } else { // Okay, Certificate is optional state.keyExchange.skipServerCredentials(); } if (serverMessage.getType() == HandshakeType.server_key_exchange) { processServerKeyExchange(state, serverMessage.getBody()); serverMessage = handshake.receiveMessage(); } else { // Okay, ServerKeyExchange is optional state.keyExchange.skipServerKeyExchange(); } if (serverMessage.getType() == HandshakeType.certificate_request) { processCertificateRequest(state, serverMessage.getBody()); serverMessage = handshake.receiveMessage(); } else { // Okay, CertificateRequest is optional } if (serverMessage.getType() == HandshakeType.server_hello_done) { if (serverMessage.getBody().length != 0) { throw new TlsFatalAlert(AlertDescription.decode_error); } } else { throw new TlsFatalAlert(AlertDescription.unexpected_message); } Vector clientSupplementalData = state.client.getClientSupplementalData(); if (clientSupplementalData != null) { byte[] supplementalDataBody = generateSupplementalData(clientSupplementalData); handshake.sendMessage(HandshakeType.supplemental_data, supplementalDataBody); } if (state.certificateRequest != null) { state.clientCredentials = state.authentication.getClientCredentials(state.certificateRequest); /* * RFC 5246 If no suitable certificate is available, the client MUST send a certificate * message containing no certificates. * * NOTE: In previous RFCs, this was SHOULD instead of MUST. */ Certificate clientCertificate = null; if (state.clientCredentials != null) { clientCertificate = state.clientCredentials.getCertificate(); } if (clientCertificate == null) { clientCertificate = Certificate.EMPTY_CHAIN; } byte[] certificateBody = generateCertificate(clientCertificate); handshake.sendMessage(HandshakeType.certificate, certificateBody); } if (state.clientCredentials != null) { state.keyExchange.processClientCredentials(state.clientCredentials); } else { state.keyExchange.skipClientCredentials(); } byte[] clientKeyExchangeBody = generateClientKeyExchange(state); handshake.sendMessage(HandshakeType.client_key_exchange, clientKeyExchangeBody); TlsProtocol.establishMasterSecret(state.clientContext, state.keyExchange); if (state.clientCredentials instanceof TlsSignerCredentials) { /* * TODO RFC 5246 4.7. digitally-signed element needs SignatureAndHashAlgorithm prepended * from TLS 1.2 */ TlsSignerCredentials signerCredentials = (TlsSignerCredentials)state.clientCredentials; byte[] md5andsha1 = handshake.getCurrentHash(); byte[] signature = signerCredentials.generateCertificateSignature(md5andsha1); byte[] certificateVerifyBody = generateCertificateVerify(state, signature); handshake.sendMessage(HandshakeType.certificate_verify, certificateVerifyBody); } recordLayer.initPendingEpoch(state.client.getCipher()); // NOTE: Calculated exclusive of the Finished message itself byte[] clientVerifyData = TlsUtils.calculateVerifyData(state.clientContext, "client finished", handshake.getCurrentHash()); handshake.sendMessage(HandshakeType.finished, clientVerifyData); if (state.expectSessionTicket) { serverMessage = handshake.receiveMessage(); if (serverMessage.getType() == HandshakeType.session_ticket) { processNewSessionTicket(state, serverMessage.getBody()); } else { throw new TlsFatalAlert(AlertDescription.unexpected_message); } } // NOTE: Calculated exclusive of the actual Finished message from the server byte[] expectedServerVerifyData = TlsUtils.calculateVerifyData(state.clientContext, "server finished", handshake.getCurrentHash()); serverMessage = handshake.receiveMessage(); if (serverMessage.getType() == HandshakeType.finished) { processFinished(serverMessage.getBody(), expectedServerVerifyData); } else { throw new TlsFatalAlert(AlertDescription.unexpected_message); } handshake.finish(); state.client.notifyHandshakeComplete(); return new DTLSTransport(recordLayer); } protected byte[] generateCertificateVerify(ClientHandshakeState state, byte[] signature) throws IOException { ByteArrayOutputStream buf = new ByteArrayOutputStream(); TlsUtils.writeOpaque16(signature, buf); return buf.toByteArray(); } protected byte[] generateClientHello(ClientHandshakeState state, TlsClient client) throws IOException { ByteArrayOutputStream buf = new ByteArrayOutputStream(); ProtocolVersion client_version = client.getClientVersion(); if (!client_version.isDTLS()) { throw new TlsFatalAlert(AlertDescription.internal_error); } state.clientContext.setClientVersion(client_version); TlsUtils.writeVersion(client_version, buf); buf.write(state.clientContext.getSecurityParameters().getClientRandom()); // Session id TlsUtils.writeOpaque8(TlsUtils.EMPTY_BYTES, buf); // Cookie TlsUtils.writeOpaque8(TlsUtils.EMPTY_BYTES, buf); /* * Cipher suites */ state.offeredCipherSuites = client.getCipherSuites(); // Integer -> byte[] state.clientExtensions = client.getClientExtensions(); // Cipher Suites (and SCSV) { /* * RFC 5746 3.4. The client MUST include either an empty "renegotiation_info" extension, * or the TLS_EMPTY_RENEGOTIATION_INFO_SCSV signaling cipher suite value in the * ClientHello. Including both is NOT RECOMMENDED. */ boolean noRenegExt = state.clientExtensions == null || state.clientExtensions.get(TlsProtocol.EXT_RenegotiationInfo) == null; int count = state.offeredCipherSuites.length; if (noRenegExt) { // Note: 1 extra slot for TLS_EMPTY_RENEGOTIATION_INFO_SCSV ++count; } TlsUtils.writeUint16(2 * count, buf); TlsUtils.writeUint16Array(state.offeredCipherSuites, buf); if (noRenegExt) { TlsUtils.writeUint16(CipherSuite.TLS_EMPTY_RENEGOTIATION_INFO_SCSV, buf); } } // TODO Add support for compression // Compression methods // state.offeredCompressionMethods = client.getCompressionMethods(); state.offeredCompressionMethods = new short[]{CompressionMethod._null}; TlsUtils.writeUint8((short)state.offeredCompressionMethods.length, buf); TlsUtils.writeUint8Array(state.offeredCompressionMethods, buf); // Extensions if (state.clientExtensions != null) { TlsProtocol.writeExtensions(buf, state.clientExtensions); } return buf.toByteArray(); } protected byte[] generateClientKeyExchange(ClientHandshakeState state) throws IOException { ByteArrayOutputStream buf = new ByteArrayOutputStream(); state.keyExchange.generateClientKeyExchange(buf); return buf.toByteArray(); } protected void processCertificateRequest(ClientHandshakeState state, byte[] body) throws IOException { if (state.authentication == null) { /* * RFC 2246 7.4.4. It is a fatal handshake_failure alert for an anonymous server to * request client identification. */ throw new TlsFatalAlert(AlertDescription.handshake_failure); } ByteArrayInputStream buf = new ByteArrayInputStream(body); state.certificateRequest = CertificateRequest.parse(buf); TlsProtocol.assertEmpty(buf); state.keyExchange.validateCertificateRequest(state.certificateRequest); } protected void processNewSessionTicket(ClientHandshakeState state, byte[] body) throws IOException { ByteArrayInputStream buf = new ByteArrayInputStream(body); NewSessionTicket newSessionTicket = NewSessionTicket.parse(buf); TlsProtocol.assertEmpty(buf); state.client.notifyNewSessionTicket(newSessionTicket); } protected void processServerCertificate(ClientHandshakeState state, byte[] body) throws IOException { ByteArrayInputStream buf = new ByteArrayInputStream(body); Certificate serverCertificate = Certificate.parse(buf); TlsProtocol.assertEmpty(buf); state.keyExchange.processServerCertificate(serverCertificate); state.authentication = state.client.getAuthentication(); state.authentication.notifyServerCertificate(serverCertificate); } protected void processServerHello(ClientHandshakeState state, byte[] body) throws IOException { SecurityParameters securityParameters = state.clientContext.getSecurityParameters(); ByteArrayInputStream buf = new ByteArrayInputStream(body); // TODO Read RFCs for guidance on the expected record layer version number ProtocolVersion server_version = TlsUtils.readVersion(buf); if (!server_version.equals(state.clientContext.getServerVersion())) { throw new TlsFatalAlert(AlertDescription.illegal_parameter); } securityParameters.serverRandom = TlsUtils.readFully(32, buf); byte[] sessionID = TlsUtils.readOpaque8(buf); if (sessionID.length > 32) { throw new TlsFatalAlert(AlertDescription.illegal_parameter); } state.client.notifySessionID(sessionID); state.selectedCipherSuite = TlsUtils.readUint16(buf); if (!TlsProtocol.arrayContains(state.offeredCipherSuites, state.selectedCipherSuite) || state.selectedCipherSuite == CipherSuite.TLS_NULL_WITH_NULL_NULL || state.selectedCipherSuite == CipherSuite.TLS_EMPTY_RENEGOTIATION_INFO_SCSV) { throw new TlsFatalAlert(AlertDescription.illegal_parameter); } validateSelectedCipherSuite(state.selectedCipherSuite, AlertDescription.illegal_parameter); state.client.notifySelectedCipherSuite(state.selectedCipherSuite); state.selectedCompressionMethod = TlsUtils.readUint8(buf); if (!TlsProtocol.arrayContains(state.offeredCompressionMethods, state.selectedCompressionMethod)) { throw new TlsFatalAlert(AlertDescription.illegal_parameter); } state.client.notifySelectedCompressionMethod(state.selectedCompressionMethod); /* * RFC3546 2.2 The extended server hello message format MAY be sent in place of the server * hello message when the client has requested extended functionality via the extended * client hello message specified in Section 2.1. ... Note that the extended server hello * message is only sent in response to an extended client hello message. This prevents the * possibility that the extended server hello message could "break" existing TLS 1.0 * clients. */ /* * TODO RFC 3546 2.3 If [...] the older session is resumed, then the server MUST ignore * extensions appearing in the client hello, and send a server hello containing no * extensions. */ // Integer -> byte[] Hashtable serverExtensions = TlsProtocol.readExtensions(buf); /* * RFC 3546 2.2 Note that the extended server hello message is only sent in response to an * extended client hello message. However, see RFC 5746 exception below. We always include * the SCSV, so an Extended Server Hello is always allowed. */ if (serverExtensions != null) { Enumeration e = serverExtensions.keys(); while (e.hasMoreElements()) { Integer extType = (Integer)e.nextElement(); /* * RFC 5746 Note that sending a "renegotiation_info" extension in response to a * ClientHello containing only the SCSV is an explicit exception to the prohibition * in RFC 5246, Section 7.4.1.4, on the server sending unsolicited extensions and is * only allowed because the client is signaling its willingness to receive the * extension via the TLS_EMPTY_RENEGOTIATION_INFO_SCSV SCSV. TLS implementations * MUST continue to comply with Section 7.4.1.4 for all other extensions. */ if (!extType.equals(TlsProtocol.EXT_RenegotiationInfo) && (state.clientExtensions == null || state.clientExtensions.get(extType) == null)) { /* * RFC 3546 2.3 Note that for all extension types (including those defined in * future), the extension type MUST NOT appear in the extended server hello * unless the same extension type appeared in the corresponding client hello. * Thus clients MUST abort the handshake if they receive an extension type in * the extended server hello that they did not request in the associated * (extended) client hello. */ throw new TlsFatalAlert(AlertDescription.unsupported_extension); } } /* * RFC 5746 3.4. Client Behavior: Initial Handshake */ { /* * When a ServerHello is received, the client MUST check if it includes the * "renegotiation_info" extension: */ byte[] renegExtValue = (byte[])serverExtensions.get(TlsProtocol.EXT_RenegotiationInfo); if (renegExtValue != null) { /* * If the extension is present, set the secure_renegotiation flag to TRUE. The * client MUST then verify that the length of the "renegotiated_connection" * field is zero, and if it is not, MUST abort the handshake (by sending a fatal * handshake_failure alert). */ state.secure_renegotiation = true; if (!Arrays.constantTimeAreEqual(renegExtValue, TlsProtocol.createRenegotiationInfo(TlsUtils.EMPTY_BYTES))) { throw new TlsFatalAlert(AlertDescription.handshake_failure); } } } state.expectSessionTicket = serverExtensions.containsKey(TlsProtocol.EXT_SessionTicket); } state.client.notifySecureRenegotiation(state.secure_renegotiation); if (state.clientExtensions != null) { state.client.processServerExtensions(serverExtensions); } } protected void processServerKeyExchange(ClientHandshakeState state, byte[] body) throws IOException { ByteArrayInputStream buf = new ByteArrayInputStream(body); state.keyExchange.processServerKeyExchange(buf); TlsProtocol.assertEmpty(buf); } protected void processServerSupplementalData(ClientHandshakeState state, byte[] body) throws IOException { ByteArrayInputStream buf = new ByteArrayInputStream(body); Vector serverSupplementalData = TlsProtocol.readSupplementalDataMessage(buf); state.client.processServerSupplementalData(serverSupplementalData); } protected static byte[] parseHelloVerifyRequest(TlsContext context, byte[] body) throws IOException { ByteArrayInputStream buf = new ByteArrayInputStream(body); ProtocolVersion server_version = TlsUtils.readVersion(buf); if (!server_version.equals(context.getServerVersion())) { throw new TlsFatalAlert(AlertDescription.illegal_parameter); } byte[] cookie = TlsUtils.readOpaque8(buf); // TODO RFC 4347 has the cookie length restricted to 32, but not in RFC 6347 TlsProtocol.assertEmpty(buf); return cookie; } protected static byte[] patchClientHelloWithCookie(byte[] clientHelloBody, byte[] cookie) throws IOException { int sessionIDPos = 34; int sessionIDLength = TlsUtils.readUint8(clientHelloBody, sessionIDPos); int cookieLengthPos = sessionIDPos + 1 + sessionIDLength; int cookiePos = cookieLengthPos + 1; byte[] patched = new byte[clientHelloBody.length + cookie.length]; System.arraycopy(clientHelloBody, 0, patched, 0, cookieLengthPos); TlsUtils.writeUint8((short)cookie.length, patched, cookieLengthPos); System.arraycopy(cookie, 0, patched, cookiePos, cookie.length); System.arraycopy(clientHelloBody, cookiePos, patched, cookiePos + cookie.length, clientHelloBody.length - cookiePos); return patched; } protected static class ClientHandshakeState { TlsClient client = null; TlsClientContextImpl clientContext = null; int[] offeredCipherSuites = null; short[] offeredCompressionMethods = null; Hashtable clientExtensions = null; int selectedCipherSuite = -1; short selectedCompressionMethod = -1; boolean secure_renegotiation = false; boolean expectSessionTicket = false; TlsKeyExchange keyExchange = null; TlsAuthentication authentication = null; CertificateRequest certificateRequest = null; TlsCredentials clientCredentials = null; } } bouncycastle-1.49.orig/src/org/bouncycastle/crypto/tls/CipherType.java0000644000175000017500000000061612151551725025552 0ustar ebourgebourgpackage org.bouncycastle.crypto.tls; /** * RFC 2246 *

    * Note that the values here are implementation-specific and arbitrary. It is recommended not to * depend on the particular values (e.g. serialization). */ public class CipherType { public static final int stream = 0; public static final int block = 1; /* * RFC 5246 */ public static final int aead = 2; } bouncycastle-1.49.orig/src/org/bouncycastle/crypto/tls/TlsServerContextImpl.java0000644000175000017500000000060112151551725027610 0ustar ebourgebourgpackage org.bouncycastle.crypto.tls; import java.security.SecureRandom; class TlsServerContextImpl extends AbstractTlsContext implements TlsServerContext { TlsServerContextImpl(SecureRandom secureRandom, SecurityParameters securityParameters) { super(secureRandom, securityParameters); } public boolean isServer() { return true; } } bouncycastle-1.49.orig/src/org/bouncycastle/crypto/tls/UDPTransport.java0000644000175000017500000000377512151551725026054 0ustar ebourgebourgpackage org.bouncycastle.crypto.tls; import java.io.IOException; import java.net.DatagramPacket; import java.net.DatagramSocket; public class UDPTransport implements DatagramTransport { private final static int MIN_IP_OVERHEAD = 20; private final static int MAX_IP_OVERHEAD = MIN_IP_OVERHEAD + 64; private final static int UDP_OVERHEAD = 8; private final DatagramSocket socket; private final int receiveLimit, sendLimit; public UDPTransport(DatagramSocket socket, int mtu) throws IOException { if (!socket.isBound() || !socket.isConnected()) { throw new IllegalArgumentException("'socket' must be bound and connected"); } this.socket = socket; // NOTE: As of JDK 1.6, can use NetworkInterface.getMTU this.receiveLimit = mtu - MIN_IP_OVERHEAD - UDP_OVERHEAD; this.sendLimit = mtu - MAX_IP_OVERHEAD - UDP_OVERHEAD; } public int getReceiveLimit() { return receiveLimit; } public int getSendLimit() { // TODO[DTLS] Implement Path-MTU discovery? return sendLimit; } public int receive(byte[] buf, int off, int len, int waitMillis) throws IOException { socket.setSoTimeout(waitMillis); DatagramPacket packet = new DatagramPacket(buf, off, len); socket.receive(packet); return packet.getLength(); } public void send(byte[] buf, int off, int len) throws IOException { if (len > getSendLimit()) { /* * RFC 4347 4.1.1. "If the application attempts to send a record larger than the MTU, * the DTLS implementation SHOULD generate an error, thus avoiding sending a packet * which will be fragmented." */ // TODO Exception } DatagramPacket packet = new DatagramPacket(buf, off, len); socket.send(packet); } public void close() throws IOException { socket.close(); } } bouncycastle-1.49.orig/src/org/bouncycastle/crypto/tls/ServerOnlyTlsAuthentication.java0000644000175000017500000000037212151551725031170 0ustar ebourgebourgpackage org.bouncycastle.crypto.tls; public abstract class ServerOnlyTlsAuthentication implements TlsAuthentication { public final TlsCredentials getClientCredentials(CertificateRequest certificateRequest) { return null; } } bouncycastle-1.49.orig/src/org/bouncycastle/crypto/tls/ConnectionEnd.java0000644000175000017500000000051412151551725026221 0ustar ebourgebourgpackage org.bouncycastle.crypto.tls; /** * RFC 2246 *

    * Note that the values here are implementation-specific and arbitrary. It is recommended not to * depend on the particular values (e.g. serialization). */ public class ConnectionEnd { public static final int server = 0; public static final int client = 1; } bouncycastle-1.49.orig/src/org/bouncycastle/crypto/tls/TlsPeer.java0000644000175000017500000000153212151551725025052 0ustar ebourgebourgpackage org.bouncycastle.crypto.tls; public interface TlsPeer { /** * This method will be called when an alert is raised by the protocol. * * @param alertLevel {@link AlertLevel} * @param alertDescription {@link AlertDescription} * @param message A human-readable message explaining what caused this alert. May be null. * @param cause The exception that caused this alert to be raised. May be null. */ void notifyAlertRaised(short alertLevel, short alertDescription, String message, Exception cause); /** * This method will be called when an alert is received from the remote peer. * * @param alertLevel {@link AlertLevel} * @param alertDescription {@link AlertDescription} */ void notifyAlertReceived(short alertLevel, short alertDescription); } bouncycastle-1.49.orig/src/org/bouncycastle/crypto/tls/ExporterLabel.java0000644000175000017500000000140212151551725026240 0ustar ebourgebourgpackage org.bouncycastle.crypto.tls; /** * RFC 5705 */ public class ExporterLabel { /* * RFC 5246 */ public static final String client_finished = "client finished"; public static final String server_finished = "server finished"; public static final String master_secret = "master secret"; public static final String key_expansion = "key expansion"; /* * RFC 5216 */ public static final String client_EAP_encryption = "client EAP encryption"; /* * RFC 5281 */ public static final String ttls_keying_material = "ttls keying material"; public static final String ttls_challenge = "ttls challenge"; /* * RFC 5764 */ public static final String dtls_srtp = "EXTRACTOR-dtls_srtp"; } bouncycastle-1.49.orig/src/org/bouncycastle/crypto/tls/AlertLevel.java0000644000175000017500000000025612146534067025541 0ustar ebourgebourgpackage org.bouncycastle.crypto.tls; /** * RFC 2246 7.2 */ public class AlertLevel { public static final short warning = 1; public static final short fatal = 2; } bouncycastle-1.49.orig/src/org/bouncycastle/crypto/tls/TlsNullCompression.java0000644000175000017500000000047312146535331027315 0ustar ebourgebourgpackage org.bouncycastle.crypto.tls; import java.io.OutputStream; public class TlsNullCompression implements TlsCompression { public OutputStream compress(OutputStream output) { return output; } public OutputStream decompress(OutputStream output) { return output; } } bouncycastle-1.49.orig/src/org/bouncycastle/crypto/tls/DTLSReassembler.java0000644000175000017500000000647012151551725026435 0ustar ebourgebourgpackage org.bouncycastle.crypto.tls; import java.util.Vector; class DTLSReassembler { private final short msg_type; private final byte[] body; private Vector missing = new Vector(); DTLSReassembler(short msg_type, int length) { this.msg_type = msg_type; this.body = new byte[length]; this.missing.addElement(new Range(0, length)); } short getType() { return msg_type; } byte[] getBodyIfComplete() { return missing.isEmpty() ? body : null; } void contributeFragment(short msg_type, int length, byte[] buf, int off, int fragment_offset, int fragment_length) { int fragment_end = fragment_offset + fragment_length; if (this.msg_type != msg_type || this.body.length != length || fragment_end > length) { return; } if (fragment_length == 0) { // NOTE: Empty messages still require an empty fragment to complete it if (fragment_offset == 0 && !missing.isEmpty()) { Range firstRange = (Range)missing.firstElement(); if (firstRange.getEnd() == 0) { missing.removeElementAt(0); } } return; } for (int i = 0; i < missing.size(); ++i) { Range range = (Range)missing.elementAt(i); if (range.getStart() >= fragment_end) { break; } if (range.getEnd() > fragment_offset) { int copyStart = Math.max(range.getStart(), fragment_offset); int copyEnd = Math.min(range.getEnd(), fragment_end); int copyLength = copyEnd - copyStart; System.arraycopy(buf, off + copyStart - fragment_offset, body, copyStart, copyLength); if (copyStart == range.getStart()) { if (copyEnd == range.getEnd()) { missing.removeElementAt(i--); } else { range.setStart(copyEnd); } } else { if (copyEnd == range.getEnd()) { range.setEnd(copyStart); } else { missing.insertElementAt(new Range(copyEnd, range.getEnd()), ++i); range.setEnd(copyStart); } } } } } void reset() { this.missing.removeAllElements(); this.missing.addElement(new Range(0, body.length)); } private static class Range { private int start, end; Range(int start, int end) { this.start = start; this.end = end; } public int getStart() { return start; } public void setStart(int start) { this.start = start; } public int getEnd() { return end; } public void setEnd(int end) { this.end = end; } } } bouncycastle-1.49.orig/src/org/bouncycastle/crypto/tls/DTLSReplayWindow.java0000644000175000017500000000435612151551725026616 0ustar ebourgebourgpackage org.bouncycastle.crypto.tls; /** * RFC 4347 4.1.2.5 Anti-replay *

    * Support fast rejection of duplicate records by maintaining a sliding receive window */ class DTLSReplayWindow { private static final long VALID_SEQ_MASK = 0x0000FFFFFFFFFFFFL; private static final long WINDOW_SIZE = 64L; private long latestConfirmedSeq = -1; private long bitmap = 0; /** * Check whether a received record with the given sequence number should be rejected as a duplicate. * * @param seq the 48-bit DTLSPlainText.sequence_number field of a received record. * @return true if the record should be discarded without further processing. */ boolean shouldDiscard(long seq) { if ((seq & VALID_SEQ_MASK) != seq) { return true; } if (seq <= latestConfirmedSeq) { long diff = latestConfirmedSeq - seq; if (diff >= WINDOW_SIZE) { return true; } if ((bitmap & (1L << diff)) != 0) { return true; } } return false; } /** * Report that a received record with the given sequence number passed authentication checks. * * @param seq the 48-bit DTLSPlainText.sequence_number field of an authenticated record. */ void reportAuthenticated(long seq) { if ((seq & VALID_SEQ_MASK) != seq) { throw new IllegalArgumentException("'seq' out of range"); } if (seq <= latestConfirmedSeq) { long diff = latestConfirmedSeq - seq; if (diff < WINDOW_SIZE) { bitmap |= (1L << diff); } } else { long diff = seq - latestConfirmedSeq; if (diff >= WINDOW_SIZE) { bitmap = 1; } else { bitmap <<= (int)diff; // for earlier JDKs bitmap |= 1; } latestConfirmedSeq = seq; } } /** * When a new epoch begins, sequence numbers begin again at 0 */ void reset() { latestConfirmedSeq = -1; bitmap = 0; } } bouncycastle-1.49.orig/src/org/bouncycastle/crypto/tls/AbstractTlsContext.java0000644000175000017500000000467712151551725027304 0ustar ebourgebourgpackage org.bouncycastle.crypto.tls; import java.security.SecureRandom; abstract class AbstractTlsContext implements TlsContext { private SecureRandom secureRandom; private SecurityParameters securityParameters; private ProtocolVersion clientVersion = null; private ProtocolVersion serverVersion = null; private Object userObject = null; AbstractTlsContext(SecureRandom secureRandom, SecurityParameters securityParameters) { this.secureRandom = secureRandom; this.securityParameters = securityParameters; } public SecureRandom getSecureRandom() { return secureRandom; } public SecurityParameters getSecurityParameters() { return securityParameters; } public ProtocolVersion getClientVersion() { return clientVersion; } public void setClientVersion(ProtocolVersion clientVersion) { this.clientVersion = clientVersion; } public ProtocolVersion getServerVersion() { return serverVersion; } public void setServerVersion(ProtocolVersion serverVersion) { this.serverVersion = serverVersion; } public Object getUserObject() { return userObject; } public void setUserObject(Object userObject) { this.userObject = userObject; } public byte[] exportKeyingMaterial(String asciiLabel, byte[] context_value, int length) { SecurityParameters sp = getSecurityParameters(); byte[] cr = sp.getClientRandom(), sr = sp.getServerRandom(); int seedLength = cr.length + sr.length; if (context_value != null) { seedLength += (2 + context_value.length); } byte[] seed = new byte[seedLength]; int seedPos = 0; System.arraycopy(cr, 0, seed, seedPos, cr.length); seedPos += cr.length; System.arraycopy(sr, 0, seed, seedPos, sr.length); seedPos += sr.length; if (context_value != null) { TlsUtils.writeUint16(context_value.length, seed, seedPos); seedPos += 2; System.arraycopy(context_value, 0, seed, seedPos, context_value.length); seedPos += context_value.length; } if (seedPos != seedLength) { throw new IllegalStateException("error in calculation of seed for export"); } return TlsUtils.PRF(this, sp.getMasterSecret(), asciiLabel, seed, length); } } bouncycastle-1.49.orig/src/org/bouncycastle/crypto/tls/ByteQueue.java0000644000175000017500000000643012146535331025405 0ustar ebourgebourgpackage org.bouncycastle.crypto.tls; /** * A queue for bytes. This file could be more optimized. */ public class ByteQueue { /** * @return The smallest number which can be written as 2^x which is bigger than i. */ public static final int nextTwoPow(int i) { /* * This code is based of a lot of code I found on the Internet which mostly * referenced a book called "Hacking delight". */ i |= (i >> 1); i |= (i >> 2); i |= (i >> 4); i |= (i >> 8); i |= (i >> 16); return i + 1; } /** * The initial size for our buffer. */ private static final int INITBUFSIZE = 1024; /** * The buffer where we store our data. */ private byte[] databuf = new byte[ByteQueue.INITBUFSIZE]; /** * How many bytes at the beginning of the buffer are skipped. */ private int skipped = 0; /** * How many bytes in the buffer are valid data. */ private int available = 0; /** * Read data from the buffer. * * @param buf The buffer where the read data will be copied to. * @param offset How many bytes to skip at the beginning of buf. * @param len How many bytes to read at all. * @param skip How many bytes from our data to skip. */ public void read(byte[] buf, int offset, int len, int skip) { if ((available - skip) < len) { throw new TlsRuntimeException("Not enough data to read"); } if ((buf.length - offset) < len) { throw new TlsRuntimeException("Buffer size of " + buf.length + " is too small for a read of " + len + " bytes"); } System.arraycopy(databuf, skipped + skip, buf, offset, len); return; } /** * Add some data to our buffer. * * @param data A byte-array to read data from. * @param offset How many bytes to skip at the beginning of the array. * @param len How many bytes to read from the array. */ public void addData(byte[] data, int offset, int len) { if ((skipped + available + len) > databuf.length) { byte[] tmp = new byte[ByteQueue.nextTwoPow(data.length)]; System.arraycopy(databuf, skipped, tmp, 0, available); skipped = 0; databuf = tmp; } System.arraycopy(data, offset, databuf, skipped + available, len); available += len; } /** * Remove some bytes from our data from the beginning. * * @param i How many bytes to remove. */ public void removeData(int i) { if (i > available) { throw new TlsRuntimeException("Cannot remove " + i + " bytes, only got " + available); } /* * Skip the data. */ available -= i; skipped += i; /* * If more than half of our data is skipped, we will move the data in the buffer. */ if (skipped > (databuf.length / 2)) { System.arraycopy(databuf, skipped, databuf, 0, available); skipped = 0; } } /** * @return The number of bytes which are available in this buffer. */ public int size() { return available; } } bouncycastle-1.49.orig/src/org/bouncycastle/crypto/tls/TlsClient.java0000644000175000017500000000405212151551725025375 0ustar ebourgebourgpackage org.bouncycastle.crypto.tls; import java.io.IOException; import java.util.Hashtable; import java.util.Vector; public interface TlsClient extends TlsPeer { void init(TlsClientContext context); ProtocolVersion getClientHelloRecordLayerVersion(); ProtocolVersion getClientVersion(); int[] getCipherSuites(); short[] getCompressionMethods(); // Hashtable is (Integer -> byte[]) Hashtable getClientExtensions() throws IOException; void notifyServerVersion(ProtocolVersion selectedVersion) throws IOException; void notifySessionID(byte[] sessionID); void notifySelectedCipherSuite(int selectedCipherSuite); void notifySelectedCompressionMethod(short selectedCompressionMethod); void notifySecureRenegotiation(boolean secureNegotiation) throws IOException; // Hashtable is (Integer -> byte[]) void processServerExtensions(Hashtable serverExtensions) throws IOException; // Vector is (SupplementalDataEntry) void processServerSupplementalData(Vector serverSupplementalData) throws IOException; TlsKeyExchange getKeyExchange() throws IOException; TlsAuthentication getAuthentication() throws IOException; // Vector is (SupplementalDataEntry) Vector getClientSupplementalData() throws IOException; TlsCompression getCompression() throws IOException; TlsCipher getCipher() throws IOException; /** * RFC 5077 3.3. NewSessionTicket Handshake Message *

    * This method will be called (only) when a NewSessionTicket handshake message is received. The * ticket is opaque to the client and clients MUST NOT examine the ticket under the assumption * that it complies with e.g. RFC 5077 4. Recommended Ticket Construction. * * @param newSessionTicket The ticket. * @throws IOException */ void notifyNewSessionTicket(NewSessionTicket newSessionTicket) throws IOException; void notifyHandshakeComplete() throws IOException; } bouncycastle-1.49.orig/src/org/bouncycastle/crypto/tls/SignatureAlgorithm.java0000644000175000017500000000050312151551725027301 0ustar ebourgebourgpackage org.bouncycastle.crypto.tls; /** * RFC 5246 7.4.1.4.1 (in RFC 2246, there were no specific values assigned) */ public class SignatureAlgorithm { public static final short anonymous = 0; public static final short rsa = 1; public static final short dsa = 2; public static final short ecdsa = 3; } bouncycastle-1.49.orig/src/org/bouncycastle/crypto/tls/ContentType.java0000644000175000017500000000044112146534067025752 0ustar ebourgebourgpackage org.bouncycastle.crypto.tls; /** * RFC 2246 6.2.1 */ public class ContentType { public static final short change_cipher_spec = 20; public static final short alert = 21; public static final short handshake = 22; public static final short application_data = 23; } bouncycastle-1.49.orig/src/org/bouncycastle/crypto/tls/DigestAlgorithm.java0000644000175000017500000000107212146535331026560 0ustar ebourgebourgpackage org.bouncycastle.crypto.tls; /** * RFC 2246 *

    * Note that the values here are implementation-specific and arbitrary. It is recommended not to * depend on the particular values (e.g. serialization). * * @deprecated use MACAlgorithm constants instead */ public class DigestAlgorithm { public static final int NULL = 0; public static final int MD5 = 1; public static final int SHA = 2; /* * RFC 5246 */ public static final int SHA256 = 3; public static final int SHA384 = 4; public static final int SHA512 = 5; } bouncycastle-1.49.orig/src/org/bouncycastle/crypto/tls/ClientAuthenticationType.java0000644000175000017500000000037312151551725030456 0ustar ebourgebourgpackage org.bouncycastle.crypto.tls; public class ClientAuthenticationType { /* * RFC 5077 4 */ public static final short anonymous = 0; public static final short certificate_based = 1; public static final short psk = 2; } bouncycastle-1.49.orig/src/org/bouncycastle/crypto/tls/HandshakeType.java0000644000175000017500000000157312146535331026230 0ustar ebourgebourgpackage org.bouncycastle.crypto.tls; public class HandshakeType { /* * RFC 2246 7.4 */ public static final short hello_request = 0; public static final short client_hello = 1; public static final short server_hello = 2; public static final short certificate = 11; public static final short server_key_exchange = 12; public static final short certificate_request = 13; public static final short server_hello_done = 14; public static final short certificate_verify = 15; public static final short client_key_exchange = 16; public static final short finished = 20; /* * (DTLS) RFC 4347 4.3.2 */ public static final short hello_verify_request = 3; /* * RFC 4680 */ public static final short supplemental_data = 23; /* * RFC 5077 */ public static final short session_ticket = 4; } bouncycastle-1.49.orig/src/org/bouncycastle/crypto/tls/TlsAgreementCredentials.java0000644000175000017500000000045212146535331030243 0ustar ebourgebourgpackage org.bouncycastle.crypto.tls; import java.io.IOException; import org.bouncycastle.crypto.params.AsymmetricKeyParameter; public interface TlsAgreementCredentials extends TlsCredentials { byte[] generateAgreement(AsymmetricKeyParameter peerPublicKey) throws IOException; } bouncycastle-1.49.orig/src/org/bouncycastle/crypto/tls/TlsDSASigner.java0000644000175000017500000000367412146535331025746 0ustar ebourgebourgpackage org.bouncycastle.crypto.tls; import org.bouncycastle.crypto.CipherParameters; import org.bouncycastle.crypto.CryptoException; import org.bouncycastle.crypto.DSA; import org.bouncycastle.crypto.Digest; import org.bouncycastle.crypto.Signer; import org.bouncycastle.crypto.digests.NullDigest; import org.bouncycastle.crypto.digests.SHA1Digest; import org.bouncycastle.crypto.params.AsymmetricKeyParameter; import org.bouncycastle.crypto.params.ParametersWithRandom; import org.bouncycastle.crypto.signers.DSADigestSigner; public abstract class TlsDSASigner extends AbstractTlsSigner { public byte[] generateRawSignature(AsymmetricKeyParameter privateKey, byte[] md5AndSha1) throws CryptoException { // Note: Only use the SHA1 part of the hash Signer signer = makeSigner(new NullDigest(), true, new ParametersWithRandom(privateKey, this.context.getSecureRandom())); signer.update(md5AndSha1, 16, 20); return signer.generateSignature(); } public boolean verifyRawSignature(byte[] sigBytes, AsymmetricKeyParameter publicKey, byte[] md5AndSha1) throws CryptoException { // Note: Only use the SHA1 part of the hash Signer signer = makeSigner(new NullDigest(), false, publicKey); signer.update(md5AndSha1, 16, 20); return signer.verifySignature(sigBytes); } public Signer createSigner(AsymmetricKeyParameter privateKey) { return makeSigner(new SHA1Digest(), true, new ParametersWithRandom(privateKey, this.context.getSecureRandom())); } public Signer createVerifyer(AsymmetricKeyParameter publicKey) { return makeSigner(new SHA1Digest(), false, publicKey); } protected Signer makeSigner(Digest d, boolean forSigning, CipherParameters cp) { Signer s = new DSADigestSigner(createDSAImpl(), d); s.init(forSigning, cp); return s; } protected abstract DSA createDSAImpl(); } bouncycastle-1.49.orig/src/org/bouncycastle/crypto/tls/SRTPProtectionProfile.java0000644000175000017500000000056112151551725027655 0ustar ebourgebourgpackage org.bouncycastle.crypto.tls; public class SRTPProtectionProfile { /* * RFC 5764 4.1.2. */ public static final int SRTP_AES128_CM_HMAC_SHA1_80 = 0x0001; public static final int SRTP_AES128_CM_HMAC_SHA1_32 = 0x0002; public static final int SRTP_NULL_HMAC_SHA1_80 = 0x0005; public static final int SRTP_NULL_HMAC_SHA1_32 = 0x0006; } bouncycastle-1.49.orig/src/org/bouncycastle/crypto/tls/package.html0000644000175000017500000000010710540165547025112 0ustar ebourgebourg A lightweight TLS API. bouncycastle-1.49.orig/src/org/bouncycastle/crypto/tls/TlsOutputStream.java0000644000175000017500000000145112146535331026632 0ustar ebourgebourgpackage org.bouncycastle.crypto.tls; import java.io.IOException; import java.io.OutputStream; /** * An OutputStream for an TLS connection. */ class TlsOutputStream extends OutputStream { private byte[] buf = new byte[1]; private TlsProtocol handler; TlsOutputStream(TlsProtocol handler) { this.handler = handler; } public void write(byte buf[], int offset, int len) throws IOException { this.handler.writeData(buf, offset, len); } public void write(int arg0) throws IOException { buf[0] = (byte)arg0; this.write(buf, 0, 1); } public void close() throws IOException { handler.close(); } public void flush() throws IOException { handler.flush(); } } bouncycastle-1.49.orig/src/org/bouncycastle/crypto/tls/DefaultTlsClient.java0000644000175000017500000004447312151551725026715 0ustar ebourgebourgpackage org.bouncycastle.crypto.tls; import java.io.IOException; import java.util.Hashtable; public abstract class DefaultTlsClient extends AbstractTlsClient { protected int[] namedCurves; protected short[] clientECPointFormats, serverECPointFormats; public DefaultTlsClient() { super(); } public DefaultTlsClient(TlsCipherFactory cipherFactory) { super(cipherFactory); } public int[] getCipherSuites() { return new int[]{CipherSuite.TLS_ECDHE_RSA_WITH_AES_256_CBC_SHA, CipherSuite.TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA, CipherSuite.TLS_ECDHE_RSA_WITH_3DES_EDE_CBC_SHA, CipherSuite.TLS_DHE_RSA_WITH_AES_256_CBC_SHA, CipherSuite.TLS_DHE_RSA_WITH_AES_128_CBC_SHA, CipherSuite.TLS_DHE_RSA_WITH_3DES_EDE_CBC_SHA, CipherSuite.TLS_RSA_WITH_AES_256_CBC_SHA, CipherSuite.TLS_RSA_WITH_AES_128_CBC_SHA, CipherSuite.TLS_RSA_WITH_3DES_EDE_CBC_SHA,}; } public Hashtable getClientExtensions() throws IOException { Hashtable clientExtensions = super.getClientExtensions(); if (TlsECCUtils.containsECCCipherSuites(getCipherSuites())) { /* * RFC 4492 5.1. A client that proposes ECC cipher suites in its ClientHello message * appends these extensions (along with any others), enumerating the curves it supports * and the point formats it can parse. Clients SHOULD send both the Supported Elliptic * Curves Extension and the Supported Point Formats Extension. */ /* * TODO Could just add all the curves since we support them all, but users may not want * to use unnecessarily large fields. Need configuration options. */ this.namedCurves = new int[]{NamedCurve.secp256r1, NamedCurve.sect233r1, NamedCurve.secp224r1, NamedCurve.sect193r1, NamedCurve.secp192r1, NamedCurve.arbitrary_explicit_char2_curves, NamedCurve.arbitrary_explicit_prime_curves}; this.clientECPointFormats = new short[]{ECPointFormat.ansiX962_compressed_char2, ECPointFormat.ansiX962_compressed_prime, ECPointFormat.uncompressed}; if (clientExtensions == null) { clientExtensions = new Hashtable(); } TlsECCUtils.addSupportedEllipticCurvesExtension(clientExtensions, namedCurves); TlsECCUtils.addSupportedPointFormatsExtension(clientExtensions, clientECPointFormats); } return clientExtensions; } public void processServerExtensions(Hashtable serverExtensions) throws IOException { super.processServerExtensions(serverExtensions); if (serverExtensions != null) { int[] namedCurves = TlsECCUtils.getSupportedEllipticCurvesExtension(serverExtensions); if (namedCurves != null) { throw new TlsFatalAlert(AlertDescription.illegal_parameter); } this.serverECPointFormats = TlsECCUtils.getSupportedPointFormatsExtension(serverExtensions); if (this.serverECPointFormats != null && !TlsECCUtils.isECCCipherSuite(this.selectedCipherSuite)) { throw new TlsFatalAlert(AlertDescription.illegal_parameter); } } } public TlsKeyExchange getKeyExchange() throws IOException { switch (selectedCipherSuite) { case CipherSuite.TLS_DH_DSS_WITH_3DES_EDE_CBC_SHA: case CipherSuite.TLS_DH_DSS_WITH_AES_128_CBC_SHA: case CipherSuite.TLS_DH_DSS_WITH_AES_128_CBC_SHA256: case CipherSuite.TLS_DH_DSS_WITH_AES_128_GCM_SHA256: case CipherSuite.TLS_DH_DSS_WITH_AES_256_CBC_SHA: case CipherSuite.TLS_DH_DSS_WITH_AES_256_CBC_SHA256: case CipherSuite.TLS_DH_DSS_WITH_AES_256_GCM_SHA384: case CipherSuite.TLS_DH_DSS_WITH_CAMELLIA_128_CBC_SHA: case CipherSuite.TLS_DH_DSS_WITH_CAMELLIA_256_CBC_SHA: case CipherSuite.TLS_DH_DSS_WITH_SEED_CBC_SHA: return createDHKeyExchange(KeyExchangeAlgorithm.DH_DSS); case CipherSuite.TLS_DH_RSA_WITH_3DES_EDE_CBC_SHA: case CipherSuite.TLS_DH_RSA_WITH_AES_128_CBC_SHA: case CipherSuite.TLS_DH_RSA_WITH_AES_128_CBC_SHA256: case CipherSuite.TLS_DH_RSA_WITH_AES_128_GCM_SHA256: case CipherSuite.TLS_DH_RSA_WITH_AES_256_CBC_SHA: case CipherSuite.TLS_DH_RSA_WITH_AES_256_CBC_SHA256: case CipherSuite.TLS_DH_RSA_WITH_AES_256_GCM_SHA384: case CipherSuite.TLS_DH_RSA_WITH_CAMELLIA_128_CBC_SHA: case CipherSuite.TLS_DH_RSA_WITH_CAMELLIA_256_CBC_SHA: case CipherSuite.TLS_DH_RSA_WITH_SEED_CBC_SHA: return createDHKeyExchange(KeyExchangeAlgorithm.DH_RSA); case CipherSuite.TLS_DHE_DSS_WITH_3DES_EDE_CBC_SHA: case CipherSuite.TLS_DHE_DSS_WITH_AES_128_CBC_SHA: case CipherSuite.TLS_DHE_DSS_WITH_AES_128_CBC_SHA256: case CipherSuite.TLS_DHE_DSS_WITH_AES_128_GCM_SHA256: case CipherSuite.TLS_DHE_DSS_WITH_AES_256_CBC_SHA: case CipherSuite.TLS_DHE_DSS_WITH_AES_256_CBC_SHA256: case CipherSuite.TLS_DHE_DSS_WITH_AES_256_GCM_SHA384: case CipherSuite.TLS_DHE_DSS_WITH_CAMELLIA_128_CBC_SHA: case CipherSuite.TLS_DHE_DSS_WITH_CAMELLIA_256_CBC_SHA: case CipherSuite.TLS_DHE_DSS_WITH_SEED_CBC_SHA: return createDHEKeyExchange(KeyExchangeAlgorithm.DHE_DSS); case CipherSuite.TLS_DHE_RSA_WITH_3DES_EDE_CBC_SHA: case CipherSuite.TLS_DHE_RSA_WITH_AES_128_CBC_SHA: case CipherSuite.TLS_DHE_RSA_WITH_AES_128_CBC_SHA256: case CipherSuite.TLS_DHE_RSA_WITH_AES_128_GCM_SHA256: case CipherSuite.TLS_DHE_RSA_WITH_AES_256_CBC_SHA: case CipherSuite.TLS_DHE_RSA_WITH_AES_256_CBC_SHA256: case CipherSuite.TLS_DHE_RSA_WITH_AES_256_GCM_SHA384: case CipherSuite.TLS_DHE_RSA_WITH_CAMELLIA_128_CBC_SHA: case CipherSuite.TLS_DHE_RSA_WITH_CAMELLIA_256_CBC_SHA: case CipherSuite.TLS_DHE_RSA_WITH_SEED_CBC_SHA: return createDHEKeyExchange(KeyExchangeAlgorithm.DHE_RSA); case CipherSuite.TLS_ECDH_ECDSA_WITH_3DES_EDE_CBC_SHA: case CipherSuite.TLS_ECDH_ECDSA_WITH_AES_128_CBC_SHA: case CipherSuite.TLS_ECDH_ECDSA_WITH_AES_128_CBC_SHA256: case CipherSuite.TLS_ECDH_ECDSA_WITH_AES_128_GCM_SHA256: case CipherSuite.TLS_ECDH_ECDSA_WITH_AES_256_CBC_SHA: case CipherSuite.TLS_ECDH_ECDSA_WITH_AES_256_CBC_SHA384: case CipherSuite.TLS_ECDH_ECDSA_WITH_AES_256_GCM_SHA384: case CipherSuite.TLS_ECDH_ECDSA_WITH_NULL_SHA: case CipherSuite.TLS_ECDH_ECDSA_WITH_RC4_128_SHA: return createECDHKeyExchange(KeyExchangeAlgorithm.ECDH_ECDSA); case CipherSuite.TLS_ECDH_RSA_WITH_3DES_EDE_CBC_SHA: case CipherSuite.TLS_ECDH_RSA_WITH_AES_128_CBC_SHA: case CipherSuite.TLS_ECDH_RSA_WITH_AES_128_CBC_SHA256: case CipherSuite.TLS_ECDH_RSA_WITH_AES_128_GCM_SHA256: case CipherSuite.TLS_ECDH_RSA_WITH_AES_256_CBC_SHA: case CipherSuite.TLS_ECDH_RSA_WITH_AES_256_CBC_SHA384: case CipherSuite.TLS_ECDH_RSA_WITH_AES_256_GCM_SHA384: case CipherSuite.TLS_ECDH_RSA_WITH_NULL_SHA: case CipherSuite.TLS_ECDH_RSA_WITH_RC4_128_SHA: return createECDHKeyExchange(KeyExchangeAlgorithm.ECDH_RSA); case CipherSuite.TLS_ECDHE_ECDSA_WITH_3DES_EDE_CBC_SHA: case CipherSuite.TLS_ECDHE_ECDSA_WITH_AES_128_CBC_SHA: case CipherSuite.TLS_ECDHE_ECDSA_WITH_AES_128_CBC_SHA256: case CipherSuite.TLS_ECDHE_ECDSA_WITH_AES_128_GCM_SHA256: case CipherSuite.TLS_ECDHE_ECDSA_WITH_AES_256_CBC_SHA: case CipherSuite.TLS_ECDHE_ECDSA_WITH_AES_256_CBC_SHA384: case CipherSuite.TLS_ECDHE_ECDSA_WITH_AES_256_GCM_SHA384: case CipherSuite.TLS_ECDHE_ECDSA_WITH_NULL_SHA: case CipherSuite.TLS_ECDHE_ECDSA_WITH_RC4_128_SHA: return createECDHEKeyExchange(KeyExchangeAlgorithm.ECDHE_ECDSA); case CipherSuite.TLS_ECDHE_RSA_WITH_3DES_EDE_CBC_SHA: case CipherSuite.TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA: case CipherSuite.TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA256: case CipherSuite.TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256: case CipherSuite.TLS_ECDHE_RSA_WITH_AES_256_CBC_SHA: case CipherSuite.TLS_ECDHE_RSA_WITH_AES_256_CBC_SHA384: case CipherSuite.TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384: case CipherSuite.TLS_ECDHE_RSA_WITH_NULL_SHA: case CipherSuite.TLS_ECDHE_RSA_WITH_RC4_128_SHA: return createECDHEKeyExchange(KeyExchangeAlgorithm.ECDHE_RSA); case CipherSuite.TLS_RSA_WITH_3DES_EDE_CBC_SHA: case CipherSuite.TLS_RSA_WITH_AES_128_CBC_SHA: case CipherSuite.TLS_RSA_WITH_AES_128_CBC_SHA256: case CipherSuite.TLS_RSA_WITH_AES_128_GCM_SHA256: case CipherSuite.TLS_RSA_WITH_AES_256_CBC_SHA: case CipherSuite.TLS_RSA_WITH_AES_256_CBC_SHA256: case CipherSuite.TLS_RSA_WITH_AES_256_GCM_SHA384: case CipherSuite.TLS_RSA_WITH_CAMELLIA_128_CBC_SHA: case CipherSuite.TLS_RSA_WITH_CAMELLIA_256_CBC_SHA: case CipherSuite.TLS_RSA_WITH_NULL_MD5: case CipherSuite.TLS_RSA_WITH_NULL_SHA: case CipherSuite.TLS_RSA_WITH_NULL_SHA256: case CipherSuite.TLS_RSA_WITH_RC4_128_MD5: case CipherSuite.TLS_RSA_WITH_RC4_128_SHA: case CipherSuite.TLS_RSA_WITH_SEED_CBC_SHA: return createRSAKeyExchange(); default: /* * Note: internal error here; the TlsProtocol implementation verifies that the * server-selected cipher suite was in the list of client-offered cipher suites, so if * we now can't produce an implementation, we shouldn't have offered it! */ throw new TlsFatalAlert(AlertDescription.internal_error); } } public TlsCipher getCipher() throws IOException { switch (selectedCipherSuite) { case CipherSuite.TLS_DH_DSS_WITH_3DES_EDE_CBC_SHA: case CipherSuite.TLS_DH_RSA_WITH_3DES_EDE_CBC_SHA: case CipherSuite.TLS_DHE_DSS_WITH_3DES_EDE_CBC_SHA: case CipherSuite.TLS_DHE_RSA_WITH_3DES_EDE_CBC_SHA: case CipherSuite.TLS_ECDH_ECDSA_WITH_3DES_EDE_CBC_SHA: case CipherSuite.TLS_ECDH_RSA_WITH_3DES_EDE_CBC_SHA: case CipherSuite.TLS_ECDHE_ECDSA_WITH_3DES_EDE_CBC_SHA: case CipherSuite.TLS_ECDHE_RSA_WITH_3DES_EDE_CBC_SHA: case CipherSuite.TLS_RSA_WITH_3DES_EDE_CBC_SHA: return cipherFactory.createCipher(context, EncryptionAlgorithm._3DES_EDE_CBC, MACAlgorithm.hmac_sha1); case CipherSuite.TLS_DH_DSS_WITH_AES_128_CBC_SHA: case CipherSuite.TLS_DH_RSA_WITH_AES_128_CBC_SHA: case CipherSuite.TLS_DHE_DSS_WITH_AES_128_CBC_SHA: case CipherSuite.TLS_DHE_RSA_WITH_AES_128_CBC_SHA: case CipherSuite.TLS_ECDH_ECDSA_WITH_AES_128_CBC_SHA: case CipherSuite.TLS_ECDH_RSA_WITH_AES_128_CBC_SHA: case CipherSuite.TLS_ECDHE_ECDSA_WITH_AES_128_CBC_SHA: case CipherSuite.TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA: case CipherSuite.TLS_RSA_WITH_AES_128_CBC_SHA: return cipherFactory.createCipher(context, EncryptionAlgorithm.AES_128_CBC, MACAlgorithm.hmac_sha1); case CipherSuite.TLS_DH_DSS_WITH_AES_128_CBC_SHA256: case CipherSuite.TLS_DH_RSA_WITH_AES_128_CBC_SHA256: case CipherSuite.TLS_DHE_DSS_WITH_AES_128_CBC_SHA256: case CipherSuite.TLS_DHE_RSA_WITH_AES_128_CBC_SHA256: case CipherSuite.TLS_ECDH_ECDSA_WITH_AES_128_CBC_SHA256: case CipherSuite.TLS_ECDH_RSA_WITH_AES_128_CBC_SHA256: case CipherSuite.TLS_ECDHE_ECDSA_WITH_AES_128_CBC_SHA256: case CipherSuite.TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA256: case CipherSuite.TLS_RSA_WITH_AES_128_CBC_SHA256: return cipherFactory.createCipher(context, EncryptionAlgorithm.AES_128_CBC, MACAlgorithm.hmac_sha256); case CipherSuite.TLS_DH_DSS_WITH_AES_128_GCM_SHA256: case CipherSuite.TLS_DH_RSA_WITH_AES_128_GCM_SHA256: case CipherSuite.TLS_DHE_DSS_WITH_AES_128_GCM_SHA256: case CipherSuite.TLS_DHE_RSA_WITH_AES_128_GCM_SHA256: case CipherSuite.TLS_ECDH_ECDSA_WITH_AES_128_GCM_SHA256: case CipherSuite.TLS_ECDH_RSA_WITH_AES_128_GCM_SHA256: case CipherSuite.TLS_ECDHE_ECDSA_WITH_AES_128_GCM_SHA256: case CipherSuite.TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256: case CipherSuite.TLS_RSA_WITH_AES_128_GCM_SHA256: return cipherFactory.createCipher(context, EncryptionAlgorithm.AES_128_GCM, MACAlgorithm._null); case CipherSuite.TLS_DH_DSS_WITH_AES_256_CBC_SHA: case CipherSuite.TLS_DH_RSA_WITH_AES_256_CBC_SHA: case CipherSuite.TLS_DHE_DSS_WITH_AES_256_CBC_SHA: case CipherSuite.TLS_DHE_RSA_WITH_AES_256_CBC_SHA: case CipherSuite.TLS_ECDH_ECDSA_WITH_AES_256_CBC_SHA: case CipherSuite.TLS_ECDH_RSA_WITH_AES_256_CBC_SHA: case CipherSuite.TLS_ECDHE_ECDSA_WITH_AES_256_CBC_SHA: case CipherSuite.TLS_ECDHE_RSA_WITH_AES_256_CBC_SHA: case CipherSuite.TLS_RSA_WITH_AES_256_CBC_SHA: return cipherFactory.createCipher(context, EncryptionAlgorithm.AES_256_CBC, MACAlgorithm.hmac_sha1); case CipherSuite.TLS_DH_DSS_WITH_AES_256_CBC_SHA256: case CipherSuite.TLS_DH_RSA_WITH_AES_256_CBC_SHA256: case CipherSuite.TLS_DHE_DSS_WITH_AES_256_CBC_SHA256: case CipherSuite.TLS_DHE_RSA_WITH_AES_256_CBC_SHA256: case CipherSuite.TLS_RSA_WITH_AES_256_CBC_SHA256: return cipherFactory.createCipher(context, EncryptionAlgorithm.AES_256_CBC, MACAlgorithm.hmac_sha256); case CipherSuite.TLS_ECDH_ECDSA_WITH_AES_256_CBC_SHA384: case CipherSuite.TLS_ECDH_RSA_WITH_AES_256_CBC_SHA384: case CipherSuite.TLS_ECDHE_ECDSA_WITH_AES_256_CBC_SHA384: case CipherSuite.TLS_ECDHE_RSA_WITH_AES_256_CBC_SHA384: return cipherFactory.createCipher(context, EncryptionAlgorithm.AES_256_CBC, MACAlgorithm.hmac_sha384); case CipherSuite.TLS_DH_DSS_WITH_AES_256_GCM_SHA384: case CipherSuite.TLS_DH_RSA_WITH_AES_256_GCM_SHA384: case CipherSuite.TLS_DHE_DSS_WITH_AES_256_GCM_SHA384: case CipherSuite.TLS_DHE_RSA_WITH_AES_256_GCM_SHA384: case CipherSuite.TLS_ECDH_ECDSA_WITH_AES_256_GCM_SHA384: case CipherSuite.TLS_ECDH_RSA_WITH_AES_256_GCM_SHA384: case CipherSuite.TLS_ECDHE_ECDSA_WITH_AES_256_GCM_SHA384: case CipherSuite.TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384: case CipherSuite.TLS_RSA_WITH_AES_256_GCM_SHA384: return cipherFactory.createCipher(context, EncryptionAlgorithm.AES_256_GCM, MACAlgorithm._null); case CipherSuite.TLS_DH_DSS_WITH_CAMELLIA_128_CBC_SHA: case CipherSuite.TLS_DH_RSA_WITH_CAMELLIA_128_CBC_SHA: case CipherSuite.TLS_DHE_DSS_WITH_CAMELLIA_128_CBC_SHA: case CipherSuite.TLS_DHE_RSA_WITH_CAMELLIA_128_CBC_SHA: case CipherSuite.TLS_RSA_WITH_CAMELLIA_128_CBC_SHA: return cipherFactory.createCipher(context, EncryptionAlgorithm.CAMELLIA_128_CBC, MACAlgorithm.hmac_sha1); case CipherSuite.TLS_DH_DSS_WITH_CAMELLIA_256_CBC_SHA: case CipherSuite.TLS_DH_RSA_WITH_CAMELLIA_256_CBC_SHA: case CipherSuite.TLS_DHE_DSS_WITH_CAMELLIA_256_CBC_SHA: case CipherSuite.TLS_DHE_RSA_WITH_CAMELLIA_256_CBC_SHA: case CipherSuite.TLS_RSA_WITH_CAMELLIA_256_CBC_SHA: return cipherFactory.createCipher(context, EncryptionAlgorithm.CAMELLIA_256_CBC, MACAlgorithm.hmac_sha1); case CipherSuite.TLS_RSA_WITH_NULL_MD5: return cipherFactory.createCipher(context, EncryptionAlgorithm.NULL, MACAlgorithm.hmac_md5); case CipherSuite.TLS_ECDH_ECDSA_WITH_NULL_SHA: case CipherSuite.TLS_ECDH_RSA_WITH_NULL_SHA: case CipherSuite.TLS_ECDHE_ECDSA_WITH_NULL_SHA: case CipherSuite.TLS_ECDHE_RSA_WITH_NULL_SHA: case CipherSuite.TLS_RSA_WITH_NULL_SHA: return cipherFactory.createCipher(context, EncryptionAlgorithm.NULL, MACAlgorithm.hmac_sha1); case CipherSuite.TLS_RSA_WITH_NULL_SHA256: return cipherFactory.createCipher(context, EncryptionAlgorithm.NULL, MACAlgorithm.hmac_sha256); case CipherSuite.TLS_RSA_WITH_RC4_128_MD5: return cipherFactory.createCipher(context, EncryptionAlgorithm.RC4_128, MACAlgorithm.hmac_md5); case CipherSuite.TLS_ECDH_ECDSA_WITH_RC4_128_SHA: case CipherSuite.TLS_ECDH_RSA_WITH_RC4_128_SHA: case CipherSuite.TLS_ECDHE_ECDSA_WITH_RC4_128_SHA: case CipherSuite.TLS_ECDHE_RSA_WITH_RC4_128_SHA: case CipherSuite.TLS_RSA_WITH_RC4_128_SHA: return cipherFactory.createCipher(context, EncryptionAlgorithm.RC4_128, MACAlgorithm.hmac_sha1); case CipherSuite.TLS_DH_DSS_WITH_SEED_CBC_SHA: case CipherSuite.TLS_DH_RSA_WITH_SEED_CBC_SHA: case CipherSuite.TLS_DHE_DSS_WITH_SEED_CBC_SHA: case CipherSuite.TLS_DHE_RSA_WITH_SEED_CBC_SHA: case CipherSuite.TLS_RSA_WITH_SEED_CBC_SHA: return cipherFactory.createCipher(context, EncryptionAlgorithm.SEED_CBC, MACAlgorithm.hmac_sha1); default: /* * Note: internal error here; the TlsProtocol implementation verifies that the * server-selected cipher suite was in the list of client-offered cipher suites, so if * we now can't produce an implementation, we shouldn't have offered it! */ throw new TlsFatalAlert(AlertDescription.internal_error); } } protected TlsKeyExchange createDHKeyExchange(int keyExchange) { return new TlsDHKeyExchange(keyExchange, supportedSignatureAlgorithms, null); } protected TlsKeyExchange createDHEKeyExchange(int keyExchange) { return new TlsDHEKeyExchange(keyExchange, supportedSignatureAlgorithms, null); } protected TlsKeyExchange createECDHKeyExchange(int keyExchange) { return new TlsECDHKeyExchange(keyExchange, supportedSignatureAlgorithms, namedCurves, clientECPointFormats, serverECPointFormats); } protected TlsKeyExchange createECDHEKeyExchange(int keyExchange) { return new TlsECDHEKeyExchange(keyExchange, supportedSignatureAlgorithms, namedCurves, clientECPointFormats, serverECPointFormats); } protected TlsKeyExchange createRSAKeyExchange() { return new TlsRSAKeyExchange(supportedSignatureAlgorithms); } } bouncycastle-1.49.orig/src/org/bouncycastle/crypto/tls/TlsCipherFactory.java0000644000175000017500000000052112151551725026716 0ustar ebourgebourgpackage org.bouncycastle.crypto.tls; import java.io.IOException; public interface TlsCipherFactory { /** * See enumeration classes EncryptionAlgorithm, MACAlgorithm for appropriate argument values */ TlsCipher createCipher(TlsContext context, int encryptionAlgorithm, int macAlgorithm) throws IOException; } bouncycastle-1.49.orig/src/org/bouncycastle/crypto/tls/DefaultTlsCipherFactory.java0000644000175000017500000001370112151551725030227 0ustar ebourgebourgpackage org.bouncycastle.crypto.tls; import java.io.IOException; import org.bouncycastle.crypto.BlockCipher; import org.bouncycastle.crypto.Digest; import org.bouncycastle.crypto.StreamCipher; import org.bouncycastle.crypto.digests.MD5Digest; import org.bouncycastle.crypto.digests.SHA1Digest; import org.bouncycastle.crypto.digests.SHA256Digest; import org.bouncycastle.crypto.digests.SHA384Digest; import org.bouncycastle.crypto.digests.SHA512Digest; import org.bouncycastle.crypto.engines.AESFastEngine; import org.bouncycastle.crypto.engines.CamelliaEngine; import org.bouncycastle.crypto.engines.DESedeEngine; import org.bouncycastle.crypto.engines.RC4Engine; import org.bouncycastle.crypto.engines.SEEDEngine; import org.bouncycastle.crypto.modes.AEADBlockCipher; import org.bouncycastle.crypto.modes.CBCBlockCipher; import org.bouncycastle.crypto.modes.GCMBlockCipher; public class DefaultTlsCipherFactory extends AbstractTlsCipherFactory { public TlsCipher createCipher(TlsContext context, int encryptionAlgorithm, int macAlgorithm) throws IOException { switch (encryptionAlgorithm) { case EncryptionAlgorithm._3DES_EDE_CBC: return createDESedeCipher(context, macAlgorithm); case EncryptionAlgorithm.AES_128_CBC: return createAESCipher(context, 16, macAlgorithm); case EncryptionAlgorithm.AES_128_GCM: // NOTE: Ignores macAlgorithm return createCipher_AES_GCM(context, 16, 16); case EncryptionAlgorithm.AES_256_CBC: return createAESCipher(context, 32, macAlgorithm); case EncryptionAlgorithm.AES_256_GCM: // NOTE: Ignores macAlgorithm return createCipher_AES_GCM(context, 32, 16); case EncryptionAlgorithm.CAMELLIA_128_CBC: return createCamelliaCipher(context, 16, macAlgorithm); case EncryptionAlgorithm.CAMELLIA_256_CBC: return createCamelliaCipher(context, 32, macAlgorithm); case EncryptionAlgorithm.NULL: return createNullCipher(context, macAlgorithm); case EncryptionAlgorithm.RC4_128: return createRC4Cipher(context, 16, macAlgorithm); case EncryptionAlgorithm.SEED_CBC: return createSEEDCipher(context, macAlgorithm); default: throw new TlsFatalAlert(AlertDescription.internal_error); } } protected TlsBlockCipher createAESCipher(TlsContext context, int cipherKeySize, int macAlgorithm) throws IOException { return new TlsBlockCipher(context, createAESBlockCipher(), createAESBlockCipher(), createHMACDigest(macAlgorithm), createHMACDigest(macAlgorithm), cipherKeySize); } protected TlsAEADCipher createCipher_AES_GCM(TlsContext context, int cipherKeySize, int macSize) throws IOException { return new TlsAEADCipher(context, createAEADBlockCipher_AES_GCM(), createAEADBlockCipher_AES_GCM(), cipherKeySize, macSize); } protected TlsBlockCipher createCamelliaCipher(TlsContext context, int cipherKeySize, int macAlgorithm) throws IOException { return new TlsBlockCipher(context, createCamelliaBlockCipher(), createCamelliaBlockCipher(), createHMACDigest(macAlgorithm), createHMACDigest(macAlgorithm), cipherKeySize); } protected TlsNullCipher createNullCipher(TlsContext context, int macAlgorithm) throws IOException { return new TlsNullCipher(context, createHMACDigest(macAlgorithm), createHMACDigest(macAlgorithm)); } protected TlsStreamCipher createRC4Cipher(TlsContext context, int cipherKeySize, int macAlgorithm) throws IOException { return new TlsStreamCipher(context, createRC4StreamCipher(), createRC4StreamCipher(), createHMACDigest(macAlgorithm), createHMACDigest(macAlgorithm), cipherKeySize); } protected TlsBlockCipher createDESedeCipher(TlsContext context, int macAlgorithm) throws IOException { return new TlsBlockCipher(context, createDESedeBlockCipher(), createDESedeBlockCipher(), createHMACDigest(macAlgorithm), createHMACDigest(macAlgorithm), 24); } protected TlsBlockCipher createSEEDCipher(TlsContext context, int macAlgorithm) throws IOException { return new TlsBlockCipher(context, createSEEDBlockCipher(), createSEEDBlockCipher(), createHMACDigest(macAlgorithm), createHMACDigest(macAlgorithm), 16); } protected StreamCipher createRC4StreamCipher() { return new RC4Engine(); } protected BlockCipher createAESBlockCipher() { return new CBCBlockCipher(new AESFastEngine()); } protected AEADBlockCipher createAEADBlockCipher_AES_GCM() { // TODO Consider allowing custom configuration of multiplier return new GCMBlockCipher(new AESFastEngine()); } protected BlockCipher createCamelliaBlockCipher() { return new CBCBlockCipher(new CamelliaEngine()); } protected BlockCipher createDESedeBlockCipher() { return new CBCBlockCipher(new DESedeEngine()); } protected BlockCipher createSEEDBlockCipher() { return new CBCBlockCipher(new SEEDEngine()); } protected Digest createHMACDigest(int macAlgorithm) throws IOException { switch (macAlgorithm) { case MACAlgorithm._null: return null; case MACAlgorithm.hmac_md5: return new MD5Digest(); case MACAlgorithm.hmac_sha1: return new SHA1Digest(); case MACAlgorithm.hmac_sha256: return new SHA256Digest(); case MACAlgorithm.hmac_sha384: return new SHA384Digest(); case MACAlgorithm.hmac_sha512: return new SHA512Digest(); default: throw new TlsFatalAlert(AlertDescription.internal_error); } } } bouncycastle-1.49.orig/src/org/bouncycastle/crypto/tls/TlsRSASigner.java0000644000175000017500000000643512146535331025762 0ustar ebourgebourgpackage org.bouncycastle.crypto.tls; import org.bouncycastle.crypto.AsymmetricBlockCipher; import org.bouncycastle.crypto.CipherParameters; import org.bouncycastle.crypto.CryptoException; import org.bouncycastle.crypto.Digest; import org.bouncycastle.crypto.Signer; import org.bouncycastle.crypto.encodings.PKCS1Encoding; import org.bouncycastle.crypto.engines.RSABlindedEngine; import org.bouncycastle.crypto.params.AsymmetricKeyParameter; import org.bouncycastle.crypto.params.ParametersWithRandom; import org.bouncycastle.crypto.params.RSAKeyParameters; import org.bouncycastle.crypto.signers.GenericSigner; import org.bouncycastle.crypto.signers.RSADigestSigner; import org.bouncycastle.util.Arrays; public class TlsRSASigner extends AbstractTlsSigner { public byte[] generateRawSignature(AsymmetricKeyParameter privateKey, byte[] md5AndSha1) throws CryptoException { AsymmetricBlockCipher engine = createRSAImpl(); engine.init(true, new ParametersWithRandom(privateKey, this.context.getSecureRandom())); return engine.processBlock(md5AndSha1, 0, md5AndSha1.length); } public boolean verifyRawSignature(byte[] sigBytes, AsymmetricKeyParameter publicKey, byte[] md5AndSha1) throws CryptoException { AsymmetricBlockCipher engine = createRSAImpl(); engine.init(false, publicKey); byte[] signed = engine.processBlock(sigBytes, 0, sigBytes.length); return Arrays.constantTimeAreEqual(signed, md5AndSha1); } public Signer createSigner(AsymmetricKeyParameter privateKey) { return makeSigner(new CombinedHash(), true, new ParametersWithRandom(privateKey, this.context.getSecureRandom())); } public Signer createVerifyer(AsymmetricKeyParameter publicKey) { return makeSigner(new CombinedHash(), false, publicKey); } public boolean isValidPublicKey(AsymmetricKeyParameter publicKey) { return publicKey instanceof RSAKeyParameters && !publicKey.isPrivate(); } protected Signer makeSigner(Digest d, boolean forSigning, CipherParameters cp) { Signer s; if (ProtocolVersion.TLSv12.isEqualOrEarlierVersionOf(context.getServerVersion().getEquivalentTLSVersion())) { /* * RFC 5246 4.7. In RSA signing, the opaque vector contains the signature generated * using the RSASSA-PKCS1-v1_5 signature scheme defined in [PKCS1]. */ s = new RSADigestSigner(d); } else { /* * RFC 5246 4.7. Note that earlier versions of TLS used a different RSA signature scheme * that did not include a DigestInfo encoding. */ s = new GenericSigner(createRSAImpl(), d); } s.init(forSigning, cp); return s; } protected AsymmetricBlockCipher createRSAImpl() { /* * RFC 5264 7.4.7.1. Implementation note: It is now known that remote timing-based attacks * on TLS are possible, at least when the client and server are on the same LAN. * Accordingly, implementations that use static RSA keys MUST use RSA blinding or some other * anti-timing technique, as described in [TIMING]. */ return new PKCS1Encoding(new RSABlindedEngine()); } } bouncycastle-1.49.orig/src/org/bouncycastle/crypto/tls/TlsServerContext.java0000644000175000017500000000014312151551725026767 0ustar ebourgebourgpackage org.bouncycastle.crypto.tls; public interface TlsServerContext extends TlsContext { } bouncycastle-1.49.orig/src/org/bouncycastle/crypto/util/0000755000175000017500000000000012152033551022774 5ustar ebourgebourgbouncycastle-1.49.orig/src/org/bouncycastle/crypto/util/PublicKeyFactory.java0000644000175000017500000002045111737275254027100 0ustar ebourgebourgpackage org.bouncycastle.crypto.util; import java.io.IOException; import java.io.InputStream; import java.math.BigInteger; import org.bouncycastle.asn1.ASN1Encodable; import org.bouncycastle.asn1.ASN1InputStream; import org.bouncycastle.asn1.ASN1Integer; import org.bouncycastle.asn1.ASN1ObjectIdentifier; import org.bouncycastle.asn1.ASN1OctetString; import org.bouncycastle.asn1.ASN1Primitive; import org.bouncycastle.asn1.ASN1Sequence; import org.bouncycastle.asn1.DEROctetString; import org.bouncycastle.asn1.nist.NISTNamedCurves; import org.bouncycastle.asn1.oiw.ElGamalParameter; import org.bouncycastle.asn1.oiw.OIWObjectIdentifiers; import org.bouncycastle.asn1.pkcs.DHParameter; import org.bouncycastle.asn1.pkcs.PKCSObjectIdentifiers; import org.bouncycastle.asn1.pkcs.RSAPublicKey; import org.bouncycastle.asn1.sec.SECNamedCurves; import org.bouncycastle.asn1.teletrust.TeleTrusTNamedCurves; import org.bouncycastle.asn1.x509.AlgorithmIdentifier; import org.bouncycastle.asn1.x509.DSAParameter; import org.bouncycastle.asn1.x509.SubjectPublicKeyInfo; import org.bouncycastle.asn1.x509.X509ObjectIdentifiers; import org.bouncycastle.asn1.x9.DHDomainParameters; import org.bouncycastle.asn1.x9.DHPublicKey; import org.bouncycastle.asn1.x9.DHValidationParms; import org.bouncycastle.asn1.x9.X962NamedCurves; import org.bouncycastle.asn1.x9.X962Parameters; import org.bouncycastle.asn1.x9.X9ECParameters; import org.bouncycastle.asn1.x9.X9ECPoint; import org.bouncycastle.asn1.x9.X9ObjectIdentifiers; import org.bouncycastle.crypto.params.AsymmetricKeyParameter; import org.bouncycastle.crypto.params.DHParameters; import org.bouncycastle.crypto.params.DHPublicKeyParameters; import org.bouncycastle.crypto.params.DHValidationParameters; import org.bouncycastle.crypto.params.DSAParameters; import org.bouncycastle.crypto.params.DSAPublicKeyParameters; import org.bouncycastle.crypto.params.ECDomainParameters; import org.bouncycastle.crypto.params.ECPublicKeyParameters; import org.bouncycastle.crypto.params.ElGamalParameters; import org.bouncycastle.crypto.params.ElGamalPublicKeyParameters; import org.bouncycastle.crypto.params.RSAKeyParameters; /** * Factory to create asymmetric public key parameters for asymmetric ciphers from range of * ASN.1 encoded SubjectPublicKeyInfo objects. */ public class PublicKeyFactory { /** * Create a public key from a SubjectPublicKeyInfo encoding * * @param keyInfoData the SubjectPublicKeyInfo encoding * @return the appropriate key parameter * @throws IOException on an error decoding the key */ public static AsymmetricKeyParameter createKey(byte[] keyInfoData) throws IOException { return createKey(SubjectPublicKeyInfo.getInstance(ASN1Primitive.fromByteArray(keyInfoData))); } /** * Create a public key from a SubjectPublicKeyInfo encoding read from a stream * * @param inStr the stream to read the SubjectPublicKeyInfo encoding from * @return the appropriate key parameter * @throws IOException on an error decoding the key */ public static AsymmetricKeyParameter createKey(InputStream inStr) throws IOException { return createKey(SubjectPublicKeyInfo.getInstance(new ASN1InputStream(inStr).readObject())); } /** * Create a public key from the passed in SubjectPublicKeyInfo * * @param keyInfo the SubjectPublicKeyInfo containing the key data * @return the appropriate key parameter * @throws IOException on an error decoding the key */ public static AsymmetricKeyParameter createKey(SubjectPublicKeyInfo keyInfo) throws IOException { AlgorithmIdentifier algId = keyInfo.getAlgorithm(); if (algId.getAlgorithm().equals(PKCSObjectIdentifiers.rsaEncryption) || algId.getAlgorithm().equals(X509ObjectIdentifiers.id_ea_rsa)) { RSAPublicKey pubKey = RSAPublicKey.getInstance(keyInfo.parsePublicKey()); return new RSAKeyParameters(false, pubKey.getModulus(), pubKey.getPublicExponent()); } else if (algId.getAlgorithm().equals(X9ObjectIdentifiers.dhpublicnumber)) { DHPublicKey dhPublicKey = DHPublicKey.getInstance(keyInfo.parsePublicKey()); BigInteger y = dhPublicKey.getY().getValue(); DHDomainParameters dhParams = DHDomainParameters.getInstance(algId.getParameters()); BigInteger p = dhParams.getP().getValue(); BigInteger g = dhParams.getG().getValue(); BigInteger q = dhParams.getQ().getValue(); BigInteger j = null; if (dhParams.getJ() != null) { j = dhParams.getJ().getValue(); } DHValidationParameters validation = null; DHValidationParms dhValidationParms = dhParams.getValidationParms(); if (dhValidationParms != null) { byte[] seed = dhValidationParms.getSeed().getBytes(); BigInteger pgenCounter = dhValidationParms.getPgenCounter().getValue(); // TODO Check pgenCounter size? validation = new DHValidationParameters(seed, pgenCounter.intValue()); } return new DHPublicKeyParameters(y, new DHParameters(p, g, q, j, validation)); } else if (algId.getAlgorithm().equals(PKCSObjectIdentifiers.dhKeyAgreement)) { DHParameter params = DHParameter.getInstance(algId.getParameters()); ASN1Integer derY = (ASN1Integer)keyInfo.parsePublicKey(); BigInteger lVal = params.getL(); int l = lVal == null ? 0 : lVal.intValue(); DHParameters dhParams = new DHParameters(params.getP(), params.getG(), null, l); return new DHPublicKeyParameters(derY.getValue(), dhParams); } else if (algId.getAlgorithm().equals(OIWObjectIdentifiers.elGamalAlgorithm)) { ElGamalParameter params = new ElGamalParameter((ASN1Sequence)algId.getParameters()); ASN1Integer derY = (ASN1Integer)keyInfo.parsePublicKey(); return new ElGamalPublicKeyParameters(derY.getValue(), new ElGamalParameters( params.getP(), params.getG())); } else if (algId.getAlgorithm().equals(X9ObjectIdentifiers.id_dsa) || algId.getAlgorithm().equals(OIWObjectIdentifiers.dsaWithSHA1)) { ASN1Integer derY = (ASN1Integer)keyInfo.parsePublicKey(); ASN1Encodable de = algId.getParameters(); DSAParameters parameters = null; if (de != null) { DSAParameter params = DSAParameter.getInstance(de.toASN1Primitive()); parameters = new DSAParameters(params.getP(), params.getQ(), params.getG()); } return new DSAPublicKeyParameters(derY.getValue(), parameters); } else if (algId.getAlgorithm().equals(X9ObjectIdentifiers.id_ecPublicKey)) { X962Parameters params = new X962Parameters( (ASN1Primitive)algId.getParameters()); X9ECParameters x9; if (params.isNamedCurve()) { ASN1ObjectIdentifier oid = (ASN1ObjectIdentifier)params.getParameters(); x9 = X962NamedCurves.getByOID(oid); if (x9 == null) { x9 = SECNamedCurves.getByOID(oid); if (x9 == null) { x9 = NISTNamedCurves.getByOID(oid); if (x9 == null) { x9 = TeleTrusTNamedCurves.getByOID(oid); } } } } else { x9 = X9ECParameters.getInstance(params.getParameters()); } ASN1OctetString key = new DEROctetString(keyInfo.getPublicKeyData().getBytes()); X9ECPoint derQ = new X9ECPoint(x9.getCurve(), key); // TODO We lose any named parameters here ECDomainParameters dParams = new ECDomainParameters( x9.getCurve(), x9.getG(), x9.getN(), x9.getH(), x9.getSeed()); return new ECPublicKeyParameters(derQ.getPoint(), dParams); } else { throw new RuntimeException("algorithm identifier in key not recognised"); } } } bouncycastle-1.49.orig/src/org/bouncycastle/crypto/util/PrivateKeyInfoFactory.java0000644000175000017500000000423712103437527030103 0ustar ebourgebourgpackage org.bouncycastle.crypto.util; import java.io.IOException; import org.bouncycastle.asn1.ASN1Integer; import org.bouncycastle.asn1.DERNull; import org.bouncycastle.asn1.pkcs.PKCSObjectIdentifiers; import org.bouncycastle.asn1.pkcs.PrivateKeyInfo; import org.bouncycastle.asn1.pkcs.RSAPrivateKey; import org.bouncycastle.asn1.x509.AlgorithmIdentifier; import org.bouncycastle.asn1.x509.DSAParameter; import org.bouncycastle.asn1.x9.X9ObjectIdentifiers; import org.bouncycastle.crypto.params.AsymmetricKeyParameter; import org.bouncycastle.crypto.params.DSAParameters; import org.bouncycastle.crypto.params.DSAPrivateKeyParameters; import org.bouncycastle.crypto.params.RSAKeyParameters; import org.bouncycastle.crypto.params.RSAPrivateCrtKeyParameters; /** * Factory to create ASN.1 private key info objects from lightweight private keys. */ public class PrivateKeyInfoFactory { /** * Create a PrivateKeyInfo representation of a private key. * * @param privateKey the SubjectPublicKeyInfo encoding * @return the appropriate key parameter * @throws java.io.IOException on an error encoding the key */ public static PrivateKeyInfo createPrivateKeyInfo(AsymmetricKeyParameter privateKey) throws IOException { if (privateKey instanceof RSAKeyParameters) { RSAPrivateCrtKeyParameters priv = (RSAPrivateCrtKeyParameters)privateKey; return new PrivateKeyInfo(new AlgorithmIdentifier(PKCSObjectIdentifiers.rsaEncryption, DERNull.INSTANCE), new RSAPrivateKey(priv.getModulus(), priv.getPublicExponent(), priv.getExponent(), priv.getP(), priv.getQ(), priv.getDP(), priv.getDQ(), priv.getQInv())); } else if (privateKey instanceof DSAPrivateKeyParameters) { DSAPrivateKeyParameters priv = (DSAPrivateKeyParameters)privateKey; DSAParameters params = priv.getParameters(); return new PrivateKeyInfo(new AlgorithmIdentifier(X9ObjectIdentifiers.id_dsa, new DSAParameter(params.getP(), params.getQ(), params.getG())), new ASN1Integer(priv.getX())); } else { throw new IOException("key parameters not recognised."); } } } bouncycastle-1.49.orig/src/org/bouncycastle/crypto/util/Pack.java0000644000175000017500000001137712151251423024525 0ustar ebourgebourgpackage org.bouncycastle.crypto.util; public abstract class Pack { public static int bigEndianToInt(byte[] bs, int off) { int n = bs[ off] << 24; n |= (bs[++off] & 0xff) << 16; n |= (bs[++off] & 0xff) << 8; n |= (bs[++off] & 0xff); return n; } public static void bigEndianToInt(byte[] bs, int off, int[] ns) { for (int i = 0; i < ns.length; ++i) { ns[i] = bigEndianToInt(bs, off); off += 4; } } public static byte[] intToBigEndian(int n) { byte[] bs = new byte[4]; intToBigEndian(n, bs, 0); return bs; } public static void intToBigEndian(int n, byte[] bs, int off) { bs[ off] = (byte)(n >>> 24); bs[++off] = (byte)(n >>> 16); bs[++off] = (byte)(n >>> 8); bs[++off] = (byte)(n ); } public static byte[] intToBigEndian(int[] ns) { byte[] bs = new byte[4 * ns.length]; intToBigEndian(ns, bs, 0); return bs; } public static void intToBigEndian(int[] ns, byte[] bs, int off) { for (int i = 0; i < ns.length; ++i) { intToBigEndian(ns[i], bs, off); off += 4; } } public static long bigEndianToLong(byte[] bs, int off) { int hi = bigEndianToInt(bs, off); int lo = bigEndianToInt(bs, off + 4); return ((long)(hi & 0xffffffffL) << 32) | (long)(lo & 0xffffffffL); } public static void bigEndianToLong(byte[] bs, int off, long[] ns) { for (int i = 0; i < ns.length; ++i) { ns[i] = bigEndianToLong(bs, off); off += 8; } } public static byte[] longToBigEndian(long n) { byte[] bs = new byte[8]; longToBigEndian(n, bs, 0); return bs; } public static void longToBigEndian(long n, byte[] bs, int off) { intToBigEndian((int)(n >>> 32), bs, off); intToBigEndian((int)(n & 0xffffffffL), bs, off + 4); } public static byte[] longToBigEndian(long[] ns) { byte[] bs = new byte[8 * ns.length]; longToBigEndian(ns, bs, 0); return bs; } public static void longToBigEndian(long[] ns, byte[] bs, int off) { for (int i = 0; i < ns.length; ++i) { longToBigEndian(ns[i], bs, off); off += 8; } } public static int littleEndianToInt(byte[] bs, int off) { int n = bs[ off] & 0xff; n |= (bs[++off] & 0xff) << 8; n |= (bs[++off] & 0xff) << 16; n |= bs[++off] << 24; return n; } public static void littleEndianToInt(byte[] bs, int off, int[] ns) { for (int i = 0; i < ns.length; ++i) { ns[i] = littleEndianToInt(bs, off); off += 4; } } public static byte[] intToLittleEndian(int n) { byte[] bs = new byte[4]; intToLittleEndian(n, bs, 0); return bs; } public static void intToLittleEndian(int n, byte[] bs, int off) { bs[ off] = (byte)(n ); bs[++off] = (byte)(n >>> 8); bs[++off] = (byte)(n >>> 16); bs[++off] = (byte)(n >>> 24); } public static byte[] intToLittleEndian(int[] ns) { byte[] bs = new byte[4 * ns.length]; intToLittleEndian(ns, bs, 0); return bs; } public static void intToLittleEndian(int[] ns, byte[] bs, int off) { for (int i = 0; i < ns.length; ++i) { intToLittleEndian(ns[i], bs, off); off += 4; } } public static long littleEndianToLong(byte[] bs, int off) { int lo = littleEndianToInt(bs, off); int hi = littleEndianToInt(bs, off + 4); return ((long)(hi & 0xffffffffL) << 32) | (long)(lo & 0xffffffffL); } public static void littleEndianToLong(byte[] bs, int off, long[] ns) { for (int i = 0; i < ns.length; ++i) { ns[i] = littleEndianToLong(bs, off); off += 8; } } public static byte[] longToLittleEndian(long n) { byte[] bs = new byte[8]; longToLittleEndian(n, bs, 0); return bs; } public static void longToLittleEndian(long n, byte[] bs, int off) { intToLittleEndian((int)(n & 0xffffffffL), bs, off); intToLittleEndian((int)(n >>> 32), bs, off + 4); } public static byte[] longToLittleEndian(long[] ns) { byte[] bs = new byte[8 * ns.length]; longToLittleEndian(ns, bs, 0); return bs; } public static void longToLittleEndian(long[] ns, byte[] bs, int off) { for (int i = 0; i < ns.length; ++i) { longToLittleEndian(ns[i], bs, off); off += 8; } } } bouncycastle-1.49.orig/src/org/bouncycastle/crypto/util/PrivateKeyFactory.java0000644000175000017500000001556311737275252027302 0ustar ebourgebourgpackage org.bouncycastle.crypto.util; import java.io.IOException; import java.io.InputStream; import java.math.BigInteger; import org.bouncycastle.asn1.ASN1Encodable; import org.bouncycastle.asn1.ASN1InputStream; import org.bouncycastle.asn1.ASN1Integer; import org.bouncycastle.asn1.ASN1ObjectIdentifier; import org.bouncycastle.asn1.ASN1Primitive; import org.bouncycastle.asn1.ASN1Sequence; import org.bouncycastle.asn1.nist.NISTNamedCurves; import org.bouncycastle.asn1.oiw.ElGamalParameter; import org.bouncycastle.asn1.oiw.OIWObjectIdentifiers; import org.bouncycastle.asn1.pkcs.DHParameter; import org.bouncycastle.asn1.pkcs.PKCSObjectIdentifiers; import org.bouncycastle.asn1.pkcs.PrivateKeyInfo; import org.bouncycastle.asn1.pkcs.RSAPrivateKey; import org.bouncycastle.asn1.sec.ECPrivateKey; import org.bouncycastle.asn1.sec.SECNamedCurves; import org.bouncycastle.asn1.teletrust.TeleTrusTNamedCurves; import org.bouncycastle.asn1.x509.AlgorithmIdentifier; import org.bouncycastle.asn1.x509.DSAParameter; import org.bouncycastle.asn1.x9.X962NamedCurves; import org.bouncycastle.asn1.x9.X962Parameters; import org.bouncycastle.asn1.x9.X9ECParameters; import org.bouncycastle.asn1.x9.X9ObjectIdentifiers; import org.bouncycastle.crypto.params.AsymmetricKeyParameter; import org.bouncycastle.crypto.params.DHParameters; import org.bouncycastle.crypto.params.DHPrivateKeyParameters; import org.bouncycastle.crypto.params.DSAParameters; import org.bouncycastle.crypto.params.DSAPrivateKeyParameters; import org.bouncycastle.crypto.params.ECDomainParameters; import org.bouncycastle.crypto.params.ECPrivateKeyParameters; import org.bouncycastle.crypto.params.ElGamalParameters; import org.bouncycastle.crypto.params.ElGamalPrivateKeyParameters; import org.bouncycastle.crypto.params.RSAPrivateCrtKeyParameters; /** * Factory for creating private key objects from PKCS8 PrivateKeyInfo objects. */ public class PrivateKeyFactory { /** * Create a private key parameter from a PKCS8 PrivateKeyInfo encoding. * * @param privateKeyInfoData the PrivateKeyInfo encoding * @return a suitable private key parameter * @throws IOException on an error decoding the key */ public static AsymmetricKeyParameter createKey(byte[] privateKeyInfoData) throws IOException { return createKey(PrivateKeyInfo.getInstance(ASN1Primitive.fromByteArray(privateKeyInfoData))); } /** * Create a private key parameter from a PKCS8 PrivateKeyInfo encoding read from a * stream. * * @param inStr the stream to read the PrivateKeyInfo encoding from * @return a suitable private key parameter * @throws IOException on an error decoding the key */ public static AsymmetricKeyParameter createKey(InputStream inStr) throws IOException { return createKey(PrivateKeyInfo.getInstance(new ASN1InputStream(inStr).readObject())); } /** * Create a private key parameter from the passed in PKCS8 PrivateKeyInfo object. * * @param keyInfo the PrivateKeyInfo object containing the key material * @return a suitable private key parameter * @throws IOException on an error decoding the key */ public static AsymmetricKeyParameter createKey(PrivateKeyInfo keyInfo) throws IOException { AlgorithmIdentifier algId = keyInfo.getPrivateKeyAlgorithm(); if (algId.getAlgorithm().equals(PKCSObjectIdentifiers.rsaEncryption)) { RSAPrivateKey keyStructure = RSAPrivateKey.getInstance(keyInfo.parsePrivateKey()); return new RSAPrivateCrtKeyParameters(keyStructure.getModulus(), keyStructure.getPublicExponent(), keyStructure.getPrivateExponent(), keyStructure.getPrime1(), keyStructure.getPrime2(), keyStructure.getExponent1(), keyStructure.getExponent2(), keyStructure.getCoefficient()); } // TODO? // else if (algId.getObjectId().equals(X9ObjectIdentifiers.dhpublicnumber)) else if (algId.getAlgorithm().equals(PKCSObjectIdentifiers.dhKeyAgreement)) { DHParameter params = DHParameter.getInstance(algId.getParameters()); ASN1Integer derX = (ASN1Integer)keyInfo.parsePrivateKey(); BigInteger lVal = params.getL(); int l = lVal == null ? 0 : lVal.intValue(); DHParameters dhParams = new DHParameters(params.getP(), params.getG(), null, l); return new DHPrivateKeyParameters(derX.getValue(), dhParams); } else if (algId.getAlgorithm().equals(OIWObjectIdentifiers.elGamalAlgorithm)) { ElGamalParameter params = new ElGamalParameter((ASN1Sequence)algId.getParameters()); ASN1Integer derX = (ASN1Integer)keyInfo.parsePrivateKey(); return new ElGamalPrivateKeyParameters(derX.getValue(), new ElGamalParameters( params.getP(), params.getG())); } else if (algId.getAlgorithm().equals(X9ObjectIdentifiers.id_dsa)) { ASN1Integer derX = (ASN1Integer)keyInfo.parsePrivateKey(); ASN1Encodable de = algId.getParameters(); DSAParameters parameters = null; if (de != null) { DSAParameter params = DSAParameter.getInstance(de.toASN1Primitive()); parameters = new DSAParameters(params.getP(), params.getQ(), params.getG()); } return new DSAPrivateKeyParameters(derX.getValue(), parameters); } else if (algId.getAlgorithm().equals(X9ObjectIdentifiers.id_ecPublicKey)) { X962Parameters params = new X962Parameters((ASN1Primitive)algId.getParameters()); X9ECParameters x9; if (params.isNamedCurve()) { ASN1ObjectIdentifier oid = ASN1ObjectIdentifier.getInstance(params.getParameters()); x9 = X962NamedCurves.getByOID(oid); if (x9 == null) { x9 = SECNamedCurves.getByOID(oid); if (x9 == null) { x9 = NISTNamedCurves.getByOID(oid); if (x9 == null) { x9 = TeleTrusTNamedCurves.getByOID(oid); } } } } else { x9 = X9ECParameters.getInstance(params.getParameters()); } ECPrivateKey ec = ECPrivateKey.getInstance(keyInfo.parsePrivateKey()); BigInteger d = ec.getKey(); // TODO We lose any named parameters here ECDomainParameters dParams = new ECDomainParameters( x9.getCurve(), x9.getG(), x9.getN(), x9.getH(), x9.getSeed()); return new ECPrivateKeyParameters(d, dParams); } else { throw new RuntimeException("algorithm identifier in key not recognised"); } } } bouncycastle-1.49.orig/src/org/bouncycastle/crypto/util/SubjectPublicKeyInfoFactory.java0000644000175000017500000000621712150532443031222 0ustar ebourgebourgpackage org.bouncycastle.crypto.util; import java.io.IOException; import org.bouncycastle.asn1.ASN1Encodable; import org.bouncycastle.asn1.ASN1Integer; import org.bouncycastle.asn1.ASN1OctetString; import org.bouncycastle.asn1.DERNull; import org.bouncycastle.asn1.pkcs.PKCSObjectIdentifiers; import org.bouncycastle.asn1.pkcs.RSAPublicKey; import org.bouncycastle.asn1.x509.AlgorithmIdentifier; import org.bouncycastle.asn1.x509.SubjectPublicKeyInfo; import org.bouncycastle.asn1.x9.X962Parameters; import org.bouncycastle.asn1.x9.X9ECParameters; import org.bouncycastle.asn1.x9.X9ECPoint; import org.bouncycastle.asn1.x9.X9ObjectIdentifiers; import org.bouncycastle.crypto.params.AsymmetricKeyParameter; import org.bouncycastle.crypto.params.DSAPublicKeyParameters; import org.bouncycastle.crypto.params.ECDomainParameters; import org.bouncycastle.crypto.params.ECPublicKeyParameters; import org.bouncycastle.crypto.params.RSAKeyParameters; /** * Factory to create ASN.1 subject public key info objects from lightweight public keys. */ public class SubjectPublicKeyInfoFactory { /** * Create a SubjectPublicKeyInfo public key. * * @param publicKey the SubjectPublicKeyInfo encoding * @return the appropriate key parameter * @throws java.io.IOException on an error encoding the key */ public static SubjectPublicKeyInfo createSubjectPublicKeyInfo(AsymmetricKeyParameter publicKey) throws IOException { if (publicKey instanceof RSAKeyParameters) { RSAKeyParameters pub = (RSAKeyParameters)publicKey; return new SubjectPublicKeyInfo(new AlgorithmIdentifier(PKCSObjectIdentifiers.rsaEncryption, DERNull.INSTANCE), new RSAPublicKey(pub.getModulus(), pub.getExponent())); } else if (publicKey instanceof DSAPublicKeyParameters) { DSAPublicKeyParameters pub = (DSAPublicKeyParameters)publicKey; return new SubjectPublicKeyInfo(new AlgorithmIdentifier(X9ObjectIdentifiers.id_dsa), new ASN1Integer(pub.getY())); } else if (publicKey instanceof ECPublicKeyParameters) { ECPublicKeyParameters pub = (ECPublicKeyParameters)publicKey; ECDomainParameters domainParams = pub.getParameters(); ASN1Encodable params; // TODO: need to handle named curves if (domainParams == null) { params = new X962Parameters(DERNull.INSTANCE); // Implicitly CA } else { X9ECParameters ecP = new X9ECParameters( domainParams.getCurve(), domainParams.getG(), domainParams.getN(), domainParams.getH(), domainParams.getSeed()); params = new X962Parameters(ecP); } ASN1OctetString p = (ASN1OctetString)new X9ECPoint(pub.getQ()).toASN1Primitive(); return new SubjectPublicKeyInfo(new AlgorithmIdentifier(X9ObjectIdentifiers.id_ecPublicKey, params), p.getOctets()); } else { throw new IOException("key parameters not recognised."); } } } bouncycastle-1.49.orig/src/org/bouncycastle/crypto/util/package.html0000644000175000017500000000013110540165547025262 0ustar ebourgebourg Some general utility/conversion classes. bouncycastle-1.49.orig/src/org/bouncycastle/crypto/StreamBlockCipher.java0000644000175000017500000000547010262753175026244 0ustar ebourgebourgpackage org.bouncycastle.crypto; /** * a wrapper for block ciphers with a single byte block size, so that they * can be treated like stream ciphers. */ public class StreamBlockCipher implements StreamCipher { private BlockCipher cipher; private byte[] oneByte = new byte[1]; /** * basic constructor. * * @param cipher the block cipher to be wrapped. * @exception IllegalArgumentException if the cipher has a block size other than * one. */ public StreamBlockCipher( BlockCipher cipher) { if (cipher.getBlockSize() != 1) { throw new IllegalArgumentException("block cipher block size != 1."); } this.cipher = cipher; } /** * initialise the underlying cipher. * * @param forEncryption true if we are setting up for encryption, false otherwise. * @param params the necessary parameters for the underlying cipher to be initialised. */ public void init( boolean forEncryption, CipherParameters params) { cipher.init(forEncryption, params); } /** * return the name of the algorithm we are wrapping. * * @return the name of the algorithm we are wrapping. */ public String getAlgorithmName() { return cipher.getAlgorithmName(); } /** * encrypt/decrypt a single byte returning the result. * * @param in the byte to be processed. * @return the result of processing the input byte. */ public byte returnByte( byte in) { oneByte[0] = in; cipher.processBlock(oneByte, 0, oneByte, 0); return oneByte[0]; } /** * process a block of bytes from in putting the result into out. * * @param in the input byte array. * @param inOff the offset into the in array where the data to be processed starts. * @param len the number of bytes to be processed. * @param out the output buffer the processed bytes go into. * @param outOff the offset into the output byte array the processed data stars at. * @exception DataLengthException if the output buffer is too small. */ public void processBytes( byte[] in, int inOff, int len, byte[] out, int outOff) throws DataLengthException { if (outOff + len > out.length) { throw new DataLengthException("output buffer too small in processBytes()"); } for (int i = 0; i != len; i++) { cipher.processBlock(in, inOff + i, out, outOff + i); } } /** * reset the underlying cipher. This leaves it in the same state * it was at after the last init (if there was one). */ public void reset() { cipher.reset(); } } bouncycastle-1.49.orig/src/org/bouncycastle/crypto/BasicAgreement.java0000644000175000017500000000110012057230777025540 0ustar ebourgebourgpackage org.bouncycastle.crypto; import java.math.BigInteger; /** * The basic interface that basic Diffie-Hellman implementations * conforms to. */ public interface BasicAgreement { /** * initialise the agreement engine. */ void init(CipherParameters param); /** * return the field size for the agreement algorithm in bytes. */ int getFieldSize(); /** * given a public key from a given party calculate the next * message in the agreement sequence. */ BigInteger calculateAgreement(CipherParameters pubKey); } bouncycastle-1.49.orig/src/org/bouncycastle/crypto/AsymmetricBlockCipher.java0000644000175000017500000000261610262753175027125 0ustar ebourgebourgpackage org.bouncycastle.crypto; /** * base interface that a public/private key block cipher needs * to conform to. */ public interface AsymmetricBlockCipher { /** * initialise the cipher. * * @param forEncryption if true the cipher is initialised for * encryption, if false for decryption. * @param param the key and other data required by the cipher. */ public void init(boolean forEncryption, CipherParameters param); /** * returns the largest size an input block can be. * * @return maximum size for an input block. */ public int getInputBlockSize(); /** * returns the maximum size of the block produced by this cipher. * * @return maximum size of the output block produced by the cipher. */ public int getOutputBlockSize(); /** * process the block of len bytes stored in in from offset inOff. * * @param in the input data * @param inOff offset into the in array where the data starts * @param len the length of the block to be processed. * @return the resulting byte array of the encryption/decryption process. * @exception InvalidCipherTextException data decrypts improperly. * @exception DataLengthException the input data is too large for the cipher. */ public byte[] processBlock(byte[] in, int inOff, int len) throws InvalidCipherTextException; } bouncycastle-1.49.orig/src/org/bouncycastle/crypto/SignerWithRecovery.java0000644000175000017500000000204411502002462026457 0ustar ebourgebourgpackage org.bouncycastle.crypto; /** * Signer with message recovery. */ public interface SignerWithRecovery extends Signer { /** * Returns true if the signer has recovered the full message as * part of signature verification. * * @return true if full message recovered. */ public boolean hasFullMessage(); /** * Returns a reference to what message was recovered (if any). * * @return full/partial message, null if nothing. */ public byte[] getRecoveredMessage(); /** * Perform an update with the recovered message before adding any other data. This must * be the first update method called, and calling it will result in the signer assuming * that further calls to update will include message content past what is recoverable. * * @param signature the signature that we are in the process of verifying. * @throws IllegalStateException */ public void updateWithRecoveredMessage(byte[] signature) throws InvalidCipherTextException; } bouncycastle-1.49.orig/src/org/bouncycastle/crypto/DataLengthException.java0000644000175000017500000000126710262753175026575 0ustar ebourgebourgpackage org.bouncycastle.crypto; /** * this exception is thrown if a buffer that is meant to have output * copied into it turns out to be too short, or if we've been given * insufficient input. In general this exception will get thrown rather * than an ArrayOutOfBounds exception. */ public class DataLengthException extends RuntimeCryptoException { /** * base constructor. */ public DataLengthException() { } /** * create a DataLengthException with the given message. * * @param message the message to be carried with the exception. */ public DataLengthException( String message) { super(message); } } bouncycastle-1.49.orig/src/org/bouncycastle/crypto/Digest.java0000644000175000017500000000247310262753175024122 0ustar ebourgebourgpackage org.bouncycastle.crypto; /** * interface that a message digest conforms to. */ public interface Digest { /** * return the algorithm name * * @return the algorithm name */ public String getAlgorithmName(); /** * return the size, in bytes, of the digest produced by this message digest. * * @return the size, in bytes, of the digest produced by this message digest. */ public int getDigestSize(); /** * update the message digest with a single byte. * * @param in the input byte to be entered. */ public void update(byte in); /** * update the message digest with a block of bytes. * * @param in the byte array containing the data. * @param inOff the offset into the byte array where the data starts. * @param len the length of the data. */ public void update(byte[] in, int inOff, int len); /** * close the digest, producing the final digest value. The doFinal * call leaves the digest reset. * * @param out the array the digest is to be copied into. * @param outOff the offset into the out array the digest is to start at. */ public int doFinal(byte[] out, int outOff); /** * reset the digest back to it's initial state. */ public void reset(); } bouncycastle-1.49.orig/src/org/bouncycastle/crypto/MaxBytesExceededException.java0000644000175000017500000000107010574717276027745 0ustar ebourgebourgpackage org.bouncycastle.crypto; /** * this exception is thrown whenever a cipher requires a change of key, iv * or similar after x amount of bytes enciphered */ public class MaxBytesExceededException extends RuntimeCryptoException { /** * base constructor. */ public MaxBytesExceededException() { } /** * create an with the given message. * * @param message the message to be carried with the exception. */ public MaxBytesExceededException( String message) { super(message); } } bouncycastle-1.49.orig/src/org/bouncycastle/crypto/RuntimeCryptoException.java0000644000175000017500000000101610262753175027376 0ustar ebourgebourgpackage org.bouncycastle.crypto; /** * the foundation class for the exceptions thrown by the crypto packages. */ public class RuntimeCryptoException extends RuntimeException { /** * base constructor. */ public RuntimeCryptoException() { } /** * create a RuntimeCryptoException with the given message. * * @param message the message to be carried with the exception. */ public RuntimeCryptoException( String message) { super(message); } } bouncycastle-1.49.orig/src/org/bouncycastle/crypto/modes/0000755000175000017500000000000012152033551023126 5ustar ebourgebourgbouncycastle-1.49.orig/src/org/bouncycastle/crypto/modes/EAXBlockCipher.java0000644000175000017500000002223412151251423026516 0ustar ebourgebourgpackage org.bouncycastle.crypto.modes; import org.bouncycastle.crypto.BlockCipher; import org.bouncycastle.crypto.CipherParameters; import org.bouncycastle.crypto.DataLengthException; import org.bouncycastle.crypto.InvalidCipherTextException; import org.bouncycastle.crypto.Mac; import org.bouncycastle.crypto.macs.CMac; import org.bouncycastle.crypto.params.AEADParameters; import org.bouncycastle.crypto.params.ParametersWithIV; import org.bouncycastle.util.Arrays; /** * A Two-Pass Authenticated-Encryption Scheme Optimized for Simplicity and * Efficiency - by M. Bellare, P. Rogaway, D. Wagner. * * http://www.cs.ucdavis.edu/~rogaway/papers/eax.pdf * * EAX is an AEAD scheme based on CTR and OMAC1/CMAC, that uses a single block * cipher to encrypt and authenticate data. It's on-line (the length of a * message isn't needed to begin processing it), has good performances, it's * simple and provably secure (provided the underlying block cipher is secure). * * Of course, this implementations is NOT thread-safe. */ public class EAXBlockCipher implements AEADBlockCipher { private static final byte nTAG = 0x0; private static final byte hTAG = 0x1; private static final byte cTAG = 0x2; private SICBlockCipher cipher; private boolean forEncryption; private int blockSize; private Mac mac; private byte[] nonceMac; private byte[] associatedTextMac; private byte[] macBlock; private int macSize; private byte[] bufBlock; private int bufOff; private boolean cipherInitialized; private byte[] initialAssociatedText; /** * Constructor that accepts an instance of a block cipher engine. * * @param cipher the engine to use */ public EAXBlockCipher(BlockCipher cipher) { blockSize = cipher.getBlockSize(); mac = new CMac(cipher); macBlock = new byte[blockSize]; bufBlock = new byte[blockSize * 2]; associatedTextMac = new byte[mac.getMacSize()]; nonceMac = new byte[mac.getMacSize()]; this.cipher = new SICBlockCipher(cipher); } public String getAlgorithmName() { return cipher.getUnderlyingCipher().getAlgorithmName() + "/EAX"; } public BlockCipher getUnderlyingCipher() { return cipher.getUnderlyingCipher(); } public int getBlockSize() { return cipher.getBlockSize(); } public void init(boolean forEncryption, CipherParameters params) throws IllegalArgumentException { this.forEncryption = forEncryption; byte[] nonce; CipherParameters keyParam; if (params instanceof AEADParameters) { AEADParameters param = (AEADParameters)params; nonce = param.getNonce(); initialAssociatedText = param.getAssociatedText(); macSize = param.getMacSize() / 8; keyParam = param.getKey(); } else if (params instanceof ParametersWithIV) { ParametersWithIV param = (ParametersWithIV)params; nonce = param.getIV(); initialAssociatedText = null; macSize = mac.getMacSize() / 2; keyParam = param.getParameters(); } else { throw new IllegalArgumentException("invalid parameters passed to EAX"); } byte[] tag = new byte[blockSize]; // Key reuse implemented in CBC mode of underlying CMac mac.init(keyParam); tag[blockSize - 1] = nTAG; mac.update(tag, 0, blockSize); mac.update(nonce, 0, nonce.length); mac.doFinal(nonceMac, 0); tag[blockSize - 1] = hTAG; mac.update(tag, 0, blockSize); if (initialAssociatedText != null) { processAADBytes(initialAssociatedText, 0, initialAssociatedText.length); } // Same BlockCipher underlies this and the mac, so reuse last key on cipher cipher.init(true, new ParametersWithIV(null, nonceMac)); } private void initCipher() { if (cipherInitialized) { return; } cipherInitialized = true; mac.doFinal(associatedTextMac, 0); byte[] tag = new byte[blockSize]; tag[blockSize - 1] = cTAG; mac.update(tag, 0, blockSize); } private void calculateMac() { byte[] outC = new byte[blockSize]; mac.doFinal(outC, 0); for (int i = 0; i < macBlock.length; i++) { macBlock[i] = (byte)(nonceMac[i] ^ associatedTextMac[i] ^ outC[i]); } } public void reset() { reset(true); } private void reset( boolean clearMac) { cipher.reset(); // TODO Redundant since the mac will reset it? mac.reset(); bufOff = 0; Arrays.fill(bufBlock, (byte)0); if (clearMac) { Arrays.fill(macBlock, (byte)0); } byte[] tag = new byte[blockSize]; tag[blockSize - 1] = hTAG; mac.update(tag, 0, blockSize); cipherInitialized = false; if (initialAssociatedText != null) { processAADBytes(initialAssociatedText, 0, initialAssociatedText.length); } } public void processAADByte(byte in) { if (cipherInitialized) { throw new IllegalStateException("AAD data cannot be added after encryption/decription processing has begun."); } mac.update(in); } public void processAADBytes(byte[] in, int inOff, int len) { if (cipherInitialized) { throw new IllegalStateException("AAD data cannot be added after encryption/decription processing has begun."); } mac.update(in, inOff, len); } public int processByte(byte in, byte[] out, int outOff) throws DataLengthException { initCipher(); return process(in, out, outOff); } public int processBytes(byte[] in, int inOff, int len, byte[] out, int outOff) throws DataLengthException { initCipher(); int resultLen = 0; for (int i = 0; i != len; i++) { resultLen += process(in[inOff + i], out, outOff + resultLen); } return resultLen; } public int doFinal(byte[] out, int outOff) throws IllegalStateException, InvalidCipherTextException { initCipher(); int extra = bufOff; byte[] tmp = new byte[bufBlock.length]; bufOff = 0; if (forEncryption) { cipher.processBlock(bufBlock, 0, tmp, 0); cipher.processBlock(bufBlock, blockSize, tmp, blockSize); System.arraycopy(tmp, 0, out, outOff, extra); mac.update(tmp, 0, extra); calculateMac(); System.arraycopy(macBlock, 0, out, outOff + extra, macSize); reset(false); return extra + macSize; } else { if (extra > macSize) { mac.update(bufBlock, 0, extra - macSize); cipher.processBlock(bufBlock, 0, tmp, 0); cipher.processBlock(bufBlock, blockSize, tmp, blockSize); System.arraycopy(tmp, 0, out, outOff, extra - macSize); } calculateMac(); if (!verifyMac(bufBlock, extra - macSize)) { throw new InvalidCipherTextException("mac check in EAX failed"); } reset(false); return extra - macSize; } } public byte[] getMac() { byte[] mac = new byte[macSize]; System.arraycopy(macBlock, 0, mac, 0, macSize); return mac; } public int getUpdateOutputSize(int len) { int totalData = len + bufOff; if (!forEncryption) { if (totalData < macSize) { return 0; } totalData -= macSize; } return totalData - totalData % blockSize; } public int getOutputSize(int len) { int totalData = len + bufOff; if (forEncryption) { return totalData + macSize; } return totalData < macSize ? 0 : totalData - macSize; } private int process(byte b, byte[] out, int outOff) { bufBlock[bufOff++] = b; if (bufOff == bufBlock.length) { // TODO Could move the processByte(s) calls to here // initCipher(); int size; if (forEncryption) { size = cipher.processBlock(bufBlock, 0, out, outOff); mac.update(out, outOff, blockSize); } else { mac.update(bufBlock, 0, blockSize); size = cipher.processBlock(bufBlock, 0, out, outOff); } bufOff = blockSize; System.arraycopy(bufBlock, blockSize, bufBlock, 0, blockSize); return size; } return 0; } private boolean verifyMac(byte[] mac, int off) { int nonEqual = 0; for (int i = 0; i < macSize; i++) { nonEqual |= (macBlock[i] ^ mac[off + i]); } return nonEqual == 0; } } bouncycastle-1.49.orig/src/org/bouncycastle/crypto/modes/CFBBlockCipher.java0000644000175000017500000001740712045642260026506 0ustar ebourgebourgpackage org.bouncycastle.crypto.modes; import org.bouncycastle.crypto.BlockCipher; import org.bouncycastle.crypto.CipherParameters; import org.bouncycastle.crypto.DataLengthException; import org.bouncycastle.crypto.params.ParametersWithIV; /** * implements a Cipher-FeedBack (CFB) mode on top of a simple cipher. */ public class CFBBlockCipher implements BlockCipher { private byte[] IV; private byte[] cfbV; private byte[] cfbOutV; private int blockSize; private BlockCipher cipher = null; private boolean encrypting; /** * Basic constructor. * * @param cipher the block cipher to be used as the basis of the * feedback mode. * @param bitBlockSize the block size in bits (note: a multiple of 8) */ public CFBBlockCipher( BlockCipher cipher, int bitBlockSize) { this.cipher = cipher; this.blockSize = bitBlockSize / 8; this.IV = new byte[cipher.getBlockSize()]; this.cfbV = new byte[cipher.getBlockSize()]; this.cfbOutV = new byte[cipher.getBlockSize()]; } /** * return the underlying block cipher that we are wrapping. * * @return the underlying block cipher that we are wrapping. */ public BlockCipher getUnderlyingCipher() { return cipher; } /** * Initialise the cipher and, possibly, the initialisation vector (IV). * If an IV isn't passed as part of the parameter, the IV will be all zeros. * An IV which is too short is handled in FIPS compliant fashion. * * @param encrypting if true the cipher is initialised for * encryption, if false for decryption. * @param params the key and other data required by the cipher. * @exception IllegalArgumentException if the params argument is * inappropriate. */ public void init( boolean encrypting, CipherParameters params) throws IllegalArgumentException { this.encrypting = encrypting; if (params instanceof ParametersWithIV) { ParametersWithIV ivParam = (ParametersWithIV)params; byte[] iv = ivParam.getIV(); if (iv.length < IV.length) { // prepend the supplied IV with zeros (per FIPS PUB 81) System.arraycopy(iv, 0, IV, IV.length - iv.length, iv.length); for (int i = 0; i < IV.length - iv.length; i++) { IV[i] = 0; } } else { System.arraycopy(iv, 0, IV, 0, IV.length); } reset(); // if null it's an IV changed only. if (ivParam.getParameters() != null) { cipher.init(true, ivParam.getParameters()); } } else { reset(); // if it's null, key is to be reused. if (params != null) { cipher.init(true, params); } } } /** * return the algorithm name and mode. * * @return the name of the underlying algorithm followed by "/CFB" * and the block size in bits. */ public String getAlgorithmName() { return cipher.getAlgorithmName() + "/CFB" + (blockSize * 8); } /** * return the block size we are operating at. * * @return the block size we are operating at (in bytes). */ public int getBlockSize() { return blockSize; } /** * Process one block of input from the array in and write it to * the out array. * * @param in the array containing the input data. * @param inOff offset into the in array the data starts at. * @param out the array the output data will be copied into. * @param outOff the offset into the out array the output will start at. * @exception DataLengthException if there isn't enough data in in, or * space in out. * @exception IllegalStateException if the cipher isn't initialised. * @return the number of bytes processed and produced. */ public int processBlock( byte[] in, int inOff, byte[] out, int outOff) throws DataLengthException, IllegalStateException { return (encrypting) ? encryptBlock(in, inOff, out, outOff) : decryptBlock(in, inOff, out, outOff); } /** * Do the appropriate processing for CFB mode encryption. * * @param in the array containing the data to be encrypted. * @param inOff offset into the in array the data starts at. * @param out the array the encrypted data will be copied into. * @param outOff the offset into the out array the output will start at. * @exception DataLengthException if there isn't enough data in in, or * space in out. * @exception IllegalStateException if the cipher isn't initialised. * @return the number of bytes processed and produced. */ public int encryptBlock( byte[] in, int inOff, byte[] out, int outOff) throws DataLengthException, IllegalStateException { if ((inOff + blockSize) > in.length) { throw new DataLengthException("input buffer too short"); } if ((outOff + blockSize) > out.length) { throw new DataLengthException("output buffer too short"); } cipher.processBlock(cfbV, 0, cfbOutV, 0); // // XOR the cfbV with the plaintext producing the ciphertext // for (int i = 0; i < blockSize; i++) { out[outOff + i] = (byte)(cfbOutV[i] ^ in[inOff + i]); } // // change over the input block. // System.arraycopy(cfbV, blockSize, cfbV, 0, cfbV.length - blockSize); System.arraycopy(out, outOff, cfbV, cfbV.length - blockSize, blockSize); return blockSize; } /** * Do the appropriate processing for CFB mode decryption. * * @param in the array containing the data to be decrypted. * @param inOff offset into the in array the data starts at. * @param out the array the encrypted data will be copied into. * @param outOff the offset into the out array the output will start at. * @exception DataLengthException if there isn't enough data in in, or * space in out. * @exception IllegalStateException if the cipher isn't initialised. * @return the number of bytes processed and produced. */ public int decryptBlock( byte[] in, int inOff, byte[] out, int outOff) throws DataLengthException, IllegalStateException { if ((inOff + blockSize) > in.length) { throw new DataLengthException("input buffer too short"); } if ((outOff + blockSize) > out.length) { throw new DataLengthException("output buffer too short"); } cipher.processBlock(cfbV, 0, cfbOutV, 0); // // change over the input block. // System.arraycopy(cfbV, blockSize, cfbV, 0, cfbV.length - blockSize); System.arraycopy(in, inOff, cfbV, cfbV.length - blockSize, blockSize); // // XOR the cfbV with the ciphertext producing the plaintext // for (int i = 0; i < blockSize; i++) { out[outOff + i] = (byte)(cfbOutV[i] ^ in[inOff + i]); } return blockSize; } /** * reset the chaining vector back to the IV and reset the underlying * cipher. */ public void reset() { System.arraycopy(IV, 0, cfbV, 0, IV.length); cipher.reset(); } } bouncycastle-1.49.orig/src/org/bouncycastle/crypto/modes/GCMBlockCipher.java0000644000175000017500000003610312052667021026514 0ustar ebourgebourgpackage org.bouncycastle.crypto.modes; import org.bouncycastle.crypto.BlockCipher; import org.bouncycastle.crypto.CipherParameters; import org.bouncycastle.crypto.DataLengthException; import org.bouncycastle.crypto.InvalidCipherTextException; import org.bouncycastle.crypto.modes.gcm.GCMExponentiator; import org.bouncycastle.crypto.modes.gcm.GCMMultiplier; import org.bouncycastle.crypto.modes.gcm.Tables1kGCMExponentiator; import org.bouncycastle.crypto.modes.gcm.Tables8kGCMMultiplier; import org.bouncycastle.crypto.params.AEADParameters; import org.bouncycastle.crypto.params.KeyParameter; import org.bouncycastle.crypto.params.ParametersWithIV; import org.bouncycastle.crypto.util.Pack; import org.bouncycastle.util.Arrays; /** * Implements the Galois/Counter mode (GCM) detailed in * NIST Special Publication 800-38D. */ public class GCMBlockCipher implements AEADBlockCipher { private static final int BLOCK_SIZE = 16; // not final due to a compiler bug private BlockCipher cipher; private GCMMultiplier multiplier; private GCMExponentiator exp; // These fields are set by init and not modified by processing private boolean forEncryption; private int macSize; private byte[] nonce; private byte[] initialAssociatedText; private byte[] H; private byte[] J0; // These fields are modified during processing private byte[] bufBlock; private byte[] macBlock; private byte[] S, S_at, S_atPre; private byte[] counter; private int bufOff; private long totalLength; private byte[] atBlock; private int atBlockPos; private long atLength; private long atLengthPre; public GCMBlockCipher(BlockCipher c) { this(c, null); } public GCMBlockCipher(BlockCipher c, GCMMultiplier m) { if (c.getBlockSize() != BLOCK_SIZE) { throw new IllegalArgumentException( "cipher required with a block size of " + BLOCK_SIZE + "."); } if (m == null) { // TODO Consider a static property specifying default multiplier m = new Tables8kGCMMultiplier(); } this.cipher = c; this.multiplier = m; } public BlockCipher getUnderlyingCipher() { return cipher; } public String getAlgorithmName() { return cipher.getAlgorithmName() + "/GCM"; } public void init(boolean forEncryption, CipherParameters params) throws IllegalArgumentException { this.forEncryption = forEncryption; this.macBlock = null; KeyParameter keyParam; if (params instanceof AEADParameters) { AEADParameters param = (AEADParameters)params; nonce = param.getNonce(); initialAssociatedText = param.getAssociatedText(); int macSizeBits = param.getMacSize(); if (macSizeBits < 96 || macSizeBits > 128 || macSizeBits % 8 != 0) { throw new IllegalArgumentException("Invalid value for MAC size: " + macSizeBits); } macSize = macSizeBits / 8; keyParam = param.getKey(); } else if (params instanceof ParametersWithIV) { ParametersWithIV param = (ParametersWithIV)params; nonce = param.getIV(); initialAssociatedText = null; macSize = 16; keyParam = (KeyParameter)param.getParameters(); } else { throw new IllegalArgumentException("invalid parameters passed to GCM"); } int bufLength = forEncryption ? BLOCK_SIZE : (BLOCK_SIZE + macSize); this.bufBlock = new byte[bufLength]; if (nonce == null || nonce.length < 1) { throw new IllegalArgumentException("IV must be at least 1 byte"); } // TODO This should be configurable by init parameters // (but must be 16 if nonce length not 12) (BLOCK_SIZE?) // this.tagLength = 16; // Cipher always used in forward mode // if keyParam is null we're reusing the last key. if (keyParam != null) { cipher.init(true, keyParam); this.H = new byte[BLOCK_SIZE]; cipher.processBlock(H, 0, H, 0); // GCMMultiplier tables don't change unless the key changes (and are expensive to init) multiplier.init(H); exp = null; } this.J0 = new byte[BLOCK_SIZE]; if (nonce.length == 12) { System.arraycopy(nonce, 0, J0, 0, nonce.length); this.J0[BLOCK_SIZE - 1] = 0x01; } else { gHASH(J0, nonce, nonce.length); byte[] X = new byte[BLOCK_SIZE]; Pack.longToBigEndian((long)nonce.length * 8, X, 8); gHASHBlock(J0, X); } this.S = new byte[BLOCK_SIZE]; this.S_at = new byte[BLOCK_SIZE]; this.S_atPre = new byte[BLOCK_SIZE]; this.atBlock = new byte[BLOCK_SIZE]; this.atBlockPos = 0; this.atLength = 0; this.atLengthPre = 0; this.counter = Arrays.clone(J0); this.bufOff = 0; this.totalLength = 0; if (initialAssociatedText != null) { processAADBytes(initialAssociatedText, 0, initialAssociatedText.length); } } public byte[] getMac() { return Arrays.clone(macBlock); } public int getOutputSize(int len) { int totalData = len + bufOff; if (forEncryption) { return totalData + macSize; } return totalData < macSize ? 0 : totalData - macSize; } public int getUpdateOutputSize(int len) { int totalData = len + bufOff; if (!forEncryption) { if (totalData < macSize) { return 0; } totalData -= macSize; } return totalData - totalData % BLOCK_SIZE; } public void processAADByte(byte in) { atBlock[atBlockPos] = in; if (++atBlockPos == BLOCK_SIZE) { // Hash each block as it fills gHASHBlock(S_at, atBlock); atBlockPos = 0; atLength += BLOCK_SIZE; } } public void processAADBytes(byte[] in, int inOff, int len) { for (int i = 0; i < len; ++i) { atBlock[atBlockPos] = in[inOff + i]; if (++atBlockPos == BLOCK_SIZE) { // Hash each block as it fills gHASHBlock(S_at, atBlock); atBlockPos = 0; atLength += BLOCK_SIZE; } } } private void initCipher() { if (atLength > 0) { System.arraycopy(S_at, 0, S_atPre, 0, BLOCK_SIZE); atLengthPre = atLength; } // Finish hash for partial AAD block if (atBlockPos > 0) { gHASHPartial(S_atPre, atBlock, 0, atBlockPos); atLengthPre += atBlockPos; } if (atLengthPre > 0) { System.arraycopy(S_atPre, 0, S, 0, BLOCK_SIZE); } } public int processByte(byte in, byte[] out, int outOff) throws DataLengthException { bufBlock[bufOff] = in; if (++bufOff == bufBlock.length) { outputBlock(out, outOff); return BLOCK_SIZE; } return 0; } public int processBytes(byte[] in, int inOff, int len, byte[] out, int outOff) throws DataLengthException { int resultLen = 0; for (int i = 0; i < len; ++i) { bufBlock[bufOff] = in[inOff + i]; if (++bufOff == bufBlock.length) { outputBlock(out, outOff + resultLen); resultLen += BLOCK_SIZE; } } return resultLen; } private void outputBlock(byte[] output, int offset) { if (totalLength == 0) { initCipher(); } gCTRBlock(bufBlock, output, offset); if (forEncryption) { bufOff = 0; } else { System.arraycopy(bufBlock, BLOCK_SIZE, bufBlock, 0, macSize); bufOff = macSize; } } public int doFinal(byte[] out, int outOff) throws IllegalStateException, InvalidCipherTextException { if (totalLength == 0) { initCipher(); } int extra = bufOff; if (!forEncryption) { if (extra < macSize) { throw new InvalidCipherTextException("data too short"); } extra -= macSize; } if (extra > 0) { gCTRPartial(bufBlock, 0, extra, out, outOff); } atLength += atBlockPos; if (atLength > atLengthPre) { /* * Some AAD was sent after the cipher started. We determine the difference b/w the hash value * we actually used when the cipher started (S_atPre) and the final hash value calculated (S_at). * Then we carry this difference forward by multiplying by H^c, where c is the number of (full or * partial) cipher-text blocks produced, and adjust the current hash. */ // Finish hash for partial AAD block if (atBlockPos > 0) { gHASHPartial(S_at, atBlock, 0, atBlockPos); } // Find the difference between the AAD hashes if (atLengthPre > 0) { xor(S_at, S_atPre); } // Number of cipher-text blocks produced long c = ((totalLength * 8) + 127) >>> 7; // Calculate the adjustment factor byte[] H_c = new byte[16]; if (exp == null) { exp = new Tables1kGCMExponentiator(); exp.init(H); } exp.exponentiateX(c, H_c); // Carry the difference forward multiply(S_at, H_c); // Adjust the current hash xor(S, S_at); } // Final gHASH byte[] X = new byte[BLOCK_SIZE]; Pack.longToBigEndian(atLength * 8, X, 0); Pack.longToBigEndian(totalLength * 8, X, 8); gHASHBlock(S, X); // TODO Fix this if tagLength becomes configurable // T = MSBt(GCTRk(J0,S)) byte[] tag = new byte[BLOCK_SIZE]; cipher.processBlock(J0, 0, tag, 0); xor(tag, S); int resultLen = extra; // We place into macBlock our calculated value for T this.macBlock = new byte[macSize]; System.arraycopy(tag, 0, macBlock, 0, macSize); if (forEncryption) { // Append T to the message System.arraycopy(macBlock, 0, out, outOff + bufOff, macSize); resultLen += macSize; } else { // Retrieve the T value from the message and compare to calculated one byte[] msgMac = new byte[macSize]; System.arraycopy(bufBlock, extra, msgMac, 0, macSize); if (!Arrays.constantTimeAreEqual(this.macBlock, msgMac)) { throw new InvalidCipherTextException("mac check in GCM failed"); } } reset(false); return resultLen; } public void reset() { reset(true); } private void reset( boolean clearMac) { cipher.reset(); S = new byte[BLOCK_SIZE]; S_at = new byte[BLOCK_SIZE]; S_atPre = new byte[BLOCK_SIZE]; atBlock = new byte[BLOCK_SIZE]; atBlockPos = 0; atLength = 0; atLengthPre = 0; counter = Arrays.clone(J0); bufOff = 0; totalLength = 0; if (bufBlock != null) { Arrays.fill(bufBlock, (byte)0); } if (clearMac) { macBlock = null; } if (initialAssociatedText != null) { processAADBytes(initialAssociatedText, 0, initialAssociatedText.length); } } private void gCTRBlock(byte[] block, byte[] out, int outOff) { byte[] tmp = getNextCounterBlock(); xor(tmp, block); System.arraycopy(tmp, 0, out, outOff, BLOCK_SIZE); gHASHBlock(S, forEncryption ? tmp : block); totalLength += BLOCK_SIZE; } private void gCTRPartial(byte[] buf, int off, int len, byte[] out, int outOff) { byte[] tmp = getNextCounterBlock(); xor(tmp, buf, off, len); System.arraycopy(tmp, 0, out, outOff, len); gHASHPartial(S, forEncryption ? tmp : buf, 0, len); totalLength += len; } private void gHASH(byte[] Y, byte[] b, int len) { for (int pos = 0; pos < len; pos += BLOCK_SIZE) { int num = Math.min(len - pos, BLOCK_SIZE); gHASHPartial(Y, b, pos, num); } } private void gHASHBlock(byte[] Y, byte[] b) { xor(Y, b); multiplier.multiplyH(Y); } private void gHASHPartial(byte[] Y, byte[] b, int off, int len) { xor(Y, b, off, len); multiplier.multiplyH(Y); } private byte[] getNextCounterBlock() { for (int i = 15; i >= 12; --i) { byte b = (byte)((counter[i] + 1) & 0xff); counter[i] = b; if (b != 0) { break; } } byte[] tmp = new byte[BLOCK_SIZE]; // TODO Sure would be nice if ciphers could operate on int[] cipher.processBlock(counter, 0, tmp, 0); return tmp; } private static void multiply(byte[] block, byte[] val) { byte[] tmp = Arrays.clone(block); byte[] c = new byte[16]; for (int i = 0; i < 16; ++i) { byte bits = val[i]; for (int j = 7; j >= 0; --j) { if ((bits & (1 << j)) != 0) { xor(c, tmp); } boolean lsb = (tmp[15] & 1) != 0; shiftRight(tmp); if (lsb) { // R = new byte[]{ 0xe1, ... }; // xor(v, R); tmp[0] ^= (byte)0xe1; } } } System.arraycopy(c, 0, block, 0, 16); } private static void shiftRight(byte[] block) { int i = 0; int bit = 0; for (;;) { int b = block[i] & 0xff; block[i] = (byte) ((b >>> 1) | bit); if (++i == 16) { break; } bit = (b & 1) << 7; } } private static void xor(byte[] block, byte[] val) { for (int i = 15; i >= 0; --i) { block[i] ^= val[i]; } } private static void xor(byte[] block, byte[] val, int off, int len) { while (len-- > 0) { block[len] ^= val[off + len]; } } } bouncycastle-1.49.orig/src/org/bouncycastle/crypto/modes/PaddedBlockCipher.java0000644000175000017500000001630410262753175027277 0ustar ebourgebourgpackage org.bouncycastle.crypto.modes; import org.bouncycastle.crypto.BlockCipher; import org.bouncycastle.crypto.BufferedBlockCipher; import org.bouncycastle.crypto.DataLengthException; import org.bouncycastle.crypto.InvalidCipherTextException; /** * A wrapper class that allows block ciphers to be used to process data in * a piecemeal fashion with PKCS5/PKCS7 padding. The PaddedBlockCipher * outputs a block only when the buffer is full and more data is being added, * or on a doFinal (unless the current block in the buffer is a pad block). * The padding mechanism used is the one outlined in PKCS5/PKCS7. * * @deprecated use org.bouncycastle.crypto.paddings.PaddedBufferedBlockCipher instead. */ public class PaddedBlockCipher extends BufferedBlockCipher { /** * Create a buffered block cipher with, or without, padding. * * @param cipher the underlying block cipher this buffering object wraps. */ public PaddedBlockCipher( BlockCipher cipher) { this.cipher = cipher; buf = new byte[cipher.getBlockSize()]; bufOff = 0; } /** * return the size of the output buffer required for an update plus a * doFinal with an input of len bytes. * * @param len the length of the input. * @return the space required to accommodate a call to update and doFinal * with len bytes of input. */ public int getOutputSize( int len) { int total = len + bufOff; int leftOver = total % buf.length; if (leftOver == 0) { if (forEncryption) { return total + buf.length; } return total; } return total - leftOver + buf.length; } /** * return the size of the output buffer required for an update * an input of len bytes. * * @param len the length of the input. * @return the space required to accommodate a call to update * with len bytes of input. */ public int getUpdateOutputSize( int len) { int total = len + bufOff; int leftOver = total % buf.length; if (leftOver == 0) { return total - buf.length; } return total - leftOver; } /** * process a single byte, producing an output block if neccessary. * * @param in the input byte. * @param out the space for any output that might be produced. * @param outOff the offset from which the output will be copied. * @exception DataLengthException if there isn't enough space in out. * @exception IllegalStateException if the cipher isn't initialised. */ public int processByte( byte in, byte[] out, int outOff) throws DataLengthException, IllegalStateException { int resultLen = 0; if (bufOff == buf.length) { resultLen = cipher.processBlock(buf, 0, out, outOff); bufOff = 0; } buf[bufOff++] = in; return resultLen; } /** * process an array of bytes, producing output if necessary. * * @param in the input byte array. * @param inOff the offset at which the input data starts. * @param len the number of bytes to be copied out of the input array. * @param out the space for any output that might be produced. * @param outOff the offset from which the output will be copied. * @exception DataLengthException if there isn't enough space in out. * @exception IllegalStateException if the cipher isn't initialised. */ public int processBytes( byte[] in, int inOff, int len, byte[] out, int outOff) throws DataLengthException, IllegalStateException { if (len < 0) { throw new IllegalArgumentException("Can't have a negative input length!"); } int blockSize = getBlockSize(); int length = getUpdateOutputSize(len); if (length > 0) { if ((outOff + length) > out.length) { throw new DataLengthException("output buffer too short"); } } int resultLen = 0; int gapLen = buf.length - bufOff; if (len > gapLen) { System.arraycopy(in, inOff, buf, bufOff, gapLen); resultLen += cipher.processBlock(buf, 0, out, outOff); bufOff = 0; len -= gapLen; inOff += gapLen; while (len > buf.length) { resultLen += cipher.processBlock(in, inOff, out, outOff + resultLen); len -= blockSize; inOff += blockSize; } } System.arraycopy(in, inOff, buf, bufOff, len); bufOff += len; return resultLen; } /** * Process the last block in the buffer. If the buffer is currently * full and padding needs to be added a call to doFinal will produce * 2 * getBlockSize() bytes. * * @param out the array the block currently being held is copied into. * @param outOff the offset at which the copying starts. * @exception DataLengthException if there is insufficient space in out for * the output or we are decrypting and the input is not block size aligned. * @exception IllegalStateException if the underlying cipher is not * initialised. * @exception InvalidCipherTextException if padding is expected and not found. */ public int doFinal( byte[] out, int outOff) throws DataLengthException, IllegalStateException, InvalidCipherTextException { int blockSize = cipher.getBlockSize(); int resultLen = 0; if (forEncryption) { if (bufOff == blockSize) { if ((outOff + 2 * blockSize) > out.length) { throw new DataLengthException("output buffer too short"); } resultLen = cipher.processBlock(buf, 0, out, outOff); bufOff = 0; } // // add PKCS7 padding // byte code = (byte)(blockSize - bufOff); while (bufOff < blockSize) { buf[bufOff] = code; bufOff++; } resultLen += cipher.processBlock(buf, 0, out, outOff + resultLen); } else { if (bufOff == blockSize) { resultLen = cipher.processBlock(buf, 0, buf, 0); bufOff = 0; } else { throw new DataLengthException("last block incomplete in decryption"); } // // remove PKCS7 padding // int count = buf[blockSize - 1] & 0xff; if ((count < 0) || (count > blockSize)) { throw new InvalidCipherTextException("pad block corrupted"); } resultLen -= count; System.arraycopy(buf, 0, out, outOff, resultLen); } reset(); return resultLen; } } bouncycastle-1.49.orig/src/org/bouncycastle/crypto/modes/SICBlockCipher.java0000644000175000017500000000560612070726306026532 0ustar ebourgebourgpackage org.bouncycastle.crypto.modes; import org.bouncycastle.crypto.BlockCipher; import org.bouncycastle.crypto.CipherParameters; import org.bouncycastle.crypto.DataLengthException; import org.bouncycastle.crypto.params.ParametersWithIV; /** * Implements the Segmented Integer Counter (SIC) mode on top of a simple * block cipher. This mode is also known as CTR mode. */ public class SICBlockCipher implements BlockCipher { private final BlockCipher cipher; private final int blockSize; private byte[] IV; private byte[] counter; private byte[] counterOut; /** * Basic constructor. * * @param c the block cipher to be used. */ public SICBlockCipher(BlockCipher c) { this.cipher = c; this.blockSize = cipher.getBlockSize(); this.IV = new byte[blockSize]; this.counter = new byte[blockSize]; this.counterOut = new byte[blockSize]; } /** * return the underlying block cipher that we are wrapping. * * @return the underlying block cipher that we are wrapping. */ public BlockCipher getUnderlyingCipher() { return cipher; } public void init( boolean forEncryption, //ignored by this CTR mode CipherParameters params) throws IllegalArgumentException { if (params instanceof ParametersWithIV) { ParametersWithIV ivParam = (ParametersWithIV)params; byte[] iv = ivParam.getIV(); System.arraycopy(iv, 0, IV, 0, IV.length); reset(); // if null it's an IV changed only. if (ivParam.getParameters() != null) { cipher.init(true, ivParam.getParameters()); } } else { throw new IllegalArgumentException("SIC mode requires ParametersWithIV"); } } public String getAlgorithmName() { return cipher.getAlgorithmName() + "/SIC"; } public int getBlockSize() { return cipher.getBlockSize(); } public int processBlock(byte[] in, int inOff, byte[] out, int outOff) throws DataLengthException, IllegalStateException { cipher.processBlock(counter, 0, counterOut, 0); // // XOR the counterOut with the plaintext producing the cipher text // for (int i = 0; i < counterOut.length; i++) { out[outOff + i] = (byte)(counterOut[i] ^ in[inOff + i]); } // increment counter by 1. for (int i = counter.length - 1; i >= 0 && ++counter[i] == 0; i--) { ; // do nothing - pre-increment and test for 0 in counter does the job. } return counter.length; } public void reset() { System.arraycopy(IV, 0, counter, 0, counter.length); cipher.reset(); } } bouncycastle-1.49.orig/src/org/bouncycastle/crypto/modes/CCMBlockCipher.java0000644000175000017500000002446212132367067026523 0ustar ebourgebourgpackage org.bouncycastle.crypto.modes; import java.io.ByteArrayOutputStream; import org.bouncycastle.crypto.BlockCipher; import org.bouncycastle.crypto.CipherParameters; import org.bouncycastle.crypto.DataLengthException; import org.bouncycastle.crypto.InvalidCipherTextException; import org.bouncycastle.crypto.Mac; import org.bouncycastle.crypto.macs.CBCBlockCipherMac; import org.bouncycastle.crypto.params.AEADParameters; import org.bouncycastle.crypto.params.ParametersWithIV; import org.bouncycastle.util.Arrays; /** * Implements the Counter with Cipher Block Chaining mode (CCM) detailed in * NIST Special Publication 800-38C. *

    * Note: this mode is a packet mode - it needs all the data up front. */ public class CCMBlockCipher implements AEADBlockCipher { private BlockCipher cipher; private int blockSize; private boolean forEncryption; private byte[] nonce; private byte[] initialAssociatedText; private int macSize; private CipherParameters keyParam; private byte[] macBlock; private ByteArrayOutputStream associatedText = new ByteArrayOutputStream(); private ByteArrayOutputStream data = new ByteArrayOutputStream(); /** * Basic constructor. * * @param c the block cipher to be used. */ public CCMBlockCipher(BlockCipher c) { this.cipher = c; this.blockSize = c.getBlockSize(); this.macBlock = new byte[blockSize]; if (blockSize != 16) { throw new IllegalArgumentException("cipher required with a block size of 16."); } } /** * return the underlying block cipher that we are wrapping. * * @return the underlying block cipher that we are wrapping. */ public BlockCipher getUnderlyingCipher() { return cipher; } public void init(boolean forEncryption, CipherParameters params) throws IllegalArgumentException { this.forEncryption = forEncryption; if (params instanceof AEADParameters) { AEADParameters param = (AEADParameters)params; nonce = param.getNonce(); initialAssociatedText = param.getAssociatedText(); macSize = param.getMacSize() / 8; keyParam = param.getKey(); } else if (params instanceof ParametersWithIV) { ParametersWithIV param = (ParametersWithIV)params; nonce = param.getIV(); initialAssociatedText = null; macSize = macBlock.length / 2; keyParam = param.getParameters(); } else { throw new IllegalArgumentException("invalid parameters passed to CCM"); } if (nonce == null || nonce.length < 7 || nonce.length > 13) { throw new IllegalArgumentException("nonce must have length from 7 to 13 octets"); } } public String getAlgorithmName() { return cipher.getAlgorithmName() + "/CCM"; } public void processAADByte(byte in) { associatedText.write(in); } public void processAADBytes(byte[] in, int inOff, int len) { // TODO: Process AAD online associatedText.write(in, inOff, len); } public int processByte(byte in, byte[] out, int outOff) throws DataLengthException, IllegalStateException { data.write(in); return 0; } public int processBytes(byte[] in, int inOff, int inLen, byte[] out, int outOff) throws DataLengthException, IllegalStateException { data.write(in, inOff, inLen); return 0; } public int doFinal(byte[] out, int outOff) throws IllegalStateException, InvalidCipherTextException { byte[] text = data.toByteArray(); byte[] enc = processPacket(text, 0, text.length); System.arraycopy(enc, 0, out, outOff, enc.length); reset(); return enc.length; } public void reset() { cipher.reset(); associatedText.reset(); data.reset(); } /** * Returns a byte array containing the mac calculated as part of the * last encrypt or decrypt operation. * * @return the last mac calculated. */ public byte[] getMac() { byte[] mac = new byte[macSize]; System.arraycopy(macBlock, 0, mac, 0, mac.length); return mac; } public int getUpdateOutputSize(int len) { return 0; } public int getOutputSize(int len) { int totalData = len + data.size(); if (forEncryption) { return totalData + macSize; } return totalData < macSize ? 0 : totalData - macSize; } public byte[] processPacket(byte[] in, int inOff, int inLen) throws IllegalStateException, InvalidCipherTextException { // TODO: handle null keyParam (e.g. via RepeatedKeySpec) // Need to keep the CTR and CBC Mac parts around and reset if (keyParam == null) { throw new IllegalStateException("CCM cipher unitialized."); } int n = nonce.length; int q = 15 - n; if (q < 4) { int limitLen = 1 << (8 * q); if (inLen >= limitLen) { throw new IllegalStateException("CCM packet too large for choice of q."); } } byte[] iv = new byte[blockSize]; iv[0] = (byte)((q - 1) & 0x7); System.arraycopy(nonce, 0, iv, 1, nonce.length); BlockCipher ctrCipher = new SICBlockCipher(cipher); ctrCipher.init(forEncryption, new ParametersWithIV(keyParam, iv)); int index = inOff; int outOff = 0; byte[] output; if (forEncryption) { output = new byte[inLen + macSize]; calculateMac(in, inOff, inLen, macBlock); ctrCipher.processBlock(macBlock, 0, macBlock, 0); // S0 while (index < inLen - blockSize) // S1... { ctrCipher.processBlock(in, index, output, outOff); outOff += blockSize; index += blockSize; } byte[] block = new byte[blockSize]; System.arraycopy(in, index, block, 0, inLen - index); ctrCipher.processBlock(block, 0, block, 0); System.arraycopy(block, 0, output, outOff, inLen - index); outOff += inLen - index; System.arraycopy(macBlock, 0, output, outOff, output.length - outOff); } else { output = new byte[inLen - macSize]; System.arraycopy(in, inOff + inLen - macSize, macBlock, 0, macSize); ctrCipher.processBlock(macBlock, 0, macBlock, 0); for (int i = macSize; i != macBlock.length; i++) { macBlock[i] = 0; } while (outOff < output.length - blockSize) { ctrCipher.processBlock(in, index, output, outOff); outOff += blockSize; index += blockSize; } byte[] block = new byte[blockSize]; System.arraycopy(in, index, block, 0, output.length - outOff); ctrCipher.processBlock(block, 0, block, 0); System.arraycopy(block, 0, output, outOff, output.length - outOff); byte[] calculatedMacBlock = new byte[blockSize]; calculateMac(output, 0, output.length, calculatedMacBlock); if (!Arrays.constantTimeAreEqual(macBlock, calculatedMacBlock)) { throw new InvalidCipherTextException("mac check in CCM failed"); } } return output; } private int calculateMac(byte[] data, int dataOff, int dataLen, byte[] macBlock) { Mac cMac = new CBCBlockCipherMac(cipher, macSize * 8); cMac.init(keyParam); // // build b0 // byte[] b0 = new byte[16]; if (hasAssociatedText()) { b0[0] |= 0x40; } b0[0] |= (((cMac.getMacSize() - 2) / 2) & 0x7) << 3; b0[0] |= ((15 - nonce.length) - 1) & 0x7; System.arraycopy(nonce, 0, b0, 1, nonce.length); int q = dataLen; int count = 1; while (q > 0) { b0[b0.length - count] = (byte)(q & 0xff); q >>>= 8; count++; } cMac.update(b0, 0, b0.length); // // process associated text // if (hasAssociatedText()) { int extra; int textLength = getAssociatedTextLength(); if (textLength < ((1 << 16) - (1 << 8))) { cMac.update((byte)(textLength >> 8)); cMac.update((byte)textLength); extra = 2; } else // can't go any higher than 2^32 { cMac.update((byte)0xff); cMac.update((byte)0xfe); cMac.update((byte)(textLength >> 24)); cMac.update((byte)(textLength >> 16)); cMac.update((byte)(textLength >> 8)); cMac.update((byte)textLength); extra = 6; } if (initialAssociatedText != null) { cMac.update(initialAssociatedText, 0, initialAssociatedText.length); } if (associatedText.size() > 0) { byte[] tmp = associatedText.toByteArray(); cMac.update(tmp, 0, tmp.length); } extra = (extra + textLength) % 16; if (extra != 0) { for (int i = extra; i != 16; i++) { cMac.update((byte)0x00); } } } // // add the text // cMac.update(data, dataOff, dataLen); return cMac.doFinal(macBlock, 0); } private int getAssociatedTextLength() { return associatedText.size() + ((initialAssociatedText == null) ? 0 : initialAssociatedText.length); } private boolean hasAssociatedText() { return getAssociatedTextLength() > 0; } } bouncycastle-1.49.orig/src/org/bouncycastle/crypto/modes/CTSBlockCipher.java0000644000175000017500000001730310262753175026547 0ustar ebourgebourgpackage org.bouncycastle.crypto.modes; import org.bouncycastle.crypto.BlockCipher; import org.bouncycastle.crypto.BufferedBlockCipher; import org.bouncycastle.crypto.DataLengthException; import org.bouncycastle.crypto.InvalidCipherTextException; /** * A Cipher Text Stealing (CTS) mode cipher. CTS allows block ciphers to * be used to produce cipher text which is the same length as the plain text. */ public class CTSBlockCipher extends BufferedBlockCipher { private int blockSize; /** * Create a buffered block cipher that uses Cipher Text Stealing * * @param cipher the underlying block cipher this buffering object wraps. */ public CTSBlockCipher( BlockCipher cipher) { if ((cipher instanceof OFBBlockCipher) || (cipher instanceof CFBBlockCipher)) { throw new IllegalArgumentException("CTSBlockCipher can only accept ECB, or CBC ciphers"); } this.cipher = cipher; blockSize = cipher.getBlockSize(); buf = new byte[blockSize * 2]; bufOff = 0; } /** * return the size of the output buffer required for an update * an input of len bytes. * * @param len the length of the input. * @return the space required to accommodate a call to update * with len bytes of input. */ public int getUpdateOutputSize( int len) { int total = len + bufOff; int leftOver = total % buf.length; if (leftOver == 0) { return total - buf.length; } return total - leftOver; } /** * return the size of the output buffer required for an update plus a * doFinal with an input of len bytes. * * @param len the length of the input. * @return the space required to accommodate a call to update and doFinal * with len bytes of input. */ public int getOutputSize( int len) { return len + bufOff; } /** * process a single byte, producing an output block if neccessary. * * @param in the input byte. * @param out the space for any output that might be produced. * @param outOff the offset from which the output will be copied. * @return the number of output bytes copied to out. * @exception DataLengthException if there isn't enough space in out. * @exception IllegalStateException if the cipher isn't initialised. */ public int processByte( byte in, byte[] out, int outOff) throws DataLengthException, IllegalStateException { int resultLen = 0; if (bufOff == buf.length) { resultLen = cipher.processBlock(buf, 0, out, outOff); System.arraycopy(buf, blockSize, buf, 0, blockSize); bufOff = blockSize; } buf[bufOff++] = in; return resultLen; } /** * process an array of bytes, producing output if necessary. * * @param in the input byte array. * @param inOff the offset at which the input data starts. * @param len the number of bytes to be copied out of the input array. * @param out the space for any output that might be produced. * @param outOff the offset from which the output will be copied. * @return the number of output bytes copied to out. * @exception DataLengthException if there isn't enough space in out. * @exception IllegalStateException if the cipher isn't initialised. */ public int processBytes( byte[] in, int inOff, int len, byte[] out, int outOff) throws DataLengthException, IllegalStateException { if (len < 0) { throw new IllegalArgumentException("Can't have a negative input length!"); } int blockSize = getBlockSize(); int length = getUpdateOutputSize(len); if (length > 0) { if ((outOff + length) > out.length) { throw new DataLengthException("output buffer too short"); } } int resultLen = 0; int gapLen = buf.length - bufOff; if (len > gapLen) { System.arraycopy(in, inOff, buf, bufOff, gapLen); resultLen += cipher.processBlock(buf, 0, out, outOff); System.arraycopy(buf, blockSize, buf, 0, blockSize); bufOff = blockSize; len -= gapLen; inOff += gapLen; while (len > blockSize) { System.arraycopy(in, inOff, buf, bufOff, blockSize); resultLen += cipher.processBlock(buf, 0, out, outOff + resultLen); System.arraycopy(buf, blockSize, buf, 0, blockSize); len -= blockSize; inOff += blockSize; } } System.arraycopy(in, inOff, buf, bufOff, len); bufOff += len; return resultLen; } /** * Process the last block in the buffer. * * @param out the array the block currently being held is copied into. * @param outOff the offset at which the copying starts. * @return the number of output bytes copied to out. * @exception DataLengthException if there is insufficient space in out for * the output. * @exception IllegalStateException if the underlying cipher is not * initialised. * @exception InvalidCipherTextException if cipher text decrypts wrongly (in * case the exception will never get thrown). */ public int doFinal( byte[] out, int outOff) throws DataLengthException, IllegalStateException, InvalidCipherTextException { if (bufOff + outOff > out.length) { throw new DataLengthException("output buffer to small in doFinal"); } int blockSize = cipher.getBlockSize(); int len = bufOff - blockSize; byte[] block = new byte[blockSize]; if (forEncryption) { cipher.processBlock(buf, 0, block, 0); if (bufOff < blockSize) { throw new DataLengthException("need at least one block of input for CTS"); } for (int i = bufOff; i != buf.length; i++) { buf[i] = block[i - blockSize]; } for (int i = blockSize; i != bufOff; i++) { buf[i] ^= block[i - blockSize]; } if (cipher instanceof CBCBlockCipher) { BlockCipher c = ((CBCBlockCipher)cipher).getUnderlyingCipher(); c.processBlock(buf, blockSize, out, outOff); } else { cipher.processBlock(buf, blockSize, out, outOff); } System.arraycopy(block, 0, out, outOff + blockSize, len); } else { byte[] lastBlock = new byte[blockSize]; if (cipher instanceof CBCBlockCipher) { BlockCipher c = ((CBCBlockCipher)cipher).getUnderlyingCipher(); c.processBlock(buf, 0, block, 0); } else { cipher.processBlock(buf, 0, block, 0); } for (int i = blockSize; i != bufOff; i++) { lastBlock[i - blockSize] = (byte)(block[i - blockSize] ^ buf[i]); } System.arraycopy(buf, blockSize, block, 0, len); cipher.processBlock(block, 0, out, outOff); System.arraycopy(lastBlock, 0, out, outOff + blockSize, len); } int offset = bufOff; reset(); return offset; } } bouncycastle-1.49.orig/src/org/bouncycastle/crypto/modes/OpenPGPCFBBlockCipher.java0000644000175000017500000002224411035014236027664 0ustar ebourgebourgpackage org.bouncycastle.crypto.modes; import org.bouncycastle.crypto.BlockCipher; import org.bouncycastle.crypto.CipherParameters; import org.bouncycastle.crypto.DataLengthException; /** * Implements OpenPGP's rather strange version of Cipher-FeedBack (CFB) mode * on top of a simple cipher. This class assumes the IV has been prepended * to the data stream already, and just accomodates the reset after * (blockSize + 2) bytes have been read. *

    * For further info see RFC 2440. */ public class OpenPGPCFBBlockCipher implements BlockCipher { private byte[] IV; private byte[] FR; private byte[] FRE; private BlockCipher cipher; private int count; private int blockSize; private boolean forEncryption; /** * Basic constructor. * * @param cipher the block cipher to be used as the basis of the * feedback mode. */ public OpenPGPCFBBlockCipher( BlockCipher cipher) { this.cipher = cipher; this.blockSize = cipher.getBlockSize(); this.IV = new byte[blockSize]; this.FR = new byte[blockSize]; this.FRE = new byte[blockSize]; } /** * return the underlying block cipher that we are wrapping. * * @return the underlying block cipher that we are wrapping. */ public BlockCipher getUnderlyingCipher() { return cipher; } /** * return the algorithm name and mode. * * @return the name of the underlying algorithm followed by "/PGPCFB" * and the block size in bits. */ public String getAlgorithmName() { return cipher.getAlgorithmName() + "/OpenPGPCFB"; } /** * return the block size we are operating at. * * @return the block size we are operating at (in bytes). */ public int getBlockSize() { return cipher.getBlockSize(); } /** * Process one block of input from the array in and write it to * the out array. * * @param in the array containing the input data. * @param inOff offset into the in array the data starts at. * @param out the array the output data will be copied into. * @param outOff the offset into the out array the output will start at. * @exception DataLengthException if there isn't enough data in in, or * space in out. * @exception IllegalStateException if the cipher isn't initialised. * @return the number of bytes processed and produced. */ public int processBlock( byte[] in, int inOff, byte[] out, int outOff) throws DataLengthException, IllegalStateException { return (forEncryption) ? encryptBlock(in, inOff, out, outOff) : decryptBlock(in, inOff, out, outOff); } /** * reset the chaining vector back to the IV and reset the underlying * cipher. */ public void reset() { count = 0; System.arraycopy(IV, 0, FR, 0, FR.length); cipher.reset(); } /** * Initialise the cipher and, possibly, the initialisation vector (IV). * If an IV isn't passed as part of the parameter, the IV will be all zeros. * An IV which is too short is handled in FIPS compliant fashion. * * @param forEncryption if true the cipher is initialised for * encryption, if false for decryption. * @param params the key and other data required by the cipher. * @exception IllegalArgumentException if the params argument is * inappropriate. */ public void init( boolean forEncryption, CipherParameters params) throws IllegalArgumentException { this.forEncryption = forEncryption; reset(); cipher.init(true, params); } /** * Encrypt one byte of data according to CFB mode. * @param data the byte to encrypt * @param blockOff offset in the current block * @return the encrypted byte */ private byte encryptByte(byte data, int blockOff) { return (byte)(FRE[blockOff] ^ data); } /** * Do the appropriate processing for CFB IV mode encryption. * * @param in the array containing the data to be encrypted. * @param inOff offset into the in array the data starts at. * @param out the array the encrypted data will be copied into. * @param outOff the offset into the out array the output will start at. * @exception DataLengthException if there isn't enough data in in, or * space in out. * @exception IllegalStateException if the cipher isn't initialised. * @return the number of bytes processed and produced. */ private int encryptBlock( byte[] in, int inOff, byte[] out, int outOff) throws DataLengthException, IllegalStateException { if ((inOff + blockSize) > in.length) { throw new DataLengthException("input buffer too short"); } if ((outOff + blockSize) > out.length) { throw new DataLengthException("output buffer too short"); } if (count > blockSize) { FR[blockSize - 2] = out[outOff] = encryptByte(in[inOff], blockSize - 2); FR[blockSize - 1] = out[outOff + 1] = encryptByte(in[inOff + 1], blockSize - 1); cipher.processBlock(FR, 0, FRE, 0); for (int n = 2; n < blockSize; n++) { FR[n - 2] = out[outOff + n] = encryptByte(in[inOff + n], n - 2); } } else if (count == 0) { cipher.processBlock(FR, 0, FRE, 0); for (int n = 0; n < blockSize; n++) { FR[n] = out[outOff + n] = encryptByte(in[inOff + n], n); } count += blockSize; } else if (count == blockSize) { cipher.processBlock(FR, 0, FRE, 0); out[outOff] = encryptByte(in[inOff], 0); out[outOff + 1] = encryptByte(in[inOff + 1], 1); // // do reset // System.arraycopy(FR, 2, FR, 0, blockSize - 2); System.arraycopy(out, outOff, FR, blockSize - 2, 2); cipher.processBlock(FR, 0, FRE, 0); for (int n = 2; n < blockSize; n++) { FR[n - 2] = out[outOff + n] = encryptByte(in[inOff + n], n - 2); } count += blockSize; } return blockSize; } /** * Do the appropriate processing for CFB IV mode decryption. * * @param in the array containing the data to be decrypted. * @param inOff offset into the in array the data starts at. * @param out the array the encrypted data will be copied into. * @param outOff the offset into the out array the output will start at. * @exception DataLengthException if there isn't enough data in in, or * space in out. * @exception IllegalStateException if the cipher isn't initialised. * @return the number of bytes processed and produced. */ private int decryptBlock( byte[] in, int inOff, byte[] out, int outOff) throws DataLengthException, IllegalStateException { if ((inOff + blockSize) > in.length) { throw new DataLengthException("input buffer too short"); } if ((outOff + blockSize) > out.length) { throw new DataLengthException("output buffer too short"); } if (count > blockSize) { byte inVal = in[inOff]; FR[blockSize - 2] = inVal; out[outOff] = encryptByte(inVal, blockSize - 2); inVal = in[inOff + 1]; FR[blockSize - 1] = inVal; out[outOff + 1] = encryptByte(inVal, blockSize - 1); cipher.processBlock(FR, 0, FRE, 0); for (int n = 2; n < blockSize; n++) { inVal = in[inOff + n]; FR[n - 2] = inVal; out[outOff + n] = encryptByte(inVal, n - 2); } } else if (count == 0) { cipher.processBlock(FR, 0, FRE, 0); for (int n = 0; n < blockSize; n++) { FR[n] = in[inOff + n]; out[n] = encryptByte(in[inOff + n], n); } count += blockSize; } else if (count == blockSize) { cipher.processBlock(FR, 0, FRE, 0); byte inVal1 = in[inOff]; byte inVal2 = in[inOff + 1]; out[outOff ] = encryptByte(inVal1, 0); out[outOff + 1] = encryptByte(inVal2, 1); System.arraycopy(FR, 2, FR, 0, blockSize - 2); FR[blockSize - 2] = inVal1; FR[blockSize - 1] = inVal2; cipher.processBlock(FR, 0, FRE, 0); for (int n = 2; n < blockSize; n++) { byte inVal = in[inOff + n]; FR[n - 2] = inVal; out[outOff + n] = encryptByte(inVal, n - 2); } count += blockSize; } return blockSize; } } bouncycastle-1.49.orig/src/org/bouncycastle/crypto/modes/gcm/0000755000175000017500000000000012152033551023674 5ustar ebourgebourgbouncycastle-1.49.orig/src/org/bouncycastle/crypto/modes/gcm/GCMMultiplier.java0000644000175000017500000000020611251463063027216 0ustar ebourgebourgpackage org.bouncycastle.crypto.modes.gcm; public interface GCMMultiplier { void init(byte[] H); void multiplyH(byte[] x); } bouncycastle-1.49.orig/src/org/bouncycastle/crypto/modes/gcm/Tables8kGCMMultiplier.java0000644000175000017500000000402512052667021030617 0ustar ebourgebourgpackage org.bouncycastle.crypto.modes.gcm; import org.bouncycastle.crypto.util.Pack; import org.bouncycastle.util.Arrays; public class Tables8kGCMMultiplier implements GCMMultiplier { private byte[] H; private int[][][] M; public void init(byte[] H) { if (M == null) { M = new int[32][16][4]; } else if (Arrays.areEqual(this.H, H)) { return; } this.H = Arrays.clone(H); // M[0][0] is ZEROES; // M[1][0] is ZEROES; GCMUtil.asInts(H, M[1][8]); for (int j = 4; j >= 1; j >>= 1) { GCMUtil.multiplyP(M[1][j + j], M[1][j]); } GCMUtil.multiplyP(M[1][1], M[0][8]); for (int j = 4; j >= 1; j >>= 1) { GCMUtil.multiplyP(M[0][j + j], M[0][j]); } int i = 0; for (;;) { for (int j = 2; j < 16; j += j) { for (int k = 1; k < j; ++k) { GCMUtil.xor(M[i][j], M[i][k], M[i][j + k]); } } if (++i == 32) { return; } if (i > 1) { // M[i][0] is ZEROES; for(int j = 8; j > 0; j >>= 1) { GCMUtil.multiplyP8(M[i - 2][j], M[i][j]); } } } } public void multiplyH(byte[] x) { // assert x.Length == 16; int[] z = new int[4]; for (int i = 15; i >= 0; --i) { // GCMUtil.xor(z, M[i + i][x[i] & 0x0f]); int[] m = M[i + i][x[i] & 0x0f]; z[0] ^= m[0]; z[1] ^= m[1]; z[2] ^= m[2]; z[3] ^= m[3]; // GCMUtil.xor(z, M[i + i + 1][(x[i] & 0xf0) >>> 4]); m = M[i + i + 1][(x[i] & 0xf0) >>> 4]; z[0] ^= m[0]; z[1] ^= m[1]; z[2] ^= m[2]; z[3] ^= m[3]; } Pack.intToBigEndian(z, x, 0); } }bouncycastle-1.49.orig/src/org/bouncycastle/crypto/modes/gcm/GCMUtil.java0000644000175000017500000001263212052667021026013 0ustar ebourgebourgpackage org.bouncycastle.crypto.modes.gcm; import org.bouncycastle.crypto.util.Pack; import org.bouncycastle.util.Arrays; abstract class GCMUtil { static byte[] oneAsBytes() { byte[] tmp = new byte[16]; tmp[0] = (byte)0x80; return tmp; } static int[] oneAsInts() { int[] tmp = new int[4]; tmp[0] = 0x80000000; return tmp; } static byte[] asBytes(int[] ns) { byte[] output = new byte[16]; Pack.intToBigEndian(ns, output, 0); return output; } static int[] asInts(byte[] bs) { int[] output = new int[4]; Pack.bigEndianToInt(bs, 0, output); return output; } static void asInts(byte[] bs, int[] output) { Pack.bigEndianToInt(bs, 0, output); } static void multiply(byte[] block, byte[] val) { byte[] tmp = Arrays.clone(block); byte[] c = new byte[16]; for (int i = 0; i < 16; ++i) { byte bits = val[i]; for (int j = 7; j >= 0; --j) { if ((bits & (1 << j)) != 0) { xor(c, tmp); } boolean lsb = (tmp[15] & 1) != 0; shiftRight(tmp); if (lsb) { // R = new byte[]{ 0xe1, ... }; // GCMUtil.xor(v, R); tmp[0] ^= (byte)0xe1; } } } System.arraycopy(c, 0, block, 0, 16); } // P is the value with only bit i=1 set static void multiplyP(int[] x) { boolean lsb = (x[3] & 1) != 0; shiftRight(x); if (lsb) { // R = new int[]{ 0xe1000000, 0, 0, 0 }; // xor(v, R); x[0] ^= 0xe1000000; } } static void multiplyP(int[] x, int[] output) { boolean lsb = (x[3] & 1) != 0; shiftRight(x, output); if (lsb) { output[0] ^= 0xe1000000; } } // P is the value with only bit i=1 set static void multiplyP8(int[] x) { // for (int i = 8; i != 0; --i) // { // multiplyP(x); // } int lsw = x[3]; shiftRightN(x, 8); for (int i = 7; i >= 0; --i) { if ((lsw & (1 << i)) != 0) { x[0] ^= (0xe1000000 >>> (7 - i)); } } } static void multiplyP8(int[] x, int[] output) { int lsw = x[3]; shiftRightN(x, 8, output); for (int i = 7; i >= 0; --i) { if ((lsw & (1 << i)) != 0) { output[0] ^= (0xe1000000 >>> (7 - i)); } } } static void shiftRight(byte[] block) { int i = 0; int bit = 0; for (;;) { int b = block[i] & 0xff; block[i] = (byte) ((b >>> 1) | bit); if (++i == 16) { break; } bit = (b & 1) << 7; } } static void shiftRight(byte[] block, byte[] output) { int i = 0; int bit = 0; for (;;) { int b = block[i] & 0xff; output[i] = (byte) ((b >>> 1) | bit); if (++i == 16) { break; } bit = (b & 1) << 7; } } static void shiftRight(int[] block) { int i = 0; int bit = 0; for (;;) { int b = block[i]; block[i] = (b >>> 1) | bit; if (++i == 4) { break; } bit = b << 31; } } static void shiftRight(int[] block, int[] output) { int i = 0; int bit = 0; for (;;) { int b = block[i]; output[i] = (b >>> 1) | bit; if (++i == 4) { break; } bit = b << 31; } } static void shiftRightN(int[] block, int n) { int i = 0; int bits = 0; for (;;) { int b = block[i]; block[i] = (b >>> n) | bits; if (++i == 4) { break; } bits = b << (32 - n); } } static void shiftRightN(int[] block, int n, int[] output) { int i = 0; int bits = 0; for (;;) { int b = block[i]; output[i] = (b >>> n) | bits; if (++i == 4) { break; } bits = b << (32 - n); } } static void xor(byte[] block, byte[] val) { for (int i = 15; i >= 0; --i) { block[i] ^= val[i]; } } static void xor(byte[] block, byte[] val, int off, int len) { while (len-- > 0) { block[len] ^= val[off + len]; } } static void xor(byte[] block, byte[] val, byte[] output) { for (int i = 15; i >= 0; --i) { output[i] = (byte)(block[i] ^ val[i]); } } static void xor(int[] block, int[] val) { for (int i = 3; i >= 0; --i) { block[i] ^= val[i]; } } static void xor(int[] block, int[] val, int[] output) { for (int i = 3; i >= 0; --i) { output[i] = block[i] ^ val[i]; } } } bouncycastle-1.49.orig/src/org/bouncycastle/crypto/modes/gcm/Tables1kGCMExponentiator.java0000644000175000017500000000260612104605503031317 0ustar ebourgebourgpackage org.bouncycastle.crypto.modes.gcm; import java.util.Vector; import org.bouncycastle.util.Arrays; public class Tables1kGCMExponentiator implements GCMExponentiator { // A lookup table of the power-of-two powers of 'x' // - lookupPowX2[i] = x^(2^i) private Vector lookupPowX2; public void init(byte[] x) { if (lookupPowX2 != null && Arrays.areEqual(x, (byte[])lookupPowX2.elementAt(0))) { return; } lookupPowX2 = new Vector(8); lookupPowX2.addElement(Arrays.clone(x)); } public void exponentiateX(long pow, byte[] output) { byte[] y = GCMUtil.oneAsBytes(); int bit = 0; while (pow > 0) { if ((pow & 1L) != 0) { ensureAvailable(bit); GCMUtil.multiply(y, (byte[])lookupPowX2.elementAt(bit)); } ++bit; pow >>>= 1; } System.arraycopy(y, 0, output, 0, 16); } private void ensureAvailable(int bit) { int count = lookupPowX2.size(); if (count <= bit) { byte[] tmp = (byte[])lookupPowX2.elementAt(count - 1); do { tmp = Arrays.clone(tmp); GCMUtil.multiply(tmp, tmp); lookupPowX2.addElement(tmp); } while (++count <= bit); } } } bouncycastle-1.49.orig/src/org/bouncycastle/crypto/modes/gcm/BasicGCMExponentiator.java0000644000175000017500000000144111346064501030672 0ustar ebourgebourgpackage org.bouncycastle.crypto.modes.gcm; import org.bouncycastle.util.Arrays; public class BasicGCMExponentiator implements GCMExponentiator { private byte[] x; public void init(byte[] x) { this.x = Arrays.clone(x); } public void exponentiateX(long pow, byte[] output) { // Initial value is little-endian 1 byte[] y = GCMUtil.oneAsBytes(); if (pow > 0) { byte[] powX = Arrays.clone(x); do { if ((pow & 1L) != 0) { GCMUtil.multiply(y, powX); } GCMUtil.multiply(powX, powX); pow >>>= 1; } while (pow > 0); } System.arraycopy(y, 0, output, 0, 16); } } bouncycastle-1.49.orig/src/org/bouncycastle/crypto/modes/gcm/Tables64kGCMMultiplier.java0000644000175000017500000000306412052667021030703 0ustar ebourgebourgpackage org.bouncycastle.crypto.modes.gcm; import org.bouncycastle.crypto.util.Pack; import org.bouncycastle.util.Arrays; public class Tables64kGCMMultiplier implements GCMMultiplier { private byte[] H; private int[][][] M; public void init(byte[] H) { if (M == null) { M = new int[16][256][4]; } else if (Arrays.areEqual(this.H, H)) { return; } this.H = Arrays.clone(H); // M[0][0] is ZEROES; GCMUtil.asInts(H, M[0][128]); for (int j = 64; j >= 1; j >>= 1) { GCMUtil.multiplyP(M[0][j + j], M[0][j]); } int i = 0; for (;;) { for (int j = 2; j < 256; j += j) { for (int k = 1; k < j; ++k) { GCMUtil.xor(M[i][j], M[i][k], M[i][j + k]); } } if (++i == 16) { return; } // M[i][0] is ZEROES; for (int j = 128; j > 0; j >>= 1) { GCMUtil.multiplyP8(M[i - 1][j], M[i][j]); } } } public void multiplyH(byte[] x) { // assert x.Length == 16; int[] z = new int[4]; for (int i = 15; i >= 0; --i) { // GCMUtil.xor(z, M[i][x[i] & 0xff]); int[] m = M[i][x[i] & 0xff]; z[0] ^= m[0]; z[1] ^= m[1]; z[2] ^= m[2]; z[3] ^= m[3]; } Pack.intToBigEndian(z, x, 0); } } bouncycastle-1.49.orig/src/org/bouncycastle/crypto/modes/gcm/GCMExponentiator.java0000644000175000017500000000023411345733735027742 0ustar ebourgebourgpackage org.bouncycastle.crypto.modes.gcm; public interface GCMExponentiator { void init(byte[] x); void exponentiateX(long pow, byte[] output); } bouncycastle-1.49.orig/src/org/bouncycastle/crypto/modes/gcm/BasicGCMMultiplier.java0000644000175000017500000000050411346422651030164 0ustar ebourgebourgpackage org.bouncycastle.crypto.modes.gcm; import org.bouncycastle.util.Arrays; public class BasicGCMMultiplier implements GCMMultiplier { private byte[] H; public void init(byte[] H) { this.H = Arrays.clone(H); } public void multiplyH(byte[] x) { GCMUtil.multiply(x, H); } } bouncycastle-1.49.orig/src/org/bouncycastle/crypto/modes/CBCBlockCipher.java0000644000175000017500000001660712052667021026504 0ustar ebourgebourgpackage org.bouncycastle.crypto.modes; import org.bouncycastle.crypto.BlockCipher; import org.bouncycastle.crypto.CipherParameters; import org.bouncycastle.crypto.DataLengthException; import org.bouncycastle.crypto.params.ParametersWithIV; import org.bouncycastle.util.Arrays; /** * implements Cipher-Block-Chaining (CBC) mode on top of a simple cipher. */ public class CBCBlockCipher implements BlockCipher { private byte[] IV; private byte[] cbcV; private byte[] cbcNextV; private int blockSize; private BlockCipher cipher = null; private boolean encrypting; /** * Basic constructor. * * @param cipher the block cipher to be used as the basis of chaining. */ public CBCBlockCipher( BlockCipher cipher) { this.cipher = cipher; this.blockSize = cipher.getBlockSize(); this.IV = new byte[blockSize]; this.cbcV = new byte[blockSize]; this.cbcNextV = new byte[blockSize]; } /** * return the underlying block cipher that we are wrapping. * * @return the underlying block cipher that we are wrapping. */ public BlockCipher getUnderlyingCipher() { return cipher; } /** * Initialise the cipher and, possibly, the initialisation vector (IV). * If an IV isn't passed as part of the parameter, the IV will be all zeros. * * @param encrypting if true the cipher is initialised for * encryption, if false for decryption. * @param params the key and other data required by the cipher. * @exception IllegalArgumentException if the params argument is * inappropriate. */ public void init( boolean encrypting, CipherParameters params) throws IllegalArgumentException { boolean oldEncrypting = this.encrypting; this.encrypting = encrypting; if (params instanceof ParametersWithIV) { ParametersWithIV ivParam = (ParametersWithIV)params; byte[] iv = ivParam.getIV(); if (iv.length != blockSize) { throw new IllegalArgumentException("initialisation vector must be the same length as block size"); } System.arraycopy(iv, 0, IV, 0, iv.length); reset(); // if null it's an IV changed only. if (ivParam.getParameters() != null) { cipher.init(encrypting, ivParam.getParameters()); } else if (oldEncrypting != encrypting) { throw new IllegalArgumentException("cannot change encrypting state without providing key."); } } else { reset(); // if it's null, key is to be reused. if (params != null) { cipher.init(encrypting, params); } else if (oldEncrypting != encrypting) { throw new IllegalArgumentException("cannot change encrypting state without providing key."); } } } /** * return the algorithm name and mode. * * @return the name of the underlying algorithm followed by "/CBC". */ public String getAlgorithmName() { return cipher.getAlgorithmName() + "/CBC"; } /** * return the block size of the underlying cipher. * * @return the block size of the underlying cipher. */ public int getBlockSize() { return cipher.getBlockSize(); } /** * Process one block of input from the array in and write it to * the out array. * * @param in the array containing the input data. * @param inOff offset into the in array the data starts at. * @param out the array the output data will be copied into. * @param outOff the offset into the out array the output will start at. * @exception DataLengthException if there isn't enough data in in, or * space in out. * @exception IllegalStateException if the cipher isn't initialised. * @return the number of bytes processed and produced. */ public int processBlock( byte[] in, int inOff, byte[] out, int outOff) throws DataLengthException, IllegalStateException { return (encrypting) ? encryptBlock(in, inOff, out, outOff) : decryptBlock(in, inOff, out, outOff); } /** * reset the chaining vector back to the IV and reset the underlying * cipher. */ public void reset() { System.arraycopy(IV, 0, cbcV, 0, IV.length); Arrays.fill(cbcNextV, (byte)0); cipher.reset(); } /** * Do the appropriate chaining step for CBC mode encryption. * * @param in the array containing the data to be encrypted. * @param inOff offset into the in array the data starts at. * @param out the array the encrypted data will be copied into. * @param outOff the offset into the out array the output will start at. * @exception DataLengthException if there isn't enough data in in, or * space in out. * @exception IllegalStateException if the cipher isn't initialised. * @return the number of bytes processed and produced. */ private int encryptBlock( byte[] in, int inOff, byte[] out, int outOff) throws DataLengthException, IllegalStateException { if ((inOff + blockSize) > in.length) { throw new DataLengthException("input buffer too short"); } /* * XOR the cbcV and the input, * then encrypt the cbcV */ for (int i = 0; i < blockSize; i++) { cbcV[i] ^= in[inOff + i]; } int length = cipher.processBlock(cbcV, 0, out, outOff); /* * copy ciphertext to cbcV */ System.arraycopy(out, outOff, cbcV, 0, cbcV.length); return length; } /** * Do the appropriate chaining step for CBC mode decryption. * * @param in the array containing the data to be decrypted. * @param inOff offset into the in array the data starts at. * @param out the array the decrypted data will be copied into. * @param outOff the offset into the out array the output will start at. * @exception DataLengthException if there isn't enough data in in, or * space in out. * @exception IllegalStateException if the cipher isn't initialised. * @return the number of bytes processed and produced. */ private int decryptBlock( byte[] in, int inOff, byte[] out, int outOff) throws DataLengthException, IllegalStateException { if ((inOff + blockSize) > in.length) { throw new DataLengthException("input buffer too short"); } System.arraycopy(in, inOff, cbcNextV, 0, blockSize); int length = cipher.processBlock(in, inOff, out, outOff); /* * XOR the cbcV and the output */ for (int i = 0; i < blockSize; i++) { out[outOff + i] ^= cbcV[i]; } /* * swap the back up buffer into next position */ byte[] tmp; tmp = cbcV; cbcV = cbcNextV; cbcNextV = tmp; return length; } } bouncycastle-1.49.orig/src/org/bouncycastle/crypto/modes/PGPCFBBlockCipher.java0000644000175000017500000003246211567575773027101 0ustar ebourgebourgpackage org.bouncycastle.crypto.modes; import org.bouncycastle.crypto.BlockCipher; import org.bouncycastle.crypto.CipherParameters; import org.bouncycastle.crypto.DataLengthException; import org.bouncycastle.crypto.params.ParametersWithIV; /** * Implements OpenPGP's rather strange version of Cipher-FeedBack (CFB) mode on top of a simple cipher. For further info see RFC 2440. */ public class PGPCFBBlockCipher implements BlockCipher { private byte[] IV; private byte[] FR; private byte[] FRE; private byte[] tmp; private BlockCipher cipher; private int count; private int blockSize; private boolean forEncryption; private boolean inlineIv; // if false we don't need to prepend an IV /** * Basic constructor. * * @param cipher the block cipher to be used as the basis of the * feedback mode. * @param inlineIv if true this is for PGP CFB with a prepended iv. */ public PGPCFBBlockCipher( BlockCipher cipher, boolean inlineIv) { this.cipher = cipher; this.inlineIv = inlineIv; this.blockSize = cipher.getBlockSize(); this.IV = new byte[blockSize]; this.FR = new byte[blockSize]; this.FRE = new byte[blockSize]; this.tmp = new byte[blockSize]; } /** * return the underlying block cipher that we are wrapping. * * @return the underlying block cipher that we are wrapping. */ public BlockCipher getUnderlyingCipher() { return cipher; } /** * return the algorithm name and mode. * * @return the name of the underlying algorithm followed by "/PGPCFB" * and the block size in bits. */ public String getAlgorithmName() { if (inlineIv) { return cipher.getAlgorithmName() + "/PGPCFBwithIV"; } else { return cipher.getAlgorithmName() + "/PGPCFB"; } } /** * return the block size we are operating at. * * @return the block size we are operating at (in bytes). */ public int getBlockSize() { return cipher.getBlockSize(); } /** * Process one block of input from the array in and write it to * the out array. * * @param in the array containing the input data. * @param inOff offset into the in array the data starts at. * @param out the array the output data will be copied into. * @param outOff the offset into the out array the output will start at. * @exception DataLengthException if there isn't enough data in in, or * space in out. * @exception IllegalStateException if the cipher isn't initialised. * @return the number of bytes processed and produced. */ public int processBlock( byte[] in, int inOff, byte[] out, int outOff) throws DataLengthException, IllegalStateException { if (inlineIv) { return (forEncryption) ? encryptBlockWithIV(in, inOff, out, outOff) : decryptBlockWithIV(in, inOff, out, outOff); } else { return (forEncryption) ? encryptBlock(in, inOff, out, outOff) : decryptBlock(in, inOff, out, outOff); } } /** * reset the chaining vector back to the IV and reset the underlying * cipher. */ public void reset() { count = 0; for (int i = 0; i != FR.length; i++) { if (inlineIv) { FR[i] = 0; } else { FR[i] = IV[i]; // if simple mode, key is IV (even if this is zero) } } cipher.reset(); } /** * Initialise the cipher and, possibly, the initialisation vector (IV). * If an IV isn't passed as part of the parameter, the IV will be all zeros. * An IV which is too short is handled in FIPS compliant fashion. * * @param forEncryption if true the cipher is initialised for * encryption, if false for decryption. * @param params the key and other data required by the cipher. * @exception IllegalArgumentException if the params argument is * inappropriate. */ public void init( boolean forEncryption, CipherParameters params) throws IllegalArgumentException { this.forEncryption = forEncryption; if (params instanceof ParametersWithIV) { ParametersWithIV ivParam = (ParametersWithIV)params; byte[] iv = ivParam.getIV(); if (iv.length < IV.length) { // prepend the supplied IV with zeros (per FIPS PUB 81) System.arraycopy(iv, 0, IV, IV.length - iv.length, iv.length); for (int i = 0; i < IV.length - iv.length; i++) { IV[i] = 0; } } else { System.arraycopy(iv, 0, IV, 0, IV.length); } reset(); cipher.init(true, ivParam.getParameters()); } else { reset(); cipher.init(true, params); } } /** * Encrypt one byte of data according to CFB mode. * @param data the byte to encrypt * @param blockOff where am i in the current block, determines when to resync the block * @returns the encrypted byte */ private byte encryptByte(byte data, int blockOff) { return (byte)(FRE[blockOff] ^ data); } /** * Do the appropriate processing for CFB IV mode encryption. * * @param in the array containing the data to be encrypted. * @param inOff offset into the in array the data starts at. * @param out the array the encrypted data will be copied into. * @param outOff the offset into the out array the output will start at. * @exception DataLengthException if there isn't enough data in in, or * space in out. * @exception IllegalStateException if the cipher isn't initialised. * @return the number of bytes processed and produced. */ private int encryptBlockWithIV( byte[] in, int inOff, byte[] out, int outOff) throws DataLengthException, IllegalStateException { if ((inOff + blockSize) > in.length) { throw new DataLengthException("input buffer too short"); } if ((outOff + blockSize) > out.length) { throw new DataLengthException("output buffer too short"); } if (count == 0) { cipher.processBlock(FR, 0, FRE, 0); for (int n = 0; n < blockSize; n++) { out[outOff + n] = encryptByte(IV[n], n); } System.arraycopy(out, outOff, FR, 0, blockSize); cipher.processBlock(FR, 0, FRE, 0); out[outOff + blockSize] = encryptByte(IV[blockSize - 2], 0); out[outOff + blockSize + 1] = encryptByte(IV[blockSize - 1], 1); System.arraycopy(out, outOff + 2, FR, 0, blockSize); cipher.processBlock(FR, 0, FRE, 0); for (int n = 0; n < blockSize; n++) { out[outOff + blockSize + 2 + n] = encryptByte(in[inOff + n], n); } System.arraycopy(out, outOff + blockSize + 2, FR, 0, blockSize); count += 2 * blockSize + 2; return 2 * blockSize + 2; } else if (count >= blockSize + 2) { cipher.processBlock(FR, 0, FRE, 0); for (int n = 0; n < blockSize; n++) { out[outOff + n] = encryptByte(in[inOff + n], n); } System.arraycopy(out, outOff, FR, 0, blockSize); } return blockSize; } /** * Do the appropriate processing for CFB IV mode decryption. * * @param in the array containing the data to be decrypted. * @param inOff offset into the in array the data starts at. * @param out the array the encrypted data will be copied into. * @param outOff the offset into the out array the output will start at. * @exception DataLengthException if there isn't enough data in in, or * space in out. * @exception IllegalStateException if the cipher isn't initialised. * @return the number of bytes processed and produced. */ private int decryptBlockWithIV( byte[] in, int inOff, byte[] out, int outOff) throws DataLengthException, IllegalStateException { if ((inOff + blockSize) > in.length) { throw new DataLengthException("input buffer too short"); } if ((outOff + blockSize) > out.length) { throw new DataLengthException("output buffer too short"); } if (count == 0) { for (int n = 0; n < blockSize; n++) { FR[n] = in[inOff + n]; } cipher.processBlock(FR, 0, FRE, 0); count += blockSize; return 0; } else if (count == blockSize) { // copy in buffer so that this mode works if in and out are the same System.arraycopy(in, inOff, tmp, 0, blockSize); System.arraycopy(FR, 2, FR, 0, blockSize - 2); FR[blockSize - 2] = tmp[0]; FR[blockSize - 1] = tmp[1]; cipher.processBlock(FR, 0, FRE, 0); for (int n = 0; n < blockSize - 2; n++) { out[outOff + n] = encryptByte(tmp[n + 2], n); } System.arraycopy(tmp, 2, FR, 0, blockSize - 2); count += 2; return blockSize - 2; } else if (count >= blockSize + 2) { // copy in buffer so that this mode works if in and out are the same System.arraycopy(in, inOff, tmp, 0, blockSize); out[outOff + 0] = encryptByte(tmp[0], blockSize - 2); out[outOff + 1] = encryptByte(tmp[1], blockSize - 1); System.arraycopy(tmp, 0, FR, blockSize - 2, 2); cipher.processBlock(FR, 0, FRE, 0); for (int n = 0; n < blockSize - 2; n++) { out[outOff + n + 2] = encryptByte(tmp[n + 2], n); } System.arraycopy(tmp, 2, FR, 0, blockSize - 2); } return blockSize; } /** * Do the appropriate processing for CFB mode encryption. * * @param in the array containing the data to be encrypted. * @param inOff offset into the in array the data starts at. * @param out the array the encrypted data will be copied into. * @param outOff the offset into the out array the output will start at. * @exception DataLengthException if there isn't enough data in in, or * space in out. * @exception IllegalStateException if the cipher isn't initialised. * @return the number of bytes processed and produced. */ private int encryptBlock( byte[] in, int inOff, byte[] out, int outOff) throws DataLengthException, IllegalStateException { if ((inOff + blockSize) > in.length) { throw new DataLengthException("input buffer too short"); } if ((outOff + blockSize) > out.length) { throw new DataLengthException("output buffer too short"); } cipher.processBlock(FR, 0, FRE, 0); for (int n = 0; n < blockSize; n++) { out[outOff + n] = encryptByte(in[inOff + n], n); } for (int n = 0; n < blockSize; n++) { FR[n] = out[outOff + n]; } return blockSize; } /** * Do the appropriate processing for CFB mode decryption. * * @param in the array containing the data to be decrypted. * @param inOff offset into the in array the data starts at. * @param out the array the encrypted data will be copied into. * @param outOff the offset into the out array the output will start at. * @exception DataLengthException if there isn't enough data in in, or * space in out. * @exception IllegalStateException if the cipher isn't initialised. * @return the number of bytes processed and produced. */ private int decryptBlock( byte[] in, int inOff, byte[] out, int outOff) throws DataLengthException, IllegalStateException { if ((inOff + blockSize) > in.length) { throw new DataLengthException("input buffer too short"); } if ((outOff + blockSize) > out.length) { throw new DataLengthException("output buffer too short"); } cipher.processBlock(FR, 0, FRE, 0); for (int n = 0; n < blockSize; n++) { out[outOff + n] = encryptByte(in[inOff + n], n); } for (int n = 0; n < blockSize; n++) { FR[n] = in[inOff + n]; } return blockSize; } } bouncycastle-1.49.orig/src/org/bouncycastle/crypto/modes/OFBBlockCipher.java0000644000175000017500000001251712045642260026517 0ustar ebourgebourgpackage org.bouncycastle.crypto.modes; import org.bouncycastle.crypto.BlockCipher; import org.bouncycastle.crypto.CipherParameters; import org.bouncycastle.crypto.DataLengthException; import org.bouncycastle.crypto.params.ParametersWithIV; /** * implements a Output-FeedBack (OFB) mode on top of a simple cipher. */ public class OFBBlockCipher implements BlockCipher { private byte[] IV; private byte[] ofbV; private byte[] ofbOutV; private final int blockSize; private final BlockCipher cipher; /** * Basic constructor. * * @param cipher the block cipher to be used as the basis of the * feedback mode. * @param blockSize the block size in bits (note: a multiple of 8) */ public OFBBlockCipher( BlockCipher cipher, int blockSize) { this.cipher = cipher; this.blockSize = blockSize / 8; this.IV = new byte[cipher.getBlockSize()]; this.ofbV = new byte[cipher.getBlockSize()]; this.ofbOutV = new byte[cipher.getBlockSize()]; } /** * return the underlying block cipher that we are wrapping. * * @return the underlying block cipher that we are wrapping. */ public BlockCipher getUnderlyingCipher() { return cipher; } /** * Initialise the cipher and, possibly, the initialisation vector (IV). * If an IV isn't passed as part of the parameter, the IV will be all zeros. * An IV which is too short is handled in FIPS compliant fashion. * * @param encrypting if true the cipher is initialised for * encryption, if false for decryption. * @param params the key and other data required by the cipher. * @exception IllegalArgumentException if the params argument is * inappropriate. */ public void init( boolean encrypting, //ignored by this OFB mode CipherParameters params) throws IllegalArgumentException { if (params instanceof ParametersWithIV) { ParametersWithIV ivParam = (ParametersWithIV)params; byte[] iv = ivParam.getIV(); if (iv.length < IV.length) { // prepend the supplied IV with zeros (per FIPS PUB 81) System.arraycopy(iv, 0, IV, IV.length - iv.length, iv.length); for (int i = 0; i < IV.length - iv.length; i++) { IV[i] = 0; } } else { System.arraycopy(iv, 0, IV, 0, IV.length); } reset(); // if null it's an IV changed only. if (ivParam.getParameters() != null) { cipher.init(true, ivParam.getParameters()); } } else { reset(); // if it's null, key is to be reused. if (params != null) { cipher.init(true, params); } } } /** * return the algorithm name and mode. * * @return the name of the underlying algorithm followed by "/OFB" * and the block size in bits */ public String getAlgorithmName() { return cipher.getAlgorithmName() + "/OFB" + (blockSize * 8); } /** * return the block size we are operating at (in bytes). * * @return the block size we are operating at (in bytes). */ public int getBlockSize() { return blockSize; } /** * Process one block of input from the array in and write it to * the out array. * * @param in the array containing the input data. * @param inOff offset into the in array the data starts at. * @param out the array the output data will be copied into. * @param outOff the offset into the out array the output will start at. * @exception DataLengthException if there isn't enough data in in, or * space in out. * @exception IllegalStateException if the cipher isn't initialised. * @return the number of bytes processed and produced. */ public int processBlock( byte[] in, int inOff, byte[] out, int outOff) throws DataLengthException, IllegalStateException { if ((inOff + blockSize) > in.length) { throw new DataLengthException("input buffer too short"); } if ((outOff + blockSize) > out.length) { throw new DataLengthException("output buffer too short"); } cipher.processBlock(ofbV, 0, ofbOutV, 0); // // XOR the ofbV with the plaintext producing the cipher text (and // the next input block). // for (int i = 0; i < blockSize; i++) { out[outOff + i] = (byte)(ofbOutV[i] ^ in[inOff + i]); } // // change over the input block. // System.arraycopy(ofbV, blockSize, ofbV, 0, ofbV.length - blockSize); System.arraycopy(ofbOutV, 0, ofbV, ofbV.length - blockSize, blockSize); return blockSize; } /** * reset the feedback vector back to the IV and reset the underlying * cipher. */ public void reset() { System.arraycopy(IV, 0, ofbV, 0, IV.length); cipher.reset(); } } bouncycastle-1.49.orig/src/org/bouncycastle/crypto/modes/OCBBlockCipher.java0000644000175000017500000003632512132367115026517 0ustar ebourgebourgpackage org.bouncycastle.crypto.modes; import java.util.Vector; import org.bouncycastle.crypto.BlockCipher; import org.bouncycastle.crypto.CipherParameters; import org.bouncycastle.crypto.DataLengthException; import org.bouncycastle.crypto.InvalidCipherTextException; import org.bouncycastle.crypto.params.AEADParameters; import org.bouncycastle.crypto.params.KeyParameter; import org.bouncycastle.crypto.params.ParametersWithIV; import org.bouncycastle.util.Arrays; /** * An implementation of the "work in progress" Internet-Draft The OCB Authenticated-Encryption * Algorithm, licensed per: *

    *

    License for * Open-Source Software Implementations of OCB (Jan 9, 2013) — “License 1”
    * Under this license, you are authorized to make, use, and distribute open-source software * implementations of OCB. This license terminates for you if you sue someone over their open-source * software implementation of OCB claiming that you have a patent covering their implementation. *

    * This is a non-binding summary of a legal document (the link above). The parameters of the license * are specified in the license document and that document is controlling.

    */ public class OCBBlockCipher implements AEADBlockCipher { private static final int BLOCK_SIZE = 16; private BlockCipher hashCipher; private BlockCipher mainCipher; /* * CONFIGURATION */ private boolean forEncryption; private int macSize; private byte[] initialAssociatedText; /* * KEY-DEPENDENT */ // NOTE: elements are lazily calculated private Vector L; private byte[] L_Asterisk, L_Dollar; /* * NONCE-DEPENDENT */ private byte[] OffsetMAIN_0; /* * PER-ENCRYPTION/DECRYPTION */ private byte[] hashBlock, mainBlock; private int hashBlockPos, mainBlockPos; private long hashBlockCount, mainBlockCount; private byte[] OffsetHASH; private byte[] Sum; private byte[] OffsetMAIN; private byte[] Checksum; // NOTE: The MAC value is preserved after doFinal private byte[] macBlock; public OCBBlockCipher(BlockCipher hashCipher, BlockCipher mainCipher) { if (hashCipher == null) { throw new IllegalArgumentException("'hashCipher' cannot be null"); } if (hashCipher.getBlockSize() != BLOCK_SIZE) { throw new IllegalArgumentException("'hashCipher' must have a block size of " + BLOCK_SIZE); } if (mainCipher == null) { throw new IllegalArgumentException("'mainCipher' cannot be null"); } if (mainCipher.getBlockSize() != BLOCK_SIZE) { throw new IllegalArgumentException("'mainCipher' must have a block size of " + BLOCK_SIZE); } if (!hashCipher.getAlgorithmName().equals(mainCipher.getAlgorithmName())) { throw new IllegalArgumentException( "'hashCipher' and 'mainCipher' must be the same algorithm"); } this.hashCipher = hashCipher; this.mainCipher = mainCipher; } public BlockCipher getUnderlyingCipher() { return mainCipher; } public String getAlgorithmName() { return mainCipher.getAlgorithmName() + "/OCB"; } public void init(boolean forEncryption, CipherParameters parameters) throws IllegalArgumentException { this.forEncryption = forEncryption; this.macBlock = null; KeyParameter keyParameter; byte[] N; if (parameters instanceof AEADParameters) { AEADParameters aeadParameters = (AEADParameters)parameters; N = aeadParameters.getNonce(); initialAssociatedText = aeadParameters.getAssociatedText(); int macSizeBits = aeadParameters.getMacSize(); if (macSizeBits < 64 || macSizeBits > 128 || macSizeBits % 8 != 0) { throw new IllegalArgumentException("Invalid value for MAC size: " + macSizeBits); } macSize = macSizeBits / 8; keyParameter = aeadParameters.getKey(); } else if (parameters instanceof ParametersWithIV) { ParametersWithIV parametersWithIV = (ParametersWithIV)parameters; N = parametersWithIV.getIV(); initialAssociatedText = null; macSize = 16; keyParameter = (KeyParameter)parametersWithIV.getParameters(); } else { throw new IllegalArgumentException("invalid parameters passed to OCB"); } this.hashBlock = new byte[16]; this.mainBlock = new byte[forEncryption ? BLOCK_SIZE : (BLOCK_SIZE + macSize)]; if (N == null) { N = new byte[0]; } if (N.length > 16 || (N.length == 16 && (N[0] & 0x80) != 0)) { /* * NOTE: We don't just ignore bit 128 because it would hide from the caller the fact * that two nonces differing only in bit 128 are not different. */ throw new IllegalArgumentException("IV must be no more than 127 bits"); } /* * KEY-DEPENDENT INITIALISATION */ // if keyParam is null we're reusing the last key. if (keyParameter != null) { // TODO } // hashCipher always used in forward mode hashCipher.init(true, keyParameter); mainCipher.init(forEncryption, keyParameter); this.L_Asterisk = new byte[16]; hashCipher.processBlock(L_Asterisk, 0, L_Asterisk, 0); this.L_Dollar = OCB_double(L_Asterisk); this.L = new Vector(); this.L.addElement(OCB_double(L_Dollar)); /* * NONCE-DEPENDENT AND PER-ENCRYPTION/DECRYPTION INITIALISATION */ byte[] nonce = new byte[16]; System.arraycopy(N, 0, nonce, nonce.length - N.length, N.length); if (N.length == 16) { nonce[0] &= 0x80; } else { nonce[15 - N.length] = 1; } int bottom = nonce[15] & 0x3F; // System.out.println("bottom: " + bottom); byte[] Ktop = new byte[16]; nonce[15] &= 0xC0; hashCipher.processBlock(nonce, 0, Ktop, 0); byte[] Stretch = new byte[24]; System.arraycopy(Ktop, 0, Stretch, 0, 16); for (int i = 0; i < 8; ++i) { Stretch[16 + i] = (byte)(Ktop[i] ^ Ktop[i + 1]); } this.OffsetMAIN_0 = new byte[16]; int bits = bottom % 8, bytes = bottom / 8; if (bits == 0) { System.arraycopy(Stretch, bytes, OffsetMAIN_0, 0, 16); } else { for (int i = 0; i < 16; ++i) { int b1 = Stretch[bytes] & 0xff; int b2 = Stretch[++bytes] & 0xff; this.OffsetMAIN_0[i] = (byte)((b1 << bits) | (b2 >>> (8 - bits))); } } this.hashBlockPos = 0; this.mainBlockPos = 0; this.hashBlockCount = 0; this.mainBlockCount = 0; this.OffsetHASH = new byte[16]; this.Sum = new byte[16]; this.OffsetMAIN = Arrays.clone(this.OffsetMAIN_0); this.Checksum = new byte[16]; if (initialAssociatedText != null) { processAADBytes(initialAssociatedText, 0, initialAssociatedText.length); } } public byte[] getMac() { return Arrays.clone(macBlock); } public int getOutputSize(int len) { int totalData = len + mainBlockPos; if (forEncryption) { return totalData + macSize; } return totalData < macSize ? 0 : totalData - macSize; } public int getUpdateOutputSize(int len) { int totalData = len + mainBlockPos; if (!forEncryption) { if (totalData < macSize) { return 0; } totalData -= macSize; } return totalData - totalData % BLOCK_SIZE; } public void processAADByte(byte input) { hashBlock[hashBlockPos] = input; if (++hashBlockPos == hashBlock.length) { processHashBlock(); } } public void processAADBytes(byte[] input, int off, int len) { for (int i = 0; i < len; ++i) { hashBlock[hashBlockPos] = input[off + i]; if (++hashBlockPos == hashBlock.length) { processHashBlock(); } } } public int processByte(byte input, byte[] output, int outOff) throws DataLengthException { mainBlock[mainBlockPos] = input; if (++mainBlockPos == mainBlock.length) { processMainBlock(output, outOff); return BLOCK_SIZE; } return 0; } public int processBytes(byte[] input, int inOff, int len, byte[] output, int outOff) throws DataLengthException { int resultLen = 0; for (int i = 0; i < len; ++i) { mainBlock[mainBlockPos] = input[inOff + i]; if (++mainBlockPos == mainBlock.length) { processMainBlock(output, outOff + resultLen); resultLen += BLOCK_SIZE; } } return resultLen; } public int doFinal(byte[] output, int outOff) throws IllegalStateException, InvalidCipherTextException { /* * For decryption, get the tag from the end of the message */ byte[] tag = null; if (!forEncryption) { if (mainBlockPos < macSize) { throw new InvalidCipherTextException("data too short"); } mainBlockPos -= macSize; tag = new byte[macSize]; System.arraycopy(mainBlock, mainBlockPos, tag, 0, macSize); } /* * HASH: Process any final partial block; compute final hash value */ if (hashBlockPos > 0) { OCB_extend(hashBlock, hashBlockPos); updateHASH(L_Asterisk); } /* * OCB-ENCRYPT/OCB-DECRYPT: Process any final partial block */ if (mainBlockPos > 0) { if (forEncryption) { OCB_extend(mainBlock, mainBlockPos); xor(Checksum, mainBlock); } xor(OffsetMAIN, L_Asterisk); byte[] Pad = new byte[16]; hashCipher.processBlock(OffsetMAIN, 0, Pad, 0); xor(mainBlock, Pad); System.arraycopy(mainBlock, 0, output, outOff, mainBlockPos); if (!forEncryption) { OCB_extend(mainBlock, mainBlockPos); xor(Checksum, mainBlock); } } /* * OCB-ENCRYPT/OCB-DECRYPT: Compute raw tag */ xor(Checksum, OffsetMAIN); xor(Checksum, L_Dollar); hashCipher.processBlock(Checksum, 0, Checksum, 0); xor(Checksum, Sum); this.macBlock = new byte[macSize]; System.arraycopy(Checksum, 0, macBlock, 0, macSize); /* * Validate or append tag and reset this cipher for the next run */ int resultLen = mainBlockPos; if (forEncryption) { // Append tag to the message System.arraycopy(macBlock, 0, output, outOff + resultLen, macSize); resultLen += macSize; } else { // Compare the tag from the message with the calculated one if (!Arrays.constantTimeAreEqual(macBlock, tag)) { throw new InvalidCipherTextException("mac check in OCB failed"); } } reset(false); return resultLen; } public void reset() { reset(true); } protected void clear(byte[] bs) { if (bs != null) { Arrays.fill(bs, (byte)0); } } protected byte[] getLSub(int n) { while (n >= L.size()) { L.addElement(OCB_double((byte[])L.lastElement())); } return (byte[])L.elementAt(n); } protected void processHashBlock() { /* * HASH: Process any whole blocks */ updateHASH(getLSub(OCB_ntz(++hashBlockCount))); hashBlockPos = 0; } protected void processMainBlock(byte[] output, int outOff) { /* * OCB-ENCRYPT/OCB-DECRYPT: Process any whole blocks */ if (forEncryption) { xor(Checksum, mainBlock); mainBlockPos = 0; } xor(OffsetMAIN, getLSub(OCB_ntz(++mainBlockCount))); xor(mainBlock, OffsetMAIN); mainCipher.processBlock(mainBlock, 0, mainBlock, 0); xor(mainBlock, OffsetMAIN); System.arraycopy(mainBlock, 0, output, outOff, 16); if (!forEncryption) { xor(Checksum, mainBlock); System.arraycopy(mainBlock, BLOCK_SIZE, mainBlock, 0, macSize); mainBlockPos = macSize; } } protected void reset(boolean clearMac) { hashCipher.reset(); mainCipher.reset(); clear(hashBlock); clear(mainBlock); hashBlockPos = 0; mainBlockPos = 0; hashBlockCount = 0; mainBlockCount = 0; clear(OffsetHASH); clear(Sum); System.arraycopy(OffsetMAIN_0, 0, OffsetMAIN, 0, 16); clear(Checksum); if (clearMac) { macBlock = null; } if (initialAssociatedText != null) { processAADBytes(initialAssociatedText, 0, initialAssociatedText.length); } } protected void updateHASH(byte[] LSub) { xor(OffsetHASH, LSub); xor(hashBlock, OffsetHASH); hashCipher.processBlock(hashBlock, 0, hashBlock, 0); xor(Sum, hashBlock); } protected static byte[] OCB_double(byte[] block) { byte[] result = new byte[16]; int carry = shiftLeft(block, result); /* * NOTE: This construction is an attempt at a constant-time implementation. */ result[15] ^= (0x87 >>> ((1 - carry) << 3)); return result; } protected static void OCB_extend(byte[] block, int pos) { block[pos] = (byte)0x80; while (++pos < 16) { block[pos] = 0; } } protected static int OCB_ntz(long x) { if (x == 0) { return 64; } int n = 0; while ((x & 1L) == 0L) { ++n; x >>= 1; } return n; } protected static int shiftLeft(byte[] block, byte[] output) { int i = 16; int bit = 0; while (--i >= 0) { int b = block[i] & 0xff; output[i] = (byte)((b << 1) | bit); bit = (b >>> 7) & 1; } return bit; } protected static void xor(byte[] block, byte[] val) { for (int i = 15; i >= 0; --i) { block[i] ^= val[i]; } } } bouncycastle-1.49.orig/src/org/bouncycastle/crypto/modes/package.html0000644000175000017500000000011510262753175025417 0ustar ebourgebourg Modes for symmetric ciphers. bouncycastle-1.49.orig/src/org/bouncycastle/crypto/modes/GOFBBlockCipher.java0000644000175000017500000001510211576521570026627 0ustar ebourgebourgpackage org.bouncycastle.crypto.modes; import org.bouncycastle.crypto.BlockCipher; import org.bouncycastle.crypto.CipherParameters; import org.bouncycastle.crypto.DataLengthException; import org.bouncycastle.crypto.params.ParametersWithIV; /** * implements the GOST 28147 OFB counter mode (GCTR). */ public class GOFBBlockCipher implements BlockCipher { private byte[] IV; private byte[] ofbV; private byte[] ofbOutV; private final int blockSize; private final BlockCipher cipher; boolean firstStep = true; int N3; int N4; static final int C1 = 16843012; //00000001000000010000000100000100 static final int C2 = 16843009; //00000001000000010000000100000001 /** * Basic constructor. * * @param cipher the block cipher to be used as the basis of the * counter mode (must have a 64 bit block size). */ public GOFBBlockCipher( BlockCipher cipher) { this.cipher = cipher; this.blockSize = cipher.getBlockSize(); if (blockSize != 8) { throw new IllegalArgumentException("GCTR only for 64 bit block ciphers"); } this.IV = new byte[cipher.getBlockSize()]; this.ofbV = new byte[cipher.getBlockSize()]; this.ofbOutV = new byte[cipher.getBlockSize()]; } /** * return the underlying block cipher that we are wrapping. * * @return the underlying block cipher that we are wrapping. */ public BlockCipher getUnderlyingCipher() { return cipher; } /** * Initialise the cipher and, possibly, the initialisation vector (IV). * If an IV isn't passed as part of the parameter, the IV will be all zeros. * An IV which is too short is handled in FIPS compliant fashion. * * @param encrypting if true the cipher is initialised for * encryption, if false for decryption. * @param params the key and other data required by the cipher. * @exception IllegalArgumentException if the params argument is * inappropriate. */ public void init( boolean encrypting, //ignored by this CTR mode CipherParameters params) throws IllegalArgumentException { firstStep = true; N3 = 0; N4 = 0; if (params instanceof ParametersWithIV) { ParametersWithIV ivParam = (ParametersWithIV)params; byte[] iv = ivParam.getIV(); if (iv.length < IV.length) { // prepend the supplied IV with zeros (per FIPS PUB 81) System.arraycopy(iv, 0, IV, IV.length - iv.length, iv.length); for (int i = 0; i < IV.length - iv.length; i++) { IV[i] = 0; } } else { System.arraycopy(iv, 0, IV, 0, IV.length); } reset(); // if params is null we reuse the current working key. if (ivParam.getParameters() != null) { cipher.init(true, ivParam.getParameters()); } } else { reset(); // if params is null we reuse the current working key. if (params != null) { cipher.init(true, params); } } } /** * return the algorithm name and mode. * * @return the name of the underlying algorithm followed by "/GCTR" * and the block size in bits */ public String getAlgorithmName() { return cipher.getAlgorithmName() + "/GCTR"; } /** * return the block size we are operating at (in bytes). * * @return the block size we are operating at (in bytes). */ public int getBlockSize() { return blockSize; } /** * Process one block of input from the array in and write it to * the out array. * * @param in the array containing the input data. * @param inOff offset into the in array the data starts at. * @param out the array the output data will be copied into. * @param outOff the offset into the out array the output will start at. * @exception DataLengthException if there isn't enough data in in, or * space in out. * @exception IllegalStateException if the cipher isn't initialised. * @return the number of bytes processed and produced. */ public int processBlock( byte[] in, int inOff, byte[] out, int outOff) throws DataLengthException, IllegalStateException { if ((inOff + blockSize) > in.length) { throw new DataLengthException("input buffer too short"); } if ((outOff + blockSize) > out.length) { throw new DataLengthException("output buffer too short"); } if (firstStep) { firstStep = false; cipher.processBlock(ofbV, 0, ofbOutV, 0); N3 = bytesToint(ofbOutV, 0); N4 = bytesToint(ofbOutV, 4); } N3 += C2; N4 += C1; intTobytes(N3, ofbV, 0); intTobytes(N4, ofbV, 4); cipher.processBlock(ofbV, 0, ofbOutV, 0); // // XOR the ofbV with the plaintext producing the cipher text (and // the next input block). // for (int i = 0; i < blockSize; i++) { out[outOff + i] = (byte)(ofbOutV[i] ^ in[inOff + i]); } // // change over the input block. // System.arraycopy(ofbV, blockSize, ofbV, 0, ofbV.length - blockSize); System.arraycopy(ofbOutV, 0, ofbV, ofbV.length - blockSize, blockSize); return blockSize; } /** * reset the feedback vector back to the IV and reset the underlying * cipher. */ public void reset() { System.arraycopy(IV, 0, ofbV, 0, IV.length); cipher.reset(); } //array of bytes to type int private int bytesToint( byte[] in, int inOff) { return ((in[inOff + 3] << 24) & 0xff000000) + ((in[inOff + 2] << 16) & 0xff0000) + ((in[inOff + 1] << 8) & 0xff00) + (in[inOff] & 0xff); } //int to array of bytes private void intTobytes( int num, byte[] out, int outOff) { out[outOff + 3] = (byte)(num >>> 24); out[outOff + 2] = (byte)(num >>> 16); out[outOff + 1] = (byte)(num >>> 8); out[outOff] = (byte)num; } } bouncycastle-1.49.orig/src/org/bouncycastle/crypto/modes/AEADBlockCipher.java0000644000175000017500000001116512045616304026601 0ustar ebourgebourgpackage org.bouncycastle.crypto.modes; import org.bouncycastle.crypto.BlockCipher; import org.bouncycastle.crypto.CipherParameters; import org.bouncycastle.crypto.DataLengthException; import org.bouncycastle.crypto.InvalidCipherTextException; /** * A block cipher mode that includes authenticated encryption with a streaming mode and optional associated data. * @see org.bouncycastle.crypto.params.AEADParameters */ public interface AEADBlockCipher { /** * initialise the underlying cipher. Parameter can either be an AEADParameters or a ParametersWithIV object. * * @param forEncryption true if we are setting up for encryption, false otherwise. * @param params the necessary parameters for the underlying cipher to be initialised. * @exception IllegalArgumentException if the params argument is inappropriate. */ public void init(boolean forEncryption, CipherParameters params) throws IllegalArgumentException; /** * Return the name of the algorithm. * * @return the algorithm name. */ public String getAlgorithmName(); /** * return the cipher this object wraps. * * @return the cipher this object wraps. */ public BlockCipher getUnderlyingCipher(); /** * Add a single byte to the associated data check. *
    If the implementation supports it, this will be an online operation and will not retain the associated data. * * @param in the byte to be processed. */ public void processAADByte(byte in); /** * Add a sequence of bytes to the associated data check. *
    If the implementation supports it, this will be an online operation and will not retain the associated data. * * @param in the input byte array. * @param inOff the offset into the in array where the data to be processed starts. * @param len the number of bytes to be processed. */ public void processAADBytes(byte[] in, int inOff, int len); /** * encrypt/decrypt a single byte. * * @param in the byte to be processed. * @param out the output buffer the processed byte goes into. * @param outOff the offset into the output byte array the processed data starts at. * @return the number of bytes written to out. * @exception DataLengthException if the output buffer is too small. */ public int processByte(byte in, byte[] out, int outOff) throws DataLengthException; /** * process a block of bytes from in putting the result into out. * * @param in the input byte array. * @param inOff the offset into the in array where the data to be processed starts. * @param len the number of bytes to be processed. * @param out the output buffer the processed bytes go into. * @param outOff the offset into the output byte array the processed data starts at. * @return the number of bytes written to out. * @exception DataLengthException if the output buffer is too small. */ public int processBytes(byte[] in, int inOff, int len, byte[] out, int outOff) throws DataLengthException; /** * Finish the operation either appending or verifying the MAC at the end of the data. * * @param out space for any resulting output data. * @param outOff offset into out to start copying the data at. * @return number of bytes written into out. * @throws IllegalStateException if the cipher is in an inappropriate state. * @throws org.bouncycastle.crypto.InvalidCipherTextException if the MAC fails to match. */ public int doFinal(byte[] out, int outOff) throws IllegalStateException, InvalidCipherTextException; /** * Return the value of the MAC associated with the last stream processed. * * @return MAC for plaintext data. */ public byte[] getMac(); /** * return the size of the output buffer required for a processBytes * an input of len bytes. * * @param len the length of the input. * @return the space required to accommodate a call to processBytes * with len bytes of input. */ public int getUpdateOutputSize(int len); /** * return the size of the output buffer required for a processBytes plus a * doFinal with an input of len bytes. * * @param len the length of the input. * @return the space required to accommodate a call to processBytes and doFinal * with len bytes of input. */ public int getOutputSize(int len); /** * Reset the cipher. After resetting the cipher is in the same state * as it was after the last init (if there was one). */ public void reset(); } bouncycastle-1.49.orig/src/org/bouncycastle/crypto/InvalidCipherTextException.java0000644000175000017500000000160312033464327030136 0ustar ebourgebourgpackage org.bouncycastle.crypto; /** * this exception is thrown whenever we find something we don't expect in a * message. */ public class InvalidCipherTextException extends CryptoException { /** * base constructor. */ public InvalidCipherTextException() { } /** * create a InvalidCipherTextException with the given message. * * @param message the message to be carried with the exception. */ public InvalidCipherTextException( String message) { super(message); } /** * create a InvalidCipherTextException with the given message. * * @param message the message to be carried with the exception. * @param cause the root cause of the exception. */ public InvalidCipherTextException( String message, Throwable cause) { super(message, cause); } } bouncycastle-1.49.orig/src/org/bouncycastle/crypto/encodings/0000755000175000017500000000000012152033551023770 5ustar ebourgebourgbouncycastle-1.49.orig/src/org/bouncycastle/crypto/encodings/ISO9796d1Encoding.java0000644000175000017500000001763211501545662027541 0ustar ebourgebourgpackage org.bouncycastle.crypto.encodings; import java.math.BigInteger; import org.bouncycastle.crypto.AsymmetricBlockCipher; import org.bouncycastle.crypto.CipherParameters; import org.bouncycastle.crypto.InvalidCipherTextException; import org.bouncycastle.crypto.params.ParametersWithRandom; import org.bouncycastle.crypto.params.RSAKeyParameters; /** * ISO 9796-1 padding. Note in the light of recent results you should * only use this with RSA (rather than the "simpler" Rabin keys) and you * should never use it with anything other than a hash (ie. even if the * message is small don't sign the message, sign it's hash) or some "random" * value. See your favorite search engine for details. */ public class ISO9796d1Encoding implements AsymmetricBlockCipher { private static final BigInteger SIXTEEN = BigInteger.valueOf(16L); private static final BigInteger SIX = BigInteger.valueOf(6L); private static byte[] shadows = { 0xe, 0x3, 0x5, 0x8, 0x9, 0x4, 0x2, 0xf, 0x0, 0xd, 0xb, 0x6, 0x7, 0xa, 0xc, 0x1 }; private static byte[] inverse = { 0x8, 0xf, 0x6, 0x1, 0x5, 0x2, 0xb, 0xc, 0x3, 0x4, 0xd, 0xa, 0xe, 0x9, 0x0, 0x7 }; private AsymmetricBlockCipher engine; private boolean forEncryption; private int bitSize; private int padBits = 0; private BigInteger modulus; public ISO9796d1Encoding( AsymmetricBlockCipher cipher) { this.engine = cipher; } public AsymmetricBlockCipher getUnderlyingCipher() { return engine; } public void init( boolean forEncryption, CipherParameters param) { RSAKeyParameters kParam = null; if (param instanceof ParametersWithRandom) { ParametersWithRandom rParam = (ParametersWithRandom)param; kParam = (RSAKeyParameters)rParam.getParameters(); } else { kParam = (RSAKeyParameters)param; } engine.init(forEncryption, param); modulus = kParam.getModulus(); bitSize = modulus.bitLength(); this.forEncryption = forEncryption; } /** * return the input block size. The largest message we can process * is (key_size_in_bits + 3)/16, which in our world comes to * key_size_in_bytes / 2. */ public int getInputBlockSize() { int baseBlockSize = engine.getInputBlockSize(); if (forEncryption) { return (baseBlockSize + 1) / 2; } else { return baseBlockSize; } } /** * return the maximum possible size for the output. */ public int getOutputBlockSize() { int baseBlockSize = engine.getOutputBlockSize(); if (forEncryption) { return baseBlockSize; } else { return (baseBlockSize + 1) / 2; } } /** * set the number of bits in the next message to be treated as * pad bits. */ public void setPadBits( int padBits) { if (padBits > 7) { throw new IllegalArgumentException("padBits > 7"); } this.padBits = padBits; } /** * retrieve the number of pad bits in the last decoded message. */ public int getPadBits() { return padBits; } public byte[] processBlock( byte[] in, int inOff, int inLen) throws InvalidCipherTextException { if (forEncryption) { return encodeBlock(in, inOff, inLen); } else { return decodeBlock(in, inOff, inLen); } } private byte[] encodeBlock( byte[] in, int inOff, int inLen) throws InvalidCipherTextException { byte[] block = new byte[(bitSize + 7) / 8]; int r = padBits + 1; int z = inLen; int t = (bitSize + 13) / 16; for (int i = 0; i < t; i += z) { if (i > t - z) { System.arraycopy(in, inOff + inLen - (t - i), block, block.length - t, t - i); } else { System.arraycopy(in, inOff, block, block.length - (i + z), z); } } for (int i = block.length - 2 * t; i != block.length; i += 2) { byte val = block[block.length - t + i / 2]; block[i] = (byte)((shadows[(val & 0xff) >>> 4] << 4) | shadows[val & 0x0f]); block[i + 1] = val; } block[block.length - 2 * z] ^= r; block[block.length - 1] = (byte)((block[block.length - 1] << 4) | 0x06); int maxBit = (8 - (bitSize - 1) % 8); int offSet = 0; if (maxBit != 8) { block[0] &= 0xff >>> maxBit; block[0] |= 0x80 >>> maxBit; } else { block[0] = 0x00; block[1] |= 0x80; offSet = 1; } return engine.processBlock(block, offSet, block.length - offSet); } /** * @exception InvalidCipherTextException if the decrypted block is not a valid ISO 9796 bit string */ private byte[] decodeBlock( byte[] in, int inOff, int inLen) throws InvalidCipherTextException { byte[] block = engine.processBlock(in, inOff, inLen); int r = 1; int t = (bitSize + 13) / 16; BigInteger iS = new BigInteger(1, block); BigInteger iR; if (iS.mod(SIXTEEN).equals(SIX)) { iR = iS; } else if ((modulus.subtract(iS)).mod(SIXTEEN).equals(SIX)) { iR = modulus.subtract(iS); } else { throw new InvalidCipherTextException("resulting integer iS or (modulus - iS) is not congruent to 6 mod 16"); } block = convertOutputDecryptOnly(iR); if ((block[block.length - 1] & 0x0f) != 0x6 ) { throw new InvalidCipherTextException("invalid forcing byte in block"); } block[block.length - 1] = (byte)(((block[block.length - 1] & 0xff) >>> 4) | ((inverse[(block[block.length - 2] & 0xff) >> 4]) << 4)); block[0] = (byte)((shadows[(block[1] & 0xff) >>> 4] << 4) | shadows[block[1] & 0x0f]); boolean boundaryFound = false; int boundary = 0; for (int i = block.length - 1; i >= block.length - 2 * t; i -= 2) { int val = ((shadows[(block[i] & 0xff) >>> 4] << 4) | shadows[block[i] & 0x0f]); if (((block[i - 1] ^ val) & 0xff) != 0) { if (!boundaryFound) { boundaryFound = true; r = (block[i - 1] ^ val) & 0xff; boundary = i - 1; } else { throw new InvalidCipherTextException("invalid tsums in block"); } } } block[boundary] = 0; byte[] nblock = new byte[(block.length - boundary) / 2]; for (int i = 0; i < nblock.length; i++) { nblock[i] = block[2 * i + boundary + 1]; } padBits = r - 1; return nblock; } private static byte[] convertOutputDecryptOnly(BigInteger result) { byte[] output = result.toByteArray(); if (output[0] == 0) // have ended up with an extra zero byte, copy down. { byte[] tmp = new byte[output.length - 1]; System.arraycopy(output, 1, tmp, 0, tmp.length); return tmp; } return output; } } bouncycastle-1.49.orig/src/org/bouncycastle/crypto/encodings/PKCS1Encoding.java0000644000175000017500000001542312102715011027121 0ustar ebourgebourgpackage org.bouncycastle.crypto.encodings; import java.security.AccessController; import java.security.PrivilegedAction; import java.security.SecureRandom; import org.bouncycastle.crypto.AsymmetricBlockCipher; import org.bouncycastle.crypto.CipherParameters; import org.bouncycastle.crypto.InvalidCipherTextException; import org.bouncycastle.crypto.params.AsymmetricKeyParameter; import org.bouncycastle.crypto.params.ParametersWithRandom; /** * this does your basic PKCS 1 v1.5 padding - whether or not you should be using this * depends on your application - see PKCS1 Version 2 for details. */ public class PKCS1Encoding implements AsymmetricBlockCipher { /** * some providers fail to include the leading zero in PKCS1 encoded blocks. If you need to * work with one of these set the system property org.bouncycastle.pkcs1.strict to false. *

    * The system property is checked during construction of the encoding object, it is set to * true by default. *

    */ public static final String STRICT_LENGTH_ENABLED_PROPERTY = "org.bouncycastle.pkcs1.strict"; private static final int HEADER_LENGTH = 10; private SecureRandom random; private AsymmetricBlockCipher engine; private boolean forEncryption; private boolean forPrivateKey; private boolean useStrictLength; /** * Basic constructor. * @param cipher */ public PKCS1Encoding( AsymmetricBlockCipher cipher) { this.engine = cipher; this.useStrictLength = useStrict(); } // // for J2ME compatibility // private boolean useStrict() { // required if security manager has been installed. String strict = (String)AccessController.doPrivileged(new PrivilegedAction() { public Object run() { return System.getProperty(STRICT_LENGTH_ENABLED_PROPERTY); } }); return strict == null || strict.equals("true"); } public AsymmetricBlockCipher getUnderlyingCipher() { return engine; } public void init( boolean forEncryption, CipherParameters param) { AsymmetricKeyParameter kParam; if (param instanceof ParametersWithRandom) { ParametersWithRandom rParam = (ParametersWithRandom)param; this.random = rParam.getRandom(); kParam = (AsymmetricKeyParameter)rParam.getParameters(); } else { this.random = new SecureRandom(); kParam = (AsymmetricKeyParameter)param; } engine.init(forEncryption, param); this.forPrivateKey = kParam.isPrivate(); this.forEncryption = forEncryption; } public int getInputBlockSize() { int baseBlockSize = engine.getInputBlockSize(); if (forEncryption) { return baseBlockSize - HEADER_LENGTH; } else { return baseBlockSize; } } public int getOutputBlockSize() { int baseBlockSize = engine.getOutputBlockSize(); if (forEncryption) { return baseBlockSize; } else { return baseBlockSize - HEADER_LENGTH; } } public byte[] processBlock( byte[] in, int inOff, int inLen) throws InvalidCipherTextException { if (forEncryption) { return encodeBlock(in, inOff, inLen); } else { return decodeBlock(in, inOff, inLen); } } private byte[] encodeBlock( byte[] in, int inOff, int inLen) throws InvalidCipherTextException { if (inLen > getInputBlockSize()) { throw new IllegalArgumentException("input data too large"); } byte[] block = new byte[engine.getInputBlockSize()]; if (forPrivateKey) { block[0] = 0x01; // type code 1 for (int i = 1; i != block.length - inLen - 1; i++) { block[i] = (byte)0xFF; } } else { random.nextBytes(block); // random fill block[0] = 0x02; // type code 2 // // a zero byte marks the end of the padding, so all // the pad bytes must be non-zero. // for (int i = 1; i != block.length - inLen - 1; i++) { while (block[i] == 0) { block[i] = (byte)random.nextInt(); } } } block[block.length - inLen - 1] = 0x00; // mark the end of the padding System.arraycopy(in, inOff, block, block.length - inLen, inLen); return engine.processBlock(block, 0, block.length); } /** * @exception InvalidCipherTextException if the decrypted block is not in PKCS1 format. */ private byte[] decodeBlock( byte[] in, int inOff, int inLen) throws InvalidCipherTextException { byte[] block = engine.processBlock(in, inOff, inLen); if (block.length < getOutputBlockSize()) { throw new InvalidCipherTextException("block truncated"); } byte type = block[0]; if (forPrivateKey) { if (type != 2) { throw new InvalidCipherTextException("unknown block type"); } } else { if (type != 1) { throw new InvalidCipherTextException("unknown block type"); } } if (useStrictLength && block.length != engine.getOutputBlockSize()) { throw new InvalidCipherTextException("block incorrect size"); } // // find and extract the message block. // int start; for (start = 1; start != block.length; start++) { byte pad = block[start]; if (pad == 0) { break; } if (type == 1 && pad != (byte)0xff) { throw new InvalidCipherTextException("block padding incorrect"); } } start++; // data should start at the next byte if (start > block.length || start < HEADER_LENGTH) { throw new InvalidCipherTextException("no data in block"); } byte[] result = new byte[block.length - start]; System.arraycopy(block, start, result, 0, result.length); return result; } } bouncycastle-1.49.orig/src/org/bouncycastle/crypto/encodings/OAEPEncoding.java0000644000175000017500000002140012151274317027031 0ustar ebourgebourgpackage org.bouncycastle.crypto.encodings; import java.security.SecureRandom; import org.bouncycastle.crypto.AsymmetricBlockCipher; import org.bouncycastle.crypto.CipherParameters; import org.bouncycastle.crypto.Digest; import org.bouncycastle.crypto.InvalidCipherTextException; import org.bouncycastle.crypto.digests.SHA1Digest; import org.bouncycastle.crypto.params.ParametersWithRandom; /** * Optimal Asymmetric Encryption Padding (OAEP) - see PKCS 1 V 2. */ public class OAEPEncoding implements AsymmetricBlockCipher { private byte[] defHash; private Digest mgf1Hash; private AsymmetricBlockCipher engine; private SecureRandom random; private boolean forEncryption; public OAEPEncoding( AsymmetricBlockCipher cipher) { this(cipher, new SHA1Digest(), null); } public OAEPEncoding( AsymmetricBlockCipher cipher, Digest hash) { this(cipher, hash, null); } public OAEPEncoding( AsymmetricBlockCipher cipher, Digest hash, byte[] encodingParams) { this(cipher, hash, hash, encodingParams); } public OAEPEncoding( AsymmetricBlockCipher cipher, Digest hash, Digest mgf1Hash, byte[] encodingParams) { this.engine = cipher; this.mgf1Hash = mgf1Hash; this.defHash = new byte[hash.getDigestSize()]; hash.reset(); if (encodingParams != null) { hash.update(encodingParams, 0, encodingParams.length); } hash.doFinal(defHash, 0); } public AsymmetricBlockCipher getUnderlyingCipher() { return engine; } public void init( boolean forEncryption, CipherParameters param) { if (param instanceof ParametersWithRandom) { ParametersWithRandom rParam = (ParametersWithRandom)param; this.random = rParam.getRandom(); } else { this.random = new SecureRandom(); } engine.init(forEncryption, param); this.forEncryption = forEncryption; } public int getInputBlockSize() { int baseBlockSize = engine.getInputBlockSize(); if (forEncryption) { return baseBlockSize - 1 - 2 * defHash.length; } else { return baseBlockSize; } } public int getOutputBlockSize() { int baseBlockSize = engine.getOutputBlockSize(); if (forEncryption) { return baseBlockSize; } else { return baseBlockSize - 1 - 2 * defHash.length; } } public byte[] processBlock( byte[] in, int inOff, int inLen) throws InvalidCipherTextException { if (forEncryption) { return encodeBlock(in, inOff, inLen); } else { return decodeBlock(in, inOff, inLen); } } public byte[] encodeBlock( byte[] in, int inOff, int inLen) throws InvalidCipherTextException { byte[] block = new byte[getInputBlockSize() + 1 + 2 * defHash.length]; // // copy in the message // System.arraycopy(in, inOff, block, block.length - inLen, inLen); // // add sentinel // block[block.length - inLen - 1] = 0x01; // // as the block is already zeroed - there's no need to add PS (the >= 0 pad of 0) // // // add the hash of the encoding params. // System.arraycopy(defHash, 0, block, defHash.length, defHash.length); // // generate the seed. // byte[] seed = new byte[defHash.length]; random.nextBytes(seed); // // mask the message block. // byte[] mask = maskGeneratorFunction1(seed, 0, seed.length, block.length - defHash.length); for (int i = defHash.length; i != block.length; i++) { block[i] ^= mask[i - defHash.length]; } // // add in the seed // System.arraycopy(seed, 0, block, 0, defHash.length); // // mask the seed. // mask = maskGeneratorFunction1( block, defHash.length, block.length - defHash.length, defHash.length); for (int i = 0; i != defHash.length; i++) { block[i] ^= mask[i]; } return engine.processBlock(block, 0, block.length); } /** * @exception InvalidCipherTextException if the decrypted block turns out to * be badly formatted. */ public byte[] decodeBlock( byte[] in, int inOff, int inLen) throws InvalidCipherTextException { byte[] data = engine.processBlock(in, inOff, inLen); byte[] block; // // as we may have zeros in our leading bytes for the block we produced // on encryption, we need to make sure our decrypted block comes back // the same size. // if (data.length < engine.getOutputBlockSize()) { block = new byte[engine.getOutputBlockSize()]; System.arraycopy(data, 0, block, block.length - data.length, data.length); } else { block = data; } if (block.length < (2 * defHash.length) + 1) { throw new InvalidCipherTextException("data too short"); } // // unmask the seed. // byte[] mask = maskGeneratorFunction1( block, defHash.length, block.length - defHash.length, defHash.length); for (int i = 0; i != defHash.length; i++) { block[i] ^= mask[i]; } // // unmask the message block. // mask = maskGeneratorFunction1(block, 0, defHash.length, block.length - defHash.length); for (int i = defHash.length; i != block.length; i++) { block[i] ^= mask[i - defHash.length]; } // // check the hash of the encoding params. // long check to try to avoid this been a source of a timing attack. // boolean defHashWrong = false; for (int i = 0; i != defHash.length; i++) { if (defHash[i] != block[defHash.length + i]) { defHashWrong = true; } } if (defHashWrong) { throw new InvalidCipherTextException("data hash wrong"); } // // find the data block // int start; for (start = 2 * defHash.length; start != block.length; start++) { if (block[start] != 0) { break; } } if (start >= (block.length - 1) || block[start] != 1) { throw new InvalidCipherTextException("data start wrong " + start); } start++; // // extract the data block // byte[] output = new byte[block.length - start]; System.arraycopy(block, start, output, 0, output.length); return output; } /** * int to octet string. */ private void ItoOSP( int i, byte[] sp) { sp[0] = (byte)(i >>> 24); sp[1] = (byte)(i >>> 16); sp[2] = (byte)(i >>> 8); sp[3] = (byte)(i >>> 0); } /** * mask generator function, as described in PKCS1v2. */ private byte[] maskGeneratorFunction1( byte[] Z, int zOff, int zLen, int length) { byte[] mask = new byte[length]; byte[] hashBuf = new byte[mgf1Hash.getDigestSize()]; byte[] C = new byte[4]; int counter = 0; mgf1Hash.reset(); while (counter < (length / hashBuf.length)) { ItoOSP(counter, C); mgf1Hash.update(Z, zOff, zLen); mgf1Hash.update(C, 0, C.length); mgf1Hash.doFinal(hashBuf, 0); System.arraycopy(hashBuf, 0, mask, counter * hashBuf.length, hashBuf.length); counter++; } if ((counter * hashBuf.length) < length) { ItoOSP(counter, C); mgf1Hash.update(Z, zOff, zLen); mgf1Hash.update(C, 0, C.length); mgf1Hash.doFinal(hashBuf, 0); System.arraycopy(hashBuf, 0, mask, counter * hashBuf.length, mask.length - (counter * hashBuf.length)); } return mask; } } bouncycastle-1.49.orig/src/org/bouncycastle/crypto/encodings/package.html0000644000175000017500000000013010262753175026256 0ustar ebourgebourg Block encodings for asymmetric ciphers. bouncycastle-1.49.orig/src/org/bouncycastle/crypto/Signer.java0000644000175000017500000000211410262753175024122 0ustar ebourgebourgpackage org.bouncycastle.crypto; /** * Generic signer interface for hash based and message recovery signers. */ public interface Signer { /** * Initialise the signer for signing or verification. * * @param forSigning true if for signing, false otherwise * @param param necessary parameters. */ public void init(boolean forSigning, CipherParameters param); /** * update the internal digest with the byte b */ public void update(byte b); /** * update the internal digest with the byte array in */ public void update(byte[] in, int off, int len); /** * generate a signature for the message we've been loaded with using * the key we were initialised with. */ public byte[] generateSignature() throws CryptoException, DataLengthException; /** * return true if the internal state represents the signature described * in the passed in array. */ public boolean verifySignature(byte[] signature); /** * reset the internal state */ public void reset(); } bouncycastle-1.49.orig/src/org/bouncycastle/crypto/Commitment.java0000644000175000017500000000161612150001736025000 0ustar ebourgebourgpackage org.bouncycastle.crypto; /** * General holding class for a commitment. */ public class Commitment { private final byte[] secret; private final byte[] commitment; /** * Base constructor. * * @param secret an encoding of the secret required to reveal the commitment. * @param commitment an encoding of the sealed commitment. */ public Commitment(byte[] secret, byte[] commitment) { this.secret = secret; this.commitment = commitment; } /** * The secret required to reveal the commitment. * * @return an encoding of the secret associated with the commitment. */ public byte[] getSecret() { return secret; } /** * The sealed commitment. * * @return an encoding of the sealed commitment. */ public byte[] getCommitment() { return commitment; } } bouncycastle-1.49.orig/src/org/bouncycastle/crypto/ec/0000755000175000017500000000000012152033551022406 5ustar ebourgebourgbouncycastle-1.49.orig/src/org/bouncycastle/crypto/ec/ECElGamalEncryptor.java0000644000175000017500000000424612132741703026702 0ustar ebourgebourgpackage org.bouncycastle.crypto.ec; import java.math.BigInteger; import java.security.SecureRandom; import org.bouncycastle.crypto.CipherParameters; import org.bouncycastle.crypto.params.ECPublicKeyParameters; import org.bouncycastle.crypto.params.ParametersWithRandom; import org.bouncycastle.math.ec.ECConstants; import org.bouncycastle.math.ec.ECPoint; /** * this does your basic ElGamal encryption algorithm using EC */ public class ECElGamalEncryptor implements ECEncryptor { private ECPublicKeyParameters key; private SecureRandom random; /** * initialise the encryptor. * * @param param the necessary EC key parameters. */ public void init( CipherParameters param) { if (param instanceof ParametersWithRandom) { ParametersWithRandom p = (ParametersWithRandom)param; if (!(p.getParameters() instanceof ECPublicKeyParameters)) { throw new IllegalArgumentException("ECPublicKeyParameters are required for encryption."); } this.key = (ECPublicKeyParameters)p.getParameters(); this.random = p.getRandom(); } else { if (!(param instanceof ECPublicKeyParameters)) { throw new IllegalArgumentException("ECPublicKeyParameters are required for encryption."); } this.key = (ECPublicKeyParameters)param; this.random = new SecureRandom(); } } /** * Process a single EC point using the basic ElGamal algorithm. * * @param point the EC point to process. * @return the result of the Elgamal process. */ public ECPair encrypt(ECPoint point) { if (key == null) { throw new IllegalStateException("ECElGamalEncryptor not initialised"); } BigInteger n = key.getParameters().getN(); BigInteger k = ECUtil.generateK(n, random); ECPoint g = key.getParameters().getG(); ECPoint gamma = g.multiply(k); ECPoint phi = key.getQ().multiply(k).add(point); return new ECPair(gamma, phi); } } bouncycastle-1.49.orig/src/org/bouncycastle/crypto/ec/ECElGamalDecryptor.java0000644000175000017500000000231712132741703026665 0ustar ebourgebourgpackage org.bouncycastle.crypto.ec; import org.bouncycastle.crypto.CipherParameters; import org.bouncycastle.crypto.params.ECPrivateKeyParameters; import org.bouncycastle.math.ec.ECPoint; /** * this does your basic decryption ElGamal style using EC */ public class ECElGamalDecryptor implements ECDecryptor { private ECPrivateKeyParameters key; /** * initialise the decryptor. * * @param param the necessary EC key parameters. */ public void init( CipherParameters param) { if (!(param instanceof ECPrivateKeyParameters)) { throw new IllegalArgumentException("ECPrivateKeyParameters are required for decryption."); } this.key = (ECPrivateKeyParameters)param; } /** * Decrypt an EC pair producing the original EC point. * * @param pair the EC point pair to process. * @return the result of the Elgamal process. */ public ECPoint decrypt(ECPair pair) { if (key == null) { throw new IllegalStateException("ECElGamalDecryptor not initialised"); } ECPoint tmp = pair.getX().multiply(key.getD()); return pair.getY().add(tmp.negate()); } } bouncycastle-1.49.orig/src/org/bouncycastle/crypto/ec/ECPair.java0000644000175000017500000000126712146342027024366 0ustar ebourgebourgpackage org.bouncycastle.crypto.ec; import org.bouncycastle.math.ec.ECPoint; public class ECPair { private final ECPoint x; private final ECPoint y; public ECPair(ECPoint x, ECPoint y) { this.x = x; this.y = y; } public ECPoint getX() { return x; } public ECPoint getY() { return y; } public byte[] getEncoded() { byte[] xEnc = x.getEncoded(); byte[] yEnc = y.getEncoded(); byte[] full = new byte[xEnc.length + yEnc.length]; System.arraycopy(xEnc, 0, full, 0, xEnc.length); System.arraycopy(yEnc, 0, full, xEnc.length, yEnc.length); return full; } } bouncycastle-1.49.orig/src/org/bouncycastle/crypto/ec/ECNewPublicKeyTransform.java0000644000175000017500000000453612151274317027734 0ustar ebourgebourgpackage org.bouncycastle.crypto.ec; import java.math.BigInteger; import java.security.SecureRandom; import org.bouncycastle.crypto.CipherParameters; import org.bouncycastle.crypto.params.ECPublicKeyParameters; import org.bouncycastle.crypto.params.ParametersWithRandom; import org.bouncycastle.math.ec.ECPoint; /** * this does your basic Elgamal encryption algorithm using EC */ public class ECNewPublicKeyTransform implements ECPairTransform { private ECPublicKeyParameters key; private SecureRandom random; /** * initialise the EC Elgamal engine. * * @param param the necessary EC key parameters. */ public void init( CipherParameters param) { if (param instanceof ParametersWithRandom) { ParametersWithRandom p = (ParametersWithRandom)param; if (!(p.getParameters() instanceof ECPublicKeyParameters)) { throw new IllegalArgumentException("ECPublicKeyParameters are required for new public key transform."); } this.key = (ECPublicKeyParameters)p.getParameters(); this.random = p.getRandom(); } else { if (!(param instanceof ECPublicKeyParameters)) { throw new IllegalArgumentException("ECPublicKeyParameters are required for new public key transform."); } this.key = (ECPublicKeyParameters)param; this.random = new SecureRandom(); } } /** * Transform an existing cipher test pair using the ElGamal algorithm. Note: the input cipherText will * need to be preserved in order to complete the transformation to the new public key. * * @param cipherText the EC point to process. * @return returns a new ECPair representing the result of the process. */ public ECPair transform(ECPair cipherText) { if (key == null) { throw new IllegalStateException("ECNewPublicKeyTransform not initialised"); } BigInteger n = key.getParameters().getN(); BigInteger k = ECUtil.generateK(n, random); ECPoint g = key.getParameters().getG(); ECPoint gamma = g.multiply(k); ECPoint phi = key.getQ().multiply(k).add(cipherText.getY()); return new ECPair(gamma, phi); } } bouncycastle-1.49.orig/src/org/bouncycastle/crypto/ec/ECEncryptor.java0000644000175000017500000000035512132703027025451 0ustar ebourgebourgpackage org.bouncycastle.crypto.ec; import org.bouncycastle.crypto.CipherParameters; import org.bouncycastle.math.ec.ECPoint; public interface ECEncryptor { void init(CipherParameters params); ECPair encrypt(ECPoint point); } bouncycastle-1.49.orig/src/org/bouncycastle/crypto/ec/ECDecryptor.java0000644000175000017500000000036212132702773025444 0ustar ebourgebourgpackage org.bouncycastle.crypto.ec; import org.bouncycastle.crypto.CipherParameters; import org.bouncycastle.math.ec.ECPoint; public interface ECDecryptor { void init(CipherParameters params); ECPoint decrypt(ECPair cipherText); } bouncycastle-1.49.orig/src/org/bouncycastle/crypto/ec/ECPairTransform.java0000644000175000017500000000031612132702436026253 0ustar ebourgebourgpackage org.bouncycastle.crypto.ec; import org.bouncycastle.crypto.CipherParameters; public interface ECPairTransform { void init(CipherParameters params); ECPair transform(ECPair cipherText); } bouncycastle-1.49.orig/src/org/bouncycastle/crypto/ec/ECUtil.java0000644000175000017500000000102612132704126024376 0ustar ebourgebourgpackage org.bouncycastle.crypto.ec; import java.math.BigInteger; import java.security.SecureRandom; import org.bouncycastle.math.ec.ECConstants; class ECUtil { static BigInteger generateK(BigInteger n, SecureRandom random) { int nBitLength = n.bitLength(); BigInteger k = new BigInteger(nBitLength, random); while (k.equals(ECConstants.ZERO) || (k.compareTo(n) >= 0)) { k = new BigInteger(nBitLength, random); } return k; } } bouncycastle-1.49.orig/src/org/bouncycastle/crypto/ec/package.html0000644000175000017500000000017712151566150024701 0ustar ebourgebourg Lightweight EC point operations, such as EC ElGamal and randomness transforms. bouncycastle-1.49.orig/src/org/bouncycastle/crypto/ec/ECNewRandomnessTransform.java0000644000175000017500000000464612137366047030166 0ustar ebourgebourgpackage org.bouncycastle.crypto.ec; import java.math.BigInteger; import java.security.SecureRandom; import org.bouncycastle.crypto.CipherParameters; import org.bouncycastle.crypto.params.ECPublicKeyParameters; import org.bouncycastle.crypto.params.ParametersWithRandom; import org.bouncycastle.math.ec.ECPoint; /** * this transforms the original randomness used for an ElGamal encryption. */ public class ECNewRandomnessTransform implements ECPairTransform { private ECPublicKeyParameters key; private SecureRandom random; /** * initialise the underlying EC ElGamal engine. * * @param param the necessary EC key parameters. */ public void init( CipherParameters param) { if (param instanceof ParametersWithRandom) { ParametersWithRandom p = (ParametersWithRandom)param; if (!(p.getParameters() instanceof ECPublicKeyParameters)) { throw new IllegalArgumentException("ECPublicKeyParameters are required for new randomness transform."); } this.key = (ECPublicKeyParameters)p.getParameters(); this.random = p.getRandom(); } else { if (!(param instanceof ECPublicKeyParameters)) { throw new IllegalArgumentException("ECPublicKeyParameters are required for new randomness transform."); } this.key = (ECPublicKeyParameters)param; this.random = new SecureRandom(); } } /** * Transform an existing cipher test pair using the ElGamal algorithm. Note: it is assumed this * transform has been initialised with the same public key that was used to create the original * cipher text. * * @param cipherText the EC point to process. * @return returns a new ECPair representing the result of the process. */ public ECPair transform(ECPair cipherText) { if (key == null) { throw new IllegalStateException("ECNewRandomnessTransform not initialised"); } BigInteger n = key.getParameters().getN(); BigInteger k = ECUtil.generateK(n, random); ECPoint g = key.getParameters().getG(); ECPoint gamma = g.multiply(k); ECPoint phi = key.getQ().multiply(k).add(cipherText.getY()); return new ECPair(cipherText.getX().add(gamma), phi); } } bouncycastle-1.49.orig/src/org/bouncycastle/crypto/BlockCipher.java0000644000175000017500000000346110262753175025066 0ustar ebourgebourgpackage org.bouncycastle.crypto; /** * Block cipher engines are expected to conform to this interface. */ public interface BlockCipher { /** * Initialise the cipher. * * @param forEncryption if true the cipher is initialised for * encryption, if false for decryption. * @param params the key and other data required by the cipher. * @exception IllegalArgumentException if the params argument is * inappropriate. */ public void init(boolean forEncryption, CipherParameters params) throws IllegalArgumentException; /** * Return the name of the algorithm the cipher implements. * * @return the name of the algorithm the cipher implements. */ public String getAlgorithmName(); /** * Return the block size for this cipher (in bytes). * * @return the block size for this cipher in bytes. */ public int getBlockSize(); /** * Process one block of input from the array in and write it to * the out array. * * @param in the array containing the input data. * @param inOff offset into the in array the data starts at. * @param out the array the output data will be copied into. * @param outOff the offset into the out array the output will start at. * @exception DataLengthException if there isn't enough data in in, or * space in out. * @exception IllegalStateException if the cipher isn't initialised. * @return the number of bytes processed and produced. */ public int processBlock(byte[] in, int inOff, byte[] out, int outOff) throws DataLengthException, IllegalStateException; /** * Reset the cipher. After resetting the cipher is in the same state * as it was after the last init (if there was one). */ public void reset(); } bouncycastle-1.49.orig/src/org/bouncycastle/crypto/CipherKeyGenerator.java0000644000175000017500000000143510262753175026432 0ustar ebourgebourgpackage org.bouncycastle.crypto; import java.security.SecureRandom; /** * The base class for symmetric, or secret, cipher key generators. */ public class CipherKeyGenerator { protected SecureRandom random; protected int strength; /** * initialise the key generator. * * @param param the parameters to be used for key generation */ public void init( KeyGenerationParameters param) { this.random = param.getRandom(); this.strength = (param.getStrength() + 7) / 8; } /** * generate a secret key. * * @return a byte array containing the key value. */ public byte[] generateKey() { byte[] key = new byte[strength]; random.nextBytes(key); return key; } } bouncycastle-1.49.orig/src/org/bouncycastle/crypto/BufferedAsymmetricBlockCipher.java0000644000175000017500000000770611214170723030563 0ustar ebourgebourgpackage org.bouncycastle.crypto; /** * a buffer wrapper for an asymmetric block cipher, allowing input * to be accumulated in a piecemeal fashion until final processing. */ public class BufferedAsymmetricBlockCipher { protected byte[] buf; protected int bufOff; private final AsymmetricBlockCipher cipher; /** * base constructor. * * @param cipher the cipher this buffering object wraps. */ public BufferedAsymmetricBlockCipher( AsymmetricBlockCipher cipher) { this.cipher = cipher; } /** * return the underlying cipher for the buffer. * * @return the underlying cipher for the buffer. */ public AsymmetricBlockCipher getUnderlyingCipher() { return cipher; } /** * return the amount of data sitting in the buffer. * * @return the amount of data sitting in the buffer. */ public int getBufferPosition() { return bufOff; } /** * initialise the buffer and the underlying cipher. * * @param forEncryption if true the cipher is initialised for * encryption, if false for decryption. * @param params the key and other data required by the cipher. */ public void init( boolean forEncryption, CipherParameters params) { reset(); cipher.init(forEncryption, params); // // we allow for an extra byte where people are using their own padding // mechanisms on a raw cipher. // buf = new byte[cipher.getInputBlockSize() + (forEncryption ? 1 : 0)]; bufOff = 0; } /** * returns the largest size an input block can be. * * @return maximum size for an input block. */ public int getInputBlockSize() { return cipher.getInputBlockSize(); } /** * returns the maximum size of the block produced by this cipher. * * @return maximum size of the output block produced by the cipher. */ public int getOutputBlockSize() { return cipher.getOutputBlockSize(); } /** * add another byte for processing. * * @param in the input byte. */ public void processByte( byte in) { if (bufOff >= buf.length) { throw new DataLengthException("attempt to process message too long for cipher"); } buf[bufOff++] = in; } /** * add len bytes to the buffer for processing. * * @param in the input data * @param inOff offset into the in array where the data starts * @param len the length of the block to be processed. */ public void processBytes( byte[] in, int inOff, int len) { if (len == 0) { return; } if (len < 0) { throw new IllegalArgumentException("Can't have a negative input length!"); } if (bufOff + len > buf.length) { throw new DataLengthException("attempt to process message too long for cipher"); } System.arraycopy(in, inOff, buf, bufOff, len); bufOff += len; } /** * process the contents of the buffer using the underlying * cipher. * * @return the result of the encryption/decryption process on the * buffer. * @exception InvalidCipherTextException if we are given a garbage block. */ public byte[] doFinal() throws InvalidCipherTextException { byte[] out = cipher.processBlock(buf, 0, bufOff); reset(); return out; } /** * Reset the buffer and the underlying cipher. */ public void reset() { /* * clean the buffer. */ if (buf != null) { for (int i = 0; i < buf.length; i++) { buf[i] = 0; } } bufOff = 0; } } bouncycastle-1.49.orig/src/org/bouncycastle/crypto/prng/0000755000175000017500000000000012152033551022765 5ustar ebourgebourgbouncycastle-1.49.orig/src/org/bouncycastle/crypto/prng/ThreadedSeedGenerator.java0000644000175000017500000000463512143336321030031 0ustar ebourgebourgpackage org.bouncycastle.crypto.prng; /** * A thread based seed generator - one source of randomness. *

    * Based on an idea from Marcus Lippert. *

    */ public class ThreadedSeedGenerator { private class SeedGenerator implements Runnable { private volatile int counter = 0; private volatile boolean stop = false; public void run() { while (!this.stop) { this.counter++; } } public byte[] generateSeed( int numbytes, boolean fast) { Thread t = new Thread(this); byte[] result = new byte[numbytes]; this.counter = 0; this.stop = false; int last = 0; int end; t.start(); if(fast) { end = numbytes; } else { end = numbytes * 8; } for (int i = 0; i < end; i++) { while (this.counter == last) { try { Thread.sleep(1); } catch (InterruptedException e) { // ignore } } last = this.counter; if (fast) { result[i] = (byte) (last & 0xff); } else { int bytepos = i/8; result[bytepos] = (byte) ((result[bytepos] << 1) | (last & 1)); } } stop = true; return result; } } /** * Generate seed bytes. Set fast to false for best quality. *

    * If fast is set to true, the code should be round about 8 times faster when * generating a long sequence of random bytes. 20 bytes of random values using * the fast mode take less than half a second on a Nokia e70. If fast is set to false, * it takes round about 2500 ms. *

    * @param numBytes the number of bytes to generate * @param fast true if fast mode should be used */ public byte[] generateSeed( int numBytes, boolean fast) { SeedGenerator gen = new SeedGenerator(); return gen.generateSeed(numBytes, fast); } } bouncycastle-1.49.orig/src/org/bouncycastle/crypto/prng/SP800SecureRandomBuilder.java0000644000175000017500000002346712143336321030236 0ustar ebourgebourgpackage org.bouncycastle.crypto.prng; import java.security.SecureRandom; import org.bouncycastle.crypto.BlockCipher; import org.bouncycastle.crypto.Digest; import org.bouncycastle.crypto.Mac; import org.bouncycastle.crypto.prng.drbg.CTRSP800DRBG; import org.bouncycastle.crypto.prng.drbg.DualECSP800DRBG; import org.bouncycastle.crypto.prng.drbg.HMacSP800DRBG; import org.bouncycastle.crypto.prng.drbg.HashSP800DRBG; import org.bouncycastle.crypto.prng.drbg.SP80090DRBG; /** * Builder class for making SecureRandom objects based on SP 800-90A Deterministic Random Bit Generators (DRBG). */ public class SP800SecureRandomBuilder { private final SecureRandom random; private final EntropySourceProvider entropySourceProvider; private byte[] personalizationString; private int securityStrength = 256; private int entropyBitsRequired = 256; /** * Basic constructor, creates a builder using an EntropySourceProvider based on the default SecureRandom with * predictionResistant set to false. *

    * Any SecureRandom created from a builder constructed like this will make use of input passed to SecureRandom.setSeed() if * the default SecureRandom does for its generateSeed() call. *

    */ public SP800SecureRandomBuilder() { this(new SecureRandom(), false); } /** * Construct a builder with an EntropySourceProvider based on the passed in SecureRandom and the passed in value * for prediction resistance. *

    * Any SecureRandom created from a builder constructed like this will make use of input passed to SecureRandom.setSeed() if * the passed in SecureRandom does for its generateSeed() call. *

    * @param entropySource * @param predictionResistant */ public SP800SecureRandomBuilder(SecureRandom entropySource, boolean predictionResistant) { this.random = entropySource; this.entropySourceProvider = new BasicEntropySourceProvider(random, predictionResistant); } /** * Create a builder which makes creates the SecureRandom objects from a specified entropy source provider. *

    * Note: If this constructor is used any calls to setSeed() in the resulting SecureRandom will be ignored. *

    * @param entropySourceProvider a provider of EntropySource objects. */ public SP800SecureRandomBuilder(EntropySourceProvider entropySourceProvider) { this.random = null; this.entropySourceProvider = entropySourceProvider; } /** * Set the personalization string for DRBG SecureRandoms created by this builder * @param personalizationString the personalisation string for the underlying DRBG. * @return the current builder. */ public SP800SecureRandomBuilder setPersonalizationString(byte[] personalizationString) { this.personalizationString = personalizationString; return this; } /** * Set the security strength required for DRBGs used in building SecureRandom objects. * * @param securityStrength the security strength (in bits) * @return the current builder. */ public SP800SecureRandomBuilder setSecurityStrength(int securityStrength) { this.securityStrength = securityStrength; return this; } /** * Set the amount of entropy bits required for seeding and reseeding DRBGs used in building SecureRandom objects. * * @param entropyBitsRequired the number of bits of entropy to be requested from the entropy source on each seed/reseed. * @return the current builder. */ public SP800SecureRandomBuilder setEntropyBitsRequired(int entropyBitsRequired) { this.entropyBitsRequired = entropyBitsRequired; return this; } /** * Build a SecureRandom based on a SP 800-90A Hash DRBG. * * @param digest digest algorithm to use in the DRBG underneath the SecureRandom. * @param nonce nonce value to use in DRBG construction. * @param predictionResistant specify whether the underlying DRBG in the resulting SecureRandom should reseed on each request for bytes. * @return a SecureRandom supported by a Hash DRBG. */ public SP800SecureRandom buildHash(Digest digest, byte[] nonce, boolean predictionResistant) { return new SP800SecureRandom(random, entropySourceProvider.get(entropyBitsRequired), new HashDRBGProvider(digest, nonce, personalizationString, securityStrength), predictionResistant); } /** * Build a SecureRandom based on a SP 800-90A CTR DRBG. * * @param cipher the block cipher to base the DRBG on. * @param keySizeInBits key size in bits to be used with the block cipher. * @param nonce nonce value to use in DRBG construction. * @param predictionResistant specify whether the underlying DRBG in the resulting SecureRandom should reseed on each request for bytes. * @return a SecureRandom supported by a CTR DRBG. */ public SP800SecureRandom buildCTR(BlockCipher cipher, int keySizeInBits, byte[] nonce, boolean predictionResistant) { return new SP800SecureRandom(random, entropySourceProvider.get(entropyBitsRequired), new CTRDRBGProvider(cipher, keySizeInBits, nonce, personalizationString, securityStrength), predictionResistant); } /** * Build a SecureRandom based on a SP 800-90A HMAC DRBG. * * @param hMac HMAC algorithm to use in the DRBG underneath the SecureRandom. * @param nonce nonce value to use in DRBG construction. * @param predictionResistant specify whether the underlying DRBG in the resulting SecureRandom should reseed on each request for bytes. * @return a SecureRandom supported by a HMAC DRBG. */ public SP800SecureRandom buildHMAC(Mac hMac, byte[] nonce, boolean predictionResistant) { return new SP800SecureRandom(random, entropySourceProvider.get(entropyBitsRequired), new HMacDRBGProvider(hMac, nonce, personalizationString, securityStrength), predictionResistant); } /** * Build a SecureRandom based on a SP 800-90A Dual EC DRBG. * * @param digest digest algorithm to use in the DRBG underneath the SecureRandom. * @param nonce nonce value to use in DRBG construction. * @param predictionResistant specify whether the underlying DRBG in the resulting SecureRandom should reseed on each request for bytes. * @return a SecureRandom supported by a Dual EC DRBG. */ public SP800SecureRandom buildDualEC(Digest digest, byte[] nonce, boolean predictionResistant) { return new SP800SecureRandom(random, entropySourceProvider.get(entropyBitsRequired), new DualECDRBGProvider(digest, nonce, personalizationString, securityStrength), predictionResistant); } private static class HashDRBGProvider implements DRBGProvider { private final Digest digest; private final byte[] nonce; private final byte[] personalizationString; private final int securityStrength; public HashDRBGProvider(Digest digest, byte[] nonce, byte[] personalizationString, int securityStrength) { this.digest = digest; this.nonce = nonce; this.personalizationString = personalizationString; this.securityStrength = securityStrength; } public SP80090DRBG get(EntropySource entropySource) { return new HashSP800DRBG(digest, securityStrength, entropySource, personalizationString, nonce); } } private static class DualECDRBGProvider implements DRBGProvider { private final Digest digest; private final byte[] nonce; private final byte[] personalizationString; private final int securityStrength; public DualECDRBGProvider(Digest digest, byte[] nonce, byte[] personalizationString, int securityStrength) { this.digest = digest; this.nonce = nonce; this.personalizationString = personalizationString; this.securityStrength = securityStrength; } public SP80090DRBG get(EntropySource entropySource) { return new DualECSP800DRBG(digest, securityStrength, entropySource, personalizationString, nonce); } } private static class HMacDRBGProvider implements DRBGProvider { private final Mac hMac; private final byte[] nonce; private final byte[] personalizationString; private final int securityStrength; public HMacDRBGProvider(Mac hMac, byte[] nonce, byte[] personalizationString, int securityStrength) { this.hMac = hMac; this.nonce = nonce; this.personalizationString = personalizationString; this.securityStrength = securityStrength; } public SP80090DRBG get(EntropySource entropySource) { return new HMacSP800DRBG(hMac, securityStrength, entropySource, personalizationString, nonce); } } private static class CTRDRBGProvider implements DRBGProvider { private final BlockCipher blockCipher; private final int keySizeInBits; private final byte[] nonce; private final byte[] personalizationString; private final int securityStrength; public CTRDRBGProvider(BlockCipher blockCipher, int keySizeInBits, byte[] nonce, byte[] personalizationString, int securityStrength) { this.blockCipher = blockCipher; this.keySizeInBits = keySizeInBits; this.nonce = nonce; this.personalizationString = personalizationString; this.securityStrength = securityStrength; } public SP80090DRBG get(EntropySource entropySource) { return new CTRSP800DRBG(blockCipher, keySizeInBits, securityStrength, entropySource, personalizationString, nonce); } } } bouncycastle-1.49.orig/src/org/bouncycastle/crypto/prng/EntropySourceProvider.java0000644000175000017500000000020112143336321030156 0ustar ebourgebourgpackage org.bouncycastle.crypto.prng; public interface EntropySourceProvider { EntropySource get(final int bitsRequired); } bouncycastle-1.49.orig/src/org/bouncycastle/crypto/prng/DRBGProvider.java0000644000175000017500000000025312143336321026062 0ustar ebourgebourgpackage org.bouncycastle.crypto.prng; import org.bouncycastle.crypto.prng.drbg.SP80090DRBG; interface DRBGProvider { SP80090DRBG get(EntropySource entropySource); } bouncycastle-1.49.orig/src/org/bouncycastle/crypto/prng/EntropySource.java0000644000175000017500000000106512143336321026454 0ustar ebourgebourgpackage org.bouncycastle.crypto.prng; public interface EntropySource { /** * Return whether or not this entropy source is regarded as prediction resistant. * * @return true if it is, false otherwise. */ boolean isPredictionResistant(); /** * Return a byte array of entropy. * * @return entropy bytes. */ byte[] getEntropy(); /** * Return the number of bits of entropy this source can produce. * * @return size in bits of the return value of getEntropy. */ int entropySize(); } bouncycastle-1.49.orig/src/org/bouncycastle/crypto/prng/FixedSecureRandom.java0000644000175000017500000000601312147613671027212 0ustar ebourgebourgpackage org.bouncycastle.crypto.prng; import java.io.ByteArrayOutputStream; import java.io.IOException; import java.security.SecureRandom; public class FixedSecureRandom extends SecureRandom { private byte[] _data; private int _index; private int _intPad; public FixedSecureRandom(byte[] value) { this(false, new byte[][] { value }); } public FixedSecureRandom( byte[][] values) { this(false, values); } /** * Pad the data on integer boundaries. This is necessary for the classpath project's BigInteger * implementation. */ public FixedSecureRandom( boolean intPad, byte[] value) { this(intPad, new byte[][] { value }); } /** * Pad the data on integer boundaries. This is necessary for the classpath project's BigInteger * implementation. */ public FixedSecureRandom( boolean intPad, byte[][] values) { ByteArrayOutputStream bOut = new ByteArrayOutputStream(); for (int i = 0; i != values.length; i++) { try { bOut.write(values[i]); } catch (IOException e) { throw new IllegalArgumentException("can't save value array."); } } _data = bOut.toByteArray(); if (intPad) { _intPad = _data.length % 4; } } public void nextBytes(byte[] bytes) { System.arraycopy(_data, _index, bytes, 0, bytes.length); _index += bytes.length; } // // classpath's implementation of SecureRandom doesn't currently go back to nextBytes // when next is called. We can't override next as it's a final method. // public int nextInt() { int val = 0; val |= nextValue() << 24; val |= nextValue() << 16; if (_intPad == 2) { _intPad--; } else { val |= nextValue() << 8; } if (_intPad == 1) { _intPad--; } else { val |= nextValue(); } return val; } // // classpath's implementation of SecureRandom doesn't currently go back to nextBytes // when next is called. We can't override next as it's a final method. // public long nextLong() { long val = 0; val |= (long)nextValue() << 56; val |= (long)nextValue() << 48; val |= (long)nextValue() << 40; val |= (long)nextValue() << 32; val |= (long)nextValue() << 24; val |= (long)nextValue() << 16; val |= (long)nextValue() << 8; val |= (long)nextValue(); return val; } public boolean isExhausted() { return _index == _data.length; } private int nextValue() { return _data[_index++] & 0xff; } } bouncycastle-1.49.orig/src/org/bouncycastle/crypto/prng/VMPCRandomGenerator.java0000644000175000017500000001312012151551725027411 0ustar ebourgebourgpackage org.bouncycastle.crypto.prng; import org.bouncycastle.crypto.util.Pack; public class VMPCRandomGenerator implements RandomGenerator { private byte n = 0; /** * Permutation generated by code: * // First 1850 fractional digit of Pi number. * byte[] key = new BigInteger("14159265358979323846...5068006422512520511").toByteArray(); * s = 0; * P = new byte[256]; * for (int i = 0; i < 256; i++) { * P[i] = (byte) i; * } * for (int m = 0; m < 768; m++) { * s = P[(s + P[m & 0xff] + key[m % key.length]) & 0xff]; * byte temp = P[m & 0xff]; * P[m & 0xff] = P[s & 0xff]; * P[s & 0xff] = temp; * } */ private byte[] P = { (byte) 0xbb, (byte) 0x2c, (byte) 0x62, (byte) 0x7f, (byte) 0xb5, (byte) 0xaa, (byte) 0xd4, (byte) 0x0d, (byte) 0x81, (byte) 0xfe, (byte) 0xb2, (byte) 0x82, (byte) 0xcb, (byte) 0xa0, (byte) 0xa1, (byte) 0x08, (byte) 0x18, (byte) 0x71, (byte) 0x56, (byte) 0xe8, (byte) 0x49, (byte) 0x02, (byte) 0x10, (byte) 0xc4, (byte) 0xde, (byte) 0x35, (byte) 0xa5, (byte) 0xec, (byte) 0x80, (byte) 0x12, (byte) 0xb8, (byte) 0x69, (byte) 0xda, (byte) 0x2f, (byte) 0x75, (byte) 0xcc, (byte) 0xa2, (byte) 0x09, (byte) 0x36, (byte) 0x03, (byte) 0x61, (byte) 0x2d, (byte) 0xfd, (byte) 0xe0, (byte) 0xdd, (byte) 0x05, (byte) 0x43, (byte) 0x90, (byte) 0xad, (byte) 0xc8, (byte) 0xe1, (byte) 0xaf, (byte) 0x57, (byte) 0x9b, (byte) 0x4c, (byte) 0xd8, (byte) 0x51, (byte) 0xae, (byte) 0x50, (byte) 0x85, (byte) 0x3c, (byte) 0x0a, (byte) 0xe4, (byte) 0xf3, (byte) 0x9c, (byte) 0x26, (byte) 0x23, (byte) 0x53, (byte) 0xc9, (byte) 0x83, (byte) 0x97, (byte) 0x46, (byte) 0xb1, (byte) 0x99, (byte) 0x64, (byte) 0x31, (byte) 0x77, (byte) 0xd5, (byte) 0x1d, (byte) 0xd6, (byte) 0x78, (byte) 0xbd, (byte) 0x5e, (byte) 0xb0, (byte) 0x8a, (byte) 0x22, (byte) 0x38, (byte) 0xf8, (byte) 0x68, (byte) 0x2b, (byte) 0x2a, (byte) 0xc5, (byte) 0xd3, (byte) 0xf7, (byte) 0xbc, (byte) 0x6f, (byte) 0xdf, (byte) 0x04, (byte) 0xe5, (byte) 0x95, (byte) 0x3e, (byte) 0x25, (byte) 0x86, (byte) 0xa6, (byte) 0x0b, (byte) 0x8f, (byte) 0xf1, (byte) 0x24, (byte) 0x0e, (byte) 0xd7, (byte) 0x40, (byte) 0xb3, (byte) 0xcf, (byte) 0x7e, (byte) 0x06, (byte) 0x15, (byte) 0x9a, (byte) 0x4d, (byte) 0x1c, (byte) 0xa3, (byte) 0xdb, (byte) 0x32, (byte) 0x92, (byte) 0x58, (byte) 0x11, (byte) 0x27, (byte) 0xf4, (byte) 0x59, (byte) 0xd0, (byte) 0x4e, (byte) 0x6a, (byte) 0x17, (byte) 0x5b, (byte) 0xac, (byte) 0xff, (byte) 0x07, (byte) 0xc0, (byte) 0x65, (byte) 0x79, (byte) 0xfc, (byte) 0xc7, (byte) 0xcd, (byte) 0x76, (byte) 0x42, (byte) 0x5d, (byte) 0xe7, (byte) 0x3a, (byte) 0x34, (byte) 0x7a, (byte) 0x30, (byte) 0x28, (byte) 0x0f, (byte) 0x73, (byte) 0x01, (byte) 0xf9, (byte) 0xd1, (byte) 0xd2, (byte) 0x19, (byte) 0xe9, (byte) 0x91, (byte) 0xb9, (byte) 0x5a, (byte) 0xed, (byte) 0x41, (byte) 0x6d, (byte) 0xb4, (byte) 0xc3, (byte) 0x9e, (byte) 0xbf, (byte) 0x63, (byte) 0xfa, (byte) 0x1f, (byte) 0x33, (byte) 0x60, (byte) 0x47, (byte) 0x89, (byte) 0xf0, (byte) 0x96, (byte) 0x1a, (byte) 0x5f, (byte) 0x93, (byte) 0x3d, (byte) 0x37, (byte) 0x4b, (byte) 0xd9, (byte) 0xa8, (byte) 0xc1, (byte) 0x1b, (byte) 0xf6, (byte) 0x39, (byte) 0x8b, (byte) 0xb7, (byte) 0x0c, (byte) 0x20, (byte) 0xce, (byte) 0x88, (byte) 0x6e, (byte) 0xb6, (byte) 0x74, (byte) 0x8e, (byte) 0x8d, (byte) 0x16, (byte) 0x29, (byte) 0xf2, (byte) 0x87, (byte) 0xf5, (byte) 0xeb, (byte) 0x70, (byte) 0xe3, (byte) 0xfb, (byte) 0x55, (byte) 0x9f, (byte) 0xc6, (byte) 0x44, (byte) 0x4a, (byte) 0x45, (byte) 0x7d, (byte) 0xe2, (byte) 0x6b, (byte) 0x5c, (byte) 0x6c, (byte) 0x66, (byte) 0xa9, (byte) 0x8c, (byte) 0xee, (byte) 0x84, (byte) 0x13, (byte) 0xa7, (byte) 0x1e, (byte) 0x9d, (byte) 0xdc, (byte) 0x67, (byte) 0x48, (byte) 0xba, (byte) 0x2e, (byte) 0xe6, (byte) 0xa4, (byte) 0xab, (byte) 0x7c, (byte) 0x94, (byte) 0x00, (byte) 0x21, (byte) 0xef, (byte) 0xea, (byte) 0xbe, (byte) 0xca, (byte) 0x72, (byte) 0x4f, (byte) 0x52, (byte) 0x98, (byte) 0x3f, (byte) 0xc2, (byte) 0x14, (byte) 0x7b, (byte) 0x3b, (byte) 0x54 }; /** * Value generated in the same way as {@link VMPCRandomGenerator#P}; */ private byte s = (byte) 0xbe; public VMPCRandomGenerator() { } public void addSeedMaterial(byte[] seed) { for (int m = 0; m < seed.length; m++) { s = P[(s + P[n & 0xff] + seed[m]) & 0xff]; byte temp = P[n & 0xff]; P[n & 0xff] = P[s & 0xff]; P[s & 0xff] = temp; n = (byte) ((n + 1) & 0xff); } } public void addSeedMaterial(long seed) { addSeedMaterial(Pack.longToBigEndian(seed)); } public void nextBytes(byte[] bytes) { nextBytes(bytes, 0, bytes.length); } public void nextBytes(byte[] bytes, int start, int len) { synchronized (P) { int end = start + len; for (int i = start; i != end; i++) { s = P[(s + P[n & 0xff]) & 0xff]; bytes[i] = P[(P[(P[s & 0xff]) & 0xff] + 1) & 0xff]; byte temp = P[n & 0xff]; P[n & 0xff] = P[s & 0xff]; P[s & 0xff] = temp; n = (byte) ((n + 1) & 0xff); } } } } bouncycastle-1.49.orig/src/org/bouncycastle/crypto/prng/BasicEntropySourceProvider.java0000644000175000017500000000325112143336321031130 0ustar ebourgebourgpackage org.bouncycastle.crypto.prng; import java.security.SecureRandom; /** * An EntropySourceProvider where entropy generation is based on a SecureRandom output using SecureRandom.generateSeed(). */ public class BasicEntropySourceProvider implements EntropySourceProvider { private final SecureRandom _sr; private final boolean _predictionResistant; /** * Create a entropy source provider based on the passed in SecureRandom. * * @param random the SecureRandom to base EntropySource construction on. * @param isPredictionResistant boolean indicating if the SecureRandom is based on prediction resistant entropy or not (true if it is). */ public BasicEntropySourceProvider(SecureRandom random, boolean isPredictionResistant) { _sr = random; _predictionResistant = isPredictionResistant; } /** * Return an entropy source that will create bitsRequired bits of entropy on * each invocation of getEntropy(). * * @param bitsRequired size (in bits) of entropy to be created by the provided source. * @return an EntropySource that generates bitsRequired bits of entropy on each call to its getEntropy() method. */ public EntropySource get(final int bitsRequired) { return new EntropySource() { public boolean isPredictionResistant() { return _predictionResistant; } public byte[] getEntropy() { return _sr.generateSeed((bitsRequired + 7) / 8); } public int entropySize() { return bitsRequired; } }; } } bouncycastle-1.49.orig/src/org/bouncycastle/crypto/prng/ReversedWindowGenerator.java0000644000175000017500000000510012143336321030443 0ustar ebourgebourgpackage org.bouncycastle.crypto.prng; /** * Takes bytes generated by an underling RandomGenerator and reverses the order in * each small window (of configurable size). *

    * Access to internals is synchronized so a single one of these can be shared. *

    */ public class ReversedWindowGenerator implements RandomGenerator { private final RandomGenerator generator; private byte[] window; private int windowCount; public ReversedWindowGenerator( RandomGenerator generator, int windowSize) { if (generator == null) { throw new IllegalArgumentException("generator cannot be null"); } if (windowSize < 2) { throw new IllegalArgumentException("windowSize must be at least 2"); } this.generator = generator; this.window = new byte[windowSize]; } /** * Add more seed material to the generator. * * @param seed a byte array to be mixed into the generator's state. */ public void addSeedMaterial( byte[] seed) { synchronized (this) { windowCount = 0; generator.addSeedMaterial(seed); } } /** * Add more seed material to the generator. * * @param seed a long value to be mixed into the generator's state. */ public void addSeedMaterial( long seed) { synchronized (this) { windowCount = 0; generator.addSeedMaterial(seed); } } /** * Fill bytes with random values. * * @param bytes byte array to be filled. */ public void nextBytes( byte[] bytes) { doNextBytes(bytes, 0, bytes.length); } /** * Fill part of bytes with random values. * * @param bytes byte array to be filled. * @param start index to start filling at. * @param len length of segment to fill. */ public void nextBytes( byte[] bytes, int start, int len) { doNextBytes(bytes, start, len); } private void doNextBytes( byte[] bytes, int start, int len) { synchronized (this) { int done = 0; while (done < len) { if (windowCount < 1) { generator.nextBytes(window, 0, window.length); windowCount = window.length; } bytes[start + done++] = window[--windowCount]; } } } } bouncycastle-1.49.orig/src/org/bouncycastle/crypto/prng/RandomGenerator.java0000644000175000017500000000161412143336321026722 0ustar ebourgebourgpackage org.bouncycastle.crypto.prng; /** * Generic interface for objects generating random bytes. */ public interface RandomGenerator { /** * Add more seed material to the generator. * * @param seed a byte array to be mixed into the generator's state. */ void addSeedMaterial(byte[] seed); /** * Add more seed material to the generator. * * @param seed a long value to be mixed into the generator's state. */ void addSeedMaterial(long seed); /** * Fill bytes with random values. * * @param bytes byte array to be filled. */ void nextBytes(byte[] bytes); /** * Fill part of bytes with random values. * * @param bytes byte array to be filled. * @param start index to start filling at. * @param len length of segment to fill. */ void nextBytes(byte[] bytes, int start, int len); } bouncycastle-1.49.orig/src/org/bouncycastle/crypto/prng/SP800SecureRandom.java0000644000175000017500000000350612143336321026717 0ustar ebourgebourgpackage org.bouncycastle.crypto.prng; import java.security.SecureRandom; import org.bouncycastle.crypto.prng.drbg.SP80090DRBG; public class SP800SecureRandom extends SecureRandom { private final DRBGProvider drbgProvider; private final boolean predictionResistant; private final SecureRandom randomSource; private final EntropySource entropySource; private SP80090DRBG drbg; SP800SecureRandom(SecureRandom randomSource, EntropySource entropySource, DRBGProvider drbgProvider, boolean predictionResistant) { this.randomSource = randomSource; this.entropySource = entropySource; this.drbgProvider = drbgProvider; this.predictionResistant = predictionResistant; } public void setSeed(byte[] seed) { synchronized (this) { if (randomSource != null) { this.randomSource.setSeed(seed); } } } public void setSeed(long seed) { synchronized (this) { // this will happen when SecureRandom() is created if (randomSource != null) { this.randomSource.setSeed(seed); } } } public void nextBytes(byte[] bytes) { synchronized (this) { if (drbg == null) { drbg = drbgProvider.get(entropySource); } // check if a reseed is required... if (drbg.generate(bytes, null, predictionResistant) < 0) { drbg.reseed(entropySource.getEntropy()); drbg.generate(bytes, null, predictionResistant); } } } public byte[] generateSeed(int numBytes) { byte[] bytes = new byte[numBytes]; this.nextBytes(bytes); return bytes; } } bouncycastle-1.49.orig/src/org/bouncycastle/crypto/prng/DigestRandomGenerator.java0000644000175000017500000000526312143336321030066 0ustar ebourgebourgpackage org.bouncycastle.crypto.prng; import org.bouncycastle.crypto.Digest; /** * Random generation based on the digest with counter. Calling addSeedMaterial will * always increase the entropy of the hash. *

    * Internal access to the digest is synchronized so a single one of these can be shared. *

    */ public class DigestRandomGenerator implements RandomGenerator { private static long CYCLE_COUNT = 10; private long stateCounter; private long seedCounter; private Digest digest; private byte[] state; private byte[] seed; // public constructors public DigestRandomGenerator( Digest digest) { this.digest = digest; this.seed = new byte[digest.getDigestSize()]; this.seedCounter = 1; this.state = new byte[digest.getDigestSize()]; this.stateCounter = 1; } public void addSeedMaterial(byte[] inSeed) { synchronized (this) { digestUpdate(inSeed); digestUpdate(seed); digestDoFinal(seed); } } public void addSeedMaterial(long rSeed) { synchronized (this) { digestAddCounter(rSeed); digestUpdate(seed); digestDoFinal(seed); } } public void nextBytes(byte[] bytes) { nextBytes(bytes, 0, bytes.length); } public void nextBytes(byte[] bytes, int start, int len) { synchronized (this) { int stateOff = 0; generateState(); int end = start + len; for (int i = start; i != end; i++) { if (stateOff == state.length) { generateState(); stateOff = 0; } bytes[i] = state[stateOff++]; } } } private void cycleSeed() { digestUpdate(seed); digestAddCounter(seedCounter++); digestDoFinal(seed); } private void generateState() { digestAddCounter(stateCounter++); digestUpdate(state); digestUpdate(seed); digestDoFinal(state); if ((stateCounter % CYCLE_COUNT) == 0) { cycleSeed(); } } private void digestAddCounter(long seed) { for (int i = 0; i != 8; i++) { digest.update((byte)seed); seed >>>= 8; } } private void digestUpdate(byte[] inSeed) { digest.update(inSeed, 0, inSeed.length); } private void digestDoFinal(byte[] result) { digest.doFinal(result, 0); } } bouncycastle-1.49.orig/src/org/bouncycastle/crypto/prng/drbg/0000755000175000017500000000000012152033551023703 5ustar ebourgebourgbouncycastle-1.49.orig/src/org/bouncycastle/crypto/prng/drbg/SP80090DRBG.java0000644000175000017500000000141512143336335026137 0ustar ebourgebourgpackage org.bouncycastle.crypto.prng.drbg; /** * Interface to SP800-90A deterministic random bit generators. */ public interface SP80090DRBG { /** * Populate a passed in array with random data. * * @param output output array for generated bits. * @param additionalInput additional input to be added to the DRBG in this step. * @param predictionResistant true if a reseed should be forced, false otherwise. * * @return number of bits generated, -1 if a reseed required. */ int generate(byte[] output, byte[] additionalInput, boolean predictionResistant); /** * Reseed the DRBG. * * @param additionalInput additional input to be added to the DRBG in this step. */ void reseed(byte[] additionalInput); } bouncycastle-1.49.orig/src/org/bouncycastle/crypto/prng/drbg/HMacSP800DRBG.java0000644000175000017500000001144112143336335026517 0ustar ebourgebourgpackage org.bouncycastle.crypto.prng.drbg; import org.bouncycastle.crypto.Mac; import org.bouncycastle.crypto.params.KeyParameter; import org.bouncycastle.crypto.prng.EntropySource; import org.bouncycastle.util.Arrays; /** * A SP800-90A HMAC DRBG. */ public class HMacSP800DRBG implements SP80090DRBG { private final static long RESEED_MAX = 1L << (48 - 1); private final static int MAX_BITS_REQUEST = 1 << (19 - 1); private byte[] _K; private byte[] _V; private long _reseedCounter; private EntropySource _entropySource; private Mac _hMac; /** * Construct a SP800-90A Hash DRBG. *

    * Minimum entropy requirement is the security strength requested. *

    * @param hMac Hash MAC to base the DRBG on. * @param securityStrength security strength required (in bits) * @param entropySource source of entropy to use for seeding/reseeding. * @param personalizationString personalization string to distinguish this DRBG (may be null). * @param nonce nonce to further distinguish this DRBG (may be null). */ public HMacSP800DRBG(Mac hMac, int securityStrength, EntropySource entropySource, byte[] personalizationString, byte[] nonce) { if (securityStrength > Utils.getMaxSecurityStrength(hMac)) { throw new IllegalArgumentException("Requested security strength is not supported by the derivation function"); } if (entropySource.entropySize() < securityStrength) { throw new IllegalArgumentException("Not enough entropy for security strength required"); } _entropySource = entropySource; _hMac = hMac; byte[] entropy = entropySource.getEntropy(); byte[] seedMaterial = Arrays.concatenate(entropy, nonce, personalizationString); _K = new byte[hMac.getMacSize()]; _V = new byte[_K.length]; Arrays.fill(_V, (byte)1); hmac_DRBG_Update(seedMaterial); _reseedCounter = 1; } private void hmac_DRBG_Update(byte[] seedMaterial) { hmac_DRBG_Update_Func(seedMaterial, (byte)0x00); if (seedMaterial != null) { hmac_DRBG_Update_Func(seedMaterial, (byte)0x01); } } private void hmac_DRBG_Update_Func(byte[] seedMaterial, byte vValue) { _hMac.init(new KeyParameter(_K)); _hMac.update(_V, 0, _V.length); _hMac.update(vValue); if (seedMaterial != null) { _hMac.update(seedMaterial, 0, seedMaterial.length); } _hMac.doFinal(_K, 0); _hMac.init(new KeyParameter(_K)); _hMac.update(_V, 0, _V.length); _hMac.doFinal(_V, 0); } /** * Populate a passed in array with random data. * * @param output output array for generated bits. * @param additionalInput additional input to be added to the DRBG in this step. * @param predictionResistant true if a reseed should be forced, false otherwise. * * @return number of bits generated, -1 if a reseed required. */ public int generate(byte[] output, byte[] additionalInput, boolean predictionResistant) { int numberOfBits = output.length * 8; if (numberOfBits > MAX_BITS_REQUEST) { throw new IllegalArgumentException("Number of bits per request limited to " + MAX_BITS_REQUEST); } if (_reseedCounter > RESEED_MAX) { return -1; } if (predictionResistant) { reseed(additionalInput); additionalInput = null; } // 2. if (additionalInput != null) { hmac_DRBG_Update(additionalInput); } // 3. byte[] rv = new byte[output.length]; int m = output.length / _V.length; _hMac.init(new KeyParameter(_K)); for (int i = 0; i < m; i++) { _hMac.update(_V, 0, _V.length); _hMac.doFinal(_V, 0); System.arraycopy(_V, 0, rv, i * _V.length, _V.length); } if (m * _V.length < rv.length) { _hMac.update(_V, 0, _V.length); _hMac.doFinal(_V, 0); System.arraycopy(_V, 0, rv, m * _V.length, rv.length - (m * _V.length)); } hmac_DRBG_Update(additionalInput); _reseedCounter++; System.arraycopy(rv, 0, output, 0, output.length); return numberOfBits; } /** * Reseed the DRBG. * * @param additionalInput additional input to be added to the DRBG in this step. */ public void reseed(byte[] additionalInput) { byte[] entropy = _entropySource.getEntropy(); byte[] seedMaterial = Arrays.concatenate(entropy, additionalInput); hmac_DRBG_Update(seedMaterial); _reseedCounter = 1; } } bouncycastle-1.49.orig/src/org/bouncycastle/crypto/prng/drbg/HashSP800DRBG.java0000644000175000017500000002154512151551725026601 0ustar ebourgebourgpackage org.bouncycastle.crypto.prng.drbg; import java.util.Hashtable; import org.bouncycastle.crypto.Digest; import org.bouncycastle.crypto.prng.EntropySource; import org.bouncycastle.util.Arrays; import org.bouncycastle.util.Integers; /** * A SP800-90A Hash DRBG. */ public class HashSP800DRBG implements SP80090DRBG { private final static byte[] ONE = { 0x01 }; private final static long RESEED_MAX = 1L << (48 - 1); private final static int MAX_BITS_REQUEST = 1 << (19 - 1); private final static Hashtable seedlens = new Hashtable(); static { seedlens.put("SHA-1", Integers.valueOf(440)); seedlens.put("SHA-224", Integers.valueOf(440)); seedlens.put("SHA-256", Integers.valueOf(440)); seedlens.put("SHA-512/256", Integers.valueOf(440)); seedlens.put("SHA-512/224", Integers.valueOf(440)); seedlens.put("SHA-384", Integers.valueOf(888)); seedlens.put("SHA-512", Integers.valueOf(888)); } private Digest _digest; private byte[] _V; private byte[] _C; private long _reseedCounter; private EntropySource _entropySource; private int _securityStrength; private int _seedLength; /** * Construct a SP800-90A Hash DRBG. *

    * Minimum entropy requirement is the security strength requested. *

    * @param digest source digest to use for DRB stream. * @param securityStrength security strength required (in bits) * @param entropySource source of entropy to use for seeding/reseeding. * @param personalizationString personalization string to distinguish this DRBG (may be null). * @param nonce nonce to further distinguish this DRBG (may be null). */ public HashSP800DRBG(Digest digest, int securityStrength, EntropySource entropySource, byte[] personalizationString, byte[] nonce) { if (securityStrength > Utils.getMaxSecurityStrength(digest)) { throw new IllegalArgumentException("Requested security strength is not supported by the derivation function"); } if (entropySource.entropySize() < securityStrength) { throw new IllegalArgumentException("Not enough entropy for security strength required"); } _digest = digest; _entropySource = entropySource; _securityStrength = securityStrength; _seedLength = ((Integer)seedlens.get(digest.getAlgorithmName())).intValue(); // 1. seed_material = entropy_input || nonce || personalization_string. // 2. seed = Hash_df (seed_material, seedlen). // 3. V = seed. // 4. C = Hash_df ((0x00 || V), seedlen). Comment: Preceed V with a byte // of zeros. // 5. reseed_counter = 1. // 6. Return V, C, and reseed_counter as the initial_working_state byte[] entropy = entropySource.getEntropy(); byte[] seedMaterial = Arrays.concatenate(entropy, nonce, personalizationString); byte[] seed = Utils.hash_df(_digest, seedMaterial, _seedLength); _V = seed; byte[] subV = new byte[_V.length + 1]; System.arraycopy(_V, 0, subV, 1, _V.length); _C = Utils.hash_df(_digest, subV, _seedLength); _reseedCounter = 1; } /** * Populate a passed in array with random data. * * @param output output array for generated bits. * @param additionalInput additional input to be added to the DRBG in this step. * @param predictionResistant true if a reseed should be forced, false otherwise. * * @return number of bits generated, -1 if a reseed required. */ public int generate(byte[] output, byte[] additionalInput, boolean predictionResistant) { // 1. If reseed_counter > reseed_interval, then return an indication that a // reseed is required. // 2. If (additional_input != Null), then do // 2.1 w = Hash (0x02 || V || additional_input). // 2.2 V = (V + w) mod 2^seedlen // . // 3. (returned_bits) = Hashgen (requested_number_of_bits, V). // 4. H = Hash (0x03 || V). // 5. V = (V + H + C + reseed_counter) mod 2^seedlen // . // 6. reseed_counter = reseed_counter + 1. // 7. Return SUCCESS, returned_bits, and the new values of V, C, and // reseed_counter for the new_working_state. int numberOfBits = output.length*8; if (numberOfBits > MAX_BITS_REQUEST) { throw new IllegalArgumentException("Number of bits per request limited to " + MAX_BITS_REQUEST); } if (_reseedCounter > RESEED_MAX) { return -1; } if (predictionResistant) { reseed(additionalInput); additionalInput = null; } // 2. if (additionalInput != null) { byte[] newInput = new byte[1 + _V.length + additionalInput.length]; newInput[0] = 0x02; System.arraycopy(_V, 0, newInput, 1, _V.length); // TODO: inOff / inLength System.arraycopy(additionalInput, 0, newInput, 1 + _V.length, additionalInput.length); byte[] w = hash(newInput); addTo(_V, w); } // 3. byte[] rv = hashgen(_V, numberOfBits); // 4. byte[] subH = new byte[_V.length + 1]; System.arraycopy(_V, 0, subH, 1, _V.length); subH[0] = 0x03; byte[] H = hash(subH); // 5. addTo(_V, H); addTo(_V, _C); byte[] c = new byte[4]; c[0] = (byte)(_reseedCounter >> 24); c[1] = (byte)(_reseedCounter >> 16); c[2] = (byte)(_reseedCounter >> 8); c[3] = (byte)_reseedCounter; addTo(_V, c); _reseedCounter++; System.arraycopy(rv, 0, output, 0, output.length); return numberOfBits; } // this will always add the shorter length byte array mathematically to the // longer length byte array. // be careful.... private void addTo(byte[] longer, byte[] shorter) { int carry = 0; for (int i=1;i <= shorter.length; i++) // warning { int res = (longer[longer.length-i] & 0xff) + (shorter[shorter.length-i] & 0xff) + carry; carry = (res > 0xff) ? 1 : 0; longer[longer.length-i] = (byte)res; } for (int i=shorter.length+1;i <= longer.length; i++) // warning { int res = (longer[longer.length-i] & 0xff) + carry; carry = (res > 0xff) ? 1 : 0; longer[longer.length-i] = (byte)res; } } /** * Reseed the DRBG. * * @param additionalInput additional input to be added to the DRBG in this step. */ public void reseed(byte[] additionalInput) { // 1. seed_material = 0x01 || V || entropy_input || additional_input. // // 2. seed = Hash_df (seed_material, seedlen). // // 3. V = seed. // // 4. C = Hash_df ((0x00 || V), seedlen). // // 5. reseed_counter = 1. // // 6. Return V, C, and reseed_counter for the new_working_state. // // Comment: Precede with a byte of all zeros. byte[] entropy = _entropySource.getEntropy(); byte[] seedMaterial = Arrays.concatenate(ONE, _V, entropy, additionalInput); byte[] seed = Utils.hash_df(_digest, seedMaterial, _seedLength); _V = seed; byte[] subV = new byte[_V.length + 1]; subV[0] = 0x00; System.arraycopy(_V, 0, subV, 1, _V.length); _C = Utils.hash_df(_digest, subV, _seedLength); _reseedCounter = 1; } private byte[] hash(byte[] input) { _digest.update(input, 0, input.length); byte[] hash = new byte[_digest.getDigestSize()]; _digest.doFinal(hash, 0); return hash; } // 1. m = [requested_number_of_bits / outlen] // 2. data = V. // 3. W = the Null string. // 4. For i = 1 to m // 4.1 wi = Hash (data). // 4.2 W = W || wi. // 4.3 data = (data + 1) mod 2^seedlen // . // 5. returned_bits = Leftmost (requested_no_of_bits) bits of W. private byte[] hashgen(byte[] input, int lengthInBits) { int digestSize = _digest.getDigestSize(); int m = (lengthInBits / 8) / digestSize; byte[] data = new byte[input.length]; System.arraycopy(input, 0, data, 0, input.length); byte[] W = new byte[lengthInBits / 8]; byte[] dig; for (int i = 0; i <= m; i++) { dig = hash(data); int bytesToCopy = ((W.length - i * dig.length) > dig.length) ? dig.length : (W.length - i * dig.length); System.arraycopy(dig, 0, W, i * dig.length, bytesToCopy); addTo(data, ONE); } return W; } }bouncycastle-1.49.orig/src/org/bouncycastle/crypto/prng/drbg/DualECSP800DRBG.java0000644000175000017500000002531512151551725027012 0ustar ebourgebourgpackage org.bouncycastle.crypto.prng.drbg; import java.math.BigInteger; import org.bouncycastle.asn1.nist.NISTNamedCurves; import org.bouncycastle.crypto.Digest; import org.bouncycastle.crypto.prng.EntropySource; import org.bouncycastle.math.ec.ECCurve; import org.bouncycastle.math.ec.ECFieldElement; import org.bouncycastle.math.ec.ECPoint; import org.bouncycastle.util.Arrays; import org.bouncycastle.util.BigIntegers; /** * A SP800-90A Dual EC DRBG. */ public class DualECSP800DRBG implements SP80090DRBG { /* * Default P, Q values for each curve */ private static final BigInteger p256_Px = new BigInteger("6b17d1f2e12c4247f8bce6e563a440f277037d812deb33a0f4a13945d898c296", 16); private static final BigInteger p256_Py = new BigInteger("4fe342e2fe1a7f9b8ee7eb4a7c0f9e162bce33576b315ececbb6406837bf51f5", 16); private static final BigInteger p256_Qx = new BigInteger("c97445f45cdef9f0d3e05e1e585fc297235b82b5be8ff3efca67c59852018192", 16); private static final BigInteger p256_Qy = new BigInteger("b28ef557ba31dfcbdd21ac46e2a91e3c304f44cb87058ada2cb815151e610046", 16); private static final BigInteger p384_Px = new BigInteger("aa87ca22be8b05378eb1c71ef320ad746e1d3b628ba79b9859f741e082542a385502f25dbf55296c3a545e3872760ab7", 16); private static final BigInteger p384_Py = new BigInteger("3617de4a96262c6f5d9e98bf9292dc29f8f41dbd289a147ce9da3113b5f0b8c00a60b1ce1d7e819d7a431d7c90ea0e5f", 16); private static final BigInteger p384_Qx = new BigInteger("8e722de3125bddb05580164bfe20b8b432216a62926c57502ceede31c47816edd1e89769124179d0b695106428815065", 16); private static final BigInteger p384_Qy = new BigInteger("023b1660dd701d0839fd45eec36f9ee7b32e13b315dc02610aa1b636e346df671f790f84c5e09b05674dbb7e45c803dd", 16); private static final BigInteger p521_Px = new BigInteger("c6858e06b70404e9cd9e3ecb662395b4429c648139053fb521f828af606b4d3dbaa14b5e77efe75928fe1dc127a2ffa8de3348b3c1856a429bf97e7e31c2e5bd66", 16); private static final BigInteger p521_Py = new BigInteger("11839296a789a3bc0045c8a5fb42c7d1bd998f54449579b446817afbd17273e662c97ee72995ef42640c550b9013fad0761353c7086a272c24088be94769fd16650", 16); private static final BigInteger p521_Qx = new BigInteger("1b9fa3e518d683c6b65763694ac8efbaec6fab44f2276171a42726507dd08add4c3b3f4c1ebc5b1222ddba077f722943b24c3edfa0f85fe24d0c8c01591f0be6f63", 16); private static final BigInteger p521_Qy = new BigInteger("1f3bdba585295d9a1110d1df1f9430ef8442c5018976ff3437ef91b81dc0b8132c8d5c39c32d0e004a3092b7d327c0e7a4d26d2c7b69b58f9066652911e457779de", 16); private static final long RESEED_MAX = 1L << (32 - 1); private static final int MAX_ADDITIONAL_INPUT = 1 << (13 - 1); private static final int MAX_ENTROPY_LENGTH = 1 << (13 - 1); private static final int MAX_PERSONALIZATION_STRING = 1 << (13 -1); private Digest _digest; private long _reseedCounter; private EntropySource _entropySource; private int _securityStrength; private int _seedlen; private int _outlen; private ECCurve.Fp _curve; private ECPoint _P; private ECPoint _Q; private byte[] _s; private int _sLength; /** * Construct a SP800-90A Dual EC DRBG. *

    * Minimum entropy requirement is the security strength requested. *

    * @param digest source digest to use with the DRB stream. * @param securityStrength security strength required (in bits) * @param entropySource source of entropy to use for seeding/reseeding. * @param personalizationString personalization string to distinguish this DRBG (may be null). * @param nonce nonce to further distinguish this DRBG (may be null). */ public DualECSP800DRBG(Digest digest, int securityStrength, EntropySource entropySource, byte[] personalizationString, byte[] nonce) { _digest = digest; _entropySource = entropySource; _securityStrength = securityStrength; if (Utils.isTooLarge(personalizationString, MAX_PERSONALIZATION_STRING / 8)) { throw new IllegalArgumentException("Personalization string too large"); } if (entropySource.entropySize() < securityStrength || entropySource.entropySize() > MAX_ENTROPY_LENGTH) { throw new IllegalArgumentException("EntropySource must provide between " + securityStrength + " and " + MAX_ENTROPY_LENGTH + " bits"); } byte[] entropy = entropySource.getEntropy(); byte[] seedMaterial = Arrays.concatenate(entropy, nonce, personalizationString); if (securityStrength <= 128) { if (Utils.getMaxSecurityStrength(digest) < 128) { throw new IllegalArgumentException("Requested security strength is not supported by digest"); } _seedlen = 256; _outlen = 240 / 8; _curve = (ECCurve.Fp)NISTNamedCurves.getByName("P-256").getCurve(); _P = new ECPoint.Fp(_curve, new ECFieldElement.Fp(_curve.getQ(), p256_Px), new ECFieldElement.Fp(_curve.getQ(), p256_Py)); _Q = new ECPoint.Fp(_curve, new ECFieldElement.Fp(_curve.getQ(), p256_Qx), new ECFieldElement.Fp(_curve.getQ(), p256_Qy)); } else if (securityStrength <= 192) { if (Utils.getMaxSecurityStrength(digest) < 192) { throw new IllegalArgumentException("Requested security strength is not supported by digest"); } _seedlen = 384; _outlen = 368 / 8; _curve = (ECCurve.Fp)NISTNamedCurves.getByName("P-384").getCurve(); _P = new ECPoint.Fp(_curve, new ECFieldElement.Fp(_curve.getQ(), p384_Px), new ECFieldElement.Fp(_curve.getQ(), p384_Py)); _Q = new ECPoint.Fp(_curve, new ECFieldElement.Fp(_curve.getQ(), p384_Qx), new ECFieldElement.Fp(_curve.getQ(), p384_Qy)); } else if (securityStrength <= 256) { if (Utils.getMaxSecurityStrength(digest) < 256) { throw new IllegalArgumentException("Requested security strength is not supported by digest"); } _seedlen = 521; _outlen = 504 / 8; _curve = (ECCurve.Fp)NISTNamedCurves.getByName("P-521").getCurve(); _P = new ECPoint.Fp(_curve, new ECFieldElement.Fp(_curve.getQ(), p521_Px), new ECFieldElement.Fp(_curve.getQ(), p521_Py)); _Q = new ECPoint.Fp(_curve, new ECFieldElement.Fp(_curve.getQ(), p521_Qx), new ECFieldElement.Fp(_curve.getQ(), p521_Qy)); } else { throw new IllegalArgumentException("security strength cannot be greater than 256 bits"); } _s = Utils.hash_df(_digest, seedMaterial, _seedlen); _sLength = _s.length; _reseedCounter = 0; } /** * Populate a passed in array with random data. * * @param output output array for generated bits. * @param additionalInput additional input to be added to the DRBG in this step. * @param predictionResistant true if a reseed should be forced, false otherwise. * * @return number of bits generated, -1 if a reseed required. */ public int generate(byte[] output, byte[] additionalInput, boolean predictionResistant) { int numberOfBits = output.length*8; int m = output.length / _outlen; if (Utils.isTooLarge(additionalInput, MAX_ADDITIONAL_INPUT / 8)) { throw new IllegalArgumentException("Additional input too large"); } if (_reseedCounter + m > RESEED_MAX) { return -1; } if (predictionResistant) { reseed(additionalInput); additionalInput = null; } if (additionalInput != null) { // Note: we ignore the use of pad8 on the additional input as we mandate byte arrays for it. additionalInput = Utils.hash_df(_digest, additionalInput, _seedlen); } for (int i = 0; i < m; i++) { BigInteger t = new BigInteger(1, xor(_s, additionalInput)); _s = _P.multiply(t).getX().toBigInteger().toByteArray(); //System.err.println("S: " + new String(Hex.encode(_s))); byte[] r = _Q.multiply(new BigInteger(1, _s)).getX().toBigInteger().toByteArray(); if (r.length > _outlen) { System.arraycopy(r, r.length - _outlen, output, i * _outlen, _outlen); } else { System.arraycopy(r, 0, output, i * _outlen + (_outlen - r.length), r.length); } //System.err.println("R: " + new String(Hex.encode(r))); additionalInput = null; _reseedCounter++; } if (m * _outlen < output.length) { BigInteger t = new BigInteger(1, xor(_s, additionalInput)); _s = _P.multiply(t).getX().toBigInteger().toByteArray(); byte[] r = _Q.multiply(new BigInteger(1, _s)).getX().toBigInteger().toByteArray(); System.arraycopy(r, 0, output, m * _outlen, output.length - (m * _outlen)); } // Need to preserve length of S as unsigned int. _s = BigIntegers.asUnsignedByteArray(_sLength, _P.multiply(new BigInteger(1, _s)).getX().toBigInteger()); return numberOfBits; } /** * Reseed the DRBG. * * @param additionalInput additional input to be added to the DRBG in this step. */ public void reseed(byte[] additionalInput) { if (Utils.isTooLarge(additionalInput, MAX_ADDITIONAL_INPUT / 8)) { throw new IllegalArgumentException("Additional input string too large"); } byte[] entropy = _entropySource.getEntropy(); byte[] seedMaterial = Arrays.concatenate(pad8(_s, _seedlen), entropy, additionalInput); _s = Utils.hash_df(_digest, seedMaterial, _seedlen); _reseedCounter = 0; } private byte[] xor(byte[] a, byte[] b) { if (b == null) { return a; } byte[] rv = new byte[a.length]; for (int i = 0; i != rv.length; i++) { rv[i] = (byte)(a[i] ^ b[i]); } return rv; } // Note: works in place private byte[] pad8(byte[] s, int seedlen) { if (seedlen % 8 == 0) { return s; } int shift = 8 - (seedlen % 8); int carry = 0; for (int i = s.length - 1; i >= 0; i--) { int b = s[i] & 0xff; s[i] = (byte)((b << shift) | (carry >> (8 - shift))); carry = b; } return s; } } bouncycastle-1.49.orig/src/org/bouncycastle/crypto/prng/drbg/CTRSP800DRBG.java0000644000175000017500000003535212143640063026342 0ustar ebourgebourgpackage org.bouncycastle.crypto.prng.drbg; import org.bouncycastle.crypto.BlockCipher; import org.bouncycastle.crypto.params.KeyParameter; import org.bouncycastle.crypto.prng.EntropySource; import org.bouncycastle.util.Arrays; import org.bouncycastle.util.encoders.Hex; /** * A SP800-90A CTR DRBG. */ public class CTRSP800DRBG implements SP80090DRBG { private static final long TDEA_RESEED_MAX = 1L << (32 - 1); private static final long AES_RESEED_MAX = 1L << (48 - 1); private static final int TDEA_MAX_BITS_REQUEST = 1 << (13 - 1); private static final int AES_MAX_BITS_REQUEST = 1 << (19 - 1); private EntropySource _entropySource; private BlockCipher _engine; private int _keySizeInBits; private int _seedLength; // internal state private byte[] _Key; private byte[] _V; private long _reseedCounter = 0; private boolean _isTDEA = false; /** * Construct a SP800-90A CTR DRBG. *

    * Minimum entropy requirement is the security strength requested. *

    * @param engine underlying block cipher to use to support DRBG * @param keySizeInBits size of the key to use with the block cipher. * @param securityStrength security strength required (in bits) * @param entropySource source of entropy to use for seeding/reseeding. * @param personalizationString personalization string to distinguish this DRBG (may be null). * @param nonce nonce to further distinguish this DRBG (may be null). */ public CTRSP800DRBG(BlockCipher engine, int keySizeInBits, int securityStrength, EntropySource entropySource, byte[] personalizationString, byte[] nonce) { _entropySource = entropySource; _engine = engine; _keySizeInBits = keySizeInBits; _seedLength = keySizeInBits + engine.getBlockSize() * 8; _isTDEA = isTDEA(engine); if (securityStrength > 256) { throw new IllegalArgumentException("Requested security strength is not supported by the derivation function"); } if (getMaxSecurityStrength(engine, keySizeInBits) < securityStrength) { throw new IllegalArgumentException("Requested security strength is not supported by block cipher and key size"); } if (entropySource.entropySize() < securityStrength) { throw new IllegalArgumentException("Not enough entropy for security strength required"); } byte[] entropy = entropySource.getEntropy(); // Get_entropy_input CTR_DRBG_Instantiate_algorithm(entropy, nonce, personalizationString); } private void CTR_DRBG_Instantiate_algorithm(byte[] entropy, byte[] nonce, byte[] personalisationString) { byte[] seedMaterial = Arrays.concatenate(entropy, nonce, personalisationString); byte[] seed = Block_Cipher_df(seedMaterial, _seedLength); int outlen = _engine.getBlockSize(); _Key = new byte[(_keySizeInBits + 7) / 8]; _V = new byte[outlen]; // _Key & _V are modified by this call CTR_DRBG_Update(seed, _Key, _V); _reseedCounter = 1; } private void CTR_DRBG_Update(byte[] seed, byte[] key, byte[] v) { byte[] temp = new byte[seed.length]; byte[] outputBlock = new byte[_engine.getBlockSize()]; int i=0; int outLen = _engine.getBlockSize(); _engine.init(true, new KeyParameter(expandKey(key))); while (i*outLen < seed.length) { addOneTo(v); _engine.processBlock(v, 0, outputBlock, 0); int bytesToCopy = ((temp.length - i * outLen) > outLen) ? outLen : (temp.length - i * outLen); System.arraycopy(outputBlock, 0, temp, i * outLen, bytesToCopy); ++i; } XOR(temp, seed, temp, 0); System.arraycopy(temp, 0, key, 0, key.length); System.arraycopy(temp, key.length, v, 0, v.length); } private void CTR_DRBG_Reseed_algorithm(EntropySource entropy, byte[] additionalInput) { byte[] seedMaterial = Arrays.concatenate(entropy.getEntropy(), additionalInput); seedMaterial = Block_Cipher_df(seedMaterial, _seedLength); CTR_DRBG_Update(seedMaterial, _Key, _V); _reseedCounter = 1; } private void XOR(byte[] out, byte[] a, byte[] b, int bOff) { for (int i=0; i< out.length; i++) { out[i] = (byte)(a[i] ^ b[i+bOff]); } } private void addOneTo(byte[] longer) { int carry = 1; for (int i = 1; i <= longer.length; i++) // warning { int res = (longer[longer.length - i] & 0xff) + carry; carry = (res > 0xff) ? 1 : 0; longer[longer.length - i] = (byte)res; } } // -- Internal state migration --- private static final byte[] K_BITS = Hex.decode("000102030405060708090A0B0C0D0E0F101112131415161718191A1B1C1D1E1F"); // 1. If (number_of_bits_to_return > max_number_of_bits), then return an // ERROR_FLAG. // 2. L = len (input_string)/8. // 3. N = number_of_bits_to_return/8. // Comment: L is the bitstring represention of // the integer resulting from len (input_string)/8. // L shall be represented as a 32-bit integer. // // Comment : N is the bitstring represention of // the integer resulting from // number_of_bits_to_return/8. N shall be // represented as a 32-bit integer. // // 4. S = L || N || input_string || 0x80. // 5. While (len (S) mod outlen) // Comment : Pad S with zeros, if necessary. // 0, S = S || 0x00. // // Comment : Compute the starting value. // 6. temp = the Null string. // 7. i = 0. // 8. K = Leftmost keylen bits of 0x00010203...1D1E1F. // 9. While len (temp) < keylen + outlen, do // // IV = i || 0outlen - len (i). // // 9.1 // // temp = temp || BCC (K, (IV || S)). // // 9.2 // // i = i + 1. // // 9.3 // // Comment : i shall be represented as a 32-bit // integer, i.e., len (i) = 32. // // Comment: The 32-bit integer represenation of // i is padded with zeros to outlen bits. // // Comment: Compute the requested number of // bits. // // 10. K = Leftmost keylen bits of temp. // // 11. X = Next outlen bits of temp. // // 12. temp = the Null string. // // 13. While len (temp) < number_of_bits_to_return, do // // 13.1 X = Block_Encrypt (K, X). // // 13.2 temp = temp || X. // // 14. requested_bits = Leftmost number_of_bits_to_return of temp. // // 15. Return SUCCESS and requested_bits. private byte[] Block_Cipher_df(byte[] inputString, int bitLength) { int outLen = _engine.getBlockSize(); int L = inputString.length; // already in bytes int N = bitLength / 8; // 4 S = L || N || inputstring || 0x80 int sLen = 4 + 4 + L + 1; int blockLen = ((sLen + outLen - 1) / outLen) * outLen; byte[] S = new byte[blockLen]; copyIntToByteArray(S, L, 0); copyIntToByteArray(S, N, 4); System.arraycopy(inputString, 0, S, 8, L); S[8 + L] = (byte)0x80; // S already padded with zeros byte[] temp = new byte[_keySizeInBits / 8 + outLen]; byte[] bccOut = new byte[outLen]; byte[] IV = new byte[outLen]; int i = 0; byte[] K = new byte[_keySizeInBits / 8]; System.arraycopy(K_BITS, 0, K, 0, K.length); while (i*outLen*8 < _keySizeInBits + outLen *8) { copyIntToByteArray(IV, i, 0); BCC(bccOut, K, IV, S); int bytesToCopy = ((temp.length - i * outLen) > outLen) ? outLen : (temp.length - i * outLen); System.arraycopy(bccOut, 0, temp, i * outLen, bytesToCopy); ++i; } byte[] X = new byte[outLen]; System.arraycopy(temp, 0, K, 0, K.length); System.arraycopy(temp, K.length, X, 0, X.length); temp = new byte[bitLength / 2]; i = 0; _engine.init(true, new KeyParameter(expandKey(K))); while (i * outLen < temp.length) { _engine.processBlock(X, 0, X, 0); int bytesToCopy = ((temp.length - i * outLen) > outLen) ? outLen : (temp.length - i * outLen); System.arraycopy(X, 0, temp, i * outLen, bytesToCopy); i++; } return temp; } /* * 1. chaining_value = 0^outlen * . Comment: Set the first chaining value to outlen zeros. * 2. n = len (data)/outlen. * 3. Starting with the leftmost bits of data, split the data into n blocks of outlen bits * each, forming block(1) to block(n). * 4. For i = 1 to n do * 4.1 input_block = chaining_value ^ block(i) . * 4.2 chaining_value = Block_Encrypt (Key, input_block). * 5. output_block = chaining_value. * 6. Return output_block. */ private void BCC(byte[] bccOut, byte[] k, byte[] iV, byte[] data) { int outlen = _engine.getBlockSize(); byte[] chainingValue = new byte[outlen]; // initial values = 0 int n = data.length / outlen; byte[] inputBlock = new byte[outlen]; _engine.init(true, new KeyParameter(expandKey(k))); _engine.processBlock(iV, 0, chainingValue, 0); for (int i = 0; i < n; i++) { XOR(inputBlock, chainingValue, data, i*outlen); _engine.processBlock(inputBlock, 0, chainingValue, 0); } System.arraycopy(chainingValue, 0, bccOut, 0, bccOut.length); } private void copyIntToByteArray(byte[] buf, int value, int offSet) { buf[offSet + 0] = ((byte)(value >> 24)); buf[offSet + 1] = ((byte)(value >> 16)); buf[offSet + 2] = ((byte)(value >> 8)); buf[offSet + 3] = ((byte)(value)); } /** * Populate a passed in array with random data. * * @param output output array for generated bits. * @param additionalInput additional input to be added to the DRBG in this step. * @param predictionResistant true if a reseed should be forced, false otherwise. * * @return number of bits generated, -1 if a reseed required. */ public int generate(byte[] output, byte[] additionalInput, boolean predictionResistant) { if (_isTDEA) { if (_reseedCounter > TDEA_RESEED_MAX) { return -1; } if (Utils.isTooLarge(output, TDEA_MAX_BITS_REQUEST / 8)) { throw new IllegalArgumentException("Number of bits per request limited to " + TDEA_MAX_BITS_REQUEST); } } else { if (_reseedCounter > AES_RESEED_MAX) { return -1; } if (Utils.isTooLarge(output, AES_MAX_BITS_REQUEST / 8)) { throw new IllegalArgumentException("Number of bits per request limited to " + AES_MAX_BITS_REQUEST); } } if (predictionResistant) { CTR_DRBG_Reseed_algorithm(_entropySource, additionalInput); additionalInput = null; } if (additionalInput != null) { additionalInput = Block_Cipher_df(additionalInput, _seedLength); CTR_DRBG_Update(additionalInput, _Key, _V); } else { additionalInput = new byte[_seedLength]; } byte[] out = new byte[_V.length]; _engine.init(true, new KeyParameter(expandKey(_Key))); for (int i = 0; i < output.length / out.length; i++) { addOneTo(_V); _engine.processBlock(_V, 0, out, 0); int bytesToCopy = ((output.length - i * out.length) > out.length) ? out.length : (output.length - i * _V.length); System.arraycopy(out, 0, output, i * out.length, bytesToCopy); } CTR_DRBG_Update(additionalInput, _Key, _V); _reseedCounter++; return output.length * 8; } /** * Reseed the DRBG. * * @param additionalInput additional input to be added to the DRBG in this step. */ public void reseed(byte[] additionalInput) { CTR_DRBG_Reseed_algorithm(_entropySource, additionalInput); } private boolean isTDEA(BlockCipher cipher) { return cipher.getAlgorithmName().equals("DESede") || cipher.getAlgorithmName().equals("TDEA"); } private int getMaxSecurityStrength(BlockCipher cipher, int keySizeInBits) { if (isTDEA(cipher) && keySizeInBits == 168) { return 112; } if (cipher.getAlgorithmName().equals("AES")) { return keySizeInBits; } return -1; } byte[] expandKey(byte[] key) { if (_isTDEA) { // expand key to 192 bits. byte[] tmp = new byte[24]; padKey(key, 0, tmp, 0); padKey(key, 7, tmp, 8); padKey(key, 14, tmp, 16); return tmp; } else { return key; } } /** * Pad out a key for TDEA, setting odd parity for each byte. * * @param keyMaster * @param keyOff * @param tmp * @param tmpOff */ private void padKey(byte[] keyMaster, int keyOff, byte[] tmp, int tmpOff) { tmp[tmpOff + 0] = (byte)(keyMaster[keyOff + 0] & 0xfe); tmp[tmpOff + 1] = (byte)((keyMaster[keyOff + 0] << 7) | ((keyMaster[keyOff + 1] & 0xfc) >>> 1)); tmp[tmpOff + 2] = (byte)((keyMaster[keyOff + 1] << 6) | ((keyMaster[keyOff + 2] & 0xf8) >>> 2)); tmp[tmpOff + 3] = (byte)((keyMaster[keyOff + 2] << 5) | ((keyMaster[keyOff + 3] & 0xf0) >>> 3)); tmp[tmpOff + 4] = (byte)((keyMaster[keyOff + 3] << 4) | ((keyMaster[keyOff + 4] & 0xe0) >>> 4)); tmp[tmpOff + 5] = (byte)((keyMaster[keyOff + 4] << 3) | ((keyMaster[keyOff + 5] & 0xc0) >>> 5)); tmp[tmpOff + 6] = (byte)((keyMaster[keyOff + 5] << 2) | ((keyMaster[keyOff + 6] & 0x80) >>> 6)); tmp[tmpOff + 7] = (byte)(keyMaster[keyOff + 6] << 1); for (int i = tmpOff; i <= tmpOff + 7; i++) { int b = tmp[i]; tmp[i] = (byte)((b & 0xfe) | ((((b >> 1) ^ (b >> 2) ^ (b >> 3) ^ (b >> 4) ^ (b >> 5) ^ (b >> 6) ^ (b >> 7)) ^ 0x01) & 0x01)); } } } bouncycastle-1.49.orig/src/org/bouncycastle/crypto/prng/drbg/Utils.java0000644000175000017500000000620312143336335025655 0ustar ebourgebourgpackage org.bouncycastle.crypto.prng.drbg; import java.util.Hashtable; import org.bouncycastle.crypto.Digest; import org.bouncycastle.crypto.Mac; import org.bouncycastle.util.Integers; class Utils { static final Hashtable maxSecurityStrengths = new Hashtable(); static { maxSecurityStrengths.put("SHA-1", Integers.valueOf(128)); maxSecurityStrengths.put("SHA-224", Integers.valueOf(192)); maxSecurityStrengths.put("SHA-256", Integers.valueOf(256)); maxSecurityStrengths.put("SHA-384", Integers.valueOf(256)); maxSecurityStrengths.put("SHA-512", Integers.valueOf(256)); maxSecurityStrengths.put("SHA-512/224", Integers.valueOf(192)); maxSecurityStrengths.put("SHA-512/256", Integers.valueOf(256)); } static int getMaxSecurityStrength(Digest d) { return ((Integer)maxSecurityStrengths.get(d.getAlgorithmName())).intValue(); } static int getMaxSecurityStrength(Mac m) { String name = m.getAlgorithmName(); return ((Integer)maxSecurityStrengths.get(name.substring(0, name.indexOf("/")))).intValue(); } /** * Used by both Dual EC and Hash. */ static byte[] hash_df(Digest digest, byte[] seedMaterial, int seedLength) { // 1. temp = the Null string. // 2. . // 3. counter = an 8-bit binary value representing the integer "1". // 4. For i = 1 to len do // Comment : In step 4.1, no_of_bits_to_return // is used as a 32-bit string. // 4.1 temp = temp || Hash (counter || no_of_bits_to_return || // input_string). // 4.2 counter = counter + 1. // 5. requested_bits = Leftmost (no_of_bits_to_return) of temp. // 6. Return SUCCESS and requested_bits. byte[] temp = new byte[(seedLength + 7) / 8]; int len = temp.length / digest.getDigestSize(); int counter = 1; byte[] dig = new byte[digest.getDigestSize()]; for (int i = 0; i <= len; i++) { digest.update((byte)counter); digest.update((byte)(seedLength >> 24)); digest.update((byte)(seedLength >> 16)); digest.update((byte)(seedLength >> 8)); digest.update((byte)seedLength); digest.update(seedMaterial, 0, seedMaterial.length); digest.doFinal(dig, 0); int bytesToCopy = ((temp.length - i * dig.length) > dig.length) ? dig.length : (temp.length - i * dig.length); System.arraycopy(dig, 0, temp, i * dig.length, bytesToCopy); counter++; } // do a left shift to get rid of excess bits. if (seedLength % 8 != 0) { int shift = 8 - (seedLength % 8); int carry = 0; for (int i = 0; i != temp.length; i++) { int b = temp[i] & 0xff; temp[i] = (byte)((b >>> shift) | (carry << (8 - shift))); carry = b; } } return temp; } static boolean isTooLarge(byte[] bytes, int maxBytes) { return bytes != null && bytes.length > maxBytes; } } bouncycastle-1.49.orig/src/org/bouncycastle/crypto/prng/drbg/package.html0000644000175000017500000000014712151565715026201 0ustar ebourgebourg NIST Deterministic Random Bit Generators (SP 800-90A). bouncycastle-1.49.orig/src/org/bouncycastle/crypto/prng/package.html0000644000175000017500000000020412151566015025247 0ustar ebourgebourg Lightweight psuedo-random number generators and SecureRandom variants and builders. bouncycastle-1.49.orig/src/org/bouncycastle/crypto/digests/0000755000175000017500000000000012152033551023461 5ustar ebourgebourgbouncycastle-1.49.orig/src/org/bouncycastle/crypto/digests/NullDigest.java0000644000175000017500000000150011334526663026406 0ustar ebourgebourgpackage org.bouncycastle.crypto.digests; import java.io.ByteArrayOutputStream; import org.bouncycastle.crypto.Digest; public class NullDigest implements Digest { private ByteArrayOutputStream bOut = new ByteArrayOutputStream(); public String getAlgorithmName() { return "NULL"; } public int getDigestSize() { return bOut.size(); } public void update(byte in) { bOut.write(in); } public void update(byte[] in, int inOff, int len) { bOut.write(in, inOff, len); } public int doFinal(byte[] out, int outOff) { byte[] res = bOut.toByteArray(); System.arraycopy(res, 0, out, outOff, res.length); reset(); return res.length; } public void reset() { bOut.reset(); } }bouncycastle-1.49.orig/src/org/bouncycastle/crypto/digests/WhirlpoolDigest.java0000644000175000017500000003304712143604417027457 0ustar ebourgebourgpackage org.bouncycastle.crypto.digests; import org.bouncycastle.crypto.ExtendedDigest; import org.bouncycastle.util.Arrays; import org.bouncycastle.util.Memoable; /** * Implementation of WhirlpoolDigest, based on Java source published by Barreto * and Rijmen. * */ public final class WhirlpoolDigest implements ExtendedDigest, Memoable { private static final int BYTE_LENGTH = 64; private static final int DIGEST_LENGTH_BYTES = 512 / 8; private static final int ROUNDS = 10; private static final int REDUCTION_POLYNOMIAL = 0x011d; // 2^8 + 2^4 + 2^3 + 2 + 1; private static final int[] SBOX = { 0x18, 0x23, 0xc6, 0xe8, 0x87, 0xb8, 0x01, 0x4f, 0x36, 0xa6, 0xd2, 0xf5, 0x79, 0x6f, 0x91, 0x52, 0x60, 0xbc, 0x9b, 0x8e, 0xa3, 0x0c, 0x7b, 0x35, 0x1d, 0xe0, 0xd7, 0xc2, 0x2e, 0x4b, 0xfe, 0x57, 0x15, 0x77, 0x37, 0xe5, 0x9f, 0xf0, 0x4a, 0xda, 0x58, 0xc9, 0x29, 0x0a, 0xb1, 0xa0, 0x6b, 0x85, 0xbd, 0x5d, 0x10, 0xf4, 0xcb, 0x3e, 0x05, 0x67, 0xe4, 0x27, 0x41, 0x8b, 0xa7, 0x7d, 0x95, 0xd8, 0xfb, 0xee, 0x7c, 0x66, 0xdd, 0x17, 0x47, 0x9e, 0xca, 0x2d, 0xbf, 0x07, 0xad, 0x5a, 0x83, 0x33, 0x63, 0x02, 0xaa, 0x71, 0xc8, 0x19, 0x49, 0xd9, 0xf2, 0xe3, 0x5b, 0x88, 0x9a, 0x26, 0x32, 0xb0, 0xe9, 0x0f, 0xd5, 0x80, 0xbe, 0xcd, 0x34, 0x48, 0xff, 0x7a, 0x90, 0x5f, 0x20, 0x68, 0x1a, 0xae, 0xb4, 0x54, 0x93, 0x22, 0x64, 0xf1, 0x73, 0x12, 0x40, 0x08, 0xc3, 0xec, 0xdb, 0xa1, 0x8d, 0x3d, 0x97, 0x00, 0xcf, 0x2b, 0x76, 0x82, 0xd6, 0x1b, 0xb5, 0xaf, 0x6a, 0x50, 0x45, 0xf3, 0x30, 0xef, 0x3f, 0x55, 0xa2, 0xea, 0x65, 0xba, 0x2f, 0xc0, 0xde, 0x1c, 0xfd, 0x4d, 0x92, 0x75, 0x06, 0x8a, 0xb2, 0xe6, 0x0e, 0x1f, 0x62, 0xd4, 0xa8, 0x96, 0xf9, 0xc5, 0x25, 0x59, 0x84, 0x72, 0x39, 0x4c, 0x5e, 0x78, 0x38, 0x8c, 0xd1, 0xa5, 0xe2, 0x61, 0xb3, 0x21, 0x9c, 0x1e, 0x43, 0xc7, 0xfc, 0x04, 0x51, 0x99, 0x6d, 0x0d, 0xfa, 0xdf, 0x7e, 0x24, 0x3b, 0xab, 0xce, 0x11, 0x8f, 0x4e, 0xb7, 0xeb, 0x3c, 0x81, 0x94, 0xf7, 0xb9, 0x13, 0x2c, 0xd3, 0xe7, 0x6e, 0xc4, 0x03, 0x56, 0x44, 0x7f, 0xa9, 0x2a, 0xbb, 0xc1, 0x53, 0xdc, 0x0b, 0x9d, 0x6c, 0x31, 0x74, 0xf6, 0x46, 0xac, 0x89, 0x14, 0xe1, 0x16, 0x3a, 0x69, 0x09, 0x70, 0xb6, 0xd0, 0xed, 0xcc, 0x42, 0x98, 0xa4, 0x28, 0x5c, 0xf8, 0x86 }; private static final long[] C0 = new long[256]; private static final long[] C1 = new long[256]; private static final long[] C2 = new long[256]; private static final long[] C3 = new long[256]; private static final long[] C4 = new long[256]; private static final long[] C5 = new long[256]; private static final long[] C6 = new long[256]; private static final long[] C7 = new long[256]; private final long[] _rc = new long[ROUNDS + 1]; public WhirlpoolDigest() { for (int i = 0; i < 256; i++) { int v1 = SBOX[i]; int v2 = maskWithReductionPolynomial(v1 << 1); int v4 = maskWithReductionPolynomial(v2 << 1); int v5 = v4 ^ v1; int v8 = maskWithReductionPolynomial(v4 << 1); int v9 = v8 ^ v1; C0[i] = packIntoLong(v1, v1, v4, v1, v8, v5, v2, v9); C1[i] = packIntoLong(v9, v1, v1, v4, v1, v8, v5, v2); C2[i] = packIntoLong(v2, v9, v1, v1, v4, v1, v8, v5); C3[i] = packIntoLong(v5, v2, v9, v1, v1, v4, v1, v8); C4[i] = packIntoLong(v8, v5, v2, v9, v1, v1, v4, v1); C5[i] = packIntoLong(v1, v8, v5, v2, v9, v1, v1, v4); C6[i] = packIntoLong(v4, v1, v8, v5, v2, v9, v1, v1); C7[i] = packIntoLong(v1, v4, v1, v8, v5, v2, v9, v1); } _rc[0] = 0L; for (int r = 1; r <= ROUNDS; r++) { int i = 8 * (r - 1); _rc[r] = (C0[i ] & 0xff00000000000000L) ^ (C1[i + 1] & 0x00ff000000000000L) ^ (C2[i + 2] & 0x0000ff0000000000L) ^ (C3[i + 3] & 0x000000ff00000000L) ^ (C4[i + 4] & 0x00000000ff000000L) ^ (C5[i + 5] & 0x0000000000ff0000L) ^ (C6[i + 6] & 0x000000000000ff00L) ^ (C7[i + 7] & 0x00000000000000ffL); } } private long packIntoLong(int b7, int b6, int b5, int b4, int b3, int b2, int b1, int b0) { return ((long)b7 << 56) ^ ((long)b6 << 48) ^ ((long)b5 << 40) ^ ((long)b4 << 32) ^ ((long)b3 << 24) ^ ((long)b2 << 16) ^ ((long)b1 << 8) ^ b0; } /* * int's are used to prevent sign extension. The values that are really being used are * actually just 0..255 */ private int maskWithReductionPolynomial(int input) { int rv = input; if (rv >= 0x100L) // high bit set { rv ^= REDUCTION_POLYNOMIAL; // reduced by the polynomial } return rv; } // --------------------------------------------------------------------------------------// // -- buffer information -- private static final int BITCOUNT_ARRAY_SIZE = 32; private byte[] _buffer = new byte[64]; private int _bufferPos = 0; private short[] _bitCount = new short[BITCOUNT_ARRAY_SIZE]; // -- internal hash state -- private long[] _hash = new long[8]; private long[] _K = new long[8]; // the round key private long[] _L = new long[8]; private long[] _block = new long[8]; // mu (buffer) private long[] _state = new long[8]; // the current "cipher" state /** * Copy constructor. This will copy the state of the provided message * digest. */ public WhirlpoolDigest(WhirlpoolDigest originalDigest) { reset(originalDigest); } public String getAlgorithmName() { return "Whirlpool"; } public int getDigestSize() { return DIGEST_LENGTH_BYTES; } public int doFinal(byte[] out, int outOff) { // sets out[outOff] .. out[outOff+DIGEST_LENGTH_BYTES] finish(); for (int i = 0; i < 8; i++) { convertLongToByteArray(_hash[i], out, outOff + (i * 8)); } reset(); return getDigestSize(); } /** * reset the chaining variables */ public void reset() { // set variables to null, blank, whatever _bufferPos = 0; Arrays.fill(_bitCount, (short)0); Arrays.fill(_buffer, (byte)0); Arrays.fill(_hash, 0); Arrays.fill(_K, 0); Arrays.fill(_L, 0); Arrays.fill(_block, 0); Arrays.fill(_state, 0); } // this takes a buffer of information and fills the block private void processFilledBuffer(byte[] in, int inOff) { // copies into the block... for (int i = 0; i < _state.length; i++) { _block[i] = bytesToLongFromBuffer(_buffer, i * 8); } processBlock(); _bufferPos = 0; Arrays.fill(_buffer, (byte)0); } private long bytesToLongFromBuffer(byte[] buffer, int startPos) { long rv = (((buffer[startPos + 0] & 0xffL) << 56) | ((buffer[startPos + 1] & 0xffL) << 48) | ((buffer[startPos + 2] & 0xffL) << 40) | ((buffer[startPos + 3] & 0xffL) << 32) | ((buffer[startPos + 4] & 0xffL) << 24) | ((buffer[startPos + 5] & 0xffL) << 16) | ((buffer[startPos + 6] & 0xffL) << 8) | ((buffer[startPos + 7]) & 0xffL)); return rv; } private void convertLongToByteArray(long inputLong, byte[] outputArray, int offSet) { for (int i = 0; i < 8; i++) { outputArray[offSet + i] = (byte)((inputLong >> (56 - (i * 8))) & 0xff); } } protected void processBlock() { // buffer contents have been transferred to the _block[] array via // processFilledBuffer // compute and apply K^0 for (int i = 0; i < 8; i++) { _state[i] = _block[i] ^ (_K[i] = _hash[i]); } // iterate over the rounds for (int round = 1; round <= ROUNDS; round++) { for (int i = 0; i < 8; i++) { _L[i] = 0; _L[i] ^= C0[(int)(_K[(i - 0) & 7] >>> 56) & 0xff]; _L[i] ^= C1[(int)(_K[(i - 1) & 7] >>> 48) & 0xff]; _L[i] ^= C2[(int)(_K[(i - 2) & 7] >>> 40) & 0xff]; _L[i] ^= C3[(int)(_K[(i - 3) & 7] >>> 32) & 0xff]; _L[i] ^= C4[(int)(_K[(i - 4) & 7] >>> 24) & 0xff]; _L[i] ^= C5[(int)(_K[(i - 5) & 7] >>> 16) & 0xff]; _L[i] ^= C6[(int)(_K[(i - 6) & 7] >>> 8) & 0xff]; _L[i] ^= C7[(int)(_K[(i - 7) & 7]) & 0xff]; } System.arraycopy(_L, 0, _K, 0, _K.length); _K[0] ^= _rc[round]; // apply the round transformation for (int i = 0; i < 8; i++) { _L[i] = _K[i]; _L[i] ^= C0[(int)(_state[(i - 0) & 7] >>> 56) & 0xff]; _L[i] ^= C1[(int)(_state[(i - 1) & 7] >>> 48) & 0xff]; _L[i] ^= C2[(int)(_state[(i - 2) & 7] >>> 40) & 0xff]; _L[i] ^= C3[(int)(_state[(i - 3) & 7] >>> 32) & 0xff]; _L[i] ^= C4[(int)(_state[(i - 4) & 7] >>> 24) & 0xff]; _L[i] ^= C5[(int)(_state[(i - 5) & 7] >>> 16) & 0xff]; _L[i] ^= C6[(int)(_state[(i - 6) & 7] >>> 8) & 0xff]; _L[i] ^= C7[(int)(_state[(i - 7) & 7]) & 0xff]; } // save the current state System.arraycopy(_L, 0, _state, 0, _state.length); } // apply Miuaguchi-Preneel compression for (int i = 0; i < 8; i++) { _hash[i] ^= _state[i] ^ _block[i]; } } public void update(byte in) { _buffer[_bufferPos] = in; //System.out.println("adding to buffer = "+_buffer[_bufferPos]); ++_bufferPos; if (_bufferPos == _buffer.length) { processFilledBuffer(_buffer, 0); } increment(); } /* * increment() can be implemented in this way using 2 arrays or * by having some temporary variables that are used to set the * value provided by EIGHT[i] and carry within the loop. * * not having done any timing, this seems likely to be faster * at the slight expense of 32*(sizeof short) bytes */ private static final short[] EIGHT = new short[BITCOUNT_ARRAY_SIZE]; static { EIGHT[BITCOUNT_ARRAY_SIZE - 1] = 8; } private void increment() { int carry = 0; for (int i = _bitCount.length - 1; i >= 0; i--) { int sum = (_bitCount[i] & 0xff) + EIGHT[i] + carry; carry = sum >>> 8; _bitCount[i] = (short)(sum & 0xff); } } public void update(byte[] in, int inOff, int len) { while (len > 0) { update(in[inOff]); ++inOff; --len; } } private void finish() { /* * this makes a copy of the current bit length. at the expense of an * object creation of 32 bytes rather than providing a _stopCounting * boolean which was the alternative I could think of. */ byte[] bitLength = copyBitLength(); _buffer[_bufferPos++] |= 0x80; if (_bufferPos == _buffer.length) { processFilledBuffer(_buffer, 0); } /* * Final block contains * [ ... data .... ][0][0][0][ length ] * * if [ length ] cannot fit. Need to create a new block. */ if (_bufferPos > 32) { while (_bufferPos != 0) { update((byte)0); } } while (_bufferPos <= 32) { update((byte)0); } // copy the length information to the final 32 bytes of the // 64 byte block.... System.arraycopy(bitLength, 0, _buffer, 32, bitLength.length); processFilledBuffer(_buffer, 0); } private byte[] copyBitLength() { byte[] rv = new byte[BITCOUNT_ARRAY_SIZE]; for (int i = 0; i < rv.length; i++) { rv[i] = (byte)(_bitCount[i] & 0xff); } return rv; } public int getByteLength() { return BYTE_LENGTH; } public Memoable copy() { return new WhirlpoolDigest(this); } public void reset(Memoable other) { WhirlpoolDigest originalDigest = (WhirlpoolDigest)other; System.arraycopy(originalDigest._rc, 0, _rc, 0, _rc.length); System.arraycopy(originalDigest._buffer, 0, _buffer, 0, _buffer.length); this._bufferPos = originalDigest._bufferPos; System.arraycopy(originalDigest._bitCount, 0, _bitCount, 0, _bitCount.length); // -- internal hash state -- System.arraycopy(originalDigest._hash, 0, _hash, 0, _hash.length); System.arraycopy(originalDigest._K, 0, _K, 0, _K.length); System.arraycopy(originalDigest._L, 0, _L, 0, _L.length); System.arraycopy(originalDigest._block, 0, _block, 0, _block.length); System.arraycopy(originalDigest._state, 0, _state, 0, _state.length); } } bouncycastle-1.49.orig/src/org/bouncycastle/crypto/digests/SHA1Digest.java0000644000175000017500000001612112143607521026165 0ustar ebourgebourgpackage org.bouncycastle.crypto.digests; import org.bouncycastle.crypto.util.Pack; import org.bouncycastle.util.Memoable; /** * implementation of SHA-1 as outlined in "Handbook of Applied Cryptography", pages 346 - 349. * * It is interesting to ponder why the, apart from the extra IV, the other difference here from MD5 * is the "endianness" of the word processing! */ public class SHA1Digest extends GeneralDigest { private static final int DIGEST_LENGTH = 20; private int H1, H2, H3, H4, H5; private int[] X = new int[80]; private int xOff; /** * Standard constructor */ public SHA1Digest() { reset(); } /** * Copy constructor. This will copy the state of the provided * message digest. */ public SHA1Digest(SHA1Digest t) { super(t); copyIn(t); } private void copyIn(SHA1Digest t) { H1 = t.H1; H2 = t.H2; H3 = t.H3; H4 = t.H4; H5 = t.H5; System.arraycopy(t.X, 0, X, 0, t.X.length); xOff = t.xOff; } public String getAlgorithmName() { return "SHA-1"; } public int getDigestSize() { return DIGEST_LENGTH; } protected void processWord( byte[] in, int inOff) { // Note: Inlined for performance // X[xOff] = Pack.bigEndianToInt(in, inOff); int n = in[ inOff] << 24; n |= (in[++inOff] & 0xff) << 16; n |= (in[++inOff] & 0xff) << 8; n |= (in[++inOff] & 0xff); X[xOff] = n; if (++xOff == 16) { processBlock(); } } protected void processLength( long bitLength) { if (xOff > 14) { processBlock(); } X[14] = (int)(bitLength >>> 32); X[15] = (int)(bitLength & 0xffffffff); } public int doFinal( byte[] out, int outOff) { finish(); Pack.intToBigEndian(H1, out, outOff); Pack.intToBigEndian(H2, out, outOff + 4); Pack.intToBigEndian(H3, out, outOff + 8); Pack.intToBigEndian(H4, out, outOff + 12); Pack.intToBigEndian(H5, out, outOff + 16); reset(); return DIGEST_LENGTH; } /** * reset the chaining variables */ public void reset() { super.reset(); H1 = 0x67452301; H2 = 0xefcdab89; H3 = 0x98badcfe; H4 = 0x10325476; H5 = 0xc3d2e1f0; xOff = 0; for (int i = 0; i != X.length; i++) { X[i] = 0; } } // // Additive constants // private static final int Y1 = 0x5a827999; private static final int Y2 = 0x6ed9eba1; private static final int Y3 = 0x8f1bbcdc; private static final int Y4 = 0xca62c1d6; private int f( int u, int v, int w) { return ((u & v) | ((~u) & w)); } private int h( int u, int v, int w) { return (u ^ v ^ w); } private int g( int u, int v, int w) { return ((u & v) | (u & w) | (v & w)); } protected void processBlock() { // // expand 16 word block into 80 word block. // for (int i = 16; i < 80; i++) { int t = X[i - 3] ^ X[i - 8] ^ X[i - 14] ^ X[i - 16]; X[i] = t << 1 | t >>> 31; } // // set up working variables. // int A = H1; int B = H2; int C = H3; int D = H4; int E = H5; // // round 1 // int idx = 0; for (int j = 0; j < 4; j++) { // E = rotateLeft(A, 5) + f(B, C, D) + E + X[idx++] + Y1 // B = rotateLeft(B, 30) E += (A << 5 | A >>> 27) + f(B, C, D) + X[idx++] + Y1; B = B << 30 | B >>> 2; D += (E << 5 | E >>> 27) + f(A, B, C) + X[idx++] + Y1; A = A << 30 | A >>> 2; C += (D << 5 | D >>> 27) + f(E, A, B) + X[idx++] + Y1; E = E << 30 | E >>> 2; B += (C << 5 | C >>> 27) + f(D, E, A) + X[idx++] + Y1; D = D << 30 | D >>> 2; A += (B << 5 | B >>> 27) + f(C, D, E) + X[idx++] + Y1; C = C << 30 | C >>> 2; } // // round 2 // for (int j = 0; j < 4; j++) { // E = rotateLeft(A, 5) + h(B, C, D) + E + X[idx++] + Y2 // B = rotateLeft(B, 30) E += (A << 5 | A >>> 27) + h(B, C, D) + X[idx++] + Y2; B = B << 30 | B >>> 2; D += (E << 5 | E >>> 27) + h(A, B, C) + X[idx++] + Y2; A = A << 30 | A >>> 2; C += (D << 5 | D >>> 27) + h(E, A, B) + X[idx++] + Y2; E = E << 30 | E >>> 2; B += (C << 5 | C >>> 27) + h(D, E, A) + X[idx++] + Y2; D = D << 30 | D >>> 2; A += (B << 5 | B >>> 27) + h(C, D, E) + X[idx++] + Y2; C = C << 30 | C >>> 2; } // // round 3 // for (int j = 0; j < 4; j++) { // E = rotateLeft(A, 5) + g(B, C, D) + E + X[idx++] + Y3 // B = rotateLeft(B, 30) E += (A << 5 | A >>> 27) + g(B, C, D) + X[idx++] + Y3; B = B << 30 | B >>> 2; D += (E << 5 | E >>> 27) + g(A, B, C) + X[idx++] + Y3; A = A << 30 | A >>> 2; C += (D << 5 | D >>> 27) + g(E, A, B) + X[idx++] + Y3; E = E << 30 | E >>> 2; B += (C << 5 | C >>> 27) + g(D, E, A) + X[idx++] + Y3; D = D << 30 | D >>> 2; A += (B << 5 | B >>> 27) + g(C, D, E) + X[idx++] + Y3; C = C << 30 | C >>> 2; } // // round 4 // for (int j = 0; j <= 3; j++) { // E = rotateLeft(A, 5) + h(B, C, D) + E + X[idx++] + Y4 // B = rotateLeft(B, 30) E += (A << 5 | A >>> 27) + h(B, C, D) + X[idx++] + Y4; B = B << 30 | B >>> 2; D += (E << 5 | E >>> 27) + h(A, B, C) + X[idx++] + Y4; A = A << 30 | A >>> 2; C += (D << 5 | D >>> 27) + h(E, A, B) + X[idx++] + Y4; E = E << 30 | E >>> 2; B += (C << 5 | C >>> 27) + h(D, E, A) + X[idx++] + Y4; D = D << 30 | D >>> 2; A += (B << 5 | B >>> 27) + h(C, D, E) + X[idx++] + Y4; C = C << 30 | C >>> 2; } H1 += A; H2 += B; H3 += C; H4 += D; H5 += E; // // reset start of the buffer. // xOff = 0; for (int i = 0; i < 16; i++) { X[i] = 0; } } public Memoable copy() { return new SHA1Digest(this); } public void reset(Memoable other) { SHA1Digest d = (SHA1Digest)other; super.copyIn(d); copyIn(d); } } bouncycastle-1.49.orig/src/org/bouncycastle/crypto/digests/LongDigest.java0000644000175000017500000002112412143607521026367 0ustar ebourgebourgpackage org.bouncycastle.crypto.digests; import org.bouncycastle.crypto.ExtendedDigest; import org.bouncycastle.crypto.util.Pack; import org.bouncycastle.util.Memoable; /** * Base class for SHA-384 and SHA-512. */ public abstract class LongDigest implements ExtendedDigest, Memoable { private static final int BYTE_LENGTH = 128; private byte[] xBuf; private int xBufOff; private long byteCount1; private long byteCount2; protected long H1, H2, H3, H4, H5, H6, H7, H8; private long[] W = new long[80]; private int wOff; /** * Constructor for variable length word */ protected LongDigest() { xBuf = new byte[8]; xBufOff = 0; reset(); } /** * Copy constructor. We are using copy constructors in place * of the Object.clone() interface as this interface is not * supported by J2ME. */ protected LongDigest(LongDigest t) { xBuf = new byte[t.xBuf.length]; copyIn(t); } protected void copyIn(LongDigest t) { System.arraycopy(t.xBuf, 0, xBuf, 0, t.xBuf.length); xBufOff = t.xBufOff; byteCount1 = t.byteCount1; byteCount2 = t.byteCount2; H1 = t.H1; H2 = t.H2; H3 = t.H3; H4 = t.H4; H5 = t.H5; H6 = t.H6; H7 = t.H7; H8 = t.H8; System.arraycopy(t.W, 0, W, 0, t.W.length); wOff = t.wOff; } public void update( byte in) { xBuf[xBufOff++] = in; if (xBufOff == xBuf.length) { processWord(xBuf, 0); xBufOff = 0; } byteCount1++; } public void update( byte[] in, int inOff, int len) { // // fill the current word // while ((xBufOff != 0) && (len > 0)) { update(in[inOff]); inOff++; len--; } // // process whole words. // while (len > xBuf.length) { processWord(in, inOff); inOff += xBuf.length; len -= xBuf.length; byteCount1 += xBuf.length; } // // load in the remainder. // while (len > 0) { update(in[inOff]); inOff++; len--; } } public void finish() { adjustByteCounts(); long lowBitLength = byteCount1 << 3; long hiBitLength = byteCount2; // // add the pad bytes. // update((byte)128); while (xBufOff != 0) { update((byte)0); } processLength(lowBitLength, hiBitLength); processBlock(); } public void reset() { byteCount1 = 0; byteCount2 = 0; xBufOff = 0; for (int i = 0; i < xBuf.length; i++) { xBuf[i] = 0; } wOff = 0; for (int i = 0; i != W.length; i++) { W[i] = 0; } } public int getByteLength() { return BYTE_LENGTH; } protected void processWord( byte[] in, int inOff) { W[wOff] = Pack.bigEndianToLong(in, inOff); if (++wOff == 16) { processBlock(); } } /** * adjust the byte counts so that byteCount2 represents the * upper long (less 3 bits) word of the byte count. */ private void adjustByteCounts() { if (byteCount1 > 0x1fffffffffffffffL) { byteCount2 += (byteCount1 >>> 61); byteCount1 &= 0x1fffffffffffffffL; } } protected void processLength( long lowW, long hiW) { if (wOff > 14) { processBlock(); } W[14] = hiW; W[15] = lowW; } protected void processBlock() { adjustByteCounts(); // // expand 16 word block into 80 word blocks. // for (int t = 16; t <= 79; t++) { W[t] = Sigma1(W[t - 2]) + W[t - 7] + Sigma0(W[t - 15]) + W[t - 16]; } // // set up working variables. // long a = H1; long b = H2; long c = H3; long d = H4; long e = H5; long f = H6; long g = H7; long h = H8; int t = 0; for(int i = 0; i < 10; i ++) { // t = 8 * i h += Sum1(e) + Ch(e, f, g) + K[t] + W[t++]; d += h; h += Sum0(a) + Maj(a, b, c); // t = 8 * i + 1 g += Sum1(d) + Ch(d, e, f) + K[t] + W[t++]; c += g; g += Sum0(h) + Maj(h, a, b); // t = 8 * i + 2 f += Sum1(c) + Ch(c, d, e) + K[t] + W[t++]; b += f; f += Sum0(g) + Maj(g, h, a); // t = 8 * i + 3 e += Sum1(b) + Ch(b, c, d) + K[t] + W[t++]; a += e; e += Sum0(f) + Maj(f, g, h); // t = 8 * i + 4 d += Sum1(a) + Ch(a, b, c) + K[t] + W[t++]; h += d; d += Sum0(e) + Maj(e, f, g); // t = 8 * i + 5 c += Sum1(h) + Ch(h, a, b) + K[t] + W[t++]; g += c; c += Sum0(d) + Maj(d, e, f); // t = 8 * i + 6 b += Sum1(g) + Ch(g, h, a) + K[t] + W[t++]; f += b; b += Sum0(c) + Maj(c, d, e); // t = 8 * i + 7 a += Sum1(f) + Ch(f, g, h) + K[t] + W[t++]; e += a; a += Sum0(b) + Maj(b, c, d); } H1 += a; H2 += b; H3 += c; H4 += d; H5 += e; H6 += f; H7 += g; H8 += h; // // reset the offset and clean out the word buffer. // wOff = 0; for (int i = 0; i < 16; i++) { W[i] = 0; } } /* SHA-384 and SHA-512 functions (as for SHA-256 but for longs) */ private long Ch( long x, long y, long z) { return ((x & y) ^ ((~x) & z)); } private long Maj( long x, long y, long z) { return ((x & y) ^ (x & z) ^ (y & z)); } private long Sum0( long x) { return ((x << 36)|(x >>> 28)) ^ ((x << 30)|(x >>> 34)) ^ ((x << 25)|(x >>> 39)); } private long Sum1( long x) { return ((x << 50)|(x >>> 14)) ^ ((x << 46)|(x >>> 18)) ^ ((x << 23)|(x >>> 41)); } private long Sigma0( long x) { return ((x << 63)|(x >>> 1)) ^ ((x << 56)|(x >>> 8)) ^ (x >>> 7); } private long Sigma1( long x) { return ((x << 45)|(x >>> 19)) ^ ((x << 3)|(x >>> 61)) ^ (x >>> 6); } /* SHA-384 and SHA-512 Constants * (represent the first 64 bits of the fractional parts of the * cube roots of the first sixty-four prime numbers) */ static final long K[] = { 0x428a2f98d728ae22L, 0x7137449123ef65cdL, 0xb5c0fbcfec4d3b2fL, 0xe9b5dba58189dbbcL, 0x3956c25bf348b538L, 0x59f111f1b605d019L, 0x923f82a4af194f9bL, 0xab1c5ed5da6d8118L, 0xd807aa98a3030242L, 0x12835b0145706fbeL, 0x243185be4ee4b28cL, 0x550c7dc3d5ffb4e2L, 0x72be5d74f27b896fL, 0x80deb1fe3b1696b1L, 0x9bdc06a725c71235L, 0xc19bf174cf692694L, 0xe49b69c19ef14ad2L, 0xefbe4786384f25e3L, 0x0fc19dc68b8cd5b5L, 0x240ca1cc77ac9c65L, 0x2de92c6f592b0275L, 0x4a7484aa6ea6e483L, 0x5cb0a9dcbd41fbd4L, 0x76f988da831153b5L, 0x983e5152ee66dfabL, 0xa831c66d2db43210L, 0xb00327c898fb213fL, 0xbf597fc7beef0ee4L, 0xc6e00bf33da88fc2L, 0xd5a79147930aa725L, 0x06ca6351e003826fL, 0x142929670a0e6e70L, 0x27b70a8546d22ffcL, 0x2e1b21385c26c926L, 0x4d2c6dfc5ac42aedL, 0x53380d139d95b3dfL, 0x650a73548baf63deL, 0x766a0abb3c77b2a8L, 0x81c2c92e47edaee6L, 0x92722c851482353bL, 0xa2bfe8a14cf10364L, 0xa81a664bbc423001L, 0xc24b8b70d0f89791L, 0xc76c51a30654be30L, 0xd192e819d6ef5218L, 0xd69906245565a910L, 0xf40e35855771202aL, 0x106aa07032bbd1b8L, 0x19a4c116b8d2d0c8L, 0x1e376c085141ab53L, 0x2748774cdf8eeb99L, 0x34b0bcb5e19b48a8L, 0x391c0cb3c5c95a63L, 0x4ed8aa4ae3418acbL, 0x5b9cca4f7763e373L, 0x682e6ff3d6b2b8a3L, 0x748f82ee5defb2fcL, 0x78a5636f43172f60L, 0x84c87814a1f0ab72L, 0x8cc702081a6439ecL, 0x90befffa23631e28L, 0xa4506cebde82bde9L, 0xbef9a3f7b2c67915L, 0xc67178f2e372532bL, 0xca273eceea26619cL, 0xd186b8c721c0c207L, 0xeada7dd6cde0eb1eL, 0xf57d4f7fee6ed178L, 0x06f067aa72176fbaL, 0x0a637dc5a2c898a6L, 0x113f9804bef90daeL, 0x1b710b35131c471bL, 0x28db77f523047d84L, 0x32caab7b40c72493L, 0x3c9ebe0a15c9bebcL, 0x431d67c49c100d4cL, 0x4cc5d4becb3e42b6L, 0x597f299cfc657e2aL, 0x5fcb6fab3ad6faecL, 0x6c44198c4a475817L }; } bouncycastle-1.49.orig/src/org/bouncycastle/crypto/digests/MD2Digest.java0000644000175000017500000001650212143435052026054 0ustar ebourgebourgpackage org.bouncycastle.crypto.digests; import org.bouncycastle.crypto.*; import org.bouncycastle.util.Memoable; /** * implementation of MD2 * as outlined in RFC1319 by B.Kaliski from RSA Laboratories April 1992 */ public class MD2Digest implements ExtendedDigest, Memoable { private static final int DIGEST_LENGTH = 16; /* X buffer */ private byte[] X = new byte[48]; private int xOff; /* M buffer */ private byte[] M = new byte[16]; private int mOff; /* check sum */ private byte[] C = new byte[16]; private int COff; public MD2Digest() { reset(); } public MD2Digest(MD2Digest t) { copyIn(t); } private void copyIn(MD2Digest t) { System.arraycopy(t.X, 0, X, 0, t.X.length); xOff = t.xOff; System.arraycopy(t.M, 0, M, 0, t.M.length); mOff = t.mOff; System.arraycopy(t.C, 0, C, 0, t.C.length); COff = t.COff; } /** * return the algorithm name * * @return the algorithm name */ public String getAlgorithmName() { return "MD2"; } /** * return the size, in bytes, of the digest produced by this message digest. * * @return the size, in bytes, of the digest produced by this message digest. */ public int getDigestSize() { return DIGEST_LENGTH; } /** * close the digest, producing the final digest value. The doFinal * call leaves the digest reset. * * @param out the array the digest is to be copied into. * @param outOff the offset into the out array the digest is to start at. */ public int doFinal(byte[] out, int outOff) { // add padding byte paddingByte = (byte)(M.length-mOff); for (int i=mOff;i 0)) { update(in[inOff]); inOff++; len--; } // // process whole words. // while (len > 16) { System.arraycopy(in,inOff,M,0,16); processCheckSum(M); processBlock(M); len -= 16; inOff += 16; } // // load in the remainder. // while (len > 0) { update(in[inOff]); inOff++; len--; } } protected void processCheckSum(byte[] m) { int L = C[15]; for (int i=0;i<16;i++) { C[i] ^= S[(m[i] ^ L) & 0xff]; L = C[i]; } } protected void processBlock(byte[] m) { for (int i=0;i<16;i++) { X[i+16] = m[i]; X[i+32] = (byte)(m[i] ^ X[i]); } // encrypt block int t = 0; for (int j=0;j<18;j++) { for (int k=0;k<48;k++) { t = X[k] ^= S[t]; t = t & 0xff; } t = (t + j)%256; } } // 256-byte random permutation constructed from the digits of PI private static final byte[] S = { (byte)41,(byte)46,(byte)67,(byte)201,(byte)162,(byte)216,(byte)124, (byte)1,(byte)61,(byte)54,(byte)84,(byte)161,(byte)236,(byte)240, (byte)6,(byte)19,(byte)98,(byte)167,(byte)5,(byte)243,(byte)192, (byte)199,(byte)115,(byte)140,(byte)152,(byte)147,(byte)43,(byte)217, (byte)188,(byte)76,(byte)130,(byte)202,(byte)30,(byte)155,(byte)87, (byte)60,(byte)253,(byte)212,(byte)224,(byte)22,(byte)103,(byte)66, (byte)111,(byte)24,(byte)138,(byte)23,(byte)229,(byte)18,(byte)190, (byte)78,(byte)196,(byte)214,(byte)218,(byte)158,(byte)222,(byte)73, (byte)160,(byte)251,(byte)245,(byte)142,(byte)187,(byte)47,(byte)238, (byte)122,(byte)169,(byte)104,(byte)121,(byte)145,(byte)21,(byte)178, (byte)7,(byte)63,(byte)148,(byte)194,(byte)16,(byte)137,(byte)11, (byte)34,(byte)95,(byte)33,(byte)128,(byte)127,(byte)93,(byte)154, (byte)90,(byte)144,(byte)50,(byte)39,(byte)53,(byte)62,(byte)204, (byte)231,(byte)191,(byte)247,(byte)151,(byte)3,(byte)255,(byte)25, (byte)48,(byte)179,(byte)72,(byte)165,(byte)181,(byte)209,(byte)215, (byte)94,(byte)146,(byte)42,(byte)172,(byte)86,(byte)170,(byte)198, (byte)79,(byte)184,(byte)56,(byte)210,(byte)150,(byte)164,(byte)125, (byte)182,(byte)118,(byte)252,(byte)107,(byte)226,(byte)156,(byte)116, (byte)4,(byte)241,(byte)69,(byte)157,(byte)112,(byte)89,(byte)100, (byte)113,(byte)135,(byte)32,(byte)134,(byte)91,(byte)207,(byte)101, (byte)230,(byte)45,(byte)168,(byte)2,(byte)27,(byte)96,(byte)37, (byte)173,(byte)174,(byte)176,(byte)185,(byte)246,(byte)28,(byte)70, (byte)97,(byte)105,(byte)52,(byte)64,(byte)126,(byte)15,(byte)85, (byte)71,(byte)163,(byte)35,(byte)221,(byte)81,(byte)175,(byte)58, (byte)195,(byte)92,(byte)249,(byte)206,(byte)186,(byte)197,(byte)234, (byte)38,(byte)44,(byte)83,(byte)13,(byte)110,(byte)133,(byte)40, (byte)132, 9,(byte)211,(byte)223,(byte)205,(byte)244,(byte)65, (byte)129,(byte)77,(byte)82,(byte)106,(byte)220,(byte)55,(byte)200, (byte)108,(byte)193,(byte)171,(byte)250,(byte)36,(byte)225,(byte)123, (byte)8,(byte)12,(byte)189,(byte)177,(byte)74,(byte)120,(byte)136, (byte)149,(byte)139,(byte)227,(byte)99,(byte)232,(byte)109,(byte)233, (byte)203,(byte)213,(byte)254,(byte)59,(byte)0,(byte)29,(byte)57, (byte)242,(byte)239,(byte)183,(byte)14,(byte)102,(byte)88,(byte)208, (byte)228,(byte)166,(byte)119,(byte)114,(byte)248,(byte)235,(byte)117, (byte)75,(byte)10,(byte)49,(byte)68,(byte)80,(byte)180,(byte)143, (byte)237,(byte)31,(byte)26,(byte)219,(byte)153,(byte)141,(byte)51, (byte)159,(byte)17,(byte)131,(byte)20 }; public int getByteLength() { return 16; } public Memoable copy() { return new MD2Digest(this); } public void reset(Memoable other) { MD2Digest d = (MD2Digest)other; copyIn(d); } } bouncycastle-1.49.orig/src/org/bouncycastle/crypto/digests/GeneralDigest.java0000644000175000017500000000526012143607521027050 0ustar ebourgebourgpackage org.bouncycastle.crypto.digests; import org.bouncycastle.crypto.ExtendedDigest; import org.bouncycastle.util.Memoable; /** * base implementation of MD4 family style digest as outlined in * "Handbook of Applied Cryptography", pages 344 - 347. */ public abstract class GeneralDigest implements ExtendedDigest, Memoable { private static final int BYTE_LENGTH = 64; private byte[] xBuf; private int xBufOff; private long byteCount; /** * Standard constructor */ protected GeneralDigest() { xBuf = new byte[4]; xBufOff = 0; } /** * Copy constructor. We are using copy constructors in place * of the Object.clone() interface as this interface is not * supported by J2ME. */ protected GeneralDigest(GeneralDigest t) { xBuf = new byte[t.xBuf.length]; copyIn(t); } protected void copyIn(GeneralDigest t) { System.arraycopy(t.xBuf, 0, xBuf, 0, t.xBuf.length); xBufOff = t.xBufOff; byteCount = t.byteCount; } public void update( byte in) { xBuf[xBufOff++] = in; if (xBufOff == xBuf.length) { processWord(xBuf, 0); xBufOff = 0; } byteCount++; } public void update( byte[] in, int inOff, int len) { // // fill the current word // while ((xBufOff != 0) && (len > 0)) { update(in[inOff]); inOff++; len--; } // // process whole words. // while (len > xBuf.length) { processWord(in, inOff); inOff += xBuf.length; len -= xBuf.length; byteCount += xBuf.length; } // // load in the remainder. // while (len > 0) { update(in[inOff]); inOff++; len--; } } public void finish() { long bitLength = (byteCount << 3); // // add the pad bytes. // update((byte)128); while (xBufOff != 0) { update((byte)0); } processLength(bitLength); processBlock(); } public void reset() { byteCount = 0; xBufOff = 0; for (int i = 0; i < xBuf.length; i++) { xBuf[i] = 0; } } public int getByteLength() { return BYTE_LENGTH; } protected abstract void processWord(byte[] in, int inOff); protected abstract void processLength(long bitLength); protected abstract void processBlock(); } bouncycastle-1.49.orig/src/org/bouncycastle/crypto/digests/ShortenedDigest.java0000644000175000017500000000361610427071732027433 0ustar ebourgebourgpackage org.bouncycastle.crypto.digests; import org.bouncycastle.crypto.ExtendedDigest; /** * Wrapper class that reduces the output length of a particular digest to * only the first n bytes of the digest function. */ public class ShortenedDigest implements ExtendedDigest { private ExtendedDigest baseDigest; private int length; /** * Base constructor. * * @param baseDigest underlying digest to use. * @param length length in bytes of the output of doFinal. * @exception IllegalArgumentException if baseDigest is null, or length is greater than baseDigest.getDigestSize(). */ public ShortenedDigest( ExtendedDigest baseDigest, int length) { if (baseDigest == null) { throw new IllegalArgumentException("baseDigest must not be null"); } if (length > baseDigest.getDigestSize()) { throw new IllegalArgumentException("baseDigest output not large enough to support length"); } this.baseDigest = baseDigest; this.length = length; } public String getAlgorithmName() { return baseDigest.getAlgorithmName() + "(" + length * 8 + ")"; } public int getDigestSize() { return length; } public void update(byte in) { baseDigest.update(in); } public void update(byte[] in, int inOff, int len) { baseDigest.update(in, inOff, len); } public int doFinal(byte[] out, int outOff) { byte[] tmp = new byte[baseDigest.getDigestSize()]; baseDigest.doFinal(tmp, 0); System.arraycopy(tmp, 0, out, outOff, length); return length; } public void reset() { baseDigest.reset(); } public int getByteLength() { return baseDigest.getByteLength(); } } bouncycastle-1.49.orig/src/org/bouncycastle/crypto/digests/SHA512tDigest.java0000644000175000017500000001157212143607413026525 0ustar ebourgebourgpackage org.bouncycastle.crypto.digests; import org.bouncycastle.util.Memoable; import org.bouncycastle.util.MemoableResetException; /** * FIPS 180-4 implementation of SHA-512/t */ public class SHA512tDigest extends LongDigest { private final int digestLength; private long H1t, H2t, H3t, H4t, H5t, H6t, H7t, H8t; /** * Standard constructor */ public SHA512tDigest(int bitLength) { if (bitLength >= 512) { throw new IllegalArgumentException("bitLength cannot be >= 512"); } if (bitLength % 8 != 0) { throw new IllegalArgumentException("bitLength needs to be a multiple of 8"); } if (bitLength == 384) { throw new IllegalArgumentException("bitLength cannot be 384 use SHA384 instead"); } this.digestLength = bitLength / 8; tIvGenerate(digestLength * 8); reset(); } /** * Copy constructor. This will copy the state of the provided * message digest. */ public SHA512tDigest(SHA512tDigest t) { super(t); this.digestLength = t.digestLength; reset(t); } public String getAlgorithmName() { return "SHA-512/" + Integer.toString(digestLength * 8); } public int getDigestSize() { return digestLength; } public int doFinal( byte[] out, int outOff) { finish(); longToBigEndian(H1, out, outOff, digestLength); longToBigEndian(H2, out, outOff + 8, digestLength - 8); longToBigEndian(H3, out, outOff + 16, digestLength - 16); longToBigEndian(H4, out, outOff + 24, digestLength - 24); longToBigEndian(H5, out, outOff + 32, digestLength - 32); longToBigEndian(H6, out, outOff + 40, digestLength - 40); longToBigEndian(H7, out, outOff + 48, digestLength - 48); longToBigEndian(H8, out, outOff + 56, digestLength - 56); reset(); return digestLength; } /** * reset the chaining variables */ public void reset() { super.reset(); /* * initial hash values use the iv generation algorithm for t. */ H1 = H1t; H2 = H2t; H3 = H3t; H4 = H4t; H5 = H5t; H6 = H6t; H7 = H7t; H8 = H8t; } private void tIvGenerate(int bitLength) { H1 = 0x6a09e667f3bcc908L ^ 0xa5a5a5a5a5a5a5a5L; H2 = 0xbb67ae8584caa73bL ^ 0xa5a5a5a5a5a5a5a5L; H3 = 0x3c6ef372fe94f82bL ^ 0xa5a5a5a5a5a5a5a5L; H4 = 0xa54ff53a5f1d36f1L ^ 0xa5a5a5a5a5a5a5a5L; H5 = 0x510e527fade682d1L ^ 0xa5a5a5a5a5a5a5a5L; H6 = 0x9b05688c2b3e6c1fL ^ 0xa5a5a5a5a5a5a5a5L; H7 = 0x1f83d9abfb41bd6bL ^ 0xa5a5a5a5a5a5a5a5L; H8 = 0x5be0cd19137e2179L ^ 0xa5a5a5a5a5a5a5a5L; update((byte)0x53); update((byte)0x48); update((byte)0x41); update((byte)0x2D); update((byte)0x35); update((byte)0x31); update((byte)0x32); update((byte)0x2F); if (bitLength > 100) { update((byte)(bitLength / 100 + 0x30)); bitLength = bitLength % 100; update((byte)(bitLength / 10 + 0x30)); bitLength = bitLength % 10; update((byte)(bitLength + 0x30)); } else if (bitLength > 10) { update((byte)(bitLength / 10 + 0x30)); bitLength = bitLength % 10; update((byte)(bitLength + 0x30)); } else { update((byte)(bitLength + 0x30)); } finish(); H1t = H1; H2t = H2; H3t = H3; H4t = H4; H5t = H5; H6t = H6; H7t = H7; H8t = H8; } private static void longToBigEndian(long n, byte[] bs, int off, int max) { if (max > 0) { intToBigEndian((int)(n >>> 32), bs, off, max); if (max > 4) { intToBigEndian((int)(n & 0xffffffffL), bs, off + 4, max - 4); } } } private static void intToBigEndian(int n, byte[] bs, int off, int max) { int num = Math.min(4, max); while (--num >= 0) { int shift = 8 * (3 - num); bs[off + num] = (byte)(n >>> shift); } } public Memoable copy() { return new SHA512tDigest(this); } public void reset(Memoable other) { SHA512tDigest t = (SHA512tDigest)other; if (this.digestLength != t.digestLength) { throw new MemoableResetException("digestLength inappropriate in other"); } super.copyIn(t); this.H1t = t.H1t; this.H2t = t.H2t; this.H3t = t.H3t; this.H4t = t.H4t; this.H5t = t.H5t; this.H6t = t.H6t; this.H7t = t.H7t; this.H8t = t.H8t; } } bouncycastle-1.49.orig/src/org/bouncycastle/crypto/digests/RIPEMD160Digest.java0000644000175000017500000004113012143607521026676 0ustar ebourgebourgpackage org.bouncycastle.crypto.digests; import org.bouncycastle.util.Memoable; /** * implementation of RIPEMD see, * http://www.esat.kuleuven.ac.be/~bosselae/ripemd160.html */ public class RIPEMD160Digest extends GeneralDigest { private static final int DIGEST_LENGTH = 20; private int H0, H1, H2, H3, H4; // IV's private int[] X = new int[16]; private int xOff; /** * Standard constructor */ public RIPEMD160Digest() { reset(); } /** * Copy constructor. This will copy the state of the provided * message digest. */ public RIPEMD160Digest(RIPEMD160Digest t) { super(t); copyIn(t); } private void copyIn(RIPEMD160Digest t) { super.copyIn(t); H0 = t.H0; H1 = t.H1; H2 = t.H2; H3 = t.H3; H4 = t.H4; System.arraycopy(t.X, 0, X, 0, t.X.length); xOff = t.xOff; } public String getAlgorithmName() { return "RIPEMD160"; } public int getDigestSize() { return DIGEST_LENGTH; } protected void processWord( byte[] in, int inOff) { X[xOff++] = (in[inOff] & 0xff) | ((in[inOff + 1] & 0xff) << 8) | ((in[inOff + 2] & 0xff) << 16) | ((in[inOff + 3] & 0xff) << 24); if (xOff == 16) { processBlock(); } } protected void processLength( long bitLength) { if (xOff > 14) { processBlock(); } X[14] = (int)(bitLength & 0xffffffff); X[15] = (int)(bitLength >>> 32); } private void unpackWord( int word, byte[] out, int outOff) { out[outOff] = (byte)word; out[outOff + 1] = (byte)(word >>> 8); out[outOff + 2] = (byte)(word >>> 16); out[outOff + 3] = (byte)(word >>> 24); } public int doFinal( byte[] out, int outOff) { finish(); unpackWord(H0, out, outOff); unpackWord(H1, out, outOff + 4); unpackWord(H2, out, outOff + 8); unpackWord(H3, out, outOff + 12); unpackWord(H4, out, outOff + 16); reset(); return DIGEST_LENGTH; } /** * reset the chaining variables to the IV values. */ public void reset() { super.reset(); H0 = 0x67452301; H1 = 0xefcdab89; H2 = 0x98badcfe; H3 = 0x10325476; H4 = 0xc3d2e1f0; xOff = 0; for (int i = 0; i != X.length; i++) { X[i] = 0; } } /* * rotate int x left n bits. */ private int RL( int x, int n) { return (x << n) | (x >>> (32 - n)); } /* * f1,f2,f3,f4,f5 are the basic RIPEMD160 functions. */ /* * rounds 0-15 */ private int f1( int x, int y, int z) { return x ^ y ^ z; } /* * rounds 16-31 */ private int f2( int x, int y, int z) { return (x & y) | (~x & z); } /* * rounds 32-47 */ private int f3( int x, int y, int z) { return (x | ~y) ^ z; } /* * rounds 48-63 */ private int f4( int x, int y, int z) { return (x & z) | (y & ~z); } /* * rounds 64-79 */ private int f5( int x, int y, int z) { return x ^ (y | ~z); } protected void processBlock() { int a, aa; int b, bb; int c, cc; int d, dd; int e, ee; a = aa = H0; b = bb = H1; c = cc = H2; d = dd = H3; e = ee = H4; // // Rounds 1 - 16 // // left a = RL(a + f1(b,c,d) + X[ 0], 11) + e; c = RL(c, 10); e = RL(e + f1(a,b,c) + X[ 1], 14) + d; b = RL(b, 10); d = RL(d + f1(e,a,b) + X[ 2], 15) + c; a = RL(a, 10); c = RL(c + f1(d,e,a) + X[ 3], 12) + b; e = RL(e, 10); b = RL(b + f1(c,d,e) + X[ 4], 5) + a; d = RL(d, 10); a = RL(a + f1(b,c,d) + X[ 5], 8) + e; c = RL(c, 10); e = RL(e + f1(a,b,c) + X[ 6], 7) + d; b = RL(b, 10); d = RL(d + f1(e,a,b) + X[ 7], 9) + c; a = RL(a, 10); c = RL(c + f1(d,e,a) + X[ 8], 11) + b; e = RL(e, 10); b = RL(b + f1(c,d,e) + X[ 9], 13) + a; d = RL(d, 10); a = RL(a + f1(b,c,d) + X[10], 14) + e; c = RL(c, 10); e = RL(e + f1(a,b,c) + X[11], 15) + d; b = RL(b, 10); d = RL(d + f1(e,a,b) + X[12], 6) + c; a = RL(a, 10); c = RL(c + f1(d,e,a) + X[13], 7) + b; e = RL(e, 10); b = RL(b + f1(c,d,e) + X[14], 9) + a; d = RL(d, 10); a = RL(a + f1(b,c,d) + X[15], 8) + e; c = RL(c, 10); // right aa = RL(aa + f5(bb,cc,dd) + X[ 5] + 0x50a28be6, 8) + ee; cc = RL(cc, 10); ee = RL(ee + f5(aa,bb,cc) + X[14] + 0x50a28be6, 9) + dd; bb = RL(bb, 10); dd = RL(dd + f5(ee,aa,bb) + X[ 7] + 0x50a28be6, 9) + cc; aa = RL(aa, 10); cc = RL(cc + f5(dd,ee,aa) + X[ 0] + 0x50a28be6, 11) + bb; ee = RL(ee, 10); bb = RL(bb + f5(cc,dd,ee) + X[ 9] + 0x50a28be6, 13) + aa; dd = RL(dd, 10); aa = RL(aa + f5(bb,cc,dd) + X[ 2] + 0x50a28be6, 15) + ee; cc = RL(cc, 10); ee = RL(ee + f5(aa,bb,cc) + X[11] + 0x50a28be6, 15) + dd; bb = RL(bb, 10); dd = RL(dd + f5(ee,aa,bb) + X[ 4] + 0x50a28be6, 5) + cc; aa = RL(aa, 10); cc = RL(cc + f5(dd,ee,aa) + X[13] + 0x50a28be6, 7) + bb; ee = RL(ee, 10); bb = RL(bb + f5(cc,dd,ee) + X[ 6] + 0x50a28be6, 7) + aa; dd = RL(dd, 10); aa = RL(aa + f5(bb,cc,dd) + X[15] + 0x50a28be6, 8) + ee; cc = RL(cc, 10); ee = RL(ee + f5(aa,bb,cc) + X[ 8] + 0x50a28be6, 11) + dd; bb = RL(bb, 10); dd = RL(dd + f5(ee,aa,bb) + X[ 1] + 0x50a28be6, 14) + cc; aa = RL(aa, 10); cc = RL(cc + f5(dd,ee,aa) + X[10] + 0x50a28be6, 14) + bb; ee = RL(ee, 10); bb = RL(bb + f5(cc,dd,ee) + X[ 3] + 0x50a28be6, 12) + aa; dd = RL(dd, 10); aa = RL(aa + f5(bb,cc,dd) + X[12] + 0x50a28be6, 6) + ee; cc = RL(cc, 10); // // Rounds 16-31 // // left e = RL(e + f2(a,b,c) + X[ 7] + 0x5a827999, 7) + d; b = RL(b, 10); d = RL(d + f2(e,a,b) + X[ 4] + 0x5a827999, 6) + c; a = RL(a, 10); c = RL(c + f2(d,e,a) + X[13] + 0x5a827999, 8) + b; e = RL(e, 10); b = RL(b + f2(c,d,e) + X[ 1] + 0x5a827999, 13) + a; d = RL(d, 10); a = RL(a + f2(b,c,d) + X[10] + 0x5a827999, 11) + e; c = RL(c, 10); e = RL(e + f2(a,b,c) + X[ 6] + 0x5a827999, 9) + d; b = RL(b, 10); d = RL(d + f2(e,a,b) + X[15] + 0x5a827999, 7) + c; a = RL(a, 10); c = RL(c + f2(d,e,a) + X[ 3] + 0x5a827999, 15) + b; e = RL(e, 10); b = RL(b + f2(c,d,e) + X[12] + 0x5a827999, 7) + a; d = RL(d, 10); a = RL(a + f2(b,c,d) + X[ 0] + 0x5a827999, 12) + e; c = RL(c, 10); e = RL(e + f2(a,b,c) + X[ 9] + 0x5a827999, 15) + d; b = RL(b, 10); d = RL(d + f2(e,a,b) + X[ 5] + 0x5a827999, 9) + c; a = RL(a, 10); c = RL(c + f2(d,e,a) + X[ 2] + 0x5a827999, 11) + b; e = RL(e, 10); b = RL(b + f2(c,d,e) + X[14] + 0x5a827999, 7) + a; d = RL(d, 10); a = RL(a + f2(b,c,d) + X[11] + 0x5a827999, 13) + e; c = RL(c, 10); e = RL(e + f2(a,b,c) + X[ 8] + 0x5a827999, 12) + d; b = RL(b, 10); // right ee = RL(ee + f4(aa,bb,cc) + X[ 6] + 0x5c4dd124, 9) + dd; bb = RL(bb, 10); dd = RL(dd + f4(ee,aa,bb) + X[11] + 0x5c4dd124, 13) + cc; aa = RL(aa, 10); cc = RL(cc + f4(dd,ee,aa) + X[ 3] + 0x5c4dd124, 15) + bb; ee = RL(ee, 10); bb = RL(bb + f4(cc,dd,ee) + X[ 7] + 0x5c4dd124, 7) + aa; dd = RL(dd, 10); aa = RL(aa + f4(bb,cc,dd) + X[ 0] + 0x5c4dd124, 12) + ee; cc = RL(cc, 10); ee = RL(ee + f4(aa,bb,cc) + X[13] + 0x5c4dd124, 8) + dd; bb = RL(bb, 10); dd = RL(dd + f4(ee,aa,bb) + X[ 5] + 0x5c4dd124, 9) + cc; aa = RL(aa, 10); cc = RL(cc + f4(dd,ee,aa) + X[10] + 0x5c4dd124, 11) + bb; ee = RL(ee, 10); bb = RL(bb + f4(cc,dd,ee) + X[14] + 0x5c4dd124, 7) + aa; dd = RL(dd, 10); aa = RL(aa + f4(bb,cc,dd) + X[15] + 0x5c4dd124, 7) + ee; cc = RL(cc, 10); ee = RL(ee + f4(aa,bb,cc) + X[ 8] + 0x5c4dd124, 12) + dd; bb = RL(bb, 10); dd = RL(dd + f4(ee,aa,bb) + X[12] + 0x5c4dd124, 7) + cc; aa = RL(aa, 10); cc = RL(cc + f4(dd,ee,aa) + X[ 4] + 0x5c4dd124, 6) + bb; ee = RL(ee, 10); bb = RL(bb + f4(cc,dd,ee) + X[ 9] + 0x5c4dd124, 15) + aa; dd = RL(dd, 10); aa = RL(aa + f4(bb,cc,dd) + X[ 1] + 0x5c4dd124, 13) + ee; cc = RL(cc, 10); ee = RL(ee + f4(aa,bb,cc) + X[ 2] + 0x5c4dd124, 11) + dd; bb = RL(bb, 10); // // Rounds 32-47 // // left d = RL(d + f3(e,a,b) + X[ 3] + 0x6ed9eba1, 11) + c; a = RL(a, 10); c = RL(c + f3(d,e,a) + X[10] + 0x6ed9eba1, 13) + b; e = RL(e, 10); b = RL(b + f3(c,d,e) + X[14] + 0x6ed9eba1, 6) + a; d = RL(d, 10); a = RL(a + f3(b,c,d) + X[ 4] + 0x6ed9eba1, 7) + e; c = RL(c, 10); e = RL(e + f3(a,b,c) + X[ 9] + 0x6ed9eba1, 14) + d; b = RL(b, 10); d = RL(d + f3(e,a,b) + X[15] + 0x6ed9eba1, 9) + c; a = RL(a, 10); c = RL(c + f3(d,e,a) + X[ 8] + 0x6ed9eba1, 13) + b; e = RL(e, 10); b = RL(b + f3(c,d,e) + X[ 1] + 0x6ed9eba1, 15) + a; d = RL(d, 10); a = RL(a + f3(b,c,d) + X[ 2] + 0x6ed9eba1, 14) + e; c = RL(c, 10); e = RL(e + f3(a,b,c) + X[ 7] + 0x6ed9eba1, 8) + d; b = RL(b, 10); d = RL(d + f3(e,a,b) + X[ 0] + 0x6ed9eba1, 13) + c; a = RL(a, 10); c = RL(c + f3(d,e,a) + X[ 6] + 0x6ed9eba1, 6) + b; e = RL(e, 10); b = RL(b + f3(c,d,e) + X[13] + 0x6ed9eba1, 5) + a; d = RL(d, 10); a = RL(a + f3(b,c,d) + X[11] + 0x6ed9eba1, 12) + e; c = RL(c, 10); e = RL(e + f3(a,b,c) + X[ 5] + 0x6ed9eba1, 7) + d; b = RL(b, 10); d = RL(d + f3(e,a,b) + X[12] + 0x6ed9eba1, 5) + c; a = RL(a, 10); // right dd = RL(dd + f3(ee,aa,bb) + X[15] + 0x6d703ef3, 9) + cc; aa = RL(aa, 10); cc = RL(cc + f3(dd,ee,aa) + X[ 5] + 0x6d703ef3, 7) + bb; ee = RL(ee, 10); bb = RL(bb + f3(cc,dd,ee) + X[ 1] + 0x6d703ef3, 15) + aa; dd = RL(dd, 10); aa = RL(aa + f3(bb,cc,dd) + X[ 3] + 0x6d703ef3, 11) + ee; cc = RL(cc, 10); ee = RL(ee + f3(aa,bb,cc) + X[ 7] + 0x6d703ef3, 8) + dd; bb = RL(bb, 10); dd = RL(dd + f3(ee,aa,bb) + X[14] + 0x6d703ef3, 6) + cc; aa = RL(aa, 10); cc = RL(cc + f3(dd,ee,aa) + X[ 6] + 0x6d703ef3, 6) + bb; ee = RL(ee, 10); bb = RL(bb + f3(cc,dd,ee) + X[ 9] + 0x6d703ef3, 14) + aa; dd = RL(dd, 10); aa = RL(aa + f3(bb,cc,dd) + X[11] + 0x6d703ef3, 12) + ee; cc = RL(cc, 10); ee = RL(ee + f3(aa,bb,cc) + X[ 8] + 0x6d703ef3, 13) + dd; bb = RL(bb, 10); dd = RL(dd + f3(ee,aa,bb) + X[12] + 0x6d703ef3, 5) + cc; aa = RL(aa, 10); cc = RL(cc + f3(dd,ee,aa) + X[ 2] + 0x6d703ef3, 14) + bb; ee = RL(ee, 10); bb = RL(bb + f3(cc,dd,ee) + X[10] + 0x6d703ef3, 13) + aa; dd = RL(dd, 10); aa = RL(aa + f3(bb,cc,dd) + X[ 0] + 0x6d703ef3, 13) + ee; cc = RL(cc, 10); ee = RL(ee + f3(aa,bb,cc) + X[ 4] + 0x6d703ef3, 7) + dd; bb = RL(bb, 10); dd = RL(dd + f3(ee,aa,bb) + X[13] + 0x6d703ef3, 5) + cc; aa = RL(aa, 10); // // Rounds 48-63 // // left c = RL(c + f4(d,e,a) + X[ 1] + 0x8f1bbcdc, 11) + b; e = RL(e, 10); b = RL(b + f4(c,d,e) + X[ 9] + 0x8f1bbcdc, 12) + a; d = RL(d, 10); a = RL(a + f4(b,c,d) + X[11] + 0x8f1bbcdc, 14) + e; c = RL(c, 10); e = RL(e + f4(a,b,c) + X[10] + 0x8f1bbcdc, 15) + d; b = RL(b, 10); d = RL(d + f4(e,a,b) + X[ 0] + 0x8f1bbcdc, 14) + c; a = RL(a, 10); c = RL(c + f4(d,e,a) + X[ 8] + 0x8f1bbcdc, 15) + b; e = RL(e, 10); b = RL(b + f4(c,d,e) + X[12] + 0x8f1bbcdc, 9) + a; d = RL(d, 10); a = RL(a + f4(b,c,d) + X[ 4] + 0x8f1bbcdc, 8) + e; c = RL(c, 10); e = RL(e + f4(a,b,c) + X[13] + 0x8f1bbcdc, 9) + d; b = RL(b, 10); d = RL(d + f4(e,a,b) + X[ 3] + 0x8f1bbcdc, 14) + c; a = RL(a, 10); c = RL(c + f4(d,e,a) + X[ 7] + 0x8f1bbcdc, 5) + b; e = RL(e, 10); b = RL(b + f4(c,d,e) + X[15] + 0x8f1bbcdc, 6) + a; d = RL(d, 10); a = RL(a + f4(b,c,d) + X[14] + 0x8f1bbcdc, 8) + e; c = RL(c, 10); e = RL(e + f4(a,b,c) + X[ 5] + 0x8f1bbcdc, 6) + d; b = RL(b, 10); d = RL(d + f4(e,a,b) + X[ 6] + 0x8f1bbcdc, 5) + c; a = RL(a, 10); c = RL(c + f4(d,e,a) + X[ 2] + 0x8f1bbcdc, 12) + b; e = RL(e, 10); // right cc = RL(cc + f2(dd,ee,aa) + X[ 8] + 0x7a6d76e9, 15) + bb; ee = RL(ee, 10); bb = RL(bb + f2(cc,dd,ee) + X[ 6] + 0x7a6d76e9, 5) + aa; dd = RL(dd, 10); aa = RL(aa + f2(bb,cc,dd) + X[ 4] + 0x7a6d76e9, 8) + ee; cc = RL(cc, 10); ee = RL(ee + f2(aa,bb,cc) + X[ 1] + 0x7a6d76e9, 11) + dd; bb = RL(bb, 10); dd = RL(dd + f2(ee,aa,bb) + X[ 3] + 0x7a6d76e9, 14) + cc; aa = RL(aa, 10); cc = RL(cc + f2(dd,ee,aa) + X[11] + 0x7a6d76e9, 14) + bb; ee = RL(ee, 10); bb = RL(bb + f2(cc,dd,ee) + X[15] + 0x7a6d76e9, 6) + aa; dd = RL(dd, 10); aa = RL(aa + f2(bb,cc,dd) + X[ 0] + 0x7a6d76e9, 14) + ee; cc = RL(cc, 10); ee = RL(ee + f2(aa,bb,cc) + X[ 5] + 0x7a6d76e9, 6) + dd; bb = RL(bb, 10); dd = RL(dd + f2(ee,aa,bb) + X[12] + 0x7a6d76e9, 9) + cc; aa = RL(aa, 10); cc = RL(cc + f2(dd,ee,aa) + X[ 2] + 0x7a6d76e9, 12) + bb; ee = RL(ee, 10); bb = RL(bb + f2(cc,dd,ee) + X[13] + 0x7a6d76e9, 9) + aa; dd = RL(dd, 10); aa = RL(aa + f2(bb,cc,dd) + X[ 9] + 0x7a6d76e9, 12) + ee; cc = RL(cc, 10); ee = RL(ee + f2(aa,bb,cc) + X[ 7] + 0x7a6d76e9, 5) + dd; bb = RL(bb, 10); dd = RL(dd + f2(ee,aa,bb) + X[10] + 0x7a6d76e9, 15) + cc; aa = RL(aa, 10); cc = RL(cc + f2(dd,ee,aa) + X[14] + 0x7a6d76e9, 8) + bb; ee = RL(ee, 10); // // Rounds 64-79 // // left b = RL(b + f5(c,d,e) + X[ 4] + 0xa953fd4e, 9) + a; d = RL(d, 10); a = RL(a + f5(b,c,d) + X[ 0] + 0xa953fd4e, 15) + e; c = RL(c, 10); e = RL(e + f5(a,b,c) + X[ 5] + 0xa953fd4e, 5) + d; b = RL(b, 10); d = RL(d + f5(e,a,b) + X[ 9] + 0xa953fd4e, 11) + c; a = RL(a, 10); c = RL(c + f5(d,e,a) + X[ 7] + 0xa953fd4e, 6) + b; e = RL(e, 10); b = RL(b + f5(c,d,e) + X[12] + 0xa953fd4e, 8) + a; d = RL(d, 10); a = RL(a + f5(b,c,d) + X[ 2] + 0xa953fd4e, 13) + e; c = RL(c, 10); e = RL(e + f5(a,b,c) + X[10] + 0xa953fd4e, 12) + d; b = RL(b, 10); d = RL(d + f5(e,a,b) + X[14] + 0xa953fd4e, 5) + c; a = RL(a, 10); c = RL(c + f5(d,e,a) + X[ 1] + 0xa953fd4e, 12) + b; e = RL(e, 10); b = RL(b + f5(c,d,e) + X[ 3] + 0xa953fd4e, 13) + a; d = RL(d, 10); a = RL(a + f5(b,c,d) + X[ 8] + 0xa953fd4e, 14) + e; c = RL(c, 10); e = RL(e + f5(a,b,c) + X[11] + 0xa953fd4e, 11) + d; b = RL(b, 10); d = RL(d + f5(e,a,b) + X[ 6] + 0xa953fd4e, 8) + c; a = RL(a, 10); c = RL(c + f5(d,e,a) + X[15] + 0xa953fd4e, 5) + b; e = RL(e, 10); b = RL(b + f5(c,d,e) + X[13] + 0xa953fd4e, 6) + a; d = RL(d, 10); // right bb = RL(bb + f1(cc,dd,ee) + X[12], 8) + aa; dd = RL(dd, 10); aa = RL(aa + f1(bb,cc,dd) + X[15], 5) + ee; cc = RL(cc, 10); ee = RL(ee + f1(aa,bb,cc) + X[10], 12) + dd; bb = RL(bb, 10); dd = RL(dd + f1(ee,aa,bb) + X[ 4], 9) + cc; aa = RL(aa, 10); cc = RL(cc + f1(dd,ee,aa) + X[ 1], 12) + bb; ee = RL(ee, 10); bb = RL(bb + f1(cc,dd,ee) + X[ 5], 5) + aa; dd = RL(dd, 10); aa = RL(aa + f1(bb,cc,dd) + X[ 8], 14) + ee; cc = RL(cc, 10); ee = RL(ee + f1(aa,bb,cc) + X[ 7], 6) + dd; bb = RL(bb, 10); dd = RL(dd + f1(ee,aa,bb) + X[ 6], 8) + cc; aa = RL(aa, 10); cc = RL(cc + f1(dd,ee,aa) + X[ 2], 13) + bb; ee = RL(ee, 10); bb = RL(bb + f1(cc,dd,ee) + X[13], 6) + aa; dd = RL(dd, 10); aa = RL(aa + f1(bb,cc,dd) + X[14], 5) + ee; cc = RL(cc, 10); ee = RL(ee + f1(aa,bb,cc) + X[ 0], 15) + dd; bb = RL(bb, 10); dd = RL(dd + f1(ee,aa,bb) + X[ 3], 13) + cc; aa = RL(aa, 10); cc = RL(cc + f1(dd,ee,aa) + X[ 9], 11) + bb; ee = RL(ee, 10); bb = RL(bb + f1(cc,dd,ee) + X[11], 11) + aa; dd = RL(dd, 10); dd += c + H1; H1 = H2 + d + ee; H2 = H3 + e + aa; H3 = H4 + a + bb; H4 = H0 + b + cc; H0 = dd; // // reset the offset and clean out the word buffer. // xOff = 0; for (int i = 0; i != X.length; i++) { X[i] = 0; } } public Memoable copy() { return new RIPEMD160Digest(this); } public void reset(Memoable other) { RIPEMD160Digest d = (RIPEMD160Digest)other; copyIn(d); } } bouncycastle-1.49.orig/src/org/bouncycastle/crypto/digests/SHA256Digest.java0000644000175000017500000001633212143607521026345 0ustar ebourgebourgpackage org.bouncycastle.crypto.digests; import org.bouncycastle.crypto.util.Pack; import org.bouncycastle.util.Memoable; /** * FIPS 180-2 implementation of SHA-256. * *
     *         block  word  digest
     * SHA-1   512    32    160
     * SHA-256 512    32    256
     * SHA-384 1024   64    384
     * SHA-512 1024   64    512
     * 
    */ public class SHA256Digest extends GeneralDigest { private static final int DIGEST_LENGTH = 32; private int H1, H2, H3, H4, H5, H6, H7, H8; private int[] X = new int[64]; private int xOff; /** * Standard constructor */ public SHA256Digest() { reset(); } /** * Copy constructor. This will copy the state of the provided * message digest. */ public SHA256Digest(SHA256Digest t) { super(t); copyIn(t); } private void copyIn(SHA256Digest t) { super.copyIn(t); H1 = t.H1; H2 = t.H2; H3 = t.H3; H4 = t.H4; H5 = t.H5; H6 = t.H6; H7 = t.H7; H8 = t.H8; System.arraycopy(t.X, 0, X, 0, t.X.length); xOff = t.xOff; } public String getAlgorithmName() { return "SHA-256"; } public int getDigestSize() { return DIGEST_LENGTH; } protected void processWord( byte[] in, int inOff) { // Note: Inlined for performance // X[xOff] = Pack.bigEndianToInt(in, inOff); int n = in[inOff] << 24; n |= (in[++inOff] & 0xff) << 16; n |= (in[++inOff] & 0xff) << 8; n |= (in[++inOff] & 0xff); X[xOff] = n; if (++xOff == 16) { processBlock(); } } protected void processLength( long bitLength) { if (xOff > 14) { processBlock(); } X[14] = (int)(bitLength >>> 32); X[15] = (int)(bitLength & 0xffffffff); } public int doFinal( byte[] out, int outOff) { finish(); Pack.intToBigEndian(H1, out, outOff); Pack.intToBigEndian(H2, out, outOff + 4); Pack.intToBigEndian(H3, out, outOff + 8); Pack.intToBigEndian(H4, out, outOff + 12); Pack.intToBigEndian(H5, out, outOff + 16); Pack.intToBigEndian(H6, out, outOff + 20); Pack.intToBigEndian(H7, out, outOff + 24); Pack.intToBigEndian(H8, out, outOff + 28); reset(); return DIGEST_LENGTH; } /** * reset the chaining variables */ public void reset() { super.reset(); /* SHA-256 initial hash value * The first 32 bits of the fractional parts of the square roots * of the first eight prime numbers */ H1 = 0x6a09e667; H2 = 0xbb67ae85; H3 = 0x3c6ef372; H4 = 0xa54ff53a; H5 = 0x510e527f; H6 = 0x9b05688c; H7 = 0x1f83d9ab; H8 = 0x5be0cd19; xOff = 0; for (int i = 0; i != X.length; i++) { X[i] = 0; } } protected void processBlock() { // // expand 16 word block into 64 word blocks. // for (int t = 16; t <= 63; t++) { X[t] = Theta1(X[t - 2]) + X[t - 7] + Theta0(X[t - 15]) + X[t - 16]; } // // set up working variables. // int a = H1; int b = H2; int c = H3; int d = H4; int e = H5; int f = H6; int g = H7; int h = H8; int t = 0; for(int i = 0; i < 8; i ++) { // t = 8 * i h += Sum1(e) + Ch(e, f, g) + K[t] + X[t]; d += h; h += Sum0(a) + Maj(a, b, c); ++t; // t = 8 * i + 1 g += Sum1(d) + Ch(d, e, f) + K[t] + X[t]; c += g; g += Sum0(h) + Maj(h, a, b); ++t; // t = 8 * i + 2 f += Sum1(c) + Ch(c, d, e) + K[t] + X[t]; b += f; f += Sum0(g) + Maj(g, h, a); ++t; // t = 8 * i + 3 e += Sum1(b) + Ch(b, c, d) + K[t] + X[t]; a += e; e += Sum0(f) + Maj(f, g, h); ++t; // t = 8 * i + 4 d += Sum1(a) + Ch(a, b, c) + K[t] + X[t]; h += d; d += Sum0(e) + Maj(e, f, g); ++t; // t = 8 * i + 5 c += Sum1(h) + Ch(h, a, b) + K[t] + X[t]; g += c; c += Sum0(d) + Maj(d, e, f); ++t; // t = 8 * i + 6 b += Sum1(g) + Ch(g, h, a) + K[t] + X[t]; f += b; b += Sum0(c) + Maj(c, d, e); ++t; // t = 8 * i + 7 a += Sum1(f) + Ch(f, g, h) + K[t] + X[t]; e += a; a += Sum0(b) + Maj(b, c, d); ++t; } H1 += a; H2 += b; H3 += c; H4 += d; H5 += e; H6 += f; H7 += g; H8 += h; // // reset the offset and clean out the word buffer. // xOff = 0; for (int i = 0; i < 16; i++) { X[i] = 0; } } /* SHA-256 functions */ private int Ch( int x, int y, int z) { return (x & y) ^ ((~x) & z); } private int Maj( int x, int y, int z) { return (x & y) ^ (x & z) ^ (y & z); } private int Sum0( int x) { return ((x >>> 2) | (x << 30)) ^ ((x >>> 13) | (x << 19)) ^ ((x >>> 22) | (x << 10)); } private int Sum1( int x) { return ((x >>> 6) | (x << 26)) ^ ((x >>> 11) | (x << 21)) ^ ((x >>> 25) | (x << 7)); } private int Theta0( int x) { return ((x >>> 7) | (x << 25)) ^ ((x >>> 18) | (x << 14)) ^ (x >>> 3); } private int Theta1( int x) { return ((x >>> 17) | (x << 15)) ^ ((x >>> 19) | (x << 13)) ^ (x >>> 10); } /* SHA-256 Constants * (represent the first 32 bits of the fractional parts of the * cube roots of the first sixty-four prime numbers) */ static final int K[] = { 0x428a2f98, 0x71374491, 0xb5c0fbcf, 0xe9b5dba5, 0x3956c25b, 0x59f111f1, 0x923f82a4, 0xab1c5ed5, 0xd807aa98, 0x12835b01, 0x243185be, 0x550c7dc3, 0x72be5d74, 0x80deb1fe, 0x9bdc06a7, 0xc19bf174, 0xe49b69c1, 0xefbe4786, 0x0fc19dc6, 0x240ca1cc, 0x2de92c6f, 0x4a7484aa, 0x5cb0a9dc, 0x76f988da, 0x983e5152, 0xa831c66d, 0xb00327c8, 0xbf597fc7, 0xc6e00bf3, 0xd5a79147, 0x06ca6351, 0x14292967, 0x27b70a85, 0x2e1b2138, 0x4d2c6dfc, 0x53380d13, 0x650a7354, 0x766a0abb, 0x81c2c92e, 0x92722c85, 0xa2bfe8a1, 0xa81a664b, 0xc24b8b70, 0xc76c51a3, 0xd192e819, 0xd6990624, 0xf40e3585, 0x106aa070, 0x19a4c116, 0x1e376c08, 0x2748774c, 0x34b0bcb5, 0x391c0cb3, 0x4ed8aa4a, 0x5b9cca4f, 0x682e6ff3, 0x748f82ee, 0x78a5636f, 0x84c87814, 0x8cc70208, 0x90befffa, 0xa4506ceb, 0xbef9a3f7, 0xc67178f2 }; public Memoable copy() { return new SHA256Digest(this); } public void reset(Memoable other) { SHA256Digest d = (SHA256Digest)other; copyIn(d); } } bouncycastle-1.49.orig/src/org/bouncycastle/crypto/digests/TigerDigest.java0000644000175000017500000013572112143604007026547 0ustar ebourgebourgpackage org.bouncycastle.crypto.digests; import org.bouncycastle.crypto.ExtendedDigest; import org.bouncycastle.util.Memoable; /** * implementation of Tiger based on: * * http://www.cs.technion.ac.il/~biham/Reports/Tiger */ public class TigerDigest implements ExtendedDigest, Memoable { private static final int BYTE_LENGTH = 64; /* * S-Boxes. */ private static final long[] t1 = { 0x02AAB17CF7E90C5EL /* 0 */, 0xAC424B03E243A8ECL /* 1 */, 0x72CD5BE30DD5FCD3L /* 2 */, 0x6D019B93F6F97F3AL /* 3 */, 0xCD9978FFD21F9193L /* 4 */, 0x7573A1C9708029E2L /* 5 */, 0xB164326B922A83C3L /* 6 */, 0x46883EEE04915870L /* 7 */, 0xEAACE3057103ECE6L /* 8 */, 0xC54169B808A3535CL /* 9 */, 0x4CE754918DDEC47CL /* 10 */, 0x0AA2F4DFDC0DF40CL /* 11 */, 0x10B76F18A74DBEFAL /* 12 */, 0xC6CCB6235AD1AB6AL /* 13 */, 0x13726121572FE2FFL /* 14 */, 0x1A488C6F199D921EL /* 15 */, 0x4BC9F9F4DA0007CAL /* 16 */, 0x26F5E6F6E85241C7L /* 17 */, 0x859079DBEA5947B6L /* 18 */, 0x4F1885C5C99E8C92L /* 19 */, 0xD78E761EA96F864BL /* 20 */, 0x8E36428C52B5C17DL /* 21 */, 0x69CF6827373063C1L /* 22 */, 0xB607C93D9BB4C56EL /* 23 */, 0x7D820E760E76B5EAL /* 24 */, 0x645C9CC6F07FDC42L /* 25 */, 0xBF38A078243342E0L /* 26 */, 0x5F6B343C9D2E7D04L /* 27 */, 0xF2C28AEB600B0EC6L /* 28 */, 0x6C0ED85F7254BCACL /* 29 */, 0x71592281A4DB4FE5L /* 30 */, 0x1967FA69CE0FED9FL /* 31 */, 0xFD5293F8B96545DBL /* 32 */, 0xC879E9D7F2A7600BL /* 33 */, 0x860248920193194EL /* 34 */, 0xA4F9533B2D9CC0B3L /* 35 */, 0x9053836C15957613L /* 36 */, 0xDB6DCF8AFC357BF1L /* 37 */, 0x18BEEA7A7A370F57L /* 38 */, 0x037117CA50B99066L /* 39 */, 0x6AB30A9774424A35L /* 40 */, 0xF4E92F02E325249BL /* 41 */, 0x7739DB07061CCAE1L /* 42 */, 0xD8F3B49CECA42A05L /* 43 */, 0xBD56BE3F51382F73L /* 44 */, 0x45FAED5843B0BB28L /* 45 */, 0x1C813D5C11BF1F83L /* 46 */, 0x8AF0E4B6D75FA169L /* 47 */, 0x33EE18A487AD9999L /* 48 */, 0x3C26E8EAB1C94410L /* 49 */, 0xB510102BC0A822F9L /* 50 */, 0x141EEF310CE6123BL /* 51 */, 0xFC65B90059DDB154L /* 52 */, 0xE0158640C5E0E607L /* 53 */, 0x884E079826C3A3CFL /* 54 */, 0x930D0D9523C535FDL /* 55 */, 0x35638D754E9A2B00L /* 56 */, 0x4085FCCF40469DD5L /* 57 */, 0xC4B17AD28BE23A4CL /* 58 */, 0xCAB2F0FC6A3E6A2EL /* 59 */, 0x2860971A6B943FCDL /* 60 */, 0x3DDE6EE212E30446L /* 61 */, 0x6222F32AE01765AEL /* 62 */, 0x5D550BB5478308FEL /* 63 */, 0xA9EFA98DA0EDA22AL /* 64 */, 0xC351A71686C40DA7L /* 65 */, 0x1105586D9C867C84L /* 66 */, 0xDCFFEE85FDA22853L /* 67 */, 0xCCFBD0262C5EEF76L /* 68 */, 0xBAF294CB8990D201L /* 69 */, 0xE69464F52AFAD975L /* 70 */, 0x94B013AFDF133E14L /* 71 */, 0x06A7D1A32823C958L /* 72 */, 0x6F95FE5130F61119L /* 73 */, 0xD92AB34E462C06C0L /* 74 */, 0xED7BDE33887C71D2L /* 75 */, 0x79746D6E6518393EL /* 76 */, 0x5BA419385D713329L /* 77 */, 0x7C1BA6B948A97564L /* 78 */, 0x31987C197BFDAC67L /* 79 */, 0xDE6C23C44B053D02L /* 80 */, 0x581C49FED002D64DL /* 81 */, 0xDD474D6338261571L /* 82 */, 0xAA4546C3E473D062L /* 83 */, 0x928FCE349455F860L /* 84 */, 0x48161BBACAAB94D9L /* 85 */, 0x63912430770E6F68L /* 86 */, 0x6EC8A5E602C6641CL /* 87 */, 0x87282515337DDD2BL /* 88 */, 0x2CDA6B42034B701BL /* 89 */, 0xB03D37C181CB096DL /* 90 */, 0xE108438266C71C6FL /* 91 */, 0x2B3180C7EB51B255L /* 92 */, 0xDF92B82F96C08BBCL /* 93 */, 0x5C68C8C0A632F3BAL /* 94 */, 0x5504CC861C3D0556L /* 95 */, 0xABBFA4E55FB26B8FL /* 96 */, 0x41848B0AB3BACEB4L /* 97 */, 0xB334A273AA445D32L /* 98 */, 0xBCA696F0A85AD881L /* 99 */, 0x24F6EC65B528D56CL /* 100 */, 0x0CE1512E90F4524AL /* 101 */, 0x4E9DD79D5506D35AL /* 102 */, 0x258905FAC6CE9779L /* 103 */, 0x2019295B3E109B33L /* 104 */, 0xF8A9478B73A054CCL /* 105 */, 0x2924F2F934417EB0L /* 106 */, 0x3993357D536D1BC4L /* 107 */, 0x38A81AC21DB6FF8BL /* 108 */, 0x47C4FBF17D6016BFL /* 109 */, 0x1E0FAADD7667E3F5L /* 110 */, 0x7ABCFF62938BEB96L /* 111 */, 0xA78DAD948FC179C9L /* 112 */, 0x8F1F98B72911E50DL /* 113 */, 0x61E48EAE27121A91L /* 114 */, 0x4D62F7AD31859808L /* 115 */, 0xECEBA345EF5CEAEBL /* 116 */, 0xF5CEB25EBC9684CEL /* 117 */, 0xF633E20CB7F76221L /* 118 */, 0xA32CDF06AB8293E4L /* 119 */, 0x985A202CA5EE2CA4L /* 120 */, 0xCF0B8447CC8A8FB1L /* 121 */, 0x9F765244979859A3L /* 122 */, 0xA8D516B1A1240017L /* 123 */, 0x0BD7BA3EBB5DC726L /* 124 */, 0xE54BCA55B86ADB39L /* 125 */, 0x1D7A3AFD6C478063L /* 126 */, 0x519EC608E7669EDDL /* 127 */, 0x0E5715A2D149AA23L /* 128 */, 0x177D4571848FF194L /* 129 */, 0xEEB55F3241014C22L /* 130 */, 0x0F5E5CA13A6E2EC2L /* 131 */, 0x8029927B75F5C361L /* 132 */, 0xAD139FABC3D6E436L /* 133 */, 0x0D5DF1A94CCF402FL /* 134 */, 0x3E8BD948BEA5DFC8L /* 135 */, 0xA5A0D357BD3FF77EL /* 136 */, 0xA2D12E251F74F645L /* 137 */, 0x66FD9E525E81A082L /* 138 */, 0x2E0C90CE7F687A49L /* 139 */, 0xC2E8BCBEBA973BC5L /* 140 */, 0x000001BCE509745FL /* 141 */, 0x423777BBE6DAB3D6L /* 142 */, 0xD1661C7EAEF06EB5L /* 143 */, 0xA1781F354DAACFD8L /* 144 */, 0x2D11284A2B16AFFCL /* 145 */, 0xF1FC4F67FA891D1FL /* 146 */, 0x73ECC25DCB920ADAL /* 147 */, 0xAE610C22C2A12651L /* 148 */, 0x96E0A810D356B78AL /* 149 */, 0x5A9A381F2FE7870FL /* 150 */, 0xD5AD62EDE94E5530L /* 151 */, 0xD225E5E8368D1427L /* 152 */, 0x65977B70C7AF4631L /* 153 */, 0x99F889B2DE39D74FL /* 154 */, 0x233F30BF54E1D143L /* 155 */, 0x9A9675D3D9A63C97L /* 156 */, 0x5470554FF334F9A8L /* 157 */, 0x166ACB744A4F5688L /* 158 */, 0x70C74CAAB2E4AEADL /* 159 */, 0xF0D091646F294D12L /* 160 */, 0x57B82A89684031D1L /* 161 */, 0xEFD95A5A61BE0B6BL /* 162 */, 0x2FBD12E969F2F29AL /* 163 */, 0x9BD37013FEFF9FE8L /* 164 */, 0x3F9B0404D6085A06L /* 165 */, 0x4940C1F3166CFE15L /* 166 */, 0x09542C4DCDF3DEFBL /* 167 */, 0xB4C5218385CD5CE3L /* 168 */, 0xC935B7DC4462A641L /* 169 */, 0x3417F8A68ED3B63FL /* 170 */, 0xB80959295B215B40L /* 171 */, 0xF99CDAEF3B8C8572L /* 172 */, 0x018C0614F8FCB95DL /* 173 */, 0x1B14ACCD1A3ACDF3L /* 174 */, 0x84D471F200BB732DL /* 175 */, 0xC1A3110E95E8DA16L /* 176 */, 0x430A7220BF1A82B8L /* 177 */, 0xB77E090D39DF210EL /* 178 */, 0x5EF4BD9F3CD05E9DL /* 179 */, 0x9D4FF6DA7E57A444L /* 180 */, 0xDA1D60E183D4A5F8L /* 181 */, 0xB287C38417998E47L /* 182 */, 0xFE3EDC121BB31886L /* 183 */, 0xC7FE3CCC980CCBEFL /* 184 */, 0xE46FB590189BFD03L /* 185 */, 0x3732FD469A4C57DCL /* 186 */, 0x7EF700A07CF1AD65L /* 187 */, 0x59C64468A31D8859L /* 188 */, 0x762FB0B4D45B61F6L /* 189 */, 0x155BAED099047718L /* 190 */, 0x68755E4C3D50BAA6L /* 191 */, 0xE9214E7F22D8B4DFL /* 192 */, 0x2ADDBF532EAC95F4L /* 193 */, 0x32AE3909B4BD0109L /* 194 */, 0x834DF537B08E3450L /* 195 */, 0xFA209DA84220728DL /* 196 */, 0x9E691D9B9EFE23F7L /* 197 */, 0x0446D288C4AE8D7FL /* 198 */, 0x7B4CC524E169785BL /* 199 */, 0x21D87F0135CA1385L /* 200 */, 0xCEBB400F137B8AA5L /* 201 */, 0x272E2B66580796BEL /* 202 */, 0x3612264125C2B0DEL /* 203 */, 0x057702BDAD1EFBB2L /* 204 */, 0xD4BABB8EACF84BE9L /* 205 */, 0x91583139641BC67BL /* 206 */, 0x8BDC2DE08036E024L /* 207 */, 0x603C8156F49F68EDL /* 208 */, 0xF7D236F7DBEF5111L /* 209 */, 0x9727C4598AD21E80L /* 210 */, 0xA08A0896670A5FD7L /* 211 */, 0xCB4A8F4309EBA9CBL /* 212 */, 0x81AF564B0F7036A1L /* 213 */, 0xC0B99AA778199ABDL /* 214 */, 0x959F1EC83FC8E952L /* 215 */, 0x8C505077794A81B9L /* 216 */, 0x3ACAAF8F056338F0L /* 217 */, 0x07B43F50627A6778L /* 218 */, 0x4A44AB49F5ECCC77L /* 219 */, 0x3BC3D6E4B679EE98L /* 220 */, 0x9CC0D4D1CF14108CL /* 221 */, 0x4406C00B206BC8A0L /* 222 */, 0x82A18854C8D72D89L /* 223 */, 0x67E366B35C3C432CL /* 224 */, 0xB923DD61102B37F2L /* 225 */, 0x56AB2779D884271DL /* 226 */, 0xBE83E1B0FF1525AFL /* 227 */, 0xFB7C65D4217E49A9L /* 228 */, 0x6BDBE0E76D48E7D4L /* 229 */, 0x08DF828745D9179EL /* 230 */, 0x22EA6A9ADD53BD34L /* 231 */, 0xE36E141C5622200AL /* 232 */, 0x7F805D1B8CB750EEL /* 233 */, 0xAFE5C7A59F58E837L /* 234 */, 0xE27F996A4FB1C23CL /* 235 */, 0xD3867DFB0775F0D0L /* 236 */, 0xD0E673DE6E88891AL /* 237 */, 0x123AEB9EAFB86C25L /* 238 */, 0x30F1D5D5C145B895L /* 239 */, 0xBB434A2DEE7269E7L /* 240 */, 0x78CB67ECF931FA38L /* 241 */, 0xF33B0372323BBF9CL /* 242 */, 0x52D66336FB279C74L /* 243 */, 0x505F33AC0AFB4EAAL /* 244 */, 0xE8A5CD99A2CCE187L /* 245 */, 0x534974801E2D30BBL /* 246 */, 0x8D2D5711D5876D90L /* 247 */, 0x1F1A412891BC038EL /* 248 */, 0xD6E2E71D82E56648L /* 249 */, 0x74036C3A497732B7L /* 250 */, 0x89B67ED96361F5ABL /* 251 */, 0xFFED95D8F1EA02A2L /* 252 */, 0xE72B3BD61464D43DL /* 253 */, 0xA6300F170BDC4820L /* 254 */, 0xEBC18760ED78A77AL /* 255 */, }; private static final long[] t2 = { 0xE6A6BE5A05A12138L /* 256 */, 0xB5A122A5B4F87C98L /* 257 */, 0x563C6089140B6990L /* 258 */, 0x4C46CB2E391F5DD5L /* 259 */, 0xD932ADDBC9B79434L /* 260 */, 0x08EA70E42015AFF5L /* 261 */, 0xD765A6673E478CF1L /* 262 */, 0xC4FB757EAB278D99L /* 263 */, 0xDF11C6862D6E0692L /* 264 */, 0xDDEB84F10D7F3B16L /* 265 */, 0x6F2EF604A665EA04L /* 266 */, 0x4A8E0F0FF0E0DFB3L /* 267 */, 0xA5EDEEF83DBCBA51L /* 268 */, 0xFC4F0A2A0EA4371EL /* 269 */, 0xE83E1DA85CB38429L /* 270 */, 0xDC8FF882BA1B1CE2L /* 271 */, 0xCD45505E8353E80DL /* 272 */, 0x18D19A00D4DB0717L /* 273 */, 0x34A0CFEDA5F38101L /* 274 */, 0x0BE77E518887CAF2L /* 275 */, 0x1E341438B3C45136L /* 276 */, 0xE05797F49089CCF9L /* 277 */, 0xFFD23F9DF2591D14L /* 278 */, 0x543DDA228595C5CDL /* 279 */, 0x661F81FD99052A33L /* 280 */, 0x8736E641DB0F7B76L /* 281 */, 0x15227725418E5307L /* 282 */, 0xE25F7F46162EB2FAL /* 283 */, 0x48A8B2126C13D9FEL /* 284 */, 0xAFDC541792E76EEAL /* 285 */, 0x03D912BFC6D1898FL /* 286 */, 0x31B1AAFA1B83F51BL /* 287 */, 0xF1AC2796E42AB7D9L /* 288 */, 0x40A3A7D7FCD2EBACL /* 289 */, 0x1056136D0AFBBCC5L /* 290 */, 0x7889E1DD9A6D0C85L /* 291 */, 0xD33525782A7974AAL /* 292 */, 0xA7E25D09078AC09BL /* 293 */, 0xBD4138B3EAC6EDD0L /* 294 */, 0x920ABFBE71EB9E70L /* 295 */, 0xA2A5D0F54FC2625CL /* 296 */, 0xC054E36B0B1290A3L /* 297 */, 0xF6DD59FF62FE932BL /* 298 */, 0x3537354511A8AC7DL /* 299 */, 0xCA845E9172FADCD4L /* 300 */, 0x84F82B60329D20DCL /* 301 */, 0x79C62CE1CD672F18L /* 302 */, 0x8B09A2ADD124642CL /* 303 */, 0xD0C1E96A19D9E726L /* 304 */, 0x5A786A9B4BA9500CL /* 305 */, 0x0E020336634C43F3L /* 306 */, 0xC17B474AEB66D822L /* 307 */, 0x6A731AE3EC9BAAC2L /* 308 */, 0x8226667AE0840258L /* 309 */, 0x67D4567691CAECA5L /* 310 */, 0x1D94155C4875ADB5L /* 311 */, 0x6D00FD985B813FDFL /* 312 */, 0x51286EFCB774CD06L /* 313 */, 0x5E8834471FA744AFL /* 314 */, 0xF72CA0AEE761AE2EL /* 315 */, 0xBE40E4CDAEE8E09AL /* 316 */, 0xE9970BBB5118F665L /* 317 */, 0x726E4BEB33DF1964L /* 318 */, 0x703B000729199762L /* 319 */, 0x4631D816F5EF30A7L /* 320 */, 0xB880B5B51504A6BEL /* 321 */, 0x641793C37ED84B6CL /* 322 */, 0x7B21ED77F6E97D96L /* 323 */, 0x776306312EF96B73L /* 324 */, 0xAE528948E86FF3F4L /* 325 */, 0x53DBD7F286A3F8F8L /* 326 */, 0x16CADCE74CFC1063L /* 327 */, 0x005C19BDFA52C6DDL /* 328 */, 0x68868F5D64D46AD3L /* 329 */, 0x3A9D512CCF1E186AL /* 330 */, 0x367E62C2385660AEL /* 331 */, 0xE359E7EA77DCB1D7L /* 332 */, 0x526C0773749ABE6EL /* 333 */, 0x735AE5F9D09F734BL /* 334 */, 0x493FC7CC8A558BA8L /* 335 */, 0xB0B9C1533041AB45L /* 336 */, 0x321958BA470A59BDL /* 337 */, 0x852DB00B5F46C393L /* 338 */, 0x91209B2BD336B0E5L /* 339 */, 0x6E604F7D659EF19FL /* 340 */, 0xB99A8AE2782CCB24L /* 341 */, 0xCCF52AB6C814C4C7L /* 342 */, 0x4727D9AFBE11727BL /* 343 */, 0x7E950D0C0121B34DL /* 344 */, 0x756F435670AD471FL /* 345 */, 0xF5ADD442615A6849L /* 346 */, 0x4E87E09980B9957AL /* 347 */, 0x2ACFA1DF50AEE355L /* 348 */, 0xD898263AFD2FD556L /* 349 */, 0xC8F4924DD80C8FD6L /* 350 */, 0xCF99CA3D754A173AL /* 351 */, 0xFE477BACAF91BF3CL /* 352 */, 0xED5371F6D690C12DL /* 353 */, 0x831A5C285E687094L /* 354 */, 0xC5D3C90A3708A0A4L /* 355 */, 0x0F7F903717D06580L /* 356 */, 0x19F9BB13B8FDF27FL /* 357 */, 0xB1BD6F1B4D502843L /* 358 */, 0x1C761BA38FFF4012L /* 359 */, 0x0D1530C4E2E21F3BL /* 360 */, 0x8943CE69A7372C8AL /* 361 */, 0xE5184E11FEB5CE66L /* 362 */, 0x618BDB80BD736621L /* 363 */, 0x7D29BAD68B574D0BL /* 364 */, 0x81BB613E25E6FE5BL /* 365 */, 0x071C9C10BC07913FL /* 366 */, 0xC7BEEB7909AC2D97L /* 367 */, 0xC3E58D353BC5D757L /* 368 */, 0xEB017892F38F61E8L /* 369 */, 0xD4EFFB9C9B1CC21AL /* 370 */, 0x99727D26F494F7ABL /* 371 */, 0xA3E063A2956B3E03L /* 372 */, 0x9D4A8B9A4AA09C30L /* 373 */, 0x3F6AB7D500090FB4L /* 374 */, 0x9CC0F2A057268AC0L /* 375 */, 0x3DEE9D2DEDBF42D1L /* 376 */, 0x330F49C87960A972L /* 377 */, 0xC6B2720287421B41L /* 378 */, 0x0AC59EC07C00369CL /* 379 */, 0xEF4EAC49CB353425L /* 380 */, 0xF450244EEF0129D8L /* 381 */, 0x8ACC46E5CAF4DEB6L /* 382 */, 0x2FFEAB63989263F7L /* 383 */, 0x8F7CB9FE5D7A4578L /* 384 */, 0x5BD8F7644E634635L /* 385 */, 0x427A7315BF2DC900L /* 386 */, 0x17D0C4AA2125261CL /* 387 */, 0x3992486C93518E50L /* 388 */, 0xB4CBFEE0A2D7D4C3L /* 389 */, 0x7C75D6202C5DDD8DL /* 390 */, 0xDBC295D8E35B6C61L /* 391 */, 0x60B369D302032B19L /* 392 */, 0xCE42685FDCE44132L /* 393 */, 0x06F3DDB9DDF65610L /* 394 */, 0x8EA4D21DB5E148F0L /* 395 */, 0x20B0FCE62FCD496FL /* 396 */, 0x2C1B912358B0EE31L /* 397 */, 0xB28317B818F5A308L /* 398 */, 0xA89C1E189CA6D2CFL /* 399 */, 0x0C6B18576AAADBC8L /* 400 */, 0xB65DEAA91299FAE3L /* 401 */, 0xFB2B794B7F1027E7L /* 402 */, 0x04E4317F443B5BEBL /* 403 */, 0x4B852D325939D0A6L /* 404 */, 0xD5AE6BEEFB207FFCL /* 405 */, 0x309682B281C7D374L /* 406 */, 0xBAE309A194C3B475L /* 407 */, 0x8CC3F97B13B49F05L /* 408 */, 0x98A9422FF8293967L /* 409 */, 0x244B16B01076FF7CL /* 410 */, 0xF8BF571C663D67EEL /* 411 */, 0x1F0D6758EEE30DA1L /* 412 */, 0xC9B611D97ADEB9B7L /* 413 */, 0xB7AFD5887B6C57A2L /* 414 */, 0x6290AE846B984FE1L /* 415 */, 0x94DF4CDEACC1A5FDL /* 416 */, 0x058A5BD1C5483AFFL /* 417 */, 0x63166CC142BA3C37L /* 418 */, 0x8DB8526EB2F76F40L /* 419 */, 0xE10880036F0D6D4EL /* 420 */, 0x9E0523C9971D311DL /* 421 */, 0x45EC2824CC7CD691L /* 422 */, 0x575B8359E62382C9L /* 423 */, 0xFA9E400DC4889995L /* 424 */, 0xD1823ECB45721568L /* 425 */, 0xDAFD983B8206082FL /* 426 */, 0xAA7D29082386A8CBL /* 427 */, 0x269FCD4403B87588L /* 428 */, 0x1B91F5F728BDD1E0L /* 429 */, 0xE4669F39040201F6L /* 430 */, 0x7A1D7C218CF04ADEL /* 431 */, 0x65623C29D79CE5CEL /* 432 */, 0x2368449096C00BB1L /* 433 */, 0xAB9BF1879DA503BAL /* 434 */, 0xBC23ECB1A458058EL /* 435 */, 0x9A58DF01BB401ECCL /* 436 */, 0xA070E868A85F143DL /* 437 */, 0x4FF188307DF2239EL /* 438 */, 0x14D565B41A641183L /* 439 */, 0xEE13337452701602L /* 440 */, 0x950E3DCF3F285E09L /* 441 */, 0x59930254B9C80953L /* 442 */, 0x3BF299408930DA6DL /* 443 */, 0xA955943F53691387L /* 444 */, 0xA15EDECAA9CB8784L /* 445 */, 0x29142127352BE9A0L /* 446 */, 0x76F0371FFF4E7AFBL /* 447 */, 0x0239F450274F2228L /* 448 */, 0xBB073AF01D5E868BL /* 449 */, 0xBFC80571C10E96C1L /* 450 */, 0xD267088568222E23L /* 451 */, 0x9671A3D48E80B5B0L /* 452 */, 0x55B5D38AE193BB81L /* 453 */, 0x693AE2D0A18B04B8L /* 454 */, 0x5C48B4ECADD5335FL /* 455 */, 0xFD743B194916A1CAL /* 456 */, 0x2577018134BE98C4L /* 457 */, 0xE77987E83C54A4ADL /* 458 */, 0x28E11014DA33E1B9L /* 459 */, 0x270CC59E226AA213L /* 460 */, 0x71495F756D1A5F60L /* 461 */, 0x9BE853FB60AFEF77L /* 462 */, 0xADC786A7F7443DBFL /* 463 */, 0x0904456173B29A82L /* 464 */, 0x58BC7A66C232BD5EL /* 465 */, 0xF306558C673AC8B2L /* 466 */, 0x41F639C6B6C9772AL /* 467 */, 0x216DEFE99FDA35DAL /* 468 */, 0x11640CC71C7BE615L /* 469 */, 0x93C43694565C5527L /* 470 */, 0xEA038E6246777839L /* 471 */, 0xF9ABF3CE5A3E2469L /* 472 */, 0x741E768D0FD312D2L /* 473 */, 0x0144B883CED652C6L /* 474 */, 0xC20B5A5BA33F8552L /* 475 */, 0x1AE69633C3435A9DL /* 476 */, 0x97A28CA4088CFDECL /* 477 */, 0x8824A43C1E96F420L /* 478 */, 0x37612FA66EEEA746L /* 479 */, 0x6B4CB165F9CF0E5AL /* 480 */, 0x43AA1C06A0ABFB4AL /* 481 */, 0x7F4DC26FF162796BL /* 482 */, 0x6CBACC8E54ED9B0FL /* 483 */, 0xA6B7FFEFD2BB253EL /* 484 */, 0x2E25BC95B0A29D4FL /* 485 */, 0x86D6A58BDEF1388CL /* 486 */, 0xDED74AC576B6F054L /* 487 */, 0x8030BDBC2B45805DL /* 488 */, 0x3C81AF70E94D9289L /* 489 */, 0x3EFF6DDA9E3100DBL /* 490 */, 0xB38DC39FDFCC8847L /* 491 */, 0x123885528D17B87EL /* 492 */, 0xF2DA0ED240B1B642L /* 493 */, 0x44CEFADCD54BF9A9L /* 494 */, 0x1312200E433C7EE6L /* 495 */, 0x9FFCC84F3A78C748L /* 496 */, 0xF0CD1F72248576BBL /* 497 */, 0xEC6974053638CFE4L /* 498 */, 0x2BA7B67C0CEC4E4CL /* 499 */, 0xAC2F4DF3E5CE32EDL /* 500 */, 0xCB33D14326EA4C11L /* 501 */, 0xA4E9044CC77E58BCL /* 502 */, 0x5F513293D934FCEFL /* 503 */, 0x5DC9645506E55444L /* 504 */, 0x50DE418F317DE40AL /* 505 */, 0x388CB31A69DDE259L /* 506 */, 0x2DB4A83455820A86L /* 507 */, 0x9010A91E84711AE9L /* 508 */, 0x4DF7F0B7B1498371L /* 509 */, 0xD62A2EABC0977179L /* 510 */, 0x22FAC097AA8D5C0EL /* 511 */, }; private static final long[] t3 = { 0xF49FCC2FF1DAF39BL /* 512 */, 0x487FD5C66FF29281L /* 513 */, 0xE8A30667FCDCA83FL /* 514 */, 0x2C9B4BE3D2FCCE63L /* 515 */, 0xDA3FF74B93FBBBC2L /* 516 */, 0x2FA165D2FE70BA66L /* 517 */, 0xA103E279970E93D4L /* 518 */, 0xBECDEC77B0E45E71L /* 519 */, 0xCFB41E723985E497L /* 520 */, 0xB70AAA025EF75017L /* 521 */, 0xD42309F03840B8E0L /* 522 */, 0x8EFC1AD035898579L /* 523 */, 0x96C6920BE2B2ABC5L /* 524 */, 0x66AF4163375A9172L /* 525 */, 0x2174ABDCCA7127FBL /* 526 */, 0xB33CCEA64A72FF41L /* 527 */, 0xF04A4933083066A5L /* 528 */, 0x8D970ACDD7289AF5L /* 529 */, 0x8F96E8E031C8C25EL /* 530 */, 0xF3FEC02276875D47L /* 531 */, 0xEC7BF310056190DDL /* 532 */, 0xF5ADB0AEBB0F1491L /* 533 */, 0x9B50F8850FD58892L /* 534 */, 0x4975488358B74DE8L /* 535 */, 0xA3354FF691531C61L /* 536 */, 0x0702BBE481D2C6EEL /* 537 */, 0x89FB24057DEDED98L /* 538 */, 0xAC3075138596E902L /* 539 */, 0x1D2D3580172772EDL /* 540 */, 0xEB738FC28E6BC30DL /* 541 */, 0x5854EF8F63044326L /* 542 */, 0x9E5C52325ADD3BBEL /* 543 */, 0x90AA53CF325C4623L /* 544 */, 0xC1D24D51349DD067L /* 545 */, 0x2051CFEEA69EA624L /* 546 */, 0x13220F0A862E7E4FL /* 547 */, 0xCE39399404E04864L /* 548 */, 0xD9C42CA47086FCB7L /* 549 */, 0x685AD2238A03E7CCL /* 550 */, 0x066484B2AB2FF1DBL /* 551 */, 0xFE9D5D70EFBF79ECL /* 552 */, 0x5B13B9DD9C481854L /* 553 */, 0x15F0D475ED1509ADL /* 554 */, 0x0BEBCD060EC79851L /* 555 */, 0xD58C6791183AB7F8L /* 556 */, 0xD1187C5052F3EEE4L /* 557 */, 0xC95D1192E54E82FFL /* 558 */, 0x86EEA14CB9AC6CA2L /* 559 */, 0x3485BEB153677D5DL /* 560 */, 0xDD191D781F8C492AL /* 561 */, 0xF60866BAA784EBF9L /* 562 */, 0x518F643BA2D08C74L /* 563 */, 0x8852E956E1087C22L /* 564 */, 0xA768CB8DC410AE8DL /* 565 */, 0x38047726BFEC8E1AL /* 566 */, 0xA67738B4CD3B45AAL /* 567 */, 0xAD16691CEC0DDE19L /* 568 */, 0xC6D4319380462E07L /* 569 */, 0xC5A5876D0BA61938L /* 570 */, 0x16B9FA1FA58FD840L /* 571 */, 0x188AB1173CA74F18L /* 572 */, 0xABDA2F98C99C021FL /* 573 */, 0x3E0580AB134AE816L /* 574 */, 0x5F3B05B773645ABBL /* 575 */, 0x2501A2BE5575F2F6L /* 576 */, 0x1B2F74004E7E8BA9L /* 577 */, 0x1CD7580371E8D953L /* 578 */, 0x7F6ED89562764E30L /* 579 */, 0xB15926FF596F003DL /* 580 */, 0x9F65293DA8C5D6B9L /* 581 */, 0x6ECEF04DD690F84CL /* 582 */, 0x4782275FFF33AF88L /* 583 */, 0xE41433083F820801L /* 584 */, 0xFD0DFE409A1AF9B5L /* 585 */, 0x4325A3342CDB396BL /* 586 */, 0x8AE77E62B301B252L /* 587 */, 0xC36F9E9F6655615AL /* 588 */, 0x85455A2D92D32C09L /* 589 */, 0xF2C7DEA949477485L /* 590 */, 0x63CFB4C133A39EBAL /* 591 */, 0x83B040CC6EBC5462L /* 592 */, 0x3B9454C8FDB326B0L /* 593 */, 0x56F56A9E87FFD78CL /* 594 */, 0x2DC2940D99F42BC6L /* 595 */, 0x98F7DF096B096E2DL /* 596 */, 0x19A6E01E3AD852BFL /* 597 */, 0x42A99CCBDBD4B40BL /* 598 */, 0xA59998AF45E9C559L /* 599 */, 0x366295E807D93186L /* 600 */, 0x6B48181BFAA1F773L /* 601 */, 0x1FEC57E2157A0A1DL /* 602 */, 0x4667446AF6201AD5L /* 603 */, 0xE615EBCACFB0F075L /* 604 */, 0xB8F31F4F68290778L /* 605 */, 0x22713ED6CE22D11EL /* 606 */, 0x3057C1A72EC3C93BL /* 607 */, 0xCB46ACC37C3F1F2FL /* 608 */, 0xDBB893FD02AAF50EL /* 609 */, 0x331FD92E600B9FCFL /* 610 */, 0xA498F96148EA3AD6L /* 611 */, 0xA8D8426E8B6A83EAL /* 612 */, 0xA089B274B7735CDCL /* 613 */, 0x87F6B3731E524A11L /* 614 */, 0x118808E5CBC96749L /* 615 */, 0x9906E4C7B19BD394L /* 616 */, 0xAFED7F7E9B24A20CL /* 617 */, 0x6509EADEEB3644A7L /* 618 */, 0x6C1EF1D3E8EF0EDEL /* 619 */, 0xB9C97D43E9798FB4L /* 620 */, 0xA2F2D784740C28A3L /* 621 */, 0x7B8496476197566FL /* 622 */, 0x7A5BE3E6B65F069DL /* 623 */, 0xF96330ED78BE6F10L /* 624 */, 0xEEE60DE77A076A15L /* 625 */, 0x2B4BEE4AA08B9BD0L /* 626 */, 0x6A56A63EC7B8894EL /* 627 */, 0x02121359BA34FEF4L /* 628 */, 0x4CBF99F8283703FCL /* 629 */, 0x398071350CAF30C8L /* 630 */, 0xD0A77A89F017687AL /* 631 */, 0xF1C1A9EB9E423569L /* 632 */, 0x8C7976282DEE8199L /* 633 */, 0x5D1737A5DD1F7ABDL /* 634 */, 0x4F53433C09A9FA80L /* 635 */, 0xFA8B0C53DF7CA1D9L /* 636 */, 0x3FD9DCBC886CCB77L /* 637 */, 0xC040917CA91B4720L /* 638 */, 0x7DD00142F9D1DCDFL /* 639 */, 0x8476FC1D4F387B58L /* 640 */, 0x23F8E7C5F3316503L /* 641 */, 0x032A2244E7E37339L /* 642 */, 0x5C87A5D750F5A74BL /* 643 */, 0x082B4CC43698992EL /* 644 */, 0xDF917BECB858F63CL /* 645 */, 0x3270B8FC5BF86DDAL /* 646 */, 0x10AE72BB29B5DD76L /* 647 */, 0x576AC94E7700362BL /* 648 */, 0x1AD112DAC61EFB8FL /* 649 */, 0x691BC30EC5FAA427L /* 650 */, 0xFF246311CC327143L /* 651 */, 0x3142368E30E53206L /* 652 */, 0x71380E31E02CA396L /* 653 */, 0x958D5C960AAD76F1L /* 654 */, 0xF8D6F430C16DA536L /* 655 */, 0xC8FFD13F1BE7E1D2L /* 656 */, 0x7578AE66004DDBE1L /* 657 */, 0x05833F01067BE646L /* 658 */, 0xBB34B5AD3BFE586DL /* 659 */, 0x095F34C9A12B97F0L /* 660 */, 0x247AB64525D60CA8L /* 661 */, 0xDCDBC6F3017477D1L /* 662 */, 0x4A2E14D4DECAD24DL /* 663 */, 0xBDB5E6D9BE0A1EEBL /* 664 */, 0x2A7E70F7794301ABL /* 665 */, 0xDEF42D8A270540FDL /* 666 */, 0x01078EC0A34C22C1L /* 667 */, 0xE5DE511AF4C16387L /* 668 */, 0x7EBB3A52BD9A330AL /* 669 */, 0x77697857AA7D6435L /* 670 */, 0x004E831603AE4C32L /* 671 */, 0xE7A21020AD78E312L /* 672 */, 0x9D41A70C6AB420F2L /* 673 */, 0x28E06C18EA1141E6L /* 674 */, 0xD2B28CBD984F6B28L /* 675 */, 0x26B75F6C446E9D83L /* 676 */, 0xBA47568C4D418D7FL /* 677 */, 0xD80BADBFE6183D8EL /* 678 */, 0x0E206D7F5F166044L /* 679 */, 0xE258A43911CBCA3EL /* 680 */, 0x723A1746B21DC0BCL /* 681 */, 0xC7CAA854F5D7CDD3L /* 682 */, 0x7CAC32883D261D9CL /* 683 */, 0x7690C26423BA942CL /* 684 */, 0x17E55524478042B8L /* 685 */, 0xE0BE477656A2389FL /* 686 */, 0x4D289B5E67AB2DA0L /* 687 */, 0x44862B9C8FBBFD31L /* 688 */, 0xB47CC8049D141365L /* 689 */, 0x822C1B362B91C793L /* 690 */, 0x4EB14655FB13DFD8L /* 691 */, 0x1ECBBA0714E2A97BL /* 692 */, 0x6143459D5CDE5F14L /* 693 */, 0x53A8FBF1D5F0AC89L /* 694 */, 0x97EA04D81C5E5B00L /* 695 */, 0x622181A8D4FDB3F3L /* 696 */, 0xE9BCD341572A1208L /* 697 */, 0x1411258643CCE58AL /* 698 */, 0x9144C5FEA4C6E0A4L /* 699 */, 0x0D33D06565CF620FL /* 700 */, 0x54A48D489F219CA1L /* 701 */, 0xC43E5EAC6D63C821L /* 702 */, 0xA9728B3A72770DAFL /* 703 */, 0xD7934E7B20DF87EFL /* 704 */, 0xE35503B61A3E86E5L /* 705 */, 0xCAE321FBC819D504L /* 706 */, 0x129A50B3AC60BFA6L /* 707 */, 0xCD5E68EA7E9FB6C3L /* 708 */, 0xB01C90199483B1C7L /* 709 */, 0x3DE93CD5C295376CL /* 710 */, 0xAED52EDF2AB9AD13L /* 711 */, 0x2E60F512C0A07884L /* 712 */, 0xBC3D86A3E36210C9L /* 713 */, 0x35269D9B163951CEL /* 714 */, 0x0C7D6E2AD0CDB5FAL /* 715 */, 0x59E86297D87F5733L /* 716 */, 0x298EF221898DB0E7L /* 717 */, 0x55000029D1A5AA7EL /* 718 */, 0x8BC08AE1B5061B45L /* 719 */, 0xC2C31C2B6C92703AL /* 720 */, 0x94CC596BAF25EF42L /* 721 */, 0x0A1D73DB22540456L /* 722 */, 0x04B6A0F9D9C4179AL /* 723 */, 0xEFFDAFA2AE3D3C60L /* 724 */, 0xF7C8075BB49496C4L /* 725 */, 0x9CC5C7141D1CD4E3L /* 726 */, 0x78BD1638218E5534L /* 727 */, 0xB2F11568F850246AL /* 728 */, 0xEDFABCFA9502BC29L /* 729 */, 0x796CE5F2DA23051BL /* 730 */, 0xAAE128B0DC93537CL /* 731 */, 0x3A493DA0EE4B29AEL /* 732 */, 0xB5DF6B2C416895D7L /* 733 */, 0xFCABBD25122D7F37L /* 734 */, 0x70810B58105DC4B1L /* 735 */, 0xE10FDD37F7882A90L /* 736 */, 0x524DCAB5518A3F5CL /* 737 */, 0x3C9E85878451255BL /* 738 */, 0x4029828119BD34E2L /* 739 */, 0x74A05B6F5D3CECCBL /* 740 */, 0xB610021542E13ECAL /* 741 */, 0x0FF979D12F59E2ACL /* 742 */, 0x6037DA27E4F9CC50L /* 743 */, 0x5E92975A0DF1847DL /* 744 */, 0xD66DE190D3E623FEL /* 745 */, 0x5032D6B87B568048L /* 746 */, 0x9A36B7CE8235216EL /* 747 */, 0x80272A7A24F64B4AL /* 748 */, 0x93EFED8B8C6916F7L /* 749 */, 0x37DDBFF44CCE1555L /* 750 */, 0x4B95DB5D4B99BD25L /* 751 */, 0x92D3FDA169812FC0L /* 752 */, 0xFB1A4A9A90660BB6L /* 753 */, 0x730C196946A4B9B2L /* 754 */, 0x81E289AA7F49DA68L /* 755 */, 0x64669A0F83B1A05FL /* 756 */, 0x27B3FF7D9644F48BL /* 757 */, 0xCC6B615C8DB675B3L /* 758 */, 0x674F20B9BCEBBE95L /* 759 */, 0x6F31238275655982L /* 760 */, 0x5AE488713E45CF05L /* 761 */, 0xBF619F9954C21157L /* 762 */, 0xEABAC46040A8EAE9L /* 763 */, 0x454C6FE9F2C0C1CDL /* 764 */, 0x419CF6496412691CL /* 765 */, 0xD3DC3BEF265B0F70L /* 766 */, 0x6D0E60F5C3578A9EL /* 767 */, }; private static final long[] t4 = { 0x5B0E608526323C55L /* 768 */, 0x1A46C1A9FA1B59F5L /* 769 */, 0xA9E245A17C4C8FFAL /* 770 */, 0x65CA5159DB2955D7L /* 771 */, 0x05DB0A76CE35AFC2L /* 772 */, 0x81EAC77EA9113D45L /* 773 */, 0x528EF88AB6AC0A0DL /* 774 */, 0xA09EA253597BE3FFL /* 775 */, 0x430DDFB3AC48CD56L /* 776 */, 0xC4B3A67AF45CE46FL /* 777 */, 0x4ECECFD8FBE2D05EL /* 778 */, 0x3EF56F10B39935F0L /* 779 */, 0x0B22D6829CD619C6L /* 780 */, 0x17FD460A74DF2069L /* 781 */, 0x6CF8CC8E8510ED40L /* 782 */, 0xD6C824BF3A6ECAA7L /* 783 */, 0x61243D581A817049L /* 784 */, 0x048BACB6BBC163A2L /* 785 */, 0xD9A38AC27D44CC32L /* 786 */, 0x7FDDFF5BAAF410ABL /* 787 */, 0xAD6D495AA804824BL /* 788 */, 0xE1A6A74F2D8C9F94L /* 789 */, 0xD4F7851235DEE8E3L /* 790 */, 0xFD4B7F886540D893L /* 791 */, 0x247C20042AA4BFDAL /* 792 */, 0x096EA1C517D1327CL /* 793 */, 0xD56966B4361A6685L /* 794 */, 0x277DA5C31221057DL /* 795 */, 0x94D59893A43ACFF7L /* 796 */, 0x64F0C51CCDC02281L /* 797 */, 0x3D33BCC4FF6189DBL /* 798 */, 0xE005CB184CE66AF1L /* 799 */, 0xFF5CCD1D1DB99BEAL /* 800 */, 0xB0B854A7FE42980FL /* 801 */, 0x7BD46A6A718D4B9FL /* 802 */, 0xD10FA8CC22A5FD8CL /* 803 */, 0xD31484952BE4BD31L /* 804 */, 0xC7FA975FCB243847L /* 805 */, 0x4886ED1E5846C407L /* 806 */, 0x28CDDB791EB70B04L /* 807 */, 0xC2B00BE2F573417FL /* 808 */, 0x5C9590452180F877L /* 809 */, 0x7A6BDDFFF370EB00L /* 810 */, 0xCE509E38D6D9D6A4L /* 811 */, 0xEBEB0F00647FA702L /* 812 */, 0x1DCC06CF76606F06L /* 813 */, 0xE4D9F28BA286FF0AL /* 814 */, 0xD85A305DC918C262L /* 815 */, 0x475B1D8732225F54L /* 816 */, 0x2D4FB51668CCB5FEL /* 817 */, 0xA679B9D9D72BBA20L /* 818 */, 0x53841C0D912D43A5L /* 819 */, 0x3B7EAA48BF12A4E8L /* 820 */, 0x781E0E47F22F1DDFL /* 821 */, 0xEFF20CE60AB50973L /* 822 */, 0x20D261D19DFFB742L /* 823 */, 0x16A12B03062A2E39L /* 824 */, 0x1960EB2239650495L /* 825 */, 0x251C16FED50EB8B8L /* 826 */, 0x9AC0C330F826016EL /* 827 */, 0xED152665953E7671L /* 828 */, 0x02D63194A6369570L /* 829 */, 0x5074F08394B1C987L /* 830 */, 0x70BA598C90B25CE1L /* 831 */, 0x794A15810B9742F6L /* 832 */, 0x0D5925E9FCAF8C6CL /* 833 */, 0x3067716CD868744EL /* 834 */, 0x910AB077E8D7731BL /* 835 */, 0x6A61BBDB5AC42F61L /* 836 */, 0x93513EFBF0851567L /* 837 */, 0xF494724B9E83E9D5L /* 838 */, 0xE887E1985C09648DL /* 839 */, 0x34B1D3C675370CFDL /* 840 */, 0xDC35E433BC0D255DL /* 841 */, 0xD0AAB84234131BE0L /* 842 */, 0x08042A50B48B7EAFL /* 843 */, 0x9997C4EE44A3AB35L /* 844 */, 0x829A7B49201799D0L /* 845 */, 0x263B8307B7C54441L /* 846 */, 0x752F95F4FD6A6CA6L /* 847 */, 0x927217402C08C6E5L /* 848 */, 0x2A8AB754A795D9EEL /* 849 */, 0xA442F7552F72943DL /* 850 */, 0x2C31334E19781208L /* 851 */, 0x4FA98D7CEAEE6291L /* 852 */, 0x55C3862F665DB309L /* 853 */, 0xBD0610175D53B1F3L /* 854 */, 0x46FE6CB840413F27L /* 855 */, 0x3FE03792DF0CFA59L /* 856 */, 0xCFE700372EB85E8FL /* 857 */, 0xA7BE29E7ADBCE118L /* 858 */, 0xE544EE5CDE8431DDL /* 859 */, 0x8A781B1B41F1873EL /* 860 */, 0xA5C94C78A0D2F0E7L /* 861 */, 0x39412E2877B60728L /* 862 */, 0xA1265EF3AFC9A62CL /* 863 */, 0xBCC2770C6A2506C5L /* 864 */, 0x3AB66DD5DCE1CE12L /* 865 */, 0xE65499D04A675B37L /* 866 */, 0x7D8F523481BFD216L /* 867 */, 0x0F6F64FCEC15F389L /* 868 */, 0x74EFBE618B5B13C8L /* 869 */, 0xACDC82B714273E1DL /* 870 */, 0xDD40BFE003199D17L /* 871 */, 0x37E99257E7E061F8L /* 872 */, 0xFA52626904775AAAL /* 873 */, 0x8BBBF63A463D56F9L /* 874 */, 0xF0013F1543A26E64L /* 875 */, 0xA8307E9F879EC898L /* 876 */, 0xCC4C27A4150177CCL /* 877 */, 0x1B432F2CCA1D3348L /* 878 */, 0xDE1D1F8F9F6FA013L /* 879 */, 0x606602A047A7DDD6L /* 880 */, 0xD237AB64CC1CB2C7L /* 881 */, 0x9B938E7225FCD1D3L /* 882 */, 0xEC4E03708E0FF476L /* 883 */, 0xFEB2FBDA3D03C12DL /* 884 */, 0xAE0BCED2EE43889AL /* 885 */, 0x22CB8923EBFB4F43L /* 886 */, 0x69360D013CF7396DL /* 887 */, 0x855E3602D2D4E022L /* 888 */, 0x073805BAD01F784CL /* 889 */, 0x33E17A133852F546L /* 890 */, 0xDF4874058AC7B638L /* 891 */, 0xBA92B29C678AA14AL /* 892 */, 0x0CE89FC76CFAADCDL /* 893 */, 0x5F9D4E0908339E34L /* 894 */, 0xF1AFE9291F5923B9L /* 895 */, 0x6E3480F60F4A265FL /* 896 */, 0xEEBF3A2AB29B841CL /* 897 */, 0xE21938A88F91B4ADL /* 898 */, 0x57DFEFF845C6D3C3L /* 899 */, 0x2F006B0BF62CAAF2L /* 900 */, 0x62F479EF6F75EE78L /* 901 */, 0x11A55AD41C8916A9L /* 902 */, 0xF229D29084FED453L /* 903 */, 0x42F1C27B16B000E6L /* 904 */, 0x2B1F76749823C074L /* 905 */, 0x4B76ECA3C2745360L /* 906 */, 0x8C98F463B91691BDL /* 907 */, 0x14BCC93CF1ADE66AL /* 908 */, 0x8885213E6D458397L /* 909 */, 0x8E177DF0274D4711L /* 910 */, 0xB49B73B5503F2951L /* 911 */, 0x10168168C3F96B6BL /* 912 */, 0x0E3D963B63CAB0AEL /* 913 */, 0x8DFC4B5655A1DB14L /* 914 */, 0xF789F1356E14DE5CL /* 915 */, 0x683E68AF4E51DAC1L /* 916 */, 0xC9A84F9D8D4B0FD9L /* 917 */, 0x3691E03F52A0F9D1L /* 918 */, 0x5ED86E46E1878E80L /* 919 */, 0x3C711A0E99D07150L /* 920 */, 0x5A0865B20C4E9310L /* 921 */, 0x56FBFC1FE4F0682EL /* 922 */, 0xEA8D5DE3105EDF9BL /* 923 */, 0x71ABFDB12379187AL /* 924 */, 0x2EB99DE1BEE77B9CL /* 925 */, 0x21ECC0EA33CF4523L /* 926 */, 0x59A4D7521805C7A1L /* 927 */, 0x3896F5EB56AE7C72L /* 928 */, 0xAA638F3DB18F75DCL /* 929 */, 0x9F39358DABE9808EL /* 930 */, 0xB7DEFA91C00B72ACL /* 931 */, 0x6B5541FD62492D92L /* 932 */, 0x6DC6DEE8F92E4D5BL /* 933 */, 0x353F57ABC4BEEA7EL /* 934 */, 0x735769D6DA5690CEL /* 935 */, 0x0A234AA642391484L /* 936 */, 0xF6F9508028F80D9DL /* 937 */, 0xB8E319A27AB3F215L /* 938 */, 0x31AD9C1151341A4DL /* 939 */, 0x773C22A57BEF5805L /* 940 */, 0x45C7561A07968633L /* 941 */, 0xF913DA9E249DBE36L /* 942 */, 0xDA652D9B78A64C68L /* 943 */, 0x4C27A97F3BC334EFL /* 944 */, 0x76621220E66B17F4L /* 945 */, 0x967743899ACD7D0BL /* 946 */, 0xF3EE5BCAE0ED6782L /* 947 */, 0x409F753600C879FCL /* 948 */, 0x06D09A39B5926DB6L /* 949 */, 0x6F83AEB0317AC588L /* 950 */, 0x01E6CA4A86381F21L /* 951 */, 0x66FF3462D19F3025L /* 952 */, 0x72207C24DDFD3BFBL /* 953 */, 0x4AF6B6D3E2ECE2EBL /* 954 */, 0x9C994DBEC7EA08DEL /* 955 */, 0x49ACE597B09A8BC4L /* 956 */, 0xB38C4766CF0797BAL /* 957 */, 0x131B9373C57C2A75L /* 958 */, 0xB1822CCE61931E58L /* 959 */, 0x9D7555B909BA1C0CL /* 960 */, 0x127FAFDD937D11D2L /* 961 */, 0x29DA3BADC66D92E4L /* 962 */, 0xA2C1D57154C2ECBCL /* 963 */, 0x58C5134D82F6FE24L /* 964 */, 0x1C3AE3515B62274FL /* 965 */, 0xE907C82E01CB8126L /* 966 */, 0xF8ED091913E37FCBL /* 967 */, 0x3249D8F9C80046C9L /* 968 */, 0x80CF9BEDE388FB63L /* 969 */, 0x1881539A116CF19EL /* 970 */, 0x5103F3F76BD52457L /* 971 */, 0x15B7E6F5AE47F7A8L /* 972 */, 0xDBD7C6DED47E9CCFL /* 973 */, 0x44E55C410228BB1AL /* 974 */, 0xB647D4255EDB4E99L /* 975 */, 0x5D11882BB8AAFC30L /* 976 */, 0xF5098BBB29D3212AL /* 977 */, 0x8FB5EA14E90296B3L /* 978 */, 0x677B942157DD025AL /* 979 */, 0xFB58E7C0A390ACB5L /* 980 */, 0x89D3674C83BD4A01L /* 981 */, 0x9E2DA4DF4BF3B93BL /* 982 */, 0xFCC41E328CAB4829L /* 983 */, 0x03F38C96BA582C52L /* 984 */, 0xCAD1BDBD7FD85DB2L /* 985 */, 0xBBB442C16082AE83L /* 986 */, 0xB95FE86BA5DA9AB0L /* 987 */, 0xB22E04673771A93FL /* 988 */, 0x845358C9493152D8L /* 989 */, 0xBE2A488697B4541EL /* 990 */, 0x95A2DC2DD38E6966L /* 991 */, 0xC02C11AC923C852BL /* 992 */, 0x2388B1990DF2A87BL /* 993 */, 0x7C8008FA1B4F37BEL /* 994 */, 0x1F70D0C84D54E503L /* 995 */, 0x5490ADEC7ECE57D4L /* 996 */, 0x002B3C27D9063A3AL /* 997 */, 0x7EAEA3848030A2BFL /* 998 */, 0xC602326DED2003C0L /* 999 */, 0x83A7287D69A94086L /* 1000 */, 0xC57A5FCB30F57A8AL /* 1001 */, 0xB56844E479EBE779L /* 1002 */, 0xA373B40F05DCBCE9L /* 1003 */, 0xD71A786E88570EE2L /* 1004 */, 0x879CBACDBDE8F6A0L /* 1005 */, 0x976AD1BCC164A32FL /* 1006 */, 0xAB21E25E9666D78BL /* 1007 */, 0x901063AAE5E5C33CL /* 1008 */, 0x9818B34448698D90L /* 1009 */, 0xE36487AE3E1E8ABBL /* 1010 */, 0xAFBDF931893BDCB4L /* 1011 */, 0x6345A0DC5FBBD519L /* 1012 */, 0x8628FE269B9465CAL /* 1013 */, 0x1E5D01603F9C51ECL /* 1014 */, 0x4DE44006A15049B7L /* 1015 */, 0xBF6C70E5F776CBB1L /* 1016 */, 0x411218F2EF552BEDL /* 1017 */, 0xCB0C0708705A36A3L /* 1018 */, 0xE74D14754F986044L /* 1019 */, 0xCD56D9430EA8280EL /* 1020 */, 0xC12591D7535F5065L /* 1021 */, 0xC83223F1720AEF96L /* 1022 */, 0xC3A0396F7363A51FL /* 1023 */ }; private static final int DIGEST_LENGTH = 24; // // registers // private long a, b, c; private long byteCount; // // buffers // private byte[] buf = new byte[8]; private int bOff = 0; private long[] x = new long[8]; private int xOff = 0; /** * Standard constructor */ public TigerDigest() { reset(); } /** * Copy constructor. This will copy the state of the provided * message digest. */ public TigerDigest(TigerDigest t) { this.reset(t); } public String getAlgorithmName() { return "Tiger"; } public int getDigestSize() { return DIGEST_LENGTH; } private void processWord( byte[] b, int off) { x[xOff++] = ((long)(b[off + 7] & 0xff) << 56) | ((long)(b[off + 6] & 0xff) << 48) | ((long)(b[off + 5] & 0xff) << 40) | ((long)(b[off + 4] & 0xff) << 32) | ((long)(b[off + 3] & 0xff) << 24) | ((long)(b[off + 2] & 0xff) << 16) | ((long)(b[off + 1] & 0xff) << 8) | ((b[off + 0] & 0xff)); if (xOff == x.length) { processBlock(); } bOff = 0; } public void update( byte in) { buf[bOff++] = in; if (bOff == buf.length) { processWord(buf, 0); } byteCount++; } public void update( byte[] in, int inOff, int len) { // // fill the current word // while ((bOff != 0) && (len > 0)) { update(in[inOff]); inOff++; len--; } // // process whole words. // while (len > 8) { processWord(in, inOff); inOff += 8; len -= 8; byteCount += 8; } // // load in the remainder. // while (len > 0) { update(in[inOff]); inOff++; len--; } } private void roundABC( long x, long mul) { c ^= x ; a -= t1[(int)c & 0xff] ^ t2[(int)(c >> 16) & 0xff] ^ t3[(int)(c >> 32) & 0xff] ^ t4[(int)(c >> 48) & 0xff]; b += t4[(int)(c >> 8) & 0xff] ^ t3[(int)(c >> 24) & 0xff] ^ t2[(int)(c >> 40) & 0xff] ^ t1[(int)(c >> 56) & 0xff]; b *= mul; } private void roundBCA( long x, long mul) { a ^= x ; b -= t1[(int)a & 0xff] ^ t2[(int)(a >> 16) & 0xff] ^ t3[(int)(a >> 32) & 0xff] ^ t4[(int)(a >> 48) & 0xff]; c += t4[(int)(a >> 8) & 0xff] ^ t3[(int)(a >> 24) & 0xff] ^ t2[(int)(a >> 40) & 0xff] ^ t1[(int)(a >> 56) & 0xff]; c *= mul; } private void roundCAB( long x, long mul) { b ^= x ; c -= t1[(int)b & 0xff] ^ t2[(int)(b >> 16) & 0xff] ^ t3[(int)(b >> 32) & 0xff] ^ t4[(int)(b >> 48) & 0xff]; a += t4[(int)(b >> 8) & 0xff] ^ t3[(int)(b >> 24) & 0xff] ^ t2[(int)(b >> 40) & 0xff] ^ t1[(int)(b >> 56) & 0xff]; a *= mul; } private void keySchedule() { x[0] -= x[7] ^ 0xA5A5A5A5A5A5A5A5L; x[1] ^= x[0]; x[2] += x[1]; x[3] -= x[2] ^ ((~x[1]) << 19); x[4] ^= x[3]; x[5] += x[4]; x[6] -= x[5] ^ ((~x[4]) >>> 23); x[7] ^= x[6]; x[0] += x[7]; x[1] -= x[0] ^ ((~x[7]) << 19); x[2] ^= x[1]; x[3] += x[2]; x[4] -= x[3] ^ ((~x[2]) >>> 23); x[5] ^= x[4]; x[6] += x[5]; x[7] -= x[6] ^ 0x0123456789ABCDEFL; } private void processBlock() { // // save abc // long aa = a; long bb = b; long cc = c; // // rounds and schedule // roundABC(x[0], 5); roundBCA(x[1], 5); roundCAB(x[2], 5); roundABC(x[3], 5); roundBCA(x[4], 5); roundCAB(x[5], 5); roundABC(x[6], 5); roundBCA(x[7], 5); keySchedule(); roundCAB(x[0], 7); roundABC(x[1], 7); roundBCA(x[2], 7); roundCAB(x[3], 7); roundABC(x[4], 7); roundBCA(x[5], 7); roundCAB(x[6], 7); roundABC(x[7], 7); keySchedule(); roundBCA(x[0], 9); roundCAB(x[1], 9); roundABC(x[2], 9); roundBCA(x[3], 9); roundCAB(x[4], 9); roundABC(x[5], 9); roundBCA(x[6], 9); roundCAB(x[7], 9); // // feed forward // a ^= aa; b -= bb; c += cc; // // clear the x buffer // xOff = 0; for (int i = 0; i != x.length; i++) { x[i] = 0; } } public void unpackWord( long r, byte[] out, int outOff) { out[outOff + 7] = (byte)(r >> 56); out[outOff + 6] = (byte)(r >> 48); out[outOff + 5] = (byte)(r >> 40); out[outOff + 4] = (byte)(r >> 32); out[outOff + 3] = (byte)(r >> 24); out[outOff + 2] = (byte)(r >> 16); out[outOff + 1] = (byte)(r >> 8); out[outOff] = (byte)r; } private void processLength( long bitLength) { x[7] = bitLength; } private void finish() { long bitLength = (byteCount << 3); update((byte)0x01); while (bOff != 0) { update((byte)0); } processLength(bitLength); processBlock(); } public int doFinal( byte[] out, int outOff) { finish(); unpackWord(a, out, outOff); unpackWord(b, out, outOff + 8); unpackWord(c, out, outOff + 16); reset(); return DIGEST_LENGTH; } /** * reset the chaining variables */ public void reset() { a = 0x0123456789ABCDEFL; b = 0xFEDCBA9876543210L; c = 0xF096A5B4C3B2E187L; xOff = 0; for (int i = 0; i != x.length; i++) { x[i] = 0; } bOff = 0; for (int i = 0; i != buf.length; i++) { buf[i] = 0; } byteCount = 0; } public int getByteLength() { return BYTE_LENGTH; } public Memoable copy() { return new TigerDigest(this); } public void reset(Memoable other) { TigerDigest t = (TigerDigest)other; a = t.a; b = t.b; c = t.c; System.arraycopy(t.x, 0, x, 0, t.x.length); xOff = t.xOff; System.arraycopy(t.buf, 0, buf, 0, t.buf.length); bOff = t.bOff; byteCount = t.byteCount; } } bouncycastle-1.49.orig/src/org/bouncycastle/crypto/digests/SHA384Digest.java0000644000175000017500000000402512143607301026337 0ustar ebourgebourgpackage org.bouncycastle.crypto.digests; import org.bouncycastle.crypto.util.Pack; import org.bouncycastle.util.Memoable; /** * FIPS 180-2 implementation of SHA-384. * *
     *         block  word  digest
     * SHA-1   512    32    160
     * SHA-256 512    32    256
     * SHA-384 1024   64    384
     * SHA-512 1024   64    512
     * 
    */ public class SHA384Digest extends LongDigest { private static final int DIGEST_LENGTH = 48; /** * Standard constructor */ public SHA384Digest() { } /** * Copy constructor. This will copy the state of the provided * message digest. */ public SHA384Digest(SHA384Digest t) { super(t); } public String getAlgorithmName() { return "SHA-384"; } public int getDigestSize() { return DIGEST_LENGTH; } public int doFinal( byte[] out, int outOff) { finish(); Pack.longToBigEndian(H1, out, outOff); Pack.longToBigEndian(H2, out, outOff + 8); Pack.longToBigEndian(H3, out, outOff + 16); Pack.longToBigEndian(H4, out, outOff + 24); Pack.longToBigEndian(H5, out, outOff + 32); Pack.longToBigEndian(H6, out, outOff + 40); reset(); return DIGEST_LENGTH; } /** * reset the chaining variables */ public void reset() { super.reset(); /* SHA-384 initial hash value * The first 64 bits of the fractional parts of the square roots * of the 9th through 16th prime numbers */ H1 = 0xcbbb9d5dc1059ed8l; H2 = 0x629a292a367cd507l; H3 = 0x9159015a3070dd17l; H4 = 0x152fecd8f70e5939l; H5 = 0x67332667ffc00b31l; H6 = 0x8eb44a8768581511l; H7 = 0xdb0c2e0d64f98fa7l; H8 = 0x47b5481dbefa4fa4l; } public Memoable copy() { return new SHA384Digest(this); } public void reset(Memoable other) { SHA384Digest d = (SHA384Digest)other; super.copyIn(d); } } bouncycastle-1.49.orig/src/org/bouncycastle/crypto/digests/NonMemoableDigest.java0000644000175000017500000000247212143612325027667 0ustar ebourgebourgpackage org.bouncycastle.crypto.digests; import org.bouncycastle.crypto.ExtendedDigest; /** * Wrapper removes exposure to the Memoable interface on an ExtendedDigest implementation. */ public class NonMemoableDigest implements ExtendedDigest { private ExtendedDigest baseDigest; /** * Base constructor. * * @param baseDigest underlying digest to use. * @exception IllegalArgumentException if baseDigest is null */ public NonMemoableDigest( ExtendedDigest baseDigest) { if (baseDigest == null) { throw new IllegalArgumentException("baseDigest must not be null"); } this.baseDigest = baseDigest; } public String getAlgorithmName() { return baseDigest.getAlgorithmName(); } public int getDigestSize() { return baseDigest.getDigestSize(); } public void update(byte in) { baseDigest.update(in); } public void update(byte[] in, int inOff, int len) { baseDigest.update(in, inOff, len); } public int doFinal(byte[] out, int outOff) { return baseDigest.doFinal(out, outOff); } public void reset() { baseDigest.reset(); } public int getByteLength() { return baseDigest.getByteLength(); } } bouncycastle-1.49.orig/src/org/bouncycastle/crypto/digests/SHA3Digest.java0000644000175000017500000003542112102643107026166 0ustar ebourgebourgpackage org.bouncycastle.crypto.digests; import org.bouncycastle.crypto.ExtendedDigest; import org.bouncycastle.util.Arrays; /** * implementation of SHA-3 based on following KeccakNISTInterface.c from http://keccak.noekeon.org/ *

    * Following the naming conventions used in the C source code to enable easy review of the implementation. */ public class SHA3Digest implements ExtendedDigest { private static long[] KeccakRoundConstants = keccakInitializeRoundConstants(); private static int[] KeccakRhoOffsets = keccakInitializeRhoOffsets(); private static long[] keccakInitializeRoundConstants() { long[] keccakRoundConstants = new long[24]; byte[] LFSRstate = new byte[1]; LFSRstate[0] = 0x01; int i, j, bitPosition; for (i = 0; i < 24; i++) { keccakRoundConstants[i] = 0; for (j = 0; j < 7; j++) { bitPosition = (1 << j) - 1; if (LFSR86540(LFSRstate)) { keccakRoundConstants[i] ^= 1L << bitPosition; } } } return keccakRoundConstants; } private static boolean LFSR86540(byte[] LFSR) { boolean result = (((LFSR[0]) & 0x01) != 0); if (((LFSR[0]) & 0x80) != 0) { LFSR[0] = (byte)(((LFSR[0]) << 1) ^ 0x71); } else { LFSR[0] <<= 1; } return result; } private static int[] keccakInitializeRhoOffsets() { int[] keccakRhoOffsets = new int[25]; int x, y, t, newX, newY; keccakRhoOffsets[(((0) % 5) + 5 * ((0) % 5))] = 0; x = 1; y = 0; for (t = 0; t < 24; t++) { keccakRhoOffsets[(((x) % 5) + 5 * ((y) % 5))] = ((t + 1) * (t + 2) / 2) % 64; newX = (0 * x + 1 * y) % 5; newY = (2 * x + 3 * y) % 5; x = newX; y = newY; } return keccakRhoOffsets; } private byte[] state = new byte[(1600 / 8)]; private byte[] dataQueue = new byte[(1536 / 8)]; private int rate; private int bitsInQueue; private int fixedOutputLength; private boolean squeezing; private int bitsAvailableForSqueezing; private byte[] chunk; private byte[] oneByte; private void clearDataQueueSection(int off, int len) { for (int i = off; i != off + len; i++) { dataQueue[i] = 0; } } public SHA3Digest() { init(0); } public SHA3Digest(int bitLength) { init(bitLength); } public SHA3Digest(SHA3Digest source) { System.arraycopy(source.state, 0, this.state, 0, source.state.length); System.arraycopy(source.dataQueue, 0, this.dataQueue, 0, source.dataQueue.length); this.rate = source.rate; this.bitsInQueue = source.bitsInQueue; this.fixedOutputLength = source.fixedOutputLength; this.squeezing = source.squeezing; this.bitsAvailableForSqueezing = source.bitsAvailableForSqueezing; this.chunk = Arrays.clone(source.chunk); this.oneByte = Arrays.clone(source.oneByte); } public String getAlgorithmName() { return "SHA3-" + fixedOutputLength; } public int getDigestSize() { return fixedOutputLength / 8; } public void update(byte in) { oneByte[0] = in; doUpdate(oneByte, 0, 8L); } public void update(byte[] in, int inOff, int len) { doUpdate(in, inOff, len * 8L); } public int doFinal(byte[] out, int outOff) { squeeze(out, outOff, fixedOutputLength); reset(); return getDigestSize(); } public void reset() { init(fixedOutputLength); } /** * Return the size of block that the compression function is applied to in bytes. * * @return internal byte length of a block. */ public int getByteLength() { return rate / 8; } private void init(int bitLength) { switch (bitLength) { case 0: case 288: initSponge(1024, 576); break; case 224: initSponge(1152, 448); break; case 256: initSponge(1088, 512); break; case 384: initSponge(832, 768); break; case 512: initSponge(576, 1024); break; default: throw new IllegalArgumentException("bitLength must be one of 224, 256, 384, or 512."); } } private void doUpdate(byte[] data, int off, long databitlen) { if ((databitlen % 8) == 0) { absorb(data, off, databitlen); } else { absorb(data, off, databitlen - (databitlen % 8)); byte[] lastByte = new byte[1]; lastByte[0] = (byte)(data[off + (int)(databitlen / 8)] >> (8 - (databitlen % 8))); absorb(lastByte, off, databitlen % 8); } } private void initSponge(int rate, int capacity) { if (rate + capacity != 1600) { throw new IllegalStateException("rate + capacity != 1600"); } if ((rate <= 0) || (rate >= 1600) || ((rate % 64) != 0)) { throw new IllegalStateException("invalid rate value"); } this.rate = rate; // this is never read, need to check to see why we want to save it // this.capacity = capacity; this.fixedOutputLength = 0; Arrays.fill(this.state, (byte)0); Arrays.fill(this.dataQueue, (byte)0); this.bitsInQueue = 0; this.squeezing = false; this.bitsAvailableForSqueezing = 0; this.fixedOutputLength = capacity / 2; this.chunk = new byte[rate / 8]; this.oneByte = new byte[1]; } private void absorbQueue() { KeccakAbsorb(state, dataQueue, rate / 8); bitsInQueue = 0; } private void absorb(byte[] data, int off, long databitlen) { long i, j, wholeBlocks; if ((bitsInQueue % 8) != 0) { throw new IllegalStateException("attempt to absorb with odd length queue."); } if (squeezing) { throw new IllegalStateException("attempt to absorb while squeezing."); } i = 0; while (i < databitlen) { if ((bitsInQueue == 0) && (databitlen >= rate) && (i <= (databitlen - rate))) { wholeBlocks = (databitlen - i) / rate; for (j = 0; j < wholeBlocks; j++) { System.arraycopy(data, (int)(off + (i / 8) + (j * chunk.length)), chunk, 0, chunk.length); // displayIntermediateValues.displayBytes(1, "Block to be absorbed", curData, rate / 8); KeccakAbsorb(state, chunk, chunk.length); } i += wholeBlocks * rate; } else { int partialBlock = (int)(databitlen - i); if (partialBlock + bitsInQueue > rate) { partialBlock = rate - bitsInQueue; } int partialByte = partialBlock % 8; partialBlock -= partialByte; System.arraycopy(data, off + (int)(i / 8), dataQueue, bitsInQueue / 8, partialBlock / 8); bitsInQueue += partialBlock; i += partialBlock; if (bitsInQueue == rate) { absorbQueue(); } if (partialByte > 0) { int mask = (1 << partialByte) - 1; dataQueue[bitsInQueue / 8] = (byte)(data[off + ((int)(i / 8))] & mask); bitsInQueue += partialByte; i += partialByte; } } } } private void padAndSwitchToSqueezingPhase() { if (bitsInQueue + 1 == rate) { dataQueue[bitsInQueue / 8] |= 1 << (bitsInQueue % 8); absorbQueue(); clearDataQueueSection(0, rate / 8); } else { clearDataQueueSection((bitsInQueue + 7) / 8, rate / 8 - (bitsInQueue + 7) / 8); dataQueue[bitsInQueue / 8] |= 1 << (bitsInQueue % 8); } dataQueue[(rate - 1) / 8] |= 1 << ((rate - 1) % 8); absorbQueue(); // displayIntermediateValues.displayText(1, "--- Switching to squeezing phase ---"); if (rate == 1024) { KeccakExtract1024bits(state, dataQueue); bitsAvailableForSqueezing = 1024; } else { KeccakExtract(state, dataQueue, rate / 64); bitsAvailableForSqueezing = rate; } // displayIntermediateValues.displayBytes(1, "Block available for squeezing", dataQueue, bitsAvailableForSqueezing / 8); squeezing = true; } private void squeeze(byte[] output, int offset, long outputLength) { long i; int partialBlock; if (!squeezing) { padAndSwitchToSqueezingPhase(); } if ((outputLength % 8) != 0) { throw new IllegalStateException("outputLength not a multiple of 8"); } i = 0; while (i < outputLength) { if (bitsAvailableForSqueezing == 0) { keccakPermutation(state); if (rate == 1024) { KeccakExtract1024bits(state, dataQueue); bitsAvailableForSqueezing = 1024; } else { KeccakExtract(state, dataQueue, rate / 64); bitsAvailableForSqueezing = rate; } // displayIntermediateValues.displayBytes(1, "Block available for squeezing", dataQueue, bitsAvailableForSqueezing / 8); } partialBlock = bitsAvailableForSqueezing; if ((long)partialBlock > outputLength - i) { partialBlock = (int)(outputLength - i); } System.arraycopy(dataQueue, (rate - bitsAvailableForSqueezing) / 8, output, offset + (int)(i / 8), partialBlock / 8); bitsAvailableForSqueezing -= partialBlock; i += partialBlock; } } private void fromBytesToWords(long[] stateAsWords, byte[] state) { for (int i = 0; i < (1600 / 64); i++) { stateAsWords[i] = 0; int index = i * (64 / 8); for (int j = 0; j < (64 / 8); j++) { stateAsWords[i] |= ((long)state[index + j] & 0xff) << ((8 * j)); } } } private void fromWordsToBytes(byte[] state, long[] stateAsWords) { for (int i = 0; i < (1600 / 64); i++) { int index = i * (64 / 8); for (int j = 0; j < (64 / 8); j++) { state[index + j] = (byte)((stateAsWords[i] >>> ((8 * j))) & 0xFF); } } } private void keccakPermutation(byte[] state) { long[] longState = new long[state.length / 8]; fromBytesToWords(longState, state); // displayIntermediateValues.displayStateAsBytes(1, "Input of permutation", longState); keccakPermutationOnWords(longState); // displayIntermediateValues.displayStateAsBytes(1, "State after permutation", longState); fromWordsToBytes(state, longState); } private void keccakPermutationAfterXor(byte[] state, byte[] data, int dataLengthInBytes) { int i; for (i = 0; i < dataLengthInBytes; i++) { state[i] ^= data[i]; } keccakPermutation(state); } private void keccakPermutationOnWords(long[] state) { int i; // displayIntermediateValues.displayStateAs64bitWords(3, "Same, with lanes as 64-bit words", state); for (i = 0; i < 24; i++) { // displayIntermediateValues.displayRoundNumber(3, i); theta(state); // displayIntermediateValues.displayStateAs64bitWords(3, "After theta", state); rho(state); // displayIntermediateValues.displayStateAs64bitWords(3, "After rho", state); pi(state); // displayIntermediateValues.displayStateAs64bitWords(3, "After pi", state); chi(state); // displayIntermediateValues.displayStateAs64bitWords(3, "After chi", state); iota(state, i); // displayIntermediateValues.displayStateAs64bitWords(3, "After iota", state); } } long[] C = new long[5]; private void theta(long[] A) { for (int x = 0; x < 5; x++) { C[x] = 0; for (int y = 0; y < 5; y++) { C[x] ^= A[x + 5 * y]; } } for (int x = 0; x < 5; x++) { long dX = ((((C[(x + 1) % 5]) << 1) ^ ((C[(x + 1) % 5]) >>> (64 - 1)))) ^ C[(x + 4) % 5]; for (int y = 0; y < 5; y++) { A[x + 5 * y] ^= dX; } } } private void rho(long[] A) { for (int x = 0; x < 5; x++) { for (int y = 0; y < 5; y++) { int index = x + 5 * y; A[index] = ((KeccakRhoOffsets[index] != 0) ? (((A[index]) << KeccakRhoOffsets[index]) ^ ((A[index]) >>> (64 - KeccakRhoOffsets[index]))) : A[index]); } } } long[] tempA = new long[25]; private void pi(long[] A) { System.arraycopy(A, 0, tempA, 0, tempA.length); for (int x = 0; x < 5; x++) { for (int y = 0; y < 5; y++) { A[y + 5 * ((2 * x + 3 * y) % 5)] = tempA[x + 5 * y]; } } } long[] chiC = new long[5]; private void chi(long[] A) { for (int y = 0; y < 5; y++) { for (int x = 0; x < 5; x++) { chiC[x] = A[x + 5 * y] ^ ((~A[(((x + 1) % 5) + 5 * y)]) & A[(((x + 2) % 5) + 5 * y)]); } for (int x = 0; x < 5; x++) { A[x + 5 * y] = chiC[x]; } } } private void iota(long[] A, int indexRound) { A[(((0) % 5) + 5 * ((0) % 5))] ^= KeccakRoundConstants[indexRound]; } private void KeccakAbsorb(byte[] byteState, byte[] data, int dataInBytes) { keccakPermutationAfterXor(byteState, data, dataInBytes); } private void KeccakExtract1024bits(byte[] byteState, byte[] data) { System.arraycopy(byteState, 0, data, 0, 128); } private void KeccakExtract(byte[] byteState, byte[] data, int laneCount) { System.arraycopy(byteState, 0, data, 0, laneCount * 8); } } bouncycastle-1.49.orig/src/org/bouncycastle/crypto/digests/RIPEMD320Digest.java0000644000175000017500000004261312143607521026703 0ustar ebourgebourgpackage org.bouncycastle.crypto.digests; import org.bouncycastle.util.Memoable; /** * implementation of RIPEMD 320. *

    * Note: this implementation offers the same level of security * as RIPEMD 160. */ public class RIPEMD320Digest extends GeneralDigest { private static final int DIGEST_LENGTH = 40; private int H0, H1, H2, H3, H4, H5, H6, H7, H8, H9; // IV's private int[] X = new int[16]; private int xOff; /** * Standard constructor */ public RIPEMD320Digest() { reset(); } /** * Copy constructor. This will copy the state of the provided * message digest. */ public RIPEMD320Digest(RIPEMD320Digest t) { super(t); doCopy(t); } private void doCopy(RIPEMD320Digest t) { super.copyIn(t); H0 = t.H0; H1 = t.H1; H2 = t.H2; H3 = t.H3; H4 = t.H4; H5 = t.H5; H6 = t.H6; H7 = t.H7; H8 = t.H8; H9 = t.H9; System.arraycopy(t.X, 0, X, 0, t.X.length); xOff = t.xOff; } public String getAlgorithmName() { return "RIPEMD320"; } public int getDigestSize() { return DIGEST_LENGTH; } protected void processWord( byte[] in, int inOff) { X[xOff++] = (in[inOff] & 0xff) | ((in[inOff + 1] & 0xff) << 8) | ((in[inOff + 2] & 0xff) << 16) | ((in[inOff + 3] & 0xff) << 24); if (xOff == 16) { processBlock(); } } protected void processLength( long bitLength) { if (xOff > 14) { processBlock(); } X[14] = (int)(bitLength & 0xffffffff); X[15] = (int)(bitLength >>> 32); } private void unpackWord( int word, byte[] out, int outOff) { out[outOff] = (byte)word; out[outOff + 1] = (byte)(word >>> 8); out[outOff + 2] = (byte)(word >>> 16); out[outOff + 3] = (byte)(word >>> 24); } public int doFinal( byte[] out, int outOff) { finish(); unpackWord(H0, out, outOff); unpackWord(H1, out, outOff + 4); unpackWord(H2, out, outOff + 8); unpackWord(H3, out, outOff + 12); unpackWord(H4, out, outOff + 16); unpackWord(H5, out, outOff + 20); unpackWord(H6, out, outOff + 24); unpackWord(H7, out, outOff + 28); unpackWord(H8, out, outOff + 32); unpackWord(H9, out, outOff + 36); reset(); return DIGEST_LENGTH; } /** * reset the chaining variables to the IV values. */ public void reset() { super.reset(); H0 = 0x67452301; H1 = 0xefcdab89; H2 = 0x98badcfe; H3 = 0x10325476; H4 = 0xc3d2e1f0; H5 = 0x76543210; H6 = 0xFEDCBA98; H7 = 0x89ABCDEF; H8 = 0x01234567; H9 = 0x3C2D1E0F; xOff = 0; for (int i = 0; i != X.length; i++) { X[i] = 0; } } /* * rotate int x left n bits. */ private int RL( int x, int n) { return (x << n) | (x >>> (32 - n)); } /* * f1,f2,f3,f4,f5 are the basic RIPEMD160 functions. */ /* * rounds 0-15 */ private int f1( int x, int y, int z) { return x ^ y ^ z; } /* * rounds 16-31 */ private int f2( int x, int y, int z) { return (x & y) | (~x & z); } /* * rounds 32-47 */ private int f3( int x, int y, int z) { return (x | ~y) ^ z; } /* * rounds 48-63 */ private int f4( int x, int y, int z) { return (x & z) | (y & ~z); } /* * rounds 64-79 */ private int f5( int x, int y, int z) { return x ^ (y | ~z); } protected void processBlock() { int a, aa; int b, bb; int c, cc; int d, dd; int e, ee; int t; a = H0; b = H1; c = H2; d = H3; e = H4; aa = H5; bb = H6; cc = H7; dd = H8; ee = H9; // // Rounds 1 - 16 // // left a = RL(a + f1(b,c,d) + X[ 0], 11) + e; c = RL(c, 10); e = RL(e + f1(a,b,c) + X[ 1], 14) + d; b = RL(b, 10); d = RL(d + f1(e,a,b) + X[ 2], 15) + c; a = RL(a, 10); c = RL(c + f1(d,e,a) + X[ 3], 12) + b; e = RL(e, 10); b = RL(b + f1(c,d,e) + X[ 4], 5) + a; d = RL(d, 10); a = RL(a + f1(b,c,d) + X[ 5], 8) + e; c = RL(c, 10); e = RL(e + f1(a,b,c) + X[ 6], 7) + d; b = RL(b, 10); d = RL(d + f1(e,a,b) + X[ 7], 9) + c; a = RL(a, 10); c = RL(c + f1(d,e,a) + X[ 8], 11) + b; e = RL(e, 10); b = RL(b + f1(c,d,e) + X[ 9], 13) + a; d = RL(d, 10); a = RL(a + f1(b,c,d) + X[10], 14) + e; c = RL(c, 10); e = RL(e + f1(a,b,c) + X[11], 15) + d; b = RL(b, 10); d = RL(d + f1(e,a,b) + X[12], 6) + c; a = RL(a, 10); c = RL(c + f1(d,e,a) + X[13], 7) + b; e = RL(e, 10); b = RL(b + f1(c,d,e) + X[14], 9) + a; d = RL(d, 10); a = RL(a + f1(b,c,d) + X[15], 8) + e; c = RL(c, 10); // right aa = RL(aa + f5(bb,cc,dd) + X[ 5] + 0x50a28be6, 8) + ee; cc = RL(cc, 10); ee = RL(ee + f5(aa,bb,cc) + X[14] + 0x50a28be6, 9) + dd; bb = RL(bb, 10); dd = RL(dd + f5(ee,aa,bb) + X[ 7] + 0x50a28be6, 9) + cc; aa = RL(aa, 10); cc = RL(cc + f5(dd,ee,aa) + X[ 0] + 0x50a28be6, 11) + bb; ee = RL(ee, 10); bb = RL(bb + f5(cc,dd,ee) + X[ 9] + 0x50a28be6, 13) + aa; dd = RL(dd, 10); aa = RL(aa + f5(bb,cc,dd) + X[ 2] + 0x50a28be6, 15) + ee; cc = RL(cc, 10); ee = RL(ee + f5(aa,bb,cc) + X[11] + 0x50a28be6, 15) + dd; bb = RL(bb, 10); dd = RL(dd + f5(ee,aa,bb) + X[ 4] + 0x50a28be6, 5) + cc; aa = RL(aa, 10); cc = RL(cc + f5(dd,ee,aa) + X[13] + 0x50a28be6, 7) + bb; ee = RL(ee, 10); bb = RL(bb + f5(cc,dd,ee) + X[ 6] + 0x50a28be6, 7) + aa; dd = RL(dd, 10); aa = RL(aa + f5(bb,cc,dd) + X[15] + 0x50a28be6, 8) + ee; cc = RL(cc, 10); ee = RL(ee + f5(aa,bb,cc) + X[ 8] + 0x50a28be6, 11) + dd; bb = RL(bb, 10); dd = RL(dd + f5(ee,aa,bb) + X[ 1] + 0x50a28be6, 14) + cc; aa = RL(aa, 10); cc = RL(cc + f5(dd,ee,aa) + X[10] + 0x50a28be6, 14) + bb; ee = RL(ee, 10); bb = RL(bb + f5(cc,dd,ee) + X[ 3] + 0x50a28be6, 12) + aa; dd = RL(dd, 10); aa = RL(aa + f5(bb,cc,dd) + X[12] + 0x50a28be6, 6) + ee; cc = RL(cc, 10); t = a; a = aa; aa = t; // // Rounds 16-31 // // left e = RL(e + f2(a,b,c) + X[ 7] + 0x5a827999, 7) + d; b = RL(b, 10); d = RL(d + f2(e,a,b) + X[ 4] + 0x5a827999, 6) + c; a = RL(a, 10); c = RL(c + f2(d,e,a) + X[13] + 0x5a827999, 8) + b; e = RL(e, 10); b = RL(b + f2(c,d,e) + X[ 1] + 0x5a827999, 13) + a; d = RL(d, 10); a = RL(a + f2(b,c,d) + X[10] + 0x5a827999, 11) + e; c = RL(c, 10); e = RL(e + f2(a,b,c) + X[ 6] + 0x5a827999, 9) + d; b = RL(b, 10); d = RL(d + f2(e,a,b) + X[15] + 0x5a827999, 7) + c; a = RL(a, 10); c = RL(c + f2(d,e,a) + X[ 3] + 0x5a827999, 15) + b; e = RL(e, 10); b = RL(b + f2(c,d,e) + X[12] + 0x5a827999, 7) + a; d = RL(d, 10); a = RL(a + f2(b,c,d) + X[ 0] + 0x5a827999, 12) + e; c = RL(c, 10); e = RL(e + f2(a,b,c) + X[ 9] + 0x5a827999, 15) + d; b = RL(b, 10); d = RL(d + f2(e,a,b) + X[ 5] + 0x5a827999, 9) + c; a = RL(a, 10); c = RL(c + f2(d,e,a) + X[ 2] + 0x5a827999, 11) + b; e = RL(e, 10); b = RL(b + f2(c,d,e) + X[14] + 0x5a827999, 7) + a; d = RL(d, 10); a = RL(a + f2(b,c,d) + X[11] + 0x5a827999, 13) + e; c = RL(c, 10); e = RL(e + f2(a,b,c) + X[ 8] + 0x5a827999, 12) + d; b = RL(b, 10); // right ee = RL(ee + f4(aa,bb,cc) + X[ 6] + 0x5c4dd124, 9) + dd; bb = RL(bb, 10); dd = RL(dd + f4(ee,aa,bb) + X[11] + 0x5c4dd124, 13) + cc; aa = RL(aa, 10); cc = RL(cc + f4(dd,ee,aa) + X[ 3] + 0x5c4dd124, 15) + bb; ee = RL(ee, 10); bb = RL(bb + f4(cc,dd,ee) + X[ 7] + 0x5c4dd124, 7) + aa; dd = RL(dd, 10); aa = RL(aa + f4(bb,cc,dd) + X[ 0] + 0x5c4dd124, 12) + ee; cc = RL(cc, 10); ee = RL(ee + f4(aa,bb,cc) + X[13] + 0x5c4dd124, 8) + dd; bb = RL(bb, 10); dd = RL(dd + f4(ee,aa,bb) + X[ 5] + 0x5c4dd124, 9) + cc; aa = RL(aa, 10); cc = RL(cc + f4(dd,ee,aa) + X[10] + 0x5c4dd124, 11) + bb; ee = RL(ee, 10); bb = RL(bb + f4(cc,dd,ee) + X[14] + 0x5c4dd124, 7) + aa; dd = RL(dd, 10); aa = RL(aa + f4(bb,cc,dd) + X[15] + 0x5c4dd124, 7) + ee; cc = RL(cc, 10); ee = RL(ee + f4(aa,bb,cc) + X[ 8] + 0x5c4dd124, 12) + dd; bb = RL(bb, 10); dd = RL(dd + f4(ee,aa,bb) + X[12] + 0x5c4dd124, 7) + cc; aa = RL(aa, 10); cc = RL(cc + f4(dd,ee,aa) + X[ 4] + 0x5c4dd124, 6) + bb; ee = RL(ee, 10); bb = RL(bb + f4(cc,dd,ee) + X[ 9] + 0x5c4dd124, 15) + aa; dd = RL(dd, 10); aa = RL(aa + f4(bb,cc,dd) + X[ 1] + 0x5c4dd124, 13) + ee; cc = RL(cc, 10); ee = RL(ee + f4(aa,bb,cc) + X[ 2] + 0x5c4dd124, 11) + dd; bb = RL(bb, 10); t = b; b = bb; bb = t; // // Rounds 32-47 // // left d = RL(d + f3(e,a,b) + X[ 3] + 0x6ed9eba1, 11) + c; a = RL(a, 10); c = RL(c + f3(d,e,a) + X[10] + 0x6ed9eba1, 13) + b; e = RL(e, 10); b = RL(b + f3(c,d,e) + X[14] + 0x6ed9eba1, 6) + a; d = RL(d, 10); a = RL(a + f3(b,c,d) + X[ 4] + 0x6ed9eba1, 7) + e; c = RL(c, 10); e = RL(e + f3(a,b,c) + X[ 9] + 0x6ed9eba1, 14) + d; b = RL(b, 10); d = RL(d + f3(e,a,b) + X[15] + 0x6ed9eba1, 9) + c; a = RL(a, 10); c = RL(c + f3(d,e,a) + X[ 8] + 0x6ed9eba1, 13) + b; e = RL(e, 10); b = RL(b + f3(c,d,e) + X[ 1] + 0x6ed9eba1, 15) + a; d = RL(d, 10); a = RL(a + f3(b,c,d) + X[ 2] + 0x6ed9eba1, 14) + e; c = RL(c, 10); e = RL(e + f3(a,b,c) + X[ 7] + 0x6ed9eba1, 8) + d; b = RL(b, 10); d = RL(d + f3(e,a,b) + X[ 0] + 0x6ed9eba1, 13) + c; a = RL(a, 10); c = RL(c + f3(d,e,a) + X[ 6] + 0x6ed9eba1, 6) + b; e = RL(e, 10); b = RL(b + f3(c,d,e) + X[13] + 0x6ed9eba1, 5) + a; d = RL(d, 10); a = RL(a + f3(b,c,d) + X[11] + 0x6ed9eba1, 12) + e; c = RL(c, 10); e = RL(e + f3(a,b,c) + X[ 5] + 0x6ed9eba1, 7) + d; b = RL(b, 10); d = RL(d + f3(e,a,b) + X[12] + 0x6ed9eba1, 5) + c; a = RL(a, 10); // right dd = RL(dd + f3(ee,aa,bb) + X[15] + 0x6d703ef3, 9) + cc; aa = RL(aa, 10); cc = RL(cc + f3(dd,ee,aa) + X[ 5] + 0x6d703ef3, 7) + bb; ee = RL(ee, 10); bb = RL(bb + f3(cc,dd,ee) + X[ 1] + 0x6d703ef3, 15) + aa; dd = RL(dd, 10); aa = RL(aa + f3(bb,cc,dd) + X[ 3] + 0x6d703ef3, 11) + ee; cc = RL(cc, 10); ee = RL(ee + f3(aa,bb,cc) + X[ 7] + 0x6d703ef3, 8) + dd; bb = RL(bb, 10); dd = RL(dd + f3(ee,aa,bb) + X[14] + 0x6d703ef3, 6) + cc; aa = RL(aa, 10); cc = RL(cc + f3(dd,ee,aa) + X[ 6] + 0x6d703ef3, 6) + bb; ee = RL(ee, 10); bb = RL(bb + f3(cc,dd,ee) + X[ 9] + 0x6d703ef3, 14) + aa; dd = RL(dd, 10); aa = RL(aa + f3(bb,cc,dd) + X[11] + 0x6d703ef3, 12) + ee; cc = RL(cc, 10); ee = RL(ee + f3(aa,bb,cc) + X[ 8] + 0x6d703ef3, 13) + dd; bb = RL(bb, 10); dd = RL(dd + f3(ee,aa,bb) + X[12] + 0x6d703ef3, 5) + cc; aa = RL(aa, 10); cc = RL(cc + f3(dd,ee,aa) + X[ 2] + 0x6d703ef3, 14) + bb; ee = RL(ee, 10); bb = RL(bb + f3(cc,dd,ee) + X[10] + 0x6d703ef3, 13) + aa; dd = RL(dd, 10); aa = RL(aa + f3(bb,cc,dd) + X[ 0] + 0x6d703ef3, 13) + ee; cc = RL(cc, 10); ee = RL(ee + f3(aa,bb,cc) + X[ 4] + 0x6d703ef3, 7) + dd; bb = RL(bb, 10); dd = RL(dd + f3(ee,aa,bb) + X[13] + 0x6d703ef3, 5) + cc; aa = RL(aa, 10); t = c; c = cc; cc = t; // // Rounds 48-63 // // left c = RL(c + f4(d,e,a) + X[ 1] + 0x8f1bbcdc, 11) + b; e = RL(e, 10); b = RL(b + f4(c,d,e) + X[ 9] + 0x8f1bbcdc, 12) + a; d = RL(d, 10); a = RL(a + f4(b,c,d) + X[11] + 0x8f1bbcdc, 14) + e; c = RL(c, 10); e = RL(e + f4(a,b,c) + X[10] + 0x8f1bbcdc, 15) + d; b = RL(b, 10); d = RL(d + f4(e,a,b) + X[ 0] + 0x8f1bbcdc, 14) + c; a = RL(a, 10); c = RL(c + f4(d,e,a) + X[ 8] + 0x8f1bbcdc, 15) + b; e = RL(e, 10); b = RL(b + f4(c,d,e) + X[12] + 0x8f1bbcdc, 9) + a; d = RL(d, 10); a = RL(a + f4(b,c,d) + X[ 4] + 0x8f1bbcdc, 8) + e; c = RL(c, 10); e = RL(e + f4(a,b,c) + X[13] + 0x8f1bbcdc, 9) + d; b = RL(b, 10); d = RL(d + f4(e,a,b) + X[ 3] + 0x8f1bbcdc, 14) + c; a = RL(a, 10); c = RL(c + f4(d,e,a) + X[ 7] + 0x8f1bbcdc, 5) + b; e = RL(e, 10); b = RL(b + f4(c,d,e) + X[15] + 0x8f1bbcdc, 6) + a; d = RL(d, 10); a = RL(a + f4(b,c,d) + X[14] + 0x8f1bbcdc, 8) + e; c = RL(c, 10); e = RL(e + f4(a,b,c) + X[ 5] + 0x8f1bbcdc, 6) + d; b = RL(b, 10); d = RL(d + f4(e,a,b) + X[ 6] + 0x8f1bbcdc, 5) + c; a = RL(a, 10); c = RL(c + f4(d,e,a) + X[ 2] + 0x8f1bbcdc, 12) + b; e = RL(e, 10); // right cc = RL(cc + f2(dd,ee,aa) + X[ 8] + 0x7a6d76e9, 15) + bb; ee = RL(ee, 10); bb = RL(bb + f2(cc,dd,ee) + X[ 6] + 0x7a6d76e9, 5) + aa; dd = RL(dd, 10); aa = RL(aa + f2(bb,cc,dd) + X[ 4] + 0x7a6d76e9, 8) + ee; cc = RL(cc, 10); ee = RL(ee + f2(aa,bb,cc) + X[ 1] + 0x7a6d76e9, 11) + dd; bb = RL(bb, 10); dd = RL(dd + f2(ee,aa,bb) + X[ 3] + 0x7a6d76e9, 14) + cc; aa = RL(aa, 10); cc = RL(cc + f2(dd,ee,aa) + X[11] + 0x7a6d76e9, 14) + bb; ee = RL(ee, 10); bb = RL(bb + f2(cc,dd,ee) + X[15] + 0x7a6d76e9, 6) + aa; dd = RL(dd, 10); aa = RL(aa + f2(bb,cc,dd) + X[ 0] + 0x7a6d76e9, 14) + ee; cc = RL(cc, 10); ee = RL(ee + f2(aa,bb,cc) + X[ 5] + 0x7a6d76e9, 6) + dd; bb = RL(bb, 10); dd = RL(dd + f2(ee,aa,bb) + X[12] + 0x7a6d76e9, 9) + cc; aa = RL(aa, 10); cc = RL(cc + f2(dd,ee,aa) + X[ 2] + 0x7a6d76e9, 12) + bb; ee = RL(ee, 10); bb = RL(bb + f2(cc,dd,ee) + X[13] + 0x7a6d76e9, 9) + aa; dd = RL(dd, 10); aa = RL(aa + f2(bb,cc,dd) + X[ 9] + 0x7a6d76e9, 12) + ee; cc = RL(cc, 10); ee = RL(ee + f2(aa,bb,cc) + X[ 7] + 0x7a6d76e9, 5) + dd; bb = RL(bb, 10); dd = RL(dd + f2(ee,aa,bb) + X[10] + 0x7a6d76e9, 15) + cc; aa = RL(aa, 10); cc = RL(cc + f2(dd,ee,aa) + X[14] + 0x7a6d76e9, 8) + bb; ee = RL(ee, 10); t = d; d = dd; dd = t; // // Rounds 64-79 // // left b = RL(b + f5(c,d,e) + X[ 4] + 0xa953fd4e, 9) + a; d = RL(d, 10); a = RL(a + f5(b,c,d) + X[ 0] + 0xa953fd4e, 15) + e; c = RL(c, 10); e = RL(e + f5(a,b,c) + X[ 5] + 0xa953fd4e, 5) + d; b = RL(b, 10); d = RL(d + f5(e,a,b) + X[ 9] + 0xa953fd4e, 11) + c; a = RL(a, 10); c = RL(c + f5(d,e,a) + X[ 7] + 0xa953fd4e, 6) + b; e = RL(e, 10); b = RL(b + f5(c,d,e) + X[12] + 0xa953fd4e, 8) + a; d = RL(d, 10); a = RL(a + f5(b,c,d) + X[ 2] + 0xa953fd4e, 13) + e; c = RL(c, 10); e = RL(e + f5(a,b,c) + X[10] + 0xa953fd4e, 12) + d; b = RL(b, 10); d = RL(d + f5(e,a,b) + X[14] + 0xa953fd4e, 5) + c; a = RL(a, 10); c = RL(c + f5(d,e,a) + X[ 1] + 0xa953fd4e, 12) + b; e = RL(e, 10); b = RL(b + f5(c,d,e) + X[ 3] + 0xa953fd4e, 13) + a; d = RL(d, 10); a = RL(a + f5(b,c,d) + X[ 8] + 0xa953fd4e, 14) + e; c = RL(c, 10); e = RL(e + f5(a,b,c) + X[11] + 0xa953fd4e, 11) + d; b = RL(b, 10); d = RL(d + f5(e,a,b) + X[ 6] + 0xa953fd4e, 8) + c; a = RL(a, 10); c = RL(c + f5(d,e,a) + X[15] + 0xa953fd4e, 5) + b; e = RL(e, 10); b = RL(b + f5(c,d,e) + X[13] + 0xa953fd4e, 6) + a; d = RL(d, 10); // right bb = RL(bb + f1(cc,dd,ee) + X[12], 8) + aa; dd = RL(dd, 10); aa = RL(aa + f1(bb,cc,dd) + X[15], 5) + ee; cc = RL(cc, 10); ee = RL(ee + f1(aa,bb,cc) + X[10], 12) + dd; bb = RL(bb, 10); dd = RL(dd + f1(ee,aa,bb) + X[ 4], 9) + cc; aa = RL(aa, 10); cc = RL(cc + f1(dd,ee,aa) + X[ 1], 12) + bb; ee = RL(ee, 10); bb = RL(bb + f1(cc,dd,ee) + X[ 5], 5) + aa; dd = RL(dd, 10); aa = RL(aa + f1(bb,cc,dd) + X[ 8], 14) + ee; cc = RL(cc, 10); ee = RL(ee + f1(aa,bb,cc) + X[ 7], 6) + dd; bb = RL(bb, 10); dd = RL(dd + f1(ee,aa,bb) + X[ 6], 8) + cc; aa = RL(aa, 10); cc = RL(cc + f1(dd,ee,aa) + X[ 2], 13) + bb; ee = RL(ee, 10); bb = RL(bb + f1(cc,dd,ee) + X[13], 6) + aa; dd = RL(dd, 10); aa = RL(aa + f1(bb,cc,dd) + X[14], 5) + ee; cc = RL(cc, 10); ee = RL(ee + f1(aa,bb,cc) + X[ 0], 15) + dd; bb = RL(bb, 10); dd = RL(dd + f1(ee,aa,bb) + X[ 3], 13) + cc; aa = RL(aa, 10); cc = RL(cc + f1(dd,ee,aa) + X[ 9], 11) + bb; ee = RL(ee, 10); bb = RL(bb + f1(cc,dd,ee) + X[11], 11) + aa; dd = RL(dd, 10); // // do (e, ee) swap as part of assignment. // H0 += a; H1 += b; H2 += c; H3 += d; H4 += ee; H5 += aa; H6 += bb; H7 += cc; H8 += dd; H9 += e; // // reset the offset and clean out the word buffer. // xOff = 0; for (int i = 0; i != X.length; i++) { X[i] = 0; } } public Memoable copy() { return new RIPEMD320Digest(this); } public void reset(Memoable other) { RIPEMD320Digest d = (RIPEMD320Digest)other; doCopy(d); } } bouncycastle-1.49.orig/src/org/bouncycastle/crypto/digests/RIPEMD128Digest.java0000644000175000017500000002567012143607521026715 0ustar ebourgebourgpackage org.bouncycastle.crypto.digests; import org.bouncycastle.util.Memoable; /** * implementation of RIPEMD128 */ public class RIPEMD128Digest extends GeneralDigest { private static final int DIGEST_LENGTH = 16; private int H0, H1, H2, H3; // IV's private int[] X = new int[16]; private int xOff; /** * Standard constructor */ public RIPEMD128Digest() { reset(); } /** * Copy constructor. This will copy the state of the provided * message digest. */ public RIPEMD128Digest(RIPEMD128Digest t) { super(t); copyIn(t); } private void copyIn(RIPEMD128Digest t) { super.copyIn(t); H0 = t.H0; H1 = t.H1; H2 = t.H2; H3 = t.H3; System.arraycopy(t.X, 0, X, 0, t.X.length); xOff = t.xOff; } public String getAlgorithmName() { return "RIPEMD128"; } public int getDigestSize() { return DIGEST_LENGTH; } protected void processWord( byte[] in, int inOff) { X[xOff++] = (in[inOff] & 0xff) | ((in[inOff + 1] & 0xff) << 8) | ((in[inOff + 2] & 0xff) << 16) | ((in[inOff + 3] & 0xff) << 24); if (xOff == 16) { processBlock(); } } protected void processLength( long bitLength) { if (xOff > 14) { processBlock(); } X[14] = (int)(bitLength & 0xffffffff); X[15] = (int)(bitLength >>> 32); } private void unpackWord( int word, byte[] out, int outOff) { out[outOff] = (byte)word; out[outOff + 1] = (byte)(word >>> 8); out[outOff + 2] = (byte)(word >>> 16); out[outOff + 3] = (byte)(word >>> 24); } public int doFinal( byte[] out, int outOff) { finish(); unpackWord(H0, out, outOff); unpackWord(H1, out, outOff + 4); unpackWord(H2, out, outOff + 8); unpackWord(H3, out, outOff + 12); reset(); return DIGEST_LENGTH; } /** * reset the chaining variables to the IV values. */ public void reset() { super.reset(); H0 = 0x67452301; H1 = 0xefcdab89; H2 = 0x98badcfe; H3 = 0x10325476; xOff = 0; for (int i = 0; i != X.length; i++) { X[i] = 0; } } /* * rotate int x left n bits. */ private int RL( int x, int n) { return (x << n) | (x >>> (32 - n)); } /* * f1,f2,f3,f4 are the basic RIPEMD128 functions. */ /* * F */ private int f1( int x, int y, int z) { return x ^ y ^ z; } /* * G */ private int f2( int x, int y, int z) { return (x & y) | (~x & z); } /* * H */ private int f3( int x, int y, int z) { return (x | ~y) ^ z; } /* * I */ private int f4( int x, int y, int z) { return (x & z) | (y & ~z); } private int F1( int a, int b, int c, int d, int x, int s) { return RL(a + f1(b, c, d) + x, s); } private int F2( int a, int b, int c, int d, int x, int s) { return RL(a + f2(b, c, d) + x + 0x5a827999, s); } private int F3( int a, int b, int c, int d, int x, int s) { return RL(a + f3(b, c, d) + x + 0x6ed9eba1, s); } private int F4( int a, int b, int c, int d, int x, int s) { return RL(a + f4(b, c, d) + x + 0x8f1bbcdc, s); } private int FF1( int a, int b, int c, int d, int x, int s) { return RL(a + f1(b, c, d) + x, s); } private int FF2( int a, int b, int c, int d, int x, int s) { return RL(a + f2(b, c, d) + x + 0x6d703ef3, s); } private int FF3( int a, int b, int c, int d, int x, int s) { return RL(a + f3(b, c, d) + x + 0x5c4dd124, s); } private int FF4( int a, int b, int c, int d, int x, int s) { return RL(a + f4(b, c, d) + x + 0x50a28be6, s); } protected void processBlock() { int a, aa; int b, bb; int c, cc; int d, dd; a = aa = H0; b = bb = H1; c = cc = H2; d = dd = H3; // // Round 1 // a = F1(a, b, c, d, X[ 0], 11); d = F1(d, a, b, c, X[ 1], 14); c = F1(c, d, a, b, X[ 2], 15); b = F1(b, c, d, a, X[ 3], 12); a = F1(a, b, c, d, X[ 4], 5); d = F1(d, a, b, c, X[ 5], 8); c = F1(c, d, a, b, X[ 6], 7); b = F1(b, c, d, a, X[ 7], 9); a = F1(a, b, c, d, X[ 8], 11); d = F1(d, a, b, c, X[ 9], 13); c = F1(c, d, a, b, X[10], 14); b = F1(b, c, d, a, X[11], 15); a = F1(a, b, c, d, X[12], 6); d = F1(d, a, b, c, X[13], 7); c = F1(c, d, a, b, X[14], 9); b = F1(b, c, d, a, X[15], 8); // // Round 2 // a = F2(a, b, c, d, X[ 7], 7); d = F2(d, a, b, c, X[ 4], 6); c = F2(c, d, a, b, X[13], 8); b = F2(b, c, d, a, X[ 1], 13); a = F2(a, b, c, d, X[10], 11); d = F2(d, a, b, c, X[ 6], 9); c = F2(c, d, a, b, X[15], 7); b = F2(b, c, d, a, X[ 3], 15); a = F2(a, b, c, d, X[12], 7); d = F2(d, a, b, c, X[ 0], 12); c = F2(c, d, a, b, X[ 9], 15); b = F2(b, c, d, a, X[ 5], 9); a = F2(a, b, c, d, X[ 2], 11); d = F2(d, a, b, c, X[14], 7); c = F2(c, d, a, b, X[11], 13); b = F2(b, c, d, a, X[ 8], 12); // // Round 3 // a = F3(a, b, c, d, X[ 3], 11); d = F3(d, a, b, c, X[10], 13); c = F3(c, d, a, b, X[14], 6); b = F3(b, c, d, a, X[ 4], 7); a = F3(a, b, c, d, X[ 9], 14); d = F3(d, a, b, c, X[15], 9); c = F3(c, d, a, b, X[ 8], 13); b = F3(b, c, d, a, X[ 1], 15); a = F3(a, b, c, d, X[ 2], 14); d = F3(d, a, b, c, X[ 7], 8); c = F3(c, d, a, b, X[ 0], 13); b = F3(b, c, d, a, X[ 6], 6); a = F3(a, b, c, d, X[13], 5); d = F3(d, a, b, c, X[11], 12); c = F3(c, d, a, b, X[ 5], 7); b = F3(b, c, d, a, X[12], 5); // // Round 4 // a = F4(a, b, c, d, X[ 1], 11); d = F4(d, a, b, c, X[ 9], 12); c = F4(c, d, a, b, X[11], 14); b = F4(b, c, d, a, X[10], 15); a = F4(a, b, c, d, X[ 0], 14); d = F4(d, a, b, c, X[ 8], 15); c = F4(c, d, a, b, X[12], 9); b = F4(b, c, d, a, X[ 4], 8); a = F4(a, b, c, d, X[13], 9); d = F4(d, a, b, c, X[ 3], 14); c = F4(c, d, a, b, X[ 7], 5); b = F4(b, c, d, a, X[15], 6); a = F4(a, b, c, d, X[14], 8); d = F4(d, a, b, c, X[ 5], 6); c = F4(c, d, a, b, X[ 6], 5); b = F4(b, c, d, a, X[ 2], 12); // // Parallel round 1 // aa = FF4(aa, bb, cc, dd, X[ 5], 8); dd = FF4(dd, aa, bb, cc, X[14], 9); cc = FF4(cc, dd, aa, bb, X[ 7], 9); bb = FF4(bb, cc, dd, aa, X[ 0], 11); aa = FF4(aa, bb, cc, dd, X[ 9], 13); dd = FF4(dd, aa, bb, cc, X[ 2], 15); cc = FF4(cc, dd, aa, bb, X[11], 15); bb = FF4(bb, cc, dd, aa, X[ 4], 5); aa = FF4(aa, bb, cc, dd, X[13], 7); dd = FF4(dd, aa, bb, cc, X[ 6], 7); cc = FF4(cc, dd, aa, bb, X[15], 8); bb = FF4(bb, cc, dd, aa, X[ 8], 11); aa = FF4(aa, bb, cc, dd, X[ 1], 14); dd = FF4(dd, aa, bb, cc, X[10], 14); cc = FF4(cc, dd, aa, bb, X[ 3], 12); bb = FF4(bb, cc, dd, aa, X[12], 6); // // Parallel round 2 // aa = FF3(aa, bb, cc, dd, X[ 6], 9); dd = FF3(dd, aa, bb, cc, X[11], 13); cc = FF3(cc, dd, aa, bb, X[ 3], 15); bb = FF3(bb, cc, dd, aa, X[ 7], 7); aa = FF3(aa, bb, cc, dd, X[ 0], 12); dd = FF3(dd, aa, bb, cc, X[13], 8); cc = FF3(cc, dd, aa, bb, X[ 5], 9); bb = FF3(bb, cc, dd, aa, X[10], 11); aa = FF3(aa, bb, cc, dd, X[14], 7); dd = FF3(dd, aa, bb, cc, X[15], 7); cc = FF3(cc, dd, aa, bb, X[ 8], 12); bb = FF3(bb, cc, dd, aa, X[12], 7); aa = FF3(aa, bb, cc, dd, X[ 4], 6); dd = FF3(dd, aa, bb, cc, X[ 9], 15); cc = FF3(cc, dd, aa, bb, X[ 1], 13); bb = FF3(bb, cc, dd, aa, X[ 2], 11); // // Parallel round 3 // aa = FF2(aa, bb, cc, dd, X[15], 9); dd = FF2(dd, aa, bb, cc, X[ 5], 7); cc = FF2(cc, dd, aa, bb, X[ 1], 15); bb = FF2(bb, cc, dd, aa, X[ 3], 11); aa = FF2(aa, bb, cc, dd, X[ 7], 8); dd = FF2(dd, aa, bb, cc, X[14], 6); cc = FF2(cc, dd, aa, bb, X[ 6], 6); bb = FF2(bb, cc, dd, aa, X[ 9], 14); aa = FF2(aa, bb, cc, dd, X[11], 12); dd = FF2(dd, aa, bb, cc, X[ 8], 13); cc = FF2(cc, dd, aa, bb, X[12], 5); bb = FF2(bb, cc, dd, aa, X[ 2], 14); aa = FF2(aa, bb, cc, dd, X[10], 13); dd = FF2(dd, aa, bb, cc, X[ 0], 13); cc = FF2(cc, dd, aa, bb, X[ 4], 7); bb = FF2(bb, cc, dd, aa, X[13], 5); // // Parallel round 4 // aa = FF1(aa, bb, cc, dd, X[ 8], 15); dd = FF1(dd, aa, bb, cc, X[ 6], 5); cc = FF1(cc, dd, aa, bb, X[ 4], 8); bb = FF1(bb, cc, dd, aa, X[ 1], 11); aa = FF1(aa, bb, cc, dd, X[ 3], 14); dd = FF1(dd, aa, bb, cc, X[11], 14); cc = FF1(cc, dd, aa, bb, X[15], 6); bb = FF1(bb, cc, dd, aa, X[ 0], 14); aa = FF1(aa, bb, cc, dd, X[ 5], 6); dd = FF1(dd, aa, bb, cc, X[12], 9); cc = FF1(cc, dd, aa, bb, X[ 2], 12); bb = FF1(bb, cc, dd, aa, X[13], 9); aa = FF1(aa, bb, cc, dd, X[ 9], 12); dd = FF1(dd, aa, bb, cc, X[ 7], 5); cc = FF1(cc, dd, aa, bb, X[10], 15); bb = FF1(bb, cc, dd, aa, X[14], 8); dd += c + H1; // final result for H0 // // combine the results // H1 = H2 + d + aa; H2 = H3 + a + bb; H3 = H0 + b + cc; H0 = dd; // // reset the offset and clean out the word buffer. // xOff = 0; for (int i = 0; i != X.length; i++) { X[i] = 0; } } public Memoable copy() { return new RIPEMD128Digest(this); } public void reset(Memoable other) { RIPEMD128Digest d = (RIPEMD128Digest)other; copyIn(d); } } bouncycastle-1.49.orig/src/org/bouncycastle/crypto/digests/SHA224Digest.java0000644000175000017500000001610512143607521026336 0ustar ebourgebourgpackage org.bouncycastle.crypto.digests; import org.bouncycastle.crypto.util.Pack; import org.bouncycastle.util.Memoable; /** * SHA-224 as described in RFC 3874 *

     *         block  word  digest
     * SHA-1   512    32    160
     * SHA-224 512    32    224
     * SHA-256 512    32    256
     * SHA-384 1024   64    384
     * SHA-512 1024   64    512
     * 
    */ public class SHA224Digest extends GeneralDigest { private static final int DIGEST_LENGTH = 28; private int H1, H2, H3, H4, H5, H6, H7, H8; private int[] X = new int[64]; private int xOff; /** * Standard constructor */ public SHA224Digest() { reset(); } /** * Copy constructor. This will copy the state of the provided * message digest. */ public SHA224Digest(SHA224Digest t) { super(t); doCopy(t); } private void doCopy(SHA224Digest t) { super.copyIn(t); H1 = t.H1; H2 = t.H2; H3 = t.H3; H4 = t.H4; H5 = t.H5; H6 = t.H6; H7 = t.H7; H8 = t.H8; System.arraycopy(t.X, 0, X, 0, t.X.length); xOff = t.xOff; } public String getAlgorithmName() { return "SHA-224"; } public int getDigestSize() { return DIGEST_LENGTH; } protected void processWord( byte[] in, int inOff) { // Note: Inlined for performance // X[xOff] = Pack.bigEndianToInt(in, inOff); int n = in[ inOff] << 24; n |= (in[++inOff] & 0xff) << 16; n |= (in[++inOff] & 0xff) << 8; n |= (in[++inOff] & 0xff); X[xOff] = n; if (++xOff == 16) { processBlock(); } } protected void processLength( long bitLength) { if (xOff > 14) { processBlock(); } X[14] = (int)(bitLength >>> 32); X[15] = (int)(bitLength & 0xffffffff); } public int doFinal( byte[] out, int outOff) { finish(); Pack.intToBigEndian(H1, out, outOff); Pack.intToBigEndian(H2, out, outOff + 4); Pack.intToBigEndian(H3, out, outOff + 8); Pack.intToBigEndian(H4, out, outOff + 12); Pack.intToBigEndian(H5, out, outOff + 16); Pack.intToBigEndian(H6, out, outOff + 20); Pack.intToBigEndian(H7, out, outOff + 24); reset(); return DIGEST_LENGTH; } /** * reset the chaining variables */ public void reset() { super.reset(); /* SHA-224 initial hash value */ H1 = 0xc1059ed8; H2 = 0x367cd507; H3 = 0x3070dd17; H4 = 0xf70e5939; H5 = 0xffc00b31; H6 = 0x68581511; H7 = 0x64f98fa7; H8 = 0xbefa4fa4; xOff = 0; for (int i = 0; i != X.length; i++) { X[i] = 0; } } protected void processBlock() { // // expand 16 word block into 64 word blocks. // for (int t = 16; t <= 63; t++) { X[t] = Theta1(X[t - 2]) + X[t - 7] + Theta0(X[t - 15]) + X[t - 16]; } // // set up working variables. // int a = H1; int b = H2; int c = H3; int d = H4; int e = H5; int f = H6; int g = H7; int h = H8; int t = 0; for(int i = 0; i < 8; i ++) { // t = 8 * i h += Sum1(e) + Ch(e, f, g) + K[t] + X[t]; d += h; h += Sum0(a) + Maj(a, b, c); ++t; // t = 8 * i + 1 g += Sum1(d) + Ch(d, e, f) + K[t] + X[t]; c += g; g += Sum0(h) + Maj(h, a, b); ++t; // t = 8 * i + 2 f += Sum1(c) + Ch(c, d, e) + K[t] + X[t]; b += f; f += Sum0(g) + Maj(g, h, a); ++t; // t = 8 * i + 3 e += Sum1(b) + Ch(b, c, d) + K[t] + X[t]; a += e; e += Sum0(f) + Maj(f, g, h); ++t; // t = 8 * i + 4 d += Sum1(a) + Ch(a, b, c) + K[t] + X[t]; h += d; d += Sum0(e) + Maj(e, f, g); ++t; // t = 8 * i + 5 c += Sum1(h) + Ch(h, a, b) + K[t] + X[t]; g += c; c += Sum0(d) + Maj(d, e, f); ++t; // t = 8 * i + 6 b += Sum1(g) + Ch(g, h, a) + K[t] + X[t]; f += b; b += Sum0(c) + Maj(c, d, e); ++t; // t = 8 * i + 7 a += Sum1(f) + Ch(f, g, h) + K[t] + X[t]; e += a; a += Sum0(b) + Maj(b, c, d); ++t; } H1 += a; H2 += b; H3 += c; H4 += d; H5 += e; H6 += f; H7 += g; H8 += h; // // reset the offset and clean out the word buffer. // xOff = 0; for (int i = 0; i < 16; i++) { X[i] = 0; } } /* SHA-224 functions */ private int Ch( int x, int y, int z) { return ((x & y) ^ ((~x) & z)); } private int Maj( int x, int y, int z) { return ((x & y) ^ (x & z) ^ (y & z)); } private int Sum0( int x) { return ((x >>> 2) | (x << 30)) ^ ((x >>> 13) | (x << 19)) ^ ((x >>> 22) | (x << 10)); } private int Sum1( int x) { return ((x >>> 6) | (x << 26)) ^ ((x >>> 11) | (x << 21)) ^ ((x >>> 25) | (x << 7)); } private int Theta0( int x) { return ((x >>> 7) | (x << 25)) ^ ((x >>> 18) | (x << 14)) ^ (x >>> 3); } private int Theta1( int x) { return ((x >>> 17) | (x << 15)) ^ ((x >>> 19) | (x << 13)) ^ (x >>> 10); } /* SHA-224 Constants * (represent the first 32 bits of the fractional parts of the * cube roots of the first sixty-four prime numbers) */ static final int K[] = { 0x428a2f98, 0x71374491, 0xb5c0fbcf, 0xe9b5dba5, 0x3956c25b, 0x59f111f1, 0x923f82a4, 0xab1c5ed5, 0xd807aa98, 0x12835b01, 0x243185be, 0x550c7dc3, 0x72be5d74, 0x80deb1fe, 0x9bdc06a7, 0xc19bf174, 0xe49b69c1, 0xefbe4786, 0x0fc19dc6, 0x240ca1cc, 0x2de92c6f, 0x4a7484aa, 0x5cb0a9dc, 0x76f988da, 0x983e5152, 0xa831c66d, 0xb00327c8, 0xbf597fc7, 0xc6e00bf3, 0xd5a79147, 0x06ca6351, 0x14292967, 0x27b70a85, 0x2e1b2138, 0x4d2c6dfc, 0x53380d13, 0x650a7354, 0x766a0abb, 0x81c2c92e, 0x92722c85, 0xa2bfe8a1, 0xa81a664b, 0xc24b8b70, 0xc76c51a3, 0xd192e819, 0xd6990624, 0xf40e3585, 0x106aa070, 0x19a4c116, 0x1e376c08, 0x2748774c, 0x34b0bcb5, 0x391c0cb3, 0x4ed8aa4a, 0x5b9cca4f, 0x682e6ff3, 0x748f82ee, 0x78a5636f, 0x84c87814, 0x8cc70208, 0x90befffa, 0xa4506ceb, 0xbef9a3f7, 0xc67178f2 }; public Memoable copy() { return new SHA224Digest(this); } public void reset(Memoable other) { SHA224Digest d = (SHA224Digest)other; doCopy(d); } } bouncycastle-1.49.orig/src/org/bouncycastle/crypto/digests/MD5Digest.java0000644000175000017500000002212612143607521026060 0ustar ebourgebourgpackage org.bouncycastle.crypto.digests; import org.bouncycastle.util.Memoable; /** * implementation of MD5 as outlined in "Handbook of Applied Cryptography", pages 346 - 347. */ public class MD5Digest extends GeneralDigest { private static final int DIGEST_LENGTH = 16; private int H1, H2, H3, H4; // IV's private int[] X = new int[16]; private int xOff; /** * Standard constructor */ public MD5Digest() { reset(); } /** * Copy constructor. This will copy the state of the provided * message digest. */ public MD5Digest(MD5Digest t) { super(t); copyIn(t); } private void copyIn(MD5Digest t) { super.copyIn(t); H1 = t.H1; H2 = t.H2; H3 = t.H3; H4 = t.H4; System.arraycopy(t.X, 0, X, 0, t.X.length); xOff = t.xOff; } public String getAlgorithmName() { return "MD5"; } public int getDigestSize() { return DIGEST_LENGTH; } protected void processWord( byte[] in, int inOff) { X[xOff++] = (in[inOff] & 0xff) | ((in[inOff + 1] & 0xff) << 8) | ((in[inOff + 2] & 0xff) << 16) | ((in[inOff + 3] & 0xff) << 24); if (xOff == 16) { processBlock(); } } protected void processLength( long bitLength) { if (xOff > 14) { processBlock(); } X[14] = (int)(bitLength & 0xffffffff); X[15] = (int)(bitLength >>> 32); } private void unpackWord( int word, byte[] out, int outOff) { out[outOff] = (byte)word; out[outOff + 1] = (byte)(word >>> 8); out[outOff + 2] = (byte)(word >>> 16); out[outOff + 3] = (byte)(word >>> 24); } public int doFinal( byte[] out, int outOff) { finish(); unpackWord(H1, out, outOff); unpackWord(H2, out, outOff + 4); unpackWord(H3, out, outOff + 8); unpackWord(H4, out, outOff + 12); reset(); return DIGEST_LENGTH; } /** * reset the chaining variables to the IV values. */ public void reset() { super.reset(); H1 = 0x67452301; H2 = 0xefcdab89; H3 = 0x98badcfe; H4 = 0x10325476; xOff = 0; for (int i = 0; i != X.length; i++) { X[i] = 0; } } // // round 1 left rotates // private static final int S11 = 7; private static final int S12 = 12; private static final int S13 = 17; private static final int S14 = 22; // // round 2 left rotates // private static final int S21 = 5; private static final int S22 = 9; private static final int S23 = 14; private static final int S24 = 20; // // round 3 left rotates // private static final int S31 = 4; private static final int S32 = 11; private static final int S33 = 16; private static final int S34 = 23; // // round 4 left rotates // private static final int S41 = 6; private static final int S42 = 10; private static final int S43 = 15; private static final int S44 = 21; /* * rotate int x left n bits. */ private int rotateLeft( int x, int n) { return (x << n) | (x >>> (32 - n)); } /* * F, G, H and I are the basic MD5 functions. */ private int F( int u, int v, int w) { return (u & v) | (~u & w); } private int G( int u, int v, int w) { return (u & w) | (v & ~w); } private int H( int u, int v, int w) { return u ^ v ^ w; } private int K( int u, int v, int w) { return v ^ (u | ~w); } protected void processBlock() { int a = H1; int b = H2; int c = H3; int d = H4; // // Round 1 - F cycle, 16 times. // a = rotateLeft(a + F(b, c, d) + X[ 0] + 0xd76aa478, S11) + b; d = rotateLeft(d + F(a, b, c) + X[ 1] + 0xe8c7b756, S12) + a; c = rotateLeft(c + F(d, a, b) + X[ 2] + 0x242070db, S13) + d; b = rotateLeft(b + F(c, d, a) + X[ 3] + 0xc1bdceee, S14) + c; a = rotateLeft(a + F(b, c, d) + X[ 4] + 0xf57c0faf, S11) + b; d = rotateLeft(d + F(a, b, c) + X[ 5] + 0x4787c62a, S12) + a; c = rotateLeft(c + F(d, a, b) + X[ 6] + 0xa8304613, S13) + d; b = rotateLeft(b + F(c, d, a) + X[ 7] + 0xfd469501, S14) + c; a = rotateLeft(a + F(b, c, d) + X[ 8] + 0x698098d8, S11) + b; d = rotateLeft(d + F(a, b, c) + X[ 9] + 0x8b44f7af, S12) + a; c = rotateLeft(c + F(d, a, b) + X[10] + 0xffff5bb1, S13) + d; b = rotateLeft(b + F(c, d, a) + X[11] + 0x895cd7be, S14) + c; a = rotateLeft(a + F(b, c, d) + X[12] + 0x6b901122, S11) + b; d = rotateLeft(d + F(a, b, c) + X[13] + 0xfd987193, S12) + a; c = rotateLeft(c + F(d, a, b) + X[14] + 0xa679438e, S13) + d; b = rotateLeft(b + F(c, d, a) + X[15] + 0x49b40821, S14) + c; // // Round 2 - G cycle, 16 times. // a = rotateLeft(a + G(b, c, d) + X[ 1] + 0xf61e2562, S21) + b; d = rotateLeft(d + G(a, b, c) + X[ 6] + 0xc040b340, S22) + a; c = rotateLeft(c + G(d, a, b) + X[11] + 0x265e5a51, S23) + d; b = rotateLeft(b + G(c, d, a) + X[ 0] + 0xe9b6c7aa, S24) + c; a = rotateLeft(a + G(b, c, d) + X[ 5] + 0xd62f105d, S21) + b; d = rotateLeft(d + G(a, b, c) + X[10] + 0x02441453, S22) + a; c = rotateLeft(c + G(d, a, b) + X[15] + 0xd8a1e681, S23) + d; b = rotateLeft(b + G(c, d, a) + X[ 4] + 0xe7d3fbc8, S24) + c; a = rotateLeft(a + G(b, c, d) + X[ 9] + 0x21e1cde6, S21) + b; d = rotateLeft(d + G(a, b, c) + X[14] + 0xc33707d6, S22) + a; c = rotateLeft(c + G(d, a, b) + X[ 3] + 0xf4d50d87, S23) + d; b = rotateLeft(b + G(c, d, a) + X[ 8] + 0x455a14ed, S24) + c; a = rotateLeft(a + G(b, c, d) + X[13] + 0xa9e3e905, S21) + b; d = rotateLeft(d + G(a, b, c) + X[ 2] + 0xfcefa3f8, S22) + a; c = rotateLeft(c + G(d, a, b) + X[ 7] + 0x676f02d9, S23) + d; b = rotateLeft(b + G(c, d, a) + X[12] + 0x8d2a4c8a, S24) + c; // // Round 3 - H cycle, 16 times. // a = rotateLeft(a + H(b, c, d) + X[ 5] + 0xfffa3942, S31) + b; d = rotateLeft(d + H(a, b, c) + X[ 8] + 0x8771f681, S32) + a; c = rotateLeft(c + H(d, a, b) + X[11] + 0x6d9d6122, S33) + d; b = rotateLeft(b + H(c, d, a) + X[14] + 0xfde5380c, S34) + c; a = rotateLeft(a + H(b, c, d) + X[ 1] + 0xa4beea44, S31) + b; d = rotateLeft(d + H(a, b, c) + X[ 4] + 0x4bdecfa9, S32) + a; c = rotateLeft(c + H(d, a, b) + X[ 7] + 0xf6bb4b60, S33) + d; b = rotateLeft(b + H(c, d, a) + X[10] + 0xbebfbc70, S34) + c; a = rotateLeft(a + H(b, c, d) + X[13] + 0x289b7ec6, S31) + b; d = rotateLeft(d + H(a, b, c) + X[ 0] + 0xeaa127fa, S32) + a; c = rotateLeft(c + H(d, a, b) + X[ 3] + 0xd4ef3085, S33) + d; b = rotateLeft(b + H(c, d, a) + X[ 6] + 0x04881d05, S34) + c; a = rotateLeft(a + H(b, c, d) + X[ 9] + 0xd9d4d039, S31) + b; d = rotateLeft(d + H(a, b, c) + X[12] + 0xe6db99e5, S32) + a; c = rotateLeft(c + H(d, a, b) + X[15] + 0x1fa27cf8, S33) + d; b = rotateLeft(b + H(c, d, a) + X[ 2] + 0xc4ac5665, S34) + c; // // Round 4 - K cycle, 16 times. // a = rotateLeft(a + K(b, c, d) + X[ 0] + 0xf4292244, S41) + b; d = rotateLeft(d + K(a, b, c) + X[ 7] + 0x432aff97, S42) + a; c = rotateLeft(c + K(d, a, b) + X[14] + 0xab9423a7, S43) + d; b = rotateLeft(b + K(c, d, a) + X[ 5] + 0xfc93a039, S44) + c; a = rotateLeft(a + K(b, c, d) + X[12] + 0x655b59c3, S41) + b; d = rotateLeft(d + K(a, b, c) + X[ 3] + 0x8f0ccc92, S42) + a; c = rotateLeft(c + K(d, a, b) + X[10] + 0xffeff47d, S43) + d; b = rotateLeft(b + K(c, d, a) + X[ 1] + 0x85845dd1, S44) + c; a = rotateLeft(a + K(b, c, d) + X[ 8] + 0x6fa87e4f, S41) + b; d = rotateLeft(d + K(a, b, c) + X[15] + 0xfe2ce6e0, S42) + a; c = rotateLeft(c + K(d, a, b) + X[ 6] + 0xa3014314, S43) + d; b = rotateLeft(b + K(c, d, a) + X[13] + 0x4e0811a1, S44) + c; a = rotateLeft(a + K(b, c, d) + X[ 4] + 0xf7537e82, S41) + b; d = rotateLeft(d + K(a, b, c) + X[11] + 0xbd3af235, S42) + a; c = rotateLeft(c + K(d, a, b) + X[ 2] + 0x2ad7d2bb, S43) + d; b = rotateLeft(b + K(c, d, a) + X[ 9] + 0xeb86d391, S44) + c; H1 += a; H2 += b; H3 += c; H4 += d; // // reset the offset and clean out the word buffer. // xOff = 0; for (int i = 0; i != X.length; i++) { X[i] = 0; } } public Memoable copy() { return new MD5Digest(this); } public void reset(Memoable other) { MD5Digest d = (MD5Digest)other; copyIn(d); } } bouncycastle-1.49.orig/src/org/bouncycastle/crypto/digests/MD4Digest.java0000644000175000017500000001666612143607521026073 0ustar ebourgebourgpackage org.bouncycastle.crypto.digests; import org.bouncycastle.util.Memoable; /** * implementation of MD4 as RFC 1320 by R. Rivest, MIT Laboratory for * Computer Science and RSA Data Security, Inc. *

    * NOTE: This algorithm is only included for backwards compatability * with legacy applications, it's not secure, don't use it for anything new! */ public class MD4Digest extends GeneralDigest { private static final int DIGEST_LENGTH = 16; private int H1, H2, H3, H4; // IV's private int[] X = new int[16]; private int xOff; /** * Standard constructor */ public MD4Digest() { reset(); } /** * Copy constructor. This will copy the state of the provided * message digest. */ public MD4Digest(MD4Digest t) { super(t); copyIn(t); } private void copyIn(MD4Digest t) { super.copyIn(t); H1 = t.H1; H2 = t.H2; H3 = t.H3; H4 = t.H4; System.arraycopy(t.X, 0, X, 0, t.X.length); xOff = t.xOff; } public String getAlgorithmName() { return "MD4"; } public int getDigestSize() { return DIGEST_LENGTH; } protected void processWord( byte[] in, int inOff) { X[xOff++] = (in[inOff] & 0xff) | ((in[inOff + 1] & 0xff) << 8) | ((in[inOff + 2] & 0xff) << 16) | ((in[inOff + 3] & 0xff) << 24); if (xOff == 16) { processBlock(); } } protected void processLength( long bitLength) { if (xOff > 14) { processBlock(); } X[14] = (int)(bitLength & 0xffffffff); X[15] = (int)(bitLength >>> 32); } private void unpackWord( int word, byte[] out, int outOff) { out[outOff] = (byte)word; out[outOff + 1] = (byte)(word >>> 8); out[outOff + 2] = (byte)(word >>> 16); out[outOff + 3] = (byte)(word >>> 24); } public int doFinal( byte[] out, int outOff) { finish(); unpackWord(H1, out, outOff); unpackWord(H2, out, outOff + 4); unpackWord(H3, out, outOff + 8); unpackWord(H4, out, outOff + 12); reset(); return DIGEST_LENGTH; } /** * reset the chaining variables to the IV values. */ public void reset() { super.reset(); H1 = 0x67452301; H2 = 0xefcdab89; H3 = 0x98badcfe; H4 = 0x10325476; xOff = 0; for (int i = 0; i != X.length; i++) { X[i] = 0; } } // // round 1 left rotates // private static final int S11 = 3; private static final int S12 = 7; private static final int S13 = 11; private static final int S14 = 19; // // round 2 left rotates // private static final int S21 = 3; private static final int S22 = 5; private static final int S23 = 9; private static final int S24 = 13; // // round 3 left rotates // private static final int S31 = 3; private static final int S32 = 9; private static final int S33 = 11; private static final int S34 = 15; /* * rotate int x left n bits. */ private int rotateLeft( int x, int n) { return (x << n) | (x >>> (32 - n)); } /* * F, G, H and I are the basic MD4 functions. */ private int F( int u, int v, int w) { return (u & v) | (~u & w); } private int G( int u, int v, int w) { return (u & v) | (u & w) | (v & w); } private int H( int u, int v, int w) { return u ^ v ^ w; } protected void processBlock() { int a = H1; int b = H2; int c = H3; int d = H4; // // Round 1 - F cycle, 16 times. // a = rotateLeft(a + F(b, c, d) + X[ 0], S11); d = rotateLeft(d + F(a, b, c) + X[ 1], S12); c = rotateLeft(c + F(d, a, b) + X[ 2], S13); b = rotateLeft(b + F(c, d, a) + X[ 3], S14); a = rotateLeft(a + F(b, c, d) + X[ 4], S11); d = rotateLeft(d + F(a, b, c) + X[ 5], S12); c = rotateLeft(c + F(d, a, b) + X[ 6], S13); b = rotateLeft(b + F(c, d, a) + X[ 7], S14); a = rotateLeft(a + F(b, c, d) + X[ 8], S11); d = rotateLeft(d + F(a, b, c) + X[ 9], S12); c = rotateLeft(c + F(d, a, b) + X[10], S13); b = rotateLeft(b + F(c, d, a) + X[11], S14); a = rotateLeft(a + F(b, c, d) + X[12], S11); d = rotateLeft(d + F(a, b, c) + X[13], S12); c = rotateLeft(c + F(d, a, b) + X[14], S13); b = rotateLeft(b + F(c, d, a) + X[15], S14); // // Round 2 - G cycle, 16 times. // a = rotateLeft(a + G(b, c, d) + X[ 0] + 0x5a827999, S21); d = rotateLeft(d + G(a, b, c) + X[ 4] + 0x5a827999, S22); c = rotateLeft(c + G(d, a, b) + X[ 8] + 0x5a827999, S23); b = rotateLeft(b + G(c, d, a) + X[12] + 0x5a827999, S24); a = rotateLeft(a + G(b, c, d) + X[ 1] + 0x5a827999, S21); d = rotateLeft(d + G(a, b, c) + X[ 5] + 0x5a827999, S22); c = rotateLeft(c + G(d, a, b) + X[ 9] + 0x5a827999, S23); b = rotateLeft(b + G(c, d, a) + X[13] + 0x5a827999, S24); a = rotateLeft(a + G(b, c, d) + X[ 2] + 0x5a827999, S21); d = rotateLeft(d + G(a, b, c) + X[ 6] + 0x5a827999, S22); c = rotateLeft(c + G(d, a, b) + X[10] + 0x5a827999, S23); b = rotateLeft(b + G(c, d, a) + X[14] + 0x5a827999, S24); a = rotateLeft(a + G(b, c, d) + X[ 3] + 0x5a827999, S21); d = rotateLeft(d + G(a, b, c) + X[ 7] + 0x5a827999, S22); c = rotateLeft(c + G(d, a, b) + X[11] + 0x5a827999, S23); b = rotateLeft(b + G(c, d, a) + X[15] + 0x5a827999, S24); // // Round 3 - H cycle, 16 times. // a = rotateLeft(a + H(b, c, d) + X[ 0] + 0x6ed9eba1, S31); d = rotateLeft(d + H(a, b, c) + X[ 8] + 0x6ed9eba1, S32); c = rotateLeft(c + H(d, a, b) + X[ 4] + 0x6ed9eba1, S33); b = rotateLeft(b + H(c, d, a) + X[12] + 0x6ed9eba1, S34); a = rotateLeft(a + H(b, c, d) + X[ 2] + 0x6ed9eba1, S31); d = rotateLeft(d + H(a, b, c) + X[10] + 0x6ed9eba1, S32); c = rotateLeft(c + H(d, a, b) + X[ 6] + 0x6ed9eba1, S33); b = rotateLeft(b + H(c, d, a) + X[14] + 0x6ed9eba1, S34); a = rotateLeft(a + H(b, c, d) + X[ 1] + 0x6ed9eba1, S31); d = rotateLeft(d + H(a, b, c) + X[ 9] + 0x6ed9eba1, S32); c = rotateLeft(c + H(d, a, b) + X[ 5] + 0x6ed9eba1, S33); b = rotateLeft(b + H(c, d, a) + X[13] + 0x6ed9eba1, S34); a = rotateLeft(a + H(b, c, d) + X[ 3] + 0x6ed9eba1, S31); d = rotateLeft(d + H(a, b, c) + X[11] + 0x6ed9eba1, S32); c = rotateLeft(c + H(d, a, b) + X[ 7] + 0x6ed9eba1, S33); b = rotateLeft(b + H(c, d, a) + X[15] + 0x6ed9eba1, S34); H1 += a; H2 += b; H3 += c; H4 += d; // // reset the offset and clean out the word buffer. // xOff = 0; for (int i = 0; i != X.length; i++) { X[i] = 0; } } public Memoable copy() { return new MD4Digest(this); } public void reset(Memoable other) { MD4Digest d = (MD4Digest)other; copyIn(d); } } bouncycastle-1.49.orig/src/org/bouncycastle/crypto/digests/RIPEMD256Digest.java0000644000175000017500000002654512143607521026721 0ustar ebourgebourgpackage org.bouncycastle.crypto.digests; import org.bouncycastle.util.Memoable; /** * implementation of RIPEMD256. *

    * note: this algorithm offers the same level of security as RIPEMD128. */ public class RIPEMD256Digest extends GeneralDigest { private static final int DIGEST_LENGTH = 32; private int H0, H1, H2, H3, H4, H5, H6, H7; // IV's private int[] X = new int[16]; private int xOff; /** * Standard constructor */ public RIPEMD256Digest() { reset(); } /** * Copy constructor. This will copy the state of the provided * message digest. */ public RIPEMD256Digest(RIPEMD256Digest t) { super(t); copyIn(t); } private void copyIn(RIPEMD256Digest t) { super.copyIn(t); H0 = t.H0; H1 = t.H1; H2 = t.H2; H3 = t.H3; H4 = t.H4; H5 = t.H5; H6 = t.H6; H7 = t.H7; System.arraycopy(t.X, 0, X, 0, t.X.length); xOff = t.xOff; } public String getAlgorithmName() { return "RIPEMD256"; } public int getDigestSize() { return DIGEST_LENGTH; } protected void processWord( byte[] in, int inOff) { X[xOff++] = (in[inOff] & 0xff) | ((in[inOff + 1] & 0xff) << 8) | ((in[inOff + 2] & 0xff) << 16) | ((in[inOff + 3] & 0xff) << 24); if (xOff == 16) { processBlock(); } } protected void processLength( long bitLength) { if (xOff > 14) { processBlock(); } X[14] = (int)(bitLength & 0xffffffff); X[15] = (int)(bitLength >>> 32); } private void unpackWord( int word, byte[] out, int outOff) { out[outOff] = (byte)word; out[outOff + 1] = (byte)(word >>> 8); out[outOff + 2] = (byte)(word >>> 16); out[outOff + 3] = (byte)(word >>> 24); } public int doFinal( byte[] out, int outOff) { finish(); unpackWord(H0, out, outOff); unpackWord(H1, out, outOff + 4); unpackWord(H2, out, outOff + 8); unpackWord(H3, out, outOff + 12); unpackWord(H4, out, outOff + 16); unpackWord(H5, out, outOff + 20); unpackWord(H6, out, outOff + 24); unpackWord(H7, out, outOff + 28); reset(); return DIGEST_LENGTH; } /** * reset the chaining variables to the IV values. */ public void reset() { super.reset(); H0 = 0x67452301; H1 = 0xefcdab89; H2 = 0x98badcfe; H3 = 0x10325476; H4 = 0x76543210; H5 = 0xFEDCBA98; H6 = 0x89ABCDEF; H7 = 0x01234567; xOff = 0; for (int i = 0; i != X.length; i++) { X[i] = 0; } } /* * rotate int x left n bits. */ private int RL( int x, int n) { return (x << n) | (x >>> (32 - n)); } /* * f1,f2,f3,f4 are the basic RIPEMD128 functions. */ /* * F */ private int f1( int x, int y, int z) { return x ^ y ^ z; } /* * G */ private int f2( int x, int y, int z) { return (x & y) | (~x & z); } /* * H */ private int f3( int x, int y, int z) { return (x | ~y) ^ z; } /* * I */ private int f4( int x, int y, int z) { return (x & z) | (y & ~z); } private int F1( int a, int b, int c, int d, int x, int s) { return RL(a + f1(b, c, d) + x, s); } private int F2( int a, int b, int c, int d, int x, int s) { return RL(a + f2(b, c, d) + x + 0x5a827999, s); } private int F3( int a, int b, int c, int d, int x, int s) { return RL(a + f3(b, c, d) + x + 0x6ed9eba1, s); } private int F4( int a, int b, int c, int d, int x, int s) { return RL(a + f4(b, c, d) + x + 0x8f1bbcdc, s); } private int FF1( int a, int b, int c, int d, int x, int s) { return RL(a + f1(b, c, d) + x, s); } private int FF2( int a, int b, int c, int d, int x, int s) { return RL(a + f2(b, c, d) + x + 0x6d703ef3, s); } private int FF3( int a, int b, int c, int d, int x, int s) { return RL(a + f3(b, c, d) + x + 0x5c4dd124, s); } private int FF4( int a, int b, int c, int d, int x, int s) { return RL(a + f4(b, c, d) + x + 0x50a28be6, s); } protected void processBlock() { int a, aa; int b, bb; int c, cc; int d, dd; int t; a = H0; b = H1; c = H2; d = H3; aa = H4; bb = H5; cc = H6; dd = H7; // // Round 1 // a = F1(a, b, c, d, X[ 0], 11); d = F1(d, a, b, c, X[ 1], 14); c = F1(c, d, a, b, X[ 2], 15); b = F1(b, c, d, a, X[ 3], 12); a = F1(a, b, c, d, X[ 4], 5); d = F1(d, a, b, c, X[ 5], 8); c = F1(c, d, a, b, X[ 6], 7); b = F1(b, c, d, a, X[ 7], 9); a = F1(a, b, c, d, X[ 8], 11); d = F1(d, a, b, c, X[ 9], 13); c = F1(c, d, a, b, X[10], 14); b = F1(b, c, d, a, X[11], 15); a = F1(a, b, c, d, X[12], 6); d = F1(d, a, b, c, X[13], 7); c = F1(c, d, a, b, X[14], 9); b = F1(b, c, d, a, X[15], 8); aa = FF4(aa, bb, cc, dd, X[ 5], 8); dd = FF4(dd, aa, bb, cc, X[14], 9); cc = FF4(cc, dd, aa, bb, X[ 7], 9); bb = FF4(bb, cc, dd, aa, X[ 0], 11); aa = FF4(aa, bb, cc, dd, X[ 9], 13); dd = FF4(dd, aa, bb, cc, X[ 2], 15); cc = FF4(cc, dd, aa, bb, X[11], 15); bb = FF4(bb, cc, dd, aa, X[ 4], 5); aa = FF4(aa, bb, cc, dd, X[13], 7); dd = FF4(dd, aa, bb, cc, X[ 6], 7); cc = FF4(cc, dd, aa, bb, X[15], 8); bb = FF4(bb, cc, dd, aa, X[ 8], 11); aa = FF4(aa, bb, cc, dd, X[ 1], 14); dd = FF4(dd, aa, bb, cc, X[10], 14); cc = FF4(cc, dd, aa, bb, X[ 3], 12); bb = FF4(bb, cc, dd, aa, X[12], 6); t = a; a = aa; aa = t; // // Round 2 // a = F2(a, b, c, d, X[ 7], 7); d = F2(d, a, b, c, X[ 4], 6); c = F2(c, d, a, b, X[13], 8); b = F2(b, c, d, a, X[ 1], 13); a = F2(a, b, c, d, X[10], 11); d = F2(d, a, b, c, X[ 6], 9); c = F2(c, d, a, b, X[15], 7); b = F2(b, c, d, a, X[ 3], 15); a = F2(a, b, c, d, X[12], 7); d = F2(d, a, b, c, X[ 0], 12); c = F2(c, d, a, b, X[ 9], 15); b = F2(b, c, d, a, X[ 5], 9); a = F2(a, b, c, d, X[ 2], 11); d = F2(d, a, b, c, X[14], 7); c = F2(c, d, a, b, X[11], 13); b = F2(b, c, d, a, X[ 8], 12); aa = FF3(aa, bb, cc, dd, X[ 6], 9); dd = FF3(dd, aa, bb, cc, X[ 11], 13); cc = FF3(cc, dd, aa, bb, X[3], 15); bb = FF3(bb, cc, dd, aa, X[ 7], 7); aa = FF3(aa, bb, cc, dd, X[0], 12); dd = FF3(dd, aa, bb, cc, X[13], 8); cc = FF3(cc, dd, aa, bb, X[5], 9); bb = FF3(bb, cc, dd, aa, X[10], 11); aa = FF3(aa, bb, cc, dd, X[14], 7); dd = FF3(dd, aa, bb, cc, X[15], 7); cc = FF3(cc, dd, aa, bb, X[ 8], 12); bb = FF3(bb, cc, dd, aa, X[12], 7); aa = FF3(aa, bb, cc, dd, X[ 4], 6); dd = FF3(dd, aa, bb, cc, X[ 9], 15); cc = FF3(cc, dd, aa, bb, X[ 1], 13); bb = FF3(bb, cc, dd, aa, X[ 2], 11); t = b; b = bb; bb = t; // // Round 3 // a = F3(a, b, c, d, X[ 3], 11); d = F3(d, a, b, c, X[10], 13); c = F3(c, d, a, b, X[14], 6); b = F3(b, c, d, a, X[ 4], 7); a = F3(a, b, c, d, X[ 9], 14); d = F3(d, a, b, c, X[15], 9); c = F3(c, d, a, b, X[ 8], 13); b = F3(b, c, d, a, X[ 1], 15); a = F3(a, b, c, d, X[ 2], 14); d = F3(d, a, b, c, X[ 7], 8); c = F3(c, d, a, b, X[ 0], 13); b = F3(b, c, d, a, X[ 6], 6); a = F3(a, b, c, d, X[13], 5); d = F3(d, a, b, c, X[11], 12); c = F3(c, d, a, b, X[ 5], 7); b = F3(b, c, d, a, X[12], 5); aa = FF2(aa, bb, cc, dd, X[ 15], 9); dd = FF2(dd, aa, bb, cc, X[5], 7); cc = FF2(cc, dd, aa, bb, X[1], 15); bb = FF2(bb, cc, dd, aa, X[ 3], 11); aa = FF2(aa, bb, cc, dd, X[ 7], 8); dd = FF2(dd, aa, bb, cc, X[14], 6); cc = FF2(cc, dd, aa, bb, X[ 6], 6); bb = FF2(bb, cc, dd, aa, X[ 9], 14); aa = FF2(aa, bb, cc, dd, X[11], 12); dd = FF2(dd, aa, bb, cc, X[ 8], 13); cc = FF2(cc, dd, aa, bb, X[12], 5); bb = FF2(bb, cc, dd, aa, X[ 2], 14); aa = FF2(aa, bb, cc, dd, X[10], 13); dd = FF2(dd, aa, bb, cc, X[ 0], 13); cc = FF2(cc, dd, aa, bb, X[ 4], 7); bb = FF2(bb, cc, dd, aa, X[13], 5); t = c; c = cc; cc = t; // // Round 4 // a = F4(a, b, c, d, X[ 1], 11); d = F4(d, a, b, c, X[ 9], 12); c = F4(c, d, a, b, X[11], 14); b = F4(b, c, d, a, X[10], 15); a = F4(a, b, c, d, X[ 0], 14); d = F4(d, a, b, c, X[ 8], 15); c = F4(c, d, a, b, X[12], 9); b = F4(b, c, d, a, X[ 4], 8); a = F4(a, b, c, d, X[13], 9); d = F4(d, a, b, c, X[ 3], 14); c = F4(c, d, a, b, X[ 7], 5); b = F4(b, c, d, a, X[15], 6); a = F4(a, b, c, d, X[14], 8); d = F4(d, a, b, c, X[ 5], 6); c = F4(c, d, a, b, X[ 6], 5); b = F4(b, c, d, a, X[ 2], 12); aa = FF1(aa, bb, cc, dd, X[ 8], 15); dd = FF1(dd, aa, bb, cc, X[ 6], 5); cc = FF1(cc, dd, aa, bb, X[ 4], 8); bb = FF1(bb, cc, dd, aa, X[ 1], 11); aa = FF1(aa, bb, cc, dd, X[ 3], 14); dd = FF1(dd, aa, bb, cc, X[11], 14); cc = FF1(cc, dd, aa, bb, X[15], 6); bb = FF1(bb, cc, dd, aa, X[ 0], 14); aa = FF1(aa, bb, cc, dd, X[ 5], 6); dd = FF1(dd, aa, bb, cc, X[12], 9); cc = FF1(cc, dd, aa, bb, X[ 2], 12); bb = FF1(bb, cc, dd, aa, X[13], 9); aa = FF1(aa, bb, cc, dd, X[ 9], 12); dd = FF1(dd, aa, bb, cc, X[ 7], 5); cc = FF1(cc, dd, aa, bb, X[10], 15); bb = FF1(bb, cc, dd, aa, X[14], 8); t = d; d = dd; dd = t; H0 += a; H1 += b; H2 += c; H3 += d; H4 += aa; H5 += bb; H6 += cc; H7 += dd; // // reset the offset and clean out the word buffer. // xOff = 0; for (int i = 0; i != X.length; i++) { X[i] = 0; } } public Memoable copy() { return new RIPEMD256Digest(this); } public void reset(Memoable other) { RIPEMD256Digest d = (RIPEMD256Digest)other; copyIn(d); } } bouncycastle-1.49.orig/src/org/bouncycastle/crypto/digests/GOST3411Digest.java0000644000175000017500000002106512143604007026555 0ustar ebourgebourgpackage org.bouncycastle.crypto.digests; import org.bouncycastle.crypto.BlockCipher; import org.bouncycastle.crypto.ExtendedDigest; import org.bouncycastle.crypto.engines.GOST28147Engine; import org.bouncycastle.crypto.params.KeyParameter; import org.bouncycastle.crypto.params.ParametersWithSBox; import org.bouncycastle.crypto.util.Pack; import org.bouncycastle.util.Arrays; import org.bouncycastle.util.Memoable; /** * implementation of GOST R 34.11-94 */ public class GOST3411Digest implements ExtendedDigest, Memoable { private static final int DIGEST_LENGTH = 32; private byte[] H = new byte[32], L = new byte[32], M = new byte[32], Sum = new byte[32]; private byte[][] C = new byte[4][32]; private byte[] xBuf = new byte[32]; private int xBufOff; private long byteCount; private BlockCipher cipher = new GOST28147Engine(); private byte[] sBox; /** * Standard constructor */ public GOST3411Digest() { sBox = GOST28147Engine.getSBox("D-A"); cipher.init(true, new ParametersWithSBox(null, sBox)); reset(); } /** * Constructor to allow use of a particular sbox with GOST28147 * @see GOST28147Engine#getSBox(String) */ public GOST3411Digest(byte[] sBoxParam) { sBox = Arrays.clone(sBoxParam); cipher.init(true, new ParametersWithSBox(null, sBox)); reset(); } /** * Copy constructor. This will copy the state of the provided * message digest. */ public GOST3411Digest(GOST3411Digest t) { reset(t); } public String getAlgorithmName() { return "GOST3411"; } public int getDigestSize() { return DIGEST_LENGTH; } public void update(byte in) { xBuf[xBufOff++] = in; if (xBufOff == xBuf.length) { sumByteArray(xBuf); // calc sum M processBlock(xBuf, 0); xBufOff = 0; } byteCount++; } public void update(byte[] in, int inOff, int len) { while ((xBufOff != 0) && (len > 0)) { update(in[inOff]); inOff++; len--; } while (len > xBuf.length) { System.arraycopy(in, inOff, xBuf, 0, xBuf.length); sumByteArray(xBuf); // calc sum M processBlock(xBuf, 0); inOff += xBuf.length; len -= xBuf.length; byteCount += xBuf.length; } // load in the remainder. while (len > 0) { update(in[inOff]); inOff++; len--; } } // (i + 1 + 4(k - 1)) = 8i + k i = 0-3, k = 1-8 private byte[] K = new byte[32]; private byte[] P(byte[] in) { for(int k = 0; k < 8; k++) { K[4*k] = in[k]; K[1 + 4*k] = in[ 8 + k]; K[2 + 4*k] = in[16 + k]; K[3 + 4*k] = in[24 + k]; } return K; } //A (x) = (x0 ^ x1) || x3 || x2 || x1 byte[] a = new byte[8]; private byte[] A(byte[] in) { for(int j=0; j<8; j++) { a[j]=(byte)(in[j] ^ in[j+8]); } System.arraycopy(in, 8, in, 0, 24); System.arraycopy(a, 0, in, 24, 8); return in; } //Encrypt function, ECB mode private void E(byte[] key, byte[] s, int sOff, byte[] in, int inOff) { cipher.init(true, new KeyParameter(key)); cipher.processBlock(in, inOff, s, sOff); } // (in:) n16||..||n1 ==> (out:) n1^n2^n3^n4^n13^n16||n16||..||n2 short[] wS = new short[16], w_S = new short[16]; private void fw(byte[] in) { cpyBytesToShort(in, wS); w_S[15] = (short)(wS[0] ^ wS[1] ^ wS[2] ^ wS[3] ^ wS[12] ^ wS[15]); System.arraycopy(wS, 1, w_S, 0, 15); cpyShortToBytes(w_S, in); } // block processing byte[] S = new byte[32]; byte[] U = new byte[32], V = new byte[32], W = new byte[32]; protected void processBlock(byte[] in, int inOff) { System.arraycopy(in, inOff, M, 0, 32); //key step 1 // H = h3 || h2 || h1 || h0 // S = s3 || s2 || s1 || s0 System.arraycopy(H, 0, U, 0, 32); System.arraycopy(M, 0, V, 0, 32); for (int j=0; j<32; j++) { W[j] = (byte)(U[j]^V[j]); } // Encrypt gost28147-ECB E(P(W), S, 0, H, 0); // s0 = EK0 [h0] //keys step 2,3,4 for (int i=1; i<4; i++) { byte[] tmpA = A(U); for (int j=0; j<32; j++) { U[j] = (byte)(tmpA[j] ^ C[i][j]); } V = A(A(V)); for (int j=0; j<32; j++) { W[j] = (byte)(U[j]^V[j]); } // Encrypt gost28147-ECB E(P(W), S, i * 8, H, i * 8); // si = EKi [hi] } // x(M, H) = y61(H^y(M^y12(S))) for(int n = 0; n < 12; n++) { fw(S); } for(int n = 0; n < 32; n++) { S[n] = (byte)(S[n] ^ M[n]); } fw(S); for(int n = 0; n < 32; n++) { S[n] = (byte)(H[n] ^ S[n]); } for(int n = 0; n < 61; n++) { fw(S); } System.arraycopy(S, 0, H, 0, H.length); } private void finish() { Pack.longToLittleEndian(byteCount * 8, L, 0); // get length into L (byteCount * 8 = bitCount) while (xBufOff != 0) { update((byte)0); } processBlock(L, 0); processBlock(Sum, 0); } public int doFinal( byte[] out, int outOff) { finish(); System.arraycopy(H, 0, out, outOff, H.length); reset(); return DIGEST_LENGTH; } /** * reset the chaining variables to the IV values. */ private static final byte[] C2 = { 0x00,(byte)0xFF,0x00,(byte)0xFF,0x00,(byte)0xFF,0x00,(byte)0xFF, (byte)0xFF,0x00,(byte)0xFF,0x00,(byte)0xFF,0x00,(byte)0xFF,0x00, 0x00,(byte)0xFF,(byte)0xFF,0x00,(byte)0xFF,0x00,0x00,(byte)0xFF, (byte)0xFF,0x00,0x00,0x00,(byte)0xFF,(byte)0xFF,0x00,(byte)0xFF}; public void reset() { byteCount = 0; xBufOff = 0; for(int i=0; i (Sum + a mod (2^256)) private void sumByteArray(byte[] in) { int carry = 0; for (int i = 0; i != Sum.length; i++) { int sum = (Sum[i] & 0xff) + (in[i] & 0xff) + carry; Sum[i] = (byte)sum; carry = sum >>> 8; } } private void cpyBytesToShort(byte[] S, short[] wS) { for(int i=0; i> 8); S[i*2] = (byte)wS[i]; } } public int getByteLength() { return 32; } public Memoable copy() { return new GOST3411Digest(this); } public void reset(Memoable other) { GOST3411Digest t = (GOST3411Digest)other; this.sBox = t.sBox; cipher.init(true, new ParametersWithSBox(null, sBox)); reset(); System.arraycopy(t.H, 0, this.H, 0, t.H.length); System.arraycopy(t.L, 0, this.L, 0, t.L.length); System.arraycopy(t.M, 0, this.M, 0, t.M.length); System.arraycopy(t.Sum, 0, this.Sum, 0, t.Sum.length); System.arraycopy(t.C[1], 0, this.C[1], 0, t.C[1].length); System.arraycopy(t.C[2], 0, this.C[2], 0, t.C[2].length); System.arraycopy(t.C[3], 0, this.C[3], 0, t.C[3].length); System.arraycopy(t.xBuf, 0, this.xBuf, 0, t.xBuf.length); this.xBufOff = t.xBufOff; this.byteCount = t.byteCount; } } bouncycastle-1.49.orig/src/org/bouncycastle/crypto/digests/SHA512Digest.java0000644000175000017500000000416312143607301026333 0ustar ebourgebourgpackage org.bouncycastle.crypto.digests; import org.bouncycastle.crypto.util.Pack; import org.bouncycastle.util.Memoable; /** * FIPS 180-2 implementation of SHA-512. * *

     *         block  word  digest
     * SHA-1   512    32    160
     * SHA-256 512    32    256
     * SHA-384 1024   64    384
     * SHA-512 1024   64    512
     * 
    */ public class SHA512Digest extends LongDigest { private static final int DIGEST_LENGTH = 64; /** * Standard constructor */ public SHA512Digest() { } /** * Copy constructor. This will copy the state of the provided * message digest. */ public SHA512Digest(SHA512Digest t) { super(t); } public String getAlgorithmName() { return "SHA-512"; } public int getDigestSize() { return DIGEST_LENGTH; } public int doFinal( byte[] out, int outOff) { finish(); Pack.longToBigEndian(H1, out, outOff); Pack.longToBigEndian(H2, out, outOff + 8); Pack.longToBigEndian(H3, out, outOff + 16); Pack.longToBigEndian(H4, out, outOff + 24); Pack.longToBigEndian(H5, out, outOff + 32); Pack.longToBigEndian(H6, out, outOff + 40); Pack.longToBigEndian(H7, out, outOff + 48); Pack.longToBigEndian(H8, out, outOff + 56); reset(); return DIGEST_LENGTH; } /** * reset the chaining variables */ public void reset() { super.reset(); /* SHA-512 initial hash value * The first 64 bits of the fractional parts of the square roots * of the first eight prime numbers */ H1 = 0x6a09e667f3bcc908L; H2 = 0xbb67ae8584caa73bL; H3 = 0x3c6ef372fe94f82bL; H4 = 0xa54ff53a5f1d36f1L; H5 = 0x510e527fade682d1L; H6 = 0x9b05688c2b3e6c1fL; H7 = 0x1f83d9abfb41bd6bL; H8 = 0x5be0cd19137e2179L; } public Memoable copy() { return new SHA512Digest(this); } public void reset(Memoable other) { SHA512Digest d = (SHA512Digest)other; copyIn(d); } } bouncycastle-1.49.orig/src/org/bouncycastle/crypto/digests/package.html0000644000175000017500000000011010262753175025745 0ustar ebourgebourg Message digest classes. bouncycastle-1.49.orig/src/org/bouncycastle/crypto/KeyGenerationParameters.java0000644000175000017500000000211710262753175027466 0ustar ebourgebourgpackage org.bouncycastle.crypto; import java.security.SecureRandom; /** * The base class for parameters to key generators. */ public class KeyGenerationParameters { private SecureRandom random; private int strength; /** * initialise the generator with a source of randomness * and a strength (in bits). * * @param random the random byte source. * @param strength the size, in bits, of the keys we want to produce. */ public KeyGenerationParameters( SecureRandom random, int strength) { this.random = random; this.strength = strength; } /** * return the random source associated with this * generator. * * @return the generators random source. */ public SecureRandom getRandom() { return random; } /** * return the bit strength for keys produced by this generator, * * @return the strength of the keys this generator produces (in bits). */ public int getStrength() { return strength; } } bouncycastle-1.49.orig/src/org/bouncycastle/crypto/kems/0000755000175000017500000000000012152033551022756 5ustar ebourgebourgbouncycastle-1.49.orig/src/org/bouncycastle/crypto/kems/RSAKeyEncapsulation.java0000755000175000017500000001140112151124203027437 0ustar ebourgebourgpackage org.bouncycastle.crypto.kems; import java.math.BigInteger; import java.security.SecureRandom; import org.bouncycastle.crypto.CipherParameters; import org.bouncycastle.crypto.DerivationFunction; import org.bouncycastle.crypto.KeyEncapsulation; import org.bouncycastle.crypto.params.KDFParameters; import org.bouncycastle.crypto.params.KeyParameter; import org.bouncycastle.crypto.params.RSAKeyParameters; import org.bouncycastle.util.BigIntegers; /** * The RSA Key Encapsulation Mechanism (RSA-KEM) from ISO 18033-2. */ public class RSAKeyEncapsulation implements KeyEncapsulation { private static final BigInteger ZERO = BigInteger.valueOf(0); private static final BigInteger ONE = BigInteger.valueOf(1); private DerivationFunction kdf; private SecureRandom rnd; private RSAKeyParameters key; /** * Set up the RSA-KEM. * * @param kdf the key derivation function to be used. * @param rnd the random source for the session key. */ public RSAKeyEncapsulation( DerivationFunction kdf, SecureRandom rnd) { this.kdf = kdf; this.rnd = rnd; } /** * Initialise the RSA-KEM. * * @param key the recipient's public (for encryption) or private (for decryption) key. */ public void init(CipherParameters key) throws IllegalArgumentException { if (!(key instanceof RSAKeyParameters)) { throw new IllegalArgumentException("RSA key required"); } else { this.key = (RSAKeyParameters)key; } } /** * Generate and encapsulate a random session key. * * @param out the output buffer for the encapsulated key. * @param outOff the offset for the output buffer. * @param keyLen the length of the random session key. * @return the random session key. */ public CipherParameters encrypt(byte[] out, int outOff, int keyLen) throws IllegalArgumentException { if (key.isPrivate()) { throw new IllegalArgumentException("Public key required for encryption"); } BigInteger n = key.getModulus(); BigInteger e = key.getExponent(); // Generate the ephemeral random and encode it BigInteger r = BigIntegers.createRandomInRange(ZERO, n.subtract(ONE), rnd); byte[] R = BigIntegers.asUnsignedByteArray((n.bitLength() + 7) / 8, r); // Encrypt the random and encode it BigInteger c = r.modPow(e, n); byte[] C = BigIntegers.asUnsignedByteArray((n.bitLength() + 7) / 8, c); System.arraycopy(C, 0, out, outOff, C.length); // Initialise the KDF kdf.init(new KDFParameters(R, null)); // Generate the secret key byte[] K = new byte[keyLen]; kdf.generateBytes(K, 0, K.length); return new KeyParameter(K); } /** * Generate and encapsulate a random session key. * * @param out the output buffer for the encapsulated key. * @param keyLen the length of the random session key. * @return the random session key. */ public CipherParameters encrypt(byte[] out, int keyLen) { return encrypt(out, 0, keyLen); } /** * Decrypt an encapsulated session key. * * @param in the input buffer for the encapsulated key. * @param inOff the offset for the input buffer. * @param inLen the length of the encapsulated key. * @param keyLen the length of the session key. * @return the session key. */ public CipherParameters decrypt(byte[] in, int inOff, int inLen, int keyLen) throws IllegalArgumentException { if (!key.isPrivate()) { throw new IllegalArgumentException("Private key required for decryption"); } BigInteger n = key.getModulus(); BigInteger d = key.getExponent(); // Decode the input byte[] C = new byte[inLen]; System.arraycopy(in, inOff, C, 0, C.length); BigInteger c = new BigInteger(1, C); // Decrypt the ephemeral random and encode it BigInteger r = c.modPow(d, n); byte[] R = BigIntegers.asUnsignedByteArray((n.bitLength() + 7) / 8, r); // Initialise the KDF kdf.init(new KDFParameters(R, null)); // Generate the secret key byte[] K = new byte[keyLen]; kdf.generateBytes(K, 0, K.length); return new KeyParameter(K); } /** * Decrypt an encapsulated session key. * * @param in the input buffer for the encapsulated key. * @param keyLen the length of the session key. * @return the session key. */ public CipherParameters decrypt(byte[] in, int keyLen) { return decrypt(in, 0, in.length, keyLen); } } bouncycastle-1.49.orig/src/org/bouncycastle/crypto/kems/ECIESKeyEncapsulation.java0000755000175000017500000001726112151124203027654 0ustar ebourgebourgpackage org.bouncycastle.crypto.kems; import java.math.BigInteger; import java.security.SecureRandom; import org.bouncycastle.crypto.CipherParameters; import org.bouncycastle.crypto.DerivationFunction; import org.bouncycastle.crypto.KeyEncapsulation; import org.bouncycastle.crypto.params.ECKeyParameters; import org.bouncycastle.crypto.params.ECPrivateKeyParameters; import org.bouncycastle.crypto.params.ECPublicKeyParameters; import org.bouncycastle.crypto.params.KDFParameters; import org.bouncycastle.crypto.params.KeyParameter; import org.bouncycastle.math.ec.ECPoint; import org.bouncycastle.util.BigIntegers; /** * The ECIES Key Encapsulation Mechanism (ECIES-KEM) from ISO 18033-2. */ public class ECIESKeyEncapsulation implements KeyEncapsulation { private static final BigInteger ONE = BigInteger.valueOf(1); private DerivationFunction kdf; private SecureRandom rnd; private ECKeyParameters key; private boolean CofactorMode; private boolean OldCofactorMode; private boolean SingleHashMode; /** * Set up the ECIES-KEM. * * @param kdf the key derivation function to be used. * @param rnd the random source for the session key. */ public ECIESKeyEncapsulation( DerivationFunction kdf, SecureRandom rnd) { this.kdf = kdf; this.rnd = rnd; this.CofactorMode = false; this.OldCofactorMode = false; this.SingleHashMode = false; } /** * Set up the ECIES-KEM. * * @param kdf the key derivation function to be used. * @param rnd the random source for the session key. * @param cofactorMode true to use the new cofactor ECDH. * @param oldCofactorMode true to use the old cofactor ECDH. * @param singleHashMode true to use single hash mode. */ public ECIESKeyEncapsulation( DerivationFunction kdf, SecureRandom rnd, boolean cofactorMode, boolean oldCofactorMode, boolean singleHashMode) { this.kdf = kdf; this.rnd = rnd; // If both cofactorMode and oldCofactorMode are set to true // then the implementation will use the new cofactor ECDH this.CofactorMode = cofactorMode; this.OldCofactorMode = oldCofactorMode; this.SingleHashMode = singleHashMode; } /** * Initialise the ECIES-KEM. * * @param key the recipient's public (for encryption) or private (for decryption) key. */ public void init(CipherParameters key) throws IllegalArgumentException { if (!(key instanceof ECKeyParameters)) { throw new IllegalArgumentException("EC key required"); } else { this.key = (ECKeyParameters)key; } } /** * Generate and encapsulate a random session key. * * @param out the output buffer for the encapsulated key. * @param outOff the offset for the output buffer. * @param keyLen the length of the session key. * @return the random session key. */ public CipherParameters encrypt(byte[] out, int outOff, int keyLen) throws IllegalArgumentException { if (!(key instanceof ECPublicKeyParameters)) { throw new IllegalArgumentException("Public key required for encryption"); } BigInteger n = key.getParameters().getN(); BigInteger h = key.getParameters().getH(); // Generate the ephemeral key pair BigInteger r = BigIntegers.createRandomInRange(ONE, n, rnd); ECPoint gTilde = key.getParameters().getG().multiply(r); // Encode the ephemeral public key byte[] C = gTilde.getEncoded(); System.arraycopy(C, 0, out, outOff, C.length); // Compute the static-ephemeral key agreement BigInteger rPrime; if (CofactorMode) { rPrime = r.multiply(h).mod(n); } else { rPrime = r; } ECPoint hTilde = ((ECPublicKeyParameters)key).getQ().multiply(rPrime); // Encode the shared secret value int PEHlen = (key.getParameters().getCurve().getFieldSize() + 7) / 8; byte[] PEH = BigIntegers.asUnsignedByteArray(PEHlen, hTilde.getX().toBigInteger()); // Initialise the KDF byte[] kdfInput; if (SingleHashMode) { kdfInput = new byte[C.length + PEH.length]; System.arraycopy(C, 0, kdfInput, 0, C.length); System.arraycopy(PEH, 0, kdfInput, C.length, PEH.length); } else { kdfInput = PEH; } kdf.init(new KDFParameters(kdfInput, null)); // Generate the secret key byte[] K = new byte[keyLen]; kdf.generateBytes(K, 0, K.length); // Return the ciphertext return new KeyParameter(K); } /** * Generate and encapsulate a random session key. * * @param out the output buffer for the encapsulated key. * @param keyLen the length of the session key. * @return the random session key. */ public CipherParameters encrypt(byte[] out, int keyLen) { return encrypt(out, 0, keyLen); } /** * Decrypt an encapsulated session key. * * @param in the input buffer for the encapsulated key. * @param inOff the offset for the input buffer. * @param inLen the length of the encapsulated key. * @param keyLen the length of the session key. * @return the session key. */ public CipherParameters decrypt(byte[] in, int inOff, int inLen, int keyLen) throws IllegalArgumentException { if (!(key instanceof ECPrivateKeyParameters)) { throw new IllegalArgumentException("Private key required for encryption"); } BigInteger n = key.getParameters().getN(); BigInteger h = key.getParameters().getH(); // Decode the ephemeral public key byte[] C = new byte[inLen]; System.arraycopy(in, inOff, C, 0, inLen); ECPoint gTilde = key.getParameters().getCurve().decodePoint(C); // Compute the static-ephemeral key agreement ECPoint gHat; if ((CofactorMode) || (OldCofactorMode)) { gHat = gTilde.multiply(h); } else { gHat = gTilde; } BigInteger xHat; if (CofactorMode) { xHat = ((ECPrivateKeyParameters)key).getD().multiply(h.modInverse(n)).mod(n); } else { xHat = ((ECPrivateKeyParameters)key).getD(); } ECPoint hTilde = gHat.multiply(xHat); // Encode the shared secret value int PEHlen = (key.getParameters().getCurve().getFieldSize() + 7) / 8; byte[] PEH = BigIntegers.asUnsignedByteArray(PEHlen, hTilde.getX().toBigInteger()); // Initialise the KDF byte[] kdfInput; if (SingleHashMode) { kdfInput = new byte[C.length + PEH.length]; System.arraycopy(C, 0, kdfInput, 0, C.length); System.arraycopy(PEH, 0, kdfInput, C.length, PEH.length); } else { kdfInput = PEH; } kdf.init(new KDFParameters(kdfInput, null)); // Generate the secret key byte[] K = new byte[keyLen]; kdf.generateBytes(K, 0, K.length); return new KeyParameter(K); } /** * Decrypt an encapsulated session key. * * @param in the input buffer for the encapsulated key. * @param keyLen the length of the session key. * @return the session key. */ public CipherParameters decrypt(byte[] in, int keyLen) { return decrypt(in, 0, in.length, keyLen); } } bouncycastle-1.49.orig/src/org/bouncycastle/crypto/kems/package.html0000644000175000017500000000015212151566260025244 0ustar ebourgebourg The Key Encapsulation Mechanisms (KEMs) from ISO 18033-2. bouncycastle-1.49.orig/src/org/bouncycastle/crypto/DSA.java0000644000175000017500000000215710262753175023311 0ustar ebourgebourgpackage org.bouncycastle.crypto; import java.math.BigInteger; /** * interface for classes implementing algorithms modeled similar to the Digital Signature Alorithm. */ public interface DSA { /** * initialise the signer for signature generation or signature * verification. * * @param forSigning true if we are generating a signature, false * otherwise. * @param param key parameters for signature generation. */ public void init(boolean forSigning, CipherParameters param); /** * sign the passed in message (usually the output of a hash function). * * @param message the message to be signed. * @return two big integers representing the r and s values respectively. */ public BigInteger[] generateSignature(byte[] message); /** * verify the message message against the signature values r and s. * * @param message the message that was supposed to have been signed. * @param r the r signature value. * @param s the s signature value. */ public boolean verifySignature(byte[] message, BigInteger r, BigInteger s); } bouncycastle-1.49.orig/src/org/bouncycastle/crypto/agreement/0000755000175000017500000000000012152033551023766 5ustar ebourgebourgbouncycastle-1.49.orig/src/org/bouncycastle/crypto/agreement/ECDHCBasicAgreement.java0000644000175000017500000000411412057264613030242 0ustar ebourgebourgpackage org.bouncycastle.crypto.agreement; import java.math.BigInteger; import org.bouncycastle.crypto.BasicAgreement; import org.bouncycastle.crypto.CipherParameters; import org.bouncycastle.crypto.params.ECDomainParameters; import org.bouncycastle.crypto.params.ECPrivateKeyParameters; import org.bouncycastle.crypto.params.ECPublicKeyParameters; import org.bouncycastle.math.ec.ECPoint; /** * P1363 7.2.2 ECSVDP-DHC * * ECSVDP-DHC is Elliptic Curve Secret Value Derivation Primitive, * Diffie-Hellman version with cofactor multiplication. It is based on * the work of [DH76], [Mil86], [Kob87], [LMQ98] and [Kal98a]. This * primitive derives a shared secret value from one party's private key * and another party's public key, where both have the same set of EC * domain parameters. If two parties correctly execute this primitive, * they will produce the same output. This primitive can be invoked by a * scheme to derive a shared secret key; specifically, it may be used * with the schemes ECKAS-DH1 and DL/ECKAS-DH2. It does not assume the * validity of the input public key (see also Section 7.2.1). *

    * Note: As stated P1363 compatibility mode with ECDH can be preset, and * in this case the implementation doesn't have a ECDH compatibility mode * (if you want that just use ECDHBasicAgreement and note they both implement * BasicAgreement!). */ public class ECDHCBasicAgreement implements BasicAgreement { ECPrivateKeyParameters key; public void init( CipherParameters key) { this.key = (ECPrivateKeyParameters)key; } public int getFieldSize() { return (key.getParameters().getCurve().getFieldSize() + 7) / 8; } public BigInteger calculateAgreement( CipherParameters pubKey) { ECPublicKeyParameters pub = (ECPublicKeyParameters)pubKey; ECDomainParameters params = pub.getParameters(); ECPoint P = pub.getQ().multiply(params.getH().multiply(key.getD())); // if (p.isInfinity()) throw new RuntimeException("Invalid public key"); return P.getX().toBigInteger(); } } bouncycastle-1.49.orig/src/org/bouncycastle/crypto/agreement/DHAgreement.java0000644000175000017500000000617711160037015026764 0ustar ebourgebourgpackage org.bouncycastle.crypto.agreement; import java.math.BigInteger; import java.security.SecureRandom; import org.bouncycastle.crypto.AsymmetricCipherKeyPair; import org.bouncycastle.crypto.CipherParameters; import org.bouncycastle.crypto.generators.DHKeyPairGenerator; import org.bouncycastle.crypto.params.DHKeyGenerationParameters; import org.bouncycastle.crypto.params.DHParameters; import org.bouncycastle.crypto.params.DHPublicKeyParameters; import org.bouncycastle.crypto.params.DHPrivateKeyParameters; import org.bouncycastle.crypto.params.AsymmetricKeyParameter; import org.bouncycastle.crypto.params.ParametersWithRandom; /** * a Diffie-Hellman key exchange engine. *

    * note: This uses MTI/A0 key agreement in order to make the key agreement * secure against passive attacks. If you're doing Diffie-Hellman and both * parties have long term public keys you should look at using this. For * further information have a look at RFC 2631. *

    * It's possible to extend this to more than two parties as well, for the moment * that is left as an exercise for the reader. */ public class DHAgreement { private DHPrivateKeyParameters key; private DHParameters dhParams; private BigInteger privateValue; private SecureRandom random; public void init( CipherParameters param) { AsymmetricKeyParameter kParam; if (param instanceof ParametersWithRandom) { ParametersWithRandom rParam = (ParametersWithRandom)param; this.random = rParam.getRandom(); kParam = (AsymmetricKeyParameter)rParam.getParameters(); } else { this.random = new SecureRandom(); kParam = (AsymmetricKeyParameter)param; } if (!(kParam instanceof DHPrivateKeyParameters)) { throw new IllegalArgumentException("DHEngine expects DHPrivateKeyParameters"); } this.key = (DHPrivateKeyParameters)kParam; this.dhParams = key.getParameters(); } /** * calculate our initial message. */ public BigInteger calculateMessage() { DHKeyPairGenerator dhGen = new DHKeyPairGenerator(); dhGen.init(new DHKeyGenerationParameters(random, dhParams)); AsymmetricCipherKeyPair dhPair = dhGen.generateKeyPair(); this.privateValue = ((DHPrivateKeyParameters)dhPair.getPrivate()).getX(); return ((DHPublicKeyParameters)dhPair.getPublic()).getY(); } /** * given a message from a given party and the corresponding public key, * calculate the next message in the agreement sequence. In this case * this will represent the shared secret. */ public BigInteger calculateAgreement( DHPublicKeyParameters pub, BigInteger message) { if (!pub.getParameters().equals(dhParams)) { throw new IllegalArgumentException("Diffie-Hellman public key has wrong parameters."); } BigInteger p = dhParams.getP(); return message.modPow(key.getX(), p).multiply(pub.getY().modPow(privateValue, p)).mod(p); } } bouncycastle-1.49.orig/src/org/bouncycastle/crypto/agreement/DHStandardGroups.java0000644000175000017500000003516712146536233030031 0ustar ebourgebourgpackage org.bouncycastle.crypto.agreement; import java.math.BigInteger; import org.bouncycastle.crypto.params.DHParameters; import org.bouncycastle.util.encoders.Hex; /** * Standard Diffie-Hellman groups from various IETF specifications. */ public class DHStandardGroups { private static DHParameters fromPG(String hexP, String hexG) { BigInteger p = new BigInteger(1, Hex.decode(hexP)); BigInteger g = new BigInteger(1, Hex.decode(hexG)); return new DHParameters(p, g); } private static DHParameters fromPGQ(String hexP, String hexG, String hexQ) { BigInteger p = new BigInteger(1, Hex.decode(hexP)); BigInteger g = new BigInteger(1, Hex.decode(hexG)); BigInteger q = new BigInteger(1, Hex.decode(hexQ)); return new DHParameters(p, g, q); } /* * RFC 2409 */ private static final String rfc2409_768_p = "FFFFFFFFFFFFFFFFC90FDAA22168C234C4C6628B80DC1CD1" + "29024E088A67CC74020BBEA63B139B22514A08798E3404DD" + "EF9519B3CD3A431B302B0A6DF25F14374FE1356D6D51C245" + "E485B576625E7EC6F44C42E9A63A3620FFFFFFFFFFFFFFFF"; private static final String rfc2409_768_g = "02"; public static final DHParameters rfc2409_768 = fromPG(rfc2409_768_p, rfc2409_768_g); private static final String rfc2409_1024_p = "FFFFFFFFFFFFFFFFC90FDAA22168C234C4C6628B80DC1CD1" + "29024E088A67CC74020BBEA63B139B22514A08798E3404DD" + "EF9519B3CD3A431B302B0A6DF25F14374FE1356D6D51C245" + "E485B576625E7EC6F44C42E9A637ED6B0BFF5CB6F406B7ED" + "EE386BFB5A899FA5AE9F24117C4B1FE649286651ECE65381" + "FFFFFFFFFFFFFFFF"; private static final String rfc2409_1024_g = "02"; public static final DHParameters rfc2409_1024 = fromPG(rfc2409_1024_p, rfc2409_1024_g); /* * RFC 3526 */ private static final String rfc3526_1536_p = "FFFFFFFFFFFFFFFFC90FDAA22168C234C4C6628B80DC1CD1" + "29024E088A67CC74020BBEA63B139B22514A08798E3404DD" + "EF9519B3CD3A431B302B0A6DF25F14374FE1356D6D51C245" + "E485B576625E7EC6F44C42E9A637ED6B0BFF5CB6F406B7ED" + "EE386BFB5A899FA5AE9F24117C4B1FE649286651ECE45B3D" + "C2007CB8A163BF0598DA48361C55D39A69163FA8FD24CF5F" + "83655D23DCA3AD961C62F356208552BB9ED529077096966D" + "670C354E4ABC9804F1746C08CA237327FFFFFFFFFFFFFFFF"; private static final String rfc3526_1536_g = "02"; public static final DHParameters rfc3526_1536 = fromPG(rfc3526_1536_p, rfc3526_1536_g); private static final String rfc3526_2048_p = "FFFFFFFFFFFFFFFFC90FDAA22168C234C4C6628B80DC1CD1" + "29024E088A67CC74020BBEA63B139B22514A08798E3404DD" + "EF9519B3CD3A431B302B0A6DF25F14374FE1356D6D51C245" + "E485B576625E7EC6F44C42E9A637ED6B0BFF5CB6F406B7ED" + "EE386BFB5A899FA5AE9F24117C4B1FE649286651ECE45B3D" + "C2007CB8A163BF0598DA48361C55D39A69163FA8FD24CF5F" + "83655D23DCA3AD961C62F356208552BB9ED529077096966D" + "670C354E4ABC9804F1746C08CA18217C32905E462E36CE3B" + "E39E772C180E86039B2783A2EC07A28FB5C55DF06F4C52C9" + "DE2BCBF6955817183995497CEA956AE515D2261898FA0510" + "15728E5A8AACAA68FFFFFFFFFFFFFFFF"; private static final String rfc3526_2048_g = "02"; public static final DHParameters rfc3526_2048 = fromPG(rfc3526_2048_p, rfc3526_2048_g); private static final String rfc3526_3072_p = "FFFFFFFFFFFFFFFFC90FDAA22168C234C4C6628B80DC1CD1" + "29024E088A67CC74020BBEA63B139B22514A08798E3404DD" + "EF9519B3CD3A431B302B0A6DF25F14374FE1356D6D51C245" + "E485B576625E7EC6F44C42E9A637ED6B0BFF5CB6F406B7ED" + "EE386BFB5A899FA5AE9F24117C4B1FE649286651ECE45B3D" + "C2007CB8A163BF0598DA48361C55D39A69163FA8FD24CF5F" + "83655D23DCA3AD961C62F356208552BB9ED529077096966D" + "670C354E4ABC9804F1746C08CA18217C32905E462E36CE3B" + "E39E772C180E86039B2783A2EC07A28FB5C55DF06F4C52C9" + "DE2BCBF6955817183995497CEA956AE515D2261898FA0510" + "15728E5A8AAAC42DAD33170D04507A33A85521ABDF1CBA64" + "ECFB850458DBEF0A8AEA71575D060C7DB3970F85A6E1E4C7" + "ABF5AE8CDB0933D71E8C94E04A25619DCEE3D2261AD2EE6B" + "F12FFA06D98A0864D87602733EC86A64521F2B18177B200C" + "BBE117577A615D6C770988C0BAD946E208E24FA074E5AB31" + "43DB5BFCE0FD108E4B82D120A93AD2CAFFFFFFFFFFFFFFFF"; private static final String rfc3526_3072_g = "02"; public static final DHParameters rfc3526_3072 = fromPG(rfc3526_3072_p, rfc3526_3072_g); private static final String rfc3526_4096_p = "FFFFFFFFFFFFFFFFC90FDAA22168C234C4C6628B80DC1CD1" + "29024E088A67CC74020BBEA63B139B22514A08798E3404DD" + "EF9519B3CD3A431B302B0A6DF25F14374FE1356D6D51C245" + "E485B576625E7EC6F44C42E9A637ED6B0BFF5CB6F406B7ED" + "EE386BFB5A899FA5AE9F24117C4B1FE649286651ECE45B3D" + "C2007CB8A163BF0598DA48361C55D39A69163FA8FD24CF5F" + "83655D23DCA3AD961C62F356208552BB9ED529077096966D" + "670C354E4ABC9804F1746C08CA18217C32905E462E36CE3B" + "E39E772C180E86039B2783A2EC07A28FB5C55DF06F4C52C9" + "DE2BCBF6955817183995497CEA956AE515D2261898FA0510" + "15728E5A8AAAC42DAD33170D04507A33A85521ABDF1CBA64" + "ECFB850458DBEF0A8AEA71575D060C7DB3970F85A6E1E4C7" + "ABF5AE8CDB0933D71E8C94E04A25619DCEE3D2261AD2EE6B" + "F12FFA06D98A0864D87602733EC86A64521F2B18177B200C" + "BBE117577A615D6C770988C0BAD946E208E24FA074E5AB31" + "43DB5BFCE0FD108E4B82D120A92108011A723C12A787E6D7" + "88719A10BDBA5B2699C327186AF4E23C1A946834B6150BDA" + "2583E9CA2AD44CE8DBBBC2DB04DE8EF92E8EFC141FBECAA6" + "287C59474E6BC05D99B2964FA090C3A2233BA186515BE7ED" + "1F612970CEE2D7AFB81BDD762170481CD0069127D5B05AA9" + "93B4EA988D8FDDC186FFB7DC90A6C08F4DF435C934063199" + "FFFFFFFFFFFFFFFF"; private static final String rfc3526_4096_g = "02"; public static final DHParameters rfc3526_4096 = fromPG(rfc3526_4096_p, rfc3526_4096_g); private static final String rfc3526_6144_p = "FFFFFFFFFFFFFFFFC90FDAA22168C234C4C6628B80DC1CD129024E08" + "8A67CC74020BBEA63B139B22514A08798E3404DDEF9519B3CD3A431B" + "302B0A6DF25F14374FE1356D6D51C245E485B576625E7EC6F44C42E9" + "A637ED6B0BFF5CB6F406B7EDEE386BFB5A899FA5AE9F24117C4B1FE6" + "49286651ECE45B3DC2007CB8A163BF0598DA48361C55D39A69163FA8" + "FD24CF5F83655D23DCA3AD961C62F356208552BB9ED529077096966D" + "670C354E4ABC9804F1746C08CA18217C32905E462E36CE3BE39E772C" + "180E86039B2783A2EC07A28FB5C55DF06F4C52C9DE2BCBF695581718" + "3995497CEA956AE515D2261898FA051015728E5A8AAAC42DAD33170D" + "04507A33A85521ABDF1CBA64ECFB850458DBEF0A8AEA71575D060C7D" + "B3970F85A6E1E4C7ABF5AE8CDB0933D71E8C94E04A25619DCEE3D226" + "1AD2EE6BF12FFA06D98A0864D87602733EC86A64521F2B18177B200C" + "BBE117577A615D6C770988C0BAD946E208E24FA074E5AB3143DB5BFC" + "E0FD108E4B82D120A92108011A723C12A787E6D788719A10BDBA5B26" + "99C327186AF4E23C1A946834B6150BDA2583E9CA2AD44CE8DBBBC2DB" + "04DE8EF92E8EFC141FBECAA6287C59474E6BC05D99B2964FA090C3A2" + "233BA186515BE7ED1F612970CEE2D7AFB81BDD762170481CD0069127" + "D5B05AA993B4EA988D8FDDC186FFB7DC90A6C08F4DF435C934028492" + "36C3FAB4D27C7026C1D4DCB2602646DEC9751E763DBA37BDF8FF9406" + "AD9E530EE5DB382F413001AEB06A53ED9027D831179727B0865A8918" + "DA3EDBEBCF9B14ED44CE6CBACED4BB1BDB7F1447E6CC254B33205151" + "2BD7AF426FB8F401378CD2BF5983CA01C64B92ECF032EA15D1721D03" + "F482D7CE6E74FEF6D55E702F46980C82B5A84031900B1C9E59E7C97F" + "BEC7E8F323A97A7E36CC88BE0F1D45B7FF585AC54BD407B22B4154AA" + "CC8F6D7EBF48E1D814CC5ED20F8037E0A79715EEF29BE32806A1D58B" + "B7C5DA76F550AA3D8A1FBFF0EB19CCB1A313D55CDA56C9EC2EF29632" + "387FE8D76E3C0468043E8F663F4860EE12BF2D5B0B7474D6E694F91E" + "6DCC4024FFFFFFFFFFFFFFFF"; private static final String rfc3526_6144_g = "02"; public static final DHParameters rfc3526_6144 = fromPG(rfc3526_6144_p, rfc3526_6144_g); private static final String rfc3526_8192_p = "FFFFFFFFFFFFFFFFC90FDAA22168C234C4C6628B80DC1CD1" + "29024E088A67CC74020BBEA63B139B22514A08798E3404DD" + "EF9519B3CD3A431B302B0A6DF25F14374FE1356D6D51C245" + "E485B576625E7EC6F44C42E9A637ED6B0BFF5CB6F406B7ED" + "EE386BFB5A899FA5AE9F24117C4B1FE649286651ECE45B3D" + "C2007CB8A163BF0598DA48361C55D39A69163FA8FD24CF5F" + "83655D23DCA3AD961C62F356208552BB9ED529077096966D" + "670C354E4ABC9804F1746C08CA18217C32905E462E36CE3B" + "E39E772C180E86039B2783A2EC07A28FB5C55DF06F4C52C9" + "DE2BCBF6955817183995497CEA956AE515D2261898FA0510" + "15728E5A8AAAC42DAD33170D04507A33A85521ABDF1CBA64" + "ECFB850458DBEF0A8AEA71575D060C7DB3970F85A6E1E4C7" + "ABF5AE8CDB0933D71E8C94E04A25619DCEE3D2261AD2EE6B" + "F12FFA06D98A0864D87602733EC86A64521F2B18177B200C" + "BBE117577A615D6C770988C0BAD946E208E24FA074E5AB31" + "43DB5BFCE0FD108E4B82D120A92108011A723C12A787E6D7" + "88719A10BDBA5B2699C327186AF4E23C1A946834B6150BDA" + "2583E9CA2AD44CE8DBBBC2DB04DE8EF92E8EFC141FBECAA6" + "287C59474E6BC05D99B2964FA090C3A2233BA186515BE7ED" + "1F612970CEE2D7AFB81BDD762170481CD0069127D5B05AA9" + "93B4EA988D8FDDC186FFB7DC90A6C08F4DF435C934028492" + "36C3FAB4D27C7026C1D4DCB2602646DEC9751E763DBA37BD" + "F8FF9406AD9E530EE5DB382F413001AEB06A53ED9027D831" + "179727B0865A8918DA3EDBEBCF9B14ED44CE6CBACED4BB1B" + "DB7F1447E6CC254B332051512BD7AF426FB8F401378CD2BF" + "5983CA01C64B92ECF032EA15D1721D03F482D7CE6E74FEF6" + "D55E702F46980C82B5A84031900B1C9E59E7C97FBEC7E8F3" + "23A97A7E36CC88BE0F1D45B7FF585AC54BD407B22B4154AA" + "CC8F6D7EBF48E1D814CC5ED20F8037E0A79715EEF29BE328" + "06A1D58BB7C5DA76F550AA3D8A1FBFF0EB19CCB1A313D55C" + "DA56C9EC2EF29632387FE8D76E3C0468043E8F663F4860EE" + "12BF2D5B0B7474D6E694F91E6DBE115974A3926F12FEE5E4" + "38777CB6A932DF8CD8BEC4D073B931BA3BC832B68D9DD300" + "741FA7BF8AFC47ED2576F6936BA424663AAB639C5AE4F568" + "3423B4742BF1C978238F16CBE39D652DE3FDB8BEFC848AD9" + "22222E04A4037C0713EB57A81A23F0C73473FC646CEA306B" + "4BCBC8862F8385DDFA9D4B7FA2C087E879683303ED5BDD3A" + "062B3CF5B3A278A66D2A13F83F44F82DDF310EE074AB6A36" + "4597E899A0255DC164F31CC50846851DF9AB48195DED7EA1" + "B1D510BD7EE74D73FAF36BC31ECFA268359046F4EB879F92" + "4009438B481C6CD7889A002ED5EE382BC9190DA6FC026E47" + "9558E4475677E9AA9E3050E2765694DFC81F56E880B96E71" + "60C980DD98EDD3DFFFFFFFFFFFFFFFFF"; private static final String rfc3526_8192_g = "02"; public static final DHParameters rfc3526_8192 = fromPG(rfc3526_8192_p, rfc3526_8192_g); /* * RFC 4306 */ public static final DHParameters rfc4306_768 = rfc2409_768; public static final DHParameters rfc4306_1024 = rfc2409_1024; /* * RFC 5114 */ private static final String rfc5114_1024_160_p = "B10B8F96A080E01DDE92DE5EAE5D54EC52C99FBCFB06A3C6" + "9A6A9DCA52D23B616073E28675A23D189838EF1E2EE652C0" + "13ECB4AEA906112324975C3CD49B83BFACCBDD7D90C4BD70" + "98488E9C219A73724EFFD6FAE5644738FAA31A4FF55BCCC0" + "A151AF5F0DC8B4BD45BF37DF365C1A65E68CFDA76D4DA708" + "DF1FB2BC2E4A4371"; private static final String rfc5114_1024_160_g = "A4D1CBD5C3FD34126765A442EFB99905F8104DD258AC507F" + "D6406CFF14266D31266FEA1E5C41564B777E690F5504F213" + "160217B4B01B886A5E91547F9E2749F4D7FBD7D3B9A92EE1" + "909D0D2263F80A76A6A24C087A091F531DBF0A0169B6A28A" + "D662A4D18E73AFA32D779D5918D08BC8858F4DCEF97C2A24" + "855E6EEB22B3B2E5"; private static final String rfc5114_1024_160_q = "F518AA8781A8DF278ABA4E7D64B7CB9D49462353"; public static final DHParameters rfc5114_1024_160 = fromPGQ(rfc5114_1024_160_p, rfc5114_1024_160_g, rfc5114_1024_160_q); private static final String rfc5114_2048_224_p = "AD107E1E9123A9D0D660FAA79559C51FA20D64E5683B9FD1" + "B54B1597B61D0A75E6FA141DF95A56DBAF9A3C407BA1DF15" + "EB3D688A309C180E1DE6B85A1274A0A66D3F8152AD6AC212" + "9037C9EDEFDA4DF8D91E8FEF55B7394B7AD5B7D0B6C12207" + "C9F98D11ED34DBF6C6BA0B2C8BBC27BE6A00E0A0B9C49708" + "B3BF8A317091883681286130BC8985DB1602E714415D9330" + "278273C7DE31EFDC7310F7121FD5A07415987D9ADC0A486D" + "CDF93ACC44328387315D75E198C641A480CD86A1B9E587E8" + "BE60E69CC928B2B9C52172E413042E9B23F10B0E16E79763" + "C9B53DCF4BA80A29E3FB73C16B8E75B97EF363E2FFA31F71" + "CF9DE5384E71B81C0AC4DFFE0C10E64F"; private static final String rfc5114_2048_224_g = "AC4032EF4F2D9AE39DF30B5C8FFDAC506CDEBE7B89998CAF" + "74866A08CFE4FFE3A6824A4E10B9A6F0DD921F01A70C4AFA" + "AB739D7700C29F52C57DB17C620A8652BE5E9001A8D66AD7" + "C17669101999024AF4D027275AC1348BB8A762D0521BC98A" + "E247150422EA1ED409939D54DA7460CDB5F6C6B250717CBE" + "F180EB34118E98D119529A45D6F834566E3025E316A330EF" + "BB77A86F0C1AB15B051AE3D428C8F8ACB70A8137150B8EEB" + "10E183EDD19963DDD9E263E4770589EF6AA21E7F5F2FF381" + "B539CCE3409D13CD566AFBB48D6C019181E1BCFE94B30269" + "EDFE72FE9B6AA4BD7B5A0F1C71CFFF4C19C418E1F6EC0179" + "81BC087F2A7065B384B890D3191F2BFA"; private static final String rfc5114_2048_224_q = "801C0D34C58D93FE997177101F80535A4738CEBCBF389A99B36371EB"; public static final DHParameters rfc5114_2048_224 = fromPGQ(rfc5114_2048_224_p, rfc5114_2048_224_g, rfc5114_2048_224_q); private static final String rfc5114_2048_256_p = "87A8E61DB4B6663CFFBBD19C651959998CEEF608660DD0F2" + "5D2CEED4435E3B00E00DF8F1D61957D4FAF7DF4561B2AA30" + "16C3D91134096FAA3BF4296D830E9A7C209E0C6497517ABD" + "5A8A9D306BCF67ED91F9E6725B4758C022E0B1EF4275BF7B" + "6C5BFC11D45F9088B941F54EB1E59BB8BC39A0BF12307F5C" + "4FDB70C581B23F76B63ACAE1CAA6B7902D52526735488A0E" + "F13C6D9A51BFA4AB3AD8347796524D8EF6A167B5A41825D9" + "67E144E5140564251CCACB83E6B486F6B3CA3F7971506026" + "C0B857F689962856DED4010ABD0BE621C3A3960A54E710C3" + "75F26375D7014103A4B54330C198AF126116D2276E11715F" + "693877FAD7EF09CADB094AE91E1A1597"; private static final String rfc5114_2048_256_g = "3FB32C9B73134D0B2E77506660EDBD484CA7B18F21EF2054" + "07F4793A1A0BA12510DBC15077BE463FFF4FED4AAC0BB555" + "BE3A6C1B0C6B47B1BC3773BF7E8C6F62901228F8C28CBB18" + "A55AE31341000A650196F931C77A57F2DDF463E5E9EC144B" + "777DE62AAAB8A8628AC376D282D6ED3864E67982428EBC83" + "1D14348F6F2F9193B5045AF2767164E1DFC967C1FB3F2E55" + "A4BD1BFFE83B9C80D052B985D182EA0ADB2A3B7313D3FE14" + "C8484B1E052588B9B7D2BBD2DF016199ECD06E1557CD0915" + "B3353BBB64E0EC377FD028370DF92B52C7891428CDC67EB6" + "184B523D1DB246C32F63078490F00EF8D647D148D4795451" + "5E2327CFEF98C582664B4C0F6CC41659"; private static final String rfc5114_2048_256_q = "8CF83642A709A097B447997640129DA299B1A47D1EB3750B" + "A308B0FE64F5FBD3"; public static final DHParameters rfc5114_2048_256 = fromPGQ(rfc5114_2048_256_p, rfc5114_2048_256_g, rfc5114_2048_256_q); /* * RFC 5996 */ public static final DHParameters rfc5996_768 = rfc4306_768; public static final DHParameters rfc5996_1024 = rfc4306_1024; } bouncycastle-1.49.orig/src/org/bouncycastle/crypto/agreement/ECDHBasicAgreement.java0000644000175000017500000000320112057264613030133 0ustar ebourgebourgpackage org.bouncycastle.crypto.agreement; import java.math.BigInteger; import org.bouncycastle.crypto.BasicAgreement; import org.bouncycastle.crypto.CipherParameters; import org.bouncycastle.crypto.params.ECPrivateKeyParameters; import org.bouncycastle.crypto.params.ECPublicKeyParameters; import org.bouncycastle.math.ec.ECPoint; /** * P1363 7.2.1 ECSVDP-DH * * ECSVDP-DH is Elliptic Curve Secret Value Derivation Primitive, * Diffie-Hellman version. It is based on the work of [DH76], [Mil86], * and [Kob87]. This primitive derives a shared secret value from one * party's private key and another party's public key, where both have * the same set of EC domain parameters. If two parties correctly * execute this primitive, they will produce the same output. This * primitive can be invoked by a scheme to derive a shared secret key; * specifically, it may be used with the schemes ECKAS-DH1 and * DL/ECKAS-DH2. It assumes that the input keys are valid (see also * Section 7.2.2). */ public class ECDHBasicAgreement implements BasicAgreement { private ECPrivateKeyParameters key; public void init( CipherParameters key) { this.key = (ECPrivateKeyParameters)key; } public int getFieldSize() { return (key.getParameters().getCurve().getFieldSize() + 7) / 8; } public BigInteger calculateAgreement( CipherParameters pubKey) { ECPublicKeyParameters pub = (ECPublicKeyParameters)pubKey; ECPoint P = pub.getQ().multiply(key.getD()); // if (p.isInfinity()) throw new RuntimeException("d*Q == infinity"); return P.getX().toBigInteger(); } } bouncycastle-1.49.orig/src/org/bouncycastle/crypto/agreement/jpake/0000755000175000017500000000000012152033551025060 5ustar ebourgebourgbouncycastle-1.49.orig/src/org/bouncycastle/crypto/agreement/jpake/JPAKEPrimeOrderGroups.java0000644000175000017500000001353012103354470031752 0ustar ebourgebourgpackage org.bouncycastle.crypto.agreement.jpake; import java.math.BigInteger; /** * Standard pre-computed prime order groups for use by J-PAKE. * (J-PAKE can use pre-computed prime order groups, same as DSA and Diffie-Hellman.) *

    *

    * This class contains some convenient constants for use as input for * constructing {@link JPAKEParticipant}s. *

    *

    * The prime order groups below are taken from Sun's JDK JavaDoc (docs/guide/security/CryptoSpec.html#AppB), * and from the prime order groups * published by NIST. */ public class JPAKEPrimeOrderGroups { /** * From Sun's JDK JavaDoc (docs/guide/security/CryptoSpec.html#AppB) * 1024-bit p, 160-bit q and 1024-bit g for 80-bit security. */ public static final JPAKEPrimeOrderGroup SUN_JCE_1024 = new JPAKEPrimeOrderGroup( // p new BigInteger( "fd7f53811d75122952df4a9c2eece4e7f611b7523cef4400c31e3f80b6512669" + "455d402251fb593d8d58fabfc5f5ba30f6cb9b556cd7813b801d346ff26660b7" + "6b9950a5a49f9fe8047b1022c24fbba9d7feb7c61bf83b57e7c6a8a6150f04fb" + "83f6d3c51ec3023554135a169132f675f3ae2b61d72aeff22203199dd14801c7", 16), // q new BigInteger( "9760508f15230bccb292b982a2eb840bf0581cf5", 16), // g new BigInteger( "f7e1a085d69b3ddecbbcab5c36b857b97994afbbfa3aea82f9574c0b3d078267" + "5159578ebad4594fe67107108180b449167123e84c281613b7cf09328cc8a6e1" + "3c167a8b547c8d28e0a3ae1e2bb3a675916ea37f0bfa213562f1fb627a01243b" + "cca4f1bea8519089a883dfe15ae59f06928b665e807b552564014c3bfecf492a", 16), true ); /** * From NIST. * 2048-bit p, 224-bit q and 2048-bit g for 112-bit security. */ public static final JPAKEPrimeOrderGroup NIST_2048 = new JPAKEPrimeOrderGroup( // p new BigInteger( "C196BA05AC29E1F9C3C72D56DFFC6154A033F1477AC88EC37F09BE6C5BB95F51" + "C296DD20D1A28A067CCC4D4316A4BD1DCA55ED1066D438C35AEBAABF57E7DAE4" + "28782A95ECA1C143DB701FD48533A3C18F0FE23557EA7AE619ECACC7E0B51652" + "A8776D02A425567DED36EABD90CA33A1E8D988F0BBB92D02D1D20290113BB562" + "CE1FC856EEB7CDD92D33EEA6F410859B179E7E789A8F75F645FAE2E136D252BF" + "FAFF89528945C1ABE705A38DBC2D364AADE99BE0D0AAD82E5320121496DC65B3" + "930E38047294FF877831A16D5228418DE8AB275D7D75651CEFED65F78AFC3EA7" + "FE4D79B35F62A0402A1117599ADAC7B269A59F353CF450E6982D3B1702D9CA83", 16), // q new BigInteger( "90EAF4D1AF0708B1B612FF35E0A2997EB9E9D263C9CE659528945C0D", 16), // g new BigInteger( "A59A749A11242C58C894E9E5A91804E8FA0AC64B56288F8D47D51B1EDC4D6544" + "4FECA0111D78F35FC9FDD4CB1F1B79A3BA9CBEE83A3F811012503C8117F98E50" + "48B089E387AF6949BF8784EBD9EF45876F2E6A5A495BE64B6E770409494B7FEE" + "1DBB1E4B2BC2A53D4F893D418B7159592E4FFFDF6969E91D770DAEBD0B5CB14C" + "00AD68EC7DC1E5745EA55C706C4A1C5C88964E34D09DEB753AD418C1AD0F4FDF" + "D049A955E5D78491C0B7A2F1575A008CCD727AB376DB6E695515B05BD412F5B8" + "C2F4C77EE10DA48ABD53F5DD498927EE7B692BBBCDA2FB23A516C5B4533D7398" + "0B2A3B60E384ED200AE21B40D273651AD6060C13D97FD69AA13C5611A51B9085", 16), true ); /** * From NIST. * 3072-bit p, 256-bit q and 3072-bit g for 128-bit security. */ public static final JPAKEPrimeOrderGroup NIST_3072 = new JPAKEPrimeOrderGroup( // p new BigInteger( "90066455B5CFC38F9CAA4A48B4281F292C260FEEF01FD61037E56258A7795A1C" + "7AD46076982CE6BB956936C6AB4DCFE05E6784586940CA544B9B2140E1EB523F" + "009D20A7E7880E4E5BFA690F1B9004A27811CD9904AF70420EEFD6EA11EF7DA1" + "29F58835FF56B89FAA637BC9AC2EFAAB903402229F491D8D3485261CD068699B" + "6BA58A1DDBBEF6DB51E8FE34E8A78E542D7BA351C21EA8D8F1D29F5D5D159394" + "87E27F4416B0CA632C59EFD1B1EB66511A5A0FBF615B766C5862D0BD8A3FE7A0" + "E0DA0FB2FE1FCB19E8F9996A8EA0FCCDE538175238FC8B0EE6F29AF7F642773E" + "BE8CD5402415A01451A840476B2FCEB0E388D30D4B376C37FE401C2A2C2F941D" + "AD179C540C1C8CE030D460C4D983BE9AB0B20F69144C1AE13F9383EA1C08504F" + "B0BF321503EFE43488310DD8DC77EC5B8349B8BFE97C2C560EA878DE87C11E3D" + "597F1FEA742D73EEC7F37BE43949EF1A0D15C3F3E3FC0A8335617055AC91328E" + "C22B50FC15B941D3D1624CD88BC25F3E941FDDC6200689581BFEC416B4B2CB73", 16), // q new BigInteger( "CFA0478A54717B08CE64805B76E5B14249A77A4838469DF7F7DC987EFCCFB11D", 16), // g new BigInteger( "5E5CBA992E0A680D885EB903AEA78E4A45A469103D448EDE3B7ACCC54D521E37" + "F84A4BDD5B06B0970CC2D2BBB715F7B82846F9A0C393914C792E6A923E2117AB" + "805276A975AADB5261D91673EA9AAFFEECBFA6183DFCB5D3B7332AA19275AFA1" + "F8EC0B60FB6F66CC23AE4870791D5982AAD1AA9485FD8F4A60126FEB2CF05DB8" + "A7F0F09B3397F3937F2E90B9E5B9C9B6EFEF642BC48351C46FB171B9BFA9EF17" + "A961CE96C7E7A7CC3D3D03DFAD1078BA21DA425198F07D2481622BCE45969D9C" + "4D6063D72AB7A0F08B2F49A7CC6AF335E08C4720E31476B67299E231F8BD90B3" + "9AC3AE3BE0C6B6CACEF8289A2E2873D58E51E029CAFBD55E6841489AB66B5B4B" + "9BA6E2F784660896AFF387D92844CCB8B69475496DE19DA2E58259B090489AC8" + "E62363CDF82CFD8EF2A427ABCD65750B506F56DDE3B988567A88126B914D7828" + "E2B63A6D7ED0747EC59E0E0A23CE7D8A74C1D2C2A7AFB6A29799620F00E11C33" + "787F7DED3B30E1A22D09F1FBDA1ABBBFBF25CAE05A13F812E34563F99410E73B", 16), true ); } bouncycastle-1.49.orig/src/org/bouncycastle/crypto/agreement/jpake/JPAKEUtil.java0000644000175000017500000003632612104603564027431 0ustar ebourgebourgpackage org.bouncycastle.crypto.agreement.jpake; import java.math.BigInteger; import java.security.SecureRandom; import org.bouncycastle.crypto.CryptoException; import org.bouncycastle.crypto.Digest; import org.bouncycastle.crypto.Mac; import org.bouncycastle.crypto.macs.HMac; import org.bouncycastle.crypto.params.KeyParameter; import org.bouncycastle.util.Arrays; import org.bouncycastle.util.BigIntegers; import org.bouncycastle.util.Strings; /** * Primitives needed for a J-PAKE exchange. *

    *

    * The recommended way to perform a J-PAKE exchange is by using * two {@link JPAKEParticipant}s. Internally, those participants * call these primitive operations in {@link JPAKEUtil}. *

    *

    * The primitives, however, can be used without a {@link JPAKEParticipant} * if needed. */ public class JPAKEUtil { static final BigInteger ZERO = BigInteger.valueOf(0); static final BigInteger ONE = BigInteger.valueOf(1); /** * Return a value that can be used as x1 or x3 during round 1. *

    *

    * The returned value is a random value in the range [0, q-1]. */ public static BigInteger generateX1( BigInteger q, SecureRandom random) { BigInteger min = ZERO; BigInteger max = q.subtract(ONE); return BigIntegers.createRandomInRange(min, max, random); } /** * Return a value that can be used as x2 or x4 during round 1. *

    *

    * The returned value is a random value in the range [1, q-1]. */ public static BigInteger generateX2( BigInteger q, SecureRandom random) { BigInteger min = ONE; BigInteger max = q.subtract(ONE); return BigIntegers.createRandomInRange(min, max, random); } /** * Converts the given password to a {@link BigInteger} * for use in arithmetic calculations. */ public static BigInteger calculateS(char[] password) { return new BigInteger(Strings.toUTF8ByteArray(password)); } /** * Calculate g^x mod p as done in round 1. */ public static BigInteger calculateGx( BigInteger p, BigInteger g, BigInteger x) { return g.modPow(x, p); } /** * Calculate ga as done in round 2. */ public static BigInteger calculateGA( BigInteger p, BigInteger gx1, BigInteger gx3, BigInteger gx4) { // ga = g^(x1+x3+x4) = g^x1 * g^x3 * g^x4 return gx1.multiply(gx3).multiply(gx4).mod(p); } /** * Calculate x2 * s as done in round 2. */ public static BigInteger calculateX2s( BigInteger q, BigInteger x2, BigInteger s) { return x2.multiply(s).mod(q); } /** * Calculate A as done in round 2. */ public static BigInteger calculateA( BigInteger p, BigInteger q, BigInteger gA, BigInteger x2s) { // A = ga^(x*s) return gA.modPow(x2s, p); } /** * Calculate a zero knowledge proof of x using Schnorr's signature. * The returned array has two elements {g^v, r = v-x*h} for x. */ public static BigInteger[] calculateZeroKnowledgeProof( BigInteger p, BigInteger q, BigInteger g, BigInteger gx, BigInteger x, String participantId, Digest digest, SecureRandom random) { BigInteger[] zeroKnowledgeProof = new BigInteger[2]; /* Generate a random v, and compute g^v */ BigInteger vMin = ZERO; BigInteger vMax = q.subtract(ONE); BigInteger v = BigIntegers.createRandomInRange(vMin, vMax, random); BigInteger gv = g.modPow(v, p); BigInteger h = calculateHashForZeroKnowledgeProof(g, gv, gx, participantId, digest); // h zeroKnowledgeProof[0] = gv; zeroKnowledgeProof[1] = v.subtract(x.multiply(h)).mod(q); // r = v-x*h return zeroKnowledgeProof; } private static BigInteger calculateHashForZeroKnowledgeProof( BigInteger g, BigInteger gr, BigInteger gx, String participantId, Digest digest) { digest.reset(); updateDigestIncludingSize(digest, g); updateDigestIncludingSize(digest, gr); updateDigestIncludingSize(digest, gx); updateDigestIncludingSize(digest, participantId); byte[] output = new byte[digest.getDigestSize()]; digest.doFinal(output, 0); return new BigInteger(output); } /** * Validates that g^x4 is not 1. * * @throws CryptoException if g^x4 is 1 */ public static void validateGx4(BigInteger gx4) throws CryptoException { if (gx4.equals(ONE)) { throw new CryptoException("g^x validation failed. g^x should not be 1."); } } /** * Validates that ga is not 1. *

    *

    * As described by Feng Hao... *

    *

    * Alice could simply check ga != 1 to ensure it is a generator. * In fact, as we will explain in Section 3, (x1 + x3 + x4 ) is random over Zq even in the face of active attacks. * Hence, the probability for ga = 1 is extremely small - on the order of 2^160 for 160-bit q. *
    * * @throws CryptoException if ga is 1 */ public static void validateGa(BigInteger ga) throws CryptoException { if (ga.equals(ONE)) { throw new CryptoException("ga is equal to 1. It should not be. The chances of this happening are on the order of 2^160 for a 160-bit q. Try again."); } } /** * Validates the zero knowledge proof (generated by * {@link #calculateZeroKnowledgeProof(BigInteger, BigInteger, BigInteger, BigInteger, BigInteger, String, Digest, SecureRandom)}) * is correct. * * @throws CryptoException if the zero knowledge proof is not correct */ public static void validateZeroKnowledgeProof( BigInteger p, BigInteger q, BigInteger g, BigInteger gx, BigInteger[] zeroKnowledgeProof, String participantId, Digest digest) throws CryptoException { /* sig={g^v,r} */ BigInteger gv = zeroKnowledgeProof[0]; BigInteger r = zeroKnowledgeProof[1]; BigInteger h = calculateHashForZeroKnowledgeProof(g, gv, gx, participantId, digest); if (!(gx.compareTo(ZERO) == 1 && // g^x > 0 gx.compareTo(p) == -1 && // g^x < p gx.modPow(q, p).compareTo(ONE) == 0 && // g^x^q mod q = 1 /* * Below, I took an straightforward way to compute g^r * g^x^h, * which needs 2 exp. Using a simultaneous computation technique * would only need 1 exp. */ g.modPow(r, p).multiply(gx.modPow(h, p)).mod(p).compareTo(gv) == 0)) // g^v=g^r * g^x^h { throw new CryptoException("Zero-knowledge proof validation failed"); } } /** * Calculates the keying material, which can be done after round 2 has completed. * A session key must be derived from this key material using a secure key derivation function (KDF). * The KDF used to derive the key is handled externally (i.e. not by {@link JPAKEParticipant}). *

    *

    *

         * KeyingMaterial = (B/g^{x2*x4*s})^x2
         * 
    */ public static BigInteger calculateKeyingMaterial( BigInteger p, BigInteger q, BigInteger gx4, BigInteger x2, BigInteger s, BigInteger B) { return gx4.modPow(x2.multiply(s).negate().mod(q), p).multiply(B).modPow(x2, p); } /** * Validates that the given participant ids are not equal. * (For the J-PAKE exchange, each participant must use a unique id.) * * @throws CryptoException if the participantId strings are equal. */ public static void validateParticipantIdsDiffer(String participantId1, String participantId2) throws CryptoException { if (participantId1.equals(participantId2)) { throw new CryptoException( "Both participants are using the same participantId (" + participantId1 + "). This is not allowed. " + "Each participant must use a unique participantId."); } } /** * Validates that the given participant ids are equal. * This is used to ensure that the payloads received from * each round all come from the same participant. * * @throws CryptoException if the participantId strings are equal. */ public static void validateParticipantIdsEqual(String expectedParticipantId, String actualParticipantId) throws CryptoException { if (!expectedParticipantId.equals(actualParticipantId)) { throw new CryptoException( "Received payload from incorrect partner (" + actualParticipantId + "). Expected to receive payload from " + expectedParticipantId + "."); } } /** * Validates that the given object is not null. * * @param object object in question * @param description name of the object (to be used in exception message) * @throws NullPointerException if the object is null. */ public static void validateNotNull(Object object, String description) { if (object == null) { throw new NullPointerException(description + " must not be null"); } } /** * Calculates the MacTag (to be used for key confirmation), as defined by * NIST SP 800-56A Revision 1, * Section 8.2 Unilateral Key Confirmation for Key Agreement Schemes. *

    *

    *

         * MacTag = HMAC(MacKey, MacLen, MacData)
         *
         * MacKey = H(K || "JPAKE_KC")
         *
         * MacData = "KC_1_U" || participantId || partnerParticipantId || gx1 || gx2 || gx3 || gx4
         *
         * Note that both participants use "KC_1_U" because the sender of the round 3 message
         * is always the initiator for key confirmation.
         *
         * HMAC = {@link HMac} used with the given {@link Digest}
         * H = The given {@link Digest}
         * MacLen = length of MacTag
         * 
    *

    */ public static BigInteger calculateMacTag( String participantId, String partnerParticipantId, BigInteger gx1, BigInteger gx2, BigInteger gx3, BigInteger gx4, BigInteger keyingMaterial, Digest digest) { byte[] macKey = calculateMacKey( keyingMaterial, digest); HMac mac = new HMac(digest); byte[] macOutput = new byte[mac.getMacSize()]; mac.init(new KeyParameter(macKey)); /* * MacData = "KC_1_U" || participantId_Alice || participantId_Bob || gx1 || gx2 || gx3 || gx4. */ updateMac(mac, "KC_1_U"); updateMac(mac, participantId); updateMac(mac, partnerParticipantId); updateMac(mac, gx1); updateMac(mac, gx2); updateMac(mac, gx3); updateMac(mac, gx4); mac.doFinal(macOutput, 0); Arrays.fill(macKey, (byte)0); return new BigInteger(macOutput); } /** * Calculates the MacKey (i.e. the key to use when calculating the MagTag for key confirmation). *

    *

    *

         * MacKey = H(K || "JPAKE_KC")
         * 
    */ private static byte[] calculateMacKey(BigInteger keyingMaterial, Digest digest) { digest.reset(); updateDigest(digest, keyingMaterial); /* * This constant is used to ensure that the macKey is NOT the same as the derived key. */ updateDigest(digest, "JPAKE_KC"); byte[] output = new byte[digest.getDigestSize()]; digest.doFinal(output, 0); return output; } /** * Validates the MacTag received from the partner participant. *

    * * @param partnerMacTag the MacTag received from the partner. * @throws CryptoException if the participantId strings are equal. */ public static void validateMacTag( String participantId, String partnerParticipantId, BigInteger gx1, BigInteger gx2, BigInteger gx3, BigInteger gx4, BigInteger keyingMaterial, Digest digest, BigInteger partnerMacTag) throws CryptoException { /* * Calculate the expected MacTag using the parameters as the partner * would have used when the partner called calculateMacTag. * * i.e. basically all the parameters are reversed. * participantId <-> partnerParticipantId * x1 <-> x3 * x2 <-> x4 */ BigInteger expectedMacTag = calculateMacTag( partnerParticipantId, participantId, gx3, gx4, gx1, gx2, keyingMaterial, digest); if (!expectedMacTag.equals(partnerMacTag)) { throw new CryptoException( "Partner MacTag validation failed. " + "Therefore, the password, MAC, or digest algorithm of each participant does not match."); } } private static void updateDigest(Digest digest, BigInteger bigInteger) { byte[] byteArray = BigIntegers.asUnsignedByteArray(bigInteger); digest.update(byteArray, 0, byteArray.length); Arrays.fill(byteArray, (byte)0); } private static void updateDigestIncludingSize(Digest digest, BigInteger bigInteger) { byte[] byteArray = BigIntegers.asUnsignedByteArray(bigInteger); digest.update(intToByteArray(byteArray.length), 0, 4); digest.update(byteArray, 0, byteArray.length); Arrays.fill(byteArray, (byte)0); } private static void updateDigest(Digest digest, String string) { byte[] byteArray = Strings.toUTF8ByteArray(string); digest.update(byteArray, 0, byteArray.length); Arrays.fill(byteArray, (byte)0); } private static void updateDigestIncludingSize(Digest digest, String string) { byte[] byteArray = Strings.toUTF8ByteArray(string); digest.update(intToByteArray(byteArray.length), 0, 4); digest.update(byteArray, 0, byteArray.length); Arrays.fill(byteArray, (byte)0); } private static void updateMac(Mac mac, BigInteger bigInteger) { byte[] byteArray = BigIntegers.asUnsignedByteArray(bigInteger); mac.update(byteArray, 0, byteArray.length); Arrays.fill(byteArray, (byte)0); } private static void updateMac(Mac mac, String string) { byte[] byteArray = Strings.toUTF8ByteArray(string); mac.update(byteArray, 0, byteArray.length); Arrays.fill(byteArray, (byte)0); } private static byte[] intToByteArray(int value) { return new byte[]{ (byte)(value >>> 24), (byte)(value >>> 16), (byte)(value >>> 8), (byte)value }; } } bouncycastle-1.49.orig/src/org/bouncycastle/crypto/agreement/jpake/JPAKERound1Payload.java0000644000175000017500000000522112152020122031146 0ustar ebourgebourgpackage org.bouncycastle.crypto.agreement.jpake; import java.math.BigInteger; import org.bouncycastle.util.Arrays; /** * The payload sent/received during the first round of a J-PAKE exchange. *

    *

    * Each {@link JPAKEParticipant} creates and sends an instance * of this payload to the other {@link JPAKEParticipant}. * The payload to send should be created via * {@link JPAKEParticipant#createRound1PayloadToSend()}. *

    *

    * Each {@link JPAKEParticipant} must also validate the payload * received from the other {@link JPAKEParticipant}. * The received payload should be validated via * {@link JPAKEParticipant#validateRound1PayloadReceived(JPAKERound1Payload)}. *

    */ public class JPAKERound1Payload { /** * The id of the {@link JPAKEParticipant} who created/sent this payload. */ private final String participantId; /** * The value of g^x1 */ private final BigInteger gx1; /** * The value of g^x2 */ private final BigInteger gx2; /** * The zero knowledge proof for x1. *

    * This is a two element array, containing {g^v, r} for x1. */ private final BigInteger[] knowledgeProofForX1; /** * The zero knowledge proof for x2. *

    * This is a two element array, containing {g^v, r} for x2. */ private final BigInteger[] knowledgeProofForX2; public JPAKERound1Payload( String participantId, BigInteger gx1, BigInteger gx2, BigInteger[] knowledgeProofForX1, BigInteger[] knowledgeProofForX2) { JPAKEUtil.validateNotNull(participantId, "participantId"); JPAKEUtil.validateNotNull(gx1, "gx1"); JPAKEUtil.validateNotNull(gx2, "gx2"); JPAKEUtil.validateNotNull(knowledgeProofForX1, "knowledgeProofForX1"); JPAKEUtil.validateNotNull(knowledgeProofForX2, "knowledgeProofForX2"); this.participantId = participantId; this.gx1 = gx1; this.gx2 = gx2; this.knowledgeProofForX1 = Arrays.copyOf(knowledgeProofForX1, knowledgeProofForX1.length); this.knowledgeProofForX2 = Arrays.copyOf(knowledgeProofForX2, knowledgeProofForX2.length); } public String getParticipantId() { return participantId; } public BigInteger getGx1() { return gx1; } public BigInteger getGx2() { return gx2; } public BigInteger[] getKnowledgeProofForX1() { return Arrays.copyOf(knowledgeProofForX1, knowledgeProofForX1.length); } public BigInteger[] getKnowledgeProofForX2() { return Arrays.copyOf(knowledgeProofForX2, knowledgeProofForX2.length); } } bouncycastle-1.49.orig/src/org/bouncycastle/crypto/agreement/jpake/JPAKEParticipant.java0000644000175000017500000005473112104027245030766 0ustar ebourgebourgpackage org.bouncycastle.crypto.agreement.jpake; import java.math.BigInteger; import java.security.SecureRandom; import org.bouncycastle.crypto.CryptoException; import org.bouncycastle.crypto.Digest; import org.bouncycastle.crypto.digests.SHA256Digest; import org.bouncycastle.util.Arrays; /** * A participant in a Password Authenticated Key Exchange by Juggling (J-PAKE) exchange. *

    *

    * The J-PAKE exchange is defined by Feng Hao and Peter Ryan in the paper * * "Password Authenticated Key Exchange by Juggling, 2008." *

    *

    * The J-PAKE protocol is symmetric. * There is no notion of a client or server, but rather just two participants. * An instance of {@link JPAKEParticipant} represents one participant, and * is the primary interface for executing the exchange. *

    *

    * To execute an exchange, construct a {@link JPAKEParticipant} on each end, * and call the following 7 methods * (once and only once, in the given order, for each participant, sending messages between them as described): *

      *
    1. {@link #createRound1PayloadToSend()} - and send the payload to the other participant
    2. *
    3. {@link #validateRound1PayloadReceived(JPAKERound1Payload)} - use the payload received from the other participant
    4. *
    5. {@link #createRound2PayloadToSend()} - and send the payload to the other participant
    6. *
    7. {@link #validateRound2PayloadReceived(JPAKERound2Payload)} - use the payload received from the other participant
    8. *
    9. {@link #calculateKeyingMaterial()}
    10. *
    11. {@link #createRound3PayloadToSend(BigInteger)} - and send the payload to the other participant
    12. *
    13. {@link #validateRound3PayloadReceived(JPAKERound3Payload, BigInteger)} - use the payload received from the other participant
    14. *
    *

    *

    * Each side should derive a session key from the keying material returned by {@link #calculateKeyingMaterial()}. * The caller is responsible for deriving the session key using a secure key derivation function (KDF). *

    *

    * Round 3 is an optional key confirmation process. * If you do not execute round 3, then there is no assurance that both participants are using the same key. * (i.e. if the participants used different passwords, then their session keys will differ.) *

    *

    * If the round 3 validation succeeds, then the keys are guaranteed to be the same on both sides. *

    *

    * The symmetric design can easily support the asymmetric cases when one party initiates the communication. * e.g. Sometimes the round1 payload and round2 payload may be sent in one pass. * Also, in some cases, the key confirmation payload can be sent together with the round2 payload. * These are the trivial techniques to optimize the communication. *

    *

    * The key confirmation process is implemented as specified in * NIST SP 800-56A Revision 1, * Section 8.2 Unilateral Key Confirmation for Key Agreement Schemes. *

    *

    * This class is stateful and NOT threadsafe. * Each instance should only be used for ONE complete J-PAKE exchange * (i.e. a new {@link JPAKEParticipant} should be constructed for each new J-PAKE exchange). *

    *

    * See {@link JPAKEExample} for example usage. */ public class JPAKEParticipant { /* * Possible internal states. Used for state checking. */ public static final int STATE_INITIALIZED = 0; public static final int STATE_ROUND_1_CREATED = 10; public static final int STATE_ROUND_1_VALIDATED = 20; public static final int STATE_ROUND_2_CREATED = 30; public static final int STATE_ROUND_2_VALIDATED = 40; public static final int STATE_KEY_CALCULATED = 50; public static final int STATE_ROUND_3_CREATED = 60; public static final int STATE_ROUND_3_VALIDATED = 70; /** * Unique identifier of this participant. * The two participants in the exchange must NOT share the same id. */ private final String participantId; /** * Shared secret. This only contains the secret between construction * and the call to {@link #calculateKeyingMaterial()}. *

    * i.e. When {@link #calculateKeyingMaterial()} is called, this buffer overwritten with 0's, * and the field is set to null. */ private char[] password; /** * Digest to use during calculations. */ private final Digest digest; /** * Source of secure random data. */ private final SecureRandom random; private final BigInteger p; private final BigInteger q; private final BigInteger g; /** * The participantId of the other participant in this exchange. */ private String partnerParticipantId; /** * Alice's x1 or Bob's x3. */ private BigInteger x1; /** * Alice's x2 or Bob's x4. */ private BigInteger x2; /** * Alice's g^x1 or Bob's g^x3. */ private BigInteger gx1; /** * Alice's g^x2 or Bob's g^x4. */ private BigInteger gx2; /** * Alice's g^x3 or Bob's g^x1. */ private BigInteger gx3; /** * Alice's g^x4 or Bob's g^x2. */ private BigInteger gx4; /** * Alice's B or Bob's A. */ private BigInteger b; /** * The current state. * See the STATE_* constants for possible values. */ private int state; /** * Convenience constructor for a new {@link JPAKEParticipant} that uses * the {@link JPAKEPrimeOrderGroups#NIST_3072} prime order group, * a SHA-256 digest, and a default {@link SecureRandom} implementation. *

    * After construction, the {@link #getState() state} will be {@link #STATE_INITIALIZED}. * * @param participantId unique identifier of this participant. * The two participants in the exchange must NOT share the same id. * @param password shared secret. * A defensive copy of this array is made (and cleared once {@link #calculateKeyingMaterial()} is called). * Caller should clear the input password as soon as possible. * @throws NullPointerException if any argument is null * @throws IllegalArgumentException if password is empty */ public JPAKEParticipant( String participantId, char[] password) { this( participantId, password, JPAKEPrimeOrderGroups.NIST_3072); } /** * Convenience constructor for a new {@link JPAKEParticipant} that uses * a SHA-256 digest and a default {@link SecureRandom} implementation. *

    * After construction, the {@link #getState() state} will be {@link #STATE_INITIALIZED}. * * @param participantId unique identifier of this participant. * The two participants in the exchange must NOT share the same id. * @param password shared secret. * A defensive copy of this array is made (and cleared once {@link #calculateKeyingMaterial()} is called). * Caller should clear the input password as soon as possible. * @param group prime order group. * See {@link JPAKEPrimeOrderGroups} for standard groups * @throws NullPointerException if any argument is null * @throws IllegalArgumentException if password is empty */ public JPAKEParticipant( String participantId, char[] password, JPAKEPrimeOrderGroup group) { this( participantId, password, group, new SHA256Digest(), new SecureRandom()); } /** * Construct a new {@link JPAKEParticipant}. *

    * After construction, the {@link #getState() state} will be {@link #STATE_INITIALIZED}. * * @param participantId unique identifier of this participant. * The two participants in the exchange must NOT share the same id. * @param password shared secret. * A defensive copy of this array is made (and cleared once {@link #calculateKeyingMaterial()} is called). * Caller should clear the input password as soon as possible. * @param group prime order group. * See {@link JPAKEPrimeOrderGroups} for standard groups * @param digest digest to use during zero knowledge proofs and key confirmation (SHA-256 or stronger preferred) * @param random source of secure random data for x1 and x2, and for the zero knowledge proofs * @throws NullPointerException if any argument is null * @throws IllegalArgumentException if password is empty */ public JPAKEParticipant( String participantId, char[] password, JPAKEPrimeOrderGroup group, Digest digest, SecureRandom random) { JPAKEUtil.validateNotNull(participantId, "participantId"); JPAKEUtil.validateNotNull(password, "password"); JPAKEUtil.validateNotNull(group, "p"); JPAKEUtil.validateNotNull(digest, "digest"); JPAKEUtil.validateNotNull(random, "random"); if (password.length == 0) { throw new IllegalArgumentException("Password must not be empty."); } this.participantId = participantId; /* * Create a defensive copy so as to fully encapsulate the password. * * This array will contain the password for the lifetime of this * participant BEFORE {@link #calculateKeyingMaterial()} is called. * * i.e. When {@link #calculateKeyingMaterial()} is called, the array will be cleared * in order to remove the password from memory. * * The caller is responsible for clearing the original password array * given as input to this constructor. */ this.password = Arrays.copyOf(password, password.length); this.p = group.getP(); this.q = group.getQ(); this.g = group.getG(); this.digest = digest; this.random = random; this.state = STATE_INITIALIZED; } /** * Gets the current state of this participant. * See the STATE_* constants for possible values. */ public int getState() { return this.state; } /** * Creates and returns the payload to send to the other participant during round 1. *

    *

    * After execution, the {@link #getState() state} will be {@link #STATE_ROUND_1_CREATED}. */ public JPAKERound1Payload createRound1PayloadToSend() { if (this.state >= STATE_ROUND_1_CREATED) { throw new IllegalStateException("Round1 payload already created for " + participantId); } this.x1 = JPAKEUtil.generateX1(q, random); this.x2 = JPAKEUtil.generateX2(q, random); this.gx1 = JPAKEUtil.calculateGx(p, g, x1); this.gx2 = JPAKEUtil.calculateGx(p, g, x2); BigInteger[] knowledgeProofForX1 = JPAKEUtil.calculateZeroKnowledgeProof(p, q, g, gx1, x1, participantId, digest, random); BigInteger[] knowledgeProofForX2 = JPAKEUtil.calculateZeroKnowledgeProof(p, q, g, gx2, x2, participantId, digest, random); this.state = STATE_ROUND_1_CREATED; return new JPAKERound1Payload(participantId, gx1, gx2, knowledgeProofForX1, knowledgeProofForX2); } /** * Validates the payload received from the other participant during round 1. *

    *

    * Must be called prior to {@link #createRound2PayloadToSend()}. *

    *

    * After execution, the {@link #getState() state} will be {@link #STATE_ROUND_1_VALIDATED}. * * @throws CryptoException if validation fails. * @throws IllegalStateException if called multiple times. */ public void validateRound1PayloadReceived(JPAKERound1Payload round1PayloadReceived) throws CryptoException { if (this.state >= STATE_ROUND_1_VALIDATED) { throw new IllegalStateException("Validation already attempted for round1 payload for" + participantId); } this.partnerParticipantId = round1PayloadReceived.getParticipantId(); this.gx3 = round1PayloadReceived.getGx1(); this.gx4 = round1PayloadReceived.getGx2(); BigInteger[] knowledgeProofForX3 = round1PayloadReceived.getKnowledgeProofForX1(); BigInteger[] knowledgeProofForX4 = round1PayloadReceived.getKnowledgeProofForX2(); JPAKEUtil.validateParticipantIdsDiffer(participantId, round1PayloadReceived.getParticipantId()); JPAKEUtil.validateGx4(gx4); JPAKEUtil.validateZeroKnowledgeProof(p, q, g, gx3, knowledgeProofForX3, round1PayloadReceived.getParticipantId(), digest); JPAKEUtil.validateZeroKnowledgeProof(p, q, g, gx4, knowledgeProofForX4, round1PayloadReceived.getParticipantId(), digest); this.state = STATE_ROUND_1_VALIDATED; } /** * Creates and returns the payload to send to the other participant during round 2. *

    *

    * {@link #validateRound1PayloadReceived(JPAKERound1Payload)} must be called prior to this method. *

    *

    * After execution, the {@link #getState() state} will be {@link #STATE_ROUND_2_CREATED}. * * @throws IllegalStateException if called prior to {@link #validateRound1PayloadReceived(JPAKERound1Payload)}, or multiple times */ public JPAKERound2Payload createRound2PayloadToSend() { if (this.state >= STATE_ROUND_2_CREATED) { throw new IllegalStateException("Round2 payload already created for " + this.participantId); } if (this.state < STATE_ROUND_1_VALIDATED) { throw new IllegalStateException("Round1 payload must be validated prior to creating Round2 payload for " + this.participantId); } BigInteger gA = JPAKEUtil.calculateGA(p, gx1, gx3, gx4); BigInteger s = JPAKEUtil.calculateS(password); BigInteger x2s = JPAKEUtil.calculateX2s(q, x2, s); BigInteger A = JPAKEUtil.calculateA(p, q, gA, x2s); BigInteger[] knowledgeProofForX2s = JPAKEUtil.calculateZeroKnowledgeProof(p, q, gA, A, x2s, participantId, digest, random); this.state = STATE_ROUND_2_CREATED; return new JPAKERound2Payload(participantId, A, knowledgeProofForX2s); } /** * Validates the payload received from the other participant during round 2. *

    *

    * Note that this DOES NOT detect a non-common password. * The only indication of a non-common password is through derivation * of different keys (which can be detected explicitly by executing round 3 and round 4) *

    *

    * Must be called prior to {@link #calculateKeyingMaterial()}. *

    *

    * After execution, the {@link #getState() state} will be {@link #STATE_ROUND_2_VALIDATED}. * * @throws CryptoException if validation fails. * @throws IllegalStateException if called prior to {@link #validateRound1PayloadReceived(JPAKERound1Payload)}, or multiple times */ public void validateRound2PayloadReceived(JPAKERound2Payload round2PayloadReceived) throws CryptoException { if (this.state >= STATE_ROUND_2_VALIDATED) { throw new IllegalStateException("Validation already attempted for round2 payload for" + participantId); } if (this.state < STATE_ROUND_1_VALIDATED) { throw new IllegalStateException("Round1 payload must be validated prior to validating Round2 payload for " + this.participantId); } BigInteger gB = JPAKEUtil.calculateGA(p, gx3, gx1, gx2); this.b = round2PayloadReceived.getA(); BigInteger[] knowledgeProofForX4s = round2PayloadReceived.getKnowledgeProofForX2s(); JPAKEUtil.validateParticipantIdsDiffer(participantId, round2PayloadReceived.getParticipantId()); JPAKEUtil.validateParticipantIdsEqual(this.partnerParticipantId, round2PayloadReceived.getParticipantId()); JPAKEUtil.validateGa(gB); JPAKEUtil.validateZeroKnowledgeProof(p, q, gB, b, knowledgeProofForX4s, round2PayloadReceived.getParticipantId(), digest); this.state = STATE_ROUND_2_VALIDATED; } /** * Calculates and returns the key material. * A session key must be derived from this key material using a secure key derivation function (KDF). * The KDF used to derive the key is handled externally (i.e. not by {@link JPAKEParticipant}). *

    *

    * The keying material will be identical for each participant if and only if * each participant's password is the same. i.e. If the participants do not * share the same password, then each participant will derive a different key. * Therefore, if you immediately start using a key derived from * the keying material, then you must handle detection of incorrect keys. * If you want to handle this detection explicitly, you can optionally perform * rounds 3 and 4. See {@link JPAKEParticipant} for details on how to execute * rounds 3 and 4. *

    *

    * The keying material will be in the range [0, p-1]. *

    *

    * {@link #validateRound2PayloadReceived(JPAKERound2Payload)} must be called prior to this method. *

    *

    * As a side effect, the internal {@link #password} array is cleared, since it is no longer needed. *

    *

    * After execution, the {@link #getState() state} will be {@link #STATE_KEY_CALCULATED}. * * @throws IllegalStateException if called prior to {@link #validateRound2PayloadReceived(JPAKERound2Payload)}, * or if called multiple times. */ public BigInteger calculateKeyingMaterial() { if (this.state >= STATE_KEY_CALCULATED) { throw new IllegalStateException("Key already calculated for " + participantId); } if (this.state < STATE_ROUND_2_VALIDATED) { throw new IllegalStateException("Round2 payload must be validated prior to creating key for " + participantId); } BigInteger s = JPAKEUtil.calculateS(password); /* * Clear the password array from memory, since we don't need it anymore. * * Also set the field to null as a flag to indicate that the key has already been calculated. */ Arrays.fill(password, (char)0); this.password = null; BigInteger keyingMaterial = JPAKEUtil.calculateKeyingMaterial(p, q, gx4, x2, s, b); /* * Clear the ephemeral private key fields as well. * Note that we're relying on the garbage collector to do its job to clean these up. * The old objects will hang around in memory until the garbage collector destroys them. * * If the ephemeral private keys x1 and x2 are leaked, * the attacker might be able to brute-force the password. */ this.x1 = null; this.x2 = null; this.b = null; /* * Do not clear gx* yet, since those are needed by round 3. */ this.state = STATE_KEY_CALCULATED; return keyingMaterial; } /** * Creates and returns the payload to send to the other participant during round 3. *

    *

    * See {@link JPAKEParticipant} for more details on round 3. *

    *

    * After execution, the {@link #getState() state} will be {@link #STATE_ROUND_3_CREATED}. * * @param keyingMaterial The keying material as returned from {@link #calculateKeyingMaterial()}. * @throws IllegalStateException if called prior to {@link #calculateKeyingMaterial()}, or multiple times */ public JPAKERound3Payload createRound3PayloadToSend(BigInteger keyingMaterial) { if (this.state >= STATE_ROUND_3_CREATED) { throw new IllegalStateException("Round3 payload already created for " + this.participantId); } if (this.state < STATE_KEY_CALCULATED) { throw new IllegalStateException("Keying material must be calculated prior to creating Round3 payload for " + this.participantId); } BigInteger macTag = JPAKEUtil.calculateMacTag( this.participantId, this.partnerParticipantId, this.gx1, this.gx2, this.gx3, this.gx4, keyingMaterial, this.digest); this.state = STATE_ROUND_3_CREATED; return new JPAKERound3Payload(participantId, macTag); } /** * Validates the payload received from the other participant during round 3. *

    *

    * See {@link JPAKEParticipant} for more details on round 3. *

    *

    * After execution, the {@link #getState() state} will be {@link #STATE_ROUND_3_VALIDATED}. * * @param keyingMaterial The keying material as returned from {@link #calculateKeyingMaterial()}. * @throws CryptoException if validation fails. * @throws IllegalStateException if called prior to {@link #calculateKeyingMaterial()}, or multiple times */ public void validateRound3PayloadReceived(JPAKERound3Payload round3PayloadReceived, BigInteger keyingMaterial) throws CryptoException { if (this.state >= STATE_ROUND_3_VALIDATED) { throw new IllegalStateException("Validation already attempted for round3 payload for" + participantId); } if (this.state < STATE_KEY_CALCULATED) { throw new IllegalStateException("Keying material must be calculated validated prior to validating Round3 payload for " + this.participantId); } JPAKEUtil.validateParticipantIdsDiffer(participantId, round3PayloadReceived.getParticipantId()); JPAKEUtil.validateParticipantIdsEqual(this.partnerParticipantId, round3PayloadReceived.getParticipantId()); JPAKEUtil.validateMacTag( this.participantId, this.partnerParticipantId, this.gx1, this.gx2, this.gx3, this.gx4, keyingMaterial, this.digest, round3PayloadReceived.getMacTag()); /* * Clear the rest of the fields. */ this.gx1 = null; this.gx2 = null; this.gx3 = null; this.gx4 = null; this.state = STATE_ROUND_3_VALIDATED; } } bouncycastle-1.49.orig/src/org/bouncycastle/crypto/agreement/jpake/JPAKERound2Payload.java0000644000175000017500000000363712152020122031160 0ustar ebourgebourgpackage org.bouncycastle.crypto.agreement.jpake; import java.math.BigInteger; import org.bouncycastle.util.Arrays; /** * The payload sent/received during the second round of a J-PAKE exchange. *

    *

    * Each {@link JPAKEParticipant} creates and sends an instance * of this payload to the other {@link JPAKEParticipant}. * The payload to send should be created via * {@link JPAKEParticipant#createRound2PayloadToSend()} *

    *

    * Each {@link JPAKEParticipant} must also validate the payload * received from the other {@link JPAKEParticipant}. * The received payload should be validated via * {@link JPAKEParticipant#validateRound2PayloadReceived(JPAKERound2Payload)} *

    */ public class JPAKERound2Payload { /** * The id of the {@link JPAKEParticipant} who created/sent this payload. */ private final String participantId; /** * The value of A, as computed during round 2. */ private final BigInteger a; /** * The zero knowledge proof for x2 * s. *

    * This is a two element array, containing {g^v, r} for x2 * s. */ private final BigInteger[] knowledgeProofForX2s; public JPAKERound2Payload( String participantId, BigInteger a, BigInteger[] knowledgeProofForX2s) { JPAKEUtil.validateNotNull(participantId, "participantId"); JPAKEUtil.validateNotNull(a, "a"); JPAKEUtil.validateNotNull(knowledgeProofForX2s, "knowledgeProofForX2s"); this.participantId = participantId; this.a = a; this.knowledgeProofForX2s = Arrays.copyOf(knowledgeProofForX2s, knowledgeProofForX2s.length); } public String getParticipantId() { return participantId; } public BigInteger getA() { return a; } public BigInteger[] getKnowledgeProofForX2s() { return Arrays.copyOf(knowledgeProofForX2s, knowledgeProofForX2s.length); } } bouncycastle-1.49.orig/src/org/bouncycastle/crypto/agreement/jpake/JPAKEPrimeOrderGroup.java0000644000175000017500000000735312104603564031577 0ustar ebourgebourgpackage org.bouncycastle.crypto.agreement.jpake; import java.math.BigInteger; /** * A pre-computed prime order group for use during a J-PAKE exchange. *

    *

    * Typically a Schnorr group is used. In general, J-PAKE can use any prime order group * that is suitable for public key cryptography, including elliptic curve cryptography. *

    *

    * See {@link JPAKEPrimeOrderGroups} for convenient standard groups. *

    *

    * NIST publishes * many groups that can be used for the desired level of security. */ public class JPAKEPrimeOrderGroup { private final BigInteger p; private final BigInteger q; private final BigInteger g; /** * Constructs a new {@link JPAKEPrimeOrderGroup}. *

    *

    * In general, you should use one of the pre-approved groups from * {@link JPAKEPrimeOrderGroups}, rather than manually constructing one. *

    *

    * The following basic checks are performed: *

      *
    • p-1 must be evenly divisible by q
    • *
    • g must be in [2, p-1]
    • *
    • g^q mod p must equal 1
    • *
    • p must be prime (within reasonably certainty)
    • *
    • q must be prime (within reasonably certainty)
    • *
    *

    *

    * The prime checks are performed using {@link BigInteger#isProbablePrime(int)}, * and are therefore subject to the same probability guarantees. *

    *

    * These checks prevent trivial mistakes. * However, due to the small uncertainties if p and q are not prime, * advanced attacks are not prevented. * Use it at your own risk. * * @throws NullPointerException if any argument is null * @throws IllegalArgumentException if any of the above validations fail */ public JPAKEPrimeOrderGroup(BigInteger p, BigInteger q, BigInteger g) { /* * Don't skip the checks on user-specified groups. */ this(p, q, g, false); } /** * Internal package-private constructor used by the pre-approved * groups in {@link JPAKEPrimeOrderGroups}. * These pre-approved groups can avoid the expensive checks. */ JPAKEPrimeOrderGroup(BigInteger p, BigInteger q, BigInteger g, boolean skipChecks) { JPAKEUtil.validateNotNull(p, "p"); JPAKEUtil.validateNotNull(q, "q"); JPAKEUtil.validateNotNull(g, "g"); if (!skipChecks) { if (!p.subtract(JPAKEUtil.ONE).mod(q).equals(JPAKEUtil.ZERO)) { throw new IllegalArgumentException("p-1 must be evenly divisible by q"); } if (g.compareTo(BigInteger.valueOf(2)) == -1 || g.compareTo(p.subtract(JPAKEUtil.ONE)) == 1) { throw new IllegalArgumentException("g must be in [2, p-1]"); } if (!g.modPow(q, p).equals(JPAKEUtil.ONE)) { throw new IllegalArgumentException("g^q mod p must equal 1"); } /* * Note that these checks do not guarantee that p and q are prime. * We just have reasonable certainty that they are prime. */ if (!p.isProbablePrime(20)) { throw new IllegalArgumentException("p must be prime"); } if (!q.isProbablePrime(20)) { throw new IllegalArgumentException("q must be prime"); } } this.p = p; this.q = q; this.g = g; } public BigInteger getP() { return p; } public BigInteger getQ() { return q; } public BigInteger getG() { return g; } } bouncycastle-1.49.orig/src/org/bouncycastle/crypto/agreement/jpake/JPAKERound3Payload.java0000644000175000017500000000270612152020122031155 0ustar ebourgebourgpackage org.bouncycastle.crypto.agreement.jpake; import java.math.BigInteger; /** * The payload sent/received during the optional third round of a J-PAKE exchange, * which is for explicit key confirmation. *

    *

    * Each {@link JPAKEParticipant} creates and sends an instance * of this payload to the other {@link JPAKEParticipant}. * The payload to send should be created via * {@link JPAKEParticipant#createRound3PayloadToSend(BigInteger)} *

    *

    * Each {@link JPAKEParticipant} must also validate the payload * received from the other {@link JPAKEParticipant}. * The received payload should be validated via * {@link JPAKEParticipant#validateRound3PayloadReceived(JPAKERound3Payload, BigInteger)} *

    */ public class JPAKERound3Payload { /** * The id of the {@link JPAKEParticipant} who created/sent this payload. */ private final String participantId; /** * The value of MacTag, as computed by round 3. * * @see JPAKEUtil#calculateMacTag(String, String, BigInteger, BigInteger, BigInteger, BigInteger, BigInteger, org.bouncycastle.crypto.Digest) */ private final BigInteger macTag; public JPAKERound3Payload(String participantId, BigInteger magTag) { this.participantId = participantId; this.macTag = magTag; } public String getParticipantId() { return participantId; } public BigInteger getMacTag() { return macTag; } } bouncycastle-1.49.orig/src/org/bouncycastle/crypto/agreement/jpake/package.html0000644000175000017500000000015212151566374027354 0ustar ebourgebourg Password Authenticated Key Exchange by Juggling (J-PAKE). bouncycastle-1.49.orig/src/org/bouncycastle/crypto/agreement/ECMQVBasicAgreement.java0000644000175000017500000000572212057260001030300 0ustar ebourgebourgpackage org.bouncycastle.crypto.agreement; import java.math.BigInteger; import org.bouncycastle.crypto.BasicAgreement; import org.bouncycastle.crypto.CipherParameters; import org.bouncycastle.crypto.params.ECDomainParameters; import org.bouncycastle.crypto.params.ECPrivateKeyParameters; import org.bouncycastle.crypto.params.ECPublicKeyParameters; import org.bouncycastle.crypto.params.MQVPrivateParameters; import org.bouncycastle.crypto.params.MQVPublicParameters; import org.bouncycastle.math.ec.ECAlgorithms; import org.bouncycastle.math.ec.ECConstants; import org.bouncycastle.math.ec.ECPoint; public class ECMQVBasicAgreement implements BasicAgreement { MQVPrivateParameters privParams; public void init( CipherParameters key) { this.privParams = (MQVPrivateParameters)key; } public int getFieldSize() { return (privParams.getStaticPrivateKey().getParameters().getCurve().getFieldSize() + 7) / 8; } public BigInteger calculateAgreement(CipherParameters pubKey) { MQVPublicParameters pubParams = (MQVPublicParameters)pubKey; ECPrivateKeyParameters staticPrivateKey = privParams.getStaticPrivateKey(); ECPoint agreement = calculateMqvAgreement(staticPrivateKey.getParameters(), staticPrivateKey, privParams.getEphemeralPrivateKey(), privParams.getEphemeralPublicKey(), pubParams.getStaticPublicKey(), pubParams.getEphemeralPublicKey()); return agreement.getX().toBigInteger(); } // The ECMQV Primitive as described in SEC-1, 3.4 private ECPoint calculateMqvAgreement( ECDomainParameters parameters, ECPrivateKeyParameters d1U, ECPrivateKeyParameters d2U, ECPublicKeyParameters Q2U, ECPublicKeyParameters Q1V, ECPublicKeyParameters Q2V) { BigInteger n = parameters.getN(); int e = (n.bitLength() + 1) / 2; BigInteger powE = ECConstants.ONE.shiftLeft(e); // The Q2U public key is optional ECPoint q; if (Q2U == null) { q = parameters.getG().multiply(d2U.getD()); } else { q = Q2U.getQ(); } BigInteger x = q.getX().toBigInteger(); BigInteger xBar = x.mod(powE); BigInteger Q2UBar = xBar.setBit(e); BigInteger s = d1U.getD().multiply(Q2UBar).mod(n).add(d2U.getD()).mod(n); BigInteger xPrime = Q2V.getQ().getX().toBigInteger(); BigInteger xPrimeBar = xPrime.mod(powE); BigInteger Q2VBar = xPrimeBar.setBit(e); BigInteger hs = parameters.getH().multiply(s).mod(n); // ECPoint p = Q1V.getQ().multiply(Q2VBar).add(Q2V.getQ()).multiply(hs); ECPoint p = ECAlgorithms.sumOfTwoMultiplies( Q1V.getQ(), Q2VBar.multiply(hs).mod(n), Q2V.getQ(), hs); if (p.isInfinity()) { throw new IllegalStateException("Infinity is not a valid agreement value for MQV"); } return p; } } bouncycastle-1.49.orig/src/org/bouncycastle/crypto/agreement/srp/0000755000175000017500000000000012152033551024572 5ustar ebourgebourgbouncycastle-1.49.orig/src/org/bouncycastle/crypto/agreement/srp/SRP6VerifierGenerator.java0000644000175000017500000000261311272214671031542 0ustar ebourgebourgpackage org.bouncycastle.crypto.agreement.srp; import java.math.BigInteger; import org.bouncycastle.crypto.Digest; /** * Generates new SRP verifier for user */ public class SRP6VerifierGenerator { protected BigInteger N; protected BigInteger g; protected Digest digest; public SRP6VerifierGenerator() { } /** * Initialises generator to create new verifiers * @param N The safe prime to use (see DHParametersGenerator) * @param g The group parameter to use (see DHParametersGenerator) * @param digest The digest to use. The same digest type will need to be used later for the actual authentication * attempt. Also note that the final session key size is dependent on the chosen digest. */ public void init(BigInteger N, BigInteger g, Digest digest) { this.N = N; this.g = g; this.digest = digest; } /** * Creates a new SRP verifier * @param salt The salt to use, generally should be large and random * @param identity The user's identifying information (eg. username) * @param password The user's password * @return A new verifier for use in future SRP authentication */ public BigInteger generateVerifier(byte[] salt, byte[] identity, byte[] password) { BigInteger x = SRP6Util.calculateX(digest, N, salt, identity, password); return g.modPow(x, N); } } bouncycastle-1.49.orig/src/org/bouncycastle/crypto/agreement/srp/SRP6Util.java0000644000175000017500000000527411662561652027052 0ustar ebourgebourgpackage org.bouncycastle.crypto.agreement.srp; import java.math.BigInteger; import java.security.SecureRandom; import org.bouncycastle.crypto.CryptoException; import org.bouncycastle.crypto.Digest; import org.bouncycastle.util.BigIntegers; public class SRP6Util { private static BigInteger ZERO = BigInteger.valueOf(0); private static BigInteger ONE = BigInteger.valueOf(1); public static BigInteger calculateK(Digest digest, BigInteger N, BigInteger g) { return hashPaddedPair(digest, N, N, g); } public static BigInteger calculateU(Digest digest, BigInteger N, BigInteger A, BigInteger B) { return hashPaddedPair(digest, N, A, B); } public static BigInteger calculateX(Digest digest, BigInteger N, byte[] salt, byte[] identity, byte[] password) { byte[] output = new byte[digest.getDigestSize()]; digest.update(identity, 0, identity.length); digest.update((byte)':'); digest.update(password, 0, password.length); digest.doFinal(output, 0); digest.update(salt, 0, salt.length); digest.update(output, 0, output.length); digest.doFinal(output, 0); return new BigInteger(1, output); } public static BigInteger generatePrivateValue(Digest digest, BigInteger N, BigInteger g, SecureRandom random) { int minBits = Math.min(256, N.bitLength() / 2); BigInteger min = ONE.shiftLeft(minBits - 1); BigInteger max = N.subtract(ONE); return BigIntegers.createRandomInRange(min, max, random); } public static BigInteger validatePublicValue(BigInteger N, BigInteger val) throws CryptoException { val = val.mod(N); // Check that val % N != 0 if (val.equals(ZERO)) { throw new CryptoException("Invalid public value: 0"); } return val; } private static BigInteger hashPaddedPair(Digest digest, BigInteger N, BigInteger n1, BigInteger n2) { int padLength = (N.bitLength() + 7) / 8; byte[] n1_bytes = getPadded(n1, padLength); byte[] n2_bytes = getPadded(n2, padLength); digest.update(n1_bytes, 0, n1_bytes.length); digest.update(n2_bytes, 0, n2_bytes.length); byte[] output = new byte[digest.getDigestSize()]; digest.doFinal(output, 0); return new BigInteger(1, output); } private static byte[] getPadded(BigInteger n, int length) { byte[] bs = BigIntegers.asUnsignedByteArray(n); if (bs.length < length) { byte[] tmp = new byte[length]; System.arraycopy(bs, 0, tmp, length - bs.length, bs.length); bs = tmp; } return bs; } } bouncycastle-1.49.orig/src/org/bouncycastle/crypto/agreement/srp/SRP6Server.java0000644000175000017500000000515111272212751027363 0ustar ebourgebourgpackage org.bouncycastle.crypto.agreement.srp; import java.math.BigInteger; import java.security.SecureRandom; import org.bouncycastle.crypto.CryptoException; import org.bouncycastle.crypto.Digest; /** * Implements the server side SRP-6a protocol. Note that this class is stateful, and therefore NOT threadsafe. * This implementation of SRP is based on the optimized message sequence put forth by Thomas Wu in the paper * "SRP-6: Improvements and Refinements to the Secure Remote Password Protocol, 2002" */ public class SRP6Server { protected BigInteger N; protected BigInteger g; protected BigInteger v; protected SecureRandom random; protected Digest digest; protected BigInteger A; protected BigInteger b; protected BigInteger B; protected BigInteger u; protected BigInteger S; public SRP6Server() { } /** * Initialises the server to accept a new client authentication attempt * @param N The safe prime associated with the client's verifier * @param g The group parameter associated with the client's verifier * @param v The client's verifier * @param digest The digest algorithm associated with the client's verifier * @param random For key generation */ public void init(BigInteger N, BigInteger g, BigInteger v, Digest digest, SecureRandom random) { this.N = N; this.g = g; this.v = v; this.random = random; this.digest = digest; } /** * Generates the server's credentials that are to be sent to the client. * @return The server's public value to the client */ public BigInteger generateServerCredentials() { BigInteger k = SRP6Util.calculateK(digest, N, g); this.b = selectPrivateValue(); this.B = k.multiply(v).mod(N).add(g.modPow(b, N)).mod(N); return B; } /** * Processes the client's credentials. If valid the shared secret is generated and returned. * @param clientA The client's credentials * @return A shared secret BigInteger * @throws CryptoException If client's credentials are invalid */ public BigInteger calculateSecret(BigInteger clientA) throws CryptoException { this.A = SRP6Util.validatePublicValue(N, clientA); this.u = SRP6Util.calculateU(digest, N, A, B); this.S = calculateS(); return S; } protected BigInteger selectPrivateValue() { return SRP6Util.generatePrivateValue(digest, N, g, random); } private BigInteger calculateS() { return v.modPow(u, N).multiply(A).mod(N).modPow(b, N); } } bouncycastle-1.49.orig/src/org/bouncycastle/crypto/agreement/srp/SRP6Client.java0000644000175000017500000000556611272215532027345 0ustar ebourgebourgpackage org.bouncycastle.crypto.agreement.srp; import java.math.BigInteger; import java.security.SecureRandom; import org.bouncycastle.crypto.CryptoException; import org.bouncycastle.crypto.Digest; /** * Implements the client side SRP-6a protocol. Note that this class is stateful, and therefore NOT threadsafe. * This implementation of SRP is based on the optimized message sequence put forth by Thomas Wu in the paper * "SRP-6: Improvements and Refinements to the Secure Remote Password Protocol, 2002" */ public class SRP6Client { protected BigInteger N; protected BigInteger g; protected BigInteger a; protected BigInteger A; protected BigInteger B; protected BigInteger x; protected BigInteger u; protected BigInteger S; protected Digest digest; protected SecureRandom random; public SRP6Client() { } /** * Initialises the client to begin new authentication attempt * @param N The safe prime associated with the client's verifier * @param g The group parameter associated with the client's verifier * @param digest The digest algorithm associated with the client's verifier * @param random For key generation */ public void init(BigInteger N, BigInteger g, Digest digest, SecureRandom random) { this.N = N; this.g = g; this.digest = digest; this.random = random; } /** * Generates client's credentials given the client's salt, identity and password * @param salt The salt used in the client's verifier. * @param identity The user's identity (eg. username) * @param password The user's password * @return Client's public value to send to server */ public BigInteger generateClientCredentials(byte[] salt, byte[] identity, byte[] password) { this.x = SRP6Util.calculateX(digest, N, salt, identity, password); this.a = selectPrivateValue(); this.A = g.modPow(a, N); return A; } /** * Generates client's verification message given the server's credentials * @param serverB The server's credentials * @return Client's verification message for the server * @throws CryptoException If server's credentials are invalid */ public BigInteger calculateSecret(BigInteger serverB) throws CryptoException { this.B = SRP6Util.validatePublicValue(N, serverB); this.u = SRP6Util.calculateU(digest, N, A, B); this.S = calculateS(); return S; } protected BigInteger selectPrivateValue() { return SRP6Util.generatePrivateValue(digest, N, g, random); } private BigInteger calculateS() { BigInteger k = SRP6Util.calculateK(digest, N, g); BigInteger exp = u.multiply(x).add(a); BigInteger tmp = g.modPow(x, N).multiply(k).mod(N); return B.subtract(tmp).mod(N).modPow(exp, N); } } bouncycastle-1.49.orig/src/org/bouncycastle/crypto/agreement/DHBasicAgreement.java0000644000175000017500000000416412057261600027725 0ustar ebourgebourgpackage org.bouncycastle.crypto.agreement; import java.math.BigInteger; import org.bouncycastle.crypto.BasicAgreement; import org.bouncycastle.crypto.CipherParameters; import org.bouncycastle.crypto.params.AsymmetricKeyParameter; import org.bouncycastle.crypto.params.DHParameters; import org.bouncycastle.crypto.params.DHPrivateKeyParameters; import org.bouncycastle.crypto.params.DHPublicKeyParameters; import org.bouncycastle.crypto.params.ParametersWithRandom; /** * a Diffie-Hellman key agreement class. *

    * note: This is only the basic algorithm, it doesn't take advantage of * long term public keys if they are available. See the DHAgreement class * for a "better" implementation. */ public class DHBasicAgreement implements BasicAgreement { private DHPrivateKeyParameters key; private DHParameters dhParams; public void init( CipherParameters param) { AsymmetricKeyParameter kParam; if (param instanceof ParametersWithRandom) { ParametersWithRandom rParam = (ParametersWithRandom)param; kParam = (AsymmetricKeyParameter)rParam.getParameters(); } else { kParam = (AsymmetricKeyParameter)param; } if (!(kParam instanceof DHPrivateKeyParameters)) { throw new IllegalArgumentException("DHEngine expects DHPrivateKeyParameters"); } this.key = (DHPrivateKeyParameters)kParam; this.dhParams = key.getParameters(); } public int getFieldSize() { return (key.getParameters().getP().bitLength() + 7) / 8; } /** * given a short term public key from a given party calculate the next * message in the agreement sequence. */ public BigInteger calculateAgreement( CipherParameters pubKey) { DHPublicKeyParameters pub = (DHPublicKeyParameters)pubKey; if (!pub.getParameters().equals(dhParams)) { throw new IllegalArgumentException("Diffie-Hellman public key has wrong parameters."); } return pub.getY().modPow(key.getX(), dhParams.getP()); } } bouncycastle-1.49.orig/src/org/bouncycastle/crypto/agreement/kdf/0000755000175000017500000000000012152033551024532 5ustar ebourgebourgbouncycastle-1.49.orig/src/org/bouncycastle/crypto/agreement/kdf/ECDHKEKGenerator.java0000644000175000017500000000436412132367036030317 0ustar ebourgebourgpackage org.bouncycastle.crypto.agreement.kdf; import java.io.IOException; import org.bouncycastle.asn1.ASN1EncodableVector; import org.bouncycastle.asn1.ASN1Encoding; import org.bouncycastle.asn1.ASN1ObjectIdentifier; import org.bouncycastle.asn1.DERNull; import org.bouncycastle.asn1.DEROctetString; import org.bouncycastle.asn1.DERSequence; import org.bouncycastle.asn1.DERTaggedObject; import org.bouncycastle.asn1.x509.AlgorithmIdentifier; import org.bouncycastle.crypto.DataLengthException; import org.bouncycastle.crypto.DerivationFunction; import org.bouncycastle.crypto.DerivationParameters; import org.bouncycastle.crypto.Digest; import org.bouncycastle.crypto.generators.KDF2BytesGenerator; import org.bouncycastle.crypto.params.KDFParameters; import org.bouncycastle.crypto.util.Pack; /** * X9.63 based key derivation function for ECDH CMS. */ public class ECDHKEKGenerator implements DerivationFunction { private DerivationFunction kdf; private ASN1ObjectIdentifier algorithm; private int keySize; private byte[] z; public ECDHKEKGenerator( Digest digest) { this.kdf = new KDF2BytesGenerator(digest); } public void init(DerivationParameters param) { DHKDFParameters params = (DHKDFParameters)param; this.algorithm = params.getAlgorithm(); this.keySize = params.getKeySize(); this.z = params.getZ(); } public Digest getDigest() { return kdf.getDigest(); } public int generateBytes(byte[] out, int outOff, int len) throws DataLengthException, IllegalArgumentException { // TODO Create an ASN.1 class for this (RFC3278) // ECC-CMS-SharedInfo ASN1EncodableVector v = new ASN1EncodableVector(); v.add(new AlgorithmIdentifier(algorithm, DERNull.INSTANCE)); v.add(new DERTaggedObject(true, 2, new DEROctetString(Pack.intToBigEndian(keySize)))); try { kdf.init(new KDFParameters(z, new DERSequence(v).getEncoded(ASN1Encoding.DER))); } catch (IOException e) { throw new IllegalArgumentException("unable to initialise kdf: " + e.getMessage()); } return kdf.generateBytes(out, outOff, len); } } bouncycastle-1.49.orig/src/org/bouncycastle/crypto/agreement/kdf/DHKEKGenerator.java0000644000175000017500000000717612132367010030103 0ustar ebourgebourgpackage org.bouncycastle.crypto.agreement.kdf; import java.io.IOException; import org.bouncycastle.asn1.ASN1EncodableVector; import org.bouncycastle.asn1.ASN1Encoding; import org.bouncycastle.asn1.DERObjectIdentifier; import org.bouncycastle.asn1.DEROctetString; import org.bouncycastle.asn1.DERSequence; import org.bouncycastle.asn1.DERTaggedObject; import org.bouncycastle.crypto.DataLengthException; import org.bouncycastle.crypto.DerivationFunction; import org.bouncycastle.crypto.DerivationParameters; import org.bouncycastle.crypto.Digest; import org.bouncycastle.crypto.util.Pack; /** * RFC 2631 Diffie-hellman KEK derivation function. */ public class DHKEKGenerator implements DerivationFunction { private final Digest digest; private DERObjectIdentifier algorithm; private int keySize; private byte[] z; private byte[] partyAInfo; public DHKEKGenerator( Digest digest) { this.digest = digest; } public void init(DerivationParameters param) { DHKDFParameters params = (DHKDFParameters)param; this.algorithm = params.getAlgorithm(); this.keySize = params.getKeySize(); this.z = params.getZ(); this.partyAInfo = params.getExtraInfo(); } public Digest getDigest() { return digest; } public int generateBytes(byte[] out, int outOff, int len) throws DataLengthException, IllegalArgumentException { if ((out.length - len) < outOff) { throw new DataLengthException("output buffer too small"); } long oBytes = len; int outLen = digest.getDigestSize(); // // this is at odds with the standard implementation, the // maximum value should be hBits * (2^32 - 1) where hBits // is the digest output size in bits. We can't have an // array with a long index at the moment... // if (oBytes > ((2L << 32) - 1)) { throw new IllegalArgumentException("Output length too large"); } int cThreshold = (int)((oBytes + outLen - 1) / outLen); byte[] dig = new byte[digest.getDigestSize()]; int counter = 1; for (int i = 0; i < cThreshold; i++) { digest.update(z, 0, z.length); // OtherInfo ASN1EncodableVector v1 = new ASN1EncodableVector(); // KeySpecificInfo ASN1EncodableVector v2 = new ASN1EncodableVector(); v2.add(algorithm); v2.add(new DEROctetString(Pack.intToBigEndian(counter))); v1.add(new DERSequence(v2)); if (partyAInfo != null) { v1.add(new DERTaggedObject(true, 0, new DEROctetString(partyAInfo))); } v1.add(new DERTaggedObject(true, 2, new DEROctetString(Pack.intToBigEndian(keySize)))); try { byte[] other = new DERSequence(v1).getEncoded(ASN1Encoding.DER); digest.update(other, 0, other.length); } catch (IOException e) { throw new IllegalArgumentException("unable to encode parameter info: " + e.getMessage()); } digest.doFinal(dig, 0); if (len > outLen) { System.arraycopy(dig, 0, out, outOff, outLen); outOff += outLen; len -= outLen; } else { System.arraycopy(dig, 0, out, outOff, len); } counter++; } digest.reset(); return (int)oBytes; } } bouncycastle-1.49.orig/src/org/bouncycastle/crypto/agreement/kdf/DHKDFParameters.java0000644000175000017500000000216111705655241030252 0ustar ebourgebourgpackage org.bouncycastle.crypto.agreement.kdf; import org.bouncycastle.asn1.ASN1ObjectIdentifier; import org.bouncycastle.asn1.DERObjectIdentifier; import org.bouncycastle.crypto.DerivationParameters; public class DHKDFParameters implements DerivationParameters { private ASN1ObjectIdentifier algorithm; private int keySize; private byte[] z; private byte[] extraInfo; public DHKDFParameters( DERObjectIdentifier algorithm, int keySize, byte[] z) { this(algorithm, keySize, z, null); } public DHKDFParameters( DERObjectIdentifier algorithm, int keySize, byte[] z, byte[] extraInfo) { this.algorithm = new ASN1ObjectIdentifier(algorithm.getId()); this.keySize = keySize; this.z = z; this.extraInfo = extraInfo; } public ASN1ObjectIdentifier getAlgorithm() { return algorithm; } public int getKeySize() { return keySize; } public byte[] getZ() { return z; } public byte[] getExtraInfo() { return extraInfo; } } bouncycastle-1.49.orig/src/org/bouncycastle/crypto/agreement/package.html0000644000175000017500000000011510262753175026257 0ustar ebourgebourg Basic key agreement classes. bouncycastle-1.49.orig/src/org/bouncycastle/crypto/KeyParser.java0000644000175000017500000000041412033463651024574 0ustar ebourgebourgpackage org.bouncycastle.crypto; import java.io.IOException; import java.io.InputStream; import org.bouncycastle.crypto.params.AsymmetricKeyParameter; public interface KeyParser { AsymmetricKeyParameter readKey(InputStream stream) throws IOException; } bouncycastle-1.49.orig/src/org/bouncycastle/crypto/parsers/0000755000175000017500000000000012152033551023476 5ustar ebourgebourgbouncycastle-1.49.orig/src/org/bouncycastle/crypto/parsers/ECIESPublicKeyParser.java0000644000175000017500000000310712033472262030163 0ustar ebourgebourgpackage org.bouncycastle.crypto.parsers; import java.io.IOException; import java.io.InputStream; import org.bouncycastle.crypto.KeyParser; import org.bouncycastle.crypto.params.AsymmetricKeyParameter; import org.bouncycastle.crypto.params.ECDomainParameters; import org.bouncycastle.crypto.params.ECPublicKeyParameters; public class ECIESPublicKeyParser implements KeyParser { private ECDomainParameters ecParams; public ECIESPublicKeyParser(ECDomainParameters ecParams) { this.ecParams = ecParams; } public AsymmetricKeyParameter readKey(InputStream stream) throws IOException { byte[] V; int first = stream.read(); // Decode the public ephemeral key switch (first) { case 0x00: // infinity throw new IOException("Sender's public key invalid."); case 0x02: // compressed case 0x03: // Byte length calculated as in ECPoint.getEncoded(); V = new byte[1 + (ecParams.getCurve().getFieldSize()+7)/8]; break; case 0x04: // uncompressed or case 0x06: // hybrid case 0x07: // Byte length calculated as in ECPoint.getEncoded(); V = new byte[1 + 2*((ecParams.getCurve().getFieldSize()+7)/8)]; break; default: throw new IOException("Sender's public key has invalid point encoding 0x" + Integer.toString(first, 16)); } V[0] = (byte)first; stream.read(V, 1, V.length - 1); return new ECPublicKeyParameters(ecParams.getCurve().decodePoint(V), ecParams); } } bouncycastle-1.49.orig/src/org/bouncycastle/crypto/parsers/DHIESPublicKeyParser.java0000644000175000017500000000147512057262616030203 0ustar ebourgebourgpackage org.bouncycastle.crypto.parsers; import java.io.IOException; import java.io.InputStream; import java.math.BigInteger; import org.bouncycastle.crypto.KeyParser; import org.bouncycastle.crypto.params.AsymmetricKeyParameter; import org.bouncycastle.crypto.params.DHParameters; import org.bouncycastle.crypto.params.DHPublicKeyParameters; public class DHIESPublicKeyParser implements KeyParser { private DHParameters dhParams; public DHIESPublicKeyParser(DHParameters dhParams) { this.dhParams = dhParams; } public AsymmetricKeyParameter readKey(InputStream stream) throws IOException { byte[] V = new byte[(dhParams.getP().bitLength() + 7) / 8]; stream.read(V, 0, V.length); return new DHPublicKeyParameters(new BigInteger(1, V), dhParams); } } bouncycastle-1.49.orig/src/org/bouncycastle/crypto/AsymmetricCipherKeyPairGenerator.java0000644000175000017500000000111110262753175031273 0ustar ebourgebourgpackage org.bouncycastle.crypto; /** * interface that a public/private key pair generator should conform to. */ public interface AsymmetricCipherKeyPairGenerator { /** * intialise the key pair generator. * * @param param the parameters the key pair is to be initialised with. */ public void init(KeyGenerationParameters param); /** * return an AsymmetricCipherKeyPair containing the generated keys. * * @return an AsymmetricCipherKeyPair containing the generated keys. */ public AsymmetricCipherKeyPair generateKeyPair(); } bouncycastle-1.49.orig/src/org/bouncycastle/crypto/DerivationParameters.java0000644000175000017500000000021110262753175027017 0ustar ebourgebourgpackage org.bouncycastle.crypto; /** * Parameters for key/byte stream derivation classes */ public interface DerivationParameters { } bouncycastle-1.49.orig/src/org/bouncycastle/crypto/DerivationFunction.java0000644000175000017500000000066610262753175026517 0ustar ebourgebourgpackage org.bouncycastle.crypto; /** * base interface for general purpose byte derivation functions. */ public interface DerivationFunction { public void init(DerivationParameters param); /** * return the message digest used as the basis for the function */ public Digest getDigest(); public int generateBytes(byte[] out, int outOff, int len) throws DataLengthException, IllegalArgumentException; } bouncycastle-1.49.orig/src/org/bouncycastle/crypto/generators/0000755000175000017500000000000012152033551024170 5ustar ebourgebourgbouncycastle-1.49.orig/src/org/bouncycastle/crypto/generators/PKCS12ParametersGenerator.java0000644000175000017500000001370312125455251031642 0ustar ebourgebourgpackage org.bouncycastle.crypto.generators; import org.bouncycastle.crypto.CipherParameters; import org.bouncycastle.crypto.Digest; import org.bouncycastle.crypto.ExtendedDigest; import org.bouncycastle.crypto.PBEParametersGenerator; import org.bouncycastle.crypto.params.KeyParameter; import org.bouncycastle.crypto.params.ParametersWithIV; /** * Generator for PBE derived keys and ivs as defined by PKCS 12 V1.0. *

    * The document this implementation is based on can be found at * * RSA's PKCS12 Page */ public class PKCS12ParametersGenerator extends PBEParametersGenerator { public static final int KEY_MATERIAL = 1; public static final int IV_MATERIAL = 2; public static final int MAC_MATERIAL = 3; private Digest digest; private int u; private int v; /** * Construct a PKCS 12 Parameters generator. This constructor will * accept any digest which also implements ExtendedDigest. * * @param digest the digest to be used as the source of derived keys. * @exception IllegalArgumentException if an unknown digest is passed in. */ public PKCS12ParametersGenerator( Digest digest) { this.digest = digest; if (digest instanceof ExtendedDigest) { u = digest.getDigestSize(); v = ((ExtendedDigest)digest).getByteLength(); } else { throw new IllegalArgumentException("Digest " + digest.getAlgorithmName() + " unsupported"); } } /** * add a + b + 1, returning the result in a. The a value is treated * as a BigInteger of length (b.length * 8) bits. The result is * modulo 2^b.length in case of overflow. */ private void adjust( byte[] a, int aOff, byte[] b) { int x = (b[b.length - 1] & 0xff) + (a[aOff + b.length - 1] & 0xff) + 1; a[aOff + b.length - 1] = (byte)x; x >>>= 8; for (int i = b.length - 2; i >= 0; i--) { x += (b[i] & 0xff) + (a[aOff + i] & 0xff); a[aOff + i] = (byte)x; x >>>= 8; } } /** * generation of a derived key ala PKCS12 V1.0. */ private byte[] generateDerivedKey( int idByte, int n) { byte[] D = new byte[v]; byte[] dKey = new byte[n]; for (int i = 0; i != D.length; i++) { D[i] = (byte)idByte; } byte[] S; if ((salt != null) && (salt.length != 0)) { S = new byte[v * ((salt.length + v - 1) / v)]; for (int i = 0; i != S.length; i++) { S[i] = salt[i % salt.length]; } } else { S = new byte[0]; } byte[] P; if ((password != null) && (password.length != 0)) { P = new byte[v * ((password.length + v - 1) / v)]; for (int i = 0; i != P.length; i++) { P[i] = password[i % password.length]; } } else { P = new byte[0]; } byte[] I = new byte[S.length + P.length]; System.arraycopy(S, 0, I, 0, S.length); System.arraycopy(P, 0, I, S.length, P.length); byte[] B = new byte[v]; int c = (n + u - 1) / u; byte[] A = new byte[u]; for (int i = 1; i <= c; i++) { digest.update(D, 0, D.length); digest.update(I, 0, I.length); digest.doFinal(A, 0); for (int j = 1; j < iterationCount; j++) { digest.update(A, 0, A.length); digest.doFinal(A, 0); } for (int j = 0; j != B.length; j++) { B[j] = A[j % A.length]; } for (int j = 0; j != I.length / v; j++) { adjust(I, j * v, B); } if (i == c) { System.arraycopy(A, 0, dKey, (i - 1) * u, dKey.length - ((i - 1) * u)); } else { System.arraycopy(A, 0, dKey, (i - 1) * u, A.length); } } return dKey; } /** * Generate a key parameter derived from the password, salt, and iteration * count we are currently initialised with. * * @param keySize the size of the key we want (in bits) * @return a KeyParameter object. */ public CipherParameters generateDerivedParameters( int keySize) { keySize = keySize / 8; byte[] dKey = generateDerivedKey(KEY_MATERIAL, keySize); return new KeyParameter(dKey, 0, keySize); } /** * Generate a key with initialisation vector parameter derived from * the password, salt, and iteration count we are currently initialised * with. * * @param keySize the size of the key we want (in bits) * @param ivSize the size of the iv we want (in bits) * @return a ParametersWithIV object. */ public CipherParameters generateDerivedParameters( int keySize, int ivSize) { keySize = keySize / 8; ivSize = ivSize / 8; byte[] dKey = generateDerivedKey(KEY_MATERIAL, keySize); byte[] iv = generateDerivedKey(IV_MATERIAL, ivSize); return new ParametersWithIV(new KeyParameter(dKey, 0, keySize), iv, 0, ivSize); } /** * Generate a key parameter for use with a MAC derived from the password, * salt, and iteration count we are currently initialised with. * * @param keySize the size of the key we want (in bits) * @return a KeyParameter object. */ public CipherParameters generateDerivedMacParameters( int keySize) { keySize = keySize / 8; byte[] dKey = generateDerivedKey(MAC_MATERIAL, keySize); return new KeyParameter(dKey, 0, keySize); } } bouncycastle-1.49.orig/src/org/bouncycastle/crypto/generators/DSAKeyPairGenerator.java0000644000175000017500000000411611302450070030573 0ustar ebourgebourgpackage org.bouncycastle.crypto.generators; import org.bouncycastle.crypto.AsymmetricCipherKeyPair; import org.bouncycastle.crypto.AsymmetricCipherKeyPairGenerator; import org.bouncycastle.crypto.KeyGenerationParameters; import org.bouncycastle.crypto.params.DSAKeyGenerationParameters; import org.bouncycastle.crypto.params.DSAParameters; import org.bouncycastle.crypto.params.DSAPrivateKeyParameters; import org.bouncycastle.crypto.params.DSAPublicKeyParameters; import org.bouncycastle.util.BigIntegers; import java.math.BigInteger; import java.security.SecureRandom; /** * a DSA key pair generator. * * This generates DSA keys in line with the method described * in FIPS 186-3 B.1 FFC Key Pair Generation. */ public class DSAKeyPairGenerator implements AsymmetricCipherKeyPairGenerator { private static final BigInteger ONE = BigInteger.valueOf(1); private DSAKeyGenerationParameters param; public void init( KeyGenerationParameters param) { this.param = (DSAKeyGenerationParameters)param; } public AsymmetricCipherKeyPair generateKeyPair() { DSAParameters dsaParams = param.getParameters(); BigInteger x = generatePrivateKey(dsaParams.getQ(), param.getRandom()); BigInteger y = calculatePublicKey(dsaParams.getP(), dsaParams.getG(), x); return new AsymmetricCipherKeyPair( new DSAPublicKeyParameters(y, dsaParams), new DSAPrivateKeyParameters(x, dsaParams)); } private static BigInteger generatePrivateKey(BigInteger q, SecureRandom random) { // TODO Prefer this method? (change test cases that used fixed random) // B.1.1 Key Pair Generation Using Extra Random Bits // BigInteger c = new BigInteger(q.bitLength() + 64, random); // return c.mod(q.subtract(ONE)).add(ONE); // B.1.2 Key Pair Generation by Testing Candidates return BigIntegers.createRandomInRange(ONE, q.subtract(ONE), random); } private static BigInteger calculatePublicKey(BigInteger p, BigInteger g, BigInteger x) { return g.modPow(x, p); } } bouncycastle-1.49.orig/src/org/bouncycastle/crypto/generators/MGF1BytesGenerator.java0000644000175000017500000000535310427071732030417 0ustar ebourgebourgpackage org.bouncycastle.crypto.generators; import org.bouncycastle.crypto.DataLengthException; import org.bouncycastle.crypto.DerivationFunction; import org.bouncycastle.crypto.DerivationParameters; import org.bouncycastle.crypto.Digest; import org.bouncycastle.crypto.params.MGFParameters; /** * Generator for MGF1 as defined in PKCS 1v2 */ public class MGF1BytesGenerator implements DerivationFunction { private Digest digest; private byte[] seed; private int hLen; /** * @param digest the digest to be used as the source of generated bytes */ public MGF1BytesGenerator( Digest digest) { this.digest = digest; this.hLen = digest.getDigestSize(); } public void init( DerivationParameters param) { if (!(param instanceof MGFParameters)) { throw new IllegalArgumentException("MGF parameters required for MGF1Generator"); } MGFParameters p = (MGFParameters)param; seed = p.getSeed(); } /** * return the underlying digest. */ public Digest getDigest() { return digest; } /** * int to octet string. */ private void ItoOSP( int i, byte[] sp) { sp[0] = (byte)(i >>> 24); sp[1] = (byte)(i >>> 16); sp[2] = (byte)(i >>> 8); sp[3] = (byte)(i >>> 0); } /** * fill len bytes of the output buffer with bytes generated from * the derivation function. * * @throws DataLengthException if the out buffer is too small. */ public int generateBytes( byte[] out, int outOff, int len) throws DataLengthException, IllegalArgumentException { if ((out.length - len) < outOff) { throw new DataLengthException("output buffer too small"); } byte[] hashBuf = new byte[hLen]; byte[] C = new byte[4]; int counter = 0; digest.reset(); if (len > hLen) { do { ItoOSP(counter, C); digest.update(seed, 0, seed.length); digest.update(C, 0, C.length); digest.doFinal(hashBuf, 0); System.arraycopy(hashBuf, 0, out, outOff + counter * hLen, hLen); } while (++counter < (len / hLen)); } if ((counter * hLen) < len) { ItoOSP(counter, C); digest.update(seed, 0, seed.length); digest.update(C, 0, C.length); digest.doFinal(hashBuf, 0); System.arraycopy(hashBuf, 0, out, outOff + counter * hLen, len - (counter * hLen)); } return len; } } bouncycastle-1.49.orig/src/org/bouncycastle/crypto/generators/ECKeyPairGenerator.java0000644000175000017500000000321610262753175030473 0ustar ebourgebourgpackage org.bouncycastle.crypto.generators; import java.math.BigInteger; import java.security.SecureRandom; import org.bouncycastle.crypto.AsymmetricCipherKeyPair; import org.bouncycastle.crypto.AsymmetricCipherKeyPairGenerator; import org.bouncycastle.crypto.KeyGenerationParameters; import org.bouncycastle.crypto.params.ECDomainParameters; import org.bouncycastle.crypto.params.ECKeyGenerationParameters; import org.bouncycastle.crypto.params.ECPrivateKeyParameters; import org.bouncycastle.crypto.params.ECPublicKeyParameters; import org.bouncycastle.math.ec.ECConstants; import org.bouncycastle.math.ec.ECPoint; public class ECKeyPairGenerator implements AsymmetricCipherKeyPairGenerator, ECConstants { ECDomainParameters params; SecureRandom random; public void init( KeyGenerationParameters param) { ECKeyGenerationParameters ecP = (ECKeyGenerationParameters)param; this.random = ecP.getRandom(); this.params = ecP.getDomainParameters(); } /** * Given the domain parameters this routine generates an EC key * pair in accordance with X9.62 section 5.2.1 pages 26, 27. */ public AsymmetricCipherKeyPair generateKeyPair() { BigInteger n = params.getN(); int nBitLength = n.bitLength(); BigInteger d; do { d = new BigInteger(nBitLength, random); } while (d.equals(ZERO) || (d.compareTo(n) >= 0)); ECPoint Q = params.getG().multiply(d); return new AsymmetricCipherKeyPair( new ECPublicKeyParameters(Q, params), new ECPrivateKeyParameters(d, params)); } } bouncycastle-1.49.orig/src/org/bouncycastle/crypto/generators/DHParametersHelper.java0000644000175000017500000000353211526373423030526 0ustar ebourgebourgpackage org.bouncycastle.crypto.generators; import java.math.BigInteger; import java.security.SecureRandom; import org.bouncycastle.util.BigIntegers; class DHParametersHelper { private static final BigInteger ONE = BigInteger.valueOf(1); private static final BigInteger TWO = BigInteger.valueOf(2); /* * Finds a pair of prime BigInteger's {p, q: p = 2q + 1} * * (see: Handbook of Applied Cryptography 4.86) */ static BigInteger[] generateSafePrimes(int size, int certainty, SecureRandom random) { BigInteger p, q; int qLength = size - 1; for (;;) { q = new BigInteger(qLength, 2, random); // p <- 2q + 1 p = q.shiftLeft(1).add(ONE); if (p.isProbablePrime(certainty) && (certainty <= 2 || q.isProbablePrime(certainty))) { break; } } return new BigInteger[] { p, q }; } /* * Select a high order element of the multiplicative group Zp* * * p and q must be s.t. p = 2*q + 1, where p and q are prime (see generateSafePrimes) */ static BigInteger selectGenerator(BigInteger p, BigInteger q, SecureRandom random) { BigInteger pMinusTwo = p.subtract(TWO); BigInteger g; /* * (see: Handbook of Applied Cryptography 4.80) */ // do // { // g = BigIntegers.createRandomInRange(TWO, pMinusTwo, random); // } // while (g.modPow(TWO, p).equals(ONE) || g.modPow(q, p).equals(ONE)); /* * RFC 2631 2.2.1.2 (and see: Handbook of Applied Cryptography 4.81) */ do { BigInteger h = BigIntegers.createRandomInRange(TWO, pMinusTwo, random); g = h.modPow(TWO, p); } while (g.equals(ONE)); return g; } } bouncycastle-1.49.orig/src/org/bouncycastle/crypto/generators/RSAKeyPairGenerator.java0000644000175000017500000000752410726050775030640 0ustar ebourgebourgpackage org.bouncycastle.crypto.generators; import org.bouncycastle.crypto.AsymmetricCipherKeyPair; import org.bouncycastle.crypto.AsymmetricCipherKeyPairGenerator; import org.bouncycastle.crypto.KeyGenerationParameters; import org.bouncycastle.crypto.params.RSAKeyGenerationParameters; import org.bouncycastle.crypto.params.RSAKeyParameters; import org.bouncycastle.crypto.params.RSAPrivateCrtKeyParameters; import java.math.BigInteger; /** * an RSA key pair generator. */ public class RSAKeyPairGenerator implements AsymmetricCipherKeyPairGenerator { private static final BigInteger ONE = BigInteger.valueOf(1); private RSAKeyGenerationParameters param; public void init( KeyGenerationParameters param) { this.param = (RSAKeyGenerationParameters)param; } public AsymmetricCipherKeyPair generateKeyPair() { BigInteger p, q, n, d, e, pSub1, qSub1, phi; // // p and q values should have a length of half the strength in bits // int strength = param.getStrength(); int pbitlength = (strength + 1) / 2; int qbitlength = strength - pbitlength; int mindiffbits = strength / 3; e = param.getPublicExponent(); // TODO Consider generating safe primes for p, q (see DHParametersHelper.generateSafePrimes) // (then p-1 and q-1 will not consist of only small factors - see "Pollard's algorithm") // // generate p, prime and (p-1) relatively prime to e // for (;;) { p = new BigInteger(pbitlength, 1, param.getRandom()); if (p.mod(e).equals(ONE)) { continue; } if (!p.isProbablePrime(param.getCertainty())) { continue; } if (e.gcd(p.subtract(ONE)).equals(ONE)) { break; } } // // generate a modulus of the required length // for (;;) { // generate q, prime and (q-1) relatively prime to e, // and not equal to p // for (;;) { q = new BigInteger(qbitlength, 1, param.getRandom()); if (q.subtract(p).abs().bitLength() < mindiffbits) { continue; } if (q.mod(e).equals(ONE)) { continue; } if (!q.isProbablePrime(param.getCertainty())) { continue; } if (e.gcd(q.subtract(ONE)).equals(ONE)) { break; } } // // calculate the modulus // n = p.multiply(q); if (n.bitLength() == param.getStrength()) { break; } // // if we get here our primes aren't big enough, make the largest // of the two p and try again // p = p.max(q); } if (p.compareTo(q) < 0) { phi = p; p = q; q = phi; } pSub1 = p.subtract(ONE); qSub1 = q.subtract(ONE); phi = pSub1.multiply(qSub1); // // calculate the private exponent // d = e.modInverse(phi); // // calculate the CRT factors // BigInteger dP, dQ, qInv; dP = d.remainder(pSub1); dQ = d.remainder(qSub1); qInv = q.modInverse(p); return new AsymmetricCipherKeyPair( new RSAKeyParameters(false, n, e), new RSAPrivateCrtKeyParameters(n, e, d, p, q, dP, dQ, qInv)); } } bouncycastle-1.49.orig/src/org/bouncycastle/crypto/generators/GOST3410KeyPairGenerator.java0000644000175000017500000000353510542454120031261 0ustar ebourgebourgpackage org.bouncycastle.crypto.generators; import org.bouncycastle.crypto.AsymmetricCipherKeyPair; import org.bouncycastle.crypto.AsymmetricCipherKeyPairGenerator; import org.bouncycastle.crypto.KeyGenerationParameters; import org.bouncycastle.crypto.params.GOST3410KeyGenerationParameters; import org.bouncycastle.crypto.params.GOST3410Parameters; import org.bouncycastle.crypto.params.GOST3410PrivateKeyParameters; import org.bouncycastle.crypto.params.GOST3410PublicKeyParameters; import java.math.BigInteger; import java.security.SecureRandom; /** * a GOST3410 key pair generator. * This generates GOST3410 keys in line with the method described * in GOST R 34.10-94. */ public class GOST3410KeyPairGenerator implements AsymmetricCipherKeyPairGenerator { private static final BigInteger ZERO = BigInteger.valueOf(0); private GOST3410KeyGenerationParameters param; public void init( KeyGenerationParameters param) { this.param = (GOST3410KeyGenerationParameters)param; } public AsymmetricCipherKeyPair generateKeyPair() { BigInteger p, q, a, x, y; GOST3410Parameters GOST3410Params = param.getParameters(); SecureRandom random = param.getRandom(); q = GOST3410Params.getQ(); p = GOST3410Params.getP(); a = GOST3410Params.getA(); do { x = new BigInteger(256, random); } while (x.equals(ZERO) || x.compareTo(q) >= 0); // // calculate the public key. // y = a.modPow(x, p); return new AsymmetricCipherKeyPair( new GOST3410PublicKeyParameters(y, GOST3410Params), new GOST3410PrivateKeyParameters(x, GOST3410Params)); } } bouncycastle-1.49.orig/src/org/bouncycastle/crypto/generators/BaseKDFBytesGenerator.java0000644000175000017500000000754212132414272031121 0ustar ebourgebourgpackage org.bouncycastle.crypto.generators; import org.bouncycastle.crypto.DataLengthException; import org.bouncycastle.crypto.DerivationFunction; import org.bouncycastle.crypto.DerivationParameters; import org.bouncycastle.crypto.Digest; import org.bouncycastle.crypto.params.ISO18033KDFParameters; import org.bouncycastle.crypto.params.KDFParameters; import org.bouncycastle.crypto.util.Pack; /** * Basic KDF generator for derived keys and ivs as defined by IEEE P1363a/ISO * 18033
    * This implementation is based on ISO 18033/P1363a. */ public class BaseKDFBytesGenerator implements DerivationFunction { private int counterStart; private Digest digest; private byte[] shared; private byte[] iv; /** * Construct a KDF Parameters generator. *

    * * @param counterStart * value of counter. * @param digest * the digest to be used as the source of derived keys. */ protected BaseKDFBytesGenerator(int counterStart, Digest digest) { this.counterStart = counterStart; this.digest = digest; } public void init(DerivationParameters param) { if (param instanceof KDFParameters) { KDFParameters p = (KDFParameters)param; shared = p.getSharedSecret(); iv = p.getIV(); } else if (param instanceof ISO18033KDFParameters) { ISO18033KDFParameters p = (ISO18033KDFParameters)param; shared = p.getSeed(); iv = null; } else { throw new IllegalArgumentException("KDF parameters required for KDF2Generator"); } } /** * return the underlying digest. */ public Digest getDigest() { return digest; } /** * fill len bytes of the output buffer with bytes generated from the * derivation function. * * @throws IllegalArgumentException * if the size of the request will cause an overflow. * @throws DataLengthException * if the out buffer is too small. */ public int generateBytes(byte[] out, int outOff, int len) throws DataLengthException, IllegalArgumentException { if ((out.length - len) < outOff) { throw new DataLengthException("output buffer too small"); } long oBytes = len; int outLen = digest.getDigestSize(); // // this is at odds with the standard implementation, the // maximum value should be hBits * (2^32 - 1) where hBits // is the digest output size in bits. We can't have an // array with a long index at the moment... // if (oBytes > ((2L << 32) - 1)) { throw new IllegalArgumentException("Output length too large"); } int cThreshold = (int)((oBytes + outLen - 1) / outLen); byte[] dig = new byte[digest.getDigestSize()]; byte[] C = new byte[4]; Pack.intToBigEndian(counterStart, C, 0); int counterBase = counterStart & ~0xFF; for (int i = 0; i < cThreshold; i++) { digest.update(shared, 0, shared.length); digest.update(C, 0, C.length); if (iv != null) { digest.update(iv, 0, iv.length); } digest.doFinal(dig, 0); if (len > outLen) { System.arraycopy(dig, 0, out, outOff, outLen); outOff += outLen; len -= outLen; } else { System.arraycopy(dig, 0, out, outOff, len); } if (++C[3] == 0) { counterBase += 0x100; Pack.intToBigEndian(counterBase, C, 0); } } digest.reset(); return (int)oBytes; } } bouncycastle-1.49.orig/src/org/bouncycastle/crypto/generators/OpenSSLPBEParametersGenerator.java0000644000175000017500000000745310262753175032564 0ustar ebourgebourgpackage org.bouncycastle.crypto.generators; import org.bouncycastle.crypto.CipherParameters; import org.bouncycastle.crypto.Digest; import org.bouncycastle.crypto.PBEParametersGenerator; import org.bouncycastle.crypto.digests.MD5Digest; import org.bouncycastle.crypto.params.KeyParameter; import org.bouncycastle.crypto.params.ParametersWithIV; /** * Generator for PBE derived keys and ivs as usd by OpenSSL. *

    * The scheme is a simple extension of PKCS 5 V2.0 Scheme 1 using MD5 with an * iteration count of 1. *

    */ public class OpenSSLPBEParametersGenerator extends PBEParametersGenerator { private Digest digest = new MD5Digest(); /** * Construct a OpenSSL Parameters generator. */ public OpenSSLPBEParametersGenerator() { } /** * Initialise - note the iteration count for this algorithm is fixed at 1. * * @param password password to use. * @param salt salt to use. */ public void init( byte[] password, byte[] salt) { super.init(password, salt, 1); } /** * the derived key function, the ith hash of the password and the salt. */ private byte[] generateDerivedKey( int bytesNeeded) { byte[] buf = new byte[digest.getDigestSize()]; byte[] key = new byte[bytesNeeded]; int offset = 0; for (;;) { digest.update(password, 0, password.length); digest.update(salt, 0, salt.length); digest.doFinal(buf, 0); int len = (bytesNeeded > buf.length) ? buf.length : bytesNeeded; System.arraycopy(buf, 0, key, offset, len); offset += len; // check if we need any more bytesNeeded -= len; if (bytesNeeded == 0) { break; } // do another round digest.reset(); digest.update(buf, 0, buf.length); } return key; } /** * Generate a key parameter derived from the password, salt, and iteration * count we are currently initialised with. * * @param keySize the size of the key we want (in bits) * @return a KeyParameter object. * @exception IllegalArgumentException if the key length larger than the base hash size. */ public CipherParameters generateDerivedParameters( int keySize) { keySize = keySize / 8; byte[] dKey = generateDerivedKey(keySize); return new KeyParameter(dKey, 0, keySize); } /** * Generate a key with initialisation vector parameter derived from * the password, salt, and iteration count we are currently initialised * with. * * @param keySize the size of the key we want (in bits) * @param ivSize the size of the iv we want (in bits) * @return a ParametersWithIV object. * @exception IllegalArgumentException if keySize + ivSize is larger than the base hash size. */ public CipherParameters generateDerivedParameters( int keySize, int ivSize) { keySize = keySize / 8; ivSize = ivSize / 8; byte[] dKey = generateDerivedKey(keySize + ivSize); return new ParametersWithIV(new KeyParameter(dKey, 0, keySize), dKey, keySize, ivSize); } /** * Generate a key parameter for use with a MAC derived from the password, * salt, and iteration count we are currently initialised with. * * @param keySize the size of the key we want (in bits) * @return a KeyParameter object. * @exception IllegalArgumentException if the key length larger than the base hash size. */ public CipherParameters generateDerivedMacParameters( int keySize) { return generateDerivedParameters(keySize); } } bouncycastle-1.49.orig/src/org/bouncycastle/crypto/generators/ElGamalParametersGenerator.java0000644000175000017500000000222610645643535032250 0ustar ebourgebourgpackage org.bouncycastle.crypto.generators; import org.bouncycastle.crypto.params.ElGamalParameters; import java.math.BigInteger; import java.security.SecureRandom; public class ElGamalParametersGenerator { private int size; private int certainty; private SecureRandom random; public void init( int size, int certainty, SecureRandom random) { this.size = size; this.certainty = certainty; this.random = random; } /** * which generates the p and g values from the given parameters, * returning the ElGamalParameters object. *

    * Note: can take a while... */ public ElGamalParameters generateParameters() { // // find a safe prime p where p = 2*q + 1, where p and q are prime. // BigInteger[] safePrimes = DHParametersHelper.generateSafePrimes(size, certainty, random); BigInteger p = safePrimes[0]; BigInteger q = safePrimes[1]; BigInteger g = DHParametersHelper.selectGenerator(p, q, random); return new ElGamalParameters(p, g); } } bouncycastle-1.49.orig/src/org/bouncycastle/crypto/generators/GOST3410ParametersGenerator.java0000644000175000017500000003745110533203754032031 0ustar ebourgebourgpackage org.bouncycastle.crypto.generators; import org.bouncycastle.crypto.params.GOST3410Parameters; import org.bouncycastle.crypto.params.GOST3410ValidationParameters; import java.math.BigInteger; import java.security.SecureRandom; /** * generate suitable parameters for GOST3410. */ public class GOST3410ParametersGenerator { private int size; private int typeproc; private SecureRandom init_random; private static final BigInteger ONE = BigInteger.valueOf(1); private static final BigInteger TWO = BigInteger.valueOf(2); /** * initialise the key generator. * * @param size size of the key * @param typeproc type procedure A,B = 1; A',B' - else * @param random random byte source. */ public void init( int size, int typeproc, SecureRandom random) { this.size = size; this.typeproc = typeproc; this.init_random = random; } //Procedure A private int procedure_A(int x0, int c, BigInteger[] pq, int size) { //Verify and perform condition: 065536) { x0 = init_random.nextInt()/32768; } while((c<0 || c>65536) || (c/2==0)) { c = init_random.nextInt()/32768 + 1; } BigInteger C = new BigInteger(Integer.toString(c)); BigInteger constA16 = new BigInteger("19381"); //step1 BigInteger[] y = new BigInteger[1]; // begin length = 1 y[0] = new BigInteger(Integer.toString(x0)); //step 2 int[] t = new int[1]; // t - orders; begin length = 1 t[0] = size; int s = 0; for (int i=0; t[i]>=17; i++) { // extension array t int tmp_t[] = new int[t.length + 1]; /////////////// System.arraycopy(t,0,tmp_t,0,t.length); // extension t = new int[tmp_t.length]; // array t System.arraycopy(tmp_t, 0, t, 0, tmp_t.length); /////////////// t[i+1] = t[i]/2; s = i+1; } //step3 BigInteger p[] = new BigInteger[s+1]; p[s] = new BigInteger("8003",16); //set min prime number length 16 bit int m = s-1; //step4 for (int i=0; i=0) { break; //step 14 } else { pq[0] = p[0]; pq[1] = p[1]; return y[0].intValue(); //return for procedure B step 2 } } } return y[0].intValue(); } //Procedure A' private long procedure_Aa(long x0, long c, BigInteger[] pq, int size) { //Verify and perform condition: 04294967296L) { x0 = init_random.nextInt()*2; } while((c<0 || c>4294967296L) || (c/2==0)) { c = init_random.nextInt()*2+1; } BigInteger C = new BigInteger(Long.toString(c)); BigInteger constA32 = new BigInteger("97781173"); //step1 BigInteger[] y = new BigInteger[1]; // begin length = 1 y[0] = new BigInteger(Long.toString(x0)); //step 2 int[] t = new int[1]; // t - orders; begin length = 1 t[0] = size; int s = 0; for (int i=0; t[i]>=33; i++) { // extension array t int tmp_t[] = new int[t.length + 1]; /////////////// System.arraycopy(t,0,tmp_t,0,t.length); // extension t = new int[tmp_t.length]; // array t System.arraycopy(tmp_t, 0, t, 0, tmp_t.length); /////////////// t[i+1] = t[i]/2; s = i+1; } //step3 BigInteger p[] = new BigInteger[s+1]; p[s] = new BigInteger("8000000B",16); //set min prime number length 32 bit int m = s-1; //step4 for (int i=0; i=0) { break; //step 14 } else { pq[0] = p[0]; pq[1] = p[1]; return y[0].longValue(); //return for procedure B' step 2 } } } return y[0].longValue(); } //Procedure B private void procedure_B(int x0, int c, BigInteger[] pq) { //Verify and perform condition: 065536) { x0 = init_random.nextInt()/32768; } while((c<0 || c>65536) || (c/2==0)) { c = init_random.nextInt()/32768 + 1; } BigInteger [] qp = new BigInteger[2]; BigInteger q = null, Q = null, p = null; BigInteger C = new BigInteger(Integer.toString(c)); BigInteger constA16 = new BigInteger("19381"); //step1 x0 = procedure_A(x0, c, qp, 256); q = qp[0]; //step2 x0 = procedure_A(x0, c, qp, 512); Q = qp[0]; BigInteger[] y = new BigInteger[65]; y[0] = new BigInteger(Integer.toString(x0)); int tp = 1024; step3: for(;;) { //step 3 for (int j=0; j<64; j++) { y[j+1] = (y[j].multiply(constA16).add(C)).mod(TWO.pow(16)); } //step 4 BigInteger Y = new BigInteger("0"); for (int j=0; j<64; j++) { Y = Y.add(y[j].multiply(TWO.pow(16*j))); } y[0] = y[64]; //step 5 //step 6 BigInteger N = TWO.pow(tp-1).divide(q.multiply(Q)). add((TWO.pow(tp-1).multiply(Y)). divide(q.multiply(Q).multiply(TWO.pow(1024)))); if (N.mod(TWO).compareTo(ONE)==0) { N = N.add(ONE); } int k = 0; //step 7 step8: for(;;) { //step 11 p = q.multiply(Q).multiply(N.add(BigInteger.valueOf(k))).add(ONE); if (p.compareTo(TWO.pow(tp))==1) { continue step3; //step 9 } //step10 if ((TWO.modPow(q.multiply(Q).multiply(N.add(BigInteger.valueOf(k))),p).compareTo(ONE)==0) && (TWO.modPow(q.multiply(N.add(BigInteger.valueOf(k))),p).compareTo(ONE)!=0)) { pq[0] = p; pq[1] = q; return; } else { k += 2; continue step8; } } } } //Procedure B' private void procedure_Bb(long x0, long c, BigInteger[] pq) { //Verify and perform condition: 04294967296L) { x0 = init_random.nextInt()*2; } while((c<0 || c>4294967296L) || (c/2==0)) { c = init_random.nextInt()*2+1; } BigInteger [] qp = new BigInteger[2]; BigInteger q = null, Q = null, p = null; BigInteger C = new BigInteger(Long.toString(c)); BigInteger constA32 = new BigInteger("97781173"); //step1 x0 = procedure_Aa(x0, c, qp, 256); q = qp[0]; //step2 x0 = procedure_Aa(x0, c, qp, 512); Q = qp[0]; BigInteger[] y = new BigInteger[33]; y[0] = new BigInteger(Long.toString(x0)); int tp = 1024; step3: for(;;) { //step 3 for (int j=0; j<32; j++) { y[j+1] = (y[j].multiply(constA32).add(C)).mod(TWO.pow(32)); } //step 4 BigInteger Y = new BigInteger("0"); for (int j=0; j<32; j++) { Y = Y.add(y[j].multiply(TWO.pow(32*j))); } y[0] = y[32]; //step 5 //step 6 BigInteger N = TWO.pow(tp-1).divide(q.multiply(Q)). add((TWO.pow(tp-1).multiply(Y)). divide(q.multiply(Q).multiply(TWO.pow(1024)))); if (N.mod(TWO).compareTo(ONE)==0) { N = N.add(ONE); } int k = 0; //step 7 step8: for(;;) { //step 11 p = q.multiply(Q).multiply(N.add(BigInteger.valueOf(k))).add(ONE); if (p.compareTo(TWO.pow(tp))==1) { continue step3; //step 9 } //step10 if ((TWO.modPow(q.multiply(Q).multiply(N.add(BigInteger.valueOf(k))),p).compareTo(ONE)==0) && (TWO.modPow(q.multiply(N.add(BigInteger.valueOf(k))),p).compareTo(ONE)!=0)) { pq[0] = p; pq[1] = q; return; } else { k += 2; continue step8; } } } } /** * Procedure C * procedure generates the a value from the given p,q, * returning the a value. */ private BigInteger procedure_C(BigInteger p, BigInteger q) { BigInteger pSub1 = p.subtract(ONE); BigInteger pSub1DivQ = pSub1.divide(q); int length = p.bitLength(); for(;;) { BigInteger d = new BigInteger(length, init_random); // 1 < d < p-1 if (d.compareTo(ONE) > 0 && d.compareTo(pSub1) < 0) { BigInteger a = d.modPow(pSub1DivQ, p); if (a.compareTo(ONE) != 0) { return a; } } } } /** * which generates the p , q and a values from the given parameters, * returning the GOST3410Parameters object. */ public GOST3410Parameters generateParameters() { BigInteger [] pq = new BigInteger[2]; BigInteger q = null, p = null, a = null; int x0, c; long x0L, cL; if (typeproc==1) { x0 = init_random.nextInt(); c = init_random.nextInt(); switch(size) { case 512: procedure_A(x0, c, pq, 512); break; case 1024: procedure_B(x0, c, pq); break; default: throw new IllegalArgumentException("Ooops! key size 512 or 1024 bit."); } p = pq[0]; q = pq[1]; a = procedure_C(p, q); //System.out.println("p:"+p.toString(16)+"\n"+"q:"+q.toString(16)+"\n"+"a:"+a.toString(16)); //System.out.println("p:"+p+"\n"+"q:"+q+"\n"+"a:"+a); return new GOST3410Parameters(p, q, a, new GOST3410ValidationParameters(x0, c)); } else { x0L = init_random.nextLong(); cL = init_random.nextLong(); switch(size) { case 512: procedure_Aa(x0L, cL, pq, 512); break; case 1024: procedure_Bb(x0L, cL, pq); break; default: throw new IllegalStateException("Ooops! key size 512 or 1024 bit."); } p = pq[0]; q = pq[1]; a = procedure_C(p, q); //System.out.println("p:"+p.toString(16)+"\n"+"q:"+q.toString(16)+"\n"+"a:"+a.toString(16)); //System.out.println("p:"+p+"\n"+"q:"+q+"\n"+"a:"+a); return new GOST3410Parameters(p, q, a, new GOST3410ValidationParameters(x0L, cL)); } } } bouncycastle-1.49.orig/src/org/bouncycastle/crypto/generators/SCrypt.java0000644000175000017500000000733211732460603026271 0ustar ebourgebourgpackage org.bouncycastle.crypto.generators; import org.bouncycastle.crypto.PBEParametersGenerator; import org.bouncycastle.crypto.digests.SHA256Digest; import org.bouncycastle.crypto.engines.Salsa20Engine; import org.bouncycastle.crypto.params.KeyParameter; import org.bouncycastle.crypto.util.Pack; import org.bouncycastle.util.Arrays; public class SCrypt { // TODO Validate arguments public static byte[] generate(byte[] P, byte[] S, int N, int r, int p, int dkLen) { return MFcrypt(P, S, N, r, p, dkLen); } private static byte[] MFcrypt(byte[] P, byte[] S, int N, int r, int p, int dkLen) { int MFLenBytes = r * 128; byte[] bytes = SingleIterationPBKDF2(P, S, p * MFLenBytes); int[] B = null; try { int BLen = bytes.length >>> 2; B = new int[BLen]; Pack.littleEndianToInt(bytes, 0, B); int MFLenWords = MFLenBytes >>> 2; for (int BOff = 0; BOff < BLen; BOff += MFLenWords) { // TODO These can be done in parallel threads SMix(B, BOff, N, r); } Pack.intToLittleEndian(B, bytes, 0); return SingleIterationPBKDF2(P, bytes, dkLen); } finally { Clear(bytes); Clear(B); } } private static byte[] SingleIterationPBKDF2(byte[] P, byte[] S, int dkLen) { PBEParametersGenerator pGen = new PKCS5S2ParametersGenerator(new SHA256Digest()); pGen.init(P, S, 1); KeyParameter key = (KeyParameter) pGen.generateDerivedMacParameters(dkLen * 8); return key.getKey(); } private static void SMix(int[] B, int BOff, int N, int r) { int BCount = r * 32; int[] blockX1 = new int[16]; int[] blockX2 = new int[16]; int[] blockY = new int[BCount]; int[] X = new int[BCount]; int[][] V = new int[N][]; try { System.arraycopy(B, BOff, X, 0, BCount); for (int i = 0; i < N; ++i) { V[i] = Arrays.clone(X); BlockMix(X, blockX1, blockX2, blockY, r); } int mask = N - 1; for (int i = 0; i < N; ++i) { int j = X[BCount - 16] & mask; Xor(X, V[j], 0, X); BlockMix(X, blockX1, blockX2, blockY, r); } System.arraycopy(X, 0, B, BOff, BCount); } finally { ClearAll(V); ClearAll(new int[][]{ X, blockX1, blockX2, blockY }); } } private static void BlockMix(int[] B, int[] X1, int[] X2, int[] Y, int r) { System.arraycopy(B, B.length - 16, X1, 0, 16); int BOff = 0, YOff = 0, halfLen = B.length >>> 1; for (int i = 2 * r; i > 0; --i) { Xor(X1, B, BOff, X2); Salsa20Engine.salsaCore(8, X2, X1); System.arraycopy(X1, 0, Y, YOff, 16); YOff = halfLen + BOff - YOff; BOff += 16; } System.arraycopy(Y, 0, B, 0, Y.length); } private static void Xor(int[] a, int[] b, int bOff, int[] output) { for (int i = output.length - 1; i >= 0; --i) { output[i] = a[i] ^ b[bOff + i]; } } private static void Clear(byte[] array) { if (array != null) { Arrays.fill(array, (byte)0); } } private static void Clear(int[] array) { if (array != null) { Arrays.fill(array, 0); } } private static void ClearAll(int[][] arrays) { for (int i = 0; i < arrays.length; ++i) { Clear(arrays[i]); } } } bouncycastle-1.49.orig/src/org/bouncycastle/crypto/generators/HKDFBytesGenerator.java0000600000175000017500000001121012076514522030417 0ustar ebourgebourgpackage org.bouncycastle.crypto.generators; import org.bouncycastle.crypto.DataLengthException; import org.bouncycastle.crypto.DerivationFunction; import org.bouncycastle.crypto.DerivationParameters; import org.bouncycastle.crypto.Digest; import org.bouncycastle.crypto.macs.HMac; import org.bouncycastle.crypto.params.HKDFParameters; import org.bouncycastle.crypto.params.KeyParameter; /** * HMAC-based Extract-and-Expand Key Derivation Function (HKDF) implemented * according to IETF RFC 5869, May 2010 as specified by H. Krawczyk, IBM * Research & P. Eronen, Nokia. It uses a HMac internally to compute de OKM * (output keying material) and is likely to have better security properties * than KDF's based on just a hash function. */ public class HKDFBytesGenerator implements DerivationFunction { private HMac hMacHash; private int hashLen; private byte[] info; private byte[] currentT; private int generatedBytes; /** * Creates a HKDFBytesGenerator based on the given hash function. * * @param hash the digest to be used as the source of generatedBytes bytes */ public HKDFBytesGenerator(Digest hash) { this.hMacHash = new HMac(hash); this.hashLen = hash.getDigestSize(); } public void init(DerivationParameters param) { if (!(param instanceof HKDFParameters)) { throw new IllegalArgumentException( "HKDF parameters required for HKDFBytesGenerator"); } HKDFParameters params = (HKDFParameters)param; if (params.skipExtract()) { // use IKM directly as PRK hMacHash.init(new KeyParameter(params.getIKM())); } else { hMacHash.init(extract(params.getSalt(), params.getIKM())); } info = params.getInfo(); generatedBytes = 0; currentT = new byte[hashLen]; } /** * Performs the extract part of the key derivation function. * * @param salt the salt to use * @param ikm the input keying material * @return the PRK as KeyParameter */ private KeyParameter extract(byte[] salt, byte[] ikm) { hMacHash.init(new KeyParameter(ikm)); if (salt == null) { // TODO check if hashLen is indeed same as HMAC size hMacHash.init(new KeyParameter(new byte[hashLen])); } else { hMacHash.init(new KeyParameter(salt)); } hMacHash.update(ikm, 0, ikm.length); byte[] prk = new byte[hashLen]; hMacHash.doFinal(prk, 0); return new KeyParameter(prk); } /** * Performs the expand part of the key derivation function, using currentT * as input and output buffer. * * @throws DataLengthException if the total number of bytes generated is larger than the one * specified by RFC 5869 (255 * HashLen) */ private void expandNext() throws DataLengthException { int n = generatedBytes / hashLen + 1; if (n >= 256) { throw new DataLengthException( "HKDF cannot generate more than 255 blocks of HashLen size"); } // special case for T(0): T(0) is empty, so no update if (generatedBytes != 0) { hMacHash.update(currentT, 0, hashLen); } hMacHash.update(info, 0, info.length); hMacHash.update((byte)n); hMacHash.doFinal(currentT, 0); } public Digest getDigest() { return hMacHash.getUnderlyingDigest(); } public int generateBytes(byte[] out, int outOff, int len) throws DataLengthException, IllegalArgumentException { if (generatedBytes + len > 255 * hashLen) { throw new DataLengthException( "HKDF may only be used for 255 * HashLen bytes of output"); } if (generatedBytes % hashLen == 0) { expandNext(); } // copy what is left in the currentT (1..hash int toGenerate = len; int posInT = generatedBytes % hashLen; int leftInT = hashLen - generatedBytes % hashLen; int toCopy = Math.min(leftInT, toGenerate); System.arraycopy(currentT, posInT, out, outOff, toCopy); generatedBytes += toCopy; toGenerate -= toCopy; outOff += toCopy; while (toGenerate > 0) { expandNext(); toCopy = Math.min(hashLen, toGenerate); System.arraycopy(currentT, 0, out, outOff, toCopy); generatedBytes += toCopy; toGenerate -= toCopy; outOff += toCopy; } return len; } } bouncycastle-1.49.orig/src/org/bouncycastle/crypto/generators/DSTU4145KeyPairGenerator.java0000644000175000017500000000132600000000314031242 0ustar ebourgebourgpackage org.bouncycastle.crypto.generators; import org.bouncycastle.crypto.AsymmetricCipherKeyPair; import org.bouncycastle.crypto.params.ECPrivateKeyParameters; import org.bouncycastle.crypto.params.ECPublicKeyParameters; public class DSTU4145KeyPairGenerator extends ECKeyPairGenerator { public AsymmetricCipherKeyPair generateKeyPair() { AsymmetricCipherKeyPair pair = super.generateKeyPair(); ECPublicKeyParameters pub = (ECPublicKeyParameters)pair.getPublic(); ECPrivateKeyParameters priv = (ECPrivateKeyParameters)pair.getPrivate(); pub = new ECPublicKeyParameters(pub.getQ().negate(), pub.getParameters()); return new AsymmetricCipherKeyPair(pub, priv); } } bouncycastle-1.49.orig/src/org/bouncycastle/crypto/generators/RSABlindingFactorGenerator.java0000644000175000017500000000422210576162253032147 0ustar ebourgebourgpackage org.bouncycastle.crypto.generators; import org.bouncycastle.crypto.CipherParameters; import org.bouncycastle.crypto.params.ParametersWithRandom; import org.bouncycastle.crypto.params.RSAKeyParameters; import org.bouncycastle.crypto.params.RSAPrivateCrtKeyParameters; import java.math.BigInteger; import java.security.SecureRandom; /** * Generate a random factor suitable for use with RSA blind signatures * as outlined in Chaum's blinding and unblinding as outlined in * "Handbook of Applied Cryptography", page 475. */ public class RSABlindingFactorGenerator { private static BigInteger ZERO = BigInteger.valueOf(0); private static BigInteger ONE = BigInteger.valueOf(1); private RSAKeyParameters key; private SecureRandom random; /** * Initialise the factor generator * * @param param the necessary RSA key parameters. */ public void init( CipherParameters param) { if (param instanceof ParametersWithRandom) { ParametersWithRandom rParam = (ParametersWithRandom)param; key = (RSAKeyParameters)rParam.getParameters(); random = rParam.getRandom(); } else { key = (RSAKeyParameters)param; random = new SecureRandom(); } if (key instanceof RSAPrivateCrtKeyParameters) { throw new IllegalArgumentException("generator requires RSA public key"); } } /** * Generate a suitable blind factor for the public key the generator was initialised with. * * @return a random blind factor */ public BigInteger generateBlindingFactor() { if (key == null) { throw new IllegalStateException("generator not initialised"); } BigInteger m = key.getModulus(); int length = m.bitLength() - 1; // must be less than m.bitLength() BigInteger factor; BigInteger gcd; do { factor = new BigInteger(length, random); gcd = factor.gcd(m); } while (factor.equals(ZERO) || factor.equals(ONE) || !gcd.equals(ONE)); return factor; } } bouncycastle-1.49.orig/src/org/bouncycastle/crypto/generators/PKCS5S1ParametersGenerator.java0000644000175000017500000000733710262753175032004 0ustar ebourgebourgpackage org.bouncycastle.crypto.generators; import org.bouncycastle.crypto.CipherParameters; import org.bouncycastle.crypto.Digest; import org.bouncycastle.crypto.PBEParametersGenerator; import org.bouncycastle.crypto.params.KeyParameter; import org.bouncycastle.crypto.params.ParametersWithIV; /** * Generator for PBE derived keys and ivs as defined by PKCS 5 V2.0 Scheme 1. * Note this generator is limited to the size of the hash produced by the * digest used to drive it. *

    * The document this implementation is based on can be found at * * RSA's PKCS5 Page */ public class PKCS5S1ParametersGenerator extends PBEParametersGenerator { private Digest digest; /** * Construct a PKCS 5 Scheme 1 Parameters generator. * * @param digest the digest to be used as the source of derived keys. */ public PKCS5S1ParametersGenerator( Digest digest) { this.digest = digest; } /** * the derived key function, the ith hash of the password and the salt. */ private byte[] generateDerivedKey() { byte[] digestBytes = new byte[digest.getDigestSize()]; digest.update(password, 0, password.length); digest.update(salt, 0, salt.length); digest.doFinal(digestBytes, 0); for (int i = 1; i < iterationCount; i++) { digest.update(digestBytes, 0, digestBytes.length); digest.doFinal(digestBytes, 0); } return digestBytes; } /** * Generate a key parameter derived from the password, salt, and iteration * count we are currently initialised with. * * @param keySize the size of the key we want (in bits) * @return a KeyParameter object. * @exception IllegalArgumentException if the key length larger than the base hash size. */ public CipherParameters generateDerivedParameters( int keySize) { keySize = keySize / 8; if (keySize > digest.getDigestSize()) { throw new IllegalArgumentException( "Can't generate a derived key " + keySize + " bytes long."); } byte[] dKey = generateDerivedKey(); return new KeyParameter(dKey, 0, keySize); } /** * Generate a key with initialisation vector parameter derived from * the password, salt, and iteration count we are currently initialised * with. * * @param keySize the size of the key we want (in bits) * @param ivSize the size of the iv we want (in bits) * @return a ParametersWithIV object. * @exception IllegalArgumentException if keySize + ivSize is larger than the base hash size. */ public CipherParameters generateDerivedParameters( int keySize, int ivSize) { keySize = keySize / 8; ivSize = ivSize / 8; if ((keySize + ivSize) > digest.getDigestSize()) { throw new IllegalArgumentException( "Can't generate a derived key " + (keySize + ivSize) + " bytes long."); } byte[] dKey = generateDerivedKey(); return new ParametersWithIV(new KeyParameter(dKey, 0, keySize), dKey, keySize, ivSize); } /** * Generate a key parameter for use with a MAC derived from the password, * salt, and iteration count we are currently initialised with. * * @param keySize the size of the key we want (in bits) * @return a KeyParameter object. * @exception IllegalArgumentException if the key length larger than the base hash size. */ public CipherParameters generateDerivedMacParameters( int keySize) { return generateDerivedParameters(keySize); } } bouncycastle-1.49.orig/src/org/bouncycastle/crypto/generators/DHKeyPairGenerator.java0000644000175000017500000000257611160037207030474 0ustar ebourgebourgpackage org.bouncycastle.crypto.generators; import org.bouncycastle.crypto.AsymmetricCipherKeyPair; import org.bouncycastle.crypto.AsymmetricCipherKeyPairGenerator; import org.bouncycastle.crypto.KeyGenerationParameters; import org.bouncycastle.crypto.params.DHKeyGenerationParameters; import org.bouncycastle.crypto.params.DHParameters; import org.bouncycastle.crypto.params.DHPrivateKeyParameters; import org.bouncycastle.crypto.params.DHPublicKeyParameters; import java.math.BigInteger; /** * a Diffie-Hellman key pair generator. * * This generates keys consistent for use in the MTI/A0 key agreement protocol * as described in "Handbook of Applied Cryptography", Pages 516-519. */ public class DHKeyPairGenerator implements AsymmetricCipherKeyPairGenerator { private DHKeyGenerationParameters param; public void init( KeyGenerationParameters param) { this.param = (DHKeyGenerationParameters)param; } public AsymmetricCipherKeyPair generateKeyPair() { DHKeyGeneratorHelper helper = DHKeyGeneratorHelper.INSTANCE; DHParameters dhp = param.getParameters(); BigInteger x = helper.calculatePrivate(dhp, param.getRandom()); BigInteger y = helper.calculatePublic(dhp, x); return new AsymmetricCipherKeyPair( new DHPublicKeyParameters(y, dhp), new DHPrivateKeyParameters(x, dhp)); } } bouncycastle-1.49.orig/src/org/bouncycastle/crypto/generators/DESKeyGenerator.java0000644000175000017500000000246011155657537030012 0ustar ebourgebourgpackage org.bouncycastle.crypto.generators; import org.bouncycastle.crypto.CipherKeyGenerator; import org.bouncycastle.crypto.KeyGenerationParameters; import org.bouncycastle.crypto.params.DESParameters; public class DESKeyGenerator extends CipherKeyGenerator { /** * initialise the key generator - if strength is set to zero * the key generated will be 64 bits in size, otherwise * strength can be 64 or 56 bits (if you don't count the parity bits). * * @param param the parameters to be used for key generation */ public void init( KeyGenerationParameters param) { super.init(param); if (strength == 0 || strength == (56 / 8)) { strength = DESParameters.DES_KEY_LENGTH; } else if (strength != DESParameters.DES_KEY_LENGTH) { throw new IllegalArgumentException("DES key must be " + (DESParameters.DES_KEY_LENGTH * 8) + " bits long."); } } public byte[] generateKey() { byte[] newKey = new byte[DESParameters.DES_KEY_LENGTH]; do { random.nextBytes(newKey); DESParameters.setOddParity(newKey); } while (DESParameters.isWeakKey(newKey, 0)); return newKey; } } bouncycastle-1.49.orig/src/org/bouncycastle/crypto/generators/KDF1BytesGenerator.java0000644000175000017500000000103610427071732030404 0ustar ebourgebourgpackage org.bouncycastle.crypto.generators; import org.bouncycastle.crypto.Digest; /** * KDF1 generator for derived keys and ivs as defined by IEEE P1363a/ISO 18033 *
    * This implementation is based on ISO 18033/IEEE P1363a. */ public class KDF1BytesGenerator extends BaseKDFBytesGenerator { /** * Construct a KDF1 byte generator. *

    * @param digest the digest to be used as the source of derived keys. */ public KDF1BytesGenerator( Digest digest) { super(0, digest); } } bouncycastle-1.49.orig/src/org/bouncycastle/crypto/generators/KDF2BytesGenerator.java0000644000175000017500000000120211634006252030374 0ustar ebourgebourgpackage org.bouncycastle.crypto.generators; import org.bouncycastle.crypto.Digest; /** * KDF2 generator for derived keys and ivs as defined by IEEE P1363a/ISO 18033 *
    * This implementation is based on IEEE P1363/ISO 18033. */ public class KDF2BytesGenerator extends BaseKDFBytesGenerator { /** * Construct a KDF2 bytes generator. Generates key material * according to IEEE P1363 or ISO 18033 depending on the initialisation. *

    * @param digest the digest to be used as the source of derived keys. */ public KDF2BytesGenerator( Digest digest) { super(1, digest); } } bouncycastle-1.49.orig/src/org/bouncycastle/crypto/generators/ElGamalKeyPairGenerator.java0000644000175000017500000000303711272214755031505 0ustar ebourgebourgpackage org.bouncycastle.crypto.generators; import java.math.BigInteger; import org.bouncycastle.crypto.AsymmetricCipherKeyPair; import org.bouncycastle.crypto.AsymmetricCipherKeyPairGenerator; import org.bouncycastle.crypto.KeyGenerationParameters; import org.bouncycastle.crypto.params.DHParameters; import org.bouncycastle.crypto.params.ElGamalKeyGenerationParameters; import org.bouncycastle.crypto.params.ElGamalParameters; import org.bouncycastle.crypto.params.ElGamalPrivateKeyParameters; import org.bouncycastle.crypto.params.ElGamalPublicKeyParameters; /** * a ElGamal key pair generator. *

    * This generates keys consistent for use with ElGamal as described in * page 164 of "Handbook of Applied Cryptography". */ public class ElGamalKeyPairGenerator implements AsymmetricCipherKeyPairGenerator { private ElGamalKeyGenerationParameters param; public void init( KeyGenerationParameters param) { this.param = (ElGamalKeyGenerationParameters)param; } public AsymmetricCipherKeyPair generateKeyPair() { DHKeyGeneratorHelper helper = DHKeyGeneratorHelper.INSTANCE; ElGamalParameters egp = param.getParameters(); DHParameters dhp = new DHParameters(egp.getP(), egp.getG(), null, egp.getL()); BigInteger x = helper.calculatePrivate(dhp, param.getRandom()); BigInteger y = helper.calculatePublic(dhp, x); return new AsymmetricCipherKeyPair( new ElGamalPublicKeyParameters(y, egp), new ElGamalPrivateKeyParameters(x, egp)); } } bouncycastle-1.49.orig/src/org/bouncycastle/crypto/generators/DHKeyGeneratorHelper.java0000644000175000017500000000240311160037207031005 0ustar ebourgebourgpackage org.bouncycastle.crypto.generators; import java.math.BigInteger; import java.security.SecureRandom; import org.bouncycastle.crypto.params.DHParameters; import org.bouncycastle.util.BigIntegers; class DHKeyGeneratorHelper { static final DHKeyGeneratorHelper INSTANCE = new DHKeyGeneratorHelper(); private static final BigInteger ONE = BigInteger.valueOf(1); private static final BigInteger TWO = BigInteger.valueOf(2); private DHKeyGeneratorHelper() { } BigInteger calculatePrivate(DHParameters dhParams, SecureRandom random) { BigInteger p = dhParams.getP(); int limit = dhParams.getL(); if (limit != 0) { return new BigInteger(limit, random).setBit(limit - 1); } BigInteger min = TWO; int m = dhParams.getM(); if (m != 0) { min = ONE.shiftLeft(m - 1); } BigInteger max = p.subtract(TWO); BigInteger q = dhParams.getQ(); if (q != null) { max = q.subtract(TWO); } return BigIntegers.createRandomInRange(min, max, random); } BigInteger calculatePublic(DHParameters dhParams, BigInteger x) { return dhParams.getG().modPow(x, dhParams.getP()); } } bouncycastle-1.49.orig/src/org/bouncycastle/crypto/generators/PKCS5S2ParametersGenerator.java0000644000175000017500000001015312151251423031757 0ustar ebourgebourgpackage org.bouncycastle.crypto.generators; import org.bouncycastle.crypto.CipherParameters; import org.bouncycastle.crypto.Digest; import org.bouncycastle.crypto.Mac; import org.bouncycastle.crypto.PBEParametersGenerator; import org.bouncycastle.crypto.digests.SHA1Digest; import org.bouncycastle.crypto.macs.HMac; import org.bouncycastle.crypto.params.KeyParameter; import org.bouncycastle.crypto.params.ParametersWithIV; /** * Generator for PBE derived keys and ivs as defined by PKCS 5 V2.0 Scheme 2. * This generator uses a SHA-1 HMac as the calculation function. *

    * The document this implementation is based on can be found at * * RSA's PKCS5 Page */ public class PKCS5S2ParametersGenerator extends PBEParametersGenerator { private Mac hMac; private byte[] state; /** * construct a PKCS5 Scheme 2 Parameters generator. */ public PKCS5S2ParametersGenerator() { this(new SHA1Digest()); } public PKCS5S2ParametersGenerator(Digest digest) { hMac = new HMac(digest); state = new byte[hMac.getMacSize()]; } private void F( byte[] S, int c, byte[] iBuf, byte[] out, int outOff) { if (c == 0) { throw new IllegalArgumentException("iteration count must be at least 1."); } if (S != null) { hMac.update(S, 0, S.length); } hMac.update(iBuf, 0, iBuf.length); hMac.doFinal(state, 0); System.arraycopy(state, 0, out, outOff, state.length); for (int count = 1; count < c; count++) { hMac.update(state, 0, state.length); hMac.doFinal(state, 0); for (int j = 0; j != state.length; j++) { out[outOff + j] ^= state[j]; } } } private byte[] generateDerivedKey( int dkLen) { int hLen = hMac.getMacSize(); int l = (dkLen + hLen - 1) / hLen; byte[] iBuf = new byte[4]; byte[] outBytes = new byte[l * hLen]; int outPos = 0; CipherParameters param = new KeyParameter(password); hMac.init(param); for (int i = 1; i <= l; i++) { // Increment the value in 'iBuf' int pos = 3; while (++iBuf[pos] == 0) { --pos; } F(salt, iterationCount, iBuf, outBytes, outPos); outPos += hLen; } return outBytes; } /** * Generate a key parameter derived from the password, salt, and iteration * count we are currently initialised with. * * @param keySize the size of the key we want (in bits) * @return a KeyParameter object. */ public CipherParameters generateDerivedParameters( int keySize) { keySize = keySize / 8; byte[] dKey = generateDerivedKey(keySize); return new KeyParameter(dKey, 0, keySize); } /** * Generate a key with initialisation vector parameter derived from * the password, salt, and iteration count we are currently initialised * with. * * @param keySize the size of the key we want (in bits) * @param ivSize the size of the iv we want (in bits) * @return a ParametersWithIV object. */ public CipherParameters generateDerivedParameters( int keySize, int ivSize) { keySize = keySize / 8; ivSize = ivSize / 8; byte[] dKey = generateDerivedKey(keySize + ivSize); return new ParametersWithIV(new KeyParameter(dKey, 0, keySize), dKey, keySize, ivSize); } /** * Generate a key parameter for use with a MAC derived from the password, * salt, and iteration count we are currently initialised with. * * @param keySize the size of the key we want (in bits) * @return a KeyParameter object. */ public CipherParameters generateDerivedMacParameters( int keySize) { return generateDerivedParameters(keySize); } } bouncycastle-1.49.orig/src/org/bouncycastle/crypto/generators/NaccacheSternKeyPairGenerator.java0000644000175000017500000002625710576162253032716 0ustar ebourgebourgpackage org.bouncycastle.crypto.generators; import org.bouncycastle.crypto.AsymmetricCipherKeyPair; import org.bouncycastle.crypto.AsymmetricCipherKeyPairGenerator; import org.bouncycastle.crypto.KeyGenerationParameters; import org.bouncycastle.crypto.params.NaccacheSternKeyGenerationParameters; import org.bouncycastle.crypto.params.NaccacheSternKeyParameters; import org.bouncycastle.crypto.params.NaccacheSternPrivateKeyParameters; import java.math.BigInteger; import java.security.SecureRandom; import java.util.Vector; /** * Key generation parameters for NaccacheStern cipher. For details on this cipher, please see * * http://www.gemplus.com/smart/rd/publications/pdf/NS98pkcs.pdf */ public class NaccacheSternKeyPairGenerator implements AsymmetricCipherKeyPairGenerator { private static int[] smallPrimes = { 3, 5, 7, 11, 13, 17, 19, 23, 29, 31, 37, 41, 43, 47, 53, 59, 61, 67, 71, 73, 79, 83, 89, 97, 101, 103, 107, 109, 113, 127, 131, 137, 139, 149, 151, 157, 163, 167, 173, 179, 181, 191, 193, 197, 199, 211, 223, 227, 229, 233, 239, 241, 251, 257, 263, 269, 271, 277, 281, 283, 293, 307, 311, 313, 317, 331, 337, 347, 349, 353, 359, 367, 373, 379, 383, 389, 397, 401, 409, 419, 421, 431, 433, 439, 443, 449, 457, 461, 463, 467, 479, 487, 491, 499, 503, 509, 521, 523, 541, 547, 557 }; private NaccacheSternKeyGenerationParameters param; private static final BigInteger ONE = BigInteger.valueOf(1); // JDK 1.1 compatibility /* * (non-Javadoc) * * @see org.bouncycastle.crypto.AsymmetricCipherKeyPairGenerator#init(org.bouncycastle.crypto.KeyGenerationParameters) */ public void init(KeyGenerationParameters param) { this.param = (NaccacheSternKeyGenerationParameters)param; } /* * (non-Javadoc) * * @see org.bouncycastle.crypto.AsymmetricCipherKeyPairGenerator#generateKeyPair() */ public AsymmetricCipherKeyPair generateKeyPair() { int strength = param.getStrength(); SecureRandom rand = param.getRandom(); int certainty = param.getCertainty(); boolean debug = param.isDebug(); if (debug) { System.out.println("Fetching first " + param.getCntSmallPrimes() + " primes."); } Vector smallPrimes = findFirstPrimes(param.getCntSmallPrimes()); smallPrimes = permuteList(smallPrimes, rand); BigInteger u = ONE; BigInteger v = ONE; for (int i = 0; i < smallPrimes.size() / 2; i++) { u = u.multiply((BigInteger)smallPrimes.elementAt(i)); } for (int i = smallPrimes.size() / 2; i < smallPrimes.size(); i++) { v = v.multiply((BigInteger)smallPrimes.elementAt(i)); } BigInteger sigma = u.multiply(v); // n = (2 a u p_ + 1 ) ( 2 b v q_ + 1) // -> |n| = strength // |2| = 1 in bits // -> |a| * |b| = |n| - |u| - |v| - |p_| - |q_| - |2| -|2| // remainingStrength = strength - sigma.bitLength() - p_.bitLength() - // q_.bitLength() - 1 -1 int remainingStrength = strength - sigma.bitLength() - 48; BigInteger a = generatePrime(remainingStrength / 2 + 1, certainty, rand); BigInteger b = generatePrime(remainingStrength / 2 + 1, certainty, rand); BigInteger p_; BigInteger q_; BigInteger p; BigInteger q; long tries = 0; if (debug) { System.out.println("generating p and q"); } BigInteger _2au = a.multiply(u).shiftLeft(1); BigInteger _2bv = b.multiply(v).shiftLeft(1); for (;;) { tries++; p_ = generatePrime(24, certainty, rand); p = p_.multiply(_2au).add(ONE); if (!p.isProbablePrime(certainty)) { continue; } for (;;) { q_ = generatePrime(24, certainty, rand); if (p_.equals(q_)) { continue; } q = q_.multiply(_2bv).add(ONE); if (q.isProbablePrime(certainty)) { break; } } if (!sigma.gcd(p_.multiply(q_)).equals(ONE)) { // System.out.println("sigma.gcd(p_.mult(q_)) != 1!\n p_: " + p_ // +"\n q_: "+ q_ ); continue; } if (p.multiply(q).bitLength() < strength) { if (debug) { System.out.println("key size too small. Should be " + strength + " but is actually " + p.multiply(q).bitLength()); } continue; } break; } if (debug) { System.out.println("needed " + tries + " tries to generate p and q."); } BigInteger n = p.multiply(q); BigInteger phi_n = p.subtract(ONE).multiply(q.subtract(ONE)); BigInteger g; tries = 0; if (debug) { System.out.println("generating g"); } for (;;) { Vector gParts = new Vector(); for (int ind = 0; ind != smallPrimes.size(); ind++) { BigInteger i = (BigInteger)smallPrimes.elementAt(ind); BigInteger e = phi_n.divide(i); for (;;) { tries++; g = new BigInteger(strength, certainty, rand); if (g.modPow(e, n).equals(ONE)) { continue; } gParts.addElement(g); break; } } g = ONE; for (int i = 0; i < smallPrimes.size(); i++) { g = g.multiply(((BigInteger)gParts.elementAt(i)).modPow(sigma.divide((BigInteger)smallPrimes.elementAt(i)), n)).mod(n); } // make sure that g is not divisible by p_i or q_i boolean divisible = false; for (int i = 0; i < smallPrimes.size(); i++) { if (g.modPow(phi_n.divide((BigInteger)smallPrimes.elementAt(i)), n).equals(ONE)) { if (debug) { System.out.println("g has order phi(n)/" + smallPrimes.elementAt(i) + "\n g: " + g); } divisible = true; break; } } if (divisible) { continue; } // make sure that g has order > phi_n/4 if (g.modPow(phi_n.divide(BigInteger.valueOf(4)), n).equals(ONE)) { if (debug) { System.out.println("g has order phi(n)/4\n g:" + g); } continue; } if (g.modPow(phi_n.divide(p_), n).equals(ONE)) { if (debug) { System.out.println("g has order phi(n)/p'\n g: " + g); } continue; } if (g.modPow(phi_n.divide(q_), n).equals(ONE)) { if (debug) { System.out.println("g has order phi(n)/q'\n g: " + g); } continue; } if (g.modPow(phi_n.divide(a), n).equals(ONE)) { if (debug) { System.out.println("g has order phi(n)/a\n g: " + g); } continue; } if (g.modPow(phi_n.divide(b), n).equals(ONE)) { if (debug) { System.out.println("g has order phi(n)/b\n g: " + g); } continue; } break; } if (debug) { System.out.println("needed " + tries + " tries to generate g"); System.out.println(); System.out.println("found new NaccacheStern cipher variables:"); System.out.println("smallPrimes: " + smallPrimes); System.out.println("sigma:...... " + sigma + " (" + sigma.bitLength() + " bits)"); System.out.println("a:.......... " + a); System.out.println("b:.......... " + b); System.out.println("p':......... " + p_); System.out.println("q':......... " + q_); System.out.println("p:.......... " + p); System.out.println("q:.......... " + q); System.out.println("n:.......... " + n); System.out.println("phi(n):..... " + phi_n); System.out.println("g:.......... " + g); System.out.println(); } return new AsymmetricCipherKeyPair(new NaccacheSternKeyParameters(false, g, n, sigma.bitLength()), new NaccacheSternPrivateKeyParameters(g, n, sigma.bitLength(), smallPrimes, phi_n)); } private static BigInteger generatePrime( int bitLength, int certainty, SecureRandom rand) { BigInteger p_ = new BigInteger(bitLength, certainty, rand); while (p_.bitLength() != bitLength) { p_ = new BigInteger(bitLength, certainty, rand); } return p_; } /** * Generates a permuted ArrayList from the original one. The original List * is not modified * * @param arr * the ArrayList to be permuted * @param rand * the source of Randomness for permutation * @return a new ArrayList with the permuted elements. */ private static Vector permuteList( Vector arr, SecureRandom rand) { Vector retval = new Vector(); Vector tmp = new Vector(); for (int i = 0; i < arr.size(); i++) { tmp.addElement(arr.elementAt(i)); } retval.addElement(tmp.elementAt(0)); tmp.removeElementAt(0); while (tmp.size() != 0) { retval.insertElementAt(tmp.elementAt(0), getInt(rand, retval.size() + 1)); tmp.removeElementAt(0); } return retval; } private static int getInt( SecureRandom rand, int n) { if ((n & -n) == n) { return (int)((n * (long)(rand.nextInt() & 0x7fffffff)) >> 31); } int bits, val; do { bits = rand.nextInt() & 0x7fffffff; val = bits % n; } while (bits - val + (n-1) < 0); return val; } /** * Finds the first 'count' primes starting with 3 * * @param count * the number of primes to find * @return a vector containing the found primes as Integer */ private static Vector findFirstPrimes( int count) { Vector primes = new Vector(count); for (int i = 0; i != count; i++) { primes.addElement(BigInteger.valueOf(smallPrimes[i])); } return primes; } } bouncycastle-1.49.orig/src/org/bouncycastle/crypto/generators/DSAParametersGenerator.java0000644000175000017500000003043712143666206031355 0ustar ebourgebourgpackage org.bouncycastle.crypto.generators; import java.math.BigInteger; import java.security.SecureRandom; import org.bouncycastle.crypto.Digest; import org.bouncycastle.crypto.digests.SHA1Digest; import org.bouncycastle.crypto.params.DSAParameterGenerationParameters; import org.bouncycastle.crypto.params.DSAParameters; import org.bouncycastle.crypto.params.DSAValidationParameters; import org.bouncycastle.util.Arrays; import org.bouncycastle.util.BigIntegers; import org.bouncycastle.util.encoders.Hex; /** * Generate suitable parameters for DSA, in line with FIPS 186-2, or FIPS 186-3. */ public class DSAParametersGenerator { private Digest digest; private int L, N; private int certainty; private SecureRandom random; private static final BigInteger ZERO = BigInteger.valueOf(0); private static final BigInteger ONE = BigInteger.valueOf(1); private static final BigInteger TWO = BigInteger.valueOf(2); private boolean use186_3; private int usageIndex; public DSAParametersGenerator() { this(new SHA1Digest()); } public DSAParametersGenerator(Digest digest) { this.digest = digest; } /** * initialise the key generator. * * @param size size of the key (range 2^512 -> 2^1024 - 64 bit increments) * @param certainty measure of robustness of prime (for FIPS 186-2 compliance this should be at least 80). * @param random random byte source. */ public void init( int size, int certainty, SecureRandom random) { this.use186_3 = false; this.L = size; this.N = getDefaultN(size); this.certainty = certainty; this.random = random; } /** * Initialise the key generator for DSA 2. *

    * Use this init method if you need to generate parameters for DSA 2 keys. *

    * * @param params DSA 2 key generation parameters. */ public void init( DSAParameterGenerationParameters params) { // TODO Should we enforce the minimum 'certainty' values as per C.3 Table C.1? this.use186_3 = true; this.L = params.getL(); this.N = params.getN(); this.certainty = params.getCertainty(); this.random = params.getRandom(); this.usageIndex = params.getUsageIndex(); if ((L < 1024 || L > 3072) || L % 1024 != 0) { throw new IllegalArgumentException("L values must be between 1024 and 3072 and a multiple of 1024"); } else if (L == 1024 && N != 160) { throw new IllegalArgumentException("N must be 160 for L = 1024"); } else if (L == 2048 && (N != 224 && N != 256)) { throw new IllegalArgumentException("N must be 224 or 256 for L = 2048"); } else if (L == 3072 && N != 256) { throw new IllegalArgumentException("N must be 256 for L = 3072"); } if (digest.getDigestSize() * 8 < N) { throw new IllegalStateException("Digest output size too small for value of N"); } } /** * which generates the p and g values from the given parameters, * returning the DSAParameters object. *

    * Note: can take a while... */ public DSAParameters generateParameters() { return (use186_3) ? generateParameters_FIPS186_3() : generateParameters_FIPS186_2(); } private DSAParameters generateParameters_FIPS186_2() { byte[] seed = new byte[20]; byte[] part1 = new byte[20]; byte[] part2 = new byte[20]; byte[] u = new byte[20]; int n = (L - 1) / 160; byte[] w = new byte[L / 8]; if (!(digest instanceof SHA1Digest)) { throw new IllegalStateException("can only use SHA-1 for generating FIPS 186-2 parameters"); } for (;;) { random.nextBytes(seed); hash(digest, seed, part1); System.arraycopy(seed, 0, part2, 0, seed.length); inc(part2); hash(digest, part2, part2); for (int i = 0; i != u.length; i++) { u[i] = (byte)(part1[i] ^ part2[i]); } u[0] |= (byte)0x80; u[19] |= (byte)0x01; BigInteger q = new BigInteger(1, u); if (!q.isProbablePrime(certainty)) { continue; } byte[] offset = Arrays.clone(seed); inc(offset); for (int counter = 0; counter < 4096; ++counter) { for (int k = 0; k < n; k++) { inc(offset); hash(digest, offset, part1); System.arraycopy(part1, 0, w, w.length - (k + 1) * part1.length, part1.length); } inc(offset); hash(digest, offset, part1); System.arraycopy(part1, part1.length - ((w.length - (n) * part1.length)), w, 0, w.length - n * part1.length); w[0] |= (byte)0x80; BigInteger x = new BigInteger(1, w); BigInteger c = x.mod(q.shiftLeft(1)); BigInteger p = x.subtract(c.subtract(ONE)); if (p.bitLength() != L) { continue; } if (p.isProbablePrime(certainty)) { BigInteger g = calculateGenerator_FIPS186_2(p, q, random); return new DSAParameters(p, q, g, new DSAValidationParameters(seed, counter)); } } } } private static BigInteger calculateGenerator_FIPS186_2(BigInteger p, BigInteger q, SecureRandom r) { BigInteger e = p.subtract(ONE).divide(q); BigInteger pSub2 = p.subtract(TWO); for (;;) { BigInteger h = BigIntegers.createRandomInRange(TWO, pSub2, r); BigInteger g = h.modPow(e, p); if (g.bitLength() > 1) { return g; } } } /** * generate suitable parameters for DSA, in line with * FIPS 186-3 A.1 Generation of the FFC Primes p and q. */ private DSAParameters generateParameters_FIPS186_3() { // A.1.1.2 Generation of the Probable Primes p and q Using an Approved Hash Function // FIXME This should be configurable (digest size in bits must be >= N) Digest d = digest; int outlen = d.getDigestSize() * 8; // 1. Check that the (L, N) pair is in the list of acceptable (L, N pairs) (see Section 4.2). If // the pair is not in the list, then return INVALID. // Note: checked at initialisation // 2. If (seedlen < N), then return INVALID. // FIXME This should be configurable (must be >= N) int seedlen = N; byte[] seed = new byte[seedlen / 8]; // 3. n = ceiling(L ℠outlen) – 1. int n = (L - 1) / outlen; // 4. b = L – 1 – (n ∗ outlen). int b = (L - 1) % outlen; byte[] output = new byte[d.getDigestSize()]; for (;;) { // 5. Get an arbitrary sequence of seedlen bits as the domain_parameter_seed. random.nextBytes(seed); // 6. U = Hash (domain_parameter_seed) mod 2^(N–1). hash(d, seed, output); BigInteger U = new BigInteger(1, output).mod(ONE.shiftLeft(N - 1)); // 7. q = 2^(N–1) + U + 1 – ( U mod 2). BigInteger q = ONE.shiftLeft(N - 1).add(U).add(ONE).subtract(U.mod(TWO)); // 8. Test whether or not q is prime as specified in Appendix C.3. // TODO Review C.3 for primality checking if (!q.isProbablePrime(certainty)) { // 9. If q is not a prime, then go to step 5. continue; } // 10. offset = 1. // Note: 'offset' value managed incrementally byte[] offset = Arrays.clone(seed); // 11. For counter = 0 to (4L – 1) do int counterLimit = 4 * L; for (int counter = 0; counter < counterLimit; ++counter) { // 11.1 For j = 0 to n do // Vj = Hash ((domain_parameter_seed + offset + j) mod 2^seedlen). // 11.2 W = V0 + (V1 ∗ 2^outlen) + ... + (V^(n–1) ∗ 2^((n–1) ∗ outlen)) + ((Vn mod 2^b) ∗ 2^(n ∗ outlen)). // TODO Assemble w as a byte array BigInteger W = ZERO; for (int j = 0, exp = 0; j <= n; ++j, exp += outlen) { inc(offset); hash(d, offset, output); BigInteger Vj = new BigInteger(1, output); if (j == n) { Vj = Vj.mod(ONE.shiftLeft(b)); } W = W.add(Vj.shiftLeft(exp)); } // 11.3 X = W + 2^(L–1). Comment: 0 ≤ W < 2L–1; hence, 2L–1 ≤ X < 2L. BigInteger X = W.add(ONE.shiftLeft(L - 1)); // 11.4 c = X mod 2q. BigInteger c = X.mod(q.shiftLeft(1)); // 11.5 p = X - (c - 1). Comment: p ≡ 1 (mod 2q). BigInteger p = X.subtract(c.subtract(ONE)); // 11.6 If (p < 2^(L - 1)), then go to step 11.9 if (p.bitLength() != L) { continue; } // 11.7 Test whether or not p is prime as specified in Appendix C.3. // TODO Review C.3 for primality checking if (p.isProbablePrime(certainty)) { // 11.8 If p is determined to be prime, then return VALID and the values of p, q and // (optionally) the values of domain_parameter_seed and counter. if (usageIndex >= 0) { BigInteger g = calculateGenerator_FIPS186_3_Verifiable(d, p, q, seed, usageIndex); if (g != null) { return new DSAParameters(p, q, g, new DSAValidationParameters(seed, counter, usageIndex)); } } BigInteger g = calculateGenerator_FIPS186_3_Unverifiable(p, q, random); return new DSAParameters(p, q, g, new DSAValidationParameters(seed, counter)); } // 11.9 offset = offset + n + 1. Comment: Increment offset; then, as part of // the loop in step 11, increment counter; if // counter < 4L, repeat steps 11.1 through 11.8. // Note: 'offset' value already incremented in inner loop } // 12. Go to step 5. } } private static BigInteger calculateGenerator_FIPS186_3_Unverifiable(BigInteger p, BigInteger q, SecureRandom r) { return calculateGenerator_FIPS186_2(p, q, r); } private static BigInteger calculateGenerator_FIPS186_3_Verifiable(Digest d, BigInteger p, BigInteger q, byte[] seed, int index) { // A.2.3 Verifiable Canonical Generation of the Generator g BigInteger e = p.subtract(ONE).divide(q); byte[] ggen = Hex.decode("6767656E"); // 7. U = domain_parameter_seed || "ggen" || index || count. byte[] U = new byte[seed.length + ggen.length + 1 + 2]; System.arraycopy(seed, 0, U, 0, seed.length); System.arraycopy(ggen, 0, U, seed.length, ggen.length); U[U.length - 3] = (byte)index; byte[] w = new byte[d.getDigestSize()]; for (int count = 1; count < (1 << 16); ++count) { inc(U); hash(d, U, w); BigInteger W = new BigInteger(1, w); BigInteger g = W.modPow(e, p); if (g.compareTo(TWO) >= 0) { return g; } } return null; } private static void hash(Digest d, byte[] input, byte[] output) { d.update(input, 0, input.length); d.doFinal(output, 0); } private static int getDefaultN(int L) { return L > 1024 ? 256 : 160; } private static void inc(byte[] buf) { for (int i = buf.length - 1; i >= 0; --i) { byte b = (byte)((buf[i] + 1) & 0xff); buf[i] = b; if (b != 0) { break; } } } } bouncycastle-1.49.orig/src/org/bouncycastle/crypto/generators/DESedeKeyGenerator.java0000644000175000017500000000325611155052521030452 0ustar ebourgebourgpackage org.bouncycastle.crypto.generators; import org.bouncycastle.crypto.KeyGenerationParameters; import org.bouncycastle.crypto.params.DESedeParameters; public class DESedeKeyGenerator extends DESKeyGenerator { /** * initialise the key generator - if strength is set to zero * the key generated will be 192 bits in size, otherwise * strength can be 128 or 192 (or 112 or 168 if you don't count * parity bits), depending on whether you wish to do 2-key or 3-key * triple DES. * * @param param the parameters to be used for key generation */ public void init( KeyGenerationParameters param) { this.random = param.getRandom(); this.strength = (param.getStrength() + 7) / 8; if (strength == 0 || strength == (168 / 8)) { strength = DESedeParameters.DES_EDE_KEY_LENGTH; } else if (strength == (112 / 8)) { strength = 2 * DESedeParameters.DES_KEY_LENGTH; } else if (strength != DESedeParameters.DES_EDE_KEY_LENGTH && strength != (2 * DESedeParameters.DES_KEY_LENGTH)) { throw new IllegalArgumentException("DESede key must be " + (DESedeParameters.DES_EDE_KEY_LENGTH * 8) + " or " + (2 * 8 * DESedeParameters.DES_KEY_LENGTH) + " bits long."); } } public byte[] generateKey() { byte[] newKey = new byte[strength]; do { random.nextBytes(newKey); DESedeParameters.setOddParity(newKey); } while (DESedeParameters.isWeakKey(newKey, 0, newKey.length)); return newKey; } } bouncycastle-1.49.orig/src/org/bouncycastle/crypto/generators/DHBasicKeyPairGenerator.java0000644000175000017500000000251611160037207031430 0ustar ebourgebourgpackage org.bouncycastle.crypto.generators; import org.bouncycastle.crypto.AsymmetricCipherKeyPair; import org.bouncycastle.crypto.AsymmetricCipherKeyPairGenerator; import org.bouncycastle.crypto.KeyGenerationParameters; import org.bouncycastle.crypto.params.DHKeyGenerationParameters; import org.bouncycastle.crypto.params.DHParameters; import org.bouncycastle.crypto.params.DHPrivateKeyParameters; import org.bouncycastle.crypto.params.DHPublicKeyParameters; import java.math.BigInteger; /** * a basic Diffie-Hellman key pair generator. * * This generates keys consistent for use with the basic algorithm for * Diffie-Hellman. */ public class DHBasicKeyPairGenerator implements AsymmetricCipherKeyPairGenerator { private DHKeyGenerationParameters param; public void init( KeyGenerationParameters param) { this.param = (DHKeyGenerationParameters)param; } public AsymmetricCipherKeyPair generateKeyPair() { DHKeyGeneratorHelper helper = DHKeyGeneratorHelper.INSTANCE; DHParameters dhp = param.getParameters(); BigInteger x = helper.calculatePrivate(dhp, param.getRandom()); BigInteger y = helper.calculatePublic(dhp, x); return new AsymmetricCipherKeyPair( new DHPublicKeyParameters(y, dhp), new DHPrivateKeyParameters(x, dhp)); } } bouncycastle-1.49.orig/src/org/bouncycastle/crypto/generators/EphemeralKeyPairGenerator.java0000644000175000017500000000140412151251423032067 0ustar ebourgebourgpackage org.bouncycastle.crypto.generators; import org.bouncycastle.crypto.AsymmetricCipherKeyPair; import org.bouncycastle.crypto.AsymmetricCipherKeyPairGenerator; import org.bouncycastle.crypto.EphemeralKeyPair; import org.bouncycastle.crypto.KeyEncoder; public class EphemeralKeyPairGenerator { private AsymmetricCipherKeyPairGenerator gen; private KeyEncoder keyEncoder; public EphemeralKeyPairGenerator(AsymmetricCipherKeyPairGenerator gen, KeyEncoder keyEncoder) { this.gen = gen; this.keyEncoder = keyEncoder; } public EphemeralKeyPair generate() { AsymmetricCipherKeyPair eph = gen.generateKeyPair(); // Encode the ephemeral public key return new EphemeralKeyPair(eph, keyEncoder); } } bouncycastle-1.49.orig/src/org/bouncycastle/crypto/generators/DHParametersGenerator.java0000644000175000017500000000266210645643535031245 0ustar ebourgebourgpackage org.bouncycastle.crypto.generators; import org.bouncycastle.crypto.params.DHParameters; import java.math.BigInteger; import java.security.SecureRandom; public class DHParametersGenerator { private int size; private int certainty; private SecureRandom random; private static final BigInteger TWO = BigInteger.valueOf(2); /** * Initialise the parameters generator. * * @param size bit length for the prime p * @param certainty level of certainty for the prime number tests * @param random a source of randomness */ public void init( int size, int certainty, SecureRandom random) { this.size = size; this.certainty = certainty; this.random = random; } /** * which generates the p and g values from the given parameters, * returning the DHParameters object. *

    * Note: can take a while... */ public DHParameters generateParameters() { // // find a safe prime p where p = 2*q + 1, where p and q are prime. // BigInteger[] safePrimes = DHParametersHelper.generateSafePrimes(size, certainty, random); BigInteger p = safePrimes[0]; BigInteger q = safePrimes[1]; BigInteger g = DHParametersHelper.selectGenerator(p, q, random); return new DHParameters(p, g, q, TWO, null); } } bouncycastle-1.49.orig/src/org/bouncycastle/crypto/generators/package.html0000644000175000017500000000017110262753175026463 0ustar ebourgebourg Generators for keys, key pairs and password based encryption algorithms. bouncycastle-1.49.orig/src/org/bouncycastle/crypto/io/0000755000175000017500000000000012152033551022426 5ustar ebourgebourgbouncycastle-1.49.orig/src/org/bouncycastle/crypto/io/MacOutputStream.java0000644000175000017500000000126211730230772026374 0ustar ebourgebourgpackage org.bouncycastle.crypto.io; import java.io.IOException; import java.io.OutputStream; import org.bouncycastle.crypto.Mac; public class MacOutputStream extends OutputStream { protected Mac mac; public MacOutputStream( Mac mac) { this.mac = mac; } public void write(int b) throws IOException { mac.update((byte)b); } public void write( byte[] b, int off, int len) throws IOException { mac.update(b, off, len); } public byte[] getMac() { byte[] res = new byte[mac.getMacSize()]; mac.doFinal(res, 0); return res; } } bouncycastle-1.49.orig/src/org/bouncycastle/crypto/io/DigestOutputStream.java0000644000175000017500000000135711730230772027120 0ustar ebourgebourgpackage org.bouncycastle.crypto.io; import java.io.IOException; import java.io.OutputStream; import org.bouncycastle.crypto.Digest; public class DigestOutputStream extends OutputStream { protected Digest digest; public DigestOutputStream( Digest Digest) { this.digest = Digest; } public void write(int b) throws IOException { digest.update((byte)b); } public void write( byte[] b, int off, int len) throws IOException { digest.update(b, off, len); } public byte[] getDigest() { byte[] res = new byte[digest.getDigestSize()]; digest.doFinal(res, 0); return res; } } bouncycastle-1.49.orig/src/org/bouncycastle/crypto/io/MacInputStream.java0000644000175000017500000000155010262753175026201 0ustar ebourgebourgpackage org.bouncycastle.crypto.io; import java.io.FilterInputStream; import java.io.IOException; import java.io.InputStream; import org.bouncycastle.crypto.Mac; public class MacInputStream extends FilterInputStream { protected Mac mac; public MacInputStream( InputStream stream, Mac mac) { super(stream); this.mac = mac; } public int read() throws IOException { int b = in.read(); if (b >= 0) { mac.update((byte)b); } return b; } public int read( byte[] b, int off, int len) throws IOException { int n = in.read(b, off, len); if (n >= 0) { mac.update(b, off, n); } return n; } public Mac getMac() { return mac; } } bouncycastle-1.49.orig/src/org/bouncycastle/crypto/io/SignerInputStream.java0000644000175000017500000000161611157402103026715 0ustar ebourgebourgpackage org.bouncycastle.crypto.io; import java.io.FilterInputStream; import java.io.IOException; import java.io.InputStream; import org.bouncycastle.crypto.Signer; public class SignerInputStream extends FilterInputStream { protected Signer signer; public SignerInputStream( InputStream stream, Signer signer) { super(stream); this.signer = signer; } public int read() throws IOException { int b = in.read(); if (b >= 0) { signer.update((byte)b); } return b; } public int read( byte[] b, int off, int len) throws IOException { int n = in.read(b, off, len); if (n > 0) { signer.update(b, off, n); } return n; } public Signer getSigner() { return signer; } } bouncycastle-1.49.orig/src/org/bouncycastle/crypto/io/CipherOutputStream.java0000644000175000017500000001206311576273525027122 0ustar ebourgebourgpackage org.bouncycastle.crypto.io; import java.io.FilterOutputStream; import java.io.IOException; import java.io.OutputStream; import org.bouncycastle.crypto.BufferedBlockCipher; import org.bouncycastle.crypto.StreamCipher; public class CipherOutputStream extends FilterOutputStream { private BufferedBlockCipher bufferedBlockCipher; private StreamCipher streamCipher; private byte[] oneByte = new byte[1]; private byte[] buf; /** * Constructs a CipherOutputStream from an OutputStream and a * BufferedBlockCipher. */ public CipherOutputStream( OutputStream os, BufferedBlockCipher cipher) { super(os); this.bufferedBlockCipher = cipher; this.buf = new byte[cipher.getBlockSize()]; } /** * Constructs a CipherOutputStream from an OutputStream and a * BufferedBlockCipher. */ public CipherOutputStream( OutputStream os, StreamCipher cipher) { super(os); this.streamCipher = cipher; } /** * Writes the specified byte to this output stream. * * @param b the byte. * @exception java.io.IOException if an I/O error occurs. */ public void write( int b) throws IOException { oneByte[0] = (byte)b; if (bufferedBlockCipher != null) { int len = bufferedBlockCipher.processBytes(oneByte, 0, 1, buf, 0); if (len != 0) { out.write(buf, 0, len); } } else { out.write(streamCipher.returnByte((byte)b)); } } /** * Writes b.length bytes from the specified byte array * to this output stream. *

    * The write method of * CipherOutputStream calls the write * method of three arguments with the three arguments * b, 0, and b.length. * * @param b the data. * @exception java.io.IOException if an I/O error occurs. * @see #write(byte[], int, int) */ public void write( byte[] b) throws IOException { write(b, 0, b.length); } /** * Writes len bytes from the specified byte array * starting at offset off to this output stream. * * @param b the data. * @param off the start offset in the data. * @param len the number of bytes to write. * @exception java.io.IOException if an I/O error occurs. */ public void write( byte[] b, int off, int len) throws IOException { if (bufferedBlockCipher != null) { byte[] buf = new byte[bufferedBlockCipher.getOutputSize(len)]; int outLen = bufferedBlockCipher.processBytes(b, off, len, buf, 0); if (outLen != 0) { out.write(buf, 0, outLen); } } else { byte[] buf = new byte[len]; streamCipher.processBytes(b, off, len, buf, 0); out.write(buf, 0, len); } } /** * Flushes this output stream by forcing any buffered output bytes * that have already been processed by the encapsulated cipher object * to be written out. * *

    * Any bytes buffered by the encapsulated cipher * and waiting to be processed by it will not be written out. For example, * if the encapsulated cipher is a block cipher, and the total number of * bytes written using one of the write methods is less than * the cipher's block size, no bytes will be written out. * * @exception java.io.IOException if an I/O error occurs. */ public void flush() throws IOException { super.flush(); } /** * Closes this output stream and releases any system resources * associated with this stream. *

    * This method invokes the doFinal method of the encapsulated * cipher object, which causes any bytes buffered by the encapsulated * cipher to be processed. The result is written out by calling the * flush method of this output stream. *

    * This method resets the encapsulated cipher object to its initial state * and calls the close method of the underlying output * stream. * * @exception java.io.IOException if an I/O error occurs. */ public void close() throws IOException { try { if (bufferedBlockCipher != null) { byte[] buf = new byte[bufferedBlockCipher.getOutputSize(0)]; int outLen = bufferedBlockCipher.doFinal(buf, 0); if (outLen != 0) { out.write(buf, 0, outLen); } } } catch (Exception e) { throw new IOException("Error closing stream: " + e.toString()); } flush(); super.close(); } } bouncycastle-1.49.orig/src/org/bouncycastle/crypto/io/DigestInputStream.java0000644000175000017500000000161610262753175026723 0ustar ebourgebourgpackage org.bouncycastle.crypto.io; import java.io.FilterInputStream; import java.io.IOException; import java.io.InputStream; import org.bouncycastle.crypto.Digest; public class DigestInputStream extends FilterInputStream { protected Digest digest; public DigestInputStream( InputStream stream, Digest digest) { super(stream); this.digest = digest; } public int read() throws IOException { int b = in.read(); if (b >= 0) { digest.update((byte)b); } return b; } public int read( byte[] b, int off, int len) throws IOException { int n = in.read(b, off, len); if (n > 0) { digest.update(b, off, n); } return n; } public Digest getDigest() { return digest; } } bouncycastle-1.49.orig/src/org/bouncycastle/crypto/io/CipherInputStream.java0000644000175000017500000001231711576273525026723 0ustar ebourgebourgpackage org.bouncycastle.crypto.io; import java.io.FilterInputStream; import java.io.IOException; import java.io.InputStream; import org.bouncycastle.crypto.BufferedBlockCipher; import org.bouncycastle.crypto.StreamCipher; /** * A CipherInputStream is composed of an InputStream and a BufferedBlockCipher so * that read() methods return data that are read in from the * underlying InputStream but have been additionally processed by the * Cipher. The Cipher must be fully initialized before being used by * a CipherInputStream. *

    * For example, if the Cipher is initialized for decryption, the * CipherInputStream will attempt to read in data and decrypt them, * before returning the decrypted data. */ public class CipherInputStream extends FilterInputStream { private BufferedBlockCipher bufferedBlockCipher; private StreamCipher streamCipher; private byte[] buf; private byte[] inBuf; private int bufOff; private int maxBuf; private boolean finalized; private static final int INPUT_BUF_SIZE = 2048; /** * Constructs a CipherInputStream from an InputStream and a * BufferedBlockCipher. */ public CipherInputStream( InputStream is, BufferedBlockCipher cipher) { super(is); this.bufferedBlockCipher = cipher; buf = new byte[cipher.getOutputSize(INPUT_BUF_SIZE)]; inBuf = new byte[INPUT_BUF_SIZE]; } public CipherInputStream( InputStream is, StreamCipher cipher) { super(is); this.streamCipher = cipher; buf = new byte[INPUT_BUF_SIZE]; inBuf = new byte[INPUT_BUF_SIZE]; } /** * grab the next chunk of input from the underlying input stream */ private int nextChunk() throws IOException { int available = super.available(); // must always try to read 1 byte! // some buggy InputStreams return < 0! if (available <= 0) { available = 1; } if (available > inBuf.length) { available = super.read(inBuf, 0, inBuf.length); } else { available = super.read(inBuf, 0, available); } if (available < 0) { if (finalized) { return -1; } try { if (bufferedBlockCipher != null) { maxBuf = bufferedBlockCipher.doFinal(buf, 0); } else { maxBuf = 0; // a stream cipher } } catch (Exception e) { throw new IOException("error processing stream: " + e.toString()); } bufOff = 0; finalized = true; if (bufOff == maxBuf) { return -1; } } else { bufOff = 0; try { if (bufferedBlockCipher != null) { maxBuf = bufferedBlockCipher.processBytes(inBuf, 0, available, buf, 0); } else { streamCipher.processBytes(inBuf, 0, available, buf, 0); maxBuf = available; } } catch (Exception e) { throw new IOException("error processing stream: " + e.toString()); } if (maxBuf == 0) // not enough bytes read for first block... { return nextChunk(); } } return maxBuf; } public int read() throws IOException { if (bufOff == maxBuf) { if (nextChunk() < 0) { return -1; } } return buf[bufOff++] & 0xff; } public int read( byte[] b) throws IOException { return read(b, 0, b.length); } public int read( byte[] b, int off, int len) throws IOException { if (bufOff == maxBuf) { if (nextChunk() < 0) { return -1; } } int available = maxBuf - bufOff; if (len > available) { System.arraycopy(buf, bufOff, b, off, available); bufOff = maxBuf; return available; } else { System.arraycopy(buf, bufOff, b, off, len); bufOff += len; return len; } } public long skip( long n) throws IOException { if (n <= 0) { return 0; } int available = maxBuf - bufOff; if (n > available) { bufOff = maxBuf; return available; } else { bufOff += (int)n; return (int)n; } } public int available() throws IOException { return maxBuf - bufOff; } public void close() throws IOException { super.close(); } public boolean markSupported() { return false; } } bouncycastle-1.49.orig/src/org/bouncycastle/crypto/io/package.html0000644000175000017500000000015010262753175024716 0ustar ebourgebourg Classes for doing "enhanced" I/O with Digests and MACs. bouncycastle-1.49.orig/src/org/bouncycastle/crypto/io/SignerOutputStream.java0000644000175000017500000000121111730230772027115 0ustar ebourgebourgpackage org.bouncycastle.crypto.io; import java.io.IOException; import java.io.OutputStream; import org.bouncycastle.crypto.Signer; public class SignerOutputStream extends OutputStream { protected Signer signer; public SignerOutputStream( Signer Signer) { this.signer = Signer; } public void write(int b) throws IOException { signer.update((byte)b); } public void write( byte[] b, int off, int len) throws IOException { signer.update(b, off, len); } public Signer getSigner() { return signer; } } bouncycastle-1.49.orig/src/org/bouncycastle/crypto/CryptoException.java0000644000175000017500000000167211625352616026041 0ustar ebourgebourgpackage org.bouncycastle.crypto; /** * the foundation class for the hard exceptions thrown by the crypto packages. */ public class CryptoException extends Exception { private Throwable cause; /** * base constructor. */ public CryptoException() { } /** * create a CryptoException with the given message. * * @param message the message to be carried with the exception. */ public CryptoException( String message) { super(message); } /** * Create a CryptoException with the given message and underlying cause. * * @param message message describing exception. * @param cause the throwable that was the underlying cause. */ public CryptoException( String message, Throwable cause) { super(message); this.cause = cause; } public Throwable getCause() { return cause; } } bouncycastle-1.49.orig/src/org/bouncycastle/crypto/params/0000755000175000017500000000000012152033551023302 5ustar ebourgebourgbouncycastle-1.49.orig/src/org/bouncycastle/crypto/params/KeyParameter.java0000644000175000017500000000103010262753175026543 0ustar ebourgebourgpackage org.bouncycastle.crypto.params; import org.bouncycastle.crypto.CipherParameters; public class KeyParameter implements CipherParameters { private byte[] key; public KeyParameter( byte[] key) { this(key, 0, key.length); } public KeyParameter( byte[] key, int keyOff, int keyLen) { this.key = new byte[keyLen]; System.arraycopy(key, keyOff, this.key, 0, keyLen); } public byte[] getKey() { return key; } } bouncycastle-1.49.orig/src/org/bouncycastle/crypto/params/ParametersWithSalt.java0000644000175000017500000000170210262753175027743 0ustar ebourgebourgpackage org.bouncycastle.crypto.params; import org.bouncycastle.crypto.CipherParameters; /** * Cipher parameters with a fixed salt value associated with them. */ public class ParametersWithSalt implements CipherParameters { private byte[] salt; private CipherParameters parameters; public ParametersWithSalt( CipherParameters parameters, byte[] salt) { this(parameters, salt, 0, salt.length); } public ParametersWithSalt( CipherParameters parameters, byte[] salt, int saltOff, int saltLen) { this.salt = new byte[saltLen]; this.parameters = parameters; System.arraycopy(salt, saltOff, this.salt, 0, saltLen); } public byte[] getSalt() { return salt; } public CipherParameters getParameters() { return parameters; } } bouncycastle-1.49.orig/src/org/bouncycastle/crypto/params/NaccacheSternKeyGenerationParameters.java0000644000175000017500000000530710452105155033365 0ustar ebourgebourgpackage org.bouncycastle.crypto.params; import java.security.SecureRandom; import org.bouncycastle.crypto.KeyGenerationParameters; /** * Parameters for NaccacheStern public private key generation. For details on * this cipher, please see * * http://www.gemplus.com/smart/rd/publications/pdf/NS98pkcs.pdf */ public class NaccacheSternKeyGenerationParameters extends KeyGenerationParameters { // private BigInteger publicExponent; private int certainty; private int cntSmallPrimes; private boolean debug = false; /** * Parameters for generating a NaccacheStern KeyPair. * * @param random * The source of randomness * @param strength * The desired strength of the Key in Bits * @param certainty * the probability that the generated primes are not really prime * as integer: 2^(-certainty) is then the probability * @param cntSmallPrimes * How many small key factors are desired */ public NaccacheSternKeyGenerationParameters(SecureRandom random, int strength, int certainty, int cntSmallPrimes) { this(random, strength, certainty, cntSmallPrimes, false); } /** * Parameters for a NaccacheStern KeyPair. * * @param random * The source of randomness * @param strength * The desired strength of the Key in Bits * @param certainty * the probability that the generated primes are not really prime * as integer: 2^(-certainty) is then the probability * @param cntSmallPrimes * How many small key factors are desired * @param debug * Turn debugging on or off (reveals secret information, use with * caution) */ public NaccacheSternKeyGenerationParameters(SecureRandom random, int strength, int certainty, int cntSmallPrimes, boolean debug) { super(random, strength); this.certainty = certainty; if (cntSmallPrimes % 2 == 1) { throw new IllegalArgumentException("cntSmallPrimes must be a multiple of 2"); } if (cntSmallPrimes < 30) { throw new IllegalArgumentException("cntSmallPrimes must be >= 30 for security reasons"); } this.cntSmallPrimes = cntSmallPrimes; this.debug = debug; } /** * @return Returns the certainty. */ public int getCertainty() { return certainty; } /** * @return Returns the cntSmallPrimes. */ public int getCntSmallPrimes() { return cntSmallPrimes; } public boolean isDebug() { return debug; } } bouncycastle-1.49.orig/src/org/bouncycastle/crypto/params/ECKeyParameters.java0000644000175000017500000000061610262753175027147 0ustar ebourgebourgpackage org.bouncycastle.crypto.params; public class ECKeyParameters extends AsymmetricKeyParameter { ECDomainParameters params; protected ECKeyParameters( boolean isPrivate, ECDomainParameters params) { super(isPrivate); this.params = params; } public ECDomainParameters getParameters() { return params; } } bouncycastle-1.49.orig/src/org/bouncycastle/crypto/params/ElGamalParameters.java0000644000175000017500000000235410741312222027474 0ustar ebourgebourgpackage org.bouncycastle.crypto.params; import java.math.BigInteger; import org.bouncycastle.crypto.CipherParameters; public class ElGamalParameters implements CipherParameters { private BigInteger g; private BigInteger p; private int l; public ElGamalParameters( BigInteger p, BigInteger g) { this(p, g, 0); } public ElGamalParameters( BigInteger p, BigInteger g, int l) { this.g = g; this.p = p; this.l = l; } public BigInteger getP() { return p; } /** * return the generator - g */ public BigInteger getG() { return g; } /** * return private value limit - l */ public int getL() { return l; } public boolean equals( Object obj) { if (!(obj instanceof ElGamalParameters)) { return false; } ElGamalParameters pm = (ElGamalParameters)obj; return pm.getP().equals(p) && pm.getG().equals(g) && pm.getL() == l; } public int hashCode() { return (getP().hashCode() ^ getG().hashCode()) + l; } } bouncycastle-1.49.orig/src/org/bouncycastle/crypto/params/ElGamalKeyGenerationParameters.java0000644000175000017500000000126011160037207032157 0ustar ebourgebourgpackage org.bouncycastle.crypto.params; import java.security.SecureRandom; import org.bouncycastle.crypto.KeyGenerationParameters; public class ElGamalKeyGenerationParameters extends KeyGenerationParameters { private ElGamalParameters params; public ElGamalKeyGenerationParameters( SecureRandom random, ElGamalParameters params) { super(random, getStrength(params)); this.params = params; } public ElGamalParameters getParameters() { return params; } static int getStrength(ElGamalParameters params) { return params.getL() != 0 ? params.getL() : params.getP().bitLength(); } } bouncycastle-1.49.orig/src/org/bouncycastle/crypto/params/DHParameters.java0000644000175000017500000001007711562112303026466 0ustar ebourgebourgpackage org.bouncycastle.crypto.params; import java.math.BigInteger; import org.bouncycastle.crypto.CipherParameters; public class DHParameters implements CipherParameters { private static final int DEFAULT_MINIMUM_LENGTH = 160; // not final due to compiler bug in "simpler" JDKs private BigInteger g; private BigInteger p; private BigInteger q; private BigInteger j; private int m; private int l; private DHValidationParameters validation; private static int getDefaultMParam( int lParam) { if (lParam == 0) { return DEFAULT_MINIMUM_LENGTH; } return lParam < DEFAULT_MINIMUM_LENGTH ? lParam : DEFAULT_MINIMUM_LENGTH; } public DHParameters( BigInteger p, BigInteger g) { this(p, g, null, 0); } public DHParameters( BigInteger p, BigInteger g, BigInteger q) { this(p, g, q, 0); } public DHParameters( BigInteger p, BigInteger g, BigInteger q, int l) { this(p, g, q, getDefaultMParam(l), l, null, null); } public DHParameters( BigInteger p, BigInteger g, BigInteger q, int m, int l) { this(p, g, q, m, l, null, null); } public DHParameters( BigInteger p, BigInteger g, BigInteger q, BigInteger j, DHValidationParameters validation) { this(p, g, q, DEFAULT_MINIMUM_LENGTH, 0, j, validation); } public DHParameters( BigInteger p, BigInteger g, BigInteger q, int m, int l, BigInteger j, DHValidationParameters validation) { if (l != 0) { BigInteger bigL = BigInteger.valueOf(2L ^ (l - 1)); if (bigL.compareTo(p) == 1) { throw new IllegalArgumentException("when l value specified, it must satisfy 2^(l-1) <= p"); } if (l < m) { throw new IllegalArgumentException("when l value specified, it may not be less than m value"); } } this.g = g; this.p = p; this.q = q; this.m = m; this.l = l; this.j = j; this.validation = validation; } public BigInteger getP() { return p; } public BigInteger getG() { return g; } public BigInteger getQ() { return q; } /** * Return the subgroup factor J. * * @return subgroup factor */ public BigInteger getJ() { return j; } /** * Return the minimum length of the private value. * * @return the minimum length of the private value in bits. */ public int getM() { return m; } /** * Return the private value length in bits - if set, zero otherwise * * @return the private value length in bits, zero otherwise. */ public int getL() { return l; } public DHValidationParameters getValidationParameters() { return validation; } public boolean equals( Object obj) { if (!(obj instanceof DHParameters)) { return false; } DHParameters pm = (DHParameters)obj; if (this.getQ() != null) { if (!this.getQ().equals(pm.getQ())) { return false; } } else { if (pm.getQ() != null) { return false; } } return pm.getP().equals(p) && pm.getG().equals(g); } public int hashCode() { return getP().hashCode() ^ getG().hashCode() ^ (getQ() != null ? getQ().hashCode() : 0); } } bouncycastle-1.49.orig/src/org/bouncycastle/crypto/params/HKDFParameters.java0000644000175000017500000000620512076516147026724 0ustar ebourgebourgpackage org.bouncycastle.crypto.params; import org.bouncycastle.crypto.DerivationParameters; import org.bouncycastle.util.Arrays; /** * Parameter class for the HKDFBytesGenerator class. */ public class HKDFParameters implements DerivationParameters { private final byte[] ikm; private final boolean skipExpand; private final byte[] salt; private final byte[] info; private HKDFParameters(final byte[] ikm, final boolean skip, final byte[] salt, final byte[] info) { if (ikm == null) { throw new IllegalArgumentException( "IKM (input keying material) should not be null"); } this.ikm = Arrays.clone(ikm); this.skipExpand = skip; if (salt == null || salt.length == 0) { this.salt = null; } else { this.salt = Arrays.clone(salt); } if (info == null) { this.info = new byte[0]; } else { this.info = Arrays.clone(info); } } /** * Generates parameters for HKDF, specifying both the optional salt and * optional info. Step 1: Extract won't be skipped. * * @param ikm the input keying material or seed * @param salt the salt to use, may be null for a salt for hashLen zeros * @param info the info to use, may be null for an info field of zero bytes */ public HKDFParameters(final byte[] ikm, final byte[] salt, final byte[] info) { this(ikm, false, salt, info); } /** * Factory method that makes the HKDF skip the extract part of the key * derivation function. * * @param ikm the input keying material or seed, directly used for step 2: * Expand * @param info the info to use, may be null for an info field of zero bytes * @return HKDFParameters that makes the implementation skip step 1 */ public static HKDFParameters skipExtractParameters(final byte[] ikm, final byte[] info) { return new HKDFParameters(ikm, true, null, info); } public static HKDFParameters defaultParameters(final byte[] ikm) { return new HKDFParameters(ikm, false, null, null); } /** * Returns the input keying material or seed. * * @return the keying material */ public byte[] getIKM() { return Arrays.clone(ikm); } /** * Returns if step 1: extract has to be skipped or not * * @return true for skipping, false for no skipping of step 1 */ public boolean skipExtract() { return skipExpand; } /** * Returns the salt, or null if the salt should be generated as a byte array * of HashLen zeros. * * @return the salt, or null */ public byte[] getSalt() { return Arrays.clone(salt); } /** * Returns the info field, which may be empty (null is converted to empty). * * @return the info field, never null */ public byte[] getInfo() { return Arrays.clone(info); } } bouncycastle-1.49.orig/src/org/bouncycastle/crypto/params/RSAPrivateCrtKeyParameters.java0000644000175000017500000000223710262753175031312 0ustar ebourgebourgpackage org.bouncycastle.crypto.params; import java.math.BigInteger; public class RSAPrivateCrtKeyParameters extends RSAKeyParameters { private BigInteger e; private BigInteger p; private BigInteger q; private BigInteger dP; private BigInteger dQ; private BigInteger qInv; /** * */ public RSAPrivateCrtKeyParameters( BigInteger modulus, BigInteger publicExponent, BigInteger privateExponent, BigInteger p, BigInteger q, BigInteger dP, BigInteger dQ, BigInteger qInv) { super(true, modulus, privateExponent); this.e = publicExponent; this.p = p; this.q = q; this.dP = dP; this.dQ = dQ; this.qInv = qInv; } public BigInteger getPublicExponent() { return e; } public BigInteger getP() { return p; } public BigInteger getQ() { return q; } public BigInteger getDP() { return dP; } public BigInteger getDQ() { return dQ; } public BigInteger getQInv() { return qInv; } } bouncycastle-1.49.orig/src/org/bouncycastle/crypto/params/ElGamalKeyParameters.java0000644000175000017500000000164310531563007030153 0ustar ebourgebourgpackage org.bouncycastle.crypto.params; public class ElGamalKeyParameters extends AsymmetricKeyParameter { private ElGamalParameters params; protected ElGamalKeyParameters( boolean isPrivate, ElGamalParameters params) { super(isPrivate); this.params = params; } public ElGamalParameters getParameters() { return params; } public int hashCode() { return (params != null) ? params.hashCode() : 0; } public boolean equals( Object obj) { if (!(obj instanceof ElGamalKeyParameters)) { return false; } ElGamalKeyParameters dhKey = (ElGamalKeyParameters)obj; if (params == null) { return dhKey.getParameters() == null; } else { return params.equals(dhKey.getParameters()); } } } bouncycastle-1.49.orig/src/org/bouncycastle/crypto/params/GOST3410PublicKeyParameters.java0000644000175000017500000000063510262753175031104 0ustar ebourgebourgpackage org.bouncycastle.crypto.params; import java.math.BigInteger; public class GOST3410PublicKeyParameters extends GOST3410KeyParameters { private BigInteger y; public GOST3410PublicKeyParameters( BigInteger y, GOST3410Parameters params) { super(false, params); this.y = y; } public BigInteger getY() { return y; } } bouncycastle-1.49.orig/src/org/bouncycastle/crypto/params/MQVPrivateParameters.java0000644000175000017500000000227011275502544030200 0ustar ebourgebourgpackage org.bouncycastle.crypto.params; import org.bouncycastle.crypto.CipherParameters; public class MQVPrivateParameters implements CipherParameters { private ECPrivateKeyParameters staticPrivateKey; private ECPrivateKeyParameters ephemeralPrivateKey; private ECPublicKeyParameters ephemeralPublicKey; public MQVPrivateParameters( ECPrivateKeyParameters staticPrivateKey, ECPrivateKeyParameters ephemeralPrivateKey) { this(staticPrivateKey, ephemeralPrivateKey, null); } public MQVPrivateParameters( ECPrivateKeyParameters staticPrivateKey, ECPrivateKeyParameters ephemeralPrivateKey, ECPublicKeyParameters ephemeralPublicKey) { this.staticPrivateKey = staticPrivateKey; this.ephemeralPrivateKey = ephemeralPrivateKey; this.ephemeralPublicKey = ephemeralPublicKey; } public ECPrivateKeyParameters getStaticPrivateKey() { return staticPrivateKey; } public ECPrivateKeyParameters getEphemeralPrivateKey() { return ephemeralPrivateKey; } public ECPublicKeyParameters getEphemeralPublicKey() { return ephemeralPublicKey; } } bouncycastle-1.49.orig/src/org/bouncycastle/crypto/params/GOST3410Parameters.java0000644000175000017500000000274210531563007027265 0ustar ebourgebourgpackage org.bouncycastle.crypto.params; import org.bouncycastle.crypto.CipherParameters; import java.math.BigInteger; public class GOST3410Parameters implements CipherParameters { private BigInteger p; private BigInteger q; private BigInteger a; private GOST3410ValidationParameters validation; public GOST3410Parameters( BigInteger p, BigInteger q, BigInteger a) { this.p = p; this.q = q; this.a = a; } public GOST3410Parameters( BigInteger p, BigInteger q, BigInteger a, GOST3410ValidationParameters params) { this.a = a; this.p = p; this.q = q; this.validation = params; } public BigInteger getP() { return p; } public BigInteger getQ() { return q; } public BigInteger getA() { return a; } public GOST3410ValidationParameters getValidationParameters() { return validation; } public int hashCode() { return p.hashCode() ^ q.hashCode() ^ a.hashCode(); } public boolean equals( Object obj) { if (!(obj instanceof GOST3410Parameters)) { return false; } GOST3410Parameters pm = (GOST3410Parameters)obj; return (pm.getP().equals(p) && pm.getQ().equals(q) && pm.getA().equals(a)); } } bouncycastle-1.49.orig/src/org/bouncycastle/crypto/params/ISO18033KDFParameters.java0000644000175000017500000000063210427071732027556 0ustar ebourgebourgpackage org.bouncycastle.crypto.params; import org.bouncycastle.crypto.DerivationParameters; /** * parameters for Key derivation functions for ISO-18033 */ public class ISO18033KDFParameters implements DerivationParameters { byte[] seed; public ISO18033KDFParameters( byte[] seed) { this.seed = seed; } public byte[] getSeed() { return seed; } } bouncycastle-1.49.orig/src/org/bouncycastle/crypto/params/RSAKeyParameters.java0000644000175000017500000000111510262753175027300 0ustar ebourgebourgpackage org.bouncycastle.crypto.params; import java.math.BigInteger; public class RSAKeyParameters extends AsymmetricKeyParameter { private BigInteger modulus; private BigInteger exponent; public RSAKeyParameters( boolean isPrivate, BigInteger modulus, BigInteger exponent) { super(isPrivate); this.modulus = modulus; this.exponent = exponent; } public BigInteger getModulus() { return modulus; } public BigInteger getExponent() { return exponent; } } bouncycastle-1.49.orig/src/org/bouncycastle/crypto/params/RSABlindingParameters.java0000644000175000017500000000150210554246677030306 0ustar ebourgebourgpackage org.bouncycastle.crypto.params; import org.bouncycastle.crypto.CipherParameters; import java.math.BigInteger; public class RSABlindingParameters implements CipherParameters { private RSAKeyParameters publicKey; private BigInteger blindingFactor; public RSABlindingParameters( RSAKeyParameters publicKey, BigInteger blindingFactor) { if (publicKey instanceof RSAPrivateCrtKeyParameters) { throw new IllegalArgumentException("RSA parameters should be for a public key"); } this.publicKey = publicKey; this.blindingFactor = blindingFactor; } public RSAKeyParameters getPublicKey() { return publicKey; } public BigInteger getBlindingFactor() { return blindingFactor; } } bouncycastle-1.49.orig/src/org/bouncycastle/crypto/params/DESParameters.java0000644000175000017500000000754410531736712026626 0ustar ebourgebourgpackage org.bouncycastle.crypto.params; public class DESParameters extends KeyParameter { public DESParameters( byte[] key) { super(key); if (isWeakKey(key, 0)) { throw new IllegalArgumentException("attempt to create weak DES key"); } } /* * DES Key length in bytes. */ static public final int DES_KEY_LENGTH = 8; /* * Table of weak and semi-weak keys taken from Schneier pp281 */ static private final int N_DES_WEAK_KEYS = 16; static private byte[] DES_weak_keys = { /* weak keys */ (byte)0x01,(byte)0x01,(byte)0x01,(byte)0x01, (byte)0x01,(byte)0x01,(byte)0x01,(byte)0x01, (byte)0x1f,(byte)0x1f,(byte)0x1f,(byte)0x1f, (byte)0x0e,(byte)0x0e,(byte)0x0e,(byte)0x0e, (byte)0xe0,(byte)0xe0,(byte)0xe0,(byte)0xe0, (byte)0xf1,(byte)0xf1,(byte)0xf1,(byte)0xf1, (byte)0xfe,(byte)0xfe,(byte)0xfe,(byte)0xfe, (byte)0xfe,(byte)0xfe,(byte)0xfe,(byte)0xfe, /* semi-weak keys */ (byte)0x01,(byte)0xfe,(byte)0x01,(byte)0xfe, (byte)0x01,(byte)0xfe,(byte)0x01,(byte)0xfe, (byte)0x1f,(byte)0xe0,(byte)0x1f,(byte)0xe0, (byte)0x0e,(byte)0xf1,(byte)0x0e,(byte)0xf1, (byte)0x01,(byte)0xe0,(byte)0x01,(byte)0xe0, (byte)0x01,(byte)0xf1,(byte)0x01,(byte)0xf1, (byte)0x1f,(byte)0xfe,(byte)0x1f,(byte)0xfe, (byte)0x0e,(byte)0xfe,(byte)0x0e,(byte)0xfe, (byte)0x01,(byte)0x1f,(byte)0x01,(byte)0x1f, (byte)0x01,(byte)0x0e,(byte)0x01,(byte)0x0e, (byte)0xe0,(byte)0xfe,(byte)0xe0,(byte)0xfe, (byte)0xf1,(byte)0xfe,(byte)0xf1,(byte)0xfe, (byte)0xfe,(byte)0x01,(byte)0xfe,(byte)0x01, (byte)0xfe,(byte)0x01,(byte)0xfe,(byte)0x01, (byte)0xe0,(byte)0x1f,(byte)0xe0,(byte)0x1f, (byte)0xf1,(byte)0x0e,(byte)0xf1,(byte)0x0e, (byte)0xe0,(byte)0x01,(byte)0xe0,(byte)0x01, (byte)0xf1,(byte)0x01,(byte)0xf1,(byte)0x01, (byte)0xfe,(byte)0x1f,(byte)0xfe,(byte)0x1f, (byte)0xfe,(byte)0x0e,(byte)0xfe,(byte)0x0e, (byte)0x1f,(byte)0x01,(byte)0x1f,(byte)0x01, (byte)0x0e,(byte)0x01,(byte)0x0e,(byte)0x01, (byte)0xfe,(byte)0xe0,(byte)0xfe,(byte)0xe0, (byte)0xfe,(byte)0xf1,(byte)0xfe,(byte)0xf1 }; /** * DES has 16 weak keys. This method will check * if the given DES key material is weak or semi-weak. * Key material that is too short is regarded as weak. *

    * See "Applied * Cryptography" by Bruce Schneier for more information. * * @return true if the given DES key material is weak or semi-weak, * false otherwise. */ public static boolean isWeakKey( byte[] key, int offset) { if (key.length - offset < DES_KEY_LENGTH) { throw new IllegalArgumentException("key material too short."); } nextkey: for (int i = 0; i < N_DES_WEAK_KEYS; i++) { for (int j = 0; j < DES_KEY_LENGTH; j++) { if (key[j + offset] != DES_weak_keys[i * DES_KEY_LENGTH + j]) { continue nextkey; } } return true; } return false; } /** * DES Keys use the LSB as the odd parity bit. This can * be used to check for corrupt keys. * * @param bytes the byte array to set the parity on. */ public static void setOddParity( byte[] bytes) { for (int i = 0; i < bytes.length; i++) { int b = bytes[i]; bytes[i] = (byte)((b & 0xfe) | ((((b >> 1) ^ (b >> 2) ^ (b >> 3) ^ (b >> 4) ^ (b >> 5) ^ (b >> 6) ^ (b >> 7)) ^ 0x01) & 0x01)); } } } bouncycastle-1.49.orig/src/org/bouncycastle/crypto/params/RC5Parameters.java0000644000175000017500000000126110262753175026575 0ustar ebourgebourgpackage org.bouncycastle.crypto.params; import org.bouncycastle.crypto.CipherParameters; public class RC5Parameters implements CipherParameters { private byte[] key; private int rounds; public RC5Parameters( byte[] key, int rounds) { if (key.length > 255) { throw new IllegalArgumentException("RC5 key length can be no greater than 255"); } this.key = new byte[key.length]; this.rounds = rounds; System.arraycopy(key, 0, this.key, 0, key.length); } public byte[] getKey() { return key; } public int getRounds() { return rounds; } } bouncycastle-1.49.orig/src/org/bouncycastle/crypto/params/DHValidationParameters.java0000644000175000017500000000161710617070647030517 0ustar ebourgebourgpackage org.bouncycastle.crypto.params; import org.bouncycastle.util.Arrays; public class DHValidationParameters { private byte[] seed; private int counter; public DHValidationParameters( byte[] seed, int counter) { this.seed = seed; this.counter = counter; } public int getCounter() { return counter; } public byte[] getSeed() { return seed; } public boolean equals( Object o) { if (!(o instanceof DHValidationParameters)) { return false; } DHValidationParameters other = (DHValidationParameters)o; if (other.counter != this.counter) { return false; } return Arrays.areEqual(this.seed, other.seed); } public int hashCode() { return counter ^ Arrays.hashCode(seed); } } bouncycastle-1.49.orig/src/org/bouncycastle/crypto/params/CCMParameters.java0000644000175000017500000000102112045616304026571 0ustar ebourgebourgpackage org.bouncycastle.crypto.params; /** * @deprecated use AEADParameters */ public class CCMParameters extends AEADParameters { /** * Base constructor. * * @param key key to be used by underlying cipher * @param macSize macSize in bits * @param nonce nonce to be used * @param associatedText associated text, if any */ public CCMParameters(KeyParameter key, int macSize, byte[] nonce, byte[] associatedText) { super(key, macSize, nonce, associatedText); } } bouncycastle-1.49.orig/src/org/bouncycastle/crypto/params/DHPublicKeyParameters.java0000644000175000017500000000137610531563007030306 0ustar ebourgebourgpackage org.bouncycastle.crypto.params; import java.math.BigInteger; public class DHPublicKeyParameters extends DHKeyParameters { private BigInteger y; public DHPublicKeyParameters( BigInteger y, DHParameters params) { super(false, params); this.y = y; } public BigInteger getY() { return y; } public int hashCode() { return y.hashCode() ^ super.hashCode(); } public boolean equals( Object obj) { if (!(obj instanceof DHPublicKeyParameters)) { return false; } DHPublicKeyParameters other = (DHPublicKeyParameters)obj; return other.getY().equals(y) && super.equals(obj); } } bouncycastle-1.49.orig/src/org/bouncycastle/crypto/params/IESWithCipherParameters.java0000644000175000017500000000137610262753175030622 0ustar ebourgebourgpackage org.bouncycastle.crypto.params; public class IESWithCipherParameters extends IESParameters { private int cipherKeySize; /** * @param derivation the derivation parameter for the KDF function. * @param encoding the encoding parameter for the KDF function. * @param macKeySize the size of the MAC key (in bits). * @param cipherKeySize the size of the associated Cipher key (in bits). */ public IESWithCipherParameters( byte[] derivation, byte[] encoding, int macKeySize, int cipherKeySize) { super(derivation, encoding, macKeySize); this.cipherKeySize = cipherKeySize; } public int getCipherKeySize() { return cipherKeySize; } } bouncycastle-1.49.orig/src/org/bouncycastle/crypto/params/NaccacheSternKeyParameters.java0000644000175000017500000000176010452105155031350 0ustar ebourgebourgpackage org.bouncycastle.crypto.params; import java.math.BigInteger; /** * Public key parameters for NaccacheStern cipher. For details on this cipher, * please see * * http://www.gemplus.com/smart/rd/publications/pdf/NS98pkcs.pdf */ public class NaccacheSternKeyParameters extends AsymmetricKeyParameter { private BigInteger g, n; int lowerSigmaBound; /** * @param privateKey */ public NaccacheSternKeyParameters(boolean privateKey, BigInteger g, BigInteger n, int lowerSigmaBound) { super(privateKey); this.g = g; this.n = n; this.lowerSigmaBound = lowerSigmaBound; } /** * @return Returns the g. */ public BigInteger getG() { return g; } /** * @return Returns the lowerSigmaBound. */ public int getLowerSigmaBound() { return lowerSigmaBound; } /** * @return Returns the n. */ public BigInteger getModulus() { return n; } } bouncycastle-1.49.orig/src/org/bouncycastle/crypto/params/MQVPublicParameters.java0000644000175000017500000000131511275502544030003 0ustar ebourgebourgpackage org.bouncycastle.crypto.params; import org.bouncycastle.crypto.CipherParameters; public class MQVPublicParameters implements CipherParameters { private ECPublicKeyParameters staticPublicKey; private ECPublicKeyParameters ephemeralPublicKey; public MQVPublicParameters( ECPublicKeyParameters staticPublicKey, ECPublicKeyParameters ephemeralPublicKey) { this.staticPublicKey = staticPublicKey; this.ephemeralPublicKey = ephemeralPublicKey; } public ECPublicKeyParameters getStaticPublicKey() { return staticPublicKey; } public ECPublicKeyParameters getEphemeralPublicKey() { return ephemeralPublicKey; } } bouncycastle-1.49.orig/src/org/bouncycastle/crypto/params/ECPublicKeyParameters.java0000644000175000017500000000060210262753175030301 0ustar ebourgebourgpackage org.bouncycastle.crypto.params; import org.bouncycastle.math.ec.ECPoint; public class ECPublicKeyParameters extends ECKeyParameters { ECPoint Q; public ECPublicKeyParameters( ECPoint Q, ECDomainParameters params) { super(false, params); this.Q = Q; } public ECPoint getQ() { return Q; } } bouncycastle-1.49.orig/src/org/bouncycastle/crypto/params/GOST3410KeyParameters.java0000644000175000017500000000064310262753175027744 0ustar ebourgebourgpackage org.bouncycastle.crypto.params; public class GOST3410KeyParameters extends AsymmetricKeyParameter { private GOST3410Parameters params; public GOST3410KeyParameters( boolean isPrivate, GOST3410Parameters params) { super(isPrivate); this.params = params; } public GOST3410Parameters getParameters() { return params; } } bouncycastle-1.49.orig/src/org/bouncycastle/crypto/params/DSAValidationParameters.java0000644000175000017500000000227612143300470030617 0ustar ebourgebourgpackage org.bouncycastle.crypto.params; import org.bouncycastle.util.Arrays; public class DSAValidationParameters { private int usageIndex; private byte[] seed; private int counter; public DSAValidationParameters( byte[] seed, int counter) { this(seed, counter, -1); } public DSAValidationParameters( byte[] seed, int counter, int usageIndex) { this.seed = seed; this.counter = counter; this.usageIndex = usageIndex; } public int getCounter() { return counter; } public byte[] getSeed() { return seed; } public int getUsageIndex() { return usageIndex; } public int hashCode() { return counter ^ Arrays.hashCode(seed); } public boolean equals( Object o) { if (!(o instanceof DSAValidationParameters)) { return false; } DSAValidationParameters other = (DSAValidationParameters)o; if (other.counter != this.counter) { return false; } return Arrays.areEqual(this.seed, other.seed); } } bouncycastle-1.49.orig/src/org/bouncycastle/crypto/params/DHKeyGenerationParameters.java0000644000175000017500000000121711160037207031152 0ustar ebourgebourgpackage org.bouncycastle.crypto.params; import java.security.SecureRandom; import org.bouncycastle.crypto.KeyGenerationParameters; public class DHKeyGenerationParameters extends KeyGenerationParameters { private DHParameters params; public DHKeyGenerationParameters( SecureRandom random, DHParameters params) { super(random, getStrength(params)); this.params = params; } public DHParameters getParameters() { return params; } static int getStrength(DHParameters params) { return params.getL() != 0 ? params.getL() : params.getP().bitLength(); } } bouncycastle-1.49.orig/src/org/bouncycastle/crypto/params/ElGamalPrivateKeyParameters.java0000644000175000017500000000152210324400067031476 0ustar ebourgebourgpackage org.bouncycastle.crypto.params; import java.math.BigInteger; public class ElGamalPrivateKeyParameters extends ElGamalKeyParameters { private BigInteger x; public ElGamalPrivateKeyParameters( BigInteger x, ElGamalParameters params) { super(true, params); this.x = x; } public BigInteger getX() { return x; } public boolean equals( Object obj) { if (!(obj instanceof ElGamalPrivateKeyParameters)) { return false; } ElGamalPrivateKeyParameters pKey = (ElGamalPrivateKeyParameters)obj; if (!pKey.getX().equals(x)) { return false; } return super.equals(obj); } public int hashCode() { return getX().hashCode(); } } bouncycastle-1.49.orig/src/org/bouncycastle/crypto/params/DHKeyParameters.java0000644000175000017500000000175410324400067027143 0ustar ebourgebourgpackage org.bouncycastle.crypto.params; public class DHKeyParameters extends AsymmetricKeyParameter { private DHParameters params; protected DHKeyParameters( boolean isPrivate, DHParameters params) { super(isPrivate); this.params = params; } public DHParameters getParameters() { return params; } public boolean equals( Object obj) { if (!(obj instanceof DHKeyParameters)) { return false; } DHKeyParameters dhKey = (DHKeyParameters)obj; if (params == null) { return dhKey.getParameters() == null; } else { return params.equals(dhKey.getParameters()); } } public int hashCode() { int code = isPrivate() ? 0 : 1; if (params != null) { code ^= params.hashCode(); } return code; } } bouncycastle-1.49.orig/src/org/bouncycastle/crypto/params/DSAKeyGenerationParameters.java0000644000175000017500000000102112143300470031254 0ustar ebourgebourgpackage org.bouncycastle.crypto.params; import java.security.SecureRandom; import org.bouncycastle.crypto.KeyGenerationParameters; public class DSAKeyGenerationParameters extends KeyGenerationParameters { private DSAParameters params; public DSAKeyGenerationParameters( SecureRandom random, DSAParameters params) { super(random, params.getP().bitLength() - 1); this.params = params; } public DSAParameters getParameters() { return params; } } bouncycastle-1.49.orig/src/org/bouncycastle/crypto/params/DSAParameterGenerationParameters.java0000644000175000017500000000371112143300470032454 0ustar ebourgebourgpackage org.bouncycastle.crypto.params; import java.security.SecureRandom; public class DSAParameterGenerationParameters { public static final int DIGITAL_SIGNATURE_USAGE = 1; public static final int KEY_ESTABLISHMENT_USAGE = 2; private final int l; private final int n; private final int usageIndex; private final int certainty; private final SecureRandom random; /** * Construct without a usage index, this will do a random construction of G. * * @param L desired length of prime P in bits (the effective key size). * @param N desired length of prime Q in bits. * @param certainty certainty level for prime number generation. * @param random the source of randomness to use. */ public DSAParameterGenerationParameters( int L, int N, int certainty, SecureRandom random) { this(L, N, certainty, random, -1); } /** * Construct for a specific usage index - this has the effect of using verifiable canonical generation of G. * * @param L desired length of prime P in bits (the effective key size). * @param N desired length of prime Q in bits. * @param certainty certainty level for prime number generation. * @param random the source of randomness to use. * @param usageIndex a valid usage index. */ public DSAParameterGenerationParameters( int L, int N, int certainty, SecureRandom random, int usageIndex) { this.l = L; this.n = N; this.certainty = certainty; this.usageIndex = usageIndex; this.random = random; } public int getL() { return l; } public int getN() { return n; } public int getCertainty() { return certainty; } public SecureRandom getRandom() { return random; } public int getUsageIndex() { return usageIndex; } } bouncycastle-1.49.orig/src/org/bouncycastle/crypto/params/RSAKeyGenerationParameters.java0000644000175000017500000000213310377036303031307 0ustar ebourgebourgpackage org.bouncycastle.crypto.params; import java.math.BigInteger; import java.security.SecureRandom; import org.bouncycastle.crypto.KeyGenerationParameters; public class RSAKeyGenerationParameters extends KeyGenerationParameters { private BigInteger publicExponent; private int certainty; public RSAKeyGenerationParameters( BigInteger publicExponent, SecureRandom random, int strength, int certainty) { super(random, strength); if (strength < 12) { throw new IllegalArgumentException("key strength too small"); } // // public exponent cannot be even // if (!publicExponent.testBit(0)) { throw new IllegalArgumentException("public exponent cannot be even"); } this.publicExponent = publicExponent; this.certainty = certainty; } public BigInteger getPublicExponent() { return publicExponent; } public int getCertainty() { return certainty; } } bouncycastle-1.49.orig/src/org/bouncycastle/crypto/params/DSAPrivateKeyParameters.java0000644000175000017500000000061112143300470030577 0ustar ebourgebourgpackage org.bouncycastle.crypto.params; import java.math.BigInteger; public class DSAPrivateKeyParameters extends DSAKeyParameters { private BigInteger x; public DSAPrivateKeyParameters( BigInteger x, DSAParameters params) { super(true, params); this.x = x; } public BigInteger getX() { return x; } } bouncycastle-1.49.orig/src/org/bouncycastle/crypto/params/ECDomainParameters.java0000644000175000017500000000253212132366707027624 0ustar ebourgebourgpackage org.bouncycastle.crypto.params; import java.math.BigInteger; import org.bouncycastle.math.ec.ECConstants; import org.bouncycastle.math.ec.ECCurve; import org.bouncycastle.math.ec.ECPoint; import org.bouncycastle.util.Arrays; public class ECDomainParameters implements ECConstants { private ECCurve curve; private byte[] seed; private ECPoint G; private BigInteger n; private BigInteger h; public ECDomainParameters( ECCurve curve, ECPoint G, BigInteger n) { this(curve, G, n, ONE, null); } public ECDomainParameters( ECCurve curve, ECPoint G, BigInteger n, BigInteger h) { this(curve, G, n, h, null); } public ECDomainParameters( ECCurve curve, ECPoint G, BigInteger n, BigInteger h, byte[] seed) { this.curve = curve; this.G = G; this.n = n; this.h = h; this.seed = seed; } public ECCurve getCurve() { return curve; } public ECPoint getG() { return G; } public BigInteger getN() { return n; } public BigInteger getH() { return h; } public byte[] getSeed() { return Arrays.clone(seed); } } bouncycastle-1.49.orig/src/org/bouncycastle/crypto/params/DSAParameters.java0000644000175000017500000000271712143300470026604 0ustar ebourgebourgpackage org.bouncycastle.crypto.params; import java.math.BigInteger; import org.bouncycastle.crypto.CipherParameters; public class DSAParameters implements CipherParameters { private BigInteger g; private BigInteger q; private BigInteger p; private DSAValidationParameters validation; public DSAParameters( BigInteger p, BigInteger q, BigInteger g) { this.g = g; this.p = p; this.q = q; } public DSAParameters( BigInteger p, BigInteger q, BigInteger g, DSAValidationParameters params) { this.g = g; this.p = p; this.q = q; this.validation = params; } public BigInteger getP() { return p; } public BigInteger getQ() { return q; } public BigInteger getG() { return g; } public DSAValidationParameters getValidationParameters() { return validation; } public boolean equals( Object obj) { if (!(obj instanceof DSAParameters)) { return false; } DSAParameters pm = (DSAParameters)obj; return (pm.getP().equals(p) && pm.getQ().equals(q) && pm.getG().equals(g)); } public int hashCode() { return getP().hashCode() ^ getQ().hashCode() ^ getG().hashCode(); } } bouncycastle-1.49.orig/src/org/bouncycastle/crypto/params/MGFParameters.java0000644000175000017500000000111210531736712026605 0ustar ebourgebourgpackage org.bouncycastle.crypto.params; import org.bouncycastle.crypto.DerivationParameters; /** * parameters for mask derivation functions. */ public class MGFParameters implements DerivationParameters { byte[] seed; public MGFParameters( byte[] seed) { this(seed, 0, seed.length); } public MGFParameters( byte[] seed, int off, int len) { this.seed = new byte[len]; System.arraycopy(seed, off, this.seed, 0, len); } public byte[] getSeed() { return seed; } } bouncycastle-1.49.orig/src/org/bouncycastle/crypto/params/ParametersWithRandom.java0000644000175000017500000000136710531736712030264 0ustar ebourgebourgpackage org.bouncycastle.crypto.params; import org.bouncycastle.crypto.CipherParameters; import java.security.SecureRandom; public class ParametersWithRandom implements CipherParameters { private SecureRandom random; private CipherParameters parameters; public ParametersWithRandom( CipherParameters parameters, SecureRandom random) { this.random = random; this.parameters = parameters; } public ParametersWithRandom( CipherParameters parameters) { this(parameters, new SecureRandom()); } public SecureRandom getRandom() { return random; } public CipherParameters getParameters() { return parameters; } } bouncycastle-1.49.orig/src/org/bouncycastle/crypto/params/NaccacheSternPrivateKeyParameters.java0000644000175000017500000000251710452105155032704 0ustar ebourgebourgpackage org.bouncycastle.crypto.params; import java.math.BigInteger; import java.util.Vector; /** * Private key parameters for NaccacheStern cipher. For details on this cipher, * please see * * http://www.gemplus.com/smart/rd/publications/pdf/NS98pkcs.pdf */ public class NaccacheSternPrivateKeyParameters extends NaccacheSternKeyParameters { private BigInteger phi_n; private Vector smallPrimes; /** * Constructs a NaccacheSternPrivateKey * * @param g * the public enryption parameter g * @param n * the public modulus n = p*q * @param lowerSigmaBound * the public lower sigma bound up to which data can be encrypted * @param smallPrimes * the small primes, of which sigma is constructed in the right * order * @param phi_n * the private modulus phi(n) = (p-1)(q-1) */ public NaccacheSternPrivateKeyParameters(BigInteger g, BigInteger n, int lowerSigmaBound, Vector smallPrimes, BigInteger phi_n) { super(true, g, n, lowerSigmaBound); this.smallPrimes = smallPrimes; this.phi_n = phi_n; } public BigInteger getPhi_n() { return phi_n; } public Vector getSmallPrimes() { return smallPrimes; } } bouncycastle-1.49.orig/src/org/bouncycastle/crypto/params/ECKeyGenerationParameters.java0000644000175000017500000000111510262753175031156 0ustar ebourgebourgpackage org.bouncycastle.crypto.params; import java.security.SecureRandom; import org.bouncycastle.crypto.KeyGenerationParameters; public class ECKeyGenerationParameters extends KeyGenerationParameters { private ECDomainParameters domainParams; public ECKeyGenerationParameters( ECDomainParameters domainParams, SecureRandom random) { super(random, domainParams.getN().bitLength()); this.domainParams = domainParams; } public ECDomainParameters getDomainParameters() { return domainParams; } } bouncycastle-1.49.orig/src/org/bouncycastle/crypto/params/IESParameters.java0000644000175000017500000000172500000712227026607 0ustar ebourgebourgpackage org.bouncycastle.crypto.params; import org.bouncycastle.crypto.CipherParameters; /** * parameters for using an integrated cipher in stream mode. */ public class IESParameters implements CipherParameters { private byte[] derivation; private byte[] encoding; private int macKeySize; /** * @param derivation the derivation parameter for the KDF function. * @param encoding the encoding parameter for the KDF function. * @param macKeySize the size of the MAC key (in bits). */ public IESParameters( byte[] derivation, byte[] encoding, int macKeySize) { this.derivation = derivation; this.encoding = encoding; this.macKeySize = macKeySize; } public byte[] getDerivationV() { return derivation; } public byte[] getEncodingV() { return encoding; } public int getMacKeySize() { return macKeySize; } } bouncycastle-1.49.orig/src/org/bouncycastle/crypto/params/DSAKeyParameters.java0000644000175000017500000000061112143300470027244 0ustar ebourgebourgpackage org.bouncycastle.crypto.params; public class DSAKeyParameters extends AsymmetricKeyParameter { private DSAParameters params; public DSAKeyParameters( boolean isPrivate, DSAParameters params) { super(isPrivate); this.params = params; } public DSAParameters getParameters() { return params; } } bouncycastle-1.49.orig/src/org/bouncycastle/crypto/params/AsymmetricKeyParameter.java0000644000175000017500000000056410262753175030614 0ustar ebourgebourgpackage org.bouncycastle.crypto.params; import org.bouncycastle.crypto.CipherParameters; public class AsymmetricKeyParameter implements CipherParameters { boolean privateKey; public AsymmetricKeyParameter( boolean privateKey) { this.privateKey = privateKey; } public boolean isPrivate() { return privateKey; } } bouncycastle-1.49.orig/src/org/bouncycastle/crypto/params/KDFParameters.java0000644000175000017500000000102210427071732026576 0ustar ebourgebourgpackage org.bouncycastle.crypto.params; import org.bouncycastle.crypto.DerivationParameters; /** * parameters for Key derivation functions for IEEE P1363a */ public class KDFParameters implements DerivationParameters { byte[] iv; byte[] shared; public KDFParameters( byte[] shared, byte[] iv) { this.shared = shared; this.iv = iv; } public byte[] getSharedSecret() { return shared; } public byte[] getIV() { return iv; } } bouncycastle-1.49.orig/src/org/bouncycastle/crypto/params/ElGamalPublicKeyParameters.java0000644000175000017500000000144110531563007031306 0ustar ebourgebourgpackage org.bouncycastle.crypto.params; import java.math.BigInteger; public class ElGamalPublicKeyParameters extends ElGamalKeyParameters { private BigInteger y; public ElGamalPublicKeyParameters( BigInteger y, ElGamalParameters params) { super(false, params); this.y = y; } public BigInteger getY() { return y; } public int hashCode() { return y.hashCode() ^ super.hashCode(); } public boolean equals( Object obj) { if (!(obj instanceof ElGamalPublicKeyParameters)) { return false; } ElGamalPublicKeyParameters other = (ElGamalPublicKeyParameters)obj; return other.getY().equals(y) && super.equals(obj); } } bouncycastle-1.49.orig/src/org/bouncycastle/crypto/params/DSAPublicKeyParameters.java0000644000175000017500000000061012143300470030402 0ustar ebourgebourgpackage org.bouncycastle.crypto.params; import java.math.BigInteger; public class DSAPublicKeyParameters extends DSAKeyParameters { private BigInteger y; public DSAPublicKeyParameters( BigInteger y, DSAParameters params) { super(false, params); this.y = y; } public BigInteger getY() { return y; } } bouncycastle-1.49.orig/src/org/bouncycastle/crypto/params/GOST3410ValidationParameters.java0000644000175000017500000000252410505533600031273 0ustar ebourgebourgpackage org.bouncycastle.crypto.params; public class GOST3410ValidationParameters { private int x0; private int c; private long x0L; private long cL; public GOST3410ValidationParameters( int x0, int c) { this.x0 = x0; this.c = c; } public GOST3410ValidationParameters( long x0L, long cL) { this.x0L = x0L; this.cL = cL; } public int getC() { return c; } public int getX0() { return x0; } public long getCL() { return cL; } public long getX0L() { return x0L; } public boolean equals( Object o) { if (!(o instanceof GOST3410ValidationParameters)) { return false; } GOST3410ValidationParameters other = (GOST3410ValidationParameters)o; if (other.c != this.c) { return false; } if (other.x0 != this.x0) { return false; } if (other.cL != this.cL) { return false; } if (other.x0L != this.x0L) { return false; } return true; } public int hashCode() { return x0 ^ c ^ (int) x0L ^ (int)(x0L >> 32) ^ (int) cL ^ (int)(cL >> 32); } } bouncycastle-1.49.orig/src/org/bouncycastle/crypto/params/ParametersWithSBox.java0000644000175000017500000000105710262753175027716 0ustar ebourgebourgpackage org.bouncycastle.crypto.params; import org.bouncycastle.crypto.CipherParameters; public class ParametersWithSBox implements CipherParameters { private CipherParameters parameters; private byte[] sBox; public ParametersWithSBox( CipherParameters parameters, byte[] sBox) { this.parameters = parameters; this.sBox = sBox; } public byte[] getSBox() { return sBox; } public CipherParameters getParameters() { return parameters; } } bouncycastle-1.49.orig/src/org/bouncycastle/crypto/params/GOST3410PrivateKeyParameters.java0000644000175000017500000000063610262753175031301 0ustar ebourgebourgpackage org.bouncycastle.crypto.params; import java.math.BigInteger; public class GOST3410PrivateKeyParameters extends GOST3410KeyParameters { private BigInteger x; public GOST3410PrivateKeyParameters( BigInteger x, GOST3410Parameters params) { super(true, params); this.x = x; } public BigInteger getX() { return x; } } bouncycastle-1.49.orig/src/org/bouncycastle/crypto/params/GOST3410KeyGenerationParameters.java0000644000175000017500000000113610262753175031756 0ustar ebourgebourgpackage org.bouncycastle.crypto.params; import org.bouncycastle.crypto.KeyGenerationParameters; import java.security.SecureRandom; public class GOST3410KeyGenerationParameters extends KeyGenerationParameters { private GOST3410Parameters params; public GOST3410KeyGenerationParameters( SecureRandom random, GOST3410Parameters params) { super(random, params.getP().bitLength() - 1); this.params = params; } public GOST3410Parameters getParameters() { return params; } } bouncycastle-1.49.orig/src/org/bouncycastle/crypto/params/DESedeParameters.java0000644000175000017500000000252510531736712027276 0ustar ebourgebourgpackage org.bouncycastle.crypto.params; public class DESedeParameters extends DESParameters { /* * DES-EDE Key length in bytes. */ static public final int DES_EDE_KEY_LENGTH = 24; public DESedeParameters( byte[] key) { super(key); if (isWeakKey(key, 0, key.length)) { throw new IllegalArgumentException("attempt to create weak DESede key"); } } /** * return true if the passed in key is a DES-EDE weak key. * * @param key bytes making up the key * @param offset offset into the byte array the key starts at * @param length number of bytes making up the key */ public static boolean isWeakKey( byte[] key, int offset, int length) { for (int i = offset; i < length; i += DES_KEY_LENGTH) { if (DESParameters.isWeakKey(key, i)) { return true; } } return false; } /** * return true if the passed in key is a DES-EDE weak key. * * @param key bytes making up the key * @param offset offset into the byte array the key starts at */ public static boolean isWeakKey( byte[] key, int offset) { return isWeakKey(key, offset, key.length - offset); } } bouncycastle-1.49.orig/src/org/bouncycastle/crypto/params/package.html0000644000175000017500000000015210262753175025574 0ustar ebourgebourg Classes for parameter objects for ciphers and generators. bouncycastle-1.49.orig/src/org/bouncycastle/crypto/params/ParametersWithIV.java0000644000175000017500000000152310262753175027357 0ustar ebourgebourgpackage org.bouncycastle.crypto.params; import org.bouncycastle.crypto.CipherParameters; public class ParametersWithIV implements CipherParameters { private byte[] iv; private CipherParameters parameters; public ParametersWithIV( CipherParameters parameters, byte[] iv) { this(parameters, iv, 0, iv.length); } public ParametersWithIV( CipherParameters parameters, byte[] iv, int ivOff, int ivLen) { this.iv = new byte[ivLen]; this.parameters = parameters; System.arraycopy(iv, ivOff, this.iv, 0, ivLen); } public byte[] getIV() { return iv; } public CipherParameters getParameters() { return parameters; } } bouncycastle-1.49.orig/src/org/bouncycastle/crypto/params/RC2Parameters.java0000644000175000017500000000123610262753175026574 0ustar ebourgebourgpackage org.bouncycastle.crypto.params; import org.bouncycastle.crypto.CipherParameters; public class RC2Parameters implements CipherParameters { private byte[] key; private int bits; public RC2Parameters( byte[] key) { this(key, (key.length > 128) ? 1024 : (key.length * 8)); } public RC2Parameters( byte[] key, int bits) { this.key = new byte[key.length]; this.bits = bits; System.arraycopy(key, 0, this.key, 0, key.length); } public byte[] getKey() { return key; } public int getEffectiveKeyBits() { return bits; } } bouncycastle-1.49.orig/src/org/bouncycastle/crypto/params/DHPrivateKeyParameters.java0000644000175000017500000000141210531563007030471 0ustar ebourgebourgpackage org.bouncycastle.crypto.params; import java.math.BigInteger; public class DHPrivateKeyParameters extends DHKeyParameters { private BigInteger x; public DHPrivateKeyParameters( BigInteger x, DHParameters params) { super(true, params); this.x = x; } public BigInteger getX() { return x; } public int hashCode() { return x.hashCode() ^ super.hashCode(); } public boolean equals( Object obj) { if (!(obj instanceof DHPrivateKeyParameters)) { return false; } DHPrivateKeyParameters other = (DHPrivateKeyParameters)obj; return other.getX().equals(this.x) && super.equals(obj); } } bouncycastle-1.49.orig/src/org/bouncycastle/crypto/params/AEADParameters.java0000644000175000017500000000245312045616304026673 0ustar ebourgebourgpackage org.bouncycastle.crypto.params; import org.bouncycastle.crypto.CipherParameters; public class AEADParameters implements CipherParameters { private byte[] associatedText; private byte[] nonce; private KeyParameter key; private int macSize; /** * Base constructor. * * @param key key to be used by underlying cipher * @param macSize macSize in bits * @param nonce nonce to be used */ public AEADParameters(KeyParameter key, int macSize, byte[] nonce) { this(key, macSize, nonce, null); } /** * Base constructor. * * @param key key to be used by underlying cipher * @param macSize macSize in bits * @param nonce nonce to be used * @param associatedText initial associated text, if any */ public AEADParameters(KeyParameter key, int macSize, byte[] nonce, byte[] associatedText) { this.key = key; this.nonce = nonce; this.macSize = macSize; this.associatedText = associatedText; } public KeyParameter getKey() { return key; } public int getMacSize() { return macSize; } public byte[] getAssociatedText() { return associatedText; } public byte[] getNonce() { return nonce; } } bouncycastle-1.49.orig/src/org/bouncycastle/crypto/params/ECPrivateKeyParameters.java0000644000175000017500000000057510262753175030506 0ustar ebourgebourgpackage org.bouncycastle.crypto.params; import java.math.BigInteger; public class ECPrivateKeyParameters extends ECKeyParameters { BigInteger d; public ECPrivateKeyParameters( BigInteger d, ECDomainParameters params) { super(true, params); this.d = d; } public BigInteger getD() { return d; } } bouncycastle-1.49.orig/src/org/bouncycastle/crypto/StreamCipher.java0000644000175000017500000000331410602132520025243 0ustar ebourgebourgpackage org.bouncycastle.crypto; /** * the interface stream ciphers conform to. */ public interface StreamCipher { /** * Initialise the cipher. * * @param forEncryption if true the cipher is initialised for * encryption, if false for decryption. * @param params the key and other data required by the cipher. * @exception IllegalArgumentException if the params argument is * inappropriate. */ public void init(boolean forEncryption, CipherParameters params) throws IllegalArgumentException; /** * Return the name of the algorithm the cipher implements. * * @return the name of the algorithm the cipher implements. */ public String getAlgorithmName(); /** * encrypt/decrypt a single byte returning the result. * * @param in the byte to be processed. * @return the result of processing the input byte. */ public byte returnByte(byte in); /** * process a block of bytes from in putting the result into out. * * @param in the input byte array. * @param inOff the offset into the in array where the data to be processed starts. * @param len the number of bytes to be processed. * @param out the output buffer the processed bytes go into. * @param outOff the offset into the output byte array the processed data starts at. * @exception DataLengthException if the output buffer is too small. */ public void processBytes(byte[] in, int inOff, int len, byte[] out, int outOff) throws DataLengthException; /** * reset the cipher. This leaves it in the same state * it was at after the last init (if there was one). */ public void reset(); } bouncycastle-1.49.orig/src/org/bouncycastle/crypto/examples/0000755000175000017500000000000012152033551023635 5ustar ebourgebourgbouncycastle-1.49.orig/src/org/bouncycastle/crypto/examples/DESExample.java0000644000175000017500000003156711251100323026432 0ustar ebourgebourgpackage org.bouncycastle.crypto.examples; import java.io.BufferedInputStream; import java.io.BufferedOutputStream; import java.io.BufferedReader; import java.io.FileInputStream; import java.io.FileNotFoundException; import java.io.FileOutputStream; import java.io.IOException; import java.io.InputStreamReader; import java.security.SecureRandom; import org.bouncycastle.crypto.CryptoException; import org.bouncycastle.crypto.KeyGenerationParameters; import org.bouncycastle.crypto.engines.DESedeEngine; import org.bouncycastle.crypto.generators.DESedeKeyGenerator; import org.bouncycastle.crypto.modes.CBCBlockCipher; import org.bouncycastle.crypto.paddings.PaddedBufferedBlockCipher; import org.bouncycastle.crypto.params.DESedeParameters; import org.bouncycastle.crypto.params.KeyParameter; import org.bouncycastle.util.encoders.Hex; /** * DESExample is a simple DES based encryptor/decryptor. *

    * The program is command line driven, with the input * and output files specified on the command line. *

     * java org.bouncycastle.crypto.examples.DESExample infile outfile [keyfile]
     * 
    * A new key is generated for each encryption, if key is not specified, * then the example will assume encryption is required, and as output * create deskey.dat in the current directory. This key is a hex * encoded byte-stream that is used for the decryption. The output * file is Hex encoded, 60 characters wide text file. *

    * When encrypting; *

      *
    • the infile is expected to be a byte stream (text or binary) *
    • there is no keyfile specified on the input line *
    *

    * When decrypting; *

  • the infile is expected to be the 60 character wide base64 * encoded file *
  • the keyfile is expected to be a base64 encoded file *

    * This example shows how to use the light-weight API, DES and * the filesystem for message encryption and decryption. * */ public class DESExample extends Object { // Encrypting or decrypting ? private boolean encrypt = true; // To hold the initialised DESede cipher private PaddedBufferedBlockCipher cipher = null; // The input stream of bytes to be processed for encryption private BufferedInputStream in = null; // The output stream of bytes to be procssed private BufferedOutputStream out = null; // The key private byte[] key = null; /* * start the application */ public static void main(String[] args) { boolean encrypt = true; String infile = null; String outfile = null; String keyfile = null; if (args.length < 2) { DESExample de = new DESExample(); System.err.println("Usage: java "+de.getClass().getName()+ " infile outfile [keyfile]"); System.exit(1); } keyfile = "deskey.dat"; infile = args[0]; outfile = args[1]; if (args.length > 2) { encrypt = false; keyfile = args[2]; } DESExample de = new DESExample(infile, outfile, keyfile, encrypt); de.process(); } // Default constructor, used for the usage message public DESExample() { } /* * Constructor, that takes the arguments appropriate for * processing the command line directives. */ public DESExample( String infile, String outfile, String keyfile, boolean encrypt) { /* * First, determine that infile & keyfile exist as appropriate. * * This will also create the BufferedInputStream as required * for reading the input file. All input files are treated * as if they are binary, even if they contain text, it's the * bytes that are encrypted. */ this.encrypt = encrypt; try { in = new BufferedInputStream(new FileInputStream(infile)); } catch (FileNotFoundException fnf) { System.err.println("Input file not found ["+infile+"]"); System.exit(1); } try { out = new BufferedOutputStream(new FileOutputStream(outfile)); } catch (IOException fnf) { System.err.println("Output file not created ["+outfile+"]"); System.exit(1); } if (encrypt) { try { /* * The process of creating a new key requires a * number of steps. * * First, create the parameters for the key generator * which are a secure random number generator, and * the length of the key (in bits). */ SecureRandom sr = null; try { sr = new SecureRandom(); /* * This following call to setSeed() makes the * initialisation of the SecureRandom object * _very_ fast, but not secure AT ALL. * * Remove the line, recreate the class file and * then run DESExample again to see the difference. * * The initialisation of a SecureRandom object * can take 5 or more seconds depending on the * CPU that the program is running on. That can * be annoying during unit testing. * -- jon */ sr.setSeed("www.bouncycastle.org".getBytes()); } catch (Exception nsa) { System.err.println("Hmmm, no SHA1PRNG, you need the "+ "Sun implementation"); System.exit(1); } KeyGenerationParameters kgp = new KeyGenerationParameters( sr, DESedeParameters.DES_EDE_KEY_LENGTH*8); /* * Second, initialise the key generator with the parameters */ DESedeKeyGenerator kg = new DESedeKeyGenerator(); kg.init(kgp); /* * Third, and finally, generate the key */ key = kg.generateKey(); /* * We can now output the key to the file, but first * hex encode the key so that we can have a look * at it with a text editor if we so desire */ BufferedOutputStream keystream = new BufferedOutputStream(new FileOutputStream(keyfile)); byte[] keyhex = Hex.encode(key); keystream.write(keyhex, 0, keyhex.length); keystream.flush(); keystream.close(); } catch (IOException createKey) { System.err.println("Could not decryption create key file "+ "["+keyfile+"]"); System.exit(1); } } else { try { // read the key, and decode from hex encoding BufferedInputStream keystream = new BufferedInputStream(new FileInputStream(keyfile)); int len = keystream.available(); byte[] keyhex = new byte[len]; keystream.read(keyhex, 0, len); key = Hex.decode(keyhex); } catch (IOException ioe) { System.err.println("Decryption key file not found, "+ "or not valid ["+keyfile+"]"); System.exit(1); } } } private void process() { /* * Setup the DESede cipher engine, create a PaddedBufferedBlockCipher * in CBC mode. */ cipher = new PaddedBufferedBlockCipher( new CBCBlockCipher(new DESedeEngine())); /* * The input and output streams are currently set up * appropriately, and the key bytes are ready to be * used. * */ if (encrypt) { performEncrypt(key); } else { performDecrypt(key); } // after processing clean up the files try { in.close(); out.flush(); out.close(); } catch (IOException closing) { } } /* * This method performs all the encryption and writes * the cipher text to the buffered output stream created * previously. */ private void performEncrypt(byte[] key) { // initialise the cipher with the key bytes, for encryption cipher.init(true, new KeyParameter(key)); /* * Create some temporary byte arrays for use in * encryption, make them a reasonable size so that * we don't spend forever reading small chunks from * a file. * * There is no particular reason for using getBlockSize() * to determine the size of the input chunk. It just * was a convenient number for the example. */ // int inBlockSize = cipher.getBlockSize() * 5; int inBlockSize = 47; int outBlockSize = cipher.getOutputSize(inBlockSize); byte[] inblock = new byte[inBlockSize]; byte[] outblock = new byte[outBlockSize]; /* * now, read the file, and output the chunks */ try { int inL; int outL; byte[] rv = null; while ((inL=in.read(inblock, 0, inBlockSize)) > 0) { outL = cipher.processBytes(inblock, 0, inL, outblock, 0); /* * Before we write anything out, we need to make sure * that we've got something to write out. */ if (outL > 0) { rv = Hex.encode(outblock, 0, outL); out.write(rv, 0, rv.length); out.write('\n'); } } try { /* * Now, process the bytes that are still buffered * within the cipher. */ outL = cipher.doFinal(outblock, 0); if (outL > 0) { rv = Hex.encode(outblock, 0, outL); out.write(rv, 0, rv.length); out.write('\n'); } } catch (CryptoException ce) { } } catch (IOException ioeread) { ioeread.printStackTrace(); } } /* * This method performs all the decryption and writes * the plain text to the buffered output stream created * previously. */ private void performDecrypt(byte[] key) { // initialise the cipher for decryption cipher.init(false, new KeyParameter(key)); /* * As the decryption is from our preformatted file, * and we know that it's a hex encoded format, then * we wrap the InputStream with a BufferedReader * so that we can read it easily. */ BufferedReader br = new BufferedReader(new InputStreamReader(in)); /* * now, read the file, and output the chunks */ try { int outL; byte[] inblock = null; byte[] outblock = null; String rv = null; while ((rv = br.readLine()) != null) { inblock = Hex.decode(rv); outblock = new byte[cipher.getOutputSize(inblock.length)]; outL = cipher.processBytes(inblock, 0, inblock.length, outblock, 0); /* * Before we write anything out, we need to make sure * that we've got something to write out. */ if (outL > 0) { out.write(outblock, 0, outL); } } try { /* * Now, process the bytes that are still buffered * within the cipher. */ outL = cipher.doFinal(outblock, 0); if (outL > 0) { out.write(outblock, 0, outL); } } catch (CryptoException ce) { } } catch (IOException ioeread) { ioeread.printStackTrace(); } } } bouncycastle-1.49.orig/src/org/bouncycastle/crypto/examples/JPAKEExample.java0000644000175000017500000002206512064000023026641 0ustar ebourgebourgpackage org.bouncycastle.crypto.examples; import java.math.BigInteger; import java.security.SecureRandom; import org.bouncycastle.crypto.CryptoException; import org.bouncycastle.crypto.Digest; import org.bouncycastle.crypto.agreement.jpake.JPAKEPrimeOrderGroup; import org.bouncycastle.crypto.agreement.jpake.JPAKEPrimeOrderGroups; import org.bouncycastle.crypto.agreement.jpake.JPAKEParticipant; import org.bouncycastle.crypto.agreement.jpake.JPAKERound1Payload; import org.bouncycastle.crypto.agreement.jpake.JPAKERound2Payload; import org.bouncycastle.crypto.agreement.jpake.JPAKERound3Payload; import org.bouncycastle.crypto.digests.SHA256Digest; /** * An example of a J-PAKE exchange. *

    * * In this example, both Alice and Bob are on the same computer (in the same JVM, in fact). * In reality, Alice and Bob would be in different locations, * and would be sending their generated payloads to each other. */ public class JPAKEExample { public static void main(String args[]) throws CryptoException { /* * Initialization * * Pick an appropriate prime order group to use throughout the exchange. * Note that both participants must use the same group. */ JPAKEPrimeOrderGroup group = JPAKEPrimeOrderGroups.NIST_3072; BigInteger p = group.getP(); BigInteger q = group.getQ(); BigInteger g = group.getG(); String alicePassword = "password"; String bobPassword = "password"; System.out.println("********* Initialization **********"); System.out.println("Public parameters for the cyclic group:"); System.out.println("p (" + p.bitLength() + " bits): " + p.toString(16)); System.out.println("q (" + q.bitLength() + " bits): " + q.toString(16)); System.out.println("g (" + p.bitLength() + " bits): " + g.toString(16)); System.out.println("p mod q = " + p.mod(q).toString(16)); System.out.println("g^{q} mod p = " + g.modPow(q, p).toString(16)); System.out.println(""); System.out.println("(Secret passwords used by Alice and Bob: " + "\"" + alicePassword + "\" and \"" + bobPassword + "\")\n"); /* * Both participants must use the same hashing algorithm. */ Digest digest = new SHA256Digest(); SecureRandom random = new SecureRandom(); JPAKEParticipant alice = new JPAKEParticipant("alice", alicePassword.toCharArray(), group, digest, random); JPAKEParticipant bob = new JPAKEParticipant("bob", bobPassword.toCharArray(), group, digest, random); /* * Round 1 * * Alice and Bob each generate a round 1 payload, and send it to each other. */ JPAKERound1Payload aliceRound1Payload = alice.createRound1PayloadToSend(); JPAKERound1Payload bobRound1Payload = bob.createRound1PayloadToSend(); System.out.println("************ Round 1 **************"); System.out.println("Alice sends to Bob: "); System.out.println("g^{x1}=" + aliceRound1Payload.getGx1().toString(16)); System.out.println("g^{x2}=" + aliceRound1Payload.getGx2().toString(16)); System.out.println("KP{x1}={" + aliceRound1Payload.getKnowledgeProofForX1()[0].toString(16) + "};{" + aliceRound1Payload.getKnowledgeProofForX1()[1].toString(16) + "}"); System.out.println("KP{x2}={" + aliceRound1Payload.getKnowledgeProofForX2()[0].toString(16) + "};{" + aliceRound1Payload.getKnowledgeProofForX2()[1].toString(16) + "}"); System.out.println(""); System.out.println("Bob sends to Alice: "); System.out.println("g^{x3}=" + bobRound1Payload.getGx1().toString(16)); System.out.println("g^{x4}=" + bobRound1Payload.getGx2().toString(16)); System.out.println("KP{x3}={" + bobRound1Payload.getKnowledgeProofForX1()[0].toString(16) + "};{" + bobRound1Payload.getKnowledgeProofForX1()[1].toString(16) + "}"); System.out.println("KP{x4}={" + bobRound1Payload.getKnowledgeProofForX2()[0].toString(16) + "};{" + bobRound1Payload.getKnowledgeProofForX2()[1].toString(16) + "}"); System.out.println(""); /* * Each participant must then validate the received payload for round 1 */ alice.validateRound1PayloadReceived(bobRound1Payload); System.out.println("Alice checks g^{x4}!=1: OK"); System.out.println("Alice checks KP{x3}: OK"); System.out.println("Alice checks KP{x4}: OK"); System.out.println(""); bob.validateRound1PayloadReceived(aliceRound1Payload); System.out.println("Bob checks g^{x2}!=1: OK"); System.out.println("Bob checks KP{x1},: OK"); System.out.println("Bob checks KP{x2},: OK"); System.out.println(""); /* * Round 2 * * Alice and Bob each generate a round 2 payload, and send it to each other. */ JPAKERound2Payload aliceRound2Payload = alice.createRound2PayloadToSend(); JPAKERound2Payload bobRound2Payload = bob.createRound2PayloadToSend(); System.out.println("************ Round 2 **************"); System.out.println("Alice sends to Bob: "); System.out.println("A=" + aliceRound2Payload.getA().toString(16)); System.out.println("KP{x2*s}={" + aliceRound2Payload.getKnowledgeProofForX2s()[0].toString(16) + "},{" + aliceRound2Payload.getKnowledgeProofForX2s()[1].toString(16) + "}"); System.out.println(""); System.out.println("Bob sends to Alice"); System.out.println("B=" + bobRound2Payload.getA().toString(16)); System.out.println("KP{x4*s}={" + bobRound2Payload.getKnowledgeProofForX2s()[0].toString(16) + "},{" + bobRound2Payload.getKnowledgeProofForX2s()[1].toString(16) + "}"); System.out.println(""); /* * Each participant must then validate the received payload for round 2 */ alice.validateRound2PayloadReceived(bobRound2Payload); System.out.println("Alice checks KP{x4*s}: OK\n"); bob.validateRound2PayloadReceived(aliceRound2Payload); System.out.println("Bob checks KP{x2*s}: OK\n"); /* * After round 2, each participant computes the keying material. */ BigInteger aliceKeyingMaterial = alice.calculateKeyingMaterial(); BigInteger bobKeyingMaterial = bob.calculateKeyingMaterial(); System.out.println("********* After round 2 ***********"); System.out.println("Alice computes key material \t K=" + aliceKeyingMaterial.toString(16)); System.out.println("Bob computes key material \t K=" + bobKeyingMaterial.toString(16)); System.out.println(); /* * You must derive a session key from the keying material applicable * to whatever encryption algorithm you want to use. */ BigInteger aliceKey = deriveSessionKey(aliceKeyingMaterial); BigInteger bobKey = deriveSessionKey(bobKeyingMaterial); /* * At this point, you can stop and use the session keys if you want. * This is implicit key confirmation. * * If you want to explicitly confirm that the key material matches, * you can continue on and perform round 3. */ /* * Round 3 * * Alice and Bob each generate a round 3 payload, and send it to each other. */ JPAKERound3Payload aliceRound3Payload = alice.createRound3PayloadToSend(aliceKeyingMaterial); JPAKERound3Payload bobRound3Payload = bob.createRound3PayloadToSend(bobKeyingMaterial); System.out.println("************ Round 3 **************"); System.out.println("Alice sends to Bob: "); System.out.println("MacTag=" + aliceRound3Payload.getMacTag().toString(16)); System.out.println(""); System.out.println("Bob sends to Alice: "); System.out.println("MacTag=" + bobRound3Payload.getMacTag().toString(16)); System.out.println(""); /* * Each participant must then validate the received payload for round 3 */ alice.validateRound3PayloadReceived(bobRound3Payload, aliceKeyingMaterial); System.out.println("Alice checks MacTag: OK\n"); bob.validateRound3PayloadReceived(aliceRound3Payload, bobKeyingMaterial); System.out.println("Bob checks MacTag: OK\n"); System.out.println(); System.out.println("MacTags validated, therefore the keying material matches."); } private static BigInteger deriveSessionKey(BigInteger keyingMaterial) { /* * You should use a secure key derivation function (KDF) to derive the session key. * * For the purposes of this example, I'm just going to use a hash of the keying material. */ SHA256Digest digest = new SHA256Digest(); byte[] keyByteArray = keyingMaterial.toByteArray(); byte[] output = new byte[digest.getDigestSize()]; digest.update(keyByteArray, 0, keyByteArray.length); digest.doFinal(output, 0); return new BigInteger(output); } } bouncycastle-1.49.orig/src/org/bouncycastle/crypto/examples/package.html0000644000175000017500000000013310262753175026126 0ustar ebourgebourg Simple examples of light weight API usage. bouncycastle-1.49.orig/src/org/bouncycastle/crypto/Mac.java0000644000175000017500000000433011222021264023355 0ustar ebourgebourgpackage org.bouncycastle.crypto; /** * The base interface for implementations of message authentication codes (MACs). */ public interface Mac { /** * Initialise the MAC. * * @param params the key and other data required by the MAC. * @exception IllegalArgumentException if the params argument is * inappropriate. */ public void init(CipherParameters params) throws IllegalArgumentException; /** * Return the name of the algorithm the MAC implements. * * @return the name of the algorithm the MAC implements. */ public String getAlgorithmName(); /** * Return the block size for this MAC (in bytes). * * @return the block size for this MAC in bytes. */ public int getMacSize(); /** * add a single byte to the mac for processing. * * @param in the byte to be processed. * @exception IllegalStateException if the MAC is not initialised. */ public void update(byte in) throws IllegalStateException; /** * @param in the array containing the input. * @param inOff the index in the array the data begins at. * @param len the length of the input starting at inOff. * @exception IllegalStateException if the MAC is not initialised. * @exception DataLengthException if there isn't enough data in in. */ public void update(byte[] in, int inOff, int len) throws DataLengthException, IllegalStateException; /** * Compute the final stage of the MAC writing the output to the out * parameter. *

    * doFinal leaves the MAC in the same state it was after the last init. * * @param out the array the MAC is to be output to. * @param outOff the offset into the out buffer the output is to start at. * @exception DataLengthException if there isn't enough space in out. * @exception IllegalStateException if the MAC is not initialised. */ public int doFinal(byte[] out, int outOff) throws DataLengthException, IllegalStateException; /** * Reset the MAC. At the end of resetting the MAC should be in the * in the same state it was after the last init (if there was one). */ public void reset(); } bouncycastle-1.49.orig/src/org/bouncycastle/crypto/KeyEncapsulation.java0000755000175000017500000000104412145535177026157 0ustar ebourgebourgpackage org.bouncycastle.crypto; /** * The basic interface for key encapsulation mechanisms. */ public interface KeyEncapsulation { /** * Initialise the key encapsulation mechanism. */ public void init(CipherParameters param); /** * Encapsulate a randomly generated session key. */ public CipherParameters encrypt(byte[] out, int outOff, int keyLen); /** * Decapsulate an encapsulated session key. */ public CipherParameters decrypt(byte[] in, int inOff, int inLen, int keyLen); } bouncycastle-1.49.orig/src/org/bouncycastle/crypto/signers/0000755000175000017500000000000012152033551023471 5ustar ebourgebourgbouncycastle-1.49.orig/src/org/bouncycastle/crypto/signers/GenericSigner.java0000644000175000017500000000663111263524566027103 0ustar ebourgebourgpackage org.bouncycastle.crypto.signers; import org.bouncycastle.crypto.AsymmetricBlockCipher; import org.bouncycastle.crypto.CipherParameters; import org.bouncycastle.crypto.CryptoException; import org.bouncycastle.crypto.DataLengthException; import org.bouncycastle.crypto.Digest; import org.bouncycastle.crypto.Signer; import org.bouncycastle.crypto.params.AsymmetricKeyParameter; import org.bouncycastle.crypto.params.ParametersWithRandom; import org.bouncycastle.util.Arrays; public class GenericSigner implements Signer { private final AsymmetricBlockCipher engine; private final Digest digest; private boolean forSigning; public GenericSigner( AsymmetricBlockCipher engine, Digest digest) { this.engine = engine; this.digest = digest; } /** * initialise the signer for signing or verification. * * @param forSigning * true if for signing, false otherwise * @param parameters * necessary parameters. */ public void init( boolean forSigning, CipherParameters parameters) { this.forSigning = forSigning; AsymmetricKeyParameter k; if (parameters instanceof ParametersWithRandom) { k = (AsymmetricKeyParameter)((ParametersWithRandom)parameters).getParameters(); } else { k = (AsymmetricKeyParameter)parameters; } if (forSigning && !k.isPrivate()) { throw new IllegalArgumentException("signing requires private key"); } if (!forSigning && k.isPrivate()) { throw new IllegalArgumentException("verification requires public key"); } reset(); engine.init(forSigning, parameters); } /** * update the internal digest with the byte b */ public void update( byte input) { digest.update(input); } /** * update the internal digest with the byte array in */ public void update( byte[] input, int inOff, int length) { digest.update(input, inOff, length); } /** * Generate a signature for the message we've been loaded with using the key * we were initialised with. */ public byte[] generateSignature() throws CryptoException, DataLengthException { if (!forSigning) { throw new IllegalStateException("GenericSigner not initialised for signature generation."); } byte[] hash = new byte[digest.getDigestSize()]; digest.doFinal(hash, 0); return engine.processBlock(hash, 0, hash.length); } /** * return true if the internal state represents the signature described in * the passed in array. */ public boolean verifySignature( byte[] signature) { if (forSigning) { throw new IllegalStateException("GenericSigner not initialised for verification"); } byte[] hash = new byte[digest.getDigestSize()]; digest.doFinal(hash, 0); try { byte[] sig = engine.processBlock(signature, 0, signature.length); return Arrays.constantTimeAreEqual(sig, hash); } catch (Exception e) { return false; } } public void reset() { digest.reset(); } } bouncycastle-1.49.orig/src/org/bouncycastle/crypto/signers/ECDSASigner.java0000644000175000017500000001064012112273576026335 0ustar ebourgebourgpackage org.bouncycastle.crypto.signers; import java.math.BigInteger; import java.security.SecureRandom; import org.bouncycastle.crypto.CipherParameters; import org.bouncycastle.crypto.DSA; import org.bouncycastle.crypto.params.ECKeyParameters; import org.bouncycastle.crypto.params.ECPrivateKeyParameters; import org.bouncycastle.crypto.params.ECPublicKeyParameters; import org.bouncycastle.crypto.params.ParametersWithRandom; import org.bouncycastle.math.ec.ECAlgorithms; import org.bouncycastle.math.ec.ECConstants; import org.bouncycastle.math.ec.ECPoint; /** * EC-DSA as described in X9.62 */ public class ECDSASigner implements ECConstants, DSA { ECKeyParameters key; SecureRandom random; public void init( boolean forSigning, CipherParameters param) { if (forSigning) { if (param instanceof ParametersWithRandom) { ParametersWithRandom rParam = (ParametersWithRandom)param; this.random = rParam.getRandom(); this.key = (ECPrivateKeyParameters)rParam.getParameters(); } else { this.random = new SecureRandom(); this.key = (ECPrivateKeyParameters)param; } } else { this.key = (ECPublicKeyParameters)param; } } // 5.3 pg 28 /** * generate a signature for the given message using the key we were * initialised with. For conventional DSA the message should be a SHA-1 * hash of the message of interest. * * @param message the message that will be verified later. */ public BigInteger[] generateSignature( byte[] message) { BigInteger n = key.getParameters().getN(); BigInteger e = calculateE(n, message); BigInteger r = null; BigInteger s = null; // 5.3.2 do // generate s { BigInteger k = null; int nBitLength = n.bitLength(); do // generate r { do { k = new BigInteger(nBitLength, random); } while (k.equals(ZERO) || k.compareTo(n) >= 0); ECPoint p = key.getParameters().getG().multiply(k); // 5.3.3 BigInteger x = p.getX().toBigInteger(); r = x.mod(n); } while (r.equals(ZERO)); BigInteger d = ((ECPrivateKeyParameters)key).getD(); s = k.modInverse(n).multiply(e.add(d.multiply(r))).mod(n); } while (s.equals(ZERO)); BigInteger[] res = new BigInteger[2]; res[0] = r; res[1] = s; return res; } // 5.4 pg 29 /** * return true if the value r and s represent a DSA signature for * the passed in message (for standard DSA the message should be * a SHA-1 hash of the real message to be verified). */ public boolean verifySignature( byte[] message, BigInteger r, BigInteger s) { BigInteger n = key.getParameters().getN(); BigInteger e = calculateE(n, message); // r in the range [1,n-1] if (r.compareTo(ONE) < 0 || r.compareTo(n) >= 0) { return false; } // s in the range [1,n-1] if (s.compareTo(ONE) < 0 || s.compareTo(n) >= 0) { return false; } BigInteger c = s.modInverse(n); BigInteger u1 = e.multiply(c).mod(n); BigInteger u2 = r.multiply(c).mod(n); ECPoint G = key.getParameters().getG(); ECPoint Q = ((ECPublicKeyParameters)key).getQ(); ECPoint point = ECAlgorithms.sumOfTwoMultiplies(G, u1, Q, u2); // components must be bogus. if (point.isInfinity()) { return false; } BigInteger v = point.getX().toBigInteger().mod(n); return v.equals(r); } private BigInteger calculateE(BigInteger n, byte[] message) { int log2n = n.bitLength(); int messageBitLength = message.length * 8; if (log2n >= messageBitLength) { return new BigInteger(1, message); } else { BigInteger trunc = new BigInteger(1, message); trunc = trunc.shiftRight(messageBitLength - log2n); return trunc; } } } bouncycastle-1.49.orig/src/org/bouncycastle/crypto/signers/ISO9796d2Signer.java0000644000175000017500000003706112131437326026737 0ustar ebourgebourgpackage org.bouncycastle.crypto.signers; import java.util.Hashtable; import org.bouncycastle.crypto.AsymmetricBlockCipher; import org.bouncycastle.crypto.CipherParameters; import org.bouncycastle.crypto.CryptoException; import org.bouncycastle.crypto.Digest; import org.bouncycastle.crypto.InvalidCipherTextException; import org.bouncycastle.crypto.SignerWithRecovery; import org.bouncycastle.crypto.params.RSAKeyParameters; import org.bouncycastle.util.Arrays; import org.bouncycastle.util.Integers; /** * ISO9796-2 - mechanism using a hash function with recovery (scheme 1) */ public class ISO9796d2Signer implements SignerWithRecovery { static final public int TRAILER_IMPLICIT = 0xBC; static final public int TRAILER_RIPEMD160 = 0x31CC; static final public int TRAILER_RIPEMD128 = 0x32CC; static final public int TRAILER_SHA1 = 0x33CC; static final public int TRAILER_SHA256 = 0x34CC; static final public int TRAILER_SHA512 = 0x35CC; static final public int TRAILER_SHA384 = 0x36CC; static final public int TRAILER_WHIRLPOOL = 0x37CC; private static Hashtable trailerMap = new Hashtable(); static { trailerMap.put("RIPEMD128", Integers.valueOf(TRAILER_RIPEMD128)); trailerMap.put("RIPEMD160", Integers.valueOf(TRAILER_RIPEMD160)); trailerMap.put("SHA-1", Integers.valueOf(TRAILER_SHA1)); trailerMap.put("SHA-256", Integers.valueOf(TRAILER_SHA256)); trailerMap.put("SHA-384", Integers.valueOf(TRAILER_SHA384)); trailerMap.put("SHA-512", Integers.valueOf(TRAILER_SHA512)); trailerMap.put("Whirlpool", Integers.valueOf(TRAILER_WHIRLPOOL)); } private Digest digest; private AsymmetricBlockCipher cipher; private int trailer; private int keyBits; private byte[] block; private byte[] mBuf; private int messageLength; private boolean fullMessage; private byte[] recoveredMessage; private byte[] preSig; private byte[] preBlock; /** * Generate a signer for the with either implicit or explicit trailers * for ISO9796-2. * * @param cipher base cipher to use for signature creation/verification * @param digest digest to use. * @param implicit whether or not the trailer is implicit or gives the hash. */ public ISO9796d2Signer( AsymmetricBlockCipher cipher, Digest digest, boolean implicit) { this.cipher = cipher; this.digest = digest; if (implicit) { trailer = TRAILER_IMPLICIT; } else { Integer trailerObj = (Integer)trailerMap.get(digest.getAlgorithmName()); if (trailerObj != null) { trailer = trailerObj.intValue(); } else { throw new IllegalArgumentException("no valid trailer for digest"); } } } /** * Constructor for a signer with an explicit digest trailer. * * @param cipher cipher to use. * @param digest digest to sign with. */ public ISO9796d2Signer( AsymmetricBlockCipher cipher, Digest digest) { this(cipher, digest, false); } public void init( boolean forSigning, CipherParameters param) { RSAKeyParameters kParam = (RSAKeyParameters)param; cipher.init(forSigning, kParam); keyBits = kParam.getModulus().bitLength(); block = new byte[(keyBits + 7) / 8]; if (trailer == TRAILER_IMPLICIT) { mBuf = new byte[block.length - digest.getDigestSize() - 2]; } else { mBuf = new byte[block.length - digest.getDigestSize() - 3]; } reset(); } /** * compare two byte arrays - constant time */ private boolean isSameAs( byte[] a, byte[] b) { boolean isOkay = true; if (messageLength > mBuf.length) { if (mBuf.length > b.length) { isOkay = false; } for (int i = 0; i != mBuf.length; i++) { if (a[i] != b[i]) { isOkay = false; } } } else { if (messageLength != b.length) { isOkay = false; } for (int i = 0; i != b.length; i++) { if (a[i] != b[i]) { isOkay = false; } } } return isOkay; } /** * clear possible sensitive data */ private void clearBlock( byte[] block) { for (int i = 0; i != block.length; i++) { block[i] = 0; } } public void updateWithRecoveredMessage(byte[] signature) throws InvalidCipherTextException { byte[] block = cipher.processBlock(signature, 0, signature.length); if (((block[0] & 0xC0) ^ 0x40) != 0) { throw new InvalidCipherTextException("malformed signature"); } if (((block[block.length - 1] & 0xF) ^ 0xC) != 0) { throw new InvalidCipherTextException("malformed signature"); } int delta = 0; if (((block[block.length - 1] & 0xFF) ^ 0xBC) == 0) { delta = 1; } else { int sigTrail = ((block[block.length - 2] & 0xFF) << 8) | (block[block.length - 1] & 0xFF); Integer trailerObj = (Integer)trailerMap.get(digest.getAlgorithmName()); if (trailerObj != null) { if (sigTrail != trailerObj.intValue()) { throw new IllegalStateException("signer initialised with wrong digest for trailer " + sigTrail); } } else { throw new IllegalArgumentException("unrecognised hash in signature"); } delta = 2; } // // find out how much padding we've got // int mStart = 0; for (mStart = 0; mStart != block.length; mStart++) { if (((block[mStart] & 0x0f) ^ 0x0a) == 0) { break; } } mStart++; int off = block.length - delta - digest.getDigestSize(); // // there must be at least one byte of message string // if ((off - mStart) <= 0) { throw new InvalidCipherTextException("malformed block"); } // // if we contain the whole message as well, check the hash of that. // if ((block[0] & 0x20) == 0) { fullMessage = true; recoveredMessage = new byte[off - mStart]; System.arraycopy(block, mStart, recoveredMessage, 0, recoveredMessage.length); } else { fullMessage = false; recoveredMessage = new byte[off - mStart]; System.arraycopy(block, mStart, recoveredMessage, 0, recoveredMessage.length); } preSig = signature; preBlock = block; digest.update(recoveredMessage, 0, recoveredMessage.length); messageLength = recoveredMessage.length; System.arraycopy(recoveredMessage, 0, mBuf, 0, recoveredMessage.length); } /** * update the internal digest with the byte b */ public void update( byte b) { digest.update(b); if (messageLength < mBuf.length) { mBuf[messageLength] = b; } messageLength++; } /** * update the internal digest with the byte array in */ public void update( byte[] in, int off, int len) { while (len > 0 && messageLength < mBuf.length) { this.update(in[off]); off++; len--; } digest.update(in, off, len); messageLength += len; } /** * reset the internal state */ public void reset() { digest.reset(); messageLength = 0; clearBlock(mBuf); if (recoveredMessage != null) { clearBlock(recoveredMessage); } recoveredMessage = null; fullMessage = false; if (preSig != null) { preSig = null; clearBlock(preBlock); preBlock = null; } } /** * generate a signature for the loaded message using the key we were * initialised with. */ public byte[] generateSignature() throws CryptoException { int digSize = digest.getDigestSize(); int t = 0; int delta = 0; if (trailer == TRAILER_IMPLICIT) { t = 8; delta = block.length - digSize - 1; digest.doFinal(block, delta); block[block.length - 1] = (byte)TRAILER_IMPLICIT; } else { t = 16; delta = block.length - digSize - 2; digest.doFinal(block, delta); block[block.length - 2] = (byte)(trailer >>> 8); block[block.length - 1] = (byte)trailer; } byte header = 0; int x = (digSize + messageLength) * 8 + t + 4 - keyBits; if (x > 0) { int mR = messageLength - ((x + 7) / 8); header = 0x60; delta -= mR; System.arraycopy(mBuf, 0, block, delta, mR); } else { header = 0x40; delta -= messageLength; System.arraycopy(mBuf, 0, block, delta, messageLength); } if ((delta - 1) > 0) { for (int i = delta - 1; i != 0; i--) { block[i] = (byte)0xbb; } block[delta - 1] ^= (byte)0x01; block[0] = (byte)0x0b; block[0] |= header; } else { block[0] = (byte)0x0a; block[0] |= header; } byte[] b = cipher.processBlock(block, 0, block.length); clearBlock(mBuf); clearBlock(block); return b; } /** * return true if the signature represents a ISO9796-2 signature * for the passed in message. */ public boolean verifySignature( byte[] signature) { byte[] block = null; if (preSig == null) { try { block = cipher.processBlock(signature, 0, signature.length); } catch (Exception e) { return false; } } else { if (!Arrays.areEqual(preSig, signature)) { throw new IllegalStateException("updateWithRecoveredMessage called on different signature"); } block = preBlock; preSig = null; preBlock = null; } if (((block[0] & 0xC0) ^ 0x40) != 0) { return returnFalse(block); } if (((block[block.length - 1] & 0xF) ^ 0xC) != 0) { return returnFalse(block); } int delta = 0; if (((block[block.length - 1] & 0xFF) ^ 0xBC) == 0) { delta = 1; } else { int sigTrail = ((block[block.length - 2] & 0xFF) << 8) | (block[block.length - 1] & 0xFF); Integer trailerObj = (Integer)trailerMap.get(digest.getAlgorithmName()); if (trailerObj != null) { if (sigTrail != trailerObj.intValue()) { throw new IllegalStateException("signer initialised with wrong digest for trailer " + sigTrail); } } else { throw new IllegalArgumentException("unrecognised hash in signature"); } delta = 2; } // // find out how much padding we've got // int mStart = 0; for (mStart = 0; mStart != block.length; mStart++) { if (((block[mStart] & 0x0f) ^ 0x0a) == 0) { break; } } mStart++; // // check the hashes // byte[] hash = new byte[digest.getDigestSize()]; int off = block.length - delta - hash.length; // // there must be at least one byte of message string // if ((off - mStart) <= 0) { return returnFalse(block); } // // if we contain the whole message as well, check the hash of that. // if ((block[0] & 0x20) == 0) { fullMessage = true; // check right number of bytes passed in. if (messageLength > off - mStart) { return returnFalse(block); } digest.reset(); digest.update(block, mStart, off - mStart); digest.doFinal(hash, 0); boolean isOkay = true; for (int i = 0; i != hash.length; i++) { block[off + i] ^= hash[i]; if (block[off + i] != 0) { isOkay = false; } } if (!isOkay) { return returnFalse(block); } recoveredMessage = new byte[off - mStart]; System.arraycopy(block, mStart, recoveredMessage, 0, recoveredMessage.length); } else { fullMessage = false; digest.doFinal(hash, 0); boolean isOkay = true; for (int i = 0; i != hash.length; i++) { block[off + i] ^= hash[i]; if (block[off + i] != 0) { isOkay = false; } } if (!isOkay) { return returnFalse(block); } recoveredMessage = new byte[off - mStart]; System.arraycopy(block, mStart, recoveredMessage, 0, recoveredMessage.length); } // // if they've input a message check what we've recovered against // what was input. // if (messageLength != 0) { if (!isSameAs(mBuf, recoveredMessage)) { return returnFalse(block); } } clearBlock(mBuf); clearBlock(block); return true; } private boolean returnFalse(byte[] block) { clearBlock(mBuf); clearBlock(block); return false; } /** * Return true if the full message was recoveredMessage. * * @return true on full message recovery, false otherwise. * @see org.bouncycastle.crypto.SignerWithRecovery#hasFullMessage() */ public boolean hasFullMessage() { return fullMessage; } /** * Return a reference to the recoveredMessage message. * * @return the full/partial recoveredMessage message. * @see org.bouncycastle.crypto.SignerWithRecovery#getRecoveredMessage() */ public byte[] getRecoveredMessage() { return recoveredMessage; } } bouncycastle-1.49.orig/src/org/bouncycastle/crypto/signers/ISO9796d2PSSSigner.java0000644000175000017500000004153212151274316027323 0ustar ebourgebourgpackage org.bouncycastle.crypto.signers; import java.security.SecureRandom; import java.util.Hashtable; import org.bouncycastle.crypto.AsymmetricBlockCipher; import org.bouncycastle.crypto.CipherParameters; import org.bouncycastle.crypto.CryptoException; import org.bouncycastle.crypto.Digest; import org.bouncycastle.crypto.InvalidCipherTextException; import org.bouncycastle.crypto.SignerWithRecovery; import org.bouncycastle.crypto.params.ParametersWithRandom; import org.bouncycastle.crypto.params.ParametersWithSalt; import org.bouncycastle.crypto.params.RSAKeyParameters; import org.bouncycastle.util.Arrays; import org.bouncycastle.util.Integers; /** * ISO9796-2 - mechanism using a hash function with recovery (scheme 2 and 3). *

    * Note: the usual length for the salt is the length of the hash * function used in bytes. */ public class ISO9796d2PSSSigner implements SignerWithRecovery { static final public int TRAILER_IMPLICIT = 0xBC; static final public int TRAILER_RIPEMD160 = 0x31CC; static final public int TRAILER_RIPEMD128 = 0x32CC; static final public int TRAILER_SHA1 = 0x33CC; static final public int TRAILER_SHA256 = 0x34CC; static final public int TRAILER_SHA512 = 0x35CC; static final public int TRAILER_SHA384 = 0x36CC; static final public int TRAILER_WHIRLPOOL = 0x37CC; private static Hashtable trailerMap = new Hashtable(); static { trailerMap.put("RIPEMD128", Integers.valueOf(TRAILER_RIPEMD128)); trailerMap.put("RIPEMD160", Integers.valueOf(TRAILER_RIPEMD160)); trailerMap.put("SHA-1", Integers.valueOf(TRAILER_SHA1)); trailerMap.put("SHA-256", Integers.valueOf(TRAILER_SHA256)); trailerMap.put("SHA-384", Integers.valueOf(TRAILER_SHA384)); trailerMap.put("SHA-512", Integers.valueOf(TRAILER_SHA512)); trailerMap.put("Whirlpool", Integers.valueOf(TRAILER_WHIRLPOOL)); } private Digest digest; private AsymmetricBlockCipher cipher; private SecureRandom random; private byte[] standardSalt; private int hLen; private int trailer; private int keyBits; private byte[] block; private byte[] mBuf; private int messageLength; private int saltLength; private boolean fullMessage; private byte[] recoveredMessage; private byte[] preSig; private byte[] preBlock; private int preMStart; private int preTLength; /** * Generate a signer for the with either implicit or explicit trailers * for ISO9796-2, scheme 2 or 3. * * @param cipher base cipher to use for signature creation/verification * @param digest digest to use. * @param saltLength length of salt in bytes. * @param implicit whether or not the trailer is implicit or gives the hash. */ public ISO9796d2PSSSigner( AsymmetricBlockCipher cipher, Digest digest, int saltLength, boolean implicit) { this.cipher = cipher; this.digest = digest; this.hLen = digest.getDigestSize(); this.saltLength = saltLength; if (implicit) { trailer = TRAILER_IMPLICIT; } else { Integer trailerObj = (Integer)trailerMap.get(digest.getAlgorithmName()); if (trailerObj != null) { trailer = trailerObj.intValue(); } else { throw new IllegalArgumentException("no valid trailer for digest"); } } } /** * Constructor for a signer with an explicit digest trailer. * * @param cipher cipher to use. * @param digest digest to sign with. * @param saltLength length of salt in bytes. */ public ISO9796d2PSSSigner( AsymmetricBlockCipher cipher, Digest digest, int saltLength) { this(cipher, digest, saltLength, false); } /** * Initialise the signer. * * @param forSigning true if for signing, false if for verification. * @param param parameters for signature generation/verification. If the * parameters are for generation they should be a ParametersWithRandom, * a ParametersWithSalt, or just an RSAKeyParameters object. If RSAKeyParameters * are passed in a SecureRandom will be created. * @throws IllegalArgumentException if wrong parameter type or a fixed * salt is passed in which is the wrong length. */ public void init( boolean forSigning, CipherParameters param) { RSAKeyParameters kParam; int lengthOfSalt = saltLength; if (param instanceof ParametersWithRandom) { ParametersWithRandom p = (ParametersWithRandom)param; kParam = (RSAKeyParameters)p.getParameters(); if (forSigning) { random = p.getRandom(); } } else if (param instanceof ParametersWithSalt) { ParametersWithSalt p = (ParametersWithSalt)param; kParam = (RSAKeyParameters)p.getParameters(); standardSalt = p.getSalt(); lengthOfSalt = standardSalt.length; if (standardSalt.length != saltLength) { throw new IllegalArgumentException("Fixed salt is of wrong length"); } } else { kParam = (RSAKeyParameters)param; if (forSigning) { random = new SecureRandom(); } } cipher.init(forSigning, kParam); keyBits = kParam.getModulus().bitLength(); block = new byte[(keyBits + 7) / 8]; if (trailer == TRAILER_IMPLICIT) { mBuf = new byte[block.length - digest.getDigestSize() - lengthOfSalt - 1 - 1]; } else { mBuf = new byte[block.length - digest.getDigestSize() - lengthOfSalt - 1 - 2]; } reset(); } /** * compare two byte arrays - constant time */ private boolean isSameAs( byte[] a, byte[] b) { boolean isOkay = true; if (messageLength != b.length) { isOkay = false; } for (int i = 0; i != b.length; i++) { if (a[i] != b[i]) { isOkay = false; } } return isOkay; } /** * clear possible sensitive data */ private void clearBlock( byte[] block) { for (int i = 0; i != block.length; i++) { block[i] = 0; } } public void updateWithRecoveredMessage(byte[] signature) throws InvalidCipherTextException { byte[] block = cipher.processBlock(signature, 0, signature.length); // // adjust block size for leading zeroes if necessary // if (block.length < (keyBits + 7) / 8) { byte[] tmp = new byte[(keyBits + 7) / 8]; System.arraycopy(block, 0, tmp, tmp.length - block.length, block.length); clearBlock(block); block = tmp; } int tLength; if (((block[block.length - 1] & 0xFF) ^ 0xBC) == 0) { tLength = 1; } else { int sigTrail = ((block[block.length - 2] & 0xFF) << 8) | (block[block.length - 1] & 0xFF); Integer trailerObj = (Integer)trailerMap.get(digest.getAlgorithmName()); if (trailerObj != null) { if (sigTrail != trailerObj.intValue()) { throw new IllegalStateException("signer initialised with wrong digest for trailer " + sigTrail); } } else { throw new IllegalArgumentException("unrecognised hash in signature"); } tLength = 2; } // // calculate H(m2) // byte[] m2Hash = new byte[hLen]; digest.doFinal(m2Hash, 0); // // remove the mask // byte[] dbMask = maskGeneratorFunction1(block, block.length - hLen - tLength, hLen, block.length - hLen - tLength); for (int i = 0; i != dbMask.length; i++) { block[i] ^= dbMask[i]; } block[0] &= 0x7f; // // find out how much padding we've got // int mStart = 0; for (; mStart != block.length; mStart++) { if (block[mStart] == 0x01) { break; } } mStart++; if (mStart >= block.length) { clearBlock(block); } fullMessage = (mStart > 1); recoveredMessage = new byte[dbMask.length - mStart - saltLength]; System.arraycopy(block, mStart, recoveredMessage, 0, recoveredMessage.length); System.arraycopy(recoveredMessage, 0, mBuf, 0, recoveredMessage.length); preSig = signature; preBlock = block; preMStart = mStart; preTLength = tLength; } /** * update the internal digest with the byte b */ public void update( byte b) { if (preSig == null && messageLength < mBuf.length) { mBuf[messageLength++] = b; } else { digest.update(b); } } /** * update the internal digest with the byte array in */ public void update( byte[] in, int off, int len) { if (preSig == null) { while (len > 0 && messageLength < mBuf.length) { this.update(in[off]); off++; len--; } } if (len > 0) { digest.update(in, off, len); } } /** * reset the internal state */ public void reset() { digest.reset(); messageLength = 0; if (mBuf != null) { clearBlock(mBuf); } if (recoveredMessage != null) { clearBlock(recoveredMessage); recoveredMessage = null; } fullMessage = false; if (preSig != null) { preSig = null; clearBlock(preBlock); preBlock = null; } } /** * generate a signature for the loaded message using the key we were * initialised with. */ public byte[] generateSignature() throws CryptoException { int digSize = digest.getDigestSize(); byte[] m2Hash = new byte[digSize]; digest.doFinal(m2Hash, 0); byte[] C = new byte[8]; LtoOSP(messageLength * 8, C); digest.update(C, 0, C.length); digest.update(mBuf, 0, messageLength); digest.update(m2Hash, 0, m2Hash.length); byte[] salt; if (standardSalt != null) { salt = standardSalt; } else { salt = new byte[saltLength]; random.nextBytes(salt); } digest.update(salt, 0, salt.length); byte[] hash = new byte[digest.getDigestSize()]; digest.doFinal(hash, 0); int tLength = 2; if (trailer == TRAILER_IMPLICIT) { tLength = 1; } int off = block.length - messageLength - salt.length - hLen - tLength - 1; block[off] = 0x01; System.arraycopy(mBuf, 0, block, off + 1, messageLength); System.arraycopy(salt, 0, block, off + 1 + messageLength, salt.length); byte[] dbMask = maskGeneratorFunction1(hash, 0, hash.length, block.length - hLen - tLength); for (int i = 0; i != dbMask.length; i++) { block[i] ^= dbMask[i]; } System.arraycopy(hash, 0, block, block.length - hLen - tLength, hLen); if (trailer == TRAILER_IMPLICIT) { block[block.length - 1] = (byte)TRAILER_IMPLICIT; } else { block[block.length - 2] = (byte)(trailer >>> 8); block[block.length - 1] = (byte)trailer; } block[0] &= 0x7f; byte[] b = cipher.processBlock(block, 0, block.length); clearBlock(mBuf); clearBlock(block); messageLength = 0; return b; } /** * return true if the signature represents a ISO9796-2 signature * for the passed in message. */ public boolean verifySignature( byte[] signature) { // // calculate H(m2) // byte[] m2Hash = new byte[hLen]; digest.doFinal(m2Hash, 0); byte[] block; int tLength; int mStart = 0; if (preSig == null) { try { updateWithRecoveredMessage(signature); } catch (Exception e) { return false; } } else { if (!Arrays.areEqual(preSig, signature)) { throw new IllegalStateException("updateWithRecoveredMessage called on different signature"); } } block = preBlock; mStart = preMStart; tLength = preTLength; preSig = null; preBlock = null; // // check the hashes // byte[] C = new byte[8]; LtoOSP(recoveredMessage.length * 8, C); digest.update(C, 0, C.length); if (recoveredMessage.length != 0) { digest.update(recoveredMessage, 0, recoveredMessage.length); } digest.update(m2Hash, 0, m2Hash.length); // Update for the salt digest.update(block, mStart + recoveredMessage.length, saltLength); byte[] hash = new byte[digest.getDigestSize()]; digest.doFinal(hash, 0); int off = block.length - tLength - hash.length; boolean isOkay = true; for (int i = 0; i != hash.length; i++) { if (hash[i] != block[off + i]) { isOkay = false; } } clearBlock(block); clearBlock(hash); if (!isOkay) { fullMessage = false; clearBlock(recoveredMessage); return false; } // // if they've input a message check what we've recovered against // what was input. // if (messageLength != 0) { if (!isSameAs(mBuf, recoveredMessage)) { clearBlock(mBuf); return false; } messageLength = 0; } clearBlock(mBuf); return true; } /** * Return true if the full message was recoveredMessage. * * @return true on full message recovery, false otherwise, or if not sure. * @see org.bouncycastle.crypto.SignerWithRecovery#hasFullMessage() */ public boolean hasFullMessage() { return fullMessage; } /** * Return a reference to the recoveredMessage message. * * @return the full/partial recoveredMessage message. * @see org.bouncycastle.crypto.SignerWithRecovery#getRecoveredMessage() */ public byte[] getRecoveredMessage() { return recoveredMessage; } /** * int to octet string. */ private void ItoOSP( int i, byte[] sp) { sp[0] = (byte)(i >>> 24); sp[1] = (byte)(i >>> 16); sp[2] = (byte)(i >>> 8); sp[3] = (byte)(i >>> 0); } /** * long to octet string. */ private void LtoOSP( long l, byte[] sp) { sp[0] = (byte)(l >>> 56); sp[1] = (byte)(l >>> 48); sp[2] = (byte)(l >>> 40); sp[3] = (byte)(l >>> 32); sp[4] = (byte)(l >>> 24); sp[5] = (byte)(l >>> 16); sp[6] = (byte)(l >>> 8); sp[7] = (byte)(l >>> 0); } /** * mask generator function, as described in PKCS1v2. */ private byte[] maskGeneratorFunction1( byte[] Z, int zOff, int zLen, int length) { byte[] mask = new byte[length]; byte[] hashBuf = new byte[hLen]; byte[] C = new byte[4]; int counter = 0; digest.reset(); while (counter < (length / hLen)) { ItoOSP(counter, C); digest.update(Z, zOff, zLen); digest.update(C, 0, C.length); digest.doFinal(hashBuf, 0); System.arraycopy(hashBuf, 0, mask, counter * hLen, hLen); counter++; } if ((counter * hLen) < length) { ItoOSP(counter, C); digest.update(Z, zOff, zLen); digest.update(C, 0, C.length); digest.doFinal(hashBuf, 0); System.arraycopy(hashBuf, 0, mask, counter * hLen, mask.length - (counter * hLen)); } return mask; } } bouncycastle-1.49.orig/src/org/bouncycastle/crypto/signers/GOST3410Signer.java0000644000175000017500000001011010262753175026574 0ustar ebourgebourgpackage org.bouncycastle.crypto.signers; import org.bouncycastle.crypto.CipherParameters; import org.bouncycastle.crypto.DSA; import org.bouncycastle.crypto.params.*; import java.security.SecureRandom; import java.math.BigInteger; /** * GOST R 34.10-94 Signature Algorithm */ public class GOST3410Signer implements DSA { GOST3410KeyParameters key; SecureRandom random; public void init( boolean forSigning, CipherParameters param) { if (forSigning) { if (param instanceof ParametersWithRandom) { ParametersWithRandom rParam = (ParametersWithRandom)param; this.random = rParam.getRandom(); this.key = (GOST3410PrivateKeyParameters)rParam.getParameters(); } else { this.random = new SecureRandom(); this.key = (GOST3410PrivateKeyParameters)param; } } else { this.key = (GOST3410PublicKeyParameters)param; } } /** * generate a signature for the given message using the key we were * initialised with. For conventional GOST3410 the message should be a GOST3411 * hash of the message of interest. * * @param message the message that will be verified later. */ public BigInteger[] generateSignature( byte[] message) { byte[] mRev = new byte[message.length]; // conversion is little-endian for (int i = 0; i != mRev.length; i++) { mRev[i] = message[mRev.length - 1 - i]; } BigInteger m = new BigInteger(1, mRev); GOST3410Parameters params = key.getParameters(); BigInteger k; do { k = new BigInteger(params.getQ().bitLength(), random); } while (k.compareTo(params.getQ()) >= 0); BigInteger r = params.getA().modPow(k, params.getP()).mod(params.getQ()); BigInteger s = k.multiply(m). add(((GOST3410PrivateKeyParameters)key).getX().multiply(r)). mod(params.getQ()); BigInteger[] res = new BigInteger[2]; res[0] = r; res[1] = s; return res; } /** * return true if the value r and s represent a GOST3410 signature for * the passed in message for standard GOST3410 the message should be a * GOST3411 hash of the real message to be verified. */ public boolean verifySignature( byte[] message, BigInteger r, BigInteger s) { byte[] mRev = new byte[message.length]; // conversion is little-endian for (int i = 0; i != mRev.length; i++) { mRev[i] = message[mRev.length - 1 - i]; } BigInteger m = new BigInteger(1, mRev); GOST3410Parameters params = key.getParameters(); BigInteger zero = BigInteger.valueOf(0); if (zero.compareTo(r) >= 0 || params.getQ().compareTo(r) <= 0) { return false; } if (zero.compareTo(s) >= 0 || params.getQ().compareTo(s) <= 0) { return false; } BigInteger v = m.modPow(params.getQ().subtract(new BigInteger("2")),params.getQ()); BigInteger z1 = s.multiply(v).mod(params.getQ()); BigInteger z2 = (params.getQ().subtract(r)).multiply(v).mod(params.getQ()); z1 = params.getA().modPow(z1, params.getP()); z2 = ((GOST3410PublicKeyParameters)key).getY().modPow(z2, params.getP()); BigInteger u = z1.multiply(z2).mod(params.getP()).mod(params.getQ()); return u.equals(r); } } bouncycastle-1.49.orig/src/org/bouncycastle/crypto/signers/PSSSigner.java0000644000175000017500000002177111501543541026163 0ustar ebourgebourgpackage org.bouncycastle.crypto.signers; import java.security.SecureRandom; import org.bouncycastle.crypto.AsymmetricBlockCipher; import org.bouncycastle.crypto.CipherParameters; import org.bouncycastle.crypto.CryptoException; import org.bouncycastle.crypto.DataLengthException; import org.bouncycastle.crypto.Digest; import org.bouncycastle.crypto.Signer; import org.bouncycastle.crypto.params.ParametersWithRandom; import org.bouncycastle.crypto.params.RSABlindingParameters; import org.bouncycastle.crypto.params.RSAKeyParameters; /** * RSA-PSS as described in PKCS# 1 v 2.1. *

    * Note: the usual value for the salt length is the number of * bytes in the hash function. */ public class PSSSigner implements Signer { static final public byte TRAILER_IMPLICIT = (byte)0xBC; private Digest contentDigest; private Digest mgfDigest; private AsymmetricBlockCipher cipher; private SecureRandom random; private int hLen; private int mgfhLen; private int sLen; private int emBits; private byte[] salt; private byte[] mDash; private byte[] block; private byte trailer; /** * basic constructor * * @param cipher the asymmetric cipher to use. * @param digest the digest to use. * @param sLen the length of the salt to use (in bytes). */ public PSSSigner( AsymmetricBlockCipher cipher, Digest digest, int sLen) { this(cipher, digest, sLen, TRAILER_IMPLICIT); } public PSSSigner( AsymmetricBlockCipher cipher, Digest contentDigest, Digest mgfDigest, int sLen) { this(cipher, contentDigest, mgfDigest, sLen, TRAILER_IMPLICIT); } public PSSSigner( AsymmetricBlockCipher cipher, Digest digest, int sLen, byte trailer) { this(cipher, digest, digest, sLen, trailer); } public PSSSigner( AsymmetricBlockCipher cipher, Digest contentDigest, Digest mgfDigest, int sLen, byte trailer) { this.cipher = cipher; this.contentDigest = contentDigest; this.mgfDigest = mgfDigest; this.hLen = contentDigest.getDigestSize(); this.mgfhLen = mgfDigest.getDigestSize(); this.sLen = sLen; this.salt = new byte[sLen]; this.mDash = new byte[8 + sLen + hLen]; this.trailer = trailer; } public void init( boolean forSigning, CipherParameters param) { CipherParameters params; if (param instanceof ParametersWithRandom) { ParametersWithRandom p = (ParametersWithRandom)param; params = p.getParameters(); random = p.getRandom(); } else { params = param; if (forSigning) { random = new SecureRandom(); } } cipher.init(forSigning, params); RSAKeyParameters kParam; if (params instanceof RSABlindingParameters) { kParam = ((RSABlindingParameters)params).getPublicKey(); } else { kParam = (RSAKeyParameters)params; } emBits = kParam.getModulus().bitLength() - 1; if (emBits < (8 * hLen + 8 * sLen + 9)) { throw new IllegalArgumentException("key too small for specified hash and salt lengths"); } block = new byte[(emBits + 7) / 8]; reset(); } /** * clear possible sensitive data */ private void clearBlock( byte[] block) { for (int i = 0; i != block.length; i++) { block[i] = 0; } } /** * update the internal digest with the byte b */ public void update( byte b) { contentDigest.update(b); } /** * update the internal digest with the byte array in */ public void update( byte[] in, int off, int len) { contentDigest.update(in, off, len); } /** * reset the internal state */ public void reset() { contentDigest.reset(); } /** * generate a signature for the message we've been loaded with using * the key we were initialised with. */ public byte[] generateSignature() throws CryptoException, DataLengthException { contentDigest.doFinal(mDash, mDash.length - hLen - sLen); if (sLen != 0) { random.nextBytes(salt); System.arraycopy(salt, 0, mDash, mDash.length - sLen, sLen); } byte[] h = new byte[hLen]; contentDigest.update(mDash, 0, mDash.length); contentDigest.doFinal(h, 0); block[block.length - sLen - 1 - hLen - 1] = 0x01; System.arraycopy(salt, 0, block, block.length - sLen - hLen - 1, sLen); byte[] dbMask = maskGeneratorFunction1(h, 0, h.length, block.length - hLen - 1); for (int i = 0; i != dbMask.length; i++) { block[i] ^= dbMask[i]; } block[0] &= (0xff >> ((block.length * 8) - emBits)); System.arraycopy(h, 0, block, block.length - hLen - 1, hLen); block[block.length - 1] = trailer; byte[] b = cipher.processBlock(block, 0, block.length); clearBlock(block); return b; } /** * return true if the internal state represents the signature described * in the passed in array. */ public boolean verifySignature( byte[] signature) { contentDigest.doFinal(mDash, mDash.length - hLen - sLen); try { byte[] b = cipher.processBlock(signature, 0, signature.length); System.arraycopy(b, 0, block, block.length - b.length, b.length); } catch (Exception e) { return false; } if (block[block.length - 1] != trailer) { clearBlock(block); return false; } byte[] dbMask = maskGeneratorFunction1(block, block.length - hLen - 1, hLen, block.length - hLen - 1); for (int i = 0; i != dbMask.length; i++) { block[i] ^= dbMask[i]; } block[0] &= (0xff >> ((block.length * 8) - emBits)); for (int i = 0; i != block.length - hLen - sLen - 2; i++) { if (block[i] != 0) { clearBlock(block); return false; } } if (block[block.length - hLen - sLen - 2] != 0x01) { clearBlock(block); return false; } System.arraycopy(block, block.length - sLen - hLen - 1, mDash, mDash.length - sLen, sLen); contentDigest.update(mDash, 0, mDash.length); contentDigest.doFinal(mDash, mDash.length - hLen); for (int i = block.length - hLen - 1, j = mDash.length - hLen; j != mDash.length; i++, j++) { if ((block[i] ^ mDash[j]) != 0) { clearBlock(mDash); clearBlock(block); return false; } } clearBlock(mDash); clearBlock(block); return true; } /** * int to octet string. */ private void ItoOSP( int i, byte[] sp) { sp[0] = (byte)(i >>> 24); sp[1] = (byte)(i >>> 16); sp[2] = (byte)(i >>> 8); sp[3] = (byte)(i >>> 0); } /** * mask generator function, as described in PKCS1v2. */ private byte[] maskGeneratorFunction1( byte[] Z, int zOff, int zLen, int length) { byte[] mask = new byte[length]; byte[] hashBuf = new byte[mgfhLen]; byte[] C = new byte[4]; int counter = 0; mgfDigest.reset(); while (counter < (length / mgfhLen)) { ItoOSP(counter, C); mgfDigest.update(Z, zOff, zLen); mgfDigest.update(C, 0, C.length); mgfDigest.doFinal(hashBuf, 0); System.arraycopy(hashBuf, 0, mask, counter * mgfhLen, mgfhLen); counter++; } if ((counter * mgfhLen) < length) { ItoOSP(counter, C); mgfDigest.update(Z, zOff, zLen); mgfDigest.update(C, 0, C.length); mgfDigest.doFinal(hashBuf, 0); System.arraycopy(hashBuf, 0, mask, counter * mgfhLen, mask.length - (counter * mgfhLen)); } return mask; } } bouncycastle-1.49.orig/src/org/bouncycastle/crypto/signers/DSTU4145Signer.java0000644000175000017500000001121012151251423026573 0ustar ebourgebourgpackage org.bouncycastle.crypto.signers; import java.math.BigInteger; import java.security.SecureRandom; import org.bouncycastle.crypto.CipherParameters; import org.bouncycastle.crypto.DSA; import org.bouncycastle.crypto.params.ECKeyParameters; import org.bouncycastle.crypto.params.ECPrivateKeyParameters; import org.bouncycastle.crypto.params.ECPublicKeyParameters; import org.bouncycastle.crypto.params.ParametersWithRandom; import org.bouncycastle.math.ec.ECAlgorithms; import org.bouncycastle.math.ec.ECCurve; import org.bouncycastle.math.ec.ECFieldElement; import org.bouncycastle.math.ec.ECPoint; import org.bouncycastle.util.Arrays; /** * DSTU 4145-2002 *

    * National Ukrainian standard of digital signature based on elliptic curves (DSTU 4145-2002). *

    */ public class DSTU4145Signer implements DSA { private static final BigInteger ONE = BigInteger.valueOf(1); private ECKeyParameters key; private SecureRandom random; public void init(boolean forSigning, CipherParameters param) { if (forSigning) { if (param instanceof ParametersWithRandom) { ParametersWithRandom rParam = (ParametersWithRandom)param; this.random = rParam.getRandom(); param = rParam.getParameters(); } else { this.random = new SecureRandom(); } this.key = (ECPrivateKeyParameters)param; } else { this.key = (ECPublicKeyParameters)param; } } public BigInteger[] generateSignature(byte[] message) { ECFieldElement h = hash2FieldElement(key.getParameters().getCurve(), message); if (h.toBigInteger().signum() == 0) { h = key.getParameters().getCurve().fromBigInteger(ONE); } BigInteger e, r, s; ECFieldElement Fe, y; do { do { do { e = generateRandomInteger(key.getParameters().getN(), random); Fe = key.getParameters().getG().multiply(e).getX(); } while (Fe.toBigInteger().signum() == 0); y = h.multiply(Fe); r = fieldElement2Integer(key.getParameters().getN(), y); } while (r.signum() == 0); s = r.multiply(((ECPrivateKeyParameters)key).getD()).add(e).mod(key.getParameters().getN()); } while (s.signum() == 0); return new BigInteger[]{r, s}; } public boolean verifySignature(byte[] message, BigInteger r, BigInteger s) { if (r.signum() == 0 || s.signum() == 0) { return false; } if (r.compareTo(key.getParameters().getN()) >= 0 || s.compareTo(key.getParameters().getN()) >= 0) { return false; } ECFieldElement h = hash2FieldElement(key.getParameters().getCurve(), message); if (h.toBigInteger().signum() == 0) { h = key.getParameters().getCurve().fromBigInteger(ONE); } ECPoint R = ECAlgorithms.sumOfTwoMultiplies(key.getParameters().getG(), s, ((ECPublicKeyParameters)key).getQ(), r); // components must be bogus. if (R.isInfinity()) { return false; } ECFieldElement y = h.multiply(R.getX()); return fieldElement2Integer(key.getParameters().getN(), y).compareTo(r) == 0; } /** * Generates random integer such, than its bit length is less than that of n */ private static BigInteger generateRandomInteger(BigInteger n, SecureRandom random) { return new BigInteger(n.bitLength() - 1, random); } private static void reverseBytes(byte[] bytes) { byte tmp; for (int i=0; i= curve.getFieldSize()) { num = num.clearBit(num.bitLength() - 1); } return curve.fromBigInteger(num); } private static BigInteger fieldElement2Integer(BigInteger n, ECFieldElement fieldElement) { BigInteger num = fieldElement.toBigInteger(); while (num.bitLength() >= n.bitLength()) { num = num.clearBit(num.bitLength() - 1); } return num; } } bouncycastle-1.49.orig/src/org/bouncycastle/crypto/signers/RSADigestSigner.java0000644000175000017500000001460411625350056027304 0ustar ebourgebourgpackage org.bouncycastle.crypto.signers; import java.io.IOException; import java.util.Hashtable; import org.bouncycastle.asn1.ASN1Encoding; import org.bouncycastle.asn1.ASN1ObjectIdentifier; import org.bouncycastle.asn1.DERNull; import org.bouncycastle.asn1.nist.NISTObjectIdentifiers; import org.bouncycastle.asn1.pkcs.PKCSObjectIdentifiers; import org.bouncycastle.asn1.teletrust.TeleTrusTObjectIdentifiers; import org.bouncycastle.asn1.x509.AlgorithmIdentifier; import org.bouncycastle.asn1.x509.DigestInfo; import org.bouncycastle.asn1.x509.X509ObjectIdentifiers; import org.bouncycastle.crypto.AsymmetricBlockCipher; import org.bouncycastle.crypto.CipherParameters; import org.bouncycastle.crypto.CryptoException; import org.bouncycastle.crypto.DataLengthException; import org.bouncycastle.crypto.Digest; import org.bouncycastle.crypto.Signer; import org.bouncycastle.crypto.encodings.PKCS1Encoding; import org.bouncycastle.crypto.engines.RSABlindedEngine; import org.bouncycastle.crypto.params.AsymmetricKeyParameter; import org.bouncycastle.crypto.params.ParametersWithRandom; import org.bouncycastle.util.Arrays; public class RSADigestSigner implements Signer { private final AsymmetricBlockCipher rsaEngine = new PKCS1Encoding(new RSABlindedEngine()); private final AlgorithmIdentifier algId; private final Digest digest; private boolean forSigning; private static final Hashtable oidMap = new Hashtable(); /* * Load OID table. */ static { oidMap.put("RIPEMD128", TeleTrusTObjectIdentifiers.ripemd128); oidMap.put("RIPEMD160", TeleTrusTObjectIdentifiers.ripemd160); oidMap.put("RIPEMD256", TeleTrusTObjectIdentifiers.ripemd256); oidMap.put("SHA-1", X509ObjectIdentifiers.id_SHA1); oidMap.put("SHA-224", NISTObjectIdentifiers.id_sha224); oidMap.put("SHA-256", NISTObjectIdentifiers.id_sha256); oidMap.put("SHA-384", NISTObjectIdentifiers.id_sha384); oidMap.put("SHA-512", NISTObjectIdentifiers.id_sha512); oidMap.put("MD2", PKCSObjectIdentifiers.md2); oidMap.put("MD4", PKCSObjectIdentifiers.md4); oidMap.put("MD5", PKCSObjectIdentifiers.md5); } public RSADigestSigner( Digest digest) { this.digest = digest; algId = new AlgorithmIdentifier((ASN1ObjectIdentifier)oidMap.get(digest.getAlgorithmName()), DERNull.INSTANCE); } /** * @deprecated */ public String getAlgorithmName() { return digest.getAlgorithmName() + "withRSA"; } /** * initialise the signer for signing or verification. * * @param forSigning * true if for signing, false otherwise * @param parameters * necessary parameters. */ public void init( boolean forSigning, CipherParameters parameters) { this.forSigning = forSigning; AsymmetricKeyParameter k; if (parameters instanceof ParametersWithRandom) { k = (AsymmetricKeyParameter)((ParametersWithRandom)parameters).getParameters(); } else { k = (AsymmetricKeyParameter)parameters; } if (forSigning && !k.isPrivate()) { throw new IllegalArgumentException("signing requires private key"); } if (!forSigning && k.isPrivate()) { throw new IllegalArgumentException("verification requires public key"); } reset(); rsaEngine.init(forSigning, parameters); } /** * update the internal digest with the byte b */ public void update( byte input) { digest.update(input); } /** * update the internal digest with the byte array in */ public void update( byte[] input, int inOff, int length) { digest.update(input, inOff, length); } /** * Generate a signature for the message we've been loaded with using the key * we were initialised with. */ public byte[] generateSignature() throws CryptoException, DataLengthException { if (!forSigning) { throw new IllegalStateException("RSADigestSigner not initialised for signature generation."); } byte[] hash = new byte[digest.getDigestSize()]; digest.doFinal(hash, 0); try { byte[] data = derEncode(hash); return rsaEngine.processBlock(data, 0, data.length); } catch (IOException e) { throw new CryptoException("unable to encode signature: " + e.getMessage(), e); } } /** * return true if the internal state represents the signature described in * the passed in array. */ public boolean verifySignature( byte[] signature) { if (forSigning) { throw new IllegalStateException("RSADigestSigner not initialised for verification"); } byte[] hash = new byte[digest.getDigestSize()]; digest.doFinal(hash, 0); byte[] sig; byte[] expected; try { sig = rsaEngine.processBlock(signature, 0, signature.length); expected = derEncode(hash); } catch (Exception e) { return false; } if (sig.length == expected.length) { return Arrays.constantTimeAreEqual(sig, expected); } else if (sig.length == expected.length - 2) // NULL left out { int sigOffset = sig.length - hash.length - 2; int expectedOffset = expected.length - hash.length - 2; expected[1] -= 2; // adjust lengths expected[3] -= 2; int nonEqual = 0; for (int i = 0; i < hash.length; i++) { nonEqual |= (sig[sigOffset + i] ^ expected[expectedOffset + i]); } for (int i = 0; i < sigOffset; i++) { nonEqual |= (sig[i] ^ expected[i]); // check header less NULL } return nonEqual == 0; } else { return false; } } public void reset() { digest.reset(); } private byte[] derEncode( byte[] hash) throws IOException { DigestInfo dInfo = new DigestInfo(algId, hash); return dInfo.getEncoded(ASN1Encoding.DER); } } bouncycastle-1.49.orig/src/org/bouncycastle/crypto/signers/ECNRSigner.java0000644000175000017500000001413612112273576026251 0ustar ebourgebourgpackage org.bouncycastle.crypto.signers; import org.bouncycastle.crypto.AsymmetricCipherKeyPair; import org.bouncycastle.crypto.CipherParameters; import org.bouncycastle.crypto.DSA; import org.bouncycastle.crypto.DataLengthException; import org.bouncycastle.crypto.generators.ECKeyPairGenerator; import org.bouncycastle.crypto.params.ECKeyGenerationParameters; import org.bouncycastle.crypto.params.ECKeyParameters; import org.bouncycastle.crypto.params.ECPrivateKeyParameters; import org.bouncycastle.crypto.params.ECPublicKeyParameters; import org.bouncycastle.crypto.params.ParametersWithRandom; import org.bouncycastle.math.ec.ECAlgorithms; import org.bouncycastle.math.ec.ECConstants; import org.bouncycastle.math.ec.ECPoint; import java.math.BigInteger; import java.security.SecureRandom; /** * EC-NR as described in IEEE 1363-2000 */ public class ECNRSigner implements DSA { private boolean forSigning; private ECKeyParameters key; private SecureRandom random; public void init( boolean forSigning, CipherParameters param) { this.forSigning = forSigning; if (forSigning) { if (param instanceof ParametersWithRandom) { ParametersWithRandom rParam = (ParametersWithRandom)param; this.random = rParam.getRandom(); this.key = (ECPrivateKeyParameters)rParam.getParameters(); } else { this.random = new SecureRandom(); this.key = (ECPrivateKeyParameters)param; } } else { this.key = (ECPublicKeyParameters)param; } } // Section 7.2.5 ECSP-NR, pg 34 /** * generate a signature for the given message using the key we were * initialised with. Generally, the order of the curve should be at * least as long as the hash of the message of interest, and with * ECNR it *must* be at least as long. * * @param digest the digest to be signed. * @exception DataLengthException if the digest is longer than the key allows */ public BigInteger[] generateSignature( byte[] digest) { if (! this.forSigning) { throw new IllegalStateException("not initialised for signing"); } BigInteger n = ((ECPrivateKeyParameters)this.key).getParameters().getN(); int nBitLength = n.bitLength(); BigInteger e = new BigInteger(1, digest); int eBitLength = e.bitLength(); ECPrivateKeyParameters privKey = (ECPrivateKeyParameters)key; if (eBitLength > nBitLength) { throw new DataLengthException("input too large for ECNR key."); } BigInteger r = null; BigInteger s = null; AsymmetricCipherKeyPair tempPair; do // generate r { // generate another, but very temporary, key pair using // the same EC parameters ECKeyPairGenerator keyGen = new ECKeyPairGenerator(); keyGen.init(new ECKeyGenerationParameters(privKey.getParameters(), this.random)); tempPair = keyGen.generateKeyPair(); // BigInteger Vx = tempPair.getPublic().getW().getAffineX(); ECPublicKeyParameters V = (ECPublicKeyParameters)tempPair.getPublic(); // get temp's public key BigInteger Vx = V.getQ().getX().toBigInteger(); // get the point's x coordinate r = Vx.add(e).mod(n); } while (r.equals(ECConstants.ZERO)); // generate s BigInteger x = privKey.getD(); // private key value BigInteger u = ((ECPrivateKeyParameters)tempPair.getPrivate()).getD(); // temp's private key value s = u.subtract(r.multiply(x)).mod(n); BigInteger[] res = new BigInteger[2]; res[0] = r; res[1] = s; return res; } // Section 7.2.6 ECVP-NR, pg 35 /** * return true if the value r and s represent a signature for the * message passed in. Generally, the order of the curve should be at * least as long as the hash of the message of interest, and with * ECNR, it *must* be at least as long. But just in case the signer * applied mod(n) to the longer digest, this implementation will * apply mod(n) during verification. * * @param digest the digest to be verified. * @param r the r value of the signature. * @param s the s value of the signature. * @exception DataLengthException if the digest is longer than the key allows */ public boolean verifySignature( byte[] digest, BigInteger r, BigInteger s) { if (this.forSigning) { throw new IllegalStateException("not initialised for verifying"); } ECPublicKeyParameters pubKey = (ECPublicKeyParameters)key; BigInteger n = pubKey.getParameters().getN(); int nBitLength = n.bitLength(); BigInteger e = new BigInteger(1, digest); int eBitLength = e.bitLength(); if (eBitLength > nBitLength) { throw new DataLengthException("input too large for ECNR key."); } // r in the range [1,n-1] if (r.compareTo(ECConstants.ONE) < 0 || r.compareTo(n) >= 0) { return false; } // s in the range [0,n-1] NB: ECNR spec says 0 if (s.compareTo(ECConstants.ZERO) < 0 || s.compareTo(n) >= 0) { return false; } // compute P = sG + rW ECPoint G = pubKey.getParameters().getG(); ECPoint W = pubKey.getQ(); // calculate P using Bouncy math ECPoint P = ECAlgorithms.sumOfTwoMultiplies(G, s, W, r); // components must be bogus. if (P.isInfinity()) { return false; } BigInteger x = P.getX().toBigInteger(); BigInteger t = r.subtract(x).mod(n); return t.equals(e); } } bouncycastle-1.49.orig/src/org/bouncycastle/crypto/signers/ECGOST3410Signer.java0000644000175000017500000001050112112273576027006 0ustar ebourgebourgpackage org.bouncycastle.crypto.signers; import org.bouncycastle.crypto.CipherParameters; import org.bouncycastle.crypto.DSA; import org.bouncycastle.crypto.params.ECKeyParameters; import org.bouncycastle.crypto.params.ECPrivateKeyParameters; import org.bouncycastle.crypto.params.ECPublicKeyParameters; import org.bouncycastle.crypto.params.ParametersWithRandom; import org.bouncycastle.math.ec.ECAlgorithms; import org.bouncycastle.math.ec.ECConstants; import org.bouncycastle.math.ec.ECPoint; import java.math.BigInteger; import java.security.SecureRandom; /** * GOST R 34.10-2001 Signature Algorithm */ public class ECGOST3410Signer implements DSA { ECKeyParameters key; SecureRandom random; public void init( boolean forSigning, CipherParameters param) { if (forSigning) { if (param instanceof ParametersWithRandom) { ParametersWithRandom rParam = (ParametersWithRandom)param; this.random = rParam.getRandom(); this.key = (ECPrivateKeyParameters)rParam.getParameters(); } else { this.random = new SecureRandom(); this.key = (ECPrivateKeyParameters)param; } } else { this.key = (ECPublicKeyParameters)param; } } /** * generate a signature for the given message using the key we were * initialised with. For conventional GOST3410 the message should be a GOST3411 * hash of the message of interest. * * @param message the message that will be verified later. */ public BigInteger[] generateSignature( byte[] message) { byte[] mRev = new byte[message.length]; // conversion is little-endian for (int i = 0; i != mRev.length; i++) { mRev[i] = message[mRev.length - 1 - i]; } BigInteger e = new BigInteger(1, mRev); BigInteger n = key.getParameters().getN(); BigInteger r = null; BigInteger s = null; do // generate s { BigInteger k = null; do // generate r { do { k = new BigInteger(n.bitLength(), random); } while (k.equals(ECConstants.ZERO)); ECPoint p = key.getParameters().getG().multiply(k); BigInteger x = p.getX().toBigInteger(); r = x.mod(n); } while (r.equals(ECConstants.ZERO)); BigInteger d = ((ECPrivateKeyParameters)key).getD(); s = (k.multiply(e)).add(d.multiply(r)).mod(n); } while (s.equals(ECConstants.ZERO)); BigInteger[] res = new BigInteger[2]; res[0] = r; res[1] = s; return res; } /** * return true if the value r and s represent a GOST3410 signature for * the passed in message (for standard GOST3410 the message should be * a GOST3411 hash of the real message to be verified). */ public boolean verifySignature( byte[] message, BigInteger r, BigInteger s) { byte[] mRev = new byte[message.length]; // conversion is little-endian for (int i = 0; i != mRev.length; i++) { mRev[i] = message[mRev.length - 1 - i]; } BigInteger e = new BigInteger(1, mRev); BigInteger n = key.getParameters().getN(); // r in the range [1,n-1] if (r.compareTo(ECConstants.ONE) < 0 || r.compareTo(n) >= 0) { return false; } // s in the range [1,n-1] if (s.compareTo(ECConstants.ONE) < 0 || s.compareTo(n) >= 0) { return false; } BigInteger v = e.modInverse(n); BigInteger z1 = s.multiply(v).mod(n); BigInteger z2 = (n.subtract(r)).multiply(v).mod(n); ECPoint G = key.getParameters().getG(); // P ECPoint Q = ((ECPublicKeyParameters)key).getQ(); ECPoint point = ECAlgorithms.sumOfTwoMultiplies(G, z1, Q, z2); // components must be bogus. if (point.isInfinity()) { return false; } BigInteger R = point.getX().toBigInteger().mod(n); return R.equals(r); } } bouncycastle-1.49.orig/src/org/bouncycastle/crypto/signers/package.html0000644000175000017500000000007710262753175025771 0ustar ebourgebourg Basic signers. bouncycastle-1.49.orig/src/org/bouncycastle/crypto/signers/DSADigestSigner.java0000644000175000017500000000774011625077210027267 0ustar ebourgebourgpackage org.bouncycastle.crypto.signers; import java.io.IOException; import java.math.BigInteger; import org.bouncycastle.asn1.ASN1EncodableVector; import org.bouncycastle.asn1.ASN1Encoding; import org.bouncycastle.asn1.ASN1Primitive; import org.bouncycastle.asn1.ASN1Sequence; import org.bouncycastle.asn1.DERInteger; import org.bouncycastle.asn1.DERSequence; import org.bouncycastle.crypto.CipherParameters; import org.bouncycastle.crypto.DSA; import org.bouncycastle.crypto.Digest; import org.bouncycastle.crypto.Signer; import org.bouncycastle.crypto.params.AsymmetricKeyParameter; import org.bouncycastle.crypto.params.ParametersWithRandom; public class DSADigestSigner implements Signer { private final Digest digest; private final DSA dsaSigner; private boolean forSigning; public DSADigestSigner( DSA signer, Digest digest) { this.digest = digest; this.dsaSigner = signer; } public void init( boolean forSigning, CipherParameters parameters) { this.forSigning = forSigning; AsymmetricKeyParameter k; if (parameters instanceof ParametersWithRandom) { k = (AsymmetricKeyParameter)((ParametersWithRandom)parameters).getParameters(); } else { k = (AsymmetricKeyParameter)parameters; } if (forSigning && !k.isPrivate()) { throw new IllegalArgumentException("Signing Requires Private Key."); } if (!forSigning && k.isPrivate()) { throw new IllegalArgumentException("Verification Requires Public Key."); } reset(); dsaSigner.init(forSigning, parameters); } /** * update the internal digest with the byte b */ public void update( byte input) { digest.update(input); } /** * update the internal digest with the byte array in */ public void update( byte[] input, int inOff, int length) { digest.update(input, inOff, length); } /** * Generate a signature for the message we've been loaded with using * the key we were initialised with. */ public byte[] generateSignature() { if (!forSigning) { throw new IllegalStateException("DSADigestSigner not initialised for signature generation."); } byte[] hash = new byte[digest.getDigestSize()]; digest.doFinal(hash, 0); BigInteger[] sig = dsaSigner.generateSignature(hash); try { return derEncode(sig[0], sig[1]); } catch (IOException e) { throw new IllegalStateException("unable to encode signature"); } } public boolean verifySignature( byte[] signature) { if (forSigning) { throw new IllegalStateException("DSADigestSigner not initialised for verification"); } byte[] hash = new byte[digest.getDigestSize()]; digest.doFinal(hash, 0); try { BigInteger[] sig = derDecode(signature); return dsaSigner.verifySignature(hash, sig[0], sig[1]); } catch (IOException e) { return false; } } public void reset() { digest.reset(); } private byte[] derEncode( BigInteger r, BigInteger s) throws IOException { ASN1EncodableVector v = new ASN1EncodableVector(); v.add(new DERInteger(r)); v.add(new DERInteger(s)); return new DERSequence(v).getEncoded(ASN1Encoding.DER); } private BigInteger[] derDecode( byte[] encoding) throws IOException { ASN1Sequence s = (ASN1Sequence)ASN1Primitive.fromByteArray(encoding); return new BigInteger[] { ((DERInteger)s.getObjectAt(0)).getValue(), ((DERInteger)s.getObjectAt(1)).getValue() }; } } bouncycastle-1.49.orig/src/org/bouncycastle/crypto/signers/DSASigner.java0000644000175000017500000000766410557547012026141 0ustar ebourgebourgpackage org.bouncycastle.crypto.signers; import org.bouncycastle.crypto.CipherParameters; import org.bouncycastle.crypto.DSA; import org.bouncycastle.crypto.params.DSAKeyParameters; import org.bouncycastle.crypto.params.DSAParameters; import org.bouncycastle.crypto.params.DSAPrivateKeyParameters; import org.bouncycastle.crypto.params.DSAPublicKeyParameters; import org.bouncycastle.crypto.params.ParametersWithRandom; import java.math.BigInteger; import java.security.SecureRandom; /** * The Digital Signature Algorithm - as described in "Handbook of Applied * Cryptography", pages 452 - 453. */ public class DSASigner implements DSA { DSAKeyParameters key; SecureRandom random; public void init( boolean forSigning, CipherParameters param) { if (forSigning) { if (param instanceof ParametersWithRandom) { ParametersWithRandom rParam = (ParametersWithRandom)param; this.random = rParam.getRandom(); this.key = (DSAPrivateKeyParameters)rParam.getParameters(); } else { this.random = new SecureRandom(); this.key = (DSAPrivateKeyParameters)param; } } else { this.key = (DSAPublicKeyParameters)param; } } /** * generate a signature for the given message using the key we were * initialised with. For conventional DSA the message should be a SHA-1 * hash of the message of interest. * * @param message the message that will be verified later. */ public BigInteger[] generateSignature( byte[] message) { DSAParameters params = key.getParameters(); BigInteger m = calculateE(params.getQ(), message); BigInteger k; int qBitLength = params.getQ().bitLength(); do { k = new BigInteger(qBitLength, random); } while (k.compareTo(params.getQ()) >= 0); BigInteger r = params.getG().modPow(k, params.getP()).mod(params.getQ()); k = k.modInverse(params.getQ()).multiply( m.add(((DSAPrivateKeyParameters)key).getX().multiply(r))); BigInteger s = k.mod(params.getQ()); BigInteger[] res = new BigInteger[2]; res[0] = r; res[1] = s; return res; } /** * return true if the value r and s represent a DSA signature for * the passed in message for standard DSA the message should be a * SHA-1 hash of the real message to be verified. */ public boolean verifySignature( byte[] message, BigInteger r, BigInteger s) { DSAParameters params = key.getParameters(); BigInteger m = calculateE(params.getQ(), message); BigInteger zero = BigInteger.valueOf(0); if (zero.compareTo(r) >= 0 || params.getQ().compareTo(r) <= 0) { return false; } if (zero.compareTo(s) >= 0 || params.getQ().compareTo(s) <= 0) { return false; } BigInteger w = s.modInverse(params.getQ()); BigInteger u1 = m.multiply(w).mod(params.getQ()); BigInteger u2 = r.multiply(w).mod(params.getQ()); u1 = params.getG().modPow(u1, params.getP()); u2 = ((DSAPublicKeyParameters)key).getY().modPow(u2, params.getP()); BigInteger v = u1.multiply(u2).mod(params.getP()).mod(params.getQ()); return v.equals(r); } private BigInteger calculateE(BigInteger n, byte[] message) { if (n.bitLength() >= message.length * 8) { return new BigInteger(1, message); } else { byte[] trunc = new byte[n.bitLength() / 8]; System.arraycopy(message, 0, trunc, 0, trunc.length); return new BigInteger(1, trunc); } } } bouncycastle-1.49.orig/src/org/bouncycastle/crypto/AsymmetricCipherKeyPair.java0000644000175000017500000000305411737302035027425 0ustar ebourgebourgpackage org.bouncycastle.crypto; import org.bouncycastle.crypto.params.AsymmetricKeyParameter; /** * a holding class for public/private parameter pairs. */ public class AsymmetricCipherKeyPair { private AsymmetricKeyParameter publicParam; private AsymmetricKeyParameter privateParam; /** * basic constructor. * * @param publicParam a public key parameters object. * @param privateParam the corresponding private key parameters. */ public AsymmetricCipherKeyPair( AsymmetricKeyParameter publicParam, AsymmetricKeyParameter privateParam) { this.publicParam = publicParam; this.privateParam = privateParam; } /** * basic constructor. * * @param publicParam a public key parameters object. * @param privateParam the corresponding private key parameters. * @deprecated use AsymmetricKeyParameter */ public AsymmetricCipherKeyPair( CipherParameters publicParam, CipherParameters privateParam) { this.publicParam = (AsymmetricKeyParameter)publicParam; this.privateParam = (AsymmetricKeyParameter)privateParam; } /** * return the public key parameters. * * @return the public key parameters. */ public AsymmetricKeyParameter getPublic() { return publicParam; } /** * return the private key parameters. * * @return the private key parameters. */ public AsymmetricKeyParameter getPrivate() { return privateParam; } } bouncycastle-1.49.orig/src/org/bouncycastle/crypto/ExtendedDigest.java0000644000175000017500000000047410405216632025571 0ustar ebourgebourgpackage org.bouncycastle.crypto; public interface ExtendedDigest extends Digest { /** * Return the size in bytes of the internal buffer the digest applies it's compression * function to. * * @return byte length of the digests internal buffer. */ public int getByteLength(); } bouncycastle-1.49.orig/src/org/bouncycastle/crypto/macs/0000755000175000017500000000000012152033551022742 5ustar ebourgebourgbouncycastle-1.49.orig/src/org/bouncycastle/crypto/macs/VMPCMac.java0000644000175000017500000001214110725007113024771 0ustar ebourgebourgpackage org.bouncycastle.crypto.macs; import org.bouncycastle.crypto.CipherParameters; import org.bouncycastle.crypto.DataLengthException; import org.bouncycastle.crypto.Mac; import org.bouncycastle.crypto.params.KeyParameter; import org.bouncycastle.crypto.params.ParametersWithIV; public class VMPCMac implements Mac { private byte g; private byte n = 0; private byte[] P = null; private byte s = 0; private byte[] T; private byte[] workingIV; private byte[] workingKey; private byte x1, x2, x3, x4; public int doFinal(byte[] out, int outOff) throws DataLengthException, IllegalStateException { // Execute the Post-Processing Phase for (int r = 1; r < 25; r++) { s = P[(s + P[n & 0xff]) & 0xff]; x4 = P[(x4 + x3 + r) & 0xff]; x3 = P[(x3 + x2 + r) & 0xff]; x2 = P[(x2 + x1 + r) & 0xff]; x1 = P[(x1 + s + r) & 0xff]; T[g & 0x1f] = (byte) (T[g & 0x1f] ^ x1); T[(g + 1) & 0x1f] = (byte) (T[(g + 1) & 0x1f] ^ x2); T[(g + 2) & 0x1f] = (byte) (T[(g + 2) & 0x1f] ^ x3); T[(g + 3) & 0x1f] = (byte) (T[(g + 3) & 0x1f] ^ x4); g = (byte) ((g + 4) & 0x1f); byte temp = P[n & 0xff]; P[n & 0xff] = P[s & 0xff]; P[s & 0xff] = temp; n = (byte) ((n + 1) & 0xff); } // Input T to the IV-phase of the VMPC KSA for (int m = 0; m < 768; m++) { s = P[(s + P[m & 0xff] + T[m & 0x1f]) & 0xff]; byte temp = P[m & 0xff]; P[m & 0xff] = P[s & 0xff]; P[s & 0xff] = temp; } // Store 20 new outputs of the VMPC Stream Cipher in table M byte[] M = new byte[20]; for (int i = 0; i < 20; i++) { s = P[(s + P[i & 0xff]) & 0xff]; M[i] = P[(P[(P[s & 0xff]) & 0xff] + 1) & 0xff]; byte temp = P[i & 0xff]; P[i & 0xff] = P[s & 0xff]; P[s & 0xff] = temp; } System.arraycopy(M, 0, out, outOff, M.length); reset(); return M.length; } public String getAlgorithmName() { return "VMPC-MAC"; } public int getMacSize() { return 20; } public void init(CipherParameters params) throws IllegalArgumentException { if (!(params instanceof ParametersWithIV)) { throw new IllegalArgumentException( "VMPC-MAC Init parameters must include an IV"); } ParametersWithIV ivParams = (ParametersWithIV) params; KeyParameter key = (KeyParameter) ivParams.getParameters(); if (!(ivParams.getParameters() instanceof KeyParameter)) { throw new IllegalArgumentException( "VMPC-MAC Init parameters must include a key"); } this.workingIV = ivParams.getIV(); if (workingIV == null || workingIV.length < 1 || workingIV.length > 768) { throw new IllegalArgumentException( "VMPC-MAC requires 1 to 768 bytes of IV"); } this.workingKey = key.getKey(); reset(); } private void initKey(byte[] keyBytes, byte[] ivBytes) { s = 0; P = new byte[256]; for (int i = 0; i < 256; i++) { P[i] = (byte) i; } for (int m = 0; m < 768; m++) { s = P[(s + P[m & 0xff] + keyBytes[m % keyBytes.length]) & 0xff]; byte temp = P[m & 0xff]; P[m & 0xff] = P[s & 0xff]; P[s & 0xff] = temp; } for (int m = 0; m < 768; m++) { s = P[(s + P[m & 0xff] + ivBytes[m % ivBytes.length]) & 0xff]; byte temp = P[m & 0xff]; P[m & 0xff] = P[s & 0xff]; P[s & 0xff] = temp; } n = 0; } public void reset() { initKey(this.workingKey, this.workingIV); g = x1 = x2 = x3 = x4 = n = 0; T = new byte[32]; for (int i = 0; i < 32; i++) { T[i] = 0; } } public void update(byte in) throws IllegalStateException { s = P[(s + P[n & 0xff]) & 0xff]; byte c = (byte) (in ^ P[(P[(P[s & 0xff]) & 0xff] + 1) & 0xff]); x4 = P[(x4 + x3) & 0xff]; x3 = P[(x3 + x2) & 0xff]; x2 = P[(x2 + x1) & 0xff]; x1 = P[(x1 + s + c) & 0xff]; T[g & 0x1f] = (byte) (T[g & 0x1f] ^ x1); T[(g + 1) & 0x1f] = (byte) (T[(g + 1) & 0x1f] ^ x2); T[(g + 2) & 0x1f] = (byte) (T[(g + 2) & 0x1f] ^ x3); T[(g + 3) & 0x1f] = (byte) (T[(g + 3) & 0x1f] ^ x4); g = (byte) ((g + 4) & 0x1f); byte temp = P[n & 0xff]; P[n & 0xff] = P[s & 0xff]; P[s & 0xff] = temp; n = (byte) ((n + 1) & 0xff); } public void update(byte[] in, int inOff, int len) throws DataLengthException, IllegalStateException { if ((inOff + len) > in.length) { throw new DataLengthException("input buffer too short"); } for (int i = 0; i < len; i++) { update(in[i]); } } } bouncycastle-1.49.orig/src/org/bouncycastle/crypto/macs/CBCBlockCipherMac.java0000644000175000017500000001402411301402613026716 0ustar ebourgebourgpackage org.bouncycastle.crypto.macs; import org.bouncycastle.crypto.BlockCipher; import org.bouncycastle.crypto.CipherParameters; import org.bouncycastle.crypto.Mac; import org.bouncycastle.crypto.modes.CBCBlockCipher; import org.bouncycastle.crypto.paddings.BlockCipherPadding; /** * standard CBC Block Cipher MAC - if no padding is specified the default of * pad of zeroes is used. */ public class CBCBlockCipherMac implements Mac { private byte[] mac; private byte[] buf; private int bufOff; private BlockCipher cipher; private BlockCipherPadding padding; private int macSize; /** * create a standard MAC based on a CBC block cipher. This will produce an * authentication code half the length of the block size of the cipher. * * @param cipher the cipher to be used as the basis of the MAC generation. */ public CBCBlockCipherMac( BlockCipher cipher) { this(cipher, (cipher.getBlockSize() * 8) / 2, null); } /** * create a standard MAC based on a CBC block cipher. This will produce an * authentication code half the length of the block size of the cipher. * * @param cipher the cipher to be used as the basis of the MAC generation. * @param padding the padding to be used to complete the last block. */ public CBCBlockCipherMac( BlockCipher cipher, BlockCipherPadding padding) { this(cipher, (cipher.getBlockSize() * 8) / 2, padding); } /** * create a standard MAC based on a block cipher with the size of the * MAC been given in bits. This class uses CBC mode as the basis for the * MAC generation. *

    * Note: the size of the MAC must be at least 24 bits (FIPS Publication 81), * or 16 bits if being used as a data authenticator (FIPS Publication 113), * and in general should be less than the size of the block cipher as it reduces * the chance of an exhaustive attack (see Handbook of Applied Cryptography). * * @param cipher the cipher to be used as the basis of the MAC generation. * @param macSizeInBits the size of the MAC in bits, must be a multiple of 8. */ public CBCBlockCipherMac( BlockCipher cipher, int macSizeInBits) { this(cipher, macSizeInBits, null); } /** * create a standard MAC based on a block cipher with the size of the * MAC been given in bits. This class uses CBC mode as the basis for the * MAC generation. *

    * Note: the size of the MAC must be at least 24 bits (FIPS Publication 81), * or 16 bits if being used as a data authenticator (FIPS Publication 113), * and in general should be less than the size of the block cipher as it reduces * the chance of an exhaustive attack (see Handbook of Applied Cryptography). * * @param cipher the cipher to be used as the basis of the MAC generation. * @param macSizeInBits the size of the MAC in bits, must be a multiple of 8. * @param padding the padding to be used to complete the last block. */ public CBCBlockCipherMac( BlockCipher cipher, int macSizeInBits, BlockCipherPadding padding) { if ((macSizeInBits % 8) != 0) { throw new IllegalArgumentException("MAC size must be multiple of 8"); } this.cipher = new CBCBlockCipher(cipher); this.padding = padding; this.macSize = macSizeInBits / 8; mac = new byte[cipher.getBlockSize()]; buf = new byte[cipher.getBlockSize()]; bufOff = 0; } public String getAlgorithmName() { return cipher.getAlgorithmName(); } public void init( CipherParameters params) { reset(); cipher.init(true, params); } public int getMacSize() { return macSize; } public void update( byte in) { if (bufOff == buf.length) { cipher.processBlock(buf, 0, mac, 0); bufOff = 0; } buf[bufOff++] = in; } public void update( byte[] in, int inOff, int len) { if (len < 0) { throw new IllegalArgumentException("Can't have a negative input length!"); } int blockSize = cipher.getBlockSize(); int gapLen = blockSize - bufOff; if (len > gapLen) { System.arraycopy(in, inOff, buf, bufOff, gapLen); cipher.processBlock(buf, 0, mac, 0); bufOff = 0; len -= gapLen; inOff += gapLen; while (len > blockSize) { cipher.processBlock(in, inOff, mac, 0); len -= blockSize; inOff += blockSize; } } System.arraycopy(in, inOff, buf, bufOff, len); bufOff += len; } public int doFinal( byte[] out, int outOff) { int blockSize = cipher.getBlockSize(); if (padding == null) { // // pad with zeroes // while (bufOff < blockSize) { buf[bufOff] = 0; bufOff++; } } else { if (bufOff == blockSize) { cipher.processBlock(buf, 0, mac, 0); bufOff = 0; } padding.addPadding(buf, bufOff); } cipher.processBlock(buf, 0, mac, 0); System.arraycopy(mac, 0, out, outOff, macSize); reset(); return macSize; } /** * Reset the mac generator. */ public void reset() { /* * clean the buffer. */ for (int i = 0; i < buf.length; i++) { buf[i] = 0; } bufOff = 0; /* * reset the underlying cipher. */ cipher.reset(); } } bouncycastle-1.49.orig/src/org/bouncycastle/crypto/macs/CMac.java0000644000175000017500000001412712045642260024421 0ustar ebourgebourgpackage org.bouncycastle.crypto.macs; import org.bouncycastle.crypto.BlockCipher; import org.bouncycastle.crypto.CipherParameters; import org.bouncycastle.crypto.Mac; import org.bouncycastle.crypto.modes.CBCBlockCipher; import org.bouncycastle.crypto.paddings.ISO7816d4Padding; /** * CMAC - as specified at www.nuee.nagoya-u.ac.jp/labs/tiwata/omac/omac.html *

    * CMAC is analogous to OMAC1 - see also en.wikipedia.org/wiki/CMAC *

    * CMAC is a NIST recomendation - see * csrc.nist.gov/CryptoToolkit/modes/800-38_Series_Publications/SP800-38B.pdf *

    * CMAC/OMAC1 is a blockcipher-based message authentication code designed and * analyzed by Tetsu Iwata and Kaoru Kurosawa. *

    * CMAC/OMAC1 is a simple variant of the CBC MAC (Cipher Block Chaining Message * Authentication Code). OMAC stands for One-Key CBC MAC. *

    * It supports 128- or 64-bits block ciphers, with any key size, and returns * a MAC with dimension less or equal to the block size of the underlying * cipher. *

    */ public class CMac implements Mac { private static final byte CONSTANT_128 = (byte)0x87; private static final byte CONSTANT_64 = (byte)0x1b; private byte[] ZEROES; private byte[] mac; private byte[] buf; private int bufOff; private BlockCipher cipher; private int macSize; private byte[] L, Lu, Lu2; /** * create a standard MAC based on a CBC block cipher (64 or 128 bit block). * This will produce an authentication code the length of the block size * of the cipher. * * @param cipher the cipher to be used as the basis of the MAC generation. */ public CMac(BlockCipher cipher) { this(cipher, cipher.getBlockSize() * 8); } /** * create a standard MAC based on a block cipher with the size of the * MAC been given in bits. *

    * Note: the size of the MAC must be at least 24 bits (FIPS Publication 81), * or 16 bits if being used as a data authenticator (FIPS Publication 113), * and in general should be less than the size of the block cipher as it reduces * the chance of an exhaustive attack (see Handbook of Applied Cryptography). * * @param cipher the cipher to be used as the basis of the MAC generation. * @param macSizeInBits the size of the MAC in bits, must be a multiple of 8 and <= 128. */ public CMac(BlockCipher cipher, int macSizeInBits) { if ((macSizeInBits % 8) != 0) { throw new IllegalArgumentException("MAC size must be multiple of 8"); } if (macSizeInBits > (cipher.getBlockSize() * 8)) { throw new IllegalArgumentException( "MAC size must be less or equal to " + (cipher.getBlockSize() * 8)); } if (cipher.getBlockSize() != 8 && cipher.getBlockSize() != 16) { throw new IllegalArgumentException( "Block size must be either 64 or 128 bits"); } this.cipher = new CBCBlockCipher(cipher); this.macSize = macSizeInBits / 8; mac = new byte[cipher.getBlockSize()]; buf = new byte[cipher.getBlockSize()]; ZEROES = new byte[cipher.getBlockSize()]; bufOff = 0; } public String getAlgorithmName() { return cipher.getAlgorithmName(); } private static byte[] doubleLu(byte[] in) { int FirstBit = (in[0] & 0xFF) >> 7; byte[] ret = new byte[in.length]; for (int i = 0; i < in.length - 1; i++) { ret[i] = (byte)((in[i] << 1) + ((in[i + 1] & 0xFF) >> 7)); } ret[in.length - 1] = (byte)(in[in.length - 1] << 1); if (FirstBit == 1) { ret[in.length - 1] ^= in.length == 16 ? CONSTANT_128 : CONSTANT_64; } return ret; } public void init(CipherParameters params) { if (params != null) { cipher.init(true, params); //initializes the L, Lu, Lu2 numbers L = new byte[ZEROES.length]; cipher.processBlock(ZEROES, 0, L, 0); Lu = doubleLu(L); Lu2 = doubleLu(Lu); } reset(); } public int getMacSize() { return macSize; } public void update(byte in) { if (bufOff == buf.length) { cipher.processBlock(buf, 0, mac, 0); bufOff = 0; } buf[bufOff++] = in; } public void update(byte[] in, int inOff, int len) { if (len < 0) { throw new IllegalArgumentException( "Can't have a negative input length!"); } int blockSize = cipher.getBlockSize(); int gapLen = blockSize - bufOff; if (len > gapLen) { System.arraycopy(in, inOff, buf, bufOff, gapLen); cipher.processBlock(buf, 0, mac, 0); bufOff = 0; len -= gapLen; inOff += gapLen; while (len > blockSize) { cipher.processBlock(in, inOff, mac, 0); len -= blockSize; inOff += blockSize; } } System.arraycopy(in, inOff, buf, bufOff, len); bufOff += len; } public int doFinal(byte[] out, int outOff) { int blockSize = cipher.getBlockSize(); byte[] lu; if (bufOff == blockSize) { lu = Lu; } else { new ISO7816d4Padding().addPadding(buf, bufOff); lu = Lu2; } for (int i = 0; i < mac.length; i++) { buf[i] ^= lu[i]; } cipher.processBlock(buf, 0, mac, 0); System.arraycopy(mac, 0, out, outOff, macSize); reset(); return macSize; } /** * Reset the mac generator. */ public void reset() { /* * clean the buffer. */ for (int i = 0; i < buf.length; i++) { buf[i] = 0; } bufOff = 0; /* * reset the underlying cipher. */ cipher.reset(); } } bouncycastle-1.49.orig/src/org/bouncycastle/crypto/macs/GMac.java0000644000175000017500000000665212147270165024435 0ustar ebourgebourgpackage org.bouncycastle.crypto.macs; import org.bouncycastle.crypto.CipherParameters; import org.bouncycastle.crypto.DataLengthException; import org.bouncycastle.crypto.InvalidCipherTextException; import org.bouncycastle.crypto.Mac; import org.bouncycastle.crypto.modes.GCMBlockCipher; import org.bouncycastle.crypto.params.AEADParameters; import org.bouncycastle.crypto.params.KeyParameter; import org.bouncycastle.crypto.params.ParametersWithIV; /** * The GMAC specialisation of Galois/Counter mode (GCM) detailed in NIST Special Publication * 800-38D. *

    * GMac is an invocation of the GCM mode where no data is encrypted (i.e. all input data to the Mac * is processed as additional authenticated data with the underlying GCM block cipher). */ public class GMac implements Mac { private final GCMBlockCipher cipher; private final int macSizeBits; /** * Creates a GMAC based on the operation of a block cipher in GCM mode. *

    * This will produce an authentication code the length of the block size of the cipher. * * @param cipher * the cipher to be used in GCM mode to generate the MAC. */ public GMac(final GCMBlockCipher cipher) { // use of this confused flow analyser in some earlier JDKs this.cipher = cipher; this.macSizeBits = 128; } /** * Creates a GMAC based on the operation of a 128 bit block cipher in GCM mode. * * @param macSizeBits * the mac size to generate, in bits. Must be a multiple of 8 and >= 96 and <= 128. * @param cipher * the cipher to be used in GCM mode to generate the MAC. */ public GMac(final GCMBlockCipher cipher, final int macSizeBits) { this.cipher = cipher; this.macSizeBits = macSizeBits; } /** * Initialises the GMAC - requires a {@link ParametersWithIV} providing a {@link KeyParameter} * and a nonce. */ public void init(final CipherParameters params) throws IllegalArgumentException { if (params instanceof ParametersWithIV) { final ParametersWithIV param = (ParametersWithIV)params; final byte[] iv = param.getIV(); final KeyParameter keyParam = (KeyParameter)param.getParameters(); // GCM is always operated in encrypt mode to calculate MAC cipher.init(true, new AEADParameters(keyParam, macSizeBits, iv)); } else { throw new IllegalArgumentException("GMAC requires ParametersWithIV"); } } public String getAlgorithmName() { return cipher.getUnderlyingCipher().getAlgorithmName() + "-GMAC"; } public int getMacSize() { return macSizeBits / 8; } public void update(byte in) throws IllegalStateException { cipher.processAADByte(in); } public void update(byte[] in, int inOff, int len) throws DataLengthException, IllegalStateException { cipher.processAADBytes(in, inOff, len); } public int doFinal(byte[] out, int outOff) throws DataLengthException, IllegalStateException { try { return cipher.doFinal(out, outOff); } catch (InvalidCipherTextException e) { // Impossible in encrypt mode throw new IllegalStateException(e.toString()); } } public void reset() { cipher.reset(); } } bouncycastle-1.49.orig/src/org/bouncycastle/crypto/macs/ISO9797Alg3Mac.java0000644000175000017500000002135711511176154025744 0ustar ebourgebourgpackage org.bouncycastle.crypto.macs; import org.bouncycastle.crypto.BlockCipher; import org.bouncycastle.crypto.CipherParameters; import org.bouncycastle.crypto.Mac; import org.bouncycastle.crypto.engines.DESEngine; import org.bouncycastle.crypto.modes.CBCBlockCipher; import org.bouncycastle.crypto.paddings.BlockCipherPadding; import org.bouncycastle.crypto.params.KeyParameter; import org.bouncycastle.crypto.params.ParametersWithIV; /** * DES based CBC Block Cipher MAC according to ISO9797, algorithm 3 (ANSI X9.19 Retail MAC) * * This could as well be derived from CBCBlockCipherMac, but then the property mac in the base * class must be changed to protected */ public class ISO9797Alg3Mac implements Mac { private byte[] mac; private byte[] buf; private int bufOff; private BlockCipher cipher; private BlockCipherPadding padding; private int macSize; private KeyParameter lastKey2; private KeyParameter lastKey3; /** * create a Retail-MAC based on a CBC block cipher. This will produce an * authentication code of the length of the block size of the cipher. * * @param cipher the cipher to be used as the basis of the MAC generation. This must * be DESEngine. */ public ISO9797Alg3Mac( BlockCipher cipher) { this(cipher, cipher.getBlockSize() * 8, null); } /** * create a Retail-MAC based on a CBC block cipher. This will produce an * authentication code of the length of the block size of the cipher. * * @param cipher the cipher to be used as the basis of the MAC generation. * @param padding the padding to be used to complete the last block. */ public ISO9797Alg3Mac( BlockCipher cipher, BlockCipherPadding padding) { this(cipher, cipher.getBlockSize() * 8, padding); } /** * create a Retail-MAC based on a block cipher with the size of the * MAC been given in bits. This class uses single DES CBC mode as the basis for the * MAC generation. *

    * Note: the size of the MAC must be at least 24 bits (FIPS Publication 81), * or 16 bits if being used as a data authenticator (FIPS Publication 113), * and in general should be less than the size of the block cipher as it reduces * the chance of an exhaustive attack (see Handbook of Applied Cryptography). * * @param cipher the cipher to be used as the basis of the MAC generation. * @param macSizeInBits the size of the MAC in bits, must be a multiple of 8. */ public ISO9797Alg3Mac( BlockCipher cipher, int macSizeInBits) { this(cipher, macSizeInBits, null); } /** * create a standard MAC based on a block cipher with the size of the * MAC been given in bits. This class uses single DES CBC mode as the basis for the * MAC generation. The final block is decrypted and then encrypted using the * middle and right part of the key. *

    * Note: the size of the MAC must be at least 24 bits (FIPS Publication 81), * or 16 bits if being used as a data authenticator (FIPS Publication 113), * and in general should be less than the size of the block cipher as it reduces * the chance of an exhaustive attack (see Handbook of Applied Cryptography). * * @param cipher the cipher to be used as the basis of the MAC generation. * @param macSizeInBits the size of the MAC in bits, must be a multiple of 8. * @param padding the padding to be used to complete the last block. */ public ISO9797Alg3Mac( BlockCipher cipher, int macSizeInBits, BlockCipherPadding padding) { if ((macSizeInBits % 8) != 0) { throw new IllegalArgumentException("MAC size must be multiple of 8"); } if (!(cipher instanceof DESEngine)) { throw new IllegalArgumentException("cipher must be instance of DESEngine"); } this.cipher = new CBCBlockCipher(cipher); this.padding = padding; this.macSize = macSizeInBits / 8; mac = new byte[cipher.getBlockSize()]; buf = new byte[cipher.getBlockSize()]; bufOff = 0; } public String getAlgorithmName() { return "ISO9797Alg3"; } public void init(CipherParameters params) { reset(); if (!(params instanceof KeyParameter || params instanceof ParametersWithIV)) { throw new IllegalArgumentException( "params must be an instance of KeyParameter or ParametersWithIV"); } // KeyParameter must contain a double or triple length DES key, // however the underlying cipher is a single DES. The middle and // right key are used only in the final step. KeyParameter kp; if (params instanceof KeyParameter) { kp = (KeyParameter)params; } else { kp = (KeyParameter)((ParametersWithIV)params).getParameters(); } KeyParameter key1; byte[] keyvalue = kp.getKey(); if (keyvalue.length == 16) { // Double length DES key key1 = new KeyParameter(keyvalue, 0, 8); this.lastKey2 = new KeyParameter(keyvalue, 8, 8); this.lastKey3 = key1; } else if (keyvalue.length == 24) { // Triple length DES key key1 = new KeyParameter(keyvalue, 0, 8); this.lastKey2 = new KeyParameter(keyvalue, 8, 8); this.lastKey3 = new KeyParameter(keyvalue, 16, 8); } else { throw new IllegalArgumentException( "Key must be either 112 or 168 bit long"); } if (params instanceof ParametersWithIV) { cipher.init(true, new ParametersWithIV(key1, ((ParametersWithIV)params).getIV())); } else { cipher.init(true, key1); } } public int getMacSize() { return macSize; } public void update( byte in) { if (bufOff == buf.length) { cipher.processBlock(buf, 0, mac, 0); bufOff = 0; } buf[bufOff++] = in; } public void update( byte[] in, int inOff, int len) { if (len < 0) { throw new IllegalArgumentException("Can't have a negative input length!"); } int blockSize = cipher.getBlockSize(); int resultLen = 0; int gapLen = blockSize - bufOff; if (len > gapLen) { System.arraycopy(in, inOff, buf, bufOff, gapLen); resultLen += cipher.processBlock(buf, 0, mac, 0); bufOff = 0; len -= gapLen; inOff += gapLen; while (len > blockSize) { resultLen += cipher.processBlock(in, inOff, mac, 0); len -= blockSize; inOff += blockSize; } } System.arraycopy(in, inOff, buf, bufOff, len); bufOff += len; } public int doFinal( byte[] out, int outOff) { int blockSize = cipher.getBlockSize(); if (padding == null) { // // pad with zeroes // while (bufOff < blockSize) { buf[bufOff] = 0; bufOff++; } } else { if (bufOff == blockSize) { cipher.processBlock(buf, 0, mac, 0); bufOff = 0; } padding.addPadding(buf, bufOff); } cipher.processBlock(buf, 0, mac, 0); // Added to code from base class DESEngine deseng = new DESEngine(); deseng.init(false, this.lastKey2); deseng.processBlock(mac, 0, mac, 0); deseng.init(true, this.lastKey3); deseng.processBlock(mac, 0, mac, 0); // **** System.arraycopy(mac, 0, out, outOff, macSize); reset(); return macSize; } /** * Reset the mac generator. */ public void reset() { /* * clean the buffer. */ for (int i = 0; i < buf.length; i++) { buf[i] = 0; } bufOff = 0; /* * reset the underlying cipher. */ cipher.reset(); } } bouncycastle-1.49.orig/src/org/bouncycastle/crypto/macs/SipHash.java0000644000175000017500000001075512151551724025162 0ustar ebourgebourgpackage org.bouncycastle.crypto.macs; import org.bouncycastle.crypto.CipherParameters; import org.bouncycastle.crypto.DataLengthException; import org.bouncycastle.crypto.Mac; import org.bouncycastle.crypto.params.KeyParameter; import org.bouncycastle.crypto.util.Pack; import org.bouncycastle.util.Arrays; /** * Implementation of SipHash as specified in "SipHash: a fast short-input PRF", by Jean-Philippe * Aumasson and Daniel J. Bernstein (https://131002.net/siphash/siphash.pdf). *

    * "SipHash is a family of PRFs SipHash-c-d where the integer parameters c and d are the number of * compression rounds and the number of finalization rounds. A compression round is identical to a * finalization round and this round function is called SipRound. Given a 128-bit key k and a * (possibly empty) byte string m, SipHash-c-d returns a 64-bit value..." */ public class SipHash implements Mac { protected final int c, d; protected long k0, k1; protected long v0, v1, v2, v3, v4; protected byte[] buf = new byte[8]; protected int bufPos = 0; protected int wordCount = 0; /** * SipHash-2-4 */ public SipHash() { // use of this confuses flow analyser on earlier JDKs. this.c = 2; this.d = 4; } /** * SipHash-c-d * * @param c the number of compression rounds * @param d the number of finalization rounds */ public SipHash(int c, int d) { this.c = c; this.d = d; } public String getAlgorithmName() { return "SipHash-" + c + "-" + d; } public int getMacSize() { return 8; } public void init(CipherParameters params) throws IllegalArgumentException { if (!(params instanceof KeyParameter)) { throw new IllegalArgumentException("'params' must be an instance of KeyParameter"); } KeyParameter keyParameter = (KeyParameter)params; byte[] key = keyParameter.getKey(); if (key.length != 16) { throw new IllegalArgumentException("'params' must be a 128-bit key"); } this.k0 = Pack.littleEndianToLong(key, 0); this.k1 = Pack.littleEndianToLong(key, 8); reset(); } public void update(byte input) throws IllegalStateException { buf[bufPos] = input; if (++bufPos == buf.length) { processMessageWord(); bufPos = 0; } } public void update(byte[] input, int offset, int length) throws DataLengthException, IllegalStateException { for (int i = 0; i < length; ++i) { buf[bufPos] = input[offset + i]; if (++bufPos == buf.length) { processMessageWord(); bufPos = 0; } } } public long doFinal() throws DataLengthException, IllegalStateException { buf[7] = (byte)(((wordCount << 3) + bufPos) & 0xff); while (bufPos < 7) { buf[bufPos++] = 0; } processMessageWord(); v2 ^= 0xffL; applySipRounds(d); long result = v0 ^ v1 ^ v2 ^ v3; reset(); return result; } public int doFinal(byte[] out, int outOff) throws DataLengthException, IllegalStateException { long result = doFinal(); Pack.longToLittleEndian(result, out, outOff); return 8; } public void reset() { v0 = k0 ^ 0x736f6d6570736575L; v1 = k1 ^ 0x646f72616e646f6dL; v2 = k0 ^ 0x6c7967656e657261L; v3 = k1 ^ 0x7465646279746573L; Arrays.fill(buf, (byte)0); bufPos = 0; wordCount = 0; } protected void processMessageWord() { ++wordCount; long m = Pack.littleEndianToLong(buf, 0); v3 ^= m; applySipRounds(c); v0 ^= m; } protected void applySipRounds(int n) { for (int r = 0; r < n; ++r) { v0 += v1; v2 += v3; v1 = rotateLeft(v1, 13); v3 = rotateLeft(v3, 16); v1 ^= v0; v3 ^= v2; v0 = rotateLeft(v0, 32); v2 += v1; v0 += v3; v1 = rotateLeft(v1, 17); v3 = rotateLeft(v3, 21); v1 ^= v2; v3 ^= v0; v2 = rotateLeft(v2, 32); } } protected static long rotateLeft(long x, int n) { return (x << n) | (x >>> (64 - n)); } } bouncycastle-1.49.orig/src/org/bouncycastle/crypto/macs/OldHMac.java0000644000175000017500000000564610262753175025102 0ustar ebourgebourgpackage org.bouncycastle.crypto.macs; import org.bouncycastle.crypto.CipherParameters; import org.bouncycastle.crypto.Digest; import org.bouncycastle.crypto.Mac; import org.bouncycastle.crypto.params.KeyParameter; /** * HMAC implementation based on RFC2104 * * H(K XOR opad, H(K XOR ipad, text)) */ public class OldHMac implements Mac { private final static int BLOCK_LENGTH = 64; private final static byte IPAD = (byte)0x36; private final static byte OPAD = (byte)0x5C; private Digest digest; private int digestSize; private byte[] inputPad = new byte[BLOCK_LENGTH]; private byte[] outputPad = new byte[BLOCK_LENGTH]; /** * @deprecated uses incorrect pad for SHA-512 and SHA-384 use HMac. */ public OldHMac( Digest digest) { this.digest = digest; digestSize = digest.getDigestSize(); } public String getAlgorithmName() { return digest.getAlgorithmName() + "/HMAC"; } public Digest getUnderlyingDigest() { return digest; } public void init( CipherParameters params) { digest.reset(); byte[] key = ((KeyParameter)params).getKey(); if (key.length > BLOCK_LENGTH) { digest.update(key, 0, key.length); digest.doFinal(inputPad, 0); for (int i = digestSize; i < inputPad.length; i++) { inputPad[i] = 0; } } else { System.arraycopy(key, 0, inputPad, 0, key.length); for (int i = key.length; i < inputPad.length; i++) { inputPad[i] = 0; } } outputPad = new byte[inputPad.length]; System.arraycopy(inputPad, 0, outputPad, 0, inputPad.length); for (int i = 0; i < inputPad.length; i++) { inputPad[i] ^= IPAD; } for (int i = 0; i < outputPad.length; i++) { outputPad[i] ^= OPAD; } digest.update(inputPad, 0, inputPad.length); } public int getMacSize() { return digestSize; } public void update( byte in) { digest.update(in); } public void update( byte[] in, int inOff, int len) { digest.update(in, inOff, len); } public int doFinal( byte[] out, int outOff) { byte[] tmp = new byte[digestSize]; digest.doFinal(tmp, 0); digest.update(outputPad, 0, outputPad.length); digest.update(tmp, 0, tmp.length); int len = digest.doFinal(out, outOff); reset(); return len; } /** * Reset the mac generator. */ public void reset() { /* * reset the underlying digest. */ digest.reset(); /* * reinitialize the digest. */ digest.update(inputPad, 0, inputPad.length); } } bouncycastle-1.49.orig/src/org/bouncycastle/crypto/macs/CFBBlockCipherMac.java0000644000175000017500000002507310707366332026747 0ustar ebourgebourgpackage org.bouncycastle.crypto.macs; import org.bouncycastle.crypto.BlockCipher; import org.bouncycastle.crypto.CipherParameters; import org.bouncycastle.crypto.DataLengthException; import org.bouncycastle.crypto.Mac; import org.bouncycastle.crypto.paddings.BlockCipherPadding; import org.bouncycastle.crypto.params.ParametersWithIV; /** * implements a Cipher-FeedBack (CFB) mode on top of a simple cipher. */ class MacCFBBlockCipher { private byte[] IV; private byte[] cfbV; private byte[] cfbOutV; private int blockSize; private BlockCipher cipher = null; /** * Basic constructor. * * @param cipher the block cipher to be used as the basis of the * feedback mode. * @param blockSize the block size in bits (note: a multiple of 8) */ public MacCFBBlockCipher( BlockCipher cipher, int bitBlockSize) { this.cipher = cipher; this.blockSize = bitBlockSize / 8; this.IV = new byte[cipher.getBlockSize()]; this.cfbV = new byte[cipher.getBlockSize()]; this.cfbOutV = new byte[cipher.getBlockSize()]; } /** * Initialise the cipher and, possibly, the initialisation vector (IV). * If an IV isn't passed as part of the parameter, the IV will be all zeros. * An IV which is too short is handled in FIPS compliant fashion. * * @param param the key and other data required by the cipher. * @exception IllegalArgumentException if the params argument is * inappropriate. */ public void init( CipherParameters params) throws IllegalArgumentException { if (params instanceof ParametersWithIV) { ParametersWithIV ivParam = (ParametersWithIV)params; byte[] iv = ivParam.getIV(); if (iv.length < IV.length) { System.arraycopy(iv, 0, IV, IV.length - iv.length, iv.length); } else { System.arraycopy(iv, 0, IV, 0, IV.length); } reset(); cipher.init(true, ivParam.getParameters()); } else { reset(); cipher.init(true, params); } } /** * return the algorithm name and mode. * * @return the name of the underlying algorithm followed by "/CFB" * and the block size in bits. */ public String getAlgorithmName() { return cipher.getAlgorithmName() + "/CFB" + (blockSize * 8); } /** * return the block size we are operating at. * * @return the block size we are operating at (in bytes). */ public int getBlockSize() { return blockSize; } /** * Process one block of input from the array in and write it to * the out array. * * @param in the array containing the input data. * @param inOff offset into the in array the data starts at. * @param out the array the output data will be copied into. * @param outOff the offset into the out array the output will start at. * @exception DataLengthException if there isn't enough data in in, or * space in out. * @exception IllegalStateException if the cipher isn't initialised. * @return the number of bytes processed and produced. */ public int processBlock( byte[] in, int inOff, byte[] out, int outOff) throws DataLengthException, IllegalStateException { if ((inOff + blockSize) > in.length) { throw new DataLengthException("input buffer too short"); } if ((outOff + blockSize) > out.length) { throw new DataLengthException("output buffer too short"); } cipher.processBlock(cfbV, 0, cfbOutV, 0); // // XOR the cfbV with the plaintext producing the cipher text // for (int i = 0; i < blockSize; i++) { out[outOff + i] = (byte)(cfbOutV[i] ^ in[inOff + i]); } // // change over the input block. // System.arraycopy(cfbV, blockSize, cfbV, 0, cfbV.length - blockSize); System.arraycopy(out, outOff, cfbV, cfbV.length - blockSize, blockSize); return blockSize; } /** * reset the chaining vector back to the IV and reset the underlying * cipher. */ public void reset() { System.arraycopy(IV, 0, cfbV, 0, IV.length); cipher.reset(); } void getMacBlock( byte[] mac) { cipher.processBlock(cfbV, 0, mac, 0); } } public class CFBBlockCipherMac implements Mac { private byte[] mac; private byte[] buf; private int bufOff; private MacCFBBlockCipher cipher; private BlockCipherPadding padding = null; private int macSize; /** * create a standard MAC based on a CFB block cipher. This will produce an * authentication code half the length of the block size of the cipher, with * the CFB mode set to 8 bits. * * @param cipher the cipher to be used as the basis of the MAC generation. */ public CFBBlockCipherMac( BlockCipher cipher) { this(cipher, 8, (cipher.getBlockSize() * 8) / 2, null); } /** * create a standard MAC based on a CFB block cipher. This will produce an * authentication code half the length of the block size of the cipher, with * the CFB mode set to 8 bits. * * @param cipher the cipher to be used as the basis of the MAC generation. * @param padding the padding to be used. */ public CFBBlockCipherMac( BlockCipher cipher, BlockCipherPadding padding) { this(cipher, 8, (cipher.getBlockSize() * 8) / 2, padding); } /** * create a standard MAC based on a block cipher with the size of the * MAC been given in bits. This class uses CFB mode as the basis for the * MAC generation. *

    * Note: the size of the MAC must be at least 24 bits (FIPS Publication 81), * or 16 bits if being used as a data authenticator (FIPS Publication 113), * and in general should be less than the size of the block cipher as it reduces * the chance of an exhaustive attack (see Handbook of Applied Cryptography). * * @param cipher the cipher to be used as the basis of the MAC generation. * @param cfbBitSize the size of an output block produced by the CFB mode. * @param macSizeInBits the size of the MAC in bits, must be a multiple of 8. */ public CFBBlockCipherMac( BlockCipher cipher, int cfbBitSize, int macSizeInBits) { this(cipher, cfbBitSize, macSizeInBits, null); } /** * create a standard MAC based on a block cipher with the size of the * MAC been given in bits. This class uses CFB mode as the basis for the * MAC generation. *

    * Note: the size of the MAC must be at least 24 bits (FIPS Publication 81), * or 16 bits if being used as a data authenticator (FIPS Publication 113), * and in general should be less than the size of the block cipher as it reduces * the chance of an exhaustive attack (see Handbook of Applied Cryptography). * * @param cipher the cipher to be used as the basis of the MAC generation. * @param cfbBitSize the size of an output block produced by the CFB mode. * @param macSizeInBits the size of the MAC in bits, must be a multiple of 8. * @param padding a padding to be used. */ public CFBBlockCipherMac( BlockCipher cipher, int cfbBitSize, int macSizeInBits, BlockCipherPadding padding) { if ((macSizeInBits % 8) != 0) { throw new IllegalArgumentException("MAC size must be multiple of 8"); } mac = new byte[cipher.getBlockSize()]; this.cipher = new MacCFBBlockCipher(cipher, cfbBitSize); this.padding = padding; this.macSize = macSizeInBits / 8; buf = new byte[this.cipher.getBlockSize()]; bufOff = 0; } public String getAlgorithmName() { return cipher.getAlgorithmName(); } public void init( CipherParameters params) { reset(); cipher.init(params); } public int getMacSize() { return macSize; } public void update( byte in) { if (bufOff == buf.length) { cipher.processBlock(buf, 0, mac, 0); bufOff = 0; } buf[bufOff++] = in; } public void update( byte[] in, int inOff, int len) { if (len < 0) { throw new IllegalArgumentException("Can't have a negative input length!"); } int blockSize = cipher.getBlockSize(); int resultLen = 0; int gapLen = blockSize - bufOff; if (len > gapLen) { System.arraycopy(in, inOff, buf, bufOff, gapLen); resultLen += cipher.processBlock(buf, 0, mac, 0); bufOff = 0; len -= gapLen; inOff += gapLen; while (len > blockSize) { resultLen += cipher.processBlock(in, inOff, mac, 0); len -= blockSize; inOff += blockSize; } } System.arraycopy(in, inOff, buf, bufOff, len); bufOff += len; } public int doFinal( byte[] out, int outOff) { int blockSize = cipher.getBlockSize(); // // pad with zeroes // if (this.padding == null) { while (bufOff < blockSize) { buf[bufOff] = 0; bufOff++; } } else { padding.addPadding(buf, bufOff); } cipher.processBlock(buf, 0, mac, 0); cipher.getMacBlock(mac); System.arraycopy(mac, 0, out, outOff, macSize); reset(); return macSize; } /** * Reset the mac generator. */ public void reset() { /* * clean the buffer. */ for (int i = 0; i < buf.length; i++) { buf[i] = 0; } bufOff = 0; /* * reset the underlying cipher. */ cipher.reset(); } } bouncycastle-1.49.orig/src/org/bouncycastle/crypto/macs/GOST28147Mac.java0000644000175000017500000001766310327157111025426 0ustar ebourgebourgpackage org.bouncycastle.crypto.macs; import org.bouncycastle.crypto.CipherParameters; import org.bouncycastle.crypto.DataLengthException; import org.bouncycastle.crypto.Mac; import org.bouncycastle.crypto.params.KeyParameter; import org.bouncycastle.crypto.params.ParametersWithSBox; /** * implementation of GOST 28147-89 MAC */ public class GOST28147Mac implements Mac { private int blockSize = 8; private int macSize = 4; private int bufOff; private byte[] buf; private byte[] mac; private boolean firstStep = true; private int[] workingKey = null; // // This is default S-box - E_A. private byte S[] = { 0x9,0x6,0x3,0x2,0x8,0xB,0x1,0x7,0xA,0x4,0xE,0xF,0xC,0x0,0xD,0x5, 0x3,0x7,0xE,0x9,0x8,0xA,0xF,0x0,0x5,0x2,0x6,0xC,0xB,0x4,0xD,0x1, 0xE,0x4,0x6,0x2,0xB,0x3,0xD,0x8,0xC,0xF,0x5,0xA,0x0,0x7,0x1,0x9, 0xE,0x7,0xA,0xC,0xD,0x1,0x3,0x9,0x0,0x2,0xB,0x4,0xF,0x8,0x5,0x6, 0xB,0x5,0x1,0x9,0x8,0xD,0xF,0x0,0xE,0x4,0x2,0x3,0xC,0x7,0xA,0x6, 0x3,0xA,0xD,0xC,0x1,0x2,0x0,0xB,0x7,0x5,0x9,0x4,0x8,0xF,0xE,0x6, 0x1,0xD,0x2,0x9,0x7,0xA,0x6,0x0,0x8,0xC,0x4,0x5,0xF,0x3,0xB,0xE, 0xB,0xA,0xF,0x5,0x0,0xC,0xE,0x8,0x6,0x2,0x3,0x9,0x1,0x7,0xD,0x4 }; public GOST28147Mac() { mac = new byte[blockSize]; buf = new byte[blockSize]; bufOff = 0; } private int[] generateWorkingKey( byte[] userKey) { if (userKey.length != 32) { throw new IllegalArgumentException("Key length invalid. Key needs to be 32 byte - 256 bit!!!"); } int key[] = new int[8]; for(int i=0; i!=8; i++) { key[i] = bytesToint(userKey,i*4); } return key; } public void init( CipherParameters params) throws IllegalArgumentException { reset(); buf = new byte[blockSize]; if (params instanceof ParametersWithSBox) { ParametersWithSBox param = (ParametersWithSBox)params; // // Set the S-Box // System.arraycopy(param.getSBox(), 0, this.S, 0, param.getSBox().length); // // set key if there is one // if (param.getParameters() != null) { workingKey = generateWorkingKey(((KeyParameter)param.getParameters()).getKey()); } } else if (params instanceof KeyParameter) { workingKey = generateWorkingKey(((KeyParameter)params).getKey()); } else { throw new IllegalArgumentException("invalid parameter passed to GOST28147 init - " + params.getClass().getName()); } } public String getAlgorithmName() { return "GOST28147Mac"; } public int getMacSize() { return macSize; } private int gost28147_mainStep(int n1, int key) { int cm = (key + n1); // CM1 // S-box replacing int om = S[ 0 + ((cm >> (0 * 4)) & 0xF)] << (0 * 4); om += S[ 16 + ((cm >> (1 * 4)) & 0xF)] << (1 * 4); om += S[ 32 + ((cm >> (2 * 4)) & 0xF)] << (2 * 4); om += S[ 48 + ((cm >> (3 * 4)) & 0xF)] << (3 * 4); om += S[ 64 + ((cm >> (4 * 4)) & 0xF)] << (4 * 4); om += S[ 80 + ((cm >> (5 * 4)) & 0xF)] << (5 * 4); om += S[ 96 + ((cm >> (6 * 4)) & 0xF)] << (6 * 4); om += S[112 + ((cm >> (7 * 4)) & 0xF)] << (7 * 4); return om << 11 | om >>> (32-11); // 11-leftshift } private void gost28147MacFunc( int[] workingKey, byte[] in, int inOff, byte[] out, int outOff) { int N1, N2, tmp; //tmp -> for saving N1 N1 = bytesToint(in, inOff); N2 = bytesToint(in, inOff + 4); for(int k = 0; k < 2; k++) // 1-16 steps { for(int j = 0; j < 8; j++) { tmp = N1; N1 = N2 ^ gost28147_mainStep(N1, workingKey[j]); // CM2 N2 = tmp; } } intTobytes(N1, out, outOff); intTobytes(N2, out, outOff + 4); } //array of bytes to type int private int bytesToint( byte[] in, int inOff) { return ((in[inOff + 3] << 24) & 0xff000000) + ((in[inOff + 2] << 16) & 0xff0000) + ((in[inOff + 1] << 8) & 0xff00) + (in[inOff] & 0xff); } //int to array of bytes private void intTobytes( int num, byte[] out, int outOff) { out[outOff + 3] = (byte)(num >>> 24); out[outOff + 2] = (byte)(num >>> 16); out[outOff + 1] = (byte)(num >>> 8); out[outOff] = (byte)num; } private byte[] CM5func(byte[] buf, int bufOff, byte[] mac) { byte[] sum = new byte[buf.length - bufOff]; System.arraycopy(buf, bufOff, sum, 0, mac.length); for (int i = 0; i != mac.length; i++) { sum[i] = (byte)(sum[i] ^ mac[i]); } return sum; } public void update(byte in) throws IllegalStateException { if (bufOff == buf.length) { byte[] sumbuf = new byte[buf.length]; System.arraycopy(buf, 0, sumbuf, 0, mac.length); if (firstStep) { firstStep = false; } else { sumbuf = CM5func(buf, 0, mac); } gost28147MacFunc(workingKey, sumbuf, 0, mac, 0); bufOff = 0; } buf[bufOff++] = in; } public void update(byte[] in, int inOff, int len) throws DataLengthException, IllegalStateException { if (len < 0) { throw new IllegalArgumentException("Can't have a negative input length!"); } int gapLen = blockSize - bufOff; if (len > gapLen) { System.arraycopy(in, inOff, buf, bufOff, gapLen); byte[] sumbuf = new byte[buf.length]; System.arraycopy(buf, 0, sumbuf, 0, mac.length); if (firstStep) { firstStep = false; } else { sumbuf = CM5func(buf, 0, mac); } gost28147MacFunc(workingKey, sumbuf, 0, mac, 0); bufOff = 0; len -= gapLen; inOff += gapLen; while (len > blockSize) { sumbuf = CM5func(in, inOff, mac); gost28147MacFunc(workingKey, sumbuf, 0, mac, 0); len -= blockSize; inOff += blockSize; } } System.arraycopy(in, inOff, buf, bufOff, len); bufOff += len; } public int doFinal(byte[] out, int outOff) throws DataLengthException, IllegalStateException { //padding with zero while (bufOff < blockSize) { buf[bufOff] = 0; bufOff++; } byte[] sumbuf = new byte[buf.length]; System.arraycopy(buf, 0, sumbuf, 0, mac.length); if (firstStep) { firstStep = false; } else { sumbuf = CM5func(buf, 0, mac); } gost28147MacFunc(workingKey, sumbuf, 0, mac, 0); System.arraycopy(mac, (mac.length/2)-macSize, out, outOff, macSize); reset(); return macSize; } public void reset() { /* * clean the buffer. */ for (int i = 0; i < buf.length; i++) { buf[i] = 0; } bufOff = 0; firstStep = true; } } bouncycastle-1.49.orig/src/org/bouncycastle/crypto/macs/BlockCipherMac.java0000644000175000017500000000776010707366332026437 0ustar ebourgebourgpackage org.bouncycastle.crypto.macs; import org.bouncycastle.crypto.BlockCipher; import org.bouncycastle.crypto.CipherParameters; import org.bouncycastle.crypto.Mac; import org.bouncycastle.crypto.modes.CBCBlockCipher; public class BlockCipherMac implements Mac { private byte[] mac; private byte[] buf; private int bufOff; private BlockCipher cipher; private int macSize; /** * create a standard MAC based on a block cipher. This will produce an * authentication code half the length of the block size of the cipher. * * @param cipher the cipher to be used as the basis of the MAC generation. * @deprecated use CBCBlockCipherMac */ public BlockCipherMac( BlockCipher cipher) { this(cipher, (cipher.getBlockSize() * 8) / 2); } /** * create a standard MAC based on a block cipher with the size of the * MAC been given in bits. *

    * Note: the size of the MAC must be at least 16 bits (FIPS Publication 113), * and in general should be less than the size of the block cipher as it reduces * the chance of an exhaustive attack (see Handbook of Applied Cryptography). * * @param cipher the cipher to be used as the basis of the MAC generation. * @param macSizeInBits the size of the MAC in bits, must be a multiple of 8. * @deprecated use CBCBlockCipherMac */ public BlockCipherMac( BlockCipher cipher, int macSizeInBits) { if ((macSizeInBits % 8) != 0) { throw new IllegalArgumentException("MAC size must be multiple of 8"); } this.cipher = new CBCBlockCipher(cipher); this.macSize = macSizeInBits / 8; mac = new byte[cipher.getBlockSize()]; buf = new byte[cipher.getBlockSize()]; bufOff = 0; } public String getAlgorithmName() { return cipher.getAlgorithmName(); } public void init( CipherParameters params) { reset(); cipher.init(true, params); } public int getMacSize() { return macSize; } public void update( byte in) { if (bufOff == buf.length) { cipher.processBlock(buf, 0, mac, 0); bufOff = 0; } buf[bufOff++] = in; } public void update( byte[] in, int inOff, int len) { if (len < 0) { throw new IllegalArgumentException("Can't have a negative input length!"); } int blockSize = cipher.getBlockSize(); int resultLen = 0; int gapLen = blockSize - bufOff; if (len > gapLen) { System.arraycopy(in, inOff, buf, bufOff, gapLen); resultLen += cipher.processBlock(buf, 0, mac, 0); bufOff = 0; len -= gapLen; inOff += gapLen; while (len > blockSize) { resultLen += cipher.processBlock(in, inOff, mac, 0); len -= blockSize; inOff += blockSize; } } System.arraycopy(in, inOff, buf, bufOff, len); bufOff += len; } public int doFinal( byte[] out, int outOff) { int blockSize = cipher.getBlockSize(); // // pad with zeroes // while (bufOff < blockSize) { buf[bufOff] = 0; bufOff++; } cipher.processBlock(buf, 0, mac, 0); System.arraycopy(mac, 0, out, outOff, macSize); reset(); return macSize; } /** * Reset the mac generator. */ public void reset() { /* * clean the buffer. */ for (int i = 0; i < buf.length; i++) { buf[i] = 0; } bufOff = 0; /* * reset the underlying cipher. */ cipher.reset(); } } bouncycastle-1.49.orig/src/org/bouncycastle/crypto/macs/package.html0000644000175000017500000000012510262753175025234 0ustar ebourgebourg Classes for creating MACs and HMACs. bouncycastle-1.49.orig/src/org/bouncycastle/crypto/macs/HMac.java0000644000175000017500000001266112144044002024415 0ustar ebourgebourgpackage org.bouncycastle.crypto.macs; import java.util.Hashtable; import org.bouncycastle.crypto.CipherParameters; import org.bouncycastle.crypto.Digest; import org.bouncycastle.crypto.ExtendedDigest; import org.bouncycastle.crypto.Mac; import org.bouncycastle.crypto.params.KeyParameter; import org.bouncycastle.util.Integers; import org.bouncycastle.util.Memoable; /** * HMAC implementation based on RFC2104 * * H(K XOR opad, H(K XOR ipad, text)) */ public class HMac implements Mac { private final static byte IPAD = (byte)0x36; private final static byte OPAD = (byte)0x5C; private Digest digest; private int digestSize; private int blockLength; private Memoable ipadState; private Memoable opadState; private byte[] inputPad; private byte[] outputBuf; private static Hashtable blockLengths; static { blockLengths = new Hashtable(); blockLengths.put("GOST3411", Integers.valueOf(32)); blockLengths.put("MD2", Integers.valueOf(16)); blockLengths.put("MD4", Integers.valueOf(64)); blockLengths.put("MD5", Integers.valueOf(64)); blockLengths.put("RIPEMD128", Integers.valueOf(64)); blockLengths.put("RIPEMD160", Integers.valueOf(64)); blockLengths.put("SHA-1", Integers.valueOf(64)); blockLengths.put("SHA-224", Integers.valueOf(64)); blockLengths.put("SHA-256", Integers.valueOf(64)); blockLengths.put("SHA-384", Integers.valueOf(128)); blockLengths.put("SHA-512", Integers.valueOf(128)); blockLengths.put("Tiger", Integers.valueOf(64)); blockLengths.put("Whirlpool", Integers.valueOf(64)); } private static int getByteLength( Digest digest) { if (digest instanceof ExtendedDigest) { return ((ExtendedDigest)digest).getByteLength(); } Integer b = (Integer)blockLengths.get(digest.getAlgorithmName()); if (b == null) { throw new IllegalArgumentException("unknown digest passed: " + digest.getAlgorithmName()); } return b.intValue(); } /** * Base constructor for one of the standard digest algorithms that the * byteLength of the algorithm is know for. * * @param digest the digest. */ public HMac( Digest digest) { this(digest, getByteLength(digest)); } private HMac( Digest digest, int byteLength) { this.digest = digest; this.digestSize = digest.getDigestSize(); this.blockLength = byteLength; this.inputPad = new byte[blockLength]; this.outputBuf = new byte[blockLength + digestSize]; } public String getAlgorithmName() { return digest.getAlgorithmName() + "/HMAC"; } public Digest getUnderlyingDigest() { return digest; } public void init( CipherParameters params) { digest.reset(); byte[] key = ((KeyParameter)params).getKey(); int keyLength = key.length; if (keyLength > blockLength) { digest.update(key, 0, keyLength); digest.doFinal(inputPad, 0); keyLength = digestSize; } else { System.arraycopy(key, 0, inputPad, 0, keyLength); } for (int i = keyLength; i < inputPad.length; i++) { inputPad[i] = 0; } System.arraycopy(inputPad, 0, outputBuf, 0, blockLength); xorPad(inputPad, blockLength, IPAD); xorPad(outputBuf, blockLength, OPAD); if (digest instanceof Memoable) { opadState = ((Memoable)digest).copy(); ((Digest)opadState).update(outputBuf, 0, blockLength); } digest.update(inputPad, 0, inputPad.length); if (digest instanceof Memoable) { ipadState = ((Memoable)digest).copy(); } } public int getMacSize() { return digestSize; } public void update( byte in) { digest.update(in); } public void update( byte[] in, int inOff, int len) { digest.update(in, inOff, len); } public int doFinal( byte[] out, int outOff) { digest.doFinal(outputBuf, blockLength); if (opadState != null) { ((Memoable)digest).reset(opadState); digest.update(outputBuf, blockLength, digest.getDigestSize()); } else { digest.update(outputBuf, 0, outputBuf.length); } int len = digest.doFinal(out, outOff); for (int i = blockLength; i < outputBuf.length; i++) { outputBuf[i] = 0; } if (ipadState != null) { ((Memoable)digest).reset(ipadState); } else { digest.update(inputPad, 0, inputPad.length); } return len; } /** * Reset the mac generator. */ public void reset() { /* * reset the underlying digest. */ digest.reset(); /* * reinitialize the digest. */ digest.update(inputPad, 0, inputPad.length); } private static void xorPad(byte[] pad, int len, byte n) { for (int i = 0; i < len; ++i) { pad[i] ^= n; } } } bouncycastle-1.49.orig/src/org/bouncycastle/crypto/CipherParameters.java0000644000175000017500000000017110262753175026132 0ustar ebourgebourgpackage org.bouncycastle.crypto; /** * all parameter classes implement this. */ public interface CipherParameters { } bouncycastle-1.49.orig/src/org/bouncycastle/crypto/engines/0000755000175000017500000000000012152033551023447 5ustar ebourgebourgbouncycastle-1.49.orig/src/org/bouncycastle/crypto/engines/RC2Engine.java0000644000175000017500000002771512106331054026040 0ustar ebourgebourgpackage org.bouncycastle.crypto.engines; import org.bouncycastle.crypto.BlockCipher; import org.bouncycastle.crypto.CipherParameters; import org.bouncycastle.crypto.DataLengthException; import org.bouncycastle.crypto.OutputLengthException; import org.bouncycastle.crypto.params.KeyParameter; import org.bouncycastle.crypto.params.RC2Parameters; /** * an implementation of RC2 as described in RFC 2268 * "A Description of the RC2(r) Encryption Algorithm" R. Rivest. */ public class RC2Engine implements BlockCipher { // // the values we use for key expansion (based on the digits of PI) // private static byte[] piTable = { (byte)0xd9, (byte)0x78, (byte)0xf9, (byte)0xc4, (byte)0x19, (byte)0xdd, (byte)0xb5, (byte)0xed, (byte)0x28, (byte)0xe9, (byte)0xfd, (byte)0x79, (byte)0x4a, (byte)0xa0, (byte)0xd8, (byte)0x9d, (byte)0xc6, (byte)0x7e, (byte)0x37, (byte)0x83, (byte)0x2b, (byte)0x76, (byte)0x53, (byte)0x8e, (byte)0x62, (byte)0x4c, (byte)0x64, (byte)0x88, (byte)0x44, (byte)0x8b, (byte)0xfb, (byte)0xa2, (byte)0x17, (byte)0x9a, (byte)0x59, (byte)0xf5, (byte)0x87, (byte)0xb3, (byte)0x4f, (byte)0x13, (byte)0x61, (byte)0x45, (byte)0x6d, (byte)0x8d, (byte)0x9, (byte)0x81, (byte)0x7d, (byte)0x32, (byte)0xbd, (byte)0x8f, (byte)0x40, (byte)0xeb, (byte)0x86, (byte)0xb7, (byte)0x7b, (byte)0xb, (byte)0xf0, (byte)0x95, (byte)0x21, (byte)0x22, (byte)0x5c, (byte)0x6b, (byte)0x4e, (byte)0x82, (byte)0x54, (byte)0xd6, (byte)0x65, (byte)0x93, (byte)0xce, (byte)0x60, (byte)0xb2, (byte)0x1c, (byte)0x73, (byte)0x56, (byte)0xc0, (byte)0x14, (byte)0xa7, (byte)0x8c, (byte)0xf1, (byte)0xdc, (byte)0x12, (byte)0x75, (byte)0xca, (byte)0x1f, (byte)0x3b, (byte)0xbe, (byte)0xe4, (byte)0xd1, (byte)0x42, (byte)0x3d, (byte)0xd4, (byte)0x30, (byte)0xa3, (byte)0x3c, (byte)0xb6, (byte)0x26, (byte)0x6f, (byte)0xbf, (byte)0xe, (byte)0xda, (byte)0x46, (byte)0x69, (byte)0x7, (byte)0x57, (byte)0x27, (byte)0xf2, (byte)0x1d, (byte)0x9b, (byte)0xbc, (byte)0x94, (byte)0x43, (byte)0x3, (byte)0xf8, (byte)0x11, (byte)0xc7, (byte)0xf6, (byte)0x90, (byte)0xef, (byte)0x3e, (byte)0xe7, (byte)0x6, (byte)0xc3, (byte)0xd5, (byte)0x2f, (byte)0xc8, (byte)0x66, (byte)0x1e, (byte)0xd7, (byte)0x8, (byte)0xe8, (byte)0xea, (byte)0xde, (byte)0x80, (byte)0x52, (byte)0xee, (byte)0xf7, (byte)0x84, (byte)0xaa, (byte)0x72, (byte)0xac, (byte)0x35, (byte)0x4d, (byte)0x6a, (byte)0x2a, (byte)0x96, (byte)0x1a, (byte)0xd2, (byte)0x71, (byte)0x5a, (byte)0x15, (byte)0x49, (byte)0x74, (byte)0x4b, (byte)0x9f, (byte)0xd0, (byte)0x5e, (byte)0x4, (byte)0x18, (byte)0xa4, (byte)0xec, (byte)0xc2, (byte)0xe0, (byte)0x41, (byte)0x6e, (byte)0xf, (byte)0x51, (byte)0xcb, (byte)0xcc, (byte)0x24, (byte)0x91, (byte)0xaf, (byte)0x50, (byte)0xa1, (byte)0xf4, (byte)0x70, (byte)0x39, (byte)0x99, (byte)0x7c, (byte)0x3a, (byte)0x85, (byte)0x23, (byte)0xb8, (byte)0xb4, (byte)0x7a, (byte)0xfc, (byte)0x2, (byte)0x36, (byte)0x5b, (byte)0x25, (byte)0x55, (byte)0x97, (byte)0x31, (byte)0x2d, (byte)0x5d, (byte)0xfa, (byte)0x98, (byte)0xe3, (byte)0x8a, (byte)0x92, (byte)0xae, (byte)0x5, (byte)0xdf, (byte)0x29, (byte)0x10, (byte)0x67, (byte)0x6c, (byte)0xba, (byte)0xc9, (byte)0xd3, (byte)0x0, (byte)0xe6, (byte)0xcf, (byte)0xe1, (byte)0x9e, (byte)0xa8, (byte)0x2c, (byte)0x63, (byte)0x16, (byte)0x1, (byte)0x3f, (byte)0x58, (byte)0xe2, (byte)0x89, (byte)0xa9, (byte)0xd, (byte)0x38, (byte)0x34, (byte)0x1b, (byte)0xab, (byte)0x33, (byte)0xff, (byte)0xb0, (byte)0xbb, (byte)0x48, (byte)0xc, (byte)0x5f, (byte)0xb9, (byte)0xb1, (byte)0xcd, (byte)0x2e, (byte)0xc5, (byte)0xf3, (byte)0xdb, (byte)0x47, (byte)0xe5, (byte)0xa5, (byte)0x9c, (byte)0x77, (byte)0xa, (byte)0xa6, (byte)0x20, (byte)0x68, (byte)0xfe, (byte)0x7f, (byte)0xc1, (byte)0xad }; private static final int BLOCK_SIZE = 8; private int[] workingKey; private boolean encrypting; private int[] generateWorkingKey( byte[] key, int bits) { int x; int[] xKey = new int[128]; for (int i = 0; i != key.length; i++) { xKey[i] = key[i] & 0xff; } // Phase 1: Expand input key to 128 bytes int len = key.length; if (len < 128) { int index = 0; x = xKey[len - 1]; do { x = piTable[(x + xKey[index++]) & 255] & 0xff; xKey[len++] = x; } while (len < 128); } // Phase 2 - reduce effective key size to "bits" len = (bits + 7) >> 3; x = piTable[xKey[128 - len] & (255 >> (7 & -bits))] & 0xff; xKey[128 - len] = x; for (int i = 128 - len - 1; i >= 0; i--) { x = piTable[x ^ xKey[i + len]] & 0xff; xKey[i] = x; } // Phase 3 - copy to newKey in little-endian order int[] newKey = new int[64]; for (int i = 0; i != newKey.length; i++) { newKey[i] = (xKey[2 * i] + (xKey[2 * i + 1] << 8)); } return newKey; } /** * initialise a RC2 cipher. * * @param encrypting whether or not we are for encryption. * @param params the parameters required to set up the cipher. * @exception IllegalArgumentException if the params argument is * inappropriate. */ public void init( boolean encrypting, CipherParameters params) { this.encrypting = encrypting; if (params instanceof RC2Parameters) { RC2Parameters param = (RC2Parameters)params; workingKey = generateWorkingKey(param.getKey(), param.getEffectiveKeyBits()); } else if (params instanceof KeyParameter) { byte[] key = ((KeyParameter)params).getKey(); workingKey = generateWorkingKey(key, key.length * 8); } else { throw new IllegalArgumentException("invalid parameter passed to RC2 init - " + params.getClass().getName()); } } public void reset() { } public String getAlgorithmName() { return "RC2"; } public int getBlockSize() { return BLOCK_SIZE; } public final int processBlock( byte[] in, int inOff, byte[] out, int outOff) { if (workingKey == null) { throw new IllegalStateException("RC2 engine not initialised"); } if ((inOff + BLOCK_SIZE) > in.length) { throw new DataLengthException("input buffer too short"); } if ((outOff + BLOCK_SIZE) > out.length) { throw new OutputLengthException("output buffer too short"); } if (encrypting) { encryptBlock(in, inOff, out, outOff); } else { decryptBlock(in, inOff, out, outOff); } return BLOCK_SIZE; } /** * return the result rotating the 16 bit number in x left by y */ private int rotateWordLeft( int x, int y) { x &= 0xffff; return (x << y) | (x >> (16 - y)); } private void encryptBlock( byte[] in, int inOff, byte[] out, int outOff) { int x76, x54, x32, x10; x76 = ((in[inOff + 7] & 0xff) << 8) + (in[inOff + 6] & 0xff); x54 = ((in[inOff + 5] & 0xff) << 8) + (in[inOff + 4] & 0xff); x32 = ((in[inOff + 3] & 0xff) << 8) + (in[inOff + 2] & 0xff); x10 = ((in[inOff + 1] & 0xff) << 8) + (in[inOff + 0] & 0xff); for (int i = 0; i <= 16; i += 4) { x10 = rotateWordLeft(x10 + (x32 & ~x76) + (x54 & x76) + workingKey[i ], 1); x32 = rotateWordLeft(x32 + (x54 & ~x10) + (x76 & x10) + workingKey[i+1], 2); x54 = rotateWordLeft(x54 + (x76 & ~x32) + (x10 & x32) + workingKey[i+2], 3); x76 = rotateWordLeft(x76 + (x10 & ~x54) + (x32 & x54) + workingKey[i+3], 5); } x10 += workingKey[x76 & 63]; x32 += workingKey[x10 & 63]; x54 += workingKey[x32 & 63]; x76 += workingKey[x54 & 63]; for (int i = 20; i <= 40; i += 4) { x10 = rotateWordLeft(x10 + (x32 & ~x76) + (x54 & x76) + workingKey[i ], 1); x32 = rotateWordLeft(x32 + (x54 & ~x10) + (x76 & x10) + workingKey[i+1], 2); x54 = rotateWordLeft(x54 + (x76 & ~x32) + (x10 & x32) + workingKey[i+2], 3); x76 = rotateWordLeft(x76 + (x10 & ~x54) + (x32 & x54) + workingKey[i+3], 5); } x10 += workingKey[x76 & 63]; x32 += workingKey[x10 & 63]; x54 += workingKey[x32 & 63]; x76 += workingKey[x54 & 63]; for (int i = 44; i < 64; i += 4) { x10 = rotateWordLeft(x10 + (x32 & ~x76) + (x54 & x76) + workingKey[i ], 1); x32 = rotateWordLeft(x32 + (x54 & ~x10) + (x76 & x10) + workingKey[i+1], 2); x54 = rotateWordLeft(x54 + (x76 & ~x32) + (x10 & x32) + workingKey[i+2], 3); x76 = rotateWordLeft(x76 + (x10 & ~x54) + (x32 & x54) + workingKey[i+3], 5); } out[outOff + 0] = (byte)x10; out[outOff + 1] = (byte)(x10 >> 8); out[outOff + 2] = (byte)x32; out[outOff + 3] = (byte)(x32 >> 8); out[outOff + 4] = (byte)x54; out[outOff + 5] = (byte)(x54 >> 8); out[outOff + 6] = (byte)x76; out[outOff + 7] = (byte)(x76 >> 8); } private void decryptBlock( byte[] in, int inOff, byte[] out, int outOff) { int x76, x54, x32, x10; x76 = ((in[inOff + 7] & 0xff) << 8) + (in[inOff + 6] & 0xff); x54 = ((in[inOff + 5] & 0xff) << 8) + (in[inOff + 4] & 0xff); x32 = ((in[inOff + 3] & 0xff) << 8) + (in[inOff + 2] & 0xff); x10 = ((in[inOff + 1] & 0xff) << 8) + (in[inOff + 0] & 0xff); for (int i = 60; i >= 44; i -= 4) { x76 = rotateWordLeft(x76, 11) - ((x10 & ~x54) + (x32 & x54) + workingKey[i+3]); x54 = rotateWordLeft(x54, 13) - ((x76 & ~x32) + (x10 & x32) + workingKey[i+2]); x32 = rotateWordLeft(x32, 14) - ((x54 & ~x10) + (x76 & x10) + workingKey[i+1]); x10 = rotateWordLeft(x10, 15) - ((x32 & ~x76) + (x54 & x76) + workingKey[i ]); } x76 -= workingKey[x54 & 63]; x54 -= workingKey[x32 & 63]; x32 -= workingKey[x10 & 63]; x10 -= workingKey[x76 & 63]; for (int i = 40; i >= 20; i -= 4) { x76 = rotateWordLeft(x76, 11) - ((x10 & ~x54) + (x32 & x54) + workingKey[i+3]); x54 = rotateWordLeft(x54, 13) - ((x76 & ~x32) + (x10 & x32) + workingKey[i+2]); x32 = rotateWordLeft(x32, 14) - ((x54 & ~x10) + (x76 & x10) + workingKey[i+1]); x10 = rotateWordLeft(x10, 15) - ((x32 & ~x76) + (x54 & x76) + workingKey[i ]); } x76 -= workingKey[x54 & 63]; x54 -= workingKey[x32 & 63]; x32 -= workingKey[x10 & 63]; x10 -= workingKey[x76 & 63]; for (int i = 16; i >= 0; i -= 4) { x76 = rotateWordLeft(x76, 11) - ((x10 & ~x54) + (x32 & x54) + workingKey[i+3]); x54 = rotateWordLeft(x54, 13) - ((x76 & ~x32) + (x10 & x32) + workingKey[i+2]); x32 = rotateWordLeft(x32, 14) - ((x54 & ~x10) + (x76 & x10) + workingKey[i+1]); x10 = rotateWordLeft(x10, 15) - ((x32 & ~x76) + (x54 & x76) + workingKey[i ]); } out[outOff + 0] = (byte)x10; out[outOff + 1] = (byte)(x10 >> 8); out[outOff + 2] = (byte)x32; out[outOff + 3] = (byte)(x32 >> 8); out[outOff + 4] = (byte)x54; out[outOff + 5] = (byte)(x54 >> 8); out[outOff + 6] = (byte)x76; out[outOff + 7] = (byte)(x76 >> 8); } } bouncycastle-1.49.orig/src/org/bouncycastle/crypto/engines/DESedeEngine.java0000644000175000017500000000646412143600004026534 0ustar ebourgebourgpackage org.bouncycastle.crypto.engines; import org.bouncycastle.crypto.CipherParameters; import org.bouncycastle.crypto.DataLengthException; import org.bouncycastle.crypto.OutputLengthException; import org.bouncycastle.crypto.params.KeyParameter; /** * a class that provides a basic DESede (or Triple DES) engine. */ public class DESedeEngine extends DESEngine { protected static final int BLOCK_SIZE = 8; private int[] workingKey1 = null; private int[] workingKey2 = null; private int[] workingKey3 = null; private boolean forEncryption; /** * standard constructor. */ public DESedeEngine() { } /** * initialise a DESede cipher. * * @param encrypting whether or not we are for encryption. * @param params the parameters required to set up the cipher. * @exception IllegalArgumentException if the params argument is * inappropriate. */ public void init( boolean encrypting, CipherParameters params) { if (!(params instanceof KeyParameter)) { throw new IllegalArgumentException("invalid parameter passed to DESede init - " + params.getClass().getName()); } byte[] keyMaster = ((KeyParameter)params).getKey(); if (keyMaster.length != 24 && keyMaster.length != 16) { throw new IllegalArgumentException("key size must be 16 or 24 bytes."); } this.forEncryption = encrypting; byte[] key1 = new byte[8]; System.arraycopy(keyMaster, 0, key1, 0, key1.length); workingKey1 = generateWorkingKey(encrypting, key1); byte[] key2 = new byte[8]; System.arraycopy(keyMaster, 8, key2, 0, key2.length); workingKey2 = generateWorkingKey(!encrypting, key2); if (keyMaster.length == 24) { byte[] key3 = new byte[8]; System.arraycopy(keyMaster, 16, key3, 0, key3.length); workingKey3 = generateWorkingKey(encrypting, key3); } else // 16 byte key { workingKey3 = workingKey1; } } public String getAlgorithmName() { return "DESede"; } public int getBlockSize() { return BLOCK_SIZE; } public int processBlock( byte[] in, int inOff, byte[] out, int outOff) { if (workingKey1 == null) { throw new IllegalStateException("DESede engine not initialised"); } if ((inOff + BLOCK_SIZE) > in.length) { throw new DataLengthException("input buffer too short"); } if ((outOff + BLOCK_SIZE) > out.length) { throw new OutputLengthException("output buffer too short"); } byte[] temp = new byte[BLOCK_SIZE]; if (forEncryption) { desFunc(workingKey1, in, inOff, temp, 0); desFunc(workingKey2, temp, 0, temp, 0); desFunc(workingKey3, temp, 0, out, outOff); } else { desFunc(workingKey3, in, inOff, temp, 0); desFunc(workingKey2, temp, 0, temp, 0); desFunc(workingKey1, temp, 0, out, outOff); } return BLOCK_SIZE; } public void reset() { } } bouncycastle-1.49.orig/src/org/bouncycastle/crypto/engines/VMPCKSA3Engine.java0000644000175000017500000000213610676460254026646 0ustar ebourgebourgpackage org.bouncycastle.crypto.engines; public class VMPCKSA3Engine extends VMPCEngine { public String getAlgorithmName() { return "VMPC-KSA3"; } protected void initKey(byte[] keyBytes, byte[] ivBytes) { s = 0; P = new byte[256]; for (int i = 0; i < 256; i++) { P[i] = (byte) i; } for (int m = 0; m < 768; m++) { s = P[(s + P[m & 0xff] + keyBytes[m % keyBytes.length]) & 0xff]; byte temp = P[m & 0xff]; P[m & 0xff] = P[s & 0xff]; P[s & 0xff] = temp; } for (int m = 0; m < 768; m++) { s = P[(s + P[m & 0xff] + ivBytes[m % ivBytes.length]) & 0xff]; byte temp = P[m & 0xff]; P[m & 0xff] = P[s & 0xff]; P[s & 0xff] = temp; } for (int m = 0; m < 768; m++) { s = P[(s + P[m & 0xff] + keyBytes[m % keyBytes.length]) & 0xff]; byte temp = P[m & 0xff]; P[m & 0xff] = P[s & 0xff]; P[s & 0xff] = temp; } n = 0; } } bouncycastle-1.49.orig/src/org/bouncycastle/crypto/engines/RC532Engine.java0000644000175000017500000001730210324400066026177 0ustar ebourgebourgpackage org.bouncycastle.crypto.engines; import org.bouncycastle.crypto.BlockCipher; import org.bouncycastle.crypto.CipherParameters; import org.bouncycastle.crypto.params.KeyParameter; import org.bouncycastle.crypto.params.RC5Parameters; /** * The specification for RC5 came from the RC5 Encryption Algorithm * publication in RSA CryptoBytes, Spring of 1995. * http://www.rsasecurity.com/rsalabs/cryptobytes. *

    * This implementation has a word size of 32 bits. *

    * Implementation courtesy of Tito Pena. */ public class RC532Engine implements BlockCipher { /* * the number of rounds to perform */ private int _noRounds; /* * the expanded key array of size 2*(rounds + 1) */ private int _S[]; /* * our "magic constants" for 32 32 * * Pw = Odd((e-2) * 2^wordsize) * Qw = Odd((o-2) * 2^wordsize) * * where e is the base of natural logarithms (2.718281828...) * and o is the golden ratio (1.61803398...) */ private static final int P32 = 0xb7e15163; private static final int Q32 = 0x9e3779b9; private boolean forEncryption; /** * Create an instance of the RC5 encryption algorithm * and set some defaults */ public RC532Engine() { _noRounds = 12; // the default _S = null; } public String getAlgorithmName() { return "RC5-32"; } public int getBlockSize() { return 2 * 4; } /** * initialise a RC5-32 cipher. * * @param forEncryption whether or not we are for encryption. * @param params the parameters required to set up the cipher. * @exception IllegalArgumentException if the params argument is * inappropriate. */ public void init( boolean forEncryption, CipherParameters params) { if (params instanceof RC5Parameters) { RC5Parameters p = (RC5Parameters)params; _noRounds = p.getRounds(); setKey(p.getKey()); } else if (params instanceof KeyParameter) { KeyParameter p = (KeyParameter)params; setKey(p.getKey()); } else { throw new IllegalArgumentException("invalid parameter passed to RC532 init - " + params.getClass().getName()); } this.forEncryption = forEncryption; } public int processBlock( byte[] in, int inOff, byte[] out, int outOff) { return (forEncryption) ? encryptBlock(in, inOff, out, outOff) : decryptBlock(in, inOff, out, outOff); } public void reset() { } /** * Re-key the cipher. *

    * @param key the key to be used */ private void setKey( byte[] key) { // // KEY EXPANSION: // // There are 3 phases to the key expansion. // // Phase 1: // Copy the secret key K[0...b-1] into an array L[0..c-1] of // c = ceil(b/u), where u = 32/8 in little-endian order. // In other words, we fill up L using u consecutive key bytes // of K. Any unfilled byte positions in L are zeroed. In the // case that b = c = 0, set c = 1 and L[0] = 0. // int[] L = new int[(key.length + (4 - 1)) / 4]; for (int i = 0; i != key.length; i++) { L[i / 4] += (key[i] & 0xff) << (8 * (i % 4)); } // // Phase 2: // Initialize S to a particular fixed pseudo-random bit pattern // using an arithmetic progression modulo 2^wordsize determined // by the magic numbers, Pw & Qw. // _S = new int[2*(_noRounds + 1)]; _S[0] = P32; for (int i=1; i < _S.length; i++) { _S[i] = (_S[i-1] + Q32); } // // Phase 3: // Mix in the user's secret key in 3 passes over the arrays S & L. // The max of the arrays sizes is used as the loop control // int iter; if (L.length > _S.length) { iter = 3 * L.length; } else { iter = 3 * _S.length; } int A = 0, B = 0; int i = 0, j = 0; for (int k = 0; k < iter; k++) { A = _S[i] = rotateLeft(_S[i] + A + B, 3); B = L[j] = rotateLeft(L[j] + A + B, A+B); i = (i+1) % _S.length; j = (j+1) % L.length; } } /** * Encrypt the given block starting at the given offset and place * the result in the provided buffer starting at the given offset. *

    * @param in in byte buffer containing data to encrypt * @param inOff offset into src buffer * @param out out buffer where encrypted data is written * @param outOff offset into out buffer */ private int encryptBlock( byte[] in, int inOff, byte[] out, int outOff) { int A = bytesToWord(in, inOff) + _S[0]; int B = bytesToWord(in, inOff + 4) + _S[1]; for (int i = 1; i <= _noRounds; i++) { A = rotateLeft(A ^ B, B) + _S[2*i]; B = rotateLeft(B ^ A, A) + _S[2*i+1]; } wordToBytes(A, out, outOff); wordToBytes(B, out, outOff + 4); return 2 * 4; } private int decryptBlock( byte[] in, int inOff, byte[] out, int outOff) { int A = bytesToWord(in, inOff); int B = bytesToWord(in, inOff + 4); for (int i = _noRounds; i >= 1; i--) { B = rotateRight(B - _S[2*i+1], A) ^ A; A = rotateRight(A - _S[2*i], B) ^ B; } wordToBytes(A - _S[0], out, outOff); wordToBytes(B - _S[1], out, outOff + 4); return 2 * 4; } ////////////////////////////////////////////////////////////// // // PRIVATE Helper Methods // ////////////////////////////////////////////////////////////// /** * Perform a left "spin" of the word. The rotation of the given * word x is rotated left by y bits. * Only the lg(32) low-order bits of y * are used to determine the rotation amount. Here it is * assumed that the wordsize used is a power of 2. *

    * @param x word to rotate * @param y number of bits to rotate % 32 */ private int rotateLeft(int x, int y) { return ((x << (y & (32-1))) | (x >>> (32 - (y & (32-1))))); } /** * Perform a right "spin" of the word. The rotation of the given * word x is rotated left by y bits. * Only the lg(32) low-order bits of y * are used to determine the rotation amount. Here it is * assumed that the wordsize used is a power of 2. *

    * @param x word to rotate * @param y number of bits to rotate % 32 */ private int rotateRight(int x, int y) { return ((x >>> (y & (32-1))) | (x << (32 - (y & (32-1))))); } private int bytesToWord( byte[] src, int srcOff) { return (src[srcOff] & 0xff) | ((src[srcOff + 1] & 0xff) << 8) | ((src[srcOff + 2] & 0xff) << 16) | ((src[srcOff + 3] & 0xff) << 24); } private void wordToBytes( int word, byte[] dst, int dstOff) { dst[dstOff] = (byte)word; dst[dstOff + 1] = (byte)(word >> 8); dst[dstOff + 2] = (byte)(word >> 16); dst[dstOff + 3] = (byte)(word >> 24); } } bouncycastle-1.49.orig/src/org/bouncycastle/crypto/engines/RC564Engine.java0000644000175000017500000001740610324400066026211 0ustar ebourgebourgpackage org.bouncycastle.crypto.engines; import org.bouncycastle.crypto.BlockCipher; import org.bouncycastle.crypto.CipherParameters; import org.bouncycastle.crypto.params.RC5Parameters; /** * The specification for RC5 came from the RC5 Encryption Algorithm * publication in RSA CryptoBytes, Spring of 1995. * http://www.rsasecurity.com/rsalabs/cryptobytes. *

    * This implementation is set to work with a 64 bit word size. *

    * Implementation courtesy of Tito Pena. */ public class RC564Engine implements BlockCipher { private static final int wordSize = 64; private static final int bytesPerWord = wordSize / 8; /* * the number of rounds to perform */ private int _noRounds; /* * the expanded key array of size 2*(rounds + 1) */ private long _S[]; /* * our "magic constants" for wordSize 62 * * Pw = Odd((e-2) * 2^wordsize) * Qw = Odd((o-2) * 2^wordsize) * * where e is the base of natural logarithms (2.718281828...) * and o is the golden ratio (1.61803398...) */ private static final long P64 = 0xb7e151628aed2a6bL; private static final long Q64 = 0x9e3779b97f4a7c15L; private boolean forEncryption; /** * Create an instance of the RC5 encryption algorithm * and set some defaults */ public RC564Engine() { _noRounds = 12; _S = null; } public String getAlgorithmName() { return "RC5-64"; } public int getBlockSize() { return 2 * bytesPerWord; } /** * initialise a RC5-64 cipher. * * @param forEncryption whether or not we are for encryption. * @param params the parameters required to set up the cipher. * @exception IllegalArgumentException if the params argument is * inappropriate. */ public void init( boolean forEncryption, CipherParameters params) { if (!(params instanceof RC5Parameters)) { throw new IllegalArgumentException("invalid parameter passed to RC564 init - " + params.getClass().getName()); } RC5Parameters p = (RC5Parameters)params; this.forEncryption = forEncryption; _noRounds = p.getRounds(); setKey(p.getKey()); } public int processBlock( byte[] in, int inOff, byte[] out, int outOff) { return (forEncryption) ? encryptBlock(in, inOff, out, outOff) : decryptBlock(in, inOff, out, outOff); } public void reset() { } /** * Re-key the cipher. *

    * @param key the key to be used */ private void setKey( byte[] key) { // // KEY EXPANSION: // // There are 3 phases to the key expansion. // // Phase 1: // Copy the secret key K[0...b-1] into an array L[0..c-1] of // c = ceil(b/u), where u = wordSize/8 in little-endian order. // In other words, we fill up L using u consecutive key bytes // of K. Any unfilled byte positions in L are zeroed. In the // case that b = c = 0, set c = 1 and L[0] = 0. // long[] L = new long[(key.length + (bytesPerWord - 1)) / bytesPerWord]; for (int i = 0; i != key.length; i++) { L[i / bytesPerWord] += (long)(key[i] & 0xff) << (8 * (i % bytesPerWord)); } // // Phase 2: // Initialize S to a particular fixed pseudo-random bit pattern // using an arithmetic progression modulo 2^wordsize determined // by the magic numbers, Pw & Qw. // _S = new long[2*(_noRounds + 1)]; _S[0] = P64; for (int i=1; i < _S.length; i++) { _S[i] = (_S[i-1] + Q64); } // // Phase 3: // Mix in the user's secret key in 3 passes over the arrays S & L. // The max of the arrays sizes is used as the loop control // int iter; if (L.length > _S.length) { iter = 3 * L.length; } else { iter = 3 * _S.length; } long A = 0, B = 0; int i = 0, j = 0; for (int k = 0; k < iter; k++) { A = _S[i] = rotateLeft(_S[i] + A + B, 3); B = L[j] = rotateLeft(L[j] + A + B, A+B); i = (i+1) % _S.length; j = (j+1) % L.length; } } /** * Encrypt the given block starting at the given offset and place * the result in the provided buffer starting at the given offset. *

    * @param in in byte buffer containing data to encrypt * @param inOff offset into src buffer * @param out out buffer where encrypted data is written * @param outOff offset into out buffer */ private int encryptBlock( byte[] in, int inOff, byte[] out, int outOff) { long A = bytesToWord(in, inOff) + _S[0]; long B = bytesToWord(in, inOff + bytesPerWord) + _S[1]; for (int i = 1; i <= _noRounds; i++) { A = rotateLeft(A ^ B, B) + _S[2*i]; B = rotateLeft(B ^ A, A) + _S[2*i+1]; } wordToBytes(A, out, outOff); wordToBytes(B, out, outOff + bytesPerWord); return 2 * bytesPerWord; } private int decryptBlock( byte[] in, int inOff, byte[] out, int outOff) { long A = bytesToWord(in, inOff); long B = bytesToWord(in, inOff + bytesPerWord); for (int i = _noRounds; i >= 1; i--) { B = rotateRight(B - _S[2*i+1], A) ^ A; A = rotateRight(A - _S[2*i], B) ^ B; } wordToBytes(A - _S[0], out, outOff); wordToBytes(B - _S[1], out, outOff + bytesPerWord); return 2 * bytesPerWord; } ////////////////////////////////////////////////////////////// // // PRIVATE Helper Methods // ////////////////////////////////////////////////////////////// /** * Perform a left "spin" of the word. The rotation of the given * word x is rotated left by y bits. * Only the lg(wordSize) low-order bits of y * are used to determine the rotation amount. Here it is * assumed that the wordsize used is a power of 2. *

    * @param x word to rotate * @param y number of bits to rotate % wordSize */ private long rotateLeft(long x, long y) { return ((x << (y & (wordSize-1))) | (x >>> (wordSize - (y & (wordSize-1))))); } /** * Perform a right "spin" of the word. The rotation of the given * word x is rotated left by y bits. * Only the lg(wordSize) low-order bits of y * are used to determine the rotation amount. Here it is * assumed that the wordsize used is a power of 2. *

    * @param x word to rotate * @param y number of bits to rotate % wordSize */ private long rotateRight(long x, long y) { return ((x >>> (y & (wordSize-1))) | (x << (wordSize - (y & (wordSize-1))))); } private long bytesToWord( byte[] src, int srcOff) { long word = 0; for (int i = bytesPerWord - 1; i >= 0; i--) { word = (word << 8) + (src[i + srcOff] & 0xff); } return word; } private void wordToBytes( long word, byte[] dst, int dstOff) { for (int i = 0; i < bytesPerWord; i++) { dst[i + dstOff] = (byte)word; word >>>= 8; } } } bouncycastle-1.49.orig/src/org/bouncycastle/crypto/engines/RSAEngine.java0000644000175000017500000000420710525330722026072 0ustar ebourgebourgpackage org.bouncycastle.crypto.engines; import org.bouncycastle.crypto.AsymmetricBlockCipher; import org.bouncycastle.crypto.CipherParameters; import org.bouncycastle.crypto.DataLengthException; /** * this does your basic RSA algorithm. */ public class RSAEngine implements AsymmetricBlockCipher { private RSACoreEngine core; /** * initialise the RSA engine. * * @param forEncryption true if we are encrypting, false otherwise. * @param param the necessary RSA key parameters. */ public void init( boolean forEncryption, CipherParameters param) { if (core == null) { core = new RSACoreEngine(); } core.init(forEncryption, param); } /** * Return the maximum size for an input block to this engine. * For RSA this is always one byte less than the key size on * encryption, and the same length as the key size on decryption. * * @return maximum size for an input block. */ public int getInputBlockSize() { return core.getInputBlockSize(); } /** * Return the maximum size for an output block to this engine. * For RSA this is always one byte less than the key size on * decryption, and the same length as the key size on encryption. * * @return maximum size for an output block. */ public int getOutputBlockSize() { return core.getOutputBlockSize(); } /** * Process a single block using the basic RSA algorithm. * * @param in the input array. * @param inOff the offset into the input buffer where the data starts. * @param inLen the length of the data to be processed. * @return the result of the RSA process. * @exception DataLengthException the input block is too large. */ public byte[] processBlock( byte[] in, int inOff, int inLen) { if (core == null) { throw new IllegalStateException("RSA engine not initialised"); } return core.convertOutput(core.processBlock(core.convertInput(in, inOff, inLen))); } } bouncycastle-1.49.orig/src/org/bouncycastle/crypto/engines/RijndaelEngine.java0000644000175000017500000007261212106331226027177 0ustar ebourgebourgpackage org.bouncycastle.crypto.engines; import org.bouncycastle.crypto.BlockCipher; import org.bouncycastle.crypto.CipherParameters; import org.bouncycastle.crypto.DataLengthException; import org.bouncycastle.crypto.OutputLengthException; import org.bouncycastle.crypto.params.KeyParameter; /** * an implementation of Rijndael, based on the documentation and reference implementation * by Paulo Barreto, Vincent Rijmen, for v2.0 August '99. *

    * Note: this implementation is based on information prior to final NIST publication. */ public class RijndaelEngine implements BlockCipher { private static final int MAXROUNDS = 14; private static final int MAXKC = (256/4); private static final byte[] logtable = { (byte)0, (byte)0, (byte)25, (byte)1, (byte)50, (byte)2, (byte)26, (byte)198, (byte)75, (byte)199, (byte)27, (byte)104, (byte)51, (byte)238, (byte)223, (byte)3, (byte)100, (byte)4, (byte)224, (byte)14, (byte)52, (byte)141, (byte)129, (byte)239, (byte)76, (byte)113, (byte)8, (byte)200, (byte)248, (byte)105, (byte)28, (byte)193, (byte)125, (byte)194, (byte)29, (byte)181, (byte)249, (byte)185, (byte)39, (byte)106, (byte)77, (byte)228, (byte)166, (byte)114, (byte)154, (byte)201, (byte)9, (byte)120, (byte)101, (byte)47, (byte)138, (byte)5, (byte)33, (byte)15, (byte)225, (byte)36, (byte)18, (byte)240, (byte)130, (byte)69, (byte)53, (byte)147, (byte)218, (byte)142, (byte)150, (byte)143, (byte)219, (byte)189, (byte)54, (byte)208, (byte)206, (byte)148, (byte)19, (byte)92, (byte)210, (byte)241, (byte)64, (byte)70, (byte)131, (byte)56, (byte)102, (byte)221, (byte)253, (byte)48, (byte)191, (byte)6, (byte)139, (byte)98, (byte)179, (byte)37, (byte)226, (byte)152, (byte)34, (byte)136, (byte)145, (byte)16, (byte)126, (byte)110, (byte)72, (byte)195, (byte)163, (byte)182, (byte)30, (byte)66, (byte)58, (byte)107, (byte)40, (byte)84, (byte)250, (byte)133, (byte)61, (byte)186, (byte)43, (byte)121, (byte)10, (byte)21, (byte)155, (byte)159, (byte)94, (byte)202, (byte)78, (byte)212, (byte)172, (byte)229, (byte)243, (byte)115, (byte)167, (byte)87, (byte)175, (byte)88, (byte)168, (byte)80, (byte)244, (byte)234, (byte)214, (byte)116, (byte)79, (byte)174, (byte)233, (byte)213, (byte)231, (byte)230, (byte)173, (byte)232, (byte)44, (byte)215, (byte)117, (byte)122, (byte)235, (byte)22, (byte)11, (byte)245, (byte)89, (byte)203, (byte)95, (byte)176, (byte)156, (byte)169, (byte)81, (byte)160, (byte)127, (byte)12, (byte)246, (byte)111, (byte)23, (byte)196, (byte)73, (byte)236, (byte)216, (byte)67, (byte)31, (byte)45, (byte)164, (byte)118, (byte)123, (byte)183, (byte)204, (byte)187, (byte)62, (byte)90, (byte)251, (byte)96, (byte)177, (byte)134, (byte)59, (byte)82, (byte)161, (byte)108, (byte)170, (byte)85, (byte)41, (byte)157, (byte)151, (byte)178, (byte)135, (byte)144, (byte)97, (byte)190, (byte)220, (byte)252, (byte)188, (byte)149, (byte)207, (byte)205, (byte)55, (byte)63, (byte)91, (byte)209, (byte)83, (byte)57, (byte)132, (byte)60, (byte)65, (byte)162, (byte)109, (byte)71, (byte)20, (byte)42, (byte)158, (byte)93, (byte)86, (byte)242, (byte)211, (byte)171, (byte)68, (byte)17, (byte)146, (byte)217, (byte)35, (byte)32, (byte)46, (byte)137, (byte)180, (byte)124, (byte)184, (byte)38, (byte)119, (byte)153, (byte)227, (byte)165, (byte)103, (byte)74, (byte)237, (byte)222, (byte)197, (byte)49, (byte)254, (byte)24, (byte)13, (byte)99, (byte)140, (byte)128, (byte)192, (byte)247, (byte)112, (byte)7 }; private static final byte[] aLogtable = { (byte)0, (byte)3, (byte)5, (byte)15, (byte)17, (byte)51, (byte)85, (byte)255, (byte)26, (byte)46, (byte)114, (byte)150, (byte)161, (byte)248, (byte)19, (byte)53, (byte)95, (byte)225, (byte)56, (byte)72, (byte)216, (byte)115, (byte)149, (byte)164, (byte)247, (byte)2, (byte)6, (byte)10, (byte)30, (byte)34, (byte)102, (byte)170, (byte)229, (byte)52, (byte)92, (byte)228, (byte)55, (byte)89, (byte)235, (byte)38, (byte)106, (byte)190, (byte)217, (byte)112, (byte)144, (byte)171, (byte)230, (byte)49, (byte)83, (byte)245, (byte)4, (byte)12, (byte)20, (byte)60, (byte)68, (byte)204, (byte)79, (byte)209, (byte)104, (byte)184, (byte)211, (byte)110, (byte)178, (byte)205, (byte)76, (byte)212, (byte)103, (byte)169, (byte)224, (byte)59, (byte)77, (byte)215, (byte)98, (byte)166, (byte)241, (byte)8, (byte)24, (byte)40, (byte)120, (byte)136, (byte)131, (byte)158, (byte)185, (byte)208, (byte)107, (byte)189, (byte)220, (byte)127, (byte)129, (byte)152, (byte)179, (byte)206, (byte)73, (byte)219, (byte)118, (byte)154, (byte)181, (byte)196, (byte)87, (byte)249, (byte)16, (byte)48, (byte)80, (byte)240, (byte)11, (byte)29, (byte)39, (byte)105, (byte)187, (byte)214, (byte)97, (byte)163, (byte)254, (byte)25, (byte)43, (byte)125, (byte)135, (byte)146, (byte)173, (byte)236, (byte)47, (byte)113, (byte)147, (byte)174, (byte)233, (byte)32, (byte)96, (byte)160, (byte)251, (byte)22, (byte)58, (byte)78, (byte)210, (byte)109, (byte)183, (byte)194, (byte)93, (byte)231, (byte)50, (byte)86, (byte)250, (byte)21, (byte)63, (byte)65, (byte)195, (byte)94, (byte)226, (byte)61, (byte)71, (byte)201, (byte)64, (byte)192, (byte)91, (byte)237, (byte)44, (byte)116, (byte)156, (byte)191, (byte)218, (byte)117, (byte)159, (byte)186, (byte)213, (byte)100, (byte)172, (byte)239, (byte)42, (byte)126, (byte)130, (byte)157, (byte)188, (byte)223, (byte)122, (byte)142, (byte)137, (byte)128, (byte)155, (byte)182, (byte)193, (byte)88, (byte)232, (byte)35, (byte)101, (byte)175, (byte)234, (byte)37, (byte)111, (byte)177, (byte)200, (byte)67, (byte)197, (byte)84, (byte)252, (byte)31, (byte)33, (byte)99, (byte)165, (byte)244, (byte)7, (byte)9, (byte)27, (byte)45, (byte)119, (byte)153, (byte)176, (byte)203, (byte)70, (byte)202, (byte)69, (byte)207, (byte)74, (byte)222, (byte)121, (byte)139, (byte)134, (byte)145, (byte)168, (byte)227, (byte)62, (byte)66, (byte)198, (byte)81, (byte)243, (byte)14, (byte)18, (byte)54, (byte)90, (byte)238, (byte)41, (byte)123, (byte)141, (byte)140, (byte)143, (byte)138, (byte)133, (byte)148, (byte)167, (byte)242, (byte)13, (byte)23, (byte)57, (byte)75, (byte)221, (byte)124, (byte)132, (byte)151, (byte)162, (byte)253, (byte)28, (byte)36, (byte)108, (byte)180, (byte)199, (byte)82, (byte)246, (byte)1, (byte)3, (byte)5, (byte)15, (byte)17, (byte)51, (byte)85, (byte)255, (byte)26, (byte)46, (byte)114, (byte)150, (byte)161, (byte)248, (byte)19, (byte)53, (byte)95, (byte)225, (byte)56, (byte)72, (byte)216, (byte)115, (byte)149, (byte)164, (byte)247, (byte)2, (byte)6, (byte)10, (byte)30, (byte)34, (byte)102, (byte)170, (byte)229, (byte)52, (byte)92, (byte)228, (byte)55, (byte)89, (byte)235, (byte)38, (byte)106, (byte)190, (byte)217, (byte)112, (byte)144, (byte)171, (byte)230, (byte)49, (byte)83, (byte)245, (byte)4, (byte)12, (byte)20, (byte)60, (byte)68, (byte)204, (byte)79, (byte)209, (byte)104, (byte)184, (byte)211, (byte)110, (byte)178, (byte)205, (byte)76, (byte)212, (byte)103, (byte)169, (byte)224, (byte)59, (byte)77, (byte)215, (byte)98, (byte)166, (byte)241, (byte)8, (byte)24, (byte)40, (byte)120, (byte)136, (byte)131, (byte)158, (byte)185, (byte)208, (byte)107, (byte)189, (byte)220, (byte)127, (byte)129, (byte)152, (byte)179, (byte)206, (byte)73, (byte)219, (byte)118, (byte)154, (byte)181, (byte)196, (byte)87, (byte)249, (byte)16, (byte)48, (byte)80, (byte)240, (byte)11, (byte)29, (byte)39, (byte)105, (byte)187, (byte)214, (byte)97, (byte)163, (byte)254, (byte)25, (byte)43, (byte)125, (byte)135, (byte)146, (byte)173, (byte)236, (byte)47, (byte)113, (byte)147, (byte)174, (byte)233, (byte)32, (byte)96, (byte)160, (byte)251, (byte)22, (byte)58, (byte)78, (byte)210, (byte)109, (byte)183, (byte)194, (byte)93, (byte)231, (byte)50, (byte)86, (byte)250, (byte)21, (byte)63, (byte)65, (byte)195, (byte)94, (byte)226, (byte)61, (byte)71, (byte)201, (byte)64, (byte)192, (byte)91, (byte)237, (byte)44, (byte)116, (byte)156, (byte)191, (byte)218, (byte)117, (byte)159, (byte)186, (byte)213, (byte)100, (byte)172, (byte)239, (byte)42, (byte)126, (byte)130, (byte)157, (byte)188, (byte)223, (byte)122, (byte)142, (byte)137, (byte)128, (byte)155, (byte)182, (byte)193, (byte)88, (byte)232, (byte)35, (byte)101, (byte)175, (byte)234, (byte)37, (byte)111, (byte)177, (byte)200, (byte)67, (byte)197, (byte)84, (byte)252, (byte)31, (byte)33, (byte)99, (byte)165, (byte)244, (byte)7, (byte)9, (byte)27, (byte)45, (byte)119, (byte)153, (byte)176, (byte)203, (byte)70, (byte)202, (byte)69, (byte)207, (byte)74, (byte)222, (byte)121, (byte)139, (byte)134, (byte)145, (byte)168, (byte)227, (byte)62, (byte)66, (byte)198, (byte)81, (byte)243, (byte)14, (byte)18, (byte)54, (byte)90, (byte)238, (byte)41, (byte)123, (byte)141, (byte)140, (byte)143, (byte)138, (byte)133, (byte)148, (byte)167, (byte)242, (byte)13, (byte)23, (byte)57, (byte)75, (byte)221, (byte)124, (byte)132, (byte)151, (byte)162, (byte)253, (byte)28, (byte)36, (byte)108, (byte)180, (byte)199, (byte)82, (byte)246, (byte)1, }; private static final byte[] S = { (byte)99, (byte)124, (byte)119, (byte)123, (byte)242, (byte)107, (byte)111, (byte)197, (byte)48, (byte)1, (byte)103, (byte)43, (byte)254, (byte)215, (byte)171, (byte)118, (byte)202, (byte)130, (byte)201, (byte)125, (byte)250, (byte)89, (byte)71, (byte)240, (byte)173, (byte)212, (byte)162, (byte)175, (byte)156, (byte)164, (byte)114, (byte)192, (byte)183, (byte)253, (byte)147, (byte)38, (byte)54, (byte)63, (byte)247, (byte)204, (byte)52, (byte)165, (byte)229, (byte)241, (byte)113, (byte)216, (byte)49, (byte)21, (byte)4, (byte)199, (byte)35, (byte)195, (byte)24, (byte)150, (byte)5, (byte)154, (byte)7, (byte)18, (byte)128, (byte)226, (byte)235, (byte)39, (byte)178, (byte)117, (byte)9, (byte)131, (byte)44, (byte)26, (byte)27, (byte)110, (byte)90, (byte)160, (byte)82, (byte)59, (byte)214, (byte)179, (byte)41, (byte)227, (byte)47, (byte)132, (byte)83, (byte)209, (byte)0, (byte)237, (byte)32, (byte)252, (byte)177, (byte)91, (byte)106, (byte)203, (byte)190, (byte)57, (byte)74, (byte)76, (byte)88, (byte)207, (byte)208, (byte)239, (byte)170, (byte)251, (byte)67, (byte)77, (byte)51, (byte)133, (byte)69, (byte)249, (byte)2, (byte)127, (byte)80, (byte)60, (byte)159, (byte)168, (byte)81, (byte)163, (byte)64, (byte)143, (byte)146, (byte)157, (byte)56, (byte)245, (byte)188, (byte)182, (byte)218, (byte)33, (byte)16, (byte)255, (byte)243, (byte)210, (byte)205, (byte)12, (byte)19, (byte)236, (byte)95, (byte)151, (byte)68, (byte)23, (byte)196, (byte)167, (byte)126, (byte)61, (byte)100, (byte)93, (byte)25, (byte)115, (byte)96, (byte)129, (byte)79, (byte)220, (byte)34, (byte)42, (byte)144, (byte)136, (byte)70, (byte)238, (byte)184, (byte)20, (byte)222, (byte)94, (byte)11, (byte)219, (byte)224, (byte)50, (byte)58, (byte)10, (byte)73, (byte)6, (byte)36, (byte)92, (byte)194, (byte)211, (byte)172, (byte)98, (byte)145, (byte)149, (byte)228, (byte)121, (byte)231, (byte)200, (byte)55, (byte)109, (byte)141, (byte)213, (byte)78, (byte)169, (byte)108, (byte)86, (byte)244, (byte)234, (byte)101, (byte)122, (byte)174, (byte)8, (byte)186, (byte)120, (byte)37, (byte)46, (byte)28, (byte)166, (byte)180, (byte)198, (byte)232, (byte)221, (byte)116, (byte)31, (byte)75, (byte)189, (byte)139, (byte)138, (byte)112, (byte)62, (byte)181, (byte)102, (byte)72, (byte)3, (byte)246, (byte)14, (byte)97, (byte)53, (byte)87, (byte)185, (byte)134, (byte)193, (byte)29, (byte)158, (byte)225, (byte)248, (byte)152, (byte)17, (byte)105, (byte)217, (byte)142, (byte)148, (byte)155, (byte)30, (byte)135, (byte)233, (byte)206, (byte)85, (byte)40, (byte)223, (byte)140, (byte)161, (byte)137, (byte)13, (byte)191, (byte)230, (byte)66, (byte)104, (byte)65, (byte)153, (byte)45, (byte)15, (byte)176, (byte)84, (byte)187, (byte)22, }; private static final byte[] Si = { (byte)82, (byte)9, (byte)106, (byte)213, (byte)48, (byte)54, (byte)165, (byte)56, (byte)191, (byte)64, (byte)163, (byte)158, (byte)129, (byte)243, (byte)215, (byte)251, (byte)124, (byte)227, (byte)57, (byte)130, (byte)155, (byte)47, (byte)255, (byte)135, (byte)52, (byte)142, (byte)67, (byte)68, (byte)196, (byte)222, (byte)233, (byte)203, (byte)84, (byte)123, (byte)148, (byte)50, (byte)166, (byte)194, (byte)35, (byte)61, (byte)238, (byte)76, (byte)149, (byte)11, (byte)66, (byte)250, (byte)195, (byte)78, (byte)8, (byte)46, (byte)161, (byte)102, (byte)40, (byte)217, (byte)36, (byte)178, (byte)118, (byte)91, (byte)162, (byte)73, (byte)109, (byte)139, (byte)209, (byte)37, (byte)114, (byte)248, (byte)246, (byte)100, (byte)134, (byte)104, (byte)152, (byte)22, (byte)212, (byte)164, (byte)92, (byte)204, (byte)93, (byte)101, (byte)182, (byte)146, (byte)108, (byte)112, (byte)72, (byte)80, (byte)253, (byte)237, (byte)185, (byte)218, (byte)94, (byte)21, (byte)70, (byte)87, (byte)167, (byte)141, (byte)157, (byte)132, (byte)144, (byte)216, (byte)171, (byte)0, (byte)140, (byte)188, (byte)211, (byte)10, (byte)247, (byte)228, (byte)88, (byte)5, (byte)184, (byte)179, (byte)69, (byte)6, (byte)208, (byte)44, (byte)30, (byte)143, (byte)202, (byte)63, (byte)15, (byte)2, (byte)193, (byte)175, (byte)189, (byte)3, (byte)1, (byte)19, (byte)138, (byte)107, (byte)58, (byte)145, (byte)17, (byte)65, (byte)79, (byte)103, (byte)220, (byte)234, (byte)151, (byte)242, (byte)207, (byte)206, (byte)240, (byte)180, (byte)230, (byte)115, (byte)150, (byte)172, (byte)116, (byte)34, (byte)231, (byte)173, (byte)53, (byte)133, (byte)226, (byte)249, (byte)55, (byte)232, (byte)28, (byte)117, (byte)223, (byte)110, (byte)71, (byte)241, (byte)26, (byte)113, (byte)29, (byte)41, (byte)197, (byte)137, (byte)111, (byte)183, (byte)98, (byte)14, (byte)170, (byte)24, (byte)190, (byte)27, (byte)252, (byte)86, (byte)62, (byte)75, (byte)198, (byte)210, (byte)121, (byte)32, (byte)154, (byte)219, (byte)192, (byte)254, (byte)120, (byte)205, (byte)90, (byte)244, (byte)31, (byte)221, (byte)168, (byte)51, (byte)136, (byte)7, (byte)199, (byte)49, (byte)177, (byte)18, (byte)16, (byte)89, (byte)39, (byte)128, (byte)236, (byte)95, (byte)96, (byte)81, (byte)127, (byte)169, (byte)25, (byte)181, (byte)74, (byte)13, (byte)45, (byte)229, (byte)122, (byte)159, (byte)147, (byte)201, (byte)156, (byte)239, (byte)160, (byte)224, (byte)59, (byte)77, (byte)174, (byte)42, (byte)245, (byte)176, (byte)200, (byte)235, (byte)187, (byte)60, (byte)131, (byte)83, (byte)153, (byte)97, (byte)23, (byte)43, (byte)4, (byte)126, (byte)186, (byte)119, (byte)214, (byte)38, (byte)225, (byte)105, (byte)20, (byte)99, (byte)85, (byte)33, (byte)12, (byte)125, }; private static final int[] rcon = { 0x01, 0x02, 0x04, 0x08, 0x10, 0x20, 0x40, 0x80, 0x1b, 0x36, 0x6c, 0xd8, 0xab, 0x4d, 0x9a, 0x2f, 0x5e, 0xbc, 0x63, 0xc6, 0x97, 0x35, 0x6a, 0xd4, 0xb3, 0x7d, 0xfa, 0xef, 0xc5, 0x91 }; static byte[][] shifts0 = { { 0, 8, 16, 24 }, { 0, 8, 16, 24 }, { 0, 8, 16, 24 }, { 0, 8, 16, 32 }, { 0, 8, 24, 32 } }; static byte[][] shifts1 = { { 0, 24, 16, 8 }, { 0, 32, 24, 16 }, { 0, 40, 32, 24 }, { 0, 48, 40, 24 }, { 0, 56, 40, 32 } }; /** * multiply two elements of GF(2^m) * needed for MixColumn and InvMixColumn */ private byte mul0x2( int b) { if (b != 0) { return aLogtable[25 + (logtable[b] & 0xff)]; } else { return 0; } } private byte mul0x3( int b) { if (b != 0) { return aLogtable[1 + (logtable[b] & 0xff)]; } else { return 0; } } private byte mul0x9( int b) { if (b >= 0) { return aLogtable[199 + b]; } else { return 0; } } private byte mul0xb( int b) { if (b >= 0) { return aLogtable[104 + b]; } else { return 0; } } private byte mul0xd( int b) { if (b >= 0) { return aLogtable[238 + b]; } else { return 0; } } private byte mul0xe( int b) { if (b >= 0) { return aLogtable[223 + b]; } else { return 0; } } /** * xor corresponding text input and round key input bytes */ private void KeyAddition( long[] rk) { A0 ^= rk[0]; A1 ^= rk[1]; A2 ^= rk[2]; A3 ^= rk[3]; } private long shift( long r, int shift) { return (((r >>> shift) | (r << (BC - shift)))) & BC_MASK; } /** * Row 0 remains unchanged * The other three rows are shifted a variable amount */ private void ShiftRow( byte[] shiftsSC) { A1 = shift(A1, shiftsSC[1]); A2 = shift(A2, shiftsSC[2]); A3 = shift(A3, shiftsSC[3]); } private long applyS( long r, byte[] box) { long res = 0; for (int j = 0; j < BC; j += 8) { res |= (long)(box[(int)((r >> j) & 0xff)] & 0xff) << j; } return res; } /** * Replace every byte of the input by the byte at that place * in the nonlinear S-box */ private void Substitution( byte[] box) { A0 = applyS(A0, box); A1 = applyS(A1, box); A2 = applyS(A2, box); A3 = applyS(A3, box); } /** * Mix the bytes of every column in a linear way */ private void MixColumn() { long r0, r1, r2, r3; r0 = r1 = r2 = r3 = 0; for (int j = 0; j < BC; j += 8) { int a0 = (int)((A0 >> j) & 0xff); int a1 = (int)((A1 >> j) & 0xff); int a2 = (int)((A2 >> j) & 0xff); int a3 = (int)((A3 >> j) & 0xff); r0 |= (long)((mul0x2(a0) ^ mul0x3(a1) ^ a2 ^ a3) & 0xff) << j; r1 |= (long)((mul0x2(a1) ^ mul0x3(a2) ^ a3 ^ a0) & 0xff) << j; r2 |= (long)((mul0x2(a2) ^ mul0x3(a3) ^ a0 ^ a1) & 0xff) << j; r3 |= (long)((mul0x2(a3) ^ mul0x3(a0) ^ a1 ^ a2) & 0xff) << j; } A0 = r0; A1 = r1; A2 = r2; A3 = r3; } /** * Mix the bytes of every column in a linear way * This is the opposite operation of Mixcolumn */ private void InvMixColumn() { long r0, r1, r2, r3; r0 = r1 = r2 = r3 = 0; for (int j = 0; j < BC; j += 8) { int a0 = (int)((A0 >> j) & 0xff); int a1 = (int)((A1 >> j) & 0xff); int a2 = (int)((A2 >> j) & 0xff); int a3 = (int)((A3 >> j) & 0xff); // // pre-lookup the log table // a0 = (a0 != 0) ? (logtable[a0 & 0xff] & 0xff) : -1; a1 = (a1 != 0) ? (logtable[a1 & 0xff] & 0xff) : -1; a2 = (a2 != 0) ? (logtable[a2 & 0xff] & 0xff) : -1; a3 = (a3 != 0) ? (logtable[a3 & 0xff] & 0xff) : -1; r0 |= (long)((mul0xe(a0) ^ mul0xb(a1) ^ mul0xd(a2) ^ mul0x9(a3)) & 0xff) << j; r1 |= (long)((mul0xe(a1) ^ mul0xb(a2) ^ mul0xd(a3) ^ mul0x9(a0)) & 0xff) << j; r2 |= (long)((mul0xe(a2) ^ mul0xb(a3) ^ mul0xd(a0) ^ mul0x9(a1)) & 0xff) << j; r3 |= (long)((mul0xe(a3) ^ mul0xb(a0) ^ mul0xd(a1) ^ mul0x9(a2)) & 0xff) << j; } A0 = r0; A1 = r1; A2 = r2; A3 = r3; } /** * Calculate the necessary round keys * The number of calculations depends on keyBits and blockBits */ private long[][] generateWorkingKey( byte[] key) { int KC; int t, rconpointer = 0; int keyBits = key.length * 8; byte[][] tk = new byte[4][MAXKC]; long[][] W = new long[MAXROUNDS+1][4]; switch (keyBits) { case 128: KC = 4; break; case 160: KC = 5; break; case 192: KC = 6; break; case 224: KC = 7; break; case 256: KC = 8; break; default : throw new IllegalArgumentException("Key length not 128/160/192/224/256 bits."); } if (keyBits >= blockBits) { ROUNDS = KC + 6; } else { ROUNDS = (BC / 8) + 6; } // // copy the key into the processing area // int index = 0; for (int i = 0; i < key.length; i++) { tk[i % 4][i / 4] = key[index++]; } t = 0; // // copy values into round key array // for (int j = 0; (j < KC) && (t < (ROUNDS+1)*(BC / 8)); j++, t++) { for (int i = 0; i < 4; i++) { W[t / (BC / 8)][i] |= (long)(tk[i][j] & 0xff) << ((t * 8) % BC); } } // // while not enough round key material calculated // calculate new values // while (t < (ROUNDS+1)*(BC/8)) { for (int i = 0; i < 4; i++) { tk[i][0] ^= S[tk[(i+1)%4][KC-1] & 0xff]; } tk[0][0] ^= rcon[rconpointer++]; if (KC <= 6) { for (int j = 1; j < KC; j++) { for (int i = 0; i < 4; i++) { tk[i][j] ^= tk[i][j-1]; } } } else { for (int j = 1; j < 4; j++) { for (int i = 0; i < 4; i++) { tk[i][j] ^= tk[i][j-1]; } } for (int i = 0; i < 4; i++) { tk[i][4] ^= S[tk[i][3] & 0xff]; } for (int j = 5; j < KC; j++) { for (int i = 0; i < 4; i++) { tk[i][j] ^= tk[i][j-1]; } } } // // copy values into round key array // for (int j = 0; (j < KC) && (t < (ROUNDS+1)*(BC/8)); j++, t++) { for (int i = 0; i < 4; i++) { W[t / (BC/8)][i] |= (long)(tk[i][j] & 0xff) << ((t * 8) % (BC)); } } } return W; } private int BC; private long BC_MASK; private int ROUNDS; private int blockBits; private long[][] workingKey; private long A0, A1, A2, A3; private boolean forEncryption; private byte[] shifts0SC; private byte[] shifts1SC; /** * default constructor - 128 bit block size. */ public RijndaelEngine() { this(128); } /** * basic constructor - set the cipher up for a given blocksize * * @param blockBits the blocksize in bits, must be 128, 192, or 256. */ public RijndaelEngine( int blockBits) { switch (blockBits) { case 128: BC = 32; BC_MASK = 0xffffffffL; shifts0SC = shifts0[0]; shifts1SC = shifts1[0]; break; case 160: BC = 40; BC_MASK = 0xffffffffffL; shifts0SC = shifts0[1]; shifts1SC = shifts1[1]; break; case 192: BC = 48; BC_MASK = 0xffffffffffffL; shifts0SC = shifts0[2]; shifts1SC = shifts1[2]; break; case 224: BC = 56; BC_MASK = 0xffffffffffffffL; shifts0SC = shifts0[3]; shifts1SC = shifts1[3]; break; case 256: BC = 64; BC_MASK = 0xffffffffffffffffL; shifts0SC = shifts0[4]; shifts1SC = shifts1[4]; break; default: throw new IllegalArgumentException("unknown blocksize to Rijndael"); } this.blockBits = blockBits; } /** * initialise a Rijndael cipher. * * @param forEncryption whether or not we are for encryption. * @param params the parameters required to set up the cipher. * @exception IllegalArgumentException if the params argument is * inappropriate. */ public void init( boolean forEncryption, CipherParameters params) { if (params instanceof KeyParameter) { workingKey = generateWorkingKey(((KeyParameter)params).getKey()); this.forEncryption = forEncryption; return; } throw new IllegalArgumentException("invalid parameter passed to Rijndael init - " + params.getClass().getName()); } public String getAlgorithmName() { return "Rijndael"; } public int getBlockSize() { return BC / 2; } public int processBlock( byte[] in, int inOff, byte[] out, int outOff) { if (workingKey == null) { throw new IllegalStateException("Rijndael engine not initialised"); } if ((inOff + (BC / 2)) > in.length) { throw new DataLengthException("input buffer too short"); } if ((outOff + (BC / 2)) > out.length) { throw new OutputLengthException("output buffer too short"); } if (forEncryption) { unpackBlock(in, inOff); encryptBlock(workingKey); packBlock(out, outOff); } else { unpackBlock(in, inOff); decryptBlock(workingKey); packBlock(out, outOff); } return BC / 2; } public void reset() { } private void unpackBlock( byte[] bytes, int off) { int index = off; A0 = (bytes[index++] & 0xff); A1 = (bytes[index++] & 0xff); A2 = (bytes[index++] & 0xff); A3 = (bytes[index++] & 0xff); for (int j = 8; j != BC; j += 8) { A0 |= (long)(bytes[index++] & 0xff) << j; A1 |= (long)(bytes[index++] & 0xff) << j; A2 |= (long)(bytes[index++] & 0xff) << j; A3 |= (long)(bytes[index++] & 0xff) << j; } } private void packBlock( byte[] bytes, int off) { int index = off; for (int j = 0; j != BC; j += 8) { bytes[index++] = (byte)(A0 >> j); bytes[index++] = (byte)(A1 >> j); bytes[index++] = (byte)(A2 >> j); bytes[index++] = (byte)(A3 >> j); } } private void encryptBlock( long[][] rk) { int r; // // begin with a key addition // KeyAddition(rk[0]); // // ROUNDS-1 ordinary rounds // for (r = 1; r < ROUNDS; r++) { Substitution(S); ShiftRow(shifts0SC); MixColumn(); KeyAddition(rk[r]); } // // Last round is special: there is no MixColumn // Substitution(S); ShiftRow(shifts0SC); KeyAddition(rk[ROUNDS]); } private void decryptBlock( long[][] rk) { int r; // To decrypt: apply the inverse operations of the encrypt routine, // in opposite order // // (KeyAddition is an involution: it 's equal to its inverse) // (the inverse of Substitution with table S is Substitution with the inverse table of S) // (the inverse of Shiftrow is Shiftrow over a suitable distance) // // First the special round: // without InvMixColumn // with extra KeyAddition // KeyAddition(rk[ROUNDS]); Substitution(Si); ShiftRow(shifts1SC); // // ROUNDS-1 ordinary rounds // for (r = ROUNDS-1; r > 0; r--) { KeyAddition(rk[r]); InvMixColumn(); Substitution(Si); ShiftRow(shifts1SC); } // // End with the extra key addition // KeyAddition(rk[0]); } } bouncycastle-1.49.orig/src/org/bouncycastle/crypto/engines/VMPCEngine.java0000644000175000017500000000744312106331472026217 0ustar ebourgebourgpackage org.bouncycastle.crypto.engines; import org.bouncycastle.crypto.CipherParameters; import org.bouncycastle.crypto.DataLengthException; import org.bouncycastle.crypto.OutputLengthException; import org.bouncycastle.crypto.StreamCipher; import org.bouncycastle.crypto.params.KeyParameter; import org.bouncycastle.crypto.params.ParametersWithIV; public class VMPCEngine implements StreamCipher { /* * variables to hold the state of the VMPC engine during encryption and * decryption */ protected byte n = 0; protected byte[] P = null; protected byte s = 0; protected byte[] workingIV; protected byte[] workingKey; public String getAlgorithmName() { return "VMPC"; } /** * initialise a VMPC cipher. * * @param forEncryption * whether or not we are for encryption. * @param params * the parameters required to set up the cipher. * @exception IllegalArgumentException * if the params argument is inappropriate. */ public void init(boolean forEncryption, CipherParameters params) { if (!(params instanceof ParametersWithIV)) { throw new IllegalArgumentException( "VMPC init parameters must include an IV"); } ParametersWithIV ivParams = (ParametersWithIV) params; KeyParameter key = (KeyParameter) ivParams.getParameters(); if (!(ivParams.getParameters() instanceof KeyParameter)) { throw new IllegalArgumentException( "VMPC init parameters must include a key"); } this.workingIV = ivParams.getIV(); if (workingIV == null || workingIV.length < 1 || workingIV.length > 768) { throw new IllegalArgumentException("VMPC requires 1 to 768 bytes of IV"); } this.workingKey = key.getKey(); initKey(this.workingKey, this.workingIV); } protected void initKey(byte[] keyBytes, byte[] ivBytes) { s = 0; P = new byte[256]; for (int i = 0; i < 256; i++) { P[i] = (byte) i; } for (int m = 0; m < 768; m++) { s = P[(s + P[m & 0xff] + keyBytes[m % keyBytes.length]) & 0xff]; byte temp = P[m & 0xff]; P[m & 0xff] = P[s & 0xff]; P[s & 0xff] = temp; } for (int m = 0; m < 768; m++) { s = P[(s + P[m & 0xff] + ivBytes[m % ivBytes.length]) & 0xff]; byte temp = P[m & 0xff]; P[m & 0xff] = P[s & 0xff]; P[s & 0xff] = temp; } n = 0; } public void processBytes(byte[] in, int inOff, int len, byte[] out, int outOff) { if ((inOff + len) > in.length) { throw new DataLengthException("input buffer too short"); } if ((outOff + len) > out.length) { throw new OutputLengthException("output buffer too short"); } for (int i = 0; i < len; i++) { s = P[(s + P[n & 0xff]) & 0xff]; byte z = P[(P[(P[s & 0xff]) & 0xff] + 1) & 0xff]; // encryption byte temp = P[n & 0xff]; P[n & 0xff] = P[s & 0xff]; P[s & 0xff] = temp; n = (byte) ((n + 1) & 0xff); // xor out[i + outOff] = (byte) (in[i + inOff] ^ z); } } public void reset() { initKey(this.workingKey, this.workingIV); } public byte returnByte(byte in) { s = P[(s + P[n & 0xff]) & 0xff]; byte z = P[(P[(P[s & 0xff]) & 0xff] + 1) & 0xff]; // encryption byte temp = P[n & 0xff]; P[n & 0xff] = P[s & 0xff]; P[s & 0xff] = temp; n = (byte) ((n + 1) & 0xff); // xor return (byte) (in ^ z); } } bouncycastle-1.49.orig/src/org/bouncycastle/crypto/engines/CamelliaEngine.java0000644000175000017500000007204612106330000027144 0ustar ebourgebourgpackage org.bouncycastle.crypto.engines; import org.bouncycastle.crypto.BlockCipher; import org.bouncycastle.crypto.CipherParameters; import org.bouncycastle.crypto.DataLengthException; import org.bouncycastle.crypto.OutputLengthException; import org.bouncycastle.crypto.params.KeyParameter; /** * Camellia - based on RFC 3713. */ public class CamelliaEngine implements BlockCipher { private boolean initialised = false; private boolean _keyIs128; private static final int BLOCK_SIZE = 16; private static final int MASK8 = 0xff; private int[] subkey = new int[24 * 4]; private int[] kw = new int[4 * 2]; // for whitening private int[] ke = new int[6 * 2]; // for FL and FL^(-1) private int[] state = new int[4]; // for encryption and decryption private static final int SIGMA[] = { 0xa09e667f, 0x3bcc908b, 0xb67ae858, 0x4caa73b2, 0xc6ef372f, 0xe94f82be, 0x54ff53a5, 0xf1d36f1c, 0x10e527fa, 0xde682d1d, 0xb05688c2, 0xb3e6c1fd }; /* * * S-box data * */ private static final int SBOX1_1110[] = { 0x70707000, 0x82828200, 0x2c2c2c00, 0xececec00, 0xb3b3b300, 0x27272700, 0xc0c0c000, 0xe5e5e500, 0xe4e4e400, 0x85858500, 0x57575700, 0x35353500, 0xeaeaea00, 0x0c0c0c00, 0xaeaeae00, 0x41414100, 0x23232300, 0xefefef00, 0x6b6b6b00, 0x93939300, 0x45454500, 0x19191900, 0xa5a5a500, 0x21212100, 0xededed00, 0x0e0e0e00, 0x4f4f4f00, 0x4e4e4e00, 0x1d1d1d00, 0x65656500, 0x92929200, 0xbdbdbd00, 0x86868600, 0xb8b8b800, 0xafafaf00, 0x8f8f8f00, 0x7c7c7c00, 0xebebeb00, 0x1f1f1f00, 0xcecece00, 0x3e3e3e00, 0x30303000, 0xdcdcdc00, 0x5f5f5f00, 0x5e5e5e00, 0xc5c5c500, 0x0b0b0b00, 0x1a1a1a00, 0xa6a6a600, 0xe1e1e100, 0x39393900, 0xcacaca00, 0xd5d5d500, 0x47474700, 0x5d5d5d00, 0x3d3d3d00, 0xd9d9d900, 0x01010100, 0x5a5a5a00, 0xd6d6d600, 0x51515100, 0x56565600, 0x6c6c6c00, 0x4d4d4d00, 0x8b8b8b00, 0x0d0d0d00, 0x9a9a9a00, 0x66666600, 0xfbfbfb00, 0xcccccc00, 0xb0b0b000, 0x2d2d2d00, 0x74747400, 0x12121200, 0x2b2b2b00, 0x20202000, 0xf0f0f000, 0xb1b1b100, 0x84848400, 0x99999900, 0xdfdfdf00, 0x4c4c4c00, 0xcbcbcb00, 0xc2c2c200, 0x34343400, 0x7e7e7e00, 0x76767600, 0x05050500, 0x6d6d6d00, 0xb7b7b700, 0xa9a9a900, 0x31313100, 0xd1d1d100, 0x17171700, 0x04040400, 0xd7d7d700, 0x14141400, 0x58585800, 0x3a3a3a00, 0x61616100, 0xdedede00, 0x1b1b1b00, 0x11111100, 0x1c1c1c00, 0x32323200, 0x0f0f0f00, 0x9c9c9c00, 0x16161600, 0x53535300, 0x18181800, 0xf2f2f200, 0x22222200, 0xfefefe00, 0x44444400, 0xcfcfcf00, 0xb2b2b200, 0xc3c3c300, 0xb5b5b500, 0x7a7a7a00, 0x91919100, 0x24242400, 0x08080800, 0xe8e8e800, 0xa8a8a800, 0x60606000, 0xfcfcfc00, 0x69696900, 0x50505000, 0xaaaaaa00, 0xd0d0d000, 0xa0a0a000, 0x7d7d7d00, 0xa1a1a100, 0x89898900, 0x62626200, 0x97979700, 0x54545400, 0x5b5b5b00, 0x1e1e1e00, 0x95959500, 0xe0e0e000, 0xffffff00, 0x64646400, 0xd2d2d200, 0x10101000, 0xc4c4c400, 0x00000000, 0x48484800, 0xa3a3a300, 0xf7f7f700, 0x75757500, 0xdbdbdb00, 0x8a8a8a00, 0x03030300, 0xe6e6e600, 0xdadada00, 0x09090900, 0x3f3f3f00, 0xdddddd00, 0x94949400, 0x87878700, 0x5c5c5c00, 0x83838300, 0x02020200, 0xcdcdcd00, 0x4a4a4a00, 0x90909000, 0x33333300, 0x73737300, 0x67676700, 0xf6f6f600, 0xf3f3f300, 0x9d9d9d00, 0x7f7f7f00, 0xbfbfbf00, 0xe2e2e200, 0x52525200, 0x9b9b9b00, 0xd8d8d800, 0x26262600, 0xc8c8c800, 0x37373700, 0xc6c6c600, 0x3b3b3b00, 0x81818100, 0x96969600, 0x6f6f6f00, 0x4b4b4b00, 0x13131300, 0xbebebe00, 0x63636300, 0x2e2e2e00, 0xe9e9e900, 0x79797900, 0xa7a7a700, 0x8c8c8c00, 0x9f9f9f00, 0x6e6e6e00, 0xbcbcbc00, 0x8e8e8e00, 0x29292900, 0xf5f5f500, 0xf9f9f900, 0xb6b6b600, 0x2f2f2f00, 0xfdfdfd00, 0xb4b4b400, 0x59595900, 0x78787800, 0x98989800, 0x06060600, 0x6a6a6a00, 0xe7e7e700, 0x46464600, 0x71717100, 0xbababa00, 0xd4d4d400, 0x25252500, 0xababab00, 0x42424200, 0x88888800, 0xa2a2a200, 0x8d8d8d00, 0xfafafa00, 0x72727200, 0x07070700, 0xb9b9b900, 0x55555500, 0xf8f8f800, 0xeeeeee00, 0xacacac00, 0x0a0a0a00, 0x36363600, 0x49494900, 0x2a2a2a00, 0x68686800, 0x3c3c3c00, 0x38383800, 0xf1f1f100, 0xa4a4a400, 0x40404000, 0x28282800, 0xd3d3d300, 0x7b7b7b00, 0xbbbbbb00, 0xc9c9c900, 0x43434300, 0xc1c1c100, 0x15151500, 0xe3e3e300, 0xadadad00, 0xf4f4f400, 0x77777700, 0xc7c7c700, 0x80808000, 0x9e9e9e00 }; private static final int SBOX4_4404[] = { 0x70700070, 0x2c2c002c, 0xb3b300b3, 0xc0c000c0, 0xe4e400e4, 0x57570057, 0xeaea00ea, 0xaeae00ae, 0x23230023, 0x6b6b006b, 0x45450045, 0xa5a500a5, 0xeded00ed, 0x4f4f004f, 0x1d1d001d, 0x92920092, 0x86860086, 0xafaf00af, 0x7c7c007c, 0x1f1f001f, 0x3e3e003e, 0xdcdc00dc, 0x5e5e005e, 0x0b0b000b, 0xa6a600a6, 0x39390039, 0xd5d500d5, 0x5d5d005d, 0xd9d900d9, 0x5a5a005a, 0x51510051, 0x6c6c006c, 0x8b8b008b, 0x9a9a009a, 0xfbfb00fb, 0xb0b000b0, 0x74740074, 0x2b2b002b, 0xf0f000f0, 0x84840084, 0xdfdf00df, 0xcbcb00cb, 0x34340034, 0x76760076, 0x6d6d006d, 0xa9a900a9, 0xd1d100d1, 0x04040004, 0x14140014, 0x3a3a003a, 0xdede00de, 0x11110011, 0x32320032, 0x9c9c009c, 0x53530053, 0xf2f200f2, 0xfefe00fe, 0xcfcf00cf, 0xc3c300c3, 0x7a7a007a, 0x24240024, 0xe8e800e8, 0x60600060, 0x69690069, 0xaaaa00aa, 0xa0a000a0, 0xa1a100a1, 0x62620062, 0x54540054, 0x1e1e001e, 0xe0e000e0, 0x64640064, 0x10100010, 0x00000000, 0xa3a300a3, 0x75750075, 0x8a8a008a, 0xe6e600e6, 0x09090009, 0xdddd00dd, 0x87870087, 0x83830083, 0xcdcd00cd, 0x90900090, 0x73730073, 0xf6f600f6, 0x9d9d009d, 0xbfbf00bf, 0x52520052, 0xd8d800d8, 0xc8c800c8, 0xc6c600c6, 0x81810081, 0x6f6f006f, 0x13130013, 0x63630063, 0xe9e900e9, 0xa7a700a7, 0x9f9f009f, 0xbcbc00bc, 0x29290029, 0xf9f900f9, 0x2f2f002f, 0xb4b400b4, 0x78780078, 0x06060006, 0xe7e700e7, 0x71710071, 0xd4d400d4, 0xabab00ab, 0x88880088, 0x8d8d008d, 0x72720072, 0xb9b900b9, 0xf8f800f8, 0xacac00ac, 0x36360036, 0x2a2a002a, 0x3c3c003c, 0xf1f100f1, 0x40400040, 0xd3d300d3, 0xbbbb00bb, 0x43430043, 0x15150015, 0xadad00ad, 0x77770077, 0x80800080, 0x82820082, 0xecec00ec, 0x27270027, 0xe5e500e5, 0x85850085, 0x35350035, 0x0c0c000c, 0x41410041, 0xefef00ef, 0x93930093, 0x19190019, 0x21210021, 0x0e0e000e, 0x4e4e004e, 0x65650065, 0xbdbd00bd, 0xb8b800b8, 0x8f8f008f, 0xebeb00eb, 0xcece00ce, 0x30300030, 0x5f5f005f, 0xc5c500c5, 0x1a1a001a, 0xe1e100e1, 0xcaca00ca, 0x47470047, 0x3d3d003d, 0x01010001, 0xd6d600d6, 0x56560056, 0x4d4d004d, 0x0d0d000d, 0x66660066, 0xcccc00cc, 0x2d2d002d, 0x12120012, 0x20200020, 0xb1b100b1, 0x99990099, 0x4c4c004c, 0xc2c200c2, 0x7e7e007e, 0x05050005, 0xb7b700b7, 0x31310031, 0x17170017, 0xd7d700d7, 0x58580058, 0x61610061, 0x1b1b001b, 0x1c1c001c, 0x0f0f000f, 0x16160016, 0x18180018, 0x22220022, 0x44440044, 0xb2b200b2, 0xb5b500b5, 0x91910091, 0x08080008, 0xa8a800a8, 0xfcfc00fc, 0x50500050, 0xd0d000d0, 0x7d7d007d, 0x89890089, 0x97970097, 0x5b5b005b, 0x95950095, 0xffff00ff, 0xd2d200d2, 0xc4c400c4, 0x48480048, 0xf7f700f7, 0xdbdb00db, 0x03030003, 0xdada00da, 0x3f3f003f, 0x94940094, 0x5c5c005c, 0x02020002, 0x4a4a004a, 0x33330033, 0x67670067, 0xf3f300f3, 0x7f7f007f, 0xe2e200e2, 0x9b9b009b, 0x26260026, 0x37370037, 0x3b3b003b, 0x96960096, 0x4b4b004b, 0xbebe00be, 0x2e2e002e, 0x79790079, 0x8c8c008c, 0x6e6e006e, 0x8e8e008e, 0xf5f500f5, 0xb6b600b6, 0xfdfd00fd, 0x59590059, 0x98980098, 0x6a6a006a, 0x46460046, 0xbaba00ba, 0x25250025, 0x42420042, 0xa2a200a2, 0xfafa00fa, 0x07070007, 0x55550055, 0xeeee00ee, 0x0a0a000a, 0x49490049, 0x68680068, 0x38380038, 0xa4a400a4, 0x28280028, 0x7b7b007b, 0xc9c900c9, 0xc1c100c1, 0xe3e300e3, 0xf4f400f4, 0xc7c700c7, 0x9e9e009e }; private static final int SBOX2_0222[] = { 0x00e0e0e0, 0x00050505, 0x00585858, 0x00d9d9d9, 0x00676767, 0x004e4e4e, 0x00818181, 0x00cbcbcb, 0x00c9c9c9, 0x000b0b0b, 0x00aeaeae, 0x006a6a6a, 0x00d5d5d5, 0x00181818, 0x005d5d5d, 0x00828282, 0x00464646, 0x00dfdfdf, 0x00d6d6d6, 0x00272727, 0x008a8a8a, 0x00323232, 0x004b4b4b, 0x00424242, 0x00dbdbdb, 0x001c1c1c, 0x009e9e9e, 0x009c9c9c, 0x003a3a3a, 0x00cacaca, 0x00252525, 0x007b7b7b, 0x000d0d0d, 0x00717171, 0x005f5f5f, 0x001f1f1f, 0x00f8f8f8, 0x00d7d7d7, 0x003e3e3e, 0x009d9d9d, 0x007c7c7c, 0x00606060, 0x00b9b9b9, 0x00bebebe, 0x00bcbcbc, 0x008b8b8b, 0x00161616, 0x00343434, 0x004d4d4d, 0x00c3c3c3, 0x00727272, 0x00959595, 0x00ababab, 0x008e8e8e, 0x00bababa, 0x007a7a7a, 0x00b3b3b3, 0x00020202, 0x00b4b4b4, 0x00adadad, 0x00a2a2a2, 0x00acacac, 0x00d8d8d8, 0x009a9a9a, 0x00171717, 0x001a1a1a, 0x00353535, 0x00cccccc, 0x00f7f7f7, 0x00999999, 0x00616161, 0x005a5a5a, 0x00e8e8e8, 0x00242424, 0x00565656, 0x00404040, 0x00e1e1e1, 0x00636363, 0x00090909, 0x00333333, 0x00bfbfbf, 0x00989898, 0x00979797, 0x00858585, 0x00686868, 0x00fcfcfc, 0x00ececec, 0x000a0a0a, 0x00dadada, 0x006f6f6f, 0x00535353, 0x00626262, 0x00a3a3a3, 0x002e2e2e, 0x00080808, 0x00afafaf, 0x00282828, 0x00b0b0b0, 0x00747474, 0x00c2c2c2, 0x00bdbdbd, 0x00363636, 0x00222222, 0x00383838, 0x00646464, 0x001e1e1e, 0x00393939, 0x002c2c2c, 0x00a6a6a6, 0x00303030, 0x00e5e5e5, 0x00444444, 0x00fdfdfd, 0x00888888, 0x009f9f9f, 0x00656565, 0x00878787, 0x006b6b6b, 0x00f4f4f4, 0x00232323, 0x00484848, 0x00101010, 0x00d1d1d1, 0x00515151, 0x00c0c0c0, 0x00f9f9f9, 0x00d2d2d2, 0x00a0a0a0, 0x00555555, 0x00a1a1a1, 0x00414141, 0x00fafafa, 0x00434343, 0x00131313, 0x00c4c4c4, 0x002f2f2f, 0x00a8a8a8, 0x00b6b6b6, 0x003c3c3c, 0x002b2b2b, 0x00c1c1c1, 0x00ffffff, 0x00c8c8c8, 0x00a5a5a5, 0x00202020, 0x00898989, 0x00000000, 0x00909090, 0x00474747, 0x00efefef, 0x00eaeaea, 0x00b7b7b7, 0x00151515, 0x00060606, 0x00cdcdcd, 0x00b5b5b5, 0x00121212, 0x007e7e7e, 0x00bbbbbb, 0x00292929, 0x000f0f0f, 0x00b8b8b8, 0x00070707, 0x00040404, 0x009b9b9b, 0x00949494, 0x00212121, 0x00666666, 0x00e6e6e6, 0x00cecece, 0x00ededed, 0x00e7e7e7, 0x003b3b3b, 0x00fefefe, 0x007f7f7f, 0x00c5c5c5, 0x00a4a4a4, 0x00373737, 0x00b1b1b1, 0x004c4c4c, 0x00919191, 0x006e6e6e, 0x008d8d8d, 0x00767676, 0x00030303, 0x002d2d2d, 0x00dedede, 0x00969696, 0x00262626, 0x007d7d7d, 0x00c6c6c6, 0x005c5c5c, 0x00d3d3d3, 0x00f2f2f2, 0x004f4f4f, 0x00191919, 0x003f3f3f, 0x00dcdcdc, 0x00797979, 0x001d1d1d, 0x00525252, 0x00ebebeb, 0x00f3f3f3, 0x006d6d6d, 0x005e5e5e, 0x00fbfbfb, 0x00696969, 0x00b2b2b2, 0x00f0f0f0, 0x00313131, 0x000c0c0c, 0x00d4d4d4, 0x00cfcfcf, 0x008c8c8c, 0x00e2e2e2, 0x00757575, 0x00a9a9a9, 0x004a4a4a, 0x00575757, 0x00848484, 0x00111111, 0x00454545, 0x001b1b1b, 0x00f5f5f5, 0x00e4e4e4, 0x000e0e0e, 0x00737373, 0x00aaaaaa, 0x00f1f1f1, 0x00dddddd, 0x00595959, 0x00141414, 0x006c6c6c, 0x00929292, 0x00545454, 0x00d0d0d0, 0x00787878, 0x00707070, 0x00e3e3e3, 0x00494949, 0x00808080, 0x00505050, 0x00a7a7a7, 0x00f6f6f6, 0x00777777, 0x00939393, 0x00868686, 0x00838383, 0x002a2a2a, 0x00c7c7c7, 0x005b5b5b, 0x00e9e9e9, 0x00eeeeee, 0x008f8f8f, 0x00010101, 0x003d3d3d }; private static final int SBOX3_3033[] = { 0x38003838, 0x41004141, 0x16001616, 0x76007676, 0xd900d9d9, 0x93009393, 0x60006060, 0xf200f2f2, 0x72007272, 0xc200c2c2, 0xab00abab, 0x9a009a9a, 0x75007575, 0x06000606, 0x57005757, 0xa000a0a0, 0x91009191, 0xf700f7f7, 0xb500b5b5, 0xc900c9c9, 0xa200a2a2, 0x8c008c8c, 0xd200d2d2, 0x90009090, 0xf600f6f6, 0x07000707, 0xa700a7a7, 0x27002727, 0x8e008e8e, 0xb200b2b2, 0x49004949, 0xde00dede, 0x43004343, 0x5c005c5c, 0xd700d7d7, 0xc700c7c7, 0x3e003e3e, 0xf500f5f5, 0x8f008f8f, 0x67006767, 0x1f001f1f, 0x18001818, 0x6e006e6e, 0xaf00afaf, 0x2f002f2f, 0xe200e2e2, 0x85008585, 0x0d000d0d, 0x53005353, 0xf000f0f0, 0x9c009c9c, 0x65006565, 0xea00eaea, 0xa300a3a3, 0xae00aeae, 0x9e009e9e, 0xec00ecec, 0x80008080, 0x2d002d2d, 0x6b006b6b, 0xa800a8a8, 0x2b002b2b, 0x36003636, 0xa600a6a6, 0xc500c5c5, 0x86008686, 0x4d004d4d, 0x33003333, 0xfd00fdfd, 0x66006666, 0x58005858, 0x96009696, 0x3a003a3a, 0x09000909, 0x95009595, 0x10001010, 0x78007878, 0xd800d8d8, 0x42004242, 0xcc00cccc, 0xef00efef, 0x26002626, 0xe500e5e5, 0x61006161, 0x1a001a1a, 0x3f003f3f, 0x3b003b3b, 0x82008282, 0xb600b6b6, 0xdb00dbdb, 0xd400d4d4, 0x98009898, 0xe800e8e8, 0x8b008b8b, 0x02000202, 0xeb00ebeb, 0x0a000a0a, 0x2c002c2c, 0x1d001d1d, 0xb000b0b0, 0x6f006f6f, 0x8d008d8d, 0x88008888, 0x0e000e0e, 0x19001919, 0x87008787, 0x4e004e4e, 0x0b000b0b, 0xa900a9a9, 0x0c000c0c, 0x79007979, 0x11001111, 0x7f007f7f, 0x22002222, 0xe700e7e7, 0x59005959, 0xe100e1e1, 0xda00dada, 0x3d003d3d, 0xc800c8c8, 0x12001212, 0x04000404, 0x74007474, 0x54005454, 0x30003030, 0x7e007e7e, 0xb400b4b4, 0x28002828, 0x55005555, 0x68006868, 0x50005050, 0xbe00bebe, 0xd000d0d0, 0xc400c4c4, 0x31003131, 0xcb00cbcb, 0x2a002a2a, 0xad00adad, 0x0f000f0f, 0xca00caca, 0x70007070, 0xff00ffff, 0x32003232, 0x69006969, 0x08000808, 0x62006262, 0x00000000, 0x24002424, 0xd100d1d1, 0xfb00fbfb, 0xba00baba, 0xed00eded, 0x45004545, 0x81008181, 0x73007373, 0x6d006d6d, 0x84008484, 0x9f009f9f, 0xee00eeee, 0x4a004a4a, 0xc300c3c3, 0x2e002e2e, 0xc100c1c1, 0x01000101, 0xe600e6e6, 0x25002525, 0x48004848, 0x99009999, 0xb900b9b9, 0xb300b3b3, 0x7b007b7b, 0xf900f9f9, 0xce00cece, 0xbf00bfbf, 0xdf00dfdf, 0x71007171, 0x29002929, 0xcd00cdcd, 0x6c006c6c, 0x13001313, 0x64006464, 0x9b009b9b, 0x63006363, 0x9d009d9d, 0xc000c0c0, 0x4b004b4b, 0xb700b7b7, 0xa500a5a5, 0x89008989, 0x5f005f5f, 0xb100b1b1, 0x17001717, 0xf400f4f4, 0xbc00bcbc, 0xd300d3d3, 0x46004646, 0xcf00cfcf, 0x37003737, 0x5e005e5e, 0x47004747, 0x94009494, 0xfa00fafa, 0xfc00fcfc, 0x5b005b5b, 0x97009797, 0xfe00fefe, 0x5a005a5a, 0xac00acac, 0x3c003c3c, 0x4c004c4c, 0x03000303, 0x35003535, 0xf300f3f3, 0x23002323, 0xb800b8b8, 0x5d005d5d, 0x6a006a6a, 0x92009292, 0xd500d5d5, 0x21002121, 0x44004444, 0x51005151, 0xc600c6c6, 0x7d007d7d, 0x39003939, 0x83008383, 0xdc00dcdc, 0xaa00aaaa, 0x7c007c7c, 0x77007777, 0x56005656, 0x05000505, 0x1b001b1b, 0xa400a4a4, 0x15001515, 0x34003434, 0x1e001e1e, 0x1c001c1c, 0xf800f8f8, 0x52005252, 0x20002020, 0x14001414, 0xe900e9e9, 0xbd00bdbd, 0xdd00dddd, 0xe400e4e4, 0xa100a1a1, 0xe000e0e0, 0x8a008a8a, 0xf100f1f1, 0xd600d6d6, 0x7a007a7a, 0xbb00bbbb, 0xe300e3e3, 0x40004040, 0x4f004f4f }; private static int rightRotate(int x, int s) { return (((x) >>> (s)) + ((x) << (32 - s))); } private static int leftRotate(int x, int s) { return ((x) << (s)) + ((x) >>> (32 - s)); } private static void roldq(int rot, int[] ki, int ioff, int[] ko, int ooff) { ko[0 + ooff] = (ki[0 + ioff] << rot) | (ki[1 + ioff] >>> (32 - rot)); ko[1 + ooff] = (ki[1 + ioff] << rot) | (ki[2 + ioff] >>> (32 - rot)); ko[2 + ooff] = (ki[2 + ioff] << rot) | (ki[3 + ioff] >>> (32 - rot)); ko[3 + ooff] = (ki[3 + ioff] << rot) | (ki[0 + ioff] >>> (32 - rot)); ki[0 + ioff] = ko[0 + ooff]; ki[1 + ioff] = ko[1 + ooff]; ki[2 + ioff] = ko[2 + ooff]; ki[3 + ioff] = ko[3 + ooff]; } private static void decroldq(int rot, int[] ki, int ioff, int[] ko, int ooff) { ko[2 + ooff] = (ki[0 + ioff] << rot) | (ki[1 + ioff] >>> (32 - rot)); ko[3 + ooff] = (ki[1 + ioff] << rot) | (ki[2 + ioff] >>> (32 - rot)); ko[0 + ooff] = (ki[2 + ioff] << rot) | (ki[3 + ioff] >>> (32 - rot)); ko[1 + ooff] = (ki[3 + ioff] << rot) | (ki[0 + ioff] >>> (32 - rot)); ki[0 + ioff] = ko[2 + ooff]; ki[1 + ioff] = ko[3 + ooff]; ki[2 + ioff] = ko[0 + ooff]; ki[3 + ioff] = ko[1 + ooff]; } private static void roldqo32(int rot, int[] ki, int ioff, int[] ko, int ooff) { ko[0 + ooff] = (ki[1 + ioff] << (rot - 32)) | (ki[2 + ioff] >>> (64 - rot)); ko[1 + ooff] = (ki[2 + ioff] << (rot - 32)) | (ki[3 + ioff] >>> (64 - rot)); ko[2 + ooff] = (ki[3 + ioff] << (rot - 32)) | (ki[0 + ioff] >>> (64 - rot)); ko[3 + ooff] = (ki[0 + ioff] << (rot - 32)) | (ki[1 + ioff] >>> (64 - rot)); ki[0 + ioff] = ko[0 + ooff]; ki[1 + ioff] = ko[1 + ooff]; ki[2 + ioff] = ko[2 + ooff]; ki[3 + ioff] = ko[3 + ooff]; } private static void decroldqo32(int rot, int[] ki, int ioff, int[] ko, int ooff) { ko[2 + ooff] = (ki[1 + ioff] << (rot - 32)) | (ki[2 + ioff] >>> (64 - rot)); ko[3 + ooff] = (ki[2 + ioff] << (rot - 32)) | (ki[3 + ioff] >>> (64 - rot)); ko[0 + ooff] = (ki[3 + ioff] << (rot - 32)) | (ki[0 + ioff] >>> (64 - rot)); ko[1 + ooff] = (ki[0 + ioff] << (rot - 32)) | (ki[1 + ioff] >>> (64 - rot)); ki[0 + ioff] = ko[2 + ooff]; ki[1 + ioff] = ko[3 + ooff]; ki[2 + ioff] = ko[0 + ooff]; ki[3 + ioff] = ko[1 + ooff]; } private int bytes2int(byte[] src, int offset) { int word = 0; for (int i = 0; i < 4; i++) { word = (word << 8) + (src[i + offset] & MASK8); } return word; } private void int2bytes(int word, byte[] dst, int offset) { for (int i = 0; i < 4; i++) { dst[(3 - i) + offset] = (byte)word; word >>>= 8; } } private void camelliaF2(int[] s, int[] skey, int keyoff) { int t1, t2, u, v; t1 = s[0] ^ skey[0 + keyoff]; u = SBOX4_4404[t1 & MASK8]; u ^= SBOX3_3033[(t1 >>> 8) & MASK8]; u ^= SBOX2_0222[(t1 >>> 16) & MASK8]; u ^= SBOX1_1110[(t1 >>> 24) & MASK8]; t2 = s[1] ^ skey[1 + keyoff]; v = SBOX1_1110[t2 & MASK8]; v ^= SBOX4_4404[(t2 >>> 8) & MASK8]; v ^= SBOX3_3033[(t2 >>> 16) & MASK8]; v ^= SBOX2_0222[(t2 >>> 24) & MASK8]; s[2] ^= u ^ v; s[3] ^= u ^ v ^ rightRotate(u, 8); t1 = s[2] ^ skey[2 + keyoff]; u = SBOX4_4404[t1 & MASK8]; u ^= SBOX3_3033[(t1 >>> 8) & MASK8]; u ^= SBOX2_0222[(t1 >>> 16) & MASK8]; u ^= SBOX1_1110[(t1 >>> 24) & MASK8]; t2 = s[3] ^ skey[3 + keyoff]; v = SBOX1_1110[t2 & MASK8]; v ^= SBOX4_4404[(t2 >>> 8) & MASK8]; v ^= SBOX3_3033[(t2 >>> 16) & MASK8]; v ^= SBOX2_0222[(t2 >>> 24) & MASK8]; s[0] ^= u ^ v; s[1] ^= u ^ v ^ rightRotate(u, 8); } private void camelliaFLs(int[] s, int[] fkey, int keyoff) { s[1] ^= leftRotate(s[0] & fkey[0 + keyoff], 1); s[0] ^= fkey[1 + keyoff] | s[1]; s[2] ^= fkey[3 + keyoff] | s[3]; s[3] ^= leftRotate(fkey[2 + keyoff] & s[2], 1); } private void setKey(boolean forEncryption, byte[] key) { int[] k = new int[8]; int[] ka = new int[4]; int[] kb = new int[4]; int[] t = new int[4]; switch (key.length) { case 16: _keyIs128 = true; k[0] = bytes2int(key, 0); k[1] = bytes2int(key, 4); k[2] = bytes2int(key, 8); k[3] = bytes2int(key, 12); k[4] = k[5] = k[6] = k[7] = 0; break; case 24: k[0] = bytes2int(key, 0); k[1] = bytes2int(key, 4); k[2] = bytes2int(key, 8); k[3] = bytes2int(key, 12); k[4] = bytes2int(key, 16); k[5] = bytes2int(key, 20); k[6] = ~k[4]; k[7] = ~k[5]; _keyIs128 = false; break; case 32: k[0] = bytes2int(key, 0); k[1] = bytes2int(key, 4); k[2] = bytes2int(key, 8); k[3] = bytes2int(key, 12); k[4] = bytes2int(key, 16); k[5] = bytes2int(key, 20); k[6] = bytes2int(key, 24); k[7] = bytes2int(key, 28); _keyIs128 = false; break; default: throw new IllegalArgumentException("key sizes are only 16/24/32 bytes."); } for (int i = 0; i < 4; i++) { ka[i] = k[i] ^ k[i + 4]; } /* compute KA */ camelliaF2(ka, SIGMA, 0); for (int i = 0; i < 4; i++) { ka[i] ^= k[i]; } camelliaF2(ka, SIGMA, 4); if (_keyIs128) { if (forEncryption) { /* KL dependant keys */ kw[0] = k[0]; kw[1] = k[1]; kw[2] = k[2]; kw[3] = k[3]; roldq(15, k, 0, subkey, 4); roldq(30, k, 0, subkey, 12); roldq(15, k, 0, t, 0); subkey[18] = t[2]; subkey[19] = t[3]; roldq(17, k, 0, ke, 4); roldq(17, k, 0, subkey, 24); roldq(17, k, 0, subkey, 32); /* KA dependant keys */ subkey[0] = ka[0]; subkey[1] = ka[1]; subkey[2] = ka[2]; subkey[3] = ka[3]; roldq(15, ka, 0, subkey, 8); roldq(15, ka, 0, ke, 0); roldq(15, ka, 0, t, 0); subkey[16] = t[0]; subkey[17] = t[1]; roldq(15, ka, 0, subkey, 20); roldqo32(34, ka, 0, subkey, 28); roldq(17, ka, 0, kw, 4); } else { // decryption /* KL dependant keys */ kw[4] = k[0]; kw[5] = k[1]; kw[6] = k[2]; kw[7] = k[3]; decroldq(15, k, 0, subkey, 28); decroldq(30, k, 0, subkey, 20); decroldq(15, k, 0, t, 0); subkey[16] = t[0]; subkey[17] = t[1]; decroldq(17, k, 0, ke, 0); decroldq(17, k, 0, subkey, 8); decroldq(17, k, 0, subkey, 0); /* KA dependant keys */ subkey[34] = ka[0]; subkey[35] = ka[1]; subkey[32] = ka[2]; subkey[33] = ka[3]; decroldq(15, ka, 0, subkey, 24); decroldq(15, ka, 0, ke, 4); decroldq(15, ka, 0, t, 0); subkey[18] = t[2]; subkey[19] = t[3]; decroldq(15, ka, 0, subkey, 12); decroldqo32(34, ka, 0, subkey, 4); roldq(17, ka, 0, kw, 0); } } else { // 192bit or 256bit /* compute KB */ for (int i = 0; i < 4; i++) { kb[i] = ka[i] ^ k[i + 4]; } camelliaF2(kb, SIGMA, 8); if (forEncryption) { /* KL dependant keys */ kw[0] = k[0]; kw[1] = k[1]; kw[2] = k[2]; kw[3] = k[3]; roldqo32(45, k, 0, subkey, 16); roldq(15, k, 0, ke, 4); roldq(17, k, 0, subkey, 32); roldqo32(34, k, 0, subkey, 44); /* KR dependant keys */ roldq(15, k, 4, subkey, 4); roldq(15, k, 4, ke, 0); roldq(30, k, 4, subkey, 24); roldqo32(34, k, 4, subkey, 36); /* KA dependant keys */ roldq(15, ka, 0, subkey, 8); roldq(30, ka, 0, subkey, 20); /* 32bit rotation */ ke[8] = ka[1]; ke[9] = ka[2]; ke[10] = ka[3]; ke[11] = ka[0]; roldqo32(49, ka, 0, subkey, 40); /* KB dependant keys */ subkey[0] = kb[0]; subkey[1] = kb[1]; subkey[2] = kb[2]; subkey[3] = kb[3]; roldq(30, kb, 0, subkey, 12); roldq(30, kb, 0, subkey, 28); roldqo32(51, kb, 0, kw, 4); } else { // decryption /* KL dependant keys */ kw[4] = k[0]; kw[5] = k[1]; kw[6] = k[2]; kw[7] = k[3]; decroldqo32(45, k, 0, subkey, 28); decroldq(15, k, 0, ke, 4); decroldq(17, k, 0, subkey, 12); decroldqo32(34, k, 0, subkey, 0); /* KR dependant keys */ decroldq(15, k, 4, subkey, 40); decroldq(15, k, 4, ke, 8); decroldq(30, k, 4, subkey, 20); decroldqo32(34, k, 4, subkey, 8); /* KA dependant keys */ decroldq(15, ka, 0, subkey, 36); decroldq(30, ka, 0, subkey, 24); /* 32bit rotation */ ke[2] = ka[1]; ke[3] = ka[2]; ke[0] = ka[3]; ke[1] = ka[0]; decroldqo32(49, ka, 0, subkey, 4); /* KB dependant keys */ subkey[46] = kb[0]; subkey[47] = kb[1]; subkey[44] = kb[2]; subkey[45] = kb[3]; decroldq(30, kb, 0, subkey, 32); decroldq(30, kb, 0, subkey, 16); roldqo32(51, kb, 0, kw, 0); } } } private int processBlock128(byte[] in, int inOff, byte[] out, int outOff) { for (int i = 0; i < 4; i++) { state[i] = bytes2int(in, inOff + (i * 4)); state[i] ^= kw[i]; } camelliaF2(state, subkey, 0); camelliaF2(state, subkey, 4); camelliaF2(state, subkey, 8); camelliaFLs(state, ke, 0); camelliaF2(state, subkey, 12); camelliaF2(state, subkey, 16); camelliaF2(state, subkey, 20); camelliaFLs(state, ke, 4); camelliaF2(state, subkey, 24); camelliaF2(state, subkey, 28); camelliaF2(state, subkey, 32); state[2] ^= kw[4]; state[3] ^= kw[5]; state[0] ^= kw[6]; state[1] ^= kw[7]; int2bytes(state[2], out, outOff); int2bytes(state[3], out, outOff + 4); int2bytes(state[0], out, outOff + 8); int2bytes(state[1], out, outOff + 12); return BLOCK_SIZE; } private int processBlock192or256(byte[] in, int inOff, byte[] out, int outOff) { for (int i = 0; i < 4; i++) { state[i] = bytes2int(in, inOff + (i * 4)); state[i] ^= kw[i]; } camelliaF2(state, subkey, 0); camelliaF2(state, subkey, 4); camelliaF2(state, subkey, 8); camelliaFLs(state, ke, 0); camelliaF2(state, subkey, 12); camelliaF2(state, subkey, 16); camelliaF2(state, subkey, 20); camelliaFLs(state, ke, 4); camelliaF2(state, subkey, 24); camelliaF2(state, subkey, 28); camelliaF2(state, subkey, 32); camelliaFLs(state, ke, 8); camelliaF2(state, subkey, 36); camelliaF2(state, subkey, 40); camelliaF2(state, subkey, 44); state[2] ^= kw[4]; state[3] ^= kw[5]; state[0] ^= kw[6]; state[1] ^= kw[7]; int2bytes(state[2], out, outOff); int2bytes(state[3], out, outOff + 4); int2bytes(state[0], out, outOff + 8); int2bytes(state[1], out, outOff + 12); return BLOCK_SIZE; } public CamelliaEngine() { } public void init(boolean forEncryption, CipherParameters params) throws IllegalArgumentException { if (!(params instanceof KeyParameter)) { throw new IllegalArgumentException("only simple KeyParameter expected."); } setKey(forEncryption, ((KeyParameter)params).getKey()); initialised = true; } public String getAlgorithmName() { return "Camellia"; } public int getBlockSize() { return BLOCK_SIZE; } public int processBlock( byte[] in, int inOff, byte[] out, int outOff) throws DataLengthException, IllegalStateException { if (!initialised) { throw new IllegalStateException("Camellia engine not initialised"); } if ((inOff + BLOCK_SIZE) > in.length) { throw new DataLengthException("input buffer too short"); } if ((outOff + BLOCK_SIZE) > out.length) { throw new OutputLengthException("output buffer too short"); } if (_keyIs128) { return processBlock128(in, inOff, out, outOff); } else { return processBlock192or256(in, inOff, out, outOff); } } public void reset() { // nothing } } bouncycastle-1.49.orig/src/org/bouncycastle/crypto/engines/AESFastEngine.java0000644000175000017500000013324112106327602026674 0ustar ebourgebourgpackage org.bouncycastle.crypto.engines; import org.bouncycastle.crypto.BlockCipher; import org.bouncycastle.crypto.CipherParameters; import org.bouncycastle.crypto.DataLengthException; import org.bouncycastle.crypto.OutputLengthException; import org.bouncycastle.crypto.params.KeyParameter; /** * an implementation of the AES (Rijndael), from FIPS-197. *

    * For further details see: http://csrc.nist.gov/encryption/aes/. * * This implementation is based on optimizations from Dr. Brian Gladman's paper and C code at * http://fp.gladman.plus.com/cryptography_technology/rijndael/ * * There are three levels of tradeoff of speed vs memory * Because java has no preprocessor, they are written as three separate classes from which to choose * * The fastest uses 8Kbytes of static tables to precompute round calculations, 4 256 word tables for encryption * and 4 for decryption. * * The middle performance version uses only one 256 word table for each, for a total of 2Kbytes, * adding 12 rotate operations per round to compute the values contained in the other tables from * the contents of the first * * The slowest version uses no static tables at all and computes the values in each round *

    * This file contains the fast version with 8Kbytes of static tables for round precomputation * */ public class AESFastEngine implements BlockCipher { // The S box private static final byte[] S = { (byte)99, (byte)124, (byte)119, (byte)123, (byte)242, (byte)107, (byte)111, (byte)197, (byte)48, (byte)1, (byte)103, (byte)43, (byte)254, (byte)215, (byte)171, (byte)118, (byte)202, (byte)130, (byte)201, (byte)125, (byte)250, (byte)89, (byte)71, (byte)240, (byte)173, (byte)212, (byte)162, (byte)175, (byte)156, (byte)164, (byte)114, (byte)192, (byte)183, (byte)253, (byte)147, (byte)38, (byte)54, (byte)63, (byte)247, (byte)204, (byte)52, (byte)165, (byte)229, (byte)241, (byte)113, (byte)216, (byte)49, (byte)21, (byte)4, (byte)199, (byte)35, (byte)195, (byte)24, (byte)150, (byte)5, (byte)154, (byte)7, (byte)18, (byte)128, (byte)226, (byte)235, (byte)39, (byte)178, (byte)117, (byte)9, (byte)131, (byte)44, (byte)26, (byte)27, (byte)110, (byte)90, (byte)160, (byte)82, (byte)59, (byte)214, (byte)179, (byte)41, (byte)227, (byte)47, (byte)132, (byte)83, (byte)209, (byte)0, (byte)237, (byte)32, (byte)252, (byte)177, (byte)91, (byte)106, (byte)203, (byte)190, (byte)57, (byte)74, (byte)76, (byte)88, (byte)207, (byte)208, (byte)239, (byte)170, (byte)251, (byte)67, (byte)77, (byte)51, (byte)133, (byte)69, (byte)249, (byte)2, (byte)127, (byte)80, (byte)60, (byte)159, (byte)168, (byte)81, (byte)163, (byte)64, (byte)143, (byte)146, (byte)157, (byte)56, (byte)245, (byte)188, (byte)182, (byte)218, (byte)33, (byte)16, (byte)255, (byte)243, (byte)210, (byte)205, (byte)12, (byte)19, (byte)236, (byte)95, (byte)151, (byte)68, (byte)23, (byte)196, (byte)167, (byte)126, (byte)61, (byte)100, (byte)93, (byte)25, (byte)115, (byte)96, (byte)129, (byte)79, (byte)220, (byte)34, (byte)42, (byte)144, (byte)136, (byte)70, (byte)238, (byte)184, (byte)20, (byte)222, (byte)94, (byte)11, (byte)219, (byte)224, (byte)50, (byte)58, (byte)10, (byte)73, (byte)6, (byte)36, (byte)92, (byte)194, (byte)211, (byte)172, (byte)98, (byte)145, (byte)149, (byte)228, (byte)121, (byte)231, (byte)200, (byte)55, (byte)109, (byte)141, (byte)213, (byte)78, (byte)169, (byte)108, (byte)86, (byte)244, (byte)234, (byte)101, (byte)122, (byte)174, (byte)8, (byte)186, (byte)120, (byte)37, (byte)46, (byte)28, (byte)166, (byte)180, (byte)198, (byte)232, (byte)221, (byte)116, (byte)31, (byte)75, (byte)189, (byte)139, (byte)138, (byte)112, (byte)62, (byte)181, (byte)102, (byte)72, (byte)3, (byte)246, (byte)14, (byte)97, (byte)53, (byte)87, (byte)185, (byte)134, (byte)193, (byte)29, (byte)158, (byte)225, (byte)248, (byte)152, (byte)17, (byte)105, (byte)217, (byte)142, (byte)148, (byte)155, (byte)30, (byte)135, (byte)233, (byte)206, (byte)85, (byte)40, (byte)223, (byte)140, (byte)161, (byte)137, (byte)13, (byte)191, (byte)230, (byte)66, (byte)104, (byte)65, (byte)153, (byte)45, (byte)15, (byte)176, (byte)84, (byte)187, (byte)22, }; // The inverse S-box private static final byte[] Si = { (byte)82, (byte)9, (byte)106, (byte)213, (byte)48, (byte)54, (byte)165, (byte)56, (byte)191, (byte)64, (byte)163, (byte)158, (byte)129, (byte)243, (byte)215, (byte)251, (byte)124, (byte)227, (byte)57, (byte)130, (byte)155, (byte)47, (byte)255, (byte)135, (byte)52, (byte)142, (byte)67, (byte)68, (byte)196, (byte)222, (byte)233, (byte)203, (byte)84, (byte)123, (byte)148, (byte)50, (byte)166, (byte)194, (byte)35, (byte)61, (byte)238, (byte)76, (byte)149, (byte)11, (byte)66, (byte)250, (byte)195, (byte)78, (byte)8, (byte)46, (byte)161, (byte)102, (byte)40, (byte)217, (byte)36, (byte)178, (byte)118, (byte)91, (byte)162, (byte)73, (byte)109, (byte)139, (byte)209, (byte)37, (byte)114, (byte)248, (byte)246, (byte)100, (byte)134, (byte)104, (byte)152, (byte)22, (byte)212, (byte)164, (byte)92, (byte)204, (byte)93, (byte)101, (byte)182, (byte)146, (byte)108, (byte)112, (byte)72, (byte)80, (byte)253, (byte)237, (byte)185, (byte)218, (byte)94, (byte)21, (byte)70, (byte)87, (byte)167, (byte)141, (byte)157, (byte)132, (byte)144, (byte)216, (byte)171, (byte)0, (byte)140, (byte)188, (byte)211, (byte)10, (byte)247, (byte)228, (byte)88, (byte)5, (byte)184, (byte)179, (byte)69, (byte)6, (byte)208, (byte)44, (byte)30, (byte)143, (byte)202, (byte)63, (byte)15, (byte)2, (byte)193, (byte)175, (byte)189, (byte)3, (byte)1, (byte)19, (byte)138, (byte)107, (byte)58, (byte)145, (byte)17, (byte)65, (byte)79, (byte)103, (byte)220, (byte)234, (byte)151, (byte)242, (byte)207, (byte)206, (byte)240, (byte)180, (byte)230, (byte)115, (byte)150, (byte)172, (byte)116, (byte)34, (byte)231, (byte)173, (byte)53, (byte)133, (byte)226, (byte)249, (byte)55, (byte)232, (byte)28, (byte)117, (byte)223, (byte)110, (byte)71, (byte)241, (byte)26, (byte)113, (byte)29, (byte)41, (byte)197, (byte)137, (byte)111, (byte)183, (byte)98, (byte)14, (byte)170, (byte)24, (byte)190, (byte)27, (byte)252, (byte)86, (byte)62, (byte)75, (byte)198, (byte)210, (byte)121, (byte)32, (byte)154, (byte)219, (byte)192, (byte)254, (byte)120, (byte)205, (byte)90, (byte)244, (byte)31, (byte)221, (byte)168, (byte)51, (byte)136, (byte)7, (byte)199, (byte)49, (byte)177, (byte)18, (byte)16, (byte)89, (byte)39, (byte)128, (byte)236, (byte)95, (byte)96, (byte)81, (byte)127, (byte)169, (byte)25, (byte)181, (byte)74, (byte)13, (byte)45, (byte)229, (byte)122, (byte)159, (byte)147, (byte)201, (byte)156, (byte)239, (byte)160, (byte)224, (byte)59, (byte)77, (byte)174, (byte)42, (byte)245, (byte)176, (byte)200, (byte)235, (byte)187, (byte)60, (byte)131, (byte)83, (byte)153, (byte)97, (byte)23, (byte)43, (byte)4, (byte)126, (byte)186, (byte)119, (byte)214, (byte)38, (byte)225, (byte)105, (byte)20, (byte)99, (byte)85, (byte)33, (byte)12, (byte)125, }; // vector used in calculating key schedule (powers of x in GF(256)) private static final int[] rcon = { 0x01, 0x02, 0x04, 0x08, 0x10, 0x20, 0x40, 0x80, 0x1b, 0x36, 0x6c, 0xd8, 0xab, 0x4d, 0x9a, 0x2f, 0x5e, 0xbc, 0x63, 0xc6, 0x97, 0x35, 0x6a, 0xd4, 0xb3, 0x7d, 0xfa, 0xef, 0xc5, 0x91 }; // precomputation tables of calculations for rounds private static final int[] T0 = { 0xa56363c6, 0x847c7cf8, 0x997777ee, 0x8d7b7bf6, 0x0df2f2ff, 0xbd6b6bd6, 0xb16f6fde, 0x54c5c591, 0x50303060, 0x03010102, 0xa96767ce, 0x7d2b2b56, 0x19fefee7, 0x62d7d7b5, 0xe6abab4d, 0x9a7676ec, 0x45caca8f, 0x9d82821f, 0x40c9c989, 0x877d7dfa, 0x15fafaef, 0xeb5959b2, 0xc947478e, 0x0bf0f0fb, 0xecadad41, 0x67d4d4b3, 0xfda2a25f, 0xeaafaf45, 0xbf9c9c23, 0xf7a4a453, 0x967272e4, 0x5bc0c09b, 0xc2b7b775, 0x1cfdfde1, 0xae93933d, 0x6a26264c, 0x5a36366c, 0x413f3f7e, 0x02f7f7f5, 0x4fcccc83, 0x5c343468, 0xf4a5a551, 0x34e5e5d1, 0x08f1f1f9, 0x937171e2, 0x73d8d8ab, 0x53313162, 0x3f15152a, 0x0c040408, 0x52c7c795, 0x65232346, 0x5ec3c39d, 0x28181830, 0xa1969637, 0x0f05050a, 0xb59a9a2f, 0x0907070e, 0x36121224, 0x9b80801b, 0x3de2e2df, 0x26ebebcd, 0x6927274e, 0xcdb2b27f, 0x9f7575ea, 0x1b090912, 0x9e83831d, 0x742c2c58, 0x2e1a1a34, 0x2d1b1b36, 0xb26e6edc, 0xee5a5ab4, 0xfba0a05b, 0xf65252a4, 0x4d3b3b76, 0x61d6d6b7, 0xceb3b37d, 0x7b292952, 0x3ee3e3dd, 0x712f2f5e, 0x97848413, 0xf55353a6, 0x68d1d1b9, 0x00000000, 0x2cededc1, 0x60202040, 0x1ffcfce3, 0xc8b1b179, 0xed5b5bb6, 0xbe6a6ad4, 0x46cbcb8d, 0xd9bebe67, 0x4b393972, 0xde4a4a94, 0xd44c4c98, 0xe85858b0, 0x4acfcf85, 0x6bd0d0bb, 0x2aefefc5, 0xe5aaaa4f, 0x16fbfbed, 0xc5434386, 0xd74d4d9a, 0x55333366, 0x94858511, 0xcf45458a, 0x10f9f9e9, 0x06020204, 0x817f7ffe, 0xf05050a0, 0x443c3c78, 0xba9f9f25, 0xe3a8a84b, 0xf35151a2, 0xfea3a35d, 0xc0404080, 0x8a8f8f05, 0xad92923f, 0xbc9d9d21, 0x48383870, 0x04f5f5f1, 0xdfbcbc63, 0xc1b6b677, 0x75dadaaf, 0x63212142, 0x30101020, 0x1affffe5, 0x0ef3f3fd, 0x6dd2d2bf, 0x4ccdcd81, 0x140c0c18, 0x35131326, 0x2fececc3, 0xe15f5fbe, 0xa2979735, 0xcc444488, 0x3917172e, 0x57c4c493, 0xf2a7a755, 0x827e7efc, 0x473d3d7a, 0xac6464c8, 0xe75d5dba, 0x2b191932, 0x957373e6, 0xa06060c0, 0x98818119, 0xd14f4f9e, 0x7fdcdca3, 0x66222244, 0x7e2a2a54, 0xab90903b, 0x8388880b, 0xca46468c, 0x29eeeec7, 0xd3b8b86b, 0x3c141428, 0x79dedea7, 0xe25e5ebc, 0x1d0b0b16, 0x76dbdbad, 0x3be0e0db, 0x56323264, 0x4e3a3a74, 0x1e0a0a14, 0xdb494992, 0x0a06060c, 0x6c242448, 0xe45c5cb8, 0x5dc2c29f, 0x6ed3d3bd, 0xefacac43, 0xa66262c4, 0xa8919139, 0xa4959531, 0x37e4e4d3, 0x8b7979f2, 0x32e7e7d5, 0x43c8c88b, 0x5937376e, 0xb76d6dda, 0x8c8d8d01, 0x64d5d5b1, 0xd24e4e9c, 0xe0a9a949, 0xb46c6cd8, 0xfa5656ac, 0x07f4f4f3, 0x25eaeacf, 0xaf6565ca, 0x8e7a7af4, 0xe9aeae47, 0x18080810, 0xd5baba6f, 0x887878f0, 0x6f25254a, 0x722e2e5c, 0x241c1c38, 0xf1a6a657, 0xc7b4b473, 0x51c6c697, 0x23e8e8cb, 0x7cdddda1, 0x9c7474e8, 0x211f1f3e, 0xdd4b4b96, 0xdcbdbd61, 0x868b8b0d, 0x858a8a0f, 0x907070e0, 0x423e3e7c, 0xc4b5b571, 0xaa6666cc, 0xd8484890, 0x05030306, 0x01f6f6f7, 0x120e0e1c, 0xa36161c2, 0x5f35356a, 0xf95757ae, 0xd0b9b969, 0x91868617, 0x58c1c199, 0x271d1d3a, 0xb99e9e27, 0x38e1e1d9, 0x13f8f8eb, 0xb398982b, 0x33111122, 0xbb6969d2, 0x70d9d9a9, 0x898e8e07, 0xa7949433, 0xb69b9b2d, 0x221e1e3c, 0x92878715, 0x20e9e9c9, 0x49cece87, 0xff5555aa, 0x78282850, 0x7adfdfa5, 0x8f8c8c03, 0xf8a1a159, 0x80898909, 0x170d0d1a, 0xdabfbf65, 0x31e6e6d7, 0xc6424284, 0xb86868d0, 0xc3414182, 0xb0999929, 0x772d2d5a, 0x110f0f1e, 0xcbb0b07b, 0xfc5454a8, 0xd6bbbb6d, 0x3a16162c}; private static final int[] T1 = { 0x6363c6a5, 0x7c7cf884, 0x7777ee99, 0x7b7bf68d, 0xf2f2ff0d, 0x6b6bd6bd, 0x6f6fdeb1, 0xc5c59154, 0x30306050, 0x01010203, 0x6767cea9, 0x2b2b567d, 0xfefee719, 0xd7d7b562, 0xabab4de6, 0x7676ec9a, 0xcaca8f45, 0x82821f9d, 0xc9c98940, 0x7d7dfa87, 0xfafaef15, 0x5959b2eb, 0x47478ec9, 0xf0f0fb0b, 0xadad41ec, 0xd4d4b367, 0xa2a25ffd, 0xafaf45ea, 0x9c9c23bf, 0xa4a453f7, 0x7272e496, 0xc0c09b5b, 0xb7b775c2, 0xfdfde11c, 0x93933dae, 0x26264c6a, 0x36366c5a, 0x3f3f7e41, 0xf7f7f502, 0xcccc834f, 0x3434685c, 0xa5a551f4, 0xe5e5d134, 0xf1f1f908, 0x7171e293, 0xd8d8ab73, 0x31316253, 0x15152a3f, 0x0404080c, 0xc7c79552, 0x23234665, 0xc3c39d5e, 0x18183028, 0x969637a1, 0x05050a0f, 0x9a9a2fb5, 0x07070e09, 0x12122436, 0x80801b9b, 0xe2e2df3d, 0xebebcd26, 0x27274e69, 0xb2b27fcd, 0x7575ea9f, 0x0909121b, 0x83831d9e, 0x2c2c5874, 0x1a1a342e, 0x1b1b362d, 0x6e6edcb2, 0x5a5ab4ee, 0xa0a05bfb, 0x5252a4f6, 0x3b3b764d, 0xd6d6b761, 0xb3b37dce, 0x2929527b, 0xe3e3dd3e, 0x2f2f5e71, 0x84841397, 0x5353a6f5, 0xd1d1b968, 0x00000000, 0xededc12c, 0x20204060, 0xfcfce31f, 0xb1b179c8, 0x5b5bb6ed, 0x6a6ad4be, 0xcbcb8d46, 0xbebe67d9, 0x3939724b, 0x4a4a94de, 0x4c4c98d4, 0x5858b0e8, 0xcfcf854a, 0xd0d0bb6b, 0xefefc52a, 0xaaaa4fe5, 0xfbfbed16, 0x434386c5, 0x4d4d9ad7, 0x33336655, 0x85851194, 0x45458acf, 0xf9f9e910, 0x02020406, 0x7f7ffe81, 0x5050a0f0, 0x3c3c7844, 0x9f9f25ba, 0xa8a84be3, 0x5151a2f3, 0xa3a35dfe, 0x404080c0, 0x8f8f058a, 0x92923fad, 0x9d9d21bc, 0x38387048, 0xf5f5f104, 0xbcbc63df, 0xb6b677c1, 0xdadaaf75, 0x21214263, 0x10102030, 0xffffe51a, 0xf3f3fd0e, 0xd2d2bf6d, 0xcdcd814c, 0x0c0c1814, 0x13132635, 0xececc32f, 0x5f5fbee1, 0x979735a2, 0x444488cc, 0x17172e39, 0xc4c49357, 0xa7a755f2, 0x7e7efc82, 0x3d3d7a47, 0x6464c8ac, 0x5d5dbae7, 0x1919322b, 0x7373e695, 0x6060c0a0, 0x81811998, 0x4f4f9ed1, 0xdcdca37f, 0x22224466, 0x2a2a547e, 0x90903bab, 0x88880b83, 0x46468cca, 0xeeeec729, 0xb8b86bd3, 0x1414283c, 0xdedea779, 0x5e5ebce2, 0x0b0b161d, 0xdbdbad76, 0xe0e0db3b, 0x32326456, 0x3a3a744e, 0x0a0a141e, 0x494992db, 0x06060c0a, 0x2424486c, 0x5c5cb8e4, 0xc2c29f5d, 0xd3d3bd6e, 0xacac43ef, 0x6262c4a6, 0x919139a8, 0x959531a4, 0xe4e4d337, 0x7979f28b, 0xe7e7d532, 0xc8c88b43, 0x37376e59, 0x6d6ddab7, 0x8d8d018c, 0xd5d5b164, 0x4e4e9cd2, 0xa9a949e0, 0x6c6cd8b4, 0x5656acfa, 0xf4f4f307, 0xeaeacf25, 0x6565caaf, 0x7a7af48e, 0xaeae47e9, 0x08081018, 0xbaba6fd5, 0x7878f088, 0x25254a6f, 0x2e2e5c72, 0x1c1c3824, 0xa6a657f1, 0xb4b473c7, 0xc6c69751, 0xe8e8cb23, 0xdddda17c, 0x7474e89c, 0x1f1f3e21, 0x4b4b96dd, 0xbdbd61dc, 0x8b8b0d86, 0x8a8a0f85, 0x7070e090, 0x3e3e7c42, 0xb5b571c4, 0x6666ccaa, 0x484890d8, 0x03030605, 0xf6f6f701, 0x0e0e1c12, 0x6161c2a3, 0x35356a5f, 0x5757aef9, 0xb9b969d0, 0x86861791, 0xc1c19958, 0x1d1d3a27, 0x9e9e27b9, 0xe1e1d938, 0xf8f8eb13, 0x98982bb3, 0x11112233, 0x6969d2bb, 0xd9d9a970, 0x8e8e0789, 0x949433a7, 0x9b9b2db6, 0x1e1e3c22, 0x87871592, 0xe9e9c920, 0xcece8749, 0x5555aaff, 0x28285078, 0xdfdfa57a, 0x8c8c038f, 0xa1a159f8, 0x89890980, 0x0d0d1a17, 0xbfbf65da, 0xe6e6d731, 0x424284c6, 0x6868d0b8, 0x414182c3, 0x999929b0, 0x2d2d5a77, 0x0f0f1e11, 0xb0b07bcb, 0x5454a8fc, 0xbbbb6dd6, 0x16162c3a}; private static final int[] T2 = { 0x63c6a563, 0x7cf8847c, 0x77ee9977, 0x7bf68d7b, 0xf2ff0df2, 0x6bd6bd6b, 0x6fdeb16f, 0xc59154c5, 0x30605030, 0x01020301, 0x67cea967, 0x2b567d2b, 0xfee719fe, 0xd7b562d7, 0xab4de6ab, 0x76ec9a76, 0xca8f45ca, 0x821f9d82, 0xc98940c9, 0x7dfa877d, 0xfaef15fa, 0x59b2eb59, 0x478ec947, 0xf0fb0bf0, 0xad41ecad, 0xd4b367d4, 0xa25ffda2, 0xaf45eaaf, 0x9c23bf9c, 0xa453f7a4, 0x72e49672, 0xc09b5bc0, 0xb775c2b7, 0xfde11cfd, 0x933dae93, 0x264c6a26, 0x366c5a36, 0x3f7e413f, 0xf7f502f7, 0xcc834fcc, 0x34685c34, 0xa551f4a5, 0xe5d134e5, 0xf1f908f1, 0x71e29371, 0xd8ab73d8, 0x31625331, 0x152a3f15, 0x04080c04, 0xc79552c7, 0x23466523, 0xc39d5ec3, 0x18302818, 0x9637a196, 0x050a0f05, 0x9a2fb59a, 0x070e0907, 0x12243612, 0x801b9b80, 0xe2df3de2, 0xebcd26eb, 0x274e6927, 0xb27fcdb2, 0x75ea9f75, 0x09121b09, 0x831d9e83, 0x2c58742c, 0x1a342e1a, 0x1b362d1b, 0x6edcb26e, 0x5ab4ee5a, 0xa05bfba0, 0x52a4f652, 0x3b764d3b, 0xd6b761d6, 0xb37dceb3, 0x29527b29, 0xe3dd3ee3, 0x2f5e712f, 0x84139784, 0x53a6f553, 0xd1b968d1, 0x00000000, 0xedc12ced, 0x20406020, 0xfce31ffc, 0xb179c8b1, 0x5bb6ed5b, 0x6ad4be6a, 0xcb8d46cb, 0xbe67d9be, 0x39724b39, 0x4a94de4a, 0x4c98d44c, 0x58b0e858, 0xcf854acf, 0xd0bb6bd0, 0xefc52aef, 0xaa4fe5aa, 0xfbed16fb, 0x4386c543, 0x4d9ad74d, 0x33665533, 0x85119485, 0x458acf45, 0xf9e910f9, 0x02040602, 0x7ffe817f, 0x50a0f050, 0x3c78443c, 0x9f25ba9f, 0xa84be3a8, 0x51a2f351, 0xa35dfea3, 0x4080c040, 0x8f058a8f, 0x923fad92, 0x9d21bc9d, 0x38704838, 0xf5f104f5, 0xbc63dfbc, 0xb677c1b6, 0xdaaf75da, 0x21426321, 0x10203010, 0xffe51aff, 0xf3fd0ef3, 0xd2bf6dd2, 0xcd814ccd, 0x0c18140c, 0x13263513, 0xecc32fec, 0x5fbee15f, 0x9735a297, 0x4488cc44, 0x172e3917, 0xc49357c4, 0xa755f2a7, 0x7efc827e, 0x3d7a473d, 0x64c8ac64, 0x5dbae75d, 0x19322b19, 0x73e69573, 0x60c0a060, 0x81199881, 0x4f9ed14f, 0xdca37fdc, 0x22446622, 0x2a547e2a, 0x903bab90, 0x880b8388, 0x468cca46, 0xeec729ee, 0xb86bd3b8, 0x14283c14, 0xdea779de, 0x5ebce25e, 0x0b161d0b, 0xdbad76db, 0xe0db3be0, 0x32645632, 0x3a744e3a, 0x0a141e0a, 0x4992db49, 0x060c0a06, 0x24486c24, 0x5cb8e45c, 0xc29f5dc2, 0xd3bd6ed3, 0xac43efac, 0x62c4a662, 0x9139a891, 0x9531a495, 0xe4d337e4, 0x79f28b79, 0xe7d532e7, 0xc88b43c8, 0x376e5937, 0x6ddab76d, 0x8d018c8d, 0xd5b164d5, 0x4e9cd24e, 0xa949e0a9, 0x6cd8b46c, 0x56acfa56, 0xf4f307f4, 0xeacf25ea, 0x65caaf65, 0x7af48e7a, 0xae47e9ae, 0x08101808, 0xba6fd5ba, 0x78f08878, 0x254a6f25, 0x2e5c722e, 0x1c38241c, 0xa657f1a6, 0xb473c7b4, 0xc69751c6, 0xe8cb23e8, 0xdda17cdd, 0x74e89c74, 0x1f3e211f, 0x4b96dd4b, 0xbd61dcbd, 0x8b0d868b, 0x8a0f858a, 0x70e09070, 0x3e7c423e, 0xb571c4b5, 0x66ccaa66, 0x4890d848, 0x03060503, 0xf6f701f6, 0x0e1c120e, 0x61c2a361, 0x356a5f35, 0x57aef957, 0xb969d0b9, 0x86179186, 0xc19958c1, 0x1d3a271d, 0x9e27b99e, 0xe1d938e1, 0xf8eb13f8, 0x982bb398, 0x11223311, 0x69d2bb69, 0xd9a970d9, 0x8e07898e, 0x9433a794, 0x9b2db69b, 0x1e3c221e, 0x87159287, 0xe9c920e9, 0xce8749ce, 0x55aaff55, 0x28507828, 0xdfa57adf, 0x8c038f8c, 0xa159f8a1, 0x89098089, 0x0d1a170d, 0xbf65dabf, 0xe6d731e6, 0x4284c642, 0x68d0b868, 0x4182c341, 0x9929b099, 0x2d5a772d, 0x0f1e110f, 0xb07bcbb0, 0x54a8fc54, 0xbb6dd6bb, 0x162c3a16}; private static final int[] T3 = { 0xc6a56363, 0xf8847c7c, 0xee997777, 0xf68d7b7b, 0xff0df2f2, 0xd6bd6b6b, 0xdeb16f6f, 0x9154c5c5, 0x60503030, 0x02030101, 0xcea96767, 0x567d2b2b, 0xe719fefe, 0xb562d7d7, 0x4de6abab, 0xec9a7676, 0x8f45caca, 0x1f9d8282, 0x8940c9c9, 0xfa877d7d, 0xef15fafa, 0xb2eb5959, 0x8ec94747, 0xfb0bf0f0, 0x41ecadad, 0xb367d4d4, 0x5ffda2a2, 0x45eaafaf, 0x23bf9c9c, 0x53f7a4a4, 0xe4967272, 0x9b5bc0c0, 0x75c2b7b7, 0xe11cfdfd, 0x3dae9393, 0x4c6a2626, 0x6c5a3636, 0x7e413f3f, 0xf502f7f7, 0x834fcccc, 0x685c3434, 0x51f4a5a5, 0xd134e5e5, 0xf908f1f1, 0xe2937171, 0xab73d8d8, 0x62533131, 0x2a3f1515, 0x080c0404, 0x9552c7c7, 0x46652323, 0x9d5ec3c3, 0x30281818, 0x37a19696, 0x0a0f0505, 0x2fb59a9a, 0x0e090707, 0x24361212, 0x1b9b8080, 0xdf3de2e2, 0xcd26ebeb, 0x4e692727, 0x7fcdb2b2, 0xea9f7575, 0x121b0909, 0x1d9e8383, 0x58742c2c, 0x342e1a1a, 0x362d1b1b, 0xdcb26e6e, 0xb4ee5a5a, 0x5bfba0a0, 0xa4f65252, 0x764d3b3b, 0xb761d6d6, 0x7dceb3b3, 0x527b2929, 0xdd3ee3e3, 0x5e712f2f, 0x13978484, 0xa6f55353, 0xb968d1d1, 0x00000000, 0xc12ceded, 0x40602020, 0xe31ffcfc, 0x79c8b1b1, 0xb6ed5b5b, 0xd4be6a6a, 0x8d46cbcb, 0x67d9bebe, 0x724b3939, 0x94de4a4a, 0x98d44c4c, 0xb0e85858, 0x854acfcf, 0xbb6bd0d0, 0xc52aefef, 0x4fe5aaaa, 0xed16fbfb, 0x86c54343, 0x9ad74d4d, 0x66553333, 0x11948585, 0x8acf4545, 0xe910f9f9, 0x04060202, 0xfe817f7f, 0xa0f05050, 0x78443c3c, 0x25ba9f9f, 0x4be3a8a8, 0xa2f35151, 0x5dfea3a3, 0x80c04040, 0x058a8f8f, 0x3fad9292, 0x21bc9d9d, 0x70483838, 0xf104f5f5, 0x63dfbcbc, 0x77c1b6b6, 0xaf75dada, 0x42632121, 0x20301010, 0xe51affff, 0xfd0ef3f3, 0xbf6dd2d2, 0x814ccdcd, 0x18140c0c, 0x26351313, 0xc32fecec, 0xbee15f5f, 0x35a29797, 0x88cc4444, 0x2e391717, 0x9357c4c4, 0x55f2a7a7, 0xfc827e7e, 0x7a473d3d, 0xc8ac6464, 0xbae75d5d, 0x322b1919, 0xe6957373, 0xc0a06060, 0x19988181, 0x9ed14f4f, 0xa37fdcdc, 0x44662222, 0x547e2a2a, 0x3bab9090, 0x0b838888, 0x8cca4646, 0xc729eeee, 0x6bd3b8b8, 0x283c1414, 0xa779dede, 0xbce25e5e, 0x161d0b0b, 0xad76dbdb, 0xdb3be0e0, 0x64563232, 0x744e3a3a, 0x141e0a0a, 0x92db4949, 0x0c0a0606, 0x486c2424, 0xb8e45c5c, 0x9f5dc2c2, 0xbd6ed3d3, 0x43efacac, 0xc4a66262, 0x39a89191, 0x31a49595, 0xd337e4e4, 0xf28b7979, 0xd532e7e7, 0x8b43c8c8, 0x6e593737, 0xdab76d6d, 0x018c8d8d, 0xb164d5d5, 0x9cd24e4e, 0x49e0a9a9, 0xd8b46c6c, 0xacfa5656, 0xf307f4f4, 0xcf25eaea, 0xcaaf6565, 0xf48e7a7a, 0x47e9aeae, 0x10180808, 0x6fd5baba, 0xf0887878, 0x4a6f2525, 0x5c722e2e, 0x38241c1c, 0x57f1a6a6, 0x73c7b4b4, 0x9751c6c6, 0xcb23e8e8, 0xa17cdddd, 0xe89c7474, 0x3e211f1f, 0x96dd4b4b, 0x61dcbdbd, 0x0d868b8b, 0x0f858a8a, 0xe0907070, 0x7c423e3e, 0x71c4b5b5, 0xccaa6666, 0x90d84848, 0x06050303, 0xf701f6f6, 0x1c120e0e, 0xc2a36161, 0x6a5f3535, 0xaef95757, 0x69d0b9b9, 0x17918686, 0x9958c1c1, 0x3a271d1d, 0x27b99e9e, 0xd938e1e1, 0xeb13f8f8, 0x2bb39898, 0x22331111, 0xd2bb6969, 0xa970d9d9, 0x07898e8e, 0x33a79494, 0x2db69b9b, 0x3c221e1e, 0x15928787, 0xc920e9e9, 0x8749cece, 0xaaff5555, 0x50782828, 0xa57adfdf, 0x038f8c8c, 0x59f8a1a1, 0x09808989, 0x1a170d0d, 0x65dabfbf, 0xd731e6e6, 0x84c64242, 0xd0b86868, 0x82c34141, 0x29b09999, 0x5a772d2d, 0x1e110f0f, 0x7bcbb0b0, 0xa8fc5454, 0x6dd6bbbb, 0x2c3a1616}; private static final int[] Tinv0 = { 0x50a7f451, 0x5365417e, 0xc3a4171a, 0x965e273a, 0xcb6bab3b, 0xf1459d1f, 0xab58faac, 0x9303e34b, 0x55fa3020, 0xf66d76ad, 0x9176cc88, 0x254c02f5, 0xfcd7e54f, 0xd7cb2ac5, 0x80443526, 0x8fa362b5, 0x495ab1de, 0x671bba25, 0x980eea45, 0xe1c0fe5d, 0x02752fc3, 0x12f04c81, 0xa397468d, 0xc6f9d36b, 0xe75f8f03, 0x959c9215, 0xeb7a6dbf, 0xda595295, 0x2d83bed4, 0xd3217458, 0x2969e049, 0x44c8c98e, 0x6a89c275, 0x78798ef4, 0x6b3e5899, 0xdd71b927, 0xb64fe1be, 0x17ad88f0, 0x66ac20c9, 0xb43ace7d, 0x184adf63, 0x82311ae5, 0x60335197, 0x457f5362, 0xe07764b1, 0x84ae6bbb, 0x1ca081fe, 0x942b08f9, 0x58684870, 0x19fd458f, 0x876cde94, 0xb7f87b52, 0x23d373ab, 0xe2024b72, 0x578f1fe3, 0x2aab5566, 0x0728ebb2, 0x03c2b52f, 0x9a7bc586, 0xa50837d3, 0xf2872830, 0xb2a5bf23, 0xba6a0302, 0x5c8216ed, 0x2b1ccf8a, 0x92b479a7, 0xf0f207f3, 0xa1e2694e, 0xcdf4da65, 0xd5be0506, 0x1f6234d1, 0x8afea6c4, 0x9d532e34, 0xa055f3a2, 0x32e18a05, 0x75ebf6a4, 0x39ec830b, 0xaaef6040, 0x069f715e, 0x51106ebd, 0xf98a213e, 0x3d06dd96, 0xae053edd, 0x46bde64d, 0xb58d5491, 0x055dc471, 0x6fd40604, 0xff155060, 0x24fb9819, 0x97e9bdd6, 0xcc434089, 0x779ed967, 0xbd42e8b0, 0x888b8907, 0x385b19e7, 0xdbeec879, 0x470a7ca1, 0xe90f427c, 0xc91e84f8, 0x00000000, 0x83868009, 0x48ed2b32, 0xac70111e, 0x4e725a6c, 0xfbff0efd, 0x5638850f, 0x1ed5ae3d, 0x27392d36, 0x64d90f0a, 0x21a65c68, 0xd1545b9b, 0x3a2e3624, 0xb1670a0c, 0x0fe75793, 0xd296eeb4, 0x9e919b1b, 0x4fc5c080, 0xa220dc61, 0x694b775a, 0x161a121c, 0x0aba93e2, 0xe52aa0c0, 0x43e0223c, 0x1d171b12, 0x0b0d090e, 0xadc78bf2, 0xb9a8b62d, 0xc8a91e14, 0x8519f157, 0x4c0775af, 0xbbdd99ee, 0xfd607fa3, 0x9f2601f7, 0xbcf5725c, 0xc53b6644, 0x347efb5b, 0x7629438b, 0xdcc623cb, 0x68fcedb6, 0x63f1e4b8, 0xcadc31d7, 0x10856342, 0x40229713, 0x2011c684, 0x7d244a85, 0xf83dbbd2, 0x1132f9ae, 0x6da129c7, 0x4b2f9e1d, 0xf330b2dc, 0xec52860d, 0xd0e3c177, 0x6c16b32b, 0x99b970a9, 0xfa489411, 0x2264e947, 0xc48cfca8, 0x1a3ff0a0, 0xd82c7d56, 0xef903322, 0xc74e4987, 0xc1d138d9, 0xfea2ca8c, 0x360bd498, 0xcf81f5a6, 0x28de7aa5, 0x268eb7da, 0xa4bfad3f, 0xe49d3a2c, 0x0d927850, 0x9bcc5f6a, 0x62467e54, 0xc2138df6, 0xe8b8d890, 0x5ef7392e, 0xf5afc382, 0xbe805d9f, 0x7c93d069, 0xa92dd56f, 0xb31225cf, 0x3b99acc8, 0xa77d1810, 0x6e639ce8, 0x7bbb3bdb, 0x097826cd, 0xf418596e, 0x01b79aec, 0xa89a4f83, 0x656e95e6, 0x7ee6ffaa, 0x08cfbc21, 0xe6e815ef, 0xd99be7ba, 0xce366f4a, 0xd4099fea, 0xd67cb029, 0xafb2a431, 0x31233f2a, 0x3094a5c6, 0xc066a235, 0x37bc4e74, 0xa6ca82fc, 0xb0d090e0, 0x15d8a733, 0x4a9804f1, 0xf7daec41, 0x0e50cd7f, 0x2ff69117, 0x8dd64d76, 0x4db0ef43, 0x544daacc, 0xdf0496e4, 0xe3b5d19e, 0x1b886a4c, 0xb81f2cc1, 0x7f516546, 0x04ea5e9d, 0x5d358c01, 0x737487fa, 0x2e410bfb, 0x5a1d67b3, 0x52d2db92, 0x335610e9, 0x1347d66d, 0x8c61d79a, 0x7a0ca137, 0x8e14f859, 0x893c13eb, 0xee27a9ce, 0x35c961b7, 0xede51ce1, 0x3cb1477a, 0x59dfd29c, 0x3f73f255, 0x79ce1418, 0xbf37c773, 0xeacdf753, 0x5baafd5f, 0x146f3ddf, 0x86db4478, 0x81f3afca, 0x3ec468b9, 0x2c342438, 0x5f40a3c2, 0x72c31d16, 0x0c25e2bc, 0x8b493c28, 0x41950dff, 0x7101a839, 0xdeb30c08, 0x9ce4b4d8, 0x90c15664, 0x6184cb7b, 0x70b632d5, 0x745c6c48, 0x4257b8d0}; private static final int[] Tinv1 = { 0xa7f45150, 0x65417e53, 0xa4171ac3, 0x5e273a96, 0x6bab3bcb, 0x459d1ff1, 0x58faacab, 0x03e34b93, 0xfa302055, 0x6d76adf6, 0x76cc8891, 0x4c02f525, 0xd7e54ffc, 0xcb2ac5d7, 0x44352680, 0xa362b58f, 0x5ab1de49, 0x1bba2567, 0x0eea4598, 0xc0fe5de1, 0x752fc302, 0xf04c8112, 0x97468da3, 0xf9d36bc6, 0x5f8f03e7, 0x9c921595, 0x7a6dbfeb, 0x595295da, 0x83bed42d, 0x217458d3, 0x69e04929, 0xc8c98e44, 0x89c2756a, 0x798ef478, 0x3e58996b, 0x71b927dd, 0x4fe1beb6, 0xad88f017, 0xac20c966, 0x3ace7db4, 0x4adf6318, 0x311ae582, 0x33519760, 0x7f536245, 0x7764b1e0, 0xae6bbb84, 0xa081fe1c, 0x2b08f994, 0x68487058, 0xfd458f19, 0x6cde9487, 0xf87b52b7, 0xd373ab23, 0x024b72e2, 0x8f1fe357, 0xab55662a, 0x28ebb207, 0xc2b52f03, 0x7bc5869a, 0x0837d3a5, 0x872830f2, 0xa5bf23b2, 0x6a0302ba, 0x8216ed5c, 0x1ccf8a2b, 0xb479a792, 0xf207f3f0, 0xe2694ea1, 0xf4da65cd, 0xbe0506d5, 0x6234d11f, 0xfea6c48a, 0x532e349d, 0x55f3a2a0, 0xe18a0532, 0xebf6a475, 0xec830b39, 0xef6040aa, 0x9f715e06, 0x106ebd51, 0x8a213ef9, 0x06dd963d, 0x053eddae, 0xbde64d46, 0x8d5491b5, 0x5dc47105, 0xd406046f, 0x155060ff, 0xfb981924, 0xe9bdd697, 0x434089cc, 0x9ed96777, 0x42e8b0bd, 0x8b890788, 0x5b19e738, 0xeec879db, 0x0a7ca147, 0x0f427ce9, 0x1e84f8c9, 0x00000000, 0x86800983, 0xed2b3248, 0x70111eac, 0x725a6c4e, 0xff0efdfb, 0x38850f56, 0xd5ae3d1e, 0x392d3627, 0xd90f0a64, 0xa65c6821, 0x545b9bd1, 0x2e36243a, 0x670a0cb1, 0xe757930f, 0x96eeb4d2, 0x919b1b9e, 0xc5c0804f, 0x20dc61a2, 0x4b775a69, 0x1a121c16, 0xba93e20a, 0x2aa0c0e5, 0xe0223c43, 0x171b121d, 0x0d090e0b, 0xc78bf2ad, 0xa8b62db9, 0xa91e14c8, 0x19f15785, 0x0775af4c, 0xdd99eebb, 0x607fa3fd, 0x2601f79f, 0xf5725cbc, 0x3b6644c5, 0x7efb5b34, 0x29438b76, 0xc623cbdc, 0xfcedb668, 0xf1e4b863, 0xdc31d7ca, 0x85634210, 0x22971340, 0x11c68420, 0x244a857d, 0x3dbbd2f8, 0x32f9ae11, 0xa129c76d, 0x2f9e1d4b, 0x30b2dcf3, 0x52860dec, 0xe3c177d0, 0x16b32b6c, 0xb970a999, 0x489411fa, 0x64e94722, 0x8cfca8c4, 0x3ff0a01a, 0x2c7d56d8, 0x903322ef, 0x4e4987c7, 0xd138d9c1, 0xa2ca8cfe, 0x0bd49836, 0x81f5a6cf, 0xde7aa528, 0x8eb7da26, 0xbfad3fa4, 0x9d3a2ce4, 0x9278500d, 0xcc5f6a9b, 0x467e5462, 0x138df6c2, 0xb8d890e8, 0xf7392e5e, 0xafc382f5, 0x805d9fbe, 0x93d0697c, 0x2dd56fa9, 0x1225cfb3, 0x99acc83b, 0x7d1810a7, 0x639ce86e, 0xbb3bdb7b, 0x7826cd09, 0x18596ef4, 0xb79aec01, 0x9a4f83a8, 0x6e95e665, 0xe6ffaa7e, 0xcfbc2108, 0xe815efe6, 0x9be7bad9, 0x366f4ace, 0x099fead4, 0x7cb029d6, 0xb2a431af, 0x233f2a31, 0x94a5c630, 0x66a235c0, 0xbc4e7437, 0xca82fca6, 0xd090e0b0, 0xd8a73315, 0x9804f14a, 0xdaec41f7, 0x50cd7f0e, 0xf691172f, 0xd64d768d, 0xb0ef434d, 0x4daacc54, 0x0496e4df, 0xb5d19ee3, 0x886a4c1b, 0x1f2cc1b8, 0x5165467f, 0xea5e9d04, 0x358c015d, 0x7487fa73, 0x410bfb2e, 0x1d67b35a, 0xd2db9252, 0x5610e933, 0x47d66d13, 0x61d79a8c, 0x0ca1377a, 0x14f8598e, 0x3c13eb89, 0x27a9ceee, 0xc961b735, 0xe51ce1ed, 0xb1477a3c, 0xdfd29c59, 0x73f2553f, 0xce141879, 0x37c773bf, 0xcdf753ea, 0xaafd5f5b, 0x6f3ddf14, 0xdb447886, 0xf3afca81, 0xc468b93e, 0x3424382c, 0x40a3c25f, 0xc31d1672, 0x25e2bc0c, 0x493c288b, 0x950dff41, 0x01a83971, 0xb30c08de, 0xe4b4d89c, 0xc1566490, 0x84cb7b61, 0xb632d570, 0x5c6c4874, 0x57b8d042}; private static final int[] Tinv2 = { 0xf45150a7, 0x417e5365, 0x171ac3a4, 0x273a965e, 0xab3bcb6b, 0x9d1ff145, 0xfaacab58, 0xe34b9303, 0x302055fa, 0x76adf66d, 0xcc889176, 0x02f5254c, 0xe54ffcd7, 0x2ac5d7cb, 0x35268044, 0x62b58fa3, 0xb1de495a, 0xba25671b, 0xea45980e, 0xfe5de1c0, 0x2fc30275, 0x4c8112f0, 0x468da397, 0xd36bc6f9, 0x8f03e75f, 0x9215959c, 0x6dbfeb7a, 0x5295da59, 0xbed42d83, 0x7458d321, 0xe0492969, 0xc98e44c8, 0xc2756a89, 0x8ef47879, 0x58996b3e, 0xb927dd71, 0xe1beb64f, 0x88f017ad, 0x20c966ac, 0xce7db43a, 0xdf63184a, 0x1ae58231, 0x51976033, 0x5362457f, 0x64b1e077, 0x6bbb84ae, 0x81fe1ca0, 0x08f9942b, 0x48705868, 0x458f19fd, 0xde94876c, 0x7b52b7f8, 0x73ab23d3, 0x4b72e202, 0x1fe3578f, 0x55662aab, 0xebb20728, 0xb52f03c2, 0xc5869a7b, 0x37d3a508, 0x2830f287, 0xbf23b2a5, 0x0302ba6a, 0x16ed5c82, 0xcf8a2b1c, 0x79a792b4, 0x07f3f0f2, 0x694ea1e2, 0xda65cdf4, 0x0506d5be, 0x34d11f62, 0xa6c48afe, 0x2e349d53, 0xf3a2a055, 0x8a0532e1, 0xf6a475eb, 0x830b39ec, 0x6040aaef, 0x715e069f, 0x6ebd5110, 0x213ef98a, 0xdd963d06, 0x3eddae05, 0xe64d46bd, 0x5491b58d, 0xc471055d, 0x06046fd4, 0x5060ff15, 0x981924fb, 0xbdd697e9, 0x4089cc43, 0xd967779e, 0xe8b0bd42, 0x8907888b, 0x19e7385b, 0xc879dbee, 0x7ca1470a, 0x427ce90f, 0x84f8c91e, 0x00000000, 0x80098386, 0x2b3248ed, 0x111eac70, 0x5a6c4e72, 0x0efdfbff, 0x850f5638, 0xae3d1ed5, 0x2d362739, 0x0f0a64d9, 0x5c6821a6, 0x5b9bd154, 0x36243a2e, 0x0a0cb167, 0x57930fe7, 0xeeb4d296, 0x9b1b9e91, 0xc0804fc5, 0xdc61a220, 0x775a694b, 0x121c161a, 0x93e20aba, 0xa0c0e52a, 0x223c43e0, 0x1b121d17, 0x090e0b0d, 0x8bf2adc7, 0xb62db9a8, 0x1e14c8a9, 0xf1578519, 0x75af4c07, 0x99eebbdd, 0x7fa3fd60, 0x01f79f26, 0x725cbcf5, 0x6644c53b, 0xfb5b347e, 0x438b7629, 0x23cbdcc6, 0xedb668fc, 0xe4b863f1, 0x31d7cadc, 0x63421085, 0x97134022, 0xc6842011, 0x4a857d24, 0xbbd2f83d, 0xf9ae1132, 0x29c76da1, 0x9e1d4b2f, 0xb2dcf330, 0x860dec52, 0xc177d0e3, 0xb32b6c16, 0x70a999b9, 0x9411fa48, 0xe9472264, 0xfca8c48c, 0xf0a01a3f, 0x7d56d82c, 0x3322ef90, 0x4987c74e, 0x38d9c1d1, 0xca8cfea2, 0xd498360b, 0xf5a6cf81, 0x7aa528de, 0xb7da268e, 0xad3fa4bf, 0x3a2ce49d, 0x78500d92, 0x5f6a9bcc, 0x7e546246, 0x8df6c213, 0xd890e8b8, 0x392e5ef7, 0xc382f5af, 0x5d9fbe80, 0xd0697c93, 0xd56fa92d, 0x25cfb312, 0xacc83b99, 0x1810a77d, 0x9ce86e63, 0x3bdb7bbb, 0x26cd0978, 0x596ef418, 0x9aec01b7, 0x4f83a89a, 0x95e6656e, 0xffaa7ee6, 0xbc2108cf, 0x15efe6e8, 0xe7bad99b, 0x6f4ace36, 0x9fead409, 0xb029d67c, 0xa431afb2, 0x3f2a3123, 0xa5c63094, 0xa235c066, 0x4e7437bc, 0x82fca6ca, 0x90e0b0d0, 0xa73315d8, 0x04f14a98, 0xec41f7da, 0xcd7f0e50, 0x91172ff6, 0x4d768dd6, 0xef434db0, 0xaacc544d, 0x96e4df04, 0xd19ee3b5, 0x6a4c1b88, 0x2cc1b81f, 0x65467f51, 0x5e9d04ea, 0x8c015d35, 0x87fa7374, 0x0bfb2e41, 0x67b35a1d, 0xdb9252d2, 0x10e93356, 0xd66d1347, 0xd79a8c61, 0xa1377a0c, 0xf8598e14, 0x13eb893c, 0xa9ceee27, 0x61b735c9, 0x1ce1ede5, 0x477a3cb1, 0xd29c59df, 0xf2553f73, 0x141879ce, 0xc773bf37, 0xf753eacd, 0xfd5f5baa, 0x3ddf146f, 0x447886db, 0xafca81f3, 0x68b93ec4, 0x24382c34, 0xa3c25f40, 0x1d1672c3, 0xe2bc0c25, 0x3c288b49, 0x0dff4195, 0xa8397101, 0x0c08deb3, 0xb4d89ce4, 0x566490c1, 0xcb7b6184, 0x32d570b6, 0x6c48745c, 0xb8d04257}; private static final int[] Tinv3 = { 0x5150a7f4, 0x7e536541, 0x1ac3a417, 0x3a965e27, 0x3bcb6bab, 0x1ff1459d, 0xacab58fa, 0x4b9303e3, 0x2055fa30, 0xadf66d76, 0x889176cc, 0xf5254c02, 0x4ffcd7e5, 0xc5d7cb2a, 0x26804435, 0xb58fa362, 0xde495ab1, 0x25671bba, 0x45980eea, 0x5de1c0fe, 0xc302752f, 0x8112f04c, 0x8da39746, 0x6bc6f9d3, 0x03e75f8f, 0x15959c92, 0xbfeb7a6d, 0x95da5952, 0xd42d83be, 0x58d32174, 0x492969e0, 0x8e44c8c9, 0x756a89c2, 0xf478798e, 0x996b3e58, 0x27dd71b9, 0xbeb64fe1, 0xf017ad88, 0xc966ac20, 0x7db43ace, 0x63184adf, 0xe582311a, 0x97603351, 0x62457f53, 0xb1e07764, 0xbb84ae6b, 0xfe1ca081, 0xf9942b08, 0x70586848, 0x8f19fd45, 0x94876cde, 0x52b7f87b, 0xab23d373, 0x72e2024b, 0xe3578f1f, 0x662aab55, 0xb20728eb, 0x2f03c2b5, 0x869a7bc5, 0xd3a50837, 0x30f28728, 0x23b2a5bf, 0x02ba6a03, 0xed5c8216, 0x8a2b1ccf, 0xa792b479, 0xf3f0f207, 0x4ea1e269, 0x65cdf4da, 0x06d5be05, 0xd11f6234, 0xc48afea6, 0x349d532e, 0xa2a055f3, 0x0532e18a, 0xa475ebf6, 0x0b39ec83, 0x40aaef60, 0x5e069f71, 0xbd51106e, 0x3ef98a21, 0x963d06dd, 0xddae053e, 0x4d46bde6, 0x91b58d54, 0x71055dc4, 0x046fd406, 0x60ff1550, 0x1924fb98, 0xd697e9bd, 0x89cc4340, 0x67779ed9, 0xb0bd42e8, 0x07888b89, 0xe7385b19, 0x79dbeec8, 0xa1470a7c, 0x7ce90f42, 0xf8c91e84, 0x00000000, 0x09838680, 0x3248ed2b, 0x1eac7011, 0x6c4e725a, 0xfdfbff0e, 0x0f563885, 0x3d1ed5ae, 0x3627392d, 0x0a64d90f, 0x6821a65c, 0x9bd1545b, 0x243a2e36, 0x0cb1670a, 0x930fe757, 0xb4d296ee, 0x1b9e919b, 0x804fc5c0, 0x61a220dc, 0x5a694b77, 0x1c161a12, 0xe20aba93, 0xc0e52aa0, 0x3c43e022, 0x121d171b, 0x0e0b0d09, 0xf2adc78b, 0x2db9a8b6, 0x14c8a91e, 0x578519f1, 0xaf4c0775, 0xeebbdd99, 0xa3fd607f, 0xf79f2601, 0x5cbcf572, 0x44c53b66, 0x5b347efb, 0x8b762943, 0xcbdcc623, 0xb668fced, 0xb863f1e4, 0xd7cadc31, 0x42108563, 0x13402297, 0x842011c6, 0x857d244a, 0xd2f83dbb, 0xae1132f9, 0xc76da129, 0x1d4b2f9e, 0xdcf330b2, 0x0dec5286, 0x77d0e3c1, 0x2b6c16b3, 0xa999b970, 0x11fa4894, 0x472264e9, 0xa8c48cfc, 0xa01a3ff0, 0x56d82c7d, 0x22ef9033, 0x87c74e49, 0xd9c1d138, 0x8cfea2ca, 0x98360bd4, 0xa6cf81f5, 0xa528de7a, 0xda268eb7, 0x3fa4bfad, 0x2ce49d3a, 0x500d9278, 0x6a9bcc5f, 0x5462467e, 0xf6c2138d, 0x90e8b8d8, 0x2e5ef739, 0x82f5afc3, 0x9fbe805d, 0x697c93d0, 0x6fa92dd5, 0xcfb31225, 0xc83b99ac, 0x10a77d18, 0xe86e639c, 0xdb7bbb3b, 0xcd097826, 0x6ef41859, 0xec01b79a, 0x83a89a4f, 0xe6656e95, 0xaa7ee6ff, 0x2108cfbc, 0xefe6e815, 0xbad99be7, 0x4ace366f, 0xead4099f, 0x29d67cb0, 0x31afb2a4, 0x2a31233f, 0xc63094a5, 0x35c066a2, 0x7437bc4e, 0xfca6ca82, 0xe0b0d090, 0x3315d8a7, 0xf14a9804, 0x41f7daec, 0x7f0e50cd, 0x172ff691, 0x768dd64d, 0x434db0ef, 0xcc544daa, 0xe4df0496, 0x9ee3b5d1, 0x4c1b886a, 0xc1b81f2c, 0x467f5165, 0x9d04ea5e, 0x015d358c, 0xfa737487, 0xfb2e410b, 0xb35a1d67, 0x9252d2db, 0xe9335610, 0x6d1347d6, 0x9a8c61d7, 0x377a0ca1, 0x598e14f8, 0xeb893c13, 0xceee27a9, 0xb735c961, 0xe1ede51c, 0x7a3cb147, 0x9c59dfd2, 0x553f73f2, 0x1879ce14, 0x73bf37c7, 0x53eacdf7, 0x5f5baafd, 0xdf146f3d, 0x7886db44, 0xca81f3af, 0xb93ec468, 0x382c3424, 0xc25f40a3, 0x1672c31d, 0xbc0c25e2, 0x288b493c, 0xff41950d, 0x397101a8, 0x08deb30c, 0xd89ce4b4, 0x6490c156, 0x7b6184cb, 0xd570b632, 0x48745c6c, 0xd04257b8}; private static int shift(int r, int shift) { return (r >>> shift) | (r << -shift); } /* multiply four bytes in GF(2^8) by 'x' {02} in parallel */ private static final int m1 = 0x80808080; private static final int m2 = 0x7f7f7f7f; private static final int m3 = 0x0000001b; private static int FFmulX(int x) { return (((x & m2) << 1) ^ (((x & m1) >>> 7) * m3)); } /* The following defines provide alternative definitions of FFmulX that might give improved performance if a fast 32-bit multiply is not available. private int FFmulX(int x) { int u = x & m1; u |= (u >> 1); return ((x & m2) << 1) ^ ((u >>> 3) | (u >>> 6)); } private static final int m4 = 0x1b1b1b1b; private int FFmulX(int x) { int u = x & m1; return ((x & m2) << 1) ^ ((u - (u >>> 7)) & m4); } */ private static int inv_mcol(int x) { int f2 = FFmulX(x); int f4 = FFmulX(f2); int f8 = FFmulX(f4); int f9 = x ^ f8; return f2 ^ f4 ^ f8 ^ shift(f2 ^ f9, 8) ^ shift(f4 ^ f9, 16) ^ shift(f9, 24); } private static int subWord(int x) { return (S[x&255]&255 | ((S[(x>>8)&255]&255)<<8) | ((S[(x>>16)&255]&255)<<16) | S[(x>>24)&255]<<24); } /** * Calculate the necessary round keys * The number of calculations depends on key size and block size * AES specified a fixed block size of 128 bits and key sizes 128/192/256 bits * This code is written assuming those are the only possible values */ private int[][] generateWorkingKey( byte[] key, boolean forEncryption) { int KC = key.length / 4; // key length in words int t; if (((KC != 4) && (KC != 6) && (KC != 8)) || ((KC * 4) != key.length)) { throw new IllegalArgumentException("Key length not 128/192/256 bits."); } ROUNDS = KC + 6; // This is not always true for the generalized Rijndael that allows larger block sizes int[][] W = new int[ROUNDS+1][4]; // 4 words in a block // // copy the key into the round key array // t = 0; int i = 0; while (i < key.length) { W[t >> 2][t & 3] = (key[i]&0xff) | ((key[i+1]&0xff) << 8) | ((key[i+2]&0xff) << 16) | (key[i+3] << 24); i+=4; t++; } // // while not enough round key material calculated // calculate new values // int k = (ROUNDS + 1) << 2; for (i = KC; (i < k); i++) { int temp = W[(i - 1) >> 2][(i - 1) & 3]; if ((i % KC) == 0) { temp = subWord(shift(temp, 8)) ^ rcon[(i / KC) - 1]; } else if ((KC > 6) && ((i % KC) == 4)) { temp = subWord(temp); } W[i >> 2][i & 3] = W[(i - KC) >> 2][(i - KC) & 3] ^ temp; } if (!forEncryption) { for (int j = 1; j < ROUNDS; j++) { for (i = 0; i < 4; i++) { W[j][i] = inv_mcol(W[j][i]); } } } return W; } private int ROUNDS; private int[][] WorkingKey = null; private int C0, C1, C2, C3; private boolean forEncryption; private static final int BLOCK_SIZE = 16; /** * default constructor - 128 bit block size. */ public AESFastEngine() { } /** * initialise an AES cipher. * * @param forEncryption whether or not we are for encryption. * @param params the parameters required to set up the cipher. * @exception IllegalArgumentException if the params argument is * inappropriate. */ public void init( boolean forEncryption, CipherParameters params) { if (params instanceof KeyParameter) { WorkingKey = generateWorkingKey(((KeyParameter)params).getKey(), forEncryption); this.forEncryption = forEncryption; return; } throw new IllegalArgumentException("invalid parameter passed to AES init - " + params.getClass().getName()); } public String getAlgorithmName() { return "AES"; } public int getBlockSize() { return BLOCK_SIZE; } public int processBlock( byte[] in, int inOff, byte[] out, int outOff) { if (WorkingKey == null) { throw new IllegalStateException("AES engine not initialised"); } if ((inOff + (32 / 2)) > in.length) { throw new DataLengthException("input buffer too short"); } if ((outOff + (32 / 2)) > out.length) { throw new OutputLengthException("output buffer too short"); } if (forEncryption) { unpackBlock(in, inOff); encryptBlock(WorkingKey); packBlock(out, outOff); } else { unpackBlock(in, inOff); decryptBlock(WorkingKey); packBlock(out, outOff); } return BLOCK_SIZE; } public void reset() { } private void unpackBlock( byte[] bytes, int off) { int index = off; C0 = (bytes[index++] & 0xff); C0 |= (bytes[index++] & 0xff) << 8; C0 |= (bytes[index++] & 0xff) << 16; C0 |= bytes[index++] << 24; C1 = (bytes[index++] & 0xff); C1 |= (bytes[index++] & 0xff) << 8; C1 |= (bytes[index++] & 0xff) << 16; C1 |= bytes[index++] << 24; C2 = (bytes[index++] & 0xff); C2 |= (bytes[index++] & 0xff) << 8; C2 |= (bytes[index++] & 0xff) << 16; C2 |= bytes[index++] << 24; C3 = (bytes[index++] & 0xff); C3 |= (bytes[index++] & 0xff) << 8; C3 |= (bytes[index++] & 0xff) << 16; C3 |= bytes[index++] << 24; } private void packBlock( byte[] bytes, int off) { int index = off; bytes[index++] = (byte)C0; bytes[index++] = (byte)(C0 >> 8); bytes[index++] = (byte)(C0 >> 16); bytes[index++] = (byte)(C0 >> 24); bytes[index++] = (byte)C1; bytes[index++] = (byte)(C1 >> 8); bytes[index++] = (byte)(C1 >> 16); bytes[index++] = (byte)(C1 >> 24); bytes[index++] = (byte)C2; bytes[index++] = (byte)(C2 >> 8); bytes[index++] = (byte)(C2 >> 16); bytes[index++] = (byte)(C2 >> 24); bytes[index++] = (byte)C3; bytes[index++] = (byte)(C3 >> 8); bytes[index++] = (byte)(C3 >> 16); bytes[index++] = (byte)(C3 >> 24); } private void encryptBlock(int[][] KW) { int r, r0, r1, r2, r3; C0 ^= KW[0][0]; C1 ^= KW[0][1]; C2 ^= KW[0][2]; C3 ^= KW[0][3]; r = 1; while (r < ROUNDS - 1) { r0 = T0[C0&255] ^ T1[(C1>>8)&255] ^ T2[(C2>>16)&255] ^ T3[(C3>>24)&255] ^ KW[r][0]; r1 = T0[C1&255] ^ T1[(C2>>8)&255] ^ T2[(C3>>16)&255] ^ T3[(C0>>24)&255] ^ KW[r][1]; r2 = T0[C2&255] ^ T1[(C3>>8)&255] ^ T2[(C0>>16)&255] ^ T3[(C1>>24)&255] ^ KW[r][2]; r3 = T0[C3&255] ^ T1[(C0>>8)&255] ^ T2[(C1>>16)&255] ^ T3[(C2>>24)&255] ^ KW[r++][3]; C0 = T0[r0&255] ^ T1[(r1>>8)&255] ^ T2[(r2>>16)&255] ^ T3[(r3>>24)&255] ^ KW[r][0]; C1 = T0[r1&255] ^ T1[(r2>>8)&255] ^ T2[(r3>>16)&255] ^ T3[(r0>>24)&255] ^ KW[r][1]; C2 = T0[r2&255] ^ T1[(r3>>8)&255] ^ T2[(r0>>16)&255] ^ T3[(r1>>24)&255] ^ KW[r][2]; C3 = T0[r3&255] ^ T1[(r0>>8)&255] ^ T2[(r1>>16)&255] ^ T3[(r2>>24)&255] ^ KW[r++][3]; } r0 = T0[C0&255] ^ T1[(C1>>8)&255] ^ T2[(C2>>16)&255] ^ T3[(C3>>24)&255] ^ KW[r][0]; r1 = T0[C1&255] ^ T1[(C2>>8)&255] ^ T2[(C3>>16)&255] ^ T3[(C0>>24)&255] ^ KW[r][1]; r2 = T0[C2&255] ^ T1[(C3>>8)&255] ^ T2[(C0>>16)&255] ^ T3[(C1>>24)&255] ^ KW[r][2]; r3 = T0[C3&255] ^ T1[(C0>>8)&255] ^ T2[(C1>>16)&255] ^ T3[(C2>>24)&255] ^ KW[r++][3]; // the final round's table is a simple function of S so we don't use a whole other four tables for it C0 = (S[r0&255]&255) ^ ((S[(r1>>8)&255]&255)<<8) ^ ((S[(r2>>16)&255]&255)<<16) ^ (S[(r3>>24)&255]<<24) ^ KW[r][0]; C1 = (S[r1&255]&255) ^ ((S[(r2>>8)&255]&255)<<8) ^ ((S[(r3>>16)&255]&255)<<16) ^ (S[(r0>>24)&255]<<24) ^ KW[r][1]; C2 = (S[r2&255]&255) ^ ((S[(r3>>8)&255]&255)<<8) ^ ((S[(r0>>16)&255]&255)<<16) ^ (S[(r1>>24)&255]<<24) ^ KW[r][2]; C3 = (S[r3&255]&255) ^ ((S[(r0>>8)&255]&255)<<8) ^ ((S[(r1>>16)&255]&255)<<16) ^ (S[(r2>>24)&255]<<24) ^ KW[r][3]; } private void decryptBlock(int[][] KW) { int r0, r1, r2, r3; C0 ^= KW[ROUNDS][0]; C1 ^= KW[ROUNDS][1]; C2 ^= KW[ROUNDS][2]; C3 ^= KW[ROUNDS][3]; int r = ROUNDS-1; while (r>1) { r0 = Tinv0[C0&255] ^ Tinv1[(C3>>8)&255] ^ Tinv2[(C2>>16)&255] ^ Tinv3[(C1>>24)&255] ^ KW[r][0]; r1 = Tinv0[C1&255] ^ Tinv1[(C0>>8)&255] ^ Tinv2[(C3>>16)&255] ^ Tinv3[(C2>>24)&255] ^ KW[r][1]; r2 = Tinv0[C2&255] ^ Tinv1[(C1>>8)&255] ^ Tinv2[(C0>>16)&255] ^ Tinv3[(C3>>24)&255] ^ KW[r][2]; r3 = Tinv0[C3&255] ^ Tinv1[(C2>>8)&255] ^ Tinv2[(C1>>16)&255] ^ Tinv3[(C0>>24)&255] ^ KW[r--][3]; C0 = Tinv0[r0&255] ^ Tinv1[(r3>>8)&255] ^ Tinv2[(r2>>16)&255] ^ Tinv3[(r1>>24)&255] ^ KW[r][0]; C1 = Tinv0[r1&255] ^ Tinv1[(r0>>8)&255] ^ Tinv2[(r3>>16)&255] ^ Tinv3[(r2>>24)&255] ^ KW[r][1]; C2 = Tinv0[r2&255] ^ Tinv1[(r1>>8)&255] ^ Tinv2[(r0>>16)&255] ^ Tinv3[(r3>>24)&255] ^ KW[r][2]; C3 = Tinv0[r3&255] ^ Tinv1[(r2>>8)&255] ^ Tinv2[(r1>>16)&255] ^ Tinv3[(r0>>24)&255] ^ KW[r--][3]; } r0 = Tinv0[C0&255] ^ Tinv1[(C3>>8)&255] ^ Tinv2[(C2>>16)&255] ^ Tinv3[(C1>>24)&255] ^ KW[r][0]; r1 = Tinv0[C1&255] ^ Tinv1[(C0>>8)&255] ^ Tinv2[(C3>>16)&255] ^ Tinv3[(C2>>24)&255] ^ KW[r][1]; r2 = Tinv0[C2&255] ^ Tinv1[(C1>>8)&255] ^ Tinv2[(C0>>16)&255] ^ Tinv3[(C3>>24)&255] ^ KW[r][2]; r3 = Tinv0[C3&255] ^ Tinv1[(C2>>8)&255] ^ Tinv2[(C1>>16)&255] ^ Tinv3[(C0>>24)&255] ^ KW[r][3]; // the final round's table is a simple function of Si so we don't use a whole other four tables for it C0 = (Si[r0&255]&255) ^ ((Si[(r3>>8)&255]&255)<<8) ^ ((Si[(r2>>16)&255]&255)<<16) ^ (Si[(r1>>24)&255]<<24) ^ KW[0][0]; C1 = (Si[r1&255]&255) ^ ((Si[(r0>>8)&255]&255)<<8) ^ ((Si[(r3>>16)&255]&255)<<16) ^ (Si[(r2>>24)&255]<<24) ^ KW[0][1]; C2 = (Si[r2&255]&255) ^ ((Si[(r1>>8)&255]&255)<<8) ^ ((Si[(r0>>16)&255]&255)<<16) ^ (Si[(r3>>24)&255]<<24) ^ KW[0][2]; C3 = (Si[r3&255]&255) ^ ((Si[(r2>>8)&255]&255)<<8) ^ ((Si[(r1>>16)&255]&255)<<16) ^ (Si[(r0>>24)&255]<<24) ^ KW[0][3]; } } bouncycastle-1.49.orig/src/org/bouncycastle/crypto/engines/XTEAEngine.java0000644000175000017500000001075512106331472026213 0ustar ebourgebourgpackage org.bouncycastle.crypto.engines; import org.bouncycastle.crypto.BlockCipher; import org.bouncycastle.crypto.CipherParameters; import org.bouncycastle.crypto.DataLengthException; import org.bouncycastle.crypto.OutputLengthException; import org.bouncycastle.crypto.params.KeyParameter; /** * An XTEA engine. */ public class XTEAEngine implements BlockCipher { private static final int rounds = 32, block_size = 8, // key_size = 16, delta = 0x9E3779B9; /* * the expanded key array of 4 subkeys */ private int[] _S = new int[4], _sum0 = new int[32], _sum1 = new int[32]; private boolean _initialised, _forEncryption; /** * Create an instance of the TEA encryption algorithm * and set some defaults */ public XTEAEngine() { _initialised = false; } public String getAlgorithmName() { return "XTEA"; } public int getBlockSize() { return block_size; } /** * initialise * * @param forEncryption whether or not we are for encryption. * @param params the parameters required to set up the cipher. * @exception IllegalArgumentException if the params argument is * inappropriate. */ public void init( boolean forEncryption, CipherParameters params) { if (!(params instanceof KeyParameter)) { throw new IllegalArgumentException("invalid parameter passed to TEA init - " + params.getClass().getName()); } _forEncryption = forEncryption; _initialised = true; KeyParameter p = (KeyParameter)params; setKey(p.getKey()); } public int processBlock( byte[] in, int inOff, byte[] out, int outOff) { if (!_initialised) { throw new IllegalStateException(getAlgorithmName()+" not initialised"); } if ((inOff + block_size) > in.length) { throw new DataLengthException("input buffer too short"); } if ((outOff + block_size) > out.length) { throw new OutputLengthException("output buffer too short"); } return (_forEncryption) ? encryptBlock(in, inOff, out, outOff) : decryptBlock(in, inOff, out, outOff); } public void reset() { } /** * Re-key the cipher. *

    * @param key the key to be used */ private void setKey( byte[] key) { int i, j; for (i = j = 0; i < 4; i++,j+=4) { _S[i] = bytesToInt(key, j); } for (i = j = 0; i < rounds; i++) { _sum0[i] = (j + _S[j & 3]); j += delta; _sum1[i] = (j + _S[j >>> 11 & 3]); } } private int encryptBlock( byte[] in, int inOff, byte[] out, int outOff) { // Pack bytes into integers int v0 = bytesToInt(in, inOff); int v1 = bytesToInt(in, inOff + 4); for (int i = 0; i < rounds; i++) { v0 += ((v1 << 4 ^ v1 >>> 5) + v1) ^ _sum0[i]; v1 += ((v0 << 4 ^ v0 >>> 5) + v0) ^ _sum1[i]; } unpackInt(v0, out, outOff); unpackInt(v1, out, outOff + 4); return block_size; } private int decryptBlock( byte[] in, int inOff, byte[] out, int outOff) { // Pack bytes into integers int v0 = bytesToInt(in, inOff); int v1 = bytesToInt(in, inOff + 4); for (int i = rounds-1; i >= 0; i--) { v1 -= ((v0 << 4 ^ v0 >>> 5) + v0) ^ _sum1[i]; v0 -= ((v1 << 4 ^ v1 >>> 5) + v1) ^ _sum0[i]; } unpackInt(v0, out, outOff); unpackInt(v1, out, outOff + 4); return block_size; } private int bytesToInt(byte[] in, int inOff) { return ((in[inOff++]) << 24) | ((in[inOff++] & 255) << 16) | ((in[inOff++] & 255) << 8) | ((in[inOff] & 255)); } private void unpackInt(int v, byte[] out, int outOff) { out[outOff++] = (byte)(v >>> 24); out[outOff++] = (byte)(v >>> 16); out[outOff++] = (byte)(v >>> 8); out[outOff ] = (byte)v; } } bouncycastle-1.49.orig/src/org/bouncycastle/crypto/engines/IESEngine.java0000755000175000017500000002755212132370116026075 0ustar ebourgebourgpackage org.bouncycastle.crypto.engines; import java.io.ByteArrayInputStream; import java.io.IOException; import java.math.BigInteger; import org.bouncycastle.crypto.BasicAgreement; import org.bouncycastle.crypto.BufferedBlockCipher; import org.bouncycastle.crypto.CipherParameters; import org.bouncycastle.crypto.DerivationFunction; import org.bouncycastle.crypto.EphemeralKeyPair; import org.bouncycastle.crypto.InvalidCipherTextException; import org.bouncycastle.crypto.KeyParser; import org.bouncycastle.crypto.Mac; import org.bouncycastle.crypto.generators.EphemeralKeyPairGenerator; import org.bouncycastle.crypto.params.AsymmetricKeyParameter; import org.bouncycastle.crypto.params.IESParameters; import org.bouncycastle.crypto.params.IESWithCipherParameters; import org.bouncycastle.crypto.params.KDFParameters; import org.bouncycastle.crypto.params.KeyParameter; import org.bouncycastle.crypto.util.Pack; import org.bouncycastle.util.Arrays; import org.bouncycastle.util.BigIntegers; /** * Support class for constructing integrated encryption ciphers * for doing basic message exchanges on top of key agreement ciphers. * Follows the description given in IEEE Std 1363a. */ public class IESEngine { BasicAgreement agree; DerivationFunction kdf; Mac mac; BufferedBlockCipher cipher; byte[] macBuf; boolean forEncryption; CipherParameters privParam, pubParam; IESParameters param; byte[] V; private EphemeralKeyPairGenerator keyPairGenerator; private KeyParser keyParser; /** * set up for use with stream mode, where the key derivation function * is used to provide a stream of bytes to xor with the message. * * @param agree the key agreement used as the basis for the encryption * @param kdf the key derivation function used for byte generation * @param mac the message authentication code generator for the message */ public IESEngine( BasicAgreement agree, DerivationFunction kdf, Mac mac) { this.agree = agree; this.kdf = kdf; this.mac = mac; this.macBuf = new byte[mac.getMacSize()]; this.cipher = null; } /** * set up for use in conjunction with a block cipher to handle the * message. * * @param agree the key agreement used as the basis for the encryption * @param kdf the key derivation function used for byte generation * @param mac the message authentication code generator for the message * @param cipher the cipher to used for encrypting the message */ public IESEngine( BasicAgreement agree, DerivationFunction kdf, Mac mac, BufferedBlockCipher cipher) { this.agree = agree; this.kdf = kdf; this.mac = mac; this.macBuf = new byte[mac.getMacSize()]; this.cipher = cipher; } /** * Initialise the encryptor. * * @param forEncryption whether or not this is encryption/decryption. * @param privParam our private key parameters * @param pubParam the recipient's/sender's public key parameters * @param param encoding and derivation parameters. */ public void init( boolean forEncryption, CipherParameters privParam, CipherParameters pubParam, CipherParameters param) { this.forEncryption = forEncryption; this.privParam = privParam; this.pubParam = pubParam; this.param = (IESParameters)param; this.V = new byte[0]; } /** * Initialise the encryptor. * * @param publicKey the recipient's/sender's public key parameters * @param params encoding and derivation parameters. * @param ephemeralKeyPairGenerator the ephemeral key pair generator to use. */ public void init(AsymmetricKeyParameter publicKey, CipherParameters params, EphemeralKeyPairGenerator ephemeralKeyPairGenerator) { this.forEncryption = true; this.pubParam = publicKey; this.param = (IESParameters)params; this.keyPairGenerator = ephemeralKeyPairGenerator; } /** * Initialise the encryptor. * * @param privateKey the recipient's private key. * @param params encoding and derivation parameters. * @param publicKeyParser the parser for reading the ephemeral public key. */ public void init(AsymmetricKeyParameter privateKey, CipherParameters params, KeyParser publicKeyParser) { this.forEncryption = false; this.privParam = privateKey; this.param = (IESParameters)params; this.keyParser = publicKeyParser; } public BufferedBlockCipher getCipher() { return cipher; } public Mac getMac() { return mac; } private byte[] encryptBlock( byte[] in, int inOff, int inLen) throws InvalidCipherTextException { byte[] C = null, K = null, K1 = null, K2 = null; int len; if (cipher == null) { // Streaming mode. K1 = new byte[inLen]; K2 = new byte[param.getMacKeySize() / 8]; K = new byte[K1.length + K2.length]; kdf.generateBytes(K, 0, K.length); if (V.length != 0) { System.arraycopy(K, 0, K2, 0, K2.length); System.arraycopy(K, K2.length, K1, 0, K1.length); } else { System.arraycopy(K, 0, K1, 0, K1.length); System.arraycopy(K, inLen, K2, 0, K2.length); } C = new byte[inLen]; for (int i = 0; i != inLen; i++) { C[i] = (byte)(in[inOff + i] ^ K1[i]); } len = inLen; } else { // Block cipher mode. K1 = new byte[((IESWithCipherParameters)param).getCipherKeySize() / 8]; K2 = new byte[param.getMacKeySize() / 8]; K = new byte[K1.length + K2.length]; kdf.generateBytes(K, 0, K.length); System.arraycopy(K, 0, K1, 0, K1.length); System.arraycopy(K, K1.length, K2, 0, K2.length); cipher.init(true, new KeyParameter(K1)); C = new byte[cipher.getOutputSize(inLen)]; len = cipher.processBytes(in, inOff, inLen, C, 0); len += cipher.doFinal(C, len); } // Convert the length of the encoding vector into a byte array. byte[] P2 = param.getEncodingV(); byte[] L2 = new byte[4]; if (V.length != 0 && P2 != null) { Pack.intToBigEndian(P2.length * 8, L2, 0); } // Apply the MAC. byte[] T = new byte[mac.getMacSize()]; mac.init(new KeyParameter(K2)); mac.update(C, 0, C.length); if (P2 != null) { mac.update(P2, 0, P2.length); } if (V.length != 0) { mac.update(L2, 0, L2.length); } mac.doFinal(T, 0); // Output the triple (V,C,T). byte[] Output = new byte[V.length + len + T.length]; System.arraycopy(V, 0, Output, 0, V.length); System.arraycopy(C, 0, Output, V.length, len); System.arraycopy(T, 0, Output, V.length + len, T.length); return Output; } private byte[] decryptBlock( byte[] in_enc, int inOff, int inLen) throws InvalidCipherTextException { byte[] M = null, K = null, K1 = null, K2 = null; int len; if (cipher == null) { // Streaming mode. K1 = new byte[inLen - V.length - mac.getMacSize()]; K2 = new byte[param.getMacKeySize() / 8]; K = new byte[K1.length + K2.length]; kdf.generateBytes(K, 0, K.length); if (V.length != 0) { System.arraycopy(K, 0, K2, 0, K2.length); System.arraycopy(K, K2.length, K1, 0, K1.length); } else { System.arraycopy(K, 0, K1, 0, K1.length); System.arraycopy(K, K1.length, K2, 0, K2.length); } M = new byte[K1.length]; for (int i = 0; i != K1.length; i++) { M[i] = (byte)(in_enc[inOff + V.length + i] ^ K1[i]); } len = K1.length; } else { // Block cipher mode. K1 = new byte[((IESWithCipherParameters)param).getCipherKeySize() / 8]; K2 = new byte[param.getMacKeySize() / 8]; K = new byte[K1.length + K2.length]; kdf.generateBytes(K, 0, K.length); System.arraycopy(K, 0, K1, 0, K1.length); System.arraycopy(K, K1.length, K2, 0, K2.length); cipher.init(false, new KeyParameter(K1)); M = new byte[cipher.getOutputSize(inLen - V.length - mac.getMacSize())]; len = cipher.processBytes(in_enc, inOff + V.length, inLen - V.length - mac.getMacSize(), M, 0); len += cipher.doFinal(M, len); } // Convert the length of the encoding vector into a byte array. byte[] P2 = param.getEncodingV(); byte[] L2 = new byte[4]; if (V.length != 0 && P2 != null) { Pack.intToBigEndian(P2.length * 8, L2, 0); } // Verify the MAC. int end = inOff + inLen; byte[] T1 = Arrays.copyOfRange(in_enc, end - mac.getMacSize(), end); byte[] T2 = new byte[T1.length]; mac.init(new KeyParameter(K2)); mac.update(in_enc, inOff + V.length, inLen - V.length - T2.length); if (P2 != null) { mac.update(P2, 0, P2.length); } if (V.length != 0) { mac.update(L2, 0, L2.length); } mac.doFinal(T2, 0); if (!Arrays.constantTimeAreEqual(T1, T2)) { throw new InvalidCipherTextException("Invalid MAC."); } // Output the message. return Arrays.copyOfRange(M, 0, len); } public byte[] processBlock( byte[] in, int inOff, int inLen) throws InvalidCipherTextException { if (forEncryption) { if (keyPairGenerator != null) { EphemeralKeyPair ephKeyPair = keyPairGenerator.generate(); this.privParam = ephKeyPair.getKeyPair().getPrivate(); this.V = ephKeyPair.getEncodedPublicKey(); } } else { if (keyParser != null) { ByteArrayInputStream bIn = new ByteArrayInputStream(in, inOff, inLen); try { this.pubParam = keyParser.readKey(bIn); } catch (IOException e) { throw new InvalidCipherTextException("unable to recover ephemeral public key: " + e.getMessage(), e); } int encLength = (inLen - bIn.available()); this.V = Arrays.copyOfRange(in, inOff, inOff + encLength); } } // Compute the common value and convert to byte array. agree.init(privParam); BigInteger z = agree.calculateAgreement(pubParam); byte[] Z = BigIntegers.asUnsignedByteArray(agree.getFieldSize(), z); // Create input to KDF. byte[] VZ; if (V.length != 0) { VZ = new byte[V.length + Z.length]; System.arraycopy(V, 0, VZ, 0, V.length); System.arraycopy(Z, 0, VZ, V.length, Z.length); } else { VZ = Z; } // Initialise the KDF. KDFParameters kdfParam = new KDFParameters(VZ, param.getDerivationV()); kdf.init(kdfParam); return forEncryption ? encryptBlock(in, inOff, inLen) : decryptBlock(in, inOff, inLen); } } bouncycastle-1.49.orig/src/org/bouncycastle/crypto/engines/RC6Engine.java0000644000175000017500000002324512106331135026036 0ustar ebourgebourgpackage org.bouncycastle.crypto.engines; import org.bouncycastle.crypto.BlockCipher; import org.bouncycastle.crypto.CipherParameters; import org.bouncycastle.crypto.DataLengthException; import org.bouncycastle.crypto.OutputLengthException; import org.bouncycastle.crypto.params.KeyParameter; /** * An RC6 engine. */ public class RC6Engine implements BlockCipher { private static final int wordSize = 32; private static final int bytesPerWord = wordSize / 8; /* * the number of rounds to perform */ private static final int _noRounds = 20; /* * the expanded key array of size 2*(rounds + 1) */ private int _S[]; /* * our "magic constants" for wordSize 32 * * Pw = Odd((e-2) * 2^wordsize) * Qw = Odd((o-2) * 2^wordsize) * * where e is the base of natural logarithms (2.718281828...) * and o is the golden ratio (1.61803398...) */ private static final int P32 = 0xb7e15163; private static final int Q32 = 0x9e3779b9; private static final int LGW = 5; // log2(32) private boolean forEncryption; /** * Create an instance of the RC6 encryption algorithm * and set some defaults */ public RC6Engine() { _S = null; } public String getAlgorithmName() { return "RC6"; } public int getBlockSize() { return 4 * bytesPerWord; } /** * initialise a RC5-32 cipher. * * @param forEncryption whether or not we are for encryption. * @param params the parameters required to set up the cipher. * @exception IllegalArgumentException if the params argument is * inappropriate. */ public void init( boolean forEncryption, CipherParameters params) { if (!(params instanceof KeyParameter)) { throw new IllegalArgumentException("invalid parameter passed to RC6 init - " + params.getClass().getName()); } KeyParameter p = (KeyParameter)params; this.forEncryption = forEncryption; setKey(p.getKey()); } public int processBlock( byte[] in, int inOff, byte[] out, int outOff) { int blockSize = getBlockSize(); if (_S == null) { throw new IllegalStateException("RC6 engine not initialised"); } if ((inOff + blockSize) > in.length) { throw new DataLengthException("input buffer too short"); } if ((outOff + blockSize) > out.length) { throw new OutputLengthException("output buffer too short"); } return (forEncryption) ? encryptBlock(in, inOff, out, outOff) : decryptBlock(in, inOff, out, outOff); } public void reset() { } /** * Re-key the cipher. *

    * @param key the key to be used */ private void setKey( byte[] key) { // // KEY EXPANSION: // // There are 3 phases to the key expansion. // // Phase 1: // Copy the secret key K[0...b-1] into an array L[0..c-1] of // c = ceil(b/u), where u = wordSize/8 in little-endian order. // In other words, we fill up L using u consecutive key bytes // of K. Any unfilled byte positions in L are zeroed. In the // case that b = c = 0, set c = 1 and L[0] = 0. // // compute number of dwords int c = (key.length + (bytesPerWord - 1)) / bytesPerWord; if (c == 0) { c = 1; } int[] L = new int[(key.length + bytesPerWord - 1) / bytesPerWord]; // load all key bytes into array of key dwords for (int i = key.length - 1; i >= 0; i--) { L[i / bytesPerWord] = (L[i / bytesPerWord] << 8) + (key[i] & 0xff); } // // Phase 2: // Key schedule is placed in a array of 2+2*ROUNDS+2 = 44 dwords. // Initialize S to a particular fixed pseudo-random bit pattern // using an arithmetic progression modulo 2^wordsize determined // by the magic numbers, Pw & Qw. // _S = new int[2+2*_noRounds+2]; _S[0] = P32; for (int i=1; i < _S.length; i++) { _S[i] = (_S[i-1] + Q32); } // // Phase 3: // Mix in the user's secret key in 3 passes over the arrays S & L. // The max of the arrays sizes is used as the loop control // int iter; if (L.length > _S.length) { iter = 3 * L.length; } else { iter = 3 * _S.length; } int A = 0; int B = 0; int i = 0, j = 0; for (int k = 0; k < iter; k++) { A = _S[i] = rotateLeft(_S[i] + A + B, 3); B = L[j] = rotateLeft(L[j] + A + B, A+B); i = (i+1) % _S.length; j = (j+1) % L.length; } } private int encryptBlock( byte[] in, int inOff, byte[] out, int outOff) { // load A,B,C and D registers from in. int A = bytesToWord(in, inOff); int B = bytesToWord(in, inOff + bytesPerWord); int C = bytesToWord(in, inOff + bytesPerWord*2); int D = bytesToWord(in, inOff + bytesPerWord*3); // Do pseudo-round #0: pre-whitening of B and D B += _S[0]; D += _S[1]; // perform round #1,#2 ... #ROUNDS of encryption for (int i = 1; i <= _noRounds; i++) { int t = 0,u = 0; t = B*(2*B+1); t = rotateLeft(t,5); u = D*(2*D+1); u = rotateLeft(u,5); A ^= t; A = rotateLeft(A,u); A += _S[2*i]; C ^= u; C = rotateLeft(C,t); C += _S[2*i+1]; int temp = A; A = B; B = C; C = D; D = temp; } // do pseudo-round #(ROUNDS+1) : post-whitening of A and C A += _S[2*_noRounds+2]; C += _S[2*_noRounds+3]; // store A, B, C and D registers to out wordToBytes(A, out, outOff); wordToBytes(B, out, outOff + bytesPerWord); wordToBytes(C, out, outOff + bytesPerWord*2); wordToBytes(D, out, outOff + bytesPerWord*3); return 4 * bytesPerWord; } private int decryptBlock( byte[] in, int inOff, byte[] out, int outOff) { // load A,B,C and D registers from out. int A = bytesToWord(in, inOff); int B = bytesToWord(in, inOff + bytesPerWord); int C = bytesToWord(in, inOff + bytesPerWord*2); int D = bytesToWord(in, inOff + bytesPerWord*3); // Undo pseudo-round #(ROUNDS+1) : post whitening of A and C C -= _S[2*_noRounds+3]; A -= _S[2*_noRounds+2]; // Undo round #ROUNDS, .., #2,#1 of encryption for (int i = _noRounds; i >= 1; i--) { int t=0,u = 0; int temp = D; D = C; C = B; B = A; A = temp; t = B*(2*B+1); t = rotateLeft(t, LGW); u = D*(2*D+1); u = rotateLeft(u, LGW); C -= _S[2*i+1]; C = rotateRight(C,t); C ^= u; A -= _S[2*i]; A = rotateRight(A,u); A ^= t; } // Undo pseudo-round #0: pre-whitening of B and D D -= _S[1]; B -= _S[0]; wordToBytes(A, out, outOff); wordToBytes(B, out, outOff + bytesPerWord); wordToBytes(C, out, outOff + bytesPerWord*2); wordToBytes(D, out, outOff + bytesPerWord*3); return 4 * bytesPerWord; } ////////////////////////////////////////////////////////////// // // PRIVATE Helper Methods // ////////////////////////////////////////////////////////////// /** * Perform a left "spin" of the word. The rotation of the given * word x is rotated left by y bits. * Only the lg(wordSize) low-order bits of y * are used to determine the rotation amount. Here it is * assumed that the wordsize used is 32. *

    * @param x word to rotate * @param y number of bits to rotate % wordSize */ private int rotateLeft(int x, int y) { return (x << y) | (x >>> -y); } /** * Perform a right "spin" of the word. The rotation of the given * word x is rotated left by y bits. * Only the lg(wordSize) low-order bits of y * are used to determine the rotation amount. Here it is * assumed that the wordsize used is a power of 2. *

    * @param x word to rotate * @param y number of bits to rotate % wordSize */ private int rotateRight(int x, int y) { return (x >>> y) | (x << -y); } private int bytesToWord( byte[] src, int srcOff) { int word = 0; for (int i = bytesPerWord - 1; i >= 0; i--) { word = (word << 8) + (src[i + srcOff] & 0xff); } return word; } private void wordToBytes( int word, byte[] dst, int dstOff) { for (int i = 0; i < bytesPerWord; i++) { dst[i + dstOff] = (byte)word; word >>>= 8; } } } bouncycastle-1.49.orig/src/org/bouncycastle/crypto/engines/CamelliaWrapEngine.java0000644000175000017500000000061410564225562030014 0ustar ebourgebourgpackage org.bouncycastle.crypto.engines; /** * An implementation of the Camellia key wrapper based on RFC 3657/RFC 3394. *

    * For further details see: http://www.ietf.org/rfc/rfc3657.txt. */ public class CamelliaWrapEngine extends RFC3394WrapEngine { public CamelliaWrapEngine() { super(new CamelliaEngine()); } } bouncycastle-1.49.orig/src/org/bouncycastle/crypto/engines/SerpentEngine.java0000644000175000017500000006557512106331365027105 0ustar ebourgebourgpackage org.bouncycastle.crypto.engines; import org.bouncycastle.crypto.BlockCipher; import org.bouncycastle.crypto.CipherParameters; import org.bouncycastle.crypto.DataLengthException; import org.bouncycastle.crypto.OutputLengthException; import org.bouncycastle.crypto.params.KeyParameter; /** * Serpent is a 128-bit 32-round block cipher with variable key lengths, * including 128, 192 and 256 bit keys conjectured to be at least as * secure as three-key triple-DES. *

    * Serpent was designed by Ross Anderson, Eli Biham and Lars Knudsen as a * candidate algorithm for the NIST AES Quest.> *

    * For full details see the The Serpent home page */ public class SerpentEngine implements BlockCipher { private static final int BLOCK_SIZE = 16; static final int ROUNDS = 32; static final int PHI = 0x9E3779B9; // (sqrt(5) - 1) * 2**31 private boolean encrypting; private int[] wKey; private int X0, X1, X2, X3; // registers /** * initialise a Serpent cipher. * * @param encrypting whether or not we are for encryption. * @param params the parameters required to set up the cipher. * @exception IllegalArgumentException if the params argument is * inappropriate. */ public void init( boolean encrypting, CipherParameters params) { if (params instanceof KeyParameter) { this.encrypting = encrypting; this.wKey = makeWorkingKey(((KeyParameter)params).getKey()); return; } throw new IllegalArgumentException("invalid parameter passed to Serpent init - " + params.getClass().getName()); } public String getAlgorithmName() { return "Serpent"; } public int getBlockSize() { return BLOCK_SIZE; } /** * Process one block of input from the array in and write it to * the out array. * * @param in the array containing the input data. * @param inOff offset into the in array the data starts at. * @param out the array the output data will be copied into. * @param outOff the offset into the out array the output will start at. * @exception DataLengthException if there isn't enough data in in, or * space in out. * @exception IllegalStateException if the cipher isn't initialised. * @return the number of bytes processed and produced. */ public final int processBlock( byte[] in, int inOff, byte[] out, int outOff) { if (wKey == null) { throw new IllegalStateException("Serpent not initialised"); } if ((inOff + BLOCK_SIZE) > in.length) { throw new DataLengthException("input buffer too short"); } if ((outOff + BLOCK_SIZE) > out.length) { throw new OutputLengthException("output buffer too short"); } if (encrypting) { encryptBlock(in, inOff, out, outOff); } else { decryptBlock(in, inOff, out, outOff); } return BLOCK_SIZE; } public void reset() { } /** * Expand a user-supplied key material into a session key. * * @param key The user-key bytes (multiples of 4) to use. * @exception IllegalArgumentException */ private int[] makeWorkingKey( byte[] key) throws IllegalArgumentException { // // pad key to 256 bits // int[] kPad = new int[16]; int off = 0; int length = 0; for (off = key.length - 4; off > 0; off -= 4) { kPad[length++] = bytesToWord(key, off); } if (off == 0) { kPad[length++] = bytesToWord(key, 0); if (length < 8) { kPad[length] = 1; } } else { throw new IllegalArgumentException("key must be a multiple of 4 bytes"); } // // expand the padded key up to 33 x 128 bits of key material // int amount = (ROUNDS + 1) * 4; int[] w = new int[amount]; // // compute w0 to w7 from w-8 to w-1 // for (int i = 8; i < 16; i++) { kPad[i] = rotateLeft(kPad[i - 8] ^ kPad[i - 5] ^ kPad[i - 3] ^ kPad[i - 1] ^ PHI ^ (i - 8), 11); } System.arraycopy(kPad, 8, w, 0, 8); // // compute w8 to w136 // for (int i = 8; i < amount; i++) { w[i] = rotateLeft(w[i - 8] ^ w[i - 5] ^ w[i - 3] ^ w[i - 1] ^ PHI ^ i, 11); } // // create the working keys by processing w with the Sbox and IP // sb3(w[0], w[1], w[2], w[3]); w[0] = X0; w[1] = X1; w[2] = X2; w[3] = X3; sb2(w[4], w[5], w[6], w[7]); w[4] = X0; w[5] = X1; w[6] = X2; w[7] = X3; sb1(w[8], w[9], w[10], w[11]); w[8] = X0; w[9] = X1; w[10] = X2; w[11] = X3; sb0(w[12], w[13], w[14], w[15]); w[12] = X0; w[13] = X1; w[14] = X2; w[15] = X3; sb7(w[16], w[17], w[18], w[19]); w[16] = X0; w[17] = X1; w[18] = X2; w[19] = X3; sb6(w[20], w[21], w[22], w[23]); w[20] = X0; w[21] = X1; w[22] = X2; w[23] = X3; sb5(w[24], w[25], w[26], w[27]); w[24] = X0; w[25] = X1; w[26] = X2; w[27] = X3; sb4(w[28], w[29], w[30], w[31]); w[28] = X0; w[29] = X1; w[30] = X2; w[31] = X3; sb3(w[32], w[33], w[34], w[35]); w[32] = X0; w[33] = X1; w[34] = X2; w[35] = X3; sb2(w[36], w[37], w[38], w[39]); w[36] = X0; w[37] = X1; w[38] = X2; w[39] = X3; sb1(w[40], w[41], w[42], w[43]); w[40] = X0; w[41] = X1; w[42] = X2; w[43] = X3; sb0(w[44], w[45], w[46], w[47]); w[44] = X0; w[45] = X1; w[46] = X2; w[47] = X3; sb7(w[48], w[49], w[50], w[51]); w[48] = X0; w[49] = X1; w[50] = X2; w[51] = X3; sb6(w[52], w[53], w[54], w[55]); w[52] = X0; w[53] = X1; w[54] = X2; w[55] = X3; sb5(w[56], w[57], w[58], w[59]); w[56] = X0; w[57] = X1; w[58] = X2; w[59] = X3; sb4(w[60], w[61], w[62], w[63]); w[60] = X0; w[61] = X1; w[62] = X2; w[63] = X3; sb3(w[64], w[65], w[66], w[67]); w[64] = X0; w[65] = X1; w[66] = X2; w[67] = X3; sb2(w[68], w[69], w[70], w[71]); w[68] = X0; w[69] = X1; w[70] = X2; w[71] = X3; sb1(w[72], w[73], w[74], w[75]); w[72] = X0; w[73] = X1; w[74] = X2; w[75] = X3; sb0(w[76], w[77], w[78], w[79]); w[76] = X0; w[77] = X1; w[78] = X2; w[79] = X3; sb7(w[80], w[81], w[82], w[83]); w[80] = X0; w[81] = X1; w[82] = X2; w[83] = X3; sb6(w[84], w[85], w[86], w[87]); w[84] = X0; w[85] = X1; w[86] = X2; w[87] = X3; sb5(w[88], w[89], w[90], w[91]); w[88] = X0; w[89] = X1; w[90] = X2; w[91] = X3; sb4(w[92], w[93], w[94], w[95]); w[92] = X0; w[93] = X1; w[94] = X2; w[95] = X3; sb3(w[96], w[97], w[98], w[99]); w[96] = X0; w[97] = X1; w[98] = X2; w[99] = X3; sb2(w[100], w[101], w[102], w[103]); w[100] = X0; w[101] = X1; w[102] = X2; w[103] = X3; sb1(w[104], w[105], w[106], w[107]); w[104] = X0; w[105] = X1; w[106] = X2; w[107] = X3; sb0(w[108], w[109], w[110], w[111]); w[108] = X0; w[109] = X1; w[110] = X2; w[111] = X3; sb7(w[112], w[113], w[114], w[115]); w[112] = X0; w[113] = X1; w[114] = X2; w[115] = X3; sb6(w[116], w[117], w[118], w[119]); w[116] = X0; w[117] = X1; w[118] = X2; w[119] = X3; sb5(w[120], w[121], w[122], w[123]); w[120] = X0; w[121] = X1; w[122] = X2; w[123] = X3; sb4(w[124], w[125], w[126], w[127]); w[124] = X0; w[125] = X1; w[126] = X2; w[127] = X3; sb3(w[128], w[129], w[130], w[131]); w[128] = X0; w[129] = X1; w[130] = X2; w[131] = X3; return w; } private int rotateLeft( int x, int bits) { return (x << bits) | (x >>> -bits); } private int rotateRight( int x, int bits) { return (x >>> bits) | (x << -bits); } private int bytesToWord( byte[] src, int srcOff) { return (((src[srcOff] & 0xff) << 24) | ((src[srcOff + 1] & 0xff) << 16) | ((src[srcOff + 2] & 0xff) << 8) | ((src[srcOff + 3] & 0xff))); } private void wordToBytes( int word, byte[] dst, int dstOff) { dst[dstOff + 3] = (byte)(word); dst[dstOff + 2] = (byte)(word >>> 8); dst[dstOff + 1] = (byte)(word >>> 16); dst[dstOff] = (byte)(word >>> 24); } /** * Encrypt one block of plaintext. * * @param in the array containing the input data. * @param inOff offset into the in array the data starts at. * @param out the array the output data will be copied into. * @param outOff the offset into the out array the output will start at. */ private void encryptBlock( byte[] in, int inOff, byte[] out, int outOff) { X3 = bytesToWord(in, inOff); X2 = bytesToWord(in, inOff + 4); X1 = bytesToWord(in, inOff + 8); X0 = bytesToWord(in, inOff + 12); sb0(wKey[0] ^ X0, wKey[1] ^ X1, wKey[2] ^ X2, wKey[3] ^ X3); LT(); sb1(wKey[4] ^ X0, wKey[5] ^ X1, wKey[6] ^ X2, wKey[7] ^ X3); LT(); sb2(wKey[8] ^ X0, wKey[9] ^ X1, wKey[10] ^ X2, wKey[11] ^ X3); LT(); sb3(wKey[12] ^ X0, wKey[13] ^ X1, wKey[14] ^ X2, wKey[15] ^ X3); LT(); sb4(wKey[16] ^ X0, wKey[17] ^ X1, wKey[18] ^ X2, wKey[19] ^ X3); LT(); sb5(wKey[20] ^ X0, wKey[21] ^ X1, wKey[22] ^ X2, wKey[23] ^ X3); LT(); sb6(wKey[24] ^ X0, wKey[25] ^ X1, wKey[26] ^ X2, wKey[27] ^ X3); LT(); sb7(wKey[28] ^ X0, wKey[29] ^ X1, wKey[30] ^ X2, wKey[31] ^ X3); LT(); sb0(wKey[32] ^ X0, wKey[33] ^ X1, wKey[34] ^ X2, wKey[35] ^ X3); LT(); sb1(wKey[36] ^ X0, wKey[37] ^ X1, wKey[38] ^ X2, wKey[39] ^ X3); LT(); sb2(wKey[40] ^ X0, wKey[41] ^ X1, wKey[42] ^ X2, wKey[43] ^ X3); LT(); sb3(wKey[44] ^ X0, wKey[45] ^ X1, wKey[46] ^ X2, wKey[47] ^ X3); LT(); sb4(wKey[48] ^ X0, wKey[49] ^ X1, wKey[50] ^ X2, wKey[51] ^ X3); LT(); sb5(wKey[52] ^ X0, wKey[53] ^ X1, wKey[54] ^ X2, wKey[55] ^ X3); LT(); sb6(wKey[56] ^ X0, wKey[57] ^ X1, wKey[58] ^ X2, wKey[59] ^ X3); LT(); sb7(wKey[60] ^ X0, wKey[61] ^ X1, wKey[62] ^ X2, wKey[63] ^ X3); LT(); sb0(wKey[64] ^ X0, wKey[65] ^ X1, wKey[66] ^ X2, wKey[67] ^ X3); LT(); sb1(wKey[68] ^ X0, wKey[69] ^ X1, wKey[70] ^ X2, wKey[71] ^ X3); LT(); sb2(wKey[72] ^ X0, wKey[73] ^ X1, wKey[74] ^ X2, wKey[75] ^ X3); LT(); sb3(wKey[76] ^ X0, wKey[77] ^ X1, wKey[78] ^ X2, wKey[79] ^ X3); LT(); sb4(wKey[80] ^ X0, wKey[81] ^ X1, wKey[82] ^ X2, wKey[83] ^ X3); LT(); sb5(wKey[84] ^ X0, wKey[85] ^ X1, wKey[86] ^ X2, wKey[87] ^ X3); LT(); sb6(wKey[88] ^ X0, wKey[89] ^ X1, wKey[90] ^ X2, wKey[91] ^ X3); LT(); sb7(wKey[92] ^ X0, wKey[93] ^ X1, wKey[94] ^ X2, wKey[95] ^ X3); LT(); sb0(wKey[96] ^ X0, wKey[97] ^ X1, wKey[98] ^ X2, wKey[99] ^ X3); LT(); sb1(wKey[100] ^ X0, wKey[101] ^ X1, wKey[102] ^ X2, wKey[103] ^ X3); LT(); sb2(wKey[104] ^ X0, wKey[105] ^ X1, wKey[106] ^ X2, wKey[107] ^ X3); LT(); sb3(wKey[108] ^ X0, wKey[109] ^ X1, wKey[110] ^ X2, wKey[111] ^ X3); LT(); sb4(wKey[112] ^ X0, wKey[113] ^ X1, wKey[114] ^ X2, wKey[115] ^ X3); LT(); sb5(wKey[116] ^ X0, wKey[117] ^ X1, wKey[118] ^ X2, wKey[119] ^ X3); LT(); sb6(wKey[120] ^ X0, wKey[121] ^ X1, wKey[122] ^ X2, wKey[123] ^ X3); LT(); sb7(wKey[124] ^ X0, wKey[125] ^ X1, wKey[126] ^ X2, wKey[127] ^ X3); wordToBytes(wKey[131] ^ X3, out, outOff); wordToBytes(wKey[130] ^ X2, out, outOff + 4); wordToBytes(wKey[129] ^ X1, out, outOff + 8); wordToBytes(wKey[128] ^ X0, out, outOff + 12); } /** * Decrypt one block of ciphertext. * * @param in the array containing the input data. * @param inOff offset into the in array the data starts at. * @param out the array the output data will be copied into. * @param outOff the offset into the out array the output will start at. */ private void decryptBlock( byte[] in, int inOff, byte[] out, int outOff) { X3 = wKey[131] ^ bytesToWord(in, inOff); X2 = wKey[130] ^ bytesToWord(in, inOff + 4); X1 = wKey[129] ^ bytesToWord(in, inOff + 8); X0 = wKey[128] ^ bytesToWord(in, inOff + 12); ib7(X0, X1, X2, X3); X0 ^= wKey[124]; X1 ^= wKey[125]; X2 ^= wKey[126]; X3 ^= wKey[127]; inverseLT(); ib6(X0, X1, X2, X3); X0 ^= wKey[120]; X1 ^= wKey[121]; X2 ^= wKey[122]; X3 ^= wKey[123]; inverseLT(); ib5(X0, X1, X2, X3); X0 ^= wKey[116]; X1 ^= wKey[117]; X2 ^= wKey[118]; X3 ^= wKey[119]; inverseLT(); ib4(X0, X1, X2, X3); X0 ^= wKey[112]; X1 ^= wKey[113]; X2 ^= wKey[114]; X3 ^= wKey[115]; inverseLT(); ib3(X0, X1, X2, X3); X0 ^= wKey[108]; X1 ^= wKey[109]; X2 ^= wKey[110]; X3 ^= wKey[111]; inverseLT(); ib2(X0, X1, X2, X3); X0 ^= wKey[104]; X1 ^= wKey[105]; X2 ^= wKey[106]; X3 ^= wKey[107]; inverseLT(); ib1(X0, X1, X2, X3); X0 ^= wKey[100]; X1 ^= wKey[101]; X2 ^= wKey[102]; X3 ^= wKey[103]; inverseLT(); ib0(X0, X1, X2, X3); X0 ^= wKey[96]; X1 ^= wKey[97]; X2 ^= wKey[98]; X3 ^= wKey[99]; inverseLT(); ib7(X0, X1, X2, X3); X0 ^= wKey[92]; X1 ^= wKey[93]; X2 ^= wKey[94]; X3 ^= wKey[95]; inverseLT(); ib6(X0, X1, X2, X3); X0 ^= wKey[88]; X1 ^= wKey[89]; X2 ^= wKey[90]; X3 ^= wKey[91]; inverseLT(); ib5(X0, X1, X2, X3); X0 ^= wKey[84]; X1 ^= wKey[85]; X2 ^= wKey[86]; X3 ^= wKey[87]; inverseLT(); ib4(X0, X1, X2, X3); X0 ^= wKey[80]; X1 ^= wKey[81]; X2 ^= wKey[82]; X3 ^= wKey[83]; inverseLT(); ib3(X0, X1, X2, X3); X0 ^= wKey[76]; X1 ^= wKey[77]; X2 ^= wKey[78]; X3 ^= wKey[79]; inverseLT(); ib2(X0, X1, X2, X3); X0 ^= wKey[72]; X1 ^= wKey[73]; X2 ^= wKey[74]; X3 ^= wKey[75]; inverseLT(); ib1(X0, X1, X2, X3); X0 ^= wKey[68]; X1 ^= wKey[69]; X2 ^= wKey[70]; X3 ^= wKey[71]; inverseLT(); ib0(X0, X1, X2, X3); X0 ^= wKey[64]; X1 ^= wKey[65]; X2 ^= wKey[66]; X3 ^= wKey[67]; inverseLT(); ib7(X0, X1, X2, X3); X0 ^= wKey[60]; X1 ^= wKey[61]; X2 ^= wKey[62]; X3 ^= wKey[63]; inverseLT(); ib6(X0, X1, X2, X3); X0 ^= wKey[56]; X1 ^= wKey[57]; X2 ^= wKey[58]; X3 ^= wKey[59]; inverseLT(); ib5(X0, X1, X2, X3); X0 ^= wKey[52]; X1 ^= wKey[53]; X2 ^= wKey[54]; X3 ^= wKey[55]; inverseLT(); ib4(X0, X1, X2, X3); X0 ^= wKey[48]; X1 ^= wKey[49]; X2 ^= wKey[50]; X3 ^= wKey[51]; inverseLT(); ib3(X0, X1, X2, X3); X0 ^= wKey[44]; X1 ^= wKey[45]; X2 ^= wKey[46]; X3 ^= wKey[47]; inverseLT(); ib2(X0, X1, X2, X3); X0 ^= wKey[40]; X1 ^= wKey[41]; X2 ^= wKey[42]; X3 ^= wKey[43]; inverseLT(); ib1(X0, X1, X2, X3); X0 ^= wKey[36]; X1 ^= wKey[37]; X2 ^= wKey[38]; X3 ^= wKey[39]; inverseLT(); ib0(X0, X1, X2, X3); X0 ^= wKey[32]; X1 ^= wKey[33]; X2 ^= wKey[34]; X3 ^= wKey[35]; inverseLT(); ib7(X0, X1, X2, X3); X0 ^= wKey[28]; X1 ^= wKey[29]; X2 ^= wKey[30]; X3 ^= wKey[31]; inverseLT(); ib6(X0, X1, X2, X3); X0 ^= wKey[24]; X1 ^= wKey[25]; X2 ^= wKey[26]; X3 ^= wKey[27]; inverseLT(); ib5(X0, X1, X2, X3); X0 ^= wKey[20]; X1 ^= wKey[21]; X2 ^= wKey[22]; X3 ^= wKey[23]; inverseLT(); ib4(X0, X1, X2, X3); X0 ^= wKey[16]; X1 ^= wKey[17]; X2 ^= wKey[18]; X3 ^= wKey[19]; inverseLT(); ib3(X0, X1, X2, X3); X0 ^= wKey[12]; X1 ^= wKey[13]; X2 ^= wKey[14]; X3 ^= wKey[15]; inverseLT(); ib2(X0, X1, X2, X3); X0 ^= wKey[8]; X1 ^= wKey[9]; X2 ^= wKey[10]; X3 ^= wKey[11]; inverseLT(); ib1(X0, X1, X2, X3); X0 ^= wKey[4]; X1 ^= wKey[5]; X2 ^= wKey[6]; X3 ^= wKey[7]; inverseLT(); ib0(X0, X1, X2, X3); wordToBytes(X3 ^ wKey[3], out, outOff); wordToBytes(X2 ^ wKey[2], out, outOff + 4); wordToBytes(X1 ^ wKey[1], out, outOff + 8); wordToBytes(X0 ^ wKey[0], out, outOff + 12); } /** * The sboxes below are based on the work of Brian Gladman and * Sam Simpson, whose original notice appears below. *

    * For further details see: * http://fp.gladman.plus.com/cryptography_technology/serpent/ */ /* Partially optimised Serpent S Box boolean functions derived */ /* using a recursive descent analyser but without a full search */ /* of all subtrees. This set of S boxes is the result of work */ /* by Sam Simpson and Brian Gladman using the spare time on a */ /* cluster of high capacity servers to search for S boxes with */ /* this customised search engine. There are now an average of */ /* 15.375 terms per S box. */ /* */ /* Copyright: Dr B. R Gladman (gladman@seven77.demon.co.uk) */ /* and Sam Simpson (s.simpson@mia.co.uk) */ /* 17th December 1998 */ /* */ /* We hereby give permission for information in this file to be */ /* used freely subject only to acknowledgement of its origin. */ /** * S0 - { 3, 8,15, 1,10, 6, 5,11,14,13, 4, 2, 7, 0, 9,12 } - 15 terms. */ private void sb0(int a, int b, int c, int d) { int t1 = a ^ d; int t3 = c ^ t1; int t4 = b ^ t3; X3 = (a & d) ^ t4; int t7 = a ^ (b & t1); X2 = t4 ^ (c | t7); int t12 = X3 & (t3 ^ t7); X1 = (~t3) ^ t12; X0 = t12 ^ (~t7); } /** * InvSO - {13, 3,11, 0,10, 6, 5,12, 1,14, 4, 7,15, 9, 8, 2 } - 15 terms. */ private void ib0(int a, int b, int c, int d) { int t1 = ~a; int t2 = a ^ b; int t4 = d ^ (t1 | t2); int t5 = c ^ t4; X2 = t2 ^ t5; int t8 = t1 ^ (d & t2); X1 = t4 ^ (X2 & t8); X3 = (a & t4) ^ (t5 | X1); X0 = X3 ^ (t5 ^ t8); } /** * S1 - {15,12, 2, 7, 9, 0, 5,10, 1,11,14, 8, 6,13, 3, 4 } - 14 terms. */ private void sb1(int a, int b, int c, int d) { int t2 = b ^ (~a); int t5 = c ^ (a | t2); X2 = d ^ t5; int t7 = b ^ (d | t2); int t8 = t2 ^ X2; X3 = t8 ^ (t5 & t7); int t11 = t5 ^ t7; X1 = X3 ^ t11; X0 = t5 ^ (t8 & t11); } /** * InvS1 - { 5, 8, 2,14,15, 6,12, 3,11, 4, 7, 9, 1,13,10, 0 } - 14 steps. */ private void ib1(int a, int b, int c, int d) { int t1 = b ^ d; int t3 = a ^ (b & t1); int t4 = t1 ^ t3; X3 = c ^ t4; int t7 = b ^ (t1 & t3); int t8 = X3 | t7; X1 = t3 ^ t8; int t10 = ~X1; int t11 = X3 ^ t7; X0 = t10 ^ t11; X2 = t4 ^ (t10 | t11); } /** * S2 - { 8, 6, 7, 9, 3,12,10,15,13, 1,14, 4, 0,11, 5, 2 } - 16 terms. */ private void sb2(int a, int b, int c, int d) { int t1 = ~a; int t2 = b ^ d; int t3 = c & t1; X0 = t2 ^ t3; int t5 = c ^ t1; int t6 = c ^ X0; int t7 = b & t6; X3 = t5 ^ t7; X2 = a ^ ((d | t7) & (X0 | t5)); X1 = (t2 ^ X3) ^ (X2 ^ (d | t1)); } /** * InvS2 - {12, 9,15, 4,11,14, 1, 2, 0, 3, 6,13, 5, 8,10, 7 } - 16 steps. */ private void ib2(int a, int b, int c, int d) { int t1 = b ^ d; int t2 = ~t1; int t3 = a ^ c; int t4 = c ^ t1; int t5 = b & t4; X0 = t3 ^ t5; int t7 = a | t2; int t8 = d ^ t7; int t9 = t3 | t8; X3 = t1 ^ t9; int t11 = ~t4; int t12 = X0 | X3; X1 = t11 ^ t12; X2 = (d & t11) ^ (t3 ^ t12); } /** * S3 - { 0,15,11, 8,12, 9, 6, 3,13, 1, 2, 4,10, 7, 5,14 } - 16 terms. */ private void sb3(int a, int b, int c, int d) { int t1 = a ^ b; int t2 = a & c; int t3 = a | d; int t4 = c ^ d; int t5 = t1 & t3; int t6 = t2 | t5; X2 = t4 ^ t6; int t8 = b ^ t3; int t9 = t6 ^ t8; int t10 = t4 & t9; X0 = t1 ^ t10; int t12 = X2 & X0; X1 = t9 ^ t12; X3 = (b | d) ^ (t4 ^ t12); } /** * InvS3 - { 0, 9,10, 7,11,14, 6,13, 3, 5,12, 2, 4, 8,15, 1 } - 15 terms */ private void ib3(int a, int b, int c, int d) { int t1 = a | b; int t2 = b ^ c; int t3 = b & t2; int t4 = a ^ t3; int t5 = c ^ t4; int t6 = d | t4; X0 = t2 ^ t6; int t8 = t2 | t6; int t9 = d ^ t8; X2 = t5 ^ t9; int t11 = t1 ^ t9; int t12 = X0 & t11; X3 = t4 ^ t12; X1 = X3 ^ (X0 ^ t11); } /** * S4 - { 1,15, 8, 3,12, 0,11, 6, 2, 5, 4,10, 9,14, 7,13 } - 15 terms. */ private void sb4(int a, int b, int c, int d) { int t1 = a ^ d; int t2 = d & t1; int t3 = c ^ t2; int t4 = b | t3; X3 = t1 ^ t4; int t6 = ~b; int t7 = t1 | t6; X0 = t3 ^ t7; int t9 = a & X0; int t10 = t1 ^ t6; int t11 = t4 & t10; X2 = t9 ^ t11; X1 = (a ^ t3) ^ (t10 & X2); } /** * InvS4 - { 5, 0, 8, 3,10, 9, 7,14, 2,12,11, 6, 4,15,13, 1 } - 15 terms. */ private void ib4(int a, int b, int c, int d) { int t1 = c | d; int t2 = a & t1; int t3 = b ^ t2; int t4 = a & t3; int t5 = c ^ t4; X1 = d ^ t5; int t7 = ~a; int t8 = t5 & X1; X3 = t3 ^ t8; int t10 = X1 | t7; int t11 = d ^ t10; X0 = X3 ^ t11; X2 = (t3 & t11) ^ (X1 ^ t7); } /** * S5 - {15, 5, 2,11, 4,10, 9,12, 0, 3,14, 8,13, 6, 7, 1 } - 16 terms. */ private void sb5(int a, int b, int c, int d) { int t1 = ~a; int t2 = a ^ b; int t3 = a ^ d; int t4 = c ^ t1; int t5 = t2 | t3; X0 = t4 ^ t5; int t7 = d & X0; int t8 = t2 ^ X0; X1 = t7 ^ t8; int t10 = t1 | X0; int t11 = t2 | t7; int t12 = t3 ^ t10; X2 = t11 ^ t12; X3 = (b ^ t7) ^ (X1 & t12); } /** * InvS5 - { 8,15, 2, 9, 4, 1,13,14,11, 6, 5, 3, 7,12,10, 0 } - 16 terms. */ private void ib5(int a, int b, int c, int d) { int t1 = ~c; int t2 = b & t1; int t3 = d ^ t2; int t4 = a & t3; int t5 = b ^ t1; X3 = t4 ^ t5; int t7 = b | X3; int t8 = a & t7; X1 = t3 ^ t8; int t10 = a | d; int t11 = t1 ^ t7; X0 = t10 ^ t11; X2 = (b & t10) ^ (t4 | (a ^ c)); } /** * S6 - { 7, 2,12, 5, 8, 4, 6,11,14, 9, 1,15,13, 3,10, 0 } - 15 terms. */ private void sb6(int a, int b, int c, int d) { int t1 = ~a; int t2 = a ^ d; int t3 = b ^ t2; int t4 = t1 | t2; int t5 = c ^ t4; X1 = b ^ t5; int t7 = t2 | X1; int t8 = d ^ t7; int t9 = t5 & t8; X2 = t3 ^ t9; int t11 = t5 ^ t8; X0 = X2 ^ t11; X3 = (~t5) ^ (t3 & t11); } /** * InvS6 - {15,10, 1,13, 5, 3, 6, 0, 4, 9,14, 7, 2,12, 8,11 } - 15 terms. */ private void ib6(int a, int b, int c, int d) { int t1 = ~a; int t2 = a ^ b; int t3 = c ^ t2; int t4 = c | t1; int t5 = d ^ t4; X1 = t3 ^ t5; int t7 = t3 & t5; int t8 = t2 ^ t7; int t9 = b | t8; X3 = t5 ^ t9; int t11 = b | X3; X0 = t8 ^ t11; X2 = (d & t1) ^ (t3 ^ t11); } /** * S7 - { 1,13,15, 0,14, 8, 2,11, 7, 4,12,10, 9, 3, 5, 6 } - 16 terms. */ private void sb7(int a, int b, int c, int d) { int t1 = b ^ c; int t2 = c & t1; int t3 = d ^ t2; int t4 = a ^ t3; int t5 = d | t1; int t6 = t4 & t5; X1 = b ^ t6; int t8 = t3 | X1; int t9 = a & t4; X3 = t1 ^ t9; int t11 = t4 ^ t8; int t12 = X3 & t11; X2 = t3 ^ t12; X0 = (~t11) ^ (X3 & X2); } /** * InvS7 - { 3, 0, 6,13, 9,14,15, 8, 5,12,11, 7,10, 1, 4, 2 } - 17 terms. */ private void ib7(int a, int b, int c, int d) { int t3 = c | (a & b); int t4 = d & (a | b); X3 = t3 ^ t4; int t6 = ~d; int t7 = b ^ t4; int t9 = t7 | (X3 ^ t6); X1 = a ^ t9; X0 = (c ^ t7) ^ (d | X1); X2 = (t3 ^ X1) ^ (X0 ^ (a & X3)); } /** * Apply the linear transformation to the register set. */ private void LT() { int x0 = rotateLeft(X0, 13); int x2 = rotateLeft(X2, 3); int x1 = X1 ^ x0 ^ x2 ; int x3 = X3 ^ x2 ^ x0 << 3; X1 = rotateLeft(x1, 1); X3 = rotateLeft(x3, 7); X0 = rotateLeft(x0 ^ X1 ^ X3, 5); X2 = rotateLeft(x2 ^ X3 ^ (X1 << 7), 22); } /** * Apply the inverse of the linear transformation to the register set. */ private void inverseLT() { int x2 = rotateRight(X2, 22) ^ X3 ^ (X1 << 7); int x0 = rotateRight(X0, 5) ^ X1 ^ X3; int x3 = rotateRight(X3, 7); int x1 = rotateRight(X1, 1); X3 = x3 ^ x2 ^ x0 << 3; X1 = x1 ^ x0 ^ x2; X2 = rotateRight(x2, 3); X0 = rotateRight(x0, 13); } } bouncycastle-1.49.orig/src/org/bouncycastle/crypto/engines/ElGamalEngine.java0000644000175000017500000001547610742022530026755 0ustar ebourgebourgpackage org.bouncycastle.crypto.engines; import org.bouncycastle.crypto.AsymmetricBlockCipher; import org.bouncycastle.crypto.CipherParameters; import org.bouncycastle.crypto.DataLengthException; import org.bouncycastle.crypto.params.ElGamalKeyParameters; import org.bouncycastle.crypto.params.ElGamalPrivateKeyParameters; import org.bouncycastle.crypto.params.ElGamalPublicKeyParameters; import org.bouncycastle.crypto.params.ParametersWithRandom; import org.bouncycastle.util.BigIntegers; import java.math.BigInteger; import java.security.SecureRandom; /** * this does your basic ElGamal algorithm. */ public class ElGamalEngine implements AsymmetricBlockCipher { private ElGamalKeyParameters key; private SecureRandom random; private boolean forEncryption; private int bitSize; private static final BigInteger ZERO = BigInteger.valueOf(0); private static final BigInteger ONE = BigInteger.valueOf(1); private static final BigInteger TWO = BigInteger.valueOf(2); /** * initialise the ElGamal engine. * * @param forEncryption true if we are encrypting, false otherwise. * @param param the necessary ElGamal key parameters. */ public void init( boolean forEncryption, CipherParameters param) { if (param instanceof ParametersWithRandom) { ParametersWithRandom p = (ParametersWithRandom)param; this.key = (ElGamalKeyParameters)p.getParameters(); this.random = p.getRandom(); } else { this.key = (ElGamalKeyParameters)param; this.random = new SecureRandom(); } this.forEncryption = forEncryption; BigInteger p = key.getParameters().getP(); bitSize = p.bitLength(); if (forEncryption) { if (!(key instanceof ElGamalPublicKeyParameters)) { throw new IllegalArgumentException("ElGamalPublicKeyParameters are required for encryption."); } } else { if (!(key instanceof ElGamalPrivateKeyParameters)) { throw new IllegalArgumentException("ElGamalPrivateKeyParameters are required for decryption."); } } } /** * Return the maximum size for an input block to this engine. * For ElGamal this is always one byte less than the size of P on * encryption, and twice the length as the size of P on decryption. * * @return maximum size for an input block. */ public int getInputBlockSize() { if (forEncryption) { return (bitSize - 1) / 8; } return 2 * ((bitSize + 7) / 8); } /** * Return the maximum size for an output block to this engine. * For ElGamal this is always one byte less than the size of P on * decryption, and twice the length as the size of P on encryption. * * @return maximum size for an output block. */ public int getOutputBlockSize() { if (forEncryption) { return 2 * ((bitSize + 7) / 8); } return (bitSize - 1) / 8; } /** * Process a single block using the basic ElGamal algorithm. * * @param in the input array. * @param inOff the offset into the input buffer where the data starts. * @param inLen the length of the data to be processed. * @return the result of the ElGamal process. * @exception DataLengthException the input block is too large. */ public byte[] processBlock( byte[] in, int inOff, int inLen) { if (key == null) { throw new IllegalStateException("ElGamal engine not initialised"); } int maxLength = forEncryption ? (bitSize - 1 + 7) / 8 : getInputBlockSize(); if (inLen > maxLength) { throw new DataLengthException("input too large for ElGamal cipher.\n"); } BigInteger p = key.getParameters().getP(); if (key instanceof ElGamalPrivateKeyParameters) // decryption { byte[] in1 = new byte[inLen / 2]; byte[] in2 = new byte[inLen / 2]; System.arraycopy(in, inOff, in1, 0, in1.length); System.arraycopy(in, inOff + in1.length, in2, 0, in2.length); BigInteger gamma = new BigInteger(1, in1); BigInteger phi = new BigInteger(1, in2); ElGamalPrivateKeyParameters priv = (ElGamalPrivateKeyParameters)key; // a shortcut, which generally relies on p being prime amongst other things. // if a problem with this shows up, check the p and g values! BigInteger m = gamma.modPow(p.subtract(ONE).subtract(priv.getX()), p).multiply(phi).mod(p); return BigIntegers.asUnsignedByteArray(m); } else // encryption { byte[] block; if (inOff != 0 || inLen != in.length) { block = new byte[inLen]; System.arraycopy(in, inOff, block, 0, inLen); } else { block = in; } BigInteger input = new BigInteger(1, block); if (input.bitLength() >= p.bitLength()) { throw new DataLengthException("input too large for ElGamal cipher.\n"); } ElGamalPublicKeyParameters pub = (ElGamalPublicKeyParameters)key; int pBitLength = p.bitLength(); BigInteger k = new BigInteger(pBitLength, random); while (k.equals(ZERO) || (k.compareTo(p.subtract(TWO)) > 0)) { k = new BigInteger(pBitLength, random); } BigInteger g = key.getParameters().getG(); BigInteger gamma = g.modPow(k, p); BigInteger phi = input.multiply(pub.getY().modPow(k, p)).mod(p); byte[] out1 = gamma.toByteArray(); byte[] out2 = phi.toByteArray(); byte[] output = new byte[this.getOutputBlockSize()]; if (out1.length > output.length / 2) { System.arraycopy(out1, 1, output, output.length / 2 - (out1.length - 1), out1.length - 1); } else { System.arraycopy(out1, 0, output, output.length / 2 - out1.length, out1.length); } if (out2.length > output.length / 2) { System.arraycopy(out2, 1, output, output.length - (out2.length - 1), out2.length - 1); } else { System.arraycopy(out2, 0, output, output.length - out2.length, out2.length); } return output; } } } bouncycastle-1.49.orig/src/org/bouncycastle/crypto/engines/TwofishEngine.java0000644000175000017500000006060712106331425027074 0ustar ebourgebourgpackage org.bouncycastle.crypto.engines; import org.bouncycastle.crypto.BlockCipher; import org.bouncycastle.crypto.CipherParameters; import org.bouncycastle.crypto.DataLengthException; import org.bouncycastle.crypto.OutputLengthException; import org.bouncycastle.crypto.params.KeyParameter; /** * A class that provides Twofish encryption operations. * * This Java implementation is based on the Java reference * implementation provided by Bruce Schneier and developed * by Raif S. Naffah. */ public final class TwofishEngine implements BlockCipher { private static final byte[][] P = { { // p0 (byte) 0xA9, (byte) 0x67, (byte) 0xB3, (byte) 0xE8, (byte) 0x04, (byte) 0xFD, (byte) 0xA3, (byte) 0x76, (byte) 0x9A, (byte) 0x92, (byte) 0x80, (byte) 0x78, (byte) 0xE4, (byte) 0xDD, (byte) 0xD1, (byte) 0x38, (byte) 0x0D, (byte) 0xC6, (byte) 0x35, (byte) 0x98, (byte) 0x18, (byte) 0xF7, (byte) 0xEC, (byte) 0x6C, (byte) 0x43, (byte) 0x75, (byte) 0x37, (byte) 0x26, (byte) 0xFA, (byte) 0x13, (byte) 0x94, (byte) 0x48, (byte) 0xF2, (byte) 0xD0, (byte) 0x8B, (byte) 0x30, (byte) 0x84, (byte) 0x54, (byte) 0xDF, (byte) 0x23, (byte) 0x19, (byte) 0x5B, (byte) 0x3D, (byte) 0x59, (byte) 0xF3, (byte) 0xAE, (byte) 0xA2, (byte) 0x82, (byte) 0x63, (byte) 0x01, (byte) 0x83, (byte) 0x2E, (byte) 0xD9, (byte) 0x51, (byte) 0x9B, (byte) 0x7C, (byte) 0xA6, (byte) 0xEB, (byte) 0xA5, (byte) 0xBE, (byte) 0x16, (byte) 0x0C, (byte) 0xE3, (byte) 0x61, (byte) 0xC0, (byte) 0x8C, (byte) 0x3A, (byte) 0xF5, (byte) 0x73, (byte) 0x2C, (byte) 0x25, (byte) 0x0B, (byte) 0xBB, (byte) 0x4E, (byte) 0x89, (byte) 0x6B, (byte) 0x53, (byte) 0x6A, (byte) 0xB4, (byte) 0xF1, (byte) 0xE1, (byte) 0xE6, (byte) 0xBD, (byte) 0x45, (byte) 0xE2, (byte) 0xF4, (byte) 0xB6, (byte) 0x66, (byte) 0xCC, (byte) 0x95, (byte) 0x03, (byte) 0x56, (byte) 0xD4, (byte) 0x1C, (byte) 0x1E, (byte) 0xD7, (byte) 0xFB, (byte) 0xC3, (byte) 0x8E, (byte) 0xB5, (byte) 0xE9, (byte) 0xCF, (byte) 0xBF, (byte) 0xBA, (byte) 0xEA, (byte) 0x77, (byte) 0x39, (byte) 0xAF, (byte) 0x33, (byte) 0xC9, (byte) 0x62, (byte) 0x71, (byte) 0x81, (byte) 0x79, (byte) 0x09, (byte) 0xAD, (byte) 0x24, (byte) 0xCD, (byte) 0xF9, (byte) 0xD8, (byte) 0xE5, (byte) 0xC5, (byte) 0xB9, (byte) 0x4D, (byte) 0x44, (byte) 0x08, (byte) 0x86, (byte) 0xE7, (byte) 0xA1, (byte) 0x1D, (byte) 0xAA, (byte) 0xED, (byte) 0x06, (byte) 0x70, (byte) 0xB2, (byte) 0xD2, (byte) 0x41, (byte) 0x7B, (byte) 0xA0, (byte) 0x11, (byte) 0x31, (byte) 0xC2, (byte) 0x27, (byte) 0x90, (byte) 0x20, (byte) 0xF6, (byte) 0x60, (byte) 0xFF, (byte) 0x96, (byte) 0x5C, (byte) 0xB1, (byte) 0xAB, (byte) 0x9E, (byte) 0x9C, (byte) 0x52, (byte) 0x1B, (byte) 0x5F, (byte) 0x93, (byte) 0x0A, (byte) 0xEF, (byte) 0x91, (byte) 0x85, (byte) 0x49, (byte) 0xEE, (byte) 0x2D, (byte) 0x4F, (byte) 0x8F, (byte) 0x3B, (byte) 0x47, (byte) 0x87, (byte) 0x6D, (byte) 0x46, (byte) 0xD6, (byte) 0x3E, (byte) 0x69, (byte) 0x64, (byte) 0x2A, (byte) 0xCE, (byte) 0xCB, (byte) 0x2F, (byte) 0xFC, (byte) 0x97, (byte) 0x05, (byte) 0x7A, (byte) 0xAC, (byte) 0x7F, (byte) 0xD5, (byte) 0x1A, (byte) 0x4B, (byte) 0x0E, (byte) 0xA7, (byte) 0x5A, (byte) 0x28, (byte) 0x14, (byte) 0x3F, (byte) 0x29, (byte) 0x88, (byte) 0x3C, (byte) 0x4C, (byte) 0x02, (byte) 0xB8, (byte) 0xDA, (byte) 0xB0, (byte) 0x17, (byte) 0x55, (byte) 0x1F, (byte) 0x8A, (byte) 0x7D, (byte) 0x57, (byte) 0xC7, (byte) 0x8D, (byte) 0x74, (byte) 0xB7, (byte) 0xC4, (byte) 0x9F, (byte) 0x72, (byte) 0x7E, (byte) 0x15, (byte) 0x22, (byte) 0x12, (byte) 0x58, (byte) 0x07, (byte) 0x99, (byte) 0x34, (byte) 0x6E, (byte) 0x50, (byte) 0xDE, (byte) 0x68, (byte) 0x65, (byte) 0xBC, (byte) 0xDB, (byte) 0xF8, (byte) 0xC8, (byte) 0xA8, (byte) 0x2B, (byte) 0x40, (byte) 0xDC, (byte) 0xFE, (byte) 0x32, (byte) 0xA4, (byte) 0xCA, (byte) 0x10, (byte) 0x21, (byte) 0xF0, (byte) 0xD3, (byte) 0x5D, (byte) 0x0F, (byte) 0x00, (byte) 0x6F, (byte) 0x9D, (byte) 0x36, (byte) 0x42, (byte) 0x4A, (byte) 0x5E, (byte) 0xC1, (byte) 0xE0 }, { // p1 (byte) 0x75, (byte) 0xF3, (byte) 0xC6, (byte) 0xF4, (byte) 0xDB, (byte) 0x7B, (byte) 0xFB, (byte) 0xC8, (byte) 0x4A, (byte) 0xD3, (byte) 0xE6, (byte) 0x6B, (byte) 0x45, (byte) 0x7D, (byte) 0xE8, (byte) 0x4B, (byte) 0xD6, (byte) 0x32, (byte) 0xD8, (byte) 0xFD, (byte) 0x37, (byte) 0x71, (byte) 0xF1, (byte) 0xE1, (byte) 0x30, (byte) 0x0F, (byte) 0xF8, (byte) 0x1B, (byte) 0x87, (byte) 0xFA, (byte) 0x06, (byte) 0x3F, (byte) 0x5E, (byte) 0xBA, (byte) 0xAE, (byte) 0x5B, (byte) 0x8A, (byte) 0x00, (byte) 0xBC, (byte) 0x9D, (byte) 0x6D, (byte) 0xC1, (byte) 0xB1, (byte) 0x0E, (byte) 0x80, (byte) 0x5D, (byte) 0xD2, (byte) 0xD5, (byte) 0xA0, (byte) 0x84, (byte) 0x07, (byte) 0x14, (byte) 0xB5, (byte) 0x90, (byte) 0x2C, (byte) 0xA3, (byte) 0xB2, (byte) 0x73, (byte) 0x4C, (byte) 0x54, (byte) 0x92, (byte) 0x74, (byte) 0x36, (byte) 0x51, (byte) 0x38, (byte) 0xB0, (byte) 0xBD, (byte) 0x5A, (byte) 0xFC, (byte) 0x60, (byte) 0x62, (byte) 0x96, (byte) 0x6C, (byte) 0x42, (byte) 0xF7, (byte) 0x10, (byte) 0x7C, (byte) 0x28, (byte) 0x27, (byte) 0x8C, (byte) 0x13, (byte) 0x95, (byte) 0x9C, (byte) 0xC7, (byte) 0x24, (byte) 0x46, (byte) 0x3B, (byte) 0x70, (byte) 0xCA, (byte) 0xE3, (byte) 0x85, (byte) 0xCB, (byte) 0x11, (byte) 0xD0, (byte) 0x93, (byte) 0xB8, (byte) 0xA6, (byte) 0x83, (byte) 0x20, (byte) 0xFF, (byte) 0x9F, (byte) 0x77, (byte) 0xC3, (byte) 0xCC, (byte) 0x03, (byte) 0x6F, (byte) 0x08, (byte) 0xBF, (byte) 0x40, (byte) 0xE7, (byte) 0x2B, (byte) 0xE2, (byte) 0x79, (byte) 0x0C, (byte) 0xAA, (byte) 0x82, (byte) 0x41, (byte) 0x3A, (byte) 0xEA, (byte) 0xB9, (byte) 0xE4, (byte) 0x9A, (byte) 0xA4, (byte) 0x97, (byte) 0x7E, (byte) 0xDA, (byte) 0x7A, (byte) 0x17, (byte) 0x66, (byte) 0x94, (byte) 0xA1, (byte) 0x1D, (byte) 0x3D, (byte) 0xF0, (byte) 0xDE, (byte) 0xB3, (byte) 0x0B, (byte) 0x72, (byte) 0xA7, (byte) 0x1C, (byte) 0xEF, (byte) 0xD1, (byte) 0x53, (byte) 0x3E, (byte) 0x8F, (byte) 0x33, (byte) 0x26, (byte) 0x5F, (byte) 0xEC, (byte) 0x76, (byte) 0x2A, (byte) 0x49, (byte) 0x81, (byte) 0x88, (byte) 0xEE, (byte) 0x21, (byte) 0xC4, (byte) 0x1A, (byte) 0xEB, (byte) 0xD9, (byte) 0xC5, (byte) 0x39, (byte) 0x99, (byte) 0xCD, (byte) 0xAD, (byte) 0x31, (byte) 0x8B, (byte) 0x01, (byte) 0x18, (byte) 0x23, (byte) 0xDD, (byte) 0x1F, (byte) 0x4E, (byte) 0x2D, (byte) 0xF9, (byte) 0x48, (byte) 0x4F, (byte) 0xF2, (byte) 0x65, (byte) 0x8E, (byte) 0x78, (byte) 0x5C, (byte) 0x58, (byte) 0x19, (byte) 0x8D, (byte) 0xE5, (byte) 0x98, (byte) 0x57, (byte) 0x67, (byte) 0x7F, (byte) 0x05, (byte) 0x64, (byte) 0xAF, (byte) 0x63, (byte) 0xB6, (byte) 0xFE, (byte) 0xF5, (byte) 0xB7, (byte) 0x3C, (byte) 0xA5, (byte) 0xCE, (byte) 0xE9, (byte) 0x68, (byte) 0x44, (byte) 0xE0, (byte) 0x4D, (byte) 0x43, (byte) 0x69, (byte) 0x29, (byte) 0x2E, (byte) 0xAC, (byte) 0x15, (byte) 0x59, (byte) 0xA8, (byte) 0x0A, (byte) 0x9E, (byte) 0x6E, (byte) 0x47, (byte) 0xDF, (byte) 0x34, (byte) 0x35, (byte) 0x6A, (byte) 0xCF, (byte) 0xDC, (byte) 0x22, (byte) 0xC9, (byte) 0xC0, (byte) 0x9B, (byte) 0x89, (byte) 0xD4, (byte) 0xED, (byte) 0xAB, (byte) 0x12, (byte) 0xA2, (byte) 0x0D, (byte) 0x52, (byte) 0xBB, (byte) 0x02, (byte) 0x2F, (byte) 0xA9, (byte) 0xD7, (byte) 0x61, (byte) 0x1E, (byte) 0xB4, (byte) 0x50, (byte) 0x04, (byte) 0xF6, (byte) 0xC2, (byte) 0x16, (byte) 0x25, (byte) 0x86, (byte) 0x56, (byte) 0x55, (byte) 0x09, (byte) 0xBE, (byte) 0x91 } }; /** * Define the fixed p0/p1 permutations used in keyed S-box lookup. * By changing the following constant definitions, the S-boxes will * automatically get changed in the Twofish engine. */ private static final int P_00 = 1; private static final int P_01 = 0; private static final int P_02 = 0; private static final int P_03 = P_01 ^ 1; private static final int P_04 = 1; private static final int P_10 = 0; private static final int P_11 = 0; private static final int P_12 = 1; private static final int P_13 = P_11 ^ 1; private static final int P_14 = 0; private static final int P_20 = 1; private static final int P_21 = 1; private static final int P_22 = 0; private static final int P_23 = P_21 ^ 1; private static final int P_24 = 0; private static final int P_30 = 0; private static final int P_31 = 1; private static final int P_32 = 1; private static final int P_33 = P_31 ^ 1; private static final int P_34 = 1; /* Primitive polynomial for GF(256) */ private static final int GF256_FDBK = 0x169; private static final int GF256_FDBK_2 = GF256_FDBK / 2; private static final int GF256_FDBK_4 = GF256_FDBK / 4; private static final int RS_GF_FDBK = 0x14D; // field generator //==================================== // Useful constants //==================================== private static final int ROUNDS = 16; private static final int MAX_ROUNDS = 16; // bytes = 128 bits private static final int BLOCK_SIZE = 16; // bytes = 128 bits private static final int MAX_KEY_BITS = 256; private static final int INPUT_WHITEN=0; private static final int OUTPUT_WHITEN=INPUT_WHITEN+BLOCK_SIZE/4; // 4 private static final int ROUND_SUBKEYS=OUTPUT_WHITEN+BLOCK_SIZE/4;// 8 private static final int TOTAL_SUBKEYS=ROUND_SUBKEYS+2*MAX_ROUNDS;// 40 private static final int SK_STEP = 0x02020202; private static final int SK_BUMP = 0x01010101; private static final int SK_ROTL = 9; private boolean encrypting = false; private int[] gMDS0 = new int[MAX_KEY_BITS]; private int[] gMDS1 = new int[MAX_KEY_BITS]; private int[] gMDS2 = new int[MAX_KEY_BITS]; private int[] gMDS3 = new int[MAX_KEY_BITS]; /** * gSubKeys[] and gSBox[] are eventually used in the * encryption and decryption methods. */ private int[] gSubKeys; private int[] gSBox; private int k64Cnt = 0; private byte[] workingKey = null; public TwofishEngine() { // calculate the MDS matrix int[] m1 = new int[2]; int[] mX = new int[2]; int[] mY = new int[2]; int j; for (int i=0; i< MAX_KEY_BITS ; i++) { j = P[0][i] & 0xff; m1[0] = j; mX[0] = Mx_X(j) & 0xff; mY[0] = Mx_Y(j) & 0xff; j = P[1][i] & 0xff; m1[1] = j; mX[1] = Mx_X(j) & 0xff; mY[1] = Mx_Y(j) & 0xff; gMDS0[i] = m1[P_00] | mX[P_00] << 8 | mY[P_00] << 16 | mY[P_00] << 24; gMDS1[i] = mY[P_10] | mY[P_10] << 8 | mX[P_10] << 16 | m1[P_10] << 24; gMDS2[i] = mX[P_20] | mY[P_20] << 8 | m1[P_20] << 16 | mY[P_20] << 24; gMDS3[i] = mX[P_30] | m1[P_30] << 8 | mY[P_30] << 16 | mX[P_30] << 24; } } /** * initialise a Twofish cipher. * * @param encrypting whether or not we are for encryption. * @param params the parameters required to set up the cipher. * @exception IllegalArgumentException if the params argument is * inappropriate. */ public void init( boolean encrypting, CipherParameters params) { if (params instanceof KeyParameter) { this.encrypting = encrypting; this.workingKey = ((KeyParameter)params).getKey(); this.k64Cnt = (this.workingKey.length / 8); // pre-padded ? setKey(this.workingKey); return; } throw new IllegalArgumentException("invalid parameter passed to Twofish init - " + params.getClass().getName()); } public String getAlgorithmName() { return "Twofish"; } public int processBlock( byte[] in, int inOff, byte[] out, int outOff) { if (workingKey == null) { throw new IllegalStateException("Twofish not initialised"); } if ((inOff + BLOCK_SIZE) > in.length) { throw new DataLengthException("input buffer too short"); } if ((outOff + BLOCK_SIZE) > out.length) { throw new OutputLengthException("output buffer too short"); } if (encrypting) { encryptBlock(in, inOff, out, outOff); } else { decryptBlock(in, inOff, out, outOff); } return BLOCK_SIZE; } public void reset() { if (this.workingKey != null) { setKey(this.workingKey); } } public int getBlockSize() { return BLOCK_SIZE; } //================================== // Private Implementation //================================== private void setKey(byte[] key) { int[] k32e = new int[MAX_KEY_BITS/64]; // 4 int[] k32o = new int[MAX_KEY_BITS/64]; // 4 int[] sBoxKeys = new int[MAX_KEY_BITS/64]; // 4 gSubKeys = new int[TOTAL_SUBKEYS]; if (k64Cnt < 1) { throw new IllegalArgumentException("Key size less than 64 bits"); } if (k64Cnt > 4) { throw new IllegalArgumentException("Key size larger than 256 bits"); } /* * k64Cnt is the number of 8 byte blocks (64 chunks) * that are in the input key. The input key is a * maximum of 32 bytes (256 bits), so the range * for k64Cnt is 1..4 */ for (int i=0; i>> 24; A += B; gSubKeys[i*2] = A; A += B; gSubKeys[i*2 + 1] = A << SK_ROTL | A >>> (32-SK_ROTL); } /* * fully expand the table for speed */ int k0 = sBoxKeys[0]; int k1 = sBoxKeys[1]; int k2 = sBoxKeys[2]; int k3 = sBoxKeys[3]; int b0, b1, b2, b3; gSBox = new int[4*MAX_KEY_BITS]; for (int i=0; i>>1 | x2 << 31; x3 = (x3 << 1 | x3 >>> 31) ^ (t0 + 2*t1 + gSubKeys[k++]); t0 = Fe32_0(x2); t1 = Fe32_3(x3); x0 ^= t0 + t1 + gSubKeys[k++]; x0 = x0 >>>1 | x0 << 31; x1 = (x1 << 1 | x1 >>> 31) ^ (t0 + 2*t1 + gSubKeys[k++]); } Bits32ToBytes(x2 ^ gSubKeys[OUTPUT_WHITEN], dst, dstIndex); Bits32ToBytes(x3 ^ gSubKeys[OUTPUT_WHITEN + 1], dst, dstIndex + 4); Bits32ToBytes(x0 ^ gSubKeys[OUTPUT_WHITEN + 2], dst, dstIndex + 8); Bits32ToBytes(x1 ^ gSubKeys[OUTPUT_WHITEN + 3], dst, dstIndex + 12); } /** * Decrypt the given input starting at the given offset and place * the result in the provided buffer starting at the given offset. * The input will be an exact multiple of our blocksize. */ private void decryptBlock( byte[] src, int srcIndex, byte[] dst, int dstIndex) { int x2 = BytesTo32Bits(src, srcIndex) ^ gSubKeys[OUTPUT_WHITEN]; int x3 = BytesTo32Bits(src, srcIndex+4) ^ gSubKeys[OUTPUT_WHITEN + 1]; int x0 = BytesTo32Bits(src, srcIndex+8) ^ gSubKeys[OUTPUT_WHITEN + 2]; int x1 = BytesTo32Bits(src, srcIndex+12) ^ gSubKeys[OUTPUT_WHITEN + 3]; int k = ROUND_SUBKEYS + 2 * ROUNDS -1 ; int t0, t1; for (int r = 0; r< ROUNDS ; r +=2) { t0 = Fe32_0(x2); t1 = Fe32_3(x3); x1 ^= t0 + 2*t1 + gSubKeys[k--]; x0 = (x0 << 1 | x0 >>> 31) ^ (t0 + t1 + gSubKeys[k--]); x1 = x1 >>>1 | x1 << 31; t0 = Fe32_0(x0); t1 = Fe32_3(x1); x3 ^= t0 + 2*t1 + gSubKeys[k--]; x2 = (x2 << 1 | x2 >>> 31) ^ (t0 + t1 + gSubKeys[k--]); x3 = x3 >>>1 | x3 << 31; } Bits32ToBytes(x0 ^ gSubKeys[INPUT_WHITEN], dst, dstIndex); Bits32ToBytes(x1 ^ gSubKeys[INPUT_WHITEN + 1], dst, dstIndex + 4); Bits32ToBytes(x2 ^ gSubKeys[INPUT_WHITEN + 2], dst, dstIndex + 8); Bits32ToBytes(x3 ^ gSubKeys[INPUT_WHITEN + 3], dst, dstIndex + 12); } /* * TODO: This can be optimised and made cleaner by combining * the functionality in this function and applying it appropriately * to the creation of the subkeys during key setup. */ private int F32(int x, int[] k32) { int b0 = b0(x); int b1 = b1(x); int b2 = b2(x); int b3 = b3(x); int k0 = k32[0]; int k1 = k32[1]; int k2 = k32[2]; int k3 = k32[3]; int result = 0; switch (k64Cnt & 3) { case 1: result = gMDS0[(P[P_01][b0] & 0xff) ^ b0(k0)] ^ gMDS1[(P[P_11][b1] & 0xff) ^ b1(k0)] ^ gMDS2[(P[P_21][b2] & 0xff) ^ b2(k0)] ^ gMDS3[(P[P_31][b3] & 0xff) ^ b3(k0)]; break; case 0: /* 256 bits of key */ b0 = (P[P_04][b0] & 0xff) ^ b0(k3); b1 = (P[P_14][b1] & 0xff) ^ b1(k3); b2 = (P[P_24][b2] & 0xff) ^ b2(k3); b3 = (P[P_34][b3] & 0xff) ^ b3(k3); case 3: b0 = (P[P_03][b0] & 0xff) ^ b0(k2); b1 = (P[P_13][b1] & 0xff) ^ b1(k2); b2 = (P[P_23][b2] & 0xff) ^ b2(k2); b3 = (P[P_33][b3] & 0xff) ^ b3(k2); case 2: result = gMDS0[(P[P_01][(P[P_02][b0]&0xff)^b0(k1)]&0xff)^b0(k0)] ^ gMDS1[(P[P_11][(P[P_12][b1]&0xff)^b1(k1)]&0xff)^b1(k0)] ^ gMDS2[(P[P_21][(P[P_22][b2]&0xff)^b2(k1)]&0xff)^b2(k0)] ^ gMDS3[(P[P_31][(P[P_32][b3]&0xff)^b3(k1)]&0xff)^b3(k0)]; break; } return result; } /** * Use (12, 8) Reed-Solomon code over GF(256) to produce * a key S-box 32-bit entity from 2 key material 32-bit * entities. * * @param k0 first 32-bit entity * @param k1 second 32-bit entity * @return Remainder polynomial generated using RS code */ private int RS_MDS_Encode(int k0, int k1) { int r = k1; for (int i = 0 ; i < 4 ; i++) // shift 1 byte at a time { r = RS_rem(r); } r ^= k0; for (int i=0 ; i < 4 ; i++) { r = RS_rem(r); } return r; } /** * Reed-Solomon code parameters: (12,8) reversible code:

    *

         * g(x) = x^4 + (a+1/a)x^3 + ax^2 + (a+1/a)x + 1
         * 
    * where a = primitive root of field generator 0x14D */ private int RS_rem(int x) { int b = (x >>> 24) & 0xff; int g2 = ((b << 1) ^ ((b & 0x80) != 0 ? RS_GF_FDBK : 0)) & 0xff; int g3 = ((b >>> 1) ^ ((b & 0x01) != 0 ? (RS_GF_FDBK >>> 1) : 0)) ^ g2 ; return ((x << 8) ^ (g3 << 24) ^ (g2 << 16) ^ (g3 << 8) ^ b); } private int LFSR1(int x) { return (x >> 1) ^ (((x & 0x01) != 0) ? GF256_FDBK_2 : 0); } private int LFSR2(int x) { return (x >> 2) ^ (((x & 0x02) != 0) ? GF256_FDBK_2 : 0) ^ (((x & 0x01) != 0) ? GF256_FDBK_4 : 0); } private int Mx_X(int x) { return x ^ LFSR2(x); } // 5B private int Mx_Y(int x) { return x ^ LFSR1(x) ^ LFSR2(x); } // EF private int b0(int x) { return x & 0xff; } private int b1(int x) { return (x >>> 8) & 0xff; } private int b2(int x) { return (x >>> 16) & 0xff; } private int b3(int x) { return (x >>> 24) & 0xff; } private int Fe32_0(int x) { return gSBox[ 0x000 + 2*(x & 0xff) ] ^ gSBox[ 0x001 + 2*((x >>> 8) & 0xff) ] ^ gSBox[ 0x200 + 2*((x >>> 16) & 0xff) ] ^ gSBox[ 0x201 + 2*((x >>> 24) & 0xff) ]; } private int Fe32_3(int x) { return gSBox[ 0x000 + 2*((x >>> 24) & 0xff) ] ^ gSBox[ 0x001 + 2*(x & 0xff) ] ^ gSBox[ 0x200 + 2*((x >>> 8) & 0xff) ] ^ gSBox[ 0x201 + 2*((x >>> 16) & 0xff) ]; } private int BytesTo32Bits(byte[] b, int p) { return ((b[p] & 0xff)) | ((b[p+1] & 0xff) << 8) | ((b[p+2] & 0xff) << 16) | ((b[p+3] & 0xff) << 24); } private void Bits32ToBytes(int in, byte[] b, int offset) { b[offset] = (byte)in; b[offset + 1] = (byte)(in >> 8); b[offset + 2] = (byte)(in >> 16); b[offset + 3] = (byte)(in >> 24); } } bouncycastle-1.49.orig/src/org/bouncycastle/crypto/engines/CAST6Engine.java0000644000175000017500000002117210504662713026272 0ustar ebourgebourgpackage org.bouncycastle.crypto.engines; /** * A class that provides CAST6 key encryption operations, * such as encoding data and generating keys. * * All the algorithms herein are from the Internet RFC * * RFC2612 - CAST6 (128bit block, 128-256bit key) * * and implement a simplified cryptography interface. */ public final class CAST6Engine extends CAST5Engine { //==================================== // Useful constants //==================================== protected static final int ROUNDS = 12; protected static final int BLOCK_SIZE = 16; // bytes = 128 bits /* * Put the round and mask keys into an array. * Kr0[i] => _Kr[i*4 + 0] */ protected int _Kr[] = new int[ROUNDS*4]; // the rotating round key(s) protected int _Km[] = new int[ROUNDS*4]; // the masking round key(s) /* * Key setup */ protected int _Tr[] = new int[24 * 8]; protected int _Tm[] = new int[24 * 8]; private int[] _workingKey = new int[8]; public CAST6Engine() { } public String getAlgorithmName() { return "CAST6"; } public void reset() { } public int getBlockSize() { return BLOCK_SIZE; } //================================== // Private Implementation //================================== /* * Creates the subkeys using the same nomenclature * as described in RFC2612. * * See section 2.4 */ protected void setKey(byte[] key) { int Cm = 0x5a827999; int Mm = 0x6ed9eba1; int Cr = 19; int Mr = 17; /* * Determine the key size here, if required * * if keysize < 256 bytes, pad with 0 * * Typical key sizes => 128, 160, 192, 224, 256 */ for (int i=0; i< 24; i++) { for (int j=0; j< 8; j++) { _Tm[i*8 + j] = Cm; Cm = (Cm + Mm); // mod 2^32; _Tr[i*8 + j] = Cr; Cr = (Cr + Mr) & 0x1f; // mod 32 } } byte[] tmpKey = new byte[64]; int length = key.length; System.arraycopy(key, 0, tmpKey, 0, length); // now create ABCDEFGH for (int i=0; i< 8; i++) { _workingKey[i] = BytesTo32bits(tmpKey, i*4); } // Generate the key schedule for (int i=0; i< 12; i++) { // KAPPA <- W2i(KAPPA) int i2 = i*2 *8; _workingKey[6] ^= F1(_workingKey[7], _Tm[i2 ], _Tr[i2 ]); _workingKey[5] ^= F2(_workingKey[6], _Tm[i2+1], _Tr[i2+1]); _workingKey[4] ^= F3(_workingKey[5], _Tm[i2+2], _Tr[i2+2]); _workingKey[3] ^= F1(_workingKey[4], _Tm[i2+3], _Tr[i2+3]); _workingKey[2] ^= F2(_workingKey[3], _Tm[i2+4], _Tr[i2+4]); _workingKey[1] ^= F3(_workingKey[2], _Tm[i2+5], _Tr[i2+5]); _workingKey[0] ^= F1(_workingKey[1], _Tm[i2+6], _Tr[i2+6]); _workingKey[7] ^= F2(_workingKey[0], _Tm[i2+7], _Tr[i2+7]); // KAPPA <- W2i+1(KAPPA) i2 = (i*2 + 1)*8; _workingKey[6] ^= F1(_workingKey[7], _Tm[i2 ], _Tr[i2 ]); _workingKey[5] ^= F2(_workingKey[6], _Tm[i2+1], _Tr[i2+1]); _workingKey[4] ^= F3(_workingKey[5], _Tm[i2+2], _Tr[i2+2]); _workingKey[3] ^= F1(_workingKey[4], _Tm[i2+3], _Tr[i2+3]); _workingKey[2] ^= F2(_workingKey[3], _Tm[i2+4], _Tr[i2+4]); _workingKey[1] ^= F3(_workingKey[2], _Tm[i2+5], _Tr[i2+5]); _workingKey[0] ^= F1(_workingKey[1], _Tm[i2+6], _Tr[i2+6]); _workingKey[7] ^= F2(_workingKey[0], _Tm[i2+7], _Tr[i2+7]); // Kr_(i) <- KAPPA _Kr[i*4 ] = _workingKey[0] & 0x1f; _Kr[i*4 + 1] = _workingKey[2] & 0x1f; _Kr[i*4 + 2] = _workingKey[4] & 0x1f; _Kr[i*4 + 3] = _workingKey[6] & 0x1f; // Km_(i) <- KAPPA _Km[i*4 ] = _workingKey[7]; _Km[i*4 + 1] = _workingKey[5]; _Km[i*4 + 2] = _workingKey[3]; _Km[i*4 + 3] = _workingKey[1]; } } /** * Encrypt the given input starting at the given offset and place * the result in the provided buffer starting at the given offset. * * @param src The plaintext buffer * @param srcIndex An offset into src * @param dst The ciphertext buffer * @param dstIndex An offset into dst */ protected int encryptBlock( byte[] src, int srcIndex, byte[] dst, int dstIndex) { int result[] = new int[4]; // process the input block // batch the units up into 4x32 bit chunks and go for it int A = BytesTo32bits(src, srcIndex); int B = BytesTo32bits(src, srcIndex + 4); int C = BytesTo32bits(src, srcIndex + 8); int D = BytesTo32bits(src, srcIndex + 12); CAST_Encipher(A, B, C, D, result); // now stuff them into the destination block Bits32ToBytes(result[0], dst, dstIndex); Bits32ToBytes(result[1], dst, dstIndex + 4); Bits32ToBytes(result[2], dst, dstIndex + 8); Bits32ToBytes(result[3], dst, dstIndex + 12); return BLOCK_SIZE; } /** * Decrypt the given input starting at the given offset and place * the result in the provided buffer starting at the given offset. * * @param src The plaintext buffer * @param srcIndex An offset into src * @param dst The ciphertext buffer * @param dstIndex An offset into dst */ protected int decryptBlock( byte[] src, int srcIndex, byte[] dst, int dstIndex) { int result[] = new int[4]; // process the input block // batch the units up into 4x32 bit chunks and go for it int A = BytesTo32bits(src, srcIndex); int B = BytesTo32bits(src, srcIndex + 4); int C = BytesTo32bits(src, srcIndex + 8); int D = BytesTo32bits(src, srcIndex + 12); CAST_Decipher(A, B, C, D, result); // now stuff them into the destination block Bits32ToBytes(result[0], dst, dstIndex); Bits32ToBytes(result[1], dst, dstIndex + 4); Bits32ToBytes(result[2], dst, dstIndex + 8); Bits32ToBytes(result[3], dst, dstIndex + 12); return BLOCK_SIZE; } /** * Does the 12 quad rounds rounds to encrypt the block. * * @param A the 00-31 bits of the plaintext block * @param B the 32-63 bits of the plaintext block * @param C the 64-95 bits of the plaintext block * @param D the 96-127 bits of the plaintext block * @param result the resulting ciphertext */ protected final void CAST_Encipher(int A, int B, int C, int D,int result[]) { int x; for (int i=0; i< 6; i++) { x = i*4; // BETA <- Qi(BETA) C ^= F1(D, _Km[x], _Kr[x]); B ^= F2(C, _Km[x + 1], _Kr[x + 1]); A ^= F3(B, _Km[x + 2], _Kr[x + 2]); D ^= F1(A, _Km[x + 3], _Kr[x + 3]); } for (int i=6; i<12; i++) { x = i*4; // BETA <- QBARi(BETA) D ^= F1(A, _Km[x + 3], _Kr[x + 3]); A ^= F3(B, _Km[x + 2], _Kr[x + 2]); B ^= F2(C, _Km[x + 1], _Kr[x + 1]); C ^= F1(D, _Km[x], _Kr[x]); } result[0] = A; result[1] = B; result[2] = C; result[3] = D; } /** * Does the 12 quad rounds rounds to decrypt the block. * * @param A the 00-31 bits of the ciphertext block * @param B the 32-63 bits of the ciphertext block * @param C the 64-95 bits of the ciphertext block * @param D the 96-127 bits of the ciphertext block * @param result the resulting plaintext */ protected final void CAST_Decipher(int A, int B, int C, int D,int result[]) { int x; for (int i=0; i< 6; i++) { x = (11-i)*4; // BETA <- Qi(BETA) C ^= F1(D, _Km[x], _Kr[x]); B ^= F2(C, _Km[x + 1], _Kr[x + 1]); A ^= F3(B, _Km[x + 2], _Kr[x + 2]); D ^= F1(A, _Km[x + 3], _Kr[x + 3]); } for (int i=6; i<12; i++) { x = (11-i)*4; // BETA <- QBARi(BETA) D ^= F1(A, _Km[x + 3], _Kr[x + 3]); A ^= F3(B, _Km[x + 2], _Kr[x + 2]); B ^= F2(C, _Km[x + 1], _Kr[x + 1]); C ^= F1(D, _Km[x], _Kr[x]); } result[0] = A; result[1] = B; result[2] = C; result[3] = D; } } bouncycastle-1.49.orig/src/org/bouncycastle/crypto/engines/RFC3211WrapEngine.java0000644000175000017500000001111211302667745027225 0ustar ebourgebourgpackage org.bouncycastle.crypto.engines; import org.bouncycastle.crypto.BlockCipher; import org.bouncycastle.crypto.CipherParameters; import org.bouncycastle.crypto.InvalidCipherTextException; import org.bouncycastle.crypto.Wrapper; import org.bouncycastle.crypto.modes.CBCBlockCipher; import org.bouncycastle.crypto.params.ParametersWithIV; import org.bouncycastle.crypto.params.ParametersWithRandom; import java.security.SecureRandom; /** * an implementation of the RFC 3211 Key Wrap * Specification. */ public class RFC3211WrapEngine implements Wrapper { private CBCBlockCipher engine; private ParametersWithIV param; private boolean forWrapping; private SecureRandom rand; public RFC3211WrapEngine(BlockCipher engine) { this.engine = new CBCBlockCipher(engine); } public void init( boolean forWrapping, CipherParameters param) { this.forWrapping = forWrapping; if (param instanceof ParametersWithRandom) { ParametersWithRandom p = (ParametersWithRandom)param; rand = p.getRandom(); this.param = (ParametersWithIV)p.getParameters(); } else { if (forWrapping) { rand = new SecureRandom(); } this.param = (ParametersWithIV)param; } } public String getAlgorithmName() { return engine.getUnderlyingCipher().getAlgorithmName() + "/RFC3211Wrap"; } public byte[] wrap( byte[] in, int inOff, int inLen) { if (!forWrapping) { throw new IllegalStateException("not set for wrapping"); } engine.init(true, param); int blockSize = engine.getBlockSize(); byte[] cekBlock; if (inLen + 4 < blockSize * 2) { cekBlock = new byte[blockSize * 2]; } else { cekBlock = new byte[(inLen + 4) % blockSize == 0 ? inLen + 4 : ((inLen + 4) / blockSize + 1) * blockSize]; } cekBlock[0] = (byte)inLen; cekBlock[1] = (byte)~in[inOff]; cekBlock[2] = (byte)~in[inOff + 1]; cekBlock[3] = (byte)~in[inOff + 2]; System.arraycopy(in, inOff, cekBlock, 4, inLen); for (int i = inLen + 4; i < cekBlock.length; i++) { cekBlock[i] = (byte)rand.nextInt(); } for (int i = 0; i < cekBlock.length; i += blockSize) { engine.processBlock(cekBlock, i, cekBlock, i); } for (int i = 0; i < cekBlock.length; i += blockSize) { engine.processBlock(cekBlock, i, cekBlock, i); } return cekBlock; } public byte[] unwrap( byte[] in, int inOff, int inLen) throws InvalidCipherTextException { if (forWrapping) { throw new IllegalStateException("not set for unwrapping"); } int blockSize = engine.getBlockSize(); if (inLen < 2 * blockSize) { throw new InvalidCipherTextException("input too short"); } byte[] cekBlock = new byte[inLen]; byte[] iv = new byte[blockSize]; System.arraycopy(in, inOff, cekBlock, 0, inLen); System.arraycopy(in, inOff, iv, 0, iv.length); engine.init(false, new ParametersWithIV(param.getParameters(), iv)); for (int i = blockSize; i < cekBlock.length; i += blockSize) { engine.processBlock(cekBlock, i, cekBlock, i); } System.arraycopy(cekBlock, cekBlock.length - iv.length, iv, 0, iv.length); engine.init(false, new ParametersWithIV(param.getParameters(), iv)); engine.processBlock(cekBlock, 0, cekBlock, 0); engine.init(false, param); for (int i = 0; i < cekBlock.length; i += blockSize) { engine.processBlock(cekBlock, i, cekBlock, i); } if ((cekBlock[0] & 0xff) > cekBlock.length - 4) { throw new InvalidCipherTextException("wrapped key corrupted"); } byte[] key = new byte[cekBlock[0] & 0xff]; System.arraycopy(cekBlock, 4, key, 0, cekBlock[0]); // Note: Using constant time comparison int nonEqual = 0; for (int i = 0; i != 3; i++) { byte check = (byte)~cekBlock[1 + i]; nonEqual |= (check ^ key[i]); } if (nonEqual != 0) { throw new InvalidCipherTextException("wrapped key fails checksum"); } return key; } } bouncycastle-1.49.orig/src/org/bouncycastle/crypto/engines/SkipjackEngine.java0000644000175000017500000001724012106331365027206 0ustar ebourgebourgpackage org.bouncycastle.crypto.engines; import org.bouncycastle.crypto.BlockCipher; import org.bouncycastle.crypto.CipherParameters; import org.bouncycastle.crypto.DataLengthException; import org.bouncycastle.crypto.OutputLengthException; import org.bouncycastle.crypto.params.KeyParameter; /** * a class that provides a basic SKIPJACK engine. */ public class SkipjackEngine implements BlockCipher { static final int BLOCK_SIZE = 8; static short ftable[] = { 0xa3, 0xd7, 0x09, 0x83, 0xf8, 0x48, 0xf6, 0xf4, 0xb3, 0x21, 0x15, 0x78, 0x99, 0xb1, 0xaf, 0xf9, 0xe7, 0x2d, 0x4d, 0x8a, 0xce, 0x4c, 0xca, 0x2e, 0x52, 0x95, 0xd9, 0x1e, 0x4e, 0x38, 0x44, 0x28, 0x0a, 0xdf, 0x02, 0xa0, 0x17, 0xf1, 0x60, 0x68, 0x12, 0xb7, 0x7a, 0xc3, 0xe9, 0xfa, 0x3d, 0x53, 0x96, 0x84, 0x6b, 0xba, 0xf2, 0x63, 0x9a, 0x19, 0x7c, 0xae, 0xe5, 0xf5, 0xf7, 0x16, 0x6a, 0xa2, 0x39, 0xb6, 0x7b, 0x0f, 0xc1, 0x93, 0x81, 0x1b, 0xee, 0xb4, 0x1a, 0xea, 0xd0, 0x91, 0x2f, 0xb8, 0x55, 0xb9, 0xda, 0x85, 0x3f, 0x41, 0xbf, 0xe0, 0x5a, 0x58, 0x80, 0x5f, 0x66, 0x0b, 0xd8, 0x90, 0x35, 0xd5, 0xc0, 0xa7, 0x33, 0x06, 0x65, 0x69, 0x45, 0x00, 0x94, 0x56, 0x6d, 0x98, 0x9b, 0x76, 0x97, 0xfc, 0xb2, 0xc2, 0xb0, 0xfe, 0xdb, 0x20, 0xe1, 0xeb, 0xd6, 0xe4, 0xdd, 0x47, 0x4a, 0x1d, 0x42, 0xed, 0x9e, 0x6e, 0x49, 0x3c, 0xcd, 0x43, 0x27, 0xd2, 0x07, 0xd4, 0xde, 0xc7, 0x67, 0x18, 0x89, 0xcb, 0x30, 0x1f, 0x8d, 0xc6, 0x8f, 0xaa, 0xc8, 0x74, 0xdc, 0xc9, 0x5d, 0x5c, 0x31, 0xa4, 0x70, 0x88, 0x61, 0x2c, 0x9f, 0x0d, 0x2b, 0x87, 0x50, 0x82, 0x54, 0x64, 0x26, 0x7d, 0x03, 0x40, 0x34, 0x4b, 0x1c, 0x73, 0xd1, 0xc4, 0xfd, 0x3b, 0xcc, 0xfb, 0x7f, 0xab, 0xe6, 0x3e, 0x5b, 0xa5, 0xad, 0x04, 0x23, 0x9c, 0x14, 0x51, 0x22, 0xf0, 0x29, 0x79, 0x71, 0x7e, 0xff, 0x8c, 0x0e, 0xe2, 0x0c, 0xef, 0xbc, 0x72, 0x75, 0x6f, 0x37, 0xa1, 0xec, 0xd3, 0x8e, 0x62, 0x8b, 0x86, 0x10, 0xe8, 0x08, 0x77, 0x11, 0xbe, 0x92, 0x4f, 0x24, 0xc5, 0x32, 0x36, 0x9d, 0xcf, 0xf3, 0xa6, 0xbb, 0xac, 0x5e, 0x6c, 0xa9, 0x13, 0x57, 0x25, 0xb5, 0xe3, 0xbd, 0xa8, 0x3a, 0x01, 0x05, 0x59, 0x2a, 0x46 }; private int[] key0, key1, key2, key3; private boolean encrypting; /** * initialise a SKIPJACK cipher. * * @param encrypting whether or not we are for encryption. * @param params the parameters required to set up the cipher. * @exception IllegalArgumentException if the params argument is * inappropriate. */ public void init( boolean encrypting, CipherParameters params) { if (!(params instanceof KeyParameter)) { throw new IllegalArgumentException("invalid parameter passed to SKIPJACK init - " + params.getClass().getName()); } byte[] keyBytes = ((KeyParameter)params).getKey(); this.encrypting = encrypting; this.key0 = new int[32]; this.key1 = new int[32]; this.key2 = new int[32]; this.key3 = new int[32]; // // expand the key to 128 bytes in 4 parts (saving us a modulo, multiply // and an addition). // for (int i = 0; i < 32; i ++) { key0[i] = keyBytes[(i * 4) % 10] & 0xff; key1[i] = keyBytes[(i * 4 + 1) % 10] & 0xff; key2[i] = keyBytes[(i * 4 + 2) % 10] & 0xff; key3[i] = keyBytes[(i * 4 + 3) % 10] & 0xff; } } public String getAlgorithmName() { return "SKIPJACK"; } public int getBlockSize() { return BLOCK_SIZE; } public int processBlock( byte[] in, int inOff, byte[] out, int outOff) { if (key1 == null) { throw new IllegalStateException("SKIPJACK engine not initialised"); } if ((inOff + BLOCK_SIZE) > in.length) { throw new DataLengthException("input buffer too short"); } if ((outOff + BLOCK_SIZE) > out.length) { throw new OutputLengthException("output buffer too short"); } if (encrypting) { encryptBlock(in, inOff, out, outOff); } else { decryptBlock(in, inOff, out, outOff); } return BLOCK_SIZE; } public void reset() { } /** * The G permutation */ private int g( int k, int w) { int g1, g2, g3, g4, g5, g6; g1 = (w >> 8) & 0xff; g2 = w & 0xff; g3 = ftable[g2 ^ key0[k]] ^ g1; g4 = ftable[g3 ^ key1[k]] ^ g2; g5 = ftable[g4 ^ key2[k]] ^ g3; g6 = ftable[g5 ^ key3[k]] ^ g4; return ((g5 << 8) + g6); } public int encryptBlock( byte[] in, int inOff, byte[] out, int outOff) { int w1 = (in[inOff + 0] << 8) + (in[inOff + 1] & 0xff); int w2 = (in[inOff + 2] << 8) + (in[inOff + 3] & 0xff); int w3 = (in[inOff + 4] << 8) + (in[inOff + 5] & 0xff); int w4 = (in[inOff + 6] << 8) + (in[inOff + 7] & 0xff); int k = 0; for (int t = 0; t < 2; t++) { for(int i = 0; i < 8; i++) { int tmp = w4; w4 = w3; w3 = w2; w2 = g(k, w1); w1 = w2 ^ tmp ^ (k + 1); k++; } for(int i = 0; i < 8; i++) { int tmp = w4; w4 = w3; w3 = w1 ^ w2 ^ (k + 1); w2 = g(k, w1); w1 = tmp; k++; } } out[outOff + 0] = (byte)((w1 >> 8)); out[outOff + 1] = (byte)(w1); out[outOff + 2] = (byte)((w2 >> 8)); out[outOff + 3] = (byte)(w2); out[outOff + 4] = (byte)((w3 >> 8)); out[outOff + 5] = (byte)(w3); out[outOff + 6] = (byte)((w4 >> 8)); out[outOff + 7] = (byte)(w4); return BLOCK_SIZE; } /** * the inverse of the G permutation. */ private int h( int k, int w) { int h1, h2, h3, h4, h5, h6; h1 = w & 0xff; h2 = (w >> 8) & 0xff; h3 = ftable[h2 ^ key3[k]] ^ h1; h4 = ftable[h3 ^ key2[k]] ^ h2; h5 = ftable[h4 ^ key1[k]] ^ h3; h6 = ftable[h5 ^ key0[k]] ^ h4; return ((h6 << 8) + h5); } public int decryptBlock( byte[] in, int inOff, byte[] out, int outOff) { int w2 = (in[inOff + 0] << 8) + (in[inOff + 1] & 0xff); int w1 = (in[inOff + 2] << 8) + (in[inOff + 3] & 0xff); int w4 = (in[inOff + 4] << 8) + (in[inOff + 5] & 0xff); int w3 = (in[inOff + 6] << 8) + (in[inOff + 7] & 0xff); int k = 31; for (int t = 0; t < 2; t++) { for(int i = 0; i < 8; i++) { int tmp = w4; w4 = w3; w3 = w2; w2 = h(k, w1); w1 = w2 ^ tmp ^ (k + 1); k--; } for(int i = 0; i < 8; i++) { int tmp = w4; w4 = w3; w3 = w1 ^ w2 ^ (k + 1); w2 = h(k, w1); w1 = tmp; k--; } } out[outOff + 0] = (byte)((w2 >> 8)); out[outOff + 1] = (byte)(w2); out[outOff + 2] = (byte)((w1 >> 8)); out[outOff + 3] = (byte)(w1); out[outOff + 4] = (byte)((w4 >> 8)); out[outOff + 5] = (byte)(w4); out[outOff + 6] = (byte)((w3 >> 8)); out[outOff + 7] = (byte)(w3); return BLOCK_SIZE; } } bouncycastle-1.49.orig/src/org/bouncycastle/crypto/engines/RC2WrapEngine.java0000644000175000017500000002667111263524566026711 0ustar ebourgebourgpackage org.bouncycastle.crypto.engines; import java.security.SecureRandom; import org.bouncycastle.crypto.CipherParameters; import org.bouncycastle.crypto.Digest; import org.bouncycastle.crypto.InvalidCipherTextException; import org.bouncycastle.crypto.Wrapper; import org.bouncycastle.crypto.digests.SHA1Digest; import org.bouncycastle.crypto.modes.CBCBlockCipher; import org.bouncycastle.crypto.params.ParametersWithIV; import org.bouncycastle.crypto.params.ParametersWithRandom; import org.bouncycastle.util.Arrays; /** * Wrap keys according to RFC 3217 - RC2 mechanism */ public class RC2WrapEngine implements Wrapper { /** Field engine */ private CBCBlockCipher engine; /** Field param */ private CipherParameters param; /** Field paramPlusIV */ private ParametersWithIV paramPlusIV; /** Field iv */ private byte[] iv; /** Field forWrapping */ private boolean forWrapping; private SecureRandom sr; /** Field IV2 */ private static final byte[] IV2 = { (byte) 0x4a, (byte) 0xdd, (byte) 0xa2, (byte) 0x2c, (byte) 0x79, (byte) 0xe8, (byte) 0x21, (byte) 0x05 }; // // checksum digest // Digest sha1 = new SHA1Digest(); byte[] digest = new byte[20]; /** * Method init * * @param forWrapping * @param param */ public void init(boolean forWrapping, CipherParameters param) { this.forWrapping = forWrapping; this.engine = new CBCBlockCipher(new RC2Engine()); if (param instanceof ParametersWithRandom) { ParametersWithRandom pWithR = (ParametersWithRandom)param; sr = pWithR.getRandom(); param = pWithR.getParameters(); } else { sr = new SecureRandom(); } if (param instanceof ParametersWithIV) { this.paramPlusIV = (ParametersWithIV)param; this.iv = this.paramPlusIV.getIV(); this.param = this.paramPlusIV.getParameters(); if (this.forWrapping) { if ((this.iv == null) || (this.iv.length != 8)) { throw new IllegalArgumentException("IV is not 8 octets"); } } else { throw new IllegalArgumentException( "You should not supply an IV for unwrapping"); } } else { this.param = param; if (this.forWrapping) { // Hm, we have no IV but we want to wrap ?!? // well, then we have to create our own IV. this.iv = new byte[8]; sr.nextBytes(iv); this.paramPlusIV = new ParametersWithIV(this.param, this.iv); } } } /** * Method getAlgorithmName * * @return the algorithm name "RC2". */ public String getAlgorithmName() { return "RC2"; } /** * Method wrap * * @param in * @param inOff * @param inLen * @return the wrapped bytes. */ public byte[] wrap(byte[] in, int inOff, int inLen) { if (!forWrapping) { throw new IllegalStateException("Not initialized for wrapping"); } int length = inLen + 1; if ((length % 8) != 0) { length += 8 - (length % 8); } byte keyToBeWrapped[] = new byte[length]; keyToBeWrapped[0] = (byte)inLen; System.arraycopy(in, inOff, keyToBeWrapped, 1, inLen); byte[] pad = new byte[keyToBeWrapped.length - inLen - 1]; if (pad.length > 0) { sr.nextBytes(pad); System.arraycopy(pad, 0, keyToBeWrapped, inLen + 1, pad.length); } // Compute the CMS Key Checksum, (section 5.6.1), call this CKS. byte[] CKS = calculateCMSKeyChecksum(keyToBeWrapped); // Let WKCKS = WK || CKS where || is concatenation. byte[] WKCKS = new byte[keyToBeWrapped.length + CKS.length]; System.arraycopy(keyToBeWrapped, 0, WKCKS, 0, keyToBeWrapped.length); System.arraycopy(CKS, 0, WKCKS, keyToBeWrapped.length, CKS.length); // Encrypt WKCKS in CBC mode using KEK as the key and IV as the // initialization vector. Call the results TEMP1. byte TEMP1[] = new byte[WKCKS.length]; System.arraycopy(WKCKS, 0, TEMP1, 0, WKCKS.length); int noOfBlocks = WKCKS.length / engine.getBlockSize(); int extraBytes = WKCKS.length % engine.getBlockSize(); if (extraBytes != 0) { throw new IllegalStateException("Not multiple of block length"); } engine.init(true, paramPlusIV); for (int i = 0; i < noOfBlocks; i++) { int currentBytePos = i * engine.getBlockSize(); engine.processBlock(TEMP1, currentBytePos, TEMP1, currentBytePos); } // Left TEMP2 = IV || TEMP1. byte[] TEMP2 = new byte[this.iv.length + TEMP1.length]; System.arraycopy(this.iv, 0, TEMP2, 0, this.iv.length); System.arraycopy(TEMP1, 0, TEMP2, this.iv.length, TEMP1.length); // Reverse the order of the octets in TEMP2 and call the result TEMP3. byte[] TEMP3 = new byte[TEMP2.length]; for (int i = 0; i < TEMP2.length; i++) { TEMP3[i] = TEMP2[TEMP2.length - (i + 1)]; } // Encrypt TEMP3 in CBC mode using the KEK and an initialization vector // of 0x 4a dd a2 2c 79 e8 21 05. The resulting cipher text is the // desired // result. It is 40 octets long if a 168 bit key is being wrapped. ParametersWithIV param2 = new ParametersWithIV(this.param, IV2); this.engine.init(true, param2); for (int i = 0; i < noOfBlocks + 1; i++) { int currentBytePos = i * engine.getBlockSize(); engine.processBlock(TEMP3, currentBytePos, TEMP3, currentBytePos); } return TEMP3; } /** * Method unwrap * * @param in * @param inOff * @param inLen * @return the unwrapped bytes. * @throws InvalidCipherTextException */ public byte[] unwrap(byte[] in, int inOff, int inLen) throws InvalidCipherTextException { if (forWrapping) { throw new IllegalStateException("Not set for unwrapping"); } if (in == null) { throw new InvalidCipherTextException("Null pointer as ciphertext"); } if (inLen % engine.getBlockSize() != 0) { throw new InvalidCipherTextException("Ciphertext not multiple of " + engine.getBlockSize()); } /* * // Check if the length of the cipher text is reasonable given the key // * type. It must be 40 bytes for a 168 bit key and either 32, 40, or // * 48 bytes for a 128, 192, or 256 bit key. If the length is not * supported // or inconsistent with the algorithm for which the key is * intended, // return error. // // we do not accept 168 bit keys. it * has to be 192 bit. int lengthA = (estimatedKeyLengthInBit / 8) + 16; * int lengthB = estimatedKeyLengthInBit % 8; * * if ((lengthA != keyToBeUnwrapped.length) || (lengthB != 0)) { throw * new XMLSecurityException("empty"); } */ // Decrypt the cipher text with TRIPLedeS in CBC mode using the KEK // and an initialization vector (IV) of 0x4adda22c79e82105. Call the // output TEMP3. ParametersWithIV param2 = new ParametersWithIV(this.param, IV2); this.engine.init(false, param2); byte TEMP3[] = new byte[inLen]; System.arraycopy(in, inOff, TEMP3, 0, inLen); for (int i = 0; i < (TEMP3.length / engine.getBlockSize()); i++) { int currentBytePos = i * engine.getBlockSize(); engine.processBlock(TEMP3, currentBytePos, TEMP3, currentBytePos); } // Reverse the order of the octets in TEMP3 and call the result TEMP2. byte[] TEMP2 = new byte[TEMP3.length]; for (int i = 0; i < TEMP3.length; i++) { TEMP2[i] = TEMP3[TEMP3.length - (i + 1)]; } // Decompose TEMP2 into IV, the first 8 octets, and TEMP1, the remaining // octets. this.iv = new byte[8]; byte[] TEMP1 = new byte[TEMP2.length - 8]; System.arraycopy(TEMP2, 0, this.iv, 0, 8); System.arraycopy(TEMP2, 8, TEMP1, 0, TEMP2.length - 8); // Decrypt TEMP1 using TRIPLedeS in CBC mode using the KEK and the IV // found in the previous step. Call the result WKCKS. this.paramPlusIV = new ParametersWithIV(this.param, this.iv); this.engine.init(false, this.paramPlusIV); byte[] LCEKPADICV = new byte[TEMP1.length]; System.arraycopy(TEMP1, 0, LCEKPADICV, 0, TEMP1.length); for (int i = 0; i < (LCEKPADICV.length / engine.getBlockSize()); i++) { int currentBytePos = i * engine.getBlockSize(); engine.processBlock(LCEKPADICV, currentBytePos, LCEKPADICV, currentBytePos); } // Decompose LCEKPADICV. CKS is the last 8 octets and WK, the wrapped // key, are // those octets before the CKS. byte[] result = new byte[LCEKPADICV.length - 8]; byte[] CKStoBeVerified = new byte[8]; System.arraycopy(LCEKPADICV, 0, result, 0, LCEKPADICV.length - 8); System.arraycopy(LCEKPADICV, LCEKPADICV.length - 8, CKStoBeVerified, 0, 8); // Calculate a CMS Key Checksum, (section 5.6.1), over the WK and // compare // with the CKS extracted in the above step. If they are not equal, // return error. if (!checkCMSKeyChecksum(result, CKStoBeVerified)) { throw new InvalidCipherTextException( "Checksum inside ciphertext is corrupted"); } if ((result.length - ((result[0] & 0xff) + 1)) > 7) { throw new InvalidCipherTextException("too many pad bytes (" + (result.length - ((result[0] & 0xff) + 1)) + ")"); } // CEK is the wrapped key, now extracted for use in data decryption. byte[] CEK = new byte[result[0]]; System.arraycopy(result, 1, CEK, 0, CEK.length); return CEK; } /** * Some key wrap algorithms make use of the Key Checksum defined * in CMS [CMS-Algorithms]. This is used to provide an integrity * check value for the key being wrapped. The algorithm is * * - Compute the 20 octet SHA-1 hash on the key being wrapped. * - Use the first 8 octets of this hash as the checksum value. * * @param key * @return * @throws RuntimeException * @see http://www.w3.org/TR/xmlenc-core/#sec-CMSKeyChecksum */ private byte[] calculateCMSKeyChecksum( byte[] key) { byte[] result = new byte[8]; sha1.update(key, 0, key.length); sha1.doFinal(digest, 0); System.arraycopy(digest, 0, result, 0, 8); return result; } /** * @param key * @param checksum * @return * @see http://www.w3.org/TR/xmlenc-core/#sec-CMSKeyChecksum */ private boolean checkCMSKeyChecksum( byte[] key, byte[] checksum) { return Arrays.constantTimeAreEqual(calculateCMSKeyChecksum(key), checksum); } } bouncycastle-1.49.orig/src/org/bouncycastle/crypto/engines/NoekeonEngine.java0000644000175000017500000001605012106331532027037 0ustar ebourgebourgpackage org.bouncycastle.crypto.engines; import org.bouncycastle.crypto.BlockCipher; import org.bouncycastle.crypto.CipherParameters; import org.bouncycastle.crypto.DataLengthException; import org.bouncycastle.crypto.OutputLengthException; import org.bouncycastle.crypto.params.KeyParameter; /** * A Noekeon engine, using direct-key mode. */ public class NoekeonEngine implements BlockCipher { private static final int genericSize = 16; // Block and key size, as well as the amount of rounds. private static final int[] nullVector = { 0x00, 0x00, 0x00, 0x00 // Used in decryption }, roundConstants = { 0x80, 0x1b, 0x36, 0x6c, 0xd8, 0xab, 0x4d, 0x9a, 0x2f, 0x5e, 0xbc, 0x63, 0xc6, 0x97, 0x35, 0x6a, 0xd4 }; private int[] state = new int[4], // a subKeys = new int[4], // k decryptKeys = new int[4]; private boolean _initialised, _forEncryption; /** * Create an instance of the Noekeon encryption algorithm * and set some defaults */ public NoekeonEngine() { _initialised = false; } public String getAlgorithmName() { return "Noekeon"; } public int getBlockSize() { return genericSize; } /** * initialise * * @param forEncryption whether or not we are for encryption. * @param params the parameters required to set up the cipher. * @exception IllegalArgumentException if the params argument is * inappropriate. */ public void init( boolean forEncryption, CipherParameters params) { if (!(params instanceof KeyParameter)) { throw new IllegalArgumentException("invalid parameter passed to Noekeon init - " + params.getClass().getName()); } _forEncryption = forEncryption; _initialised = true; KeyParameter p = (KeyParameter)params; setKey(p.getKey()); } public int processBlock( byte[] in, int inOff, byte[] out, int outOff) { if (!_initialised) { throw new IllegalStateException(getAlgorithmName()+" not initialised"); } if ((inOff + genericSize) > in.length) { throw new DataLengthException("input buffer too short"); } if ((outOff + genericSize) > out.length) { throw new OutputLengthException("output buffer too short"); } return (_forEncryption) ? encryptBlock(in, inOff, out, outOff) : decryptBlock(in, inOff, out, outOff); } public void reset() { } /** * Re-key the cipher. *

    * @param key the key to be used */ private void setKey( byte[] key) { subKeys[0] = bytesToIntBig(key, 0); subKeys[1] = bytesToIntBig(key, 4); subKeys[2] = bytesToIntBig(key, 8); subKeys[3] = bytesToIntBig(key, 12); } private int encryptBlock( byte[] in, int inOff, byte[] out, int outOff) { state[0] = bytesToIntBig(in, inOff); state[1] = bytesToIntBig(in, inOff+4); state[2] = bytesToIntBig(in, inOff+8); state[3] = bytesToIntBig(in, inOff+12); int i; for (i = 0; i < genericSize; i++) { state[0] ^= roundConstants[i]; theta(state, subKeys); pi1(state); gamma(state); pi2(state); } state[0] ^= roundConstants[i]; theta(state, subKeys); intToBytesBig(state[0], out, outOff); intToBytesBig(state[1], out, outOff+4); intToBytesBig(state[2], out, outOff+8); intToBytesBig(state[3], out, outOff+12); return genericSize; } private int decryptBlock( byte[] in, int inOff, byte[] out, int outOff) { state[0] = bytesToIntBig(in, inOff); state[1] = bytesToIntBig(in, inOff+4); state[2] = bytesToIntBig(in, inOff+8); state[3] = bytesToIntBig(in, inOff+12); System.arraycopy(subKeys, 0, decryptKeys, 0, subKeys.length); theta(decryptKeys, nullVector); int i; for (i = genericSize; i > 0; i--) { theta(state, decryptKeys); state[0] ^= roundConstants[i]; pi1(state); gamma(state); pi2(state); } theta(state, decryptKeys); state[0] ^= roundConstants[i]; intToBytesBig(state[0], out, outOff); intToBytesBig(state[1], out, outOff+4); intToBytesBig(state[2], out, outOff+8); intToBytesBig(state[3], out, outOff+12); return genericSize; } private void gamma(int[] a) { a[1] ^= ~a[3] & ~a[2]; a[0] ^= a[2] & a[1]; int tmp = a[3]; a[3] = a[0]; a[0] = tmp; a[2] ^= a[0]^a[1]^a[3]; a[1] ^= ~a[3] & ~a[2]; a[0] ^= a[2] & a[1]; } private void theta(int[] a, int[] k) { int tmp; tmp = a[0]^a[2]; tmp ^= rotl(tmp,8)^rotl(tmp,24); a[1] ^= tmp; a[3] ^= tmp; for (int i = 0; i < 4; i++) { a[i] ^= k[i]; } tmp = a[1]^a[3]; tmp ^= rotl(tmp,8)^rotl(tmp,24); a[0] ^= tmp; a[2] ^= tmp; } private void pi1(int[] a) { a[1] = rotl(a[1], 1); a[2] = rotl(a[2], 5); a[3] = rotl(a[3], 2); } private void pi2(int[] a) { a[1] = rotl(a[1], 31); a[2] = rotl(a[2], 27); a[3] = rotl(a[3], 30); } // Helpers private int bytesToIntBig(byte[] in, int off) { return ((in[off++]) << 24) | ((in[off++] & 0xff) << 16) | ((in[off++] & 0xff) << 8) | (in[off ] & 0xff); } private void intToBytesBig(int x, byte[] out, int off) { out[off++] = (byte)(x >>> 24); out[off++] = (byte)(x >>> 16); out[off++] = (byte)(x >>> 8); out[off ] = (byte)x; } private int rotl(int x, int y) { return (x << y) | (x >>> (32-y)); } } bouncycastle-1.49.orig/src/org/bouncycastle/crypto/engines/DESEngine.java0000644000175000017500000004215212106330250026052 0ustar ebourgebourgpackage org.bouncycastle.crypto.engines; import org.bouncycastle.crypto.BlockCipher; import org.bouncycastle.crypto.CipherParameters; import org.bouncycastle.crypto.DataLengthException; import org.bouncycastle.crypto.OutputLengthException; import org.bouncycastle.crypto.params.KeyParameter; /** * a class that provides a basic DES engine. */ public class DESEngine implements BlockCipher { protected static final int BLOCK_SIZE = 8; private int[] workingKey = null; /** * standard constructor. */ public DESEngine() { } /** * initialise a DES cipher. * * @param encrypting whether or not we are for encryption. * @param params the parameters required to set up the cipher. * @exception IllegalArgumentException if the params argument is * inappropriate. */ public void init( boolean encrypting, CipherParameters params) { if (params instanceof KeyParameter) { if (((KeyParameter)params).getKey().length > 8) { throw new IllegalArgumentException("DES key too long - should be 8 bytes"); } workingKey = generateWorkingKey(encrypting, ((KeyParameter)params).getKey()); return; } throw new IllegalArgumentException("invalid parameter passed to DES init - " + params.getClass().getName()); } public String getAlgorithmName() { return "DES"; } public int getBlockSize() { return BLOCK_SIZE; } public int processBlock( byte[] in, int inOff, byte[] out, int outOff) { if (workingKey == null) { throw new IllegalStateException("DES engine not initialised"); } if ((inOff + BLOCK_SIZE) > in.length) { throw new DataLengthException("input buffer too short"); } if ((outOff + BLOCK_SIZE) > out.length) { throw new OutputLengthException("output buffer too short"); } desFunc(workingKey, in, inOff, out, outOff); return BLOCK_SIZE; } public void reset() { } /** * what follows is mainly taken from "Applied Cryptography", by * Bruce Schneier, however it also bears great resemblance to Richard * Outerbridge's D3DES... */ // private static final short[] Df_Key = // { // 0x01,0x23,0x45,0x67,0x89,0xab,0xcd,0xef, // 0xfe,0xdc,0xba,0x98,0x76,0x54,0x32,0x10, // 0x89,0xab,0xcd,0xef,0x01,0x23,0x45,0x67 // }; private static final short[] bytebit = { 0200, 0100, 040, 020, 010, 04, 02, 01 }; private static final int[] bigbyte = { 0x800000, 0x400000, 0x200000, 0x100000, 0x80000, 0x40000, 0x20000, 0x10000, 0x8000, 0x4000, 0x2000, 0x1000, 0x800, 0x400, 0x200, 0x100, 0x80, 0x40, 0x20, 0x10, 0x8, 0x4, 0x2, 0x1 }; /* * Use the key schedule specified in the Standard (ANSI X3.92-1981). */ private static final byte[] pc1 = { 56, 48, 40, 32, 24, 16, 8, 0, 57, 49, 41, 33, 25, 17, 9, 1, 58, 50, 42, 34, 26, 18, 10, 2, 59, 51, 43, 35, 62, 54, 46, 38, 30, 22, 14, 6, 61, 53, 45, 37, 29, 21, 13, 5, 60, 52, 44, 36, 28, 20, 12, 4, 27, 19, 11, 3 }; private static final byte[] totrot = { 1, 2, 4, 6, 8, 10, 12, 14, 15, 17, 19, 21, 23, 25, 27, 28 }; private static final byte[] pc2 = { 13, 16, 10, 23, 0, 4, 2, 27, 14, 5, 20, 9, 22, 18, 11, 3, 25, 7, 15, 6, 26, 19, 12, 1, 40, 51, 30, 36, 46, 54, 29, 39, 50, 44, 32, 47, 43, 48, 38, 55, 33, 52, 45, 41, 49, 35, 28, 31 }; private static final int[] SP1 = { 0x01010400, 0x00000000, 0x00010000, 0x01010404, 0x01010004, 0x00010404, 0x00000004, 0x00010000, 0x00000400, 0x01010400, 0x01010404, 0x00000400, 0x01000404, 0x01010004, 0x01000000, 0x00000004, 0x00000404, 0x01000400, 0x01000400, 0x00010400, 0x00010400, 0x01010000, 0x01010000, 0x01000404, 0x00010004, 0x01000004, 0x01000004, 0x00010004, 0x00000000, 0x00000404, 0x00010404, 0x01000000, 0x00010000, 0x01010404, 0x00000004, 0x01010000, 0x01010400, 0x01000000, 0x01000000, 0x00000400, 0x01010004, 0x00010000, 0x00010400, 0x01000004, 0x00000400, 0x00000004, 0x01000404, 0x00010404, 0x01010404, 0x00010004, 0x01010000, 0x01000404, 0x01000004, 0x00000404, 0x00010404, 0x01010400, 0x00000404, 0x01000400, 0x01000400, 0x00000000, 0x00010004, 0x00010400, 0x00000000, 0x01010004 }; private static final int[] SP2 = { 0x80108020, 0x80008000, 0x00008000, 0x00108020, 0x00100000, 0x00000020, 0x80100020, 0x80008020, 0x80000020, 0x80108020, 0x80108000, 0x80000000, 0x80008000, 0x00100000, 0x00000020, 0x80100020, 0x00108000, 0x00100020, 0x80008020, 0x00000000, 0x80000000, 0x00008000, 0x00108020, 0x80100000, 0x00100020, 0x80000020, 0x00000000, 0x00108000, 0x00008020, 0x80108000, 0x80100000, 0x00008020, 0x00000000, 0x00108020, 0x80100020, 0x00100000, 0x80008020, 0x80100000, 0x80108000, 0x00008000, 0x80100000, 0x80008000, 0x00000020, 0x80108020, 0x00108020, 0x00000020, 0x00008000, 0x80000000, 0x00008020, 0x80108000, 0x00100000, 0x80000020, 0x00100020, 0x80008020, 0x80000020, 0x00100020, 0x00108000, 0x00000000, 0x80008000, 0x00008020, 0x80000000, 0x80100020, 0x80108020, 0x00108000 }; private static final int[] SP3 = { 0x00000208, 0x08020200, 0x00000000, 0x08020008, 0x08000200, 0x00000000, 0x00020208, 0x08000200, 0x00020008, 0x08000008, 0x08000008, 0x00020000, 0x08020208, 0x00020008, 0x08020000, 0x00000208, 0x08000000, 0x00000008, 0x08020200, 0x00000200, 0x00020200, 0x08020000, 0x08020008, 0x00020208, 0x08000208, 0x00020200, 0x00020000, 0x08000208, 0x00000008, 0x08020208, 0x00000200, 0x08000000, 0x08020200, 0x08000000, 0x00020008, 0x00000208, 0x00020000, 0x08020200, 0x08000200, 0x00000000, 0x00000200, 0x00020008, 0x08020208, 0x08000200, 0x08000008, 0x00000200, 0x00000000, 0x08020008, 0x08000208, 0x00020000, 0x08000000, 0x08020208, 0x00000008, 0x00020208, 0x00020200, 0x08000008, 0x08020000, 0x08000208, 0x00000208, 0x08020000, 0x00020208, 0x00000008, 0x08020008, 0x00020200 }; private static final int[] SP4 = { 0x00802001, 0x00002081, 0x00002081, 0x00000080, 0x00802080, 0x00800081, 0x00800001, 0x00002001, 0x00000000, 0x00802000, 0x00802000, 0x00802081, 0x00000081, 0x00000000, 0x00800080, 0x00800001, 0x00000001, 0x00002000, 0x00800000, 0x00802001, 0x00000080, 0x00800000, 0x00002001, 0x00002080, 0x00800081, 0x00000001, 0x00002080, 0x00800080, 0x00002000, 0x00802080, 0x00802081, 0x00000081, 0x00800080, 0x00800001, 0x00802000, 0x00802081, 0x00000081, 0x00000000, 0x00000000, 0x00802000, 0x00002080, 0x00800080, 0x00800081, 0x00000001, 0x00802001, 0x00002081, 0x00002081, 0x00000080, 0x00802081, 0x00000081, 0x00000001, 0x00002000, 0x00800001, 0x00002001, 0x00802080, 0x00800081, 0x00002001, 0x00002080, 0x00800000, 0x00802001, 0x00000080, 0x00800000, 0x00002000, 0x00802080 }; private static final int[] SP5 = { 0x00000100, 0x02080100, 0x02080000, 0x42000100, 0x00080000, 0x00000100, 0x40000000, 0x02080000, 0x40080100, 0x00080000, 0x02000100, 0x40080100, 0x42000100, 0x42080000, 0x00080100, 0x40000000, 0x02000000, 0x40080000, 0x40080000, 0x00000000, 0x40000100, 0x42080100, 0x42080100, 0x02000100, 0x42080000, 0x40000100, 0x00000000, 0x42000000, 0x02080100, 0x02000000, 0x42000000, 0x00080100, 0x00080000, 0x42000100, 0x00000100, 0x02000000, 0x40000000, 0x02080000, 0x42000100, 0x40080100, 0x02000100, 0x40000000, 0x42080000, 0x02080100, 0x40080100, 0x00000100, 0x02000000, 0x42080000, 0x42080100, 0x00080100, 0x42000000, 0x42080100, 0x02080000, 0x00000000, 0x40080000, 0x42000000, 0x00080100, 0x02000100, 0x40000100, 0x00080000, 0x00000000, 0x40080000, 0x02080100, 0x40000100 }; private static final int[] SP6 = { 0x20000010, 0x20400000, 0x00004000, 0x20404010, 0x20400000, 0x00000010, 0x20404010, 0x00400000, 0x20004000, 0x00404010, 0x00400000, 0x20000010, 0x00400010, 0x20004000, 0x20000000, 0x00004010, 0x00000000, 0x00400010, 0x20004010, 0x00004000, 0x00404000, 0x20004010, 0x00000010, 0x20400010, 0x20400010, 0x00000000, 0x00404010, 0x20404000, 0x00004010, 0x00404000, 0x20404000, 0x20000000, 0x20004000, 0x00000010, 0x20400010, 0x00404000, 0x20404010, 0x00400000, 0x00004010, 0x20000010, 0x00400000, 0x20004000, 0x20000000, 0x00004010, 0x20000010, 0x20404010, 0x00404000, 0x20400000, 0x00404010, 0x20404000, 0x00000000, 0x20400010, 0x00000010, 0x00004000, 0x20400000, 0x00404010, 0x00004000, 0x00400010, 0x20004010, 0x00000000, 0x20404000, 0x20000000, 0x00400010, 0x20004010 }; private static final int[] SP7 = { 0x00200000, 0x04200002, 0x04000802, 0x00000000, 0x00000800, 0x04000802, 0x00200802, 0x04200800, 0x04200802, 0x00200000, 0x00000000, 0x04000002, 0x00000002, 0x04000000, 0x04200002, 0x00000802, 0x04000800, 0x00200802, 0x00200002, 0x04000800, 0x04000002, 0x04200000, 0x04200800, 0x00200002, 0x04200000, 0x00000800, 0x00000802, 0x04200802, 0x00200800, 0x00000002, 0x04000000, 0x00200800, 0x04000000, 0x00200800, 0x00200000, 0x04000802, 0x04000802, 0x04200002, 0x04200002, 0x00000002, 0x00200002, 0x04000000, 0x04000800, 0x00200000, 0x04200800, 0x00000802, 0x00200802, 0x04200800, 0x00000802, 0x04000002, 0x04200802, 0x04200000, 0x00200800, 0x00000000, 0x00000002, 0x04200802, 0x00000000, 0x00200802, 0x04200000, 0x00000800, 0x04000002, 0x04000800, 0x00000800, 0x00200002 }; private static final int[] SP8 = { 0x10001040, 0x00001000, 0x00040000, 0x10041040, 0x10000000, 0x10001040, 0x00000040, 0x10000000, 0x00040040, 0x10040000, 0x10041040, 0x00041000, 0x10041000, 0x00041040, 0x00001000, 0x00000040, 0x10040000, 0x10000040, 0x10001000, 0x00001040, 0x00041000, 0x00040040, 0x10040040, 0x10041000, 0x00001040, 0x00000000, 0x00000000, 0x10040040, 0x10000040, 0x10001000, 0x00041040, 0x00040000, 0x00041040, 0x00040000, 0x10041000, 0x00001000, 0x00000040, 0x10040040, 0x00001000, 0x00041040, 0x10001000, 0x00000040, 0x10000040, 0x10040000, 0x10040040, 0x10000000, 0x00040000, 0x10001040, 0x00000000, 0x10041040, 0x00040040, 0x10000040, 0x10040000, 0x10001000, 0x10001040, 0x00000000, 0x10041040, 0x00041000, 0x00041000, 0x00001040, 0x00001040, 0x00040040, 0x10000000, 0x10041000 }; /** * generate an integer based working key based on our secret key * and what we processing we are planning to do. * * Acknowledgements for this routine go to James Gillogly & Phil Karn. * (whoever, and wherever they are!). */ protected int[] generateWorkingKey( boolean encrypting, byte[] key) { int[] newKey = new int[32]; boolean[] pc1m = new boolean[56], pcr = new boolean[56]; for (int j = 0; j < 56; j++) { int l = pc1[j]; pc1m[j] = ((key[l >>> 3] & bytebit[l & 07]) != 0); } for (int i = 0; i < 16; i++) { int l, m, n; if (encrypting) { m = i << 1; } else { m = (15 - i) << 1; } n = m + 1; newKey[m] = newKey[n] = 0; for (int j = 0; j < 28; j++) { l = j + totrot[i]; if (l < 28) { pcr[j] = pc1m[l]; } else { pcr[j] = pc1m[l - 28]; } } for (int j = 28; j < 56; j++) { l = j + totrot[i]; if (l < 56) { pcr[j] = pc1m[l]; } else { pcr[j] = pc1m[l - 28]; } } for (int j = 0; j < 24; j++) { if (pcr[pc2[j]]) { newKey[m] |= bigbyte[j]; } if (pcr[pc2[j + 24]]) { newKey[n] |= bigbyte[j]; } } } // // store the processed key // for (int i = 0; i != 32; i += 2) { int i1, i2; i1 = newKey[i]; i2 = newKey[i + 1]; newKey[i] = ((i1 & 0x00fc0000) << 6) | ((i1 & 0x00000fc0) << 10) | ((i2 & 0x00fc0000) >>> 10) | ((i2 & 0x00000fc0) >>> 6); newKey[i + 1] = ((i1 & 0x0003f000) << 12) | ((i1 & 0x0000003f) << 16) | ((i2 & 0x0003f000) >>> 4) | (i2 & 0x0000003f); } return newKey; } /** * the DES engine. */ protected void desFunc( int[] wKey, byte[] in, int inOff, byte[] out, int outOff) { int work, right, left; left = (in[inOff + 0] & 0xff) << 24; left |= (in[inOff + 1] & 0xff) << 16; left |= (in[inOff + 2] & 0xff) << 8; left |= (in[inOff + 3] & 0xff); right = (in[inOff + 4] & 0xff) << 24; right |= (in[inOff + 5] & 0xff) << 16; right |= (in[inOff + 6] & 0xff) << 8; right |= (in[inOff + 7] & 0xff); work = ((left >>> 4) ^ right) & 0x0f0f0f0f; right ^= work; left ^= (work << 4); work = ((left >>> 16) ^ right) & 0x0000ffff; right ^= work; left ^= (work << 16); work = ((right >>> 2) ^ left) & 0x33333333; left ^= work; right ^= (work << 2); work = ((right >>> 8) ^ left) & 0x00ff00ff; left ^= work; right ^= (work << 8); right = ((right << 1) | ((right >>> 31) & 1)) & 0xffffffff; work = (left ^ right) & 0xaaaaaaaa; left ^= work; right ^= work; left = ((left << 1) | ((left >>> 31) & 1)) & 0xffffffff; for (int round = 0; round < 8; round++) { int fval; work = (right << 28) | (right >>> 4); work ^= wKey[round * 4 + 0]; fval = SP7[ work & 0x3f]; fval |= SP5[(work >>> 8) & 0x3f]; fval |= SP3[(work >>> 16) & 0x3f]; fval |= SP1[(work >>> 24) & 0x3f]; work = right ^ wKey[round * 4 + 1]; fval |= SP8[ work & 0x3f]; fval |= SP6[(work >>> 8) & 0x3f]; fval |= SP4[(work >>> 16) & 0x3f]; fval |= SP2[(work >>> 24) & 0x3f]; left ^= fval; work = (left << 28) | (left >>> 4); work ^= wKey[round * 4 + 2]; fval = SP7[ work & 0x3f]; fval |= SP5[(work >>> 8) & 0x3f]; fval |= SP3[(work >>> 16) & 0x3f]; fval |= SP1[(work >>> 24) & 0x3f]; work = left ^ wKey[round * 4 + 3]; fval |= SP8[ work & 0x3f]; fval |= SP6[(work >>> 8) & 0x3f]; fval |= SP4[(work >>> 16) & 0x3f]; fval |= SP2[(work >>> 24) & 0x3f]; right ^= fval; } right = (right << 31) | (right >>> 1); work = (left ^ right) & 0xaaaaaaaa; left ^= work; right ^= work; left = (left << 31) | (left >>> 1); work = ((left >>> 8) ^ right) & 0x00ff00ff; right ^= work; left ^= (work << 8); work = ((left >>> 2) ^ right) & 0x33333333; right ^= work; left ^= (work << 2); work = ((right >>> 16) ^ left) & 0x0000ffff; left ^= work; right ^= (work << 16); work = ((right >>> 4) ^ left) & 0x0f0f0f0f; left ^= work; right ^= (work << 4); out[outOff + 0] = (byte)((right >>> 24) & 0xff); out[outOff + 1] = (byte)((right >>> 16) & 0xff); out[outOff + 2] = (byte)((right >>> 8) & 0xff); out[outOff + 3] = (byte)(right & 0xff); out[outOff + 4] = (byte)((left >>> 24) & 0xff); out[outOff + 5] = (byte)((left >>> 16) & 0xff); out[outOff + 6] = (byte)((left >>> 8) & 0xff); out[outOff + 7] = (byte)(left & 0xff); } } bouncycastle-1.49.orig/src/org/bouncycastle/crypto/engines/Grainv1Engine.java0000644000175000017500000002010012106330250026733 0ustar ebourgebourgpackage org.bouncycastle.crypto.engines; import org.bouncycastle.crypto.CipherParameters; import org.bouncycastle.crypto.DataLengthException; import org.bouncycastle.crypto.OutputLengthException; import org.bouncycastle.crypto.StreamCipher; import org.bouncycastle.crypto.params.KeyParameter; import org.bouncycastle.crypto.params.ParametersWithIV; /** * Implementation of Martin Hell's, Thomas Johansson's and Willi Meier's stream * cipher, Grain v1. */ public class Grainv1Engine implements StreamCipher { /** * Constants */ private static final int STATE_SIZE = 5; /** * Variables to hold the state of the engine during encryption and * decryption */ private byte[] workingKey; private byte[] workingIV; private byte[] out; private int[] lfsr; private int[] nfsr; private int output; private int index = 2; private boolean initialised = false; public String getAlgorithmName() { return "Grain v1"; } /** * Initialize a Grain v1 cipher. * * @param forEncryption Whether or not we are for encryption. * @param params The parameters required to set up the cipher. * @throws IllegalArgumentException If the params argument is inappropriate. */ public void init(boolean forEncryption, CipherParameters params) throws IllegalArgumentException { /** * Grain encryption and decryption is completely symmetrical, so the * 'forEncryption' is irrelevant. */ if (!(params instanceof ParametersWithIV)) { throw new IllegalArgumentException( "Grain v1 Init parameters must include an IV"); } ParametersWithIV ivParams = (ParametersWithIV)params; byte[] iv = ivParams.getIV(); if (iv == null || iv.length != 8) { throw new IllegalArgumentException( "Grain v1 requires exactly 8 bytes of IV"); } if (!(ivParams.getParameters() instanceof KeyParameter)) { throw new IllegalArgumentException( "Grain v1 Init parameters must include a key"); } KeyParameter key = (KeyParameter)ivParams.getParameters(); /** * Initialize variables. */ workingIV = new byte[key.getKey().length]; workingKey = new byte[key.getKey().length]; lfsr = new int[STATE_SIZE]; nfsr = new int[STATE_SIZE]; out = new byte[2]; System.arraycopy(iv, 0, workingIV, 0, iv.length); System.arraycopy(key.getKey(), 0, workingKey, 0, key.getKey().length); setKey(workingKey, workingIV); initGrain(); } /** * 160 clocks initialization phase. */ private void initGrain() { for (int i = 0; i < 10; i++) { output = getOutput(); nfsr = shift(nfsr, getOutputNFSR() ^ lfsr[0] ^ output); lfsr = shift(lfsr, getOutputLFSR() ^ output); } initialised = true; } /** * Get output from non-linear function g(x). * * @return Output from NFSR. */ private int getOutputNFSR() { int b0 = nfsr[0]; int b9 = nfsr[0] >>> 9 | nfsr[1] << 7; int b14 = nfsr[0] >>> 14 | nfsr[1] << 2; int b15 = nfsr[0] >>> 15 | nfsr[1] << 1; int b21 = nfsr[1] >>> 5 | nfsr[2] << 11; int b28 = nfsr[1] >>> 12 | nfsr[2] << 4; int b33 = nfsr[2] >>> 1 | nfsr[3] << 15; int b37 = nfsr[2] >>> 5 | nfsr[3] << 11; int b45 = nfsr[2] >>> 13 | nfsr[3] << 3; int b52 = nfsr[3] >>> 4 | nfsr[4] << 12; int b60 = nfsr[3] >>> 12 | nfsr[4] << 4; int b62 = nfsr[3] >>> 14 | nfsr[4] << 2; int b63 = nfsr[3] >>> 15 | nfsr[4] << 1; return (b62 ^ b60 ^ b52 ^ b45 ^ b37 ^ b33 ^ b28 ^ b21 ^ b14 ^ b9 ^ b0 ^ b63 & b60 ^ b37 & b33 ^ b15 & b9 ^ b60 & b52 & b45 ^ b33 & b28 & b21 ^ b63 & b45 & b28 & b9 ^ b60 & b52 & b37 & b33 ^ b63 & b60 & b21 & b15 ^ b63 & b60 & b52 & b45 & b37 ^ b33 & b28 & b21 & b15 & b9 ^ b52 & b45 & b37 & b33 & b28 & b21) & 0x0000FFFF; } /** * Get output from linear function f(x). * * @return Output from LFSR. */ private int getOutputLFSR() { int s0 = lfsr[0]; int s13 = lfsr[0] >>> 13 | lfsr[1] << 3; int s23 = lfsr[1] >>> 7 | lfsr[2] << 9; int s38 = lfsr[2] >>> 6 | lfsr[3] << 10; int s51 = lfsr[3] >>> 3 | lfsr[4] << 13; int s62 = lfsr[3] >>> 14 | lfsr[4] << 2; return (s0 ^ s13 ^ s23 ^ s38 ^ s51 ^ s62) & 0x0000FFFF; } /** * Get output from output function h(x). * * @return Output from h(x). */ private int getOutput() { int b1 = nfsr[0] >>> 1 | nfsr[1] << 15; int b2 = nfsr[0] >>> 2 | nfsr[1] << 14; int b4 = nfsr[0] >>> 4 | nfsr[1] << 12; int b10 = nfsr[0] >>> 10 | nfsr[1] << 6; int b31 = nfsr[1] >>> 15 | nfsr[2] << 1; int b43 = nfsr[2] >>> 11 | nfsr[3] << 5; int b56 = nfsr[3] >>> 8 | nfsr[4] << 8; int b63 = nfsr[3] >>> 15 | nfsr[4] << 1; int s3 = lfsr[0] >>> 3 | lfsr[1] << 13; int s25 = lfsr[1] >>> 9 | lfsr[2] << 7; int s46 = lfsr[2] >>> 14 | lfsr[3] << 2; int s64 = lfsr[4]; return (s25 ^ b63 ^ s3 & s64 ^ s46 & s64 ^ s64 & b63 ^ s3 & s25 & s46 ^ s3 & s46 & s64 ^ s3 & s46 & b63 ^ s25 & s46 & b63 ^ s46 & s64 & b63 ^ b1 ^ b2 ^ b4 ^ b10 ^ b31 ^ b43 ^ b56) & 0x0000FFFF; } /** * Shift array 16 bits and add val to index.length - 1. * * @param array The array to shift. * @param val The value to shift in. * @return The shifted array with val added to index.length - 1. */ private int[] shift(int[] array, int val) { array[0] = array[1]; array[1] = array[2]; array[2] = array[3]; array[3] = array[4]; array[4] = val; return array; } /** * Set keys, reset cipher. * * @param keyBytes The key. * @param ivBytes The IV. */ private void setKey(byte[] keyBytes, byte[] ivBytes) { ivBytes[8] = (byte)0xFF; ivBytes[9] = (byte)0xFF; workingKey = keyBytes; workingIV = ivBytes; /** * Load NFSR and LFSR */ int j = 0; for (int i = 0; i < nfsr.length; i++) { nfsr[i] = (workingKey[j + 1] << 8 | workingKey[j] & 0xFF) & 0x0000FFFF; lfsr[i] = (workingIV[j + 1] << 8 | workingIV[j] & 0xFF) & 0x0000FFFF; j += 2; } } public void processBytes(byte[] in, int inOff, int len, byte[] out, int outOff) throws DataLengthException { if (!initialised) { throw new IllegalStateException(getAlgorithmName() + " not initialised"); } if ((inOff + len) > in.length) { throw new DataLengthException("input buffer too short"); } if ((outOff + len) > out.length) { throw new OutputLengthException("output buffer too short"); } for (int i = 0; i < len; i++) { out[outOff + i] = (byte)(in[inOff + i] ^ getKeyStream()); } } public void reset() { index = 2; setKey(workingKey, workingIV); initGrain(); } /** * Run Grain one round(i.e. 16 bits). */ private void oneRound() { output = getOutput(); out[0] = (byte)output; out[1] = (byte)(output >> 8); nfsr = shift(nfsr, getOutputNFSR() ^ lfsr[0]); lfsr = shift(lfsr, getOutputLFSR()); } public byte returnByte(byte in) { if (!initialised) { throw new IllegalStateException(getAlgorithmName() + " not initialised"); } return (byte)(in ^ getKeyStream()); } private byte getKeyStream() { if (index > 1) { oneRound(); index = 0; } return out[index++]; } }bouncycastle-1.49.orig/src/org/bouncycastle/crypto/engines/BlowfishEngine.java0000644000175000017500000006117612106330733027231 0ustar ebourgebourgpackage org.bouncycastle.crypto.engines; import org.bouncycastle.crypto.BlockCipher; import org.bouncycastle.crypto.CipherParameters; import org.bouncycastle.crypto.DataLengthException; import org.bouncycastle.crypto.OutputLengthException; import org.bouncycastle.crypto.params.KeyParameter; /** * A class that provides Blowfish key encryption operations, * such as encoding data and generating keys. * All the algorithms herein are from Applied Cryptography * and implement a simplified cryptography interface. */ public final class BlowfishEngine implements BlockCipher { private final static int[] KP = { 0x243F6A88, 0x85A308D3, 0x13198A2E, 0x03707344, 0xA4093822, 0x299F31D0, 0x082EFA98, 0xEC4E6C89, 0x452821E6, 0x38D01377, 0xBE5466CF, 0x34E90C6C, 0xC0AC29B7, 0xC97C50DD, 0x3F84D5B5, 0xB5470917, 0x9216D5D9, 0x8979FB1B }, KS0 = { 0xD1310BA6, 0x98DFB5AC, 0x2FFD72DB, 0xD01ADFB7, 0xB8E1AFED, 0x6A267E96, 0xBA7C9045, 0xF12C7F99, 0x24A19947, 0xB3916CF7, 0x0801F2E2, 0x858EFC16, 0x636920D8, 0x71574E69, 0xA458FEA3, 0xF4933D7E, 0x0D95748F, 0x728EB658, 0x718BCD58, 0x82154AEE, 0x7B54A41D, 0xC25A59B5, 0x9C30D539, 0x2AF26013, 0xC5D1B023, 0x286085F0, 0xCA417918, 0xB8DB38EF, 0x8E79DCB0, 0x603A180E, 0x6C9E0E8B, 0xB01E8A3E, 0xD71577C1, 0xBD314B27, 0x78AF2FDA, 0x55605C60, 0xE65525F3, 0xAA55AB94, 0x57489862, 0x63E81440, 0x55CA396A, 0x2AAB10B6, 0xB4CC5C34, 0x1141E8CE, 0xA15486AF, 0x7C72E993, 0xB3EE1411, 0x636FBC2A, 0x2BA9C55D, 0x741831F6, 0xCE5C3E16, 0x9B87931E, 0xAFD6BA33, 0x6C24CF5C, 0x7A325381, 0x28958677, 0x3B8F4898, 0x6B4BB9AF, 0xC4BFE81B, 0x66282193, 0x61D809CC, 0xFB21A991, 0x487CAC60, 0x5DEC8032, 0xEF845D5D, 0xE98575B1, 0xDC262302, 0xEB651B88, 0x23893E81, 0xD396ACC5, 0x0F6D6FF3, 0x83F44239, 0x2E0B4482, 0xA4842004, 0x69C8F04A, 0x9E1F9B5E, 0x21C66842, 0xF6E96C9A, 0x670C9C61, 0xABD388F0, 0x6A51A0D2, 0xD8542F68, 0x960FA728, 0xAB5133A3, 0x6EEF0B6C, 0x137A3BE4, 0xBA3BF050, 0x7EFB2A98, 0xA1F1651D, 0x39AF0176, 0x66CA593E, 0x82430E88, 0x8CEE8619, 0x456F9FB4, 0x7D84A5C3, 0x3B8B5EBE, 0xE06F75D8, 0x85C12073, 0x401A449F, 0x56C16AA6, 0x4ED3AA62, 0x363F7706, 0x1BFEDF72, 0x429B023D, 0x37D0D724, 0xD00A1248, 0xDB0FEAD3, 0x49F1C09B, 0x075372C9, 0x80991B7B, 0x25D479D8, 0xF6E8DEF7, 0xE3FE501A, 0xB6794C3B, 0x976CE0BD, 0x04C006BA, 0xC1A94FB6, 0x409F60C4, 0x5E5C9EC2, 0x196A2463, 0x68FB6FAF, 0x3E6C53B5, 0x1339B2EB, 0x3B52EC6F, 0x6DFC511F, 0x9B30952C, 0xCC814544, 0xAF5EBD09, 0xBEE3D004, 0xDE334AFD, 0x660F2807, 0x192E4BB3, 0xC0CBA857, 0x45C8740F, 0xD20B5F39, 0xB9D3FBDB, 0x5579C0BD, 0x1A60320A, 0xD6A100C6, 0x402C7279, 0x679F25FE, 0xFB1FA3CC, 0x8EA5E9F8, 0xDB3222F8, 0x3C7516DF, 0xFD616B15, 0x2F501EC8, 0xAD0552AB, 0x323DB5FA, 0xFD238760, 0x53317B48, 0x3E00DF82, 0x9E5C57BB, 0xCA6F8CA0, 0x1A87562E, 0xDF1769DB, 0xD542A8F6, 0x287EFFC3, 0xAC6732C6, 0x8C4F5573, 0x695B27B0, 0xBBCA58C8, 0xE1FFA35D, 0xB8F011A0, 0x10FA3D98, 0xFD2183B8, 0x4AFCB56C, 0x2DD1D35B, 0x9A53E479, 0xB6F84565, 0xD28E49BC, 0x4BFB9790, 0xE1DDF2DA, 0xA4CB7E33, 0x62FB1341, 0xCEE4C6E8, 0xEF20CADA, 0x36774C01, 0xD07E9EFE, 0x2BF11FB4, 0x95DBDA4D, 0xAE909198, 0xEAAD8E71, 0x6B93D5A0, 0xD08ED1D0, 0xAFC725E0, 0x8E3C5B2F, 0x8E7594B7, 0x8FF6E2FB, 0xF2122B64, 0x8888B812, 0x900DF01C, 0x4FAD5EA0, 0x688FC31C, 0xD1CFF191, 0xB3A8C1AD, 0x2F2F2218, 0xBE0E1777, 0xEA752DFE, 0x8B021FA1, 0xE5A0CC0F, 0xB56F74E8, 0x18ACF3D6, 0xCE89E299, 0xB4A84FE0, 0xFD13E0B7, 0x7CC43B81, 0xD2ADA8D9, 0x165FA266, 0x80957705, 0x93CC7314, 0x211A1477, 0xE6AD2065, 0x77B5FA86, 0xC75442F5, 0xFB9D35CF, 0xEBCDAF0C, 0x7B3E89A0, 0xD6411BD3, 0xAE1E7E49, 0x00250E2D, 0x2071B35E, 0x226800BB, 0x57B8E0AF, 0x2464369B, 0xF009B91E, 0x5563911D, 0x59DFA6AA, 0x78C14389, 0xD95A537F, 0x207D5BA2, 0x02E5B9C5, 0x83260376, 0x6295CFA9, 0x11C81968, 0x4E734A41, 0xB3472DCA, 0x7B14A94A, 0x1B510052, 0x9A532915, 0xD60F573F, 0xBC9BC6E4, 0x2B60A476, 0x81E67400, 0x08BA6FB5, 0x571BE91F, 0xF296EC6B, 0x2A0DD915, 0xB6636521, 0xE7B9F9B6, 0xFF34052E, 0xC5855664, 0x53B02D5D, 0xA99F8FA1, 0x08BA4799, 0x6E85076A }, KS1 = { 0x4B7A70E9, 0xB5B32944, 0xDB75092E, 0xC4192623, 0xAD6EA6B0, 0x49A7DF7D, 0x9CEE60B8, 0x8FEDB266, 0xECAA8C71, 0x699A17FF, 0x5664526C, 0xC2B19EE1, 0x193602A5, 0x75094C29, 0xA0591340, 0xE4183A3E, 0x3F54989A, 0x5B429D65, 0x6B8FE4D6, 0x99F73FD6, 0xA1D29C07, 0xEFE830F5, 0x4D2D38E6, 0xF0255DC1, 0x4CDD2086, 0x8470EB26, 0x6382E9C6, 0x021ECC5E, 0x09686B3F, 0x3EBAEFC9, 0x3C971814, 0x6B6A70A1, 0x687F3584, 0x52A0E286, 0xB79C5305, 0xAA500737, 0x3E07841C, 0x7FDEAE5C, 0x8E7D44EC, 0x5716F2B8, 0xB03ADA37, 0xF0500C0D, 0xF01C1F04, 0x0200B3FF, 0xAE0CF51A, 0x3CB574B2, 0x25837A58, 0xDC0921BD, 0xD19113F9, 0x7CA92FF6, 0x94324773, 0x22F54701, 0x3AE5E581, 0x37C2DADC, 0xC8B57634, 0x9AF3DDA7, 0xA9446146, 0x0FD0030E, 0xECC8C73E, 0xA4751E41, 0xE238CD99, 0x3BEA0E2F, 0x3280BBA1, 0x183EB331, 0x4E548B38, 0x4F6DB908, 0x6F420D03, 0xF60A04BF, 0x2CB81290, 0x24977C79, 0x5679B072, 0xBCAF89AF, 0xDE9A771F, 0xD9930810, 0xB38BAE12, 0xDCCF3F2E, 0x5512721F, 0x2E6B7124, 0x501ADDE6, 0x9F84CD87, 0x7A584718, 0x7408DA17, 0xBC9F9ABC, 0xE94B7D8C, 0xEC7AEC3A, 0xDB851DFA, 0x63094366, 0xC464C3D2, 0xEF1C1847, 0x3215D908, 0xDD433B37, 0x24C2BA16, 0x12A14D43, 0x2A65C451, 0x50940002, 0x133AE4DD, 0x71DFF89E, 0x10314E55, 0x81AC77D6, 0x5F11199B, 0x043556F1, 0xD7A3C76B, 0x3C11183B, 0x5924A509, 0xF28FE6ED, 0x97F1FBFA, 0x9EBABF2C, 0x1E153C6E, 0x86E34570, 0xEAE96FB1, 0x860E5E0A, 0x5A3E2AB3, 0x771FE71C, 0x4E3D06FA, 0x2965DCB9, 0x99E71D0F, 0x803E89D6, 0x5266C825, 0x2E4CC978, 0x9C10B36A, 0xC6150EBA, 0x94E2EA78, 0xA5FC3C53, 0x1E0A2DF4, 0xF2F74EA7, 0x361D2B3D, 0x1939260F, 0x19C27960, 0x5223A708, 0xF71312B6, 0xEBADFE6E, 0xEAC31F66, 0xE3BC4595, 0xA67BC883, 0xB17F37D1, 0x018CFF28, 0xC332DDEF, 0xBE6C5AA5, 0x65582185, 0x68AB9802, 0xEECEA50F, 0xDB2F953B, 0x2AEF7DAD, 0x5B6E2F84, 0x1521B628, 0x29076170, 0xECDD4775, 0x619F1510, 0x13CCA830, 0xEB61BD96, 0x0334FE1E, 0xAA0363CF, 0xB5735C90, 0x4C70A239, 0xD59E9E0B, 0xCBAADE14, 0xEECC86BC, 0x60622CA7, 0x9CAB5CAB, 0xB2F3846E, 0x648B1EAF, 0x19BDF0CA, 0xA02369B9, 0x655ABB50, 0x40685A32, 0x3C2AB4B3, 0x319EE9D5, 0xC021B8F7, 0x9B540B19, 0x875FA099, 0x95F7997E, 0x623D7DA8, 0xF837889A, 0x97E32D77, 0x11ED935F, 0x16681281, 0x0E358829, 0xC7E61FD6, 0x96DEDFA1, 0x7858BA99, 0x57F584A5, 0x1B227263, 0x9B83C3FF, 0x1AC24696, 0xCDB30AEB, 0x532E3054, 0x8FD948E4, 0x6DBC3128, 0x58EBF2EF, 0x34C6FFEA, 0xFE28ED61, 0xEE7C3C73, 0x5D4A14D9, 0xE864B7E3, 0x42105D14, 0x203E13E0, 0x45EEE2B6, 0xA3AAABEA, 0xDB6C4F15, 0xFACB4FD0, 0xC742F442, 0xEF6ABBB5, 0x654F3B1D, 0x41CD2105, 0xD81E799E, 0x86854DC7, 0xE44B476A, 0x3D816250, 0xCF62A1F2, 0x5B8D2646, 0xFC8883A0, 0xC1C7B6A3, 0x7F1524C3, 0x69CB7492, 0x47848A0B, 0x5692B285, 0x095BBF00, 0xAD19489D, 0x1462B174, 0x23820E00, 0x58428D2A, 0x0C55F5EA, 0x1DADF43E, 0x233F7061, 0x3372F092, 0x8D937E41, 0xD65FECF1, 0x6C223BDB, 0x7CDE3759, 0xCBEE7460, 0x4085F2A7, 0xCE77326E, 0xA6078084, 0x19F8509E, 0xE8EFD855, 0x61D99735, 0xA969A7AA, 0xC50C06C2, 0x5A04ABFC, 0x800BCADC, 0x9E447A2E, 0xC3453484, 0xFDD56705, 0x0E1E9EC9, 0xDB73DBD3, 0x105588CD, 0x675FDA79, 0xE3674340, 0xC5C43465, 0x713E38D8, 0x3D28F89E, 0xF16DFF20, 0x153E21E7, 0x8FB03D4A, 0xE6E39F2B, 0xDB83ADF7 }, KS2 = { 0xE93D5A68, 0x948140F7, 0xF64C261C, 0x94692934, 0x411520F7, 0x7602D4F7, 0xBCF46B2E, 0xD4A20068, 0xD4082471, 0x3320F46A, 0x43B7D4B7, 0x500061AF, 0x1E39F62E, 0x97244546, 0x14214F74, 0xBF8B8840, 0x4D95FC1D, 0x96B591AF, 0x70F4DDD3, 0x66A02F45, 0xBFBC09EC, 0x03BD9785, 0x7FAC6DD0, 0x31CB8504, 0x96EB27B3, 0x55FD3941, 0xDA2547E6, 0xABCA0A9A, 0x28507825, 0x530429F4, 0x0A2C86DA, 0xE9B66DFB, 0x68DC1462, 0xD7486900, 0x680EC0A4, 0x27A18DEE, 0x4F3FFEA2, 0xE887AD8C, 0xB58CE006, 0x7AF4D6B6, 0xAACE1E7C, 0xD3375FEC, 0xCE78A399, 0x406B2A42, 0x20FE9E35, 0xD9F385B9, 0xEE39D7AB, 0x3B124E8B, 0x1DC9FAF7, 0x4B6D1856, 0x26A36631, 0xEAE397B2, 0x3A6EFA74, 0xDD5B4332, 0x6841E7F7, 0xCA7820FB, 0xFB0AF54E, 0xD8FEB397, 0x454056AC, 0xBA489527, 0x55533A3A, 0x20838D87, 0xFE6BA9B7, 0xD096954B, 0x55A867BC, 0xA1159A58, 0xCCA92963, 0x99E1DB33, 0xA62A4A56, 0x3F3125F9, 0x5EF47E1C, 0x9029317C, 0xFDF8E802, 0x04272F70, 0x80BB155C, 0x05282CE3, 0x95C11548, 0xE4C66D22, 0x48C1133F, 0xC70F86DC, 0x07F9C9EE, 0x41041F0F, 0x404779A4, 0x5D886E17, 0x325F51EB, 0xD59BC0D1, 0xF2BCC18F, 0x41113564, 0x257B7834, 0x602A9C60, 0xDFF8E8A3, 0x1F636C1B, 0x0E12B4C2, 0x02E1329E, 0xAF664FD1, 0xCAD18115, 0x6B2395E0, 0x333E92E1, 0x3B240B62, 0xEEBEB922, 0x85B2A20E, 0xE6BA0D99, 0xDE720C8C, 0x2DA2F728, 0xD0127845, 0x95B794FD, 0x647D0862, 0xE7CCF5F0, 0x5449A36F, 0x877D48FA, 0xC39DFD27, 0xF33E8D1E, 0x0A476341, 0x992EFF74, 0x3A6F6EAB, 0xF4F8FD37, 0xA812DC60, 0xA1EBDDF8, 0x991BE14C, 0xDB6E6B0D, 0xC67B5510, 0x6D672C37, 0x2765D43B, 0xDCD0E804, 0xF1290DC7, 0xCC00FFA3, 0xB5390F92, 0x690FED0B, 0x667B9FFB, 0xCEDB7D9C, 0xA091CF0B, 0xD9155EA3, 0xBB132F88, 0x515BAD24, 0x7B9479BF, 0x763BD6EB, 0x37392EB3, 0xCC115979, 0x8026E297, 0xF42E312D, 0x6842ADA7, 0xC66A2B3B, 0x12754CCC, 0x782EF11C, 0x6A124237, 0xB79251E7, 0x06A1BBE6, 0x4BFB6350, 0x1A6B1018, 0x11CAEDFA, 0x3D25BDD8, 0xE2E1C3C9, 0x44421659, 0x0A121386, 0xD90CEC6E, 0xD5ABEA2A, 0x64AF674E, 0xDA86A85F, 0xBEBFE988, 0x64E4C3FE, 0x9DBC8057, 0xF0F7C086, 0x60787BF8, 0x6003604D, 0xD1FD8346, 0xF6381FB0, 0x7745AE04, 0xD736FCCC, 0x83426B33, 0xF01EAB71, 0xB0804187, 0x3C005E5F, 0x77A057BE, 0xBDE8AE24, 0x55464299, 0xBF582E61, 0x4E58F48F, 0xF2DDFDA2, 0xF474EF38, 0x8789BDC2, 0x5366F9C3, 0xC8B38E74, 0xB475F255, 0x46FCD9B9, 0x7AEB2661, 0x8B1DDF84, 0x846A0E79, 0x915F95E2, 0x466E598E, 0x20B45770, 0x8CD55591, 0xC902DE4C, 0xB90BACE1, 0xBB8205D0, 0x11A86248, 0x7574A99E, 0xB77F19B6, 0xE0A9DC09, 0x662D09A1, 0xC4324633, 0xE85A1F02, 0x09F0BE8C, 0x4A99A025, 0x1D6EFE10, 0x1AB93D1D, 0x0BA5A4DF, 0xA186F20F, 0x2868F169, 0xDCB7DA83, 0x573906FE, 0xA1E2CE9B, 0x4FCD7F52, 0x50115E01, 0xA70683FA, 0xA002B5C4, 0x0DE6D027, 0x9AF88C27, 0x773F8641, 0xC3604C06, 0x61A806B5, 0xF0177A28, 0xC0F586E0, 0x006058AA, 0x30DC7D62, 0x11E69ED7, 0x2338EA63, 0x53C2DD94, 0xC2C21634, 0xBBCBEE56, 0x90BCB6DE, 0xEBFC7DA1, 0xCE591D76, 0x6F05E409, 0x4B7C0188, 0x39720A3D, 0x7C927C24, 0x86E3725F, 0x724D9DB9, 0x1AC15BB4, 0xD39EB8FC, 0xED545578, 0x08FCA5B5, 0xD83D7CD3, 0x4DAD0FC4, 0x1E50EF5E, 0xB161E6F8, 0xA28514D9, 0x6C51133C, 0x6FD5C7E7, 0x56E14EC4, 0x362ABFCE, 0xDDC6C837, 0xD79A3234, 0x92638212, 0x670EFA8E, 0x406000E0 }, KS3 = { 0x3A39CE37, 0xD3FAF5CF, 0xABC27737, 0x5AC52D1B, 0x5CB0679E, 0x4FA33742, 0xD3822740, 0x99BC9BBE, 0xD5118E9D, 0xBF0F7315, 0xD62D1C7E, 0xC700C47B, 0xB78C1B6B, 0x21A19045, 0xB26EB1BE, 0x6A366EB4, 0x5748AB2F, 0xBC946E79, 0xC6A376D2, 0x6549C2C8, 0x530FF8EE, 0x468DDE7D, 0xD5730A1D, 0x4CD04DC6, 0x2939BBDB, 0xA9BA4650, 0xAC9526E8, 0xBE5EE304, 0xA1FAD5F0, 0x6A2D519A, 0x63EF8CE2, 0x9A86EE22, 0xC089C2B8, 0x43242EF6, 0xA51E03AA, 0x9CF2D0A4, 0x83C061BA, 0x9BE96A4D, 0x8FE51550, 0xBA645BD6, 0x2826A2F9, 0xA73A3AE1, 0x4BA99586, 0xEF5562E9, 0xC72FEFD3, 0xF752F7DA, 0x3F046F69, 0x77FA0A59, 0x80E4A915, 0x87B08601, 0x9B09E6AD, 0x3B3EE593, 0xE990FD5A, 0x9E34D797, 0x2CF0B7D9, 0x022B8B51, 0x96D5AC3A, 0x017DA67D, 0xD1CF3ED6, 0x7C7D2D28, 0x1F9F25CF, 0xADF2B89B, 0x5AD6B472, 0x5A88F54C, 0xE029AC71, 0xE019A5E6, 0x47B0ACFD, 0xED93FA9B, 0xE8D3C48D, 0x283B57CC, 0xF8D56629, 0x79132E28, 0x785F0191, 0xED756055, 0xF7960E44, 0xE3D35E8C, 0x15056DD4, 0x88F46DBA, 0x03A16125, 0x0564F0BD, 0xC3EB9E15, 0x3C9057A2, 0x97271AEC, 0xA93A072A, 0x1B3F6D9B, 0x1E6321F5, 0xF59C66FB, 0x26DCF319, 0x7533D928, 0xB155FDF5, 0x03563482, 0x8ABA3CBB, 0x28517711, 0xC20AD9F8, 0xABCC5167, 0xCCAD925F, 0x4DE81751, 0x3830DC8E, 0x379D5862, 0x9320F991, 0xEA7A90C2, 0xFB3E7BCE, 0x5121CE64, 0x774FBE32, 0xA8B6E37E, 0xC3293D46, 0x48DE5369, 0x6413E680, 0xA2AE0810, 0xDD6DB224, 0x69852DFD, 0x09072166, 0xB39A460A, 0x6445C0DD, 0x586CDECF, 0x1C20C8AE, 0x5BBEF7DD, 0x1B588D40, 0xCCD2017F, 0x6BB4E3BB, 0xDDA26A7E, 0x3A59FF45, 0x3E350A44, 0xBCB4CDD5, 0x72EACEA8, 0xFA6484BB, 0x8D6612AE, 0xBF3C6F47, 0xD29BE463, 0x542F5D9E, 0xAEC2771B, 0xF64E6370, 0x740E0D8D, 0xE75B1357, 0xF8721671, 0xAF537D5D, 0x4040CB08, 0x4EB4E2CC, 0x34D2466A, 0x0115AF84, 0xE1B00428, 0x95983A1D, 0x06B89FB4, 0xCE6EA048, 0x6F3F3B82, 0x3520AB82, 0x011A1D4B, 0x277227F8, 0x611560B1, 0xE7933FDC, 0xBB3A792B, 0x344525BD, 0xA08839E1, 0x51CE794B, 0x2F32C9B7, 0xA01FBAC9, 0xE01CC87E, 0xBCC7D1F6, 0xCF0111C3, 0xA1E8AAC7, 0x1A908749, 0xD44FBD9A, 0xD0DADECB, 0xD50ADA38, 0x0339C32A, 0xC6913667, 0x8DF9317C, 0xE0B12B4F, 0xF79E59B7, 0x43F5BB3A, 0xF2D519FF, 0x27D9459C, 0xBF97222C, 0x15E6FC2A, 0x0F91FC71, 0x9B941525, 0xFAE59361, 0xCEB69CEB, 0xC2A86459, 0x12BAA8D1, 0xB6C1075E, 0xE3056A0C, 0x10D25065, 0xCB03A442, 0xE0EC6E0E, 0x1698DB3B, 0x4C98A0BE, 0x3278E964, 0x9F1F9532, 0xE0D392DF, 0xD3A0342B, 0x8971F21E, 0x1B0A7441, 0x4BA3348C, 0xC5BE7120, 0xC37632D8, 0xDF359F8D, 0x9B992F2E, 0xE60B6F47, 0x0FE3F11D, 0xE54CDA54, 0x1EDAD891, 0xCE6279CF, 0xCD3E7E6F, 0x1618B166, 0xFD2C1D05, 0x848FD2C5, 0xF6FB2299, 0xF523F357, 0xA6327623, 0x93A83531, 0x56CCCD02, 0xACF08162, 0x5A75EBB5, 0x6E163697, 0x88D273CC, 0xDE966292, 0x81B949D0, 0x4C50901B, 0x71C65614, 0xE6C6C7BD, 0x327A140A, 0x45E1D006, 0xC3F27B9A, 0xC9AA53FD, 0x62A80F00, 0xBB25BFE2, 0x35BDD2F6, 0x71126905, 0xB2040222, 0xB6CBCF7C, 0xCD769C2B, 0x53113EC0, 0x1640E3D3, 0x38ABBD60, 0x2547ADF0, 0xBA38209C, 0xF746CE76, 0x77AFA1C5, 0x20756060, 0x85CBFE4E, 0x8AE88DD8, 0x7AAAF9B0, 0x4CF9AA7E, 0x1948C25C, 0x02FB8A8C, 0x01C36AE4, 0xD6EBE1F9, 0x90D4F869, 0xA65CDEA0, 0x3F09252D, 0xC208E69F, 0xB74E6132, 0xCE77E25B, 0x578FDFE3, 0x3AC372E6 }; //==================================== // Useful constants //==================================== private static final int ROUNDS = 16; private static final int BLOCK_SIZE = 8; // bytes = 64 bits private static final int SBOX_SK = 256; private static final int P_SZ = ROUNDS+2; private final int[] S0, S1, S2, S3; // the s-boxes private final int[] P; // the p-array private boolean encrypting = false; private byte[] workingKey = null; public BlowfishEngine() { S0 = new int[SBOX_SK]; S1 = new int[SBOX_SK]; S2 = new int[SBOX_SK]; S3 = new int[SBOX_SK]; P = new int[P_SZ]; } /** * initialise a Blowfish cipher. * * @param encrypting whether or not we are for encryption. * @param params the parameters required to set up the cipher. * @exception IllegalArgumentException if the params argument is * inappropriate. */ public void init( boolean encrypting, CipherParameters params) { if (params instanceof KeyParameter) { this.encrypting = encrypting; this.workingKey = ((KeyParameter)params).getKey(); setKey(this.workingKey); return; } throw new IllegalArgumentException("invalid parameter passed to Blowfish init - " + params.getClass().getName()); } public String getAlgorithmName() { return "Blowfish"; } public final int processBlock( byte[] in, int inOff, byte[] out, int outOff) { if (workingKey == null) { throw new IllegalStateException("Blowfish not initialised"); } if ((inOff + BLOCK_SIZE) > in.length) { throw new DataLengthException("input buffer too short"); } if ((outOff + BLOCK_SIZE) > out.length) { throw new OutputLengthException("output buffer too short"); } if (encrypting) { encryptBlock(in, inOff, out, outOff); } else { decryptBlock(in, inOff, out, outOff); } return BLOCK_SIZE; } public void reset() { } public int getBlockSize() { return BLOCK_SIZE; } //================================== // Private Implementation //================================== private int F(int x) { return (((S0[(x >>> 24)] + S1[(x >>> 16) & 0xff]) ^ S2[(x >>> 8) & 0xff]) + S3[x & 0xff]); } /** * apply the encryption cycle to each value pair in the table. */ private void processTable( int xl, int xr, int[] table) { int size = table.length; for (int s = 0; s < size; s += 2) { xl ^= P[0]; for (int i = 1; i < ROUNDS; i += 2) { xr ^= F(xl) ^ P[i]; xl ^= F(xr) ^ P[i + 1]; } xr ^= P[ROUNDS + 1]; table[s] = xr; table[s + 1] = xl; xr = xl; // end of cycle swap xl = table[s]; } } private void setKey(byte[] key) { /* * - comments are from _Applied Crypto_, Schneier, p338 * please be careful comparing the two, AC numbers the * arrays from 1, the enclosed code from 0. * * (1) * Initialise the S-boxes and the P-array, with a fixed string * This string contains the hexadecimal digits of pi (3.141...) */ System.arraycopy(KS0, 0, S0, 0, SBOX_SK); System.arraycopy(KS1, 0, S1, 0, SBOX_SK); System.arraycopy(KS2, 0, S2, 0, SBOX_SK); System.arraycopy(KS3, 0, S3, 0, SBOX_SK); System.arraycopy(KP, 0, P, 0, P_SZ); /* * (2) * Now, XOR P[0] with the first 32 bits of the key, XOR P[1] with the * second 32-bits of the key, and so on for all bits of the key * (up to P[17]). Repeatedly cycle through the key bits until the * entire P-array has been XOR-ed with the key bits */ int keyLength = key.length; int keyIndex = 0; for (int i=0; i < P_SZ; i++) { // get the 32 bits of the key, in 4 * 8 bit chunks int data = 0x0000000; for (int j=0; j < 4; j++) { // create a 32 bit block data = (data << 8) | (key[keyIndex++] & 0xff); // wrap when we get to the end of the key if (keyIndex >= keyLength) { keyIndex = 0; } } // XOR the newly created 32 bit chunk onto the P-array P[i] ^= data; } /* * (3) * Encrypt the all-zero string with the Blowfish algorithm, using * the subkeys described in (1) and (2) * * (4) * Replace P1 and P2 with the output of step (3) * * (5) * Encrypt the output of step(3) using the Blowfish algorithm, * with the modified subkeys. * * (6) * Replace P3 and P4 with the output of step (5) * * (7) * Continue the process, replacing all elements of the P-array * and then all four S-boxes in order, with the output of the * continuously changing Blowfish algorithm */ processTable(0, 0, P); processTable(P[P_SZ - 2], P[P_SZ - 1], S0); processTable(S0[SBOX_SK - 2], S0[SBOX_SK - 1], S1); processTable(S1[SBOX_SK - 2], S1[SBOX_SK - 1], S2); processTable(S2[SBOX_SK - 2], S2[SBOX_SK - 1], S3); } /** * Encrypt the given input starting at the given offset and place * the result in the provided buffer starting at the given offset. * The input will be an exact multiple of our blocksize. */ private void encryptBlock( byte[] src, int srcIndex, byte[] dst, int dstIndex) { int xl = BytesTo32bits(src, srcIndex); int xr = BytesTo32bits(src, srcIndex+4); xl ^= P[0]; for (int i = 1; i < ROUNDS; i += 2) { xr ^= F(xl) ^ P[i]; xl ^= F(xr) ^ P[i + 1]; } xr ^= P[ROUNDS + 1]; Bits32ToBytes(xr, dst, dstIndex); Bits32ToBytes(xl, dst, dstIndex + 4); } /** * Decrypt the given input starting at the given offset and place * the result in the provided buffer starting at the given offset. * The input will be an exact multiple of our blocksize. */ private void decryptBlock( byte[] src, int srcIndex, byte[] dst, int dstIndex) { int xl = BytesTo32bits(src, srcIndex); int xr = BytesTo32bits(src, srcIndex + 4); xl ^= P[ROUNDS + 1]; for (int i = ROUNDS; i > 0 ; i -= 2) { xr ^= F(xl) ^ P[i]; xl ^= F(xr) ^ P[i - 1]; } xr ^= P[0]; Bits32ToBytes(xr, dst, dstIndex); Bits32ToBytes(xl, dst, dstIndex+4); } private int BytesTo32bits(byte[] b, int i) { return ((b[i] & 0xff) << 24) | ((b[i+1] & 0xff) << 16) | ((b[i+2] & 0xff) << 8) | ((b[i+3] & 0xff)); } private void Bits32ToBytes(int in, byte[] b, int offset) { b[offset + 3] = (byte)in; b[offset + 2] = (byte)(in >> 8); b[offset + 1] = (byte)(in >> 16); b[offset] = (byte)(in >> 24); } } bouncycastle-1.49.orig/src/org/bouncycastle/crypto/engines/RC4Engine.java0000644000175000017500000000716712106331135026041 0ustar ebourgebourgpackage org.bouncycastle.crypto.engines; import org.bouncycastle.crypto.CipherParameters; import org.bouncycastle.crypto.DataLengthException; import org.bouncycastle.crypto.OutputLengthException; import org.bouncycastle.crypto.StreamCipher; import org.bouncycastle.crypto.params.KeyParameter; public class RC4Engine implements StreamCipher { private final static int STATE_LENGTH = 256; /* * variables to hold the state of the RC4 engine * during encryption and decryption */ private byte[] engineState = null; private int x = 0; private int y = 0; private byte[] workingKey = null; /** * initialise a RC4 cipher. * * @param forEncryption whether or not we are for encryption. * @param params the parameters required to set up the cipher. * @exception IllegalArgumentException if the params argument is * inappropriate. */ public void init( boolean forEncryption, CipherParameters params ) { if (params instanceof KeyParameter) { /* * RC4 encryption and decryption is completely * symmetrical, so the 'forEncryption' is * irrelevant. */ workingKey = ((KeyParameter)params).getKey(); setKey(workingKey); return; } throw new IllegalArgumentException("invalid parameter passed to RC4 init - " + params.getClass().getName()); } public String getAlgorithmName() { return "RC4"; } public byte returnByte(byte in) { x = (x + 1) & 0xff; y = (engineState[x] + y) & 0xff; // swap byte tmp = engineState[x]; engineState[x] = engineState[y]; engineState[y] = tmp; // xor return (byte)(in ^ engineState[(engineState[x] + engineState[y]) & 0xff]); } public void processBytes( byte[] in, int inOff, int len, byte[] out, int outOff) { if ((inOff + len) > in.length) { throw new DataLengthException("input buffer too short"); } if ((outOff + len) > out.length) { throw new OutputLengthException("output buffer too short"); } for (int i = 0; i < len ; i++) { x = (x + 1) & 0xff; y = (engineState[x] + y) & 0xff; // swap byte tmp = engineState[x]; engineState[x] = engineState[y]; engineState[y] = tmp; // xor out[i+outOff] = (byte)(in[i + inOff] ^ engineState[(engineState[x] + engineState[y]) & 0xff]); } } public void reset() { setKey(workingKey); } // Private implementation private void setKey(byte[] keyBytes) { workingKey = keyBytes; // System.out.println("the key length is ; "+ workingKey.length); x = 0; y = 0; if (engineState == null) { engineState = new byte[STATE_LENGTH]; } // reset the state of the engine for (int i=0; i < STATE_LENGTH; i++) { engineState[i] = (byte)i; } int i1 = 0; int i2 = 0; for (int i=0; i < STATE_LENGTH; i++) { i2 = ((keyBytes[i1] & 0xff) + engineState[i] + i2) & 0xff; // do the byte-swap inline byte tmp = engineState[i]; engineState[i] = engineState[i2]; engineState[i2] = tmp; i1 = (i1+1) % keyBytes.length; } } } bouncycastle-1.49.orig/src/org/bouncycastle/crypto/engines/CAST5Engine.java0000644000175000017500000012475412106330000026260 0ustar ebourgebourgpackage org.bouncycastle.crypto.engines; import org.bouncycastle.crypto.BlockCipher; import org.bouncycastle.crypto.CipherParameters; import org.bouncycastle.crypto.DataLengthException; import org.bouncycastle.crypto.OutputLengthException; import org.bouncycastle.crypto.params.KeyParameter; /** * A class that provides CAST key encryption operations, * such as encoding data and generating keys. * * All the algorithms herein are from the Internet RFC's * * RFC2144 - CAST5 (64bit block, 40-128bit key) * RFC2612 - CAST6 (128bit block, 128-256bit key) * * and implement a simplified cryptography interface. */ public class CAST5Engine implements BlockCipher { protected final static int M32 = 0xffffffff; protected final static int[] S1 = { 0x30fb40d4, 0x9fa0ff0b, 0x6beccd2f, 0x3f258c7a, 0x1e213f2f, 0x9c004dd3, 0x6003e540, 0xcf9fc949, 0xbfd4af27, 0x88bbbdb5, 0xe2034090, 0x98d09675, 0x6e63a0e0, 0x15c361d2, 0xc2e7661d, 0x22d4ff8e, 0x28683b6f, 0xc07fd059, 0xff2379c8, 0x775f50e2, 0x43c340d3, 0xdf2f8656, 0x887ca41a, 0xa2d2bd2d, 0xa1c9e0d6, 0x346c4819, 0x61b76d87, 0x22540f2f, 0x2abe32e1, 0xaa54166b, 0x22568e3a, 0xa2d341d0, 0x66db40c8, 0xa784392f, 0x004dff2f, 0x2db9d2de, 0x97943fac, 0x4a97c1d8, 0x527644b7, 0xb5f437a7, 0xb82cbaef, 0xd751d159, 0x6ff7f0ed, 0x5a097a1f, 0x827b68d0, 0x90ecf52e, 0x22b0c054, 0xbc8e5935, 0x4b6d2f7f, 0x50bb64a2, 0xd2664910, 0xbee5812d, 0xb7332290, 0xe93b159f, 0xb48ee411, 0x4bff345d, 0xfd45c240, 0xad31973f, 0xc4f6d02e, 0x55fc8165, 0xd5b1caad, 0xa1ac2dae, 0xa2d4b76d, 0xc19b0c50, 0x882240f2, 0x0c6e4f38, 0xa4e4bfd7, 0x4f5ba272, 0x564c1d2f, 0xc59c5319, 0xb949e354, 0xb04669fe, 0xb1b6ab8a, 0xc71358dd, 0x6385c545, 0x110f935d, 0x57538ad5, 0x6a390493, 0xe63d37e0, 0x2a54f6b3, 0x3a787d5f, 0x6276a0b5, 0x19a6fcdf, 0x7a42206a, 0x29f9d4d5, 0xf61b1891, 0xbb72275e, 0xaa508167, 0x38901091, 0xc6b505eb, 0x84c7cb8c, 0x2ad75a0f, 0x874a1427, 0xa2d1936b, 0x2ad286af, 0xaa56d291, 0xd7894360, 0x425c750d, 0x93b39e26, 0x187184c9, 0x6c00b32d, 0x73e2bb14, 0xa0bebc3c, 0x54623779, 0x64459eab, 0x3f328b82, 0x7718cf82, 0x59a2cea6, 0x04ee002e, 0x89fe78e6, 0x3fab0950, 0x325ff6c2, 0x81383f05, 0x6963c5c8, 0x76cb5ad6, 0xd49974c9, 0xca180dcf, 0x380782d5, 0xc7fa5cf6, 0x8ac31511, 0x35e79e13, 0x47da91d0, 0xf40f9086, 0xa7e2419e, 0x31366241, 0x051ef495, 0xaa573b04, 0x4a805d8d, 0x548300d0, 0x00322a3c, 0xbf64cddf, 0xba57a68e, 0x75c6372b, 0x50afd341, 0xa7c13275, 0x915a0bf5, 0x6b54bfab, 0x2b0b1426, 0xab4cc9d7, 0x449ccd82, 0xf7fbf265, 0xab85c5f3, 0x1b55db94, 0xaad4e324, 0xcfa4bd3f, 0x2deaa3e2, 0x9e204d02, 0xc8bd25ac, 0xeadf55b3, 0xd5bd9e98, 0xe31231b2, 0x2ad5ad6c, 0x954329de, 0xadbe4528, 0xd8710f69, 0xaa51c90f, 0xaa786bf6, 0x22513f1e, 0xaa51a79b, 0x2ad344cc, 0x7b5a41f0, 0xd37cfbad, 0x1b069505, 0x41ece491, 0xb4c332e6, 0x032268d4, 0xc9600acc, 0xce387e6d, 0xbf6bb16c, 0x6a70fb78, 0x0d03d9c9, 0xd4df39de, 0xe01063da, 0x4736f464, 0x5ad328d8, 0xb347cc96, 0x75bb0fc3, 0x98511bfb, 0x4ffbcc35, 0xb58bcf6a, 0xe11f0abc, 0xbfc5fe4a, 0xa70aec10, 0xac39570a, 0x3f04442f, 0x6188b153, 0xe0397a2e, 0x5727cb79, 0x9ceb418f, 0x1cacd68d, 0x2ad37c96, 0x0175cb9d, 0xc69dff09, 0xc75b65f0, 0xd9db40d8, 0xec0e7779, 0x4744ead4, 0xb11c3274, 0xdd24cb9e, 0x7e1c54bd, 0xf01144f9, 0xd2240eb1, 0x9675b3fd, 0xa3ac3755, 0xd47c27af, 0x51c85f4d, 0x56907596, 0xa5bb15e6, 0x580304f0, 0xca042cf1, 0x011a37ea, 0x8dbfaadb, 0x35ba3e4a, 0x3526ffa0, 0xc37b4d09, 0xbc306ed9, 0x98a52666, 0x5648f725, 0xff5e569d, 0x0ced63d0, 0x7c63b2cf, 0x700b45e1, 0xd5ea50f1, 0x85a92872, 0xaf1fbda7, 0xd4234870, 0xa7870bf3, 0x2d3b4d79, 0x42e04198, 0x0cd0ede7, 0x26470db8, 0xf881814c, 0x474d6ad7, 0x7c0c5e5c, 0xd1231959, 0x381b7298, 0xf5d2f4db, 0xab838653, 0x6e2f1e23, 0x83719c9e, 0xbd91e046, 0x9a56456e, 0xdc39200c, 0x20c8c571, 0x962bda1c, 0xe1e696ff, 0xb141ab08, 0x7cca89b9, 0x1a69e783, 0x02cc4843, 0xa2f7c579, 0x429ef47d, 0x427b169c, 0x5ac9f049, 0xdd8f0f00, 0x5c8165bf }, S2 = { 0x1f201094, 0xef0ba75b, 0x69e3cf7e, 0x393f4380, 0xfe61cf7a, 0xeec5207a, 0x55889c94, 0x72fc0651, 0xada7ef79, 0x4e1d7235, 0xd55a63ce, 0xde0436ba, 0x99c430ef, 0x5f0c0794, 0x18dcdb7d, 0xa1d6eff3, 0xa0b52f7b, 0x59e83605, 0xee15b094, 0xe9ffd909, 0xdc440086, 0xef944459, 0xba83ccb3, 0xe0c3cdfb, 0xd1da4181, 0x3b092ab1, 0xf997f1c1, 0xa5e6cf7b, 0x01420ddb, 0xe4e7ef5b, 0x25a1ff41, 0xe180f806, 0x1fc41080, 0x179bee7a, 0xd37ac6a9, 0xfe5830a4, 0x98de8b7f, 0x77e83f4e, 0x79929269, 0x24fa9f7b, 0xe113c85b, 0xacc40083, 0xd7503525, 0xf7ea615f, 0x62143154, 0x0d554b63, 0x5d681121, 0xc866c359, 0x3d63cf73, 0xcee234c0, 0xd4d87e87, 0x5c672b21, 0x071f6181, 0x39f7627f, 0x361e3084, 0xe4eb573b, 0x602f64a4, 0xd63acd9c, 0x1bbc4635, 0x9e81032d, 0x2701f50c, 0x99847ab4, 0xa0e3df79, 0xba6cf38c, 0x10843094, 0x2537a95e, 0xf46f6ffe, 0xa1ff3b1f, 0x208cfb6a, 0x8f458c74, 0xd9e0a227, 0x4ec73a34, 0xfc884f69, 0x3e4de8df, 0xef0e0088, 0x3559648d, 0x8a45388c, 0x1d804366, 0x721d9bfd, 0xa58684bb, 0xe8256333, 0x844e8212, 0x128d8098, 0xfed33fb4, 0xce280ae1, 0x27e19ba5, 0xd5a6c252, 0xe49754bd, 0xc5d655dd, 0xeb667064, 0x77840b4d, 0xa1b6a801, 0x84db26a9, 0xe0b56714, 0x21f043b7, 0xe5d05860, 0x54f03084, 0x066ff472, 0xa31aa153, 0xdadc4755, 0xb5625dbf, 0x68561be6, 0x83ca6b94, 0x2d6ed23b, 0xeccf01db, 0xa6d3d0ba, 0xb6803d5c, 0xaf77a709, 0x33b4a34c, 0x397bc8d6, 0x5ee22b95, 0x5f0e5304, 0x81ed6f61, 0x20e74364, 0xb45e1378, 0xde18639b, 0x881ca122, 0xb96726d1, 0x8049a7e8, 0x22b7da7b, 0x5e552d25, 0x5272d237, 0x79d2951c, 0xc60d894c, 0x488cb402, 0x1ba4fe5b, 0xa4b09f6b, 0x1ca815cf, 0xa20c3005, 0x8871df63, 0xb9de2fcb, 0x0cc6c9e9, 0x0beeff53, 0xe3214517, 0xb4542835, 0x9f63293c, 0xee41e729, 0x6e1d2d7c, 0x50045286, 0x1e6685f3, 0xf33401c6, 0x30a22c95, 0x31a70850, 0x60930f13, 0x73f98417, 0xa1269859, 0xec645c44, 0x52c877a9, 0xcdff33a6, 0xa02b1741, 0x7cbad9a2, 0x2180036f, 0x50d99c08, 0xcb3f4861, 0xc26bd765, 0x64a3f6ab, 0x80342676, 0x25a75e7b, 0xe4e6d1fc, 0x20c710e6, 0xcdf0b680, 0x17844d3b, 0x31eef84d, 0x7e0824e4, 0x2ccb49eb, 0x846a3bae, 0x8ff77888, 0xee5d60f6, 0x7af75673, 0x2fdd5cdb, 0xa11631c1, 0x30f66f43, 0xb3faec54, 0x157fd7fa, 0xef8579cc, 0xd152de58, 0xdb2ffd5e, 0x8f32ce19, 0x306af97a, 0x02f03ef8, 0x99319ad5, 0xc242fa0f, 0xa7e3ebb0, 0xc68e4906, 0xb8da230c, 0x80823028, 0xdcdef3c8, 0xd35fb171, 0x088a1bc8, 0xbec0c560, 0x61a3c9e8, 0xbca8f54d, 0xc72feffa, 0x22822e99, 0x82c570b4, 0xd8d94e89, 0x8b1c34bc, 0x301e16e6, 0x273be979, 0xb0ffeaa6, 0x61d9b8c6, 0x00b24869, 0xb7ffce3f, 0x08dc283b, 0x43daf65a, 0xf7e19798, 0x7619b72f, 0x8f1c9ba4, 0xdc8637a0, 0x16a7d3b1, 0x9fc393b7, 0xa7136eeb, 0xc6bcc63e, 0x1a513742, 0xef6828bc, 0x520365d6, 0x2d6a77ab, 0x3527ed4b, 0x821fd216, 0x095c6e2e, 0xdb92f2fb, 0x5eea29cb, 0x145892f5, 0x91584f7f, 0x5483697b, 0x2667a8cc, 0x85196048, 0x8c4bacea, 0x833860d4, 0x0d23e0f9, 0x6c387e8a, 0x0ae6d249, 0xb284600c, 0xd835731d, 0xdcb1c647, 0xac4c56ea, 0x3ebd81b3, 0x230eabb0, 0x6438bc87, 0xf0b5b1fa, 0x8f5ea2b3, 0xfc184642, 0x0a036b7a, 0x4fb089bd, 0x649da589, 0xa345415e, 0x5c038323, 0x3e5d3bb9, 0x43d79572, 0x7e6dd07c, 0x06dfdf1e, 0x6c6cc4ef, 0x7160a539, 0x73bfbe70, 0x83877605, 0x4523ecf1 }, S3 = { 0x8defc240, 0x25fa5d9f, 0xeb903dbf, 0xe810c907, 0x47607fff, 0x369fe44b, 0x8c1fc644, 0xaececa90, 0xbeb1f9bf, 0xeefbcaea, 0xe8cf1950, 0x51df07ae, 0x920e8806, 0xf0ad0548, 0xe13c8d83, 0x927010d5, 0x11107d9f, 0x07647db9, 0xb2e3e4d4, 0x3d4f285e, 0xb9afa820, 0xfade82e0, 0xa067268b, 0x8272792e, 0x553fb2c0, 0x489ae22b, 0xd4ef9794, 0x125e3fbc, 0x21fffcee, 0x825b1bfd, 0x9255c5ed, 0x1257a240, 0x4e1a8302, 0xbae07fff, 0x528246e7, 0x8e57140e, 0x3373f7bf, 0x8c9f8188, 0xa6fc4ee8, 0xc982b5a5, 0xa8c01db7, 0x579fc264, 0x67094f31, 0xf2bd3f5f, 0x40fff7c1, 0x1fb78dfc, 0x8e6bd2c1, 0x437be59b, 0x99b03dbf, 0xb5dbc64b, 0x638dc0e6, 0x55819d99, 0xa197c81c, 0x4a012d6e, 0xc5884a28, 0xccc36f71, 0xb843c213, 0x6c0743f1, 0x8309893c, 0x0feddd5f, 0x2f7fe850, 0xd7c07f7e, 0x02507fbf, 0x5afb9a04, 0xa747d2d0, 0x1651192e, 0xaf70bf3e, 0x58c31380, 0x5f98302e, 0x727cc3c4, 0x0a0fb402, 0x0f7fef82, 0x8c96fdad, 0x5d2c2aae, 0x8ee99a49, 0x50da88b8, 0x8427f4a0, 0x1eac5790, 0x796fb449, 0x8252dc15, 0xefbd7d9b, 0xa672597d, 0xada840d8, 0x45f54504, 0xfa5d7403, 0xe83ec305, 0x4f91751a, 0x925669c2, 0x23efe941, 0xa903f12e, 0x60270df2, 0x0276e4b6, 0x94fd6574, 0x927985b2, 0x8276dbcb, 0x02778176, 0xf8af918d, 0x4e48f79e, 0x8f616ddf, 0xe29d840e, 0x842f7d83, 0x340ce5c8, 0x96bbb682, 0x93b4b148, 0xef303cab, 0x984faf28, 0x779faf9b, 0x92dc560d, 0x224d1e20, 0x8437aa88, 0x7d29dc96, 0x2756d3dc, 0x8b907cee, 0xb51fd240, 0xe7c07ce3, 0xe566b4a1, 0xc3e9615e, 0x3cf8209d, 0x6094d1e3, 0xcd9ca341, 0x5c76460e, 0x00ea983b, 0xd4d67881, 0xfd47572c, 0xf76cedd9, 0xbda8229c, 0x127dadaa, 0x438a074e, 0x1f97c090, 0x081bdb8a, 0x93a07ebe, 0xb938ca15, 0x97b03cff, 0x3dc2c0f8, 0x8d1ab2ec, 0x64380e51, 0x68cc7bfb, 0xd90f2788, 0x12490181, 0x5de5ffd4, 0xdd7ef86a, 0x76a2e214, 0xb9a40368, 0x925d958f, 0x4b39fffa, 0xba39aee9, 0xa4ffd30b, 0xfaf7933b, 0x6d498623, 0x193cbcfa, 0x27627545, 0x825cf47a, 0x61bd8ba0, 0xd11e42d1, 0xcead04f4, 0x127ea392, 0x10428db7, 0x8272a972, 0x9270c4a8, 0x127de50b, 0x285ba1c8, 0x3c62f44f, 0x35c0eaa5, 0xe805d231, 0x428929fb, 0xb4fcdf82, 0x4fb66a53, 0x0e7dc15b, 0x1f081fab, 0x108618ae, 0xfcfd086d, 0xf9ff2889, 0x694bcc11, 0x236a5cae, 0x12deca4d, 0x2c3f8cc5, 0xd2d02dfe, 0xf8ef5896, 0xe4cf52da, 0x95155b67, 0x494a488c, 0xb9b6a80c, 0x5c8f82bc, 0x89d36b45, 0x3a609437, 0xec00c9a9, 0x44715253, 0x0a874b49, 0xd773bc40, 0x7c34671c, 0x02717ef6, 0x4feb5536, 0xa2d02fff, 0xd2bf60c4, 0xd43f03c0, 0x50b4ef6d, 0x07478cd1, 0x006e1888, 0xa2e53f55, 0xb9e6d4bc, 0xa2048016, 0x97573833, 0xd7207d67, 0xde0f8f3d, 0x72f87b33, 0xabcc4f33, 0x7688c55d, 0x7b00a6b0, 0x947b0001, 0x570075d2, 0xf9bb88f8, 0x8942019e, 0x4264a5ff, 0x856302e0, 0x72dbd92b, 0xee971b69, 0x6ea22fde, 0x5f08ae2b, 0xaf7a616d, 0xe5c98767, 0xcf1febd2, 0x61efc8c2, 0xf1ac2571, 0xcc8239c2, 0x67214cb8, 0xb1e583d1, 0xb7dc3e62, 0x7f10bdce, 0xf90a5c38, 0x0ff0443d, 0x606e6dc6, 0x60543a49, 0x5727c148, 0x2be98a1d, 0x8ab41738, 0x20e1be24, 0xaf96da0f, 0x68458425, 0x99833be5, 0x600d457d, 0x282f9350, 0x8334b362, 0xd91d1120, 0x2b6d8da0, 0x642b1e31, 0x9c305a00, 0x52bce688, 0x1b03588a, 0xf7baefd5, 0x4142ed9c, 0xa4315c11, 0x83323ec5, 0xdfef4636, 0xa133c501, 0xe9d3531c, 0xee353783 }, S4 = { 0x9db30420, 0x1fb6e9de, 0xa7be7bef, 0xd273a298, 0x4a4f7bdb, 0x64ad8c57, 0x85510443, 0xfa020ed1, 0x7e287aff, 0xe60fb663, 0x095f35a1, 0x79ebf120, 0xfd059d43, 0x6497b7b1, 0xf3641f63, 0x241e4adf, 0x28147f5f, 0x4fa2b8cd, 0xc9430040, 0x0cc32220, 0xfdd30b30, 0xc0a5374f, 0x1d2d00d9, 0x24147b15, 0xee4d111a, 0x0fca5167, 0x71ff904c, 0x2d195ffe, 0x1a05645f, 0x0c13fefe, 0x081b08ca, 0x05170121, 0x80530100, 0xe83e5efe, 0xac9af4f8, 0x7fe72701, 0xd2b8ee5f, 0x06df4261, 0xbb9e9b8a, 0x7293ea25, 0xce84ffdf, 0xf5718801, 0x3dd64b04, 0xa26f263b, 0x7ed48400, 0x547eebe6, 0x446d4ca0, 0x6cf3d6f5, 0x2649abdf, 0xaea0c7f5, 0x36338cc1, 0x503f7e93, 0xd3772061, 0x11b638e1, 0x72500e03, 0xf80eb2bb, 0xabe0502e, 0xec8d77de, 0x57971e81, 0xe14f6746, 0xc9335400, 0x6920318f, 0x081dbb99, 0xffc304a5, 0x4d351805, 0x7f3d5ce3, 0xa6c866c6, 0x5d5bcca9, 0xdaec6fea, 0x9f926f91, 0x9f46222f, 0x3991467d, 0xa5bf6d8e, 0x1143c44f, 0x43958302, 0xd0214eeb, 0x022083b8, 0x3fb6180c, 0x18f8931e, 0x281658e6, 0x26486e3e, 0x8bd78a70, 0x7477e4c1, 0xb506e07c, 0xf32d0a25, 0x79098b02, 0xe4eabb81, 0x28123b23, 0x69dead38, 0x1574ca16, 0xdf871b62, 0x211c40b7, 0xa51a9ef9, 0x0014377b, 0x041e8ac8, 0x09114003, 0xbd59e4d2, 0xe3d156d5, 0x4fe876d5, 0x2f91a340, 0x557be8de, 0x00eae4a7, 0x0ce5c2ec, 0x4db4bba6, 0xe756bdff, 0xdd3369ac, 0xec17b035, 0x06572327, 0x99afc8b0, 0x56c8c391, 0x6b65811c, 0x5e146119, 0x6e85cb75, 0xbe07c002, 0xc2325577, 0x893ff4ec, 0x5bbfc92d, 0xd0ec3b25, 0xb7801ab7, 0x8d6d3b24, 0x20c763ef, 0xc366a5fc, 0x9c382880, 0x0ace3205, 0xaac9548a, 0xeca1d7c7, 0x041afa32, 0x1d16625a, 0x6701902c, 0x9b757a54, 0x31d477f7, 0x9126b031, 0x36cc6fdb, 0xc70b8b46, 0xd9e66a48, 0x56e55a79, 0x026a4ceb, 0x52437eff, 0x2f8f76b4, 0x0df980a5, 0x8674cde3, 0xedda04eb, 0x17a9be04, 0x2c18f4df, 0xb7747f9d, 0xab2af7b4, 0xefc34d20, 0x2e096b7c, 0x1741a254, 0xe5b6a035, 0x213d42f6, 0x2c1c7c26, 0x61c2f50f, 0x6552daf9, 0xd2c231f8, 0x25130f69, 0xd8167fa2, 0x0418f2c8, 0x001a96a6, 0x0d1526ab, 0x63315c21, 0x5e0a72ec, 0x49bafefd, 0x187908d9, 0x8d0dbd86, 0x311170a7, 0x3e9b640c, 0xcc3e10d7, 0xd5cad3b6, 0x0caec388, 0xf73001e1, 0x6c728aff, 0x71eae2a1, 0x1f9af36e, 0xcfcbd12f, 0xc1de8417, 0xac07be6b, 0xcb44a1d8, 0x8b9b0f56, 0x013988c3, 0xb1c52fca, 0xb4be31cd, 0xd8782806, 0x12a3a4e2, 0x6f7de532, 0x58fd7eb6, 0xd01ee900, 0x24adffc2, 0xf4990fc5, 0x9711aac5, 0x001d7b95, 0x82e5e7d2, 0x109873f6, 0x00613096, 0xc32d9521, 0xada121ff, 0x29908415, 0x7fbb977f, 0xaf9eb3db, 0x29c9ed2a, 0x5ce2a465, 0xa730f32c, 0xd0aa3fe8, 0x8a5cc091, 0xd49e2ce7, 0x0ce454a9, 0xd60acd86, 0x015f1919, 0x77079103, 0xdea03af6, 0x78a8565e, 0xdee356df, 0x21f05cbe, 0x8b75e387, 0xb3c50651, 0xb8a5c3ef, 0xd8eeb6d2, 0xe523be77, 0xc2154529, 0x2f69efdf, 0xafe67afb, 0xf470c4b2, 0xf3e0eb5b, 0xd6cc9876, 0x39e4460c, 0x1fda8538, 0x1987832f, 0xca007367, 0xa99144f8, 0x296b299e, 0x492fc295, 0x9266beab, 0xb5676e69, 0x9bd3ddda, 0xdf7e052f, 0xdb25701c, 0x1b5e51ee, 0xf65324e6, 0x6afce36c, 0x0316cc04, 0x8644213e, 0xb7dc59d0, 0x7965291f, 0xccd6fd43, 0x41823979, 0x932bcdf6, 0xb657c34d, 0x4edfd282, 0x7ae5290c, 0x3cb9536b, 0x851e20fe, 0x9833557e, 0x13ecf0b0, 0xd3ffb372, 0x3f85c5c1, 0x0aef7ed2 }, S5 = { 0x7ec90c04, 0x2c6e74b9, 0x9b0e66df, 0xa6337911, 0xb86a7fff, 0x1dd358f5, 0x44dd9d44, 0x1731167f, 0x08fbf1fa, 0xe7f511cc, 0xd2051b00, 0x735aba00, 0x2ab722d8, 0x386381cb, 0xacf6243a, 0x69befd7a, 0xe6a2e77f, 0xf0c720cd, 0xc4494816, 0xccf5c180, 0x38851640, 0x15b0a848, 0xe68b18cb, 0x4caadeff, 0x5f480a01, 0x0412b2aa, 0x259814fc, 0x41d0efe2, 0x4e40b48d, 0x248eb6fb, 0x8dba1cfe, 0x41a99b02, 0x1a550a04, 0xba8f65cb, 0x7251f4e7, 0x95a51725, 0xc106ecd7, 0x97a5980a, 0xc539b9aa, 0x4d79fe6a, 0xf2f3f763, 0x68af8040, 0xed0c9e56, 0x11b4958b, 0xe1eb5a88, 0x8709e6b0, 0xd7e07156, 0x4e29fea7, 0x6366e52d, 0x02d1c000, 0xc4ac8e05, 0x9377f571, 0x0c05372a, 0x578535f2, 0x2261be02, 0xd642a0c9, 0xdf13a280, 0x74b55bd2, 0x682199c0, 0xd421e5ec, 0x53fb3ce8, 0xc8adedb3, 0x28a87fc9, 0x3d959981, 0x5c1ff900, 0xfe38d399, 0x0c4eff0b, 0x062407ea, 0xaa2f4fb1, 0x4fb96976, 0x90c79505, 0xb0a8a774, 0xef55a1ff, 0xe59ca2c2, 0xa6b62d27, 0xe66a4263, 0xdf65001f, 0x0ec50966, 0xdfdd55bc, 0x29de0655, 0x911e739a, 0x17af8975, 0x32c7911c, 0x89f89468, 0x0d01e980, 0x524755f4, 0x03b63cc9, 0x0cc844b2, 0xbcf3f0aa, 0x87ac36e9, 0xe53a7426, 0x01b3d82b, 0x1a9e7449, 0x64ee2d7e, 0xcddbb1da, 0x01c94910, 0xb868bf80, 0x0d26f3fd, 0x9342ede7, 0x04a5c284, 0x636737b6, 0x50f5b616, 0xf24766e3, 0x8eca36c1, 0x136e05db, 0xfef18391, 0xfb887a37, 0xd6e7f7d4, 0xc7fb7dc9, 0x3063fcdf, 0xb6f589de, 0xec2941da, 0x26e46695, 0xb7566419, 0xf654efc5, 0xd08d58b7, 0x48925401, 0xc1bacb7f, 0xe5ff550f, 0xb6083049, 0x5bb5d0e8, 0x87d72e5a, 0xab6a6ee1, 0x223a66ce, 0xc62bf3cd, 0x9e0885f9, 0x68cb3e47, 0x086c010f, 0xa21de820, 0xd18b69de, 0xf3f65777, 0xfa02c3f6, 0x407edac3, 0xcbb3d550, 0x1793084d, 0xb0d70eba, 0x0ab378d5, 0xd951fb0c, 0xded7da56, 0x4124bbe4, 0x94ca0b56, 0x0f5755d1, 0xe0e1e56e, 0x6184b5be, 0x580a249f, 0x94f74bc0, 0xe327888e, 0x9f7b5561, 0xc3dc0280, 0x05687715, 0x646c6bd7, 0x44904db3, 0x66b4f0a3, 0xc0f1648a, 0x697ed5af, 0x49e92ff6, 0x309e374f, 0x2cb6356a, 0x85808573, 0x4991f840, 0x76f0ae02, 0x083be84d, 0x28421c9a, 0x44489406, 0x736e4cb8, 0xc1092910, 0x8bc95fc6, 0x7d869cf4, 0x134f616f, 0x2e77118d, 0xb31b2be1, 0xaa90b472, 0x3ca5d717, 0x7d161bba, 0x9cad9010, 0xaf462ba2, 0x9fe459d2, 0x45d34559, 0xd9f2da13, 0xdbc65487, 0xf3e4f94e, 0x176d486f, 0x097c13ea, 0x631da5c7, 0x445f7382, 0x175683f4, 0xcdc66a97, 0x70be0288, 0xb3cdcf72, 0x6e5dd2f3, 0x20936079, 0x459b80a5, 0xbe60e2db, 0xa9c23101, 0xeba5315c, 0x224e42f2, 0x1c5c1572, 0xf6721b2c, 0x1ad2fff3, 0x8c25404e, 0x324ed72f, 0x4067b7fd, 0x0523138e, 0x5ca3bc78, 0xdc0fd66e, 0x75922283, 0x784d6b17, 0x58ebb16e, 0x44094f85, 0x3f481d87, 0xfcfeae7b, 0x77b5ff76, 0x8c2302bf, 0xaaf47556, 0x5f46b02a, 0x2b092801, 0x3d38f5f7, 0x0ca81f36, 0x52af4a8a, 0x66d5e7c0, 0xdf3b0874, 0x95055110, 0x1b5ad7a8, 0xf61ed5ad, 0x6cf6e479, 0x20758184, 0xd0cefa65, 0x88f7be58, 0x4a046826, 0x0ff6f8f3, 0xa09c7f70, 0x5346aba0, 0x5ce96c28, 0xe176eda3, 0x6bac307f, 0x376829d2, 0x85360fa9, 0x17e3fe2a, 0x24b79767, 0xf5a96b20, 0xd6cd2595, 0x68ff1ebf, 0x7555442c, 0xf19f06be, 0xf9e0659a, 0xeeb9491d, 0x34010718, 0xbb30cab8, 0xe822fe15, 0x88570983, 0x750e6249, 0xda627e55, 0x5e76ffa8, 0xb1534546, 0x6d47de08, 0xefe9e7d4 }, S6 = { 0xf6fa8f9d, 0x2cac6ce1, 0x4ca34867, 0xe2337f7c, 0x95db08e7, 0x016843b4, 0xeced5cbc, 0x325553ac, 0xbf9f0960, 0xdfa1e2ed, 0x83f0579d, 0x63ed86b9, 0x1ab6a6b8, 0xde5ebe39, 0xf38ff732, 0x8989b138, 0x33f14961, 0xc01937bd, 0xf506c6da, 0xe4625e7e, 0xa308ea99, 0x4e23e33c, 0x79cbd7cc, 0x48a14367, 0xa3149619, 0xfec94bd5, 0xa114174a, 0xeaa01866, 0xa084db2d, 0x09a8486f, 0xa888614a, 0x2900af98, 0x01665991, 0xe1992863, 0xc8f30c60, 0x2e78ef3c, 0xd0d51932, 0xcf0fec14, 0xf7ca07d2, 0xd0a82072, 0xfd41197e, 0x9305a6b0, 0xe86be3da, 0x74bed3cd, 0x372da53c, 0x4c7f4448, 0xdab5d440, 0x6dba0ec3, 0x083919a7, 0x9fbaeed9, 0x49dbcfb0, 0x4e670c53, 0x5c3d9c01, 0x64bdb941, 0x2c0e636a, 0xba7dd9cd, 0xea6f7388, 0xe70bc762, 0x35f29adb, 0x5c4cdd8d, 0xf0d48d8c, 0xb88153e2, 0x08a19866, 0x1ae2eac8, 0x284caf89, 0xaa928223, 0x9334be53, 0x3b3a21bf, 0x16434be3, 0x9aea3906, 0xefe8c36e, 0xf890cdd9, 0x80226dae, 0xc340a4a3, 0xdf7e9c09, 0xa694a807, 0x5b7c5ecc, 0x221db3a6, 0x9a69a02f, 0x68818a54, 0xceb2296f, 0x53c0843a, 0xfe893655, 0x25bfe68a, 0xb4628abc, 0xcf222ebf, 0x25ac6f48, 0xa9a99387, 0x53bddb65, 0xe76ffbe7, 0xe967fd78, 0x0ba93563, 0x8e342bc1, 0xe8a11be9, 0x4980740d, 0xc8087dfc, 0x8de4bf99, 0xa11101a0, 0x7fd37975, 0xda5a26c0, 0xe81f994f, 0x9528cd89, 0xfd339fed, 0xb87834bf, 0x5f04456d, 0x22258698, 0xc9c4c83b, 0x2dc156be, 0x4f628daa, 0x57f55ec5, 0xe2220abe, 0xd2916ebf, 0x4ec75b95, 0x24f2c3c0, 0x42d15d99, 0xcd0d7fa0, 0x7b6e27ff, 0xa8dc8af0, 0x7345c106, 0xf41e232f, 0x35162386, 0xe6ea8926, 0x3333b094, 0x157ec6f2, 0x372b74af, 0x692573e4, 0xe9a9d848, 0xf3160289, 0x3a62ef1d, 0xa787e238, 0xf3a5f676, 0x74364853, 0x20951063, 0x4576698d, 0xb6fad407, 0x592af950, 0x36f73523, 0x4cfb6e87, 0x7da4cec0, 0x6c152daa, 0xcb0396a8, 0xc50dfe5d, 0xfcd707ab, 0x0921c42f, 0x89dff0bb, 0x5fe2be78, 0x448f4f33, 0x754613c9, 0x2b05d08d, 0x48b9d585, 0xdc049441, 0xc8098f9b, 0x7dede786, 0xc39a3373, 0x42410005, 0x6a091751, 0x0ef3c8a6, 0x890072d6, 0x28207682, 0xa9a9f7be, 0xbf32679d, 0xd45b5b75, 0xb353fd00, 0xcbb0e358, 0x830f220a, 0x1f8fb214, 0xd372cf08, 0xcc3c4a13, 0x8cf63166, 0x061c87be, 0x88c98f88, 0x6062e397, 0x47cf8e7a, 0xb6c85283, 0x3cc2acfb, 0x3fc06976, 0x4e8f0252, 0x64d8314d, 0xda3870e3, 0x1e665459, 0xc10908f0, 0x513021a5, 0x6c5b68b7, 0x822f8aa0, 0x3007cd3e, 0x74719eef, 0xdc872681, 0x073340d4, 0x7e432fd9, 0x0c5ec241, 0x8809286c, 0xf592d891, 0x08a930f6, 0x957ef305, 0xb7fbffbd, 0xc266e96f, 0x6fe4ac98, 0xb173ecc0, 0xbc60b42a, 0x953498da, 0xfba1ae12, 0x2d4bd736, 0x0f25faab, 0xa4f3fceb, 0xe2969123, 0x257f0c3d, 0x9348af49, 0x361400bc, 0xe8816f4a, 0x3814f200, 0xa3f94043, 0x9c7a54c2, 0xbc704f57, 0xda41e7f9, 0xc25ad33a, 0x54f4a084, 0xb17f5505, 0x59357cbe, 0xedbd15c8, 0x7f97c5ab, 0xba5ac7b5, 0xb6f6deaf, 0x3a479c3a, 0x5302da25, 0x653d7e6a, 0x54268d49, 0x51a477ea, 0x5017d55b, 0xd7d25d88, 0x44136c76, 0x0404a8c8, 0xb8e5a121, 0xb81a928a, 0x60ed5869, 0x97c55b96, 0xeaec991b, 0x29935913, 0x01fdb7f1, 0x088e8dfa, 0x9ab6f6f5, 0x3b4cbf9f, 0x4a5de3ab, 0xe6051d35, 0xa0e1d855, 0xd36b4cf1, 0xf544edeb, 0xb0e93524, 0xbebb8fbd, 0xa2d762cf, 0x49c92f54, 0x38b5f331, 0x7128a454, 0x48392905, 0xa65b1db8, 0x851c97bd, 0xd675cf2f }, S7 = { 0x85e04019, 0x332bf567, 0x662dbfff, 0xcfc65693, 0x2a8d7f6f, 0xab9bc912, 0xde6008a1, 0x2028da1f, 0x0227bce7, 0x4d642916, 0x18fac300, 0x50f18b82, 0x2cb2cb11, 0xb232e75c, 0x4b3695f2, 0xb28707de, 0xa05fbcf6, 0xcd4181e9, 0xe150210c, 0xe24ef1bd, 0xb168c381, 0xfde4e789, 0x5c79b0d8, 0x1e8bfd43, 0x4d495001, 0x38be4341, 0x913cee1d, 0x92a79c3f, 0x089766be, 0xbaeeadf4, 0x1286becf, 0xb6eacb19, 0x2660c200, 0x7565bde4, 0x64241f7a, 0x8248dca9, 0xc3b3ad66, 0x28136086, 0x0bd8dfa8, 0x356d1cf2, 0x107789be, 0xb3b2e9ce, 0x0502aa8f, 0x0bc0351e, 0x166bf52a, 0xeb12ff82, 0xe3486911, 0xd34d7516, 0x4e7b3aff, 0x5f43671b, 0x9cf6e037, 0x4981ac83, 0x334266ce, 0x8c9341b7, 0xd0d854c0, 0xcb3a6c88, 0x47bc2829, 0x4725ba37, 0xa66ad22b, 0x7ad61f1e, 0x0c5cbafa, 0x4437f107, 0xb6e79962, 0x42d2d816, 0x0a961288, 0xe1a5c06e, 0x13749e67, 0x72fc081a, 0xb1d139f7, 0xf9583745, 0xcf19df58, 0xbec3f756, 0xc06eba30, 0x07211b24, 0x45c28829, 0xc95e317f, 0xbc8ec511, 0x38bc46e9, 0xc6e6fa14, 0xbae8584a, 0xad4ebc46, 0x468f508b, 0x7829435f, 0xf124183b, 0x821dba9f, 0xaff60ff4, 0xea2c4e6d, 0x16e39264, 0x92544a8b, 0x009b4fc3, 0xaba68ced, 0x9ac96f78, 0x06a5b79a, 0xb2856e6e, 0x1aec3ca9, 0xbe838688, 0x0e0804e9, 0x55f1be56, 0xe7e5363b, 0xb3a1f25d, 0xf7debb85, 0x61fe033c, 0x16746233, 0x3c034c28, 0xda6d0c74, 0x79aac56c, 0x3ce4e1ad, 0x51f0c802, 0x98f8f35a, 0x1626a49f, 0xeed82b29, 0x1d382fe3, 0x0c4fb99a, 0xbb325778, 0x3ec6d97b, 0x6e77a6a9, 0xcb658b5c, 0xd45230c7, 0x2bd1408b, 0x60c03eb7, 0xb9068d78, 0xa33754f4, 0xf430c87d, 0xc8a71302, 0xb96d8c32, 0xebd4e7be, 0xbe8b9d2d, 0x7979fb06, 0xe7225308, 0x8b75cf77, 0x11ef8da4, 0xe083c858, 0x8d6b786f, 0x5a6317a6, 0xfa5cf7a0, 0x5dda0033, 0xf28ebfb0, 0xf5b9c310, 0xa0eac280, 0x08b9767a, 0xa3d9d2b0, 0x79d34217, 0x021a718d, 0x9ac6336a, 0x2711fd60, 0x438050e3, 0x069908a8, 0x3d7fedc4, 0x826d2bef, 0x4eeb8476, 0x488dcf25, 0x36c9d566, 0x28e74e41, 0xc2610aca, 0x3d49a9cf, 0xbae3b9df, 0xb65f8de6, 0x92aeaf64, 0x3ac7d5e6, 0x9ea80509, 0xf22b017d, 0xa4173f70, 0xdd1e16c3, 0x15e0d7f9, 0x50b1b887, 0x2b9f4fd5, 0x625aba82, 0x6a017962, 0x2ec01b9c, 0x15488aa9, 0xd716e740, 0x40055a2c, 0x93d29a22, 0xe32dbf9a, 0x058745b9, 0x3453dc1e, 0xd699296e, 0x496cff6f, 0x1c9f4986, 0xdfe2ed07, 0xb87242d1, 0x19de7eae, 0x053e561a, 0x15ad6f8c, 0x66626c1c, 0x7154c24c, 0xea082b2a, 0x93eb2939, 0x17dcb0f0, 0x58d4f2ae, 0x9ea294fb, 0x52cf564c, 0x9883fe66, 0x2ec40581, 0x763953c3, 0x01d6692e, 0xd3a0c108, 0xa1e7160e, 0xe4f2dfa6, 0x693ed285, 0x74904698, 0x4c2b0edd, 0x4f757656, 0x5d393378, 0xa132234f, 0x3d321c5d, 0xc3f5e194, 0x4b269301, 0xc79f022f, 0x3c997e7e, 0x5e4f9504, 0x3ffafbbd, 0x76f7ad0e, 0x296693f4, 0x3d1fce6f, 0xc61e45be, 0xd3b5ab34, 0xf72bf9b7, 0x1b0434c0, 0x4e72b567, 0x5592a33d, 0xb5229301, 0xcfd2a87f, 0x60aeb767, 0x1814386b, 0x30bcc33d, 0x38a0c07d, 0xfd1606f2, 0xc363519b, 0x589dd390, 0x5479f8e6, 0x1cb8d647, 0x97fd61a9, 0xea7759f4, 0x2d57539d, 0x569a58cf, 0xe84e63ad, 0x462e1b78, 0x6580f87e, 0xf3817914, 0x91da55f4, 0x40a230f3, 0xd1988f35, 0xb6e318d2, 0x3ffa50bc, 0x3d40f021, 0xc3c0bdae, 0x4958c24c, 0x518f36b2, 0x84b1d370, 0x0fedce83, 0x878ddada, 0xf2a279c7, 0x94e01be8, 0x90716f4b, 0x954b8aa3 }, S8 = { 0xe216300d, 0xbbddfffc, 0xa7ebdabd, 0x35648095, 0x7789f8b7, 0xe6c1121b, 0x0e241600, 0x052ce8b5, 0x11a9cfb0, 0xe5952f11, 0xece7990a, 0x9386d174, 0x2a42931c, 0x76e38111, 0xb12def3a, 0x37ddddfc, 0xde9adeb1, 0x0a0cc32c, 0xbe197029, 0x84a00940, 0xbb243a0f, 0xb4d137cf, 0xb44e79f0, 0x049eedfd, 0x0b15a15d, 0x480d3168, 0x8bbbde5a, 0x669ded42, 0xc7ece831, 0x3f8f95e7, 0x72df191b, 0x7580330d, 0x94074251, 0x5c7dcdfa, 0xabbe6d63, 0xaa402164, 0xb301d40a, 0x02e7d1ca, 0x53571dae, 0x7a3182a2, 0x12a8ddec, 0xfdaa335d, 0x176f43e8, 0x71fb46d4, 0x38129022, 0xce949ad4, 0xb84769ad, 0x965bd862, 0x82f3d055, 0x66fb9767, 0x15b80b4e, 0x1d5b47a0, 0x4cfde06f, 0xc28ec4b8, 0x57e8726e, 0x647a78fc, 0x99865d44, 0x608bd593, 0x6c200e03, 0x39dc5ff6, 0x5d0b00a3, 0xae63aff2, 0x7e8bd632, 0x70108c0c, 0xbbd35049, 0x2998df04, 0x980cf42a, 0x9b6df491, 0x9e7edd53, 0x06918548, 0x58cb7e07, 0x3b74ef2e, 0x522fffb1, 0xd24708cc, 0x1c7e27cd, 0xa4eb215b, 0x3cf1d2e2, 0x19b47a38, 0x424f7618, 0x35856039, 0x9d17dee7, 0x27eb35e6, 0xc9aff67b, 0x36baf5b8, 0x09c467cd, 0xc18910b1, 0xe11dbf7b, 0x06cd1af8, 0x7170c608, 0x2d5e3354, 0xd4de495a, 0x64c6d006, 0xbcc0c62c, 0x3dd00db3, 0x708f8f34, 0x77d51b42, 0x264f620f, 0x24b8d2bf, 0x15c1b79e, 0x46a52564, 0xf8d7e54e, 0x3e378160, 0x7895cda5, 0x859c15a5, 0xe6459788, 0xc37bc75f, 0xdb07ba0c, 0x0676a3ab, 0x7f229b1e, 0x31842e7b, 0x24259fd7, 0xf8bef472, 0x835ffcb8, 0x6df4c1f2, 0x96f5b195, 0xfd0af0fc, 0xb0fe134c, 0xe2506d3d, 0x4f9b12ea, 0xf215f225, 0xa223736f, 0x9fb4c428, 0x25d04979, 0x34c713f8, 0xc4618187, 0xea7a6e98, 0x7cd16efc, 0x1436876c, 0xf1544107, 0xbedeee14, 0x56e9af27, 0xa04aa441, 0x3cf7c899, 0x92ecbae6, 0xdd67016d, 0x151682eb, 0xa842eedf, 0xfdba60b4, 0xf1907b75, 0x20e3030f, 0x24d8c29e, 0xe139673b, 0xefa63fb8, 0x71873054, 0xb6f2cf3b, 0x9f326442, 0xcb15a4cc, 0xb01a4504, 0xf1e47d8d, 0x844a1be5, 0xbae7dfdc, 0x42cbda70, 0xcd7dae0a, 0x57e85b7a, 0xd53f5af6, 0x20cf4d8c, 0xcea4d428, 0x79d130a4, 0x3486ebfb, 0x33d3cddc, 0x77853b53, 0x37effcb5, 0xc5068778, 0xe580b3e6, 0x4e68b8f4, 0xc5c8b37e, 0x0d809ea2, 0x398feb7c, 0x132a4f94, 0x43b7950e, 0x2fee7d1c, 0x223613bd, 0xdd06caa2, 0x37df932b, 0xc4248289, 0xacf3ebc3, 0x5715f6b7, 0xef3478dd, 0xf267616f, 0xc148cbe4, 0x9052815e, 0x5e410fab, 0xb48a2465, 0x2eda7fa4, 0xe87b40e4, 0xe98ea084, 0x5889e9e1, 0xefd390fc, 0xdd07d35b, 0xdb485694, 0x38d7e5b2, 0x57720101, 0x730edebc, 0x5b643113, 0x94917e4f, 0x503c2fba, 0x646f1282, 0x7523d24a, 0xe0779695, 0xf9c17a8f, 0x7a5b2121, 0xd187b896, 0x29263a4d, 0xba510cdf, 0x81f47c9f, 0xad1163ed, 0xea7b5965, 0x1a00726e, 0x11403092, 0x00da6d77, 0x4a0cdd61, 0xad1f4603, 0x605bdfb0, 0x9eedc364, 0x22ebe6a8, 0xcee7d28a, 0xa0e736a0, 0x5564a6b9, 0x10853209, 0xc7eb8f37, 0x2de705ca, 0x8951570f, 0xdf09822b, 0xbd691a6c, 0xaa12e4f2, 0x87451c0f, 0xe0f6a27a, 0x3ada4819, 0x4cf1764f, 0x0d771c2b, 0x67cdb156, 0x350d8384, 0x5938fa0f, 0x42399ef3, 0x36997b07, 0x0e84093d, 0x4aa93e61, 0x8360d87b, 0x1fa98b0c, 0x1149382c, 0xe97625a5, 0x0614d1b7, 0x0e25244b, 0x0c768347, 0x589e8d82, 0x0d2059d1, 0xa466bb1e, 0xf8da0a82, 0x04f19130, 0xba6e4ec0, 0x99265164, 0x1ee7230d, 0x50b2ad80, 0xeaee6801, 0x8db2a283, 0xea8bf59e }; //==================================== // Useful constants //==================================== protected static final int MAX_ROUNDS = 16; protected static final int RED_ROUNDS = 12; protected static final int BLOCK_SIZE = 8; // bytes = 64 bits protected int _Kr[] = new int[17]; // the rotating round key protected int _Km[] = new int[17]; // the masking round key private boolean _encrypting = false; private byte[] _workingKey = null; private int _rounds = MAX_ROUNDS; public CAST5Engine() { } /** * initialise a CAST cipher. * * @param encrypting whether or not we are for encryption. * @param params the parameters required to set up the cipher. * @exception IllegalArgumentException if the params argument is * inappropriate. */ public void init( boolean encrypting, CipherParameters params) { if (params instanceof KeyParameter) { _encrypting = encrypting; _workingKey = ((KeyParameter)params).getKey(); setKey(_workingKey); return; } throw new IllegalArgumentException("Invalid parameter passed to "+getAlgorithmName()+" init - " + params.getClass().getName()); } public String getAlgorithmName() { return "CAST5"; } public int processBlock( byte[] in, int inOff, byte[] out, int outOff) { if (_workingKey == null) { throw new IllegalStateException(getAlgorithmName()+" not initialised"); } int blockSize = getBlockSize(); if ((inOff + blockSize) > in.length) { throw new DataLengthException("Input buffer too short"); } if ((outOff + blockSize) > out.length) { throw new OutputLengthException("Output buffer too short"); } if (_encrypting) { return encryptBlock(in, inOff, out, outOff); } else { return decryptBlock(in, inOff, out, outOff); } } public void reset() { } public int getBlockSize() { return BLOCK_SIZE; } //================================== // Private Implementation //================================== /* * Creates the subkeys using the same nomenclature * as described in RFC2144. * * See section 2.4 */ protected void setKey(byte[] key) { /* * Determine the key size here, if required * * if keysize <= 80bits, use 12 rounds instead of 16 * if keysize < 128bits, pad with 0 * * Typical key sizes => 40, 64, 80, 128 */ if (key.length < 11) { _rounds = RED_ROUNDS; } int z[] = new int[16]; int x[] = new int[16]; int z03, z47, z8B, zCF; int x03, x47, x8B, xCF; /* copy the key into x */ for (int i=0; i< key.length; i++) { x[i] = key[i] & 0xff; } /* * This will look different because the selection of * bytes from the input key I've already chosen the * correct int. */ x03 = IntsTo32bits(x, 0x0); x47 = IntsTo32bits(x, 0x4); x8B = IntsTo32bits(x, 0x8); xCF = IntsTo32bits(x, 0xC); z03 = x03 ^S5[x[0xD]] ^S6[x[0xF]] ^S7[x[0xC]] ^S8[x[0xE]] ^S7[x[0x8]]; Bits32ToInts(z03, z, 0x0); z47 = x8B ^S5[z[0x0]] ^S6[z[0x2]] ^S7[z[0x1]] ^S8[z[0x3]] ^S8[x[0xA]]; Bits32ToInts(z47, z, 0x4); z8B = xCF ^S5[z[0x7]] ^S6[z[0x6]] ^S7[z[0x5]] ^S8[z[0x4]] ^S5[x[0x9]]; Bits32ToInts(z8B, z, 0x8); zCF = x47 ^S5[z[0xA]] ^S6[z[0x9]] ^S7[z[0xB]] ^S8[z[0x8]] ^S6[x[0xB]]; Bits32ToInts(zCF, z, 0xC); _Km[ 1]= S5[z[0x8]] ^ S6[z[0x9]] ^ S7[z[0x7]] ^ S8[z[0x6]] ^ S5[z[0x2]]; _Km[ 2]= S5[z[0xA]] ^ S6[z[0xB]] ^ S7[z[0x5]] ^ S8[z[0x4]] ^ S6[z[0x6]]; _Km[ 3]= S5[z[0xC]] ^ S6[z[0xD]] ^ S7[z[0x3]] ^ S8[z[0x2]] ^ S7[z[0x9]]; _Km[ 4]= S5[z[0xE]] ^ S6[z[0xF]] ^ S7[z[0x1]] ^ S8[z[0x0]] ^ S8[z[0xC]]; z03 = IntsTo32bits(z, 0x0); z47 = IntsTo32bits(z, 0x4); z8B = IntsTo32bits(z, 0x8); zCF = IntsTo32bits(z, 0xC); x03 = z8B ^S5[z[0x5]] ^S6[z[0x7]] ^S7[z[0x4]] ^S8[z[0x6]] ^S7[z[0x0]]; Bits32ToInts(x03, x, 0x0); x47 = z03 ^S5[x[0x0]] ^S6[x[0x2]] ^S7[x[0x1]] ^S8[x[0x3]] ^S8[z[0x2]]; Bits32ToInts(x47, x, 0x4); x8B = z47 ^S5[x[0x7]] ^S6[x[0x6]] ^S7[x[0x5]] ^S8[x[0x4]] ^S5[z[0x1]]; Bits32ToInts(x8B, x, 0x8); xCF = zCF ^S5[x[0xA]] ^S6[x[0x9]] ^S7[x[0xB]] ^S8[x[0x8]] ^S6[z[0x3]]; Bits32ToInts(xCF, x, 0xC); _Km[ 5]= S5[x[0x3]] ^ S6[x[0x2]] ^ S7[x[0xC]] ^ S8[x[0xD]] ^ S5[x[0x8]]; _Km[ 6]= S5[x[0x1]] ^ S6[x[0x0]] ^ S7[x[0xE]] ^ S8[x[0xF]] ^ S6[x[0xD]]; _Km[ 7]= S5[x[0x7]] ^ S6[x[0x6]] ^ S7[x[0x8]] ^ S8[x[0x9]] ^ S7[x[0x3]]; _Km[ 8]= S5[x[0x5]] ^ S6[x[0x4]] ^ S7[x[0xA]] ^ S8[x[0xB]] ^ S8[x[0x7]]; x03 = IntsTo32bits(x, 0x0); x47 = IntsTo32bits(x, 0x4); x8B = IntsTo32bits(x, 0x8); xCF = IntsTo32bits(x, 0xC); z03 = x03 ^S5[x[0xD]] ^S6[x[0xF]] ^S7[x[0xC]] ^S8[x[0xE]] ^S7[x[0x8]]; Bits32ToInts(z03, z, 0x0); z47 = x8B ^S5[z[0x0]] ^S6[z[0x2]] ^S7[z[0x1]] ^S8[z[0x3]] ^S8[x[0xA]]; Bits32ToInts(z47, z, 0x4); z8B = xCF ^S5[z[0x7]] ^S6[z[0x6]] ^S7[z[0x5]] ^S8[z[0x4]] ^S5[x[0x9]]; Bits32ToInts(z8B, z, 0x8); zCF = x47 ^S5[z[0xA]] ^S6[z[0x9]] ^S7[z[0xB]] ^S8[z[0x8]] ^S6[x[0xB]]; Bits32ToInts(zCF, z, 0xC); _Km[ 9]= S5[z[0x3]] ^ S6[z[0x2]] ^ S7[z[0xC]] ^ S8[z[0xD]] ^ S5[z[0x9]]; _Km[10]= S5[z[0x1]] ^ S6[z[0x0]] ^ S7[z[0xE]] ^ S8[z[0xF]] ^ S6[z[0xc]]; _Km[11]= S5[z[0x7]] ^ S6[z[0x6]] ^ S7[z[0x8]] ^ S8[z[0x9]] ^ S7[z[0x2]]; _Km[12]= S5[z[0x5]] ^ S6[z[0x4]] ^ S7[z[0xA]] ^ S8[z[0xB]] ^ S8[z[0x6]]; z03 = IntsTo32bits(z, 0x0); z47 = IntsTo32bits(z, 0x4); z8B = IntsTo32bits(z, 0x8); zCF = IntsTo32bits(z, 0xC); x03 = z8B ^S5[z[0x5]] ^S6[z[0x7]] ^S7[z[0x4]] ^S8[z[0x6]] ^S7[z[0x0]]; Bits32ToInts(x03, x, 0x0); x47 = z03 ^S5[x[0x0]] ^S6[x[0x2]] ^S7[x[0x1]] ^S8[x[0x3]] ^S8[z[0x2]]; Bits32ToInts(x47, x, 0x4); x8B = z47 ^S5[x[0x7]] ^S6[x[0x6]] ^S7[x[0x5]] ^S8[x[0x4]] ^S5[z[0x1]]; Bits32ToInts(x8B, x, 0x8); xCF = zCF ^S5[x[0xA]] ^S6[x[0x9]] ^S7[x[0xB]] ^S8[x[0x8]] ^S6[z[0x3]]; Bits32ToInts(xCF, x, 0xC); _Km[13]= S5[x[0x8]] ^ S6[x[0x9]] ^ S7[x[0x7]] ^ S8[x[0x6]] ^ S5[x[0x3]]; _Km[14]= S5[x[0xA]] ^ S6[x[0xB]] ^ S7[x[0x5]] ^ S8[x[0x4]] ^ S6[x[0x7]]; _Km[15]= S5[x[0xC]] ^ S6[x[0xD]] ^ S7[x[0x3]] ^ S8[x[0x2]] ^ S7[x[0x8]]; _Km[16]= S5[x[0xE]] ^ S6[x[0xF]] ^ S7[x[0x1]] ^ S8[x[0x0]] ^ S8[x[0xD]]; x03 = IntsTo32bits(x, 0x0); x47 = IntsTo32bits(x, 0x4); x8B = IntsTo32bits(x, 0x8); xCF = IntsTo32bits(x, 0xC); z03 = x03 ^S5[x[0xD]] ^S6[x[0xF]] ^S7[x[0xC]] ^S8[x[0xE]] ^S7[x[0x8]]; Bits32ToInts(z03, z, 0x0); z47 = x8B ^S5[z[0x0]] ^S6[z[0x2]] ^S7[z[0x1]] ^S8[z[0x3]] ^S8[x[0xA]]; Bits32ToInts(z47, z, 0x4); z8B = xCF ^S5[z[0x7]] ^S6[z[0x6]] ^S7[z[0x5]] ^S8[z[0x4]] ^S5[x[0x9]]; Bits32ToInts(z8B, z, 0x8); zCF = x47 ^S5[z[0xA]] ^S6[z[0x9]] ^S7[z[0xB]] ^S8[z[0x8]] ^S6[x[0xB]]; Bits32ToInts(zCF, z, 0xC); _Kr[ 1]=(S5[z[0x8]]^S6[z[0x9]]^S7[z[0x7]]^S8[z[0x6]] ^ S5[z[0x2]])&0x1f; _Kr[ 2]=(S5[z[0xA]]^S6[z[0xB]]^S7[z[0x5]]^S8[z[0x4]] ^ S6[z[0x6]])&0x1f; _Kr[ 3]=(S5[z[0xC]]^S6[z[0xD]]^S7[z[0x3]]^S8[z[0x2]] ^ S7[z[0x9]])&0x1f; _Kr[ 4]=(S5[z[0xE]]^S6[z[0xF]]^S7[z[0x1]]^S8[z[0x0]] ^ S8[z[0xC]])&0x1f; z03 = IntsTo32bits(z, 0x0); z47 = IntsTo32bits(z, 0x4); z8B = IntsTo32bits(z, 0x8); zCF = IntsTo32bits(z, 0xC); x03 = z8B ^S5[z[0x5]] ^S6[z[0x7]] ^S7[z[0x4]] ^S8[z[0x6]] ^S7[z[0x0]]; Bits32ToInts(x03, x, 0x0); x47 = z03 ^S5[x[0x0]] ^S6[x[0x2]] ^S7[x[0x1]] ^S8[x[0x3]] ^S8[z[0x2]]; Bits32ToInts(x47, x, 0x4); x8B = z47 ^S5[x[0x7]] ^S6[x[0x6]] ^S7[x[0x5]] ^S8[x[0x4]] ^S5[z[0x1]]; Bits32ToInts(x8B, x, 0x8); xCF = zCF ^S5[x[0xA]] ^S6[x[0x9]] ^S7[x[0xB]] ^S8[x[0x8]] ^S6[z[0x3]]; Bits32ToInts(xCF, x, 0xC); _Kr[ 5]=(S5[x[0x3]]^S6[x[0x2]]^S7[x[0xC]]^S8[x[0xD]]^S5[x[0x8]])&0x1f; _Kr[ 6]=(S5[x[0x1]]^S6[x[0x0]]^S7[x[0xE]]^S8[x[0xF]]^S6[x[0xD]])&0x1f; _Kr[ 7]=(S5[x[0x7]]^S6[x[0x6]]^S7[x[0x8]]^S8[x[0x9]]^S7[x[0x3]])&0x1f; _Kr[ 8]=(S5[x[0x5]]^S6[x[0x4]]^S7[x[0xA]]^S8[x[0xB]]^S8[x[0x7]])&0x1f; x03 = IntsTo32bits(x, 0x0); x47 = IntsTo32bits(x, 0x4); x8B = IntsTo32bits(x, 0x8); xCF = IntsTo32bits(x, 0xC); z03 = x03 ^S5[x[0xD]] ^S6[x[0xF]] ^S7[x[0xC]] ^S8[x[0xE]] ^S7[x[0x8]]; Bits32ToInts(z03, z, 0x0); z47 = x8B ^S5[z[0x0]] ^S6[z[0x2]] ^S7[z[0x1]] ^S8[z[0x3]] ^S8[x[0xA]]; Bits32ToInts(z47, z, 0x4); z8B = xCF ^S5[z[0x7]] ^S6[z[0x6]] ^S7[z[0x5]] ^S8[z[0x4]] ^S5[x[0x9]]; Bits32ToInts(z8B, z, 0x8); zCF = x47 ^S5[z[0xA]] ^S6[z[0x9]] ^S7[z[0xB]] ^S8[z[0x8]] ^S6[x[0xB]]; Bits32ToInts(zCF, z, 0xC); _Kr[ 9]=(S5[z[0x3]]^S6[z[0x2]]^S7[z[0xC]]^S8[z[0xD]]^S5[z[0x9]])&0x1f; _Kr[10]=(S5[z[0x1]]^S6[z[0x0]]^S7[z[0xE]]^S8[z[0xF]]^S6[z[0xc]])&0x1f; _Kr[11]=(S5[z[0x7]]^S6[z[0x6]]^S7[z[0x8]]^S8[z[0x9]]^S7[z[0x2]])&0x1f; _Kr[12]=(S5[z[0x5]]^S6[z[0x4]]^S7[z[0xA]]^S8[z[0xB]]^S8[z[0x6]])&0x1f; z03 = IntsTo32bits(z, 0x0); z47 = IntsTo32bits(z, 0x4); z8B = IntsTo32bits(z, 0x8); zCF = IntsTo32bits(z, 0xC); x03 = z8B ^S5[z[0x5]] ^S6[z[0x7]] ^S7[z[0x4]] ^S8[z[0x6]] ^S7[z[0x0]]; Bits32ToInts(x03, x, 0x0); x47 = z03 ^S5[x[0x0]] ^S6[x[0x2]] ^S7[x[0x1]] ^S8[x[0x3]] ^S8[z[0x2]]; Bits32ToInts(x47, x, 0x4); x8B = z47 ^S5[x[0x7]] ^S6[x[0x6]] ^S7[x[0x5]] ^S8[x[0x4]] ^S5[z[0x1]]; Bits32ToInts(x8B, x, 0x8); xCF = zCF ^S5[x[0xA]] ^S6[x[0x9]] ^S7[x[0xB]] ^S8[x[0x8]] ^S6[z[0x3]]; Bits32ToInts(xCF, x, 0xC); _Kr[13]=(S5[x[0x8]]^S6[x[0x9]]^S7[x[0x7]]^S8[x[0x6]]^S5[x[0x3]])&0x1f; _Kr[14]=(S5[x[0xA]]^S6[x[0xB]]^S7[x[0x5]]^S8[x[0x4]]^S6[x[0x7]])&0x1f; _Kr[15]=(S5[x[0xC]]^S6[x[0xD]]^S7[x[0x3]]^S8[x[0x2]]^S7[x[0x8]])&0x1f; _Kr[16]=(S5[x[0xE]]^S6[x[0xF]]^S7[x[0x1]]^S8[x[0x0]]^S8[x[0xD]])&0x1f; } /** * Encrypt the given input starting at the given offset and place * the result in the provided buffer starting at the given offset. * * @param src The plaintext buffer * @param srcIndex An offset into src * @param dst The ciphertext buffer * @param dstIndex An offset into dst */ protected int encryptBlock( byte[] src, int srcIndex, byte[] dst, int dstIndex) { int result[] = new int[2]; // process the input block // batch the units up into a 32 bit chunk and go for it // the array is in bytes, the increment is 8x8 bits = 64 int L0 = BytesTo32bits(src, srcIndex); int R0 = BytesTo32bits(src, srcIndex + 4); CAST_Encipher(L0, R0, result); // now stuff them into the destination block Bits32ToBytes(result[0], dst, dstIndex); Bits32ToBytes(result[1], dst, dstIndex + 4); return BLOCK_SIZE; } /** * Decrypt the given input starting at the given offset and place * the result in the provided buffer starting at the given offset. * * @param src The plaintext buffer * @param srcIndex An offset into src * @param dst The ciphertext buffer * @param dstIndex An offset into dst */ protected int decryptBlock( byte[] src, int srcIndex, byte[] dst, int dstIndex) { int result[] = new int[2]; // process the input block // batch the units up into a 32 bit chunk and go for it // the array is in bytes, the increment is 8x8 bits = 64 int L16 = BytesTo32bits(src, srcIndex); int R16 = BytesTo32bits(src, srcIndex+4); CAST_Decipher(L16, R16, result); // now stuff them into the destination block Bits32ToBytes(result[0], dst, dstIndex); Bits32ToBytes(result[1], dst, dstIndex+4); return BLOCK_SIZE; } /** * The first of the three processing functions for the * encryption and decryption. * * @param D the input to be processed * @param Kmi the mask to be used from Km[n] * @param Kri the rotation value to be used * */ protected final int F1(int D, int Kmi, int Kri) { int I = Kmi + D; I = I << Kri | I >>> (32-Kri); return ((S1[(I>>>24)&0xff]^S2[(I>>>16)&0xff])-S3[(I>>> 8)&0xff])+ S4[I & 0xff]; } /** * The second of the three processing functions for the * encryption and decryption. * * @param D the input to be processed * @param Kmi the mask to be used from Km[n] * @param Kri the rotation value to be used * */ protected final int F2(int D, int Kmi, int Kri) { int I = Kmi ^ D; I = I << Kri | I >>> (32-Kri); return ((S1[(I>>>24)&0xff]-S2[(I>>>16)&0xff])+S3[(I>>> 8)&0xff])^ S4[I & 0xff]; } /** * The third of the three processing functions for the * encryption and decryption. * * @param D the input to be processed * @param Kmi the mask to be used from Km[n] * @param Kri the rotation value to be used * */ protected final int F3(int D, int Kmi, int Kri) { int I = Kmi - D; I = I << Kri | I >>> (32-Kri); return ((S1[(I>>>24)&0xff]+S2[(I>>>16)&0xff])^S3[(I>>> 8)&0xff])- S4[I & 0xff]; } /** * Does the 16 rounds to encrypt the block. * * @param L0 the LH-32bits of the plaintext block * @param R0 the RH-32bits of the plaintext block */ protected final void CAST_Encipher(int L0, int R0, int result[]) { int Lp = L0; // the previous value, equiv to L[i-1] int Rp = R0; // equivalent to R[i-1] /* * numbering consistent with paper to make * checking and validating easier */ int Li = L0, Ri = R0; for (int i = 1; i<=_rounds ; i++) { Lp = Li; Rp = Ri; Li = Rp; switch (i) { case 1: case 4: case 7: case 10: case 13: case 16: Ri = Lp ^ F1(Rp, _Km[i], _Kr[i]); break; case 2: case 5: case 8: case 11: case 14: Ri = Lp ^ F2(Rp, _Km[i], _Kr[i]); break; case 3: case 6: case 9: case 12: case 15: Ri = Lp ^ F3(Rp, _Km[i], _Kr[i]); break; } } result[0] = Ri; result[1] = Li; return; } protected final void CAST_Decipher(int L16, int R16, int result[]) { int Lp = L16; // the previous value, equiv to L[i-1] int Rp = R16; // equivalent to R[i-1] /* * numbering consistent with paper to make * checking and validating easier */ int Li = L16, Ri = R16; for (int i = _rounds; i > 0; i--) { Lp = Li; Rp = Ri; Li = Rp; switch (i) { case 1: case 4: case 7: case 10: case 13: case 16: Ri = Lp ^ F1(Rp, _Km[i], _Kr[i]); break; case 2: case 5: case 8: case 11: case 14: Ri = Lp ^ F2(Rp, _Km[i], _Kr[i]); break; case 3: case 6: case 9: case 12: case 15: Ri = Lp ^ F3(Rp, _Km[i], _Kr[i]); break; } } result[0] = Ri; result[1] = Li; return; } protected final void Bits32ToInts(int in, int[] b, int offset) { b[offset + 3] = (in & 0xff); b[offset + 2] = ((in >>> 8) & 0xff); b[offset + 1] = ((in >>> 16) & 0xff); b[offset] = ((in >>> 24) & 0xff); } protected final int IntsTo32bits(int[] b, int i) { int rv = 0; rv = ((b[i] & 0xff) << 24) | ((b[i+1] & 0xff) << 16) | ((b[i+2] & 0xff) << 8) | ((b[i+3] & 0xff)); return rv; } protected final void Bits32ToBytes(int in, byte[] b, int offset) { b[offset + 3] = (byte)in; b[offset + 2] = (byte)(in >>> 8); b[offset + 1] = (byte)(in >>> 16); b[offset] = (byte)(in >>> 24); } protected final int BytesTo32bits(byte[] b, int i) { return ((b[i] & 0xff) << 24) | ((b[i+1] & 0xff) << 16) | ((b[i+2] & 0xff) << 8) | ((b[i+3] & 0xff)); } } bouncycastle-1.49.orig/src/org/bouncycastle/crypto/engines/IDEAEngine.java0000644000175000017500000002235412106330250026143 0ustar ebourgebourgpackage org.bouncycastle.crypto.engines; import org.bouncycastle.crypto.BlockCipher; import org.bouncycastle.crypto.CipherParameters; import org.bouncycastle.crypto.DataLengthException; import org.bouncycastle.crypto.OutputLengthException; import org.bouncycastle.crypto.params.KeyParameter; /** * A class that provides a basic International Data Encryption Algorithm (IDEA) engine. *

    * This implementation is based on the "HOWTO: INTERNATIONAL DATA ENCRYPTION ALGORITHM" * implementation summary by Fauzan Mirza (F.U.Mirza@sheffield.ac.uk). (baring 1 typo at the * end of the mulinv function!). *

    * It can be found at ftp://ftp.funet.fi/pub/crypt/cryptography/symmetric/idea/ *

    * Note 1: This algorithm is patented in the USA, Japan, and Europe including * at least Austria, France, Germany, Italy, Netherlands, Spain, Sweden, Switzerland * and the United Kingdom. Non-commercial use is free, however any commercial * products are liable for royalties. Please see * www.mediacrypt.com for * further details. This announcement has been included at the request of * the patent holders. *

    * Note 2: Due to the requests concerning the above, this algorithm is now only * included in the extended Bouncy Castle provider and JCE signed jars. It is * not included in the default distributions. */ public class IDEAEngine implements BlockCipher { protected static final int BLOCK_SIZE = 8; private int[] workingKey = null; /** * standard constructor. */ public IDEAEngine() { } /** * initialise an IDEA cipher. * * @param forEncryption whether or not we are for encryption. * @param params the parameters required to set up the cipher. * @exception IllegalArgumentException if the params argument is * inappropriate. */ public void init( boolean forEncryption, CipherParameters params) { if (params instanceof KeyParameter) { workingKey = generateWorkingKey(forEncryption, ((KeyParameter)params).getKey()); return; } throw new IllegalArgumentException("invalid parameter passed to IDEA init - " + params.getClass().getName()); } public String getAlgorithmName() { return "IDEA"; } public int getBlockSize() { return BLOCK_SIZE; } public int processBlock( byte[] in, int inOff, byte[] out, int outOff) { if (workingKey == null) { throw new IllegalStateException("IDEA engine not initialised"); } if ((inOff + BLOCK_SIZE) > in.length) { throw new DataLengthException("input buffer too short"); } if ((outOff + BLOCK_SIZE) > out.length) { throw new OutputLengthException("output buffer too short"); } ideaFunc(workingKey, in, inOff, out, outOff); return BLOCK_SIZE; } public void reset() { } private static final int MASK = 0xffff; private static final int BASE = 0x10001; private int bytesToWord( byte[] in, int inOff) { return ((in[inOff] << 8) & 0xff00) + (in[inOff + 1] & 0xff); } private void wordToBytes( int word, byte[] out, int outOff) { out[outOff] = (byte)(word >>> 8); out[outOff + 1] = (byte)word; } /** * return x = x * y where the multiplication is done modulo * 65537 (0x10001) (as defined in the IDEA specification) and * a zero input is taken to be 65536 (0x10000). * * @param x the x value * @param y the y value * @return x = x * y */ private int mul( int x, int y) { if (x == 0) { x = (BASE - y); } else if (y == 0) { x = (BASE - x); } else { int p = x * y; y = p & MASK; x = p >>> 16; x = y - x + ((y < x) ? 1 : 0); } return x & MASK; } private void ideaFunc( int[] workingKey, byte[] in, int inOff, byte[] out, int outOff) { int x0, x1, x2, x3, t0, t1; int keyOff = 0; x0 = bytesToWord(in, inOff); x1 = bytesToWord(in, inOff + 2); x2 = bytesToWord(in, inOff + 4); x3 = bytesToWord(in, inOff + 6); for (int round = 0; round < 8; round++) { x0 = mul(x0, workingKey[keyOff++]); x1 += workingKey[keyOff++]; x1 &= MASK; x2 += workingKey[keyOff++]; x2 &= MASK; x3 = mul(x3, workingKey[keyOff++]); t0 = x1; t1 = x2; x2 ^= x0; x1 ^= x3; x2 = mul(x2, workingKey[keyOff++]); x1 += x2; x1 &= MASK; x1 = mul(x1, workingKey[keyOff++]); x2 += x1; x2 &= MASK; x0 ^= x1; x3 ^= x2; x1 ^= t1; x2 ^= t0; } wordToBytes(mul(x0, workingKey[keyOff++]), out, outOff); wordToBytes(x2 + workingKey[keyOff++], out, outOff + 2); /* NB: Order */ wordToBytes(x1 + workingKey[keyOff++], out, outOff + 4); wordToBytes(mul(x3, workingKey[keyOff]), out, outOff + 6); } /** * The following function is used to expand the user key to the encryption * subkey. The first 16 bytes are the user key, and the rest of the subkey * is calculated by rotating the previous 16 bytes by 25 bits to the left, * and so on until the subkey is completed. */ private int[] expandKey( byte[] uKey) { int[] key = new int[52]; if (uKey.length < 16) { byte[] tmp = new byte[16]; System.arraycopy(uKey, 0, tmp, tmp.length - uKey.length, uKey.length); uKey = tmp; } for (int i = 0; i < 8; i++) { key[i] = bytesToWord(uKey, i * 2); } for (int i = 8; i < 52; i++) { if ((i & 7) < 6) { key[i] = ((key[i - 7] & 127) << 9 | key[i - 6] >> 7) & MASK; } else if ((i & 7) == 6) { key[i] = ((key[i - 7] & 127) << 9 | key[i - 14] >> 7) & MASK; } else { key[i] = ((key[i - 15] & 127) << 9 | key[i - 14] >> 7) & MASK; } } return key; } /** * This function computes multiplicative inverse using Euclid's Greatest * Common Divisor algorithm. Zero and one are self inverse. *

    * i.e. x * mulInv(x) == 1 (modulo BASE) */ private int mulInv( int x) { int t0, t1, q, y; if (x < 2) { return x; } t0 = 1; t1 = BASE / x; y = BASE % x; while (y != 1) { q = x / y; x = x % y; t0 = (t0 + (t1 * q)) & MASK; if (x == 1) { return t0; } q = y / x; y = y % x; t1 = (t1 + (t0 * q)) & MASK; } return (1 - t1) & MASK; } /** * Return the additive inverse of x. *

    * i.e. x + addInv(x) == 0 */ int addInv( int x) { return (0 - x) & MASK; } /** * The function to invert the encryption subkey to the decryption subkey. * It also involves the multiplicative inverse and the additive inverse functions. */ private int[] invertKey( int[] inKey) { int t1, t2, t3, t4; int p = 52; /* We work backwards */ int[] key = new int[52]; int inOff = 0; t1 = mulInv(inKey[inOff++]); t2 = addInv(inKey[inOff++]); t3 = addInv(inKey[inOff++]); t4 = mulInv(inKey[inOff++]); key[--p] = t4; key[--p] = t3; key[--p] = t2; key[--p] = t1; for (int round = 1; round < 8; round++) { t1 = inKey[inOff++]; t2 = inKey[inOff++]; key[--p] = t2; key[--p] = t1; t1 = mulInv(inKey[inOff++]); t2 = addInv(inKey[inOff++]); t3 = addInv(inKey[inOff++]); t4 = mulInv(inKey[inOff++]); key[--p] = t4; key[--p] = t2; /* NB: Order */ key[--p] = t3; key[--p] = t1; } t1 = inKey[inOff++]; t2 = inKey[inOff++]; key[--p] = t2; key[--p] = t1; t1 = mulInv(inKey[inOff++]); t2 = addInv(inKey[inOff++]); t3 = addInv(inKey[inOff++]); t4 = mulInv(inKey[inOff]); key[--p] = t4; key[--p] = t3; key[--p] = t2; key[--p] = t1; return key; } private int[] generateWorkingKey( boolean forEncryption, byte[] userKey) { if (forEncryption) { return expandKey(userKey); } else { return invertKey(expandKey(userKey)); } } } bouncycastle-1.49.orig/src/org/bouncycastle/crypto/engines/HC128Engine.java0000644000175000017500000001423412106330250026164 0ustar ebourgebourgpackage org.bouncycastle.crypto.engines; import org.bouncycastle.crypto.CipherParameters; import org.bouncycastle.crypto.DataLengthException; import org.bouncycastle.crypto.OutputLengthException; import org.bouncycastle.crypto.StreamCipher; import org.bouncycastle.crypto.params.KeyParameter; import org.bouncycastle.crypto.params.ParametersWithIV; /** * HC-128 is a software-efficient stream cipher created by Hongjun Wu. It * generates keystream from a 128-bit secret key and a 128-bit initialization * vector. *

    * http://www.ecrypt.eu.org/stream/p3ciphers/hc/hc128_p3.pdf *

    * It is a third phase candidate in the eStream contest, and is patent-free. * No attacks are known as of today (April 2007). See * * http://www.ecrypt.eu.org/stream/hcp3.html *

    */ public class HC128Engine implements StreamCipher { private int[] p = new int[512]; private int[] q = new int[512]; private int cnt = 0; private static int f1(int x) { return rotateRight(x, 7) ^ rotateRight(x, 18) ^ (x >>> 3); } private static int f2(int x) { return rotateRight(x, 17) ^ rotateRight(x, 19) ^ (x >>> 10); } private int g1(int x, int y, int z) { return (rotateRight(x, 10) ^ rotateRight(z, 23)) + rotateRight(y, 8); } private int g2(int x, int y, int z) { return (rotateLeft(x, 10) ^ rotateLeft(z, 23)) + rotateLeft(y, 8); } private static int rotateLeft( int x, int bits) { return (x << bits) | (x >>> -bits); } private static int rotateRight( int x, int bits) { return (x >>> bits) | (x << -bits); } private int h1(int x) { return q[x & 0xFF] + q[((x >> 16) & 0xFF) + 256]; } private int h2(int x) { return p[x & 0xFF] + p[((x >> 16) & 0xFF) + 256]; } private static int mod1024(int x) { return x & 0x3FF; } private static int mod512(int x) { return x & 0x1FF; } private static int dim(int x, int y) { return mod512(x - y); } private int step() { int j = mod512(cnt); int ret; if (cnt < 512) { p[j] += g1(p[dim(j, 3)], p[dim(j, 10)], p[dim(j, 511)]); ret = h1(p[dim(j, 12)]) ^ p[j]; } else { q[j] += g2(q[dim(j, 3)], q[dim(j, 10)], q[dim(j, 511)]); ret = h2(q[dim(j, 12)]) ^ q[j]; } cnt = mod1024(cnt + 1); return ret; } private byte[] key, iv; private boolean initialised; private void init() { if (key.length != 16) { throw new java.lang.IllegalArgumentException( "The key must be 128 bits long"); } cnt = 0; int[] w = new int[1280]; for (int i = 0; i < 16; i++) { w[i >> 2] |= (key[i] & 0xff) << (8 * (i & 0x3)); } System.arraycopy(w, 0, w, 4, 4); for (int i = 0; i < iv.length && i < 16; i++) { w[(i >> 2) + 8] |= (iv[i] & 0xff) << (8 * (i & 0x3)); } System.arraycopy(w, 8, w, 12, 4); for (int i = 16; i < 1280; i++) { w[i] = f2(w[i - 2]) + w[i - 7] + f1(w[i - 15]) + w[i - 16] + i; } System.arraycopy(w, 256, p, 0, 512); System.arraycopy(w, 768, q, 0, 512); for (int i = 0; i < 512; i++) { p[i] = step(); } for (int i = 0; i < 512; i++) { q[i] = step(); } cnt = 0; } public String getAlgorithmName() { return "HC-128"; } /** * Initialise a HC-128 cipher. * * @param forEncryption whether or not we are for encryption. Irrelevant, as * encryption and decryption are the same. * @param params the parameters required to set up the cipher. * @throws IllegalArgumentException if the params argument is * inappropriate (ie. the key is not 128 bit long). */ public void init(boolean forEncryption, CipherParameters params) throws IllegalArgumentException { CipherParameters keyParam = params; if (params instanceof ParametersWithIV) { iv = ((ParametersWithIV)params).getIV(); keyParam = ((ParametersWithIV)params).getParameters(); } else { iv = new byte[0]; } if (keyParam instanceof KeyParameter) { key = ((KeyParameter)keyParam).getKey(); init(); } else { throw new IllegalArgumentException( "Invalid parameter passed to HC128 init - " + params.getClass().getName()); } initialised = true; } private byte[] buf = new byte[4]; private int idx = 0; private byte getByte() { if (idx == 0) { int step = step(); buf[0] = (byte)(step & 0xFF); step >>= 8; buf[1] = (byte)(step & 0xFF); step >>= 8; buf[2] = (byte)(step & 0xFF); step >>= 8; buf[3] = (byte)(step & 0xFF); } byte ret = buf[idx]; idx = idx + 1 & 0x3; return ret; } public void processBytes(byte[] in, int inOff, int len, byte[] out, int outOff) throws DataLengthException { if (!initialised) { throw new IllegalStateException(getAlgorithmName() + " not initialised"); } if ((inOff + len) > in.length) { throw new DataLengthException("input buffer too short"); } if ((outOff + len) > out.length) { throw new OutputLengthException("output buffer too short"); } for (int i = 0; i < len; i++) { out[outOff + i] = (byte)(in[inOff + i] ^ getByte()); } } public void reset() { idx = 0; init(); } public byte returnByte(byte in) { return (byte)(in ^ getByte()); } } bouncycastle-1.49.orig/src/org/bouncycastle/crypto/engines/NaccacheSternEngine.java0000644000175000017500000003544210726050775030165 0ustar ebourgebourgpackage org.bouncycastle.crypto.engines; import java.math.BigInteger; import java.util.Vector; import org.bouncycastle.util.Arrays; import org.bouncycastle.crypto.AsymmetricBlockCipher; import org.bouncycastle.crypto.CipherParameters; import org.bouncycastle.crypto.DataLengthException; import org.bouncycastle.crypto.InvalidCipherTextException; import org.bouncycastle.crypto.params.NaccacheSternKeyParameters; import org.bouncycastle.crypto.params.NaccacheSternPrivateKeyParameters; import org.bouncycastle.crypto.params.ParametersWithRandom; /** * NaccacheStern Engine. For details on this cipher, please see * http://www.gemplus.com/smart/rd/publications/pdf/NS98pkcs.pdf */ public class NaccacheSternEngine implements AsymmetricBlockCipher { private boolean forEncryption; private NaccacheSternKeyParameters key; private Vector[] lookup = null; private boolean debug = false; private static BigInteger ZERO = BigInteger.valueOf(0); private static BigInteger ONE = BigInteger.valueOf(1); /** * Initializes this algorithm. Must be called before all other Functions. * * @see org.bouncycastle.crypto.AsymmetricBlockCipher#init(boolean, * org.bouncycastle.crypto.CipherParameters) */ public void init(boolean forEncryption, CipherParameters param) { this.forEncryption = forEncryption; if (param instanceof ParametersWithRandom) { param = ((ParametersWithRandom) param).getParameters(); } key = (NaccacheSternKeyParameters)param; // construct lookup table for faster decryption if necessary if (!this.forEncryption) { if (debug) { System.out.println("Constructing lookup Array"); } NaccacheSternPrivateKeyParameters priv = (NaccacheSternPrivateKeyParameters)key; Vector primes = priv.getSmallPrimes(); lookup = new Vector[primes.size()]; for (int i = 0; i < primes.size(); i++) { BigInteger actualPrime = (BigInteger)primes.elementAt(i); int actualPrimeValue = actualPrime.intValue(); lookup[i] = new Vector(); lookup[i].addElement(ONE); if (debug) { System.out.println("Constructing lookup ArrayList for " + actualPrimeValue); } BigInteger accJ = ZERO; for (int j = 1; j < actualPrimeValue; j++) { accJ = accJ.add(priv.getPhi_n()); BigInteger comp = accJ.divide(actualPrime); lookup[i].addElement(priv.getG().modPow(comp, priv.getModulus())); } } } } public void setDebug(boolean debug) { this.debug = debug; } /** * Returns the input block size of this algorithm. * * @see org.bouncycastle.crypto.AsymmetricBlockCipher#getInputBlockSize() */ public int getInputBlockSize() { if (forEncryption) { // We can only encrypt values up to lowerSigmaBound return (key.getLowerSigmaBound() + 7) / 8 - 1; } else { // We pad to modulus-size bytes for easier decryption. return key.getModulus().toByteArray().length; } } /** * Returns the output block size of this algorithm. * * @see org.bouncycastle.crypto.AsymmetricBlockCipher#getOutputBlockSize() */ public int getOutputBlockSize() { if (forEncryption) { // encrypted Data is always padded up to modulus size return key.getModulus().toByteArray().length; } else { // decrypted Data has upper limit lowerSigmaBound return (key.getLowerSigmaBound() + 7) / 8 - 1; } } /** * Process a single Block using the Naccache-Stern algorithm. * * @see org.bouncycastle.crypto.AsymmetricBlockCipher#processBlock(byte[], * int, int) */ public byte[] processBlock(byte[] in, int inOff, int len) throws InvalidCipherTextException { if (key == null) { throw new IllegalStateException("NaccacheStern engine not initialised"); } if (len > (getInputBlockSize() + 1)) { throw new DataLengthException("input too large for Naccache-Stern cipher.\n"); } if (!forEncryption) { // At decryption make sure that we receive padded data blocks if (len < getInputBlockSize()) { throw new InvalidCipherTextException("BlockLength does not match modulus for Naccache-Stern cipher.\n"); } } byte[] block; if (inOff != 0 || len != in.length) { block = new byte[len]; System.arraycopy(in, inOff, block, 0, len); } else { block = in; } // transform input into BigInteger BigInteger input = new BigInteger(1, block); if (debug) { System.out.println("input as BigInteger: " + input); } byte[] output; if (forEncryption) { output = encrypt(input); } else { Vector plain = new Vector(); NaccacheSternPrivateKeyParameters priv = (NaccacheSternPrivateKeyParameters)key; Vector primes = priv.getSmallPrimes(); // Get Chinese Remainders of CipherText for (int i = 0; i < primes.size(); i++) { BigInteger exp = input.modPow(priv.getPhi_n().divide((BigInteger)primes.elementAt(i)), priv.getModulus()); Vector al = lookup[i]; if (lookup[i].size() != ((BigInteger)primes.elementAt(i)).intValue()) { if (debug) { System.out.println("Prime is " + primes.elementAt(i) + ", lookup table has size " + al.size()); } throw new InvalidCipherTextException("Error in lookup Array for " + ((BigInteger)primes.elementAt(i)).intValue() + ": Size mismatch. Expected ArrayList with length " + ((BigInteger)primes.elementAt(i)).intValue() + " but found ArrayList of length " + lookup[i].size()); } int lookedup = al.indexOf(exp); if (lookedup == -1) { if (debug) { System.out.println("Actual prime is " + primes.elementAt(i)); System.out.println("Decrypted value is " + exp); System.out.println("LookupList for " + primes.elementAt(i) + " with size " + lookup[i].size() + " is: "); for (int j = 0; j < lookup[i].size(); j++) { System.out.println(lookup[i].elementAt(j)); } } throw new InvalidCipherTextException("Lookup failed"); } plain.addElement(BigInteger.valueOf(lookedup)); } BigInteger test = chineseRemainder(plain, primes); // Should not be used as an oracle, so reencrypt output to see // if it corresponds to input // this breaks probabilisic encryption, so disable it. Anyway, we do // use the first n primes for key generation, so it is pretty easy // to guess them. But as stated in the paper, this is not a security // breach. So we can just work with the correct sigma. // if (debug) { // System.out.println("Decryption is " + test); // } // if ((key.getG().modPow(test, key.getModulus())).equals(input)) { // output = test.toByteArray(); // } else { // if(debug){ // System.out.println("Engine seems to be used as an oracle, // returning null"); // } // output = null; // } output = test.toByteArray(); } return output; } /** * Encrypts a BigInteger aka Plaintext with the public key. * * @param plain * The BigInteger to encrypt * @return The byte[] representation of the encrypted BigInteger (i.e. * crypted.toByteArray()) */ public byte[] encrypt(BigInteger plain) { // Always return modulus size values 0-padded at the beginning // 0-padding at the beginning is correctly parsed by BigInteger :) byte[] output = key.getModulus().toByteArray(); Arrays.fill(output, (byte)0); byte[] tmp = key.getG().modPow(plain, key.getModulus()).toByteArray(); System .arraycopy(tmp, 0, output, output.length - tmp.length, tmp.length); if (debug) { System.out .println("Encrypted value is: " + new BigInteger(output)); } return output; } /** * Adds the contents of two encrypted blocks mod sigma * * @param block1 * the first encrypted block * @param block2 * the second encrypted block * @return encrypt((block1 + block2) mod sigma) * @throws InvalidCipherTextException */ public byte[] addCryptedBlocks(byte[] block1, byte[] block2) throws InvalidCipherTextException { // check for correct blocksize if (forEncryption) { if ((block1.length > getOutputBlockSize()) || (block2.length > getOutputBlockSize())) { throw new InvalidCipherTextException( "BlockLength too large for simple addition.\n"); } } else { if ((block1.length > getInputBlockSize()) || (block2.length > getInputBlockSize())) { throw new InvalidCipherTextException( "BlockLength too large for simple addition.\n"); } } // calculate resulting block BigInteger m1Crypt = new BigInteger(1, block1); BigInteger m2Crypt = new BigInteger(1, block2); BigInteger m1m2Crypt = m1Crypt.multiply(m2Crypt); m1m2Crypt = m1m2Crypt.mod(key.getModulus()); if (debug) { System.out.println("c(m1) as BigInteger:....... " + m1Crypt); System.out.println("c(m2) as BigInteger:....... " + m2Crypt); System.out.println("c(m1)*c(m2)%n = c(m1+m2)%n: " + m1m2Crypt); } byte[] output = key.getModulus().toByteArray(); Arrays.fill(output, (byte)0); System.arraycopy(m1m2Crypt.toByteArray(), 0, output, output.length - m1m2Crypt.toByteArray().length, m1m2Crypt.toByteArray().length); return output; } /** * Convenience Method for data exchange with the cipher. * * Determines blocksize and splits data to blocksize. * * @param data the data to be processed * @return the data after it went through the NaccacheSternEngine. * @throws InvalidCipherTextException */ public byte[] processData(byte[] data) throws InvalidCipherTextException { if (debug) { System.out.println(); } if (data.length > getInputBlockSize()) { int inBlocksize = getInputBlockSize(); int outBlocksize = getOutputBlockSize(); if (debug) { System.out.println("Input blocksize is: " + inBlocksize + " bytes"); System.out.println("Output blocksize is: " + outBlocksize + " bytes"); System.out.println("Data has length:.... " + data.length + " bytes"); } int datapos = 0; int retpos = 0; byte[] retval = new byte[(data.length / inBlocksize + 1) * outBlocksize]; while (datapos < data.length) { byte[] tmp; if (datapos + inBlocksize < data.length) { tmp = processBlock(data, datapos, inBlocksize); datapos += inBlocksize; } else { tmp = processBlock(data, datapos, data.length - datapos); datapos += data.length - datapos; } if (debug) { System.out.println("new datapos is " + datapos); } if (tmp != null) { System.arraycopy(tmp, 0, retval, retpos, tmp.length); retpos += tmp.length; } else { if (debug) { System.out.println("cipher returned null"); } throw new InvalidCipherTextException("cipher returned null"); } } byte[] ret = new byte[retpos]; System.arraycopy(retval, 0, ret, 0, retpos); if (debug) { System.out.println("returning " + ret.length + " bytes"); } return ret; } else { if (debug) { System.out.println("data size is less then input block size, processing directly"); } return processBlock(data, 0, data.length); } } /** * Computes the integer x that is expressed through the given primes and the * congruences with the chinese remainder theorem (CRT). * * @param congruences * the congruences c_i * @param primes * the primes p_i * @return an integer x for that x % p_i == c_i */ private static BigInteger chineseRemainder(Vector congruences, Vector primes) { BigInteger retval = ZERO; BigInteger all = ONE; for (int i = 0; i < primes.size(); i++) { all = all.multiply((BigInteger)primes.elementAt(i)); } for (int i = 0; i < primes.size(); i++) { BigInteger a = (BigInteger)primes.elementAt(i); BigInteger b = all.divide(a); BigInteger b_ = b.modInverse(a); BigInteger tmp = b.multiply(b_); tmp = tmp.multiply((BigInteger)congruences.elementAt(i)); retval = retval.add(tmp); } return retval.mod(all); } } bouncycastle-1.49.orig/src/org/bouncycastle/crypto/engines/RFC3394WrapEngine.java0000644000175000017500000001167711302667745027261 0ustar ebourgebourgpackage org.bouncycastle.crypto.engines; import org.bouncycastle.crypto.BlockCipher; import org.bouncycastle.crypto.CipherParameters; import org.bouncycastle.crypto.DataLengthException; import org.bouncycastle.crypto.InvalidCipherTextException; import org.bouncycastle.crypto.Wrapper; import org.bouncycastle.crypto.params.KeyParameter; import org.bouncycastle.crypto.params.ParametersWithIV; import org.bouncycastle.crypto.params.ParametersWithRandom; import org.bouncycastle.util.Arrays; /** * an implementation of the AES Key Wrapper from the NIST Key Wrap * Specification as described in RFC 3394. *

    * For further details see: http://www.ietf.org/rfc/rfc3394.txt * and http://csrc.nist.gov/encryption/kms/key-wrap.pdf. */ public class RFC3394WrapEngine implements Wrapper { private BlockCipher engine; private KeyParameter param; private boolean forWrapping; private byte[] iv = { (byte)0xa6, (byte)0xa6, (byte)0xa6, (byte)0xa6, (byte)0xa6, (byte)0xa6, (byte)0xa6, (byte)0xa6 }; public RFC3394WrapEngine(BlockCipher engine) { this.engine = engine; } public void init( boolean forWrapping, CipherParameters param) { this.forWrapping = forWrapping; if (param instanceof ParametersWithRandom) { param = ((ParametersWithRandom) param).getParameters(); } if (param instanceof KeyParameter) { this.param = (KeyParameter)param; } else if (param instanceof ParametersWithIV) { this.iv = ((ParametersWithIV)param).getIV(); this.param = (KeyParameter)((ParametersWithIV) param).getParameters(); if (this.iv.length != 8) { throw new IllegalArgumentException("IV not equal to 8"); } } } public String getAlgorithmName() { return engine.getAlgorithmName(); } public byte[] wrap( byte[] in, int inOff, int inLen) { if (!forWrapping) { throw new IllegalStateException("not set for wrapping"); } int n = inLen / 8; if ((n * 8) != inLen) { throw new DataLengthException("wrap data must be a multiple of 8 bytes"); } byte[] block = new byte[inLen + iv.length]; byte[] buf = new byte[8 + iv.length]; System.arraycopy(iv, 0, block, 0, iv.length); System.arraycopy(in, 0, block, iv.length, inLen); engine.init(true, param); for (int j = 0; j != 6; j++) { for (int i = 1; i <= n; i++) { System.arraycopy(block, 0, buf, 0, iv.length); System.arraycopy(block, 8 * i, buf, iv.length, 8); engine.processBlock(buf, 0, buf, 0); int t = n * j + i; for (int k = 1; t != 0; k++) { byte v = (byte)t; buf[iv.length - k] ^= v; t >>>= 8; } System.arraycopy(buf, 0, block, 0, 8); System.arraycopy(buf, 8, block, 8 * i, 8); } } return block; } public byte[] unwrap( byte[] in, int inOff, int inLen) throws InvalidCipherTextException { if (forWrapping) { throw new IllegalStateException("not set for unwrapping"); } int n = inLen / 8; if ((n * 8) != inLen) { throw new InvalidCipherTextException("unwrap data must be a multiple of 8 bytes"); } byte[] block = new byte[inLen - iv.length]; byte[] a = new byte[iv.length]; byte[] buf = new byte[8 + iv.length]; System.arraycopy(in, 0, a, 0, iv.length); System.arraycopy(in, iv.length, block, 0, inLen - iv.length); engine.init(false, param); n = n - 1; for (int j = 5; j >= 0; j--) { for (int i = n; i >= 1; i--) { System.arraycopy(a, 0, buf, 0, iv.length); System.arraycopy(block, 8 * (i - 1), buf, iv.length, 8); int t = n * j + i; for (int k = 1; t != 0; k++) { byte v = (byte)t; buf[iv.length - k] ^= v; t >>>= 8; } engine.processBlock(buf, 0, buf, 0); System.arraycopy(buf, 0, a, 0, 8); System.arraycopy(buf, 8, block, 8 * (i - 1), 8); } } if (!Arrays.constantTimeAreEqual(a, iv)) { throw new InvalidCipherTextException("checksum failed"); } return block; } } bouncycastle-1.49.orig/src/org/bouncycastle/crypto/engines/GOST28147Engine.java0000644000175000017500000003146412106330250026625 0ustar ebourgebourgpackage org.bouncycastle.crypto.engines; import java.util.Hashtable; import org.bouncycastle.crypto.BlockCipher; import org.bouncycastle.crypto.CipherParameters; import org.bouncycastle.crypto.DataLengthException; import org.bouncycastle.crypto.OutputLengthException; import org.bouncycastle.crypto.params.KeyParameter; import org.bouncycastle.crypto.params.ParametersWithSBox; import org.bouncycastle.util.Arrays; import org.bouncycastle.util.Strings; /** * implementation of GOST 28147-89 */ public class GOST28147Engine implements BlockCipher { protected static final int BLOCK_SIZE = 8; private int[] workingKey = null; private boolean forEncryption; private byte[] S = Sbox_Default; // these are the S-boxes given in Applied Cryptography 2nd Ed., p. 333 // This is default S-box! private static byte Sbox_Default[] = { 0x4,0xA,0x9,0x2,0xD,0x8,0x0,0xE,0x6,0xB,0x1,0xC,0x7,0xF,0x5,0x3, 0xE,0xB,0x4,0xC,0x6,0xD,0xF,0xA,0x2,0x3,0x8,0x1,0x0,0x7,0x5,0x9, 0x5,0x8,0x1,0xD,0xA,0x3,0x4,0x2,0xE,0xF,0xC,0x7,0x6,0x0,0x9,0xB, 0x7,0xD,0xA,0x1,0x0,0x8,0x9,0xF,0xE,0x4,0x6,0xC,0xB,0x2,0x5,0x3, 0x6,0xC,0x7,0x1,0x5,0xF,0xD,0x8,0x4,0xA,0x9,0xE,0x0,0x3,0xB,0x2, 0x4,0xB,0xA,0x0,0x7,0x2,0x1,0xD,0x3,0x6,0x8,0x5,0x9,0xC,0xF,0xE, 0xD,0xB,0x4,0x1,0x3,0xF,0x5,0x9,0x0,0xA,0xE,0x7,0x6,0x8,0x2,0xC, 0x1,0xF,0xD,0x0,0x5,0x7,0xA,0x4,0x9,0x2,0x3,0xE,0x6,0xB,0x8,0xC }; /* * class content S-box parameters for encrypting * getting from, see: http://tools.ietf.org/id/draft-popov-cryptopro-cpalgs-01.txt * http://tools.ietf.org/id/draft-popov-cryptopro-cpalgs-02.txt */ private static byte[] ESbox_Test = { 0x4,0x2,0xF,0x5,0x9,0x1,0x0,0x8,0xE,0x3,0xB,0xC,0xD,0x7,0xA,0x6, 0xC,0x9,0xF,0xE,0x8,0x1,0x3,0xA,0x2,0x7,0x4,0xD,0x6,0x0,0xB,0x5, 0xD,0x8,0xE,0xC,0x7,0x3,0x9,0xA,0x1,0x5,0x2,0x4,0x6,0xF,0x0,0xB, 0xE,0x9,0xB,0x2,0x5,0xF,0x7,0x1,0x0,0xD,0xC,0x6,0xA,0x4,0x3,0x8, 0x3,0xE,0x5,0x9,0x6,0x8,0x0,0xD,0xA,0xB,0x7,0xC,0x2,0x1,0xF,0x4, 0x8,0xF,0x6,0xB,0x1,0x9,0xC,0x5,0xD,0x3,0x7,0xA,0x0,0xE,0x2,0x4, 0x9,0xB,0xC,0x0,0x3,0x6,0x7,0x5,0x4,0x8,0xE,0xF,0x1,0xA,0x2,0xD, 0xC,0x6,0x5,0x2,0xB,0x0,0x9,0xD,0x3,0xE,0x7,0xA,0xF,0x4,0x1,0x8 }; private static byte[] ESbox_A = { 0x9,0x6,0x3,0x2,0x8,0xB,0x1,0x7,0xA,0x4,0xE,0xF,0xC,0x0,0xD,0x5, 0x3,0x7,0xE,0x9,0x8,0xA,0xF,0x0,0x5,0x2,0x6,0xC,0xB,0x4,0xD,0x1, 0xE,0x4,0x6,0x2,0xB,0x3,0xD,0x8,0xC,0xF,0x5,0xA,0x0,0x7,0x1,0x9, 0xE,0x7,0xA,0xC,0xD,0x1,0x3,0x9,0x0,0x2,0xB,0x4,0xF,0x8,0x5,0x6, 0xB,0x5,0x1,0x9,0x8,0xD,0xF,0x0,0xE,0x4,0x2,0x3,0xC,0x7,0xA,0x6, 0x3,0xA,0xD,0xC,0x1,0x2,0x0,0xB,0x7,0x5,0x9,0x4,0x8,0xF,0xE,0x6, 0x1,0xD,0x2,0x9,0x7,0xA,0x6,0x0,0x8,0xC,0x4,0x5,0xF,0x3,0xB,0xE, 0xB,0xA,0xF,0x5,0x0,0xC,0xE,0x8,0x6,0x2,0x3,0x9,0x1,0x7,0xD,0x4 }; private static byte[] ESbox_B = { 0x8,0x4,0xB,0x1,0x3,0x5,0x0,0x9,0x2,0xE,0xA,0xC,0xD,0x6,0x7,0xF, 0x0,0x1,0x2,0xA,0x4,0xD,0x5,0xC,0x9,0x7,0x3,0xF,0xB,0x8,0x6,0xE, 0xE,0xC,0x0,0xA,0x9,0x2,0xD,0xB,0x7,0x5,0x8,0xF,0x3,0x6,0x1,0x4, 0x7,0x5,0x0,0xD,0xB,0x6,0x1,0x2,0x3,0xA,0xC,0xF,0x4,0xE,0x9,0x8, 0x2,0x7,0xC,0xF,0x9,0x5,0xA,0xB,0x1,0x4,0x0,0xD,0x6,0x8,0xE,0x3, 0x8,0x3,0x2,0x6,0x4,0xD,0xE,0xB,0xC,0x1,0x7,0xF,0xA,0x0,0x9,0x5, 0x5,0x2,0xA,0xB,0x9,0x1,0xC,0x3,0x7,0x4,0xD,0x0,0x6,0xF,0x8,0xE, 0x0,0x4,0xB,0xE,0x8,0x3,0x7,0x1,0xA,0x2,0x9,0x6,0xF,0xD,0x5,0xC }; private static byte[] ESbox_C = { 0x1,0xB,0xC,0x2,0x9,0xD,0x0,0xF,0x4,0x5,0x8,0xE,0xA,0x7,0x6,0x3, 0x0,0x1,0x7,0xD,0xB,0x4,0x5,0x2,0x8,0xE,0xF,0xC,0x9,0xA,0x6,0x3, 0x8,0x2,0x5,0x0,0x4,0x9,0xF,0xA,0x3,0x7,0xC,0xD,0x6,0xE,0x1,0xB, 0x3,0x6,0x0,0x1,0x5,0xD,0xA,0x8,0xB,0x2,0x9,0x7,0xE,0xF,0xC,0x4, 0x8,0xD,0xB,0x0,0x4,0x5,0x1,0x2,0x9,0x3,0xC,0xE,0x6,0xF,0xA,0x7, 0xC,0x9,0xB,0x1,0x8,0xE,0x2,0x4,0x7,0x3,0x6,0x5,0xA,0x0,0xF,0xD, 0xA,0x9,0x6,0x8,0xD,0xE,0x2,0x0,0xF,0x3,0x5,0xB,0x4,0x1,0xC,0x7, 0x7,0x4,0x0,0x5,0xA,0x2,0xF,0xE,0xC,0x6,0x1,0xB,0xD,0x9,0x3,0x8 }; private static byte[] ESbox_D = { 0xF,0xC,0x2,0xA,0x6,0x4,0x5,0x0,0x7,0x9,0xE,0xD,0x1,0xB,0x8,0x3, 0xB,0x6,0x3,0x4,0xC,0xF,0xE,0x2,0x7,0xD,0x8,0x0,0x5,0xA,0x9,0x1, 0x1,0xC,0xB,0x0,0xF,0xE,0x6,0x5,0xA,0xD,0x4,0x8,0x9,0x3,0x7,0x2, 0x1,0x5,0xE,0xC,0xA,0x7,0x0,0xD,0x6,0x2,0xB,0x4,0x9,0x3,0xF,0x8, 0x0,0xC,0x8,0x9,0xD,0x2,0xA,0xB,0x7,0x3,0x6,0x5,0x4,0xE,0xF,0x1, 0x8,0x0,0xF,0x3,0x2,0x5,0xE,0xB,0x1,0xA,0x4,0x7,0xC,0x9,0xD,0x6, 0x3,0x0,0x6,0xF,0x1,0xE,0x9,0x2,0xD,0x8,0xC,0x4,0xB,0xA,0x5,0x7, 0x1,0xA,0x6,0x8,0xF,0xB,0x0,0x4,0xC,0x3,0x5,0x9,0x7,0xD,0x2,0xE }; //S-box for digest private static byte DSbox_Test[] = { 0x4,0xA,0x9,0x2,0xD,0x8,0x0,0xE,0x6,0xB,0x1,0xC,0x7,0xF,0x5,0x3, 0xE,0xB,0x4,0xC,0x6,0xD,0xF,0xA,0x2,0x3,0x8,0x1,0x0,0x7,0x5,0x9, 0x5,0x8,0x1,0xD,0xA,0x3,0x4,0x2,0xE,0xF,0xC,0x7,0x6,0x0,0x9,0xB, 0x7,0xD,0xA,0x1,0x0,0x8,0x9,0xF,0xE,0x4,0x6,0xC,0xB,0x2,0x5,0x3, 0x6,0xC,0x7,0x1,0x5,0xF,0xD,0x8,0x4,0xA,0x9,0xE,0x0,0x3,0xB,0x2, 0x4,0xB,0xA,0x0,0x7,0x2,0x1,0xD,0x3,0x6,0x8,0x5,0x9,0xC,0xF,0xE, 0xD,0xB,0x4,0x1,0x3,0xF,0x5,0x9,0x0,0xA,0xE,0x7,0x6,0x8,0x2,0xC, 0x1,0xF,0xD,0x0,0x5,0x7,0xA,0x4,0x9,0x2,0x3,0xE,0x6,0xB,0x8,0xC }; private static byte DSbox_A[] = { 0xA,0x4,0x5,0x6,0x8,0x1,0x3,0x7,0xD,0xC,0xE,0x0,0x9,0x2,0xB,0xF, 0x5,0xF,0x4,0x0,0x2,0xD,0xB,0x9,0x1,0x7,0x6,0x3,0xC,0xE,0xA,0x8, 0x7,0xF,0xC,0xE,0x9,0x4,0x1,0x0,0x3,0xB,0x5,0x2,0x6,0xA,0x8,0xD, 0x4,0xA,0x7,0xC,0x0,0xF,0x2,0x8,0xE,0x1,0x6,0x5,0xD,0xB,0x9,0x3, 0x7,0x6,0x4,0xB,0x9,0xC,0x2,0xA,0x1,0x8,0x0,0xE,0xF,0xD,0x3,0x5, 0x7,0x6,0x2,0x4,0xD,0x9,0xF,0x0,0xA,0x1,0x5,0xB,0x8,0xE,0xC,0x3, 0xD,0xE,0x4,0x1,0x7,0x0,0x5,0xA,0x3,0xC,0x8,0xF,0x6,0x2,0x9,0xB, 0x1,0x3,0xA,0x9,0x5,0xB,0x4,0xF,0x8,0x6,0x7,0xE,0xD,0x0,0x2,0xC }; // // pre-defined sbox table // private static Hashtable sBoxes = new Hashtable(); static { addSBox("Default", Sbox_Default); addSBox("E-TEST", ESbox_Test); addSBox("E-A", ESbox_A); addSBox("E-B", ESbox_B); addSBox("E-C", ESbox_C); addSBox("E-D", ESbox_D); addSBox("D-TEST", DSbox_Test); addSBox("D-A", DSbox_A); } private static void addSBox(String sBoxName, byte[] sBox) { sBoxes.put(Strings.toUpperCase(sBoxName), sBox); } /** * standard constructor. */ public GOST28147Engine() { } /** * initialise an GOST28147 cipher. * * @param forEncryption whether or not we are for encryption. * @param params the parameters required to set up the cipher. * @exception IllegalArgumentException if the params argument is * inappropriate. */ public void init( boolean forEncryption, CipherParameters params) { if (params instanceof ParametersWithSBox) { ParametersWithSBox param = (ParametersWithSBox)params; // // Set the S-Box // byte[] sBox = param.getSBox(); if (sBox.length != Sbox_Default.length) { throw new IllegalArgumentException("invalid S-box passed to GOST28147 init"); } this.S = Arrays.clone(sBox); // // set key if there is one // if (param.getParameters() != null) { workingKey = generateWorkingKey(forEncryption, ((KeyParameter)param.getParameters()).getKey()); } } else if (params instanceof KeyParameter) { workingKey = generateWorkingKey(forEncryption, ((KeyParameter)params).getKey()); } else if (params != null) { throw new IllegalArgumentException("invalid parameter passed to GOST28147 init - " + params.getClass().getName()); } } public String getAlgorithmName() { return "GOST28147"; } public int getBlockSize() { return BLOCK_SIZE; } public int processBlock( byte[] in, int inOff, byte[] out, int outOff) { if (workingKey == null) { throw new IllegalStateException("GOST28147 engine not initialised"); } if ((inOff + BLOCK_SIZE) > in.length) { throw new DataLengthException("input buffer too short"); } if ((outOff + BLOCK_SIZE) > out.length) { throw new OutputLengthException("output buffer too short"); } GOST28147Func(workingKey, in, inOff, out, outOff); return BLOCK_SIZE; } public void reset() { } private int[] generateWorkingKey( boolean forEncryption, byte[] userKey) { this.forEncryption = forEncryption; if (userKey.length != 32) { throw new IllegalArgumentException("Key length invalid. Key needs to be 32 byte - 256 bit!!!"); } int key[] = new int[8]; for(int i=0; i!=8; i++) { key[i] = bytesToint(userKey,i*4); } return key; } private int GOST28147_mainStep(int n1, int key) { int cm = (key + n1); // CM1 // S-box replacing int om = S[ 0 + ((cm >> (0 * 4)) & 0xF)] << (0 * 4); om += S[ 16 + ((cm >> (1 * 4)) & 0xF)] << (1 * 4); om += S[ 32 + ((cm >> (2 * 4)) & 0xF)] << (2 * 4); om += S[ 48 + ((cm >> (3 * 4)) & 0xF)] << (3 * 4); om += S[ 64 + ((cm >> (4 * 4)) & 0xF)] << (4 * 4); om += S[ 80 + ((cm >> (5 * 4)) & 0xF)] << (5 * 4); om += S[ 96 + ((cm >> (6 * 4)) & 0xF)] << (6 * 4); om += S[112 + ((cm >> (7 * 4)) & 0xF)] << (7 * 4); return om << 11 | om >>> (32-11); // 11-leftshift } private void GOST28147Func( int[] workingKey, byte[] in, int inOff, byte[] out, int outOff) { int N1, N2, tmp; //tmp -> for saving N1 N1 = bytesToint(in, inOff); N2 = bytesToint(in, inOff + 4); if (this.forEncryption) { for(int k = 0; k < 3; k++) // 1-24 steps { for(int j = 0; j < 8; j++) { tmp = N1; N1 = N2 ^ GOST28147_mainStep(N1, workingKey[j]); // CM2 N2 = tmp; } } for(int j = 7; j > 0; j--) // 25-31 steps { tmp = N1; N1 = N2 ^ GOST28147_mainStep(N1, workingKey[j]); // CM2 N2 = tmp; } } else //decrypt { for(int j = 0; j < 8; j++) // 1-8 steps { tmp = N1; N1 = N2 ^ GOST28147_mainStep(N1, workingKey[j]); // CM2 N2 = tmp; } for(int k = 0; k < 3; k++) //9-31 steps { for(int j = 7; j >= 0; j--) { if ((k == 2) && (j==0)) { break; // break 32 step } tmp = N1; N1 = N2 ^ GOST28147_mainStep(N1, workingKey[j]); // CM2 N2 = tmp; } } } N2 = N2 ^ GOST28147_mainStep(N1, workingKey[0]); // 32 step (N1=N1) intTobytes(N1, out, outOff); intTobytes(N2, out, outOff + 4); } //array of bytes to type int private int bytesToint( byte[] in, int inOff) { return ((in[inOff + 3] << 24) & 0xff000000) + ((in[inOff + 2] << 16) & 0xff0000) + ((in[inOff + 1] << 8) & 0xff00) + (in[inOff] & 0xff); } //int to array of bytes private void intTobytes( int num, byte[] out, int outOff) { out[outOff + 3] = (byte)(num >>> 24); out[outOff + 2] = (byte)(num >>> 16); out[outOff + 1] = (byte)(num >>> 8); out[outOff] = (byte)num; } /** * Return the S-Box associated with SBoxName * @param sBoxName name of the S-Box * @return byte array representing the S-Box */ public static byte[] getSBox( String sBoxName) { byte[] sBox = (byte[])sBoxes.get(Strings.toUpperCase(sBoxName)); if (sBox == null) { throw new IllegalArgumentException("Unknown S-Box - possible types: " + "\"Default\", \"E-Test\", \"E-A\", \"E-B\", \"E-C\", \"E-D\", \"D-Test\", \"D-A\"."); } return Arrays.clone(sBox); } } bouncycastle-1.49.orig/src/org/bouncycastle/crypto/engines/AESLightEngine.java0000644000175000017500000004736312106327653027065 0ustar ebourgebourgpackage org.bouncycastle.crypto.engines; import org.bouncycastle.crypto.BlockCipher; import org.bouncycastle.crypto.CipherParameters; import org.bouncycastle.crypto.DataLengthException; import org.bouncycastle.crypto.OutputLengthException; import org.bouncycastle.crypto.params.KeyParameter; /** * an implementation of the AES (Rijndael), from FIPS-197. *

    * For further details see: http://csrc.nist.gov/encryption/aes/. * * This implementation is based on optimizations from Dr. Brian Gladman's paper and C code at * http://fp.gladman.plus.com/cryptography_technology/rijndael/ * * There are three levels of tradeoff of speed vs memory * Because java has no preprocessor, they are written as three separate classes from which to choose * * The fastest uses 8Kbytes of static tables to precompute round calculations, 4 256 word tables for encryption * and 4 for decryption. * * The middle performance version uses only one 256 word table for each, for a total of 2Kbytes, * adding 12 rotate operations per round to compute the values contained in the other tables from * the contents of the first * * The slowest version uses no static tables at all and computes the values * in each round. *

    * This file contains the slowest performance version with no static tables * for round precomputation, but it has the smallest foot print. * */ public class AESLightEngine implements BlockCipher { // The S box private static final byte[] S = { (byte)99, (byte)124, (byte)119, (byte)123, (byte)242, (byte)107, (byte)111, (byte)197, (byte)48, (byte)1, (byte)103, (byte)43, (byte)254, (byte)215, (byte)171, (byte)118, (byte)202, (byte)130, (byte)201, (byte)125, (byte)250, (byte)89, (byte)71, (byte)240, (byte)173, (byte)212, (byte)162, (byte)175, (byte)156, (byte)164, (byte)114, (byte)192, (byte)183, (byte)253, (byte)147, (byte)38, (byte)54, (byte)63, (byte)247, (byte)204, (byte)52, (byte)165, (byte)229, (byte)241, (byte)113, (byte)216, (byte)49, (byte)21, (byte)4, (byte)199, (byte)35, (byte)195, (byte)24, (byte)150, (byte)5, (byte)154, (byte)7, (byte)18, (byte)128, (byte)226, (byte)235, (byte)39, (byte)178, (byte)117, (byte)9, (byte)131, (byte)44, (byte)26, (byte)27, (byte)110, (byte)90, (byte)160, (byte)82, (byte)59, (byte)214, (byte)179, (byte)41, (byte)227, (byte)47, (byte)132, (byte)83, (byte)209, (byte)0, (byte)237, (byte)32, (byte)252, (byte)177, (byte)91, (byte)106, (byte)203, (byte)190, (byte)57, (byte)74, (byte)76, (byte)88, (byte)207, (byte)208, (byte)239, (byte)170, (byte)251, (byte)67, (byte)77, (byte)51, (byte)133, (byte)69, (byte)249, (byte)2, (byte)127, (byte)80, (byte)60, (byte)159, (byte)168, (byte)81, (byte)163, (byte)64, (byte)143, (byte)146, (byte)157, (byte)56, (byte)245, (byte)188, (byte)182, (byte)218, (byte)33, (byte)16, (byte)255, (byte)243, (byte)210, (byte)205, (byte)12, (byte)19, (byte)236, (byte)95, (byte)151, (byte)68, (byte)23, (byte)196, (byte)167, (byte)126, (byte)61, (byte)100, (byte)93, (byte)25, (byte)115, (byte)96, (byte)129, (byte)79, (byte)220, (byte)34, (byte)42, (byte)144, (byte)136, (byte)70, (byte)238, (byte)184, (byte)20, (byte)222, (byte)94, (byte)11, (byte)219, (byte)224, (byte)50, (byte)58, (byte)10, (byte)73, (byte)6, (byte)36, (byte)92, (byte)194, (byte)211, (byte)172, (byte)98, (byte)145, (byte)149, (byte)228, (byte)121, (byte)231, (byte)200, (byte)55, (byte)109, (byte)141, (byte)213, (byte)78, (byte)169, (byte)108, (byte)86, (byte)244, (byte)234, (byte)101, (byte)122, (byte)174, (byte)8, (byte)186, (byte)120, (byte)37, (byte)46, (byte)28, (byte)166, (byte)180, (byte)198, (byte)232, (byte)221, (byte)116, (byte)31, (byte)75, (byte)189, (byte)139, (byte)138, (byte)112, (byte)62, (byte)181, (byte)102, (byte)72, (byte)3, (byte)246, (byte)14, (byte)97, (byte)53, (byte)87, (byte)185, (byte)134, (byte)193, (byte)29, (byte)158, (byte)225, (byte)248, (byte)152, (byte)17, (byte)105, (byte)217, (byte)142, (byte)148, (byte)155, (byte)30, (byte)135, (byte)233, (byte)206, (byte)85, (byte)40, (byte)223, (byte)140, (byte)161, (byte)137, (byte)13, (byte)191, (byte)230, (byte)66, (byte)104, (byte)65, (byte)153, (byte)45, (byte)15, (byte)176, (byte)84, (byte)187, (byte)22, }; // The inverse S-box private static final byte[] Si = { (byte)82, (byte)9, (byte)106, (byte)213, (byte)48, (byte)54, (byte)165, (byte)56, (byte)191, (byte)64, (byte)163, (byte)158, (byte)129, (byte)243, (byte)215, (byte)251, (byte)124, (byte)227, (byte)57, (byte)130, (byte)155, (byte)47, (byte)255, (byte)135, (byte)52, (byte)142, (byte)67, (byte)68, (byte)196, (byte)222, (byte)233, (byte)203, (byte)84, (byte)123, (byte)148, (byte)50, (byte)166, (byte)194, (byte)35, (byte)61, (byte)238, (byte)76, (byte)149, (byte)11, (byte)66, (byte)250, (byte)195, (byte)78, (byte)8, (byte)46, (byte)161, (byte)102, (byte)40, (byte)217, (byte)36, (byte)178, (byte)118, (byte)91, (byte)162, (byte)73, (byte)109, (byte)139, (byte)209, (byte)37, (byte)114, (byte)248, (byte)246, (byte)100, (byte)134, (byte)104, (byte)152, (byte)22, (byte)212, (byte)164, (byte)92, (byte)204, (byte)93, (byte)101, (byte)182, (byte)146, (byte)108, (byte)112, (byte)72, (byte)80, (byte)253, (byte)237, (byte)185, (byte)218, (byte)94, (byte)21, (byte)70, (byte)87, (byte)167, (byte)141, (byte)157, (byte)132, (byte)144, (byte)216, (byte)171, (byte)0, (byte)140, (byte)188, (byte)211, (byte)10, (byte)247, (byte)228, (byte)88, (byte)5, (byte)184, (byte)179, (byte)69, (byte)6, (byte)208, (byte)44, (byte)30, (byte)143, (byte)202, (byte)63, (byte)15, (byte)2, (byte)193, (byte)175, (byte)189, (byte)3, (byte)1, (byte)19, (byte)138, (byte)107, (byte)58, (byte)145, (byte)17, (byte)65, (byte)79, (byte)103, (byte)220, (byte)234, (byte)151, (byte)242, (byte)207, (byte)206, (byte)240, (byte)180, (byte)230, (byte)115, (byte)150, (byte)172, (byte)116, (byte)34, (byte)231, (byte)173, (byte)53, (byte)133, (byte)226, (byte)249, (byte)55, (byte)232, (byte)28, (byte)117, (byte)223, (byte)110, (byte)71, (byte)241, (byte)26, (byte)113, (byte)29, (byte)41, (byte)197, (byte)137, (byte)111, (byte)183, (byte)98, (byte)14, (byte)170, (byte)24, (byte)190, (byte)27, (byte)252, (byte)86, (byte)62, (byte)75, (byte)198, (byte)210, (byte)121, (byte)32, (byte)154, (byte)219, (byte)192, (byte)254, (byte)120, (byte)205, (byte)90, (byte)244, (byte)31, (byte)221, (byte)168, (byte)51, (byte)136, (byte)7, (byte)199, (byte)49, (byte)177, (byte)18, (byte)16, (byte)89, (byte)39, (byte)128, (byte)236, (byte)95, (byte)96, (byte)81, (byte)127, (byte)169, (byte)25, (byte)181, (byte)74, (byte)13, (byte)45, (byte)229, (byte)122, (byte)159, (byte)147, (byte)201, (byte)156, (byte)239, (byte)160, (byte)224, (byte)59, (byte)77, (byte)174, (byte)42, (byte)245, (byte)176, (byte)200, (byte)235, (byte)187, (byte)60, (byte)131, (byte)83, (byte)153, (byte)97, (byte)23, (byte)43, (byte)4, (byte)126, (byte)186, (byte)119, (byte)214, (byte)38, (byte)225, (byte)105, (byte)20, (byte)99, (byte)85, (byte)33, (byte)12, (byte)125, }; // vector used in calculating key schedule (powers of x in GF(256)) private static final int[] rcon = { 0x01, 0x02, 0x04, 0x08, 0x10, 0x20, 0x40, 0x80, 0x1b, 0x36, 0x6c, 0xd8, 0xab, 0x4d, 0x9a, 0x2f, 0x5e, 0xbc, 0x63, 0xc6, 0x97, 0x35, 0x6a, 0xd4, 0xb3, 0x7d, 0xfa, 0xef, 0xc5, 0x91 }; private static int shift(int r, int shift) { return (r >>> shift) | (r << -shift); } /* multiply four bytes in GF(2^8) by 'x' {02} in parallel */ private static final int m1 = 0x80808080; private static final int m2 = 0x7f7f7f7f; private static final int m3 = 0x0000001b; private static int FFmulX(int x) { return (((x & m2) << 1) ^ (((x & m1) >>> 7) * m3)); } /* The following defines provide alternative definitions of FFmulX that might give improved performance if a fast 32-bit multiply is not available. private int FFmulX(int x) { int u = x & m1; u |= (u >> 1); return ((x & m2) << 1) ^ ((u >>> 3) | (u >>> 6)); } private static final int m4 = 0x1b1b1b1b; private int FFmulX(int x) { int u = x & m1; return ((x & m2) << 1) ^ ((u - (u >>> 7)) & m4); } */ private static int mcol(int x) { int f2 = FFmulX(x); return f2 ^ shift(x ^ f2, 8) ^ shift(x, 16) ^ shift(x, 24); } private static int inv_mcol(int x) { int f2 = FFmulX(x); int f4 = FFmulX(f2); int f8 = FFmulX(f4); int f9 = x ^ f8; return f2 ^ f4 ^ f8 ^ shift(f2 ^ f9, 8) ^ shift(f4 ^ f9, 16) ^ shift(f9, 24); } private static int subWord(int x) { return (S[x&255]&255 | ((S[(x>>8)&255]&255)<<8) | ((S[(x>>16)&255]&255)<<16) | S[(x>>24)&255]<<24); } /** * Calculate the necessary round keys * The number of calculations depends on key size and block size * AES specified a fixed block size of 128 bits and key sizes 128/192/256 bits * This code is written assuming those are the only possible values */ private int[][] generateWorkingKey( byte[] key, boolean forEncryption) { int KC = key.length / 4; // key length in words int t; if (((KC != 4) && (KC != 6) && (KC != 8)) || ((KC * 4) != key.length)) { throw new IllegalArgumentException("Key length not 128/192/256 bits."); } ROUNDS = KC + 6; // This is not always true for the generalized Rijndael that allows larger block sizes int[][] W = new int[ROUNDS+1][4]; // 4 words in a block // // copy the key into the round key array // t = 0; int i = 0; while (i < key.length) { W[t >> 2][t & 3] = (key[i]&0xff) | ((key[i+1]&0xff) << 8) | ((key[i+2]&0xff) << 16) | (key[i+3] << 24); i+=4; t++; } // // while not enough round key material calculated // calculate new values // int k = (ROUNDS + 1) << 2; for (i = KC; (i < k); i++) { int temp = W[(i-1)>>2][(i-1)&3]; if ((i % KC) == 0) { temp = subWord(shift(temp, 8)) ^ rcon[(i / KC)-1]; } else if ((KC > 6) && ((i % KC) == 4)) { temp = subWord(temp); } W[i>>2][i&3] = W[(i - KC)>>2][(i-KC)&3] ^ temp; } if (!forEncryption) { for (int j = 1; j < ROUNDS; j++) { for (i = 0; i < 4; i++) { W[j][i] = inv_mcol(W[j][i]); } } } return W; } private int ROUNDS; private int[][] WorkingKey = null; private int C0, C1, C2, C3; private boolean forEncryption; private static final int BLOCK_SIZE = 16; /** * default constructor - 128 bit block size. */ public AESLightEngine() { } /** * initialise an AES cipher. * * @param forEncryption whether or not we are for encryption. * @param params the parameters required to set up the cipher. * @exception IllegalArgumentException if the params argument is * inappropriate. */ public void init( boolean forEncryption, CipherParameters params) { if (params instanceof KeyParameter) { WorkingKey = generateWorkingKey(((KeyParameter)params).getKey(), forEncryption); this.forEncryption = forEncryption; return; } throw new IllegalArgumentException("invalid parameter passed to AES init - " + params.getClass().getName()); } public String getAlgorithmName() { return "AES"; } public int getBlockSize() { return BLOCK_SIZE; } public int processBlock( byte[] in, int inOff, byte[] out, int outOff) { if (WorkingKey == null) { throw new IllegalStateException("AES engine not initialised"); } if ((inOff + (32 / 2)) > in.length) { throw new DataLengthException("input buffer too short"); } if ((outOff + (32 / 2)) > out.length) { throw new OutputLengthException("output buffer too short"); } if (forEncryption) { unpackBlock(in, inOff); encryptBlock(WorkingKey); packBlock(out, outOff); } else { unpackBlock(in, inOff); decryptBlock(WorkingKey); packBlock(out, outOff); } return BLOCK_SIZE; } public void reset() { } private void unpackBlock( byte[] bytes, int off) { int index = off; C0 = (bytes[index++] & 0xff); C0 |= (bytes[index++] & 0xff) << 8; C0 |= (bytes[index++] & 0xff) << 16; C0 |= bytes[index++] << 24; C1 = (bytes[index++] & 0xff); C1 |= (bytes[index++] & 0xff) << 8; C1 |= (bytes[index++] & 0xff) << 16; C1 |= bytes[index++] << 24; C2 = (bytes[index++] & 0xff); C2 |= (bytes[index++] & 0xff) << 8; C2 |= (bytes[index++] & 0xff) << 16; C2 |= bytes[index++] << 24; C3 = (bytes[index++] & 0xff); C3 |= (bytes[index++] & 0xff) << 8; C3 |= (bytes[index++] & 0xff) << 16; C3 |= bytes[index++] << 24; } private void packBlock( byte[] bytes, int off) { int index = off; bytes[index++] = (byte)C0; bytes[index++] = (byte)(C0 >> 8); bytes[index++] = (byte)(C0 >> 16); bytes[index++] = (byte)(C0 >> 24); bytes[index++] = (byte)C1; bytes[index++] = (byte)(C1 >> 8); bytes[index++] = (byte)(C1 >> 16); bytes[index++] = (byte)(C1 >> 24); bytes[index++] = (byte)C2; bytes[index++] = (byte)(C2 >> 8); bytes[index++] = (byte)(C2 >> 16); bytes[index++] = (byte)(C2 >> 24); bytes[index++] = (byte)C3; bytes[index++] = (byte)(C3 >> 8); bytes[index++] = (byte)(C3 >> 16); bytes[index++] = (byte)(C3 >> 24); } private void encryptBlock(int[][] KW) { int r, r0, r1, r2, r3; C0 ^= KW[0][0]; C1 ^= KW[0][1]; C2 ^= KW[0][2]; C3 ^= KW[0][3]; for (r = 1; r < ROUNDS - 1;) { r0 = mcol((S[C0&255]&255) ^ ((S[(C1>>8)&255]&255)<<8) ^ ((S[(C2>>16)&255]&255)<<16) ^ (S[(C3>>24)&255]<<24)) ^ KW[r][0]; r1 = mcol((S[C1&255]&255) ^ ((S[(C2>>8)&255]&255)<<8) ^ ((S[(C3>>16)&255]&255)<<16) ^ (S[(C0>>24)&255]<<24)) ^ KW[r][1]; r2 = mcol((S[C2&255]&255) ^ ((S[(C3>>8)&255]&255)<<8) ^ ((S[(C0>>16)&255]&255)<<16) ^ (S[(C1>>24)&255]<<24)) ^ KW[r][2]; r3 = mcol((S[C3&255]&255) ^ ((S[(C0>>8)&255]&255)<<8) ^ ((S[(C1>>16)&255]&255)<<16) ^ (S[(C2>>24)&255]<<24)) ^ KW[r++][3]; C0 = mcol((S[r0&255]&255) ^ ((S[(r1>>8)&255]&255)<<8) ^ ((S[(r2>>16)&255]&255)<<16) ^ (S[(r3>>24)&255]<<24)) ^ KW[r][0]; C1 = mcol((S[r1&255]&255) ^ ((S[(r2>>8)&255]&255)<<8) ^ ((S[(r3>>16)&255]&255)<<16) ^ (S[(r0>>24)&255]<<24)) ^ KW[r][1]; C2 = mcol((S[r2&255]&255) ^ ((S[(r3>>8)&255]&255)<<8) ^ ((S[(r0>>16)&255]&255)<<16) ^ (S[(r1>>24)&255]<<24)) ^ KW[r][2]; C3 = mcol((S[r3&255]&255) ^ ((S[(r0>>8)&255]&255)<<8) ^ ((S[(r1>>16)&255]&255)<<16) ^ (S[(r2>>24)&255]<<24)) ^ KW[r++][3]; } r0 = mcol((S[C0&255]&255) ^ ((S[(C1>>8)&255]&255)<<8) ^ ((S[(C2>>16)&255]&255)<<16) ^ (S[(C3>>24)&255]<<24)) ^ KW[r][0]; r1 = mcol((S[C1&255]&255) ^ ((S[(C2>>8)&255]&255)<<8) ^ ((S[(C3>>16)&255]&255)<<16) ^ (S[(C0>>24)&255]<<24)) ^ KW[r][1]; r2 = mcol((S[C2&255]&255) ^ ((S[(C3>>8)&255]&255)<<8) ^ ((S[(C0>>16)&255]&255)<<16) ^ (S[(C1>>24)&255]<<24)) ^ KW[r][2]; r3 = mcol((S[C3&255]&255) ^ ((S[(C0>>8)&255]&255)<<8) ^ ((S[(C1>>16)&255]&255)<<16) ^ (S[(C2>>24)&255]<<24)) ^ KW[r++][3]; // the final round is a simple function of S C0 = (S[r0&255]&255) ^ ((S[(r1>>8)&255]&255)<<8) ^ ((S[(r2>>16)&255]&255)<<16) ^ (S[(r3>>24)&255]<<24) ^ KW[r][0]; C1 = (S[r1&255]&255) ^ ((S[(r2>>8)&255]&255)<<8) ^ ((S[(r3>>16)&255]&255)<<16) ^ (S[(r0>>24)&255]<<24) ^ KW[r][1]; C2 = (S[r2&255]&255) ^ ((S[(r3>>8)&255]&255)<<8) ^ ((S[(r0>>16)&255]&255)<<16) ^ (S[(r1>>24)&255]<<24) ^ KW[r][2]; C3 = (S[r3&255]&255) ^ ((S[(r0>>8)&255]&255)<<8) ^ ((S[(r1>>16)&255]&255)<<16) ^ (S[(r2>>24)&255]<<24) ^ KW[r][3]; } private void decryptBlock(int[][] KW) { int r, r0, r1, r2, r3; C0 ^= KW[ROUNDS][0]; C1 ^= KW[ROUNDS][1]; C2 ^= KW[ROUNDS][2]; C3 ^= KW[ROUNDS][3]; for (r = ROUNDS-1; r>1;) { r0 = inv_mcol((Si[C0&255]&255) ^ ((Si[(C3>>8)&255]&255)<<8) ^ ((Si[(C2>>16)&255]&255)<<16) ^ (Si[(C1>>24)&255]<<24)) ^ KW[r][0]; r1 = inv_mcol((Si[C1&255]&255) ^ ((Si[(C0>>8)&255]&255)<<8) ^ ((Si[(C3>>16)&255]&255)<<16) ^ (Si[(C2>>24)&255]<<24)) ^ KW[r][1]; r2 = inv_mcol((Si[C2&255]&255) ^ ((Si[(C1>>8)&255]&255)<<8) ^ ((Si[(C0>>16)&255]&255)<<16) ^ (Si[(C3>>24)&255]<<24)) ^ KW[r][2]; r3 = inv_mcol((Si[C3&255]&255) ^ ((Si[(C2>>8)&255]&255)<<8) ^ ((Si[(C1>>16)&255]&255)<<16) ^ (Si[(C0>>24)&255]<<24)) ^ KW[r--][3]; C0 = inv_mcol((Si[r0&255]&255) ^ ((Si[(r3>>8)&255]&255)<<8) ^ ((Si[(r2>>16)&255]&255)<<16) ^ (Si[(r1>>24)&255]<<24)) ^ KW[r][0]; C1 = inv_mcol((Si[r1&255]&255) ^ ((Si[(r0>>8)&255]&255)<<8) ^ ((Si[(r3>>16)&255]&255)<<16) ^ (Si[(r2>>24)&255]<<24)) ^ KW[r][1]; C2 = inv_mcol((Si[r2&255]&255) ^ ((Si[(r1>>8)&255]&255)<<8) ^ ((Si[(r0>>16)&255]&255)<<16) ^ (Si[(r3>>24)&255]<<24)) ^ KW[r][2]; C3 = inv_mcol((Si[r3&255]&255) ^ ((Si[(r2>>8)&255]&255)<<8) ^ ((Si[(r1>>16)&255]&255)<<16) ^ (Si[(r0>>24)&255]<<24)) ^ KW[r--][3]; } r0 = inv_mcol((Si[C0&255]&255) ^ ((Si[(C3>>8)&255]&255)<<8) ^ ((Si[(C2>>16)&255]&255)<<16) ^ (Si[(C1>>24)&255]<<24)) ^ KW[r][0]; r1 = inv_mcol((Si[C1&255]&255) ^ ((Si[(C0>>8)&255]&255)<<8) ^ ((Si[(C3>>16)&255]&255)<<16) ^ (Si[(C2>>24)&255]<<24)) ^ KW[r][1]; r2 = inv_mcol((Si[C2&255]&255) ^ ((Si[(C1>>8)&255]&255)<<8) ^ ((Si[(C0>>16)&255]&255)<<16) ^ (Si[(C3>>24)&255]<<24)) ^ KW[r][2]; r3 = inv_mcol((Si[C3&255]&255) ^ ((Si[(C2>>8)&255]&255)<<8) ^ ((Si[(C1>>16)&255]&255)<<16) ^ (Si[(C0>>24)&255]<<24)) ^ KW[r][3]; // the final round's table is a simple function of Si C0 = (Si[r0&255]&255) ^ ((Si[(r3>>8)&255]&255)<<8) ^ ((Si[(r2>>16)&255]&255)<<16) ^ (Si[(r1>>24)&255]<<24) ^ KW[0][0]; C1 = (Si[r1&255]&255) ^ ((Si[(r0>>8)&255]&255)<<8) ^ ((Si[(r3>>16)&255]&255)<<16) ^ (Si[(r2>>24)&255]<<24) ^ KW[0][1]; C2 = (Si[r2&255]&255) ^ ((Si[(r1>>8)&255]&255)<<8) ^ ((Si[(r0>>16)&255]&255)<<16) ^ (Si[(r3>>24)&255]<<24) ^ KW[0][2]; C3 = (Si[r3&255]&255) ^ ((Si[(r2>>8)&255]&255)<<8) ^ ((Si[(r1>>16)&255]&255)<<16) ^ (Si[(r0>>24)&255]<<24) ^ KW[0][3]; } } bouncycastle-1.49.orig/src/org/bouncycastle/crypto/engines/Salsa20Engine.java0000644000175000017500000002142512151251423026650 0ustar ebourgebourgpackage org.bouncycastle.crypto.engines; import org.bouncycastle.crypto.CipherParameters; import org.bouncycastle.crypto.DataLengthException; import org.bouncycastle.crypto.MaxBytesExceededException; import org.bouncycastle.crypto.OutputLengthException; import org.bouncycastle.crypto.StreamCipher; import org.bouncycastle.crypto.params.KeyParameter; import org.bouncycastle.crypto.params.ParametersWithIV; import org.bouncycastle.crypto.util.Pack; import org.bouncycastle.util.Strings; /** * Implementation of Daniel J. Bernstein's Salsa20 stream cipher, Snuffle 2005 */ public class Salsa20Engine implements StreamCipher { /** Constants */ private final static int STATE_SIZE = 16; // 16, 32 bit ints = 64 bytes private final static byte[] sigma = Strings.toByteArray("expand 32-byte k"), tau = Strings.toByteArray("expand 16-byte k"); /* * variables to hold the state of the engine * during encryption and decryption */ private int index = 0; private int[] engineState = new int[STATE_SIZE]; // state private int[] x = new int[STATE_SIZE] ; // internal buffer private byte[] keyStream = new byte[STATE_SIZE * 4], // expanded state, 64 bytes workingKey = null, workingIV = null; private boolean initialised = false; /* * internal counter */ private int cW0, cW1, cW2; /** * initialise a Salsa20 cipher. * * @param forEncryption whether or not we are for encryption. * @param params the parameters required to set up the cipher. * @exception IllegalArgumentException if the params argument is * inappropriate. */ public void init( boolean forEncryption, CipherParameters params) { /* * Salsa20 encryption and decryption is completely * symmetrical, so the 'forEncryption' is * irrelevant. (Like 90% of stream ciphers) */ if (!(params instanceof ParametersWithIV)) { throw new IllegalArgumentException("Salsa20 Init parameters must include an IV"); } ParametersWithIV ivParams = (ParametersWithIV) params; byte[] iv = ivParams.getIV(); if (iv == null || iv.length != 8) { throw new IllegalArgumentException("Salsa20 requires exactly 8 bytes of IV"); } if (!(ivParams.getParameters() instanceof KeyParameter)) { throw new IllegalArgumentException("Salsa20 Init parameters must include a key"); } KeyParameter key = (KeyParameter) ivParams.getParameters(); workingKey = key.getKey(); workingIV = iv; setKey(workingKey, workingIV); } public String getAlgorithmName() { return "Salsa20"; } public byte returnByte(byte in) { if (limitExceeded()) { throw new MaxBytesExceededException("2^70 byte limit per IV; Change IV"); } if (index == 0) { generateKeyStream(keyStream); if (++engineState[8] == 0) { ++engineState[9]; } } byte out = (byte)(keyStream[index]^in); index = (index + 1) & 63; return out; } public void processBytes( byte[] in, int inOff, int len, byte[] out, int outOff) { if (!initialised) { throw new IllegalStateException(getAlgorithmName()+" not initialised"); } if ((inOff + len) > in.length) { throw new DataLengthException("input buffer too short"); } if ((outOff + len) > out.length) { throw new OutputLengthException("output buffer too short"); } if (limitExceeded(len)) { throw new MaxBytesExceededException("2^70 byte limit per IV would be exceeded; Change IV"); } for (int i = 0; i < len; i++) { if (index == 0) { generateKeyStream(keyStream); if (++engineState[8] == 0) { ++engineState[9]; } } out[i+outOff] = (byte)(keyStream[index]^in[i+inOff]); index = (index + 1) & 63; } } public void reset() { setKey(workingKey, workingIV); } // Private implementation private void setKey(byte[] keyBytes, byte[] ivBytes) { workingKey = keyBytes; workingIV = ivBytes; index = 0; resetCounter(); int offset = 0; byte[] constants; // Key engineState[1] = Pack.littleEndianToInt(workingKey, 0); engineState[2] = Pack.littleEndianToInt(workingKey, 4); engineState[3] = Pack.littleEndianToInt(workingKey, 8); engineState[4] = Pack.littleEndianToInt(workingKey, 12); if (workingKey.length == 32) { constants = sigma; offset = 16; } else { constants = tau; } engineState[11] = Pack.littleEndianToInt(workingKey, offset); engineState[12] = Pack.littleEndianToInt(workingKey, offset+4); engineState[13] = Pack.littleEndianToInt(workingKey, offset+8); engineState[14] = Pack.littleEndianToInt(workingKey, offset+12); engineState[0 ] = Pack.littleEndianToInt(constants, 0); engineState[5 ] = Pack.littleEndianToInt(constants, 4); engineState[10] = Pack.littleEndianToInt(constants, 8); engineState[15] = Pack.littleEndianToInt(constants, 12); // IV engineState[6] = Pack.littleEndianToInt(workingIV, 0); engineState[7] = Pack.littleEndianToInt(workingIV, 4); engineState[8] = engineState[9] = 0; initialised = true; } private void generateKeyStream(byte[] output) { salsaCore(20, engineState, x); Pack.intToLittleEndian(x, output, 0); } /** * Salsa20 function * * @param input input data * * @return keystream */ public static void salsaCore(int rounds, int[] input, int[] x) { // TODO Exception if rounds odd? System.arraycopy(input, 0, x, 0, input.length); for (int i = rounds; i > 0; i -= 2) { x[ 4] ^= rotl((x[ 0]+x[12]), 7); x[ 8] ^= rotl((x[ 4]+x[ 0]), 9); x[12] ^= rotl((x[ 8]+x[ 4]),13); x[ 0] ^= rotl((x[12]+x[ 8]),18); x[ 9] ^= rotl((x[ 5]+x[ 1]), 7); x[13] ^= rotl((x[ 9]+x[ 5]), 9); x[ 1] ^= rotl((x[13]+x[ 9]),13); x[ 5] ^= rotl((x[ 1]+x[13]),18); x[14] ^= rotl((x[10]+x[ 6]), 7); x[ 2] ^= rotl((x[14]+x[10]), 9); x[ 6] ^= rotl((x[ 2]+x[14]),13); x[10] ^= rotl((x[ 6]+x[ 2]),18); x[ 3] ^= rotl((x[15]+x[11]), 7); x[ 7] ^= rotl((x[ 3]+x[15]), 9); x[11] ^= rotl((x[ 7]+x[ 3]),13); x[15] ^= rotl((x[11]+x[ 7]),18); x[ 1] ^= rotl((x[ 0]+x[ 3]), 7); x[ 2] ^= rotl((x[ 1]+x[ 0]), 9); x[ 3] ^= rotl((x[ 2]+x[ 1]),13); x[ 0] ^= rotl((x[ 3]+x[ 2]),18); x[ 6] ^= rotl((x[ 5]+x[ 4]), 7); x[ 7] ^= rotl((x[ 6]+x[ 5]), 9); x[ 4] ^= rotl((x[ 7]+x[ 6]),13); x[ 5] ^= rotl((x[ 4]+x[ 7]),18); x[11] ^= rotl((x[10]+x[ 9]), 7); x[ 8] ^= rotl((x[11]+x[10]), 9); x[ 9] ^= rotl((x[ 8]+x[11]),13); x[10] ^= rotl((x[ 9]+x[ 8]),18); x[12] ^= rotl((x[15]+x[14]), 7); x[13] ^= rotl((x[12]+x[15]), 9); x[14] ^= rotl((x[13]+x[12]),13); x[15] ^= rotl((x[14]+x[13]),18); } for (int i = 0; i < STATE_SIZE; ++i) { x[i] += input[i]; } } /** * Rotate left * * @param x value to rotate * @param y amount to rotate x * * @return rotated x */ private static int rotl(int x, int y) { return (x << y) | (x >>> -y); } private void resetCounter() { cW0 = 0; cW1 = 0; cW2 = 0; } private boolean limitExceeded() { if (++cW0 == 0) { if (++cW1 == 0) { return (++cW2 & 0x20) != 0; // 2^(32 + 32 + 6) } } return false; } /* * this relies on the fact len will always be positive. */ private boolean limitExceeded(int len) { cW0 += len; if (cW0 < len && cW0 >= 0) { if (++cW1 == 0) { return (++cW2 & 0x20) != 0; // 2^(32 + 32 + 6) } } return false; } } bouncycastle-1.49.orig/src/org/bouncycastle/crypto/engines/DESedeWrapEngine.java0000644000175000017500000002513711321472114027372 0ustar ebourgebourgpackage org.bouncycastle.crypto.engines; import java.security.SecureRandom; import org.bouncycastle.crypto.CipherParameters; import org.bouncycastle.crypto.Digest; import org.bouncycastle.crypto.InvalidCipherTextException; import org.bouncycastle.crypto.Wrapper; import org.bouncycastle.crypto.digests.SHA1Digest; import org.bouncycastle.crypto.modes.CBCBlockCipher; import org.bouncycastle.crypto.params.KeyParameter; import org.bouncycastle.crypto.params.ParametersWithIV; import org.bouncycastle.crypto.params.ParametersWithRandom; import org.bouncycastle.util.Arrays; /** * Wrap keys according to * * draft-ietf-smime-key-wrap-01.txt. *

    * Note: *

      *
    • this is based on a draft, and as such is subject to change - don't use this class for anything requiring long term storage. *
    • if you are using this to wrap triple-des keys you need to set the * parity bits on the key and, if it's a two-key triple-des key, pad it * yourself. *
    */ public class DESedeWrapEngine implements Wrapper { /** Field engine */ private CBCBlockCipher engine; /** Field param */ private KeyParameter param; /** Field paramPlusIV */ private ParametersWithIV paramPlusIV; /** Field iv */ private byte[] iv; /** Field forWrapping */ private boolean forWrapping; /** Field IV2 */ private static final byte[] IV2 = { (byte) 0x4a, (byte) 0xdd, (byte) 0xa2, (byte) 0x2c, (byte) 0x79, (byte) 0xe8, (byte) 0x21, (byte) 0x05 }; // // checksum digest // Digest sha1 = new SHA1Digest(); byte[] digest = new byte[20]; /** * Method init * * @param forWrapping * @param param */ public void init(boolean forWrapping, CipherParameters param) { this.forWrapping = forWrapping; this.engine = new CBCBlockCipher(new DESedeEngine()); SecureRandom sr; if (param instanceof ParametersWithRandom) { ParametersWithRandom pr = (ParametersWithRandom) param; param = pr.getParameters(); sr = pr.getRandom(); } else { sr = new SecureRandom(); } if (param instanceof KeyParameter) { this.param = (KeyParameter)param; if (this.forWrapping) { // Hm, we have no IV but we want to wrap ?!? // well, then we have to create our own IV. this.iv = new byte[8]; sr.nextBytes(iv); this.paramPlusIV = new ParametersWithIV(this.param, this.iv); } } else if (param instanceof ParametersWithIV) { this.paramPlusIV = (ParametersWithIV)param; this.iv = this.paramPlusIV.getIV(); this.param = (KeyParameter)this.paramPlusIV.getParameters(); if (this.forWrapping) { if ((this.iv == null) || (this.iv.length != 8)) { throw new IllegalArgumentException("IV is not 8 octets"); } } else { throw new IllegalArgumentException( "You should not supply an IV for unwrapping"); } } } /** * Method getAlgorithmName * * @return the algorithm name "DESede". */ public String getAlgorithmName() { return "DESede"; } /** * Method wrap * * @param in * @param inOff * @param inLen * @return the wrapped bytes. */ public byte[] wrap(byte[] in, int inOff, int inLen) { if (!forWrapping) { throw new IllegalStateException("Not initialized for wrapping"); } byte keyToBeWrapped[] = new byte[inLen]; System.arraycopy(in, inOff, keyToBeWrapped, 0, inLen); // Compute the CMS Key Checksum, (section 5.6.1), call this CKS. byte[] CKS = calculateCMSKeyChecksum(keyToBeWrapped); // Let WKCKS = WK || CKS where || is concatenation. byte[] WKCKS = new byte[keyToBeWrapped.length + CKS.length]; System.arraycopy(keyToBeWrapped, 0, WKCKS, 0, keyToBeWrapped.length); System.arraycopy(CKS, 0, WKCKS, keyToBeWrapped.length, CKS.length); // Encrypt WKCKS in CBC mode using KEK as the key and IV as the // initialization vector. Call the results TEMP1. int blockSize = engine.getBlockSize(); if (WKCKS.length % blockSize != 0) { throw new IllegalStateException("Not multiple of block length"); } engine.init(true, paramPlusIV); byte TEMP1[] = new byte[WKCKS.length]; for (int currentBytePos = 0; currentBytePos != WKCKS.length; currentBytePos += blockSize) { engine.processBlock(WKCKS, currentBytePos, TEMP1, currentBytePos); } // Let TEMP2 = IV || TEMP1. byte[] TEMP2 = new byte[this.iv.length + TEMP1.length]; System.arraycopy(this.iv, 0, TEMP2, 0, this.iv.length); System.arraycopy(TEMP1, 0, TEMP2, this.iv.length, TEMP1.length); // Reverse the order of the octets in TEMP2 and call the result TEMP3. byte[] TEMP3 = reverse(TEMP2); // Encrypt TEMP3 in CBC mode using the KEK and an initialization vector // of 0x 4a dd a2 2c 79 e8 21 05. The resulting cipher text is the desired // result. It is 40 octets long if a 168 bit key is being wrapped. ParametersWithIV param2 = new ParametersWithIV(this.param, IV2); this.engine.init(true, param2); for (int currentBytePos = 0; currentBytePos != TEMP3.length; currentBytePos += blockSize) { engine.processBlock(TEMP3, currentBytePos, TEMP3, currentBytePos); } return TEMP3; } /** * Method unwrap * * @param in * @param inOff * @param inLen * @return the unwrapped bytes. * @throws InvalidCipherTextException */ public byte[] unwrap(byte[] in, int inOff, int inLen) throws InvalidCipherTextException { if (forWrapping) { throw new IllegalStateException("Not set for unwrapping"); } if (in == null) { throw new InvalidCipherTextException("Null pointer as ciphertext"); } final int blockSize = engine.getBlockSize(); if (inLen % blockSize != 0) { throw new InvalidCipherTextException("Ciphertext not multiple of " + blockSize); } /* // Check if the length of the cipher text is reasonable given the key // type. It must be 40 bytes for a 168 bit key and either 32, 40, or // 48 bytes for a 128, 192, or 256 bit key. If the length is not supported // or inconsistent with the algorithm for which the key is intended, // return error. // // we do not accept 168 bit keys. it has to be 192 bit. int lengthA = (estimatedKeyLengthInBit / 8) + 16; int lengthB = estimatedKeyLengthInBit % 8; if ((lengthA != keyToBeUnwrapped.length) || (lengthB != 0)) { throw new XMLSecurityException("empty"); } */ // Decrypt the cipher text with TRIPLedeS in CBC mode using the KEK // and an initialization vector (IV) of 0x4adda22c79e82105. Call the output TEMP3. ParametersWithIV param2 = new ParametersWithIV(this.param, IV2); this.engine.init(false, param2); byte TEMP3[] = new byte[inLen]; for (int currentBytePos = 0; currentBytePos != inLen; currentBytePos += blockSize) { engine.processBlock(in, inOff + currentBytePos, TEMP3, currentBytePos); } // Reverse the order of the octets in TEMP3 and call the result TEMP2. byte[] TEMP2 = reverse(TEMP3); // Decompose TEMP2 into IV, the first 8 octets, and TEMP1, the remaining octets. this.iv = new byte[8]; byte[] TEMP1 = new byte[TEMP2.length - 8]; System.arraycopy(TEMP2, 0, this.iv, 0, 8); System.arraycopy(TEMP2, 8, TEMP1, 0, TEMP2.length - 8); // Decrypt TEMP1 using TRIPLedeS in CBC mode using the KEK and the IV // found in the previous step. Call the result WKCKS. this.paramPlusIV = new ParametersWithIV(this.param, this.iv); this.engine.init(false, this.paramPlusIV); byte[] WKCKS = new byte[TEMP1.length]; for (int currentBytePos = 0; currentBytePos != WKCKS.length; currentBytePos += blockSize) { engine.processBlock(TEMP1, currentBytePos, WKCKS, currentBytePos); } // Decompose WKCKS. CKS is the last 8 octets and WK, the wrapped key, are // those octets before the CKS. byte[] result = new byte[WKCKS.length - 8]; byte[] CKStoBeVerified = new byte[8]; System.arraycopy(WKCKS, 0, result, 0, WKCKS.length - 8); System.arraycopy(WKCKS, WKCKS.length - 8, CKStoBeVerified, 0, 8); // Calculate a CMS Key Checksum, (section 5.6.1), over the WK and compare // with the CKS extracted in the above step. If they are not equal, return error. if (!checkCMSKeyChecksum(result, CKStoBeVerified)) { throw new InvalidCipherTextException( "Checksum inside ciphertext is corrupted"); } // WK is the wrapped key, now extracted for use in data decryption. return result; } /** * Some key wrap algorithms make use of the Key Checksum defined * in CMS [CMS-Algorithms]. This is used to provide an integrity * check value for the key being wrapped. The algorithm is * * - Compute the 20 octet SHA-1 hash on the key being wrapped. * - Use the first 8 octets of this hash as the checksum value. * * @param key * @return the CMS checksum. * @throws RuntimeException * @see http://www.w3.org/TR/xmlenc-core/#sec-CMSKeyChecksum */ private byte[] calculateCMSKeyChecksum( byte[] key) { byte[] result = new byte[8]; sha1.update(key, 0, key.length); sha1.doFinal(digest, 0); System.arraycopy(digest, 0, result, 0, 8); return result; } /** * @param key * @param checksum * @return true if okay, false otherwise. * @see http://www.w3.org/TR/xmlenc-core/#sec-CMSKeyChecksum */ private boolean checkCMSKeyChecksum( byte[] key, byte[] checksum) { return Arrays.constantTimeAreEqual(calculateCMSKeyChecksum(key), checksum); } private static byte[] reverse(byte[] bs) { byte[] result = new byte[bs.length]; for (int i = 0; i < bs.length; i++) { result[i] = bs[bs.length - (i + 1)]; } return result; } } bouncycastle-1.49.orig/src/org/bouncycastle/crypto/engines/HC256Engine.java0000644000175000017500000001456612106330250026176 0ustar ebourgebourgpackage org.bouncycastle.crypto.engines; import org.bouncycastle.crypto.CipherParameters; import org.bouncycastle.crypto.DataLengthException; import org.bouncycastle.crypto.OutputLengthException; import org.bouncycastle.crypto.StreamCipher; import org.bouncycastle.crypto.params.KeyParameter; import org.bouncycastle.crypto.params.ParametersWithIV; /** * HC-256 is a software-efficient stream cipher created by Hongjun Wu. It * generates keystream from a 256-bit secret key and a 256-bit initialization * vector. *

    * http://www.ecrypt.eu.org/stream/p3ciphers/hc/hc256_p3.pdf *

    * Its brother, HC-128, is a third phase candidate in the eStream contest. * The algorithm is patent-free. No attacks are known as of today (April 2007). * See * * http://www.ecrypt.eu.org/stream/hcp3.html *

    */ public class HC256Engine implements StreamCipher { private int[] p = new int[1024]; private int[] q = new int[1024]; private int cnt = 0; private int step() { int j = cnt & 0x3FF; int ret; if (cnt < 1024) { int x = p[(j - 3 & 0x3FF)]; int y = p[(j - 1023 & 0x3FF)]; p[j] += p[(j - 10 & 0x3FF)] + (rotateRight(x, 10) ^ rotateRight(y, 23)) + q[((x ^ y) & 0x3FF)]; x = p[(j - 12 & 0x3FF)]; ret = (q[x & 0xFF] + q[((x >> 8) & 0xFF) + 256] + q[((x >> 16) & 0xFF) + 512] + q[((x >> 24) & 0xFF) + 768]) ^ p[j]; } else { int x = q[(j - 3 & 0x3FF)]; int y = q[(j - 1023 & 0x3FF)]; q[j] += q[(j - 10 & 0x3FF)] + (rotateRight(x, 10) ^ rotateRight(y, 23)) + p[((x ^ y) & 0x3FF)]; x = q[(j - 12 & 0x3FF)]; ret = (p[x & 0xFF] + p[((x >> 8) & 0xFF) + 256] + p[((x >> 16) & 0xFF) + 512] + p[((x >> 24) & 0xFF) + 768]) ^ q[j]; } cnt = cnt + 1 & 0x7FF; return ret; } private byte[] key, iv; private boolean initialised; private void init() { if (key.length != 32 && key.length != 16) { throw new IllegalArgumentException( "The key must be 128/256 bits long"); } if (iv.length < 16) { throw new IllegalArgumentException( "The IV must be at least 128 bits long"); } if (key.length != 32) { byte[] k = new byte[32]; System.arraycopy(key, 0, k, 0, key.length); System.arraycopy(key, 0, k, 16, key.length); key = k; } if (iv.length < 32) { byte[] newIV = new byte[32]; System.arraycopy(iv, 0, newIV, 0, iv.length); System.arraycopy(iv, 0, newIV, iv.length, newIV.length - iv.length); iv = newIV; } cnt = 0; int[] w = new int[2560]; for (int i = 0; i < 32; i++) { w[i >> 2] |= (key[i] & 0xff) << (8 * (i & 0x3)); } for (int i = 0; i < 32; i++) { w[(i >> 2) + 8] |= (iv[i] & 0xff) << (8 * (i & 0x3)); } for (int i = 16; i < 2560; i++) { int x = w[i - 2]; int y = w[i - 15]; w[i] = (rotateRight(x, 17) ^ rotateRight(x, 19) ^ (x >>> 10)) + w[i - 7] + (rotateRight(y, 7) ^ rotateRight(y, 18) ^ (y >>> 3)) + w[i - 16] + i; } System.arraycopy(w, 512, p, 0, 1024); System.arraycopy(w, 1536, q, 0, 1024); for (int i = 0; i < 4096; i++) { step(); } cnt = 0; } public String getAlgorithmName() { return "HC-256"; } /** * Initialise a HC-256 cipher. * * @param forEncryption whether or not we are for encryption. Irrelevant, as * encryption and decryption are the same. * @param params the parameters required to set up the cipher. * @throws IllegalArgumentException if the params argument is * inappropriate (ie. the key is not 256 bit long). */ public void init(boolean forEncryption, CipherParameters params) throws IllegalArgumentException { CipherParameters keyParam = params; if (params instanceof ParametersWithIV) { iv = ((ParametersWithIV)params).getIV(); keyParam = ((ParametersWithIV)params).getParameters(); } else { iv = new byte[0]; } if (keyParam instanceof KeyParameter) { key = ((KeyParameter)keyParam).getKey(); init(); } else { throw new IllegalArgumentException( "Invalid parameter passed to HC256 init - " + params.getClass().getName()); } initialised = true; } private byte[] buf = new byte[4]; private int idx = 0; private byte getByte() { if (idx == 0) { int step = step(); buf[0] = (byte)(step & 0xFF); step >>= 8; buf[1] = (byte)(step & 0xFF); step >>= 8; buf[2] = (byte)(step & 0xFF); step >>= 8; buf[3] = (byte)(step & 0xFF); } byte ret = buf[idx]; idx = idx + 1 & 0x3; return ret; } public void processBytes(byte[] in, int inOff, int len, byte[] out, int outOff) throws DataLengthException { if (!initialised) { throw new IllegalStateException(getAlgorithmName() + " not initialised"); } if ((inOff + len) > in.length) { throw new DataLengthException("input buffer too short"); } if ((outOff + len) > out.length) { throw new OutputLengthException("output buffer too short"); } for (int i = 0; i < len; i++) { out[outOff + i] = (byte)(in[inOff + i] ^ getByte()); } } public void reset() { idx = 0; init(); } public byte returnByte(byte in) { return (byte)(in ^ getByte()); } private static int rotateRight( int x, int bits) { return (x >>> bits) | (x << -bits); } } bouncycastle-1.49.orig/src/org/bouncycastle/crypto/engines/SEEDWrapEngine.java0000644000175000017500000000057410564225562027032 0ustar ebourgebourgpackage org.bouncycastle.crypto.engines; /** * An implementation of the SEED key wrapper based on RFC 4010/RFC 3394. *

    * For further details see: http://www.ietf.org/rfc/rfc4010.txt. */ public class SEEDWrapEngine extends RFC3394WrapEngine { public SEEDWrapEngine() { super(new SEEDEngine()); } } bouncycastle-1.49.orig/src/org/bouncycastle/crypto/engines/Grain128Engine.java0000644000175000017500000002111012106330250026721 0ustar ebourgebourgpackage org.bouncycastle.crypto.engines; import org.bouncycastle.crypto.CipherParameters; import org.bouncycastle.crypto.DataLengthException; import org.bouncycastle.crypto.OutputLengthException; import org.bouncycastle.crypto.StreamCipher; import org.bouncycastle.crypto.params.KeyParameter; import org.bouncycastle.crypto.params.ParametersWithIV; /** * Implementation of Martin Hell's, Thomas Johansson's and Willi Meier's stream * cipher, Grain-128. */ public class Grain128Engine implements StreamCipher { /** * Constants */ private static final int STATE_SIZE = 4; /** * Variables to hold the state of the engine during encryption and * decryption */ private byte[] workingKey; private byte[] workingIV; private byte[] out; private int[] lfsr; private int[] nfsr; private int output; private int index = 4; private boolean initialised = false; public String getAlgorithmName() { return "Grain-128"; } /** * Initialize a Grain-128 cipher. * * @param forEncryption Whether or not we are for encryption. * @param params The parameters required to set up the cipher. * @throws IllegalArgumentException If the params argument is inappropriate. */ public void init(boolean forEncryption, CipherParameters params) throws IllegalArgumentException { /** * Grain encryption and decryption is completely symmetrical, so the * 'forEncryption' is irrelevant. */ if (!(params instanceof ParametersWithIV)) { throw new IllegalArgumentException( "Grain-128 Init parameters must include an IV"); } ParametersWithIV ivParams = (ParametersWithIV)params; byte[] iv = ivParams.getIV(); if (iv == null || iv.length != 12) { throw new IllegalArgumentException( "Grain-128 requires exactly 12 bytes of IV"); } if (!(ivParams.getParameters() instanceof KeyParameter)) { throw new IllegalArgumentException( "Grain-128 Init parameters must include a key"); } KeyParameter key = (KeyParameter)ivParams.getParameters(); /** * Initialize variables. */ workingIV = new byte[key.getKey().length]; workingKey = new byte[key.getKey().length]; lfsr = new int[STATE_SIZE]; nfsr = new int[STATE_SIZE]; out = new byte[4]; System.arraycopy(iv, 0, workingIV, 0, iv.length); System.arraycopy(key.getKey(), 0, workingKey, 0, key.getKey().length); setKey(workingKey, workingIV); initGrain(); } /** * 256 clocks initialization phase. */ private void initGrain() { for (int i = 0; i < 8; i++) { output = getOutput(); nfsr = shift(nfsr, getOutputNFSR() ^ lfsr[0] ^ output); lfsr = shift(lfsr, getOutputLFSR() ^ output); } initialised = true; } /** * Get output from non-linear function g(x). * * @return Output from NFSR. */ private int getOutputNFSR() { int b0 = nfsr[0]; int b3 = nfsr[0] >>> 3 | nfsr[1] << 29; int b11 = nfsr[0] >>> 11 | nfsr[1] << 21; int b13 = nfsr[0] >>> 13 | nfsr[1] << 19; int b17 = nfsr[0] >>> 17 | nfsr[1] << 15; int b18 = nfsr[0] >>> 18 | nfsr[1] << 14; int b26 = nfsr[0] >>> 26 | nfsr[1] << 6; int b27 = nfsr[0] >>> 27 | nfsr[1] << 5; int b40 = nfsr[1] >>> 8 | nfsr[2] << 24; int b48 = nfsr[1] >>> 16 | nfsr[2] << 16; int b56 = nfsr[1] >>> 24 | nfsr[2] << 8; int b59 = nfsr[1] >>> 27 | nfsr[2] << 5; int b61 = nfsr[1] >>> 29 | nfsr[2] << 3; int b65 = nfsr[2] >>> 1 | nfsr[3] << 31; int b67 = nfsr[2] >>> 3 | nfsr[3] << 29; int b68 = nfsr[2] >>> 4 | nfsr[3] << 28; int b84 = nfsr[2] >>> 20 | nfsr[3] << 12; int b91 = nfsr[2] >>> 27 | nfsr[3] << 5; int b96 = nfsr[3]; return b0 ^ b26 ^ b56 ^ b91 ^ b96 ^ b3 & b67 ^ b11 & b13 ^ b17 & b18 ^ b27 & b59 ^ b40 & b48 ^ b61 & b65 ^ b68 & b84; } /** * Get output from linear function f(x). * * @return Output from LFSR. */ private int getOutputLFSR() { int s0 = lfsr[0]; int s7 = lfsr[0] >>> 7 | lfsr[1] << 25; int s38 = lfsr[1] >>> 6 | lfsr[2] << 26; int s70 = lfsr[2] >>> 6 | lfsr[3] << 26; int s81 = lfsr[2] >>> 17 | lfsr[3] << 15; int s96 = lfsr[3]; return s0 ^ s7 ^ s38 ^ s70 ^ s81 ^ s96; } /** * Get output from output function h(x). * * @return Output from h(x). */ private int getOutput() { int b2 = nfsr[0] >>> 2 | nfsr[1] << 30; int b12 = nfsr[0] >>> 12 | nfsr[1] << 20; int b15 = nfsr[0] >>> 15 | nfsr[1] << 17; int b36 = nfsr[1] >>> 4 | nfsr[2] << 28; int b45 = nfsr[1] >>> 13 | nfsr[2] << 19; int b64 = nfsr[2]; int b73 = nfsr[2] >>> 9 | nfsr[3] << 23; int b89 = nfsr[2] >>> 25 | nfsr[3] << 7; int b95 = nfsr[2] >>> 31 | nfsr[3] << 1; int s8 = lfsr[0] >>> 8 | lfsr[1] << 24; int s13 = lfsr[0] >>> 13 | lfsr[1] << 19; int s20 = lfsr[0] >>> 20 | lfsr[1] << 12; int s42 = lfsr[1] >>> 10 | lfsr[2] << 22; int s60 = lfsr[1] >>> 28 | lfsr[2] << 4; int s79 = lfsr[2] >>> 15 | lfsr[3] << 17; int s93 = lfsr[2] >>> 29 | lfsr[3] << 3; int s95 = lfsr[2] >>> 31 | lfsr[3] << 1; return b12 & s8 ^ s13 & s20 ^ b95 & s42 ^ s60 & s79 ^ b12 & b95 & s95 ^ s93 ^ b2 ^ b15 ^ b36 ^ b45 ^ b64 ^ b73 ^ b89; } /** * Shift array 32 bits and add val to index.length - 1. * * @param array The array to shift. * @param val The value to shift in. * @return The shifted array with val added to index.length - 1. */ private int[] shift(int[] array, int val) { array[0] = array[1]; array[1] = array[2]; array[2] = array[3]; array[3] = val; return array; } /** * Set keys, reset cipher. * * @param keyBytes The key. * @param ivBytes The IV. */ private void setKey(byte[] keyBytes, byte[] ivBytes) { ivBytes[12] = (byte)0xFF; ivBytes[13] = (byte)0xFF; ivBytes[14] = (byte)0xFF; ivBytes[15] = (byte)0xFF; workingKey = keyBytes; workingIV = ivBytes; /** * Load NFSR and LFSR */ int j = 0; for (int i = 0; i < nfsr.length; i++) { nfsr[i] = ((workingKey[j + 3]) << 24) | ((workingKey[j + 2]) << 16) & 0x00FF0000 | ((workingKey[j + 1]) << 8) & 0x0000FF00 | ((workingKey[j]) & 0x000000FF); lfsr[i] = ((workingIV[j + 3]) << 24) | ((workingIV[j + 2]) << 16) & 0x00FF0000 | ((workingIV[j + 1]) << 8) & 0x0000FF00 | ((workingIV[j]) & 0x000000FF); j += 4; } } public void processBytes(byte[] in, int inOff, int len, byte[] out, int outOff) throws DataLengthException { if (!initialised) { throw new IllegalStateException(getAlgorithmName() + " not initialised"); } if ((inOff + len) > in.length) { throw new DataLengthException("input buffer too short"); } if ((outOff + len) > out.length) { throw new OutputLengthException("output buffer too short"); } for (int i = 0; i < len; i++) { out[outOff + i] = (byte)(in[inOff + i] ^ getKeyStream()); } } public void reset() { index = 4; setKey(workingKey, workingIV); initGrain(); } /** * Run Grain one round(i.e. 32 bits). */ private void oneRound() { output = getOutput(); out[0] = (byte)output; out[1] = (byte)(output >> 8); out[2] = (byte)(output >> 16); out[3] = (byte)(output >> 24); nfsr = shift(nfsr, getOutputNFSR() ^ lfsr[0]); lfsr = shift(lfsr, getOutputLFSR()); } public byte returnByte(byte in) { if (!initialised) { throw new IllegalStateException(getAlgorithmName() + " not initialised"); } return (byte)(in ^ getKeyStream()); } private byte getKeyStream() { if (index > 3) { oneRound(); index = 0; } return out[index++]; } } bouncycastle-1.49.orig/src/org/bouncycastle/crypto/engines/RSACoreEngine.java0000644000175000017500000001276010554246700026712 0ustar ebourgebourgpackage org.bouncycastle.crypto.engines; import org.bouncycastle.crypto.CipherParameters; import org.bouncycastle.crypto.DataLengthException; import org.bouncycastle.crypto.params.ParametersWithRandom; import org.bouncycastle.crypto.params.RSAKeyParameters; import org.bouncycastle.crypto.params.RSAPrivateCrtKeyParameters; import java.math.BigInteger; /** * this does your basic RSA algorithm. */ class RSACoreEngine { private RSAKeyParameters key; private boolean forEncryption; /** * initialise the RSA engine. * * @param forEncryption true if we are encrypting, false otherwise. * @param param the necessary RSA key parameters. */ public void init( boolean forEncryption, CipherParameters param) { if (param instanceof ParametersWithRandom) { ParametersWithRandom rParam = (ParametersWithRandom)param; key = (RSAKeyParameters)rParam.getParameters(); } else { key = (RSAKeyParameters)param; } this.forEncryption = forEncryption; } /** * Return the maximum size for an input block to this engine. * For RSA this is always one byte less than the key size on * encryption, and the same length as the key size on decryption. * * @return maximum size for an input block. */ public int getInputBlockSize() { int bitSize = key.getModulus().bitLength(); if (forEncryption) { return (bitSize + 7) / 8 - 1; } else { return (bitSize + 7) / 8; } } /** * Return the maximum size for an output block to this engine. * For RSA this is always one byte less than the key size on * decryption, and the same length as the key size on encryption. * * @return maximum size for an output block. */ public int getOutputBlockSize() { int bitSize = key.getModulus().bitLength(); if (forEncryption) { return (bitSize + 7) / 8; } else { return (bitSize + 7) / 8 - 1; } } public BigInteger convertInput( byte[] in, int inOff, int inLen) { if (inLen > (getInputBlockSize() + 1)) { throw new DataLengthException("input too large for RSA cipher."); } else if (inLen == (getInputBlockSize() + 1) && !forEncryption) { throw new DataLengthException("input too large for RSA cipher."); } byte[] block; if (inOff != 0 || inLen != in.length) { block = new byte[inLen]; System.arraycopy(in, inOff, block, 0, inLen); } else { block = in; } BigInteger res = new BigInteger(1, block); if (res.compareTo(key.getModulus()) >= 0) { throw new DataLengthException("input too large for RSA cipher."); } return res; } public byte[] convertOutput( BigInteger result) { byte[] output = result.toByteArray(); if (forEncryption) { if (output[0] == 0 && output.length > getOutputBlockSize()) // have ended up with an extra zero byte, copy down. { byte[] tmp = new byte[output.length - 1]; System.arraycopy(output, 1, tmp, 0, tmp.length); return tmp; } if (output.length < getOutputBlockSize()) // have ended up with less bytes than normal, lengthen { byte[] tmp = new byte[getOutputBlockSize()]; System.arraycopy(output, 0, tmp, tmp.length - output.length, output.length); return tmp; } } else { if (output[0] == 0) // have ended up with an extra zero byte, copy down. { byte[] tmp = new byte[output.length - 1]; System.arraycopy(output, 1, tmp, 0, tmp.length); return tmp; } } return output; } public BigInteger processBlock(BigInteger input) { if (key instanceof RSAPrivateCrtKeyParameters) { // // we have the extra factors, use the Chinese Remainder Theorem - the author // wishes to express his thanks to Dirk Bonekaemper at rtsffm.com for // advice regarding the expression of this. // RSAPrivateCrtKeyParameters crtKey = (RSAPrivateCrtKeyParameters)key; BigInteger p = crtKey.getP(); BigInteger q = crtKey.getQ(); BigInteger dP = crtKey.getDP(); BigInteger dQ = crtKey.getDQ(); BigInteger qInv = crtKey.getQInv(); BigInteger mP, mQ, h, m; // mP = ((input mod p) ^ dP)) mod p mP = (input.remainder(p)).modPow(dP, p); // mQ = ((input mod q) ^ dQ)) mod q mQ = (input.remainder(q)).modPow(dQ, q); // h = qInv * (mP - mQ) mod p h = mP.subtract(mQ); h = h.multiply(qInv); h = h.mod(p); // mod (in Java) returns the positive residual // m = h * q + mQ m = h.multiply(q); m = m.add(mQ); return m; } else { return input.modPow( key.getExponent(), key.getModulus()); } } } bouncycastle-1.49.orig/src/org/bouncycastle/crypto/engines/ISAACEngine.java0000644000175000017500000001376012132367244026276 0ustar ebourgebourgpackage org.bouncycastle.crypto.engines; import org.bouncycastle.crypto.CipherParameters; import org.bouncycastle.crypto.DataLengthException; import org.bouncycastle.crypto.OutputLengthException; import org.bouncycastle.crypto.StreamCipher; import org.bouncycastle.crypto.params.KeyParameter; import org.bouncycastle.crypto.util.Pack; /** * Implementation of Bob Jenkin's ISAAC (Indirection Shift Accumulate Add and Count). * see: http://www.burtleburtle.net/bob/rand/isaacafa.html */ public class ISAACEngine implements StreamCipher { // Constants private final int sizeL = 8, stateArraySize = sizeL<<5; // 256 // Cipher's internal state private int[] engineState = null, // mm results = null; // randrsl private int a = 0, b = 0, c = 0; // Engine state private int index = 0; private byte[] keyStream = new byte[stateArraySize<<2], // results expanded into bytes workingKey = null; private boolean initialised = false; /** * initialise an ISAAC cipher. * * @param forEncryption whether or not we are for encryption. * @param params the parameters required to set up the cipher. * @exception IllegalArgumentException if the params argument is * inappropriate. */ public void init( boolean forEncryption, CipherParameters params) { if (!(params instanceof KeyParameter)) { throw new IllegalArgumentException("invalid parameter passed to ISAAC init - " + params.getClass().getName()); } /* * ISAAC encryption and decryption is completely * symmetrical, so the 'forEncryption' is * irrelevant. */ KeyParameter p = (KeyParameter)params; setKey(p.getKey()); return; } public byte returnByte(byte in) { if (index == 0) { isaac(); keyStream = Pack.intToBigEndian(results); } byte out = (byte)(keyStream[index]^in); index = (index + 1) & 1023; return out; } public void processBytes( byte[] in, int inOff, int len, byte[] out, int outOff) { if (!initialised) { throw new IllegalStateException(getAlgorithmName()+" not initialised"); } if ((inOff + len) > in.length) { throw new DataLengthException("input buffer too short"); } if ((outOff + len) > out.length) { throw new OutputLengthException("output buffer too short"); } for (int i = 0; i < len; i++) { if (index == 0) { isaac(); keyStream = Pack.intToBigEndian(results); } out[i+outOff] = (byte)(keyStream[index]^in[i+inOff]); index = (index + 1) & 1023; } } public String getAlgorithmName() { return "ISAAC"; } public void reset() { setKey(workingKey); } // Private implementation private void setKey(byte[] keyBytes) { workingKey = keyBytes; if (engineState == null) { engineState = new int[stateArraySize]; } if (results == null) { results = new int[stateArraySize]; } int i, j, k; // Reset state for (i = 0; i < stateArraySize; i++) { engineState[i] = results[i] = 0; } a = b = c = 0; // Reset index counter for output index = 0; // Convert the key bytes to ints and put them into results[] for initialization byte[] t = new byte[keyBytes.length + (keyBytes.length & 3)]; System.arraycopy(keyBytes, 0, t, 0, keyBytes.length); for (i = 0; i < t.length; i+=4) { results[i >>> 2] = Pack.littleEndianToInt(t, i); } // It has begun? int[] abcdefgh = new int[sizeL]; for (i = 0; i < sizeL; i++) { abcdefgh[i] = 0x9e3779b9; // Phi (golden ratio) } for (i = 0; i < 4; i++) { mix(abcdefgh); } for (i = 0; i < 2; i++) { for (j = 0; j < stateArraySize; j+=sizeL) { for (k = 0; k < sizeL; k++) { abcdefgh[k] += (i<1) ? results[j+k] : engineState[j+k]; } mix(abcdefgh); for (k = 0; k < sizeL; k++) { engineState[j+k] = abcdefgh[k]; } } } isaac(); initialised = true; } private void isaac() { int i, x, y; b += ++c; for (i = 0; i < stateArraySize; i++) { x = engineState[i]; switch (i & 3) { case 0: a ^= (a << 13); break; case 1: a ^= (a >>> 6); break; case 2: a ^= (a << 2); break; case 3: a ^= (a >>> 16); break; } a += engineState[(i+128) & 0xFF]; engineState[i] = y = engineState[(x >>> 2) & 0xFF] + a + b; results[i] = b = engineState[(y >>> 10) & 0xFF] + x; } } private void mix(int[] x) { x[0]^=x[1]<< 11; x[3]+=x[0]; x[1]+=x[2]; x[1]^=x[2]>>> 2; x[4]+=x[1]; x[2]+=x[3]; x[2]^=x[3]<< 8; x[5]+=x[2]; x[3]+=x[4]; x[3]^=x[4]>>>16; x[6]+=x[3]; x[4]+=x[5]; x[4]^=x[5]<< 10; x[7]+=x[4]; x[5]+=x[6]; x[5]^=x[6]>>> 4; x[0]+=x[5]; x[6]+=x[7]; x[6]^=x[7]<< 8; x[1]+=x[6]; x[7]+=x[0]; x[7]^=x[0]>>> 9; x[2]+=x[7]; x[0]+=x[1]; } } bouncycastle-1.49.orig/src/org/bouncycastle/crypto/engines/RSABlindedEngine.java0000644000175000017500000000743111215325445027361 0ustar ebourgebourgpackage org.bouncycastle.crypto.engines; import org.bouncycastle.crypto.AsymmetricBlockCipher; import org.bouncycastle.crypto.CipherParameters; import org.bouncycastle.crypto.DataLengthException; import org.bouncycastle.crypto.params.ParametersWithRandom; import org.bouncycastle.crypto.params.RSAKeyParameters; import org.bouncycastle.crypto.params.RSAPrivateCrtKeyParameters; import org.bouncycastle.util.BigIntegers; import java.math.BigInteger; import java.security.SecureRandom; /** * this does your basic RSA algorithm with blinding */ public class RSABlindedEngine implements AsymmetricBlockCipher { private static BigInteger ONE = BigInteger.valueOf(1); private RSACoreEngine core = new RSACoreEngine(); private RSAKeyParameters key; private SecureRandom random; /** * initialise the RSA engine. * * @param forEncryption true if we are encrypting, false otherwise. * @param param the necessary RSA key parameters. */ public void init( boolean forEncryption, CipherParameters param) { core.init(forEncryption, param); if (param instanceof ParametersWithRandom) { ParametersWithRandom rParam = (ParametersWithRandom)param; key = (RSAKeyParameters)rParam.getParameters(); random = rParam.getRandom(); } else { key = (RSAKeyParameters)param; random = new SecureRandom(); } } /** * Return the maximum size for an input block to this engine. * For RSA this is always one byte less than the key size on * encryption, and the same length as the key size on decryption. * * @return maximum size for an input block. */ public int getInputBlockSize() { return core.getInputBlockSize(); } /** * Return the maximum size for an output block to this engine. * For RSA this is always one byte less than the key size on * decryption, and the same length as the key size on encryption. * * @return maximum size for an output block. */ public int getOutputBlockSize() { return core.getOutputBlockSize(); } /** * Process a single block using the basic RSA algorithm. * * @param in the input array. * @param inOff the offset into the input buffer where the data starts. * @param inLen the length of the data to be processed. * @return the result of the RSA process. * @exception DataLengthException the input block is too large. */ public byte[] processBlock( byte[] in, int inOff, int inLen) { if (key == null) { throw new IllegalStateException("RSA engine not initialised"); } BigInteger input = core.convertInput(in, inOff, inLen); BigInteger result; if (key instanceof RSAPrivateCrtKeyParameters) { RSAPrivateCrtKeyParameters k = (RSAPrivateCrtKeyParameters)key; BigInteger e = k.getPublicExponent(); if (e != null) // can't do blinding without a public exponent { BigInteger m = k.getModulus(); BigInteger r = BigIntegers.createRandomInRange(ONE, m.subtract(ONE), random); BigInteger blindedInput = r.modPow(e, m).multiply(input).mod(m); BigInteger blindedResult = core.processBlock(blindedInput); BigInteger rInv = r.modInverse(m); result = blindedResult.multiply(rInv).mod(m); } else { result = core.processBlock(input); } } else { result = core.processBlock(input); } return core.convertOutput(result); } } bouncycastle-1.49.orig/src/org/bouncycastle/crypto/engines/TEAEngine.java0000644000175000017500000001077212106331425026060 0ustar ebourgebourgpackage org.bouncycastle.crypto.engines; import org.bouncycastle.crypto.BlockCipher; import org.bouncycastle.crypto.CipherParameters; import org.bouncycastle.crypto.DataLengthException; import org.bouncycastle.crypto.OutputLengthException; import org.bouncycastle.crypto.params.KeyParameter; /** * An TEA engine. */ public class TEAEngine implements BlockCipher { private static final int rounds = 32, block_size = 8, // key_size = 16, delta = 0x9E3779B9, d_sum = 0xC6EF3720; // sum on decrypt /* * the expanded key array of 4 subkeys */ private int _a, _b, _c, _d; private boolean _initialised; private boolean _forEncryption; /** * Create an instance of the TEA encryption algorithm * and set some defaults */ public TEAEngine() { _initialised = false; } public String getAlgorithmName() { return "TEA"; } public int getBlockSize() { return block_size; } /** * initialise * * @param forEncryption whether or not we are for encryption. * @param params the parameters required to set up the cipher. * @exception IllegalArgumentException if the params argument is * inappropriate. */ public void init( boolean forEncryption, CipherParameters params) { if (!(params instanceof KeyParameter)) { throw new IllegalArgumentException("invalid parameter passed to TEA init - " + params.getClass().getName()); } _forEncryption = forEncryption; _initialised = true; KeyParameter p = (KeyParameter)params; setKey(p.getKey()); } public int processBlock( byte[] in, int inOff, byte[] out, int outOff) { if (!_initialised) { throw new IllegalStateException(getAlgorithmName()+" not initialised"); } if ((inOff + block_size) > in.length) { throw new DataLengthException("input buffer too short"); } if ((outOff + block_size) > out.length) { throw new OutputLengthException("output buffer too short"); } return (_forEncryption) ? encryptBlock(in, inOff, out, outOff) : decryptBlock(in, inOff, out, outOff); } public void reset() { } /** * Re-key the cipher. *

    * @param key the key to be used */ private void setKey( byte[] key) { _a = bytesToInt(key, 0); _b = bytesToInt(key, 4); _c = bytesToInt(key, 8); _d = bytesToInt(key, 12); } private int encryptBlock( byte[] in, int inOff, byte[] out, int outOff) { // Pack bytes into integers int v0 = bytesToInt(in, inOff); int v1 = bytesToInt(in, inOff + 4); int sum = 0; for (int i = 0; i != rounds; i++) { sum += delta; v0 += ((v1 << 4) + _a) ^ (v1 + sum) ^ ((v1 >>> 5) + _b); v1 += ((v0 << 4) + _c) ^ (v0 + sum) ^ ((v0 >>> 5) + _d); } unpackInt(v0, out, outOff); unpackInt(v1, out, outOff + 4); return block_size; } private int decryptBlock( byte[] in, int inOff, byte[] out, int outOff) { // Pack bytes into integers int v0 = bytesToInt(in, inOff); int v1 = bytesToInt(in, inOff + 4); int sum = d_sum; for (int i = 0; i != rounds; i++) { v1 -= ((v0 << 4) + _c) ^ (v0 + sum) ^ ((v0 >>> 5) + _d); v0 -= ((v1 << 4) + _a) ^ (v1 + sum) ^ ((v1 >>> 5) + _b); sum -= delta; } unpackInt(v0, out, outOff); unpackInt(v1, out, outOff + 4); return block_size; } private int bytesToInt(byte[] in, int inOff) { return ((in[inOff++]) << 24) | ((in[inOff++] & 255) << 16) | ((in[inOff++] & 255) << 8) | ((in[inOff] & 255)); } private void unpackInt(int v, byte[] out, int outOff) { out[outOff++] = (byte)(v >>> 24); out[outOff++] = (byte)(v >>> 16); out[outOff++] = (byte)(v >>> 8); out[outOff ] = (byte)v; } } bouncycastle-1.49.orig/src/org/bouncycastle/crypto/engines/CamelliaLightEngine.java0000644000175000017500000004660412106330000030135 0ustar ebourgebourgpackage org.bouncycastle.crypto.engines; import org.bouncycastle.crypto.BlockCipher; import org.bouncycastle.crypto.CipherParameters; import org.bouncycastle.crypto.DataLengthException; import org.bouncycastle.crypto.OutputLengthException; import org.bouncycastle.crypto.params.KeyParameter; /** * Camellia - based on RFC 3713, smaller implementation, about half the size of CamelliaEngine. */ public class CamelliaLightEngine implements BlockCipher { private static final int BLOCK_SIZE = 16; private static final int MASK8 = 0xff; private boolean initialized; private boolean _keyis128; private int[] subkey = new int[24 * 4]; private int[] kw = new int[4 * 2]; // for whitening private int[] ke = new int[6 * 2]; // for FL and FL^(-1) private int[] state = new int[4]; // for encryption and decryption private static final int SIGMA[] = { 0xa09e667f, 0x3bcc908b, 0xb67ae858, 0x4caa73b2, 0xc6ef372f, 0xe94f82be, 0x54ff53a5, 0xf1d36f1c, 0x10e527fa, 0xde682d1d, 0xb05688c2, 0xb3e6c1fd }; /* * * S-box data * */ private static final byte SBOX1[] = { (byte)112, (byte)130, (byte)44, (byte)236, (byte)179, (byte)39, (byte)192, (byte)229, (byte)228, (byte)133, (byte)87, (byte)53, (byte)234, (byte)12, (byte)174, (byte)65, (byte)35, (byte)239, (byte)107, (byte)147, (byte)69, (byte)25, (byte)165, (byte)33, (byte)237, (byte)14, (byte)79, (byte)78, (byte)29, (byte)101, (byte)146, (byte)189, (byte)134, (byte)184, (byte)175, (byte)143, (byte)124, (byte)235, (byte)31, (byte)206, (byte)62, (byte)48, (byte)220, (byte)95, (byte)94, (byte)197, (byte)11, (byte)26, (byte)166, (byte)225, (byte)57, (byte)202, (byte)213, (byte)71, (byte)93, (byte)61, (byte)217, (byte)1, (byte)90, (byte)214, (byte)81, (byte)86, (byte)108, (byte)77, (byte)139, (byte)13, (byte)154, (byte)102, (byte)251, (byte)204, (byte)176, (byte)45, (byte)116, (byte)18, (byte)43, (byte)32, (byte)240, (byte)177, (byte)132, (byte)153, (byte)223, (byte)76, (byte)203, (byte)194, (byte)52, (byte)126, (byte)118, (byte)5, (byte)109, (byte)183, (byte)169, (byte)49, (byte)209, (byte)23, (byte)4, (byte)215, (byte)20, (byte)88, (byte)58, (byte)97, (byte)222, (byte)27, (byte)17, (byte)28, (byte)50, (byte)15, (byte)156, (byte)22, (byte)83, (byte)24, (byte)242, (byte)34, (byte)254, (byte)68, (byte)207, (byte)178, (byte)195, (byte)181, (byte)122, (byte)145, (byte)36, (byte)8, (byte)232, (byte)168, (byte)96, (byte)252, (byte)105, (byte)80, (byte)170, (byte)208, (byte)160, (byte)125, (byte)161, (byte)137, (byte)98, (byte)151, (byte)84, (byte)91, (byte)30, (byte)149, (byte)224, (byte)255, (byte)100, (byte)210, (byte)16, (byte)196, (byte)0, (byte)72, (byte)163, (byte)247, (byte)117, (byte)219, (byte)138, (byte)3, (byte)230, (byte)218, (byte)9, (byte)63, (byte)221, (byte)148, (byte)135, (byte)92, (byte)131, (byte)2, (byte)205, (byte)74, (byte)144, (byte)51, (byte)115, (byte)103, (byte)246, (byte)243, (byte)157, (byte)127, (byte)191, (byte)226, (byte)82, (byte)155, (byte)216, (byte)38, (byte)200, (byte)55, (byte)198, (byte)59, (byte)129, (byte)150, (byte)111, (byte)75, (byte)19, (byte)190, (byte)99, (byte)46, (byte)233, (byte)121, (byte)167, (byte)140, (byte)159, (byte)110, (byte)188, (byte)142, (byte)41, (byte)245, (byte)249, (byte)182, (byte)47, (byte)253, (byte)180, (byte)89, (byte)120, (byte)152, (byte)6, (byte)106, (byte)231, (byte)70, (byte)113, (byte)186, (byte)212, (byte)37, (byte)171, (byte)66, (byte)136, (byte)162, (byte)141, (byte)250, (byte)114, (byte)7, (byte)185, (byte)85, (byte)248, (byte)238, (byte)172, (byte)10, (byte)54, (byte)73, (byte)42, (byte)104, (byte)60, (byte)56, (byte)241, (byte)164, (byte)64, (byte)40, (byte)211, (byte)123, (byte)187, (byte)201, (byte)67, (byte)193, (byte)21, (byte)227, (byte)173, (byte)244, (byte)119, (byte)199, (byte)128, (byte)158 }; private static int rightRotate(int x, int s) { return (((x) >>> (s)) + ((x) << (32 - s))); } private static int leftRotate(int x, int s) { return ((x) << (s)) + ((x) >>> (32 - s)); } private static void roldq(int rot, int[] ki, int ioff, int[] ko, int ooff) { ko[0 + ooff] = (ki[0 + ioff] << rot) | (ki[1 + ioff] >>> (32 - rot)); ko[1 + ooff] = (ki[1 + ioff] << rot) | (ki[2 + ioff] >>> (32 - rot)); ko[2 + ooff] = (ki[2 + ioff] << rot) | (ki[3 + ioff] >>> (32 - rot)); ko[3 + ooff] = (ki[3 + ioff] << rot) | (ki[0 + ioff] >>> (32 - rot)); ki[0 + ioff] = ko[0 + ooff]; ki[1 + ioff] = ko[1 + ooff]; ki[2 + ioff] = ko[2 + ooff]; ki[3 + ioff] = ko[3 + ooff]; } private static void decroldq(int rot, int[] ki, int ioff, int[] ko, int ooff) { ko[2 + ooff] = (ki[0 + ioff] << rot) | (ki[1 + ioff] >>> (32 - rot)); ko[3 + ooff] = (ki[1 + ioff] << rot) | (ki[2 + ioff] >>> (32 - rot)); ko[0 + ooff] = (ki[2 + ioff] << rot) | (ki[3 + ioff] >>> (32 - rot)); ko[1 + ooff] = (ki[3 + ioff] << rot) | (ki[0 + ioff] >>> (32 - rot)); ki[0 + ioff] = ko[2 + ooff]; ki[1 + ioff] = ko[3 + ooff]; ki[2 + ioff] = ko[0 + ooff]; ki[3 + ioff] = ko[1 + ooff]; } private static void roldqo32(int rot, int[] ki, int ioff, int[] ko, int ooff) { ko[0 + ooff] = (ki[1 + ioff] << (rot - 32)) | (ki[2 + ioff] >>> (64 - rot)); ko[1 + ooff] = (ki[2 + ioff] << (rot - 32)) | (ki[3 + ioff] >>> (64 - rot)); ko[2 + ooff] = (ki[3 + ioff] << (rot - 32)) | (ki[0 + ioff] >>> (64 - rot)); ko[3 + ooff] = (ki[0 + ioff] << (rot - 32)) | (ki[1 + ioff] >>> (64 - rot)); ki[0 + ioff] = ko[0 + ooff]; ki[1 + ioff] = ko[1 + ooff]; ki[2 + ioff] = ko[2 + ooff]; ki[3 + ioff] = ko[3 + ooff]; } private static void decroldqo32(int rot, int[] ki, int ioff, int[] ko, int ooff) { ko[2 + ooff] = (ki[1 + ioff] << (rot - 32)) | (ki[2 + ioff] >>> (64 - rot)); ko[3 + ooff] = (ki[2 + ioff] << (rot - 32)) | (ki[3 + ioff] >>> (64 - rot)); ko[0 + ooff] = (ki[3 + ioff] << (rot - 32)) | (ki[0 + ioff] >>> (64 - rot)); ko[1 + ooff] = (ki[0 + ioff] << (rot - 32)) | (ki[1 + ioff] >>> (64 - rot)); ki[0 + ioff] = ko[2 + ooff]; ki[1 + ioff] = ko[3 + ooff]; ki[2 + ioff] = ko[0 + ooff]; ki[3 + ioff] = ko[1 + ooff]; } private int bytes2int(byte[] src, int offset) { int word = 0; for (int i = 0; i < 4; i++) { word = (word << 8) + (src[i + offset] & MASK8); } return word; } private void int2bytes(int word, byte[] dst, int offset) { for (int i = 0; i < 4; i++) { dst[(3 - i) + offset] = (byte)word; word >>>= 8; } } private byte lRot8(byte v, int rot) { return (byte)((v << rot) | ((v & 0xff) >>> (8 - rot))); } private int sbox2(int x) { return (lRot8(SBOX1[x], 1) & MASK8); } private int sbox3(int x) { return (lRot8(SBOX1[x], 7) & MASK8); } private int sbox4(int x) { return (SBOX1[((int)lRot8((byte)x, 1) & MASK8)] & MASK8); } private void camelliaF2(int[] s, int[] skey, int keyoff) { int t1, t2, u, v; t1 = s[0] ^ skey[0 + keyoff]; u = sbox4((t1 & MASK8)); u |= (sbox3(((t1 >>> 8) & MASK8)) << 8); u |= (sbox2(((t1 >>> 16) & MASK8)) << 16); u |= ((int)(SBOX1[((t1 >>> 24) & MASK8)] & MASK8) << 24); t2 = s[1] ^ skey[1 + keyoff]; v = (int)SBOX1[(t2 & MASK8)] & MASK8; v |= (sbox4(((t2 >>> 8) & MASK8)) << 8); v |= (sbox3(((t2 >>> 16) & MASK8)) << 16); v |= (sbox2(((t2 >>> 24) & MASK8)) << 24); v = leftRotate(v, 8); u ^= v; v = leftRotate(v, 8) ^ u; u = rightRotate(u, 8) ^ v; s[2] ^= leftRotate(v, 16) ^ u; s[3] ^= leftRotate(u, 8); t1 = s[2] ^ skey[2 + keyoff]; u = sbox4((t1 & MASK8)); u |= sbox3(((t1 >>> 8) & MASK8)) << 8; u |= sbox2(((t1 >>> 16) & MASK8)) << 16; u |= ((int)SBOX1[((t1 >>> 24) & MASK8)] & MASK8) << 24; t2 = s[3] ^ skey[3 + keyoff]; v = ((int)SBOX1[(t2 & MASK8)] & MASK8); v |= sbox4(((t2 >>> 8) & MASK8)) << 8; v |= sbox3(((t2 >>> 16) & MASK8)) << 16; v |= sbox2(((t2 >>> 24) & MASK8)) << 24; v = leftRotate(v, 8); u ^= v; v = leftRotate(v, 8) ^ u; u = rightRotate(u, 8) ^ v; s[0] ^= leftRotate(v, 16) ^ u; s[1] ^= leftRotate(u, 8); } private void camelliaFLs(int[] s, int[] fkey, int keyoff) { s[1] ^= leftRotate(s[0] & fkey[0 + keyoff], 1); s[0] ^= fkey[1 + keyoff] | s[1]; s[2] ^= fkey[3 + keyoff] | s[3]; s[3] ^= leftRotate(fkey[2 + keyoff] & s[2], 1); } private void setKey(boolean forEncryption, byte[] key) { int[] k = new int[8]; int[] ka = new int[4]; int[] kb = new int[4]; int[] t = new int[4]; switch (key.length) { case 16: _keyis128 = true; k[0] = bytes2int(key, 0); k[1] = bytes2int(key, 4); k[2] = bytes2int(key, 8); k[3] = bytes2int(key, 12); k[4] = k[5] = k[6] = k[7] = 0; break; case 24: k[0] = bytes2int(key, 0); k[1] = bytes2int(key, 4); k[2] = bytes2int(key, 8); k[3] = bytes2int(key, 12); k[4] = bytes2int(key, 16); k[5] = bytes2int(key, 20); k[6] = ~k[4]; k[7] = ~k[5]; _keyis128 = false; break; case 32: k[0] = bytes2int(key, 0); k[1] = bytes2int(key, 4); k[2] = bytes2int(key, 8); k[3] = bytes2int(key, 12); k[4] = bytes2int(key, 16); k[5] = bytes2int(key, 20); k[6] = bytes2int(key, 24); k[7] = bytes2int(key, 28); _keyis128 = false; break; default: throw new IllegalArgumentException("key sizes are only 16/24/32 bytes."); } for (int i = 0; i < 4; i++) { ka[i] = k[i] ^ k[i + 4]; } /* compute KA */ camelliaF2(ka, SIGMA, 0); for (int i = 0; i < 4; i++) { ka[i] ^= k[i]; } camelliaF2(ka, SIGMA, 4); if (_keyis128) { if (forEncryption) { /* KL dependant keys */ kw[0] = k[0]; kw[1] = k[1]; kw[2] = k[2]; kw[3] = k[3]; roldq(15, k, 0, subkey, 4); roldq(30, k, 0, subkey, 12); roldq(15, k, 0, t, 0); subkey[18] = t[2]; subkey[19] = t[3]; roldq(17, k, 0, ke, 4); roldq(17, k, 0, subkey, 24); roldq(17, k, 0, subkey, 32); /* KA dependant keys */ subkey[0] = ka[0]; subkey[1] = ka[1]; subkey[2] = ka[2]; subkey[3] = ka[3]; roldq(15, ka, 0, subkey, 8); roldq(15, ka, 0, ke, 0); roldq(15, ka, 0, t, 0); subkey[16] = t[0]; subkey[17] = t[1]; roldq(15, ka, 0, subkey, 20); roldqo32(34, ka, 0, subkey, 28); roldq(17, ka, 0, kw, 4); } else { // decryption /* KL dependant keys */ kw[4] = k[0]; kw[5] = k[1]; kw[6] = k[2]; kw[7] = k[3]; decroldq(15, k, 0, subkey, 28); decroldq(30, k, 0, subkey, 20); decroldq(15, k, 0, t, 0); subkey[16] = t[0]; subkey[17] = t[1]; decroldq(17, k, 0, ke, 0); decroldq(17, k, 0, subkey, 8); decroldq(17, k, 0, subkey, 0); /* KA dependant keys */ subkey[34] = ka[0]; subkey[35] = ka[1]; subkey[32] = ka[2]; subkey[33] = ka[3]; decroldq(15, ka, 0, subkey, 24); decroldq(15, ka, 0, ke, 4); decroldq(15, ka, 0, t, 0); subkey[18] = t[2]; subkey[19] = t[3]; decroldq(15, ka, 0, subkey, 12); decroldqo32(34, ka, 0, subkey, 4); roldq(17, ka, 0, kw, 0); } } else { // 192bit or 256bit /* compute KB */ for (int i = 0; i < 4; i++) { kb[i] = ka[i] ^ k[i + 4]; } camelliaF2(kb, SIGMA, 8); if (forEncryption) { /* KL dependant keys */ kw[0] = k[0]; kw[1] = k[1]; kw[2] = k[2]; kw[3] = k[3]; roldqo32(45, k, 0, subkey, 16); roldq(15, k, 0, ke, 4); roldq(17, k, 0, subkey, 32); roldqo32(34, k, 0, subkey, 44); /* KR dependant keys */ roldq(15, k, 4, subkey, 4); roldq(15, k, 4, ke, 0); roldq(30, k, 4, subkey, 24); roldqo32(34, k, 4, subkey, 36); /* KA dependant keys */ roldq(15, ka, 0, subkey, 8); roldq(30, ka, 0, subkey, 20); /* 32bit rotation */ ke[8] = ka[1]; ke[9] = ka[2]; ke[10] = ka[3]; ke[11] = ka[0]; roldqo32(49, ka, 0, subkey, 40); /* KB dependant keys */ subkey[0] = kb[0]; subkey[1] = kb[1]; subkey[2] = kb[2]; subkey[3] = kb[3]; roldq(30, kb, 0, subkey, 12); roldq(30, kb, 0, subkey, 28); roldqo32(51, kb, 0, kw, 4); } else { // decryption /* KL dependant keys */ kw[4] = k[0]; kw[5] = k[1]; kw[6] = k[2]; kw[7] = k[3]; decroldqo32(45, k, 0, subkey, 28); decroldq(15, k, 0, ke, 4); decroldq(17, k, 0, subkey, 12); decroldqo32(34, k, 0, subkey, 0); /* KR dependant keys */ decroldq(15, k, 4, subkey, 40); decroldq(15, k, 4, ke, 8); decroldq(30, k, 4, subkey, 20); decroldqo32(34, k, 4, subkey, 8); /* KA dependant keys */ decroldq(15, ka, 0, subkey, 36); decroldq(30, ka, 0, subkey, 24); /* 32bit rotation */ ke[2] = ka[1]; ke[3] = ka[2]; ke[0] = ka[3]; ke[1] = ka[0]; decroldqo32(49, ka, 0, subkey, 4); /* KB dependant keys */ subkey[46] = kb[0]; subkey[47] = kb[1]; subkey[44] = kb[2]; subkey[45] = kb[3]; decroldq(30, kb, 0, subkey, 32); decroldq(30, kb, 0, subkey, 16); roldqo32(51, kb, 0, kw, 0); } } } private int processBlock128(byte[] in, int inOff, byte[] out, int outOff) { for (int i = 0; i < 4; i++) { state[i] = bytes2int(in, inOff + (i * 4)); state[i] ^= kw[i]; } camelliaF2(state, subkey, 0); camelliaF2(state, subkey, 4); camelliaF2(state, subkey, 8); camelliaFLs(state, ke, 0); camelliaF2(state, subkey, 12); camelliaF2(state, subkey, 16); camelliaF2(state, subkey, 20); camelliaFLs(state, ke, 4); camelliaF2(state, subkey, 24); camelliaF2(state, subkey, 28); camelliaF2(state, subkey, 32); state[2] ^= kw[4]; state[3] ^= kw[5]; state[0] ^= kw[6]; state[1] ^= kw[7]; int2bytes(state[2], out, outOff); int2bytes(state[3], out, outOff + 4); int2bytes(state[0], out, outOff + 8); int2bytes(state[1], out, outOff + 12); return BLOCK_SIZE; } private int processBlock192or256(byte[] in, int inOff, byte[] out, int outOff) { for (int i = 0; i < 4; i++) { state[i] = bytes2int(in, inOff + (i * 4)); state[i] ^= kw[i]; } camelliaF2(state, subkey, 0); camelliaF2(state, subkey, 4); camelliaF2(state, subkey, 8); camelliaFLs(state, ke, 0); camelliaF2(state, subkey, 12); camelliaF2(state, subkey, 16); camelliaF2(state, subkey, 20); camelliaFLs(state, ke, 4); camelliaF2(state, subkey, 24); camelliaF2(state, subkey, 28); camelliaF2(state, subkey, 32); camelliaFLs(state, ke, 8); camelliaF2(state, subkey, 36); camelliaF2(state, subkey, 40); camelliaF2(state, subkey, 44); state[2] ^= kw[4]; state[3] ^= kw[5]; state[0] ^= kw[6]; state[1] ^= kw[7]; int2bytes(state[2], out, outOff); int2bytes(state[3], out, outOff + 4); int2bytes(state[0], out, outOff + 8); int2bytes(state[1], out, outOff + 12); return BLOCK_SIZE; } public CamelliaLightEngine() { } public String getAlgorithmName() { return "Camellia"; } public int getBlockSize() { return BLOCK_SIZE; } public void init(boolean forEncryption, CipherParameters params) { if (!(params instanceof KeyParameter)) { throw new IllegalArgumentException("only simple KeyParameter expected."); } setKey(forEncryption, ((KeyParameter)params).getKey()); initialized = true; } public int processBlock(byte[] in, int inOff, byte[] out, int outOff) throws IllegalStateException { if (!initialized) { throw new IllegalStateException("Camellia is not initialized"); } if ((inOff + BLOCK_SIZE) > in.length) { throw new DataLengthException("input buffer too short"); } if ((outOff + BLOCK_SIZE) > out.length) { throw new OutputLengthException("output buffer too short"); } if (_keyis128) { return processBlock128(in, inOff, out, outOff); } else { return processBlock192or256(in, inOff, out, outOff); } } public void reset() { } } bouncycastle-1.49.orig/src/org/bouncycastle/crypto/engines/SEEDEngine.java0000644000175000017500000004464412106331312026167 0ustar ebourgebourgpackage org.bouncycastle.crypto.engines; import org.bouncycastle.crypto.BlockCipher; import org.bouncycastle.crypto.CipherParameters; import org.bouncycastle.crypto.DataLengthException; import org.bouncycastle.crypto.OutputLengthException; import org.bouncycastle.crypto.params.KeyParameter; /** * Implementation of the SEED algorithm as described in RFC 4009 */ public class SEEDEngine implements BlockCipher { private final int BLOCK_SIZE = 16; private static final int[] SS0 = { 0x2989a1a8, 0x05858184, 0x16c6d2d4, 0x13c3d3d0, 0x14445054, 0x1d0d111c, 0x2c8ca0ac, 0x25052124, 0x1d4d515c, 0x03434340, 0x18081018, 0x1e0e121c, 0x11415150, 0x3cccf0fc, 0x0acac2c8, 0x23436360, 0x28082028, 0x04444044, 0x20002020, 0x1d8d919c, 0x20c0e0e0, 0x22c2e2e0, 0x08c8c0c8, 0x17071314, 0x2585a1a4, 0x0f8f838c, 0x03030300, 0x3b4b7378, 0x3b8bb3b8, 0x13031310, 0x12c2d2d0, 0x2ecee2ec, 0x30407070, 0x0c8c808c, 0x3f0f333c, 0x2888a0a8, 0x32023230, 0x1dcdd1dc, 0x36c6f2f4, 0x34447074, 0x2ccce0ec, 0x15859194, 0x0b0b0308, 0x17475354, 0x1c4c505c, 0x1b4b5358, 0x3d8db1bc, 0x01010100, 0x24042024, 0x1c0c101c, 0x33437370, 0x18889098, 0x10001010, 0x0cccc0cc, 0x32c2f2f0, 0x19c9d1d8, 0x2c0c202c, 0x27c7e3e4, 0x32427270, 0x03838380, 0x1b8b9398, 0x11c1d1d0, 0x06868284, 0x09c9c1c8, 0x20406060, 0x10405050, 0x2383a3a0, 0x2bcbe3e8, 0x0d0d010c, 0x3686b2b4, 0x1e8e929c, 0x0f4f434c, 0x3787b3b4, 0x1a4a5258, 0x06c6c2c4, 0x38487078, 0x2686a2a4, 0x12021210, 0x2f8fa3ac, 0x15c5d1d4, 0x21416160, 0x03c3c3c0, 0x3484b0b4, 0x01414140, 0x12425250, 0x3d4d717c, 0x0d8d818c, 0x08080008, 0x1f0f131c, 0x19899198, 0x00000000, 0x19091118, 0x04040004, 0x13435350, 0x37c7f3f4, 0x21c1e1e0, 0x3dcdf1fc, 0x36467274, 0x2f0f232c, 0x27072324, 0x3080b0b0, 0x0b8b8388, 0x0e0e020c, 0x2b8ba3a8, 0x2282a2a0, 0x2e4e626c, 0x13839390, 0x0d4d414c, 0x29496168, 0x3c4c707c, 0x09090108, 0x0a0a0208, 0x3f8fb3bc, 0x2fcfe3ec, 0x33c3f3f0, 0x05c5c1c4, 0x07878384, 0x14041014, 0x3ecef2fc, 0x24446064, 0x1eced2dc, 0x2e0e222c, 0x0b4b4348, 0x1a0a1218, 0x06060204, 0x21012120, 0x2b4b6368, 0x26466264, 0x02020200, 0x35c5f1f4, 0x12829290, 0x0a8a8288, 0x0c0c000c, 0x3383b3b0, 0x3e4e727c, 0x10c0d0d0, 0x3a4a7278, 0x07474344, 0x16869294, 0x25c5e1e4, 0x26062224, 0x00808080, 0x2d8da1ac, 0x1fcfd3dc, 0x2181a1a0, 0x30003030, 0x37073334, 0x2e8ea2ac, 0x36063234, 0x15051114, 0x22022220, 0x38083038, 0x34c4f0f4, 0x2787a3a4, 0x05454144, 0x0c4c404c, 0x01818180, 0x29c9e1e8, 0x04848084, 0x17879394, 0x35053134, 0x0bcbc3c8, 0x0ecec2cc, 0x3c0c303c, 0x31417170, 0x11011110, 0x07c7c3c4, 0x09898188, 0x35457174, 0x3bcbf3f8, 0x1acad2d8, 0x38c8f0f8, 0x14849094, 0x19495158, 0x02828280, 0x04c4c0c4, 0x3fcff3fc, 0x09494148, 0x39093138, 0x27476364, 0x00c0c0c0, 0x0fcfc3cc, 0x17c7d3d4, 0x3888b0b8, 0x0f0f030c, 0x0e8e828c, 0x02424240, 0x23032320, 0x11819190, 0x2c4c606c, 0x1bcbd3d8, 0x2484a0a4, 0x34043034, 0x31c1f1f0, 0x08484048, 0x02c2c2c0, 0x2f4f636c, 0x3d0d313c, 0x2d0d212c, 0x00404040, 0x3e8eb2bc, 0x3e0e323c, 0x3c8cb0bc, 0x01c1c1c0, 0x2a8aa2a8, 0x3a8ab2b8, 0x0e4e424c, 0x15455154, 0x3b0b3338, 0x1cccd0dc, 0x28486068, 0x3f4f737c, 0x1c8c909c, 0x18c8d0d8, 0x0a4a4248, 0x16465254, 0x37477374, 0x2080a0a0, 0x2dcde1ec, 0x06464244, 0x3585b1b4, 0x2b0b2328, 0x25456164, 0x3acaf2f8, 0x23c3e3e0, 0x3989b1b8, 0x3181b1b0, 0x1f8f939c, 0x1e4e525c, 0x39c9f1f8, 0x26c6e2e4, 0x3282b2b0, 0x31013130, 0x2acae2e8, 0x2d4d616c, 0x1f4f535c, 0x24c4e0e4, 0x30c0f0f0, 0x0dcdc1cc, 0x08888088, 0x16061214, 0x3a0a3238, 0x18485058, 0x14c4d0d4, 0x22426260, 0x29092128, 0x07070304, 0x33033330, 0x28c8e0e8, 0x1b0b1318, 0x05050104, 0x39497178, 0x10809090, 0x2a4a6268, 0x2a0a2228, 0x1a8a9298 }; private static final int[] SS1 = { 0x38380830, 0xe828c8e0, 0x2c2d0d21, 0xa42686a2, 0xcc0fcfc3, 0xdc1eced2, 0xb03383b3, 0xb83888b0, 0xac2f8fa3, 0x60204060, 0x54154551, 0xc407c7c3, 0x44044440, 0x6c2f4f63, 0x682b4b63, 0x581b4b53, 0xc003c3c3, 0x60224262, 0x30330333, 0xb43585b1, 0x28290921, 0xa02080a0, 0xe022c2e2, 0xa42787a3, 0xd013c3d3, 0x90118191, 0x10110111, 0x04060602, 0x1c1c0c10, 0xbc3c8cb0, 0x34360632, 0x480b4b43, 0xec2fcfe3, 0x88088880, 0x6c2c4c60, 0xa82888a0, 0x14170713, 0xc404c4c0, 0x14160612, 0xf434c4f0, 0xc002c2c2, 0x44054541, 0xe021c1e1, 0xd416c6d2, 0x3c3f0f33, 0x3c3d0d31, 0x8c0e8e82, 0x98188890, 0x28280820, 0x4c0e4e42, 0xf436c6f2, 0x3c3e0e32, 0xa42585a1, 0xf839c9f1, 0x0c0d0d01, 0xdc1fcfd3, 0xd818c8d0, 0x282b0b23, 0x64264662, 0x783a4a72, 0x24270723, 0x2c2f0f23, 0xf031c1f1, 0x70324272, 0x40024242, 0xd414c4d0, 0x40014141, 0xc000c0c0, 0x70334373, 0x64274763, 0xac2c8ca0, 0x880b8b83, 0xf437c7f3, 0xac2d8da1, 0x80008080, 0x1c1f0f13, 0xc80acac2, 0x2c2c0c20, 0xa82a8aa2, 0x34340430, 0xd012c2d2, 0x080b0b03, 0xec2ecee2, 0xe829c9e1, 0x5c1d4d51, 0x94148490, 0x18180810, 0xf838c8f0, 0x54174753, 0xac2e8ea2, 0x08080800, 0xc405c5c1, 0x10130313, 0xcc0dcdc1, 0x84068682, 0xb83989b1, 0xfc3fcff3, 0x7c3d4d71, 0xc001c1c1, 0x30310131, 0xf435c5f1, 0x880a8a82, 0x682a4a62, 0xb03181b1, 0xd011c1d1, 0x20200020, 0xd417c7d3, 0x00020202, 0x20220222, 0x04040400, 0x68284860, 0x70314171, 0x04070703, 0xd81bcbd3, 0x9c1d8d91, 0x98198991, 0x60214161, 0xbc3e8eb2, 0xe426c6e2, 0x58194951, 0xdc1dcdd1, 0x50114151, 0x90108090, 0xdc1cccd0, 0x981a8a92, 0xa02383a3, 0xa82b8ba3, 0xd010c0d0, 0x80018181, 0x0c0f0f03, 0x44074743, 0x181a0a12, 0xe023c3e3, 0xec2ccce0, 0x8c0d8d81, 0xbc3f8fb3, 0x94168692, 0x783b4b73, 0x5c1c4c50, 0xa02282a2, 0xa02181a1, 0x60234363, 0x20230323, 0x4c0d4d41, 0xc808c8c0, 0x9c1e8e92, 0x9c1c8c90, 0x383a0a32, 0x0c0c0c00, 0x2c2e0e22, 0xb83a8ab2, 0x6c2e4e62, 0x9c1f8f93, 0x581a4a52, 0xf032c2f2, 0x90128292, 0xf033c3f3, 0x48094941, 0x78384870, 0xcc0cccc0, 0x14150511, 0xf83bcbf3, 0x70304070, 0x74354571, 0x7c3f4f73, 0x34350531, 0x10100010, 0x00030303, 0x64244460, 0x6c2d4d61, 0xc406c6c2, 0x74344470, 0xd415c5d1, 0xb43484b0, 0xe82acae2, 0x08090901, 0x74364672, 0x18190911, 0xfc3ecef2, 0x40004040, 0x10120212, 0xe020c0e0, 0xbc3d8db1, 0x04050501, 0xf83acaf2, 0x00010101, 0xf030c0f0, 0x282a0a22, 0x5c1e4e52, 0xa82989a1, 0x54164652, 0x40034343, 0x84058581, 0x14140410, 0x88098981, 0x981b8b93, 0xb03080b0, 0xe425c5e1, 0x48084840, 0x78394971, 0x94178793, 0xfc3cccf0, 0x1c1e0e12, 0x80028282, 0x20210121, 0x8c0c8c80, 0x181b0b13, 0x5c1f4f53, 0x74374773, 0x54144450, 0xb03282b2, 0x1c1d0d11, 0x24250521, 0x4c0f4f43, 0x00000000, 0x44064642, 0xec2dcde1, 0x58184850, 0x50124252, 0xe82bcbe3, 0x7c3e4e72, 0xd81acad2, 0xc809c9c1, 0xfc3dcdf1, 0x30300030, 0x94158591, 0x64254561, 0x3c3c0c30, 0xb43686b2, 0xe424c4e0, 0xb83b8bb3, 0x7c3c4c70, 0x0c0e0e02, 0x50104050, 0x38390931, 0x24260622, 0x30320232, 0x84048480, 0x68294961, 0x90138393, 0x34370733, 0xe427c7e3, 0x24240420, 0xa42484a0, 0xc80bcbc3, 0x50134353, 0x080a0a02, 0x84078783, 0xd819c9d1, 0x4c0c4c40, 0x80038383, 0x8c0f8f83, 0xcc0ecec2, 0x383b0b33, 0x480a4a42, 0xb43787b3 }; private static final int[] SS2 = { 0xa1a82989, 0x81840585, 0xd2d416c6, 0xd3d013c3, 0x50541444, 0x111c1d0d, 0xa0ac2c8c, 0x21242505, 0x515c1d4d, 0x43400343, 0x10181808, 0x121c1e0e, 0x51501141, 0xf0fc3ccc, 0xc2c80aca, 0x63602343, 0x20282808, 0x40440444, 0x20202000, 0x919c1d8d, 0xe0e020c0, 0xe2e022c2, 0xc0c808c8, 0x13141707, 0xa1a42585, 0x838c0f8f, 0x03000303, 0x73783b4b, 0xb3b83b8b, 0x13101303, 0xd2d012c2, 0xe2ec2ece, 0x70703040, 0x808c0c8c, 0x333c3f0f, 0xa0a82888, 0x32303202, 0xd1dc1dcd, 0xf2f436c6, 0x70743444, 0xe0ec2ccc, 0x91941585, 0x03080b0b, 0x53541747, 0x505c1c4c, 0x53581b4b, 0xb1bc3d8d, 0x01000101, 0x20242404, 0x101c1c0c, 0x73703343, 0x90981888, 0x10101000, 0xc0cc0ccc, 0xf2f032c2, 0xd1d819c9, 0x202c2c0c, 0xe3e427c7, 0x72703242, 0x83800383, 0x93981b8b, 0xd1d011c1, 0x82840686, 0xc1c809c9, 0x60602040, 0x50501040, 0xa3a02383, 0xe3e82bcb, 0x010c0d0d, 0xb2b43686, 0x929c1e8e, 0x434c0f4f, 0xb3b43787, 0x52581a4a, 0xc2c406c6, 0x70783848, 0xa2a42686, 0x12101202, 0xa3ac2f8f, 0xd1d415c5, 0x61602141, 0xc3c003c3, 0xb0b43484, 0x41400141, 0x52501242, 0x717c3d4d, 0x818c0d8d, 0x00080808, 0x131c1f0f, 0x91981989, 0x00000000, 0x11181909, 0x00040404, 0x53501343, 0xf3f437c7, 0xe1e021c1, 0xf1fc3dcd, 0x72743646, 0x232c2f0f, 0x23242707, 0xb0b03080, 0x83880b8b, 0x020c0e0e, 0xa3a82b8b, 0xa2a02282, 0x626c2e4e, 0x93901383, 0x414c0d4d, 0x61682949, 0x707c3c4c, 0x01080909, 0x02080a0a, 0xb3bc3f8f, 0xe3ec2fcf, 0xf3f033c3, 0xc1c405c5, 0x83840787, 0x10141404, 0xf2fc3ece, 0x60642444, 0xd2dc1ece, 0x222c2e0e, 0x43480b4b, 0x12181a0a, 0x02040606, 0x21202101, 0x63682b4b, 0x62642646, 0x02000202, 0xf1f435c5, 0x92901282, 0x82880a8a, 0x000c0c0c, 0xb3b03383, 0x727c3e4e, 0xd0d010c0, 0x72783a4a, 0x43440747, 0x92941686, 0xe1e425c5, 0x22242606, 0x80800080, 0xa1ac2d8d, 0xd3dc1fcf, 0xa1a02181, 0x30303000, 0x33343707, 0xa2ac2e8e, 0x32343606, 0x11141505, 0x22202202, 0x30383808, 0xf0f434c4, 0xa3a42787, 0x41440545, 0x404c0c4c, 0x81800181, 0xe1e829c9, 0x80840484, 0x93941787, 0x31343505, 0xc3c80bcb, 0xc2cc0ece, 0x303c3c0c, 0x71703141, 0x11101101, 0xc3c407c7, 0x81880989, 0x71743545, 0xf3f83bcb, 0xd2d81aca, 0xf0f838c8, 0x90941484, 0x51581949, 0x82800282, 0xc0c404c4, 0xf3fc3fcf, 0x41480949, 0x31383909, 0x63642747, 0xc0c000c0, 0xc3cc0fcf, 0xd3d417c7, 0xb0b83888, 0x030c0f0f, 0x828c0e8e, 0x42400242, 0x23202303, 0x91901181, 0x606c2c4c, 0xd3d81bcb, 0xa0a42484, 0x30343404, 0xf1f031c1, 0x40480848, 0xc2c002c2, 0x636c2f4f, 0x313c3d0d, 0x212c2d0d, 0x40400040, 0xb2bc3e8e, 0x323c3e0e, 0xb0bc3c8c, 0xc1c001c1, 0xa2a82a8a, 0xb2b83a8a, 0x424c0e4e, 0x51541545, 0x33383b0b, 0xd0dc1ccc, 0x60682848, 0x737c3f4f, 0x909c1c8c, 0xd0d818c8, 0x42480a4a, 0x52541646, 0x73743747, 0xa0a02080, 0xe1ec2dcd, 0x42440646, 0xb1b43585, 0x23282b0b, 0x61642545, 0xf2f83aca, 0xe3e023c3, 0xb1b83989, 0xb1b03181, 0x939c1f8f, 0x525c1e4e, 0xf1f839c9, 0xe2e426c6, 0xb2b03282, 0x31303101, 0xe2e82aca, 0x616c2d4d, 0x535c1f4f, 0xe0e424c4, 0xf0f030c0, 0xc1cc0dcd, 0x80880888, 0x12141606, 0x32383a0a, 0x50581848, 0xd0d414c4, 0x62602242, 0x21282909, 0x03040707, 0x33303303, 0xe0e828c8, 0x13181b0b, 0x01040505, 0x71783949, 0x90901080, 0x62682a4a, 0x22282a0a, 0x92981a8a }; private static final int[] SS3 = { 0x08303838, 0xc8e0e828, 0x0d212c2d, 0x86a2a426, 0xcfc3cc0f, 0xced2dc1e, 0x83b3b033, 0x88b0b838, 0x8fa3ac2f, 0x40606020, 0x45515415, 0xc7c3c407, 0x44404404, 0x4f636c2f, 0x4b63682b, 0x4b53581b, 0xc3c3c003, 0x42626022, 0x03333033, 0x85b1b435, 0x09212829, 0x80a0a020, 0xc2e2e022, 0x87a3a427, 0xc3d3d013, 0x81919011, 0x01111011, 0x06020406, 0x0c101c1c, 0x8cb0bc3c, 0x06323436, 0x4b43480b, 0xcfe3ec2f, 0x88808808, 0x4c606c2c, 0x88a0a828, 0x07131417, 0xc4c0c404, 0x06121416, 0xc4f0f434, 0xc2c2c002, 0x45414405, 0xc1e1e021, 0xc6d2d416, 0x0f333c3f, 0x0d313c3d, 0x8e828c0e, 0x88909818, 0x08202828, 0x4e424c0e, 0xc6f2f436, 0x0e323c3e, 0x85a1a425, 0xc9f1f839, 0x0d010c0d, 0xcfd3dc1f, 0xc8d0d818, 0x0b23282b, 0x46626426, 0x4a72783a, 0x07232427, 0x0f232c2f, 0xc1f1f031, 0x42727032, 0x42424002, 0xc4d0d414, 0x41414001, 0xc0c0c000, 0x43737033, 0x47636427, 0x8ca0ac2c, 0x8b83880b, 0xc7f3f437, 0x8da1ac2d, 0x80808000, 0x0f131c1f, 0xcac2c80a, 0x0c202c2c, 0x8aa2a82a, 0x04303434, 0xc2d2d012, 0x0b03080b, 0xcee2ec2e, 0xc9e1e829, 0x4d515c1d, 0x84909414, 0x08101818, 0xc8f0f838, 0x47535417, 0x8ea2ac2e, 0x08000808, 0xc5c1c405, 0x03131013, 0xcdc1cc0d, 0x86828406, 0x89b1b839, 0xcff3fc3f, 0x4d717c3d, 0xc1c1c001, 0x01313031, 0xc5f1f435, 0x8a82880a, 0x4a62682a, 0x81b1b031, 0xc1d1d011, 0x00202020, 0xc7d3d417, 0x02020002, 0x02222022, 0x04000404, 0x48606828, 0x41717031, 0x07030407, 0xcbd3d81b, 0x8d919c1d, 0x89919819, 0x41616021, 0x8eb2bc3e, 0xc6e2e426, 0x49515819, 0xcdd1dc1d, 0x41515011, 0x80909010, 0xccd0dc1c, 0x8a92981a, 0x83a3a023, 0x8ba3a82b, 0xc0d0d010, 0x81818001, 0x0f030c0f, 0x47434407, 0x0a12181a, 0xc3e3e023, 0xcce0ec2c, 0x8d818c0d, 0x8fb3bc3f, 0x86929416, 0x4b73783b, 0x4c505c1c, 0x82a2a022, 0x81a1a021, 0x43636023, 0x03232023, 0x4d414c0d, 0xc8c0c808, 0x8e929c1e, 0x8c909c1c, 0x0a32383a, 0x0c000c0c, 0x0e222c2e, 0x8ab2b83a, 0x4e626c2e, 0x8f939c1f, 0x4a52581a, 0xc2f2f032, 0x82929012, 0xc3f3f033, 0x49414809, 0x48707838, 0xccc0cc0c, 0x05111415, 0xcbf3f83b, 0x40707030, 0x45717435, 0x4f737c3f, 0x05313435, 0x00101010, 0x03030003, 0x44606424, 0x4d616c2d, 0xc6c2c406, 0x44707434, 0xc5d1d415, 0x84b0b434, 0xcae2e82a, 0x09010809, 0x46727436, 0x09111819, 0xcef2fc3e, 0x40404000, 0x02121012, 0xc0e0e020, 0x8db1bc3d, 0x05010405, 0xcaf2f83a, 0x01010001, 0xc0f0f030, 0x0a22282a, 0x4e525c1e, 0x89a1a829, 0x46525416, 0x43434003, 0x85818405, 0x04101414, 0x89818809, 0x8b93981b, 0x80b0b030, 0xc5e1e425, 0x48404808, 0x49717839, 0x87939417, 0xccf0fc3c, 0x0e121c1e, 0x82828002, 0x01212021, 0x8c808c0c, 0x0b13181b, 0x4f535c1f, 0x47737437, 0x44505414, 0x82b2b032, 0x0d111c1d, 0x05212425, 0x4f434c0f, 0x00000000, 0x46424406, 0xcde1ec2d, 0x48505818, 0x42525012, 0xcbe3e82b, 0x4e727c3e, 0xcad2d81a, 0xc9c1c809, 0xcdf1fc3d, 0x00303030, 0x85919415, 0x45616425, 0x0c303c3c, 0x86b2b436, 0xc4e0e424, 0x8bb3b83b, 0x4c707c3c, 0x0e020c0e, 0x40505010, 0x09313839, 0x06222426, 0x02323032, 0x84808404, 0x49616829, 0x83939013, 0x07333437, 0xc7e3e427, 0x04202424, 0x84a0a424, 0xcbc3c80b, 0x43535013, 0x0a02080a, 0x87838407, 0xc9d1d819, 0x4c404c0c, 0x83838003, 0x8f838c0f, 0xcec2cc0e, 0x0b33383b, 0x4a42480a, 0x87b3b437 }; private static final int[] KC = { 0x9e3779b9, 0x3c6ef373, 0x78dde6e6, 0xf1bbcdcc, 0xe3779b99, 0xc6ef3733, 0x8dde6e67, 0x1bbcdccf, 0x3779b99e, 0x6ef3733c, 0xdde6e678, 0xbbcdccf1, 0x779b99e3, 0xef3733c6, 0xde6e678d, 0xbcdccf1b }; private int[] wKey; private boolean forEncryption; public void init(boolean forEncryption, CipherParameters params) throws IllegalArgumentException { this.forEncryption = forEncryption; wKey = createWorkingKey(((KeyParameter)params).getKey()); } public String getAlgorithmName() { return "SEED"; } public int getBlockSize() { return BLOCK_SIZE; } public int processBlock(byte[] in, int inOff, byte[] out, int outOff) throws DataLengthException, IllegalStateException { if (wKey == null) { throw new IllegalStateException("SEED engine not initialised"); } if (inOff + BLOCK_SIZE > in.length) { throw new DataLengthException("input buffer too short"); } if (outOff + BLOCK_SIZE > out.length) { throw new OutputLengthException("output buffer too short"); } long l = bytesToLong(in, inOff + 0); long r = bytesToLong(in, inOff + 8); if (forEncryption) { for (int i = 0; i < 16; i++) { long nl = r; r = l ^ F(wKey[2 * i], wKey[(2 * i) + 1], r); l = nl; } } else { for (int i = 15; i >= 0; i--) { long nl = r; r = l ^ F(wKey[2 * i], wKey[(2 * i) + 1], r); l = nl; } } longToBytes(out, outOff + 0, r); longToBytes(out, outOff + 8, l); return BLOCK_SIZE; } public void reset() { } private int[] createWorkingKey(byte[] inKey) { int[] key = new int[32]; long lower = bytesToLong(inKey, 0); long upper = bytesToLong(inKey, 8); int key0 = extractW0(lower); int key1 = extractW1(lower); int key2 = extractW0(upper); int key3 = extractW1(upper); for (int i = 0; i < 16; i++) { key[2 * i] = G(key0 + key2 - KC[i]); key[2 * i + 1] = G(key1 - key3 + KC[i]); if (i % 2 == 0) { lower = rotateRight8(lower); key0 = extractW0(lower); key1 = extractW1(lower); } else { upper = rotateLeft8(upper); key2 = extractW0(upper); key3 = extractW1(upper); } } return key; } private int extractW1(long lVal) { return (int)lVal; } private int extractW0(long lVal) { return (int)(lVal >> 32); } private long rotateLeft8(long x) { return (x << 8) | (x >>> 56); } private long rotateRight8(long x) { return (x >>> 8) | (x << 56); } private long bytesToLong( byte[] src, int srcOff) { long word = 0; for (int i = 0; i <= 7; i++) { word = (word << 8) + (src[i + srcOff] & 0xff); } return word; } private void longToBytes( byte[] dest, int destOff, long value) { for (int i = 0; i < 8; i++) { dest[i + destOff] = (byte)(value >> ((7 - i) * 8)); } } private int G(int x) { return SS0[x & 0xff] ^ SS1[(x >> 8) & 0xff] ^ SS2[(x >> 16) & 0xff] ^ SS3[(x >> 24) & 0xff]; } private long F(int ki0, int ki1, long r) { int r0 = (int)(r >> 32); int r1 = (int)r; int rd1 = phaseCalc2(r0, ki0, r1, ki1); int rd0 = rd1 + phaseCalc1(r0, ki0, r1, ki1); return ((long)rd0 << 32) | (rd1 & 0xffffffffL); } private int phaseCalc1(int r0, int ki0, int r1, int ki1) { return G(G((r0 ^ ki0) ^ (r1 ^ ki1)) + (r0 ^ ki0)); } private int phaseCalc2(int r0, int ki0, int r1, int ki1) { return G(phaseCalc1(r0, ki0, r1, ki1) + G((r0 ^ ki0) ^ (r1 ^ ki1))); } } bouncycastle-1.49.orig/src/org/bouncycastle/crypto/engines/RSABlindingEngine.java0000644000175000017500000000753510554246700027554 0ustar ebourgebourgpackage org.bouncycastle.crypto.engines; import org.bouncycastle.crypto.AsymmetricBlockCipher; import org.bouncycastle.crypto.CipherParameters; import org.bouncycastle.crypto.DataLengthException; import org.bouncycastle.crypto.params.ParametersWithRandom; import org.bouncycastle.crypto.params.RSABlindingParameters; import org.bouncycastle.crypto.params.RSAKeyParameters; import java.math.BigInteger; /** * This does your basic RSA Chaum's blinding and unblinding as outlined in * "Handbook of Applied Cryptography", page 475. You need to use this if you are * trying to get another party to generate signatures without them being aware * of the message they are signing. */ public class RSABlindingEngine implements AsymmetricBlockCipher { private RSACoreEngine core = new RSACoreEngine(); private RSAKeyParameters key; private BigInteger blindingFactor; private boolean forEncryption; /** * Initialise the blinding engine. * * @param forEncryption true if we are encrypting (blinding), false otherwise. * @param param the necessary RSA key parameters. */ public void init( boolean forEncryption, CipherParameters param) { RSABlindingParameters p; if (param instanceof ParametersWithRandom) { ParametersWithRandom rParam = (ParametersWithRandom)param; p = (RSABlindingParameters)rParam.getParameters(); } else { p = (RSABlindingParameters)param; } core.init(forEncryption, p.getPublicKey()); this.forEncryption = forEncryption; this.key = p.getPublicKey(); this.blindingFactor = p.getBlindingFactor(); } /** * Return the maximum size for an input block to this engine. * For RSA this is always one byte less than the key size on * encryption, and the same length as the key size on decryption. * * @return maximum size for an input block. */ public int getInputBlockSize() { return core.getInputBlockSize(); } /** * Return the maximum size for an output block to this engine. * For RSA this is always one byte less than the key size on * decryption, and the same length as the key size on encryption. * * @return maximum size for an output block. */ public int getOutputBlockSize() { return core.getOutputBlockSize(); } /** * Process a single block using the RSA blinding algorithm. * * @param in the input array. * @param inOff the offset into the input buffer where the data starts. * @param inLen the length of the data to be processed. * @return the result of the RSA process. * @throws DataLengthException the input block is too large. */ public byte[] processBlock( byte[] in, int inOff, int inLen) { BigInteger msg = core.convertInput(in, inOff, inLen); if (forEncryption) { msg = blindMessage(msg); } else { msg = unblindMessage(msg); } return core.convertOutput(msg); } /* * Blind message with the blind factor. */ private BigInteger blindMessage( BigInteger msg) { BigInteger blindMsg = blindingFactor; blindMsg = msg.multiply(blindMsg.modPow(key.getExponent(), key.getModulus())); blindMsg = blindMsg.mod(key.getModulus()); return blindMsg; } /* * Unblind the message blinded with the blind factor. */ private BigInteger unblindMessage( BigInteger blindedMsg) { BigInteger m = key.getModulus(); BigInteger msg = blindedMsg; BigInteger blindFactorInverse = blindingFactor.modInverse(m); msg = msg.multiply(blindFactorInverse); msg = msg.mod(m); return msg; } } bouncycastle-1.49.orig/src/org/bouncycastle/crypto/engines/AESWrapEngine.java0000644000175000017500000000063710564225562026722 0ustar ebourgebourgpackage org.bouncycastle.crypto.engines; /** * an implementation of the AES Key Wrapper from the NIST Key Wrap * Specification. *

    * For further details see: http://csrc.nist.gov/encryption/kms/key-wrap.pdf. */ public class AESWrapEngine extends RFC3394WrapEngine { public AESWrapEngine() { super(new AESEngine()); } } bouncycastle-1.49.orig/src/org/bouncycastle/crypto/engines/package.html0000644000175000017500000000010610262753175025740 0ustar ebourgebourg Basic cipher classes. bouncycastle-1.49.orig/src/org/bouncycastle/crypto/engines/AESEngine.java0000644000175000017500000006455712106327653026101 0ustar ebourgebourgpackage org.bouncycastle.crypto.engines; import org.bouncycastle.crypto.BlockCipher; import org.bouncycastle.crypto.CipherParameters; import org.bouncycastle.crypto.DataLengthException; import org.bouncycastle.crypto.OutputLengthException; import org.bouncycastle.crypto.params.KeyParameter; /** * an implementation of the AES (Rijndael), from FIPS-197. *

    * For further details see: http://csrc.nist.gov/encryption/aes/. * * This implementation is based on optimizations from Dr. Brian Gladman's paper and C code at * http://fp.gladman.plus.com/cryptography_technology/rijndael/ * * There are three levels of tradeoff of speed vs memory * Because java has no preprocessor, they are written as three separate classes from which to choose * * The fastest uses 8Kbytes of static tables to precompute round calculations, 4 256 word tables for encryption * and 4 for decryption. * * The middle performance version uses only one 256 word table for each, for a total of 2Kbytes, * adding 12 rotate operations per round to compute the values contained in the other tables from * the contents of the first. * * The slowest version uses no static tables at all and computes the values in each round. *

    * This file contains the middle performance version with 2Kbytes of static tables for round precomputation. * */ public class AESEngine implements BlockCipher { // The S box private static final byte[] S = { (byte)99, (byte)124, (byte)119, (byte)123, (byte)242, (byte)107, (byte)111, (byte)197, (byte)48, (byte)1, (byte)103, (byte)43, (byte)254, (byte)215, (byte)171, (byte)118, (byte)202, (byte)130, (byte)201, (byte)125, (byte)250, (byte)89, (byte)71, (byte)240, (byte)173, (byte)212, (byte)162, (byte)175, (byte)156, (byte)164, (byte)114, (byte)192, (byte)183, (byte)253, (byte)147, (byte)38, (byte)54, (byte)63, (byte)247, (byte)204, (byte)52, (byte)165, (byte)229, (byte)241, (byte)113, (byte)216, (byte)49, (byte)21, (byte)4, (byte)199, (byte)35, (byte)195, (byte)24, (byte)150, (byte)5, (byte)154, (byte)7, (byte)18, (byte)128, (byte)226, (byte)235, (byte)39, (byte)178, (byte)117, (byte)9, (byte)131, (byte)44, (byte)26, (byte)27, (byte)110, (byte)90, (byte)160, (byte)82, (byte)59, (byte)214, (byte)179, (byte)41, (byte)227, (byte)47, (byte)132, (byte)83, (byte)209, (byte)0, (byte)237, (byte)32, (byte)252, (byte)177, (byte)91, (byte)106, (byte)203, (byte)190, (byte)57, (byte)74, (byte)76, (byte)88, (byte)207, (byte)208, (byte)239, (byte)170, (byte)251, (byte)67, (byte)77, (byte)51, (byte)133, (byte)69, (byte)249, (byte)2, (byte)127, (byte)80, (byte)60, (byte)159, (byte)168, (byte)81, (byte)163, (byte)64, (byte)143, (byte)146, (byte)157, (byte)56, (byte)245, (byte)188, (byte)182, (byte)218, (byte)33, (byte)16, (byte)255, (byte)243, (byte)210, (byte)205, (byte)12, (byte)19, (byte)236, (byte)95, (byte)151, (byte)68, (byte)23, (byte)196, (byte)167, (byte)126, (byte)61, (byte)100, (byte)93, (byte)25, (byte)115, (byte)96, (byte)129, (byte)79, (byte)220, (byte)34, (byte)42, (byte)144, (byte)136, (byte)70, (byte)238, (byte)184, (byte)20, (byte)222, (byte)94, (byte)11, (byte)219, (byte)224, (byte)50, (byte)58, (byte)10, (byte)73, (byte)6, (byte)36, (byte)92, (byte)194, (byte)211, (byte)172, (byte)98, (byte)145, (byte)149, (byte)228, (byte)121, (byte)231, (byte)200, (byte)55, (byte)109, (byte)141, (byte)213, (byte)78, (byte)169, (byte)108, (byte)86, (byte)244, (byte)234, (byte)101, (byte)122, (byte)174, (byte)8, (byte)186, (byte)120, (byte)37, (byte)46, (byte)28, (byte)166, (byte)180, (byte)198, (byte)232, (byte)221, (byte)116, (byte)31, (byte)75, (byte)189, (byte)139, (byte)138, (byte)112, (byte)62, (byte)181, (byte)102, (byte)72, (byte)3, (byte)246, (byte)14, (byte)97, (byte)53, (byte)87, (byte)185, (byte)134, (byte)193, (byte)29, (byte)158, (byte)225, (byte)248, (byte)152, (byte)17, (byte)105, (byte)217, (byte)142, (byte)148, (byte)155, (byte)30, (byte)135, (byte)233, (byte)206, (byte)85, (byte)40, (byte)223, (byte)140, (byte)161, (byte)137, (byte)13, (byte)191, (byte)230, (byte)66, (byte)104, (byte)65, (byte)153, (byte)45, (byte)15, (byte)176, (byte)84, (byte)187, (byte)22, }; // The inverse S-box private static final byte[] Si = { (byte)82, (byte)9, (byte)106, (byte)213, (byte)48, (byte)54, (byte)165, (byte)56, (byte)191, (byte)64, (byte)163, (byte)158, (byte)129, (byte)243, (byte)215, (byte)251, (byte)124, (byte)227, (byte)57, (byte)130, (byte)155, (byte)47, (byte)255, (byte)135, (byte)52, (byte)142, (byte)67, (byte)68, (byte)196, (byte)222, (byte)233, (byte)203, (byte)84, (byte)123, (byte)148, (byte)50, (byte)166, (byte)194, (byte)35, (byte)61, (byte)238, (byte)76, (byte)149, (byte)11, (byte)66, (byte)250, (byte)195, (byte)78, (byte)8, (byte)46, (byte)161, (byte)102, (byte)40, (byte)217, (byte)36, (byte)178, (byte)118, (byte)91, (byte)162, (byte)73, (byte)109, (byte)139, (byte)209, (byte)37, (byte)114, (byte)248, (byte)246, (byte)100, (byte)134, (byte)104, (byte)152, (byte)22, (byte)212, (byte)164, (byte)92, (byte)204, (byte)93, (byte)101, (byte)182, (byte)146, (byte)108, (byte)112, (byte)72, (byte)80, (byte)253, (byte)237, (byte)185, (byte)218, (byte)94, (byte)21, (byte)70, (byte)87, (byte)167, (byte)141, (byte)157, (byte)132, (byte)144, (byte)216, (byte)171, (byte)0, (byte)140, (byte)188, (byte)211, (byte)10, (byte)247, (byte)228, (byte)88, (byte)5, (byte)184, (byte)179, (byte)69, (byte)6, (byte)208, (byte)44, (byte)30, (byte)143, (byte)202, (byte)63, (byte)15, (byte)2, (byte)193, (byte)175, (byte)189, (byte)3, (byte)1, (byte)19, (byte)138, (byte)107, (byte)58, (byte)145, (byte)17, (byte)65, (byte)79, (byte)103, (byte)220, (byte)234, (byte)151, (byte)242, (byte)207, (byte)206, (byte)240, (byte)180, (byte)230, (byte)115, (byte)150, (byte)172, (byte)116, (byte)34, (byte)231, (byte)173, (byte)53, (byte)133, (byte)226, (byte)249, (byte)55, (byte)232, (byte)28, (byte)117, (byte)223, (byte)110, (byte)71, (byte)241, (byte)26, (byte)113, (byte)29, (byte)41, (byte)197, (byte)137, (byte)111, (byte)183, (byte)98, (byte)14, (byte)170, (byte)24, (byte)190, (byte)27, (byte)252, (byte)86, (byte)62, (byte)75, (byte)198, (byte)210, (byte)121, (byte)32, (byte)154, (byte)219, (byte)192, (byte)254, (byte)120, (byte)205, (byte)90, (byte)244, (byte)31, (byte)221, (byte)168, (byte)51, (byte)136, (byte)7, (byte)199, (byte)49, (byte)177, (byte)18, (byte)16, (byte)89, (byte)39, (byte)128, (byte)236, (byte)95, (byte)96, (byte)81, (byte)127, (byte)169, (byte)25, (byte)181, (byte)74, (byte)13, (byte)45, (byte)229, (byte)122, (byte)159, (byte)147, (byte)201, (byte)156, (byte)239, (byte)160, (byte)224, (byte)59, (byte)77, (byte)174, (byte)42, (byte)245, (byte)176, (byte)200, (byte)235, (byte)187, (byte)60, (byte)131, (byte)83, (byte)153, (byte)97, (byte)23, (byte)43, (byte)4, (byte)126, (byte)186, (byte)119, (byte)214, (byte)38, (byte)225, (byte)105, (byte)20, (byte)99, (byte)85, (byte)33, (byte)12, (byte)125, }; // vector used in calculating key schedule (powers of x in GF(256)) private static final int[] rcon = { 0x01, 0x02, 0x04, 0x08, 0x10, 0x20, 0x40, 0x80, 0x1b, 0x36, 0x6c, 0xd8, 0xab, 0x4d, 0x9a, 0x2f, 0x5e, 0xbc, 0x63, 0xc6, 0x97, 0x35, 0x6a, 0xd4, 0xb3, 0x7d, 0xfa, 0xef, 0xc5, 0x91 }; // precomputation tables of calculations for rounds private static final int[] T0 = { 0xa56363c6, 0x847c7cf8, 0x997777ee, 0x8d7b7bf6, 0x0df2f2ff, 0xbd6b6bd6, 0xb16f6fde, 0x54c5c591, 0x50303060, 0x03010102, 0xa96767ce, 0x7d2b2b56, 0x19fefee7, 0x62d7d7b5, 0xe6abab4d, 0x9a7676ec, 0x45caca8f, 0x9d82821f, 0x40c9c989, 0x877d7dfa, 0x15fafaef, 0xeb5959b2, 0xc947478e, 0x0bf0f0fb, 0xecadad41, 0x67d4d4b3, 0xfda2a25f, 0xeaafaf45, 0xbf9c9c23, 0xf7a4a453, 0x967272e4, 0x5bc0c09b, 0xc2b7b775, 0x1cfdfde1, 0xae93933d, 0x6a26264c, 0x5a36366c, 0x413f3f7e, 0x02f7f7f5, 0x4fcccc83, 0x5c343468, 0xf4a5a551, 0x34e5e5d1, 0x08f1f1f9, 0x937171e2, 0x73d8d8ab, 0x53313162, 0x3f15152a, 0x0c040408, 0x52c7c795, 0x65232346, 0x5ec3c39d, 0x28181830, 0xa1969637, 0x0f05050a, 0xb59a9a2f, 0x0907070e, 0x36121224, 0x9b80801b, 0x3de2e2df, 0x26ebebcd, 0x6927274e, 0xcdb2b27f, 0x9f7575ea, 0x1b090912, 0x9e83831d, 0x742c2c58, 0x2e1a1a34, 0x2d1b1b36, 0xb26e6edc, 0xee5a5ab4, 0xfba0a05b, 0xf65252a4, 0x4d3b3b76, 0x61d6d6b7, 0xceb3b37d, 0x7b292952, 0x3ee3e3dd, 0x712f2f5e, 0x97848413, 0xf55353a6, 0x68d1d1b9, 0x00000000, 0x2cededc1, 0x60202040, 0x1ffcfce3, 0xc8b1b179, 0xed5b5bb6, 0xbe6a6ad4, 0x46cbcb8d, 0xd9bebe67, 0x4b393972, 0xde4a4a94, 0xd44c4c98, 0xe85858b0, 0x4acfcf85, 0x6bd0d0bb, 0x2aefefc5, 0xe5aaaa4f, 0x16fbfbed, 0xc5434386, 0xd74d4d9a, 0x55333366, 0x94858511, 0xcf45458a, 0x10f9f9e9, 0x06020204, 0x817f7ffe, 0xf05050a0, 0x443c3c78, 0xba9f9f25, 0xe3a8a84b, 0xf35151a2, 0xfea3a35d, 0xc0404080, 0x8a8f8f05, 0xad92923f, 0xbc9d9d21, 0x48383870, 0x04f5f5f1, 0xdfbcbc63, 0xc1b6b677, 0x75dadaaf, 0x63212142, 0x30101020, 0x1affffe5, 0x0ef3f3fd, 0x6dd2d2bf, 0x4ccdcd81, 0x140c0c18, 0x35131326, 0x2fececc3, 0xe15f5fbe, 0xa2979735, 0xcc444488, 0x3917172e, 0x57c4c493, 0xf2a7a755, 0x827e7efc, 0x473d3d7a, 0xac6464c8, 0xe75d5dba, 0x2b191932, 0x957373e6, 0xa06060c0, 0x98818119, 0xd14f4f9e, 0x7fdcdca3, 0x66222244, 0x7e2a2a54, 0xab90903b, 0x8388880b, 0xca46468c, 0x29eeeec7, 0xd3b8b86b, 0x3c141428, 0x79dedea7, 0xe25e5ebc, 0x1d0b0b16, 0x76dbdbad, 0x3be0e0db, 0x56323264, 0x4e3a3a74, 0x1e0a0a14, 0xdb494992, 0x0a06060c, 0x6c242448, 0xe45c5cb8, 0x5dc2c29f, 0x6ed3d3bd, 0xefacac43, 0xa66262c4, 0xa8919139, 0xa4959531, 0x37e4e4d3, 0x8b7979f2, 0x32e7e7d5, 0x43c8c88b, 0x5937376e, 0xb76d6dda, 0x8c8d8d01, 0x64d5d5b1, 0xd24e4e9c, 0xe0a9a949, 0xb46c6cd8, 0xfa5656ac, 0x07f4f4f3, 0x25eaeacf, 0xaf6565ca, 0x8e7a7af4, 0xe9aeae47, 0x18080810, 0xd5baba6f, 0x887878f0, 0x6f25254a, 0x722e2e5c, 0x241c1c38, 0xf1a6a657, 0xc7b4b473, 0x51c6c697, 0x23e8e8cb, 0x7cdddda1, 0x9c7474e8, 0x211f1f3e, 0xdd4b4b96, 0xdcbdbd61, 0x868b8b0d, 0x858a8a0f, 0x907070e0, 0x423e3e7c, 0xc4b5b571, 0xaa6666cc, 0xd8484890, 0x05030306, 0x01f6f6f7, 0x120e0e1c, 0xa36161c2, 0x5f35356a, 0xf95757ae, 0xd0b9b969, 0x91868617, 0x58c1c199, 0x271d1d3a, 0xb99e9e27, 0x38e1e1d9, 0x13f8f8eb, 0xb398982b, 0x33111122, 0xbb6969d2, 0x70d9d9a9, 0x898e8e07, 0xa7949433, 0xb69b9b2d, 0x221e1e3c, 0x92878715, 0x20e9e9c9, 0x49cece87, 0xff5555aa, 0x78282850, 0x7adfdfa5, 0x8f8c8c03, 0xf8a1a159, 0x80898909, 0x170d0d1a, 0xdabfbf65, 0x31e6e6d7, 0xc6424284, 0xb86868d0, 0xc3414182, 0xb0999929, 0x772d2d5a, 0x110f0f1e, 0xcbb0b07b, 0xfc5454a8, 0xd6bbbb6d, 0x3a16162c}; private static final int[] Tinv0 = { 0x50a7f451, 0x5365417e, 0xc3a4171a, 0x965e273a, 0xcb6bab3b, 0xf1459d1f, 0xab58faac, 0x9303e34b, 0x55fa3020, 0xf66d76ad, 0x9176cc88, 0x254c02f5, 0xfcd7e54f, 0xd7cb2ac5, 0x80443526, 0x8fa362b5, 0x495ab1de, 0x671bba25, 0x980eea45, 0xe1c0fe5d, 0x02752fc3, 0x12f04c81, 0xa397468d, 0xc6f9d36b, 0xe75f8f03, 0x959c9215, 0xeb7a6dbf, 0xda595295, 0x2d83bed4, 0xd3217458, 0x2969e049, 0x44c8c98e, 0x6a89c275, 0x78798ef4, 0x6b3e5899, 0xdd71b927, 0xb64fe1be, 0x17ad88f0, 0x66ac20c9, 0xb43ace7d, 0x184adf63, 0x82311ae5, 0x60335197, 0x457f5362, 0xe07764b1, 0x84ae6bbb, 0x1ca081fe, 0x942b08f9, 0x58684870, 0x19fd458f, 0x876cde94, 0xb7f87b52, 0x23d373ab, 0xe2024b72, 0x578f1fe3, 0x2aab5566, 0x0728ebb2, 0x03c2b52f, 0x9a7bc586, 0xa50837d3, 0xf2872830, 0xb2a5bf23, 0xba6a0302, 0x5c8216ed, 0x2b1ccf8a, 0x92b479a7, 0xf0f207f3, 0xa1e2694e, 0xcdf4da65, 0xd5be0506, 0x1f6234d1, 0x8afea6c4, 0x9d532e34, 0xa055f3a2, 0x32e18a05, 0x75ebf6a4, 0x39ec830b, 0xaaef6040, 0x069f715e, 0x51106ebd, 0xf98a213e, 0x3d06dd96, 0xae053edd, 0x46bde64d, 0xb58d5491, 0x055dc471, 0x6fd40604, 0xff155060, 0x24fb9819, 0x97e9bdd6, 0xcc434089, 0x779ed967, 0xbd42e8b0, 0x888b8907, 0x385b19e7, 0xdbeec879, 0x470a7ca1, 0xe90f427c, 0xc91e84f8, 0x00000000, 0x83868009, 0x48ed2b32, 0xac70111e, 0x4e725a6c, 0xfbff0efd, 0x5638850f, 0x1ed5ae3d, 0x27392d36, 0x64d90f0a, 0x21a65c68, 0xd1545b9b, 0x3a2e3624, 0xb1670a0c, 0x0fe75793, 0xd296eeb4, 0x9e919b1b, 0x4fc5c080, 0xa220dc61, 0x694b775a, 0x161a121c, 0x0aba93e2, 0xe52aa0c0, 0x43e0223c, 0x1d171b12, 0x0b0d090e, 0xadc78bf2, 0xb9a8b62d, 0xc8a91e14, 0x8519f157, 0x4c0775af, 0xbbdd99ee, 0xfd607fa3, 0x9f2601f7, 0xbcf5725c, 0xc53b6644, 0x347efb5b, 0x7629438b, 0xdcc623cb, 0x68fcedb6, 0x63f1e4b8, 0xcadc31d7, 0x10856342, 0x40229713, 0x2011c684, 0x7d244a85, 0xf83dbbd2, 0x1132f9ae, 0x6da129c7, 0x4b2f9e1d, 0xf330b2dc, 0xec52860d, 0xd0e3c177, 0x6c16b32b, 0x99b970a9, 0xfa489411, 0x2264e947, 0xc48cfca8, 0x1a3ff0a0, 0xd82c7d56, 0xef903322, 0xc74e4987, 0xc1d138d9, 0xfea2ca8c, 0x360bd498, 0xcf81f5a6, 0x28de7aa5, 0x268eb7da, 0xa4bfad3f, 0xe49d3a2c, 0x0d927850, 0x9bcc5f6a, 0x62467e54, 0xc2138df6, 0xe8b8d890, 0x5ef7392e, 0xf5afc382, 0xbe805d9f, 0x7c93d069, 0xa92dd56f, 0xb31225cf, 0x3b99acc8, 0xa77d1810, 0x6e639ce8, 0x7bbb3bdb, 0x097826cd, 0xf418596e, 0x01b79aec, 0xa89a4f83, 0x656e95e6, 0x7ee6ffaa, 0x08cfbc21, 0xe6e815ef, 0xd99be7ba, 0xce366f4a, 0xd4099fea, 0xd67cb029, 0xafb2a431, 0x31233f2a, 0x3094a5c6, 0xc066a235, 0x37bc4e74, 0xa6ca82fc, 0xb0d090e0, 0x15d8a733, 0x4a9804f1, 0xf7daec41, 0x0e50cd7f, 0x2ff69117, 0x8dd64d76, 0x4db0ef43, 0x544daacc, 0xdf0496e4, 0xe3b5d19e, 0x1b886a4c, 0xb81f2cc1, 0x7f516546, 0x04ea5e9d, 0x5d358c01, 0x737487fa, 0x2e410bfb, 0x5a1d67b3, 0x52d2db92, 0x335610e9, 0x1347d66d, 0x8c61d79a, 0x7a0ca137, 0x8e14f859, 0x893c13eb, 0xee27a9ce, 0x35c961b7, 0xede51ce1, 0x3cb1477a, 0x59dfd29c, 0x3f73f255, 0x79ce1418, 0xbf37c773, 0xeacdf753, 0x5baafd5f, 0x146f3ddf, 0x86db4478, 0x81f3afca, 0x3ec468b9, 0x2c342438, 0x5f40a3c2, 0x72c31d16, 0x0c25e2bc, 0x8b493c28, 0x41950dff, 0x7101a839, 0xdeb30c08, 0x9ce4b4d8, 0x90c15664, 0x6184cb7b, 0x70b632d5, 0x745c6c48, 0x4257b8d0}; private static int shift(int r, int shift) { return (r >>> shift) | (r << -shift); } /* multiply four bytes in GF(2^8) by 'x' {02} in parallel */ private static final int m1 = 0x80808080; private static final int m2 = 0x7f7f7f7f; private static final int m3 = 0x0000001b; private static int FFmulX(int x) { return (((x & m2) << 1) ^ (((x & m1) >>> 7) * m3)); } /* The following defines provide alternative definitions of FFmulX that might give improved performance if a fast 32-bit multiply is not available. private int FFmulX(int x) { int u = x & m1; u |= (u >> 1); return ((x & m2) << 1) ^ ((u >>> 3) | (u >>> 6)); } private static final int m4 = 0x1b1b1b1b; private int FFmulX(int x) { int u = x & m1; return ((x & m2) << 1) ^ ((u - (u >>> 7)) & m4); } */ private static int inv_mcol(int x) { int f2 = FFmulX(x); int f4 = FFmulX(f2); int f8 = FFmulX(f4); int f9 = x ^ f8; return f2 ^ f4 ^ f8 ^ shift(f2 ^ f9, 8) ^ shift(f4 ^ f9, 16) ^ shift(f9, 24); } private static int subWord(int x) { return (S[x&255]&255 | ((S[(x>>8)&255]&255)<<8) | ((S[(x>>16)&255]&255)<<16) | S[(x>>24)&255]<<24); } /** * Calculate the necessary round keys * The number of calculations depends on key size and block size * AES specified a fixed block size of 128 bits and key sizes 128/192/256 bits * This code is written assuming those are the only possible values */ private int[][] generateWorkingKey( byte[] key, boolean forEncryption) { int KC = key.length / 4; // key length in words int t; if (((KC != 4) && (KC != 6) && (KC != 8)) || ((KC * 4) != key.length)) { throw new IllegalArgumentException("Key length not 128/192/256 bits."); } ROUNDS = KC + 6; // This is not always true for the generalized Rijndael that allows larger block sizes int[][] W = new int[ROUNDS+1][4]; // 4 words in a block // // copy the key into the round key array // t = 0; int i = 0; while (i < key.length) { W[t >> 2][t & 3] = (key[i]&0xff) | ((key[i+1]&0xff) << 8) | ((key[i+2]&0xff) << 16) | (key[i+3] << 24); i+=4; t++; } // // while not enough round key material calculated // calculate new values // int k = (ROUNDS + 1) << 2; for (i = KC; (i < k); i++) { int temp = W[(i-1)>>2][(i-1)&3]; if ((i % KC) == 0) { temp = subWord(shift(temp, 8)) ^ rcon[(i / KC)-1]; } else if ((KC > 6) && ((i % KC) == 4)) { temp = subWord(temp); } W[i>>2][i&3] = W[(i - KC)>>2][(i-KC)&3] ^ temp; } if (!forEncryption) { for (int j = 1; j < ROUNDS; j++) { for (i = 0; i < 4; i++) { W[j][i] = inv_mcol(W[j][i]); } } } return W; } private int ROUNDS; private int[][] WorkingKey = null; private int C0, C1, C2, C3; private boolean forEncryption; private static final int BLOCK_SIZE = 16; /** * default constructor - 128 bit block size. */ public AESEngine() { } /** * initialise an AES cipher. * * @param forEncryption whether or not we are for encryption. * @param params the parameters required to set up the cipher. * @exception IllegalArgumentException if the params argument is * inappropriate. */ public void init( boolean forEncryption, CipherParameters params) { if (params instanceof KeyParameter) { WorkingKey = generateWorkingKey(((KeyParameter)params).getKey(), forEncryption); this.forEncryption = forEncryption; return; } throw new IllegalArgumentException("invalid parameter passed to AES init - " + params.getClass().getName()); } public String getAlgorithmName() { return "AES"; } public int getBlockSize() { return BLOCK_SIZE; } public int processBlock( byte[] in, int inOff, byte[] out, int outOff) { if (WorkingKey == null) { throw new IllegalStateException("AES engine not initialised"); } if ((inOff + (32 / 2)) > in.length) { throw new DataLengthException("input buffer too short"); } if ((outOff + (32 / 2)) > out.length) { throw new OutputLengthException("output buffer too short"); } if (forEncryption) { unpackBlock(in, inOff); encryptBlock(WorkingKey); packBlock(out, outOff); } else { unpackBlock(in, inOff); decryptBlock(WorkingKey); packBlock(out, outOff); } return BLOCK_SIZE; } public void reset() { } private void unpackBlock( byte[] bytes, int off) { int index = off; C0 = (bytes[index++] & 0xff); C0 |= (bytes[index++] & 0xff) << 8; C0 |= (bytes[index++] & 0xff) << 16; C0 |= bytes[index++] << 24; C1 = (bytes[index++] & 0xff); C1 |= (bytes[index++] & 0xff) << 8; C1 |= (bytes[index++] & 0xff) << 16; C1 |= bytes[index++] << 24; C2 = (bytes[index++] & 0xff); C2 |= (bytes[index++] & 0xff) << 8; C2 |= (bytes[index++] & 0xff) << 16; C2 |= bytes[index++] << 24; C3 = (bytes[index++] & 0xff); C3 |= (bytes[index++] & 0xff) << 8; C3 |= (bytes[index++] & 0xff) << 16; C3 |= bytes[index++] << 24; } private void packBlock( byte[] bytes, int off) { int index = off; bytes[index++] = (byte)C0; bytes[index++] = (byte)(C0 >> 8); bytes[index++] = (byte)(C0 >> 16); bytes[index++] = (byte)(C0 >> 24); bytes[index++] = (byte)C1; bytes[index++] = (byte)(C1 >> 8); bytes[index++] = (byte)(C1 >> 16); bytes[index++] = (byte)(C1 >> 24); bytes[index++] = (byte)C2; bytes[index++] = (byte)(C2 >> 8); bytes[index++] = (byte)(C2 >> 16); bytes[index++] = (byte)(C2 >> 24); bytes[index++] = (byte)C3; bytes[index++] = (byte)(C3 >> 8); bytes[index++] = (byte)(C3 >> 16); bytes[index++] = (byte)(C3 >> 24); } private void encryptBlock(int[][] KW) { int r, r0, r1, r2, r3; C0 ^= KW[0][0]; C1 ^= KW[0][1]; C2 ^= KW[0][2]; C3 ^= KW[0][3]; r = 1; while (r < ROUNDS - 1) { r0 = T0[C0&255] ^ shift(T0[(C1>>8)&255], 24) ^ shift(T0[(C2>>16)&255],16) ^ shift(T0[(C3>>24)&255],8) ^ KW[r][0]; r1 = T0[C1&255] ^ shift(T0[(C2>>8)&255], 24) ^ shift(T0[(C3>>16)&255], 16) ^ shift(T0[(C0>>24)&255], 8) ^ KW[r][1]; r2 = T0[C2&255] ^ shift(T0[(C3>>8)&255], 24) ^ shift(T0[(C0>>16)&255], 16) ^ shift(T0[(C1>>24)&255], 8) ^ KW[r][2]; r3 = T0[C3&255] ^ shift(T0[(C0>>8)&255], 24) ^ shift(T0[(C1>>16)&255], 16) ^ shift(T0[(C2>>24)&255], 8) ^ KW[r++][3]; C0 = T0[r0&255] ^ shift(T0[(r1>>8)&255], 24) ^ shift(T0[(r2>>16)&255], 16) ^ shift(T0[(r3>>24)&255], 8) ^ KW[r][0]; C1 = T0[r1&255] ^ shift(T0[(r2>>8)&255], 24) ^ shift(T0[(r3>>16)&255], 16) ^ shift(T0[(r0>>24)&255], 8) ^ KW[r][1]; C2 = T0[r2&255] ^ shift(T0[(r3>>8)&255], 24) ^ shift(T0[(r0>>16)&255], 16) ^ shift(T0[(r1>>24)&255], 8) ^ KW[r][2]; C3 = T0[r3&255] ^ shift(T0[(r0>>8)&255], 24) ^ shift(T0[(r1>>16)&255], 16) ^ shift(T0[(r2>>24)&255], 8) ^ KW[r++][3]; } r0 = T0[C0&255] ^ shift(T0[(C1>>8)&255], 24) ^ shift(T0[(C2>>16)&255], 16) ^ shift(T0[(C3>>24)&255], 8) ^ KW[r][0]; r1 = T0[C1&255] ^ shift(T0[(C2>>8)&255], 24) ^ shift(T0[(C3>>16)&255], 16) ^ shift(T0[(C0>>24)&255], 8) ^ KW[r][1]; r2 = T0[C2&255] ^ shift(T0[(C3>>8)&255], 24) ^ shift(T0[(C0>>16)&255], 16) ^ shift(T0[(C1>>24)&255], 8) ^ KW[r][2]; r3 = T0[C3&255] ^ shift(T0[(C0>>8)&255], 24) ^ shift(T0[(C1>>16)&255], 16) ^ shift(T0[(C2>>24)&255], 8) ^ KW[r++][3]; // the final round's table is a simple function of S so we don't use a whole other four tables for it C0 = (S[r0&255]&255) ^ ((S[(r1>>8)&255]&255)<<8) ^ ((S[(r2>>16)&255]&255)<<16) ^ (S[(r3>>24)&255]<<24) ^ KW[r][0]; C1 = (S[r1&255]&255) ^ ((S[(r2>>8)&255]&255)<<8) ^ ((S[(r3>>16)&255]&255)<<16) ^ (S[(r0>>24)&255]<<24) ^ KW[r][1]; C2 = (S[r2&255]&255) ^ ((S[(r3>>8)&255]&255)<<8) ^ ((S[(r0>>16)&255]&255)<<16) ^ (S[(r1>>24)&255]<<24) ^ KW[r][2]; C3 = (S[r3&255]&255) ^ ((S[(r0>>8)&255]&255)<<8) ^ ((S[(r1>>16)&255]&255)<<16) ^ (S[(r2>>24)&255]<<24) ^ KW[r][3]; } private void decryptBlock(int[][] KW) { int r, r0, r1, r2, r3; C0 ^= KW[ROUNDS][0]; C1 ^= KW[ROUNDS][1]; C2 ^= KW[ROUNDS][2]; C3 ^= KW[ROUNDS][3]; r = ROUNDS-1; while (r>1) { r0 = Tinv0[C0&255] ^ shift(Tinv0[(C3>>8)&255], 24) ^ shift(Tinv0[(C2>>16)&255], 16) ^ shift(Tinv0[(C1>>24)&255], 8) ^ KW[r][0]; r1 = Tinv0[C1&255] ^ shift(Tinv0[(C0>>8)&255], 24) ^ shift(Tinv0[(C3>>16)&255], 16) ^ shift(Tinv0[(C2>>24)&255], 8) ^ KW[r][1]; r2 = Tinv0[C2&255] ^ shift(Tinv0[(C1>>8)&255], 24) ^ shift(Tinv0[(C0>>16)&255], 16) ^ shift(Tinv0[(C3>>24)&255], 8) ^ KW[r][2]; r3 = Tinv0[C3&255] ^ shift(Tinv0[(C2>>8)&255], 24) ^ shift(Tinv0[(C1>>16)&255], 16) ^ shift(Tinv0[(C0>>24)&255], 8) ^ KW[r--][3]; C0 = Tinv0[r0&255] ^ shift(Tinv0[(r3>>8)&255], 24) ^ shift(Tinv0[(r2>>16)&255], 16) ^ shift(Tinv0[(r1>>24)&255], 8) ^ KW[r][0]; C1 = Tinv0[r1&255] ^ shift(Tinv0[(r0>>8)&255], 24) ^ shift(Tinv0[(r3>>16)&255], 16) ^ shift(Tinv0[(r2>>24)&255], 8) ^ KW[r][1]; C2 = Tinv0[r2&255] ^ shift(Tinv0[(r1>>8)&255], 24) ^ shift(Tinv0[(r0>>16)&255], 16) ^ shift(Tinv0[(r3>>24)&255], 8) ^ KW[r][2]; C3 = Tinv0[r3&255] ^ shift(Tinv0[(r2>>8)&255], 24) ^ shift(Tinv0[(r1>>16)&255], 16) ^ shift(Tinv0[(r0>>24)&255], 8) ^ KW[r--][3]; } r0 = Tinv0[C0&255] ^ shift(Tinv0[(C3>>8)&255], 24) ^ shift(Tinv0[(C2>>16)&255], 16) ^ shift(Tinv0[(C1>>24)&255], 8) ^ KW[r][0]; r1 = Tinv0[C1&255] ^ shift(Tinv0[(C0>>8)&255], 24) ^ shift(Tinv0[(C3>>16)&255], 16) ^ shift(Tinv0[(C2>>24)&255], 8) ^ KW[r][1]; r2 = Tinv0[C2&255] ^ shift(Tinv0[(C1>>8)&255], 24) ^ shift(Tinv0[(C0>>16)&255], 16) ^ shift(Tinv0[(C3>>24)&255], 8) ^ KW[r][2]; r3 = Tinv0[C3&255] ^ shift(Tinv0[(C2>>8)&255], 24) ^ shift(Tinv0[(C1>>16)&255], 16) ^ shift(Tinv0[(C0>>24)&255], 8) ^ KW[r][3]; // the final round's table is a simple function of Si so we don't use a whole other four tables for it C0 = (Si[r0&255]&255) ^ ((Si[(r3>>8)&255]&255)<<8) ^ ((Si[(r2>>16)&255]&255)<<16) ^ (Si[(r1>>24)&255]<<24) ^ KW[0][0]; C1 = (Si[r1&255]&255) ^ ((Si[(r0>>8)&255]&255)<<8) ^ ((Si[(r3>>16)&255]&255)<<16) ^ (Si[(r2>>24)&255]<<24) ^ KW[0][1]; C2 = (Si[r2&255]&255) ^ ((Si[(r1>>8)&255]&255)<<8) ^ ((Si[(r0>>16)&255]&255)<<16) ^ (Si[(r3>>24)&255]<<24) ^ KW[0][2]; C3 = (Si[r3&255]&255) ^ ((Si[(r2>>8)&255]&255)<<8) ^ ((Si[(r1>>16)&255]&255)<<16) ^ (Si[(r0>>24)&255]<<24) ^ KW[0][3]; } } bouncycastle-1.49.orig/src/org/bouncycastle/crypto/engines/NullEngine.java0000644000175000017500000000443112106331021026344 0ustar ebourgebourgpackage org.bouncycastle.crypto.engines; import org.bouncycastle.crypto.BlockCipher; import org.bouncycastle.crypto.CipherParameters; import org.bouncycastle.crypto.DataLengthException; import org.bouncycastle.crypto.OutputLengthException; /** * The no-op engine that just copies bytes through, irrespective of whether encrypting and decrypting. * Provided for the sake of completeness. */ public class NullEngine implements BlockCipher { private boolean initialised; protected static final int BLOCK_SIZE = 1; /** * Standard constructor. */ public NullEngine() { super(); } /* (non-Javadoc) * @see org.bouncycastle.crypto.BlockCipher#init(boolean, org.bouncycastle.crypto.CipherParameters) */ public void init(boolean forEncryption, CipherParameters params) throws IllegalArgumentException { // we don't mind any parameters that may come in this.initialised = true; } /* (non-Javadoc) * @see org.bouncycastle.crypto.BlockCipher#getAlgorithmName() */ public String getAlgorithmName() { return "Null"; } /* (non-Javadoc) * @see org.bouncycastle.crypto.BlockCipher#getBlockSize() */ public int getBlockSize() { return BLOCK_SIZE; } /* (non-Javadoc) * @see org.bouncycastle.crypto.BlockCipher#processBlock(byte[], int, byte[], int) */ public int processBlock(byte[] in, int inOff, byte[] out, int outOff) throws DataLengthException, IllegalStateException { if (!initialised) { throw new IllegalStateException("Null engine not initialised"); } if ((inOff + BLOCK_SIZE) > in.length) { throw new DataLengthException("input buffer too short"); } if ((outOff + BLOCK_SIZE) > out.length) { throw new OutputLengthException("output buffer too short"); } for (int i = 0; i < BLOCK_SIZE; ++i) { out[outOff + i] = in[inOff + i]; } return BLOCK_SIZE; } /* (non-Javadoc) * @see org.bouncycastle.crypto.BlockCipher#reset() */ public void reset() { // nothing needs to be done } } bouncycastle-1.49.orig/src/org/bouncycastle/crypto/EphemeralKeyPair.java0000644000175000017500000000103612033455513026055 0ustar ebourgebourgpackage org.bouncycastle.crypto; public class EphemeralKeyPair { private AsymmetricCipherKeyPair keyPair; private KeyEncoder publicKeyEncoder; public EphemeralKeyPair(AsymmetricCipherKeyPair keyPair, KeyEncoder publicKeyEncoder) { this.keyPair = keyPair; this.publicKeyEncoder = publicKeyEncoder; } public AsymmetricCipherKeyPair getKeyPair() { return keyPair; } public byte[] getEncodedPublicKey() { return publicKeyEncoder.getEncoded(keyPair.getPublic()); } } bouncycastle-1.49.orig/src/org/bouncycastle/crypto/OutputLengthException.java0000644000175000017500000000026612103433540027205 0ustar ebourgebourgpackage org.bouncycastle.crypto; public class OutputLengthException extends DataLengthException { public OutputLengthException(String msg) { super(msg); } } bouncycastle-1.49.orig/src/org/bouncycastle/crypto/commitments/0000755000175000017500000000000012152033551024356 5ustar ebourgebourgbouncycastle-1.49.orig/src/org/bouncycastle/crypto/commitments/HashCommitter.java0000644000175000017500000000513212150003626027767 0ustar ebourgebourgpackage org.bouncycastle.crypto.commitments; import java.security.SecureRandom; import org.bouncycastle.crypto.Commitment; import org.bouncycastle.crypto.Committer; import org.bouncycastle.crypto.DataLengthException; import org.bouncycastle.crypto.Digest; import org.bouncycastle.crypto.ExtendedDigest; import org.bouncycastle.util.Arrays; /** * A basic hash-committer as described in "Making Mix Nets Robust for Electronic Voting by Randomized Partial Checking", * by Jakobsson, Juels, and Rivest (11th Usenix Security Symposium, 2002). */ public class HashCommitter implements Committer { private final Digest digest; private final int byteLength; private final SecureRandom random; /** * Base Constructor. The maximum message length that can be committed to is half the length of the internal * block size for the digest (ExtendedDigest.getBlockLength()). * * @param digest digest to use for creating commitments. * @param random source of randomness for generating secrets. */ public HashCommitter(ExtendedDigest digest, SecureRandom random) { this.digest = digest; this.byteLength = digest.getByteLength(); this.random = random; } /** * Generate a commitment for the passed in message. * * @param message the message to be committed to, * @return a Commitment */ public Commitment commit(byte[] message) { if (message.length > byteLength / 2) { throw new DataLengthException("Message to be committed to too large for digest."); } byte[] w = new byte[byteLength - message.length]; random.nextBytes(w); return new Commitment(w, calculateCommitment(w, message)); } /** * Return true if the passed in commitment represents a commitment to the passed in maessage. * * @param commitment a commitment previously generated. * @param message the message that was expected to have been committed to. * @return true if commitment matches message, false otherwise. */ public boolean isRevealed(Commitment commitment, byte[] message) { byte[] calcCommitment = calculateCommitment(commitment.getSecret(), message); return Arrays.constantTimeAreEqual(commitment.getCommitment(), calcCommitment); } private byte[] calculateCommitment(byte[] w, byte[] message) { byte[] commitment = new byte[digest.getDigestSize()]; digest.update(w, 0, w.length); digest.update(message, 0, message.length); digest.doFinal(commitment, 0); return commitment; } } bouncycastle-1.49.orig/src/org/bouncycastle/crypto/commitments/package.html0000644000175000017500000000010712151566574026654 0ustar ebourgebourg Commitment algorithms. bouncycastle-1.49.orig/src/org/bouncycastle/crypto/package.html0000644000175000017500000000012610262753175024312 0ustar ebourgebourg Base classes for the lightweight API. bouncycastle-1.49.orig/src/org/bouncycastle/crypto/Committer.java0000644000175000017500000000134112150001736024622 0ustar ebourgebourgpackage org.bouncycastle.crypto; /** * General interface fdr classes that produce and validate commitments. */ public interface Committer { /** * Generate a commitment for the passed in message. * * @param message the message to be committed to, * @return a Commitment */ Commitment commit(byte[] message); /** * Return true if the passed in commitment represents a commitment to the passed in maessage. * * @param commitment a commitment previously generated. * @param message the message that was expected to have been committed to. * @return true if commitment matches message, false otherwise. */ boolean isRevealed(Commitment commitment, byte[] message); } bouncycastle-1.49.orig/src/org/bouncycastle/asn1/0000755000175000017500000000000012152033551021341 5ustar ebourgebourgbouncycastle-1.49.orig/src/org/bouncycastle/asn1/DERIA5String.java0000644000175000017500000001016412062243165024312 0ustar ebourgebourgpackage org.bouncycastle.asn1; import java.io.IOException; import org.bouncycastle.util.Arrays; import org.bouncycastle.util.Strings; /** * DER IA5String object - this is an ascii string. */ public class DERIA5String extends ASN1Primitive implements ASN1String { private byte[] string; /** * return a IA5 string from the passed in object * * @exception IllegalArgumentException if the object cannot be converted. */ public static DERIA5String getInstance( Object obj) { if (obj == null || obj instanceof DERIA5String) { return (DERIA5String)obj; } if (obj instanceof byte[]) { try { return (DERIA5String)fromByteArray((byte[])obj); } catch (Exception e) { throw new IllegalArgumentException("encoding error in getInstance: " + e.toString()); } } throw new IllegalArgumentException("illegal object in getInstance: " + obj.getClass().getName()); } /** * return an IA5 String from a tagged object. * * @param obj the tagged object holding the object we want * @param explicit true if the object is meant to be explicitly * tagged false otherwise. * @exception IllegalArgumentException if the tagged object cannot * be converted. */ public static DERIA5String getInstance( ASN1TaggedObject obj, boolean explicit) { ASN1Primitive o = obj.getObject(); if (explicit || o instanceof DERIA5String) { return getInstance(o); } else { return new DERIA5String(((ASN1OctetString)o).getOctets()); } } /** * basic constructor - with bytes. */ DERIA5String( byte[] string) { this.string = string; } /** * basic constructor - without validation. */ public DERIA5String( String string) { this(string, false); } /** * Constructor with optional validation. * * @param string the base string to wrap. * @param validate whether or not to check the string. * @throws IllegalArgumentException if validate is true and the string * contains characters that should not be in an IA5String. */ public DERIA5String( String string, boolean validate) { if (string == null) { throw new NullPointerException("string cannot be null"); } if (validate && !isIA5String(string)) { throw new IllegalArgumentException("string contains illegal characters"); } this.string = Strings.toByteArray(string); } public String getString() { return Strings.fromByteArray(string); } public String toString() { return getString(); } public byte[] getOctets() { return Arrays.clone(string); } boolean isConstructed() { return false; } int encodedLength() { return 1 + StreamUtil.calculateBodyLength(string.length) + string.length; } void encode( ASN1OutputStream out) throws IOException { out.writeEncoded(BERTags.IA5_STRING, string); } public int hashCode() { return Arrays.hashCode(string); } boolean asn1Equals( ASN1Primitive o) { if (!(o instanceof DERIA5String)) { return false; } DERIA5String s = (DERIA5String)o; return Arrays.areEqual(string, s.string); } /** * return true if the passed in String can be represented without * loss as an IA5String, false otherwise. * * @return true if in printable set, false otherwise. */ public static boolean isIA5String( String str) { for (int i = str.length() - 1; i >= 0; i--) { char ch = str.charAt(i); if (ch > 0x007f) { return false; } } return true; } } bouncycastle-1.49.orig/src/org/bouncycastle/asn1/BERConstructedOctetString.java0000644000175000017500000000621311676500665027241 0ustar ebourgebourgpackage org.bouncycastle.asn1; import java.io.ByteArrayOutputStream; import java.io.IOException; import java.util.Enumeration; import java.util.Vector; /** * @deprecated use BEROctetString */ public class BERConstructedOctetString extends BEROctetString { private static final int MAX_LENGTH = 1000; /** * convert a vector of octet strings into a single byte string */ static private byte[] toBytes( Vector octs) { ByteArrayOutputStream bOut = new ByteArrayOutputStream(); for (int i = 0; i != octs.size(); i++) { try { DEROctetString o = (DEROctetString)octs.elementAt(i); bOut.write(o.getOctets()); } catch (ClassCastException e) { throw new IllegalArgumentException(octs.elementAt(i).getClass().getName() + " found in input should only contain DEROctetString"); } catch (IOException e) { throw new IllegalArgumentException("exception converting octets " + e.toString()); } } return bOut.toByteArray(); } private Vector octs; /** * @param string the octets making up the octet string. */ public BERConstructedOctetString( byte[] string) { super(string); } public BERConstructedOctetString( Vector octs) { super(toBytes(octs)); this.octs = octs; } public BERConstructedOctetString( ASN1Primitive obj) { super(toByteArray(obj)); } private static byte[] toByteArray(ASN1Primitive obj) { try { return obj.getEncoded(); } catch (IOException e) { throw new IllegalArgumentException("Unable to encode object"); } } public BERConstructedOctetString( ASN1Encodable obj) { this(obj.toASN1Primitive()); } public byte[] getOctets() { return string; } /** * return the DER octets that make up this string. */ public Enumeration getObjects() { if (octs == null) { return generateOcts().elements(); } return octs.elements(); } private Vector generateOcts() { Vector vec = new Vector(); for (int i = 0; i < string.length; i += MAX_LENGTH) { int end; if (i + MAX_LENGTH > string.length) { end = string.length; } else { end = i + MAX_LENGTH; } byte[] nStr = new byte[end - i]; System.arraycopy(string, i, nStr, 0, nStr.length); vec.addElement(new DEROctetString(nStr)); } return vec; } public static BEROctetString fromSequence(ASN1Sequence seq) { Vector v = new Vector(); Enumeration e = seq.getObjects(); while (e.hasMoreElements()) { v.addElement(e.nextElement()); } return new BERConstructedOctetString(v); } } bouncycastle-1.49.orig/src/org/bouncycastle/asn1/DERUniversalString.java0000644000175000017500000000710412062243040025674 0ustar ebourgebourgpackage org.bouncycastle.asn1; import java.io.ByteArrayOutputStream; import java.io.IOException; import org.bouncycastle.util.Arrays; /** * DER UniversalString object. */ public class DERUniversalString extends ASN1Primitive implements ASN1String { private static final char[] table = { '0', '1', '2', '3', '4', '5', '6', '7', '8', '9', 'A', 'B', 'C', 'D', 'E', 'F' }; private byte[] string; /** * return a Universal String from the passed in object. * * @exception IllegalArgumentException if the object cannot be converted. */ public static DERUniversalString getInstance( Object obj) { if (obj == null || obj instanceof DERUniversalString) { return (DERUniversalString)obj; } if (obj instanceof byte[]) { try { return (DERUniversalString)fromByteArray((byte[])obj); } catch (Exception e) { throw new IllegalArgumentException("encoding error getInstance: " + e.toString()); } } throw new IllegalArgumentException("illegal object in getInstance: " + obj.getClass().getName()); } /** * return a Universal String from a tagged object. * * @param obj the tagged object holding the object we want * @param explicit true if the object is meant to be explicitly * tagged false otherwise. * @exception IllegalArgumentException if the tagged object cannot * be converted. */ public static DERUniversalString getInstance( ASN1TaggedObject obj, boolean explicit) { ASN1Primitive o = obj.getObject(); if (explicit || o instanceof DERUniversalString) { return getInstance(o); } else { return new DERUniversalString(((ASN1OctetString)o).getOctets()); } } /** * basic constructor - byte encoded string. */ public DERUniversalString( byte[] string) { this.string = string; } public String getString() { StringBuffer buf = new StringBuffer("#"); ByteArrayOutputStream bOut = new ByteArrayOutputStream(); ASN1OutputStream aOut = new ASN1OutputStream(bOut); try { aOut.writeObject(this); } catch (IOException e) { throw new RuntimeException("internal error encoding BitString"); } byte[] string = bOut.toByteArray(); for (int i = 0; i != string.length; i++) { buf.append(table[(string[i] >>> 4) & 0xf]); buf.append(table[string[i] & 0xf]); } return buf.toString(); } public String toString() { return getString(); } public byte[] getOctets() { return string; } boolean isConstructed() { return false; } int encodedLength() { return 1 + StreamUtil.calculateBodyLength(string.length) + string.length; } void encode( ASN1OutputStream out) throws IOException { out.writeEncoded(BERTags.UNIVERSAL_STRING, this.getOctets()); } boolean asn1Equals( ASN1Primitive o) { if (!(o instanceof DERUniversalString)) { return false; } return Arrays.areEqual(string, ((DERUniversalString)o).string); } public int hashCode() { return Arrays.hashCode(string); } } bouncycastle-1.49.orig/src/org/bouncycastle/asn1/DLOutputStream.java0000644000175000017500000000112211703154552025102 0ustar ebourgebourgpackage org.bouncycastle.asn1; import java.io.IOException; import java.io.OutputStream; /** * Stream that outputs encoding based on definite length. */ public class DLOutputStream extends ASN1OutputStream { public DLOutputStream( OutputStream os) { super(os); } public void writeObject( ASN1Encodable obj) throws IOException { if (obj != null) { obj.toASN1Primitive().toDLObject().encode(this); } else { throw new IOException("null object detected"); } } } bouncycastle-1.49.orig/src/org/bouncycastle/asn1/smime/0000755000175000017500000000000012152033551022453 5ustar ebourgebourgbouncycastle-1.49.orig/src/org/bouncycastle/asn1/smime/SMIMECapabilities.java0000644000175000017500000000646411624652565026533 0ustar ebourgebourgpackage org.bouncycastle.asn1.smime; import java.util.Enumeration; import java.util.Vector; import org.bouncycastle.asn1.ASN1Object; import org.bouncycastle.asn1.ASN1ObjectIdentifier; import org.bouncycastle.asn1.ASN1Primitive; import org.bouncycastle.asn1.ASN1Sequence; import org.bouncycastle.asn1.cms.Attribute; import org.bouncycastle.asn1.pkcs.PKCSObjectIdentifiers; /** * Handler class for dealing with S/MIME Capabilities */ public class SMIMECapabilities extends ASN1Object { /** * general preferences */ public static final ASN1ObjectIdentifier preferSignedData = PKCSObjectIdentifiers.preferSignedData; public static final ASN1ObjectIdentifier canNotDecryptAny = PKCSObjectIdentifiers.canNotDecryptAny; public static final ASN1ObjectIdentifier sMIMECapabilitesVersions = PKCSObjectIdentifiers.sMIMECapabilitiesVersions; /** * encryption algorithms preferences */ public static final ASN1ObjectIdentifier dES_CBC = new ASN1ObjectIdentifier("1.3.14.3.2.7"); public static final ASN1ObjectIdentifier dES_EDE3_CBC = PKCSObjectIdentifiers.des_EDE3_CBC; public static final ASN1ObjectIdentifier rC2_CBC = PKCSObjectIdentifiers.RC2_CBC; private ASN1Sequence capabilities; /** * return an Attribute object from the given object. * * @param o the object we want converted. * @exception IllegalArgumentException if the object cannot be converted. */ public static SMIMECapabilities getInstance( Object o) { if (o == null || o instanceof SMIMECapabilities) { return (SMIMECapabilities)o; } if (o instanceof ASN1Sequence) { return new SMIMECapabilities((ASN1Sequence)o); } if (o instanceof Attribute) { return new SMIMECapabilities( (ASN1Sequence)(((Attribute)o).getAttrValues().getObjectAt(0))); } throw new IllegalArgumentException("unknown object in factory: " + o.getClass().getName()); } public SMIMECapabilities( ASN1Sequence seq) { capabilities = seq; } /** * returns a vector with 0 or more objects of all the capabilities * matching the passed in capability OID. If the OID passed is null the * entire set is returned. */ public Vector getCapabilities( ASN1ObjectIdentifier capability) { Enumeration e = capabilities.getObjects(); Vector list = new Vector(); if (capability == null) { while (e.hasMoreElements()) { SMIMECapability cap = SMIMECapability.getInstance(e.nextElement()); list.addElement(cap); } } else { while (e.hasMoreElements()) { SMIMECapability cap = SMIMECapability.getInstance(e.nextElement()); if (capability.equals(cap.getCapabilityID())) { list.addElement(cap); } } } return list; } /** * Produce an object suitable for an ASN1OutputStream. *

         * SMIMECapabilities ::= SEQUENCE OF SMIMECapability
         * 
    */ public ASN1Primitive toASN1Primitive() { return capabilities; } } bouncycastle-1.49.orig/src/org/bouncycastle/asn1/smime/SMIMEEncryptionKeyPreferenceAttribute.java0000644000175000017500000000265211624622715032615 0ustar ebourgebourgpackage org.bouncycastle.asn1.smime; import org.bouncycastle.asn1.ASN1OctetString; import org.bouncycastle.asn1.DERSet; import org.bouncycastle.asn1.DERTaggedObject; import org.bouncycastle.asn1.cms.Attribute; import org.bouncycastle.asn1.cms.IssuerAndSerialNumber; import org.bouncycastle.asn1.cms.RecipientKeyIdentifier; /** * The SMIMEEncryptionKeyPreference object. *
     * SMIMEEncryptionKeyPreference ::= CHOICE {
     *     issuerAndSerialNumber   [0] IssuerAndSerialNumber,
     *     receipentKeyId          [1] RecipientKeyIdentifier,
     *     subjectAltKeyIdentifier [2] SubjectKeyIdentifier
     * }
     * 
    */ public class SMIMEEncryptionKeyPreferenceAttribute extends Attribute { public SMIMEEncryptionKeyPreferenceAttribute( IssuerAndSerialNumber issAndSer) { super(SMIMEAttributes.encrypKeyPref, new DERSet(new DERTaggedObject(false, 0, issAndSer))); } public SMIMEEncryptionKeyPreferenceAttribute( RecipientKeyIdentifier rKeyId) { super(SMIMEAttributes.encrypKeyPref, new DERSet(new DERTaggedObject(false, 1, rKeyId))); } /** * @param sKeyId the subjectKeyIdentifier value (normally the X.509 one) */ public SMIMEEncryptionKeyPreferenceAttribute( ASN1OctetString sKeyId) { super(SMIMEAttributes.encrypKeyPref, new DERSet(new DERTaggedObject(false, 2, sKeyId))); } } bouncycastle-1.49.orig/src/org/bouncycastle/asn1/smime/SMIMECapabilityVector.java0000644000175000017500000000234111724561172027366 0ustar ebourgebourgpackage org.bouncycastle.asn1.smime; import org.bouncycastle.asn1.ASN1Encodable; import org.bouncycastle.asn1.ASN1EncodableVector; import org.bouncycastle.asn1.ASN1Integer; import org.bouncycastle.asn1.ASN1ObjectIdentifier; import org.bouncycastle.asn1.DERSequence; /** * Handler for creating a vector S/MIME Capabilities */ public class SMIMECapabilityVector { private ASN1EncodableVector capabilities = new ASN1EncodableVector(); public void addCapability( ASN1ObjectIdentifier capability) { capabilities.add(new DERSequence(capability)); } public void addCapability( ASN1ObjectIdentifier capability, int value) { ASN1EncodableVector v = new ASN1EncodableVector(); v.add(capability); v.add(new ASN1Integer(value)); capabilities.add(new DERSequence(v)); } public void addCapability( ASN1ObjectIdentifier capability, ASN1Encodable params) { ASN1EncodableVector v = new ASN1EncodableVector(); v.add(capability); v.add(params); capabilities.add(new DERSequence(v)); } public ASN1EncodableVector toASN1EncodableVector() { return capabilities; } } bouncycastle-1.49.orig/src/org/bouncycastle/asn1/smime/SMIMECapabilitiesAttribute.java0000644000175000017500000000071011624622715030375 0ustar ebourgebourgpackage org.bouncycastle.asn1.smime; import org.bouncycastle.asn1.DERSequence; import org.bouncycastle.asn1.DERSet; import org.bouncycastle.asn1.cms.Attribute; public class SMIMECapabilitiesAttribute extends Attribute { public SMIMECapabilitiesAttribute( SMIMECapabilityVector capabilities) { super(SMIMEAttributes.smimeCapabilities, new DERSet(new DERSequence(capabilities.toASN1EncodableVector()))); } } bouncycastle-1.49.orig/src/org/bouncycastle/asn1/smime/SMIMEAttributes.java0000644000175000017500000000062611624622715026254 0ustar ebourgebourgpackage org.bouncycastle.asn1.smime; import org.bouncycastle.asn1.ASN1ObjectIdentifier; import org.bouncycastle.asn1.pkcs.PKCSObjectIdentifiers; public interface SMIMEAttributes { public static final ASN1ObjectIdentifier smimeCapabilities = PKCSObjectIdentifiers.pkcs_9_at_smimeCapabilities; public static final ASN1ObjectIdentifier encrypKeyPref = PKCSObjectIdentifiers.id_aa_encrypKeyPref; } bouncycastle-1.49.orig/src/org/bouncycastle/asn1/smime/SMIMECapability.java0000644000175000017500000000616011624652552026210 0ustar ebourgebourgpackage org.bouncycastle.asn1.smime; import org.bouncycastle.asn1.ASN1Encodable; import org.bouncycastle.asn1.ASN1EncodableVector; import org.bouncycastle.asn1.ASN1Object; import org.bouncycastle.asn1.ASN1ObjectIdentifier; import org.bouncycastle.asn1.ASN1Primitive; import org.bouncycastle.asn1.ASN1Sequence; import org.bouncycastle.asn1.DERSequence; import org.bouncycastle.asn1.nist.NISTObjectIdentifiers; import org.bouncycastle.asn1.pkcs.PKCSObjectIdentifiers; public class SMIMECapability extends ASN1Object { /** * general preferences */ public static final ASN1ObjectIdentifier preferSignedData = PKCSObjectIdentifiers.preferSignedData; public static final ASN1ObjectIdentifier canNotDecryptAny = PKCSObjectIdentifiers.canNotDecryptAny; public static final ASN1ObjectIdentifier sMIMECapabilitiesVersions = PKCSObjectIdentifiers.sMIMECapabilitiesVersions; /** * encryption algorithms preferences */ public static final ASN1ObjectIdentifier dES_CBC = new ASN1ObjectIdentifier("1.3.14.3.2.7"); public static final ASN1ObjectIdentifier dES_EDE3_CBC = PKCSObjectIdentifiers.des_EDE3_CBC; public static final ASN1ObjectIdentifier rC2_CBC = PKCSObjectIdentifiers.RC2_CBC; public static final ASN1ObjectIdentifier aES128_CBC = NISTObjectIdentifiers.id_aes128_CBC; public static final ASN1ObjectIdentifier aES192_CBC = NISTObjectIdentifiers.id_aes192_CBC; public static final ASN1ObjectIdentifier aES256_CBC = NISTObjectIdentifiers.id_aes256_CBC; private ASN1ObjectIdentifier capabilityID; private ASN1Encodable parameters; public SMIMECapability( ASN1Sequence seq) { capabilityID = (ASN1ObjectIdentifier)seq.getObjectAt(0); if (seq.size() > 1) { parameters = (ASN1Primitive)seq.getObjectAt(1); } } public SMIMECapability( ASN1ObjectIdentifier capabilityID, ASN1Encodable parameters) { this.capabilityID = capabilityID; this.parameters = parameters; } public static SMIMECapability getInstance( Object obj) { if (obj == null || obj instanceof SMIMECapability) { return (SMIMECapability)obj; } if (obj instanceof ASN1Sequence) { return new SMIMECapability((ASN1Sequence)obj); } throw new IllegalArgumentException("Invalid SMIMECapability"); } public ASN1ObjectIdentifier getCapabilityID() { return capabilityID; } public ASN1Encodable getParameters() { return parameters; } /** * Produce an object suitable for an ASN1OutputStream. *
     
         * SMIMECapability ::= SEQUENCE {
         *     capabilityID OBJECT IDENTIFIER,
         *     parameters ANY DEFINED BY capabilityID OPTIONAL 
         * }
         * 
    */ public ASN1Primitive toASN1Primitive() { ASN1EncodableVector v = new ASN1EncodableVector(); v.add(capabilityID); if (parameters != null) { v.add(parameters); } return new DERSequence(v); } } bouncycastle-1.49.orig/src/org/bouncycastle/asn1/smime/package.html0000644000175000017500000000015310262753174024745 0ustar ebourgebourg Support classes useful for encoding and supporting S/MIME. bouncycastle-1.49.orig/src/org/bouncycastle/asn1/DERSequence.java0000644000175000017500000000421211703177363024321 0ustar ebourgebourgpackage org.bouncycastle.asn1; import java.io.IOException; import java.util.Enumeration; public class DERSequence extends ASN1Sequence { private int bodyLength = -1; /** * create an empty sequence */ public DERSequence() { } /** * create a sequence containing one object */ public DERSequence( ASN1Encodable obj) { super(obj); } /** * create a sequence containing a vector of objects. */ public DERSequence( ASN1EncodableVector v) { super(v); } /** * create a sequence containing an array of objects. */ public DERSequence( ASN1Encodable[] array) { super(array); } private int getBodyLength() throws IOException { if (bodyLength < 0) { int length = 0; for (Enumeration e = this.getObjects(); e.hasMoreElements();) { Object obj = e.nextElement(); length += ((ASN1Encodable)obj).toASN1Primitive().toDERObject().encodedLength(); } bodyLength = length; } return bodyLength; } int encodedLength() throws IOException { int length = getBodyLength(); return 1 + StreamUtil.calculateBodyLength(length) + length; } /* * A note on the implementation: *

    * As DER requires the constructed, definite-length model to * be used for structured types, this varies slightly from the * ASN.1 descriptions given. Rather than just outputting SEQUENCE, * we also have to specify CONSTRUCTED, and the objects length. */ void encode( ASN1OutputStream out) throws IOException { ASN1OutputStream dOut = out.getDERSubStream(); int length = getBodyLength(); out.write(BERTags.SEQUENCE | BERTags.CONSTRUCTED); out.writeLength(length); for (Enumeration e = this.getObjects(); e.hasMoreElements();) { Object obj = e.nextElement(); dOut.writeObject((ASN1Encodable)obj); } } } bouncycastle-1.49.orig/src/org/bouncycastle/asn1/ASN1Encoding.java0000644000175000017500000000025711624616551024373 0ustar ebourgebourgpackage org.bouncycastle.asn1; public interface ASN1Encoding { static final String DER = "DER"; static final String DL = "DL"; static final String BER = "BER"; } bouncycastle-1.49.orig/src/org/bouncycastle/asn1/crmf/0000755000175000017500000000000012152033551022270 5ustar ebourgebourgbouncycastle-1.49.orig/src/org/bouncycastle/asn1/crmf/SubsequentMessage.java0000644000175000017500000000124111724300151026571 0ustar ebourgebourgpackage org.bouncycastle.asn1.crmf; import org.bouncycastle.asn1.ASN1Integer; public class SubsequentMessage extends ASN1Integer { public static final SubsequentMessage encrCert = new SubsequentMessage(0); public static final SubsequentMessage challengeResp = new SubsequentMessage(1); private SubsequentMessage(int value) { super(value); } public static SubsequentMessage valueOf(int value) { if (value == 0) { return encrCert; } if (value == 1) { return challengeResp; } throw new IllegalArgumentException("unknown value: " + value); } } bouncycastle-1.49.orig/src/org/bouncycastle/asn1/crmf/CertTemplate.java0000644000175000017500000001056311724315643025542 0ustar ebourgebourgpackage org.bouncycastle.asn1.crmf; import java.util.Enumeration; import org.bouncycastle.asn1.ASN1Integer; import org.bouncycastle.asn1.ASN1Object; import org.bouncycastle.asn1.ASN1Primitive; import org.bouncycastle.asn1.ASN1Sequence; import org.bouncycastle.asn1.ASN1TaggedObject; import org.bouncycastle.asn1.DERBitString; import org.bouncycastle.asn1.x500.X500Name; import org.bouncycastle.asn1.x509.AlgorithmIdentifier; import org.bouncycastle.asn1.x509.Extensions; import org.bouncycastle.asn1.x509.SubjectPublicKeyInfo; public class CertTemplate extends ASN1Object { private ASN1Sequence seq; private ASN1Integer version; private ASN1Integer serialNumber; private AlgorithmIdentifier signingAlg; private X500Name issuer; private OptionalValidity validity; private X500Name subject; private SubjectPublicKeyInfo publicKey; private DERBitString issuerUID; private DERBitString subjectUID; private Extensions extensions; private CertTemplate(ASN1Sequence seq) { this.seq = seq; Enumeration en = seq.getObjects(); while (en.hasMoreElements()) { ASN1TaggedObject tObj = (ASN1TaggedObject)en.nextElement(); switch (tObj.getTagNo()) { case 0: version = ASN1Integer.getInstance(tObj, false); break; case 1: serialNumber = ASN1Integer.getInstance(tObj, false); break; case 2: signingAlg = AlgorithmIdentifier.getInstance(tObj, false); break; case 3: issuer = X500Name.getInstance(tObj, true); // CHOICE break; case 4: validity = OptionalValidity.getInstance(ASN1Sequence.getInstance(tObj, false)); break; case 5: subject = X500Name.getInstance(tObj, true); // CHOICE break; case 6: publicKey = SubjectPublicKeyInfo.getInstance(tObj, false); break; case 7: issuerUID = DERBitString.getInstance(tObj, false); break; case 8: subjectUID = DERBitString.getInstance(tObj, false); break; case 9: extensions = Extensions.getInstance(tObj, false); break; default: throw new IllegalArgumentException("unknown tag: " + tObj.getTagNo()); } } } public static CertTemplate getInstance(Object o) { if (o instanceof CertTemplate) { return (CertTemplate)o; } else if (o != null) { return new CertTemplate(ASN1Sequence.getInstance(o)); } return null; } public int getVersion() { return version.getValue().intValue(); } public ASN1Integer getSerialNumber() { return serialNumber; } public AlgorithmIdentifier getSigningAlg() { return signingAlg; } public X500Name getIssuer() { return issuer; } public OptionalValidity getValidity() { return validity; } public X500Name getSubject() { return subject; } public SubjectPublicKeyInfo getPublicKey() { return publicKey; } public DERBitString getIssuerUID() { return issuerUID; } public DERBitString getSubjectUID() { return subjectUID; } public Extensions getExtensions() { return extensions; } /** *

         *  CertTemplate ::= SEQUENCE {
         *      version      [0] Version               OPTIONAL,
         *      serialNumber [1] INTEGER               OPTIONAL,
         *      signingAlg   [2] AlgorithmIdentifier   OPTIONAL,
         *      issuer       [3] Name                  OPTIONAL,
         *      validity     [4] OptionalValidity      OPTIONAL,
         *      subject      [5] Name                  OPTIONAL,
         *      publicKey    [6] SubjectPublicKeyInfo  OPTIONAL,
         *      issuerUID    [7] UniqueIdentifier      OPTIONAL,
         *      subjectUID   [8] UniqueIdentifier      OPTIONAL,
         *      extensions   [9] Extensions            OPTIONAL }
         * 
    * @return a basic ASN.1 object representation. */ public ASN1Primitive toASN1Primitive() { return seq; } } bouncycastle-1.49.orig/src/org/bouncycastle/asn1/crmf/SinglePubInfo.java0000644000175000017500000000326111725271164025652 0ustar ebourgebourgpackage org.bouncycastle.asn1.crmf; import org.bouncycastle.asn1.ASN1EncodableVector; import org.bouncycastle.asn1.ASN1Integer; import org.bouncycastle.asn1.ASN1Object; import org.bouncycastle.asn1.ASN1Primitive; import org.bouncycastle.asn1.ASN1Sequence; import org.bouncycastle.asn1.DERSequence; import org.bouncycastle.asn1.x509.GeneralName; public class SinglePubInfo extends ASN1Object { private ASN1Integer pubMethod; private GeneralName pubLocation; private SinglePubInfo(ASN1Sequence seq) { pubMethod = ASN1Integer.getInstance(seq.getObjectAt(0)); if (seq.size() == 2) { pubLocation = GeneralName.getInstance(seq.getObjectAt(1)); } } public static SinglePubInfo getInstance(Object o) { if (o instanceof SinglePubInfo) { return (SinglePubInfo)o; } if (o != null) { return new SinglePubInfo(ASN1Sequence.getInstance(o)); } return null; } public GeneralName getPubLocation() { return pubLocation; } /** *
         * SinglePubInfo ::= SEQUENCE {
         *        pubMethod    INTEGER {
         *           dontCare    (0),
         *           x500        (1),
         *           web         (2),
         *           ldap        (3) },
         *       pubLocation  GeneralName OPTIONAL }
         * 
    * @return a basic ASN.1 object representation. */ public ASN1Primitive toASN1Primitive() { ASN1EncodableVector v = new ASN1EncodableVector(); v.add(pubMethod); if (pubLocation != null) { v.add(pubLocation); } return new DERSequence(v); } } bouncycastle-1.49.orig/src/org/bouncycastle/asn1/crmf/PKIPublicationInfo.java0000644000175000017500000000411211725271004026564 0ustar ebourgebourgpackage org.bouncycastle.asn1.crmf; import org.bouncycastle.asn1.ASN1EncodableVector; import org.bouncycastle.asn1.ASN1Integer; import org.bouncycastle.asn1.ASN1Object; import org.bouncycastle.asn1.ASN1Primitive; import org.bouncycastle.asn1.ASN1Sequence; import org.bouncycastle.asn1.DERSequence; public class PKIPublicationInfo extends ASN1Object { private ASN1Integer action; private ASN1Sequence pubInfos; private PKIPublicationInfo(ASN1Sequence seq) { action = ASN1Integer.getInstance(seq.getObjectAt(0)); pubInfos = ASN1Sequence.getInstance(seq.getObjectAt(1)); } public static PKIPublicationInfo getInstance(Object o) { if (o instanceof PKIPublicationInfo) { return (PKIPublicationInfo)o; } if (o != null) { return new PKIPublicationInfo(ASN1Sequence.getInstance(o)); } return null; } public ASN1Integer getAction() { return action; } public SinglePubInfo[] getPubInfos() { if (pubInfos == null) { return null; } SinglePubInfo[] results = new SinglePubInfo[pubInfos.size()]; for (int i = 0; i != results.length; i++) { results[i] = SinglePubInfo.getInstance(pubInfos.getObjectAt(i)); } return results; } /** *
         * PKIPublicationInfo ::= SEQUENCE {
         *                  action     INTEGER {
         *                                 dontPublish (0),
         *                                 pleasePublish (1) },
         *                  pubInfos  SEQUENCE SIZE (1..MAX) OF SinglePubInfo OPTIONAL }
         * -- pubInfos MUST NOT be present if action is "dontPublish"
         * -- (if action is "pleasePublish" and pubInfos is omitted,
         * -- "dontCare" is assumed)
         * 
    * @return a basic ASN.1 object representation. */ public ASN1Primitive toASN1Primitive() { ASN1EncodableVector v = new ASN1EncodableVector(); v.add(action); v.add(pubInfos); return new DERSequence(v); } } bouncycastle-1.49.orig/src/org/bouncycastle/asn1/crmf/CertTemplateBuilder.java0000644000175000017500000001020411724561172027041 0ustar ebourgebourgpackage org.bouncycastle.asn1.crmf; import org.bouncycastle.asn1.ASN1Encodable; import org.bouncycastle.asn1.ASN1EncodableVector; import org.bouncycastle.asn1.ASN1Integer; import org.bouncycastle.asn1.DERBitString; import org.bouncycastle.asn1.DERSequence; import org.bouncycastle.asn1.DERTaggedObject; import org.bouncycastle.asn1.x500.X500Name; import org.bouncycastle.asn1.x509.AlgorithmIdentifier; import org.bouncycastle.asn1.x509.Extensions; import org.bouncycastle.asn1.x509.SubjectPublicKeyInfo; import org.bouncycastle.asn1.x509.X509Extensions; public class CertTemplateBuilder { private ASN1Integer version; private ASN1Integer serialNumber; private AlgorithmIdentifier signingAlg; private X500Name issuer; private OptionalValidity validity; private X500Name subject; private SubjectPublicKeyInfo publicKey; private DERBitString issuerUID; private DERBitString subjectUID; private Extensions extensions; /** Sets the X.509 version. Note: for X509v3, use 2 here. */ public CertTemplateBuilder setVersion(int ver) { version = new ASN1Integer(ver); return this; } public CertTemplateBuilder setSerialNumber(ASN1Integer ser) { serialNumber = ser; return this; } public CertTemplateBuilder setSigningAlg(AlgorithmIdentifier aid) { signingAlg = aid; return this; } public CertTemplateBuilder setIssuer(X500Name name) { issuer = name; return this; } public CertTemplateBuilder setValidity(OptionalValidity v) { validity = v; return this; } public CertTemplateBuilder setSubject(X500Name name) { subject = name; return this; } public CertTemplateBuilder setPublicKey(SubjectPublicKeyInfo spki) { publicKey = spki; return this; } /** Sets the issuer unique ID (deprecated in X.509v3) */ public CertTemplateBuilder setIssuerUID(DERBitString uid) { issuerUID = uid; return this; } /** Sets the subject unique ID (deprecated in X.509v3) */ public CertTemplateBuilder setSubjectUID(DERBitString uid) { subjectUID = uid; return this; } /** * @deprecated use method taking Extensions * @param extens * @return */ public CertTemplateBuilder setExtensions(X509Extensions extens) { return setExtensions(Extensions.getInstance(extens)); } public CertTemplateBuilder setExtensions(Extensions extens) { extensions = extens; return this; } /** *
         *  CertTemplate ::= SEQUENCE {
         *      version      [0] Version               OPTIONAL,
         *      serialNumber [1] INTEGER               OPTIONAL,
         *      signingAlg   [2] AlgorithmIdentifier   OPTIONAL,
         *      issuer       [3] Name                  OPTIONAL,
         *      validity     [4] OptionalValidity      OPTIONAL,
         *      subject      [5] Name                  OPTIONAL,
         *      publicKey    [6] SubjectPublicKeyInfo  OPTIONAL,
         *      issuerUID    [7] UniqueIdentifier      OPTIONAL,
         *      subjectUID   [8] UniqueIdentifier      OPTIONAL,
         *      extensions   [9] Extensions            OPTIONAL }
         * 
    * @return a basic ASN.1 object representation. */ public CertTemplate build() { ASN1EncodableVector v = new ASN1EncodableVector(); addOptional(v, 0, false, version); addOptional(v, 1, false, serialNumber); addOptional(v, 2, false, signingAlg); addOptional(v, 3, true, issuer); // CHOICE addOptional(v, 4, false, validity); addOptional(v, 5, true, subject); // CHOICE addOptional(v, 6, false, publicKey); addOptional(v, 7, false, issuerUID); addOptional(v, 8, false, subjectUID); addOptional(v, 9, false, extensions); return CertTemplate.getInstance(new DERSequence(v)); } private void addOptional(ASN1EncodableVector v, int tagNo, boolean isExplicit, ASN1Encodable obj) { if (obj != null) { v.add(new DERTaggedObject(isExplicit, tagNo, obj)); } } } bouncycastle-1.49.orig/src/org/bouncycastle/asn1/crmf/CertRequest.java0000644000175000017500000000462211724300706025410 0ustar ebourgebourgpackage org.bouncycastle.asn1.crmf; import org.bouncycastle.asn1.ASN1EncodableVector; import org.bouncycastle.asn1.ASN1Integer; import org.bouncycastle.asn1.ASN1Object; import org.bouncycastle.asn1.ASN1Primitive; import org.bouncycastle.asn1.ASN1Sequence; import org.bouncycastle.asn1.DERSequence; public class CertRequest extends ASN1Object { private ASN1Integer certReqId; private CertTemplate certTemplate; private Controls controls; private CertRequest(ASN1Sequence seq) { certReqId = new ASN1Integer(ASN1Integer.getInstance(seq.getObjectAt(0)).getValue()); certTemplate = CertTemplate.getInstance(seq.getObjectAt(1)); if (seq.size() > 2) { controls = Controls.getInstance(seq.getObjectAt(2)); } } public static CertRequest getInstance(Object o) { if (o instanceof CertRequest) { return (CertRequest)o; } else if (o != null) { return new CertRequest(ASN1Sequence.getInstance(o)); } return null; } public CertRequest( int certReqId, CertTemplate certTemplate, Controls controls) { this(new ASN1Integer(certReqId), certTemplate, controls); } public CertRequest( ASN1Integer certReqId, CertTemplate certTemplate, Controls controls) { this.certReqId = certReqId; this.certTemplate = certTemplate; this.controls = controls; } public ASN1Integer getCertReqId() { return certReqId; } public CertTemplate getCertTemplate() { return certTemplate; } public Controls getControls() { return controls; } /** *
         * CertRequest ::= SEQUENCE {
         *                      certReqId     INTEGER,          -- ID for matching request and reply
         *                      certTemplate  CertTemplate,  -- Selected fields of cert to be issued
         *                      controls      Controls OPTIONAL }   -- Attributes affecting issuance
         * 
    * @return a basic ASN.1 object representation. */ public ASN1Primitive toASN1Primitive() { ASN1EncodableVector v = new ASN1EncodableVector(); v.add(certReqId); v.add(certTemplate); if (controls != null) { v.add(controls); } return new DERSequence(v); } } bouncycastle-1.49.orig/src/org/bouncycastle/asn1/crmf/POPOSigningKey.java0000644000175000017500000001013012151253000025663 0ustar ebourgebourgpackage org.bouncycastle.asn1.crmf; import org.bouncycastle.asn1.ASN1EncodableVector; import org.bouncycastle.asn1.ASN1Object; import org.bouncycastle.asn1.ASN1Primitive; import org.bouncycastle.asn1.ASN1Sequence; import org.bouncycastle.asn1.ASN1TaggedObject; import org.bouncycastle.asn1.DERBitString; import org.bouncycastle.asn1.DERSequence; import org.bouncycastle.asn1.DERTaggedObject; import org.bouncycastle.asn1.x509.AlgorithmIdentifier; public class POPOSigningKey extends ASN1Object { private POPOSigningKeyInput poposkInput; private AlgorithmIdentifier algorithmIdentifier; private DERBitString signature; private POPOSigningKey(ASN1Sequence seq) { int index = 0; if (seq.getObjectAt(index) instanceof ASN1TaggedObject) { ASN1TaggedObject tagObj = (ASN1TaggedObject)seq.getObjectAt(index++); if (tagObj.getTagNo() != 0) { throw new IllegalArgumentException( "Unknown POPOSigningKeyInput tag: " + tagObj.getTagNo()); } poposkInput = POPOSigningKeyInput.getInstance(tagObj.getObject()); } algorithmIdentifier = AlgorithmIdentifier.getInstance(seq.getObjectAt(index++)); signature = DERBitString.getInstance(seq.getObjectAt(index)); } public static POPOSigningKey getInstance(Object o) { if (o instanceof POPOSigningKey) { return (POPOSigningKey)o; } if (o != null) { return new POPOSigningKey(ASN1Sequence.getInstance(o)); } return null; } public static POPOSigningKey getInstance(ASN1TaggedObject obj, boolean explicit) { return getInstance(ASN1Sequence.getInstance(obj, explicit)); } /** * Creates a new Proof of Possession object for a signing key. * * @param poposkIn the POPOSigningKeyInput structure, or null if the * CertTemplate includes both subject and publicKey values. * @param aid the AlgorithmIdentifier used to sign the proof of possession. * @param signature a signature over the DER-encoded value of poposkIn, * or the DER-encoded value of certReq if poposkIn is null. */ public POPOSigningKey( POPOSigningKeyInput poposkIn, AlgorithmIdentifier aid, DERBitString signature) { this.poposkInput = poposkIn; this.algorithmIdentifier = aid; this.signature = signature; } public POPOSigningKeyInput getPoposkInput() { return poposkInput; } public AlgorithmIdentifier getAlgorithmIdentifier() { return algorithmIdentifier; } public DERBitString getSignature() { return signature; } /** *
         * POPOSigningKey ::= SEQUENCE {
         *                      poposkInput           [0] POPOSigningKeyInput OPTIONAL,
         *                      algorithmIdentifier   AlgorithmIdentifier,
         *                      signature             BIT STRING }
         *  -- The signature (using "algorithmIdentifier") is on the
         *  -- DER-encoded value of poposkInput.  NOTE: If the CertReqMsg
         *  -- certReq CertTemplate contains the subject and publicKey values,
         *  -- then poposkInput MUST be omitted and the signature MUST be
         *  -- computed on the DER-encoded value of CertReqMsg certReq.  If
         *  -- the CertReqMsg certReq CertTemplate does not contain the public
         *  -- key and subject values, then poposkInput MUST be present and
         *  -- MUST be signed.  This strategy ensures that the public key is
         *  -- not present in both the poposkInput and CertReqMsg certReq
         *  -- CertTemplate fields.
         * 
    * * @return a basic ASN.1 object representation. */ public ASN1Primitive toASN1Primitive() { ASN1EncodableVector v = new ASN1EncodableVector(); if (poposkInput != null) { v.add(new DERTaggedObject(false, 0, poposkInput)); } v.add(algorithmIdentifier); v.add(signature); return new DERSequence(v); } } bouncycastle-1.49.orig/src/org/bouncycastle/asn1/crmf/OptionalValidity.java0000644000175000017500000000456112057024655026445 0ustar ebourgebourgpackage org.bouncycastle.asn1.crmf; import java.util.Enumeration; import org.bouncycastle.asn1.ASN1EncodableVector; import org.bouncycastle.asn1.ASN1Object; import org.bouncycastle.asn1.ASN1Primitive; import org.bouncycastle.asn1.ASN1Sequence; import org.bouncycastle.asn1.ASN1TaggedObject; import org.bouncycastle.asn1.DERSequence; import org.bouncycastle.asn1.DERTaggedObject; import org.bouncycastle.asn1.x509.Time; public class OptionalValidity extends ASN1Object { private Time notBefore; private Time notAfter; private OptionalValidity(ASN1Sequence seq) { Enumeration en = seq.getObjects(); while (en.hasMoreElements()) { ASN1TaggedObject tObj = (ASN1TaggedObject)en.nextElement(); if (tObj.getTagNo() == 0) { notBefore = Time.getInstance(tObj, true); } else { notAfter = Time.getInstance(tObj, true); } } } public static OptionalValidity getInstance(Object o) { if (o instanceof OptionalValidity) { return (OptionalValidity)o; } if (o != null) { return new OptionalValidity(ASN1Sequence.getInstance(o)); } return null; } public OptionalValidity(Time notBefore, Time notAfter) { if (notBefore == null && notAfter == null) { throw new IllegalArgumentException("at least one of notBefore/notAfter must not be null."); } this.notBefore = notBefore; this.notAfter = notAfter; } public Time getNotBefore() { return notBefore; } public Time getNotAfter() { return notAfter; } /** *
         * OptionalValidity ::= SEQUENCE {
         *                        notBefore  [0] Time OPTIONAL,
         *                        notAfter   [1] Time OPTIONAL } --at least one MUST be present
         * 
    * @return a basic ASN.1 object representation. */ public ASN1Primitive toASN1Primitive() { ASN1EncodableVector v = new ASN1EncodableVector(); if (notBefore != null) { v.add(new DERTaggedObject(true, 0, notBefore)); } if (notAfter != null) { v.add(new DERTaggedObject(true, 1, notAfter)); } return new DERSequence(v); } } bouncycastle-1.49.orig/src/org/bouncycastle/asn1/crmf/CertReqMessages.java0000644000175000017500000000313612151253000026163 0ustar ebourgebourgpackage org.bouncycastle.asn1.crmf; import org.bouncycastle.asn1.ASN1EncodableVector; import org.bouncycastle.asn1.ASN1Object; import org.bouncycastle.asn1.ASN1Primitive; import org.bouncycastle.asn1.ASN1Sequence; import org.bouncycastle.asn1.DERSequence; public class CertReqMessages extends ASN1Object { private ASN1Sequence content; private CertReqMessages(ASN1Sequence seq) { content = seq; } public static CertReqMessages getInstance(Object o) { if (o instanceof CertReqMessages) { return (CertReqMessages)o; } if (o != null) { return new CertReqMessages(ASN1Sequence.getInstance(o)); } return null; } public CertReqMessages( CertReqMsg msg) { content = new DERSequence(msg); } public CertReqMessages( CertReqMsg[] msgs) { ASN1EncodableVector v = new ASN1EncodableVector(); for (int i = 0; i < msgs.length; i++) { v.add(msgs[i]); } content = new DERSequence(v); } public CertReqMsg[] toCertReqMsgArray() { CertReqMsg[] result = new CertReqMsg[content.size()]; for (int i = 0; i != result.length; i++) { result[i] = CertReqMsg.getInstance(content.getObjectAt(i)); } return result; } /** *
         * CertReqMessages ::= SEQUENCE SIZE (1..MAX) OF CertReqMsg
         * 
    * * @return a basic ASN.1 object representation. */ public ASN1Primitive toASN1Primitive() { return content; } } bouncycastle-1.49.orig/src/org/bouncycastle/asn1/crmf/CertId.java0000644000175000017500000000375011725315430024316 0ustar ebourgebourgpackage org.bouncycastle.asn1.crmf; import java.math.BigInteger; import org.bouncycastle.asn1.ASN1EncodableVector; import org.bouncycastle.asn1.ASN1Integer; import org.bouncycastle.asn1.ASN1Object; import org.bouncycastle.asn1.ASN1Primitive; import org.bouncycastle.asn1.ASN1Sequence; import org.bouncycastle.asn1.ASN1TaggedObject; import org.bouncycastle.asn1.DERSequence; import org.bouncycastle.asn1.x509.GeneralName; public class CertId extends ASN1Object { private GeneralName issuer; private ASN1Integer serialNumber; private CertId(ASN1Sequence seq) { issuer = GeneralName.getInstance(seq.getObjectAt(0)); serialNumber = ASN1Integer.getInstance(seq.getObjectAt(1)); } public static CertId getInstance(Object o) { if (o instanceof CertId) { return (CertId)o; } if (o != null) { return new CertId(ASN1Sequence.getInstance(o)); } return null; } public static CertId getInstance(ASN1TaggedObject obj, boolean isExplicit) { return getInstance(ASN1Sequence.getInstance(obj, isExplicit)); } public CertId(GeneralName issuer, BigInteger serialNumber) { this(issuer, new ASN1Integer(serialNumber)); } public CertId(GeneralName issuer, ASN1Integer serialNumber) { this.issuer = issuer; this.serialNumber = serialNumber; } public GeneralName getIssuer() { return issuer; } public ASN1Integer getSerialNumber() { return serialNumber; } /** *
         * CertId ::= SEQUENCE {
         *                 issuer           GeneralName,
         *                 serialNumber     INTEGER }
         * 
    * @return a basic ASN.1 object representation. */ public ASN1Primitive toASN1Primitive() { ASN1EncodableVector v = new ASN1EncodableVector(); v.add(issuer); v.add(serialNumber); return new DERSequence(v); } } bouncycastle-1.49.orig/src/org/bouncycastle/asn1/crmf/POPOSigningKeyInput.java0000644000175000017500000000750611725271103026732 0ustar ebourgebourgpackage org.bouncycastle.asn1.crmf; import org.bouncycastle.asn1.ASN1Encodable; import org.bouncycastle.asn1.ASN1EncodableVector; import org.bouncycastle.asn1.ASN1Object; import org.bouncycastle.asn1.ASN1Primitive; import org.bouncycastle.asn1.ASN1Sequence; import org.bouncycastle.asn1.ASN1TaggedObject; import org.bouncycastle.asn1.DERSequence; import org.bouncycastle.asn1.DERTaggedObject; import org.bouncycastle.asn1.x509.GeneralName; import org.bouncycastle.asn1.x509.SubjectPublicKeyInfo; public class POPOSigningKeyInput extends ASN1Object { private GeneralName sender; private PKMACValue publicKeyMAC; private SubjectPublicKeyInfo publicKey; private POPOSigningKeyInput(ASN1Sequence seq) { ASN1Encodable authInfo = (ASN1Encodable)seq.getObjectAt(0); if (authInfo instanceof ASN1TaggedObject) { ASN1TaggedObject tagObj = (ASN1TaggedObject)authInfo; if (tagObj.getTagNo() != 0) { throw new IllegalArgumentException( "Unknown authInfo tag: " + tagObj.getTagNo()); } sender = GeneralName.getInstance(tagObj.getObject()); } else { publicKeyMAC = PKMACValue.getInstance(authInfo); } publicKey = SubjectPublicKeyInfo.getInstance(seq.getObjectAt(1)); } public static POPOSigningKeyInput getInstance(Object o) { if (o instanceof POPOSigningKeyInput) { return (POPOSigningKeyInput)o; } if (o != null) { return new POPOSigningKeyInput(ASN1Sequence.getInstance(o)); } return null; } /** * Creates a new POPOSigningKeyInput with sender name as authInfo. */ public POPOSigningKeyInput( GeneralName sender, SubjectPublicKeyInfo spki) { this.sender = sender; this.publicKey = spki; } /** * Creates a new POPOSigningKeyInput using password-based MAC. */ public POPOSigningKeyInput( PKMACValue pkmac, SubjectPublicKeyInfo spki) { this.publicKeyMAC = pkmac; this.publicKey = spki; } /** * Returns the sender field, or null if authInfo is publicKeyMAC */ public GeneralName getSender() { return sender; } /** * Returns the publicKeyMAC field, or null if authInfo is sender */ public PKMACValue getPublicKeyMAC() { return publicKeyMAC; } public SubjectPublicKeyInfo getPublicKey() { return publicKey; } /** *
         * POPOSigningKeyInput ::= SEQUENCE {
         *        authInfo             CHOICE {
         *                                 sender              [0] GeneralName,
         *                                 -- used only if an authenticated identity has been
         *                                 -- established for the sender (e.g., a DN from a
         *                                 -- previously-issued and currently-valid certificate
         *                                 publicKeyMAC        PKMACValue },
         *                                 -- used if no authenticated GeneralName currently exists for
         *                                 -- the sender; publicKeyMAC contains a password-based MAC
         *                                 -- on the DER-encoded value of publicKey
         *        publicKey           SubjectPublicKeyInfo }  -- from CertTemplate
         * 
    * @return a basic ASN.1 object representation. */ public ASN1Primitive toASN1Primitive() { ASN1EncodableVector v = new ASN1EncodableVector(); if (sender != null) { v.add(new DERTaggedObject(false, 0, sender)); } else { v.add(publicKeyMAC); } v.add(publicKey); return new DERSequence(v); } } bouncycastle-1.49.orig/src/org/bouncycastle/asn1/crmf/PKIArchiveOptions.java0000644000175000017500000000637111736740374026462 0ustar ebourgebourgpackage org.bouncycastle.asn1.crmf; import org.bouncycastle.asn1.ASN1Boolean; import org.bouncycastle.asn1.ASN1Choice; import org.bouncycastle.asn1.ASN1Encodable; import org.bouncycastle.asn1.ASN1Object; import org.bouncycastle.asn1.ASN1OctetString; import org.bouncycastle.asn1.ASN1Primitive; import org.bouncycastle.asn1.ASN1TaggedObject; import org.bouncycastle.asn1.DERTaggedObject; public class PKIArchiveOptions extends ASN1Object implements ASN1Choice { public static final int encryptedPrivKey = 0; public static final int keyGenParameters = 1; public static final int archiveRemGenPrivKey = 2; private ASN1Encodable value; public static PKIArchiveOptions getInstance(Object o) { if (o == null || o instanceof PKIArchiveOptions) { return (PKIArchiveOptions)o; } else if (o instanceof ASN1TaggedObject) { return new PKIArchiveOptions((ASN1TaggedObject)o); } throw new IllegalArgumentException("unknown object: " + o); } private PKIArchiveOptions(ASN1TaggedObject tagged) { switch (tagged.getTagNo()) { case encryptedPrivKey: value = EncryptedKey.getInstance(tagged.getObject()); break; case keyGenParameters: value = ASN1OctetString.getInstance(tagged, false); break; case archiveRemGenPrivKey: value = ASN1Boolean.getInstance(tagged, false); break; default: throw new IllegalArgumentException("unknown tag number: " + tagged.getTagNo()); } } public PKIArchiveOptions(EncryptedKey encKey) { this.value = encKey; } public PKIArchiveOptions(ASN1OctetString keyGenParameters) { this.value = keyGenParameters; } public PKIArchiveOptions(boolean archiveRemGenPrivKey) { this.value = ASN1Boolean.getInstance(archiveRemGenPrivKey); } public int getType() { if (value instanceof EncryptedKey) { return encryptedPrivKey; } if (value instanceof ASN1OctetString) { return keyGenParameters; } return archiveRemGenPrivKey; } public ASN1Encodable getValue() { return value; } /** *
         *  PKIArchiveOptions ::= CHOICE {
         *      encryptedPrivKey     [0] EncryptedKey,
         *      -- the actual value of the private key
         *      keyGenParameters     [1] KeyGenParameters,
         *      -- parameters which allow the private key to be re-generated
         *      archiveRemGenPrivKey [2] BOOLEAN }
         *      -- set to TRUE if sender wishes receiver to archive the private
         *      -- key of a key pair that the receiver generates in response to
         *      -- this request; set to FALSE if no archival is desired.
         * 
    */ public ASN1Primitive toASN1Primitive() { if (value instanceof EncryptedKey) { return new DERTaggedObject(true, encryptedPrivKey, value); // choice } if (value instanceof ASN1OctetString) { return new DERTaggedObject(false, keyGenParameters, value); } return new DERTaggedObject(false, archiveRemGenPrivKey, value); } } bouncycastle-1.49.orig/src/org/bouncycastle/asn1/crmf/EncryptedKey.java0000644000175000017500000000410111624626647025556 0ustar ebourgebourgpackage org.bouncycastle.asn1.crmf; import org.bouncycastle.asn1.ASN1Choice; import org.bouncycastle.asn1.ASN1Encodable; import org.bouncycastle.asn1.ASN1Object; import org.bouncycastle.asn1.ASN1Primitive; import org.bouncycastle.asn1.ASN1TaggedObject; import org.bouncycastle.asn1.DERTaggedObject; import org.bouncycastle.asn1.cms.EnvelopedData; public class EncryptedKey extends ASN1Object implements ASN1Choice { private EnvelopedData envelopedData; private EncryptedValue encryptedValue; public static EncryptedKey getInstance(Object o) { if (o instanceof EncryptedKey) { return (EncryptedKey)o; } else if (o instanceof ASN1TaggedObject) { return new EncryptedKey(EnvelopedData.getInstance((ASN1TaggedObject)o, false)); } else if (o instanceof EncryptedValue) { return new EncryptedKey((EncryptedValue)o); } else { return new EncryptedKey(EncryptedValue.getInstance(o)); } } public EncryptedKey(EnvelopedData envelopedData) { this.envelopedData = envelopedData; } public EncryptedKey(EncryptedValue encryptedValue) { this.encryptedValue = encryptedValue; } public boolean isEncryptedValue() { return encryptedValue != null; } public ASN1Encodable getValue() { if (encryptedValue != null) { return encryptedValue; } return envelopedData; } /** *
         *    EncryptedKey ::= CHOICE {
         *        encryptedValue        EncryptedValue, -- deprecated
         *        envelopedData     [0] EnvelopedData }
         *        -- The encrypted private key MUST be placed in the envelopedData
         *        -- encryptedContentInfo encryptedContent OCTET STRING.
         * 
    */ public ASN1Primitive toASN1Primitive() { if (encryptedValue != null) { return encryptedValue.toASN1Primitive(); } return new DERTaggedObject(false, 0, envelopedData); } } bouncycastle-1.49.orig/src/org/bouncycastle/asn1/crmf/Controls.java0000644000175000017500000000314512151253000024731 0ustar ebourgebourgpackage org.bouncycastle.asn1.crmf; import org.bouncycastle.asn1.ASN1EncodableVector; import org.bouncycastle.asn1.ASN1Object; import org.bouncycastle.asn1.ASN1Primitive; import org.bouncycastle.asn1.ASN1Sequence; import org.bouncycastle.asn1.DERSequence; public class Controls extends ASN1Object { private ASN1Sequence content; private Controls(ASN1Sequence seq) { content = seq; } public static Controls getInstance(Object o) { if (o instanceof Controls) { return (Controls)o; } if (o != null) { return new Controls(ASN1Sequence.getInstance(o)); } return null; } public Controls(AttributeTypeAndValue atv) { content = new DERSequence(atv); } public Controls(AttributeTypeAndValue[] atvs) { ASN1EncodableVector v = new ASN1EncodableVector(); for (int i = 0; i < atvs.length; i++) { v.add(atvs[i]); } content = new DERSequence(v); } public AttributeTypeAndValue[] toAttributeTypeAndValueArray() { AttributeTypeAndValue[] result = new AttributeTypeAndValue[content.size()]; for (int i = 0; i != result.length; i++) { result[i] = AttributeTypeAndValue.getInstance(content.getObjectAt(i)); } return result; } /** *
         * Controls  ::= SEQUENCE SIZE(1..MAX) OF AttributeTypeAndValue
         * 
    * * @return a basic ASN.1 object representation. */ public ASN1Primitive toASN1Primitive() { return content; } } bouncycastle-1.49.orig/src/org/bouncycastle/asn1/crmf/EncKeyWithID.java0000644000175000017500000000536311624651554025405 0ustar ebourgebourgpackage org.bouncycastle.asn1.crmf; import org.bouncycastle.asn1.ASN1Encodable; import org.bouncycastle.asn1.ASN1EncodableVector; import org.bouncycastle.asn1.ASN1Object; import org.bouncycastle.asn1.ASN1Primitive; import org.bouncycastle.asn1.ASN1Sequence; import org.bouncycastle.asn1.DERSequence; import org.bouncycastle.asn1.DERUTF8String; import org.bouncycastle.asn1.pkcs.PrivateKeyInfo; import org.bouncycastle.asn1.x509.GeneralName; public class EncKeyWithID extends ASN1Object { private final PrivateKeyInfo privKeyInfo; private final ASN1Encodable identifier; public static EncKeyWithID getInstance(Object o) { if (o instanceof EncKeyWithID) { return (EncKeyWithID)o; } else if (o != null) { return new EncKeyWithID(ASN1Sequence.getInstance(o)); } return null; } private EncKeyWithID(ASN1Sequence seq) { this.privKeyInfo = PrivateKeyInfo.getInstance(seq.getObjectAt(0)); if (seq.size() > 1) { if (!(seq.getObjectAt(1) instanceof DERUTF8String)) { this.identifier = GeneralName.getInstance(seq.getObjectAt(1)); } else { this.identifier = (ASN1Encodable)seq.getObjectAt(1); } } else { this.identifier = null; } } public EncKeyWithID(PrivateKeyInfo privKeyInfo) { this.privKeyInfo = privKeyInfo; this.identifier = null; } public EncKeyWithID(PrivateKeyInfo privKeyInfo, DERUTF8String str) { this.privKeyInfo = privKeyInfo; this.identifier = str; } public EncKeyWithID(PrivateKeyInfo privKeyInfo, GeneralName generalName) { this.privKeyInfo = privKeyInfo; this.identifier = generalName; } public PrivateKeyInfo getPrivateKey() { return privKeyInfo; } public boolean hasIdentifier() { return identifier != null; } public boolean isIdentifierUTF8String() { return identifier instanceof DERUTF8String; } public ASN1Encodable getIdentifier() { return identifier; } /** *
         * EncKeyWithID ::= SEQUENCE {
         *      privateKey           PrivateKeyInfo,
         *      identifier CHOICE {
         *         string               UTF8String,
         *         generalName          GeneralName
         *     } OPTIONAL
         * }
         * 
    * @return */ public ASN1Primitive toASN1Primitive() { ASN1EncodableVector v = new ASN1EncodableVector(); v.add(privKeyInfo); if (identifier != null) { v.add(identifier); } return new DERSequence(v); } } bouncycastle-1.49.orig/src/org/bouncycastle/asn1/crmf/PKMACValue.java0000644000175000017500000000524611725271046025002 0ustar ebourgebourgpackage org.bouncycastle.asn1.crmf; import org.bouncycastle.asn1.ASN1EncodableVector; import org.bouncycastle.asn1.ASN1Object; import org.bouncycastle.asn1.ASN1Primitive; import org.bouncycastle.asn1.ASN1Sequence; import org.bouncycastle.asn1.ASN1TaggedObject; import org.bouncycastle.asn1.DERBitString; import org.bouncycastle.asn1.DERSequence; import org.bouncycastle.asn1.cmp.CMPObjectIdentifiers; import org.bouncycastle.asn1.cmp.PBMParameter; import org.bouncycastle.asn1.x509.AlgorithmIdentifier; /** * Password-based MAC value for use with POPOSigningKeyInput. */ public class PKMACValue extends ASN1Object { private AlgorithmIdentifier algId; private DERBitString value; private PKMACValue(ASN1Sequence seq) { algId = AlgorithmIdentifier.getInstance(seq.getObjectAt(0)); value = DERBitString.getInstance(seq.getObjectAt(1)); } public static PKMACValue getInstance(Object o) { if (o instanceof PKMACValue) { return (PKMACValue)o; } if (o != null) { return new PKMACValue(ASN1Sequence.getInstance(o)); } return null; } public static PKMACValue getInstance(ASN1TaggedObject obj, boolean isExplicit) { return getInstance(ASN1Sequence.getInstance(obj, isExplicit)); } /** * Creates a new PKMACValue. * @param params parameters for password-based MAC * @param value MAC of the DER-encoded SubjectPublicKeyInfo */ public PKMACValue( PBMParameter params, DERBitString value) { this(new AlgorithmIdentifier( CMPObjectIdentifiers.passwordBasedMac, params), value); } /** * Creates a new PKMACValue. * @param aid CMPObjectIdentifiers.passwordBasedMAC, with PBMParameter * @param value MAC of the DER-encoded SubjectPublicKeyInfo */ public PKMACValue( AlgorithmIdentifier aid, DERBitString value) { this.algId = aid; this.value = value; } public AlgorithmIdentifier getAlgId() { return algId; } public DERBitString getValue() { return value; } /** *
         * PKMACValue ::= SEQUENCE {
         *      algId  AlgorithmIdentifier,
         *      -- algorithm value shall be PasswordBasedMac 1.2.840.113533.7.66.13
         *      -- parameter value is PBMParameter
         *      value  BIT STRING }
         * 
    * @return a basic ASN.1 object representation. */ public ASN1Primitive toASN1Primitive() { ASN1EncodableVector v = new ASN1EncodableVector(); v.add(algId); v.add(value); return new DERSequence(v); } } bouncycastle-1.49.orig/src/org/bouncycastle/asn1/crmf/CRMFObjectIdentifiers.java0000644000175000017500000000171511624622713027212 0ustar ebourgebourgpackage org.bouncycastle.asn1.crmf; import org.bouncycastle.asn1.ASN1ObjectIdentifier; import org.bouncycastle.asn1.pkcs.PKCSObjectIdentifiers; public interface CRMFObjectIdentifiers { static final ASN1ObjectIdentifier id_pkix = new ASN1ObjectIdentifier("1.3.6.1.5.5.7"); // arc for Internet X.509 PKI protocols and their components static final ASN1ObjectIdentifier id_pkip = id_pkix.branch("5"); static final ASN1ObjectIdentifier id_regCtrl = id_pkip.branch("1"); static final ASN1ObjectIdentifier id_regCtrl_regToken = id_regCtrl.branch("1"); static final ASN1ObjectIdentifier id_regCtrl_authenticator = id_regCtrl.branch("2"); static final ASN1ObjectIdentifier id_regCtrl_pkiPublicationInfo = id_regCtrl.branch("3"); static final ASN1ObjectIdentifier id_regCtrl_pkiArchiveOptions = id_regCtrl.branch("4"); static final ASN1ObjectIdentifier id_ct_encKeyWithID = new ASN1ObjectIdentifier(PKCSObjectIdentifiers.id_ct + ".21"); } bouncycastle-1.49.orig/src/org/bouncycastle/asn1/crmf/CertReqMsg.java0000644000175000017500000000645011624626647025175 0ustar ebourgebourgpackage org.bouncycastle.asn1.crmf; import java.util.Enumeration; import org.bouncycastle.asn1.ASN1Encodable; import org.bouncycastle.asn1.ASN1EncodableVector; import org.bouncycastle.asn1.ASN1Object; import org.bouncycastle.asn1.ASN1Primitive; import org.bouncycastle.asn1.ASN1Sequence; import org.bouncycastle.asn1.ASN1TaggedObject; import org.bouncycastle.asn1.DERSequence; public class CertReqMsg extends ASN1Object { private CertRequest certReq; private ProofOfPossession pop; private ASN1Sequence regInfo; private CertReqMsg(ASN1Sequence seq) { Enumeration en = seq.getObjects(); certReq = CertRequest.getInstance(en.nextElement()); while (en.hasMoreElements()) { Object o = en.nextElement(); if (o instanceof ASN1TaggedObject || o instanceof ProofOfPossession) { pop = ProofOfPossession.getInstance(o); } else { regInfo = ASN1Sequence.getInstance(o); } } } public static CertReqMsg getInstance(Object o) { if (o instanceof CertReqMsg) { return (CertReqMsg)o; } else if (o != null) { return new CertReqMsg(ASN1Sequence.getInstance(o)); } return null; } /** * Creates a new CertReqMsg. * @param certReq CertRequest * @param pop may be null * @param regInfo may be null */ public CertReqMsg( CertRequest certReq, ProofOfPossession pop, AttributeTypeAndValue[] regInfo) { if (certReq == null) { throw new IllegalArgumentException("'certReq' cannot be null"); } this.certReq = certReq; this.pop = pop; if (regInfo != null) { this.regInfo = new DERSequence(regInfo); } } public CertRequest getCertReq() { return certReq; } /** * @deprecated use getPopo */ public ProofOfPossession getPop() { return pop; } public ProofOfPossession getPopo() { return pop; } public AttributeTypeAndValue[] getRegInfo() { if (regInfo == null) { return null; } AttributeTypeAndValue[] results = new AttributeTypeAndValue[regInfo.size()]; for (int i = 0; i != results.length; i++) { results[i] = AttributeTypeAndValue.getInstance(regInfo.getObjectAt(i)); } return results; } /** *
         * CertReqMsg ::= SEQUENCE {
         *                    certReq   CertRequest,
         *                    popo       ProofOfPossession  OPTIONAL,
         *                    -- content depends upon key type
         *                    regInfo   SEQUENCE SIZE(1..MAX) OF AttributeTypeAndValue OPTIONAL }
         * 
    * @return a basic ASN.1 object representation. */ public ASN1Primitive toASN1Primitive() { ASN1EncodableVector v = new ASN1EncodableVector(); v.add(certReq); addOptional(v, pop); addOptional(v, regInfo); return new DERSequence(v); } private void addOptional(ASN1EncodableVector v, ASN1Encodable obj) { if (obj != null) { v.add(obj); } } } bouncycastle-1.49.orig/src/org/bouncycastle/asn1/crmf/EncryptedValue.java0000644000175000017500000001165411624626647026115 0ustar ebourgebourgpackage org.bouncycastle.asn1.crmf; import org.bouncycastle.asn1.ASN1Encodable; import org.bouncycastle.asn1.ASN1EncodableVector; import org.bouncycastle.asn1.ASN1Object; import org.bouncycastle.asn1.ASN1OctetString; import org.bouncycastle.asn1.ASN1Primitive; import org.bouncycastle.asn1.ASN1Sequence; import org.bouncycastle.asn1.ASN1TaggedObject; import org.bouncycastle.asn1.DERBitString; import org.bouncycastle.asn1.DERSequence; import org.bouncycastle.asn1.DERTaggedObject; import org.bouncycastle.asn1.x509.AlgorithmIdentifier; public class EncryptedValue extends ASN1Object { private AlgorithmIdentifier intendedAlg; private AlgorithmIdentifier symmAlg; private DERBitString encSymmKey; private AlgorithmIdentifier keyAlg; private ASN1OctetString valueHint; private DERBitString encValue; private EncryptedValue(ASN1Sequence seq) { int index = 0; while (seq.getObjectAt(index) instanceof ASN1TaggedObject) { ASN1TaggedObject tObj = (ASN1TaggedObject)seq.getObjectAt(index); switch (tObj.getTagNo()) { case 0: intendedAlg = AlgorithmIdentifier.getInstance(tObj, false); break; case 1: symmAlg = AlgorithmIdentifier.getInstance(tObj, false); break; case 2: encSymmKey = DERBitString.getInstance(tObj, false); break; case 3: keyAlg = AlgorithmIdentifier.getInstance(tObj, false); break; case 4: valueHint = ASN1OctetString.getInstance(tObj, false); break; } index++; } encValue = DERBitString.getInstance(seq.getObjectAt(index)); } public static EncryptedValue getInstance(Object o) { if (o instanceof EncryptedValue) { return (EncryptedValue)o; } else if (o != null) { return new EncryptedValue(ASN1Sequence.getInstance(o)); } return null; } public EncryptedValue( AlgorithmIdentifier intendedAlg, AlgorithmIdentifier symmAlg, DERBitString encSymmKey, AlgorithmIdentifier keyAlg, ASN1OctetString valueHint, DERBitString encValue) { if (encValue == null) { throw new IllegalArgumentException("'encValue' cannot be null"); } this.intendedAlg = intendedAlg; this.symmAlg = symmAlg; this.encSymmKey = encSymmKey; this.keyAlg = keyAlg; this.valueHint = valueHint; this.encValue = encValue; } public AlgorithmIdentifier getIntendedAlg() { return intendedAlg; } public AlgorithmIdentifier getSymmAlg() { return symmAlg; } public DERBitString getEncSymmKey() { return encSymmKey; } public AlgorithmIdentifier getKeyAlg() { return keyAlg; } public ASN1OctetString getValueHint() { return valueHint; } public DERBitString getEncValue() { return encValue; } /** *
         * EncryptedValue ::= SEQUENCE {
         *                     intendedAlg   [0] AlgorithmIdentifier  OPTIONAL,
         *                     -- the intended algorithm for which the value will be used
         *                     symmAlg       [1] AlgorithmIdentifier  OPTIONAL,
         *                     -- the symmetric algorithm used to encrypt the value
         *                     encSymmKey    [2] BIT STRING           OPTIONAL,
         *                     -- the (encrypted) symmetric key used to encrypt the value
         *                     keyAlg        [3] AlgorithmIdentifier  OPTIONAL,
         *                     -- algorithm used to encrypt the symmetric key
         *                     valueHint     [4] OCTET STRING         OPTIONAL,
         *                     -- a brief description or identifier of the encValue content
         *                     -- (may be meaningful only to the sending entity, and used only
         *                     -- if EncryptedValue might be re-examined by the sending entity
         *                     -- in the future)
         *                     encValue       BIT STRING }
         *                     -- the encrypted value itself
         * 
    * @return a basic ASN.1 object representation. */ public ASN1Primitive toASN1Primitive() { ASN1EncodableVector v = new ASN1EncodableVector(); addOptional(v, 0, intendedAlg); addOptional(v, 1, symmAlg); addOptional(v, 2, encSymmKey); addOptional(v, 3, keyAlg); addOptional(v, 4, valueHint); v.add(encValue); return new DERSequence(v); } private void addOptional(ASN1EncodableVector v, int tagNo, ASN1Encodable obj) { if (obj != null) { v.add(new DERTaggedObject(false, tagNo, obj)); } } } bouncycastle-1.49.orig/src/org/bouncycastle/asn1/crmf/AttributeTypeAndValue.java0000644000175000017500000000354211725270505027373 0ustar ebourgebourgpackage org.bouncycastle.asn1.crmf; import org.bouncycastle.asn1.ASN1Encodable; import org.bouncycastle.asn1.ASN1EncodableVector; import org.bouncycastle.asn1.ASN1Object; import org.bouncycastle.asn1.ASN1ObjectIdentifier; import org.bouncycastle.asn1.ASN1Primitive; import org.bouncycastle.asn1.ASN1Sequence; import org.bouncycastle.asn1.DERSequence; public class AttributeTypeAndValue extends ASN1Object { private ASN1ObjectIdentifier type; private ASN1Encodable value; private AttributeTypeAndValue(ASN1Sequence seq) { type = (ASN1ObjectIdentifier)seq.getObjectAt(0); value = (ASN1Encodable)seq.getObjectAt(1); } public static AttributeTypeAndValue getInstance(Object o) { if (o instanceof AttributeTypeAndValue) { return (AttributeTypeAndValue)o; } if (o != null) { return new AttributeTypeAndValue(ASN1Sequence.getInstance(o)); } return null; } public AttributeTypeAndValue( String oid, ASN1Encodable value) { this(new ASN1ObjectIdentifier(oid), value); } public AttributeTypeAndValue( ASN1ObjectIdentifier type, ASN1Encodable value) { this.type = type; this.value = value; } public ASN1ObjectIdentifier getType() { return type; } public ASN1Encodable getValue() { return value; } /** *
         * AttributeTypeAndValue ::= SEQUENCE {
         *           type         OBJECT IDENTIFIER,
         *           value        ANY DEFINED BY type }
         * 
    * @return a basic ASN.1 object representation. */ public ASN1Primitive toASN1Primitive() { ASN1EncodableVector v = new ASN1EncodableVector(); v.add(type); v.add(value); return new DERSequence(v); } } bouncycastle-1.49.orig/src/org/bouncycastle/asn1/crmf/ProofOfPossession.java0000644000175000017500000000573011741216222026601 0ustar ebourgebourgpackage org.bouncycastle.asn1.crmf; import org.bouncycastle.asn1.ASN1Choice; import org.bouncycastle.asn1.ASN1Encodable; import org.bouncycastle.asn1.ASN1Object; import org.bouncycastle.asn1.ASN1Primitive; import org.bouncycastle.asn1.ASN1TaggedObject; import org.bouncycastle.asn1.DERNull; import org.bouncycastle.asn1.DERTaggedObject; public class ProofOfPossession extends ASN1Object implements ASN1Choice { public static final int TYPE_RA_VERIFIED = 0; public static final int TYPE_SIGNING_KEY = 1; public static final int TYPE_KEY_ENCIPHERMENT = 2; public static final int TYPE_KEY_AGREEMENT = 3; private int tagNo; private ASN1Encodable obj; private ProofOfPossession(ASN1TaggedObject tagged) { tagNo = tagged.getTagNo(); switch (tagNo) { case 0: obj = DERNull.INSTANCE; break; case 1: obj = POPOSigningKey.getInstance(tagged, false); break; case 2: case 3: obj = POPOPrivKey.getInstance(tagged, true); break; default: throw new IllegalArgumentException("unknown tag: " + tagNo); } } public static ProofOfPossession getInstance(Object o) { if (o == null || o instanceof ProofOfPossession) { return (ProofOfPossession)o; } if (o instanceof ASN1TaggedObject) { return new ProofOfPossession((ASN1TaggedObject)o); } throw new IllegalArgumentException("Invalid object: " + o.getClass().getName()); } /** Creates a ProofOfPossession with type raVerified. */ public ProofOfPossession() { tagNo = TYPE_RA_VERIFIED; obj = DERNull.INSTANCE; } /** Creates a ProofOfPossession for a signing key. */ public ProofOfPossession(POPOSigningKey poposk) { tagNo = TYPE_SIGNING_KEY; obj = poposk; } /** * Creates a ProofOfPossession for key encipherment or agreement. * @param type one of TYPE_KEY_ENCIPHERMENT or TYPE_KEY_AGREEMENT */ public ProofOfPossession(int type, POPOPrivKey privkey) { tagNo = type; obj = privkey; } public int getType() { return tagNo; } public ASN1Encodable getObject() { return obj; } /** *
         * ProofOfPossession ::= CHOICE {
         *                           raVerified        [0] NULL,
         *                           -- used if the RA has already verified that the requester is in
         *                           -- possession of the private key
         *                           signature         [1] POPOSigningKey,
         *                           keyEncipherment   [2] POPOPrivKey,
         *                           keyAgreement      [3] POPOPrivKey }
         * 
    * @return a basic ASN.1 object representation. */ public ASN1Primitive toASN1Primitive() { return new DERTaggedObject(false, tagNo, obj); } } bouncycastle-1.49.orig/src/org/bouncycastle/asn1/crmf/POPOPrivKey.java0000644000175000017500000000567711725324036025247 0ustar ebourgebourgpackage org.bouncycastle.asn1.crmf; import org.bouncycastle.asn1.ASN1Choice; import org.bouncycastle.asn1.ASN1Encodable; import org.bouncycastle.asn1.ASN1Integer; import org.bouncycastle.asn1.ASN1Object; import org.bouncycastle.asn1.ASN1Primitive; import org.bouncycastle.asn1.ASN1TaggedObject; import org.bouncycastle.asn1.DERBitString; import org.bouncycastle.asn1.DERTaggedObject; import org.bouncycastle.asn1.cms.EnvelopedData; public class POPOPrivKey extends ASN1Object implements ASN1Choice { public static final int thisMessage = 0; public static final int subsequentMessage = 1; public static final int dhMAC = 2; public static final int agreeMAC = 3; public static final int encryptedKey = 4; private int tagNo; private ASN1Encodable obj; private POPOPrivKey(ASN1TaggedObject obj) { this.tagNo = obj.getTagNo(); switch (tagNo) { case thisMessage: this.obj = DERBitString.getInstance(obj, false); break; case subsequentMessage: this.obj = SubsequentMessage.valueOf(ASN1Integer.getInstance(obj, false).getValue().intValue()); break; case dhMAC: this.obj = DERBitString.getInstance(obj, false); break; case agreeMAC: this.obj = PKMACValue.getInstance(obj, false); break; case encryptedKey: this.obj = EnvelopedData.getInstance(obj, false); break; default: throw new IllegalArgumentException("unknown tag in POPOPrivKey"); } } public static POPOPrivKey getInstance(Object obj) { if (obj instanceof POPOPrivKey) { return (POPOPrivKey)obj; } if (obj != null) { return new POPOPrivKey(ASN1TaggedObject.getInstance(obj)); } return null; } public static POPOPrivKey getInstance(ASN1TaggedObject obj, boolean explicit) { return getInstance(ASN1TaggedObject.getInstance(obj, explicit)); } public POPOPrivKey(SubsequentMessage msg) { this.tagNo = subsequentMessage; this.obj = msg; } public int getType() { return tagNo; } public ASN1Encodable getValue() { return obj; } /** *
         * POPOPrivKey ::= CHOICE {
         *        thisMessage       [0] BIT STRING,         -- Deprecated
         *         -- possession is proven in this message (which contains the private
         *         -- key itself (encrypted for the CA))
         *        subsequentMessage [1] SubsequentMessage,
         *         -- possession will be proven in a subsequent message
         *        dhMAC             [2] BIT STRING,         -- Deprecated
         *        agreeMAC          [3] PKMACValue,
         *        encryptedKey      [4] EnvelopedData }
         * 
    */ public ASN1Primitive toASN1Primitive() { return new DERTaggedObject(false, tagNo, obj); } } bouncycastle-1.49.orig/src/org/bouncycastle/asn1/DERBitString.java0000644000175000017500000001626111737006105024455 0ustar ebourgebourgpackage org.bouncycastle.asn1; import java.io.ByteArrayOutputStream; import java.io.EOFException; import java.io.IOException; import java.io.InputStream; import org.bouncycastle.util.Arrays; import org.bouncycastle.util.io.Streams; public class DERBitString extends ASN1Primitive implements ASN1String { private static final char[] table = { '0', '1', '2', '3', '4', '5', '6', '7', '8', '9', 'A', 'B', 'C', 'D', 'E', 'F' }; protected byte[] data; protected int padBits; /** * return the correct number of pad bits for a bit string defined in * a 32 bit constant */ static protected int getPadBits( int bitString) { int val = 0; for (int i = 3; i >= 0; i--) { // // this may look a little odd, but if it isn't done like this pre jdk1.2 // JVM's break! // if (i != 0) { if ((bitString >> (i * 8)) != 0) { val = (bitString >> (i * 8)) & 0xFF; break; } } else { if (bitString != 0) { val = bitString & 0xFF; break; } } } if (val == 0) { return 7; } int bits = 1; while (((val <<= 1) & 0xFF) != 0) { bits++; } return 8 - bits; } /** * return the correct number of bytes for a bit string defined in * a 32 bit constant */ static protected byte[] getBytes(int bitString) { int bytes = 4; for (int i = 3; i >= 1; i--) { if ((bitString & (0xFF << (i * 8))) != 0) { break; } bytes--; } byte[] result = new byte[bytes]; for (int i = 0; i < bytes; i++) { result[i] = (byte) ((bitString >> (i * 8)) & 0xFF); } return result; } /** * return a Bit String from the passed in object * * @exception IllegalArgumentException if the object cannot be converted. */ public static DERBitString getInstance( Object obj) { if (obj == null || obj instanceof DERBitString) { return (DERBitString)obj; } throw new IllegalArgumentException("illegal object in getInstance: " + obj.getClass().getName()); } /** * return a Bit String from a tagged object. * * @param obj the tagged object holding the object we want * @param explicit true if the object is meant to be explicitly * tagged false otherwise. * @exception IllegalArgumentException if the tagged object cannot * be converted. */ public static DERBitString getInstance( ASN1TaggedObject obj, boolean explicit) { ASN1Primitive o = obj.getObject(); if (explicit || o instanceof DERBitString) { return getInstance(o); } else { return fromOctetString(((ASN1OctetString)o).getOctets()); } } protected DERBitString( byte data, int padBits) { this.data = new byte[1]; this.data[0] = data; this.padBits = padBits; } /** * @param data the octets making up the bit string. * @param padBits the number of extra bits at the end of the string. */ public DERBitString( byte[] data, int padBits) { this.data = data; this.padBits = padBits; } public DERBitString( byte[] data) { this(data, 0); } public DERBitString( int value) { this.data = getBytes(value); this.padBits = getPadBits(value); } public DERBitString( ASN1Encodable obj) throws IOException { this.data = obj.toASN1Primitive().getEncoded(ASN1Encoding.DER); this.padBits = 0; } public byte[] getBytes() { return data; } public int getPadBits() { return padBits; } /** * @return the value of the bit string as an int (truncating if necessary) */ public int intValue() { int value = 0; for (int i = 0; i != data.length && i != 4; i++) { value |= (data[i] & 0xff) << (8 * i); } return value; } boolean isConstructed() { return false; } int encodedLength() { return 1 + StreamUtil.calculateBodyLength(data.length + 1) + data.length + 1; } void encode( ASN1OutputStream out) throws IOException { byte[] bytes = new byte[getBytes().length + 1]; bytes[0] = (byte)getPadBits(); System.arraycopy(getBytes(), 0, bytes, 1, bytes.length - 1); out.writeEncoded(BERTags.BIT_STRING, bytes); } public int hashCode() { return padBits ^ Arrays.hashCode(data); } protected boolean asn1Equals( ASN1Primitive o) { if (!(o instanceof DERBitString)) { return false; } DERBitString other = (DERBitString)o; return this.padBits == other.padBits && Arrays.areEqual(this.data, other.data); } public String getString() { StringBuffer buf = new StringBuffer("#"); ByteArrayOutputStream bOut = new ByteArrayOutputStream(); ASN1OutputStream aOut = new ASN1OutputStream(bOut); try { aOut.writeObject(this); } catch (IOException e) { throw new RuntimeException("internal error encoding BitString"); } byte[] string = bOut.toByteArray(); for (int i = 0; i != string.length; i++) { buf.append(table[(string[i] >>> 4) & 0xf]); buf.append(table[string[i] & 0xf]); } return buf.toString(); } public String toString() { return getString(); } static DERBitString fromOctetString(byte[] bytes) { if (bytes.length < 1) { throw new IllegalArgumentException("truncated BIT STRING detected"); } int padBits = bytes[0]; byte[] data = new byte[bytes.length - 1]; if (data.length != 0) { System.arraycopy(bytes, 1, data, 0, bytes.length - 1); } return new DERBitString(data, padBits); } static DERBitString fromInputStream(int length, InputStream stream) throws IOException { if (length < 1) { throw new IllegalArgumentException("truncated BIT STRING detected"); } int padBits = stream.read(); byte[] data = new byte[length - 1]; if (data.length != 0) { if (Streams.readFully(stream, data) != data.length) { throw new EOFException("EOF encountered in middle of BIT STRING"); } } return new DERBitString(data, padBits); } } bouncycastle-1.49.orig/src/org/bouncycastle/asn1/DERExternalParser.java0000644000175000017500000000213711624650365025514 0ustar ebourgebourgpackage org.bouncycastle.asn1; import java.io.IOException; public class DERExternalParser implements ASN1Encodable, InMemoryRepresentable { private ASN1StreamParser _parser; /** * */ public DERExternalParser(ASN1StreamParser parser) { this._parser = parser; } public ASN1Encodable readObject() throws IOException { return _parser.readObject(); } public ASN1Primitive getLoadedObject() throws IOException { try { return new DERExternal(_parser.readVector()); } catch (IllegalArgumentException e) { throw new ASN1Exception(e.getMessage(), e); } } public ASN1Primitive toASN1Primitive() { try { return getLoadedObject(); } catch (IOException ioe) { throw new ASN1ParsingException("unable to get DER object", ioe); } catch (IllegalArgumentException ioe) { throw new ASN1ParsingException("unable to get DER object", ioe); } } } bouncycastle-1.49.orig/src/org/bouncycastle/asn1/DERUTCTime.java0000644000175000017500000001555712062243503024026 0ustar ebourgebourgpackage org.bouncycastle.asn1; import java.io.IOException; import java.text.ParseException; import java.text.SimpleDateFormat; import java.util.Date; import java.util.SimpleTimeZone; import org.bouncycastle.util.Arrays; import org.bouncycastle.util.Strings; /** * UTC time object. */ public class DERUTCTime extends ASN1Primitive { private byte[] time; /** * return an UTC Time from the passed in object. * * @exception IllegalArgumentException if the object cannot be converted. */ public static ASN1UTCTime getInstance( Object obj) { if (obj == null || obj instanceof ASN1UTCTime) { return (ASN1UTCTime)obj; } if (obj instanceof DERUTCTime) { return new ASN1UTCTime(((DERUTCTime)obj).time); } if (obj instanceof byte[]) { try { return (ASN1UTCTime)fromByteArray((byte[])obj); } catch (Exception e) { throw new IllegalArgumentException("encoding error in getInstance: " + e.toString()); } } throw new IllegalArgumentException("illegal object in getInstance: " + obj.getClass().getName()); } /** * return an UTC Time from a tagged object. * * @param obj the tagged object holding the object we want * @param explicit true if the object is meant to be explicitly * tagged false otherwise. * @exception IllegalArgumentException if the tagged object cannot * be converted. */ public static ASN1UTCTime getInstance( ASN1TaggedObject obj, boolean explicit) { ASN1Object o = obj.getObject(); if (explicit || o instanceof ASN1UTCTime) { return getInstance(o); } else { return new ASN1UTCTime(((ASN1OctetString)o).getOctets()); } } /** * The correct format for this is YYMMDDHHMMSSZ (it used to be that seconds were * never encoded. When you're creating one of these objects from scratch, that's * what you want to use, otherwise we'll try to deal with whatever gets read from * the input stream... (this is why the input format is different from the getTime() * method output). *

    * * @param time the time string. */ public DERUTCTime( String time) { this.time = Strings.toByteArray(time); try { this.getDate(); } catch (ParseException e) { throw new IllegalArgumentException("invalid date string: " + e.getMessage()); } } /** * base constructer from a java.util.date object */ public DERUTCTime( Date time) { SimpleDateFormat dateF = new SimpleDateFormat("yyMMddHHmmss'Z'"); dateF.setTimeZone(new SimpleTimeZone(0,"Z")); this.time = Strings.toByteArray(dateF.format(time)); } DERUTCTime( byte[] time) { this.time = time; } /** * return the time as a date based on whatever a 2 digit year will return. For * standardised processing use getAdjustedDate(). * * @return the resulting date * @exception ParseException if the date string cannot be parsed. */ public Date getDate() throws ParseException { SimpleDateFormat dateF = new SimpleDateFormat("yyMMddHHmmssz"); return dateF.parse(getTime()); } /** * return the time as an adjusted date * in the range of 1950 - 2049. * * @return a date in the range of 1950 to 2049. * @exception ParseException if the date string cannot be parsed. */ public Date getAdjustedDate() throws ParseException { SimpleDateFormat dateF = new SimpleDateFormat("yyyyMMddHHmmssz"); dateF.setTimeZone(new SimpleTimeZone(0, "Z")); return dateF.parse(getAdjustedTime()); } /** * return the time - always in the form of * YYMMDDhhmmssGMT(+hh:mm|-hh:mm). *

    * Normally in a certificate we would expect "Z" rather than "GMT", * however adding the "GMT" means we can just use: *

         *     dateF = new SimpleDateFormat("yyMMddHHmmssz");
         * 
    * To read in the time and get a date which is compatible with our local * time zone. *

    * Note: In some cases, due to the local date processing, this * may lead to unexpected results. If you want to stick the normal * convention of 1950 to 2049 use the getAdjustedTime() method. */ public String getTime() { String stime = Strings.fromByteArray(time); // // standardise the format. // if (stime.indexOf('-') < 0 && stime.indexOf('+') < 0) { if (stime.length() == 11) { return stime.substring(0, 10) + "00GMT+00:00"; } else { return stime.substring(0, 12) + "GMT+00:00"; } } else { int index = stime.indexOf('-'); if (index < 0) { index = stime.indexOf('+'); } String d = stime; if (index == stime.length() - 3) { d += "00"; } if (index == 10) { return d.substring(0, 10) + "00GMT" + d.substring(10, 13) + ":" + d.substring(13, 15); } else { return d.substring(0, 12) + "GMT" + d.substring(12, 15) + ":" + d.substring(15, 17); } } } /** * return a time string as an adjusted date with a 4 digit year. This goes * in the range of 1950 - 2049. */ public String getAdjustedTime() { String d = this.getTime(); if (d.charAt(0) < '5') { return "20" + d; } else { return "19" + d; } } boolean isConstructed() { return false; } int encodedLength() { int length = time.length; return 1 + StreamUtil.calculateBodyLength(length) + length; } void encode( ASN1OutputStream out) throws IOException { out.write(BERTags.UTC_TIME); int length = time.length; out.writeLength(length); for (int i = 0; i != length; i++) { out.write((byte)time[i]); } } boolean asn1Equals( ASN1Primitive o) { if (!(o instanceof DERUTCTime)) { return false; } return Arrays.areEqual(time, ((DERUTCTime)o).time); } public int hashCode() { return Arrays.hashCode(time); } public String toString() { return Strings.fromByteArray(time); } } bouncycastle-1.49.orig/src/org/bouncycastle/asn1/DERGeneralizedTime.java0000644000175000017500000002223312062243454025616 0ustar ebourgebourgpackage org.bouncycastle.asn1; import java.io.IOException; import java.text.ParseException; import java.text.SimpleDateFormat; import java.util.Date; import java.util.SimpleTimeZone; import java.util.TimeZone; import org.bouncycastle.util.Arrays; import org.bouncycastle.util.Strings; /** * Generalized time object. */ public class DERGeneralizedTime extends ASN1Primitive { private byte[] time; /** * return a generalized time from the passed in object * * @exception IllegalArgumentException if the object cannot be converted. */ public static ASN1GeneralizedTime getInstance( Object obj) { if (obj == null || obj instanceof ASN1GeneralizedTime) { return (ASN1GeneralizedTime)obj; } if (obj instanceof DERGeneralizedTime) { return new ASN1GeneralizedTime(((DERGeneralizedTime)obj).time); } if (obj instanceof byte[]) { try { return (ASN1GeneralizedTime)fromByteArray((byte[])obj); } catch (Exception e) { throw new IllegalArgumentException("encoding error in getInstance: " + e.toString()); } } throw new IllegalArgumentException("illegal object in getInstance: " + obj.getClass().getName()); } /** * return a Generalized Time object from a tagged object. * * @param obj the tagged object holding the object we want * @param explicit true if the object is meant to be explicitly * tagged false otherwise. * @exception IllegalArgumentException if the tagged object cannot * be converted. */ public static ASN1GeneralizedTime getInstance( ASN1TaggedObject obj, boolean explicit) { ASN1Primitive o = obj.getObject(); if (explicit || o instanceof DERGeneralizedTime) { return getInstance(o); } else { return new ASN1GeneralizedTime(((ASN1OctetString)o).getOctets()); } } /** * The correct format for this is YYYYMMDDHHMMSS[.f]Z, or without the Z * for local time, or Z+-HHMM on the end, for difference between local * time and UTC time. The fractional second amount f must consist of at * least one number with trailing zeroes removed. * * @param time the time string. * @exception IllegalArgumentException if String is an illegal format. */ public DERGeneralizedTime( String time) { this.time = Strings.toByteArray(time); try { this.getDate(); } catch (ParseException e) { throw new IllegalArgumentException("invalid date string: " + e.getMessage()); } } /** * base constructor from a java.util.date object */ public DERGeneralizedTime( Date time) { SimpleDateFormat dateF = new SimpleDateFormat("yyyyMMddHHmmss'Z'"); dateF.setTimeZone(new SimpleTimeZone(0,"Z")); this.time = Strings.toByteArray(dateF.format(time)); } DERGeneralizedTime( byte[] bytes) { this.time = bytes; } /** * Return the time. * @return The time string as it appeared in the encoded object. */ public String getTimeString() { return Strings.fromByteArray(time); } /** * return the time - always in the form of * YYYYMMDDhhmmssGMT(+hh:mm|-hh:mm). *

    * Normally in a certificate we would expect "Z" rather than "GMT", * however adding the "GMT" means we can just use: *

         *     dateF = new SimpleDateFormat("yyyyMMddHHmmssz");
         * 
    * To read in the time and get a date which is compatible with our local * time zone. */ public String getTime() { String stime = Strings.fromByteArray(time); // // standardise the format. // if (stime.charAt(stime.length() - 1) == 'Z') { return stime.substring(0, stime.length() - 1) + "GMT+00:00"; } else { int signPos = stime.length() - 5; char sign = stime.charAt(signPos); if (sign == '-' || sign == '+') { return stime.substring(0, signPos) + "GMT" + stime.substring(signPos, signPos + 3) + ":" + stime.substring(signPos + 3); } else { signPos = stime.length() - 3; sign = stime.charAt(signPos); if (sign == '-' || sign == '+') { return stime.substring(0, signPos) + "GMT" + stime.substring(signPos) + ":00"; } } } return stime + calculateGMTOffset(); } private String calculateGMTOffset() { String sign = "+"; TimeZone timeZone = TimeZone.getDefault(); int offset = timeZone.getRawOffset(); if (offset < 0) { sign = "-"; offset = -offset; } int hours = offset / (60 * 60 * 1000); int minutes = (offset - (hours * 60 * 60 * 1000)) / (60 * 1000); try { if (timeZone.useDaylightTime() && timeZone.inDaylightTime(this.getDate())) { hours += sign.equals("+") ? 1 : -1; } } catch (ParseException e) { // we'll do our best and ignore daylight savings } return "GMT" + sign + convert(hours) + ":" + convert(minutes); } private String convert(int time) { if (time < 10) { return "0" + time; } return Integer.toString(time); } public Date getDate() throws ParseException { SimpleDateFormat dateF; String stime = Strings.fromByteArray(time); String d = stime; if (stime.endsWith("Z")) { if (hasFractionalSeconds()) { dateF = new SimpleDateFormat("yyyyMMddHHmmss.SSS'Z'"); } else { dateF = new SimpleDateFormat("yyyyMMddHHmmss'Z'"); } dateF.setTimeZone(new SimpleTimeZone(0, "Z")); } else if (stime.indexOf('-') > 0 || stime.indexOf('+') > 0) { d = this.getTime(); if (hasFractionalSeconds()) { dateF = new SimpleDateFormat("yyyyMMddHHmmss.SSSz"); } else { dateF = new SimpleDateFormat("yyyyMMddHHmmssz"); } dateF.setTimeZone(new SimpleTimeZone(0, "Z")); } else { if (hasFractionalSeconds()) { dateF = new SimpleDateFormat("yyyyMMddHHmmss.SSS"); } else { dateF = new SimpleDateFormat("yyyyMMddHHmmss"); } dateF.setTimeZone(new SimpleTimeZone(0, TimeZone.getDefault().getID())); } if (hasFractionalSeconds()) { // java misinterprets extra digits as being milliseconds... String frac = d.substring(14); int index; for (index = 1; index < frac.length(); index++) { char ch = frac.charAt(index); if (!('0' <= ch && ch <= '9')) { break; } } if (index - 1 > 3) { frac = frac.substring(0, 4) + frac.substring(index); d = d.substring(0, 14) + frac; } else if (index - 1 == 1) { frac = frac.substring(0, index) + "00" + frac.substring(index); d = d.substring(0, 14) + frac; } else if (index - 1 == 2) { frac = frac.substring(0, index) + "0" + frac.substring(index); d = d.substring(0, 14) + frac; } } return dateF.parse(d); } private boolean hasFractionalSeconds() { for (int i = 0; i != time.length; i++) { if (time[i] == '.') { if (i == 14) { return true; } } } return false; } boolean isConstructed() { return false; } int encodedLength() { int length = time.length; return 1 + StreamUtil.calculateBodyLength(length) + length; } void encode( ASN1OutputStream out) throws IOException { out.writeEncoded(BERTags.GENERALIZED_TIME, time); } boolean asn1Equals( ASN1Primitive o) { if (!(o instanceof DERGeneralizedTime)) { return false; } return Arrays.areEqual(time, ((DERGeneralizedTime)o).time); } public int hashCode() { return Arrays.hashCode(time); } } bouncycastle-1.49.orig/src/org/bouncycastle/asn1/DERT61UTF8String.java0000644000175000017500000000724412135375100024756 0ustar ebourgebourgpackage org.bouncycastle.asn1; import java.io.IOException; import org.bouncycastle.util.Arrays; import org.bouncycastle.util.Strings; /** * DER T61String (also the teletex string) - a "modern" encapsulation that uses UTF-8. If at all possible, avoid this one! It's only for emergencies. * Use UTF8String instead. */ public class DERT61UTF8String extends ASN1Primitive implements ASN1String { private byte[] string; /** * return a T61 string from the passed in object. UTF-8 Encoding is assumed in this case. * * @throws IllegalArgumentException if the object cannot be converted. */ public static DERT61UTF8String getInstance( Object obj) { if (obj instanceof DERT61String) { return new DERT61UTF8String(((DERT61String)obj).getOctets()); } if (obj == null || obj instanceof DERT61UTF8String) { return (DERT61UTF8String)obj; } if (obj instanceof byte[]) { try { return new DERT61UTF8String(((DERT61String)fromByteArray((byte[])obj)).getOctets()); } catch (Exception e) { throw new IllegalArgumentException("encoding error in getInstance: " + e.toString()); } } throw new IllegalArgumentException("illegal object in getInstance: " + obj.getClass().getName()); } /** * return an T61 String from a tagged object. UTF-8 encoding is assumed in this case. * * @param obj the tagged object holding the object we want * @param explicit true if the object is meant to be explicitly * tagged false otherwise. * @throws IllegalArgumentException if the tagged object cannot * be converted. */ public static DERT61UTF8String getInstance( ASN1TaggedObject obj, boolean explicit) { ASN1Primitive o = obj.getObject(); if (explicit || o instanceof DERT61String || o instanceof DERT61UTF8String) { return getInstance(o); } else { return new DERT61UTF8String(ASN1OctetString.getInstance(o).getOctets()); } } /** * basic constructor - string encoded as a sequence of bytes. */ public DERT61UTF8String( byte[] string) { this.string = string; } /** * basic constructor - with string UTF8 conversion assumed. */ public DERT61UTF8String( String string) { this(Strings.toUTF8ByteArray(string)); } /** * Decode the encoded string and return it, UTF8 assumed. * * @return the decoded String */ public String getString() { return Strings.fromUTF8ByteArray(string); } public String toString() { return getString(); } boolean isConstructed() { return false; } int encodedLength() { return 1 + StreamUtil.calculateBodyLength(string.length) + string.length; } void encode( ASN1OutputStream out) throws IOException { out.writeEncoded(BERTags.T61_STRING, string); } /** * Return the encoded string as a byte array. * * @return the actual bytes making up the encoded body of the T61 string. */ public byte[] getOctets() { return Arrays.clone(string); } boolean asn1Equals( ASN1Primitive o) { if (!(o instanceof DERT61UTF8String)) { return false; } return Arrays.areEqual(string, ((DERT61UTF8String)o).string); } public int hashCode() { return Arrays.hashCode(string); } } bouncycastle-1.49.orig/src/org/bouncycastle/asn1/DERGenerator.java0000644000175000017500000000522411624652555024506 0ustar ebourgebourgpackage org.bouncycastle.asn1; import java.io.ByteArrayOutputStream; import java.io.IOException; import java.io.InputStream; import java.io.OutputStream; import org.bouncycastle.util.io.Streams; public abstract class DERGenerator extends ASN1Generator { private boolean _tagged = false; private boolean _isExplicit; private int _tagNo; protected DERGenerator( OutputStream out) { super(out); } public DERGenerator( OutputStream out, int tagNo, boolean isExplicit) { super(out); _tagged = true; _isExplicit = isExplicit; _tagNo = tagNo; } private void writeLength( OutputStream out, int length) throws IOException { if (length > 127) { int size = 1; int val = length; while ((val >>>= 8) != 0) { size++; } out.write((byte)(size | 0x80)); for (int i = (size - 1) * 8; i >= 0; i -= 8) { out.write((byte)(length >> i)); } } else { out.write((byte)length); } } void writeDEREncoded( OutputStream out, int tag, byte[] bytes) throws IOException { out.write(tag); writeLength(out, bytes.length); out.write(bytes); } void writeDEREncoded( int tag, byte[] bytes) throws IOException { if (_tagged) { int tagNum = _tagNo | BERTags.TAGGED; if (_isExplicit) { int newTag = _tagNo | BERTags.CONSTRUCTED | BERTags.TAGGED; ByteArrayOutputStream bOut = new ByteArrayOutputStream(); writeDEREncoded(bOut, tag, bytes); writeDEREncoded(_out, newTag, bOut.toByteArray()); } else { if ((tag & BERTags.CONSTRUCTED) != 0) { writeDEREncoded(_out, tagNum | BERTags.CONSTRUCTED, bytes); } else { writeDEREncoded(_out, tagNum, bytes); } } } else { writeDEREncoded(_out, tag, bytes); } } void writeDEREncoded( OutputStream out, int tag, InputStream in) throws IOException { writeDEREncoded(out, tag, Streams.readAll(in)); } } bouncycastle-1.49.orig/src/org/bouncycastle/asn1/BERFactory.java0000644000175000017500000000065611625075064024164 0ustar ebourgebourgpackage org.bouncycastle.asn1; class BERFactory { static final BERSequence EMPTY_SEQUENCE = new BERSequence(); static final BERSet EMPTY_SET = new BERSet(); static BERSequence createSequence(ASN1EncodableVector v) { return v.size() < 1 ? EMPTY_SEQUENCE : new BERSequence(v); } static BERSet createSet(ASN1EncodableVector v) { return v.size() < 1 ? EMPTY_SET : new BERSet(v); } } bouncycastle-1.49.orig/src/org/bouncycastle/asn1/oiw/0000755000175000017500000000000012152033551022137 5ustar ebourgebourgbouncycastle-1.49.orig/src/org/bouncycastle/asn1/oiw/ElGamalParameter.java0000644000175000017500000000220011724561172026150 0ustar ebourgebourgpackage org.bouncycastle.asn1.oiw; import java.math.BigInteger; import java.util.Enumeration; import org.bouncycastle.asn1.ASN1EncodableVector; import org.bouncycastle.asn1.ASN1Integer; import org.bouncycastle.asn1.ASN1Object; import org.bouncycastle.asn1.ASN1Primitive; import org.bouncycastle.asn1.ASN1Sequence; import org.bouncycastle.asn1.DERSequence; public class ElGamalParameter extends ASN1Object { ASN1Integer p, g; public ElGamalParameter( BigInteger p, BigInteger g) { this.p = new ASN1Integer(p); this.g = new ASN1Integer(g); } public ElGamalParameter( ASN1Sequence seq) { Enumeration e = seq.getObjects(); p = (ASN1Integer)e.nextElement(); g = (ASN1Integer)e.nextElement(); } public BigInteger getP() { return p.getPositiveValue(); } public BigInteger getG() { return g.getPositiveValue(); } public ASN1Primitive toASN1Primitive() { ASN1EncodableVector v = new ASN1EncodableVector(); v.add(p); v.add(g); return new DERSequence(v); } } bouncycastle-1.49.orig/src/org/bouncycastle/asn1/oiw/OIWObjectIdentifiers.java0000644000175000017500000000332011624622714026763 0ustar ebourgebourgpackage org.bouncycastle.asn1.oiw; import org.bouncycastle.asn1.ASN1ObjectIdentifier; public interface OIWObjectIdentifiers { // id-SHA1 OBJECT IDENTIFIER ::= // {iso(1) identified-organization(3) oiw(14) secsig(3) algorithms(2) 26 } // static final ASN1ObjectIdentifier md4WithRSA = new ASN1ObjectIdentifier("1.3.14.3.2.2"); static final ASN1ObjectIdentifier md5WithRSA = new ASN1ObjectIdentifier("1.3.14.3.2.3"); static final ASN1ObjectIdentifier md4WithRSAEncryption = new ASN1ObjectIdentifier("1.3.14.3.2.4"); static final ASN1ObjectIdentifier desECB = new ASN1ObjectIdentifier("1.3.14.3.2.6"); static final ASN1ObjectIdentifier desCBC = new ASN1ObjectIdentifier("1.3.14.3.2.7"); static final ASN1ObjectIdentifier desOFB = new ASN1ObjectIdentifier("1.3.14.3.2.8"); static final ASN1ObjectIdentifier desCFB = new ASN1ObjectIdentifier("1.3.14.3.2.9"); static final ASN1ObjectIdentifier desEDE = new ASN1ObjectIdentifier("1.3.14.3.2.17"); static final ASN1ObjectIdentifier idSHA1 = new ASN1ObjectIdentifier("1.3.14.3.2.26"); static final ASN1ObjectIdentifier dsaWithSHA1 = new ASN1ObjectIdentifier("1.3.14.3.2.27"); static final ASN1ObjectIdentifier sha1WithRSA = new ASN1ObjectIdentifier("1.3.14.3.2.29"); // ElGamal Algorithm OBJECT IDENTIFIER ::= // {iso(1) identified-organization(3) oiw(14) dirservsig(7) algorithm(2) encryption(1) 1 } // static final ASN1ObjectIdentifier elGamalAlgorithm = new ASN1ObjectIdentifier("1.3.14.7.2.1.1"); } bouncycastle-1.49.orig/src/org/bouncycastle/asn1/oiw/package.html0000644000175000017500000000013410262753175024431 0ustar ebourgebourg Objects and OID for the support of ISO OIW. bouncycastle-1.49.orig/src/org/bouncycastle/asn1/ASN1Sequence.java0000644000175000017500000001757211703171235024416 0ustar ebourgebourgpackage org.bouncycastle.asn1; import java.io.IOException; import java.util.Enumeration; import java.util.Vector; public abstract class ASN1Sequence extends ASN1Primitive { protected Vector seq = new Vector(); /** * return an ASN1Sequence from the given object. * * @param obj the object we want converted. * @exception IllegalArgumentException if the object cannot be converted. */ public static ASN1Sequence getInstance( Object obj) { if (obj == null || obj instanceof ASN1Sequence) { return (ASN1Sequence)obj; } else if (obj instanceof ASN1SequenceParser) { return ASN1Sequence.getInstance(((ASN1SequenceParser)obj).toASN1Primitive()); } else if (obj instanceof byte[]) { try { return ASN1Sequence.getInstance(fromByteArray((byte[])obj)); } catch (IOException e) { throw new IllegalArgumentException("failed to construct sequence from byte[]: " + e.getMessage()); } } else if (obj instanceof ASN1Encodable) { ASN1Primitive primitive = ((ASN1Encodable)obj).toASN1Primitive(); if (primitive instanceof ASN1Sequence) { return (ASN1Sequence)primitive; } } throw new IllegalArgumentException("unknown object in getInstance: " + obj.getClass().getName()); } /** * Return an ASN1 sequence from a tagged object. There is a special * case here, if an object appears to have been explicitly tagged on * reading but we were expecting it to be implicitly tagged in the * normal course of events it indicates that we lost the surrounding * sequence - so we need to add it back (this will happen if the tagged * object is a sequence that contains other sequences). If you are * dealing with implicitly tagged sequences you really should * be using this method. * * @param obj the tagged object. * @param explicit true if the object is meant to be explicitly tagged, * false otherwise. * @exception IllegalArgumentException if the tagged object cannot * be converted. */ public static ASN1Sequence getInstance( ASN1TaggedObject obj, boolean explicit) { if (explicit) { if (!obj.isExplicit()) { throw new IllegalArgumentException("object implicit - explicit expected."); } return ASN1Sequence.getInstance(obj.getObject().toASN1Primitive()); } else { // // constructed object which appears to be explicitly tagged // when it should be implicit means we have to add the // surrounding sequence. // if (obj.isExplicit()) { if (obj instanceof BERTaggedObject) { return new BERSequence(obj.getObject()); } else { return new DLSequence(obj.getObject()); } } else { if (obj.getObject() instanceof ASN1Sequence) { return (ASN1Sequence)obj.getObject(); } } } throw new IllegalArgumentException("unknown object in getInstance: " + obj.getClass().getName()); } /** * create an empty sequence */ protected ASN1Sequence() { } /** * create a sequence containing one object */ protected ASN1Sequence( ASN1Encodable obj) { seq.addElement(obj); } /** * create a sequence containing a vector of objects. */ protected ASN1Sequence( ASN1EncodableVector v) { for (int i = 0; i != v.size(); i++) { seq.addElement(v.get(i)); } } /** * create a sequence containing a vector of objects. */ protected ASN1Sequence( ASN1Encodable[] array) { for (int i = 0; i != array.length; i++) { seq.addElement(array[i]); } } public ASN1Encodable[] toArray() { ASN1Encodable[] values = new ASN1Encodable[this.size()]; for (int i = 0; i != this.size(); i++) { values[i] = this.getObjectAt(i); } return values; } public Enumeration getObjects() { return seq.elements(); } public ASN1SequenceParser parser() { final ASN1Sequence outer = this; return new ASN1SequenceParser() { private final int max = size(); private int index; public ASN1Encodable readObject() throws IOException { if (index == max) { return null; } ASN1Encodable obj = getObjectAt(index++); if (obj instanceof ASN1Sequence) { return ((ASN1Sequence)obj).parser(); } if (obj instanceof ASN1Set) { return ((ASN1Set)obj).parser(); } return obj; } public ASN1Primitive getLoadedObject() { return outer; } public ASN1Primitive toASN1Primitive() { return outer; } }; } /** * return the object at the sequence position indicated by index. * * @param index the sequence number (starting at zero) of the object * @return the object at the sequence position indicated by index. */ public ASN1Encodable getObjectAt( int index) { return (ASN1Encodable)seq.elementAt(index); } /** * return the number of objects in this sequence. * * @return the number of objects in this sequence. */ public int size() { return seq.size(); } public int hashCode() { Enumeration e = this.getObjects(); int hashCode = size(); while (e.hasMoreElements()) { Object o = getNext(e); hashCode *= 17; hashCode ^= o.hashCode(); } return hashCode; } boolean asn1Equals( ASN1Primitive o) { if (!(o instanceof ASN1Sequence)) { return false; } ASN1Sequence other = (ASN1Sequence)o; if (this.size() != other.size()) { return false; } Enumeration s1 = this.getObjects(); Enumeration s2 = other.getObjects(); while (s1.hasMoreElements()) { ASN1Encodable obj1 = getNext(s1); ASN1Encodable obj2 = getNext(s2); ASN1Primitive o1 = obj1.toASN1Primitive(); ASN1Primitive o2 = obj2.toASN1Primitive(); if (o1 == o2 || o1.equals(o2)) { continue; } return false; } return true; } private ASN1Encodable getNext(Enumeration e) { ASN1Encodable encObj = (ASN1Encodable)e.nextElement(); return encObj; } ASN1Primitive toDERObject() { ASN1Sequence derSeq = new DERSequence(); derSeq.seq = this.seq; return derSeq; } ASN1Primitive toDLObject() { ASN1Sequence dlSeq = new DLSequence(); dlSeq.seq = this.seq; return dlSeq; } boolean isConstructed() { return true; } abstract void encode(ASN1OutputStream out) throws IOException; public String toString() { return seq.toString(); } } bouncycastle-1.49.orig/src/org/bouncycastle/asn1/IndefiniteLengthInputStream.java0000644000175000017500000000404411625105237027627 0ustar ebourgebourgpackage org.bouncycastle.asn1; import java.io.EOFException; import java.io.IOException; import java.io.InputStream; class IndefiniteLengthInputStream extends LimitedInputStream { private int _b1; private int _b2; private boolean _eofReached = false; private boolean _eofOn00 = true; IndefiniteLengthInputStream( InputStream in, int limit) throws IOException { super(in, limit); _b1 = in.read(); _b2 = in.read(); if (_b2 < 0) { // Corrupted stream throw new EOFException(); } checkForEof(); } void setEofOn00( boolean eofOn00) { _eofOn00 = eofOn00; checkForEof(); } private boolean checkForEof() { if (!_eofReached && _eofOn00 && (_b1 == 0x00 && _b2 == 0x00)) { _eofReached = true; setParentEofDetect(true); } return _eofReached; } public int read(byte[] b, int off, int len) throws IOException { // Only use this optimisation if we aren't checking for 00 if (_eofOn00 || len < 3) { return super.read(b, off, len); } if (_eofReached) { return -1; } int numRead = _in.read(b, off + 2, len - 2); if (numRead < 0) { // Corrupted stream throw new EOFException(); } b[off] = (byte)_b1; b[off + 1] = (byte)_b2; _b1 = _in.read(); _b2 = _in.read(); if (_b2 < 0) { // Corrupted stream throw new EOFException(); } return numRead + 2; } public int read() throws IOException { if (checkForEof()) { return -1; } int b = _in.read(); if (b < 0) { // Corrupted stream throw new EOFException(); } int v = _b1; _b1 = _b2; _b2 = b; return v; } } bouncycastle-1.49.orig/src/org/bouncycastle/asn1/x9/0000755000175000017500000000000012152033551021701 5ustar ebourgebourgbouncycastle-1.49.orig/src/org/bouncycastle/asn1/x9/X9FieldID.java0000644000175000017500000000653711724561172024251 0ustar ebourgebourgpackage org.bouncycastle.asn1.x9; import java.math.BigInteger; import org.bouncycastle.asn1.ASN1EncodableVector; import org.bouncycastle.asn1.ASN1Integer; import org.bouncycastle.asn1.ASN1Object; import org.bouncycastle.asn1.ASN1ObjectIdentifier; import org.bouncycastle.asn1.ASN1Primitive; import org.bouncycastle.asn1.ASN1Sequence; import org.bouncycastle.asn1.DERSequence; /** * ASN.1 def for Elliptic-Curve Field ID structure. See * X9.62, for further details. */ public class X9FieldID extends ASN1Object implements X9ObjectIdentifiers { private ASN1ObjectIdentifier id; private ASN1Primitive parameters; /** * Constructor for elliptic curves over prime fields * F2. * @param primeP The prime p defining the prime field. */ public X9FieldID(BigInteger primeP) { this.id = prime_field; this.parameters = new ASN1Integer(primeP); } /** * Constructor for elliptic curves over binary fields * F2m. * @param m The exponent m of * F2m. * @param k1 The integer k1 where xm + * xk3 + xk2 + xk1 + 1 * represents the reduction polynomial f(z). * @param k2 The integer k2 where xm + * xk3 + xk2 + xk1 + 1 * represents the reduction polynomial f(z). * @param k3 The integer k3 where xm + * xk3 + xk2 + xk1 + 1 * represents the reduction polynomial f(z).. */ public X9FieldID(int m, int k1, int k2, int k3) { this.id = characteristic_two_field; ASN1EncodableVector fieldIdParams = new ASN1EncodableVector(); fieldIdParams.add(new ASN1Integer(m)); if (k2 == 0) { fieldIdParams.add(tpBasis); fieldIdParams.add(new ASN1Integer(k1)); } else { fieldIdParams.add(ppBasis); ASN1EncodableVector pentanomialParams = new ASN1EncodableVector(); pentanomialParams.add(new ASN1Integer(k1)); pentanomialParams.add(new ASN1Integer(k2)); pentanomialParams.add(new ASN1Integer(k3)); fieldIdParams.add(new DERSequence(pentanomialParams)); } this.parameters = new DERSequence(fieldIdParams); } public X9FieldID( ASN1Sequence seq) { this.id = (ASN1ObjectIdentifier)seq.getObjectAt(0); this.parameters = (ASN1Primitive)seq.getObjectAt(1); } public ASN1ObjectIdentifier getIdentifier() { return id; } public ASN1Primitive getParameters() { return parameters; } /** * Produce a DER encoding of the following structure. *
         *  FieldID ::= SEQUENCE {
         *      fieldType       FIELD-ID.&id({IOSet}),
         *      parameters      FIELD-ID.&Type({IOSet}{@fieldType})
         *  }
         * 
    */ public ASN1Primitive toASN1Primitive() { ASN1EncodableVector v = new ASN1EncodableVector(); v.add(this.id); v.add(this.parameters); return new DERSequence(v); } } bouncycastle-1.49.orig/src/org/bouncycastle/asn1/x9/DHValidationParms.java0000644000175000017500000000424211724561172026070 0ustar ebourgebourgpackage org.bouncycastle.asn1.x9; import org.bouncycastle.asn1.ASN1EncodableVector; import org.bouncycastle.asn1.ASN1Integer; import org.bouncycastle.asn1.ASN1Object; import org.bouncycastle.asn1.ASN1Primitive; import org.bouncycastle.asn1.ASN1Sequence; import org.bouncycastle.asn1.ASN1TaggedObject; import org.bouncycastle.asn1.DERBitString; import org.bouncycastle.asn1.DERSequence; public class DHValidationParms extends ASN1Object { private DERBitString seed; private ASN1Integer pgenCounter; public static DHValidationParms getInstance(ASN1TaggedObject obj, boolean explicit) { return getInstance(ASN1Sequence.getInstance(obj, explicit)); } public static DHValidationParms getInstance(Object obj) { if (obj == null || obj instanceof DHDomainParameters) { return (DHValidationParms)obj; } if (obj instanceof ASN1Sequence) { return new DHValidationParms((ASN1Sequence)obj); } throw new IllegalArgumentException("Invalid DHValidationParms: " + obj.getClass().getName()); } public DHValidationParms(DERBitString seed, ASN1Integer pgenCounter) { if (seed == null) { throw new IllegalArgumentException("'seed' cannot be null"); } if (pgenCounter == null) { throw new IllegalArgumentException("'pgenCounter' cannot be null"); } this.seed = seed; this.pgenCounter = pgenCounter; } private DHValidationParms(ASN1Sequence seq) { if (seq.size() != 2) { throw new IllegalArgumentException("Bad sequence size: " + seq.size()); } this.seed = DERBitString.getInstance(seq.getObjectAt(0)); this.pgenCounter = ASN1Integer.getInstance(seq.getObjectAt(1)); } public DERBitString getSeed() { return this.seed; } public ASN1Integer getPgenCounter() { return this.pgenCounter; } public ASN1Primitive toASN1Primitive() { ASN1EncodableVector v = new ASN1EncodableVector(); v.add(this.seed); v.add(this.pgenCounter); return new DERSequence(v); } } bouncycastle-1.49.orig/src/org/bouncycastle/asn1/x9/DHDomainParameters.java0000644000175000017500000000661411724561172026233 0ustar ebourgebourgpackage org.bouncycastle.asn1.x9; import java.util.Enumeration; import org.bouncycastle.asn1.ASN1Encodable; import org.bouncycastle.asn1.ASN1EncodableVector; import org.bouncycastle.asn1.ASN1Integer; import org.bouncycastle.asn1.ASN1Object; import org.bouncycastle.asn1.ASN1Primitive; import org.bouncycastle.asn1.ASN1Sequence; import org.bouncycastle.asn1.ASN1TaggedObject; import org.bouncycastle.asn1.DERSequence; public class DHDomainParameters extends ASN1Object { private ASN1Integer p, g, q, j; private DHValidationParms validationParms; public static DHDomainParameters getInstance(ASN1TaggedObject obj, boolean explicit) { return getInstance(ASN1Sequence.getInstance(obj, explicit)); } public static DHDomainParameters getInstance(Object obj) { if (obj == null || obj instanceof DHDomainParameters) { return (DHDomainParameters)obj; } if (obj instanceof ASN1Sequence) { return new DHDomainParameters((ASN1Sequence)obj); } throw new IllegalArgumentException("Invalid DHDomainParameters: " + obj.getClass().getName()); } public DHDomainParameters(ASN1Integer p, ASN1Integer g, ASN1Integer q, ASN1Integer j, DHValidationParms validationParms) { if (p == null) { throw new IllegalArgumentException("'p' cannot be null"); } if (g == null) { throw new IllegalArgumentException("'g' cannot be null"); } if (q == null) { throw new IllegalArgumentException("'q' cannot be null"); } this.p = p; this.g = g; this.q = q; this.j = j; this.validationParms = validationParms; } private DHDomainParameters(ASN1Sequence seq) { if (seq.size() < 3 || seq.size() > 5) { throw new IllegalArgumentException("Bad sequence size: " + seq.size()); } Enumeration e = seq.getObjects(); this.p = ASN1Integer.getInstance(e.nextElement()); this.g = ASN1Integer.getInstance(e.nextElement()); this.q = ASN1Integer.getInstance(e.nextElement()); ASN1Encodable next = getNext(e); if (next != null && next instanceof ASN1Integer) { this.j = ASN1Integer.getInstance(next); next = getNext(e); } if (next != null) { this.validationParms = DHValidationParms.getInstance(next.toASN1Primitive()); } } private static ASN1Encodable getNext(Enumeration e) { return e.hasMoreElements() ? (ASN1Encodable)e.nextElement() : null; } public ASN1Integer getP() { return this.p; } public ASN1Integer getG() { return this.g; } public ASN1Integer getQ() { return this.q; } public ASN1Integer getJ() { return this.j; } public DHValidationParms getValidationParms() { return this.validationParms; } public ASN1Primitive toASN1Primitive() { ASN1EncodableVector v = new ASN1EncodableVector(); v.add(this.p); v.add(this.g); v.add(this.q); if (this.j != null) { v.add(this.j); } if (this.validationParms != null) { v.add(this.validationParms); } return new DERSequence(v); } } bouncycastle-1.49.orig/src/org/bouncycastle/asn1/x9/OtherInfo.java0000644000175000017500000000446111624645077024465 0ustar ebourgebourgpackage org.bouncycastle.asn1.x9; import java.util.Enumeration; import org.bouncycastle.asn1.ASN1EncodableVector; import org.bouncycastle.asn1.ASN1Object; import org.bouncycastle.asn1.ASN1OctetString; import org.bouncycastle.asn1.ASN1Primitive; import org.bouncycastle.asn1.ASN1Sequence; import org.bouncycastle.asn1.DERSequence; import org.bouncycastle.asn1.DERTaggedObject; /** * ANS.1 def for Diffie-Hellman key exchange OtherInfo structure. See * RFC 2631, or X9.42, for further details. */ public class OtherInfo extends ASN1Object { private KeySpecificInfo keyInfo; private ASN1OctetString partyAInfo; private ASN1OctetString suppPubInfo; public OtherInfo( KeySpecificInfo keyInfo, ASN1OctetString partyAInfo, ASN1OctetString suppPubInfo) { this.keyInfo = keyInfo; this.partyAInfo = partyAInfo; this.suppPubInfo = suppPubInfo; } public OtherInfo( ASN1Sequence seq) { Enumeration e = seq.getObjects(); keyInfo = new KeySpecificInfo((ASN1Sequence)e.nextElement()); while (e.hasMoreElements()) { DERTaggedObject o = (DERTaggedObject)e.nextElement(); if (o.getTagNo() == 0) { partyAInfo = (ASN1OctetString)o.getObject(); } else if (o.getTagNo() == 2) { suppPubInfo = (ASN1OctetString)o.getObject(); } } } public KeySpecificInfo getKeyInfo() { return keyInfo; } public ASN1OctetString getPartyAInfo() { return partyAInfo; } public ASN1OctetString getSuppPubInfo() { return suppPubInfo; } /** * Produce an object suitable for an ASN1OutputStream. *
         *  OtherInfo ::= SEQUENCE {
         *      keyInfo KeySpecificInfo,
         *      partyAInfo [0] OCTET STRING OPTIONAL,
         *      suppPubInfo [2] OCTET STRING
         *  }
         * 
    */ public ASN1Primitive toASN1Primitive() { ASN1EncodableVector v = new ASN1EncodableVector(); v.add(keyInfo); if (partyAInfo != null) { v.add(new DERTaggedObject(0, partyAInfo)); } v.add(new DERTaggedObject(2, suppPubInfo)); return new DERSequence(v); } } bouncycastle-1.49.orig/src/org/bouncycastle/asn1/x9/X9ECParameters.java0000644000175000017500000001042411724561172025312 0ustar ebourgebourgpackage org.bouncycastle.asn1.x9; import java.math.BigInteger; import org.bouncycastle.asn1.ASN1EncodableVector; import org.bouncycastle.asn1.ASN1Integer; import org.bouncycastle.asn1.ASN1Object; import org.bouncycastle.asn1.ASN1OctetString; import org.bouncycastle.asn1.ASN1Primitive; import org.bouncycastle.asn1.ASN1Sequence; import org.bouncycastle.asn1.DERSequence; import org.bouncycastle.math.ec.ECCurve; import org.bouncycastle.math.ec.ECPoint; /** * ASN.1 def for Elliptic-Curve ECParameters structure. See * X9.62, for further details. */ public class X9ECParameters extends ASN1Object implements X9ObjectIdentifiers { private static final BigInteger ONE = BigInteger.valueOf(1); private X9FieldID fieldID; private ECCurve curve; private ECPoint g; private BigInteger n; private BigInteger h; private byte[] seed; private X9ECParameters( ASN1Sequence seq) { if (!(seq.getObjectAt(0) instanceof ASN1Integer) || !((ASN1Integer)seq.getObjectAt(0)).getValue().equals(ONE)) { throw new IllegalArgumentException("bad version in X9ECParameters"); } X9Curve x9c = new X9Curve( new X9FieldID((ASN1Sequence)seq.getObjectAt(1)), (ASN1Sequence)seq.getObjectAt(2)); this.curve = x9c.getCurve(); this.g = new X9ECPoint(curve, (ASN1OctetString)seq.getObjectAt(3)).getPoint(); this.n = ((ASN1Integer)seq.getObjectAt(4)).getValue(); this.seed = x9c.getSeed(); if (seq.size() == 6) { this.h = ((ASN1Integer)seq.getObjectAt(5)).getValue(); } } public static X9ECParameters getInstance(Object obj) { if (obj instanceof X9ECParameters) { return (X9ECParameters)obj; } if (obj != null) { return new X9ECParameters(ASN1Sequence.getInstance(obj)); } return null; } public X9ECParameters( ECCurve curve, ECPoint g, BigInteger n) { this(curve, g, n, ONE, null); } public X9ECParameters( ECCurve curve, ECPoint g, BigInteger n, BigInteger h) { this(curve, g, n, h, null); } public X9ECParameters( ECCurve curve, ECPoint g, BigInteger n, BigInteger h, byte[] seed) { this.curve = curve; this.g = g; this.n = n; this.h = h; this.seed = seed; if (curve instanceof ECCurve.Fp) { this.fieldID = new X9FieldID(((ECCurve.Fp)curve).getQ()); } else { if (curve instanceof ECCurve.F2m) { ECCurve.F2m curveF2m = (ECCurve.F2m)curve; this.fieldID = new X9FieldID(curveF2m.getM(), curveF2m.getK1(), curveF2m.getK2(), curveF2m.getK3()); } } } public ECCurve getCurve() { return curve; } public ECPoint getG() { return g; } public BigInteger getN() { return n; } public BigInteger getH() { if (h == null) { return ONE; // TODO - this should be calculated, it will cause issues with custom curves. } return h; } public byte[] getSeed() { return seed; } /** * Produce an object suitable for an ASN1OutputStream. *
         *  ECParameters ::= SEQUENCE {
         *      version         INTEGER { ecpVer1(1) } (ecpVer1),
         *      fieldID         FieldID {{FieldTypes}},
         *      curve           X9Curve,
         *      base            X9ECPoint,
         *      order           INTEGER,
         *      cofactor        INTEGER OPTIONAL
         *  }
         * 
    */ public ASN1Primitive toASN1Primitive() { ASN1EncodableVector v = new ASN1EncodableVector(); v.add(new ASN1Integer(1)); v.add(fieldID); v.add(new X9Curve(curve, seed)); v.add(new X9ECPoint(g)); v.add(new ASN1Integer(n)); if (h != null) { v.add(new ASN1Integer(h)); } return new DERSequence(v); } } bouncycastle-1.49.orig/src/org/bouncycastle/asn1/x9/X9ObjectIdentifiers.java0000644000175000017500000001372612132366606026402 0ustar ebourgebourgpackage org.bouncycastle.asn1.x9; import org.bouncycastle.asn1.ASN1ObjectIdentifier; public interface X9ObjectIdentifiers { // // X9.62 // // ansi-X9-62 OBJECT IDENTIFIER ::= { iso(1) member-body(2) // us(840) ansi-x962(10045) } // static final ASN1ObjectIdentifier ansi_X9_62 = new ASN1ObjectIdentifier("1.2.840.10045"); static final ASN1ObjectIdentifier id_fieldType = ansi_X9_62.branch("1"); static final ASN1ObjectIdentifier prime_field = id_fieldType.branch("1"); static final ASN1ObjectIdentifier characteristic_two_field = id_fieldType.branch("2"); static final ASN1ObjectIdentifier gnBasis = characteristic_two_field.branch("3.1"); static final ASN1ObjectIdentifier tpBasis = characteristic_two_field.branch("3.2"); static final ASN1ObjectIdentifier ppBasis = characteristic_two_field.branch("3.3"); static final ASN1ObjectIdentifier id_ecSigType = ansi_X9_62.branch("4"); static final ASN1ObjectIdentifier ecdsa_with_SHA1 = new ASN1ObjectIdentifier(id_ecSigType + ".1"); static final ASN1ObjectIdentifier id_publicKeyType = ansi_X9_62.branch("2"); static final ASN1ObjectIdentifier id_ecPublicKey = id_publicKeyType.branch("1"); static final ASN1ObjectIdentifier ecdsa_with_SHA2 = id_ecSigType.branch("3"); static final ASN1ObjectIdentifier ecdsa_with_SHA224 = ecdsa_with_SHA2.branch("1"); static final ASN1ObjectIdentifier ecdsa_with_SHA256 = ecdsa_with_SHA2.branch("2"); static final ASN1ObjectIdentifier ecdsa_with_SHA384 = ecdsa_with_SHA2.branch("3"); static final ASN1ObjectIdentifier ecdsa_with_SHA512 = ecdsa_with_SHA2.branch("4"); // // named curves // static final ASN1ObjectIdentifier ellipticCurve = ansi_X9_62.branch("3"); // // Two Curves // static final ASN1ObjectIdentifier cTwoCurve = ellipticCurve.branch("0"); static final ASN1ObjectIdentifier c2pnb163v1 = cTwoCurve.branch("1"); static final ASN1ObjectIdentifier c2pnb163v2 = cTwoCurve.branch("2"); static final ASN1ObjectIdentifier c2pnb163v3 = cTwoCurve.branch("3"); static final ASN1ObjectIdentifier c2pnb176w1 = cTwoCurve.branch("4"); static final ASN1ObjectIdentifier c2tnb191v1 = cTwoCurve.branch("5"); static final ASN1ObjectIdentifier c2tnb191v2 = cTwoCurve.branch("6"); static final ASN1ObjectIdentifier c2tnb191v3 = cTwoCurve.branch("7"); static final ASN1ObjectIdentifier c2onb191v4 = cTwoCurve.branch("8"); static final ASN1ObjectIdentifier c2onb191v5 = cTwoCurve.branch("9"); static final ASN1ObjectIdentifier c2pnb208w1 = cTwoCurve.branch("10"); static final ASN1ObjectIdentifier c2tnb239v1 = cTwoCurve.branch("11"); static final ASN1ObjectIdentifier c2tnb239v2 = cTwoCurve.branch("12"); static final ASN1ObjectIdentifier c2tnb239v3 = cTwoCurve.branch("13"); static final ASN1ObjectIdentifier c2onb239v4 = cTwoCurve.branch("14"); static final ASN1ObjectIdentifier c2onb239v5 = cTwoCurve.branch("15"); static final ASN1ObjectIdentifier c2pnb272w1 = cTwoCurve.branch("16"); static final ASN1ObjectIdentifier c2pnb304w1 = cTwoCurve.branch("17"); static final ASN1ObjectIdentifier c2tnb359v1 = cTwoCurve.branch("18"); static final ASN1ObjectIdentifier c2pnb368w1 = cTwoCurve.branch("19"); static final ASN1ObjectIdentifier c2tnb431r1 = cTwoCurve.branch("20"); // // Prime // static final ASN1ObjectIdentifier primeCurve = ellipticCurve.branch("1"); static final ASN1ObjectIdentifier prime192v1 = primeCurve.branch("1"); static final ASN1ObjectIdentifier prime192v2 = primeCurve.branch("2"); static final ASN1ObjectIdentifier prime192v3 = primeCurve.branch("3"); static final ASN1ObjectIdentifier prime239v1 = primeCurve.branch("4"); static final ASN1ObjectIdentifier prime239v2 = primeCurve.branch("5"); static final ASN1ObjectIdentifier prime239v3 = primeCurve.branch("6"); static final ASN1ObjectIdentifier prime256v1 = primeCurve.branch("7"); // // DSA // // dsapublicnumber OBJECT IDENTIFIER ::= { iso(1) member-body(2) // us(840) ansi-x957(10040) number-type(4) 1 } static final ASN1ObjectIdentifier id_dsa = new ASN1ObjectIdentifier("1.2.840.10040.4.1"); /** * id-dsa-with-sha1 OBJECT IDENTIFIER ::= { iso(1) member-body(2) us(840) x9-57 * (10040) x9cm(4) 3 } */ public static final ASN1ObjectIdentifier id_dsa_with_sha1 = new ASN1ObjectIdentifier("1.2.840.10040.4.3"); /** * X9.63 */ public static final ASN1ObjectIdentifier x9_63_scheme = new ASN1ObjectIdentifier("1.3.133.16.840.63.0"); public static final ASN1ObjectIdentifier dhSinglePass_stdDH_sha1kdf_scheme = x9_63_scheme.branch("2"); public static final ASN1ObjectIdentifier dhSinglePass_cofactorDH_sha1kdf_scheme = x9_63_scheme.branch("3"); public static final ASN1ObjectIdentifier mqvSinglePass_sha1kdf_scheme = x9_63_scheme.branch("16"); /** * X9.42 */ static final ASN1ObjectIdentifier ansi_X9_42 = new ASN1ObjectIdentifier("1.2.840.10046"); // // Diffie-Hellman // // dhpublicnumber OBJECT IDENTIFIER ::= { iso(1) member-body(2) // us(840) ansi-x942(10046) number-type(2) 1 } // public static final ASN1ObjectIdentifier dhpublicnumber = ansi_X9_42.branch("2.1"); public static final ASN1ObjectIdentifier x9_42_schemes = ansi_X9_42.branch("3"); public static final ASN1ObjectIdentifier dhStatic = x9_42_schemes.branch("1"); public static final ASN1ObjectIdentifier dhEphem = x9_42_schemes.branch("2"); public static final ASN1ObjectIdentifier dhOneFlow = x9_42_schemes.branch("3"); public static final ASN1ObjectIdentifier dhHybrid1 = x9_42_schemes.branch("4"); public static final ASN1ObjectIdentifier dhHybrid2 = x9_42_schemes.branch("5"); public static final ASN1ObjectIdentifier dhHybridOneFlow = x9_42_schemes.branch("6"); public static final ASN1ObjectIdentifier mqv2 = x9_42_schemes.branch("7"); public static final ASN1ObjectIdentifier mqv1 = x9_42_schemes.branch("8"); } bouncycastle-1.49.orig/src/org/bouncycastle/asn1/x9/DHPublicKey.java0000644000175000017500000000222511724561172024661 0ustar ebourgebourgpackage org.bouncycastle.asn1.x9; import org.bouncycastle.asn1.ASN1Integer; import org.bouncycastle.asn1.ASN1Object; import org.bouncycastle.asn1.ASN1Primitive; import org.bouncycastle.asn1.ASN1TaggedObject; public class DHPublicKey extends ASN1Object { private ASN1Integer y; public static DHPublicKey getInstance(ASN1TaggedObject obj, boolean explicit) { return getInstance(ASN1Integer.getInstance(obj, explicit)); } public static DHPublicKey getInstance(Object obj) { if (obj == null || obj instanceof DHPublicKey) { return (DHPublicKey)obj; } if (obj instanceof ASN1Integer) { return new DHPublicKey((ASN1Integer)obj); } throw new IllegalArgumentException("Invalid DHPublicKey: " + obj.getClass().getName()); } public DHPublicKey(ASN1Integer y) { if (y == null) { throw new IllegalArgumentException("'y' cannot be null"); } this.y = y; } public ASN1Integer getY() { return this.y; } public ASN1Primitive toASN1Primitive() { return this.y; } } bouncycastle-1.49.orig/src/org/bouncycastle/asn1/x9/ECNamedCurveTable.java0000644000175000017500000000463112147601314025763 0ustar ebourgebourgpackage org.bouncycastle.asn1.x9; import java.util.Enumeration; import java.util.Vector; import org.bouncycastle.asn1.ASN1ObjectIdentifier; import org.bouncycastle.asn1.nist.NISTNamedCurves; import org.bouncycastle.asn1.sec.SECNamedCurves; import org.bouncycastle.asn1.teletrust.TeleTrusTNamedCurves; /** * A general class that reads all X9.62 style EC curve tables. */ public class ECNamedCurveTable { /** * return a X9ECParameters object representing the passed in named * curve. The routine returns null if the curve is not present. * * @param name the name of the curve requested * @return an X9ECParameters object or null if the curve is not available. */ public static X9ECParameters getByName( String name) { X9ECParameters ecP = X962NamedCurves.getByName(name); if (ecP == null) { ecP = SECNamedCurves.getByName(name); } if (ecP == null) { ecP = TeleTrusTNamedCurves.getByName(name); } if (ecP == null) { ecP = NISTNamedCurves.getByName(name); } return ecP; } /** * return a X9ECParameters object representing the passed in named * curve. * * @param oid the object id of the curve requested * @return an X9ECParameters object or null if the curve is not available. */ public static X9ECParameters getByOID( ASN1ObjectIdentifier oid) { X9ECParameters ecP = X962NamedCurves.getByOID(oid); if (ecP == null) { ecP = SECNamedCurves.getByOID(oid); } if (ecP == null) { ecP = TeleTrusTNamedCurves.getByOID(oid); } return ecP; } /** * return an enumeration of the names of the available curves. * * @return an enumeration of the names of the available curves. */ public static Enumeration getNames() { Vector v = new Vector(); addEnumeration(v, X962NamedCurves.getNames()); addEnumeration(v, SECNamedCurves.getNames()); addEnumeration(v, NISTNamedCurves.getNames()); addEnumeration(v, TeleTrusTNamedCurves.getNames()); return v.elements(); } private static void addEnumeration( Vector v, Enumeration e) { while (e.hasMoreElements()) { v.addElement(e.nextElement()); } } } bouncycastle-1.49.orig/src/org/bouncycastle/asn1/x9/X9ECParametersHolder.java0000644000175000017500000000053011624622715026445 0ustar ebourgebourgpackage org.bouncycastle.asn1.x9; public abstract class X9ECParametersHolder { private X9ECParameters params; public X9ECParameters getParameters() { if (params == null) { params = createParameters(); } return params; } protected abstract X9ECParameters createParameters(); } bouncycastle-1.49.orig/src/org/bouncycastle/asn1/x9/X9IntegerConverter.java0000644000175000017500000000203211624652555026265 0ustar ebourgebourgpackage org.bouncycastle.asn1.x9; import java.math.BigInteger; import org.bouncycastle.math.ec.ECCurve; import org.bouncycastle.math.ec.ECFieldElement; public class X9IntegerConverter { public int getByteLength( ECCurve c) { return (c.getFieldSize() + 7) / 8; } public int getByteLength( ECFieldElement fe) { return (fe.getFieldSize() + 7) / 8; } public byte[] integerToBytes( BigInteger s, int qLength) { byte[] bytes = s.toByteArray(); if (qLength < bytes.length) { byte[] tmp = new byte[qLength]; System.arraycopy(bytes, bytes.length - tmp.length, tmp, 0, tmp.length); return tmp; } else if (qLength > bytes.length) { byte[] tmp = new byte[qLength]; System.arraycopy(bytes, 0, tmp, tmp.length - bytes.length, bytes.length); return tmp; } return bytes; } } bouncycastle-1.49.orig/src/org/bouncycastle/asn1/x9/X9Curve.java0000644000175000017500000001214712132366631024064 0ustar ebourgebourgpackage org.bouncycastle.asn1.x9; import java.math.BigInteger; import org.bouncycastle.asn1.ASN1EncodableVector; import org.bouncycastle.asn1.ASN1Integer; import org.bouncycastle.asn1.ASN1Object; import org.bouncycastle.asn1.ASN1ObjectIdentifier; import org.bouncycastle.asn1.ASN1OctetString; import org.bouncycastle.asn1.ASN1Primitive; import org.bouncycastle.asn1.ASN1Sequence; import org.bouncycastle.asn1.DERBitString; import org.bouncycastle.asn1.DERSequence; import org.bouncycastle.math.ec.ECCurve; /** * ASN.1 def for Elliptic-Curve Curve structure. See * X9.62, for further details. */ public class X9Curve extends ASN1Object implements X9ObjectIdentifiers { private ECCurve curve; private byte[] seed; private ASN1ObjectIdentifier fieldIdentifier = null; public X9Curve( ECCurve curve) { this.curve = curve; this.seed = null; setFieldIdentifier(); } public X9Curve( ECCurve curve, byte[] seed) { this.curve = curve; this.seed = seed; setFieldIdentifier(); } public X9Curve( X9FieldID fieldID, ASN1Sequence seq) { fieldIdentifier = fieldID.getIdentifier(); if (fieldIdentifier.equals(prime_field)) { BigInteger p = ((ASN1Integer)fieldID.getParameters()).getValue(); X9FieldElement x9A = new X9FieldElement(p, (ASN1OctetString)seq.getObjectAt(0)); X9FieldElement x9B = new X9FieldElement(p, (ASN1OctetString)seq.getObjectAt(1)); curve = new ECCurve.Fp(p, x9A.getValue().toBigInteger(), x9B.getValue().toBigInteger()); } else if (fieldIdentifier.equals(characteristic_two_field)) { // Characteristic two field ASN1Sequence parameters = ASN1Sequence.getInstance(fieldID.getParameters()); int m = ((ASN1Integer)parameters.getObjectAt(0)).getValue(). intValue(); ASN1ObjectIdentifier representation = (ASN1ObjectIdentifier)parameters.getObjectAt(1); int k1 = 0; int k2 = 0; int k3 = 0; if (representation.equals(tpBasis)) { // Trinomial basis representation k1 = ASN1Integer.getInstance(parameters.getObjectAt(2)).getValue().intValue(); } else if (representation.equals(ppBasis)) { // Pentanomial basis representation ASN1Sequence pentanomial = ASN1Sequence.getInstance(parameters.getObjectAt(2)); k1 = ASN1Integer.getInstance(pentanomial.getObjectAt(0)).getValue().intValue(); k2 = ASN1Integer.getInstance(pentanomial.getObjectAt(1)).getValue().intValue(); k3 = ASN1Integer.getInstance(pentanomial.getObjectAt(2)).getValue().intValue(); } else { throw new IllegalArgumentException("This type of EC basis is not implemented"); } X9FieldElement x9A = new X9FieldElement(m, k1, k2, k3, (ASN1OctetString)seq.getObjectAt(0)); X9FieldElement x9B = new X9FieldElement(m, k1, k2, k3, (ASN1OctetString)seq.getObjectAt(1)); // TODO Is it possible to get the order (n) and cofactor(h) too? curve = new ECCurve.F2m(m, k1, k2, k3, x9A.getValue().toBigInteger(), x9B.getValue().toBigInteger()); } else { throw new IllegalArgumentException("This type of ECCurve is not implemented"); } if (seq.size() == 3) { seed = ((DERBitString)seq.getObjectAt(2)).getBytes(); } } private void setFieldIdentifier() { if (curve instanceof ECCurve.Fp) { fieldIdentifier = prime_field; } else if (curve instanceof ECCurve.F2m) { fieldIdentifier = characteristic_two_field; } else { throw new IllegalArgumentException("This type of ECCurve is not implemented"); } } public ECCurve getCurve() { return curve; } public byte[] getSeed() { return seed; } /** * Produce an object suitable for an ASN1OutputStream. *
         *  Curve ::= SEQUENCE {
         *      a               FieldElement,
         *      b               FieldElement,
         *      seed            BIT STRING      OPTIONAL
         *  }
         * 
    */ public ASN1Primitive toASN1Primitive() { ASN1EncodableVector v = new ASN1EncodableVector(); if (fieldIdentifier.equals(prime_field)) { v.add(new X9FieldElement(curve.getA()).toASN1Primitive()); v.add(new X9FieldElement(curve.getB()).toASN1Primitive()); } else if (fieldIdentifier.equals(characteristic_two_field)) { v.add(new X9FieldElement(curve.getA()).toASN1Primitive()); v.add(new X9FieldElement(curve.getB()).toASN1Primitive()); } if (seed != null) { v.add(new DERBitString(seed)); } return new DERSequence(v); } } bouncycastle-1.49.orig/src/org/bouncycastle/asn1/x9/X962Parameters.java0000644000175000017500000000376311624652555025267 0ustar ebourgebourgpackage org.bouncycastle.asn1.x9; import org.bouncycastle.asn1.ASN1Choice; import org.bouncycastle.asn1.ASN1Null; import org.bouncycastle.asn1.ASN1Object; import org.bouncycastle.asn1.ASN1ObjectIdentifier; import org.bouncycastle.asn1.ASN1Primitive; import org.bouncycastle.asn1.ASN1TaggedObject; public class X962Parameters extends ASN1Object implements ASN1Choice { private ASN1Primitive params = null; public static X962Parameters getInstance( Object obj) { if (obj == null || obj instanceof X962Parameters) { return (X962Parameters)obj; } if (obj instanceof ASN1Primitive) { return new X962Parameters((ASN1Primitive)obj); } throw new IllegalArgumentException("unknown object in getInstance()"); } public static X962Parameters getInstance( ASN1TaggedObject obj, boolean explicit) { return getInstance(obj.getObject()); // must be explicitly tagged } public X962Parameters( X9ECParameters ecParameters) { this.params = ecParameters.toASN1Primitive(); } public X962Parameters( ASN1ObjectIdentifier namedCurve) { this.params = namedCurve; } public X962Parameters( ASN1Primitive obj) { this.params = obj; } public boolean isNamedCurve() { return (params instanceof ASN1ObjectIdentifier); } public boolean isImplicitlyCA() { return (params instanceof ASN1Null); } public ASN1Primitive getParameters() { return params; } /** * Produce an object suitable for an ASN1OutputStream. *
         * Parameters ::= CHOICE {
         *    ecParameters ECParameters,
         *    namedCurve   CURVES.&id({CurveNames}),
         *    implicitlyCA NULL
         * }
         * 
    */ public ASN1Primitive toASN1Primitive() { return (ASN1Primitive)params; } } bouncycastle-1.49.orig/src/org/bouncycastle/asn1/x9/X9ECPoint.java0000644000175000017500000000175211624622715024304 0ustar ebourgebourgpackage org.bouncycastle.asn1.x9; import org.bouncycastle.asn1.ASN1Object; import org.bouncycastle.asn1.ASN1OctetString; import org.bouncycastle.asn1.ASN1Primitive; import org.bouncycastle.asn1.DEROctetString; import org.bouncycastle.math.ec.ECCurve; import org.bouncycastle.math.ec.ECPoint; /** * class for describing an ECPoint as a DER object. */ public class X9ECPoint extends ASN1Object { ECPoint p; public X9ECPoint( ECPoint p) { this.p = p; } public X9ECPoint( ECCurve c, ASN1OctetString s) { this.p = c.decodePoint(s.getOctets()); } public ECPoint getPoint() { return p; } /** * Produce an object suitable for an ASN1OutputStream. *
         *  ECPoint ::= OCTET STRING
         * 
    *

    * Octet string produced using ECPoint.getEncoded(). */ public ASN1Primitive toASN1Primitive() { return new DEROctetString(p.getEncoded()); } } bouncycastle-1.49.orig/src/org/bouncycastle/asn1/x9/KeySpecificInfo.java0000644000175000017500000000320211624652555025571 0ustar ebourgebourgpackage org.bouncycastle.asn1.x9; import java.util.Enumeration; import org.bouncycastle.asn1.ASN1EncodableVector; import org.bouncycastle.asn1.ASN1Object; import org.bouncycastle.asn1.ASN1ObjectIdentifier; import org.bouncycastle.asn1.ASN1OctetString; import org.bouncycastle.asn1.ASN1Primitive; import org.bouncycastle.asn1.ASN1Sequence; import org.bouncycastle.asn1.DERSequence; /** * ASN.1 def for Diffie-Hellman key exchange KeySpecificInfo structure. See * RFC 2631, or X9.42, for further details. */ public class KeySpecificInfo extends ASN1Object { private ASN1ObjectIdentifier algorithm; private ASN1OctetString counter; public KeySpecificInfo( ASN1ObjectIdentifier algorithm, ASN1OctetString counter) { this.algorithm = algorithm; this.counter = counter; } public KeySpecificInfo( ASN1Sequence seq) { Enumeration e = seq.getObjects(); algorithm = (ASN1ObjectIdentifier)e.nextElement(); counter = (ASN1OctetString)e.nextElement(); } public ASN1ObjectIdentifier getAlgorithm() { return algorithm; } public ASN1OctetString getCounter() { return counter; } /** * Produce an object suitable for an ASN1OutputStream. *

         *  KeySpecificInfo ::= SEQUENCE {
         *      algorithm OBJECT IDENTIFIER,
         *      counter OCTET STRING SIZE (4..4)
         *  }
         * 
    */ public ASN1Primitive toASN1Primitive() { ASN1EncodableVector v = new ASN1EncodableVector(); v.add(algorithm); v.add(counter); return new DERSequence(v); } } bouncycastle-1.49.orig/src/org/bouncycastle/asn1/x9/X9FieldElement.java0000644000175000017500000000342511624625016025334 0ustar ebourgebourgpackage org.bouncycastle.asn1.x9; import java.math.BigInteger; import org.bouncycastle.asn1.ASN1Object; import org.bouncycastle.asn1.ASN1OctetString; import org.bouncycastle.asn1.ASN1Primitive; import org.bouncycastle.asn1.DEROctetString; import org.bouncycastle.math.ec.ECFieldElement; /** * class for processing an FieldElement as a DER object. */ public class X9FieldElement extends ASN1Object { protected ECFieldElement f; private static X9IntegerConverter converter = new X9IntegerConverter(); public X9FieldElement(ECFieldElement f) { this.f = f; } public X9FieldElement(BigInteger p, ASN1OctetString s) { this(new ECFieldElement.Fp(p, new BigInteger(1, s.getOctets()))); } public X9FieldElement(int m, int k1, int k2, int k3, ASN1OctetString s) { this(new ECFieldElement.F2m(m, k1, k2, k3, new BigInteger(1, s.getOctets()))); } public ECFieldElement getValue() { return f; } /** * Produce an object suitable for an ASN1OutputStream. *
         *  FieldElement ::= OCTET STRING
         * 
    *

    *

      *
    1. if q is an odd prime then the field element is * processed as an Integer and converted to an octet string * according to x 9.62 4.3.1.
    2. *
    3. if q is 2m then the bit string * contained in the field element is converted into an octet * string with the same ordering padded at the front if necessary. *
    4. *
    */ public ASN1Primitive toASN1Primitive() { int byteCount = converter.getByteLength(f); byte[] paddedBigInteger = converter.integerToBytes(f.toBigInteger(), byteCount); return new DEROctetString(paddedBigInteger); } } bouncycastle-1.49.orig/src/org/bouncycastle/asn1/x9/package.html0000644000175000017500000000017110262753175024174 0ustar ebourgebourg Support classes useful for encoding and supporting X9.62 elliptic curve. bouncycastle-1.49.orig/src/org/bouncycastle/asn1/x9/X962NamedCurves.java0000644000175000017500000006205711736442772025403 0ustar ebourgebourgpackage org.bouncycastle.asn1.x9; import java.math.BigInteger; import java.util.Enumeration; import java.util.Hashtable; import org.bouncycastle.asn1.ASN1ObjectIdentifier; import org.bouncycastle.math.ec.ECCurve; import org.bouncycastle.util.Strings; import org.bouncycastle.util.encoders.Hex; /** * table of the current named curves defined in X.962 EC-DSA. */ public class X962NamedCurves { static X9ECParametersHolder prime192v1 = new X9ECParametersHolder() { protected X9ECParameters createParameters() { ECCurve cFp192v1 = new ECCurve.Fp( new BigInteger("6277101735386680763835789423207666416083908700390324961279"), new BigInteger("fffffffffffffffffffffffffffffffefffffffffffffffc", 16), new BigInteger("64210519e59c80e70fa7e9ab72243049feb8deecc146b9b1", 16)); return new X9ECParameters( cFp192v1, cFp192v1.decodePoint( Hex.decode("03188da80eb03090f67cbf20eb43a18800f4ff0afd82ff1012")), new BigInteger("ffffffffffffffffffffffff99def836146bc9b1b4d22831", 16), BigInteger.valueOf(1), Hex.decode("3045AE6FC8422f64ED579528D38120EAE12196D5")); } }; static X9ECParametersHolder prime192v2 = new X9ECParametersHolder() { protected X9ECParameters createParameters() { ECCurve cFp192v2 = new ECCurve.Fp( new BigInteger("6277101735386680763835789423207666416083908700390324961279"), new BigInteger("fffffffffffffffffffffffffffffffefffffffffffffffc", 16), new BigInteger("cc22d6dfb95c6b25e49c0d6364a4e5980c393aa21668d953", 16)); return new X9ECParameters( cFp192v2, cFp192v2.decodePoint( Hex.decode("03eea2bae7e1497842f2de7769cfe9c989c072ad696f48034a")), new BigInteger("fffffffffffffffffffffffe5fb1a724dc80418648d8dd31", 16), BigInteger.valueOf(1), Hex.decode("31a92ee2029fd10d901b113e990710f0d21ac6b6")); } }; static X9ECParametersHolder prime192v3 = new X9ECParametersHolder() { protected X9ECParameters createParameters() { ECCurve cFp192v3 = new ECCurve.Fp( new BigInteger("6277101735386680763835789423207666416083908700390324961279"), new BigInteger("fffffffffffffffffffffffffffffffefffffffffffffffc", 16), new BigInteger("22123dc2395a05caa7423daeccc94760a7d462256bd56916", 16)); return new X9ECParameters( cFp192v3, cFp192v3.decodePoint( Hex.decode("027d29778100c65a1da1783716588dce2b8b4aee8e228f1896")), new BigInteger("ffffffffffffffffffffffff7a62d031c83f4294f640ec13", 16), BigInteger.valueOf(1), Hex.decode("c469684435deb378c4b65ca9591e2a5763059a2e")); } }; static X9ECParametersHolder prime239v1 = new X9ECParametersHolder() { protected X9ECParameters createParameters() { ECCurve cFp239v1 = new ECCurve.Fp( new BigInteger("883423532389192164791648750360308885314476597252960362792450860609699839"), new BigInteger("7fffffffffffffffffffffff7fffffffffff8000000000007ffffffffffc", 16), new BigInteger("6b016c3bdcf18941d0d654921475ca71a9db2fb27d1d37796185c2942c0a", 16)); return new X9ECParameters( cFp239v1, cFp239v1.decodePoint( Hex.decode("020ffa963cdca8816ccc33b8642bedf905c3d358573d3f27fbbd3b3cb9aaaf")), new BigInteger("7fffffffffffffffffffffff7fffff9e5e9a9f5d9071fbd1522688909d0b", 16), BigInteger.valueOf(1), Hex.decode("e43bb460f0b80cc0c0b075798e948060f8321b7d")); } }; static X9ECParametersHolder prime239v2 = new X9ECParametersHolder() { protected X9ECParameters createParameters() { ECCurve cFp239v2 = new ECCurve.Fp( new BigInteger("883423532389192164791648750360308885314476597252960362792450860609699839"), new BigInteger("7fffffffffffffffffffffff7fffffffffff8000000000007ffffffffffc", 16), new BigInteger("617fab6832576cbbfed50d99f0249c3fee58b94ba0038c7ae84c8c832f2c", 16)); return new X9ECParameters( cFp239v2, cFp239v2.decodePoint( Hex.decode("0238af09d98727705120c921bb5e9e26296a3cdcf2f35757a0eafd87b830e7")), new BigInteger("7fffffffffffffffffffffff800000cfa7e8594377d414c03821bc582063", 16), BigInteger.valueOf(1), Hex.decode("e8b4011604095303ca3b8099982be09fcb9ae616")); } }; static X9ECParametersHolder prime239v3 = new X9ECParametersHolder() { protected X9ECParameters createParameters() { ECCurve cFp239v3 = new ECCurve.Fp( new BigInteger("883423532389192164791648750360308885314476597252960362792450860609699839"), new BigInteger("7fffffffffffffffffffffff7fffffffffff8000000000007ffffffffffc", 16), new BigInteger("255705fa2a306654b1f4cb03d6a750a30c250102d4988717d9ba15ab6d3e", 16)); return new X9ECParameters( cFp239v3, cFp239v3.decodePoint( Hex.decode("036768ae8e18bb92cfcf005c949aa2c6d94853d0e660bbf854b1c9505fe95a")), new BigInteger("7fffffffffffffffffffffff7fffff975deb41b3a6057c3c432146526551", 16), BigInteger.valueOf(1), Hex.decode("7d7374168ffe3471b60a857686a19475d3bfa2ff")); } }; static X9ECParametersHolder prime256v1 = new X9ECParametersHolder() { protected X9ECParameters createParameters() { ECCurve cFp256v1 = new ECCurve.Fp( new BigInteger("115792089210356248762697446949407573530086143415290314195533631308867097853951"), new BigInteger("ffffffff00000001000000000000000000000000fffffffffffffffffffffffc", 16), new BigInteger("5ac635d8aa3a93e7b3ebbd55769886bc651d06b0cc53b0f63bce3c3e27d2604b", 16)); return new X9ECParameters( cFp256v1, cFp256v1.decodePoint( Hex.decode("036b17d1f2e12c4247f8bce6e563a440f277037d812deb33a0f4a13945d898c296")), new BigInteger("ffffffff00000000ffffffffffffffffbce6faada7179e84f3b9cac2fc632551", 16), BigInteger.valueOf(1), Hex.decode("c49d360886e704936a6678e1139d26b7819f7e90")); } }; /* * F2m Curves */ static X9ECParametersHolder c2pnb163v1 = new X9ECParametersHolder() { protected X9ECParameters createParameters() { BigInteger c2m163v1n = new BigInteger("0400000000000000000001E60FC8821CC74DAEAFC1", 16); BigInteger c2m163v1h = BigInteger.valueOf(2); ECCurve c2m163v1 = new ECCurve.F2m( 163, 1, 2, 8, new BigInteger("072546B5435234A422E0789675F432C89435DE5242", 16), new BigInteger("00C9517D06D5240D3CFF38C74B20B6CD4D6F9DD4D9", 16), c2m163v1n, c2m163v1h); return new X9ECParameters( c2m163v1, c2m163v1.decodePoint( Hex.decode("0307AF69989546103D79329FCC3D74880F33BBE803CB")), c2m163v1n, c2m163v1h, Hex.decode("D2C0FB15760860DEF1EEF4D696E6768756151754")); } }; static X9ECParametersHolder c2pnb163v2 = new X9ECParametersHolder() { protected X9ECParameters createParameters() { BigInteger c2m163v2n = new BigInteger("03FFFFFFFFFFFFFFFFFFFDF64DE1151ADBB78F10A7", 16); BigInteger c2m163v2h = BigInteger.valueOf(2); ECCurve c2m163v2 = new ECCurve.F2m( 163, 1, 2, 8, new BigInteger("0108B39E77C4B108BED981ED0E890E117C511CF072", 16), new BigInteger("0667ACEB38AF4E488C407433FFAE4F1C811638DF20", 16), c2m163v2n, c2m163v2h); return new X9ECParameters( c2m163v2, c2m163v2.decodePoint( Hex.decode("030024266E4EB5106D0A964D92C4860E2671DB9B6CC5")), c2m163v2n, c2m163v2h, null); } }; static X9ECParametersHolder c2pnb163v3 = new X9ECParametersHolder() { protected X9ECParameters createParameters() { BigInteger c2m163v3n = new BigInteger("03FFFFFFFFFFFFFFFFFFFE1AEE140F110AFF961309", 16); BigInteger c2m163v3h = BigInteger.valueOf(2); ECCurve c2m163v3 = new ECCurve.F2m( 163, 1, 2, 8, new BigInteger("07A526C63D3E25A256A007699F5447E32AE456B50E", 16), new BigInteger("03F7061798EB99E238FD6F1BF95B48FEEB4854252B", 16), c2m163v3n, c2m163v3h); return new X9ECParameters( c2m163v3, c2m163v3.decodePoint( Hex.decode("0202F9F87B7C574D0BDECF8A22E6524775F98CDEBDCB")), c2m163v3n, c2m163v3h, null); } }; static X9ECParametersHolder c2pnb176w1 = new X9ECParametersHolder() { protected X9ECParameters createParameters() { BigInteger c2m176w1n = new BigInteger("010092537397ECA4F6145799D62B0A19CE06FE26AD", 16); BigInteger c2m176w1h = BigInteger.valueOf(0xFF6E); ECCurve c2m176w1 = new ECCurve.F2m( 176, 1, 2, 43, new BigInteger("00E4E6DB2995065C407D9D39B8D0967B96704BA8E9C90B", 16), new BigInteger("005DDA470ABE6414DE8EC133AE28E9BBD7FCEC0AE0FFF2", 16), c2m176w1n, c2m176w1h); return new X9ECParameters( c2m176w1, c2m176w1.decodePoint( Hex.decode("038D16C2866798B600F9F08BB4A8E860F3298CE04A5798")), c2m176w1n, c2m176w1h, null); } }; static X9ECParametersHolder c2tnb191v1 = new X9ECParametersHolder() { protected X9ECParameters createParameters() { BigInteger c2m191v1n = new BigInteger("40000000000000000000000004A20E90C39067C893BBB9A5", 16); BigInteger c2m191v1h = BigInteger.valueOf(2); ECCurve c2m191v1 = new ECCurve.F2m( 191, 9, new BigInteger("2866537B676752636A68F56554E12640276B649EF7526267", 16), new BigInteger("2E45EF571F00786F67B0081B9495A3D95462F5DE0AA185EC", 16), c2m191v1n, c2m191v1h); return new X9ECParameters( c2m191v1, c2m191v1.decodePoint( Hex.decode("0236B3DAF8A23206F9C4F299D7B21A9C369137F2C84AE1AA0D")), c2m191v1n, c2m191v1h, Hex.decode("4E13CA542744D696E67687561517552F279A8C84")); } }; static X9ECParametersHolder c2tnb191v2 = new X9ECParametersHolder() { protected X9ECParameters createParameters() { BigInteger c2m191v2n = new BigInteger("20000000000000000000000050508CB89F652824E06B8173", 16); BigInteger c2m191v2h = BigInteger.valueOf(4); ECCurve c2m191v2 = new ECCurve.F2m( 191, 9, new BigInteger("401028774D7777C7B7666D1366EA432071274F89FF01E718", 16), new BigInteger("0620048D28BCBD03B6249C99182B7C8CD19700C362C46A01", 16), c2m191v2n, c2m191v2h); return new X9ECParameters( c2m191v2, c2m191v2.decodePoint( Hex.decode("023809B2B7CC1B28CC5A87926AAD83FD28789E81E2C9E3BF10")), c2m191v2n, c2m191v2h, null); } }; static X9ECParametersHolder c2tnb191v3 = new X9ECParametersHolder() { protected X9ECParameters createParameters() { BigInteger c2m191v3n = new BigInteger("155555555555555555555555610C0B196812BFB6288A3EA3", 16); BigInteger c2m191v3h = BigInteger.valueOf(6); ECCurve c2m191v3 = new ECCurve.F2m( 191, 9, new BigInteger("6C01074756099122221056911C77D77E77A777E7E7E77FCB", 16), new BigInteger("71FE1AF926CF847989EFEF8DB459F66394D90F32AD3F15E8", 16), c2m191v3n, c2m191v3h); return new X9ECParameters( c2m191v3, c2m191v3.decodePoint( Hex.decode("03375D4CE24FDE434489DE8746E71786015009E66E38A926DD")), c2m191v3n, c2m191v3h, null); } }; static X9ECParametersHolder c2pnb208w1 = new X9ECParametersHolder() { protected X9ECParameters createParameters() { BigInteger c2m208w1n = new BigInteger("0101BAF95C9723C57B6C21DA2EFF2D5ED588BDD5717E212F9D", 16); BigInteger c2m208w1h = BigInteger.valueOf(0xFE48); ECCurve c2m208w1 = new ECCurve.F2m( 208, 1, 2, 83, new BigInteger("0", 16), new BigInteger("00C8619ED45A62E6212E1160349E2BFA844439FAFC2A3FD1638F9E", 16), c2m208w1n, c2m208w1h); return new X9ECParameters( c2m208w1, c2m208w1.decodePoint( Hex.decode("0289FDFBE4ABE193DF9559ECF07AC0CE78554E2784EB8C1ED1A57A")), c2m208w1n, c2m208w1h, null); } }; static X9ECParametersHolder c2tnb239v1 = new X9ECParametersHolder() { protected X9ECParameters createParameters() { BigInteger c2m239v1n = new BigInteger("2000000000000000000000000000000F4D42FFE1492A4993F1CAD666E447", 16); BigInteger c2m239v1h = BigInteger.valueOf(4); ECCurve c2m239v1 = new ECCurve.F2m( 239, 36, new BigInteger("32010857077C5431123A46B808906756F543423E8D27877578125778AC76", 16), new BigInteger("790408F2EEDAF392B012EDEFB3392F30F4327C0CA3F31FC383C422AA8C16", 16), c2m239v1n, c2m239v1h); return new X9ECParameters( c2m239v1, c2m239v1.decodePoint( Hex.decode("0257927098FA932E7C0A96D3FD5B706EF7E5F5C156E16B7E7C86038552E91D")), c2m239v1n, c2m239v1h, null); } }; static X9ECParametersHolder c2tnb239v2 = new X9ECParametersHolder() { protected X9ECParameters createParameters() { BigInteger c2m239v2n = new BigInteger("1555555555555555555555555555553C6F2885259C31E3FCDF154624522D", 16); BigInteger c2m239v2h = BigInteger.valueOf(6); ECCurve c2m239v2 = new ECCurve.F2m( 239, 36, new BigInteger("4230017757A767FAE42398569B746325D45313AF0766266479B75654E65F", 16), new BigInteger("5037EA654196CFF0CD82B2C14A2FCF2E3FF8775285B545722F03EACDB74B", 16), c2m239v2n, c2m239v2h); return new X9ECParameters( c2m239v2, c2m239v2.decodePoint( Hex.decode("0228F9D04E900069C8DC47A08534FE76D2B900B7D7EF31F5709F200C4CA205")), c2m239v2n, c2m239v2h, null); } }; static X9ECParametersHolder c2tnb239v3 = new X9ECParametersHolder() { protected X9ECParameters createParameters() { BigInteger c2m239v3n = new BigInteger("0CCCCCCCCCCCCCCCCCCCCCCCCCCCCCAC4912D2D9DF903EF9888B8A0E4CFF", 16); BigInteger c2m239v3h = BigInteger.valueOf(10); ECCurve c2m239v3 = new ECCurve.F2m( 239, 36, new BigInteger("01238774666A67766D6676F778E676B66999176666E687666D8766C66A9F", 16), new BigInteger("6A941977BA9F6A435199ACFC51067ED587F519C5ECB541B8E44111DE1D40", 16), c2m239v3n, c2m239v3h); return new X9ECParameters( c2m239v3, c2m239v3.decodePoint( Hex.decode("0370F6E9D04D289C4E89913CE3530BFDE903977D42B146D539BF1BDE4E9C92")), c2m239v3n, c2m239v3h, null); } }; static X9ECParametersHolder c2pnb272w1 = new X9ECParametersHolder() { protected X9ECParameters createParameters() { BigInteger c2m272w1n = new BigInteger("0100FAF51354E0E39E4892DF6E319C72C8161603FA45AA7B998A167B8F1E629521", 16); BigInteger c2m272w1h = BigInteger.valueOf(0xFF06); ECCurve c2m272w1 = new ECCurve.F2m( 272, 1, 3, 56, new BigInteger("0091A091F03B5FBA4AB2CCF49C4EDD220FB028712D42BE752B2C40094DBACDB586FB20", 16), new BigInteger("7167EFC92BB2E3CE7C8AAAFF34E12A9C557003D7C73A6FAF003F99F6CC8482E540F7", 16), c2m272w1n, c2m272w1h); return new X9ECParameters( c2m272w1, c2m272w1.decodePoint( Hex.decode("026108BABB2CEEBCF787058A056CBE0CFE622D7723A289E08A07AE13EF0D10D171DD8D")), c2m272w1n, c2m272w1h, null); } }; static X9ECParametersHolder c2pnb304w1 = new X9ECParametersHolder() { protected X9ECParameters createParameters() { BigInteger c2m304w1n = new BigInteger("0101D556572AABAC800101D556572AABAC8001022D5C91DD173F8FB561DA6899164443051D", 16); BigInteger c2m304w1h = BigInteger.valueOf(0xFE2E); ECCurve c2m304w1 = new ECCurve.F2m( 304, 1, 2, 11, new BigInteger("00FD0D693149A118F651E6DCE6802085377E5F882D1B510B44160074C1288078365A0396C8E681", 16), new BigInteger("00BDDB97E555A50A908E43B01C798EA5DAA6788F1EA2794EFCF57166B8C14039601E55827340BE", 16), c2m304w1n, c2m304w1h); return new X9ECParameters( c2m304w1, c2m304w1.decodePoint( Hex.decode("02197B07845E9BE2D96ADB0F5F3C7F2CFFBD7A3EB8B6FEC35C7FD67F26DDF6285A644F740A2614")), c2m304w1n, c2m304w1h, null); } }; static X9ECParametersHolder c2tnb359v1 = new X9ECParametersHolder() { protected X9ECParameters createParameters() { BigInteger c2m359v1n = new BigInteger("01AF286BCA1AF286BCA1AF286BCA1AF286BCA1AF286BC9FB8F6B85C556892C20A7EB964FE7719E74F490758D3B", 16); BigInteger c2m359v1h = BigInteger.valueOf(0x4C); ECCurve c2m359v1 = new ECCurve.F2m( 359, 68, new BigInteger("5667676A654B20754F356EA92017D946567C46675556F19556A04616B567D223A5E05656FB549016A96656A557", 16), new BigInteger("2472E2D0197C49363F1FE7F5B6DB075D52B6947D135D8CA445805D39BC345626089687742B6329E70680231988", 16), c2m359v1n, c2m359v1h); return new X9ECParameters( c2m359v1, c2m359v1.decodePoint( Hex.decode("033C258EF3047767E7EDE0F1FDAA79DAEE3841366A132E163ACED4ED2401DF9C6BDCDE98E8E707C07A2239B1B097")), c2m359v1n, c2m359v1h, null); } }; static X9ECParametersHolder c2pnb368w1 = new X9ECParametersHolder() { protected X9ECParameters createParameters() { BigInteger c2m368w1n = new BigInteger("010090512DA9AF72B08349D98A5DD4C7B0532ECA51CE03E2D10F3B7AC579BD87E909AE40A6F131E9CFCE5BD967", 16); BigInteger c2m368w1h = BigInteger.valueOf(0xFF70); ECCurve c2m368w1 = new ECCurve.F2m( 368, 1, 2, 85, new BigInteger("00E0D2EE25095206F5E2A4F9ED229F1F256E79A0E2B455970D8D0D865BD94778C576D62F0AB7519CCD2A1A906AE30D", 16), new BigInteger("00FC1217D4320A90452C760A58EDCD30C8DD069B3C34453837A34ED50CB54917E1C2112D84D164F444F8F74786046A", 16), c2m368w1n, c2m368w1h); return new X9ECParameters( c2m368w1, c2m368w1.decodePoint( Hex.decode("021085E2755381DCCCE3C1557AFA10C2F0C0C2825646C5B34A394CBCFA8BC16B22E7E789E927BE216F02E1FB136A5F")), c2m368w1n, c2m368w1h, null); } }; static X9ECParametersHolder c2tnb431r1 = new X9ECParametersHolder() { protected X9ECParameters createParameters() { BigInteger c2m431r1n = new BigInteger("0340340340340340340340340340340340340340340340340340340323C313FAB50589703B5EC68D3587FEC60D161CC149C1AD4A91", 16); BigInteger c2m431r1h = BigInteger.valueOf(0x2760); ECCurve c2m431r1 = new ECCurve.F2m( 431, 120, new BigInteger("1A827EF00DD6FC0E234CAF046C6A5D8A85395B236CC4AD2CF32A0CADBDC9DDF620B0EB9906D0957F6C6FEACD615468DF104DE296CD8F", 16), new BigInteger("10D9B4A3D9047D8B154359ABFB1B7F5485B04CEB868237DDC9DEDA982A679A5A919B626D4E50A8DD731B107A9962381FB5D807BF2618", 16), c2m431r1n, c2m431r1h); return new X9ECParameters( c2m431r1, c2m431r1.decodePoint( Hex.decode("02120FC05D3C67A99DE161D2F4092622FECA701BE4F50F4758714E8A87BBF2A658EF8C21E7C5EFE965361F6C2999C0C247B0DBD70CE6B7")), c2m431r1n, c2m431r1h, null); } }; static final Hashtable objIds = new Hashtable(); static final Hashtable curves = new Hashtable(); static final Hashtable names = new Hashtable(); static void defineCurve(String name, ASN1ObjectIdentifier oid, X9ECParametersHolder holder) { objIds.put(name, oid); names.put(oid, name); curves.put(oid, holder); } static { defineCurve("prime192v1", X9ObjectIdentifiers.prime192v1, prime192v1); defineCurve("prime192v2", X9ObjectIdentifiers.prime192v2, prime192v2); defineCurve("prime192v3", X9ObjectIdentifiers.prime192v3, prime192v3); defineCurve("prime239v1", X9ObjectIdentifiers.prime239v1, prime239v1); defineCurve("prime239v2", X9ObjectIdentifiers.prime239v2, prime239v2); defineCurve("prime239v3", X9ObjectIdentifiers.prime239v3, prime239v3); defineCurve("prime256v1", X9ObjectIdentifiers.prime256v1, prime256v1); defineCurve("c2pnb163v1", X9ObjectIdentifiers.c2pnb163v1, c2pnb163v1); defineCurve("c2pnb163v2", X9ObjectIdentifiers.c2pnb163v2, c2pnb163v2); defineCurve("c2pnb163v3", X9ObjectIdentifiers.c2pnb163v3, c2pnb163v3); defineCurve("c2pnb176w1", X9ObjectIdentifiers.c2pnb176w1, c2pnb176w1); defineCurve("c2tnb191v1", X9ObjectIdentifiers.c2tnb191v1, c2tnb191v1); defineCurve("c2tnb191v2", X9ObjectIdentifiers.c2tnb191v2, c2tnb191v2); defineCurve("c2tnb191v3", X9ObjectIdentifiers.c2tnb191v3, c2tnb191v3); defineCurve("c2pnb208w1", X9ObjectIdentifiers.c2pnb208w1, c2pnb208w1); defineCurve("c2tnb239v1", X9ObjectIdentifiers.c2tnb239v1, c2tnb239v1); defineCurve("c2tnb239v2", X9ObjectIdentifiers.c2tnb239v2, c2tnb239v2); defineCurve("c2tnb239v3", X9ObjectIdentifiers.c2tnb239v3, c2tnb239v3); defineCurve("c2pnb272w1", X9ObjectIdentifiers.c2pnb272w1, c2pnb272w1); defineCurve("c2pnb304w1", X9ObjectIdentifiers.c2pnb304w1, c2pnb304w1); defineCurve("c2tnb359v1", X9ObjectIdentifiers.c2tnb359v1, c2tnb359v1); defineCurve("c2pnb368w1", X9ObjectIdentifiers.c2pnb368w1, c2pnb368w1); defineCurve("c2tnb431r1", X9ObjectIdentifiers.c2tnb431r1, c2tnb431r1); } public static X9ECParameters getByName( String name) { ASN1ObjectIdentifier oid = (ASN1ObjectIdentifier)objIds.get(Strings.toLowerCase(name)); if (oid != null) { return getByOID(oid); } return null; } /** * return the X9ECParameters object for the named curve represented by * the passed in object identifier. Null if the curve isn't present. * * @param oid an object identifier representing a named curve, if present. */ public static X9ECParameters getByOID( ASN1ObjectIdentifier oid) { X9ECParametersHolder holder = (X9ECParametersHolder)curves.get(oid); if (holder != null) { return holder.getParameters(); } return null; } /** * return the object identifier signified by the passed in name. Null * if there is no object identifier associated with name. * * @return the object identifier associated with name, if present. */ public static ASN1ObjectIdentifier getOID( String name) { return (ASN1ObjectIdentifier)objIds.get(Strings.toLowerCase(name)); } /** * return the named curve name represented by the given object identifier. */ public static String getName( ASN1ObjectIdentifier oid) { return (String)names.get(oid); } /** * returns an enumeration containing the name strings for curves * contained in this structure. */ public static Enumeration getNames() { return objIds.keys(); } } bouncycastle-1.49.orig/src/org/bouncycastle/asn1/ASN1SetParser.java0000644000175000017500000000032311624616767024560 0ustar ebourgebourgpackage org.bouncycastle.asn1; import java.io.IOException; public interface ASN1SetParser extends ASN1Encodable, InMemoryRepresentable { public ASN1Encodable readObject() throws IOException; } bouncycastle-1.49.orig/src/org/bouncycastle/asn1/BERTaggedObjectParser.java0000644000175000017500000000265111624650405026246 0ustar ebourgebourgpackage org.bouncycastle.asn1; import java.io.IOException; public class BERTaggedObjectParser implements ASN1TaggedObjectParser { private boolean _constructed; private int _tagNumber; private ASN1StreamParser _parser; BERTaggedObjectParser( boolean constructed, int tagNumber, ASN1StreamParser parser) { _constructed = constructed; _tagNumber = tagNumber; _parser = parser; } public boolean isConstructed() { return _constructed; } public int getTagNo() { return _tagNumber; } public ASN1Encodable getObjectParser( int tag, boolean isExplicit) throws IOException { if (isExplicit) { if (!_constructed) { throw new IOException("Explicit tags must be constructed (see X.690 8.14.2)"); } return _parser.readObject(); } return _parser.readImplicit(_constructed, tag); } public ASN1Primitive getLoadedObject() throws IOException { return _parser.readTaggedObject(_constructed, _tagNumber); } public ASN1Primitive toASN1Primitive() { try { return this.getLoadedObject(); } catch (IOException e) { throw new ASN1ParsingException(e.getMessage()); } } } bouncycastle-1.49.orig/src/org/bouncycastle/asn1/dvcs/0000755000175000017500000000000012152033551022300 5ustar ebourgebourgbouncycastle-1.49.orig/src/org/bouncycastle/asn1/dvcs/DVCSCertInfo.java0000644000175000017500000001734312151250553025346 0ustar ebourgebourgpackage org.bouncycastle.asn1.dvcs; import org.bouncycastle.asn1.ASN1Encodable; import org.bouncycastle.asn1.ASN1EncodableVector; import org.bouncycastle.asn1.ASN1Integer; import org.bouncycastle.asn1.ASN1Object; import org.bouncycastle.asn1.ASN1Primitive; import org.bouncycastle.asn1.ASN1Sequence; import org.bouncycastle.asn1.ASN1Set; import org.bouncycastle.asn1.ASN1TaggedObject; import org.bouncycastle.asn1.DERSequence; import org.bouncycastle.asn1.DERTaggedObject; import org.bouncycastle.asn1.cmp.PKIStatusInfo; import org.bouncycastle.asn1.x509.DigestInfo; import org.bouncycastle.asn1.x509.Extensions; import org.bouncycastle.asn1.x509.PolicyInformation; /** *
     *     DVCSCertInfo::= SEQUENCE  {
     *         version             Integer DEFAULT 1 ,
     *         dvReqInfo           DVCSRequestInformation,
     *         messageImprint      DigestInfo,
     *         serialNumber        Integer,
     *         responseTime        DVCSTime,
     *         dvStatus            [0] PKIStatusInfo OPTIONAL,
     *         policy              [1] PolicyInformation OPTIONAL,
     *         reqSignature        [2] SignerInfos  OPTIONAL,
     *         certs               [3] SEQUENCE SIZE (1..MAX) OF
     *                                 TargetEtcChain OPTIONAL,
     *         extensions          Extensions OPTIONAL
     *     }
     * 
    */ public class DVCSCertInfo extends ASN1Object { private int version = DEFAULT_VERSION; private DVCSRequestInformation dvReqInfo; private DigestInfo messageImprint; private ASN1Integer serialNumber; private DVCSTime responseTime; private PKIStatusInfo dvStatus; private PolicyInformation policy; private ASN1Set reqSignature; private ASN1Sequence certs; private Extensions extensions; private static final int DEFAULT_VERSION = 1; private static final int TAG_DV_STATUS = 0; private static final int TAG_POLICY = 1; private static final int TAG_REQ_SIGNATURE = 2; private static final int TAG_CERTS = 3; public DVCSCertInfo( DVCSRequestInformation dvReqInfo, DigestInfo messageImprint, ASN1Integer serialNumber, DVCSTime responseTime) { this.dvReqInfo = dvReqInfo; this.messageImprint = messageImprint; this.serialNumber = serialNumber; this.responseTime = responseTime; } private DVCSCertInfo(ASN1Sequence seq) { int i = 0; ASN1Encodable x = seq.getObjectAt(i++); try { ASN1Integer encVersion = ASN1Integer.getInstance(x); this.version = encVersion.getValue().intValue(); x = seq.getObjectAt(i++); } catch (IllegalArgumentException e) { } this.dvReqInfo = DVCSRequestInformation.getInstance(x); x = seq.getObjectAt(i++); this.messageImprint = DigestInfo.getInstance(x); x = seq.getObjectAt(i++); this.serialNumber = ASN1Integer.getInstance(x); x = seq.getObjectAt(i++); this.responseTime = DVCSTime.getInstance(x); while (i < seq.size()) { x = seq.getObjectAt(i++); try { ASN1TaggedObject t = ASN1TaggedObject.getInstance(x); int tagNo = t.getTagNo(); switch (tagNo) { case TAG_DV_STATUS: this.dvStatus = PKIStatusInfo.getInstance(t, false); break; case TAG_POLICY: this.policy = PolicyInformation.getInstance(ASN1Sequence.getInstance(t, false)); break; case TAG_REQ_SIGNATURE: this.reqSignature = ASN1Set.getInstance(t, false); break; case TAG_CERTS: this.certs = ASN1Sequence.getInstance(t, false); break; } continue; } catch (IllegalArgumentException e) { } try { this.extensions = Extensions.getInstance(x); } catch (IllegalArgumentException e) { } } } public static DVCSCertInfo getInstance(Object obj) { if (obj instanceof DVCSCertInfo) { return (DVCSCertInfo)obj; } else if (obj != null) { return new DVCSCertInfo(ASN1Sequence.getInstance(obj)); } return null; } public static DVCSCertInfo getInstance( ASN1TaggedObject obj, boolean explicit) { return getInstance(ASN1Sequence.getInstance(obj, explicit)); } public ASN1Primitive toASN1Primitive() { ASN1EncodableVector v = new ASN1EncodableVector(); if (version != DEFAULT_VERSION) { v.add(new ASN1Integer(version)); } v.add(dvReqInfo); v.add(messageImprint); v.add(serialNumber); v.add(responseTime); if (dvStatus != null) { v.add(new DERTaggedObject(false, TAG_DV_STATUS, dvStatus)); } if (policy != null) { v.add(new DERTaggedObject(false, TAG_POLICY, policy)); } if (reqSignature != null) { v.add(new DERTaggedObject(false, TAG_REQ_SIGNATURE, reqSignature)); } if (certs != null) { v.add(new DERTaggedObject(false, TAG_CERTS, certs)); } if (extensions != null) { v.add(extensions); } return new DERSequence(v); } public String toString() { StringBuffer s = new StringBuffer(); s.append("DVCSCertInfo {\n"); if (version != DEFAULT_VERSION) { s.append("version: " + version + "\n"); } s.append("dvReqInfo: " + dvReqInfo + "\n"); s.append("messageImprint: " + messageImprint + "\n"); s.append("serialNumber: " + serialNumber + "\n"); s.append("responseTime: " + responseTime + "\n"); if (dvStatus != null) { s.append("dvStatus: " + dvStatus + "\n"); } if (policy != null) { s.append("policy: " + policy + "\n"); } if (reqSignature != null) { s.append("reqSignature: " + reqSignature + "\n"); } if (certs != null) { s.append("certs: " + certs + "\n"); } if (extensions != null) { s.append("extensions: " + extensions + "\n"); } s.append("}\n"); return s.toString(); } public int getVersion() { return version; } private void setVersion(int version) { this.version = version; } public DVCSRequestInformation getDvReqInfo() { return dvReqInfo; } private void setDvReqInfo(DVCSRequestInformation dvReqInfo) { this.dvReqInfo = dvReqInfo; } public DigestInfo getMessageImprint() { return messageImprint; } private void setMessageImprint(DigestInfo messageImprint) { this.messageImprint = messageImprint; } public ASN1Integer getSerialNumber() { return serialNumber; } public DVCSTime getResponseTime() { return responseTime; } public PKIStatusInfo getDvStatus() { return dvStatus; } public PolicyInformation getPolicy() { return policy; } public ASN1Set getReqSignature() { return reqSignature; } public TargetEtcChain[] getCerts() { if (certs != null) { return TargetEtcChain.arrayFromSequence(certs); } return null; } public Extensions getExtensions() { return extensions; } } bouncycastle-1.49.orig/src/org/bouncycastle/asn1/dvcs/DVCSErrorNotice.java0000644000175000017500000000500112151250553026054 0ustar ebourgebourgpackage org.bouncycastle.asn1.dvcs; import org.bouncycastle.asn1.ASN1EncodableVector; import org.bouncycastle.asn1.ASN1Object; import org.bouncycastle.asn1.ASN1Primitive; import org.bouncycastle.asn1.ASN1Sequence; import org.bouncycastle.asn1.ASN1TaggedObject; import org.bouncycastle.asn1.DERSequence; import org.bouncycastle.asn1.cmp.PKIStatusInfo; import org.bouncycastle.asn1.x509.GeneralName; /** *
     *     DVCSErrorNotice ::= SEQUENCE {
     *         transactionStatus           PKIStatusInfo ,
     *         transactionIdentifier       GeneralName OPTIONAL
     *     }
     * 
    */ public class DVCSErrorNotice extends ASN1Object { private PKIStatusInfo transactionStatus; private GeneralName transactionIdentifier; public DVCSErrorNotice(PKIStatusInfo status) { this(status, null); } public DVCSErrorNotice(PKIStatusInfo status, GeneralName transactionIdentifier) { this.transactionStatus = status; this.transactionIdentifier = transactionIdentifier; } private DVCSErrorNotice(ASN1Sequence seq) { this.transactionStatus = PKIStatusInfo.getInstance(seq.getObjectAt(0)); if (seq.size() > 1) { this.transactionIdentifier = GeneralName.getInstance(seq.getObjectAt(1)); } } public static DVCSErrorNotice getInstance(Object obj) { if (obj instanceof DVCSErrorNotice) { return (DVCSErrorNotice)obj; } else if (obj != null) { return new DVCSErrorNotice(ASN1Sequence.getInstance(obj)); } return null; } public static DVCSErrorNotice getInstance( ASN1TaggedObject obj, boolean explicit) { return getInstance(ASN1Sequence.getInstance(obj, explicit)); } public ASN1Primitive toASN1Primitive() { ASN1EncodableVector v = new ASN1EncodableVector(); v.add(transactionStatus); if (transactionIdentifier != null) { v.add(transactionIdentifier); } return new DERSequence(v); } public String toString() { return "DVCSErrorNotice {\n" + "transactionStatus: " + transactionStatus + "\n" + (transactionIdentifier != null ? "transactionIdentifier: " + transactionIdentifier + "\n" : "") + "}\n"; } public PKIStatusInfo getTransactionStatus() { return transactionStatus; } public GeneralName getTransactionIdentifier() { return transactionIdentifier; } } bouncycastle-1.49.orig/src/org/bouncycastle/asn1/dvcs/DVCSCertInfoBuilder.java0000644000175000017500000001010212151250553026637 0ustar ebourgebourgpackage org.bouncycastle.asn1.dvcs; import org.bouncycastle.asn1.ASN1EncodableVector; import org.bouncycastle.asn1.ASN1Integer; import org.bouncycastle.asn1.ASN1Sequence; import org.bouncycastle.asn1.ASN1Set; import org.bouncycastle.asn1.DERSequence; import org.bouncycastle.asn1.DERTaggedObject; import org.bouncycastle.asn1.cmp.PKIStatusInfo; import org.bouncycastle.asn1.x509.DigestInfo; import org.bouncycastle.asn1.x509.Extensions; import org.bouncycastle.asn1.x509.PolicyInformation; /** *
     *     DVCSCertInfo::= SEQUENCE  {
     *         version             Integer DEFAULT 1 ,
     *         dvReqInfo           DVCSRequestInformation,
     *         messageImprint      DigestInfo,
     *         serialNumber        Integer,
     *         responseTime        DVCSTime,
     *         dvStatus            [0] PKIStatusInfo OPTIONAL,
     *         policy              [1] PolicyInformation OPTIONAL,
     *         reqSignature        [2] SignerInfos  OPTIONAL,
     *         certs               [3] SEQUENCE SIZE (1..MAX) OF
     *                                 TargetEtcChain OPTIONAL,
     *         extensions          Extensions OPTIONAL
     *     }
     * 
    */ public class DVCSCertInfoBuilder { private int version = DEFAULT_VERSION; private DVCSRequestInformation dvReqInfo; private DigestInfo messageImprint; private ASN1Integer serialNumber; private DVCSTime responseTime; private PKIStatusInfo dvStatus; private PolicyInformation policy; private ASN1Set reqSignature; private ASN1Sequence certs; private Extensions extensions; private static final int DEFAULT_VERSION = 1; private static final int TAG_DV_STATUS = 0; private static final int TAG_POLICY = 1; private static final int TAG_REQ_SIGNATURE = 2; private static final int TAG_CERTS = 3; public DVCSCertInfoBuilder( DVCSRequestInformation dvReqInfo, DigestInfo messageImprint, ASN1Integer serialNumber, DVCSTime responseTime) { this.dvReqInfo = dvReqInfo; this.messageImprint = messageImprint; this.serialNumber = serialNumber; this.responseTime = responseTime; } public DVCSCertInfo build() { ASN1EncodableVector v = new ASN1EncodableVector(); if (version != DEFAULT_VERSION) { v.add(new ASN1Integer(version)); } v.add(dvReqInfo); v.add(messageImprint); v.add(serialNumber); v.add(responseTime); if (dvStatus != null) { v.add(new DERTaggedObject(false, TAG_DV_STATUS, dvStatus)); } if (policy != null) { v.add(new DERTaggedObject(false, TAG_POLICY, policy)); } if (reqSignature != null) { v.add(new DERTaggedObject(false, TAG_REQ_SIGNATURE, reqSignature)); } if (certs != null) { v.add(new DERTaggedObject(false, TAG_CERTS, certs)); } if (extensions != null) { v.add(extensions); } return DVCSCertInfo.getInstance(new DERSequence(v)); } public void setVersion(int version) { this.version = version; } public void setDvReqInfo(DVCSRequestInformation dvReqInfo) { this.dvReqInfo = dvReqInfo; } public void setMessageImprint(DigestInfo messageImprint) { this.messageImprint = messageImprint; } public void setSerialNumber(ASN1Integer serialNumber) { this.serialNumber = serialNumber; } public void setResponseTime(DVCSTime responseTime) { this.responseTime = responseTime; } public void setDvStatus(PKIStatusInfo dvStatus) { this.dvStatus = dvStatus; } public void setPolicy(PolicyInformation policy) { this.policy = policy; } public void setReqSignature(ASN1Set reqSignature) { this.reqSignature = reqSignature; } public void setCerts(TargetEtcChain[] certs) { this.certs = new DERSequence(certs); } public void setExtensions(Extensions extensions) { this.extensions = extensions; } } bouncycastle-1.49.orig/src/org/bouncycastle/asn1/dvcs/PathProcInput.java0000644000175000017500000001252712151250553025714 0ustar ebourgebourgpackage org.bouncycastle.asn1.dvcs; import org.bouncycastle.asn1.ASN1Boolean; import org.bouncycastle.asn1.ASN1EncodableVector; import org.bouncycastle.asn1.ASN1Object; import org.bouncycastle.asn1.ASN1Primitive; import org.bouncycastle.asn1.ASN1Sequence; import org.bouncycastle.asn1.ASN1TaggedObject; import org.bouncycastle.asn1.DERSequence; import org.bouncycastle.asn1.DERTaggedObject; import org.bouncycastle.asn1.x509.PolicyInformation; /** *
     *     PathProcInput ::= SEQUENCE {
     *         acceptablePolicySet          SEQUENCE SIZE (1..MAX) OF
     *                                         PolicyInformation,
     *         inhibitPolicyMapping         BOOLEAN DEFAULT FALSE,
     *         explicitPolicyReqd           [0] BOOLEAN DEFAULT FALSE ,
     *         inhibitAnyPolicy             [1] BOOLEAN DEFAULT FALSE
     *     }
     * 
    */ public class PathProcInput extends ASN1Object { private PolicyInformation[] acceptablePolicySet; private boolean inhibitPolicyMapping = false; private boolean explicitPolicyReqd = false; private boolean inhibitAnyPolicy = false; public PathProcInput(PolicyInformation[] acceptablePolicySet) { this.acceptablePolicySet = acceptablePolicySet; } public PathProcInput(PolicyInformation[] acceptablePolicySet, boolean inhibitPolicyMapping, boolean explicitPolicyReqd, boolean inhibitAnyPolicy) { this.acceptablePolicySet = acceptablePolicySet; this.inhibitPolicyMapping = inhibitPolicyMapping; this.explicitPolicyReqd = explicitPolicyReqd; this.inhibitAnyPolicy = inhibitAnyPolicy; } private static PolicyInformation[] fromSequence(ASN1Sequence seq) { PolicyInformation[] tmp = new PolicyInformation[seq.size()]; for (int i = 0; i != tmp.length; i++) { tmp[i] = PolicyInformation.getInstance(seq.getObjectAt(i)); } return tmp; } public static PathProcInput getInstance(Object obj) { if (obj instanceof PathProcInput) { return (PathProcInput)obj; } else if (obj != null) { ASN1Sequence seq = ASN1Sequence.getInstance(obj); ASN1Sequence policies = ASN1Sequence.getInstance(seq.getObjectAt(0)); PathProcInput result = new PathProcInput(fromSequence(policies)); for (int i = 1; i < seq.size(); i++) { Object o = seq.getObjectAt(i); if (o instanceof ASN1Boolean) { ASN1Boolean x = ASN1Boolean.getInstance(o); result.setInhibitPolicyMapping(x.isTrue()); } else if (o instanceof ASN1TaggedObject) { ASN1TaggedObject t = ASN1TaggedObject.getInstance(o); ASN1Boolean x; switch (t.getTagNo()) { case 0: x = ASN1Boolean.getInstance(t, false); result.setExplicitPolicyReqd(x.isTrue()); break; case 1: x = ASN1Boolean.getInstance(t, false); result.setInhibitAnyPolicy(x.isTrue()); } } } return result; } return null; } public static PathProcInput getInstance( ASN1TaggedObject obj, boolean explicit) { return getInstance(ASN1Sequence.getInstance(obj, explicit)); } public ASN1Primitive toASN1Primitive() { ASN1EncodableVector v = new ASN1EncodableVector(); ASN1EncodableVector pV = new ASN1EncodableVector(); for (int i = 0; i != acceptablePolicySet.length; i++) { pV.add(acceptablePolicySet[i]); } v.add(new DERSequence(pV)); if (inhibitPolicyMapping) { v.add(new ASN1Boolean(inhibitPolicyMapping)); } if (explicitPolicyReqd) { v.add(new DERTaggedObject(false, 0, new ASN1Boolean(explicitPolicyReqd))); } if (inhibitAnyPolicy) { v.add(new DERTaggedObject(false, 1, new ASN1Boolean(inhibitAnyPolicy))); } return new DERSequence(v); } public String toString() { return "PathProcInput: {\n" + "acceptablePolicySet: " + acceptablePolicySet + "\n" + "inhibitPolicyMapping: " + inhibitPolicyMapping + "\n" + "explicitPolicyReqd: " + explicitPolicyReqd + "\n" + "inhibitAnyPolicy: " + inhibitAnyPolicy + "\n" + "}\n"; } public PolicyInformation[] getAcceptablePolicySet() { return acceptablePolicySet; } public boolean isInhibitPolicyMapping() { return inhibitPolicyMapping; } private void setInhibitPolicyMapping(boolean inhibitPolicyMapping) { this.inhibitPolicyMapping = inhibitPolicyMapping; } public boolean isExplicitPolicyReqd() { return explicitPolicyReqd; } private void setExplicitPolicyReqd(boolean explicitPolicyReqd) { this.explicitPolicyReqd = explicitPolicyReqd; } public boolean isInhibitAnyPolicy() { return inhibitAnyPolicy; } private void setInhibitAnyPolicy(boolean inhibitAnyPolicy) { this.inhibitAnyPolicy = inhibitAnyPolicy; } } bouncycastle-1.49.orig/src/org/bouncycastle/asn1/dvcs/DVCSRequestInformation.java0000644000175000017500000001633412151250553027472 0ustar ebourgebourgpackage org.bouncycastle.asn1.dvcs; import java.math.BigInteger; import org.bouncycastle.asn1.ASN1Encodable; import org.bouncycastle.asn1.ASN1EncodableVector; import org.bouncycastle.asn1.ASN1GeneralizedTime; import org.bouncycastle.asn1.ASN1Integer; import org.bouncycastle.asn1.ASN1Object; import org.bouncycastle.asn1.ASN1Primitive; import org.bouncycastle.asn1.ASN1Sequence; import org.bouncycastle.asn1.ASN1TaggedObject; import org.bouncycastle.asn1.DERSequence; import org.bouncycastle.asn1.DERTaggedObject; import org.bouncycastle.asn1.x509.Extensions; import org.bouncycastle.asn1.x509.GeneralNames; import org.bouncycastle.asn1.x509.PolicyInformation; /** *
     *     DVCSRequestInformation ::= SEQUENCE  {
     *         version                      INTEGER DEFAULT 1 ,
     *         service                      ServiceType,
     *         nonce                        Nonce OPTIONAL,
     *         requestTime                  DVCSTime OPTIONAL,
     *         requester                    [0] GeneralNames OPTIONAL,
     *         requestPolicy                [1] PolicyInformation OPTIONAL,
     *         dvcs                         [2] GeneralNames OPTIONAL,
     *         dataLocations                [3] GeneralNames OPTIONAL,
     *         extensions                   [4] IMPLICIT Extensions OPTIONAL
     *     }
     * 
    */ public class DVCSRequestInformation extends ASN1Object { private int version = DEFAULT_VERSION; private ServiceType service; private BigInteger nonce; private DVCSTime requestTime; private GeneralNames requester; private PolicyInformation requestPolicy; private GeneralNames dvcs; private GeneralNames dataLocations; private Extensions extensions; private static final int DEFAULT_VERSION = 1; private static final int TAG_REQUESTER = 0; private static final int TAG_REQUEST_POLICY = 1; private static final int TAG_DVCS = 2; private static final int TAG_DATA_LOCATIONS = 3; private static final int TAG_EXTENSIONS = 4; private DVCSRequestInformation(ASN1Sequence seq) { int i = 0; if (seq.getObjectAt(0) instanceof ASN1Integer) { ASN1Integer encVersion = ASN1Integer.getInstance(seq.getObjectAt(i++)); this.version = encVersion.getValue().intValue(); } else { this.version = 1; } this.service = ServiceType.getInstance(seq.getObjectAt(i++)); while (i < seq.size()) { ASN1Encodable x = seq.getObjectAt(i); if (x instanceof ASN1Integer) { this.nonce = ASN1Integer.getInstance(x).getValue(); } else if (x instanceof ASN1GeneralizedTime) { this.requestTime = DVCSTime.getInstance(x); } else if (x instanceof ASN1TaggedObject) { ASN1TaggedObject t = ASN1TaggedObject.getInstance(x); int tagNo = t.getTagNo(); switch (tagNo) { case TAG_REQUESTER: this.requester = GeneralNames.getInstance(t, false); break; case TAG_REQUEST_POLICY: this.requestPolicy = PolicyInformation.getInstance(ASN1Sequence.getInstance(t, false)); break; case TAG_DVCS: this.dvcs = GeneralNames.getInstance(t, false); break; case TAG_DATA_LOCATIONS: this.dataLocations = GeneralNames.getInstance(t, false); break; case TAG_EXTENSIONS: this.extensions = Extensions.getInstance(t, false); break; } } else { this.requestTime = DVCSTime.getInstance(x); } i++; } } public static DVCSRequestInformation getInstance(Object obj) { if (obj instanceof DVCSRequestInformation) { return (DVCSRequestInformation)obj; } else if (obj != null) { return new DVCSRequestInformation(ASN1Sequence.getInstance(obj)); } return null; } public static DVCSRequestInformation getInstance( ASN1TaggedObject obj, boolean explicit) { return getInstance(ASN1Sequence.getInstance(obj, explicit)); } public ASN1Primitive toASN1Primitive() { ASN1EncodableVector v = new ASN1EncodableVector(); if (version != DEFAULT_VERSION) { v.add(new ASN1Integer(version)); } v.add(service); if (nonce != null) { v.add(new ASN1Integer(nonce)); } if (requestTime != null) { v.add(requestTime); } int[] tags = new int[]{ TAG_REQUESTER, TAG_REQUEST_POLICY, TAG_DVCS, TAG_DATA_LOCATIONS, TAG_EXTENSIONS }; ASN1Encodable[] taggedObjects = new ASN1Encodable[]{ requester, requestPolicy, dvcs, dataLocations, extensions }; for (int i = 0; i < tags.length; i++) { int tag = tags[i]; ASN1Encodable taggedObject = taggedObjects[i]; if (taggedObject != null) { v.add(new DERTaggedObject(false, tag, taggedObject)); } } return new DERSequence(v); } public String toString() { StringBuffer s = new StringBuffer(); s.append("DVCSRequestInformation {\n"); if (version != DEFAULT_VERSION) { s.append("version: " + version + "\n"); } s.append("service: " + service + "\n"); if (nonce != null) { s.append("nonce: " + nonce + "\n"); } if (requestTime != null) { s.append("requestTime: " + requestTime + "\n"); } if (requester != null) { s.append("requester: " + requester + "\n"); } if (requestPolicy != null) { s.append("requestPolicy: " + requestPolicy + "\n"); } if (dvcs != null) { s.append("dvcs: " + dvcs + "\n"); } if (dataLocations != null) { s.append("dataLocations: " + dataLocations + "\n"); } if (extensions != null) { s.append("extensions: " + extensions + "\n"); } s.append("}\n"); return s.toString(); } public int getVersion() { return version; } public ServiceType getService() { return service; } public BigInteger getNonce() { return nonce; } public DVCSTime getRequestTime() { return requestTime; } public GeneralNames getRequester() { return requester; } public PolicyInformation getRequestPolicy() { return requestPolicy; } public GeneralNames getDVCS() { return dvcs; } public GeneralNames getDataLocations() { return dataLocations; } public Extensions getExtensions() { return extensions; } } bouncycastle-1.49.orig/src/org/bouncycastle/asn1/dvcs/DVCSResponse.java0000644000175000017500000000570712151250553025434 0ustar ebourgebourgpackage org.bouncycastle.asn1.dvcs; import java.io.IOException; import org.bouncycastle.asn1.ASN1Choice; import org.bouncycastle.asn1.ASN1Object; import org.bouncycastle.asn1.ASN1Primitive; import org.bouncycastle.asn1.ASN1Sequence; import org.bouncycastle.asn1.ASN1TaggedObject; import org.bouncycastle.asn1.DERTaggedObject; /** *
     *     DVCSResponse ::= CHOICE
     *     {
     *         dvCertInfo         DVCSCertInfo ,
     *         dvErrorNote        [0] DVCSErrorNotice
     *     }
     * 
    */ public class DVCSResponse extends ASN1Object implements ASN1Choice { private DVCSCertInfo dvCertInfo; private DVCSErrorNotice dvErrorNote; public DVCSResponse(DVCSCertInfo dvCertInfo) { this.dvCertInfo = dvCertInfo; } public DVCSResponse(DVCSErrorNotice dvErrorNote) { this.dvErrorNote = dvErrorNote; } public static DVCSResponse getInstance(Object obj) { if (obj == null || obj instanceof DVCSResponse) { return (DVCSResponse)obj; } else { if (obj instanceof byte[]) { try { return getInstance(ASN1Primitive.fromByteArray((byte[])obj)); } catch (IOException e) { throw new IllegalArgumentException("failed to construct sequence from byte[]: " + e.getMessage()); } } if (obj instanceof ASN1Sequence) { DVCSCertInfo dvCertInfo = DVCSCertInfo.getInstance(obj); return new DVCSResponse(dvCertInfo); } if (obj instanceof ASN1TaggedObject) { ASN1TaggedObject t = ASN1TaggedObject.getInstance(obj); DVCSErrorNotice dvErrorNote = DVCSErrorNotice.getInstance(t, false); return new DVCSResponse(dvErrorNote); } } throw new IllegalArgumentException("Couldn't convert from object to DVCSResponse: " + obj.getClass().getName()); } public static DVCSResponse getInstance( ASN1TaggedObject obj, boolean explicit) { return getInstance(ASN1Sequence.getInstance(obj, explicit)); } public DVCSCertInfo getCertInfo() { return dvCertInfo; } public DVCSErrorNotice getErrorNotice() { return dvErrorNote; } public ASN1Primitive toASN1Primitive() { if (dvCertInfo != null) { return dvCertInfo.toASN1Primitive(); } else { return new DERTaggedObject(0, dvErrorNote); } } public String toString() { if (dvCertInfo != null) { return "DVCSResponse {\ndvCertInfo: " + dvCertInfo.toString() + "}\n"; } if (dvErrorNote != null) { return "DVCSResponse {\ndvErrorNote: " + dvErrorNote.toString() + "}\n"; } return null; } } bouncycastle-1.49.orig/src/org/bouncycastle/asn1/dvcs/DVCSTime.java0000644000175000017500000000442112151250553024524 0ustar ebourgebourgpackage org.bouncycastle.asn1.dvcs; import java.util.Date; import org.bouncycastle.asn1.ASN1Choice; import org.bouncycastle.asn1.ASN1GeneralizedTime; import org.bouncycastle.asn1.ASN1Object; import org.bouncycastle.asn1.ASN1Primitive; import org.bouncycastle.asn1.ASN1TaggedObject; import org.bouncycastle.asn1.cms.ContentInfo; /** *
     *     DVCSTime ::= CHOICE  {
     *         genTime                      GeneralizedTime,
     *         timeStampToken               ContentInfo
     *     }
     * 
    */ public class DVCSTime extends ASN1Object implements ASN1Choice { private ASN1GeneralizedTime genTime; private ContentInfo timeStampToken; private Date time; // constructors: public DVCSTime(Date time) { this(new ASN1GeneralizedTime(time)); } public DVCSTime(ASN1GeneralizedTime genTime) { this.genTime = genTime; } public DVCSTime(ContentInfo timeStampToken) { this.timeStampToken = timeStampToken; } public static DVCSTime getInstance(Object obj) { if (obj instanceof DVCSTime) { return (DVCSTime)obj; } else if (obj instanceof ASN1GeneralizedTime) { return new DVCSTime(ASN1GeneralizedTime.getInstance(obj)); } else if (obj != null) { return new DVCSTime(ContentInfo.getInstance(obj)); } return null; } public static DVCSTime getInstance( ASN1TaggedObject obj, boolean explicit) { return getInstance(obj.getObject()); // must be explicitly tagged } // selectors: public ASN1GeneralizedTime getGenTime() { return genTime; } public ContentInfo getTimeStampToken() { return timeStampToken; } public ASN1Primitive toASN1Primitive() { if (genTime != null) { return genTime; } if (timeStampToken != null) { return timeStampToken.toASN1Primitive(); } return null; } public String toString() { if (genTime != null) { return genTime.toString(); } if (timeStampToken != null) { return timeStampToken.toString(); } return null; } } bouncycastle-1.49.orig/src/org/bouncycastle/asn1/dvcs/TargetEtcChain.java0000644000175000017500000001074612151250553026002 0ustar ebourgebourgpackage org.bouncycastle.asn1.dvcs; import org.bouncycastle.asn1.ASN1Encodable; import org.bouncycastle.asn1.ASN1EncodableVector; import org.bouncycastle.asn1.ASN1Object; import org.bouncycastle.asn1.ASN1Primitive; import org.bouncycastle.asn1.ASN1Sequence; import org.bouncycastle.asn1.ASN1TaggedObject; import org.bouncycastle.asn1.DERSequence; import org.bouncycastle.asn1.DERTaggedObject; /** *
     *     TargetEtcChain ::= SEQUENCE {
     *         target                       CertEtcToken,
     *         chain                        SEQUENCE SIZE (1..MAX) OF
     *                                         CertEtcToken OPTIONAL,
     *         pathProcInput                [0] PathProcInput OPTIONAL
     *     }
     * 
    */ public class TargetEtcChain extends ASN1Object { private CertEtcToken target; private ASN1Sequence chain; private PathProcInput pathProcInput; public TargetEtcChain(CertEtcToken target) { this(target, null, null); } public TargetEtcChain(CertEtcToken target, CertEtcToken[] chain) { this(target, chain, null); } public TargetEtcChain(CertEtcToken target, PathProcInput pathProcInput) { this(target, null, pathProcInput); } public TargetEtcChain(CertEtcToken target, CertEtcToken[] chain, PathProcInput pathProcInput) { this.target = target; if (chain != null) { this.chain = new DERSequence(chain); } this.pathProcInput = pathProcInput; } private TargetEtcChain(ASN1Sequence seq) { int i = 0; ASN1Encodable obj = seq.getObjectAt(i++); this.target = CertEtcToken.getInstance(obj); try { obj = seq.getObjectAt(i++); this.chain = ASN1Sequence.getInstance(obj); } catch (IllegalArgumentException e) { } catch (IndexOutOfBoundsException e) { return; } try { obj = seq.getObjectAt(i++); ASN1TaggedObject tagged = ASN1TaggedObject.getInstance(obj); switch (tagged.getTagNo()) { case 0: this.pathProcInput = PathProcInput.getInstance(tagged, false); break; } } catch (IllegalArgumentException e) { } catch (IndexOutOfBoundsException e) { } } public static TargetEtcChain getInstance(Object obj) { if (obj instanceof TargetEtcChain) { return (TargetEtcChain)obj; } else if (obj != null) { return new TargetEtcChain(ASN1Sequence.getInstance(obj)); } return null; } public static TargetEtcChain getInstance( ASN1TaggedObject obj, boolean explicit) { return getInstance(ASN1Sequence.getInstance(obj, explicit)); } public ASN1Primitive toASN1Primitive() { ASN1EncodableVector v = new ASN1EncodableVector(); v.add(target); if (chain != null) { v.add(chain); } if (pathProcInput != null) { v.add(new DERTaggedObject(false, 0, pathProcInput)); } return new DERSequence(v); } public String toString() { StringBuffer s = new StringBuffer(); s.append("TargetEtcChain {\n"); s.append("target: " + target + "\n"); if (chain != null) { s.append("chain: " + chain + "\n"); } if (pathProcInput != null) { s.append("pathProcInput: " + pathProcInput + "\n"); } s.append("}\n"); return s.toString(); } public CertEtcToken getTarget() { return target; } public CertEtcToken[] getChain() { if (chain != null) { return CertEtcToken.arrayFromSequence(chain); } return null; } private void setChain(ASN1Sequence chain) { this.chain = chain; } public PathProcInput getPathProcInput() { return pathProcInput; } private void setPathProcInput(PathProcInput pathProcInput) { this.pathProcInput = pathProcInput; } public static TargetEtcChain[] arrayFromSequence(ASN1Sequence seq) { TargetEtcChain[] tmp = new TargetEtcChain[seq.size()]; for (int i = 0; i != tmp.length; i++) { tmp[i] = TargetEtcChain.getInstance(seq.getObjectAt(i)); } return tmp; } } bouncycastle-1.49.orig/src/org/bouncycastle/asn1/dvcs/ServiceType.java0000644000175000017500000000431312151250553025410 0ustar ebourgebourgpackage org.bouncycastle.asn1.dvcs; import java.math.BigInteger; import org.bouncycastle.asn1.ASN1Enumerated; import org.bouncycastle.asn1.ASN1Object; import org.bouncycastle.asn1.ASN1Primitive; import org.bouncycastle.asn1.ASN1TaggedObject; /** * ServiceType ::= ENUMERATED { cpd(1), vsd(2), cpkc(3), ccpd(4) } */ public class ServiceType extends ASN1Object { /** * Identifier of CPD service (Certify Possession of Data). */ public static final ServiceType CPD = new ServiceType(1); /** * Identifier of VSD service (Verify Signed Document). */ public static final ServiceType VSD = new ServiceType(2); /** * Identifier of VPKC service (Verify Public Key Certificates (also referred to as CPKC)). */ public static final ServiceType VPKC = new ServiceType(3); /** * Identifier of CCPD service (Certify Claim of Possession of Data). */ public static final ServiceType CCPD = new ServiceType(4); private ASN1Enumerated value; public ServiceType(int value) { this.value = new ASN1Enumerated(value); } private ServiceType(ASN1Enumerated value) { this.value = value; } public static ServiceType getInstance(Object obj) { if (obj instanceof ServiceType) { return (ServiceType)obj; } else if (obj != null) { return new ServiceType(ASN1Enumerated.getInstance(obj)); } return null; } public static ServiceType getInstance( ASN1TaggedObject obj, boolean explicit) { return getInstance(ASN1Enumerated.getInstance(obj, explicit)); } public BigInteger getValue() { return value.getValue(); } public ASN1Primitive toASN1Primitive() { return value; } public String toString() { int num = value.getValue().intValue(); return "" + num + ( num == CPD.getValue().intValue() ? "(CPD)" : num == VSD.getValue().intValue() ? "(VSD)" : num == VPKC.getValue().intValue() ? "(VPKC)" : num == CCPD.getValue().intValue() ? "(CCPD)" : "?"); } } bouncycastle-1.49.orig/src/org/bouncycastle/asn1/dvcs/DVCSRequestInformationBuilder.java0000644000175000017500000001547612151250553031007 0ustar ebourgebourgpackage org.bouncycastle.asn1.dvcs; import java.math.BigInteger; import org.bouncycastle.asn1.ASN1Encodable; import org.bouncycastle.asn1.ASN1EncodableVector; import org.bouncycastle.asn1.ASN1Integer; import org.bouncycastle.asn1.DERSequence; import org.bouncycastle.asn1.DERTaggedObject; import org.bouncycastle.asn1.x509.Extensions; import org.bouncycastle.asn1.x509.GeneralName; import org.bouncycastle.asn1.x509.GeneralNames; import org.bouncycastle.asn1.x509.PolicyInformation; import org.bouncycastle.util.BigIntegers; /** *
     *     DVCSRequestInformation ::= SEQUENCE  {
     *         version                      INTEGER DEFAULT 1 ,
     *         service                      ServiceType,
     *         nonce                        Nonce OPTIONAL,
     *         requestTime                  DVCSTime OPTIONAL,
     *         requester                    [0] GeneralNames OPTIONAL,
     *         requestPolicy                [1] PolicyInformation OPTIONAL,
     *         dvcs                         [2] GeneralNames OPTIONAL,
     *         dataLocations                [3] GeneralNames OPTIONAL,
     *         extensions                   [4] IMPLICIT Extensions OPTIONAL
     *     }
     * 
    */ public class DVCSRequestInformationBuilder { private int version = DEFAULT_VERSION; private final ServiceType service; private DVCSRequestInformation initialInfo; private BigInteger nonce; private DVCSTime requestTime; private GeneralNames requester; private PolicyInformation requestPolicy; private GeneralNames dvcs; private GeneralNames dataLocations; private Extensions extensions; private static final int DEFAULT_VERSION = 1; private static final int TAG_REQUESTER = 0; private static final int TAG_REQUEST_POLICY = 1; private static final int TAG_DVCS = 2; private static final int TAG_DATA_LOCATIONS = 3; private static final int TAG_EXTENSIONS = 4; public DVCSRequestInformationBuilder(ServiceType service) { this.service = service; } public DVCSRequestInformationBuilder(DVCSRequestInformation initialInfo) { this.initialInfo = initialInfo; this.service = initialInfo.getService(); this.version = initialInfo.getVersion(); this.nonce = initialInfo.getNonce(); this.requestTime = initialInfo.getRequestTime(); this.requestPolicy = initialInfo.getRequestPolicy(); this.dvcs = initialInfo.getDVCS(); this.dataLocations = initialInfo.getDataLocations(); } public DVCSRequestInformation build() { ASN1EncodableVector v = new ASN1EncodableVector(); if (version != DEFAULT_VERSION) { v.add(new ASN1Integer(version)); } v.add(service); if (nonce != null) { v.add(new ASN1Integer(nonce)); } if (requestTime != null) { v.add(requestTime); } int[] tags = new int[]{ TAG_REQUESTER, TAG_REQUEST_POLICY, TAG_DVCS, TAG_DATA_LOCATIONS, TAG_EXTENSIONS }; ASN1Encodable[] taggedObjects = new ASN1Encodable[]{ requester, requestPolicy, dvcs, dataLocations, extensions }; for (int i = 0; i < tags.length; i++) { int tag = tags[i]; ASN1Encodable taggedObject = taggedObjects[i]; if (taggedObject != null) { v.add(new DERTaggedObject(false, tag, taggedObject)); } } return DVCSRequestInformation.getInstance(new DERSequence(v)); } public void setVersion(int version) { if (initialInfo != null) { throw new IllegalStateException("cannot change version in existing DVCSRequestInformation"); } this.version = version; } public void setNonce(BigInteger nonce) { // RFC 3029, 9.1: The DVCS MAY modify the fields // 'dvcs', 'requester', 'dataLocations', and 'nonce' of the ReqInfo structure // RFC 3029, 9.1: The only modification // allowed to a 'nonce' is the inclusion of a new field if it was not // present, or to concatenate other data to the end (right) of an // existing value. if (initialInfo != null) { if (initialInfo.getNonce() == null) { this.nonce = nonce; } else { byte[] initialBytes = initialInfo.getNonce().toByteArray(); byte[] newBytes = BigIntegers.asUnsignedByteArray(nonce); byte[] nonceBytes = new byte[initialBytes.length + newBytes.length]; System.arraycopy(initialBytes, 0, nonceBytes, 0, initialBytes.length); System.arraycopy(newBytes, 0, nonceBytes, initialBytes.length, newBytes.length); this.nonce = new BigInteger(nonceBytes); } } this.nonce = nonce; } public void setRequestTime(DVCSTime requestTime) { if (initialInfo != null) { throw new IllegalStateException("cannot change request time in existing DVCSRequestInformation"); } this.requestTime = requestTime; } public void setRequester(GeneralName requester) { this.setRequester(new GeneralNames(requester)); } public void setRequester(GeneralNames requester) { // RFC 3029, 9.1: The DVCS MAY modify the fields // 'dvcs', 'requester', 'dataLocations', and 'nonce' of the ReqInfo structure this.requester = requester; } public void setRequestPolicy(PolicyInformation requestPolicy) { if (initialInfo != null) { throw new IllegalStateException("cannot change request policy in existing DVCSRequestInformation"); } this.requestPolicy = requestPolicy; } public void setDVCS(GeneralName dvcs) { this.setDVCS(new GeneralNames(dvcs)); } public void setDVCS(GeneralNames dvcs) { // RFC 3029, 9.1: The DVCS MAY modify the fields // 'dvcs', 'requester', 'dataLocations', and 'nonce' of the ReqInfo structure this.dvcs = dvcs; } public void setDataLocations(GeneralName dataLocation) { this.setDataLocations(new GeneralNames(dataLocation)); } public void setDataLocations(GeneralNames dataLocations) { // RFC 3029, 9.1: The DVCS MAY modify the fields // 'dvcs', 'requester', 'dataLocations', and 'nonce' of the ReqInfo structure this.dataLocations = dataLocations; } public void setExtensions(Extensions extensions) { if (initialInfo != null) { throw new IllegalStateException("cannot change extensions in existing DVCSRequestInformation"); } this.extensions = extensions; } } bouncycastle-1.49.orig/src/org/bouncycastle/asn1/dvcs/DVCSRequest.java0000644000175000017500000000545412151250553025265 0ustar ebourgebourgpackage org.bouncycastle.asn1.dvcs; import org.bouncycastle.asn1.ASN1EncodableVector; import org.bouncycastle.asn1.ASN1Object; import org.bouncycastle.asn1.ASN1Primitive; import org.bouncycastle.asn1.ASN1Sequence; import org.bouncycastle.asn1.ASN1TaggedObject; import org.bouncycastle.asn1.DERSequence; import org.bouncycastle.asn1.x509.GeneralName; /** *
     *     DVCSRequest ::= SEQUENCE  {
     *         requestInformation         DVCSRequestInformation,
     *         data                       Data,
     *         transactionIdentifier      GeneralName OPTIONAL
     *     }
     * 
    */ public class DVCSRequest extends ASN1Object { private DVCSRequestInformation requestInformation; private Data data; private GeneralName transactionIdentifier; public DVCSRequest(DVCSRequestInformation requestInformation, Data data) { this(requestInformation, data, null); } public DVCSRequest(DVCSRequestInformation requestInformation, Data data, GeneralName transactionIdentifier) { this.requestInformation = requestInformation; this.data = data; this.transactionIdentifier = transactionIdentifier; } private DVCSRequest(ASN1Sequence seq) { requestInformation = DVCSRequestInformation.getInstance(seq.getObjectAt(0)); data = Data.getInstance(seq.getObjectAt(1)); if (seq.size() > 2) { transactionIdentifier = GeneralName.getInstance(seq.getObjectAt(2)); } } public static DVCSRequest getInstance(Object obj) { if (obj instanceof DVCSRequest) { return (DVCSRequest)obj; } else if (obj != null) { return new DVCSRequest(ASN1Sequence.getInstance(obj)); } return null; } public static DVCSRequest getInstance( ASN1TaggedObject obj, boolean explicit) { return getInstance(ASN1Sequence.getInstance(obj, explicit)); } public ASN1Primitive toASN1Primitive() { ASN1EncodableVector v = new ASN1EncodableVector(); v.add(requestInformation); v.add(data); if (transactionIdentifier != null) { v.add(transactionIdentifier); } return new DERSequence(v); } public String toString() { return "DVCSRequest {\n" + "requestInformation: " + requestInformation + "\n" + "data: " + data + "\n" + (transactionIdentifier != null ? "transactionIdentifier: " + transactionIdentifier + "\n" : "") + "}\n"; } public Data getData() { return data; } public DVCSRequestInformation getRequestInformation() { return requestInformation; } public GeneralName getTransactionIdentifier() { return transactionIdentifier; } } bouncycastle-1.49.orig/src/org/bouncycastle/asn1/dvcs/Data.java0000644000175000017500000000656712151250553024034 0ustar ebourgebourgpackage org.bouncycastle.asn1.dvcs; import org.bouncycastle.asn1.ASN1Choice; import org.bouncycastle.asn1.ASN1Object; import org.bouncycastle.asn1.ASN1OctetString; import org.bouncycastle.asn1.ASN1Primitive; import org.bouncycastle.asn1.ASN1Sequence; import org.bouncycastle.asn1.ASN1TaggedObject; import org.bouncycastle.asn1.DEROctetString; import org.bouncycastle.asn1.DERSequence; import org.bouncycastle.asn1.DERTaggedObject; import org.bouncycastle.asn1.x509.DigestInfo; /** *
     * Data ::= CHOICE {
     *   message           OCTET STRING ,
     *   messageImprint    DigestInfo,
     *   certs             [0] SEQUENCE SIZE (1..MAX) OF
     *                         TargetEtcChain
     * }
     * 
    */ public class Data extends ASN1Object implements ASN1Choice { private ASN1OctetString message; private DigestInfo messageImprint; private ASN1Sequence certs; public Data(byte[] messageBytes) { this.message = new DEROctetString(messageBytes); } public Data(ASN1OctetString message) { this.message = message; } public Data(DigestInfo messageImprint) { this.messageImprint = messageImprint; } public Data(TargetEtcChain cert) { this.certs = new DERSequence(cert); } public Data(TargetEtcChain[] certs) { this.certs = new DERSequence(certs); } private Data(ASN1Sequence certs) { this.certs = certs; } public static Data getInstance(Object obj) { if (obj instanceof Data) { return (Data)obj; } else if (obj instanceof ASN1OctetString) { return new Data((ASN1OctetString)obj); } else if (obj instanceof ASN1Sequence) { return new Data(DigestInfo.getInstance(obj)); } else if (obj instanceof ASN1TaggedObject) { return new Data(ASN1Sequence.getInstance((ASN1TaggedObject)obj, false)); } throw new IllegalArgumentException("Unknown object submitted to getInstance: " + obj.getClass().getName()); } public static Data getInstance( ASN1TaggedObject obj, boolean explicit) { return getInstance(obj.getObject()); } public ASN1Primitive toASN1Primitive() { if (message != null) { return message.toASN1Primitive(); } if (messageImprint != null) { return messageImprint.toASN1Primitive(); } else { return new DERTaggedObject(false, 0, certs); } } public String toString() { if (message != null) { return "Data {\n" + message + "}\n"; } if (messageImprint != null) { return "Data {\n" + messageImprint + "}\n"; } else { return "Data {\n" + certs + "}\n"; } } public ASN1OctetString getMessage() { return message; } public DigestInfo getMessageImprint() { return messageImprint; } public TargetEtcChain[] getCerts() { if (certs == null) { return null; } TargetEtcChain[] tmp = new TargetEtcChain[certs.size()]; for (int i = 0; i != tmp.length; i++) { tmp[i] = TargetEtcChain.getInstance(certs.getObjectAt(i)); } return tmp; } } bouncycastle-1.49.orig/src/org/bouncycastle/asn1/dvcs/DVCSObjectIdentifiers.java0000644000175000017500000000312312151250553027220 0ustar ebourgebourgpackage org.bouncycastle.asn1.dvcs; import org.bouncycastle.asn1.ASN1ObjectIdentifier; public interface DVCSObjectIdentifiers { // id-pkix OBJECT IDENTIFIER ::= {iso(1) // identified-organization(3) dod(6) // internet(1) security(5) mechanisms(5) pkix(7)} // // id-smime OBJECT IDENTIFIER ::= { iso(1) member-body(2) // us(840) rsadsi(113549) pkcs(1) pkcs-9(9) 16 } public static final ASN1ObjectIdentifier id_pkix = new ASN1ObjectIdentifier("1.3.6.1.5.5.7"); public static final ASN1ObjectIdentifier id_smime = new ASN1ObjectIdentifier("1.2.840.113549.1.9.16"); // -- Authority Information Access for DVCS // // id-ad-dvcs OBJECT IDENTIFIER ::= {id-pkix id-ad(48) 4} public static final ASN1ObjectIdentifier id_ad_dvcs = id_pkix.branch("48.4"); // -- Key Purpose for DVCS // // id-kp-dvcs OBJECT IDENTIFIER ::= {id-pkix id-kp(3) 10} public static final ASN1ObjectIdentifier id_kp_dvcs = id_pkix.branch("3.10"); // id-ct-DVCSRequestData OBJECT IDENTIFIER ::= { id-smime ct(1) 7 } // id-ct-DVCSResponseData OBJECT IDENTIFIER ::= { id-smime ct(1) 8 } public static final ASN1ObjectIdentifier id_ct_DVCSRequestData = id_smime.branch("1.7"); public static final ASN1ObjectIdentifier id_ct_DVCSResponseData = id_smime.branch("1.8"); // -- Data validation certificate attribute // // id-aa-dvcs-dvc OBJECT IDENTIFIER ::= { id-smime aa(2) 29 } public static final ASN1ObjectIdentifier id_aa_dvcs_dvc = id_smime.branch("2.29"); } bouncycastle-1.49.orig/src/org/bouncycastle/asn1/dvcs/CertEtcToken.java0000644000175000017500000001162412151250553025503 0ustar ebourgebourgpackage org.bouncycastle.asn1.dvcs; import org.bouncycastle.asn1.ASN1Choice; import org.bouncycastle.asn1.ASN1Encodable; import org.bouncycastle.asn1.ASN1Object; import org.bouncycastle.asn1.ASN1Primitive; import org.bouncycastle.asn1.ASN1Sequence; import org.bouncycastle.asn1.ASN1TaggedObject; import org.bouncycastle.asn1.DERTaggedObject; import org.bouncycastle.asn1.cmp.PKIStatusInfo; import org.bouncycastle.asn1.cms.ContentInfo; import org.bouncycastle.asn1.ess.ESSCertID; import org.bouncycastle.asn1.ocsp.CertID; import org.bouncycastle.asn1.ocsp.CertStatus; import org.bouncycastle.asn1.ocsp.OCSPResponse; import org.bouncycastle.asn1.smime.SMIMECapabilities; import org.bouncycastle.asn1.x509.Certificate; import org.bouncycastle.asn1.x509.CertificateList; import org.bouncycastle.asn1.x509.Extension; /** *
     * CertEtcToken ::= CHOICE {
     *         certificate                  [0] IMPLICIT Certificate ,
     *         esscertid                    [1] ESSCertId ,
     *         pkistatus                    [2] IMPLICIT PKIStatusInfo ,
     *         assertion                    [3] ContentInfo ,
     *         crl                          [4] IMPLICIT CertificateList,
     *         ocspcertstatus               [5] CertStatus,
     *         oscpcertid                   [6] IMPLICIT CertId ,
     *         oscpresponse                 [7] IMPLICIT OCSPResponse,
     *         capabilities                 [8] SMIMECapabilities,
     *         extension                    Extension
     * }
     * 
    */ public class CertEtcToken extends ASN1Object implements ASN1Choice { public static final int TAG_CERTIFICATE = 0; public static final int TAG_ESSCERTID = 1; public static final int TAG_PKISTATUS = 2; public static final int TAG_ASSERTION = 3; public static final int TAG_CRL = 4; public static final int TAG_OCSPCERTSTATUS = 5; public static final int TAG_OCSPCERTID = 6; public static final int TAG_OCSPRESPONSE = 7; public static final int TAG_CAPABILITIES = 8; private static final boolean[] explicit = new boolean[] { false, true, false, true, false, true, false, false, true }; private int tagNo; private ASN1Encodable value; private Extension extension; public CertEtcToken(int tagNo, ASN1Encodable value) { this.tagNo = tagNo; this.value = value; } public CertEtcToken(Extension extension) { this.tagNo = -1; this.extension = extension; } private CertEtcToken(ASN1TaggedObject choice) { this.tagNo = choice.getTagNo(); switch (tagNo) { case TAG_CERTIFICATE: value = Certificate.getInstance(choice, false); break; case TAG_ESSCERTID: value = ESSCertID.getInstance(choice.getObject()); break; case TAG_PKISTATUS: value = PKIStatusInfo.getInstance(choice, false); break; case TAG_ASSERTION: value = ContentInfo.getInstance(choice.getObject()); break; case TAG_CRL: value = CertificateList.getInstance(choice, false); break; case TAG_OCSPCERTSTATUS: value = CertStatus.getInstance(choice.getObject()); break; case TAG_OCSPCERTID: value = CertID.getInstance(choice, false); break; case TAG_OCSPRESPONSE: value = OCSPResponse.getInstance(choice, false); break; case TAG_CAPABILITIES: value = SMIMECapabilities.getInstance(choice.getObject()); break; default: throw new IllegalArgumentException("Unknown tag: " + tagNo); } } public static CertEtcToken getInstance(Object obj) { if (obj instanceof CertEtcToken) { return (CertEtcToken)obj; } else if (obj instanceof ASN1TaggedObject) { return new CertEtcToken((ASN1TaggedObject)obj); } else if (obj != null) { return new CertEtcToken(Extension.getInstance(obj)); } return null; } public ASN1Primitive toASN1Primitive() { if (extension == null) { return new DERTaggedObject(explicit[tagNo], tagNo, value); } else { return extension.toASN1Primitive(); } } public int getTagNo() { return tagNo; } public ASN1Encodable getValue() { return value; } public Extension getExtension() { return extension; } public String toString() { return "CertEtcToken {\n" + value + "}\n"; } public static CertEtcToken[] arrayFromSequence(ASN1Sequence seq) { CertEtcToken[] tmp = new CertEtcToken[seq.size()]; for (int i = 0; i != tmp.length; i++) { tmp[i] = CertEtcToken.getInstance(seq.getObjectAt(i)); } return tmp; } } bouncycastle-1.49.orig/src/org/bouncycastle/asn1/dvcs/package.html0000644000175000017500000000026712123712404024565 0ustar ebourgebourg Support classes useful for encoding and processing Data Validation and Certification Server (DVCS) protocols as described in RFC 3029. bouncycastle-1.49.orig/src/org/bouncycastle/asn1/DERVisibleString.java0000644000175000017500000000574012062243351025332 0ustar ebourgebourgpackage org.bouncycastle.asn1; import java.io.IOException; import org.bouncycastle.util.Arrays; import org.bouncycastle.util.Strings; /** * DER VisibleString object. */ public class DERVisibleString extends ASN1Primitive implements ASN1String { private byte[] string; /** * return a Visible String from the passed in object. * * @exception IllegalArgumentException if the object cannot be converted. */ public static DERVisibleString getInstance( Object obj) { if (obj == null || obj instanceof DERVisibleString) { return (DERVisibleString)obj; } if (obj instanceof byte[]) { try { return (DERVisibleString)fromByteArray((byte[])obj); } catch (Exception e) { throw new IllegalArgumentException("encoding error in getInstance: " + e.toString()); } } throw new IllegalArgumentException("illegal object in getInstance: " + obj.getClass().getName()); } /** * return a Visible String from a tagged object. * * @param obj the tagged object holding the object we want * @param explicit true if the object is meant to be explicitly * tagged false otherwise. * @exception IllegalArgumentException if the tagged object cannot * be converted. */ public static DERVisibleString getInstance( ASN1TaggedObject obj, boolean explicit) { ASN1Primitive o = obj.getObject(); if (explicit || o instanceof DERVisibleString) { return getInstance(o); } else { return new DERVisibleString(ASN1OctetString.getInstance(o).getOctets()); } } /** * basic constructor - byte encoded string. */ DERVisibleString( byte[] string) { this.string = string; } /** * basic constructor */ public DERVisibleString( String string) { this.string = Strings.toByteArray(string); } public String getString() { return Strings.fromByteArray(string); } public String toString() { return getString(); } public byte[] getOctets() { return Arrays.clone(string); } boolean isConstructed() { return false; } int encodedLength() { return 1 + StreamUtil.calculateBodyLength(string.length) + string.length; } void encode( ASN1OutputStream out) throws IOException { out.writeEncoded(BERTags.VISIBLE_STRING, this.string); } boolean asn1Equals( ASN1Primitive o) { if (!(o instanceof DERVisibleString)) { return false; } return Arrays.areEqual(string, ((DERVisibleString)o).string); } public int hashCode() { return Arrays.hashCode(string); } } bouncycastle-1.49.orig/src/org/bouncycastle/asn1/util/0000755000175000017500000000000012152033551022316 5ustar ebourgebourgbouncycastle-1.49.orig/src/org/bouncycastle/asn1/util/ASN1Dump.java0000644000175000017500000003144312151274315024522 0ustar ebourgebourgpackage org.bouncycastle.asn1.util; import java.io.IOException; import java.util.Enumeration; import org.bouncycastle.asn1.ASN1Encodable; import org.bouncycastle.asn1.ASN1Integer; import org.bouncycastle.asn1.ASN1ObjectIdentifier; import org.bouncycastle.asn1.ASN1OctetString; import org.bouncycastle.asn1.ASN1Primitive; import org.bouncycastle.asn1.ASN1Sequence; import org.bouncycastle.asn1.ASN1Set; import org.bouncycastle.asn1.ASN1TaggedObject; import org.bouncycastle.asn1.BERApplicationSpecific; import org.bouncycastle.asn1.BERConstructedOctetString; import org.bouncycastle.asn1.BEROctetString; import org.bouncycastle.asn1.BERSequence; import org.bouncycastle.asn1.BERSet; import org.bouncycastle.asn1.BERTaggedObject; import org.bouncycastle.asn1.BERTags; import org.bouncycastle.asn1.DERApplicationSpecific; import org.bouncycastle.asn1.DERBMPString; import org.bouncycastle.asn1.DERBitString; import org.bouncycastle.asn1.DERBoolean; import org.bouncycastle.asn1.DEREnumerated; import org.bouncycastle.asn1.DERExternal; import org.bouncycastle.asn1.DERGeneralizedTime; import org.bouncycastle.asn1.DERIA5String; import org.bouncycastle.asn1.DERNull; import org.bouncycastle.asn1.DERPrintableString; import org.bouncycastle.asn1.DERSequence; import org.bouncycastle.asn1.DERT61String; import org.bouncycastle.asn1.DERUTCTime; import org.bouncycastle.asn1.DERUTF8String; import org.bouncycastle.asn1.DERVisibleString; import org.bouncycastle.util.encoders.Hex; public class ASN1Dump { private static final String TAB = " "; private static final int SAMPLE_SIZE = 32; /** * dump a DER object as a formatted string with indentation * * @param obj the ASN1Primitive to be dumped out. */ static void _dumpAsString( String indent, boolean verbose, ASN1Primitive obj, StringBuffer buf) { String nl = System.getProperty("line.separator"); if (obj instanceof ASN1Sequence) { Enumeration e = ((ASN1Sequence)obj).getObjects(); String tab = indent + TAB; buf.append(indent); if (obj instanceof BERSequence) { buf.append("BER Sequence"); } else if (obj instanceof DERSequence) { buf.append("DER Sequence"); } else { buf.append("Sequence"); } buf.append(nl); while (e.hasMoreElements()) { Object o = e.nextElement(); if (o == null || o.equals(DERNull.INSTANCE)) { buf.append(tab); buf.append("NULL"); buf.append(nl); } else if (o instanceof ASN1Primitive) { _dumpAsString(tab, verbose, (ASN1Primitive)o, buf); } else { _dumpAsString(tab, verbose, ((ASN1Encodable)o).toASN1Primitive(), buf); } } } else if (obj instanceof ASN1TaggedObject) { String tab = indent + TAB; buf.append(indent); if (obj instanceof BERTaggedObject) { buf.append("BER Tagged ["); } else { buf.append("Tagged ["); } ASN1TaggedObject o = (ASN1TaggedObject)obj; buf.append(Integer.toString(o.getTagNo())); buf.append(']'); if (!o.isExplicit()) { buf.append(" IMPLICIT "); } buf.append(nl); if (o.isEmpty()) { buf.append(tab); buf.append("EMPTY"); buf.append(nl); } else { _dumpAsString(tab, verbose, o.getObject(), buf); } } else if (obj instanceof ASN1Set) { Enumeration e = ((ASN1Set)obj).getObjects(); String tab = indent + TAB; buf.append(indent); if (obj instanceof BERSet) { buf.append("BER Set"); } else { buf.append("DER Set"); } buf.append(nl); while (e.hasMoreElements()) { Object o = e.nextElement(); if (o == null) { buf.append(tab); buf.append("NULL"); buf.append(nl); } else if (o instanceof ASN1Primitive) { _dumpAsString(tab, verbose, (ASN1Primitive)o, buf); } else { _dumpAsString(tab, verbose, ((ASN1Encodable)o).toASN1Primitive(), buf); } } } else if (obj instanceof ASN1OctetString) { ASN1OctetString oct = (ASN1OctetString)obj; if (obj instanceof BEROctetString || obj instanceof BERConstructedOctetString) { buf.append(indent + "BER Constructed Octet String" + "[" + oct.getOctets().length + "] "); } else { buf.append(indent + "DER Octet String" + "[" + oct.getOctets().length + "] "); } if (verbose) { buf.append(dumpBinaryDataAsString(indent, oct.getOctets())); } else { buf.append(nl); } } else if (obj instanceof ASN1ObjectIdentifier) { buf.append(indent + "ObjectIdentifier(" + ((ASN1ObjectIdentifier)obj).getId() + ")" + nl); } else if (obj instanceof DERBoolean) { buf.append(indent + "Boolean(" + ((DERBoolean)obj).isTrue() + ")" + nl); } else if (obj instanceof ASN1Integer) { buf.append(indent + "Integer(" + ((ASN1Integer)obj).getValue() + ")" + nl); } else if (obj instanceof DERBitString) { DERBitString bt = (DERBitString)obj; buf.append(indent + "DER Bit String" + "[" + bt.getBytes().length + ", " + bt.getPadBits() + "] "); if (verbose) { buf.append(dumpBinaryDataAsString(indent, bt.getBytes())); } else { buf.append(nl); } } else if (obj instanceof DERIA5String) { buf.append(indent + "IA5String(" + ((DERIA5String)obj).getString() + ") " + nl); } else if (obj instanceof DERUTF8String) { buf.append(indent + "UTF8String(" + ((DERUTF8String)obj).getString() + ") " + nl); } else if (obj instanceof DERPrintableString) { buf.append(indent + "PrintableString(" + ((DERPrintableString)obj).getString() + ") " + nl); } else if (obj instanceof DERVisibleString) { buf.append(indent + "VisibleString(" + ((DERVisibleString)obj).getString() + ") " + nl); } else if (obj instanceof DERBMPString) { buf.append(indent + "BMPString(" + ((DERBMPString)obj).getString() + ") " + nl); } else if (obj instanceof DERT61String) { buf.append(indent + "T61String(" + ((DERT61String)obj).getString() + ") " + nl); } else if (obj instanceof DERUTCTime) { buf.append(indent + "UTCTime(" + ((DERUTCTime)obj).getTime() + ") " + nl); } else if (obj instanceof DERGeneralizedTime) { buf.append(indent + "GeneralizedTime(" + ((DERGeneralizedTime)obj).getTime() + ") " + nl); } else if (obj instanceof BERApplicationSpecific) { buf.append(outputApplicationSpecific("BER", indent, verbose, obj, nl)); } else if (obj instanceof DERApplicationSpecific) { buf.append(outputApplicationSpecific("DER", indent, verbose, obj, nl)); } else if (obj instanceof DEREnumerated) { DEREnumerated en = (DEREnumerated) obj; buf.append(indent + "DER Enumerated(" + en.getValue() + ")" + nl); } else if (obj instanceof DERExternal) { DERExternal ext = (DERExternal) obj; buf.append(indent + "External " + nl); String tab = indent + TAB; if (ext.getDirectReference() != null) { buf.append(tab + "Direct Reference: " + ext.getDirectReference().getId() + nl); } if (ext.getIndirectReference() != null) { buf.append(tab + "Indirect Reference: " + ext.getIndirectReference().toString() + nl); } if (ext.getDataValueDescriptor() != null) { _dumpAsString(tab, verbose, ext.getDataValueDescriptor(), buf); } buf.append(tab + "Encoding: " + ext.getEncoding() + nl); _dumpAsString(tab, verbose, ext.getExternalContent(), buf); } else { buf.append(indent + obj.toString() + nl); } } private static String outputApplicationSpecific(String type, String indent, boolean verbose, ASN1Primitive obj, String nl) { DERApplicationSpecific app = (DERApplicationSpecific)obj; StringBuffer buf = new StringBuffer(); if (app.isConstructed()) { try { ASN1Sequence s = ASN1Sequence.getInstance(app.getObject(BERTags.SEQUENCE)); buf.append(indent + type + " ApplicationSpecific[" + app.getApplicationTag() + "]" + nl); for (Enumeration e = s.getObjects(); e.hasMoreElements();) { _dumpAsString(indent + TAB, verbose, (ASN1Primitive)e.nextElement(), buf); } } catch (IOException e) { buf.append(e); } return buf.toString(); } return indent + type + " ApplicationSpecific[" + app.getApplicationTag() + "] (" + new String(Hex.encode(app.getContents())) + ")" + nl; } /** * dump out a DER object as a formatted string, in non-verbose mode. * * @param obj the ASN1Primitive to be dumped out. * @return the resulting string. */ public static String dumpAsString( Object obj) { return dumpAsString(obj, false); } /** * Dump out the object as a string. * * @param obj the object to be dumped * @param verbose if true, dump out the contents of octet and bit strings. * @return the resulting string. */ public static String dumpAsString( Object obj, boolean verbose) { StringBuffer buf = new StringBuffer(); if (obj instanceof ASN1Primitive) { _dumpAsString("", verbose, (ASN1Primitive)obj, buf); } else if (obj instanceof ASN1Encodable) { _dumpAsString("", verbose, ((ASN1Encodable)obj).toASN1Primitive(), buf); } else { return "unknown object type " + obj.toString(); } return buf.toString(); } private static String dumpBinaryDataAsString(String indent, byte[] bytes) { String nl = System.getProperty("line.separator"); StringBuffer buf = new StringBuffer(); indent += TAB; buf.append(nl); for (int i = 0; i < bytes.length; i += SAMPLE_SIZE) { if (bytes.length - i > SAMPLE_SIZE) { buf.append(indent); buf.append(new String(Hex.encode(bytes, i, SAMPLE_SIZE))); buf.append(TAB); buf.append(calculateAscString(bytes, i, SAMPLE_SIZE)); buf.append(nl); } else { buf.append(indent); buf.append(new String(Hex.encode(bytes, i, bytes.length - i))); for (int j = bytes.length - i; j != SAMPLE_SIZE; j++) { buf.append(" "); } buf.append(TAB); buf.append(calculateAscString(bytes, i, bytes.length - i)); buf.append(nl); } } return buf.toString(); } private static String calculateAscString(byte[] bytes, int off, int len) { StringBuffer buf = new StringBuffer(); for (int i = off; i != off + len; i++) { if (bytes[i] >= ' ' && bytes[i] <= '~') { buf.append((char)bytes[i]); } } return buf.toString(); } } bouncycastle-1.49.orig/src/org/bouncycastle/asn1/util/Dump.java0000644000175000017500000000077611624622715024111 0ustar ebourgebourgpackage org.bouncycastle.asn1.util; import java.io.FileInputStream; import org.bouncycastle.asn1.ASN1InputStream; public class Dump { public static void main( String args[]) throws Exception { FileInputStream fIn = new FileInputStream(args[0]); ASN1InputStream bIn = new ASN1InputStream(fIn); Object obj = null; while ((obj = bIn.readObject()) != null) { System.out.println(ASN1Dump.dumpAsString(obj)); } } } bouncycastle-1.49.orig/src/org/bouncycastle/asn1/util/DERDump.java0000644000175000017500000000157011624652340024432 0ustar ebourgebourgpackage org.bouncycastle.asn1.util; import org.bouncycastle.asn1.ASN1Encodable; import org.bouncycastle.asn1.ASN1Primitive; /** * @deprecated use ASN1Dump. */ public class DERDump extends ASN1Dump { /** * dump out a DER object as a formatted string * * @param obj the ASN1Primitive to be dumped out. */ public static String dumpAsString( ASN1Primitive obj) { StringBuffer buf = new StringBuffer(); _dumpAsString("", false, obj, buf); return buf.toString(); } /** * dump out a DER object as a formatted string * * @param obj the ASN1Primitive to be dumped out. */ public static String dumpAsString( ASN1Encodable obj) { StringBuffer buf = new StringBuffer(); _dumpAsString("", false, obj.toASN1Primitive(), buf); return buf.toString(); } } bouncycastle-1.49.orig/src/org/bouncycastle/asn1/util/package.html0000644000175000017500000000010710262753175024610 0ustar ebourgebourg An ASN.1 dump utility. bouncycastle-1.49.orig/src/org/bouncycastle/asn1/ASN1TaggedObjectParser.java0000644000175000017500000000043411624616434026341 0ustar ebourgebourgpackage org.bouncycastle.asn1; import java.io.IOException; public interface ASN1TaggedObjectParser extends ASN1Encodable, InMemoryRepresentable { public int getTagNo(); public ASN1Encodable getObjectParser(int tag, boolean isExplicit) throws IOException; } bouncycastle-1.49.orig/src/org/bouncycastle/asn1/DERT61String.java0000644000175000017500000000651612135375171024320 0ustar ebourgebourgpackage org.bouncycastle.asn1; import java.io.IOException; import org.bouncycastle.util.Arrays; import org.bouncycastle.util.Strings; /** * DER T61String (also the teletex string), try not to use this if you don't need to. The standard support the encoding for * this has been withdrawn. */ public class DERT61String extends ASN1Primitive implements ASN1String { private byte[] string; /** * return a T61 string from the passed in object. * * @exception IllegalArgumentException if the object cannot be converted. */ public static DERT61String getInstance( Object obj) { if (obj == null || obj instanceof DERT61String) { return (DERT61String)obj; } if (obj instanceof byte[]) { try { return (DERT61String)fromByteArray((byte[])obj); } catch (Exception e) { throw new IllegalArgumentException("encoding error in getInstance: " + e.toString()); } } throw new IllegalArgumentException("illegal object in getInstance: " + obj.getClass().getName()); } /** * return an T61 String from a tagged object. * * @param obj the tagged object holding the object we want * @param explicit true if the object is meant to be explicitly * tagged false otherwise. * @exception IllegalArgumentException if the tagged object cannot * be converted. */ public static DERT61String getInstance( ASN1TaggedObject obj, boolean explicit) { ASN1Primitive o = obj.getObject(); if (explicit || o instanceof DERT61String) { return getInstance(o); } else { return new DERT61String(ASN1OctetString.getInstance(o).getOctets()); } } /** * basic constructor - string encoded as a sequence of bytes. */ public DERT61String( byte[] string) { this.string = string; } /** * basic constructor - with string 8 bit assumed. */ public DERT61String( String string) { this(Strings.toByteArray(string)); } /** * Decode the encoded string and return it, 8 bit encoding assumed. * @return the decoded String */ public String getString() { return Strings.fromByteArray(string); } public String toString() { return getString(); } boolean isConstructed() { return false; } int encodedLength() { return 1 + StreamUtil.calculateBodyLength(string.length) + string.length; } void encode( ASN1OutputStream out) throws IOException { out.writeEncoded(BERTags.T61_STRING, string); } /** * Return the encoded string as a byte array. * @return the actual bytes making up the encoded body of the T61 string. */ public byte[] getOctets() { return Arrays.clone(string); } boolean asn1Equals( ASN1Primitive o) { if (!(o instanceof DERT61String)) { return false; } return Arrays.areEqual(string, ((DERT61String)o).string); } public int hashCode() { return Arrays.hashCode(string); } } bouncycastle-1.49.orig/src/org/bouncycastle/asn1/InMemoryRepresentable.java0000644000175000017500000000025011624614576026473 0ustar ebourgebourgpackage org.bouncycastle.asn1; import java.io.IOException; public interface InMemoryRepresentable { ASN1Primitive getLoadedObject() throws IOException; } bouncycastle-1.49.orig/src/org/bouncycastle/asn1/StreamUtil.java0000644000175000017500000000511212150600262024271 0ustar ebourgebourgpackage org.bouncycastle.asn1; import java.io.ByteArrayInputStream; import java.io.FileInputStream; import java.io.IOException; import java.io.InputStream; import java.nio.channels.FileChannel; class StreamUtil { private static final long MAX_MEMORY = Runtime.getRuntime().maxMemory(); /** * Find out possible longest length... * * @param in input stream of interest * @return length calculation or MAX_VALUE. */ static int findLimit(InputStream in) { if (in instanceof LimitedInputStream) { return ((LimitedInputStream)in).getRemaining(); } else if (in instanceof ASN1InputStream) { return ((ASN1InputStream)in).getLimit(); } else if (in instanceof ByteArrayInputStream) { return ((ByteArrayInputStream)in).available(); } else if (in instanceof FileInputStream) { try { FileChannel channel = ((FileInputStream)in).getChannel(); long size = (channel != null) ? channel.size() : Integer.MAX_VALUE; if (size < Integer.MAX_VALUE) { return (int)size; } } catch (IOException e) { // ignore - they'll find out soon enough! } } if (MAX_MEMORY > Integer.MAX_VALUE) { return Integer.MAX_VALUE; } return (int)MAX_MEMORY; } static int calculateBodyLength( int length) { int count = 1; if (length > 127) { int size = 1; int val = length; while ((val >>>= 8) != 0) { size++; } for (int i = (size - 1) * 8; i >= 0; i -= 8) { count++; } } return count; } static int calculateTagLength(int tagNo) throws IOException { int length = 1; if (tagNo >= 31) { if (tagNo < 128) { length++; } else { byte[] stack = new byte[5]; int pos = stack.length; stack[--pos] = (byte)(tagNo & 0x7F); do { tagNo >>= 7; stack[--pos] = (byte)(tagNo & 0x7F | 0x80); } while (tagNo > 127); length += stack.length - pos; } } return length; } } bouncycastle-1.49.orig/src/org/bouncycastle/asn1/DERNumericString.java0000644000175000017500000001041412062243213025326 0ustar ebourgebourgpackage org.bouncycastle.asn1; import java.io.IOException; import org.bouncycastle.util.Arrays; import org.bouncycastle.util.Strings; /** * DER NumericString object - this is an ascii string of characters {0,1,2,3,4,5,6,7,8,9, }. */ public class DERNumericString extends ASN1Primitive implements ASN1String { private byte[] string; /** * return a Numeric string from the passed in object * * @exception IllegalArgumentException if the object cannot be converted. */ public static DERNumericString getInstance( Object obj) { if (obj == null || obj instanceof DERNumericString) { return (DERNumericString)obj; } if (obj instanceof byte[]) { try { return (DERNumericString)fromByteArray((byte[])obj); } catch (Exception e) { throw new IllegalArgumentException("encoding error in getInstance: " + e.toString()); } } throw new IllegalArgumentException("illegal object in getInstance: " + obj.getClass().getName()); } /** * return an Numeric String from a tagged object. * * @param obj the tagged object holding the object we want * @param explicit true if the object is meant to be explicitly * tagged false otherwise. * @exception IllegalArgumentException if the tagged object cannot * be converted. */ public static DERNumericString getInstance( ASN1TaggedObject obj, boolean explicit) { ASN1Primitive o = obj.getObject(); if (explicit || o instanceof DERNumericString) { return getInstance(o); } else { return new DERNumericString(ASN1OctetString.getInstance(o).getOctets()); } } /** * basic constructor - with bytes. */ DERNumericString( byte[] string) { this.string = string; } /** * basic constructor - without validation.. */ public DERNumericString( String string) { this(string, false); } /** * Constructor with optional validation. * * @param string the base string to wrap. * @param validate whether or not to check the string. * @throws IllegalArgumentException if validate is true and the string * contains characters that should not be in a NumericString. */ public DERNumericString( String string, boolean validate) { if (validate && !isNumericString(string)) { throw new IllegalArgumentException("string contains illegal characters"); } this.string = Strings.toByteArray(string); } public String getString() { return Strings.fromByteArray(string); } public String toString() { return getString(); } public byte[] getOctets() { return Arrays.clone(string); } boolean isConstructed() { return false; } int encodedLength() { return 1 + StreamUtil.calculateBodyLength(string.length) + string.length; } void encode( ASN1OutputStream out) throws IOException { out.writeEncoded(BERTags.NUMERIC_STRING, string); } public int hashCode() { return Arrays.hashCode(string); } boolean asn1Equals( ASN1Primitive o) { if (!(o instanceof DERNumericString)) { return false; } DERNumericString s = (DERNumericString)o; return Arrays.areEqual(string, s.string); } /** * Return true if the string can be represented as a NumericString ('0'..'9', ' ') * * @param str string to validate. * @return true if numeric, fale otherwise. */ public static boolean isNumericString( String str) { for (int i = str.length() - 1; i >= 0; i--) { char ch = str.charAt(i); if (ch > 0x007f) { return false; } if (('0' <= ch && ch <= '9') || ch == ' ') { continue; } return false; } return true; } } bouncycastle-1.49.orig/src/org/bouncycastle/asn1/misc/0000755000175000017500000000000012152033551022274 5ustar ebourgebourgbouncycastle-1.49.orig/src/org/bouncycastle/asn1/misc/MiscObjectIdentifiers.java0000644000175000017500000000427111624622714027363 0ustar ebourgebourgpackage org.bouncycastle.asn1.misc; import org.bouncycastle.asn1.ASN1ObjectIdentifier; public interface MiscObjectIdentifiers { // // Netscape // iso/itu(2) joint-assign(16) us(840) uscompany(1) netscape(113730) cert-extensions(1) } // static final ASN1ObjectIdentifier netscape = new ASN1ObjectIdentifier("2.16.840.1.113730.1"); static final ASN1ObjectIdentifier netscapeCertType = netscape.branch("1"); static final ASN1ObjectIdentifier netscapeBaseURL = netscape.branch("2"); static final ASN1ObjectIdentifier netscapeRevocationURL = netscape.branch("3"); static final ASN1ObjectIdentifier netscapeCARevocationURL = netscape.branch("4"); static final ASN1ObjectIdentifier netscapeRenewalURL = netscape.branch("7"); static final ASN1ObjectIdentifier netscapeCApolicyURL = netscape.branch("8"); static final ASN1ObjectIdentifier netscapeSSLServerName = netscape.branch("12"); static final ASN1ObjectIdentifier netscapeCertComment = netscape.branch("13"); // // Verisign // iso/itu(2) joint-assign(16) us(840) uscompany(1) verisign(113733) cert-extensions(1) } // static final ASN1ObjectIdentifier verisign = new ASN1ObjectIdentifier("2.16.840.1.113733.1"); // // CZAG - country, zip, age, and gender // static final ASN1ObjectIdentifier verisignCzagExtension = verisign.branch("6.3"); // D&B D-U-N-S number static final ASN1ObjectIdentifier verisignDnbDunsNumber = verisign.branch("6.15"); // // Novell // iso/itu(2) country(16) us(840) organization(1) novell(113719) // static final ASN1ObjectIdentifier novell = new ASN1ObjectIdentifier("2.16.840.1.113719"); static final ASN1ObjectIdentifier novellSecurityAttribs = novell.branch("1.9.4.1"); // // Entrust // iso(1) member-body(16) us(840) nortelnetworks(113533) entrust(7) // static final ASN1ObjectIdentifier entrust = new ASN1ObjectIdentifier("1.2.840.113533.7"); static final ASN1ObjectIdentifier entrustVersionExtension = entrust.branch("65.0"); } bouncycastle-1.49.orig/src/org/bouncycastle/asn1/misc/IDEACBCPar.java0000644000175000017500000000321611725271614024627 0ustar ebourgebourgpackage org.bouncycastle.asn1.misc; import org.bouncycastle.asn1.ASN1EncodableVector; import org.bouncycastle.asn1.ASN1Object; import org.bouncycastle.asn1.ASN1OctetString; import org.bouncycastle.asn1.ASN1Primitive; import org.bouncycastle.asn1.ASN1Sequence; import org.bouncycastle.asn1.DEROctetString; import org.bouncycastle.asn1.DERSequence; public class IDEACBCPar extends ASN1Object { ASN1OctetString iv; public static IDEACBCPar getInstance( Object o) { if (o instanceof IDEACBCPar) { return (IDEACBCPar)o; } else if (o != null) { return new IDEACBCPar(ASN1Sequence.getInstance(o)); } return null; } public IDEACBCPar( byte[] iv) { this.iv = new DEROctetString(iv); } public IDEACBCPar( ASN1Sequence seq) { if (seq.size() == 1) { iv = (ASN1OctetString)seq.getObjectAt(0); } else { iv = null; } } public byte[] getIV() { if (iv != null) { return iv.getOctets(); } else { return null; } } /** * Produce an object suitable for an ASN1OutputStream. *
         * IDEA-CBCPar ::= SEQUENCE {
         *                      iv    OCTET STRING OPTIONAL -- exactly 8 octets
         *                  }
         * 
    */ public ASN1Primitive toASN1Primitive() { ASN1EncodableVector v = new ASN1EncodableVector(); if (iv != null) { v.add(iv); } return new DERSequence(v); } } bouncycastle-1.49.orig/src/org/bouncycastle/asn1/misc/VerisignCzagExtension.java0000644000175000017500000000054011624652565027445 0ustar ebourgebourgpackage org.bouncycastle.asn1.misc; import org.bouncycastle.asn1.DERIA5String; public class VerisignCzagExtension extends DERIA5String { public VerisignCzagExtension( DERIA5String str) { super(str.getString()); } public String toString() { return "VerisignCzagExtension: " + this.getString(); } } bouncycastle-1.49.orig/src/org/bouncycastle/asn1/misc/NetscapeCertType.java0000644000175000017500000000316511624652552026401 0ustar ebourgebourgpackage org.bouncycastle.asn1.misc; import org.bouncycastle.asn1.DERBitString; /** * The NetscapeCertType object. *
     *    NetscapeCertType ::= BIT STRING {
     *         SSLClient               (0),
     *         SSLServer               (1),
     *         S/MIME                  (2),
     *         Object Signing          (3),
     *         Reserved                (4),
     *         SSL CA                  (5),
     *         S/MIME CA               (6),
     *         Object Signing CA       (7) }
     * 
    */ public class NetscapeCertType extends DERBitString { public static final int sslClient = (1 << 7); public static final int sslServer = (1 << 6); public static final int smime = (1 << 5); public static final int objectSigning = (1 << 4); public static final int reserved = (1 << 3); public static final int sslCA = (1 << 2); public static final int smimeCA = (1 << 1); public static final int objectSigningCA = (1 << 0); /** * Basic constructor. * * @param usage - the bitwise OR of the Key Usage flags giving the * allowed uses for the key. * e.g. (X509NetscapeCertType.sslCA | X509NetscapeCertType.smimeCA) */ public NetscapeCertType( int usage) { super(getBytes(usage), getPadBits(usage)); } public NetscapeCertType( DERBitString usage) { super(usage.getBytes(), usage.getPadBits()); } public String toString() { return "NetscapeCertType: 0x" + Integer.toHexString(data[0] & 0xff); } } bouncycastle-1.49.orig/src/org/bouncycastle/asn1/misc/CAST5CBCParameters.java0000644000175000017500000000367111725271554026335 0ustar ebourgebourgpackage org.bouncycastle.asn1.misc; import org.bouncycastle.asn1.ASN1EncodableVector; import org.bouncycastle.asn1.ASN1Integer; import org.bouncycastle.asn1.ASN1Object; import org.bouncycastle.asn1.ASN1OctetString; import org.bouncycastle.asn1.ASN1Primitive; import org.bouncycastle.asn1.ASN1Sequence; import org.bouncycastle.asn1.DEROctetString; import org.bouncycastle.asn1.DERSequence; public class CAST5CBCParameters extends ASN1Object { ASN1Integer keyLength; ASN1OctetString iv; public static CAST5CBCParameters getInstance( Object o) { if (o instanceof CAST5CBCParameters) { return (CAST5CBCParameters)o; } else if (o != null) { return new CAST5CBCParameters(ASN1Sequence.getInstance(o)); } return null; } public CAST5CBCParameters( byte[] iv, int keyLength) { this.iv = new DEROctetString(iv); this.keyLength = new ASN1Integer(keyLength); } public CAST5CBCParameters( ASN1Sequence seq) { iv = (ASN1OctetString)seq.getObjectAt(0); keyLength = (ASN1Integer)seq.getObjectAt(1); } public byte[] getIV() { return iv.getOctets(); } public int getKeyLength() { return keyLength.getValue().intValue(); } /** * Produce an object suitable for an ASN1OutputStream. *
         * cast5CBCParameters ::= SEQUENCE {
         *                           iv         OCTET STRING DEFAULT 0,
         *                                  -- Initialization vector
         *                           keyLength  INTEGER
         *                                  -- Key length, in bits
         *                      }
         * 
    */ public ASN1Primitive toASN1Primitive() { ASN1EncodableVector v = new ASN1EncodableVector(); v.add(iv); v.add(keyLength); return new DERSequence(v); } } bouncycastle-1.49.orig/src/org/bouncycastle/asn1/misc/NetscapeRevocationURL.java0000644000175000017500000000054011624652552027330 0ustar ebourgebourgpackage org.bouncycastle.asn1.misc; import org.bouncycastle.asn1.DERIA5String; public class NetscapeRevocationURL extends DERIA5String { public NetscapeRevocationURL( DERIA5String str) { super(str.getString()); } public String toString() { return "NetscapeRevocationURL: " + this.getString(); } } bouncycastle-1.49.orig/src/org/bouncycastle/asn1/misc/package.html0000644000175000017500000000013610262753174024567 0ustar ebourgebourg Miscellaneous object identifiers and objects. bouncycastle-1.49.orig/src/org/bouncycastle/asn1/BERTags.java0000644000175000017500000000321411624615370023443 0ustar ebourgebourgpackage org.bouncycastle.asn1; public interface BERTags { public static final int BOOLEAN = 0x01; public static final int INTEGER = 0x02; public static final int BIT_STRING = 0x03; public static final int OCTET_STRING = 0x04; public static final int NULL = 0x05; public static final int OBJECT_IDENTIFIER = 0x06; public static final int EXTERNAL = 0x08; public static final int ENUMERATED = 0x0a; public static final int SEQUENCE = 0x10; public static final int SEQUENCE_OF = 0x10; // for completeness public static final int SET = 0x11; public static final int SET_OF = 0x11; // for completeness public static final int NUMERIC_STRING = 0x12; public static final int PRINTABLE_STRING = 0x13; public static final int T61_STRING = 0x14; public static final int VIDEOTEX_STRING = 0x15; public static final int IA5_STRING = 0x16; public static final int UTC_TIME = 0x17; public static final int GENERALIZED_TIME = 0x18; public static final int GRAPHIC_STRING = 0x19; public static final int VISIBLE_STRING = 0x1a; public static final int GENERAL_STRING = 0x1b; public static final int UNIVERSAL_STRING = 0x1c; public static final int BMP_STRING = 0x1e; public static final int UTF8_STRING = 0x0c; public static final int CONSTRUCTED = 0x20; public static final int APPLICATION = 0x40; public static final int TAGGED = 0x80; } bouncycastle-1.49.orig/src/org/bouncycastle/asn1/DERPrintableString.java0000644000175000017500000001143112062243165025652 0ustar ebourgebourgpackage org.bouncycastle.asn1; import java.io.IOException; import org.bouncycastle.util.Arrays; import org.bouncycastle.util.Strings; /** * DER PrintableString object. */ public class DERPrintableString extends ASN1Primitive implements ASN1String { private byte[] string; /** * return a printable string from the passed in object. * * @exception IllegalArgumentException if the object cannot be converted. */ public static DERPrintableString getInstance( Object obj) { if (obj == null || obj instanceof DERPrintableString) { return (DERPrintableString)obj; } if (obj instanceof byte[]) { try { return (DERPrintableString)fromByteArray((byte[])obj); } catch (Exception e) { throw new IllegalArgumentException("encoding error in getInstance: " + e.toString()); } } throw new IllegalArgumentException("illegal object in getInstance: " + obj.getClass().getName()); } /** * return a Printable String from a tagged object. * * @param obj the tagged object holding the object we want * @param explicit true if the object is meant to be explicitly * tagged false otherwise. * @exception IllegalArgumentException if the tagged object cannot * be converted. */ public static DERPrintableString getInstance( ASN1TaggedObject obj, boolean explicit) { ASN1Primitive o = obj.getObject(); if (explicit || o instanceof DERPrintableString) { return getInstance(o); } else { return new DERPrintableString(ASN1OctetString.getInstance(o).getOctets()); } } /** * basic constructor - byte encoded string. */ DERPrintableString( byte[] string) { this.string = string; } /** * basic constructor - this does not validate the string */ public DERPrintableString( String string) { this(string, false); } /** * Constructor with optional validation. * * @param string the base string to wrap. * @param validate whether or not to check the string. * @throws IllegalArgumentException if validate is true and the string * contains characters that should not be in a PrintableString. */ public DERPrintableString( String string, boolean validate) { if (validate && !isPrintableString(string)) { throw new IllegalArgumentException("string contains illegal characters"); } this.string = Strings.toByteArray(string); } public String getString() { return Strings.fromByteArray(string); } public byte[] getOctets() { return Arrays.clone(string); } boolean isConstructed() { return false; } int encodedLength() { return 1 + StreamUtil.calculateBodyLength(string.length) + string.length; } void encode( ASN1OutputStream out) throws IOException { out.writeEncoded(BERTags.PRINTABLE_STRING, string); } public int hashCode() { return Arrays.hashCode(string); } boolean asn1Equals( ASN1Primitive o) { if (!(o instanceof DERPrintableString)) { return false; } DERPrintableString s = (DERPrintableString)o; return Arrays.areEqual(string, s.string); } public String toString() { return getString(); } /** * return true if the passed in String can be represented without * loss as a PrintableString, false otherwise. * * @return true if in printable set, false otherwise. */ public static boolean isPrintableString( String str) { for (int i = str.length() - 1; i >= 0; i--) { char ch = str.charAt(i); if (ch > 0x007f) { return false; } if ('a' <= ch && ch <= 'z') { continue; } if ('A' <= ch && ch <= 'Z') { continue; } if ('0' <= ch && ch <= '9') { continue; } switch (ch) { case ' ': case '\'': case '(': case ')': case '+': case '-': case '.': case ':': case '=': case '?': case '/': case ',': continue; } return false; } return true; } } bouncycastle-1.49.orig/src/org/bouncycastle/asn1/ASN1UTCTime.java0000644000175000017500000000046611703701575024120 0ustar ebourgebourgpackage org.bouncycastle.asn1; import java.util.Date; public class ASN1UTCTime extends DERUTCTime { ASN1UTCTime(byte[] bytes) { super(bytes); } public ASN1UTCTime(Date time) { super(time); } public ASN1UTCTime(String time) { super(time); } } bouncycastle-1.49.orig/src/org/bouncycastle/asn1/DEREnumerated.java0000644000175000017500000000712112062243555024640 0ustar ebourgebourgpackage org.bouncycastle.asn1; import java.io.IOException; import java.math.BigInteger; import org.bouncycastle.util.Arrays; public class DEREnumerated extends ASN1Primitive { byte[] bytes; /** * return an integer from the passed in object * * @exception IllegalArgumentException if the object cannot be converted. */ public static ASN1Enumerated getInstance( Object obj) { if (obj == null || obj instanceof ASN1Enumerated) { return (ASN1Enumerated)obj; } if (obj instanceof DEREnumerated) { return new ASN1Enumerated(((DEREnumerated)obj).getValue()); } if (obj instanceof byte[]) { try { return (ASN1Enumerated)fromByteArray((byte[])obj); } catch (Exception e) { throw new IllegalArgumentException("encoding error in getInstance: " + e.toString()); } } throw new IllegalArgumentException("illegal object in getInstance: " + obj.getClass().getName()); } /** * return an Enumerated from a tagged object. * * @param obj the tagged object holding the object we want * @param explicit true if the object is meant to be explicitly * tagged false otherwise. * @exception IllegalArgumentException if the tagged object cannot * be converted. */ public static DEREnumerated getInstance( ASN1TaggedObject obj, boolean explicit) { ASN1Primitive o = obj.getObject(); if (explicit || o instanceof DEREnumerated) { return getInstance(o); } else { return fromOctetString(((ASN1OctetString)o).getOctets()); } } public DEREnumerated( int value) { bytes = BigInteger.valueOf(value).toByteArray(); } public DEREnumerated( BigInteger value) { bytes = value.toByteArray(); } public DEREnumerated( byte[] bytes) { this.bytes = bytes; } public BigInteger getValue() { return new BigInteger(bytes); } boolean isConstructed() { return false; } int encodedLength() { return 1 + StreamUtil.calculateBodyLength(bytes.length) + bytes.length; } void encode( ASN1OutputStream out) throws IOException { out.writeEncoded(BERTags.ENUMERATED, bytes); } boolean asn1Equals( ASN1Primitive o) { if (!(o instanceof DEREnumerated)) { return false; } DEREnumerated other = (DEREnumerated)o; return Arrays.areEqual(this.bytes, other.bytes); } public int hashCode() { return Arrays.hashCode(bytes); } private static ASN1Enumerated[] cache = new ASN1Enumerated[12]; static ASN1Enumerated fromOctetString(byte[] enc) { if (enc.length > 1) { return new ASN1Enumerated(Arrays.clone(enc)); } if (enc.length == 0) { throw new IllegalArgumentException("ENUMERATED has zero length"); } int value = enc[0] & 0xff; if (value >= cache.length) { return new ASN1Enumerated(Arrays.clone(enc)); } ASN1Enumerated possibleMatch = cache[value]; if (possibleMatch == null) { possibleMatch = cache[value] = new ASN1Enumerated(Arrays.clone(enc)); } return possibleMatch; } } bouncycastle-1.49.orig/src/org/bouncycastle/asn1/isismtt/0000755000175000017500000000000012152033551023035 5ustar ebourgebourgbouncycastle-1.49.orig/src/org/bouncycastle/asn1/isismtt/ocsp/0000755000175000017500000000000012152033551024001 5ustar ebourgebourgbouncycastle-1.49.orig/src/org/bouncycastle/asn1/isismtt/ocsp/CertHash.java0000644000175000017500000000726111624645077026372 0ustar ebourgebourgpackage org.bouncycastle.asn1.isismtt.ocsp; import org.bouncycastle.asn1.ASN1EncodableVector; import org.bouncycastle.asn1.ASN1Object; import org.bouncycastle.asn1.ASN1Primitive; import org.bouncycastle.asn1.ASN1Sequence; import org.bouncycastle.asn1.DEROctetString; import org.bouncycastle.asn1.DERSequence; import org.bouncycastle.asn1.x509.AlgorithmIdentifier; /** * ISIS-MTT PROFILE: The responder may include this extension in a response to * send the hash of the requested certificate to the responder. This hash is * cryptographically bound to the certificate and serves as evidence that the * certificate is known to the responder (i.e. it has been issued and is present * in the directory). Hence, this extension is a means to provide a positive * statement of availability as described in T8.[8]. As explained in T13.[1], * clients may rely on this information to be able to validate signatures after * the expiry of the corresponding certificate. Hence, clients MUST support this * extension. If a positive statement of availability is to be delivered, this * extension syntax and OID MUST be used. *

    *

    *

     *     CertHash ::= SEQUENCE {
     *       hashAlgorithm AlgorithmIdentifier,
     *       certificateHash OCTET STRING
     *     }
     * 
    */ public class CertHash extends ASN1Object { private AlgorithmIdentifier hashAlgorithm; private byte[] certificateHash; public static CertHash getInstance(Object obj) { if (obj == null || obj instanceof CertHash) { return (CertHash)obj; } if (obj instanceof ASN1Sequence) { return new CertHash((ASN1Sequence)obj); } throw new IllegalArgumentException("illegal object in getInstance: " + obj.getClass().getName()); } /** * Constructor from ASN1Sequence. *

    * The sequence is of type CertHash: *

    *

         *     CertHash ::= SEQUENCE {
         *       hashAlgorithm AlgorithmIdentifier,
         *       certificateHash OCTET STRING
         *     }
         * 
    * * @param seq The ASN.1 sequence. */ private CertHash(ASN1Sequence seq) { if (seq.size() != 2) { throw new IllegalArgumentException("Bad sequence size: " + seq.size()); } hashAlgorithm = AlgorithmIdentifier.getInstance(seq.getObjectAt(0)); certificateHash = DEROctetString.getInstance(seq.getObjectAt(1)).getOctets(); } /** * Constructor from a given details. * * @param hashAlgorithm The hash algorithm identifier. * @param certificateHash The hash of the whole DER encoding of the certificate. */ public CertHash(AlgorithmIdentifier hashAlgorithm, byte[] certificateHash) { this.hashAlgorithm = hashAlgorithm; this.certificateHash = new byte[certificateHash.length]; System.arraycopy(certificateHash, 0, this.certificateHash, 0, certificateHash.length); } public AlgorithmIdentifier getHashAlgorithm() { return hashAlgorithm; } public byte[] getCertificateHash() { return certificateHash; } /** * Produce an object suitable for an ASN1OutputStream. *

    * Returns: *

    *

         *     CertHash ::= SEQUENCE {
         *       hashAlgorithm AlgorithmIdentifier,
         *       certificateHash OCTET STRING
         *     }
         * 
    * * @return a DERObject */ public ASN1Primitive toASN1Primitive() { ASN1EncodableVector vec = new ASN1EncodableVector(); vec.add(hashAlgorithm); vec.add(new DEROctetString(certificateHash)); return new DERSequence(vec); } } bouncycastle-1.49.orig/src/org/bouncycastle/asn1/isismtt/ocsp/RequestedCertificate.java0000644000175000017500000001310011736736613030763 0ustar ebourgebourgpackage org.bouncycastle.asn1.isismtt.ocsp; import java.io.IOException; import org.bouncycastle.asn1.ASN1Choice; import org.bouncycastle.asn1.ASN1Object; import org.bouncycastle.asn1.ASN1OctetString; import org.bouncycastle.asn1.ASN1Primitive; import org.bouncycastle.asn1.ASN1Sequence; import org.bouncycastle.asn1.ASN1TaggedObject; import org.bouncycastle.asn1.DEROctetString; import org.bouncycastle.asn1.DERTaggedObject; import org.bouncycastle.asn1.x509.Certificate; /** * ISIS-MTT-Optional: The certificate requested by the client by inserting the * RetrieveIfAllowed extension in the request, will be returned in this * extension. *

    * ISIS-MTT-SigG: The signature act allows publishing certificates only then, * when the certificate owner gives his explicit permission. Accordingly, there * may be �nondownloadable� certificates, about which the responder must provide * status information, but MUST NOT include them in the response. Clients may * get therefore the following three kind of answers on a single request * including the RetrieveIfAllowed extension: *

      *
    • a) the responder supports the extension and is allowed to publish the * certificate: RequestedCertificate returned including the requested * certificate *
    • b) the responder supports the extension but is NOT allowed to publish * the certificate: RequestedCertificate returned including an empty OCTET * STRING *
    • c) the responder does not support the extension: RequestedCertificate is * not included in the response *
    * Clients requesting RetrieveIfAllowed MUST be able to handle these cases. If * any of the OCTET STRING options is used, it MUST contain the DER encoding of * the requested certificate. *

    *

     *            RequestedCertificate ::= CHOICE {
     *              Certificate Certificate,
     *              publicKeyCertificate [0] EXPLICIT OCTET STRING,
     *              attributeCertificate [1] EXPLICIT OCTET STRING
     *            }
     * 
    */ public class RequestedCertificate extends ASN1Object implements ASN1Choice { public static final int certificate = -1; public static final int publicKeyCertificate = 0; public static final int attributeCertificate = 1; private Certificate cert; private byte[] publicKeyCert; private byte[] attributeCert; public static RequestedCertificate getInstance(Object obj) { if (obj == null || obj instanceof RequestedCertificate) { return (RequestedCertificate)obj; } if (obj instanceof ASN1Sequence) { return new RequestedCertificate(Certificate.getInstance(obj)); } if (obj instanceof ASN1TaggedObject) { return new RequestedCertificate((ASN1TaggedObject)obj); } throw new IllegalArgumentException("illegal object in getInstance: " + obj.getClass().getName()); } public static RequestedCertificate getInstance(ASN1TaggedObject obj, boolean explicit) { if (!explicit) { throw new IllegalArgumentException("choice item must be explicitly tagged"); } return getInstance(obj.getObject()); } private RequestedCertificate(ASN1TaggedObject tagged) { if (tagged.getTagNo() == publicKeyCertificate) { publicKeyCert = ASN1OctetString.getInstance(tagged, true).getOctets(); } else if (tagged.getTagNo() == attributeCertificate) { attributeCert = ASN1OctetString.getInstance(tagged, true).getOctets(); } else { throw new IllegalArgumentException("unknown tag number: " + tagged.getTagNo()); } } /** * Constructor from a given details. *

    * Only one parameter can be given. All other must be null. * * @param certificate Given as Certificate */ public RequestedCertificate(Certificate certificate) { this.cert = certificate; } public RequestedCertificate(int type, byte[] certificateOctets) { this(new DERTaggedObject(type, new DEROctetString(certificateOctets))); } public int getType() { if (cert != null) { return certificate; } if (publicKeyCert != null) { return publicKeyCertificate; } return attributeCertificate; } public byte[] getCertificateBytes() { if (cert != null) { try { return cert.getEncoded(); } catch (IOException e) { throw new IllegalStateException("can't decode certificate: " + e); } } if (publicKeyCert != null) { return publicKeyCert; } return attributeCert; } /** * Produce an object suitable for an ASN1OutputStream. *

    * Returns: *

    *

         *            RequestedCertificate ::= CHOICE {
         *              Certificate Certificate,
         *              publicKeyCertificate [0] EXPLICIT OCTET STRING,
         *              attributeCertificate [1] EXPLICIT OCTET STRING
         *            }
         * 
    * * @return a DERObject */ public ASN1Primitive toASN1Primitive() { if (publicKeyCert != null) { return new DERTaggedObject(0, new DEROctetString(publicKeyCert)); } if (attributeCert != null) { return new DERTaggedObject(1, new DEROctetString(attributeCert)); } return cert.toASN1Primitive(); } } bouncycastle-1.49.orig/src/org/bouncycastle/asn1/isismtt/x509/0000755000175000017500000000000012152033551023542 5ustar ebourgebourgbouncycastle-1.49.orig/src/org/bouncycastle/asn1/isismtt/x509/ProcurationSyntax.java0000644000175000017500000001712211624652555030142 0ustar ebourgebourgpackage org.bouncycastle.asn1.isismtt.x509; import java.util.Enumeration; import org.bouncycastle.asn1.ASN1Encodable; import org.bouncycastle.asn1.ASN1EncodableVector; import org.bouncycastle.asn1.ASN1Object; import org.bouncycastle.asn1.ASN1Primitive; import org.bouncycastle.asn1.ASN1Sequence; import org.bouncycastle.asn1.ASN1TaggedObject; import org.bouncycastle.asn1.DERPrintableString; import org.bouncycastle.asn1.DERSequence; import org.bouncycastle.asn1.DERTaggedObject; import org.bouncycastle.asn1.x500.DirectoryString; import org.bouncycastle.asn1.x509.GeneralName; import org.bouncycastle.asn1.x509.IssuerSerial; /** * Attribute to indicate that the certificate holder may sign in the name of a * third person. *

    * ISIS-MTT PROFILE: The corresponding ProcurationSyntax contains either the * name of the person who is represented (subcomponent thirdPerson) or a * reference to his/her base certificate (in the component signingFor, * subcomponent certRef), furthermore the optional components country and * typeSubstitution to indicate the country whose laws apply, and respectively * the type of procuration (e.g. manager, procuration, custody). *

    * ISIS-MTT PROFILE: The GeneralName MUST be of type directoryName and MAY only * contain: - RFC3039 attributes, except pseudonym (countryName, commonName, * surname, givenName, serialNumber, organizationName, organizationalUnitName, * stateOrProvincename, localityName, postalAddress) and - SubjectDirectoryName * attributes (title, dateOfBirth, placeOfBirth, gender, countryOfCitizenship, * countryOfResidence and NameAtBirth). * *

     *               ProcurationSyntax ::= SEQUENCE {
     *                 country [1] EXPLICIT PrintableString(SIZE(2)) OPTIONAL,
     *                 typeOfSubstitution [2] EXPLICIT DirectoryString (SIZE(1..128)) OPTIONAL,
     *                 signingFor [3] EXPLICIT SigningFor 
     *               }
     *               
     *               SigningFor ::= CHOICE 
     *               { 
     *                 thirdPerson GeneralName,
     *                 certRef IssuerSerial 
     *               }
     * 
    * */ public class ProcurationSyntax extends ASN1Object { private String country; private DirectoryString typeOfSubstitution; private GeneralName thirdPerson; private IssuerSerial certRef; public static ProcurationSyntax getInstance(Object obj) { if (obj == null || obj instanceof ProcurationSyntax) { return (ProcurationSyntax)obj; } if (obj instanceof ASN1Sequence) { return new ProcurationSyntax((ASN1Sequence)obj); } throw new IllegalArgumentException("illegal object in getInstance: " + obj.getClass().getName()); } /** * Constructor from ASN1Sequence. *

    * The sequence is of type ProcurationSyntax: *

    *

         *               ProcurationSyntax ::= SEQUENCE {
         *                 country [1] EXPLICIT PrintableString(SIZE(2)) OPTIONAL,
         *                 typeOfSubstitution [2] EXPLICIT DirectoryString (SIZE(1..128)) OPTIONAL,
         *                 signingFor [3] EXPLICIT SigningFor
         *               }
         * 

    * SigningFor ::= CHOICE * { * thirdPerson GeneralName, * certRef IssuerSerial * } *

    * * @param seq The ASN.1 sequence. */ private ProcurationSyntax(ASN1Sequence seq) { if (seq.size() < 1 || seq.size() > 3) { throw new IllegalArgumentException("Bad sequence size: " + seq.size()); } Enumeration e = seq.getObjects(); while (e.hasMoreElements()) { ASN1TaggedObject o = ASN1TaggedObject.getInstance(e.nextElement()); switch (o.getTagNo()) { case 1: country = DERPrintableString.getInstance(o, true).getString(); break; case 2: typeOfSubstitution = DirectoryString.getInstance(o, true); break; case 3: ASN1Encodable signingFor = o.getObject(); if (signingFor instanceof ASN1TaggedObject) { thirdPerson = GeneralName.getInstance(signingFor); } else { certRef = IssuerSerial.getInstance(signingFor); } break; default: throw new IllegalArgumentException("Bad tag number: " + o.getTagNo()); } } } /** * Constructor from a given details. *

    *

    * Either generalName or certRef MUST be * null. * * @param country The country code whose laws apply. * @param typeOfSubstitution The type of procuration. * @param certRef Reference to certificate of the person who is represented. */ public ProcurationSyntax( String country, DirectoryString typeOfSubstitution, IssuerSerial certRef) { this.country = country; this.typeOfSubstitution = typeOfSubstitution; this.thirdPerson = null; this.certRef = certRef; } /** * Constructor from a given details. *

    *

    * Either generalName or certRef MUST be * null. * * @param country The country code whose laws apply. * @param typeOfSubstitution The type of procuration. * @param thirdPerson The GeneralName of the person who is represented. */ public ProcurationSyntax( String country, DirectoryString typeOfSubstitution, GeneralName thirdPerson) { this.country = country; this.typeOfSubstitution = typeOfSubstitution; this.thirdPerson = thirdPerson; this.certRef = null; } public String getCountry() { return country; } public DirectoryString getTypeOfSubstitution() { return typeOfSubstitution; } public GeneralName getThirdPerson() { return thirdPerson; } public IssuerSerial getCertRef() { return certRef; } /** * Produce an object suitable for an ASN1OutputStream. *

    * Returns: *

    *

         *               ProcurationSyntax ::= SEQUENCE {
         *                 country [1] EXPLICIT PrintableString(SIZE(2)) OPTIONAL,
         *                 typeOfSubstitution [2] EXPLICIT DirectoryString (SIZE(1..128)) OPTIONAL,
         *                 signingFor [3] EXPLICIT SigningFor
         *               }
         * 

    * SigningFor ::= CHOICE * { * thirdPerson GeneralName, * certRef IssuerSerial * } *

    * * @return a DERObject */ public ASN1Primitive toASN1Primitive() { ASN1EncodableVector vec = new ASN1EncodableVector(); if (country != null) { vec.add(new DERTaggedObject(true, 1, new DERPrintableString(country, true))); } if (typeOfSubstitution != null) { vec.add(new DERTaggedObject(true, 2, typeOfSubstitution)); } if (thirdPerson != null) { vec.add(new DERTaggedObject(true, 3, thirdPerson)); } else { vec.add(new DERTaggedObject(true, 3, certRef)); } return new DERSequence(vec); } } bouncycastle-1.49.orig/src/org/bouncycastle/asn1/isismtt/x509/AdmissionSyntax.java0000644000175000017500000002530711624646232027562 0ustar ebourgebourgpackage org.bouncycastle.asn1.isismtt.x509; import java.util.Enumeration; import org.bouncycastle.asn1.ASN1EncodableVector; import org.bouncycastle.asn1.ASN1Object; import org.bouncycastle.asn1.ASN1Primitive; import org.bouncycastle.asn1.ASN1Sequence; import org.bouncycastle.asn1.DERSequence; import org.bouncycastle.asn1.x509.GeneralName; /** * Attribute to indicate admissions to certain professions. *

    *

     *     AdmissionSyntax ::= SEQUENCE
     *     {
     *       admissionAuthority GeneralName OPTIONAL,
     *       contentsOfAdmissions SEQUENCE OF Admissions
     *     }
     * 

    * Admissions ::= SEQUENCE * { * admissionAuthority [0] EXPLICIT GeneralName OPTIONAL * namingAuthority [1] EXPLICIT NamingAuthority OPTIONAL * professionInfos SEQUENCE OF ProfessionInfo * } *

    * NamingAuthority ::= SEQUENCE * { * namingAuthorityId OBJECT IDENTIFIER OPTIONAL, * namingAuthorityUrl IA5String OPTIONAL, * namingAuthorityText DirectoryString(SIZE(1..128)) OPTIONAL * } *

    * ProfessionInfo ::= SEQUENCE * { * namingAuthority [0] EXPLICIT NamingAuthority OPTIONAL, * professionItems SEQUENCE OF DirectoryString (SIZE(1..128)), * professionOIDs SEQUENCE OF OBJECT IDENTIFIER OPTIONAL, * registrationNumber PrintableString(SIZE(1..128)) OPTIONAL, * addProfessionInfo OCTET STRING OPTIONAL * } *

    *

    *

    * ISIS-MTT PROFILE: The relatively complex structure of AdmissionSyntax * supports the following concepts and requirements: *

      *
    • External institutions (e.g. professional associations, chambers, unions, * administrative bodies, companies, etc.), which are responsible for granting * and verifying professional admissions, are indicated by means of the data * field admissionAuthority. An admission authority is indicated by a * GeneralName object. Here an X.501 directory name (distinguished name) can be * indicated in the field directoryName, a URL address can be indicated in the * field uniformResourceIdentifier, and an object identifier can be indicated in * the field registeredId. *
    • The names of authorities which are responsible for the administration of * title registers are indicated in the data field namingAuthority. The name of * the authority can be identified by an object identifier in the field * namingAuthorityId, by means of a text string in the field * namingAuthorityText, by means of a URL address in the field * namingAuthorityUrl, or by a combination of them. For example, the text string * can contain the name of the authority, the country and the name of the title * register. The URL-option refers to a web page which contains lists with * �officially� registered professions (text and possibly OID) as well as * further information on these professions. Object identifiers for the * component namingAuthorityId are grouped under the OID-branch * id-isis-at-namingAuthorities and must be applied for. *
    • See * http://www.teletrust.de/anwend.asp?Id=30200&Sprache=E_&HomePG=0 for * an application form and http://www.teletrust.de/links.asp?id=30220,11 * for an overview of registered naming authorities. *
    • By means of the data type ProfessionInfo certain professions, * specializations, disciplines, fields of activity, etc. are identified. A * profession is represented by one or more text strings, resp. profession OIDs * in the fields professionItems and professionOIDs and by a registration number * in the field registrationNumber. An indication in text form must always be * present, whereas the other indications are optional. The component * addProfessionInfo may contain additional applicationspecific information in * DER-encoded form. *
    *

    * By means of different namingAuthority-OIDs or profession OIDs hierarchies of * professions, specializations, disciplines, fields of activity, etc. can be * expressed. The issuing admission authority should always be indicated (field * admissionAuthority), whenever a registration number is presented. Still, * information on admissions can be given without indicating an admission or a * naming authority by the exclusive use of the component professionItems. In * this case the certification authority is responsible for the verification of * the admission information. *

    *

    *

    * This attribute is single-valued. Still, several admissions can be captured in * the sequence structure of the component contentsOfAdmissions of * AdmissionSyntax or in the component professionInfos of Admissions. The * component admissionAuthority of AdmissionSyntax serves as default value for * the component admissionAuthority of Admissions. Within the latter component * the default value can be overwritten, in case that another authority is * responsible. The component namingAuthority of Admissions serves as a default * value for the component namingAuthority of ProfessionInfo. Within the latter * component the default value can be overwritten, in case that another naming * authority needs to be recorded. *

    * The length of the string objects is limited to 128 characters. It is * recommended to indicate a namingAuthorityURL in all issued attribute * certificates. If a namingAuthorityURL is indicated, the field professionItems * of ProfessionInfo should contain only registered titles. If the field * professionOIDs exists, it has to contain the OIDs of the professions listed * in professionItems in the same order. In general, the field professionInfos * should contain only one entry, unless the admissions that are to be listed * are logically connected (e.g. they have been issued under the same admission * number). * * @see org.bouncycastle.asn1.isismtt.x509.Admissions * @see org.bouncycastle.asn1.isismtt.x509.ProfessionInfo * @see org.bouncycastle.asn1.isismtt.x509.NamingAuthority */ public class AdmissionSyntax extends ASN1Object { private GeneralName admissionAuthority; private ASN1Sequence contentsOfAdmissions; public static AdmissionSyntax getInstance(Object obj) { if (obj == null || obj instanceof AdmissionSyntax) { return (AdmissionSyntax)obj; } if (obj instanceof ASN1Sequence) { return new AdmissionSyntax((ASN1Sequence)obj); } throw new IllegalArgumentException("illegal object in getInstance: " + obj.getClass().getName()); } /** * Constructor from ASN1Sequence. *

    * The sequence is of type ProcurationSyntax: *

    *

         *     AdmissionSyntax ::= SEQUENCE
         *     {
         *       admissionAuthority GeneralName OPTIONAL,
         *       contentsOfAdmissions SEQUENCE OF Admissions
         *     }
         * 

    * Admissions ::= SEQUENCE * { * admissionAuthority [0] EXPLICIT GeneralName OPTIONAL * namingAuthority [1] EXPLICIT NamingAuthority OPTIONAL * professionInfos SEQUENCE OF ProfessionInfo * } *

    * NamingAuthority ::= SEQUENCE * { * namingAuthorityId OBJECT IDENTIFIER OPTIONAL, * namingAuthorityUrl IA5String OPTIONAL, * namingAuthorityText DirectoryString(SIZE(1..128)) OPTIONAL * } *

    * ProfessionInfo ::= SEQUENCE * { * namingAuthority [0] EXPLICIT NamingAuthority OPTIONAL, * professionItems SEQUENCE OF DirectoryString (SIZE(1..128)), * professionOIDs SEQUENCE OF OBJECT IDENTIFIER OPTIONAL, * registrationNumber PrintableString(SIZE(1..128)) OPTIONAL, * addProfessionInfo OCTET STRING OPTIONAL * } *

    * * @param seq The ASN.1 sequence. */ private AdmissionSyntax(ASN1Sequence seq) { switch (seq.size()) { case 1: contentsOfAdmissions = DERSequence.getInstance(seq.getObjectAt(0)); break; case 2: admissionAuthority = GeneralName.getInstance(seq.getObjectAt(0)); contentsOfAdmissions = DERSequence.getInstance(seq.getObjectAt(1)); break; default: throw new IllegalArgumentException("Bad sequence size: " + seq.size()); } } /** * Constructor from given details. * * @param admissionAuthority The admission authority. * @param contentsOfAdmissions The admissions. */ public AdmissionSyntax(GeneralName admissionAuthority, ASN1Sequence contentsOfAdmissions) { this.admissionAuthority = admissionAuthority; this.contentsOfAdmissions = contentsOfAdmissions; } /** * Produce an object suitable for an ASN1OutputStream. *

    * Returns: *

    *

         *     AdmissionSyntax ::= SEQUENCE
         *     {
         *       admissionAuthority GeneralName OPTIONAL,
         *       contentsOfAdmissions SEQUENCE OF Admissions
         *     }
         * 

    * Admissions ::= SEQUENCE * { * admissionAuthority [0] EXPLICIT GeneralName OPTIONAL * namingAuthority [1] EXPLICIT NamingAuthority OPTIONAL * professionInfos SEQUENCE OF ProfessionInfo * } *

    * NamingAuthority ::= SEQUENCE * { * namingAuthorityId OBJECT IDENTIFIER OPTIONAL, * namingAuthorityUrl IA5String OPTIONAL, * namingAuthorityText DirectoryString(SIZE(1..128)) OPTIONAL * } *

    * ProfessionInfo ::= SEQUENCE * { * namingAuthority [0] EXPLICIT NamingAuthority OPTIONAL, * professionItems SEQUENCE OF DirectoryString (SIZE(1..128)), * professionOIDs SEQUENCE OF OBJECT IDENTIFIER OPTIONAL, * registrationNumber PrintableString(SIZE(1..128)) OPTIONAL, * addProfessionInfo OCTET STRING OPTIONAL * } *

    * * @return a DERObject */ public ASN1Primitive toASN1Primitive() { ASN1EncodableVector vec = new ASN1EncodableVector(); if (admissionAuthority != null) { vec.add(admissionAuthority); } vec.add(contentsOfAdmissions); return new DERSequence(vec); } /** * @return Returns the admissionAuthority if present, null otherwise. */ public GeneralName getAdmissionAuthority() { return admissionAuthority; } /** * @return Returns the contentsOfAdmissions. */ public Admissions[] getContentsOfAdmissions() { Admissions[] admissions = new Admissions[contentsOfAdmissions.size()]; int count = 0; for (Enumeration e = contentsOfAdmissions.getObjects(); e.hasMoreElements();) { admissions[count++] = Admissions.getInstance(e.nextElement()); } return admissions; } } bouncycastle-1.49.orig/src/org/bouncycastle/asn1/isismtt/x509/AdditionalInformationSyntax.java0000644000175000017500000000317211725324036032103 0ustar ebourgebourgpackage org.bouncycastle.asn1.isismtt.x509; import org.bouncycastle.asn1.ASN1Object; import org.bouncycastle.asn1.ASN1Primitive; import org.bouncycastle.asn1.x500.DirectoryString; /** * Some other information of non-restrictive nature regarding the usage of this * certificate. * *
     *    AdditionalInformationSyntax ::= DirectoryString (SIZE(1..2048))
     * 
    */ public class AdditionalInformationSyntax extends ASN1Object { private DirectoryString information; public static AdditionalInformationSyntax getInstance(Object obj) { if (obj instanceof AdditionalInformationSyntax) { return (AdditionalInformationSyntax)obj; } if (obj != null) { return new AdditionalInformationSyntax(DirectoryString.getInstance(obj)); } return null; } private AdditionalInformationSyntax(DirectoryString information) { this.information = information; } /** * Constructor from a given details. * * @param information The describtion of the information. */ public AdditionalInformationSyntax(String information) { this(new DirectoryString(information)); } public DirectoryString getInformation() { return information; } /** * Produce an object suitable for an ASN1OutputStream. *

    * Returns: *

    *

         *   AdditionalInformationSyntax ::= DirectoryString (SIZE(1..2048))
         * 
    * * @return a DERObject */ public ASN1Primitive toASN1Primitive() { return information.toASN1Primitive(); } } bouncycastle-1.49.orig/src/org/bouncycastle/asn1/isismtt/x509/ProfessionInfo.java0000644000175000017500000003210411724561172027361 0ustar ebourgebourgpackage org.bouncycastle.asn1.isismtt.x509; import java.util.Enumeration; import org.bouncycastle.asn1.ASN1Encodable; import org.bouncycastle.asn1.ASN1EncodableVector; import org.bouncycastle.asn1.ASN1Object; import org.bouncycastle.asn1.ASN1ObjectIdentifier; import org.bouncycastle.asn1.ASN1OctetString; import org.bouncycastle.asn1.ASN1Primitive; import org.bouncycastle.asn1.ASN1Sequence; import org.bouncycastle.asn1.ASN1TaggedObject; import org.bouncycastle.asn1.DEROctetString; import org.bouncycastle.asn1.DERPrintableString; import org.bouncycastle.asn1.DERSequence; import org.bouncycastle.asn1.DERTaggedObject; import org.bouncycastle.asn1.x500.DirectoryString; /** * Professions, specializations, disciplines, fields of activity, etc. * *
     *               ProfessionInfo ::= SEQUENCE 
     *               {
     *                 namingAuthority [0] EXPLICIT NamingAuthority OPTIONAL,
     *                 professionItems SEQUENCE OF DirectoryString (SIZE(1..128)),
     *                 professionOIDs SEQUENCE OF OBJECT IDENTIFIER OPTIONAL,
     *                 registrationNumber PrintableString(SIZE(1..128)) OPTIONAL,
     *                 addProfessionInfo OCTET STRING OPTIONAL 
     *               }
     * 
    * * @see org.bouncycastle.asn1.isismtt.x509.AdmissionSyntax */ public class ProfessionInfo extends ASN1Object { /** * Rechtsanw�ltin */ public static final ASN1ObjectIdentifier Rechtsanwltin = new ASN1ObjectIdentifier( NamingAuthority.id_isismtt_at_namingAuthorities_RechtWirtschaftSteuern + ".1"); /** * Rechtsanwalt */ public static final ASN1ObjectIdentifier Rechtsanwalt = new ASN1ObjectIdentifier( NamingAuthority.id_isismtt_at_namingAuthorities_RechtWirtschaftSteuern + ".2"); /** * Rechtsbeistand */ public static final ASN1ObjectIdentifier Rechtsbeistand = new ASN1ObjectIdentifier( NamingAuthority.id_isismtt_at_namingAuthorities_RechtWirtschaftSteuern + ".3"); /** * Steuerberaterin */ public static final ASN1ObjectIdentifier Steuerberaterin = new ASN1ObjectIdentifier( NamingAuthority.id_isismtt_at_namingAuthorities_RechtWirtschaftSteuern + ".4"); /** * Steuerberater */ public static final ASN1ObjectIdentifier Steuerberater = new ASN1ObjectIdentifier( NamingAuthority.id_isismtt_at_namingAuthorities_RechtWirtschaftSteuern + ".5"); /** * Steuerbevollm�chtigte */ public static final ASN1ObjectIdentifier Steuerbevollmchtigte = new ASN1ObjectIdentifier( NamingAuthority.id_isismtt_at_namingAuthorities_RechtWirtschaftSteuern + ".6"); /** * Steuerbevollm�chtigter */ public static final ASN1ObjectIdentifier Steuerbevollmchtigter = new ASN1ObjectIdentifier( NamingAuthority.id_isismtt_at_namingAuthorities_RechtWirtschaftSteuern + ".7"); /** * Notarin */ public static final ASN1ObjectIdentifier Notarin = new ASN1ObjectIdentifier( NamingAuthority.id_isismtt_at_namingAuthorities_RechtWirtschaftSteuern + ".8"); /** * Notar */ public static final ASN1ObjectIdentifier Notar = new ASN1ObjectIdentifier( NamingAuthority.id_isismtt_at_namingAuthorities_RechtWirtschaftSteuern + ".9"); /** * Notarvertreterin */ public static final ASN1ObjectIdentifier Notarvertreterin = new ASN1ObjectIdentifier( NamingAuthority.id_isismtt_at_namingAuthorities_RechtWirtschaftSteuern + ".10"); /** * Notarvertreter */ public static final ASN1ObjectIdentifier Notarvertreter = new ASN1ObjectIdentifier( NamingAuthority.id_isismtt_at_namingAuthorities_RechtWirtschaftSteuern + ".11"); /** * Notariatsverwalterin */ public static final ASN1ObjectIdentifier Notariatsverwalterin = new ASN1ObjectIdentifier( NamingAuthority.id_isismtt_at_namingAuthorities_RechtWirtschaftSteuern + ".12"); /** * Notariatsverwalter */ public static final ASN1ObjectIdentifier Notariatsverwalter = new ASN1ObjectIdentifier( NamingAuthority.id_isismtt_at_namingAuthorities_RechtWirtschaftSteuern + ".13"); /** * Wirtschaftspr�ferin */ public static final ASN1ObjectIdentifier Wirtschaftsprferin = new ASN1ObjectIdentifier( NamingAuthority.id_isismtt_at_namingAuthorities_RechtWirtschaftSteuern + ".14"); /** * Wirtschaftspr�fer */ public static final ASN1ObjectIdentifier Wirtschaftsprfer = new ASN1ObjectIdentifier( NamingAuthority.id_isismtt_at_namingAuthorities_RechtWirtschaftSteuern + ".15"); /** * Vereidigte Buchpr�ferin */ public static final ASN1ObjectIdentifier VereidigteBuchprferin = new ASN1ObjectIdentifier( NamingAuthority.id_isismtt_at_namingAuthorities_RechtWirtschaftSteuern + ".16"); /** * Vereidigter Buchpr�fer */ public static final ASN1ObjectIdentifier VereidigterBuchprfer = new ASN1ObjectIdentifier( NamingAuthority.id_isismtt_at_namingAuthorities_RechtWirtschaftSteuern + ".17"); /** * Patentanw�ltin */ public static final ASN1ObjectIdentifier Patentanwltin = new ASN1ObjectIdentifier( NamingAuthority.id_isismtt_at_namingAuthorities_RechtWirtschaftSteuern + ".18"); /** * Patentanwalt */ public static final ASN1ObjectIdentifier Patentanwalt = new ASN1ObjectIdentifier( NamingAuthority.id_isismtt_at_namingAuthorities_RechtWirtschaftSteuern + ".19"); private NamingAuthority namingAuthority; private ASN1Sequence professionItems; private ASN1Sequence professionOIDs; private String registrationNumber; private ASN1OctetString addProfessionInfo; public static ProfessionInfo getInstance(Object obj) { if (obj == null || obj instanceof ProfessionInfo) { return (ProfessionInfo)obj; } if (obj instanceof ASN1Sequence) { return new ProfessionInfo((ASN1Sequence)obj); } throw new IllegalArgumentException("illegal object in getInstance: " + obj.getClass().getName()); } /** * Constructor from ASN1Sequence. *

    *

    *

         *               ProfessionInfo ::= SEQUENCE
         *               {
         *                 namingAuthority [0] EXPLICIT NamingAuthority OPTIONAL,
         *                 professionItems SEQUENCE OF DirectoryString (SIZE(1..128)),
         *                 professionOIDs SEQUENCE OF OBJECT IDENTIFIER OPTIONAL,
         *                 registrationNumber PrintableString(SIZE(1..128)) OPTIONAL,
         *                 addProfessionInfo OCTET STRING OPTIONAL
         *               }
         * 
    * * @param seq The ASN.1 sequence. */ private ProfessionInfo(ASN1Sequence seq) { if (seq.size() > 5) { throw new IllegalArgumentException("Bad sequence size: " + seq.size()); } Enumeration e = seq.getObjects(); ASN1Encodable o = (ASN1Encodable)e.nextElement(); if (o instanceof ASN1TaggedObject) { if (((ASN1TaggedObject)o).getTagNo() != 0) { throw new IllegalArgumentException("Bad tag number: " + ((ASN1TaggedObject)o).getTagNo()); } namingAuthority = NamingAuthority.getInstance((ASN1TaggedObject)o, true); o = (ASN1Encodable)e.nextElement(); } professionItems = ASN1Sequence.getInstance(o); if (e.hasMoreElements()) { o = (ASN1Encodable)e.nextElement(); if (o instanceof ASN1Sequence) { professionOIDs = ASN1Sequence.getInstance(o); } else if (o instanceof DERPrintableString) { registrationNumber = DERPrintableString.getInstance(o).getString(); } else if (o instanceof ASN1OctetString) { addProfessionInfo = ASN1OctetString.getInstance(o); } else { throw new IllegalArgumentException("Bad object encountered: " + o.getClass()); } } if (e.hasMoreElements()) { o = (ASN1Encodable)e.nextElement(); if (o instanceof DERPrintableString) { registrationNumber = DERPrintableString.getInstance(o).getString(); } else if (o instanceof DEROctetString) { addProfessionInfo = (DEROctetString)o; } else { throw new IllegalArgumentException("Bad object encountered: " + o.getClass()); } } if (e.hasMoreElements()) { o = (ASN1Encodable)e.nextElement(); if (o instanceof DEROctetString) { addProfessionInfo = (DEROctetString)o; } else { throw new IllegalArgumentException("Bad object encountered: " + o.getClass()); } } } /** * Constructor from given details. *

    * professionItems is mandatory, all other parameters are * optional. * * @param namingAuthority The naming authority. * @param professionItems Directory strings of the profession. * @param professionOIDs DERObjectIdentfier objects for the * profession. * @param registrationNumber Registration number. * @param addProfessionInfo Additional infos in encoded form. */ public ProfessionInfo(NamingAuthority namingAuthority, DirectoryString[] professionItems, ASN1ObjectIdentifier[] professionOIDs, String registrationNumber, ASN1OctetString addProfessionInfo) { this.namingAuthority = namingAuthority; ASN1EncodableVector v = new ASN1EncodableVector(); for (int i = 0; i != professionItems.length; i++) { v.add(professionItems[i]); } this.professionItems = new DERSequence(v); if (professionOIDs != null) { v = new ASN1EncodableVector(); for (int i = 0; i != professionOIDs.length; i++) { v.add(professionOIDs[i]); } this.professionOIDs = new DERSequence(v); } this.registrationNumber = registrationNumber; this.addProfessionInfo = addProfessionInfo; } /** * Produce an object suitable for an ASN1OutputStream. *

    * Returns: *

    *

         *               ProfessionInfo ::= SEQUENCE
         *               {
         *                 namingAuthority [0] EXPLICIT NamingAuthority OPTIONAL,
         *                 professionItems SEQUENCE OF DirectoryString (SIZE(1..128)),
         *                 professionOIDs SEQUENCE OF OBJECT IDENTIFIER OPTIONAL,
         *                 registrationNumber PrintableString(SIZE(1..128)) OPTIONAL,
         *                 addProfessionInfo OCTET STRING OPTIONAL
         *               }
         * 
    * * @return a DERObject */ public ASN1Primitive toASN1Primitive() { ASN1EncodableVector vec = new ASN1EncodableVector(); if (namingAuthority != null) { vec.add(new DERTaggedObject(true, 0, namingAuthority)); } vec.add(professionItems); if (professionOIDs != null) { vec.add(professionOIDs); } if (registrationNumber != null) { vec.add(new DERPrintableString(registrationNumber, true)); } if (addProfessionInfo != null) { vec.add(addProfessionInfo); } return new DERSequence(vec); } /** * @return Returns the addProfessionInfo. */ public ASN1OctetString getAddProfessionInfo() { return addProfessionInfo; } /** * @return Returns the namingAuthority. */ public NamingAuthority getNamingAuthority() { return namingAuthority; } /** * @return Returns the professionItems. */ public DirectoryString[] getProfessionItems() { DirectoryString[] items = new DirectoryString[professionItems.size()]; int count = 0; for (Enumeration e = professionItems.getObjects(); e.hasMoreElements();) { items[count++] = DirectoryString.getInstance(e.nextElement()); } return items; } /** * @return Returns the professionOIDs. */ public ASN1ObjectIdentifier[] getProfessionOIDs() { if (professionOIDs == null) { return new ASN1ObjectIdentifier[0]; } ASN1ObjectIdentifier[] oids = new ASN1ObjectIdentifier[professionOIDs.size()]; int count = 0; for (Enumeration e = professionOIDs.getObjects(); e.hasMoreElements();) { oids[count++] = ASN1ObjectIdentifier.getInstance(e.nextElement()); } return oids; } /** * @return Returns the registrationNumber. */ public String getRegistrationNumber() { return registrationNumber; } } bouncycastle-1.49.orig/src/org/bouncycastle/asn1/isismtt/x509/NamingAuthority.java0000644000175000017500000001705111724561172027544 0ustar ebourgebourgpackage org.bouncycastle.asn1.isismtt.x509; import java.util.Enumeration; import org.bouncycastle.asn1.ASN1Encodable; import org.bouncycastle.asn1.ASN1EncodableVector; import org.bouncycastle.asn1.ASN1Object; import org.bouncycastle.asn1.ASN1ObjectIdentifier; import org.bouncycastle.asn1.ASN1Primitive; import org.bouncycastle.asn1.ASN1Sequence; import org.bouncycastle.asn1.ASN1String; import org.bouncycastle.asn1.ASN1TaggedObject; import org.bouncycastle.asn1.DERIA5String; import org.bouncycastle.asn1.DERObjectIdentifier; import org.bouncycastle.asn1.DERSequence; import org.bouncycastle.asn1.isismtt.ISISMTTObjectIdentifiers; import org.bouncycastle.asn1.x500.DirectoryString; /** * Names of authorities which are responsible for the administration of title * registers. * *
     *             NamingAuthority ::= SEQUENCE 
     *             {
     *               namingAuthorityId OBJECT IDENTIFIER OPTIONAL,
     *               namingAuthorityUrl IA5String OPTIONAL,
     *               namingAuthorityText DirectoryString(SIZE(1..128)) OPTIONAL
     *             }
     * 
    * @see org.bouncycastle.asn1.isismtt.x509.AdmissionSyntax * */ public class NamingAuthority extends ASN1Object { /** * Profession OIDs should always be defined under the OID branch of the * responsible naming authority. At the time of this writing, the work group * �Recht, Wirtschaft, Steuern� (�Law, Economy, Taxes�) is registered as the * first naming authority under the OID id-isismtt-at-namingAuthorities. */ public static final ASN1ObjectIdentifier id_isismtt_at_namingAuthorities_RechtWirtschaftSteuern = new ASN1ObjectIdentifier(ISISMTTObjectIdentifiers.id_isismtt_at_namingAuthorities + ".1"); private ASN1ObjectIdentifier namingAuthorityId; private String namingAuthorityUrl; private DirectoryString namingAuthorityText; public static NamingAuthority getInstance(Object obj) { if (obj == null || obj instanceof NamingAuthority) { return (NamingAuthority)obj; } if (obj instanceof ASN1Sequence) { return new NamingAuthority((ASN1Sequence)obj); } throw new IllegalArgumentException("illegal object in getInstance: " + obj.getClass().getName()); } public static NamingAuthority getInstance(ASN1TaggedObject obj, boolean explicit) { return getInstance(ASN1Sequence.getInstance(obj, explicit)); } /** * Constructor from ASN1Sequence. *

    *

    *

         *             NamingAuthority ::= SEQUENCE
         *             {
         *               namingAuthorityId OBJECT IDENTIFIER OPTIONAL,
         *               namingAuthorityUrl IA5String OPTIONAL,
         *               namingAuthorityText DirectoryString(SIZE(1..128)) OPTIONAL
         *             }
         * 
    * * @param seq The ASN.1 sequence. */ private NamingAuthority(ASN1Sequence seq) { if (seq.size() > 3) { throw new IllegalArgumentException("Bad sequence size: " + seq.size()); } Enumeration e = seq.getObjects(); if (e.hasMoreElements()) { ASN1Encodable o = (ASN1Encodable)e.nextElement(); if (o instanceof ASN1ObjectIdentifier) { namingAuthorityId = (ASN1ObjectIdentifier)o; } else if (o instanceof DERIA5String) { namingAuthorityUrl = DERIA5String.getInstance(o).getString(); } else if (o instanceof ASN1String) { namingAuthorityText = DirectoryString.getInstance(o); } else { throw new IllegalArgumentException("Bad object encountered: " + o.getClass()); } } if (e.hasMoreElements()) { ASN1Encodable o = (ASN1Encodable)e.nextElement(); if (o instanceof DERIA5String) { namingAuthorityUrl = DERIA5String.getInstance(o).getString(); } else if (o instanceof ASN1String) { namingAuthorityText = DirectoryString.getInstance(o); } else { throw new IllegalArgumentException("Bad object encountered: " + o.getClass()); } } if (e.hasMoreElements()) { ASN1Encodable o = (ASN1Encodable)e.nextElement(); if (o instanceof ASN1String) { namingAuthorityText = DirectoryString.getInstance(o); } else { throw new IllegalArgumentException("Bad object encountered: " + o.getClass()); } } } /** * @return Returns the namingAuthorityId. */ public ASN1ObjectIdentifier getNamingAuthorityId() { return namingAuthorityId; } /** * @return Returns the namingAuthorityText. */ public DirectoryString getNamingAuthorityText() { return namingAuthorityText; } /** * @return Returns the namingAuthorityUrl. */ public String getNamingAuthorityUrl() { return namingAuthorityUrl; } /** * Constructor from given details. *

    * All parameters can be combined. * * @param namingAuthorityId ObjectIdentifier for naming authority. * @param namingAuthorityUrl URL for naming authority. * @param namingAuthorityText Textual representation of naming authority. * @deprecated use ASN1ObjectIdentifier method */ public NamingAuthority(DERObjectIdentifier namingAuthorityId, String namingAuthorityUrl, DirectoryString namingAuthorityText) { this.namingAuthorityId = new ASN1ObjectIdentifier(namingAuthorityId.getId()); this.namingAuthorityUrl = namingAuthorityUrl; this.namingAuthorityText = namingAuthorityText; } /** * Constructor from given details. *

    * All parameters can be combined. * * @param namingAuthorityId ObjectIdentifier for naming authority. * @param namingAuthorityUrl URL for naming authority. * @param namingAuthorityText Textual representation of naming authority. */ public NamingAuthority(ASN1ObjectIdentifier namingAuthorityId, String namingAuthorityUrl, DirectoryString namingAuthorityText) { this.namingAuthorityId = namingAuthorityId; this.namingAuthorityUrl = namingAuthorityUrl; this.namingAuthorityText = namingAuthorityText; } /** * Produce an object suitable for an ASN1OutputStream. *

    * Returns: *

    *

         *             NamingAuthority ::= SEQUENCE
         *             {
         *               namingAuthorityId OBJECT IDENTIFIER OPTIONAL,
         *               namingAuthorityUrl IA5String OPTIONAL,
         *               namingAuthorityText DirectoryString(SIZE(1..128)) OPTIONAL
         *             }
         * 
    * * @return a DERObject */ public ASN1Primitive toASN1Primitive() { ASN1EncodableVector vec = new ASN1EncodableVector(); if (namingAuthorityId != null) { vec.add(namingAuthorityId); } if (namingAuthorityUrl != null) { vec.add(new DERIA5String(namingAuthorityUrl, true)); } if (namingAuthorityText != null) { vec.add(namingAuthorityText); } return new DERSequence(vec); } } bouncycastle-1.49.orig/src/org/bouncycastle/asn1/isismtt/x509/MonetaryLimit.java0000644000175000017500000000665011724561172027222 0ustar ebourgebourgpackage org.bouncycastle.asn1.isismtt.x509; import java.math.BigInteger; import java.util.Enumeration; import org.bouncycastle.asn1.ASN1EncodableVector; import org.bouncycastle.asn1.ASN1Integer; import org.bouncycastle.asn1.ASN1Object; import org.bouncycastle.asn1.ASN1Primitive; import org.bouncycastle.asn1.ASN1Sequence; import org.bouncycastle.asn1.DERPrintableString; import org.bouncycastle.asn1.DERSequence; /** * Monetary limit for transactions. The QcEuMonetaryLimit QC statement MUST be * used in new certificates in place of the extension/attribute MonetaryLimit * since January 1, 2004. For the sake of backward compatibility with * certificates already in use, components SHOULD support MonetaryLimit (as well * as QcEuLimitValue). *

    * Indicates a monetary limit within which the certificate holder is authorized * to act. (This value DOES NOT express a limit on the liability of the * certification authority). *

    *

     *    MonetaryLimitSyntax ::= SEQUENCE
     *    {
     *      currency PrintableString (SIZE(3)),
     *      amount INTEGER,
     *      exponent INTEGER
     *    }
     * 
    *

    * currency must be the ISO code. *

    * value = amount�10*exponent */ public class MonetaryLimit extends ASN1Object { DERPrintableString currency; ASN1Integer amount; ASN1Integer exponent; public static MonetaryLimit getInstance(Object obj) { if (obj == null || obj instanceof MonetaryLimit) { return (MonetaryLimit)obj; } if (obj instanceof ASN1Sequence) { return new MonetaryLimit(ASN1Sequence.getInstance(obj)); } throw new IllegalArgumentException("unknown object in getInstance"); } private MonetaryLimit(ASN1Sequence seq) { if (seq.size() != 3) { throw new IllegalArgumentException("Bad sequence size: " + seq.size()); } Enumeration e = seq.getObjects(); currency = DERPrintableString.getInstance(e.nextElement()); amount = ASN1Integer.getInstance(e.nextElement()); exponent = ASN1Integer.getInstance(e.nextElement()); } /** * Constructor from a given details. *

    *

    * value = amount�10^exponent * * @param currency The currency. Must be the ISO code. * @param amount The amount * @param exponent The exponent */ public MonetaryLimit(String currency, int amount, int exponent) { this.currency = new DERPrintableString(currency, true); this.amount = new ASN1Integer(amount); this.exponent = new ASN1Integer(exponent); } public String getCurrency() { return currency.getString(); } public BigInteger getAmount() { return amount.getValue(); } public BigInteger getExponent() { return exponent.getValue(); } /** * Produce an object suitable for an ASN1OutputStream. *

    * Returns: *

    *

         *    MonetaryLimitSyntax ::= SEQUENCE
         *    {
         *      currency PrintableString (SIZE(3)),
         *      amount INTEGER,
         *      exponent INTEGER
         *    }
         * 
    * * @return a DERObject */ public ASN1Primitive toASN1Primitive() { ASN1EncodableVector seq = new ASN1EncodableVector(); seq.add(currency); seq.add(amount); seq.add(exponent); return new DERSequence(seq); } } bouncycastle-1.49.orig/src/org/bouncycastle/asn1/isismtt/x509/Admissions.java0000644000175000017500000001314311624652555026536 0ustar ebourgebourgpackage org.bouncycastle.asn1.isismtt.x509; import java.util.Enumeration; import org.bouncycastle.asn1.ASN1Encodable; import org.bouncycastle.asn1.ASN1EncodableVector; import org.bouncycastle.asn1.ASN1Object; import org.bouncycastle.asn1.ASN1Primitive; import org.bouncycastle.asn1.ASN1Sequence; import org.bouncycastle.asn1.ASN1TaggedObject; import org.bouncycastle.asn1.DERSequence; import org.bouncycastle.asn1.DERTaggedObject; import org.bouncycastle.asn1.x509.GeneralName; /** * An Admissions structure. *

    *

     *            Admissions ::= SEQUENCE
     *            {
     *              admissionAuthority [0] EXPLICIT GeneralName OPTIONAL
     *              namingAuthority [1] EXPLICIT NamingAuthority OPTIONAL
     *              professionInfos SEQUENCE OF ProfessionInfo
     *            }
     * 

    *

    * * @see org.bouncycastle.asn1.isismtt.x509.AdmissionSyntax * @see org.bouncycastle.asn1.isismtt.x509.ProfessionInfo * @see org.bouncycastle.asn1.isismtt.x509.NamingAuthority */ public class Admissions extends ASN1Object { private GeneralName admissionAuthority; private NamingAuthority namingAuthority; private ASN1Sequence professionInfos; public static Admissions getInstance(Object obj) { if (obj == null || obj instanceof Admissions) { return (Admissions)obj; } if (obj instanceof ASN1Sequence) { return new Admissions((ASN1Sequence)obj); } throw new IllegalArgumentException("illegal object in getInstance: " + obj.getClass().getName()); } /** * Constructor from ASN1Sequence. *

    * The sequence is of type ProcurationSyntax: *

    *

         *            Admissions ::= SEQUENCE
         *            {
         *              admissionAuthority [0] EXPLICIT GeneralName OPTIONAL
         *              namingAuthority [1] EXPLICIT NamingAuthority OPTIONAL
         *              professionInfos SEQUENCE OF ProfessionInfo
         *            }
         * 
    * * @param seq The ASN.1 sequence. */ private Admissions(ASN1Sequence seq) { if (seq.size() > 3) { throw new IllegalArgumentException("Bad sequence size: " + seq.size()); } Enumeration e = seq.getObjects(); ASN1Encodable o = (ASN1Encodable)e.nextElement(); if (o instanceof ASN1TaggedObject) { switch (((ASN1TaggedObject)o).getTagNo()) { case 0: admissionAuthority = GeneralName.getInstance((ASN1TaggedObject)o, true); break; case 1: namingAuthority = NamingAuthority.getInstance((ASN1TaggedObject)o, true); break; default: throw new IllegalArgumentException("Bad tag number: " + ((ASN1TaggedObject)o).getTagNo()); } o = (ASN1Encodable)e.nextElement(); } if (o instanceof ASN1TaggedObject) { switch (((ASN1TaggedObject)o).getTagNo()) { case 1: namingAuthority = NamingAuthority.getInstance((ASN1TaggedObject)o, true); break; default: throw new IllegalArgumentException("Bad tag number: " + ((ASN1TaggedObject)o).getTagNo()); } o = (ASN1Encodable)e.nextElement(); } professionInfos = ASN1Sequence.getInstance(o); if (e.hasMoreElements()) { throw new IllegalArgumentException("Bad object encountered: " + e.nextElement().getClass()); } } /** * Constructor from a given details. *

    * Parameter professionInfos is mandatory. * * @param admissionAuthority The admission authority. * @param namingAuthority The naming authority. * @param professionInfos The profession infos. */ public Admissions(GeneralName admissionAuthority, NamingAuthority namingAuthority, ProfessionInfo[] professionInfos) { this.admissionAuthority = admissionAuthority; this.namingAuthority = namingAuthority; this.professionInfos = new DERSequence(professionInfos); } public GeneralName getAdmissionAuthority() { return admissionAuthority; } public NamingAuthority getNamingAuthority() { return namingAuthority; } public ProfessionInfo[] getProfessionInfos() { ProfessionInfo[] infos = new ProfessionInfo[professionInfos.size()]; int count = 0; for (Enumeration e = professionInfos.getObjects(); e.hasMoreElements();) { infos[count++] = ProfessionInfo.getInstance(e.nextElement()); } return infos; } /** * Produce an object suitable for an ASN1OutputStream. *

    * Returns: *

    *

         *       Admissions ::= SEQUENCE
         *       {
         *         admissionAuthority [0] EXPLICIT GeneralName OPTIONAL
         *         namingAuthority [1] EXPLICIT NamingAuthority OPTIONAL
         *         professionInfos SEQUENCE OF ProfessionInfo
         *       }
         * 

    *

    * * @return an ASN1Primitive */ public ASN1Primitive toASN1Primitive() { ASN1EncodableVector vec = new ASN1EncodableVector(); if (admissionAuthority != null) { vec.add(new DERTaggedObject(true, 0, admissionAuthority)); } if (namingAuthority != null) { vec.add(new DERTaggedObject(true, 1, namingAuthority)); } vec.add(professionInfos); return new DERSequence(vec); } } bouncycastle-1.49.orig/src/org/bouncycastle/asn1/isismtt/x509/DeclarationOfMajority.java0000644000175000017500000001064011737275254030657 0ustar ebourgebourgpackage org.bouncycastle.asn1.isismtt.x509; import org.bouncycastle.asn1.ASN1Boolean; import org.bouncycastle.asn1.ASN1Choice; import org.bouncycastle.asn1.ASN1EncodableVector; import org.bouncycastle.asn1.ASN1GeneralizedTime; import org.bouncycastle.asn1.ASN1Integer; import org.bouncycastle.asn1.ASN1Object; import org.bouncycastle.asn1.ASN1Primitive; import org.bouncycastle.asn1.ASN1Sequence; import org.bouncycastle.asn1.ASN1TaggedObject; import org.bouncycastle.asn1.DERPrintableString; import org.bouncycastle.asn1.DERSequence; import org.bouncycastle.asn1.DERTaggedObject; /** * A declaration of majority. *

    *

     *           DeclarationOfMajoritySyntax ::= CHOICE
     *           {
     *             notYoungerThan [0] IMPLICIT INTEGER,
     *             fullAgeAtCountry [1] IMPLICIT SEQUENCE
     *             {
     *               fullAge BOOLEAN DEFAULT TRUE,
     *               country PrintableString (SIZE(2))
     *             }
     *             dateOfBirth [2] IMPLICIT GeneralizedTime
     *           }
     * 
    *

    * fullAgeAtCountry indicates the majority of the owner with respect to the laws * of a specific country. */ public class DeclarationOfMajority extends ASN1Object implements ASN1Choice { public static final int notYoungerThan = 0; public static final int fullAgeAtCountry = 1; public static final int dateOfBirth = 2; private ASN1TaggedObject declaration; public DeclarationOfMajority(int notYoungerThan) { declaration = new DERTaggedObject(false, 0, new ASN1Integer(notYoungerThan)); } public DeclarationOfMajority(boolean fullAge, String country) { if (country.length() > 2) { throw new IllegalArgumentException("country can only be 2 characters"); } if (fullAge) { declaration = new DERTaggedObject(false, 1, new DERSequence(new DERPrintableString(country, true))); } else { ASN1EncodableVector v = new ASN1EncodableVector(); v.add(ASN1Boolean.FALSE); v.add(new DERPrintableString(country, true)); declaration = new DERTaggedObject(false, 1, new DERSequence(v)); } } public DeclarationOfMajority(ASN1GeneralizedTime dateOfBirth) { declaration = new DERTaggedObject(false, 2, dateOfBirth); } public static DeclarationOfMajority getInstance(Object obj) { if (obj == null || obj instanceof DeclarationOfMajority) { return (DeclarationOfMajority)obj; } if (obj instanceof ASN1TaggedObject) { return new DeclarationOfMajority((ASN1TaggedObject)obj); } throw new IllegalArgumentException("illegal object in getInstance: " + obj.getClass().getName()); } private DeclarationOfMajority(ASN1TaggedObject o) { if (o.getTagNo() > 2) { throw new IllegalArgumentException("Bad tag number: " + o.getTagNo()); } declaration = o; } /** * Produce an object suitable for an ASN1OutputStream. *

    * Returns: *

    *

         *           DeclarationOfMajoritySyntax ::= CHOICE
         *           {
         *             notYoungerThan [0] IMPLICIT INTEGER,
         *             fullAgeAtCountry [1] IMPLICIT SEQUENCE
         *             {
         *               fullAge BOOLEAN DEFAULT TRUE,
         *               country PrintableString (SIZE(2))
         *             }
         *             dateOfBirth [2] IMPLICIT GeneralizedTime
         *           }
         * 
    * * @return a DERObject */ public ASN1Primitive toASN1Primitive() { return declaration; } public int getType() { return declaration.getTagNo(); } /** * @return notYoungerThan if that's what we are, -1 otherwise */ public int notYoungerThan() { if (declaration.getTagNo() != 0) { return -1; } return ASN1Integer.getInstance(declaration, false).getValue().intValue(); } public ASN1Sequence fullAgeAtCountry() { if (declaration.getTagNo() != 1) { return null; } return ASN1Sequence.getInstance(declaration, false); } public ASN1GeneralizedTime getDateOfBirth() { if (declaration.getTagNo() != 2) { return null; } return ASN1GeneralizedTime.getInstance(declaration, false); } } bouncycastle-1.49.orig/src/org/bouncycastle/asn1/isismtt/x509/Restriction.java0000644000175000017500000000342211725324036026721 0ustar ebourgebourgpackage org.bouncycastle.asn1.isismtt.x509; import org.bouncycastle.asn1.ASN1Object; import org.bouncycastle.asn1.ASN1Primitive; import org.bouncycastle.asn1.x500.DirectoryString; /** * Some other restriction regarding the usage of this certificate. *

    *

     *  RestrictionSyntax ::= DirectoryString (SIZE(1..1024))
     * 
    */ public class Restriction extends ASN1Object { private DirectoryString restriction; public static Restriction getInstance(Object obj) { if (obj instanceof Restriction) { return (Restriction)obj; } if (obj != null) { return new Restriction(DirectoryString.getInstance(obj)); } return null; } /** * Constructor from DirectoryString. *

    * The DirectoryString is of type RestrictionSyntax: *

    *

         *      RestrictionSyntax ::= DirectoryString (SIZE(1..1024))
         * 
    * * @param restriction A DirectoryString. */ private Restriction(DirectoryString restriction) { this.restriction = restriction; } /** * Constructor from a given details. * * @param restriction The describtion of the restriction. */ public Restriction(String restriction) { this.restriction = new DirectoryString(restriction); } public DirectoryString getRestriction() { return restriction; } /** * Produce an object suitable for an ASN1OutputStream. *

    * Returns: *

    *

         *      RestrictionSyntax ::= DirectoryString (SIZE(1..1024))
         * 

    *

    * * @return a DERObject */ public ASN1Primitive toASN1Primitive() { return restriction.toASN1Primitive(); } } bouncycastle-1.49.orig/src/org/bouncycastle/asn1/isismtt/ISISMTTObjectIdentifiers.java0000644000175000017500000001555111624622714030370 0ustar ebourgebourgpackage org.bouncycastle.asn1.isismtt; import org.bouncycastle.asn1.ASN1ObjectIdentifier; public interface ISISMTTObjectIdentifiers { static final ASN1ObjectIdentifier id_isismtt = new ASN1ObjectIdentifier("1.3.36.8"); static final ASN1ObjectIdentifier id_isismtt_cp = id_isismtt.branch("1"); /** * The id-isismtt-cp-accredited OID indicates that the certificate is a * qualified certificate according to Directive 1999/93/EC of the European * Parliament and of the Council of 13 December 1999 on a Community * Framework for Electronic Signatures, which additionally conforms the * special requirements of the SigG and has been issued by an accredited CA. */ static final ASN1ObjectIdentifier id_isismtt_cp_accredited = id_isismtt_cp.branch("1"); static final ASN1ObjectIdentifier id_isismtt_at = id_isismtt.branch("3"); /** * Certificate extensionDate of certificate generation * *
         *                DateOfCertGenSyntax ::= GeneralizedTime
         * 
    */ static final ASN1ObjectIdentifier id_isismtt_at_dateOfCertGen = id_isismtt_at.branch("1"); /** * Attribute to indicate that the certificate holder may sign in the name of * a third person. May also be used as extension in a certificate. */ static final ASN1ObjectIdentifier id_isismtt_at_procuration = id_isismtt_at.branch("2"); /** * Attribute to indicate admissions to certain professions. May be used as * attribute in attribute certificate or as extension in a certificate */ static final ASN1ObjectIdentifier id_isismtt_at_admission = id_isismtt_at.branch("3"); /** * Monetary limit for transactions. The QcEuMonetaryLimit QC statement MUST * be used in new certificates in place of the extension/attribute * MonetaryLimit since January 1, 2004. For the sake of backward * compatibility with certificates already in use, SigG conforming * components MUST support MonetaryLimit (as well as QcEuLimitValue). */ static final ASN1ObjectIdentifier id_isismtt_at_monetaryLimit = id_isismtt_at.branch("4"); /** * A declaration of majority. May be used as attribute in attribute * certificate or as extension in a certificate */ static final ASN1ObjectIdentifier id_isismtt_at_declarationOfMajority = id_isismtt_at.branch("5"); /** * * Serial number of the smart card containing the corresponding private key * *
         *                 ICCSNSyntax ::= OCTET STRING (SIZE(8..20))
         * 
    */ static final ASN1ObjectIdentifier id_isismtt_at_iCCSN = id_isismtt_at.branch("6"); /** * * Reference for a file of a smartcard that stores the public key of this * certificate and that is used as �security anchor�. * *
         *      PKReferenceSyntax ::= OCTET STRING (SIZE(20))
         * 
    */ static final ASN1ObjectIdentifier id_isismtt_at_PKReference = id_isismtt_at.branch("7"); /** * Some other restriction regarding the usage of this certificate. May be * used as attribute in attribute certificate or as extension in a * certificate. * *
         *             RestrictionSyntax ::= DirectoryString (SIZE(1..1024))
         * 
    * * @see org.bouncycastle.asn1.isismtt.x509.Restriction */ static final ASN1ObjectIdentifier id_isismtt_at_restriction = id_isismtt_at.branch("8"); /** * * (Single)Request extension: Clients may include this extension in a * (single) Request to request the responder to send the certificate in the * response message along with the status information. Besides the LDAP * service, this extension provides another mechanism for the distribution * of certificates, which MAY optionally be provided by certificate * repositories. * *
         *        RetrieveIfAllowed ::= BOOLEAN
         *       
         * 
    */ static final ASN1ObjectIdentifier id_isismtt_at_retrieveIfAllowed = id_isismtt_at.branch("9"); /** * SingleOCSPResponse extension: The certificate requested by the client by * inserting the RetrieveIfAllowed extension in the request, will be * returned in this extension. * * @see org.bouncycastle.asn1.isismtt.ocsp.RequestedCertificate */ static final ASN1ObjectIdentifier id_isismtt_at_requestedCertificate = id_isismtt_at.branch("10"); /** * Base ObjectIdentifier for naming authorities */ static final ASN1ObjectIdentifier id_isismtt_at_namingAuthorities = id_isismtt_at.branch("11"); /** * SingleOCSPResponse extension: Date, when certificate has been published * in the directory and status information has become available. Currently, * accrediting authorities enforce that SigG-conforming OCSP servers include * this extension in the responses. * *
         *      CertInDirSince ::= GeneralizedTime
         * 
    */ static final ASN1ObjectIdentifier id_isismtt_at_certInDirSince = id_isismtt_at.branch("12"); /** * Hash of a certificate in OCSP. * * @see org.bouncycastle.asn1.isismtt.ocsp.CertHash */ static final ASN1ObjectIdentifier id_isismtt_at_certHash = id_isismtt_at.branch("13"); /** *
         *          NameAtBirth ::= DirectoryString(SIZE(1..64)
         * 
    * * Used in * {@link org.bouncycastle.asn1.x509.SubjectDirectoryAttributes SubjectDirectoryAttributes} */ static final ASN1ObjectIdentifier id_isismtt_at_nameAtBirth = id_isismtt_at.branch("14"); /** * Some other information of non-restrictive nature regarding the usage of * this certificate. May be used as attribute in atribute certificate or as * extension in a certificate. * *
         *               AdditionalInformationSyntax ::= DirectoryString (SIZE(1..2048))
         * 
    * * @see org.bouncycastle.asn1.isismtt.x509.AdditionalInformationSyntax */ static final ASN1ObjectIdentifier id_isismtt_at_additionalInformation = id_isismtt_at.branch("15"); /** * Indicates that an attribute certificate exists, which limits the * usability of this public key certificate. Whenever verifying a signature * with the help of this certificate, the content of the corresponding * attribute certificate should be concerned. This extension MUST be * included in a PKC, if a corresponding attribute certificate (having the * PKC as base certificate) contains some attribute that restricts the * usability of the PKC too. Attribute certificates with restricting content * MUST always be included in the signed document. * *
         *                   LiabilityLimitationFlagSyntax ::= BOOLEAN
         * 
    */ static final ASN1ObjectIdentifier id_isismtt_at_liabilityLimitationFlag = new ASN1ObjectIdentifier("0.2.262.1.10.12.0"); } bouncycastle-1.49.orig/src/org/bouncycastle/asn1/cmp/0000755000175000017500000000000012152033551022120 5ustar ebourgebourgbouncycastle-1.49.orig/src/org/bouncycastle/asn1/cmp/CMPCertificate.java0000644000175000017500000000470712062242174025560 0ustar ebourgebourgpackage org.bouncycastle.asn1.cmp; import org.bouncycastle.asn1.ASN1Choice; import org.bouncycastle.asn1.ASN1Object; import org.bouncycastle.asn1.ASN1Primitive; import org.bouncycastle.asn1.ASN1Sequence; import org.bouncycastle.asn1.ASN1TaggedObject; import org.bouncycastle.asn1.DERTaggedObject; import org.bouncycastle.asn1.x509.AttributeCertificate; import org.bouncycastle.asn1.x509.Certificate; public class CMPCertificate extends ASN1Object implements ASN1Choice { private Certificate x509v3PKCert; private AttributeCertificate x509v2AttrCert; /** * Note: the addition of attribute certificates is a BC extension. */ public CMPCertificate(AttributeCertificate x509v2AttrCert) { this.x509v2AttrCert = x509v2AttrCert; } public CMPCertificate(Certificate x509v3PKCert) { if (x509v3PKCert.getVersionNumber() != 3) { throw new IllegalArgumentException("only version 3 certificates allowed"); } this.x509v3PKCert = x509v3PKCert; } public static CMPCertificate getInstance(Object o) { if (o == null || o instanceof CMPCertificate) { return (CMPCertificate)o; } if (o instanceof ASN1Sequence || o instanceof byte[]) { return new CMPCertificate(Certificate.getInstance(o)); } if (o instanceof ASN1TaggedObject) { return new CMPCertificate(AttributeCertificate.getInstance(((ASN1TaggedObject)o).getObject())); } throw new IllegalArgumentException("Invalid object: " + o.getClass().getName()); } public boolean isX509v3PKCert() { return x509v3PKCert != null; } public Certificate getX509v3PKCert() { return x509v3PKCert; } public AttributeCertificate getX509v2AttrCert() { return x509v2AttrCert; } /** *
         * CMPCertificate ::= CHOICE {
         *            x509v3PKCert        Certificate
         *            x509v2AttrCert      [1] AttributeCertificate
         *  }
         * 
    * Note: the addition of attribute certificates is a BC extension. * * @return a basic ASN.1 object representation. */ public ASN1Primitive toASN1Primitive() { if (x509v2AttrCert != null) { // explicit following CMP conventions return new DERTaggedObject(true, 1, x509v2AttrCert); } return x509v3PKCert.toASN1Primitive(); } } bouncycastle-1.49.orig/src/org/bouncycastle/asn1/cmp/PKIHeaderBuilder.java0000644000175000017500000001727011737275254026055 0ustar ebourgebourgpackage org.bouncycastle.asn1.cmp; import org.bouncycastle.asn1.ASN1Encodable; import org.bouncycastle.asn1.ASN1EncodableVector; import org.bouncycastle.asn1.ASN1GeneralizedTime; import org.bouncycastle.asn1.ASN1Integer; import org.bouncycastle.asn1.ASN1OctetString; import org.bouncycastle.asn1.ASN1Sequence; import org.bouncycastle.asn1.DERGeneralizedTime; import org.bouncycastle.asn1.DEROctetString; import org.bouncycastle.asn1.DERSequence; import org.bouncycastle.asn1.DERTaggedObject; import org.bouncycastle.asn1.x509.AlgorithmIdentifier; import org.bouncycastle.asn1.x509.GeneralName; public class PKIHeaderBuilder { private ASN1Integer pvno; private GeneralName sender; private GeneralName recipient; private ASN1GeneralizedTime messageTime; private AlgorithmIdentifier protectionAlg; private ASN1OctetString senderKID; // KeyIdentifier private ASN1OctetString recipKID; // KeyIdentifier private ASN1OctetString transactionID; private ASN1OctetString senderNonce; private ASN1OctetString recipNonce; private PKIFreeText freeText; private ASN1Sequence generalInfo; public PKIHeaderBuilder( int pvno, GeneralName sender, GeneralName recipient) { this(new ASN1Integer(pvno), sender, recipient); } private PKIHeaderBuilder( ASN1Integer pvno, GeneralName sender, GeneralName recipient) { this.pvno = pvno; this.sender = sender; this.recipient = recipient; } /** * @deprecated use ASN1GeneralizedTime */ public PKIHeaderBuilder setMessageTime(DERGeneralizedTime time) { messageTime = ASN1GeneralizedTime.getInstance(time); return this; } public PKIHeaderBuilder setMessageTime(ASN1GeneralizedTime time) { messageTime = time; return this; } public PKIHeaderBuilder setProtectionAlg(AlgorithmIdentifier aid) { protectionAlg = aid; return this; } public PKIHeaderBuilder setSenderKID(byte[] kid) { return setSenderKID(kid == null ? null : new DEROctetString(kid)); } public PKIHeaderBuilder setSenderKID(ASN1OctetString kid) { senderKID = kid; return this; } public PKIHeaderBuilder setRecipKID(byte[] kid) { return setRecipKID(kid == null ? null : new DEROctetString(kid)); } public PKIHeaderBuilder setRecipKID(DEROctetString kid) { recipKID = kid; return this; } public PKIHeaderBuilder setTransactionID(byte[] tid) { return setTransactionID(tid == null ? null : new DEROctetString(tid)); } public PKIHeaderBuilder setTransactionID(ASN1OctetString tid) { transactionID = tid; return this; } public PKIHeaderBuilder setSenderNonce(byte[] nonce) { return setSenderNonce(nonce == null ? null : new DEROctetString(nonce)); } public PKIHeaderBuilder setSenderNonce(ASN1OctetString nonce) { senderNonce = nonce; return this; } public PKIHeaderBuilder setRecipNonce(byte[] nonce) { return setRecipNonce(nonce == null ? null : new DEROctetString(nonce)); } public PKIHeaderBuilder setRecipNonce(ASN1OctetString nonce) { recipNonce = nonce; return this; } public PKIHeaderBuilder setFreeText(PKIFreeText text) { freeText = text; return this; } public PKIHeaderBuilder setGeneralInfo(InfoTypeAndValue genInfo) { return setGeneralInfo(makeGeneralInfoSeq(genInfo)); } public PKIHeaderBuilder setGeneralInfo(InfoTypeAndValue[] genInfos) { return setGeneralInfo(makeGeneralInfoSeq(genInfos)); } public PKIHeaderBuilder setGeneralInfo(ASN1Sequence seqOfInfoTypeAndValue) { generalInfo = seqOfInfoTypeAndValue; return this; } private static ASN1Sequence makeGeneralInfoSeq( InfoTypeAndValue generalInfo) { return new DERSequence(generalInfo); } private static ASN1Sequence makeGeneralInfoSeq( InfoTypeAndValue[] generalInfos) { ASN1Sequence genInfoSeq = null; if (generalInfos != null) { ASN1EncodableVector v = new ASN1EncodableVector(); for (int i = 0; i < generalInfos.length; i++) { v.add(generalInfos[i]); } genInfoSeq = new DERSequence(v); } return genInfoSeq; } /** *
         *  PKIHeader ::= SEQUENCE {
         *            pvno                INTEGER     { cmp1999(1), cmp2000(2) },
         *            sender              GeneralName,
         *            -- identifies the sender
         *            recipient           GeneralName,
         *            -- identifies the intended recipient
         *            messageTime     [0] GeneralizedTime         OPTIONAL,
         *            -- time of production of this message (used when sender
         *            -- believes that the transport will be "suitable"; i.e.,
         *            -- that the time will still be meaningful upon receipt)
         *            protectionAlg   [1] AlgorithmIdentifier     OPTIONAL,
         *            -- algorithm used for calculation of protection bits
         *            senderKID       [2] KeyIdentifier           OPTIONAL,
         *            recipKID        [3] KeyIdentifier           OPTIONAL,
         *            -- to identify specific keys used for protection
         *            transactionID   [4] OCTET STRING            OPTIONAL,
         *            -- identifies the transaction; i.e., this will be the same in
         *            -- corresponding request, response, certConf, and PKIConf
         *            -- messages
         *            senderNonce     [5] OCTET STRING            OPTIONAL,
         *            recipNonce      [6] OCTET STRING            OPTIONAL,
         *            -- nonces used to provide replay protection, senderNonce
         *            -- is inserted by the creator of this message; recipNonce
         *            -- is a nonce previously inserted in a related message by
         *            -- the intended recipient of this message
         *            freeText        [7] PKIFreeText             OPTIONAL,
         *            -- this may be used to indicate context-specific instructions
         *            -- (this field is intended for human consumption)
         *            generalInfo     [8] SEQUENCE SIZE (1..MAX) OF
         *                                 InfoTypeAndValue     OPTIONAL
         *            -- this may be used to convey context-specific information
         *            -- (this field not primarily intended for human consumption)
         * }
         * 
    * @return a basic ASN.1 object representation. */ public PKIHeader build() { ASN1EncodableVector v = new ASN1EncodableVector(); v.add(pvno); v.add(sender); v.add(recipient); addOptional(v, 0, messageTime); addOptional(v, 1, protectionAlg); addOptional(v, 2, senderKID); addOptional(v, 3, recipKID); addOptional(v, 4, transactionID); addOptional(v, 5, senderNonce); addOptional(v, 6, recipNonce); addOptional(v, 7, freeText); addOptional(v, 8, generalInfo); messageTime = null; protectionAlg = null; senderKID = null; recipKID = null; transactionID = null; senderNonce = null; recipNonce = null; freeText = null; generalInfo = null; return PKIHeader.getInstance(new DERSequence(v)); } private void addOptional(ASN1EncodableVector v, int tagNo, ASN1Encodable obj) { if (obj != null) { v.add(new DERTaggedObject(true, tagNo, obj)); } } } bouncycastle-1.49.orig/src/org/bouncycastle/asn1/cmp/PKIMessages.java0000644000175000017500000000304011725267400025102 0ustar ebourgebourgpackage org.bouncycastle.asn1.cmp; import org.bouncycastle.asn1.ASN1EncodableVector; import org.bouncycastle.asn1.ASN1Object; import org.bouncycastle.asn1.ASN1Primitive; import org.bouncycastle.asn1.ASN1Sequence; import org.bouncycastle.asn1.DERSequence; public class PKIMessages extends ASN1Object { private ASN1Sequence content; private PKIMessages(ASN1Sequence seq) { content = seq; } public static PKIMessages getInstance(Object o) { if (o instanceof PKIMessages) { return (PKIMessages)o; } if (o != null) { return new PKIMessages(ASN1Sequence.getInstance(o)); } return null; } public PKIMessages(PKIMessage msg) { content = new DERSequence(msg); } public PKIMessages(PKIMessage[] msgs) { ASN1EncodableVector v = new ASN1EncodableVector(); for (int i = 0; i < msgs.length; i++) { v.add(msgs[i]); } content = new DERSequence(v); } public PKIMessage[] toPKIMessageArray() { PKIMessage[] result = new PKIMessage[content.size()]; for (int i = 0; i != result.length; i++) { result[i] = PKIMessage.getInstance(content.getObjectAt(i)); } return result; } /** *
         * PKIMessages ::= SEQUENCE SIZE (1..MAX) OF PKIMessage
         * 
    * @return a basic ASN.1 object representation. */ public ASN1Primitive toASN1Primitive() { return content; } } bouncycastle-1.49.orig/src/org/bouncycastle/asn1/cmp/RevRepContentBuilder.java0000644000175000017500000000304711624622713027043 0ustar ebourgebourgpackage org.bouncycastle.asn1.cmp; import org.bouncycastle.asn1.ASN1EncodableVector; import org.bouncycastle.asn1.DERSequence; import org.bouncycastle.asn1.DERTaggedObject; import org.bouncycastle.asn1.crmf.CertId; import org.bouncycastle.asn1.x509.CertificateList; public class RevRepContentBuilder { private ASN1EncodableVector status = new ASN1EncodableVector(); private ASN1EncodableVector revCerts = new ASN1EncodableVector(); private ASN1EncodableVector crls = new ASN1EncodableVector(); public RevRepContentBuilder add(PKIStatusInfo status) { this.status.add(status); return this; } public RevRepContentBuilder add(PKIStatusInfo status, CertId certId) { if (this.status.size() != this.revCerts.size()) { throw new IllegalStateException("status and revCerts sequence must be in common order"); } this.status.add(status); this.revCerts.add(certId); return this; } public RevRepContentBuilder addCrl(CertificateList crl) { this.crls.add(crl); return this; } public RevRepContent build() { ASN1EncodableVector v = new ASN1EncodableVector(); v.add(new DERSequence(status)); if (revCerts.size() != 0) { v.add(new DERTaggedObject(true, 0, new DERSequence(revCerts))); } if (crls.size() != 0) { v.add(new DERTaggedObject(true, 1, new DERSequence(crls))); } return RevRepContent.getInstance(new DERSequence(v)); } } bouncycastle-1.49.orig/src/org/bouncycastle/asn1/cmp/CertRepMessage.java0000644000175000017500000000612011725266120025640 0ustar ebourgebourgpackage org.bouncycastle.asn1.cmp; import org.bouncycastle.asn1.ASN1EncodableVector; import org.bouncycastle.asn1.ASN1Object; import org.bouncycastle.asn1.ASN1Primitive; import org.bouncycastle.asn1.ASN1Sequence; import org.bouncycastle.asn1.ASN1TaggedObject; import org.bouncycastle.asn1.DERSequence; import org.bouncycastle.asn1.DERTaggedObject; public class CertRepMessage extends ASN1Object { private ASN1Sequence caPubs; private ASN1Sequence response; private CertRepMessage(ASN1Sequence seq) { int index = 0; if (seq.size() > 1) { caPubs = ASN1Sequence.getInstance((ASN1TaggedObject)seq.getObjectAt(index++), true); } response = ASN1Sequence.getInstance(seq.getObjectAt(index)); } public static CertRepMessage getInstance(Object o) { if (o instanceof CertRepMessage) { return (CertRepMessage)o; } if (o != null) { return new CertRepMessage(ASN1Sequence.getInstance(o)); } return null; } public CertRepMessage(CMPCertificate[] caPubs, CertResponse[] response) { if (response == null) { throw new IllegalArgumentException("'response' cannot be null"); } if (caPubs != null) { ASN1EncodableVector v = new ASN1EncodableVector(); for (int i = 0; i < caPubs.length; i++) { v.add(caPubs[i]); } this.caPubs = new DERSequence(v); } { ASN1EncodableVector v = new ASN1EncodableVector(); for (int i = 0; i < response.length; i++) { v.add(response[i]); } this.response = new DERSequence(v); } } public CMPCertificate[] getCaPubs() { if (caPubs == null) { return null; } CMPCertificate[] results = new CMPCertificate[caPubs.size()]; for (int i = 0; i != results.length; i++) { results[i] = CMPCertificate.getInstance(caPubs.getObjectAt(i)); } return results; } public CertResponse[] getResponse() { CertResponse[] results = new CertResponse[response.size()]; for (int i = 0; i != results.length; i++) { results[i] = CertResponse.getInstance(response.getObjectAt(i)); } return results; } /** *
         * CertRepMessage ::= SEQUENCE {
         *                          caPubs       [1] SEQUENCE SIZE (1..MAX) OF CMPCertificate
         *                                                                             OPTIONAL,
         *                          response         SEQUENCE OF CertResponse
         * }
         * 
    * @return a basic ASN.1 object representation. */ public ASN1Primitive toASN1Primitive() { ASN1EncodableVector v = new ASN1EncodableVector(); if (caPubs != null) { v.add(new DERTaggedObject(true, 1, caPubs)); } v.add(response); return new DERSequence(v); } } bouncycastle-1.49.orig/src/org/bouncycastle/asn1/cmp/Challenge.java0000644000175000017500000000675711725326162024674 0ustar ebourgebourgpackage org.bouncycastle.asn1.cmp; import org.bouncycastle.asn1.ASN1Encodable; import org.bouncycastle.asn1.ASN1EncodableVector; import org.bouncycastle.asn1.ASN1Object; import org.bouncycastle.asn1.ASN1OctetString; import org.bouncycastle.asn1.ASN1Primitive; import org.bouncycastle.asn1.ASN1Sequence; import org.bouncycastle.asn1.DEROctetString; import org.bouncycastle.asn1.DERSequence; import org.bouncycastle.asn1.x509.AlgorithmIdentifier; public class Challenge extends ASN1Object { private AlgorithmIdentifier owf; private ASN1OctetString witness; private ASN1OctetString challenge; private Challenge(ASN1Sequence seq) { int index = 0; if (seq.size() == 3) { owf = AlgorithmIdentifier.getInstance(seq.getObjectAt(index++)); } witness = ASN1OctetString.getInstance(seq.getObjectAt(index++)); challenge = ASN1OctetString.getInstance(seq.getObjectAt(index)); } public static Challenge getInstance(Object o) { if (o instanceof Challenge) { return (Challenge)o; } if (o != null) { return new Challenge(ASN1Sequence.getInstance(o)); } return null; } public Challenge(byte[] witness, byte[] challenge) { this(null, witness, challenge); } public Challenge(AlgorithmIdentifier owf, byte[] witness, byte[] challenge) { this.owf = owf; this.witness = new DEROctetString(witness); this.challenge = new DEROctetString(challenge); } public AlgorithmIdentifier getOwf() { return owf; } public byte[] getWitness() { return witness.getOctets(); } public byte[] getChallenge() { return challenge.getOctets(); } /** *
         * Challenge ::= SEQUENCE {
         *                 owf                 AlgorithmIdentifier  OPTIONAL,
         *
         *                 -- MUST be present in the first Challenge; MAY be omitted in
         *                 -- any subsequent Challenge in POPODecKeyChallContent (if
         *                 -- omitted, then the owf used in the immediately preceding
         *                 -- Challenge is to be used).
         *
         *                 witness             OCTET STRING,
         *                 -- the result of applying the one-way function (owf) to a
         *                 -- randomly-generated INTEGER, A.  [Note that a different
         *                 -- INTEGER MUST be used for each Challenge.]
         *                 challenge           OCTET STRING
         *                 -- the encryption (under the public key for which the cert.
         *                 -- request is being made) of Rand, where Rand is specified as
         *                 --   Rand ::= SEQUENCE {
         *                 --      int      INTEGER,
         *                 --       - the randomly-generated INTEGER A (above)
         *                 --      sender   GeneralName
         *                 --       - the sender's name (as included in PKIHeader)
         *                 --   }
         *      }
         * 
    * @return a basic ASN.1 object representation. */ public ASN1Primitive toASN1Primitive() { ASN1EncodableVector v = new ASN1EncodableVector(); addOptional(v, owf); v.add(witness); v.add(challenge); return new DERSequence(v); } private void addOptional(ASN1EncodableVector v, ASN1Encodable obj) { if (obj != null) { v.add(obj); } } } bouncycastle-1.49.orig/src/org/bouncycastle/asn1/cmp/PKIStatus.java0000644000175000017500000000347511725267560024641 0ustar ebourgebourgpackage org.bouncycastle.asn1.cmp; import java.math.BigInteger; import org.bouncycastle.asn1.ASN1Integer; import org.bouncycastle.asn1.ASN1Object; import org.bouncycastle.asn1.ASN1Primitive; public class PKIStatus extends ASN1Object { public static final int GRANTED = 0; public static final int GRANTED_WITH_MODS = 1; public static final int REJECTION = 2; public static final int WAITING = 3; public static final int REVOCATION_WARNING = 4; public static final int REVOCATION_NOTIFICATION = 5; public static final int KEY_UPDATE_WARNING = 6; public static final PKIStatus granted = new PKIStatus(GRANTED); public static final PKIStatus grantedWithMods = new PKIStatus(GRANTED_WITH_MODS); public static final PKIStatus rejection = new PKIStatus(REJECTION); public static final PKIStatus waiting = new PKIStatus(WAITING); public static final PKIStatus revocationWarning = new PKIStatus(REVOCATION_WARNING); public static final PKIStatus revocationNotification = new PKIStatus(REVOCATION_NOTIFICATION); public static final PKIStatus keyUpdateWaiting = new PKIStatus(KEY_UPDATE_WARNING); private ASN1Integer value; private PKIStatus(int value) { this(new ASN1Integer(value)); } private PKIStatus(ASN1Integer value) { this.value = value; } public static PKIStatus getInstance(Object o) { if (o instanceof PKIStatus) { return (PKIStatus)o; } if (o != null) { return new PKIStatus(ASN1Integer.getInstance(o)); } return null; } public BigInteger getValue() { return value.getValue(); } public ASN1Primitive toASN1Primitive() { return value; } } bouncycastle-1.49.orig/src/org/bouncycastle/asn1/cmp/CertifiedKeyPair.java0000644000175000017500000000677511725266027026200 0ustar ebourgebourgpackage org.bouncycastle.asn1.cmp; import org.bouncycastle.asn1.ASN1EncodableVector; import org.bouncycastle.asn1.ASN1Object; import org.bouncycastle.asn1.ASN1Primitive; import org.bouncycastle.asn1.ASN1Sequence; import org.bouncycastle.asn1.ASN1TaggedObject; import org.bouncycastle.asn1.DERSequence; import org.bouncycastle.asn1.DERTaggedObject; import org.bouncycastle.asn1.crmf.EncryptedValue; import org.bouncycastle.asn1.crmf.PKIPublicationInfo; public class CertifiedKeyPair extends ASN1Object { private CertOrEncCert certOrEncCert; private EncryptedValue privateKey; private PKIPublicationInfo publicationInfo; private CertifiedKeyPair(ASN1Sequence seq) { certOrEncCert = CertOrEncCert.getInstance(seq.getObjectAt(0)); if (seq.size() >= 2) { if (seq.size() == 2) { ASN1TaggedObject tagged = ASN1TaggedObject.getInstance(seq.getObjectAt(1)); if (tagged.getTagNo() == 0) { privateKey = EncryptedValue.getInstance(tagged.getObject()); } else { publicationInfo = PKIPublicationInfo.getInstance(tagged.getObject()); } } else { privateKey = EncryptedValue.getInstance(ASN1TaggedObject.getInstance(seq.getObjectAt(1))); publicationInfo = PKIPublicationInfo.getInstance(ASN1TaggedObject.getInstance(seq.getObjectAt(2))); } } } public static CertifiedKeyPair getInstance(Object o) { if (o instanceof CertifiedKeyPair) { return (CertifiedKeyPair)o; } if (o != null) { return new CertifiedKeyPair(ASN1Sequence.getInstance(o)); } return null; } public CertifiedKeyPair( CertOrEncCert certOrEncCert) { this(certOrEncCert, null, null); } public CertifiedKeyPair( CertOrEncCert certOrEncCert, EncryptedValue privateKey, PKIPublicationInfo publicationInfo ) { if (certOrEncCert == null) { throw new IllegalArgumentException("'certOrEncCert' cannot be null"); } this.certOrEncCert = certOrEncCert; this.privateKey = privateKey; this.publicationInfo = publicationInfo; } public CertOrEncCert getCertOrEncCert() { return certOrEncCert; } public EncryptedValue getPrivateKey() { return privateKey; } public PKIPublicationInfo getPublicationInfo() { return publicationInfo; } /** *
         * CertifiedKeyPair ::= SEQUENCE {
         *                                  certOrEncCert       CertOrEncCert,
         *                                  privateKey      [0] EncryptedValue      OPTIONAL,
         *                                  -- see [CRMF] for comment on encoding
         *                                  publicationInfo [1] PKIPublicationInfo  OPTIONAL
         *       }
         * 
    * @return a basic ASN.1 object representation. */ public ASN1Primitive toASN1Primitive() { ASN1EncodableVector v = new ASN1EncodableVector(); v.add(certOrEncCert); if (privateKey != null) { v.add(new DERTaggedObject(true, 0, privateKey)); } if (publicationInfo != null) { v.add(new DERTaggedObject(true, 1, publicationInfo)); } return new DERSequence(v); } } bouncycastle-1.49.orig/src/org/bouncycastle/asn1/cmp/PBMParameter.java0000644000175000017500000000677711725266746025306 0ustar ebourgebourgpackage org.bouncycastle.asn1.cmp; import org.bouncycastle.asn1.ASN1EncodableVector; import org.bouncycastle.asn1.ASN1Integer; import org.bouncycastle.asn1.ASN1Object; import org.bouncycastle.asn1.ASN1OctetString; import org.bouncycastle.asn1.ASN1Primitive; import org.bouncycastle.asn1.ASN1Sequence; import org.bouncycastle.asn1.DEROctetString; import org.bouncycastle.asn1.DERSequence; import org.bouncycastle.asn1.x509.AlgorithmIdentifier; public class PBMParameter extends ASN1Object { private ASN1OctetString salt; private AlgorithmIdentifier owf; private ASN1Integer iterationCount; private AlgorithmIdentifier mac; private PBMParameter(ASN1Sequence seq) { salt = ASN1OctetString.getInstance(seq.getObjectAt(0)); owf = AlgorithmIdentifier.getInstance(seq.getObjectAt(1)); iterationCount = ASN1Integer.getInstance(seq.getObjectAt(2)); mac = AlgorithmIdentifier.getInstance(seq.getObjectAt(3)); } public static PBMParameter getInstance(Object o) { if (o instanceof PBMParameter) { return (PBMParameter)o; } if (o != null) { return new PBMParameter(ASN1Sequence.getInstance(o)); } return null; } public PBMParameter( byte[] salt, AlgorithmIdentifier owf, int iterationCount, AlgorithmIdentifier mac) { this(new DEROctetString(salt), owf, new ASN1Integer(iterationCount), mac); } public PBMParameter( ASN1OctetString salt, AlgorithmIdentifier owf, ASN1Integer iterationCount, AlgorithmIdentifier mac) { this.salt = salt; this.owf = owf; this.iterationCount = iterationCount; this.mac = mac; } public ASN1OctetString getSalt() { return salt; } public AlgorithmIdentifier getOwf() { return owf; } public ASN1Integer getIterationCount() { return iterationCount; } public AlgorithmIdentifier getMac() { return mac; } /** *
         *  PBMParameter ::= SEQUENCE {
         *                        salt                OCTET STRING,
         *                        -- note:  implementations MAY wish to limit acceptable sizes
         *                        -- of this string to values appropriate for their environment
         *                        -- in order to reduce the risk of denial-of-service attacks
         *                        owf                 AlgorithmIdentifier,
         *                        -- AlgId for a One-Way Function (SHA-1 recommended)
         *                        iterationCount      INTEGER,
         *                        -- number of times the OWF is applied
         *                        -- note:  implementations MAY wish to limit acceptable sizes
         *                        -- of this integer to values appropriate for their environment
         *                        -- in order to reduce the risk of denial-of-service attacks
         *                        mac                 AlgorithmIdentifier
         *                        -- the MAC AlgId (e.g., DES-MAC, Triple-DES-MAC [PKCS11],
         *    }   -- or HMAC [RFC2104, RFC2202])
         * 
    * @return a basic ASN.1 object representation. */ public ASN1Primitive toASN1Primitive() { ASN1EncodableVector v = new ASN1EncodableVector(); v.add(salt); v.add(owf); v.add(iterationCount); v.add(mac); return new DERSequence(v); } } bouncycastle-1.49.orig/src/org/bouncycastle/asn1/cmp/RevRepContent.java0000644000175000017500000000671511725270200025531 0ustar ebourgebourgpackage org.bouncycastle.asn1.cmp; import java.util.Enumeration; import org.bouncycastle.asn1.ASN1Encodable; import org.bouncycastle.asn1.ASN1EncodableVector; import org.bouncycastle.asn1.ASN1Object; import org.bouncycastle.asn1.ASN1Primitive; import org.bouncycastle.asn1.ASN1Sequence; import org.bouncycastle.asn1.ASN1TaggedObject; import org.bouncycastle.asn1.DERSequence; import org.bouncycastle.asn1.DERTaggedObject; import org.bouncycastle.asn1.crmf.CertId; import org.bouncycastle.asn1.x509.CertificateList; public class RevRepContent extends ASN1Object { private ASN1Sequence status; private ASN1Sequence revCerts; private ASN1Sequence crls; private RevRepContent(ASN1Sequence seq) { Enumeration en = seq.getObjects(); status = ASN1Sequence.getInstance(en.nextElement()); while (en.hasMoreElements()) { ASN1TaggedObject tObj = ASN1TaggedObject.getInstance(en.nextElement()); if (tObj.getTagNo() == 0) { revCerts = ASN1Sequence.getInstance(tObj, true); } else { crls = ASN1Sequence.getInstance(tObj, true); } } } public static RevRepContent getInstance(Object o) { if (o instanceof RevRepContent) { return (RevRepContent)o; } if (o != null) { return new RevRepContent(ASN1Sequence.getInstance(o)); } return null; } public PKIStatusInfo[] getStatus() { PKIStatusInfo[] results = new PKIStatusInfo[status.size()]; for (int i = 0; i != results.length; i++) { results[i] = PKIStatusInfo.getInstance(status.getObjectAt(i)); } return results; } public CertId[] getRevCerts() { if (revCerts == null) { return null; } CertId[] results = new CertId[revCerts.size()]; for (int i = 0; i != results.length; i++) { results[i] = CertId.getInstance(revCerts.getObjectAt(i)); } return results; } public CertificateList[] getCrls() { if (crls == null) { return null; } CertificateList[] results = new CertificateList[crls.size()]; for (int i = 0; i != results.length; i++) { results[i] = CertificateList.getInstance(crls.getObjectAt(i)); } return results; } /** *
         * RevRepContent ::= SEQUENCE {
         *        status       SEQUENCE SIZE (1..MAX) OF PKIStatusInfo,
         *        -- in same order as was sent in RevReqContent
         *        revCerts [0] SEQUENCE SIZE (1..MAX) OF CertId OPTIONAL,
         *        -- IDs for which revocation was requested
         *        -- (same order as status)
         *        crls     [1] SEQUENCE SIZE (1..MAX) OF CertificateList OPTIONAL
         *        -- the resulting CRLs (there may be more than one)
         *   }
         * 
    * @return a basic ASN.1 object representation. */ public ASN1Primitive toASN1Primitive() { ASN1EncodableVector v = new ASN1EncodableVector(); v.add(status); addOptional(v, 0, revCerts); addOptional(v, 1, crls); return new DERSequence(v); } private void addOptional(ASN1EncodableVector v, int tagNo, ASN1Encodable obj) { if (obj != null) { v.add(new DERTaggedObject(true, tagNo, obj)); } } } bouncycastle-1.49.orig/src/org/bouncycastle/asn1/cmp/POPODecKeyChallContent.java0000644000175000017500000000225311725267737027152 0ustar ebourgebourgpackage org.bouncycastle.asn1.cmp; import org.bouncycastle.asn1.ASN1Object; import org.bouncycastle.asn1.ASN1Primitive; import org.bouncycastle.asn1.ASN1Sequence; public class POPODecKeyChallContent extends ASN1Object { private ASN1Sequence content; private POPODecKeyChallContent(ASN1Sequence seq) { content = seq; } public static POPODecKeyChallContent getInstance(Object o) { if (o instanceof POPODecKeyChallContent) { return (POPODecKeyChallContent)o; } if (o != null) { return new POPODecKeyChallContent(ASN1Sequence.getInstance(o)); } return null; } public Challenge[] toChallengeArray() { Challenge[] result = new Challenge[content.size()]; for (int i = 0; i != result.length; i++) { result[i] = Challenge.getInstance(content.getObjectAt(i)); } return result; } /** *
         * POPODecKeyChallContent ::= SEQUENCE OF Challenge
         * 
    * @return a basic ASN.1 object representation. */ public ASN1Primitive toASN1Primitive() { return content; } } bouncycastle-1.49.orig/src/org/bouncycastle/asn1/cmp/PKIMessage.java0000644000175000017500000001005512151253000024704 0ustar ebourgebourgpackage org.bouncycastle.asn1.cmp; import java.util.Enumeration; import org.bouncycastle.asn1.ASN1Encodable; import org.bouncycastle.asn1.ASN1EncodableVector; import org.bouncycastle.asn1.ASN1Object; import org.bouncycastle.asn1.ASN1Primitive; import org.bouncycastle.asn1.ASN1Sequence; import org.bouncycastle.asn1.ASN1TaggedObject; import org.bouncycastle.asn1.DERBitString; import org.bouncycastle.asn1.DERSequence; import org.bouncycastle.asn1.DERTaggedObject; public class PKIMessage extends ASN1Object { private PKIHeader header; private PKIBody body; private DERBitString protection; private ASN1Sequence extraCerts; private PKIMessage(ASN1Sequence seq) { Enumeration en = seq.getObjects(); header = PKIHeader.getInstance(en.nextElement()); body = PKIBody.getInstance(en.nextElement()); while (en.hasMoreElements()) { ASN1TaggedObject tObj = (ASN1TaggedObject)en.nextElement(); if (tObj.getTagNo() == 0) { protection = DERBitString.getInstance(tObj, true); } else { extraCerts = ASN1Sequence.getInstance(tObj, true); } } } public static PKIMessage getInstance(Object o) { if (o instanceof PKIMessage) { return (PKIMessage)o; } else if (o != null) { return new PKIMessage(ASN1Sequence.getInstance(o)); } return null; } /** * Creates a new PKIMessage. * * @param header message header * @param body message body * @param protection message protection (may be null) * @param extraCerts extra certificates (may be null) */ public PKIMessage( PKIHeader header, PKIBody body, DERBitString protection, CMPCertificate[] extraCerts) { this.header = header; this.body = body; this.protection = protection; if (extraCerts != null) { ASN1EncodableVector v = new ASN1EncodableVector(); for (int i = 0; i < extraCerts.length; i++) { v.add(extraCerts[i]); } this.extraCerts = new DERSequence(v); } } public PKIMessage( PKIHeader header, PKIBody body, DERBitString protection) { this(header, body, protection, null); } public PKIMessage( PKIHeader header, PKIBody body) { this(header, body, null, null); } public PKIHeader getHeader() { return header; } public PKIBody getBody() { return body; } public DERBitString getProtection() { return protection; } public CMPCertificate[] getExtraCerts() { if (extraCerts == null) { return null; } CMPCertificate[] results = new CMPCertificate[extraCerts.size()]; for (int i = 0; i < results.length; i++) { results[i] = CMPCertificate.getInstance(extraCerts.getObjectAt(i)); } return results; } /** *
         * PKIMessage ::= SEQUENCE {
         *                  header           PKIHeader,
         *                  body             PKIBody,
         *                  protection   [0] PKIProtection OPTIONAL,
         *                  extraCerts   [1] SEQUENCE SIZE (1..MAX) OF CMPCertificate
         *                                                                     OPTIONAL
         * }
         * 
    * * @return a basic ASN.1 object representation. */ public ASN1Primitive toASN1Primitive() { ASN1EncodableVector v = new ASN1EncodableVector(); v.add(header); v.add(body); addOptional(v, 0, protection); addOptional(v, 1, extraCerts); return new DERSequence(v); } private void addOptional(ASN1EncodableVector v, int tagNo, ASN1Encodable obj) { if (obj != null) { v.add(new DERTaggedObject(true, tagNo, obj)); } } } bouncycastle-1.49.orig/src/org/bouncycastle/asn1/cmp/PollRepContent.java0000644000175000017500000000575112075141472025711 0ustar ebourgebourgpackage org.bouncycastle.asn1.cmp; import org.bouncycastle.asn1.ASN1EncodableVector; import org.bouncycastle.asn1.ASN1Integer; import org.bouncycastle.asn1.ASN1Object; import org.bouncycastle.asn1.ASN1Primitive; import org.bouncycastle.asn1.ASN1Sequence; import org.bouncycastle.asn1.DERSequence; public class PollRepContent extends ASN1Object { private ASN1Integer[] certReqId; private ASN1Integer[] checkAfter; private PKIFreeText[] reason; private PollRepContent(ASN1Sequence seq) { certReqId = new ASN1Integer[seq.size()]; checkAfter = new ASN1Integer[seq.size()]; reason = new PKIFreeText[seq.size()]; for (int i = 0; i != seq.size(); i++) { ASN1Sequence s = ASN1Sequence.getInstance(seq.getObjectAt(i)); certReqId[i] = ASN1Integer.getInstance(s.getObjectAt(0)); checkAfter[i] = ASN1Integer.getInstance(s.getObjectAt(1)); if (s.size() > 2) { reason[i] = PKIFreeText.getInstance(s.getObjectAt(2)); } } } public static PollRepContent getInstance(Object o) { if (o instanceof PollRepContent) { return (PollRepContent)o; } if (o != null) { return new PollRepContent(ASN1Sequence.getInstance(o)); } return null; } public PollRepContent(ASN1Integer certReqId, ASN1Integer checkAfter) { this(certReqId, checkAfter, null); } public PollRepContent(ASN1Integer certReqId, ASN1Integer checkAfter, PKIFreeText reason) { this.certReqId = new ASN1Integer[1]; this.checkAfter = new ASN1Integer[1]; this.reason = new PKIFreeText[1]; this.certReqId[0] = certReqId; this.checkAfter[0] = checkAfter; this.reason[0] = reason; } public int size() { return certReqId.length; } public ASN1Integer getCertReqId(int index) { return certReqId[index]; } public ASN1Integer getCheckAfter(int index) { return checkAfter[index]; } public PKIFreeText getReason(int index) { return reason[index]; } /** *
         * PollRepContent ::= SEQUENCE OF SEQUENCE {
         *         certReqId              INTEGER,
         *         checkAfter             INTEGER,  -- time in seconds
         *         reason                 PKIFreeText OPTIONAL
         *     }
         * 
    * @return a basic ASN.1 object representation. */ public ASN1Primitive toASN1Primitive() { ASN1EncodableVector outer = new ASN1EncodableVector(); for (int i = 0; i != certReqId.length; i++) { ASN1EncodableVector v = new ASN1EncodableVector(); v.add(certReqId[i]); v.add(checkAfter[i]); if (reason[i] != null) { v.add(reason[i]); } outer.add(new DERSequence(v)); } return new DERSequence(outer); } } bouncycastle-1.49.orig/src/org/bouncycastle/asn1/cmp/OOBCertHash.java0000644000175000017500000000575612057025431025043 0ustar ebourgebourgpackage org.bouncycastle.asn1.cmp; import org.bouncycastle.asn1.ASN1Encodable; import org.bouncycastle.asn1.ASN1EncodableVector; import org.bouncycastle.asn1.ASN1Object; import org.bouncycastle.asn1.ASN1Primitive; import org.bouncycastle.asn1.ASN1Sequence; import org.bouncycastle.asn1.ASN1TaggedObject; import org.bouncycastle.asn1.DERBitString; import org.bouncycastle.asn1.DERSequence; import org.bouncycastle.asn1.DERTaggedObject; import org.bouncycastle.asn1.crmf.CertId; import org.bouncycastle.asn1.x509.AlgorithmIdentifier; public class OOBCertHash extends ASN1Object { private AlgorithmIdentifier hashAlg; private CertId certId; private DERBitString hashVal; private OOBCertHash(ASN1Sequence seq) { int index = seq.size() - 1; hashVal = DERBitString.getInstance(seq.getObjectAt(index--)); for (int i = index; i >= 0; i--) { ASN1TaggedObject tObj = (ASN1TaggedObject)seq.getObjectAt(i); if (tObj.getTagNo() == 0) { hashAlg = AlgorithmIdentifier.getInstance(tObj, true); } else { certId = CertId.getInstance(tObj, true); } } } public static OOBCertHash getInstance(Object o) { if (o instanceof OOBCertHash) { return (OOBCertHash)o; } if (o != null) { return new OOBCertHash(ASN1Sequence.getInstance(o)); } return null; } public OOBCertHash(AlgorithmIdentifier hashAlg, CertId certId, byte[] hashVal) { this(hashAlg, certId, new DERBitString(hashVal)); } public OOBCertHash(AlgorithmIdentifier hashAlg, CertId certId, DERBitString hashVal) { this.hashAlg = hashAlg; this.certId = certId; this.hashVal = hashVal; } public AlgorithmIdentifier getHashAlg() { return hashAlg; } public CertId getCertId() { return certId; } public DERBitString getHashVal() { return hashVal; } /** *
         * OOBCertHash ::= SEQUENCE {
         *                      hashAlg     [0] AlgorithmIdentifier     OPTIONAL,
         *                      certId      [1] CertId                  OPTIONAL,
         *                      hashVal         BIT STRING
         *                      -- hashVal is calculated over the DER encoding of the
         *                      -- self-signed certificate with the identifier certID.
         *       }
         * 
    * @return a basic ASN.1 object representation. */ public ASN1Primitive toASN1Primitive() { ASN1EncodableVector v = new ASN1EncodableVector(); addOptional(v, 0, hashAlg); addOptional(v, 1, certId); v.add(hashVal); return new DERSequence(v); } private void addOptional(ASN1EncodableVector v, int tagNo, ASN1Encodable obj) { if (obj != null) { v.add(new DERTaggedObject(true, tagNo, obj)); } } } bouncycastle-1.49.orig/src/org/bouncycastle/asn1/cmp/RevDetails.java0000644000175000017500000000521312030442726025031 0ustar ebourgebourgpackage org.bouncycastle.asn1.cmp; import org.bouncycastle.asn1.ASN1EncodableVector; import org.bouncycastle.asn1.ASN1Object; import org.bouncycastle.asn1.ASN1Primitive; import org.bouncycastle.asn1.ASN1Sequence; import org.bouncycastle.asn1.DERSequence; import org.bouncycastle.asn1.crmf.CertTemplate; import org.bouncycastle.asn1.x509.Extensions; import org.bouncycastle.asn1.x509.X509Extensions; public class RevDetails extends ASN1Object { private CertTemplate certDetails; private Extensions crlEntryDetails; private RevDetails(ASN1Sequence seq) { certDetails = CertTemplate.getInstance(seq.getObjectAt(0)); if (seq.size() > 1) { crlEntryDetails = Extensions.getInstance(seq.getObjectAt(1)); } } public static RevDetails getInstance(Object o) { if (o instanceof RevDetails) { return (RevDetails)o; } if (o != null) { return new RevDetails(ASN1Sequence.getInstance(o)); } return null; } public RevDetails(CertTemplate certDetails) { this.certDetails = certDetails; } /** * @deprecated use method taking Extensions * @param certDetails * @param crlEntryDetails */ public RevDetails(CertTemplate certDetails, X509Extensions crlEntryDetails) { this.certDetails = certDetails; this.crlEntryDetails = Extensions.getInstance(crlEntryDetails.toASN1Primitive()); } public RevDetails(CertTemplate certDetails, Extensions crlEntryDetails) { this.certDetails = certDetails; this.crlEntryDetails = crlEntryDetails; } public CertTemplate getCertDetails() { return certDetails; } public Extensions getCrlEntryDetails() { return crlEntryDetails; } /** *
         * RevDetails ::= SEQUENCE {
         *                  certDetails         CertTemplate,
         *                   -- allows requester to specify as much as they can about
         *                   -- the cert. for which revocation is requested
         *                   -- (e.g., for cases in which serialNumber is not available)
         *                   crlEntryDetails     Extensions       OPTIONAL
         *                   -- requested crlEntryExtensions
         *             }
         * 
    * @return a basic ASN.1 object representation. */ public ASN1Primitive toASN1Primitive() { ASN1EncodableVector v = new ASN1EncodableVector(); v.add(certDetails); if (crlEntryDetails != null) { v.add(crlEntryDetails); } return new DERSequence(v); } } bouncycastle-1.49.orig/src/org/bouncycastle/asn1/cmp/GenRepContent.java0000644000175000017500000000312111725266523025507 0ustar ebourgebourgpackage org.bouncycastle.asn1.cmp; import org.bouncycastle.asn1.ASN1EncodableVector; import org.bouncycastle.asn1.ASN1Object; import org.bouncycastle.asn1.ASN1Primitive; import org.bouncycastle.asn1.ASN1Sequence; import org.bouncycastle.asn1.DERSequence; public class GenRepContent extends ASN1Object { private ASN1Sequence content; private GenRepContent(ASN1Sequence seq) { content = seq; } public static GenRepContent getInstance(Object o) { if (o instanceof GenRepContent) { return (GenRepContent)o; } if (o != null) { return new GenRepContent(ASN1Sequence.getInstance(o)); } return null; } public GenRepContent(InfoTypeAndValue itv) { content = new DERSequence(itv); } public GenRepContent(InfoTypeAndValue[] itv) { ASN1EncodableVector v = new ASN1EncodableVector(); for (int i = 0; i < itv.length; i++) { v.add(itv[i]); } content = new DERSequence(v); } public InfoTypeAndValue[] toInfoTypeAndValueArray() { InfoTypeAndValue[] result = new InfoTypeAndValue[content.size()]; for (int i = 0; i != result.length; i++) { result[i] = InfoTypeAndValue.getInstance(content.getObjectAt(i)); } return result; } /** *
         * GenRepContent ::= SEQUENCE OF InfoTypeAndValue
         * 
    * @return a basic ASN.1 object representation. */ public ASN1Primitive toASN1Primitive() { return content; } } bouncycastle-1.49.orig/src/org/bouncycastle/asn1/cmp/CertStatus.java0000644000175000017500000000516611725266222025104 0ustar ebourgebourgpackage org.bouncycastle.asn1.cmp; import java.math.BigInteger; import org.bouncycastle.asn1.ASN1EncodableVector; import org.bouncycastle.asn1.ASN1Integer; import org.bouncycastle.asn1.ASN1Object; import org.bouncycastle.asn1.ASN1OctetString; import org.bouncycastle.asn1.ASN1Primitive; import org.bouncycastle.asn1.ASN1Sequence; import org.bouncycastle.asn1.DEROctetString; import org.bouncycastle.asn1.DERSequence; public class CertStatus extends ASN1Object { private ASN1OctetString certHash; private ASN1Integer certReqId; private PKIStatusInfo statusInfo; private CertStatus(ASN1Sequence seq) { certHash = ASN1OctetString.getInstance(seq.getObjectAt(0)); certReqId = ASN1Integer.getInstance(seq.getObjectAt(1)); if (seq.size() > 2) { statusInfo = PKIStatusInfo.getInstance(seq.getObjectAt(2)); } } public CertStatus(byte[] certHash, BigInteger certReqId) { this.certHash = new DEROctetString(certHash); this.certReqId = new ASN1Integer(certReqId); } public CertStatus(byte[] certHash, BigInteger certReqId, PKIStatusInfo statusInfo) { this.certHash = new DEROctetString(certHash); this.certReqId = new ASN1Integer(certReqId); this.statusInfo = statusInfo; } public static CertStatus getInstance(Object o) { if (o instanceof CertStatus) { return (CertStatus)o; } if (o != null) { return new CertStatus(ASN1Sequence.getInstance(o)); } return null; } public ASN1OctetString getCertHash() { return certHash; } public ASN1Integer getCertReqId() { return certReqId; } public PKIStatusInfo getStatusInfo() { return statusInfo; } /** *
         * CertStatus ::= SEQUENCE {
         *                   certHash    OCTET STRING,
         *                   -- the hash of the certificate, using the same hash algorithm
         *                   -- as is used to create and verify the certificate signature
         *                   certReqId   INTEGER,
         *                   -- to match this confirmation with the corresponding req/rep
         *                   statusInfo  PKIStatusInfo OPTIONAL
         * }
         * 
    * @return a basic ASN.1 object representation. */ public ASN1Primitive toASN1Primitive() { ASN1EncodableVector v = new ASN1EncodableVector(); v.add(certHash); v.add(certReqId); if (statusInfo != null) { v.add(statusInfo); } return new DERSequence(v); } } bouncycastle-1.49.orig/src/org/bouncycastle/asn1/cmp/RevAnnContent.java0000644000175000017500000000503111737275254025526 0ustar ebourgebourgpackage org.bouncycastle.asn1.cmp; import org.bouncycastle.asn1.ASN1EncodableVector; import org.bouncycastle.asn1.ASN1GeneralizedTime; import org.bouncycastle.asn1.ASN1Object; import org.bouncycastle.asn1.ASN1Primitive; import org.bouncycastle.asn1.ASN1Sequence; import org.bouncycastle.asn1.DERSequence; import org.bouncycastle.asn1.crmf.CertId; import org.bouncycastle.asn1.x509.Extensions; public class RevAnnContent extends ASN1Object { private PKIStatus status; private CertId certId; private ASN1GeneralizedTime willBeRevokedAt; private ASN1GeneralizedTime badSinceDate; private Extensions crlDetails; private RevAnnContent(ASN1Sequence seq) { status = PKIStatus.getInstance(seq.getObjectAt(0)); certId = CertId.getInstance(seq.getObjectAt(1)); willBeRevokedAt = ASN1GeneralizedTime.getInstance(seq.getObjectAt(2)); badSinceDate = ASN1GeneralizedTime.getInstance(seq.getObjectAt(3)); if (seq.size() > 4) { crlDetails = Extensions.getInstance(seq.getObjectAt(4)); } } public static RevAnnContent getInstance(Object o) { if (o instanceof RevAnnContent) { return (RevAnnContent)o; } if (o != null) { return new RevAnnContent(ASN1Sequence.getInstance(o)); } return null; } public PKIStatus getStatus() { return status; } public CertId getCertId() { return certId; } public ASN1GeneralizedTime getWillBeRevokedAt() { return willBeRevokedAt; } public ASN1GeneralizedTime getBadSinceDate() { return badSinceDate; } public Extensions getCrlDetails() { return crlDetails; } /** *
         * RevAnnContent ::= SEQUENCE {
         *       status              PKIStatus,
         *       certId              CertId,
         *       willBeRevokedAt     GeneralizedTime,
         *       badSinceDate        GeneralizedTime,
         *       crlDetails          Extensions  OPTIONAL
         *        -- extra CRL details (e.g., crl number, reason, location, etc.)
         * }
         * 
    * @return a basic ASN.1 object representation. */ public ASN1Primitive toASN1Primitive() { ASN1EncodableVector v = new ASN1EncodableVector(); v.add(status); v.add(certId); v.add(willBeRevokedAt); v.add(badSinceDate); if (crlDetails != null) { v.add(crlDetails); } return new DERSequence(v); } } bouncycastle-1.49.orig/src/org/bouncycastle/asn1/cmp/ProtectedPart.java0000644000175000017500000000276211725270042025555 0ustar ebourgebourgpackage org.bouncycastle.asn1.cmp; import org.bouncycastle.asn1.ASN1EncodableVector; import org.bouncycastle.asn1.ASN1Object; import org.bouncycastle.asn1.ASN1Primitive; import org.bouncycastle.asn1.ASN1Sequence; import org.bouncycastle.asn1.DERSequence; public class ProtectedPart extends ASN1Object { private PKIHeader header; private PKIBody body; private ProtectedPart(ASN1Sequence seq) { header = PKIHeader.getInstance(seq.getObjectAt(0)); body = PKIBody.getInstance(seq.getObjectAt(1)); } public static ProtectedPart getInstance(Object o) { if (o instanceof ProtectedPart) { return (ProtectedPart)o; } if (o != null) { return new ProtectedPart(ASN1Sequence.getInstance(o)); } return null; } public ProtectedPart(PKIHeader header, PKIBody body) { this.header = header; this.body = body; } public PKIHeader getHeader() { return header; } public PKIBody getBody() { return body; } /** *
         * ProtectedPart ::= SEQUENCE {
         *                    header    PKIHeader,
         *                    body      PKIBody
         * }
         * 
    * @return a basic ASN.1 object representation. */ public ASN1Primitive toASN1Primitive() { ASN1EncodableVector v = new ASN1EncodableVector(); v.add(header); v.add(body); return new DERSequence(v); } } bouncycastle-1.49.orig/src/org/bouncycastle/asn1/cmp/PKIFreeText.java0000644000175000017500000000501312151274316025061 0ustar ebourgebourgpackage org.bouncycastle.asn1.cmp; import java.util.Enumeration; import org.bouncycastle.asn1.ASN1EncodableVector; import org.bouncycastle.asn1.ASN1Object; import org.bouncycastle.asn1.ASN1Primitive; import org.bouncycastle.asn1.ASN1Sequence; import org.bouncycastle.asn1.ASN1TaggedObject; import org.bouncycastle.asn1.DERSequence; import org.bouncycastle.asn1.DERUTF8String; public class PKIFreeText extends ASN1Object { ASN1Sequence strings; public static PKIFreeText getInstance( ASN1TaggedObject obj, boolean explicit) { return getInstance(ASN1Sequence.getInstance(obj, explicit)); } public static PKIFreeText getInstance( Object obj) { if (obj instanceof PKIFreeText) { return (PKIFreeText)obj; } else if (obj != null) { return new PKIFreeText(ASN1Sequence.getInstance(obj)); } return null; } private PKIFreeText( ASN1Sequence seq) { Enumeration e = seq.getObjects(); while (e.hasMoreElements()) { if (!(e.nextElement() instanceof DERUTF8String)) { throw new IllegalArgumentException("attempt to insert non UTF8 STRING into PKIFreeText"); } } strings = seq; } public PKIFreeText( DERUTF8String p) { strings = new DERSequence(p); } public PKIFreeText( String p) { this(new DERUTF8String(p)); } public PKIFreeText( DERUTF8String[] strs) { strings = new DERSequence(strs); } public PKIFreeText( String[] strs) { ASN1EncodableVector v = new ASN1EncodableVector(); for (int i = 0; i < strs.length; i++) { v.add(new DERUTF8String(strs[i])); } strings = new DERSequence(v); } /** * Return the number of string elements present. * * @return number of elements present. */ public int size() { return strings.size(); } /** * Return the UTF8STRING at index i. * * @param i index of the string of interest * @return the string at index i. */ public DERUTF8String getStringAt( int i) { return (DERUTF8String)strings.getObjectAt(i); } /** *
         * PKIFreeText ::= SEQUENCE SIZE (1..MAX) OF UTF8String
         * 
    */ public ASN1Primitive toASN1Primitive() { return strings; } } bouncycastle-1.49.orig/src/org/bouncycastle/asn1/cmp/KeyRecRepContent.java0000644000175000017500000000737611725266625026203 0ustar ebourgebourgpackage org.bouncycastle.asn1.cmp; import java.util.Enumeration; import org.bouncycastle.asn1.ASN1Encodable; import org.bouncycastle.asn1.ASN1EncodableVector; import org.bouncycastle.asn1.ASN1Object; import org.bouncycastle.asn1.ASN1Primitive; import org.bouncycastle.asn1.ASN1Sequence; import org.bouncycastle.asn1.ASN1TaggedObject; import org.bouncycastle.asn1.DERSequence; import org.bouncycastle.asn1.DERTaggedObject; public class KeyRecRepContent extends ASN1Object { private PKIStatusInfo status; private CMPCertificate newSigCert; private ASN1Sequence caCerts; private ASN1Sequence keyPairHist; private KeyRecRepContent(ASN1Sequence seq) { Enumeration en = seq.getObjects(); status = PKIStatusInfo.getInstance(en.nextElement()); while (en.hasMoreElements()) { ASN1TaggedObject tObj = ASN1TaggedObject.getInstance(en.nextElement()); switch (tObj.getTagNo()) { case 0: newSigCert = CMPCertificate.getInstance(tObj.getObject()); break; case 1: caCerts = ASN1Sequence.getInstance(tObj.getObject()); break; case 2: keyPairHist = ASN1Sequence.getInstance(tObj.getObject()); break; default: throw new IllegalArgumentException("unknown tag number: " + tObj.getTagNo()); } } } public static KeyRecRepContent getInstance(Object o) { if (o instanceof KeyRecRepContent) { return (KeyRecRepContent)o; } if (o != null) { return new KeyRecRepContent(ASN1Sequence.getInstance(o)); } return null; } public PKIStatusInfo getStatus() { return status; } public CMPCertificate getNewSigCert() { return newSigCert; } public CMPCertificate[] getCaCerts() { if (caCerts == null) { return null; } CMPCertificate[] results = new CMPCertificate[caCerts.size()]; for (int i = 0; i != results.length; i++) { results[i] = CMPCertificate.getInstance(caCerts.getObjectAt(i)); } return results; } public CertifiedKeyPair[] getKeyPairHist() { if (keyPairHist == null) { return null; } CertifiedKeyPair[] results = new CertifiedKeyPair[keyPairHist.size()]; for (int i = 0; i != results.length; i++) { results[i] = CertifiedKeyPair.getInstance(keyPairHist.getObjectAt(i)); } return results; } /** *
         * KeyRecRepContent ::= SEQUENCE {
         *                         status                  PKIStatusInfo,
         *                         newSigCert          [0] CMPCertificate OPTIONAL,
         *                         caCerts             [1] SEQUENCE SIZE (1..MAX) OF
         *                                                           CMPCertificate OPTIONAL,
         *                         keyPairHist         [2] SEQUENCE SIZE (1..MAX) OF
         *                                                           CertifiedKeyPair OPTIONAL
         *              }
         * 
    * @return a basic ASN.1 object representation. */ public ASN1Primitive toASN1Primitive() { ASN1EncodableVector v = new ASN1EncodableVector(); v.add(status); addOptional(v, 0, newSigCert); addOptional(v, 1, caCerts); addOptional(v, 2, keyPairHist); return new DERSequence(v); } private void addOptional(ASN1EncodableVector v, int tagNo, ASN1Encodable obj) { if (obj != null) { v.add(new DERTaggedObject(true, tagNo, obj)); } } } bouncycastle-1.49.orig/src/org/bouncycastle/asn1/cmp/PKIConfirmContent.java0000644000175000017500000000201311725267125026266 0ustar ebourgebourgpackage org.bouncycastle.asn1.cmp; import org.bouncycastle.asn1.ASN1Null; import org.bouncycastle.asn1.ASN1Object; import org.bouncycastle.asn1.ASN1Primitive; import org.bouncycastle.asn1.DERNull; public class PKIConfirmContent extends ASN1Object { private ASN1Null val; private PKIConfirmContent(ASN1Null val) { this.val = val; } public static PKIConfirmContent getInstance(Object o) { if (o == null || o instanceof PKIConfirmContent) { return (PKIConfirmContent)o; } if (o instanceof ASN1Null) { return new PKIConfirmContent((ASN1Null)o); } throw new IllegalArgumentException("Invalid object: " + o.getClass().getName()); } public PKIConfirmContent() { val = DERNull.INSTANCE; } /** *
         * PKIConfirmContent ::= NULL
         * 
    * @return a basic ASN.1 object representation. */ public ASN1Primitive toASN1Primitive() { return val; } } bouncycastle-1.49.orig/src/org/bouncycastle/asn1/cmp/InfoTypeAndValue.java0000644000175000017500000001005611725266566026165 0ustar ebourgebourgpackage org.bouncycastle.asn1.cmp; import org.bouncycastle.asn1.ASN1Encodable; import org.bouncycastle.asn1.ASN1EncodableVector; import org.bouncycastle.asn1.ASN1Object; import org.bouncycastle.asn1.ASN1ObjectIdentifier; import org.bouncycastle.asn1.ASN1Primitive; import org.bouncycastle.asn1.ASN1Sequence; import org.bouncycastle.asn1.DERSequence; /** * Example InfoTypeAndValue contents include, but are not limited * to, the following (un-comment in this ASN.1 module and use as * appropriate for a given environment): *
     *   id-it-caProtEncCert    OBJECT IDENTIFIER ::= {id-it 1}
     *      CAProtEncCertValue      ::= CMPCertificate
     *   id-it-signKeyPairTypes OBJECT IDENTIFIER ::= {id-it 2}
     *     SignKeyPairTypesValue   ::= SEQUENCE OF AlgorithmIdentifier
     *   id-it-encKeyPairTypes  OBJECT IDENTIFIER ::= {id-it 3}
     *     EncKeyPairTypesValue    ::= SEQUENCE OF AlgorithmIdentifier
     *   id-it-preferredSymmAlg OBJECT IDENTIFIER ::= {id-it 4}
     *      PreferredSymmAlgValue   ::= AlgorithmIdentifier
     *   id-it-caKeyUpdateInfo  OBJECT IDENTIFIER ::= {id-it 5}
     *      CAKeyUpdateInfoValue    ::= CAKeyUpdAnnContent
     *   id-it-currentCRL       OBJECT IDENTIFIER ::= {id-it 6}
     *      CurrentCRLValue         ::= CertificateList
     *   id-it-unsupportedOIDs  OBJECT IDENTIFIER ::= {id-it 7}
     *      UnsupportedOIDsValue    ::= SEQUENCE OF OBJECT IDENTIFIER
     *   id-it-keyPairParamReq  OBJECT IDENTIFIER ::= {id-it 10}
     *      KeyPairParamReqValue    ::= OBJECT IDENTIFIER
     *   id-it-keyPairParamRep  OBJECT IDENTIFIER ::= {id-it 11}
     *      KeyPairParamRepValue    ::= AlgorithmIdentifer
     *   id-it-revPassphrase    OBJECT IDENTIFIER ::= {id-it 12}
     *      RevPassphraseValue      ::= EncryptedValue
     *   id-it-implicitConfirm  OBJECT IDENTIFIER ::= {id-it 13}
     *      ImplicitConfirmValue    ::= NULL
     *   id-it-confirmWaitTime  OBJECT IDENTIFIER ::= {id-it 14}
     *      ConfirmWaitTimeValue    ::= GeneralizedTime
     *   id-it-origPKIMessage   OBJECT IDENTIFIER ::= {id-it 15}
     *      OrigPKIMessageValue     ::= PKIMessages
     *   id-it-suppLangTags     OBJECT IDENTIFIER ::= {id-it 16}
     *      SuppLangTagsValue       ::= SEQUENCE OF UTF8String
     *
     * where
     *
     *   id-pkix OBJECT IDENTIFIER ::= {
     *      iso(1) identified-organization(3)
     *      dod(6) internet(1) security(5) mechanisms(5) pkix(7)}
     * and
     *      id-it   OBJECT IDENTIFIER ::= {id-pkix 4}
     * 
    */ public class InfoTypeAndValue extends ASN1Object { private ASN1ObjectIdentifier infoType; private ASN1Encodable infoValue; private InfoTypeAndValue(ASN1Sequence seq) { infoType = ASN1ObjectIdentifier.getInstance(seq.getObjectAt(0)); if (seq.size() > 1) { infoValue = (ASN1Encodable)seq.getObjectAt(1); } } public static InfoTypeAndValue getInstance(Object o) { if (o instanceof InfoTypeAndValue) { return (InfoTypeAndValue)o; } if (o != null) { return new InfoTypeAndValue(ASN1Sequence.getInstance(o)); } return null; } public InfoTypeAndValue( ASN1ObjectIdentifier infoType) { this.infoType = infoType; this.infoValue = null; } public InfoTypeAndValue( ASN1ObjectIdentifier infoType, ASN1Encodable optionalValue) { this.infoType = infoType; this.infoValue = optionalValue; } public ASN1ObjectIdentifier getInfoType() { return infoType; } public ASN1Encodable getInfoValue() { return infoValue; } /** *
         * InfoTypeAndValue ::= SEQUENCE {
         *                         infoType               OBJECT IDENTIFIER,
         *                         infoValue              ANY DEFINED BY infoType  OPTIONAL
         * }
         * 
    * @return a basic ASN.1 object representation. */ public ASN1Primitive toASN1Primitive() { ASN1EncodableVector v = new ASN1EncodableVector(); v.add(infoType); if (infoValue != null) { v.add(infoValue); } return new DERSequence(v); } } bouncycastle-1.49.orig/src/org/bouncycastle/asn1/cmp/PKIBody.java0000644000175000017500000001652711725267210024245 0ustar ebourgebourgpackage org.bouncycastle.asn1.cmp; import org.bouncycastle.asn1.ASN1Choice; import org.bouncycastle.asn1.ASN1Encodable; import org.bouncycastle.asn1.ASN1Object; import org.bouncycastle.asn1.ASN1Primitive; import org.bouncycastle.asn1.ASN1TaggedObject; import org.bouncycastle.asn1.DERTaggedObject; import org.bouncycastle.asn1.crmf.CertReqMessages; import org.bouncycastle.asn1.pkcs.CertificationRequest; public class PKIBody extends ASN1Object implements ASN1Choice { public static final int TYPE_INIT_REQ = 0; public static final int TYPE_INIT_REP = 1; public static final int TYPE_CERT_REQ = 2; public static final int TYPE_CERT_REP = 3; public static final int TYPE_P10_CERT_REQ = 4; public static final int TYPE_POPO_CHALL = 5; public static final int TYPE_POPO_REP = 6; public static final int TYPE_KEY_UPDATE_REQ = 7; public static final int TYPE_KEY_UPDATE_REP = 8; public static final int TYPE_KEY_RECOVERY_REQ = 9; public static final int TYPE_KEY_RECOVERY_REP = 10; public static final int TYPE_REVOCATION_REQ = 11; public static final int TYPE_REVOCATION_REP = 12; public static final int TYPE_CROSS_CERT_REQ = 13; public static final int TYPE_CROSS_CERT_REP = 14; public static final int TYPE_CA_KEY_UPDATE_ANN = 15; public static final int TYPE_CERT_ANN = 16; public static final int TYPE_REVOCATION_ANN = 17; public static final int TYPE_CRL_ANN = 18; public static final int TYPE_CONFIRM = 19; public static final int TYPE_NESTED = 20; public static final int TYPE_GEN_MSG = 21; public static final int TYPE_GEN_REP = 22; public static final int TYPE_ERROR = 23; public static final int TYPE_CERT_CONFIRM = 24; public static final int TYPE_POLL_REQ = 25; public static final int TYPE_POLL_REP = 26; private int tagNo; private ASN1Encodable body; public static PKIBody getInstance(Object o) { if (o == null || o instanceof PKIBody) { return (PKIBody)o; } if (o instanceof ASN1TaggedObject) { return new PKIBody((ASN1TaggedObject)o); } throw new IllegalArgumentException("Invalid object: " + o.getClass().getName()); } private PKIBody(ASN1TaggedObject tagged) { tagNo = tagged.getTagNo(); body = getBodyForType(tagNo, tagged.getObject()); } /** * Creates a new PKIBody. * @param type one of the TYPE_* constants * @param content message content */ public PKIBody( int type, ASN1Encodable content) { tagNo = type; body = getBodyForType(type, content); } private static ASN1Encodable getBodyForType( int type, ASN1Encodable o) { switch (type) { case TYPE_INIT_REQ: return CertReqMessages.getInstance(o); case TYPE_INIT_REP: return CertRepMessage.getInstance(o); case TYPE_CERT_REQ: return CertReqMessages.getInstance(o); case TYPE_CERT_REP: return CertRepMessage.getInstance(o); case TYPE_P10_CERT_REQ: return CertificationRequest.getInstance(o); case TYPE_POPO_CHALL: return POPODecKeyChallContent.getInstance(o); case TYPE_POPO_REP: return POPODecKeyRespContent.getInstance(o); case TYPE_KEY_UPDATE_REQ: return CertReqMessages.getInstance(o); case TYPE_KEY_UPDATE_REP: return CertRepMessage.getInstance(o); case TYPE_KEY_RECOVERY_REQ: return CertReqMessages.getInstance(o); case TYPE_KEY_RECOVERY_REP: return KeyRecRepContent.getInstance(o); case TYPE_REVOCATION_REQ: return RevReqContent.getInstance(o); case TYPE_REVOCATION_REP: return RevRepContent.getInstance(o); case TYPE_CROSS_CERT_REQ: return CertReqMessages.getInstance(o); case TYPE_CROSS_CERT_REP: return CertRepMessage.getInstance(o); case TYPE_CA_KEY_UPDATE_ANN: return CAKeyUpdAnnContent.getInstance(o); case TYPE_CERT_ANN: return CMPCertificate.getInstance(o); case TYPE_REVOCATION_ANN: return RevAnnContent.getInstance(o); case TYPE_CRL_ANN: return CRLAnnContent.getInstance(o); case TYPE_CONFIRM: return PKIConfirmContent.getInstance(o); case TYPE_NESTED: return PKIMessages.getInstance(o); case TYPE_GEN_MSG: return GenMsgContent.getInstance(o); case TYPE_GEN_REP: return GenRepContent.getInstance(o); case TYPE_ERROR: return ErrorMsgContent.getInstance(o); case TYPE_CERT_CONFIRM: return CertConfirmContent.getInstance(o); case TYPE_POLL_REQ: return PollReqContent.getInstance(o); case TYPE_POLL_REP: return PollRepContent.getInstance(o); default: throw new IllegalArgumentException("unknown tag number: " + type); } } public int getType() { return tagNo; } public ASN1Encodable getContent() { return body; } /** *
         * PKIBody ::= CHOICE {       -- message-specific body elements
         *        ir       [0]  CertReqMessages,        --Initialization Request
         *        ip       [1]  CertRepMessage,         --Initialization Response
         *        cr       [2]  CertReqMessages,        --Certification Request
         *        cp       [3]  CertRepMessage,         --Certification Response
         *        p10cr    [4]  CertificationRequest,   --imported from [PKCS10]
         *        popdecc  [5]  POPODecKeyChallContent, --pop Challenge
         *        popdecr  [6]  POPODecKeyRespContent,  --pop Response
         *        kur      [7]  CertReqMessages,        --Key Update Request
         *        kup      [8]  CertRepMessage,         --Key Update Response
         *        krr      [9]  CertReqMessages,        --Key Recovery Request
         *        krp      [10] KeyRecRepContent,       --Key Recovery Response
         *        rr       [11] RevReqContent,          --Revocation Request
         *        rp       [12] RevRepContent,          --Revocation Response
         *        ccr      [13] CertReqMessages,        --Cross-Cert. Request
         *        ccp      [14] CertRepMessage,         --Cross-Cert. Response
         *        ckuann   [15] CAKeyUpdAnnContent,     --CA Key Update Ann.
         *        cann     [16] CertAnnContent,         --Certificate Ann.
         *        rann     [17] RevAnnContent,          --Revocation Ann.
         *        crlann   [18] CRLAnnContent,          --CRL Announcement
         *        pkiconf  [19] PKIConfirmContent,      --Confirmation
         *        nested   [20] NestedMessageContent,   --Nested Message
         *        genm     [21] GenMsgContent,          --General Message
         *        genp     [22] GenRepContent,          --General Response
         *        error    [23] ErrorMsgContent,        --Error Message
         *        certConf [24] CertConfirmContent,     --Certificate confirm
         *        pollReq  [25] PollReqContent,         --Polling request
         *        pollRep  [26] PollRepContent          --Polling response
         * }
         * 
    * @return a basic ASN.1 object representation. */ public ASN1Primitive toASN1Primitive() { return new DERTaggedObject(true, tagNo, body); } } bouncycastle-1.49.orig/src/org/bouncycastle/asn1/cmp/CertOrEncCert.java0000644000175000017500000000453311725266055025446 0ustar ebourgebourgpackage org.bouncycastle.asn1.cmp; import org.bouncycastle.asn1.ASN1Choice; import org.bouncycastle.asn1.ASN1Object; import org.bouncycastle.asn1.ASN1Primitive; import org.bouncycastle.asn1.ASN1TaggedObject; import org.bouncycastle.asn1.DERTaggedObject; import org.bouncycastle.asn1.crmf.EncryptedValue; public class CertOrEncCert extends ASN1Object implements ASN1Choice { private CMPCertificate certificate; private EncryptedValue encryptedCert; private CertOrEncCert(ASN1TaggedObject tagged) { if (tagged.getTagNo() == 0) { certificate = CMPCertificate.getInstance(tagged.getObject()); } else if (tagged.getTagNo() == 1) { encryptedCert = EncryptedValue.getInstance(tagged.getObject()); } else { throw new IllegalArgumentException("unknown tag: " + tagged.getTagNo()); } } public static CertOrEncCert getInstance(Object o) { if (o instanceof CertOrEncCert) { return (CertOrEncCert)o; } if (o instanceof ASN1TaggedObject) { return new CertOrEncCert((ASN1TaggedObject)o); } return null; } public CertOrEncCert(CMPCertificate certificate) { if (certificate == null) { throw new IllegalArgumentException("'certificate' cannot be null"); } this.certificate = certificate; } public CertOrEncCert(EncryptedValue encryptedCert) { if (encryptedCert == null) { throw new IllegalArgumentException("'encryptedCert' cannot be null"); } this.encryptedCert = encryptedCert; } public CMPCertificate getCertificate() { return certificate; } public EncryptedValue getEncryptedCert() { return encryptedCert; } /** *
         * CertOrEncCert ::= CHOICE {
         *                      certificate     [0] CMPCertificate,
         *                      encryptedCert   [1] EncryptedValue
         *           }
         * 
    * @return a basic ASN.1 object representation. */ public ASN1Primitive toASN1Primitive() { if (certificate != null) { return new DERTaggedObject(true, 0, certificate); } return new DERTaggedObject(true, 1, encryptedCert); } } bouncycastle-1.49.orig/src/org/bouncycastle/asn1/cmp/CMPObjectIdentifiers.java0000644000175000017500000001433011624622713026727 0ustar ebourgebourgpackage org.bouncycastle.asn1.cmp; import org.bouncycastle.asn1.ASN1ObjectIdentifier; public interface CMPObjectIdentifiers { // RFC 4210 // id-PasswordBasedMac OBJECT IDENTIFIER ::= {1 2 840 113533 7 66 13} static final ASN1ObjectIdentifier passwordBasedMac = new ASN1ObjectIdentifier("1.2.840.113533.7.66.13"); // id-DHBasedMac OBJECT IDENTIFIER ::= {1 2 840 113533 7 66 30} static final ASN1ObjectIdentifier dhBasedMac = new ASN1ObjectIdentifier("1.2.840.113533.7.66.30"); // Example InfoTypeAndValue contents include, but are not limited // to, the following (un-comment in this ASN.1 module and use as // appropriate for a given environment): // // id-it-caProtEncCert OBJECT IDENTIFIER ::= {id-it 1} // CAProtEncCertValue ::= CMPCertificate // id-it-signKeyPairTypes OBJECT IDENTIFIER ::= {id-it 2} // SignKeyPairTypesValue ::= SEQUENCE OF AlgorithmIdentifier // id-it-encKeyPairTypes OBJECT IDENTIFIER ::= {id-it 3} // EncKeyPairTypesValue ::= SEQUENCE OF AlgorithmIdentifier // id-it-preferredSymmAlg OBJECT IDENTIFIER ::= {id-it 4} // PreferredSymmAlgValue ::= AlgorithmIdentifier // id-it-caKeyUpdateInfo OBJECT IDENTIFIER ::= {id-it 5} // CAKeyUpdateInfoValue ::= CAKeyUpdAnnContent // id-it-currentCRL OBJECT IDENTIFIER ::= {id-it 6} // CurrentCRLValue ::= CertificateList // id-it-unsupportedOIDs OBJECT IDENTIFIER ::= {id-it 7} // UnsupportedOIDsValue ::= SEQUENCE OF OBJECT IDENTIFIER // id-it-keyPairParamReq OBJECT IDENTIFIER ::= {id-it 10} // KeyPairParamReqValue ::= OBJECT IDENTIFIER // id-it-keyPairParamRep OBJECT IDENTIFIER ::= {id-it 11} // KeyPairParamRepValue ::= AlgorithmIdentifer // id-it-revPassphrase OBJECT IDENTIFIER ::= {id-it 12} // RevPassphraseValue ::= EncryptedValue // id-it-implicitConfirm OBJECT IDENTIFIER ::= {id-it 13} // ImplicitConfirmValue ::= NULL // id-it-confirmWaitTime OBJECT IDENTIFIER ::= {id-it 14} // ConfirmWaitTimeValue ::= GeneralizedTime // id-it-origPKIMessage OBJECT IDENTIFIER ::= {id-it 15} // OrigPKIMessageValue ::= PKIMessages // id-it-suppLangTags OBJECT IDENTIFIER ::= {id-it 16} // SuppLangTagsValue ::= SEQUENCE OF UTF8String // // where // // id-pkix OBJECT IDENTIFIER ::= { // iso(1) identified-organization(3) // dod(6) internet(1) security(5) mechanisms(5) pkix(7)} // and // id-it OBJECT IDENTIFIER ::= {id-pkix 4} static final ASN1ObjectIdentifier it_caProtEncCert = new ASN1ObjectIdentifier("1.3.6.1.5.5.7.4.1"); static final ASN1ObjectIdentifier it_signKeyPairTypes = new ASN1ObjectIdentifier("1.3.6.1.5.5.7.4.2"); static final ASN1ObjectIdentifier it_encKeyPairTypes = new ASN1ObjectIdentifier("1.3.6.1.5.5.7.4.3"); static final ASN1ObjectIdentifier it_preferredSymAlg = new ASN1ObjectIdentifier("1.3.6.1.5.5.7.4.4"); static final ASN1ObjectIdentifier it_caKeyUpdateInfo = new ASN1ObjectIdentifier("1.3.6.1.5.5.7.4.5"); static final ASN1ObjectIdentifier it_currentCRL = new ASN1ObjectIdentifier("1.3.6.1.5.5.7.4.6"); static final ASN1ObjectIdentifier it_unsupportedOIDs = new ASN1ObjectIdentifier("1.3.6.1.5.5.7.4.7"); static final ASN1ObjectIdentifier it_keyPairParamReq = new ASN1ObjectIdentifier("1.3.6.1.5.5.7.4.10"); static final ASN1ObjectIdentifier it_keyPairParamRep = new ASN1ObjectIdentifier("1.3.6.1.5.5.7.4.11"); static final ASN1ObjectIdentifier it_revPassphrase = new ASN1ObjectIdentifier("1.3.6.1.5.5.7.4.12"); static final ASN1ObjectIdentifier it_implicitConfirm = new ASN1ObjectIdentifier("1.3.6.1.5.5.7.4.13"); static final ASN1ObjectIdentifier it_confirmWaitTime = new ASN1ObjectIdentifier("1.3.6.1.5.5.7.4.14"); static final ASN1ObjectIdentifier it_origPKIMessage = new ASN1ObjectIdentifier("1.3.6.1.5.5.7.4.15"); static final ASN1ObjectIdentifier it_suppLangTags = new ASN1ObjectIdentifier("1.3.6.1.5.5.7.4.16"); // RFC 4211 // id-pkix OBJECT IDENTIFIER ::= { iso(1) identified-organization(3) // dod(6) internet(1) security(5) mechanisms(5) pkix(7) } // // arc for Internet X.509 PKI protocols and their components // id-pkip OBJECT IDENTIFIER :: { id-pkix pkip(5) } // // arc for Registration Controls in CRMF // id-regCtrl OBJECT IDENTIFIER ::= { id-pkip regCtrl(1) } // // arc for Registration Info in CRMF // id-regInfo OBJECT IDENTIFIER ::= { id-pkip id-regInfo(2) } static final ASN1ObjectIdentifier regCtrl_regToken = new ASN1ObjectIdentifier("1.3.6.1.5.5.7.5.1.1"); static final ASN1ObjectIdentifier regCtrl_authenticator = new ASN1ObjectIdentifier("1.3.6.1.5.5.7.5.1.2"); static final ASN1ObjectIdentifier regCtrl_pkiPublicationInfo = new ASN1ObjectIdentifier("1.3.6.1.5.5.7.5.1.3"); static final ASN1ObjectIdentifier regCtrl_pkiArchiveOptions = new ASN1ObjectIdentifier("1.3.6.1.5.5.7.5.1.4"); static final ASN1ObjectIdentifier regCtrl_oldCertID = new ASN1ObjectIdentifier("1.3.6.1.5.5.7.5.1.5"); static final ASN1ObjectIdentifier regCtrl_protocolEncrKey = new ASN1ObjectIdentifier("1.3.6.1.5.5.7.5.1.6"); // From RFC4210: // id-regCtrl-altCertTemplate OBJECT IDENTIFIER ::= {id-regCtrl 7} static final ASN1ObjectIdentifier regCtrl_altCertTemplate = new ASN1ObjectIdentifier("1.3.6.1.5.5.7.5.1.7"); static final ASN1ObjectIdentifier regInfo_utf8Pairs = new ASN1ObjectIdentifier("1.3.6.1.5.5.7.5.2.1"); static final ASN1ObjectIdentifier regInfo_certReq = new ASN1ObjectIdentifier("1.3.6.1.5.5.7.5.2.2"); // id-smime OBJECT IDENTIFIER ::= { iso(1) member-body(2) // us(840) rsadsi(113549) pkcs(1) pkcs9(9) 16 } // // id-ct OBJECT IDENTIFIER ::= { id-smime 1 } -- content types // // id-ct-encKeyWithID OBJECT IDENTIFIER ::= {id-ct 21} static final ASN1ObjectIdentifier ct_encKeyWithID = new ASN1ObjectIdentifier("1.2.840.113549.1.9.16.1.21"); } bouncycastle-1.49.orig/src/org/bouncycastle/asn1/cmp/CertConfirmContent.java0000644000175000017500000000223111725265767026554 0ustar ebourgebourgpackage org.bouncycastle.asn1.cmp; import org.bouncycastle.asn1.ASN1Object; import org.bouncycastle.asn1.ASN1Primitive; import org.bouncycastle.asn1.ASN1Sequence; public class CertConfirmContent extends ASN1Object { private ASN1Sequence content; private CertConfirmContent(ASN1Sequence seq) { content = seq; } public static CertConfirmContent getInstance(Object o) { if (o instanceof CertConfirmContent) { return (CertConfirmContent)o; } if (o != null) { return new CertConfirmContent(ASN1Sequence.getInstance(o)); } return null; } public CertStatus[] toCertStatusArray() { CertStatus[] result = new CertStatus[content.size()]; for (int i = 0; i != result.length; i++) { result[i] = CertStatus.getInstance(content.getObjectAt(i)); } return result; } /** *
         * CertConfirmContent ::= SEQUENCE OF CertStatus
         * 
    * @return a basic ASN.1 object representation. */ public ASN1Primitive toASN1Primitive() { return content; } } bouncycastle-1.49.orig/src/org/bouncycastle/asn1/cmp/RevReqContent.java0000644000175000017500000000314011725270236025530 0ustar ebourgebourgpackage org.bouncycastle.asn1.cmp; import org.bouncycastle.asn1.ASN1EncodableVector; import org.bouncycastle.asn1.ASN1Object; import org.bouncycastle.asn1.ASN1Primitive; import org.bouncycastle.asn1.ASN1Sequence; import org.bouncycastle.asn1.DERSequence; public class RevReqContent extends ASN1Object { private ASN1Sequence content; private RevReqContent(ASN1Sequence seq) { content = seq; } public static RevReqContent getInstance(Object o) { if (o instanceof RevReqContent) { return (RevReqContent)o; } if (o != null) { return new RevReqContent(ASN1Sequence.getInstance(o)); } return null; } public RevReqContent(RevDetails revDetails) { this.content = new DERSequence(revDetails); } public RevReqContent(RevDetails[] revDetailsArray) { ASN1EncodableVector v = new ASN1EncodableVector(); for (int i = 0; i != revDetailsArray.length; i++) { v.add(revDetailsArray[i]); } this.content = new DERSequence(v); } public RevDetails[] toRevDetailsArray() { RevDetails[] result = new RevDetails[content.size()]; for (int i = 0; i != result.length; i++) { result[i] = RevDetails.getInstance(content.getObjectAt(i)); } return result; } /** *
         * RevReqContent ::= SEQUENCE OF RevDetails
         * 
    * @return a basic ASN.1 object representation. */ public ASN1Primitive toASN1Primitive() { return content; } } bouncycastle-1.49.orig/src/org/bouncycastle/asn1/cmp/PKIFailureInfo.java0000644000175000017500000001503311624622713025543 0ustar ebourgebourgpackage org.bouncycastle.asn1.cmp; import org.bouncycastle.asn1.DERBitString; /** *
     * PKIFailureInfo ::= BIT STRING {
     * badAlg               (0),
     *   -- unrecognized or unsupported Algorithm Identifier
     * badMessageCheck      (1), -- integrity check failed (e.g., signature did not verify)
     * badRequest           (2),
     *   -- transaction not permitted or supported
     * badTime              (3), -- messageTime was not sufficiently close to the system time, as defined by local policy
     * badCertId            (4), -- no certificate could be found matching the provided criteria
     * badDataFormat        (5),
     *   -- the data submitted has the wrong format
     * wrongAuthority       (6), -- the authority indicated in the request is different from the one creating the response token
     * incorrectData        (7), -- the requester's data is incorrect (for notary services)
     * missingTimeStamp     (8), -- when the timestamp is missing but should be there (by policy)
     * badPOP               (9)  -- the proof-of-possession failed
     * certRevoked         (10),
     * certConfirmed       (11),
     * wrongIntegrity      (12),
     * badRecipientNonce   (13), 
     * timeNotAvailable    (14),
     *   -- the TSA's time source is not available
     * unacceptedPolicy    (15),
     *   -- the requested TSA policy is not supported by the TSA
     * unacceptedExtension (16),
     *   -- the requested extension is not supported by the TSA
     * addInfoNotAvailable (17)
     *   -- the additional information requested could not be understood
     *   -- or is not available
     * badSenderNonce      (18),
     * badCertTemplate     (19),
     * signerNotTrusted    (20),
     * transactionIdInUse  (21),
     * unsupportedVersion  (22),
     * notAuthorized       (23),
     * systemUnavail       (24),    
     * systemFailure       (25),
     *   -- the request cannot be handled due to system failure
     * duplicateCertReq    (26) 
     * 
    */ public class PKIFailureInfo extends DERBitString { public static final int badAlg = (1 << 7); // unrecognized or unsupported Algorithm Identifier public static final int badMessageCheck = (1 << 6); // integrity check failed (e.g., signature did not verify) public static final int badRequest = (1 << 5); public static final int badTime = (1 << 4); // -- messageTime was not sufficiently close to the system time, as defined by local policy public static final int badCertId = (1 << 3); // no certificate could be found matching the provided criteria public static final int badDataFormat = (1 << 2); public static final int wrongAuthority = (1 << 1); // the authority indicated in the request is different from the one creating the response token public static final int incorrectData = 1; // the requester's data is incorrect (for notary services) public static final int missingTimeStamp = (1 << 15); // when the timestamp is missing but should be there (by policy) public static final int badPOP = (1 << 14); // the proof-of-possession failed public static final int certRevoked = (1 << 13); public static final int certConfirmed = (1 << 12); public static final int wrongIntegrity = (1 << 11); public static final int badRecipientNonce = (1 << 10); public static final int timeNotAvailable = (1 << 9); // the TSA's time source is not available public static final int unacceptedPolicy = (1 << 8); // the requested TSA policy is not supported by the TSA public static final int unacceptedExtension = (1 << 23); //the requested extension is not supported by the TSA public static final int addInfoNotAvailable = (1 << 22); //the additional information requested could not be understood or is not available public static final int badSenderNonce = (1 << 21); public static final int badCertTemplate = (1 << 20); public static final int signerNotTrusted = (1 << 19); public static final int transactionIdInUse = (1 << 18); public static final int unsupportedVersion = (1 << 17); public static final int notAuthorized = (1 << 16); public static final int systemUnavail = (1 << 31); public static final int systemFailure = (1 << 30); //the request cannot be handled due to system failure public static final int duplicateCertReq = (1 << 29); /** @deprecated use lower case version */ public static final int BAD_ALG = badAlg; // unrecognized or unsupported Algorithm Identifier /** @deprecated use lower case version */ public static final int BAD_MESSAGE_CHECK = badMessageCheck; /** @deprecated use lower case version */ public static final int BAD_REQUEST = badRequest; // transaction not permitted or supported /** @deprecated use lower case version */ public static final int BAD_TIME = badTime; /** @deprecated use lower case version */ public static final int BAD_CERT_ID = badCertId; /** @deprecated use lower case version */ public static final int BAD_DATA_FORMAT = badDataFormat; // the data submitted has the wrong format /** @deprecated use lower case version */ public static final int WRONG_AUTHORITY = wrongAuthority; /** @deprecated use lower case version */ public static final int INCORRECT_DATA = incorrectData; /** @deprecated use lower case version */ public static final int MISSING_TIME_STAMP = missingTimeStamp; /** @deprecated use lower case version */ public static final int BAD_POP = badPOP; /** @deprecated use lower case version */ public static final int TIME_NOT_AVAILABLE = timeNotAvailable; /** @deprecated use lower case version */ public static final int UNACCEPTED_POLICY = unacceptedPolicy; /** @deprecated use lower case version */ public static final int UNACCEPTED_EXTENSION = unacceptedExtension; /** @deprecated use lower case version */ public static final int ADD_INFO_NOT_AVAILABLE = addInfoNotAvailable; /** @deprecated use lower case version */ public static final int SYSTEM_FAILURE = systemFailure; /** * Basic constructor. */ public PKIFailureInfo( int info) { super(getBytes(info), getPadBits(info)); } public PKIFailureInfo( DERBitString info) { super(info.getBytes(), info.getPadBits()); } public String toString() { return "PKIFailureInfo: 0x" + Integer.toHexString(this.intValue()); } } bouncycastle-1.49.orig/src/org/bouncycastle/asn1/cmp/PollReqContent.java0000644000175000017500000000354012075137352025706 0ustar ebourgebourgpackage org.bouncycastle.asn1.cmp; import org.bouncycastle.asn1.ASN1Integer; import org.bouncycastle.asn1.ASN1Object; import org.bouncycastle.asn1.ASN1Primitive; import org.bouncycastle.asn1.ASN1Sequence; import org.bouncycastle.asn1.DERSequence; public class PollReqContent extends ASN1Object { private ASN1Sequence content; private PollReqContent(ASN1Sequence seq) { content = seq; } public static PollReqContent getInstance(Object o) { if (o instanceof PollReqContent) { return (PollReqContent)o; } if (o != null) { return new PollReqContent(ASN1Sequence.getInstance(o)); } return null; } /** * Create a pollReqContent for a single certReqId. * * @param certReqId the certificate request ID. */ public PollReqContent(ASN1Integer certReqId) { this(new DERSequence(new DERSequence(certReqId))); } public ASN1Integer[][] getCertReqIds() { ASN1Integer[][] result = new ASN1Integer[content.size()][]; for (int i = 0; i != result.length; i++) { result[i] = sequenceToASN1IntegerArray((ASN1Sequence)content.getObjectAt(i)); } return result; } private static ASN1Integer[] sequenceToASN1IntegerArray(ASN1Sequence seq) { ASN1Integer[] result = new ASN1Integer[seq.size()]; for (int i = 0; i != result.length; i++) { result[i] = ASN1Integer.getInstance(seq.getObjectAt(i)); } return result; } /** *
         * PollReqContent ::= SEQUENCE OF SEQUENCE {
         *                        certReqId              INTEGER
         * }
         * 
    * @return a basic ASN.1 object representation. */ public ASN1Primitive toASN1Primitive() { return content; } } bouncycastle-1.49.orig/src/org/bouncycastle/asn1/cmp/PKIHeader.java0000644000175000017500000001770612151253000024522 0ustar ebourgebourgpackage org.bouncycastle.asn1.cmp; import java.util.Enumeration; import org.bouncycastle.asn1.ASN1Encodable; import org.bouncycastle.asn1.ASN1EncodableVector; import org.bouncycastle.asn1.ASN1Integer; import org.bouncycastle.asn1.ASN1Object; import org.bouncycastle.asn1.ASN1OctetString; import org.bouncycastle.asn1.ASN1Primitive; import org.bouncycastle.asn1.ASN1Sequence; import org.bouncycastle.asn1.ASN1TaggedObject; import org.bouncycastle.asn1.DERGeneralizedTime; import org.bouncycastle.asn1.DERSequence; import org.bouncycastle.asn1.DERTaggedObject; import org.bouncycastle.asn1.x500.X500Name; import org.bouncycastle.asn1.x509.AlgorithmIdentifier; import org.bouncycastle.asn1.x509.GeneralName; public class PKIHeader extends ASN1Object { /** * Value for a "null" recipient or sender. */ public static final GeneralName NULL_NAME = new GeneralName(X500Name.getInstance(new DERSequence())); public static final int CMP_1999 = 1; public static final int CMP_2000 = 2; private ASN1Integer pvno; private GeneralName sender; private GeneralName recipient; private DERGeneralizedTime messageTime; private AlgorithmIdentifier protectionAlg; private ASN1OctetString senderKID; // KeyIdentifier private ASN1OctetString recipKID; // KeyIdentifier private ASN1OctetString transactionID; private ASN1OctetString senderNonce; private ASN1OctetString recipNonce; private PKIFreeText freeText; private ASN1Sequence generalInfo; private PKIHeader(ASN1Sequence seq) { Enumeration en = seq.getObjects(); pvno = ASN1Integer.getInstance(en.nextElement()); sender = GeneralName.getInstance(en.nextElement()); recipient = GeneralName.getInstance(en.nextElement()); while (en.hasMoreElements()) { ASN1TaggedObject tObj = (ASN1TaggedObject)en.nextElement(); switch (tObj.getTagNo()) { case 0: messageTime = DERGeneralizedTime.getInstance(tObj, true); break; case 1: protectionAlg = AlgorithmIdentifier.getInstance(tObj, true); break; case 2: senderKID = ASN1OctetString.getInstance(tObj, true); break; case 3: recipKID = ASN1OctetString.getInstance(tObj, true); break; case 4: transactionID = ASN1OctetString.getInstance(tObj, true); break; case 5: senderNonce = ASN1OctetString.getInstance(tObj, true); break; case 6: recipNonce = ASN1OctetString.getInstance(tObj, true); break; case 7: freeText = PKIFreeText.getInstance(tObj, true); break; case 8: generalInfo = ASN1Sequence.getInstance(tObj, true); break; default: throw new IllegalArgumentException("unknown tag number: " + tObj.getTagNo()); } } } public static PKIHeader getInstance(Object o) { if (o instanceof PKIHeader) { return (PKIHeader)o; } if (o != null) { return new PKIHeader(ASN1Sequence.getInstance(o)); } return null; } public PKIHeader( int pvno, GeneralName sender, GeneralName recipient) { this(new ASN1Integer(pvno), sender, recipient); } private PKIHeader( ASN1Integer pvno, GeneralName sender, GeneralName recipient) { this.pvno = pvno; this.sender = sender; this.recipient = recipient; } public ASN1Integer getPvno() { return pvno; } public GeneralName getSender() { return sender; } public GeneralName getRecipient() { return recipient; } public DERGeneralizedTime getMessageTime() { return messageTime; } public AlgorithmIdentifier getProtectionAlg() { return protectionAlg; } public ASN1OctetString getSenderKID() { return senderKID; } public ASN1OctetString getRecipKID() { return recipKID; } public ASN1OctetString getTransactionID() { return transactionID; } public ASN1OctetString getSenderNonce() { return senderNonce; } public ASN1OctetString getRecipNonce() { return recipNonce; } public PKIFreeText getFreeText() { return freeText; } public InfoTypeAndValue[] getGeneralInfo() { if (generalInfo == null) { return null; } InfoTypeAndValue[] results = new InfoTypeAndValue[generalInfo.size()]; for (int i = 0; i < results.length; i++) { results[i] = InfoTypeAndValue.getInstance(generalInfo.getObjectAt(i)); } return results; } /** *
         *  PKIHeader ::= SEQUENCE {
         *            pvno                INTEGER     { cmp1999(1), cmp2000(2) },
         *            sender              GeneralName,
         *            -- identifies the sender
         *            recipient           GeneralName,
         *            -- identifies the intended recipient
         *            messageTime     [0] GeneralizedTime         OPTIONAL,
         *            -- time of production of this message (used when sender
         *            -- believes that the transport will be "suitable"; i.e.,
         *            -- that the time will still be meaningful upon receipt)
         *            protectionAlg   [1] AlgorithmIdentifier     OPTIONAL,
         *            -- algorithm used for calculation of protection bits
         *            senderKID       [2] KeyIdentifier           OPTIONAL,
         *            recipKID        [3] KeyIdentifier           OPTIONAL,
         *            -- to identify specific keys used for protection
         *            transactionID   [4] OCTET STRING            OPTIONAL,
         *            -- identifies the transaction; i.e., this will be the same in
         *            -- corresponding request, response, certConf, and PKIConf
         *            -- messages
         *            senderNonce     [5] OCTET STRING            OPTIONAL,
         *            recipNonce      [6] OCTET STRING            OPTIONAL,
         *            -- nonces used to provide replay protection, senderNonce
         *            -- is inserted by the creator of this message; recipNonce
         *            -- is a nonce previously inserted in a related message by
         *            -- the intended recipient of this message
         *            freeText        [7] PKIFreeText             OPTIONAL,
         *            -- this may be used to indicate context-specific instructions
         *            -- (this field is intended for human consumption)
         *            generalInfo     [8] SEQUENCE SIZE (1..MAX) OF
         *                                 InfoTypeAndValue     OPTIONAL
         *            -- this may be used to convey context-specific information
         *            -- (this field not primarily intended for human consumption)
         * }
         * 
    * * @return a basic ASN.1 object representation. */ public ASN1Primitive toASN1Primitive() { ASN1EncodableVector v = new ASN1EncodableVector(); v.add(pvno); v.add(sender); v.add(recipient); addOptional(v, 0, messageTime); addOptional(v, 1, protectionAlg); addOptional(v, 2, senderKID); addOptional(v, 3, recipKID); addOptional(v, 4, transactionID); addOptional(v, 5, senderNonce); addOptional(v, 6, recipNonce); addOptional(v, 7, freeText); addOptional(v, 8, generalInfo); return new DERSequence(v); } private void addOptional(ASN1EncodableVector v, int tagNo, ASN1Encodable obj) { if (obj != null) { v.add(new DERTaggedObject(true, tagNo, obj)); } } } bouncycastle-1.49.orig/src/org/bouncycastle/asn1/cmp/POPODecKeyRespContent.java0000644000175000017500000000232611725270001027013 0ustar ebourgebourgpackage org.bouncycastle.asn1.cmp; import org.bouncycastle.asn1.ASN1Integer; import org.bouncycastle.asn1.ASN1Object; import org.bouncycastle.asn1.ASN1Primitive; import org.bouncycastle.asn1.ASN1Sequence; public class POPODecKeyRespContent extends ASN1Object { private ASN1Sequence content; private POPODecKeyRespContent(ASN1Sequence seq) { content = seq; } public static POPODecKeyRespContent getInstance(Object o) { if (o instanceof POPODecKeyRespContent) { return (POPODecKeyRespContent)o; } if (o != null) { return new POPODecKeyRespContent(ASN1Sequence.getInstance(o)); } return null; } public ASN1Integer[] toASN1IntegerArray() { ASN1Integer[] result = new ASN1Integer[content.size()]; for (int i = 0; i != result.length; i++) { result[i] = ASN1Integer.getInstance(content.getObjectAt(i)); } return result; } /** *
         * POPODecKeyRespContent ::= SEQUENCE OF INTEGER
         * 
    * @return a basic ASN.1 object representation. */ public ASN1Primitive toASN1Primitive() { return content; } } bouncycastle-1.49.orig/src/org/bouncycastle/asn1/cmp/CRLAnnContent.java0000644000175000017500000000252211725321374025404 0ustar ebourgebourgpackage org.bouncycastle.asn1.cmp; import org.bouncycastle.asn1.ASN1Object; import org.bouncycastle.asn1.ASN1Primitive; import org.bouncycastle.asn1.ASN1Sequence; import org.bouncycastle.asn1.DERSequence; import org.bouncycastle.asn1.x509.CertificateList; public class CRLAnnContent extends ASN1Object { private ASN1Sequence content; private CRLAnnContent(ASN1Sequence seq) { content = seq; } public static CRLAnnContent getInstance(Object o) { if (o instanceof CRLAnnContent) { return (CRLAnnContent)o; } if (o != null) { return new CRLAnnContent(ASN1Sequence.getInstance(o)); } return null; } public CRLAnnContent(CertificateList crl) { this.content = new DERSequence(crl); } public CertificateList[] getCertificateLists() { CertificateList[] result = new CertificateList[content.size()]; for (int i = 0; i != result.length; i++) { result[i] = CertificateList.getInstance(content.getObjectAt(i)); } return result; } /** *
         * CRLAnnContent ::= SEQUENCE OF CertificateList
         * 
    * @return a basic ASN.1 object representation. */ public ASN1Primitive toASN1Primitive() { return content; } } bouncycastle-1.49.orig/src/org/bouncycastle/asn1/cmp/CAKeyUpdAnnContent.java0000644000175000017500000000417211725316361026374 0ustar ebourgebourgpackage org.bouncycastle.asn1.cmp; import org.bouncycastle.asn1.ASN1EncodableVector; import org.bouncycastle.asn1.ASN1Object; import org.bouncycastle.asn1.ASN1Primitive; import org.bouncycastle.asn1.ASN1Sequence; import org.bouncycastle.asn1.DERSequence; public class CAKeyUpdAnnContent extends ASN1Object { private CMPCertificate oldWithNew; private CMPCertificate newWithOld; private CMPCertificate newWithNew; private CAKeyUpdAnnContent(ASN1Sequence seq) { oldWithNew = CMPCertificate.getInstance(seq.getObjectAt(0)); newWithOld = CMPCertificate.getInstance(seq.getObjectAt(1)); newWithNew = CMPCertificate.getInstance(seq.getObjectAt(2)); } public static CAKeyUpdAnnContent getInstance(Object o) { if (o instanceof CAKeyUpdAnnContent) { return (CAKeyUpdAnnContent)o; } if (o != null) { return new CAKeyUpdAnnContent(ASN1Sequence.getInstance(o)); } return null; } public CAKeyUpdAnnContent(CMPCertificate oldWithNew, CMPCertificate newWithOld, CMPCertificate newWithNew) { this.oldWithNew = oldWithNew; this.newWithOld = newWithOld; this.newWithNew = newWithNew; } public CMPCertificate getOldWithNew() { return oldWithNew; } public CMPCertificate getNewWithOld() { return newWithOld; } public CMPCertificate getNewWithNew() { return newWithNew; } /** *
         * CAKeyUpdAnnContent ::= SEQUENCE {
         *                             oldWithNew   CMPCertificate, -- old pub signed with new priv
         *                             newWithOld   CMPCertificate, -- new pub signed with old priv
         *                             newWithNew   CMPCertificate  -- new pub signed with new priv
         *  }
         * 
    * @return a basic ASN.1 object representation. */ public ASN1Primitive toASN1Primitive() { ASN1EncodableVector v = new ASN1EncodableVector(); v.add(oldWithNew); v.add(newWithOld); v.add(newWithNew); return new DERSequence(v); } } bouncycastle-1.49.orig/src/org/bouncycastle/asn1/cmp/PKIStatusInfo.java0000644000175000017500000001166212151253000025424 0ustar ebourgebourgpackage org.bouncycastle.asn1.cmp; import java.math.BigInteger; import org.bouncycastle.asn1.ASN1EncodableVector; import org.bouncycastle.asn1.ASN1Integer; import org.bouncycastle.asn1.ASN1Object; import org.bouncycastle.asn1.ASN1Primitive; import org.bouncycastle.asn1.ASN1Sequence; import org.bouncycastle.asn1.ASN1TaggedObject; import org.bouncycastle.asn1.DERBitString; import org.bouncycastle.asn1.DERSequence; public class PKIStatusInfo extends ASN1Object { ASN1Integer status; PKIFreeText statusString; DERBitString failInfo; public static PKIStatusInfo getInstance( ASN1TaggedObject obj, boolean explicit) { return getInstance(ASN1Sequence.getInstance(obj, explicit)); } public static PKIStatusInfo getInstance( Object obj) { if (obj instanceof PKIStatusInfo) { return (PKIStatusInfo)obj; } else if (obj != null) { return new PKIStatusInfo(ASN1Sequence.getInstance(obj)); } return null; } private PKIStatusInfo( ASN1Sequence seq) { this.status = ASN1Integer.getInstance(seq.getObjectAt(0)); this.statusString = null; this.failInfo = null; if (seq.size() > 2) { this.statusString = PKIFreeText.getInstance(seq.getObjectAt(1)); this.failInfo = DERBitString.getInstance(seq.getObjectAt(2)); } else if (seq.size() > 1) { Object obj = seq.getObjectAt(1); if (obj instanceof DERBitString) { this.failInfo = DERBitString.getInstance(obj); } else { this.statusString = PKIFreeText.getInstance(obj); } } } /** * @param status */ public PKIStatusInfo(PKIStatus status) { this.status = ASN1Integer.getInstance(status.toASN1Primitive()); } /** * * @param status * @param statusString */ public PKIStatusInfo( PKIStatus status, PKIFreeText statusString) { this.status = ASN1Integer.getInstance(status.toASN1Primitive()); this.statusString = statusString; } public PKIStatusInfo( PKIStatus status, PKIFreeText statusString, PKIFailureInfo failInfo) { this.status = ASN1Integer.getInstance(status.toASN1Primitive()); this.statusString = statusString; this.failInfo = failInfo; } public BigInteger getStatus() { return status.getValue(); } public PKIFreeText getStatusString() { return statusString; } public DERBitString getFailInfo() { return failInfo; } /** *
         * PKIStatusInfo ::= SEQUENCE {
         *     status        PKIStatus,                (INTEGER)
         *     statusString  PKIFreeText     OPTIONAL,
         *     failInfo      PKIFailureInfo  OPTIONAL  (BIT STRING)
         * }
         *
         * PKIStatus:
         *   granted                (0), -- you got exactly what you asked for
         *   grantedWithMods        (1), -- you got something like what you asked for
         *   rejection              (2), -- you don't get it, more information elsewhere in the message
         *   waiting                (3), -- the request body part has not yet been processed, expect to hear more later
         *   revocationWarning      (4), -- this message contains a warning that a revocation is imminent
         *   revocationNotification (5), -- notification that a revocation has occurred
         *   keyUpdateWarning       (6)  -- update already done for the oldCertId specified in CertReqMsg
         *
         * PKIFailureInfo:
         *   badAlg           (0), -- unrecognized or unsupported Algorithm Identifier
         *   badMessageCheck  (1), -- integrity check failed (e.g., signature did not verify)
         *   badRequest       (2), -- transaction not permitted or supported
         *   badTime          (3), -- messageTime was not sufficiently close to the system time, as defined by local policy
         *   badCertId        (4), -- no certificate could be found matching the provided criteria
         *   badDataFormat    (5), -- the data submitted has the wrong format
         *   wrongAuthority   (6), -- the authority indicated in the request is different from the one creating the response token
         *   incorrectData    (7), -- the requester's data is incorrect (for notary services)
         *   missingTimeStamp (8), -- when the timestamp is missing but should be there (by policy)
         *   badPOP           (9)  -- the proof-of-possession failed
         *
         * 
    */ public ASN1Primitive toASN1Primitive() { ASN1EncodableVector v = new ASN1EncodableVector(); v.add(status); if (statusString != null) { v.add(statusString); } if (failInfo!= null) { v.add(failInfo); } return new DERSequence(v); } } bouncycastle-1.49.orig/src/org/bouncycastle/asn1/cmp/ErrorMsgContent.java0000644000175000017500000000572611725260520026073 0ustar ebourgebourgpackage org.bouncycastle.asn1.cmp; import java.util.Enumeration; import org.bouncycastle.asn1.ASN1Encodable; import org.bouncycastle.asn1.ASN1EncodableVector; import org.bouncycastle.asn1.ASN1Integer; import org.bouncycastle.asn1.ASN1Object; import org.bouncycastle.asn1.ASN1Primitive; import org.bouncycastle.asn1.ASN1Sequence; import org.bouncycastle.asn1.DERSequence; public class ErrorMsgContent extends ASN1Object { private PKIStatusInfo pkiStatusInfo; private ASN1Integer errorCode; private PKIFreeText errorDetails; private ErrorMsgContent(ASN1Sequence seq) { Enumeration en = seq.getObjects(); pkiStatusInfo = PKIStatusInfo.getInstance(en.nextElement()); while (en.hasMoreElements()) { Object o = en.nextElement(); if (o instanceof ASN1Integer) { errorCode = ASN1Integer.getInstance(o); } else { errorDetails = PKIFreeText.getInstance(o); } } } public static ErrorMsgContent getInstance(Object o) { if (o instanceof ErrorMsgContent) { return (ErrorMsgContent)o; } if (o != null) { return new ErrorMsgContent(ASN1Sequence.getInstance(o)); } return null; } public ErrorMsgContent(PKIStatusInfo pkiStatusInfo) { this(pkiStatusInfo, null, null); } public ErrorMsgContent( PKIStatusInfo pkiStatusInfo, ASN1Integer errorCode, PKIFreeText errorDetails) { if (pkiStatusInfo == null) { throw new IllegalArgumentException("'pkiStatusInfo' cannot be null"); } this.pkiStatusInfo = pkiStatusInfo; this.errorCode = errorCode; this.errorDetails = errorDetails; } public PKIStatusInfo getPKIStatusInfo() { return pkiStatusInfo; } public ASN1Integer getErrorCode() { return errorCode; } public PKIFreeText getErrorDetails() { return errorDetails; } /** *
         * ErrorMsgContent ::= SEQUENCE {
         *                        pKIStatusInfo          PKIStatusInfo,
         *                        errorCode              INTEGER           OPTIONAL,
         *                        -- implementation-specific error codes
         *                        errorDetails           PKIFreeText       OPTIONAL
         *                        -- implementation-specific error details
         * }
         * 
    * @return a basic ASN.1 object representation. */ public ASN1Primitive toASN1Primitive() { ASN1EncodableVector v = new ASN1EncodableVector(); v.add(pkiStatusInfo); addOptional(v, errorCode); addOptional(v, errorDetails); return new DERSequence(v); } private void addOptional(ASN1EncodableVector v, ASN1Encodable obj) { if (obj != null) { v.add(obj); } } } bouncycastle-1.49.orig/src/org/bouncycastle/asn1/cmp/CertResponse.java0000644000175000017500000000753111725266161025417 0ustar ebourgebourgpackage org.bouncycastle.asn1.cmp; import org.bouncycastle.asn1.ASN1Encodable; import org.bouncycastle.asn1.ASN1EncodableVector; import org.bouncycastle.asn1.ASN1Integer; import org.bouncycastle.asn1.ASN1Object; import org.bouncycastle.asn1.ASN1OctetString; import org.bouncycastle.asn1.ASN1Primitive; import org.bouncycastle.asn1.ASN1Sequence; import org.bouncycastle.asn1.DERSequence; public class CertResponse extends ASN1Object { private ASN1Integer certReqId; private PKIStatusInfo status; private CertifiedKeyPair certifiedKeyPair; private ASN1OctetString rspInfo; private CertResponse(ASN1Sequence seq) { certReqId = ASN1Integer.getInstance(seq.getObjectAt(0)); status = PKIStatusInfo.getInstance(seq.getObjectAt(1)); if (seq.size() >= 3) { if (seq.size() == 3) { ASN1Encodable o = seq.getObjectAt(2); if (o instanceof ASN1OctetString) { rspInfo = ASN1OctetString.getInstance(o); } else { certifiedKeyPair = CertifiedKeyPair.getInstance(o); } } else { certifiedKeyPair = CertifiedKeyPair.getInstance(seq.getObjectAt(2)); rspInfo = ASN1OctetString.getInstance(seq.getObjectAt(3)); } } } public static CertResponse getInstance(Object o) { if (o instanceof CertResponse) { return (CertResponse)o; } if (o != null) { return new CertResponse(ASN1Sequence.getInstance(o)); } return null; } public CertResponse( ASN1Integer certReqId, PKIStatusInfo status) { this(certReqId, status, null, null); } public CertResponse( ASN1Integer certReqId, PKIStatusInfo status, CertifiedKeyPair certifiedKeyPair, ASN1OctetString rspInfo) { if (certReqId == null) { throw new IllegalArgumentException("'certReqId' cannot be null"); } if (status == null) { throw new IllegalArgumentException("'status' cannot be null"); } this.certReqId = certReqId; this.status = status; this.certifiedKeyPair = certifiedKeyPair; this.rspInfo = rspInfo; } public ASN1Integer getCertReqId() { return certReqId; } public PKIStatusInfo getStatus() { return status; } public CertifiedKeyPair getCertifiedKeyPair() { return certifiedKeyPair; } /** *
         * CertResponse ::= SEQUENCE {
         *                            certReqId           INTEGER,
         *                            -- to match this response with corresponding request (a value
         *                            -- of -1 is to be used if certReqId is not specified in the
         *                            -- corresponding request)
         *                            status              PKIStatusInfo,
         *                            certifiedKeyPair    CertifiedKeyPair    OPTIONAL,
         *                            rspInfo             OCTET STRING        OPTIONAL
         *                            -- analogous to the id-regInfo-utf8Pairs string defined
         *                            -- for regInfo in CertReqMsg [CRMF]
         *             }
         * 
    * @return a basic ASN.1 object representation. */ public ASN1Primitive toASN1Primitive() { ASN1EncodableVector v = new ASN1EncodableVector(); v.add(certReqId); v.add(status); if (certifiedKeyPair != null) { v.add(certifiedKeyPair); } if (rspInfo != null) { v.add(rspInfo); } return new DERSequence(v); } } bouncycastle-1.49.orig/src/org/bouncycastle/asn1/cmp/GenMsgContent.java0000644000175000017500000000312111725266464025513 0ustar ebourgebourgpackage org.bouncycastle.asn1.cmp; import org.bouncycastle.asn1.ASN1EncodableVector; import org.bouncycastle.asn1.ASN1Object; import org.bouncycastle.asn1.ASN1Primitive; import org.bouncycastle.asn1.ASN1Sequence; import org.bouncycastle.asn1.DERSequence; public class GenMsgContent extends ASN1Object { private ASN1Sequence content; private GenMsgContent(ASN1Sequence seq) { content = seq; } public static GenMsgContent getInstance(Object o) { if (o instanceof GenMsgContent) { return (GenMsgContent)o; } if (o != null) { return new GenMsgContent(ASN1Sequence.getInstance(o)); } return null; } public GenMsgContent(InfoTypeAndValue itv) { content = new DERSequence(itv); } public GenMsgContent(InfoTypeAndValue[] itv) { ASN1EncodableVector v = new ASN1EncodableVector(); for (int i = 0; i < itv.length; i++) { v.add(itv[i]); } content = new DERSequence(v); } public InfoTypeAndValue[] toInfoTypeAndValueArray() { InfoTypeAndValue[] result = new InfoTypeAndValue[content.size()]; for (int i = 0; i != result.length; i++) { result[i] = InfoTypeAndValue.getInstance(content.getObjectAt(i)); } return result; } /** *
         * GenMsgContent ::= SEQUENCE OF InfoTypeAndValue
         * 
    * @return a basic ASN.1 object representation. */ public ASN1Primitive toASN1Primitive() { return content; } } bouncycastle-1.49.orig/src/org/bouncycastle/asn1/cmp/package.html0000644000175000017500000000020310262753174024406 0ustar ebourgebourg Support classes useful for encoding and supporting PKIX-CMP as described RFC 2510. bouncycastle-1.49.orig/src/org/bouncycastle/asn1/BERApplicationSpecific.java0000644000175000017500000000033011624614576026461 0ustar ebourgebourgpackage org.bouncycastle.asn1; public class BERApplicationSpecific extends DERApplicationSpecific { public BERApplicationSpecific(int tagNo, ASN1EncodableVector vec) { super(tagNo, vec); } } bouncycastle-1.49.orig/src/org/bouncycastle/asn1/DERTags.java0000644000175000017500000000016411624615665023455 0ustar ebourgebourgpackage org.bouncycastle.asn1; /** * @deprecated use BERTags */ public interface DERTags extends BERTags { } bouncycastle-1.49.orig/src/org/bouncycastle/asn1/LazyConstructionEnumeration.java0000644000175000017500000000147611625105230027753 0ustar ebourgebourgpackage org.bouncycastle.asn1; import java.io.IOException; import java.util.Enumeration; class LazyConstructionEnumeration implements Enumeration { private ASN1InputStream aIn; private Object nextObj; public LazyConstructionEnumeration(byte[] encoded) { aIn = new ASN1InputStream(encoded, true); nextObj = readObject(); } public boolean hasMoreElements() { return nextObj != null; } public Object nextElement() { Object o = nextObj; nextObj = readObject(); return o; } private Object readObject() { try { return aIn.readObject(); } catch (IOException e) { throw new ASN1ParsingException("malformed DER construction: " + e, e); } } } bouncycastle-1.49.orig/src/org/bouncycastle/asn1/BERSequenceGenerator.java0000644000175000017500000000152511624617033026165 0ustar ebourgebourgpackage org.bouncycastle.asn1; import java.io.IOException; import java.io.OutputStream; public class BERSequenceGenerator extends BERGenerator { public BERSequenceGenerator( OutputStream out) throws IOException { super(out); writeBERHeader(BERTags.CONSTRUCTED | BERTags.SEQUENCE); } public BERSequenceGenerator( OutputStream out, int tagNo, boolean isExplicit) throws IOException { super(out, tagNo, isExplicit); writeBERHeader(BERTags.CONSTRUCTED | BERTags.SEQUENCE); } public void addObject( ASN1Encodable object) throws IOException { object.toASN1Primitive().encode(new BEROutputStream(_out)); } public void close() throws IOException { writeBEREnd(); } } bouncycastle-1.49.orig/src/org/bouncycastle/asn1/DERNull.java0000644000175000017500000000112412103437557023461 0ustar ebourgebourgpackage org.bouncycastle.asn1; import java.io.IOException; /** * A NULL object. */ public class DERNull extends ASN1Null { public static final DERNull INSTANCE = new DERNull(); private static final byte[] zeroBytes = new byte[0]; /** * @deprecated use DERNull.INSTANCE */ public DERNull() { } boolean isConstructed() { return false; } int encodedLength() { return 2; } void encode( ASN1OutputStream out) throws IOException { out.writeEncoded(BERTags.NULL, zeroBytes); } } bouncycastle-1.49.orig/src/org/bouncycastle/asn1/DERSet.java0000644000175000017500000000440511703177363023310 0ustar ebourgebourgpackage org.bouncycastle.asn1; import java.io.IOException; import java.util.Enumeration; /** * A DER encoded set object */ public class DERSet extends ASN1Set { private int bodyLength = -1; /** * create an empty set */ public DERSet() { } /** * @param obj - a single object that makes up the set. */ public DERSet( ASN1Encodable obj) { super(obj); } /** * @param v - a vector of objects making up the set. */ public DERSet( ASN1EncodableVector v) { super(v, true); } /** * create a set from an array of objects. */ public DERSet( ASN1Encodable[] a) { super(a, true); } DERSet( ASN1EncodableVector v, boolean doSort) { super(v, doSort); } private int getBodyLength() throws IOException { if (bodyLength < 0) { int length = 0; for (Enumeration e = this.getObjects(); e.hasMoreElements();) { Object obj = e.nextElement(); length += ((ASN1Encodable)obj).toASN1Primitive().toDERObject().encodedLength(); } bodyLength = length; } return bodyLength; } int encodedLength() throws IOException { int length = getBodyLength(); return 1 + StreamUtil.calculateBodyLength(length) + length; } /* * A note on the implementation: *

    * As DER requires the constructed, definite-length model to * be used for structured types, this varies slightly from the * ASN.1 descriptions given. Rather than just outputting SET, * we also have to specify CONSTRUCTED, and the objects length. */ void encode( ASN1OutputStream out) throws IOException { ASN1OutputStream dOut = out.getDERSubStream(); int length = getBodyLength(); out.write(BERTags.SET | BERTags.CONSTRUCTED); out.writeLength(length); for (Enumeration e = this.getObjects(); e.hasMoreElements();) { Object obj = e.nextElement(); dOut.writeObject((ASN1Encodable)obj); } } } bouncycastle-1.49.orig/src/org/bouncycastle/asn1/OIDTokenizer.java0000644000175000017500000000163511624614576024536 0ustar ebourgebourgpackage org.bouncycastle.asn1; /** * class for breaking up an OID into it's component tokens, ala * java.util.StringTokenizer. We need this class as some of the * lightweight Java environment don't support classes like * StringTokenizer. */ public class OIDTokenizer { private String oid; private int index; public OIDTokenizer( String oid) { this.oid = oid; this.index = 0; } public boolean hasMoreTokens() { return (index != -1); } public String nextToken() { if (index == -1) { return null; } String token; int end = oid.indexOf('.', index); if (end == -1) { token = oid.substring(index); index = -1; return token; } token = oid.substring(index, end); index = end + 1; return token; } } bouncycastle-1.49.orig/src/org/bouncycastle/asn1/BEROctetString.java0000644000175000017500000000732111703177363025020 0ustar ebourgebourgpackage org.bouncycastle.asn1; import java.io.ByteArrayOutputStream; import java.io.IOException; import java.util.Enumeration; import java.util.Vector; public class BEROctetString extends ASN1OctetString { private static final int MAX_LENGTH = 1000; private ASN1OctetString[] octs; /** * convert a vector of octet strings into a single byte string */ static private byte[] toBytes( ASN1OctetString[] octs) { ByteArrayOutputStream bOut = new ByteArrayOutputStream(); for (int i = 0; i != octs.length; i++) { try { DEROctetString o = (DEROctetString)octs[i]; bOut.write(o.getOctets()); } catch (ClassCastException e) { throw new IllegalArgumentException(octs[i].getClass().getName() + " found in input should only contain DEROctetString"); } catch (IOException e) { throw new IllegalArgumentException("exception converting octets " + e.toString()); } } return bOut.toByteArray(); } /** * @param string the octets making up the octet string. */ public BEROctetString( byte[] string) { super(string); } public BEROctetString( ASN1OctetString[] octs) { super(toBytes(octs)); this.octs = octs; } public byte[] getOctets() { return string; } /** * return the DER octets that make up this string. */ public Enumeration getObjects() { if (octs == null) { return generateOcts().elements(); } return new Enumeration() { int counter = 0; public boolean hasMoreElements() { return counter < octs.length; } public Object nextElement() { return octs[counter++]; } }; } private Vector generateOcts() { Vector vec = new Vector(); for (int i = 0; i < string.length; i += MAX_LENGTH) { int end; if (i + MAX_LENGTH > string.length) { end = string.length; } else { end = i + MAX_LENGTH; } byte[] nStr = new byte[end - i]; System.arraycopy(string, i, nStr, 0, nStr.length); vec.addElement(new DEROctetString(nStr)); } return vec; } boolean isConstructed() { return true; } int encodedLength() throws IOException { int length = 0; for (Enumeration e = getObjects(); e.hasMoreElements();) { length += ((ASN1Encodable)e.nextElement()).toASN1Primitive().encodedLength(); } return 2 + length + 2; } public void encode( ASN1OutputStream out) throws IOException { out.write(BERTags.CONSTRUCTED | BERTags.OCTET_STRING); out.write(0x80); // // write out the octet array // for (Enumeration e = getObjects(); e.hasMoreElements();) { out.writeObject((ASN1Encodable)e.nextElement()); } out.write(0x00); out.write(0x00); } static BEROctetString fromSequence(ASN1Sequence seq) { ASN1OctetString[] v = new ASN1OctetString[seq.size()]; Enumeration e = seq.getObjects(); int index = 0; while (e.hasMoreElements()) { v[index++] = (ASN1OctetString)e.nextElement(); } return new BEROctetString(v); } } bouncycastle-1.49.orig/src/org/bouncycastle/asn1/BERSequence.java0000644000175000017500000000255511703177363024327 0ustar ebourgebourgpackage org.bouncycastle.asn1; import java.io.IOException; import java.util.Enumeration; public class BERSequence extends ASN1Sequence { /** * create an empty sequence */ public BERSequence() { } /** * create a sequence containing one object */ public BERSequence( ASN1Encodable obj) { super(obj); } /** * create a sequence containing a vector of objects. */ public BERSequence( ASN1EncodableVector v) { super(v); } /** * create a sequence containing an array of objects. */ public BERSequence( ASN1Encodable[] array) { super(array); } int encodedLength() throws IOException { int length = 0; for (Enumeration e = getObjects(); e.hasMoreElements();) { length += ((ASN1Encodable)e.nextElement()).toASN1Primitive().encodedLength(); } return 2 + length + 2; } /* */ void encode( ASN1OutputStream out) throws IOException { out.write(BERTags.SEQUENCE | BERTags.CONSTRUCTED); out.write(0x80); Enumeration e = getObjects(); while (e.hasMoreElements()) { out.writeObject((ASN1Encodable)e.nextElement()); } out.write(0x00); out.write(0x00); } } bouncycastle-1.49.orig/src/org/bouncycastle/asn1/cryptopro/0000755000175000017500000000000012152033551023402 5ustar ebourgebourgbouncycastle-1.49.orig/src/org/bouncycastle/asn1/cryptopro/GOST3410PublicKeyAlgParameters.java0000644000175000017500000000541211726512011031612 0ustar ebourgebourgpackage org.bouncycastle.asn1.cryptopro; import org.bouncycastle.asn1.ASN1EncodableVector; import org.bouncycastle.asn1.ASN1Object; import org.bouncycastle.asn1.ASN1ObjectIdentifier; import org.bouncycastle.asn1.ASN1Primitive; import org.bouncycastle.asn1.ASN1Sequence; import org.bouncycastle.asn1.ASN1TaggedObject; import org.bouncycastle.asn1.DERSequence; public class GOST3410PublicKeyAlgParameters extends ASN1Object { private ASN1ObjectIdentifier publicKeyParamSet; private ASN1ObjectIdentifier digestParamSet; private ASN1ObjectIdentifier encryptionParamSet; public static GOST3410PublicKeyAlgParameters getInstance( ASN1TaggedObject obj, boolean explicit) { return getInstance(ASN1Sequence.getInstance(obj, explicit)); } public static GOST3410PublicKeyAlgParameters getInstance( Object obj) { if (obj instanceof GOST3410PublicKeyAlgParameters) { return (GOST3410PublicKeyAlgParameters)obj; } if(obj != null) { return new GOST3410PublicKeyAlgParameters(ASN1Sequence.getInstance(obj)); } return null; } public GOST3410PublicKeyAlgParameters( ASN1ObjectIdentifier publicKeyParamSet, ASN1ObjectIdentifier digestParamSet) { this.publicKeyParamSet = publicKeyParamSet; this.digestParamSet = digestParamSet; this.encryptionParamSet = null; } public GOST3410PublicKeyAlgParameters( ASN1ObjectIdentifier publicKeyParamSet, ASN1ObjectIdentifier digestParamSet, ASN1ObjectIdentifier encryptionParamSet) { this.publicKeyParamSet = publicKeyParamSet; this.digestParamSet = digestParamSet; this.encryptionParamSet = encryptionParamSet; } public GOST3410PublicKeyAlgParameters( ASN1Sequence seq) { this.publicKeyParamSet = (ASN1ObjectIdentifier)seq.getObjectAt(0); this.digestParamSet = (ASN1ObjectIdentifier)seq.getObjectAt(1); if (seq.size() > 2) { this.encryptionParamSet = (ASN1ObjectIdentifier)seq.getObjectAt(2); } } public ASN1ObjectIdentifier getPublicKeyParamSet() { return publicKeyParamSet; } public ASN1ObjectIdentifier getDigestParamSet() { return digestParamSet; } public ASN1ObjectIdentifier getEncryptionParamSet() { return encryptionParamSet; } public ASN1Primitive toASN1Primitive() { ASN1EncodableVector v = new ASN1EncodableVector(); v.add(publicKeyParamSet); v.add(digestParamSet); if (encryptionParamSet != null) { v.add(encryptionParamSet); } return new DERSequence(v); } } bouncycastle-1.49.orig/src/org/bouncycastle/asn1/cryptopro/GOST3410NamedParameters.java0000644000175000017500000001367511624622714030346 0ustar ebourgebourgpackage org.bouncycastle.asn1.cryptopro; import java.math.BigInteger; import java.util.Enumeration; import java.util.Hashtable; import org.bouncycastle.asn1.ASN1ObjectIdentifier; /** * table of the available named parameters for GOST 3410-94. */ public class GOST3410NamedParameters { static final Hashtable objIds = new Hashtable(); static final Hashtable params = new Hashtable(); static final Hashtable names = new Hashtable(); static private GOST3410ParamSetParameters cryptoProA = new GOST3410ParamSetParameters( 1024, new BigInteger("127021248288932417465907042777176443525787653508916535812817507265705031260985098497423188333483401180925999995120988934130659205614996724254121049274349357074920312769561451689224110579311248812610229678534638401693520013288995000362260684222750813532307004517341633685004541062586971416883686778842537820383"), new BigInteger("68363196144955700784444165611827252895102170888761442055095051287550314083023"), new BigInteger("100997906755055304772081815535925224869841082572053457874823515875577147990529272777244152852699298796483356699682842027972896052747173175480590485607134746852141928680912561502802222185647539190902656116367847270145019066794290930185446216399730872221732889830323194097355403213400972588322876850946740663962") // validationAlgorithm { // algorithm // id-GostR3410-94-bBis, // parameters // GostR3410-94-ValidationBisParameters: { // x0 1376285941, // c 3996757427 // } // } ); static private GOST3410ParamSetParameters cryptoProB = new GOST3410ParamSetParameters( 1024, new BigInteger("139454871199115825601409655107690713107041707059928031797758001454375765357722984094124368522288239833039114681648076688236921220737322672160740747771700911134550432053804647694904686120113087816240740184800477047157336662926249423571248823968542221753660143391485680840520336859458494803187341288580489525163"), new BigInteger("79885141663410976897627118935756323747307951916507639758300472692338873533959"), new BigInteger("42941826148615804143873447737955502392672345968607143066798112994089471231420027060385216699563848719957657284814898909770759462613437669456364882730370838934791080835932647976778601915343474400961034231316672578686920482194932878633360203384797092684342247621055760235016132614780652761028509445403338652341") // validationAlgorithm { // algorithm // id-GostR3410-94-bBis, // parameters // GostR3410-94-ValidationBisParameters: { // x0 1536654555, // c 1855361757, // d 14408629386140014567655 //4902939282056547857802241461782996702017713059974755104394739915140 //6115284791024439062735788342744854120601660303926203867703556828005 //8957203818114895398976594425537561271800850306 // } // } //} ); static private GOST3410ParamSetParameters cryptoProXchA = new GOST3410ParamSetParameters( 1024, new BigInteger("142011741597563481196368286022318089743276138395243738762872573441927459393512718973631166078467600360848946623567625795282774719212241929071046134208380636394084512691828894000571524625445295769349356752728956831541775441763139384457191755096847107846595662547942312293338483924514339614727760681880609734239"), new BigInteger("91771529896554605945588149018382750217296858393520724172743325725474374979801"), new BigInteger("133531813272720673433859519948319001217942375967847486899482359599369642528734712461590403327731821410328012529253871914788598993103310567744136196364803064721377826656898686468463277710150809401182608770201615324990468332931294920912776241137878030224355746606283971659376426832674269780880061631528163475887") ); static { params.put(CryptoProObjectIdentifiers.gostR3410_94_CryptoPro_A, cryptoProA); params.put(CryptoProObjectIdentifiers.gostR3410_94_CryptoPro_B, cryptoProB); // params.put(CryptoProObjectIdentifiers.gostR3410_94_CryptoPro_C, cryptoProC); // params.put(CryptoProObjectIdentifiers.gostR3410_94_CryptoPro_D, cryptoProD); params.put(CryptoProObjectIdentifiers.gostR3410_94_CryptoPro_XchA, cryptoProXchA); // params.put(CryptoProObjectIdentifiers.gostR3410_94_CryptoPro_XchB, cryptoProXchA); // params.put(CryptoProObjectIdentifiers.gostR3410_94_CryptoPro_XchC, cryptoProXchA); objIds.put("GostR3410-94-CryptoPro-A", CryptoProObjectIdentifiers.gostR3410_94_CryptoPro_A); objIds.put("GostR3410-94-CryptoPro-B", CryptoProObjectIdentifiers.gostR3410_94_CryptoPro_B); objIds.put("GostR3410-94-CryptoPro-XchA", CryptoProObjectIdentifiers.gostR3410_94_CryptoPro_XchA); } /** * return the GOST3410ParamSetParameters object for the given OID, null if it * isn't present. * * @param oid an object identifier representing a named parameters, if present. */ public static GOST3410ParamSetParameters getByOID( ASN1ObjectIdentifier oid) { return (GOST3410ParamSetParameters)params.get(oid); } /** * returns an enumeration containing the name strings for parameters * contained in this structure. */ public static Enumeration getNames() { return objIds.keys(); } public static GOST3410ParamSetParameters getByName( String name) { ASN1ObjectIdentifier oid = (ASN1ObjectIdentifier)objIds.get(name); if (oid != null) { return (GOST3410ParamSetParameters)params.get(oid); } return null; } public static ASN1ObjectIdentifier getOID(String name) { return (ASN1ObjectIdentifier)objIds.get(name); } } bouncycastle-1.49.orig/src/org/bouncycastle/asn1/cryptopro/GOST3410ParamSetParameters.java0000644000175000017500000000467011724561171031031 0ustar ebourgebourgpackage org.bouncycastle.asn1.cryptopro; import java.math.BigInteger; import java.util.Enumeration; import org.bouncycastle.asn1.ASN1EncodableVector; import org.bouncycastle.asn1.ASN1Integer; import org.bouncycastle.asn1.ASN1Object; import org.bouncycastle.asn1.ASN1Primitive; import org.bouncycastle.asn1.ASN1Sequence; import org.bouncycastle.asn1.ASN1TaggedObject; import org.bouncycastle.asn1.DERSequence; public class GOST3410ParamSetParameters extends ASN1Object { int keySize; ASN1Integer p, q, a; public static GOST3410ParamSetParameters getInstance( ASN1TaggedObject obj, boolean explicit) { return getInstance(ASN1Sequence.getInstance(obj, explicit)); } public static GOST3410ParamSetParameters getInstance( Object obj) { if(obj == null || obj instanceof GOST3410ParamSetParameters) { return (GOST3410ParamSetParameters)obj; } if(obj instanceof ASN1Sequence) { return new GOST3410ParamSetParameters((ASN1Sequence)obj); } throw new IllegalArgumentException("Invalid GOST3410Parameter: " + obj.getClass().getName()); } public GOST3410ParamSetParameters( int keySize, BigInteger p, BigInteger q, BigInteger a) { this.keySize = keySize; this.p = new ASN1Integer(p); this.q = new ASN1Integer(q); this.a = new ASN1Integer(a); } public GOST3410ParamSetParameters( ASN1Sequence seq) { Enumeration e = seq.getObjects(); keySize = ((ASN1Integer)e.nextElement()).getValue().intValue(); p = (ASN1Integer)e.nextElement(); q = (ASN1Integer)e.nextElement(); a = (ASN1Integer)e.nextElement(); } /** * @deprecated use getKeySize */ public int getLKeySize() { return keySize; } public int getKeySize() { return keySize; } public BigInteger getP() { return p.getPositiveValue(); } public BigInteger getQ() { return q.getPositiveValue(); } public BigInteger getA() { return a.getPositiveValue(); } public ASN1Primitive toASN1Primitive() { ASN1EncodableVector v = new ASN1EncodableVector(); v.add(new ASN1Integer(keySize)); v.add(p); v.add(q); v.add(a); return new DERSequence(v); } } bouncycastle-1.49.orig/src/org/bouncycastle/asn1/cryptopro/CryptoProObjectIdentifiers.java0000644000175000017500000000631212002421271031517 0ustar ebourgebourgpackage org.bouncycastle.asn1.cryptopro; import org.bouncycastle.asn1.ASN1ObjectIdentifier; public interface CryptoProObjectIdentifiers { // GOST Algorithms OBJECT IDENTIFIERS : // { iso(1) member-body(2) ru(643) rans(2) cryptopro(2)} static final ASN1ObjectIdentifier GOST_id = new ASN1ObjectIdentifier("1.2.643.2.2"); static final ASN1ObjectIdentifier gostR3411 = GOST_id.branch("9"); static final ASN1ObjectIdentifier gostR3411Hmac = GOST_id.branch("10"); static final ASN1ObjectIdentifier gostR28147_cbc = new ASN1ObjectIdentifier(GOST_id+".21"); static final ASN1ObjectIdentifier id_Gost28147_89_CryptoPro_A_ParamSet = GOST_id.branch("31.1"); static final ASN1ObjectIdentifier gostR3410_94 = new ASN1ObjectIdentifier(GOST_id+".20"); static final ASN1ObjectIdentifier gostR3410_2001 = new ASN1ObjectIdentifier(GOST_id+".19"); static final ASN1ObjectIdentifier gostR3411_94_with_gostR3410_94 = new ASN1ObjectIdentifier(GOST_id+".4"); static final ASN1ObjectIdentifier gostR3411_94_with_gostR3410_2001 = new ASN1ObjectIdentifier(GOST_id+".3"); // { iso(1) member-body(2) ru(643) rans(2) cryptopro(2) hashes(30) } static final ASN1ObjectIdentifier gostR3411_94_CryptoProParamSet = new ASN1ObjectIdentifier(GOST_id+".30.1"); // { iso(1) member-body(2) ru(643) rans(2) cryptopro(2) signs(32) } static final ASN1ObjectIdentifier gostR3410_94_CryptoPro_A = new ASN1ObjectIdentifier(GOST_id+".32.2"); static final ASN1ObjectIdentifier gostR3410_94_CryptoPro_B = new ASN1ObjectIdentifier(GOST_id+".32.3"); static final ASN1ObjectIdentifier gostR3410_94_CryptoPro_C = new ASN1ObjectIdentifier(GOST_id+".32.4"); static final ASN1ObjectIdentifier gostR3410_94_CryptoPro_D = new ASN1ObjectIdentifier(GOST_id+".32.5"); // { iso(1) member-body(2) ru(643) rans(2) cryptopro(2) exchanges(33) } static final ASN1ObjectIdentifier gostR3410_94_CryptoPro_XchA = new ASN1ObjectIdentifier(GOST_id+".33.1"); static final ASN1ObjectIdentifier gostR3410_94_CryptoPro_XchB = new ASN1ObjectIdentifier(GOST_id+".33.2"); static final ASN1ObjectIdentifier gostR3410_94_CryptoPro_XchC = new ASN1ObjectIdentifier(GOST_id+".33.3"); //{ iso(1) member-body(2)ru(643) rans(2) cryptopro(2) ecc-signs(35) } static final ASN1ObjectIdentifier gostR3410_2001_CryptoPro_A = new ASN1ObjectIdentifier(GOST_id+".35.1"); static final ASN1ObjectIdentifier gostR3410_2001_CryptoPro_B = new ASN1ObjectIdentifier(GOST_id+".35.2"); static final ASN1ObjectIdentifier gostR3410_2001_CryptoPro_C = new ASN1ObjectIdentifier(GOST_id+".35.3"); // { iso(1) member-body(2) ru(643) rans(2) cryptopro(2) ecc-exchanges(36) } static final ASN1ObjectIdentifier gostR3410_2001_CryptoPro_XchA = new ASN1ObjectIdentifier(GOST_id+".36.0"); static final ASN1ObjectIdentifier gostR3410_2001_CryptoPro_XchB = new ASN1ObjectIdentifier(GOST_id+".36.1"); static final ASN1ObjectIdentifier gost_ElSgDH3410_default = new ASN1ObjectIdentifier(GOST_id+".36.0"); static final ASN1ObjectIdentifier gost_ElSgDH3410_1 = new ASN1ObjectIdentifier(GOST_id+".36.1"); } bouncycastle-1.49.orig/src/org/bouncycastle/asn1/cryptopro/GOST28147Parameters.java0000644000175000017500000000362711624652565027502 0ustar ebourgebourgpackage org.bouncycastle.asn1.cryptopro; import java.util.Enumeration; import org.bouncycastle.asn1.ASN1EncodableVector; import org.bouncycastle.asn1.ASN1Object; import org.bouncycastle.asn1.ASN1ObjectIdentifier; import org.bouncycastle.asn1.ASN1OctetString; import org.bouncycastle.asn1.ASN1Primitive; import org.bouncycastle.asn1.ASN1Sequence; import org.bouncycastle.asn1.ASN1TaggedObject; import org.bouncycastle.asn1.DERSequence; public class GOST28147Parameters extends ASN1Object { ASN1OctetString iv; ASN1ObjectIdentifier paramSet; public static GOST28147Parameters getInstance( ASN1TaggedObject obj, boolean explicit) { return getInstance(ASN1Sequence.getInstance(obj, explicit)); } public static GOST28147Parameters getInstance( Object obj) { if(obj == null || obj instanceof GOST28147Parameters) { return (GOST28147Parameters)obj; } if(obj instanceof ASN1Sequence) { return new GOST28147Parameters((ASN1Sequence)obj); } throw new IllegalArgumentException("Invalid GOST3410Parameter: " + obj.getClass().getName()); } public GOST28147Parameters( ASN1Sequence seq) { Enumeration e = seq.getObjects(); iv = (ASN1OctetString)e.nextElement(); paramSet = (ASN1ObjectIdentifier)e.nextElement(); } /** *

         * Gost28147-89-Parameters ::=
         *               SEQUENCE {
         *                       iv                   Gost28147-89-IV,
         *                       encryptionParamSet   OBJECT IDENTIFIER
         *                }
         *
         *   Gost28147-89-IV ::= OCTET STRING (SIZE (8))
         * 
    */ public ASN1Primitive toASN1Primitive() { ASN1EncodableVector v = new ASN1EncodableVector(); v.add(iv); v.add(paramSet); return new DERSequence(v); } } bouncycastle-1.49.orig/src/org/bouncycastle/asn1/cryptopro/ECGOST3410ParamSetParameters.java0000644000175000017500000000467311724561172031245 0ustar ebourgebourgpackage org.bouncycastle.asn1.cryptopro; import java.math.BigInteger; import java.util.Enumeration; import org.bouncycastle.asn1.ASN1EncodableVector; import org.bouncycastle.asn1.ASN1Integer; import org.bouncycastle.asn1.ASN1Object; import org.bouncycastle.asn1.ASN1Primitive; import org.bouncycastle.asn1.ASN1Sequence; import org.bouncycastle.asn1.ASN1TaggedObject; import org.bouncycastle.asn1.DERSequence; public class ECGOST3410ParamSetParameters extends ASN1Object { ASN1Integer p, q, a, b, x, y; public static ECGOST3410ParamSetParameters getInstance( ASN1TaggedObject obj, boolean explicit) { return getInstance(ASN1Sequence.getInstance(obj, explicit)); } public static ECGOST3410ParamSetParameters getInstance( Object obj) { if(obj == null || obj instanceof ECGOST3410ParamSetParameters) { return (ECGOST3410ParamSetParameters)obj; } if(obj instanceof ASN1Sequence) { return new ECGOST3410ParamSetParameters((ASN1Sequence)obj); } throw new IllegalArgumentException("Invalid GOST3410Parameter: " + obj.getClass().getName()); } public ECGOST3410ParamSetParameters( BigInteger a, BigInteger b, BigInteger p, BigInteger q, int x, BigInteger y) { this.a = new ASN1Integer(a); this.b = new ASN1Integer(b); this.p = new ASN1Integer(p); this.q = new ASN1Integer(q); this.x = new ASN1Integer(x); this.y = new ASN1Integer(y); } public ECGOST3410ParamSetParameters( ASN1Sequence seq) { Enumeration e = seq.getObjects(); a = (ASN1Integer)e.nextElement(); b = (ASN1Integer)e.nextElement(); p = (ASN1Integer)e.nextElement(); q = (ASN1Integer)e.nextElement(); x = (ASN1Integer)e.nextElement(); y = (ASN1Integer)e.nextElement(); } public BigInteger getP() { return p.getPositiveValue(); } public BigInteger getQ() { return q.getPositiveValue(); } public BigInteger getA() { return a.getPositiveValue(); } public ASN1Primitive toASN1Primitive() { ASN1EncodableVector v = new ASN1EncodableVector(); v.add(a); v.add(b); v.add(p); v.add(q); v.add(x); v.add(y); return new DERSequence(v); } } bouncycastle-1.49.orig/src/org/bouncycastle/asn1/cryptopro/ECGOST3410NamedCurves.java0000644000175000017500000001676111624622714027721 0ustar ebourgebourgpackage org.bouncycastle.asn1.cryptopro; import java.math.BigInteger; import java.util.Enumeration; import java.util.Hashtable; import org.bouncycastle.asn1.ASN1ObjectIdentifier; import org.bouncycastle.crypto.params.ECDomainParameters; import org.bouncycastle.math.ec.ECCurve; import org.bouncycastle.math.ec.ECFieldElement; import org.bouncycastle.math.ec.ECPoint; /** * table of the available named parameters for GOST 3410-2001. */ public class ECGOST3410NamedCurves { static final Hashtable objIds = new Hashtable(); static final Hashtable params = new Hashtable(); static final Hashtable names = new Hashtable(); static { BigInteger mod_p = new BigInteger("115792089237316195423570985008687907853269984665640564039457584007913129639319"); BigInteger mod_q = new BigInteger("115792089237316195423570985008687907853073762908499243225378155805079068850323"); ECCurve.Fp curve = new ECCurve.Fp( mod_p, // p new BigInteger("115792089237316195423570985008687907853269984665640564039457584007913129639316"), // a new BigInteger("166")); // b ECDomainParameters ecParams = new ECDomainParameters( curve, new ECPoint.Fp(curve, new ECFieldElement.Fp(curve.getQ(),new BigInteger("1")), // x new ECFieldElement.Fp(curve.getQ(),new BigInteger("64033881142927202683649881450433473985931760268884941288852745803908878638612"))), // y mod_q); params.put(CryptoProObjectIdentifiers.gostR3410_2001_CryptoPro_A, ecParams); mod_p = new BigInteger("115792089237316195423570985008687907853269984665640564039457584007913129639319"); mod_q = new BigInteger("115792089237316195423570985008687907853073762908499243225378155805079068850323"); curve = new ECCurve.Fp( mod_p, // p new BigInteger("115792089237316195423570985008687907853269984665640564039457584007913129639316"), new BigInteger("166")); ecParams = new ECDomainParameters( curve, new ECPoint.Fp(curve, new ECFieldElement.Fp(curve.getQ(),new BigInteger("1")), // x new ECFieldElement.Fp(curve.getQ(),new BigInteger("64033881142927202683649881450433473985931760268884941288852745803908878638612"))), // y mod_q); params.put(CryptoProObjectIdentifiers.gostR3410_2001_CryptoPro_XchA, ecParams); mod_p = new BigInteger("57896044618658097711785492504343953926634992332820282019728792003956564823193"); //p mod_q = new BigInteger("57896044618658097711785492504343953927102133160255826820068844496087732066703"); //q curve = new ECCurve.Fp( mod_p, // p new BigInteger("57896044618658097711785492504343953926634992332820282019728792003956564823190"), // a new BigInteger("28091019353058090096996979000309560759124368558014865957655842872397301267595")); // b ecParams = new ECDomainParameters( curve, new ECPoint.Fp(curve, new ECFieldElement.Fp(mod_p,new BigInteger("1")), // x new ECFieldElement.Fp(mod_p,new BigInteger("28792665814854611296992347458380284135028636778229113005756334730996303888124"))), // y mod_q); // q params.put(CryptoProObjectIdentifiers.gostR3410_2001_CryptoPro_B, ecParams); mod_p = new BigInteger("70390085352083305199547718019018437841079516630045180471284346843705633502619"); mod_q = new BigInteger("70390085352083305199547718019018437840920882647164081035322601458352298396601"); curve = new ECCurve.Fp( mod_p, // p new BigInteger("70390085352083305199547718019018437841079516630045180471284346843705633502616"), new BigInteger("32858")); ecParams = new ECDomainParameters( curve, new ECPoint.Fp(curve, new ECFieldElement.Fp(mod_p,new BigInteger("0")), new ECFieldElement.Fp(mod_p,new BigInteger("29818893917731240733471273240314769927240550812383695689146495261604565990247"))), mod_q); params.put(CryptoProObjectIdentifiers.gostR3410_2001_CryptoPro_XchB, ecParams); mod_p = new BigInteger("70390085352083305199547718019018437841079516630045180471284346843705633502619"); //p mod_q = new BigInteger("70390085352083305199547718019018437840920882647164081035322601458352298396601"); //q curve = new ECCurve.Fp( mod_p, // p new BigInteger("70390085352083305199547718019018437841079516630045180471284346843705633502616"), // a new BigInteger("32858")); // b ecParams = new ECDomainParameters( curve, new ECPoint.Fp(curve, new ECFieldElement.Fp(mod_p,new BigInteger("0")), // x new ECFieldElement.Fp(mod_p,new BigInteger("29818893917731240733471273240314769927240550812383695689146495261604565990247"))), // y mod_q); // q params.put(CryptoProObjectIdentifiers.gostR3410_2001_CryptoPro_C, ecParams); objIds.put("GostR3410-2001-CryptoPro-A", CryptoProObjectIdentifiers.gostR3410_2001_CryptoPro_A); objIds.put("GostR3410-2001-CryptoPro-B", CryptoProObjectIdentifiers.gostR3410_2001_CryptoPro_B); objIds.put("GostR3410-2001-CryptoPro-C", CryptoProObjectIdentifiers.gostR3410_2001_CryptoPro_C); objIds.put("GostR3410-2001-CryptoPro-XchA", CryptoProObjectIdentifiers.gostR3410_2001_CryptoPro_XchA); objIds.put("GostR3410-2001-CryptoPro-XchB", CryptoProObjectIdentifiers.gostR3410_2001_CryptoPro_XchB); names.put(CryptoProObjectIdentifiers.gostR3410_2001_CryptoPro_A, "GostR3410-2001-CryptoPro-A"); names.put(CryptoProObjectIdentifiers.gostR3410_2001_CryptoPro_B, "GostR3410-2001-CryptoPro-B"); names.put(CryptoProObjectIdentifiers.gostR3410_2001_CryptoPro_C, "GostR3410-2001-CryptoPro-C"); names.put(CryptoProObjectIdentifiers.gostR3410_2001_CryptoPro_XchA, "GostR3410-2001-CryptoPro-XchA"); names.put(CryptoProObjectIdentifiers.gostR3410_2001_CryptoPro_XchB, "GostR3410-2001-CryptoPro-XchB"); } /** * return the ECDomainParameters object for the given OID, null if it * isn't present. * * @param oid an object identifier representing a named parameters, if present. */ public static ECDomainParameters getByOID( ASN1ObjectIdentifier oid) { return (ECDomainParameters)params.get(oid); } /** * returns an enumeration containing the name strings for parameters * contained in this structure. */ public static Enumeration getNames() { return objIds.keys(); } public static ECDomainParameters getByName( String name) { ASN1ObjectIdentifier oid = (ASN1ObjectIdentifier)objIds.get(name); if (oid != null) { return (ECDomainParameters)params.get(oid); } return null; } /** * return the named curve name represented by the given object identifier. */ public static String getName( ASN1ObjectIdentifier oid) { return (String)names.get(oid); } public static ASN1ObjectIdentifier getOID(String name) { return (ASN1ObjectIdentifier)objIds.get(name); } } bouncycastle-1.49.orig/src/org/bouncycastle/asn1/cryptopro/package.html0000644000175000017500000000017310262753175025677 0ustar ebourgebourg Support classes for CRYPTO-PRO related objects - such as GOST identifiers. bouncycastle-1.49.orig/src/org/bouncycastle/asn1/ASN1Boolean.java0000644000175000017500000000033511624614575024225 0ustar ebourgebourgpackage org.bouncycastle.asn1; public class ASN1Boolean extends DERBoolean { public ASN1Boolean(boolean value) { super(value); } ASN1Boolean(byte[] value) { super(value); } } bouncycastle-1.49.orig/src/org/bouncycastle/asn1/ocsp/0000755000175000017500000000000012152033551022305 5ustar ebourgebourgbouncycastle-1.49.orig/src/org/bouncycastle/asn1/ocsp/RevokedInfo.java0000644000175000017500000000466511736761350025412 0ustar ebourgebourgpackage org.bouncycastle.asn1.ocsp; import org.bouncycastle.asn1.ASN1EncodableVector; import org.bouncycastle.asn1.ASN1GeneralizedTime; import org.bouncycastle.asn1.ASN1Object; import org.bouncycastle.asn1.ASN1Primitive; import org.bouncycastle.asn1.ASN1Sequence; import org.bouncycastle.asn1.ASN1TaggedObject; import org.bouncycastle.asn1.DEREnumerated; import org.bouncycastle.asn1.DERSequence; import org.bouncycastle.asn1.DERTaggedObject; import org.bouncycastle.asn1.x509.CRLReason; public class RevokedInfo extends ASN1Object { private ASN1GeneralizedTime revocationTime; private CRLReason revocationReason; public RevokedInfo( ASN1GeneralizedTime revocationTime, CRLReason revocationReason) { this.revocationTime = revocationTime; this.revocationReason = revocationReason; } private RevokedInfo( ASN1Sequence seq) { this.revocationTime = ASN1GeneralizedTime.getInstance(seq.getObjectAt(0)); if (seq.size() > 1) { this.revocationReason = CRLReason.getInstance(DEREnumerated.getInstance( (ASN1TaggedObject)seq.getObjectAt(1), true)); } } public static RevokedInfo getInstance( ASN1TaggedObject obj, boolean explicit) { return getInstance(ASN1Sequence.getInstance(obj, explicit)); } public static RevokedInfo getInstance( Object obj) { if (obj instanceof RevokedInfo) { return (RevokedInfo)obj; } else if (obj != null) { return new RevokedInfo(ASN1Sequence.getInstance(obj)); } return null; } public ASN1GeneralizedTime getRevocationTime() { return revocationTime; } public CRLReason getRevocationReason() { return revocationReason; } /** * Produce an object suitable for an ASN1OutputStream. *
         * RevokedInfo ::= SEQUENCE {
         *      revocationTime              GeneralizedTime,
         *      revocationReason    [0]     EXPLICIT CRLReason OPTIONAL }
         * 
    */ public ASN1Primitive toASN1Primitive() { ASN1EncodableVector v = new ASN1EncodableVector(); v.add(revocationTime); if (revocationReason != null) { v.add(new DERTaggedObject(true, 0, revocationReason)); } return new DERSequence(v); } } bouncycastle-1.49.orig/src/org/bouncycastle/asn1/ocsp/OCSPRequest.java0000644000175000017500000000430011710123224025256 0ustar ebourgebourgpackage org.bouncycastle.asn1.ocsp; import org.bouncycastle.asn1.ASN1EncodableVector; import org.bouncycastle.asn1.ASN1Object; import org.bouncycastle.asn1.ASN1Primitive; import org.bouncycastle.asn1.ASN1Sequence; import org.bouncycastle.asn1.ASN1TaggedObject; import org.bouncycastle.asn1.DERSequence; import org.bouncycastle.asn1.DERTaggedObject; public class OCSPRequest extends ASN1Object { TBSRequest tbsRequest; Signature optionalSignature; public OCSPRequest( TBSRequest tbsRequest, Signature optionalSignature) { this.tbsRequest = tbsRequest; this.optionalSignature = optionalSignature; } private OCSPRequest( ASN1Sequence seq) { tbsRequest = TBSRequest.getInstance(seq.getObjectAt(0)); if (seq.size() == 2) { optionalSignature = Signature.getInstance( (ASN1TaggedObject)seq.getObjectAt(1), true); } } public static OCSPRequest getInstance( ASN1TaggedObject obj, boolean explicit) { return getInstance(ASN1Sequence.getInstance(obj, explicit)); } public static OCSPRequest getInstance( Object obj) { if (obj instanceof OCSPRequest) { return (OCSPRequest)obj; } else if (obj != null) { return new OCSPRequest(ASN1Sequence.getInstance(obj)); } return null; } public TBSRequest getTbsRequest() { return tbsRequest; } public Signature getOptionalSignature() { return optionalSignature; } /** * Produce an object suitable for an ASN1OutputStream. *
         * OCSPRequest     ::=     SEQUENCE {
         *     tbsRequest                  TBSRequest,
         *     optionalSignature   [0]     EXPLICIT Signature OPTIONAL }
         * 
    */ public ASN1Primitive toASN1Primitive() { ASN1EncodableVector v = new ASN1EncodableVector(); v.add(tbsRequest); if (optionalSignature != null) { v.add(new DERTaggedObject(true, 0, optionalSignature)); } return new DERSequence(v); } } bouncycastle-1.49.orig/src/org/bouncycastle/asn1/ocsp/BasicOCSPResponse.java0000644000175000017500000000603711710123224026377 0ustar ebourgebourgpackage org.bouncycastle.asn1.ocsp; import org.bouncycastle.asn1.ASN1EncodableVector; import org.bouncycastle.asn1.ASN1Object; import org.bouncycastle.asn1.ASN1Primitive; import org.bouncycastle.asn1.ASN1Sequence; import org.bouncycastle.asn1.ASN1TaggedObject; import org.bouncycastle.asn1.DERBitString; import org.bouncycastle.asn1.DERSequence; import org.bouncycastle.asn1.DERTaggedObject; import org.bouncycastle.asn1.x509.AlgorithmIdentifier; public class BasicOCSPResponse extends ASN1Object { private ResponseData tbsResponseData; private AlgorithmIdentifier signatureAlgorithm; private DERBitString signature; private ASN1Sequence certs; public BasicOCSPResponse( ResponseData tbsResponseData, AlgorithmIdentifier signatureAlgorithm, DERBitString signature, ASN1Sequence certs) { this.tbsResponseData = tbsResponseData; this.signatureAlgorithm = signatureAlgorithm; this.signature = signature; this.certs = certs; } private BasicOCSPResponse( ASN1Sequence seq) { this.tbsResponseData = ResponseData.getInstance(seq.getObjectAt(0)); this.signatureAlgorithm = AlgorithmIdentifier.getInstance(seq.getObjectAt(1)); this.signature = (DERBitString)seq.getObjectAt(2); if (seq.size() > 3) { this.certs = ASN1Sequence.getInstance((ASN1TaggedObject)seq.getObjectAt(3), true); } } public static BasicOCSPResponse getInstance( ASN1TaggedObject obj, boolean explicit) { return getInstance(ASN1Sequence.getInstance(obj, explicit)); } public static BasicOCSPResponse getInstance( Object obj) { if (obj instanceof BasicOCSPResponse) { return (BasicOCSPResponse)obj; } else if (obj != null) { return new BasicOCSPResponse(ASN1Sequence.getInstance(obj)); } return null; } public ResponseData getTbsResponseData() { return tbsResponseData; } public AlgorithmIdentifier getSignatureAlgorithm() { return signatureAlgorithm; } public DERBitString getSignature() { return signature; } public ASN1Sequence getCerts() { return certs; } /** * Produce an object suitable for an ASN1OutputStream. *
         * BasicOCSPResponse       ::= SEQUENCE {
         *      tbsResponseData      ResponseData,
         *      signatureAlgorithm   AlgorithmIdentifier,
         *      signature            BIT STRING,
         *      certs                [0] EXPLICIT SEQUENCE OF Certificate OPTIONAL }
         * 
    */ public ASN1Primitive toASN1Primitive() { ASN1EncodableVector v = new ASN1EncodableVector(); v.add(tbsResponseData); v.add(signatureAlgorithm); v.add(signature); if (certs != null) { v.add(new DERTaggedObject(true, 0, certs)); } return new DERSequence(v); } } bouncycastle-1.49.orig/src/org/bouncycastle/asn1/ocsp/ResponseBytes.java0000644000175000017500000000413711624625016025770 0ustar ebourgebourgpackage org.bouncycastle.asn1.ocsp; import org.bouncycastle.asn1.ASN1EncodableVector; import org.bouncycastle.asn1.ASN1Object; import org.bouncycastle.asn1.ASN1ObjectIdentifier; import org.bouncycastle.asn1.ASN1OctetString; import org.bouncycastle.asn1.ASN1Primitive; import org.bouncycastle.asn1.ASN1Sequence; import org.bouncycastle.asn1.ASN1TaggedObject; import org.bouncycastle.asn1.DERSequence; public class ResponseBytes extends ASN1Object { ASN1ObjectIdentifier responseType; ASN1OctetString response; public ResponseBytes( ASN1ObjectIdentifier responseType, ASN1OctetString response) { this.responseType = responseType; this.response = response; } public ResponseBytes( ASN1Sequence seq) { responseType = (ASN1ObjectIdentifier)seq.getObjectAt(0); response = (ASN1OctetString)seq.getObjectAt(1); } public static ResponseBytes getInstance( ASN1TaggedObject obj, boolean explicit) { return getInstance(ASN1Sequence.getInstance(obj, explicit)); } public static ResponseBytes getInstance( Object obj) { if (obj == null || obj instanceof ResponseBytes) { return (ResponseBytes)obj; } else if (obj instanceof ASN1Sequence) { return new ResponseBytes((ASN1Sequence)obj); } throw new IllegalArgumentException("unknown object in factory: " + obj.getClass().getName()); } public ASN1ObjectIdentifier getResponseType() { return responseType; } public ASN1OctetString getResponse() { return response; } /** * Produce an object suitable for an ASN1OutputStream. *
         * ResponseBytes ::=       SEQUENCE {
         *     responseType   OBJECT IDENTIFIER,
         *     response       OCTET STRING }
         * 
    */ public ASN1Primitive toASN1Primitive() { ASN1EncodableVector v = new ASN1EncodableVector(); v.add(responseType); v.add(response); return new DERSequence(v); } } bouncycastle-1.49.orig/src/org/bouncycastle/asn1/ocsp/ServiceLocator.java0000644000175000017500000000151511624647401026106 0ustar ebourgebourgpackage org.bouncycastle.asn1.ocsp; import org.bouncycastle.asn1.ASN1EncodableVector; import org.bouncycastle.asn1.ASN1Object; import org.bouncycastle.asn1.ASN1Primitive; import org.bouncycastle.asn1.DERSequence; import org.bouncycastle.asn1.x500.X500Name; public class ServiceLocator extends ASN1Object { X500Name issuer; ASN1Primitive locator; /** * Produce an object suitable for an ASN1OutputStream. *
         * ServiceLocator ::= SEQUENCE {
         *     issuer    Name,
         *     locator   AuthorityInfoAccessSyntax OPTIONAL }
         * 
    */ public ASN1Primitive toASN1Primitive() { ASN1EncodableVector v = new ASN1EncodableVector(); v.add(issuer); if (locator != null) { v.add(locator); } return new DERSequence(v); } } bouncycastle-1.49.orig/src/org/bouncycastle/asn1/ocsp/ResponderID.java0000644000175000017500000000500012151251423025320 0ustar ebourgebourgpackage org.bouncycastle.asn1.ocsp; import org.bouncycastle.asn1.ASN1Choice; import org.bouncycastle.asn1.ASN1Encodable; import org.bouncycastle.asn1.ASN1Object; import org.bouncycastle.asn1.ASN1OctetString; import org.bouncycastle.asn1.ASN1Primitive; import org.bouncycastle.asn1.ASN1TaggedObject; import org.bouncycastle.asn1.DEROctetString; import org.bouncycastle.asn1.DERTaggedObject; import org.bouncycastle.asn1.x500.X500Name; public class ResponderID extends ASN1Object implements ASN1Choice { private ASN1Encodable value; public ResponderID( ASN1OctetString value) { this.value = value; } public ResponderID( X500Name value) { this.value = value; } public static ResponderID getInstance( Object obj) { if (obj instanceof ResponderID) { return (ResponderID)obj; } else if (obj instanceof DEROctetString) { return new ResponderID((DEROctetString)obj); } else if (obj instanceof ASN1TaggedObject) { ASN1TaggedObject o = (ASN1TaggedObject)obj; if (o.getTagNo() == 1) { return new ResponderID(X500Name.getInstance(o, true)); } else { return new ResponderID(ASN1OctetString.getInstance(o, true)); } } return new ResponderID(X500Name.getInstance(obj)); } public static ResponderID getInstance( ASN1TaggedObject obj, boolean explicit) { return getInstance(obj.getObject()); // must be explicitly tagged } public byte[] getKeyHash() { if (this.value instanceof ASN1OctetString) { ASN1OctetString octetString = (ASN1OctetString)this.value; return octetString.getOctets(); } return null; } public X500Name getName() { if (this.value instanceof ASN1OctetString) { return null; } return X500Name.getInstance(value); } /** * Produce an object suitable for an ASN1OutputStream. *
         * ResponderID ::= CHOICE {
         *      byName          [1] Name,
         *      byKey           [2] KeyHash }
         * 
    */ public ASN1Primitive toASN1Primitive() { if (value instanceof ASN1OctetString) { return new DERTaggedObject(true, 2, value); } return new DERTaggedObject(true, 1, value); } } bouncycastle-1.49.orig/src/org/bouncycastle/asn1/ocsp/SingleResponse.java0000644000175000017500000001224511737210072026117 0ustar ebourgebourgpackage org.bouncycastle.asn1.ocsp; import org.bouncycastle.asn1.ASN1EncodableVector; import org.bouncycastle.asn1.ASN1GeneralizedTime; import org.bouncycastle.asn1.ASN1Object; import org.bouncycastle.asn1.ASN1Primitive; import org.bouncycastle.asn1.ASN1Sequence; import org.bouncycastle.asn1.ASN1TaggedObject; import org.bouncycastle.asn1.DERGeneralizedTime; import org.bouncycastle.asn1.DERSequence; import org.bouncycastle.asn1.DERTaggedObject; import org.bouncycastle.asn1.x509.Extensions; import org.bouncycastle.asn1.x509.X509Extensions; public class SingleResponse extends ASN1Object { private CertID certID; private CertStatus certStatus; private ASN1GeneralizedTime thisUpdate; private ASN1GeneralizedTime nextUpdate; private Extensions singleExtensions; /** * @deprecated use method taking ASN1GeneralizedTime and Extensions * @param certID * @param certStatus * @param thisUpdate * @param nextUpdate * @param singleExtensions */ public SingleResponse( CertID certID, CertStatus certStatus, DERGeneralizedTime thisUpdate, DERGeneralizedTime nextUpdate, X509Extensions singleExtensions) { this(certID, certStatus, thisUpdate, nextUpdate, Extensions.getInstance(singleExtensions)); } /** * @deprecated use method taking ASN1GeneralizedTime and Extensions * @param certID * @param certStatus * @param thisUpdate * @param nextUpdate * @param singleExtensions */ public SingleResponse( CertID certID, CertStatus certStatus, DERGeneralizedTime thisUpdate, DERGeneralizedTime nextUpdate, Extensions singleExtensions) { this(certID, certStatus, ASN1GeneralizedTime.getInstance(thisUpdate), ASN1GeneralizedTime.getInstance(nextUpdate), Extensions.getInstance(singleExtensions)); } public SingleResponse( CertID certID, CertStatus certStatus, ASN1GeneralizedTime thisUpdate, ASN1GeneralizedTime nextUpdate, Extensions singleExtensions) { this.certID = certID; this.certStatus = certStatus; this.thisUpdate = thisUpdate; this.nextUpdate = nextUpdate; this.singleExtensions = singleExtensions; } private SingleResponse( ASN1Sequence seq) { this.certID = CertID.getInstance(seq.getObjectAt(0)); this.certStatus = CertStatus.getInstance(seq.getObjectAt(1)); this.thisUpdate = ASN1GeneralizedTime.getInstance(seq.getObjectAt(2)); if (seq.size() > 4) { this.nextUpdate = ASN1GeneralizedTime.getInstance( (ASN1TaggedObject)seq.getObjectAt(3), true); this.singleExtensions = Extensions.getInstance( (ASN1TaggedObject)seq.getObjectAt(4), true); } else if (seq.size() > 3) { ASN1TaggedObject o = (ASN1TaggedObject)seq.getObjectAt(3); if (o.getTagNo() == 0) { this.nextUpdate = ASN1GeneralizedTime.getInstance(o, true); } else { this.singleExtensions = Extensions.getInstance(o, true); } } } public static SingleResponse getInstance( ASN1TaggedObject obj, boolean explicit) { return getInstance(ASN1Sequence.getInstance(obj, explicit)); } public static SingleResponse getInstance( Object obj) { if (obj instanceof SingleResponse) { return (SingleResponse)obj; } else if (obj != null) { return new SingleResponse(ASN1Sequence.getInstance(obj)); } return null; } public CertID getCertID() { return certID; } public CertStatus getCertStatus() { return certStatus; } public ASN1GeneralizedTime getThisUpdate() { return thisUpdate; } public ASN1GeneralizedTime getNextUpdate() { return nextUpdate; } public Extensions getSingleExtensions() { return singleExtensions; } /** * Produce an object suitable for an ASN1OutputStream. *
         *  SingleResponse ::= SEQUENCE {
         *          certID                       CertID,
         *          certStatus                   CertStatus,
         *          thisUpdate                   GeneralizedTime,
         *          nextUpdate         [0]       EXPLICIT GeneralizedTime OPTIONAL,
         *          singleExtensions   [1]       EXPLICIT Extensions OPTIONAL }
         * 
    */ public ASN1Primitive toASN1Primitive() { ASN1EncodableVector v = new ASN1EncodableVector(); v.add(certID); v.add(certStatus); v.add(thisUpdate); if (nextUpdate != null) { v.add(new DERTaggedObject(true, 0, nextUpdate)); } if (singleExtensions != null) { v.add(new DERTaggedObject(true, 1, singleExtensions)); } return new DERSequence(v); } } bouncycastle-1.49.orig/src/org/bouncycastle/asn1/ocsp/TBSRequest.java0000644000175000017500000001077611724561172025175 0ustar ebourgebourgpackage org.bouncycastle.asn1.ocsp; import org.bouncycastle.asn1.ASN1EncodableVector; import org.bouncycastle.asn1.ASN1Integer; import org.bouncycastle.asn1.ASN1Object; import org.bouncycastle.asn1.ASN1Primitive; import org.bouncycastle.asn1.ASN1Sequence; import org.bouncycastle.asn1.ASN1TaggedObject; import org.bouncycastle.asn1.DERSequence; import org.bouncycastle.asn1.DERTaggedObject; import org.bouncycastle.asn1.x509.Extensions; import org.bouncycastle.asn1.x509.GeneralName; import org.bouncycastle.asn1.x509.X509Extensions; public class TBSRequest extends ASN1Object { private static final ASN1Integer V1 = new ASN1Integer(0); ASN1Integer version; GeneralName requestorName; ASN1Sequence requestList; Extensions requestExtensions; boolean versionSet; /** * @deprecated use method taking Extensions * @param requestorName * @param requestList * @param requestExtensions */ public TBSRequest( GeneralName requestorName, ASN1Sequence requestList, X509Extensions requestExtensions) { this.version = V1; this.requestorName = requestorName; this.requestList = requestList; this.requestExtensions = Extensions.getInstance(requestExtensions); } public TBSRequest( GeneralName requestorName, ASN1Sequence requestList, Extensions requestExtensions) { this.version = V1; this.requestorName = requestorName; this.requestList = requestList; this.requestExtensions = requestExtensions; } private TBSRequest( ASN1Sequence seq) { int index = 0; if (seq.getObjectAt(0) instanceof ASN1TaggedObject) { ASN1TaggedObject o = (ASN1TaggedObject)seq.getObjectAt(0); if (o.getTagNo() == 0) { versionSet = true; version = ASN1Integer.getInstance((ASN1TaggedObject)seq.getObjectAt(0), true); index++; } else { version = V1; } } else { version = V1; } if (seq.getObjectAt(index) instanceof ASN1TaggedObject) { requestorName = GeneralName.getInstance((ASN1TaggedObject)seq.getObjectAt(index++), true); } requestList = (ASN1Sequence)seq.getObjectAt(index++); if (seq.size() == (index + 1)) { requestExtensions = Extensions.getInstance((ASN1TaggedObject)seq.getObjectAt(index), true); } } public static TBSRequest getInstance( ASN1TaggedObject obj, boolean explicit) { return getInstance(ASN1Sequence.getInstance(obj, explicit)); } public static TBSRequest getInstance( Object obj) { if (obj instanceof TBSRequest) { return (TBSRequest)obj; } else if (obj != null) { return new TBSRequest(ASN1Sequence.getInstance(obj)); } return null; } public ASN1Integer getVersion() { return version; } public GeneralName getRequestorName() { return requestorName; } public ASN1Sequence getRequestList() { return requestList; } public Extensions getRequestExtensions() { return requestExtensions; } /** * Produce an object suitable for an ASN1OutputStream. *
         * TBSRequest      ::=     SEQUENCE {
         *     version             [0]     EXPLICIT Version DEFAULT v1,
         *     requestorName       [1]     EXPLICIT GeneralName OPTIONAL,
         *     requestList                 SEQUENCE OF Request,
         *     requestExtensions   [2]     EXPLICIT Extensions OPTIONAL }
         * 
    */ public ASN1Primitive toASN1Primitive() { ASN1EncodableVector v = new ASN1EncodableVector(); // // if default don't include - unless explicitly provided. Not strictly correct // but required for some requests // if (!version.equals(V1) || versionSet) { v.add(new DERTaggedObject(true, 0, version)); } if (requestorName != null) { v.add(new DERTaggedObject(true, 1, requestorName)); } v.add(requestList); if (requestExtensions != null) { v.add(new DERTaggedObject(true, 2, requestExtensions)); } return new DERSequence(v); } } bouncycastle-1.49.orig/src/org/bouncycastle/asn1/ocsp/Signature.java0000644000175000017500000000545411710123224025115 0ustar ebourgebourgpackage org.bouncycastle.asn1.ocsp; import org.bouncycastle.asn1.ASN1EncodableVector; import org.bouncycastle.asn1.ASN1Object; import org.bouncycastle.asn1.ASN1Primitive; import org.bouncycastle.asn1.ASN1Sequence; import org.bouncycastle.asn1.ASN1TaggedObject; import org.bouncycastle.asn1.DERBitString; import org.bouncycastle.asn1.DERSequence; import org.bouncycastle.asn1.DERTaggedObject; import org.bouncycastle.asn1.x509.AlgorithmIdentifier; public class Signature extends ASN1Object { AlgorithmIdentifier signatureAlgorithm; DERBitString signature; ASN1Sequence certs; public Signature( AlgorithmIdentifier signatureAlgorithm, DERBitString signature) { this.signatureAlgorithm = signatureAlgorithm; this.signature = signature; } public Signature( AlgorithmIdentifier signatureAlgorithm, DERBitString signature, ASN1Sequence certs) { this.signatureAlgorithm = signatureAlgorithm; this.signature = signature; this.certs = certs; } private Signature( ASN1Sequence seq) { signatureAlgorithm = AlgorithmIdentifier.getInstance(seq.getObjectAt(0)); signature = (DERBitString)seq.getObjectAt(1); if (seq.size() == 3) { certs = ASN1Sequence.getInstance( (ASN1TaggedObject)seq.getObjectAt(2), true); } } public static Signature getInstance( ASN1TaggedObject obj, boolean explicit) { return getInstance(ASN1Sequence.getInstance(obj, explicit)); } public static Signature getInstance( Object obj) { if (obj instanceof Signature) { return (Signature)obj; } else if (obj != null) { return new Signature(ASN1Sequence.getInstance(obj)); } return null; } public AlgorithmIdentifier getSignatureAlgorithm() { return signatureAlgorithm; } public DERBitString getSignature() { return signature; } public ASN1Sequence getCerts() { return certs; } /** * Produce an object suitable for an ASN1OutputStream. *
         * Signature       ::=     SEQUENCE {
         *     signatureAlgorithm      AlgorithmIdentifier,
         *     signature               BIT STRING,
         *     certs               [0] EXPLICIT SEQUENCE OF Certificate OPTIONAL}
         * 
    */ public ASN1Primitive toASN1Primitive() { ASN1EncodableVector v = new ASN1EncodableVector(); v.add(signatureAlgorithm); v.add(signature); if (certs != null) { v.add(new DERTaggedObject(true, 0, certs)); } return new DERSequence(v); } } bouncycastle-1.49.orig/src/org/bouncycastle/asn1/ocsp/OCSPResponse.java0000644000175000017500000000435611710124020025432 0ustar ebourgebourgpackage org.bouncycastle.asn1.ocsp; import org.bouncycastle.asn1.ASN1EncodableVector; import org.bouncycastle.asn1.ASN1Object; import org.bouncycastle.asn1.ASN1Primitive; import org.bouncycastle.asn1.ASN1Sequence; import org.bouncycastle.asn1.ASN1TaggedObject; import org.bouncycastle.asn1.DERSequence; import org.bouncycastle.asn1.DERTaggedObject; public class OCSPResponse extends ASN1Object { OCSPResponseStatus responseStatus; ResponseBytes responseBytes; public OCSPResponse( OCSPResponseStatus responseStatus, ResponseBytes responseBytes) { this.responseStatus = responseStatus; this.responseBytes = responseBytes; } private OCSPResponse( ASN1Sequence seq) { responseStatus = OCSPResponseStatus.getInstance(seq.getObjectAt(0)); if (seq.size() == 2) { responseBytes = ResponseBytes.getInstance( (ASN1TaggedObject)seq.getObjectAt(1), true); } } public static OCSPResponse getInstance( ASN1TaggedObject obj, boolean explicit) { return getInstance(ASN1Sequence.getInstance(obj, explicit)); } public static OCSPResponse getInstance( Object obj) { if (obj instanceof OCSPResponse) { return (OCSPResponse)obj; } else if (obj != null) { return new OCSPResponse(ASN1Sequence.getInstance(obj)); } return null; } public OCSPResponseStatus getResponseStatus() { return responseStatus; } public ResponseBytes getResponseBytes() { return responseBytes; } /** * Produce an object suitable for an ASN1OutputStream. *
         * OCSPResponse ::= SEQUENCE {
         *     responseStatus         OCSPResponseStatus,
         *     responseBytes          [0] EXPLICIT ResponseBytes OPTIONAL }
         * 
    */ public ASN1Primitive toASN1Primitive() { ASN1EncodableVector v = new ASN1EncodableVector(); v.add(responseStatus); if (responseBytes != null) { v.add(new DERTaggedObject(true, 0, responseBytes)); } return new DERSequence(v); } } bouncycastle-1.49.orig/src/org/bouncycastle/asn1/ocsp/OCSPObjectIdentifiers.java0000644000175000017500000000215111624622714027240 0ustar ebourgebourgpackage org.bouncycastle.asn1.ocsp; import org.bouncycastle.asn1.ASN1ObjectIdentifier; public interface OCSPObjectIdentifiers { public static final String pkix_ocsp = "1.3.6.1.5.5.7.48.1"; public static final ASN1ObjectIdentifier id_pkix_ocsp = new ASN1ObjectIdentifier(pkix_ocsp); public static final ASN1ObjectIdentifier id_pkix_ocsp_basic = new ASN1ObjectIdentifier(pkix_ocsp + ".1"); // // extensions // public static final ASN1ObjectIdentifier id_pkix_ocsp_nonce = new ASN1ObjectIdentifier(pkix_ocsp + ".2"); public static final ASN1ObjectIdentifier id_pkix_ocsp_crl = new ASN1ObjectIdentifier(pkix_ocsp + ".3"); public static final ASN1ObjectIdentifier id_pkix_ocsp_response = new ASN1ObjectIdentifier(pkix_ocsp + ".4"); public static final ASN1ObjectIdentifier id_pkix_ocsp_nocheck = new ASN1ObjectIdentifier(pkix_ocsp + ".5"); public static final ASN1ObjectIdentifier id_pkix_ocsp_archive_cutoff = new ASN1ObjectIdentifier(pkix_ocsp + ".6"); public static final ASN1ObjectIdentifier id_pkix_ocsp_service_locator = new ASN1ObjectIdentifier(pkix_ocsp + ".7"); } bouncycastle-1.49.orig/src/org/bouncycastle/asn1/ocsp/CertStatus.java0000644000175000017500000000464612103437527025272 0ustar ebourgebourgpackage org.bouncycastle.asn1.ocsp; import org.bouncycastle.asn1.ASN1Choice; import org.bouncycastle.asn1.ASN1Encodable; import org.bouncycastle.asn1.ASN1Object; import org.bouncycastle.asn1.ASN1Primitive; import org.bouncycastle.asn1.ASN1TaggedObject; import org.bouncycastle.asn1.DERNull; import org.bouncycastle.asn1.DERTaggedObject; public class CertStatus extends ASN1Object implements ASN1Choice { private int tagNo; private ASN1Encodable value; /** * create a CertStatus object with a tag of zero. */ public CertStatus() { tagNo = 0; value = DERNull.INSTANCE; } public CertStatus( RevokedInfo info) { tagNo = 1; value = info; } public CertStatus( int tagNo, ASN1Encodable value) { this.tagNo = tagNo; this.value = value; } public CertStatus( ASN1TaggedObject choice) { this.tagNo = choice.getTagNo(); switch (choice.getTagNo()) { case 0: value = DERNull.INSTANCE; break; case 1: value = RevokedInfo.getInstance(choice, false); break; case 2: value = DERNull.INSTANCE; } } public static CertStatus getInstance( Object obj) { if (obj == null || obj instanceof CertStatus) { return (CertStatus)obj; } else if (obj instanceof ASN1TaggedObject) { return new CertStatus((ASN1TaggedObject)obj); } throw new IllegalArgumentException("unknown object in factory: " + obj.getClass().getName()); } public static CertStatus getInstance( ASN1TaggedObject obj, boolean explicit) { return getInstance(obj.getObject()); // must be explicitly tagged } public int getTagNo() { return tagNo; } public ASN1Encodable getStatus() { return value; } /** * Produce an object suitable for an ASN1OutputStream. *
         *  CertStatus ::= CHOICE {
         *                  good        [0]     IMPLICIT NULL,
         *                  revoked     [1]     IMPLICIT RevokedInfo,
         *                  unknown     [2]     IMPLICIT UnknownInfo }
         * 
    */ public ASN1Primitive toASN1Primitive() { return new DERTaggedObject(false, tagNo, value); } } bouncycastle-1.49.orig/src/org/bouncycastle/asn1/ocsp/CrlID.java0000644000175000017500000000537611724561172024131 0ustar ebourgebourgpackage org.bouncycastle.asn1.ocsp; import java.util.Enumeration; import org.bouncycastle.asn1.ASN1EncodableVector; import org.bouncycastle.asn1.ASN1GeneralizedTime; import org.bouncycastle.asn1.ASN1Integer; import org.bouncycastle.asn1.ASN1Object; import org.bouncycastle.asn1.ASN1Primitive; import org.bouncycastle.asn1.ASN1Sequence; import org.bouncycastle.asn1.ASN1TaggedObject; import org.bouncycastle.asn1.DERGeneralizedTime; import org.bouncycastle.asn1.DERIA5String; import org.bouncycastle.asn1.DERSequence; import org.bouncycastle.asn1.DERTaggedObject; public class CrlID extends ASN1Object { private DERIA5String crlUrl; private ASN1Integer crlNum; private ASN1GeneralizedTime crlTime; private CrlID( ASN1Sequence seq) { Enumeration e = seq.getObjects(); while (e.hasMoreElements()) { ASN1TaggedObject o = (ASN1TaggedObject)e.nextElement(); switch (o.getTagNo()) { case 0: crlUrl = DERIA5String.getInstance(o, true); break; case 1: crlNum = ASN1Integer.getInstance(o, true); break; case 2: crlTime = DERGeneralizedTime.getInstance(o, true); break; default: throw new IllegalArgumentException( "unknown tag number: " + o.getTagNo()); } } } public static CrlID getInstance( Object obj) { if (obj instanceof CrlID) { return (CrlID)obj; } else if (obj != null) { return new CrlID(ASN1Sequence.getInstance(obj)); } return null; } public DERIA5String getCrlUrl() { return crlUrl; } public ASN1Integer getCrlNum() { return crlNum; } public ASN1GeneralizedTime getCrlTime() { return crlTime; } /** * Produce an object suitable for an ASN1OutputStream. *
         * CrlID ::= SEQUENCE {
         *     crlUrl               [0]     EXPLICIT IA5String OPTIONAL,
         *     crlNum               [1]     EXPLICIT INTEGER OPTIONAL,
         *     crlTime              [2]     EXPLICIT GeneralizedTime OPTIONAL }
         * 
    */ public ASN1Primitive toASN1Primitive() { ASN1EncodableVector v = new ASN1EncodableVector(); if (crlUrl != null) { v.add(new DERTaggedObject(true, 0, crlUrl)); } if (crlNum != null) { v.add(new DERTaggedObject(true, 1, crlNum)); } if (crlTime != null) { v.add(new DERTaggedObject(true, 2, crlTime)); } return new DERSequence(v); } } bouncycastle-1.49.orig/src/org/bouncycastle/asn1/ocsp/CertID.java0000644000175000017500000000546311724561172024303 0ustar ebourgebourgpackage org.bouncycastle.asn1.ocsp; import org.bouncycastle.asn1.ASN1EncodableVector; import org.bouncycastle.asn1.ASN1Integer; import org.bouncycastle.asn1.ASN1Object; import org.bouncycastle.asn1.ASN1OctetString; import org.bouncycastle.asn1.ASN1Primitive; import org.bouncycastle.asn1.ASN1Sequence; import org.bouncycastle.asn1.ASN1TaggedObject; import org.bouncycastle.asn1.DERSequence; import org.bouncycastle.asn1.x509.AlgorithmIdentifier; public class CertID extends ASN1Object { AlgorithmIdentifier hashAlgorithm; ASN1OctetString issuerNameHash; ASN1OctetString issuerKeyHash; ASN1Integer serialNumber; public CertID( AlgorithmIdentifier hashAlgorithm, ASN1OctetString issuerNameHash, ASN1OctetString issuerKeyHash, ASN1Integer serialNumber) { this.hashAlgorithm = hashAlgorithm; this.issuerNameHash = issuerNameHash; this.issuerKeyHash = issuerKeyHash; this.serialNumber = serialNumber; } private CertID( ASN1Sequence seq) { hashAlgorithm = AlgorithmIdentifier.getInstance(seq.getObjectAt(0)); issuerNameHash = (ASN1OctetString)seq.getObjectAt(1); issuerKeyHash = (ASN1OctetString)seq.getObjectAt(2); serialNumber = (ASN1Integer)seq.getObjectAt(3); } public static CertID getInstance( ASN1TaggedObject obj, boolean explicit) { return getInstance(ASN1Sequence.getInstance(obj, explicit)); } public static CertID getInstance( Object obj) { if (obj instanceof CertID) { return (CertID)obj; } else if (obj != null) { return new CertID(ASN1Sequence.getInstance(obj)); } return null; } public AlgorithmIdentifier getHashAlgorithm() { return hashAlgorithm; } public ASN1OctetString getIssuerNameHash() { return issuerNameHash; } public ASN1OctetString getIssuerKeyHash() { return issuerKeyHash; } public ASN1Integer getSerialNumber() { return serialNumber; } /** * Produce an object suitable for an ASN1OutputStream. *
         * CertID          ::=     SEQUENCE {
         *     hashAlgorithm       AlgorithmIdentifier,
         *     issuerNameHash      OCTET STRING, -- Hash of Issuer's DN
         *     issuerKeyHash       OCTET STRING, -- Hash of Issuers public key
         *     serialNumber        CertificateSerialNumber }
         * 
    */ public ASN1Primitive toASN1Primitive() { ASN1EncodableVector v = new ASN1EncodableVector(); v.add(hashAlgorithm); v.add(issuerNameHash); v.add(issuerKeyHash); v.add(serialNumber); return new DERSequence(v); } } bouncycastle-1.49.orig/src/org/bouncycastle/asn1/ocsp/ResponseData.java0000644000175000017500000001202311737210072025541 0ustar ebourgebourgpackage org.bouncycastle.asn1.ocsp; import org.bouncycastle.asn1.ASN1EncodableVector; import org.bouncycastle.asn1.ASN1GeneralizedTime; import org.bouncycastle.asn1.ASN1Integer; import org.bouncycastle.asn1.ASN1Object; import org.bouncycastle.asn1.ASN1Primitive; import org.bouncycastle.asn1.ASN1Sequence; import org.bouncycastle.asn1.ASN1TaggedObject; import org.bouncycastle.asn1.DERGeneralizedTime; import org.bouncycastle.asn1.DERSequence; import org.bouncycastle.asn1.DERTaggedObject; import org.bouncycastle.asn1.x509.Extensions; import org.bouncycastle.asn1.x509.X509Extensions; public class ResponseData extends ASN1Object { private static final ASN1Integer V1 = new ASN1Integer(0); private boolean versionPresent; private ASN1Integer version; private ResponderID responderID; private ASN1GeneralizedTime producedAt; private ASN1Sequence responses; private Extensions responseExtensions; public ResponseData( ASN1Integer version, ResponderID responderID, ASN1GeneralizedTime producedAt, ASN1Sequence responses, Extensions responseExtensions) { this.version = version; this.responderID = responderID; this.producedAt = producedAt; this.responses = responses; this.responseExtensions = responseExtensions; } /** * @deprecated use method taking Extensions * @param responderID * @param producedAt * @param responses * @param responseExtensions */ public ResponseData( ResponderID responderID, DERGeneralizedTime producedAt, ASN1Sequence responses, X509Extensions responseExtensions) { this(V1, responderID, ASN1GeneralizedTime.getInstance(producedAt), responses, Extensions.getInstance(responseExtensions)); } public ResponseData( ResponderID responderID, ASN1GeneralizedTime producedAt, ASN1Sequence responses, Extensions responseExtensions) { this(V1, responderID, producedAt, responses, responseExtensions); } private ResponseData( ASN1Sequence seq) { int index = 0; if (seq.getObjectAt(0) instanceof ASN1TaggedObject) { ASN1TaggedObject o = (ASN1TaggedObject)seq.getObjectAt(0); if (o.getTagNo() == 0) { this.versionPresent = true; this.version = ASN1Integer.getInstance( (ASN1TaggedObject)seq.getObjectAt(0), true); index++; } else { this.version = V1; } } else { this.version = V1; } this.responderID = ResponderID.getInstance(seq.getObjectAt(index++)); this.producedAt = ASN1GeneralizedTime.getInstance(seq.getObjectAt(index++)); this.responses = (ASN1Sequence)seq.getObjectAt(index++); if (seq.size() > index) { this.responseExtensions = Extensions.getInstance( (ASN1TaggedObject)seq.getObjectAt(index), true); } } public static ResponseData getInstance( ASN1TaggedObject obj, boolean explicit) { return getInstance(ASN1Sequence.getInstance(obj, explicit)); } public static ResponseData getInstance( Object obj) { if (obj instanceof ResponseData) { return (ResponseData)obj; } else if (obj != null) { return new ResponseData(ASN1Sequence.getInstance(obj)); } return null; } public ASN1Integer getVersion() { return version; } public ResponderID getResponderID() { return responderID; } public ASN1GeneralizedTime getProducedAt() { return producedAt; } public ASN1Sequence getResponses() { return responses; } public Extensions getResponseExtensions() { return responseExtensions; } /** * Produce an object suitable for an ASN1OutputStream. *
         * ResponseData ::= SEQUENCE {
         *     version              [0] EXPLICIT Version DEFAULT v1,
         *     responderID              ResponderID,
         *     producedAt               GeneralizedTime,
         *     responses                SEQUENCE OF SingleResponse,
         *     responseExtensions   [1] EXPLICIT Extensions OPTIONAL }
         * 
    */ public ASN1Primitive toASN1Primitive() { ASN1EncodableVector v = new ASN1EncodableVector(); if (versionPresent || !version.equals(V1)) { v.add(new DERTaggedObject(true, 0, version)); } v.add(responderID); v.add(producedAt); v.add(responses); if (responseExtensions != null) { v.add(new DERTaggedObject(true, 1, responseExtensions)); } return new DERSequence(v); } } bouncycastle-1.49.orig/src/org/bouncycastle/asn1/ocsp/OCSPResponseStatus.java0000644000175000017500000000351011710124020026625 0ustar ebourgebourgpackage org.bouncycastle.asn1.ocsp; import java.math.BigInteger; import org.bouncycastle.asn1.ASN1Enumerated; import org.bouncycastle.asn1.ASN1Object; import org.bouncycastle.asn1.ASN1Primitive; public class OCSPResponseStatus extends ASN1Object { public static final int SUCCESSFUL = 0; public static final int MALFORMED_REQUEST = 1; public static final int INTERNAL_ERROR = 2; public static final int TRY_LATER = 3; public static final int SIG_REQUIRED = 5; public static final int UNAUTHORIZED = 6; private ASN1Enumerated value; /** * The OCSPResponseStatus enumeration. *
         * OCSPResponseStatus ::= ENUMERATED {
         *     successful            (0),  --Response has valid confirmations
         *     malformedRequest      (1),  --Illegal confirmation request
         *     internalError         (2),  --Internal error in issuer
         *     tryLater              (3),  --Try again later
         *                                 --(4) is not used
         *     sigRequired           (5),  --Must sign the request
         *     unauthorized          (6)   --Request unauthorized
         * }
         * 
    */ public OCSPResponseStatus( int value) { this(new ASN1Enumerated(value)); } private OCSPResponseStatus( ASN1Enumerated value) { this.value = value; } public static OCSPResponseStatus getInstance( Object obj) { if (obj instanceof OCSPResponseStatus) { return (OCSPResponseStatus)obj; } else if (obj != null) { return new OCSPResponseStatus(ASN1Enumerated.getInstance(obj)); } return null; } public BigInteger getValue() { return value.getValue(); } public ASN1Primitive toASN1Primitive() { return value; } } bouncycastle-1.49.orig/src/org/bouncycastle/asn1/ocsp/Request.java0000644000175000017500000000434211724561172024614 0ustar ebourgebourgpackage org.bouncycastle.asn1.ocsp; import org.bouncycastle.asn1.ASN1EncodableVector; import org.bouncycastle.asn1.ASN1Object; import org.bouncycastle.asn1.ASN1Primitive; import org.bouncycastle.asn1.ASN1Sequence; import org.bouncycastle.asn1.ASN1TaggedObject; import org.bouncycastle.asn1.DERSequence; import org.bouncycastle.asn1.DERTaggedObject; import org.bouncycastle.asn1.x509.Extensions; public class Request extends ASN1Object { CertID reqCert; Extensions singleRequestExtensions; public Request( CertID reqCert, Extensions singleRequestExtensions) { this.reqCert = reqCert; this.singleRequestExtensions = singleRequestExtensions; } private Request( ASN1Sequence seq) { reqCert = CertID.getInstance(seq.getObjectAt(0)); if (seq.size() == 2) { singleRequestExtensions = Extensions.getInstance( (ASN1TaggedObject)seq.getObjectAt(1), true); } } public static Request getInstance( ASN1TaggedObject obj, boolean explicit) { return getInstance(ASN1Sequence.getInstance(obj, explicit)); } public static Request getInstance( Object obj) { if (obj instanceof Request) { return (Request)obj; } else if (obj != null) { return new Request(ASN1Sequence.getInstance(obj)); } return null; } public CertID getReqCert() { return reqCert; } public Extensions getSingleRequestExtensions() { return singleRequestExtensions; } /** * Produce an object suitable for an ASN1OutputStream. *
         * Request         ::=     SEQUENCE {
         *     reqCert                     CertID,
         *     singleRequestExtensions     [0] EXPLICIT Extensions OPTIONAL }
         * 
    */ public ASN1Primitive toASN1Primitive() { ASN1EncodableVector v = new ASN1EncodableVector(); v.add(reqCert); if (singleRequestExtensions != null) { v.add(new DERTaggedObject(true, 0, singleRequestExtensions)); } return new DERSequence(v); } } bouncycastle-1.49.orig/src/org/bouncycastle/asn1/ocsp/package.html0000644000175000017500000000016110262753174024576 0ustar ebourgebourg Support classes useful for encoding and supporting OCSP objects. bouncycastle-1.49.orig/src/org/bouncycastle/asn1/cms/0000755000175000017500000000000012152033551022123 5ustar ebourgebourgbouncycastle-1.49.orig/src/org/bouncycastle/asn1/cms/ContentInfo.java0000644000175000017500000000520112117777732025233 0ustar ebourgebourgpackage org.bouncycastle.asn1.cms; import org.bouncycastle.asn1.ASN1Encodable; import org.bouncycastle.asn1.ASN1EncodableVector; import org.bouncycastle.asn1.ASN1Object; import org.bouncycastle.asn1.ASN1ObjectIdentifier; import org.bouncycastle.asn1.ASN1Primitive; import org.bouncycastle.asn1.ASN1Sequence; import org.bouncycastle.asn1.ASN1TaggedObject; import org.bouncycastle.asn1.BERSequence; import org.bouncycastle.asn1.BERTaggedObject; public class ContentInfo extends ASN1Object implements CMSObjectIdentifiers { private ASN1ObjectIdentifier contentType; private ASN1Encodable content; public static ContentInfo getInstance( Object obj) { if (obj instanceof ContentInfo) { return (ContentInfo)obj; } else if (obj != null) { return new ContentInfo(ASN1Sequence.getInstance(obj)); } return null; } public static ContentInfo getInstance( ASN1TaggedObject obj, boolean explicit) { return getInstance(ASN1Sequence.getInstance(obj, explicit)); } /** * @deprecated use getInstance() */ public ContentInfo( ASN1Sequence seq) { if (seq.size() < 1 || seq.size() > 2) { throw new IllegalArgumentException("Bad sequence size: " + seq.size()); } contentType = (ASN1ObjectIdentifier)seq.getObjectAt(0); if (seq.size() > 1) { ASN1TaggedObject tagged = (ASN1TaggedObject)seq.getObjectAt(1); if (!tagged.isExplicit() || tagged.getTagNo() != 0) { throw new IllegalArgumentException("Bad tag for 'content'"); } content = tagged.getObject(); } } public ContentInfo( ASN1ObjectIdentifier contentType, ASN1Encodable content) { this.contentType = contentType; this.content = content; } public ASN1ObjectIdentifier getContentType() { return contentType; } public ASN1Encodable getContent() { return content; } /** * Produce an object suitable for an ASN1OutputStream. *
         * ContentInfo ::= SEQUENCE {
         *          contentType ContentType,
         *          content
         *          [0] EXPLICIT ANY DEFINED BY contentType OPTIONAL }
         * 
    */ public ASN1Primitive toASN1Primitive() { ASN1EncodableVector v = new ASN1EncodableVector(); v.add(contentType); if (content != null) { v.add(new BERTaggedObject(0, content)); } return new BERSequence(v); } } bouncycastle-1.49.orig/src/org/bouncycastle/asn1/cms/SCVPReqRes.java0000644000175000017500000000425112147274153024676 0ustar ebourgebourgpackage org.bouncycastle.asn1.cms; import org.bouncycastle.asn1.ASN1EncodableVector; import org.bouncycastle.asn1.ASN1Object; import org.bouncycastle.asn1.ASN1Primitive; import org.bouncycastle.asn1.ASN1Sequence; import org.bouncycastle.asn1.ASN1TaggedObject; import org.bouncycastle.asn1.DERSequence; import org.bouncycastle.asn1.DERTaggedObject; public class SCVPReqRes extends ASN1Object { private final ContentInfo request; private final ContentInfo response; public static SCVPReqRes getInstance( Object obj) { if (obj instanceof SCVPReqRes) { return (SCVPReqRes)obj; } else if (obj != null) { return new SCVPReqRes(ASN1Sequence.getInstance(obj)); } return null; } private SCVPReqRes( ASN1Sequence seq) { if (seq.getObjectAt(0) instanceof ASN1TaggedObject) { this.request = ContentInfo.getInstance(ASN1TaggedObject.getInstance(seq.getObjectAt(0)), true); this.response = ContentInfo.getInstance(seq.getObjectAt(1)); } else { this.request = null; this.response = ContentInfo.getInstance(seq.getObjectAt(0)); } } public SCVPReqRes(ContentInfo response) { this.request = null; // use of this confuses earlier JDKs this.response = response; } public SCVPReqRes(ContentInfo request, ContentInfo response) { this.request = request; this.response = response; } public ContentInfo getRequest() { return request; } public ContentInfo getResponse() { return response; } /** *
         *    SCVPReqRes ::= SEQUENCE {
         *    request  [0] EXPLICIT ContentInfo OPTIONAL,
         *    response     ContentInfo }
         * 
    * @return the ASN.1 primitive representation. */ public ASN1Primitive toASN1Primitive() { ASN1EncodableVector v = new ASN1EncodableVector(); if (request != null) { v.add(new DERTaggedObject(true, 0, request)); } v.add(response); return new DERSequence(v); } } bouncycastle-1.49.orig/src/org/bouncycastle/asn1/cms/KeyAgreeRecipientIdentifier.java0000644000175000017500000000601311624652552030343 0ustar ebourgebourgpackage org.bouncycastle.asn1.cms; import org.bouncycastle.asn1.ASN1Choice; import org.bouncycastle.asn1.ASN1Object; import org.bouncycastle.asn1.ASN1Primitive; import org.bouncycastle.asn1.ASN1Sequence; import org.bouncycastle.asn1.ASN1TaggedObject; import org.bouncycastle.asn1.DERTaggedObject; public class KeyAgreeRecipientIdentifier extends ASN1Object implements ASN1Choice { private IssuerAndSerialNumber issuerSerial; private RecipientKeyIdentifier rKeyID; /** * return an KeyAgreeRecipientIdentifier object from a tagged object. * * @param obj the tagged object holding the object we want. * @param explicit true if the object is meant to be explicitly * tagged false otherwise. * @exception IllegalArgumentException if the object held by the * tagged object cannot be converted. */ public static KeyAgreeRecipientIdentifier getInstance( ASN1TaggedObject obj, boolean explicit) { return getInstance(ASN1Sequence.getInstance(obj, explicit)); } /** * return an KeyAgreeRecipientIdentifier object from the given object. * * @param obj the object we want converted. * @exception IllegalArgumentException if the object cannot be converted. */ public static KeyAgreeRecipientIdentifier getInstance( Object obj) { if (obj == null || obj instanceof KeyAgreeRecipientIdentifier) { return (KeyAgreeRecipientIdentifier)obj; } if (obj instanceof ASN1Sequence) { return new KeyAgreeRecipientIdentifier(IssuerAndSerialNumber.getInstance(obj)); } if (obj instanceof ASN1TaggedObject && ((ASN1TaggedObject)obj).getTagNo() == 0) { return new KeyAgreeRecipientIdentifier(RecipientKeyIdentifier.getInstance( (ASN1TaggedObject)obj, false)); } throw new IllegalArgumentException("Invalid KeyAgreeRecipientIdentifier: " + obj.getClass().getName()); } public KeyAgreeRecipientIdentifier( IssuerAndSerialNumber issuerSerial) { this.issuerSerial = issuerSerial; this.rKeyID = null; } public KeyAgreeRecipientIdentifier( RecipientKeyIdentifier rKeyID) { this.issuerSerial = null; this.rKeyID = rKeyID; } public IssuerAndSerialNumber getIssuerAndSerialNumber() { return issuerSerial; } public RecipientKeyIdentifier getRKeyID() { return rKeyID; } /** * Produce an object suitable for an ASN1OutputStream. *
         * KeyAgreeRecipientIdentifier ::= CHOICE {
         *     issuerAndSerialNumber IssuerAndSerialNumber,
         *     rKeyId [0] IMPLICIT RecipientKeyIdentifier
         * }
         * 
    */ public ASN1Primitive toASN1Primitive() { if (issuerSerial != null) { return issuerSerial.toASN1Primitive(); } return new DERTaggedObject(false, 0, rKeyID); } } bouncycastle-1.49.orig/src/org/bouncycastle/asn1/cms/KeyAgreeRecipientInfo.java0000644000175000017500000001122111724561172027147 0ustar ebourgebourgpackage org.bouncycastle.asn1.cms; import org.bouncycastle.asn1.ASN1EncodableVector; import org.bouncycastle.asn1.ASN1Integer; import org.bouncycastle.asn1.ASN1Object; import org.bouncycastle.asn1.ASN1OctetString; import org.bouncycastle.asn1.ASN1Primitive; import org.bouncycastle.asn1.ASN1Sequence; import org.bouncycastle.asn1.ASN1TaggedObject; import org.bouncycastle.asn1.DERSequence; import org.bouncycastle.asn1.DERTaggedObject; import org.bouncycastle.asn1.x509.AlgorithmIdentifier; public class KeyAgreeRecipientInfo extends ASN1Object { private ASN1Integer version; private OriginatorIdentifierOrKey originator; private ASN1OctetString ukm; private AlgorithmIdentifier keyEncryptionAlgorithm; private ASN1Sequence recipientEncryptedKeys; public KeyAgreeRecipientInfo( OriginatorIdentifierOrKey originator, ASN1OctetString ukm, AlgorithmIdentifier keyEncryptionAlgorithm, ASN1Sequence recipientEncryptedKeys) { this.version = new ASN1Integer(3); this.originator = originator; this.ukm = ukm; this.keyEncryptionAlgorithm = keyEncryptionAlgorithm; this.recipientEncryptedKeys = recipientEncryptedKeys; } public KeyAgreeRecipientInfo( ASN1Sequence seq) { int index = 0; version = (ASN1Integer)seq.getObjectAt(index++); originator = OriginatorIdentifierOrKey.getInstance( (ASN1TaggedObject)seq.getObjectAt(index++), true); if (seq.getObjectAt(index) instanceof ASN1TaggedObject) { ukm = ASN1OctetString.getInstance( (ASN1TaggedObject)seq.getObjectAt(index++), true); } keyEncryptionAlgorithm = AlgorithmIdentifier.getInstance( seq.getObjectAt(index++)); recipientEncryptedKeys = (ASN1Sequence)seq.getObjectAt(index++); } /** * return a KeyAgreeRecipientInfo object from a tagged object. * * @param obj the tagged object holding the object we want. * @param explicit true if the object is meant to be explicitly * tagged false otherwise. * @exception IllegalArgumentException if the object held by the * tagged object cannot be converted. */ public static KeyAgreeRecipientInfo getInstance( ASN1TaggedObject obj, boolean explicit) { return getInstance(ASN1Sequence.getInstance(obj, explicit)); } /** * return a KeyAgreeRecipientInfo object from the given object. * * @param obj the object we want converted. * @exception IllegalArgumentException if the object cannot be converted. */ public static KeyAgreeRecipientInfo getInstance( Object obj) { if (obj == null || obj instanceof KeyAgreeRecipientInfo) { return (KeyAgreeRecipientInfo)obj; } if (obj instanceof ASN1Sequence) { return new KeyAgreeRecipientInfo((ASN1Sequence)obj); } throw new IllegalArgumentException( "Illegal object in KeyAgreeRecipientInfo: " + obj.getClass().getName()); } public ASN1Integer getVersion() { return version; } public OriginatorIdentifierOrKey getOriginator() { return originator; } public ASN1OctetString getUserKeyingMaterial() { return ukm; } public AlgorithmIdentifier getKeyEncryptionAlgorithm() { return keyEncryptionAlgorithm; } public ASN1Sequence getRecipientEncryptedKeys() { return recipientEncryptedKeys; } /** * Produce an object suitable for an ASN1OutputStream. *
         * KeyAgreeRecipientInfo ::= SEQUENCE {
         *     version CMSVersion,  -- always set to 3
         *     originator [0] EXPLICIT OriginatorIdentifierOrKey,
         *     ukm [1] EXPLICIT UserKeyingMaterial OPTIONAL,
         *     keyEncryptionAlgorithm KeyEncryptionAlgorithmIdentifier,
         *     recipientEncryptedKeys RecipientEncryptedKeys 
         * }
         *
         * UserKeyingMaterial ::= OCTET STRING
         * 
    */ public ASN1Primitive toASN1Primitive() { ASN1EncodableVector v = new ASN1EncodableVector(); v.add(version); v.add(new DERTaggedObject(true, 0, originator)); if (ukm != null) { v.add(new DERTaggedObject(true, 1, ukm)); } v.add(keyEncryptionAlgorithm); v.add(recipientEncryptedKeys); return new DERSequence(v); } } bouncycastle-1.49.orig/src/org/bouncycastle/asn1/cms/ecc/0000755000175000017500000000000012152033551022655 5ustar ebourgebourgbouncycastle-1.49.orig/src/org/bouncycastle/asn1/cms/ecc/MQVuserKeyingMaterial.java0000644000175000017500000000632611624652552027732 0ustar ebourgebourgpackage org.bouncycastle.asn1.cms.ecc; import org.bouncycastle.asn1.ASN1EncodableVector; import org.bouncycastle.asn1.ASN1Object; import org.bouncycastle.asn1.ASN1OctetString; import org.bouncycastle.asn1.ASN1Primitive; import org.bouncycastle.asn1.ASN1Sequence; import org.bouncycastle.asn1.ASN1TaggedObject; import org.bouncycastle.asn1.DERSequence; import org.bouncycastle.asn1.DERTaggedObject; import org.bouncycastle.asn1.cms.OriginatorPublicKey; public class MQVuserKeyingMaterial extends ASN1Object { private OriginatorPublicKey ephemeralPublicKey; private ASN1OctetString addedukm; public MQVuserKeyingMaterial( OriginatorPublicKey ephemeralPublicKey, ASN1OctetString addedukm) { // TODO Check ephemeralPublicKey not null this.ephemeralPublicKey = ephemeralPublicKey; this.addedukm = addedukm; } private MQVuserKeyingMaterial( ASN1Sequence seq) { // TODO Check seq has either 1 or 2 elements this.ephemeralPublicKey = OriginatorPublicKey.getInstance( seq.getObjectAt(0)); if (seq.size() > 1) { this.addedukm = ASN1OctetString.getInstance( (ASN1TaggedObject)seq.getObjectAt(1), true); } } /** * return an MQVuserKeyingMaterial object from a tagged object. * * @param obj the tagged object holding the object we want. * @param explicit true if the object is meant to be explicitly * tagged false otherwise. * @throws IllegalArgumentException if the object held by the * tagged object cannot be converted. */ public static MQVuserKeyingMaterial getInstance( ASN1TaggedObject obj, boolean explicit) { return getInstance(ASN1Sequence.getInstance(obj, explicit)); } /** * return an MQVuserKeyingMaterial object from the given object. * * @param obj the object we want converted. * @throws IllegalArgumentException if the object cannot be converted. */ public static MQVuserKeyingMaterial getInstance( Object obj) { if (obj == null || obj instanceof MQVuserKeyingMaterial) { return (MQVuserKeyingMaterial)obj; } if (obj instanceof ASN1Sequence) { return new MQVuserKeyingMaterial((ASN1Sequence)obj); } throw new IllegalArgumentException("Invalid MQVuserKeyingMaterial: " + obj.getClass().getName()); } public OriginatorPublicKey getEphemeralPublicKey() { return ephemeralPublicKey; } public ASN1OctetString getAddedukm() { return addedukm; } /** * Produce an object suitable for an ASN1OutputStream. *
         * MQVuserKeyingMaterial ::= SEQUENCE {
         *   ephemeralPublicKey OriginatorPublicKey,
         *   addedukm [0] EXPLICIT UserKeyingMaterial OPTIONAL  }
         * 
    */ public ASN1Primitive toASN1Primitive() { ASN1EncodableVector v = new ASN1EncodableVector(); v.add(ephemeralPublicKey); if (addedukm != null) { v.add(new DERTaggedObject(true, 0, addedukm)); } return new DERSequence(v); } } bouncycastle-1.49.orig/src/org/bouncycastle/asn1/cms/OtherRecipientInfo.java0000644000175000017500000000525512117742013026536 0ustar ebourgebourgpackage org.bouncycastle.asn1.cms; import org.bouncycastle.asn1.ASN1Encodable; import org.bouncycastle.asn1.ASN1EncodableVector; import org.bouncycastle.asn1.ASN1Object; import org.bouncycastle.asn1.ASN1ObjectIdentifier; import org.bouncycastle.asn1.ASN1Primitive; import org.bouncycastle.asn1.ASN1Sequence; import org.bouncycastle.asn1.ASN1TaggedObject; import org.bouncycastle.asn1.DERSequence; public class OtherRecipientInfo extends ASN1Object { private ASN1ObjectIdentifier oriType; private ASN1Encodable oriValue; public OtherRecipientInfo( ASN1ObjectIdentifier oriType, ASN1Encodable oriValue) { this.oriType = oriType; this.oriValue = oriValue; } /** * @deprecated use getInstance(). * @param seq */ public OtherRecipientInfo( ASN1Sequence seq) { oriType = ASN1ObjectIdentifier.getInstance(seq.getObjectAt(0)); oriValue = seq.getObjectAt(1); } /** * return a OtherRecipientInfo object from a tagged object. * * @param obj the tagged object holding the object we want. * @param explicit true if the object is meant to be explicitly * tagged false otherwise. * @exception IllegalArgumentException if the object held by the * tagged object cannot be converted. */ public static OtherRecipientInfo getInstance( ASN1TaggedObject obj, boolean explicit) { return getInstance(ASN1Sequence.getInstance(obj, explicit)); } /** * return a OtherRecipientInfo object from the given object. * * @param obj the object we want converted. * @exception IllegalArgumentException if the object cannot be converted. */ public static OtherRecipientInfo getInstance( Object obj) { if (obj instanceof OtherRecipientInfo) { return (OtherRecipientInfo)obj; } if (obj != null) { return new OtherRecipientInfo(ASN1Sequence.getInstance(obj)); } return null; } public ASN1ObjectIdentifier getType() { return oriType; } public ASN1Encodable getValue() { return oriValue; } /** * Produce an object suitable for an ASN1OutputStream. *
         * OtherRecipientInfo ::= SEQUENCE {
         *    oriType OBJECT IDENTIFIER,
         *    oriValue ANY DEFINED BY oriType }
         * 
    */ public ASN1Primitive toASN1Primitive() { ASN1EncodableVector v = new ASN1EncodableVector(); v.add(oriType); v.add(oriValue); return new DERSequence(v); } } bouncycastle-1.49.orig/src/org/bouncycastle/asn1/cms/OriginatorPublicKey.java0000644000175000017500000000542511624652552026734 0ustar ebourgebourgpackage org.bouncycastle.asn1.cms; import org.bouncycastle.asn1.ASN1EncodableVector; import org.bouncycastle.asn1.ASN1Object; import org.bouncycastle.asn1.ASN1Primitive; import org.bouncycastle.asn1.ASN1Sequence; import org.bouncycastle.asn1.ASN1TaggedObject; import org.bouncycastle.asn1.DERBitString; import org.bouncycastle.asn1.DERSequence; import org.bouncycastle.asn1.x509.AlgorithmIdentifier; public class OriginatorPublicKey extends ASN1Object { private AlgorithmIdentifier algorithm; private DERBitString publicKey; public OriginatorPublicKey( AlgorithmIdentifier algorithm, byte[] publicKey) { this.algorithm = algorithm; this.publicKey = new DERBitString(publicKey); } public OriginatorPublicKey( ASN1Sequence seq) { algorithm = AlgorithmIdentifier.getInstance(seq.getObjectAt(0)); publicKey = (DERBitString)seq.getObjectAt(1); } /** * return an OriginatorPublicKey object from a tagged object. * * @param obj the tagged object holding the object we want. * @param explicit true if the object is meant to be explicitly * tagged false otherwise. * @exception IllegalArgumentException if the object held by the * tagged object cannot be converted. */ public static OriginatorPublicKey getInstance( ASN1TaggedObject obj, boolean explicit) { return getInstance(ASN1Sequence.getInstance(obj, explicit)); } /** * return an OriginatorPublicKey object from the given object. * * @param obj the object we want converted. * @exception IllegalArgumentException if the object cannot be converted. */ public static OriginatorPublicKey getInstance( Object obj) { if (obj == null || obj instanceof OriginatorPublicKey) { return (OriginatorPublicKey)obj; } if (obj instanceof ASN1Sequence) { return new OriginatorPublicKey((ASN1Sequence)obj); } throw new IllegalArgumentException("Invalid OriginatorPublicKey: " + obj.getClass().getName()); } public AlgorithmIdentifier getAlgorithm() { return algorithm; } public DERBitString getPublicKey() { return publicKey; } /** * Produce an object suitable for an ASN1OutputStream. *
         * OriginatorPublicKey ::= SEQUENCE {
         *     algorithm AlgorithmIdentifier,
         *     publicKey BIT STRING 
         * }
         * 
    */ public ASN1Primitive toASN1Primitive() { ASN1EncodableVector v = new ASN1EncodableVector(); v.add(algorithm); v.add(publicKey); return new DERSequence(v); } } bouncycastle-1.49.orig/src/org/bouncycastle/asn1/cms/RecipientKeyIdentifier.java0000644000175000017500000001061011624652555027400 0ustar ebourgebourgpackage org.bouncycastle.asn1.cms; import org.bouncycastle.asn1.ASN1EncodableVector; import org.bouncycastle.asn1.ASN1Object; import org.bouncycastle.asn1.ASN1OctetString; import org.bouncycastle.asn1.ASN1Primitive; import org.bouncycastle.asn1.ASN1Sequence; import org.bouncycastle.asn1.ASN1TaggedObject; import org.bouncycastle.asn1.DERGeneralizedTime; import org.bouncycastle.asn1.DEROctetString; import org.bouncycastle.asn1.DERSequence; public class RecipientKeyIdentifier extends ASN1Object { private ASN1OctetString subjectKeyIdentifier; private DERGeneralizedTime date; private OtherKeyAttribute other; public RecipientKeyIdentifier( ASN1OctetString subjectKeyIdentifier, DERGeneralizedTime date, OtherKeyAttribute other) { this.subjectKeyIdentifier = subjectKeyIdentifier; this.date = date; this.other = other; } public RecipientKeyIdentifier( byte[] subjectKeyIdentifier, DERGeneralizedTime date, OtherKeyAttribute other) { this.subjectKeyIdentifier = new DEROctetString(subjectKeyIdentifier); this.date = date; this.other = other; } public RecipientKeyIdentifier( byte[] subjectKeyIdentifier) { this(subjectKeyIdentifier, null, null); } public RecipientKeyIdentifier( ASN1Sequence seq) { subjectKeyIdentifier = ASN1OctetString.getInstance( seq.getObjectAt(0)); switch(seq.size()) { case 1: break; case 2: if (seq.getObjectAt(1) instanceof DERGeneralizedTime) { date = (DERGeneralizedTime)seq.getObjectAt(1); } else { other = OtherKeyAttribute.getInstance(seq.getObjectAt(2)); } break; case 3: date = (DERGeneralizedTime)seq.getObjectAt(1); other = OtherKeyAttribute.getInstance(seq.getObjectAt(2)); break; default: throw new IllegalArgumentException("Invalid RecipientKeyIdentifier"); } } /** * return a RecipientKeyIdentifier object from a tagged object. * * @param _ato the tagged object holding the object we want. * @param _explicit true if the object is meant to be explicitly * tagged false otherwise. * @exception IllegalArgumentException if the object held by the * tagged object cannot be converted. */ public static RecipientKeyIdentifier getInstance(ASN1TaggedObject _ato, boolean _explicit) { return getInstance(ASN1Sequence.getInstance(_ato, _explicit)); } /** * return a RecipientKeyIdentifier object from the given object. * * @param _obj the object we want converted. * @exception IllegalArgumentException if the object cannot be converted. */ public static RecipientKeyIdentifier getInstance(Object _obj) { if(_obj == null || _obj instanceof RecipientKeyIdentifier) { return (RecipientKeyIdentifier)_obj; } if(_obj instanceof ASN1Sequence) { return new RecipientKeyIdentifier((ASN1Sequence)_obj); } throw new IllegalArgumentException("Invalid RecipientKeyIdentifier: " + _obj.getClass().getName()); } public ASN1OctetString getSubjectKeyIdentifier() { return subjectKeyIdentifier; } public DERGeneralizedTime getDate() { return date; } public OtherKeyAttribute getOtherKeyAttribute() { return other; } /** * Produce an object suitable for an ASN1OutputStream. *
         * RecipientKeyIdentifier ::= SEQUENCE {
         *     subjectKeyIdentifier SubjectKeyIdentifier,
         *     date GeneralizedTime OPTIONAL,
         *     other OtherKeyAttribute OPTIONAL 
         * }
         *
         * SubjectKeyIdentifier ::= OCTET STRING
         * 
    */ public ASN1Primitive toASN1Primitive() { ASN1EncodableVector v = new ASN1EncodableVector(); v.add(subjectKeyIdentifier); if (date != null) { v.add(date); } if (other != null) { v.add(other); } return new DERSequence(v); } } bouncycastle-1.49.orig/src/org/bouncycastle/asn1/cms/KEKIdentifier.java0000644000175000017500000000725211737275254025431 0ustar ebourgebourgpackage org.bouncycastle.asn1.cms; import org.bouncycastle.asn1.ASN1EncodableVector; import org.bouncycastle.asn1.ASN1GeneralizedTime; import org.bouncycastle.asn1.ASN1Object; import org.bouncycastle.asn1.ASN1OctetString; import org.bouncycastle.asn1.ASN1Primitive; import org.bouncycastle.asn1.ASN1Sequence; import org.bouncycastle.asn1.ASN1TaggedObject; import org.bouncycastle.asn1.DEROctetString; import org.bouncycastle.asn1.DERSequence; public class KEKIdentifier extends ASN1Object { private ASN1OctetString keyIdentifier; private ASN1GeneralizedTime date; private OtherKeyAttribute other; public KEKIdentifier( byte[] keyIdentifier, ASN1GeneralizedTime date, OtherKeyAttribute other) { this.keyIdentifier = new DEROctetString(keyIdentifier); this.date = date; this.other = other; } private KEKIdentifier( ASN1Sequence seq) { keyIdentifier = (ASN1OctetString)seq.getObjectAt(0); switch (seq.size()) { case 1: break; case 2: if (seq.getObjectAt(1) instanceof ASN1GeneralizedTime) { date = (ASN1GeneralizedTime)seq.getObjectAt(1); } else { other = OtherKeyAttribute.getInstance(seq.getObjectAt(1)); } break; case 3: date = (ASN1GeneralizedTime)seq.getObjectAt(1); other = OtherKeyAttribute.getInstance(seq.getObjectAt(2)); break; default: throw new IllegalArgumentException("Invalid KEKIdentifier"); } } /** * return a KEKIdentifier object from a tagged object. * * @param obj the tagged object holding the object we want. * @param explicit true if the object is meant to be explicitly * tagged false otherwise. * @exception IllegalArgumentException if the object held by the * tagged object cannot be converted. */ public static KEKIdentifier getInstance( ASN1TaggedObject obj, boolean explicit) { return getInstance(ASN1Sequence.getInstance(obj, explicit)); } /** * return a KEKIdentifier object from the given object. * * @param obj the object we want converted. * @exception IllegalArgumentException if the object cannot be converted. */ public static KEKIdentifier getInstance( Object obj) { if (obj == null || obj instanceof KEKIdentifier) { return (KEKIdentifier)obj; } if (obj instanceof ASN1Sequence) { return new KEKIdentifier((ASN1Sequence)obj); } throw new IllegalArgumentException("Invalid KEKIdentifier: " + obj.getClass().getName()); } public ASN1OctetString getKeyIdentifier() { return keyIdentifier; } public ASN1GeneralizedTime getDate() { return date; } public OtherKeyAttribute getOther() { return other; } /** * Produce an object suitable for an ASN1OutputStream. *
         * KEKIdentifier ::= SEQUENCE {
         *     keyIdentifier OCTET STRING,
         *     date GeneralizedTime OPTIONAL,
         *     other OtherKeyAttribute OPTIONAL 
         * }
         * 
    */ public ASN1Primitive toASN1Primitive() { ASN1EncodableVector v = new ASN1EncodableVector(); v.add(keyIdentifier); if (date != null) { v.add(date); } if (other != null) { v.add(other); } return new DERSequence(v); } } bouncycastle-1.49.orig/src/org/bouncycastle/asn1/cms/EncryptedContentInfoParser.java0000644000175000017500000000274511624642103030261 0ustar ebourgebourgpackage org.bouncycastle.asn1.cms; import java.io.IOException; import org.bouncycastle.asn1.ASN1Encodable; import org.bouncycastle.asn1.ASN1ObjectIdentifier; import org.bouncycastle.asn1.ASN1SequenceParser; import org.bouncycastle.asn1.ASN1TaggedObjectParser; import org.bouncycastle.asn1.x509.AlgorithmIdentifier; /** *
     * EncryptedContentInfo ::= SEQUENCE {
     *     contentType ContentType,
     *     contentEncryptionAlgorithm ContentEncryptionAlgorithmIdentifier,
     *     encryptedContent [0] IMPLICIT EncryptedContent OPTIONAL 
     * }
     * 
    */ public class EncryptedContentInfoParser { private ASN1ObjectIdentifier _contentType; private AlgorithmIdentifier _contentEncryptionAlgorithm; private ASN1TaggedObjectParser _encryptedContent; public EncryptedContentInfoParser( ASN1SequenceParser seq) throws IOException { _contentType = (ASN1ObjectIdentifier)seq.readObject(); _contentEncryptionAlgorithm = AlgorithmIdentifier.getInstance(seq.readObject().toASN1Primitive()); _encryptedContent = (ASN1TaggedObjectParser)seq.readObject(); } public ASN1ObjectIdentifier getContentType() { return _contentType; } public AlgorithmIdentifier getContentEncryptionAlgorithm() { return _contentEncryptionAlgorithm; } public ASN1Encodable getEncryptedContent( int tag) throws IOException { return _encryptedContent.getObjectParser(tag, false); } } bouncycastle-1.49.orig/src/org/bouncycastle/asn1/cms/AuthEnvelopedDataParser.java0000644000175000017500000000777511724561172027531 0ustar ebourgebourgpackage org.bouncycastle.asn1.cms; import java.io.IOException; import org.bouncycastle.asn1.ASN1Encodable; import org.bouncycastle.asn1.ASN1Integer; import org.bouncycastle.asn1.ASN1OctetString; import org.bouncycastle.asn1.ASN1SequenceParser; import org.bouncycastle.asn1.ASN1SetParser; import org.bouncycastle.asn1.ASN1TaggedObjectParser; import org.bouncycastle.asn1.BERTags; /** * Produce an object suitable for an ASN1OutputStream. * *
     * AuthEnvelopedData ::= SEQUENCE {
     *   version CMSVersion,
     *   originatorInfo [0] IMPLICIT OriginatorInfo OPTIONAL,
     *   recipientInfos RecipientInfos,
     *   authEncryptedContentInfo EncryptedContentInfo,
     *   authAttrs [1] IMPLICIT AuthAttributes OPTIONAL,
     *   mac MessageAuthenticationCode,
     *   unauthAttrs [2] IMPLICIT UnauthAttributes OPTIONAL }
     * 
    */ public class AuthEnvelopedDataParser { private ASN1SequenceParser seq; private ASN1Integer version; private ASN1Encodable nextObject; private boolean originatorInfoCalled; public AuthEnvelopedDataParser(ASN1SequenceParser seq) throws IOException { this.seq = seq; // TODO // "It MUST be set to 0." this.version = ASN1Integer.getInstance(seq.readObject()); } public ASN1Integer getVersion() { return version; } public OriginatorInfo getOriginatorInfo() throws IOException { originatorInfoCalled = true; if (nextObject == null) { nextObject = seq.readObject(); } if (nextObject instanceof ASN1TaggedObjectParser && ((ASN1TaggedObjectParser)nextObject).getTagNo() == 0) { ASN1SequenceParser originatorInfo = (ASN1SequenceParser) ((ASN1TaggedObjectParser)nextObject).getObjectParser(BERTags.SEQUENCE, false); nextObject = null; return OriginatorInfo.getInstance(originatorInfo.toASN1Primitive()); } return null; } public ASN1SetParser getRecipientInfos() throws IOException { if (!originatorInfoCalled) { getOriginatorInfo(); } if (nextObject == null) { nextObject = seq.readObject(); } ASN1SetParser recipientInfos = (ASN1SetParser)nextObject; nextObject = null; return recipientInfos; } public EncryptedContentInfoParser getAuthEncryptedContentInfo() throws IOException { if (nextObject == null) { nextObject = seq.readObject(); } if (nextObject != null) { ASN1SequenceParser o = (ASN1SequenceParser) nextObject; nextObject = null; return new EncryptedContentInfoParser(o); } return null; } public ASN1SetParser getAuthAttrs() throws IOException { if (nextObject == null) { nextObject = seq.readObject(); } if (nextObject instanceof ASN1TaggedObjectParser) { ASN1Encodable o = nextObject; nextObject = null; return (ASN1SetParser)((ASN1TaggedObjectParser)o).getObjectParser(BERTags.SET, false); } // TODO // "The authAttrs MUST be present if the content type carried in // EncryptedContentInfo is not id-data." return null; } public ASN1OctetString getMac() throws IOException { if (nextObject == null) { nextObject = seq.readObject(); } ASN1Encodable o = nextObject; nextObject = null; return ASN1OctetString.getInstance(o.toASN1Primitive()); } public ASN1SetParser getUnauthAttrs() throws IOException { if (nextObject == null) { nextObject = seq.readObject(); } if (nextObject != null) { ASN1Encodable o = nextObject; nextObject = null; return (ASN1SetParser)((ASN1TaggedObjectParser)o).getObjectParser(BERTags.SET, false); } return null; } } bouncycastle-1.49.orig/src/org/bouncycastle/asn1/cms/EncryptedData.java0000644000175000017500000000472411725270274025536 0ustar ebourgebourgpackage org.bouncycastle.asn1.cms; import org.bouncycastle.asn1.ASN1EncodableVector; import org.bouncycastle.asn1.ASN1Integer; import org.bouncycastle.asn1.ASN1Object; import org.bouncycastle.asn1.ASN1Primitive; import org.bouncycastle.asn1.ASN1Sequence; import org.bouncycastle.asn1.ASN1Set; import org.bouncycastle.asn1.BERSequence; import org.bouncycastle.asn1.BERTaggedObject; public class EncryptedData extends ASN1Object { private ASN1Integer version; private EncryptedContentInfo encryptedContentInfo; private ASN1Set unprotectedAttrs; public static EncryptedData getInstance(Object o) { if (o instanceof EncryptedData) { return (EncryptedData)o; } if (o != null) { return new EncryptedData(ASN1Sequence.getInstance(o)); } return null; } public EncryptedData(EncryptedContentInfo encInfo) { this(encInfo, null); } public EncryptedData(EncryptedContentInfo encInfo, ASN1Set unprotectedAttrs) { this.version = new ASN1Integer((unprotectedAttrs == null) ? 0 : 2); this.encryptedContentInfo = encInfo; this.unprotectedAttrs = unprotectedAttrs; } private EncryptedData(ASN1Sequence seq) { this.version = ASN1Integer.getInstance(seq.getObjectAt(0)); this.encryptedContentInfo = EncryptedContentInfo.getInstance(seq.getObjectAt(1)); if (seq.size() == 3) { this.unprotectedAttrs = ASN1Set.getInstance(seq.getObjectAt(2)); } } public ASN1Integer getVersion() { return version; } public EncryptedContentInfo getEncryptedContentInfo() { return encryptedContentInfo; } public ASN1Set getUnprotectedAttrs() { return unprotectedAttrs; } /** *
         *       EncryptedData ::= SEQUENCE {
         *                     version CMSVersion,
         *                     encryptedContentInfo EncryptedContentInfo,
         *                     unprotectedAttrs [1] IMPLICIT UnprotectedAttributes OPTIONAL }
         * 
    * @return a basic ASN.1 object representation. */ public ASN1Primitive toASN1Primitive() { ASN1EncodableVector v = new ASN1EncodableVector(); v.add(version); v.add(encryptedContentInfo); if (unprotectedAttrs != null) { v.add(new BERTaggedObject(false, 1, unprotectedAttrs)); } return new BERSequence(v); } } bouncycastle-1.49.orig/src/org/bouncycastle/asn1/cms/KeyTransRecipientInfo.java0000644000175000017500000000625711724561172027230 0ustar ebourgebourgpackage org.bouncycastle.asn1.cms; import org.bouncycastle.asn1.ASN1EncodableVector; import org.bouncycastle.asn1.ASN1Integer; import org.bouncycastle.asn1.ASN1Object; import org.bouncycastle.asn1.ASN1OctetString; import org.bouncycastle.asn1.ASN1Primitive; import org.bouncycastle.asn1.ASN1Sequence; import org.bouncycastle.asn1.ASN1TaggedObject; import org.bouncycastle.asn1.DERSequence; import org.bouncycastle.asn1.x509.AlgorithmIdentifier; public class KeyTransRecipientInfo extends ASN1Object { private ASN1Integer version; private RecipientIdentifier rid; private AlgorithmIdentifier keyEncryptionAlgorithm; private ASN1OctetString encryptedKey; public KeyTransRecipientInfo( RecipientIdentifier rid, AlgorithmIdentifier keyEncryptionAlgorithm, ASN1OctetString encryptedKey) { if (rid.toASN1Primitive() instanceof ASN1TaggedObject) { this.version = new ASN1Integer(2); } else { this.version = new ASN1Integer(0); } this.rid = rid; this.keyEncryptionAlgorithm = keyEncryptionAlgorithm; this.encryptedKey = encryptedKey; } public KeyTransRecipientInfo( ASN1Sequence seq) { this.version = (ASN1Integer)seq.getObjectAt(0); this.rid = RecipientIdentifier.getInstance(seq.getObjectAt(1)); this.keyEncryptionAlgorithm = AlgorithmIdentifier.getInstance(seq.getObjectAt(2)); this.encryptedKey = (ASN1OctetString)seq.getObjectAt(3); } /** * return a KeyTransRecipientInfo object from the given object. * * @param obj the object we want converted. * @exception IllegalArgumentException if the object cannot be converted. */ public static KeyTransRecipientInfo getInstance( Object obj) { if (obj == null || obj instanceof KeyTransRecipientInfo) { return (KeyTransRecipientInfo)obj; } if(obj instanceof ASN1Sequence) { return new KeyTransRecipientInfo((ASN1Sequence)obj); } throw new IllegalArgumentException( "Illegal object in KeyTransRecipientInfo: " + obj.getClass().getName()); } public ASN1Integer getVersion() { return version; } public RecipientIdentifier getRecipientIdentifier() { return rid; } public AlgorithmIdentifier getKeyEncryptionAlgorithm() { return keyEncryptionAlgorithm; } public ASN1OctetString getEncryptedKey() { return encryptedKey; } /** * Produce an object suitable for an ASN1OutputStream. *
         * KeyTransRecipientInfo ::= SEQUENCE {
         *     version CMSVersion,  -- always set to 0 or 2
         *     rid RecipientIdentifier,
         *     keyEncryptionAlgorithm KeyEncryptionAlgorithmIdentifier,
         *     encryptedKey EncryptedKey 
         * }
         * 
    */ public ASN1Primitive toASN1Primitive() { ASN1EncodableVector v = new ASN1EncodableVector(); v.add(version); v.add(rid); v.add(keyEncryptionAlgorithm); v.add(encryptedKey); return new DERSequence(v); } } bouncycastle-1.49.orig/src/org/bouncycastle/asn1/cms/EncryptedContentInfo.java0000644000175000017500000000625711711652543027114 0ustar ebourgebourgpackage org.bouncycastle.asn1.cms; import org.bouncycastle.asn1.ASN1EncodableVector; import org.bouncycastle.asn1.ASN1Object; import org.bouncycastle.asn1.ASN1ObjectIdentifier; import org.bouncycastle.asn1.ASN1OctetString; import org.bouncycastle.asn1.ASN1Primitive; import org.bouncycastle.asn1.ASN1Sequence; import org.bouncycastle.asn1.ASN1TaggedObject; import org.bouncycastle.asn1.BERSequence; import org.bouncycastle.asn1.BERTaggedObject; import org.bouncycastle.asn1.x509.AlgorithmIdentifier; public class EncryptedContentInfo extends ASN1Object { private ASN1ObjectIdentifier contentType; private AlgorithmIdentifier contentEncryptionAlgorithm; private ASN1OctetString encryptedContent; public EncryptedContentInfo( ASN1ObjectIdentifier contentType, AlgorithmIdentifier contentEncryptionAlgorithm, ASN1OctetString encryptedContent) { this.contentType = contentType; this.contentEncryptionAlgorithm = contentEncryptionAlgorithm; this.encryptedContent = encryptedContent; } private EncryptedContentInfo( ASN1Sequence seq) { if (seq.size() < 2) { throw new IllegalArgumentException("Truncated Sequence Found"); } contentType = (ASN1ObjectIdentifier)seq.getObjectAt(0); contentEncryptionAlgorithm = AlgorithmIdentifier.getInstance( seq.getObjectAt(1)); if (seq.size() > 2) { encryptedContent = ASN1OctetString.getInstance( (ASN1TaggedObject)seq.getObjectAt(2), false); } } /** * return an EncryptedContentInfo object from the given object. * * @param obj the object we want converted. * @exception IllegalArgumentException if the object cannot be converted. */ public static EncryptedContentInfo getInstance( Object obj) { if (obj instanceof EncryptedContentInfo) { return (EncryptedContentInfo)obj; } if (obj != null) { return new EncryptedContentInfo(ASN1Sequence.getInstance(obj)); } return null; } public ASN1ObjectIdentifier getContentType() { return contentType; } public AlgorithmIdentifier getContentEncryptionAlgorithm() { return contentEncryptionAlgorithm; } public ASN1OctetString getEncryptedContent() { return encryptedContent; } /** * Produce an object suitable for an ASN1OutputStream. *
         * EncryptedContentInfo ::= SEQUENCE {
         *     contentType ContentType,
         *     contentEncryptionAlgorithm ContentEncryptionAlgorithmIdentifier,
         *     encryptedContent [0] IMPLICIT EncryptedContent OPTIONAL 
         * }
         * 
    */ public ASN1Primitive toASN1Primitive() { ASN1EncodableVector v = new ASN1EncodableVector(); v.add(contentType); v.add(contentEncryptionAlgorithm); if (encryptedContent != null) { v.add(new BERTaggedObject(false, 0, encryptedContent)); } return new BERSequence(v); } } bouncycastle-1.49.orig/src/org/bouncycastle/asn1/cms/IssuerAndSerialNumber.java0000644000175000017500000000526512116277761027221 0ustar ebourgebourgpackage org.bouncycastle.asn1.cms; import java.math.BigInteger; import org.bouncycastle.asn1.ASN1EncodableVector; import org.bouncycastle.asn1.ASN1Integer; import org.bouncycastle.asn1.ASN1Object; import org.bouncycastle.asn1.ASN1Primitive; import org.bouncycastle.asn1.ASN1Sequence; import org.bouncycastle.asn1.DERSequence; import org.bouncycastle.asn1.x500.X500Name; import org.bouncycastle.asn1.x509.Certificate; import org.bouncycastle.asn1.x509.X509CertificateStructure; import org.bouncycastle.asn1.x509.X509Name; public class IssuerAndSerialNumber extends ASN1Object { private X500Name name; private ASN1Integer serialNumber; public static IssuerAndSerialNumber getInstance( Object obj) { if (obj instanceof IssuerAndSerialNumber) { return (IssuerAndSerialNumber)obj; } else if (obj != null) { return new IssuerAndSerialNumber(ASN1Sequence.getInstance(obj)); } return null; } /** * @deprecated use getInstance() method. * @param seq */ public IssuerAndSerialNumber( ASN1Sequence seq) { this.name = X500Name.getInstance(seq.getObjectAt(0)); this.serialNumber = (ASN1Integer)seq.getObjectAt(1); } public IssuerAndSerialNumber( Certificate certificate) { this.name = certificate.getIssuer(); this.serialNumber = certificate.getSerialNumber(); } public IssuerAndSerialNumber( X509CertificateStructure certificate) { this.name = certificate.getIssuer(); this.serialNumber = certificate.getSerialNumber(); } public IssuerAndSerialNumber( X500Name name, BigInteger serialNumber) { this.name = name; this.serialNumber = new ASN1Integer(serialNumber); } /** * @deprecated use X500Name constructor */ public IssuerAndSerialNumber( X509Name name, BigInteger serialNumber) { this.name = X500Name.getInstance(name); this.serialNumber = new ASN1Integer(serialNumber); } /** * @deprecated use X500Name constructor */ public IssuerAndSerialNumber( X509Name name, ASN1Integer serialNumber) { this.name = X500Name.getInstance(name); this.serialNumber = serialNumber; } public X500Name getName() { return name; } public ASN1Integer getSerialNumber() { return serialNumber; } public ASN1Primitive toASN1Primitive() { ASN1EncodableVector v = new ASN1EncodableVector(); v.add(name); v.add(serialNumber); return new DERSequence(v); } } bouncycastle-1.49.orig/src/org/bouncycastle/asn1/cms/TimeStampAndCRL.java0000644000175000017500000000353311624626647025702 0ustar ebourgebourgpackage org.bouncycastle.asn1.cms; import org.bouncycastle.asn1.ASN1EncodableVector; import org.bouncycastle.asn1.ASN1Object; import org.bouncycastle.asn1.ASN1Primitive; import org.bouncycastle.asn1.ASN1Sequence; import org.bouncycastle.asn1.DERSequence; import org.bouncycastle.asn1.x509.CertificateList; public class TimeStampAndCRL extends ASN1Object { private ContentInfo timeStamp; private CertificateList crl; public TimeStampAndCRL(ContentInfo timeStamp) { this.timeStamp = timeStamp; } private TimeStampAndCRL(ASN1Sequence seq) { this.timeStamp = ContentInfo.getInstance(seq.getObjectAt(0)); if (seq.size() == 2) { this.crl = CertificateList.getInstance(seq.getObjectAt(1)); } } public static TimeStampAndCRL getInstance(Object obj) { if (obj instanceof TimeStampAndCRL) { return (TimeStampAndCRL)obj; } else if (obj != null) { return new TimeStampAndCRL(ASN1Sequence.getInstance(obj)); } return null; } public ContentInfo getTimeStampToken() { return this.timeStamp; } /** @deprecated use getCRL() */ public CertificateList getCertificateList() { return this.crl; } public CertificateList getCRL() { return this.crl; } /** *
         * TimeStampAndCRL ::= SEQUENCE {
         *     timeStamp   TimeStampToken,          -- according to RFC 3161
         *     crl         CertificateList OPTIONAL -- according to RFC 5280
         *  }
         * 
    * @return */ public ASN1Primitive toASN1Primitive() { ASN1EncodableVector v = new ASN1EncodableVector(); v.add(timeStamp); if (crl != null) { v.add(crl); } return new DERSequence(v); } } bouncycastle-1.49.orig/src/org/bouncycastle/asn1/cms/AuthenticatedData.java0000644000175000017500000002016411724561172026356 0ustar ebourgebourgpackage org.bouncycastle.asn1.cms; import java.util.Enumeration; import org.bouncycastle.asn1.ASN1EncodableVector; import org.bouncycastle.asn1.ASN1Integer; import org.bouncycastle.asn1.ASN1Object; import org.bouncycastle.asn1.ASN1OctetString; import org.bouncycastle.asn1.ASN1Primitive; import org.bouncycastle.asn1.ASN1Sequence; import org.bouncycastle.asn1.ASN1Set; import org.bouncycastle.asn1.ASN1TaggedObject; import org.bouncycastle.asn1.BERSequence; import org.bouncycastle.asn1.DERTaggedObject; import org.bouncycastle.asn1.x509.AlgorithmIdentifier; public class AuthenticatedData extends ASN1Object { private ASN1Integer version; private OriginatorInfo originatorInfo; private ASN1Set recipientInfos; private AlgorithmIdentifier macAlgorithm; private AlgorithmIdentifier digestAlgorithm; private ContentInfo encapsulatedContentInfo; private ASN1Set authAttrs; private ASN1OctetString mac; private ASN1Set unauthAttrs; public AuthenticatedData( OriginatorInfo originatorInfo, ASN1Set recipientInfos, AlgorithmIdentifier macAlgorithm, AlgorithmIdentifier digestAlgorithm, ContentInfo encapsulatedContent, ASN1Set authAttrs, ASN1OctetString mac, ASN1Set unauthAttrs) { if (digestAlgorithm != null || authAttrs != null) { if (digestAlgorithm == null || authAttrs == null) { throw new IllegalArgumentException("digestAlgorithm and authAttrs must be set together"); } } version = new ASN1Integer(calculateVersion(originatorInfo)); this.originatorInfo = originatorInfo; this.macAlgorithm = macAlgorithm; this.digestAlgorithm = digestAlgorithm; this.recipientInfos = recipientInfos; this.encapsulatedContentInfo = encapsulatedContent; this.authAttrs = authAttrs; this.mac = mac; this.unauthAttrs = unauthAttrs; } public AuthenticatedData( ASN1Sequence seq) { int index = 0; version = (ASN1Integer)seq.getObjectAt(index++); Object tmp = seq.getObjectAt(index++); if (tmp instanceof ASN1TaggedObject) { originatorInfo = OriginatorInfo.getInstance((ASN1TaggedObject)tmp, false); tmp = seq.getObjectAt(index++); } recipientInfos = ASN1Set.getInstance(tmp); macAlgorithm = AlgorithmIdentifier.getInstance(seq.getObjectAt(index++)); tmp = seq.getObjectAt(index++); if (tmp instanceof ASN1TaggedObject) { digestAlgorithm = AlgorithmIdentifier.getInstance((ASN1TaggedObject)tmp, false); tmp = seq.getObjectAt(index++); } encapsulatedContentInfo = ContentInfo.getInstance(tmp); tmp = seq.getObjectAt(index++); if (tmp instanceof ASN1TaggedObject) { authAttrs = ASN1Set.getInstance((ASN1TaggedObject)tmp, false); tmp = seq.getObjectAt(index++); } mac = ASN1OctetString.getInstance(tmp); if (seq.size() > index) { unauthAttrs = ASN1Set.getInstance((ASN1TaggedObject)seq.getObjectAt(index), false); } } /** * return an AuthenticatedData object from a tagged object. * * @param obj the tagged object holding the object we want. * @param explicit true if the object is meant to be explicitly * tagged false otherwise. * @throws IllegalArgumentException if the object held by the * tagged object cannot be converted. */ public static AuthenticatedData getInstance( ASN1TaggedObject obj, boolean explicit) { return getInstance(ASN1Sequence.getInstance(obj, explicit)); } /** * return an AuthenticatedData object from the given object. * * @param obj the object we want converted. * @throws IllegalArgumentException if the object cannot be converted. */ public static AuthenticatedData getInstance( Object obj) { if (obj == null || obj instanceof AuthenticatedData) { return (AuthenticatedData)obj; } if (obj instanceof ASN1Sequence) { return new AuthenticatedData((ASN1Sequence)obj); } throw new IllegalArgumentException("Invalid AuthenticatedData: " + obj.getClass().getName()); } public ASN1Integer getVersion() { return version; } public OriginatorInfo getOriginatorInfo() { return originatorInfo; } public ASN1Set getRecipientInfos() { return recipientInfos; } public AlgorithmIdentifier getMacAlgorithm() { return macAlgorithm; } public AlgorithmIdentifier getDigestAlgorithm() { return digestAlgorithm; } public ContentInfo getEncapsulatedContentInfo() { return encapsulatedContentInfo; } public ASN1Set getAuthAttrs() { return authAttrs; } public ASN1OctetString getMac() { return mac; } public ASN1Set getUnauthAttrs() { return unauthAttrs; } /** * Produce an object suitable for an ASN1OutputStream. *
         * AuthenticatedData ::= SEQUENCE {
         *       version CMSVersion,
         *       originatorInfo [0] IMPLICIT OriginatorInfo OPTIONAL,
         *       recipientInfos RecipientInfos,
         *       macAlgorithm MessageAuthenticationCodeAlgorithm,
         *       digestAlgorithm [1] DigestAlgorithmIdentifier OPTIONAL,
         *       encapContentInfo EncapsulatedContentInfo,
         *       authAttrs [2] IMPLICIT AuthAttributes OPTIONAL,
         *       mac MessageAuthenticationCode,
         *       unauthAttrs [3] IMPLICIT UnauthAttributes OPTIONAL }
         *
         * AuthAttributes ::= SET SIZE (1..MAX) OF Attribute
         *
         * UnauthAttributes ::= SET SIZE (1..MAX) OF Attribute
         *
         * MessageAuthenticationCode ::= OCTET STRING
         * 
    */ public ASN1Primitive toASN1Primitive() { ASN1EncodableVector v = new ASN1EncodableVector(); v.add(version); if (originatorInfo != null) { v.add(new DERTaggedObject(false, 0, originatorInfo)); } v.add(recipientInfos); v.add(macAlgorithm); if (digestAlgorithm != null) { v.add(new DERTaggedObject(false, 1, digestAlgorithm)); } v.add(encapsulatedContentInfo); if (authAttrs != null) { v.add(new DERTaggedObject(false, 2, authAttrs)); } v.add(mac); if (unauthAttrs != null) { v.add(new DERTaggedObject(false, 3, unauthAttrs)); } return new BERSequence(v); } public static int calculateVersion(OriginatorInfo origInfo) { if (origInfo == null) { return 0; } else { int ver = 0; for (Enumeration e = origInfo.getCertificates().getObjects(); e.hasMoreElements();) { Object obj = e.nextElement(); if (obj instanceof ASN1TaggedObject) { ASN1TaggedObject tag = (ASN1TaggedObject)obj; if (tag.getTagNo() == 2) { ver = 1; } else if (tag.getTagNo() == 3) { ver = 3; break; } } } if (origInfo.getCRLs() != null) { for (Enumeration e = origInfo.getCRLs().getObjects(); e.hasMoreElements();) { Object obj = e.nextElement(); if (obj instanceof ASN1TaggedObject) { ASN1TaggedObject tag = (ASN1TaggedObject)obj; if (tag.getTagNo() == 1) { ver = 3; break; } } } } return ver; } } } bouncycastle-1.49.orig/src/org/bouncycastle/asn1/cms/OtherRevocationInfoFormat.java0000644000175000017500000000544312117742461030104 0ustar ebourgebourgpackage org.bouncycastle.asn1.cms; import org.bouncycastle.asn1.ASN1Encodable; import org.bouncycastle.asn1.ASN1EncodableVector; import org.bouncycastle.asn1.ASN1Object; import org.bouncycastle.asn1.ASN1ObjectIdentifier; import org.bouncycastle.asn1.ASN1Primitive; import org.bouncycastle.asn1.ASN1Sequence; import org.bouncycastle.asn1.ASN1TaggedObject; import org.bouncycastle.asn1.DERSequence; public class OtherRevocationInfoFormat extends ASN1Object { private ASN1ObjectIdentifier otherRevInfoFormat; private ASN1Encodable otherRevInfo; public OtherRevocationInfoFormat( ASN1ObjectIdentifier otherRevInfoFormat, ASN1Encodable otherRevInfo) { this.otherRevInfoFormat = otherRevInfoFormat; this.otherRevInfo = otherRevInfo; } private OtherRevocationInfoFormat( ASN1Sequence seq) { otherRevInfoFormat = ASN1ObjectIdentifier.getInstance(seq.getObjectAt(0)); otherRevInfo = seq.getObjectAt(1); } /** * return a OtherRevocationInfoFormat object from a tagged object. * * @param obj the tagged object holding the object we want. * @param explicit true if the object is meant to be explicitly * tagged false otherwise. * @exception IllegalArgumentException if the object held by the * tagged object cannot be converted. */ public static OtherRevocationInfoFormat getInstance( ASN1TaggedObject obj, boolean explicit) { return getInstance(ASN1Sequence.getInstance(obj, explicit)); } /** * return a OtherRevocationInfoFormat object from the given object. * * @param obj the object we want converted. * @exception IllegalArgumentException if the object cannot be converted. */ public static OtherRevocationInfoFormat getInstance( Object obj) { if (obj instanceof OtherRevocationInfoFormat) { return (OtherRevocationInfoFormat)obj; } if (obj != null) { return new OtherRevocationInfoFormat(ASN1Sequence.getInstance(obj)); } return null; } public ASN1ObjectIdentifier getInfoFormat() { return otherRevInfoFormat; } public ASN1Encodable getInfo() { return otherRevInfo; } /** * Produce an object suitable for an ASN1OutputStream. *
         * OtherRevocationInfoFormat ::= SEQUENCE {
         *      otherRevInfoFormat OBJECT IDENTIFIER,
         *      otherRevInfo ANY DEFINED BY otherRevInfoFormat }
         * 
    */ public ASN1Primitive toASN1Primitive() { ASN1EncodableVector v = new ASN1EncodableVector(); v.add(otherRevInfoFormat); v.add(otherRevInfo); return new DERSequence(v); } } bouncycastle-1.49.orig/src/org/bouncycastle/asn1/cms/EnvelopedData.java0000644000175000017500000001337612127172056025521 0ustar ebourgebourgpackage org.bouncycastle.asn1.cms; import java.util.Enumeration; import org.bouncycastle.asn1.ASN1EncodableVector; import org.bouncycastle.asn1.ASN1Integer; import org.bouncycastle.asn1.ASN1Object; import org.bouncycastle.asn1.ASN1Primitive; import org.bouncycastle.asn1.ASN1Sequence; import org.bouncycastle.asn1.ASN1Set; import org.bouncycastle.asn1.ASN1TaggedObject; import org.bouncycastle.asn1.BERSequence; import org.bouncycastle.asn1.DERTaggedObject; public class EnvelopedData extends ASN1Object { private ASN1Integer version; private OriginatorInfo originatorInfo; private ASN1Set recipientInfos; private EncryptedContentInfo encryptedContentInfo; private ASN1Set unprotectedAttrs; public EnvelopedData( OriginatorInfo originatorInfo, ASN1Set recipientInfos, EncryptedContentInfo encryptedContentInfo, ASN1Set unprotectedAttrs) { version = new ASN1Integer(calculateVersion(originatorInfo, recipientInfos, unprotectedAttrs)); this.originatorInfo = originatorInfo; this.recipientInfos = recipientInfos; this.encryptedContentInfo = encryptedContentInfo; this.unprotectedAttrs = unprotectedAttrs; } public EnvelopedData( OriginatorInfo originatorInfo, ASN1Set recipientInfos, EncryptedContentInfo encryptedContentInfo, Attributes unprotectedAttrs) { version = new ASN1Integer(calculateVersion(originatorInfo, recipientInfos, ASN1Set.getInstance(unprotectedAttrs))); this.originatorInfo = originatorInfo; this.recipientInfos = recipientInfos; this.encryptedContentInfo = encryptedContentInfo; this.unprotectedAttrs = ASN1Set.getInstance(unprotectedAttrs); } /** * @deprecated use getInstance() */ public EnvelopedData( ASN1Sequence seq) { int index = 0; version = (ASN1Integer)seq.getObjectAt(index++); Object tmp = seq.getObjectAt(index++); if (tmp instanceof ASN1TaggedObject) { originatorInfo = OriginatorInfo.getInstance((ASN1TaggedObject)tmp, false); tmp = seq.getObjectAt(index++); } recipientInfos = ASN1Set.getInstance(tmp); encryptedContentInfo = EncryptedContentInfo.getInstance(seq.getObjectAt(index++)); if(seq.size() > index) { unprotectedAttrs = ASN1Set.getInstance((ASN1TaggedObject)seq.getObjectAt(index), false); } } /** * return an EnvelopedData object from a tagged object. * * @param obj the tagged object holding the object we want. * @param explicit true if the object is meant to be explicitly * tagged false otherwise. * @exception IllegalArgumentException if the object held by the * tagged object cannot be converted. */ public static EnvelopedData getInstance( ASN1TaggedObject obj, boolean explicit) { return getInstance(ASN1Sequence.getInstance(obj, explicit)); } /** * return an EnvelopedData object from the given object. * * @param obj the object we want converted. * @exception IllegalArgumentException if the object cannot be converted. */ public static EnvelopedData getInstance( Object obj) { if (obj instanceof EnvelopedData) { return (EnvelopedData)obj; } if (obj != null) { return new EnvelopedData(ASN1Sequence.getInstance(obj)); } return null; } public ASN1Integer getVersion() { return version; } public OriginatorInfo getOriginatorInfo() { return originatorInfo; } public ASN1Set getRecipientInfos() { return recipientInfos; } public EncryptedContentInfo getEncryptedContentInfo() { return encryptedContentInfo; } public ASN1Set getUnprotectedAttrs() { return unprotectedAttrs; } /** * Produce an object suitable for an ASN1OutputStream. *
         * EnvelopedData ::= SEQUENCE {
         *     version CMSVersion,
         *     originatorInfo [0] IMPLICIT OriginatorInfo OPTIONAL,
         *     recipientInfos RecipientInfos,
         *     encryptedContentInfo EncryptedContentInfo,
         *     unprotectedAttrs [1] IMPLICIT UnprotectedAttributes OPTIONAL 
         * }
         * 
    */ public ASN1Primitive toASN1Primitive() { ASN1EncodableVector v = new ASN1EncodableVector(); v.add(version); if (originatorInfo != null) { v.add(new DERTaggedObject(false, 0, originatorInfo)); } v.add(recipientInfos); v.add(encryptedContentInfo); if (unprotectedAttrs != null) { v.add(new DERTaggedObject(false, 1, unprotectedAttrs)); } return new BERSequence(v); } public static int calculateVersion(OriginatorInfo originatorInfo, ASN1Set recipientInfos, ASN1Set unprotectedAttrs) { int version; if (originatorInfo != null || unprotectedAttrs != null) { version = 2; } else { version = 0; Enumeration e = recipientInfos.getObjects(); while (e.hasMoreElements()) { RecipientInfo ri = RecipientInfo.getInstance(e.nextElement()); if (ri.getVersion().getValue().intValue() != version) { version = 2; break; } } } return version; } } bouncycastle-1.49.orig/src/org/bouncycastle/asn1/cms/TimeStampedDataParser.java0000644000175000017500000000617311724561172027171 0ustar ebourgebourgpackage org.bouncycastle.asn1.cms; import java.io.IOException; import org.bouncycastle.asn1.ASN1Encodable; import org.bouncycastle.asn1.ASN1EncodableVector; import org.bouncycastle.asn1.ASN1Integer; import org.bouncycastle.asn1.ASN1OctetStringParser; import org.bouncycastle.asn1.ASN1Primitive; import org.bouncycastle.asn1.ASN1Sequence; import org.bouncycastle.asn1.ASN1SequenceParser; import org.bouncycastle.asn1.BERSequence; import org.bouncycastle.asn1.DERIA5String; public class TimeStampedDataParser { private ASN1Integer version; private DERIA5String dataUri; private MetaData metaData; private ASN1OctetStringParser content; private Evidence temporalEvidence; private ASN1SequenceParser parser; private TimeStampedDataParser(ASN1SequenceParser parser) throws IOException { this.parser = parser; this.version = ASN1Integer.getInstance(parser.readObject()); ASN1Encodable obj = parser.readObject(); if (obj instanceof DERIA5String) { this.dataUri = DERIA5String.getInstance(obj); obj = parser.readObject(); } if (obj instanceof MetaData || obj instanceof ASN1SequenceParser) { this.metaData = MetaData.getInstance(obj.toASN1Primitive()); obj = parser.readObject(); } if (obj instanceof ASN1OctetStringParser) { this.content = (ASN1OctetStringParser)obj; } } public static TimeStampedDataParser getInstance(Object obj) throws IOException { if (obj instanceof ASN1Sequence) { return new TimeStampedDataParser(((ASN1Sequence)obj).parser()); } if (obj instanceof ASN1SequenceParser) { return new TimeStampedDataParser((ASN1SequenceParser)obj); } return null; } public DERIA5String getDataUri() { return dataUri; } public MetaData getMetaData() { return metaData; } public ASN1OctetStringParser getContent() { return content; } public Evidence getTemporalEvidence() throws IOException { if (temporalEvidence == null) { temporalEvidence = Evidence.getInstance(parser.readObject().toASN1Primitive()); } return temporalEvidence; } /** *
         * TimeStampedData ::= SEQUENCE {
         *   version              INTEGER { v1(1) },
         *   dataUri              IA5String OPTIONAL,
         *   metaData             MetaData OPTIONAL,
         *   content              OCTET STRING OPTIONAL,
         *   temporalEvidence     Evidence
         * }
         * 
    * @return * @deprecated will be removed */ public ASN1Primitive toASN1Primitive() { ASN1EncodableVector v = new ASN1EncodableVector(); v.add(version); if (dataUri != null) { v.add(dataUri); } if (metaData != null) { v.add(metaData); } if (content != null) { v.add(content); } v.add(temporalEvidence); return new BERSequence(v); } } bouncycastle-1.49.orig/src/org/bouncycastle/asn1/cms/RecipientEncryptedKey.java0000644000175000017500000000543711624643631027261 0ustar ebourgebourgpackage org.bouncycastle.asn1.cms; import org.bouncycastle.asn1.ASN1EncodableVector; import org.bouncycastle.asn1.ASN1Object; import org.bouncycastle.asn1.ASN1OctetString; import org.bouncycastle.asn1.ASN1Primitive; import org.bouncycastle.asn1.ASN1Sequence; import org.bouncycastle.asn1.ASN1TaggedObject; import org.bouncycastle.asn1.DERSequence; public class RecipientEncryptedKey extends ASN1Object { private KeyAgreeRecipientIdentifier identifier; private ASN1OctetString encryptedKey; private RecipientEncryptedKey( ASN1Sequence seq) { identifier = KeyAgreeRecipientIdentifier.getInstance(seq.getObjectAt(0)); encryptedKey = (ASN1OctetString)seq.getObjectAt(1); } /** * return an RecipientEncryptedKey object from a tagged object. * * @param obj the tagged object holding the object we want. * @param explicit true if the object is meant to be explicitly * tagged false otherwise. * @exception IllegalArgumentException if the object held by the * tagged object cannot be converted. */ public static RecipientEncryptedKey getInstance( ASN1TaggedObject obj, boolean explicit) { return getInstance(ASN1Sequence.getInstance(obj, explicit)); } /** * return a RecipientEncryptedKey object from the given object. * * @param obj the object we want converted. * @exception IllegalArgumentException if the object cannot be converted. */ public static RecipientEncryptedKey getInstance( Object obj) { if (obj == null || obj instanceof RecipientEncryptedKey) { return (RecipientEncryptedKey)obj; } if (obj instanceof ASN1Sequence) { return new RecipientEncryptedKey((ASN1Sequence)obj); } throw new IllegalArgumentException("Invalid RecipientEncryptedKey: " + obj.getClass().getName()); } public RecipientEncryptedKey( KeyAgreeRecipientIdentifier id, ASN1OctetString encryptedKey) { this.identifier = id; this.encryptedKey = encryptedKey; } public KeyAgreeRecipientIdentifier getIdentifier() { return identifier; } public ASN1OctetString getEncryptedKey() { return encryptedKey; } /** * Produce an object suitable for an ASN1OutputStream. *
         * RecipientEncryptedKey ::= SEQUENCE {
         *     rid KeyAgreeRecipientIdentifier,
         *     encryptedKey EncryptedKey
         * }
         * 
    */ public ASN1Primitive toASN1Primitive() { ASN1EncodableVector v = new ASN1EncodableVector(); v.add(identifier); v.add(encryptedKey); return new DERSequence(v); } } bouncycastle-1.49.orig/src/org/bouncycastle/asn1/cms/SignedData.java0000644000175000017500000002041412117743707025006 0ustar ebourgebourgpackage org.bouncycastle.asn1.cms; import java.util.Enumeration; import org.bouncycastle.asn1.ASN1EncodableVector; import org.bouncycastle.asn1.ASN1Integer; import org.bouncycastle.asn1.ASN1Object; import org.bouncycastle.asn1.ASN1ObjectIdentifier; import org.bouncycastle.asn1.ASN1Primitive; import org.bouncycastle.asn1.ASN1Sequence; import org.bouncycastle.asn1.ASN1Set; import org.bouncycastle.asn1.ASN1TaggedObject; import org.bouncycastle.asn1.BERSequence; import org.bouncycastle.asn1.BERSet; import org.bouncycastle.asn1.BERTaggedObject; import org.bouncycastle.asn1.DERTaggedObject; /** * a signed data object. */ public class SignedData extends ASN1Object { private static final ASN1Integer VERSION_1 = new ASN1Integer(1); private static final ASN1Integer VERSION_3 = new ASN1Integer(3); private static final ASN1Integer VERSION_4 = new ASN1Integer(4); private static final ASN1Integer VERSION_5 = new ASN1Integer(5); private ASN1Integer version; private ASN1Set digestAlgorithms; private ContentInfo contentInfo; private ASN1Set certificates; private ASN1Set crls; private ASN1Set signerInfos; private boolean certsBer; private boolean crlsBer; public static SignedData getInstance( Object o) { if (o instanceof SignedData) { return (SignedData)o; } else if (o != null) { return new SignedData(ASN1Sequence.getInstance(o)); } return null; } public SignedData( ASN1Set digestAlgorithms, ContentInfo contentInfo, ASN1Set certificates, ASN1Set crls, ASN1Set signerInfos) { this.version = calculateVersion(contentInfo.getContentType(), certificates, crls, signerInfos); this.digestAlgorithms = digestAlgorithms; this.contentInfo = contentInfo; this.certificates = certificates; this.crls = crls; this.signerInfos = signerInfos; this.crlsBer = crls instanceof BERSet; this.certsBer = certificates instanceof BERSet; } // RFC3852, section 5.1: // IF ((certificates is present) AND // (any certificates with a type of other are present)) OR // ((crls is present) AND // (any crls with a type of other are present)) // THEN version MUST be 5 // ELSE // IF (certificates is present) AND // (any version 2 attribute certificates are present) // THEN version MUST be 4 // ELSE // IF ((certificates is present) AND // (any version 1 attribute certificates are present)) OR // (any SignerInfo structures are version 3) OR // (encapContentInfo eContentType is other than id-data) // THEN version MUST be 3 // ELSE version MUST be 1 // private ASN1Integer calculateVersion( ASN1ObjectIdentifier contentOid, ASN1Set certs, ASN1Set crls, ASN1Set signerInfs) { boolean otherCert = false; boolean otherCrl = false; boolean attrCertV1Found = false; boolean attrCertV2Found = false; if (certs != null) { for (Enumeration en = certs.getObjects(); en.hasMoreElements();) { Object obj = en.nextElement(); if (obj instanceof ASN1TaggedObject) { ASN1TaggedObject tagged = ASN1TaggedObject.getInstance(obj); if (tagged.getTagNo() == 1) { attrCertV1Found = true; } else if (tagged.getTagNo() == 2) { attrCertV2Found = true; } else if (tagged.getTagNo() == 3) { otherCert = true; } } } } if (otherCert) { return new ASN1Integer(5); } if (crls != null) // no need to check if otherCert is true { for (Enumeration en = crls.getObjects(); en.hasMoreElements();) { Object obj = en.nextElement(); if (obj instanceof ASN1TaggedObject) { otherCrl = true; } } } if (otherCrl) { return VERSION_5; } if (attrCertV2Found) { return VERSION_4; } if (attrCertV1Found) { return VERSION_3; } if (checkForVersion3(signerInfs)) { return VERSION_3; } if (!CMSObjectIdentifiers.data.equals(contentOid)) { return VERSION_3; } return VERSION_1; } private boolean checkForVersion3(ASN1Set signerInfs) { for (Enumeration e = signerInfs.getObjects(); e.hasMoreElements();) { SignerInfo s = SignerInfo.getInstance(e.nextElement()); if (s.getVersion().getValue().intValue() == 3) { return true; } } return false; } private SignedData( ASN1Sequence seq) { Enumeration e = seq.getObjects(); version = ASN1Integer.getInstance(e.nextElement()); digestAlgorithms = ((ASN1Set)e.nextElement()); contentInfo = ContentInfo.getInstance(e.nextElement()); while (e.hasMoreElements()) { ASN1Primitive o = (ASN1Primitive)e.nextElement(); // // an interesting feature of SignedData is that there appear // to be varying implementations... // for the moment we ignore anything which doesn't fit. // if (o instanceof ASN1TaggedObject) { ASN1TaggedObject tagged = (ASN1TaggedObject)o; switch (tagged.getTagNo()) { case 0: certsBer = tagged instanceof BERTaggedObject; certificates = ASN1Set.getInstance(tagged, false); break; case 1: crlsBer = tagged instanceof BERTaggedObject; crls = ASN1Set.getInstance(tagged, false); break; default: throw new IllegalArgumentException("unknown tag value " + tagged.getTagNo()); } } else { signerInfos = (ASN1Set)o; } } } public ASN1Integer getVersion() { return version; } public ASN1Set getDigestAlgorithms() { return digestAlgorithms; } public ContentInfo getEncapContentInfo() { return contentInfo; } public ASN1Set getCertificates() { return certificates; } public ASN1Set getCRLs() { return crls; } public ASN1Set getSignerInfos() { return signerInfos; } /** * Produce an object suitable for an ASN1OutputStream. *
         * SignedData ::= SEQUENCE {
         *     version CMSVersion,
         *     digestAlgorithms DigestAlgorithmIdentifiers,
         *     encapContentInfo EncapsulatedContentInfo,
         *     certificates [0] IMPLICIT CertificateSet OPTIONAL,
         *     crls [1] IMPLICIT CertificateRevocationLists OPTIONAL,
         *     signerInfos SignerInfos
         *   }
         * 
    */ public ASN1Primitive toASN1Primitive() { ASN1EncodableVector v = new ASN1EncodableVector(); v.add(version); v.add(digestAlgorithms); v.add(contentInfo); if (certificates != null) { if (certsBer) { v.add(new BERTaggedObject(false, 0, certificates)); } else { v.add(new DERTaggedObject(false, 0, certificates)); } } if (crls != null) { if (crlsBer) { v.add(new BERTaggedObject(false, 1, crls)); } else { v.add(new DERTaggedObject(false, 1, crls)); } } v.add(signerInfos); return new BERSequence(v); } } bouncycastle-1.49.orig/src/org/bouncycastle/asn1/cms/Attributes.java0000644000175000017500000000240512151253000025105 0ustar ebourgebourgpackage org.bouncycastle.asn1.cms; import org.bouncycastle.asn1.ASN1EncodableVector; import org.bouncycastle.asn1.ASN1Object; import org.bouncycastle.asn1.ASN1Primitive; import org.bouncycastle.asn1.ASN1Set; import org.bouncycastle.asn1.DLSet; public class Attributes extends ASN1Object { private ASN1Set attributes; private Attributes(ASN1Set set) { attributes = set; } public Attributes(ASN1EncodableVector v) { attributes = new DLSet(v); } public static Attributes getInstance(Object obj) { if (obj instanceof Attributes) { return (Attributes)obj; } else if (obj != null) { return new Attributes(ASN1Set.getInstance(obj)); } return null; } public Attribute[] getAttributes() { Attribute[] rv = new Attribute[attributes.size()]; for (int i = 0; i != rv.length; i++) { rv[i] = Attribute.getInstance(attributes.getObjectAt(i)); } return rv; } /** *
         * Attributes ::=
         *   SET SIZE(1..MAX) OF Attribute -- according to RFC 5652
         * 
    * @return */ public ASN1Primitive toASN1Primitive() { return attributes; } } bouncycastle-1.49.orig/src/org/bouncycastle/asn1/cms/CompressedData.java0000644000175000017500000000574312053026563025702 0ustar ebourgebourgpackage org.bouncycastle.asn1.cms; import org.bouncycastle.asn1.ASN1EncodableVector; import org.bouncycastle.asn1.ASN1Integer; import org.bouncycastle.asn1.ASN1Object; import org.bouncycastle.asn1.ASN1Primitive; import org.bouncycastle.asn1.ASN1Sequence; import org.bouncycastle.asn1.ASN1TaggedObject; import org.bouncycastle.asn1.BERSequence; import org.bouncycastle.asn1.x509.AlgorithmIdentifier; /** * RFC 3274 - CMS Compressed Data. *
     * CompressedData ::= SEQUENCE {
     *  version CMSVersion,
     *  compressionAlgorithm CompressionAlgorithmIdentifier,
     *  encapContentInfo EncapsulatedContentInfo
     * }
     * 
    */ public class CompressedData extends ASN1Object { private ASN1Integer version; private AlgorithmIdentifier compressionAlgorithm; private ContentInfo encapContentInfo; public CompressedData( AlgorithmIdentifier compressionAlgorithm, ContentInfo encapContentInfo) { this.version = new ASN1Integer(0); this.compressionAlgorithm = compressionAlgorithm; this.encapContentInfo = encapContentInfo; } private CompressedData( ASN1Sequence seq) { this.version = (ASN1Integer)seq.getObjectAt(0); this.compressionAlgorithm = AlgorithmIdentifier.getInstance(seq.getObjectAt(1)); this.encapContentInfo = ContentInfo.getInstance(seq.getObjectAt(2)); } /** * return a CompressedData object from a tagged object. * * @param _ato the tagged object holding the object we want. * @param _explicit true if the object is meant to be explicitly * tagged false otherwise. * @exception IllegalArgumentException if the object held by the * tagged object cannot be converted. */ public static CompressedData getInstance( ASN1TaggedObject _ato, boolean _explicit) { return getInstance(ASN1Sequence.getInstance(_ato, _explicit)); } /** * return a CompressedData object from the given object. * * @param obj the object we want converted. * @exception IllegalArgumentException if the object cannot be converted. */ public static CompressedData getInstance( Object obj) { if (obj instanceof CompressedData) { return (CompressedData)obj; } if (obj != null) { return new CompressedData(ASN1Sequence.getInstance(obj)); } return null; } public ASN1Integer getVersion() { return version; } public AlgorithmIdentifier getCompressionAlgorithmIdentifier() { return compressionAlgorithm; } public ContentInfo getEncapContentInfo() { return encapContentInfo; } public ASN1Primitive toASN1Primitive() { ASN1EncodableVector v = new ASN1EncodableVector(); v.add(version); v.add(compressionAlgorithm); v.add(encapContentInfo); return new BERSequence(v); } } bouncycastle-1.49.orig/src/org/bouncycastle/asn1/cms/AttributeTable.java0000644000175000017500000001357512062225112025710 0ustar ebourgebourgpackage org.bouncycastle.asn1.cms; import java.util.Enumeration; import java.util.Hashtable; import java.util.Vector; import org.bouncycastle.asn1.ASN1Encodable; import org.bouncycastle.asn1.ASN1EncodableVector; import org.bouncycastle.asn1.ASN1ObjectIdentifier; import org.bouncycastle.asn1.ASN1Set; import org.bouncycastle.asn1.DERObjectIdentifier; import org.bouncycastle.asn1.DERSet; public class AttributeTable { private Hashtable attributes = new Hashtable(); public AttributeTable( Hashtable attrs) { attributes = copyTable(attrs); } public AttributeTable( ASN1EncodableVector v) { for (int i = 0; i != v.size(); i++) { Attribute a = Attribute.getInstance(v.get(i)); addAttribute(a.getAttrType(), a); } } public AttributeTable( ASN1Set s) { for (int i = 0; i != s.size(); i++) { Attribute a = Attribute.getInstance(s.getObjectAt(i)); addAttribute(a.getAttrType(), a); } } public AttributeTable( Attribute attr) { addAttribute(attr.getAttrType(), attr); } public AttributeTable( Attributes attrs) { this(ASN1Set.getInstance(attrs.toASN1Primitive())); } private void addAttribute( ASN1ObjectIdentifier oid, Attribute a) { Object value = attributes.get(oid); if (value == null) { attributes.put(oid, a); } else { Vector v; if (value instanceof Attribute) { v = new Vector(); v.addElement(value); v.addElement(a); } else { v = (Vector)value; v.addElement(a); } attributes.put(oid, v); } } /** * @deprecated use ASN1ObjectIdentifier */ public Attribute get(DERObjectIdentifier oid) { return get(new ASN1ObjectIdentifier(oid.getId())); } /** * Return the first attribute matching the OBJECT IDENTIFIER oid. * * @param oid type of attribute required. * @return first attribute found of type oid. */ public Attribute get( ASN1ObjectIdentifier oid) { Object value = attributes.get(oid); if (value instanceof Vector) { return (Attribute)((Vector)value).elementAt(0); } return (Attribute)value; } /** * @deprecated use ASN1ObjectIdentifier */ public ASN1EncodableVector getAll(DERObjectIdentifier oid) { return getAll(new ASN1ObjectIdentifier(oid.getId())); } /** * Return all the attributes matching the OBJECT IDENTIFIER oid. The vector will be * empty if there are no attributes of the required type present. * * @param oid type of attribute required. * @return a vector of all the attributes found of type oid. */ public ASN1EncodableVector getAll( ASN1ObjectIdentifier oid) { ASN1EncodableVector v = new ASN1EncodableVector(); Object value = attributes.get(oid); if (value instanceof Vector) { Enumeration e = ((Vector)value).elements(); while (e.hasMoreElements()) { v.add((Attribute)e.nextElement()); } } else if (value != null) { v.add((Attribute)value); } return v; } public int size() { int size = 0; for (Enumeration en = attributes.elements(); en.hasMoreElements();) { Object o = en.nextElement(); if (o instanceof Vector) { size += ((Vector)o).size(); } else { size++; } } return size; } public Hashtable toHashtable() { return copyTable(attributes); } public ASN1EncodableVector toASN1EncodableVector() { ASN1EncodableVector v = new ASN1EncodableVector(); Enumeration e = attributes.elements(); while (e.hasMoreElements()) { Object value = e.nextElement(); if (value instanceof Vector) { Enumeration en = ((Vector)value).elements(); while (en.hasMoreElements()) { v.add(Attribute.getInstance(en.nextElement())); } } else { v.add(Attribute.getInstance(value)); } } return v; } public Attributes toASN1Structure() { return new Attributes(this.toASN1EncodableVector()); } private Hashtable copyTable( Hashtable in) { Hashtable out = new Hashtable(); Enumeration e = in.keys(); while (e.hasMoreElements()) { Object key = e.nextElement(); out.put(key, in.get(key)); } return out; } /** * Return a new table with the passed in attribute added. * * @param attrType * @param attrValue * @return */ public AttributeTable add(ASN1ObjectIdentifier attrType, ASN1Encodable attrValue) { AttributeTable newTable = new AttributeTable(attributes); newTable.addAttribute(attrType, new Attribute(attrType, new DERSet(attrValue))); return newTable; } public AttributeTable remove(ASN1ObjectIdentifier attrType) { AttributeTable newTable = new AttributeTable(attributes); newTable.attributes.remove(attrType); return newTable; } } bouncycastle-1.49.orig/src/org/bouncycastle/asn1/cms/DigestedData.java0000644000175000017500000000652612053026563025326 0ustar ebourgebourgpackage org.bouncycastle.asn1.cms; import org.bouncycastle.asn1.ASN1EncodableVector; import org.bouncycastle.asn1.ASN1Integer; import org.bouncycastle.asn1.ASN1Object; import org.bouncycastle.asn1.ASN1OctetString; import org.bouncycastle.asn1.ASN1Primitive; import org.bouncycastle.asn1.ASN1Sequence; import org.bouncycastle.asn1.ASN1TaggedObject; import org.bouncycastle.asn1.BERSequence; import org.bouncycastle.asn1.DEROctetString; import org.bouncycastle.asn1.x509.AlgorithmIdentifier; /** * RFC 3274 - CMS Digest Data. *
     * DigestedData ::= SEQUENCE {
     *               version CMSVersion,
     *               digestAlgorithm DigestAlgorithmIdentifier,
     *               encapContentInfo EncapsulatedContentInfo,
     *               digest Digest }
     * 
    */ public class DigestedData extends ASN1Object { private ASN1Integer version; private AlgorithmIdentifier digestAlgorithm; private ContentInfo encapContentInfo; private ASN1OctetString digest; public DigestedData( AlgorithmIdentifier digestAlgorithm, ContentInfo encapContentInfo, byte[] digest) { this.version = new ASN1Integer(0); this.digestAlgorithm = digestAlgorithm; this.encapContentInfo = encapContentInfo; this.digest = new DEROctetString(digest); } private DigestedData( ASN1Sequence seq) { this.version = (ASN1Integer)seq.getObjectAt(0); this.digestAlgorithm = AlgorithmIdentifier.getInstance(seq.getObjectAt(1)); this.encapContentInfo = ContentInfo.getInstance(seq.getObjectAt(2)); this.digest = ASN1OctetString.getInstance(seq.getObjectAt(3)); } /** * return a CompressedData object from a tagged object. * * @param _ato the tagged object holding the object we want. * @param _explicit true if the object is meant to be explicitly * tagged false otherwise. * @exception IllegalArgumentException if the object held by the * tagged object cannot be converted. */ public static DigestedData getInstance( ASN1TaggedObject _ato, boolean _explicit) { return getInstance(ASN1Sequence.getInstance(_ato, _explicit)); } /** * return a CompressedData object from the given object. * * @param obj the object we want converted. * @exception IllegalArgumentException if the object cannot be converted. */ public static DigestedData getInstance( Object obj) { if (obj instanceof DigestedData) { return (DigestedData)obj; } if (obj != null) { return new DigestedData(ASN1Sequence.getInstance(obj)); } return null; } public ASN1Integer getVersion() { return version; } public AlgorithmIdentifier getDigestAlgorithm() { return digestAlgorithm; } public ContentInfo getEncapContentInfo() { return encapContentInfo; } public ASN1Primitive toASN1Primitive() { ASN1EncodableVector v = new ASN1EncodableVector(); v.add(version); v.add(digestAlgorithm); v.add(encapContentInfo); v.add(digest); return new BERSequence(v); } public byte[] getDigest() { return digest.getOctets(); } } bouncycastle-1.49.orig/src/org/bouncycastle/asn1/cms/Evidence.java0000644000175000017500000000251011725270320024510 0ustar ebourgebourgpackage org.bouncycastle.asn1.cms; import org.bouncycastle.asn1.ASN1Choice; import org.bouncycastle.asn1.ASN1Object; import org.bouncycastle.asn1.ASN1Primitive; import org.bouncycastle.asn1.ASN1TaggedObject; import org.bouncycastle.asn1.DERTaggedObject; public class Evidence extends ASN1Object implements ASN1Choice { private TimeStampTokenEvidence tstEvidence; public Evidence(TimeStampTokenEvidence tstEvidence) { this.tstEvidence = tstEvidence; } private Evidence(ASN1TaggedObject tagged) { if (tagged.getTagNo() == 0) { this.tstEvidence = TimeStampTokenEvidence.getInstance(tagged, false); } } public static Evidence getInstance(Object obj) { if (obj == null || obj instanceof Evidence) { return (Evidence)obj; } else if (obj instanceof ASN1TaggedObject) { return new Evidence(ASN1TaggedObject.getInstance(obj)); } throw new IllegalArgumentException("unknown object in getInstance"); } public TimeStampTokenEvidence getTstEvidence() { return tstEvidence; } public ASN1Primitive toASN1Primitive() { if (tstEvidence != null) { return new DERTaggedObject(false, 0, tstEvidence); } return null; } } bouncycastle-1.49.orig/src/org/bouncycastle/asn1/cms/CompressedDataParser.java0000644000175000017500000000236011724561172027053 0ustar ebourgebourgpackage org.bouncycastle.asn1.cms; import java.io.IOException; import org.bouncycastle.asn1.ASN1Integer; import org.bouncycastle.asn1.ASN1SequenceParser; import org.bouncycastle.asn1.x509.AlgorithmIdentifier; /** * RFC 3274 - CMS Compressed Data. *
     * CompressedData ::= SEQUENCE {
     *  version CMSVersion,
     *  compressionAlgorithm CompressionAlgorithmIdentifier,
     *  encapContentInfo EncapsulatedContentInfo
     * }
     * 
    */ public class CompressedDataParser { private ASN1Integer _version; private AlgorithmIdentifier _compressionAlgorithm; private ContentInfoParser _encapContentInfo; public CompressedDataParser( ASN1SequenceParser seq) throws IOException { this._version = (ASN1Integer)seq.readObject(); this._compressionAlgorithm = AlgorithmIdentifier.getInstance(seq.readObject().toASN1Primitive()); this._encapContentInfo = new ContentInfoParser((ASN1SequenceParser)seq.readObject()); } public ASN1Integer getVersion() { return _version; } public AlgorithmIdentifier getCompressionAlgorithmIdentifier() { return _compressionAlgorithm; } public ContentInfoParser getEncapContentInfo() { return _encapContentInfo; } } bouncycastle-1.49.orig/src/org/bouncycastle/asn1/cms/RecipientInfo.java0000644000175000017500000001003411724561172025533 0ustar ebourgebourgpackage org.bouncycastle.asn1.cms; import org.bouncycastle.asn1.ASN1Choice; import org.bouncycastle.asn1.ASN1Encodable; import org.bouncycastle.asn1.ASN1Integer; import org.bouncycastle.asn1.ASN1Object; import org.bouncycastle.asn1.ASN1Primitive; import org.bouncycastle.asn1.ASN1Sequence; import org.bouncycastle.asn1.ASN1TaggedObject; import org.bouncycastle.asn1.DERTaggedObject; public class RecipientInfo extends ASN1Object implements ASN1Choice { ASN1Encodable info; public RecipientInfo( KeyTransRecipientInfo info) { this.info = info; } public RecipientInfo( KeyAgreeRecipientInfo info) { this.info = new DERTaggedObject(false, 1, info); } public RecipientInfo( KEKRecipientInfo info) { this.info = new DERTaggedObject(false, 2, info); } public RecipientInfo( PasswordRecipientInfo info) { this.info = new DERTaggedObject(false, 3, info); } public RecipientInfo( OtherRecipientInfo info) { this.info = new DERTaggedObject(false, 4, info); } public RecipientInfo( ASN1Primitive info) { this.info = info; } public static RecipientInfo getInstance( Object o) { if (o == null || o instanceof RecipientInfo) { return (RecipientInfo)o; } else if (o instanceof ASN1Sequence) { return new RecipientInfo((ASN1Sequence)o); } else if (o instanceof ASN1TaggedObject) { return new RecipientInfo((ASN1TaggedObject)o); } throw new IllegalArgumentException("unknown object in factory: " + o.getClass().getName()); } public ASN1Integer getVersion() { if (info instanceof ASN1TaggedObject) { ASN1TaggedObject o = (ASN1TaggedObject)info; switch (o.getTagNo()) { case 1: return KeyAgreeRecipientInfo.getInstance(o, false).getVersion(); case 2: return getKEKInfo(o).getVersion(); case 3: return PasswordRecipientInfo.getInstance(o, false).getVersion(); case 4: return new ASN1Integer(0); // no syntax version for OtherRecipientInfo default: throw new IllegalStateException("unknown tag"); } } return KeyTransRecipientInfo.getInstance(info).getVersion(); } public boolean isTagged() { return (info instanceof ASN1TaggedObject); } public ASN1Encodable getInfo() { if (info instanceof ASN1TaggedObject) { ASN1TaggedObject o = (ASN1TaggedObject)info; switch (o.getTagNo()) { case 1: return KeyAgreeRecipientInfo.getInstance(o, false); case 2: return getKEKInfo(o); case 3: return PasswordRecipientInfo.getInstance(o, false); case 4: return OtherRecipientInfo.getInstance(o, false); default: throw new IllegalStateException("unknown tag"); } } return KeyTransRecipientInfo.getInstance(info); } private KEKRecipientInfo getKEKInfo(ASN1TaggedObject o) { if (o.isExplicit()) { // compatibilty with erroneous version return KEKRecipientInfo.getInstance(o, true); } else { return KEKRecipientInfo.getInstance(o, false); } } /** * Produce an object suitable for an ASN1OutputStream. *
         * RecipientInfo ::= CHOICE {
         *     ktri KeyTransRecipientInfo,
         *     kari [1] KeyAgreeRecipientInfo,
         *     kekri [2] KEKRecipientInfo,
         *     pwri [3] PasswordRecipientInfo,
         *     ori [4] OtherRecipientInfo }
         * 
    */ public ASN1Primitive toASN1Primitive() { return info.toASN1Primitive(); } } bouncycastle-1.49.orig/src/org/bouncycastle/asn1/cms/Attribute.java0000644000175000017500000000455511730475447024761 0ustar ebourgebourgpackage org.bouncycastle.asn1.cms; import org.bouncycastle.asn1.ASN1Encodable; import org.bouncycastle.asn1.ASN1EncodableVector; import org.bouncycastle.asn1.ASN1Object; import org.bouncycastle.asn1.ASN1ObjectIdentifier; import org.bouncycastle.asn1.ASN1Primitive; import org.bouncycastle.asn1.ASN1Sequence; import org.bouncycastle.asn1.ASN1Set; import org.bouncycastle.asn1.DERObjectIdentifier; import org.bouncycastle.asn1.DERSequence; public class Attribute extends ASN1Object { private ASN1ObjectIdentifier attrType; private ASN1Set attrValues; /** * return an Attribute object from the given object. * * @param o the object we want converted. * @exception IllegalArgumentException if the object cannot be converted. */ public static Attribute getInstance( Object o) { if (o instanceof Attribute) { return (Attribute)o; } if (o != null) { return new Attribute(ASN1Sequence.getInstance(o)); } return null; } private Attribute( ASN1Sequence seq) { attrType = (ASN1ObjectIdentifier)seq.getObjectAt(0); attrValues = (ASN1Set)seq.getObjectAt(1); } /** * @deprecated use ASN1ObjectIdentifier */ public Attribute( DERObjectIdentifier attrType, ASN1Set attrValues) { this.attrType = new ASN1ObjectIdentifier(attrType.getId()); this.attrValues = attrValues; } public Attribute( ASN1ObjectIdentifier attrType, ASN1Set attrValues) { this.attrType = attrType; this.attrValues = attrValues; } public ASN1ObjectIdentifier getAttrType() { return attrType; } public ASN1Set getAttrValues() { return attrValues; } public ASN1Encodable[] getAttributeValues() { return attrValues.toArray(); } /** * Produce an object suitable for an ASN1OutputStream. *
         * Attribute ::= SEQUENCE {
         *     attrType OBJECT IDENTIFIER,
         *     attrValues SET OF AttributeValue
         * }
         * 
    */ public ASN1Primitive toASN1Primitive() { ASN1EncodableVector v = new ASN1EncodableVector(); v.add(attrType); v.add(attrValues); return new DERSequence(v); } } bouncycastle-1.49.orig/src/org/bouncycastle/asn1/cms/OriginatorInfo.java0000644000175000017500000000665711676757677025775 0ustar ebourgebourgpackage org.bouncycastle.asn1.cms; import org.bouncycastle.asn1.ASN1EncodableVector; import org.bouncycastle.asn1.ASN1Object; import org.bouncycastle.asn1.ASN1Primitive; import org.bouncycastle.asn1.ASN1Sequence; import org.bouncycastle.asn1.ASN1Set; import org.bouncycastle.asn1.ASN1TaggedObject; import org.bouncycastle.asn1.DERSequence; import org.bouncycastle.asn1.DERTaggedObject; public class OriginatorInfo extends ASN1Object { private ASN1Set certs; private ASN1Set crls; public OriginatorInfo( ASN1Set certs, ASN1Set crls) { this.certs = certs; this.crls = crls; } private OriginatorInfo( ASN1Sequence seq) { switch (seq.size()) { case 0: // empty break; case 1: ASN1TaggedObject o = (ASN1TaggedObject)seq.getObjectAt(0); switch (o.getTagNo()) { case 0 : certs = ASN1Set.getInstance(o, false); break; case 1 : crls = ASN1Set.getInstance(o, false); break; default: throw new IllegalArgumentException("Bad tag in OriginatorInfo: " + o.getTagNo()); } break; case 2: certs = ASN1Set.getInstance((ASN1TaggedObject)seq.getObjectAt(0), false); crls = ASN1Set.getInstance((ASN1TaggedObject)seq.getObjectAt(1), false); break; default: throw new IllegalArgumentException("OriginatorInfo too big"); } } /** * return an OriginatorInfo object from a tagged object. * * @param obj the tagged object holding the object we want. * @param explicit true if the object is meant to be explicitly * tagged false otherwise. * @exception IllegalArgumentException if the object held by the * tagged object cannot be converted. */ public static OriginatorInfo getInstance( ASN1TaggedObject obj, boolean explicit) { return getInstance(ASN1Sequence.getInstance(obj, explicit)); } /** * return an OriginatorInfo object from the given object. * * @param obj the object we want converted. * @exception IllegalArgumentException if the object cannot be converted. */ public static OriginatorInfo getInstance( Object obj) { if (obj instanceof OriginatorInfo) { return (OriginatorInfo)obj; } else if (obj != null) { return new OriginatorInfo(ASN1Sequence.getInstance(obj)); } return null; } public ASN1Set getCertificates() { return certs; } public ASN1Set getCRLs() { return crls; } /** * Produce an object suitable for an ASN1OutputStream. *
         * OriginatorInfo ::= SEQUENCE {
         *     certs [0] IMPLICIT CertificateSet OPTIONAL,
         *     crls [1] IMPLICIT CertificateRevocationLists OPTIONAL 
         * }
         * 
    */ public ASN1Primitive toASN1Primitive() { ASN1EncodableVector v = new ASN1EncodableVector(); if (certs != null) { v.add(new DERTaggedObject(false, 0, certs)); } if (crls != null) { v.add(new DERTaggedObject(false, 1, crls)); } return new DERSequence(v); } } bouncycastle-1.49.orig/src/org/bouncycastle/asn1/cms/OtherKeyAttribute.java0000644000175000017500000000407411624652565026430 0ustar ebourgebourgpackage org.bouncycastle.asn1.cms; import org.bouncycastle.asn1.ASN1Encodable; import org.bouncycastle.asn1.ASN1EncodableVector; import org.bouncycastle.asn1.ASN1Object; import org.bouncycastle.asn1.ASN1ObjectIdentifier; import org.bouncycastle.asn1.ASN1Primitive; import org.bouncycastle.asn1.ASN1Sequence; import org.bouncycastle.asn1.DERSequence; public class OtherKeyAttribute extends ASN1Object { private ASN1ObjectIdentifier keyAttrId; private ASN1Encodable keyAttr; /** * return an OtherKeyAttribute object from the given object. * * @param o the object we want converted. * @exception IllegalArgumentException if the object cannot be converted. */ public static OtherKeyAttribute getInstance( Object o) { if (o == null || o instanceof OtherKeyAttribute) { return (OtherKeyAttribute)o; } if (o instanceof ASN1Sequence) { return new OtherKeyAttribute((ASN1Sequence)o); } throw new IllegalArgumentException("unknown object in factory: " + o.getClass().getName()); } public OtherKeyAttribute( ASN1Sequence seq) { keyAttrId = (ASN1ObjectIdentifier)seq.getObjectAt(0); keyAttr = seq.getObjectAt(1); } public OtherKeyAttribute( ASN1ObjectIdentifier keyAttrId, ASN1Encodable keyAttr) { this.keyAttrId = keyAttrId; this.keyAttr = keyAttr; } public ASN1ObjectIdentifier getKeyAttrId() { return keyAttrId; } public ASN1Encodable getKeyAttr() { return keyAttr; } /** * Produce an object suitable for an ASN1OutputStream. *
         * OtherKeyAttribute ::= SEQUENCE {
         *     keyAttrId OBJECT IDENTIFIER,
         *     keyAttr ANY DEFINED BY keyAttrId OPTIONAL
         * }
         * 
    */ public ASN1Primitive toASN1Primitive() { ASN1EncodableVector v = new ASN1EncodableVector(); v.add(keyAttrId); v.add(keyAttr); return new DERSequence(v); } } bouncycastle-1.49.orig/src/org/bouncycastle/asn1/cms/CMSAttributes.java0000644000175000017500000000131311624622713025464 0ustar ebourgebourgpackage org.bouncycastle.asn1.cms; import org.bouncycastle.asn1.ASN1ObjectIdentifier; import org.bouncycastle.asn1.pkcs.PKCSObjectIdentifiers; public interface CMSAttributes { public static final ASN1ObjectIdentifier contentType = PKCSObjectIdentifiers.pkcs_9_at_contentType; public static final ASN1ObjectIdentifier messageDigest = PKCSObjectIdentifiers.pkcs_9_at_messageDigest; public static final ASN1ObjectIdentifier signingTime = PKCSObjectIdentifiers.pkcs_9_at_signingTime; public static final ASN1ObjectIdentifier counterSignature = PKCSObjectIdentifiers.pkcs_9_at_counterSignature; public static final ASN1ObjectIdentifier contentHint = PKCSObjectIdentifiers.id_aa_contentHint; } bouncycastle-1.49.orig/src/org/bouncycastle/asn1/cms/EnvelopedDataParser.java0000644000175000017500000000610511724561172026671 0ustar ebourgebourgpackage org.bouncycastle.asn1.cms; import java.io.IOException; import org.bouncycastle.asn1.ASN1Encodable; import org.bouncycastle.asn1.ASN1Integer; import org.bouncycastle.asn1.ASN1SequenceParser; import org.bouncycastle.asn1.ASN1SetParser; import org.bouncycastle.asn1.ASN1TaggedObjectParser; import org.bouncycastle.asn1.BERTags; /** *
     * EnvelopedData ::= SEQUENCE {
     *     version CMSVersion,
     *     originatorInfo [0] IMPLICIT OriginatorInfo OPTIONAL,
     *     recipientInfos RecipientInfos,
     *     encryptedContentInfo EncryptedContentInfo,
     *     unprotectedAttrs [1] IMPLICIT UnprotectedAttributes OPTIONAL 
     * }
     * 
    */ public class EnvelopedDataParser { private ASN1SequenceParser _seq; private ASN1Integer _version; private ASN1Encodable _nextObject; private boolean _originatorInfoCalled; public EnvelopedDataParser( ASN1SequenceParser seq) throws IOException { this._seq = seq; this._version = ASN1Integer.getInstance(seq.readObject()); } public ASN1Integer getVersion() { return _version; } public OriginatorInfo getOriginatorInfo() throws IOException { _originatorInfoCalled = true; if (_nextObject == null) { _nextObject = _seq.readObject(); } if (_nextObject instanceof ASN1TaggedObjectParser && ((ASN1TaggedObjectParser)_nextObject).getTagNo() == 0) { ASN1SequenceParser originatorInfo = (ASN1SequenceParser) ((ASN1TaggedObjectParser)_nextObject).getObjectParser(BERTags.SEQUENCE, false); _nextObject = null; return OriginatorInfo.getInstance(originatorInfo.toASN1Primitive()); } return null; } public ASN1SetParser getRecipientInfos() throws IOException { if (!_originatorInfoCalled) { getOriginatorInfo(); } if (_nextObject == null) { _nextObject = _seq.readObject(); } ASN1SetParser recipientInfos = (ASN1SetParser)_nextObject; _nextObject = null; return recipientInfos; } public EncryptedContentInfoParser getEncryptedContentInfo() throws IOException { if (_nextObject == null) { _nextObject = _seq.readObject(); } if (_nextObject != null) { ASN1SequenceParser o = (ASN1SequenceParser) _nextObject; _nextObject = null; return new EncryptedContentInfoParser(o); } return null; } public ASN1SetParser getUnprotectedAttrs() throws IOException { if (_nextObject == null) { _nextObject = _seq.readObject(); } if (_nextObject != null) { ASN1Encodable o = _nextObject; _nextObject = null; return (ASN1SetParser)((ASN1TaggedObjectParser)o).getObjectParser(BERTags.SET, false); } return null; } } bouncycastle-1.49.orig/src/org/bouncycastle/asn1/cms/CMSObjectIdentifiers.java0000644000175000017500000000314312116276613026736 0ustar ebourgebourgpackage org.bouncycastle.asn1.cms; import org.bouncycastle.asn1.ASN1ObjectIdentifier; import org.bouncycastle.asn1.pkcs.PKCSObjectIdentifiers; public interface CMSObjectIdentifiers { static final ASN1ObjectIdentifier data = PKCSObjectIdentifiers.data; static final ASN1ObjectIdentifier signedData = PKCSObjectIdentifiers.signedData; static final ASN1ObjectIdentifier envelopedData = PKCSObjectIdentifiers.envelopedData; static final ASN1ObjectIdentifier signedAndEnvelopedData = PKCSObjectIdentifiers.signedAndEnvelopedData; static final ASN1ObjectIdentifier digestedData = PKCSObjectIdentifiers.digestedData; static final ASN1ObjectIdentifier encryptedData = PKCSObjectIdentifiers.encryptedData; static final ASN1ObjectIdentifier authenticatedData = PKCSObjectIdentifiers.id_ct_authData; static final ASN1ObjectIdentifier compressedData = PKCSObjectIdentifiers.id_ct_compressedData; static final ASN1ObjectIdentifier authEnvelopedData = PKCSObjectIdentifiers.id_ct_authEnvelopedData; static final ASN1ObjectIdentifier timestampedData = PKCSObjectIdentifiers.id_ct_timestampedData; /** * The other Revocation Info arc * id-ri OBJECT IDENTIFIER ::= { iso(1) identified-organization(3) * dod(6) internet(1) security(5) mechanisms(5) pkix(7) ri(16) } */ static final ASN1ObjectIdentifier id_ri = new ASN1ObjectIdentifier("1.3.6.1.5.5.7.16"); static final ASN1ObjectIdentifier id_ri_ocsp_response = id_ri.branch("2"); static final ASN1ObjectIdentifier id_ri_scvp = id_ri.branch("4"); } bouncycastle-1.49.orig/src/org/bouncycastle/asn1/cms/OriginatorIdentifierOrKey.java0000644000175000017500000001055211725023222030062 0ustar ebourgebourgpackage org.bouncycastle.asn1.cms; import org.bouncycastle.asn1.ASN1Choice; import org.bouncycastle.asn1.ASN1Encodable; import org.bouncycastle.asn1.ASN1Object; import org.bouncycastle.asn1.ASN1OctetString; import org.bouncycastle.asn1.ASN1Primitive; import org.bouncycastle.asn1.ASN1TaggedObject; import org.bouncycastle.asn1.DERTaggedObject; import org.bouncycastle.asn1.x509.SubjectKeyIdentifier; public class OriginatorIdentifierOrKey extends ASN1Object implements ASN1Choice { private ASN1Encodable id; public OriginatorIdentifierOrKey( IssuerAndSerialNumber id) { this.id = id; } /** * @deprecated use version taking a SubjectKeyIdentifier */ public OriginatorIdentifierOrKey( ASN1OctetString id) { this(new SubjectKeyIdentifier(id.getOctets())); } public OriginatorIdentifierOrKey( SubjectKeyIdentifier id) { this.id = new DERTaggedObject(false, 0, id); } public OriginatorIdentifierOrKey( OriginatorPublicKey id) { this.id = new DERTaggedObject(false, 1, id); } /** * @deprecated use more specific version */ public OriginatorIdentifierOrKey( ASN1Primitive id) { this.id = id; } /** * return an OriginatorIdentifierOrKey object from a tagged object. * * @param o the tagged object holding the object we want. * @param explicit true if the object is meant to be explicitly * tagged false otherwise. * @exception IllegalArgumentException if the object held by the * tagged object cannot be converted. */ public static OriginatorIdentifierOrKey getInstance( ASN1TaggedObject o, boolean explicit) { if (!explicit) { throw new IllegalArgumentException( "Can't implicitly tag OriginatorIdentifierOrKey"); } return getInstance(o.getObject()); } /** * return an OriginatorIdentifierOrKey object from the given object. * * @param o the object we want converted. * @exception IllegalArgumentException if the object cannot be converted. */ public static OriginatorIdentifierOrKey getInstance( Object o) { if (o == null || o instanceof OriginatorIdentifierOrKey) { return (OriginatorIdentifierOrKey)o; } if (o instanceof IssuerAndSerialNumber) { return new OriginatorIdentifierOrKey((IssuerAndSerialNumber)o); } if (o instanceof SubjectKeyIdentifier) { return new OriginatorIdentifierOrKey((SubjectKeyIdentifier)o); } if (o instanceof OriginatorPublicKey) { return new OriginatorIdentifierOrKey((OriginatorPublicKey)o); } if (o instanceof ASN1TaggedObject) { // TODO Add validation return new OriginatorIdentifierOrKey((ASN1TaggedObject)o); } throw new IllegalArgumentException("Invalid OriginatorIdentifierOrKey: " + o.getClass().getName()); } public ASN1Encodable getId() { return id; } public IssuerAndSerialNumber getIssuerAndSerialNumber() { if (id instanceof IssuerAndSerialNumber) { return (IssuerAndSerialNumber)id; } return null; } public SubjectKeyIdentifier getSubjectKeyIdentifier() { if (id instanceof ASN1TaggedObject && ((ASN1TaggedObject)id).getTagNo() == 0) { return SubjectKeyIdentifier.getInstance((ASN1TaggedObject)id, false); } return null; } public OriginatorPublicKey getOriginatorKey() { if (id instanceof ASN1TaggedObject && ((ASN1TaggedObject)id).getTagNo() == 1) { return OriginatorPublicKey.getInstance((ASN1TaggedObject)id, false); } return null; } /** * Produce an object suitable for an ASN1OutputStream. *
         * OriginatorIdentifierOrKey ::= CHOICE {
         *     issuerAndSerialNumber IssuerAndSerialNumber,
         *     subjectKeyIdentifier [0] SubjectKeyIdentifier,
         *     originatorKey [1] OriginatorPublicKey 
         * }
         *
         * SubjectKeyIdentifier ::= OCTET STRING
         * 
    */ public ASN1Primitive toASN1Primitive() { return id.toASN1Primitive(); } } bouncycastle-1.49.orig/src/org/bouncycastle/asn1/cms/SignerIdentifier.java0000644000175000017500000000460311624626647026244 0ustar ebourgebourgpackage org.bouncycastle.asn1.cms; import org.bouncycastle.asn1.ASN1Choice; import org.bouncycastle.asn1.ASN1Encodable; import org.bouncycastle.asn1.ASN1Object; import org.bouncycastle.asn1.ASN1OctetString; import org.bouncycastle.asn1.ASN1Primitive; import org.bouncycastle.asn1.ASN1TaggedObject; import org.bouncycastle.asn1.DERTaggedObject; public class SignerIdentifier extends ASN1Object implements ASN1Choice { private ASN1Encodable id; public SignerIdentifier( IssuerAndSerialNumber id) { this.id = id; } public SignerIdentifier( ASN1OctetString id) { this.id = new DERTaggedObject(false, 0, id); } public SignerIdentifier( ASN1Primitive id) { this.id = id; } /** * return a SignerIdentifier object from the given object. * * @param o the object we want converted. * @exception IllegalArgumentException if the object cannot be converted. */ public static SignerIdentifier getInstance( Object o) { if (o == null || o instanceof SignerIdentifier) { return (SignerIdentifier)o; } if (o instanceof IssuerAndSerialNumber) { return new SignerIdentifier((IssuerAndSerialNumber)o); } if (o instanceof ASN1OctetString) { return new SignerIdentifier((ASN1OctetString)o); } if (o instanceof ASN1Primitive) { return new SignerIdentifier((ASN1Primitive)o); } throw new IllegalArgumentException( "Illegal object in SignerIdentifier: " + o.getClass().getName()); } public boolean isTagged() { return (id instanceof ASN1TaggedObject); } public ASN1Encodable getId() { if (id instanceof ASN1TaggedObject) { return ASN1OctetString.getInstance((ASN1TaggedObject)id, false); } return id; } /** * Produce an object suitable for an ASN1OutputStream. *
         * SignerIdentifier ::= CHOICE {
         *     issuerAndSerialNumber IssuerAndSerialNumber,
         *     subjectKeyIdentifier [0] SubjectKeyIdentifier 
         * }
         *
         * SubjectKeyIdentifier ::= OCTET STRING
         * 
    */ public ASN1Primitive toASN1Primitive() { return id.toASN1Primitive(); } } bouncycastle-1.49.orig/src/org/bouncycastle/asn1/cms/RecipientIdentifier.java0000644000175000017500000000471211624626647026740 0ustar ebourgebourgpackage org.bouncycastle.asn1.cms; import org.bouncycastle.asn1.ASN1Choice; import org.bouncycastle.asn1.ASN1Encodable; import org.bouncycastle.asn1.ASN1Object; import org.bouncycastle.asn1.ASN1OctetString; import org.bouncycastle.asn1.ASN1Primitive; import org.bouncycastle.asn1.ASN1TaggedObject; import org.bouncycastle.asn1.DERTaggedObject; public class RecipientIdentifier extends ASN1Object implements ASN1Choice { private ASN1Encodable id; public RecipientIdentifier( IssuerAndSerialNumber id) { this.id = id; } public RecipientIdentifier( ASN1OctetString id) { this.id = new DERTaggedObject(false, 0, id); } public RecipientIdentifier( ASN1Primitive id) { this.id = id; } /** * return a RecipientIdentifier object from the given object. * * @param o the object we want converted. * @exception IllegalArgumentException if the object cannot be converted. */ public static RecipientIdentifier getInstance( Object o) { if (o == null || o instanceof RecipientIdentifier) { return (RecipientIdentifier)o; } if (o instanceof IssuerAndSerialNumber) { return new RecipientIdentifier((IssuerAndSerialNumber)o); } if (o instanceof ASN1OctetString) { return new RecipientIdentifier((ASN1OctetString)o); } if (o instanceof ASN1Primitive) { return new RecipientIdentifier((ASN1Primitive)o); } throw new IllegalArgumentException( "Illegal object in RecipientIdentifier: " + o.getClass().getName()); } public boolean isTagged() { return (id instanceof ASN1TaggedObject); } public ASN1Encodable getId() { if (id instanceof ASN1TaggedObject) { return ASN1OctetString.getInstance((ASN1TaggedObject)id, false); } return IssuerAndSerialNumber.getInstance(id); } /** * Produce an object suitable for an ASN1OutputStream. *
         * RecipientIdentifier ::= CHOICE {
         *     issuerAndSerialNumber IssuerAndSerialNumber,
         *     subjectKeyIdentifier [0] SubjectKeyIdentifier 
         * }
         *
         * SubjectKeyIdentifier ::= OCTET STRING
         * 
    */ public ASN1Primitive toASN1Primitive() { return id.toASN1Primitive(); } } bouncycastle-1.49.orig/src/org/bouncycastle/asn1/cms/SignedDataParser.java0000644000175000017500000000704711724561172026167 0ustar ebourgebourgpackage org.bouncycastle.asn1.cms; import java.io.IOException; import org.bouncycastle.asn1.ASN1Integer; import org.bouncycastle.asn1.ASN1Sequence; import org.bouncycastle.asn1.ASN1SequenceParser; import org.bouncycastle.asn1.ASN1Set; import org.bouncycastle.asn1.ASN1SetParser; import org.bouncycastle.asn1.ASN1TaggedObjectParser; import org.bouncycastle.asn1.BERTags; /** *
     * SignedData ::= SEQUENCE {
     *     version CMSVersion,
     *     digestAlgorithms DigestAlgorithmIdentifiers,
     *     encapContentInfo EncapsulatedContentInfo,
     *     certificates [0] IMPLICIT CertificateSet OPTIONAL,
     *     crls [1] IMPLICIT CertificateRevocationLists OPTIONAL,
     *     signerInfos SignerInfos
     *   }
     * 
    */ public class SignedDataParser { private ASN1SequenceParser _seq; private ASN1Integer _version; private Object _nextObject; private boolean _certsCalled; private boolean _crlsCalled; public static SignedDataParser getInstance( Object o) throws IOException { if (o instanceof ASN1Sequence) { return new SignedDataParser(((ASN1Sequence)o).parser()); } if (o instanceof ASN1SequenceParser) { return new SignedDataParser((ASN1SequenceParser)o); } throw new IOException("unknown object encountered: " + o.getClass().getName()); } private SignedDataParser( ASN1SequenceParser seq) throws IOException { this._seq = seq; this._version = (ASN1Integer)seq.readObject(); } public ASN1Integer getVersion() { return _version; } public ASN1SetParser getDigestAlgorithms() throws IOException { Object o = _seq.readObject(); if (o instanceof ASN1Set) { return ((ASN1Set)o).parser(); } return (ASN1SetParser)o; } public ContentInfoParser getEncapContentInfo() throws IOException { return new ContentInfoParser((ASN1SequenceParser)_seq.readObject()); } public ASN1SetParser getCertificates() throws IOException { _certsCalled = true; _nextObject = _seq.readObject(); if (_nextObject instanceof ASN1TaggedObjectParser && ((ASN1TaggedObjectParser)_nextObject).getTagNo() == 0) { ASN1SetParser certs = (ASN1SetParser)((ASN1TaggedObjectParser)_nextObject).getObjectParser(BERTags.SET, false); _nextObject = null; return certs; } return null; } public ASN1SetParser getCrls() throws IOException { if (!_certsCalled) { throw new IOException("getCerts() has not been called."); } _crlsCalled = true; if (_nextObject == null) { _nextObject = _seq.readObject(); } if (_nextObject instanceof ASN1TaggedObjectParser && ((ASN1TaggedObjectParser)_nextObject).getTagNo() == 1) { ASN1SetParser crls = (ASN1SetParser)((ASN1TaggedObjectParser)_nextObject).getObjectParser(BERTags.SET, false); _nextObject = null; return crls; } return null; } public ASN1SetParser getSignerInfos() throws IOException { if (!_certsCalled || !_crlsCalled) { throw new IOException("getCerts() and/or getCrls() has not been called."); } if (_nextObject == null) { _nextObject = _seq.readObject(); } return (ASN1SetParser)_nextObject; } } bouncycastle-1.49.orig/src/org/bouncycastle/asn1/cms/ContentInfoParser.java0000644000175000017500000000220311624642103026370 0ustar ebourgebourgpackage org.bouncycastle.asn1.cms; import java.io.IOException; import org.bouncycastle.asn1.ASN1Encodable; import org.bouncycastle.asn1.ASN1ObjectIdentifier; import org.bouncycastle.asn1.ASN1SequenceParser; import org.bouncycastle.asn1.ASN1TaggedObjectParser; /** * Produce an object suitable for an ASN1OutputStream. *
     * ContentInfo ::= SEQUENCE {
     *          contentType ContentType,
     *          content
     *          [0] EXPLICIT ANY DEFINED BY contentType OPTIONAL }
     * 
    */ public class ContentInfoParser { private ASN1ObjectIdentifier contentType; private ASN1TaggedObjectParser content; public ContentInfoParser( ASN1SequenceParser seq) throws IOException { contentType = (ASN1ObjectIdentifier)seq.readObject(); content = (ASN1TaggedObjectParser)seq.readObject(); } public ASN1ObjectIdentifier getContentType() { return contentType; } public ASN1Encodable getContent( int tag) throws IOException { if (content != null) { return content.getObjectParser(tag, true); } return null; } } bouncycastle-1.49.orig/src/org/bouncycastle/asn1/cms/PasswordRecipientInfo.java0000644000175000017500000001076711724561172027273 0ustar ebourgebourgpackage org.bouncycastle.asn1.cms; import org.bouncycastle.asn1.ASN1EncodableVector; import org.bouncycastle.asn1.ASN1Integer; import org.bouncycastle.asn1.ASN1Object; import org.bouncycastle.asn1.ASN1OctetString; import org.bouncycastle.asn1.ASN1Primitive; import org.bouncycastle.asn1.ASN1Sequence; import org.bouncycastle.asn1.ASN1TaggedObject; import org.bouncycastle.asn1.DERSequence; import org.bouncycastle.asn1.DERTaggedObject; import org.bouncycastle.asn1.x509.AlgorithmIdentifier; public class PasswordRecipientInfo extends ASN1Object { private ASN1Integer version; private AlgorithmIdentifier keyDerivationAlgorithm; private AlgorithmIdentifier keyEncryptionAlgorithm; private ASN1OctetString encryptedKey; public PasswordRecipientInfo( AlgorithmIdentifier keyEncryptionAlgorithm, ASN1OctetString encryptedKey) { this.version = new ASN1Integer(0); this.keyEncryptionAlgorithm = keyEncryptionAlgorithm; this.encryptedKey = encryptedKey; } public PasswordRecipientInfo( AlgorithmIdentifier keyDerivationAlgorithm, AlgorithmIdentifier keyEncryptionAlgorithm, ASN1OctetString encryptedKey) { this.version = new ASN1Integer(0); this.keyDerivationAlgorithm = keyDerivationAlgorithm; this.keyEncryptionAlgorithm = keyEncryptionAlgorithm; this.encryptedKey = encryptedKey; } public PasswordRecipientInfo( ASN1Sequence seq) { version = (ASN1Integer)seq.getObjectAt(0); if (seq.getObjectAt(1) instanceof ASN1TaggedObject) { keyDerivationAlgorithm = AlgorithmIdentifier.getInstance((ASN1TaggedObject)seq.getObjectAt(1), false); keyEncryptionAlgorithm = AlgorithmIdentifier.getInstance(seq.getObjectAt(2)); encryptedKey = (ASN1OctetString)seq.getObjectAt(3); } else { keyEncryptionAlgorithm = AlgorithmIdentifier.getInstance(seq.getObjectAt(1)); encryptedKey = (ASN1OctetString)seq.getObjectAt(2); } } /** * return a PasswordRecipientInfo object from a tagged object. * * @param obj the tagged object holding the object we want. * @param explicit true if the object is meant to be explicitly * tagged false otherwise. * @exception IllegalArgumentException if the object held by the * tagged object cannot be converted. */ public static PasswordRecipientInfo getInstance( ASN1TaggedObject obj, boolean explicit) { return getInstance(ASN1Sequence.getInstance(obj, explicit)); } /** * return a PasswordRecipientInfo object from the given object. * * @param obj the object we want converted. * @exception IllegalArgumentException if the object cannot be converted. */ public static PasswordRecipientInfo getInstance( Object obj) { if (obj == null || obj instanceof PasswordRecipientInfo) { return (PasswordRecipientInfo)obj; } if(obj instanceof ASN1Sequence) { return new PasswordRecipientInfo((ASN1Sequence)obj); } throw new IllegalArgumentException("Invalid PasswordRecipientInfo: " + obj.getClass().getName()); } public ASN1Integer getVersion() { return version; } public AlgorithmIdentifier getKeyDerivationAlgorithm() { return keyDerivationAlgorithm; } public AlgorithmIdentifier getKeyEncryptionAlgorithm() { return keyEncryptionAlgorithm; } public ASN1OctetString getEncryptedKey() { return encryptedKey; } /** * Produce an object suitable for an ASN1OutputStream. *
         * PasswordRecipientInfo ::= SEQUENCE {
         *   version CMSVersion,   -- Always set to 0
         *   keyDerivationAlgorithm [0] KeyDerivationAlgorithmIdentifier
         *                             OPTIONAL,
         *  keyEncryptionAlgorithm KeyEncryptionAlgorithmIdentifier,
         *  encryptedKey EncryptedKey }
         * 
    */ public ASN1Primitive toASN1Primitive() { ASN1EncodableVector v = new ASN1EncodableVector(); v.add(version); if (keyDerivationAlgorithm != null) { v.add(new DERTaggedObject(false, 0, keyDerivationAlgorithm)); } v.add(keyEncryptionAlgorithm); v.add(encryptedKey); return new DERSequence(v); } } bouncycastle-1.49.orig/src/org/bouncycastle/asn1/cms/SignerInfo.java0000644000175000017500000001406512127171760025046 0ustar ebourgebourgpackage org.bouncycastle.asn1.cms; import java.util.Enumeration; import org.bouncycastle.asn1.ASN1EncodableVector; import org.bouncycastle.asn1.ASN1Integer; import org.bouncycastle.asn1.ASN1Object; import org.bouncycastle.asn1.ASN1OctetString; 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.DERTaggedObject; import org.bouncycastle.asn1.x509.AlgorithmIdentifier; public class SignerInfo extends ASN1Object { private ASN1Integer version; private SignerIdentifier sid; private AlgorithmIdentifier digAlgorithm; private ASN1Set authenticatedAttributes; private AlgorithmIdentifier digEncryptionAlgorithm; private ASN1OctetString encryptedDigest; private ASN1Set unauthenticatedAttributes; public static SignerInfo getInstance( Object o) throws IllegalArgumentException { if (o == null || o instanceof SignerInfo) { return (SignerInfo)o; } else if (o instanceof ASN1Sequence) { return new SignerInfo((ASN1Sequence)o); } throw new IllegalArgumentException("unknown object in factory: " + o.getClass().getName()); } public SignerInfo( SignerIdentifier sid, AlgorithmIdentifier digAlgorithm, ASN1Set authenticatedAttributes, AlgorithmIdentifier digEncryptionAlgorithm, ASN1OctetString encryptedDigest, ASN1Set unauthenticatedAttributes) { if (sid.isTagged()) { this.version = new ASN1Integer(3); } else { this.version = new ASN1Integer(1); } this.sid = sid; this.digAlgorithm = digAlgorithm; this.authenticatedAttributes = authenticatedAttributes; this.digEncryptionAlgorithm = digEncryptionAlgorithm; this.encryptedDigest = encryptedDigest; this.unauthenticatedAttributes = unauthenticatedAttributes; } public SignerInfo( SignerIdentifier sid, AlgorithmIdentifier digAlgorithm, Attributes authenticatedAttributes, AlgorithmIdentifier digEncryptionAlgorithm, ASN1OctetString encryptedDigest, Attributes unauthenticatedAttributes) { if (sid.isTagged()) { this.version = new ASN1Integer(3); } else { this.version = new ASN1Integer(1); } this.sid = sid; this.digAlgorithm = digAlgorithm; this.authenticatedAttributes = ASN1Set.getInstance(authenticatedAttributes); this.digEncryptionAlgorithm = digEncryptionAlgorithm; this.encryptedDigest = encryptedDigest; this.unauthenticatedAttributes = ASN1Set.getInstance(unauthenticatedAttributes); } /** * @deprecated use getInstance() method. */ public SignerInfo( ASN1Sequence seq) { Enumeration e = seq.getObjects(); version = (ASN1Integer)e.nextElement(); sid = SignerIdentifier.getInstance(e.nextElement()); digAlgorithm = AlgorithmIdentifier.getInstance(e.nextElement()); Object obj = e.nextElement(); if (obj instanceof ASN1TaggedObject) { authenticatedAttributes = ASN1Set.getInstance((ASN1TaggedObject)obj, false); digEncryptionAlgorithm = AlgorithmIdentifier.getInstance(e.nextElement()); } else { authenticatedAttributes = null; digEncryptionAlgorithm = AlgorithmIdentifier.getInstance(obj); } encryptedDigest = DEROctetString.getInstance(e.nextElement()); if (e.hasMoreElements()) { unauthenticatedAttributes = ASN1Set.getInstance((ASN1TaggedObject)e.nextElement(), false); } else { unauthenticatedAttributes = null; } } public ASN1Integer getVersion() { return version; } public SignerIdentifier getSID() { return sid; } public ASN1Set getAuthenticatedAttributes() { return authenticatedAttributes; } public AlgorithmIdentifier getDigestAlgorithm() { return digAlgorithm; } public ASN1OctetString getEncryptedDigest() { return encryptedDigest; } public AlgorithmIdentifier getDigestEncryptionAlgorithm() { return digEncryptionAlgorithm; } public ASN1Set getUnauthenticatedAttributes() { return unauthenticatedAttributes; } /** * Produce an object suitable for an ASN1OutputStream. *
         *  SignerInfo ::= SEQUENCE {
         *      version Version,
         *      SignerIdentifier sid,
         *      digestAlgorithm DigestAlgorithmIdentifier,
         *      authenticatedAttributes [0] IMPLICIT Attributes OPTIONAL,
         *      digestEncryptionAlgorithm DigestEncryptionAlgorithmIdentifier,
         *      encryptedDigest EncryptedDigest,
         *      unauthenticatedAttributes [1] IMPLICIT Attributes OPTIONAL
         *  }
         *
         *  EncryptedDigest ::= OCTET STRING
         *
         *  DigestAlgorithmIdentifier ::= AlgorithmIdentifier
         *
         *  DigestEncryptionAlgorithmIdentifier ::= AlgorithmIdentifier
         * 
    */ public ASN1Primitive toASN1Primitive() { ASN1EncodableVector v = new ASN1EncodableVector(); v.add(version); v.add(sid); v.add(digAlgorithm); if (authenticatedAttributes != null) { v.add(new DERTaggedObject(false, 0, authenticatedAttributes)); } v.add(digEncryptionAlgorithm); v.add(encryptedDigest); if (unauthenticatedAttributes != null) { v.add(new DERTaggedObject(false, 1, unauthenticatedAttributes)); } return new DERSequence(v); } } bouncycastle-1.49.orig/src/org/bouncycastle/asn1/cms/TimeStampTokenEvidence.java0000644000175000017500000000414011624652555027352 0ustar ebourgebourgpackage org.bouncycastle.asn1.cms; import java.util.Enumeration; import org.bouncycastle.asn1.ASN1EncodableVector; import org.bouncycastle.asn1.ASN1Object; import org.bouncycastle.asn1.ASN1Primitive; import org.bouncycastle.asn1.ASN1Sequence; import org.bouncycastle.asn1.ASN1TaggedObject; import org.bouncycastle.asn1.DERSequence; public class TimeStampTokenEvidence extends ASN1Object { private TimeStampAndCRL[] timeStampAndCRLs; public TimeStampTokenEvidence(TimeStampAndCRL[] timeStampAndCRLs) { this.timeStampAndCRLs = timeStampAndCRLs; } public TimeStampTokenEvidence(TimeStampAndCRL timeStampAndCRL) { this.timeStampAndCRLs = new TimeStampAndCRL[1]; timeStampAndCRLs[0] = timeStampAndCRL; } private TimeStampTokenEvidence(ASN1Sequence seq) { this.timeStampAndCRLs = new TimeStampAndCRL[seq.size()]; int count = 0; for (Enumeration en = seq.getObjects(); en.hasMoreElements();) { timeStampAndCRLs[count++] = TimeStampAndCRL.getInstance(en.nextElement()); } } public static TimeStampTokenEvidence getInstance(ASN1TaggedObject tagged, boolean explicit) { return getInstance(ASN1Sequence.getInstance(tagged, explicit)); } public static TimeStampTokenEvidence getInstance(Object obj) { if (obj instanceof TimeStampTokenEvidence) { return (TimeStampTokenEvidence)obj; } else if (obj != null) { return new TimeStampTokenEvidence(ASN1Sequence.getInstance(obj)); } return null; } public TimeStampAndCRL[] toTimeStampAndCRLArray() { return timeStampAndCRLs; } /** *
         * TimeStampTokenEvidence ::=
         *    SEQUENCE SIZE(1..MAX) OF TimeStampAndCRL
         * 
    * @return */ public ASN1Primitive toASN1Primitive() { ASN1EncodableVector v = new ASN1EncodableVector(); for (int i = 0; i != timeStampAndCRLs.length; i++) { v.add(timeStampAndCRLs[i]); } return new DERSequence(v); } } bouncycastle-1.49.orig/src/org/bouncycastle/asn1/cms/AuthEnvelopedData.java0000644000175000017500000001425311724561172026341 0ustar ebourgebourgpackage org.bouncycastle.asn1.cms; import org.bouncycastle.asn1.ASN1EncodableVector; import org.bouncycastle.asn1.ASN1Integer; import org.bouncycastle.asn1.ASN1Object; import org.bouncycastle.asn1.ASN1OctetString; import org.bouncycastle.asn1.ASN1Primitive; import org.bouncycastle.asn1.ASN1Sequence; import org.bouncycastle.asn1.ASN1Set; import org.bouncycastle.asn1.ASN1TaggedObject; import org.bouncycastle.asn1.BERSequence; import org.bouncycastle.asn1.DERTaggedObject; public class AuthEnvelopedData extends ASN1Object { private ASN1Integer version; private OriginatorInfo originatorInfo; private ASN1Set recipientInfos; private EncryptedContentInfo authEncryptedContentInfo; private ASN1Set authAttrs; private ASN1OctetString mac; private ASN1Set unauthAttrs; public AuthEnvelopedData( OriginatorInfo originatorInfo, ASN1Set recipientInfos, EncryptedContentInfo authEncryptedContentInfo, ASN1Set authAttrs, ASN1OctetString mac, ASN1Set unauthAttrs) { // "It MUST be set to 0." this.version = new ASN1Integer(0); this.originatorInfo = originatorInfo; // TODO // "There MUST be at least one element in the collection." this.recipientInfos = recipientInfos; this.authEncryptedContentInfo = authEncryptedContentInfo; // TODO // "The authAttrs MUST be present if the content type carried in // EncryptedContentInfo is not id-data." this.authAttrs = authAttrs; this.mac = mac; this.unauthAttrs = unauthAttrs; } public AuthEnvelopedData( ASN1Sequence seq) { int index = 0; // TODO // "It MUST be set to 0." ASN1Primitive tmp = seq.getObjectAt(index++).toASN1Primitive(); version = (ASN1Integer)tmp; tmp = seq.getObjectAt(index++).toASN1Primitive(); if (tmp instanceof ASN1TaggedObject) { originatorInfo = OriginatorInfo.getInstance((ASN1TaggedObject)tmp, false); tmp = seq.getObjectAt(index++).toASN1Primitive(); } // TODO // "There MUST be at least one element in the collection." recipientInfos = ASN1Set.getInstance(tmp); tmp = seq.getObjectAt(index++).toASN1Primitive(); authEncryptedContentInfo = EncryptedContentInfo.getInstance(tmp); tmp = seq.getObjectAt(index++).toASN1Primitive(); if (tmp instanceof ASN1TaggedObject) { authAttrs = ASN1Set.getInstance((ASN1TaggedObject)tmp, false); tmp = seq.getObjectAt(index++).toASN1Primitive(); } else { // TODO // "The authAttrs MUST be present if the content type carried in // EncryptedContentInfo is not id-data." } mac = ASN1OctetString.getInstance(tmp); if (seq.size() > index) { tmp = seq.getObjectAt(index++).toASN1Primitive(); unauthAttrs = ASN1Set.getInstance((ASN1TaggedObject)tmp, false); } } /** * return an AuthEnvelopedData object from a tagged object. * * @param obj the tagged object holding the object we want. * @param explicit true if the object is meant to be explicitly * tagged false otherwise. * @throws IllegalArgumentException if the object held by the * tagged object cannot be converted. */ public static AuthEnvelopedData getInstance( ASN1TaggedObject obj, boolean explicit) { return getInstance(ASN1Sequence.getInstance(obj, explicit)); } /** * return an AuthEnvelopedData object from the given object. * * @param obj the object we want converted. * @throws IllegalArgumentException if the object cannot be converted. */ public static AuthEnvelopedData getInstance( Object obj) { if (obj == null || obj instanceof AuthEnvelopedData) { return (AuthEnvelopedData)obj; } if (obj instanceof ASN1Sequence) { return new AuthEnvelopedData((ASN1Sequence)obj); } throw new IllegalArgumentException("Invalid AuthEnvelopedData: " + obj.getClass().getName()); } public ASN1Integer getVersion() { return version; } public OriginatorInfo getOriginatorInfo() { return originatorInfo; } public ASN1Set getRecipientInfos() { return recipientInfos; } public EncryptedContentInfo getAuthEncryptedContentInfo() { return authEncryptedContentInfo; } public ASN1Set getAuthAttrs() { return authAttrs; } public ASN1OctetString getMac() { return mac; } public ASN1Set getUnauthAttrs() { return unauthAttrs; } /** * Produce an object suitable for an ASN1OutputStream. *
         * AuthEnvelopedData ::= SEQUENCE {
         *   version CMSVersion,
         *   originatorInfo [0] IMPLICIT OriginatorInfo OPTIONAL,
         *   recipientInfos RecipientInfos,
         *   authEncryptedContentInfo EncryptedContentInfo,
         *   authAttrs [1] IMPLICIT AuthAttributes OPTIONAL,
         *   mac MessageAuthenticationCode,
         *   unauthAttrs [2] IMPLICIT UnauthAttributes OPTIONAL }
         * 
    */ public ASN1Primitive toASN1Primitive() { ASN1EncodableVector v = new ASN1EncodableVector(); v.add(version); if (originatorInfo != null) { v.add(new DERTaggedObject(false, 0, originatorInfo)); } v.add(recipientInfos); v.add(authEncryptedContentInfo); // "authAttrs optionally contains the authenticated attributes." if (authAttrs != null) { // "AuthAttributes MUST be DER encoded, even if the rest of the // AuthEnvelopedData structure is BER encoded." v.add(new DERTaggedObject(false, 1, authAttrs)); } v.add(mac); // "unauthAttrs optionally contains the unauthenticated attributes." if (unauthAttrs != null) { v.add(new DERTaggedObject(false, 2, unauthAttrs)); } return new BERSequence(v); } } bouncycastle-1.49.orig/src/org/bouncycastle/asn1/cms/KEKRecipientInfo.java0000644000175000017500000000674611724561172026105 0ustar ebourgebourgpackage org.bouncycastle.asn1.cms; import org.bouncycastle.asn1.ASN1EncodableVector; import org.bouncycastle.asn1.ASN1Integer; import org.bouncycastle.asn1.ASN1Object; import org.bouncycastle.asn1.ASN1OctetString; import org.bouncycastle.asn1.ASN1Primitive; import org.bouncycastle.asn1.ASN1Sequence; import org.bouncycastle.asn1.ASN1TaggedObject; import org.bouncycastle.asn1.DERSequence; import org.bouncycastle.asn1.x509.AlgorithmIdentifier; public class KEKRecipientInfo extends ASN1Object { private ASN1Integer version; private KEKIdentifier kekid; private AlgorithmIdentifier keyEncryptionAlgorithm; private ASN1OctetString encryptedKey; public KEKRecipientInfo( KEKIdentifier kekid, AlgorithmIdentifier keyEncryptionAlgorithm, ASN1OctetString encryptedKey) { this.version = new ASN1Integer(4); this.kekid = kekid; this.keyEncryptionAlgorithm = keyEncryptionAlgorithm; this.encryptedKey = encryptedKey; } public KEKRecipientInfo( ASN1Sequence seq) { version = (ASN1Integer)seq.getObjectAt(0); kekid = KEKIdentifier.getInstance(seq.getObjectAt(1)); keyEncryptionAlgorithm = AlgorithmIdentifier.getInstance(seq.getObjectAt(2)); encryptedKey = (ASN1OctetString)seq.getObjectAt(3); } /** * return a KEKRecipientInfo object from a tagged object. * * @param obj the tagged object holding the object we want. * @param explicit true if the object is meant to be explicitly * tagged false otherwise. * @exception IllegalArgumentException if the object held by the * tagged object cannot be converted. */ public static KEKRecipientInfo getInstance( ASN1TaggedObject obj, boolean explicit) { return getInstance(ASN1Sequence.getInstance(obj, explicit)); } /** * return a KEKRecipientInfo object from the given object. * * @param obj the object we want converted. * @exception IllegalArgumentException if the object cannot be converted. */ public static KEKRecipientInfo getInstance( Object obj) { if (obj == null || obj instanceof KEKRecipientInfo) { return (KEKRecipientInfo)obj; } if(obj instanceof ASN1Sequence) { return new KEKRecipientInfo((ASN1Sequence)obj); } throw new IllegalArgumentException("Invalid KEKRecipientInfo: " + obj.getClass().getName()); } public ASN1Integer getVersion() { return version; } public KEKIdentifier getKekid() { return kekid; } public AlgorithmIdentifier getKeyEncryptionAlgorithm() { return keyEncryptionAlgorithm; } public ASN1OctetString getEncryptedKey() { return encryptedKey; } /** * Produce an object suitable for an ASN1OutputStream. *
         * KEKRecipientInfo ::= SEQUENCE {
         *     version CMSVersion,  -- always set to 4
         *     kekid KEKIdentifier,
         *     keyEncryptionAlgorithm KeyEncryptionAlgorithmIdentifier,
         *     encryptedKey EncryptedKey 
         * }
         * 
    */ public ASN1Primitive toASN1Primitive() { ASN1EncodableVector v = new ASN1EncodableVector(); v.add(version); v.add(kekid); v.add(keyEncryptionAlgorithm); v.add(encryptedKey); return new DERSequence(v); } } bouncycastle-1.49.orig/src/org/bouncycastle/asn1/cms/AuthenticatedDataParser.java0000644000175000017500000001212411724561172027530 0ustar ebourgebourgpackage org.bouncycastle.asn1.cms; import java.io.IOException; import org.bouncycastle.asn1.ASN1Encodable; import org.bouncycastle.asn1.ASN1Integer; import org.bouncycastle.asn1.ASN1OctetString; import org.bouncycastle.asn1.ASN1SequenceParser; import org.bouncycastle.asn1.ASN1SetParser; import org.bouncycastle.asn1.ASN1TaggedObject; import org.bouncycastle.asn1.ASN1TaggedObjectParser; import org.bouncycastle.asn1.BERTags; import org.bouncycastle.asn1.x509.AlgorithmIdentifier; /** * Produce an object suitable for an ASN1OutputStream. *
     * AuthenticatedData ::= SEQUENCE {
     *       version CMSVersion,
     *       originatorInfo [0] IMPLICIT OriginatorInfo OPTIONAL,
     *       recipientInfos RecipientInfos,
     *       macAlgorithm MessageAuthenticationCodeAlgorithm,
     *       digestAlgorithm [1] DigestAlgorithmIdentifier OPTIONAL,
     *       encapContentInfo EncapsulatedContentInfo,
     *       authAttrs [2] IMPLICIT AuthAttributes OPTIONAL,
     *       mac MessageAuthenticationCode,
     *       unauthAttrs [3] IMPLICIT UnauthAttributes OPTIONAL }
     *
     * AuthAttributes ::= SET SIZE (1..MAX) OF Attribute
     *
     * UnauthAttributes ::= SET SIZE (1..MAX) OF Attribute
     *
     * MessageAuthenticationCode ::= OCTET STRING
     * 
    */ public class AuthenticatedDataParser { private ASN1SequenceParser seq; private ASN1Integer version; private ASN1Encodable nextObject; private boolean originatorInfoCalled; public AuthenticatedDataParser( ASN1SequenceParser seq) throws IOException { this.seq = seq; this.version = ASN1Integer.getInstance(seq.readObject()); } public ASN1Integer getVersion() { return version; } public OriginatorInfo getOriginatorInfo() throws IOException { originatorInfoCalled = true; if (nextObject == null) { nextObject = seq.readObject(); } if (nextObject instanceof ASN1TaggedObjectParser && ((ASN1TaggedObjectParser)nextObject).getTagNo() == 0) { ASN1SequenceParser originatorInfo = (ASN1SequenceParser) ((ASN1TaggedObjectParser)nextObject).getObjectParser(BERTags.SEQUENCE, false); nextObject = null; return OriginatorInfo.getInstance(originatorInfo.toASN1Primitive()); } return null; } public ASN1SetParser getRecipientInfos() throws IOException { if (!originatorInfoCalled) { getOriginatorInfo(); } if (nextObject == null) { nextObject = seq.readObject(); } ASN1SetParser recipientInfos = (ASN1SetParser)nextObject; nextObject = null; return recipientInfos; } public AlgorithmIdentifier getMacAlgorithm() throws IOException { if (nextObject == null) { nextObject = seq.readObject(); } if (nextObject != null) { ASN1SequenceParser o = (ASN1SequenceParser)nextObject; nextObject = null; return AlgorithmIdentifier.getInstance(o.toASN1Primitive()); } return null; } public AlgorithmIdentifier getDigestAlgorithm() throws IOException { if (nextObject == null) { nextObject = seq.readObject(); } if (nextObject instanceof ASN1TaggedObjectParser) { AlgorithmIdentifier obj = AlgorithmIdentifier.getInstance((ASN1TaggedObject)nextObject.toASN1Primitive(), false); nextObject = null; return obj; } return null; } public ContentInfoParser getEnapsulatedContentInfo() throws IOException { if (nextObject == null) { nextObject = seq.readObject(); } if (nextObject != null) { ASN1SequenceParser o = (ASN1SequenceParser)nextObject; nextObject = null; return new ContentInfoParser(o); } return null; } public ASN1SetParser getAuthAttrs() throws IOException { if (nextObject == null) { nextObject = seq.readObject(); } if (nextObject instanceof ASN1TaggedObjectParser) { ASN1Encodable o = nextObject; nextObject = null; return (ASN1SetParser)((ASN1TaggedObjectParser)o).getObjectParser(BERTags.SET, false); } return null; } public ASN1OctetString getMac() throws IOException { if (nextObject == null) { nextObject = seq.readObject(); } ASN1Encodable o = nextObject; nextObject = null; return ASN1OctetString.getInstance(o.toASN1Primitive()); } public ASN1SetParser getUnauthAttrs() throws IOException { if (nextObject == null) { nextObject = seq.readObject(); } if (nextObject != null) { ASN1Encodable o = nextObject; nextObject = null; return (ASN1SetParser)((ASN1TaggedObjectParser)o).getObjectParser(BERTags.SET, false); } return null; } } bouncycastle-1.49.orig/src/org/bouncycastle/asn1/cms/Time.java0000644000175000017500000000620711624626647023712 0ustar ebourgebourgpackage org.bouncycastle.asn1.cms; import java.text.ParseException; import java.text.SimpleDateFormat; import java.util.Date; import java.util.SimpleTimeZone; import org.bouncycastle.asn1.ASN1Choice; import org.bouncycastle.asn1.ASN1Object; import org.bouncycastle.asn1.ASN1Primitive; import org.bouncycastle.asn1.ASN1TaggedObject; import org.bouncycastle.asn1.DERGeneralizedTime; import org.bouncycastle.asn1.DERUTCTime; public class Time extends ASN1Object implements ASN1Choice { ASN1Primitive time; public static Time getInstance( ASN1TaggedObject obj, boolean explicit) { return getInstance(obj.getObject()); } public Time( ASN1Primitive time) { if (!(time instanceof DERUTCTime) && !(time instanceof DERGeneralizedTime)) { throw new IllegalArgumentException("unknown object passed to Time"); } this.time = time; } /** * creates a time object from a given date - if the date is between 1950 * and 2049 a UTCTime object is generated, otherwise a GeneralizedTime * is used. */ public Time( Date date) { SimpleTimeZone tz = new SimpleTimeZone(0, "Z"); SimpleDateFormat dateF = new SimpleDateFormat("yyyyMMddHHmmss"); dateF.setTimeZone(tz); String d = dateF.format(date) + "Z"; int year = Integer.parseInt(d.substring(0, 4)); if (year < 1950 || year > 2049) { time = new DERGeneralizedTime(d); } else { time = new DERUTCTime(d.substring(2)); } } public static Time getInstance( Object obj) { if (obj == null || obj instanceof Time) { return (Time)obj; } else if (obj instanceof DERUTCTime) { return new Time((DERUTCTime)obj); } else if (obj instanceof DERGeneralizedTime) { return new Time((DERGeneralizedTime)obj); } throw new IllegalArgumentException("unknown object in factory: " + obj.getClass().getName()); } public String getTime() { if (time instanceof DERUTCTime) { return ((DERUTCTime)time).getAdjustedTime(); } else { return ((DERGeneralizedTime)time).getTime(); } } public Date getDate() { try { if (time instanceof DERUTCTime) { return ((DERUTCTime)time).getAdjustedDate(); } else { return ((DERGeneralizedTime)time).getDate(); } } catch (ParseException e) { // this should never happen throw new IllegalStateException("invalid date string: " + e.getMessage()); } } /** * Produce an object suitable for an ASN1OutputStream. *
         * Time ::= CHOICE {
         *             utcTime        UTCTime,
         *             generalTime    GeneralizedTime }
         * 
    */ public ASN1Primitive toASN1Primitive() { return time; } } bouncycastle-1.49.orig/src/org/bouncycastle/asn1/cms/MetaData.java0000644000175000017500000000555211737275254024475 0ustar ebourgebourgpackage org.bouncycastle.asn1.cms; import org.bouncycastle.asn1.ASN1Boolean; import org.bouncycastle.asn1.ASN1EncodableVector; import org.bouncycastle.asn1.ASN1Object; import org.bouncycastle.asn1.ASN1Primitive; import org.bouncycastle.asn1.ASN1Sequence; import org.bouncycastle.asn1.DERIA5String; import org.bouncycastle.asn1.DERSequence; import org.bouncycastle.asn1.DERUTF8String; public class MetaData extends ASN1Object { private ASN1Boolean hashProtected; private DERUTF8String fileName; private DERIA5String mediaType; private Attributes otherMetaData; public MetaData( ASN1Boolean hashProtected, DERUTF8String fileName, DERIA5String mediaType, Attributes otherMetaData) { this.hashProtected = hashProtected; this.fileName = fileName; this.mediaType = mediaType; this.otherMetaData = otherMetaData; } private MetaData(ASN1Sequence seq) { this.hashProtected = ASN1Boolean.getInstance(seq.getObjectAt(0)); int index = 1; if (index < seq.size() && seq.getObjectAt(index) instanceof DERUTF8String) { this.fileName = DERUTF8String.getInstance(seq.getObjectAt(index++)); } if (index < seq.size() && seq.getObjectAt(index) instanceof DERIA5String) { this.mediaType = DERIA5String.getInstance(seq.getObjectAt(index++)); } if (index < seq.size()) { this.otherMetaData = Attributes.getInstance(seq.getObjectAt(index++)); } } public static MetaData getInstance(Object obj) { if (obj instanceof MetaData) { return (MetaData)obj; } else if (obj != null) { return new MetaData(ASN1Sequence.getInstance(obj)); } return null; } /** *
         * MetaData ::= SEQUENCE {
         *   hashProtected        BOOLEAN,
         *   fileName             UTF8String OPTIONAL,
         *   mediaType            IA5String OPTIONAL,
         *   otherMetaData        Attributes OPTIONAL
         * }
         * 
    * @return */ public ASN1Primitive toASN1Primitive() { ASN1EncodableVector v = new ASN1EncodableVector(); v.add(hashProtected); if (fileName != null) { v.add(fileName); } if (mediaType != null) { v.add(mediaType); } if (otherMetaData != null) { v.add(otherMetaData); } return new DERSequence(v); } public boolean isHashProtected() { return hashProtected.isTrue(); } public DERUTF8String getFileName() { return this.fileName; } public DERIA5String getMediaType() { return this.mediaType; } public Attributes getOtherMetaData() { return otherMetaData; } } bouncycastle-1.49.orig/src/org/bouncycastle/asn1/cms/package.html0000644000175000017500000000027110262753174024416 0ustar ebourgebourg Support classes useful for encoding and supporting Cryptographic Message Syntax as described in PKCS#7 and RFC 3369 (formerly RFC 2630). bouncycastle-1.49.orig/src/org/bouncycastle/asn1/cms/TimeStampedData.java0000644000175000017500000000605611724561173026015 0ustar ebourgebourgpackage org.bouncycastle.asn1.cms; import org.bouncycastle.asn1.ASN1EncodableVector; import org.bouncycastle.asn1.ASN1Integer; import org.bouncycastle.asn1.ASN1Object; import org.bouncycastle.asn1.ASN1OctetString; import org.bouncycastle.asn1.ASN1Primitive; import org.bouncycastle.asn1.ASN1Sequence; import org.bouncycastle.asn1.BERSequence; import org.bouncycastle.asn1.DERIA5String; public class TimeStampedData extends ASN1Object { private ASN1Integer version; private DERIA5String dataUri; private MetaData metaData; private ASN1OctetString content; private Evidence temporalEvidence; public TimeStampedData(DERIA5String dataUri, MetaData metaData, ASN1OctetString content, Evidence temporalEvidence) { this.version = new ASN1Integer(1); this.dataUri = dataUri; this.metaData = metaData; this.content = content; this.temporalEvidence = temporalEvidence; } private TimeStampedData(ASN1Sequence seq) { this.version = ASN1Integer.getInstance(seq.getObjectAt(0)); int index = 1; if (seq.getObjectAt(index) instanceof DERIA5String) { this.dataUri = DERIA5String.getInstance(seq.getObjectAt(index++)); } if (seq.getObjectAt(index) instanceof MetaData || seq.getObjectAt(index) instanceof ASN1Sequence) { this.metaData = MetaData.getInstance(seq.getObjectAt(index++)); } if (seq.getObjectAt(index) instanceof ASN1OctetString) { this.content = ASN1OctetString.getInstance(seq.getObjectAt(index++)); } this.temporalEvidence = Evidence.getInstance(seq.getObjectAt(index)); } public static TimeStampedData getInstance(Object obj) { if (obj instanceof TimeStampedData) { return (TimeStampedData)obj; } else if (obj != null) { return new TimeStampedData(ASN1Sequence.getInstance(obj)); } return null; } public DERIA5String getDataUri() { return dataUri; } public MetaData getMetaData() { return metaData; } public ASN1OctetString getContent() { return content; } public Evidence getTemporalEvidence() { return temporalEvidence; } /** *
         * TimeStampedData ::= SEQUENCE {
         *   version              INTEGER { v1(1) },
         *   dataUri              IA5String OPTIONAL,
         *   metaData             MetaData OPTIONAL,
         *   content              OCTET STRING OPTIONAL,
         *   temporalEvidence     Evidence
         * }
         * 
    * @return */ public ASN1Primitive toASN1Primitive() { ASN1EncodableVector v = new ASN1EncodableVector(); v.add(version); if (dataUri != null) { v.add(dataUri); } if (metaData != null) { v.add(metaData); } if (content != null) { v.add(content); } v.add(temporalEvidence); return new BERSequence(v); } } bouncycastle-1.49.orig/src/org/bouncycastle/asn1/iana/0000755000175000017500000000000012152033551022251 5ustar ebourgebourgbouncycastle-1.49.orig/src/org/bouncycastle/asn1/iana/IANAObjectIdentifiers.java0000644000175000017500000000146711624622714027161 0ustar ebourgebourgpackage org.bouncycastle.asn1.iana; import org.bouncycastle.asn1.ASN1ObjectIdentifier; public interface IANAObjectIdentifiers { // id-SHA1 OBJECT IDENTIFIER ::= // {iso(1) identified-organization(3) dod(6) internet(1) security(5) mechanisms(5) ipsec(8) isakmpOakley(1)} // static final ASN1ObjectIdentifier isakmpOakley = new ASN1ObjectIdentifier("1.3.6.1.5.5.8.1"); static final ASN1ObjectIdentifier hmacMD5 = new ASN1ObjectIdentifier(isakmpOakley + ".1"); static final ASN1ObjectIdentifier hmacSHA1 = new ASN1ObjectIdentifier(isakmpOakley + ".2"); static final ASN1ObjectIdentifier hmacTIGER = new ASN1ObjectIdentifier(isakmpOakley + ".3"); static final ASN1ObjectIdentifier hmacRIPEMD160 = new ASN1ObjectIdentifier(isakmpOakley + ".4"); } bouncycastle-1.49.orig/src/org/bouncycastle/asn1/tsp/0000755000175000017500000000000012152033551022147 5ustar ebourgebourgbouncycastle-1.49.orig/src/org/bouncycastle/asn1/tsp/MessageImprint.java0000644000175000017500000000371411624652555025764 0ustar ebourgebourgpackage org.bouncycastle.asn1.tsp; import org.bouncycastle.asn1.ASN1EncodableVector; import org.bouncycastle.asn1.ASN1Object; import org.bouncycastle.asn1.ASN1OctetString; import org.bouncycastle.asn1.ASN1Primitive; import org.bouncycastle.asn1.ASN1Sequence; import org.bouncycastle.asn1.DEROctetString; import org.bouncycastle.asn1.DERSequence; import org.bouncycastle.asn1.x509.AlgorithmIdentifier; public class MessageImprint extends ASN1Object { AlgorithmIdentifier hashAlgorithm; byte[] hashedMessage; /** * @param o * @return a MessageImprint object. */ public static MessageImprint getInstance(Object o) { if (o instanceof MessageImprint) { return (MessageImprint)o; } if (o != null) { return new MessageImprint(ASN1Sequence.getInstance(o)); } return null; } private MessageImprint( ASN1Sequence seq) { this.hashAlgorithm = AlgorithmIdentifier.getInstance(seq.getObjectAt(0)); this.hashedMessage = ASN1OctetString.getInstance(seq.getObjectAt(1)).getOctets(); } public MessageImprint( AlgorithmIdentifier hashAlgorithm, byte[] hashedMessage) { this.hashAlgorithm = hashAlgorithm; this.hashedMessage = hashedMessage; } public AlgorithmIdentifier getHashAlgorithm() { return hashAlgorithm; } public byte[] getHashedMessage() { return hashedMessage; } /** *
         *    MessageImprint ::= SEQUENCE  {
         *       hashAlgorithm                AlgorithmIdentifier,
         *       hashedMessage                OCTET STRING  }
         * 
    */ public ASN1Primitive toASN1Primitive() { ASN1EncodableVector v = new ASN1EncodableVector(); v.add(hashAlgorithm); v.add(new DEROctetString(hashedMessage)); return new DERSequence(v); } } bouncycastle-1.49.orig/src/org/bouncycastle/asn1/tsp/TSTInfo.java0000644000175000017500000001446111724561172024317 0ustar ebourgebourgpackage org.bouncycastle.asn1.tsp; import java.util.Enumeration; import org.bouncycastle.asn1.ASN1Boolean; import org.bouncycastle.asn1.ASN1EncodableVector; import org.bouncycastle.asn1.ASN1GeneralizedTime; import org.bouncycastle.asn1.ASN1Integer; import org.bouncycastle.asn1.ASN1Object; import org.bouncycastle.asn1.ASN1ObjectIdentifier; import org.bouncycastle.asn1.ASN1Primitive; import org.bouncycastle.asn1.ASN1Sequence; import org.bouncycastle.asn1.ASN1TaggedObject; import org.bouncycastle.asn1.DERSequence; import org.bouncycastle.asn1.DERTaggedObject; import org.bouncycastle.asn1.x509.Extensions; import org.bouncycastle.asn1.x509.GeneralName; public class TSTInfo extends ASN1Object { private ASN1Integer version; private ASN1ObjectIdentifier tsaPolicyId; private MessageImprint messageImprint; private ASN1Integer serialNumber; private ASN1GeneralizedTime genTime; private Accuracy accuracy; private ASN1Boolean ordering; private ASN1Integer nonce; private GeneralName tsa; private Extensions extensions; public static TSTInfo getInstance(Object o) { if (o instanceof TSTInfo) { return (TSTInfo)o; } else if (o != null) { return new TSTInfo(ASN1Sequence.getInstance(o)); } return null; } private TSTInfo(ASN1Sequence seq) { Enumeration e = seq.getObjects(); // version version = ASN1Integer.getInstance(e.nextElement()); // tsaPolicy tsaPolicyId = ASN1ObjectIdentifier.getInstance(e.nextElement()); // messageImprint messageImprint = MessageImprint.getInstance(e.nextElement()); // serialNumber serialNumber = ASN1Integer.getInstance(e.nextElement()); // genTime genTime = ASN1GeneralizedTime.getInstance(e.nextElement()); // default for ordering ordering = ASN1Boolean.getInstance(false); while (e.hasMoreElements()) { ASN1Object o = (ASN1Object) e.nextElement(); if (o instanceof ASN1TaggedObject) { DERTaggedObject tagged = (DERTaggedObject) o; switch (tagged.getTagNo()) { case 0: tsa = GeneralName.getInstance(tagged, true); break; case 1: extensions = Extensions.getInstance(tagged, false); break; default: throw new IllegalArgumentException("Unknown tag value " + tagged.getTagNo()); } } else if (o instanceof ASN1Sequence || o instanceof Accuracy) { accuracy = Accuracy.getInstance(o); } else if (o instanceof ASN1Boolean) { ordering = ASN1Boolean.getInstance(o); } else if (o instanceof ASN1Integer) { nonce = ASN1Integer.getInstance(o); } } } public TSTInfo(ASN1ObjectIdentifier tsaPolicyId, MessageImprint messageImprint, ASN1Integer serialNumber, ASN1GeneralizedTime genTime, Accuracy accuracy, ASN1Boolean ordering, ASN1Integer nonce, GeneralName tsa, Extensions extensions) { version = new ASN1Integer(1); this.tsaPolicyId = tsaPolicyId; this.messageImprint = messageImprint; this.serialNumber = serialNumber; this.genTime = genTime; this.accuracy = accuracy; this.ordering = ordering; this.nonce = nonce; this.tsa = tsa; this.extensions = extensions; } public ASN1Integer getVersion() { return version; } public MessageImprint getMessageImprint() { return messageImprint; } public ASN1ObjectIdentifier getPolicy() { return tsaPolicyId; } public ASN1Integer getSerialNumber() { return serialNumber; } public Accuracy getAccuracy() { return accuracy; } public ASN1GeneralizedTime getGenTime() { return genTime; } public ASN1Boolean getOrdering() { return ordering; } public ASN1Integer getNonce() { return nonce; } public GeneralName getTsa() { return tsa; } public Extensions getExtensions() { return extensions; } /** *
         * 
         *     TSTInfo ::= SEQUENCE  {
         *        version                      INTEGER  { v1(1) },
         *        policy                       TSAPolicyId,
         *        messageImprint               MessageImprint,
         *          -- MUST have the same value as the similar field in
         *          -- TimeStampReq
         *        serialNumber                 INTEGER,
         *         -- Time-Stamping users MUST be ready to accommodate integers
         *         -- up to 160 bits.
         *        genTime                      GeneralizedTime,
         *        accuracy                     Accuracy                 OPTIONAL,
         *        ordering                     BOOLEAN             DEFAULT FALSE,
         *        nonce                        INTEGER                  OPTIONAL,
         *          -- MUST be present if the similar field was present
         *          -- in TimeStampReq.  In that case it MUST have the same value.
         *        tsa                          [0] GeneralName          OPTIONAL,
         *        extensions                   [1] IMPLICIT Extensions   OPTIONAL  }
         * 
         * 
    */ public ASN1Primitive toASN1Primitive() { ASN1EncodableVector seq = new ASN1EncodableVector(); seq.add(version); seq.add(tsaPolicyId); seq.add(messageImprint); seq.add(serialNumber); seq.add(genTime); if (accuracy != null) { seq.add(accuracy); } if (ordering != null && ordering.isTrue()) { seq.add(ordering); } if (nonce != null) { seq.add(nonce); } if (tsa != null) { seq.add(new DERTaggedObject(true, 0, tsa)); } if (extensions != null) { seq.add(new DERTaggedObject(false, 1, extensions)); } return new DERSequence(seq); } } bouncycastle-1.49.orig/src/org/bouncycastle/asn1/tsp/Accuracy.java0000644000175000017500000001055411624652555024567 0ustar ebourgebourgpackage org.bouncycastle.asn1.tsp; import org.bouncycastle.asn1.ASN1EncodableVector; import org.bouncycastle.asn1.ASN1Integer; import org.bouncycastle.asn1.ASN1Object; import org.bouncycastle.asn1.ASN1Primitive; import org.bouncycastle.asn1.ASN1Sequence; import org.bouncycastle.asn1.DERSequence; import org.bouncycastle.asn1.DERTaggedObject; public class Accuracy extends ASN1Object { ASN1Integer seconds; ASN1Integer millis; ASN1Integer micros; // constantes protected static final int MIN_MILLIS = 1; protected static final int MAX_MILLIS = 999; protected static final int MIN_MICROS = 1; protected static final int MAX_MICROS = 999; protected Accuracy() { } public Accuracy( ASN1Integer seconds, ASN1Integer millis, ASN1Integer micros) { this.seconds = seconds; //Verifications if (millis != null && (millis.getValue().intValue() < MIN_MILLIS || millis .getValue().intValue() > MAX_MILLIS)) { throw new IllegalArgumentException( "Invalid millis field : not in (1..999)"); } else { this.millis = millis; } if (micros != null && (micros.getValue().intValue() < MIN_MICROS || micros .getValue().intValue() > MAX_MICROS)) { throw new IllegalArgumentException( "Invalid micros field : not in (1..999)"); } else { this.micros = micros; } } private Accuracy(ASN1Sequence seq) { seconds = null; millis = null; micros = null; for (int i = 0; i < seq.size(); i++) { // seconds if (seq.getObjectAt(i) instanceof ASN1Integer) { seconds = (ASN1Integer) seq.getObjectAt(i); } else if (seq.getObjectAt(i) instanceof DERTaggedObject) { DERTaggedObject extra = (DERTaggedObject) seq.getObjectAt(i); switch (extra.getTagNo()) { case 0: millis = ASN1Integer.getInstance(extra, false); if (millis.getValue().intValue() < MIN_MILLIS || millis.getValue().intValue() > MAX_MILLIS) { throw new IllegalArgumentException( "Invalid millis field : not in (1..999)."); } break; case 1: micros = ASN1Integer.getInstance(extra, false); if (micros.getValue().intValue() < MIN_MICROS || micros.getValue().intValue() > MAX_MICROS) { throw new IllegalArgumentException( "Invalid micros field : not in (1..999)."); } break; default: throw new IllegalArgumentException("Invalig tag number"); } } } } public static Accuracy getInstance(Object o) { if (o instanceof Accuracy) { return (Accuracy) o; } if (o != null) { return new Accuracy(ASN1Sequence.getInstance(o)); } return null; } public ASN1Integer getSeconds() { return seconds; } public ASN1Integer getMillis() { return millis; } public ASN1Integer getMicros() { return micros; } /** *
         * Accuracy ::= SEQUENCE {
         *             seconds        INTEGER              OPTIONAL,
         *             millis     [0] INTEGER  (1..999)    OPTIONAL,
         *             micros     [1] INTEGER  (1..999)    OPTIONAL
         *             }
         * 
    */ public ASN1Primitive toASN1Primitive() { ASN1EncodableVector v = new ASN1EncodableVector(); if (seconds != null) { v.add(seconds); } if (millis != null) { v.add(new DERTaggedObject(false, 0, millis)); } if (micros != null) { v.add(new DERTaggedObject(false, 1, micros)); } return new DERSequence(v); } } bouncycastle-1.49.orig/src/org/bouncycastle/asn1/tsp/TimeStampReq.java0000644000175000017500000001070711737006562025404 0ustar ebourgebourgpackage org.bouncycastle.asn1.tsp; import org.bouncycastle.asn1.ASN1Boolean; import org.bouncycastle.asn1.ASN1EncodableVector; import org.bouncycastle.asn1.ASN1Integer; import org.bouncycastle.asn1.ASN1Object; import org.bouncycastle.asn1.ASN1ObjectIdentifier; import org.bouncycastle.asn1.ASN1Primitive; import org.bouncycastle.asn1.ASN1Sequence; import org.bouncycastle.asn1.ASN1TaggedObject; import org.bouncycastle.asn1.DERSequence; import org.bouncycastle.asn1.DERTaggedObject; import org.bouncycastle.asn1.x509.Extensions; public class TimeStampReq extends ASN1Object { ASN1Integer version; MessageImprint messageImprint; ASN1ObjectIdentifier tsaPolicy; ASN1Integer nonce; ASN1Boolean certReq; Extensions extensions; public static TimeStampReq getInstance(Object o) { if (o instanceof TimeStampReq) { return (TimeStampReq) o; } else if (o != null) { return new TimeStampReq(ASN1Sequence.getInstance(o)); } return null; } private TimeStampReq(ASN1Sequence seq) { int nbObjects = seq.size(); int seqStart = 0; // version version = ASN1Integer.getInstance(seq.getObjectAt(seqStart)); seqStart++; // messageImprint messageImprint = MessageImprint.getInstance(seq.getObjectAt(seqStart)); seqStart++; for (int opt = seqStart; opt < nbObjects; opt++) { // tsaPolicy if (seq.getObjectAt(opt) instanceof ASN1ObjectIdentifier) { tsaPolicy = ASN1ObjectIdentifier.getInstance(seq.getObjectAt(opt)); } // nonce else if (seq.getObjectAt(opt) instanceof ASN1Integer) { nonce = ASN1Integer.getInstance(seq.getObjectAt(opt)); } // certReq else if (seq.getObjectAt(opt) instanceof ASN1Boolean) { certReq = ASN1Boolean.getInstance(seq.getObjectAt(opt)); } // extensions else if (seq.getObjectAt(opt) instanceof ASN1TaggedObject) { ASN1TaggedObject tagged = (ASN1TaggedObject)seq.getObjectAt(opt); if (tagged.getTagNo() == 0) { extensions = Extensions.getInstance(tagged, false); } } } } public TimeStampReq( MessageImprint messageImprint, ASN1ObjectIdentifier tsaPolicy, ASN1Integer nonce, ASN1Boolean certReq, Extensions extensions) { // default version = new ASN1Integer(1); this.messageImprint = messageImprint; this.tsaPolicy = tsaPolicy; this.nonce = nonce; this.certReq = certReq; this.extensions = extensions; } public ASN1Integer getVersion() { return version; } public MessageImprint getMessageImprint() { return messageImprint; } public ASN1ObjectIdentifier getReqPolicy() { return tsaPolicy; } public ASN1Integer getNonce() { return nonce; } public ASN1Boolean getCertReq() { return certReq; } public Extensions getExtensions() { return extensions; } /** *
         * TimeStampReq ::= SEQUENCE  {
         *  version                      INTEGER  { v1(1) },
         *  messageImprint               MessageImprint,
         *    --a hash algorithm OID and the hash value of the data to be
         *    --time-stamped
         *  reqPolicy             TSAPolicyId              OPTIONAL,
         *  nonce                 INTEGER                  OPTIONAL,
         *  certReq               BOOLEAN                  DEFAULT FALSE,
         *  extensions            [0] IMPLICIT Extensions  OPTIONAL
         * }
         * 
    */ public ASN1Primitive toASN1Primitive() { ASN1EncodableVector v = new ASN1EncodableVector(); v.add(version); v.add(messageImprint); if (tsaPolicy != null) { v.add(tsaPolicy); } if (nonce != null) { v.add(nonce); } if (certReq != null && certReq.isTrue()) { v.add(certReq); } if (extensions != null) { v.add(new DERTaggedObject(false, 0, extensions)); } return new DERSequence(v); } } bouncycastle-1.49.orig/src/org/bouncycastle/asn1/tsp/TimeStampResp.java0000644000175000017500000000362611725240230025555 0ustar ebourgebourgpackage org.bouncycastle.asn1.tsp; import java.util.Enumeration; import org.bouncycastle.asn1.ASN1EncodableVector; import org.bouncycastle.asn1.ASN1Object; import org.bouncycastle.asn1.ASN1Primitive; import org.bouncycastle.asn1.ASN1Sequence; import org.bouncycastle.asn1.DERSequence; import org.bouncycastle.asn1.cmp.PKIStatusInfo; import org.bouncycastle.asn1.cms.ContentInfo; public class TimeStampResp extends ASN1Object { PKIStatusInfo pkiStatusInfo; ContentInfo timeStampToken; public static TimeStampResp getInstance(Object o) { if (o instanceof TimeStampResp) { return (TimeStampResp) o; } else if (o != null) { return new TimeStampResp(ASN1Sequence.getInstance(o)); } return null; } private TimeStampResp(ASN1Sequence seq) { Enumeration e = seq.getObjects(); // status pkiStatusInfo = PKIStatusInfo.getInstance(e.nextElement()); if (e.hasMoreElements()) { timeStampToken = ContentInfo.getInstance(e.nextElement()); } } public TimeStampResp(PKIStatusInfo pkiStatusInfo, ContentInfo timeStampToken) { this.pkiStatusInfo = pkiStatusInfo; this.timeStampToken = timeStampToken; } public PKIStatusInfo getStatus() { return pkiStatusInfo; } public ContentInfo getTimeStampToken() { return timeStampToken; } /** *
         * TimeStampResp ::= SEQUENCE  {
         *   status                  PKIStatusInfo,
         *   timeStampToken          TimeStampToken     OPTIONAL  }
         * 
    */ public ASN1Primitive toASN1Primitive() { ASN1EncodableVector v = new ASN1EncodableVector(); v.add(pkiStatusInfo); if (timeStampToken != null) { v.add(timeStampToken); } return new DERSequence(v); } } bouncycastle-1.49.orig/src/org/bouncycastle/asn1/tsp/package.html0000644000175000017500000000021610262753175024442 0ustar ebourgebourg Support classes useful for encoding and supporting Time Stamp Protocol as described RFC 3161. bouncycastle-1.49.orig/src/org/bouncycastle/asn1/BERGenerator.java0000644000175000017500000000375011624615370024500 0ustar ebourgebourgpackage org.bouncycastle.asn1; import java.io.IOException; import java.io.InputStream; import java.io.OutputStream; public class BERGenerator extends ASN1Generator { private boolean _tagged = false; private boolean _isExplicit; private int _tagNo; protected BERGenerator( OutputStream out) { super(out); } public BERGenerator( OutputStream out, int tagNo, boolean isExplicit) { super(out); _tagged = true; _isExplicit = isExplicit; _tagNo = tagNo; } public OutputStream getRawOutputStream() { return _out; } private void writeHdr( int tag) throws IOException { _out.write(tag); _out.write(0x80); } protected void writeBERHeader( int tag) throws IOException { if (_tagged) { int tagNum = _tagNo | BERTags.TAGGED; if (_isExplicit) { writeHdr(tagNum | BERTags.CONSTRUCTED); writeHdr(tag); } else { if ((tag & BERTags.CONSTRUCTED) != 0) { writeHdr(tagNum | BERTags.CONSTRUCTED); } else { writeHdr(tagNum); } } } else { writeHdr(tag); } } protected void writeBERBody( InputStream contentStream) throws IOException { int ch; while ((ch = contentStream.read()) >= 0) { _out.write(ch); } } protected void writeBEREnd() throws IOException { _out.write(0x00); _out.write(0x00); if (_tagged && _isExplicit) // write extra end for tag header { _out.write(0x00); _out.write(0x00); } } } bouncycastle-1.49.orig/src/org/bouncycastle/asn1/eac/0000755000175000017500000000000012152033551022071 5ustar ebourgebourgbouncycastle-1.49.orig/src/org/bouncycastle/asn1/eac/CertificateHolderAuthorization.java0000644000175000017500000001275112151251423031102 0ustar ebourgebourgpackage org.bouncycastle.asn1.eac; import java.io.IOException; import java.util.Hashtable; import org.bouncycastle.asn1.ASN1EncodableVector; import org.bouncycastle.asn1.ASN1InputStream; import org.bouncycastle.asn1.ASN1Object; import org.bouncycastle.asn1.ASN1ObjectIdentifier; import org.bouncycastle.asn1.ASN1Primitive; import org.bouncycastle.asn1.DERApplicationSpecific; import org.bouncycastle.util.Integers; /** * an Iso7816CertificateHolderAuthorization structure. *

    *

     *  Certificate Holder Authorization ::= SEQUENCE {
     *      // specifies the format and the rules for the evaluation of the authorization
     *      // level
     *      ASN1ObjectIdentifier        oid,
     *      // access rights
     *      DERApplicationSpecific    accessRights,
     *  }
     * 
    */ public class CertificateHolderAuthorization extends ASN1Object { ASN1ObjectIdentifier oid; DERApplicationSpecific accessRights; public static final ASN1ObjectIdentifier id_role_EAC = EACObjectIdentifiers.bsi_de.branch("3.1.2.1"); public static final int CVCA = 0xC0; public static final int DV_DOMESTIC = 0x80; public static final int DV_FOREIGN = 0x40; public static final int IS = 0; public static final int RADG4 = 0x02;//Read Access to DG4 (Iris) public static final int RADG3 = 0x01;//Read Access to DG3 (fingerprint) static Hashtable RightsDecodeMap = new Hashtable(); static BidirectionalMap AuthorizationRole = new BidirectionalMap(); static Hashtable ReverseMap = new Hashtable(); static { RightsDecodeMap.put(Integers.valueOf(RADG4), "RADG4"); RightsDecodeMap.put(Integers.valueOf(RADG3), "RADG3"); AuthorizationRole.put(Integers.valueOf(CVCA), "CVCA"); AuthorizationRole.put(Integers.valueOf(DV_DOMESTIC), "DV_DOMESTIC"); AuthorizationRole.put(Integers.valueOf(DV_FOREIGN), "DV_FOREIGN"); AuthorizationRole.put(Integers.valueOf(IS), "IS"); /* for (int i : RightsDecodeMap.keySet()) ReverseMap.put(RightsDecodeMap.get(i), i); for (int i : AuthorizationRole.keySet()) ReverseMap.put(AuthorizationRole.get(i), i); */ } public static String GetRoleDescription(int i) { return (String)AuthorizationRole.get(Integers.valueOf(i)); } public static int GetFlag(String description) { Integer i = (Integer)AuthorizationRole.getReverse(description); if (i == null) { throw new IllegalArgumentException("Unknown value " + description); } return i.intValue(); } private void setPrivateData(ASN1InputStream cha) throws IOException { ASN1Primitive obj; obj = cha.readObject(); if (obj instanceof ASN1ObjectIdentifier) { this.oid = (ASN1ObjectIdentifier)obj; } else { throw new IllegalArgumentException("no Oid in CerticateHolderAuthorization"); } obj = cha.readObject(); if (obj instanceof DERApplicationSpecific) { this.accessRights = (DERApplicationSpecific)obj; } else { throw new IllegalArgumentException("No access rights in CerticateHolderAuthorization"); } } /** * create an Iso7816CertificateHolderAuthorization according to the parameters * * @param oid Object Identifier : specifies the format and the rules for the * evaluatioin of the authorization level. * @param rights specifies the access rights * @throws IOException */ public CertificateHolderAuthorization(ASN1ObjectIdentifier oid, int rights) throws IOException { setOid(oid); setAccessRights((byte)rights); } /** * create an Iso7816CertificateHolderAuthorization according to the {@link DERApplicationSpecific} * * @param aSpe the DERApplicationSpecific containing the data * @throws IOException */ public CertificateHolderAuthorization(DERApplicationSpecific aSpe) throws IOException { if (aSpe.getApplicationTag() == EACTags.CERTIFICATE_HOLDER_AUTHORIZATION_TEMPLATE) { setPrivateData(new ASN1InputStream(aSpe.getContents())); } } /** * @return containing the access rights */ public int getAccessRights() { return accessRights.getContents()[0] & 0xff; } /** * create a DERApplicationSpecific and set the access rights to "rights" * * @param rights byte containing the rights. */ private void setAccessRights(byte rights) { byte[] accessRights = new byte[1]; accessRights[0] = rights; this.accessRights = new DERApplicationSpecific( EACTags.getTag(EACTags.DISCRETIONARY_DATA), accessRights); } /** * @return the Object identifier */ public ASN1ObjectIdentifier getOid() { return oid; } /** * set the Object Identifier * * @param oid {@link ASN1ObjectIdentifier} containing the Object Identifier */ private void setOid(ASN1ObjectIdentifier oid) { this.oid = oid; } /** * return the Certificate Holder Authorization as a DERApplicationSpecific Object */ public ASN1Primitive toASN1Primitive() { ASN1EncodableVector v = new ASN1EncodableVector(); v.add(oid); v.add(accessRights); return new DERApplicationSpecific(EACTags.CERTIFICATE_HOLDER_AUTHORIZATION_TEMPLATE, v); } } bouncycastle-1.49.orig/src/org/bouncycastle/asn1/eac/EACTags.java0000644000175000017500000002117212151253000024136 0ustar ebourgebourgpackage org.bouncycastle.asn1.eac; import org.bouncycastle.asn1.BERTags; import org.bouncycastle.asn1.DERApplicationSpecific; public class EACTags { public static final int OBJECT_IDENTIFIER = 0x06; public static final int COUNTRY_CODE_NATIONAL_DATA = 0x41; public static final int ISSUER_IDENTIFICATION_NUMBER = 0x02; //0x42; public static final int CARD_SERVICE_DATA = 0x43; public static final int INITIAL_ACCESS_DATA = 0x44; public static final int CARD_ISSUER_DATA = 0x45; public static final int PRE_ISSUING_DATA = 0x46; public static final int CARD_CAPABILITIES = 0x47; public static final int STATUS_INFORMATION = 0x48; public static final int EXTENDED_HEADER_LIST = 0x4D; public static final int APPLICATION_IDENTIFIER = 0x4F; public static final int APPLICATION_LABEL = 0x50; public static final int FILE_REFERENCE = 0x51; public static final int COMMAND_TO_PERFORM = 0x52; public static final int DISCRETIONARY_DATA = 0x53; public static final int OFFSET_DATA_OBJECT = 0x54; public static final int TRACK1_APPLICATION = 0x56; public static final int TRACK2_APPLICATION = 0x57; public static final int TRACK3_APPLICATION = 0x58; public static final int CARD_EXPIRATION_DATA = 0x59; public static final int PRIMARY_ACCOUNT_NUMBER = 0x5A;// PAN public static final int NAME = 0x5B; public static final int TAG_LIST = 0x5C; public static final int HEADER_LIST = 0x5D; public static final int LOGIN_DATA = 0x5E; public static final int CARDHOLDER_NAME = 0x20; // 0x5F20; public static final int TRACK1_CARD = 0x5F21; public static final int TRACK2_CARD = 0x5F22; public static final int TRACK3_CARD = 0x5F23; public static final int APPLICATION_EXPIRATION_DATE = 0x24; // 0x5F24; public static final int APPLICATION_EFFECTIVE_DATE = 0x25; // 0x5F25; public static final int CARD_EFFECTIVE_DATE = 0x5F26; public static final int INTERCHANGE_CONTROL = 0x5F27; public static final int COUNTRY_CODE = 0x5F28; public static final int INTERCHANGE_PROFILE = 0x29; // 0x5F29; public static final int CURRENCY_CODE = 0x5F2A; public static final int DATE_OF_BIRTH = 0x5F2B; public static final int CARDHOLDER_NATIONALITY = 0x5F2C; public static final int LANGUAGE_PREFERENCES = 0x5F2D; public static final int CARDHOLDER_BIOMETRIC_DATA = 0x5F2E; public static final int PIN_USAGE_POLICY = 0x5F2F; public static final int SERVICE_CODE = 0x5F30; public static final int TRANSACTION_COUNTER = 0x5F32; public static final int TRANSACTION_DATE = 0x5F33; public static final int CARD_SEQUENCE_NUMBER = 0x5F34; public static final int SEX = 0x5F35; public static final int CURRENCY_EXPONENT = 0x5F36; public static final int STATIC_INTERNAL_AUTHENTIFICATION_ONE_STEP = 0x37; // 0x5F37; public static final int SIGNATURE = 0x5F37; public static final int STATIC_INTERNAL_AUTHENTIFICATION_FIRST_DATA = 0x5F38; public static final int STATIC_INTERNAL_AUTHENTIFICATION_SECOND_DATA = 0x5F39; public static final int DYNAMIC_INTERNAL_AUTHENTIFICATION = 0x5F3A; public static final int DYNAMIC_EXTERNAL_AUTHENTIFICATION = 0x5F3B; public static final int DYNAMIC_MUTUAL_AUTHENTIFICATION = 0x5F3C; public static final int CARDHOLDER_PORTRAIT_IMAGE = 0x5F40; public static final int ELEMENT_LIST = 0x5F41; public static final int ADDRESS = 0x5F42; public static final int CARDHOLDER_HANDWRITTEN_SIGNATURE = 0x5F43; public static final int APPLICATION_IMAGE = 0x5F44; public static final int DISPLAY_IMAGE = 0x5F45; public static final int TIMER = 0x5F46; public static final int MESSAGE_REFERENCE = 0x5F47; public static final int CARDHOLDER_PRIVATE_KEY = 0x5F48; public static final int CARDHOLDER_PUBLIC_KEY = 0x5F49; public static final int CERTIFICATION_AUTHORITY_PUBLIC_KEY = 0x5F4A; public static final int DEPRECATED = 0x5F4B; public static final int CERTIFICATE_HOLDER_AUTHORIZATION = 0x5F4C;// Not yet defined in iso7816. The allocation is requested public static final int INTEGRATED_CIRCUIT_MANUFACTURER_ID = 0x5F4D; public static final int CERTIFICATE_CONTENT = 0x5F4E; public static final int UNIFORM_RESOURCE_LOCATOR = 0x5F50; public static final int ANSWER_TO_RESET = 0x5F51; public static final int HISTORICAL_BYTES = 0x5F52; public static final int DIGITAL_SIGNATURE = 0x5F3D; public static final int APPLICATION_TEMPLATE = 0x61; public static final int FCP_TEMPLATE = 0x62; public static final int WRAPPER = 0x63; public static final int FMD_TEMPLATE = 0x64; public static final int CARDHOLDER_RELATIVE_DATA = 0x65; public static final int CARD_DATA = 0x66; public static final int AUTHENTIFICATION_DATA = 0x67; public static final int SPECIAL_USER_REQUIREMENTS = 0x68; public static final int LOGIN_TEMPLATE = 0x6A; public static final int QUALIFIED_NAME = 0x6B; public static final int CARDHOLDER_IMAGE_TEMPLATE = 0x6C; public static final int APPLICATION_IMAGE_TEMPLATE = 0x6D; public static final int APPLICATION_RELATED_DATA = 0x6E; public static final int FCI_TEMPLATE = 0x6F; public static final int DISCRETIONARY_DATA_OBJECTS = 0x73; public static final int COMPATIBLE_TAG_ALLOCATION_AUTHORITY = 0x78; public static final int COEXISTANT_TAG_ALLOCATION_AUTHORITY = 0x79; public static final int SECURITY_SUPPORT_TEMPLATE = 0x7A; public static final int SECURITY_ENVIRONMENT_TEMPLATE = 0x7B; public static final int DYNAMIC_AUTHENTIFICATION_TEMPLATE = 0x7C; public static final int SECURE_MESSAGING_TEMPLATE = 0x7D; public static final int NON_INTERINDUSTRY_DATA_OBJECT_NESTING_TEMPLATE = 0x7E; public static final int DISPLAY_CONTROL = 0x7F20; public static final int CARDHOLDER_CERTIFICATE = 0x21; // 0x7F21; public static final int CV_CERTIFICATE = 0x7F21; public static final int CARDHOLER_REQUIREMENTS_INCLUDED_FEATURES = 0x7F22; public static final int CARDHOLER_REQUIREMENTS_EXCLUDED_FEATURES = 0x7F23; public static final int BIOMETRIC_DATA_TEMPLATE = 0x7F2E; public static final int DIGITAL_SIGNATURE_BLOCK = 0x7F3D; public static final int CARDHOLDER_PRIVATE_KEY_TEMPLATE = 0x7F48; public static final int CARDHOLDER_PUBLIC_KEY_TEMPLATE = 0x49; // 0x7F49; public static final int CERTIFICATE_HOLDER_AUTHORIZATION_TEMPLATE = 0x4C; // 0x7F4C; public static final int CERTIFICATE_CONTENT_TEMPLATE = 0x4E; // 0x7F4E; public static final int CERTIFICATE_BODY = 0x4E; // 0x7F4E; public static final int BIOMETRIC_INFORMATION_TEMPLATE = 0x7F60; public static final int BIOMETRIC_INFORMATION_GROUP_TEMPLATE = 0x7F61; public static int getTag(int encodedTag) { /* int i; for (i = 24; i>=0; i-=8) { if (((0xFF<> i); } return 0; */ return decodeTag(encodedTag); } public static int getTagNo(int tag) { int i; for (i = 24; i >= 0; i -= 8) { if (((0xFF << i) & tag) != 0) { return ((~(0xFF << i)) & tag); } } return 0; } public static int encodeTag(DERApplicationSpecific spec) { int retValue = BERTags.APPLICATION; boolean constructed = spec.isConstructed(); if (constructed) { retValue |= BERTags.CONSTRUCTED; } int tag = spec.getApplicationTag(); if (tag > 31) { retValue |= 0x1F; retValue <<= 8; int currentByte = tag & 0x7F; retValue |= currentByte; tag >>= 7; while (tag > 0) { retValue |= 0x80; retValue <<= 8; currentByte = tag & 0x7F; tag >>= 7; } } else { retValue |= tag; } return retValue; } public static int decodeTag(int tag) { int retValue = 0; boolean multiBytes = false; for (int i = 24; i >= 0; i -= 8) { int currentByte = tag >> i & 0xFF; if (currentByte == 0) { continue; } if (multiBytes) { retValue <<= 7; retValue |= currentByte & 0x7F; } else if ((currentByte & 0x1F) == 0x1F) { multiBytes = true; } else { return currentByte & 0x1F; // higher order bit are for DER.Constructed and type } } return retValue; } } bouncycastle-1.49.orig/src/org/bouncycastle/asn1/eac/CVCertificate.java0000644000175000017500000002262612151251423025416 0ustar ebourgebourgpackage org.bouncycastle.asn1.eac; import java.io.IOException; import org.bouncycastle.asn1.ASN1EncodableVector; import org.bouncycastle.asn1.ASN1InputStream; import org.bouncycastle.asn1.ASN1Object; import org.bouncycastle.asn1.ASN1ObjectIdentifier; import org.bouncycastle.asn1.ASN1ParsingException; import org.bouncycastle.asn1.ASN1Primitive; import org.bouncycastle.asn1.DERApplicationSpecific; import org.bouncycastle.asn1.DEROctetString; /** * an iso7816Certificate structure. *

    *

     *  Certificate ::= SEQUENCE {
     *      CertificateBody         Iso7816CertificateBody,
     *      signature               DER Application specific
     *  }
     * 
    */ public class CVCertificate extends ASN1Object { private CertificateBody certificateBody; private byte[] signature; private int valid; private static int bodyValid = 0x01; private static int signValid = 0x02; public static final byte version_1 = 0x0; public static String ReferenceEncoding = "ISO-8859-1"; /** * Sets the values of the certificate (body and signature). * * @param appSpe is a DERApplicationSpecific object containing body and signature. * @throws IOException if tags or value are incorrect. */ private void setPrivateData(DERApplicationSpecific appSpe) throws IOException { valid = 0; if (appSpe.getApplicationTag() == EACTags.CARDHOLDER_CERTIFICATE) { ASN1InputStream content = new ASN1InputStream(appSpe.getContents()); ASN1Primitive tmpObj; while ((tmpObj = content.readObject()) != null) { DERApplicationSpecific aSpe; if (tmpObj instanceof DERApplicationSpecific) { aSpe = (DERApplicationSpecific)tmpObj; switch (aSpe.getApplicationTag()) { case EACTags.CERTIFICATE_CONTENT_TEMPLATE: certificateBody = CertificateBody.getInstance(aSpe); valid |= bodyValid; break; case EACTags.STATIC_INTERNAL_AUTHENTIFICATION_ONE_STEP: signature = aSpe.getContents(); valid |= signValid; break; default: throw new IOException("Invalid tag, not an Iso7816CertificateStructure :" + aSpe.getApplicationTag()); } } else { throw new IOException("Invalid Object, not an Iso7816CertificateStructure"); } } } else { throw new IOException("not a CARDHOLDER_CERTIFICATE :" + appSpe.getApplicationTag()); } } /** * Create an iso7816Certificate structure from an ASN1InputStream. * * @param aIS the byte stream to parse. * @return the Iso7816CertificateStructure represented by the byte stream. * @throws IOException if there is a problem parsing the data. */ public CVCertificate(ASN1InputStream aIS) throws IOException { initFrom(aIS); } private void initFrom(ASN1InputStream aIS) throws IOException { ASN1Primitive obj; while ((obj = aIS.readObject()) != null) { if (obj instanceof DERApplicationSpecific) { setPrivateData((DERApplicationSpecific)obj); } else { throw new IOException("Invalid Input Stream for creating an Iso7816CertificateStructure"); } } } /** * Create an iso7816Certificate structure from a DERApplicationSpecific. * * @param appSpe the DERApplicationSpecific object. * @return the Iso7816CertificateStructure represented by the DERApplicationSpecific object. * @throws IOException if there is a problem parsing the data. */ private CVCertificate(DERApplicationSpecific appSpe) throws IOException { setPrivateData(appSpe); } /** * Create an iso7816Certificate structure from a body and its signature. * * @param body the Iso7816CertificateBody object containing the body. * @param signature the byte array containing the signature * @return the Iso7816CertificateStructure * @throws IOException if there is a problem parsing the data. */ public CVCertificate(CertificateBody body, byte[] signature) throws IOException { certificateBody = body; this.signature = signature; // patch remi valid |= bodyValid; valid |= signValid; } /** * Create an iso7816Certificate structure from an object. * * @param obj the Object to extract the certificate from. * @return the Iso7816CertificateStructure represented by the byte stream. * @throws IOException if there is a problem parsing the data. */ public static CVCertificate getInstance(Object obj) { if (obj instanceof CVCertificate) { return (CVCertificate)obj; } else if (obj != null) { try { return new CVCertificate(DERApplicationSpecific.getInstance(obj)); } catch (IOException e) { throw new ASN1ParsingException("unable to parse data: " + e.getMessage(), e); } } return null; } /** * Gives the signature of the whole body. Type of signature is given in * the Iso7816CertificateBody.Iso7816PublicKey.ASN1ObjectIdentifier * * @return the signature of the body. */ public byte[] getSignature() { return signature; } /** * Gives the body of the certificate. * * @return the body. */ public CertificateBody getBody() { return certificateBody; } /** * @see org.bouncycastle.asn1.ASN1Object#toASN1Primitive() */ public ASN1Primitive toASN1Primitive() { ASN1EncodableVector v = new ASN1EncodableVector(); if (valid != (signValid | bodyValid)) { return null; } v.add(certificateBody); try { v.add(new DERApplicationSpecific(false, EACTags.STATIC_INTERNAL_AUTHENTIFICATION_ONE_STEP, new DEROctetString(signature))); } catch (IOException e) { throw new IllegalStateException("unable to convert signature!"); } return new DERApplicationSpecific(EACTags.CARDHOLDER_CERTIFICATE, v); } /** * @return the Holder authorization and role (CVCA, DV, IS). */ public ASN1ObjectIdentifier getHolderAuthorization() throws IOException { CertificateHolderAuthorization cha = certificateBody.getCertificateHolderAuthorization(); return cha.getOid(); } /** * @return the date of the certificate generation */ public PackedDate getEffectiveDate() throws IOException { return certificateBody.getCertificateEffectiveDate(); } /** * @return the type of certificate (request or profile) * value is either Iso7816CertificateBody.profileType * or Iso7816CertificateBody.requestType. Any other value * is not valid. */ public int getCertificateType() { return this.certificateBody.getCertificateType(); } /** * @return the date of the certificate generation */ public PackedDate getExpirationDate() throws IOException { return certificateBody.getCertificateExpirationDate(); } /** * return a bits field coded on one byte. For signification of the * several bit see Iso7816CertificateHolderAuthorization * * @return role and access rigth * @throws IOException * @see CertificateHolderAuthorization */ public int getRole() throws IOException { CertificateHolderAuthorization cha = certificateBody.getCertificateHolderAuthorization(); return cha.getAccessRights(); } /** * @return the Authority Reference field of the certificate * @throws IOException */ public CertificationAuthorityReference getAuthorityReference() throws IOException { return certificateBody.getCertificationAuthorityReference(); } /** * @return the Holder Reference Field of the certificate * @throws IOException */ public CertificateHolderReference getHolderReference() throws IOException { return certificateBody.getCertificateHolderReference(); } /** * @return the bits corresponding to the role intented for the certificate * See Iso7816CertificateHolderAuthorization static int for values * @throws IOException */ public int getHolderAuthorizationRole() throws IOException { int rights = certificateBody.getCertificateHolderAuthorization().getAccessRights(); return rights & 0xC0; } /** * @return the bits corresponding the authorizations contained in the certificate * See Iso7816CertificateHolderAuthorization static int for values * @throws IOException */ public Flags getHolderAuthorizationRights() throws IOException { return new Flags(certificateBody.getCertificateHolderAuthorization().getAccessRights() & 0x1F); } } bouncycastle-1.49.orig/src/org/bouncycastle/asn1/eac/ECDSAPublicKey.java0000644000175000017500000002220412151251423025362 0ustar ebourgebourgpackage org.bouncycastle.asn1.eac; import java.math.BigInteger; import java.util.Enumeration; import org.bouncycastle.asn1.ASN1EncodableVector; import org.bouncycastle.asn1.ASN1ObjectIdentifier; import org.bouncycastle.asn1.ASN1OctetString; import org.bouncycastle.asn1.ASN1Primitive; import org.bouncycastle.asn1.ASN1Sequence; import org.bouncycastle.asn1.ASN1TaggedObject; import org.bouncycastle.asn1.DEROctetString; import org.bouncycastle.asn1.DERSequence; import org.bouncycastle.asn1.DERTaggedObject; /** * an Iso7816ECDSAPublicKeyStructure structure. *

    *

     *  Certificate Holder Authorization ::= SEQUENCE {
     *      ASN1TaggedObject primeModulusP;        // OPTIONAL
     *      ASN1TaggedObject firstCoefA;            // OPTIONAL
     *      ASN1TaggedObject secondCoefB;        // OPTIONAL
     *      ASN1TaggedObject basePointG;            // OPTIONAL
     *      ASN1TaggedObject orderOfBasePointR;    // OPTIONAL
     *      ASN1TaggedObject publicPointY;        //REQUIRED
     *      ASN1TaggedObject    cofactorF;            // OPTIONAL
     *  }
     * 
    */ public class ECDSAPublicKey extends PublicKeyDataObject { private ASN1ObjectIdentifier usage; private BigInteger primeModulusP; // OPTIONAL private BigInteger firstCoefA; // OPTIONAL private BigInteger secondCoefB; // OPTIONAL private byte[] basePointG; // OPTIONAL private BigInteger orderOfBasePointR; // OPTIONAL private byte[] publicPointY; //REQUIRED private BigInteger cofactorF; // OPTIONAL private int options; private static final int P = 0x01; private static final int A = 0x02; private static final int B = 0x04; private static final int G = 0x08; private static final int R = 0x10; private static final int Y = 0x20; private static final int F = 0x40; ECDSAPublicKey(ASN1Sequence seq) throws IllegalArgumentException { Enumeration en = seq.getObjects(); this.usage = ASN1ObjectIdentifier.getInstance(en.nextElement()); options = 0; while (en.hasMoreElements()) { Object obj = en.nextElement(); if (obj instanceof ASN1TaggedObject) { ASN1TaggedObject to = (ASN1TaggedObject)obj; switch (to.getTagNo()) { case 0x1: setPrimeModulusP(UnsignedInteger.getInstance(to).getValue()); break; case 0x2: setFirstCoefA(UnsignedInteger.getInstance(to).getValue()); break; case 0x3: setSecondCoefB(UnsignedInteger.getInstance(to).getValue()); break; case 0x4: setBasePointG(ASN1OctetString.getInstance(to, false)); break; case 0x5: setOrderOfBasePointR(UnsignedInteger.getInstance(to).getValue()); break; case 0x6: setPublicPointY(ASN1OctetString.getInstance(to, false)); break; case 0x7: setCofactorF(UnsignedInteger.getInstance(to).getValue()); break; default: options = 0; throw new IllegalArgumentException("Unknown Object Identifier!"); } } else { throw new IllegalArgumentException("Unknown Object Identifier!"); } } if (options != 0x20 && options != 0x7F) { throw new IllegalArgumentException("All options must be either present or absent!"); } } public ECDSAPublicKey(ASN1ObjectIdentifier usage, byte[] ppY) throws IllegalArgumentException { this.usage = usage; setPublicPointY(new DEROctetString(ppY)); } public ECDSAPublicKey(ASN1ObjectIdentifier usage, BigInteger p, BigInteger a, BigInteger b, byte[] basePoint, BigInteger order, byte[] publicPoint, int cofactor) { this.usage = usage; setPrimeModulusP(p); setFirstCoefA(a); setSecondCoefB(b); setBasePointG(new DEROctetString(basePoint)); setOrderOfBasePointR(order); setPublicPointY(new DEROctetString(publicPoint)); setCofactorF(BigInteger.valueOf(cofactor)); } public ASN1ObjectIdentifier getUsage() { return usage; } public byte[] getBasePointG() { if ((options & G) != 0) { return basePointG; } else { return null; } } private void setBasePointG(ASN1OctetString basePointG) throws IllegalArgumentException { if ((options & G) == 0) { options |= G; this.basePointG = basePointG.getOctets(); } else { throw new IllegalArgumentException("Base Point G already set"); } } public BigInteger getCofactorF() { if ((options & F) != 0) { return cofactorF; } else { return null; } } private void setCofactorF(BigInteger cofactorF) throws IllegalArgumentException { if ((options & F) == 0) { options |= F; this.cofactorF = cofactorF; } else { throw new IllegalArgumentException("Cofactor F already set"); } } public BigInteger getFirstCoefA() { if ((options & A) != 0) { return firstCoefA; } else { return null; } } private void setFirstCoefA(BigInteger firstCoefA) throws IllegalArgumentException { if ((options & A) == 0) { options |= A; this.firstCoefA = firstCoefA; } else { throw new IllegalArgumentException("First Coef A already set"); } } public BigInteger getOrderOfBasePointR() { if ((options & R) != 0) { return orderOfBasePointR; } else { return null; } } private void setOrderOfBasePointR(BigInteger orderOfBasePointR) throws IllegalArgumentException { if ((options & R) == 0) { options |= R; this.orderOfBasePointR = orderOfBasePointR; } else { throw new IllegalArgumentException("Order of base point R already set"); } } public BigInteger getPrimeModulusP() { if ((options & P) != 0) { return primeModulusP; } else { return null; } } private void setPrimeModulusP(BigInteger primeModulusP) { if ((options & P) == 0) { options |= P; this.primeModulusP = primeModulusP; } else { throw new IllegalArgumentException("Prime Modulus P already set"); } } public byte[] getPublicPointY() { if ((options & Y) != 0) { return publicPointY; } else { return null; } } private void setPublicPointY(ASN1OctetString publicPointY) throws IllegalArgumentException { if ((options & Y) == 0) { options |= Y; this.publicPointY = publicPointY.getOctets(); } else { throw new IllegalArgumentException("Public Point Y already set"); } } public BigInteger getSecondCoefB() { if ((options & B) != 0) { return secondCoefB; } else { return null; } } private void setSecondCoefB(BigInteger secondCoefB) throws IllegalArgumentException { if ((options & B) == 0) { options |= B; this.secondCoefB = secondCoefB; } else { throw new IllegalArgumentException("Second Coef B already set"); } } public boolean hasParameters() { return primeModulusP != null; } public ASN1EncodableVector getASN1EncodableVector(ASN1ObjectIdentifier oid, boolean publicPointOnly) { ASN1EncodableVector v = new ASN1EncodableVector(); v.add(oid); if (!publicPointOnly) { v.add(new UnsignedInteger(0x01, getPrimeModulusP())); v.add(new UnsignedInteger(0x02, getFirstCoefA())); v.add(new UnsignedInteger(0x03, getSecondCoefB())); v.add(new DERTaggedObject(false, 0x04, new DEROctetString(getBasePointG()))); v.add(new UnsignedInteger(0x05, getOrderOfBasePointR())); } v.add(new DERTaggedObject(false, 0x06, new DEROctetString(getPublicPointY()))); if (!publicPointOnly) { v.add(new UnsignedInteger(0x07, getCofactorF())); } return v; } public ASN1Primitive toASN1Primitive() { return new DERSequence(getASN1EncodableVector(usage, false)); } } bouncycastle-1.49.orig/src/org/bouncycastle/asn1/eac/CertificationAuthorityReference.java0000644000175000017500000000061411643216347031262 0ustar ebourgebourgpackage org.bouncycastle.asn1.eac; public class CertificationAuthorityReference extends CertificateHolderReference { public CertificationAuthorityReference(String countryCode, String holderMnemonic, String sequenceNumber) { super(countryCode, holderMnemonic, sequenceNumber); } CertificationAuthorityReference(byte[] contents) { super(contents); } } bouncycastle-1.49.orig/src/org/bouncycastle/asn1/eac/CertificateBody.java0000644000175000017500000004277412151253000026002 0ustar ebourgebourgpackage org.bouncycastle.asn1.eac; import java.io.IOException; import org.bouncycastle.asn1.ASN1EncodableVector; import org.bouncycastle.asn1.ASN1InputStream; import org.bouncycastle.asn1.ASN1Object; import org.bouncycastle.asn1.ASN1Primitive; import org.bouncycastle.asn1.BERTags; import org.bouncycastle.asn1.DERApplicationSpecific; import org.bouncycastle.asn1.DEROctetString; /** * an Iso7816CertificateBody structure. *

    *

     *  CertificateBody ::= SEQUENCE {
     *      // version of the certificate format. Must be 0 (version 1)
     *      CertificateProfileIdentifer         DERApplicationSpecific,
     *      //uniquely identifies the issuinng CA's signature key pair
     *      // contains the iso3166-1 alpha2 encoded country code, the
     *      // name of issuer and the sequence number of the key pair.
     *      CertificationAuthorityReference        DERApplicationSpecific,
     *      // stores the encoded public key
     *      PublicKey                            Iso7816PublicKey,
     *      //associates the public key contained in the certificate with a unique name
     *      // contains the iso3166-1 alpha2 encoded country code, the
     *      // name of the holder and the sequence number of the key pair.
     *      certificateHolderReference            DERApplicationSpecific,
     *      // Encodes the role of the holder (i.e. CVCA, DV, IS) and assigns read/write
     *      // access rights to data groups storing sensitive data
     *      certificateHolderAuthorization        Iso7816CertificateHolderAuthorization,
     *      // the date of the certificate generation
     *      CertificateEffectiveDate            DERApplicationSpecific,
     *      // the date after wich the certificate expires
     *      certificateExpirationDate            DERApplicationSpecific
     *  }
     * 
    */ public class CertificateBody extends ASN1Object { ASN1InputStream seq; private DERApplicationSpecific certificateProfileIdentifier;// version of the certificate format. Must be 0 (version 1) private DERApplicationSpecific certificationAuthorityReference;//uniquely identifies the issuinng CA's signature key pair private PublicKeyDataObject publicKey;// stores the encoded public key private DERApplicationSpecific certificateHolderReference;//associates the public key contained in the certificate with a unique name private CertificateHolderAuthorization certificateHolderAuthorization;// Encodes the role of the holder (i.e. CVCA, DV, IS) and assigns read/write access rights to data groups storing sensitive data private DERApplicationSpecific certificateEffectiveDate;// the date of the certificate generation private DERApplicationSpecific certificateExpirationDate;// the date after wich the certificate expires private int certificateType = 0;// bit field of initialized data. This will tell us if the data are valid. private static final int CPI = 0x01;//certificate Profile Identifier private static final int CAR = 0x02;//certification Authority Reference private static final int PK = 0x04;//public Key private static final int CHR = 0x08;//certificate Holder Reference private static final int CHA = 0x10;//certificate Holder Authorization private static final int CEfD = 0x20;//certificate Effective Date private static final int CExD = 0x40;//certificate Expiration Date public static final int profileType = 0x7f;//Profile type Certificate public static final int requestType = 0x0D;// Request type Certificate private void setIso7816CertificateBody(DERApplicationSpecific appSpe) throws IOException { byte[] content; if (appSpe.getApplicationTag() == EACTags.CERTIFICATE_CONTENT_TEMPLATE) { content = appSpe.getContents(); } else { throw new IOException("Bad tag : not an iso7816 CERTIFICATE_CONTENT_TEMPLATE"); } ASN1InputStream aIS = new ASN1InputStream(content); ASN1Primitive obj; while ((obj = aIS.readObject()) != null) { DERApplicationSpecific aSpe; if (obj instanceof DERApplicationSpecific) { aSpe = (DERApplicationSpecific)obj; } else { throw new IOException("Not a valid iso7816 content : not a DERApplicationSpecific Object :" + EACTags.encodeTag(appSpe) + obj.getClass()); } switch (aSpe.getApplicationTag()) { case EACTags.INTERCHANGE_PROFILE: setCertificateProfileIdentifier(aSpe); break; case EACTags.ISSUER_IDENTIFICATION_NUMBER: setCertificationAuthorityReference(aSpe); break; case EACTags.CARDHOLDER_PUBLIC_KEY_TEMPLATE: setPublicKey(PublicKeyDataObject.getInstance(aSpe.getObject(BERTags.SEQUENCE))); break; case EACTags.CARDHOLDER_NAME: setCertificateHolderReference(aSpe); break; case EACTags.CERTIFICATE_HOLDER_AUTHORIZATION_TEMPLATE: setCertificateHolderAuthorization(new CertificateHolderAuthorization(aSpe)); break; case EACTags.APPLICATION_EFFECTIVE_DATE: setCertificateEffectiveDate(aSpe); break; case EACTags.APPLICATION_EXPIRATION_DATE: setCertificateExpirationDate(aSpe); break; default: certificateType = 0; throw new IOException("Not a valid iso7816 DERApplicationSpecific tag " + aSpe.getApplicationTag()); } } } /** * builds an Iso7816CertificateBody by settings each parameters. * * @param certificateProfileIdentifier * @param certificationAuthorityReference * * @param publicKey * @param certificateHolderReference * @param certificateHolderAuthorization * @param certificateEffectiveDate * @param certificateExpirationDate * @throws IOException */ public CertificateBody( DERApplicationSpecific certificateProfileIdentifier, CertificationAuthorityReference certificationAuthorityReference, PublicKeyDataObject publicKey, CertificateHolderReference certificateHolderReference, CertificateHolderAuthorization certificateHolderAuthorization, PackedDate certificateEffectiveDate, PackedDate certificateExpirationDate ) { setCertificateProfileIdentifier(certificateProfileIdentifier); setCertificationAuthorityReference(new DERApplicationSpecific( EACTags.ISSUER_IDENTIFICATION_NUMBER, certificationAuthorityReference.getEncoded())); setPublicKey(publicKey); setCertificateHolderReference(new DERApplicationSpecific( EACTags.CARDHOLDER_NAME, certificateHolderReference.getEncoded())); setCertificateHolderAuthorization(certificateHolderAuthorization); try { setCertificateEffectiveDate(new DERApplicationSpecific( false, EACTags.APPLICATION_EFFECTIVE_DATE, new DEROctetString(certificateEffectiveDate.getEncoding()))); setCertificateExpirationDate(new DERApplicationSpecific( false, EACTags.APPLICATION_EXPIRATION_DATE, new DEROctetString(certificateExpirationDate.getEncoding()))); } catch (IOException e) { throw new IllegalArgumentException("unable to encode dates: " + e.getMessage()); } } /** * builds an Iso7816CertificateBody with an ASN1InputStream. * * @param obj DERApplicationSpecific containing the whole body. * @throws IOException if the body is not valid. */ private CertificateBody(DERApplicationSpecific obj) throws IOException { setIso7816CertificateBody(obj); } /** * create a profile type Iso7816CertificateBody. * * @return return the "profile" type certificate body. * @throws IOException if the DERApplicationSpecific cannot be created. */ private ASN1Primitive profileToASN1Object() throws IOException { ASN1EncodableVector v = new ASN1EncodableVector(); v.add(certificateProfileIdentifier); v.add(certificationAuthorityReference); v.add(new DERApplicationSpecific(false, EACTags.CARDHOLDER_PUBLIC_KEY_TEMPLATE, publicKey)); v.add(certificateHolderReference); v.add(certificateHolderAuthorization); v.add(certificateEffectiveDate); v.add(certificateExpirationDate); return new DERApplicationSpecific(EACTags.CERTIFICATE_CONTENT_TEMPLATE, v); } private void setCertificateProfileIdentifier(DERApplicationSpecific certificateProfileIdentifier) throws IllegalArgumentException { if (certificateProfileIdentifier.getApplicationTag() == EACTags.INTERCHANGE_PROFILE) { this.certificateProfileIdentifier = certificateProfileIdentifier; certificateType |= CPI; } else { throw new IllegalArgumentException("Not an Iso7816Tags.INTERCHANGE_PROFILE tag :" + EACTags.encodeTag(certificateProfileIdentifier)); } } private void setCertificateHolderReference(DERApplicationSpecific certificateHolderReference) throws IllegalArgumentException { if (certificateHolderReference.getApplicationTag() == EACTags.CARDHOLDER_NAME) { this.certificateHolderReference = certificateHolderReference; certificateType |= CHR; } else { throw new IllegalArgumentException("Not an Iso7816Tags.CARDHOLDER_NAME tag"); } } /** * set the CertificationAuthorityReference. * * @param certificationAuthorityReference * the DERApplicationSpecific containing the CertificationAuthorityReference. * @throws IllegalArgumentException if the DERApplicationSpecific is not valid. */ private void setCertificationAuthorityReference( DERApplicationSpecific certificationAuthorityReference) throws IllegalArgumentException { if (certificationAuthorityReference.getApplicationTag() == EACTags.ISSUER_IDENTIFICATION_NUMBER) { this.certificationAuthorityReference = certificationAuthorityReference; certificateType |= CAR; } else { throw new IllegalArgumentException("Not an Iso7816Tags.ISSUER_IDENTIFICATION_NUMBER tag"); } } /** * set the public Key * * @param publicKey : the DERApplicationSpecific containing the public key * @throws java.io.IOException */ private void setPublicKey(PublicKeyDataObject publicKey) { this.publicKey = PublicKeyDataObject.getInstance(publicKey); this.certificateType |= PK; } /** * create a request type Iso7816CertificateBody. * * @return return the "request" type certificate body. * @throws IOException if the DERApplicationSpecific cannot be created. */ private ASN1Primitive requestToASN1Object() throws IOException { ASN1EncodableVector v = new ASN1EncodableVector(); v.add(certificateProfileIdentifier); v.add(new DERApplicationSpecific(false, EACTags.CARDHOLDER_PUBLIC_KEY_TEMPLATE, publicKey)); v.add(certificateHolderReference); return new DERApplicationSpecific(EACTags.CERTIFICATE_CONTENT_TEMPLATE, v); } /** * create a "request" or "profile" type Iso7816CertificateBody according to the variables sets. * * @return return the ASN1Primitive representing the "request" or "profile" type certificate body. * @throws IOException if the DERApplicationSpecific cannot be created or if data are missings to create a valid certificate. */ public ASN1Primitive toASN1Primitive() { try { if (certificateType == profileType) { return profileToASN1Object(); } if (certificateType == requestType) { return requestToASN1Object(); } } catch (IOException e) { return null; } return null; } /** * gives the type of the certificate (value should be profileType or requestType if all data are set). * * @return the int representing the data already set. */ public int getCertificateType() { return certificateType; } /** * Gives an instance of Iso7816CertificateBody taken from Object obj * * @param obj is the Object to extract the certificate body from. * @return the Iso7816CertificateBody taken from Object obj. * @throws IOException if object is not valid. */ public static CertificateBody getInstance(Object obj) throws IOException { if (obj instanceof CertificateBody) { return (CertificateBody)obj; } else if (obj != null) { return new CertificateBody(DERApplicationSpecific.getInstance(obj)); } return null; } /** * @return the date of the certificate generation */ public PackedDate getCertificateEffectiveDate() { if ((this.certificateType & CertificateBody.CEfD) == CertificateBody.CEfD) { return new PackedDate(certificateEffectiveDate.getContents()); } return null; } /** * set the date of the certificate generation * * @param ced DERApplicationSpecific containing the date of the certificate generation * @throws IllegalArgumentException if the tag is not Iso7816Tags.APPLICATION_EFFECTIVE_DATE */ private void setCertificateEffectiveDate(DERApplicationSpecific ced) throws IllegalArgumentException { if (ced.getApplicationTag() == EACTags.APPLICATION_EFFECTIVE_DATE) { this.certificateEffectiveDate = ced; certificateType |= CEfD; } else { throw new IllegalArgumentException("Not an Iso7816Tags.APPLICATION_EFFECTIVE_DATE tag :" + EACTags.encodeTag(ced)); } } /** * @return the date after wich the certificate expires */ public PackedDate getCertificateExpirationDate() throws IOException { if ((this.certificateType & CertificateBody.CExD) == CertificateBody.CExD) { return new PackedDate(certificateExpirationDate.getContents()); } throw new IOException("certificate Expiration Date not set"); } /** * set the date after wich the certificate expires * * @param ced DERApplicationSpecific containing the date after wich the certificate expires * @throws IllegalArgumentException if the tag is not Iso7816Tags.APPLICATION_EXPIRATION_DATE */ private void setCertificateExpirationDate(DERApplicationSpecific ced) throws IllegalArgumentException { if (ced.getApplicationTag() == EACTags.APPLICATION_EXPIRATION_DATE) { this.certificateExpirationDate = ced; certificateType |= CExD; } else { throw new IllegalArgumentException("Not an Iso7816Tags.APPLICATION_EXPIRATION_DATE tag"); } } /** * the Iso7816CertificateHolderAuthorization encodes the role of the holder * (i.e. CVCA, DV, IS) and assigns read/write access rights to data groups * storing sensitive data. This functions returns the Certificate Holder * Authorization * * @return the Iso7816CertificateHolderAuthorization */ public CertificateHolderAuthorization getCertificateHolderAuthorization() throws IOException { if ((this.certificateType & CertificateBody.CHA) == CertificateBody.CHA) { return certificateHolderAuthorization; } throw new IOException("Certificate Holder Authorisation not set"); } /** * set the CertificateHolderAuthorization * * @param cha the Certificate Holder Authorization */ private void setCertificateHolderAuthorization( CertificateHolderAuthorization cha) { this.certificateHolderAuthorization = cha; certificateType |= CHA; } /** * certificateHolderReference : associates the public key contained in the certificate with a unique name * * @return the certificateHolderReference. */ public CertificateHolderReference getCertificateHolderReference() { return new CertificateHolderReference(certificateHolderReference.getContents()); } /** * CertificateProfileIdentifier : version of the certificate format. Must be 0 (version 1) * * @return the CertificateProfileIdentifier */ public DERApplicationSpecific getCertificateProfileIdentifier() { return certificateProfileIdentifier; } /** * get the certificationAuthorityReference * certificationAuthorityReference : uniquely identifies the issuinng CA's signature key pair * * @return the certificationAuthorityReference */ public CertificationAuthorityReference getCertificationAuthorityReference() throws IOException { if ((this.certificateType & CertificateBody.CAR) == CertificateBody.CAR) { return new CertificationAuthorityReference(certificationAuthorityReference.getContents()); } throw new IOException("Certification authority reference not set"); } /** * @return the PublicKey */ public PublicKeyDataObject getPublicKey() { return publicKey; } } bouncycastle-1.49.orig/src/org/bouncycastle/asn1/eac/BidirectionalMap.java0000644000175000017500000000070012151274314026142 0ustar ebourgebourgpackage org.bouncycastle.asn1.eac; import java.util.Hashtable; public class BidirectionalMap extends Hashtable { private static final long serialVersionUID = -7457289971962812909L; Hashtable reverseMap = new Hashtable(); public Object getReverse(Object o) { return reverseMap.get(o); } public Object put(Object key, Object o) { reverseMap.put(o, key); return super.put(key, o); } } bouncycastle-1.49.orig/src/org/bouncycastle/asn1/eac/Flags.java0000644000175000017500000000332511676501036024003 0ustar ebourgebourgpackage org.bouncycastle.asn1.eac; import java.util.Enumeration; import java.util.Hashtable; public class Flags { int value = 0; public Flags() { } public Flags(int v) { value = v; } public void set(int flag) { value |= flag; } public boolean isSet(int flag) { return (value & flag) != 0; } public int getFlags() { return value; } /* Java 1.5 String decode(Map decodeMap) { StringJoiner joiner = new StringJoiner(" "); for (int i : decodeMap.keySet()) { if (isSet(i)) joiner.add(decodeMap.get(i)); } return joiner.toString(); } */ String decode(Hashtable decodeMap) { StringJoiner joiner = new StringJoiner(" "); Enumeration e = decodeMap.keys(); while (e.hasMoreElements()) { Integer i = (Integer)e.nextElement(); if (isSet(i.intValue())) { joiner.add((String)decodeMap.get(i)); } } return joiner.toString(); } private class StringJoiner { String mSeparator; boolean First = true; StringBuffer b = new StringBuffer(); public StringJoiner(String separator) { mSeparator = separator; } public void add(String str) { if (First) { First = false; } else { b.append(mSeparator); } b.append(str); } public String toString() { return b.toString(); } } } bouncycastle-1.49.orig/src/org/bouncycastle/asn1/eac/PackedDate.java0000644000175000017500000000406011643211433024722 0ustar ebourgebourgpackage org.bouncycastle.asn1.eac; import java.text.ParseException; import java.text.SimpleDateFormat; import java.util.Date; import java.util.SimpleTimeZone; import org.bouncycastle.util.Arrays; /** * EAC encoding date object */ public class PackedDate { private byte[] time; public PackedDate( String time) { this.time = convert(time); } /** * base constructer from a java.util.date object */ public PackedDate( Date time) { SimpleDateFormat dateF = new SimpleDateFormat("yyMMdd'Z'"); dateF.setTimeZone(new SimpleTimeZone(0,"Z")); this.time = convert(dateF.format(time)); } private byte[] convert(String sTime) { char[] digs = sTime.toCharArray(); byte[] date = new byte[6]; for (int i = 0; i != 6; i++) { date[i] = (byte)(digs[i] - '0'); } return date; } PackedDate( byte[] bytes) { this.time = bytes; } /** * return the time as a date based on whatever a 2 digit year will return. For * standardised processing use getAdjustedDate(). * * @return the resulting date * @exception java.text.ParseException if the date string cannot be parsed. */ public Date getDate() throws ParseException { SimpleDateFormat dateF = new SimpleDateFormat("yyyyMMdd"); return dateF.parse("20" + toString()); } public int hashCode() { return Arrays.hashCode(time); } public boolean equals(Object o) { if (!(o instanceof PackedDate)) { return false; } PackedDate other = (PackedDate)o; return Arrays.areEqual(time, other.time); } public String toString() { char[] dateC = new char[time.length]; for (int i = 0; i != dateC.length; i++) { dateC[i] = (char)((time[i] & 0xff) + '0'); } return new String(dateC); } public byte[] getEncoding() { return time; } } bouncycastle-1.49.orig/src/org/bouncycastle/asn1/eac/PublicKeyDataObject.java0000644000175000017500000000164611643462504026563 0ustar ebourgebourgpackage org.bouncycastle.asn1.eac; import org.bouncycastle.asn1.ASN1Object; import org.bouncycastle.asn1.ASN1ObjectIdentifier; import org.bouncycastle.asn1.ASN1Sequence; public abstract class PublicKeyDataObject extends ASN1Object { public static PublicKeyDataObject getInstance(Object obj) { if (obj instanceof PublicKeyDataObject) { return (PublicKeyDataObject)obj; } if (obj != null) { ASN1Sequence seq = ASN1Sequence.getInstance(obj); ASN1ObjectIdentifier usage = ASN1ObjectIdentifier.getInstance(seq.getObjectAt(0)); if (usage.on(EACObjectIdentifiers.id_TA_ECDSA)) { return new ECDSAPublicKey(seq); } else { return new RSAPublicKey(seq); } } return null; } public abstract ASN1ObjectIdentifier getUsage(); } bouncycastle-1.49.orig/src/org/bouncycastle/asn1/eac/EACObjectIdentifiers.java0000644000175000017500000000521411643462504026653 0ustar ebourgebourgpackage org.bouncycastle.asn1.eac; import org.bouncycastle.asn1.ASN1ObjectIdentifier; public interface EACObjectIdentifiers { // bsi-de OBJECT IDENTIFIER ::= { // itu-t(0) identified-organization(4) etsi(0) // reserved(127) etsi-identified-organization(0) 7 // } static final ASN1ObjectIdentifier bsi_de = new ASN1ObjectIdentifier("0.4.0.127.0.7"); // id-PK OBJECT IDENTIFIER ::= { // bsi-de protocols(2) smartcard(2) 1 // } static final ASN1ObjectIdentifier id_PK = bsi_de.branch("2.2.1"); static final ASN1ObjectIdentifier id_PK_DH = id_PK.branch("1"); static final ASN1ObjectIdentifier id_PK_ECDH = id_PK.branch("2"); // id-CA OBJECT IDENTIFIER ::= { // bsi-de protocols(2) smartcard(2) 3 // } static final ASN1ObjectIdentifier id_CA = bsi_de.branch("2.2.3"); static final ASN1ObjectIdentifier id_CA_DH = id_CA.branch("1"); static final ASN1ObjectIdentifier id_CA_DH_3DES_CBC_CBC = id_CA_DH.branch("1"); static final ASN1ObjectIdentifier id_CA_ECDH = id_CA.branch("2"); static final ASN1ObjectIdentifier id_CA_ECDH_3DES_CBC_CBC = id_CA_ECDH.branch("1"); // // id-TA OBJECT IDENTIFIER ::= { // bsi-de protocols(2) smartcard(2) 2 // } static final ASN1ObjectIdentifier id_TA = bsi_de.branch("2.2.2"); static final ASN1ObjectIdentifier id_TA_RSA = id_TA.branch("1"); static final ASN1ObjectIdentifier id_TA_RSA_v1_5_SHA_1 = id_TA_RSA .branch("1"); static final ASN1ObjectIdentifier id_TA_RSA_v1_5_SHA_256 = id_TA_RSA.branch("2"); static final ASN1ObjectIdentifier id_TA_RSA_PSS_SHA_1 = id_TA_RSA.branch("3"); static final ASN1ObjectIdentifier id_TA_RSA_PSS_SHA_256 = id_TA_RSA.branch("4"); static final ASN1ObjectIdentifier id_TA_RSA_v1_5_SHA_512 = id_TA_RSA.branch("5"); static final ASN1ObjectIdentifier id_TA_RSA_PSS_SHA_512 = id_TA_RSA.branch("6"); static final ASN1ObjectIdentifier id_TA_ECDSA = id_TA.branch("2"); static final ASN1ObjectIdentifier id_TA_ECDSA_SHA_1 = id_TA_ECDSA.branch("1"); static final ASN1ObjectIdentifier id_TA_ECDSA_SHA_224 = id_TA_ECDSA.branch("2"); static final ASN1ObjectIdentifier id_TA_ECDSA_SHA_256 = id_TA_ECDSA.branch("3"); static final ASN1ObjectIdentifier id_TA_ECDSA_SHA_384 = id_TA_ECDSA.branch("4"); static final ASN1ObjectIdentifier id_TA_ECDSA_SHA_512 = id_TA_ECDSA.branch("5"); /** * id-EAC-ePassport OBJECT IDENTIFIER ::= { * bsi-de applications(3) mrtd(1) roles(2) 1} */ static final ASN1ObjectIdentifier id_EAC_ePassport = bsi_de.branch("3.1.2.1"); } bouncycastle-1.49.orig/src/org/bouncycastle/asn1/eac/CertificateHolderReference.java0000644000175000017500000000310211643216347030141 0ustar ebourgebourgpackage org.bouncycastle.asn1.eac; import java.io.UnsupportedEncodingException; public class CertificateHolderReference { private static final String ReferenceEncoding = "ISO-8859-1"; private String countryCode; private String holderMnemonic; private String sequenceNumber; public CertificateHolderReference(String countryCode, String holderMnemonic, String sequenceNumber) { this.countryCode = countryCode; this.holderMnemonic = holderMnemonic; this.sequenceNumber = sequenceNumber; } CertificateHolderReference(byte[] contents) { try { String concat = new String(contents, ReferenceEncoding); this.countryCode = concat.substring(0, 2); this.holderMnemonic = concat.substring(2, concat.length() - 5); this.sequenceNumber = concat.substring(concat.length() - 5); } catch (UnsupportedEncodingException e) { throw new IllegalStateException(e.toString()); } } public String getCountryCode() { return countryCode; } public String getHolderMnemonic() { return holderMnemonic; } public String getSequenceNumber() { return sequenceNumber; } public byte[] getEncoded() { String ref = countryCode + holderMnemonic + sequenceNumber; try { return ref.getBytes(ReferenceEncoding); } catch (UnsupportedEncodingException e) { throw new IllegalStateException(e.toString()); } } } bouncycastle-1.49.orig/src/org/bouncycastle/asn1/eac/RSAPublicKey.java0000644000175000017500000000607612151251423025201 0ustar ebourgebourgpackage org.bouncycastle.asn1.eac; import java.math.BigInteger; import java.util.Enumeration; import org.bouncycastle.asn1.ASN1EncodableVector; import org.bouncycastle.asn1.ASN1ObjectIdentifier; import org.bouncycastle.asn1.ASN1Primitive; import org.bouncycastle.asn1.ASN1Sequence; import org.bouncycastle.asn1.DERSequence; /** * an Iso7816RSAPublicKeyStructure structure. *

    *

     *  Certificate Holder Authorization ::= SEQUENCE {
     *      // modulus should be at least 1024bit and a multiple of 512.
     *      DERTaggedObject        modulus,
     *      // access rights    exponent
     *      DERTaggedObject    accessRights,
     *  }
     * 
    */ public class RSAPublicKey extends PublicKeyDataObject { private ASN1ObjectIdentifier usage; private BigInteger modulus; private BigInteger exponent; private int valid = 0; private static int modulusValid = 0x01; private static int exponentValid = 0x02; RSAPublicKey(ASN1Sequence seq) { Enumeration en = seq.getObjects(); this.usage = ASN1ObjectIdentifier.getInstance(en.nextElement()); while (en.hasMoreElements()) { UnsignedInteger val = UnsignedInteger.getInstance(en.nextElement()); switch (val.getTagNo()) { case 0x1: setModulus(val); break; case 0x2: setExponent(val); break; default: throw new IllegalArgumentException("Unknown DERTaggedObject :" + val.getTagNo() + "-> not an Iso7816RSAPublicKeyStructure"); } } if (valid != 0x3) { throw new IllegalArgumentException("missing argument -> not an Iso7816RSAPublicKeyStructure"); } } public RSAPublicKey(ASN1ObjectIdentifier usage, BigInteger modulus, BigInteger exponent) { this.usage = usage; this.modulus = modulus; this.exponent = exponent; } public ASN1ObjectIdentifier getUsage() { return usage; } public BigInteger getModulus() { return modulus; } public BigInteger getPublicExponent() { return exponent; } private void setModulus(UnsignedInteger modulus) { if ((valid & modulusValid) == 0) { valid |= modulusValid; this.modulus = modulus.getValue(); } else { throw new IllegalArgumentException("Modulus already set"); } } private void setExponent(UnsignedInteger exponent) { if ((valid & exponentValid) == 0) { valid |= exponentValid; this.exponent = exponent.getValue(); } else { throw new IllegalArgumentException("Exponent already set"); } } public ASN1Primitive toASN1Primitive() { ASN1EncodableVector v = new ASN1EncodableVector(); v.add(usage); v.add(new UnsignedInteger(0x01, getModulus())); v.add(new UnsignedInteger(0x02, getPublicExponent())); return new DERSequence(v); } } bouncycastle-1.49.orig/src/org/bouncycastle/asn1/eac/CVCertificateRequest.java0000644000175000017500000001127311724561172026775 0ustar ebourgebourgpackage org.bouncycastle.asn1.eac; import java.io.IOException; import java.util.Enumeration; import org.bouncycastle.asn1.ASN1EncodableVector; import org.bouncycastle.asn1.ASN1Object; import org.bouncycastle.asn1.ASN1ObjectIdentifier; import org.bouncycastle.asn1.ASN1ParsingException; import org.bouncycastle.asn1.ASN1Primitive; import org.bouncycastle.asn1.ASN1Sequence; import org.bouncycastle.asn1.BERTags; import org.bouncycastle.asn1.DERApplicationSpecific; import org.bouncycastle.asn1.DEROctetString; //import java.math.BigInteger; public class CVCertificateRequest extends ASN1Object { private CertificateBody certificateBody; private byte[] innerSignature = null; private byte[] outerSignature = null; private int valid; private static int bodyValid = 0x01; private static int signValid = 0x02; private CVCertificateRequest(DERApplicationSpecific request) throws IOException { if (request.getApplicationTag() == EACTags.AUTHENTIFICATION_DATA) { ASN1Sequence seq = ASN1Sequence.getInstance(request.getObject(BERTags.SEQUENCE)); initCertBody(DERApplicationSpecific.getInstance(seq.getObjectAt(0))); outerSignature = DERApplicationSpecific.getInstance(seq.getObjectAt(seq.size() - 1)).getContents(); } else { initCertBody(request); } } private void initCertBody(DERApplicationSpecific request) throws IOException { if (request.getApplicationTag() == EACTags.CARDHOLDER_CERTIFICATE) { ASN1Sequence seq = ASN1Sequence.getInstance(request.getObject(BERTags.SEQUENCE)); for (Enumeration en = seq.getObjects(); en.hasMoreElements();) { DERApplicationSpecific obj = DERApplicationSpecific.getInstance(en.nextElement()); switch (obj.getApplicationTag()) { case EACTags.CERTIFICATE_CONTENT_TEMPLATE: certificateBody = CertificateBody.getInstance(obj); valid |= bodyValid; break; case EACTags.STATIC_INTERNAL_AUTHENTIFICATION_ONE_STEP: innerSignature = obj.getContents(); valid |= signValid; break; default: throw new IOException("Invalid tag, not an CV Certificate Request element:" + obj.getApplicationTag()); } } } else { throw new IOException("not a CARDHOLDER_CERTIFICATE in request:" + request.getApplicationTag()); } } public static CVCertificateRequest getInstance(Object obj) { if (obj instanceof CVCertificateRequest) { return (CVCertificateRequest)obj; } else if (obj != null) { try { return new CVCertificateRequest(DERApplicationSpecific.getInstance(obj)); } catch (IOException e) { throw new ASN1ParsingException("unable to parse data: " + e.getMessage(), e); } } return null; } ASN1ObjectIdentifier signOid = null; ASN1ObjectIdentifier keyOid = null; public static byte[] ZeroArray = new byte[]{0}; String strCertificateHolderReference; byte[] encodedAuthorityReference; int ProfileId; /** * Returns the body of the certificate template * * @return the body. */ public CertificateBody getCertificateBody() { return certificateBody; } /** * Return the public key data object carried in the request * @return the public key */ public PublicKeyDataObject getPublicKey() { return certificateBody.getPublicKey(); } public byte[] getInnerSignature() { return innerSignature; } public byte[] getOuterSignature() { return outerSignature; } byte[] certificate = null; protected String overSignerReference = null; public boolean hasOuterSignature() { return outerSignature != null; } byte[] encoded; PublicKeyDataObject iso7816PubKey = null; public ASN1Primitive toASN1Primitive() { ASN1EncodableVector v = new ASN1EncodableVector(); v.add(certificateBody); try { v.add(new DERApplicationSpecific(false, EACTags.STATIC_INTERNAL_AUTHENTIFICATION_ONE_STEP, new DEROctetString(innerSignature))); } catch (IOException e) { throw new IllegalStateException("unable to convert signature!"); } return new DERApplicationSpecific(EACTags.CARDHOLDER_CERTIFICATE, v); } } bouncycastle-1.49.orig/src/org/bouncycastle/asn1/eac/UnsignedInteger.java0000644000175000017500000000314211624652555026044 0ustar ebourgebourgpackage org.bouncycastle.asn1.eac; import java.math.BigInteger; import org.bouncycastle.asn1.ASN1Object; import org.bouncycastle.asn1.ASN1OctetString; import org.bouncycastle.asn1.ASN1Primitive; import org.bouncycastle.asn1.ASN1TaggedObject; import org.bouncycastle.asn1.DEROctetString; import org.bouncycastle.asn1.DERTaggedObject; public class UnsignedInteger extends ASN1Object { private int tagNo; private BigInteger value; public UnsignedInteger(int tagNo, BigInteger value) { this.tagNo = tagNo; this.value = value; } private UnsignedInteger(ASN1TaggedObject obj) { this.tagNo = obj.getTagNo(); this.value = new BigInteger(1, ASN1OctetString.getInstance(obj, false).getOctets()); } public static UnsignedInteger getInstance(Object obj) { if (obj instanceof UnsignedInteger) { return (UnsignedInteger)obj; } if (obj != null) { return new UnsignedInteger(ASN1TaggedObject.getInstance(obj)); } return null; } private byte[] convertValue() { byte[] v = value.toByteArray(); if (v[0] == 0) { byte[] tmp = new byte[v.length - 1]; System.arraycopy(v, 1, tmp, 0, tmp.length); return tmp; } return v; } public int getTagNo() { return tagNo; } public BigInteger getValue() { return value; } public ASN1Primitive toASN1Primitive() { return new DERTaggedObject(false, tagNo, new DEROctetString(convertValue())); } } bouncycastle-1.49.orig/src/org/bouncycastle/asn1/x509/0000755000175000017500000000000012152033551022046 5ustar ebourgebourgbouncycastle-1.49.orig/src/org/bouncycastle/asn1/x509/PolicyQualifierInfo.java0000644000175000017500000000563611725273065026653 0ustar ebourgebourgpackage org.bouncycastle.asn1.x509; import org.bouncycastle.asn1.ASN1Encodable; import org.bouncycastle.asn1.ASN1EncodableVector; import org.bouncycastle.asn1.ASN1Object; import org.bouncycastle.asn1.ASN1ObjectIdentifier; import org.bouncycastle.asn1.ASN1Primitive; import org.bouncycastle.asn1.ASN1Sequence; import org.bouncycastle.asn1.DERIA5String; import org.bouncycastle.asn1.DERSequence; /** * Policy qualifiers, used in the X509V3 CertificatePolicies * extension. * *
     *   PolicyQualifierInfo ::= SEQUENCE {
     *       policyQualifierId  PolicyQualifierId,
     *       qualifier          ANY DEFINED BY policyQualifierId }
     * 
    */ public class PolicyQualifierInfo extends ASN1Object { private ASN1ObjectIdentifier policyQualifierId; private ASN1Encodable qualifier; /** * Creates a new PolicyQualifierInfo instance. * * @param policyQualifierId a PolicyQualifierId value * @param qualifier the qualifier, defined by the above field. */ public PolicyQualifierInfo( ASN1ObjectIdentifier policyQualifierId, ASN1Encodable qualifier) { this.policyQualifierId = policyQualifierId; this.qualifier = qualifier; } /** * Creates a new PolicyQualifierInfo containing a * cPSuri qualifier. * * @param cps the CPS (certification practice statement) uri as a * String. */ public PolicyQualifierInfo( String cps) { policyQualifierId = PolicyQualifierId.id_qt_cps; qualifier = new DERIA5String (cps); } /** * Creates a new PolicyQualifierInfo instance. * * @param as PolicyQualifierInfo X509 structure * encoded as an ASN1Sequence. */ public PolicyQualifierInfo( ASN1Sequence as) { if (as.size() != 2) { throw new IllegalArgumentException("Bad sequence size: " + as.size()); } policyQualifierId = ASN1ObjectIdentifier.getInstance(as.getObjectAt(0)); qualifier = as.getObjectAt(1); } public static PolicyQualifierInfo getInstance( Object obj) { if (obj instanceof PolicyQualifierInfo) { return (PolicyQualifierInfo)obj; } else if (obj != null) { return new PolicyQualifierInfo(ASN1Sequence.getInstance(obj)); } return null; } public ASN1ObjectIdentifier getPolicyQualifierId() { return policyQualifierId; } public ASN1Encodable getQualifier() { return qualifier; } /** * Returns a DER-encodable representation of this instance. * * @return a ASN1Primitive value */ public ASN1Primitive toASN1Primitive() { ASN1EncodableVector dev = new ASN1EncodableVector(); dev.add(policyQualifierId); dev.add(qualifier); return new DERSequence(dev); } } bouncycastle-1.49.orig/src/org/bouncycastle/asn1/x509/Targets.java0000644000175000017500000000607711725273264024350 0ustar ebourgebourgpackage org.bouncycastle.asn1.x509; import java.util.Enumeration; import org.bouncycastle.asn1.ASN1Object; import org.bouncycastle.asn1.ASN1Primitive; import org.bouncycastle.asn1.ASN1Sequence; import org.bouncycastle.asn1.DERSequence; /** * Targets structure used in target information extension for attribute * certificates from RFC 3281. * *
     *            Targets ::= SEQUENCE OF Target
     *           
     *            Target  ::= CHOICE {
     *              targetName          [0] GeneralName,
     *              targetGroup         [1] GeneralName,
     *              targetCert          [2] TargetCert
     *            }
     *           
     *            TargetCert  ::= SEQUENCE {
     *              targetCertificate    IssuerSerial,
     *              targetName           GeneralName OPTIONAL,
     *              certDigestInfo       ObjectDigestInfo OPTIONAL
     *            }
     * 
    * * @see org.bouncycastle.asn1.x509.Target * @see org.bouncycastle.asn1.x509.TargetInformation */ public class Targets extends ASN1Object { private ASN1Sequence targets; /** * Creates an instance of a Targets from the given object. *

    * obj can be a Targets or a {@link ASN1Sequence} * * @param obj The object. * @return A Targets instance. * @throws IllegalArgumentException if the given object cannot be * interpreted as Target. */ public static Targets getInstance(Object obj) { if (obj instanceof Targets) { return (Targets)obj; } else if (obj != null) { return new Targets(ASN1Sequence.getInstance(obj)); } return null; } /** * Constructor from ASN1Sequence. * * @param targets The ASN.1 SEQUENCE. * @throws IllegalArgumentException if the contents of the sequence are * invalid. */ private Targets(ASN1Sequence targets) { this.targets = targets; } /** * Constructor from given targets. *

    * The vector is copied. * * @param targets A Vector of {@link Target}s. * @see Target * @throws IllegalArgumentException if the vector contains not only Targets. */ public Targets(Target[] targets) { this.targets = new DERSequence(targets); } /** * Returns the targets in a Vector. *

    * The vector is cloned before it is returned. * * @return Returns the targets. */ public Target[] getTargets() { Target[] targs = new Target[targets.size()]; int count = 0; for (Enumeration e = targets.getObjects(); e.hasMoreElements();) { targs[count++] = Target.getInstance(e.nextElement()); } return targs; } /** * Produce an object suitable for an ASN1OutputStream. * * Returns: * *

         *            Targets ::= SEQUENCE OF Target
         * 
    * * @return a ASN1Primitive */ public ASN1Primitive toASN1Primitive() { return targets; } } bouncycastle-1.49.orig/src/org/bouncycastle/asn1/x509/X509Extension.java0000644000175000017500000001540611724260460025266 0ustar ebourgebourgpackage org.bouncycastle.asn1.x509; import java.io.IOException; import org.bouncycastle.asn1.ASN1Encodable; import org.bouncycastle.asn1.ASN1ObjectIdentifier; import org.bouncycastle.asn1.ASN1OctetString; import org.bouncycastle.asn1.ASN1Primitive; import org.bouncycastle.asn1.DERBoolean; /** * an object for the elements in the X.509 V3 extension block. */ public class X509Extension { /** * Subject Directory Attributes */ public static final ASN1ObjectIdentifier subjectDirectoryAttributes = new ASN1ObjectIdentifier("2.5.29.9"); /** * Subject Key Identifier */ public static final ASN1ObjectIdentifier subjectKeyIdentifier = new ASN1ObjectIdentifier("2.5.29.14"); /** * Key Usage */ public static final ASN1ObjectIdentifier keyUsage = new ASN1ObjectIdentifier("2.5.29.15"); /** * Private Key Usage Period */ public static final ASN1ObjectIdentifier privateKeyUsagePeriod = new ASN1ObjectIdentifier("2.5.29.16"); /** * Subject Alternative Name */ public static final ASN1ObjectIdentifier subjectAlternativeName = new ASN1ObjectIdentifier("2.5.29.17"); /** * Issuer Alternative Name */ public static final ASN1ObjectIdentifier issuerAlternativeName = new ASN1ObjectIdentifier("2.5.29.18"); /** * Basic Constraints */ public static final ASN1ObjectIdentifier basicConstraints = new ASN1ObjectIdentifier("2.5.29.19"); /** * CRL Number */ public static final ASN1ObjectIdentifier cRLNumber = new ASN1ObjectIdentifier("2.5.29.20"); /** * Reason code */ public static final ASN1ObjectIdentifier reasonCode = new ASN1ObjectIdentifier("2.5.29.21"); /** * Hold Instruction Code */ public static final ASN1ObjectIdentifier instructionCode = new ASN1ObjectIdentifier("2.5.29.23"); /** * Invalidity Date */ public static final ASN1ObjectIdentifier invalidityDate = new ASN1ObjectIdentifier("2.5.29.24"); /** * Delta CRL indicator */ public static final ASN1ObjectIdentifier deltaCRLIndicator = new ASN1ObjectIdentifier("2.5.29.27"); /** * Issuing Distribution Point */ public static final ASN1ObjectIdentifier issuingDistributionPoint = new ASN1ObjectIdentifier("2.5.29.28"); /** * Certificate Issuer */ public static final ASN1ObjectIdentifier certificateIssuer = new ASN1ObjectIdentifier("2.5.29.29"); /** * Name Constraints */ public static final ASN1ObjectIdentifier nameConstraints = new ASN1ObjectIdentifier("2.5.29.30"); /** * CRL Distribution Points */ public static final ASN1ObjectIdentifier cRLDistributionPoints = new ASN1ObjectIdentifier("2.5.29.31"); /** * Certificate Policies */ public static final ASN1ObjectIdentifier certificatePolicies = new ASN1ObjectIdentifier("2.5.29.32"); /** * Policy Mappings */ public static final ASN1ObjectIdentifier policyMappings = new ASN1ObjectIdentifier("2.5.29.33"); /** * Authority Key Identifier */ public static final ASN1ObjectIdentifier authorityKeyIdentifier = new ASN1ObjectIdentifier("2.5.29.35"); /** * Policy Constraints */ public static final ASN1ObjectIdentifier policyConstraints = new ASN1ObjectIdentifier("2.5.29.36"); /** * Extended Key Usage */ public static final ASN1ObjectIdentifier extendedKeyUsage = new ASN1ObjectIdentifier("2.5.29.37"); /** * Freshest CRL */ public static final ASN1ObjectIdentifier freshestCRL = new ASN1ObjectIdentifier("2.5.29.46"); /** * Inhibit Any Policy */ public static final ASN1ObjectIdentifier inhibitAnyPolicy = new ASN1ObjectIdentifier("2.5.29.54"); /** * Authority Info Access */ public static final ASN1ObjectIdentifier authorityInfoAccess = new ASN1ObjectIdentifier("1.3.6.1.5.5.7.1.1"); /** * Subject Info Access */ public static final ASN1ObjectIdentifier subjectInfoAccess = new ASN1ObjectIdentifier("1.3.6.1.5.5.7.1.11"); /** * Logo Type */ public static final ASN1ObjectIdentifier logoType = new ASN1ObjectIdentifier("1.3.6.1.5.5.7.1.12"); /** * BiometricInfo */ public static final ASN1ObjectIdentifier biometricInfo = new ASN1ObjectIdentifier("1.3.6.1.5.5.7.1.2"); /** * QCStatements */ public static final ASN1ObjectIdentifier qCStatements = new ASN1ObjectIdentifier("1.3.6.1.5.5.7.1.3"); /** * Audit identity extension in attribute certificates. */ public static final ASN1ObjectIdentifier auditIdentity = new ASN1ObjectIdentifier("1.3.6.1.5.5.7.1.4"); /** * NoRevAvail extension in attribute certificates. */ public static final ASN1ObjectIdentifier noRevAvail = new ASN1ObjectIdentifier("2.5.29.56"); /** * TargetInformation extension in attribute certificates. */ public static final ASN1ObjectIdentifier targetInformation = new ASN1ObjectIdentifier("2.5.29.55"); boolean critical; ASN1OctetString value; public X509Extension( DERBoolean critical, ASN1OctetString value) { this.critical = critical.isTrue(); this.value = value; } public X509Extension( boolean critical, ASN1OctetString value) { this.critical = critical; this.value = value; } public boolean isCritical() { return critical; } public ASN1OctetString getValue() { return value; } public ASN1Encodable getParsedValue() { return convertValueToObject(this); } public int hashCode() { if (this.isCritical()) { return this.getValue().hashCode(); } return ~this.getValue().hashCode(); } public boolean equals( Object o) { if (!(o instanceof X509Extension)) { return false; } X509Extension other = (X509Extension)o; return other.getValue().equals(this.getValue()) && (other.isCritical() == this.isCritical()); } /** * Convert the value of the passed in extension to an object * @param ext the extension to parse * @return the object the value string contains * @exception IllegalArgumentException if conversion is not possible */ public static ASN1Primitive convertValueToObject( X509Extension ext) throws IllegalArgumentException { try { return ASN1Primitive.fromByteArray(ext.getValue().getOctets()); } catch (IOException e) { throw new IllegalArgumentException("can't convert extension: " + e); } } } bouncycastle-1.49.orig/src/org/bouncycastle/asn1/x509/AccessDescription.java0000644000175000017500000000476311725023645026340 0ustar ebourgebourgpackage org.bouncycastle.asn1.x509; import org.bouncycastle.asn1.ASN1EncodableVector; import org.bouncycastle.asn1.ASN1Object; import org.bouncycastle.asn1.ASN1ObjectIdentifier; import org.bouncycastle.asn1.ASN1Primitive; import org.bouncycastle.asn1.ASN1Sequence; import org.bouncycastle.asn1.DERSequence; /** * The AccessDescription object. *
     * AccessDescription  ::=  SEQUENCE {
     *       accessMethod          OBJECT IDENTIFIER,
     *       accessLocation        GeneralName  }
     * 
    */ public class AccessDescription extends ASN1Object { public final static ASN1ObjectIdentifier id_ad_caIssuers = new ASN1ObjectIdentifier("1.3.6.1.5.5.7.48.2"); public final static ASN1ObjectIdentifier id_ad_ocsp = new ASN1ObjectIdentifier("1.3.6.1.5.5.7.48.1"); ASN1ObjectIdentifier accessMethod = null; GeneralName accessLocation = null; public static AccessDescription getInstance( Object obj) { if (obj instanceof AccessDescription) { return (AccessDescription)obj; } else if (obj != null) { return new AccessDescription(ASN1Sequence.getInstance(obj)); } return null; } private AccessDescription( ASN1Sequence seq) { if (seq.size() != 2) { throw new IllegalArgumentException("wrong number of elements in sequence"); } accessMethod = ASN1ObjectIdentifier.getInstance(seq.getObjectAt(0)); accessLocation = GeneralName.getInstance(seq.getObjectAt(1)); } /** * create an AccessDescription with the oid and location provided. */ public AccessDescription( ASN1ObjectIdentifier oid, GeneralName location) { accessMethod = oid; accessLocation = location; } /** * * @return the access method. */ public ASN1ObjectIdentifier getAccessMethod() { return accessMethod; } /** * * @return the access location */ public GeneralName getAccessLocation() { return accessLocation; } public ASN1Primitive toASN1Primitive() { ASN1EncodableVector accessDescription = new ASN1EncodableVector(); accessDescription.add(accessMethod); accessDescription.add(accessLocation); return new DERSequence(accessDescription); } public String toString() { return ("AccessDescription: Oid(" + this.accessMethod.getId() + ")"); } } bouncycastle-1.49.orig/src/org/bouncycastle/asn1/x509/GeneralNamesBuilder.java0000644000175000017500000000140612121754054026566 0ustar ebourgebourgpackage org.bouncycastle.asn1.x509; import java.util.Vector; public class GeneralNamesBuilder { private Vector names = new Vector(); public GeneralNamesBuilder addNames(GeneralNames names) { GeneralName[] n = names.getNames(); for (int i = 0; i != n.length; i++) { this.names.addElement(n[i]); } return this; } public GeneralNamesBuilder addName(GeneralName name) { names.addElement(name); return this; } public GeneralNames build() { GeneralName[] tmp = new GeneralName[names.size()]; for (int i = 0; i != tmp.length; i++) { tmp[i] = (GeneralName)names.elementAt(i); } return new GeneralNames(tmp); } } bouncycastle-1.49.orig/src/org/bouncycastle/asn1/x509/GeneralSubtree.java0000644000175000017500000001253111725023716025631 0ustar ebourgebourgpackage org.bouncycastle.asn1.x509; import java.math.BigInteger; import org.bouncycastle.asn1.ASN1EncodableVector; import org.bouncycastle.asn1.ASN1Integer; import org.bouncycastle.asn1.ASN1Object; import org.bouncycastle.asn1.ASN1Primitive; import org.bouncycastle.asn1.ASN1Sequence; import org.bouncycastle.asn1.ASN1TaggedObject; import org.bouncycastle.asn1.DERSequence; import org.bouncycastle.asn1.DERTaggedObject; /** * Class for containing a restriction object subtrees in NameConstraints. See * RFC 3280. * *
     *       
     *       GeneralSubtree ::= SEQUENCE 
     *       {
     *         base                    GeneralName,
     *         minimum         [0]     BaseDistance DEFAULT 0,
     *         maximum         [1]     BaseDistance OPTIONAL 
     *       }
     * 
    * * @see org.bouncycastle.asn1.x509.NameConstraints * */ public class GeneralSubtree extends ASN1Object { private static final BigInteger ZERO = BigInteger.valueOf(0); private GeneralName base; private ASN1Integer minimum; private ASN1Integer maximum; private GeneralSubtree( ASN1Sequence seq) { base = GeneralName.getInstance(seq.getObjectAt(0)); switch (seq.size()) { case 1: break; case 2: ASN1TaggedObject o = ASN1TaggedObject.getInstance(seq.getObjectAt(1)); switch (o.getTagNo()) { case 0: minimum = ASN1Integer.getInstance(o, false); break; case 1: maximum = ASN1Integer.getInstance(o, false); break; default: throw new IllegalArgumentException("Bad tag number: " + o.getTagNo()); } break; case 3: { { ASN1TaggedObject oMin = ASN1TaggedObject.getInstance(seq.getObjectAt(1)); if (oMin.getTagNo() != 0) { throw new IllegalArgumentException("Bad tag number for 'minimum': " + oMin.getTagNo()); } minimum = ASN1Integer.getInstance(oMin, false); } { ASN1TaggedObject oMax = ASN1TaggedObject.getInstance(seq.getObjectAt(2)); if (oMax.getTagNo() != 1) { throw new IllegalArgumentException("Bad tag number for 'maximum': " + oMax.getTagNo()); } maximum = ASN1Integer.getInstance(oMax, false); } break; } default: throw new IllegalArgumentException("Bad sequence size: " + seq.size()); } } /** * Constructor from a given details. * * According RFC 3280, the minimum and maximum fields are not used with any * name forms, thus minimum MUST be zero, and maximum MUST be absent. *

    * If minimum is null, zero is assumed, if * maximum is null, maximum is absent. * * @param base * A restriction. * @param minimum * Minimum * * @param maximum * Maximum */ public GeneralSubtree( GeneralName base, BigInteger minimum, BigInteger maximum) { this.base = base; if (maximum != null) { this.maximum = new ASN1Integer(maximum); } if (minimum == null) { this.minimum = null; } else { this.minimum = new ASN1Integer(minimum); } } public GeneralSubtree(GeneralName base) { this(base, null, null); } public static GeneralSubtree getInstance( ASN1TaggedObject o, boolean explicit) { return new GeneralSubtree(ASN1Sequence.getInstance(o, explicit)); } public static GeneralSubtree getInstance( Object obj) { if (obj == null) { return null; } if (obj instanceof GeneralSubtree) { return (GeneralSubtree) obj; } return new GeneralSubtree(ASN1Sequence.getInstance(obj)); } public GeneralName getBase() { return base; } public BigInteger getMinimum() { if (minimum == null) { return ZERO; } return minimum.getValue(); } public BigInteger getMaximum() { if (maximum == null) { return null; } return maximum.getValue(); } /** * Produce an object suitable for an ASN1OutputStream. * * Returns: * *

         *       GeneralSubtree ::= SEQUENCE 
         *       {
         *         base                    GeneralName,
         *         minimum         [0]     BaseDistance DEFAULT 0,
         *         maximum         [1]     BaseDistance OPTIONAL 
         *       }
         * 
    * * @return a ASN1Primitive */ public ASN1Primitive toASN1Primitive() { ASN1EncodableVector v = new ASN1EncodableVector(); v.add(base); if (minimum != null && !minimum.getValue().equals(ZERO)) { v.add(new DERTaggedObject(false, 0, minimum)); } if (maximum != null) { v.add(new DERTaggedObject(false, 1, maximum)); } return new DERSequence(v); } } bouncycastle-1.49.orig/src/org/bouncycastle/asn1/x509/X509ExtensionsGenerator.java0000644000175000017500000000633311724301472027316 0ustar ebourgebourgpackage org.bouncycastle.asn1.x509; import java.io.IOException; import java.util.Hashtable; import java.util.Vector; import org.bouncycastle.asn1.ASN1Encodable; import org.bouncycastle.asn1.ASN1Encoding; import org.bouncycastle.asn1.ASN1ObjectIdentifier; import org.bouncycastle.asn1.DERObjectIdentifier; import org.bouncycastle.asn1.DEROctetString; /** * Generator for X.509 extensions * @deprecated use org.bouncycastle.asn1.x509.ExtensionsGenerator */ public class X509ExtensionsGenerator { private Hashtable extensions = new Hashtable(); private Vector extOrdering = new Vector(); /** * Reset the generator */ public void reset() { extensions = new Hashtable(); extOrdering = new Vector(); } /** * @deprecated use ASN1ObjectIdentifier */ public void addExtension( DERObjectIdentifier oid, boolean critical, ASN1Encodable value) { addExtension(new ASN1ObjectIdentifier(oid.getId()), critical, value); } /** * @deprecated use ASN1ObjectIdentifier */ public void addExtension( DERObjectIdentifier oid, boolean critical, byte[] value) { addExtension(new ASN1ObjectIdentifier(oid.getId()), critical, value); } /** * Add an extension with the given oid and the passed in value to be included * in the OCTET STRING associated with the extension. * * @param oid OID for the extension. * @param critical true if critical, false otherwise. * @param value the ASN.1 object to be included in the extension. */ public void addExtension( ASN1ObjectIdentifier oid, boolean critical, ASN1Encodable value) { try { this.addExtension(oid, critical, value.toASN1Primitive().getEncoded(ASN1Encoding.DER)); } catch (IOException e) { throw new IllegalArgumentException("error encoding value: " + e); } } /** * Add an extension with the given oid and the passed in byte array to be wrapped in the * OCTET STRING associated with the extension. * * @param oid OID for the extension. * @param critical true if critical, false otherwise. * @param value the byte array to be wrapped. */ public void addExtension( ASN1ObjectIdentifier oid, boolean critical, byte[] value) { if (extensions.containsKey(oid)) { throw new IllegalArgumentException("extension " + oid + " already added"); } extOrdering.addElement(oid); extensions.put(oid, new X509Extension(critical, new DEROctetString(value))); } /** * Return true if there are no extension present in this generator. * * @return true if empty, false otherwise */ public boolean isEmpty() { return extOrdering.isEmpty(); } /** * Generate an X509Extensions object based on the current state of the generator. * * @return an X09Extensions object. */ public X509Extensions generate() { return new X509Extensions(extOrdering, extensions); } } bouncycastle-1.49.orig/src/org/bouncycastle/asn1/x509/X509AttributeIdentifiers.java0000644000175000017500000000265211726010374027441 0ustar ebourgebourgpackage org.bouncycastle.asn1.x509; import org.bouncycastle.asn1.ASN1ObjectIdentifier; public interface X509AttributeIdentifiers { /** * @deprecated use id_at_role */ static final ASN1ObjectIdentifier RoleSyntax = new ASN1ObjectIdentifier("2.5.4.72"); static final ASN1ObjectIdentifier id_pe_ac_auditIdentity = X509ObjectIdentifiers.id_pe.branch("4"); static final ASN1ObjectIdentifier id_pe_aaControls = X509ObjectIdentifiers.id_pe.branch("6"); static final ASN1ObjectIdentifier id_pe_ac_proxying = X509ObjectIdentifiers.id_pe.branch("10"); static final ASN1ObjectIdentifier id_ce_targetInformation= X509ObjectIdentifiers.id_ce.branch("55"); static final ASN1ObjectIdentifier id_aca = X509ObjectIdentifiers.id_pkix.branch("10"); static final ASN1ObjectIdentifier id_aca_authenticationInfo = id_aca.branch("1"); static final ASN1ObjectIdentifier id_aca_accessIdentity = id_aca.branch("2"); static final ASN1ObjectIdentifier id_aca_chargingIdentity = id_aca.branch("3"); static final ASN1ObjectIdentifier id_aca_group = id_aca.branch("4"); // { id-aca 5 } is reserved static final ASN1ObjectIdentifier id_aca_encAttrs = id_aca.branch("6"); static final ASN1ObjectIdentifier id_at_role = new ASN1ObjectIdentifier("2.5.4.72"); static final ASN1ObjectIdentifier id_at_clearance = new ASN1ObjectIdentifier("2.5.1.5.55"); } bouncycastle-1.49.orig/src/org/bouncycastle/asn1/x509/qualified/0000755000175000017500000000000012152033551024011 5ustar ebourgebourgbouncycastle-1.49.orig/src/org/bouncycastle/asn1/x509/qualified/RFC3739QCObjectIdentifiers.java0000644000175000017500000000071011501126443031353 0ustar ebourgebourgpackage org.bouncycastle.asn1.x509.qualified; import org.bouncycastle.asn1.ASN1ObjectIdentifier; public interface RFC3739QCObjectIdentifiers { // // base id // static final ASN1ObjectIdentifier id_qcs = new ASN1ObjectIdentifier("1.3.6.1.5.5.7.11"); static final ASN1ObjectIdentifier id_qcs_pkixQCSyntax_v1 = id_qcs.branch("1"); static final ASN1ObjectIdentifier id_qcs_pkixQCSyntax_v2 = id_qcs.branch("2"); } bouncycastle-1.49.orig/src/org/bouncycastle/asn1/x509/qualified/MonetaryValue.java0000644000175000017500000000451511724561171027464 0ustar ebourgebourgpackage org.bouncycastle.asn1.x509.qualified; import java.math.BigInteger; import java.util.Enumeration; import org.bouncycastle.asn1.ASN1EncodableVector; import org.bouncycastle.asn1.ASN1Integer; import org.bouncycastle.asn1.ASN1Object; import org.bouncycastle.asn1.ASN1Primitive; import org.bouncycastle.asn1.ASN1Sequence; import org.bouncycastle.asn1.DERSequence; /** * The MonetaryValue object. *
     * MonetaryValue  ::=  SEQUENCE {
     *       currency              Iso4217CurrencyCode,
     *       amount               INTEGER, 
     *       exponent             INTEGER }
     * -- value = amount * 10^exponent
     * 
    */ public class MonetaryValue extends ASN1Object { private Iso4217CurrencyCode currency; private ASN1Integer amount; private ASN1Integer exponent; public static MonetaryValue getInstance( Object obj) { if (obj instanceof MonetaryValue) { return (MonetaryValue)obj; } if (obj != null) { return new MonetaryValue(ASN1Sequence.getInstance(obj)); } return null; } private MonetaryValue( ASN1Sequence seq) { Enumeration e = seq.getObjects(); // currency currency = Iso4217CurrencyCode.getInstance(e.nextElement()); // hashAlgorithm amount = ASN1Integer.getInstance(e.nextElement()); // exponent exponent = ASN1Integer.getInstance(e.nextElement()); } public MonetaryValue( Iso4217CurrencyCode currency, int amount, int exponent) { this.currency = currency; this.amount = new ASN1Integer(amount); this.exponent = new ASN1Integer(exponent); } public Iso4217CurrencyCode getCurrency() { return currency; } public BigInteger getAmount() { return amount.getValue(); } public BigInteger getExponent() { return exponent.getValue(); } public ASN1Primitive toASN1Primitive() { ASN1EncodableVector seq = new ASN1EncodableVector(); seq.add(currency); seq.add(amount); seq.add(exponent); return new DERSequence(seq); } } bouncycastle-1.49.orig/src/org/bouncycastle/asn1/x509/qualified/Iso4217CurrencyCode.java0000644000175000017500000000530411706151655030246 0ustar ebourgebourgpackage org.bouncycastle.asn1.x509.qualified; import org.bouncycastle.asn1.ASN1Choice; import org.bouncycastle.asn1.ASN1Encodable; import org.bouncycastle.asn1.ASN1Integer; import org.bouncycastle.asn1.ASN1Object; import org.bouncycastle.asn1.ASN1Primitive; import org.bouncycastle.asn1.DERPrintableString; /** * The Iso4217CurrencyCode object. *
     * Iso4217CurrencyCode  ::=  CHOICE {
     *       alphabetic              PrintableString (SIZE 3), --Recommended
     *       numeric              INTEGER (1..999) }
     * -- Alphabetic or numeric currency code as defined in ISO 4217
     * -- It is recommended that the Alphabetic form is used
     * 
    */ public class Iso4217CurrencyCode extends ASN1Object implements ASN1Choice { final int ALPHABETIC_MAXSIZE = 3; final int NUMERIC_MINSIZE = 1; final int NUMERIC_MAXSIZE = 999; ASN1Encodable obj; int numeric; public static Iso4217CurrencyCode getInstance( Object obj) { if (obj == null || obj instanceof Iso4217CurrencyCode) { return (Iso4217CurrencyCode)obj; } if (obj instanceof ASN1Integer) { ASN1Integer numericobj = ASN1Integer.getInstance(obj); int numeric = numericobj.getValue().intValue(); return new Iso4217CurrencyCode(numeric); } else if (obj instanceof DERPrintableString) { DERPrintableString alphabetic = DERPrintableString.getInstance(obj); return new Iso4217CurrencyCode(alphabetic.getString()); } throw new IllegalArgumentException("unknown object in getInstance"); } public Iso4217CurrencyCode( int numeric) { if (numeric > NUMERIC_MAXSIZE || numeric < NUMERIC_MINSIZE) { throw new IllegalArgumentException("wrong size in numeric code : not in (" +NUMERIC_MINSIZE +".."+ NUMERIC_MAXSIZE +")"); } obj = new ASN1Integer(numeric); } public Iso4217CurrencyCode( String alphabetic) { if (alphabetic.length() > ALPHABETIC_MAXSIZE) { throw new IllegalArgumentException("wrong size in alphabetic code : max size is " + ALPHABETIC_MAXSIZE); } obj = new DERPrintableString(alphabetic); } public boolean isAlphabetic() { return obj instanceof DERPrintableString; } public String getAlphabetic() { return ((DERPrintableString)obj).getString(); } public int getNumeric() { return ((ASN1Integer)obj).getValue().intValue(); } public ASN1Primitive toASN1Primitive() { return obj.toASN1Primitive(); } } bouncycastle-1.49.orig/src/org/bouncycastle/asn1/x509/qualified/TypeOfBiometricData.java0000644000175000017500000000514011706152174030521 0ustar ebourgebourgpackage org.bouncycastle.asn1.x509.qualified; import org.bouncycastle.asn1.ASN1Choice; import org.bouncycastle.asn1.ASN1Encodable; import org.bouncycastle.asn1.ASN1Integer; import org.bouncycastle.asn1.ASN1Object; import org.bouncycastle.asn1.ASN1ObjectIdentifier; import org.bouncycastle.asn1.ASN1Primitive; /** * The TypeOfBiometricData object. *
     * TypeOfBiometricData ::= CHOICE {
     *   predefinedBiometricType   PredefinedBiometricType,
     *   biometricDataOid          OBJECT IDENTIFIER }
     *
     * PredefinedBiometricType ::= INTEGER {
     *   picture(0),handwritten-signature(1)}
     *   (picture|handwritten-signature)
     * 
    */ public class TypeOfBiometricData extends ASN1Object implements ASN1Choice { public static final int PICTURE = 0; public static final int HANDWRITTEN_SIGNATURE = 1; ASN1Encodable obj; public static TypeOfBiometricData getInstance(Object obj) { if (obj == null || obj instanceof TypeOfBiometricData) { return (TypeOfBiometricData)obj; } if (obj instanceof ASN1Integer) { ASN1Integer predefinedBiometricTypeObj = ASN1Integer.getInstance(obj); int predefinedBiometricType = predefinedBiometricTypeObj.getValue().intValue(); return new TypeOfBiometricData(predefinedBiometricType); } else if (obj instanceof ASN1ObjectIdentifier) { ASN1ObjectIdentifier BiometricDataID = ASN1ObjectIdentifier.getInstance(obj); return new TypeOfBiometricData(BiometricDataID); } throw new IllegalArgumentException("unknown object in getInstance"); } public TypeOfBiometricData(int predefinedBiometricType) { if (predefinedBiometricType == PICTURE || predefinedBiometricType == HANDWRITTEN_SIGNATURE) { obj = new ASN1Integer(predefinedBiometricType); } else { throw new IllegalArgumentException("unknow PredefinedBiometricType : " + predefinedBiometricType); } } public TypeOfBiometricData(ASN1ObjectIdentifier BiometricDataID) { obj = BiometricDataID; } public boolean isPredefined() { return obj instanceof ASN1Integer; } public int getPredefinedBiometricType() { return ((ASN1Integer)obj).getValue().intValue(); } public ASN1ObjectIdentifier getBiometricDataOid() { return (ASN1ObjectIdentifier)obj; } public ASN1Primitive toASN1Primitive() { return obj.toASN1Primitive(); } } bouncycastle-1.49.orig/src/org/bouncycastle/asn1/x509/qualified/QCStatement.java0000644000175000017500000000446611706146040027060 0ustar ebourgebourgpackage org.bouncycastle.asn1.x509.qualified; import java.util.Enumeration; import org.bouncycastle.asn1.ASN1Encodable; import org.bouncycastle.asn1.ASN1EncodableVector; import org.bouncycastle.asn1.ASN1Object; import org.bouncycastle.asn1.ASN1ObjectIdentifier; import org.bouncycastle.asn1.ASN1Primitive; import org.bouncycastle.asn1.ASN1Sequence; import org.bouncycastle.asn1.DERSequence; /** * The QCStatement object. *
     * QCStatement ::= SEQUENCE {
     *   statementId        OBJECT IDENTIFIER,
     *   statementInfo      ANY DEFINED BY statementId OPTIONAL} 
     * 
    */ public class QCStatement extends ASN1Object implements ETSIQCObjectIdentifiers, RFC3739QCObjectIdentifiers { ASN1ObjectIdentifier qcStatementId; ASN1Encodable qcStatementInfo; public static QCStatement getInstance( Object obj) { if (obj instanceof QCStatement) { return (QCStatement)obj; } if (obj != null) { return new QCStatement(ASN1Sequence.getInstance(obj)); } return null; } private QCStatement( ASN1Sequence seq) { Enumeration e = seq.getObjects(); // qcStatementId qcStatementId = ASN1ObjectIdentifier.getInstance(e.nextElement()); // qcstatementInfo if (e.hasMoreElements()) { qcStatementInfo = (ASN1Encodable) e.nextElement(); } } public QCStatement( ASN1ObjectIdentifier qcStatementId) { this.qcStatementId = qcStatementId; this.qcStatementInfo = null; } public QCStatement( ASN1ObjectIdentifier qcStatementId, ASN1Encodable qcStatementInfo) { this.qcStatementId = qcStatementId; this.qcStatementInfo = qcStatementInfo; } public ASN1ObjectIdentifier getStatementId() { return qcStatementId; } public ASN1Encodable getStatementInfo() { return qcStatementInfo; } public ASN1Primitive toASN1Primitive() { ASN1EncodableVector seq = new ASN1EncodableVector(); seq.add(qcStatementId); if (qcStatementInfo != null) { seq.add(qcStatementInfo); } return new DERSequence(seq); } } bouncycastle-1.49.orig/src/org/bouncycastle/asn1/x509/qualified/ETSIQCObjectIdentifiers.java0000644000175000017500000000124411501126443031162 0ustar ebourgebourgpackage org.bouncycastle.asn1.x509.qualified; import org.bouncycastle.asn1.ASN1ObjectIdentifier; public interface ETSIQCObjectIdentifiers { // // base id // static final ASN1ObjectIdentifier id_etsi_qcs = new ASN1ObjectIdentifier("0.4.0.1862.1"); static final ASN1ObjectIdentifier id_etsi_qcs_QcCompliance = id_etsi_qcs.branch("1"); static final ASN1ObjectIdentifier id_etsi_qcs_LimiteValue = id_etsi_qcs.branch("2"); static final ASN1ObjectIdentifier id_etsi_qcs_RetentionPeriod = id_etsi_qcs.branch("3"); static final ASN1ObjectIdentifier id_etsi_qcs_QcSSCD = id_etsi_qcs.branch("4"); } bouncycastle-1.49.orig/src/org/bouncycastle/asn1/x509/qualified/SemanticsInformation.java0000644000175000017500000000771311724561172031031 0ustar ebourgebourgpackage org.bouncycastle.asn1.x509.qualified; import java.util.Enumeration; import org.bouncycastle.asn1.ASN1EncodableVector; import org.bouncycastle.asn1.ASN1Object; import org.bouncycastle.asn1.ASN1ObjectIdentifier; import org.bouncycastle.asn1.ASN1Primitive; import org.bouncycastle.asn1.ASN1Sequence; import org.bouncycastle.asn1.DERSequence; import org.bouncycastle.asn1.x509.GeneralName; /** * The SemanticsInformation object. *
     *       SemanticsInformation ::= SEQUENCE {
     *         semanticsIdentifier        OBJECT IDENTIFIER   OPTIONAL,
     *         nameRegistrationAuthorities NameRegistrationAuthorities
     *                                                         OPTIONAL }
     *         (WITH COMPONENTS {..., semanticsIdentifier PRESENT}|
     *          WITH COMPONENTS {..., nameRegistrationAuthorities PRESENT})
     *
     *     NameRegistrationAuthorities ::=  SEQUENCE SIZE (1..MAX) OF
     *         GeneralName
     * 
    */ public class SemanticsInformation extends ASN1Object { private ASN1ObjectIdentifier semanticsIdentifier; private GeneralName[] nameRegistrationAuthorities; public static SemanticsInformation getInstance(Object obj) { if (obj instanceof SemanticsInformation) { return (SemanticsInformation)obj; } if (obj != null) { return new SemanticsInformation(ASN1Sequence.getInstance(obj)); } return null; } private SemanticsInformation(ASN1Sequence seq) { Enumeration e = seq.getObjects(); if (seq.size() < 1) { throw new IllegalArgumentException("no objects in SemanticsInformation"); } Object object = e.nextElement(); if (object instanceof ASN1ObjectIdentifier) { semanticsIdentifier = ASN1ObjectIdentifier.getInstance(object); if (e.hasMoreElements()) { object = e.nextElement(); } else { object = null; } } if (object != null) { ASN1Sequence generalNameSeq = ASN1Sequence.getInstance(object); nameRegistrationAuthorities = new GeneralName[generalNameSeq.size()]; for (int i= 0; i < generalNameSeq.size(); i++) { nameRegistrationAuthorities[i] = GeneralName.getInstance(generalNameSeq.getObjectAt(i)); } } } public SemanticsInformation( ASN1ObjectIdentifier semanticsIdentifier, GeneralName[] generalNames) { this.semanticsIdentifier = semanticsIdentifier; this.nameRegistrationAuthorities = generalNames; } public SemanticsInformation(ASN1ObjectIdentifier semanticsIdentifier) { this.semanticsIdentifier = semanticsIdentifier; this.nameRegistrationAuthorities = null; } public SemanticsInformation(GeneralName[] generalNames) { this.semanticsIdentifier = null; this.nameRegistrationAuthorities = generalNames; } public ASN1ObjectIdentifier getSemanticsIdentifier() { return semanticsIdentifier; } public GeneralName[] getNameRegistrationAuthorities() { return nameRegistrationAuthorities; } public ASN1Primitive toASN1Primitive() { ASN1EncodableVector seq = new ASN1EncodableVector(); if (this.semanticsIdentifier != null) { seq.add(semanticsIdentifier); } if (this.nameRegistrationAuthorities != null) { ASN1EncodableVector seqname = new ASN1EncodableVector(); for (int i = 0; i < nameRegistrationAuthorities.length; i++) { seqname.add(nameRegistrationAuthorities[i]); } seq.add(new DERSequence(seqname)); } return new DERSequence(seq); } } bouncycastle-1.49.orig/src/org/bouncycastle/asn1/x509/qualified/package.html0000644000175000017500000000020110333062470026264 0ustar ebourgebourg Support classes useful for encoding and processing messages based around RFC3739 bouncycastle-1.49.orig/src/org/bouncycastle/asn1/x509/qualified/BiometricData.java0000644000175000017500000000657711706151655027414 0ustar ebourgebourgpackage org.bouncycastle.asn1.x509.qualified; import java.util.Enumeration; import org.bouncycastle.asn1.ASN1EncodableVector; import org.bouncycastle.asn1.ASN1Object; import org.bouncycastle.asn1.ASN1OctetString; import org.bouncycastle.asn1.ASN1Primitive; import org.bouncycastle.asn1.ASN1Sequence; import org.bouncycastle.asn1.DERIA5String; import org.bouncycastle.asn1.DERSequence; import org.bouncycastle.asn1.x509.AlgorithmIdentifier; /** * The BiometricData object. *
     * BiometricData  ::=  SEQUENCE {
     *       typeOfBiometricData  TypeOfBiometricData,
     *       hashAlgorithm        AlgorithmIdentifier,
     *       biometricDataHash    OCTET STRING,
     *       sourceDataUri        IA5String OPTIONAL  }
     * 
    */ public class BiometricData extends ASN1Object { private TypeOfBiometricData typeOfBiometricData; private AlgorithmIdentifier hashAlgorithm; private ASN1OctetString biometricDataHash; private DERIA5String sourceDataUri; public static BiometricData getInstance( Object obj) { if (obj instanceof BiometricData) { return (BiometricData)obj; } if (obj != null) { return new BiometricData(ASN1Sequence.getInstance(obj)); } return null; } private BiometricData(ASN1Sequence seq) { Enumeration e = seq.getObjects(); // typeOfBiometricData typeOfBiometricData = TypeOfBiometricData.getInstance(e.nextElement()); // hashAlgorithm hashAlgorithm = AlgorithmIdentifier.getInstance(e.nextElement()); // biometricDataHash biometricDataHash = ASN1OctetString.getInstance(e.nextElement()); // sourceDataUri if (e.hasMoreElements()) { sourceDataUri = DERIA5String.getInstance(e.nextElement()); } } public BiometricData( TypeOfBiometricData typeOfBiometricData, AlgorithmIdentifier hashAlgorithm, ASN1OctetString biometricDataHash, DERIA5String sourceDataUri) { this.typeOfBiometricData = typeOfBiometricData; this.hashAlgorithm = hashAlgorithm; this.biometricDataHash = biometricDataHash; this.sourceDataUri = sourceDataUri; } public BiometricData( TypeOfBiometricData typeOfBiometricData, AlgorithmIdentifier hashAlgorithm, ASN1OctetString biometricDataHash) { this.typeOfBiometricData = typeOfBiometricData; this.hashAlgorithm = hashAlgorithm; this.biometricDataHash = biometricDataHash; this.sourceDataUri = null; } public TypeOfBiometricData getTypeOfBiometricData() { return typeOfBiometricData; } public AlgorithmIdentifier getHashAlgorithm() { return hashAlgorithm; } public ASN1OctetString getBiometricDataHash() { return biometricDataHash; } public DERIA5String getSourceDataUri() { return sourceDataUri; } public ASN1Primitive toASN1Primitive() { ASN1EncodableVector seq = new ASN1EncodableVector(); seq.add(typeOfBiometricData); seq.add(hashAlgorithm); seq.add(biometricDataHash); if (sourceDataUri != null) { seq.add(sourceDataUri); } return new DERSequence(seq); } } bouncycastle-1.49.orig/src/org/bouncycastle/asn1/x509/UserNotice.java0000644000175000017500000000645311726005666025015 0ustar ebourgebourgpackage org.bouncycastle.asn1.x509; import org.bouncycastle.asn1.ASN1EncodableVector; import org.bouncycastle.asn1.ASN1Object; import org.bouncycastle.asn1.ASN1Primitive; import org.bouncycastle.asn1.ASN1Sequence; import org.bouncycastle.asn1.DERSequence; /** * UserNotice class, used in * CertificatePolicies X509 extensions (in policy * qualifiers). *
     * UserNotice ::= SEQUENCE {
     *      noticeRef        NoticeReference OPTIONAL,
     *      explicitText     DisplayText OPTIONAL}
     *
     * 
    * * @see PolicyQualifierId * @see PolicyInformation */ public class UserNotice extends ASN1Object { private NoticeReference noticeRef; private DisplayText explicitText; /** * Creates a new UserNotice instance. * * @param noticeRef a NoticeReference value * @param explicitText a DisplayText value */ public UserNotice( NoticeReference noticeRef, DisplayText explicitText) { this.noticeRef = noticeRef; this.explicitText = explicitText; } /** * Creates a new UserNotice instance. * * @param noticeRef a NoticeReference value * @param str the explicitText field as a String. */ public UserNotice( NoticeReference noticeRef, String str) { this(noticeRef, new DisplayText(str)); } /** * Creates a new UserNotice instance. *

    Useful from reconstructing a UserNotice instance * from its encodable/encoded form. * * @param as an ASN1Sequence value obtained from either * calling @{link toASN1Primitive()} for a UserNotice * instance or from parsing it from a DER-encoded stream. */ private UserNotice( ASN1Sequence as) { if (as.size() == 2) { noticeRef = NoticeReference.getInstance(as.getObjectAt(0)); explicitText = DisplayText.getInstance(as.getObjectAt(1)); } else if (as.size() == 1) { if (as.getObjectAt(0).toASN1Primitive() instanceof ASN1Sequence) { noticeRef = NoticeReference.getInstance(as.getObjectAt(0)); } else { explicitText = DisplayText.getInstance(as.getObjectAt(0)); } } else { throw new IllegalArgumentException("Bad sequence size: " + as.size()); } } public static UserNotice getInstance( Object obj) { if (obj instanceof UserNotice) { return (UserNotice)obj; } if (obj != null) { return new UserNotice(ASN1Sequence.getInstance(obj)); } return null; } public NoticeReference getNoticeRef() { return noticeRef; } public DisplayText getExplicitText() { return explicitText; } public ASN1Primitive toASN1Primitive() { ASN1EncodableVector av = new ASN1EncodableVector(); if (noticeRef != null) { av.add(noticeRef); } if (explicitText != null) { av.add(explicitText); } return new DERSequence(av); } } bouncycastle-1.49.orig/src/org/bouncycastle/asn1/x509/AttCertIssuer.java0000644000175000017500000000462412103442450025456 0ustar ebourgebourgpackage org.bouncycastle.asn1.x509; import org.bouncycastle.asn1.ASN1Choice; import org.bouncycastle.asn1.ASN1Encodable; import org.bouncycastle.asn1.ASN1Object; import org.bouncycastle.asn1.ASN1Primitive; import org.bouncycastle.asn1.ASN1Sequence; import org.bouncycastle.asn1.ASN1TaggedObject; import org.bouncycastle.asn1.DERTaggedObject; public class AttCertIssuer extends ASN1Object implements ASN1Choice { ASN1Encodable obj; ASN1Primitive choiceObj; public static AttCertIssuer getInstance( Object obj) { if (obj == null || obj instanceof AttCertIssuer) { return (AttCertIssuer)obj; } else if (obj instanceof V2Form) { return new AttCertIssuer(V2Form.getInstance(obj)); } else if (obj instanceof GeneralNames) { return new AttCertIssuer((GeneralNames)obj); } else if (obj instanceof ASN1TaggedObject) { return new AttCertIssuer(V2Form.getInstance((ASN1TaggedObject)obj, false)); } else if (obj instanceof ASN1Sequence) { return new AttCertIssuer(GeneralNames.getInstance(obj)); } throw new IllegalArgumentException("unknown object in factory: " + obj.getClass().getName()); } public static AttCertIssuer getInstance( ASN1TaggedObject obj, boolean explicit) { return getInstance(obj.getObject()); // must be explicitly tagged } /** * Don't use this one if you are trying to be RFC 3281 compliant. * Use it for v1 attribute certificates only. * * @param names our GeneralNames structure */ public AttCertIssuer( GeneralNames names) { obj = names; choiceObj = obj.toASN1Primitive(); } public AttCertIssuer( V2Form v2Form) { obj = v2Form; choiceObj = new DERTaggedObject(false, 0, obj); } public ASN1Encodable getIssuer() { return obj; } /** * Produce an object suitable for an ASN1OutputStream. *

         *  AttCertIssuer ::= CHOICE {
         *       v1Form   GeneralNames,  -- MUST NOT be used in this
         *                               -- profile
         *       v2Form   [0] V2Form     -- v2 only
         *  }
         * 
    */ public ASN1Primitive toASN1Primitive() { return choiceObj; } } bouncycastle-1.49.orig/src/org/bouncycastle/asn1/x509/TargetInformation.java0000644000175000017500000000615611625355266026373 0ustar ebourgebourgpackage org.bouncycastle.asn1.x509; import java.util.Enumeration; import org.bouncycastle.asn1.ASN1Object; import org.bouncycastle.asn1.ASN1Primitive; import org.bouncycastle.asn1.ASN1Sequence; import org.bouncycastle.asn1.DERSequence; /** * Target information extension for attributes certificates according to RFC * 3281. * *
     *           SEQUENCE OF Targets
     * 
    * */ public class TargetInformation extends ASN1Object { private ASN1Sequence targets; /** * Creates an instance of a TargetInformation from the given object. *

    * obj can be a TargetInformation or a {@link ASN1Sequence} * * @param obj The object. * @return A TargetInformation instance. * @throws IllegalArgumentException if the given object cannot be * interpreted as TargetInformation. */ public static TargetInformation getInstance(Object obj) { if (obj instanceof TargetInformation) { return (TargetInformation)obj; } else if (obj != null) { return new TargetInformation(ASN1Sequence.getInstance(obj)); } return null; } /** * Constructor from a ASN1Sequence. * * @param seq The ASN1Sequence. * @throws IllegalArgumentException if the sequence does not contain * correctly encoded Targets elements. */ private TargetInformation(ASN1Sequence seq) { targets = seq; } /** * Returns the targets in this target information extension. * * @return Returns the targets. */ public Targets[] getTargetsObjects() { Targets[] copy = new Targets[targets.size()]; int count = 0; for (Enumeration e = targets.getObjects(); e.hasMoreElements();) { copy[count++] = Targets.getInstance(e.nextElement()); } return copy; } /** * Constructs a target information from a single targets element. * According to RFC 3281 only one targets element must be produced. * * @param targets A Targets instance. */ public TargetInformation(Targets targets) { this.targets = new DERSequence(targets); } /** * According to RFC 3281 only one targets element must be produced. If * multiple targets are given they must be merged in * into one targets element. * * @param targets An array with {@link Targets}. */ public TargetInformation(Target[] targets) { this(new Targets(targets)); } /** * Produce an object suitable for an ASN1OutputStream. * * Returns: * *

         *          SEQUENCE OF Targets
         * 
    * *

    * According to RFC 3281 only one targets element must be produced. If * multiple targets are given in the constructor they are merged into one * targets element. If this was produced from a * {@link org.bouncycastle.asn1.ASN1Sequence} the encoding is kept. * * @return a ASN1Primitive */ public ASN1Primitive toASN1Primitive() { return targets; } } bouncycastle-1.49.orig/src/org/bouncycastle/asn1/x509/V2TBSCertListGenerator.java0000644000175000017500000001764012147753566027125 0ustar ebourgebourgpackage org.bouncycastle.asn1.x509; import java.io.IOException; import org.bouncycastle.asn1.ASN1EncodableVector; import org.bouncycastle.asn1.ASN1GeneralizedTime; import org.bouncycastle.asn1.ASN1Integer; import org.bouncycastle.asn1.ASN1Sequence; import org.bouncycastle.asn1.ASN1UTCTime; import org.bouncycastle.asn1.DEROctetString; import org.bouncycastle.asn1.DERSequence; import org.bouncycastle.asn1.DERTaggedObject; import org.bouncycastle.asn1.x500.X500Name; /** * Generator for Version 2 TBSCertList structures. *

     *  TBSCertList  ::=  SEQUENCE  {
     *       version                 Version OPTIONAL,
     *                                    -- if present, shall be v2
     *       signature               AlgorithmIdentifier,
     *       issuer                  Name,
     *       thisUpdate              Time,
     *       nextUpdate              Time OPTIONAL,
     *       revokedCertificates     SEQUENCE OF SEQUENCE  {
     *            userCertificate         CertificateSerialNumber,
     *            revocationDate          Time,
     *            crlEntryExtensions      Extensions OPTIONAL
     *                                          -- if present, shall be v2
     *                                 }  OPTIONAL,
     *       crlExtensions           [0]  EXPLICIT Extensions OPTIONAL
     *                                          -- if present, shall be v2
     *                                 }
     * 
    * * Note: This class may be subject to change */ public class V2TBSCertListGenerator { private ASN1Integer version = new ASN1Integer(1); private AlgorithmIdentifier signature; private X500Name issuer; private Time thisUpdate, nextUpdate=null; private Extensions extensions = null; private ASN1EncodableVector crlentries = new ASN1EncodableVector(); private final static ASN1Sequence[] reasons; static { reasons = new ASN1Sequence[11]; reasons[0] = createReasonExtension(CRLReason.unspecified); reasons[1] = createReasonExtension(CRLReason.keyCompromise); reasons[2] = createReasonExtension(CRLReason.cACompromise); reasons[3] = createReasonExtension(CRLReason.affiliationChanged); reasons[4] = createReasonExtension(CRLReason.superseded); reasons[5] = createReasonExtension(CRLReason.cessationOfOperation); reasons[6] = createReasonExtension(CRLReason.certificateHold); reasons[7] = createReasonExtension(7); // 7 -> unknown reasons[8] = createReasonExtension(CRLReason.removeFromCRL); reasons[9] = createReasonExtension(CRLReason.privilegeWithdrawn); reasons[10] = createReasonExtension(CRLReason.aACompromise); } public V2TBSCertListGenerator() { } public void setSignature( AlgorithmIdentifier signature) { this.signature = signature; } /** * @deprecated use X500Name method */ public void setIssuer( X509Name issuer) { this.issuer = X500Name.getInstance(issuer.toASN1Primitive()); } public void setIssuer(X500Name issuer) { this.issuer = issuer; } public void setThisUpdate( ASN1UTCTime thisUpdate) { this.thisUpdate = new Time(thisUpdate); } public void setNextUpdate( ASN1UTCTime nextUpdate) { this.nextUpdate = new Time(nextUpdate); } public void setThisUpdate( Time thisUpdate) { this.thisUpdate = thisUpdate; } public void setNextUpdate( Time nextUpdate) { this.nextUpdate = nextUpdate; } public void addCRLEntry( ASN1Sequence crlEntry) { crlentries.add(crlEntry); } public void addCRLEntry(ASN1Integer userCertificate, ASN1UTCTime revocationDate, int reason) { addCRLEntry(userCertificate, new Time(revocationDate), reason); } public void addCRLEntry(ASN1Integer userCertificate, Time revocationDate, int reason) { addCRLEntry(userCertificate, revocationDate, reason, null); } public void addCRLEntry(ASN1Integer userCertificate, Time revocationDate, int reason, ASN1GeneralizedTime invalidityDate) { if (reason != 0) { ASN1EncodableVector v = new ASN1EncodableVector(); if (reason < reasons.length) { if (reason < 0) { throw new IllegalArgumentException("invalid reason value: " + reason); } v.add(reasons[reason]); } else { v.add(createReasonExtension(reason)); } if (invalidityDate != null) { v.add(createInvalidityDateExtension(invalidityDate)); } internalAddCRLEntry(userCertificate, revocationDate, new DERSequence(v)); } else if (invalidityDate != null) { ASN1EncodableVector v = new ASN1EncodableVector(); v.add(createInvalidityDateExtension(invalidityDate)); internalAddCRLEntry(userCertificate, revocationDate, new DERSequence(v)); } else { addCRLEntry(userCertificate, revocationDate, null); } } private void internalAddCRLEntry(ASN1Integer userCertificate, Time revocationDate, ASN1Sequence extensions) { ASN1EncodableVector v = new ASN1EncodableVector(); v.add(userCertificate); v.add(revocationDate); if (extensions != null) { v.add(extensions); } addCRLEntry(new DERSequence(v)); } public void addCRLEntry(ASN1Integer userCertificate, Time revocationDate, Extensions extensions) { ASN1EncodableVector v = new ASN1EncodableVector(); v.add(userCertificate); v.add(revocationDate); if (extensions != null) { v.add(extensions); } addCRLEntry(new DERSequence(v)); } public void setExtensions( X509Extensions extensions) { setExtensions(Extensions.getInstance(extensions)); } public void setExtensions( Extensions extensions) { this.extensions = extensions; } public TBSCertList generateTBSCertList() { if ((signature == null) || (issuer == null) || (thisUpdate == null)) { throw new IllegalStateException("Not all mandatory fields set in V2 TBSCertList generator."); } ASN1EncodableVector v = new ASN1EncodableVector(); v.add(version); v.add(signature); v.add(issuer); v.add(thisUpdate); if (nextUpdate != null) { v.add(nextUpdate); } // Add CRLEntries if they exist if (crlentries.size() != 0) { v.add(new DERSequence(crlentries)); } if (extensions != null) { v.add(new DERTaggedObject(0, extensions)); } return new TBSCertList(new DERSequence(v)); } private static ASN1Sequence createReasonExtension(int reasonCode) { ASN1EncodableVector v = new ASN1EncodableVector(); CRLReason crlReason = CRLReason.lookup(reasonCode); try { v.add(Extension.reasonCode); v.add(new DEROctetString(crlReason.getEncoded())); } catch (IOException e) { throw new IllegalArgumentException("error encoding reason: " + e); } return new DERSequence(v); } private static ASN1Sequence createInvalidityDateExtension(ASN1GeneralizedTime invalidityDate) { ASN1EncodableVector v = new ASN1EncodableVector(); try { v.add(Extension.invalidityDate); v.add(new DEROctetString(invalidityDate.getEncoded())); } catch (IOException e) { throw new IllegalArgumentException("error encoding reason: " + e); } return new DERSequence(v); } } bouncycastle-1.49.orig/src/org/bouncycastle/asn1/x509/GeneralNames.java0000644000175000017500000000477512076416141025274 0ustar ebourgebourgpackage org.bouncycastle.asn1.x509; import org.bouncycastle.asn1.ASN1Object; import org.bouncycastle.asn1.ASN1ObjectIdentifier; import org.bouncycastle.asn1.ASN1Primitive; import org.bouncycastle.asn1.ASN1Sequence; import org.bouncycastle.asn1.ASN1TaggedObject; import org.bouncycastle.asn1.DERSequence; public class GeneralNames extends ASN1Object { private final GeneralName[] names; public static GeneralNames getInstance( Object obj) { if (obj instanceof GeneralNames) { return (GeneralNames)obj; } if (obj != null) { return new GeneralNames(ASN1Sequence.getInstance(obj)); } return null; } public static GeneralNames getInstance( ASN1TaggedObject obj, boolean explicit) { return getInstance(ASN1Sequence.getInstance(obj, explicit)); } public static GeneralNames fromExtensions(Extensions extensions, ASN1ObjectIdentifier extOID) { return GeneralNames.getInstance(extensions.getExtensionParsedValue(extOID)); } /** * Construct a GeneralNames object containing one GeneralName. * * @param name the name to be contained. */ public GeneralNames( GeneralName name) { this.names = new GeneralName[] { name }; } public GeneralNames( GeneralName[] names) { this.names = names; } private GeneralNames( ASN1Sequence seq) { this.names = new GeneralName[seq.size()]; for (int i = 0; i != seq.size(); i++) { names[i] = GeneralName.getInstance(seq.getObjectAt(i)); } } public GeneralName[] getNames() { GeneralName[] tmp = new GeneralName[names.length]; System.arraycopy(names, 0, tmp, 0, names.length); return tmp; } /** * Produce an object suitable for an ASN1OutputStream. *
         * GeneralNames ::= SEQUENCE SIZE {1..MAX} OF GeneralName
         * 
    */ public ASN1Primitive toASN1Primitive() { return new DERSequence(names); } public String toString() { StringBuffer buf = new StringBuffer(); String sep = System.getProperty("line.separator"); buf.append("GeneralNames:"); buf.append(sep); for (int i = 0; i != names.length; i++) { buf.append(" "); buf.append(names[i]); buf.append(sep); } return buf.toString(); } } bouncycastle-1.49.orig/src/org/bouncycastle/asn1/x509/TBSCertList.java0000644000175000017500000001736011725273323025032 0ustar ebourgebourgpackage org.bouncycastle.asn1.x509; import java.util.Enumeration; import org.bouncycastle.asn1.ASN1EncodableVector; import org.bouncycastle.asn1.ASN1Integer; import org.bouncycastle.asn1.ASN1Object; import org.bouncycastle.asn1.ASN1Primitive; import org.bouncycastle.asn1.ASN1Sequence; import org.bouncycastle.asn1.ASN1TaggedObject; import org.bouncycastle.asn1.DERGeneralizedTime; import org.bouncycastle.asn1.DERSequence; import org.bouncycastle.asn1.DERTaggedObject; import org.bouncycastle.asn1.DERUTCTime; import org.bouncycastle.asn1.x500.X500Name; /** * PKIX RFC-2459 - TBSCertList object. *
     * TBSCertList  ::=  SEQUENCE  {
     *      version                 Version OPTIONAL,
     *                                   -- if present, shall be v2
     *      signature               AlgorithmIdentifier,
     *      issuer                  Name,
     *      thisUpdate              Time,
     *      nextUpdate              Time OPTIONAL,
     *      revokedCertificates     SEQUENCE OF SEQUENCE  {
     *           userCertificate         CertificateSerialNumber,
     *           revocationDate          Time,
     *           crlEntryExtensions      Extensions OPTIONAL
     *                                         -- if present, shall be v2
     *                                }  OPTIONAL,
     *      crlExtensions           [0]  EXPLICIT Extensions OPTIONAL
     *                                         -- if present, shall be v2
     *                                }
     * 
    */ public class TBSCertList extends ASN1Object { public static class CRLEntry extends ASN1Object { ASN1Sequence seq; Extensions crlEntryExtensions; private CRLEntry( ASN1Sequence seq) { if (seq.size() < 2 || seq.size() > 3) { throw new IllegalArgumentException("Bad sequence size: " + seq.size()); } this.seq = seq; } public static CRLEntry getInstance(Object o) { if (o instanceof CRLEntry) { return ((CRLEntry)o); } else if (o != null) { return new CRLEntry(ASN1Sequence.getInstance(o)); } return null; } public ASN1Integer getUserCertificate() { return ASN1Integer.getInstance(seq.getObjectAt(0)); } public Time getRevocationDate() { return Time.getInstance(seq.getObjectAt(1)); } public Extensions getExtensions() { if (crlEntryExtensions == null && seq.size() == 3) { crlEntryExtensions = Extensions.getInstance(seq.getObjectAt(2)); } return crlEntryExtensions; } public ASN1Primitive toASN1Primitive() { return seq; } public boolean hasExtensions() { return seq.size() == 3; } } private class RevokedCertificatesEnumeration implements Enumeration { private final Enumeration en; RevokedCertificatesEnumeration(Enumeration en) { this.en = en; } public boolean hasMoreElements() { return en.hasMoreElements(); } public Object nextElement() { return CRLEntry.getInstance(en.nextElement()); } } private class EmptyEnumeration implements Enumeration { public boolean hasMoreElements() { return false; } public Object nextElement() { return null; // TODO: check exception handling } } ASN1Integer version; AlgorithmIdentifier signature; X500Name issuer; Time thisUpdate; Time nextUpdate; ASN1Sequence revokedCertificates; Extensions crlExtensions; public static TBSCertList getInstance( ASN1TaggedObject obj, boolean explicit) { return getInstance(ASN1Sequence.getInstance(obj, explicit)); } public static TBSCertList getInstance( Object obj) { if (obj instanceof TBSCertList) { return (TBSCertList)obj; } else if (obj != null) { return new TBSCertList(ASN1Sequence.getInstance(obj)); } return null; } public TBSCertList( ASN1Sequence seq) { if (seq.size() < 3 || seq.size() > 7) { throw new IllegalArgumentException("Bad sequence size: " + seq.size()); } int seqPos = 0; if (seq.getObjectAt(seqPos) instanceof ASN1Integer) { version = ASN1Integer.getInstance(seq.getObjectAt(seqPos++)); } else { version = null; // version is optional } signature = AlgorithmIdentifier.getInstance(seq.getObjectAt(seqPos++)); issuer = X500Name.getInstance(seq.getObjectAt(seqPos++)); thisUpdate = Time.getInstance(seq.getObjectAt(seqPos++)); if (seqPos < seq.size() && (seq.getObjectAt(seqPos) instanceof DERUTCTime || seq.getObjectAt(seqPos) instanceof DERGeneralizedTime || seq.getObjectAt(seqPos) instanceof Time)) { nextUpdate = Time.getInstance(seq.getObjectAt(seqPos++)); } if (seqPos < seq.size() && !(seq.getObjectAt(seqPos) instanceof DERTaggedObject)) { revokedCertificates = ASN1Sequence.getInstance(seq.getObjectAt(seqPos++)); } if (seqPos < seq.size() && seq.getObjectAt(seqPos) instanceof DERTaggedObject) { crlExtensions = Extensions.getInstance(ASN1Sequence.getInstance((ASN1TaggedObject)seq.getObjectAt(seqPos), true)); } } public int getVersionNumber() { if (version == null) { return 1; } return version.getValue().intValue() + 1; } public ASN1Integer getVersion() { return version; } public AlgorithmIdentifier getSignature() { return signature; } public X500Name getIssuer() { return issuer; } public Time getThisUpdate() { return thisUpdate; } public Time getNextUpdate() { return nextUpdate; } public CRLEntry[] getRevokedCertificates() { if (revokedCertificates == null) { return new CRLEntry[0]; } CRLEntry[] entries = new CRLEntry[revokedCertificates.size()]; for (int i = 0; i < entries.length; i++) { entries[i] = CRLEntry.getInstance(revokedCertificates.getObjectAt(i)); } return entries; } public Enumeration getRevokedCertificateEnumeration() { if (revokedCertificates == null) { return new EmptyEnumeration(); } return new RevokedCertificatesEnumeration(revokedCertificates.getObjects()); } public Extensions getExtensions() { return crlExtensions; } public ASN1Primitive toASN1Primitive() { ASN1EncodableVector v = new ASN1EncodableVector(); if (version != null) { v.add(version); } v.add(signature); v.add(issuer); v.add(thisUpdate); if (nextUpdate != null) { v.add(nextUpdate); } // Add CRLEntries if they exist if (revokedCertificates != null) { v.add(revokedCertificates); } if (crlExtensions != null) { v.add(new DERTaggedObject(0, crlExtensions)); } return new DERSequence(v); } } bouncycastle-1.49.orig/src/org/bouncycastle/asn1/x509/X509NameTokenizer.java0000644000175000017500000000374312111037271026057 0ustar ebourgebourgpackage org.bouncycastle.asn1.x509; /** * class for breaking up an X500 Name into it's component tokens, ala * java.util.StringTokenizer. We need this class as some of the * lightweight Java environment don't support classes like * StringTokenizer. * @deprecated use X500NameTokenizer */ public class X509NameTokenizer { private String value; private int index; private char separator; private StringBuffer buf = new StringBuffer(); public X509NameTokenizer( String oid) { this(oid, ','); } public X509NameTokenizer( String oid, char separator) { this.value = oid; this.index = -1; this.separator = separator; } public boolean hasMoreTokens() { return (index != value.length()); } public String nextToken() { if (index == value.length()) { return null; } int end = index + 1; boolean quoted = false; boolean escaped = false; buf.setLength(0); while (end != value.length()) { char c = value.charAt(end); if (c == '"') { if (!escaped) { quoted = !quoted; } buf.append(c); escaped = false; } else { if (escaped || quoted) { buf.append(c); escaped = false; } else if (c == '\\') { buf.append(c); escaped = true; } else if (c == separator) { break; } else { buf.append(c); } } end++; } index = end; return buf.toString(); } } bouncycastle-1.49.orig/src/org/bouncycastle/asn1/x509/ReasonFlags.java0000644000175000017500000000504411624622715025131 0ustar ebourgebourgpackage org.bouncycastle.asn1.x509; import org.bouncycastle.asn1.DERBitString; /** * The ReasonFlags object. *
     * ReasonFlags ::= BIT STRING {
     *      unused                  (0),
     *      keyCompromise           (1),
     *      cACompromise            (2),
     *      affiliationChanged      (3),
     *      superseded              (4),
     *      cessationOfOperation    (5),
     *      certificateHold         (6),
     *      privilegeWithdrawn      (7),
     *      aACompromise            (8) }
     * 
    */ public class ReasonFlags extends DERBitString { /** * @deprecated use lower case version */ public static final int UNUSED = (1 << 7); /** * @deprecated use lower case version */ public static final int KEY_COMPROMISE = (1 << 6); /** * @deprecated use lower case version */ public static final int CA_COMPROMISE = (1 << 5); /** * @deprecated use lower case version */ public static final int AFFILIATION_CHANGED = (1 << 4); /** * @deprecated use lower case version */ public static final int SUPERSEDED = (1 << 3); /** * @deprecated use lower case version */ public static final int CESSATION_OF_OPERATION = (1 << 2); /** * @deprecated use lower case version */ public static final int CERTIFICATE_HOLD = (1 << 1); /** * @deprecated use lower case version */ public static final int PRIVILEGE_WITHDRAWN = (1 << 0); /** * @deprecated use lower case version */ public static final int AA_COMPROMISE = (1 << 15); public static final int unused = (1 << 7); public static final int keyCompromise = (1 << 6); public static final int cACompromise = (1 << 5); public static final int affiliationChanged = (1 << 4); public static final int superseded = (1 << 3); public static final int cessationOfOperation = (1 << 2); public static final int certificateHold = (1 << 1); public static final int privilegeWithdrawn = (1 << 0); public static final int aACompromise = (1 << 15); /** * @param reasons - the bitwise OR of the Key Reason flags giving the * allowed uses for the key. */ public ReasonFlags( int reasons) { super(getBytes(reasons), getPadBits(reasons)); } public ReasonFlags( DERBitString reasons) { super(reasons.getBytes(), reasons.getPadBits()); } } bouncycastle-1.49.orig/src/org/bouncycastle/asn1/x509/AttributeCertificate.java0000644000175000017500000000500611624652555027036 0ustar ebourgebourgpackage org.bouncycastle.asn1.x509; import org.bouncycastle.asn1.ASN1EncodableVector; import org.bouncycastle.asn1.ASN1Object; import org.bouncycastle.asn1.ASN1Primitive; import org.bouncycastle.asn1.ASN1Sequence; import org.bouncycastle.asn1.DERBitString; import org.bouncycastle.asn1.DERSequence; public class AttributeCertificate extends ASN1Object { AttributeCertificateInfo acinfo; AlgorithmIdentifier signatureAlgorithm; DERBitString signatureValue; /** * @param obj * @return an AttributeCertificate object */ public static AttributeCertificate getInstance(Object obj) { if (obj instanceof AttributeCertificate) { return (AttributeCertificate)obj; } else if (obj != null) { return new AttributeCertificate(ASN1Sequence.getInstance(obj)); } return null; } public AttributeCertificate( AttributeCertificateInfo acinfo, AlgorithmIdentifier signatureAlgorithm, DERBitString signatureValue) { this.acinfo = acinfo; this.signatureAlgorithm = signatureAlgorithm; this.signatureValue = signatureValue; } public AttributeCertificate( ASN1Sequence seq) { if (seq.size() != 3) { throw new IllegalArgumentException("Bad sequence size: " + seq.size()); } this.acinfo = AttributeCertificateInfo.getInstance(seq.getObjectAt(0)); this.signatureAlgorithm = AlgorithmIdentifier.getInstance(seq.getObjectAt(1)); this.signatureValue = DERBitString.getInstance(seq.getObjectAt(2)); } public AttributeCertificateInfo getAcinfo() { return acinfo; } public AlgorithmIdentifier getSignatureAlgorithm() { return signatureAlgorithm; } public DERBitString getSignatureValue() { return signatureValue; } /** * Produce an object suitable for an ASN1OutputStream. *
         *  AttributeCertificate ::= SEQUENCE {
         *       acinfo               AttributeCertificateInfo,
         *       signatureAlgorithm   AlgorithmIdentifier,
         *       signatureValue       BIT STRING
         *  }
         * 
    */ public ASN1Primitive toASN1Primitive() { ASN1EncodableVector v = new ASN1EncodableVector(); v.add(acinfo); v.add(signatureAlgorithm); v.add(signatureValue); return new DERSequence(v); } } bouncycastle-1.49.orig/src/org/bouncycastle/asn1/x509/PolicyMappings.java0000644000175000017500000000577611737200721025671 0ustar ebourgebourgpackage org.bouncycastle.asn1.x509; import java.util.Enumeration; import java.util.Hashtable; import org.bouncycastle.asn1.ASN1EncodableVector; import org.bouncycastle.asn1.ASN1Object; import org.bouncycastle.asn1.ASN1ObjectIdentifier; import org.bouncycastle.asn1.ASN1Primitive; import org.bouncycastle.asn1.ASN1Sequence; import org.bouncycastle.asn1.DERSequence; /** * PolicyMappings V3 extension, described in RFC3280. *
     *    PolicyMappings ::= SEQUENCE SIZE (1..MAX) OF SEQUENCE {
     *      issuerDomainPolicy      CertPolicyId,
     *      subjectDomainPolicy     CertPolicyId }
     * 
    * * @see RFC 3280, section 4.2.1.6 */ public class PolicyMappings extends ASN1Object { ASN1Sequence seq = null; public static PolicyMappings getInstance(Object obj) { if (obj instanceof PolicyMappings) { return (PolicyMappings)obj; } if (obj != null) { return new PolicyMappings(ASN1Sequence.getInstance(obj)); } return null; } /** * Creates a new PolicyMappings instance. * * @param seq an ASN1Sequence constructed as specified * in RFC 3280 */ private PolicyMappings(ASN1Sequence seq) { this.seq = seq; } /** * Creates a new PolicyMappings instance. * * @param mappings a HashMap value that maps * String oids * to other String oids. * @deprecated use CertPolicyId constructors. */ public PolicyMappings(Hashtable mappings) { ASN1EncodableVector dev = new ASN1EncodableVector(); Enumeration it = mappings.keys(); while (it.hasMoreElements()) { String idp = (String)it.nextElement(); String sdp = (String)mappings.get(idp); ASN1EncodableVector dv = new ASN1EncodableVector(); dv.add(new ASN1ObjectIdentifier(idp)); dv.add(new ASN1ObjectIdentifier(sdp)); dev.add(new DERSequence(dv)); } seq = new DERSequence(dev); } public PolicyMappings(CertPolicyId issuerDomainPolicy, CertPolicyId subjectDomainPolicy) { ASN1EncodableVector dv = new ASN1EncodableVector(); dv.add(issuerDomainPolicy); dv.add(subjectDomainPolicy); seq = new DERSequence(new DERSequence(dv)); } public PolicyMappings(CertPolicyId[] issuerDomainPolicy, CertPolicyId[] subjectDomainPolicy) { ASN1EncodableVector dev = new ASN1EncodableVector(); for (int i = 0; i != issuerDomainPolicy.length; i++) { ASN1EncodableVector dv = new ASN1EncodableVector(); dv.add(issuerDomainPolicy[i]); dv.add(subjectDomainPolicy[i]); dev.add(new DERSequence(dv)); } seq = new DERSequence(dev); } public ASN1Primitive toASN1Primitive() { return seq; } } bouncycastle-1.49.orig/src/org/bouncycastle/asn1/x509/DisplayText.java0000644000175000017500000001062711725272672025207 0ustar ebourgebourg package org.bouncycastle.asn1.x509; import org.bouncycastle.asn1.ASN1Choice; import org.bouncycastle.asn1.ASN1Object; import org.bouncycastle.asn1.ASN1Primitive; import org.bouncycastle.asn1.ASN1String; import org.bouncycastle.asn1.ASN1TaggedObject; import org.bouncycastle.asn1.DERBMPString; import org.bouncycastle.asn1.DERIA5String; import org.bouncycastle.asn1.DERUTF8String; import org.bouncycastle.asn1.DERVisibleString; /** * DisplayText class, used in * CertificatePolicies X509 V3 extensions (in policy qualifiers). * *

    It stores a string in a chosen encoding. *

     * DisplayText ::= CHOICE {
     *      ia5String        IA5String      (SIZE (1..200)),
     *      visibleString    VisibleString  (SIZE (1..200)),
     *      bmpString        BMPString      (SIZE (1..200)),
     *      utf8String       UTF8String     (SIZE (1..200)) }
     * 
    * @see PolicyQualifierInfo * @see PolicyInformation */ public class DisplayText extends ASN1Object implements ASN1Choice { /** * Constant corresponding to ia5String encoding. * */ public static final int CONTENT_TYPE_IA5STRING = 0; /** * Constant corresponding to bmpString encoding. * */ public static final int CONTENT_TYPE_BMPSTRING = 1; /** * Constant corresponding to utf8String encoding. * */ public static final int CONTENT_TYPE_UTF8STRING = 2; /** * Constant corresponding to visibleString encoding. * */ public static final int CONTENT_TYPE_VISIBLESTRING = 3; /** * Describe constant DISPLAY_TEXT_MAXIMUM_SIZE here. * */ public static final int DISPLAY_TEXT_MAXIMUM_SIZE = 200; int contentType; ASN1String contents; /** * Creates a new DisplayText instance. * * @param type the desired encoding type for the text. * @param text the text to store. Strings longer than 200 * characters are truncated. */ public DisplayText(int type, String text) { if (text.length() > DISPLAY_TEXT_MAXIMUM_SIZE) { // RFC3280 limits these strings to 200 chars // truncate the string text = text.substring (0, DISPLAY_TEXT_MAXIMUM_SIZE); } contentType = type; switch (type) { case CONTENT_TYPE_IA5STRING: contents = new DERIA5String(text); break; case CONTENT_TYPE_UTF8STRING: contents = new DERUTF8String(text); break; case CONTENT_TYPE_VISIBLESTRING: contents = new DERVisibleString(text); break; case CONTENT_TYPE_BMPSTRING: contents = new DERBMPString(text); break; default: contents = new DERUTF8String(text); break; } } /** * Creates a new DisplayText instance. * * @param text the text to encapsulate. Strings longer than 200 * characters are truncated. */ public DisplayText(String text) { // by default use UTF8String if (text.length() > DISPLAY_TEXT_MAXIMUM_SIZE) { text = text.substring(0, DISPLAY_TEXT_MAXIMUM_SIZE); } contentType = CONTENT_TYPE_UTF8STRING; contents = new DERUTF8String(text); } /** * Creates a new DisplayText instance. *

    Useful when reading back a DisplayText class * from it's ASN1Encodable/DEREncodable form. * * @param de a DEREncodable instance. */ private DisplayText(ASN1String de) { contents = de; } public static DisplayText getInstance(Object obj) { if (obj instanceof ASN1String) { return new DisplayText((ASN1String)obj); } else if (obj == null || obj instanceof DisplayText) { return (DisplayText)obj; } throw new IllegalArgumentException("illegal object in getInstance: " + obj.getClass().getName()); } public static DisplayText getInstance( ASN1TaggedObject obj, boolean explicit) { return getInstance(obj.getObject()); // must be explicitly tagged } public ASN1Primitive toASN1Primitive() { return (ASN1Primitive)contents; } /** * Returns the stored String object. * * @return the stored text as a String. */ public String getString() { return contents.getString(); } } bouncycastle-1.49.orig/src/org/bouncycastle/asn1/x509/Extension.java0000644000175000017500000002131412121462152024665 0ustar ebourgebourgpackage org.bouncycastle.asn1.x509; import java.io.IOException; import org.bouncycastle.asn1.ASN1Boolean; import org.bouncycastle.asn1.ASN1Encodable; import org.bouncycastle.asn1.ASN1EncodableVector; import org.bouncycastle.asn1.ASN1Object; import org.bouncycastle.asn1.ASN1ObjectIdentifier; import org.bouncycastle.asn1.ASN1OctetString; import org.bouncycastle.asn1.ASN1Primitive; import org.bouncycastle.asn1.ASN1Sequence; import org.bouncycastle.asn1.DEROctetString; import org.bouncycastle.asn1.DERSequence; /** * an object for the elements in the X.509 V3 extension block. */ public class Extension extends ASN1Object { /** * Subject Directory Attributes */ public static final ASN1ObjectIdentifier subjectDirectoryAttributes = new ASN1ObjectIdentifier("2.5.29.9"); /** * Subject Key Identifier */ public static final ASN1ObjectIdentifier subjectKeyIdentifier = new ASN1ObjectIdentifier("2.5.29.14"); /** * Key Usage */ public static final ASN1ObjectIdentifier keyUsage = new ASN1ObjectIdentifier("2.5.29.15"); /** * Private Key Usage Period */ public static final ASN1ObjectIdentifier privateKeyUsagePeriod = new ASN1ObjectIdentifier("2.5.29.16"); /** * Subject Alternative Name */ public static final ASN1ObjectIdentifier subjectAlternativeName = new ASN1ObjectIdentifier("2.5.29.17"); /** * Issuer Alternative Name */ public static final ASN1ObjectIdentifier issuerAlternativeName = new ASN1ObjectIdentifier("2.5.29.18"); /** * Basic Constraints */ public static final ASN1ObjectIdentifier basicConstraints = new ASN1ObjectIdentifier("2.5.29.19"); /** * CRL Number */ public static final ASN1ObjectIdentifier cRLNumber = new ASN1ObjectIdentifier("2.5.29.20"); /** * Reason code */ public static final ASN1ObjectIdentifier reasonCode = new ASN1ObjectIdentifier("2.5.29.21"); /** * Hold Instruction Code */ public static final ASN1ObjectIdentifier instructionCode = new ASN1ObjectIdentifier("2.5.29.23"); /** * Invalidity Date */ public static final ASN1ObjectIdentifier invalidityDate = new ASN1ObjectIdentifier("2.5.29.24"); /** * Delta CRL indicator */ public static final ASN1ObjectIdentifier deltaCRLIndicator = new ASN1ObjectIdentifier("2.5.29.27"); /** * Issuing Distribution Point */ public static final ASN1ObjectIdentifier issuingDistributionPoint = new ASN1ObjectIdentifier("2.5.29.28"); /** * Certificate Issuer */ public static final ASN1ObjectIdentifier certificateIssuer = new ASN1ObjectIdentifier("2.5.29.29"); /** * Name Constraints */ public static final ASN1ObjectIdentifier nameConstraints = new ASN1ObjectIdentifier("2.5.29.30"); /** * CRL Distribution Points */ public static final ASN1ObjectIdentifier cRLDistributionPoints = new ASN1ObjectIdentifier("2.5.29.31"); /** * Certificate Policies */ public static final ASN1ObjectIdentifier certificatePolicies = new ASN1ObjectIdentifier("2.5.29.32"); /** * Policy Mappings */ public static final ASN1ObjectIdentifier policyMappings = new ASN1ObjectIdentifier("2.5.29.33"); /** * Authority Key Identifier */ public static final ASN1ObjectIdentifier authorityKeyIdentifier = new ASN1ObjectIdentifier("2.5.29.35"); /** * Policy Constraints */ public static final ASN1ObjectIdentifier policyConstraints = new ASN1ObjectIdentifier("2.5.29.36"); /** * Extended Key Usage */ public static final ASN1ObjectIdentifier extendedKeyUsage = new ASN1ObjectIdentifier("2.5.29.37"); /** * Freshest CRL */ public static final ASN1ObjectIdentifier freshestCRL = new ASN1ObjectIdentifier("2.5.29.46"); /** * Inhibit Any Policy */ public static final ASN1ObjectIdentifier inhibitAnyPolicy = new ASN1ObjectIdentifier("2.5.29.54"); /** * Authority Info Access */ public static final ASN1ObjectIdentifier authorityInfoAccess = new ASN1ObjectIdentifier("1.3.6.1.5.5.7.1.1"); /** * Subject Info Access */ public static final ASN1ObjectIdentifier subjectInfoAccess = new ASN1ObjectIdentifier("1.3.6.1.5.5.7.1.11"); /** * Logo Type */ public static final ASN1ObjectIdentifier logoType = new ASN1ObjectIdentifier("1.3.6.1.5.5.7.1.12"); /** * BiometricInfo */ public static final ASN1ObjectIdentifier biometricInfo = new ASN1ObjectIdentifier("1.3.6.1.5.5.7.1.2"); /** * QCStatements */ public static final ASN1ObjectIdentifier qCStatements = new ASN1ObjectIdentifier("1.3.6.1.5.5.7.1.3"); /** * Audit identity extension in attribute certificates. */ public static final ASN1ObjectIdentifier auditIdentity = new ASN1ObjectIdentifier("1.3.6.1.5.5.7.1.4"); /** * NoRevAvail extension in attribute certificates. */ public static final ASN1ObjectIdentifier noRevAvail = new ASN1ObjectIdentifier("2.5.29.56"); /** * TargetInformation extension in attribute certificates. */ public static final ASN1ObjectIdentifier targetInformation = new ASN1ObjectIdentifier("2.5.29.55"); private ASN1ObjectIdentifier extnId; private boolean critical; private ASN1OctetString value; public Extension( ASN1ObjectIdentifier extnId, ASN1Boolean critical, ASN1OctetString value) { this(extnId, critical.isTrue(), value); } public Extension( ASN1ObjectIdentifier extnId, boolean critical, byte[] value) { this(extnId, critical, new DEROctetString(value)); } public Extension( ASN1ObjectIdentifier extnId, boolean critical, ASN1OctetString value) { this.extnId = extnId; this.critical = critical; this.value = value; } private Extension(ASN1Sequence seq) { if (seq.size() == 2) { this.extnId = ASN1ObjectIdentifier.getInstance(seq.getObjectAt(0)); this.critical = false; this.value = ASN1OctetString.getInstance(seq.getObjectAt(1)); } else if (seq.size() == 3) { this.extnId = ASN1ObjectIdentifier.getInstance(seq.getObjectAt(0)); this.critical = ASN1Boolean.getInstance(seq.getObjectAt(1)).isTrue(); this.value = ASN1OctetString.getInstance(seq.getObjectAt(2)); } else { throw new IllegalArgumentException("Bad sequence size: " + seq.size()); } } public static Extension getInstance(Object obj) { if (obj instanceof Extension) { return (Extension)obj; } else if (obj != null) { return new Extension(ASN1Sequence.getInstance(obj)); } return null; } public ASN1ObjectIdentifier getExtnId() { return extnId; } public boolean isCritical() { return critical; } public ASN1OctetString getExtnValue() { return value; } public ASN1Encodable getParsedValue() { return convertValueToObject(this); } public int hashCode() { if (this.isCritical()) { return this.getExtnValue().hashCode() ^ this.getExtnId().hashCode(); } return ~(this.getExtnValue().hashCode() ^ this.getExtnId().hashCode()); } public boolean equals( Object o) { if (!(o instanceof Extension)) { return false; } Extension other = (Extension)o; return other.getExtnId().equals(this.getExtnId()) && other.getExtnValue().equals(this.getExtnValue()) && (other.isCritical() == this.isCritical()); } public ASN1Primitive toASN1Primitive() { ASN1EncodableVector v = new ASN1EncodableVector(); v.add(extnId); if (critical) { v.add(ASN1Boolean.getInstance(true)); } v.add(value); return new DERSequence(v); } /** * Convert the value of the passed in extension to an object * @param ext the extension to parse * @return the object the value string contains * @exception IllegalArgumentException if conversion is not possible */ private static ASN1Primitive convertValueToObject( Extension ext) throws IllegalArgumentException { try { return ASN1Primitive.fromByteArray(ext.getExtnValue().getOctets()); } catch (IOException e) { throw new IllegalArgumentException("can't convert extension: " + e); } } } bouncycastle-1.49.orig/src/org/bouncycastle/asn1/x509/AttCertValidityPeriod.java0000644000175000017500000000412711737275254027154 0ustar ebourgebourgpackage org.bouncycastle.asn1.x509; import org.bouncycastle.asn1.ASN1EncodableVector; import org.bouncycastle.asn1.ASN1GeneralizedTime; import org.bouncycastle.asn1.ASN1Object; import org.bouncycastle.asn1.ASN1Primitive; import org.bouncycastle.asn1.ASN1Sequence; import org.bouncycastle.asn1.DERSequence; public class AttCertValidityPeriod extends ASN1Object { ASN1GeneralizedTime notBeforeTime; ASN1GeneralizedTime notAfterTime; public static AttCertValidityPeriod getInstance( Object obj) { if (obj instanceof AttCertValidityPeriod) { return (AttCertValidityPeriod)obj; } else if (obj != null) { return new AttCertValidityPeriod(ASN1Sequence.getInstance(obj)); } return null; } private AttCertValidityPeriod( ASN1Sequence seq) { if (seq.size() != 2) { throw new IllegalArgumentException("Bad sequence size: " + seq.size()); } notBeforeTime = ASN1GeneralizedTime.getInstance(seq.getObjectAt(0)); notAfterTime = ASN1GeneralizedTime.getInstance(seq.getObjectAt(1)); } /** * @param notBeforeTime * @param notAfterTime */ public AttCertValidityPeriod( ASN1GeneralizedTime notBeforeTime, ASN1GeneralizedTime notAfterTime) { this.notBeforeTime = notBeforeTime; this.notAfterTime = notAfterTime; } public ASN1GeneralizedTime getNotBeforeTime() { return notBeforeTime; } public ASN1GeneralizedTime getNotAfterTime() { return notAfterTime; } /** * Produce an object suitable for an ASN1OutputStream. *

         *  AttCertValidityPeriod  ::= SEQUENCE {
         *       notBeforeTime  GeneralizedTime,
         *       notAfterTime   GeneralizedTime
         *  } 
         * 
    */ public ASN1Primitive toASN1Primitive() { ASN1EncodableVector v = new ASN1EncodableVector(); v.add(notBeforeTime); v.add(notAfterTime); return new DERSequence(v); } } bouncycastle-1.49.orig/src/org/bouncycastle/asn1/x509/CertPolicyId.java0000644000175000017500000000214011737200335025244 0ustar ebourgebourgpackage org.bouncycastle.asn1.x509; import org.bouncycastle.asn1.ASN1Object; import org.bouncycastle.asn1.ASN1ObjectIdentifier; import org.bouncycastle.asn1.ASN1Primitive; /** * CertPolicyId, used in the CertificatePolicies and PolicyMappings * X509V3 Extensions. * *
     *     CertPolicyId ::= OBJECT IDENTIFIER
     * 
    */ /** * CertPolicyId, used in the CertificatePolicies and PolicyMappings * X509V3 Extensions. * *
     *     CertPolicyId ::= OBJECT IDENTIFIER
     * 
    */ public class CertPolicyId extends ASN1Object { private ASN1ObjectIdentifier id; private CertPolicyId(ASN1ObjectIdentifier id) { this.id = id; } public static CertPolicyId getInstance(Object o) { if (o instanceof CertPolicyId) { return (CertPolicyId)o; } else if (o != null) { return new CertPolicyId(ASN1ObjectIdentifier.getInstance(o)); } return null; } public String getId() { return id.getId(); } public ASN1Primitive toASN1Primitive() { return id; } } bouncycastle-1.49.orig/src/org/bouncycastle/asn1/x509/KeyPurposeId.java0000644000175000017500000001075512123520610025277 0ustar ebourgebourgpackage org.bouncycastle.asn1.x509; import org.bouncycastle.asn1.ASN1Object; import org.bouncycastle.asn1.ASN1ObjectIdentifier; import org.bouncycastle.asn1.ASN1Primitive; /** * The KeyPurposeId object. *
     *     KeyPurposeId ::= OBJECT IDENTIFIER
     *
     *     id-kp ::= OBJECT IDENTIFIER { iso(1) identified-organization(3) 
     *          dod(6) internet(1) security(5) mechanisms(5) pkix(7) 3}
     *
     * 
    * To create a new KeyPurposeId where none of the below suit, use *
     *     ASN1ObjectIdentifier newKeyPurposeIdOID = new ASN1ObjectIdentifier("1.3.6.1...");
     *
     *     KeyPurposeId newKeyPurposeId = KeyPurposeId.getInstance(newKeyPurposeIdOID);
     * 
    */ public class KeyPurposeId extends ASN1Object { private static final ASN1ObjectIdentifier id_kp = new ASN1ObjectIdentifier("1.3.6.1.5.5.7.3"); /** * { 2 5 29 37 0 } */ public static final KeyPurposeId anyExtendedKeyUsage = new KeyPurposeId(Extension.extendedKeyUsage.branch("0")); /** * { id-kp 1 } */ public static final KeyPurposeId id_kp_serverAuth = new KeyPurposeId(id_kp.branch("1")); /** * { id-kp 2 } */ public static final KeyPurposeId id_kp_clientAuth = new KeyPurposeId(id_kp.branch("2")); /** * { id-kp 3 } */ public static final KeyPurposeId id_kp_codeSigning = new KeyPurposeId(id_kp.branch("3")); /** * { id-kp 4 } */ public static final KeyPurposeId id_kp_emailProtection = new KeyPurposeId(id_kp.branch("4")); /** * Usage deprecated by RFC4945 - was { id-kp 5 } */ public static final KeyPurposeId id_kp_ipsecEndSystem = new KeyPurposeId(id_kp.branch("5")); /** * Usage deprecated by RFC4945 - was { id-kp 6 } */ public static final KeyPurposeId id_kp_ipsecTunnel = new KeyPurposeId(id_kp.branch("6")); /** * Usage deprecated by RFC4945 - was { idkp 7 } */ public static final KeyPurposeId id_kp_ipsecUser = new KeyPurposeId(id_kp.branch("7")); /** * { id-kp 8 } */ public static final KeyPurposeId id_kp_timeStamping = new KeyPurposeId(id_kp.branch("8")); /** * { id-kp 9 } */ public static final KeyPurposeId id_kp_OCSPSigning = new KeyPurposeId(id_kp.branch("9")); /** * { id-kp 10 } */ public static final KeyPurposeId id_kp_dvcs = new KeyPurposeId(id_kp.branch("10")); /** * { id-kp 11 } */ public static final KeyPurposeId id_kp_sbgpCertAAServerAuth = new KeyPurposeId(id_kp.branch("11")); /** * { id-kp 12 } */ public static final KeyPurposeId id_kp_scvp_responder = new KeyPurposeId(id_kp.branch("12")); /** * { id-kp 13 } */ public static final KeyPurposeId id_kp_eapOverPPP = new KeyPurposeId(id_kp.branch("13")); /** * { id-kp 14 } */ public static final KeyPurposeId id_kp_eapOverLAN = new KeyPurposeId(id_kp.branch("14")); /** * { id-kp 15 } */ public static final KeyPurposeId id_kp_scvpServer = new KeyPurposeId(id_kp.branch("15")); /** * { id-kp 16 } */ public static final KeyPurposeId id_kp_scvpClient = new KeyPurposeId(id_kp.branch("16")); /** * { id-kp 17 } */ public static final KeyPurposeId id_kp_ipsecIKE = new KeyPurposeId(id_kp.branch("17")); /** * { id-kp 18 } */ public static final KeyPurposeId id_kp_capwapAC = new KeyPurposeId(id_kp.branch("18")); /** * { id-kp 19 } */ public static final KeyPurposeId id_kp_capwapWTP = new KeyPurposeId(id_kp.branch("19")); // // microsoft key purpose ids // /** * { 1 3 6 1 4 1 311 20 2 2 } */ public static final KeyPurposeId id_kp_smartcardlogon = new KeyPurposeId(new ASN1ObjectIdentifier("1.3.6.1.4.1.311.20.2.2")); private ASN1ObjectIdentifier id; private KeyPurposeId(ASN1ObjectIdentifier id) { this.id = id; } /** * @deprecated use getInstance and an OID or one of the constants above. * @param id string representation of an OID. */ public KeyPurposeId(String id) { this(new ASN1ObjectIdentifier(id)); } public static KeyPurposeId getInstance(Object o) { if (o instanceof KeyPurposeId) { return (KeyPurposeId)o; } else if (o != null) { return new KeyPurposeId(ASN1ObjectIdentifier.getInstance(o)); } return null; } public ASN1Primitive toASN1Primitive() { return id; } public String getId() { return id.getId(); } } bouncycastle-1.49.orig/src/org/bouncycastle/asn1/x509/IssuerSerial.java0000644000175000017500000000516711737177615025356 0ustar ebourgebourgpackage org.bouncycastle.asn1.x509; import java.math.BigInteger; import org.bouncycastle.asn1.ASN1EncodableVector; import org.bouncycastle.asn1.ASN1Integer; import org.bouncycastle.asn1.ASN1Object; import org.bouncycastle.asn1.ASN1Primitive; import org.bouncycastle.asn1.ASN1Sequence; import org.bouncycastle.asn1.ASN1TaggedObject; import org.bouncycastle.asn1.DERBitString; import org.bouncycastle.asn1.DERSequence; public class IssuerSerial extends ASN1Object { GeneralNames issuer; ASN1Integer serial; DERBitString issuerUID; public static IssuerSerial getInstance( Object obj) { if (obj instanceof IssuerSerial) { return (IssuerSerial)obj; } if (obj != null) { return new IssuerSerial(ASN1Sequence.getInstance(obj)); } return null; } public static IssuerSerial getInstance( ASN1TaggedObject obj, boolean explicit) { return getInstance(ASN1Sequence.getInstance(obj, explicit)); } private IssuerSerial( ASN1Sequence seq) { if (seq.size() != 2 && seq.size() != 3) { throw new IllegalArgumentException("Bad sequence size: " + seq.size()); } issuer = GeneralNames.getInstance(seq.getObjectAt(0)); serial = ASN1Integer.getInstance(seq.getObjectAt(1)); if (seq.size() == 3) { issuerUID = DERBitString.getInstance(seq.getObjectAt(2)); } } public IssuerSerial( GeneralNames issuer, BigInteger serial) { this(issuer, new ASN1Integer(serial)); } public IssuerSerial( GeneralNames issuer, ASN1Integer serial) { this.issuer = issuer; this.serial = serial; } public GeneralNames getIssuer() { return issuer; } public ASN1Integer getSerial() { return serial; } public DERBitString getIssuerUID() { return issuerUID; } /** * Produce an object suitable for an ASN1OutputStream. *
         *  IssuerSerial  ::=  SEQUENCE {
         *       issuer         GeneralNames,
         *       serial         CertificateSerialNumber,
         *       issuerUID      UniqueIdentifier OPTIONAL
         *  }
         * 
    */ public ASN1Primitive toASN1Primitive() { ASN1EncodableVector v = new ASN1EncodableVector(); v.add(issuer); v.add(serial); if (issuerUID != null) { v.add(issuerUID); } return new DERSequence(v); } } bouncycastle-1.49.orig/src/org/bouncycastle/asn1/x509/sigi/0000755000175000017500000000000012152033551023001 5ustar ebourgebourgbouncycastle-1.49.orig/src/org/bouncycastle/asn1/x509/sigi/PersonalData.java0000644000175000017500000001457711737275254026257 0ustar ebourgebourgpackage org.bouncycastle.asn1.x509.sigi; import java.math.BigInteger; import java.util.Enumeration; import org.bouncycastle.asn1.ASN1EncodableVector; import org.bouncycastle.asn1.ASN1GeneralizedTime; import org.bouncycastle.asn1.ASN1Integer; import org.bouncycastle.asn1.ASN1Object; import org.bouncycastle.asn1.ASN1Primitive; import org.bouncycastle.asn1.ASN1Sequence; import org.bouncycastle.asn1.ASN1TaggedObject; import org.bouncycastle.asn1.DERPrintableString; import org.bouncycastle.asn1.DERSequence; import org.bouncycastle.asn1.DERTaggedObject; import org.bouncycastle.asn1.x500.DirectoryString; /** * Contains personal data for the otherName field in the subjectAltNames * extension. *

    *

     *     PersonalData ::= SEQUENCE {
     *       nameOrPseudonym NameOrPseudonym,
     *       nameDistinguisher [0] INTEGER OPTIONAL,
     *       dateOfBirth [1] GeneralizedTime OPTIONAL,
     *       placeOfBirth [2] DirectoryString OPTIONAL,
     *       gender [3] PrintableString OPTIONAL,
     *       postalAddress [4] DirectoryString OPTIONAL
     *       }
     * 
    * * @see org.bouncycastle.asn1.x509.sigi.NameOrPseudonym * @see org.bouncycastle.asn1.x509.sigi.SigIObjectIdentifiers */ public class PersonalData extends ASN1Object { private NameOrPseudonym nameOrPseudonym; private BigInteger nameDistinguisher; private ASN1GeneralizedTime dateOfBirth; private DirectoryString placeOfBirth; private String gender; private DirectoryString postalAddress; public static PersonalData getInstance(Object obj) { if (obj == null || obj instanceof PersonalData) { return (PersonalData)obj; } if (obj instanceof ASN1Sequence) { return new PersonalData((ASN1Sequence)obj); } throw new IllegalArgumentException("illegal object in getInstance: " + obj.getClass().getName()); } /** * Constructor from ASN1Sequence. *

    * The sequence is of type NameOrPseudonym: *

    *

         *     PersonalData ::= SEQUENCE {
         *       nameOrPseudonym NameOrPseudonym,
         *       nameDistinguisher [0] INTEGER OPTIONAL,
         *       dateOfBirth [1] GeneralizedTime OPTIONAL,
         *       placeOfBirth [2] DirectoryString OPTIONAL,
         *       gender [3] PrintableString OPTIONAL,
         *       postalAddress [4] DirectoryString OPTIONAL
         *       }
         * 
    * * @param seq The ASN.1 sequence. */ private PersonalData(ASN1Sequence seq) { if (seq.size() < 1) { throw new IllegalArgumentException("Bad sequence size: " + seq.size()); } Enumeration e = seq.getObjects(); nameOrPseudonym = NameOrPseudonym.getInstance(e.nextElement()); while (e.hasMoreElements()) { ASN1TaggedObject o = ASN1TaggedObject.getInstance(e.nextElement()); int tag = o.getTagNo(); switch (tag) { case 0: nameDistinguisher = ASN1Integer.getInstance(o, false).getValue(); break; case 1: dateOfBirth = ASN1GeneralizedTime.getInstance(o, false); break; case 2: placeOfBirth = DirectoryString.getInstance(o, true); break; case 3: gender = DERPrintableString.getInstance(o, false).getString(); break; case 4: postalAddress = DirectoryString.getInstance(o, true); break; default: throw new IllegalArgumentException("Bad tag number: " + o.getTagNo()); } } } /** * Constructor from a given details. * * @param nameOrPseudonym Name or pseudonym. * @param nameDistinguisher Name distinguisher. * @param dateOfBirth Date of birth. * @param placeOfBirth Place of birth. * @param gender Gender. * @param postalAddress Postal Address. */ public PersonalData(NameOrPseudonym nameOrPseudonym, BigInteger nameDistinguisher, ASN1GeneralizedTime dateOfBirth, DirectoryString placeOfBirth, String gender, DirectoryString postalAddress) { this.nameOrPseudonym = nameOrPseudonym; this.dateOfBirth = dateOfBirth; this.gender = gender; this.nameDistinguisher = nameDistinguisher; this.postalAddress = postalAddress; this.placeOfBirth = placeOfBirth; } public NameOrPseudonym getNameOrPseudonym() { return nameOrPseudonym; } public BigInteger getNameDistinguisher() { return nameDistinguisher; } public ASN1GeneralizedTime getDateOfBirth() { return dateOfBirth; } public DirectoryString getPlaceOfBirth() { return placeOfBirth; } public String getGender() { return gender; } public DirectoryString getPostalAddress() { return postalAddress; } /** * Produce an object suitable for an ASN1OutputStream. *

    * Returns: *

    *

         *     PersonalData ::= SEQUENCE {
         *       nameOrPseudonym NameOrPseudonym,
         *       nameDistinguisher [0] INTEGER OPTIONAL,
         *       dateOfBirth [1] GeneralizedTime OPTIONAL,
         *       placeOfBirth [2] DirectoryString OPTIONAL,
         *       gender [3] PrintableString OPTIONAL,
         *       postalAddress [4] DirectoryString OPTIONAL
         *       }
         * 
    * * @return a DERObject */ public ASN1Primitive toASN1Primitive() { ASN1EncodableVector vec = new ASN1EncodableVector(); vec.add(nameOrPseudonym); if (nameDistinguisher != null) { vec.add(new DERTaggedObject(false, 0, new ASN1Integer(nameDistinguisher))); } if (dateOfBirth != null) { vec.add(new DERTaggedObject(false, 1, dateOfBirth)); } if (placeOfBirth != null) { vec.add(new DERTaggedObject(true, 2, placeOfBirth)); } if (gender != null) { vec.add(new DERTaggedObject(false, 3, new DERPrintableString(gender, true))); } if (postalAddress != null) { vec.add(new DERTaggedObject(true, 4, postalAddress)); } return new DERSequence(vec); } } bouncycastle-1.49.orig/src/org/bouncycastle/asn1/x509/sigi/SigIObjectIdentifiers.java0000644000175000017500000000275511501126443030025 0ustar ebourgebourgpackage org.bouncycastle.asn1.x509.sigi; import org.bouncycastle.asn1.ASN1ObjectIdentifier; /** * Object Identifiers of SigI specifciation (German Signature Law * Interoperability specification). */ public interface SigIObjectIdentifiers { public final static ASN1ObjectIdentifier id_sigi = new ASN1ObjectIdentifier("1.3.36.8"); /** * Key purpose IDs for German SigI (Signature Interoperability * Specification) */ public final static ASN1ObjectIdentifier id_sigi_kp = new ASN1ObjectIdentifier(id_sigi + ".2"); /** * Certificate policy IDs for German SigI (Signature Interoperability * Specification) */ public final static ASN1ObjectIdentifier id_sigi_cp = new ASN1ObjectIdentifier(id_sigi + ".1"); /** * Other Name IDs for German SigI (Signature Interoperability Specification) */ public final static ASN1ObjectIdentifier id_sigi_on = new ASN1ObjectIdentifier(id_sigi + ".4"); /** * To be used for for the generation of directory service certificates. */ public static final ASN1ObjectIdentifier id_sigi_kp_directoryService = new ASN1ObjectIdentifier(id_sigi_kp + ".1"); /** * ID for PersonalData */ public static final ASN1ObjectIdentifier id_sigi_on_personalData = new ASN1ObjectIdentifier(id_sigi_on + ".1"); /** * Certificate is conform to german signature law. */ public static final ASN1ObjectIdentifier id_sigi_cp_sigconform = new ASN1ObjectIdentifier(id_sigi_cp + ".1"); } bouncycastle-1.49.orig/src/org/bouncycastle/asn1/x509/sigi/NameOrPseudonym.java0000644000175000017500000001160111625362120026731 0ustar ebourgebourgpackage org.bouncycastle.asn1.x509.sigi; import java.util.Enumeration; import org.bouncycastle.asn1.ASN1Choice; import org.bouncycastle.asn1.ASN1EncodableVector; import org.bouncycastle.asn1.ASN1Object; import org.bouncycastle.asn1.ASN1Primitive; import org.bouncycastle.asn1.ASN1Sequence; import org.bouncycastle.asn1.ASN1String; import org.bouncycastle.asn1.DERSequence; import org.bouncycastle.asn1.x500.DirectoryString; /** * Structure for a name or pseudonym. * *
     *       NameOrPseudonym ::= CHOICE {
     *            surAndGivenName SEQUENCE {
     *              surName DirectoryString,
     *              givenName SEQUENCE OF DirectoryString 
     *         },
     *            pseudonym DirectoryString 
     *       }
     * 
    * * @see org.bouncycastle.asn1.x509.sigi.PersonalData * */ public class NameOrPseudonym extends ASN1Object implements ASN1Choice { private DirectoryString pseudonym; private DirectoryString surname; private ASN1Sequence givenName; public static NameOrPseudonym getInstance(Object obj) { if (obj == null || obj instanceof NameOrPseudonym) { return (NameOrPseudonym)obj; } if (obj instanceof ASN1String) { return new NameOrPseudonym(DirectoryString.getInstance(obj)); } if (obj instanceof ASN1Sequence) { return new NameOrPseudonym((ASN1Sequence)obj); } throw new IllegalArgumentException("illegal object in getInstance: " + obj.getClass().getName()); } /** * Constructor from DirectoryString. *

    * The sequence is of type NameOrPseudonym: *

    *

         *       NameOrPseudonym ::= CHOICE {
         *            surAndGivenName SEQUENCE {
         *              surName DirectoryString,
         *              givenName SEQUENCE OF DirectoryString
         *         },
         *            pseudonym DirectoryString
         *       }
         * 
    * @param pseudonym pseudonym value to use. */ public NameOrPseudonym(DirectoryString pseudonym) { this.pseudonym = pseudonym; } /** * Constructor from ASN1Sequence. *

    * The sequence is of type NameOrPseudonym: *

    *

         *       NameOrPseudonym ::= CHOICE {
         *            surAndGivenName SEQUENCE {
         *              surName DirectoryString,
         *              givenName SEQUENCE OF DirectoryString
         *         },
         *            pseudonym DirectoryString
         *       }
         * 
    * * @param seq The ASN.1 sequence. */ private NameOrPseudonym(ASN1Sequence seq) { if (seq.size() != 2) { throw new IllegalArgumentException("Bad sequence size: " + seq.size()); } if (!(seq.getObjectAt(0) instanceof ASN1String)) { throw new IllegalArgumentException("Bad object encountered: " + seq.getObjectAt(0).getClass()); } surname = DirectoryString.getInstance(seq.getObjectAt(0)); givenName = ASN1Sequence.getInstance(seq.getObjectAt(1)); } /** * Constructor from a given details. * * @param pseudonym The pseudonym. */ public NameOrPseudonym(String pseudonym) { this(new DirectoryString(pseudonym)); } /** * Constructor from a given details. * * @param surname The surname. * @param givenName A sequence of directory strings making up the givenName */ public NameOrPseudonym(DirectoryString surname, ASN1Sequence givenName) { this.surname = surname; this.givenName = givenName; } public DirectoryString getPseudonym() { return pseudonym; } public DirectoryString getSurname() { return surname; } public DirectoryString[] getGivenName() { DirectoryString[] items = new DirectoryString[givenName.size()]; int count = 0; for (Enumeration e = givenName.getObjects(); e.hasMoreElements();) { items[count++] = DirectoryString.getInstance(e.nextElement()); } return items; } /** * Produce an object suitable for an ASN1OutputStream. *

    * Returns: *

    *

         *       NameOrPseudonym ::= CHOICE {
         *            surAndGivenName SEQUENCE {
         *              surName DirectoryString,
         *              givenName SEQUENCE OF DirectoryString
         *         },
         *            pseudonym DirectoryString
         *       }
         * 
    * * @return a DERObject */ public ASN1Primitive toASN1Primitive() { if (pseudonym != null) { return pseudonym.toASN1Primitive(); } else { ASN1EncodableVector vec1 = new ASN1EncodableVector(); vec1.add(surname); vec1.add(givenName); return new DERSequence(vec1); } } } bouncycastle-1.49.orig/src/org/bouncycastle/asn1/x509/RSAPublicKeyStructure.java0000644000175000017500000000505311724561172027103 0ustar ebourgebourgpackage org.bouncycastle.asn1.x509; import java.math.BigInteger; import java.util.Enumeration; import org.bouncycastle.asn1.ASN1EncodableVector; import org.bouncycastle.asn1.ASN1Integer; import org.bouncycastle.asn1.ASN1Object; import org.bouncycastle.asn1.ASN1Primitive; import org.bouncycastle.asn1.ASN1Sequence; import org.bouncycastle.asn1.ASN1TaggedObject; import org.bouncycastle.asn1.DERSequence; /** * @deprecated use org.bouncycastle.asn1.pkcs.RSAPublicKey */ public class RSAPublicKeyStructure extends ASN1Object { private BigInteger modulus; private BigInteger publicExponent; public static RSAPublicKeyStructure getInstance( ASN1TaggedObject obj, boolean explicit) { return getInstance(ASN1Sequence.getInstance(obj, explicit)); } public static RSAPublicKeyStructure getInstance( Object obj) { if(obj == null || obj instanceof RSAPublicKeyStructure) { return (RSAPublicKeyStructure)obj; } if(obj instanceof ASN1Sequence) { return new RSAPublicKeyStructure((ASN1Sequence)obj); } throw new IllegalArgumentException("Invalid RSAPublicKeyStructure: " + obj.getClass().getName()); } public RSAPublicKeyStructure( BigInteger modulus, BigInteger publicExponent) { this.modulus = modulus; this.publicExponent = publicExponent; } public RSAPublicKeyStructure( ASN1Sequence seq) { if (seq.size() != 2) { throw new IllegalArgumentException("Bad sequence size: " + seq.size()); } Enumeration e = seq.getObjects(); modulus = ASN1Integer.getInstance(e.nextElement()).getPositiveValue(); publicExponent = ASN1Integer.getInstance(e.nextElement()).getPositiveValue(); } public BigInteger getModulus() { return modulus; } public BigInteger getPublicExponent() { return publicExponent; } /** * This outputs the key in PKCS1v2 format. *
         *      RSAPublicKey ::= SEQUENCE {
         *                          modulus INTEGER, -- n
         *                          publicExponent INTEGER, -- e
         *                      }
         * 
    *

    */ public ASN1Primitive toASN1Primitive() { ASN1EncodableVector v = new ASN1EncodableVector(); v.add(new ASN1Integer(getModulus())); v.add(new ASN1Integer(getPublicExponent())); return new DERSequence(v); } } bouncycastle-1.49.orig/src/org/bouncycastle/asn1/x509/ExtendedKeyUsage.java0000644000175000017500000000714612103373450026120 0ustar ebourgebourgpackage org.bouncycastle.asn1.x509; import java.util.Enumeration; import java.util.Hashtable; import java.util.Vector; import org.bouncycastle.asn1.ASN1Encodable; import org.bouncycastle.asn1.ASN1EncodableVector; import org.bouncycastle.asn1.ASN1Object; import org.bouncycastle.asn1.ASN1ObjectIdentifier; import org.bouncycastle.asn1.ASN1Primitive; import org.bouncycastle.asn1.ASN1Sequence; import org.bouncycastle.asn1.ASN1TaggedObject; import org.bouncycastle.asn1.DERSequence; /** * The extendedKeyUsage object. *

     *      extendedKeyUsage ::= SEQUENCE SIZE (1..MAX) OF KeyPurposeId
     * 
    */ public class ExtendedKeyUsage extends ASN1Object { Hashtable usageTable = new Hashtable(); ASN1Sequence seq; public static ExtendedKeyUsage getInstance( ASN1TaggedObject obj, boolean explicit) { return getInstance(ASN1Sequence.getInstance(obj, explicit)); } public static ExtendedKeyUsage getInstance( Object obj) { if (obj instanceof ExtendedKeyUsage) { return (ExtendedKeyUsage)obj; } else if (obj != null) { return new ExtendedKeyUsage(ASN1Sequence.getInstance(obj)); } return null; } public static ExtendedKeyUsage fromExtensions(Extensions extensions) { return ExtendedKeyUsage.getInstance(extensions.getExtensionParsedValue(Extension.extendedKeyUsage)); } public ExtendedKeyUsage( KeyPurposeId usage) { this.seq = new DERSequence(usage); this.usageTable.put(usage, usage); } private ExtendedKeyUsage( ASN1Sequence seq) { this.seq = seq; Enumeration e = seq.getObjects(); while (e.hasMoreElements()) { ASN1Encodable o = (ASN1Encodable)e.nextElement(); if (!(o.toASN1Primitive() instanceof ASN1ObjectIdentifier)) { throw new IllegalArgumentException("Only ASN1ObjectIdentifiers allowed in ExtendedKeyUsage."); } this.usageTable.put(o, o); } } public ExtendedKeyUsage( KeyPurposeId[] usages) { ASN1EncodableVector v = new ASN1EncodableVector(); for (int i = 0; i != usages.length; i++) { v.add(usages[i]); this.usageTable.put(usages[i], usages[i]); } this.seq = new DERSequence(v); } /** * @deprecated use KeyPurposeId[] constructor. */ public ExtendedKeyUsage( Vector usages) { ASN1EncodableVector v = new ASN1EncodableVector(); Enumeration e = usages.elements(); while (e.hasMoreElements()) { ASN1Primitive o = (ASN1Primitive)e.nextElement(); v.add(o); this.usageTable.put(o, o); } this.seq = new DERSequence(v); } public boolean hasKeyPurposeId( KeyPurposeId keyPurposeId) { return (usageTable.get(keyPurposeId) != null); } /** * Returns all extended key usages. * The returned vector contains DERObjectIdentifiers. * @return An array with all key purposes. */ public KeyPurposeId[] getUsages() { KeyPurposeId[] temp = new KeyPurposeId[seq.size()]; int i = 0; for (Enumeration it = seq.getObjects(); it.hasMoreElements();) { temp[i++] = KeyPurposeId.getInstance(it.nextElement()); } return temp; } public int size() { return usageTable.size(); } public ASN1Primitive toASN1Primitive() { return seq; } } bouncycastle-1.49.orig/src/org/bouncycastle/asn1/x509/V2Form.java0000644000175000017500000000771112117732455024044 0ustar ebourgebourgpackage org.bouncycastle.asn1.x509; import org.bouncycastle.asn1.ASN1EncodableVector; import org.bouncycastle.asn1.ASN1Object; import org.bouncycastle.asn1.ASN1Primitive; import org.bouncycastle.asn1.ASN1Sequence; import org.bouncycastle.asn1.ASN1TaggedObject; import org.bouncycastle.asn1.DERSequence; import org.bouncycastle.asn1.DERTaggedObject; public class V2Form extends ASN1Object { GeneralNames issuerName; IssuerSerial baseCertificateID; ObjectDigestInfo objectDigestInfo; public static V2Form getInstance( ASN1TaggedObject obj, boolean explicit) { return getInstance(ASN1Sequence.getInstance(obj, explicit)); } public static V2Form getInstance( Object obj) { if (obj instanceof V2Form) { return (V2Form)obj; } else if (obj != null) { return new V2Form(ASN1Sequence.getInstance(obj)); } return null; } public V2Form( GeneralNames issuerName) { this(issuerName, null, null); } public V2Form( GeneralNames issuerName, IssuerSerial baseCertificateID) { this(issuerName, baseCertificateID, null); } public V2Form( GeneralNames issuerName, ObjectDigestInfo objectDigestInfo) { this(issuerName, null, objectDigestInfo); } public V2Form( GeneralNames issuerName, IssuerSerial baseCertificateID, ObjectDigestInfo objectDigestInfo) { this.issuerName = issuerName; this.baseCertificateID = baseCertificateID; this.objectDigestInfo = objectDigestInfo; } /** * @deprecated use getInstance(). */ public V2Form( ASN1Sequence seq) { if (seq.size() > 3) { throw new IllegalArgumentException("Bad sequence size: " + seq.size()); } int index = 0; if (!(seq.getObjectAt(0) instanceof ASN1TaggedObject)) { index++; this.issuerName = GeneralNames.getInstance(seq.getObjectAt(0)); } for (int i = index; i != seq.size(); i++) { ASN1TaggedObject o = ASN1TaggedObject.getInstance(seq.getObjectAt(i)); if (o.getTagNo() == 0) { baseCertificateID = IssuerSerial.getInstance(o, false); } else if (o.getTagNo() == 1) { objectDigestInfo = ObjectDigestInfo.getInstance(o, false); } else { throw new IllegalArgumentException("Bad tag number: " + o.getTagNo()); } } } public GeneralNames getIssuerName() { return issuerName; } public IssuerSerial getBaseCertificateID() { return baseCertificateID; } public ObjectDigestInfo getObjectDigestInfo() { return objectDigestInfo; } /** * Produce an object suitable for an ASN1OutputStream. *
         *  V2Form ::= SEQUENCE {
         *       issuerName            GeneralNames  OPTIONAL,
         *       baseCertificateID     [0] IssuerSerial  OPTIONAL,
         *       objectDigestInfo      [1] ObjectDigestInfo  OPTIONAL
         *         -- issuerName MUST be present in this profile
         *         -- baseCertificateID and objectDigestInfo MUST NOT
         *         -- be present in this profile
         *  }
         * 
    */ public ASN1Primitive toASN1Primitive() { ASN1EncodableVector v = new ASN1EncodableVector(); if (issuerName != null) { v.add(issuerName); } if (baseCertificateID != null) { v.add(new DERTaggedObject(false, 0, baseCertificateID)); } if (objectDigestInfo != null) { v.add(new DERTaggedObject(false, 1, objectDigestInfo)); } return new DERSequence(v); } } bouncycastle-1.49.orig/src/org/bouncycastle/asn1/x509/IetfAttrSyntax.java0000644000175000017500000001163611725244000025647 0ustar ebourgebourgpackage org.bouncycastle.asn1.x509; import java.util.Enumeration; import java.util.Vector; import org.bouncycastle.asn1.ASN1Encodable; import org.bouncycastle.asn1.ASN1EncodableVector; import org.bouncycastle.asn1.ASN1Object; import org.bouncycastle.asn1.ASN1ObjectIdentifier; import org.bouncycastle.asn1.ASN1OctetString; import org.bouncycastle.asn1.ASN1Primitive; import org.bouncycastle.asn1.ASN1Sequence; import org.bouncycastle.asn1.ASN1TaggedObject; import org.bouncycastle.asn1.DEROctetString; import org.bouncycastle.asn1.DERSequence; import org.bouncycastle.asn1.DERTaggedObject; import org.bouncycastle.asn1.DERUTF8String; /** * Implementation of IetfAttrSyntax as specified by RFC3281. */ public class IetfAttrSyntax extends ASN1Object { public static final int VALUE_OCTETS = 1; public static final int VALUE_OID = 2; public static final int VALUE_UTF8 = 3; GeneralNames policyAuthority = null; Vector values = new Vector(); int valueChoice = -1; public static IetfAttrSyntax getInstance(Object obj) { if (obj instanceof IetfAttrSyntax) { return (IetfAttrSyntax)obj; } if (obj != null) { return new IetfAttrSyntax(ASN1Sequence.getInstance(obj)); } return null; } /** * */ private IetfAttrSyntax(ASN1Sequence seq) { int i = 0; if (seq.getObjectAt(0) instanceof ASN1TaggedObject) { policyAuthority = GeneralNames.getInstance(((ASN1TaggedObject)seq.getObjectAt(0)), false); i++; } else if (seq.size() == 2) { // VOMS fix policyAuthority = GeneralNames.getInstance(seq.getObjectAt(0)); i++; } if (!(seq.getObjectAt(i) instanceof ASN1Sequence)) { throw new IllegalArgumentException("Non-IetfAttrSyntax encoding"); } seq = (ASN1Sequence)seq.getObjectAt(i); for (Enumeration e = seq.getObjects(); e.hasMoreElements();) { ASN1Primitive obj = (ASN1Primitive)e.nextElement(); int type; if (obj instanceof ASN1ObjectIdentifier) { type = VALUE_OID; } else if (obj instanceof DERUTF8String) { type = VALUE_UTF8; } else if (obj instanceof DEROctetString) { type = VALUE_OCTETS; } else { throw new IllegalArgumentException("Bad value type encoding IetfAttrSyntax"); } if (valueChoice < 0) { valueChoice = type; } if (type != valueChoice) { throw new IllegalArgumentException("Mix of value types in IetfAttrSyntax"); } values.addElement(obj); } } public GeneralNames getPolicyAuthority() { return policyAuthority; } public int getValueType() { return valueChoice; } public Object[] getValues() { if (this.getValueType() == VALUE_OCTETS) { ASN1OctetString[] tmp = new ASN1OctetString[values.size()]; for (int i = 0; i != tmp.length; i++) { tmp[i] = (ASN1OctetString)values.elementAt(i); } return tmp; } else if (this.getValueType() == VALUE_OID) { ASN1ObjectIdentifier[] tmp = new ASN1ObjectIdentifier[values.size()]; for (int i = 0; i != tmp.length; i++) { tmp[i] = (ASN1ObjectIdentifier)values.elementAt(i); } return tmp; } else { DERUTF8String[] tmp = new DERUTF8String[values.size()]; for (int i = 0; i != tmp.length; i++) { tmp[i] = (DERUTF8String)values.elementAt(i); } return tmp; } } /** * *
         * 
         *  IetfAttrSyntax ::= SEQUENCE {
         *    policyAuthority [0] GeneralNames OPTIONAL,
         *    values SEQUENCE OF CHOICE {
         *      octets OCTET STRING,
         *      oid OBJECT IDENTIFIER,
         *      string UTF8String
         *    }
         *  }
         *  
         * 
    */ public ASN1Primitive toASN1Primitive() { ASN1EncodableVector v = new ASN1EncodableVector(); if (policyAuthority != null) { v.add(new DERTaggedObject(0, policyAuthority)); } ASN1EncodableVector v2 = new ASN1EncodableVector(); for (Enumeration i = values.elements(); i.hasMoreElements();) { v2.add((ASN1Encodable)i.nextElement()); } v.add(new DERSequence(v2)); return new DERSequence(v); } } bouncycastle-1.49.orig/src/org/bouncycastle/asn1/x509/PolicyQualifierId.java0000644000175000017500000000152211624622715026300 0ustar ebourgebourg package org.bouncycastle.asn1.x509; import org.bouncycastle.asn1.ASN1ObjectIdentifier; /** * PolicyQualifierId, used in the CertificatePolicies * X509V3 extension. * *
     *    id-qt          OBJECT IDENTIFIER ::=  { id-pkix 2 }
     *    id-qt-cps      OBJECT IDENTIFIER ::=  { id-qt 1 }
     *    id-qt-unotice  OBJECT IDENTIFIER ::=  { id-qt 2 }
     *  PolicyQualifierId ::=
     *       OBJECT IDENTIFIER (id-qt-cps | id-qt-unotice)
     * 
    */ public class PolicyQualifierId extends ASN1ObjectIdentifier { private static final String id_qt = "1.3.6.1.5.5.7.2"; private PolicyQualifierId(String id) { super(id); } public static final PolicyQualifierId id_qt_cps = new PolicyQualifierId(id_qt + ".1"); public static final PolicyQualifierId id_qt_unotice = new PolicyQualifierId(id_qt + ".2"); } bouncycastle-1.49.orig/src/org/bouncycastle/asn1/x509/AuthorityKeyIdentifier.java0000644000175000017500000001525212111367570027370 0ustar ebourgebourgpackage org.bouncycastle.asn1.x509; import java.math.BigInteger; import java.util.Enumeration; import org.bouncycastle.asn1.ASN1EncodableVector; import org.bouncycastle.asn1.ASN1Integer; import org.bouncycastle.asn1.ASN1Object; import org.bouncycastle.asn1.ASN1OctetString; import org.bouncycastle.asn1.ASN1Primitive; import org.bouncycastle.asn1.ASN1Sequence; import org.bouncycastle.asn1.ASN1TaggedObject; import org.bouncycastle.asn1.DEROctetString; import org.bouncycastle.asn1.DERSequence; import org.bouncycastle.asn1.DERTaggedObject; import org.bouncycastle.crypto.Digest; import org.bouncycastle.crypto.digests.SHA1Digest; /** * The AuthorityKeyIdentifier object. *
     * id-ce-authorityKeyIdentifier OBJECT IDENTIFIER ::=  { id-ce 35 }
     *
     *   AuthorityKeyIdentifier ::= SEQUENCE {
     *      keyIdentifier             [0] IMPLICIT KeyIdentifier           OPTIONAL,
     *      authorityCertIssuer       [1] IMPLICIT GeneralNames            OPTIONAL,
     *      authorityCertSerialNumber [2] IMPLICIT CertificateSerialNumber OPTIONAL  }
     *
     *   KeyIdentifier ::= OCTET STRING
     * 
    * */ public class AuthorityKeyIdentifier extends ASN1Object { ASN1OctetString keyidentifier=null; GeneralNames certissuer=null; ASN1Integer certserno=null; public static AuthorityKeyIdentifier getInstance( ASN1TaggedObject obj, boolean explicit) { return getInstance(ASN1Sequence.getInstance(obj, explicit)); } public static AuthorityKeyIdentifier getInstance( Object obj) { if (obj instanceof AuthorityKeyIdentifier) { return (AuthorityKeyIdentifier)obj; } if (obj != null) { return new AuthorityKeyIdentifier(ASN1Sequence.getInstance(obj)); } return null; } public static AuthorityKeyIdentifier fromExtensions(Extensions extensions) { return AuthorityKeyIdentifier.getInstance(extensions.getExtensionParsedValue(Extension.authorityKeyIdentifier)); } protected AuthorityKeyIdentifier( ASN1Sequence seq) { Enumeration e = seq.getObjects(); while (e.hasMoreElements()) { ASN1TaggedObject o = DERTaggedObject.getInstance(e.nextElement()); switch (o.getTagNo()) { case 0: this.keyidentifier = ASN1OctetString.getInstance(o, false); break; case 1: this.certissuer = GeneralNames.getInstance(o, false); break; case 2: this.certserno = ASN1Integer.getInstance(o, false); break; default: throw new IllegalArgumentException("illegal tag"); } } } /** * * Calulates the keyidentifier using a SHA1 hash over the BIT STRING * from SubjectPublicKeyInfo as defined in RFC2459. * * Example of making a AuthorityKeyIdentifier: *
         *   SubjectPublicKeyInfo apki = new SubjectPublicKeyInfo((ASN1Sequence)new ASN1InputStream(
         *       publicKey.getEncoded()).readObject());
         *   AuthorityKeyIdentifier aki = new AuthorityKeyIdentifier(apki);
         * 
    * **/ public AuthorityKeyIdentifier( SubjectPublicKeyInfo spki) { Digest digest = new SHA1Digest(); byte[] resBuf = new byte[digest.getDigestSize()]; byte[] bytes = spki.getPublicKeyData().getBytes(); digest.update(bytes, 0, bytes.length); digest.doFinal(resBuf, 0); this.keyidentifier = new DEROctetString(resBuf); } /** * create an AuthorityKeyIdentifier with the GeneralNames tag and * the serial number provided as well. */ public AuthorityKeyIdentifier( SubjectPublicKeyInfo spki, GeneralNames name, BigInteger serialNumber) { Digest digest = new SHA1Digest(); byte[] resBuf = new byte[digest.getDigestSize()]; byte[] bytes = spki.getPublicKeyData().getBytes(); digest.update(bytes, 0, bytes.length); digest.doFinal(resBuf, 0); this.keyidentifier = new DEROctetString(resBuf); this.certissuer = GeneralNames.getInstance(name.toASN1Primitive()); this.certserno = new ASN1Integer(serialNumber); } /** * create an AuthorityKeyIdentifier with the GeneralNames tag and * the serial number provided. */ public AuthorityKeyIdentifier( GeneralNames name, BigInteger serialNumber) { this.keyidentifier = null; this.certissuer = GeneralNames.getInstance(name.toASN1Primitive()); this.certserno = new ASN1Integer(serialNumber); } /** * create an AuthorityKeyIdentifier with a precomputed key identifier */ public AuthorityKeyIdentifier( byte[] keyIdentifier) { this.keyidentifier = new DEROctetString(keyIdentifier); this.certissuer = null; this.certserno = null; } /** * create an AuthorityKeyIdentifier with a precomputed key identifier * and the GeneralNames tag and the serial number provided as well. */ public AuthorityKeyIdentifier( byte[] keyIdentifier, GeneralNames name, BigInteger serialNumber) { this.keyidentifier = new DEROctetString(keyIdentifier); this.certissuer = GeneralNames.getInstance(name.toASN1Primitive()); this.certserno = new ASN1Integer(serialNumber); } public byte[] getKeyIdentifier() { if (keyidentifier != null) { return keyidentifier.getOctets(); } return null; } public GeneralNames getAuthorityCertIssuer() { return certissuer; } public BigInteger getAuthorityCertSerialNumber() { if (certserno != null) { return certserno.getValue(); } return null; } /** * Produce an object suitable for an ASN1OutputStream. */ public ASN1Primitive toASN1Primitive() { ASN1EncodableVector v = new ASN1EncodableVector(); if (keyidentifier != null) { v.add(new DERTaggedObject(false, 0, keyidentifier)); } if (certissuer != null) { v.add(new DERTaggedObject(false, 1, certissuer)); } if (certserno != null) { v.add(new DERTaggedObject(false, 2, certserno)); } return new DERSequence(v); } public String toString() { return ("AuthorityKeyIdentifier: KeyID(" + this.keyidentifier.getOctets() + ")"); } } bouncycastle-1.49.orig/src/org/bouncycastle/asn1/x509/X509NameEntryConverter.java0000644000175000017500000000655411624652552027116 0ustar ebourgebourgpackage org.bouncycastle.asn1.x509; import java.io.IOException; import org.bouncycastle.asn1.ASN1InputStream; import org.bouncycastle.asn1.ASN1ObjectIdentifier; import org.bouncycastle.asn1.ASN1Primitive; import org.bouncycastle.asn1.DERPrintableString; import org.bouncycastle.util.Strings; /** * It turns out that the number of standard ways the fields in a DN should be * encoded into their ASN.1 counterparts is rapidly approaching the * number of machines on the internet. By default the X509Name class * will produce UTF8Strings in line with the current recommendations (RFC 3280). *

    * An example of an encoder look like below: *

     * public class X509DirEntryConverter
     *     extends X509NameEntryConverter
     * {
     *     public ASN1Primitive getConvertedValue(
     *         ASN1ObjectIdentifier  oid,
     *         String               value)
     *     {
     *         if (str.length() != 0 && str.charAt(0) == '#')
     *         {
     *             return convertHexEncoded(str, 1);
     *         }
     *         if (oid.equals(EmailAddress))
     *         {
     *             return new DERIA5String(str);
     *         }
     *         else if (canBePrintable(str))
     *         {
     *             return new DERPrintableString(str);
     *         }
     *         else if (canBeUTF8(str))
     *         {
     *             return new DERUTF8String(str);
     *         }
     *         else
     *         {
     *             return new DERBMPString(str);
     *         }
     *     }
     * }
     */
    public abstract class X509NameEntryConverter
    {
        /**
         * Convert an inline encoded hex string rendition of an ASN.1
         * object back into its corresponding ASN.1 object.
         * 
         * @param str the hex encoded object
         * @param off the index at which the encoding starts
         * @return the decoded object
         */
        protected ASN1Primitive convertHexEncoded(
            String  str,
            int     off)
            throws IOException
        {
            str = Strings.toLowerCase(str);
            byte[] data = new byte[(str.length() - off) / 2];
            for (int index = 0; index != data.length; index++)
            {
                char left = str.charAt((index * 2) + off);
                char right = str.charAt((index * 2) + off + 1);
                
                if (left < 'a')
                {
                    data[index] = (byte)((left - '0') << 4);
                }
                else
                {
                    data[index] = (byte)((left - 'a' + 10) << 4);
                }
                if (right < 'a')
                {
                    data[index] |= (byte)(right - '0');
                }
                else
                {
                    data[index] |= (byte)(right - 'a' + 10);
                }
            }
    
            ASN1InputStream aIn = new ASN1InputStream(data);
                                                
            return aIn.readObject();
        }
        
        /**
         * return true if the passed in String can be represented without
         * loss as a PrintableString, false otherwise.
         */
        protected boolean canBePrintable(
            String  str)
        {
            return DERPrintableString.isPrintableString(str);
        }
        
        /**
         * Convert the passed in String value into the appropriate ASN.1
         * encoded object.
         * 
         * @param oid the oid associated with the value in the DN.
         * @param value the value of the particular DN component.
         * @return the ASN.1 equivalent for the value.
         */
        public abstract ASN1Primitive getConvertedValue(ASN1ObjectIdentifier oid, String value);
    }
    bouncycastle-1.49.orig/src/org/bouncycastle/asn1/x509/DistributionPointName.java0000644000175000017500000000661411624625016027220 0ustar  ebourgebourgpackage org.bouncycastle.asn1.x509;
    
    import org.bouncycastle.asn1.ASN1Choice;
    import org.bouncycastle.asn1.ASN1Encodable;
    import org.bouncycastle.asn1.ASN1Object;
    import org.bouncycastle.asn1.ASN1Primitive;
    import org.bouncycastle.asn1.ASN1Set;
    import org.bouncycastle.asn1.ASN1TaggedObject;
    import org.bouncycastle.asn1.DERTaggedObject;
    
    /**
     * The DistributionPointName object.
     * 
     * DistributionPointName ::= CHOICE {
     *     fullName                 [0] GeneralNames,
     *     nameRelativeToCRLIssuer  [1] RDN
     * }
     * 
    */ public class DistributionPointName extends ASN1Object implements ASN1Choice { ASN1Encodable name; int type; public static final int FULL_NAME = 0; public static final int NAME_RELATIVE_TO_CRL_ISSUER = 1; public static DistributionPointName getInstance( ASN1TaggedObject obj, boolean explicit) { return getInstance(ASN1TaggedObject.getInstance(obj, true)); } public static DistributionPointName getInstance( Object obj) { if (obj == null || obj instanceof DistributionPointName) { return (DistributionPointName)obj; } else if (obj instanceof ASN1TaggedObject) { return new DistributionPointName((ASN1TaggedObject)obj); } throw new IllegalArgumentException("unknown object in factory: " + obj.getClass().getName()); } public DistributionPointName( int type, ASN1Encodable name) { this.type = type; this.name = name; } public DistributionPointName( GeneralNames name) { this(FULL_NAME, name); } /** * Return the tag number applying to the underlying choice. * * @return the tag number for this point name. */ public int getType() { return this.type; } /** * Return the tagged object inside the distribution point name. * * @return the underlying choice item. */ public ASN1Encodable getName() { return (ASN1Encodable)name; } public DistributionPointName( ASN1TaggedObject obj) { this.type = obj.getTagNo(); if (type == 0) { this.name = GeneralNames.getInstance(obj, false); } else { this.name = ASN1Set.getInstance(obj, false); } } public ASN1Primitive toASN1Primitive() { return new DERTaggedObject(false, type, name); } public String toString() { String sep = System.getProperty("line.separator"); StringBuffer buf = new StringBuffer(); buf.append("DistributionPointName: ["); buf.append(sep); if (type == FULL_NAME) { appendObject(buf, sep, "fullName", name.toString()); } else { appendObject(buf, sep, "nameRelativeToCRLIssuer", name.toString()); } buf.append("]"); buf.append(sep); return buf.toString(); } private void appendObject(StringBuffer buf, String sep, String name, String value) { String indent = " "; buf.append(indent); buf.append(name); buf.append(":"); buf.append(sep); buf.append(indent); buf.append(indent); buf.append(value); buf.append(sep); } } bouncycastle-1.49.orig/src/org/bouncycastle/asn1/x509/X509Name.java0000644000175000017500000012240412147057710024171 0ustar ebourgebourgpackage org.bouncycastle.asn1.x509; import java.io.IOException; import java.util.Enumeration; import java.util.Hashtable; import java.util.Vector; import org.bouncycastle.asn1.ASN1Encodable; import org.bouncycastle.asn1.ASN1EncodableVector; import org.bouncycastle.asn1.ASN1Encoding; import org.bouncycastle.asn1.ASN1Object; import org.bouncycastle.asn1.ASN1ObjectIdentifier; import org.bouncycastle.asn1.ASN1Primitive; import org.bouncycastle.asn1.ASN1Sequence; import org.bouncycastle.asn1.ASN1Set; import org.bouncycastle.asn1.ASN1String; import org.bouncycastle.asn1.ASN1TaggedObject; import org.bouncycastle.asn1.DERSequence; import org.bouncycastle.asn1.DERSet; import org.bouncycastle.asn1.DERUniversalString; import org.bouncycastle.asn1.pkcs.PKCSObjectIdentifiers; import org.bouncycastle.asn1.x500.X500Name; import org.bouncycastle.util.Strings; import org.bouncycastle.util.encoders.Hex; /** *
     *     RDNSequence ::= SEQUENCE OF RelativeDistinguishedName
     *
     *     RelativeDistinguishedName ::= SET SIZE (1..MAX) OF AttributeTypeAndValue
     *
     *     AttributeTypeAndValue ::= SEQUENCE {
     *                                   type  OBJECT IDENTIFIER,
     *                                   value ANY }
     * 
    * @deprecated use org.bouncycastle.asn1.x500.X500Name. */ public class X509Name extends ASN1Object { /** * country code - StringType(SIZE(2)) * @deprecated use a X500NameStyle */ public static final ASN1ObjectIdentifier C = new ASN1ObjectIdentifier("2.5.4.6"); /** * organization - StringType(SIZE(1..64)) * @deprecated use a X500NameStyle */ public static final ASN1ObjectIdentifier O = new ASN1ObjectIdentifier("2.5.4.10"); /** * organizational unit name - StringType(SIZE(1..64)) * @deprecated use a X500NameStyle */ public static final ASN1ObjectIdentifier OU = new ASN1ObjectIdentifier("2.5.4.11"); /** * Title * @deprecated use a X500NameStyle */ public static final ASN1ObjectIdentifier T = new ASN1ObjectIdentifier("2.5.4.12"); /** * common name - StringType(SIZE(1..64)) * @deprecated use a X500NameStyle */ public static final ASN1ObjectIdentifier CN = new ASN1ObjectIdentifier("2.5.4.3"); /** * device serial number name - StringType(SIZE(1..64)) */ public static final ASN1ObjectIdentifier SN = new ASN1ObjectIdentifier("2.5.4.5"); /** * street - StringType(SIZE(1..64)) */ public static final ASN1ObjectIdentifier STREET = new ASN1ObjectIdentifier("2.5.4.9"); /** * device serial number name - StringType(SIZE(1..64)) */ public static final ASN1ObjectIdentifier SERIALNUMBER = SN; /** * locality name - StringType(SIZE(1..64)) */ public static final ASN1ObjectIdentifier L = new ASN1ObjectIdentifier("2.5.4.7"); /** * state, or province name - StringType(SIZE(1..64)) */ public static final ASN1ObjectIdentifier ST = new ASN1ObjectIdentifier("2.5.4.8"); /** * Naming attributes of type X520name */ public static final ASN1ObjectIdentifier SURNAME = new ASN1ObjectIdentifier("2.5.4.4"); public static final ASN1ObjectIdentifier GIVENNAME = new ASN1ObjectIdentifier("2.5.4.42"); public static final ASN1ObjectIdentifier INITIALS = new ASN1ObjectIdentifier("2.5.4.43"); public static final ASN1ObjectIdentifier GENERATION = new ASN1ObjectIdentifier("2.5.4.44"); public static final ASN1ObjectIdentifier UNIQUE_IDENTIFIER = new ASN1ObjectIdentifier("2.5.4.45"); /** * businessCategory - DirectoryString(SIZE(1..128) */ public static final ASN1ObjectIdentifier BUSINESS_CATEGORY = new ASN1ObjectIdentifier( "2.5.4.15"); /** * postalCode - DirectoryString(SIZE(1..40) */ public static final ASN1ObjectIdentifier POSTAL_CODE = new ASN1ObjectIdentifier( "2.5.4.17"); /** * dnQualifier - DirectoryString(SIZE(1..64) */ public static final ASN1ObjectIdentifier DN_QUALIFIER = new ASN1ObjectIdentifier( "2.5.4.46"); /** * RFC 3039 Pseudonym - DirectoryString(SIZE(1..64) */ public static final ASN1ObjectIdentifier PSEUDONYM = new ASN1ObjectIdentifier( "2.5.4.65"); /** * RFC 3039 DateOfBirth - GeneralizedTime - YYYYMMDD000000Z */ public static final ASN1ObjectIdentifier DATE_OF_BIRTH = new ASN1ObjectIdentifier( "1.3.6.1.5.5.7.9.1"); /** * RFC 3039 PlaceOfBirth - DirectoryString(SIZE(1..128) */ public static final ASN1ObjectIdentifier PLACE_OF_BIRTH = new ASN1ObjectIdentifier( "1.3.6.1.5.5.7.9.2"); /** * RFC 3039 Gender - PrintableString (SIZE(1)) -- "M", "F", "m" or "f" */ public static final ASN1ObjectIdentifier GENDER = new ASN1ObjectIdentifier( "1.3.6.1.5.5.7.9.3"); /** * RFC 3039 CountryOfCitizenship - PrintableString (SIZE (2)) -- ISO 3166 * codes only */ public static final ASN1ObjectIdentifier COUNTRY_OF_CITIZENSHIP = new ASN1ObjectIdentifier( "1.3.6.1.5.5.7.9.4"); /** * RFC 3039 CountryOfResidence - PrintableString (SIZE (2)) -- ISO 3166 * codes only */ public static final ASN1ObjectIdentifier COUNTRY_OF_RESIDENCE = new ASN1ObjectIdentifier( "1.3.6.1.5.5.7.9.5"); /** * ISIS-MTT NameAtBirth - DirectoryString(SIZE(1..64) */ public static final ASN1ObjectIdentifier NAME_AT_BIRTH = new ASN1ObjectIdentifier("1.3.36.8.3.14"); /** * RFC 3039 PostalAddress - SEQUENCE SIZE (1..6) OF * DirectoryString(SIZE(1..30)) */ public static final ASN1ObjectIdentifier POSTAL_ADDRESS = new ASN1ObjectIdentifier("2.5.4.16"); /** * RFC 2256 dmdName */ public static final ASN1ObjectIdentifier DMD_NAME = new ASN1ObjectIdentifier("2.5.4.54"); /** * id-at-telephoneNumber */ public static final ASN1ObjectIdentifier TELEPHONE_NUMBER = X509ObjectIdentifiers.id_at_telephoneNumber; /** * id-at-name */ public static final ASN1ObjectIdentifier NAME = X509ObjectIdentifiers.id_at_name; /** * Email address (RSA PKCS#9 extension) - IA5String. *

    Note: if you're trying to be ultra orthodox, don't use this! It shouldn't be in here. * @deprecated use a X500NameStyle */ public static final ASN1ObjectIdentifier EmailAddress = PKCSObjectIdentifiers.pkcs_9_at_emailAddress; /** * more from PKCS#9 */ public static final ASN1ObjectIdentifier UnstructuredName = PKCSObjectIdentifiers.pkcs_9_at_unstructuredName; public static final ASN1ObjectIdentifier UnstructuredAddress = PKCSObjectIdentifiers.pkcs_9_at_unstructuredAddress; /** * email address in Verisign certificates */ public static final ASN1ObjectIdentifier E = EmailAddress; /* * others... */ public static final ASN1ObjectIdentifier DC = new ASN1ObjectIdentifier("0.9.2342.19200300.100.1.25"); /** * LDAP User id. */ public static final ASN1ObjectIdentifier UID = new ASN1ObjectIdentifier("0.9.2342.19200300.100.1.1"); /** * determines whether or not strings should be processed and printed * from back to front. */ public static boolean DefaultReverse = false; /** * default look up table translating OID values into their common symbols following * the convention in RFC 2253 with a few extras */ public static final Hashtable DefaultSymbols = new Hashtable(); /** * look up table translating OID values into their common symbols following the convention in RFC 2253 * */ public static final Hashtable RFC2253Symbols = new Hashtable(); /** * look up table translating OID values into their common symbols following the convention in RFC 1779 * */ public static final Hashtable RFC1779Symbols = new Hashtable(); /** * look up table translating common symbols into their OIDS. */ public static final Hashtable DefaultLookUp = new Hashtable(); /** * look up table translating OID values into their common symbols * @deprecated use DefaultSymbols */ public static final Hashtable OIDLookUp = DefaultSymbols; /** * look up table translating string values into their OIDS - * @deprecated use DefaultLookUp */ public static final Hashtable SymbolLookUp = DefaultLookUp; private static final Boolean TRUE = new Boolean(true); // for J2ME compatibility private static final Boolean FALSE = new Boolean(false); static { DefaultSymbols.put(C, "C"); DefaultSymbols.put(O, "O"); DefaultSymbols.put(T, "T"); DefaultSymbols.put(OU, "OU"); DefaultSymbols.put(CN, "CN"); DefaultSymbols.put(L, "L"); DefaultSymbols.put(ST, "ST"); DefaultSymbols.put(SN, "SERIALNUMBER"); DefaultSymbols.put(EmailAddress, "E"); DefaultSymbols.put(DC, "DC"); DefaultSymbols.put(UID, "UID"); DefaultSymbols.put(STREET, "STREET"); DefaultSymbols.put(SURNAME, "SURNAME"); DefaultSymbols.put(GIVENNAME, "GIVENNAME"); DefaultSymbols.put(INITIALS, "INITIALS"); DefaultSymbols.put(GENERATION, "GENERATION"); DefaultSymbols.put(UnstructuredAddress, "unstructuredAddress"); DefaultSymbols.put(UnstructuredName, "unstructuredName"); DefaultSymbols.put(UNIQUE_IDENTIFIER, "UniqueIdentifier"); DefaultSymbols.put(DN_QUALIFIER, "DN"); DefaultSymbols.put(PSEUDONYM, "Pseudonym"); DefaultSymbols.put(POSTAL_ADDRESS, "PostalAddress"); DefaultSymbols.put(NAME_AT_BIRTH, "NameAtBirth"); DefaultSymbols.put(COUNTRY_OF_CITIZENSHIP, "CountryOfCitizenship"); DefaultSymbols.put(COUNTRY_OF_RESIDENCE, "CountryOfResidence"); DefaultSymbols.put(GENDER, "Gender"); DefaultSymbols.put(PLACE_OF_BIRTH, "PlaceOfBirth"); DefaultSymbols.put(DATE_OF_BIRTH, "DateOfBirth"); DefaultSymbols.put(POSTAL_CODE, "PostalCode"); DefaultSymbols.put(BUSINESS_CATEGORY, "BusinessCategory"); DefaultSymbols.put(TELEPHONE_NUMBER, "TelephoneNumber"); DefaultSymbols.put(NAME, "Name"); RFC2253Symbols.put(C, "C"); RFC2253Symbols.put(O, "O"); RFC2253Symbols.put(OU, "OU"); RFC2253Symbols.put(CN, "CN"); RFC2253Symbols.put(L, "L"); RFC2253Symbols.put(ST, "ST"); RFC2253Symbols.put(STREET, "STREET"); RFC2253Symbols.put(DC, "DC"); RFC2253Symbols.put(UID, "UID"); RFC1779Symbols.put(C, "C"); RFC1779Symbols.put(O, "O"); RFC1779Symbols.put(OU, "OU"); RFC1779Symbols.put(CN, "CN"); RFC1779Symbols.put(L, "L"); RFC1779Symbols.put(ST, "ST"); RFC1779Symbols.put(STREET, "STREET"); DefaultLookUp.put("c", C); DefaultLookUp.put("o", O); DefaultLookUp.put("t", T); DefaultLookUp.put("ou", OU); DefaultLookUp.put("cn", CN); DefaultLookUp.put("l", L); DefaultLookUp.put("st", ST); DefaultLookUp.put("sn", SN); DefaultLookUp.put("serialnumber", SN); DefaultLookUp.put("street", STREET); DefaultLookUp.put("emailaddress", E); DefaultLookUp.put("dc", DC); DefaultLookUp.put("e", E); DefaultLookUp.put("uid", UID); DefaultLookUp.put("surname", SURNAME); DefaultLookUp.put("givenname", GIVENNAME); DefaultLookUp.put("initials", INITIALS); DefaultLookUp.put("generation", GENERATION); DefaultLookUp.put("unstructuredaddress", UnstructuredAddress); DefaultLookUp.put("unstructuredname", UnstructuredName); DefaultLookUp.put("uniqueidentifier", UNIQUE_IDENTIFIER); DefaultLookUp.put("dn", DN_QUALIFIER); DefaultLookUp.put("pseudonym", PSEUDONYM); DefaultLookUp.put("postaladdress", POSTAL_ADDRESS); DefaultLookUp.put("nameofbirth", NAME_AT_BIRTH); DefaultLookUp.put("countryofcitizenship", COUNTRY_OF_CITIZENSHIP); DefaultLookUp.put("countryofresidence", COUNTRY_OF_RESIDENCE); DefaultLookUp.put("gender", GENDER); DefaultLookUp.put("placeofbirth", PLACE_OF_BIRTH); DefaultLookUp.put("dateofbirth", DATE_OF_BIRTH); DefaultLookUp.put("postalcode", POSTAL_CODE); DefaultLookUp.put("businesscategory", BUSINESS_CATEGORY); DefaultLookUp.put("telephonenumber", TELEPHONE_NUMBER); DefaultLookUp.put("name", NAME); } private X509NameEntryConverter converter = null; private Vector ordering = new Vector(); private Vector values = new Vector(); private Vector added = new Vector(); private ASN1Sequence seq; private boolean isHashCodeCalculated; private int hashCodeValue; /** * Return a X509Name based on the passed in tagged object. * * @param obj tag object holding name. * @param explicit true if explicitly tagged false otherwise. * @return the X509Name */ public static X509Name getInstance( ASN1TaggedObject obj, boolean explicit) { return getInstance(ASN1Sequence.getInstance(obj, explicit)); } public static X509Name getInstance( Object obj) { if (obj == null || obj instanceof X509Name) { return (X509Name)obj; } else if (obj instanceof X500Name) { return new X509Name(ASN1Sequence.getInstance(((X500Name)obj).toASN1Primitive())); } else if (obj != null) { return new X509Name(ASN1Sequence.getInstance(obj)); } return null; } protected X509Name() { // constructure use by new X500 Name class } /** * Constructor from ASN1Sequence * * the principal will be a list of constructed sets, each containing an (OID, String) pair. * @deprecated use X500Name.getInstance() */ public X509Name( ASN1Sequence seq) { this.seq = seq; Enumeration e = seq.getObjects(); while (e.hasMoreElements()) { ASN1Set set = ASN1Set.getInstance(((ASN1Encodable)e.nextElement()).toASN1Primitive()); for (int i = 0; i < set.size(); i++) { ASN1Sequence s = ASN1Sequence.getInstance(set.getObjectAt(i).toASN1Primitive()); if (s.size() != 2) { throw new IllegalArgumentException("badly sized pair"); } ordering.addElement(ASN1ObjectIdentifier.getInstance(s.getObjectAt(0))); ASN1Encodable value = s.getObjectAt(1); if (value instanceof ASN1String && !(value instanceof DERUniversalString)) { String v = ((ASN1String)value).getString(); if (v.length() > 0 && v.charAt(0) == '#') { values.addElement("\\" + v); } else { values.addElement(v); } } else { try { values.addElement("#" + bytesToString(Hex.encode(value.toASN1Primitive().getEncoded(ASN1Encoding.DER)))); } catch (IOException e1) { throw new IllegalArgumentException("cannot encode value"); } } added.addElement((i != 0) ? TRUE : FALSE); // to allow earlier JDK compatibility } } } /** * constructor from a table of attributes. *

    * it's is assumed the table contains OID/String pairs, and the contents * of the table are copied into an internal table as part of the * construction process. *

    * Note: if the name you are trying to generate should be * following a specific ordering, you should use the constructor * with the ordering specified below. * @deprecated use an ordered constructor! The hashtable ordering is rarely correct */ public X509Name( Hashtable attributes) { this(null, attributes); } /** * Constructor from a table of attributes with ordering. *

    * it's is assumed the table contains OID/String pairs, and the contents * of the table are copied into an internal table as part of the * construction process. The ordering vector should contain the OIDs * in the order they are meant to be encoded or printed in toString. */ public X509Name( Vector ordering, Hashtable attributes) { this(ordering, attributes, new X509DefaultEntryConverter()); } /** * Constructor from a table of attributes with ordering. *

    * it's is assumed the table contains OID/String pairs, and the contents * of the table are copied into an internal table as part of the * construction process. The ordering vector should contain the OIDs * in the order they are meant to be encoded or printed in toString. *

    * The passed in converter will be used to convert the strings into their * ASN.1 counterparts. * @deprecated use X500Name, X500NameBuilder */ public X509Name( Vector ordering, Hashtable attributes, X509NameEntryConverter converter) { this.converter = converter; if (ordering != null) { for (int i = 0; i != ordering.size(); i++) { this.ordering.addElement(ordering.elementAt(i)); this.added.addElement(FALSE); } } else { Enumeration e = attributes.keys(); while (e.hasMoreElements()) { this.ordering.addElement(e.nextElement()); this.added.addElement(FALSE); } } for (int i = 0; i != this.ordering.size(); i++) { ASN1ObjectIdentifier oid = (ASN1ObjectIdentifier)this.ordering.elementAt(i); if (attributes.get(oid) == null) { throw new IllegalArgumentException("No attribute for object id - " + oid.getId() + " - passed to distinguished name"); } this.values.addElement(attributes.get(oid)); // copy the hash table } } /** * Takes two vectors one of the oids and the other of the values. * @deprecated use X500Name, X500NameBuilder */ public X509Name( Vector oids, Vector values) { this(oids, values, new X509DefaultEntryConverter()); } /** * Takes two vectors one of the oids and the other of the values. *

    * The passed in converter will be used to convert the strings into their * ASN.1 counterparts. * @deprecated use X500Name, X500NameBuilder */ public X509Name( Vector oids, Vector values, X509NameEntryConverter converter) { this.converter = converter; if (oids.size() != values.size()) { throw new IllegalArgumentException("oids vector must be same length as values."); } for (int i = 0; i < oids.size(); i++) { this.ordering.addElement(oids.elementAt(i)); this.values.addElement(values.elementAt(i)); this.added.addElement(FALSE); } } // private Boolean isEncoded(String s) // { // if (s.charAt(0) == '#') // { // return TRUE; // } // // return FALSE; // } /** * Takes an X509 dir name as a string of the format "C=AU, ST=Victoria", or * some such, converting it into an ordered set of name attributes. * @deprecated use X500Name, X500NameBuilder */ public X509Name( String dirName) { this(DefaultReverse, DefaultLookUp, dirName); } /** * Takes an X509 dir name as a string of the format "C=AU, ST=Victoria", or * some such, converting it into an ordered set of name attributes with each * string value being converted to its associated ASN.1 type using the passed * in converter. * @deprecated use X500Name, X500NameBuilder */ public X509Name( String dirName, X509NameEntryConverter converter) { this(DefaultReverse, DefaultLookUp, dirName, converter); } /** * Takes an X509 dir name as a string of the format "C=AU, ST=Victoria", or * some such, converting it into an ordered set of name attributes. If reverse * is true, create the encoded version of the sequence starting from the * last element in the string. * @deprecated use X500Name, X500NameBuilder */ public X509Name( boolean reverse, String dirName) { this(reverse, DefaultLookUp, dirName); } /** * Takes an X509 dir name as a string of the format "C=AU, ST=Victoria", or * some such, converting it into an ordered set of name attributes with each * string value being converted to its associated ASN.1 type using the passed * in converter. If reverse is true the ASN.1 sequence representing the DN will * be built by starting at the end of the string, rather than the start. * @deprecated use X500Name, X500NameBuilder */ public X509Name( boolean reverse, String dirName, X509NameEntryConverter converter) { this(reverse, DefaultLookUp, dirName, converter); } /** * Takes an X509 dir name as a string of the format "C=AU, ST=Victoria", or * some such, converting it into an ordered set of name attributes. lookUp * should provide a table of lookups, indexed by lowercase only strings and * yielding a ASN1ObjectIdentifier, other than that OID. and numeric oids * will be processed automatically. *
    * If reverse is true, create the encoded version of the sequence * starting from the last element in the string. * @param reverse true if we should start scanning from the end (RFC 2553). * @param lookUp table of names and their oids. * @param dirName the X.500 string to be parsed. * @deprecated use X500Name, X500NameBuilder */ public X509Name( boolean reverse, Hashtable lookUp, String dirName) { this(reverse, lookUp, dirName, new X509DefaultEntryConverter()); } private ASN1ObjectIdentifier decodeOID( String name, Hashtable lookUp) { name = name.trim(); if (Strings.toUpperCase(name).startsWith("OID.")) { return new ASN1ObjectIdentifier(name.substring(4)); } else if (name.charAt(0) >= '0' && name.charAt(0) <= '9') { return new ASN1ObjectIdentifier(name); } ASN1ObjectIdentifier oid = (ASN1ObjectIdentifier)lookUp.get(Strings.toLowerCase(name)); if (oid == null) { throw new IllegalArgumentException("Unknown object id - " + name + " - passed to distinguished name"); } return oid; } private String unescape(String elt) { if (elt.length() == 0 || (elt.indexOf('\\') < 0 && elt.indexOf('"') < 0)) { return elt.trim(); } char[] elts = elt.toCharArray(); boolean escaped = false; boolean quoted = false; StringBuffer buf = new StringBuffer(elt.length()); int start = 0; // if it's an escaped hash string and not an actual encoding in string form // we need to leave it escaped. if (elts[0] == '\\') { if (elts[1] == '#') { start = 2; buf.append("\\#"); } } boolean nonWhiteSpaceEncountered = false; int lastEscaped = 0; for (int i = start; i != elts.length; i++) { char c = elts[i]; if (c != ' ') { nonWhiteSpaceEncountered = true; } if (c == '"') { if (!escaped) { quoted = !quoted; } else { buf.append(c); } escaped = false; } else if (c == '\\' && !(escaped || quoted)) { escaped = true; lastEscaped = buf.length(); } else { if (c == ' ' && !escaped && !nonWhiteSpaceEncountered) { continue; } buf.append(c); escaped = false; } } if (buf.length() > 0) { while (buf.charAt(buf.length() - 1) == ' ' && lastEscaped != (buf.length() - 1)) { buf.setLength(buf.length() - 1); } } return buf.toString(); } /** * Takes an X509 dir name as a string of the format "C=AU, ST=Victoria", or * some such, converting it into an ordered set of name attributes. lookUp * should provide a table of lookups, indexed by lowercase only strings and * yielding a ASN1ObjectIdentifier, other than that OID. and numeric oids * will be processed automatically. The passed in converter is used to convert the * string values to the right of each equals sign to their ASN.1 counterparts. *
    * @param reverse true if we should start scanning from the end, false otherwise. * @param lookUp table of names and oids. * @param dirName the string dirName * @param converter the converter to convert string values into their ASN.1 equivalents */ public X509Name( boolean reverse, Hashtable lookUp, String dirName, X509NameEntryConverter converter) { this.converter = converter; X509NameTokenizer nTok = new X509NameTokenizer(dirName); while (nTok.hasMoreTokens()) { String token = nTok.nextToken(); if (token.indexOf('+') > 0) { X509NameTokenizer pTok = new X509NameTokenizer(token, '+'); addEntry(lookUp, pTok.nextToken(), FALSE); while (pTok.hasMoreTokens()) { addEntry(lookUp, pTok.nextToken(), TRUE); } } else { addEntry(lookUp, token, FALSE); } } if (reverse) { Vector o = new Vector(); Vector v = new Vector(); Vector a = new Vector(); int count = 1; for (int i = 0; i < this.ordering.size(); i++) { if (((Boolean)this.added.elementAt(i)).booleanValue()) { o.insertElementAt(this.ordering.elementAt(i), count); v.insertElementAt(this.values.elementAt(i), count); a.insertElementAt(this.added.elementAt(i), count); count++; } else { o.insertElementAt(this.ordering.elementAt(i), 0); v.insertElementAt(this.values.elementAt(i), 0); a.insertElementAt(this.added.elementAt(i), 0); count = 1; } } this.ordering = o; this.values = v; this.added = a; } } private void addEntry(Hashtable lookUp, String token, Boolean isAdded) { X509NameTokenizer vTok; String name; String value;ASN1ObjectIdentifier oid; vTok = new X509NameTokenizer(token, '='); name = vTok.nextToken(); if (!vTok.hasMoreTokens()) { throw new IllegalArgumentException("badly formatted directory string"); } value = vTok.nextToken(); oid = decodeOID(name, lookUp); this.ordering.addElement(oid); this.values.addElement(unescape(value)); this.added.addElement(isAdded); } /** * return a vector of the oids in the name, in the order they were found. */ public Vector getOIDs() { Vector v = new Vector(); for (int i = 0; i != ordering.size(); i++) { v.addElement(ordering.elementAt(i)); } return v; } /** * return a vector of the values found in the name, in the order they * were found. */ public Vector getValues() { Vector v = new Vector(); for (int i = 0; i != values.size(); i++) { v.addElement(values.elementAt(i)); } return v; } /** * return a vector of the values found in the name, in the order they * were found, with the DN label corresponding to passed in oid. */ public Vector getValues( ASN1ObjectIdentifier oid) { Vector v = new Vector(); for (int i = 0; i != values.size(); i++) { if (ordering.elementAt(i).equals(oid)) { String val = (String)values.elementAt(i); if (val.length() > 2 && val.charAt(0) == '\\' && val.charAt(1) == '#') { v.addElement(val.substring(1)); } else { v.addElement(val); } } } return v; } public ASN1Primitive toASN1Primitive() { if (seq == null) { ASN1EncodableVector vec = new ASN1EncodableVector(); ASN1EncodableVector sVec = new ASN1EncodableVector(); ASN1ObjectIdentifier lstOid = null; for (int i = 0; i != ordering.size(); i++) { ASN1EncodableVector v = new ASN1EncodableVector(); ASN1ObjectIdentifier oid = (ASN1ObjectIdentifier)ordering.elementAt(i); v.add(oid); String str = (String)values.elementAt(i); v.add(converter.getConvertedValue(oid, str)); if (lstOid == null || ((Boolean)this.added.elementAt(i)).booleanValue()) { sVec.add(new DERSequence(v)); } else { vec.add(new DERSet(sVec)); sVec = new ASN1EncodableVector(); sVec.add(new DERSequence(v)); } lstOid = oid; } vec.add(new DERSet(sVec)); seq = new DERSequence(vec); } return seq; } /** * @param inOrder if true the order of both X509 names must be the same, * as well as the values associated with each element. */ public boolean equals(Object obj, boolean inOrder) { if (!inOrder) { return this.equals(obj); } if (obj == this) { return true; } if (!(obj instanceof X509Name || obj instanceof ASN1Sequence)) { return false; } ASN1Primitive derO = ((ASN1Encodable)obj).toASN1Primitive(); if (this.toASN1Primitive().equals(derO)) { return true; } X509Name other; try { other = X509Name.getInstance(obj); } catch (IllegalArgumentException e) { return false; } int orderingSize = ordering.size(); if (orderingSize != other.ordering.size()) { return false; } for (int i = 0; i < orderingSize; i++) { ASN1ObjectIdentifier oid = (ASN1ObjectIdentifier)ordering.elementAt(i); ASN1ObjectIdentifier oOid = (ASN1ObjectIdentifier)other.ordering.elementAt(i); if (oid.equals(oOid)) { String value = (String)values.elementAt(i); String oValue = (String)other.values.elementAt(i); if (!equivalentStrings(value, oValue)) { return false; } } else { return false; } } return true; } public int hashCode() { if (isHashCodeCalculated) { return hashCodeValue; } isHashCodeCalculated = true; // this needs to be order independent, like equals for (int i = 0; i != ordering.size(); i += 1) { String value = (String)values.elementAt(i); value = canonicalize(value); value = stripInternalSpaces(value); hashCodeValue ^= ordering.elementAt(i).hashCode(); hashCodeValue ^= value.hashCode(); } return hashCodeValue; } /** * test for equality - note: case is ignored. */ public boolean equals(Object obj) { if (obj == this) { return true; } if (!(obj instanceof X509Name || obj instanceof ASN1Sequence)) { return false; } ASN1Primitive derO = ((ASN1Encodable)obj).toASN1Primitive(); if (this.toASN1Primitive().equals(derO)) { return true; } X509Name other; try { other = X509Name.getInstance(obj); } catch (IllegalArgumentException e) { return false; } int orderingSize = ordering.size(); if (orderingSize != other.ordering.size()) { return false; } boolean[] indexes = new boolean[orderingSize]; int start, end, delta; if (ordering.elementAt(0).equals(other.ordering.elementAt(0))) // guess forward { start = 0; end = orderingSize; delta = 1; } else // guess reversed - most common problem { start = orderingSize - 1; end = -1; delta = -1; } for (int i = start; i != end; i += delta) { boolean found = false; ASN1ObjectIdentifier oid = (ASN1ObjectIdentifier)ordering.elementAt(i); String value = (String)values.elementAt(i); for (int j = 0; j < orderingSize; j++) { if (indexes[j]) { continue; } ASN1ObjectIdentifier oOid = (ASN1ObjectIdentifier)other.ordering.elementAt(j); if (oid.equals(oOid)) { String oValue = (String)other.values.elementAt(j); if (equivalentStrings(value, oValue)) { indexes[j] = true; found = true; break; } } } if (!found) { return false; } } return true; } private boolean equivalentStrings(String s1, String s2) { String value = canonicalize(s1); String oValue = canonicalize(s2); if (!value.equals(oValue)) { value = stripInternalSpaces(value); oValue = stripInternalSpaces(oValue); if (!value.equals(oValue)) { return false; } } return true; } private String canonicalize(String s) { String value = Strings.toLowerCase(s.trim()); if (value.length() > 0 && value.charAt(0) == '#') { ASN1Primitive obj = decodeObject(value); if (obj instanceof ASN1String) { value = Strings.toLowerCase(((ASN1String)obj).getString().trim()); } } return value; } private ASN1Primitive decodeObject(String oValue) { try { return ASN1Primitive.fromByteArray(Hex.decode(oValue.substring(1))); } catch (IOException e) { throw new IllegalStateException("unknown encoding in name: " + e); } } private String stripInternalSpaces( String str) { StringBuffer res = new StringBuffer(); if (str.length() != 0) { char c1 = str.charAt(0); res.append(c1); for (int k = 1; k < str.length(); k++) { char c2 = str.charAt(k); if (!(c1 == ' ' && c2 == ' ')) { res.append(c2); } c1 = c2; } } return res.toString(); } private void appendValue( StringBuffer buf, Hashtable oidSymbols, ASN1ObjectIdentifier oid, String value) { String sym = (String)oidSymbols.get(oid); if (sym != null) { buf.append(sym); } else { buf.append(oid.getId()); } buf.append('='); int index = buf.length(); int start = index; buf.append(value); int end = buf.length(); if (value.length() >= 2 && value.charAt(0) == '\\' && value.charAt(1) == '#') { index += 2; } while (index != end) { if ((buf.charAt(index) == ',') || (buf.charAt(index) == '"') || (buf.charAt(index) == '\\') || (buf.charAt(index) == '+') || (buf.charAt(index) == '=') || (buf.charAt(index) == '<') || (buf.charAt(index) == '>') || (buf.charAt(index) == ';')) { buf.insert(index, "\\"); index++; end++; } index++; } while (buf.charAt(start) == ' ') { buf.insert(start, "\\"); start += 2; } int endBuf = buf.length() - 1; while (endBuf >= 0 && buf.charAt(endBuf) == ' ') { buf.insert(endBuf, '\\'); endBuf--; } } /** * convert the structure to a string - if reverse is true the * oids and values are listed out starting with the last element * in the sequence (ala RFC 2253), otherwise the string will begin * with the first element of the structure. If no string definition * for the oid is found in oidSymbols the string value of the oid is * added. Two standard symbol tables are provided DefaultSymbols, and * RFC2253Symbols as part of this class. * * @param reverse if true start at the end of the sequence and work back. * @param oidSymbols look up table strings for oids. */ public String toString( boolean reverse, Hashtable oidSymbols) { StringBuffer buf = new StringBuffer(); Vector components = new Vector(); boolean first = true; StringBuffer ava = null; for (int i = 0; i < ordering.size(); i++) { if (((Boolean)added.elementAt(i)).booleanValue()) { ava.append('+'); appendValue(ava, oidSymbols, (ASN1ObjectIdentifier)ordering.elementAt(i), (String)values.elementAt(i)); } else { ava = new StringBuffer(); appendValue(ava, oidSymbols, (ASN1ObjectIdentifier)ordering.elementAt(i), (String)values.elementAt(i)); components.addElement(ava); } } if (reverse) { for (int i = components.size() - 1; i >= 0; i--) { if (first) { first = false; } else { buf.append(','); } buf.append(components.elementAt(i).toString()); } } else { for (int i = 0; i < components.size(); i++) { if (first) { first = false; } else { buf.append(','); } buf.append(components.elementAt(i).toString()); } } return buf.toString(); } private String bytesToString( byte[] data) { char[] cs = new char[data.length]; for (int i = 0; i != cs.length; i++) { cs[i] = (char)(data[i] & 0xff); } return new String(cs); } public String toString() { return toString(DefaultReverse, DefaultSymbols); } } bouncycastle-1.49.orig/src/org/bouncycastle/asn1/x509/V2AttributeCertificateInfoGenerator.java0000644000175000017500000001027311737275254031735 0ustar ebourgebourgpackage org.bouncycastle.asn1.x509; import org.bouncycastle.asn1.ASN1Encodable; import org.bouncycastle.asn1.ASN1EncodableVector; import org.bouncycastle.asn1.ASN1GeneralizedTime; import org.bouncycastle.asn1.ASN1Integer; import org.bouncycastle.asn1.ASN1ObjectIdentifier; import org.bouncycastle.asn1.DERBitString; import org.bouncycastle.asn1.DERSequence; import org.bouncycastle.asn1.DERSet; /** * Generator for Version 2 AttributeCertificateInfo *

     * AttributeCertificateInfo ::= SEQUENCE {
     *       version              AttCertVersion -- version is v2,
     *       holder               Holder,
     *       issuer               AttCertIssuer,
     *       signature            AlgorithmIdentifier,
     *       serialNumber         CertificateSerialNumber,
     *       attrCertValidityPeriod   AttCertValidityPeriod,
     *       attributes           SEQUENCE OF Attribute,
     *       issuerUniqueID       UniqueIdentifier OPTIONAL,
     *       extensions           Extensions OPTIONAL
     * }
     * 
    * */ public class V2AttributeCertificateInfoGenerator { private ASN1Integer version; private Holder holder; private AttCertIssuer issuer; private AlgorithmIdentifier signature; private ASN1Integer serialNumber; private ASN1EncodableVector attributes; private DERBitString issuerUniqueID; private Extensions extensions; // Note: validity period start/end dates stored directly //private AttCertValidityPeriod attrCertValidityPeriod; private ASN1GeneralizedTime startDate, endDate; public V2AttributeCertificateInfoGenerator() { this.version = new ASN1Integer(1); attributes = new ASN1EncodableVector(); } public void setHolder(Holder holder) { this.holder = holder; } public void addAttribute(String oid, ASN1Encodable value) { attributes.add(new Attribute(new ASN1ObjectIdentifier(oid), new DERSet(value))); } /** * @param attribute */ public void addAttribute(Attribute attribute) { attributes.add(attribute); } public void setSerialNumber( ASN1Integer serialNumber) { this.serialNumber = serialNumber; } public void setSignature( AlgorithmIdentifier signature) { this.signature = signature; } public void setIssuer( AttCertIssuer issuer) { this.issuer = issuer; } public void setStartDate( ASN1GeneralizedTime startDate) { this.startDate = startDate; } public void setEndDate( ASN1GeneralizedTime endDate) { this.endDate = endDate; } public void setIssuerUniqueID( DERBitString issuerUniqueID) { this.issuerUniqueID = issuerUniqueID; } /** * @deprecated use method taking Extensions * @param extensions */ public void setExtensions( X509Extensions extensions) { this.extensions = Extensions.getInstance(extensions.toASN1Primitive()); } public void setExtensions( Extensions extensions) { this.extensions = extensions; } public AttributeCertificateInfo generateAttributeCertificateInfo() { if ((serialNumber == null) || (signature == null) || (issuer == null) || (startDate == null) || (endDate == null) || (holder == null) || (attributes == null)) { throw new IllegalStateException("not all mandatory fields set in V2 AttributeCertificateInfo generator"); } ASN1EncodableVector v = new ASN1EncodableVector(); v.add(version); v.add(holder); v.add(issuer); v.add(signature); v.add(serialNumber); // // before and after dates => AttCertValidityPeriod // AttCertValidityPeriod validity = new AttCertValidityPeriod(startDate, endDate); v.add(validity); // Attributes v.add(new DERSequence(attributes)); if (issuerUniqueID != null) { v.add(issuerUniqueID); } if (extensions != null) { v.add(extensions); } return AttributeCertificateInfo.getInstance(new DERSequence(v)); } } bouncycastle-1.49.orig/src/org/bouncycastle/asn1/x509/GeneralName.java0000644000175000017500000003255111701226727025105 0ustar ebourgebourgpackage org.bouncycastle.asn1.x509; import java.io.IOException; import java.util.StringTokenizer; import org.bouncycastle.asn1.ASN1Choice; import org.bouncycastle.asn1.ASN1Encodable; import org.bouncycastle.asn1.ASN1Object; import org.bouncycastle.asn1.ASN1ObjectIdentifier; import org.bouncycastle.asn1.ASN1OctetString; import org.bouncycastle.asn1.ASN1Primitive; import org.bouncycastle.asn1.ASN1Sequence; import org.bouncycastle.asn1.ASN1TaggedObject; import org.bouncycastle.asn1.DERIA5String; import org.bouncycastle.asn1.DEROctetString; import org.bouncycastle.asn1.DERTaggedObject; import org.bouncycastle.asn1.x500.X500Name; import org.bouncycastle.util.IPAddress; /** * The GeneralName object. *
     * GeneralName ::= CHOICE {
     *      otherName                       [0]     OtherName,
     *      rfc822Name                      [1]     IA5String,
     *      dNSName                         [2]     IA5String,
     *      x400Address                     [3]     ORAddress,
     *      directoryName                   [4]     Name,
     *      ediPartyName                    [5]     EDIPartyName,
     *      uniformResourceIdentifier       [6]     IA5String,
     *      iPAddress                       [7]     OCTET STRING,
     *      registeredID                    [8]     OBJECT IDENTIFIER}
     *
     * OtherName ::= SEQUENCE {
     *      type-id    OBJECT IDENTIFIER,
     *      value      [0] EXPLICIT ANY DEFINED BY type-id }
     *
     * EDIPartyName ::= SEQUENCE {
     *      nameAssigner            [0]     DirectoryString OPTIONAL,
     *      partyName               [1]     DirectoryString }
     * 
     * Name ::= CHOICE { RDNSequence }
     * 
    */ public class GeneralName extends ASN1Object implements ASN1Choice { public static final int otherName = 0; public static final int rfc822Name = 1; public static final int dNSName = 2; public static final int x400Address = 3; public static final int directoryName = 4; public static final int ediPartyName = 5; public static final int uniformResourceIdentifier = 6; public static final int iPAddress = 7; public static final int registeredID = 8; private ASN1Encodable obj; private int tag; /** * @deprecated use X500Name constructor. * @param dirName */ public GeneralName( X509Name dirName) { this.obj = X500Name.getInstance(dirName); this.tag = 4; } public GeneralName( X500Name dirName) { this.obj = dirName; this.tag = 4; } /** * When the subjectAltName extension contains an Internet mail address, * the address MUST be included as an rfc822Name. The format of an * rfc822Name is an "addr-spec" as defined in RFC 822 [RFC 822]. * * When the subjectAltName extension contains a domain name service * label, the domain name MUST be stored in the dNSName (an IA5String). * The name MUST be in the "preferred name syntax," as specified by RFC * 1034 [RFC 1034]. * * When the subjectAltName extension contains a URI, the name MUST be * stored in the uniformResourceIdentifier (an IA5String). The name MUST * be a non-relative URL, and MUST follow the URL syntax and encoding * rules specified in [RFC 1738]. The name must include both a scheme * (e.g., "http" or "ftp") and a scheme-specific-part. The scheme- * specific-part must include a fully qualified domain name or IP * address as the host. * * When the subjectAltName extension contains a iPAddress, the address * MUST be stored in the octet string in "network byte order," as * specified in RFC 791 [RFC 791]. The least significant bit (LSB) of * each octet is the LSB of the corresponding byte in the network * address. For IP Version 4, as specified in RFC 791, the octet string * MUST contain exactly four octets. For IP Version 6, as specified in * RFC 1883, the octet string MUST contain exactly sixteen octets [RFC * 1883]. */ public GeneralName( int tag, ASN1Encodable name) { this.obj = name; this.tag = tag; } /** * Create a GeneralName for the given tag from the passed in String. *

    * This constructor can handle: *

      *
    • rfc822Name *
    • iPAddress *
    • directoryName *
    • dNSName *
    • uniformResourceIdentifier *
    • registeredID *
    * For x400Address, otherName and ediPartyName there is no common string * format defined. *

    * Note: A directory name can be encoded in different ways into a byte * representation. Be aware of this if the byte representation is used for * comparing results. * * @param tag tag number * @param name string representation of name * @throws IllegalArgumentException if the string encoding is not correct or * not supported. */ public GeneralName( int tag, String name) { this.tag = tag; if (tag == rfc822Name || tag == dNSName || tag == uniformResourceIdentifier) { this.obj = new DERIA5String(name); } else if (tag == registeredID) { this.obj = new ASN1ObjectIdentifier(name); } else if (tag == directoryName) { this.obj = new X500Name(name); } else if (tag == iPAddress) { byte[] enc = toGeneralNameEncoding(name); if (enc != null) { this.obj = new DEROctetString(enc); } else { throw new IllegalArgumentException("IP Address is invalid"); } } else { throw new IllegalArgumentException("can't process String for tag: " + tag); } } public static GeneralName getInstance( Object obj) { if (obj == null || obj instanceof GeneralName) { return (GeneralName)obj; } if (obj instanceof ASN1TaggedObject) { ASN1TaggedObject tagObj = (ASN1TaggedObject)obj; int tag = tagObj.getTagNo(); switch (tag) { case otherName: return new GeneralName(tag, ASN1Sequence.getInstance(tagObj, false)); case rfc822Name: return new GeneralName(tag, DERIA5String.getInstance(tagObj, false)); case dNSName: return new GeneralName(tag, DERIA5String.getInstance(tagObj, false)); case x400Address: throw new IllegalArgumentException("unknown tag: " + tag); case directoryName: return new GeneralName(tag, X500Name.getInstance(tagObj, true)); case ediPartyName: return new GeneralName(tag, ASN1Sequence.getInstance(tagObj, false)); case uniformResourceIdentifier: return new GeneralName(tag, DERIA5String.getInstance(tagObj, false)); case iPAddress: return new GeneralName(tag, ASN1OctetString.getInstance(tagObj, false)); case registeredID: return new GeneralName(tag, ASN1ObjectIdentifier.getInstance(tagObj, false)); } } if (obj instanceof byte[]) { try { return getInstance(ASN1Primitive.fromByteArray((byte[])obj)); } catch (IOException e) { throw new IllegalArgumentException("unable to parse encoded general name"); } } throw new IllegalArgumentException("unknown object in getInstance: " + obj.getClass().getName()); } public static GeneralName getInstance( ASN1TaggedObject tagObj, boolean explicit) { return GeneralName.getInstance(ASN1TaggedObject.getInstance(tagObj, true)); } public int getTagNo() { return tag; } public ASN1Encodable getName() { return obj; } public String toString() { StringBuffer buf = new StringBuffer(); buf.append(tag); buf.append(": "); switch (tag) { case rfc822Name: case dNSName: case uniformResourceIdentifier: buf.append(DERIA5String.getInstance(obj).getString()); break; case directoryName: buf.append(X500Name.getInstance(obj).toString()); break; default: buf.append(obj.toString()); } return buf.toString(); } private byte[] toGeneralNameEncoding(String ip) { if (IPAddress.isValidIPv6WithNetmask(ip) || IPAddress.isValidIPv6(ip)) { int slashIndex = ip.indexOf('/'); if (slashIndex < 0) { byte[] addr = new byte[16]; int[] parsedIp = parseIPv6(ip); copyInts(parsedIp, addr, 0); return addr; } else { byte[] addr = new byte[32]; int[] parsedIp = parseIPv6(ip.substring(0, slashIndex)); copyInts(parsedIp, addr, 0); String mask = ip.substring(slashIndex + 1); if (mask.indexOf(':') > 0) { parsedIp = parseIPv6(mask); } else { parsedIp = parseMask(mask); } copyInts(parsedIp, addr, 16); return addr; } } else if (IPAddress.isValidIPv4WithNetmask(ip) || IPAddress.isValidIPv4(ip)) { int slashIndex = ip.indexOf('/'); if (slashIndex < 0) { byte[] addr = new byte[4]; parseIPv4(ip, addr, 0); return addr; } else { byte[] addr = new byte[8]; parseIPv4(ip.substring(0, slashIndex), addr, 0); String mask = ip.substring(slashIndex + 1); if (mask.indexOf('.') > 0) { parseIPv4(mask, addr, 4); } else { parseIPv4Mask(mask, addr, 4); } return addr; } } return null; } private void parseIPv4Mask(String mask, byte[] addr, int offset) { int maskVal = Integer.parseInt(mask); for (int i = 0; i != maskVal; i++) { addr[(i / 8) + offset] |= 1 << (7 - (i % 8)); } } private void parseIPv4(String ip, byte[] addr, int offset) { StringTokenizer sTok = new StringTokenizer(ip, "./"); int index = 0; while (sTok.hasMoreTokens()) { addr[offset + index++] = (byte)Integer.parseInt(sTok.nextToken()); } } private int[] parseMask(String mask) { int[] res = new int[8]; int maskVal = Integer.parseInt(mask); for (int i = 0; i != maskVal; i++) { res[i / 16] |= 1 << (15 - (i % 16)); } return res; } private void copyInts(int[] parsedIp, byte[] addr, int offSet) { for (int i = 0; i != parsedIp.length; i++) { addr[(i * 2) + offSet] = (byte)(parsedIp[i] >> 8); addr[(i * 2 + 1) + offSet] = (byte)parsedIp[i]; } } private int[] parseIPv6(String ip) { StringTokenizer sTok = new StringTokenizer(ip, ":", true); int index = 0; int[] val = new int[8]; if (ip.charAt(0) == ':' && ip.charAt(1) == ':') { sTok.nextToken(); // skip the first one } int doubleColon = -1; while (sTok.hasMoreTokens()) { String e = sTok.nextToken(); if (e.equals(":")) { doubleColon = index; val[index++] = 0; } else { if (e.indexOf('.') < 0) { val[index++] = Integer.parseInt(e, 16); if (sTok.hasMoreTokens()) { sTok.nextToken(); } } else { StringTokenizer eTok = new StringTokenizer(e, "."); val[index++] = (Integer.parseInt(eTok.nextToken()) << 8) | Integer.parseInt(eTok.nextToken()); val[index++] = (Integer.parseInt(eTok.nextToken()) << 8) | Integer.parseInt(eTok.nextToken()); } } } if (index != val.length) { System.arraycopy(val, doubleColon, val, val.length - (index - doubleColon), index - doubleColon); for (int i = doubleColon; i != val.length - (index - doubleColon); i++) { val[i] = 0; } } return val; } public ASN1Primitive toASN1Primitive() { if (tag == directoryName) // directoryName is explicitly tagged as it is a CHOICE { return new DERTaggedObject(true, tag, obj); } else { return new DERTaggedObject(false, tag, obj); } } } bouncycastle-1.49.orig/src/org/bouncycastle/asn1/x509/ObjectDigestInfo.java0000644000175000017500000001207711736733672026124 0ustar ebourgebourgpackage org.bouncycastle.asn1.x509; import org.bouncycastle.asn1.ASN1EncodableVector; import org.bouncycastle.asn1.ASN1Enumerated; import org.bouncycastle.asn1.ASN1Object; import org.bouncycastle.asn1.ASN1ObjectIdentifier; import org.bouncycastle.asn1.ASN1Primitive; import org.bouncycastle.asn1.ASN1Sequence; import org.bouncycastle.asn1.ASN1TaggedObject; import org.bouncycastle.asn1.DERBitString; import org.bouncycastle.asn1.DERSequence; /** * ObjectDigestInfo ASN.1 structure used in v2 attribute certificates. * *

     *  
     *    ObjectDigestInfo ::= SEQUENCE {
     *         digestedObjectType  ENUMERATED {
     *                 publicKey            (0),
     *                 publicKeyCert        (1),
     *                 otherObjectTypes     (2) },
     *                         -- otherObjectTypes MUST NOT
     *                         -- be used in this profile
     *         otherObjectTypeID   OBJECT IDENTIFIER OPTIONAL,
     *         digestAlgorithm     AlgorithmIdentifier,
     *         objectDigest        BIT STRING
     *    }
     *   
     * 
    * */ public class ObjectDigestInfo extends ASN1Object { /** * The public key is hashed. */ public final static int publicKey = 0; /** * The public key certificate is hashed. */ public final static int publicKeyCert = 1; /** * An other object is hashed. */ public final static int otherObjectDigest = 2; ASN1Enumerated digestedObjectType; ASN1ObjectIdentifier otherObjectTypeID; AlgorithmIdentifier digestAlgorithm; DERBitString objectDigest; public static ObjectDigestInfo getInstance( Object obj) { if (obj instanceof ObjectDigestInfo) { return (ObjectDigestInfo)obj; } if (obj != null) { return new ObjectDigestInfo(ASN1Sequence.getInstance(obj)); } return null; } public static ObjectDigestInfo getInstance( ASN1TaggedObject obj, boolean explicit) { return getInstance(ASN1Sequence.getInstance(obj, explicit)); } /** * Constructor from given details. *

    * If digestedObjectType is not {@link #publicKeyCert} or * {@link #publicKey} otherObjectTypeID must be given, * otherwise it is ignored. * * @param digestedObjectType The digest object type. * @param otherObjectTypeID The object type ID for * otherObjectDigest. * @param digestAlgorithm The algorithm identifier for the hash. * @param objectDigest The hash value. */ public ObjectDigestInfo( int digestedObjectType, ASN1ObjectIdentifier otherObjectTypeID, AlgorithmIdentifier digestAlgorithm, byte[] objectDigest) { this.digestedObjectType = new ASN1Enumerated(digestedObjectType); if (digestedObjectType == otherObjectDigest) { this.otherObjectTypeID = otherObjectTypeID; } this.digestAlgorithm = digestAlgorithm; this.objectDigest = new DERBitString(objectDigest); } private ObjectDigestInfo( ASN1Sequence seq) { if (seq.size() > 4 || seq.size() < 3) { throw new IllegalArgumentException("Bad sequence size: " + seq.size()); } digestedObjectType = ASN1Enumerated.getInstance(seq.getObjectAt(0)); int offset = 0; if (seq.size() == 4) { otherObjectTypeID = ASN1ObjectIdentifier.getInstance(seq.getObjectAt(1)); offset++; } digestAlgorithm = AlgorithmIdentifier.getInstance(seq.getObjectAt(1 + offset)); objectDigest = DERBitString.getInstance(seq.getObjectAt(2 + offset)); } public ASN1Enumerated getDigestedObjectType() { return digestedObjectType; } public ASN1ObjectIdentifier getOtherObjectTypeID() { return otherObjectTypeID; } public AlgorithmIdentifier getDigestAlgorithm() { return digestAlgorithm; } public DERBitString getObjectDigest() { return objectDigest; } /** * Produce an object suitable for an ASN1OutputStream. * *

         *  
         *    ObjectDigestInfo ::= SEQUENCE {
         *         digestedObjectType  ENUMERATED {
         *                 publicKey            (0),
         *                 publicKeyCert        (1),
         *                 otherObjectTypes     (2) },
         *                         -- otherObjectTypes MUST NOT
         *                         -- be used in this profile
         *         otherObjectTypeID   OBJECT IDENTIFIER OPTIONAL,
         *         digestAlgorithm     AlgorithmIdentifier,
         *         objectDigest        BIT STRING
         *    }
         *   
         * 
    */ public ASN1Primitive toASN1Primitive() { ASN1EncodableVector v = new ASN1EncodableVector(); v.add(digestedObjectType); if (otherObjectTypeID != null) { v.add(otherObjectTypeID); } v.add(digestAlgorithm); v.add(objectDigest); return new DERSequence(v); } } bouncycastle-1.49.orig/src/org/bouncycastle/asn1/x509/PrivateKeyUsagePeriod.java0000644000175000017500000000413511725273140027134 0ustar ebourgebourgpackage org.bouncycastle.asn1.x509; import java.util.Enumeration; import org.bouncycastle.asn1.ASN1EncodableVector; import org.bouncycastle.asn1.ASN1Object; import org.bouncycastle.asn1.ASN1Primitive; import org.bouncycastle.asn1.ASN1Sequence; import org.bouncycastle.asn1.ASN1TaggedObject; import org.bouncycastle.asn1.DERGeneralizedTime; import org.bouncycastle.asn1.DERSequence; import org.bouncycastle.asn1.DERTaggedObject; /** *
     *    PrivateKeyUsagePeriod ::= SEQUENCE {
     *      notBefore       [0]     GeneralizedTime OPTIONAL,
     *      notAfter        [1]     GeneralizedTime OPTIONAL }
     * 
    */ public class PrivateKeyUsagePeriod extends ASN1Object { public static PrivateKeyUsagePeriod getInstance(Object obj) { if (obj instanceof PrivateKeyUsagePeriod) { return (PrivateKeyUsagePeriod)obj; } if (obj != null) { return new PrivateKeyUsagePeriod(ASN1Sequence.getInstance(obj)); } return null; } private DERGeneralizedTime _notBefore, _notAfter; private PrivateKeyUsagePeriod(ASN1Sequence seq) { Enumeration en = seq.getObjects(); while (en.hasMoreElements()) { ASN1TaggedObject tObj = (ASN1TaggedObject)en.nextElement(); if (tObj.getTagNo() == 0) { _notBefore = DERGeneralizedTime.getInstance(tObj, false); } else if (tObj.getTagNo() == 1) { _notAfter = DERGeneralizedTime.getInstance(tObj, false); } } } public DERGeneralizedTime getNotBefore() { return _notBefore; } public DERGeneralizedTime getNotAfter() { return _notAfter; } public ASN1Primitive toASN1Primitive() { ASN1EncodableVector v = new ASN1EncodableVector(); if (_notBefore != null) { v.add(new DERTaggedObject(false, 0, _notBefore)); } if (_notAfter != null) { v.add(new DERTaggedObject(false, 1, _notAfter)); } return new DERSequence(v); } } bouncycastle-1.49.orig/src/org/bouncycastle/asn1/x509/AttributeCertificateInfo.java0000644000175000017500000001120711724574222027645 0ustar ebourgebourgpackage org.bouncycastle.asn1.x509; import org.bouncycastle.asn1.ASN1Encodable; import org.bouncycastle.asn1.ASN1EncodableVector; import org.bouncycastle.asn1.ASN1Integer; import org.bouncycastle.asn1.ASN1Object; import org.bouncycastle.asn1.ASN1Primitive; import org.bouncycastle.asn1.ASN1Sequence; import org.bouncycastle.asn1.ASN1TaggedObject; import org.bouncycastle.asn1.DERBitString; import org.bouncycastle.asn1.DERSequence; public class AttributeCertificateInfo extends ASN1Object { private ASN1Integer version; private Holder holder; private AttCertIssuer issuer; private AlgorithmIdentifier signature; private ASN1Integer serialNumber; private AttCertValidityPeriod attrCertValidityPeriod; private ASN1Sequence attributes; private DERBitString issuerUniqueID; private Extensions extensions; public static AttributeCertificateInfo getInstance( ASN1TaggedObject obj, boolean explicit) { return getInstance(ASN1Sequence.getInstance(obj, explicit)); } public static AttributeCertificateInfo getInstance( Object obj) { if (obj instanceof AttributeCertificateInfo) { return (AttributeCertificateInfo)obj; } else if (obj != null) { return new AttributeCertificateInfo(ASN1Sequence.getInstance(obj)); } return null; } private AttributeCertificateInfo( ASN1Sequence seq) { if (seq.size() < 7 || seq.size() > 9) { throw new IllegalArgumentException("Bad sequence size: " + seq.size()); } this.version = ASN1Integer.getInstance(seq.getObjectAt(0)); this.holder = Holder.getInstance(seq.getObjectAt(1)); this.issuer = AttCertIssuer.getInstance(seq.getObjectAt(2)); this.signature = AlgorithmIdentifier.getInstance(seq.getObjectAt(3)); this.serialNumber = ASN1Integer.getInstance(seq.getObjectAt(4)); this.attrCertValidityPeriod = AttCertValidityPeriod.getInstance(seq.getObjectAt(5)); this.attributes = ASN1Sequence.getInstance(seq.getObjectAt(6)); for (int i = 7; i < seq.size(); i++) { ASN1Encodable obj = (ASN1Encodable)seq.getObjectAt(i); if (obj instanceof DERBitString) { this.issuerUniqueID = DERBitString.getInstance(seq.getObjectAt(i)); } else if (obj instanceof ASN1Sequence || obj instanceof Extensions) { this.extensions = Extensions.getInstance(seq.getObjectAt(i)); } } } public ASN1Integer getVersion() { return version; } public Holder getHolder() { return holder; } public AttCertIssuer getIssuer() { return issuer; } public AlgorithmIdentifier getSignature() { return signature; } public ASN1Integer getSerialNumber() { return serialNumber; } public AttCertValidityPeriod getAttrCertValidityPeriod() { return attrCertValidityPeriod; } public ASN1Sequence getAttributes() { return attributes; } public DERBitString getIssuerUniqueID() { return issuerUniqueID; } public Extensions getExtensions() { return extensions; } /** * Produce an object suitable for an ASN1OutputStream. *
         *  AttributeCertificateInfo ::= SEQUENCE {
         *       version              AttCertVersion -- version is v2,
         *       holder               Holder,
         *       issuer               AttCertIssuer,
         *       signature            AlgorithmIdentifier,
         *       serialNumber         CertificateSerialNumber,
         *       attrCertValidityPeriod   AttCertValidityPeriod,
         *       attributes           SEQUENCE OF Attribute,
         *       issuerUniqueID       UniqueIdentifier OPTIONAL,
         *       extensions           Extensions OPTIONAL
         *  }
         *
         *  AttCertVersion ::= INTEGER { v2(1) }
         * 
    */ public ASN1Primitive toASN1Primitive() { ASN1EncodableVector v = new ASN1EncodableVector(); v.add(version); v.add(holder); v.add(issuer); v.add(signature); v.add(serialNumber); v.add(attrCertValidityPeriod); v.add(attributes); if (issuerUniqueID != null) { v.add(issuerUniqueID); } if (extensions != null) { v.add(extensions); } return new DERSequence(v); } } bouncycastle-1.49.orig/src/org/bouncycastle/asn1/x509/AuthorityInformationAccess.java0000644000175000017500000000517211725023645030246 0ustar ebourgebourgpackage org.bouncycastle.asn1.x509; import org.bouncycastle.asn1.ASN1EncodableVector; import org.bouncycastle.asn1.ASN1Object; import org.bouncycastle.asn1.ASN1ObjectIdentifier; import org.bouncycastle.asn1.ASN1Primitive; import org.bouncycastle.asn1.ASN1Sequence; import org.bouncycastle.asn1.DERSequence; /** * The AuthorityInformationAccess object. *
     * id-pe-authorityInfoAccess OBJECT IDENTIFIER ::= { id-pe 1 }
     *
     * AuthorityInfoAccessSyntax  ::=
     *      SEQUENCE SIZE (1..MAX) OF AccessDescription
     * AccessDescription  ::=  SEQUENCE {
     *       accessMethod          OBJECT IDENTIFIER,
     *       accessLocation        GeneralName  }
     *
     * id-ad OBJECT IDENTIFIER ::= { id-pkix 48 }
     * id-ad-caIssuers OBJECT IDENTIFIER ::= { id-ad 2 }
     * id-ad-ocsp OBJECT IDENTIFIER ::= { id-ad 1 }
     * 
    */ public class AuthorityInformationAccess extends ASN1Object { private AccessDescription[] descriptions; public static AuthorityInformationAccess getInstance( Object obj) { if (obj instanceof AuthorityInformationAccess) { return (AuthorityInformationAccess)obj; } if (obj != null) { return new AuthorityInformationAccess(ASN1Sequence.getInstance(obj)); } return null; } private AuthorityInformationAccess( ASN1Sequence seq) { if (seq.size() < 1) { throw new IllegalArgumentException("sequence may not be empty"); } descriptions = new AccessDescription[seq.size()]; for (int i = 0; i != seq.size(); i++) { descriptions[i] = AccessDescription.getInstance(seq.getObjectAt(i)); } } /** * create an AuthorityInformationAccess with the oid and location provided. */ public AuthorityInformationAccess( ASN1ObjectIdentifier oid, GeneralName location) { descriptions = new AccessDescription[1]; descriptions[0] = new AccessDescription(oid, location); } /** * * @return the access descriptions contained in this object. */ public AccessDescription[] getAccessDescriptions() { return descriptions; } public ASN1Primitive toASN1Primitive() { ASN1EncodableVector vec = new ASN1EncodableVector(); for (int i = 0; i != descriptions.length; i++) { vec.add(descriptions[i]); } return new DERSequence(vec); } public String toString() { return ("AuthorityInformationAccess: Oid(" + this.descriptions[0].getAccessMethod().getId() + ")"); } } bouncycastle-1.49.orig/src/org/bouncycastle/asn1/x509/X509DefaultEntryConverter.java0000644000175000017500000000407511624652555027621 0ustar ebourgebourgpackage org.bouncycastle.asn1.x509; import java.io.IOException; import org.bouncycastle.asn1.ASN1ObjectIdentifier; import org.bouncycastle.asn1.ASN1Primitive; import org.bouncycastle.asn1.DERGeneralizedTime; import org.bouncycastle.asn1.DERIA5String; import org.bouncycastle.asn1.DERPrintableString; import org.bouncycastle.asn1.DERUTF8String; /** * The default converter for X509 DN entries when going from their * string value to ASN.1 strings. */ public class X509DefaultEntryConverter extends X509NameEntryConverter { /** * Apply default coversion for the given value depending on the oid * and the character range of the value. * * @param oid the object identifier for the DN entry * @param value the value associated with it * @return the ASN.1 equivalent for the string value. */ public ASN1Primitive getConvertedValue( ASN1ObjectIdentifier oid, String value) { if (value.length() != 0 && value.charAt(0) == '#') { try { return convertHexEncoded(value, 1); } catch (IOException e) { throw new RuntimeException("can't recode value for oid " + oid.getId()); } } else { if (value.length() != 0 && value.charAt(0) == '\\') { value = value.substring(1); } if (oid.equals(X509Name.EmailAddress) || oid.equals(X509Name.DC)) { return new DERIA5String(value); } else if (oid.equals(X509Name.DATE_OF_BIRTH)) // accept time string as well as # (for compatibility) { return new DERGeneralizedTime(value); } else if (oid.equals(X509Name.C) || oid.equals(X509Name.SN) || oid.equals(X509Name.DN_QUALIFIER) || oid.equals(X509Name.TELEPHONE_NUMBER)) { return new DERPrintableString(value); } } return new DERUTF8String(value); } } bouncycastle-1.49.orig/src/org/bouncycastle/asn1/x509/DSAParameter.java0000644000175000017500000000404712101612475025170 0ustar ebourgebourgpackage org.bouncycastle.asn1.x509; import java.math.BigInteger; import java.util.Enumeration; import org.bouncycastle.asn1.ASN1EncodableVector; import org.bouncycastle.asn1.ASN1Integer; import org.bouncycastle.asn1.ASN1Object; import org.bouncycastle.asn1.ASN1Primitive; import org.bouncycastle.asn1.ASN1Sequence; import org.bouncycastle.asn1.ASN1TaggedObject; import org.bouncycastle.asn1.DERSequence; public class DSAParameter extends ASN1Object { ASN1Integer p, q, g; public static DSAParameter getInstance( ASN1TaggedObject obj, boolean explicit) { return getInstance(ASN1Sequence.getInstance(obj, explicit)); } public static DSAParameter getInstance( Object obj) { if (obj instanceof DSAParameter) { return (DSAParameter)obj; } if(obj != null) { return new DSAParameter(ASN1Sequence.getInstance(obj)); } return null; } public DSAParameter( BigInteger p, BigInteger q, BigInteger g) { this.p = new ASN1Integer(p); this.q = new ASN1Integer(q); this.g = new ASN1Integer(g); } private DSAParameter( ASN1Sequence seq) { if (seq.size() != 3) { throw new IllegalArgumentException("Bad sequence size: " + seq.size()); } Enumeration e = seq.getObjects(); p = ASN1Integer.getInstance(e.nextElement()); q = ASN1Integer.getInstance(e.nextElement()); g = ASN1Integer.getInstance(e.nextElement()); } public BigInteger getP() { return p.getPositiveValue(); } public BigInteger getQ() { return q.getPositiveValue(); } public BigInteger getG() { return g.getPositiveValue(); } public ASN1Primitive toASN1Primitive() { ASN1EncodableVector v = new ASN1EncodableVector(); v.add(p); v.add(q); v.add(g); return new DERSequence(v); } } bouncycastle-1.49.orig/src/org/bouncycastle/asn1/x509/CRLReason.java0000644000175000017500000000734112103440213024477 0ustar ebourgebourgpackage org.bouncycastle.asn1.x509; import java.math.BigInteger; import java.util.Hashtable; import org.bouncycastle.asn1.ASN1Enumerated; import org.bouncycastle.asn1.ASN1Object; import org.bouncycastle.asn1.ASN1Primitive; import org.bouncycastle.util.Integers; /** * The CRLReason enumeration. *
     * CRLReason ::= ENUMERATED {
     *  unspecified             (0),
     *  keyCompromise           (1),
     *  cACompromise            (2),
     *  affiliationChanged      (3),
     *  superseded              (4),
     *  cessationOfOperation    (5),
     *  certificateHold         (6),
     *  removeFromCRL           (8),
     *  privilegeWithdrawn      (9),
     *  aACompromise           (10)
     * }
     * 
    */ public class CRLReason extends ASN1Object { /** * @deprecated use lower case version */ public static final int UNSPECIFIED = 0; /** * @deprecated use lower case version */ public static final int KEY_COMPROMISE = 1; /** * @deprecated use lower case version */ public static final int CA_COMPROMISE = 2; /** * @deprecated use lower case version */ public static final int AFFILIATION_CHANGED = 3; /** * @deprecated use lower case version */ public static final int SUPERSEDED = 4; /** * @deprecated use lower case version */ public static final int CESSATION_OF_OPERATION = 5; /** * @deprecated use lower case version */ public static final int CERTIFICATE_HOLD = 6; /** * @deprecated use lower case version */ public static final int REMOVE_FROM_CRL = 8; /** * @deprecated use lower case version */ public static final int PRIVILEGE_WITHDRAWN = 9; /** * @deprecated use lower case version */ public static final int AA_COMPROMISE = 10; public static final int unspecified = 0; public static final int keyCompromise = 1; public static final int cACompromise = 2; public static final int affiliationChanged = 3; public static final int superseded = 4; public static final int cessationOfOperation = 5; public static final int certificateHold = 6; // 7 -> unknown public static final int removeFromCRL = 8; public static final int privilegeWithdrawn = 9; public static final int aACompromise = 10; private static final String[] reasonString = { "unspecified", "keyCompromise", "cACompromise", "affiliationChanged", "superseded", "cessationOfOperation", "certificateHold", "unknown", "removeFromCRL", "privilegeWithdrawn", "aACompromise" }; private static final Hashtable table = new Hashtable(); private ASN1Enumerated value; public static CRLReason getInstance(Object o) { if (o instanceof CRLReason) { return (CRLReason)o; } else if (o != null) { return lookup(ASN1Enumerated.getInstance(o).getValue().intValue()); } return null; } private CRLReason( int reason) { value = new ASN1Enumerated(reason); } public String toString() { String str; int reason = getValue().intValue(); if (reason < 0 || reason > 10) { str = "invalid"; } else { str = reasonString[reason]; } return "CRLReason: " + str; } public BigInteger getValue() { return value.getValue(); } public ASN1Primitive toASN1Primitive() { return value; } public static CRLReason lookup(int value) { Integer idx = Integers.valueOf(value); if (!table.containsKey(idx)) { table.put(idx, new CRLReason(value)); } return (CRLReason)table.get(idx); } } bouncycastle-1.49.orig/src/org/bouncycastle/asn1/x509/SubjectPublicKeyInfo.java0000644000175000017500000001007511737273326026755 0ustar ebourgebourgpackage org.bouncycastle.asn1.x509; import java.io.IOException; import java.util.Enumeration; import org.bouncycastle.asn1.ASN1Encodable; import org.bouncycastle.asn1.ASN1EncodableVector; import org.bouncycastle.asn1.ASN1InputStream; import org.bouncycastle.asn1.ASN1Object; import org.bouncycastle.asn1.ASN1Primitive; import org.bouncycastle.asn1.ASN1Sequence; import org.bouncycastle.asn1.ASN1TaggedObject; import org.bouncycastle.asn1.DERBitString; import org.bouncycastle.asn1.DERSequence; /** * The object that contains the public key stored in a certficate. *

    * The getEncoded() method in the public keys in the JCE produces a DER * encoded one of these. */ public class SubjectPublicKeyInfo extends ASN1Object { private AlgorithmIdentifier algId; private DERBitString keyData; public static SubjectPublicKeyInfo getInstance( ASN1TaggedObject obj, boolean explicit) { return getInstance(ASN1Sequence.getInstance(obj, explicit)); } public static SubjectPublicKeyInfo getInstance( Object obj) { if (obj instanceof SubjectPublicKeyInfo) { return (SubjectPublicKeyInfo)obj; } else if (obj != null) { return new SubjectPublicKeyInfo(ASN1Sequence.getInstance(obj)); } return null; } public SubjectPublicKeyInfo( AlgorithmIdentifier algId, ASN1Encodable publicKey) throws IOException { this.keyData = new DERBitString(publicKey); this.algId = algId; } public SubjectPublicKeyInfo( AlgorithmIdentifier algId, byte[] publicKey) { this.keyData = new DERBitString(publicKey); this.algId = algId; } public SubjectPublicKeyInfo( ASN1Sequence seq) { if (seq.size() != 2) { throw new IllegalArgumentException("Bad sequence size: " + seq.size()); } Enumeration e = seq.getObjects(); this.algId = AlgorithmIdentifier.getInstance(e.nextElement()); this.keyData = DERBitString.getInstance(e.nextElement()); } public AlgorithmIdentifier getAlgorithm() { return algId; } /** * @deprecated use getAlgorithm() * @return alg ID. */ public AlgorithmIdentifier getAlgorithmId() { return algId; } /** * for when the public key is an encoded object - if the bitstring * can't be decoded this routine throws an IOException. * * @exception IOException - if the bit string doesn't represent a DER * encoded object. * @return the public key as an ASN.1 primitive. */ public ASN1Primitive parsePublicKey() throws IOException { ASN1InputStream aIn = new ASN1InputStream(keyData.getBytes()); return aIn.readObject(); } /** * for when the public key is an encoded object - if the bitstring * can't be decoded this routine throws an IOException. * * @exception IOException - if the bit string doesn't represent a DER * encoded object. * @deprecated use parsePublicKey * @return the public key as an ASN.1 primitive. */ public ASN1Primitive getPublicKey() throws IOException { ASN1InputStream aIn = new ASN1InputStream(keyData.getBytes()); return aIn.readObject(); } /** * for when the public key is raw bits. * * @return the public key as the raw bit string... */ public DERBitString getPublicKeyData() { return keyData; } /** * Produce an object suitable for an ASN1OutputStream. *

         * SubjectPublicKeyInfo ::= SEQUENCE {
         *                          algorithm AlgorithmIdentifier,
         *                          publicKey BIT STRING }
         * 
    */ public ASN1Primitive toASN1Primitive() { ASN1EncodableVector v = new ASN1EncodableVector(); v.add(algId); v.add(keyData); return new DERSequence(v); } } bouncycastle-1.49.orig/src/org/bouncycastle/asn1/x509/DistributionPoint.java0000644000175000017500000001033511624652552026417 0ustar ebourgebourgpackage org.bouncycastle.asn1.x509; import org.bouncycastle.asn1.ASN1EncodableVector; import org.bouncycastle.asn1.ASN1Object; import org.bouncycastle.asn1.ASN1Primitive; import org.bouncycastle.asn1.ASN1Sequence; import org.bouncycastle.asn1.ASN1TaggedObject; import org.bouncycastle.asn1.DERBitString; import org.bouncycastle.asn1.DERSequence; import org.bouncycastle.asn1.DERTaggedObject; /** * The DistributionPoint object. *
     * DistributionPoint ::= SEQUENCE {
     *      distributionPoint [0] DistributionPointName OPTIONAL,
     *      reasons           [1] ReasonFlags OPTIONAL,
     *      cRLIssuer         [2] GeneralNames OPTIONAL
     * }
     * 
    */ public class DistributionPoint extends ASN1Object { DistributionPointName distributionPoint; ReasonFlags reasons; GeneralNames cRLIssuer; public static DistributionPoint getInstance( ASN1TaggedObject obj, boolean explicit) { return getInstance(ASN1Sequence.getInstance(obj, explicit)); } public static DistributionPoint getInstance( Object obj) { if(obj == null || obj instanceof DistributionPoint) { return (DistributionPoint)obj; } if(obj instanceof ASN1Sequence) { return new DistributionPoint((ASN1Sequence)obj); } throw new IllegalArgumentException("Invalid DistributionPoint: " + obj.getClass().getName()); } public DistributionPoint( ASN1Sequence seq) { for (int i = 0; i != seq.size(); i++) { ASN1TaggedObject t = ASN1TaggedObject.getInstance(seq.getObjectAt(i)); switch (t.getTagNo()) { case 0: distributionPoint = DistributionPointName.getInstance(t, true); break; case 1: reasons = new ReasonFlags(DERBitString.getInstance(t, false)); break; case 2: cRLIssuer = GeneralNames.getInstance(t, false); } } } public DistributionPoint( DistributionPointName distributionPoint, ReasonFlags reasons, GeneralNames cRLIssuer) { this.distributionPoint = distributionPoint; this.reasons = reasons; this.cRLIssuer = cRLIssuer; } public DistributionPointName getDistributionPoint() { return distributionPoint; } public ReasonFlags getReasons() { return reasons; } public GeneralNames getCRLIssuer() { return cRLIssuer; } public ASN1Primitive toASN1Primitive() { ASN1EncodableVector v = new ASN1EncodableVector(); if (distributionPoint != null) { // // as this is a CHOICE it must be explicitly tagged // v.add(new DERTaggedObject(0, distributionPoint)); } if (reasons != null) { v.add(new DERTaggedObject(false, 1, reasons)); } if (cRLIssuer != null) { v.add(new DERTaggedObject(false, 2, cRLIssuer)); } return new DERSequence(v); } public String toString() { String sep = System.getProperty("line.separator"); StringBuffer buf = new StringBuffer(); buf.append("DistributionPoint: ["); buf.append(sep); if (distributionPoint != null) { appendObject(buf, sep, "distributionPoint", distributionPoint.toString()); } if (reasons != null) { appendObject(buf, sep, "reasons", reasons.toString()); } if (cRLIssuer != null) { appendObject(buf, sep, "cRLIssuer", cRLIssuer.toString()); } buf.append("]"); buf.append(sep); return buf.toString(); } private void appendObject(StringBuffer buf, String sep, String name, String value) { String indent = " "; buf.append(indent); buf.append(name); buf.append(":"); buf.append(sep); buf.append(indent); buf.append(indent); buf.append(value); buf.append(sep); } } bouncycastle-1.49.orig/src/org/bouncycastle/asn1/x509/NoticeReference.java0000644000175000017500000001051411726002317025754 0ustar ebourgebourgpackage org.bouncycastle.asn1.x509; import java.math.BigInteger; import java.util.Enumeration; import java.util.Vector; import org.bouncycastle.asn1.ASN1EncodableVector; import org.bouncycastle.asn1.ASN1Integer; import org.bouncycastle.asn1.ASN1Object; import org.bouncycastle.asn1.ASN1Primitive; import org.bouncycastle.asn1.ASN1Sequence; import org.bouncycastle.asn1.DERSequence; /** * NoticeReference class, used in * CertificatePolicies X509 V3 extensions * (in policy qualifiers). * *
     *  NoticeReference ::= SEQUENCE {
     *      organization     DisplayText,
     *      noticeNumbers    SEQUENCE OF INTEGER }
     *
     * 
    * * @see PolicyQualifierInfo * @see PolicyInformation */ public class NoticeReference extends ASN1Object { private DisplayText organization; private ASN1Sequence noticeNumbers; private static ASN1EncodableVector convertVector(Vector numbers) { ASN1EncodableVector av = new ASN1EncodableVector(); Enumeration it = numbers.elements(); while (it.hasMoreElements()) { Object o = it.nextElement(); ASN1Integer di; if (o instanceof BigInteger) { di = new ASN1Integer((BigInteger)o); } else if (o instanceof Integer) { di = new ASN1Integer(((Integer)o).intValue()); } else { throw new IllegalArgumentException(); } av.add(di); } return av; } /** * Creates a new NoticeReference instance. * * @param organization a String value * @param numbers a Vector value */ public NoticeReference( String organization, Vector numbers) { this(organization, convertVector(numbers)); } /** * Creates a new NoticeReference instance. * * @param organization a String value * @param noticeNumbers an ASN1EncodableVector value */ public NoticeReference( String organization, ASN1EncodableVector noticeNumbers) { this(new DisplayText(organization), noticeNumbers); } /** * Creates a new NoticeReference instance. * * @param organization displayText * @param noticeNumbers an ASN1EncodableVector value */ public NoticeReference( DisplayText organization, ASN1EncodableVector noticeNumbers) { this.organization = organization; this.noticeNumbers = new DERSequence(noticeNumbers); } /** * Creates a new NoticeReference instance. *

    Useful for reconstructing a NoticeReference * instance from its encodable/encoded form. * * @param as an ASN1Sequence value obtained from either * calling @{link toASN1Primitive()} for a NoticeReference * instance or from parsing it from a DER-encoded stream. */ private NoticeReference( ASN1Sequence as) { if (as.size() != 2) { throw new IllegalArgumentException("Bad sequence size: " + as.size()); } organization = DisplayText.getInstance(as.getObjectAt(0)); noticeNumbers = ASN1Sequence.getInstance(as.getObjectAt(1)); } public static NoticeReference getInstance( Object as) { if (as instanceof NoticeReference) { return (NoticeReference)as; } else if (as != null) { return new NoticeReference(ASN1Sequence.getInstance(as)); } return null; } public DisplayText getOrganization() { return organization; } public ASN1Integer[] getNoticeNumbers() { ASN1Integer[] tmp = new ASN1Integer[noticeNumbers.size()]; for (int i = 0; i != noticeNumbers.size(); i++) { tmp[i] = ASN1Integer.getInstance(noticeNumbers.getObjectAt(i)); } return tmp; } /** * Describe toASN1Object method here. * * @return a ASN1Primitive value */ public ASN1Primitive toASN1Primitive() { ASN1EncodableVector av = new ASN1EncodableVector(); av.add (organization); av.add (noticeNumbers); return new DERSequence (av); } } bouncycastle-1.49.orig/src/org/bouncycastle/asn1/x509/Certificate.java0000644000175000017500000000541711724256221025147 0ustar ebourgebourgpackage org.bouncycastle.asn1.x509; import org.bouncycastle.asn1.ASN1Integer; import org.bouncycastle.asn1.ASN1Object; import org.bouncycastle.asn1.ASN1Primitive; import org.bouncycastle.asn1.ASN1Sequence; import org.bouncycastle.asn1.ASN1TaggedObject; import org.bouncycastle.asn1.DERBitString; import org.bouncycastle.asn1.x500.X500Name; /** * an X509Certificate structure. *

     *  Certificate ::= SEQUENCE {
     *      tbsCertificate          TBSCertificate,
     *      signatureAlgorithm      AlgorithmIdentifier,
     *      signature               BIT STRING
     *  }
     * 
    */ public class Certificate extends ASN1Object { ASN1Sequence seq; TBSCertificate tbsCert; AlgorithmIdentifier sigAlgId; DERBitString sig; public static Certificate getInstance( ASN1TaggedObject obj, boolean explicit) { return getInstance(ASN1Sequence.getInstance(obj, explicit)); } public static Certificate getInstance( Object obj) { if (obj instanceof Certificate) { return (Certificate)obj; } else if (obj != null) { return new Certificate(ASN1Sequence.getInstance(obj)); } return null; } private Certificate( ASN1Sequence seq) { this.seq = seq; // // correct x509 certficate // if (seq.size() == 3) { tbsCert = TBSCertificate.getInstance(seq.getObjectAt(0)); sigAlgId = AlgorithmIdentifier.getInstance(seq.getObjectAt(1)); sig = DERBitString.getInstance(seq.getObjectAt(2)); } else { throw new IllegalArgumentException("sequence wrong size for a certificate"); } } public TBSCertificate getTBSCertificate() { return tbsCert; } public ASN1Integer getVersion() { return tbsCert.getVersion(); } public int getVersionNumber() { return tbsCert.getVersionNumber(); } public ASN1Integer getSerialNumber() { return tbsCert.getSerialNumber(); } public X500Name getIssuer() { return tbsCert.getIssuer(); } public Time getStartDate() { return tbsCert.getStartDate(); } public Time getEndDate() { return tbsCert.getEndDate(); } public X500Name getSubject() { return tbsCert.getSubject(); } public SubjectPublicKeyInfo getSubjectPublicKeyInfo() { return tbsCert.getSubjectPublicKeyInfo(); } public AlgorithmIdentifier getSignatureAlgorithm() { return sigAlgId; } public DERBitString getSignature() { return sig; } public ASN1Primitive toASN1Primitive() { return seq; } } bouncycastle-1.49.orig/src/org/bouncycastle/asn1/x509/Target.java0000644000175000017500000000711011725273166024153 0ustar ebourgebourgpackage org.bouncycastle.asn1.x509; import org.bouncycastle.asn1.ASN1Choice; import org.bouncycastle.asn1.ASN1Object; import org.bouncycastle.asn1.ASN1Primitive; import org.bouncycastle.asn1.ASN1TaggedObject; import org.bouncycastle.asn1.DERTaggedObject; /** * Target structure used in target information extension for attribute * certificates from RFC 3281. * *
     *     Target  ::= CHOICE {
     *       targetName          [0] GeneralName,
     *       targetGroup         [1] GeneralName,
     *       targetCert          [2] TargetCert
     *     }
     * 
    * *

    * The targetCert field is currently not supported and must not be used * according to RFC 3281. */ public class Target extends ASN1Object implements ASN1Choice { public static final int targetName = 0; public static final int targetGroup = 1; private GeneralName targName; private GeneralName targGroup; /** * Creates an instance of a Target from the given object. *

    * obj can be a Target or a {@link ASN1TaggedObject} * * @param obj The object. * @return A Target instance. * @throws IllegalArgumentException if the given object cannot be * interpreted as Target. */ public static Target getInstance(Object obj) { if (obj == null || obj instanceof Target) { return (Target) obj; } else if (obj instanceof ASN1TaggedObject) { return new Target((ASN1TaggedObject)obj); } throw new IllegalArgumentException("unknown object in factory: " + obj.getClass()); } /** * Constructor from ASN1TaggedObject. * * @param tagObj The tagged object. * @throws IllegalArgumentException if the encoding is wrong. */ private Target(ASN1TaggedObject tagObj) { switch (tagObj.getTagNo()) { case targetName: // GeneralName is already a choice so explicit targName = GeneralName.getInstance(tagObj, true); break; case targetGroup: targGroup = GeneralName.getInstance(tagObj, true); break; default: throw new IllegalArgumentException("unknown tag: " + tagObj.getTagNo()); } } /** * Constructor from given details. *

    * Exactly one of the parameters must be not null. * * @param type the choice type to apply to the name. * @param name the general name. * @throws IllegalArgumentException if type is invalid. */ public Target(int type, GeneralName name) { this(new DERTaggedObject(type, name)); } /** * @return Returns the targetGroup. */ public GeneralName getTargetGroup() { return targGroup; } /** * @return Returns the targetName. */ public GeneralName getTargetName() { return targName; } /** * Produce an object suitable for an ASN1OutputStream. * * Returns: * *

         *     Target  ::= CHOICE {
         *       targetName          [0] GeneralName,
         *       targetGroup         [1] GeneralName,
         *       targetCert          [2] TargetCert
         *     }
         * 
    * * @return a ASN1Primitive */ public ASN1Primitive toASN1Primitive() { // GeneralName is a choice already so most be explicitly tagged if (targName != null) { return new DERTaggedObject(true, 0, targName); } else { return new DERTaggedObject(true, 1, targGroup); } } } bouncycastle-1.49.orig/src/org/bouncycastle/asn1/x509/Attribute.java0000644000175000017500000000434111725023645024666 0ustar ebourgebourgpackage org.bouncycastle.asn1.x509; import org.bouncycastle.asn1.ASN1Encodable; import org.bouncycastle.asn1.ASN1EncodableVector; import org.bouncycastle.asn1.ASN1Object; import org.bouncycastle.asn1.ASN1ObjectIdentifier; import org.bouncycastle.asn1.ASN1Primitive; import org.bouncycastle.asn1.ASN1Sequence; import org.bouncycastle.asn1.ASN1Set; import org.bouncycastle.asn1.DERSequence; public class Attribute extends ASN1Object { private ASN1ObjectIdentifier attrType; private ASN1Set attrValues; /** * return an Attribute object from the given object. * * @param o the object we want converted. * @exception IllegalArgumentException if the object cannot be converted. */ public static Attribute getInstance( Object o) { if (o instanceof Attribute) { return (Attribute)o; } if (o != null) { return new Attribute(ASN1Sequence.getInstance(o)); } return null; } private Attribute( ASN1Sequence seq) { if (seq.size() != 2) { throw new IllegalArgumentException("Bad sequence size: " + seq.size()); } attrType = ASN1ObjectIdentifier.getInstance(seq.getObjectAt(0)); attrValues = ASN1Set.getInstance(seq.getObjectAt(1)); } public Attribute( ASN1ObjectIdentifier attrType, ASN1Set attrValues) { this.attrType = attrType; this.attrValues = attrValues; } public ASN1ObjectIdentifier getAttrType() { return new ASN1ObjectIdentifier(attrType.getId()); } public ASN1Encodable[] getAttributeValues() { return attrValues.toArray(); } public ASN1Set getAttrValues() { return attrValues; } /** * Produce an object suitable for an ASN1OutputStream. *
         * Attribute ::= SEQUENCE {
         *     attrType OBJECT IDENTIFIER,
         *     attrValues SET OF AttributeValue
         * }
         * 
    */ public ASN1Primitive toASN1Primitive() { ASN1EncodableVector v = new ASN1EncodableVector(); v.add(attrType); v.add(attrValues); return new DERSequence(v); } } bouncycastle-1.49.orig/src/org/bouncycastle/asn1/x509/CRLDistPoint.java0000644000175000017500000000454511725011134025175 0ustar ebourgebourgpackage org.bouncycastle.asn1.x509; import org.bouncycastle.asn1.ASN1EncodableVector; import org.bouncycastle.asn1.ASN1Object; import org.bouncycastle.asn1.ASN1Primitive; import org.bouncycastle.asn1.ASN1Sequence; import org.bouncycastle.asn1.ASN1TaggedObject; import org.bouncycastle.asn1.DERSequence; public class CRLDistPoint extends ASN1Object { ASN1Sequence seq = null; public static CRLDistPoint getInstance( ASN1TaggedObject obj, boolean explicit) { return getInstance(ASN1Sequence.getInstance(obj, explicit)); } public static CRLDistPoint getInstance( Object obj) { if (obj instanceof CRLDistPoint) { return (CRLDistPoint)obj; } else if (obj != null) { return new CRLDistPoint(ASN1Sequence.getInstance(obj)); } return null; } private CRLDistPoint( ASN1Sequence seq) { this.seq = seq; } public CRLDistPoint( DistributionPoint[] points) { ASN1EncodableVector v = new ASN1EncodableVector(); for (int i = 0; i != points.length; i++) { v.add(points[i]); } seq = new DERSequence(v); } /** * Return the distribution points making up the sequence. * * @return DistributionPoint[] */ public DistributionPoint[] getDistributionPoints() { DistributionPoint[] dp = new DistributionPoint[seq.size()]; for (int i = 0; i != seq.size(); i++) { dp[i] = DistributionPoint.getInstance(seq.getObjectAt(i)); } return dp; } /** * Produce an object suitable for an ASN1OutputStream. *
         * CRLDistPoint ::= SEQUENCE SIZE {1..MAX} OF DistributionPoint
         * 
    */ public ASN1Primitive toASN1Primitive() { return seq; } public String toString() { StringBuffer buf = new StringBuffer(); String sep = System.getProperty("line.separator"); buf.append("CRLDistPoint:"); buf.append(sep); DistributionPoint dp[] = getDistributionPoints(); for (int i = 0; i != dp.length; i++) { buf.append(" "); buf.append(dp[i]); buf.append(sep); } return buf.toString(); } } bouncycastle-1.49.orig/src/org/bouncycastle/asn1/x509/CertificatePair.java0000644000175000017500000001167711736740374026002 0ustar ebourgebourgpackage org.bouncycastle.asn1.x509; import java.util.Enumeration; import org.bouncycastle.asn1.ASN1EncodableVector; import org.bouncycastle.asn1.ASN1Object; import org.bouncycastle.asn1.ASN1Primitive; import org.bouncycastle.asn1.ASN1Sequence; import org.bouncycastle.asn1.ASN1TaggedObject; import org.bouncycastle.asn1.DERSequence; import org.bouncycastle.asn1.DERTaggedObject; /** * This class helps to support crossCerfificatePairs in a LDAP directory * according RFC 2587 * *
     *     crossCertificatePairATTRIBUTE::={
     *       WITH SYNTAX   CertificatePair
     *       EQUALITY MATCHING RULE certificatePairExactMatch
     *       ID joint-iso-ccitt(2) ds(5) attributeType(4) crossCertificatePair(40)}
     * 
    * *
    The forward elements of the crossCertificatePair attribute of a * CA's directory entry shall be used to store all, except self-issued * certificates issued to this CA. Optionally, the reverse elements of the * crossCertificatePair attribute, of a CA's directory entry may contain a * subset of certificates issued by this CA to other CAs. When both the forward * and the reverse elements are present in a single attribute value, issuer name * in one certificate shall match the subject name in the other and vice versa, * and the subject public key in one certificate shall be capable of verifying * the digital signature on the other certificate and vice versa. * * When a reverse element is present, the forward element value and the reverse * element value need not be stored in the same attribute value; in other words, * they can be stored in either a single attribute value or two attribute * values.
    * *
     *       CertificatePair ::= SEQUENCE {
     *         forward        [0]    Certificate OPTIONAL,
     *         reverse        [1]    Certificate OPTIONAL,
     *         -- at least one of the pair shall be present -- } 
     * 
    */ public class CertificatePair extends ASN1Object { private Certificate forward; private Certificate reverse; public static CertificatePair getInstance(Object obj) { if (obj == null || obj instanceof CertificatePair) { return (CertificatePair)obj; } if (obj instanceof ASN1Sequence) { return new CertificatePair((ASN1Sequence)obj); } throw new IllegalArgumentException("illegal object in getInstance: " + obj.getClass().getName()); } /** * Constructor from ASN1Sequence. *

    * The sequence is of type CertificatePair: *

    *

         *       CertificatePair ::= SEQUENCE {
         *         forward        [0]    Certificate OPTIONAL,
         *         reverse        [1]    Certificate OPTIONAL,
         *         -- at least one of the pair shall be present -- }
         * 
    * * @param seq The ASN.1 sequence. */ private CertificatePair(ASN1Sequence seq) { if (seq.size() != 1 && seq.size() != 2) { throw new IllegalArgumentException("Bad sequence size: " + seq.size()); } Enumeration e = seq.getObjects(); while (e.hasMoreElements()) { ASN1TaggedObject o = ASN1TaggedObject.getInstance(e.nextElement()); if (o.getTagNo() == 0) { forward = Certificate.getInstance(o, true); } else if (o.getTagNo() == 1) { reverse = Certificate.getInstance(o, true); } else { throw new IllegalArgumentException("Bad tag number: " + o.getTagNo()); } } } /** * Constructor from a given details. * * @param forward Certificates issued to this CA. * @param reverse Certificates issued by this CA to other CAs. */ public CertificatePair(Certificate forward, Certificate reverse) { this.forward = forward; this.reverse = reverse; } /** * Produce an object suitable for an ASN1OutputStream. *

    * Returns: *

    *

         *       CertificatePair ::= SEQUENCE {
         *         forward        [0]    Certificate OPTIONAL,
         *         reverse        [1]    Certificate OPTIONAL,
         *         -- at least one of the pair shall be present -- }
         * 
    * * @return a ASN1Primitive */ public ASN1Primitive toASN1Primitive() { ASN1EncodableVector vec = new ASN1EncodableVector(); if (forward != null) { vec.add(new DERTaggedObject(0, forward)); } if (reverse != null) { vec.add(new DERTaggedObject(1, reverse)); } return new DERSequence(vec); } /** * @return Returns the forward. */ public Certificate getForward() { return forward; } /** * @return Returns the reverse. */ public Certificate getReverse() { return reverse; } } bouncycastle-1.49.orig/src/org/bouncycastle/asn1/x509/RoleSyntax.java0000644000175000017500000001616711624651554025050 0ustar ebourgebourgpackage org.bouncycastle.asn1.x509; import org.bouncycastle.asn1.ASN1Encodable; import org.bouncycastle.asn1.ASN1EncodableVector; import org.bouncycastle.asn1.ASN1Object; import org.bouncycastle.asn1.ASN1Primitive; import org.bouncycastle.asn1.ASN1Sequence; import org.bouncycastle.asn1.ASN1String; import org.bouncycastle.asn1.ASN1TaggedObject; import org.bouncycastle.asn1.DERSequence; import org.bouncycastle.asn1.DERTaggedObject; /** * Implementation of the RoleSyntax object as specified by the RFC3281. * *
     * RoleSyntax ::= SEQUENCE {
     *                 roleAuthority  [0] GeneralNames OPTIONAL,
     *                 roleName       [1] GeneralName
     *           } 
     * 
    */ public class RoleSyntax extends ASN1Object { private GeneralNames roleAuthority; private GeneralName roleName; /** * RoleSyntax factory method. * @param obj the object used to construct an instance of * RoleSyntax. It must be an instance of RoleSyntax * or ASN1Sequence. * @return the instance of RoleSyntax built from the * supplied object. * @throws java.lang.IllegalArgumentException if the object passed * to the factory is not an instance of RoleSyntax or * ASN1Sequence. */ public static RoleSyntax getInstance( Object obj) { if (obj instanceof RoleSyntax) { return (RoleSyntax)obj; } else if (obj != null) { return new RoleSyntax(ASN1Sequence.getInstance(obj)); } return null; } /** * Constructor. * @param roleAuthority the role authority of this RoleSyntax. * @param roleName the role name of this RoleSyntax. */ public RoleSyntax( GeneralNames roleAuthority, GeneralName roleName) { if(roleName == null || roleName.getTagNo() != GeneralName.uniformResourceIdentifier || ((ASN1String)roleName.getName()).getString().equals("")) { throw new IllegalArgumentException("the role name MUST be non empty and MUST " + "use the URI option of GeneralName"); } this.roleAuthority = roleAuthority; this.roleName = roleName; } /** * Constructor. Invoking this constructor is the same as invoking * new RoleSyntax(null, roleName). * @param roleName the role name of this RoleSyntax. */ public RoleSyntax( GeneralName roleName) { this(null, roleName); } /** * Utility constructor. Takes a String argument representing * the role name, builds a GeneralName to hold the role name * and calls the constructor that takes a GeneralName. * @param roleName */ public RoleSyntax( String roleName) { this(new GeneralName(GeneralName.uniformResourceIdentifier, (roleName == null)? "": roleName)); } /** * Constructor that builds an instance of RoleSyntax by * extracting the encoded elements from the ASN1Sequence * object supplied. * @param seq an instance of ASN1Sequence that holds * the encoded elements used to build this RoleSyntax. */ private RoleSyntax( ASN1Sequence seq) { if (seq.size() < 1 || seq.size() > 2) { throw new IllegalArgumentException("Bad sequence size: " + seq.size()); } for (int i = 0; i != seq.size(); i++) { ASN1TaggedObject taggedObject = ASN1TaggedObject.getInstance(seq.getObjectAt(i)); switch (taggedObject.getTagNo()) { case 0: roleAuthority = GeneralNames.getInstance(taggedObject, false); break; case 1: roleName = GeneralName.getInstance(taggedObject, true); break; default: throw new IllegalArgumentException("Unknown tag in RoleSyntax"); } } } /** * Gets the role authority of this RoleSyntax. * @return an instance of GeneralNames holding the * role authority of this RoleSyntax. */ public GeneralNames getRoleAuthority() { return this.roleAuthority; } /** * Gets the role name of this RoleSyntax. * @return an instance of GeneralName holding the * role name of this RoleSyntax. */ public GeneralName getRoleName() { return this.roleName; } /** * Gets the role name as a java.lang.String object. * @return the role name of this RoleSyntax represented as a * java.lang.String object. */ public String getRoleNameAsString() { ASN1String str = (ASN1String)this.roleName.getName(); return str.getString(); } /** * Gets the role authority as a String[] object. * @return the role authority of this RoleSyntax represented as a * String[] array. */ public String[] getRoleAuthorityAsString() { if(roleAuthority == null) { return new String[0]; } GeneralName[] names = roleAuthority.getNames(); String[] namesString = new String[names.length]; for(int i = 0; i < names.length; i++) { ASN1Encodable value = names[i].getName(); if(value instanceof ASN1String) { namesString[i] = ((ASN1String)value).getString(); } else { namesString[i] = value.toString(); } } return namesString; } /** * Implementation of the method toASN1Object as * required by the superclass ASN1Encodable. * *
         * RoleSyntax ::= SEQUENCE {
         *                 roleAuthority  [0] GeneralNames OPTIONAL,
         *                 roleName       [1] GeneralName
         *           } 
         * 
    */ public ASN1Primitive toASN1Primitive() { ASN1EncodableVector v = new ASN1EncodableVector(); if(this.roleAuthority != null) { v.add(new DERTaggedObject(false, 0, roleAuthority)); } v.add(new DERTaggedObject(true, 1, roleName)); return new DERSequence(v); } public String toString() { StringBuffer buff = new StringBuffer("Name: " + this.getRoleNameAsString() + " - Auth: "); if(this.roleAuthority == null || roleAuthority.getNames().length == 0) { buff.append("N/A"); } else { String[] names = this.getRoleAuthorityAsString(); buff.append('[').append(names[0]); for(int i = 1; i < names.length; i++) { buff.append(", ").append(names[i]); } buff.append(']'); } return buff.toString(); } } bouncycastle-1.49.orig/src/org/bouncycastle/asn1/x509/PolicyInformation.java0000644000175000017500000000434711725304160026370 0ustar ebourgebourgpackage org.bouncycastle.asn1.x509; import org.bouncycastle.asn1.ASN1EncodableVector; import org.bouncycastle.asn1.ASN1Object; import org.bouncycastle.asn1.ASN1ObjectIdentifier; import org.bouncycastle.asn1.ASN1Primitive; import org.bouncycastle.asn1.ASN1Sequence; import org.bouncycastle.asn1.DERSequence; public class PolicyInformation extends ASN1Object { private ASN1ObjectIdentifier policyIdentifier; private ASN1Sequence policyQualifiers; private PolicyInformation( ASN1Sequence seq) { if (seq.size() < 1 || seq.size() > 2) { throw new IllegalArgumentException("Bad sequence size: " + seq.size()); } policyIdentifier = ASN1ObjectIdentifier.getInstance(seq.getObjectAt(0)); if (seq.size() > 1) { policyQualifiers = ASN1Sequence.getInstance(seq.getObjectAt(1)); } } public PolicyInformation( ASN1ObjectIdentifier policyIdentifier) { this.policyIdentifier = policyIdentifier; } public PolicyInformation( ASN1ObjectIdentifier policyIdentifier, ASN1Sequence policyQualifiers) { this.policyIdentifier = policyIdentifier; this.policyQualifiers = policyQualifiers; } public static PolicyInformation getInstance( Object obj) { if (obj == null || obj instanceof PolicyInformation) { return (PolicyInformation)obj; } return new PolicyInformation(ASN1Sequence.getInstance(obj)); } public ASN1ObjectIdentifier getPolicyIdentifier() { return policyIdentifier; } public ASN1Sequence getPolicyQualifiers() { return policyQualifiers; } /* * PolicyInformation ::= SEQUENCE { * policyIdentifier CertPolicyId, * policyQualifiers SEQUENCE SIZE (1..MAX) OF * PolicyQualifierInfo OPTIONAL } */ public ASN1Primitive toASN1Primitive() { ASN1EncodableVector v = new ASN1EncodableVector(); v.add(policyIdentifier); if (policyQualifiers != null) { v.add(policyQualifiers); } return new DERSequence(v); } } bouncycastle-1.49.orig/src/org/bouncycastle/asn1/x509/NameConstraints.java0000644000175000017500000000563311737275254026050 0ustar ebourgebourgpackage org.bouncycastle.asn1.x509; import java.util.Enumeration; import org.bouncycastle.asn1.ASN1EncodableVector; import org.bouncycastle.asn1.ASN1Object; import org.bouncycastle.asn1.ASN1Primitive; import org.bouncycastle.asn1.ASN1Sequence; import org.bouncycastle.asn1.ASN1TaggedObject; import org.bouncycastle.asn1.DERSequence; import org.bouncycastle.asn1.DERTaggedObject; public class NameConstraints extends ASN1Object { private GeneralSubtree[] permitted, excluded; public static NameConstraints getInstance(Object obj) { if (obj instanceof NameConstraints) { return (NameConstraints)obj; } if (obj != null) { return new NameConstraints(ASN1Sequence.getInstance(obj)); } return null; } private NameConstraints(ASN1Sequence seq) { Enumeration e = seq.getObjects(); while (e.hasMoreElements()) { ASN1TaggedObject o = ASN1TaggedObject.getInstance(e.nextElement()); switch (o.getTagNo()) { case 0: permitted = createArray(ASN1Sequence.getInstance(o, false)); break; case 1: excluded = createArray(ASN1Sequence.getInstance(o, false)); break; } } } /** * Constructor from a given details. * *

    * permitted and excluded are arrays of GeneralSubtree objects. * * @param permitted * Permitted subtrees * @param excluded * Excludes subtrees */ public NameConstraints( GeneralSubtree[] permitted, GeneralSubtree[] excluded) { if (permitted != null) { this.permitted = permitted; } if (excluded != null) { this.excluded = excluded; } } private GeneralSubtree[] createArray(ASN1Sequence subtree) { GeneralSubtree[] ar = new GeneralSubtree[subtree.size()]; for (int i = 0; i != ar.length; i++) { ar[i] = GeneralSubtree.getInstance(subtree.getObjectAt(i)); } return ar; } public GeneralSubtree[] getPermittedSubtrees() { return permitted; } public GeneralSubtree[] getExcludedSubtrees() { return excluded; } /* * NameConstraints ::= SEQUENCE { permittedSubtrees [0] GeneralSubtrees * OPTIONAL, excludedSubtrees [1] GeneralSubtrees OPTIONAL } */ public ASN1Primitive toASN1Primitive() { ASN1EncodableVector v = new ASN1EncodableVector(); if (permitted != null) { v.add(new DERTaggedObject(false, 0, new DERSequence(permitted))); } if (excluded != null) { v.add(new DERTaggedObject(false, 1, new DERSequence(excluded))); } return new DERSequence(v); } } bouncycastle-1.49.orig/src/org/bouncycastle/asn1/x509/X509CertificateStructure.java0000644000175000017500000000572211724561172027461 0ustar ebourgebourgpackage org.bouncycastle.asn1.x509; import org.bouncycastle.asn1.ASN1Integer; import org.bouncycastle.asn1.ASN1Object; import org.bouncycastle.asn1.ASN1Primitive; import org.bouncycastle.asn1.ASN1Sequence; import org.bouncycastle.asn1.ASN1TaggedObject; import org.bouncycastle.asn1.DERBitString; import org.bouncycastle.asn1.pkcs.PKCSObjectIdentifiers; import org.bouncycastle.asn1.x500.X500Name; /** * an X509Certificate structure. *

     *  Certificate ::= SEQUENCE {
     *      tbsCertificate          TBSCertificate,
     *      signatureAlgorithm      AlgorithmIdentifier,
     *      signature               BIT STRING
     *  }
     * 
    * @deprecated use org.bouncycastle.asn1.x509.Certificate */ public class X509CertificateStructure extends ASN1Object implements X509ObjectIdentifiers, PKCSObjectIdentifiers { ASN1Sequence seq; TBSCertificateStructure tbsCert; AlgorithmIdentifier sigAlgId; DERBitString sig; public static X509CertificateStructure getInstance( ASN1TaggedObject obj, boolean explicit) { return getInstance(ASN1Sequence.getInstance(obj, explicit)); } public static X509CertificateStructure getInstance( Object obj) { if (obj instanceof X509CertificateStructure) { return (X509CertificateStructure)obj; } else if (obj != null) { return new X509CertificateStructure(ASN1Sequence.getInstance(obj)); } return null; } public X509CertificateStructure( ASN1Sequence seq) { this.seq = seq; // // correct x509 certficate // if (seq.size() == 3) { tbsCert = TBSCertificateStructure.getInstance(seq.getObjectAt(0)); sigAlgId = AlgorithmIdentifier.getInstance(seq.getObjectAt(1)); sig = DERBitString.getInstance(seq.getObjectAt(2)); } else { throw new IllegalArgumentException("sequence wrong size for a certificate"); } } public TBSCertificateStructure getTBSCertificate() { return tbsCert; } public int getVersion() { return tbsCert.getVersion(); } public ASN1Integer getSerialNumber() { return tbsCert.getSerialNumber(); } public X500Name getIssuer() { return tbsCert.getIssuer(); } public Time getStartDate() { return tbsCert.getStartDate(); } public Time getEndDate() { return tbsCert.getEndDate(); } public X500Name getSubject() { return tbsCert.getSubject(); } public SubjectPublicKeyInfo getSubjectPublicKeyInfo() { return tbsCert.getSubjectPublicKeyInfo(); } public AlgorithmIdentifier getSignatureAlgorithm() { return sigAlgId; } public DERBitString getSignature() { return sig; } public ASN1Primitive toASN1Primitive() { return seq; } } bouncycastle-1.49.orig/src/org/bouncycastle/asn1/x509/BasicConstraints.java0000644000175000017500000001024712070232721026165 0ustar ebourgebourgpackage org.bouncycastle.asn1.x509; import java.math.BigInteger; import org.bouncycastle.asn1.ASN1Boolean; import org.bouncycastle.asn1.ASN1EncodableVector; import org.bouncycastle.asn1.ASN1Integer; import org.bouncycastle.asn1.ASN1Object; import org.bouncycastle.asn1.ASN1Primitive; import org.bouncycastle.asn1.ASN1Sequence; import org.bouncycastle.asn1.ASN1TaggedObject; import org.bouncycastle.asn1.DERBoolean; import org.bouncycastle.asn1.DERSequence; public class BasicConstraints extends ASN1Object { ASN1Boolean cA = ASN1Boolean.getInstance(false); ASN1Integer pathLenConstraint = null; public static BasicConstraints getInstance( ASN1TaggedObject obj, boolean explicit) { return getInstance(ASN1Sequence.getInstance(obj, explicit)); } public static BasicConstraints getInstance( Object obj) { if (obj instanceof BasicConstraints) { return (BasicConstraints)obj; } if (obj instanceof X509Extension) { return getInstance(X509Extension.convertValueToObject((X509Extension)obj)); } if (obj != null) { return new BasicConstraints(ASN1Sequence.getInstance(obj)); } return null; } public static BasicConstraints fromExtensions(Extensions extensions) { return BasicConstraints.getInstance(extensions.getExtensionParsedValue(Extension.basicConstraints)); } private BasicConstraints( ASN1Sequence seq) { if (seq.size() == 0) { this.cA = null; this.pathLenConstraint = null; } else { if (seq.getObjectAt(0) instanceof DERBoolean) { this.cA = DERBoolean.getInstance(seq.getObjectAt(0)); } else { this.cA = null; this.pathLenConstraint = ASN1Integer.getInstance(seq.getObjectAt(0)); } if (seq.size() > 1) { if (this.cA != null) { this.pathLenConstraint = ASN1Integer.getInstance(seq.getObjectAt(1)); } else { throw new IllegalArgumentException("wrong sequence in constructor"); } } } } public BasicConstraints( boolean cA) { if (cA) { this.cA = ASN1Boolean.getInstance(true); } else { this.cA = null; } this.pathLenConstraint = null; } /** * create a cA=true object for the given path length constraint. * * @param pathLenConstraint */ public BasicConstraints( int pathLenConstraint) { this.cA = ASN1Boolean.getInstance(true); this.pathLenConstraint = new ASN1Integer(pathLenConstraint); } public boolean isCA() { return (cA != null) && cA.isTrue(); } public BigInteger getPathLenConstraint() { if (pathLenConstraint != null) { return pathLenConstraint.getValue(); } return null; } /** * Produce an object suitable for an ASN1OutputStream. *
         * BasicConstraints := SEQUENCE {
         *    cA                  BOOLEAN DEFAULT FALSE,
         *    pathLenConstraint   INTEGER (0..MAX) OPTIONAL
         * }
         * 
    */ public ASN1Primitive toASN1Primitive() { ASN1EncodableVector v = new ASN1EncodableVector(); if (cA != null) { v.add(cA); } if (pathLenConstraint != null) // yes some people actually do this when cA is false... { v.add(pathLenConstraint); } return new DERSequence(v); } public String toString() { if (pathLenConstraint == null) { if (cA == null) { return "BasicConstraints: isCa(false)"; } return "BasicConstraints: isCa(" + this.isCA() + ")"; } return "BasicConstraints: isCa(" + this.isCA() + "), pathLenConstraint = " + pathLenConstraint.getValue(); } } bouncycastle-1.49.orig/src/org/bouncycastle/asn1/x509/DigestInfo.java0000644000175000017500000000374311725272605024765 0ustar ebourgebourgpackage org.bouncycastle.asn1.x509; import java.util.Enumeration; import org.bouncycastle.asn1.ASN1EncodableVector; import org.bouncycastle.asn1.ASN1Object; import org.bouncycastle.asn1.ASN1OctetString; import org.bouncycastle.asn1.ASN1Primitive; import org.bouncycastle.asn1.ASN1Sequence; import org.bouncycastle.asn1.ASN1TaggedObject; import org.bouncycastle.asn1.DEROctetString; import org.bouncycastle.asn1.DERSequence; /** * The DigestInfo object. *
     * DigestInfo::=SEQUENCE{
     *          digestAlgorithm  AlgorithmIdentifier,
     *          digest OCTET STRING }
     * 
    */ public class DigestInfo extends ASN1Object { private byte[] digest; private AlgorithmIdentifier algId; public static DigestInfo getInstance( ASN1TaggedObject obj, boolean explicit) { return getInstance(ASN1Sequence.getInstance(obj, explicit)); } public static DigestInfo getInstance( Object obj) { if (obj instanceof DigestInfo) { return (DigestInfo)obj; } else if (obj != null) { return new DigestInfo(ASN1Sequence.getInstance(obj)); } return null; } public DigestInfo( AlgorithmIdentifier algId, byte[] digest) { this.digest = digest; this.algId = algId; } public DigestInfo( ASN1Sequence obj) { Enumeration e = obj.getObjects(); algId = AlgorithmIdentifier.getInstance(e.nextElement()); digest = ASN1OctetString.getInstance(e.nextElement()).getOctets(); } public AlgorithmIdentifier getAlgorithmId() { return algId; } public byte[] getDigest() { return digest; } public ASN1Primitive toASN1Primitive() { ASN1EncodableVector v = new ASN1EncodableVector(); v.add(algId); v.add(new DEROctetString(digest)); return new DERSequence(v); } } bouncycastle-1.49.orig/src/org/bouncycastle/asn1/x509/CertificateList.java0000644000175000017500000000566511724566440026017 0ustar ebourgebourg package org.bouncycastle.asn1.x509; import java.util.Enumeration; import org.bouncycastle.asn1.ASN1EncodableVector; import org.bouncycastle.asn1.ASN1Object; import org.bouncycastle.asn1.ASN1Primitive; import org.bouncycastle.asn1.ASN1Sequence; import org.bouncycastle.asn1.ASN1TaggedObject; import org.bouncycastle.asn1.DERBitString; import org.bouncycastle.asn1.DERSequence; import org.bouncycastle.asn1.x500.X500Name; /** * PKIX RFC-2459 * * The X.509 v2 CRL syntax is as follows. For signature calculation, * the data that is to be signed is ASN.1 DER encoded. * *
     * CertificateList  ::=  SEQUENCE  {
     *      tbsCertList          TBSCertList,
     *      signatureAlgorithm   AlgorithmIdentifier,
     *      signatureValue       BIT STRING  }
     * 
    */ public class CertificateList extends ASN1Object { TBSCertList tbsCertList; AlgorithmIdentifier sigAlgId; DERBitString sig; public static CertificateList getInstance( ASN1TaggedObject obj, boolean explicit) { return getInstance(ASN1Sequence.getInstance(obj, explicit)); } public static CertificateList getInstance( Object obj) { if (obj instanceof CertificateList) { return (CertificateList)obj; } else if (obj != null) { return new CertificateList(ASN1Sequence.getInstance(obj)); } return null; } public CertificateList( ASN1Sequence seq) { if (seq.size() == 3) { tbsCertList = TBSCertList.getInstance(seq.getObjectAt(0)); sigAlgId = AlgorithmIdentifier.getInstance(seq.getObjectAt(1)); sig = DERBitString.getInstance(seq.getObjectAt(2)); } else { throw new IllegalArgumentException("sequence wrong size for CertificateList"); } } public TBSCertList getTBSCertList() { return tbsCertList; } public TBSCertList.CRLEntry[] getRevokedCertificates() { return tbsCertList.getRevokedCertificates(); } public Enumeration getRevokedCertificateEnumeration() { return tbsCertList.getRevokedCertificateEnumeration(); } public AlgorithmIdentifier getSignatureAlgorithm() { return sigAlgId; } public DERBitString getSignature() { return sig; } public int getVersionNumber() { return tbsCertList.getVersionNumber(); } public X500Name getIssuer() { return tbsCertList.getIssuer(); } public Time getThisUpdate() { return tbsCertList.getThisUpdate(); } public Time getNextUpdate() { return tbsCertList.getNextUpdate(); } public ASN1Primitive toASN1Primitive() { ASN1EncodableVector v = new ASN1EncodableVector(); v.add(tbsCertList); v.add(sigAlgId); v.add(sig); return new DERSequence(v); } } bouncycastle-1.49.orig/src/org/bouncycastle/asn1/x509/X509Extensions.java0000644000175000017500000003336512103435260025447 0ustar ebourgebourgpackage org.bouncycastle.asn1.x509; import java.util.Enumeration; import java.util.Hashtable; import java.util.Vector; import org.bouncycastle.asn1.ASN1EncodableVector; import org.bouncycastle.asn1.ASN1Object; import org.bouncycastle.asn1.ASN1ObjectIdentifier; import org.bouncycastle.asn1.ASN1OctetString; import org.bouncycastle.asn1.ASN1Primitive; import org.bouncycastle.asn1.ASN1Sequence; import org.bouncycastle.asn1.ASN1TaggedObject; import org.bouncycastle.asn1.DERBoolean; import org.bouncycastle.asn1.DERObjectIdentifier; import org.bouncycastle.asn1.DERSequence; /** * @deprecated use Extensions */ public class X509Extensions extends ASN1Object { /** * Subject Directory Attributes * @deprecated use X509Extension value. */ public static final ASN1ObjectIdentifier SubjectDirectoryAttributes = new ASN1ObjectIdentifier("2.5.29.9"); /** * Subject Key Identifier * @deprecated use X509Extension value. */ public static final ASN1ObjectIdentifier SubjectKeyIdentifier = new ASN1ObjectIdentifier("2.5.29.14"); /** * Key Usage * @deprecated use X509Extension value. */ public static final ASN1ObjectIdentifier KeyUsage = new ASN1ObjectIdentifier("2.5.29.15"); /** * Private Key Usage Period * @deprecated use X509Extension value. */ public static final ASN1ObjectIdentifier PrivateKeyUsagePeriod = new ASN1ObjectIdentifier("2.5.29.16"); /** * Subject Alternative Name * @deprecated use X509Extension value. */ public static final ASN1ObjectIdentifier SubjectAlternativeName = new ASN1ObjectIdentifier("2.5.29.17"); /** * Issuer Alternative Name * @deprecated use X509Extension value. */ public static final ASN1ObjectIdentifier IssuerAlternativeName = new ASN1ObjectIdentifier("2.5.29.18"); /** * Basic Constraints * @deprecated use X509Extension value. */ public static final ASN1ObjectIdentifier BasicConstraints = new ASN1ObjectIdentifier("2.5.29.19"); /** * CRL Number * @deprecated use X509Extension value. */ public static final ASN1ObjectIdentifier CRLNumber = new ASN1ObjectIdentifier("2.5.29.20"); /** * Reason code * @deprecated use X509Extension value. */ public static final ASN1ObjectIdentifier ReasonCode = new ASN1ObjectIdentifier("2.5.29.21"); /** * Hold Instruction Code * @deprecated use X509Extension value. */ public static final ASN1ObjectIdentifier InstructionCode = new ASN1ObjectIdentifier("2.5.29.23"); /** * Invalidity Date * @deprecated use X509Extension value. */ public static final ASN1ObjectIdentifier InvalidityDate = new ASN1ObjectIdentifier("2.5.29.24"); /** * Delta CRL indicator * @deprecated use X509Extension value. */ public static final ASN1ObjectIdentifier DeltaCRLIndicator = new ASN1ObjectIdentifier("2.5.29.27"); /** * Issuing Distribution Point * @deprecated use X509Extension value. */ public static final ASN1ObjectIdentifier IssuingDistributionPoint = new ASN1ObjectIdentifier("2.5.29.28"); /** * Certificate Issuer * @deprecated use X509Extension value. */ public static final ASN1ObjectIdentifier CertificateIssuer = new ASN1ObjectIdentifier("2.5.29.29"); /** * Name Constraints * @deprecated use X509Extension value. */ public static final ASN1ObjectIdentifier NameConstraints = new ASN1ObjectIdentifier("2.5.29.30"); /** * CRL Distribution Points * @deprecated use X509Extension value. */ public static final ASN1ObjectIdentifier CRLDistributionPoints = new ASN1ObjectIdentifier("2.5.29.31"); /** * Certificate Policies * @deprecated use X509Extension value. */ public static final ASN1ObjectIdentifier CertificatePolicies = new ASN1ObjectIdentifier("2.5.29.32"); /** * Policy Mappings * @deprecated use X509Extension value. */ public static final ASN1ObjectIdentifier PolicyMappings = new ASN1ObjectIdentifier("2.5.29.33"); /** * Authority Key Identifier * @deprecated use X509Extension value. */ public static final ASN1ObjectIdentifier AuthorityKeyIdentifier = new ASN1ObjectIdentifier("2.5.29.35"); /** * Policy Constraints * @deprecated use X509Extension value. */ public static final ASN1ObjectIdentifier PolicyConstraints = new ASN1ObjectIdentifier("2.5.29.36"); /** * Extended Key Usage * @deprecated use X509Extension value. */ public static final ASN1ObjectIdentifier ExtendedKeyUsage = new ASN1ObjectIdentifier("2.5.29.37"); /** * Freshest CRL * @deprecated use X509Extension value. */ public static final ASN1ObjectIdentifier FreshestCRL = new ASN1ObjectIdentifier("2.5.29.46"); /** * Inhibit Any Policy * @deprecated use X509Extension value. */ public static final ASN1ObjectIdentifier InhibitAnyPolicy = new ASN1ObjectIdentifier("2.5.29.54"); /** * Authority Info Access * @deprecated use X509Extension value. */ public static final ASN1ObjectIdentifier AuthorityInfoAccess = new ASN1ObjectIdentifier("1.3.6.1.5.5.7.1.1"); /** * Subject Info Access * @deprecated use X509Extension value. */ public static final ASN1ObjectIdentifier SubjectInfoAccess = new ASN1ObjectIdentifier("1.3.6.1.5.5.7.1.11"); /** * Logo Type * @deprecated use X509Extension value. */ public static final ASN1ObjectIdentifier LogoType = new ASN1ObjectIdentifier("1.3.6.1.5.5.7.1.12"); /** * BiometricInfo * @deprecated use X509Extension value. */ public static final ASN1ObjectIdentifier BiometricInfo = new ASN1ObjectIdentifier("1.3.6.1.5.5.7.1.2"); /** * QCStatements * @deprecated use X509Extension value. */ public static final ASN1ObjectIdentifier QCStatements = new ASN1ObjectIdentifier("1.3.6.1.5.5.7.1.3"); /** * Audit identity extension in attribute certificates. * @deprecated use X509Extension value. */ public static final ASN1ObjectIdentifier AuditIdentity = new ASN1ObjectIdentifier("1.3.6.1.5.5.7.1.4"); /** * NoRevAvail extension in attribute certificates. * @deprecated use X509Extension value. */ public static final ASN1ObjectIdentifier NoRevAvail = new ASN1ObjectIdentifier("2.5.29.56"); /** * TargetInformation extension in attribute certificates. * @deprecated use X509Extension value. */ public static final ASN1ObjectIdentifier TargetInformation = new ASN1ObjectIdentifier("2.5.29.55"); private Hashtable extensions = new Hashtable(); private Vector ordering = new Vector(); public static X509Extensions getInstance( ASN1TaggedObject obj, boolean explicit) { return getInstance(ASN1Sequence.getInstance(obj, explicit)); } public static X509Extensions getInstance( Object obj) { if (obj == null || obj instanceof X509Extensions) { return (X509Extensions)obj; } if (obj instanceof ASN1Sequence) { return new X509Extensions((ASN1Sequence)obj); } if (obj instanceof Extensions) { return new X509Extensions((ASN1Sequence)((Extensions)obj).toASN1Primitive()); } if (obj instanceof ASN1TaggedObject) { return getInstance(((ASN1TaggedObject)obj).getObject()); } throw new IllegalArgumentException("illegal object in getInstance: " + obj.getClass().getName()); } /** * Constructor from ASN1Sequence. * * the extensions are a list of constructed sequences, either with (OID, OctetString) or (OID, Boolean, OctetString) */ public X509Extensions( ASN1Sequence seq) { Enumeration e = seq.getObjects(); while (e.hasMoreElements()) { ASN1Sequence s = ASN1Sequence.getInstance(e.nextElement()); if (s.size() == 3) { extensions.put(s.getObjectAt(0), new X509Extension(DERBoolean.getInstance(s.getObjectAt(1)), ASN1OctetString.getInstance(s.getObjectAt(2)))); } else if (s.size() == 2) { extensions.put(s.getObjectAt(0), new X509Extension(false, ASN1OctetString.getInstance(s.getObjectAt(1)))); } else { throw new IllegalArgumentException("Bad sequence size: " + s.size()); } ordering.addElement(s.getObjectAt(0)); } } /** * constructor from a table of extensions. *

    * it's is assumed the table contains OID/String pairs. */ public X509Extensions( Hashtable extensions) { this(null, extensions); } /** * Constructor from a table of extensions with ordering. *

    * It's is assumed the table contains OID/String pairs. * @deprecated use Extensions */ public X509Extensions( Vector ordering, Hashtable extensions) { Enumeration e; if (ordering == null) { e = extensions.keys(); } else { e = ordering.elements(); } while (e.hasMoreElements()) { this.ordering.addElement(ASN1ObjectIdentifier.getInstance(e.nextElement())); } e = this.ordering.elements(); while (e.hasMoreElements()) { ASN1ObjectIdentifier oid = ASN1ObjectIdentifier.getInstance(e.nextElement()); X509Extension ext = (X509Extension)extensions.get(oid); this.extensions.put(oid, ext); } } /** * Constructor from two vectors * * @param objectIDs a vector of the object identifiers. * @param values a vector of the extension values. * @deprecated use Extensions */ public X509Extensions( Vector objectIDs, Vector values) { Enumeration e = objectIDs.elements(); while (e.hasMoreElements()) { this.ordering.addElement(e.nextElement()); } int count = 0; e = this.ordering.elements(); while (e.hasMoreElements()) { ASN1ObjectIdentifier oid = (ASN1ObjectIdentifier)e.nextElement(); X509Extension ext = (X509Extension)values.elementAt(count); this.extensions.put(oid, ext); count++; } } /** * return an Enumeration of the extension field's object ids. */ public Enumeration oids() { return ordering.elements(); } /** * return the extension represented by the object identifier * passed in. * * @return the extension if it's present, null otherwise. */ public X509Extension getExtension( DERObjectIdentifier oid) { return (X509Extension)extensions.get(oid); } /** * @deprecated * @param oid * @return */ public X509Extension getExtension( ASN1ObjectIdentifier oid) { return (X509Extension)extensions.get(oid); } /** *

         *     Extensions        ::=   SEQUENCE SIZE (1..MAX) OF Extension
         *
         *     Extension         ::=   SEQUENCE {
         *        extnId            EXTENSION.&id ({ExtensionSet}),
         *        critical          BOOLEAN DEFAULT FALSE,
         *        extnValue         OCTET STRING }
         * 
    */ public ASN1Primitive toASN1Primitive() { ASN1EncodableVector vec = new ASN1EncodableVector(); Enumeration e = ordering.elements(); while (e.hasMoreElements()) { ASN1ObjectIdentifier oid = (ASN1ObjectIdentifier)e.nextElement(); X509Extension ext = (X509Extension)extensions.get(oid); ASN1EncodableVector v = new ASN1EncodableVector(); v.add(oid); if (ext.isCritical()) { v.add(DERBoolean.TRUE); } v.add(ext.getValue()); vec.add(new DERSequence(v)); } return new DERSequence(vec); } public boolean equivalent( X509Extensions other) { if (extensions.size() != other.extensions.size()) { return false; } Enumeration e1 = extensions.keys(); while (e1.hasMoreElements()) { Object key = e1.nextElement(); if (!extensions.get(key).equals(other.extensions.get(key))) { return false; } } return true; } public ASN1ObjectIdentifier[] getExtensionOIDs() { return toOidArray(ordering); } public ASN1ObjectIdentifier[] getNonCriticalExtensionOIDs() { return getExtensionOIDs(false); } public ASN1ObjectIdentifier[] getCriticalExtensionOIDs() { return getExtensionOIDs(true); } private ASN1ObjectIdentifier[] getExtensionOIDs(boolean isCritical) { Vector oidVec = new Vector(); for (int i = 0; i != ordering.size(); i++) { Object oid = ordering.elementAt(i); if (((X509Extension)extensions.get(oid)).isCritical() == isCritical) { oidVec.addElement(oid); } } return toOidArray(oidVec); } private ASN1ObjectIdentifier[] toOidArray(Vector oidVec) { ASN1ObjectIdentifier[] oids = new ASN1ObjectIdentifier[oidVec.size()]; for (int i = 0; i != oids.length; i++) { oids[i] = (ASN1ObjectIdentifier)oidVec.elementAt(i); } return oids; } } bouncycastle-1.49.orig/src/org/bouncycastle/asn1/x509/TBSCertificateStructure.java0000644000175000017500000001217711724561172027446 0ustar ebourgebourgpackage org.bouncycastle.asn1.x509; import org.bouncycastle.asn1.ASN1Integer; import org.bouncycastle.asn1.ASN1Object; import org.bouncycastle.asn1.ASN1Primitive; import org.bouncycastle.asn1.ASN1Sequence; import org.bouncycastle.asn1.ASN1TaggedObject; import org.bouncycastle.asn1.DERBitString; import org.bouncycastle.asn1.DERTaggedObject; import org.bouncycastle.asn1.pkcs.PKCSObjectIdentifiers; import org.bouncycastle.asn1.x500.X500Name; /** * The TBSCertificate object. *
     * TBSCertificate ::= SEQUENCE {
     *      version          [ 0 ]  Version DEFAULT v1(0),
     *      serialNumber            CertificateSerialNumber,
     *      signature               AlgorithmIdentifier,
     *      issuer                  Name,
     *      validity                Validity,
     *      subject                 Name,
     *      subjectPublicKeyInfo    SubjectPublicKeyInfo,
     *      issuerUniqueID    [ 1 ] IMPLICIT UniqueIdentifier OPTIONAL,
     *      subjectUniqueID   [ 2 ] IMPLICIT UniqueIdentifier OPTIONAL,
     *      extensions        [ 3 ] Extensions OPTIONAL
     *      }
     * 
    *

    * Note: issuerUniqueID and subjectUniqueID are both deprecated by the IETF. This class * will parse them, but you really shouldn't be creating new ones. */ public class TBSCertificateStructure extends ASN1Object implements X509ObjectIdentifiers, PKCSObjectIdentifiers { ASN1Sequence seq; ASN1Integer version; ASN1Integer serialNumber; AlgorithmIdentifier signature; X500Name issuer; Time startDate, endDate; X500Name subject; SubjectPublicKeyInfo subjectPublicKeyInfo; DERBitString issuerUniqueId; DERBitString subjectUniqueId; X509Extensions extensions; public static TBSCertificateStructure getInstance( ASN1TaggedObject obj, boolean explicit) { return getInstance(ASN1Sequence.getInstance(obj, explicit)); } public static TBSCertificateStructure getInstance( Object obj) { if (obj instanceof TBSCertificateStructure) { return (TBSCertificateStructure)obj; } else if (obj != null) { return new TBSCertificateStructure(ASN1Sequence.getInstance(obj)); } return null; } public TBSCertificateStructure( ASN1Sequence seq) { int seqStart = 0; this.seq = seq; // // some certficates don't include a version number - we assume v1 // if (seq.getObjectAt(0) instanceof DERTaggedObject) { version = ASN1Integer.getInstance((ASN1TaggedObject)seq.getObjectAt(0), true); } else { seqStart = -1; // field 0 is missing! version = new ASN1Integer(0); } serialNumber = ASN1Integer.getInstance(seq.getObjectAt(seqStart + 1)); signature = AlgorithmIdentifier.getInstance(seq.getObjectAt(seqStart + 2)); issuer = X500Name.getInstance(seq.getObjectAt(seqStart + 3)); // // before and after dates // ASN1Sequence dates = (ASN1Sequence)seq.getObjectAt(seqStart + 4); startDate = Time.getInstance(dates.getObjectAt(0)); endDate = Time.getInstance(dates.getObjectAt(1)); subject = X500Name.getInstance(seq.getObjectAt(seqStart + 5)); // // public key info. // subjectPublicKeyInfo = SubjectPublicKeyInfo.getInstance(seq.getObjectAt(seqStart + 6)); for (int extras = seq.size() - (seqStart + 6) - 1; extras > 0; extras--) { DERTaggedObject extra = (DERTaggedObject)seq.getObjectAt(seqStart + 6 + extras); switch (extra.getTagNo()) { case 1: issuerUniqueId = DERBitString.getInstance(extra, false); break; case 2: subjectUniqueId = DERBitString.getInstance(extra, false); break; case 3: extensions = X509Extensions.getInstance(extra); } } } public int getVersion() { return version.getValue().intValue() + 1; } public ASN1Integer getVersionNumber() { return version; } public ASN1Integer getSerialNumber() { return serialNumber; } public AlgorithmIdentifier getSignature() { return signature; } public X500Name getIssuer() { return issuer; } public Time getStartDate() { return startDate; } public Time getEndDate() { return endDate; } public X500Name getSubject() { return subject; } public SubjectPublicKeyInfo getSubjectPublicKeyInfo() { return subjectPublicKeyInfo; } public DERBitString getIssuerUniqueId() { return issuerUniqueId; } public DERBitString getSubjectUniqueId() { return subjectUniqueId; } public X509Extensions getExtensions() { return extensions; } public ASN1Primitive toASN1Primitive() { return seq; } } bouncycastle-1.49.orig/src/org/bouncycastle/asn1/x509/CertificatePolicies.java0000644000175000017500000000467511725303011026633 0ustar ebourgebourgpackage org.bouncycastle.asn1.x509; import org.bouncycastle.asn1.ASN1Object; import org.bouncycastle.asn1.ASN1Primitive; import org.bouncycastle.asn1.ASN1Sequence; import org.bouncycastle.asn1.ASN1TaggedObject; import org.bouncycastle.asn1.DERSequence; public class CertificatePolicies extends ASN1Object { private final PolicyInformation[] policyInformation; public static CertificatePolicies getInstance( Object obj) { if (obj instanceof CertificatePolicies) { return (CertificatePolicies)obj; } if (obj != null) { return new CertificatePolicies(ASN1Sequence.getInstance(obj)); } return null; } public static CertificatePolicies getInstance( ASN1TaggedObject obj, boolean explicit) { return getInstance(ASN1Sequence.getInstance(obj, explicit)); } /** * Construct a CertificatePolicies object containing one PolicyInformation. * * @param name the name to be contained. */ public CertificatePolicies( PolicyInformation name) { this.policyInformation = new PolicyInformation[] { name }; } public CertificatePolicies( PolicyInformation[] policyInformation) { this.policyInformation = policyInformation; } private CertificatePolicies( ASN1Sequence seq) { this.policyInformation = new PolicyInformation[seq.size()]; for (int i = 0; i != seq.size(); i++) { policyInformation[i] = PolicyInformation.getInstance(seq.getObjectAt(i)); } } public PolicyInformation[] getPolicyInformation() { PolicyInformation[] tmp = new PolicyInformation[policyInformation.length]; System.arraycopy(policyInformation, 0, tmp, 0, policyInformation.length); return tmp; } /** * Produce an object suitable for an ASN1OutputStream. *

         * CertificatePolicies ::= SEQUENCE SIZE {1..MAX} OF PolicyInformation
         * 
    */ public ASN1Primitive toASN1Primitive() { return new DERSequence(policyInformation); } public String toString() { String p = null; for (int i = 0; i < policyInformation.length; i++) { if (p != null) { p += ", "; } p += policyInformation[i]; } return "CertificatePolicies: " + p; } } bouncycastle-1.49.orig/src/org/bouncycastle/asn1/x509/IssuingDistributionPoint.java0000644000175000017500000002044711737275254027773 0ustar ebourgebourgpackage org.bouncycastle.asn1.x509; import org.bouncycastle.asn1.ASN1Boolean; import org.bouncycastle.asn1.ASN1EncodableVector; import org.bouncycastle.asn1.ASN1Object; import org.bouncycastle.asn1.ASN1Primitive; import org.bouncycastle.asn1.ASN1Sequence; import org.bouncycastle.asn1.ASN1TaggedObject; import org.bouncycastle.asn1.DERSequence; import org.bouncycastle.asn1.DERTaggedObject; /** *
     * IssuingDistributionPoint ::= SEQUENCE { 
     *   distributionPoint          [0] DistributionPointName OPTIONAL, 
     *   onlyContainsUserCerts      [1] BOOLEAN DEFAULT FALSE, 
     *   onlyContainsCACerts        [2] BOOLEAN DEFAULT FALSE, 
     *   onlySomeReasons            [3] ReasonFlags OPTIONAL, 
     *   indirectCRL                [4] BOOLEAN DEFAULT FALSE,
     *   onlyContainsAttributeCerts [5] BOOLEAN DEFAULT FALSE }
     * 
    */ public class IssuingDistributionPoint extends ASN1Object { private DistributionPointName distributionPoint; private boolean onlyContainsUserCerts; private boolean onlyContainsCACerts; private ReasonFlags onlySomeReasons; private boolean indirectCRL; private boolean onlyContainsAttributeCerts; private ASN1Sequence seq; public static IssuingDistributionPoint getInstance( ASN1TaggedObject obj, boolean explicit) { return getInstance(ASN1Sequence.getInstance(obj, explicit)); } public static IssuingDistributionPoint getInstance( Object obj) { if (obj instanceof IssuingDistributionPoint) { return (IssuingDistributionPoint)obj; } else if (obj != null) { return new IssuingDistributionPoint(ASN1Sequence.getInstance(obj)); } return null; } /** * Constructor from given details. * * @param distributionPoint * May contain an URI as pointer to most current CRL. * @param onlyContainsUserCerts Covers revocation information for end certificates. * @param onlyContainsCACerts Covers revocation information for CA certificates. * * @param onlySomeReasons * Which revocation reasons does this point cover. * @param indirectCRL * If true then the CRL contains revocation * information about certificates ssued by other CAs. * @param onlyContainsAttributeCerts Covers revocation information for attribute certificates. */ public IssuingDistributionPoint( DistributionPointName distributionPoint, boolean onlyContainsUserCerts, boolean onlyContainsCACerts, ReasonFlags onlySomeReasons, boolean indirectCRL, boolean onlyContainsAttributeCerts) { this.distributionPoint = distributionPoint; this.indirectCRL = indirectCRL; this.onlyContainsAttributeCerts = onlyContainsAttributeCerts; this.onlyContainsCACerts = onlyContainsCACerts; this.onlyContainsUserCerts = onlyContainsUserCerts; this.onlySomeReasons = onlySomeReasons; ASN1EncodableVector vec = new ASN1EncodableVector(); if (distributionPoint != null) { // CHOICE item so explicitly tagged vec.add(new DERTaggedObject(true, 0, distributionPoint)); } if (onlyContainsUserCerts) { vec.add(new DERTaggedObject(false, 1, ASN1Boolean.getInstance(true))); } if (onlyContainsCACerts) { vec.add(new DERTaggedObject(false, 2, ASN1Boolean.getInstance(true))); } if (onlySomeReasons != null) { vec.add(new DERTaggedObject(false, 3, onlySomeReasons)); } if (indirectCRL) { vec.add(new DERTaggedObject(false, 4, ASN1Boolean.getInstance(true))); } if (onlyContainsAttributeCerts) { vec.add(new DERTaggedObject(false, 5, ASN1Boolean.getInstance(true))); } seq = new DERSequence(vec); } /** * Shorthand Constructor from given details. * * @param distributionPoint * May contain an URI as pointer to most current CRL. * @param indirectCRL * If true then the CRL contains revocation * information about certificates ssued by other CAs. * @param onlyContainsAttributeCerts Covers revocation information for attribute certificates. */ public IssuingDistributionPoint( DistributionPointName distributionPoint, boolean indirectCRL, boolean onlyContainsAttributeCerts) { this(distributionPoint, false, false, null, indirectCRL, onlyContainsAttributeCerts); } /** * Constructor from ASN1Sequence */ private IssuingDistributionPoint( ASN1Sequence seq) { this.seq = seq; for (int i = 0; i != seq.size(); i++) { ASN1TaggedObject o = ASN1TaggedObject.getInstance(seq.getObjectAt(i)); switch (o.getTagNo()) { case 0: // CHOICE so explicit distributionPoint = DistributionPointName.getInstance(o, true); break; case 1: onlyContainsUserCerts = ASN1Boolean.getInstance(o, false).isTrue(); break; case 2: onlyContainsCACerts = ASN1Boolean.getInstance(o, false).isTrue(); break; case 3: onlySomeReasons = new ReasonFlags(ReasonFlags.getInstance(o, false)); break; case 4: indirectCRL = ASN1Boolean.getInstance(o, false).isTrue(); break; case 5: onlyContainsAttributeCerts = ASN1Boolean.getInstance(o, false).isTrue(); break; default: throw new IllegalArgumentException( "unknown tag in IssuingDistributionPoint"); } } } public boolean onlyContainsUserCerts() { return onlyContainsUserCerts; } public boolean onlyContainsCACerts() { return onlyContainsCACerts; } public boolean isIndirectCRL() { return indirectCRL; } public boolean onlyContainsAttributeCerts() { return onlyContainsAttributeCerts; } /** * @return Returns the distributionPoint. */ public DistributionPointName getDistributionPoint() { return distributionPoint; } /** * @return Returns the onlySomeReasons. */ public ReasonFlags getOnlySomeReasons() { return onlySomeReasons; } public ASN1Primitive toASN1Primitive() { return seq; } public String toString() { String sep = System.getProperty("line.separator"); StringBuffer buf = new StringBuffer(); buf.append("IssuingDistributionPoint: ["); buf.append(sep); if (distributionPoint != null) { appendObject(buf, sep, "distributionPoint", distributionPoint.toString()); } if (onlyContainsUserCerts) { appendObject(buf, sep, "onlyContainsUserCerts", booleanToString(onlyContainsUserCerts)); } if (onlyContainsCACerts) { appendObject(buf, sep, "onlyContainsCACerts", booleanToString(onlyContainsCACerts)); } if (onlySomeReasons != null) { appendObject(buf, sep, "onlySomeReasons", onlySomeReasons.toString()); } if (onlyContainsAttributeCerts) { appendObject(buf, sep, "onlyContainsAttributeCerts", booleanToString(onlyContainsAttributeCerts)); } if (indirectCRL) { appendObject(buf, sep, "indirectCRL", booleanToString(indirectCRL)); } buf.append("]"); buf.append(sep); return buf.toString(); } private void appendObject(StringBuffer buf, String sep, String name, String value) { String indent = " "; buf.append(indent); buf.append(name); buf.append(":"); buf.append(sep); buf.append(indent); buf.append(indent); buf.append(value); buf.append(sep); } private String booleanToString(boolean value) { return value ? "true" : "false"; } } bouncycastle-1.49.orig/src/org/bouncycastle/asn1/x509/Time.java0000644000175000017500000000635111624625016023622 0ustar ebourgebourgpackage org.bouncycastle.asn1.x509; import java.text.ParseException; import java.text.SimpleDateFormat; import java.util.Date; import java.util.SimpleTimeZone; import org.bouncycastle.asn1.ASN1Choice; import org.bouncycastle.asn1.ASN1Object; import org.bouncycastle.asn1.ASN1Primitive; import org.bouncycastle.asn1.ASN1TaggedObject; import org.bouncycastle.asn1.DERGeneralizedTime; import org.bouncycastle.asn1.DERUTCTime; public class Time extends ASN1Object implements ASN1Choice { ASN1Primitive time; public static Time getInstance( ASN1TaggedObject obj, boolean explicit) { return getInstance(obj.getObject()); // must be explicitly tagged } public Time( ASN1Primitive time) { if (!(time instanceof DERUTCTime) && !(time instanceof DERGeneralizedTime)) { throw new IllegalArgumentException("unknown object passed to Time"); } this.time = time; } /** * creates a time object from a given date - if the date is between 1950 * and 2049 a UTCTime object is generated, otherwise a GeneralizedTime * is used. */ public Time( Date date) { SimpleTimeZone tz = new SimpleTimeZone(0, "Z"); SimpleDateFormat dateF = new SimpleDateFormat("yyyyMMddHHmmss"); dateF.setTimeZone(tz); String d = dateF.format(date) + "Z"; int year = Integer.parseInt(d.substring(0, 4)); if (year < 1950 || year > 2049) { time = new DERGeneralizedTime(d); } else { time = new DERUTCTime(d.substring(2)); } } public static Time getInstance( Object obj) { if (obj == null || obj instanceof Time) { return (Time)obj; } else if (obj instanceof DERUTCTime) { return new Time((DERUTCTime)obj); } else if (obj instanceof DERGeneralizedTime) { return new Time((DERGeneralizedTime)obj); } throw new IllegalArgumentException("unknown object in factory: " + obj.getClass().getName()); } public String getTime() { if (time instanceof DERUTCTime) { return ((DERUTCTime)time).getAdjustedTime(); } else { return ((DERGeneralizedTime)time).getTime(); } } public Date getDate() { try { if (time instanceof DERUTCTime) { return ((DERUTCTime)time).getAdjustedDate(); } else { return ((DERGeneralizedTime)time).getDate(); } } catch (ParseException e) { // this should never happen throw new IllegalStateException("invalid date string: " + e.getMessage()); } } /** * Produce an object suitable for an ASN1OutputStream. *
         * Time ::= CHOICE {
         *             utcTime        UTCTime,
         *             generalTime    GeneralizedTime }
         * 
    */ public ASN1Primitive toASN1Primitive() { return time; } public String toString() { return getTime(); } } bouncycastle-1.49.orig/src/org/bouncycastle/asn1/x509/AlgorithmIdentifier.java0000644000175000017500000001036712151274315026655 0ustar ebourgebourgpackage org.bouncycastle.asn1.x509; import org.bouncycastle.asn1.ASN1Encodable; import org.bouncycastle.asn1.ASN1EncodableVector; import org.bouncycastle.asn1.ASN1Object; import org.bouncycastle.asn1.ASN1ObjectIdentifier; import org.bouncycastle.asn1.ASN1Primitive; import org.bouncycastle.asn1.ASN1Sequence; import org.bouncycastle.asn1.ASN1TaggedObject; import org.bouncycastle.asn1.DERNull; import org.bouncycastle.asn1.DERObjectIdentifier; import org.bouncycastle.asn1.DERSequence; public class AlgorithmIdentifier extends ASN1Object { private ASN1ObjectIdentifier objectId; private ASN1Encodable parameters; private boolean parametersDefined = false; public static AlgorithmIdentifier getInstance( ASN1TaggedObject obj, boolean explicit) { return getInstance(ASN1Sequence.getInstance(obj, explicit)); } public static AlgorithmIdentifier getInstance( Object obj) { if (obj== null || obj instanceof AlgorithmIdentifier) { return (AlgorithmIdentifier)obj; } // TODO: delete if (obj instanceof ASN1ObjectIdentifier) { return new AlgorithmIdentifier((ASN1ObjectIdentifier)obj); } // TODO: delete if (obj instanceof String) { return new AlgorithmIdentifier((String)obj); } return new AlgorithmIdentifier(ASN1Sequence.getInstance(obj)); } public AlgorithmIdentifier( ASN1ObjectIdentifier objectId) { this.objectId = objectId; } /** * @deprecated use ASN1ObjectIdentifier * @param objectId */ public AlgorithmIdentifier( String objectId) { this.objectId = new ASN1ObjectIdentifier(objectId); } /** * @deprecated use ASN1ObjectIdentifier * @param objectId */ public AlgorithmIdentifier( DERObjectIdentifier objectId) { this.objectId = new ASN1ObjectIdentifier(objectId.getId()); } /** * @deprecated use ASN1ObjectIdentifier * @param objectId * @param parameters */ public AlgorithmIdentifier( DERObjectIdentifier objectId, ASN1Encodable parameters) { parametersDefined = true; this.objectId = new ASN1ObjectIdentifier(objectId.getId()); this.parameters = parameters; } public AlgorithmIdentifier( ASN1ObjectIdentifier objectId, ASN1Encodable parameters) { parametersDefined = true; this.objectId = objectId; this.parameters = parameters; } /** * @deprecated use AlgorithmIdentifier.getInstance() * @param seq */ public AlgorithmIdentifier( ASN1Sequence seq) { if (seq.size() < 1 || seq.size() > 2) { throw new IllegalArgumentException("Bad sequence size: " + seq.size()); } objectId = ASN1ObjectIdentifier.getInstance(seq.getObjectAt(0)); if (seq.size() == 2) { parametersDefined = true; parameters = seq.getObjectAt(1); } else { parameters = null; } } public ASN1ObjectIdentifier getAlgorithm() { return new ASN1ObjectIdentifier(objectId.getId()); } /** * @deprecated use getAlgorithm * @return */ public ASN1ObjectIdentifier getObjectId() { return objectId; } public ASN1Encodable getParameters() { return parameters; } /** * Produce an object suitable for an ASN1OutputStream. *
         *      AlgorithmIdentifier ::= SEQUENCE {
         *                            algorithm OBJECT IDENTIFIER,
         *                            parameters ANY DEFINED BY algorithm OPTIONAL }
         * 
    */ public ASN1Primitive toASN1Primitive() { ASN1EncodableVector v = new ASN1EncodableVector(); v.add(objectId); if (parametersDefined) { if (parameters != null) { v.add(parameters); } else { v.add(DERNull.INSTANCE); } } return new DERSequence(v); } } bouncycastle-1.49.orig/src/org/bouncycastle/asn1/x509/CRLNumber.java0000644000175000017500000000175511676771047024535 0ustar ebourgebourgpackage org.bouncycastle.asn1.x509; import java.math.BigInteger; import org.bouncycastle.asn1.ASN1Integer; import org.bouncycastle.asn1.ASN1Object; import org.bouncycastle.asn1.ASN1Primitive; /** * The CRLNumber object. *
     * CRLNumber::= INTEGER(0..MAX)
     * 
    */ public class CRLNumber extends ASN1Object { private BigInteger number; public CRLNumber( BigInteger number) { this.number = number; } public BigInteger getCRLNumber() { return number; } public String toString() { return "CRLNumber: " + getCRLNumber(); } public ASN1Primitive toASN1Primitive() { return new ASN1Integer(number); } public static CRLNumber getInstance(Object o) { if (o instanceof CRLNumber) { return (CRLNumber)o; } else if (o != null) { return new CRLNumber(ASN1Integer.getInstance(o).getValue()); } return null; } } bouncycastle-1.49.orig/src/org/bouncycastle/asn1/x509/TBSCertificate.java0000644000175000017500000001174311724574222025523 0ustar ebourgebourgpackage org.bouncycastle.asn1.x509; import org.bouncycastle.asn1.ASN1Integer; import org.bouncycastle.asn1.ASN1Object; import org.bouncycastle.asn1.ASN1Primitive; import org.bouncycastle.asn1.ASN1Sequence; import org.bouncycastle.asn1.ASN1TaggedObject; import org.bouncycastle.asn1.DERBitString; import org.bouncycastle.asn1.DERTaggedObject; import org.bouncycastle.asn1.x500.X500Name; /** * The TBSCertificate object. *
     * TBSCertificate ::= SEQUENCE {
     *      version          [ 0 ]  Version DEFAULT v1(0),
     *      serialNumber            CertificateSerialNumber,
     *      signature               AlgorithmIdentifier,
     *      issuer                  Name,
     *      validity                Validity,
     *      subject                 Name,
     *      subjectPublicKeyInfo    SubjectPublicKeyInfo,
     *      issuerUniqueID    [ 1 ] IMPLICIT UniqueIdentifier OPTIONAL,
     *      subjectUniqueID   [ 2 ] IMPLICIT UniqueIdentifier OPTIONAL,
     *      extensions        [ 3 ] Extensions OPTIONAL
     *      }
     * 
    *

    * Note: issuerUniqueID and subjectUniqueID are both deprecated by the IETF. This class * will parse them, but you really shouldn't be creating new ones. */ public class TBSCertificate extends ASN1Object { ASN1Sequence seq; ASN1Integer version; ASN1Integer serialNumber; AlgorithmIdentifier signature; X500Name issuer; Time startDate, endDate; X500Name subject; SubjectPublicKeyInfo subjectPublicKeyInfo; DERBitString issuerUniqueId; DERBitString subjectUniqueId; Extensions extensions; public static TBSCertificate getInstance( ASN1TaggedObject obj, boolean explicit) { return getInstance(ASN1Sequence.getInstance(obj, explicit)); } public static TBSCertificate getInstance( Object obj) { if (obj instanceof TBSCertificate) { return (TBSCertificate)obj; } else if (obj != null) { return new TBSCertificate(ASN1Sequence.getInstance(obj)); } return null; } private TBSCertificate( ASN1Sequence seq) { int seqStart = 0; this.seq = seq; // // some certficates don't include a version number - we assume v1 // if (seq.getObjectAt(0) instanceof DERTaggedObject) { version = ASN1Integer.getInstance((ASN1TaggedObject)seq.getObjectAt(0), true); } else { seqStart = -1; // field 0 is missing! version = new ASN1Integer(0); } serialNumber = ASN1Integer.getInstance(seq.getObjectAt(seqStart + 1)); signature = AlgorithmIdentifier.getInstance(seq.getObjectAt(seqStart + 2)); issuer = X500Name.getInstance(seq.getObjectAt(seqStart + 3)); // // before and after dates // ASN1Sequence dates = (ASN1Sequence)seq.getObjectAt(seqStart + 4); startDate = Time.getInstance(dates.getObjectAt(0)); endDate = Time.getInstance(dates.getObjectAt(1)); subject = X500Name.getInstance(seq.getObjectAt(seqStart + 5)); // // public key info. // subjectPublicKeyInfo = SubjectPublicKeyInfo.getInstance(seq.getObjectAt(seqStart + 6)); for (int extras = seq.size() - (seqStart + 6) - 1; extras > 0; extras--) { DERTaggedObject extra = (DERTaggedObject)seq.getObjectAt(seqStart + 6 + extras); switch (extra.getTagNo()) { case 1: issuerUniqueId = DERBitString.getInstance(extra, false); break; case 2: subjectUniqueId = DERBitString.getInstance(extra, false); break; case 3: extensions = Extensions.getInstance(ASN1Sequence.getInstance(extra, true)); } } } public int getVersionNumber() { return version.getValue().intValue() + 1; } public ASN1Integer getVersion() { return version; } public ASN1Integer getSerialNumber() { return serialNumber; } public AlgorithmIdentifier getSignature() { return signature; } public X500Name getIssuer() { return issuer; } public Time getStartDate() { return startDate; } public Time getEndDate() { return endDate; } public X500Name getSubject() { return subject; } public SubjectPublicKeyInfo getSubjectPublicKeyInfo() { return subjectPublicKeyInfo; } public DERBitString getIssuerUniqueId() { return issuerUniqueId; } public DERBitString getSubjectUniqueId() { return subjectUniqueId; } public Extensions getExtensions() { return extensions; } public ASN1Primitive toASN1Primitive() { return seq; } } bouncycastle-1.49.orig/src/org/bouncycastle/asn1/x509/X509ObjectIdentifiers.java0000644000175000017500000000563511726010374026710 0ustar ebourgebourgpackage org.bouncycastle.asn1.x509; import org.bouncycastle.asn1.ASN1ObjectIdentifier; public interface X509ObjectIdentifiers { // // base id // static final String id = "2.5.4"; static final ASN1ObjectIdentifier commonName = new ASN1ObjectIdentifier(id + ".3"); static final ASN1ObjectIdentifier countryName = new ASN1ObjectIdentifier(id + ".6"); static final ASN1ObjectIdentifier localityName = new ASN1ObjectIdentifier(id + ".7"); static final ASN1ObjectIdentifier stateOrProvinceName = new ASN1ObjectIdentifier(id + ".8"); static final ASN1ObjectIdentifier organization = new ASN1ObjectIdentifier(id + ".10"); static final ASN1ObjectIdentifier organizationalUnitName = new ASN1ObjectIdentifier(id + ".11"); static final ASN1ObjectIdentifier id_at_telephoneNumber = new ASN1ObjectIdentifier("2.5.4.20"); static final ASN1ObjectIdentifier id_at_name = new ASN1ObjectIdentifier(id + ".41"); // id-SHA1 OBJECT IDENTIFIER ::= // {iso(1) identified-organization(3) oiw(14) secsig(3) algorithms(2) 26 } // static final ASN1ObjectIdentifier id_SHA1 = new ASN1ObjectIdentifier("1.3.14.3.2.26"); // // ripemd160 OBJECT IDENTIFIER ::= // {iso(1) identified-organization(3) TeleTrust(36) algorithm(3) hashAlgorithm(2) RIPEMD-160(1)} // static final ASN1ObjectIdentifier ripemd160 = new ASN1ObjectIdentifier("1.3.36.3.2.1"); // // ripemd160WithRSAEncryption OBJECT IDENTIFIER ::= // {iso(1) identified-organization(3) TeleTrust(36) algorithm(3) signatureAlgorithm(3) rsaSignature(1) rsaSignatureWithripemd160(2) } // static final ASN1ObjectIdentifier ripemd160WithRSAEncryption = new ASN1ObjectIdentifier("1.3.36.3.3.1.2"); static final ASN1ObjectIdentifier id_ea_rsa = new ASN1ObjectIdentifier("2.5.8.1.1"); // id-pkix static final ASN1ObjectIdentifier id_pkix = new ASN1ObjectIdentifier("1.3.6.1.5.5.7"); // // private internet extensions // static final ASN1ObjectIdentifier id_pe = new ASN1ObjectIdentifier(id_pkix + ".1"); // // ISO ARC for standard certificate and CRL extensions // static final ASN1ObjectIdentifier id_ce = new ASN1ObjectIdentifier("2.5.29"); // // authority information access // static final ASN1ObjectIdentifier id_ad = new ASN1ObjectIdentifier(id_pkix + ".48"); static final ASN1ObjectIdentifier id_ad_caIssuers = new ASN1ObjectIdentifier(id_ad + ".2"); static final ASN1ObjectIdentifier id_ad_ocsp = new ASN1ObjectIdentifier(id_ad + ".1"); // // OID for ocsp and crl uri in AuthorityInformationAccess extension // static final ASN1ObjectIdentifier ocspAccessMethod = id_ad_ocsp; static final ASN1ObjectIdentifier crlAccessMethod = id_ad_caIssuers; } bouncycastle-1.49.orig/src/org/bouncycastle/asn1/x509/Holder.java0000644000175000017500000001505411725243621024141 0ustar ebourgebourgpackage org.bouncycastle.asn1.x509; import org.bouncycastle.asn1.ASN1EncodableVector; import org.bouncycastle.asn1.ASN1Object; import org.bouncycastle.asn1.ASN1Primitive; import org.bouncycastle.asn1.ASN1Sequence; import org.bouncycastle.asn1.ASN1TaggedObject; import org.bouncycastle.asn1.DERSequence; import org.bouncycastle.asn1.DERTaggedObject; /** * The Holder object. *

    * For an v2 attribute certificate this is: * *

     *            Holder ::= SEQUENCE {
     *                  baseCertificateID   [0] IssuerSerial OPTIONAL,
     *                           -- the issuer and serial number of
     *                           -- the holder's Public Key Certificate
     *                  entityName          [1] GeneralNames OPTIONAL,
     *                           -- the name of the claimant or role
     *                  objectDigestInfo    [2] ObjectDigestInfo OPTIONAL
     *                           -- used to directly authenticate the holder,
     *                           -- for example, an executable
     *            }
     * 
    * *

    * For an v1 attribute certificate this is: * *

     *         subject CHOICE {
     *          baseCertificateID [0] IssuerSerial,
     *          -- associated with a Public Key Certificate
     *          subjectName [1] GeneralNames },
     *          -- associated with a name
     * 
    */ public class Holder extends ASN1Object { public static final int V1_CERTIFICATE_HOLDER = 0; public static final int V2_CERTIFICATE_HOLDER = 1; IssuerSerial baseCertificateID; GeneralNames entityName; ObjectDigestInfo objectDigestInfo; private int version = V2_CERTIFICATE_HOLDER; public static Holder getInstance(Object obj) { if (obj instanceof Holder) { return (Holder)obj; } else if (obj instanceof ASN1TaggedObject) { return new Holder(ASN1TaggedObject.getInstance(obj)); } else if (obj != null) { return new Holder(ASN1Sequence.getInstance(obj)); } return null; } /** * Constructor for a holder for an V1 attribute certificate. * * @param tagObj The ASN.1 tagged holder object. */ private Holder(ASN1TaggedObject tagObj) { switch (tagObj.getTagNo()) { case 0: baseCertificateID = IssuerSerial.getInstance(tagObj, false); break; case 1: entityName = GeneralNames.getInstance(tagObj, false); break; default: throw new IllegalArgumentException("unknown tag in Holder"); } version = 0; } /** * Constructor for a holder for an V2 attribute certificate. * * @param seq The ASN.1 sequence. */ private Holder(ASN1Sequence seq) { if (seq.size() > 3) { throw new IllegalArgumentException("Bad sequence size: " + seq.size()); } for (int i = 0; i != seq.size(); i++) { ASN1TaggedObject tObj = ASN1TaggedObject.getInstance(seq .getObjectAt(i)); switch (tObj.getTagNo()) { case 0: baseCertificateID = IssuerSerial.getInstance(tObj, false); break; case 1: entityName = GeneralNames.getInstance(tObj, false); break; case 2: objectDigestInfo = ObjectDigestInfo.getInstance(tObj, false); break; default: throw new IllegalArgumentException("unknown tag in Holder"); } } version = 1; } public Holder(IssuerSerial baseCertificateID) { this(baseCertificateID, V2_CERTIFICATE_HOLDER); } /** * Constructs a holder from a IssuerSerial for a V1 or V2 certificate. * . * @param baseCertificateID The IssuerSerial. * @param version The version of the attribute certificate. */ public Holder(IssuerSerial baseCertificateID, int version) { this.baseCertificateID = baseCertificateID; this.version = version; } /** * Returns 1 for V2 attribute certificates or 0 for V1 attribute * certificates. * @return The version of the attribute certificate. */ public int getVersion() { return version; } /** * Constructs a holder with an entityName for V2 attribute certificates. * * @param entityName The entity or subject name. */ public Holder(GeneralNames entityName) { this(entityName, V2_CERTIFICATE_HOLDER); } /** * Constructs a holder with an entityName for V2 attribute certificates or * with a subjectName for V1 attribute certificates. * * @param entityName The entity or subject name. * @param version The version of the attribute certificate. */ public Holder(GeneralNames entityName, int version) { this.entityName = entityName; this.version = version; } /** * Constructs a holder from an object digest info. * * @param objectDigestInfo The object digest info object. */ public Holder(ObjectDigestInfo objectDigestInfo) { this.objectDigestInfo = objectDigestInfo; } public IssuerSerial getBaseCertificateID() { return baseCertificateID; } /** * Returns the entityName for an V2 attribute certificate or the subjectName * for an V1 attribute certificate. * * @return The entityname or subjectname. */ public GeneralNames getEntityName() { return entityName; } public ObjectDigestInfo getObjectDigestInfo() { return objectDigestInfo; } public ASN1Primitive toASN1Primitive() { if (version == 1) { ASN1EncodableVector v = new ASN1EncodableVector(); if (baseCertificateID != null) { v.add(new DERTaggedObject(false, 0, baseCertificateID)); } if (entityName != null) { v.add(new DERTaggedObject(false, 1, entityName)); } if (objectDigestInfo != null) { v.add(new DERTaggedObject(false, 2, objectDigestInfo)); } return new DERSequence(v); } else { if (entityName != null) { return new DERTaggedObject(false, 1, entityName); } else { return new DERTaggedObject(false, 0, baseCertificateID); } } } } bouncycastle-1.49.orig/src/org/bouncycastle/asn1/x509/Extensions.java0000644000175000017500000001261012151253000025040 0ustar ebourgebourgpackage org.bouncycastle.asn1.x509; import java.util.Enumeration; import java.util.Hashtable; import java.util.Vector; import org.bouncycastle.asn1.ASN1Encodable; import org.bouncycastle.asn1.ASN1EncodableVector; import org.bouncycastle.asn1.ASN1Object; import org.bouncycastle.asn1.ASN1ObjectIdentifier; import org.bouncycastle.asn1.ASN1Primitive; import org.bouncycastle.asn1.ASN1Sequence; import org.bouncycastle.asn1.ASN1TaggedObject; import org.bouncycastle.asn1.DERSequence; public class Extensions extends ASN1Object { private Hashtable extensions = new Hashtable(); private Vector ordering = new Vector(); public static Extensions getInstance( ASN1TaggedObject obj, boolean explicit) { return getInstance(ASN1Sequence.getInstance(obj, explicit)); } public static Extensions getInstance( Object obj) { if (obj instanceof Extensions) { return (Extensions)obj; } else if (obj != null) { return new Extensions(ASN1Sequence.getInstance(obj)); } return null; } /** * Constructor from ASN1Sequence. *

    * the extensions are a list of constructed sequences, either with (OID, OctetString) or (OID, Boolean, OctetString) */ private Extensions( ASN1Sequence seq) { Enumeration e = seq.getObjects(); while (e.hasMoreElements()) { Extension ext = Extension.getInstance(e.nextElement()); extensions.put(ext.getExtnId(), ext); ordering.addElement(ext.getExtnId()); } } /** * Base Constructor * * @param extension a single extension. */ public Extensions( Extension extension) { this.ordering.addElement(extension.getExtnId()); this.extensions.put(extension.getExtnId(), extension); } /** * Base Constructor * * @param extensions an array of extensions. */ public Extensions( Extension[] extensions) { for (int i = 0; i != extensions.length; i++) { Extension ext = extensions[i]; this.ordering.addElement(ext.getExtnId()); this.extensions.put(ext.getExtnId(), ext); } } /** * return an Enumeration of the extension field's object ids. */ public Enumeration oids() { return ordering.elements(); } /** * return the extension represented by the object identifier * passed in. * * @return the extension if it's present, null otherwise. */ public Extension getExtension( ASN1ObjectIdentifier oid) { return (Extension)extensions.get(oid); } /** * return the parsed value of the extension represented by the object identifier * passed in. * * @return the parsed value of the extension if it's present, null otherwise. */ public ASN1Encodable getExtensionParsedValue(ASN1ObjectIdentifier oid) { Extension ext = this.getExtension(oid); if (ext != null) { return ext.getParsedValue(); } return null; } /** *

         *     Extensions        ::=   SEQUENCE SIZE (1..MAX) OF Extension
         *
         *     Extension         ::=   SEQUENCE {
         *        extnId            EXTENSION.&id ({ExtensionSet}),
         *        critical          BOOLEAN DEFAULT FALSE,
         *        extnValue         OCTET STRING }
         * 
    */ public ASN1Primitive toASN1Primitive() { ASN1EncodableVector vec = new ASN1EncodableVector(); Enumeration e = ordering.elements(); while (e.hasMoreElements()) { ASN1ObjectIdentifier oid = (ASN1ObjectIdentifier)e.nextElement(); Extension ext = (Extension)extensions.get(oid); vec.add(ext); } return new DERSequence(vec); } public boolean equivalent( Extensions other) { if (extensions.size() != other.extensions.size()) { return false; } Enumeration e1 = extensions.keys(); while (e1.hasMoreElements()) { Object key = e1.nextElement(); if (!extensions.get(key).equals(other.extensions.get(key))) { return false; } } return true; } public ASN1ObjectIdentifier[] getExtensionOIDs() { return toOidArray(ordering); } public ASN1ObjectIdentifier[] getNonCriticalExtensionOIDs() { return getExtensionOIDs(false); } public ASN1ObjectIdentifier[] getCriticalExtensionOIDs() { return getExtensionOIDs(true); } private ASN1ObjectIdentifier[] getExtensionOIDs(boolean isCritical) { Vector oidVec = new Vector(); for (int i = 0; i != ordering.size(); i++) { Object oid = ordering.elementAt(i); if (((Extension)extensions.get(oid)).isCritical() == isCritical) { oidVec.addElement(oid); } } return toOidArray(oidVec); } private ASN1ObjectIdentifier[] toOidArray(Vector oidVec) { ASN1ObjectIdentifier[] oids = new ASN1ObjectIdentifier[oidVec.size()]; for (int i = 0; i != oids.length; i++) { oids[i] = (ASN1ObjectIdentifier)oidVec.elementAt(i); } return oids; } } bouncycastle-1.49.orig/src/org/bouncycastle/asn1/x509/V3TBSCertificateGenerator.java0000644000175000017500000001226311724574331027602 0ustar ebourgebourgpackage org.bouncycastle.asn1.x509; import org.bouncycastle.asn1.ASN1EncodableVector; import org.bouncycastle.asn1.ASN1Integer; import org.bouncycastle.asn1.DERBitString; import org.bouncycastle.asn1.DERSequence; import org.bouncycastle.asn1.DERTaggedObject; import org.bouncycastle.asn1.DERUTCTime; import org.bouncycastle.asn1.x500.X500Name; /** * Generator for Version 3 TBSCertificateStructures. *
     * TBSCertificate ::= SEQUENCE {
     *      version          [ 0 ]  Version DEFAULT v1(0),
     *      serialNumber            CertificateSerialNumber,
     *      signature               AlgorithmIdentifier,
     *      issuer                  Name,
     *      validity                Validity,
     *      subject                 Name,
     *      subjectPublicKeyInfo    SubjectPublicKeyInfo,
     *      issuerUniqueID    [ 1 ] IMPLICIT UniqueIdentifier OPTIONAL,
     *      subjectUniqueID   [ 2 ] IMPLICIT UniqueIdentifier OPTIONAL,
     *      extensions        [ 3 ] Extensions OPTIONAL
     *      }
     * 
    * */ public class V3TBSCertificateGenerator { DERTaggedObject version = new DERTaggedObject(true, 0, new ASN1Integer(2)); ASN1Integer serialNumber; AlgorithmIdentifier signature; X500Name issuer; Time startDate, endDate; X500Name subject; SubjectPublicKeyInfo subjectPublicKeyInfo; Extensions extensions; private boolean altNamePresentAndCritical; private DERBitString issuerUniqueID; private DERBitString subjectUniqueID; public V3TBSCertificateGenerator() { } public void setSerialNumber( ASN1Integer serialNumber) { this.serialNumber = serialNumber; } public void setSignature( AlgorithmIdentifier signature) { this.signature = signature; } /** * @deprecated use X500Name method */ public void setIssuer( X509Name issuer) { this.issuer = X500Name.getInstance(issuer); } public void setIssuer( X500Name issuer) { this.issuer = issuer; } public void setStartDate( DERUTCTime startDate) { this.startDate = new Time(startDate); } public void setStartDate( Time startDate) { this.startDate = startDate; } public void setEndDate( DERUTCTime endDate) { this.endDate = new Time(endDate); } public void setEndDate( Time endDate) { this.endDate = endDate; } /** * @deprecated use X500Name method */ public void setSubject( X509Name subject) { this.subject = X500Name.getInstance(subject.toASN1Primitive()); } public void setSubject( X500Name subject) { this.subject = subject; } public void setIssuerUniqueID( DERBitString uniqueID) { this.issuerUniqueID = uniqueID; } public void setSubjectUniqueID( DERBitString uniqueID) { this.subjectUniqueID = uniqueID; } public void setSubjectPublicKeyInfo( SubjectPublicKeyInfo pubKeyInfo) { this.subjectPublicKeyInfo = pubKeyInfo; } /** * @deprecated use method taking Extensions * @param extensions */ public void setExtensions( X509Extensions extensions) { setExtensions(Extensions.getInstance(extensions)); } public void setExtensions( Extensions extensions) { this.extensions = extensions; if (extensions != null) { Extension altName = extensions.getExtension(Extension.subjectAlternativeName); if (altName != null && altName.isCritical()) { altNamePresentAndCritical = true; } } } public TBSCertificate generateTBSCertificate() { if ((serialNumber == null) || (signature == null) || (issuer == null) || (startDate == null) || (endDate == null) || (subject == null && !altNamePresentAndCritical) || (subjectPublicKeyInfo == null)) { throw new IllegalStateException("not all mandatory fields set in V3 TBScertificate generator"); } ASN1EncodableVector v = new ASN1EncodableVector(); v.add(version); v.add(serialNumber); v.add(signature); v.add(issuer); // // before and after dates // ASN1EncodableVector validity = new ASN1EncodableVector(); validity.add(startDate); validity.add(endDate); v.add(new DERSequence(validity)); if (subject != null) { v.add(subject); } else { v.add(new DERSequence()); } v.add(subjectPublicKeyInfo); if (issuerUniqueID != null) { v.add(new DERTaggedObject(false, 1, issuerUniqueID)); } if (subjectUniqueID != null) { v.add(new DERTaggedObject(false, 2, subjectUniqueID)); } if (extensions != null) { v.add(new DERTaggedObject(true, 3, extensions)); } return TBSCertificate.getInstance(new DERSequence(v)); } } bouncycastle-1.49.orig/src/org/bouncycastle/asn1/x509/V1TBSCertificateGenerator.java0000644000175000017500000000677711736761350027617 0ustar ebourgebourgpackage org.bouncycastle.asn1.x509; import org.bouncycastle.asn1.ASN1EncodableVector; import org.bouncycastle.asn1.ASN1Integer; import org.bouncycastle.asn1.ASN1UTCTime; import org.bouncycastle.asn1.DERSequence; import org.bouncycastle.asn1.DERTaggedObject; import org.bouncycastle.asn1.x500.X500Name; /** * Generator for Version 1 TBSCertificateStructures. *
     * TBSCertificate ::= SEQUENCE {
     *      version          [ 0 ]  Version DEFAULT v1(0),
     *      serialNumber            CertificateSerialNumber,
     *      signature               AlgorithmIdentifier,
     *      issuer                  Name,
     *      validity                Validity,
     *      subject                 Name,
     *      subjectPublicKeyInfo    SubjectPublicKeyInfo,
     *      }
     * 
    * */ public class V1TBSCertificateGenerator { DERTaggedObject version = new DERTaggedObject(true, 0, new ASN1Integer(0)); ASN1Integer serialNumber; AlgorithmIdentifier signature; X500Name issuer; Time startDate, endDate; X500Name subject; SubjectPublicKeyInfo subjectPublicKeyInfo; public V1TBSCertificateGenerator() { } public void setSerialNumber( ASN1Integer serialNumber) { this.serialNumber = serialNumber; } public void setSignature( AlgorithmIdentifier signature) { this.signature = signature; } /** * @deprecated use X500Name method */ public void setIssuer( X509Name issuer) { this.issuer = X500Name.getInstance(issuer.toASN1Primitive()); } public void setIssuer( X500Name issuer) { this.issuer = issuer; } public void setStartDate( Time startDate) { this.startDate = startDate; } public void setStartDate( ASN1UTCTime startDate) { this.startDate = new Time(startDate); } public void setEndDate( Time endDate) { this.endDate = endDate; } public void setEndDate( ASN1UTCTime endDate) { this.endDate = new Time(endDate); } /** * @deprecated use X500Name method */ public void setSubject( X509Name subject) { this.subject = X500Name.getInstance(subject.toASN1Primitive()); } public void setSubject( X500Name subject) { this.subject = subject; } public void setSubjectPublicKeyInfo( SubjectPublicKeyInfo pubKeyInfo) { this.subjectPublicKeyInfo = pubKeyInfo; } public TBSCertificate generateTBSCertificate() { if ((serialNumber == null) || (signature == null) || (issuer == null) || (startDate == null) || (endDate == null) || (subject == null) || (subjectPublicKeyInfo == null)) { throw new IllegalStateException("not all mandatory fields set in V1 TBScertificate generator"); } ASN1EncodableVector seq = new ASN1EncodableVector(); // seq.add(version); - not required as default value. seq.add(serialNumber); seq.add(signature); seq.add(issuer); // // before and after dates // ASN1EncodableVector validity = new ASN1EncodableVector(); validity.add(startDate); validity.add(endDate); seq.add(new DERSequence(validity)); seq.add(subject); seq.add(subjectPublicKeyInfo); return TBSCertificate.getInstance(new DERSequence(seq)); } } bouncycastle-1.49.orig/src/org/bouncycastle/asn1/x509/SubjectKeyIdentifier.java0000644000175000017500000000755112070233326026775 0ustar ebourgebourgpackage org.bouncycastle.asn1.x509; import org.bouncycastle.asn1.ASN1Object; import org.bouncycastle.asn1.ASN1OctetString; import org.bouncycastle.asn1.ASN1Primitive; import org.bouncycastle.asn1.ASN1TaggedObject; import org.bouncycastle.asn1.DEROctetString; import org.bouncycastle.crypto.Digest; import org.bouncycastle.crypto.digests.SHA1Digest; /** * The SubjectKeyIdentifier object. *
     * SubjectKeyIdentifier::= OCTET STRING
     * 
    */ public class SubjectKeyIdentifier extends ASN1Object { private byte[] keyidentifier; public static SubjectKeyIdentifier getInstance( ASN1TaggedObject obj, boolean explicit) { return getInstance(ASN1OctetString.getInstance(obj, explicit)); } public static SubjectKeyIdentifier getInstance( Object obj) { if (obj instanceof SubjectKeyIdentifier) { return (SubjectKeyIdentifier)obj; } else if (obj != null) { return new SubjectKeyIdentifier(ASN1OctetString.getInstance(obj)); } return null; } public static SubjectKeyIdentifier fromExtensions(Extensions extensions) { return SubjectKeyIdentifier.getInstance(extensions.getExtensionParsedValue(Extension.subjectKeyIdentifier)); } public SubjectKeyIdentifier( byte[] keyid) { this.keyidentifier = keyid; } protected SubjectKeyIdentifier( ASN1OctetString keyid) { this.keyidentifier = keyid.getOctets(); } public byte[] getKeyIdentifier() { return keyidentifier; } public ASN1Primitive toASN1Primitive() { return new DEROctetString(keyidentifier); } /** * Calculates the keyidentifier using a SHA1 hash over the BIT STRING * from SubjectPublicKeyInfo as defined in RFC3280. * * @param spki the subject public key info. * @deprecated */ public SubjectKeyIdentifier( SubjectPublicKeyInfo spki) { this.keyidentifier = getDigest(spki); } /** * Return a RFC 3280 type 1 key identifier. As in: *
         * (1) The keyIdentifier is composed of the 160-bit SHA-1 hash of the
         * value of the BIT STRING subjectPublicKey (excluding the tag,
         * length, and number of unused bits).
         * 
    * @param keyInfo the key info object containing the subjectPublicKey field. * @return the key identifier. * @deprecated use org.bouncycastle.cert.X509ExtensionUtils.createSubjectKeyIdentifier */ public static SubjectKeyIdentifier createSHA1KeyIdentifier(SubjectPublicKeyInfo keyInfo) { return new SubjectKeyIdentifier(keyInfo); } /** * Return a RFC 3280 type 2 key identifier. As in: *
         * (2) The keyIdentifier is composed of a four bit type field with
         * the value 0100 followed by the least significant 60 bits of the
         * SHA-1 hash of the value of the BIT STRING subjectPublicKey.
         * 
    * @param keyInfo the key info object containing the subjectPublicKey field. * @return the key identifier. * @deprecated use org.bouncycastle.cert.X509ExtensionUtils.createTruncatedSubjectKeyIdentifier */ public static SubjectKeyIdentifier createTruncatedSHA1KeyIdentifier(SubjectPublicKeyInfo keyInfo) { byte[] dig = getDigest(keyInfo); byte[] id = new byte[8]; System.arraycopy(dig, dig.length - 8, id, 0, id.length); id[0] &= 0x0f; id[0] |= 0x40; return new SubjectKeyIdentifier(id); } private static byte[] getDigest(SubjectPublicKeyInfo spki) { Digest digest = new SHA1Digest(); byte[] resBuf = new byte[digest.getDigestSize()]; byte[] bytes = spki.getPublicKeyData().getBytes(); digest.update(bytes, 0, bytes.length); digest.doFinal(resBuf, 0); return resBuf; } } bouncycastle-1.49.orig/src/org/bouncycastle/asn1/x509/ExtensionsGenerator.java0000644000175000017500000000512511724273464026737 0ustar ebourgebourgpackage org.bouncycastle.asn1.x509; import java.io.IOException; import java.util.Hashtable; import java.util.Vector; import org.bouncycastle.asn1.ASN1Encodable; import org.bouncycastle.asn1.ASN1Encoding; import org.bouncycastle.asn1.ASN1ObjectIdentifier; import org.bouncycastle.asn1.DEROctetString; /** * Generator for X.509 extensions */ public class ExtensionsGenerator { private Hashtable extensions = new Hashtable(); private Vector extOrdering = new Vector(); /** * Reset the generator */ public void reset() { extensions = new Hashtable(); extOrdering = new Vector(); } /** * Add an extension with the given oid and the passed in value to be included * in the OCTET STRING associated with the extension. * * @param oid OID for the extension. * @param critical true if critical, false otherwise. * @param value the ASN.1 object to be included in the extension. */ public void addExtension( ASN1ObjectIdentifier oid, boolean critical, ASN1Encodable value) throws IOException { this.addExtension(oid, critical, value.toASN1Primitive().getEncoded(ASN1Encoding.DER)); } /** * Add an extension with the given oid and the passed in byte array to be wrapped in the * OCTET STRING associated with the extension. * * @param oid OID for the extension. * @param critical true if critical, false otherwise. * @param value the byte array to be wrapped. */ public void addExtension( ASN1ObjectIdentifier oid, boolean critical, byte[] value) { if (extensions.containsKey(oid)) { throw new IllegalArgumentException("extension " + oid + " already added"); } extOrdering.addElement(oid); extensions.put(oid, new Extension(oid, critical, new DEROctetString(value))); } /** * Return true if there are no extension present in this generator. * * @return true if empty, false otherwise */ public boolean isEmpty() { return extOrdering.isEmpty(); } /** * Generate an Extensions object based on the current state of the generator. * * @return an X09Extensions object. */ public Extensions generate() { Extension[] exts = new Extension[extOrdering.size()]; for (int i = 0; i != extOrdering.size(); i++) { exts[i] = (Extension)extensions.get(extOrdering.elementAt(i)); } return new Extensions(exts); } } bouncycastle-1.49.orig/src/org/bouncycastle/asn1/x509/SubjectDirectoryAttributes.java0000644000175000017500000000715011725244447030264 0ustar ebourgebourgpackage org.bouncycastle.asn1.x509; import java.util.Enumeration; import java.util.Vector; import org.bouncycastle.asn1.ASN1EncodableVector; import org.bouncycastle.asn1.ASN1Object; import org.bouncycastle.asn1.ASN1Primitive; import org.bouncycastle.asn1.ASN1Sequence; import org.bouncycastle.asn1.DERSequence; /** * This extension may contain further X.500 attributes of the subject. See also * RFC 3039. * *
     *     SubjectDirectoryAttributes ::= Attributes
     *     Attributes ::= SEQUENCE SIZE (1..MAX) OF Attribute
     *     Attribute ::= SEQUENCE 
     *     {
     *       type AttributeType 
     *       values SET OF AttributeValue 
     *     }
     *     
     *     AttributeType ::= OBJECT IDENTIFIER
     *     AttributeValue ::= ANY DEFINED BY AttributeType
     * 
    * * @see org.bouncycastle.asn1.x500.style.BCStyle for AttributeType ObjectIdentifiers. */ public class SubjectDirectoryAttributes extends ASN1Object { private Vector attributes = new Vector(); public static SubjectDirectoryAttributes getInstance( Object obj) { if (obj instanceof SubjectDirectoryAttributes) { return (SubjectDirectoryAttributes)obj; } if (obj != null) { return new SubjectDirectoryAttributes(ASN1Sequence.getInstance(obj)); } return null; } /** * Constructor from ASN1Sequence. * * The sequence is of type SubjectDirectoryAttributes: * *
         *      SubjectDirectoryAttributes ::= Attributes
         *      Attributes ::= SEQUENCE SIZE (1..MAX) OF Attribute
         *      Attribute ::= SEQUENCE 
         *      {
         *        type AttributeType 
         *        values SET OF AttributeValue 
         *      }
         *      
         *      AttributeType ::= OBJECT IDENTIFIER
         *      AttributeValue ::= ANY DEFINED BY AttributeType
         * 
    * * @param seq * The ASN.1 sequence. */ private SubjectDirectoryAttributes(ASN1Sequence seq) { Enumeration e = seq.getObjects(); while (e.hasMoreElements()) { ASN1Sequence s = ASN1Sequence.getInstance(e.nextElement()); attributes.addElement(Attribute.getInstance(s)); } } /** * Constructor from a vector of attributes. * * The vector consists of attributes of type {@link Attribute Attribute} * * @param attributes * The attributes. * */ public SubjectDirectoryAttributes(Vector attributes) { Enumeration e = attributes.elements(); while (e.hasMoreElements()) { this.attributes.addElement(e.nextElement()); } } /** * Produce an object suitable for an ASN1OutputStream. * * Returns: * *
         *      SubjectDirectoryAttributes ::= Attributes
         *      Attributes ::= SEQUENCE SIZE (1..MAX) OF Attribute
         *      Attribute ::= SEQUENCE 
         *      {
         *        type AttributeType 
         *        values SET OF AttributeValue 
         *      }
         *      
         *      AttributeType ::= OBJECT IDENTIFIER
         *      AttributeValue ::= ANY DEFINED BY AttributeType
         * 
    * * @return a ASN1Primitive */ public ASN1Primitive toASN1Primitive() { ASN1EncodableVector vec = new ASN1EncodableVector(); Enumeration e = attributes.elements(); while (e.hasMoreElements()) { vec.add((Attribute)e.nextElement()); } return new DERSequence(vec); } /** * @return Returns the attributes. */ public Vector getAttributes() { return attributes; } } bouncycastle-1.49.orig/src/org/bouncycastle/asn1/x509/package.html0000644000175000017500000000016710262753175024346 0ustar ebourgebourg Support classes useful for encoding and processing X.509 certificates. bouncycastle-1.49.orig/src/org/bouncycastle/asn1/x509/KeyUsage.java0000644000175000017500000000537512070233305024436 0ustar ebourgebourgpackage org.bouncycastle.asn1.x509; import org.bouncycastle.asn1.ASN1Object; import org.bouncycastle.asn1.ASN1Primitive; import org.bouncycastle.asn1.DERBitString; /** * The KeyUsage object. *
     *    id-ce-keyUsage OBJECT IDENTIFIER ::=  { id-ce 15 }
     *
     *    KeyUsage ::= BIT STRING {
     *         digitalSignature        (0),
     *         nonRepudiation          (1),
     *         keyEncipherment         (2),
     *         dataEncipherment        (3),
     *         keyAgreement            (4),
     *         keyCertSign             (5),
     *         cRLSign                 (6),
     *         encipherOnly            (7),
     *         decipherOnly            (8) }
     * 
    */ public class KeyUsage extends ASN1Object { public static final int digitalSignature = (1 << 7); public static final int nonRepudiation = (1 << 6); public static final int keyEncipherment = (1 << 5); public static final int dataEncipherment = (1 << 4); public static final int keyAgreement = (1 << 3); public static final int keyCertSign = (1 << 2); public static final int cRLSign = (1 << 1); public static final int encipherOnly = (1 << 0); public static final int decipherOnly = (1 << 15); private DERBitString bitString; public static KeyUsage getInstance(Object obj) // needs to be DERBitString for other VMs { if (obj instanceof KeyUsage) { return (KeyUsage)obj; } else if (obj != null) { return new KeyUsage(DERBitString.getInstance(obj)); } return null; } public static KeyUsage fromExtensions(Extensions extensions) { return KeyUsage.getInstance(extensions.getExtensionParsedValue(Extension.keyUsage)); } /** * Basic constructor. * * @param usage - the bitwise OR of the Key Usage flags giving the * allowed uses for the key. * e.g. (KeyUsage.keyEncipherment | KeyUsage.dataEncipherment) */ public KeyUsage( int usage) { this.bitString = new DERBitString(usage); } private KeyUsage( DERBitString bitString) { this.bitString = bitString; } public byte[] getBytes() { return bitString.getBytes(); } public int getPadBits() { return bitString.getPadBits(); } public String toString() { byte[] data = bitString.getBytes(); if (data.length == 1) { return "KeyUsage: 0x" + Integer.toHexString(data[0] & 0xff); } return "KeyUsage: 0x" + Integer.toHexString((data[1] & 0xff) << 8 | (data[0] & 0xff)); } public ASN1Primitive toASN1Primitive() { return bitString; } } bouncycastle-1.49.orig/src/org/bouncycastle/asn1/BERSet.java0000644000175000017500000000252111703177363023303 0ustar ebourgebourgpackage org.bouncycastle.asn1; import java.io.IOException; import java.util.Enumeration; public class BERSet extends ASN1Set { /** * create an empty sequence */ public BERSet() { } /** * @param obj - a single object that makes up the set. */ public BERSet( ASN1Encodable obj) { super(obj); } /** * @param v - a vector of objects making up the set. */ public BERSet( ASN1EncodableVector v) { super(v, false); } /** * create a set from an array of objects. */ public BERSet( ASN1Encodable[] a) { super(a, false); } int encodedLength() throws IOException { int length = 0; for (Enumeration e = getObjects(); e.hasMoreElements();) { length += ((ASN1Encodable)e.nextElement()).toASN1Primitive().encodedLength(); } return 2 + length + 2; } /* */ void encode( ASN1OutputStream out) throws IOException { out.write(BERTags.SET | BERTags.CONSTRUCTED); out.write(0x80); Enumeration e = getObjects(); while (e.hasMoreElements()) { out.writeObject((ASN1Encodable)e.nextElement()); } out.write(0x00); out.write(0x00); } } bouncycastle-1.49.orig/src/org/bouncycastle/asn1/ASN1Encodable.java0000644000175000017500000000015011624616551024511 0ustar ebourgebourgpackage org.bouncycastle.asn1; public interface ASN1Encodable { ASN1Primitive toASN1Primitive(); } bouncycastle-1.49.orig/src/org/bouncycastle/asn1/ntt/0000755000175000017500000000000012152033551022146 5ustar ebourgebourgbouncycastle-1.49.orig/src/org/bouncycastle/asn1/ntt/NTTObjectIdentifiers.java0000644000175000017500000000156511624622714027012 0ustar ebourgebourgpackage org.bouncycastle.asn1.ntt; import org.bouncycastle.asn1.ASN1ObjectIdentifier; /** * From RFC 3657 */ public interface NTTObjectIdentifiers { public static final ASN1ObjectIdentifier id_camellia128_cbc = new ASN1ObjectIdentifier("1.2.392.200011.61.1.1.1.2"); public static final ASN1ObjectIdentifier id_camellia192_cbc = new ASN1ObjectIdentifier("1.2.392.200011.61.1.1.1.3"); public static final ASN1ObjectIdentifier id_camellia256_cbc = new ASN1ObjectIdentifier("1.2.392.200011.61.1.1.1.4"); public static final ASN1ObjectIdentifier id_camellia128_wrap = new ASN1ObjectIdentifier("1.2.392.200011.61.1.1.3.2"); public static final ASN1ObjectIdentifier id_camellia192_wrap = new ASN1ObjectIdentifier("1.2.392.200011.61.1.1.3.3"); public static final ASN1ObjectIdentifier id_camellia256_wrap = new ASN1ObjectIdentifier("1.2.392.200011.61.1.1.3.4"); } bouncycastle-1.49.orig/src/org/bouncycastle/asn1/ASN1StreamParser.java0000644000175000017500000001654511703721535025261 0ustar ebourgebourgpackage org.bouncycastle.asn1; import java.io.ByteArrayInputStream; import java.io.IOException; import java.io.InputStream; public class ASN1StreamParser { private final InputStream _in; private final int _limit; private final byte[][] tmpBuffers; public ASN1StreamParser( InputStream in) { this(in, StreamUtil.findLimit(in)); } public ASN1StreamParser( InputStream in, int limit) { this._in = in; this._limit = limit; this.tmpBuffers = new byte[11][]; } public ASN1StreamParser( byte[] encoding) { this(new ByteArrayInputStream(encoding), encoding.length); } ASN1Encodable readIndef(int tagValue) throws IOException { // Note: INDEF => CONSTRUCTED // TODO There are other tags that may be constructed (e.g. BIT_STRING) switch (tagValue) { case BERTags.EXTERNAL: return new DERExternalParser(this); case BERTags.OCTET_STRING: return new BEROctetStringParser(this); case BERTags.SEQUENCE: return new BERSequenceParser(this); case BERTags.SET: return new BERSetParser(this); default: throw new ASN1Exception("unknown BER object encountered: 0x" + Integer.toHexString(tagValue)); } } ASN1Encodable readImplicit(boolean constructed, int tag) throws IOException { if (_in instanceof IndefiniteLengthInputStream) { if (!constructed) { throw new IOException("indefinite length primitive encoding encountered"); } return readIndef(tag); } if (constructed) { switch (tag) { case BERTags.SET: return new DERSetParser(this); case BERTags.SEQUENCE: return new DERSequenceParser(this); case BERTags.OCTET_STRING: return new BEROctetStringParser(this); } } else { switch (tag) { case BERTags.SET: throw new ASN1Exception("sequences must use constructed encoding (see X.690 8.9.1/8.10.1)"); case BERTags.SEQUENCE: throw new ASN1Exception("sets must use constructed encoding (see X.690 8.11.1/8.12.1)"); case BERTags.OCTET_STRING: return new DEROctetStringParser((DefiniteLengthInputStream)_in); } } // TODO ASN1Exception throw new RuntimeException("implicit tagging not implemented"); } ASN1Primitive readTaggedObject(boolean constructed, int tag) throws IOException { if (!constructed) { // Note: !CONSTRUCTED => IMPLICIT DefiniteLengthInputStream defIn = (DefiniteLengthInputStream)_in; return new DERTaggedObject(false, tag, new DEROctetString(defIn.toByteArray())); } ASN1EncodableVector v = readVector(); if (_in instanceof IndefiniteLengthInputStream) { return v.size() == 1 ? new BERTaggedObject(true, tag, v.get(0)) : new BERTaggedObject(false, tag, BERFactory.createSequence(v)); } return v.size() == 1 ? new DERTaggedObject(true, tag, v.get(0)) : new DERTaggedObject(false, tag, DERFactory.createSequence(v)); } public ASN1Encodable readObject() throws IOException { int tag = _in.read(); if (tag == -1) { return null; } // // turn of looking for "00" while we resolve the tag // set00Check(false); // // calculate tag number // int tagNo = ASN1InputStream.readTagNumber(_in, tag); boolean isConstructed = (tag & BERTags.CONSTRUCTED) != 0; // // calculate length // int length = ASN1InputStream.readLength(_in, _limit); if (length < 0) // indefinite length method { if (!isConstructed) { throw new IOException("indefinite length primitive encoding encountered"); } IndefiniteLengthInputStream indIn = new IndefiniteLengthInputStream(_in, _limit); ASN1StreamParser sp = new ASN1StreamParser(indIn, _limit); if ((tag & BERTags.APPLICATION) != 0) { return new BERApplicationSpecificParser(tagNo, sp); } if ((tag & BERTags.TAGGED) != 0) { return new BERTaggedObjectParser(true, tagNo, sp); } return sp.readIndef(tagNo); } else { DefiniteLengthInputStream defIn = new DefiniteLengthInputStream(_in, length); if ((tag & BERTags.APPLICATION) != 0) { return new DERApplicationSpecific(isConstructed, tagNo, defIn.toByteArray()); } if ((tag & BERTags.TAGGED) != 0) { return new BERTaggedObjectParser(isConstructed, tagNo, new ASN1StreamParser(defIn)); } if (isConstructed) { // TODO There are other tags that may be constructed (e.g. BIT_STRING) switch (tagNo) { case BERTags.OCTET_STRING: // // yes, people actually do this... // return new BEROctetStringParser(new ASN1StreamParser(defIn)); case BERTags.SEQUENCE: return new DERSequenceParser(new ASN1StreamParser(defIn)); case BERTags.SET: return new DERSetParser(new ASN1StreamParser(defIn)); case BERTags.EXTERNAL: return new DERExternalParser(new ASN1StreamParser(defIn)); default: throw new IOException("unknown tag " + tagNo + " encountered"); } } // Some primitive encodings can be handled by parsers too... switch (tagNo) { case BERTags.OCTET_STRING: return new DEROctetStringParser(defIn); } try { return ASN1InputStream.createPrimitiveDERObject(tagNo, defIn, tmpBuffers); } catch (IllegalArgumentException e) { throw new ASN1Exception("corrupted stream detected", e); } } } private void set00Check(boolean enabled) { if (_in instanceof IndefiniteLengthInputStream) { ((IndefiniteLengthInputStream)_in).setEofOn00(enabled); } } ASN1EncodableVector readVector() throws IOException { ASN1EncodableVector v = new ASN1EncodableVector(); ASN1Encodable obj; while ((obj = readObject()) != null) { if (obj instanceof InMemoryRepresentable) { v.add(((InMemoryRepresentable)obj).getLoadedObject()); } else { v.add(obj.toASN1Primitive()); } } return v; } } bouncycastle-1.49.orig/src/org/bouncycastle/asn1/DLSequence.java0000644000175000017500000000420111703177363024204 0ustar ebourgebourgpackage org.bouncycastle.asn1; import java.io.IOException; import java.util.Enumeration; public class DLSequence extends ASN1Sequence { private int bodyLength = -1; /** * create an empty sequence */ public DLSequence() { } /** * create a sequence containing one object */ public DLSequence( ASN1Encodable obj) { super(obj); } /** * create a sequence containing a vector of objects. */ public DLSequence( ASN1EncodableVector v) { super(v); } /** * create a sequence containing an array of objects. */ public DLSequence( ASN1Encodable[] array) { super(array); } private int getBodyLength() throws IOException { if (bodyLength < 0) { int length = 0; for (Enumeration e = this.getObjects(); e.hasMoreElements();) { Object obj = e.nextElement(); length += ((ASN1Encodable)obj).toASN1Primitive().toDLObject().encodedLength(); } bodyLength = length; } return bodyLength; } int encodedLength() throws IOException { int length = getBodyLength(); return 1 + StreamUtil.calculateBodyLength(length) + length; } /* * A note on the implementation: *

    * As DL requires the constructed, definite-length model to * be used for structured types, this varies slightly from the * ASN.1 descriptions given. Rather than just outputting SEQUENCE, * we also have to specify CONSTRUCTED, and the objects length. */ void encode( ASN1OutputStream out) throws IOException { ASN1OutputStream dOut = out.getDLSubStream(); int length = getBodyLength(); out.write(BERTags.SEQUENCE | BERTags.CONSTRUCTED); out.writeLength(length); for (Enumeration e = this.getObjects(); e.hasMoreElements();) { Object obj = e.nextElement(); dOut.writeObject((ASN1Encodable)obj); } } } bouncycastle-1.49.orig/src/org/bouncycastle/asn1/DERExternal.java0000644000175000017500000002122511703176120024324 0ustar ebourgebourgpackage org.bouncycastle.asn1; import java.io.ByteArrayOutputStream; import java.io.IOException; /** * Class representing the DER-type External */ public class DERExternal extends ASN1Primitive { private ASN1ObjectIdentifier directReference; private ASN1Integer indirectReference; private ASN1Primitive dataValueDescriptor; private int encoding; private ASN1Primitive externalContent; public DERExternal(ASN1EncodableVector vector) { int offset = 0; ASN1Primitive enc = getObjFromVector(vector, offset); if (enc instanceof ASN1ObjectIdentifier) { directReference = (ASN1ObjectIdentifier)enc; offset++; enc = getObjFromVector(vector, offset); } if (enc instanceof ASN1Integer) { indirectReference = (ASN1Integer) enc; offset++; enc = getObjFromVector(vector, offset); } if (!(enc instanceof DERTaggedObject)) { dataValueDescriptor = (ASN1Primitive) enc; offset++; enc = getObjFromVector(vector, offset); } if (vector.size() != offset + 1) { throw new IllegalArgumentException("input vector too large"); } if (!(enc instanceof DERTaggedObject)) { throw new IllegalArgumentException("No tagged object found in vector. Structure doesn't seem to be of type External"); } DERTaggedObject obj = (DERTaggedObject)enc; setEncoding(obj.getTagNo()); externalContent = obj.getObject(); } private ASN1Primitive getObjFromVector(ASN1EncodableVector v, int index) { if (v.size() <= index) { throw new IllegalArgumentException("too few objects in input vector"); } return v.get(index).toASN1Primitive(); } /** * Creates a new instance of DERExternal * See X.690 for more informations about the meaning of these parameters * @param directReference The direct reference or null if not set. * @param indirectReference The indirect reference or null if not set. * @param dataValueDescriptor The data value descriptor or null if not set. * @param externalData The external data in its encoded form. */ public DERExternal(ASN1ObjectIdentifier directReference, ASN1Integer indirectReference, ASN1Primitive dataValueDescriptor, DERTaggedObject externalData) { this(directReference, indirectReference, dataValueDescriptor, externalData.getTagNo(), externalData.toASN1Primitive()); } /** * Creates a new instance of DERExternal. * See X.690 for more informations about the meaning of these parameters * @param directReference The direct reference or null if not set. * @param indirectReference The indirect reference or null if not set. * @param dataValueDescriptor The data value descriptor or null if not set. * @param encoding The encoding to be used for the external data * @param externalData The external data */ public DERExternal(ASN1ObjectIdentifier directReference, ASN1Integer indirectReference, ASN1Primitive dataValueDescriptor, int encoding, ASN1Primitive externalData) { setDirectReference(directReference); setIndirectReference(indirectReference); setDataValueDescriptor(dataValueDescriptor); setEncoding(encoding); setExternalContent(externalData.toASN1Primitive()); } /* (non-Javadoc) * @see java.lang.Object#hashCode() */ public int hashCode() { int ret = 0; if (directReference != null) { ret = directReference.hashCode(); } if (indirectReference != null) { ret ^= indirectReference.hashCode(); } if (dataValueDescriptor != null) { ret ^= dataValueDescriptor.hashCode(); } ret ^= externalContent.hashCode(); return ret; } boolean isConstructed() { return true; } int encodedLength() throws IOException { return this.getEncoded().length; } /* (non-Javadoc) * @see org.bouncycastle.asn1.ASN1Primitive#encode(org.bouncycastle.asn1.DEROutputStream) */ void encode(ASN1OutputStream out) throws IOException { ByteArrayOutputStream baos = new ByteArrayOutputStream(); if (directReference != null) { baos.write(directReference.getEncoded(ASN1Encoding.DER)); } if (indirectReference != null) { baos.write(indirectReference.getEncoded(ASN1Encoding.DER)); } if (dataValueDescriptor != null) { baos.write(dataValueDescriptor.getEncoded(ASN1Encoding.DER)); } DERTaggedObject obj = new DERTaggedObject(true, encoding, externalContent); baos.write(obj.getEncoded(ASN1Encoding.DER)); out.writeEncoded(BERTags.CONSTRUCTED, BERTags.EXTERNAL, baos.toByteArray()); } /* (non-Javadoc) * @see org.bouncycastle.asn1.ASN1Primitive#asn1Equals(org.bouncycastle.asn1.ASN1Primitive) */ boolean asn1Equals(ASN1Primitive o) { if (!(o instanceof DERExternal)) { return false; } if (this == o) { return true; } DERExternal other = (DERExternal)o; if (directReference != null) { if (other.directReference == null || !other.directReference.equals(directReference)) { return false; } } if (indirectReference != null) { if (other.indirectReference == null || !other.indirectReference.equals(indirectReference)) { return false; } } if (dataValueDescriptor != null) { if (other.dataValueDescriptor == null || !other.dataValueDescriptor.equals(dataValueDescriptor)) { return false; } } return externalContent.equals(other.externalContent); } /** * Returns the data value descriptor * @return The descriptor */ public ASN1Primitive getDataValueDescriptor() { return dataValueDescriptor; } /** * Returns the direct reference of the external element * @return The reference */ public ASN1ObjectIdentifier getDirectReference() { return directReference; } /** * Returns the encoding of the content. Valid values are *

      *
    • 0 single-ASN1-type
    • *
    • 1 OCTET STRING
    • *
    • 2 BIT STRING
    • *
    * @return The encoding */ public int getEncoding() { return encoding; } /** * Returns the content of this element * @return The content */ public ASN1Primitive getExternalContent() { return externalContent; } /** * Returns the indirect reference of this element * @return The reference */ public ASN1Integer getIndirectReference() { return indirectReference; } /** * Sets the data value descriptor * @param dataValueDescriptor The descriptor */ private void setDataValueDescriptor(ASN1Primitive dataValueDescriptor) { this.dataValueDescriptor = dataValueDescriptor; } /** * Sets the direct reference of the external element * @param directReferemce The reference */ private void setDirectReference(ASN1ObjectIdentifier directReferemce) { this.directReference = directReferemce; } /** * Sets the encoding of the content. Valid values are *
      *
    • 0 single-ASN1-type
    • *
    • 1 OCTET STRING
    • *
    • 2 BIT STRING
    • *
    * @param encoding The encoding */ private void setEncoding(int encoding) { if (encoding < 0 || encoding > 2) { throw new IllegalArgumentException("invalid encoding value: " + encoding); } this.encoding = encoding; } /** * Sets the content of this element * @param externalContent The content */ private void setExternalContent(ASN1Primitive externalContent) { this.externalContent = externalContent; } /** * Sets the indirect reference of this element * @param indirectReference The reference */ private void setIndirectReference(ASN1Integer indirectReference) { this.indirectReference = indirectReference; } } bouncycastle-1.49.orig/src/org/bouncycastle/asn1/BERSetParser.java0000644000175000017500000000133211624617033024452 0ustar ebourgebourgpackage org.bouncycastle.asn1; import java.io.IOException; public class BERSetParser implements ASN1SetParser { private ASN1StreamParser _parser; BERSetParser(ASN1StreamParser parser) { this._parser = parser; } public ASN1Encodable readObject() throws IOException { return _parser.readObject(); } public ASN1Primitive getLoadedObject() throws IOException { return new BERSet(_parser.readVector()); } public ASN1Primitive toASN1Primitive() { try { return getLoadedObject(); } catch (IOException e) { throw new ASN1ParsingException(e.getMessage(), e); } } } bouncycastle-1.49.orig/src/org/bouncycastle/asn1/ASN1String.java0000644000175000017500000000013711625362120024077 0ustar ebourgebourgpackage org.bouncycastle.asn1; public interface ASN1String { public String getString(); } bouncycastle-1.49.orig/src/org/bouncycastle/asn1/ASN1Null.java0000644000175000017500000000244212103436276023552 0ustar ebourgebourgpackage org.bouncycastle.asn1; import java.io.IOException; /** * A NULL object. */ public abstract class ASN1Null extends ASN1Primitive { /** * @deprecated use DERNull.INSTANCE */ public ASN1Null() { } public static ASN1Null getInstance(Object o) { if (o instanceof ASN1Null) { return (ASN1Null)o; } if (o != null) { try { return ASN1Null.getInstance(ASN1Primitive.fromByteArray((byte[])o)); } catch (IOException e) { throw new IllegalArgumentException("failed to construct NULL from byte[]: " + e.getMessage()); } catch (ClassCastException e) { throw new IllegalArgumentException("unknown object in getInstance(): " + o.getClass().getName()); } } return null; } public int hashCode() { return -1; } boolean asn1Equals( ASN1Primitive o) { if (!(o instanceof ASN1Null)) { return false; } return true; } abstract void encode(ASN1OutputStream out) throws IOException; public String toString() { return "NULL"; } } bouncycastle-1.49.orig/src/org/bouncycastle/asn1/ASN1ParsingException.java0000644000175000017500000000063711643163767026140 0ustar ebourgebourgpackage org.bouncycastle.asn1; public class ASN1ParsingException extends IllegalStateException { private Throwable cause; public ASN1ParsingException(String message) { super(message); } public ASN1ParsingException(String message, Throwable cause) { super(message); this.cause = cause; } public Throwable getCause() { return cause; } } bouncycastle-1.49.orig/src/org/bouncycastle/asn1/ASN1Set.java0000644000175000017500000002607511762272666023416 0ustar ebourgebourgpackage org.bouncycastle.asn1; import java.io.ByteArrayOutputStream; import java.io.IOException; import java.util.Enumeration; import java.util.Vector; abstract public class ASN1Set extends ASN1Primitive { private Vector set = new Vector(); private boolean isSorted = false; /** * return an ASN1Set from the given object. * * @param obj the object we want converted. * @exception IllegalArgumentException if the object cannot be converted. */ public static ASN1Set getInstance( Object obj) { if (obj == null || obj instanceof ASN1Set) { return (ASN1Set)obj; } else if (obj instanceof ASN1SetParser) { return ASN1Set.getInstance(((ASN1SetParser)obj).toASN1Primitive()); } else if (obj instanceof byte[]) { try { return ASN1Set.getInstance(ASN1Primitive.fromByteArray((byte[])obj)); } catch (IOException e) { throw new IllegalArgumentException("failed to construct set from byte[]: " + e.getMessage()); } } else if (obj instanceof ASN1Encodable) { ASN1Primitive primitive = ((ASN1Encodable)obj).toASN1Primitive(); if (primitive instanceof ASN1Set) { return (ASN1Set)primitive; } } throw new IllegalArgumentException("unknown object in getInstance: " + obj.getClass().getName()); } /** * Return an ASN1 set from a tagged object. There is a special * case here, if an object appears to have been explicitly tagged on * reading but we were expecting it to be implicitly tagged in the * normal course of events it indicates that we lost the surrounding * set - so we need to add it back (this will happen if the tagged * object is a sequence that contains other sequences). If you are * dealing with implicitly tagged sets you really should * be using this method. * * @param obj the tagged object. * @param explicit true if the object is meant to be explicitly tagged * false otherwise. * @exception IllegalArgumentException if the tagged object cannot * be converted. */ public static ASN1Set getInstance( ASN1TaggedObject obj, boolean explicit) { if (explicit) { if (!obj.isExplicit()) { throw new IllegalArgumentException("object implicit - explicit expected."); } return (ASN1Set)obj.getObject(); } else { // // constructed object which appears to be explicitly tagged // and it's really implicit means we have to add the // surrounding set. // if (obj.isExplicit()) { if (obj instanceof BERTaggedObject) { return new BERSet(obj.getObject()); } else { return new DLSet(obj.getObject()); } } else { if (obj.getObject() instanceof ASN1Set) { return (ASN1Set)obj.getObject(); } // // in this case the parser returns a sequence, convert it // into a set. // if (obj.getObject() instanceof ASN1Sequence) { ASN1Sequence s = (ASN1Sequence)obj.getObject(); if (obj instanceof BERTaggedObject) { return new BERSet(s.toArray()); } else { return new DLSet(s.toArray()); } } } } throw new IllegalArgumentException("unknown object in getInstance: " + obj.getClass().getName()); } protected ASN1Set() { } /** * create a sequence containing one object */ protected ASN1Set( ASN1Encodable obj) { set.addElement(obj); } /** * create a sequence containing a vector of objects. */ protected ASN1Set( ASN1EncodableVector v, boolean doSort) { for (int i = 0; i != v.size(); i++) { set.addElement(v.get(i)); } if (doSort) { this.sort(); } } /** * create a sequence containing a vector of objects. */ protected ASN1Set( ASN1Encodable[] array, boolean doSort) { for (int i = 0; i != array.length; i++) { set.addElement(array[i]); } if (doSort) { this.sort(); } } public Enumeration getObjects() { return set.elements(); } /** * return the object at the set position indicated by index. * * @param index the set number (starting at zero) of the object * @return the object at the set position indicated by index. */ public ASN1Encodable getObjectAt( int index) { return (ASN1Encodable)set.elementAt(index); } /** * return the number of objects in this set. * * @return the number of objects in this set. */ public int size() { return set.size(); } public ASN1Encodable[] toArray() { ASN1Encodable[] values = new ASN1Encodable[this.size()]; for (int i = 0; i != this.size(); i++) { values[i] = this.getObjectAt(i); } return values; } public ASN1SetParser parser() { final ASN1Set outer = this; return new ASN1SetParser() { private final int max = size(); private int index; public ASN1Encodable readObject() throws IOException { if (index == max) { return null; } ASN1Encodable obj = getObjectAt(index++); if (obj instanceof ASN1Sequence) { return ((ASN1Sequence)obj).parser(); } if (obj instanceof ASN1Set) { return ((ASN1Set)obj).parser(); } return obj; } public ASN1Primitive getLoadedObject() { return outer; } public ASN1Primitive toASN1Primitive() { return outer; } }; } public int hashCode() { Enumeration e = this.getObjects(); int hashCode = size(); while (e.hasMoreElements()) { Object o = getNext(e); hashCode *= 17; hashCode ^= o.hashCode(); } return hashCode; } ASN1Primitive toDERObject() { if (isSorted) { ASN1Set derSet = new DERSet(); derSet.set = this.set; return derSet; } else { Vector v = new Vector(); for (int i = 0; i != set.size(); i++) { v.addElement(set.elementAt(i)); } ASN1Set derSet = new DERSet(); derSet.set = v; derSet.sort(); return derSet; } } ASN1Primitive toDLObject() { ASN1Set derSet = new DLSet(); derSet.set = this.set; return derSet; } boolean asn1Equals( ASN1Primitive o) { if (!(o instanceof ASN1Set)) { return false; } ASN1Set other = (ASN1Set)o; if (this.size() != other.size()) { return false; } Enumeration s1 = this.getObjects(); Enumeration s2 = other.getObjects(); while (s1.hasMoreElements()) { ASN1Encodable obj1 = getNext(s1); ASN1Encodable obj2 = getNext(s2); ASN1Primitive o1 = obj1.toASN1Primitive(); ASN1Primitive o2 = obj2.toASN1Primitive(); if (o1 == o2 || o1.equals(o2)) { continue; } return false; } return true; } private ASN1Encodable getNext(Enumeration e) { ASN1Encodable encObj = (ASN1Encodable)e.nextElement(); // unfortunately null was allowed as a substitute for DER null if (encObj == null) { return DERNull.INSTANCE; } return encObj; } /** * return true if a <= b (arrays are assumed padded with zeros). */ private boolean lessThanOrEqual( byte[] a, byte[] b) { int len = Math.min(a.length, b.length); for (int i = 0; i != len; ++i) { if (a[i] != b[i]) { return (a[i] & 0xff) < (b[i] & 0xff); } } return len == a.length; } private byte[] getEncoded( ASN1Encodable obj) { ByteArrayOutputStream bOut = new ByteArrayOutputStream(); ASN1OutputStream aOut = new ASN1OutputStream(bOut); try { aOut.writeObject(obj); } catch (IOException e) { throw new IllegalArgumentException("cannot encode object added to SET"); } return bOut.toByteArray(); } protected void sort() { if (!isSorted) { isSorted = true; if (set.size() > 1) { boolean swapped = true; int lastSwap = set.size() - 1; while (swapped) { int index = 0; int swapIndex = 0; byte[] a = getEncoded((ASN1Encodable)set.elementAt(0)); swapped = false; while (index != lastSwap) { byte[] b = getEncoded((ASN1Encodable)set.elementAt(index + 1)); if (lessThanOrEqual(a, b)) { a = b; } else { Object o = set.elementAt(index); set.setElementAt(set.elementAt(index + 1), index); set.setElementAt(o, index + 1); swapped = true; swapIndex = index; } index++; } lastSwap = swapIndex; } } } } boolean isConstructed() { return true; } abstract void encode(ASN1OutputStream out) throws IOException; public String toString() { return set.toString(); } } bouncycastle-1.49.orig/src/org/bouncycastle/asn1/bc/0000755000175000017500000000000012152033551021725 5ustar ebourgebourgbouncycastle-1.49.orig/src/org/bouncycastle/asn1/bc/BCObjectIdentifiers.java0000644000175000017500000000507411624622713026406 0ustar ebourgebourgpackage org.bouncycastle.asn1.bc; import org.bouncycastle.asn1.ASN1ObjectIdentifier; public interface BCObjectIdentifiers { /** * iso.org.dod.internet.private.enterprise.legion-of-the-bouncy-castle * * 1.3.6.1.4.1.22554 */ public static final ASN1ObjectIdentifier bc = new ASN1ObjectIdentifier("1.3.6.1.4.1.22554"); /** * pbe(1) algorithms */ public static final ASN1ObjectIdentifier bc_pbe = new ASN1ObjectIdentifier(bc.getId() + ".1"); /** * SHA-1(1) */ public static final ASN1ObjectIdentifier bc_pbe_sha1 = new ASN1ObjectIdentifier(bc_pbe.getId() + ".1"); /** * SHA-2(2) . (SHA-256(1)|SHA-384(2)|SHA-512(3)|SHA-224(4)) */ public static final ASN1ObjectIdentifier bc_pbe_sha256 = new ASN1ObjectIdentifier(bc_pbe.getId() + ".2.1"); public static final ASN1ObjectIdentifier bc_pbe_sha384 = new ASN1ObjectIdentifier(bc_pbe.getId() + ".2.2"); public static final ASN1ObjectIdentifier bc_pbe_sha512 = new ASN1ObjectIdentifier(bc_pbe.getId() + ".2.3"); public static final ASN1ObjectIdentifier bc_pbe_sha224 = new ASN1ObjectIdentifier(bc_pbe.getId() + ".2.4"); /** * PKCS-5(1)|PKCS-12(2) */ public static final ASN1ObjectIdentifier bc_pbe_sha1_pkcs5 = new ASN1ObjectIdentifier(bc_pbe_sha1.getId() + ".1"); public static final ASN1ObjectIdentifier bc_pbe_sha1_pkcs12 = new ASN1ObjectIdentifier(bc_pbe_sha1.getId() + ".2"); public static final ASN1ObjectIdentifier bc_pbe_sha256_pkcs5 = new ASN1ObjectIdentifier(bc_pbe_sha256.getId() + ".1"); public static final ASN1ObjectIdentifier bc_pbe_sha256_pkcs12 = new ASN1ObjectIdentifier(bc_pbe_sha256.getId() + ".2"); /** * AES(1) . (CBC-128(2)|CBC-192(22)|CBC-256(42)) */ public static final ASN1ObjectIdentifier bc_pbe_sha1_pkcs12_aes128_cbc = new ASN1ObjectIdentifier(bc_pbe_sha1_pkcs12.getId() + ".1.2"); public static final ASN1ObjectIdentifier bc_pbe_sha1_pkcs12_aes192_cbc = new ASN1ObjectIdentifier(bc_pbe_sha1_pkcs12.getId() + ".1.22"); public static final ASN1ObjectIdentifier bc_pbe_sha1_pkcs12_aes256_cbc = new ASN1ObjectIdentifier(bc_pbe_sha1_pkcs12.getId() + ".1.42"); public static final ASN1ObjectIdentifier bc_pbe_sha256_pkcs12_aes128_cbc = new ASN1ObjectIdentifier(bc_pbe_sha256_pkcs12.getId() + ".1.2"); public static final ASN1ObjectIdentifier bc_pbe_sha256_pkcs12_aes192_cbc = new ASN1ObjectIdentifier(bc_pbe_sha256_pkcs12.getId() + ".1.22"); public static final ASN1ObjectIdentifier bc_pbe_sha256_pkcs12_aes256_cbc = new ASN1ObjectIdentifier(bc_pbe_sha256_pkcs12.getId() + ".1.42"); } bouncycastle-1.49.orig/src/org/bouncycastle/asn1/DERGeneralString.java0000644000175000017500000000451212062243165025311 0ustar ebourgebourgpackage org.bouncycastle.asn1; import java.io.IOException; import org.bouncycastle.util.Arrays; import org.bouncycastle.util.Strings; public class DERGeneralString extends ASN1Primitive implements ASN1String { private byte[] string; public static DERGeneralString getInstance( Object obj) { if (obj == null || obj instanceof DERGeneralString) { return (DERGeneralString) obj; } if (obj instanceof byte[]) { try { return (DERGeneralString)fromByteArray((byte[])obj); } catch (Exception e) { throw new IllegalArgumentException("encoding error in getInstance: " + e.toString()); } } throw new IllegalArgumentException("illegal object in getInstance: " + obj.getClass().getName()); } public static DERGeneralString getInstance( ASN1TaggedObject obj, boolean explicit) { ASN1Primitive o = obj.getObject(); if (explicit || o instanceof DERGeneralString) { return getInstance(o); } else { return new DERGeneralString(((ASN1OctetString)o).getOctets()); } } DERGeneralString(byte[] string) { this.string = string; } public DERGeneralString(String string) { this.string = Strings.toByteArray(string); } public String getString() { return Strings.fromByteArray(string); } public String toString() { return getString(); } public byte[] getOctets() { return Arrays.clone(string); } boolean isConstructed() { return false; } int encodedLength() { return 1 + StreamUtil.calculateBodyLength(string.length) + string.length; } void encode(ASN1OutputStream out) throws IOException { out.writeEncoded(BERTags.GENERAL_STRING, string); } public int hashCode() { return Arrays.hashCode(string); } boolean asn1Equals(ASN1Primitive o) { if (!(o instanceof DERGeneralString)) { return false; } DERGeneralString s = (DERGeneralString)o; return Arrays.areEqual(string, s.string); } } bouncycastle-1.49.orig/src/org/bouncycastle/asn1/DERFactory.java0000644000175000017500000000066011625624537024166 0ustar ebourgebourgpackage org.bouncycastle.asn1; class DERFactory { static final ASN1Sequence EMPTY_SEQUENCE = new DERSequence(); static final ASN1Set EMPTY_SET = new DERSet(); static ASN1Sequence createSequence(ASN1EncodableVector v) { return v.size() < 1 ? EMPTY_SEQUENCE : new DLSequence(v); } static ASN1Set createSet(ASN1EncodableVector v) { return v.size() < 1 ? EMPTY_SET : new DLSet(v); } } bouncycastle-1.49.orig/src/org/bouncycastle/asn1/ASN1Object.java0000644000175000017500000000453411730521773024054 0ustar ebourgebourgpackage org.bouncycastle.asn1; import java.io.ByteArrayOutputStream; import java.io.IOException; public abstract class ASN1Object implements ASN1Encodable { /** * Return the default BER or DER encoding for this object. * * @return BER/DER byte encoded object. * @throws java.io.IOException on encoding error. */ public byte[] getEncoded() throws IOException { ByteArrayOutputStream bOut = new ByteArrayOutputStream(); ASN1OutputStream aOut = new ASN1OutputStream(bOut); aOut.writeObject(this); return bOut.toByteArray(); } /** * Return either the default for "BER" or a DER encoding if "DER" is specified. * * @param encoding name of encoding to use. * @return byte encoded object. * @throws IOException on encoding error. */ public byte[] getEncoded( String encoding) throws IOException { if (encoding.equals(ASN1Encoding.DER)) { ByteArrayOutputStream bOut = new ByteArrayOutputStream(); DEROutputStream dOut = new DEROutputStream(bOut); dOut.writeObject(this); return bOut.toByteArray(); } else if (encoding.equals(ASN1Encoding.DL)) { ByteArrayOutputStream bOut = new ByteArrayOutputStream(); DLOutputStream dOut = new DLOutputStream(bOut); dOut.writeObject(this); return bOut.toByteArray(); } return this.getEncoded(); } public int hashCode() { return this.toASN1Primitive().hashCode(); } public boolean equals( Object o) { if (this == o) { return true; } if (!(o instanceof ASN1Encodable)) { return false; } ASN1Encodable other = (ASN1Encodable)o; return this.toASN1Primitive().equals(other.toASN1Primitive()); } /** * @deprecated use toASN1Primitive() * @return the underlying primitive type. */ public ASN1Primitive toASN1Object() { return this.toASN1Primitive(); } protected static boolean hasEncodedTagValue(Object obj, int tagValue) { return (obj instanceof byte[]) && ((byte[])obj)[0] == tagValue; } public abstract ASN1Primitive toASN1Primitive(); } bouncycastle-1.49.orig/src/org/bouncycastle/asn1/DERSetParser.java0000644000175000017500000000134111624650302024450 0ustar ebourgebourgpackage org.bouncycastle.asn1; import java.io.IOException; public class DERSetParser implements ASN1SetParser { private ASN1StreamParser _parser; DERSetParser(ASN1StreamParser parser) { this._parser = parser; } public ASN1Encodable readObject() throws IOException { return _parser.readObject(); } public ASN1Primitive getLoadedObject() throws IOException { return new DERSet(_parser.readVector(), false); } public ASN1Primitive toASN1Primitive() { try { return getLoadedObject(); } catch (IOException e) { throw new ASN1ParsingException(e.getMessage(), e); } } } bouncycastle-1.49.orig/src/org/bouncycastle/asn1/ess/0000755000175000017500000000000012152033551022133 5ustar ebourgebourgbouncycastle-1.49.orig/src/org/bouncycastle/asn1/ess/OtherSigningCertificate.java0000644000175000017500000000516111723262010027541 0ustar ebourgebourgpackage org.bouncycastle.asn1.ess; import org.bouncycastle.asn1.ASN1EncodableVector; import org.bouncycastle.asn1.ASN1Object; import org.bouncycastle.asn1.ASN1Primitive; import org.bouncycastle.asn1.ASN1Sequence; import org.bouncycastle.asn1.DERSequence; import org.bouncycastle.asn1.x509.PolicyInformation; public class OtherSigningCertificate extends ASN1Object { ASN1Sequence certs; ASN1Sequence policies; public static OtherSigningCertificate getInstance(Object o) { if (o instanceof OtherSigningCertificate) { return (OtherSigningCertificate) o; } else if (o != null) { return new OtherSigningCertificate(ASN1Sequence.getInstance(o)); } return null; } /** * constructeurs */ private OtherSigningCertificate(ASN1Sequence seq) { if (seq.size() < 1 || seq.size() > 2) { throw new IllegalArgumentException("Bad sequence size: " + seq.size()); } this.certs = ASN1Sequence.getInstance(seq.getObjectAt(0)); if (seq.size() > 1) { this.policies = ASN1Sequence.getInstance(seq.getObjectAt(1)); } } public OtherSigningCertificate( OtherCertID otherCertID) { certs = new DERSequence(otherCertID); } public OtherCertID[] getCerts() { OtherCertID[] cs = new OtherCertID[certs.size()]; for (int i = 0; i != certs.size(); i++) { cs[i] = OtherCertID.getInstance(certs.getObjectAt(i)); } return cs; } public PolicyInformation[] getPolicies() { if (policies == null) { return null; } PolicyInformation[] ps = new PolicyInformation[policies.size()]; for (int i = 0; i != policies.size(); i++) { ps[i] = PolicyInformation.getInstance(policies.getObjectAt(i)); } return ps; } /** * The definition of OtherSigningCertificate is *
         * OtherSigningCertificate ::=  SEQUENCE {
         *      certs        SEQUENCE OF OtherCertID,
         *      policies     SEQUENCE OF PolicyInformation OPTIONAL
         * }
         * 
    * id-aa-ets-otherSigCert OBJECT IDENTIFIER ::= { iso(1) * member-body(2) us(840) rsadsi(113549) pkcs(1) pkcs9(9) * smime(16) id-aa(2) 19 } */ public ASN1Primitive toASN1Primitive() { ASN1EncodableVector v = new ASN1EncodableVector(); v.add(certs); if (policies != null) { v.add(policies); } return new DERSequence(v); } } bouncycastle-1.49.orig/src/org/bouncycastle/asn1/ess/SigningCertificate.java0000644000175000017500000000517611723262010026545 0ustar ebourgebourgpackage org.bouncycastle.asn1.ess; import org.bouncycastle.asn1.ASN1EncodableVector; import org.bouncycastle.asn1.ASN1Object; import org.bouncycastle.asn1.ASN1Primitive; import org.bouncycastle.asn1.ASN1Sequence; import org.bouncycastle.asn1.DERSequence; import org.bouncycastle.asn1.x509.PolicyInformation; public class SigningCertificate extends ASN1Object { ASN1Sequence certs; ASN1Sequence policies; public static SigningCertificate getInstance(Object o) { if (o instanceof SigningCertificate) { return (SigningCertificate) o; } else if (o != null) { return new SigningCertificate(ASN1Sequence.getInstance(o)); } return null; } /** * constructeurs */ private SigningCertificate(ASN1Sequence seq) { if (seq.size() < 1 || seq.size() > 2) { throw new IllegalArgumentException("Bad sequence size: " + seq.size()); } this.certs = ASN1Sequence.getInstance(seq.getObjectAt(0)); if (seq.size() > 1) { this.policies = ASN1Sequence.getInstance(seq.getObjectAt(1)); } } public SigningCertificate( ESSCertID essCertID) { certs = new DERSequence(essCertID); } public ESSCertID[] getCerts() { ESSCertID[] cs = new ESSCertID[certs.size()]; for (int i = 0; i != certs.size(); i++) { cs[i] = ESSCertID.getInstance(certs.getObjectAt(i)); } return cs; } public PolicyInformation[] getPolicies() { if (policies == null) { return null; } PolicyInformation[] ps = new PolicyInformation[policies.size()]; for (int i = 0; i != policies.size(); i++) { ps[i] = PolicyInformation.getInstance(policies.getObjectAt(i)); } return ps; } /** * The definition of SigningCertificate is *
         * SigningCertificate ::=  SEQUENCE {
         *      certs        SEQUENCE OF ESSCertID,
         *      policies     SEQUENCE OF PolicyInformation OPTIONAL
         * }
         * 
    * id-aa-signingCertificate OBJECT IDENTIFIER ::= { iso(1) * member-body(2) us(840) rsadsi(113549) pkcs(1) pkcs9(9) * smime(16) id-aa(2) 12 } */ public ASN1Primitive toASN1Primitive() { ASN1EncodableVector v = new ASN1EncodableVector(); v.add(certs); if (policies != null) { v.add(policies); } return new DERSequence(v); } } bouncycastle-1.49.orig/src/org/bouncycastle/asn1/ess/ContentIdentifier.java0000644000175000017500000000263211723273127026426 0ustar ebourgebourgpackage org.bouncycastle.asn1.ess; import org.bouncycastle.asn1.ASN1Object; import org.bouncycastle.asn1.ASN1OctetString; import org.bouncycastle.asn1.ASN1Primitive; import org.bouncycastle.asn1.DEROctetString; public class ContentIdentifier extends ASN1Object { ASN1OctetString value; public static ContentIdentifier getInstance(Object o) { if (o instanceof ContentIdentifier) { return (ContentIdentifier) o; } else if (o != null) { return new ContentIdentifier(ASN1OctetString.getInstance(o)); } return null; } /** * Create from OCTET STRING whose octets represent the identifier. */ private ContentIdentifier( ASN1OctetString value) { this.value = value; } /** * Create from byte array representing the identifier. */ public ContentIdentifier( byte[] value) { this(new DEROctetString(value)); } public ASN1OctetString getValue() { return value; } /** * The definition of ContentIdentifier is *
         * ContentIdentifier ::=  OCTET STRING
         * 
    * id-aa-contentIdentifier OBJECT IDENTIFIER ::= { iso(1) * member-body(2) us(840) rsadsi(113549) pkcs(1) pkcs9(9) * smime(16) id-aa(2) 7 } */ public ASN1Primitive toASN1Primitive() { return value; } } bouncycastle-1.49.orig/src/org/bouncycastle/asn1/ess/OtherCertID.java0000644000175000017500000000663711737273326025144 0ustar ebourgebourgpackage org.bouncycastle.asn1.ess; import org.bouncycastle.asn1.ASN1Encodable; import org.bouncycastle.asn1.ASN1EncodableVector; import org.bouncycastle.asn1.ASN1Object; import org.bouncycastle.asn1.ASN1OctetString; import org.bouncycastle.asn1.ASN1Primitive; import org.bouncycastle.asn1.ASN1Sequence; import org.bouncycastle.asn1.DERSequence; import org.bouncycastle.asn1.x509.AlgorithmIdentifier; import org.bouncycastle.asn1.x509.DigestInfo; import org.bouncycastle.asn1.x509.IssuerSerial; public class OtherCertID extends ASN1Object { private ASN1Encodable otherCertHash; private IssuerSerial issuerSerial; public static OtherCertID getInstance(Object o) { if (o instanceof OtherCertID) { return (OtherCertID) o; } else if (o != null) { return new OtherCertID(ASN1Sequence.getInstance(o)); } return null; } /** * constructor */ private OtherCertID(ASN1Sequence seq) { if (seq.size() < 1 || seq.size() > 2) { throw new IllegalArgumentException("Bad sequence size: " + seq.size()); } if (seq.getObjectAt(0).toASN1Primitive() instanceof ASN1OctetString) { otherCertHash = ASN1OctetString.getInstance(seq.getObjectAt(0)); } else { otherCertHash = DigestInfo.getInstance(seq.getObjectAt(0)); } if (seq.size() > 1) { issuerSerial = IssuerSerial.getInstance(seq.getObjectAt(1)); } } public OtherCertID( AlgorithmIdentifier algId, byte[] digest) { this.otherCertHash = new DigestInfo(algId, digest); } public OtherCertID( AlgorithmIdentifier algId, byte[] digest, IssuerSerial issuerSerial) { this.otherCertHash = new DigestInfo(algId, digest); this.issuerSerial = issuerSerial; } public AlgorithmIdentifier getAlgorithmHash() { if (otherCertHash.toASN1Primitive() instanceof ASN1OctetString) { // SHA-1 return new AlgorithmIdentifier("1.3.14.3.2.26"); } else { return DigestInfo.getInstance(otherCertHash).getAlgorithmId(); } } public byte[] getCertHash() { if (otherCertHash.toASN1Primitive() instanceof ASN1OctetString) { // SHA-1 return ((ASN1OctetString)otherCertHash.toASN1Primitive()).getOctets(); } else { return DigestInfo.getInstance(otherCertHash).getDigest(); } } public IssuerSerial getIssuerSerial() { return issuerSerial; } /** *
         * OtherCertID ::= SEQUENCE {
         *     otherCertHash    OtherHash,
         *     issuerSerial     IssuerSerial OPTIONAL }
         *
         * OtherHash ::= CHOICE {
         *     sha1Hash     OCTET STRING,
         *     otherHash    OtherHashAlgAndValue }
         *
         * OtherHashAlgAndValue ::= SEQUENCE {
         *     hashAlgorithm    AlgorithmIdentifier,
         *     hashValue        OCTET STRING }
         *
         * 
    */ public ASN1Primitive toASN1Primitive() { ASN1EncodableVector v = new ASN1EncodableVector(); v.add(otherCertHash); if (issuerSerial != null) { v.add(issuerSerial); } return new DERSequence(v); } } bouncycastle-1.49.orig/src/org/bouncycastle/asn1/ess/ESSCertID.java0000644000175000017500000000413511723273127024476 0ustar ebourgebourgpackage org.bouncycastle.asn1.ess; import org.bouncycastle.asn1.ASN1EncodableVector; import org.bouncycastle.asn1.ASN1Object; import org.bouncycastle.asn1.ASN1OctetString; import org.bouncycastle.asn1.ASN1Primitive; import org.bouncycastle.asn1.ASN1Sequence; import org.bouncycastle.asn1.DEROctetString; import org.bouncycastle.asn1.DERSequence; import org.bouncycastle.asn1.x509.IssuerSerial; public class ESSCertID extends ASN1Object { private ASN1OctetString certHash; private IssuerSerial issuerSerial; public static ESSCertID getInstance(Object o) { if (o instanceof ESSCertID) { return (ESSCertID)o; } else if (o != null) { return new ESSCertID(ASN1Sequence.getInstance(o)); } return null; } /** * constructor */ private ESSCertID(ASN1Sequence seq) { if (seq.size() < 1 || seq.size() > 2) { throw new IllegalArgumentException("Bad sequence size: " + seq.size()); } certHash = ASN1OctetString.getInstance(seq.getObjectAt(0)); if (seq.size() > 1) { issuerSerial = IssuerSerial.getInstance(seq.getObjectAt(1)); } } public ESSCertID( byte[] hash) { certHash = new DEROctetString(hash); } public ESSCertID( byte[] hash, IssuerSerial issuerSerial) { this.certHash = new DEROctetString(hash); this.issuerSerial = issuerSerial; } public byte[] getCertHash() { return certHash.getOctets(); } public IssuerSerial getIssuerSerial() { return issuerSerial; } /** *
         * ESSCertID ::= SEQUENCE {
         *     certHash Hash, 
         *     issuerSerial IssuerSerial OPTIONAL }
         * 
    */ public ASN1Primitive toASN1Primitive() { ASN1EncodableVector v = new ASN1EncodableVector(); v.add(certHash); if (issuerSerial != null) { v.add(issuerSerial); } return new DERSequence(v); } } bouncycastle-1.49.orig/src/org/bouncycastle/asn1/ess/SigningCertificateV2.java0000644000175000017500000000667512117475207026776 0ustar ebourgebourgpackage org.bouncycastle.asn1.ess; import org.bouncycastle.asn1.ASN1EncodableVector; import org.bouncycastle.asn1.ASN1Object; import org.bouncycastle.asn1.ASN1Primitive; import org.bouncycastle.asn1.ASN1Sequence; import org.bouncycastle.asn1.DERSequence; import org.bouncycastle.asn1.x509.PolicyInformation; public class SigningCertificateV2 extends ASN1Object { ASN1Sequence certs; ASN1Sequence policies; public static SigningCertificateV2 getInstance( Object o) { if (o == null || o instanceof SigningCertificateV2) { return (SigningCertificateV2) o; } else if (o instanceof ASN1Sequence) { return new SigningCertificateV2((ASN1Sequence) o); } return null; } private SigningCertificateV2( ASN1Sequence seq) { if (seq.size() < 1 || seq.size() > 2) { throw new IllegalArgumentException("Bad sequence size: " + seq.size()); } this.certs = ASN1Sequence.getInstance(seq.getObjectAt(0)); if (seq.size() > 1) { this.policies = ASN1Sequence.getInstance(seq.getObjectAt(1)); } } public SigningCertificateV2( ESSCertIDv2 cert) { this.certs = new DERSequence(cert); } public SigningCertificateV2( ESSCertIDv2[] certs) { ASN1EncodableVector v = new ASN1EncodableVector(); for (int i=0; i < certs.length; i++) { v.add(certs[i]); } this.certs = new DERSequence(v); } public SigningCertificateV2( ESSCertIDv2[] certs, PolicyInformation[] policies) { ASN1EncodableVector v = new ASN1EncodableVector(); for (int i=0; i < certs.length; i++) { v.add(certs[i]); } this.certs = new DERSequence(v); if (policies != null) { v = new ASN1EncodableVector(); for (int i=0; i < policies.length; i++) { v.add(policies[i]); } this.policies = new DERSequence(v); } } public ESSCertIDv2[] getCerts() { ESSCertIDv2[] certIds = new ESSCertIDv2[certs.size()]; for (int i = 0; i != certs.size(); i++) { certIds[i] = ESSCertIDv2.getInstance(certs.getObjectAt(i)); } return certIds; } public PolicyInformation[] getPolicies() { if (policies == null) { return null; } PolicyInformation[] policyInformations = new PolicyInformation[policies.size()]; for (int i = 0; i != policies.size(); i++) { policyInformations[i] = PolicyInformation.getInstance(policies.getObjectAt(i)); } return policyInformations; } /** * The definition of SigningCertificateV2 is *
         * SigningCertificateV2 ::=  SEQUENCE {
         *      certs        SEQUENCE OF ESSCertIDv2,
         *      policies     SEQUENCE OF PolicyInformation OPTIONAL
         * }
         * 
    * id-aa-signingCertificateV2 OBJECT IDENTIFIER ::= { iso(1) * member-body(2) us(840) rsadsi(113549) pkcs(1) pkcs9(9) * smime(16) id-aa(2) 47 } */ public ASN1Primitive toASN1Primitive() { ASN1EncodableVector v = new ASN1EncodableVector(); v.add(certs); if (policies != null) { v.add(policies); } return new DERSequence(v); } } bouncycastle-1.49.orig/src/org/bouncycastle/asn1/ess/ESSCertIDv2.java0000644000175000017500000000740212117471757024755 0ustar ebourgebourgpackage org.bouncycastle.asn1.ess; import org.bouncycastle.asn1.ASN1EncodableVector; import org.bouncycastle.asn1.ASN1Object; import org.bouncycastle.asn1.ASN1OctetString; import org.bouncycastle.asn1.ASN1Primitive; import org.bouncycastle.asn1.ASN1Sequence; import org.bouncycastle.asn1.DEROctetString; import org.bouncycastle.asn1.DERSequence; import org.bouncycastle.asn1.nist.NISTObjectIdentifiers; import org.bouncycastle.asn1.x509.AlgorithmIdentifier; import org.bouncycastle.asn1.x509.IssuerSerial; public class ESSCertIDv2 extends ASN1Object { private AlgorithmIdentifier hashAlgorithm; private byte[] certHash; private IssuerSerial issuerSerial; private static final AlgorithmIdentifier DEFAULT_ALG_ID = new AlgorithmIdentifier(NISTObjectIdentifiers.id_sha256); public static ESSCertIDv2 getInstance( Object o) { if (o instanceof ESSCertIDv2) { return (ESSCertIDv2) o; } else if (o != null) { return new ESSCertIDv2(ASN1Sequence.getInstance(o)); } return null; } private ESSCertIDv2( ASN1Sequence seq) { if (seq.size() > 3) { throw new IllegalArgumentException("Bad sequence size: " + seq.size()); } int count = 0; if (seq.getObjectAt(0) instanceof ASN1OctetString) { // Default value this.hashAlgorithm = DEFAULT_ALG_ID; } else { this.hashAlgorithm = AlgorithmIdentifier.getInstance(seq.getObjectAt(count++).toASN1Primitive()); } this.certHash = ASN1OctetString.getInstance(seq.getObjectAt(count++).toASN1Primitive()).getOctets(); if (seq.size() > count) { this.issuerSerial = IssuerSerial.getInstance(seq.getObjectAt(count)); } } public ESSCertIDv2( byte[] certHash) { this(null, certHash, null); } public ESSCertIDv2( AlgorithmIdentifier algId, byte[] certHash) { this(algId, certHash, null); } public ESSCertIDv2( byte[] certHash, IssuerSerial issuerSerial) { this(null, certHash, issuerSerial); } public ESSCertIDv2( AlgorithmIdentifier algId, byte[] certHash, IssuerSerial issuerSerial) { if (algId == null) { // Default value this.hashAlgorithm = DEFAULT_ALG_ID; } else { this.hashAlgorithm = algId; } this.certHash = certHash; this.issuerSerial = issuerSerial; } public AlgorithmIdentifier getHashAlgorithm() { return this.hashAlgorithm; } public byte[] getCertHash() { return certHash; } public IssuerSerial getIssuerSerial() { return issuerSerial; } /** *
         * ESSCertIDv2 ::=  SEQUENCE {
         *     hashAlgorithm     AlgorithmIdentifier
         *              DEFAULT {algorithm id-sha256},
         *     certHash          Hash,
         *     issuerSerial      IssuerSerial OPTIONAL
         * }
         *
         * Hash ::= OCTET STRING
         *
         * IssuerSerial ::= SEQUENCE {
         *     issuer         GeneralNames,
         *     serialNumber   CertificateSerialNumber
         * }
         * 
    */ public ASN1Primitive toASN1Primitive() { ASN1EncodableVector v = new ASN1EncodableVector(); if (!hashAlgorithm.equals(DEFAULT_ALG_ID)) { v.add(hashAlgorithm); } v.add(new DEROctetString(certHash).toASN1Primitive()); if (issuerSerial != null) { v.add(issuerSerial); } return new DERSequence(v); } } bouncycastle-1.49.orig/src/org/bouncycastle/asn1/ess/ContentHints.java0000644000175000017500000000545211724301431025423 0ustar ebourgebourgpackage org.bouncycastle.asn1.ess; import org.bouncycastle.asn1.ASN1Encodable; import org.bouncycastle.asn1.ASN1EncodableVector; import org.bouncycastle.asn1.ASN1Object; import org.bouncycastle.asn1.ASN1ObjectIdentifier; import org.bouncycastle.asn1.ASN1Primitive; import org.bouncycastle.asn1.ASN1Sequence; import org.bouncycastle.asn1.DERObjectIdentifier; import org.bouncycastle.asn1.DERSequence; import org.bouncycastle.asn1.DERUTF8String; public class ContentHints extends ASN1Object { private DERUTF8String contentDescription; private ASN1ObjectIdentifier contentType; public static ContentHints getInstance(Object o) { if (o instanceof ContentHints) { return (ContentHints)o; } else if (o != null) { return new ContentHints(ASN1Sequence.getInstance(o)); } return null; } /** * constructor */ private ContentHints(ASN1Sequence seq) { ASN1Encodable field = seq.getObjectAt(0); if (field.toASN1Primitive() instanceof DERUTF8String) { contentDescription = DERUTF8String.getInstance(field); contentType = ASN1ObjectIdentifier.getInstance(seq.getObjectAt(1)); } else { contentType = ASN1ObjectIdentifier.getInstance(seq.getObjectAt(0)); } } /** * @deprecated use ASN1ObjectIdentifier */ public ContentHints( DERObjectIdentifier contentType) { this(new ASN1ObjectIdentifier(contentType.getId())); } /** * @deprecated use ASN1ObjectIdentifier */ public ContentHints( DERObjectIdentifier contentType, DERUTF8String contentDescription) { this(new ASN1ObjectIdentifier(contentType.getId()), contentDescription); } public ContentHints( ASN1ObjectIdentifier contentType) { this.contentType = contentType; this.contentDescription = null; } public ContentHints( ASN1ObjectIdentifier contentType, DERUTF8String contentDescription) { this.contentType = contentType; this.contentDescription = contentDescription; } public ASN1ObjectIdentifier getContentType() { return contentType; } public DERUTF8String getContentDescription() { return contentDescription; } /** *
         * ContentHints ::= SEQUENCE {
         *   contentDescription UTF8String (SIZE (1..MAX)) OPTIONAL,
         *   contentType ContentType }
         * 
    */ public ASN1Primitive toASN1Primitive() { ASN1EncodableVector v = new ASN1EncodableVector(); if (contentDescription != null) { v.add(contentDescription); } v.add(contentType); return new DERSequence(v); } } bouncycastle-1.49.orig/src/org/bouncycastle/asn1/ess/package.html0000644000175000017500000000025511052463707024426 0ustar ebourgebourg Support classes useful for encoding and supporting Enhanced Security Services for S/MIME as described RFC 2634 and RFC 5035. bouncycastle-1.49.orig/src/org/bouncycastle/asn1/ASN1EncodableVector.java0000644000175000017500000000117212151251423025666 0ustar ebourgebourgpackage org.bouncycastle.asn1; import java.util.Enumeration; import java.util.Vector; public class ASN1EncodableVector { Vector v = new Vector(); public ASN1EncodableVector() { } public void add(ASN1Encodable obj) { v.addElement(obj); } public void addAll(ASN1EncodableVector other) { for (Enumeration en = other.v.elements(); en.hasMoreElements();) { v.addElement(en.nextElement()); } } public ASN1Encodable get(int i) { return (ASN1Encodable)v.elementAt(i); } public int size() { return v.size(); } } bouncycastle-1.49.orig/src/org/bouncycastle/asn1/ConstructedOctetStream.java0000644000175000017500000000461211624652555026675 0ustar ebourgebourgpackage org.bouncycastle.asn1; import java.io.IOException; import java.io.InputStream; class ConstructedOctetStream extends InputStream { private final ASN1StreamParser _parser; private boolean _first = true; private InputStream _currentStream; ConstructedOctetStream( ASN1StreamParser parser) { _parser = parser; } public int read(byte[] b, int off, int len) throws IOException { if (_currentStream == null) { if (!_first) { return -1; } ASN1OctetStringParser s = (ASN1OctetStringParser)_parser.readObject(); if (s == null) { return -1; } _first = false; _currentStream = s.getOctetStream(); } int totalRead = 0; for (;;) { int numRead = _currentStream.read(b, off + totalRead, len - totalRead); if (numRead >= 0) { totalRead += numRead; if (totalRead == len) { return totalRead; } } else { ASN1OctetStringParser aos = (ASN1OctetStringParser)_parser.readObject(); if (aos == null) { _currentStream = null; return totalRead < 1 ? -1 : totalRead; } _currentStream = aos.getOctetStream(); } } } public int read() throws IOException { if (_currentStream == null) { if (!_first) { return -1; } ASN1OctetStringParser s = (ASN1OctetStringParser)_parser.readObject(); if (s == null) { return -1; } _first = false; _currentStream = s.getOctetStream(); } for (;;) { int b = _currentStream.read(); if (b >= 0) { return b; } ASN1OctetStringParser s = (ASN1OctetStringParser)_parser.readObject(); if (s == null) { _currentStream = null; return -1; } _currentStream = s.getOctetStream(); } } } bouncycastle-1.49.orig/src/org/bouncycastle/asn1/gnu/0000755000175000017500000000000012152033551022132 5ustar ebourgebourgbouncycastle-1.49.orig/src/org/bouncycastle/asn1/gnu/GNUObjectIdentifiers.java0000644000175000017500000000605211624622714026756 0ustar ebourgebourgpackage org.bouncycastle.asn1.gnu; import org.bouncycastle.asn1.ASN1ObjectIdentifier; public interface GNUObjectIdentifiers { public static final ASN1ObjectIdentifier GNU = new ASN1ObjectIdentifier("1.3.6.1.4.1.11591.1"); // GNU Radius public static final ASN1ObjectIdentifier GnuPG = new ASN1ObjectIdentifier("1.3.6.1.4.1.11591.2"); // GnuPG (Ägypten) public static final ASN1ObjectIdentifier notation = new ASN1ObjectIdentifier("1.3.6.1.4.1.11591.2.1"); // notation public static final ASN1ObjectIdentifier pkaAddress = new ASN1ObjectIdentifier("1.3.6.1.4.1.11591.2.1.1"); // pkaAddress public static final ASN1ObjectIdentifier GnuRadar = new ASN1ObjectIdentifier("1.3.6.1.4.1.11591.3"); // GNU Radar public static final ASN1ObjectIdentifier digestAlgorithm = new ASN1ObjectIdentifier("1.3.6.1.4.1.11591.12"); // digestAlgorithm public static final ASN1ObjectIdentifier Tiger_192 = new ASN1ObjectIdentifier("1.3.6.1.4.1.11591.12.2"); // TIGER/192 public static final ASN1ObjectIdentifier encryptionAlgorithm = new ASN1ObjectIdentifier("1.3.6.1.4.1.11591.13"); // encryptionAlgorithm public static final ASN1ObjectIdentifier Serpent = new ASN1ObjectIdentifier("1.3.6.1.4.1.11591.13.2"); // Serpent public static final ASN1ObjectIdentifier Serpent_128_ECB = new ASN1ObjectIdentifier("1.3.6.1.4.1.11591.13.2.1"); // Serpent-128-ECB public static final ASN1ObjectIdentifier Serpent_128_CBC = new ASN1ObjectIdentifier("1.3.6.1.4.1.11591.13.2.2"); // Serpent-128-CBC public static final ASN1ObjectIdentifier Serpent_128_OFB = new ASN1ObjectIdentifier("1.3.6.1.4.1.11591.13.2.3"); // Serpent-128-OFB public static final ASN1ObjectIdentifier Serpent_128_CFB = new ASN1ObjectIdentifier("1.3.6.1.4.1.11591.13.2.4"); // Serpent-128-CFB public static final ASN1ObjectIdentifier Serpent_192_ECB = new ASN1ObjectIdentifier("1.3.6.1.4.1.11591.13.2.21"); // Serpent-192-ECB public static final ASN1ObjectIdentifier Serpent_192_CBC = new ASN1ObjectIdentifier("1.3.6.1.4.1.11591.13.2.22"); // Serpent-192-CBC public static final ASN1ObjectIdentifier Serpent_192_OFB = new ASN1ObjectIdentifier("1.3.6.1.4.1.11591.13.2.23"); // Serpent-192-OFB public static final ASN1ObjectIdentifier Serpent_192_CFB = new ASN1ObjectIdentifier("1.3.6.1.4.1.11591.13.2.24"); // Serpent-192-CFB public static final ASN1ObjectIdentifier Serpent_256_ECB = new ASN1ObjectIdentifier("1.3.6.1.4.1.11591.13.2.41"); // Serpent-256-ECB public static final ASN1ObjectIdentifier Serpent_256_CBC = new ASN1ObjectIdentifier("1.3.6.1.4.1.11591.13.2.42"); // Serpent-256-CBC public static final ASN1ObjectIdentifier Serpent_256_OFB = new ASN1ObjectIdentifier("1.3.6.1.4.1.11591.13.2.43"); // Serpent-256-OFB public static final ASN1ObjectIdentifier Serpent_256_CFB = new ASN1ObjectIdentifier("1.3.6.1.4.1.11591.13.2.44"); // Serpent-256-CFB public static final ASN1ObjectIdentifier CRC = new ASN1ObjectIdentifier("1.3.6.1.4.1.11591.14"); // CRC algorithms public static final ASN1ObjectIdentifier CRC32 = new ASN1ObjectIdentifier("1.3.6.1.4.1.11591.14.1"); // CRC 32 } bouncycastle-1.49.orig/src/org/bouncycastle/asn1/ASN1Generator.java0000644000175000017500000000042311624614575024572 0ustar ebourgebourgpackage org.bouncycastle.asn1; import java.io.OutputStream; public abstract class ASN1Generator { protected OutputStream _out; public ASN1Generator(OutputStream out) { _out = out; } public abstract OutputStream getRawOutputStream(); } bouncycastle-1.49.orig/src/org/bouncycastle/asn1/ASN1Integer.java0000644000175000017500000000050412057025023024222 0ustar ebourgebourgpackage org.bouncycastle.asn1; import java.math.BigInteger; public class ASN1Integer extends DERInteger { ASN1Integer(byte[] bytes) { super(bytes); } public ASN1Integer(BigInteger value) { super(value); } public ASN1Integer(long value) { super(value); } } bouncycastle-1.49.orig/src/org/bouncycastle/asn1/kisa/0000755000175000017500000000000012152033551022270 5ustar ebourgebourgbouncycastle-1.49.orig/src/org/bouncycastle/asn1/kisa/KISAObjectIdentifiers.java0000644000175000017500000000055211624622714027211 0ustar ebourgebourgpackage org.bouncycastle.asn1.kisa; import org.bouncycastle.asn1.ASN1ObjectIdentifier; public interface KISAObjectIdentifiers { public static final ASN1ObjectIdentifier id_seedCBC = new ASN1ObjectIdentifier("1.2.410.200004.1.4"); public static final ASN1ObjectIdentifier id_npki_app_cmsSeed_wrap = new ASN1ObjectIdentifier("1.2.410.200004.7.1.1.1"); } bouncycastle-1.49.orig/src/org/bouncycastle/asn1/ASN1OctetString.java0000644000175000017500000000676611625362525025125 0ustar ebourgebourgpackage org.bouncycastle.asn1; import java.io.ByteArrayInputStream; import java.io.IOException; import java.io.InputStream; import org.bouncycastle.util.Arrays; import org.bouncycastle.util.encoders.Hex; public abstract class ASN1OctetString extends ASN1Primitive implements ASN1OctetStringParser { byte[] string; /** * return an Octet String from a tagged object. * * @param obj the tagged object holding the object we want. * @param explicit true if the object is meant to be explicitly * tagged false otherwise. * @exception IllegalArgumentException if the tagged object cannot * be converted. */ public static ASN1OctetString getInstance( ASN1TaggedObject obj, boolean explicit) { ASN1Primitive o = obj.getObject(); if (explicit || o instanceof ASN1OctetString) { return getInstance(o); } else { return BEROctetString.fromSequence(ASN1Sequence.getInstance(o)); } } /** * return an Octet String from the given object. * * @param obj the object we want converted. * @exception IllegalArgumentException if the object cannot be converted. */ public static ASN1OctetString getInstance( Object obj) { if (obj == null || obj instanceof ASN1OctetString) { return (ASN1OctetString)obj; } else if (obj instanceof byte[]) { try { return ASN1OctetString.getInstance(ASN1Primitive.fromByteArray((byte[])obj)); } catch (IOException e) { throw new IllegalArgumentException("failed to construct OCTET STRING from byte[]: " + e.getMessage()); } } else if (obj instanceof ASN1Encodable) { ASN1Primitive primitive = ((ASN1Encodable)obj).toASN1Primitive(); if (primitive instanceof ASN1OctetString) { return (ASN1OctetString)primitive; } } throw new IllegalArgumentException("illegal object in getInstance: " + obj.getClass().getName()); } /** * @param string the octets making up the octet string. */ public ASN1OctetString( byte[] string) { if (string == null) { throw new NullPointerException("string cannot be null"); } this.string = string; } public InputStream getOctetStream() { return new ByteArrayInputStream(string); } public ASN1OctetStringParser parser() { return this; } public byte[] getOctets() { return string; } public int hashCode() { return Arrays.hashCode(this.getOctets()); } boolean asn1Equals( ASN1Primitive o) { if (!(o instanceof ASN1OctetString)) { return false; } ASN1OctetString other = (ASN1OctetString)o; return Arrays.areEqual(string, other.string); } public ASN1Primitive getLoadedObject() { return this.toASN1Primitive(); } ASN1Primitive toDERObject() { return new DEROctetString(string); } ASN1Primitive toDLObject() { return new DEROctetString(string); } abstract void encode(ASN1OutputStream out) throws IOException; public String toString() { return "#"+new String(Hex.encode(string)); } } bouncycastle-1.49.orig/src/org/bouncycastle/asn1/DERTaggedObject.java0000644000175000017500000000564211703205061025066 0ustar ebourgebourgpackage org.bouncycastle.asn1; import java.io.IOException; /** * DER TaggedObject - in ASN.1 notation this is any object preceded by * a [n] where n is some number - these are assumed to follow the construction * rules (as with sequences). */ public class DERTaggedObject extends ASN1TaggedObject { private static final byte[] ZERO_BYTES = new byte[0]; /** * @param explicit true if an explicitly tagged object. * @param tagNo the tag number for this object. * @param obj the tagged object. */ public DERTaggedObject( boolean explicit, int tagNo, ASN1Encodable obj) { super(explicit, tagNo, obj); } public DERTaggedObject(int tagNo, ASN1Encodable encodable) { super(true, tagNo, encodable); } boolean isConstructed() { if (!empty) { if (explicit) { return true; } else { ASN1Primitive primitive = obj.toASN1Primitive().toDERObject(); return primitive.isConstructed(); } } else { return true; } } int encodedLength() throws IOException { if (!empty) { ASN1Primitive primitive = obj.toASN1Primitive().toDERObject(); int length = primitive.encodedLength(); if (explicit) { return StreamUtil.calculateTagLength(tagNo) + StreamUtil.calculateBodyLength(length) + length; } else { // header length already in calculation length = length - 1; return StreamUtil.calculateTagLength(tagNo) + length; } } else { return StreamUtil.calculateTagLength(tagNo) + 1; } } void encode( ASN1OutputStream out) throws IOException { if (!empty) { ASN1Primitive primitive = obj.toASN1Primitive().toDERObject(); if (explicit) { out.writeTag(BERTags.CONSTRUCTED | BERTags.TAGGED, tagNo); out.writeLength(primitive.encodedLength()); out.writeObject(primitive); } else { // // need to mark constructed types... // int flags; if (primitive.isConstructed()) { flags = BERTags.CONSTRUCTED | BERTags.TAGGED; } else { flags = BERTags.TAGGED; } out.writeTag(flags, tagNo); out.writeImplicitObject(primitive); } } else { out.writeEncoded(BERTags.CONSTRUCTED | BERTags.TAGGED, tagNo, ZERO_BYTES); } } } bouncycastle-1.49.orig/src/org/bouncycastle/asn1/DEROctetStringParser.java0000644000175000017500000000147611624650351026177 0ustar ebourgebourgpackage org.bouncycastle.asn1; import java.io.IOException; import java.io.InputStream; public class DEROctetStringParser implements ASN1OctetStringParser { private DefiniteLengthInputStream stream; DEROctetStringParser( DefiniteLengthInputStream stream) { this.stream = stream; } public InputStream getOctetStream() { return stream; } public ASN1Primitive getLoadedObject() throws IOException { return new DEROctetString(stream.toByteArray()); } public ASN1Primitive toASN1Primitive() { try { return getLoadedObject(); } catch (IOException e) { throw new ASN1ParsingException("IOException converting stream to byte array: " + e.getMessage(), e); } } } bouncycastle-1.49.orig/src/org/bouncycastle/asn1/DERSequenceGenerator.java0000644000175000017500000000173711624622072026173 0ustar ebourgebourgpackage org.bouncycastle.asn1; import java.io.ByteArrayOutputStream; import java.io.IOException; import java.io.OutputStream; public class DERSequenceGenerator extends DERGenerator { private final ByteArrayOutputStream _bOut = new ByteArrayOutputStream(); public DERSequenceGenerator( OutputStream out) throws IOException { super(out); } public DERSequenceGenerator( OutputStream out, int tagNo, boolean isExplicit) throws IOException { super(out, tagNo, isExplicit); } public void addObject( ASN1Encodable object) throws IOException { object.toASN1Primitive().encode(new DEROutputStream(_bOut)); } public OutputStream getRawOutputStream() { return _bOut; } public void close() throws IOException { writeDEREncoded(BERTags.CONSTRUCTED | BERTags.SEQUENCE, _bOut.toByteArray()); } } bouncycastle-1.49.orig/src/org/bouncycastle/asn1/DERInteger.java0000644000175000017500000000637012062243420024140 0ustar ebourgebourgpackage org.bouncycastle.asn1; import java.io.IOException; import java.math.BigInteger; import org.bouncycastle.util.Arrays; public class DERInteger extends ASN1Primitive { byte[] bytes; /** * return an integer from the passed in object * * @exception IllegalArgumentException if the object cannot be converted. */ public static ASN1Integer getInstance( Object obj) { if (obj == null || obj instanceof ASN1Integer) { return (ASN1Integer)obj; } if (obj instanceof DERInteger) { return new ASN1Integer((((DERInteger)obj).getValue())); } if (obj instanceof byte[]) { try { return (ASN1Integer)fromByteArray((byte[])obj); } catch (Exception e) { throw new IllegalArgumentException("encoding error in getInstance: " + e.toString()); } } throw new IllegalArgumentException("illegal object in getInstance: " + obj.getClass().getName()); } /** * return an Integer from a tagged object. * * @param obj the tagged object holding the object we want * @param explicit true if the object is meant to be explicitly * tagged false otherwise. * @exception IllegalArgumentException if the tagged object cannot * be converted. */ public static ASN1Integer getInstance( ASN1TaggedObject obj, boolean explicit) { ASN1Primitive o = obj.getObject(); if (explicit || o instanceof DERInteger) { return getInstance(o); } else { return new ASN1Integer(ASN1OctetString.getInstance(obj.getObject()).getOctets()); } } public DERInteger( long value) { bytes = BigInteger.valueOf(value).toByteArray(); } public DERInteger( BigInteger value) { bytes = value.toByteArray(); } public DERInteger( byte[] bytes) { this.bytes = bytes; } public BigInteger getValue() { return new BigInteger(bytes); } /** * in some cases positive values get crammed into a space, * that's not quite big enough... */ public BigInteger getPositiveValue() { return new BigInteger(1, bytes); } boolean isConstructed() { return false; } int encodedLength() { return 1 + StreamUtil.calculateBodyLength(bytes.length) + bytes.length; } void encode( ASN1OutputStream out) throws IOException { out.writeEncoded(BERTags.INTEGER, bytes); } public int hashCode() { int value = 0; for (int i = 0; i != bytes.length; i++) { value ^= (bytes[i] & 0xff) << (i % 4); } return value; } boolean asn1Equals( ASN1Primitive o) { if (!(o instanceof DERInteger)) { return false; } DERInteger other = (DERInteger)o; return Arrays.areEqual(bytes, other.bytes); } public String toString() { return getValue().toString(); } } bouncycastle-1.49.orig/src/org/bouncycastle/asn1/BERApplicationSpecificParser.java0000644000175000017500000000153711624615370027641 0ustar ebourgebourgpackage org.bouncycastle.asn1; import java.io.IOException; public class BERApplicationSpecificParser implements ASN1ApplicationSpecificParser { private final int tag; private final ASN1StreamParser parser; BERApplicationSpecificParser(int tag, ASN1StreamParser parser) { this.tag = tag; this.parser = parser; } public ASN1Encodable readObject() throws IOException { return parser.readObject(); } public ASN1Primitive getLoadedObject() throws IOException { return new BERApplicationSpecific(tag, parser.readVector()); } public ASN1Primitive toASN1Primitive() { try { return getLoadedObject(); } catch (IOException e) { throw new ASN1ParsingException(e.getMessage(), e); } } } bouncycastle-1.49.orig/src/org/bouncycastle/asn1/DERUTF8String.java0000644000175000017500000000564412062243165024471 0ustar ebourgebourgpackage org.bouncycastle.asn1; import java.io.IOException; import org.bouncycastle.util.Arrays; import org.bouncycastle.util.Strings; /** * DER UTF8String object. */ public class DERUTF8String extends ASN1Primitive implements ASN1String { private byte[] string; /** * return an UTF8 string from the passed in object. * * @exception IllegalArgumentException * if the object cannot be converted. */ public static DERUTF8String getInstance(Object obj) { if (obj == null || obj instanceof DERUTF8String) { return (DERUTF8String)obj; } if (obj instanceof byte[]) { try { return (DERUTF8String)fromByteArray((byte[])obj); } catch (Exception e) { throw new IllegalArgumentException("encoding error in getInstance: " + e.toString()); } } throw new IllegalArgumentException("illegal object in getInstance: " + obj.getClass().getName()); } /** * return an UTF8 String from a tagged object. * * @param obj * the tagged object holding the object we want * @param explicit * true if the object is meant to be explicitly tagged false * otherwise. * @exception IllegalArgumentException * if the tagged object cannot be converted. */ public static DERUTF8String getInstance( ASN1TaggedObject obj, boolean explicit) { ASN1Primitive o = obj.getObject(); if (explicit || o instanceof DERUTF8String) { return getInstance(o); } else { return new DERUTF8String(ASN1OctetString.getInstance(o).getOctets()); } } /** * basic constructor - byte encoded string. */ DERUTF8String(byte[] string) { this.string = string; } /** * basic constructor */ public DERUTF8String(String string) { this.string = Strings.toUTF8ByteArray(string); } public String getString() { return Strings.fromUTF8ByteArray(string); } public String toString() { return getString(); } public int hashCode() { return Arrays.hashCode(string); } boolean asn1Equals(ASN1Primitive o) { if (!(o instanceof DERUTF8String)) { return false; } DERUTF8String s = (DERUTF8String)o; return Arrays.areEqual(string, s.string); } boolean isConstructed() { return false; } int encodedLength() throws IOException { return 1 + StreamUtil.calculateBodyLength(string.length) + string.length; } void encode(ASN1OutputStream out) throws IOException { out.writeEncoded(BERTags.UTF8_STRING, string); } } bouncycastle-1.49.orig/src/org/bouncycastle/asn1/teletrust/0000755000175000017500000000000012152033551023374 5ustar ebourgebourgbouncycastle-1.49.orig/src/org/bouncycastle/asn1/teletrust/TeleTrusTNamedCurves.java0000644000175000017500000004477411624652552030322 0ustar ebourgebourgpackage org.bouncycastle.asn1.teletrust; import java.math.BigInteger; import java.util.Enumeration; import java.util.Hashtable; import org.bouncycastle.asn1.ASN1ObjectIdentifier; import org.bouncycastle.asn1.x9.X9ECParameters; import org.bouncycastle.asn1.x9.X9ECParametersHolder; import org.bouncycastle.math.ec.ECCurve; import org.bouncycastle.util.Strings; import org.bouncycastle.util.encoders.Hex; /** * elliptic curves defined in "ECC Brainpool Standard Curves and Curve Generation" * http://www.ecc-brainpool.org/download/draft_pkix_additional_ecc_dp.txt */ public class TeleTrusTNamedCurves { static X9ECParametersHolder brainpoolP160r1 = new X9ECParametersHolder() { protected X9ECParameters createParameters() { ECCurve curve = new ECCurve.Fp( new BigInteger("E95E4A5F737059DC60DFC7AD95B3D8139515620F", 16), // q new BigInteger("340E7BE2A280EB74E2BE61BADA745D97E8F7C300", 16), // a new BigInteger("1E589A8595423412134FAA2DBDEC95C8D8675E58", 16)); // b return new X9ECParameters( curve, curve.decodePoint(Hex.decode("04BED5AF16EA3F6A4F62938C4631EB5AF7BDBCDBC31667CB477A1A8EC338F94741669C976316DA6321")), // G new BigInteger("E95E4A5F737059DC60DF5991D45029409E60FC09", 16), //n new BigInteger("01", 16)); // h } }; static X9ECParametersHolder brainpoolP160t1 = new X9ECParametersHolder() { protected X9ECParameters createParameters() { ECCurve curve = new ECCurve.Fp( // new BigInteger("24DBFF5DEC9B986BBFE5295A29BFBAE45E0F5D0B", 16), // Z new BigInteger("E95E4A5F737059DC60DFC7AD95B3D8139515620F", 16), // q new BigInteger("E95E4A5F737059DC60DFC7AD95B3D8139515620C", 16), // a' new BigInteger("7A556B6DAE535B7B51ED2C4D7DAA7A0B5C55F380", 16)); // b' return new X9ECParameters( curve, curve.decodePoint(Hex.decode("04B199B13B9B34EFC1397E64BAEB05ACC265FF2378ADD6718B7C7C1961F0991B842443772152C9E0AD")), // G new BigInteger("E95E4A5F737059DC60DF5991D45029409E60FC09", 16), //n new BigInteger("01", 16)); // h } }; static X9ECParametersHolder brainpoolP192r1 = new X9ECParametersHolder() { protected X9ECParameters createParameters() { ECCurve curve = new ECCurve.Fp( new BigInteger("C302F41D932A36CDA7A3463093D18DB78FCE476DE1A86297", 16), // q new BigInteger("6A91174076B1E0E19C39C031FE8685C1CAE040E5C69A28EF", 16), // a new BigInteger("469A28EF7C28CCA3DC721D044F4496BCCA7EF4146FBF25C9", 16)); // b return new X9ECParameters( curve, curve.decodePoint(Hex.decode("04C0A0647EAAB6A48753B033C56CB0F0900A2F5C4853375FD614B690866ABD5BB88B5F4828C1490002E6773FA2FA299B8F")), // G new BigInteger("C302F41D932A36CDA7A3462F9E9E916B5BE8F1029AC4ACC1", 16), //n new BigInteger("01", 16)); // h } }; static X9ECParametersHolder brainpoolP192t1 = new X9ECParametersHolder() { protected X9ECParameters createParameters() { ECCurve curve = new ECCurve.Fp( //new BigInteger("1B6F5CC8DB4DC7AF19458A9CB80DC2295E5EB9C3732104CB") //Z new BigInteger("C302F41D932A36CDA7A3463093D18DB78FCE476DE1A86297", 16), // q new BigInteger("C302F41D932A36CDA7A3463093D18DB78FCE476DE1A86294", 16), // a' new BigInteger("13D56FFAEC78681E68F9DEB43B35BEC2FB68542E27897B79", 16)); // b' return new X9ECParameters( curve, curve.decodePoint(Hex.decode("043AE9E58C82F63C30282E1FE7BBF43FA72C446AF6F4618129097E2C5667C2223A902AB5CA449D0084B7E5B3DE7CCC01C9")), // G' new BigInteger("C302F41D932A36CDA7A3462F9E9E916B5BE8F1029AC4ACC1", 16), //n new BigInteger("01", 16)); // h } }; static X9ECParametersHolder brainpoolP224r1 = new X9ECParametersHolder() { protected X9ECParameters createParameters() { ECCurve curve = new ECCurve.Fp( new BigInteger("D7C134AA264366862A18302575D1D787B09F075797DA89F57EC8C0FF", 16), // q new BigInteger("68A5E62CA9CE6C1C299803A6C1530B514E182AD8B0042A59CAD29F43", 16), // a new BigInteger("2580F63CCFE44138870713B1A92369E33E2135D266DBB372386C400B", 16)); // b return new X9ECParameters( curve, curve.decodePoint(Hex.decode("040D9029AD2C7E5CF4340823B2A87DC68C9E4CE3174C1E6EFDEE12C07D58AA56F772C0726F24C6B89E4ECDAC24354B9E99CAA3F6D3761402CD")), // G new BigInteger("D7C134AA264366862A18302575D0FB98D116BC4B6DDEBCA3A5A7939F", 16), //n new BigInteger("01", 16)); // n } }; static X9ECParametersHolder brainpoolP224t1 = new X9ECParametersHolder() { protected X9ECParameters createParameters() { ECCurve curve = new ECCurve.Fp( //new BigInteger("2DF271E14427A346910CF7A2E6CFA7B3F484E5C2CCE1C8B730E28B3F") //Z new BigInteger("D7C134AA264366862A18302575D1D787B09F075797DA89F57EC8C0FF", 16), // q new BigInteger("D7C134AA264366862A18302575D1D787B09F075797DA89F57EC8C0FC", 16), // a' new BigInteger("4B337D934104CD7BEF271BF60CED1ED20DA14C08B3BB64F18A60888D", 16)); // b' return new X9ECParameters( curve, curve.decodePoint(Hex.decode("046AB1E344CE25FF3896424E7FFE14762ECB49F8928AC0C76029B4D5800374E9F5143E568CD23F3F4D7C0D4B1E41C8CC0D1C6ABD5F1A46DB4C")), // G' new BigInteger("D7C134AA264366862A18302575D0FB98D116BC4B6DDEBCA3A5A7939F", 16), //n new BigInteger("01", 16)); // h } }; static X9ECParametersHolder brainpoolP256r1 = new X9ECParametersHolder() { protected X9ECParameters createParameters() { ECCurve curve = new ECCurve.Fp( new BigInteger("A9FB57DBA1EEA9BC3E660A909D838D726E3BF623D52620282013481D1F6E5377", 16), // q new BigInteger("7D5A0975FC2C3057EEF67530417AFFE7FB8055C126DC5C6CE94A4B44F330B5D9", 16), // a new BigInteger("26DC5C6CE94A4B44F330B5D9BBD77CBF958416295CF7E1CE6BCCDC18FF8C07B6", 16)); // b return new X9ECParameters( curve, curve.decodePoint(Hex.decode("048BD2AEB9CB7E57CB2C4B482FFC81B7AFB9DE27E1E3BD23C23A4453BD9ACE3262547EF835C3DAC4FD97F8461A14611DC9C27745132DED8E545C1D54C72F046997")), // G new BigInteger("A9FB57DBA1EEA9BC3E660A909D838D718C397AA3B561A6F7901E0E82974856A7", 16), //n new BigInteger("01", 16)); // h } }; static X9ECParametersHolder brainpoolP256t1 = new X9ECParametersHolder() { protected X9ECParameters createParameters() { ECCurve curve = new ECCurve.Fp( //new BigInteger("3E2D4BD9597B58639AE7AA669CAB9837CF5CF20A2C852D10F655668DFC150EF0") //Z new BigInteger("A9FB57DBA1EEA9BC3E660A909D838D726E3BF623D52620282013481D1F6E5377", 16), // q new BigInteger("A9FB57DBA1EEA9BC3E660A909D838D726E3BF623D52620282013481D1F6E5374", 16), // a' new BigInteger("662C61C430D84EA4FE66A7733D0B76B7BF93EBC4AF2F49256AE58101FEE92B04", 16)); // b' return new X9ECParameters( curve, curve.decodePoint(Hex.decode("04A3E8EB3CC1CFE7B7732213B23A656149AFA142C47AAFBC2B79A191562E1305F42D996C823439C56D7F7B22E14644417E69BCB6DE39D027001DABE8F35B25C9BE")), // G' new BigInteger("A9FB57DBA1EEA9BC3E660A909D838D718C397AA3B561A6F7901E0E82974856A7", 16), //n new BigInteger("01", 16)); // h } }; static X9ECParametersHolder brainpoolP320r1 = new X9ECParametersHolder() { protected X9ECParameters createParameters() { ECCurve curve = new ECCurve.Fp( new BigInteger("D35E472036BC4FB7E13C785ED201E065F98FCFA6F6F40DEF4F92B9EC7893EC28FCD412B1F1B32E27", 16), // q new BigInteger("3EE30B568FBAB0F883CCEBD46D3F3BB8A2A73513F5EB79DA66190EB085FFA9F492F375A97D860EB4", 16), // a new BigInteger("520883949DFDBC42D3AD198640688A6FE13F41349554B49ACC31DCCD884539816F5EB4AC8FB1F1A6", 16)); // b return new X9ECParameters( curve, curve.decodePoint(Hex.decode("0443BD7E9AFB53D8B85289BCC48EE5BFE6F20137D10A087EB6E7871E2A10A599C710AF8D0D39E2061114FDD05545EC1CC8AB4093247F77275E0743FFED117182EAA9C77877AAAC6AC7D35245D1692E8EE1")), // G new BigInteger("D35E472036BC4FB7E13C785ED201E065F98FCFA5B68F12A32D482EC7EE8658E98691555B44C59311", 16), //n new BigInteger("01", 16)); // h } }; static X9ECParametersHolder brainpoolP320t1 = new X9ECParametersHolder() { protected X9ECParameters createParameters() { ECCurve curve = new ECCurve.Fp( //new BigInteger("15F75CAF668077F7E85B42EB01F0A81FF56ECD6191D55CB82B7D861458A18FEFC3E5AB7496F3C7B1") //Z new BigInteger("D35E472036BC4FB7E13C785ED201E065F98FCFA6F6F40DEF4F92B9EC7893EC28FCD412B1F1B32E27", 16), // q new BigInteger("D35E472036BC4FB7E13C785ED201E065F98FCFA6F6F40DEF4F92B9EC7893EC28FCD412B1F1B32E24", 16), // a' new BigInteger("A7F561E038EB1ED560B3D147DB782013064C19F27ED27C6780AAF77FB8A547CEB5B4FEF422340353", 16)); // b' return new X9ECParameters( curve, curve.decodePoint(Hex.decode("04925BE9FB01AFC6FB4D3E7D4990010F813408AB106C4F09CB7EE07868CC136FFF3357F624A21BED5263BA3A7A27483EBF6671DBEF7ABB30EBEE084E58A0B077AD42A5A0989D1EE71B1B9BC0455FB0D2C3")), // G' new BigInteger("D35E472036BC4FB7E13C785ED201E065F98FCFA5B68F12A32D482EC7EE8658E98691555B44C59311", 16), //n new BigInteger("01", 16)); // h } }; static X9ECParametersHolder brainpoolP384r1 = new X9ECParametersHolder() { protected X9ECParameters createParameters() { ECCurve curve = new ECCurve.Fp( new BigInteger("8CB91E82A3386D280F5D6F7E50E641DF152F7109ED5456B412B1DA197FB71123ACD3A729901D1A71874700133107EC53", 16), // q new BigInteger("7BC382C63D8C150C3C72080ACE05AFA0C2BEA28E4FB22787139165EFBA91F90F8AA5814A503AD4EB04A8C7DD22CE2826", 16), // a new BigInteger("4A8C7DD22CE28268B39B55416F0447C2FB77DE107DCD2A62E880EA53EEB62D57CB4390295DBC9943AB78696FA504C11", 16)); // b return new X9ECParameters( curve, curve.decodePoint(Hex.decode("041D1C64F068CF45FFA2A63A81B7C13F6B8847A3E77EF14FE3DB7FCAFE0CBD10E8E826E03436D646AAEF87B2E247D4AF1E8ABE1D7520F9C2A45CB1EB8E95CFD55262B70B29FEEC5864E19C054FF99129280E4646217791811142820341263C5315")), // G new BigInteger("8CB91E82A3386D280F5D6F7E50E641DF152F7109ED5456B31F166E6CAC0425A7CF3AB6AF6B7FC3103B883202E9046565", 16), //n new BigInteger("01", 16)); // h } }; static X9ECParametersHolder brainpoolP384t1 = new X9ECParametersHolder() { protected X9ECParameters createParameters() { ECCurve curve = new ECCurve.Fp( //new BigInteger("41DFE8DD399331F7166A66076734A89CD0D2BCDB7D068E44E1F378F41ECBAE97D2D63DBC87BCCDDCCC5DA39E8589291C") //Z new BigInteger("8CB91E82A3386D280F5D6F7E50E641DF152F7109ED5456B412B1DA197FB71123ACD3A729901D1A71874700133107EC53", 16), // q new BigInteger("8CB91E82A3386D280F5D6F7E50E641DF152F7109ED5456B412B1DA197FB71123ACD3A729901D1A71874700133107EC50", 16), // a' new BigInteger("7F519EADA7BDA81BD826DBA647910F8C4B9346ED8CCDC64E4B1ABD11756DCE1D2074AA263B88805CED70355A33B471EE", 16)); // b' return new X9ECParameters( curve, curve.decodePoint(Hex.decode("0418DE98B02DB9A306F2AFCD7235F72A819B80AB12EBD653172476FECD462AABFFC4FF191B946A5F54D8D0AA2F418808CC25AB056962D30651A114AFD2755AD336747F93475B7A1FCA3B88F2B6A208CCFE469408584DC2B2912675BF5B9E582928")), // G' new BigInteger("8CB91E82A3386D280F5D6F7E50E641DF152F7109ED5456B31F166E6CAC0425A7CF3AB6AF6B7FC3103B883202E9046565", 16), //n new BigInteger("01", 16)); // h } }; static X9ECParametersHolder brainpoolP512r1 = new X9ECParametersHolder() { protected X9ECParameters createParameters() { ECCurve curve = new ECCurve.Fp( new BigInteger("AADD9DB8DBE9C48B3FD4E6AE33C9FC07CB308DB3B3C9D20ED6639CCA703308717D4D9B009BC66842AECDA12AE6A380E62881FF2F2D82C68528AA6056583A48F3", 16), // q new BigInteger("7830A3318B603B89E2327145AC234CC594CBDD8D3DF91610A83441CAEA9863BC2DED5D5AA8253AA10A2EF1C98B9AC8B57F1117A72BF2C7B9E7C1AC4D77FC94CA", 16), // a new BigInteger("3DF91610A83441CAEA9863BC2DED5D5AA8253AA10A2EF1C98B9AC8B57F1117A72BF2C7B9E7C1AC4D77FC94CADC083E67984050B75EBAE5DD2809BD638016F723", 16)); // b return new X9ECParameters( curve, curve.decodePoint(Hex.decode("0481AEE4BDD82ED9645A21322E9C4C6A9385ED9F70B5D916C1B43B62EEF4D0098EFF3B1F78E2D0D48D50D1687B93B97D5F7C6D5047406A5E688B352209BCB9F8227DDE385D566332ECC0EABFA9CF7822FDF209F70024A57B1AA000C55B881F8111B2DCDE494A5F485E5BCA4BD88A2763AED1CA2B2FA8F0540678CD1E0F3AD80892")), // G new BigInteger("AADD9DB8DBE9C48B3FD4E6AE33C9FC07CB308DB3B3C9D20ED6639CCA70330870553E5C414CA92619418661197FAC10471DB1D381085DDADDB58796829CA90069", 16), //n new BigInteger("01", 16)); // h } }; static X9ECParametersHolder brainpoolP512t1 = new X9ECParametersHolder() { protected X9ECParameters createParameters() { ECCurve curve = new ECCurve.Fp( //new BigInteger("12EE58E6764838B69782136F0F2D3BA06E27695716054092E60A80BEDB212B64E585D90BCE13761F85C3F1D2A64E3BE8FEA2220F01EBA5EEB0F35DBD29D922AB") //Z new BigInteger("AADD9DB8DBE9C48B3FD4E6AE33C9FC07CB308DB3B3C9D20ED6639CCA703308717D4D9B009BC66842AECDA12AE6A380E62881FF2F2D82C68528AA6056583A48F3", 16), // q new BigInteger("AADD9DB8DBE9C48B3FD4E6AE33C9FC07CB308DB3B3C9D20ED6639CCA703308717D4D9B009BC66842AECDA12AE6A380E62881FF2F2D82C68528AA6056583A48F0", 16), // a' new BigInteger("7CBBBCF9441CFAB76E1890E46884EAE321F70C0BCB4981527897504BEC3E36A62BCDFA2304976540F6450085F2DAE145C22553B465763689180EA2571867423E", 16)); // b' return new X9ECParameters( curve, curve.decodePoint(Hex.decode("04640ECE5C12788717B9C1BA06CBC2A6FEBA85842458C56DDE9DB1758D39C0313D82BA51735CDB3EA499AA77A7D6943A64F7A3F25FE26F06B51BAA2696FA9035DA5B534BD595F5AF0FA2C892376C84ACE1BB4E3019B71634C01131159CAE03CEE9D9932184BEEF216BD71DF2DADF86A627306ECFF96DBB8BACE198B61E00F8B332")), // G' new BigInteger("AADD9DB8DBE9C48B3FD4E6AE33C9FC07CB308DB3B3C9D20ED6639CCA70330870553E5C414CA92619418661197FAC10471DB1D381085DDADDB58796829CA90069", 16), //n new BigInteger("01", 16)); // h } }; static final Hashtable objIds = new Hashtable(); static final Hashtable curves = new Hashtable(); static final Hashtable names = new Hashtable(); static void defineCurve(String name, ASN1ObjectIdentifier oid, X9ECParametersHolder holder) { objIds.put(name, oid); names.put(oid, name); curves.put(oid, holder); } static { defineCurve("brainpoolp160r1", TeleTrusTObjectIdentifiers.brainpoolP160r1, brainpoolP160r1); defineCurve("brainpoolp160t1", TeleTrusTObjectIdentifiers.brainpoolP160t1, brainpoolP160t1); defineCurve("brainpoolp192r1", TeleTrusTObjectIdentifiers.brainpoolP192r1, brainpoolP192r1); defineCurve("brainpoolp192t1", TeleTrusTObjectIdentifiers.brainpoolP192t1, brainpoolP192t1); defineCurve("brainpoolp224r1", TeleTrusTObjectIdentifiers.brainpoolP224r1, brainpoolP224r1); defineCurve("brainpoolp224t1", TeleTrusTObjectIdentifiers.brainpoolP224t1, brainpoolP224t1); defineCurve("brainpoolp256r1", TeleTrusTObjectIdentifiers.brainpoolP256r1, brainpoolP256r1); defineCurve("brainpoolp256t1", TeleTrusTObjectIdentifiers.brainpoolP256t1, brainpoolP256t1); defineCurve("brainpoolp320r1", TeleTrusTObjectIdentifiers.brainpoolP320r1, brainpoolP320r1); defineCurve("brainpoolp320t1", TeleTrusTObjectIdentifiers.brainpoolP320t1, brainpoolP320t1); defineCurve("brainpoolp384r1", TeleTrusTObjectIdentifiers.brainpoolP384r1, brainpoolP384r1); defineCurve("brainpoolp384t1", TeleTrusTObjectIdentifiers.brainpoolP384t1, brainpoolP384t1); defineCurve("brainpoolp512r1", TeleTrusTObjectIdentifiers.brainpoolP512r1, brainpoolP512r1); defineCurve("brainpoolp512t1", TeleTrusTObjectIdentifiers.brainpoolP512t1, brainpoolP512t1); } public static X9ECParameters getByName( String name) { ASN1ObjectIdentifier oid = (ASN1ObjectIdentifier)objIds.get(Strings.toLowerCase(name)); if (oid != null) { return getByOID(oid); } return null; } /** * return the X9ECParameters object for the named curve represented by * the passed in object identifier. Null if the curve isn't present. * * @param oid an object identifier representing a named curve, if present. */ public static X9ECParameters getByOID( ASN1ObjectIdentifier oid) { X9ECParametersHolder holder = (X9ECParametersHolder)curves.get(oid); if (holder != null) { return holder.getParameters(); } return null; } /** * return the object identifier signified by the passed in name. Null * if there is no object identifier associated with name. * * @return the object identifier associated with name, if present. */ public static ASN1ObjectIdentifier getOID( String name) { return (ASN1ObjectIdentifier)objIds.get(Strings.toLowerCase(name)); } /** * return the named curve name represented by the given object identifier. */ public static String getName( ASN1ObjectIdentifier oid) { return (String)names.get(oid); } /** * returns an enumeration containing the name strings for curves * contained in this structure. */ public static Enumeration getNames() { return objIds.keys(); } public static ASN1ObjectIdentifier getOID(short curvesize, boolean twisted) { return getOID("brainpoolP" + curvesize + (twisted ? "t" : "r") + "1"); } } bouncycastle-1.49.orig/src/org/bouncycastle/asn1/teletrust/TeleTrusTObjectIdentifiers.java0000644000175000017500000000511011624622715031455 0ustar ebourgebourgpackage org.bouncycastle.asn1.teletrust; import org.bouncycastle.asn1.ASN1ObjectIdentifier; public interface TeleTrusTObjectIdentifiers { static final ASN1ObjectIdentifier teleTrusTAlgorithm = new ASN1ObjectIdentifier("1.3.36.3"); static final ASN1ObjectIdentifier ripemd160 = teleTrusTAlgorithm.branch("2.1"); static final ASN1ObjectIdentifier ripemd128 = teleTrusTAlgorithm.branch("2.2"); static final ASN1ObjectIdentifier ripemd256 = teleTrusTAlgorithm.branch("2.3"); static final ASN1ObjectIdentifier teleTrusTRSAsignatureAlgorithm = teleTrusTAlgorithm.branch("3.1"); static final ASN1ObjectIdentifier rsaSignatureWithripemd160 = teleTrusTRSAsignatureAlgorithm.branch("2"); static final ASN1ObjectIdentifier rsaSignatureWithripemd128 = teleTrusTRSAsignatureAlgorithm.branch("3"); static final ASN1ObjectIdentifier rsaSignatureWithripemd256 = teleTrusTRSAsignatureAlgorithm.branch("4"); static final ASN1ObjectIdentifier ecSign = teleTrusTAlgorithm.branch("3.2"); static final ASN1ObjectIdentifier ecSignWithSha1 = ecSign.branch("1"); static final ASN1ObjectIdentifier ecSignWithRipemd160 = ecSign.branch("2"); static final ASN1ObjectIdentifier ecc_brainpool = teleTrusTAlgorithm.branch("3.2.8"); static final ASN1ObjectIdentifier ellipticCurve = ecc_brainpool.branch("1"); static final ASN1ObjectIdentifier versionOne = ellipticCurve.branch("1"); static final ASN1ObjectIdentifier brainpoolP160r1 = versionOne.branch("1"); static final ASN1ObjectIdentifier brainpoolP160t1 = versionOne.branch("2"); static final ASN1ObjectIdentifier brainpoolP192r1 = versionOne.branch("3"); static final ASN1ObjectIdentifier brainpoolP192t1 = versionOne.branch("4"); static final ASN1ObjectIdentifier brainpoolP224r1 = versionOne.branch("5"); static final ASN1ObjectIdentifier brainpoolP224t1 = versionOne.branch("6"); static final ASN1ObjectIdentifier brainpoolP256r1 = versionOne.branch("7"); static final ASN1ObjectIdentifier brainpoolP256t1 = versionOne.branch("8"); static final ASN1ObjectIdentifier brainpoolP320r1 = versionOne.branch("9"); static final ASN1ObjectIdentifier brainpoolP320t1 = versionOne.branch("10"); static final ASN1ObjectIdentifier brainpoolP384r1 = versionOne.branch("11"); static final ASN1ObjectIdentifier brainpoolP384t1 = versionOne.branch("12"); static final ASN1ObjectIdentifier brainpoolP512r1 = versionOne.branch("13"); static final ASN1ObjectIdentifier brainpoolP512t1 = versionOne.branch("14"); } bouncycastle-1.49.orig/src/org/bouncycastle/asn1/teletrust/package.html0000644000175000017500000000013710262753175025671 0ustar ebourgebourg Support classes for TeleTrust related objects. bouncycastle-1.49.orig/src/org/bouncycastle/asn1/DERBoolean.java0000644000175000017500000000762512121500536024126 0ustar ebourgebourgpackage org.bouncycastle.asn1; import java.io.IOException; import org.bouncycastle.util.Arrays; public class DERBoolean extends ASN1Primitive { private static final byte[] TRUE_VALUE = new byte[] { (byte)0xff }; private static final byte[] FALSE_VALUE = new byte[] { 0 }; private byte[] value; public static final ASN1Boolean FALSE = new ASN1Boolean(false); public static final ASN1Boolean TRUE = new ASN1Boolean(true); /** * return a boolean from the passed in object. * * @exception IllegalArgumentException if the object cannot be converted. */ public static ASN1Boolean getInstance( Object obj) { if (obj == null || obj instanceof ASN1Boolean) { return (ASN1Boolean)obj; } if (obj instanceof DERBoolean) { return ((DERBoolean)obj).isTrue() ? DERBoolean.TRUE : DERBoolean.FALSE; } throw new IllegalArgumentException("illegal object in getInstance: " + obj.getClass().getName()); } /** * return a ASN1Boolean from the passed in boolean. */ public static ASN1Boolean getInstance( boolean value) { return (value ? TRUE : FALSE); } /** * return a ASN1Boolean from the passed in boolean. */ public static ASN1Boolean getInstance( int value) { return (value != 0 ? TRUE : FALSE); } /** * return a Boolean from a tagged object. * * @param obj the tagged object holding the object we want * @param explicit true if the object is meant to be explicitly * tagged false otherwise. * @exception IllegalArgumentException if the tagged object cannot * be converted. */ public static ASN1Boolean getInstance( ASN1TaggedObject obj, boolean explicit) { ASN1Primitive o = obj.getObject(); if (explicit || o instanceof DERBoolean) { return getInstance(o); } else { return ASN1Boolean.fromOctetString(((ASN1OctetString)o).getOctets()); } } DERBoolean( byte[] value) { if (value.length != 1) { throw new IllegalArgumentException("byte value should have 1 byte in it"); } if (value[0] == 0) { this.value = FALSE_VALUE; } else if (value[0] == 0xff) { this.value = TRUE_VALUE; } else { this.value = Arrays.clone(value); } } /** * @deprecated use getInstance(boolean) method. * @param value */ public DERBoolean( boolean value) { this.value = (value) ? TRUE_VALUE : FALSE_VALUE; } public boolean isTrue() { return (value[0] != 0); } boolean isConstructed() { return false; } int encodedLength() { return 3; } void encode( ASN1OutputStream out) throws IOException { out.writeEncoded(BERTags.BOOLEAN, value); } protected boolean asn1Equals( ASN1Primitive o) { if ((o == null) || !(o instanceof DERBoolean)) { return false; } return (value[0] == ((DERBoolean)o).value[0]); } public int hashCode() { return value[0]; } public String toString() { return (value[0] != 0) ? "TRUE" : "FALSE"; } static ASN1Boolean fromOctetString(byte[] value) { if (value.length != 1) { throw new IllegalArgumentException("byte value should have 1 byte in it"); } if (value[0] == 0) { return FALSE; } else if (value[0] == 0xff) { return TRUE; } else { return new ASN1Boolean(value); } } } bouncycastle-1.49.orig/src/org/bouncycastle/asn1/ASN1ObjectIdentifier.java0000644000175000017500000000220212132366547026050 0ustar ebourgebourgpackage org.bouncycastle.asn1; public class ASN1ObjectIdentifier extends DERObjectIdentifier { public ASN1ObjectIdentifier(String identifier) { super(identifier); } ASN1ObjectIdentifier(byte[] bytes) { super(bytes); } ASN1ObjectIdentifier(ASN1ObjectIdentifier oid, String branch) { super(oid, branch); } /** * Return an OID that creates a branch under the current one. * * @param branchID node numbers for the new branch. * @return the OID for the new created branch. */ public ASN1ObjectIdentifier branch(String branchID) { return new ASN1ObjectIdentifier(this, branchID); } /** * Return true if this oid is an extension of the passed in branch, stem. * @param stem the arc or branch that is a possible parent. * @return true if the branch is on the passed in stem, false otherwise. */ public boolean on(ASN1ObjectIdentifier stem) { String id = getId(), stemId = stem.getId(); return id.length() > stemId.length() && id.charAt(stemId.length()) == '.' && id.startsWith(stemId); } } bouncycastle-1.49.orig/src/org/bouncycastle/asn1/DLSet.java0000644000175000017500000000422211703177363023172 0ustar ebourgebourgpackage org.bouncycastle.asn1; import java.io.IOException; import java.util.Enumeration; /** * A DER encoded set object */ public class DLSet extends ASN1Set { private int bodyLength = -1; /** * create an empty set */ public DLSet() { } /** * @param obj - a single object that makes up the set. */ public DLSet( ASN1Encodable obj) { super(obj); } /** * @param v - a vector of objects making up the set. */ public DLSet( ASN1EncodableVector v) { super(v, false); } /** * create a set from an array of objects. */ public DLSet( ASN1Encodable[] a) { super(a, false); } private int getBodyLength() throws IOException { if (bodyLength < 0) { int length = 0; for (Enumeration e = this.getObjects(); e.hasMoreElements();) { Object obj = e.nextElement(); length += ((ASN1Encodable)obj).toASN1Primitive().toDLObject().encodedLength(); } bodyLength = length; } return bodyLength; } int encodedLength() throws IOException { int length = getBodyLength(); return 1 + StreamUtil.calculateBodyLength(length) + length; } /* * A note on the implementation: *

    * As DL requires the constructed, definite-length model to * be used for structured types, this varies slightly from the * ASN.1 descriptions given. Rather than just outputting SET, * we also have to specify CONSTRUCTED, and the objects length. */ void encode( ASN1OutputStream out) throws IOException { ASN1OutputStream dOut = out.getDLSubStream(); int length = getBodyLength(); out.write(BERTags.SET | BERTags.CONSTRUCTED); out.writeLength(length); for (Enumeration e = this.getObjects(); e.hasMoreElements();) { Object obj = e.nextElement(); dOut.writeObject((ASN1Encodable)obj); } } } bouncycastle-1.49.orig/src/org/bouncycastle/asn1/x500/0000755000175000017500000000000012152033551022035 5ustar ebourgebourgbouncycastle-1.49.orig/src/org/bouncycastle/asn1/x500/X500Name.java0000644000175000017500000001704611730273721024153 0ustar ebourgebourgpackage org.bouncycastle.asn1.x500; import java.util.Enumeration; import org.bouncycastle.asn1.ASN1Choice; import org.bouncycastle.asn1.ASN1Encodable; import org.bouncycastle.asn1.ASN1Object; import org.bouncycastle.asn1.ASN1ObjectIdentifier; import org.bouncycastle.asn1.ASN1Primitive; import org.bouncycastle.asn1.ASN1Sequence; import org.bouncycastle.asn1.ASN1TaggedObject; import org.bouncycastle.asn1.DERSequence; import org.bouncycastle.asn1.x500.style.BCStyle; /** *

     *     Name ::= CHOICE {
     *                       RDNSequence }
     *
     *     RDNSequence ::= SEQUENCE OF RelativeDistinguishedName
     *
     *     RelativeDistinguishedName ::= SET SIZE (1..MAX) OF AttributeTypeAndValue
     *
     *     AttributeTypeAndValue ::= SEQUENCE {
     *                                   type  OBJECT IDENTIFIER,
     *                                   value ANY }
     * 
    */ public class X500Name extends ASN1Object implements ASN1Choice { private static X500NameStyle defaultStyle = BCStyle.INSTANCE; private boolean isHashCodeCalculated; private int hashCodeValue; private X500NameStyle style; private RDN[] rdns; public X500Name(X500NameStyle style, X500Name name) { this.rdns = name.rdns; this.style = style; } /** * Return a X500Name based on the passed in tagged object. * * @param obj tag object holding name. * @param explicit true if explicitly tagged false otherwise. * @return the X500Name */ public static X500Name getInstance( ASN1TaggedObject obj, boolean explicit) { // must be true as choice item return getInstance(ASN1Sequence.getInstance(obj, true)); } public static X500Name getInstance( Object obj) { if (obj instanceof X500Name) { return (X500Name)obj; } else if (obj != null) { return new X500Name(ASN1Sequence.getInstance(obj)); } return null; } public static X500Name getInstance( X500NameStyle style, Object obj) { if (obj instanceof X500Name) { return getInstance(style, ((X500Name)obj).toASN1Primitive()); } else if (obj != null) { return new X500Name(style, ASN1Sequence.getInstance(obj)); } return null; } /** * Constructor from ASN1Sequence * * the principal will be a list of constructed sets, each containing an (OID, String) pair. */ private X500Name( ASN1Sequence seq) { this(defaultStyle, seq); } private X500Name( X500NameStyle style, ASN1Sequence seq) { this.style = style; this.rdns = new RDN[seq.size()]; int index = 0; for (Enumeration e = seq.getObjects(); e.hasMoreElements();) { rdns[index++] = RDN.getInstance(e.nextElement()); } } public X500Name( RDN[] rDNs) { this(defaultStyle, rDNs); } public X500Name( X500NameStyle style, RDN[] rDNs) { this.rdns = rDNs; this.style = style; } public X500Name( String dirName) { this(defaultStyle, dirName); } public X500Name( X500NameStyle style, String dirName) { this(style.fromString(dirName)); this.style = style; } /** * return an array of RDNs in structure order. * * @return an array of RDN objects. */ public RDN[] getRDNs() { RDN[] tmp = new RDN[this.rdns.length]; System.arraycopy(rdns, 0, tmp, 0, tmp.length); return tmp; } /** * return an array of OIDs contained in the attribute type of each RDN in structure order. * * @return an array, possibly zero length, of ASN1ObjectIdentifiers objects. */ public ASN1ObjectIdentifier[] getAttributeTypes() { int count = 0; for (int i = 0; i != rdns.length; i++) { RDN rdn = rdns[i]; count += rdn.size(); } ASN1ObjectIdentifier[] res = new ASN1ObjectIdentifier[count]; count = 0; for (int i = 0; i != rdns.length; i++) { RDN rdn = rdns[i]; if (rdn.isMultiValued()) { AttributeTypeAndValue[] attr = rdn.getTypesAndValues(); for (int j = 0; j != attr.length; j++) { res[count++] = attr[j].getType(); } } else if (rdn.size() != 0) { res[count++] = rdn.getFirst().getType(); } } return res; } /** * return an array of RDNs containing the attribute type given by OID in structure order. * * @param attributeType the type OID we are looking for. * @return an array, possibly zero length, of RDN objects. */ public RDN[] getRDNs(ASN1ObjectIdentifier attributeType) { RDN[] res = new RDN[rdns.length]; int count = 0; for (int i = 0; i != rdns.length; i++) { RDN rdn = rdns[i]; if (rdn.isMultiValued()) { AttributeTypeAndValue[] attr = rdn.getTypesAndValues(); for (int j = 0; j != attr.length; j++) { if (attr[j].getType().equals(attributeType)) { res[count++] = rdn; break; } } } else { if (rdn.getFirst().getType().equals(attributeType)) { res[count++] = rdn; } } } RDN[] tmp = new RDN[count]; System.arraycopy(res, 0, tmp, 0, tmp.length); return tmp; } public ASN1Primitive toASN1Primitive() { return new DERSequence(rdns); } public int hashCode() { if (isHashCodeCalculated) { return hashCodeValue; } isHashCodeCalculated = true; hashCodeValue = style.calculateHashCode(this); return hashCodeValue; } /** * test for equality - note: case is ignored. */ public boolean equals(Object obj) { if (obj == this) { return true; } if (!(obj instanceof X500Name || obj instanceof ASN1Sequence)) { return false; } ASN1Primitive derO = ((ASN1Encodable)obj).toASN1Primitive(); if (this.toASN1Primitive().equals(derO)) { return true; } try { return style.areEqual(this, new X500Name(ASN1Sequence.getInstance(((ASN1Encodable)obj).toASN1Primitive()))); } catch (Exception e) { return false; } } public String toString() { return style.toString(this); } /** * Set the default style for X500Name construction. * * @param style an X500NameStyle */ public static void setDefaultStyle(X500NameStyle style) { if (style == null) { throw new NullPointerException("cannot set style to null"); } defaultStyle = style; } /** * Return the current default style. * * @return default style for X500Name construction. */ public static X500NameStyle getDefaultStyle() { return defaultStyle; } } bouncycastle-1.49.orig/src/org/bouncycastle/asn1/x500/X500NameBuilder.java0000644000175000017500000000405212075153656025462 0ustar ebourgebourgpackage org.bouncycastle.asn1.x500; import java.util.Vector; import org.bouncycastle.asn1.ASN1Encodable; import org.bouncycastle.asn1.ASN1ObjectIdentifier; import org.bouncycastle.asn1.x500.style.BCStyle; public class X500NameBuilder { private X500NameStyle template; private Vector rdns = new Vector(); public X500NameBuilder() { this(BCStyle.INSTANCE); } public X500NameBuilder(X500NameStyle template) { this.template = template; } public X500NameBuilder addRDN(ASN1ObjectIdentifier oid, String value) { this.addRDN(oid, template.stringToValue(oid, value)); return this; } public X500NameBuilder addRDN(ASN1ObjectIdentifier oid, ASN1Encodable value) { rdns.addElement(new RDN(oid, value)); return this; } public X500NameBuilder addRDN(AttributeTypeAndValue attrTAndV) { rdns.addElement(new RDN(attrTAndV)); return this; } public X500NameBuilder addMultiValuedRDN(ASN1ObjectIdentifier[] oids, String[] values) { ASN1Encodable[] vals = new ASN1Encodable[values.length]; for (int i = 0; i != vals.length; i++) { vals[i] = template.stringToValue(oids[i], values[i]); } return addMultiValuedRDN(oids, vals); } public X500NameBuilder addMultiValuedRDN(ASN1ObjectIdentifier[] oids, ASN1Encodable[] values) { AttributeTypeAndValue[] avs = new AttributeTypeAndValue[oids.length]; for (int i = 0; i != oids.length; i++) { avs[i] = new AttributeTypeAndValue(oids[i], values[i]); } return addMultiValuedRDN(avs); } public X500NameBuilder addMultiValuedRDN(AttributeTypeAndValue[] attrTAndVs) { rdns.addElement(new RDN(attrTAndVs)); return this; } public X500Name build() { RDN[] vals = new RDN[rdns.size()]; for (int i = 0; i != vals.length; i++) { vals[i] = (RDN)rdns.elementAt(i); } return new X500Name(template, vals); } } bouncycastle-1.49.orig/src/org/bouncycastle/asn1/x500/RDN.java0000644000175000017500000000523011730520413023322 0ustar ebourgebourgpackage org.bouncycastle.asn1.x500; import org.bouncycastle.asn1.ASN1Encodable; import org.bouncycastle.asn1.ASN1EncodableVector; import org.bouncycastle.asn1.ASN1Object; import org.bouncycastle.asn1.ASN1ObjectIdentifier; import org.bouncycastle.asn1.ASN1Primitive; import org.bouncycastle.asn1.ASN1Set; import org.bouncycastle.asn1.DERSequence; import org.bouncycastle.asn1.DERSet; public class RDN extends ASN1Object { private ASN1Set values; private RDN(ASN1Set values) { this.values = values; } public static RDN getInstance(Object obj) { if (obj instanceof RDN) { return (RDN)obj; } else if (obj != null) { return new RDN(ASN1Set.getInstance(obj)); } return null; } /** * Create a single valued RDN. * * @param oid RDN type. * @param value RDN value. */ public RDN(ASN1ObjectIdentifier oid, ASN1Encodable value) { ASN1EncodableVector v = new ASN1EncodableVector(); v.add(oid); v.add(value); this.values = new DERSet(new DERSequence(v)); } public RDN(AttributeTypeAndValue attrTAndV) { this.values = new DERSet(attrTAndV); } /** * Create a multi-valued RDN. * * @param aAndVs attribute type/value pairs making up the RDN */ public RDN(AttributeTypeAndValue[] aAndVs) { this.values = new DERSet(aAndVs); } public boolean isMultiValued() { return this.values.size() > 1; } /** * Return the number of AttributeTypeAndValue objects in this RDN, * * @return size of RDN, greater than 1 if multi-valued. */ public int size() { return this.values.size(); } public AttributeTypeAndValue getFirst() { if (this.values.size() == 0) { return null; } return AttributeTypeAndValue.getInstance(this.values.getObjectAt(0)); } public AttributeTypeAndValue[] getTypesAndValues() { AttributeTypeAndValue[] tmp = new AttributeTypeAndValue[values.size()]; for (int i = 0; i != tmp.length; i++) { tmp[i] = AttributeTypeAndValue.getInstance(values.getObjectAt(i)); } return tmp; } /** *
         * RelativeDistinguishedName ::=
         *                     SET OF AttributeTypeAndValue
    
         * AttributeTypeAndValue ::= SEQUENCE {
         *        type     AttributeType,
         *        value    AttributeValue }
         * 
    * @return this object as an ASN1Primitive type */ public ASN1Primitive toASN1Primitive() { return values; } } bouncycastle-1.49.orig/src/org/bouncycastle/asn1/x500/DirectoryString.java0000644000175000017500000000610011725272334026041 0ustar ebourgebourgpackage org.bouncycastle.asn1.x500; import org.bouncycastle.asn1.ASN1Choice; import org.bouncycastle.asn1.ASN1Encodable; import org.bouncycastle.asn1.ASN1Object; import org.bouncycastle.asn1.ASN1Primitive; import org.bouncycastle.asn1.ASN1String; import org.bouncycastle.asn1.ASN1TaggedObject; import org.bouncycastle.asn1.DERBMPString; import org.bouncycastle.asn1.DERPrintableString; import org.bouncycastle.asn1.DERT61String; import org.bouncycastle.asn1.DERUTF8String; import org.bouncycastle.asn1.DERUniversalString; public class DirectoryString extends ASN1Object implements ASN1Choice, ASN1String { private ASN1String string; public static DirectoryString getInstance(Object o) { if (o == null || o instanceof DirectoryString) { return (DirectoryString)o; } if (o instanceof DERT61String) { return new DirectoryString((DERT61String)o); } if (o instanceof DERPrintableString) { return new DirectoryString((DERPrintableString)o); } if (o instanceof DERUniversalString) { return new DirectoryString((DERUniversalString)o); } if (o instanceof DERUTF8String) { return new DirectoryString((DERUTF8String)o); } if (o instanceof DERBMPString) { return new DirectoryString((DERBMPString)o); } throw new IllegalArgumentException("illegal object in getInstance: " + o.getClass().getName()); } public static DirectoryString getInstance(ASN1TaggedObject o, boolean explicit) { if (!explicit) { throw new IllegalArgumentException("choice item must be explicitly tagged"); } return getInstance(o.getObject()); } private DirectoryString( DERT61String string) { this.string = string; } private DirectoryString( DERPrintableString string) { this.string = string; } private DirectoryString( DERUniversalString string) { this.string = string; } private DirectoryString( DERUTF8String string) { this.string = string; } private DirectoryString( DERBMPString string) { this.string = string; } public DirectoryString(String string) { this.string = new DERUTF8String(string); } public String getString() { return string.getString(); } public String toString() { return string.getString(); } /** *
         *  DirectoryString ::= CHOICE {
         *    teletexString               TeletexString (SIZE (1..MAX)),
         *    printableString             PrintableString (SIZE (1..MAX)),
         *    universalString             UniversalString (SIZE (1..MAX)),
         *    utf8String                  UTF8String (SIZE (1..MAX)),
         *    bmpString                   BMPString (SIZE (1..MAX))  }
         * 
    */ public ASN1Primitive toASN1Primitive() { return ((ASN1Encodable)string).toASN1Primitive(); } } bouncycastle-1.49.orig/src/org/bouncycastle/asn1/x500/X500NameStyle.java0000644000175000017500000000466612151455117025177 0ustar ebourgebourgpackage org.bouncycastle.asn1.x500; import org.bouncycastle.asn1.ASN1Encodable; import org.bouncycastle.asn1.ASN1ObjectIdentifier; /** * It turns out that the number of standard ways the fields in a DN should be * encoded into their ASN.1 counterparts is rapidly approaching the * number of machines on the internet. By default the X500Name class * will produce UTF8Strings in line with the current recommendations (RFC 3280). *

    */ public interface X500NameStyle { /** * Convert the passed in String value into the appropriate ASN.1 * encoded object. * * @param oid the OID associated with the value in the DN. * @param value the value of the particular DN component. * @return the ASN.1 equivalent for the value. */ ASN1Encodable stringToValue(ASN1ObjectIdentifier oid, String value); /** * Return the OID associated with the passed in name. * * @param attrName the string to match. * @return an OID */ ASN1ObjectIdentifier attrNameToOID(String attrName); /** * Return an array of RDN generated from the passed in String. * @param dirName the String representation. * @return an array of corresponding RDNs. */ RDN[] fromString(String dirName); /** * Return true if the two names are equal. * * @param name1 first name for comparison. * @param name2 second name for comparison. * @return true if name1 = name 2, false otherwise. */ boolean areEqual(X500Name name1, X500Name name2); /** * Calculate a hashCode for the passed in name. * * @param name the name the hashCode is required for. * @return the calculated hashCode. */ int calculateHashCode(X500Name name); /** * Convert the passed in X500Name to a String. * @param name the name to convert. * @return a String representation. */ String toString(X500Name name); /** * Return the display name for toString() associated with the OID. * * @param oid the OID of interest. * @return the name displayed in toString(), null if no mapping provided. */ String oidToDisplayName(ASN1ObjectIdentifier oid); /** * Return the acceptable names in a String DN that map to OID. * * @param oid the OID of interest. * @return an array of String aliases for the OID, zero length if there are none. */ String[] oidToAttrNames(ASN1ObjectIdentifier oid); } bouncycastle-1.49.orig/src/org/bouncycastle/asn1/x500/AttributeTypeAndValue.java0000644000175000017500000000341011624622715027134 0ustar ebourgebourgpackage org.bouncycastle.asn1.x500; import org.bouncycastle.asn1.ASN1Encodable; import org.bouncycastle.asn1.ASN1EncodableVector; import org.bouncycastle.asn1.ASN1Object; import org.bouncycastle.asn1.ASN1ObjectIdentifier; import org.bouncycastle.asn1.ASN1Primitive; import org.bouncycastle.asn1.ASN1Sequence; import org.bouncycastle.asn1.DERSequence; public class AttributeTypeAndValue extends ASN1Object { private ASN1ObjectIdentifier type; private ASN1Encodable value; private AttributeTypeAndValue(ASN1Sequence seq) { type = (ASN1ObjectIdentifier)seq.getObjectAt(0); value = (ASN1Encodable)seq.getObjectAt(1); } public static AttributeTypeAndValue getInstance(Object o) { if (o instanceof AttributeTypeAndValue) { return (AttributeTypeAndValue)o; } else if (o != null) { return new AttributeTypeAndValue(ASN1Sequence.getInstance(o)); } throw new IllegalArgumentException("null value in getInstance()"); } public AttributeTypeAndValue( ASN1ObjectIdentifier type, ASN1Encodable value) { this.type = type; this.value = value; } public ASN1ObjectIdentifier getType() { return type; } public ASN1Encodable getValue() { return value; } /** *

         * AttributeTypeAndValue ::= SEQUENCE {
         *           type         OBJECT IDENTIFIER,
         *           value        ANY DEFINED BY type }
         * 
    * @return a basic ASN.1 object representation. */ public ASN1Primitive toASN1Primitive() { ASN1EncodableVector v = new ASN1EncodableVector(); v.add(type); v.add(value); return new DERSequence(v); } } bouncycastle-1.49.orig/src/org/bouncycastle/asn1/x500/style/0000755000175000017500000000000012152033551023175 5ustar ebourgebourgbouncycastle-1.49.orig/src/org/bouncycastle/asn1/x500/style/RFC4519Style.java0000644000175000017500000003517612151455201026031 0ustar ebourgebourgpackage org.bouncycastle.asn1.x500.style; import java.io.IOException; import java.util.Hashtable; import org.bouncycastle.asn1.ASN1Encodable; import org.bouncycastle.asn1.ASN1ObjectIdentifier; import org.bouncycastle.asn1.DERIA5String; import org.bouncycastle.asn1.DERPrintableString; import org.bouncycastle.asn1.DERUTF8String; import org.bouncycastle.asn1.x500.AttributeTypeAndValue; import org.bouncycastle.asn1.x500.RDN; import org.bouncycastle.asn1.x500.X500Name; import org.bouncycastle.asn1.x500.X500NameStyle; public class RFC4519Style implements X500NameStyle { public static final X500NameStyle INSTANCE = new RFC4519Style(); public static final ASN1ObjectIdentifier businessCategory = new ASN1ObjectIdentifier("2.5.4.15"); public static final ASN1ObjectIdentifier c = new ASN1ObjectIdentifier("2.5.4.6"); public static final ASN1ObjectIdentifier cn = new ASN1ObjectIdentifier("2.5.4.3"); public static final ASN1ObjectIdentifier dc = new ASN1ObjectIdentifier("0.9.2342.19200300.100.1.25"); public static final ASN1ObjectIdentifier description = new ASN1ObjectIdentifier("2.5.4.13"); public static final ASN1ObjectIdentifier destinationIndicator = new ASN1ObjectIdentifier("2.5.4.27"); public static final ASN1ObjectIdentifier distinguishedName = new ASN1ObjectIdentifier("2.5.4.49"); public static final ASN1ObjectIdentifier dnQualifier = new ASN1ObjectIdentifier("2.5.4.46"); public static final ASN1ObjectIdentifier enhancedSearchGuide = new ASN1ObjectIdentifier("2.5.4.47"); public static final ASN1ObjectIdentifier facsimileTelephoneNumber = new ASN1ObjectIdentifier("2.5.4.23"); public static final ASN1ObjectIdentifier generationQualifier = new ASN1ObjectIdentifier("2.5.4.44"); public static final ASN1ObjectIdentifier givenName = new ASN1ObjectIdentifier("2.5.4.42"); public static final ASN1ObjectIdentifier houseIdentifier = new ASN1ObjectIdentifier("2.5.4.51"); public static final ASN1ObjectIdentifier initials = new ASN1ObjectIdentifier("2.5.4.43"); public static final ASN1ObjectIdentifier internationalISDNNumber = new ASN1ObjectIdentifier("2.5.4.25"); public static final ASN1ObjectIdentifier l = new ASN1ObjectIdentifier("2.5.4.7"); public static final ASN1ObjectIdentifier member = new ASN1ObjectIdentifier("2.5.4.31"); public static final ASN1ObjectIdentifier name = new ASN1ObjectIdentifier("2.5.4.41"); public static final ASN1ObjectIdentifier o = new ASN1ObjectIdentifier("2.5.4.10"); public static final ASN1ObjectIdentifier ou = new ASN1ObjectIdentifier("2.5.4.11"); public static final ASN1ObjectIdentifier owner = new ASN1ObjectIdentifier("2.5.4.32"); public static final ASN1ObjectIdentifier physicalDeliveryOfficeName = new ASN1ObjectIdentifier("2.5.4.19"); public static final ASN1ObjectIdentifier postalAddress = new ASN1ObjectIdentifier("2.5.4.16"); public static final ASN1ObjectIdentifier postalCode = new ASN1ObjectIdentifier("2.5.4.17"); public static final ASN1ObjectIdentifier postOfficeBox = new ASN1ObjectIdentifier("2.5.4.18"); public static final ASN1ObjectIdentifier preferredDeliveryMethod = new ASN1ObjectIdentifier("2.5.4.28"); public static final ASN1ObjectIdentifier registeredAddress = new ASN1ObjectIdentifier("2.5.4.26"); public static final ASN1ObjectIdentifier roleOccupant = new ASN1ObjectIdentifier("2.5.4.33"); public static final ASN1ObjectIdentifier searchGuide = new ASN1ObjectIdentifier("2.5.4.14"); public static final ASN1ObjectIdentifier seeAlso = new ASN1ObjectIdentifier("2.5.4.34"); public static final ASN1ObjectIdentifier serialNumber = new ASN1ObjectIdentifier("2.5.4.5"); public static final ASN1ObjectIdentifier sn = new ASN1ObjectIdentifier("2.5.4.4"); public static final ASN1ObjectIdentifier st = new ASN1ObjectIdentifier("2.5.4.8"); public static final ASN1ObjectIdentifier street = new ASN1ObjectIdentifier("2.5.4.9"); public static final ASN1ObjectIdentifier telephoneNumber = new ASN1ObjectIdentifier("2.5.4.20"); public static final ASN1ObjectIdentifier teletexTerminalIdentifier = new ASN1ObjectIdentifier("2.5.4.22"); public static final ASN1ObjectIdentifier telexNumber = new ASN1ObjectIdentifier("2.5.4.21"); public static final ASN1ObjectIdentifier title = new ASN1ObjectIdentifier("2.5.4.12"); public static final ASN1ObjectIdentifier uid = new ASN1ObjectIdentifier("0.9.2342.19200300.100.1.1"); public static final ASN1ObjectIdentifier uniqueMember = new ASN1ObjectIdentifier("2.5.4.50"); public static final ASN1ObjectIdentifier userPassword = new ASN1ObjectIdentifier("2.5.4.35"); public static final ASN1ObjectIdentifier x121Address = new ASN1ObjectIdentifier("2.5.4.24"); public static final ASN1ObjectIdentifier x500UniqueIdentifier = new ASN1ObjectIdentifier("2.5.4.45"); /** * default look up table translating OID values into their common symbols following * the convention in RFC 2253 with a few extras */ private static final Hashtable DefaultSymbols = new Hashtable(); /** * look up table translating common symbols into their OIDS. */ private static final Hashtable DefaultLookUp = new Hashtable(); static { DefaultSymbols.put(businessCategory, "businessCategory"); DefaultSymbols.put(c, "c"); DefaultSymbols.put(cn, "cn"); DefaultSymbols.put(dc, "dc"); DefaultSymbols.put(description, "description"); DefaultSymbols.put(destinationIndicator, "destinationIndicator"); DefaultSymbols.put(distinguishedName, "distinguishedName"); DefaultSymbols.put(dnQualifier, "dnQualifier"); DefaultSymbols.put(enhancedSearchGuide, "enhancedSearchGuide"); DefaultSymbols.put(facsimileTelephoneNumber, "facsimileTelephoneNumber"); DefaultSymbols.put(generationQualifier, "generationQualifier"); DefaultSymbols.put(givenName, "givenName"); DefaultSymbols.put(houseIdentifier, "houseIdentifier"); DefaultSymbols.put(initials, "initials"); DefaultSymbols.put(internationalISDNNumber, "internationalISDNNumber"); DefaultSymbols.put(l, "l"); DefaultSymbols.put(member, "member"); DefaultSymbols.put(name, "name"); DefaultSymbols.put(o, "o"); DefaultSymbols.put(ou, "ou"); DefaultSymbols.put(owner, "owner"); DefaultSymbols.put(physicalDeliveryOfficeName, "physicalDeliveryOfficeName"); DefaultSymbols.put(postalAddress, "postalAddress"); DefaultSymbols.put(postalCode, "postalCode"); DefaultSymbols.put(postOfficeBox, "postOfficeBox"); DefaultSymbols.put(preferredDeliveryMethod, "preferredDeliveryMethod"); DefaultSymbols.put(registeredAddress, "registeredAddress"); DefaultSymbols.put(roleOccupant, "roleOccupant"); DefaultSymbols.put(searchGuide, "searchGuide"); DefaultSymbols.put(seeAlso, "seeAlso"); DefaultSymbols.put(serialNumber, "serialNumber"); DefaultSymbols.put(sn, "sn"); DefaultSymbols.put(st, "st"); DefaultSymbols.put(street, "street"); DefaultSymbols.put(telephoneNumber, "telephoneNumber"); DefaultSymbols.put(teletexTerminalIdentifier, "teletexTerminalIdentifier"); DefaultSymbols.put(telexNumber, "telexNumber"); DefaultSymbols.put(title, "title"); DefaultSymbols.put(uid, "uid"); DefaultSymbols.put(uniqueMember, "uniqueMember"); DefaultSymbols.put(userPassword, "userPassword"); DefaultSymbols.put(x121Address, "x121Address"); DefaultSymbols.put(x500UniqueIdentifier, "x500UniqueIdentifier"); DefaultLookUp.put("businesscategory", businessCategory); DefaultLookUp.put("c", c); DefaultLookUp.put("cn", cn); DefaultLookUp.put("dc", dc); DefaultLookUp.put("description", description); DefaultLookUp.put("destinationindicator", destinationIndicator); DefaultLookUp.put("distinguishedname", distinguishedName); DefaultLookUp.put("dnqualifier", dnQualifier); DefaultLookUp.put("enhancedsearchguide", enhancedSearchGuide); DefaultLookUp.put("facsimiletelephonenumber", facsimileTelephoneNumber); DefaultLookUp.put("generationqualifier", generationQualifier); DefaultLookUp.put("givenname", givenName); DefaultLookUp.put("houseidentifier", houseIdentifier); DefaultLookUp.put("initials", initials); DefaultLookUp.put("internationalisdnnumber", internationalISDNNumber); DefaultLookUp.put("l", l); DefaultLookUp.put("member", member); DefaultLookUp.put("name", name); DefaultLookUp.put("o", o); DefaultLookUp.put("ou", ou); DefaultLookUp.put("owner", owner); DefaultLookUp.put("physicaldeliveryofficename", physicalDeliveryOfficeName); DefaultLookUp.put("postaladdress", postalAddress); DefaultLookUp.put("postalcode", postalCode); DefaultLookUp.put("postofficebox", postOfficeBox); DefaultLookUp.put("preferreddeliverymethod", preferredDeliveryMethod); DefaultLookUp.put("registeredaddress", registeredAddress); DefaultLookUp.put("roleoccupant", roleOccupant); DefaultLookUp.put("searchguide", searchGuide); DefaultLookUp.put("seealso", seeAlso); DefaultLookUp.put("serialnumber", serialNumber); DefaultLookUp.put("sn", sn); DefaultLookUp.put("st", st); DefaultLookUp.put("street", street); DefaultLookUp.put("telephonenumber", telephoneNumber); DefaultLookUp.put("teletexterminalidentifier", teletexTerminalIdentifier); DefaultLookUp.put("telexnumber", telexNumber); DefaultLookUp.put("title", title); DefaultLookUp.put("uid", uid); DefaultLookUp.put("uniquemember", uniqueMember); DefaultLookUp.put("userpassword", userPassword); DefaultLookUp.put("x121address", x121Address); DefaultLookUp.put("x500uniqueidentifier", x500UniqueIdentifier); // TODO: need to add correct matching for equality comparisons. } protected RFC4519Style() { } public ASN1Encodable stringToValue(ASN1ObjectIdentifier oid, String value) { if (value.length() != 0 && value.charAt(0) == '#') { try { return IETFUtils.valueFromHexString(value, 1); } catch (IOException e) { throw new RuntimeException("can't recode value for oid " + oid.getId()); } } else { if (value.length() != 0 && value.charAt(0) == '\\') { value = value.substring(1); } if (oid.equals(dc)) { return new DERIA5String(value); } else if (oid.equals(c) || oid.equals(serialNumber) || oid.equals(dnQualifier) || oid.equals(telephoneNumber)) { return new DERPrintableString(value); } } return new DERUTF8String(value); } public String oidToDisplayName(ASN1ObjectIdentifier oid) { return (String)DefaultSymbols.get(oid); } public String[] oidToAttrNames(ASN1ObjectIdentifier oid) { return IETFUtils.findAttrNamesForOID(oid, DefaultLookUp); } public ASN1ObjectIdentifier attrNameToOID(String attrName) { return IETFUtils.decodeAttrName(attrName, DefaultLookUp); } public boolean areEqual(X500Name name1, X500Name name2) { RDN[] rdns1 = name1.getRDNs(); RDN[] rdns2 = name2.getRDNs(); if (rdns1.length != rdns2.length) { return false; } boolean reverse = false; if (rdns1[0].getFirst() != null && rdns2[0].getFirst() != null) { reverse = !rdns1[0].getFirst().getType().equals(rdns2[0].getFirst().getType()); // guess forward } for (int i = 0; i != rdns1.length; i++) { if (!foundMatch(reverse, rdns1[i], rdns2)) { return false; } } return true; } private boolean foundMatch(boolean reverse, RDN rdn, RDN[] possRDNs) { if (reverse) { for (int i = possRDNs.length - 1; i >= 0; i--) { if (possRDNs[i] != null && rdnAreEqual(rdn, possRDNs[i])) { possRDNs[i] = null; return true; } } } else { for (int i = 0; i != possRDNs.length; i++) { if (possRDNs[i] != null && rdnAreEqual(rdn, possRDNs[i])) { possRDNs[i] = null; return true; } } } return false; } protected boolean rdnAreEqual(RDN rdn1, RDN rdn2) { return IETFUtils.rDNAreEqual(rdn1, rdn2); } // parse backwards public RDN[] fromString(String dirName) { RDN[] tmp = IETFUtils.rDNsFromString(dirName, this); RDN[] res = new RDN[tmp.length]; for (int i = 0; i != tmp.length; i++) { res[res.length - i - 1] = tmp[i]; } return res; } public int calculateHashCode(X500Name name) { int hashCodeValue = 0; RDN[] rdns = name.getRDNs(); // this needs to be order independent, like equals for (int i = 0; i != rdns.length; i++) { if (rdns[i].isMultiValued()) { AttributeTypeAndValue[] atv = rdns[i].getTypesAndValues(); for (int j = 0; j != atv.length; j++) { hashCodeValue ^= atv[j].getType().hashCode(); hashCodeValue ^= calcHashCode(atv[j].getValue()); } } else { hashCodeValue ^= rdns[i].getFirst().getType().hashCode(); hashCodeValue ^= calcHashCode(rdns[i].getFirst().getValue()); } } return hashCodeValue; } private int calcHashCode(ASN1Encodable enc) { String value = IETFUtils.valueToString(enc); value = IETFUtils.canonicalize(value); return value.hashCode(); } // convert in reverse public String toString(X500Name name) { StringBuffer buf = new StringBuffer(); boolean first = true; RDN[] rdns = name.getRDNs(); for (int i = rdns.length - 1; i >= 0; i--) { if (first) { first = false; } else { buf.append(','); } IETFUtils.appendRDN(buf, rdns[i], DefaultSymbols); } return buf.toString(); } } bouncycastle-1.49.orig/src/org/bouncycastle/asn1/x500/style/BCStyle.java0000644000175000017500000003505112151455167025363 0ustar ebourgebourgpackage org.bouncycastle.asn1.x500.style; import java.io.IOException; import java.util.Hashtable; import org.bouncycastle.asn1.ASN1Encodable; import org.bouncycastle.asn1.ASN1GeneralizedTime; import org.bouncycastle.asn1.ASN1ObjectIdentifier; import org.bouncycastle.asn1.DERIA5String; import org.bouncycastle.asn1.DERPrintableString; import org.bouncycastle.asn1.DERUTF8String; import org.bouncycastle.asn1.pkcs.PKCSObjectIdentifiers; import org.bouncycastle.asn1.x500.AttributeTypeAndValue; import org.bouncycastle.asn1.x500.RDN; import org.bouncycastle.asn1.x500.X500Name; import org.bouncycastle.asn1.x500.X500NameStyle; import org.bouncycastle.asn1.x509.X509ObjectIdentifiers; public class BCStyle implements X500NameStyle { public static final X500NameStyle INSTANCE = new BCStyle(); /** * country code - StringType(SIZE(2)) */ public static final ASN1ObjectIdentifier C = new ASN1ObjectIdentifier("2.5.4.6"); /** * organization - StringType(SIZE(1..64)) */ public static final ASN1ObjectIdentifier O = new ASN1ObjectIdentifier("2.5.4.10"); /** * organizational unit name - StringType(SIZE(1..64)) */ public static final ASN1ObjectIdentifier OU = new ASN1ObjectIdentifier("2.5.4.11"); /** * Title */ public static final ASN1ObjectIdentifier T = new ASN1ObjectIdentifier("2.5.4.12"); /** * common name - StringType(SIZE(1..64)) */ public static final ASN1ObjectIdentifier CN = new ASN1ObjectIdentifier("2.5.4.3"); /** * device serial number name - StringType(SIZE(1..64)) */ public static final ASN1ObjectIdentifier SN = new ASN1ObjectIdentifier("2.5.4.5"); /** * street - StringType(SIZE(1..64)) */ public static final ASN1ObjectIdentifier STREET = new ASN1ObjectIdentifier("2.5.4.9"); /** * device serial number name - StringType(SIZE(1..64)) */ public static final ASN1ObjectIdentifier SERIALNUMBER = SN; /** * locality name - StringType(SIZE(1..64)) */ public static final ASN1ObjectIdentifier L = new ASN1ObjectIdentifier("2.5.4.7"); /** * state, or province name - StringType(SIZE(1..64)) */ public static final ASN1ObjectIdentifier ST = new ASN1ObjectIdentifier("2.5.4.8"); /** * Naming attributes of type X520name */ public static final ASN1ObjectIdentifier SURNAME = new ASN1ObjectIdentifier("2.5.4.4"); public static final ASN1ObjectIdentifier GIVENNAME = new ASN1ObjectIdentifier("2.5.4.42"); public static final ASN1ObjectIdentifier INITIALS = new ASN1ObjectIdentifier("2.5.4.43"); public static final ASN1ObjectIdentifier GENERATION = new ASN1ObjectIdentifier("2.5.4.44"); public static final ASN1ObjectIdentifier UNIQUE_IDENTIFIER = new ASN1ObjectIdentifier("2.5.4.45"); /** * businessCategory - DirectoryString(SIZE(1..128) */ public static final ASN1ObjectIdentifier BUSINESS_CATEGORY = new ASN1ObjectIdentifier( "2.5.4.15"); /** * postalCode - DirectoryString(SIZE(1..40) */ public static final ASN1ObjectIdentifier POSTAL_CODE = new ASN1ObjectIdentifier( "2.5.4.17"); /** * dnQualifier - DirectoryString(SIZE(1..64) */ public static final ASN1ObjectIdentifier DN_QUALIFIER = new ASN1ObjectIdentifier( "2.5.4.46"); /** * RFC 3039 Pseudonym - DirectoryString(SIZE(1..64) */ public static final ASN1ObjectIdentifier PSEUDONYM = new ASN1ObjectIdentifier( "2.5.4.65"); /** * RFC 3039 DateOfBirth - GeneralizedTime - YYYYMMDD000000Z */ public static final ASN1ObjectIdentifier DATE_OF_BIRTH = new ASN1ObjectIdentifier( "1.3.6.1.5.5.7.9.1"); /** * RFC 3039 PlaceOfBirth - DirectoryString(SIZE(1..128) */ public static final ASN1ObjectIdentifier PLACE_OF_BIRTH = new ASN1ObjectIdentifier( "1.3.6.1.5.5.7.9.2"); /** * RFC 3039 Gender - PrintableString (SIZE(1)) -- "M", "F", "m" or "f" */ public static final ASN1ObjectIdentifier GENDER = new ASN1ObjectIdentifier( "1.3.6.1.5.5.7.9.3"); /** * RFC 3039 CountryOfCitizenship - PrintableString (SIZE (2)) -- ISO 3166 * codes only */ public static final ASN1ObjectIdentifier COUNTRY_OF_CITIZENSHIP = new ASN1ObjectIdentifier( "1.3.6.1.5.5.7.9.4"); /** * RFC 3039 CountryOfResidence - PrintableString (SIZE (2)) -- ISO 3166 * codes only */ public static final ASN1ObjectIdentifier COUNTRY_OF_RESIDENCE = new ASN1ObjectIdentifier( "1.3.6.1.5.5.7.9.5"); /** * ISIS-MTT NameAtBirth - DirectoryString(SIZE(1..64) */ public static final ASN1ObjectIdentifier NAME_AT_BIRTH = new ASN1ObjectIdentifier("1.3.36.8.3.14"); /** * RFC 3039 PostalAddress - SEQUENCE SIZE (1..6) OF * DirectoryString(SIZE(1..30)) */ public static final ASN1ObjectIdentifier POSTAL_ADDRESS = new ASN1ObjectIdentifier("2.5.4.16"); /** * RFC 2256 dmdName */ public static final ASN1ObjectIdentifier DMD_NAME = new ASN1ObjectIdentifier("2.5.4.54"); /** * id-at-telephoneNumber */ public static final ASN1ObjectIdentifier TELEPHONE_NUMBER = X509ObjectIdentifiers.id_at_telephoneNumber; /** * id-at-name */ public static final ASN1ObjectIdentifier NAME = X509ObjectIdentifiers.id_at_name; /** * Email address (RSA PKCS#9 extension) - IA5String. *

    Note: if you're trying to be ultra orthodox, don't use this! It shouldn't be in here. */ public static final ASN1ObjectIdentifier EmailAddress = PKCSObjectIdentifiers.pkcs_9_at_emailAddress; /** * more from PKCS#9 */ public static final ASN1ObjectIdentifier UnstructuredName = PKCSObjectIdentifiers.pkcs_9_at_unstructuredName; public static final ASN1ObjectIdentifier UnstructuredAddress = PKCSObjectIdentifiers.pkcs_9_at_unstructuredAddress; /** * email address in Verisign certificates */ public static final ASN1ObjectIdentifier E = EmailAddress; /* * others... */ public static final ASN1ObjectIdentifier DC = new ASN1ObjectIdentifier("0.9.2342.19200300.100.1.25"); /** * LDAP User id. */ public static final ASN1ObjectIdentifier UID = new ASN1ObjectIdentifier("0.9.2342.19200300.100.1.1"); /** * default look up table translating OID values into their common symbols following * the convention in RFC 2253 with a few extras */ private static final Hashtable DefaultSymbols = new Hashtable(); /** * look up table translating common symbols into their OIDS. */ private static final Hashtable DefaultLookUp = new Hashtable(); static { DefaultSymbols.put(C, "C"); DefaultSymbols.put(O, "O"); DefaultSymbols.put(T, "T"); DefaultSymbols.put(OU, "OU"); DefaultSymbols.put(CN, "CN"); DefaultSymbols.put(L, "L"); DefaultSymbols.put(ST, "ST"); DefaultSymbols.put(SN, "SERIALNUMBER"); DefaultSymbols.put(EmailAddress, "E"); DefaultSymbols.put(DC, "DC"); DefaultSymbols.put(UID, "UID"); DefaultSymbols.put(STREET, "STREET"); DefaultSymbols.put(SURNAME, "SURNAME"); DefaultSymbols.put(GIVENNAME, "GIVENNAME"); DefaultSymbols.put(INITIALS, "INITIALS"); DefaultSymbols.put(GENERATION, "GENERATION"); DefaultSymbols.put(UnstructuredAddress, "unstructuredAddress"); DefaultSymbols.put(UnstructuredName, "unstructuredName"); DefaultSymbols.put(UNIQUE_IDENTIFIER, "UniqueIdentifier"); DefaultSymbols.put(DN_QUALIFIER, "DN"); DefaultSymbols.put(PSEUDONYM, "Pseudonym"); DefaultSymbols.put(POSTAL_ADDRESS, "PostalAddress"); DefaultSymbols.put(NAME_AT_BIRTH, "NameAtBirth"); DefaultSymbols.put(COUNTRY_OF_CITIZENSHIP, "CountryOfCitizenship"); DefaultSymbols.put(COUNTRY_OF_RESIDENCE, "CountryOfResidence"); DefaultSymbols.put(GENDER, "Gender"); DefaultSymbols.put(PLACE_OF_BIRTH, "PlaceOfBirth"); DefaultSymbols.put(DATE_OF_BIRTH, "DateOfBirth"); DefaultSymbols.put(POSTAL_CODE, "PostalCode"); DefaultSymbols.put(BUSINESS_CATEGORY, "BusinessCategory"); DefaultSymbols.put(TELEPHONE_NUMBER, "TelephoneNumber"); DefaultSymbols.put(NAME, "Name"); DefaultLookUp.put("c", C); DefaultLookUp.put("o", O); DefaultLookUp.put("t", T); DefaultLookUp.put("ou", OU); DefaultLookUp.put("cn", CN); DefaultLookUp.put("l", L); DefaultLookUp.put("st", ST); DefaultLookUp.put("sn", SN); DefaultLookUp.put("serialnumber", SN); DefaultLookUp.put("street", STREET); DefaultLookUp.put("emailaddress", E); DefaultLookUp.put("dc", DC); DefaultLookUp.put("e", E); DefaultLookUp.put("uid", UID); DefaultLookUp.put("surname", SURNAME); DefaultLookUp.put("givenname", GIVENNAME); DefaultLookUp.put("initials", INITIALS); DefaultLookUp.put("generation", GENERATION); DefaultLookUp.put("unstructuredaddress", UnstructuredAddress); DefaultLookUp.put("unstructuredname", UnstructuredName); DefaultLookUp.put("uniqueidentifier", UNIQUE_IDENTIFIER); DefaultLookUp.put("dn", DN_QUALIFIER); DefaultLookUp.put("pseudonym", PSEUDONYM); DefaultLookUp.put("postaladdress", POSTAL_ADDRESS); DefaultLookUp.put("nameofbirth", NAME_AT_BIRTH); DefaultLookUp.put("countryofcitizenship", COUNTRY_OF_CITIZENSHIP); DefaultLookUp.put("countryofresidence", COUNTRY_OF_RESIDENCE); DefaultLookUp.put("gender", GENDER); DefaultLookUp.put("placeofbirth", PLACE_OF_BIRTH); DefaultLookUp.put("dateofbirth", DATE_OF_BIRTH); DefaultLookUp.put("postalcode", POSTAL_CODE); DefaultLookUp.put("businesscategory", BUSINESS_CATEGORY); DefaultLookUp.put("telephonenumber", TELEPHONE_NUMBER); DefaultLookUp.put("name", NAME); } protected BCStyle() { } public ASN1Encodable stringToValue(ASN1ObjectIdentifier oid, String value) { if (value.length() != 0 && value.charAt(0) == '#') { try { return IETFUtils.valueFromHexString(value, 1); } catch (IOException e) { throw new RuntimeException("can't recode value for oid " + oid.getId()); } } else { if (value.length() != 0 && value.charAt(0) == '\\') { value = value.substring(1); } if (oid.equals(EmailAddress) || oid.equals(DC)) { return new DERIA5String(value); } else if (oid.equals(DATE_OF_BIRTH)) // accept time string as well as # (for compatibility) { return new ASN1GeneralizedTime(value); } else if (oid.equals(C) || oid.equals(SN) || oid.equals(DN_QUALIFIER) || oid.equals(TELEPHONE_NUMBER)) { return new DERPrintableString(value); } } return new DERUTF8String(value); } public String oidToDisplayName(ASN1ObjectIdentifier oid) { return (String)DefaultSymbols.get(oid); } public String[] oidToAttrNames(ASN1ObjectIdentifier oid) { return IETFUtils.findAttrNamesForOID(oid, DefaultLookUp); } public ASN1ObjectIdentifier attrNameToOID(String attrName) { return IETFUtils.decodeAttrName(attrName, DefaultLookUp); } public boolean areEqual(X500Name name1, X500Name name2) { RDN[] rdns1 = name1.getRDNs(); RDN[] rdns2 = name2.getRDNs(); if (rdns1.length != rdns2.length) { return false; } boolean reverse = false; if (rdns1[0].getFirst() != null && rdns2[0].getFirst() != null) { reverse = !rdns1[0].getFirst().getType().equals(rdns2[0].getFirst().getType()); // guess forward } for (int i = 0; i != rdns1.length; i++) { if (!foundMatch(reverse, rdns1[i], rdns2)) { return false; } } return true; } private boolean foundMatch(boolean reverse, RDN rdn, RDN[] possRDNs) { if (reverse) { for (int i = possRDNs.length - 1; i >= 0; i--) { if (possRDNs[i] != null && rdnAreEqual(rdn, possRDNs[i])) { possRDNs[i] = null; return true; } } } else { for (int i = 0; i != possRDNs.length; i++) { if (possRDNs[i] != null && rdnAreEqual(rdn, possRDNs[i])) { possRDNs[i] = null; return true; } } } return false; } protected boolean rdnAreEqual(RDN rdn1, RDN rdn2) { return IETFUtils.rDNAreEqual(rdn1, rdn2); } public RDN[] fromString(String dirName) { return IETFUtils.rDNsFromString(dirName, this); } public int calculateHashCode(X500Name name) { int hashCodeValue = 0; RDN[] rdns = name.getRDNs(); // this needs to be order independent, like equals for (int i = 0; i != rdns.length; i++) { if (rdns[i].isMultiValued()) { AttributeTypeAndValue[] atv = rdns[i].getTypesAndValues(); for (int j = 0; j != atv.length; j++) { hashCodeValue ^= atv[j].getType().hashCode(); hashCodeValue ^= calcHashCode(atv[j].getValue()); } } else { hashCodeValue ^= rdns[i].getFirst().getType().hashCode(); hashCodeValue ^= calcHashCode(rdns[i].getFirst().getValue()); } } return hashCodeValue; } private int calcHashCode(ASN1Encodable enc) { String value = IETFUtils.valueToString(enc); value = IETFUtils.canonicalize(value); return value.hashCode(); } public String toString(X500Name name) { StringBuffer buf = new StringBuffer(); boolean first = true; RDN[] rdns = name.getRDNs(); for (int i = 0; i < rdns.length; i++) { if (first) { first = false; } else { buf.append(','); } IETFUtils.appendRDN(buf, rdns[i], DefaultSymbols); } return buf.toString(); } } bouncycastle-1.49.orig/src/org/bouncycastle/asn1/x500/style/X500NameTokenizer.java0000644000175000017500000000371312111252254027172 0ustar ebourgebourgpackage org.bouncycastle.asn1.x500.style; /** * class for breaking up an X500 Name into it's component tokens, ala * java.util.StringTokenizer. We need this class as some of the * lightweight Java environment don't support classes like * StringTokenizer. */ class X500NameTokenizer { private String value; private int index; private char separator; private StringBuffer buf = new StringBuffer(); public X500NameTokenizer( String oid) { this(oid, ','); } public X500NameTokenizer( String oid, char separator) { this.value = oid; this.index = -1; this.separator = separator; } public boolean hasMoreTokens() { return (index != value.length()); } public String nextToken() { if (index == value.length()) { return null; } int end = index + 1; boolean quoted = false; boolean escaped = false; buf.setLength(0); while (end != value.length()) { char c = value.charAt(end); if (c == '"') { if (!escaped) { quoted = !quoted; } buf.append(c); escaped = false; } else { if (escaped || quoted) { buf.append(c); escaped = false; } else if (c == '\\') { buf.append(c); escaped = true; } else if (c == separator) { break; } else { buf.append(c); } } end++; } index = end; return buf.toString(); } } bouncycastle-1.49.orig/src/org/bouncycastle/asn1/x500/style/IETFUtils.java0000644000175000017500000003564512151455151025630 0ustar ebourgebourgpackage org.bouncycastle.asn1.x500.style; import java.io.IOException; import java.util.Enumeration; import java.util.Hashtable; import java.util.Vector; import org.bouncycastle.asn1.ASN1Encodable; import org.bouncycastle.asn1.ASN1Encoding; import org.bouncycastle.asn1.ASN1ObjectIdentifier; import org.bouncycastle.asn1.ASN1Primitive; import org.bouncycastle.asn1.ASN1String; import org.bouncycastle.asn1.DERUniversalString; import org.bouncycastle.asn1.x500.AttributeTypeAndValue; import org.bouncycastle.asn1.x500.RDN; import org.bouncycastle.asn1.x500.X500NameBuilder; import org.bouncycastle.asn1.x500.X500NameStyle; import org.bouncycastle.util.Strings; import org.bouncycastle.util.encoders.Hex; public class IETFUtils { private static String unescape(String elt) { if (elt.length() == 0 || (elt.indexOf('\\') < 0 && elt.indexOf('"') < 0)) { return elt.trim(); } char[] elts = elt.toCharArray(); boolean escaped = false; boolean quoted = false; StringBuffer buf = new StringBuffer(elt.length()); int start = 0; // if it's an escaped hash string and not an actual encoding in string form // we need to leave it escaped. if (elts[0] == '\\') { if (elts[1] == '#') { start = 2; buf.append("\\#"); } } boolean nonWhiteSpaceEncountered = false; int lastEscaped = 0; char hex1 = 0; for (int i = start; i != elts.length; i++) { char c = elts[i]; if (c != ' ') { nonWhiteSpaceEncountered = true; } if (c == '"') { if (!escaped) { quoted = !quoted; } else { buf.append(c); } escaped = false; } else if (c == '\\' && !(escaped || quoted)) { escaped = true; lastEscaped = buf.length(); } else { if (c == ' ' && !escaped && !nonWhiteSpaceEncountered) { continue; } if (escaped && isHexDigit(c)) { if (hex1 != 0) { buf.append((char)(convertHex(hex1) * 16 + convertHex(c))); escaped = false; hex1 = 0; continue; } hex1 = c; continue; } buf.append(c); escaped = false; } } if (buf.length() > 0) { while (buf.charAt(buf.length() - 1) == ' ' && lastEscaped != (buf.length() - 1)) { buf.setLength(buf.length() - 1); } } return buf.toString(); } private static boolean isHexDigit(char c) { return ('0' <= c && c <= '9') || ('a' <= c && c <= 'f') || ('A' <= c && c <= 'F'); } private static int convertHex(char c) { if ('0' <= c && c <= '9') { return c - '0'; } if ('a' <= c && c <= 'f') { return c - 'a' + 10; } return c - 'A' + 10; } public static RDN[] rDNsFromString(String name, X500NameStyle x500Style) { X500NameTokenizer nTok = new X500NameTokenizer(name); X500NameBuilder builder = new X500NameBuilder(x500Style); while (nTok.hasMoreTokens()) { String token = nTok.nextToken(); if (token.indexOf('+') > 0) { X500NameTokenizer pTok = new X500NameTokenizer(token, '+'); X500NameTokenizer vTok = new X500NameTokenizer(pTok.nextToken(), '='); String attr = vTok.nextToken(); if (!vTok.hasMoreTokens()) { throw new IllegalArgumentException("badly formatted directory string"); } String value = vTok.nextToken(); ASN1ObjectIdentifier oid = x500Style.attrNameToOID(attr.trim()); if (pTok.hasMoreTokens()) { Vector oids = new Vector(); Vector values = new Vector(); oids.addElement(oid); values.addElement(unescape(value)); while (pTok.hasMoreTokens()) { vTok = new X500NameTokenizer(pTok.nextToken(), '='); attr = vTok.nextToken(); if (!vTok.hasMoreTokens()) { throw new IllegalArgumentException("badly formatted directory string"); } value = vTok.nextToken(); oid = x500Style.attrNameToOID(attr.trim()); oids.addElement(oid); values.addElement(unescape(value)); } builder.addMultiValuedRDN(toOIDArray(oids), toValueArray(values)); } else { builder.addRDN(oid, unescape(value)); } } else { X500NameTokenizer vTok = new X500NameTokenizer(token, '='); String attr = vTok.nextToken(); if (!vTok.hasMoreTokens()) { throw new IllegalArgumentException("badly formatted directory string"); } String value = vTok.nextToken(); ASN1ObjectIdentifier oid = x500Style.attrNameToOID(attr.trim()); builder.addRDN(oid, unescape(value)); } } return builder.build().getRDNs(); } private static String[] toValueArray(Vector values) { String[] tmp = new String[values.size()]; for (int i = 0; i != tmp.length; i++) { tmp[i] = (String)values.elementAt(i); } return tmp; } private static ASN1ObjectIdentifier[] toOIDArray(Vector oids) { ASN1ObjectIdentifier[] tmp = new ASN1ObjectIdentifier[oids.size()]; for (int i = 0; i != tmp.length; i++) { tmp[i] = (ASN1ObjectIdentifier)oids.elementAt(i); } return tmp; } public static String[] findAttrNamesForOID( ASN1ObjectIdentifier oid, Hashtable lookup) { int count = 0; for (Enumeration en = lookup.elements(); en.hasMoreElements();) { if (oid.equals(en.nextElement())) { count++; } } String[] aliases = new String[count]; count = 0; for (Enumeration en = lookup.keys(); en.hasMoreElements();) { String key = (String)en.nextElement(); if (oid.equals(lookup.get(key))) { aliases[count++] = key; } } return aliases; } public static ASN1ObjectIdentifier decodeAttrName( String name, Hashtable lookUp) { if (Strings.toUpperCase(name).startsWith("OID.")) { return new ASN1ObjectIdentifier(name.substring(4)); } else if (name.charAt(0) >= '0' && name.charAt(0) <= '9') { return new ASN1ObjectIdentifier(name); } ASN1ObjectIdentifier oid = (ASN1ObjectIdentifier)lookUp.get(Strings.toLowerCase(name)); if (oid == null) { throw new IllegalArgumentException("Unknown object id - " + name + " - passed to distinguished name"); } return oid; } public static ASN1Encodable valueFromHexString( String str, int off) throws IOException { byte[] data = new byte[(str.length() - off) / 2]; for (int index = 0; index != data.length; index++) { char left = str.charAt((index * 2) + off); char right = str.charAt((index * 2) + off + 1); data[index] = (byte)((convertHex(left) << 4) | convertHex(right)); } return ASN1Primitive.fromByteArray(data); } public static void appendRDN( StringBuffer buf, RDN rdn, Hashtable oidSymbols) { if (rdn.isMultiValued()) { AttributeTypeAndValue[] atv = rdn.getTypesAndValues(); boolean firstAtv = true; for (int j = 0; j != atv.length; j++) { if (firstAtv) { firstAtv = false; } else { buf.append('+'); } IETFUtils.appendTypeAndValue(buf, atv[j], oidSymbols); } } else { IETFUtils.appendTypeAndValue(buf, rdn.getFirst(), oidSymbols); } } public static void appendTypeAndValue( StringBuffer buf, AttributeTypeAndValue typeAndValue, Hashtable oidSymbols) { String sym = (String)oidSymbols.get(typeAndValue.getType()); if (sym != null) { buf.append(sym); } else { buf.append(typeAndValue.getType().getId()); } buf.append('='); buf.append(valueToString(typeAndValue.getValue())); } public static String valueToString(ASN1Encodable value) { StringBuffer vBuf = new StringBuffer(); if (value instanceof ASN1String && !(value instanceof DERUniversalString)) { String v = ((ASN1String)value).getString(); if (v.length() > 0 && v.charAt(0) == '#') { vBuf.append("\\" + v); } else { vBuf.append(v); } } else { try { vBuf.append("#" + bytesToString(Hex.encode(value.toASN1Primitive().getEncoded(ASN1Encoding.DER)))); } catch (IOException e) { throw new IllegalArgumentException("Other value has no encoded form"); } } int end = vBuf.length(); int index = 0; if (vBuf.length() >= 2 && vBuf.charAt(0) == '\\' && vBuf.charAt(1) == '#') { index += 2; } while (index != end) { if ((vBuf.charAt(index) == ',') || (vBuf.charAt(index) == '"') || (vBuf.charAt(index) == '\\') || (vBuf.charAt(index) == '+') || (vBuf.charAt(index) == '=') || (vBuf.charAt(index) == '<') || (vBuf.charAt(index) == '>') || (vBuf.charAt(index) == ';')) { vBuf.insert(index, "\\"); index++; end++; } index++; } int start = 0; if (vBuf.length() > 0) { while (vBuf.charAt(start) == ' ') { vBuf.insert(start, "\\"); start += 2; } } int endBuf = vBuf.length() - 1; while (endBuf >= 0 && vBuf.charAt(endBuf) == ' ') { vBuf.insert(endBuf, '\\'); endBuf--; } return vBuf.toString(); } private static String bytesToString( byte[] data) { char[] cs = new char[data.length]; for (int i = 0; i != cs.length; i++) { cs[i] = (char)(data[i] & 0xff); } return new String(cs); } public static String canonicalize(String s) { String value = Strings.toLowerCase(s.trim()); if (value.length() > 0 && value.charAt(0) == '#') { ASN1Primitive obj = decodeObject(value); if (obj instanceof ASN1String) { value = Strings.toLowerCase(((ASN1String)obj).getString().trim()); } } value = stripInternalSpaces(value); return value; } private static ASN1Primitive decodeObject(String oValue) { try { return ASN1Primitive.fromByteArray(Hex.decode(oValue.substring(1))); } catch (IOException e) { throw new IllegalStateException("unknown encoding in name: " + e); } } public static String stripInternalSpaces( String str) { StringBuffer res = new StringBuffer(); if (str.length() != 0) { char c1 = str.charAt(0); res.append(c1); for (int k = 1; k < str.length(); k++) { char c2 = str.charAt(k); if (!(c1 == ' ' && c2 == ' ')) { res.append(c2); } c1 = c2; } } return res.toString(); } public static boolean rDNAreEqual(RDN rdn1, RDN rdn2) { if (rdn1.isMultiValued()) { if (rdn2.isMultiValued()) { AttributeTypeAndValue[] atvs1 = rdn1.getTypesAndValues(); AttributeTypeAndValue[] atvs2 = rdn2.getTypesAndValues(); if (atvs1.length != atvs2.length) { return false; } for (int i = 0; i != atvs1.length; i++) { if (!atvAreEqual(atvs1[i], atvs2[i])) { return false; } } } else { return false; } } else { if (!rdn2.isMultiValued()) { return atvAreEqual(rdn1.getFirst(), rdn2.getFirst()); } else { return false; } } return true; } private static boolean atvAreEqual(AttributeTypeAndValue atv1, AttributeTypeAndValue atv2) { if (atv1 == atv2) { return true; } if (atv1 == null) { return false; } if (atv2 == null) { return false; } ASN1ObjectIdentifier o1 = atv1.getType(); ASN1ObjectIdentifier o2 = atv2.getType(); if (!o1.equals(o2)) { return false; } String v1 = IETFUtils.canonicalize(IETFUtils.valueToString(atv1.getValue())); String v2 = IETFUtils.canonicalize(IETFUtils.valueToString(atv2.getValue())); if (!v1.equals(v2)) { return false; } return true; } } bouncycastle-1.49.orig/src/org/bouncycastle/asn1/x500/style/BCStrictStyle.java0000644000175000017500000000151111735214303026536 0ustar ebourgebourgpackage org.bouncycastle.asn1.x500.style; import org.bouncycastle.asn1.x500.RDN; import org.bouncycastle.asn1.x500.X500Name; import org.bouncycastle.asn1.x500.X500NameStyle; /** * Variation of BCStyle that insists on strict ordering for equality * and hashCode comparisons */ public class BCStrictStyle extends BCStyle { public static final X500NameStyle INSTANCE = new BCStrictStyle(); public boolean areEqual(X500Name name1, X500Name name2) { RDN[] rdns1 = name1.getRDNs(); RDN[] rdns2 = name2.getRDNs(); if (rdns1.length != rdns2.length) { return false; } for (int i = 0; i != rdns1.length; i++) { if (!rdnAreEqual(rdns1[i], rdns2[i])) { return false; } } return true; } } bouncycastle-1.49.orig/src/org/bouncycastle/asn1/ASN1GeneralizedTime.java0000644000175000017500000000053611703700201025675 0ustar ebourgebourgpackage org.bouncycastle.asn1; import java.util.Date; public class ASN1GeneralizedTime extends DERGeneralizedTime { ASN1GeneralizedTime(byte[] bytes) { super(bytes); } public ASN1GeneralizedTime(Date time) { super(time); } public ASN1GeneralizedTime(String time) { super(time); } } bouncycastle-1.49.orig/src/org/bouncycastle/asn1/BEROctetStringParser.java0000644000175000017500000000157111624650351026171 0ustar ebourgebourgpackage org.bouncycastle.asn1; import java.io.IOException; import java.io.InputStream; import org.bouncycastle.util.io.Streams; public class BEROctetStringParser implements ASN1OctetStringParser { private ASN1StreamParser _parser; BEROctetStringParser( ASN1StreamParser parser) { _parser = parser; } public InputStream getOctetStream() { return new ConstructedOctetStream(_parser); } public ASN1Primitive getLoadedObject() throws IOException { return new BEROctetString(Streams.readAll(getOctetStream())); } public ASN1Primitive toASN1Primitive() { try { return getLoadedObject(); } catch (IOException e) { throw new ASN1ParsingException("IOException converting stream to byte array: " + e.getMessage(), e); } } } bouncycastle-1.49.orig/src/org/bouncycastle/asn1/ASN1Enumerated.java0000644000175000017500000000052211704677346024741 0ustar ebourgebourgpackage org.bouncycastle.asn1; import java.math.BigInteger; public class ASN1Enumerated extends DEREnumerated { ASN1Enumerated(byte[] bytes) { super(bytes); } public ASN1Enumerated(BigInteger value) { super(value); } public ASN1Enumerated(int value) { super(value); } } bouncycastle-1.49.orig/src/org/bouncycastle/asn1/DERBMPString.java0000644000175000017500000000647412062243165024363 0ustar ebourgebourgpackage org.bouncycastle.asn1; import java.io.IOException; import org.bouncycastle.util.Arrays; /** * DER BMPString object. */ public class DERBMPString extends ASN1Primitive implements ASN1String { private char[] string; /** * return a BMP String from the given object. * * @param obj the object we want converted. * @exception IllegalArgumentException if the object cannot be converted. */ public static DERBMPString getInstance( Object obj) { if (obj == null || obj instanceof DERBMPString) { return (DERBMPString)obj; } if (obj instanceof byte[]) { try { return (DERBMPString)fromByteArray((byte[])obj); } catch (Exception e) { throw new IllegalArgumentException("encoding error in getInstance: " + e.toString()); } } throw new IllegalArgumentException("illegal object in getInstance: " + obj.getClass().getName()); } /** * return a BMP String from a tagged object. * * @param obj the tagged object holding the object we want * @param explicit true if the object is meant to be explicitly * tagged false otherwise. * @exception IllegalArgumentException if the tagged object cannot * be converted. */ public static DERBMPString getInstance( ASN1TaggedObject obj, boolean explicit) { ASN1Primitive o = obj.getObject(); if (explicit || o instanceof DERBMPString) { return getInstance(o); } else { return new DERBMPString(ASN1OctetString.getInstance(o).getOctets()); } } /** * basic constructor - byte encoded string. */ DERBMPString( byte[] string) { char[] cs = new char[string.length / 2]; for (int i = 0; i != cs.length; i++) { cs[i] = (char)((string[2 * i] << 8) | (string[2 * i + 1] & 0xff)); } this.string = cs; } DERBMPString(char[] string) { this.string = string; } /** * basic constructor */ public DERBMPString( String string) { this.string = string.toCharArray(); } public String getString() { return new String(string); } public String toString() { return getString(); } public int hashCode() { return Arrays.hashCode(string); } protected boolean asn1Equals( ASN1Primitive o) { if (!(o instanceof DERBMPString)) { return false; } DERBMPString s = (DERBMPString)o; return Arrays.areEqual(string, s.string); } boolean isConstructed() { return false; } int encodedLength() { return 1 + StreamUtil.calculateBodyLength(string.length * 2) + (string.length * 2); } void encode( ASN1OutputStream out) throws IOException { out.write(BERTags.BMP_STRING); out.writeLength(string.length * 2); for (int i = 0; i != string.length; i++) { char c = string[i]; out.write((byte)(c >> 8)); out.write((byte)c); } } } bouncycastle-1.49.orig/src/org/bouncycastle/asn1/ASN1OutputStream.java0000644000175000017500000000726411703706415025323 0ustar ebourgebourgpackage org.bouncycastle.asn1; import java.io.IOException; import java.io.OutputStream; /** * Stream that produces output based on the default encoding for the passed in objects. */ public class ASN1OutputStream { private OutputStream os; public ASN1OutputStream( OutputStream os) { this.os = os; } void writeLength( int length) throws IOException { if (length > 127) { int size = 1; int val = length; while ((val >>>= 8) != 0) { size++; } write((byte)(size | 0x80)); for (int i = (size - 1) * 8; i >= 0; i -= 8) { write((byte)(length >> i)); } } else { write((byte)length); } } void write(int b) throws IOException { os.write(b); } void write(byte[] bytes) throws IOException { os.write(bytes); } void write(byte[] bytes, int off, int len) throws IOException { os.write(bytes, off, len); } void writeEncoded( int tag, byte[] bytes) throws IOException { write(tag); writeLength(bytes.length); write(bytes); } void writeTag(int flags, int tagNo) throws IOException { if (tagNo < 31) { write(flags | tagNo); } else { write(flags | 0x1f); if (tagNo < 128) { write(tagNo); } else { byte[] stack = new byte[5]; int pos = stack.length; stack[--pos] = (byte)(tagNo & 0x7F); do { tagNo >>= 7; stack[--pos] = (byte)(tagNo & 0x7F | 0x80); } while (tagNo > 127); write(stack, pos, stack.length - pos); } } } void writeEncoded(int flags, int tagNo, byte[] bytes) throws IOException { writeTag(flags, tagNo); writeLength(bytes.length); write(bytes); } protected void writeNull() throws IOException { os.write(BERTags.NULL); os.write(0x00); } public void writeObject( ASN1Encodable obj) throws IOException { if (obj != null) { obj.toASN1Primitive().encode(this); } else { throw new IOException("null object detected"); } } void writeImplicitObject(ASN1Primitive obj) throws IOException { if (obj != null) { obj.encode(new ImplicitOutputStream(os)); } else { throw new IOException("null object detected"); } } public void close() throws IOException { os.close(); } public void flush() throws IOException { os.flush(); } ASN1OutputStream getDERSubStream() { return new DEROutputStream(os); } ASN1OutputStream getDLSubStream() { return new DLOutputStream(os); } private class ImplicitOutputStream extends ASN1OutputStream { private boolean first = true; public ImplicitOutputStream(OutputStream os) { super(os); } public void write(int b) throws IOException { if (first) { first = false; } else { super.write(b); } } } } bouncycastle-1.49.orig/src/org/bouncycastle/asn1/nist/0000755000175000017500000000000012152033551022316 5ustar ebourgebourgbouncycastle-1.49.orig/src/org/bouncycastle/asn1/nist/NISTNamedCurves.java0000644000175000017500000000610612132366522026103 0ustar ebourgebourgpackage org.bouncycastle.asn1.nist; import java.util.Enumeration; import java.util.Hashtable; import org.bouncycastle.asn1.ASN1ObjectIdentifier; import org.bouncycastle.asn1.sec.SECNamedCurves; import org.bouncycastle.asn1.sec.SECObjectIdentifiers; import org.bouncycastle.asn1.x9.X9ECParameters; import org.bouncycastle.util.Strings; /** * Utility class for fetching curves using their NIST names as published in FIPS-PUB 186-3 */ public class NISTNamedCurves { static final Hashtable objIds = new Hashtable(); static final Hashtable names = new Hashtable(); static void defineCurve(String name, ASN1ObjectIdentifier oid) { objIds.put(name, oid); names.put(oid, name); } static { defineCurve("B-571", SECObjectIdentifiers.sect571r1); defineCurve("B-409", SECObjectIdentifiers.sect409r1); defineCurve("B-283", SECObjectIdentifiers.sect283r1); defineCurve("B-233", SECObjectIdentifiers.sect233r1); defineCurve("B-163", SECObjectIdentifiers.sect163r2); defineCurve("K-571", SECObjectIdentifiers.sect571k1); defineCurve("K-409", SECObjectIdentifiers.sect409k1); defineCurve("K-283", SECObjectIdentifiers.sect283k1); defineCurve("K-233", SECObjectIdentifiers.sect233k1); defineCurve("K-163", SECObjectIdentifiers.sect163k1); defineCurve("P-521", SECObjectIdentifiers.secp521r1); defineCurve("P-384", SECObjectIdentifiers.secp384r1); defineCurve("P-256", SECObjectIdentifiers.secp256r1); defineCurve("P-224", SECObjectIdentifiers.secp224r1); defineCurve("P-192", SECObjectIdentifiers.secp192r1); } public static X9ECParameters getByName( String name) { ASN1ObjectIdentifier oid = (ASN1ObjectIdentifier)objIds.get(Strings.toUpperCase(name)); if (oid != null) { return getByOID(oid); } return null; } /** * return the X9ECParameters object for the named curve represented by * the passed in object identifier. Null if the curve isn't present. * * @param oid an object identifier representing a named curve, if present. */ public static X9ECParameters getByOID( ASN1ObjectIdentifier oid) { return SECNamedCurves.getByOID(oid); } /** * return the object identifier signified by the passed in name. Null * if there is no object identifier associated with name. * * @return the object identifier associated with name, if present. */ public static ASN1ObjectIdentifier getOID( String name) { return (ASN1ObjectIdentifier)objIds.get(Strings.toUpperCase(name)); } /** * return the named curve name represented by the given object identifier. */ public static String getName( ASN1ObjectIdentifier oid) { return (String)names.get(oid); } /** * returns an enumeration containing the name strings for curves * contained in this structure. */ public static Enumeration getNames() { return objIds.keys(); } } bouncycastle-1.49.orig/src/org/bouncycastle/asn1/nist/NISTObjectIdentifiers.java0000644000175000017500000000655112110542323027256 0ustar ebourgebourgpackage org.bouncycastle.asn1.nist; import org.bouncycastle.asn1.ASN1ObjectIdentifier; public interface NISTObjectIdentifiers { // // NIST // iso/itu(2) joint-assign(16) us(840) organization(1) gov(101) csor(3) // // nistalgorithms(4) // static final ASN1ObjectIdentifier nistAlgorithm = new ASN1ObjectIdentifier("2.16.840.1.101.3.4"); static final ASN1ObjectIdentifier hashAlgs = nistAlgorithm.branch("2"); static final ASN1ObjectIdentifier id_sha256 = hashAlgs.branch("1"); static final ASN1ObjectIdentifier id_sha384 = hashAlgs.branch("2"); static final ASN1ObjectIdentifier id_sha512 = hashAlgs.branch("3"); static final ASN1ObjectIdentifier id_sha224 = hashAlgs.branch("4"); static final ASN1ObjectIdentifier id_sha512_224 = hashAlgs.branch("5"); static final ASN1ObjectIdentifier id_sha512_256 = hashAlgs.branch("6"); static final ASN1ObjectIdentifier aes = nistAlgorithm.branch("1"); static final ASN1ObjectIdentifier id_aes128_ECB = aes.branch("1"); static final ASN1ObjectIdentifier id_aes128_CBC = aes.branch("2"); static final ASN1ObjectIdentifier id_aes128_OFB = aes.branch("3"); static final ASN1ObjectIdentifier id_aes128_CFB = aes.branch("4"); static final ASN1ObjectIdentifier id_aes128_wrap = aes.branch("5"); static final ASN1ObjectIdentifier id_aes128_GCM = aes.branch("6"); static final ASN1ObjectIdentifier id_aes128_CCM = aes.branch("7"); static final ASN1ObjectIdentifier id_aes192_ECB = aes.branch("21"); static final ASN1ObjectIdentifier id_aes192_CBC = aes.branch("22"); static final ASN1ObjectIdentifier id_aes192_OFB = aes.branch("23"); static final ASN1ObjectIdentifier id_aes192_CFB = aes.branch("24"); static final ASN1ObjectIdentifier id_aes192_wrap = aes.branch("25"); static final ASN1ObjectIdentifier id_aes192_GCM = aes.branch("26"); static final ASN1ObjectIdentifier id_aes192_CCM = aes.branch("27"); static final ASN1ObjectIdentifier id_aes256_ECB = aes.branch("41"); static final ASN1ObjectIdentifier id_aes256_CBC = aes.branch("42"); static final ASN1ObjectIdentifier id_aes256_OFB = aes.branch("43"); static final ASN1ObjectIdentifier id_aes256_CFB = aes.branch("44"); static final ASN1ObjectIdentifier id_aes256_wrap = aes.branch("45"); static final ASN1ObjectIdentifier id_aes256_GCM = aes.branch("46"); static final ASN1ObjectIdentifier id_aes256_CCM = aes.branch("47"); // // signatures // static final ASN1ObjectIdentifier id_dsa_with_sha2 = nistAlgorithm.branch("3"); static final ASN1ObjectIdentifier dsa_with_sha224 = id_dsa_with_sha2.branch("1"); static final ASN1ObjectIdentifier dsa_with_sha256 = id_dsa_with_sha2.branch("2"); static final ASN1ObjectIdentifier dsa_with_sha384 = id_dsa_with_sha2.branch("3"); static final ASN1ObjectIdentifier dsa_with_sha512 = id_dsa_with_sha2.branch("4"); } bouncycastle-1.49.orig/src/org/bouncycastle/asn1/nist/package.html0000644000175000017500000000013210262753175024606 0ustar ebourgebourg Support classes for NIST related objects. bouncycastle-1.49.orig/src/org/bouncycastle/asn1/ASN1Primitive.java0000644000175000017500000000265211703176536024620 0ustar ebourgebourgpackage org.bouncycastle.asn1; import java.io.IOException; public abstract class ASN1Primitive extends ASN1Object { ASN1Primitive() { } /** * Create a base ASN.1 object from a byte stream. * * @param data the byte stream to parse. * @return the base ASN.1 object represented by the byte stream. * @exception IOException if there is a problem parsing the data. */ public static ASN1Primitive fromByteArray(byte[] data) throws IOException { ASN1InputStream aIn = new ASN1InputStream(data); try { return aIn.readObject(); } catch (ClassCastException e) { throw new IOException("cannot recognise object in stream"); } } public final boolean equals(Object o) { if (this == o) { return true; } return (o instanceof ASN1Encodable) && asn1Equals(((ASN1Encodable)o).toASN1Primitive()); } public ASN1Primitive toASN1Primitive() { return this; } ASN1Primitive toDERObject() { return this; } ASN1Primitive toDLObject() { return this; } public abstract int hashCode(); abstract boolean isConstructed(); abstract int encodedLength() throws IOException; abstract void encode(ASN1OutputStream out) throws IOException; abstract boolean asn1Equals(ASN1Primitive o); }bouncycastle-1.49.orig/src/org/bouncycastle/asn1/BEROutputStream.java0000644000175000017500000000134511625075106025222 0ustar ebourgebourgpackage org.bouncycastle.asn1; import java.io.IOException; import java.io.OutputStream; public class BEROutputStream extends DEROutputStream { public BEROutputStream( OutputStream os) { super(os); } public void writeObject( Object obj) throws IOException { if (obj == null) { writeNull(); } else if (obj instanceof ASN1Primitive) { ((ASN1Primitive)obj).encode(this); } else if (obj instanceof ASN1Encodable) { ((ASN1Encodable)obj).toASN1Primitive().encode(this); } else { throw new IOException("object not BEREncodable"); } } } bouncycastle-1.49.orig/src/org/bouncycastle/asn1/icao/0000755000175000017500000000000012152033551022254 5ustar ebourgebourgbouncycastle-1.49.orig/src/org/bouncycastle/asn1/icao/LDSSecurityObject.java0000644000175000017500000001107711724561172026437 0ustar ebourgebourgpackage org.bouncycastle.asn1.icao; import java.util.Enumeration; import org.bouncycastle.asn1.ASN1EncodableVector; import org.bouncycastle.asn1.ASN1Integer; import org.bouncycastle.asn1.ASN1Object; import org.bouncycastle.asn1.ASN1Primitive; import org.bouncycastle.asn1.ASN1Sequence; import org.bouncycastle.asn1.DERSequence; import org.bouncycastle.asn1.x509.AlgorithmIdentifier; /** * The LDSSecurityObject object (V1.8). *

     * LDSSecurityObject ::= SEQUENCE {
     *   version                LDSSecurityObjectVersion,
     *   hashAlgorithm          DigestAlgorithmIdentifier,
     *   dataGroupHashValues    SEQUENCE SIZE (2..ub-DataGroups) OF DataHashGroup,
     *   ldsVersionInfo         LDSVersionInfo OPTIONAL
     *   -- if present, version MUST be v1 }
     *   
     * DigestAlgorithmIdentifier ::= AlgorithmIdentifier,
     * 
     * LDSSecurityObjectVersion :: INTEGER {V0(0)}
     * 
    */ public class LDSSecurityObject extends ASN1Object implements ICAOObjectIdentifiers { public static final int ub_DataGroups = 16; private ASN1Integer version = new ASN1Integer(0); private AlgorithmIdentifier digestAlgorithmIdentifier; private DataGroupHash[] datagroupHash; private LDSVersionInfo versionInfo; public static LDSSecurityObject getInstance( Object obj) { if (obj instanceof LDSSecurityObject) { return (LDSSecurityObject)obj; } else if (obj != null) { return new LDSSecurityObject(ASN1Sequence.getInstance(obj)); } return null; } private LDSSecurityObject( ASN1Sequence seq) { if (seq == null || seq.size() == 0) { throw new IllegalArgumentException("null or empty sequence passed."); } Enumeration e = seq.getObjects(); // version version = ASN1Integer.getInstance(e.nextElement()); // digestAlgorithmIdentifier digestAlgorithmIdentifier = AlgorithmIdentifier.getInstance(e.nextElement()); ASN1Sequence datagroupHashSeq = ASN1Sequence.getInstance(e.nextElement()); if (version.getValue().intValue() == 1) { versionInfo = LDSVersionInfo.getInstance(e.nextElement()); } checkDatagroupHashSeqSize(datagroupHashSeq.size()); datagroupHash = new DataGroupHash[datagroupHashSeq.size()]; for (int i= 0; i< datagroupHashSeq.size();i++) { datagroupHash[i] = DataGroupHash.getInstance(datagroupHashSeq.getObjectAt(i)); } } public LDSSecurityObject( AlgorithmIdentifier digestAlgorithmIdentifier, DataGroupHash[] datagroupHash) { this.version = new ASN1Integer(0); this.digestAlgorithmIdentifier = digestAlgorithmIdentifier; this.datagroupHash = datagroupHash; checkDatagroupHashSeqSize(datagroupHash.length); } public LDSSecurityObject( AlgorithmIdentifier digestAlgorithmIdentifier, DataGroupHash[] datagroupHash, LDSVersionInfo versionInfo) { this.version = new ASN1Integer(1); this.digestAlgorithmIdentifier = digestAlgorithmIdentifier; this.datagroupHash = datagroupHash; this.versionInfo = versionInfo; checkDatagroupHashSeqSize(datagroupHash.length); } private void checkDatagroupHashSeqSize(int size) { if ((size < 2) || (size > ub_DataGroups)) { throw new IllegalArgumentException("wrong size in DataGroupHashValues : not in (2.."+ ub_DataGroups +")"); } } public int getVersion() { return version.getValue().intValue(); } public AlgorithmIdentifier getDigestAlgorithmIdentifier() { return digestAlgorithmIdentifier; } public DataGroupHash[] getDatagroupHash() { return datagroupHash; } public LDSVersionInfo getVersionInfo() { return versionInfo; } public ASN1Primitive toASN1Primitive() { ASN1EncodableVector seq = new ASN1EncodableVector(); seq.add(version); seq.add(digestAlgorithmIdentifier); ASN1EncodableVector seqname = new ASN1EncodableVector(); for (int i = 0; i < datagroupHash.length; i++) { seqname.add(datagroupHash[i]); } seq.add(new DERSequence(seqname)); if (versionInfo != null) { seq.add(versionInfo); } return new DERSequence(seq); } } bouncycastle-1.49.orig/src/org/bouncycastle/asn1/icao/DataGroupHash.java0000644000175000017500000000502011724561172025617 0ustar ebourgebourgpackage org.bouncycastle.asn1.icao; import java.util.Enumeration; import org.bouncycastle.asn1.ASN1EncodableVector; import org.bouncycastle.asn1.ASN1Integer; import org.bouncycastle.asn1.ASN1Object; import org.bouncycastle.asn1.ASN1OctetString; import org.bouncycastle.asn1.ASN1Primitive; import org.bouncycastle.asn1.ASN1Sequence; import org.bouncycastle.asn1.DERSequence; /** * The DataGroupHash object. *
     * DataGroupHash  ::=  SEQUENCE {
     *      dataGroupNumber         DataGroupNumber,
     *      dataGroupHashValue     OCTET STRING }
     * 
     * DataGroupNumber ::= INTEGER {
     *         dataGroup1    (1),
     *         dataGroup1    (2),
     *         dataGroup1    (3),
     *         dataGroup1    (4),
     *         dataGroup1    (5),
     *         dataGroup1    (6),
     *         dataGroup1    (7),
     *         dataGroup1    (8),
     *         dataGroup1    (9),
     *         dataGroup1    (10),
     *         dataGroup1    (11),
     *         dataGroup1    (12),
     *         dataGroup1    (13),
     *         dataGroup1    (14),
     *         dataGroup1    (15),
     *         dataGroup1    (16) }
     * 
     * 
    */ public class DataGroupHash extends ASN1Object { ASN1Integer dataGroupNumber; ASN1OctetString dataGroupHashValue; public static DataGroupHash getInstance( Object obj) { if (obj instanceof DataGroupHash) { return (DataGroupHash)obj; } else if (obj != null) { return new DataGroupHash(ASN1Sequence.getInstance(obj)); } return null; } private DataGroupHash(ASN1Sequence seq) { Enumeration e = seq.getObjects(); // dataGroupNumber dataGroupNumber = ASN1Integer.getInstance(e.nextElement()); // dataGroupHashValue dataGroupHashValue = ASN1OctetString.getInstance(e.nextElement()); } public DataGroupHash( int dataGroupNumber, ASN1OctetString dataGroupHashValue) { this.dataGroupNumber = new ASN1Integer(dataGroupNumber); this.dataGroupHashValue = dataGroupHashValue; } public int getDataGroupNumber() { return dataGroupNumber.getValue().intValue(); } public ASN1OctetString getDataGroupHashValue() { return dataGroupHashValue; } public ASN1Primitive toASN1Primitive() { ASN1EncodableVector seq = new ASN1EncodableVector(); seq.add(dataGroupNumber); seq.add(dataGroupHashValue); return new DERSequence(seq); } } bouncycastle-1.49.orig/src/org/bouncycastle/asn1/icao/CscaMasterList.java0000644000175000017500000000551512151274315026012 0ustar ebourgebourgpackage org.bouncycastle.asn1.icao; import org.bouncycastle.asn1.ASN1EncodableVector; import org.bouncycastle.asn1.ASN1Integer; import org.bouncycastle.asn1.ASN1Object; import org.bouncycastle.asn1.ASN1Primitive; import org.bouncycastle.asn1.ASN1Sequence; import org.bouncycastle.asn1.ASN1Set; import org.bouncycastle.asn1.DERSequence; import org.bouncycastle.asn1.DERSet; import org.bouncycastle.asn1.x509.Certificate; /** * The CscaMasterList object. This object can be wrapped in a * CMSSignedData to be published in LDAP. *

    *

     * CscaMasterList ::= SEQUENCE {
     *   version                CscaMasterListVersion,
     *   certList               SET OF Certificate }
     *
     * CscaMasterListVersion :: INTEGER {v0(0)}
     * 
    */ public class CscaMasterList extends ASN1Object { private ASN1Integer version = new ASN1Integer(0); private Certificate[] certList; public static CscaMasterList getInstance( Object obj) { if (obj instanceof CscaMasterList) { return (CscaMasterList)obj; } else if (obj != null) { return new CscaMasterList(ASN1Sequence.getInstance(obj)); } return null; } private CscaMasterList( ASN1Sequence seq) { if (seq == null || seq.size() == 0) { throw new IllegalArgumentException( "null or empty sequence passed."); } if (seq.size() != 2) { throw new IllegalArgumentException( "Incorrect sequence size: " + seq.size()); } version = ASN1Integer.getInstance(seq.getObjectAt(0)); ASN1Set certSet = ASN1Set.getInstance(seq.getObjectAt(1)); certList = new Certificate[certSet.size()]; for (int i = 0; i < certList.length; i++) { certList[i] = Certificate.getInstance(certSet.getObjectAt(i)); } } public CscaMasterList( Certificate[] certStructs) { certList = copyCertList(certStructs); } public int getVersion() { return version.getValue().intValue(); } public Certificate[] getCertStructs() { return copyCertList(certList); } private Certificate[] copyCertList(Certificate[] orig) { Certificate[] certs = new Certificate[orig.length]; for (int i = 0; i != certs.length; i++) { certs[i] = orig[i]; } return certs; } public ASN1Primitive toASN1Primitive() { ASN1EncodableVector seq = new ASN1EncodableVector(); seq.add(version); ASN1EncodableVector certSet = new ASN1EncodableVector(); for (int i = 0; i < certList.length; i++) { certSet.add(certList[i]); } seq.add(new DERSet(certSet)); return new DERSequence(seq); } } bouncycastle-1.49.orig/src/org/bouncycastle/asn1/icao/ICAOObjectIdentifiers.java0000644000175000017500000000313111624622714027155 0ustar ebourgebourgpackage org.bouncycastle.asn1.icao; import org.bouncycastle.asn1.ASN1ObjectIdentifier; public interface ICAOObjectIdentifiers { // // base id // static final ASN1ObjectIdentifier id_icao = new ASN1ObjectIdentifier("2.23.136"); static final ASN1ObjectIdentifier id_icao_mrtd = id_icao.branch("1"); static final ASN1ObjectIdentifier id_icao_mrtd_security = id_icao_mrtd.branch("1"); // LDS security object, see ICAO Doc 9303-Volume 2-Section IV-A3.2 static final ASN1ObjectIdentifier id_icao_ldsSecurityObject = id_icao_mrtd_security.branch("1"); // CSCA master list, see TR CSCA Countersigning and Master List issuance static final ASN1ObjectIdentifier id_icao_cscaMasterList = id_icao_mrtd_security.branch("2"); static final ASN1ObjectIdentifier id_icao_cscaMasterListSigningKey = id_icao_mrtd_security.branch("3"); // document type list, see draft TR LDS and PKI Maintenance, par. 3.2.1 static final ASN1ObjectIdentifier id_icao_documentTypeList = id_icao_mrtd_security.branch("4"); // Active Authentication protocol, see draft TR LDS and PKI Maintenance, // par. 5.2.2 static final ASN1ObjectIdentifier id_icao_aaProtocolObject = id_icao_mrtd_security.branch("5"); // CSCA name change and key reoll-over, see draft TR LDS and PKI // Maintenance, par. 3.2.1 static final ASN1ObjectIdentifier id_icao_extensions = id_icao_mrtd_security.branch("6"); static final ASN1ObjectIdentifier id_icao_extensions_namechangekeyrollover = id_icao_extensions.branch("1"); } bouncycastle-1.49.orig/src/org/bouncycastle/asn1/icao/package.html0000644000175000017500000000013410363131612024532 0ustar ebourgebourg ICAO ASN.1 classes for electronic passport. bouncycastle-1.49.orig/src/org/bouncycastle/asn1/icao/LDSVersionInfo.java0000644000175000017500000000357112151251423025730 0ustar ebourgebourgpackage org.bouncycastle.asn1.icao; import org.bouncycastle.asn1.ASN1EncodableVector; import org.bouncycastle.asn1.ASN1Object; import org.bouncycastle.asn1.ASN1Primitive; import org.bouncycastle.asn1.ASN1Sequence; import org.bouncycastle.asn1.DERPrintableString; import org.bouncycastle.asn1.DERSequence; public class LDSVersionInfo extends ASN1Object { private DERPrintableString ldsVersion; private DERPrintableString unicodeVersion; public LDSVersionInfo(String ldsVersion, String unicodeVersion) { this.ldsVersion = new DERPrintableString(ldsVersion); this.unicodeVersion = new DERPrintableString(unicodeVersion); } private LDSVersionInfo(ASN1Sequence seq) { if (seq.size() != 2) { throw new IllegalArgumentException("sequence wrong size for LDSVersionInfo"); } this.ldsVersion = DERPrintableString.getInstance(seq.getObjectAt(0)); this.unicodeVersion = DERPrintableString.getInstance(seq.getObjectAt(1)); } public static LDSVersionInfo getInstance(Object obj) { if (obj instanceof LDSVersionInfo) { return (LDSVersionInfo)obj; } else if (obj != null) { return new LDSVersionInfo(ASN1Sequence.getInstance(obj)); } return null; } public String getLdsVersion() { return ldsVersion.getString(); } public String getUnicodeVersion() { return unicodeVersion.getString(); } /** *
         * LDSVersionInfo ::= SEQUENCE {
         *    ldsVersion PRINTABLE STRING
         *    unicodeVersion PRINTABLE STRING
         *  }
         * 
    * @return */ public ASN1Primitive toASN1Primitive() { ASN1EncodableVector v = new ASN1EncodableVector(); v.add(ldsVersion); v.add(unicodeVersion); return new DERSequence(v); } } bouncycastle-1.49.orig/src/org/bouncycastle/asn1/ASN1SequenceParser.java0000644000175000017500000000032111624616767025573 0ustar ebourgebourgpackage org.bouncycastle.asn1; import java.io.IOException; public interface ASN1SequenceParser extends ASN1Encodable, InMemoryRepresentable { ASN1Encodable readObject() throws IOException; } bouncycastle-1.49.orig/src/org/bouncycastle/asn1/DERObjectIdentifier.java0000644000175000017500000002540412151247361025762 0ustar ebourgebourgpackage org.bouncycastle.asn1; import java.io.ByteArrayOutputStream; import java.io.IOException; import java.math.BigInteger; import org.bouncycastle.util.Arrays; public class DERObjectIdentifier extends ASN1Primitive { String identifier; private byte[] body; /** * return an OID from the passed in object * * @throws IllegalArgumentException if the object cannot be converted. */ public static ASN1ObjectIdentifier getInstance( Object obj) { if (obj == null || obj instanceof ASN1ObjectIdentifier) { return (ASN1ObjectIdentifier)obj; } if (obj instanceof DERObjectIdentifier) { return new ASN1ObjectIdentifier(((DERObjectIdentifier)obj).getId()); } if (obj instanceof ASN1Encodable && ((ASN1Encodable)obj).toASN1Primitive() instanceof ASN1ObjectIdentifier) { return (ASN1ObjectIdentifier)((ASN1Encodable)obj).toASN1Primitive(); } if (obj instanceof byte[]) { return ASN1ObjectIdentifier.fromOctetString((byte[])obj); } throw new IllegalArgumentException("illegal object in getInstance: " + obj.getClass().getName()); } /** * return an Object Identifier from a tagged object. * * @param obj the tagged object holding the object we want * @param explicit true if the object is meant to be explicitly * tagged false otherwise. * @throws IllegalArgumentException if the tagged object cannot * be converted. */ public static ASN1ObjectIdentifier getInstance( ASN1TaggedObject obj, boolean explicit) { ASN1Primitive o = obj.getObject(); if (explicit || o instanceof DERObjectIdentifier) { return getInstance(o); } else { return ASN1ObjectIdentifier.fromOctetString(ASN1OctetString.getInstance(obj.getObject()).getOctets()); } } private static final long LONG_LIMIT = (Long.MAX_VALUE >> 7) - 0x7f; DERObjectIdentifier( byte[] bytes) { StringBuffer objId = new StringBuffer(); long value = 0; BigInteger bigValue = null; boolean first = true; for (int i = 0; i != bytes.length; i++) { int b = bytes[i] & 0xff; if (value <= LONG_LIMIT) { value += (b & 0x7f); if ((b & 0x80) == 0) // end of number reached { if (first) { if (value < 40) { objId.append('0'); } else if (value < 80) { objId.append('1'); value -= 40; } else { objId.append('2'); value -= 80; } first = false; } objId.append('.'); objId.append(value); value = 0; } else { value <<= 7; } } else { if (bigValue == null) { bigValue = BigInteger.valueOf(value); } bigValue = bigValue.or(BigInteger.valueOf(b & 0x7f)); if ((b & 0x80) == 0) { if (first) { objId.append('2'); bigValue = bigValue.subtract(BigInteger.valueOf(80)); first = false; } objId.append('.'); objId.append(bigValue); bigValue = null; value = 0; } else { bigValue = bigValue.shiftLeft(7); } } } this.identifier = objId.toString(); this.body = Arrays.clone(bytes); } public DERObjectIdentifier( String identifier) { if (identifier == null) { throw new IllegalArgumentException("'identifier' cannot be null"); } if (!isValidIdentifier(identifier)) { throw new IllegalArgumentException("string " + identifier + " not an OID"); } this.identifier = identifier; } DERObjectIdentifier(DERObjectIdentifier oid, String branchID) { if (!isValidBranchID(branchID, 0)) { throw new IllegalArgumentException("string " + branchID + " not a valid OID branch"); } this.identifier = oid.getId() + "." + branchID; } public String getId() { return identifier; } private void writeField( ByteArrayOutputStream out, long fieldValue) { byte[] result = new byte[9]; int pos = 8; result[pos] = (byte)((int)fieldValue & 0x7f); while (fieldValue >= (1L << 7)) { fieldValue >>= 7; result[--pos] = (byte)((int)fieldValue & 0x7f | 0x80); } out.write(result, pos, 9 - pos); } private void writeField( ByteArrayOutputStream out, BigInteger fieldValue) { int byteCount = (fieldValue.bitLength() + 6) / 7; if (byteCount == 0) { out.write(0); } else { BigInteger tmpValue = fieldValue; byte[] tmp = new byte[byteCount]; for (int i = byteCount - 1; i >= 0; i--) { tmp[i] = (byte)((tmpValue.intValue() & 0x7f) | 0x80); tmpValue = tmpValue.shiftRight(7); } tmp[byteCount - 1] &= 0x7f; out.write(tmp, 0, tmp.length); } } private void doOutput(ByteArrayOutputStream aOut) { OIDTokenizer tok = new OIDTokenizer(identifier); int first = Integer.parseInt(tok.nextToken()) * 40; String secondToken = tok.nextToken(); if (secondToken.length() <= 18) { writeField(aOut, first + Long.parseLong(secondToken)); } else { writeField(aOut, new BigInteger(secondToken).add(BigInteger.valueOf(first))); } while (tok.hasMoreTokens()) { String token = tok.nextToken(); if (token.length() <= 18) { writeField(aOut, Long.parseLong(token)); } else { writeField(aOut, new BigInteger(token)); } } } protected synchronized byte[] getBody() { if (body == null) { ByteArrayOutputStream bOut = new ByteArrayOutputStream(); doOutput(bOut); body = bOut.toByteArray(); } return body; } boolean isConstructed() { return false; } int encodedLength() throws IOException { int length = getBody().length; return 1 + StreamUtil.calculateBodyLength(length) + length; } void encode( ASN1OutputStream out) throws IOException { byte[] enc = getBody(); out.write(BERTags.OBJECT_IDENTIFIER); out.writeLength(enc.length); out.write(enc); } public int hashCode() { return identifier.hashCode(); } boolean asn1Equals( ASN1Primitive o) { if (!(o instanceof DERObjectIdentifier)) { return false; } return identifier.equals(((DERObjectIdentifier)o).identifier); } public String toString() { return getId(); } private static boolean isValidBranchID( String branchID, int start) { boolean periodAllowed = false; int pos = branchID.length(); while (--pos >= start) { char ch = branchID.charAt(pos); // TODO Leading zeroes? if ('0' <= ch && ch <= '9') { periodAllowed = true; continue; } if (ch == '.') { if (!periodAllowed) { return false; } periodAllowed = false; continue; } return false; } return periodAllowed; } private static boolean isValidIdentifier( String identifier) { if (identifier.length() < 3 || identifier.charAt(1) != '.') { return false; } char first = identifier.charAt(0); if (first < '0' || first > '2') { return false; } return isValidBranchID(identifier, 2); } private static ASN1ObjectIdentifier[][] cache = new ASN1ObjectIdentifier[256][]; static ASN1ObjectIdentifier fromOctetString(byte[] enc) { if (enc.length < 3) { return new ASN1ObjectIdentifier(enc); } int idx1 = enc[enc.length - 2] & 0xff; // in this case top bit is always zero int idx2 = enc[enc.length - 1] & 0x7f; ASN1ObjectIdentifier possibleMatch; synchronized (cache) { ASN1ObjectIdentifier[] first = cache[idx1]; if (first == null) { first = cache[idx1] = new ASN1ObjectIdentifier[128]; } possibleMatch = first[idx2]; if (possibleMatch == null) { return first[idx2] = new ASN1ObjectIdentifier(enc); } if (Arrays.areEqual(enc, possibleMatch.getBody())) { return possibleMatch; } idx1 = (idx1 + 1) & 0xff; first = cache[idx1]; if (first == null) { first = cache[idx1] = new ASN1ObjectIdentifier[128]; } possibleMatch = first[idx2]; if (possibleMatch == null) { return first[idx2] = new ASN1ObjectIdentifier(enc); } if (Arrays.areEqual(enc, possibleMatch.getBody())) { return possibleMatch; } idx2 = (idx2 + 1) & 0x7f; possibleMatch = first[idx2]; if (possibleMatch == null) { return first[idx2] = new ASN1ObjectIdentifier(enc); } } if (Arrays.areEqual(enc, possibleMatch.getBody())) { return possibleMatch; } return new ASN1ObjectIdentifier(enc); } } bouncycastle-1.49.orig/src/org/bouncycastle/asn1/ASN1TaggedObject.java0000644000175000017500000001373611730460711025166 0ustar ebourgebourgpackage org.bouncycastle.asn1; import java.io.IOException; /** * ASN.1 TaggedObject - in ASN.1 notation this is any object preceded by * a [n] where n is some number - these are assumed to follow the construction * rules (as with sequences). */ public abstract class ASN1TaggedObject extends ASN1Primitive implements ASN1TaggedObjectParser { int tagNo; boolean empty = false; boolean explicit = true; ASN1Encodable obj = null; static public ASN1TaggedObject getInstance( ASN1TaggedObject obj, boolean explicit) { if (explicit) { return (ASN1TaggedObject)obj.getObject(); } throw new IllegalArgumentException("implicitly tagged tagged object"); } static public ASN1TaggedObject getInstance( Object obj) { if (obj == null || obj instanceof ASN1TaggedObject) { return (ASN1TaggedObject)obj; } else if (obj instanceof byte[]) { try { return ASN1TaggedObject.getInstance(fromByteArray((byte[])obj)); } catch (IOException e) { throw new IllegalArgumentException("failed to construct tagged object from byte[]: " + e.getMessage()); } } throw new IllegalArgumentException("unknown object in getInstance: " + obj.getClass().getName()); } /** * Create a tagged object with the style given by the value of explicit. *

    * If the object implements ASN1Choice the tag style will always be changed * to explicit in accordance with the ASN.1 encoding rules. *

    * @param explicit true if the object is explicitly tagged. * @param tagNo the tag number for this object. * @param obj the tagged object. */ public ASN1TaggedObject( boolean explicit, int tagNo, ASN1Encodable obj) { if (obj instanceof ASN1Choice) { this.explicit = true; } else { this.explicit = explicit; } this.tagNo = tagNo; if (this.explicit) { this.obj = obj; } else { ASN1Primitive prim = obj.toASN1Primitive(); if (prim instanceof ASN1Set) { ASN1Set s = null; } this.obj = obj; } } boolean asn1Equals( ASN1Primitive o) { if (!(o instanceof ASN1TaggedObject)) { return false; } ASN1TaggedObject other = (ASN1TaggedObject)o; if (tagNo != other.tagNo || empty != other.empty || explicit != other.explicit) { return false; } if(obj == null) { if (other.obj != null) { return false; } } else { if (!(obj.toASN1Primitive().equals(other.obj.toASN1Primitive()))) { return false; } } return true; } public int hashCode() { int code = tagNo; // TODO: actually this is wrong - the problem is that a re-encoded // object may end up with a different hashCode due to implicit // tagging. As implicit tagging is ambiguous if a sequence is involved // it seems the only correct method for both equals and hashCode is to // compare the encodings... if (obj != null) { code ^= obj.hashCode(); } return code; } public int getTagNo() { return tagNo; } /** * return whether or not the object may be explicitly tagged. *

    * Note: if the object has been read from an input stream, the only * time you can be sure if isExplicit is returning the true state of * affairs is if it returns false. An implicitly tagged object may appear * to be explicitly tagged, so you need to understand the context under * which the reading was done as well, see getObject below. */ public boolean isExplicit() { return explicit; } public boolean isEmpty() { return empty; } /** * return whatever was following the tag. *

    * Note: tagged objects are generally context dependent if you're * trying to extract a tagged object you should be going via the * appropriate getInstance method. */ public ASN1Primitive getObject() { if (obj != null) { return obj.toASN1Primitive(); } return null; } /** * Return the object held in this tagged object as a parser assuming it has * the type of the passed in tag. If the object doesn't have a parser * associated with it, the base object is returned. */ public ASN1Encodable getObjectParser( int tag, boolean isExplicit) { switch (tag) { case BERTags.SET: return ASN1Set.getInstance(this, isExplicit).parser(); case BERTags.SEQUENCE: return ASN1Sequence.getInstance(this, isExplicit).parser(); case BERTags.OCTET_STRING: return ASN1OctetString.getInstance(this, isExplicit).parser(); } if (isExplicit) { return getObject(); } throw new RuntimeException("implicit tagging not implemented for tag: " + tag); } public ASN1Primitive getLoadedObject() { return this.toASN1Primitive(); } ASN1Primitive toDERObject() { return new DERTaggedObject(explicit, tagNo, obj); } ASN1Primitive toDLObject() { return new DLTaggedObject(explicit, tagNo, obj); } abstract void encode(ASN1OutputStream out) throws IOException; public String toString() { return "[" + tagNo + "]" + obj; } } bouncycastle-1.49.orig/src/org/bouncycastle/asn1/BEROctetStringGenerator.java0000644000175000017500000000462611624615370026671 0ustar ebourgebourgpackage org.bouncycastle.asn1; import java.io.IOException; import java.io.OutputStream; public class BEROctetStringGenerator extends BERGenerator { public BEROctetStringGenerator(OutputStream out) throws IOException { super(out); writeBERHeader(BERTags.CONSTRUCTED | BERTags.OCTET_STRING); } public BEROctetStringGenerator( OutputStream out, int tagNo, boolean isExplicit) throws IOException { super(out, tagNo, isExplicit); writeBERHeader(BERTags.CONSTRUCTED | BERTags.OCTET_STRING); } public OutputStream getOctetOutputStream() { return getOctetOutputStream(new byte[1000]); // limit for CER encoding. } public OutputStream getOctetOutputStream( byte[] buf) { return new BufferedBEROctetStream(buf); } private class BufferedBEROctetStream extends OutputStream { private byte[] _buf; private int _off; private DEROutputStream _derOut; BufferedBEROctetStream( byte[] buf) { _buf = buf; _off = 0; _derOut = new DEROutputStream(_out); } public void write( int b) throws IOException { _buf[_off++] = (byte)b; if (_off == _buf.length) { DEROctetString.encode(_derOut, _buf); _off = 0; } } public void write(byte[] b, int off, int len) throws IOException { while (len > 0) { int numToCopy = Math.min(len, _buf.length - _off); System.arraycopy(b, off, _buf, _off, numToCopy); _off += numToCopy; if (_off < _buf.length) { break; } DEROctetString.encode(_derOut, _buf); _off = 0; off += numToCopy; len -= numToCopy; } } public void close() throws IOException { if (_off != 0) { byte[] bytes = new byte[_off]; System.arraycopy(_buf, 0, bytes, 0, _off); DEROctetString.encode(_derOut, bytes); } writeBEREnd(); } } } bouncycastle-1.49.orig/src/org/bouncycastle/asn1/microsoft/0000755000175000017500000000000012152033551023346 5ustar ebourgebourgbouncycastle-1.49.orig/src/org/bouncycastle/asn1/microsoft/MicrosoftObjectIdentifiers.java0000644000175000017500000000153111624622714031503 0ustar ebourgebourgpackage org.bouncycastle.asn1.microsoft; import org.bouncycastle.asn1.ASN1ObjectIdentifier; public interface MicrosoftObjectIdentifiers { // // Microsoft // iso(1) identified-organization(3) dod(6) internet(1) private(4) enterprise(1) microsoft(311) // static final ASN1ObjectIdentifier microsoft = new ASN1ObjectIdentifier("1.3.6.1.4.1.311"); static final ASN1ObjectIdentifier microsoftCertTemplateV1 = microsoft.branch("20.2"); static final ASN1ObjectIdentifier microsoftCaVersion = microsoft.branch("21.1"); static final ASN1ObjectIdentifier microsoftPrevCaCertHash = microsoft.branch("21.2"); static final ASN1ObjectIdentifier microsoftCertTemplateV2 = microsoft.branch("21.7"); static final ASN1ObjectIdentifier microsoftAppPolicies = microsoft.branch("21.10"); } bouncycastle-1.49.orig/src/org/bouncycastle/asn1/DERSequenceParser.java0000644000175000017500000000135511624622072025475 0ustar ebourgebourgpackage org.bouncycastle.asn1; import java.io.IOException; public class DERSequenceParser implements ASN1SequenceParser { private ASN1StreamParser _parser; DERSequenceParser(ASN1StreamParser parser) { this._parser = parser; } public ASN1Encodable readObject() throws IOException { return _parser.readObject(); } public ASN1Primitive getLoadedObject() throws IOException { return new DERSequence(_parser.readVector()); } public ASN1Primitive toASN1Primitive() { try { return getLoadedObject(); } catch (IOException e) { throw new IllegalStateException(e.getMessage()); } } } bouncycastle-1.49.orig/src/org/bouncycastle/asn1/DERApplicationSpecific.java0000644000175000017500000001603111703177363026464 0ustar ebourgebourgpackage org.bouncycastle.asn1; import java.io.ByteArrayOutputStream; import java.io.IOException; import org.bouncycastle.util.Arrays; /** * Base class for an application specific object */ public class DERApplicationSpecific extends ASN1Primitive { private final boolean isConstructed; private final int tag; private final byte[] octets; DERApplicationSpecific( boolean isConstructed, int tag, byte[] octets) { this.isConstructed = isConstructed; this.tag = tag; this.octets = octets; } public DERApplicationSpecific( int tag, byte[] octets) { this(false, tag, octets); } public DERApplicationSpecific( int tag, ASN1Encodable object) throws IOException { this(true, tag, object); } public DERApplicationSpecific( boolean explicit, int tag, ASN1Encodable object) throws IOException { ASN1Primitive primitive = object.toASN1Primitive(); byte[] data = primitive.getEncoded(ASN1Encoding.DER); this.isConstructed = explicit || (primitive instanceof ASN1Set || primitive instanceof ASN1Sequence); this.tag = tag; if (explicit) { this.octets = data; } else { int lenBytes = getLengthOfHeader(data); byte[] tmp = new byte[data.length - lenBytes]; System.arraycopy(data, lenBytes, tmp, 0, tmp.length); this.octets = tmp; } } public DERApplicationSpecific(int tagNo, ASN1EncodableVector vec) { this.tag = tagNo; this.isConstructed = true; ByteArrayOutputStream bOut = new ByteArrayOutputStream(); for (int i = 0; i != vec.size(); i++) { try { bOut.write(((ASN1Object)vec.get(i)).getEncoded(ASN1Encoding.DER)); } catch (IOException e) { throw new ASN1ParsingException("malformed object: " + e, e); } } this.octets = bOut.toByteArray(); } public static DERApplicationSpecific getInstance(Object obj) { if (obj == null || obj instanceof DERApplicationSpecific) { return (DERApplicationSpecific)obj; } else if (obj instanceof byte[]) { try { return DERApplicationSpecific.getInstance(ASN1Primitive.fromByteArray((byte[])obj)); } catch (IOException e) { throw new IllegalArgumentException("failed to construct object from byte[]: " + e.getMessage()); } } else if (obj instanceof ASN1Encodable) { ASN1Primitive primitive = ((ASN1Encodable)obj).toASN1Primitive(); if (primitive instanceof ASN1Sequence) { return (DERApplicationSpecific)primitive; } } throw new IllegalArgumentException("unknown object in getInstance: " + obj.getClass().getName()); } private int getLengthOfHeader(byte[] data) { int length = data[1] & 0xff; // TODO: assumes 1 byte tag if (length == 0x80) { return 2; // indefinite-length encoding } if (length > 127) { int size = length & 0x7f; // Note: The invalid long form "0xff" (see X.690 8.1.3.5c) will be caught here if (size > 4) { throw new IllegalStateException("DER length more than 4 bytes: " + size); } return size + 2; } return 2; } public boolean isConstructed() { return isConstructed; } public byte[] getContents() { return octets; } public int getApplicationTag() { return tag; } /** * Return the enclosed object assuming explicit tagging. * * @return the resulting object * @throws IOException if reconstruction fails. */ public ASN1Primitive getObject() throws IOException { return new ASN1InputStream(getContents()).readObject(); } /** * Return the enclosed object assuming implicit tagging. * * @param derTagNo the type tag that should be applied to the object's contents. * @return the resulting object * @throws IOException if reconstruction fails. */ public ASN1Primitive getObject(int derTagNo) throws IOException { if (derTagNo >= 0x1f) { throw new IOException("unsupported tag number"); } byte[] orig = this.getEncoded(); byte[] tmp = replaceTagNumber(derTagNo, orig); if ((orig[0] & BERTags.CONSTRUCTED) != 0) { tmp[0] |= BERTags.CONSTRUCTED; } return new ASN1InputStream(tmp).readObject(); } int encodedLength() throws IOException { return StreamUtil.calculateTagLength(tag) + StreamUtil.calculateBodyLength(octets.length) + octets.length; } /* (non-Javadoc) * @see org.bouncycastle.asn1.ASN1Primitive#encode(org.bouncycastle.asn1.DEROutputStream) */ void encode(ASN1OutputStream out) throws IOException { int classBits = BERTags.APPLICATION; if (isConstructed) { classBits |= BERTags.CONSTRUCTED; } out.writeEncoded(classBits, tag, octets); } boolean asn1Equals( ASN1Primitive o) { if (!(o instanceof DERApplicationSpecific)) { return false; } DERApplicationSpecific other = (DERApplicationSpecific)o; return isConstructed == other.isConstructed && tag == other.tag && Arrays.areEqual(octets, other.octets); } public int hashCode() { return (isConstructed ? 1 : 0) ^ tag ^ Arrays.hashCode(octets); } private byte[] replaceTagNumber(int newTag, byte[] input) throws IOException { int tagNo = input[0] & 0x1f; int index = 1; // // with tagged object tag number is bottom 5 bits, or stored at the start of the content // if (tagNo == 0x1f) { tagNo = 0; int b = input[index++] & 0xff; // X.690-0207 8.1.2.4.2 // "c) bits 7 to 1 of the first subsequent octet shall not all be zero." if ((b & 0x7f) == 0) // Note: -1 will pass { throw new ASN1ParsingException("corrupted stream - invalid high tag number found"); } while ((b >= 0) && ((b & 0x80) != 0)) { tagNo |= (b & 0x7f); tagNo <<= 7; b = input[index++] & 0xff; } tagNo |= (b & 0x7f); } byte[] tmp = new byte[input.length - index + 1]; System.arraycopy(input, index, tmp, 1, tmp.length - 1); tmp[0] = (byte)newTag; return tmp; } } bouncycastle-1.49.orig/src/org/bouncycastle/asn1/ASN1Choice.java0000644000175000017500000000070411624614575024040 0ustar ebourgebourgpackage org.bouncycastle.asn1; /** * Marker interface for CHOICE objects - if you implement this in a role your * own object any attempt to tag the object implicitly will convert the tag to * an explicit one as the encoding rules require. *

    * If you use this interface your class should also implement the getInstance * pattern which takes a tag object and the tagging mode used. */ public interface ASN1Choice { // marker interface } bouncycastle-1.49.orig/src/org/bouncycastle/asn1/DLTaggedObject.java0000644000175000017500000000536611703205061024756 0ustar ebourgebourgpackage org.bouncycastle.asn1; import java.io.IOException; /** * Definite Length TaggedObject - in ASN.1 notation this is any object preceded by * a [n] where n is some number - these are assumed to follow the construction * rules (as with sequences). */ public class DLTaggedObject extends ASN1TaggedObject { private static final byte[] ZERO_BYTES = new byte[0]; /** * @param explicit true if an explicitly tagged object. * @param tagNo the tag number for this object. * @param obj the tagged object. */ public DLTaggedObject( boolean explicit, int tagNo, ASN1Encodable obj) { super(explicit, tagNo, obj); } boolean isConstructed() { if (!empty) { if (explicit) { return true; } else { ASN1Primitive primitive = obj.toASN1Primitive().toDLObject(); return primitive.isConstructed(); } } else { return true; } } int encodedLength() throws IOException { if (!empty) { int length = obj.toASN1Primitive().toDLObject().encodedLength(); if (explicit) { return StreamUtil.calculateTagLength(tagNo) + StreamUtil.calculateBodyLength(length) + length; } else { // header length already in calculation length = length - 1; return StreamUtil.calculateTagLength(tagNo) + length; } } else { return StreamUtil.calculateTagLength(tagNo) + 1; } } void encode( ASN1OutputStream out) throws IOException { if (!empty) { ASN1Primitive primitive = obj.toASN1Primitive().toDLObject(); if (explicit) { out.writeTag(BERTags.CONSTRUCTED | BERTags.TAGGED, tagNo); out.writeLength(primitive.encodedLength()); out.writeObject(primitive); } else { // // need to mark constructed types... // int flags; if (primitive.isConstructed()) { flags = BERTags.CONSTRUCTED | BERTags.TAGGED; } else { flags = BERTags.TAGGED; } out.writeTag(flags, tagNo); out.writeImplicitObject(primitive); } } else { out.writeEncoded(BERTags.CONSTRUCTED | BERTags.TAGGED, tagNo, ZERO_BYTES); } } } bouncycastle-1.49.orig/src/org/bouncycastle/asn1/LazyEncodedSequence.java0000644000175000017500000000375711703447326026124 0ustar ebourgebourgpackage org.bouncycastle.asn1; import java.io.IOException; import java.util.Enumeration; /** * Note: this class is for processing DER/DL encoded sequences only. */ class LazyEncodedSequence extends ASN1Sequence { private byte[] encoded; LazyEncodedSequence( byte[] encoded) throws IOException { this.encoded = encoded; } private void parse() { Enumeration en = new LazyConstructionEnumeration(encoded); while (en.hasMoreElements()) { seq.addElement(en.nextElement()); } encoded = null; } public synchronized ASN1Encodable getObjectAt(int index) { if (encoded != null) { parse(); } return super.getObjectAt(index); } public synchronized Enumeration getObjects() { if (encoded == null) { return super.getObjects(); } return new LazyConstructionEnumeration(encoded); } public synchronized int size() { if (encoded != null) { parse(); } return super.size(); } ASN1Primitive toDERObject() { if (encoded != null) { parse(); } return super.toDERObject(); } ASN1Primitive toDLObject() { if (encoded != null) { parse(); } return super.toDLObject(); } int encodedLength() throws IOException { if (encoded != null) { return 1 + StreamUtil.calculateBodyLength(encoded.length) + encoded.length; } else { return super.toDLObject().encodedLength(); } } void encode( ASN1OutputStream out) throws IOException { if (encoded != null) { out.writeEncoded(BERTags.SEQUENCE | BERTags.CONSTRUCTED, encoded); } else { super.toDLObject().encode(out); } } } bouncycastle-1.49.orig/src/org/bouncycastle/asn1/DefiniteLengthInputStream.java0000644000175000017500000000426411741406451027305 0ustar ebourgebourgpackage org.bouncycastle.asn1; import java.io.EOFException; import java.io.IOException; import java.io.InputStream; import org.bouncycastle.util.io.Streams; class DefiniteLengthInputStream extends LimitedInputStream { private static final byte[] EMPTY_BYTES = new byte[0]; private final int _originalLength; private int _remaining; DefiniteLengthInputStream( InputStream in, int length) { super(in, length); if (length < 0) { throw new IllegalArgumentException("negative lengths not allowed"); } this._originalLength = length; this._remaining = length; if (length == 0) { setParentEofDetect(true); } } int getRemaining() { return _remaining; } public int read() throws IOException { if (_remaining == 0) { return -1; } int b = _in.read(); if (b < 0) { throw new EOFException("DEF length " + _originalLength + " object truncated by " + _remaining); } if (--_remaining == 0) { setParentEofDetect(true); } return b; } public int read(byte[] buf, int off, int len) throws IOException { if (_remaining == 0) { return -1; } int toRead = Math.min(len, _remaining); int numRead = _in.read(buf, off, toRead); if (numRead < 0) { throw new EOFException("DEF length " + _originalLength + " object truncated by " + _remaining); } if ((_remaining -= numRead) == 0) { setParentEofDetect(true); } return numRead; } byte[] toByteArray() throws IOException { if (_remaining == 0) { return EMPTY_BYTES; } byte[] bytes = new byte[_remaining]; if ((_remaining -= Streams.readFully(_in, bytes)) != 0) { throw new EOFException("DEF length " + _originalLength + " object truncated by " + _remaining); } setParentEofDetect(true); return bytes; } } bouncycastle-1.49.orig/src/org/bouncycastle/asn1/DEROctetString.java0000644000175000017500000000167211703177363025025 0ustar ebourgebourgpackage org.bouncycastle.asn1; import java.io.IOException; public class DEROctetString extends ASN1OctetString { /** * @param string the octets making up the octet string. */ public DEROctetString( byte[] string) { super(string); } public DEROctetString( ASN1Encodable obj) throws IOException { super(obj.toASN1Primitive().getEncoded(ASN1Encoding.DER)); } boolean isConstructed() { return false; } int encodedLength() { return 1 + StreamUtil.calculateBodyLength(string.length) + string.length; } void encode( ASN1OutputStream out) throws IOException { out.writeEncoded(BERTags.OCTET_STRING, string); } static void encode( DEROutputStream derOut, byte[] bytes) throws IOException { derOut.writeEncoded(BERTags.OCTET_STRING, bytes); } } bouncycastle-1.49.orig/src/org/bouncycastle/asn1/mozilla/0000755000175000017500000000000012152033551023010 5ustar ebourgebourgbouncycastle-1.49.orig/src/org/bouncycastle/asn1/mozilla/package.html0000644000175000017500000000015510262753175025305 0ustar ebourgebourg Support classes useful for encoding objects used by mozilla. bouncycastle-1.49.orig/src/org/bouncycastle/asn1/mozilla/PublicKeyAndChallenge.java0000644000175000017500000000277411725237756030024 0ustar ebourgebourgpackage org.bouncycastle.asn1.mozilla; import org.bouncycastle.asn1.ASN1Object; import org.bouncycastle.asn1.ASN1Primitive; import org.bouncycastle.asn1.ASN1Sequence; import org.bouncycastle.asn1.DERIA5String; import org.bouncycastle.asn1.x509.SubjectPublicKeyInfo; /** * This is designed to parse * the PublicKeyAndChallenge created by the KEYGEN tag included by * Mozilla based browsers. *

     *  PublicKeyAndChallenge ::= SEQUENCE {
     *    spki SubjectPublicKeyInfo,
     *    challenge IA5STRING
     *  }
     *
     *  
    */ public class PublicKeyAndChallenge extends ASN1Object { private ASN1Sequence pkacSeq; private SubjectPublicKeyInfo spki; private DERIA5String challenge; public static PublicKeyAndChallenge getInstance(Object obj) { if (obj instanceof PublicKeyAndChallenge) { return (PublicKeyAndChallenge)obj; } else if (obj != null) { return new PublicKeyAndChallenge(ASN1Sequence.getInstance(obj)); } return null; } private PublicKeyAndChallenge(ASN1Sequence seq) { pkacSeq = seq; spki = SubjectPublicKeyInfo.getInstance(seq.getObjectAt(0)); challenge = DERIA5String.getInstance(seq.getObjectAt(1)); } public ASN1Primitive toASN1Primitive() { return pkacSeq; } public SubjectPublicKeyInfo getSubjectPublicKeyInfo() { return spki; } public DERIA5String getChallenge() { return challenge; } } bouncycastle-1.49.orig/src/org/bouncycastle/asn1/LimitedInputStream.java0000644000175000017500000000121611625105237025774 0ustar ebourgebourgpackage org.bouncycastle.asn1; import java.io.InputStream; abstract class LimitedInputStream extends InputStream { protected final InputStream _in; private int _limit; LimitedInputStream( InputStream in, int limit) { this._in = in; this._limit = limit; } int getRemaining() { // TODO: maybe one day this can become more accurate return _limit; } protected void setParentEofDetect(boolean on) { if (_in instanceof IndefiniteLengthInputStream) { ((IndefiniteLengthInputStream)_in).setEofOn00(on); } } } bouncycastle-1.49.orig/src/org/bouncycastle/asn1/ASN1OctetStringParser.java0000644000175000017500000000030211624650351026252 0ustar ebourgebourgpackage org.bouncycastle.asn1; import java.io.InputStream; public interface ASN1OctetStringParser extends ASN1Encodable, InMemoryRepresentable { public InputStream getOctetStream(); } bouncycastle-1.49.orig/src/org/bouncycastle/asn1/pkcs/0000755000175000017500000000000012152033551022301 5ustar ebourgebourgbouncycastle-1.49.orig/src/org/bouncycastle/asn1/pkcs/ContentInfo.java0000644000175000017500000000453311730257757025420 0ustar ebourgebourgpackage org.bouncycastle.asn1.pkcs; import java.util.Enumeration; import org.bouncycastle.asn1.ASN1Encodable; import org.bouncycastle.asn1.ASN1EncodableVector; import org.bouncycastle.asn1.ASN1Object; import org.bouncycastle.asn1.ASN1ObjectIdentifier; import org.bouncycastle.asn1.ASN1Primitive; import org.bouncycastle.asn1.ASN1Sequence; import org.bouncycastle.asn1.ASN1TaggedObject; import org.bouncycastle.asn1.BERSequence; import org.bouncycastle.asn1.BERTaggedObject; import org.bouncycastle.asn1.DLSequence; public class ContentInfo extends ASN1Object implements PKCSObjectIdentifiers { private ASN1ObjectIdentifier contentType; private ASN1Encodable content; private boolean isBer = true; public static ContentInfo getInstance( Object obj) { if (obj instanceof ContentInfo) { return (ContentInfo)obj; } if (obj != null) { return new ContentInfo(ASN1Sequence.getInstance(obj)); } return null; } private ContentInfo( ASN1Sequence seq) { Enumeration e = seq.getObjects(); contentType = (ASN1ObjectIdentifier)e.nextElement(); if (e.hasMoreElements()) { content = ((ASN1TaggedObject)e.nextElement()).getObject(); } isBer = seq instanceof BERSequence; } public ContentInfo( ASN1ObjectIdentifier contentType, ASN1Encodable content) { this.contentType = contentType; this.content = content; } public ASN1ObjectIdentifier getContentType() { return contentType; } public ASN1Encodable getContent() { return content; } /** * Produce an object suitable for an ASN1OutputStream. *
         * ContentInfo ::= SEQUENCE {
         *          contentType ContentType,
         *          content
         *          [0] EXPLICIT ANY DEFINED BY contentType OPTIONAL }
         * 
    */ public ASN1Primitive toASN1Primitive() { ASN1EncodableVector v = new ASN1EncodableVector(); v.add(contentType); if (content != null) { v.add(new BERTaggedObject(true, 0, content)); } if (isBer) { return new BERSequence(v); } else { return new DLSequence(v); } } } bouncycastle-1.49.orig/src/org/bouncycastle/asn1/pkcs/PBKDF2Params.java0000644000175000017500000000447612151251423025232 0ustar ebourgebourgpackage org.bouncycastle.asn1.pkcs; import java.math.BigInteger; import java.util.Enumeration; import org.bouncycastle.asn1.ASN1EncodableVector; import org.bouncycastle.asn1.ASN1Integer; import org.bouncycastle.asn1.ASN1Object; import org.bouncycastle.asn1.ASN1OctetString; import org.bouncycastle.asn1.ASN1Primitive; import org.bouncycastle.asn1.ASN1Sequence; import org.bouncycastle.asn1.DEROctetString; import org.bouncycastle.asn1.DERSequence; public class PBKDF2Params extends ASN1Object { private ASN1OctetString octStr; private ASN1Integer iterationCount; private ASN1Integer keyLength; public static PBKDF2Params getInstance( Object obj) { if (obj instanceof PBKDF2Params) { return (PBKDF2Params)obj; } if (obj != null) { return new PBKDF2Params(ASN1Sequence.getInstance(obj)); } return null; } public PBKDF2Params( byte[] salt, int iterationCount) { this.octStr = new DEROctetString(salt); this.iterationCount = new ASN1Integer(iterationCount); } public PBKDF2Params( byte[] salt, int iterationCount, int keyLength) { this(salt, iterationCount); this.keyLength = new ASN1Integer(keyLength); } private PBKDF2Params( ASN1Sequence seq) { Enumeration e = seq.getObjects(); octStr = (ASN1OctetString)e.nextElement(); iterationCount = (ASN1Integer)e.nextElement(); if (e.hasMoreElements()) { keyLength = (ASN1Integer)e.nextElement(); } else { keyLength = null; } } public byte[] getSalt() { return octStr.getOctets(); } public BigInteger getIterationCount() { return iterationCount.getValue(); } public BigInteger getKeyLength() { if (keyLength != null) { return keyLength.getValue(); } return null; } public ASN1Primitive toASN1Primitive() { ASN1EncodableVector v = new ASN1EncodableVector(); v.add(octStr); v.add(iterationCount); if (keyLength != null) { v.add(keyLength); } return new DERSequence(v); } } bouncycastle-1.49.orig/src/org/bouncycastle/asn1/pkcs/PBEParameter.java0000644000175000017500000000325611725272035025430 0ustar ebourgebourgpackage org.bouncycastle.asn1.pkcs; import java.math.BigInteger; import org.bouncycastle.asn1.ASN1EncodableVector; import org.bouncycastle.asn1.ASN1Integer; import org.bouncycastle.asn1.ASN1Object; import org.bouncycastle.asn1.ASN1OctetString; import org.bouncycastle.asn1.ASN1Primitive; import org.bouncycastle.asn1.ASN1Sequence; import org.bouncycastle.asn1.DEROctetString; import org.bouncycastle.asn1.DERSequence; public class PBEParameter extends ASN1Object { ASN1Integer iterations; ASN1OctetString salt; public PBEParameter( byte[] salt, int iterations) { if (salt.length != 8) { throw new IllegalArgumentException("salt length must be 8"); } this.salt = new DEROctetString(salt); this.iterations = new ASN1Integer(iterations); } private PBEParameter( ASN1Sequence seq) { salt = (ASN1OctetString)seq.getObjectAt(0); iterations = (ASN1Integer)seq.getObjectAt(1); } public static PBEParameter getInstance( Object obj) { if (obj instanceof PBEParameter) { return (PBEParameter)obj; } else if (obj != null) { return new PBEParameter(ASN1Sequence.getInstance(obj)); } return null; } public BigInteger getIterationCount() { return iterations.getValue(); } public byte[] getSalt() { return salt.getOctets(); } public ASN1Primitive toASN1Primitive() { ASN1EncodableVector v = new ASN1EncodableVector(); v.add(salt); v.add(iterations); return new DERSequence(v); } } bouncycastle-1.49.orig/src/org/bouncycastle/asn1/pkcs/CertificationRequest.java0000644000175000017500000000442511624625016027313 0ustar ebourgebourgpackage org.bouncycastle.asn1.pkcs; import org.bouncycastle.asn1.ASN1EncodableVector; import org.bouncycastle.asn1.ASN1Object; import org.bouncycastle.asn1.ASN1Primitive; import org.bouncycastle.asn1.ASN1Sequence; import org.bouncycastle.asn1.DERBitString; import org.bouncycastle.asn1.DERSequence; import org.bouncycastle.asn1.x509.AlgorithmIdentifier; /** * PKCS10 Certification request object. *
     * CertificationRequest ::= SEQUENCE {
     *   certificationRequestInfo  CertificationRequestInfo,
     *   signatureAlgorithm        AlgorithmIdentifier{{ SignatureAlgorithms }},
     *   signature                 BIT STRING
     * }
     * 
    */ public class CertificationRequest extends ASN1Object { protected CertificationRequestInfo reqInfo = null; protected AlgorithmIdentifier sigAlgId = null; protected DERBitString sigBits = null; public static CertificationRequest getInstance(Object o) { if (o instanceof CertificationRequest) { return (CertificationRequest)o; } if (o != null) { return new CertificationRequest(ASN1Sequence.getInstance(o)); } return null; } protected CertificationRequest() { } public CertificationRequest( CertificationRequestInfo requestInfo, AlgorithmIdentifier algorithm, DERBitString signature) { this.reqInfo = requestInfo; this.sigAlgId = algorithm; this.sigBits = signature; } public CertificationRequest( ASN1Sequence seq) { reqInfo = CertificationRequestInfo.getInstance(seq.getObjectAt(0)); sigAlgId = AlgorithmIdentifier.getInstance(seq.getObjectAt(1)); sigBits = (DERBitString)seq.getObjectAt(2); } public CertificationRequestInfo getCertificationRequestInfo() { return reqInfo; } public AlgorithmIdentifier getSignatureAlgorithm() { return sigAlgId; } public DERBitString getSignature() { return sigBits; } public ASN1Primitive toASN1Primitive() { // Construct the CertificateRequest ASN1EncodableVector v = new ASN1EncodableVector(); v.add(reqInfo); v.add(sigAlgId); v.add(sigBits); return new DERSequence(v); } } bouncycastle-1.49.orig/src/org/bouncycastle/asn1/pkcs/RSASSAPSSparams.java0000644000175000017500000001251512103437527025745 0ustar ebourgebourgpackage org.bouncycastle.asn1.pkcs; import java.math.BigInteger; import org.bouncycastle.asn1.ASN1EncodableVector; import org.bouncycastle.asn1.ASN1Integer; import org.bouncycastle.asn1.ASN1Object; import org.bouncycastle.asn1.ASN1Primitive; import org.bouncycastle.asn1.ASN1Sequence; import org.bouncycastle.asn1.ASN1TaggedObject; import org.bouncycastle.asn1.DERNull; import org.bouncycastle.asn1.DERSequence; import org.bouncycastle.asn1.DERTaggedObject; import org.bouncycastle.asn1.oiw.OIWObjectIdentifiers; import org.bouncycastle.asn1.x509.AlgorithmIdentifier; public class RSASSAPSSparams extends ASN1Object { private AlgorithmIdentifier hashAlgorithm; private AlgorithmIdentifier maskGenAlgorithm; private ASN1Integer saltLength; private ASN1Integer trailerField; public final static AlgorithmIdentifier DEFAULT_HASH_ALGORITHM = new AlgorithmIdentifier(OIWObjectIdentifiers.idSHA1, DERNull.INSTANCE); public final static AlgorithmIdentifier DEFAULT_MASK_GEN_FUNCTION = new AlgorithmIdentifier(PKCSObjectIdentifiers.id_mgf1, DEFAULT_HASH_ALGORITHM); public final static ASN1Integer DEFAULT_SALT_LENGTH = new ASN1Integer(20); public final static ASN1Integer DEFAULT_TRAILER_FIELD = new ASN1Integer(1); public static RSASSAPSSparams getInstance( Object obj) { if (obj instanceof RSASSAPSSparams) { return (RSASSAPSSparams)obj; } else if (obj != null) { return new RSASSAPSSparams(ASN1Sequence.getInstance(obj)); } return null; } /** * The default version */ public RSASSAPSSparams() { hashAlgorithm = DEFAULT_HASH_ALGORITHM; maskGenAlgorithm = DEFAULT_MASK_GEN_FUNCTION; saltLength = DEFAULT_SALT_LENGTH; trailerField = DEFAULT_TRAILER_FIELD; } public RSASSAPSSparams( AlgorithmIdentifier hashAlgorithm, AlgorithmIdentifier maskGenAlgorithm, ASN1Integer saltLength, ASN1Integer trailerField) { this.hashAlgorithm = hashAlgorithm; this.maskGenAlgorithm = maskGenAlgorithm; this.saltLength = saltLength; this.trailerField = trailerField; } private RSASSAPSSparams( ASN1Sequence seq) { hashAlgorithm = DEFAULT_HASH_ALGORITHM; maskGenAlgorithm = DEFAULT_MASK_GEN_FUNCTION; saltLength = DEFAULT_SALT_LENGTH; trailerField = DEFAULT_TRAILER_FIELD; for (int i = 0; i != seq.size(); i++) { ASN1TaggedObject o = (ASN1TaggedObject)seq.getObjectAt(i); switch (o.getTagNo()) { case 0: hashAlgorithm = AlgorithmIdentifier.getInstance(o, true); break; case 1: maskGenAlgorithm = AlgorithmIdentifier.getInstance(o, true); break; case 2: saltLength = ASN1Integer.getInstance(o, true); break; case 3: trailerField = ASN1Integer.getInstance(o, true); break; default: throw new IllegalArgumentException("unknown tag"); } } } public AlgorithmIdentifier getHashAlgorithm() { return hashAlgorithm; } public AlgorithmIdentifier getMaskGenAlgorithm() { return maskGenAlgorithm; } public BigInteger getSaltLength() { return saltLength.getValue(); } public BigInteger getTrailerField() { return trailerField.getValue(); } /** *
         * RSASSA-PSS-params ::= SEQUENCE {
         *   hashAlgorithm      [0] OAEP-PSSDigestAlgorithms  DEFAULT sha1,
         *    maskGenAlgorithm   [1] PKCS1MGFAlgorithms  DEFAULT mgf1SHA1,
         *    saltLength         [2] INTEGER  DEFAULT 20,
         *    trailerField       [3] TrailerField  DEFAULT trailerFieldBC
         *  }
         *
         * OAEP-PSSDigestAlgorithms    ALGORITHM-IDENTIFIER ::= {
         *    { OID id-sha1 PARAMETERS NULL   }|
         *    { OID id-sha256 PARAMETERS NULL }|
         *    { OID id-sha384 PARAMETERS NULL }|
         *    { OID id-sha512 PARAMETERS NULL },
         *    ...  -- Allows for future expansion --
         * }
         *
         * PKCS1MGFAlgorithms    ALGORITHM-IDENTIFIER ::= {
         *   { OID id-mgf1 PARAMETERS OAEP-PSSDigestAlgorithms },
         *    ...  -- Allows for future expansion --
         * }
         * 
         * TrailerField ::= INTEGER { trailerFieldBC(1) }
         * 
    * @return the asn1 primitive representing the parameters. */ public ASN1Primitive toASN1Primitive() { ASN1EncodableVector v = new ASN1EncodableVector(); if (!hashAlgorithm.equals(DEFAULT_HASH_ALGORITHM)) { v.add(new DERTaggedObject(true, 0, hashAlgorithm)); } if (!maskGenAlgorithm.equals(DEFAULT_MASK_GEN_FUNCTION)) { v.add(new DERTaggedObject(true, 1, maskGenAlgorithm)); } if (!saltLength.equals(DEFAULT_SALT_LENGTH)) { v.add(new DERTaggedObject(true, 2, saltLength)); } if (!trailerField.equals(DEFAULT_TRAILER_FIELD)) { v.add(new DERTaggedObject(true, 3, trailerField)); } return new DERSequence(v); } } bouncycastle-1.49.orig/src/org/bouncycastle/asn1/pkcs/MacData.java0000644000175000017500000000502511725271757024461 0ustar ebourgebourgpackage org.bouncycastle.asn1.pkcs; import java.math.BigInteger; import org.bouncycastle.asn1.ASN1EncodableVector; import org.bouncycastle.asn1.ASN1Integer; import org.bouncycastle.asn1.ASN1Object; import org.bouncycastle.asn1.ASN1OctetString; import org.bouncycastle.asn1.ASN1Primitive; import org.bouncycastle.asn1.ASN1Sequence; import org.bouncycastle.asn1.DEROctetString; import org.bouncycastle.asn1.DERSequence; import org.bouncycastle.asn1.x509.DigestInfo; public class MacData extends ASN1Object { private static final BigInteger ONE = BigInteger.valueOf(1); DigestInfo digInfo; byte[] salt; BigInteger iterationCount; public static MacData getInstance( Object obj) { if (obj instanceof MacData) { return (MacData)obj; } else if (obj != null) { return new MacData(ASN1Sequence.getInstance(obj)); } return null; } private MacData( ASN1Sequence seq) { this.digInfo = DigestInfo.getInstance(seq.getObjectAt(0)); this.salt = ((ASN1OctetString)seq.getObjectAt(1)).getOctets(); if (seq.size() == 3) { this.iterationCount = ((ASN1Integer)seq.getObjectAt(2)).getValue(); } else { this.iterationCount = ONE; } } public MacData( DigestInfo digInfo, byte[] salt, int iterationCount) { this.digInfo = digInfo; this.salt = salt; this.iterationCount = BigInteger.valueOf(iterationCount); } public DigestInfo getMac() { return digInfo; } public byte[] getSalt() { return salt; } public BigInteger getIterationCount() { return iterationCount; } /** *
         * MacData ::= SEQUENCE {
         *     mac      DigestInfo,
         *     macSalt  OCTET STRING,
         *     iterations INTEGER DEFAULT 1
         *     -- Note: The default is for historic reasons and its use is deprecated. A
         *     -- higher value, like 1024 is recommended.
         * 
    * @return the basic ASN1Primitive construction. */ public ASN1Primitive toASN1Primitive() { ASN1EncodableVector v = new ASN1EncodableVector(); v.add(digInfo); v.add(new DEROctetString(salt)); if (!iterationCount.equals(ONE)) { v.add(new ASN1Integer(iterationCount)); } return new DERSequence(v); } } bouncycastle-1.49.orig/src/org/bouncycastle/asn1/pkcs/EncryptedData.java0000644000175000017500000000572611703207236025711 0ustar ebourgebourgpackage org.bouncycastle.asn1.pkcs; import org.bouncycastle.asn1.ASN1Encodable; import org.bouncycastle.asn1.ASN1EncodableVector; import org.bouncycastle.asn1.ASN1Integer; import org.bouncycastle.asn1.ASN1Object; import org.bouncycastle.asn1.ASN1ObjectIdentifier; import org.bouncycastle.asn1.ASN1OctetString; import org.bouncycastle.asn1.ASN1Primitive; import org.bouncycastle.asn1.ASN1Sequence; import org.bouncycastle.asn1.ASN1TaggedObject; import org.bouncycastle.asn1.BERSequence; import org.bouncycastle.asn1.BERTaggedObject; import org.bouncycastle.asn1.x509.AlgorithmIdentifier; /** * The EncryptedData object. *
     *      EncryptedData ::= SEQUENCE {
     *           version Version,
     *           encryptedContentInfo EncryptedContentInfo
     *      }
     *
     *
     *      EncryptedContentInfo ::= SEQUENCE {
     *          contentType ContentType,
     *          contentEncryptionAlgorithm  ContentEncryptionAlgorithmIdentifier,
     *          encryptedContent [0] IMPLICIT EncryptedContent OPTIONAL
     *    }
     *
     *    EncryptedContent ::= OCTET STRING
     * 
    */ public class EncryptedData extends ASN1Object { ASN1Sequence data; ASN1ObjectIdentifier bagId; ASN1Primitive bagValue; public static EncryptedData getInstance( Object obj) { if (obj instanceof EncryptedData) { return (EncryptedData)obj; } if (obj != null) { return new EncryptedData(ASN1Sequence.getInstance(obj)); } return null; } private EncryptedData( ASN1Sequence seq) { int version = ((ASN1Integer)seq.getObjectAt(0)).getValue().intValue(); if (version != 0) { throw new IllegalArgumentException("sequence not version 0"); } this.data = ASN1Sequence.getInstance(seq.getObjectAt(1)); } public EncryptedData( ASN1ObjectIdentifier contentType, AlgorithmIdentifier encryptionAlgorithm, ASN1Encodable content) { ASN1EncodableVector v = new ASN1EncodableVector(); v.add(contentType); v.add(encryptionAlgorithm.toASN1Primitive()); v.add(new BERTaggedObject(false, 0, content)); data = new BERSequence(v); } public ASN1ObjectIdentifier getContentType() { return ASN1ObjectIdentifier.getInstance(data.getObjectAt(0)); } public AlgorithmIdentifier getEncryptionAlgorithm() { return AlgorithmIdentifier.getInstance(data.getObjectAt(1)); } public ASN1OctetString getContent() { if (data.size() == 3) { ASN1TaggedObject o = ASN1TaggedObject.getInstance(data.getObjectAt(2)); return ASN1OctetString.getInstance(o, false); } return null; } public ASN1Primitive toASN1Primitive() { ASN1EncodableVector v = new ASN1EncodableVector(); v.add(new ASN1Integer(0)); v.add(data); return new BERSequence(v); } } bouncycastle-1.49.orig/src/org/bouncycastle/asn1/pkcs/EncryptedPrivateKeyInfo.java0000644000175000017500000000422512103442636027730 0ustar ebourgebourgpackage org.bouncycastle.asn1.pkcs; import java.util.Enumeration; import org.bouncycastle.asn1.ASN1EncodableVector; import org.bouncycastle.asn1.ASN1Object; import org.bouncycastle.asn1.ASN1OctetString; import org.bouncycastle.asn1.ASN1Primitive; import org.bouncycastle.asn1.ASN1Sequence; import org.bouncycastle.asn1.DEROctetString; import org.bouncycastle.asn1.DERSequence; import org.bouncycastle.asn1.x509.AlgorithmIdentifier; public class EncryptedPrivateKeyInfo extends ASN1Object { private AlgorithmIdentifier algId; private ASN1OctetString data; private EncryptedPrivateKeyInfo( ASN1Sequence seq) { Enumeration e = seq.getObjects(); algId = AlgorithmIdentifier.getInstance(e.nextElement()); data = ASN1OctetString.getInstance(e.nextElement()); } public EncryptedPrivateKeyInfo( AlgorithmIdentifier algId, byte[] encoding) { this.algId = algId; this.data = new DEROctetString(encoding); } public static EncryptedPrivateKeyInfo getInstance( Object obj) { if (obj instanceof EncryptedPrivateKeyInfo) { return (EncryptedPrivateKeyInfo)obj; } else if (obj != null) { return new EncryptedPrivateKeyInfo(ASN1Sequence.getInstance(obj)); } return null; } public AlgorithmIdentifier getEncryptionAlgorithm() { return algId; } public byte[] getEncryptedData() { return data.getOctets(); } /** * Produce an object suitable for an ASN1OutputStream. *
         * EncryptedPrivateKeyInfo ::= SEQUENCE {
         *      encryptionAlgorithm AlgorithmIdentifier {{KeyEncryptionAlgorithms}},
         *      encryptedData EncryptedData
         * }
         *
         * EncryptedData ::= OCTET STRING
         *
         * KeyEncryptionAlgorithms ALGORITHM-IDENTIFIER ::= {
         *          ... -- For local profiles
         * }
         * 
    */ public ASN1Primitive toASN1Primitive() { ASN1EncodableVector v = new ASN1EncodableVector(); v.add(algId); v.add(data); return new DERSequence(v); } } bouncycastle-1.49.orig/src/org/bouncycastle/asn1/pkcs/IssuerAndSerialNumber.java0000644000175000017500000000413211736736613027372 0ustar ebourgebourgpackage org.bouncycastle.asn1.pkcs; import java.math.BigInteger; import org.bouncycastle.asn1.ASN1EncodableVector; import org.bouncycastle.asn1.ASN1Integer; import org.bouncycastle.asn1.ASN1Object; import org.bouncycastle.asn1.ASN1Primitive; import org.bouncycastle.asn1.ASN1Sequence; import org.bouncycastle.asn1.DERSequence; import org.bouncycastle.asn1.x500.X500Name; import org.bouncycastle.asn1.x509.X509Name; public class IssuerAndSerialNumber extends ASN1Object { X500Name name; ASN1Integer certSerialNumber; public static IssuerAndSerialNumber getInstance( Object obj) { if (obj instanceof IssuerAndSerialNumber) { return (IssuerAndSerialNumber)obj; } else if (obj != null) { return new IssuerAndSerialNumber(ASN1Sequence.getInstance(obj)); } return null; } private IssuerAndSerialNumber( ASN1Sequence seq) { this.name = X500Name.getInstance(seq.getObjectAt(0)); this.certSerialNumber = (ASN1Integer)seq.getObjectAt(1); } public IssuerAndSerialNumber( X509Name name, BigInteger certSerialNumber) { this.name = X500Name.getInstance(name.toASN1Primitive()); this.certSerialNumber = new ASN1Integer(certSerialNumber); } public IssuerAndSerialNumber( X509Name name, ASN1Integer certSerialNumber) { this.name = X500Name.getInstance(name.toASN1Primitive()); this.certSerialNumber = certSerialNumber; } public IssuerAndSerialNumber( X500Name name, BigInteger certSerialNumber) { this.name = name; this.certSerialNumber = new ASN1Integer(certSerialNumber); } public X500Name getName() { return name; } public ASN1Integer getCertificateSerialNumber() { return certSerialNumber; } public ASN1Primitive toASN1Primitive() { ASN1EncodableVector v = new ASN1EncodableVector(); v.add(name); v.add(certSerialNumber); return new DERSequence(v); } } bouncycastle-1.49.orig/src/org/bouncycastle/asn1/pkcs/PBES2Algorithms.java0000644000175000017500000000356512110310541026011 0ustar ebourgebourgpackage org.bouncycastle.asn1.pkcs; import java.util.Enumeration; import org.bouncycastle.asn1.ASN1EncodableVector; import org.bouncycastle.asn1.ASN1ObjectIdentifier; import org.bouncycastle.asn1.ASN1Primitive; import org.bouncycastle.asn1.ASN1Sequence; import org.bouncycastle.asn1.DERSequence; import org.bouncycastle.asn1.x509.AlgorithmIdentifier; /** * @deprecated - use AlgorithmIdentifier and PBES2Parameters */ public class PBES2Algorithms extends AlgorithmIdentifier implements PKCSObjectIdentifiers { private ASN1ObjectIdentifier objectId; private KeyDerivationFunc func; private EncryptionScheme scheme; public PBES2Algorithms( ASN1Sequence obj) { super(obj); Enumeration e = obj.getObjects(); objectId = (ASN1ObjectIdentifier)e.nextElement(); ASN1Sequence seq = (ASN1Sequence)e.nextElement(); e = seq.getObjects(); ASN1Sequence funcSeq = (ASN1Sequence)e.nextElement(); if (funcSeq.getObjectAt(0).equals(id_PBKDF2)) { func = new KeyDerivationFunc(id_PBKDF2, PBKDF2Params.getInstance(funcSeq.getObjectAt(1))); } else { func = KeyDerivationFunc.getInstance(funcSeq); } scheme = EncryptionScheme.getInstance(e.nextElement()); } public ASN1ObjectIdentifier getObjectId() { return objectId; } public KeyDerivationFunc getKeyDerivationFunc() { return func; } public EncryptionScheme getEncryptionScheme() { return scheme; } public ASN1Primitive getASN1Primitive() { ASN1EncodableVector v = new ASN1EncodableVector(); ASN1EncodableVector subV = new ASN1EncodableVector(); v.add(objectId); subV.add(func); subV.add(scheme); v.add(new DERSequence(subV)); return new DERSequence(v); } } bouncycastle-1.49.orig/src/org/bouncycastle/asn1/pkcs/RSAPrivateKey.java0000644000175000017500000001237211624622714025612 0ustar ebourgebourgpackage org.bouncycastle.asn1.pkcs; import java.math.BigInteger; import java.util.Enumeration; import org.bouncycastle.asn1.ASN1EncodableVector; import org.bouncycastle.asn1.ASN1Integer; import org.bouncycastle.asn1.ASN1Object; import org.bouncycastle.asn1.ASN1Primitive; import org.bouncycastle.asn1.ASN1Sequence; import org.bouncycastle.asn1.ASN1TaggedObject; import org.bouncycastle.asn1.DERSequence; public class RSAPrivateKey extends ASN1Object { private BigInteger version; private BigInteger modulus; private BigInteger publicExponent; private BigInteger privateExponent; private BigInteger prime1; private BigInteger prime2; private BigInteger exponent1; private BigInteger exponent2; private BigInteger coefficient; private ASN1Sequence otherPrimeInfos = null; public static RSAPrivateKey getInstance( ASN1TaggedObject obj, boolean explicit) { return getInstance(ASN1Sequence.getInstance(obj, explicit)); } public static RSAPrivateKey getInstance( Object obj) { if (obj instanceof RSAPrivateKey) { return (RSAPrivateKey)obj; } if (obj != null) { return new RSAPrivateKey(ASN1Sequence.getInstance(obj)); } return null; } public RSAPrivateKey( BigInteger modulus, BigInteger publicExponent, BigInteger privateExponent, BigInteger prime1, BigInteger prime2, BigInteger exponent1, BigInteger exponent2, BigInteger coefficient) { this.version = BigInteger.valueOf(0); this.modulus = modulus; this.publicExponent = publicExponent; this.privateExponent = privateExponent; this.prime1 = prime1; this.prime2 = prime2; this.exponent1 = exponent1; this.exponent2 = exponent2; this.coefficient = coefficient; } private RSAPrivateKey( ASN1Sequence seq) { Enumeration e = seq.getObjects(); BigInteger v = ((ASN1Integer)e.nextElement()).getValue(); if (v.intValue() != 0 && v.intValue() != 1) { throw new IllegalArgumentException("wrong version for RSA private key"); } version = v; modulus = ((ASN1Integer)e.nextElement()).getValue(); publicExponent = ((ASN1Integer)e.nextElement()).getValue(); privateExponent = ((ASN1Integer)e.nextElement()).getValue(); prime1 = ((ASN1Integer)e.nextElement()).getValue(); prime2 = ((ASN1Integer)e.nextElement()).getValue(); exponent1 = ((ASN1Integer)e.nextElement()).getValue(); exponent2 = ((ASN1Integer)e.nextElement()).getValue(); coefficient = ((ASN1Integer)e.nextElement()).getValue(); if (e.hasMoreElements()) { otherPrimeInfos = (ASN1Sequence)e.nextElement(); } } public BigInteger getVersion() { return version; } public BigInteger getModulus() { return modulus; } public BigInteger getPublicExponent() { return publicExponent; } public BigInteger getPrivateExponent() { return privateExponent; } public BigInteger getPrime1() { return prime1; } public BigInteger getPrime2() { return prime2; } public BigInteger getExponent1() { return exponent1; } public BigInteger getExponent2() { return exponent2; } public BigInteger getCoefficient() { return coefficient; } /** * This outputs the key in PKCS1v2 format. *
         *      RSAPrivateKey ::= SEQUENCE {
         *                          version Version,
         *                          modulus INTEGER, -- n
         *                          publicExponent INTEGER, -- e
         *                          privateExponent INTEGER, -- d
         *                          prime1 INTEGER, -- p
         *                          prime2 INTEGER, -- q
         *                          exponent1 INTEGER, -- d mod (p-1)
         *                          exponent2 INTEGER, -- d mod (q-1)
         *                          coefficient INTEGER, -- (inverse of q) mod p
         *                          otherPrimeInfos OtherPrimeInfos OPTIONAL
         *                      }
         *
         *      Version ::= INTEGER { two-prime(0), multi(1) }
         *        (CONSTRAINED BY {-- version must be multi if otherPrimeInfos present --})
         * 
    *

    * This routine is written to output PKCS1 version 2.1, private keys. */ public ASN1Primitive toASN1Primitive() { ASN1EncodableVector v = new ASN1EncodableVector(); v.add(new ASN1Integer(version)); // version v.add(new ASN1Integer(getModulus())); v.add(new ASN1Integer(getPublicExponent())); v.add(new ASN1Integer(getPrivateExponent())); v.add(new ASN1Integer(getPrime1())); v.add(new ASN1Integer(getPrime2())); v.add(new ASN1Integer(getExponent1())); v.add(new ASN1Integer(getExponent2())); v.add(new ASN1Integer(getCoefficient())); if (otherPrimeInfos != null) { v.add(otherPrimeInfos); } return new DERSequence(v); } } bouncycastle-1.49.orig/src/org/bouncycastle/asn1/pkcs/SignedData.java0000644000175000017500000001047112030175024025147 0ustar ebourgebourgpackage org.bouncycastle.asn1.pkcs; import java.util.Enumeration; import org.bouncycastle.asn1.ASN1EncodableVector; import org.bouncycastle.asn1.ASN1Integer; import org.bouncycastle.asn1.ASN1Object; import org.bouncycastle.asn1.ASN1Primitive; import org.bouncycastle.asn1.ASN1Sequence; import org.bouncycastle.asn1.ASN1Set; import org.bouncycastle.asn1.ASN1TaggedObject; import org.bouncycastle.asn1.BERSequence; import org.bouncycastle.asn1.DERTaggedObject; /** * a PKCS#7 signed data object. */ public class SignedData extends ASN1Object implements PKCSObjectIdentifiers { private ASN1Integer version; private ASN1Set digestAlgorithms; private ContentInfo contentInfo; private ASN1Set certificates; private ASN1Set crls; private ASN1Set signerInfos; public static SignedData getInstance( Object o) { if (o instanceof SignedData) { return (SignedData)o; } else if (o != null) { return new SignedData(ASN1Sequence.getInstance(o)); } return null; } public SignedData( ASN1Integer _version, ASN1Set _digestAlgorithms, ContentInfo _contentInfo, ASN1Set _certificates, ASN1Set _crls, ASN1Set _signerInfos) { version = _version; digestAlgorithms = _digestAlgorithms; contentInfo = _contentInfo; certificates = _certificates; crls = _crls; signerInfos = _signerInfos; } public SignedData( ASN1Sequence seq) { Enumeration e = seq.getObjects(); version = (ASN1Integer)e.nextElement(); digestAlgorithms = ((ASN1Set)e.nextElement()); contentInfo = ContentInfo.getInstance(e.nextElement()); while (e.hasMoreElements()) { ASN1Primitive o = (ASN1Primitive)e.nextElement(); // // an interesting feature of SignedData is that there appear to be varying implementations... // for the moment we ignore anything which doesn't fit. // if (o instanceof ASN1TaggedObject) { ASN1TaggedObject tagged = (ASN1TaggedObject)o; switch (tagged.getTagNo()) { case 0: certificates = ASN1Set.getInstance(tagged, false); break; case 1: crls = ASN1Set.getInstance(tagged, false); break; default: throw new IllegalArgumentException("unknown tag value " + tagged.getTagNo()); } } else { signerInfos = (ASN1Set)o; } } } public ASN1Integer getVersion() { return version; } public ASN1Set getDigestAlgorithms() { return digestAlgorithms; } public ContentInfo getContentInfo() { return contentInfo; } public ASN1Set getCertificates() { return certificates; } public ASN1Set getCRLs() { return crls; } public ASN1Set getSignerInfos() { return signerInfos; } /** * Produce an object suitable for an ASN1OutputStream. *

         *  SignedData ::= SEQUENCE {
         *      version Version,
         *      digestAlgorithms DigestAlgorithmIdentifiers,
         *      contentInfo ContentInfo,
         *      certificates
         *          [0] IMPLICIT ExtendedCertificatesAndCertificates
         *                   OPTIONAL,
         *      crls
         *          [1] IMPLICIT CertificateRevocationLists OPTIONAL,
         *      signerInfos SignerInfos }
         * 
    */ public ASN1Primitive toASN1Primitive() { ASN1EncodableVector v = new ASN1EncodableVector(); v.add(version); v.add(digestAlgorithms); v.add(contentInfo); if (certificates != null) { v.add(new DERTaggedObject(false, 0, certificates)); } if (crls != null) { v.add(new DERTaggedObject(false, 1, crls)); } v.add(signerInfos); return new BERSequence(v); } } bouncycastle-1.49.orig/src/org/bouncycastle/asn1/pkcs/Pfx.java0000644000175000017500000000354111625364337023721 0ustar ebourgebourgpackage org.bouncycastle.asn1.pkcs; import java.math.BigInteger; import org.bouncycastle.asn1.ASN1EncodableVector; import org.bouncycastle.asn1.ASN1Integer; import org.bouncycastle.asn1.ASN1Object; import org.bouncycastle.asn1.ASN1Primitive; import org.bouncycastle.asn1.ASN1Sequence; import org.bouncycastle.asn1.BERSequence; /** * the infamous Pfx from PKCS12 */ public class Pfx extends ASN1Object implements PKCSObjectIdentifiers { private ContentInfo contentInfo; private MacData macData = null; private Pfx( ASN1Sequence seq) { BigInteger version = ((ASN1Integer)seq.getObjectAt(0)).getValue(); if (version.intValue() != 3) { throw new IllegalArgumentException("wrong version for PFX PDU"); } contentInfo = ContentInfo.getInstance(seq.getObjectAt(1)); if (seq.size() == 3) { macData = MacData.getInstance(seq.getObjectAt(2)); } } public static Pfx getInstance( Object obj) { if (obj instanceof Pfx) { return (Pfx)obj; } if (obj != null) { return new Pfx(ASN1Sequence.getInstance(obj)); } return null; } public Pfx( ContentInfo contentInfo, MacData macData) { this.contentInfo = contentInfo; this.macData = macData; } public ContentInfo getAuthSafe() { return contentInfo; } public MacData getMacData() { return macData; } public ASN1Primitive toASN1Primitive() { ASN1EncodableVector v = new ASN1EncodableVector(); v.add(new ASN1Integer(3)); v.add(contentInfo); if (macData != null) { v.add(macData); } return new BERSequence(v); } } bouncycastle-1.49.orig/src/org/bouncycastle/asn1/pkcs/EncryptionScheme.java0000644000175000017500000000247512110277555026443 0ustar ebourgebourgpackage org.bouncycastle.asn1.pkcs; import org.bouncycastle.asn1.ASN1Encodable; import org.bouncycastle.asn1.ASN1Object; import org.bouncycastle.asn1.ASN1ObjectIdentifier; import org.bouncycastle.asn1.ASN1Primitive; import org.bouncycastle.asn1.ASN1Sequence; import org.bouncycastle.asn1.x509.AlgorithmIdentifier; public class EncryptionScheme extends ASN1Object { private AlgorithmIdentifier algId; public EncryptionScheme( ASN1ObjectIdentifier objectId, ASN1Encodable parameters) { this.algId = new AlgorithmIdentifier(objectId, parameters); } private EncryptionScheme( ASN1Sequence seq) { this.algId = AlgorithmIdentifier.getInstance(seq); } public static final EncryptionScheme getInstance(Object obj) { if (obj instanceof EncryptionScheme) { return (EncryptionScheme)obj; } else if (obj != null) { return new EncryptionScheme(ASN1Sequence.getInstance(obj)); } return null; } public ASN1ObjectIdentifier getAlgorithm() { return algId.getAlgorithm(); } public ASN1Encodable getParameters() { return algId.getParameters(); } public ASN1Primitive toASN1Primitive() { return algId.toASN1Primitive(); } } bouncycastle-1.49.orig/src/org/bouncycastle/asn1/pkcs/RSAPublicKey.java0000644000175000017500000000445311624652552025422 0ustar ebourgebourgpackage org.bouncycastle.asn1.pkcs; import java.math.BigInteger; import java.util.Enumeration; import org.bouncycastle.asn1.ASN1EncodableVector; import org.bouncycastle.asn1.ASN1Integer; import org.bouncycastle.asn1.ASN1Object; import org.bouncycastle.asn1.ASN1Primitive; import org.bouncycastle.asn1.ASN1Sequence; import org.bouncycastle.asn1.ASN1TaggedObject; import org.bouncycastle.asn1.DERSequence; public class RSAPublicKey extends ASN1Object { private BigInteger modulus; private BigInteger publicExponent; public static RSAPublicKey getInstance( ASN1TaggedObject obj, boolean explicit) { return getInstance(ASN1Sequence.getInstance(obj, explicit)); } public static RSAPublicKey getInstance( Object obj) { if (obj instanceof RSAPublicKey) { return (RSAPublicKey)obj; } if (obj != null) { return new RSAPublicKey(ASN1Sequence.getInstance(obj)); } return null; } public RSAPublicKey( BigInteger modulus, BigInteger publicExponent) { this.modulus = modulus; this.publicExponent = publicExponent; } private RSAPublicKey( ASN1Sequence seq) { if (seq.size() != 2) { throw new IllegalArgumentException("Bad sequence size: " + seq.size()); } Enumeration e = seq.getObjects(); modulus = ASN1Integer.getInstance(e.nextElement()).getPositiveValue(); publicExponent = ASN1Integer.getInstance(e.nextElement()).getPositiveValue(); } public BigInteger getModulus() { return modulus; } public BigInteger getPublicExponent() { return publicExponent; } /** * This outputs the key in PKCS1v2 format. *
         *      RSAPublicKey ::= SEQUENCE {
         *                          modulus INTEGER, -- n
         *                          publicExponent INTEGER, -- e
         *                      }
         * 
    *

    */ public ASN1Primitive toASN1Primitive() { ASN1EncodableVector v = new ASN1EncodableVector(); v.add(new ASN1Integer(getModulus())); v.add(new ASN1Integer(getPublicExponent())); return new DERSequence(v); } } bouncycastle-1.49.orig/src/org/bouncycastle/asn1/pkcs/RSAESOAEPparams.java0000644000175000017500000001163712103437526025710 0ustar ebourgebourgpackage org.bouncycastle.asn1.pkcs; import org.bouncycastle.asn1.ASN1EncodableVector; import org.bouncycastle.asn1.ASN1Object; import org.bouncycastle.asn1.ASN1Primitive; import org.bouncycastle.asn1.ASN1Sequence; import org.bouncycastle.asn1.ASN1TaggedObject; import org.bouncycastle.asn1.DERNull; import org.bouncycastle.asn1.DEROctetString; import org.bouncycastle.asn1.DERSequence; import org.bouncycastle.asn1.DERTaggedObject; import org.bouncycastle.asn1.oiw.OIWObjectIdentifiers; import org.bouncycastle.asn1.x509.AlgorithmIdentifier; public class RSAESOAEPparams extends ASN1Object { private AlgorithmIdentifier hashAlgorithm; private AlgorithmIdentifier maskGenAlgorithm; private AlgorithmIdentifier pSourceAlgorithm; public final static AlgorithmIdentifier DEFAULT_HASH_ALGORITHM = new AlgorithmIdentifier(OIWObjectIdentifiers.idSHA1, DERNull.INSTANCE); public final static AlgorithmIdentifier DEFAULT_MASK_GEN_FUNCTION = new AlgorithmIdentifier(PKCSObjectIdentifiers.id_mgf1, DEFAULT_HASH_ALGORITHM); public final static AlgorithmIdentifier DEFAULT_P_SOURCE_ALGORITHM = new AlgorithmIdentifier(PKCSObjectIdentifiers.id_pSpecified, new DEROctetString(new byte[0])); public static RSAESOAEPparams getInstance( Object obj) { if (obj instanceof RSAESOAEPparams) { return (RSAESOAEPparams)obj; } else if (obj != null) { return new RSAESOAEPparams(ASN1Sequence.getInstance(obj)); } return null; } /** * The default version */ public RSAESOAEPparams() { hashAlgorithm = DEFAULT_HASH_ALGORITHM; maskGenAlgorithm = DEFAULT_MASK_GEN_FUNCTION; pSourceAlgorithm = DEFAULT_P_SOURCE_ALGORITHM; } public RSAESOAEPparams( AlgorithmIdentifier hashAlgorithm, AlgorithmIdentifier maskGenAlgorithm, AlgorithmIdentifier pSourceAlgorithm) { this.hashAlgorithm = hashAlgorithm; this.maskGenAlgorithm = maskGenAlgorithm; this.pSourceAlgorithm = pSourceAlgorithm; } public RSAESOAEPparams( ASN1Sequence seq) { hashAlgorithm = DEFAULT_HASH_ALGORITHM; maskGenAlgorithm = DEFAULT_MASK_GEN_FUNCTION; pSourceAlgorithm = DEFAULT_P_SOURCE_ALGORITHM; for (int i = 0; i != seq.size(); i++) { ASN1TaggedObject o = (ASN1TaggedObject)seq.getObjectAt(i); switch (o.getTagNo()) { case 0: hashAlgorithm = AlgorithmIdentifier.getInstance(o, true); break; case 1: maskGenAlgorithm = AlgorithmIdentifier.getInstance(o, true); break; case 2: pSourceAlgorithm = AlgorithmIdentifier.getInstance(o, true); break; default: throw new IllegalArgumentException("unknown tag"); } } } public AlgorithmIdentifier getHashAlgorithm() { return hashAlgorithm; } public AlgorithmIdentifier getMaskGenAlgorithm() { return maskGenAlgorithm; } public AlgorithmIdentifier getPSourceAlgorithm() { return pSourceAlgorithm; } /** *

         *  RSAES-OAEP-params ::= SEQUENCE {
         *     hashAlgorithm      [0] OAEP-PSSDigestAlgorithms     DEFAULT sha1,
         *     maskGenAlgorithm   [1] PKCS1MGFAlgorithms  DEFAULT mgf1SHA1,
         *     pSourceAlgorithm   [2] PKCS1PSourceAlgorithms  DEFAULT pSpecifiedEmpty
         *   }
         *  
         *   OAEP-PSSDigestAlgorithms    ALGORITHM-IDENTIFIER ::= {
         *     { OID id-sha1 PARAMETERS NULL   }|
         *     { OID id-sha256 PARAMETERS NULL }|
         *     { OID id-sha384 PARAMETERS NULL }|
         *     { OID id-sha512 PARAMETERS NULL },
         *     ...  -- Allows for future expansion --
         *   }
         *   PKCS1MGFAlgorithms    ALGORITHM-IDENTIFIER ::= {
         *     { OID id-mgf1 PARAMETERS OAEP-PSSDigestAlgorithms },
         *    ...  -- Allows for future expansion --
         *   }
         *   PKCS1PSourceAlgorithms    ALGORITHM-IDENTIFIER ::= {
         *     { OID id-pSpecified PARAMETERS OCTET STRING },
         *     ...  -- Allows for future expansion --
         *  }
         * 
    * @return the asn1 primitive representing the parameters. */ public ASN1Primitive toASN1Primitive() { ASN1EncodableVector v = new ASN1EncodableVector(); if (!hashAlgorithm.equals(DEFAULT_HASH_ALGORITHM)) { v.add(new DERTaggedObject(true, 0, hashAlgorithm)); } if (!maskGenAlgorithm.equals(DEFAULT_MASK_GEN_FUNCTION)) { v.add(new DERTaggedObject(true, 1, maskGenAlgorithm)); } if (!pSourceAlgorithm.equals(DEFAULT_P_SOURCE_ALGORITHM)) { v.add(new DERTaggedObject(true, 2, pSourceAlgorithm)); } return new DERSequence(v); } } bouncycastle-1.49.orig/src/org/bouncycastle/asn1/pkcs/RSAPrivateKeyStructure.java0000644000175000017500000001271011724561171027527 0ustar ebourgebourgpackage org.bouncycastle.asn1.pkcs; import java.math.BigInteger; import java.util.Enumeration; import org.bouncycastle.asn1.ASN1EncodableVector; import org.bouncycastle.asn1.ASN1Integer; import org.bouncycastle.asn1.ASN1Object; import org.bouncycastle.asn1.ASN1Primitive; import org.bouncycastle.asn1.ASN1Sequence; import org.bouncycastle.asn1.ASN1TaggedObject; import org.bouncycastle.asn1.DERSequence; /** * @deprecated use RSAPrivateKey */ public class RSAPrivateKeyStructure extends ASN1Object { private int version; private BigInteger modulus; private BigInteger publicExponent; private BigInteger privateExponent; private BigInteger prime1; private BigInteger prime2; private BigInteger exponent1; private BigInteger exponent2; private BigInteger coefficient; private ASN1Sequence otherPrimeInfos = null; public static RSAPrivateKeyStructure getInstance( ASN1TaggedObject obj, boolean explicit) { return getInstance(ASN1Sequence.getInstance(obj, explicit)); } public static RSAPrivateKeyStructure getInstance( Object obj) { if (obj instanceof RSAPrivateKeyStructure) { return (RSAPrivateKeyStructure)obj; } else if (obj instanceof ASN1Sequence) { return new RSAPrivateKeyStructure((ASN1Sequence)obj); } throw new IllegalArgumentException("unknown object in factory: " + obj.getClass().getName()); } public RSAPrivateKeyStructure( BigInteger modulus, BigInteger publicExponent, BigInteger privateExponent, BigInteger prime1, BigInteger prime2, BigInteger exponent1, BigInteger exponent2, BigInteger coefficient) { this.version = 0; this.modulus = modulus; this.publicExponent = publicExponent; this.privateExponent = privateExponent; this.prime1 = prime1; this.prime2 = prime2; this.exponent1 = exponent1; this.exponent2 = exponent2; this.coefficient = coefficient; } public RSAPrivateKeyStructure( ASN1Sequence seq) { Enumeration e = seq.getObjects(); BigInteger v = ((ASN1Integer)e.nextElement()).getValue(); if (v.intValue() != 0 && v.intValue() != 1) { throw new IllegalArgumentException("wrong version for RSA private key"); } version = v.intValue(); modulus = ((ASN1Integer)e.nextElement()).getValue(); publicExponent = ((ASN1Integer)e.nextElement()).getValue(); privateExponent = ((ASN1Integer)e.nextElement()).getValue(); prime1 = ((ASN1Integer)e.nextElement()).getValue(); prime2 = ((ASN1Integer)e.nextElement()).getValue(); exponent1 = ((ASN1Integer)e.nextElement()).getValue(); exponent2 = ((ASN1Integer)e.nextElement()).getValue(); coefficient = ((ASN1Integer)e.nextElement()).getValue(); if (e.hasMoreElements()) { otherPrimeInfos = (ASN1Sequence)e.nextElement(); } } public int getVersion() { return version; } public BigInteger getModulus() { return modulus; } public BigInteger getPublicExponent() { return publicExponent; } public BigInteger getPrivateExponent() { return privateExponent; } public BigInteger getPrime1() { return prime1; } public BigInteger getPrime2() { return prime2; } public BigInteger getExponent1() { return exponent1; } public BigInteger getExponent2() { return exponent2; } public BigInteger getCoefficient() { return coefficient; } /** * This outputs the key in PKCS1v2 format. *
         *      RSAPrivateKey ::= SEQUENCE {
         *                          version Version,
         *                          modulus INTEGER, -- n
         *                          publicExponent INTEGER, -- e
         *                          privateExponent INTEGER, -- d
         *                          prime1 INTEGER, -- p
         *                          prime2 INTEGER, -- q
         *                          exponent1 INTEGER, -- d mod (p-1)
         *                          exponent2 INTEGER, -- d mod (q-1)
         *                          coefficient INTEGER, -- (inverse of q) mod p
         *                          otherPrimeInfos OtherPrimeInfos OPTIONAL
         *                      }
         *
         *      Version ::= INTEGER { two-prime(0), multi(1) }
         *        (CONSTRAINED BY {-- version must be multi if otherPrimeInfos present --})
         * 
    *

    * This routine is written to output PKCS1 version 2.1, private keys. */ public ASN1Primitive toASN1Primitive() { ASN1EncodableVector v = new ASN1EncodableVector(); v.add(new ASN1Integer(version)); // version v.add(new ASN1Integer(getModulus())); v.add(new ASN1Integer(getPublicExponent())); v.add(new ASN1Integer(getPrivateExponent())); v.add(new ASN1Integer(getPrime1())); v.add(new ASN1Integer(getPrime2())); v.add(new ASN1Integer(getExponent1())); v.add(new ASN1Integer(getExponent2())); v.add(new ASN1Integer(getCoefficient())); if (otherPrimeInfos != null) { v.add(otherPrimeInfos); } return new DERSequence(v); } } bouncycastle-1.49.orig/src/org/bouncycastle/asn1/pkcs/SafeBag.java0000644000175000017500000000430411727731066024452 0ustar ebourgebourgpackage org.bouncycastle.asn1.pkcs; import org.bouncycastle.asn1.ASN1Encodable; import org.bouncycastle.asn1.ASN1EncodableVector; import org.bouncycastle.asn1.ASN1Object; import org.bouncycastle.asn1.ASN1ObjectIdentifier; import org.bouncycastle.asn1.ASN1Primitive; import org.bouncycastle.asn1.ASN1Sequence; import org.bouncycastle.asn1.ASN1Set; import org.bouncycastle.asn1.ASN1TaggedObject; import org.bouncycastle.asn1.DLSequence; import org.bouncycastle.asn1.DLTaggedObject; public class SafeBag extends ASN1Object { private ASN1ObjectIdentifier bagId; private ASN1Encodable bagValue; private ASN1Set bagAttributes; public SafeBag( ASN1ObjectIdentifier oid, ASN1Encodable obj) { this.bagId = oid; this.bagValue = obj; this.bagAttributes = null; } public SafeBag( ASN1ObjectIdentifier oid, ASN1Encodable obj, ASN1Set bagAttributes) { this.bagId = oid; this.bagValue = obj; this.bagAttributes = bagAttributes; } public static SafeBag getInstance( Object obj) { if (obj instanceof SafeBag) { return (SafeBag)obj; } if (obj != null) { return new SafeBag(ASN1Sequence.getInstance(obj)); } return null; } private SafeBag( ASN1Sequence seq) { this.bagId = (ASN1ObjectIdentifier)seq.getObjectAt(0); this.bagValue = ((ASN1TaggedObject)seq.getObjectAt(1)).getObject(); if (seq.size() == 3) { this.bagAttributes = (ASN1Set)seq.getObjectAt(2); } } public ASN1ObjectIdentifier getBagId() { return bagId; } public ASN1Encodable getBagValue() { return bagValue; } public ASN1Set getBagAttributes() { return bagAttributes; } public ASN1Primitive toASN1Primitive() { ASN1EncodableVector v = new ASN1EncodableVector(); v.add(bagId); v.add(new DLTaggedObject(true, 0, bagValue)); if (bagAttributes != null) { v.add(bagAttributes); } return new DLSequence(v); } } bouncycastle-1.49.orig/src/org/bouncycastle/asn1/pkcs/Attribute.java0000644000175000017500000000420511730475222025116 0ustar ebourgebourgpackage org.bouncycastle.asn1.pkcs; import org.bouncycastle.asn1.ASN1Encodable; import org.bouncycastle.asn1.ASN1EncodableVector; import org.bouncycastle.asn1.ASN1Object; import org.bouncycastle.asn1.ASN1ObjectIdentifier; import org.bouncycastle.asn1.ASN1Primitive; import org.bouncycastle.asn1.ASN1Sequence; import org.bouncycastle.asn1.ASN1Set; import org.bouncycastle.asn1.DERSequence; public class Attribute extends ASN1Object { private ASN1ObjectIdentifier attrType; private ASN1Set attrValues; /** * return an Attribute object from the given object. * * @param o the object we want converted. * @exception IllegalArgumentException if the object cannot be converted. */ public static Attribute getInstance( Object o) { if (o == null || o instanceof Attribute) { return (Attribute)o; } if (o instanceof ASN1Sequence) { return new Attribute((ASN1Sequence)o); } throw new IllegalArgumentException("unknown object in factory: " + o.getClass().getName()); } public Attribute( ASN1Sequence seq) { attrType = (ASN1ObjectIdentifier)seq.getObjectAt(0); attrValues = (ASN1Set)seq.getObjectAt(1); } public Attribute( ASN1ObjectIdentifier attrType, ASN1Set attrValues) { this.attrType = attrType; this.attrValues = attrValues; } public ASN1ObjectIdentifier getAttrType() { return attrType; } public ASN1Set getAttrValues() { return attrValues; } public ASN1Encodable[] getAttributeValues() { return attrValues.toArray(); } /** * Produce an object suitable for an ASN1OutputStream. *

         * Attribute ::= SEQUENCE {
         *     attrType OBJECT IDENTIFIER,
         *     attrValues SET OF AttributeValue
         * }
         * 
    */ public ASN1Primitive toASN1Primitive() { ASN1EncodableVector v = new ASN1EncodableVector(); v.add(attrType); v.add(attrValues); return new DERSequence(v); } } bouncycastle-1.49.orig/src/org/bouncycastle/asn1/pkcs/CertBag.java0000644000175000017500000000303611727531766024477 0ustar ebourgebourgpackage org.bouncycastle.asn1.pkcs; import org.bouncycastle.asn1.ASN1Encodable; import org.bouncycastle.asn1.ASN1EncodableVector; import org.bouncycastle.asn1.ASN1Object; import org.bouncycastle.asn1.ASN1ObjectIdentifier; import org.bouncycastle.asn1.ASN1Primitive; import org.bouncycastle.asn1.ASN1Sequence; import org.bouncycastle.asn1.DERSequence; import org.bouncycastle.asn1.DERTaggedObject; public class CertBag extends ASN1Object { private ASN1ObjectIdentifier certId; private ASN1Encodable certValue; private CertBag( ASN1Sequence seq) { this.certId = (ASN1ObjectIdentifier)seq.getObjectAt(0); this.certValue = ((DERTaggedObject)seq.getObjectAt(1)).getObject(); } public static CertBag getInstance(Object o) { if (o instanceof CertBag) { return (CertBag)o; } else if (o != null) { return new CertBag(ASN1Sequence.getInstance(o)); } return null; } public CertBag( ASN1ObjectIdentifier certId, ASN1Encodable certValue) { this.certId = certId; this.certValue = certValue; } public ASN1ObjectIdentifier getCertId() { return certId; } public ASN1Encodable getCertValue() { return certValue; } public ASN1Primitive toASN1Primitive() { ASN1EncodableVector v = new ASN1EncodableVector(); v.add(certId); v.add(new DERTaggedObject(0, certValue)); return new DERSequence(v); } } bouncycastle-1.49.orig/src/org/bouncycastle/asn1/pkcs/DHParameter.java0000644000175000017500000000374311724561172025320 0ustar ebourgebourgpackage org.bouncycastle.asn1.pkcs; import java.math.BigInteger; import java.util.Enumeration; import org.bouncycastle.asn1.ASN1EncodableVector; import org.bouncycastle.asn1.ASN1Integer; import org.bouncycastle.asn1.ASN1Object; import org.bouncycastle.asn1.ASN1Primitive; import org.bouncycastle.asn1.ASN1Sequence; import org.bouncycastle.asn1.DERSequence; public class DHParameter extends ASN1Object { ASN1Integer p, g, l; public DHParameter( BigInteger p, BigInteger g, int l) { this.p = new ASN1Integer(p); this.g = new ASN1Integer(g); if (l != 0) { this.l = new ASN1Integer(l); } else { this.l = null; } } public static DHParameter getInstance( Object obj) { if (obj instanceof DHParameter) { return (DHParameter)obj; } if (obj != null) { return new DHParameter(ASN1Sequence.getInstance(obj)); } return null; } private DHParameter( ASN1Sequence seq) { Enumeration e = seq.getObjects(); p = ASN1Integer.getInstance(e.nextElement()); g = ASN1Integer.getInstance(e.nextElement()); if (e.hasMoreElements()) { l = (ASN1Integer)e.nextElement(); } else { l = null; } } public BigInteger getP() { return p.getPositiveValue(); } public BigInteger getG() { return g.getPositiveValue(); } public BigInteger getL() { if (l == null) { return null; } return l.getPositiveValue(); } public ASN1Primitive toASN1Primitive() { ASN1EncodableVector v = new ASN1EncodableVector(); v.add(p); v.add(g); if (this.getL() != null) { v.add(l); } return new DERSequence(v); } } bouncycastle-1.49.orig/src/org/bouncycastle/asn1/pkcs/CertificationRequestInfo.java0000644000175000017500000001152712116544374030134 0ustar ebourgebourgpackage org.bouncycastle.asn1.pkcs; import org.bouncycastle.asn1.ASN1EncodableVector; import org.bouncycastle.asn1.ASN1Integer; import org.bouncycastle.asn1.ASN1Object; import org.bouncycastle.asn1.ASN1Primitive; import org.bouncycastle.asn1.ASN1Sequence; import org.bouncycastle.asn1.ASN1Set; import org.bouncycastle.asn1.DERSequence; import org.bouncycastle.asn1.DERTaggedObject; import org.bouncycastle.asn1.x500.X500Name; import org.bouncycastle.asn1.x509.SubjectPublicKeyInfo; import org.bouncycastle.asn1.x509.X509Name; /** * PKCS10 CertificationRequestInfo object. *
     *  CertificationRequestInfo ::= SEQUENCE {
     *   version             INTEGER { v1(0) } (v1,...),
     *   subject             Name,
     *   subjectPKInfo   SubjectPublicKeyInfo{{ PKInfoAlgorithms }},
     *   attributes          [0] Attributes{{ CRIAttributes }}
     *  }
     *
     *  Attributes { ATTRIBUTE:IOSet } ::= SET OF Attribute{{ IOSet }}
     *
     *  Attribute { ATTRIBUTE:IOSet } ::= SEQUENCE {
     *    type    ATTRIBUTE.&id({IOSet}),
     *    values  SET SIZE(1..MAX) OF ATTRIBUTE.&Type({IOSet}{\@type})
     *  }
     * 
    */ public class CertificationRequestInfo extends ASN1Object { ASN1Integer version = new ASN1Integer(0); X500Name subject; SubjectPublicKeyInfo subjectPKInfo; ASN1Set attributes = null; public static CertificationRequestInfo getInstance( Object obj) { if (obj instanceof CertificationRequestInfo) { return (CertificationRequestInfo)obj; } else if (obj != null) { return new CertificationRequestInfo(ASN1Sequence.getInstance(obj)); } return null; } /** * Basic constructor. *

    * Note: Early on a lot of CAs would only accept messages with attributes missing. As the ASN.1 def shows * the attributes field is not optional so should always at least contain an empty set. If a fully compliant * request is required, pass in an empty set, the class will otherwise interpret a null as it should * encode the request with the field missing. *

    * * @param subject subject to be associated with the public key * @param pkInfo public key to be associated with subject * @param attributes any attributes to be associated with the request. */ public CertificationRequestInfo( X500Name subject, SubjectPublicKeyInfo pkInfo, ASN1Set attributes) { this.subject = subject; this.subjectPKInfo = pkInfo; this.attributes = attributes; if ((subject == null) || (version == null) || (subjectPKInfo == null)) { throw new IllegalArgumentException("Not all mandatory fields set in CertificationRequestInfo generator."); } } /** * @deprecated use X500Name method. */ public CertificationRequestInfo( X509Name subject, SubjectPublicKeyInfo pkInfo, ASN1Set attributes) { this.subject = X500Name.getInstance(subject.toASN1Primitive()); this.subjectPKInfo = pkInfo; this.attributes = attributes; if ((subject == null) || (version == null) || (subjectPKInfo == null)) { throw new IllegalArgumentException("Not all mandatory fields set in CertificationRequestInfo generator."); } } /** * @deprecated use getInstance(). */ public CertificationRequestInfo( ASN1Sequence seq) { version = (ASN1Integer)seq.getObjectAt(0); subject = X500Name.getInstance(seq.getObjectAt(1)); subjectPKInfo = SubjectPublicKeyInfo.getInstance(seq.getObjectAt(2)); // // some CertificationRequestInfo objects seem to treat this field // as optional. // if (seq.size() > 3) { DERTaggedObject tagobj = (DERTaggedObject)seq.getObjectAt(3); attributes = ASN1Set.getInstance(tagobj, false); } if ((subject == null) || (version == null) || (subjectPKInfo == null)) { throw new IllegalArgumentException("Not all mandatory fields set in CertificationRequestInfo generator."); } } public ASN1Integer getVersion() { return version; } public X500Name getSubject() { return subject; } public SubjectPublicKeyInfo getSubjectPublicKeyInfo() { return subjectPKInfo; } public ASN1Set getAttributes() { return attributes; } public ASN1Primitive toASN1Primitive() { ASN1EncodableVector v = new ASN1EncodableVector(); v.add(version); v.add(subject); v.add(subjectPKInfo); if (attributes != null) { v.add(new DERTaggedObject(false, 0, attributes)); } return new DERSequence(v); } } bouncycastle-1.49.orig/src/org/bouncycastle/asn1/pkcs/KeyDerivationFunc.java0000644000175000017500000000250012110277315026534 0ustar ebourgebourgpackage org.bouncycastle.asn1.pkcs; import org.bouncycastle.asn1.ASN1Encodable; import org.bouncycastle.asn1.ASN1Object; import org.bouncycastle.asn1.ASN1ObjectIdentifier; import org.bouncycastle.asn1.ASN1Primitive; import org.bouncycastle.asn1.ASN1Sequence; import org.bouncycastle.asn1.x509.AlgorithmIdentifier; public class KeyDerivationFunc extends ASN1Object { private AlgorithmIdentifier algId; public KeyDerivationFunc( ASN1ObjectIdentifier objectId, ASN1Encodable parameters) { this.algId = new AlgorithmIdentifier(objectId, parameters); } private KeyDerivationFunc( ASN1Sequence seq) { this.algId = AlgorithmIdentifier.getInstance(seq); } public static final KeyDerivationFunc getInstance(Object obj) { if (obj instanceof KeyDerivationFunc) { return (KeyDerivationFunc)obj; } else if (obj != null) { return new KeyDerivationFunc(ASN1Sequence.getInstance(obj)); } return null; } public ASN1ObjectIdentifier getAlgorithm() { return algId.getAlgorithm(); } public ASN1Encodable getParameters() { return algId.getParameters(); } public ASN1Primitive toASN1Primitive() { return algId.toASN1Primitive(); } } bouncycastle-1.49.orig/src/org/bouncycastle/asn1/pkcs/PKCSObjectIdentifiers.java0000644000175000017500000003455711737141155027247 0ustar ebourgebourgpackage org.bouncycastle.asn1.pkcs; import org.bouncycastle.asn1.ASN1ObjectIdentifier; public interface PKCSObjectIdentifiers { // // pkcs-1 OBJECT IDENTIFIER ::= { // iso(1) member-body(2) us(840) rsadsi(113549) pkcs(1) 1 } // static final ASN1ObjectIdentifier pkcs_1 = new ASN1ObjectIdentifier("1.2.840.113549.1.1"); static final ASN1ObjectIdentifier rsaEncryption = pkcs_1.branch("1"); static final ASN1ObjectIdentifier md2WithRSAEncryption = pkcs_1.branch("2"); static final ASN1ObjectIdentifier md4WithRSAEncryption = pkcs_1.branch("3"); static final ASN1ObjectIdentifier md5WithRSAEncryption = pkcs_1.branch("4"); static final ASN1ObjectIdentifier sha1WithRSAEncryption = pkcs_1.branch("5"); static final ASN1ObjectIdentifier srsaOAEPEncryptionSET = pkcs_1.branch("6"); static final ASN1ObjectIdentifier id_RSAES_OAEP = pkcs_1.branch("7"); static final ASN1ObjectIdentifier id_mgf1 = pkcs_1.branch("8"); static final ASN1ObjectIdentifier id_pSpecified = pkcs_1.branch("9"); static final ASN1ObjectIdentifier id_RSASSA_PSS = pkcs_1.branch("10"); static final ASN1ObjectIdentifier sha256WithRSAEncryption = pkcs_1.branch("11"); static final ASN1ObjectIdentifier sha384WithRSAEncryption = pkcs_1.branch("12"); static final ASN1ObjectIdentifier sha512WithRSAEncryption = pkcs_1.branch("13"); static final ASN1ObjectIdentifier sha224WithRSAEncryption = pkcs_1.branch("14"); // // pkcs-3 OBJECT IDENTIFIER ::= { // iso(1) member-body(2) us(840) rsadsi(113549) pkcs(1) 3 } // static final ASN1ObjectIdentifier pkcs_3 = new ASN1ObjectIdentifier("1.2.840.113549.1.3"); static final ASN1ObjectIdentifier dhKeyAgreement = pkcs_3.branch("1"); // // pkcs-5 OBJECT IDENTIFIER ::= { // iso(1) member-body(2) us(840) rsadsi(113549) pkcs(1) 5 } // static final ASN1ObjectIdentifier pkcs_5 = new ASN1ObjectIdentifier("1.2.840.113549.1.5"); static final ASN1ObjectIdentifier pbeWithMD2AndDES_CBC = pkcs_5.branch("1"); static final ASN1ObjectIdentifier pbeWithMD2AndRC2_CBC = pkcs_5.branch("4"); static final ASN1ObjectIdentifier pbeWithMD5AndDES_CBC = pkcs_5.branch("3"); static final ASN1ObjectIdentifier pbeWithMD5AndRC2_CBC = pkcs_5.branch("6"); static final ASN1ObjectIdentifier pbeWithSHA1AndDES_CBC = pkcs_5.branch("10"); static final ASN1ObjectIdentifier pbeWithSHA1AndRC2_CBC = pkcs_5.branch("11"); static final ASN1ObjectIdentifier id_PBES2 = pkcs_5.branch("13"); static final ASN1ObjectIdentifier id_PBKDF2 = pkcs_5.branch("12"); // // encryptionAlgorithm OBJECT IDENTIFIER ::= { // iso(1) member-body(2) us(840) rsadsi(113549) 3 } // static final ASN1ObjectIdentifier encryptionAlgorithm = new ASN1ObjectIdentifier("1.2.840.113549.3"); static final ASN1ObjectIdentifier des_EDE3_CBC = encryptionAlgorithm.branch("7"); static final ASN1ObjectIdentifier RC2_CBC = encryptionAlgorithm.branch("2"); static final ASN1ObjectIdentifier rc4 = encryptionAlgorithm.branch("4"); // // object identifiers for digests // static final ASN1ObjectIdentifier digestAlgorithm = new ASN1ObjectIdentifier("1.2.840.113549.2"); // // md2 OBJECT IDENTIFIER ::= // {iso(1) member-body(2) US(840) rsadsi(113549) digestAlgorithm(2) 2} // static final ASN1ObjectIdentifier md2 = digestAlgorithm.branch("2"); // // md4 OBJECT IDENTIFIER ::= // {iso(1) member-body(2) US(840) rsadsi(113549) digestAlgorithm(2) 4} // static final ASN1ObjectIdentifier md4 = digestAlgorithm.branch("4"); // // md5 OBJECT IDENTIFIER ::= // {iso(1) member-body(2) US(840) rsadsi(113549) digestAlgorithm(2) 5} // static final ASN1ObjectIdentifier md5 = digestAlgorithm.branch("5"); static final ASN1ObjectIdentifier id_hmacWithSHA1 = digestAlgorithm.branch("7"); static final ASN1ObjectIdentifier id_hmacWithSHA224 = digestAlgorithm.branch("8"); static final ASN1ObjectIdentifier id_hmacWithSHA256 = digestAlgorithm.branch("9"); static final ASN1ObjectIdentifier id_hmacWithSHA384 = digestAlgorithm.branch("10"); static final ASN1ObjectIdentifier id_hmacWithSHA512 = digestAlgorithm.branch("11"); // // pkcs-7 OBJECT IDENTIFIER ::= { // iso(1) member-body(2) us(840) rsadsi(113549) pkcs(1) 7 } // static final String pkcs_7 = "1.2.840.113549.1.7"; static final ASN1ObjectIdentifier data = new ASN1ObjectIdentifier(pkcs_7 + ".1"); static final ASN1ObjectIdentifier signedData = new ASN1ObjectIdentifier(pkcs_7 + ".2"); static final ASN1ObjectIdentifier envelopedData = new ASN1ObjectIdentifier(pkcs_7 + ".3"); static final ASN1ObjectIdentifier signedAndEnvelopedData = new ASN1ObjectIdentifier(pkcs_7 + ".4"); static final ASN1ObjectIdentifier digestedData = new ASN1ObjectIdentifier(pkcs_7 + ".5"); static final ASN1ObjectIdentifier encryptedData = new ASN1ObjectIdentifier(pkcs_7 + ".6"); // // pkcs-9 OBJECT IDENTIFIER ::= { // iso(1) member-body(2) us(840) rsadsi(113549) pkcs(1) 9 } // static final ASN1ObjectIdentifier pkcs_9 = new ASN1ObjectIdentifier("1.2.840.113549.1.9"); static final ASN1ObjectIdentifier pkcs_9_at_emailAddress = pkcs_9.branch("1"); static final ASN1ObjectIdentifier pkcs_9_at_unstructuredName = pkcs_9.branch("2"); static final ASN1ObjectIdentifier pkcs_9_at_contentType = pkcs_9.branch("3"); static final ASN1ObjectIdentifier pkcs_9_at_messageDigest = pkcs_9.branch("4"); static final ASN1ObjectIdentifier pkcs_9_at_signingTime = pkcs_9.branch("5"); static final ASN1ObjectIdentifier pkcs_9_at_counterSignature = pkcs_9.branch("6"); static final ASN1ObjectIdentifier pkcs_9_at_challengePassword = pkcs_9.branch("7"); static final ASN1ObjectIdentifier pkcs_9_at_unstructuredAddress = pkcs_9.branch("8"); static final ASN1ObjectIdentifier pkcs_9_at_extendedCertificateAttributes = pkcs_9.branch("9"); static final ASN1ObjectIdentifier pkcs_9_at_signingDescription = pkcs_9.branch("13"); static final ASN1ObjectIdentifier pkcs_9_at_extensionRequest = pkcs_9.branch("14"); static final ASN1ObjectIdentifier pkcs_9_at_smimeCapabilities = pkcs_9.branch("15"); static final ASN1ObjectIdentifier pkcs_9_at_friendlyName = pkcs_9.branch("20"); static final ASN1ObjectIdentifier pkcs_9_at_localKeyId = pkcs_9.branch("21"); /** @deprecated use x509Certificate instead */ static final ASN1ObjectIdentifier x509certType = pkcs_9.branch("22.1"); static final ASN1ObjectIdentifier certTypes = pkcs_9.branch("22"); static final ASN1ObjectIdentifier x509Certificate = certTypes.branch("1"); static final ASN1ObjectIdentifier sdsiCertificate = certTypes.branch("2"); static final ASN1ObjectIdentifier crlTypes = pkcs_9.branch("23"); static final ASN1ObjectIdentifier x509Crl = crlTypes.branch("1"); static final ASN1ObjectIdentifier id_alg_PWRI_KEK = pkcs_9.branch("16.3.9"); // // SMIME capability sub oids. // static final ASN1ObjectIdentifier preferSignedData = pkcs_9.branch("15.1"); static final ASN1ObjectIdentifier canNotDecryptAny = pkcs_9.branch("15.2"); static final ASN1ObjectIdentifier sMIMECapabilitiesVersions = pkcs_9.branch("15.3"); // // id-ct OBJECT IDENTIFIER ::= {iso(1) member-body(2) usa(840) // rsadsi(113549) pkcs(1) pkcs-9(9) smime(16) ct(1)} // static final ASN1ObjectIdentifier id_ct = new ASN1ObjectIdentifier("1.2.840.113549.1.9.16.1"); static final ASN1ObjectIdentifier id_ct_authData = id_ct.branch("2"); static final ASN1ObjectIdentifier id_ct_TSTInfo = id_ct.branch("4"); static final ASN1ObjectIdentifier id_ct_compressedData = id_ct.branch("9"); static final ASN1ObjectIdentifier id_ct_authEnvelopedData = id_ct.branch("23"); static final ASN1ObjectIdentifier id_ct_timestampedData = id_ct.branch("31"); // // id-cti OBJECT IDENTIFIER ::= {iso(1) member-body(2) usa(840) // rsadsi(113549) pkcs(1) pkcs-9(9) smime(16) cti(6)} // static final ASN1ObjectIdentifier id_cti = new ASN1ObjectIdentifier("1.2.840.113549.1.9.16.6"); static final ASN1ObjectIdentifier id_cti_ets_proofOfOrigin = id_cti.branch("1"); static final ASN1ObjectIdentifier id_cti_ets_proofOfReceipt = id_cti.branch("2"); static final ASN1ObjectIdentifier id_cti_ets_proofOfDelivery = id_cti.branch("3"); static final ASN1ObjectIdentifier id_cti_ets_proofOfSender = id_cti.branch("4"); static final ASN1ObjectIdentifier id_cti_ets_proofOfApproval = id_cti.branch("5"); static final ASN1ObjectIdentifier id_cti_ets_proofOfCreation = id_cti.branch("6"); // // id-aa OBJECT IDENTIFIER ::= {iso(1) member-body(2) usa(840) // rsadsi(113549) pkcs(1) pkcs-9(9) smime(16) attributes(2)} // static final ASN1ObjectIdentifier id_aa = new ASN1ObjectIdentifier("1.2.840.113549.1.9.16.2"); static final ASN1ObjectIdentifier id_aa_receiptRequest = id_aa.branch("1"); static final ASN1ObjectIdentifier id_aa_contentHint = id_aa.branch("4"); // See RFC 2634 static final ASN1ObjectIdentifier id_aa_msgSigDigest = id_aa.branch("5"); static final ASN1ObjectIdentifier id_aa_contentReference = id_aa.branch("10"); /* * id-aa-encrypKeyPref OBJECT IDENTIFIER ::= {id-aa 11} * */ static final ASN1ObjectIdentifier id_aa_encrypKeyPref = id_aa.branch("11"); static final ASN1ObjectIdentifier id_aa_signingCertificate = id_aa.branch("12"); static final ASN1ObjectIdentifier id_aa_signingCertificateV2 = id_aa.branch("47"); static final ASN1ObjectIdentifier id_aa_contentIdentifier = id_aa.branch("7"); // See RFC 2634 /* * RFC 3126 */ static final ASN1ObjectIdentifier id_aa_signatureTimeStampToken = id_aa.branch("14"); static final ASN1ObjectIdentifier id_aa_ets_sigPolicyId = id_aa.branch("15"); static final ASN1ObjectIdentifier id_aa_ets_commitmentType = id_aa.branch("16"); static final ASN1ObjectIdentifier id_aa_ets_signerLocation = id_aa.branch("17"); static final ASN1ObjectIdentifier id_aa_ets_signerAttr = id_aa.branch("18"); static final ASN1ObjectIdentifier id_aa_ets_otherSigCert = id_aa.branch("19"); static final ASN1ObjectIdentifier id_aa_ets_contentTimestamp = id_aa.branch("20"); static final ASN1ObjectIdentifier id_aa_ets_certificateRefs = id_aa.branch("21"); static final ASN1ObjectIdentifier id_aa_ets_revocationRefs = id_aa.branch("22"); static final ASN1ObjectIdentifier id_aa_ets_certValues = id_aa.branch("23"); static final ASN1ObjectIdentifier id_aa_ets_revocationValues = id_aa.branch("24"); static final ASN1ObjectIdentifier id_aa_ets_escTimeStamp = id_aa.branch("25"); static final ASN1ObjectIdentifier id_aa_ets_certCRLTimestamp = id_aa.branch("26"); static final ASN1ObjectIdentifier id_aa_ets_archiveTimestamp = id_aa.branch("27"); /** @deprecated use id_aa_ets_sigPolicyId instead */ static final ASN1ObjectIdentifier id_aa_sigPolicyId = id_aa_ets_sigPolicyId; /** @deprecated use id_aa_ets_commitmentType instead */ static final ASN1ObjectIdentifier id_aa_commitmentType = id_aa_ets_commitmentType; /** @deprecated use id_aa_ets_signerLocation instead */ static final ASN1ObjectIdentifier id_aa_signerLocation = id_aa_ets_signerLocation; /** @deprecated use id_aa_ets_otherSigCert instead */ static final ASN1ObjectIdentifier id_aa_otherSigCert = id_aa_ets_otherSigCert; // // id-spq OBJECT IDENTIFIER ::= {iso(1) member-body(2) usa(840) // rsadsi(113549) pkcs(1) pkcs-9(9) smime(16) id-spq(5)} // final String id_spq = "1.2.840.113549.1.9.16.5"; static final ASN1ObjectIdentifier id_spq_ets_uri = new ASN1ObjectIdentifier(id_spq + ".1"); static final ASN1ObjectIdentifier id_spq_ets_unotice = new ASN1ObjectIdentifier(id_spq + ".2"); // // pkcs-12 OBJECT IDENTIFIER ::= { // iso(1) member-body(2) us(840) rsadsi(113549) pkcs(1) 12 } // static final ASN1ObjectIdentifier pkcs_12 = new ASN1ObjectIdentifier("1.2.840.113549.1.12"); static final ASN1ObjectIdentifier bagtypes = pkcs_12.branch("10.1"); static final ASN1ObjectIdentifier keyBag = bagtypes.branch("1"); static final ASN1ObjectIdentifier pkcs8ShroudedKeyBag = bagtypes.branch("2"); static final ASN1ObjectIdentifier certBag = bagtypes.branch("3"); static final ASN1ObjectIdentifier crlBag = bagtypes.branch("4"); static final ASN1ObjectIdentifier secretBag = bagtypes.branch("5"); static final ASN1ObjectIdentifier safeContentsBag = bagtypes.branch("6"); static final ASN1ObjectIdentifier pkcs_12PbeIds = pkcs_12.branch("1"); static final ASN1ObjectIdentifier pbeWithSHAAnd128BitRC4 = pkcs_12PbeIds.branch("1"); static final ASN1ObjectIdentifier pbeWithSHAAnd40BitRC4 = pkcs_12PbeIds.branch("2"); static final ASN1ObjectIdentifier pbeWithSHAAnd3_KeyTripleDES_CBC = pkcs_12PbeIds.branch("3"); static final ASN1ObjectIdentifier pbeWithSHAAnd2_KeyTripleDES_CBC = pkcs_12PbeIds.branch("4"); static final ASN1ObjectIdentifier pbeWithSHAAnd128BitRC2_CBC = pkcs_12PbeIds.branch("5"); static final ASN1ObjectIdentifier pbeWithSHAAnd40BitRC2_CBC = pkcs_12PbeIds.branch("6"); /** * @deprecated use pbeWithSHAAnd40BitRC2_CBC */ static final ASN1ObjectIdentifier pbewithSHAAnd40BitRC2_CBC = pkcs_12PbeIds.branch("6"); static final ASN1ObjectIdentifier id_alg_CMS3DESwrap = new ASN1ObjectIdentifier("1.2.840.113549.1.9.16.3.6"); static final ASN1ObjectIdentifier id_alg_CMSRC2wrap = new ASN1ObjectIdentifier("1.2.840.113549.1.9.16.3.7"); } bouncycastle-1.49.orig/src/org/bouncycastle/asn1/pkcs/PBES2Parameters.java0000644000175000017500000000356712114551714026022 0ustar ebourgebourgpackage org.bouncycastle.asn1.pkcs; import java.util.Enumeration; import org.bouncycastle.asn1.ASN1Encodable; import org.bouncycastle.asn1.ASN1EncodableVector; import org.bouncycastle.asn1.ASN1Object; import org.bouncycastle.asn1.ASN1Primitive; import org.bouncycastle.asn1.ASN1Sequence; import org.bouncycastle.asn1.DERSequence; public class PBES2Parameters extends ASN1Object implements PKCSObjectIdentifiers { private KeyDerivationFunc func; private EncryptionScheme scheme; public static PBES2Parameters getInstance( Object obj) { if (obj instanceof PBES2Parameters) { return (PBES2Parameters)obj; } if (obj != null) { return new PBES2Parameters(ASN1Sequence.getInstance(obj)); } return null; } public PBES2Parameters(KeyDerivationFunc keyDevFunc, EncryptionScheme encScheme) { this.func = keyDevFunc; this.scheme = encScheme; } private PBES2Parameters( ASN1Sequence obj) { Enumeration e = obj.getObjects(); ASN1Sequence funcSeq = ASN1Sequence.getInstance(((ASN1Encodable)e.nextElement()).toASN1Primitive()); if (funcSeq.getObjectAt(0).equals(id_PBKDF2)) { func = new KeyDerivationFunc(id_PBKDF2, PBKDF2Params.getInstance(funcSeq.getObjectAt(1))); } else { func = KeyDerivationFunc.getInstance(funcSeq); } scheme = EncryptionScheme.getInstance(e.nextElement()); } public KeyDerivationFunc getKeyDerivationFunc() { return func; } public EncryptionScheme getEncryptionScheme() { return scheme; } public ASN1Primitive toASN1Primitive() { ASN1EncodableVector v = new ASN1EncodableVector(); v.add(func); v.add(scheme); return new DERSequence(v); } } bouncycastle-1.49.orig/src/org/bouncycastle/asn1/pkcs/AuthenticatedSafe.java0000644000175000017500000000306011730257757026545 0ustar ebourgebourgpackage org.bouncycastle.asn1.pkcs; import org.bouncycastle.asn1.ASN1EncodableVector; import org.bouncycastle.asn1.ASN1Object; import org.bouncycastle.asn1.ASN1Primitive; import org.bouncycastle.asn1.ASN1Sequence; import org.bouncycastle.asn1.BERSequence; import org.bouncycastle.asn1.DLSequence; public class AuthenticatedSafe extends ASN1Object { private ContentInfo[] info; private boolean isBer = true; private AuthenticatedSafe( ASN1Sequence seq) { info = new ContentInfo[seq.size()]; for (int i = 0; i != info.length; i++) { info[i] = ContentInfo.getInstance(seq.getObjectAt(i)); } isBer = seq instanceof BERSequence; } public static AuthenticatedSafe getInstance( Object o) { if (o instanceof AuthenticatedSafe) { return (AuthenticatedSafe)o; } if (o != null) { return new AuthenticatedSafe(ASN1Sequence.getInstance(o)); } return null; } public AuthenticatedSafe( ContentInfo[] info) { this.info = info; } public ContentInfo[] getContentInfo() { return info; } public ASN1Primitive toASN1Primitive() { ASN1EncodableVector v = new ASN1EncodableVector(); for (int i = 0; i != info.length; i++) { v.add(info[i]); } if (isBer) { return new BERSequence(v); } else { return new DLSequence(v); } } } bouncycastle-1.49.orig/src/org/bouncycastle/asn1/pkcs/SignerInfo.java0000644000175000017500000001232511724561172025223 0ustar ebourgebourgpackage org.bouncycastle.asn1.pkcs; import java.util.Enumeration; import org.bouncycastle.asn1.ASN1EncodableVector; import org.bouncycastle.asn1.ASN1Integer; import org.bouncycastle.asn1.ASN1Object; import org.bouncycastle.asn1.ASN1OctetString; 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.DERTaggedObject; import org.bouncycastle.asn1.x509.AlgorithmIdentifier; /** * a PKCS#7 signer info object. */ public class SignerInfo extends ASN1Object { private ASN1Integer version; private IssuerAndSerialNumber issuerAndSerialNumber; private AlgorithmIdentifier digAlgorithm; private ASN1Set authenticatedAttributes; private AlgorithmIdentifier digEncryptionAlgorithm; private ASN1OctetString encryptedDigest; private ASN1Set unauthenticatedAttributes; public static SignerInfo getInstance( Object o) { if (o instanceof SignerInfo) { return (SignerInfo)o; } else if (o instanceof ASN1Sequence) { return new SignerInfo((ASN1Sequence)o); } throw new IllegalArgumentException("unknown object in factory: " + o.getClass().getName()); } public SignerInfo( ASN1Integer version, IssuerAndSerialNumber issuerAndSerialNumber, AlgorithmIdentifier digAlgorithm, ASN1Set authenticatedAttributes, AlgorithmIdentifier digEncryptionAlgorithm, ASN1OctetString encryptedDigest, ASN1Set unauthenticatedAttributes) { this.version = version; this.issuerAndSerialNumber = issuerAndSerialNumber; this.digAlgorithm = digAlgorithm; this.authenticatedAttributes = authenticatedAttributes; this.digEncryptionAlgorithm = digEncryptionAlgorithm; this.encryptedDigest = encryptedDigest; this.unauthenticatedAttributes = unauthenticatedAttributes; } public SignerInfo( ASN1Sequence seq) { Enumeration e = seq.getObjects(); version = (ASN1Integer)e.nextElement(); issuerAndSerialNumber = IssuerAndSerialNumber.getInstance(e.nextElement()); digAlgorithm = AlgorithmIdentifier.getInstance(e.nextElement()); Object obj = e.nextElement(); if (obj instanceof ASN1TaggedObject) { authenticatedAttributes = ASN1Set.getInstance((ASN1TaggedObject)obj, false); digEncryptionAlgorithm = AlgorithmIdentifier.getInstance(e.nextElement()); } else { authenticatedAttributes = null; digEncryptionAlgorithm = AlgorithmIdentifier.getInstance(obj); } encryptedDigest = DEROctetString.getInstance(e.nextElement()); if (e.hasMoreElements()) { unauthenticatedAttributes = ASN1Set.getInstance((ASN1TaggedObject)e.nextElement(), false); } else { unauthenticatedAttributes = null; } } public ASN1Integer getVersion() { return version; } public IssuerAndSerialNumber getIssuerAndSerialNumber() { return issuerAndSerialNumber; } public ASN1Set getAuthenticatedAttributes() { return authenticatedAttributes; } public AlgorithmIdentifier getDigestAlgorithm() { return digAlgorithm; } public ASN1OctetString getEncryptedDigest() { return encryptedDigest; } public AlgorithmIdentifier getDigestEncryptionAlgorithm() { return digEncryptionAlgorithm; } public ASN1Set getUnauthenticatedAttributes() { return unauthenticatedAttributes; } /** * Produce an object suitable for an ASN1OutputStream. *
         *  SignerInfo ::= SEQUENCE {
         *      version Version,
         *      issuerAndSerialNumber IssuerAndSerialNumber,
         *      digestAlgorithm DigestAlgorithmIdentifier,
         *      authenticatedAttributes [0] IMPLICIT Attributes OPTIONAL,
         *      digestEncryptionAlgorithm DigestEncryptionAlgorithmIdentifier,
         *      encryptedDigest EncryptedDigest,
         *      unauthenticatedAttributes [1] IMPLICIT Attributes OPTIONAL
         *  }
         *
         *  EncryptedDigest ::= OCTET STRING
         *
         *  DigestAlgorithmIdentifier ::= AlgorithmIdentifier
         *
         *  DigestEncryptionAlgorithmIdentifier ::= AlgorithmIdentifier
         * 
    */ public ASN1Primitive toASN1Primitive() { ASN1EncodableVector v = new ASN1EncodableVector(); v.add(version); v.add(issuerAndSerialNumber); v.add(digAlgorithm); if (authenticatedAttributes != null) { v.add(new DERTaggedObject(false, 0, authenticatedAttributes)); } v.add(digEncryptionAlgorithm); v.add(encryptedDigest); if (unauthenticatedAttributes != null) { v.add(new DERTaggedObject(false, 1, unauthenticatedAttributes)); } return new DERSequence(v); } } bouncycastle-1.49.orig/src/org/bouncycastle/asn1/pkcs/PrivateKeyInfo.java0000644000175000017500000001063612110312313026037 0ustar ebourgebourgpackage org.bouncycastle.asn1.pkcs; import java.io.IOException; import java.math.BigInteger; import java.util.Enumeration; import org.bouncycastle.asn1.ASN1Encodable; import org.bouncycastle.asn1.ASN1EncodableVector; import org.bouncycastle.asn1.ASN1Encoding; import org.bouncycastle.asn1.ASN1Integer; import org.bouncycastle.asn1.ASN1Object; import org.bouncycastle.asn1.ASN1OctetString; 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.DERTaggedObject; import org.bouncycastle.asn1.x509.AlgorithmIdentifier; public class PrivateKeyInfo extends ASN1Object { private ASN1OctetString privKey; private AlgorithmIdentifier algId; private ASN1Set attributes; public static PrivateKeyInfo getInstance( ASN1TaggedObject obj, boolean explicit) { return getInstance(ASN1Sequence.getInstance(obj, explicit)); } public static PrivateKeyInfo getInstance( Object obj) { if (obj instanceof PrivateKeyInfo) { return (PrivateKeyInfo)obj; } else if (obj != null) { return new PrivateKeyInfo(ASN1Sequence.getInstance(obj)); } return null; } public PrivateKeyInfo( AlgorithmIdentifier algId, ASN1Encodable privateKey) throws IOException { this(algId, privateKey, null); } public PrivateKeyInfo( AlgorithmIdentifier algId, ASN1Encodable privateKey, ASN1Set attributes) throws IOException { this.privKey = new DEROctetString(privateKey.toASN1Primitive().getEncoded(ASN1Encoding.DER)); this.algId = algId; this.attributes = attributes; } /** * @deprectaed use PrivateKeyInfo.getInstance() * @param seq */ public PrivateKeyInfo( ASN1Sequence seq) { Enumeration e = seq.getObjects(); BigInteger version = ((ASN1Integer)e.nextElement()).getValue(); if (version.intValue() != 0) { throw new IllegalArgumentException("wrong version for private key info"); } algId = AlgorithmIdentifier.getInstance(e.nextElement()); privKey = ASN1OctetString.getInstance(e.nextElement()); if (e.hasMoreElements()) { attributes = ASN1Set.getInstance((ASN1TaggedObject)e.nextElement(), false); } } public AlgorithmIdentifier getPrivateKeyAlgorithm() { return algId; } /** * @deprecated use getPrivateKeyAlgorithm() */ public AlgorithmIdentifier getAlgorithmId() { return algId; } public ASN1Encodable parsePrivateKey() throws IOException { return ASN1Primitive.fromByteArray(privKey.getOctets()); } /** * @deprecated use parsePrivateKey() */ public ASN1Primitive getPrivateKey() { try { return parsePrivateKey().toASN1Primitive(); } catch (IOException e) { throw new IllegalStateException("unable to parse private key"); } } public ASN1Set getAttributes() { return attributes; } /** * write out an RSA private key with its associated information * as described in PKCS8. *
         *      PrivateKeyInfo ::= SEQUENCE {
         *                              version Version,
         *                              privateKeyAlgorithm AlgorithmIdentifier {{PrivateKeyAlgorithms}},
         *                              privateKey PrivateKey,
         *                              attributes [0] IMPLICIT Attributes OPTIONAL 
         *                          }
         *      Version ::= INTEGER {v1(0)} (v1,...)
         *
         *      PrivateKey ::= OCTET STRING
         *
         *      Attributes ::= SET OF Attribute
         * 
    */ public ASN1Primitive toASN1Primitive() { ASN1EncodableVector v = new ASN1EncodableVector(); v.add(new ASN1Integer(0)); v.add(algId); v.add(privKey); if (attributes != null) { v.add(new DERTaggedObject(false, 0, attributes)); } return new DERSequence(v); } } bouncycastle-1.49.orig/src/org/bouncycastle/asn1/pkcs/RC2CBCParameter.java0000644000175000017500000000372411725272215025720 0ustar ebourgebourgpackage org.bouncycastle.asn1.pkcs; import java.math.BigInteger; import org.bouncycastle.asn1.ASN1EncodableVector; import org.bouncycastle.asn1.ASN1Integer; import org.bouncycastle.asn1.ASN1Object; import org.bouncycastle.asn1.ASN1OctetString; import org.bouncycastle.asn1.ASN1Primitive; import org.bouncycastle.asn1.ASN1Sequence; import org.bouncycastle.asn1.DEROctetString; import org.bouncycastle.asn1.DERSequence; public class RC2CBCParameter extends ASN1Object { ASN1Integer version; ASN1OctetString iv; public static RC2CBCParameter getInstance( Object o) { if (o instanceof RC2CBCParameter) { return (RC2CBCParameter)o; } if (o != null) { return new RC2CBCParameter(ASN1Sequence.getInstance(o)); } return null; } public RC2CBCParameter( byte[] iv) { this.version = null; this.iv = new DEROctetString(iv); } public RC2CBCParameter( int parameterVersion, byte[] iv) { this.version = new ASN1Integer(parameterVersion); this.iv = new DEROctetString(iv); } private RC2CBCParameter( ASN1Sequence seq) { if (seq.size() == 1) { version = null; iv = (ASN1OctetString)seq.getObjectAt(0); } else { version = (ASN1Integer)seq.getObjectAt(0); iv = (ASN1OctetString)seq.getObjectAt(1); } } public BigInteger getRC2ParameterVersion() { if (version == null) { return null; } return version.getValue(); } public byte[] getIV() { return iv.getOctets(); } public ASN1Primitive toASN1Primitive() { ASN1EncodableVector v = new ASN1EncodableVector(); if (version != null) { v.add(version); } v.add(iv); return new DERSequence(v); } } bouncycastle-1.49.orig/src/org/bouncycastle/asn1/pkcs/PKCS12PBEParams.java0000644000175000017500000000310400000000371025517 0ustar ebourgebourgpackage org.bouncycastle.asn1.pkcs; import java.math.BigInteger; import org.bouncycastle.asn1.ASN1EncodableVector; import org.bouncycastle.asn1.ASN1Integer; import org.bouncycastle.asn1.ASN1Object; import org.bouncycastle.asn1.ASN1OctetString; import org.bouncycastle.asn1.ASN1Primitive; import org.bouncycastle.asn1.ASN1Sequence; import org.bouncycastle.asn1.DEROctetString; import org.bouncycastle.asn1.DERSequence; public class PKCS12PBEParams extends ASN1Object { ASN1Integer iterations; ASN1OctetString iv; public PKCS12PBEParams( byte[] salt, int iterations) { this.iv = new DEROctetString(salt); this.iterations = new ASN1Integer(iterations); } private PKCS12PBEParams( ASN1Sequence seq) { iv = (ASN1OctetString)seq.getObjectAt(0); iterations = ASN1Integer.getInstance(seq.getObjectAt(1)); } public static PKCS12PBEParams getInstance( Object obj) { if (obj instanceof PKCS12PBEParams) { return (PKCS12PBEParams)obj; } else if (obj != null) { return new PKCS12PBEParams(ASN1Sequence.getInstance(obj)); } return null; } public BigInteger getIterations() { return iterations.getValue(); } public byte[] getIV() { return iv.getOctets(); } public ASN1Primitive toASN1Primitive() { ASN1EncodableVector v = new ASN1EncodableVector(); v.add(iv); v.add(iterations); return new DERSequence(v); } } bouncycastle-1.49.orig/src/org/bouncycastle/asn1/pkcs/package.html0000644000175000017500000000020310262753175024570 0ustar ebourgebourg Support classes useful for encoding and supporting the various RSA PKCS documents. bouncycastle-1.49.orig/src/org/bouncycastle/asn1/pkcs/CRLBag.java0000644000175000017500000000360011730473631024205 0ustar ebourgebourgpackage org.bouncycastle.asn1.pkcs; import org.bouncycastle.asn1.ASN1Encodable; import org.bouncycastle.asn1.ASN1EncodableVector; import org.bouncycastle.asn1.ASN1Object; import org.bouncycastle.asn1.ASN1ObjectIdentifier; import org.bouncycastle.asn1.ASN1Primitive; import org.bouncycastle.asn1.ASN1Sequence; import org.bouncycastle.asn1.DERSequence; import org.bouncycastle.asn1.DERTaggedObject; public class CRLBag extends ASN1Object { private ASN1ObjectIdentifier crlId; private ASN1Encodable crlValue; private CRLBag( ASN1Sequence seq) { this.crlId = (ASN1ObjectIdentifier)seq.getObjectAt(0); this.crlValue = ((DERTaggedObject)seq.getObjectAt(1)).getObject(); } public static CRLBag getInstance(Object o) { if (o instanceof CRLBag) { return (CRLBag)o; } else if (o != null) { return new CRLBag(ASN1Sequence.getInstance(o)); } return null; } public CRLBag( ASN1ObjectIdentifier crlId, ASN1Encodable crlValue) { this.crlId = crlId; this.crlValue = crlValue; } public ASN1ObjectIdentifier getcrlId() { return crlId; } public ASN1Encodable getCRLValue() { return crlValue; } /** *
         CRLBag ::= SEQUENCE {
         crlId  BAG-TYPE.&id ({CRLTypes}),
         crlValue  [0] EXPLICIT BAG-TYPE.&Type ({CRLTypes}{@crlId})
         }
    
         x509CRL BAG-TYPE ::= {OCTET STRING IDENTIFIED BY {certTypes 1}
         -- DER-encoded X.509 CRL stored in OCTET STRING
    
         CRLTypes BAG-TYPE ::= {
         x509CRL,
         ... -- For future extensions
         }
           
    */ public ASN1Primitive toASN1Primitive() { ASN1EncodableVector v = new ASN1EncodableVector(); v.add(crlId); v.add(new DERTaggedObject(0, crlValue)); return new DERSequence(v); } } bouncycastle-1.49.orig/src/org/bouncycastle/asn1/ua/0000755000175000017500000000000012152033551021746 5ustar ebourgebourgbouncycastle-1.49.orig/src/org/bouncycastle/asn1/ua/DSTU4145NamedCurves.java0000644000175000017500000001464012104603006026043 0ustar ebourgebourgpackage org.bouncycastle.asn1.ua; import java.math.BigInteger; import org.bouncycastle.asn1.ASN1ObjectIdentifier; import org.bouncycastle.crypto.params.ECDomainParameters; import org.bouncycastle.math.ec.ECCurve; import org.bouncycastle.math.ec.ECPoint; public class DSTU4145NamedCurves { private static final BigInteger ZERO = BigInteger.valueOf(0); private static final BigInteger ONE = BigInteger.valueOf(1); public static final ECDomainParameters[] params = new ECDomainParameters[10]; static final ASN1ObjectIdentifier[] oids = new ASN1ObjectIdentifier[10]; //All named curves have the following oid format: 1.2.804.2.1.1.1.1.3.1.1.2.X //where X is the curve number 0-9 static final String oidBase = UAObjectIdentifiers.dstu4145le.getId() + ".2."; static { ECCurve.F2m[] curves = new ECCurve.F2m[10]; curves[0] = new ECCurve.F2m(163, 3, 6, 7, ONE, new BigInteger("5FF6108462A2DC8210AB403925E638A19C1455D21", 16)); curves[1] = new ECCurve.F2m(167, 6, ONE, new BigInteger("6EE3CEEB230811759F20518A0930F1A4315A827DAC", 16)); curves[2] = new ECCurve.F2m(173, 1, 2, 10, ZERO, new BigInteger("108576C80499DB2FC16EDDF6853BBB278F6B6FB437D9", 16)); curves[3] = new ECCurve.F2m(179, 1, 2, 4, ONE, new BigInteger("4A6E0856526436F2F88DD07A341E32D04184572BEB710", 16)); curves[4] = new ECCurve.F2m(191, 9, ONE, new BigInteger("7BC86E2102902EC4D5890E8B6B4981ff27E0482750FEFC03", 16)); curves[5] = new ECCurve.F2m(233, 1, 4, 9, ONE, new BigInteger("06973B15095675534C7CF7E64A21BD54EF5DD3B8A0326AA936ECE454D2C", 16)); curves[6] = new ECCurve.F2m(257, 12, ZERO, new BigInteger("1CEF494720115657E18F938D7A7942394FF9425C1458C57861F9EEA6ADBE3BE10", 16)); curves[7] = new ECCurve.F2m(307, 2, 4, 8, ONE, new BigInteger("393C7F7D53666B5054B5E6C6D3DE94F4296C0C599E2E2E241050DF18B6090BDC90186904968BB", 16)); curves[8] = new ECCurve.F2m(367, 21, ONE, new BigInteger("43FC8AD242B0B7A6F3D1627AD5654447556B47BF6AA4A64B0C2AFE42CADAB8F93D92394C79A79755437B56995136", 16)); curves[9] = new ECCurve.F2m(431, 1, 3, 5, ONE, new BigInteger("03CE10490F6A708FC26DFE8C3D27C4F94E690134D5BFF988D8D28AAEAEDE975936C66BAC536B18AE2DC312CA493117DAA469C640CAF3", 16)); ECPoint[] points = new ECPoint[10]; points[0] = curves[0].createPoint(new BigInteger("2E2F85F5DD74CE983A5C4237229DAF8A3F35823BE", 16), new BigInteger("3826F008A8C51D7B95284D9D03FF0E00CE2CD723A", 16), false); points[1] = curves[1].createPoint(new BigInteger("7A1F6653786A68192803910A3D30B2A2018B21CD54", 16), new BigInteger("5F49EB26781C0EC6B8909156D98ED435E45FD59918", 16), false); points[2] = curves[2].createPoint(new BigInteger("4D41A619BCC6EADF0448FA22FAD567A9181D37389CA", 16), new BigInteger("10B51CC12849B234C75E6DD2028BF7FF5C1CE0D991A1", 16), false); points[3] = curves[3].createPoint(new BigInteger("6BA06FE51464B2BD26DC57F48819BA9954667022C7D03", 16), new BigInteger("25FBC363582DCEC065080CA8287AAFF09788A66DC3A9E", 16), false); points[4] = curves[4].createPoint(new BigInteger("714114B762F2FF4A7912A6D2AC58B9B5C2FCFE76DAEB7129", 16), new BigInteger("29C41E568B77C617EFE5902F11DB96FA9613CD8D03DB08DA", 16), false); points[5] = curves[5].createPoint(new BigInteger("3FCDA526B6CDF83BA1118DF35B3C31761D3545F32728D003EEB25EFE96", 16), new BigInteger("9CA8B57A934C54DEEDA9E54A7BBAD95E3B2E91C54D32BE0B9DF96D8D35", 16), false); points[6] = curves[6].createPoint(new BigInteger("02A29EF207D0E9B6C55CD260B306C7E007AC491CA1B10C62334A9E8DCD8D20FB7", 16), new BigInteger("10686D41FF744D4449FCCF6D8EEA03102E6812C93A9D60B978B702CF156D814EF", 16), false); points[7] = curves[7].createPoint(new BigInteger("216EE8B189D291A0224984C1E92F1D16BF75CCD825A087A239B276D3167743C52C02D6E7232AA", 16), new BigInteger("5D9306BACD22B7FAEB09D2E049C6E2866C5D1677762A8F2F2DC9A11C7F7BE8340AB2237C7F2A0", 16), false); points[8] = curves[8].createPoint(new BigInteger("324A6EDDD512F08C49A99AE0D3F961197A76413E7BE81A400CA681E09639B5FE12E59A109F78BF4A373541B3B9A1", 16), new BigInteger("1AB597A5B4477F59E39539007C7F977D1A567B92B043A49C6B61984C3FE3481AAF454CD41BA1F051626442B3C10", 16), false); points[9] = curves[9].createPoint(new BigInteger("1A62BA79D98133A16BBAE7ED9A8E03C32E0824D57AEF72F88986874E5AAE49C27BED49A2A95058068426C2171E99FD3B43C5947C857D", 16), new BigInteger("70B5E1E14031C1F70BBEFE96BDDE66F451754B4CA5F48DA241F331AA396B8D1839A855C1769B1EA14BA53308B5E2723724E090E02DB9", 16), false); BigInteger[] n_s = new BigInteger[10]; n_s[0] = new BigInteger("400000000000000000002BEC12BE2262D39BCF14D", 16); n_s[1] = new BigInteger("3FFFFFFFFFFFFFFFFFFFFFB12EBCC7D7F29FF7701F", 16); n_s[2] = new BigInteger("800000000000000000000189B4E67606E3825BB2831", 16); n_s[3] = new BigInteger("3FFFFFFFFFFFFFFFFFFFFFFB981960435FE5AB64236EF", 16); n_s[4] = new BigInteger("40000000000000000000000069A779CAC1DABC6788F7474F", 16); n_s[5] = new BigInteger("1000000000000000000000000000013E974E72F8A6922031D2603CFE0D7", 16); n_s[6] = new BigInteger("800000000000000000000000000000006759213AF182E987D3E17714907D470D", 16); n_s[7] = new BigInteger("3FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFC079C2F3825DA70D390FBBA588D4604022B7B7", 16); n_s[8] = new BigInteger("40000000000000000000000000000000000000000000009C300B75A3FA824F22428FD28CE8812245EF44049B2D49", 16); n_s[9] = new BigInteger("3FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFBA3175458009A8C0A724F02F81AA8A1FCBAF80D90C7A95110504CF", 16); for (int i = 0; i < params.length; i++) { params[i] = new ECDomainParameters(curves[i], points[i], n_s[i]); } for (int i = 0; i < oids.length; i++) { oids[i] = new ASN1ObjectIdentifier(oidBase + i); } } /** * All named curves have the following oid format: 1.2.804.2.1.1.1.1.3.1.1.2.X * where X is the curve number 0-9 */ public static ASN1ObjectIdentifier[] getOIDs() { return oids; } /** * All named curves have the following oid format: 1.2.804.2.1.1.1.1.3.1.1.2.X * where X is the curve number 0-9 */ public static ECDomainParameters getByOID(ASN1ObjectIdentifier oid) { String oidStr = oid.getId(); if (oidStr.startsWith(oidBase)) { int index = Integer.parseInt(oidStr.substring(oidStr.length() - 1)); return params[index]; } return null; } } bouncycastle-1.49.orig/src/org/bouncycastle/asn1/ua/DSTU4145PointEncoder.java0000644000175000017500000001201412057517024026224 0ustar ebourgebourgpackage org.bouncycastle.asn1.ua; import java.math.BigInteger; import java.util.Random; import org.bouncycastle.asn1.x9.X9IntegerConverter; import org.bouncycastle.math.ec.ECConstants; import org.bouncycastle.math.ec.ECCurve; import org.bouncycastle.math.ec.ECFieldElement; import org.bouncycastle.math.ec.ECPoint; import org.bouncycastle.util.Arrays; /** * DSTU4145 encodes points somewhat differently than X9.62 * It compresses the point to the size of the field element */ public abstract class DSTU4145PointEncoder { private static X9IntegerConverter converter = new X9IntegerConverter(); private static BigInteger trace(ECFieldElement fe) { ECFieldElement t = fe; for (int i = 0; i < fe.getFieldSize() - 1; i++) { t = t.square().add(fe); } return t.toBigInteger(); } /** * Solves a quadratic equation z2 + z = beta(X9.62 * D.1.6) The other solution is z + 1. * * @param beta The value to solve the qradratic equation for. * @return the solution for z2 + z = beta or * null if no solution exists. */ private static ECFieldElement solveQuadradicEquation(ECFieldElement beta) { ECFieldElement.F2m b = (ECFieldElement.F2m)beta; ECFieldElement zeroElement = new ECFieldElement.F2m( b.getM(), b.getK1(), b.getK2(), b.getK3(), ECConstants.ZERO); if (beta.toBigInteger().equals(ECConstants.ZERO)) { return zeroElement; } ECFieldElement z = null; ECFieldElement gamma = zeroElement; Random rand = new Random(); int m = b.getM(); do { ECFieldElement t = new ECFieldElement.F2m(b.getM(), b.getK1(), b.getK2(), b.getK3(), new BigInteger(m, rand)); z = zeroElement; ECFieldElement w = beta; for (int i = 1; i <= m - 1; i++) { ECFieldElement w2 = w.square(); z = z.square().add(w2.multiply(t)); w = w2.add(beta); } if (!w.toBigInteger().equals(ECConstants.ZERO)) { return null; } gamma = z.square().add(z); } while (gamma.toBigInteger().equals(ECConstants.ZERO)); return z; } public static byte[] encodePoint(ECPoint Q) { /*if (!Q.isCompressed()) Q=new ECPoint.F2m(Q.getCurve(),Q.getX(),Q.getY(),true); byte[] bytes=Q.getEncoded(); if (bytes[0]==0x02) bytes[bytes.length-1]&=0xFE; else if (bytes[0]==0x02) bytes[bytes.length-1]|=0x01; return Arrays.copyOfRange(bytes, 1, bytes.length);*/ int byteCount = converter.getByteLength(Q.getX()); byte[] bytes = converter.integerToBytes(Q.getX().toBigInteger(), byteCount); if (!(Q.getX().toBigInteger().equals(ECConstants.ZERO))) { ECFieldElement y = Q.getY().multiply(Q.getX().invert()); if (trace(y).equals(ECConstants.ONE)) { bytes[bytes.length - 1] |= 0x01; } else { bytes[bytes.length - 1] &= 0xFE; } } return bytes; } public static ECPoint decodePoint(ECCurve curve, byte[] bytes) { /*byte[] bp_enc=new byte[bytes.length+1]; if (0==(bytes[bytes.length-1]&0x1)) bp_enc[0]=0x02; else bp_enc[0]=0x03; System.arraycopy(bytes, 0, bp_enc, 1, bytes.length); if (!trace(curve.fromBigInteger(new BigInteger(1, bytes))).equals(curve.getA().toBigInteger())) bp_enc[bp_enc.length-1]^=0x01; return curve.decodePoint(bp_enc);*/ BigInteger k = BigInteger.valueOf(bytes[bytes.length - 1] & 0x1); if (!trace(curve.fromBigInteger(new BigInteger(1, bytes))).equals(curve.getA().toBigInteger())) { bytes = Arrays.clone(bytes); bytes[bytes.length - 1] ^= 0x01; } ECCurve.F2m c = (ECCurve.F2m)curve; ECFieldElement xp = curve.fromBigInteger(new BigInteger(1, bytes)); ECFieldElement yp = null; if (xp.toBigInteger().equals(ECConstants.ZERO)) { yp = (ECFieldElement.F2m)curve.getB(); for (int i = 0; i < c.getM() - 1; i++) { yp = yp.square(); } } else { ECFieldElement beta = xp.add(curve.getA()).add( curve.getB().multiply(xp.square().invert())); ECFieldElement z = solveQuadradicEquation(beta); if (z == null) { throw new RuntimeException("Invalid point compression"); } if (!trace(z).equals(k)) { z = z.add(curve.fromBigInteger(ECConstants.ONE)); } yp = xp.multiply(z); } return new ECPoint.F2m(curve, xp, yp); } } bouncycastle-1.49.orig/src/org/bouncycastle/asn1/ua/DSTU4145ECBinary.java0000644000175000017500000000772312151251423025273 0ustar ebourgebourgpackage org.bouncycastle.asn1.ua; import java.math.BigInteger; import org.bouncycastle.asn1.ASN1EncodableVector; import org.bouncycastle.asn1.ASN1Integer; import org.bouncycastle.asn1.ASN1Object; import org.bouncycastle.asn1.ASN1OctetString; import org.bouncycastle.asn1.ASN1Primitive; import org.bouncycastle.asn1.ASN1Sequence; import org.bouncycastle.asn1.ASN1TaggedObject; import org.bouncycastle.asn1.DEROctetString; import org.bouncycastle.asn1.DERSequence; import org.bouncycastle.asn1.DERTaggedObject; import org.bouncycastle.asn1.x9.X9IntegerConverter; import org.bouncycastle.crypto.params.ECDomainParameters; import org.bouncycastle.math.ec.ECCurve; import org.bouncycastle.util.Arrays; public class DSTU4145ECBinary extends ASN1Object { BigInteger version = BigInteger.valueOf(0); DSTU4145BinaryField f; ASN1Integer a; ASN1OctetString b; ASN1Integer n; ASN1OctetString bp; public DSTU4145ECBinary(ECDomainParameters params) { if (!(params.getCurve() instanceof ECCurve.F2m)) { throw new IllegalArgumentException("only binary domain is possible"); } // We always use big-endian in parameter encoding ECCurve.F2m curve = (ECCurve.F2m)params.getCurve(); f = new DSTU4145BinaryField(curve.getM(), curve.getK1(), curve.getK2(), curve.getK3()); a = new ASN1Integer(curve.getA().toBigInteger()); X9IntegerConverter converter = new X9IntegerConverter(); b = new DEROctetString(converter.integerToBytes(curve.getB().toBigInteger(), converter.getByteLength(curve))); n = new ASN1Integer(params.getN()); bp = new DEROctetString(DSTU4145PointEncoder.encodePoint(params.getG())); } private DSTU4145ECBinary(ASN1Sequence seq) { int index = 0; if (seq.getObjectAt(index) instanceof ASN1TaggedObject) { ASN1TaggedObject taggedVersion = (ASN1TaggedObject)seq.getObjectAt(index); if (taggedVersion.isExplicit() && 0 == taggedVersion.getTagNo()) { version = ASN1Integer.getInstance(taggedVersion.getLoadedObject()).getValue(); index++; } else { throw new IllegalArgumentException("object parse error"); } } f = DSTU4145BinaryField.getInstance(seq.getObjectAt(index)); index++; a = ASN1Integer.getInstance(seq.getObjectAt(index)); index++; b = ASN1OctetString.getInstance(seq.getObjectAt(index)); index++; n = ASN1Integer.getInstance(seq.getObjectAt(index)); index++; bp = ASN1OctetString.getInstance(seq.getObjectAt(index)); } public static DSTU4145ECBinary getInstance(Object obj) { if (obj instanceof DSTU4145ECBinary) { return (DSTU4145ECBinary)obj; } if (obj != null) { return new DSTU4145ECBinary(ASN1Sequence.getInstance(obj)); } return null; } public DSTU4145BinaryField getField() { return f; } public BigInteger getA() { return a.getValue(); } public byte[] getB() { return Arrays.clone(b.getOctets()); } public BigInteger getN() { return n.getValue(); } public byte[] getG() { return Arrays.clone(bp.getOctets()); } /** * ECBinary ::= SEQUENCE { * version [0] EXPLICIT INTEGER DEFAULT 0, * f BinaryField, * a INTEGER (0..1), * b OCTET STRING, * n INTEGER, * bp OCTET STRING} */ public ASN1Primitive toASN1Primitive() { ASN1EncodableVector v = new ASN1EncodableVector(); if (0 != version.compareTo(BigInteger.valueOf(0))) { v.add(new DERTaggedObject(true, 0, new ASN1Integer(version))); } v.add(f); v.add(a); v.add(b); v.add(n); v.add(bp); return new DERSequence(v); } } bouncycastle-1.49.orig/src/org/bouncycastle/asn1/ua/DSTU4145PublicKey.java0000644000175000017500000000202412057030020025504 0ustar ebourgebourgpackage org.bouncycastle.asn1.ua; import org.bouncycastle.asn1.ASN1Object; import org.bouncycastle.asn1.ASN1OctetString; import org.bouncycastle.asn1.ASN1Primitive; import org.bouncycastle.asn1.DEROctetString; import org.bouncycastle.math.ec.ECPoint; public class DSTU4145PublicKey extends ASN1Object { private ASN1OctetString pubKey; public DSTU4145PublicKey(ECPoint pubKey) { // We always use big-endian in parameter encoding this.pubKey = new DEROctetString(DSTU4145PointEncoder.encodePoint(pubKey)); } private DSTU4145PublicKey(ASN1OctetString ocStr) { pubKey = ocStr; } public static DSTU4145PublicKey getInstance(Object obj) { if (obj instanceof DSTU4145PublicKey) { return (DSTU4145PublicKey)obj; } if (obj != null) { return new DSTU4145PublicKey(ASN1OctetString.getInstance(obj)); } return null; } public ASN1Primitive toASN1Primitive() { return pubKey; } } bouncycastle-1.49.orig/src/org/bouncycastle/asn1/ua/UAObjectIdentifiers.java0000644000175000017500000000124612015352677026451 0ustar ebourgebourgpackage org.bouncycastle.asn1.ua; import org.bouncycastle.asn1.ASN1ObjectIdentifier; public interface UAObjectIdentifiers { // Ukrainian object identifiers // {iso(1) member-body(2) Ukraine(804 ) root(2) security(1) cryptography(1) pki(1)} static final ASN1ObjectIdentifier UaOid = new ASN1ObjectIdentifier("1.2.804.2.1.1.1"); // {pki-alg(1) pki-alg-�sym(3) Dstu4145WithGost34311(1) PB(1)} // DSTU4145 in polynomial basis has 2 oids, one for little-endian representation and one for big-endian static final ASN1ObjectIdentifier dstu4145le = UaOid.branch("1.3.1.1"); static final ASN1ObjectIdentifier dstu4145be = UaOid.branch("1.3.1.1.1.1"); } bouncycastle-1.49.orig/src/org/bouncycastle/asn1/ua/DSTU4145BinaryField.java0000644000175000017500000000536312151251423026025 0ustar ebourgebourgpackage org.bouncycastle.asn1.ua; import org.bouncycastle.asn1.ASN1EncodableVector; import org.bouncycastle.asn1.ASN1Integer; import org.bouncycastle.asn1.ASN1Object; import org.bouncycastle.asn1.ASN1Primitive; import org.bouncycastle.asn1.ASN1Sequence; import org.bouncycastle.asn1.DERSequence; public class DSTU4145BinaryField extends ASN1Object { private int m, k, j, l; private DSTU4145BinaryField(ASN1Sequence seq) { m = ASN1Integer.getInstance(seq.getObjectAt(0)).getPositiveValue().intValue(); if (seq.getObjectAt(1) instanceof ASN1Integer) { k = ((ASN1Integer)seq.getObjectAt(1)).getPositiveValue().intValue(); } else if (seq.getObjectAt(1) instanceof ASN1Sequence) { ASN1Sequence coefs = ASN1Sequence.getInstance(seq.getObjectAt(1)); k = ASN1Integer.getInstance(coefs.getObjectAt(0)).getPositiveValue().intValue(); j = ASN1Integer.getInstance(coefs.getObjectAt(1)).getPositiveValue().intValue(); l = ASN1Integer.getInstance(coefs.getObjectAt(2)).getPositiveValue().intValue(); } else { throw new IllegalArgumentException("object parse error"); } } public static DSTU4145BinaryField getInstance(Object obj) { if (obj instanceof DSTU4145BinaryField) { return (DSTU4145BinaryField)obj; } if (obj != null) { return new DSTU4145BinaryField(ASN1Sequence.getInstance(obj)); } return null; } public DSTU4145BinaryField(int m, int k1, int k2, int k3) { this.m = m; this.k = k1; this.j = k2; this.l = k3; } public int getM() { return m; } public int getK1() { return k; } public int getK2() { return j; } public int getK3() { return l; } public DSTU4145BinaryField(int m, int k) { this(m, k, 0, 0); } /** * BinaryField ::= SEQUENCE { * M INTEGER, * CHOICE {Trinomial, Pentanomial} * Trinomial::= INTEGER * Pentanomial::= SEQUENCE { * k INTEGER, * j INTEGER, * l INTEGER} */ public ASN1Primitive toASN1Primitive() { ASN1EncodableVector v = new ASN1EncodableVector(); v.add(new ASN1Integer(m)); if (j == 0) //Trinomial { v.add(new ASN1Integer(k)); } else { ASN1EncodableVector coefs = new ASN1EncodableVector(); coefs.add(new ASN1Integer(k)); coefs.add(new ASN1Integer(j)); coefs.add(new ASN1Integer(l)); v.add(new DERSequence(coefs)); } return new DERSequence(v); } } bouncycastle-1.49.orig/src/org/bouncycastle/asn1/ua/DSTU4145Params.java0000644000175000017500000000646712151253000025057 0ustar ebourgebourgpackage org.bouncycastle.asn1.ua; import org.bouncycastle.asn1.ASN1EncodableVector; import org.bouncycastle.asn1.ASN1Object; import org.bouncycastle.asn1.ASN1ObjectIdentifier; import org.bouncycastle.asn1.ASN1OctetString; import org.bouncycastle.asn1.ASN1Primitive; import org.bouncycastle.asn1.ASN1Sequence; import org.bouncycastle.asn1.DEROctetString; import org.bouncycastle.asn1.DERSequence; public class DSTU4145Params extends ASN1Object { private static final byte DEFAULT_DKE[] = { (byte)0xa9, (byte)0xd6, (byte)0xeb, 0x45, (byte)0xf1, 0x3c, 0x70, (byte)0x82, (byte)0x80, (byte)0xc4, (byte)0x96, 0x7b, 0x23, 0x1f, 0x5e, (byte)0xad, (byte)0xf6, 0x58, (byte)0xeb, (byte)0xa4, (byte)0xc0, 0x37, 0x29, 0x1d, 0x38, (byte)0xd9, 0x6b, (byte)0xf0, 0x25, (byte)0xca, 0x4e, 0x17, (byte)0xf8, (byte)0xe9, 0x72, 0x0d, (byte)0xc6, 0x15, (byte)0xb4, 0x3a, 0x28, (byte)0x97, 0x5f, 0x0b, (byte)0xc1, (byte)0xde, (byte)0xa3, 0x64, 0x38, (byte)0xb5, 0x64, (byte)0xea, 0x2c, 0x17, (byte)0x9f, (byte)0xd0, 0x12, 0x3e, 0x6d, (byte)0xb8, (byte)0xfa, (byte)0xc5, 0x79, 0x04}; private ASN1ObjectIdentifier namedCurve; private DSTU4145ECBinary ecbinary; private byte[] dke = DEFAULT_DKE; public DSTU4145Params(ASN1ObjectIdentifier namedCurve) { this.namedCurve = namedCurve; } public DSTU4145Params(DSTU4145ECBinary ecbinary) { this.ecbinary = ecbinary; } public boolean isNamedCurve() { return namedCurve != null; } public DSTU4145ECBinary getECBinary() { return ecbinary; } public byte[] getDKE() { return dke; } public static byte[] getDefaultDKE() { return DEFAULT_DKE; } public ASN1ObjectIdentifier getNamedCurve() { return namedCurve; } public static DSTU4145Params getInstance(Object obj) { if (obj instanceof DSTU4145Params) { return (DSTU4145Params)obj; } if (obj != null) { ASN1Sequence seq = ASN1Sequence.getInstance(obj); DSTU4145Params params; if (seq.getObjectAt(0) instanceof ASN1ObjectIdentifier) { params = new DSTU4145Params(ASN1ObjectIdentifier.getInstance(seq.getObjectAt(0))); } else { params = new DSTU4145Params(DSTU4145ECBinary.getInstance(seq.getObjectAt(0))); } if (seq.size() == 2) { params.dke = ASN1OctetString.getInstance(seq.getObjectAt(1)).getOctets(); if (params.dke.length != DSTU4145Params.DEFAULT_DKE.length) { throw new IllegalArgumentException("object parse error"); } } return params; } throw new IllegalArgumentException("object parse error"); } public ASN1Primitive toASN1Primitive() { ASN1EncodableVector v = new ASN1EncodableVector(); if (namedCurve != null) { v.add(namedCurve); } else { v.add(ecbinary); } if (!org.bouncycastle.util.Arrays.areEqual(dke, DEFAULT_DKE)) { v.add(new DEROctetString(dke)); } return new DERSequence(v); } } bouncycastle-1.49.orig/src/org/bouncycastle/asn1/sec/0000755000175000017500000000000012152033551022113 5ustar ebourgebourgbouncycastle-1.49.orig/src/org/bouncycastle/asn1/sec/ECPrivateKeyStructure.java0000644000175000017500000000625711724561172027215 0ustar ebourgebourgpackage org.bouncycastle.asn1.sec; import java.math.BigInteger; import java.util.Enumeration; import org.bouncycastle.asn1.ASN1Encodable; import org.bouncycastle.asn1.ASN1EncodableVector; import org.bouncycastle.asn1.ASN1Integer; import org.bouncycastle.asn1.ASN1Object; import org.bouncycastle.asn1.ASN1OctetString; import org.bouncycastle.asn1.ASN1Primitive; import org.bouncycastle.asn1.ASN1Sequence; import org.bouncycastle.asn1.ASN1TaggedObject; import org.bouncycastle.asn1.DERBitString; import org.bouncycastle.asn1.DEROctetString; import org.bouncycastle.asn1.DERSequence; import org.bouncycastle.asn1.DERTaggedObject; import org.bouncycastle.util.BigIntegers; /** * the elliptic curve private key object from SEC 1 * @deprecated use ECPrivateKey */ public class ECPrivateKeyStructure extends ASN1Object { private ASN1Sequence seq; public ECPrivateKeyStructure( ASN1Sequence seq) { this.seq = seq; } public ECPrivateKeyStructure( BigInteger key) { byte[] bytes = BigIntegers.asUnsignedByteArray(key); ASN1EncodableVector v = new ASN1EncodableVector(); v.add(new ASN1Integer(1)); v.add(new DEROctetString(bytes)); seq = new DERSequence(v); } public ECPrivateKeyStructure( BigInteger key, ASN1Encodable parameters) { this(key, null, parameters); } public ECPrivateKeyStructure( BigInteger key, DERBitString publicKey, ASN1Encodable parameters) { byte[] bytes = BigIntegers.asUnsignedByteArray(key); ASN1EncodableVector v = new ASN1EncodableVector(); v.add(new ASN1Integer(1)); v.add(new DEROctetString(bytes)); if (parameters != null) { v.add(new DERTaggedObject(true, 0, parameters)); } if (publicKey != null) { v.add(new DERTaggedObject(true, 1, publicKey)); } seq = new DERSequence(v); } public BigInteger getKey() { ASN1OctetString octs = (ASN1OctetString)seq.getObjectAt(1); return new BigInteger(1, octs.getOctets()); } public DERBitString getPublicKey() { return (DERBitString)getObjectInTag(1); } public ASN1Primitive getParameters() { return getObjectInTag(0); } private ASN1Primitive getObjectInTag(int tagNo) { Enumeration e = seq.getObjects(); while (e.hasMoreElements()) { ASN1Encodable obj = (ASN1Encodable)e.nextElement(); if (obj instanceof ASN1TaggedObject) { ASN1TaggedObject tag = (ASN1TaggedObject)obj; if (tag.getTagNo() == tagNo) { return (ASN1Primitive)((ASN1Encodable)tag.getObject()).toASN1Primitive(); } } } return null; } /** * ECPrivateKey ::= SEQUENCE { * version INTEGER { ecPrivkeyVer1(1) } (ecPrivkeyVer1), * privateKey OCTET STRING, * parameters [0] Parameters OPTIONAL, * publicKey [1] BIT STRING OPTIONAL } */ public ASN1Primitive toASN1Primitive() { return seq; } } bouncycastle-1.49.orig/src/org/bouncycastle/asn1/sec/SECObjectIdentifiers.java0000644000175000017500000000566311624622715026730 0ustar ebourgebourgpackage org.bouncycastle.asn1.sec; import org.bouncycastle.asn1.ASN1ObjectIdentifier; import org.bouncycastle.asn1.x9.X9ObjectIdentifiers; public interface SECObjectIdentifiers { /** * ellipticCurve OBJECT IDENTIFIER ::= { * iso(1) identified-organization(3) certicom(132) curve(0) * } */ static final ASN1ObjectIdentifier ellipticCurve = new ASN1ObjectIdentifier("1.3.132.0"); static final ASN1ObjectIdentifier sect163k1 = ellipticCurve.branch("1"); static final ASN1ObjectIdentifier sect163r1 = ellipticCurve.branch("2"); static final ASN1ObjectIdentifier sect239k1 = ellipticCurve.branch("3"); static final ASN1ObjectIdentifier sect113r1 = ellipticCurve.branch("4"); static final ASN1ObjectIdentifier sect113r2 = ellipticCurve.branch("5"); static final ASN1ObjectIdentifier secp112r1 = ellipticCurve.branch("6"); static final ASN1ObjectIdentifier secp112r2 = ellipticCurve.branch("7"); static final ASN1ObjectIdentifier secp160r1 = ellipticCurve.branch("8"); static final ASN1ObjectIdentifier secp160k1 = ellipticCurve.branch("9"); static final ASN1ObjectIdentifier secp256k1 = ellipticCurve.branch("10"); static final ASN1ObjectIdentifier sect163r2 = ellipticCurve.branch("15"); static final ASN1ObjectIdentifier sect283k1 = ellipticCurve.branch("16"); static final ASN1ObjectIdentifier sect283r1 = ellipticCurve.branch("17"); static final ASN1ObjectIdentifier sect131r1 = ellipticCurve.branch("22"); static final ASN1ObjectIdentifier sect131r2 = ellipticCurve.branch("23"); static final ASN1ObjectIdentifier sect193r1 = ellipticCurve.branch("24"); static final ASN1ObjectIdentifier sect193r2 = ellipticCurve.branch("25"); static final ASN1ObjectIdentifier sect233k1 = ellipticCurve.branch("26"); static final ASN1ObjectIdentifier sect233r1 = ellipticCurve.branch("27"); static final ASN1ObjectIdentifier secp128r1 = ellipticCurve.branch("28"); static final ASN1ObjectIdentifier secp128r2 = ellipticCurve.branch("29"); static final ASN1ObjectIdentifier secp160r2 = ellipticCurve.branch("30"); static final ASN1ObjectIdentifier secp192k1 = ellipticCurve.branch("31"); static final ASN1ObjectIdentifier secp224k1 = ellipticCurve.branch("32"); static final ASN1ObjectIdentifier secp224r1 = ellipticCurve.branch("33"); static final ASN1ObjectIdentifier secp384r1 = ellipticCurve.branch("34"); static final ASN1ObjectIdentifier secp521r1 = ellipticCurve.branch("35"); static final ASN1ObjectIdentifier sect409k1 = ellipticCurve.branch("36"); static final ASN1ObjectIdentifier sect409r1 = ellipticCurve.branch("37"); static final ASN1ObjectIdentifier sect571k1 = ellipticCurve.branch("38"); static final ASN1ObjectIdentifier sect571r1 = ellipticCurve.branch("39"); static final ASN1ObjectIdentifier secp192r1 = X9ObjectIdentifiers.prime192v1; static final ASN1ObjectIdentifier secp256r1 = X9ObjectIdentifiers.prime256v1; } bouncycastle-1.49.orig/src/org/bouncycastle/asn1/sec/SECNamedCurves.java0000644000175000017500000012401511624652555025546 0ustar ebourgebourgpackage org.bouncycastle.asn1.sec; import java.math.BigInteger; import java.util.Enumeration; import java.util.Hashtable; import org.bouncycastle.asn1.ASN1ObjectIdentifier; import org.bouncycastle.asn1.x9.X9ECParameters; import org.bouncycastle.asn1.x9.X9ECParametersHolder; import org.bouncycastle.math.ec.ECConstants; import org.bouncycastle.math.ec.ECCurve; import org.bouncycastle.math.ec.ECPoint; import org.bouncycastle.util.Strings; import org.bouncycastle.util.encoders.Hex; public class SECNamedCurves { private static BigInteger fromHex( String hex) { return new BigInteger(1, Hex.decode(hex)); } /* * secp112r1 */ static X9ECParametersHolder secp112r1 = new X9ECParametersHolder() { protected X9ECParameters createParameters() { // p = (2^128 - 3) / 76439 BigInteger p = fromHex("DB7C2ABF62E35E668076BEAD208B"); BigInteger a = fromHex("DB7C2ABF62E35E668076BEAD2088"); BigInteger b = fromHex("659EF8BA043916EEDE8911702B22"); byte[] S = Hex.decode("00F50B028E4D696E676875615175290472783FB1"); BigInteger n = fromHex("DB7C2ABF62E35E7628DFAC6561C5"); BigInteger h = BigInteger.valueOf(1); ECCurve curve = new ECCurve.Fp(p, a, b); //ECPoint G = curve.decodePoint(Hex.decode("02" //+ "09487239995A5EE76B55F9C2F098")); ECPoint G = curve.decodePoint(Hex.decode("04" + "09487239995A5EE76B55F9C2F098" + "A89CE5AF8724C0A23E0E0FF77500")); return new X9ECParameters(curve, G, n, h, S); } }; /* * secp112r2 */ static X9ECParametersHolder secp112r2 = new X9ECParametersHolder() { protected X9ECParameters createParameters() { // p = (2^128 - 3) / 76439 BigInteger p = fromHex("DB7C2ABF62E35E668076BEAD208B"); BigInteger a = fromHex("6127C24C05F38A0AAAF65C0EF02C"); BigInteger b = fromHex("51DEF1815DB5ED74FCC34C85D709"); byte[] S = Hex.decode("002757A1114D696E6768756151755316C05E0BD4"); BigInteger n = fromHex("36DF0AAFD8B8D7597CA10520D04B"); BigInteger h = BigInteger.valueOf(4); ECCurve curve = new ECCurve.Fp(p, a, b); //ECPoint G = curve.decodePoint(Hex.decode("03" //+ "4BA30AB5E892B4E1649DD0928643")); ECPoint G = curve.decodePoint(Hex.decode("04" + "4BA30AB5E892B4E1649DD0928643" + "ADCD46F5882E3747DEF36E956E97")); return new X9ECParameters(curve, G, n, h, S); } }; /* * secp128r1 */ static X9ECParametersHolder secp128r1 = new X9ECParametersHolder() { protected X9ECParameters createParameters() { // p = 2^128 - 2^97 - 1 BigInteger p = fromHex("FFFFFFFDFFFFFFFFFFFFFFFFFFFFFFFF"); BigInteger a = fromHex("FFFFFFFDFFFFFFFFFFFFFFFFFFFFFFFC"); BigInteger b = fromHex("E87579C11079F43DD824993C2CEE5ED3"); byte[] S = Hex.decode("000E0D4D696E6768756151750CC03A4473D03679"); BigInteger n = fromHex("FFFFFFFE0000000075A30D1B9038A115"); BigInteger h = BigInteger.valueOf(1); ECCurve curve = new ECCurve.Fp(p, a, b); //ECPoint G = curve.decodePoint(Hex.decode("03" //+ "161FF7528B899B2D0C28607CA52C5B86")); ECPoint G = curve.decodePoint(Hex.decode("04" + "161FF7528B899B2D0C28607CA52C5B86" + "CF5AC8395BAFEB13C02DA292DDED7A83")); return new X9ECParameters(curve, G, n, h, S); } }; /* * secp128r2 */ static X9ECParametersHolder secp128r2 = new X9ECParametersHolder() { protected X9ECParameters createParameters() { // p = 2^128 - 2^97 - 1 BigInteger p = fromHex("FFFFFFFDFFFFFFFFFFFFFFFFFFFFFFFF"); BigInteger a = fromHex("D6031998D1B3BBFEBF59CC9BBFF9AEE1"); BigInteger b = fromHex("5EEEFCA380D02919DC2C6558BB6D8A5D"); byte[] S = Hex.decode("004D696E67687561517512D8F03431FCE63B88F4"); BigInteger n = fromHex("3FFFFFFF7FFFFFFFBE0024720613B5A3"); BigInteger h = BigInteger.valueOf(4); ECCurve curve = new ECCurve.Fp(p, a, b); //ECPoint G = curve.decodePoint(Hex.decode("02" //+ "7B6AA5D85E572983E6FB32A7CDEBC140")); ECPoint G = curve.decodePoint(Hex.decode("04" + "7B6AA5D85E572983E6FB32A7CDEBC140" + "27B6916A894D3AEE7106FE805FC34B44")); return new X9ECParameters(curve, G, n, h, S); } }; /* * secp160k1 */ static X9ECParametersHolder secp160k1 = new X9ECParametersHolder() { protected X9ECParameters createParameters() { // p = 2^160 - 2^32 - 2^14 - 2^12 - 2^9 - 2^8 - 2^7 - 2^3 - 2^2 - 1 BigInteger p = fromHex("FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEFFFFAC73"); BigInteger a = ECConstants.ZERO; BigInteger b = BigInteger.valueOf(7); byte[] S = null; BigInteger n = fromHex("0100000000000000000001B8FA16DFAB9ACA16B6B3"); BigInteger h = BigInteger.valueOf(1); ECCurve curve = new ECCurve.Fp(p, a, b); // ECPoint G = curve.decodePoint(Hex.decode("02" // + "3B4C382CE37AA192A4019E763036F4F5DD4D7EBB")); ECPoint G = curve.decodePoint(Hex.decode("04" + "3B4C382CE37AA192A4019E763036F4F5DD4D7EBB" + "938CF935318FDCED6BC28286531733C3F03C4FEE")); return new X9ECParameters(curve, G, n, h, S); } }; /* * secp160r1 */ static X9ECParametersHolder secp160r1 = new X9ECParametersHolder() { protected X9ECParameters createParameters() { // p = 2^160 - 2^31 - 1 BigInteger p = fromHex("FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF7FFFFFFF"); BigInteger a = fromHex("FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF7FFFFFFC"); BigInteger b = fromHex("1C97BEFC54BD7A8B65ACF89F81D4D4ADC565FA45"); byte[] S = Hex.decode("1053CDE42C14D696E67687561517533BF3F83345"); BigInteger n = fromHex("0100000000000000000001F4C8F927AED3CA752257"); BigInteger h = BigInteger.valueOf(1); ECCurve curve = new ECCurve.Fp(p, a, b); //ECPoint G = curve.decodePoint(Hex.decode("02" //+ "4A96B5688EF573284664698968C38BB913CBFC82")); ECPoint G = curve.decodePoint(Hex.decode("04" + "4A96B5688EF573284664698968C38BB913CBFC82" + "23A628553168947D59DCC912042351377AC5FB32")); return new X9ECParameters(curve, G, n, h, S); } }; /* * secp160r2 */ static X9ECParametersHolder secp160r2 = new X9ECParametersHolder() { protected X9ECParameters createParameters() { // p = 2^160 - 2^32 - 2^14 - 2^12 - 2^9 - 2^8 - 2^7 - 2^3 - 2^2 - 1 BigInteger p = fromHex("FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEFFFFAC73"); BigInteger a = fromHex("FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEFFFFAC70"); BigInteger b = fromHex("B4E134D3FB59EB8BAB57274904664D5AF50388BA"); byte[] S = Hex.decode("B99B99B099B323E02709A4D696E6768756151751"); BigInteger n = fromHex("0100000000000000000000351EE786A818F3A1A16B"); BigInteger h = BigInteger.valueOf(1); ECCurve curve = new ECCurve.Fp(p, a, b); //ECPoint G = curve.decodePoint(Hex.decode("02" //+ "52DCB034293A117E1F4FF11B30F7199D3144CE6D")); ECPoint G = curve.decodePoint(Hex.decode("04" + "52DCB034293A117E1F4FF11B30F7199D3144CE6D" + "FEAFFEF2E331F296E071FA0DF9982CFEA7D43F2E")); return new X9ECParameters(curve, G, n, h, S); } }; /* * secp192k1 */ static X9ECParametersHolder secp192k1 = new X9ECParametersHolder() { protected X9ECParameters createParameters() { // p = 2^192 - 2^32 - 2^12 - 2^8 - 2^7 - 2^6 - 2^3 - 1 BigInteger p = fromHex("FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEFFFFEE37"); BigInteger a = ECConstants.ZERO; BigInteger b = BigInteger.valueOf(3); byte[] S = null; BigInteger n = fromHex("FFFFFFFFFFFFFFFFFFFFFFFE26F2FC170F69466A74DEFD8D"); BigInteger h = BigInteger.valueOf(1); ECCurve curve = new ECCurve.Fp(p, a, b); //ECPoint G = curve.decodePoint(Hex.decode("03" //+ "DB4FF10EC057E9AE26B07D0280B7F4341DA5D1B1EAE06C7D")); ECPoint G = curve.decodePoint(Hex.decode("04" + "DB4FF10EC057E9AE26B07D0280B7F4341DA5D1B1EAE06C7D" + "9B2F2F6D9C5628A7844163D015BE86344082AA88D95E2F9D")); return new X9ECParameters(curve, G, n, h, S); } }; /* * secp192r1 */ static X9ECParametersHolder secp192r1 = new X9ECParametersHolder() { protected X9ECParameters createParameters() { // p = 2^192 - 2^64 - 1 BigInteger p = fromHex("FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEFFFFFFFFFFFFFFFF"); BigInteger a = fromHex("FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEFFFFFFFFFFFFFFFC"); BigInteger b = fromHex("64210519E59C80E70FA7E9AB72243049FEB8DEECC146B9B1"); byte[] S = Hex.decode("3045AE6FC8422F64ED579528D38120EAE12196D5"); BigInteger n = fromHex("FFFFFFFFFFFFFFFFFFFFFFFF99DEF836146BC9B1B4D22831"); BigInteger h = BigInteger.valueOf(1); ECCurve curve = new ECCurve.Fp(p, a, b); //ECPoint G = curve.decodePoint(Hex.decode("03" //+ "188DA80EB03090F67CBF20EB43A18800F4FF0AFD82FF1012")); ECPoint G = curve.decodePoint(Hex.decode("04" + "188DA80EB03090F67CBF20EB43A18800F4FF0AFD82FF1012" + "07192B95FFC8DA78631011ED6B24CDD573F977A11E794811")); return new X9ECParameters(curve, G, n, h, S); } }; /* * secp224k1 */ static X9ECParametersHolder secp224k1 = new X9ECParametersHolder() { protected X9ECParameters createParameters() { // p = 2^224 - 2^32 - 2^12 - 2^11 - 2^9 - 2^7 - 2^4 - 2 - 1 BigInteger p = fromHex("FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEFFFFE56D"); BigInteger a = ECConstants.ZERO; BigInteger b = BigInteger.valueOf(5); byte[] S = null; BigInteger n = fromHex("010000000000000000000000000001DCE8D2EC6184CAF0A971769FB1F7"); BigInteger h = BigInteger.valueOf(1); ECCurve curve = new ECCurve.Fp(p, a, b); //ECPoint G = curve.decodePoint(Hex.decode("03" //+ "A1455B334DF099DF30FC28A169A467E9E47075A90F7E650EB6B7A45C")); ECPoint G = curve.decodePoint(Hex.decode("04" + "A1455B334DF099DF30FC28A169A467E9E47075A90F7E650EB6B7A45C" + "7E089FED7FBA344282CAFBD6F7E319F7C0B0BD59E2CA4BDB556D61A5")); return new X9ECParameters(curve, G, n, h, S); } }; /* * secp224r1 */ static X9ECParametersHolder secp224r1 = new X9ECParametersHolder() { protected X9ECParameters createParameters() { // p = 2^224 - 2^96 + 1 BigInteger p = fromHex("FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF000000000000000000000001"); BigInteger a = fromHex("FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEFFFFFFFFFFFFFFFFFFFFFFFE"); BigInteger b = fromHex("B4050A850C04B3ABF54132565044B0B7D7BFD8BA270B39432355FFB4"); byte[] S = Hex.decode("BD71344799D5C7FCDC45B59FA3B9AB8F6A948BC5"); BigInteger n = fromHex("FFFFFFFFFFFFFFFFFFFFFFFFFFFF16A2E0B8F03E13DD29455C5C2A3D"); BigInteger h = BigInteger.valueOf(1); ECCurve curve = new ECCurve.Fp(p, a, b); //ECPoint G = curve.decodePoint(Hex.decode("02" //+ "B70E0CBD6BB4BF7F321390B94A03C1D356C21122343280D6115C1D21")); ECPoint G = curve.decodePoint(Hex.decode("04" + "B70E0CBD6BB4BF7F321390B94A03C1D356C21122343280D6115C1D21" + "BD376388B5F723FB4C22DFE6CD4375A05A07476444D5819985007E34")); return new X9ECParameters(curve, G, n, h, S); } }; /* * secp256k1 */ static X9ECParametersHolder secp256k1 = new X9ECParametersHolder() { protected X9ECParameters createParameters() { // p = 2^256 - 2^32 - 2^9 - 2^8 - 2^7 - 2^6 - 2^4 - 1 BigInteger p = fromHex("FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEFFFFFC2F"); BigInteger a = ECConstants.ZERO; BigInteger b = BigInteger.valueOf(7); byte[] S = null; BigInteger n = fromHex("FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEBAAEDCE6AF48A03BBFD25E8CD0364141"); BigInteger h = BigInteger.valueOf(1); ECCurve curve = new ECCurve.Fp(p, a, b); //ECPoint G = curve.decodePoint(Hex.decode("02" //+ "79BE667EF9DCBBAC55A06295CE870B07029BFCDB2DCE28D959F2815B16F81798")); ECPoint G = curve.decodePoint(Hex.decode("04" + "79BE667EF9DCBBAC55A06295CE870B07029BFCDB2DCE28D959F2815B16F81798" + "483ADA7726A3C4655DA4FBFC0E1108A8FD17B448A68554199C47D08FFB10D4B8")); return new X9ECParameters(curve, G, n, h, S); } }; /* * secp256r1 */ static X9ECParametersHolder secp256r1 = new X9ECParametersHolder() { protected X9ECParameters createParameters() { // p = 2^224 (2^32 - 1) + 2^192 + 2^96 - 1 BigInteger p = fromHex("FFFFFFFF00000001000000000000000000000000FFFFFFFFFFFFFFFFFFFFFFFF"); BigInteger a = fromHex("FFFFFFFF00000001000000000000000000000000FFFFFFFFFFFFFFFFFFFFFFFC"); BigInteger b = fromHex("5AC635D8AA3A93E7B3EBBD55769886BC651D06B0CC53B0F63BCE3C3E27D2604B"); byte[] S = Hex.decode("C49D360886E704936A6678E1139D26B7819F7E90"); BigInteger n = fromHex("FFFFFFFF00000000FFFFFFFFFFFFFFFFBCE6FAADA7179E84F3B9CAC2FC632551"); BigInteger h = BigInteger.valueOf(1); ECCurve curve = new ECCurve.Fp(p, a, b); //ECPoint G = curve.decodePoint(Hex.decode("03" //+ "6B17D1F2E12C4247F8BCE6E563A440F277037D812DEB33A0F4A13945D898C296")); ECPoint G = curve.decodePoint(Hex.decode("04" + "6B17D1F2E12C4247F8BCE6E563A440F277037D812DEB33A0F4A13945D898C296" + "4FE342E2FE1A7F9B8EE7EB4A7C0F9E162BCE33576B315ECECBB6406837BF51F5")); return new X9ECParameters(curve, G, n, h, S); } }; /* * secp384r1 */ static X9ECParametersHolder secp384r1 = new X9ECParametersHolder() { protected X9ECParameters createParameters() { // p = 2^384 - 2^128 - 2^96 + 2^32 - 1 BigInteger p = fromHex("FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEFFFFFFFF0000000000000000FFFFFFFF"); BigInteger a = fromHex("FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEFFFFFFFF0000000000000000FFFFFFFC"); BigInteger b = fromHex("B3312FA7E23EE7E4988E056BE3F82D19181D9C6EFE8141120314088F5013875AC656398D8A2ED19D2A85C8EDD3EC2AEF"); byte[] S = Hex.decode("A335926AA319A27A1D00896A6773A4827ACDAC73"); BigInteger n = fromHex("FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFC7634D81F4372DDF581A0DB248B0A77AECEC196ACCC52973"); BigInteger h = BigInteger.valueOf(1); ECCurve curve = new ECCurve.Fp(p, a, b); //ECPoint G = curve.decodePoint(Hex.decode("03" //+ "AA87CA22BE8B05378EB1C71EF320AD746E1D3B628BA79B9859F741E082542A385502F25DBF55296C3A545E3872760AB7")); ECPoint G = curve.decodePoint(Hex.decode("04" + "AA87CA22BE8B05378EB1C71EF320AD746E1D3B628BA79B9859F741E082542A385502F25DBF55296C3A545E3872760AB7" + "3617DE4A96262C6F5D9E98BF9292DC29F8F41DBD289A147CE9DA3113B5F0B8C00A60B1CE1D7E819D7A431D7C90EA0E5F")); return new X9ECParameters(curve, G, n, h, S); } }; /* * secp521r1 */ static X9ECParametersHolder secp521r1 = new X9ECParametersHolder() { protected X9ECParameters createParameters() { // p = 2^521 - 1 BigInteger p = fromHex("01FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF"); BigInteger a = fromHex("01FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFC"); BigInteger b = fromHex("0051953EB9618E1C9A1F929A21A0B68540EEA2DA725B99B315F3B8B489918EF109E156193951EC7E937B1652C0BD3BB1BF073573DF883D2C34F1EF451FD46B503F00"); byte[] S = Hex.decode("D09E8800291CB85396CC6717393284AAA0DA64BA"); BigInteger n = fromHex("01FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFA51868783BF2F966B7FCC0148F709A5D03BB5C9B8899C47AEBB6FB71E91386409"); BigInteger h = BigInteger.valueOf(1); ECCurve curve = new ECCurve.Fp(p, a, b); //ECPoint G = curve.decodePoint(Hex.decode("02" //+ "00C6858E06B70404E9CD9E3ECB662395B4429C648139053FB521F828AF606B4D3DBAA14B5E77EFE75928FE1DC127A2FFA8DE3348B3C1856A429BF97E7E31C2E5BD66")); ECPoint G = curve.decodePoint(Hex.decode("04" + "00C6858E06B70404E9CD9E3ECB662395B4429C648139053FB521F828AF606B4D3DBAA14B5E77EFE75928FE1DC127A2FFA8DE3348B3C1856A429BF97E7E31C2E5BD66" + "011839296A789A3BC0045C8A5FB42C7D1BD998F54449579B446817AFBD17273E662C97EE72995EF42640C550B9013FAD0761353C7086A272C24088BE94769FD16650")); return new X9ECParameters(curve, G, n, h, S); } }; /* * sect113r1 */ static X9ECParametersHolder sect113r1 = new X9ECParametersHolder() { protected X9ECParameters createParameters() { int m = 113; int k = 9; BigInteger a = fromHex("003088250CA6E7C7FE649CE85820F7"); BigInteger b = fromHex("00E8BEE4D3E2260744188BE0E9C723"); byte[] S = Hex.decode("10E723AB14D696E6768756151756FEBF8FCB49A9"); BigInteger n = fromHex("0100000000000000D9CCEC8A39E56F"); BigInteger h = BigInteger.valueOf(2); ECCurve curve = new ECCurve.F2m(m, k, a, b, n, h); //ECPoint G = curve.decodePoint(Hex.decode("03" //+ "009D73616F35F4AB1407D73562C10F")); ECPoint G = curve.decodePoint(Hex.decode("04" + "009D73616F35F4AB1407D73562C10F" + "00A52830277958EE84D1315ED31886")); return new X9ECParameters(curve, G, n, h, S); } }; /* * sect113r2 */ static X9ECParametersHolder sect113r2 = new X9ECParametersHolder() { protected X9ECParameters createParameters() { int m = 113; int k = 9; BigInteger a = fromHex("00689918DBEC7E5A0DD6DFC0AA55C7"); BigInteger b = fromHex("0095E9A9EC9B297BD4BF36E059184F"); byte[] S = Hex.decode("10C0FB15760860DEF1EEF4D696E676875615175D"); BigInteger n = fromHex("010000000000000108789B2496AF93"); BigInteger h = BigInteger.valueOf(2); ECCurve curve = new ECCurve.F2m(m, k, a, b, n, h); //ECPoint G = curve.decodePoint(Hex.decode("03" //+ "01A57A6A7B26CA5EF52FCDB8164797")); ECPoint G = curve.decodePoint(Hex.decode("04" + "01A57A6A7B26CA5EF52FCDB8164797" + "00B3ADC94ED1FE674C06E695BABA1D")); return new X9ECParameters(curve, G, n, h, S); } }; /* * sect131r1 */ static X9ECParametersHolder sect131r1 = new X9ECParametersHolder() { protected X9ECParameters createParameters() { int m = 131; int k1 = 2; int k2 = 3; int k3 = 8; BigInteger a = fromHex("07A11B09A76B562144418FF3FF8C2570B8"); BigInteger b = fromHex("0217C05610884B63B9C6C7291678F9D341"); byte[] S = Hex.decode("4D696E676875615175985BD3ADBADA21B43A97E2"); BigInteger n = fromHex("0400000000000000023123953A9464B54D"); BigInteger h = BigInteger.valueOf(2); ECCurve curve = new ECCurve.F2m(m, k1, k2, k3, a, b, n, h); //ECPoint G = curve.decodePoint(Hex.decode("03" //+ "0081BAF91FDF9833C40F9C181343638399")); ECPoint G = curve.decodePoint(Hex.decode("04" + "0081BAF91FDF9833C40F9C181343638399" + "078C6E7EA38C001F73C8134B1B4EF9E150")); return new X9ECParameters(curve, G, n, h, S); } }; /* * sect131r2 */ static X9ECParametersHolder sect131r2 = new X9ECParametersHolder() { protected X9ECParameters createParameters() { int m = 131; int k1 = 2; int k2 = 3; int k3 = 8; BigInteger a = fromHex("03E5A88919D7CAFCBF415F07C2176573B2"); BigInteger b = fromHex("04B8266A46C55657AC734CE38F018F2192"); byte[] S = Hex.decode("985BD3ADBAD4D696E676875615175A21B43A97E3"); BigInteger n = fromHex("0400000000000000016954A233049BA98F"); BigInteger h = BigInteger.valueOf(2); ECCurve curve = new ECCurve.F2m(m, k1, k2, k3, a, b, n, h); //ECPoint G = curve.decodePoint(Hex.decode("03" //+ "0356DCD8F2F95031AD652D23951BB366A8")); ECPoint G = curve.decodePoint(Hex.decode("04" + "0356DCD8F2F95031AD652D23951BB366A8" + "0648F06D867940A5366D9E265DE9EB240F")); return new X9ECParameters(curve, G, n, h, S); } }; /* * sect163k1 */ static X9ECParametersHolder sect163k1 = new X9ECParametersHolder() { protected X9ECParameters createParameters() { int m = 163; int k1 = 3; int k2 = 6; int k3 = 7; BigInteger a = BigInteger.valueOf(1); BigInteger b = BigInteger.valueOf(1); byte[] S = null; BigInteger n = fromHex("04000000000000000000020108A2E0CC0D99F8A5EF"); BigInteger h = BigInteger.valueOf(2); ECCurve curve = new ECCurve.F2m(m, k1, k2, k3, a, b, n, h); //ECPoint G = curve.decodePoint(Hex.decode("03" //+ "02FE13C0537BBC11ACAA07D793DE4E6D5E5C94EEE8")); ECPoint G = curve.decodePoint(Hex.decode("04" + "02FE13C0537BBC11ACAA07D793DE4E6D5E5C94EEE8" + "0289070FB05D38FF58321F2E800536D538CCDAA3D9")); return new X9ECParameters(curve, G, n, h, S); } }; /* * sect163r1 */ static X9ECParametersHolder sect163r1 = new X9ECParametersHolder() { protected X9ECParameters createParameters() { int m = 163; int k1 = 3; int k2 = 6; int k3 = 7; BigInteger a = fromHex("07B6882CAAEFA84F9554FF8428BD88E246D2782AE2"); BigInteger b = fromHex("0713612DCDDCB40AAB946BDA29CA91F73AF958AFD9"); byte[] S = Hex.decode("24B7B137C8A14D696E6768756151756FD0DA2E5C"); BigInteger n = fromHex("03FFFFFFFFFFFFFFFFFFFF48AAB689C29CA710279B"); BigInteger h = BigInteger.valueOf(2); ECCurve curve = new ECCurve.F2m(m, k1, k2, k3, a, b, n, h); //ECPoint G = curve.decodePoint(Hex.decode("03" //+ "0369979697AB43897789566789567F787A7876A654")); ECPoint G = curve.decodePoint(Hex.decode("04" + "0369979697AB43897789566789567F787A7876A654" + "00435EDB42EFAFB2989D51FEFCE3C80988F41FF883")); return new X9ECParameters(curve, G, n, h, S); } }; /* * sect163r2 */ static X9ECParametersHolder sect163r2 = new X9ECParametersHolder() { protected X9ECParameters createParameters() { int m = 163; int k1 = 3; int k2 = 6; int k3 = 7; BigInteger a = BigInteger.valueOf(1); BigInteger b = fromHex("020A601907B8C953CA1481EB10512F78744A3205FD"); byte[] S = Hex.decode("85E25BFE5C86226CDB12016F7553F9D0E693A268"); BigInteger n = fromHex("040000000000000000000292FE77E70C12A4234C33"); BigInteger h = BigInteger.valueOf(2); ECCurve curve = new ECCurve.F2m(m, k1, k2, k3, a, b, n, h); //ECPoint G = curve.decodePoint(Hex.decode("03" //+ "03F0EBA16286A2D57EA0991168D4994637E8343E36")); ECPoint G = curve.decodePoint(Hex.decode("04" + "03F0EBA16286A2D57EA0991168D4994637E8343E36" + "00D51FBC6C71A0094FA2CDD545B11C5C0C797324F1")); return new X9ECParameters(curve, G, n, h, S); } }; /* * sect193r1 */ static X9ECParametersHolder sect193r1 = new X9ECParametersHolder() { protected X9ECParameters createParameters() { int m = 193; int k = 15; BigInteger a = fromHex("0017858FEB7A98975169E171F77B4087DE098AC8A911DF7B01"); BigInteger b = fromHex("00FDFB49BFE6C3A89FACADAA7A1E5BBC7CC1C2E5D831478814"); byte[] S = Hex.decode("103FAEC74D696E676875615175777FC5B191EF30"); BigInteger n = fromHex("01000000000000000000000000C7F34A778F443ACC920EBA49"); BigInteger h = BigInteger.valueOf(2); ECCurve curve = new ECCurve.F2m(m, k, a, b, n, h); //ECPoint G = curve.decodePoint(Hex.decode("03" //+ "01F481BC5F0FF84A74AD6CDF6FDEF4BF6179625372D8C0C5E1")); ECPoint G = curve.decodePoint(Hex.decode("04" + "01F481BC5F0FF84A74AD6CDF6FDEF4BF6179625372D8C0C5E1" + "0025E399F2903712CCF3EA9E3A1AD17FB0B3201B6AF7CE1B05")); return new X9ECParameters(curve, G, n, h, S); } }; /* * sect193r2 */ static X9ECParametersHolder sect193r2 = new X9ECParametersHolder() { protected X9ECParameters createParameters() { int m = 193; int k = 15; BigInteger a = fromHex("0163F35A5137C2CE3EA6ED8667190B0BC43ECD69977702709B"); BigInteger b = fromHex("00C9BB9E8927D4D64C377E2AB2856A5B16E3EFB7F61D4316AE"); byte[] S = Hex.decode("10B7B4D696E676875615175137C8A16FD0DA2211"); BigInteger n = fromHex("010000000000000000000000015AAB561B005413CCD4EE99D5"); BigInteger h = BigInteger.valueOf(2); ECCurve curve = new ECCurve.F2m(m, k, a, b, n, h); //ECPoint G = curve.decodePoint(Hex.decode("03" //+ "00D9B67D192E0367C803F39E1A7E82CA14A651350AAE617E8F")); ECPoint G = curve.decodePoint(Hex.decode("04" + "00D9B67D192E0367C803F39E1A7E82CA14A651350AAE617E8F" + "01CE94335607C304AC29E7DEFBD9CA01F596F927224CDECF6C")); return new X9ECParameters(curve, G, n, h, S); } }; /* * sect233k1 */ static X9ECParametersHolder sect233k1 = new X9ECParametersHolder() { protected X9ECParameters createParameters() { int m = 233; int k = 74; BigInteger a = ECConstants.ZERO; BigInteger b = BigInteger.valueOf(1); byte[] S = null; BigInteger n = fromHex("8000000000000000000000000000069D5BB915BCD46EFB1AD5F173ABDF"); BigInteger h = BigInteger.valueOf(4); ECCurve curve = new ECCurve.F2m(m, k, a, b, n, h); //ECPoint G = curve.decodePoint(Hex.decode("02" //+ "017232BA853A7E731AF129F22FF4149563A419C26BF50A4C9D6EEFAD6126")); ECPoint G = curve.decodePoint(Hex.decode("04" + "017232BA853A7E731AF129F22FF4149563A419C26BF50A4C9D6EEFAD6126" + "01DB537DECE819B7F70F555A67C427A8CD9BF18AEB9B56E0C11056FAE6A3")); return new X9ECParameters(curve, G, n, h, S); } }; /* * sect233r1 */ static X9ECParametersHolder sect233r1 = new X9ECParametersHolder() { protected X9ECParameters createParameters() { int m = 233; int k = 74; BigInteger a = BigInteger.valueOf(1); BigInteger b = fromHex("0066647EDE6C332C7F8C0923BB58213B333B20E9CE4281FE115F7D8F90AD"); byte[] S = Hex.decode("74D59FF07F6B413D0EA14B344B20A2DB049B50C3"); BigInteger n = fromHex("01000000000000000000000000000013E974E72F8A6922031D2603CFE0D7"); BigInteger h = BigInteger.valueOf(2); ECCurve curve = new ECCurve.F2m(m, k, a, b, n, h); //ECPoint G = curve.decodePoint(Hex.decode("03" //+ "00FAC9DFCBAC8313BB2139F1BB755FEF65BC391F8B36F8F8EB7371FD558B")); ECPoint G = curve.decodePoint(Hex.decode("04" + "00FAC9DFCBAC8313BB2139F1BB755FEF65BC391F8B36F8F8EB7371FD558B" + "01006A08A41903350678E58528BEBF8A0BEFF867A7CA36716F7E01F81052")); return new X9ECParameters(curve, G, n, h, S); } }; /* * sect239k1 */ static X9ECParametersHolder sect239k1 = new X9ECParametersHolder() { protected X9ECParameters createParameters() { int m = 239; int k = 158; BigInteger a = ECConstants.ZERO; BigInteger b = BigInteger.valueOf(1); byte[] S = null; BigInteger n = fromHex("2000000000000000000000000000005A79FEC67CB6E91F1C1DA800E478A5"); BigInteger h = BigInteger.valueOf(4); ECCurve curve = new ECCurve.F2m(m, k, a, b, n, h); //ECPoint G = curve.decodePoint(Hex.decode("03" //+ "29A0B6A887A983E9730988A68727A8B2D126C44CC2CC7B2A6555193035DC")); ECPoint G = curve.decodePoint(Hex.decode("04" + "29A0B6A887A983E9730988A68727A8B2D126C44CC2CC7B2A6555193035DC" + "76310804F12E549BDB011C103089E73510ACB275FC312A5DC6B76553F0CA")); return new X9ECParameters(curve, G, n, h, S); } }; /* * sect283k1 */ static X9ECParametersHolder sect283k1 = new X9ECParametersHolder() { protected X9ECParameters createParameters() { int m = 283; int k1 = 5; int k2 = 7; int k3 = 12; BigInteger a = ECConstants.ZERO; BigInteger b = BigInteger.valueOf(1); byte[] S = null; BigInteger n = fromHex("01FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFE9AE2ED07577265DFF7F94451E061E163C61"); BigInteger h = BigInteger.valueOf(4); ECCurve curve = new ECCurve.F2m(m, k1, k2, k3, a, b, n, h); //ECPoint G = curve.decodePoint(Hex.decode("02" //+ "0503213F78CA44883F1A3B8162F188E553CD265F23C1567A16876913B0C2AC2458492836")); ECPoint G = curve.decodePoint(Hex.decode("04" + "0503213F78CA44883F1A3B8162F188E553CD265F23C1567A16876913B0C2AC2458492836" + "01CCDA380F1C9E318D90F95D07E5426FE87E45C0E8184698E45962364E34116177DD2259")); return new X9ECParameters(curve, G, n, h, S); } }; /* * sect283r1 */ static X9ECParametersHolder sect283r1 = new X9ECParametersHolder() { protected X9ECParameters createParameters() { int m = 283; int k1 = 5; int k2 = 7; int k3 = 12; BigInteger a = BigInteger.valueOf(1); BigInteger b = fromHex("027B680AC8B8596DA5A4AF8A19A0303FCA97FD7645309FA2A581485AF6263E313B79A2F5"); byte[] S = Hex.decode("77E2B07370EB0F832A6DD5B62DFC88CD06BB84BE"); BigInteger n = fromHex("03FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEF90399660FC938A90165B042A7CEFADB307"); BigInteger h = BigInteger.valueOf(2); ECCurve curve = new ECCurve.F2m(m, k1, k2, k3, a, b, n, h); //ECPoint G = curve.decodePoint(Hex.decode("03" //+ "05F939258DB7DD90E1934F8C70B0DFEC2EED25B8557EAC9C80E2E198F8CDBECD86B12053")); ECPoint G = curve.decodePoint(Hex.decode("04" + "05F939258DB7DD90E1934F8C70B0DFEC2EED25B8557EAC9C80E2E198F8CDBECD86B12053" + "03676854FE24141CB98FE6D4B20D02B4516FF702350EDDB0826779C813F0DF45BE8112F4")); return new X9ECParameters(curve, G, n, h, S); } }; /* * sect409k1 */ static X9ECParametersHolder sect409k1 = new X9ECParametersHolder() { protected X9ECParameters createParameters() { int m = 409; int k = 87; BigInteger a = ECConstants.ZERO; BigInteger b = BigInteger.valueOf(1); byte[] S = null; BigInteger n = fromHex("7FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFE5F83B2D4EA20400EC4557D5ED3E3E7CA5B4B5C83B8E01E5FCF"); BigInteger h = BigInteger.valueOf(4); ECCurve curve = new ECCurve.F2m(m, k, a, b, n, h); //ECPoint G = curve.decodePoint(Hex.decode("03" //+ "0060F05F658F49C1AD3AB1890F7184210EFD0987E307C84C27ACCFB8F9F67CC2C460189EB5AAAA62EE222EB1B35540CFE9023746")); ECPoint G = curve.decodePoint(Hex.decode("04" + "0060F05F658F49C1AD3AB1890F7184210EFD0987E307C84C27ACCFB8F9F67CC2C460189EB5AAAA62EE222EB1B35540CFE9023746" + "01E369050B7C4E42ACBA1DACBF04299C3460782F918EA427E6325165E9EA10E3DA5F6C42E9C55215AA9CA27A5863EC48D8E0286B")); return new X9ECParameters(curve, G, n, h, S); } }; /* * sect409r1 */ static X9ECParametersHolder sect409r1 = new X9ECParametersHolder() { protected X9ECParameters createParameters() { int m = 409; int k = 87; BigInteger a = BigInteger.valueOf(1); BigInteger b = fromHex("0021A5C2C8EE9FEB5C4B9A753B7B476B7FD6422EF1F3DD674761FA99D6AC27C8A9A197B272822F6CD57A55AA4F50AE317B13545F"); byte[] S = Hex.decode("4099B5A457F9D69F79213D094C4BCD4D4262210B"); BigInteger n = fromHex("010000000000000000000000000000000000000000000000000001E2AAD6A612F33307BE5FA47C3C9E052F838164CD37D9A21173"); BigInteger h = BigInteger.valueOf(2); ECCurve curve = new ECCurve.F2m(m, k, a, b, n, h); //ECPoint G = curve.decodePoint(Hex.decode("03" //+ "015D4860D088DDB3496B0C6064756260441CDE4AF1771D4DB01FFE5B34E59703DC255A868A1180515603AEAB60794E54BB7996A7")); ECPoint G = curve.decodePoint(Hex.decode("04" + "015D4860D088DDB3496B0C6064756260441CDE4AF1771D4DB01FFE5B34E59703DC255A868A1180515603AEAB60794E54BB7996A7" + "0061B1CFAB6BE5F32BBFA78324ED106A7636B9C5A7BD198D0158AA4F5488D08F38514F1FDF4B4F40D2181B3681C364BA0273C706")); return new X9ECParameters(curve, G, n, h, S); } }; /* * sect571k1 */ static X9ECParametersHolder sect571k1 = new X9ECParametersHolder() { protected X9ECParameters createParameters() { int m = 571; int k1 = 2; int k2 = 5; int k3 = 10; BigInteger a = ECConstants.ZERO; BigInteger b = BigInteger.valueOf(1); byte[] S = null; BigInteger n = fromHex("020000000000000000000000000000000000000000000000000000000000000000000000131850E1F19A63E4B391A8DB917F4138B630D84BE5D639381E91DEB45CFE778F637C1001"); BigInteger h = BigInteger.valueOf(4); ECCurve curve = new ECCurve.F2m(m, k1, k2, k3, a, b, n, h); //ECPoint G = curve.decodePoint(Hex.decode("02" //+ "026EB7A859923FBC82189631F8103FE4AC9CA2970012D5D46024804801841CA44370958493B205E647DA304DB4CEB08CBBD1BA39494776FB988B47174DCA88C7E2945283A01C8972")); ECPoint G = curve.decodePoint(Hex.decode("04" + "026EB7A859923FBC82189631F8103FE4AC9CA2970012D5D46024804801841CA44370958493B205E647DA304DB4CEB08CBBD1BA39494776FB988B47174DCA88C7E2945283A01C8972" + "0349DC807F4FBF374F4AEADE3BCA95314DD58CEC9F307A54FFC61EFC006D8A2C9D4979C0AC44AEA74FBEBBB9F772AEDCB620B01A7BA7AF1B320430C8591984F601CD4C143EF1C7A3")); return new X9ECParameters(curve, G, n, h, S); } }; /* * sect571r1 */ static X9ECParametersHolder sect571r1 = new X9ECParametersHolder() { protected X9ECParameters createParameters() { int m = 571; int k1 = 2; int k2 = 5; int k3 = 10; BigInteger a = BigInteger.valueOf(1); BigInteger b = fromHex("02F40E7E2221F295DE297117B7F3D62F5C6A97FFCB8CEFF1CD6BA8CE4A9A18AD84FFABBD8EFA59332BE7AD6756A66E294AFD185A78FF12AA520E4DE739BACA0C7FFEFF7F2955727A"); byte[] S = Hex.decode("2AA058F73A0E33AB486B0F610410C53A7F132310"); BigInteger n = fromHex("03FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFE661CE18FF55987308059B186823851EC7DD9CA1161DE93D5174D66E8382E9BB2FE84E47"); BigInteger h = BigInteger.valueOf(2); ECCurve curve = new ECCurve.F2m(m, k1, k2, k3, a, b, n, h); //ECPoint G = curve.decodePoint(Hex.decode("03" //+ "0303001D34B856296C16C0D40D3CD7750A93D1D2955FA80AA5F40FC8DB7B2ABDBDE53950F4C0D293CDD711A35B67FB1499AE60038614F1394ABFA3B4C850D927E1E7769C8EEC2D19")); ECPoint G = curve.decodePoint(Hex.decode("04" + "0303001D34B856296C16C0D40D3CD7750A93D1D2955FA80AA5F40FC8DB7B2ABDBDE53950F4C0D293CDD711A35B67FB1499AE60038614F1394ABFA3B4C850D927E1E7769C8EEC2D19" + "037BF27342DA639B6DCCFFFEB73D69D78C6C27A6009CBBCA1980F8533921E8A684423E43BAB08A576291AF8F461BB2A8B3531D2F0485C19B16E2F1516E23DD3C1A4827AF1B8AC15B")); return new X9ECParameters(curve, G, n, h, S); } }; static final Hashtable objIds = new Hashtable(); static final Hashtable curves = new Hashtable(); static final Hashtable names = new Hashtable(); static void defineCurve(String name, ASN1ObjectIdentifier oid, X9ECParametersHolder holder) { objIds.put(name, oid); names.put(oid, name); curves.put(oid, holder); } static { defineCurve("secp112r1", SECObjectIdentifiers.secp112r1, secp112r1); defineCurve("secp112r2", SECObjectIdentifiers.secp112r2, secp112r2); defineCurve("secp128r1", SECObjectIdentifiers.secp128r1, secp128r1); defineCurve("secp128r2", SECObjectIdentifiers.secp128r2, secp128r2); defineCurve("secp160k1", SECObjectIdentifiers.secp160k1, secp160k1); defineCurve("secp160r1", SECObjectIdentifiers.secp160r1, secp160r1); defineCurve("secp160r2", SECObjectIdentifiers.secp160r2, secp160r2); defineCurve("secp192k1", SECObjectIdentifiers.secp192k1, secp192k1); defineCurve("secp192r1", SECObjectIdentifiers.secp192r1, secp192r1); defineCurve("secp224k1", SECObjectIdentifiers.secp224k1, secp224k1); defineCurve("secp224r1", SECObjectIdentifiers.secp224r1, secp224r1); defineCurve("secp256k1", SECObjectIdentifiers.secp256k1, secp256k1); defineCurve("secp256r1", SECObjectIdentifiers.secp256r1, secp256r1); defineCurve("secp384r1", SECObjectIdentifiers.secp384r1, secp384r1); defineCurve("secp521r1", SECObjectIdentifiers.secp521r1, secp521r1); defineCurve("sect113r1", SECObjectIdentifiers.sect113r1, sect113r1); defineCurve("sect113r2", SECObjectIdentifiers.sect113r2, sect113r2); defineCurve("sect131r1", SECObjectIdentifiers.sect131r1, sect131r1); defineCurve("sect131r2", SECObjectIdentifiers.sect131r2, sect131r2); defineCurve("sect163k1", SECObjectIdentifiers.sect163k1, sect163k1); defineCurve("sect163r1", SECObjectIdentifiers.sect163r1, sect163r1); defineCurve("sect163r2", SECObjectIdentifiers.sect163r2, sect163r2); defineCurve("sect193r1", SECObjectIdentifiers.sect193r1, sect193r1); defineCurve("sect193r2", SECObjectIdentifiers.sect193r2, sect193r2); defineCurve("sect233k1", SECObjectIdentifiers.sect233k1, sect233k1); defineCurve("sect233r1", SECObjectIdentifiers.sect233r1, sect233r1); defineCurve("sect239k1", SECObjectIdentifiers.sect239k1, sect239k1); defineCurve("sect283k1", SECObjectIdentifiers.sect283k1, sect283k1); defineCurve("sect283r1", SECObjectIdentifiers.sect283r1, sect283r1); defineCurve("sect409k1", SECObjectIdentifiers.sect409k1, sect409k1); defineCurve("sect409r1", SECObjectIdentifiers.sect409r1, sect409r1); defineCurve("sect571k1", SECObjectIdentifiers.sect571k1, sect571k1); defineCurve("sect571r1", SECObjectIdentifiers.sect571r1, sect571r1); } public static X9ECParameters getByName( String name) { ASN1ObjectIdentifier oid = (ASN1ObjectIdentifier)objIds.get(Strings.toLowerCase(name)); if (oid != null) { return getByOID(oid); } return null; } /** * return the X9ECParameters object for the named curve represented by * the passed in object identifier. Null if the curve isn't present. * * @param oid an object identifier representing a named curve, if present. */ public static X9ECParameters getByOID( ASN1ObjectIdentifier oid) { X9ECParametersHolder holder = (X9ECParametersHolder)curves.get(oid); if (holder != null) { return holder.getParameters(); } return null; } /** * return the object identifier signified by the passed in name. Null * if there is no object identifier associated with name. * * @return the object identifier associated with name, if present. */ public static ASN1ObjectIdentifier getOID( String name) { return (ASN1ObjectIdentifier)objIds.get(Strings.toLowerCase(name)); } /** * return the named curve name represented by the given object identifier. */ public static String getName( ASN1ObjectIdentifier oid) { return (String)names.get(oid); } /** * returns an enumeration containing the name strings for curves * contained in this structure. */ public static Enumeration getNames() { return objIds.keys(); } } bouncycastle-1.49.orig/src/org/bouncycastle/asn1/sec/ECPrivateKey.java0000644000175000017500000000655211624622714025271 0ustar ebourgebourgpackage org.bouncycastle.asn1.sec; import java.math.BigInteger; import java.util.Enumeration; import org.bouncycastle.asn1.ASN1Encodable; import org.bouncycastle.asn1.ASN1EncodableVector; import org.bouncycastle.asn1.ASN1Integer; import org.bouncycastle.asn1.ASN1Object; import org.bouncycastle.asn1.ASN1OctetString; import org.bouncycastle.asn1.ASN1Primitive; import org.bouncycastle.asn1.ASN1Sequence; import org.bouncycastle.asn1.ASN1TaggedObject; import org.bouncycastle.asn1.DERBitString; import org.bouncycastle.asn1.DEROctetString; import org.bouncycastle.asn1.DERSequence; import org.bouncycastle.asn1.DERTaggedObject; import org.bouncycastle.util.BigIntegers; /** * the elliptic curve private key object from SEC 1 */ public class ECPrivateKey extends ASN1Object { private ASN1Sequence seq; private ECPrivateKey( ASN1Sequence seq) { this.seq = seq; } public static ECPrivateKey getInstance( Object obj) { if (obj instanceof ECPrivateKey) { return (ECPrivateKey)obj; } if (obj != null) { return new ECPrivateKey(ASN1Sequence.getInstance(obj)); } return null; } public ECPrivateKey( BigInteger key) { byte[] bytes = BigIntegers.asUnsignedByteArray(key); ASN1EncodableVector v = new ASN1EncodableVector(); v.add(new ASN1Integer(1)); v.add(new DEROctetString(bytes)); seq = new DERSequence(v); } public ECPrivateKey( BigInteger key, ASN1Object parameters) { this(key, null, parameters); } public ECPrivateKey( BigInteger key, DERBitString publicKey, ASN1Object parameters) { byte[] bytes = BigIntegers.asUnsignedByteArray(key); ASN1EncodableVector v = new ASN1EncodableVector(); v.add(new ASN1Integer(1)); v.add(new DEROctetString(bytes)); if (parameters != null) { v.add(new DERTaggedObject(true, 0, parameters)); } if (publicKey != null) { v.add(new DERTaggedObject(true, 1, publicKey)); } seq = new DERSequence(v); } public BigInteger getKey() { ASN1OctetString octs = (ASN1OctetString)seq.getObjectAt(1); return new BigInteger(1, octs.getOctets()); } public DERBitString getPublicKey() { return (DERBitString)getObjectInTag(1); } public ASN1Primitive getParameters() { return getObjectInTag(0); } private ASN1Primitive getObjectInTag(int tagNo) { Enumeration e = seq.getObjects(); while (e.hasMoreElements()) { ASN1Encodable obj = (ASN1Encodable)e.nextElement(); if (obj instanceof ASN1TaggedObject) { ASN1TaggedObject tag = (ASN1TaggedObject)obj; if (tag.getTagNo() == tagNo) { return tag.getObject().toASN1Primitive(); } } } return null; } /** * ECPrivateKey ::= SEQUENCE { * version INTEGER { ecPrivkeyVer1(1) } (ecPrivkeyVer1), * privateKey OCTET STRING, * parameters [0] Parameters OPTIONAL, * publicKey [1] BIT STRING OPTIONAL } */ public ASN1Primitive toASN1Primitive() { return seq; } } bouncycastle-1.49.orig/src/org/bouncycastle/asn1/sec/package.html0000644000175000017500000000015410262753175024407 0ustar ebourgebourg Classes for support of the SEC standard for Elliptic Curve. bouncycastle-1.49.orig/src/org/bouncycastle/asn1/ASN1InputStream.java0000644000175000017500000003321411703735642025120 0ustar ebourgebourgpackage org.bouncycastle.asn1; import java.io.ByteArrayInputStream; import java.io.EOFException; import java.io.FilterInputStream; import java.io.IOException; import java.io.InputStream; import org.bouncycastle.util.io.Streams; /** * a general purpose ASN.1 decoder - note: this class differs from the * others in that it returns null after it has read the last object in * the stream. If an ASN.1 NULL is encountered a DER/BER Null object is * returned. */ public class ASN1InputStream extends FilterInputStream implements BERTags { private final int limit; private final boolean lazyEvaluate; private final byte[][] tmpBuffers; public ASN1InputStream( InputStream is) { this(is, StreamUtil.findLimit(is)); } /** * Create an ASN1InputStream based on the input byte array. The length of DER objects in * the stream is automatically limited to the length of the input array. * * @param input array containing ASN.1 encoded data. */ public ASN1InputStream( byte[] input) { this(new ByteArrayInputStream(input), input.length); } /** * Create an ASN1InputStream based on the input byte array. The length of DER objects in * the stream is automatically limited to the length of the input array. * * @param input array containing ASN.1 encoded data. * @param lazyEvaluate true if parsing inside constructed objects can be delayed. */ public ASN1InputStream( byte[] input, boolean lazyEvaluate) { this(new ByteArrayInputStream(input), input.length, lazyEvaluate); } /** * Create an ASN1InputStream where no DER object will be longer than limit. * * @param input stream containing ASN.1 encoded data. * @param limit maximum size of a DER encoded object. */ public ASN1InputStream( InputStream input, int limit) { this(input, limit, false); } /** * Create an ASN1InputStream where no DER object will be longer than limit, and constructed * objects such as sequences will be parsed lazily. * * @param input stream containing ASN.1 encoded data. * @param lazyEvaluate true if parsing inside constructed objects can be delayed. */ public ASN1InputStream( InputStream input, boolean lazyEvaluate) { this(input, StreamUtil.findLimit(input), lazyEvaluate); } /** * Create an ASN1InputStream where no DER object will be longer than limit, and constructed * objects such as sequences will be parsed lazily. * * @param input stream containing ASN.1 encoded data. * @param limit maximum size of a DER encoded object. * @param lazyEvaluate true if parsing inside constructed objects can be delayed. */ public ASN1InputStream( InputStream input, int limit, boolean lazyEvaluate) { super(input); this.limit = limit; this.lazyEvaluate = lazyEvaluate; this.tmpBuffers = new byte[11][]; } int getLimit() { return limit; } protected int readLength() throws IOException { return readLength(this, limit); } protected void readFully( byte[] bytes) throws IOException { if (Streams.readFully(this, bytes) != bytes.length) { throw new EOFException("EOF encountered in middle of object"); } } /** * build an object given its tag and the number of bytes to construct it from. */ protected ASN1Primitive buildObject( int tag, int tagNo, int length) throws IOException { boolean isConstructed = (tag & CONSTRUCTED) != 0; DefiniteLengthInputStream defIn = new DefiniteLengthInputStream(this, length); if ((tag & APPLICATION) != 0) { return new DERApplicationSpecific(isConstructed, tagNo, defIn.toByteArray()); } if ((tag & TAGGED) != 0) { return new ASN1StreamParser(defIn).readTaggedObject(isConstructed, tagNo); } if (isConstructed) { // TODO There are other tags that may be constructed (e.g. BIT_STRING) switch (tagNo) { case OCTET_STRING: // // yes, people actually do this... // ASN1EncodableVector v = buildDEREncodableVector(defIn); ASN1OctetString[] strings = new ASN1OctetString[v.size()]; for (int i = 0; i != strings.length; i++) { strings[i] = (ASN1OctetString)v.get(i); } return new BEROctetString(strings); case SEQUENCE: if (lazyEvaluate) { return new LazyEncodedSequence(defIn.toByteArray()); } else { return DERFactory.createSequence(buildDEREncodableVector(defIn)); } case SET: return DERFactory.createSet(buildDEREncodableVector(defIn)); case EXTERNAL: return new DERExternal(buildDEREncodableVector(defIn)); default: throw new IOException("unknown tag " + tagNo + " encountered"); } } return createPrimitiveDERObject(tagNo, defIn, tmpBuffers); } ASN1EncodableVector buildEncodableVector() throws IOException { ASN1EncodableVector v = new ASN1EncodableVector(); ASN1Primitive o; while ((o = readObject()) != null) { v.add(o); } return v; } ASN1EncodableVector buildDEREncodableVector( DefiniteLengthInputStream dIn) throws IOException { return new ASN1InputStream(dIn).buildEncodableVector(); } public ASN1Primitive readObject() throws IOException { int tag = read(); if (tag <= 0) { if (tag == 0) { throw new IOException("unexpected end-of-contents marker"); } return null; } // // calculate tag number // int tagNo = readTagNumber(this, tag); boolean isConstructed = (tag & CONSTRUCTED) != 0; // // calculate length // int length = readLength(); if (length < 0) // indefinite length method { if (!isConstructed) { throw new IOException("indefinite length primitive encoding encountered"); } IndefiniteLengthInputStream indIn = new IndefiniteLengthInputStream(this, limit); ASN1StreamParser sp = new ASN1StreamParser(indIn, limit); if ((tag & APPLICATION) != 0) { return new BERApplicationSpecificParser(tagNo, sp).getLoadedObject(); } if ((tag & TAGGED) != 0) { return new BERTaggedObjectParser(true, tagNo, sp).getLoadedObject(); } // TODO There are other tags that may be constructed (e.g. BIT_STRING) switch (tagNo) { case OCTET_STRING: return new BEROctetStringParser(sp).getLoadedObject(); case SEQUENCE: return new BERSequenceParser(sp).getLoadedObject(); case SET: return new BERSetParser(sp).getLoadedObject(); case EXTERNAL: return new DERExternalParser(sp).getLoadedObject(); default: throw new IOException("unknown BER object encountered"); } } else { try { return buildObject(tag, tagNo, length); } catch (IllegalArgumentException e) { throw new ASN1Exception("corrupted stream detected", e); } } } static int readTagNumber(InputStream s, int tag) throws IOException { int tagNo = tag & 0x1f; // // with tagged object tag number is bottom 5 bits, or stored at the start of the content // if (tagNo == 0x1f) { tagNo = 0; int b = s.read(); // X.690-0207 8.1.2.4.2 // "c) bits 7 to 1 of the first subsequent octet shall not all be zero." if ((b & 0x7f) == 0) // Note: -1 will pass { throw new IOException("corrupted stream - invalid high tag number found"); } while ((b >= 0) && ((b & 0x80) != 0)) { tagNo |= (b & 0x7f); tagNo <<= 7; b = s.read(); } if (b < 0) { throw new EOFException("EOF found inside tag value."); } tagNo |= (b & 0x7f); } return tagNo; } static int readLength(InputStream s, int limit) throws IOException { int length = s.read(); if (length < 0) { throw new EOFException("EOF found when length expected"); } if (length == 0x80) { return -1; // indefinite-length encoding } if (length > 127) { int size = length & 0x7f; // Note: The invalid long form "0xff" (see X.690 8.1.3.5c) will be caught here if (size > 4) { throw new IOException("DER length more than 4 bytes: " + size); } length = 0; for (int i = 0; i < size; i++) { int next = s.read(); if (next < 0) { throw new EOFException("EOF found reading length"); } length = (length << 8) + next; } if (length < 0) { throw new IOException("corrupted stream - negative length found"); } if (length >= limit) // after all we must have read at least 1 byte { throw new IOException("corrupted stream - out of bounds length found"); } } return length; } private static byte[] getBuffer(DefiniteLengthInputStream defIn, byte[][] tmpBuffers) throws IOException { int len = defIn.getRemaining(); if (defIn.getRemaining() < tmpBuffers.length) { byte[] buf = tmpBuffers[len]; if (buf == null) { buf = tmpBuffers[len] = new byte[len]; } Streams.readFully(defIn, buf); return buf; } else { return defIn.toByteArray(); } } private static char[] getBMPCharBuffer(DefiniteLengthInputStream defIn) throws IOException { int len = defIn.getRemaining() / 2; char[] buf = new char[len]; int totalRead = 0; while (totalRead < len) { int ch1 = defIn.read(); if (ch1 < 0) { break; } int ch2 = defIn.read(); if (ch2 < 0) { break; } buf[totalRead++] = (char)((ch1 << 8) | (ch2 & 0xff)); } return buf; } static ASN1Primitive createPrimitiveDERObject( int tagNo, DefiniteLengthInputStream defIn, byte[][] tmpBuffers) throws IOException { switch (tagNo) { case BIT_STRING: return DERBitString.fromInputStream(defIn.getRemaining(), defIn); case BMP_STRING: return new DERBMPString(getBMPCharBuffer(defIn)); case BOOLEAN: return ASN1Boolean.fromOctetString(getBuffer(defIn, tmpBuffers)); case ENUMERATED: return ASN1Enumerated.fromOctetString(getBuffer(defIn, tmpBuffers)); case GENERALIZED_TIME: return new ASN1GeneralizedTime(defIn.toByteArray()); case GENERAL_STRING: return new DERGeneralString(defIn.toByteArray()); case IA5_STRING: return new DERIA5String(defIn.toByteArray()); case INTEGER: return new ASN1Integer(defIn.toByteArray()); case NULL: return DERNull.INSTANCE; // actual content is ignored (enforce 0 length?) case NUMERIC_STRING: return new DERNumericString(defIn.toByteArray()); case OBJECT_IDENTIFIER: return ASN1ObjectIdentifier.fromOctetString(getBuffer(defIn, tmpBuffers)); case OCTET_STRING: return new DEROctetString(defIn.toByteArray()); case PRINTABLE_STRING: return new DERPrintableString(defIn.toByteArray()); case T61_STRING: return new DERT61String(defIn.toByteArray()); case UNIVERSAL_STRING: return new DERUniversalString(defIn.toByteArray()); case UTC_TIME: return new ASN1UTCTime(defIn.toByteArray()); case UTF8_STRING: return new DERUTF8String(defIn.toByteArray()); case VISIBLE_STRING: return new DERVisibleString(defIn.toByteArray()); default: throw new IOException("unknown tag " + tagNo + " encountered"); } } } bouncycastle-1.49.orig/src/org/bouncycastle/asn1/ASN1Exception.java0000644000175000017500000000061711624614575024607 0ustar ebourgebourgpackage org.bouncycastle.asn1; import java.io.IOException; public class ASN1Exception extends IOException { private Throwable cause; ASN1Exception(String message) { super(message); } ASN1Exception(String message, Throwable cause) { super(message); this.cause = cause; } public Throwable getCause() { return cause; } } bouncycastle-1.49.orig/src/org/bouncycastle/asn1/BERSequenceParser.java0000644000175000017500000000136011624617033025470 0ustar ebourgebourgpackage org.bouncycastle.asn1; import java.io.IOException; public class BERSequenceParser implements ASN1SequenceParser { private ASN1StreamParser _parser; BERSequenceParser(ASN1StreamParser parser) { this._parser = parser; } public ASN1Encodable readObject() throws IOException { return _parser.readObject(); } public ASN1Primitive getLoadedObject() throws IOException { return new BERSequence(_parser.readVector()); } public ASN1Primitive toASN1Primitive() { try { return getLoadedObject(); } catch (IOException e) { throw new IllegalStateException(e.getMessage()); } } } bouncycastle-1.49.orig/src/org/bouncycastle/asn1/BERTaggedObject.java0000644000175000017500000000731111703205061025057 0ustar ebourgebourgpackage org.bouncycastle.asn1; import java.io.IOException; import java.util.Enumeration; /** * BER TaggedObject - in ASN.1 notation this is any object preceded by * a [n] where n is some number - these are assumed to follow the construction * rules (as with sequences). */ public class BERTaggedObject extends ASN1TaggedObject { /** * @param tagNo the tag number for this object. * @param obj the tagged object. */ public BERTaggedObject( int tagNo, ASN1Encodable obj) { super(true, tagNo, obj); } /** * @param explicit true if an explicitly tagged object. * @param tagNo the tag number for this object. * @param obj the tagged object. */ public BERTaggedObject( boolean explicit, int tagNo, ASN1Encodable obj) { super(explicit, tagNo, obj); } /** * create an implicitly tagged object that contains a zero * length sequence. */ public BERTaggedObject( int tagNo) { super(false, tagNo, new BERSequence()); } boolean isConstructed() { if (!empty) { if (explicit) { return true; } else { ASN1Primitive primitive = obj.toASN1Primitive().toDERObject(); return primitive.isConstructed(); } } else { return true; } } int encodedLength() throws IOException { if (!empty) { ASN1Primitive primitive = obj.toASN1Primitive(); int length = primitive.encodedLength(); if (explicit) { return StreamUtil.calculateTagLength(tagNo) + StreamUtil.calculateBodyLength(length) + length; } else { // header length already in calculation length = length - 1; return StreamUtil.calculateTagLength(tagNo) + length; } } else { return StreamUtil.calculateTagLength(tagNo) + 1; } } void encode( ASN1OutputStream out) throws IOException { out.writeTag(BERTags.CONSTRUCTED | BERTags.TAGGED, tagNo); out.write(0x80); if (!empty) { if (!explicit) { Enumeration e; if (obj instanceof ASN1OctetString) { if (obj instanceof BEROctetString) { e = ((BEROctetString)obj).getObjects(); } else { ASN1OctetString octs = (ASN1OctetString)obj; BEROctetString berO = new BEROctetString(octs.getOctets()); e = berO.getObjects(); } } else if (obj instanceof ASN1Sequence) { e = ((ASN1Sequence)obj).getObjects(); } else if (obj instanceof ASN1Set) { e = ((ASN1Set)obj).getObjects(); } else { throw new RuntimeException("not implemented: " + obj.getClass().getName()); } while (e.hasMoreElements()) { out.writeObject((ASN1Encodable)e.nextElement()); } } else { out.writeObject(obj); } } out.write(0x00); out.write(0x00); } } bouncycastle-1.49.orig/src/org/bouncycastle/asn1/package.html0000644000175000017500000000021710262753174023634 0ustar ebourgebourg A library for parsing and writing ASN.1 objects. Support is provided for DER and BER encoding. bouncycastle-1.49.orig/src/org/bouncycastle/asn1/ASN1ApplicationSpecificParser.java0000644000175000017500000000033411624614575027733 0ustar ebourgebourgpackage org.bouncycastle.asn1; import java.io.IOException; public interface ASN1ApplicationSpecificParser extends ASN1Encodable, InMemoryRepresentable { ASN1Encodable readObject() throws IOException; } bouncycastle-1.49.orig/src/org/bouncycastle/asn1/DEREncodableVector.java0000644000175000017500000000062011624616720025604 0ustar ebourgebourgpackage org.bouncycastle.asn1; /** * a general class for building up a vector of DER encodable objects - * this will eventually be superceded by ASN1EncodableVector so you should * use that class in preference. */ public class DEREncodableVector extends ASN1EncodableVector { /** * @deprecated use ASN1EncodableVector instead. */ public DEREncodableVector() { } } bouncycastle-1.49.orig/src/org/bouncycastle/asn1/DEROutputStream.java0000644000175000017500000000136611703154552025227 0ustar ebourgebourgpackage org.bouncycastle.asn1; import java.io.IOException; import java.io.OutputStream; /** * Stream that outputs encoding based on distinguished encoding rules. */ public class DEROutputStream extends ASN1OutputStream { public DEROutputStream( OutputStream os) { super(os); } public void writeObject( ASN1Encodable obj) throws IOException { if (obj != null) { obj.toASN1Primitive().toDERObject().encode(this); } else { throw new IOException("null object detected"); } } ASN1OutputStream getDERSubStream() { return this; } ASN1OutputStream getDLSubStream() { return this; } } bouncycastle-1.49.orig/src/org/bouncycastle/asn1/esf/0000755000175000017500000000000012152033551022116 5ustar ebourgebourgbouncycastle-1.49.orig/src/org/bouncycastle/asn1/esf/CommitmentTypeQualifier.java0000644000175000017500000000567011725567234027630 0ustar ebourgebourgpackage org.bouncycastle.asn1.esf; import org.bouncycastle.asn1.ASN1Encodable; import org.bouncycastle.asn1.ASN1EncodableVector; import org.bouncycastle.asn1.ASN1Object; import org.bouncycastle.asn1.ASN1ObjectIdentifier; import org.bouncycastle.asn1.ASN1Primitive; import org.bouncycastle.asn1.ASN1Sequence; import org.bouncycastle.asn1.DERSequence; /** * Commitment type qualifiers, used in the Commitment-Type-Indication attribute (RFC3126). * *
     *   CommitmentTypeQualifier ::= SEQUENCE {
     *       commitmentTypeIdentifier  CommitmentTypeIdentifier,
     *       qualifier          ANY DEFINED BY commitmentTypeIdentifier OPTIONAL }
     * 
    */ public class CommitmentTypeQualifier extends ASN1Object { private ASN1ObjectIdentifier commitmentTypeIdentifier; private ASN1Encodable qualifier; /** * Creates a new CommitmentTypeQualifier instance. * * @param commitmentTypeIdentifier a CommitmentTypeIdentifier value */ public CommitmentTypeQualifier( ASN1ObjectIdentifier commitmentTypeIdentifier) { this(commitmentTypeIdentifier, null); } /** * Creates a new CommitmentTypeQualifier instance. * * @param commitmentTypeIdentifier a CommitmentTypeIdentifier value * @param qualifier the qualifier, defined by the above field. */ public CommitmentTypeQualifier( ASN1ObjectIdentifier commitmentTypeIdentifier, ASN1Encodable qualifier) { this.commitmentTypeIdentifier = commitmentTypeIdentifier; this.qualifier = qualifier; } /** * Creates a new CommitmentTypeQualifier instance. * * @param as CommitmentTypeQualifier structure * encoded as an ASN1Sequence. */ private CommitmentTypeQualifier( ASN1Sequence as) { commitmentTypeIdentifier = (ASN1ObjectIdentifier)as.getObjectAt(0); if (as.size() > 1) { qualifier = as.getObjectAt(1); } } public static CommitmentTypeQualifier getInstance(Object as) { if (as instanceof CommitmentTypeQualifier) { return (CommitmentTypeQualifier)as; } else if (as != null) { return new CommitmentTypeQualifier(ASN1Sequence.getInstance(as)); } return null; } public ASN1ObjectIdentifier getCommitmentTypeIdentifier() { return commitmentTypeIdentifier; } public ASN1Encodable getQualifier() { return qualifier; } /** * Returns a DER-encodable representation of this instance. * * @return a ASN1Primitive value */ public ASN1Primitive toASN1Primitive() { ASN1EncodableVector dev = new ASN1EncodableVector(); dev.add(commitmentTypeIdentifier); if (qualifier != null) { dev.add(qualifier); } return new DERSequence(dev); } } bouncycastle-1.49.orig/src/org/bouncycastle/asn1/esf/OtherRevRefs.java0000644000175000017500000000433011725530461025346 0ustar ebourgebourgpackage org.bouncycastle.asn1.esf; import java.io.IOException; import org.bouncycastle.asn1.ASN1Encodable; import org.bouncycastle.asn1.ASN1EncodableVector; import org.bouncycastle.asn1.ASN1Encoding; import org.bouncycastle.asn1.ASN1Object; import org.bouncycastle.asn1.ASN1ObjectIdentifier; import org.bouncycastle.asn1.ASN1Primitive; import org.bouncycastle.asn1.ASN1Sequence; import org.bouncycastle.asn1.DERSequence; /** *
     * OtherRevRefs ::= SEQUENCE {
     *   otherRevRefType OtherRevRefType,
     *   otherRevRefs ANY DEFINED BY otherRevRefType
     * }
     *
     * OtherRevRefType ::= OBJECT IDENTIFIER
     * 
    */ public class OtherRevRefs extends ASN1Object { private ASN1ObjectIdentifier otherRevRefType; private ASN1Encodable otherRevRefs; public static OtherRevRefs getInstance(Object obj) { if (obj instanceof OtherRevRefs) { return (OtherRevRefs)obj; } else if (obj != null) { return new OtherRevRefs(ASN1Sequence.getInstance(obj)); } return null; } private OtherRevRefs(ASN1Sequence seq) { if (seq.size() != 2) { throw new IllegalArgumentException("Bad sequence size: " + seq.size()); } this.otherRevRefType = new ASN1ObjectIdentifier(((ASN1ObjectIdentifier)seq.getObjectAt(0)).getId()); try { this.otherRevRefs = ASN1Primitive.fromByteArray(seq.getObjectAt(1) .toASN1Primitive().getEncoded(ASN1Encoding.DER)); } catch (IOException e) { throw new IllegalStateException(); } } public OtherRevRefs(ASN1ObjectIdentifier otherRevRefType, ASN1Encodable otherRevRefs) { this.otherRevRefType = otherRevRefType; this.otherRevRefs = otherRevRefs; } public ASN1ObjectIdentifier getOtherRevRefType() { return this.otherRevRefType; } public ASN1Encodable getOtherRevRefs() { return this.otherRevRefs; } public ASN1Primitive toASN1Primitive() { ASN1EncodableVector v = new ASN1EncodableVector(); v.add(this.otherRevRefType); v.add(this.otherRevRefs); return new DERSequence(v); } } bouncycastle-1.49.orig/src/org/bouncycastle/asn1/esf/SPUserNotice.java0000644000175000017500000000472612062243717025324 0ustar ebourgebourgpackage org.bouncycastle.asn1.esf; import java.util.Enumeration; import org.bouncycastle.asn1.ASN1Encodable; import org.bouncycastle.asn1.ASN1EncodableVector; import org.bouncycastle.asn1.ASN1Object; import org.bouncycastle.asn1.ASN1Primitive; import org.bouncycastle.asn1.ASN1Sequence; import org.bouncycastle.asn1.ASN1String; import org.bouncycastle.asn1.DERSequence; import org.bouncycastle.asn1.x509.DisplayText; import org.bouncycastle.asn1.x509.NoticeReference; public class SPUserNotice extends ASN1Object { private NoticeReference noticeRef; private DisplayText explicitText; public static SPUserNotice getInstance( Object obj) { if (obj instanceof SPUserNotice) { return (SPUserNotice)obj; } else if (obj != null) { return new SPUserNotice(ASN1Sequence.getInstance(obj)); } return null; } private SPUserNotice( ASN1Sequence seq) { Enumeration e = seq.getObjects(); while (e.hasMoreElements()) { ASN1Encodable object = (ASN1Encodable)e.nextElement(); if (object instanceof DisplayText || object instanceof ASN1String) { explicitText = DisplayText.getInstance(object); } else if (object instanceof NoticeReference || object instanceof ASN1Sequence) { noticeRef = NoticeReference.getInstance(object); } else { throw new IllegalArgumentException("Invalid element in 'SPUserNotice': " + object.getClass().getName()); } } } public SPUserNotice( NoticeReference noticeRef, DisplayText explicitText) { this.noticeRef = noticeRef; this.explicitText = explicitText; } public NoticeReference getNoticeRef() { return noticeRef; } public DisplayText getExplicitText() { return explicitText; } /** *
         * SPUserNotice ::= SEQUENCE {
         *     noticeRef NoticeReference OPTIONAL,
         *     explicitText DisplayText OPTIONAL }
         * 
    */ public ASN1Primitive toASN1Primitive() { ASN1EncodableVector v = new ASN1EncodableVector(); if (noticeRef != null) { v.add(noticeRef); } if (explicitText != null) { v.add(explicitText); } return new DERSequence(v); } } bouncycastle-1.49.orig/src/org/bouncycastle/asn1/esf/SPuri.java0000644000175000017500000000143111725271517024035 0ustar ebourgebourgpackage org.bouncycastle.asn1.esf; import org.bouncycastle.asn1.ASN1Primitive; import org.bouncycastle.asn1.DERIA5String; public class SPuri { private DERIA5String uri; public static SPuri getInstance( Object obj) { if (obj instanceof SPuri) { return (SPuri) obj; } else if (obj instanceof DERIA5String) { return new SPuri(DERIA5String.getInstance(obj)); } return null; } public SPuri( DERIA5String uri) { this.uri = uri; } public DERIA5String getUri() { return uri; } /** *
         * SPuri ::= IA5String
         * 
    */ public ASN1Primitive toASN1Primitive() { return uri.toASN1Primitive(); } } bouncycastle-1.49.orig/src/org/bouncycastle/asn1/esf/CrlListID.java0000644000175000017500000000273111725271247024570 0ustar ebourgebourgpackage org.bouncycastle.asn1.esf; import java.util.Enumeration; import org.bouncycastle.asn1.ASN1Object; import org.bouncycastle.asn1.ASN1Primitive; import org.bouncycastle.asn1.ASN1Sequence; import org.bouncycastle.asn1.DERSequence; /** *
     * CRLListID ::= SEQUENCE {
     *     crls SEQUENCE OF CrlValidatedID }
     * 
    */ public class CrlListID extends ASN1Object { private ASN1Sequence crls; public static CrlListID getInstance(Object obj) { if (obj instanceof CrlListID) { return (CrlListID)obj; } else if (obj != null) { return new CrlListID(ASN1Sequence.getInstance(obj)); } return null; } private CrlListID(ASN1Sequence seq) { this.crls = (ASN1Sequence)seq.getObjectAt(0); Enumeration e = this.crls.getObjects(); while (e.hasMoreElements()) { CrlValidatedID.getInstance(e.nextElement()); } } public CrlListID(CrlValidatedID[] crls) { this.crls = new DERSequence(crls); } public CrlValidatedID[] getCrls() { CrlValidatedID[] result = new CrlValidatedID[this.crls.size()]; for (int idx = 0; idx < result.length; idx++) { result[idx] = CrlValidatedID .getInstance(this.crls.getObjectAt(idx)); } return result; } public ASN1Primitive toASN1Primitive() { return new DERSequence(this.crls); } } bouncycastle-1.49.orig/src/org/bouncycastle/asn1/esf/SignaturePolicyIdentifier.java0000644000175000017500000000360512103437527030120 0ustar ebourgebourgpackage org.bouncycastle.asn1.esf; import org.bouncycastle.asn1.ASN1Null; import org.bouncycastle.asn1.ASN1Object; import org.bouncycastle.asn1.ASN1Primitive; import org.bouncycastle.asn1.BERTags; import org.bouncycastle.asn1.DERNull; public class SignaturePolicyIdentifier extends ASN1Object { private SignaturePolicyId signaturePolicyId; private boolean isSignaturePolicyImplied; public static SignaturePolicyIdentifier getInstance( Object obj) { if (obj instanceof SignaturePolicyIdentifier) { return (SignaturePolicyIdentifier)obj; } else if (obj instanceof ASN1Null || hasEncodedTagValue(obj, BERTags.NULL)) { return new SignaturePolicyIdentifier(); } else if (obj != null) { return new SignaturePolicyIdentifier(SignaturePolicyId.getInstance(obj)); } return null; } public SignaturePolicyIdentifier() { this.isSignaturePolicyImplied = true; } public SignaturePolicyIdentifier( SignaturePolicyId signaturePolicyId) { this.signaturePolicyId = signaturePolicyId; this.isSignaturePolicyImplied = false; } public SignaturePolicyId getSignaturePolicyId() { return signaturePolicyId; } public boolean isSignaturePolicyImplied() { return isSignaturePolicyImplied; } /** *
         * SignaturePolicyIdentifier ::= CHOICE{
         *     SignaturePolicyId         SignaturePolicyId,
         *     SignaturePolicyImplied    SignaturePolicyImplied }
         *
         * SignaturePolicyImplied ::= NULL
         * 
    */ public ASN1Primitive toASN1Primitive() { if (isSignaturePolicyImplied) { return DERNull.INSTANCE; } else { return signaturePolicyId.toASN1Primitive(); } } } bouncycastle-1.49.orig/src/org/bouncycastle/asn1/esf/OcspIdentifier.java0000644000175000017500000000362511737275254025716 0ustar ebourgebourgpackage org.bouncycastle.asn1.esf; import org.bouncycastle.asn1.ASN1EncodableVector; import org.bouncycastle.asn1.ASN1GeneralizedTime; import org.bouncycastle.asn1.ASN1Object; import org.bouncycastle.asn1.ASN1Primitive; import org.bouncycastle.asn1.ASN1Sequence; import org.bouncycastle.asn1.DERSequence; import org.bouncycastle.asn1.ocsp.ResponderID; /** *
     * OcspIdentifier ::= SEQUENCE {
     *     ocspResponderID ResponderID, -- As in OCSP response data
     *     producedAt GeneralizedTime -- As in OCSP response data
     * }
     * 
    */ public class OcspIdentifier extends ASN1Object { private ResponderID ocspResponderID; private ASN1GeneralizedTime producedAt; public static OcspIdentifier getInstance(Object obj) { if (obj instanceof OcspIdentifier) { return (OcspIdentifier)obj; } else if (obj != null) { return new OcspIdentifier(ASN1Sequence.getInstance(obj)); } return null; } private OcspIdentifier(ASN1Sequence seq) { if (seq.size() != 2) { throw new IllegalArgumentException("Bad sequence size: " + seq.size()); } this.ocspResponderID = ResponderID.getInstance(seq.getObjectAt(0)); this.producedAt = (ASN1GeneralizedTime)seq.getObjectAt(1); } public OcspIdentifier(ResponderID ocspResponderID, ASN1GeneralizedTime producedAt) { this.ocspResponderID = ocspResponderID; this.producedAt = producedAt; } public ResponderID getOcspResponderID() { return this.ocspResponderID; } public ASN1GeneralizedTime getProducedAt() { return this.producedAt; } public ASN1Primitive toASN1Primitive() { ASN1EncodableVector v = new ASN1EncodableVector(); v.add(this.ocspResponderID); v.add(this.producedAt); return new DERSequence(v); } } bouncycastle-1.49.orig/src/org/bouncycastle/asn1/esf/SignerAttribute.java0000644000175000017500000000665311725567100026115 0ustar ebourgebourgpackage org.bouncycastle.asn1.esf; import java.util.Enumeration; import org.bouncycastle.asn1.ASN1EncodableVector; import org.bouncycastle.asn1.ASN1Object; import org.bouncycastle.asn1.ASN1Primitive; import org.bouncycastle.asn1.ASN1Sequence; import org.bouncycastle.asn1.ASN1TaggedObject; import org.bouncycastle.asn1.DERSequence; import org.bouncycastle.asn1.DERTaggedObject; import org.bouncycastle.asn1.x509.Attribute; import org.bouncycastle.asn1.x509.AttributeCertificate; public class SignerAttribute extends ASN1Object { private Object[] values; public static SignerAttribute getInstance( Object o) { if (o instanceof SignerAttribute) { return (SignerAttribute) o; } else if (o != null) { return new SignerAttribute(ASN1Sequence.getInstance(o)); } return null; } private SignerAttribute( ASN1Sequence seq) { int index = 0; values = new Object[seq.size()]; for (Enumeration e = seq.getObjects(); e.hasMoreElements();) { ASN1TaggedObject taggedObject = ASN1TaggedObject.getInstance(e.nextElement()); if (taggedObject.getTagNo() == 0) { ASN1Sequence attrs = ASN1Sequence.getInstance(taggedObject, true); Attribute[] attributes = new Attribute[attrs.size()]; for (int i = 0; i != attributes.length; i++) { attributes[i] = Attribute.getInstance(attrs.getObjectAt(i)); } values[index] = attributes; } else if (taggedObject.getTagNo() == 1) { values[index] = AttributeCertificate.getInstance(ASN1Sequence.getInstance(taggedObject, true)); } else { throw new IllegalArgumentException("illegal tag: " + taggedObject.getTagNo()); } index++; } } public SignerAttribute( Attribute[] claimedAttributes) { this.values = new Object[1]; this.values[0] = claimedAttributes; } public SignerAttribute( AttributeCertificate certifiedAttributes) { this.values = new Object[1]; this.values[0] = certifiedAttributes; } /** * Return the sequence of choices - the array elements will either be of * type Attribute[] or AttributeCertificate depending on what tag was used. * * @return array of choices. */ public Object[] getValues() { return values; } /** * *
         *  SignerAttribute ::= SEQUENCE OF CHOICE {
         *      claimedAttributes   [0] ClaimedAttributes,
         *      certifiedAttributes [1] CertifiedAttributes }
         *
         *  ClaimedAttributes ::= SEQUENCE OF Attribute
         *  CertifiedAttributes ::= AttributeCertificate -- as defined in RFC 3281: see clause 4.1.
         * 
    */ public ASN1Primitive toASN1Primitive() { ASN1EncodableVector v = new ASN1EncodableVector(); for (int i = 0; i != values.length; i++) { if (values[i] instanceof Attribute[]) { v.add(new DERTaggedObject(0, new DERSequence((Attribute[])values[i]))); } else { v.add(new DERTaggedObject(1, (AttributeCertificate)values[i])); } } return new DERSequence(v); } } bouncycastle-1.49.orig/src/org/bouncycastle/asn1/esf/CompleteRevocationRefs.java0000644000175000017500000000305111725271211027404 0ustar ebourgebourgpackage org.bouncycastle.asn1.esf; import java.util.Enumeration; import org.bouncycastle.asn1.ASN1Object; import org.bouncycastle.asn1.ASN1Primitive; import org.bouncycastle.asn1.ASN1Sequence; import org.bouncycastle.asn1.DERSequence; /** *
     * CompleteRevocationRefs ::= SEQUENCE OF CrlOcspRef
     * 
    */ public class CompleteRevocationRefs extends ASN1Object { private ASN1Sequence crlOcspRefs; public static CompleteRevocationRefs getInstance(Object obj) { if (obj instanceof CompleteRevocationRefs) { return (CompleteRevocationRefs)obj; } else if (obj != null) { return new CompleteRevocationRefs(ASN1Sequence.getInstance(obj)); } return null; } private CompleteRevocationRefs(ASN1Sequence seq) { Enumeration seqEnum = seq.getObjects(); while (seqEnum.hasMoreElements()) { CrlOcspRef.getInstance(seqEnum.nextElement()); } this.crlOcspRefs = seq; } public CompleteRevocationRefs(CrlOcspRef[] crlOcspRefs) { this.crlOcspRefs = new DERSequence(crlOcspRefs); } public CrlOcspRef[] getCrlOcspRefs() { CrlOcspRef[] result = new CrlOcspRef[this.crlOcspRefs.size()]; for (int idx = 0; idx < result.length; idx++) { result[idx] = CrlOcspRef.getInstance(this.crlOcspRefs .getObjectAt(idx)); } return result; } public ASN1Primitive toASN1Primitive() { return this.crlOcspRefs; } } bouncycastle-1.49.orig/src/org/bouncycastle/asn1/esf/RevocationValues.java0000644000175000017500000001100011725773522026260 0ustar ebourgebourgpackage org.bouncycastle.asn1.esf; import java.util.Enumeration; import org.bouncycastle.asn1.ASN1EncodableVector; import org.bouncycastle.asn1.ASN1Object; import org.bouncycastle.asn1.ASN1Primitive; import org.bouncycastle.asn1.ASN1Sequence; import org.bouncycastle.asn1.DERSequence; import org.bouncycastle.asn1.DERTaggedObject; import org.bouncycastle.asn1.ocsp.BasicOCSPResponse; import org.bouncycastle.asn1.x509.CertificateList; /** *
     * RevocationValues ::= SEQUENCE {
     *    crlVals [0] SEQUENCE OF CertificateList OPTIONAL,
     *    ocspVals [1] SEQUENCE OF BasicOCSPResponse OPTIONAL,
     *    otherRevVals [2] OtherRevVals OPTIONAL}
     * 
    */ public class RevocationValues extends ASN1Object { private ASN1Sequence crlVals; private ASN1Sequence ocspVals; private OtherRevVals otherRevVals; public static RevocationValues getInstance(Object obj) { if (obj instanceof RevocationValues) { return (RevocationValues)obj; } else if (obj != null) { return new RevocationValues(ASN1Sequence.getInstance(obj)); } return null; } private RevocationValues(ASN1Sequence seq) { if (seq.size() > 3) { throw new IllegalArgumentException("Bad sequence size: " + seq.size()); } Enumeration e = seq.getObjects(); while (e.hasMoreElements()) { DERTaggedObject o = (DERTaggedObject)e.nextElement(); switch (o.getTagNo()) { case 0: ASN1Sequence crlValsSeq = (ASN1Sequence)o.getObject(); Enumeration crlValsEnum = crlValsSeq.getObjects(); while (crlValsEnum.hasMoreElements()) { CertificateList.getInstance(crlValsEnum.nextElement()); } this.crlVals = crlValsSeq; break; case 1: ASN1Sequence ocspValsSeq = (ASN1Sequence)o.getObject(); Enumeration ocspValsEnum = ocspValsSeq.getObjects(); while (ocspValsEnum.hasMoreElements()) { BasicOCSPResponse.getInstance(ocspValsEnum.nextElement()); } this.ocspVals = ocspValsSeq; break; case 2: this.otherRevVals = OtherRevVals.getInstance(o.getObject()); break; default: throw new IllegalArgumentException("invalid tag: " + o.getTagNo()); } } } public RevocationValues(CertificateList[] crlVals, BasicOCSPResponse[] ocspVals, OtherRevVals otherRevVals) { if (null != crlVals) { this.crlVals = new DERSequence(crlVals); } if (null != ocspVals) { this.ocspVals = new DERSequence(ocspVals); } this.otherRevVals = otherRevVals; } public CertificateList[] getCrlVals() { if (null == this.crlVals) { return new CertificateList[0]; } CertificateList[] result = new CertificateList[this.crlVals.size()]; for (int idx = 0; idx < result.length; idx++) { result[idx] = CertificateList.getInstance(this.crlVals .getObjectAt(idx)); } return result; } public BasicOCSPResponse[] getOcspVals() { if (null == this.ocspVals) { return new BasicOCSPResponse[0]; } BasicOCSPResponse[] result = new BasicOCSPResponse[this.ocspVals.size()]; for (int idx = 0; idx < result.length; idx++) { result[idx] = BasicOCSPResponse.getInstance(this.ocspVals .getObjectAt(idx)); } return result; } public OtherRevVals getOtherRevVals() { return this.otherRevVals; } public ASN1Primitive toASN1Primitive() { ASN1EncodableVector v = new ASN1EncodableVector(); if (null != this.crlVals) { v.add(new DERTaggedObject(true, 0, this.crlVals)); } if (null != this.ocspVals) { v.add(new DERTaggedObject(true, 1, this.ocspVals)); } if (null != this.otherRevVals) { v.add(new DERTaggedObject(true, 2, this.otherRevVals.toASN1Primitive())); } return new DERSequence(v); } } bouncycastle-1.49.orig/src/org/bouncycastle/asn1/esf/CrlOcspRef.java0000644000175000017500000000523411725271264025001 0ustar ebourgebourgpackage org.bouncycastle.asn1.esf; import java.util.Enumeration; import org.bouncycastle.asn1.ASN1EncodableVector; import org.bouncycastle.asn1.ASN1Object; import org.bouncycastle.asn1.ASN1Primitive; import org.bouncycastle.asn1.ASN1Sequence; import org.bouncycastle.asn1.DERSequence; import org.bouncycastle.asn1.DERTaggedObject; /** *
     * CrlOcspRef ::= SEQUENCE {
     *     crlids [0] CRLListID OPTIONAL,
     *     ocspids [1] OcspListID OPTIONAL,
     *     otherRev [2] OtherRevRefs OPTIONAL
     * }
     * 
    */ public class CrlOcspRef extends ASN1Object { private CrlListID crlids; private OcspListID ocspids; private OtherRevRefs otherRev; public static CrlOcspRef getInstance(Object obj) { if (obj instanceof CrlOcspRef) { return (CrlOcspRef)obj; } else if (obj != null) { return new CrlOcspRef(ASN1Sequence.getInstance(obj)); } return null; } private CrlOcspRef(ASN1Sequence seq) { Enumeration e = seq.getObjects(); while (e.hasMoreElements()) { DERTaggedObject o = (DERTaggedObject)e.nextElement(); switch (o.getTagNo()) { case 0: this.crlids = CrlListID.getInstance(o.getObject()); break; case 1: this.ocspids = OcspListID.getInstance(o.getObject()); break; case 2: this.otherRev = OtherRevRefs.getInstance(o.getObject()); break; default: throw new IllegalArgumentException("illegal tag"); } } } public CrlOcspRef(CrlListID crlids, OcspListID ocspids, OtherRevRefs otherRev) { this.crlids = crlids; this.ocspids = ocspids; this.otherRev = otherRev; } public CrlListID getCrlids() { return this.crlids; } public OcspListID getOcspids() { return this.ocspids; } public OtherRevRefs getOtherRev() { return this.otherRev; } public ASN1Primitive toASN1Primitive() { ASN1EncodableVector v = new ASN1EncodableVector(); if (null != this.crlids) { v.add(new DERTaggedObject(true, 0, this.crlids.toASN1Primitive())); } if (null != this.ocspids) { v.add(new DERTaggedObject(true, 1, this.ocspids.toASN1Primitive())); } if (null != this.otherRev) { v.add(new DERTaggedObject(true, 2, this.otherRev.toASN1Primitive())); } return new DERSequence(v); } } bouncycastle-1.49.orig/src/org/bouncycastle/asn1/esf/CommitmentTypeIdentifier.java0000644000175000017500000000153311624622714027754 0ustar ebourgebourgpackage org.bouncycastle.asn1.esf; import org.bouncycastle.asn1.ASN1ObjectIdentifier; import org.bouncycastle.asn1.pkcs.PKCSObjectIdentifiers; public interface CommitmentTypeIdentifier { public static final ASN1ObjectIdentifier proofOfOrigin = PKCSObjectIdentifiers.id_cti_ets_proofOfOrigin; public static final ASN1ObjectIdentifier proofOfReceipt = PKCSObjectIdentifiers.id_cti_ets_proofOfReceipt; public static final ASN1ObjectIdentifier proofOfDelivery = PKCSObjectIdentifiers.id_cti_ets_proofOfDelivery; public static final ASN1ObjectIdentifier proofOfSender = PKCSObjectIdentifiers.id_cti_ets_proofOfSender; public static final ASN1ObjectIdentifier proofOfApproval = PKCSObjectIdentifiers.id_cti_ets_proofOfApproval; public static final ASN1ObjectIdentifier proofOfCreation = PKCSObjectIdentifiers.id_cti_ets_proofOfCreation; } bouncycastle-1.49.orig/src/org/bouncycastle/asn1/esf/ESFAttributes.java0000644000175000017500000000327011624622714025457 0ustar ebourgebourgpackage org.bouncycastle.asn1.esf; import org.bouncycastle.asn1.ASN1ObjectIdentifier; import org.bouncycastle.asn1.pkcs.PKCSObjectIdentifiers; public interface ESFAttributes { public static final ASN1ObjectIdentifier sigPolicyId = PKCSObjectIdentifiers.id_aa_ets_sigPolicyId; public static final ASN1ObjectIdentifier commitmentType = PKCSObjectIdentifiers.id_aa_ets_commitmentType; public static final ASN1ObjectIdentifier signerLocation = PKCSObjectIdentifiers.id_aa_ets_signerLocation; public static final ASN1ObjectIdentifier signerAttr = PKCSObjectIdentifiers.id_aa_ets_signerAttr; public static final ASN1ObjectIdentifier otherSigCert = PKCSObjectIdentifiers.id_aa_ets_otherSigCert; public static final ASN1ObjectIdentifier contentTimestamp = PKCSObjectIdentifiers.id_aa_ets_contentTimestamp; public static final ASN1ObjectIdentifier certificateRefs = PKCSObjectIdentifiers.id_aa_ets_certificateRefs; public static final ASN1ObjectIdentifier revocationRefs = PKCSObjectIdentifiers.id_aa_ets_revocationRefs; public static final ASN1ObjectIdentifier certValues = PKCSObjectIdentifiers.id_aa_ets_certValues; public static final ASN1ObjectIdentifier revocationValues = PKCSObjectIdentifiers.id_aa_ets_revocationValues; public static final ASN1ObjectIdentifier escTimeStamp = PKCSObjectIdentifiers.id_aa_ets_escTimeStamp; public static final ASN1ObjectIdentifier certCRLTimestamp = PKCSObjectIdentifiers.id_aa_ets_certCRLTimestamp; public static final ASN1ObjectIdentifier archiveTimestamp = PKCSObjectIdentifiers.id_aa_ets_archiveTimestamp; public static final ASN1ObjectIdentifier archiveTimestampV2 = PKCSObjectIdentifiers.id_aa.branch("48"); } bouncycastle-1.49.orig/src/org/bouncycastle/asn1/esf/OcspResponsesID.java0000644000175000017500000000374711725271352026027 0ustar ebourgebourgpackage org.bouncycastle.asn1.esf; import org.bouncycastle.asn1.ASN1EncodableVector; import org.bouncycastle.asn1.ASN1Object; import org.bouncycastle.asn1.ASN1Primitive; import org.bouncycastle.asn1.ASN1Sequence; import org.bouncycastle.asn1.DERSequence; /** *
     * OcspResponsesID ::= SEQUENCE {
     *    ocspIdentifier OcspIdentifier,
     *    ocspRepHash OtherHash OPTIONAL
     * }
     * 
    */ public class OcspResponsesID extends ASN1Object { private OcspIdentifier ocspIdentifier; private OtherHash ocspRepHash; public static OcspResponsesID getInstance(Object obj) { if (obj instanceof OcspResponsesID) { return (OcspResponsesID)obj; } else if (obj != null) { return new OcspResponsesID(ASN1Sequence.getInstance(obj)); } return null; } private OcspResponsesID(ASN1Sequence seq) { if (seq.size() < 1 || seq.size() > 2) { throw new IllegalArgumentException("Bad sequence size: " + seq.size()); } this.ocspIdentifier = OcspIdentifier.getInstance(seq.getObjectAt(0)); if (seq.size() > 1) { this.ocspRepHash = OtherHash.getInstance(seq.getObjectAt(1)); } } public OcspResponsesID(OcspIdentifier ocspIdentifier) { this(ocspIdentifier, null); } public OcspResponsesID(OcspIdentifier ocspIdentifier, OtherHash ocspRepHash) { this.ocspIdentifier = ocspIdentifier; this.ocspRepHash = ocspRepHash; } public OcspIdentifier getOcspIdentifier() { return this.ocspIdentifier; } public OtherHash getOcspRepHash() { return this.ocspRepHash; } public ASN1Primitive toASN1Primitive() { ASN1EncodableVector v = new ASN1EncodableVector(); v.add(this.ocspIdentifier); if (null != this.ocspRepHash) { v.add(this.ocspRepHash); } return new DERSequence(v); } } bouncycastle-1.49.orig/src/org/bouncycastle/asn1/esf/SignaturePolicyId.java0000644000175000017500000000532111725547650026377 0ustar ebourgebourgpackage org.bouncycastle.asn1.esf; import org.bouncycastle.asn1.ASN1EncodableVector; import org.bouncycastle.asn1.ASN1Object; import org.bouncycastle.asn1.ASN1ObjectIdentifier; import org.bouncycastle.asn1.ASN1Primitive; import org.bouncycastle.asn1.ASN1Sequence; import org.bouncycastle.asn1.DERSequence; public class SignaturePolicyId extends ASN1Object { private ASN1ObjectIdentifier sigPolicyId; private OtherHashAlgAndValue sigPolicyHash; private SigPolicyQualifiers sigPolicyQualifiers; public static SignaturePolicyId getInstance( Object obj) { if (obj instanceof SignaturePolicyId) { return (SignaturePolicyId)obj; } else if (obj != null) { return new SignaturePolicyId(ASN1Sequence.getInstance(obj)); } return null; } private SignaturePolicyId( ASN1Sequence seq) { if (seq.size() != 2 && seq.size() != 3) { throw new IllegalArgumentException("Bad sequence size: " + seq.size()); } sigPolicyId = ASN1ObjectIdentifier.getInstance(seq.getObjectAt(0)); sigPolicyHash = OtherHashAlgAndValue.getInstance(seq.getObjectAt(1)); if (seq.size() == 3) { sigPolicyQualifiers = SigPolicyQualifiers.getInstance(seq.getObjectAt(2)); } } public SignaturePolicyId( ASN1ObjectIdentifier sigPolicyIdentifier, OtherHashAlgAndValue sigPolicyHash) { this(sigPolicyIdentifier, sigPolicyHash, null); } public SignaturePolicyId( ASN1ObjectIdentifier sigPolicyId, OtherHashAlgAndValue sigPolicyHash, SigPolicyQualifiers sigPolicyQualifiers) { this.sigPolicyId = sigPolicyId; this.sigPolicyHash = sigPolicyHash; this.sigPolicyQualifiers = sigPolicyQualifiers; } public ASN1ObjectIdentifier getSigPolicyId() { return new ASN1ObjectIdentifier(sigPolicyId.getId()); } public OtherHashAlgAndValue getSigPolicyHash() { return sigPolicyHash; } public SigPolicyQualifiers getSigPolicyQualifiers() { return sigPolicyQualifiers; } /** *
         * SignaturePolicyId ::= SEQUENCE {
         *     sigPolicyId SigPolicyId,
         *     sigPolicyHash SigPolicyHash,
         *     sigPolicyQualifiers SEQUENCE SIZE (1..MAX) OF SigPolicyQualifierInfo OPTIONAL}
         * 
    */ public ASN1Primitive toASN1Primitive() { ASN1EncodableVector v = new ASN1EncodableVector(); v.add(sigPolicyId); v.add(sigPolicyHash); if (sigPolicyQualifiers != null) { v.add(sigPolicyQualifiers); } return new DERSequence(v); } } bouncycastle-1.49.orig/src/org/bouncycastle/asn1/esf/CrlValidatedID.java0000644000175000017500000000367211725271301025546 0ustar ebourgebourgpackage org.bouncycastle.asn1.esf; import org.bouncycastle.asn1.ASN1EncodableVector; import org.bouncycastle.asn1.ASN1Object; import org.bouncycastle.asn1.ASN1Primitive; import org.bouncycastle.asn1.ASN1Sequence; import org.bouncycastle.asn1.DERSequence; /** *
     * CrlValidatedID ::= SEQUENCE {
     *   crlHash OtherHash,
     *   crlIdentifier CrlIdentifier OPTIONAL }
     * 
    */ public class CrlValidatedID extends ASN1Object { private OtherHash crlHash; private CrlIdentifier crlIdentifier; public static CrlValidatedID getInstance(Object obj) { if (obj instanceof CrlValidatedID) { return (CrlValidatedID)obj; } else if (obj != null) { return new CrlValidatedID(ASN1Sequence.getInstance(obj)); } return null; } private CrlValidatedID(ASN1Sequence seq) { if (seq.size() < 1 || seq.size() > 2) { throw new IllegalArgumentException("Bad sequence size: " + seq.size()); } this.crlHash = OtherHash.getInstance(seq.getObjectAt(0)); if (seq.size() > 1) { this.crlIdentifier = CrlIdentifier.getInstance(seq.getObjectAt(1)); } } public CrlValidatedID(OtherHash crlHash) { this(crlHash, null); } public CrlValidatedID(OtherHash crlHash, CrlIdentifier crlIdentifier) { this.crlHash = crlHash; this.crlIdentifier = crlIdentifier; } public OtherHash getCrlHash() { return this.crlHash; } public CrlIdentifier getCrlIdentifier() { return this.crlIdentifier; } public ASN1Primitive toASN1Primitive() { ASN1EncodableVector v = new ASN1EncodableVector(); v.add(this.crlHash.toASN1Primitive()); if (null != this.crlIdentifier) { v.add(this.crlIdentifier.toASN1Primitive()); } return new DERSequence(v); } } bouncycastle-1.49.orig/src/org/bouncycastle/asn1/esf/OcspListID.java0000644000175000017500000000336011725271335024751 0ustar ebourgebourgpackage org.bouncycastle.asn1.esf; import java.util.Enumeration; import org.bouncycastle.asn1.ASN1Object; import org.bouncycastle.asn1.ASN1Primitive; import org.bouncycastle.asn1.ASN1Sequence; import org.bouncycastle.asn1.DERSequence; /** *
     * OcspListID ::=  SEQUENCE {
     *    ocspResponses  SEQUENCE OF OcspResponsesID
     * }
     * 
    */ public class OcspListID extends ASN1Object { private ASN1Sequence ocspResponses; public static OcspListID getInstance(Object obj) { if (obj instanceof OcspListID) { return (OcspListID)obj; } else if (obj != null) { return new OcspListID(ASN1Sequence.getInstance(obj)); } return null; } private OcspListID(ASN1Sequence seq) { if (seq.size() != 1) { throw new IllegalArgumentException("Bad sequence size: " + seq.size()); } this.ocspResponses = (ASN1Sequence)seq.getObjectAt(0); Enumeration e = this.ocspResponses.getObjects(); while (e.hasMoreElements()) { OcspResponsesID.getInstance(e.nextElement()); } } public OcspListID(OcspResponsesID[] ocspResponses) { this.ocspResponses = new DERSequence(ocspResponses); } public OcspResponsesID[] getOcspResponses() { OcspResponsesID[] result = new OcspResponsesID[this.ocspResponses .size()]; for (int idx = 0; idx < result.length; idx++) { result[idx] = OcspResponsesID.getInstance(this.ocspResponses .getObjectAt(idx)); } return result; } public ASN1Primitive toASN1Primitive() { return new DERSequence(this.ocspResponses); } } bouncycastle-1.49.orig/src/org/bouncycastle/asn1/esf/CommitmentTypeIndication.java0000644000175000017500000000432711725567234027766 0ustar ebourgebourgpackage org.bouncycastle.asn1.esf; import org.bouncycastle.asn1.ASN1EncodableVector; import org.bouncycastle.asn1.ASN1Object; import org.bouncycastle.asn1.ASN1ObjectIdentifier; import org.bouncycastle.asn1.ASN1Primitive; import org.bouncycastle.asn1.ASN1Sequence; import org.bouncycastle.asn1.DERSequence; public class CommitmentTypeIndication extends ASN1Object { private ASN1ObjectIdentifier commitmentTypeId; private ASN1Sequence commitmentTypeQualifier; private CommitmentTypeIndication( ASN1Sequence seq) { commitmentTypeId = (ASN1ObjectIdentifier)seq.getObjectAt(0); if (seq.size() > 1) { commitmentTypeQualifier = (ASN1Sequence)seq.getObjectAt(1); } } public CommitmentTypeIndication( ASN1ObjectIdentifier commitmentTypeId) { this.commitmentTypeId = commitmentTypeId; } public CommitmentTypeIndication( ASN1ObjectIdentifier commitmentTypeId, ASN1Sequence commitmentTypeQualifier) { this.commitmentTypeId = commitmentTypeId; this.commitmentTypeQualifier = commitmentTypeQualifier; } public static CommitmentTypeIndication getInstance( Object obj) { if (obj == null || obj instanceof CommitmentTypeIndication) { return (CommitmentTypeIndication)obj; } return new CommitmentTypeIndication(ASN1Sequence.getInstance(obj)); } public ASN1ObjectIdentifier getCommitmentTypeId() { return commitmentTypeId; } public ASN1Sequence getCommitmentTypeQualifier() { return commitmentTypeQualifier; } /** *
         * CommitmentTypeIndication ::= SEQUENCE {
         *      commitmentTypeId   CommitmentTypeIdentifier,
         *      commitmentTypeQualifier   SEQUENCE SIZE (1..MAX) OF
         *              CommitmentTypeQualifier OPTIONAL }
         * 
    */ public ASN1Primitive toASN1Primitive() { ASN1EncodableVector v = new ASN1EncodableVector(); v.add(commitmentTypeId); if (commitmentTypeQualifier != null) { v.add(commitmentTypeQualifier); } return new DERSequence(v); } } bouncycastle-1.49.orig/src/org/bouncycastle/asn1/esf/OtherHash.java0000644000175000017500000000366511624652552024673 0ustar ebourgebourgpackage org.bouncycastle.asn1.esf; import org.bouncycastle.asn1.ASN1Choice; import org.bouncycastle.asn1.ASN1Object; import org.bouncycastle.asn1.ASN1OctetString; import org.bouncycastle.asn1.ASN1Primitive; import org.bouncycastle.asn1.DEROctetString; import org.bouncycastle.asn1.oiw.OIWObjectIdentifiers; import org.bouncycastle.asn1.x509.AlgorithmIdentifier; /** *
     * OtherHash ::= CHOICE {
     *    sha1Hash  OtherHashValue, -- This contains a SHA-1 hash
     *   otherHash  OtherHashAlgAndValue
     *  }
     * 
    */ public class OtherHash extends ASN1Object implements ASN1Choice { private ASN1OctetString sha1Hash; private OtherHashAlgAndValue otherHash; public static OtherHash getInstance(Object obj) { if (obj instanceof OtherHash) { return (OtherHash)obj; } if (obj instanceof ASN1OctetString) { return new OtherHash((ASN1OctetString)obj); } return new OtherHash(OtherHashAlgAndValue.getInstance(obj)); } private OtherHash(ASN1OctetString sha1Hash) { this.sha1Hash = sha1Hash; } public OtherHash(OtherHashAlgAndValue otherHash) { this.otherHash = otherHash; } public OtherHash(byte[] sha1Hash) { this.sha1Hash = new DEROctetString(sha1Hash); } public AlgorithmIdentifier getHashAlgorithm() { if (null == this.otherHash) { return new AlgorithmIdentifier(OIWObjectIdentifiers.idSHA1); } return this.otherHash.getHashAlgorithm(); } public byte[] getHashValue() { if (null == this.otherHash) { return this.sha1Hash.getOctets(); } return this.otherHash.getHashValue().getOctets(); } public ASN1Primitive toASN1Primitive() { if (null == this.otherHash) { return this.sha1Hash; } return this.otherHash.toASN1Primitive(); } } bouncycastle-1.49.orig/src/org/bouncycastle/asn1/esf/SignerLocation.java0000644000175000017500000001152011725566174025721 0ustar ebourgebourgpackage org.bouncycastle.asn1.esf; import java.util.Enumeration; import org.bouncycastle.asn1.ASN1EncodableVector; import org.bouncycastle.asn1.ASN1Object; import org.bouncycastle.asn1.ASN1Primitive; import org.bouncycastle.asn1.ASN1Sequence; import org.bouncycastle.asn1.DERSequence; import org.bouncycastle.asn1.DERTaggedObject; import org.bouncycastle.asn1.DERUTF8String; import org.bouncycastle.asn1.x500.DirectoryString; /** * Signer-Location attribute (RFC3126). * *
     *   SignerLocation ::= SEQUENCE {
     *       countryName        [0] DirectoryString OPTIONAL,
     *       localityName       [1] DirectoryString OPTIONAL,
     *       postalAddress      [2] PostalAddress OPTIONAL }
     *
     *   PostalAddress ::= SEQUENCE SIZE(1..6) OF DirectoryString
     * 
    */ public class SignerLocation extends ASN1Object { private DERUTF8String countryName; private DERUTF8String localityName; private ASN1Sequence postalAddress; private SignerLocation( ASN1Sequence seq) { Enumeration e = seq.getObjects(); while (e.hasMoreElements()) { DERTaggedObject o = (DERTaggedObject)e.nextElement(); switch (o.getTagNo()) { case 0: DirectoryString countryNameDirectoryString = DirectoryString.getInstance(o, true); this.countryName = new DERUTF8String(countryNameDirectoryString.getString()); break; case 1: DirectoryString localityNameDirectoryString = DirectoryString.getInstance(o, true); this.localityName = new DERUTF8String(localityNameDirectoryString.getString()); break; case 2: if (o.isExplicit()) { this.postalAddress = ASN1Sequence.getInstance(o, true); } else // handle erroneous implicitly tagged sequences { this.postalAddress = ASN1Sequence.getInstance(o, false); } if (postalAddress != null && postalAddress.size() > 6) { throw new IllegalArgumentException("postal address must contain less than 6 strings"); } break; default: throw new IllegalArgumentException("illegal tag"); } } } public SignerLocation( DERUTF8String countryName, DERUTF8String localityName, ASN1Sequence postalAddress) { if (postalAddress != null && postalAddress.size() > 6) { throw new IllegalArgumentException("postal address must contain less than 6 strings"); } if (countryName != null) { this.countryName = DERUTF8String.getInstance(countryName.toASN1Primitive()); } if (localityName != null) { this.localityName = DERUTF8String.getInstance(localityName.toASN1Primitive()); } if (postalAddress != null) { this.postalAddress = ASN1Sequence.getInstance(postalAddress.toASN1Primitive()); } } public static SignerLocation getInstance( Object obj) { if (obj == null || obj instanceof SignerLocation) { return (SignerLocation)obj; } return new SignerLocation(ASN1Sequence.getInstance(obj)); } public DERUTF8String getCountryName() { return countryName; } public DERUTF8String getLocalityName() { return localityName; } public ASN1Sequence getPostalAddress() { return postalAddress; } /** *
         *   SignerLocation ::= SEQUENCE {
         *       countryName        [0] DirectoryString OPTIONAL,
         *       localityName       [1] DirectoryString OPTIONAL,
         *       postalAddress      [2] PostalAddress OPTIONAL }
         *
         *   PostalAddress ::= SEQUENCE SIZE(1..6) OF DirectoryString
         *   
         *   DirectoryString ::= CHOICE {
         *         teletexString           TeletexString (SIZE (1..MAX)),
         *         printableString         PrintableString (SIZE (1..MAX)),
         *         universalString         UniversalString (SIZE (1..MAX)),
         *         utf8String              UTF8String (SIZE (1.. MAX)),
         *         bmpString               BMPString (SIZE (1..MAX)) }
         * 
    */ public ASN1Primitive toASN1Primitive() { ASN1EncodableVector v = new ASN1EncodableVector(); if (countryName != null) { v.add(new DERTaggedObject(true, 0, countryName)); } if (localityName != null) { v.add(new DERTaggedObject(true, 1, localityName)); } if (postalAddress != null) { v.add(new DERTaggedObject(true, 2, postalAddress)); } return new DERSequence(v); } } bouncycastle-1.49.orig/src/org/bouncycastle/asn1/esf/SigPolicyQualifierInfo.java0000644000175000017500000000375611725566617027377 0ustar ebourgebourgpackage org.bouncycastle.asn1.esf; import org.bouncycastle.asn1.ASN1Encodable; import org.bouncycastle.asn1.ASN1EncodableVector; import org.bouncycastle.asn1.ASN1Object; import org.bouncycastle.asn1.ASN1ObjectIdentifier; import org.bouncycastle.asn1.ASN1Primitive; import org.bouncycastle.asn1.ASN1Sequence; import org.bouncycastle.asn1.DERSequence; public class SigPolicyQualifierInfo extends ASN1Object { private ASN1ObjectIdentifier sigPolicyQualifierId; private ASN1Encodable sigQualifier; public SigPolicyQualifierInfo( ASN1ObjectIdentifier sigPolicyQualifierId, ASN1Encodable sigQualifier) { this.sigPolicyQualifierId = sigPolicyQualifierId; this.sigQualifier = sigQualifier; } private SigPolicyQualifierInfo( ASN1Sequence seq) { sigPolicyQualifierId = ASN1ObjectIdentifier.getInstance(seq.getObjectAt(0)); sigQualifier = seq.getObjectAt(1); } public static SigPolicyQualifierInfo getInstance( Object obj) { if (obj instanceof SigPolicyQualifierInfo) { return (SigPolicyQualifierInfo) obj; } else if (obj != null) { return new SigPolicyQualifierInfo(ASN1Sequence.getInstance(obj)); } return null; } public ASN1ObjectIdentifier getSigPolicyQualifierId() { return new ASN1ObjectIdentifier(sigPolicyQualifierId.getId()); } public ASN1Encodable getSigQualifier() { return sigQualifier; } /** *
         * SigPolicyQualifierInfo ::= SEQUENCE {
         *    sigPolicyQualifierId SigPolicyQualifierId,
         *    sigQualifier ANY DEFINED BY sigPolicyQualifierId }
         *
         * SigPolicyQualifierId ::= OBJECT IDENTIFIER
         * 
    */ public ASN1Primitive toASN1Primitive() { ASN1EncodableVector v = new ASN1EncodableVector(); v.add(sigPolicyQualifierId); v.add(sigQualifier); return new DERSequence(v); } } bouncycastle-1.49.orig/src/org/bouncycastle/asn1/esf/OtherRevVals.java0000644000175000017500000000431211725543560025360 0ustar ebourgebourgpackage org.bouncycastle.asn1.esf; import java.io.IOException; import org.bouncycastle.asn1.ASN1Encodable; import org.bouncycastle.asn1.ASN1EncodableVector; import org.bouncycastle.asn1.ASN1Encoding; import org.bouncycastle.asn1.ASN1Object; import org.bouncycastle.asn1.ASN1ObjectIdentifier; import org.bouncycastle.asn1.ASN1Primitive; import org.bouncycastle.asn1.ASN1Sequence; import org.bouncycastle.asn1.DERSequence; /** *
     * OtherRevVals ::= SEQUENCE {
     *    otherRevValType OtherRevValType,
     *    otherRevVals ANY DEFINED BY OtherRevValType
     * }
     *
     * OtherRevValType ::= OBJECT IDENTIFIER
     * 
    */ public class OtherRevVals extends ASN1Object { private ASN1ObjectIdentifier otherRevValType; private ASN1Encodable otherRevVals; public static OtherRevVals getInstance(Object obj) { if (obj instanceof OtherRevVals) { return (OtherRevVals)obj; } if (obj != null) { return new OtherRevVals(ASN1Sequence.getInstance(obj)); } return null; } private OtherRevVals(ASN1Sequence seq) { if (seq.size() != 2) { throw new IllegalArgumentException("Bad sequence size: " + seq.size()); } this.otherRevValType = (ASN1ObjectIdentifier)seq.getObjectAt(0); try { this.otherRevVals = ASN1Primitive.fromByteArray(seq.getObjectAt(1) .toASN1Primitive().getEncoded(ASN1Encoding.DER)); } catch (IOException e) { throw new IllegalStateException(); } } public OtherRevVals(ASN1ObjectIdentifier otherRevValType, ASN1Encodable otherRevVals) { this.otherRevValType = otherRevValType; this.otherRevVals = otherRevVals; } public ASN1ObjectIdentifier getOtherRevValType() { return this.otherRevValType; } public ASN1Encodable getOtherRevVals() { return this.otherRevVals; } public ASN1Primitive toASN1Primitive() { ASN1EncodableVector v = new ASN1EncodableVector(); v.add(this.otherRevValType); v.add(this.otherRevVals); return new DERSequence(v); } } bouncycastle-1.49.orig/src/org/bouncycastle/asn1/esf/CrlIdentifier.java0000644000175000017500000000504611737275254025531 0ustar ebourgebourgpackage org.bouncycastle.asn1.esf; import java.math.BigInteger; import org.bouncycastle.asn1.ASN1EncodableVector; import org.bouncycastle.asn1.ASN1Integer; import org.bouncycastle.asn1.ASN1Object; import org.bouncycastle.asn1.ASN1Primitive; import org.bouncycastle.asn1.ASN1Sequence; import org.bouncycastle.asn1.ASN1UTCTime; import org.bouncycastle.asn1.DERSequence; import org.bouncycastle.asn1.x500.X500Name; /** *
     *  CrlIdentifier ::= SEQUENCE 
     * {
     *   crlissuer    Name,
     *   crlIssuedTime  UTCTime,
     *   crlNumber    INTEGER OPTIONAL
     * }
     * 
    */ public class CrlIdentifier extends ASN1Object { private X500Name crlIssuer; private ASN1UTCTime crlIssuedTime; private ASN1Integer crlNumber; public static CrlIdentifier getInstance(Object obj) { if (obj instanceof CrlIdentifier) { return (CrlIdentifier)obj; } else if (obj != null) { return new CrlIdentifier(ASN1Sequence.getInstance(obj)); } return null; } private CrlIdentifier(ASN1Sequence seq) { if (seq.size() < 2 || seq.size() > 3) { throw new IllegalArgumentException(); } this.crlIssuer = X500Name.getInstance(seq.getObjectAt(0)); this.crlIssuedTime = ASN1UTCTime.getInstance(seq.getObjectAt(1)); if (seq.size() > 2) { this.crlNumber = ASN1Integer.getInstance(seq.getObjectAt(2)); } } public CrlIdentifier(X500Name crlIssuer, ASN1UTCTime crlIssuedTime) { this(crlIssuer, crlIssuedTime, null); } public CrlIdentifier(X500Name crlIssuer, ASN1UTCTime crlIssuedTime, BigInteger crlNumber) { this.crlIssuer = crlIssuer; this.crlIssuedTime = crlIssuedTime; if (null != crlNumber) { this.crlNumber = new ASN1Integer(crlNumber); } } public X500Name getCrlIssuer() { return this.crlIssuer; } public ASN1UTCTime getCrlIssuedTime() { return this.crlIssuedTime; } public BigInteger getCrlNumber() { if (null == this.crlNumber) { return null; } return this.crlNumber.getValue(); } public ASN1Primitive toASN1Primitive() { ASN1EncodableVector v = new ASN1EncodableVector(); v.add(this.crlIssuer.toASN1Primitive()); v.add(this.crlIssuedTime); if (null != this.crlNumber) { v.add(this.crlNumber); } return new DERSequence(v); } } bouncycastle-1.49.orig/src/org/bouncycastle/asn1/esf/OtherHashAlgAndValue.java0000644000175000017500000000374211725271367026736 0ustar ebourgebourgpackage org.bouncycastle.asn1.esf; import org.bouncycastle.asn1.ASN1EncodableVector; import org.bouncycastle.asn1.ASN1Object; import org.bouncycastle.asn1.ASN1OctetString; import org.bouncycastle.asn1.ASN1Primitive; import org.bouncycastle.asn1.ASN1Sequence; import org.bouncycastle.asn1.DERSequence; import org.bouncycastle.asn1.x509.AlgorithmIdentifier; public class OtherHashAlgAndValue extends ASN1Object { private AlgorithmIdentifier hashAlgorithm; private ASN1OctetString hashValue; public static OtherHashAlgAndValue getInstance( Object obj) { if (obj instanceof OtherHashAlgAndValue) { return (OtherHashAlgAndValue) obj; } else if (obj != null) { return new OtherHashAlgAndValue(ASN1Sequence.getInstance(obj)); } return null; } private OtherHashAlgAndValue( ASN1Sequence seq) { if (seq.size() != 2) { throw new IllegalArgumentException("Bad sequence size: " + seq.size()); } hashAlgorithm = AlgorithmIdentifier.getInstance(seq.getObjectAt(0)); hashValue = ASN1OctetString.getInstance(seq.getObjectAt(1)); } public OtherHashAlgAndValue( AlgorithmIdentifier hashAlgorithm, ASN1OctetString hashValue) { this.hashAlgorithm = hashAlgorithm; this.hashValue = hashValue; } public AlgorithmIdentifier getHashAlgorithm() { return hashAlgorithm; } public ASN1OctetString getHashValue() { return hashValue; } /** *
         * OtherHashAlgAndValue ::= SEQUENCE {
         *     hashAlgorithm AlgorithmIdentifier,
         *     hashValue OtherHashValue }
         *
         * OtherHashValue ::= OCTET STRING
         * 
    */ public ASN1Primitive toASN1Primitive() { ASN1EncodableVector v = new ASN1EncodableVector(); v.add(hashAlgorithm); v.add(hashValue); return new DERSequence(v); } } bouncycastle-1.49.orig/src/org/bouncycastle/asn1/esf/SigPolicyQualifiers.java0000644000175000017500000000343611725567005026731 0ustar ebourgebourgpackage org.bouncycastle.asn1.esf; import org.bouncycastle.asn1.ASN1EncodableVector; import org.bouncycastle.asn1.ASN1Object; import org.bouncycastle.asn1.ASN1Primitive; import org.bouncycastle.asn1.ASN1Sequence; import org.bouncycastle.asn1.DERSequence; public class SigPolicyQualifiers extends ASN1Object { ASN1Sequence qualifiers; public static SigPolicyQualifiers getInstance( Object obj) { if (obj instanceof SigPolicyQualifiers) { return (SigPolicyQualifiers) obj; } else if (obj instanceof ASN1Sequence) { return new SigPolicyQualifiers(ASN1Sequence.getInstance(obj)); } return null; } private SigPolicyQualifiers( ASN1Sequence seq) { qualifiers = seq; } public SigPolicyQualifiers( SigPolicyQualifierInfo[] qualifierInfos) { ASN1EncodableVector v = new ASN1EncodableVector(); for (int i=0; i < qualifierInfos.length; i++) { v.add(qualifierInfos[i]); } qualifiers = new DERSequence(v); } /** * Return the number of qualifier info elements present. * * @return number of elements present. */ public int size() { return qualifiers.size(); } /** * Return the SigPolicyQualifierInfo at index i. * * @param i index of the info of interest * @return the info at index i. */ public SigPolicyQualifierInfo getInfoAt( int i) { return SigPolicyQualifierInfo.getInstance(qualifiers.getObjectAt(i)); } /** *
         * SigPolicyQualifiers ::= SEQUENCE SIZE (1..MAX) OF SigPolicyQualifierInfo
         * 
    */ public ASN1Primitive toASN1Primitive() { return qualifiers; } } bouncycastle-1.49.orig/src/org/bouncycastle/asn1/esf/package.html0000644000175000017500000000026410262753174024413 0ustar ebourgebourg Support classes useful for encoding and supporting [ESF] RFC3126 Electronic Signature Formats for long term electronic signatures. bouncycastle-1.49.orig/src/org/bouncycastle/dvcs/0000755000175000017500000000000012152033551021436 5ustar ebourgebourgbouncycastle-1.49.orig/src/org/bouncycastle/dvcs/DVCSRequestData.java0000644000175000017500000000145012151253000025173 0ustar ebourgebourgpackage org.bouncycastle.dvcs; import org.bouncycastle.asn1.dvcs.Data; /** * Data piece of DVCRequest object (DVCS Data structure). * Its contents depend on the service type. * Its subclasses define the service-specific interface. *

    * The concrete objects of DVCRequestData are created by buildDVCRequestData static method. */ public abstract class DVCSRequestData { /** * The underlying data object is accessible by subclasses. */ protected Data data; /** * The constructor is accessible by subclasses. * * @param data */ protected DVCSRequestData(Data data) { this.data = data; } /** * Convert to ASN.1 structure (Data). * * @return */ public Data toASN1Structure() { return data; } } bouncycastle-1.49.orig/src/org/bouncycastle/dvcs/CPDRequestBuilder.java0000644000175000017500000000144312131665046025600 0ustar ebourgebourgpackage org.bouncycastle.dvcs; import java.io.IOException; import org.bouncycastle.asn1.dvcs.DVCSRequestInformationBuilder; import org.bouncycastle.asn1.dvcs.Data; import org.bouncycastle.asn1.dvcs.ServiceType; /** * Builder of DVCSRequests to CPD service (Certify Possession of Data). */ public class CPDRequestBuilder extends DVCSRequestBuilder { public CPDRequestBuilder() { super(new DVCSRequestInformationBuilder(ServiceType.CPD)); } /** * Build CPD request. * * @param messageBytes - data to be certified * @return * @throws DVCSException */ public DVCSRequest build(byte[] messageBytes) throws DVCSException, IOException { Data data = new Data(messageBytes); return createDVCRequest(data); } } bouncycastle-1.49.orig/src/org/bouncycastle/dvcs/DVCSException.java0000644000175000017500000000074712131665046024736 0ustar ebourgebourgpackage org.bouncycastle.dvcs; /** * General DVCSException. */ public class DVCSException extends Exception { private static final long serialVersionUID = 389345256020131488L; private Throwable cause; public DVCSException(String message) { super(message); } public DVCSException(String message, Throwable cause) { super(message); this.cause = cause; } public Throwable getCause() { return cause; } } bouncycastle-1.49.orig/src/org/bouncycastle/dvcs/MessageImprint.java0000644000175000017500000000131112151274314025227 0ustar ebourgebourgpackage org.bouncycastle.dvcs; import org.bouncycastle.asn1.x509.DigestInfo; public class MessageImprint { private final DigestInfo messageImprint; public MessageImprint(DigestInfo messageImprint) { this.messageImprint = messageImprint; } public DigestInfo toASN1Structure() { return messageImprint; } public boolean equals(Object o) { if (o == this) { return true; } if (o instanceof MessageImprint) { return messageImprint.equals(((MessageImprint)o).messageImprint); } return false; } public int hashCode() { return messageImprint.hashCode(); } } bouncycastle-1.49.orig/src/org/bouncycastle/dvcs/DVCSConstructionException.java0000644000175000017500000000070612131665046027344 0ustar ebourgebourgpackage org.bouncycastle.dvcs; /** * Exception thrown when failed to initialize some DVCS-related staff. */ public class DVCSConstructionException extends DVCSException { private static final long serialVersionUID = 660035299653583980L; public DVCSConstructionException(String message) { super(message); } public DVCSConstructionException(String message, Throwable cause) { super(message, cause); } } bouncycastle-1.49.orig/src/org/bouncycastle/dvcs/DVCSMessage.java0000644000175000017500000000100312131665046024346 0ustar ebourgebourgpackage org.bouncycastle.dvcs; import org.bouncycastle.asn1.ASN1Encodable; import org.bouncycastle.asn1.ASN1ObjectIdentifier; import org.bouncycastle.asn1.cms.ContentInfo; public abstract class DVCSMessage { private final ContentInfo contentInfo; protected DVCSMessage(ContentInfo contentInfo) { this.contentInfo = contentInfo; } public ASN1ObjectIdentifier getContentType() { return contentInfo.getContentType(); } public abstract ASN1Encodable getContent(); } bouncycastle-1.49.orig/src/org/bouncycastle/dvcs/DVCSResponse.java0000644000175000017500000000452112132366367024575 0ustar ebourgebourgpackage org.bouncycastle.dvcs; import org.bouncycastle.asn1.ASN1Encodable; import org.bouncycastle.asn1.ASN1OctetString; import org.bouncycastle.asn1.ASN1Sequence; import org.bouncycastle.asn1.cms.ContentInfo; import org.bouncycastle.asn1.cms.SignedData; import org.bouncycastle.asn1.dvcs.DVCSObjectIdentifiers; import org.bouncycastle.cms.CMSSignedData; /** * DVCResponse is general response to DVCS (RFC 3029). * It represents responses for all types of services. */ public class DVCSResponse extends DVCSMessage { private org.bouncycastle.asn1.dvcs.DVCSResponse asn1; /** * Constructs DVCRequest from CMS SignedData object. * * @param signedData the CMS SignedData object containing the request * @throws org.bouncycastle.dvcs.DVCSConstructionException */ public DVCSResponse(CMSSignedData signedData) throws DVCSConstructionException { this(SignedData.getInstance(signedData.toASN1Structure().getContent()).getEncapContentInfo()); } /** * Construct a DVCS Request from a ContentInfo * * @param contentInfo the contentInfo representing the DVCSRequest * @throws org.bouncycastle.dvcs.DVCSConstructionException */ public DVCSResponse(ContentInfo contentInfo) throws DVCSConstructionException { super(contentInfo); if (!DVCSObjectIdentifiers.id_ct_DVCSResponseData.equals(contentInfo.getContentType())) { throw new DVCSConstructionException("ContentInfo not a DVCS Request"); } try { if (contentInfo.getContent().toASN1Primitive() instanceof ASN1Sequence) { this.asn1 = org.bouncycastle.asn1.dvcs.DVCSResponse.getInstance(contentInfo.getContent()); } else { this.asn1 = org.bouncycastle.asn1.dvcs.DVCSResponse.getInstance(ASN1OctetString.getInstance(contentInfo.getContent()).getOctets()); } } catch (Exception e) { throw new DVCSConstructionException("Unable to parse content: " + e.getMessage(), e); } } /** * Return the ASN.1 DVCSResponse structure making up the body of this response. * * @return an org.bouncycastle.asn1.dvcs.DVCSResponse object. */ public ASN1Encodable getContent() { return asn1; } } bouncycastle-1.49.orig/src/org/bouncycastle/dvcs/MessageImprintBuilder.java0000644000175000017500000000161012131665046026544 0ustar ebourgebourgpackage org.bouncycastle.dvcs; import java.io.OutputStream; import org.bouncycastle.asn1.x509.DigestInfo; import org.bouncycastle.operator.DigestCalculator; public class MessageImprintBuilder { private final DigestCalculator digestCalculator; public MessageImprintBuilder(DigestCalculator digestCalculator) { this.digestCalculator = digestCalculator; } public MessageImprint build(byte[] message) throws DVCSException { try { OutputStream dOut = digestCalculator.getOutputStream(); dOut.write(message); dOut.close(); return new MessageImprint(new DigestInfo(digestCalculator.getAlgorithmIdentifier(), digestCalculator.getDigest())); } catch (Exception e) { throw new DVCSException("unable to build MessageImprint: " + e.getMessage(), e); } } } bouncycastle-1.49.orig/src/org/bouncycastle/dvcs/CCPDRequestData.java0000644000175000017500000000232112151253000025143 0ustar ebourgebourgpackage org.bouncycastle.dvcs; import org.bouncycastle.asn1.dvcs.Data; /** * Data piece of DVCRequest for CCPD service (Certify Claim of Possession of Data). * It contains CCPD-specific selector interface. *

    * This objects are constructed internally, * to build DVCS request to CCPD service use CCPDRequestBuilder. */ public class CCPDRequestData extends DVCSRequestData { /** * Construct from corresponding ASN.1 Data structure. * Note, that data should have messageImprint choice, * otherwise DVCSConstructionException is thrown. * * @param data * @throws DVCSConstructionException */ CCPDRequestData(Data data) throws DVCSConstructionException { super(data); initDigest(); } private void initDigest() throws DVCSConstructionException { if (data.getMessageImprint() == null) { throw new DVCSConstructionException("DVCSRequest.data.messageImprint should be specified for CCPD service"); } } /** * Get MessageImprint value * * @return */ public MessageImprint getMessageImprint() { return new MessageImprint(data.getMessageImprint()); } } bouncycastle-1.49.orig/src/org/bouncycastle/dvcs/CPDRequestData.java0000644000175000017500000000165712131665046025072 0ustar ebourgebourgpackage org.bouncycastle.dvcs; import org.bouncycastle.asn1.dvcs.Data; /** * Data piece of DVCRequest for CPD service (Certify Possession of Data). * It contains CPD-specific selector interface. *

    * This objects are constructed internally, * to build DVCS request to CPD service use CPDRequestBuilder. */ public class CPDRequestData extends DVCSRequestData { CPDRequestData(Data data) throws DVCSConstructionException { super(data); initMessage(); } private void initMessage() throws DVCSConstructionException { if (data.getMessage() == null) { throw new DVCSConstructionException("DVCSRequest.data.message should be specified for CPD service"); } } /** * Get contained message (data to be certified). * * @return */ public byte[] getMessage() { return data.getMessage().getOctets(); } } bouncycastle-1.49.orig/src/org/bouncycastle/dvcs/TargetChain.java0000644000175000017500000000047512131665046024507 0ustar ebourgebourgpackage org.bouncycastle.dvcs; import org.bouncycastle.asn1.dvcs.TargetEtcChain; public class TargetChain { private final TargetEtcChain certs; public TargetChain(TargetEtcChain certs) { this.certs = certs; } public TargetEtcChain toASN1Structure() { return certs; } } bouncycastle-1.49.orig/src/org/bouncycastle/dvcs/VSDRequestBuilder.java0000644000175000017500000000227512131665046025632 0ustar ebourgebourgpackage org.bouncycastle.dvcs; import java.io.IOException; import java.util.Date; import org.bouncycastle.asn1.dvcs.DVCSRequestInformationBuilder; import org.bouncycastle.asn1.dvcs.DVCSTime; import org.bouncycastle.asn1.dvcs.Data; import org.bouncycastle.asn1.dvcs.ServiceType; import org.bouncycastle.cms.CMSSignedData; /** * Builder of DVCS requests to VSD service (Verify Signed Document). */ public class VSDRequestBuilder extends DVCSRequestBuilder { public VSDRequestBuilder() { super(new DVCSRequestInformationBuilder(ServiceType.VSD)); } public void setRequestTime(Date requestTime) { requestInformationBuilder.setRequestTime(new DVCSTime(requestTime)); } /** * Build VSD request from CMS SignedData object. * * @param document * @return * @throws DVCSException */ public DVCSRequest build(CMSSignedData document) throws DVCSException { try { Data data = new Data(document.getEncoded()); return createDVCRequest(data); } catch (IOException e) { throw new DVCSException("Failed to encode CMS signed data", e); } } } bouncycastle-1.49.orig/src/org/bouncycastle/dvcs/DVCSRequest.java0000644000175000017500000000776312151274314024431 0ustar ebourgebourgpackage org.bouncycastle.dvcs; import org.bouncycastle.asn1.ASN1Encodable; import org.bouncycastle.asn1.ASN1OctetString; import org.bouncycastle.asn1.ASN1Sequence; import org.bouncycastle.asn1.cms.ContentInfo; import org.bouncycastle.asn1.cms.SignedData; import org.bouncycastle.asn1.dvcs.DVCSObjectIdentifiers; import org.bouncycastle.asn1.dvcs.ServiceType; import org.bouncycastle.asn1.x509.GeneralName; import org.bouncycastle.cms.CMSSignedData; /** * DVCRequest is general request to DVCS (RFC 3029). * It represents requests for all types of services. * Requests for different services differ in DVCData structure. */ public class DVCSRequest extends DVCSMessage { private org.bouncycastle.asn1.dvcs.DVCSRequest asn1; private DVCSRequestInfo reqInfo; private DVCSRequestData data; /** * Constructs DVCRequest from CMS SignedData object. * * @param signedData the CMS SignedData object containing the request * @throws DVCSConstructionException */ public DVCSRequest(CMSSignedData signedData) throws DVCSConstructionException { this(SignedData.getInstance(signedData.toASN1Structure().getContent()).getEncapContentInfo()); } /** * Construct a DVCS Request from a ContentInfo * * @param contentInfo the contentInfo representing the DVCSRequest * @throws DVCSConstructionException */ public DVCSRequest(ContentInfo contentInfo) throws DVCSConstructionException { super(contentInfo); if (!DVCSObjectIdentifiers.id_ct_DVCSRequestData.equals(contentInfo.getContentType())) { throw new DVCSConstructionException("ContentInfo not a DVCS Request"); } try { if (contentInfo.getContent().toASN1Primitive() instanceof ASN1Sequence) { this.asn1 = org.bouncycastle.asn1.dvcs.DVCSRequest.getInstance(contentInfo.getContent()); } else { this.asn1 = org.bouncycastle.asn1.dvcs.DVCSRequest.getInstance(ASN1OctetString.getInstance(contentInfo.getContent()).getOctets()); } } catch (Exception e) { throw new DVCSConstructionException("Unable to parse content: " + e.getMessage(), e); } this.reqInfo = new DVCSRequestInfo(asn1.getRequestInformation()); int service = reqInfo.getServiceType(); if (service == ServiceType.CPD.getValue().intValue()) { this.data = new CPDRequestData(asn1.getData()); } else if (service == ServiceType.VSD.getValue().intValue()) { this.data = new VSDRequestData(asn1.getData()); } else if (service == ServiceType.VPKC.getValue().intValue()) { this.data = new VPKCRequestData(asn1.getData()); } else if (service == ServiceType.CCPD.getValue().intValue()) { this.data = new CCPDRequestData(asn1.getData()); } else { throw new DVCSConstructionException("Unknown service type: " + service); } } /** * Return the ASN.1 DVCSRequest structure making up the body of this request. * * @return an org.bouncycastle.asn1.dvcs.DVCSRequest object. */ public ASN1Encodable getContent() { return asn1; } /** * Get RequestInformation envelope. * * @return the request info object. */ public DVCSRequestInfo getRequestInfo() { return reqInfo; } /** * Get data of DVCRequest. * Depending on type of the request it could be different subclasses of DVCRequestData. * * @return the request Data object. */ public DVCSRequestData getData() { return data; } /** * Get the transaction identifier of request. * * @return the GeneralName representing the Transaction Identifier. */ public GeneralName getTransactionIdentifier() { return asn1.getTransactionIdentifier(); } } bouncycastle-1.49.orig/src/org/bouncycastle/dvcs/VPKCRequestBuilder.java0000644000175000017500000000411012131665046025727 0ustar ebourgebourgpackage org.bouncycastle.dvcs; import java.util.ArrayList; import java.util.Date; import java.util.List; import org.bouncycastle.asn1.dvcs.CertEtcToken; import org.bouncycastle.asn1.dvcs.DVCSRequestInformationBuilder; import org.bouncycastle.asn1.dvcs.DVCSTime; import org.bouncycastle.asn1.dvcs.Data; import org.bouncycastle.asn1.dvcs.ServiceType; import org.bouncycastle.asn1.dvcs.TargetEtcChain; import org.bouncycastle.asn1.x509.Extension; import org.bouncycastle.cert.X509CertificateHolder; /** * Builder of DVC requests to VPKC service (Verify Public Key Certificates). */ public class VPKCRequestBuilder extends DVCSRequestBuilder { private List chains = new ArrayList(); public VPKCRequestBuilder() { super(new DVCSRequestInformationBuilder(ServiceType.VPKC)); } /** * Adds a TargetChain representing a X.509 certificate to the request. * * @param cert the certificate to be added */ public void addTargetChain(X509CertificateHolder cert) { chains.add(new TargetEtcChain(new CertEtcToken(CertEtcToken.TAG_CERTIFICATE, cert.toASN1Structure()))); } /** * Adds a TargetChain representing a single X.509 Extension to the request * * @param extension the extension to be added. */ public void addTargetChain(Extension extension) { chains.add(new TargetEtcChain(new CertEtcToken(extension))); } /** * Adds a X.509 certificate to the request. * * @param targetChain the CertChain object to be added. */ public void addTargetChain(TargetChain targetChain) { chains.add(targetChain.toASN1Structure()); } public void setRequestTime(Date requestTime) { requestInformationBuilder.setRequestTime(new DVCSTime(requestTime)); } /** * Build DVCS request to VPKC service. * * @throws DVCSException */ public DVCSRequest build() throws DVCSException { Data data = new Data((TargetEtcChain[])chains.toArray(new TargetEtcChain[chains.size()])); return createDVCRequest(data); } } bouncycastle-1.49.orig/src/org/bouncycastle/dvcs/DVCSRequestInfo.java0000644000175000017500000001423012151253000025215 0ustar ebourgebourgpackage org.bouncycastle.dvcs; import java.math.BigInteger; import java.util.Date; import org.bouncycastle.asn1.dvcs.DVCSRequestInformation; import org.bouncycastle.asn1.dvcs.DVCSTime; import org.bouncycastle.asn1.x509.GeneralNames; import org.bouncycastle.asn1.x509.PolicyInformation; import org.bouncycastle.tsp.TimeStampToken; import org.bouncycastle.util.Arrays; /** * Information piece of DVCS requests. * It is common for all types of DVCS requests. */ public class DVCSRequestInfo { private DVCSRequestInformation data; /** * Constructs DVCRequestInfo from byte array (DER encoded DVCSRequestInformation). * * @param in */ public DVCSRequestInfo(byte[] in) { this(DVCSRequestInformation.getInstance(in)); } /** * Constructs DVCRequestInfo from DVCSRequestInformation ASN.1 structure. * * @param data */ public DVCSRequestInfo(DVCSRequestInformation data) { this.data = data; } /** * Converts to corresponding ASN.1 structure (DVCSRequestInformation). * * @return */ public DVCSRequestInformation toASN1Structure() { return data; } // // DVCRequestInfo selector interface // /** * Get DVCS version of request. * * @return */ public int getVersion() { return data.getVersion(); } /** * Get requested service type. * * @return one of CPD, VSD, VPKC, CCPD (see constants). */ public int getServiceType() { return data.getService().getValue().intValue(); } /** * Get nonce if it is set. * Note: this field can be set (if not present) or extended (if present) by DVCS. * * @return nonce value, or null if it is not set. */ public BigInteger getNonce() { return data.getNonce(); } /** * Get request generation time if it is set. * * @return time of request, or null if it is not set. * @throws DVCSParsingException if a request time is present but cannot be extracted. */ public Date getRequestTime() throws DVCSParsingException { DVCSTime time = data.getRequestTime(); if (time == null) { return null; } try { if (time.getGenTime() != null) { return time.getGenTime().getDate(); } else { TimeStampToken token = new TimeStampToken(time.getTimeStampToken()); return token.getTimeStampInfo().getGenTime(); } } catch (Exception e) { throw new DVCSParsingException("unable to extract time: " + e.getMessage(), e); } } /** * Get names of requesting entity, if set. * * @return */ public GeneralNames getRequester() { return data.getRequester(); } /** * Get policy, under which the validation is requested. * * @return policy identifier or null, if any policy is acceptable. */ public PolicyInformation getRequestPolicy() { if (data.getRequestPolicy() != null) { return data.getRequestPolicy(); } return null; } /** * Get names of DVCS servers. * Note: this field can be set by DVCS. * * @return */ public GeneralNames getDVCSNames() { return data.getDVCS(); } /** * Get data locations, where the copy of request Data can be obtained. * Note: the exact meaning of field is up to applications. * Note: this field can be set by DVCS. * * @return */ public GeneralNames getDataLocations() { return data.getDataLocations(); } /** * Compares two DVCRequestInfo structures: one from DVCRequest, and one from DVCResponse. * This function implements RFC 3029, 9.1 checks of reqInfo. * * @param requestInfo - DVCRequestInfo of DVCRequest * @param responseInfo - DVCRequestInfo of DVCResponse * @return true if server's requestInfo matches client's requestInfo */ public static boolean validate(DVCSRequestInfo requestInfo, DVCSRequestInfo responseInfo) { // RFC 3029, 9.1 // The DVCS MAY modify the fields: // 'dvcs', 'requester', 'dataLocations', and 'nonce' of the ReqInfo structure. DVCSRequestInformation clientInfo = requestInfo.data; DVCSRequestInformation serverInfo = responseInfo.data; if (clientInfo.getVersion() != serverInfo.getVersion()) { return false; } if (!clientEqualsServer(clientInfo.getService(), serverInfo.getService())) { return false; } if (!clientEqualsServer(clientInfo.getRequestTime(), serverInfo.getRequestTime())) { return false; } if (!clientEqualsServer(clientInfo.getRequestPolicy(), serverInfo.getRequestPolicy())) { return false; } if (!clientEqualsServer(clientInfo.getExtensions(), serverInfo.getExtensions())) { return false; } // RFC 3029, 9.1. The only modification allowed to a 'nonce' // is the inclusion of a new field if it was not present, // or to concatenate other data to the end (right) of an existing value. if (clientInfo.getNonce() != null) { if (serverInfo.getNonce() == null) { return false; } byte[] clientNonce = clientInfo.getNonce().toByteArray(); byte[] serverNonce = serverInfo.getNonce().toByteArray(); if (serverNonce.length < clientNonce.length) { return false; } if (!Arrays.areEqual(clientNonce, Arrays.copyOfRange(serverNonce, 0, clientNonce.length))) { return false; } } return true; } // null-protected compare of any two objects private static boolean clientEqualsServer(Object client, Object server) { return (client == null && server == null) || (client != null && client.equals(server)); } } bouncycastle-1.49.orig/src/org/bouncycastle/dvcs/DVCSParsingException.java0000644000175000017500000000067012131665046026255 0ustar ebourgebourgpackage org.bouncycastle.dvcs; /** * DVCS parsing exception - thrown when failed to parse DVCS message. */ public class DVCSParsingException extends DVCSException { private static final long serialVersionUID = -7895880961377691266L; public DVCSParsingException(String message) { super(message); } public DVCSParsingException(String message, Throwable cause) { super(message, cause); } } bouncycastle-1.49.orig/src/org/bouncycastle/dvcs/DVCSRequestBuilder.java0000644000175000017500000000733212151253000025715 0ustar ebourgebourgpackage org.bouncycastle.dvcs; import java.io.IOException; import java.math.BigInteger; import org.bouncycastle.asn1.ASN1Encodable; import org.bouncycastle.asn1.ASN1ObjectIdentifier; import org.bouncycastle.asn1.cms.ContentInfo; import org.bouncycastle.asn1.dvcs.DVCSObjectIdentifiers; import org.bouncycastle.asn1.dvcs.DVCSRequestInformationBuilder; import org.bouncycastle.asn1.dvcs.Data; import org.bouncycastle.asn1.x509.ExtensionsGenerator; import org.bouncycastle.asn1.x509.GeneralName; import org.bouncycastle.asn1.x509.GeneralNames; import org.bouncycastle.cms.CMSSignedDataGenerator; /** * Common base class for client DVCRequest builders. * This class aims at DVCSRequestInformation and TransactionIdentifier construction, * and its subclasses - for Data field construction (as it is specific for the requested service). */ public abstract class DVCSRequestBuilder { private final ExtensionsGenerator extGenerator = new ExtensionsGenerator(); private final CMSSignedDataGenerator signedDataGen = new CMSSignedDataGenerator(); protected final DVCSRequestInformationBuilder requestInformationBuilder; protected DVCSRequestBuilder(DVCSRequestInformationBuilder requestInformationBuilder) { this.requestInformationBuilder = requestInformationBuilder; } /** * Set a nonce for this request, * * @param nonce */ public void setNonce(BigInteger nonce) { requestInformationBuilder.setNonce(nonce); } /** * Set requester name. * * @param requester */ public void setRequester(GeneralName requester) { requestInformationBuilder.setRequester(requester); } /** * Set DVCS name to generated requests. * * @param dvcs */ public void setDVCS(GeneralName dvcs) { requestInformationBuilder.setDVCS(dvcs); } /** * Set DVCS name to generated requests. * * @param dvcs */ public void setDVCS(GeneralNames dvcs) { requestInformationBuilder.setDVCS(dvcs); } /** * Set data location to generated requests. * * @param dataLocation */ public void setDataLocations(GeneralName dataLocation) { requestInformationBuilder.setDataLocations(dataLocation); } /** * Set data location to generated requests. * * @param dataLocations */ public void setDataLocations(GeneralNames dataLocations) { requestInformationBuilder.setDataLocations(dataLocations); } /** * Add a given extension field. * * @param oid the OID defining the extension type. * @param isCritical true if the extension is critical, false otherwise. * @param value the ASN.1 structure that forms the extension's value. * @return this builder object. * @throws DVCSException if there is an issue encoding the extension for adding. */ public void addExtension( ASN1ObjectIdentifier oid, boolean isCritical, ASN1Encodable value) throws DVCSException { try { extGenerator.addExtension(oid, isCritical, value); } catch (IOException e) { throw new DVCSException("cannot encode extension: " + e.getMessage(), e); } } protected DVCSRequest createDVCRequest(Data data) throws DVCSException { if (!extGenerator.isEmpty()) { requestInformationBuilder.setExtensions(extGenerator.generate()); } org.bouncycastle.asn1.dvcs.DVCSRequest request = new org.bouncycastle.asn1.dvcs.DVCSRequest(requestInformationBuilder.build(), data); return new DVCSRequest(new ContentInfo(DVCSObjectIdentifiers.id_ct_DVCSRequestData, request)); } } bouncycastle-1.49.orig/src/org/bouncycastle/dvcs/CCPDRequestBuilder.java0000644000175000017500000000144312151274314025677 0ustar ebourgebourgpackage org.bouncycastle.dvcs; import org.bouncycastle.asn1.dvcs.DVCSRequestInformationBuilder; import org.bouncycastle.asn1.dvcs.Data; import org.bouncycastle.asn1.dvcs.ServiceType; /** * Builder of CCPD requests (Certify Claim of Possession of Data). */ public class CCPDRequestBuilder extends DVCSRequestBuilder { public CCPDRequestBuilder() { super(new DVCSRequestInformationBuilder(ServiceType.CCPD)); } /** * Builds CCPD request. * * @param messageImprint - the message imprint to include. * @return * @throws DVCSException */ public DVCSRequest build(MessageImprint messageImprint) throws DVCSException { Data data = new Data(messageImprint.toASN1Structure()); return createDVCRequest(data); } } bouncycastle-1.49.orig/src/org/bouncycastle/dvcs/VSDRequestData.java0000644000175000017500000000316512131665046025114 0ustar ebourgebourgpackage org.bouncycastle.dvcs; import org.bouncycastle.asn1.dvcs.Data; import org.bouncycastle.cms.CMSException; import org.bouncycastle.cms.CMSSignedData; /** * Data piece of DVCS request to VSD service (Verify Signed Document). * It contains VSD-specific selector interface. * Note: the request should contain CMS SignedData object as message. *

    * This objects are constructed internally, * to build DVCS request to VSD service use VSDRequestBuilder. */ public class VSDRequestData extends DVCSRequestData { private CMSSignedData doc; VSDRequestData(Data data) throws DVCSConstructionException { super(data); initDocument(); } private void initDocument() throws DVCSConstructionException { if (doc == null) { if (data.getMessage() == null) { throw new DVCSConstructionException("DVCSRequest.data.message should be specified for VSD service"); } try { doc = new CMSSignedData(data.getMessage().getOctets()); } catch (CMSException e) { throw new DVCSConstructionException("Can't read CMS SignedData from input", e); } } } /** * Get contained message (data to be certified). * * @return */ public byte[] getMessage() { return data.getMessage().getOctets(); } /** * Get the CMS SignedData object represented by the encoded message. * * @return */ public CMSSignedData getParsedMessage() { return doc; } } bouncycastle-1.49.orig/src/org/bouncycastle/dvcs/package.html0000644000175000017500000000025612131470420023717 0ustar ebourgebourg Classes for dealing "Internet X.509 Public Key Infrastructure Data Validation and Certification Server Protocols" - RFC 3029. bouncycastle-1.49.orig/src/org/bouncycastle/dvcs/SignedDVCSMessageGenerator.java0000644000175000017500000000260512131665046027360 0ustar ebourgebourgpackage org.bouncycastle.dvcs; import java.io.IOException; import org.bouncycastle.asn1.ASN1Encoding; import org.bouncycastle.cms.CMSException; import org.bouncycastle.cms.CMSProcessableByteArray; import org.bouncycastle.cms.CMSSignedData; import org.bouncycastle.cms.CMSSignedDataGenerator; public class SignedDVCSMessageGenerator { private final CMSSignedDataGenerator signedDataGen; public SignedDVCSMessageGenerator(CMSSignedDataGenerator signedDataGen) { this.signedDataGen = signedDataGen; } /** * Creates a CMSSignedData object containing the passed in DVCSMessage * * @param message the request to be signed. * @return an encapsulating SignedData object. * @throws DVCSException in the event of failure to encode the request or sign it. */ public CMSSignedData build(DVCSMessage message) throws DVCSException { try { byte[] encapsulatedData = message.getContent().toASN1Primitive().getEncoded(ASN1Encoding.DER); return signedDataGen.generate(new CMSProcessableByteArray(message.getContentType(), encapsulatedData), true); } catch (CMSException e) { throw new DVCSException("Could not sign DVCS request", e); } catch (IOException e) { throw new DVCSException("Could not encode DVCS request", e); } } } bouncycastle-1.49.orig/src/org/bouncycastle/dvcs/VPKCRequestData.java0000644000175000017500000000230512151274314025212 0ustar ebourgebourgpackage org.bouncycastle.dvcs; import java.util.ArrayList; import java.util.Collections; import java.util.List; import org.bouncycastle.asn1.dvcs.Data; import org.bouncycastle.asn1.dvcs.TargetEtcChain; /** * Data piece of DVCS request to VPKC service (Verify Public Key Certificates). * It contains VPKC-specific interface. *

    * This objects are constructed internally, * to build DVCS request to VPKC service use VPKCRequestBuilder. */ public class VPKCRequestData extends DVCSRequestData { private List chains; VPKCRequestData(Data data) throws DVCSConstructionException { super(data); TargetEtcChain[] certs = data.getCerts(); if (certs == null) { throw new DVCSConstructionException("DVCSRequest.data.certs should be specified for VPKC service"); } chains = new ArrayList(certs.length); for (int i = 0; i != certs.length; i++) { chains.add(new TargetChain(certs[i])); } } /** * Get contained certs choice data.. * * @return a list of CertChain objects. */ public List getCerts() { return Collections.unmodifiableList(chains); } } bouncycastle-1.49.orig/src/org/bouncycastle/util/0000755000175000017500000000000012152033551021454 5ustar ebourgebourgbouncycastle-1.49.orig/src/org/bouncycastle/util/CollectionStore.java0000644000175000017500000000233310540164524025434 0ustar ebourgebourgpackage org.bouncycastle.util; import java.util.ArrayList; import java.util.Collection; import java.util.Iterator; import java.util.List; /** * A simple collection backed store. */ public class CollectionStore implements Store { private Collection _local; /** * Basic constructor. * * @param collection - initial contents for the store, this is copied. */ public CollectionStore( Collection collection) { _local = new ArrayList(collection); } /** * Return the matches in the collection for the passed in selector. * * @param selector the selector to match against. * @return a possibly empty collection of matching objects. */ public Collection getMatches(Selector selector) { if (selector == null) { return new ArrayList(_local); } else { List col = new ArrayList(); Iterator iter = _local.iterator(); while (iter.hasNext()) { Object obj = iter.next(); if (selector.match(obj)) { col.add(obj); } } return col; } } } bouncycastle-1.49.orig/src/org/bouncycastle/util/Store.java0000644000175000017500000000024510526271010023411 0ustar ebourgebourgpackage org.bouncycastle.util; import java.util.Collection; public interface Store { Collection getMatches(Selector selector) throws StoreException; } bouncycastle-1.49.orig/src/org/bouncycastle/util/Selector.java0000644000175000017500000000021010532755676024113 0ustar ebourgebourgpackage org.bouncycastle.util; public interface Selector extends Cloneable { boolean match(Object obj); Object clone(); } bouncycastle-1.49.orig/src/org/bouncycastle/util/Strings.java0000644000175000017500000001717211703673563023776 0ustar ebourgebourgpackage org.bouncycastle.util; import java.io.ByteArrayOutputStream; import java.io.IOException; import java.io.OutputStream; import java.util.Vector; public final class Strings { public static String fromUTF8ByteArray(byte[] bytes) { int i = 0; int length = 0; while (i < bytes.length) { length++; if ((bytes[i] & 0xf0) == 0xf0) { // surrogate pair length++; i += 4; } else if ((bytes[i] & 0xe0) == 0xe0) { i += 3; } else if ((bytes[i] & 0xc0) == 0xc0) { i += 2; } else { i += 1; } } char[] cs = new char[length]; i = 0; length = 0; while (i < bytes.length) { char ch; if ((bytes[i] & 0xf0) == 0xf0) { int codePoint = ((bytes[i] & 0x03) << 18) | ((bytes[i+1] & 0x3F) << 12) | ((bytes[i+2] & 0x3F) << 6) | (bytes[i+3] & 0x3F); int U = codePoint - 0x10000; char W1 = (char)(0xD800 | (U >> 10)); char W2 = (char)(0xDC00 | (U & 0x3FF)); cs[length++] = W1; ch = W2; i += 4; } else if ((bytes[i] & 0xe0) == 0xe0) { ch = (char)(((bytes[i] & 0x0f) << 12) | ((bytes[i + 1] & 0x3f) << 6) | (bytes[i + 2] & 0x3f)); i += 3; } else if ((bytes[i] & 0xd0) == 0xd0) { ch = (char)(((bytes[i] & 0x1f) << 6) | (bytes[i + 1] & 0x3f)); i += 2; } else if ((bytes[i] & 0xc0) == 0xc0) { ch = (char)(((bytes[i] & 0x1f) << 6) | (bytes[i + 1] & 0x3f)); i += 2; } else { ch = (char)(bytes[i] & 0xff); i += 1; } cs[length++] = ch; } return new String(cs); } public static byte[] toUTF8ByteArray(String string) { return toUTF8ByteArray(string.toCharArray()); } public static byte[] toUTF8ByteArray(char[] string) { ByteArrayOutputStream bOut = new ByteArrayOutputStream(); try { toUTF8ByteArray(string, bOut); } catch (IOException e) { throw new IllegalStateException("cannot encode string to byte array!"); } return bOut.toByteArray(); } public static void toUTF8ByteArray(char[] string, OutputStream sOut) throws IOException { char[] c = string; int i = 0; while (i < c.length) { char ch = c[i]; if (ch < 0x0080) { sOut.write(ch); } else if (ch < 0x0800) { sOut.write(0xc0 | (ch >> 6)); sOut.write(0x80 | (ch & 0x3f)); } // surrogate pair else if (ch >= 0xD800 && ch <= 0xDFFF) { // in error - can only happen, if the Java String class has a // bug. if (i + 1 >= c.length) { throw new IllegalStateException("invalid UTF-16 codepoint"); } char W1 = ch; ch = c[++i]; char W2 = ch; // in error - can only happen, if the Java String class has a // bug. if (W1 > 0xDBFF) { throw new IllegalStateException("invalid UTF-16 codepoint"); } int codePoint = (((W1 & 0x03FF) << 10) | (W2 & 0x03FF)) + 0x10000; sOut.write(0xf0 | (codePoint >> 18)); sOut.write(0x80 | ((codePoint >> 12) & 0x3F)); sOut.write(0x80 | ((codePoint >> 6) & 0x3F)); sOut.write(0x80 | (codePoint & 0x3F)); } else { sOut.write(0xe0 | (ch >> 12)); sOut.write(0x80 | ((ch >> 6) & 0x3F)); sOut.write(0x80 | (ch & 0x3F)); } i++; } } /** * A locale independent version of toUpperCase. * * @param string input to be converted * @return a US Ascii uppercase version */ public static String toUpperCase(String string) { boolean changed = false; char[] chars = string.toCharArray(); for (int i = 0; i != chars.length; i++) { char ch = chars[i]; if ('a' <= ch && 'z' >= ch) { changed = true; chars[i] = (char)(ch - 'a' + 'A'); } } if (changed) { return new String(chars); } return string; } /** * A locale independent version of toLowerCase. * * @param string input to be converted * @return a US ASCII lowercase version */ public static String toLowerCase(String string) { boolean changed = false; char[] chars = string.toCharArray(); for (int i = 0; i != chars.length; i++) { char ch = chars[i]; if ('A' <= ch && 'Z' >= ch) { changed = true; chars[i] = (char)(ch - 'A' + 'a'); } } if (changed) { return new String(chars); } return string; } public static byte[] toByteArray(char[] chars) { byte[] bytes = new byte[chars.length]; for (int i = 0; i != bytes.length; i++) { bytes[i] = (byte)chars[i]; } return bytes; } public static byte[] toByteArray(String string) { byte[] bytes = new byte[string.length()]; for (int i = 0; i != bytes.length; i++) { char ch = string.charAt(i); bytes[i] = (byte)ch; } return bytes; } /** * Convert an array of 8 bit characters into a string. * * @param bytes 8 bit characters. * @return resulting String. */ public static String fromByteArray(byte[] bytes) { return new String(asCharArray(bytes)); } /** * Do a simple conversion of an array of 8 bit characters into a string. * * @param bytes 8 bit characters. * @return resulting String. */ public static char[] asCharArray(byte[] bytes) { char[] chars = new char[bytes.length]; for (int i = 0; i != chars.length; i++) { chars[i] = (char)(bytes[i] & 0xff); } return chars; } public static String[] split(String input, char delimiter) { Vector v = new Vector(); boolean moreTokens = true; String subString; while (moreTokens) { int tokenLocation = input.indexOf(delimiter); if (tokenLocation > 0) { subString = input.substring(0, tokenLocation); v.addElement(subString); input = input.substring(tokenLocation + 1); } else { moreTokens = false; v.addElement(input); } } String[] res = new String[v.size()]; for (int i = 0; i != res.length; i++) { res[i] = (String)v.elementAt(i); } return res; } } bouncycastle-1.49.orig/src/org/bouncycastle/util/encoders/0000755000175000017500000000000012152033551023256 5ustar ebourgebourgbouncycastle-1.49.orig/src/org/bouncycastle/util/encoders/BufferedEncoder.java0000644000175000017500000000421410262753174027156 0ustar ebourgebourgpackage org.bouncycastle.util.encoders; /** * a buffering class to allow translation from one format to another to * be done in discrete chunks. */ public class BufferedEncoder { protected byte[] buf; protected int bufOff; protected Translator translator; /** * @param translator the translator to use. * @param bufSize amount of input to buffer for each chunk. */ public BufferedEncoder( Translator translator, int bufSize) { this.translator = translator; if ((bufSize % translator.getEncodedBlockSize()) != 0) { throw new IllegalArgumentException("buffer size not multiple of input block size"); } buf = new byte[bufSize]; bufOff = 0; } public int processByte( byte in, byte[] out, int outOff) { int resultLen = 0; buf[bufOff++] = in; if (bufOff == buf.length) { resultLen = translator.encode(buf, 0, buf.length, out, outOff); bufOff = 0; } return resultLen; } public int processBytes( byte[] in, int inOff, int len, byte[] out, int outOff) { if (len < 0) { throw new IllegalArgumentException("Can't have a negative input length!"); } int resultLen = 0; int gapLen = buf.length - bufOff; if (len > gapLen) { System.arraycopy(in, inOff, buf, bufOff, gapLen); resultLen += translator.encode(buf, 0, buf.length, out, outOff); bufOff = 0; len -= gapLen; inOff += gapLen; outOff += resultLen; int chunkSize = len - (len % buf.length); resultLen += translator.encode(in, inOff, chunkSize, out, outOff); len -= chunkSize; inOff += chunkSize; } if (len != 0) { System.arraycopy(in, inOff, buf, bufOff, len); bufOff += len; } return resultLen; } } bouncycastle-1.49.orig/src/org/bouncycastle/util/encoders/Translator.java0000644000175000017500000000110210262753174026256 0ustar ebourgebourgpackage org.bouncycastle.util.encoders; /** * general interface for an translator. */ public interface Translator { /** * size of the output block on encoding produced by getDecodedBlockSize() * bytes. */ public int getEncodedBlockSize(); public int encode(byte[] in, int inOff, int length, byte[] out, int outOff); /** * size of the output block on decoding produced by getEncodedBlockSize() * bytes. */ public int getDecodedBlockSize(); public int decode(byte[] in, int inOff, int length, byte[] out, int outOff); } bouncycastle-1.49.orig/src/org/bouncycastle/util/encoders/Encoder.java0000644000175000017500000000072510262753174025516 0ustar ebourgebourgpackage org.bouncycastle.util.encoders; import java.io.IOException; import java.io.OutputStream; /** * Encode and decode byte arrays (typically from binary to 7-bit ASCII * encodings). */ public interface Encoder { int encode(byte[] data, int off, int length, OutputStream out) throws IOException; int decode(byte[] data, int off, int length, OutputStream out) throws IOException; int decode(String data, OutputStream out) throws IOException; } bouncycastle-1.49.orig/src/org/bouncycastle/util/encoders/HexEncoder.java0000644000175000017500000001061112077622451026155 0ustar ebourgebourgpackage org.bouncycastle.util.encoders; import java.io.IOException; import java.io.OutputStream; public class HexEncoder implements Encoder { protected final byte[] encodingTable = { (byte)'0', (byte)'1', (byte)'2', (byte)'3', (byte)'4', (byte)'5', (byte)'6', (byte)'7', (byte)'8', (byte)'9', (byte)'a', (byte)'b', (byte)'c', (byte)'d', (byte)'e', (byte)'f' }; /* * set up the decoding table. */ protected final byte[] decodingTable = new byte[128]; protected void initialiseDecodingTable() { for (int i = 0; i < decodingTable.length; i++) { decodingTable[i] = (byte)0xff; } for (int i = 0; i < encodingTable.length; i++) { decodingTable[encodingTable[i]] = (byte)i; } decodingTable['A'] = decodingTable['a']; decodingTable['B'] = decodingTable['b']; decodingTable['C'] = decodingTable['c']; decodingTable['D'] = decodingTable['d']; decodingTable['E'] = decodingTable['e']; decodingTable['F'] = decodingTable['f']; } public HexEncoder() { initialiseDecodingTable(); } /** * encode the input data producing a Hex output stream. * * @return the number of bytes produced. */ public int encode( byte[] data, int off, int length, OutputStream out) throws IOException { for (int i = off; i < (off + length); i++) { int v = data[i] & 0xff; out.write(encodingTable[(v >>> 4)]); out.write(encodingTable[v & 0xf]); } return length * 2; } private static boolean ignore( char c) { return c == '\n' || c =='\r' || c == '\t' || c == ' '; } /** * decode the Hex encoded byte data writing it to the given output stream, * whitespace characters will be ignored. * * @return the number of bytes produced. */ public int decode( byte[] data, int off, int length, OutputStream out) throws IOException { byte b1, b2; int outLen = 0; int end = off + length; while (end > off) { if (!ignore((char)data[end - 1])) { break; } end--; } int i = off; while (i < end) { while (i < end && ignore((char)data[i])) { i++; } b1 = decodingTable[data[i++]]; while (i < end && ignore((char)data[i])) { i++; } b2 = decodingTable[data[i++]]; if ((b1 | b2) < 0) { throw new IOException("invalid characters encountered in Hex data"); } out.write((b1 << 4) | b2); outLen++; } return outLen; } /** * decode the Hex encoded String data writing it to the given output stream, * whitespace characters will be ignored. * * @return the number of bytes produced. */ public int decode( String data, OutputStream out) throws IOException { byte b1, b2; int length = 0; int end = data.length(); while (end > 0) { if (!ignore(data.charAt(end - 1))) { break; } end--; } int i = 0; while (i < end) { while (i < end && ignore(data.charAt(i))) { i++; } b1 = decodingTable[data.charAt(i++)]; while (i < end && ignore(data.charAt(i))) { i++; } b2 = decodingTable[data.charAt(i++)]; if ((b1 | b2) < 0) { throw new IOException("invalid characters encountered in Hex string"); } out.write((b1 << 4) | b2); length++; } return length; } } bouncycastle-1.49.orig/src/org/bouncycastle/util/encoders/UrlBase64Encoder.java0000644000175000017500000000201610262753174027141 0ustar ebourgebourgpackage org.bouncycastle.util.encoders; /** * Convert binary data to and from UrlBase64 encoding. This is identical to * Base64 encoding, except that the padding character is "." and the other * non-alphanumeric characters are "-" and "_" instead of "+" and "/". *

    * The purpose of UrlBase64 encoding is to provide a compact encoding of binary * data that is safe for use as an URL parameter. Base64 encoding does not * produce encoded values that are safe for use in URLs, since "/" can be * interpreted as a path delimiter; "+" is the encoded form of a space; and * "=" is used to separate a name from the corresponding value in an URL * parameter. */ public class UrlBase64Encoder extends Base64Encoder { public UrlBase64Encoder() { encodingTable[encodingTable.length - 2] = (byte) '-'; encodingTable[encodingTable.length - 1] = (byte) '_'; padding = (byte) '.'; // we must re-create the decoding table with the new encoded values. initialiseDecodingTable(); } } bouncycastle-1.49.orig/src/org/bouncycastle/util/encoders/EncoderException.java0000644000175000017500000000047511735222524027373 0ustar ebourgebourgpackage org.bouncycastle.util.encoders; public class EncoderException extends IllegalStateException { private Throwable cause; EncoderException(String msg, Throwable cause) { super(msg); this.cause = cause; } public Throwable getCause() { return cause; } } bouncycastle-1.49.orig/src/org/bouncycastle/util/encoders/UrlBase64.java0000644000175000017500000000732011735224613025641 0ustar ebourgebourgpackage org.bouncycastle.util.encoders; import java.io.ByteArrayOutputStream; import java.io.IOException; import java.io.OutputStream; /** * Convert binary data to and from UrlBase64 encoding. This is identical to * Base64 encoding, except that the padding character is "." and the other * non-alphanumeric characters are "-" and "_" instead of "+" and "/". *

    * The purpose of UrlBase64 encoding is to provide a compact encoding of binary * data that is safe for use as an URL parameter. Base64 encoding does not * produce encoded values that are safe for use in URLs, since "/" can be * interpreted as a path delimiter; "+" is the encoded form of a space; and * "=" is used to separate a name from the corresponding value in an URL * parameter. */ public class UrlBase64 { private static final Encoder encoder = new UrlBase64Encoder(); /** * Encode the input data producing a URL safe base 64 encoded byte array. * * @return a byte array containing the URL safe base 64 encoded data. */ public static byte[] encode( byte[] data) { ByteArrayOutputStream bOut = new ByteArrayOutputStream(); try { encoder.encode(data, 0, data.length, bOut); } catch (Exception e) { throw new EncoderException("exception encoding URL safe base64 data: " + e.getMessage(), e); } return bOut.toByteArray(); } /** * Encode the byte data writing it to the given output stream. * * @return the number of bytes produced. */ public static int encode( byte[] data, OutputStream out) throws IOException { return encoder.encode(data, 0, data.length, out); } /** * Decode the URL safe base 64 encoded input data - white space will be ignored. * * @return a byte array representing the decoded data. */ public static byte[] decode( byte[] data) { ByteArrayOutputStream bOut = new ByteArrayOutputStream(); try { encoder.decode(data, 0, data.length, bOut); } catch (Exception e) { throw new DecoderException("exception decoding URL safe base64 string: " + e.getMessage(), e); } return bOut.toByteArray(); } /** * decode the URL safe base 64 encoded byte data writing it to the given output stream, * whitespace characters will be ignored. * * @return the number of bytes produced. */ public static int decode( byte[] data, OutputStream out) throws IOException { return encoder.decode(data, 0, data.length, out); } /** * decode the URL safe base 64 encoded String data - whitespace will be ignored. * * @return a byte array representing the decoded data. */ public static byte[] decode( String data) { ByteArrayOutputStream bOut = new ByteArrayOutputStream(); try { encoder.decode(data, bOut); } catch (Exception e) { throw new DecoderException("exception decoding URL safe base64 string: " + e.getMessage(), e); } return bOut.toByteArray(); } /** * Decode the URL safe base 64 encoded String data writing it to the given output stream, * whitespace characters will be ignored. * * @return the number of bytes produced. */ public static int decode( String data, OutputStream out) throws IOException { return encoder.decode(data, out); } } bouncycastle-1.49.orig/src/org/bouncycastle/util/encoders/Base64.java0000644000175000017500000000751212132370165025155 0ustar ebourgebourgpackage org.bouncycastle.util.encoders; import java.io.ByteArrayOutputStream; import java.io.IOException; import java.io.OutputStream; import org.bouncycastle.util.Strings; public class Base64 { private static final Encoder encoder = new Base64Encoder(); public static String toBase64String( byte[] data) { return toBase64String(data, 0, data.length); } public static String toBase64String( byte[] data, int off, int length) { byte[] encoded = encode(data, off, length); return Strings.fromByteArray(encoded); } /** * encode the input data producing a base 64 encoded byte array. * * @return a byte array containing the base 64 encoded data. */ public static byte[] encode( byte[] data) { return encode(data, 0, data.length); } /** * encode the input data producing a base 64 encoded byte array. * * @return a byte array containing the base 64 encoded data. */ public static byte[] encode( byte[] data, int off, int length) { int len = (length + 2) / 3 * 4; ByteArrayOutputStream bOut = new ByteArrayOutputStream(len); try { encoder.encode(data, off, length, bOut); } catch (Exception e) { throw new EncoderException("exception encoding base64 string: " + e.getMessage(), e); } return bOut.toByteArray(); } /** * Encode the byte data to base 64 writing it to the given output stream. * * @return the number of bytes produced. */ public static int encode( byte[] data, OutputStream out) throws IOException { return encoder.encode(data, 0, data.length, out); } /** * Encode the byte data to base 64 writing it to the given output stream. * * @return the number of bytes produced. */ public static int encode( byte[] data, int off, int length, OutputStream out) throws IOException { return encoder.encode(data, off, length, out); } /** * decode the base 64 encoded input data. It is assumed the input data is valid. * * @return a byte array representing the decoded data. */ public static byte[] decode( byte[] data) { int len = data.length / 4 * 3; ByteArrayOutputStream bOut = new ByteArrayOutputStream(len); try { encoder.decode(data, 0, data.length, bOut); } catch (Exception e) { throw new DecoderException("unable to decode base64 data: " + e.getMessage(), e); } return bOut.toByteArray(); } /** * decode the base 64 encoded String data - whitespace will be ignored. * * @return a byte array representing the decoded data. */ public static byte[] decode( String data) { int len = data.length() / 4 * 3; ByteArrayOutputStream bOut = new ByteArrayOutputStream(len); try { encoder.decode(data, bOut); } catch (Exception e) { throw new DecoderException("unable to decode base64 string: " + e.getMessage(), e); } return bOut.toByteArray(); } /** * decode the base 64 encoded String data writing it to the given output stream, * whitespace characters will be ignored. * * @return the number of bytes produced. */ public static int decode( String data, OutputStream out) throws IOException { return encoder.decode(data, out); } } bouncycastle-1.49.orig/src/org/bouncycastle/util/encoders/DecoderException.java0000644000175000017500000000047511735221663027364 0ustar ebourgebourgpackage org.bouncycastle.util.encoders; public class DecoderException extends IllegalStateException { private Throwable cause; DecoderException(String msg, Throwable cause) { super(msg); this.cause = cause; } public Throwable getCause() { return cause; } } bouncycastle-1.49.orig/src/org/bouncycastle/util/encoders/Base64Encoder.java0000644000175000017500000002137411735222620026457 0ustar ebourgebourgpackage org.bouncycastle.util.encoders; import java.io.IOException; import java.io.OutputStream; public class Base64Encoder implements Encoder { protected final byte[] encodingTable = { (byte)'A', (byte)'B', (byte)'C', (byte)'D', (byte)'E', (byte)'F', (byte)'G', (byte)'H', (byte)'I', (byte)'J', (byte)'K', (byte)'L', (byte)'M', (byte)'N', (byte)'O', (byte)'P', (byte)'Q', (byte)'R', (byte)'S', (byte)'T', (byte)'U', (byte)'V', (byte)'W', (byte)'X', (byte)'Y', (byte)'Z', (byte)'a', (byte)'b', (byte)'c', (byte)'d', (byte)'e', (byte)'f', (byte)'g', (byte)'h', (byte)'i', (byte)'j', (byte)'k', (byte)'l', (byte)'m', (byte)'n', (byte)'o', (byte)'p', (byte)'q', (byte)'r', (byte)'s', (byte)'t', (byte)'u', (byte)'v', (byte)'w', (byte)'x', (byte)'y', (byte)'z', (byte)'0', (byte)'1', (byte)'2', (byte)'3', (byte)'4', (byte)'5', (byte)'6', (byte)'7', (byte)'8', (byte)'9', (byte)'+', (byte)'/' }; protected byte padding = (byte)'='; /* * set up the decoding table. */ protected final byte[] decodingTable = new byte[128]; protected void initialiseDecodingTable() { for (int i = 0; i < decodingTable.length; i++) { decodingTable[i] = (byte)0xff; } for (int i = 0; i < encodingTable.length; i++) { decodingTable[encodingTable[i]] = (byte)i; } } public Base64Encoder() { initialiseDecodingTable(); } /** * encode the input data producing a base 64 output stream. * * @return the number of bytes produced. */ public int encode( byte[] data, int off, int length, OutputStream out) throws IOException { int modulus = length % 3; int dataLength = (length - modulus); int a1, a2, a3; for (int i = off; i < off + dataLength; i += 3) { a1 = data[i] & 0xff; a2 = data[i + 1] & 0xff; a3 = data[i + 2] & 0xff; out.write(encodingTable[(a1 >>> 2) & 0x3f]); out.write(encodingTable[((a1 << 4) | (a2 >>> 4)) & 0x3f]); out.write(encodingTable[((a2 << 2) | (a3 >>> 6)) & 0x3f]); out.write(encodingTable[a3 & 0x3f]); } /* * process the tail end. */ int b1, b2, b3; int d1, d2; switch (modulus) { case 0: /* nothing left to do */ break; case 1: d1 = data[off + dataLength] & 0xff; b1 = (d1 >>> 2) & 0x3f; b2 = (d1 << 4) & 0x3f; out.write(encodingTable[b1]); out.write(encodingTable[b2]); out.write(padding); out.write(padding); break; case 2: d1 = data[off + dataLength] & 0xff; d2 = data[off + dataLength + 1] & 0xff; b1 = (d1 >>> 2) & 0x3f; b2 = ((d1 << 4) | (d2 >>> 4)) & 0x3f; b3 = (d2 << 2) & 0x3f; out.write(encodingTable[b1]); out.write(encodingTable[b2]); out.write(encodingTable[b3]); out.write(padding); break; } return (dataLength / 3) * 4 + ((modulus == 0) ? 0 : 4); } private boolean ignore( char c) { return (c == '\n' || c =='\r' || c == '\t' || c == ' '); } /** * decode the base 64 encoded byte data writing it to the given output stream, * whitespace characters will be ignored. * * @return the number of bytes produced. */ public int decode( byte[] data, int off, int length, OutputStream out) throws IOException { byte b1, b2, b3, b4; int outLen = 0; int end = off + length; while (end > off) { if (!ignore((char)data[end - 1])) { break; } end--; } int i = off; int finish = end - 4; i = nextI(data, i, finish); while (i < finish) { b1 = decodingTable[data[i++]]; i = nextI(data, i, finish); b2 = decodingTable[data[i++]]; i = nextI(data, i, finish); b3 = decodingTable[data[i++]]; i = nextI(data, i, finish); b4 = decodingTable[data[i++]]; if ((b1 | b2 | b3 | b4) < 0) { throw new IOException("invalid characters encountered in base64 data"); } out.write((b1 << 2) | (b2 >> 4)); out.write((b2 << 4) | (b3 >> 2)); out.write((b3 << 6) | b4); outLen += 3; i = nextI(data, i, finish); } outLen += decodeLastBlock(out, (char)data[end - 4], (char)data[end - 3], (char)data[end - 2], (char)data[end - 1]); return outLen; } private int nextI(byte[] data, int i, int finish) { while ((i < finish) && ignore((char)data[i])) { i++; } return i; } /** * decode the base 64 encoded String data writing it to the given output stream, * whitespace characters will be ignored. * * @return the number of bytes produced. */ public int decode( String data, OutputStream out) throws IOException { byte b1, b2, b3, b4; int length = 0; int end = data.length(); while (end > 0) { if (!ignore(data.charAt(end - 1))) { break; } end--; } int i = 0; int finish = end - 4; i = nextI(data, i, finish); while (i < finish) { b1 = decodingTable[data.charAt(i++)]; i = nextI(data, i, finish); b2 = decodingTable[data.charAt(i++)]; i = nextI(data, i, finish); b3 = decodingTable[data.charAt(i++)]; i = nextI(data, i, finish); b4 = decodingTable[data.charAt(i++)]; if ((b1 | b2 | b3 | b4) < 0) { throw new IOException("invalid characters encountered in base64 data"); } out.write((b1 << 2) | (b2 >> 4)); out.write((b2 << 4) | (b3 >> 2)); out.write((b3 << 6) | b4); length += 3; i = nextI(data, i, finish); } length += decodeLastBlock(out, data.charAt(end - 4), data.charAt(end - 3), data.charAt(end - 2), data.charAt(end - 1)); return length; } private int decodeLastBlock(OutputStream out, char c1, char c2, char c3, char c4) throws IOException { byte b1, b2, b3, b4; if (c3 == padding) { b1 = decodingTable[c1]; b2 = decodingTable[c2]; if ((b1 | b2) < 0) { throw new IOException("invalid characters encountered at end of base64 data"); } out.write((b1 << 2) | (b2 >> 4)); return 1; } else if (c4 == padding) { b1 = decodingTable[c1]; b2 = decodingTable[c2]; b3 = decodingTable[c3]; if ((b1 | b2 | b3) < 0) { throw new IOException("invalid characters encountered at end of base64 data"); } out.write((b1 << 2) | (b2 >> 4)); out.write((b2 << 4) | (b3 >> 2)); return 2; } else { b1 = decodingTable[c1]; b2 = decodingTable[c2]; b3 = decodingTable[c3]; b4 = decodingTable[c4]; if ((b1 | b2 | b3 | b4) < 0) { throw new IOException("invalid characters encountered at end of base64 data"); } out.write((b1 << 2) | (b2 >> 4)); out.write((b2 << 4) | (b3 >> 2)); out.write((b3 << 6) | b4); return 3; } } private int nextI(String data, int i, int finish) { while ((i < finish) && ignore(data.charAt(i))) { i++; } return i; } } bouncycastle-1.49.orig/src/org/bouncycastle/util/encoders/Hex.java0000644000175000017500000000720312132370142024645 0ustar ebourgebourgpackage org.bouncycastle.util.encoders; import java.io.ByteArrayOutputStream; import java.io.IOException; import java.io.OutputStream; import org.bouncycastle.util.Strings; public class Hex { private static final Encoder encoder = new HexEncoder(); public static String toHexString( byte[] data) { return toHexString(data, 0, data.length); } public static String toHexString( byte[] data, int off, int length) { byte[] encoded = encode(data, off, length); return Strings.fromByteArray(encoded); } /** * encode the input data producing a Hex encoded byte array. * * @return a byte array containing the Hex encoded data. */ public static byte[] encode( byte[] data) { return encode(data, 0, data.length); } /** * encode the input data producing a Hex encoded byte array. * * @return a byte array containing the Hex encoded data. */ public static byte[] encode( byte[] data, int off, int length) { ByteArrayOutputStream bOut = new ByteArrayOutputStream(); try { encoder.encode(data, off, length, bOut); } catch (Exception e) { throw new EncoderException("exception encoding Hex string: " + e.getMessage(), e); } return bOut.toByteArray(); } /** * Hex encode the byte data writing it to the given output stream. * * @return the number of bytes produced. */ public static int encode( byte[] data, OutputStream out) throws IOException { return encoder.encode(data, 0, data.length, out); } /** * Hex encode the byte data writing it to the given output stream. * * @return the number of bytes produced. */ public static int encode( byte[] data, int off, int length, OutputStream out) throws IOException { return encoder.encode(data, off, length, out); } /** * decode the Hex encoded input data. It is assumed the input data is valid. * * @return a byte array representing the decoded data. */ public static byte[] decode( byte[] data) { ByteArrayOutputStream bOut = new ByteArrayOutputStream(); try { encoder.decode(data, 0, data.length, bOut); } catch (Exception e) { throw new DecoderException("exception decoding Hex data: " + e.getMessage(), e); } return bOut.toByteArray(); } /** * decode the Hex encoded String data - whitespace will be ignored. * * @return a byte array representing the decoded data. */ public static byte[] decode( String data) { ByteArrayOutputStream bOut = new ByteArrayOutputStream(); try { encoder.decode(data, bOut); } catch (Exception e) { throw new DecoderException("exception decoding Hex string: " + e.getMessage(), e); } return bOut.toByteArray(); } /** * decode the Hex encoded String data writing it to the given output stream, * whitespace characters will be ignored. * * @return the number of bytes produced. */ public static int decode( String data, OutputStream out) throws IOException { return encoder.decode(data, out); } } bouncycastle-1.49.orig/src/org/bouncycastle/util/encoders/HexTranslator.java0000644000175000017500000000404710262753174026736 0ustar ebourgebourgpackage org.bouncycastle.util.encoders; /** * Converters for going from hex to binary and back. Note: this class assumes ASCII processing. */ public class HexTranslator implements Translator { private static final byte[] hexTable = { (byte)'0', (byte)'1', (byte)'2', (byte)'3', (byte)'4', (byte)'5', (byte)'6', (byte)'7', (byte)'8', (byte)'9', (byte)'a', (byte)'b', (byte)'c', (byte)'d', (byte)'e', (byte)'f' }; /** * size of the output block on encoding produced by getDecodedBlockSize() * bytes. */ public int getEncodedBlockSize() { return 2; } public int encode( byte[] in, int inOff, int length, byte[] out, int outOff) { for (int i = 0, j = 0; i < length; i++, j += 2) { out[outOff + j] = hexTable[(in[inOff] >> 4) & 0x0f]; out[outOff + j + 1] = hexTable[in[inOff] & 0x0f]; inOff++; } return length * 2; } /** * size of the output block on decoding produced by getEncodedBlockSize() * bytes. */ public int getDecodedBlockSize() { return 1; } public int decode( byte[] in, int inOff, int length, byte[] out, int outOff) { int halfLength = length / 2; byte left, right; for (int i = 0; i < halfLength; i++) { left = in[inOff + i * 2]; right = in[inOff + i * 2 + 1]; if (left < (byte)'a') { out[outOff] = (byte)((left - '0') << 4); } else { out[outOff] = (byte)((left - 'a' + 10) << 4); } if (right < (byte)'a') { out[outOff] += (byte)(right - '0'); } else { out[outOff] += (byte)(right - 'a' + 10); } outOff++; } return halfLength; } } bouncycastle-1.49.orig/src/org/bouncycastle/util/encoders/BufferedDecoder.java0000644000175000017500000000421410262753174027144 0ustar ebourgebourgpackage org.bouncycastle.util.encoders; /** * a buffering class to allow translation from one format to another to * be done in discrete chunks. */ public class BufferedDecoder { protected byte[] buf; protected int bufOff; protected Translator translator; /** * @param translator the translator to use. * @param bufSize amount of input to buffer for each chunk. */ public BufferedDecoder( Translator translator, int bufSize) { this.translator = translator; if ((bufSize % translator.getEncodedBlockSize()) != 0) { throw new IllegalArgumentException("buffer size not multiple of input block size"); } buf = new byte[bufSize]; bufOff = 0; } public int processByte( byte in, byte[] out, int outOff) { int resultLen = 0; buf[bufOff++] = in; if (bufOff == buf.length) { resultLen = translator.decode(buf, 0, buf.length, out, outOff); bufOff = 0; } return resultLen; } public int processBytes( byte[] in, int inOff, int len, byte[] out, int outOff) { if (len < 0) { throw new IllegalArgumentException("Can't have a negative input length!"); } int resultLen = 0; int gapLen = buf.length - bufOff; if (len > gapLen) { System.arraycopy(in, inOff, buf, bufOff, gapLen); resultLen += translator.decode(buf, 0, buf.length, out, outOff); bufOff = 0; len -= gapLen; inOff += gapLen; outOff += resultLen; int chunkSize = len - (len % buf.length); resultLen += translator.decode(in, inOff, chunkSize, out, outOff); len -= chunkSize; inOff += chunkSize; } if (len != 0) { System.arraycopy(in, inOff, buf, bufOff, len); bufOff += len; } return resultLen; } } bouncycastle-1.49.orig/src/org/bouncycastle/util/encoders/package.html0000644000175000017500000000015210262753174025547 0ustar ebourgebourg Classes for producing and reading Base64 and Hex strings. bouncycastle-1.49.orig/src/org/bouncycastle/util/MemoableResetException.java0000644000175000017500000000105112143606432026723 0ustar ebourgebourgpackage org.bouncycastle.util; /** * Exception to be thrown on a failure to reset an object implementing Memoable. *

    * The exception extends ClassCastException to enable users to have a single handling case, * only introducing specific handling of this one if required. *

    */ public class MemoableResetException extends ClassCastException { /** * Basic Constructor. * * @param msg message to be associated with this exception. */ public MemoableResetException(String msg) { super(msg); } } bouncycastle-1.49.orig/src/org/bouncycastle/util/StoreException.java0000644000175000017500000000042710525263755025312 0ustar ebourgebourgpackage org.bouncycastle.util; public class StoreException extends RuntimeException { private Throwable _e; public StoreException(String s, Throwable e) { super(s); _e = e; } public Throwable getCause() { return _e; } } bouncycastle-1.49.orig/src/org/bouncycastle/util/test/0000755000175000017500000000000012152033551022433 5ustar ebourgebourgbouncycastle-1.49.orig/src/org/bouncycastle/util/test/Test.java0000644000175000017500000000016010262753174024224 0ustar ebourgebourgpackage org.bouncycastle.util.test; public interface Test { String getName(); TestResult perform(); } bouncycastle-1.49.orig/src/org/bouncycastle/util/test/TestResult.java0000644000175000017500000000026510326637740025432 0ustar ebourgebourgpackage org.bouncycastle.util.test; public interface TestResult { public boolean isSuccessful(); public Throwable getException(); public String toString(); } bouncycastle-1.49.orig/src/org/bouncycastle/util/test/FixedSecureRandom.java0000644000175000017500000000601110460160171026642 0ustar ebourgebourgpackage org.bouncycastle.util.test; import java.io.ByteArrayOutputStream; import java.io.IOException; import java.security.SecureRandom; public class FixedSecureRandom extends SecureRandom { private byte[] _data; private int _index; private int _intPad; public FixedSecureRandom(byte[] value) { this(false, new byte[][] { value }); } public FixedSecureRandom( byte[][] values) { this(false, values); } /** * Pad the data on integer boundaries. This is necessary for the classpath project's BigInteger * implementation. */ public FixedSecureRandom( boolean intPad, byte[] value) { this(intPad, new byte[][] { value }); } /** * Pad the data on integer boundaries. This is necessary for the classpath project's BigInteger * implementation. */ public FixedSecureRandom( boolean intPad, byte[][] values) { ByteArrayOutputStream bOut = new ByteArrayOutputStream(); for (int i = 0; i != values.length; i++) { try { bOut.write(values[i]); } catch (IOException e) { throw new IllegalArgumentException("can't save value array."); } } _data = bOut.toByteArray(); if (intPad) { _intPad = _data.length % 4; } } public void nextBytes(byte[] bytes) { System.arraycopy(_data, _index, bytes, 0, bytes.length); _index += bytes.length; } // // classpath's implementation of SecureRandom doesn't currently go back to nextBytes // when next is called. We can't override next as it's a final method. // public int nextInt() { int val = 0; val |= nextValue() << 24; val |= nextValue() << 16; if (_intPad == 2) { _intPad--; } else { val |= nextValue() << 8; } if (_intPad == 1) { _intPad--; } else { val |= nextValue(); } return val; } // // classpath's implementation of SecureRandom doesn't currently go back to nextBytes // when next is called. We can't override next as it's a final method. // public long nextLong() { long val = 0; val |= (long)nextValue() << 56; val |= (long)nextValue() << 48; val |= (long)nextValue() << 40; val |= (long)nextValue() << 32; val |= (long)nextValue() << 24; val |= (long)nextValue() << 16; val |= (long)nextValue() << 8; val |= (long)nextValue(); return val; } public boolean isExhausted() { return _index == _data.length; } private int nextValue() { return _data[_index++] & 0xff; } } bouncycastle-1.49.orig/src/org/bouncycastle/util/test/SimpleTestResult.java0000644000175000017500000000401510326637740026601 0ustar ebourgebourgpackage org.bouncycastle.util.test; public class SimpleTestResult implements TestResult { private static final String SEPARATOR = System.getProperty("line.separator"); private boolean success; private String message; private Throwable exception; public SimpleTestResult(boolean success, String message) { this.success = success; this.message = message; } public SimpleTestResult(boolean success, String message, Throwable exception) { this.success = success; this.message = message; this.exception = exception; } public static TestResult successful( Test test, String message) { return new SimpleTestResult(true, test.getName() + ": " + message); } public static TestResult failed( Test test, String message) { return new SimpleTestResult(false, test.getName() + ": " + message); } public static TestResult failed( Test test, String message, Throwable t) { return new SimpleTestResult(false, test.getName() + ": " + message, t); } public static TestResult failed( Test test, String message, Object expected, Object found) { return failed(test, message + SEPARATOR + "Expected: " + expected + SEPARATOR + "Found : " + found); } public static String failedMessage(String algorithm, String testName, String expected, String actual) { StringBuffer sb = new StringBuffer(algorithm); sb.append(" failing ").append(testName); sb.append(SEPARATOR).append(" expected: ").append(expected); sb.append(SEPARATOR).append(" got : ").append(actual); return sb.toString(); } public boolean isSuccessful() { return success; } public String toString() { return message; } public Throwable getException() { return exception; } } bouncycastle-1.49.orig/src/org/bouncycastle/util/test/UncloseableOutputStream.java0000644000175000017500000000100010527772456030140 0ustar ebourgebourgpackage org.bouncycastle.util.test; import java.io.FilterOutputStream; import java.io.IOException; import java.io.OutputStream; public class UncloseableOutputStream extends FilterOutputStream { public UncloseableOutputStream(OutputStream s) { super(s); } public void close() { throw new RuntimeException("close() called on UncloseableOutputStream"); } public void write(byte[] b, int off, int len) throws IOException { out.write(b, off, len); } } bouncycastle-1.49.orig/src/org/bouncycastle/util/test/TestFailedException.java0000644000175000017500000000047110326637740027216 0ustar ebourgebourgpackage org.bouncycastle.util.test; public class TestFailedException extends RuntimeException { private TestResult _result; public TestFailedException( TestResult result) { _result = result; } public TestResult getResult() { return _result; } } bouncycastle-1.49.orig/src/org/bouncycastle/util/test/NumberParsing.java0000644000175000017500000000140610262753174026065 0ustar ebourgebourgpackage org.bouncycastle.util.test; /** * Parsing */ public final class NumberParsing { private NumberParsing() { // Hide constructor } public static long decodeLongFromHex(String longAsString) { if ((longAsString.charAt(1) == 'x') || (longAsString.charAt(1) == 'X')) { return Long.parseLong(longAsString.substring(2), 16); } return Long.parseLong(longAsString, 16); } public static int decodeIntFromHex(String intAsString) { if ((intAsString.charAt(1) == 'x') || (intAsString.charAt(1) == 'X')) { return Integer.parseInt(intAsString.substring(2), 16); } return Integer.parseInt(intAsString, 16); } } bouncycastle-1.49.orig/src/org/bouncycastle/util/test/package.html0000644000175000017500000000013510262753174024725 0ustar ebourgebourg Light weight test API. If you can use Junit! bouncycastle-1.49.orig/src/org/bouncycastle/util/test/SimpleTest.java0000644000175000017500000000344310355150016025372 0ustar ebourgebourgpackage org.bouncycastle.util.test; import java.io.PrintStream; import org.bouncycastle.util.Arrays; public abstract class SimpleTest implements Test { public abstract String getName(); private TestResult success() { return SimpleTestResult.successful(this, "Okay"); } protected void fail( String message) { throw new TestFailedException(SimpleTestResult.failed(this, message)); } protected void fail( String message, Throwable throwable) { throw new TestFailedException(SimpleTestResult.failed(this, message, throwable)); } protected void fail( String message, Object expected, Object found) { throw new TestFailedException(SimpleTestResult.failed(this, message, expected, found)); } protected boolean areEqual( byte[] a, byte[] b) { return Arrays.areEqual(a, b); } public TestResult perform() { try { performTest(); return success(); } catch (TestFailedException e) { return e.getResult(); } catch (Exception e) { return SimpleTestResult.failed(this, "Exception: " + e, e); } } protected static void runTest( Test test) { runTest(test, System.out); } protected static void runTest( Test test, PrintStream out) { TestResult result = test.perform(); out.println(result.toString()); if (result.getException() != null) { result.getException().printStackTrace(out); } } public abstract void performTest() throws Exception; } bouncycastle-1.49.orig/src/org/bouncycastle/util/Integers.java0000644000175000017500000000023212103440213024065 0ustar ebourgebourgpackage org.bouncycastle.util; public class Integers { public static Integer valueOf(int value) { return Integer.valueOf(value); } } bouncycastle-1.49.orig/src/org/bouncycastle/util/StreamParsingException.java0000644000175000017500000000044510523226157026766 0ustar ebourgebourgpackage org.bouncycastle.util; public class StreamParsingException extends Exception { Throwable _e; public StreamParsingException(String message, Throwable e) { super(message); _e = e; } public Throwable getCause() { return _e; } } bouncycastle-1.49.orig/src/org/bouncycastle/util/io/0000755000175000017500000000000012152033551022063 5ustar ebourgebourgbouncycastle-1.49.orig/src/org/bouncycastle/util/io/TeeInputStream.java0000644000175000017500000000213211576336733025656 0ustar ebourgebourgpackage org.bouncycastle.util.io; import java.io.IOException; import java.io.InputStream; import java.io.OutputStream; public class TeeInputStream extends InputStream { private final InputStream input; private final OutputStream output; public TeeInputStream(InputStream input, OutputStream output) { this.input = input; this.output = output; } public int read(byte[] buf) throws IOException { return read(buf, 0, buf.length); } public int read(byte[] buf, int off, int len) throws IOException { int i = input.read(buf, off, len); if (i > 0) { output.write(buf, off, i); } return i; } public int read() throws IOException { int i = input.read(); if (i >= 0) { output.write(i); } return i; } public void close() throws IOException { this.input.close(); this.output.close(); } public OutputStream getOutputStream() { return output; } } bouncycastle-1.49.orig/src/org/bouncycastle/util/io/pem/0000755000175000017500000000000012152033551022644 5ustar ebourgebourgbouncycastle-1.49.orig/src/org/bouncycastle/util/io/pem/PemReader.java0000644000175000017500000000365711571363625025402 0ustar ebourgebourgpackage org.bouncycastle.util.io.pem; import java.io.BufferedReader; import java.io.IOException; import java.io.Reader; import java.util.ArrayList; import java.util.List; import org.bouncycastle.util.encoders.Base64; public class PemReader extends BufferedReader { private static final String BEGIN = "-----BEGIN "; private static final String END = "-----END "; public PemReader(Reader reader) { super(reader); } public PemObject readPemObject() throws IOException { String line = readLine(); while (line != null && !line.startsWith(BEGIN)) { line = readLine(); } if (line != null) { line = line.substring(BEGIN.length()); int index = line.indexOf('-'); String type = line.substring(0, index); if (index > 0) { return loadObject(type); } } return null; } private PemObject loadObject(String type) throws IOException { String line; String endMarker = END + type; StringBuffer buf = new StringBuffer(); List headers = new ArrayList(); while ((line = readLine()) != null) { if (line.indexOf(":") >= 0) { int index = line.indexOf(':'); String hdr = line.substring(0, index); String value = line.substring(index + 1).trim(); headers.add(new PemHeader(hdr, value)); continue; } if (line.indexOf(endMarker) != -1) { break; } buf.append(line.trim()); } if (line == null) { throw new IOException(endMarker + " not found"); } return new PemObject(type, headers, Base64.decode(buf.toString())); } } bouncycastle-1.49.orig/src/org/bouncycastle/util/io/pem/PemObjectParser.java0000644000175000017500000000025711442065640026545 0ustar ebourgebourgpackage org.bouncycastle.util.io.pem; import java.io.IOException; public interface PemObjectParser { Object parseObject(PemObject obj) throws IOException; } bouncycastle-1.49.orig/src/org/bouncycastle/util/io/pem/PemObjectGenerator.java0000644000175000017500000000021711442065640027233 0ustar ebourgebourgpackage org.bouncycastle.util.io.pem; public interface PemObjectGenerator { PemObject generate() throws PemGenerationException; } bouncycastle-1.49.orig/src/org/bouncycastle/util/io/pem/PemObject.java0000644000175000017500000000247711442065640025376 0ustar ebourgebourgpackage org.bouncycastle.util.io.pem; import java.util.ArrayList; import java.util.Collections; import java.util.List; public class PemObject implements PemObjectGenerator { private static final List EMPTY_LIST = Collections.unmodifiableList(new ArrayList()); private String type; private List headers; private byte[] content; /** * Generic constructor for object without headers. * * @param type pem object type. * @param content the binary content of the object. */ public PemObject(String type, byte[] content) { this(type, EMPTY_LIST, content); } /** * Generic constructor for object with headers. * * @param type pem object type. * @param headers a list of PemHeader objects. * @param content the binary content of the object. */ public PemObject(String type, List headers, byte[] content) { this.type = type; this.headers = Collections.unmodifiableList(headers); this.content = content; } public String getType() { return type; } public List getHeaders() { return headers; } public byte[] getContent() { return content; } public PemObject generate() throws PemGenerationException { return this; } } bouncycastle-1.49.orig/src/org/bouncycastle/util/io/pem/PemGenerationException.java0000644000175000017500000000067711442065640030142 0ustar ebourgebourgpackage org.bouncycastle.util.io.pem; import java.io.IOException; public class PemGenerationException extends IOException { private Throwable cause; public PemGenerationException(String message, Throwable cause) { super(message); this.cause = cause; } public PemGenerationException(String message) { super(message); } public Throwable getCause() { return cause; } } bouncycastle-1.49.orig/src/org/bouncycastle/util/io/pem/PemWriter.java0000644000175000017500000000645111442065640025440 0ustar ebourgebourgpackage org.bouncycastle.util.io.pem; import java.io.BufferedWriter; import java.io.IOException; import java.io.Writer; import java.util.Iterator; import org.bouncycastle.util.encoders.Base64; /** * A generic PEM writer, based on RFC 1421 */ public class PemWriter extends BufferedWriter { private static final int LINE_LENGTH = 64; private final int nlLength; private char[] buf = new char[LINE_LENGTH]; /** * Base constructor. * * @param out output stream to use. */ public PemWriter(Writer out) { super(out); String nl = System.getProperty("line.separator"); if (nl != null) { nlLength = nl.length(); } else { nlLength = 2; } } /** * Return the number of bytes or characters required to contain the * passed in object if it is PEM encoded. * * @param obj pem object to be output * @return an estimate of the number of bytes */ public int getOutputSize(PemObject obj) { // BEGIN and END boundaries. int size = (2 * (obj.getType().length() + 10 + nlLength)) + 6 + 4; if (!obj.getHeaders().isEmpty()) { for (Iterator it = obj.getHeaders().iterator(); it.hasNext();) { PemHeader hdr = (PemHeader)it.next(); size += hdr.getName().length() + ": ".length() + hdr.getValue().length() + nlLength; } size += nlLength; } // base64 encoding int dataLen = ((obj.getContent().length + 2) / 3) * 4; size += dataLen + (((dataLen + LINE_LENGTH - 1) / LINE_LENGTH) * nlLength); return size; } public void writeObject(PemObjectGenerator objGen) throws IOException { PemObject obj = objGen.generate(); writePreEncapsulationBoundary(obj.getType()); if (!obj.getHeaders().isEmpty()) { for (Iterator it = obj.getHeaders().iterator(); it.hasNext();) { PemHeader hdr = (PemHeader)it.next(); this.write(hdr.getName()); this.write(": "); this.write(hdr.getValue()); this.newLine(); } this.newLine(); } writeEncoded(obj.getContent()); writePostEncapsulationBoundary(obj.getType()); } private void writeEncoded(byte[] bytes) throws IOException { bytes = Base64.encode(bytes); for (int i = 0; i < bytes.length; i += buf.length) { int index = 0; while (index != buf.length) { if ((i + index) >= bytes.length) { break; } buf[index] = (char)bytes[i + index]; index++; } this.write(buf, 0, index); this.newLine(); } } private void writePreEncapsulationBoundary( String type) throws IOException { this.write("-----BEGIN " + type + "-----"); this.newLine(); } private void writePostEncapsulationBoundary( String type) throws IOException { this.write("-----END " + type + "-----"); this.newLine(); } } bouncycastle-1.49.orig/src/org/bouncycastle/util/io/pem/PemHeader.java0000644000175000017500000000216611442065640025353 0ustar ebourgebourgpackage org.bouncycastle.util.io.pem; public class PemHeader { private String name; private String value; public PemHeader(String name, String value) { this.name = name; this.value = value; } public String getName() { return name; } public String getValue() { return value; } public int hashCode() { return getHashCode(this.name) + 31 * getHashCode(this.value); } public boolean equals(Object o) { if (!(o instanceof PemHeader)) { return false; } PemHeader other = (PemHeader)o; return other == this || (isEqual(this.name, other.name) && isEqual(this.value, other.value)); } private int getHashCode(String s) { if (s == null) { return 1; } return s.hashCode(); } private boolean isEqual(String s1, String s2) { if (s1 == s2) { return true; } if (s1 == null || s2 == null) { return false; } return s1.equals(s2); } } bouncycastle-1.49.orig/src/org/bouncycastle/util/io/TeeOutputStream.java0000644000175000017500000000204711442065640026050 0ustar ebourgebourgpackage org.bouncycastle.util.io; import java.io.IOException; import java.io.OutputStream; public class TeeOutputStream extends OutputStream { private OutputStream output1; private OutputStream output2; public TeeOutputStream(OutputStream output1, OutputStream output2) { this.output1 = output1; this.output2 = output2; } public void write(byte[] buf) throws IOException { this.output1.write(buf); this.output2.write(buf); } public void write(byte[] buf, int off, int len) throws IOException { this.output1.write(buf, off, len); this.output2.write(buf, off, len); } public void write(int b) throws IOException { this.output1.write(b); this.output2.write(b); } public void flush() throws IOException { this.output1.flush(); this.output2.flush(); } public void close() throws IOException { this.output1.close(); this.output2.close(); } }bouncycastle-1.49.orig/src/org/bouncycastle/util/io/Streams.java0000644000175000017500000000437211272212216024351 0ustar ebourgebourgpackage org.bouncycastle.util.io; import java.io.ByteArrayOutputStream; import java.io.IOException; import java.io.InputStream; import java.io.OutputStream; public final class Streams { private static int BUFFER_SIZE = 512; public static void drain(InputStream inStr) throws IOException { byte[] bs = new byte[BUFFER_SIZE]; while (inStr.read(bs, 0, bs.length) >= 0) { } } public static byte[] readAll(InputStream inStr) throws IOException { ByteArrayOutputStream buf = new ByteArrayOutputStream(); pipeAll(inStr, buf); return buf.toByteArray(); } public static byte[] readAllLimited(InputStream inStr, int limit) throws IOException { ByteArrayOutputStream buf = new ByteArrayOutputStream(); pipeAllLimited(inStr, limit, buf); return buf.toByteArray(); } public static int readFully(InputStream inStr, byte[] buf) throws IOException { return readFully(inStr, buf, 0, buf.length); } public static int readFully(InputStream inStr, byte[] buf, int off, int len) throws IOException { int totalRead = 0; while (totalRead < len) { int numRead = inStr.read(buf, off + totalRead, len - totalRead); if (numRead < 0) { break; } totalRead += numRead; } return totalRead; } public static void pipeAll(InputStream inStr, OutputStream outStr) throws IOException { byte[] bs = new byte[BUFFER_SIZE]; int numRead; while ((numRead = inStr.read(bs, 0, bs.length)) >= 0) { outStr.write(bs, 0, numRead); } } public static long pipeAllLimited(InputStream inStr, long limit, OutputStream outStr) throws IOException { long total = 0; byte[] bs = new byte[BUFFER_SIZE]; int numRead; while ((numRead = inStr.read(bs, 0, bs.length)) >= 0) { total += numRead; if (total > limit) { throw new StreamOverflowException("Data Overflow"); } outStr.write(bs, 0, numRead); } return total; } } bouncycastle-1.49.orig/src/org/bouncycastle/util/io/StreamOverflowException.java0000644000175000017500000000032011442065640027564 0ustar ebourgebourgpackage org.bouncycastle.util.io; import java.io.IOException; public class StreamOverflowException extends IOException { public StreamOverflowException(String msg) { super(msg); } } bouncycastle-1.49.orig/src/org/bouncycastle/util/StreamParser.java0000644000175000017500000000031210522776100024726 0ustar ebourgebourgpackage org.bouncycastle.util; import java.util.Collection; public interface StreamParser { Object read() throws StreamParsingException; Collection readAll() throws StreamParsingException; } bouncycastle-1.49.orig/src/org/bouncycastle/util/Memoable.java0000644000175000017500000000157212143617211024046 0ustar ebourgebourgpackage org.bouncycastle.util; public interface Memoable { /** * Produce a copy of this object with its configuration and in its current state. *

    * The returned object may be used simply to store the state, or may be used as a similar object * starting from the copied state. */ public Memoable copy(); /** * Restore a copied object state into this object. *

    * Implementations of this method should try to avoid or minimise memory allocation to perform the reset. * * @param other an object originally {@link #copy() copied} from an object of the same type as this instance. * @throws ClassCastException if the provided object is not of the correct type. * @throws MemoableResetException if the other parameter is in some other way invalid. */ public void reset(Memoable other); } bouncycastle-1.49.orig/src/org/bouncycastle/util/IPAddress.java0000644000175000017500000001117011040273002024125 0ustar ebourgebourgpackage org.bouncycastle.util; public class IPAddress { /** * Validate the given IPv4 or IPv6 address. * * @param address the IP address as a String. * * @return true if a valid address, false otherwise */ public static boolean isValid( String address) { return isValidIPv4(address) || isValidIPv6(address); } /** * Validate the given IPv4 or IPv6 address and netmask. * * @param address the IP address as a String. * * @return true if a valid address with netmask, false otherwise */ public static boolean isValidWithNetMask( String address) { return isValidIPv4WithNetmask(address) || isValidIPv6WithNetmask(address); } /** * Validate the given IPv4 address. * * @param address the IP address as a String. * * @return true if a valid IPv4 address, false otherwise */ public static boolean isValidIPv4( String address) { if (address.length() == 0) { return false; } int octet; int octets = 0; String temp = address+"."; int pos; int start = 0; while (start < temp.length() && (pos = temp.indexOf('.', start)) > start) { if (octets == 4) { return false; } try { octet = Integer.parseInt(temp.substring(start, pos)); } catch (NumberFormatException ex) { return false; } if (octet < 0 || octet > 255) { return false; } start = pos + 1; octets++; } return octets == 4; } public static boolean isValidIPv4WithNetmask( String address) { int index = address.indexOf("/"); String mask = address.substring(index + 1); return (index > 0) && isValidIPv4(address.substring(0, index)) && (isValidIPv4(mask) || isMaskValue(mask, 32)); } public static boolean isValidIPv6WithNetmask( String address) { int index = address.indexOf("/"); String mask = address.substring(index + 1); return (index > 0) && (isValidIPv6(address.substring(0, index)) && (isValidIPv6(mask) || isMaskValue(mask, 128))); } private static boolean isMaskValue(String component, int size) { try { int value = Integer.parseInt(component); return value >= 0 && value <= size; } catch (NumberFormatException e) { return false; } } /** * Validate the given IPv6 address. * * @param address the IP address as a String. * * @return true if a valid IPv4 address, false otherwise */ public static boolean isValidIPv6( String address) { if (address.length() == 0) { return false; } int octet; int octets = 0; String temp = address + ":"; boolean doubleColonFound = false; int pos; int start = 0; while (start < temp.length() && (pos = temp.indexOf(':', start)) >= start) { if (octets == 8) { return false; } if (start != pos) { String value = temp.substring(start, pos); if (pos == (temp.length() - 1) && value.indexOf('.') > 0) { if (!isValidIPv4(value)) { return false; } octets++; // add an extra one as address covers 2 words. } else { try { octet = Integer.parseInt(temp.substring(start, pos), 16); } catch (NumberFormatException ex) { return false; } if (octet < 0 || octet > 0xffff) { return false; } } } else { if (pos != 1 && pos != temp.length() - 1 && doubleColonFound) { return false; } doubleColonFound = true; } start = pos + 1; octets++; } return octets == 8 || doubleColonFound; } } bouncycastle-1.49.orig/src/org/bouncycastle/util/Arrays.java0000644000175000017500000003375512151251423023574 0ustar ebourgebourgpackage org.bouncycastle.util; import java.math.BigInteger; /** * General array utilities. */ public final class Arrays { private Arrays() { // static class, hide constructor } public static boolean areEqual( boolean[] a, boolean[] b) { if (a == b) { return true; } if (a == null || b == null) { return false; } if (a.length != b.length) { return false; } for (int i = 0; i != a.length; i++) { if (a[i] != b[i]) { return false; } } return true; } public static boolean areEqual( char[] a, char[] b) { if (a == b) { return true; } if (a == null || b == null) { return false; } if (a.length != b.length) { return false; } for (int i = 0; i != a.length; i++) { if (a[i] != b[i]) { return false; } } return true; } public static boolean areEqual( byte[] a, byte[] b) { if (a == b) { return true; } if (a == null || b == null) { return false; } if (a.length != b.length) { return false; } for (int i = 0; i != a.length; i++) { if (a[i] != b[i]) { return false; } } return true; } /** * A constant time equals comparison - does not terminate early if * test will fail. * * @param a first array * @param b second array * @return true if arrays equal, false otherwise. */ public static boolean constantTimeAreEqual( byte[] a, byte[] b) { if (a == b) { return true; } if (a == null || b == null) { return false; } if (a.length != b.length) { return false; } int nonEqual = 0; for (int i = 0; i != a.length; i++) { nonEqual |= (a[i] ^ b[i]); } return nonEqual == 0; } public static boolean areEqual( int[] a, int[] b) { if (a == b) { return true; } if (a == null || b == null) { return false; } if (a.length != b.length) { return false; } for (int i = 0; i != a.length; i++) { if (a[i] != b[i]) { return false; } } return true; } public static boolean areEqual( long[] a, long[] b) { if (a == b) { return true; } if (a == null || b == null) { return false; } if (a.length != b.length) { return false; } for (int i = 0; i != a.length; i++) { if (a[i] != b[i]) { return false; } } return true; } public static boolean areEqual( BigInteger[] a, BigInteger[] b) { if (a == b) { return true; } if (a == null || b == null) { return false; } if (a.length != b.length) { return false; } for (int i = 0; i != a.length; i++) { if (!a[i].equals(b[i])) { return false; } } return true; } public static void fill( byte[] array, byte value) { for (int i = 0; i < array.length; i++) { array[i] = value; } } public static void fill( char[] array, char value) { for (int i = 0; i < array.length; i++) { array[i] = value; } } public static void fill( long[] array, long value) { for (int i = 0; i < array.length; i++) { array[i] = value; } } public static void fill( short[] array, short value) { for (int i = 0; i < array.length; i++) { array[i] = value; } } public static void fill( int[] array, int value) { for (int i = 0; i < array.length; i++) { array[i] = value; } } public static int hashCode(byte[] data) { if (data == null) { return 0; } int i = data.length; int hc = i + 1; while (--i >= 0) { hc *= 257; hc ^= data[i]; } return hc; } public static int hashCode(char[] data) { if (data == null) { return 0; } int i = data.length; int hc = i + 1; while (--i >= 0) { hc *= 257; hc ^= data[i]; } return hc; } public static int hashCode(int[][] ints) { int hc = 0; for (int i = 0; i != ints.length; i++) { hc = hc * 257 + hashCode(ints[i]); } return hc; } public static int hashCode(int[] data) { if (data == null) { return 0; } int i = data.length; int hc = i + 1; while (--i >= 0) { hc *= 257; hc ^= data[i]; } return hc; } public static int hashCode(short[][][] shorts) { int hc = 0; for (int i = 0; i != shorts.length; i++) { hc = hc * 257 + hashCode(shorts[i]); } return hc; } public static int hashCode(short[][] shorts) { int hc = 0; for (int i = 0; i != shorts.length; i++) { hc = hc * 257 + hashCode(shorts[i]); } return hc; } public static int hashCode(short[] data) { if (data == null) { return 0; } int i = data.length; int hc = i + 1; while (--i >= 0) { hc *= 257; hc ^= (data[i] & 0xff); } return hc; } public static int hashCode(BigInteger[] data) { if (data == null) { return 0; } int i = data.length; int hc = i + 1; while (--i >= 0) { hc *= 257; hc ^= data[i].hashCode(); } return hc; } public static byte[] clone(byte[] data) { if (data == null) { return null; } byte[] copy = new byte[data.length]; System.arraycopy(data, 0, copy, 0, data.length); return copy; } public static byte[][] clone(byte[][] data) { if (data == null) { return null; } byte[][] copy = new byte[data.length][]; for (int i = 0; i != copy.length; i++) { copy[i] = clone(data[i]); } return copy; } public static byte[][][] clone(byte[][][] data) { if (data == null) { return null; } byte[][][] copy = new byte[data.length][][]; for (int i = 0; i != copy.length; i++) { copy[i] = clone(data[i]); } return copy; } public static int[] clone(int[] data) { if (data == null) { return null; } int[] copy = new int[data.length]; System.arraycopy(data, 0, copy, 0, data.length); return copy; } public static short[] clone(short[] data) { if (data == null) { return null; } short[] copy = new short[data.length]; System.arraycopy(data, 0, copy, 0, data.length); return copy; } public static BigInteger[] clone(BigInteger[] data) { if (data == null) { return null; } BigInteger[] copy = new BigInteger[data.length]; System.arraycopy(data, 0, copy, 0, data.length); return copy; } public static byte[] copyOf(byte[] data, int newLength) { byte[] tmp = new byte[newLength]; if (newLength < data.length) { System.arraycopy(data, 0, tmp, 0, newLength); } else { System.arraycopy(data, 0, tmp, 0, data.length); } return tmp; } public static char[] copyOf(char[] data, int newLength) { char[] tmp = new char[newLength]; if (newLength < data.length) { System.arraycopy(data, 0, tmp, 0, newLength); } else { System.arraycopy(data, 0, tmp, 0, data.length); } return tmp; } public static int[] copyOf(int[] data, int newLength) { int[] tmp = new int[newLength]; if (newLength < data.length) { System.arraycopy(data, 0, tmp, 0, newLength); } else { System.arraycopy(data, 0, tmp, 0, data.length); } return tmp; } public static long[] copyOf(long[] data, int newLength) { long[] tmp = new long[newLength]; if (newLength < data.length) { System.arraycopy(data, 0, tmp, 0, newLength); } else { System.arraycopy(data, 0, tmp, 0, data.length); } return tmp; } public static BigInteger[] copyOf(BigInteger[] data, int newLength) { BigInteger[] tmp = new BigInteger[newLength]; if (newLength < data.length) { System.arraycopy(data, 0, tmp, 0, newLength); } else { System.arraycopy(data, 0, tmp, 0, data.length); } return tmp; } public static byte[] copyOfRange(byte[] data, int from, int to) { int newLength = getLength(from, to); byte[] tmp = new byte[newLength]; if (data.length - from < newLength) { System.arraycopy(data, from, tmp, 0, data.length - from); } else { System.arraycopy(data, from, tmp, 0, newLength); } return tmp; } public static int[] copyOfRange(int[] data, int from, int to) { int newLength = getLength(from, to); int[] tmp = new int[newLength]; if (data.length - from < newLength) { System.arraycopy(data, from, tmp, 0, data.length - from); } else { System.arraycopy(data, from, tmp, 0, newLength); } return tmp; } public static long[] copyOfRange(long[] data, int from, int to) { int newLength = getLength(from, to); long[] tmp = new long[newLength]; if (data.length - from < newLength) { System.arraycopy(data, from, tmp, 0, data.length - from); } else { System.arraycopy(data, from, tmp, 0, newLength); } return tmp; } public static BigInteger[] copyOfRange(BigInteger[] data, int from, int to) { int newLength = getLength(from, to); BigInteger[] tmp = new BigInteger[newLength]; if (data.length - from < newLength) { System.arraycopy(data, from, tmp, 0, data.length - from); } else { System.arraycopy(data, from, tmp, 0, newLength); } return tmp; } private static int getLength(int from, int to) { int newLength = to - from; if (newLength < 0) { StringBuffer sb = new StringBuffer(from); sb.append(" > ").append(to); throw new IllegalArgumentException(sb.toString()); } return newLength; } public static byte[] concatenate(byte[] a, byte[] b) { if (a != null && b != null) { byte[] rv = new byte[a.length + b.length]; System.arraycopy(a, 0, rv, 0, a.length); System.arraycopy(b, 0, rv, a.length, b.length); return rv; } else if (b != null) { return clone(b); } else { return clone(a); } } public static byte[] concatenate(byte[] a, byte[] b, byte[] c) { if (a != null && b != null && c != null) { byte[] rv = new byte[a.length + b.length + c.length]; System.arraycopy(a, 0, rv, 0, a.length); System.arraycopy(b, 0, rv, a.length, b.length); System.arraycopy(c, 0, rv, a.length + b.length, c.length); return rv; } else if (b == null) { return concatenate(a, c); } else { return concatenate(a, b); } } public static byte[] concatenate(byte[] a, byte[] b, byte[] c, byte[] d) { if (a != null && b != null && c != null && d != null) { byte[] rv = new byte[a.length + b.length + c.length + d.length]; System.arraycopy(a, 0, rv, 0, a.length); System.arraycopy(b, 0, rv, a.length, b.length); System.arraycopy(c, 0, rv, a.length + b.length, c.length); System.arraycopy(d, 0, rv, a.length + b.length + c.length, d.length); return rv; } else if (d == null) { return concatenate(a, b, c); } else if (c == null) { return concatenate(a, b, d); } else if (b == null) { return concatenate(a, c, d); } else { return concatenate(b, c, d); } } } bouncycastle-1.49.orig/src/org/bouncycastle/util/BigIntegers.java0000644000175000017500000000643212057746473024550 0ustar ebourgebourgpackage org.bouncycastle.util; import java.math.BigInteger; import java.security.SecureRandom; /** * BigInteger utilities. */ public final class BigIntegers { private static final int MAX_ITERATIONS = 1000; private static final BigInteger ZERO = BigInteger.valueOf(0); /** * Return the passed in value as an unsigned byte array. * * @param value value to be converted. * @return a byte array without a leading zero byte if present in the signed encoding. */ public static byte[] asUnsignedByteArray( BigInteger value) { byte[] bytes = value.toByteArray(); if (bytes[0] == 0) { byte[] tmp = new byte[bytes.length - 1]; System.arraycopy(bytes, 1, tmp, 0, tmp.length); return tmp; } return bytes; } /** * Return the passed in value as an unsigned byte array. * * @param value value to be converted. * @return a byte array without a leading zero byte if present in the signed encoding. */ public static byte[] asUnsignedByteArray( int length, BigInteger value) { byte[] bytes = value.toByteArray(); if (bytes[0] == 0) { if (bytes.length - 1 > length) { throw new IllegalArgumentException("standard length exceeded for value"); } byte[] tmp = new byte[length]; System.arraycopy(bytes, 1, tmp, tmp.length - (bytes.length - 1), bytes.length - 1); return tmp; } else { if (bytes.length == length) { return bytes; } if (bytes.length > length) { throw new IllegalArgumentException("standard length exceeded for value"); } byte[] tmp = new byte[length]; System.arraycopy(bytes, 0, tmp, tmp.length - bytes.length, bytes.length); return tmp; } } /** * Return a random BigInteger not less than 'min' and not greater than 'max' * * @param min the least value that may be generated * @param max the greatest value that may be generated * @param random the source of randomness * @return a random BigInteger value in the range [min,max] */ public static BigInteger createRandomInRange( BigInteger min, BigInteger max, SecureRandom random) { int cmp = min.compareTo(max); if (cmp >= 0) { if (cmp > 0) { throw new IllegalArgumentException("'min' may not be greater than 'max'"); } return min; } if (min.bitLength() > max.bitLength() / 2) { return createRandomInRange(ZERO, max.subtract(min), random).add(min); } for (int i = 0; i < MAX_ITERATIONS; ++i) { BigInteger x = new BigInteger(max.bitLength(), random); if (x.compareTo(min) >= 0 && x.compareTo(max) <= 0) { return x; } } // fall back to a faster (restricted) method return new BigInteger(max.subtract(min).bitLength() - 1, random).add(min); } } bouncycastle-1.49.orig/src/org/bouncycastle/cert/0000755000175000017500000000000012152033551021434 5ustar ebourgebourgbouncycastle-1.49.orig/src/org/bouncycastle/cert/CertException.java0000644000175000017500000000070511501603563025060 0ustar ebourgebourgpackage org.bouncycastle.cert; /** * General checked Exception thrown in the cert package and its sub-packages. */ public class CertException extends Exception { private Throwable cause; public CertException(String msg, Throwable cause) { super(msg); this.cause = cause; } public CertException(String msg) { super(msg); } public Throwable getCause() { return cause; } } bouncycastle-1.49.orig/src/org/bouncycastle/cert/crmf/0000755000175000017500000000000012152033551022363 5ustar ebourgebourgbouncycastle-1.49.orig/src/org/bouncycastle/cert/crmf/ValueDecryptorGenerator.java0000644000175000017500000000050611442065637030061 0ustar ebourgebourgpackage org.bouncycastle.cert.crmf; import org.bouncycastle.asn1.x509.AlgorithmIdentifier; import org.bouncycastle.operator.InputDecryptor; public interface ValueDecryptorGenerator { InputDecryptor getValueDecryptor(AlgorithmIdentifier keyAlg, AlgorithmIdentifier symmAlg, byte[] encKey) throws CRMFException; } bouncycastle-1.49.orig/src/org/bouncycastle/cert/crmf/Control.java0000644000175000017500000000105011503763036024651 0ustar ebourgebourgpackage org.bouncycastle.cert.crmf; import org.bouncycastle.asn1.ASN1Encodable; import org.bouncycastle.asn1.ASN1ObjectIdentifier; /** * Generic interface for a CertificateRequestMessage control value. */ public interface Control { /** * Return the type of this control. * * @return an ASN1ObjectIdentifier representing the type. */ ASN1ObjectIdentifier getType(); /** * Return the value contained in this control object. * * @return the value of the control. */ ASN1Encodable getValue(); } bouncycastle-1.49.orig/src/org/bouncycastle/cert/crmf/FixedLengthMGF1Padder.java0000644000175000017500000000616711732523747027212 0ustar ebourgebourgpackage org.bouncycastle.cert.crmf; import java.security.SecureRandom; import org.bouncycastle.crypto.Digest; import org.bouncycastle.crypto.digests.SHA1Digest; import org.bouncycastle.crypto.generators.MGF1BytesGenerator; import org.bouncycastle.crypto.params.MGFParameters; /** * An encrypted value padder that uses MGF1 as the basis of the padding. */ public class FixedLengthMGF1Padder implements EncryptedValuePadder { private int length; private SecureRandom random; private Digest dig = new SHA1Digest(); /** * Create a padder to so that padded output will always be at least * length bytes long. * * @param length fixed length for padded output. */ public FixedLengthMGF1Padder(int length) { this(length, null); } /** * Create a padder to so that padded output will always be at least * length bytes long, using the passed in source of randomness to * provide the random material for the padder. * * @param length fixed length for padded output. * @param random a source of randomness. */ public FixedLengthMGF1Padder(int length, SecureRandom random) { this.length = length; this.random = random; } public byte[] getPaddedData(byte[] data) { byte[] bytes = new byte[length]; byte[] seed = new byte[dig.getDigestSize()]; byte[] mask = new byte[length - dig.getDigestSize()]; if (random == null) { random = new SecureRandom(); } random.nextBytes(seed); MGF1BytesGenerator maskGen = new MGF1BytesGenerator(dig); maskGen.init(new MGFParameters(seed)); maskGen.generateBytes(mask, 0, mask.length); System.arraycopy(seed, 0, bytes, 0, seed.length); System.arraycopy(data, 0, bytes, seed.length, data.length); for (int i = seed.length + data.length + 1; i != bytes.length; i++) { bytes[i] = (byte)(1 + random.nextInt(255)); } for (int i = 0; i != mask.length; i++) { bytes[i + seed.length] ^= mask[i]; } return bytes; } public byte[] getUnpaddedData(byte[] paddedData) { byte[] seed = new byte[dig.getDigestSize()]; byte[] mask = new byte[length - dig.getDigestSize()]; System.arraycopy(paddedData, 0, seed, 0, seed.length); MGF1BytesGenerator maskGen = new MGF1BytesGenerator(dig); maskGen.init(new MGFParameters(seed)); maskGen.generateBytes(mask, 0, mask.length); for (int i = 0; i != mask.length; i++) { paddedData[i + seed.length] ^= mask[i]; } int end = 0; for (int i = paddedData.length - 1; i != seed.length; i--) { if (paddedData[i] == 0) { end = i; break; } } if (end == 0) { throw new IllegalStateException("bad padding in encoding"); } byte[] data = new byte[end - seed.length]; System.arraycopy(paddedData, seed.length, data, 0, data.length); return data; } } bouncycastle-1.49.orig/src/org/bouncycastle/cert/crmf/PKMACValuesCalculator.java0000644000175000017500000000060711442065637027271 0ustar ebourgebourgpackage org.bouncycastle.cert.crmf; import org.bouncycastle.asn1.x509.AlgorithmIdentifier; public interface PKMACValuesCalculator { void setup(AlgorithmIdentifier digestAlg, AlgorithmIdentifier macAlg) throws CRMFException; byte[] calculateDigest(byte[] data) throws CRMFException; byte[] calculateMac(byte[] pwd, byte[] data) throws CRMFException; } bouncycastle-1.49.orig/src/org/bouncycastle/cert/crmf/CRMFException.java0000644000175000017500000000045511442065637025653 0ustar ebourgebourgpackage org.bouncycastle.cert.crmf; public class CRMFException extends Exception { private Throwable cause; public CRMFException(String msg, Throwable cause) { super(msg); this.cause = cause; } public Throwable getCause() { return cause; } }bouncycastle-1.49.orig/src/org/bouncycastle/cert/crmf/PKIArchiveControl.java0000644000175000017500000000613611711655564026540 0ustar ebourgebourgpackage org.bouncycastle.cert.crmf; import org.bouncycastle.asn1.ASN1Encodable; import org.bouncycastle.asn1.ASN1ObjectIdentifier; import org.bouncycastle.asn1.cms.CMSObjectIdentifiers; import org.bouncycastle.asn1.cms.ContentInfo; import org.bouncycastle.asn1.cms.EnvelopedData; import org.bouncycastle.asn1.crmf.CRMFObjectIdentifiers; import org.bouncycastle.asn1.crmf.EncryptedKey; import org.bouncycastle.asn1.crmf.PKIArchiveOptions; import org.bouncycastle.cms.CMSEnvelopedData; import org.bouncycastle.cms.CMSException; /** * Carrier for a PKIArchiveOptions structure. */ public class PKIArchiveControl implements Control { public static final int encryptedPrivKey = PKIArchiveOptions.encryptedPrivKey; public static final int keyGenParameters = PKIArchiveOptions.keyGenParameters; public static final int archiveRemGenPrivKey = PKIArchiveOptions.archiveRemGenPrivKey; private static final ASN1ObjectIdentifier type = CRMFObjectIdentifiers.id_regCtrl_pkiArchiveOptions; private final PKIArchiveOptions pkiArchiveOptions; /** * Basic constructor - build from an PKIArchiveOptions structure. * * @param pkiArchiveOptions the ASN.1 structure that will underlie this control. */ public PKIArchiveControl(PKIArchiveOptions pkiArchiveOptions) { this.pkiArchiveOptions = pkiArchiveOptions; } /** * Return the type of this control. * * @return CRMFObjectIdentifiers.id_regCtrl_pkiArchiveOptions */ public ASN1ObjectIdentifier getType() { return type; } /** * Return the underlying ASN.1 object. * * @return a PKIArchiveOptions structure. */ public ASN1Encodable getValue() { return pkiArchiveOptions; } /** * Return the archive control type, one of: encryptedPrivKey,keyGenParameters,or archiveRemGenPrivKey. * * @return the archive control type. */ public int getArchiveType() { return pkiArchiveOptions.getType(); } /** * Return whether this control contains enveloped data. * * @return true if the control contains enveloped data, false otherwise. */ public boolean isEnvelopedData() { EncryptedKey encKey = EncryptedKey.getInstance(pkiArchiveOptions.getValue()); return !encKey.isEncryptedValue(); } /** * Return the enveloped data structure contained in this control. * * @return a CMSEnvelopedData object. */ public CMSEnvelopedData getEnvelopedData() throws CRMFException { try { EncryptedKey encKey = EncryptedKey.getInstance(pkiArchiveOptions.getValue()); EnvelopedData data = EnvelopedData.getInstance(encKey.getValue()); return new CMSEnvelopedData(new ContentInfo(CMSObjectIdentifiers.envelopedData, data)); } catch (CMSException e) { throw new CRMFException("CMS parsing error: " + e.getMessage(), e.getCause()); } catch (Exception e) { throw new CRMFException("CRMF parsing error: " + e.getMessage(), e); } } } bouncycastle-1.49.orig/src/org/bouncycastle/cert/crmf/CRMFRuntimeException.java0000644000175000017500000000050211442065637027210 0ustar ebourgebourgpackage org.bouncycastle.cert.crmf; public class CRMFRuntimeException extends RuntimeException { private Throwable cause; public CRMFRuntimeException(String msg, Throwable cause) { super(msg); this.cause = cause; } public Throwable getCause() { return cause; } }bouncycastle-1.49.orig/src/org/bouncycastle/cert/crmf/EncryptedValueBuilder.java0000644000175000017500000001057211503342074027476 0ustar ebourgebourgpackage org.bouncycastle.cert.crmf; import java.io.ByteArrayOutputStream; import java.io.IOException; import java.io.OutputStream; import org.bouncycastle.asn1.ASN1OctetString; import org.bouncycastle.asn1.DERBitString; import org.bouncycastle.asn1.crmf.EncryptedValue; import org.bouncycastle.asn1.x509.AlgorithmIdentifier; import org.bouncycastle.cert.X509CertificateHolder; import org.bouncycastle.operator.KeyWrapper; import org.bouncycastle.operator.OperatorException; import org.bouncycastle.operator.OutputEncryptor; import org.bouncycastle.util.Strings; /** * Builder for EncryptedValue structures. */ public class EncryptedValueBuilder { private KeyWrapper wrapper; private OutputEncryptor encryptor; private EncryptedValuePadder padder; /** * Create a builder that makes EncryptedValue structures. * * @param wrapper a wrapper for key used to encrypt the actual data contained in the EncryptedValue. * @param encryptor an output encryptor to encrypt the actual data contained in the EncryptedValue. */ public EncryptedValueBuilder(KeyWrapper wrapper, OutputEncryptor encryptor) { this(wrapper, encryptor, null); } /** * Create a builder that makes EncryptedValue structures with fixed length blocks padded using the passed in padder. * * @param wrapper a wrapper for key used to encrypt the actual data contained in the EncryptedValue. * @param encryptor an output encryptor to encrypt the actual data contained in the EncryptedValue. * @param padder a padder to ensure that the EncryptedValue created will always be a constant length. */ public EncryptedValueBuilder(KeyWrapper wrapper, OutputEncryptor encryptor, EncryptedValuePadder padder) { this.wrapper = wrapper; this.encryptor = encryptor; this.padder = padder; } /** * Build an EncryptedValue structure containing the passed in pass phrase. * * @param revocationPassphrase a revocation pass phrase. * @return an EncryptedValue containing the encrypted pass phrase. * @throws CRMFException on a failure to encrypt the data, or wrap the symmetric key for this value. */ public EncryptedValue build(char[] revocationPassphrase) throws CRMFException { return encryptData(padData(Strings.toUTF8ByteArray(revocationPassphrase))); } /** * Build an EncryptedValue structure containing the certificate contained in * the passed in holder. * * @param holder a holder containing a certificate. * @return an EncryptedValue containing the encrypted certificate. * @throws CRMFException on a failure to encrypt the data, or wrap the symmetric key for this value. */ public EncryptedValue build(X509CertificateHolder holder) throws CRMFException { try { return encryptData(padData(holder.getEncoded())); } catch (IOException e) { throw new CRMFException("cannot encode certificate: " + e.getMessage(), e); } } private EncryptedValue encryptData(byte[] data) throws CRMFException { ByteArrayOutputStream bOut = new ByteArrayOutputStream(); OutputStream eOut = encryptor.getOutputStream(bOut); try { eOut.write(data); eOut.close(); } catch (IOException e) { throw new CRMFException("cannot process data: " + e.getMessage(), e); } AlgorithmIdentifier intendedAlg = null; AlgorithmIdentifier symmAlg = encryptor.getAlgorithmIdentifier(); DERBitString encSymmKey; try { wrapper.generateWrappedKey(encryptor.getKey()); encSymmKey = new DERBitString(wrapper.generateWrappedKey(encryptor.getKey())); } catch (OperatorException e) { throw new CRMFException("cannot wrap key: " + e.getMessage(), e); } AlgorithmIdentifier keyAlg = wrapper.getAlgorithmIdentifier(); ASN1OctetString valueHint = null; DERBitString encValue = new DERBitString(bOut.toByteArray()); return new EncryptedValue(intendedAlg, symmAlg, encSymmKey, keyAlg, valueHint, encValue); } private byte[] padData(byte[] data) { if (padder != null) { return padder.getPaddedData(data); } return data; } } bouncycastle-1.49.orig/src/org/bouncycastle/cert/crmf/CertificateRequestMessageBuilder.java0000644000175000017500000001617711724561171031661 0ustar ebourgebourgpackage org.bouncycastle.cert.crmf; import java.math.BigInteger; import java.util.ArrayList; import java.util.Iterator; import java.util.List; import org.bouncycastle.asn1.ASN1Encodable; import org.bouncycastle.asn1.ASN1EncodableVector; import org.bouncycastle.asn1.ASN1Integer; import org.bouncycastle.asn1.ASN1Null; import org.bouncycastle.asn1.ASN1ObjectIdentifier; import org.bouncycastle.asn1.DERNull; import org.bouncycastle.asn1.DERSequence; import org.bouncycastle.asn1.crmf.AttributeTypeAndValue; import org.bouncycastle.asn1.crmf.CertReqMsg; import org.bouncycastle.asn1.crmf.CertRequest; import org.bouncycastle.asn1.crmf.CertTemplate; import org.bouncycastle.asn1.crmf.CertTemplateBuilder; import org.bouncycastle.asn1.crmf.POPOPrivKey; import org.bouncycastle.asn1.crmf.ProofOfPossession; import org.bouncycastle.asn1.crmf.SubsequentMessage; import org.bouncycastle.asn1.x500.X500Name; import org.bouncycastle.asn1.x509.ExtensionsGenerator; import org.bouncycastle.asn1.x509.GeneralName; import org.bouncycastle.asn1.x509.SubjectPublicKeyInfo; import org.bouncycastle.cert.CertIOException; import org.bouncycastle.operator.ContentSigner; public class CertificateRequestMessageBuilder { private final BigInteger certReqId; private ExtensionsGenerator extGenerator; private CertTemplateBuilder templateBuilder; private List controls; private ContentSigner popSigner; private PKMACBuilder pkmacBuilder; private char[] password; private GeneralName sender; private POPOPrivKey popoPrivKey; private ASN1Null popRaVerified; public CertificateRequestMessageBuilder(BigInteger certReqId) { this.certReqId = certReqId; this.extGenerator = new ExtensionsGenerator(); this.templateBuilder = new CertTemplateBuilder(); this.controls = new ArrayList(); } public CertificateRequestMessageBuilder setPublicKey(SubjectPublicKeyInfo publicKey) { if (publicKey != null) { templateBuilder.setPublicKey(publicKey); } return this; } public CertificateRequestMessageBuilder setIssuer(X500Name issuer) { if (issuer != null) { templateBuilder.setIssuer(issuer); } return this; } public CertificateRequestMessageBuilder setSubject(X500Name subject) { if (subject != null) { templateBuilder.setSubject(subject); } return this; } public CertificateRequestMessageBuilder setSerialNumber(BigInteger serialNumber) { if (serialNumber != null) { templateBuilder.setSerialNumber(new ASN1Integer(serialNumber)); } return this; } public CertificateRequestMessageBuilder addExtension( ASN1ObjectIdentifier oid, boolean critical, ASN1Encodable value) throws CertIOException { CRMFUtil.addExtension(extGenerator, oid, critical, value); return this; } public CertificateRequestMessageBuilder addExtension( ASN1ObjectIdentifier oid, boolean critical, byte[] value) { extGenerator.addExtension(oid, critical, value); return this; } public CertificateRequestMessageBuilder addControl(Control control) { controls.add(control); return this; } public CertificateRequestMessageBuilder setProofOfPossessionSigningKeySigner(ContentSigner popSigner) { if (popoPrivKey != null || popRaVerified != null) { throw new IllegalStateException("only one proof of possession allowed"); } this.popSigner = popSigner; return this; } public CertificateRequestMessageBuilder setProofOfPossessionSubsequentMessage(SubsequentMessage msg) { if (popSigner != null || popRaVerified != null) { throw new IllegalStateException("only one proof of possession allowed"); } this.popoPrivKey = new POPOPrivKey(msg); return this; } public CertificateRequestMessageBuilder setProofOfPossessionRaVerified() { if (popSigner != null || popoPrivKey != null) { throw new IllegalStateException("only one proof of possession allowed"); } this.popRaVerified = DERNull.INSTANCE; return this; } public CertificateRequestMessageBuilder setAuthInfoPKMAC(PKMACBuilder pkmacBuilder, char[] password) { this.pkmacBuilder = pkmacBuilder; this.password = password; return this; } public CertificateRequestMessageBuilder setAuthInfoSender(X500Name sender) { return setAuthInfoSender(new GeneralName(sender)); } public CertificateRequestMessageBuilder setAuthInfoSender(GeneralName sender) { this.sender = sender; return this; } public CertificateRequestMessage build() throws CRMFException { ASN1EncodableVector v = new ASN1EncodableVector(); v.add(new ASN1Integer(certReqId)); if (!extGenerator.isEmpty()) { templateBuilder.setExtensions(extGenerator.generate()); } v.add(templateBuilder.build()); if (!controls.isEmpty()) { ASN1EncodableVector controlV = new ASN1EncodableVector(); for (Iterator it = controls.iterator(); it.hasNext();) { Control control = (Control)it.next(); controlV.add(new AttributeTypeAndValue(control.getType(), control.getValue())); } v.add(new DERSequence(controlV)); } CertRequest request = CertRequest.getInstance(new DERSequence(v)); v = new ASN1EncodableVector(); v.add(request); if (popSigner != null) { CertTemplate template = request.getCertTemplate(); if (template.getSubject() == null || template.getPublicKey() == null) { SubjectPublicKeyInfo pubKeyInfo = request.getCertTemplate().getPublicKey(); ProofOfPossessionSigningKeyBuilder builder = new ProofOfPossessionSigningKeyBuilder(pubKeyInfo); if (sender != null) { builder.setSender(sender); } else { PKMACValueGenerator pkmacGenerator = new PKMACValueGenerator(pkmacBuilder); builder.setPublicKeyMac(pkmacGenerator, password); } v.add(new ProofOfPossession(builder.build(popSigner))); } else { ProofOfPossessionSigningKeyBuilder builder = new ProofOfPossessionSigningKeyBuilder(request); v.add(new ProofOfPossession(builder.build(popSigner))); } } else if (popoPrivKey != null) { v.add(new ProofOfPossession(ProofOfPossession.TYPE_KEY_ENCIPHERMENT, popoPrivKey)); } else if (popRaVerified != null) { v.add(new ProofOfPossession()); } return new CertificateRequestMessage(CertReqMsg.getInstance(new DERSequence(v))); } }bouncycastle-1.49.orig/src/org/bouncycastle/cert/crmf/PKMACValueVerifier.java0000644000175000017500000000232211625352704026561 0ustar ebourgebourgpackage org.bouncycastle.cert.crmf; import java.io.IOException; import java.io.OutputStream; import org.bouncycastle.asn1.ASN1Encoding; import org.bouncycastle.asn1.cmp.PBMParameter; import org.bouncycastle.asn1.crmf.PKMACValue; import org.bouncycastle.asn1.x509.SubjectPublicKeyInfo; import org.bouncycastle.operator.MacCalculator; import org.bouncycastle.util.Arrays; class PKMACValueVerifier { private final PKMACBuilder builder; public PKMACValueVerifier(PKMACBuilder builder) { this.builder = builder; } public boolean isValid(PKMACValue value, char[] password, SubjectPublicKeyInfo keyInfo) throws CRMFException { builder.setParameters(PBMParameter.getInstance(value.getAlgId().getParameters())); MacCalculator calculator = builder.build(password); OutputStream macOut = calculator.getOutputStream(); try { macOut.write(keyInfo.getEncoded(ASN1Encoding.DER)); macOut.close(); } catch (IOException e) { throw new CRMFException("exception encoding mac input: " + e.getMessage(), e); } return Arrays.areEqual(calculator.getMac(), value.getValue().getBytes()); } }bouncycastle-1.49.orig/src/org/bouncycastle/cert/crmf/PKMACValueGenerator.java0000644000175000017500000000212611625352251026733 0ustar ebourgebourgpackage org.bouncycastle.cert.crmf; import java.io.IOException; import java.io.OutputStream; import org.bouncycastle.asn1.ASN1Encoding; import org.bouncycastle.asn1.DERBitString; import org.bouncycastle.asn1.crmf.PKMACValue; import org.bouncycastle.asn1.x509.SubjectPublicKeyInfo; import org.bouncycastle.operator.MacCalculator; class PKMACValueGenerator { private PKMACBuilder builder; public PKMACValueGenerator(PKMACBuilder builder) { this.builder = builder; } public PKMACValue generate(char[] password, SubjectPublicKeyInfo keyInfo) throws CRMFException { MacCalculator calculator = builder.build(password); OutputStream macOut = calculator.getOutputStream(); try { macOut.write(keyInfo.getEncoded(ASN1Encoding.DER)); macOut.close(); } catch (IOException e) { throw new CRMFException("exception encoding mac input: " + e.getMessage(), e); } return new PKMACValue(calculator.getAlgorithmIdentifier(), new DERBitString(calculator.getMac())); } } bouncycastle-1.49.orig/src/org/bouncycastle/cert/crmf/PKIArchiveControlBuilder.java0000644000175000017500000000525511740756376030055 0ustar ebourgebourgpackage org.bouncycastle.cert.crmf; import java.io.IOException; import org.bouncycastle.asn1.cms.EnvelopedData; import org.bouncycastle.asn1.crmf.CRMFObjectIdentifiers; import org.bouncycastle.asn1.crmf.EncKeyWithID; import org.bouncycastle.asn1.crmf.EncryptedKey; import org.bouncycastle.asn1.crmf.PKIArchiveOptions; import org.bouncycastle.asn1.pkcs.PrivateKeyInfo; import org.bouncycastle.asn1.x509.GeneralName; import org.bouncycastle.cms.CMSEnvelopedData; import org.bouncycastle.cms.CMSEnvelopedDataGenerator; import org.bouncycastle.cms.CMSException; import org.bouncycastle.cms.CMSProcessableByteArray; import org.bouncycastle.cms.RecipientInfoGenerator; import org.bouncycastle.operator.OutputEncryptor; /** * Builder for a PKIArchiveControl structure. */ public class PKIArchiveControlBuilder { private CMSEnvelopedDataGenerator envGen; private CMSProcessableByteArray keyContent; /** * Basic constructor - specify the contents of the PKIArchiveControl structure. * * @param privateKeyInfo the private key to be archived. * @param generalName the general name to be associated with the private key. */ public PKIArchiveControlBuilder(PrivateKeyInfo privateKeyInfo, GeneralName generalName) { EncKeyWithID encKeyWithID = new EncKeyWithID(privateKeyInfo, generalName); try { this.keyContent = new CMSProcessableByteArray(CRMFObjectIdentifiers.id_ct_encKeyWithID, encKeyWithID.getEncoded()); } catch (IOException e) { throw new IllegalStateException("unable to encode key and general name info"); } this.envGen = new CMSEnvelopedDataGenerator(); } /** * Add a recipient generator to this control. * * @param recipientGen recipient generator created for a specific recipient. * @return this builder object. */ public PKIArchiveControlBuilder addRecipientGenerator(RecipientInfoGenerator recipientGen) { envGen.addRecipientInfoGenerator(recipientGen); return this; } /** * Build the PKIArchiveControl using the passed in encryptor to encrypt its contents. * * @param contentEncryptor a suitable content encryptor. * @return a PKIArchiveControl object. * @throws CMSException in the event the build fails. */ public PKIArchiveControl build(OutputEncryptor contentEncryptor) throws CMSException { CMSEnvelopedData envContent = envGen.generate(keyContent, contentEncryptor); EnvelopedData envD = EnvelopedData.getInstance(envContent.toASN1Structure().getContent()); return new PKIArchiveControl(new PKIArchiveOptions(new EncryptedKey(envD))); } }bouncycastle-1.49.orig/src/org/bouncycastle/cert/crmf/RegTokenControl.java0000644000175000017500000000251711503764146026324 0ustar ebourgebourgpackage org.bouncycastle.cert.crmf; import org.bouncycastle.asn1.ASN1Encodable; import org.bouncycastle.asn1.ASN1ObjectIdentifier; import org.bouncycastle.asn1.DERUTF8String; import org.bouncycastle.asn1.crmf.CRMFObjectIdentifiers; /** * Carrier for a registration token control. */ public class RegTokenControl implements Control { private static final ASN1ObjectIdentifier type = CRMFObjectIdentifiers.id_regCtrl_regToken; private final DERUTF8String token; /** * Basic constructor - build from a UTF-8 string representing the token. * * @param token UTF-8 string representing the token. */ public RegTokenControl(DERUTF8String token) { this.token = token; } /** * Basic constructor - build from a string representing the token. * * @param token string representing the token. */ public RegTokenControl(String token) { this.token = new DERUTF8String(token); } /** * Return the type of this control. * * @return CRMFObjectIdentifiers.id_regCtrl_regToken */ public ASN1ObjectIdentifier getType() { return type; } /** * Return the token associated with this control (a UTF8String). * * @return a UTF8String. */ public ASN1Encodable getValue() { return token; } } bouncycastle-1.49.orig/src/org/bouncycastle/cert/crmf/PKMACBuilder.java0000644000175000017500000001351111737140557025406 0ustar ebourgebourgpackage org.bouncycastle.cert.crmf; import java.io.ByteArrayOutputStream; import java.io.OutputStream; import java.security.SecureRandom; import org.bouncycastle.asn1.DERNull; import org.bouncycastle.asn1.cmp.CMPObjectIdentifiers; import org.bouncycastle.asn1.cmp.PBMParameter; import org.bouncycastle.asn1.iana.IANAObjectIdentifiers; import org.bouncycastle.asn1.oiw.OIWObjectIdentifiers; import org.bouncycastle.asn1.x509.AlgorithmIdentifier; import org.bouncycastle.operator.GenericKey; import org.bouncycastle.operator.MacCalculator; import org.bouncycastle.operator.RuntimeOperatorException; import org.bouncycastle.util.Strings; public class PKMACBuilder { private AlgorithmIdentifier owf; private int iterationCount; private AlgorithmIdentifier mac; private int saltLength = 20; private SecureRandom random; private PKMACValuesCalculator calculator; private PBMParameter parameters; private int maxIterations; public PKMACBuilder(PKMACValuesCalculator calculator) { this(new AlgorithmIdentifier(OIWObjectIdentifiers.idSHA1), 1000, new AlgorithmIdentifier(IANAObjectIdentifiers.hmacSHA1, DERNull.INSTANCE), calculator); } /** * Create a PKMAC builder enforcing a ceiling on the maximum iteration count. * * @param calculator supporting calculator * @param maxIterations max allowable value for iteration count. */ public PKMACBuilder(PKMACValuesCalculator calculator, int maxIterations) { this.maxIterations = maxIterations; this.calculator = calculator; } private PKMACBuilder(AlgorithmIdentifier hashAlgorithm, int iterationCount, AlgorithmIdentifier macAlgorithm, PKMACValuesCalculator calculator) { this.owf = hashAlgorithm; this.iterationCount = iterationCount; this.mac = macAlgorithm; this.calculator = calculator; } /** * Set the salt length in octets. * * @param saltLength length in octets of the salt to be generated. * @return the generator */ public PKMACBuilder setSaltLength(int saltLength) { if (saltLength < 8) { throw new IllegalArgumentException("salt length must be at least 8 bytes"); } this.saltLength = saltLength; return this; } public PKMACBuilder setIterationCount(int iterationCount) { if (iterationCount < 100) { throw new IllegalArgumentException("iteration count must be at least 100"); } checkIterationCountCeiling(iterationCount); this.iterationCount = iterationCount; return this; } public PKMACBuilder setSecureRandom(SecureRandom random) { this.random = random; return this; } public PKMACBuilder setParameters(PBMParameter parameters) { checkIterationCountCeiling(parameters.getIterationCount().getValue().intValue()); this.parameters = parameters; return this; } public MacCalculator build(char[] password) throws CRMFException { if (parameters != null) { return genCalculator(parameters, password); } else { byte[] salt = new byte[saltLength]; if (random == null) { this.random = new SecureRandom(); } random.nextBytes(salt); return genCalculator(new PBMParameter(salt, owf, iterationCount, mac), password); } } private void checkIterationCountCeiling(int iterationCount) { if (maxIterations > 0 && iterationCount > maxIterations) { throw new IllegalArgumentException("iteration count exceeds limit (" + iterationCount + " > " + maxIterations + ")"); } } private MacCalculator genCalculator(final PBMParameter params, char[] password) throws CRMFException { // From RFC 4211 // // 1. Generate a random salt value S // // 2. Append the salt to the pw. K = pw || salt. // // 3. Hash the value of K. K = HASH(K) // // 4. Iter = Iter - 1. If Iter is greater than zero. Goto step 3. // // 5. Compute an HMAC as documented in [HMAC]. // // MAC = HASH( K XOR opad, HASH( K XOR ipad, data) ) // // Where opad and ipad are defined in [HMAC]. byte[] pw = Strings.toUTF8ByteArray(password); byte[] salt = params.getSalt().getOctets(); byte[] K = new byte[pw.length + salt.length]; System.arraycopy(pw, 0, K, 0, pw.length); System.arraycopy(salt, 0, K, pw.length, salt.length); calculator.setup(params.getOwf(), params.getMac()); int iter = params.getIterationCount().getValue().intValue(); do { K = calculator.calculateDigest(K); } while (--iter > 0); final byte[] key = K; return new MacCalculator() { ByteArrayOutputStream bOut = new ByteArrayOutputStream(); public AlgorithmIdentifier getAlgorithmIdentifier() { return new AlgorithmIdentifier(CMPObjectIdentifiers.passwordBasedMac, params); } public GenericKey getKey() { return new GenericKey(getAlgorithmIdentifier(), key); } public OutputStream getOutputStream() { return bOut; } public byte[] getMac() { try { return calculator.calculateMac(key, bOut.toByteArray()); } catch (CRMFException e) { throw new RuntimeOperatorException("exception calculating mac: " + e.getMessage(), e); } } }; } } bouncycastle-1.49.orig/src/org/bouncycastle/cert/crmf/EncryptedValueParser.java0000644000175000017500000000625311724263616027356 0ustar ebourgebourgpackage org.bouncycastle.cert.crmf; import java.io.ByteArrayInputStream; import java.io.IOException; import java.io.InputStream; import org.bouncycastle.asn1.crmf.EncryptedValue; import org.bouncycastle.asn1.x509.Certificate; import org.bouncycastle.cert.X509CertificateHolder; import org.bouncycastle.operator.InputDecryptor; import org.bouncycastle.util.Strings; import org.bouncycastle.util.io.Streams; /** * Parser for EncryptedValue structures. */ public class EncryptedValueParser { private EncryptedValue value; private EncryptedValuePadder padder; /** * Basic constructor - create a parser to read the passed in value. * * @param value the value to be parsed. */ public EncryptedValueParser(EncryptedValue value) { this.value = value; } /** * Create a parser to read the passed in value, assuming the padder was * applied to the data prior to encryption. * * @param value the value to be parsed. * @param padder the padder to be used to remove padding from the decrypted value.. */ public EncryptedValueParser(EncryptedValue value, EncryptedValuePadder padder) { this.value = value; this.padder = padder; } private byte[] decryptValue(ValueDecryptorGenerator decGen) throws CRMFException { if (value.getIntendedAlg() != null) { throw new UnsupportedOperationException(); } if (value.getValueHint() != null) { throw new UnsupportedOperationException(); } InputDecryptor decryptor = decGen.getValueDecryptor(value.getKeyAlg(), value.getSymmAlg(), value.getEncSymmKey().getBytes()); InputStream dataIn = decryptor.getInputStream(new ByteArrayInputStream( value.getEncValue().getBytes())); try { byte[] data = Streams.readAll(dataIn); if (padder != null) { return padder.getUnpaddedData(data); } return data; } catch (IOException e) { throw new CRMFException("Cannot parse decrypted data: " + e.getMessage(), e); } } /** * Read a X.509 certificate. * * @param decGen the decryptor generator to decrypt the encrypted value. * @return an X509CertificateHolder containing the certificate read. * @throws CRMFException if the decrypted data cannot be parsed, or a decryptor cannot be generated. */ public X509CertificateHolder readCertificateHolder(ValueDecryptorGenerator decGen) throws CRMFException { return new X509CertificateHolder(Certificate.getInstance(decryptValue(decGen))); } /** * Read a pass phrase. * * @param decGen the decryptor generator to decrypt the encrypted value. * @return a pass phrase as recovered from the encrypted value. * @throws CRMFException if the decrypted data cannot be parsed, or a decryptor cannot be generated. */ public char[] readPassphrase(ValueDecryptorGenerator decGen) throws CRMFException { return Strings.fromUTF8ByteArray(decryptValue(decGen)).toCharArray(); } } bouncycastle-1.49.orig/src/org/bouncycastle/cert/crmf/CertificateRequestMessage.java0000644000175000017500000002414711624652565030355 0ustar ebourgebourgpackage org.bouncycastle.cert.crmf; import java.io.IOException; import org.bouncycastle.asn1.ASN1ObjectIdentifier; import org.bouncycastle.asn1.ASN1Primitive; import org.bouncycastle.asn1.DERUTF8String; import org.bouncycastle.asn1.crmf.AttributeTypeAndValue; import org.bouncycastle.asn1.crmf.CRMFObjectIdentifiers; import org.bouncycastle.asn1.crmf.CertReqMsg; import org.bouncycastle.asn1.crmf.CertTemplate; import org.bouncycastle.asn1.crmf.Controls; import org.bouncycastle.asn1.crmf.PKIArchiveOptions; import org.bouncycastle.asn1.crmf.PKMACValue; import org.bouncycastle.asn1.crmf.POPOSigningKey; import org.bouncycastle.asn1.crmf.ProofOfPossession; import org.bouncycastle.cert.CertIOException; import org.bouncycastle.operator.ContentVerifier; import org.bouncycastle.operator.ContentVerifierProvider; import org.bouncycastle.operator.OperatorCreationException; /** * Carrier for a CRMF CertReqMsg. */ public class CertificateRequestMessage { public static final int popRaVerified = ProofOfPossession.TYPE_RA_VERIFIED; public static final int popSigningKey = ProofOfPossession.TYPE_SIGNING_KEY; public static final int popKeyEncipherment = ProofOfPossession.TYPE_KEY_ENCIPHERMENT; public static final int popKeyAgreement = ProofOfPossession.TYPE_KEY_AGREEMENT; private final CertReqMsg certReqMsg; private final Controls controls; private static CertReqMsg parseBytes(byte[] encoding) throws IOException { try { return CertReqMsg.getInstance(ASN1Primitive.fromByteArray(encoding)); } catch (ClassCastException e) { throw new CertIOException("malformed data: " + e.getMessage(), e); } catch (IllegalArgumentException e) { throw new CertIOException("malformed data: " + e.getMessage(), e); } } /** * Create a CertificateRequestMessage from the passed in bytes. * * @param certReqMsg BER/DER encoding of the CertReqMsg structure. * @throws IOException in the event of corrupted data, or an incorrect structure. */ public CertificateRequestMessage(byte[] certReqMsg) throws IOException { this(parseBytes(certReqMsg)); } public CertificateRequestMessage(CertReqMsg certReqMsg) { this.certReqMsg = certReqMsg; this.controls = certReqMsg.getCertReq().getControls(); } /** * Return the underlying ASN.1 object defining this CertificateRequestMessage object. * * @return a CertReqMsg. */ public CertReqMsg toASN1Structure() { return certReqMsg; } /** * Return the certificate template contained in this message. * * @return a CertTemplate structure. */ public CertTemplate getCertTemplate() { return this.certReqMsg.getCertReq().getCertTemplate(); } /** * Return whether or not this request has control values associated with it. * * @return true if there are control values present, false otherwise. */ public boolean hasControls() { return controls != null; } /** * Return whether or not this request has a specific type of control value. * * @param type the type OID for the control value we are checking for. * @return true if a control value of type is present, false otherwise. */ public boolean hasControl(ASN1ObjectIdentifier type) { return findControl(type) != null; } /** * Return a control value of the specified type. * * @param type the type OID for the control value we are checking for. * @return the control value if present, null otherwise. */ public Control getControl(ASN1ObjectIdentifier type) { AttributeTypeAndValue found = findControl(type); if (found != null) { if (found.getType().equals(CRMFObjectIdentifiers.id_regCtrl_pkiArchiveOptions)) { return new PKIArchiveControl(PKIArchiveOptions.getInstance(found.getValue())); } if (found.getType().equals(CRMFObjectIdentifiers.id_regCtrl_regToken)) { return new RegTokenControl(DERUTF8String.getInstance(found.getValue())); } if (found.getType().equals(CRMFObjectIdentifiers.id_regCtrl_authenticator)) { return new AuthenticatorControl(DERUTF8String.getInstance(found.getValue())); } } return null; } private AttributeTypeAndValue findControl(ASN1ObjectIdentifier type) { if (controls == null) { return null; } AttributeTypeAndValue[] tAndVs = controls.toAttributeTypeAndValueArray(); AttributeTypeAndValue found = null; for (int i = 0; i != tAndVs.length; i++) { if (tAndVs[i].getType().equals(type)) { found = tAndVs[i]; break; } } return found; } /** * Return whether or not this request message has a proof-of-possession field in it. * * @return true if proof-of-possession is present, false otherwise. */ public boolean hasProofOfPossession() { return this.certReqMsg.getPopo() != null; } /** * Return the type of the proof-of-possession this request message provides. * * @return one of: popRaVerified, popSigningKey, popKeyEncipherment, popKeyAgreement */ public int getProofOfPossessionType() { return this.certReqMsg.getPopo().getType(); } /** * Return whether or not the proof-of-possession (POP) is of the type popSigningKey and * it has a public key MAC associated with it. * * @return true if POP is popSigningKey and a PKMAC is present, false otherwise. */ public boolean hasSigningKeyProofOfPossessionWithPKMAC() { ProofOfPossession pop = certReqMsg.getPopo(); if (pop.getType() == popSigningKey) { POPOSigningKey popoSign = POPOSigningKey.getInstance(pop.getObject()); return popoSign.getPoposkInput().getPublicKeyMAC() != null; } return false; } /** * Return whether or not a signing key proof-of-possession (POP) is valid. * * @param verifierProvider a provider that can produce content verifiers for the signature contained in this POP. * @return true if the POP is valid, false otherwise. * @throws CRMFException if there is a problem in verification or content verifier creation. * @throws IllegalStateException if POP not appropriate. */ public boolean isValidSigningKeyPOP(ContentVerifierProvider verifierProvider) throws CRMFException, IllegalStateException { ProofOfPossession pop = certReqMsg.getPopo(); if (pop.getType() == popSigningKey) { POPOSigningKey popoSign = POPOSigningKey.getInstance(pop.getObject()); if (popoSign.getPoposkInput() != null && popoSign.getPoposkInput().getPublicKeyMAC() != null) { throw new IllegalStateException("verification requires password check"); } return verifySignature(verifierProvider, popoSign); } else { throw new IllegalStateException("not Signing Key type of proof of possession"); } } /** * Return whether or not a signing key proof-of-possession (POP), with an associated PKMAC, is valid. * * @param verifierProvider a provider that can produce content verifiers for the signature contained in this POP. * @param macBuilder a suitable PKMACBuilder to create the MAC verifier. * @param password the password used to key the MAC calculation. * @return true if the POP is valid, false otherwise. * @throws CRMFException if there is a problem in verification or content verifier creation. * @throws IllegalStateException if POP not appropriate. */ public boolean isValidSigningKeyPOP(ContentVerifierProvider verifierProvider, PKMACBuilder macBuilder, char[] password) throws CRMFException, IllegalStateException { ProofOfPossession pop = certReqMsg.getPopo(); if (pop.getType() == popSigningKey) { POPOSigningKey popoSign = POPOSigningKey.getInstance(pop.getObject()); if (popoSign.getPoposkInput() == null || popoSign.getPoposkInput().getSender() != null) { throw new IllegalStateException("no PKMAC present in proof of possession"); } PKMACValue pkMAC = popoSign.getPoposkInput().getPublicKeyMAC(); PKMACValueVerifier macVerifier = new PKMACValueVerifier(macBuilder); if (macVerifier.isValid(pkMAC, password, this.getCertTemplate().getPublicKey())) { return verifySignature(verifierProvider, popoSign); } return false; } else { throw new IllegalStateException("not Signing Key type of proof of possession"); } } private boolean verifySignature(ContentVerifierProvider verifierProvider, POPOSigningKey popoSign) throws CRMFException { ContentVerifier verifier; try { verifier = verifierProvider.get(popoSign.getAlgorithmIdentifier()); } catch (OperatorCreationException e) { throw new CRMFException("unable to create verifier: " + e.getMessage(), e); } if (popoSign.getPoposkInput() != null) { CRMFUtil.derEncodeToStream(popoSign.getPoposkInput(), verifier.getOutputStream()); } else { CRMFUtil.derEncodeToStream(certReqMsg.getCertReq(), verifier.getOutputStream()); } return verifier.verify(popoSign.getSignature().getBytes()); } /** * Return the ASN.1 encoding of the certReqMsg we wrap. * * @return a byte array containing the binary encoding of the certReqMsg. * @throws IOException if there is an exception creating the encoding. */ public byte[] getEncoded() throws IOException { return certReqMsg.getEncoded(); } }bouncycastle-1.49.orig/src/org/bouncycastle/cert/crmf/AuthenticatorControl.java0000644000175000017500000000254411503764146027420 0ustar ebourgebourgpackage org.bouncycastle.cert.crmf; import org.bouncycastle.asn1.ASN1Encodable; import org.bouncycastle.asn1.ASN1ObjectIdentifier; import org.bouncycastle.asn1.DERUTF8String; import org.bouncycastle.asn1.crmf.CRMFObjectIdentifiers; /** * Carrier for an authenticator control. */ public class AuthenticatorControl implements Control { private static final ASN1ObjectIdentifier type = CRMFObjectIdentifiers.id_regCtrl_authenticator; private final DERUTF8String token; /** * Basic constructor - build from a UTF-8 string representing the token. * * @param token UTF-8 string representing the token. */ public AuthenticatorControl(DERUTF8String token) { this.token = token; } /** * Basic constructor - build from a string representing the token. * * @param token string representing the token. */ public AuthenticatorControl(String token) { this.token = new DERUTF8String(token); } /** * Return the type of this control. * * @return CRMFObjectIdentifiers.id_regCtrl_authenticator */ public ASN1ObjectIdentifier getType() { return type; } /** * Return the token associated with this control (a UTF8String). * * @return a UTF8String. */ public ASN1Encodable getValue() { return token; } } bouncycastle-1.49.orig/src/org/bouncycastle/cert/crmf/ProofOfPossessionSigningKeyBuilder.java0000644000175000017500000000416411573273573032212 0ustar ebourgebourgpackage org.bouncycastle.cert.crmf; import org.bouncycastle.asn1.DERBitString; import org.bouncycastle.asn1.crmf.CertRequest; import org.bouncycastle.asn1.crmf.PKMACValue; import org.bouncycastle.asn1.crmf.POPOSigningKey; import org.bouncycastle.asn1.crmf.POPOSigningKeyInput; import org.bouncycastle.asn1.x509.GeneralName; import org.bouncycastle.asn1.x509.SubjectPublicKeyInfo; import org.bouncycastle.operator.ContentSigner; public class ProofOfPossessionSigningKeyBuilder { private CertRequest certRequest; private SubjectPublicKeyInfo pubKeyInfo; private GeneralName name; private PKMACValue publicKeyMAC; public ProofOfPossessionSigningKeyBuilder(CertRequest certRequest) { this.certRequest = certRequest; } public ProofOfPossessionSigningKeyBuilder(SubjectPublicKeyInfo pubKeyInfo) { this.pubKeyInfo = pubKeyInfo; } public ProofOfPossessionSigningKeyBuilder setSender(GeneralName name) { this.name = name; return this; } public ProofOfPossessionSigningKeyBuilder setPublicKeyMac(PKMACValueGenerator generator, char[] password) throws CRMFException { this.publicKeyMAC = generator.generate(password, pubKeyInfo); return this; } public POPOSigningKey build(ContentSigner signer) { if (name != null && publicKeyMAC != null) { throw new IllegalStateException("name and publicKeyMAC cannot both be set."); } POPOSigningKeyInput popo; if (certRequest != null) { popo = null; CRMFUtil.derEncodeToStream(certRequest, signer.getOutputStream()); } else if (name != null) { popo = new POPOSigningKeyInput(name, pubKeyInfo); CRMFUtil.derEncodeToStream(popo, signer.getOutputStream()); } else { popo = new POPOSigningKeyInput(publicKeyMAC, pubKeyInfo); CRMFUtil.derEncodeToStream(popo, signer.getOutputStream()); } return new POPOSigningKey(popo, signer.getAlgorithmIdentifier(), new DERBitString(signer.getSignature())); } } bouncycastle-1.49.orig/src/org/bouncycastle/cert/crmf/jcajce/0000755000175000017500000000000012152033551023602 5ustar ebourgebourgbouncycastle-1.49.orig/src/org/bouncycastle/cert/crmf/jcajce/JcaPKIArchiveControlBuilder.java0000644000175000017500000000157311504270770031674 0ustar ebourgebourgpackage org.bouncycastle.cert.crmf.jcajce; import java.security.PrivateKey; import javax.security.auth.x500.X500Principal; import org.bouncycastle.asn1.pkcs.PrivateKeyInfo; import org.bouncycastle.asn1.x500.X500Name; import org.bouncycastle.asn1.x509.GeneralName; import org.bouncycastle.cert.crmf.PKIArchiveControlBuilder; public class JcaPKIArchiveControlBuilder extends PKIArchiveControlBuilder { public JcaPKIArchiveControlBuilder(PrivateKey privateKey, X500Name name) { this(privateKey, new GeneralName(name)); } public JcaPKIArchiveControlBuilder(PrivateKey privateKey, X500Principal name) { this(privateKey, X500Name.getInstance(name.getEncoded())); } public JcaPKIArchiveControlBuilder(PrivateKey privateKey, GeneralName generalName) { super(PrivateKeyInfo.getInstance(privateKey.getEncoded()), generalName); } } ././@LongLink0000000000000000000000000000014700000000000011567 Lustar rootrootbouncycastle-1.49.orig/src/org/bouncycastle/cert/crmf/jcajce/JceAsymmetricValueDecryptorGenerator.javabouncycastle-1.49.orig/src/org/bouncycastle/cert/crmf/jcajce/JceAsymmetricValueDecryptorGenerator.ja0000644000175000017500000000774711435111231033427 0ustar ebourgebourgpackage org.bouncycastle.cert.crmf.jcajce; import java.io.InputStream; import java.security.GeneralSecurityException; import java.security.InvalidKeyException; import java.security.Key; import java.security.PrivateKey; import java.security.Provider; import java.security.ProviderException; import javax.crypto.BadPaddingException; import javax.crypto.Cipher; import javax.crypto.CipherInputStream; import javax.crypto.IllegalBlockSizeException; import javax.crypto.spec.SecretKeySpec; import org.bouncycastle.asn1.x509.AlgorithmIdentifier; import org.bouncycastle.cert.crmf.CRMFException; import org.bouncycastle.cert.crmf.ValueDecryptorGenerator; import org.bouncycastle.jcajce.DefaultJcaJceHelper; import org.bouncycastle.jcajce.NamedJcaJceHelper; import org.bouncycastle.jcajce.ProviderJcaJceHelper; import org.bouncycastle.operator.InputDecryptor; public class JceAsymmetricValueDecryptorGenerator implements ValueDecryptorGenerator { private PrivateKey recipientKey; private CRMFHelper helper = new CRMFHelper(new DefaultJcaJceHelper()); public JceAsymmetricValueDecryptorGenerator(PrivateKey recipientKey) { this.recipientKey = recipientKey; } public JceAsymmetricValueDecryptorGenerator setProvider(Provider provider) { this.helper = new CRMFHelper(new ProviderJcaJceHelper(provider)); return this; } public JceAsymmetricValueDecryptorGenerator setProvider(String providerName) { this.helper = new CRMFHelper(new NamedJcaJceHelper(providerName)); return this; } private Key extractSecretKey(AlgorithmIdentifier keyEncryptionAlgorithm, AlgorithmIdentifier contentEncryptionAlgorithm, byte[] encryptedContentEncryptionKey) throws CRMFException { try { Key sKey = null; Cipher keyCipher = helper.createCipher(keyEncryptionAlgorithm.getAlgorithm()); try { keyCipher.init(Cipher.UNWRAP_MODE, recipientKey); sKey = keyCipher.unwrap(encryptedContentEncryptionKey, contentEncryptionAlgorithm.getAlgorithm().getId(), Cipher.SECRET_KEY); } catch (GeneralSecurityException e) { } catch (IllegalStateException e) { } catch (UnsupportedOperationException e) { } catch (ProviderException e) { } // some providers do not support UNWRAP (this appears to be only for asymmetric algorithms) if (sKey == null) { keyCipher.init(Cipher.DECRYPT_MODE, recipientKey); sKey = new SecretKeySpec(keyCipher.doFinal(encryptedContentEncryptionKey), contentEncryptionAlgorithm.getAlgorithm().getId()); } return sKey; } catch (InvalidKeyException e) { throw new CRMFException("key invalid in message.", e); } catch (IllegalBlockSizeException e) { throw new CRMFException("illegal blocksize in message.", e); } catch (BadPaddingException e) { throw new CRMFException("bad padding in message.", e); } } public InputDecryptor getValueDecryptor(AlgorithmIdentifier keyEncryptionAlgorithm, final AlgorithmIdentifier contentEncryptionAlgorithm, byte[] encryptedContentEncryptionKey) throws CRMFException { Key secretKey = extractSecretKey(keyEncryptionAlgorithm, contentEncryptionAlgorithm, encryptedContentEncryptionKey); final Cipher dataCipher = helper.createContentCipher(secretKey, contentEncryptionAlgorithm); return new InputDecryptor() { public AlgorithmIdentifier getAlgorithmIdentifier() { return contentEncryptionAlgorithm; } public InputStream getInputStream(InputStream dataIn) { return new CipherInputStream(dataIn, dataCipher); } }; } } bouncycastle-1.49.orig/src/org/bouncycastle/cert/crmf/jcajce/JceCRMFEncryptorBuilder.java0000644000175000017500000000767711737140557031071 0ustar ebourgebourgpackage org.bouncycastle.cert.crmf.jcajce; import java.io.OutputStream; import java.security.AlgorithmParameters; import java.security.GeneralSecurityException; import java.security.Provider; import java.security.SecureRandom; import javax.crypto.Cipher; import javax.crypto.CipherOutputStream; import javax.crypto.KeyGenerator; import javax.crypto.SecretKey; import org.bouncycastle.asn1.ASN1ObjectIdentifier; import org.bouncycastle.asn1.x509.AlgorithmIdentifier; import org.bouncycastle.cert.crmf.CRMFException; import org.bouncycastle.jcajce.DefaultJcaJceHelper; import org.bouncycastle.jcajce.NamedJcaJceHelper; import org.bouncycastle.jcajce.ProviderJcaJceHelper; import org.bouncycastle.operator.GenericKey; import org.bouncycastle.operator.OutputEncryptor; import org.bouncycastle.operator.jcajce.JceGenericKey; public class JceCRMFEncryptorBuilder { private final ASN1ObjectIdentifier encryptionOID; private final int keySize; private CRMFHelper helper = new CRMFHelper(new DefaultJcaJceHelper()); private SecureRandom random; public JceCRMFEncryptorBuilder(ASN1ObjectIdentifier encryptionOID) { this(encryptionOID, -1); } public JceCRMFEncryptorBuilder(ASN1ObjectIdentifier encryptionOID, int keySize) { this.encryptionOID = encryptionOID; this.keySize = keySize; } public JceCRMFEncryptorBuilder setProvider(Provider provider) { this.helper = new CRMFHelper(new ProviderJcaJceHelper(provider)); return this; } public JceCRMFEncryptorBuilder setProvider(String providerName) { this.helper = new CRMFHelper(new NamedJcaJceHelper(providerName)); return this; } public JceCRMFEncryptorBuilder setSecureRandom(SecureRandom random) { this.random = random; return this; } public OutputEncryptor build() throws CRMFException { return new CRMFOutputEncryptor(encryptionOID, keySize, random); } private class CRMFOutputEncryptor implements OutputEncryptor { private SecretKey encKey; private AlgorithmIdentifier algorithmIdentifier; private Cipher cipher; CRMFOutputEncryptor(ASN1ObjectIdentifier encryptionOID, int keySize, SecureRandom random) throws CRMFException { KeyGenerator keyGen = helper.createKeyGenerator(encryptionOID); if (random == null) { random = new SecureRandom(); } if (keySize < 0) { keyGen.init(random); } else { keyGen.init(keySize, random); } cipher = helper.createCipher(encryptionOID); encKey = keyGen.generateKey(); AlgorithmParameters params = helper.generateParameters(encryptionOID, encKey, random); try { cipher.init(Cipher.ENCRYPT_MODE, encKey, params, random); } catch (GeneralSecurityException e) { throw new CRMFException("unable to initialize cipher: " + e.getMessage(), e); } // // If params are null we try and second guess on them as some providers don't provide // algorithm parameter generation explicity but instead generate them under the hood. // if (params == null) { params = cipher.getParameters(); } algorithmIdentifier = helper.getAlgorithmIdentifier(encryptionOID, params); } public AlgorithmIdentifier getAlgorithmIdentifier() { return algorithmIdentifier; } public OutputStream getOutputStream(OutputStream dOut) { return new CipherOutputStream(dOut, cipher); } public GenericKey getKey() { return new JceGenericKey(algorithmIdentifier, encKey); } } } bouncycastle-1.49.orig/src/org/bouncycastle/cert/crmf/jcajce/JcaCertificateRequestMessage.java0000644000175000017500000000443111741213336032171 0ustar ebourgebourgpackage org.bouncycastle.cert.crmf.jcajce; import java.io.IOException; import java.security.Provider; import java.security.PublicKey; import javax.security.auth.x500.X500Principal; import org.bouncycastle.asn1.ASN1Encoding; import org.bouncycastle.asn1.crmf.CertReqMsg; import org.bouncycastle.asn1.x500.X500Name; import org.bouncycastle.asn1.x509.SubjectPublicKeyInfo; import org.bouncycastle.cert.crmf.CRMFException; import org.bouncycastle.cert.crmf.CertificateRequestMessage; import org.bouncycastle.jcajce.DefaultJcaJceHelper; import org.bouncycastle.jcajce.NamedJcaJceHelper; import org.bouncycastle.jcajce.ProviderJcaJceHelper; public class JcaCertificateRequestMessage extends CertificateRequestMessage { private CRMFHelper helper = new CRMFHelper(new DefaultJcaJceHelper()); public JcaCertificateRequestMessage(byte[] certReqMsg) { this(CertReqMsg.getInstance(certReqMsg)); } public JcaCertificateRequestMessage(CertificateRequestMessage certReqMsg) { this(certReqMsg.toASN1Structure()); } public JcaCertificateRequestMessage(CertReqMsg certReqMsg) { super(certReqMsg); } public JcaCertificateRequestMessage setProvider(String providerName) { this.helper = new CRMFHelper(new NamedJcaJceHelper(providerName)); return this; } public JcaCertificateRequestMessage setProvider(Provider provider) { this.helper = new CRMFHelper(new ProviderJcaJceHelper(provider)); return this; } public X500Principal getSubjectX500Principal() { X500Name subject = this.getCertTemplate().getSubject(); if (subject != null) { try { return new X500Principal(subject.getEncoded(ASN1Encoding.DER)); } catch (IOException e) { throw new IllegalStateException("unable to construct DER encoding of name: " + e.getMessage()); } } return null; } public PublicKey getPublicKey() throws CRMFException { SubjectPublicKeyInfo subjectPublicKeyInfo = getCertTemplate().getPublicKey(); if (subjectPublicKeyInfo != null) { return helper.toPublicKey(subjectPublicKeyInfo); } return null; } } ././@LongLink0000000000000000000000000000014600000000000011566 Lustar rootrootbouncycastle-1.49.orig/src/org/bouncycastle/cert/crmf/jcajce/JcaCertificateRequestMessageBuilder.javabouncycastle-1.49.orig/src/org/bouncycastle/cert/crmf/jcajce/JcaCertificateRequestMessageBuilder.jav0000644000175000017500000000272511472400363033342 0ustar ebourgebourgpackage org.bouncycastle.cert.crmf.jcajce; import java.math.BigInteger; import java.security.PublicKey; import javax.security.auth.x500.X500Principal; import org.bouncycastle.asn1.x500.X500Name; import org.bouncycastle.asn1.x509.GeneralName; import org.bouncycastle.asn1.x509.SubjectPublicKeyInfo; import org.bouncycastle.cert.crmf.CertificateRequestMessageBuilder; public class JcaCertificateRequestMessageBuilder extends CertificateRequestMessageBuilder { public JcaCertificateRequestMessageBuilder(BigInteger certReqId) { super(certReqId); } public JcaCertificateRequestMessageBuilder setIssuer(X500Principal issuer) { if (issuer != null) { setIssuer(X500Name.getInstance(issuer.getEncoded())); } return this; } public JcaCertificateRequestMessageBuilder setSubject(X500Principal subject) { if (subject != null) { setSubject(X500Name.getInstance(subject.getEncoded())); } return this; } public JcaCertificateRequestMessageBuilder setAuthInfoSender(X500Principal sender) { if (sender != null) { setAuthInfoSender(new GeneralName(X500Name.getInstance(sender.getEncoded()))); } return this; } public JcaCertificateRequestMessageBuilder setPublicKey(PublicKey publicKey) { setPublicKey(SubjectPublicKeyInfo.getInstance(publicKey.getEncoded())); return this; } } bouncycastle-1.49.orig/src/org/bouncycastle/cert/crmf/jcajce/CRMFHelper.java0000644000175000017500000003654611737275254026372 0ustar ebourgebourgpackage org.bouncycastle.cert.crmf.jcajce; import java.io.IOException; import java.security.AlgorithmParameterGenerator; import java.security.AlgorithmParameters; import java.security.GeneralSecurityException; import java.security.InvalidAlgorithmParameterException; import java.security.InvalidKeyException; import java.security.Key; import java.security.KeyFactory; import java.security.MessageDigest; import java.security.NoSuchAlgorithmException; import java.security.NoSuchProviderException; import java.security.PublicKey; import java.security.SecureRandom; import java.security.spec.InvalidParameterSpecException; import java.security.spec.X509EncodedKeySpec; import java.util.HashMap; import java.util.Map; import javax.crypto.Cipher; import javax.crypto.KeyGenerator; import javax.crypto.Mac; import javax.crypto.NoSuchPaddingException; import javax.crypto.SecretKey; import javax.crypto.spec.IvParameterSpec; import javax.crypto.spec.RC2ParameterSpec; import org.bouncycastle.asn1.ASN1Encodable; import org.bouncycastle.asn1.ASN1Null; import org.bouncycastle.asn1.ASN1ObjectIdentifier; import org.bouncycastle.asn1.ASN1OctetString; import org.bouncycastle.asn1.ASN1Primitive; import org.bouncycastle.asn1.DERNull; import org.bouncycastle.asn1.iana.IANAObjectIdentifiers; import org.bouncycastle.asn1.nist.NISTObjectIdentifiers; import org.bouncycastle.asn1.oiw.OIWObjectIdentifiers; import org.bouncycastle.asn1.pkcs.PKCSObjectIdentifiers; import org.bouncycastle.asn1.x509.AlgorithmIdentifier; import org.bouncycastle.asn1.x509.SubjectPublicKeyInfo; import org.bouncycastle.asn1.x9.X9ObjectIdentifiers; import org.bouncycastle.cert.crmf.CRMFException; import org.bouncycastle.cms.CMSAlgorithm; import org.bouncycastle.jcajce.JcaJceHelper; class CRMFHelper { protected static final Map BASE_CIPHER_NAMES = new HashMap(); protected static final Map CIPHER_ALG_NAMES = new HashMap(); protected static final Map DIGEST_ALG_NAMES = new HashMap(); protected static final Map KEY_ALG_NAMES = new HashMap(); protected static final Map MAC_ALG_NAMES = new HashMap(); static { BASE_CIPHER_NAMES.put(PKCSObjectIdentifiers.des_EDE3_CBC, "DESEDE"); BASE_CIPHER_NAMES.put(NISTObjectIdentifiers.id_aes128_CBC, "AES"); BASE_CIPHER_NAMES.put(NISTObjectIdentifiers.id_aes192_CBC, "AES"); BASE_CIPHER_NAMES.put(NISTObjectIdentifiers.id_aes256_CBC, "AES"); CIPHER_ALG_NAMES.put(CMSAlgorithm.DES_EDE3_CBC, "DESEDE/CBC/PKCS5Padding"); CIPHER_ALG_NAMES.put(CMSAlgorithm.AES128_CBC, "AES/CBC/PKCS5Padding"); CIPHER_ALG_NAMES.put(CMSAlgorithm.AES192_CBC, "AES/CBC/PKCS5Padding"); CIPHER_ALG_NAMES.put(CMSAlgorithm.AES256_CBC, "AES/CBC/PKCS5Padding"); CIPHER_ALG_NAMES.put(new ASN1ObjectIdentifier(PKCSObjectIdentifiers.rsaEncryption.getId()), "RSA/ECB/PKCS1Padding"); DIGEST_ALG_NAMES.put(OIWObjectIdentifiers.idSHA1, "SHA1"); DIGEST_ALG_NAMES.put(NISTObjectIdentifiers.id_sha224, "SHA224"); DIGEST_ALG_NAMES.put(NISTObjectIdentifiers.id_sha256, "SHA256"); DIGEST_ALG_NAMES.put(NISTObjectIdentifiers.id_sha384, "SHA384"); DIGEST_ALG_NAMES.put(NISTObjectIdentifiers.id_sha512, "SHA512"); MAC_ALG_NAMES.put(IANAObjectIdentifiers.hmacSHA1, "HMACSHA1"); MAC_ALG_NAMES.put(PKCSObjectIdentifiers.id_hmacWithSHA1, "HMACSHA1"); MAC_ALG_NAMES.put(PKCSObjectIdentifiers.id_hmacWithSHA224, "HMACSHA224"); MAC_ALG_NAMES.put(PKCSObjectIdentifiers.id_hmacWithSHA256, "HMACSHA256"); MAC_ALG_NAMES.put(PKCSObjectIdentifiers.id_hmacWithSHA384, "HMACSHA384"); MAC_ALG_NAMES.put(PKCSObjectIdentifiers.id_hmacWithSHA512, "HMACSHA512"); KEY_ALG_NAMES.put(PKCSObjectIdentifiers.rsaEncryption, "RSA"); KEY_ALG_NAMES.put(X9ObjectIdentifiers.id_dsa, "DSA"); } private JcaJceHelper helper; CRMFHelper(JcaJceHelper helper) { this.helper = helper; } PublicKey toPublicKey(SubjectPublicKeyInfo subjectPublicKeyInfo) throws CRMFException { try { X509EncodedKeySpec xspec = new X509EncodedKeySpec(subjectPublicKeyInfo.getEncoded()); AlgorithmIdentifier keyAlg = subjectPublicKeyInfo.getAlgorithm(); return createKeyFactory(keyAlg.getAlgorithm()).generatePublic(xspec); } catch (Exception e) { throw new CRMFException("invalid key: " + e.getMessage(), e); } } Cipher createCipher(ASN1ObjectIdentifier algorithm) throws CRMFException { try { String cipherName = (String)CIPHER_ALG_NAMES.get(algorithm); if (cipherName != null) { try { // this is reversed as the Sun policy files now allow unlimited strength RSA return helper.createCipher(cipherName); } catch (NoSuchAlgorithmException e) { // Ignore } } return helper.createCipher(algorithm.getId()); } catch (GeneralSecurityException e) { throw new CRMFException("cannot create cipher: " + e.getMessage(), e); } } public KeyGenerator createKeyGenerator(ASN1ObjectIdentifier algorithm) throws CRMFException { try { String cipherName = (String)BASE_CIPHER_NAMES.get(algorithm); if (cipherName != null) { try { // this is reversed as the Sun policy files now allow unlimited strength RSA return helper.createKeyGenerator(cipherName); } catch (NoSuchAlgorithmException e) { // Ignore } } return helper.createKeyGenerator(algorithm.getId()); } catch (GeneralSecurityException e) { throw new CRMFException("cannot create key generator: " + e.getMessage(), e); } } Cipher createContentCipher(final Key sKey, final AlgorithmIdentifier encryptionAlgID) throws CRMFException { return (Cipher)execute(new JCECallback() { public Object doInJCE() throws CRMFException, InvalidAlgorithmParameterException, InvalidKeyException, InvalidParameterSpecException, NoSuchAlgorithmException, NoSuchPaddingException, NoSuchProviderException { Cipher cipher = createCipher(encryptionAlgID.getAlgorithm()); ASN1Primitive sParams = (ASN1Primitive)encryptionAlgID.getParameters(); ASN1ObjectIdentifier encAlg = encryptionAlgID.getAlgorithm(); if (sParams != null && !(sParams instanceof ASN1Null)) { try { AlgorithmParameters params = createAlgorithmParameters(encryptionAlgID.getAlgorithm()); try { params.init(sParams.getEncoded(), "ASN.1"); } catch (IOException e) { throw new CRMFException("error decoding algorithm parameters.", e); } cipher.init(Cipher.DECRYPT_MODE, sKey, params); } catch (NoSuchAlgorithmException e) { if (encAlg.equals(CMSAlgorithm.DES_EDE3_CBC) || encAlg.equals(CMSAlgorithm.IDEA_CBC) || encAlg.equals(CMSAlgorithm.AES128_CBC) || encAlg.equals(CMSAlgorithm.AES192_CBC) || encAlg.equals(CMSAlgorithm.AES256_CBC)) { cipher.init(Cipher.DECRYPT_MODE, sKey, new IvParameterSpec( ASN1OctetString.getInstance(sParams).getOctets())); } else { throw e; } } } else { if (encAlg.equals(CMSAlgorithm.DES_EDE3_CBC) || encAlg.equals(CMSAlgorithm.IDEA_CBC) || encAlg.equals(CMSAlgorithm.CAST5_CBC)) { cipher.init(Cipher.DECRYPT_MODE, sKey, new IvParameterSpec(new byte[8])); } else { cipher.init(Cipher.DECRYPT_MODE, sKey); } } return cipher; } }); } AlgorithmParameters createAlgorithmParameters(ASN1ObjectIdentifier algorithm) throws NoSuchAlgorithmException, NoSuchProviderException { String algorithmName = (String)BASE_CIPHER_NAMES.get(algorithm); if (algorithmName != null) { try { // this is reversed as the Sun policy files now allow unlimited strength RSA return helper.createAlgorithmParameters(algorithmName); } catch (NoSuchAlgorithmException e) { // Ignore } } return helper.createAlgorithmParameters(algorithm.getId()); } KeyFactory createKeyFactory(ASN1ObjectIdentifier algorithm) throws CRMFException { try { String algName = (String)KEY_ALG_NAMES.get(algorithm); if (algName != null) { try { // this is reversed as the Sun policy files now allow unlimited strength RSA return helper.createKeyFactory(algName); } catch (NoSuchAlgorithmException e) { // Ignore } } return helper.createKeyFactory(algorithm.getId()); } catch (GeneralSecurityException e) { throw new CRMFException("cannot create cipher: " + e.getMessage(), e); } } MessageDigest createDigest(ASN1ObjectIdentifier algorithm) throws CRMFException { try { String digestName = (String)DIGEST_ALG_NAMES.get(algorithm); if (digestName != null) { try { // this is reversed as the Sun policy files now allow unlimited strength RSA return helper.createDigest(digestName); } catch (NoSuchAlgorithmException e) { // Ignore } } return helper.createDigest(algorithm.getId()); } catch (GeneralSecurityException e) { throw new CRMFException("cannot create cipher: " + e.getMessage(), e); } } Mac createMac(ASN1ObjectIdentifier algorithm) throws CRMFException { try { String macName = (String)MAC_ALG_NAMES.get(algorithm); if (macName != null) { try { // this is reversed as the Sun policy files now allow unlimited strength RSA return helper.createMac(macName); } catch (NoSuchAlgorithmException e) { // Ignore } } return helper.createMac(algorithm.getId()); } catch (GeneralSecurityException e) { throw new CRMFException("cannot create mac: " + e.getMessage(), e); } } AlgorithmParameterGenerator createAlgorithmParameterGenerator(ASN1ObjectIdentifier algorithm) throws GeneralSecurityException { String algorithmName = (String)BASE_CIPHER_NAMES.get(algorithm); if (algorithmName != null) { try { // this is reversed as the Sun policy files now allow unlimited strength RSA return helper.createAlgorithmParameterGenerator(algorithmName); } catch (NoSuchAlgorithmException e) { // Ignore } } return helper.createAlgorithmParameterGenerator(algorithm.getId()); } AlgorithmParameters generateParameters(ASN1ObjectIdentifier encryptionOID, SecretKey encKey, SecureRandom rand) throws CRMFException { try { AlgorithmParameterGenerator pGen = createAlgorithmParameterGenerator(encryptionOID); if (encryptionOID.equals(CMSAlgorithm.RC2_CBC)) { byte[] iv = new byte[8]; rand.nextBytes(iv); try { pGen.init(new RC2ParameterSpec(encKey.getEncoded().length * 8, iv), rand); } catch (InvalidAlgorithmParameterException e) { throw new CRMFException("parameters generation error: " + e, e); } } return pGen.generateParameters(); } catch (NoSuchAlgorithmException e) { return null; } catch (GeneralSecurityException e) { throw new CRMFException("exception creating algorithm parameter generator: " + e, e); } } AlgorithmIdentifier getAlgorithmIdentifier(ASN1ObjectIdentifier encryptionOID, AlgorithmParameters params) throws CRMFException { ASN1Encodable asn1Params; if (params != null) { try { asn1Params = ASN1Primitive.fromByteArray(params.getEncoded("ASN.1")); } catch (IOException e) { throw new CRMFException("cannot encode parameters: " + e.getMessage(), e); } } else { asn1Params = DERNull.INSTANCE; } return new AlgorithmIdentifier( encryptionOID, asn1Params); } static Object execute(JCECallback callback) throws CRMFException { try { return callback.doInJCE(); } catch (NoSuchAlgorithmException e) { throw new CRMFException("can't find algorithm.", e); } catch (InvalidKeyException e) { throw new CRMFException("key invalid in message.", e); } catch (NoSuchProviderException e) { throw new CRMFException("can't find provider.", e); } catch (NoSuchPaddingException e) { throw new CRMFException("required padding not supported.", e); } catch (InvalidAlgorithmParameterException e) { throw new CRMFException("algorithm parameters invalid.", e); } catch (InvalidParameterSpecException e) { throw new CRMFException("MAC algorithm parameter spec invalid.", e); } } static interface JCECallback { Object doInJCE() throws CRMFException, InvalidAlgorithmParameterException, InvalidKeyException, InvalidParameterSpecException, NoSuchAlgorithmException, NoSuchPaddingException, NoSuchProviderException; } } bouncycastle-1.49.orig/src/org/bouncycastle/cert/crmf/jcajce/JcaEncryptedValueBuilder.java0000644000175000017500000000153611442037352031335 0ustar ebourgebourgpackage org.bouncycastle.cert.crmf.jcajce; import java.security.cert.CertificateEncodingException; import java.security.cert.X509Certificate; import org.bouncycastle.asn1.crmf.EncryptedValue; import org.bouncycastle.cert.crmf.CRMFException; import org.bouncycastle.cert.crmf.EncryptedValueBuilder; import org.bouncycastle.cert.jcajce.JcaX509CertificateHolder; import org.bouncycastle.operator.KeyWrapper; import org.bouncycastle.operator.OutputEncryptor; public class JcaEncryptedValueBuilder extends EncryptedValueBuilder { public JcaEncryptedValueBuilder(KeyWrapper wrapper, OutputEncryptor encryptor) { super(wrapper, encryptor); } public EncryptedValue build(X509Certificate certificate) throws CertificateEncodingException, CRMFException { return build(new JcaX509CertificateHolder(certificate)); } } bouncycastle-1.49.orig/src/org/bouncycastle/cert/crmf/jcajce/package.html0000644000175000017500000000033511501604353026065 0ustar ebourgebourg JCA extensions to the CRMF online certificate request package. bouncycastle-1.49.orig/src/org/bouncycastle/cert/crmf/jcajce/JcePKMACValuesCalculator.java0000644000175000017500000000355411437115415031130 0ustar ebourgebourgpackage org.bouncycastle.cert.crmf.jcajce; import java.security.GeneralSecurityException; import java.security.MessageDigest; import java.security.Provider; import javax.crypto.Mac; import javax.crypto.spec.SecretKeySpec; import org.bouncycastle.asn1.x509.AlgorithmIdentifier; import org.bouncycastle.cert.crmf.CRMFException; import org.bouncycastle.cert.crmf.PKMACValuesCalculator; import org.bouncycastle.jcajce.DefaultJcaJceHelper; import org.bouncycastle.jcajce.NamedJcaJceHelper; import org.bouncycastle.jcajce.ProviderJcaJceHelper; public class JcePKMACValuesCalculator implements PKMACValuesCalculator { private MessageDigest digest; private Mac mac; private CRMFHelper helper; public JcePKMACValuesCalculator() { this.helper = new CRMFHelper(new DefaultJcaJceHelper()); } public JcePKMACValuesCalculator setProvider(Provider provider) { this.helper = new CRMFHelper(new ProviderJcaJceHelper(provider)); return this; } public JcePKMACValuesCalculator setProvider(String providerName) { this.helper = new CRMFHelper(new NamedJcaJceHelper(providerName)); return this; } public void setup(AlgorithmIdentifier digAlg, AlgorithmIdentifier macAlg) throws CRMFException { digest = helper.createDigest(digAlg.getAlgorithm()); mac = helper.createMac(macAlg.getAlgorithm()); } public byte[] calculateDigest(byte[] data) { return digest.digest(data); } public byte[] calculateMac(byte[] pwd, byte[] data) throws CRMFException { try { mac.init(new SecretKeySpec(pwd, mac.getAlgorithm())); return mac.doFinal(data); } catch (GeneralSecurityException e) { throw new CRMFException("failure in setup: " + e.getMessage(), e); } } } bouncycastle-1.49.orig/src/org/bouncycastle/cert/crmf/CRMFUtil.java0000644000175000017500000000220011724275407024621 0ustar ebourgebourgpackage org.bouncycastle.cert.crmf; import java.io.IOException; import java.io.OutputStream; import org.bouncycastle.asn1.ASN1Encodable; import org.bouncycastle.asn1.ASN1ObjectIdentifier; import org.bouncycastle.asn1.DEROutputStream; import org.bouncycastle.asn1.x509.ExtensionsGenerator; import org.bouncycastle.cert.CertIOException; class CRMFUtil { static void derEncodeToStream(ASN1Encodable obj, OutputStream stream) { DEROutputStream dOut = new DEROutputStream(stream); try { dOut.writeObject(obj); dOut.close(); } catch (IOException e) { throw new CRMFRuntimeException("unable to DER encode object: " + e.getMessage(), e); } } static void addExtension(ExtensionsGenerator extGenerator, ASN1ObjectIdentifier oid, boolean isCritical, ASN1Encodable value) throws CertIOException { try { extGenerator.addExtension(oid, isCritical, value); } catch (IOException e) { throw new CertIOException("cannot encode extension: " + e.getMessage(), e); } } } bouncycastle-1.49.orig/src/org/bouncycastle/cert/crmf/package.html0000644000175000017500000000037411501604353024651 0ustar ebourgebourg Basic support package for handling and creating CRMF (RFC 4211) certificate request messages. bouncycastle-1.49.orig/src/org/bouncycastle/cert/crmf/EncryptedValuePadder.java0000644000175000017500000000121311503340173027275 0ustar ebourgebourgpackage org.bouncycastle.cert.crmf; /** * An encrypted value padder is used to make sure that prior to a value been * encrypted the data is padded to a standard length. */ public interface EncryptedValuePadder { /** * Return a byte array of padded data. * * @param data the data to be padded. * @return a padded byte array containing data. */ byte[] getPaddedData(byte[] data); /** * Return a byte array of with padding removed. * * @param paddedData the data to be padded. * @return an array containing the original unpadded data. */ byte[] getUnpaddedData(byte[] paddedData); } bouncycastle-1.49.orig/src/org/bouncycastle/cert/AttributeCertificateIssuer.java0000644000175000017500000000702211725030156027604 0ustar ebourgebourgpackage org.bouncycastle.cert; import java.util.ArrayList; import java.util.List; import org.bouncycastle.asn1.ASN1Encodable; import org.bouncycastle.asn1.x500.X500Name; import org.bouncycastle.asn1.x509.AttCertIssuer; import org.bouncycastle.asn1.x509.GeneralName; import org.bouncycastle.asn1.x509.GeneralNames; import org.bouncycastle.asn1.x509.V2Form; import org.bouncycastle.util.Selector; /** * Carrying class for an attribute certificate issuer. */ public class AttributeCertificateIssuer implements Selector { final ASN1Encodable form; /** * Set the issuer directly with the ASN.1 structure. * * @param issuer The issuer */ public AttributeCertificateIssuer(AttCertIssuer issuer) { form = issuer.getIssuer(); } public AttributeCertificateIssuer(X500Name principal) { form = new V2Form(new GeneralNames(new GeneralName(principal))); } public X500Name[] getNames() { GeneralNames name; if (form instanceof V2Form) { name = ((V2Form)form).getIssuerName(); } else { name = (GeneralNames)form; } GeneralName[] names = name.getNames(); List l = new ArrayList(names.length); for (int i = 0; i != names.length; i++) { if (names[i].getTagNo() == GeneralName.directoryName) { l.add(X500Name.getInstance(names[i].getName())); } } return (X500Name[])l.toArray(new X500Name[l.size()]); } private boolean matchesDN(X500Name subject, GeneralNames targets) { GeneralName[] names = targets.getNames(); for (int i = 0; i != names.length; i++) { GeneralName gn = names[i]; if (gn.getTagNo() == GeneralName.directoryName) { if (X500Name.getInstance(gn.getName()).equals(subject)) { return true; } } } return false; } public Object clone() { return new AttributeCertificateIssuer(AttCertIssuer.getInstance(form)); } public boolean equals(Object obj) { if (obj == this) { return true; } if (!(obj instanceof AttributeCertificateIssuer)) { return false; } AttributeCertificateIssuer other = (AttributeCertificateIssuer)obj; return this.form.equals(other.form); } public int hashCode() { return this.form.hashCode(); } public boolean match(Object obj) { if (!(obj instanceof X509CertificateHolder)) { return false; } X509CertificateHolder x509Cert = (X509CertificateHolder)obj; if (form instanceof V2Form) { V2Form issuer = (V2Form)form; if (issuer.getBaseCertificateID() != null) { return issuer.getBaseCertificateID().getSerial().getValue().equals(x509Cert.getSerialNumber()) && matchesDN(x509Cert.getIssuer(), issuer.getBaseCertificateID().getIssuer()); } GeneralNames name = issuer.getIssuerName(); if (matchesDN(x509Cert.getSubject(), name)) { return true; } } else { GeneralNames name = (GeneralNames)form; if (matchesDN(x509Cert.getSubject(), name)) { return true; } } return false; } } bouncycastle-1.49.orig/src/org/bouncycastle/cert/X509CRLHolder.java0000644000175000017500000002173612070232011024443 0ustar ebourgebourgpackage org.bouncycastle.cert; import java.io.ByteArrayInputStream; import java.io.IOException; import java.io.InputStream; import java.io.OutputStream; import java.math.BigInteger; import java.util.ArrayList; import java.util.Collection; import java.util.Enumeration; import java.util.List; import java.util.Set; import org.bouncycastle.asn1.ASN1InputStream; import org.bouncycastle.asn1.ASN1ObjectIdentifier; import org.bouncycastle.asn1.DEROutputStream; import org.bouncycastle.asn1.x500.X500Name; import org.bouncycastle.asn1.x509.CertificateList; import org.bouncycastle.asn1.x509.Extension; import org.bouncycastle.asn1.x509.Extensions; import org.bouncycastle.asn1.x509.GeneralName; import org.bouncycastle.asn1.x509.GeneralNames; import org.bouncycastle.asn1.x509.IssuingDistributionPoint; import org.bouncycastle.asn1.x509.TBSCertList; import org.bouncycastle.operator.ContentVerifier; import org.bouncycastle.operator.ContentVerifierProvider; /** * Holding class for an X.509 CRL structure. */ public class X509CRLHolder { private CertificateList x509CRL; private boolean isIndirect; private Extensions extensions; private GeneralNames issuerName; private static CertificateList parseStream(InputStream stream) throws IOException { try { return CertificateList.getInstance(new ASN1InputStream(stream, true).readObject()); } catch (ClassCastException e) { throw new CertIOException("malformed data: " + e.getMessage(), e); } catch (IllegalArgumentException e) { throw new CertIOException("malformed data: " + e.getMessage(), e); } } private static boolean isIndirectCRL(Extensions extensions) { if (extensions == null) { return false; } Extension ext = extensions.getExtension(Extension.issuingDistributionPoint); return ext != null && IssuingDistributionPoint.getInstance(ext.getParsedValue()).isIndirectCRL(); } /** * Create a X509CRLHolder from the passed in bytes. * * @param crlEncoding BER/DER encoding of the CRL * @throws IOException in the event of corrupted data, or an incorrect structure. */ public X509CRLHolder(byte[] crlEncoding) throws IOException { this(parseStream(new ByteArrayInputStream(crlEncoding))); } /** * Create a X509CRLHolder from the passed in InputStream. * * @param crlStream BER/DER encoded InputStream of the CRL * @throws IOException in the event of corrupted data, or an incorrect structure. */ public X509CRLHolder(InputStream crlStream) throws IOException { this(parseStream(crlStream)); } /** * Create a X509CRLHolder from the passed in ASN.1 structure. * * @param x509CRL an ASN.1 CertificateList structure. */ public X509CRLHolder(CertificateList x509CRL) { this.x509CRL = x509CRL; this.extensions = x509CRL.getTBSCertList().getExtensions(); this.isIndirect = isIndirectCRL(extensions); this.issuerName = new GeneralNames(new GeneralName(x509CRL.getIssuer())); } /** * Return the ASN.1 encoding of this holder's CRL. * * @return a DER encoded byte array. * @throws IOException if an encoding cannot be generated. */ public byte[] getEncoded() throws IOException { return x509CRL.getEncoded(); } /** * Return the issuer of this holder's CRL. * * @return the CRL issuer. */ public X500Name getIssuer() { return X500Name.getInstance(x509CRL.getIssuer()); } public X509CRLEntryHolder getRevokedCertificate(BigInteger serialNumber) { GeneralNames currentCA = issuerName; for (Enumeration en = x509CRL.getRevokedCertificateEnumeration(); en.hasMoreElements();) { TBSCertList.CRLEntry entry = (TBSCertList.CRLEntry)en.nextElement(); if (entry.getUserCertificate().getValue().equals(serialNumber)) { return new X509CRLEntryHolder(entry, isIndirect, currentCA); } if (isIndirect && entry.hasExtensions()) { Extension currentCaName = entry.getExtensions().getExtension(Extension.certificateIssuer); if (currentCaName != null) { currentCA = GeneralNames.getInstance(currentCaName.getParsedValue()); } } } return null; } /** * Return a collection of X509CRLEntryHolder objects, giving the details of the * revoked certificates that appear on this CRL. * * @return the revoked certificates as a collection of X509CRLEntryHolder objects. */ public Collection getRevokedCertificates() { TBSCertList.CRLEntry[] entries = x509CRL.getRevokedCertificates(); List l = new ArrayList(entries.length); GeneralNames currentCA = issuerName; for (Enumeration en = x509CRL.getRevokedCertificateEnumeration(); en.hasMoreElements();) { TBSCertList.CRLEntry entry = (TBSCertList.CRLEntry)en.nextElement(); X509CRLEntryHolder crlEntry = new X509CRLEntryHolder(entry, isIndirect, currentCA); l.add(crlEntry); currentCA = crlEntry.getCertificateIssuer(); } return l; } /** * Return whether or not the holder's CRL contains extensions. * * @return true if extension are present, false otherwise. */ public boolean hasExtensions() { return extensions != null; } /** * Look up the extension associated with the passed in OID. * * @param oid the OID of the extension of interest. * * @return the extension if present, null otherwise. */ public Extension getExtension(ASN1ObjectIdentifier oid) { if (extensions != null) { return extensions.getExtension(oid); } return null; } /** * Return the extensions block associated with this CRL if there is one. * * @return the extensions block, null otherwise. */ public Extensions getExtensions() { return extensions; } /** * Returns a list of ASN1ObjectIdentifier objects representing the OIDs of the * extensions contained in this holder's CRL. * * @return a list of extension OIDs. */ public List getExtensionOIDs() { return CertUtils.getExtensionOIDs(extensions); } /** * Returns a set of ASN1ObjectIdentifier objects representing the OIDs of the * critical extensions contained in this holder's CRL. * * @return a set of critical extension OIDs. */ public Set getCriticalExtensionOIDs() { return CertUtils.getCriticalExtensionOIDs(extensions); } /** * Returns a set of ASN1ObjectIdentifier objects representing the OIDs of the * non-critical extensions contained in this holder's CRL. * * @return a set of non-critical extension OIDs. */ public Set getNonCriticalExtensionOIDs() { return CertUtils.getNonCriticalExtensionOIDs(extensions); } /** * Return the underlying ASN.1 structure for the CRL in this holder. * * @return a CertificateList object. */ public CertificateList toASN1Structure() { return x509CRL; } /** * Validate the signature on the CRL. * * @param verifierProvider a ContentVerifierProvider that can generate a verifier for the signature. * @return true if the signature is valid, false otherwise. * @throws CertException if the signature cannot be processed or is inappropriate. */ public boolean isSignatureValid(ContentVerifierProvider verifierProvider) throws CertException { TBSCertList tbsCRL = x509CRL.getTBSCertList(); if (!CertUtils.isAlgIdEqual(tbsCRL.getSignature(), x509CRL.getSignatureAlgorithm())) { throw new CertException("signature invalid - algorithm identifier mismatch"); } ContentVerifier verifier; try { verifier = verifierProvider.get((tbsCRL.getSignature())); OutputStream sOut = verifier.getOutputStream(); DEROutputStream dOut = new DEROutputStream(sOut); dOut.writeObject(tbsCRL); sOut.close(); } catch (Exception e) { throw new CertException("unable to process signature: " + e.getMessage(), e); } return verifier.verify(x509CRL.getSignature().getBytes()); } public boolean equals( Object o) { if (o == this) { return true; } if (!(o instanceof X509CRLHolder)) { return false; } X509CRLHolder other = (X509CRLHolder)o; return this.x509CRL.equals(other.x509CRL); } public int hashCode() { return this.x509CRL.hashCode(); } } bouncycastle-1.49.orig/src/org/bouncycastle/cert/selector/0000755000175000017500000000000012152033551023254 5ustar ebourgebourg././@LongLink0000000000000000000000000000015500000000000011566 Lustar rootrootbouncycastle-1.49.orig/src/org/bouncycastle/cert/selector/X509AttributeCertificateHolderSelectorBuilder.javabouncycastle-1.49.orig/src/org/bouncycastle/cert/selector/X509AttributeCertificateHolderSelectorBuil0000644000175000017500000001402511726250024033352 0ustar ebourgebourgpackage org.bouncycastle.cert.selector; import java.io.IOException; import java.math.BigInteger; import java.util.Collection; import java.util.Collections; import java.util.Date; import java.util.HashSet; import java.util.Iterator; import java.util.Set; import org.bouncycastle.asn1.x509.GeneralName; import org.bouncycastle.cert.AttributeCertificateHolder; import org.bouncycastle.cert.AttributeCertificateIssuer; import org.bouncycastle.cert.X509AttributeCertificateHolder; /** * This class builds selectors according to the set criteria. */ public class X509AttributeCertificateHolderSelectorBuilder { // TODO: name constraints??? private AttributeCertificateHolder holder; private AttributeCertificateIssuer issuer; private BigInteger serialNumber; private Date attributeCertificateValid; private X509AttributeCertificateHolder attributeCert; private Collection targetNames = new HashSet(); private Collection targetGroups = new HashSet(); public X509AttributeCertificateHolderSelectorBuilder() { } /** * Set the attribute certificate to be matched. If null is * given any will do. * * @param attributeCert The attribute certificate holder to set. */ public void setAttributeCert(X509AttributeCertificateHolder attributeCert) { this.attributeCert = attributeCert; } /** * Set the time, when the certificate must be valid. If null * is given any will do. * * @param attributeCertificateValid The attribute certificate validation * time to set. */ public void setAttributeCertificateValid(Date attributeCertificateValid) { if (attributeCertificateValid != null) { this.attributeCertificateValid = new Date(attributeCertificateValid .getTime()); } else { this.attributeCertificateValid = null; } } /** * Sets the holder. If null is given any will do. * * @param holder The holder to set. */ public void setHolder(AttributeCertificateHolder holder) { this.holder = holder; } /** * Sets the issuer the attribute certificate must have. If null * is given any will do. * * @param issuer The issuer to set. */ public void setIssuer(AttributeCertificateIssuer issuer) { this.issuer = issuer; } /** * Sets the serial number the attribute certificate must have. If * null is given any will do. * * @param serialNumber The serialNumber to set. */ public void setSerialNumber(BigInteger serialNumber) { this.serialNumber = serialNumber; } /** * Adds a target name criterion for the attribute certificate to the target * information extension criteria. The X509AttributeCertificateHolder * must contain at least one of the specified target names. *

    * Each attribute certificate may contain a target information extension * limiting the servers where this attribute certificate can be used. If * this extension is not present, the attribute certificate is not targeted * and may be accepted by any server. * * @param name The name as a GeneralName (not null) */ public void addTargetName(GeneralName name) { targetNames.add(name); } /** * Adds a collection with target names criteria. If null is * given any will do. *

    * The collection consists of either GeneralName objects or byte[] arrays representing * DER encoded GeneralName structures. * * @param names A collection of target names. * @throws java.io.IOException if a parsing error occurs. * @see #addTargetName(org.bouncycastle.asn1.x509.GeneralName) */ public void setTargetNames(Collection names) throws IOException { targetNames = extractGeneralNames(names); } /** * Adds a target group criterion for the attribute certificate to the target * information extension criteria. The X509AttributeCertificateHolder * must contain at least one of the specified target groups. *

    * Each attribute certificate may contain a target information extension * limiting the servers where this attribute certificate can be used. If * this extension is not present, the attribute certificate is not targeted * and may be accepted by any server. * * @param group The group as GeneralName form (not null) */ public void addTargetGroup(GeneralName group) { targetGroups.add(group); } /** * Adds a collection with target groups criteria. If null is * given any will do. *

    * The collection consists of GeneralName objects or byte[]Selector like implementation to select * attribute certificates from a given set of criteria. */ public class X509AttributeCertificateHolderSelector implements Selector { // TODO: name constraints??? private final AttributeCertificateHolder holder; private final AttributeCertificateIssuer issuer; private final BigInteger serialNumber; private final Date attributeCertificateValid; private final X509AttributeCertificateHolder attributeCert; private final Collection targetNames; private final Collection targetGroups; X509AttributeCertificateHolderSelector( AttributeCertificateHolder holder, AttributeCertificateIssuer issuer, BigInteger serialNumber, Date attributeCertificateValid, X509AttributeCertificateHolder attributeCert, Collection targetNames, Collection targetGroups) { this.holder = holder; this.issuer = issuer; this.serialNumber = serialNumber; this.attributeCertificateValid = attributeCertificateValid; this.attributeCert = attributeCert; this.targetNames = targetNames; this.targetGroups = targetGroups; } /** * Decides if the given attribute certificate should be selected. * * @param obj The X509AttributeCertificateHolder which should be checked. * @return true if the attribute certificate is a match * false otherwise. */ public boolean match(Object obj) { if (!(obj instanceof X509AttributeCertificateHolder)) { return false; } X509AttributeCertificateHolder attrCert = (X509AttributeCertificateHolder)obj; if (this.attributeCert != null) { if (!this.attributeCert.equals(attrCert)) { return false; } } if (serialNumber != null) { if (!attrCert.getSerialNumber().equals(serialNumber)) { return false; } } if (holder != null) { if (!attrCert.getHolder().equals(holder)) { return false; } } if (issuer != null) { if (!attrCert.getIssuer().equals(issuer)) { return false; } } if (attributeCertificateValid != null) { if (!attrCert.isValidOn(attributeCertificateValid)) { return false; } } if (!targetNames.isEmpty() || !targetGroups.isEmpty()) { Extension targetInfoExt = attrCert.getExtension(Extension.targetInformation); if (targetInfoExt != null) { TargetInformation targetinfo; try { targetinfo = TargetInformation.getInstance(targetInfoExt.getParsedValue()); } catch (IllegalArgumentException e) { return false; } Targets[] targetss = targetinfo.getTargetsObjects(); if (!targetNames.isEmpty()) { boolean found = false; for (int i=0; i * The returned collection is immutable. * * @return The collection of target names */ public Collection getTargetNames() { return targetNames; } /** * Gets the target groups. The collection consists of GeneralName objects. *

    * The returned collection is immutable. * * @return The collection of target groups. */ public Collection getTargetGroups() { return targetGroups; } } bouncycastle-1.49.orig/src/org/bouncycastle/cert/selector/X509CertificateHolderSelector.java0000644000175000017500000001042111726251114031567 0ustar ebourgebourgpackage org.bouncycastle.cert.selector; import java.math.BigInteger; import org.bouncycastle.asn1.ASN1OctetString; import org.bouncycastle.asn1.cms.IssuerAndSerialNumber; import org.bouncycastle.asn1.x500.X500Name; import org.bouncycastle.asn1.x509.Extension; import org.bouncycastle.cert.X509CertificateHolder; import org.bouncycastle.util.Arrays; import org.bouncycastle.util.Selector; /** * a basic index for a X509CertificateHolder class */ public class X509CertificateHolderSelector implements Selector { private byte[] subjectKeyId; private X500Name issuer; private BigInteger serialNumber; /** * Construct a selector with the value of a public key's subjectKeyId. * * @param subjectKeyId a subjectKeyId */ public X509CertificateHolderSelector(byte[] subjectKeyId) { this(null, null, subjectKeyId); } /** * Construct a signer ID based on the issuer and serial number of the signer's associated * certificate. * * @param issuer the issuer of the signer's associated certificate. * @param serialNumber the serial number of the signer's associated certificate. */ public X509CertificateHolderSelector(X500Name issuer, BigInteger serialNumber) { this(issuer, serialNumber, null); } /** * Construct a signer ID based on the issuer and serial number of the signer's associated * certificate. * * @param issuer the issuer of the signer's associated certificate. * @param serialNumber the serial number of the signer's associated certificate. * @param subjectKeyId the subject key identifier to use to match the signers associated certificate. */ public X509CertificateHolderSelector(X500Name issuer, BigInteger serialNumber, byte[] subjectKeyId) { this.issuer = issuer; this.serialNumber = serialNumber; this.subjectKeyId = subjectKeyId; } public X500Name getIssuer() { return issuer; } public BigInteger getSerialNumber() { return serialNumber; } public byte[] getSubjectKeyIdentifier() { return Arrays.clone(subjectKeyId); } public int hashCode() { int code = Arrays.hashCode(subjectKeyId); if (this.serialNumber != null) { code ^= this.serialNumber.hashCode(); } if (this.issuer != null) { code ^= this.issuer.hashCode(); } return code; } public boolean equals( Object o) { if (!(o instanceof X509CertificateHolderSelector)) { return false; } X509CertificateHolderSelector id = (X509CertificateHolderSelector)o; return Arrays.areEqual(subjectKeyId, id.subjectKeyId) && equalsObj(this.serialNumber, id.serialNumber) && equalsObj(this.issuer, id.issuer); } private boolean equalsObj(Object a, Object b) { return (a != null) ? a.equals(b) : b == null; } public boolean match(Object obj) { if (obj instanceof X509CertificateHolder) { X509CertificateHolder certHldr = (X509CertificateHolder)obj; if (this.getSerialNumber() != null) { IssuerAndSerialNumber iAndS = new IssuerAndSerialNumber(certHldr.toASN1Structure()); return iAndS.getName().equals(this.issuer) && iAndS.getSerialNumber().getValue().equals(this.serialNumber); } else if (subjectKeyId != null) { Extension ext = certHldr.getExtension(Extension.subjectKeyIdentifier); if (ext == null) { return Arrays.areEqual(subjectKeyId, MSOutlookKeyIdCalculator.calculateKeyId(certHldr.getSubjectPublicKeyInfo())); } byte[] subKeyID = ASN1OctetString.getInstance(ext.getParsedValue()).getOctets(); return Arrays.areEqual(subjectKeyId, subKeyID); } } else if (obj instanceof byte[]) { return Arrays.areEqual(subjectKeyId, (byte[])obj); } return false; } public Object clone() { return new X509CertificateHolderSelector(this.issuer, this.serialNumber, this.subjectKeyId); } } bouncycastle-1.49.orig/src/org/bouncycastle/cert/selector/jcajce/0000755000175000017500000000000012152033551024473 5ustar ebourgebourgbouncycastle-1.49.orig/src/org/bouncycastle/cert/selector/jcajce/JcaX509CertSelectorConverter.java0000644000175000017500000000316211726254712032644 0ustar ebourgebourgpackage org.bouncycastle.cert.selector.jcajce; import java.io.IOException; import java.math.BigInteger; import java.security.cert.X509CertSelector; import org.bouncycastle.asn1.DEROctetString; import org.bouncycastle.asn1.x500.X500Name; import org.bouncycastle.cert.selector.X509CertificateHolderSelector; public class JcaX509CertSelectorConverter { public JcaX509CertSelectorConverter() { } protected X509CertSelector doConversion(X500Name issuer, BigInteger serialNumber, byte[] subjectKeyIdentifier) { X509CertSelector selector = new X509CertSelector(); if (issuer != null) { try { selector.setIssuer(issuer.getEncoded()); } catch (IOException e) { throw new IllegalArgumentException("unable to convert issuer: " + e.getMessage()); } } if (serialNumber != null) { selector.setSerialNumber(serialNumber); } if (subjectKeyIdentifier != null) { try { selector.setSubjectKeyIdentifier(new DEROctetString(subjectKeyIdentifier).getEncoded()); } catch (IOException e) { throw new IllegalArgumentException("unable to convert issuer: " + e.getMessage()); } } return selector; } public X509CertSelector getCertSelector(X509CertificateHolderSelector holderSelector) { return doConversion(holderSelector.getIssuer(), holderSelector.getSerialNumber(), holderSelector.getSubjectKeyIdentifier()); } } ././@LongLink0000000000000000000000000000014700000000000011567 Lustar rootrootbouncycastle-1.49.orig/src/org/bouncycastle/cert/selector/jcajce/JcaX509CertificateHolderSelector.javabouncycastle-1.49.orig/src/org/bouncycastle/cert/selector/jcajce/JcaX509CertificateHolderSelector.ja0000644000175000017500000000450211736740374033114 0ustar ebourgebourgpackage org.bouncycastle.cert.selector.jcajce; import java.math.BigInteger; import java.security.cert.X509Certificate; import javax.security.auth.x500.X500Principal; import org.bouncycastle.asn1.ASN1OctetString; import org.bouncycastle.asn1.x500.X500Name; import org.bouncycastle.asn1.x509.Extension; import org.bouncycastle.cert.selector.X509CertificateHolderSelector; public class JcaX509CertificateHolderSelector extends X509CertificateHolderSelector { /** * Construct a signer identifier based on the issuer, serial number and subject key identifier (if present) of the passed in * certificate. * * @param certificate certificate providing the issue and serial number and subject key identifier. */ public JcaX509CertificateHolderSelector(X509Certificate certificate) { super(convertPrincipal(certificate.getIssuerX500Principal()), certificate.getSerialNumber(), getSubjectKeyId(certificate)); } /** * Construct a signer identifier based on the provided issuer and serial number.. * * @param issuer the issuer to use. * @param serialNumber the serial number to use. */ public JcaX509CertificateHolderSelector(X500Principal issuer, BigInteger serialNumber) { super(convertPrincipal(issuer), serialNumber); } /** * Construct a signer identifier based on the provided issuer, serial number, and subjectKeyId.. * * @param issuer the issuer to use. * @param serialNumber the serial number to use. * @param subjectKeyId the subject key ID to use. */ public JcaX509CertificateHolderSelector(X500Principal issuer, BigInteger serialNumber, byte[] subjectKeyId) { super(convertPrincipal(issuer), serialNumber, subjectKeyId); } private static X500Name convertPrincipal(X500Principal issuer) { if (issuer == null) { return null; } return X500Name.getInstance(issuer.getEncoded()); } private static byte[] getSubjectKeyId(X509Certificate cert) { byte[] ext = cert.getExtensionValue(Extension.subjectKeyIdentifier.getId()); if (ext != null) { return ASN1OctetString.getInstance(ASN1OctetString.getInstance(ext).getOctets()).getOctets(); } else { return null; } } } bouncycastle-1.49.orig/src/org/bouncycastle/cert/selector/jcajce/JcaSelectorConverter.java0000644000175000017500000000221511726521136031433 0ustar ebourgebourgpackage org.bouncycastle.cert.selector.jcajce; import java.io.IOException; import java.security.cert.X509CertSelector; import org.bouncycastle.asn1.ASN1OctetString; import org.bouncycastle.asn1.x500.X500Name; import org.bouncycastle.cert.selector.X509CertificateHolderSelector; public class JcaSelectorConverter { public JcaSelectorConverter() { } public X509CertificateHolderSelector getCertificateHolderSelector(X509CertSelector certSelector) { try { if (certSelector.getSubjectKeyIdentifier() != null) { return new X509CertificateHolderSelector(X500Name.getInstance(certSelector.getIssuerAsBytes()), certSelector.getSerialNumber(), ASN1OctetString.getInstance(certSelector.getSubjectKeyIdentifier()).getOctets()); } else { return new X509CertificateHolderSelector(X500Name.getInstance(certSelector.getIssuerAsBytes()), certSelector.getSerialNumber()); } } catch (IOException e) { throw new IllegalArgumentException("unable to convert issuer: " + e.getMessage()); } } } bouncycastle-1.49.orig/src/org/bouncycastle/cert/selector/package.html0000644000175000017500000000035711503336651025550 0ustar ebourgebourg Specialised Selector classes for certificates, CRLs, and attribute certificates. bouncycastle-1.49.orig/src/org/bouncycastle/cert/AttributeCertificateHolder.java0000644000175000017500000002523511737217451027565 0ustar ebourgebourgpackage org.bouncycastle.cert; import java.io.OutputStream; import java.math.BigInteger; import java.util.ArrayList; import java.util.List; import org.bouncycastle.asn1.ASN1Integer; import org.bouncycastle.asn1.ASN1ObjectIdentifier; import org.bouncycastle.asn1.ASN1Sequence; import org.bouncycastle.asn1.x500.X500Name; import org.bouncycastle.asn1.x509.AlgorithmIdentifier; import org.bouncycastle.asn1.x509.GeneralName; import org.bouncycastle.asn1.x509.GeneralNames; import org.bouncycastle.asn1.x509.Holder; import org.bouncycastle.asn1.x509.IssuerSerial; import org.bouncycastle.asn1.x509.ObjectDigestInfo; import org.bouncycastle.operator.DigestCalculator; import org.bouncycastle.operator.DigestCalculatorProvider; import org.bouncycastle.util.Arrays; import org.bouncycastle.util.Selector; /** * The Holder object. * *

     *          Holder ::= SEQUENCE {
     *                baseCertificateID   [0] IssuerSerial OPTIONAL,
     *                         -- the issuer and serial number of
     *                         -- the holder's Public Key Certificate
     *                entityName          [1] GeneralNames OPTIONAL,
     *                         -- the name of the claimant or role
     *                objectDigestInfo    [2] ObjectDigestInfo OPTIONAL
     *                         -- used to directly authenticate the holder,
     *                         -- for example, an executable
     *          }
     * 
    *

    * Note: If objectDigestInfo comparisons are to be carried out the static * method setDigestCalculatorProvider must be called once to configure the class * to do the necessary calculations. *

    */ public class AttributeCertificateHolder implements Selector { private static DigestCalculatorProvider digestCalculatorProvider; final Holder holder; AttributeCertificateHolder(ASN1Sequence seq) { holder = Holder.getInstance(seq); } public AttributeCertificateHolder(X500Name issuerName, BigInteger serialNumber) { holder = new Holder(new IssuerSerial( new GeneralNames(new GeneralName(issuerName)), new ASN1Integer(serialNumber))); } public AttributeCertificateHolder(X509CertificateHolder cert) { holder = new Holder(new IssuerSerial(generateGeneralNames(cert.getIssuer()), new ASN1Integer(cert.getSerialNumber()))); } public AttributeCertificateHolder(X500Name principal) { holder = new Holder(generateGeneralNames(principal)); } /** * Constructs a holder for v2 attribute certificates with a hash value for * some type of object. *

    * digestedObjectType can be one of the following: *

      *
    • 0 - publicKey - A hash of the public key of the holder must be * passed. *
    • 1 - publicKeyCert - A hash of the public key certificate of the * holder must be passed. *
    • 2 - otherObjectDigest - A hash of some other object type must be * passed. otherObjectTypeID must not be empty. *
    *

    * This cannot be used if a v1 attribute certificate is used. * * @param digestedObjectType The digest object type. * @param digestAlgorithm The algorithm identifier for the hash. * @param otherObjectTypeID The object type ID if * digestedObjectType is * otherObjectDigest. * @param objectDigest The hash value. */ public AttributeCertificateHolder(int digestedObjectType, ASN1ObjectIdentifier digestAlgorithm, ASN1ObjectIdentifier otherObjectTypeID, byte[] objectDigest) { holder = new Holder(new ObjectDigestInfo(digestedObjectType, otherObjectTypeID, new AlgorithmIdentifier(digestAlgorithm), Arrays .clone(objectDigest))); } /** * Returns the digest object type if an object digest info is used. *

    *

      *
    • 0 - publicKey - A hash of the public key of the holder must be * passed. *
    • 1 - publicKeyCert - A hash of the public key certificate of the * holder must be passed. *
    • 2 - otherObjectDigest - A hash of some other object type must be * passed. otherObjectTypeID must not be empty. *
    * * @return The digest object type or -1 if no object digest info is set. */ public int getDigestedObjectType() { if (holder.getObjectDigestInfo() != null) { return holder.getObjectDigestInfo().getDigestedObjectType() .getValue().intValue(); } return -1; } /** * Returns algorithm identifier for the digest used if ObjectDigestInfo is present. * * @return digest AlgorithmIdentifier or null if ObjectDigestInfo is absent. */ public AlgorithmIdentifier getDigestAlgorithm() { if (holder.getObjectDigestInfo() != null) { return holder.getObjectDigestInfo().getDigestAlgorithm(); } return null; } /** * Returns the hash if an object digest info is used. * * @return The hash or null if ObjectDigestInfo is absent. */ public byte[] getObjectDigest() { if (holder.getObjectDigestInfo() != null) { return holder.getObjectDigestInfo().getObjectDigest().getBytes(); } return null; } /** * Returns the digest algorithm ID if an object digest info is used. * * @return The digest algorithm ID or null if no object * digest info is set. */ public ASN1ObjectIdentifier getOtherObjectTypeID() { if (holder.getObjectDigestInfo() != null) { new ASN1ObjectIdentifier(holder.getObjectDigestInfo().getOtherObjectTypeID().getId()); } return null; } private GeneralNames generateGeneralNames(X500Name principal) { return new GeneralNames(new GeneralName(principal)); } private boolean matchesDN(X500Name subject, GeneralNames targets) { GeneralName[] names = targets.getNames(); for (int i = 0; i != names.length; i++) { GeneralName gn = names[i]; if (gn.getTagNo() == GeneralName.directoryName) { if (X500Name.getInstance(gn.getName()).equals(subject)) { return true; } } } return false; } private X500Name[] getPrincipals(GeneralName[] names) { List l = new ArrayList(names.length); for (int i = 0; i != names.length; i++) { if (names[i].getTagNo() == GeneralName.directoryName) { l.add(X500Name.getInstance(names[i].getName())); } } return (X500Name[])l.toArray(new X500Name[l.size()]); } /** * Return any principal objects inside the attribute certificate holder * entity names field. * * @return an array of Principal objects (usually X500Principal), null if no * entity names field is set. */ public X500Name[] getEntityNames() { if (holder.getEntityName() != null) { return getPrincipals(holder.getEntityName().getNames()); } return null; } /** * Return the principals associated with the issuer attached to this holder * * @return an array of principals, null if no BaseCertificateID is set. */ public X500Name[] getIssuer() { if (holder.getBaseCertificateID() != null) { return getPrincipals(holder.getBaseCertificateID().getIssuer().getNames()); } return null; } /** * Return the serial number associated with the issuer attached to this * holder. * * @return the certificate serial number, null if no BaseCertificateID is * set. */ public BigInteger getSerialNumber() { if (holder.getBaseCertificateID() != null) { return holder.getBaseCertificateID().getSerial().getValue(); } return null; } public Object clone() { return new AttributeCertificateHolder((ASN1Sequence)holder.toASN1Primitive()); } public boolean match(Object obj) { if (!(obj instanceof X509CertificateHolder)) { return false; } X509CertificateHolder x509Cert = (X509CertificateHolder)obj; if (holder.getBaseCertificateID() != null) { return holder.getBaseCertificateID().getSerial().getValue().equals(x509Cert.getSerialNumber()) && matchesDN(x509Cert.getIssuer(), holder.getBaseCertificateID().getIssuer()); } if (holder.getEntityName() != null) { if (matchesDN(x509Cert.getSubject(), holder.getEntityName())) { return true; } } if (holder.getObjectDigestInfo() != null) { try { DigestCalculator digCalc = digestCalculatorProvider.get(holder.getObjectDigestInfo().getDigestAlgorithm()); OutputStream digOut = digCalc.getOutputStream(); switch (getDigestedObjectType()) { case ObjectDigestInfo.publicKey: // TODO: DSA Dss-parms digOut.write(x509Cert.getSubjectPublicKeyInfo().getEncoded()); break; case ObjectDigestInfo.publicKeyCert: digOut.write(x509Cert.getEncoded()); break; } digOut.close(); if (!Arrays.areEqual(digCalc.getDigest(), getObjectDigest())) { return false; } } catch (Exception e) { return false; } } return false; } public boolean equals(Object obj) { if (obj == this) { return true; } if (!(obj instanceof AttributeCertificateHolder)) { return false; } AttributeCertificateHolder other = (AttributeCertificateHolder)obj; return this.holder.equals(other.holder); } public int hashCode() { return this.holder.hashCode(); } /** * Set a digest calculator provider to be used if matches are attempted using * ObjectDigestInfo, * * @param digCalcProvider a provider of digest calculators. */ public static void setDigestCalculatorProvider(DigestCalculatorProvider digCalcProvider) { digestCalculatorProvider = digCalcProvider; } } bouncycastle-1.49.orig/src/org/bouncycastle/cert/X509v2CRLBuilder.java0000644000175000017500000001436111737275254025111 0ustar ebourgebourgpackage org.bouncycastle.cert; import java.math.BigInteger; import java.util.Date; import java.util.Enumeration; import org.bouncycastle.asn1.ASN1Encodable; import org.bouncycastle.asn1.ASN1GeneralizedTime; import org.bouncycastle.asn1.ASN1Integer; import org.bouncycastle.asn1.ASN1ObjectIdentifier; import org.bouncycastle.asn1.ASN1Sequence; import org.bouncycastle.asn1.x500.X500Name; import org.bouncycastle.asn1.x509.Extensions; import org.bouncycastle.asn1.x509.ExtensionsGenerator; import org.bouncycastle.asn1.x509.TBSCertList; import org.bouncycastle.asn1.x509.Time; import org.bouncycastle.asn1.x509.V2TBSCertListGenerator; import org.bouncycastle.asn1.x509.X509Extensions; import org.bouncycastle.operator.ContentSigner; /** * class to produce an X.509 Version 2 CRL. */ public class X509v2CRLBuilder { private V2TBSCertListGenerator tbsGen; private ExtensionsGenerator extGenerator; /** * Basic constructor. * * @param issuer the issuer this CRL is associated with. * @param thisUpdate the date of this update. */ public X509v2CRLBuilder( X500Name issuer, Date thisUpdate) { tbsGen = new V2TBSCertListGenerator(); extGenerator = new ExtensionsGenerator(); tbsGen.setIssuer(issuer); tbsGen.setThisUpdate(new Time(thisUpdate)); } /** * Set the date by which the next CRL will become available. * * @param date date of next CRL update. * @return the current builder. */ public X509v2CRLBuilder setNextUpdate( Date date) { tbsGen.setNextUpdate(new Time(date)); return this; } /** * Add a CRL entry with the just reasonCode extension. * * @param userCertificateSerial serial number of revoked certificate. * @param revocationDate date of certificate revocation. * @param reason the reason code, as indicated in CRLReason, i.e CRLReason.keyCompromise, or 0 if not to be used. * @return the current builder. */ public X509v2CRLBuilder addCRLEntry(BigInteger userCertificateSerial, Date revocationDate, int reason) { tbsGen.addCRLEntry(new ASN1Integer(userCertificateSerial), new Time(revocationDate), reason); return this; } /** * Add a CRL entry with an invalidityDate extension as well as a reasonCode extension. This is used * where the date of revocation might be after issues with the certificate may have occurred. * * @param userCertificateSerial serial number of revoked certificate. * @param revocationDate date of certificate revocation. * @param reason the reason code, as indicated in CRLReason, i.e CRLReason.keyCompromise, or 0 if not to be used. * @param invalidityDate the date on which the private key for the certificate became compromised or the certificate otherwise became invalid. * @return the current builder. */ public X509v2CRLBuilder addCRLEntry(BigInteger userCertificateSerial, Date revocationDate, int reason, Date invalidityDate) { tbsGen.addCRLEntry(new ASN1Integer(userCertificateSerial), new Time(revocationDate), reason, new ASN1GeneralizedTime(invalidityDate)); return this; } /** * Add a CRL entry with extensions. * * @param userCertificateSerial serial number of revoked certificate. * @param revocationDate date of certificate revocation. * @param extensions extension set to be associated with this CRLEntry. * @return the current builder. * @deprecated use method taking Extensions */ public X509v2CRLBuilder addCRLEntry(BigInteger userCertificateSerial, Date revocationDate, X509Extensions extensions) { tbsGen.addCRLEntry(new ASN1Integer(userCertificateSerial), new Time(revocationDate), Extensions.getInstance(extensions)); return this; } /** * Add a CRL entry with extensions. * * @param userCertificateSerial serial number of revoked certificate. * @param revocationDate date of certificate revocation. * @param extensions extension set to be associated with this CRLEntry. * @return the current builder. */ public X509v2CRLBuilder addCRLEntry(BigInteger userCertificateSerial, Date revocationDate, Extensions extensions) { tbsGen.addCRLEntry(new ASN1Integer(userCertificateSerial), new Time(revocationDate), extensions); return this; } /** * Add the CRLEntry objects contained in a previous CRL. * * @param other the X509CRLHolder to source the other entries from. * @return the current builder. */ public X509v2CRLBuilder addCRL(X509CRLHolder other) { TBSCertList revocations = other.toASN1Structure().getTBSCertList(); if (revocations != null) { for (Enumeration en = revocations.getRevokedCertificateEnumeration(); en.hasMoreElements();) { tbsGen.addCRLEntry(ASN1Sequence.getInstance(((ASN1Encodable)en.nextElement()).toASN1Primitive())); } } return this; } /** * Add a given extension field for the standard extensions tag (tag 3) * * @param oid the OID defining the extension type. * @param isCritical true if the extension is critical, false otherwise. * @param value the ASN.1 structure that forms the extension's value. * @return this builder object. */ public X509v2CRLBuilder addExtension( ASN1ObjectIdentifier oid, boolean isCritical, ASN1Encodable value) throws CertIOException { CertUtils.addExtension(extGenerator, oid, isCritical, value); return this; } /** * Generate an X.509 CRL, based on the current issuer and subject * using the passed in signer. * * @param signer the content signer to be used to generate the signature validating the certificate. * @return a holder containing the resulting signed certificate. */ public X509CRLHolder build( ContentSigner signer) { tbsGen.setSignature(signer.getAlgorithmIdentifier()); if (!extGenerator.isEmpty()) { tbsGen.setExtensions(extGenerator.generate()); } return CertUtils.generateFullCRL(signer, tbsGen.generateTBSCertList()); } } bouncycastle-1.49.orig/src/org/bouncycastle/cert/cmp/0000755000175000017500000000000012152033551022213 5ustar ebourgebourgbouncycastle-1.49.orig/src/org/bouncycastle/cert/cmp/CMPRuntimeException.java0000644000175000017500000000047711442065637026743 0ustar ebourgebourgpackage org.bouncycastle.cert.cmp; public class CMPRuntimeException extends RuntimeException { private Throwable cause; public CMPRuntimeException(String msg, Throwable cause) { super(msg); this.cause = cause; } public Throwable getCause() { return cause; } }bouncycastle-1.49.orig/src/org/bouncycastle/cert/cmp/ProtectedPKIMessageBuilder.java0000644000175000017500000002110511736740374030205 0ustar ebourgebourgpackage org.bouncycastle.cert.cmp; import java.io.IOException; import java.io.OutputStream; import java.util.ArrayList; import java.util.Date; import java.util.List; import org.bouncycastle.asn1.ASN1EncodableVector; import org.bouncycastle.asn1.ASN1Encoding; import org.bouncycastle.asn1.ASN1GeneralizedTime; import org.bouncycastle.asn1.DERBitString; import org.bouncycastle.asn1.DERSequence; import org.bouncycastle.asn1.cmp.CMPCertificate; import org.bouncycastle.asn1.cmp.InfoTypeAndValue; import org.bouncycastle.asn1.cmp.PKIBody; import org.bouncycastle.asn1.cmp.PKIFreeText; import org.bouncycastle.asn1.cmp.PKIHeader; import org.bouncycastle.asn1.cmp.PKIHeaderBuilder; import org.bouncycastle.asn1.cmp.PKIMessage; import org.bouncycastle.asn1.x509.AlgorithmIdentifier; import org.bouncycastle.asn1.x509.GeneralName; import org.bouncycastle.cert.X509CertificateHolder; import org.bouncycastle.operator.ContentSigner; import org.bouncycastle.operator.MacCalculator; /** * Builder for creating a protected PKI message. */ public class ProtectedPKIMessageBuilder { private PKIHeaderBuilder hdrBuilder; private PKIBody body; private List generalInfos = new ArrayList(); private List extraCerts = new ArrayList(); /** * Commence a message with the header version CMP_2000. * * @param sender message sender. * @param recipient intended recipient. */ public ProtectedPKIMessageBuilder(GeneralName sender, GeneralName recipient) { this(PKIHeader.CMP_2000, sender, recipient); } /** * Commence a message with a specific header type. * * @param pvno the version CMP_1999 or CMP_2000. * @param sender message sender. * @param recipient intended recipient. */ public ProtectedPKIMessageBuilder(int pvno, GeneralName sender, GeneralName recipient) { hdrBuilder = new PKIHeaderBuilder(pvno, sender, recipient); } /** * Set the identifier for the transaction the new message will belong to. * * @param tid the transaction ID. * @return the current builder instance. */ public ProtectedPKIMessageBuilder setTransactionID(byte[] tid) { hdrBuilder.setTransactionID(tid); return this; } /** * Include a human-readable message in the new message. * * @param freeText the contents of the human readable message, * @return the current builder instance. */ public ProtectedPKIMessageBuilder setFreeText(PKIFreeText freeText) { hdrBuilder.setFreeText(freeText); return this; } /** * Add a generalInfo data record to the header of the new message. * * @param genInfo the generalInfo data to be added. * @return the current builder instance. */ public ProtectedPKIMessageBuilder addGeneralInfo(InfoTypeAndValue genInfo) { generalInfos.add(genInfo); return this; } /** * Set the creation time for the new message. * * @param time the message creation time. * @return the current builder instance. */ public ProtectedPKIMessageBuilder setMessageTime(Date time) { hdrBuilder.setMessageTime(new ASN1GeneralizedTime(time)); return this; } /** * Set the recipient key identifier for the key to be used to verify the new message. * * @param kid a key identifier. * @return the current builder instance. */ public ProtectedPKIMessageBuilder setRecipKID(byte[] kid) { hdrBuilder.setRecipKID(kid); return this; } /** * Set the recipient nonce field on the new message. * * @param nonce a NONCE, typically copied from the sender nonce of the previous message. * @return the current builder instance. */ public ProtectedPKIMessageBuilder setRecipNonce(byte[] nonce) { hdrBuilder.setRecipNonce(nonce); return this; } /** * Set the sender key identifier for the key used to protect the new message. * * @param kid a key identifier. * @return the current builder instance. */ public ProtectedPKIMessageBuilder setSenderKID(byte[] kid) { hdrBuilder.setSenderKID(kid); return this; } /** * Set the sender nonce field on the new message. * * @param nonce a NONCE, typically 128 bits of random data. * @return the current builder instance. */ public ProtectedPKIMessageBuilder setSenderNonce(byte[] nonce) { hdrBuilder.setSenderNonce(nonce); return this; } /** * Set the body for the new message * * @param body the message body. * @return the current builder instance. */ public ProtectedPKIMessageBuilder setBody(PKIBody body) { this.body = body; return this; } /** * Add an "extra certificate" to the message. * * @param extraCert the extra certificate to add. * @return the current builder instance. */ public ProtectedPKIMessageBuilder addCMPCertificate(X509CertificateHolder extraCert) { extraCerts.add(extraCert); return this; } /** * Build a protected PKI message which has MAC based integrity protection. * * @param macCalculator MAC calculator. * @return the resulting protected PKI message. * @throws CMPException if the protection MAC cannot be calculated. */ public ProtectedPKIMessage build(MacCalculator macCalculator) throws CMPException { finaliseHeader(macCalculator.getAlgorithmIdentifier()); PKIHeader header = hdrBuilder.build(); try { DERBitString protection = new DERBitString(calculateMac(macCalculator, header, body)); return finaliseMessage(header, protection); } catch (IOException e) { throw new CMPException("unable to encode MAC input: " + e.getMessage(), e); } } /** * Build a protected PKI message which has MAC based integrity protection. * * @param signer the ContentSigner to be used to calculate the signature. * @return the resulting protected PKI message. * @throws CMPException if the protection signature cannot be calculated. */ public ProtectedPKIMessage build(ContentSigner signer) throws CMPException { finaliseHeader(signer.getAlgorithmIdentifier()); PKIHeader header = hdrBuilder.build(); try { DERBitString protection = new DERBitString(calculateSignature(signer, header, body)); return finaliseMessage(header, protection); } catch (IOException e) { throw new CMPException("unable to encode signature input: " + e.getMessage(), e); } } private void finaliseHeader(AlgorithmIdentifier algorithmIdentifier) { hdrBuilder.setProtectionAlg(algorithmIdentifier); if (!generalInfos.isEmpty()) { InfoTypeAndValue[] genInfos = new InfoTypeAndValue[generalInfos.size()]; hdrBuilder.setGeneralInfo((InfoTypeAndValue[])generalInfos.toArray(genInfos)); } } private ProtectedPKIMessage finaliseMessage(PKIHeader header, DERBitString protection) { if (!extraCerts.isEmpty()) { CMPCertificate[] cmpCerts = new CMPCertificate[extraCerts.size()]; for (int i = 0; i != cmpCerts.length; i++) { cmpCerts[i] = new CMPCertificate(((X509CertificateHolder)extraCerts.get(i)).toASN1Structure()); } return new ProtectedPKIMessage(new PKIMessage(header, body, protection, cmpCerts)); } else { return new ProtectedPKIMessage(new PKIMessage(header, body, protection)); } } private byte[] calculateSignature(ContentSigner signer, PKIHeader header, PKIBody body) throws IOException { ASN1EncodableVector v = new ASN1EncodableVector(); v.add(header); v.add(body); OutputStream sOut = signer.getOutputStream(); sOut.write(new DERSequence(v).getEncoded(ASN1Encoding.DER)); sOut.close(); return signer.getSignature(); } private byte[] calculateMac(MacCalculator macCalculator, PKIHeader header, PKIBody body) throws IOException { ASN1EncodableVector v = new ASN1EncodableVector(); v.add(header); v.add(body); OutputStream sOut = macCalculator.getOutputStream(); sOut.write(new DERSequence(v).getEncoded(ASN1Encoding.DER)); sOut.close(); return macCalculator.getMac(); } } bouncycastle-1.49.orig/src/org/bouncycastle/cert/cmp/RevocationDetails.java0000644000175000017500000000134311472377733026517 0ustar ebourgebourgpackage org.bouncycastle.cert.cmp; import java.math.BigInteger; import org.bouncycastle.asn1.cmp.RevDetails; import org.bouncycastle.asn1.x500.X500Name; public class RevocationDetails { private RevDetails revDetails; public RevocationDetails(RevDetails revDetails) { this.revDetails = revDetails; } public X500Name getSubject() { return revDetails.getCertDetails().getSubject(); } public X500Name getIssuer() { return revDetails.getCertDetails().getIssuer(); } public BigInteger getSerialNumber() { return revDetails.getCertDetails().getSerialNumber().getValue(); } public RevDetails toASN1Structure() { return revDetails; } } bouncycastle-1.49.orig/src/org/bouncycastle/cert/cmp/RevocationDetailsBuilder.java0000644000175000017500000000260611724276327030026 0ustar ebourgebourgpackage org.bouncycastle.cert.cmp; import java.math.BigInteger; import org.bouncycastle.asn1.ASN1Integer; import org.bouncycastle.asn1.cmp.RevDetails; import org.bouncycastle.asn1.crmf.CertTemplateBuilder; import org.bouncycastle.asn1.x500.X500Name; import org.bouncycastle.asn1.x509.SubjectPublicKeyInfo; public class RevocationDetailsBuilder { private CertTemplateBuilder templateBuilder = new CertTemplateBuilder(); public RevocationDetailsBuilder setPublicKey(SubjectPublicKeyInfo publicKey) { if (publicKey != null) { templateBuilder.setPublicKey(publicKey); } return this; } public RevocationDetailsBuilder setIssuer(X500Name issuer) { if (issuer != null) { templateBuilder.setIssuer(issuer); } return this; } public RevocationDetailsBuilder setSerialNumber(BigInteger serialNumber) { if (serialNumber != null) { templateBuilder.setSerialNumber(new ASN1Integer(serialNumber)); } return this; } public RevocationDetailsBuilder setSubject(X500Name subject) { if (subject != null) { templateBuilder.setSubject(subject); } return this; } public RevocationDetails build() { return new RevocationDetails(new RevDetails(templateBuilder.build())); } } bouncycastle-1.49.orig/src/org/bouncycastle/cert/cmp/CertificateStatus.java0000644000175000017500000000361011442065637026517 0ustar ebourgebourgpackage org.bouncycastle.cert.cmp; import java.math.BigInteger; import org.bouncycastle.asn1.cmp.CertStatus; import org.bouncycastle.asn1.cmp.PKIStatusInfo; import org.bouncycastle.asn1.x509.AlgorithmIdentifier; import org.bouncycastle.cert.X509CertificateHolder; import org.bouncycastle.operator.DigestAlgorithmIdentifierFinder; import org.bouncycastle.operator.DigestCalculator; import org.bouncycastle.operator.DigestCalculatorProvider; import org.bouncycastle.operator.OperatorCreationException; import org.bouncycastle.util.Arrays; public class CertificateStatus { private DigestAlgorithmIdentifierFinder digestAlgFinder; private CertStatus certStatus; CertificateStatus(DigestAlgorithmIdentifierFinder digestAlgFinder, CertStatus certStatus) { this.digestAlgFinder = digestAlgFinder; this.certStatus = certStatus; } public PKIStatusInfo getStatusInfo() { return certStatus.getStatusInfo(); } public BigInteger getCertRequestID() { return certStatus.getCertReqId().getValue(); } public boolean isVerified(X509CertificateHolder certHolder, DigestCalculatorProvider digesterProvider) throws CMPException { AlgorithmIdentifier digAlg = digestAlgFinder.find(certHolder.toASN1Structure().getSignatureAlgorithm()); if (digAlg == null) { throw new CMPException("cannot find algorithm for digest from signature"); } DigestCalculator digester; try { digester = digesterProvider.get(digAlg); } catch (OperatorCreationException e) { throw new CMPException("unable to create digester: " + e.getMessage(), e); } CMPUtil.derEncodeToStream(certHolder.toASN1Structure(), digester.getOutputStream()); return Arrays.areEqual(certStatus.getCertHash().getOctets(), digester.getDigest()); } } bouncycastle-1.49.orig/src/org/bouncycastle/cert/cmp/CertificateConfirmationContentBuilder.java0000644000175000017500000000530411442065637032530 0ustar ebourgebourgpackage org.bouncycastle.cert.cmp; import java.math.BigInteger; import java.util.ArrayList; import java.util.List; import org.bouncycastle.asn1.ASN1EncodableVector; import org.bouncycastle.asn1.DERSequence; import org.bouncycastle.asn1.cmp.CertConfirmContent; import org.bouncycastle.asn1.cmp.CertStatus; import org.bouncycastle.asn1.x509.AlgorithmIdentifier; import org.bouncycastle.cert.X509CertificateHolder; import org.bouncycastle.operator.DefaultDigestAlgorithmIdentifierFinder; import org.bouncycastle.operator.DigestAlgorithmIdentifierFinder; import org.bouncycastle.operator.DigestCalculator; import org.bouncycastle.operator.DigestCalculatorProvider; import org.bouncycastle.operator.OperatorCreationException; public class CertificateConfirmationContentBuilder { private DigestAlgorithmIdentifierFinder digestAlgFinder; private List acceptedCerts = new ArrayList(); private List acceptedReqIds = new ArrayList(); public CertificateConfirmationContentBuilder() { this(new DefaultDigestAlgorithmIdentifierFinder()); } public CertificateConfirmationContentBuilder(DigestAlgorithmIdentifierFinder digestAlgFinder) { this.digestAlgFinder = digestAlgFinder; } public CertificateConfirmationContentBuilder addAcceptedCertificate(X509CertificateHolder certHolder, BigInteger certReqID) { acceptedCerts.add(certHolder); acceptedReqIds.add(certReqID); return this; } public CertificateConfirmationContent build(DigestCalculatorProvider digesterProvider) throws CMPException { ASN1EncodableVector v = new ASN1EncodableVector(); for (int i = 0; i != acceptedCerts.size(); i++) { X509CertificateHolder certHolder = (X509CertificateHolder)acceptedCerts.get(i); BigInteger reqID = (BigInteger)acceptedReqIds.get(i); AlgorithmIdentifier digAlg = digestAlgFinder.find(certHolder.toASN1Structure().getSignatureAlgorithm()); if (digAlg == null) { throw new CMPException("cannot find algorithm for digest from signature"); } DigestCalculator digester; try { digester = digesterProvider.get(digAlg); } catch (OperatorCreationException e) { throw new CMPException("unable to create digest: " + e.getMessage(), e); } CMPUtil.derEncodeToStream(certHolder.toASN1Structure(), digester.getOutputStream()); v.add(new CertStatus(digester.getDigest(), reqID)); } return new CertificateConfirmationContent(CertConfirmContent.getInstance(new DERSequence(v)), digestAlgFinder); } } bouncycastle-1.49.orig/src/org/bouncycastle/cert/cmp/GeneralPKIMessage.java0000644000175000017500000000402111624572761026317 0ustar ebourgebourgpackage org.bouncycastle.cert.cmp; import java.io.IOException; import org.bouncycastle.asn1.ASN1Primitive; import org.bouncycastle.asn1.cmp.PKIBody; import org.bouncycastle.asn1.cmp.PKIHeader; import org.bouncycastle.asn1.cmp.PKIMessage; import org.bouncycastle.cert.CertIOException; /** * General wrapper for a generic PKIMessage */ public class GeneralPKIMessage { private final PKIMessage pkiMessage; private static PKIMessage parseBytes(byte[] encoding) throws IOException { try { return PKIMessage.getInstance(ASN1Primitive.fromByteArray(encoding)); } catch (ClassCastException e) { throw new CertIOException("malformed data: " + e.getMessage(), e); } catch (IllegalArgumentException e) { throw new CertIOException("malformed data: " + e.getMessage(), e); } } /** * Create a PKIMessage from the passed in bytes. * * @param encoding BER/DER encoding of the PKIMessage * @throws IOException in the event of corrupted data, or an incorrect structure. */ public GeneralPKIMessage(byte[] encoding) throws IOException { this(parseBytes(encoding)); } /** * Wrap a PKIMessage ASN.1 structure. * * @param pkiMessage base PKI message. */ public GeneralPKIMessage(PKIMessage pkiMessage) { this.pkiMessage = pkiMessage; } public PKIHeader getHeader() { return pkiMessage.getHeader(); } public PKIBody getBody() { return pkiMessage.getBody(); } /** * Return true if this message has protection bits on it. A return value of true * indicates the message can be used to construct a ProtectedPKIMessage. * * @return true if message has protection, false otherwise. */ public boolean hasProtection() { return pkiMessage.getHeader().getProtectionAlg() != null; } public PKIMessage toASN1Structure() { return pkiMessage; } } bouncycastle-1.49.orig/src/org/bouncycastle/cert/cmp/CMPUtil.java0000644000175000017500000000111611442065637024345 0ustar ebourgebourgpackage org.bouncycastle.cert.cmp; import java.io.IOException; import java.io.OutputStream; import org.bouncycastle.asn1.ASN1Encodable; import org.bouncycastle.asn1.DEROutputStream; class CMPUtil { static void derEncodeToStream(ASN1Encodable obj, OutputStream stream) { DEROutputStream dOut = new DEROutputStream(stream); try { dOut.writeObject(obj); dOut.close(); } catch (IOException e) { throw new CMPRuntimeException("unable to DER encode object: " + e.getMessage(), e); } } } bouncycastle-1.49.orig/src/org/bouncycastle/cert/cmp/ProtectedPKIMessage.java0000644000175000017500000001364311625352321026672 0ustar ebourgebourgpackage org.bouncycastle.cert.cmp; import java.io.IOException; import java.io.OutputStream; import org.bouncycastle.asn1.ASN1EncodableVector; import org.bouncycastle.asn1.ASN1Encoding; import org.bouncycastle.asn1.DERSequence; import org.bouncycastle.asn1.cmp.CMPCertificate; import org.bouncycastle.asn1.cmp.CMPObjectIdentifiers; import org.bouncycastle.asn1.cmp.PBMParameter; import org.bouncycastle.asn1.cmp.PKIBody; import org.bouncycastle.asn1.cmp.PKIHeader; import org.bouncycastle.asn1.cmp.PKIMessage; import org.bouncycastle.cert.X509CertificateHolder; import org.bouncycastle.cert.crmf.PKMACBuilder; import org.bouncycastle.operator.ContentVerifier; import org.bouncycastle.operator.ContentVerifierProvider; import org.bouncycastle.operator.MacCalculator; import org.bouncycastle.util.Arrays; /** * Wrapper for a PKIMessage with protection attached to it. */ public class ProtectedPKIMessage { private PKIMessage pkiMessage; /** * Base constructor. * * @param pkiMessage a GeneralPKIMessage with */ public ProtectedPKIMessage(GeneralPKIMessage pkiMessage) { if (!pkiMessage.hasProtection()) { throw new IllegalArgumentException("PKIMessage not protected"); } this.pkiMessage = pkiMessage.toASN1Structure(); } ProtectedPKIMessage(PKIMessage pkiMessage) { if (pkiMessage.getHeader().getProtectionAlg() == null) { throw new IllegalArgumentException("PKIMessage not protected"); } this.pkiMessage = pkiMessage; } /** * Return the message header. * * @return the message's PKIHeader structure. */ public PKIHeader getHeader() { return pkiMessage.getHeader(); } /** * Return the message body. * * @return the message's PKIBody structure. */ public PKIBody getBody() { return pkiMessage.getBody(); } /** * Return the underlying ASN.1 structure contained in this object. * * @return a PKIMessage structure. */ public PKIMessage toASN1Structure() { return pkiMessage; } /** * Determine whether the message is protected by a password based MAC. Use verify(PKMACBuilder, char[]) * to verify the message if this method returns true. * * @return true if protection MAC PBE based, false otherwise. */ public boolean hasPasswordBasedMacProtection() { return pkiMessage.getHeader().getProtectionAlg().getAlgorithm().equals(CMPObjectIdentifiers.passwordBasedMac); } /** * Return the extra certificates associated with this message. * * @return an array of extra certificates, zero length if none present. */ public X509CertificateHolder[] getCertificates() { CMPCertificate[] certs = pkiMessage.getExtraCerts(); if (certs == null) { return new X509CertificateHolder[0]; } X509CertificateHolder[] res = new X509CertificateHolder[certs.length]; for (int i = 0; i != certs.length; i++) { res[i] = new X509CertificateHolder(certs[i].getX509v3PKCert()); } return res; } /** * Verify a message with a public key based signature attached. * * @param verifierProvider a provider of signature verifiers. * @return true if the provider is able to create a verifier that validates * the signature, false otherwise. * @throws CMPException if an exception is thrown trying to verify the signature. */ public boolean verify(ContentVerifierProvider verifierProvider) throws CMPException { ContentVerifier verifier; try { verifier = verifierProvider.get(pkiMessage.getHeader().getProtectionAlg()); return verifySignature(pkiMessage.getProtection().getBytes(), verifier); } catch (Exception e) { throw new CMPException("unable to verify signature: " + e.getMessage(), e); } } /** * Verify a message with password based MAC protection. * * @param pkMacBuilder MAC builder that can be used to construct the appropriate MacCalculator * @param password the MAC password * @return true if the passed in password and MAC builder verify the message, false otherwise. * @throws CMPException if algorithm not MAC based, or an exception is thrown verifying the MAC. */ public boolean verify(PKMACBuilder pkMacBuilder, char[] password) throws CMPException { if (!CMPObjectIdentifiers.passwordBasedMac.equals(pkiMessage.getHeader().getProtectionAlg().getAlgorithm())) { throw new CMPException("protection algorithm not mac based"); } try { pkMacBuilder.setParameters(PBMParameter.getInstance(pkiMessage.getHeader().getProtectionAlg().getParameters())); MacCalculator calculator = pkMacBuilder.build(password); OutputStream macOut = calculator.getOutputStream(); ASN1EncodableVector v = new ASN1EncodableVector(); v.add(pkiMessage.getHeader()); v.add(pkiMessage.getBody()); macOut.write(new DERSequence(v).getEncoded(ASN1Encoding.DER)); macOut.close(); return Arrays.areEqual(calculator.getMac(), pkiMessage.getProtection().getBytes()); } catch (Exception e) { throw new CMPException("unable to verify MAC: " + e.getMessage(), e); } } private boolean verifySignature(byte[] signature, ContentVerifier verifier) throws IOException { ASN1EncodableVector v = new ASN1EncodableVector(); v.add(pkiMessage.getHeader()); v.add(pkiMessage.getBody()); OutputStream sOut = verifier.getOutputStream(); sOut.write(new DERSequence(v).getEncoded(ASN1Encoding.DER)); sOut.close(); return verifier.verify(signature); } } bouncycastle-1.49.orig/src/org/bouncycastle/cert/cmp/package.html0000644000175000017500000000037611501601440024475 0ustar ebourgebourg Basic support package for handling and creating CMP (RFC 4210) certificate management messages. bouncycastle-1.49.orig/src/org/bouncycastle/cert/cmp/CertificateConfirmationContent.java0000644000175000017500000000233211442065637031217 0ustar ebourgebourgpackage org.bouncycastle.cert.cmp; import org.bouncycastle.asn1.cmp.CertConfirmContent; import org.bouncycastle.asn1.cmp.CertStatus; import org.bouncycastle.operator.DefaultDigestAlgorithmIdentifierFinder; import org.bouncycastle.operator.DigestAlgorithmIdentifierFinder; public class CertificateConfirmationContent { private DigestAlgorithmIdentifierFinder digestAlgFinder; private CertConfirmContent content; public CertificateConfirmationContent(CertConfirmContent content) { this(content, new DefaultDigestAlgorithmIdentifierFinder()); } public CertificateConfirmationContent(CertConfirmContent content, DigestAlgorithmIdentifierFinder digestAlgFinder) { this.digestAlgFinder = digestAlgFinder; this.content = content; } public CertConfirmContent toASN1Structure() { return content; } public CertificateStatus[] getStatusMessages() { CertStatus[] statusArray = content.toCertStatusArray(); CertificateStatus[] ret = new CertificateStatus[statusArray.length]; for (int i = 0; i != ret.length; i++) { ret[i] = new CertificateStatus(digestAlgFinder, statusArray[i]); } return ret; } } bouncycastle-1.49.orig/src/org/bouncycastle/cert/cmp/CMPException.java0000644000175000017500000000055711442065637025376 0ustar ebourgebourgpackage org.bouncycastle.cert.cmp; public class CMPException extends Exception { private Throwable cause; public CMPException(String msg, Throwable cause) { super(msg); this.cause = cause; } public CMPException(String msg) { super(msg); } public Throwable getCause() { return cause; } }bouncycastle-1.49.orig/src/org/bouncycastle/cert/X509v1CertificateBuilder.java0000644000175000017500000000437211724275704026707 0ustar ebourgebourgpackage org.bouncycastle.cert; import java.math.BigInteger; import java.util.Date; import org.bouncycastle.asn1.ASN1Integer; import org.bouncycastle.asn1.x500.X500Name; import org.bouncycastle.asn1.x509.SubjectPublicKeyInfo; import org.bouncycastle.asn1.x509.Time; import org.bouncycastle.asn1.x509.V1TBSCertificateGenerator; import org.bouncycastle.operator.ContentSigner; /** * class to produce an X.509 Version 1 certificate. */ public class X509v1CertificateBuilder { private V1TBSCertificateGenerator tbsGen; /** * Create a builder for a version 1 certificate. * * @param issuer the certificate issuer * @param serial the certificate serial number * @param notBefore the date before which the certificate is not valid * @param notAfter the date after which the certificate is not valid * @param subject the certificate subject * @param publicKeyInfo the info structure for the public key to be associated with this certificate. */ public X509v1CertificateBuilder(X500Name issuer, BigInteger serial, Date notBefore, Date notAfter, X500Name subject, SubjectPublicKeyInfo publicKeyInfo) { if (issuer == null) { throw new IllegalArgumentException("issuer must not be null"); } if (publicKeyInfo == null) { throw new IllegalArgumentException("publicKeyInfo must not be null"); } tbsGen = new V1TBSCertificateGenerator(); tbsGen.setSerialNumber(new ASN1Integer(serial)); tbsGen.setIssuer(issuer); tbsGen.setStartDate(new Time(notBefore)); tbsGen.setEndDate(new Time(notAfter)); tbsGen.setSubject(subject); tbsGen.setSubjectPublicKeyInfo(publicKeyInfo); } /** * Generate an X509 certificate, based on the current issuer and subject * using the passed in signer. * * @param signer the content signer to be used to generate the signature validating the certificate. * @return a holder containing the resulting signed certificate. */ public X509CertificateHolder build( ContentSigner signer) { tbsGen.setSignature(signer.getAlgorithmIdentifier()); return CertUtils.generateFullCert(signer, tbsGen.generateTBSCertificate()); } }bouncycastle-1.49.orig/src/org/bouncycastle/cert/ocsp/0000755000175000017500000000000012152033551022400 5ustar ebourgebourgbouncycastle-1.49.orig/src/org/bouncycastle/cert/ocsp/CertificateID.java0000644000175000017500000001130211724561172025710 0ustar ebourgebourgpackage org.bouncycastle.cert.ocsp; import java.io.OutputStream; import java.math.BigInteger; import org.bouncycastle.asn1.ASN1Encoding; import org.bouncycastle.asn1.ASN1Integer; import org.bouncycastle.asn1.ASN1ObjectIdentifier; import org.bouncycastle.asn1.ASN1OctetString; import org.bouncycastle.asn1.DERNull; import org.bouncycastle.asn1.DEROctetString; import org.bouncycastle.asn1.ocsp.CertID; import org.bouncycastle.asn1.oiw.OIWObjectIdentifiers; import org.bouncycastle.asn1.x509.AlgorithmIdentifier; import org.bouncycastle.asn1.x509.SubjectPublicKeyInfo; import org.bouncycastle.cert.X509CertificateHolder; import org.bouncycastle.operator.DigestCalculator; import org.bouncycastle.operator.DigestCalculatorProvider; import org.bouncycastle.operator.OperatorCreationException; public class CertificateID { public static final AlgorithmIdentifier HASH_SHA1 = new AlgorithmIdentifier(OIWObjectIdentifiers.idSHA1, DERNull.INSTANCE); private final CertID id; public CertificateID( CertID id) { if (id == null) { throw new IllegalArgumentException("'id' cannot be null"); } this.id = id; } /** * create from an issuer certificate and the serial number of the * certificate it signed. * * @param issuerCert issuing certificate * @param number serial number * * @exception OCSPException if any problems occur creating the id fields. */ public CertificateID( DigestCalculator digestCalculator, X509CertificateHolder issuerCert, BigInteger number) throws OCSPException { this.id = createCertID(digestCalculator, issuerCert, new ASN1Integer(number)); } public ASN1ObjectIdentifier getHashAlgOID() { return id.getHashAlgorithm().getAlgorithm(); } public byte[] getIssuerNameHash() { return id.getIssuerNameHash().getOctets(); } public byte[] getIssuerKeyHash() { return id.getIssuerKeyHash().getOctets(); } /** * return the serial number for the certificate associated * with this request. */ public BigInteger getSerialNumber() { return id.getSerialNumber().getValue(); } public boolean matchesIssuer(X509CertificateHolder issuerCert, DigestCalculatorProvider digCalcProvider) throws OCSPException { try { return createCertID(digCalcProvider.get(id.getHashAlgorithm()), issuerCert, id.getSerialNumber()).equals(id); } catch (OperatorCreationException e) { throw new OCSPException("unable to create digest calculator: " + e.getMessage(), e); } } public CertID toASN1Object() { return id; } public boolean equals( Object o) { if (!(o instanceof CertificateID)) { return false; } CertificateID obj = (CertificateID)o; return id.toASN1Primitive().equals(obj.id.toASN1Primitive()); } public int hashCode() { return id.toASN1Primitive().hashCode(); } /** * Create a new CertificateID for a new serial number derived from a previous one * calculated for the same CA certificate. * * @param original the previously calculated CertificateID for the CA. * @param newSerialNumber the serial number for the new certificate of interest. * * @return a new CertificateID for newSerialNumber */ public static CertificateID deriveCertificateID(CertificateID original, BigInteger newSerialNumber) { return new CertificateID(new CertID(original.id.getHashAlgorithm(), original.id.getIssuerNameHash(), original.id.getIssuerKeyHash(), new ASN1Integer(newSerialNumber))); } private static CertID createCertID(DigestCalculator digCalc, X509CertificateHolder issuerCert, ASN1Integer serialNumber) throws OCSPException { try { OutputStream dgOut = digCalc.getOutputStream(); dgOut.write(issuerCert.toASN1Structure().getSubject().getEncoded(ASN1Encoding.DER)); dgOut.close(); ASN1OctetString issuerNameHash = new DEROctetString(digCalc.getDigest()); SubjectPublicKeyInfo info = issuerCert.getSubjectPublicKeyInfo(); dgOut = digCalc.getOutputStream(); dgOut.write(info.getPublicKeyData().getBytes()); dgOut.close(); ASN1OctetString issuerKeyHash = new DEROctetString(digCalc.getDigest()); return new CertID(digCalc.getAlgorithmIdentifier(), issuerNameHash, issuerKeyHash, serialNumber); } catch (Exception e) { throw new OCSPException("problem creating ID: " + e, e); } } } bouncycastle-1.49.orig/src/org/bouncycastle/cert/ocsp/UnknownStatus.java0000644000175000017500000000027211474644376026132 0ustar ebourgebourgpackage org.bouncycastle.cert.ocsp; /** * wrapper for the UnknownInfo object */ public class UnknownStatus implements CertificateStatus { public UnknownStatus() { } } bouncycastle-1.49.orig/src/org/bouncycastle/cert/ocsp/RespData.java0000644000175000017500000000215311724337165024763 0ustar ebourgebourgpackage org.bouncycastle.cert.ocsp; import java.util.Date; import org.bouncycastle.asn1.ASN1Sequence; import org.bouncycastle.asn1.ocsp.ResponseData; import org.bouncycastle.asn1.ocsp.SingleResponse; import org.bouncycastle.asn1.x509.Extensions; public class RespData { private ResponseData data; public RespData( ResponseData data) { this.data = data; } public int getVersion() { return data.getVersion().getValue().intValue() + 1; } public RespID getResponderId() { return new RespID(data.getResponderID()); } public Date getProducedAt() { return OCSPUtils.extractDate(data.getProducedAt()); } public SingleResp[] getResponses() { ASN1Sequence s = data.getResponses(); SingleResp[] rs = new SingleResp[s.size()]; for (int i = 0; i != rs.length; i++) { rs[i] = new SingleResp(SingleResponse.getInstance(s.getObjectAt(i))); } return rs; } public Extensions getResponseExtensions() { return data.getResponseExtensions(); } } bouncycastle-1.49.orig/src/org/bouncycastle/cert/ocsp/Req.java0000644000175000017500000000071611724337165024012 0ustar ebourgebourgpackage org.bouncycastle.cert.ocsp; import org.bouncycastle.asn1.ocsp.Request; import org.bouncycastle.asn1.x509.Extensions; public class Req { private Request req; public Req( Request req) { this.req = req; } public CertificateID getCertID() { return new CertificateID(req.getReqCert()); } public Extensions getSingleRequestExtensions() { return req.getSingleRequestExtensions(); } } bouncycastle-1.49.orig/src/org/bouncycastle/cert/ocsp/OCSPReqBuilder.java0000644000175000017500000001252611724561172026005 0ustar ebourgebourgpackage org.bouncycastle.cert.ocsp; import java.io.OutputStream; import java.util.ArrayList; import java.util.Iterator; import java.util.List; import org.bouncycastle.asn1.ASN1EncodableVector; import org.bouncycastle.asn1.ASN1Encoding; import org.bouncycastle.asn1.DERBitString; import org.bouncycastle.asn1.DERSequence; import org.bouncycastle.asn1.ocsp.OCSPRequest; import org.bouncycastle.asn1.ocsp.Request; import org.bouncycastle.asn1.ocsp.Signature; import org.bouncycastle.asn1.ocsp.TBSRequest; import org.bouncycastle.asn1.x500.X500Name; import org.bouncycastle.asn1.x509.AlgorithmIdentifier; import org.bouncycastle.asn1.x509.Extensions; import org.bouncycastle.asn1.x509.GeneralName; import org.bouncycastle.cert.X509CertificateHolder; import org.bouncycastle.operator.ContentSigner; public class OCSPReqBuilder { private List list = new ArrayList(); private GeneralName requestorName = null; private Extensions requestExtensions = null; private class RequestObject { CertificateID certId; Extensions extensions; public RequestObject( CertificateID certId, Extensions extensions) { this.certId = certId; this.extensions = extensions; } public Request toRequest() throws Exception { return new Request(certId.toASN1Object(), extensions); } } /** * Add a request for the given CertificateID. * * @param certId certificate ID of interest */ public OCSPReqBuilder addRequest( CertificateID certId) { list.add(new RequestObject(certId, null)); return this; } /** * Add a request with extensions * * @param certId certificate ID of interest * @param singleRequestExtensions the extensions to attach to the request */ public OCSPReqBuilder addRequest( CertificateID certId, Extensions singleRequestExtensions) { list.add(new RequestObject(certId, singleRequestExtensions)); return this; } /** * Set the requestor name to the passed in X500Principal * * @param requestorName a X500Principal representing the requestor name. */ public OCSPReqBuilder setRequestorName( X500Name requestorName) { this.requestorName = new GeneralName(GeneralName.directoryName, requestorName); return this; } public OCSPReqBuilder setRequestorName( GeneralName requestorName) { this.requestorName = requestorName; return this; } public OCSPReqBuilder setRequestExtensions( Extensions requestExtensions) { this.requestExtensions = requestExtensions; return this; } private OCSPReq generateRequest( ContentSigner contentSigner, X509CertificateHolder[] chain) throws OCSPException { Iterator it = list.iterator(); ASN1EncodableVector requests = new ASN1EncodableVector(); while (it.hasNext()) { try { requests.add(((RequestObject)it.next()).toRequest()); } catch (Exception e) { throw new OCSPException("exception creating Request", e); } } TBSRequest tbsReq = new TBSRequest(requestorName, new DERSequence(requests), requestExtensions); Signature signature = null; if (contentSigner != null) { if (requestorName == null) { throw new OCSPException("requestorName must be specified if request is signed."); } try { OutputStream sOut = contentSigner.getOutputStream(); sOut.write(tbsReq.getEncoded(ASN1Encoding.DER)); sOut.close(); } catch (Exception e) { throw new OCSPException("exception processing TBSRequest: " + e, e); } DERBitString bitSig = new DERBitString(contentSigner.getSignature()); AlgorithmIdentifier sigAlgId = contentSigner.getAlgorithmIdentifier(); if (chain != null && chain.length > 0) { ASN1EncodableVector v = new ASN1EncodableVector(); for (int i = 0; i != chain.length; i++) { v.add(chain[i].toASN1Structure()); } signature = new Signature(sigAlgId, bitSig, new DERSequence(v)); } else { signature = new Signature(sigAlgId, bitSig); } } return new OCSPReq(new OCSPRequest(tbsReq, signature)); } /** * Generate an unsigned request * * @return the OCSPReq * @throws org.bouncycastle.ocsp.OCSPException */ public OCSPReq build() throws OCSPException { return generateRequest(null, null); } public OCSPReq build( ContentSigner signer, X509CertificateHolder[] chain) throws OCSPException, IllegalArgumentException { if (signer == null) { throw new IllegalArgumentException("no signer specified"); } return generateRequest(signer, chain); } } bouncycastle-1.49.orig/src/org/bouncycastle/cert/ocsp/RespID.java0000644000175000017500000000425311475100256024401 0ustar ebourgebourgpackage org.bouncycastle.cert.ocsp; import java.io.OutputStream; import org.bouncycastle.asn1.DERNull; import org.bouncycastle.asn1.DEROctetString; import org.bouncycastle.asn1.ocsp.ResponderID; import org.bouncycastle.asn1.oiw.OIWObjectIdentifiers; import org.bouncycastle.asn1.x500.X500Name; import org.bouncycastle.asn1.x509.AlgorithmIdentifier; import org.bouncycastle.asn1.x509.SubjectPublicKeyInfo; import org.bouncycastle.operator.DigestCalculator; /** * Carrier for a ResponderID. */ public class RespID { public static final AlgorithmIdentifier HASH_SHA1 = new AlgorithmIdentifier(OIWObjectIdentifiers.idSHA1, DERNull.INSTANCE); ResponderID id; public RespID( ResponderID id) { this.id = id; } public RespID( X500Name name) { this.id = new ResponderID(name); } /** * Calculate a RespID based on the public key of the responder. * * @param subjectPublicKeyInfo the info structure for the responder public key. * @param digCalc a SHA-1 digest calculator. * @throws OCSPException on exception creating ID. */ public RespID( SubjectPublicKeyInfo subjectPublicKeyInfo, DigestCalculator digCalc) throws OCSPException { try { if (!digCalc.getAlgorithmIdentifier().equals(HASH_SHA1)) { throw new IllegalArgumentException("only SHA-1 can be used with RespID"); } OutputStream digOut = digCalc.getOutputStream(); digOut.write(subjectPublicKeyInfo.getPublicKeyData().getBytes()); digOut.close(); this.id = new ResponderID(new DEROctetString(digCalc.getDigest())); } catch (Exception e) { throw new OCSPException("problem creating ID: " + e, e); } } public ResponderID toASN1Object() { return id; } public boolean equals( Object o) { if (!(o instanceof RespID)) { return false; } RespID obj = (RespID)o; return id.equals(obj.id); } public int hashCode() { return id.hashCode(); } } bouncycastle-1.49.orig/src/org/bouncycastle/cert/ocsp/CertificateStatus.java0000644000175000017500000000020311474643526026703 0ustar ebourgebourgpackage org.bouncycastle.cert.ocsp; public interface CertificateStatus { public static final CertificateStatus GOOD = null; } bouncycastle-1.49.orig/src/org/bouncycastle/cert/ocsp/SingleResp.java0000644000175000017500000000450711724561171025334 0ustar ebourgebourgpackage org.bouncycastle.cert.ocsp; import java.util.Date; import java.util.List; import java.util.Set; import org.bouncycastle.asn1.ASN1ObjectIdentifier; import org.bouncycastle.asn1.ocsp.CertStatus; import org.bouncycastle.asn1.ocsp.RevokedInfo; import org.bouncycastle.asn1.ocsp.SingleResponse; import org.bouncycastle.asn1.x509.Extension; import org.bouncycastle.asn1.x509.Extensions; public class SingleResp { private SingleResponse resp; private Extensions extensions; public SingleResp( SingleResponse resp) { this.resp = resp; this.extensions = resp.getSingleExtensions(); } public CertificateID getCertID() { return new CertificateID(resp.getCertID()); } /** * Return the status object for the response - null indicates good. * * @return the status object for the response, null if it is good. */ public CertificateStatus getCertStatus() { CertStatus s = resp.getCertStatus(); if (s.getTagNo() == 0) { return null; // good } else if (s.getTagNo() == 1) { return new RevokedStatus(RevokedInfo.getInstance(s.getStatus())); } return new UnknownStatus(); } public Date getThisUpdate() { return OCSPUtils.extractDate(resp.getThisUpdate()); } /** * return the NextUpdate value - note: this is an optional field so may * be returned as null. * * @return nextUpdate, or null if not present. */ public Date getNextUpdate() { if (resp.getNextUpdate() == null) { return null; } return OCSPUtils.extractDate(resp.getNextUpdate()); } public boolean hasExtensions() { return extensions != null; } public Extension getExtension(ASN1ObjectIdentifier oid) { if (extensions != null) { return extensions.getExtension(oid); } return null; } public List getExtensionOIDs() { return OCSPUtils.getExtensionOIDs(extensions); } public Set getCriticalExtensionOIDs() { return OCSPUtils.getCriticalExtensionOIDs(extensions); } public Set getNonCriticalExtensionOIDs() { return OCSPUtils.getNonCriticalExtensionOIDs(extensions); } } bouncycastle-1.49.orig/src/org/bouncycastle/cert/ocsp/OCSPReq.java0000644000175000017500000001617312143622361024472 0ustar ebourgebourgpackage org.bouncycastle.cert.ocsp; import java.io.ByteArrayOutputStream; import java.io.IOException; import java.io.OutputStream; import java.util.List; import java.util.Set; import org.bouncycastle.asn1.ASN1Encoding; import org.bouncycastle.asn1.ASN1Exception; import org.bouncycastle.asn1.ASN1InputStream; import org.bouncycastle.asn1.ASN1ObjectIdentifier; import org.bouncycastle.asn1.ASN1OutputStream; import org.bouncycastle.asn1.ASN1Sequence; import org.bouncycastle.asn1.ocsp.OCSPRequest; import org.bouncycastle.asn1.ocsp.Request; import org.bouncycastle.asn1.x509.Certificate; import org.bouncycastle.asn1.x509.Extension; import org.bouncycastle.asn1.x509.Extensions; import org.bouncycastle.asn1.x509.GeneralName; import org.bouncycastle.cert.CertIOException; import org.bouncycastle.cert.X509CertificateHolder; import org.bouncycastle.operator.ContentVerifier; import org.bouncycastle.operator.ContentVerifierProvider; /** *
     * OCSPRequest     ::=     SEQUENCE {
     *       tbsRequest                  TBSRequest,
     *       optionalSignature   [0]     EXPLICIT Signature OPTIONAL }
     *
     *   TBSRequest      ::=     SEQUENCE {
     *       version             [0]     EXPLICIT Version DEFAULT v1,
     *       requestorName       [1]     EXPLICIT GeneralName OPTIONAL,
     *       requestList                 SEQUENCE OF Request,
     *       requestExtensions   [2]     EXPLICIT Extensions OPTIONAL }
     *
     *   Signature       ::=     SEQUENCE {
     *       signatureAlgorithm      AlgorithmIdentifier,
     *       signature               BIT STRING,
     *       certs               [0] EXPLICIT SEQUENCE OF Certificate OPTIONAL}
     *
     *   Version         ::=             INTEGER  {  v1(0) }
     *
     *   Request         ::=     SEQUENCE {
     *       reqCert                     CertID,
     *       singleRequestExtensions     [0] EXPLICIT Extensions OPTIONAL }
     *
     *   CertID          ::=     SEQUENCE {
     *       hashAlgorithm       AlgorithmIdentifier,
     *       issuerNameHash      OCTET STRING, -- Hash of Issuer's DN
     *       issuerKeyHash       OCTET STRING, -- Hash of Issuers public key
     *       serialNumber        CertificateSerialNumber }
     * 
    */ public class OCSPReq { private static final X509CertificateHolder[] EMPTY_CERTS = new X509CertificateHolder[0]; private OCSPRequest req; private Extensions extensions; public OCSPReq( OCSPRequest req) { this.req = req; this.extensions = req.getTbsRequest().getRequestExtensions(); } public OCSPReq( byte[] req) throws IOException { this(new ASN1InputStream(req)); } private OCSPReq( ASN1InputStream aIn) throws IOException { try { this.req = OCSPRequest.getInstance(aIn.readObject()); if (req == null) { throw new CertIOException("malformed request: no request data found"); } this.extensions = req.getTbsRequest().getRequestExtensions(); } catch (IllegalArgumentException e) { throw new CertIOException("malformed request: " + e.getMessage(), e); } catch (ClassCastException e) { throw new CertIOException("malformed request: " + e.getMessage(), e); } catch (ASN1Exception e) { throw new CertIOException("malformed request: " + e.getMessage(), e); } } public int getVersionNumber() { return req.getTbsRequest().getVersion().getValue().intValue() + 1; } public GeneralName getRequestorName() { return GeneralName.getInstance(req.getTbsRequest().getRequestorName()); } public Req[] getRequestList() { ASN1Sequence seq = req.getTbsRequest().getRequestList(); Req[] requests = new Req[seq.size()]; for (int i = 0; i != requests.length; i++) { requests[i] = new Req(Request.getInstance(seq.getObjectAt(i))); } return requests; } public boolean hasExtensions() { return extensions != null; } public Extension getExtension(ASN1ObjectIdentifier oid) { if (extensions != null) { return extensions.getExtension(oid); } return null; } public List getExtensionOIDs() { return OCSPUtils.getExtensionOIDs(extensions); } public Set getCriticalExtensionOIDs() { return OCSPUtils.getCriticalExtensionOIDs(extensions); } public Set getNonCriticalExtensionOIDs() { return OCSPUtils.getNonCriticalExtensionOIDs(extensions); } /** * return the object identifier representing the signature algorithm */ public ASN1ObjectIdentifier getSignatureAlgOID() { if (!this.isSigned()) { return null; } return req.getOptionalSignature().getSignatureAlgorithm().getAlgorithm(); } public byte[] getSignature() { if (!this.isSigned()) { return null; } return req.getOptionalSignature().getSignature().getBytes(); } public X509CertificateHolder[] getCerts() { // // load the certificates if we have any // if (req.getOptionalSignature() != null) { ASN1Sequence s = req.getOptionalSignature().getCerts(); if (s != null) { X509CertificateHolder[] certs = new X509CertificateHolder[s.size()]; for (int i = 0; i != certs.length; i++) { certs[i] = new X509CertificateHolder(Certificate.getInstance(s.getObjectAt(i))); } return certs; } return EMPTY_CERTS; } else { return EMPTY_CERTS; } } /** * Return whether or not this request is signed. * * @return true if signed false otherwise. */ public boolean isSigned() { return req.getOptionalSignature() != null; } /** * verify the signature against the TBSRequest object we contain. */ public boolean isSignatureValid( ContentVerifierProvider verifierProvider) throws OCSPException { if (!this.isSigned()) { throw new OCSPException("attempt to verify signature on unsigned object"); } try { ContentVerifier verifier = verifierProvider.get(req.getOptionalSignature().getSignatureAlgorithm()); OutputStream sOut = verifier.getOutputStream(); sOut.write(req.getTbsRequest().getEncoded(ASN1Encoding.DER)); return verifier.verify(this.getSignature()); } catch (Exception e) { throw new OCSPException("exception processing signature: " + e, e); } } /** * return the ASN.1 encoded representation of this object. */ public byte[] getEncoded() throws IOException { ByteArrayOutputStream bOut = new ByteArrayOutputStream(); ASN1OutputStream aOut = new ASN1OutputStream(bOut); aOut.writeObject(req); return bOut.toByteArray(); } } bouncycastle-1.49.orig/src/org/bouncycastle/cert/ocsp/OCSPRespBuilder.java0000644000175000017500000000362511475067164026174 0ustar ebourgebourgpackage org.bouncycastle.cert.ocsp; import java.io.IOException; import org.bouncycastle.asn1.ASN1OctetString; import org.bouncycastle.asn1.DEROctetString; import org.bouncycastle.asn1.ocsp.OCSPObjectIdentifiers; import org.bouncycastle.asn1.ocsp.OCSPResponse; import org.bouncycastle.asn1.ocsp.OCSPResponseStatus; import org.bouncycastle.asn1.ocsp.ResponseBytes; /** * base generator for an OCSP response - at the moment this only supports the * generation of responses containing BasicOCSP responses. */ public class OCSPRespBuilder { public static final int SUCCESSFUL = 0; // Response has valid confirmations public static final int MALFORMED_REQUEST = 1; // Illegal confirmation request public static final int INTERNAL_ERROR = 2; // Internal error in issuer public static final int TRY_LATER = 3; // Try again later // (4) is not used public static final int SIG_REQUIRED = 5; // Must sign the request public static final int UNAUTHORIZED = 6; // Request unauthorized public OCSPResp build( int status, Object response) throws OCSPException { if (response == null) { return new OCSPResp(new OCSPResponse(new OCSPResponseStatus(status), null)); } if (response instanceof BasicOCSPResp) { BasicOCSPResp r = (BasicOCSPResp)response; ASN1OctetString octs; try { octs = new DEROctetString(r.getEncoded()); } catch (IOException e) { throw new OCSPException("can't encode object.", e); } ResponseBytes rb = new ResponseBytes( OCSPObjectIdentifiers.id_pkix_ocsp_basic, octs); return new OCSPResp(new OCSPResponse( new OCSPResponseStatus(status), rb)); } throw new OCSPException("unknown response object"); } } bouncycastle-1.49.orig/src/org/bouncycastle/cert/ocsp/BasicOCSPResp.java0000644000175000017500000001212012151251423025576 0ustar ebourgebourgpackage org.bouncycastle.cert.ocsp; import java.io.IOException; import java.io.OutputStream; import java.util.Date; import java.util.List; import java.util.Set; import org.bouncycastle.asn1.ASN1Encoding; import org.bouncycastle.asn1.ASN1ObjectIdentifier; import org.bouncycastle.asn1.ASN1Sequence; import org.bouncycastle.asn1.ocsp.BasicOCSPResponse; import org.bouncycastle.asn1.ocsp.ResponseData; import org.bouncycastle.asn1.ocsp.SingleResponse; import org.bouncycastle.asn1.x509.Certificate; import org.bouncycastle.asn1.x509.Extension; import org.bouncycastle.asn1.x509.Extensions; import org.bouncycastle.cert.X509CertificateHolder; import org.bouncycastle.operator.ContentVerifier; import org.bouncycastle.operator.ContentVerifierProvider; /** *
     * BasicOCSPResponse       ::= SEQUENCE {
     *    tbsResponseData      ResponseData,
     *    signatureAlgorithm   AlgorithmIdentifier,
     *    signature            BIT STRING,
     *    certs                [0] EXPLICIT SEQUENCE OF Certificate OPTIONAL }
     * 
    */ public class BasicOCSPResp { private BasicOCSPResponse resp; private ResponseData data; private Extensions extensions; public BasicOCSPResp( BasicOCSPResponse resp) { this.resp = resp; this.data = resp.getTbsResponseData(); this.extensions = Extensions.getInstance(resp.getTbsResponseData().getResponseExtensions()); } /** * Return the DER encoding of the tbsResponseData field. * @return DER encoding of tbsResponseData */ public byte[] getTBSResponseData() { try { return resp.getTbsResponseData().getEncoded(ASN1Encoding.DER); } catch (IOException e) { return null; } } public int getVersion() { return data.getVersion().getValue().intValue() + 1; } public RespID getResponderId() { return new RespID(data.getResponderID()); } public Date getProducedAt() { return OCSPUtils.extractDate(data.getProducedAt()); } public SingleResp[] getResponses() { ASN1Sequence s = data.getResponses(); SingleResp[] rs = new SingleResp[s.size()]; for (int i = 0; i != rs.length; i++) { rs[i] = new SingleResp(SingleResponse.getInstance(s.getObjectAt(i))); } return rs; } public boolean hasExtensions() { return extensions != null; } public Extension getExtension(ASN1ObjectIdentifier oid) { if (extensions != null) { return extensions.getExtension(oid); } return null; } public List getExtensionOIDs() { return OCSPUtils.getExtensionOIDs(extensions); } public Set getCriticalExtensionOIDs() { return OCSPUtils.getCriticalExtensionOIDs(extensions); } public Set getNonCriticalExtensionOIDs() { return OCSPUtils.getNonCriticalExtensionOIDs(extensions); } public ASN1ObjectIdentifier getSignatureAlgOID() { return resp.getSignatureAlgorithm().getAlgorithm(); } public byte[] getSignature() { return resp.getSignature().getBytes(); } public X509CertificateHolder[] getCerts() { // // load the certificates if we have any // if (resp.getCerts() != null) { ASN1Sequence s = resp.getCerts(); if (s != null) { X509CertificateHolder[] certs = new X509CertificateHolder[s.size()]; for (int i = 0; i != certs.length; i++) { certs[i] = new X509CertificateHolder(Certificate.getInstance(s.getObjectAt(i))); } return certs; } return OCSPUtils.EMPTY_CERTS; } else { return OCSPUtils.EMPTY_CERTS; } } /** * verify the signature against the tbsResponseData object we contain. */ public boolean isSignatureValid( ContentVerifierProvider verifierProvider) throws OCSPException { try { ContentVerifier verifier = verifierProvider.get(resp.getSignatureAlgorithm()); OutputStream vOut = verifier.getOutputStream(); vOut.write(resp.getTbsResponseData().getEncoded(ASN1Encoding.DER)); vOut.close(); return verifier.verify(this.getSignature()); } catch (Exception e) { throw new OCSPException("exception processing sig: " + e, e); } } /** * return the ASN.1 encoded representation of this object. */ public byte[] getEncoded() throws IOException { return resp.getEncoded(); } public boolean equals(Object o) { if (o == this) { return true; } if (!(o instanceof BasicOCSPResp)) { return false; } BasicOCSPResp r = (BasicOCSPResp)o; return resp.equals(r.resp); } public int hashCode() { return resp.hashCode(); } } bouncycastle-1.49.orig/src/org/bouncycastle/cert/ocsp/BasicOCSPRespBuilder.java0000644000175000017500000002005312103437527027121 0ustar ebourgebourgpackage org.bouncycastle.cert.ocsp; import java.io.OutputStream; import java.util.ArrayList; import java.util.Date; import java.util.Iterator; import java.util.List; import org.bouncycastle.asn1.ASN1EncodableVector; import org.bouncycastle.asn1.ASN1Encoding; import org.bouncycastle.asn1.ASN1GeneralizedTime; import org.bouncycastle.asn1.DERBitString; import org.bouncycastle.asn1.DERGeneralizedTime; import org.bouncycastle.asn1.DERNull; import org.bouncycastle.asn1.DERSequence; import org.bouncycastle.asn1.ocsp.BasicOCSPResponse; import org.bouncycastle.asn1.ocsp.CertStatus; import org.bouncycastle.asn1.ocsp.ResponseData; import org.bouncycastle.asn1.ocsp.RevokedInfo; import org.bouncycastle.asn1.ocsp.SingleResponse; import org.bouncycastle.asn1.x509.AlgorithmIdentifier; import org.bouncycastle.asn1.x509.CRLReason; import org.bouncycastle.asn1.x509.Extensions; import org.bouncycastle.asn1.x509.SubjectPublicKeyInfo; import org.bouncycastle.cert.X509CertificateHolder; import org.bouncycastle.operator.ContentSigner; import org.bouncycastle.operator.DigestCalculator; /** * Generator for basic OCSP response objects. */ public class BasicOCSPRespBuilder { private List list = new ArrayList(); private Extensions responseExtensions = null; private RespID responderID; private class ResponseObject { CertificateID certId; CertStatus certStatus; DERGeneralizedTime thisUpdate; DERGeneralizedTime nextUpdate; Extensions extensions; public ResponseObject( CertificateID certId, CertificateStatus certStatus, Date thisUpdate, Date nextUpdate, Extensions extensions) { this.certId = certId; if (certStatus == null) { this.certStatus = new CertStatus(); } else if (certStatus instanceof UnknownStatus) { this.certStatus = new CertStatus(2, DERNull.INSTANCE); } else { RevokedStatus rs = (RevokedStatus)certStatus; if (rs.hasRevocationReason()) { this.certStatus = new CertStatus( new RevokedInfo(new ASN1GeneralizedTime(rs.getRevocationTime()), CRLReason.lookup(rs.getRevocationReason()))); } else { this.certStatus = new CertStatus( new RevokedInfo(new ASN1GeneralizedTime(rs.getRevocationTime()), null)); } } this.thisUpdate = new DERGeneralizedTime(thisUpdate); if (nextUpdate != null) { this.nextUpdate = new DERGeneralizedTime(nextUpdate); } else { this.nextUpdate = null; } this.extensions = extensions; } public SingleResponse toResponse() throws Exception { return new SingleResponse(certId.toASN1Object(), certStatus, thisUpdate, nextUpdate, extensions); } } /** * basic constructor */ public BasicOCSPRespBuilder( RespID responderID) { this.responderID = responderID; } /** * construct with the responderID to be the SHA-1 keyHash of the passed in public key. * * @param key the key info of the responder public key. * @param digCalc a SHA-1 digest calculator */ public BasicOCSPRespBuilder( SubjectPublicKeyInfo key, DigestCalculator digCalc) throws OCSPException { this.responderID = new RespID(key, digCalc); } /** * Add a response for a particular Certificate ID. * * @param certID certificate ID details * @param certStatus status of the certificate - null if okay */ public BasicOCSPRespBuilder addResponse( CertificateID certID, CertificateStatus certStatus) { list.add(new ResponseObject(certID, certStatus, new Date(), null, null)); return this; } /** * Add a response for a particular Certificate ID. * * @param certID certificate ID details * @param certStatus status of the certificate - null if okay * @param singleExtensions optional extensions */ public BasicOCSPRespBuilder addResponse( CertificateID certID, CertificateStatus certStatus, Extensions singleExtensions) { list.add(new ResponseObject(certID, certStatus, new Date(), null, singleExtensions)); return this; } /** * Add a response for a particular Certificate ID. * * @param certID certificate ID details * @param nextUpdate date when next update should be requested * @param certStatus status of the certificate - null if okay * @param singleExtensions optional extensions */ public BasicOCSPRespBuilder addResponse( CertificateID certID, CertificateStatus certStatus, Date nextUpdate, Extensions singleExtensions) { list.add(new ResponseObject(certID, certStatus, new Date(), nextUpdate, singleExtensions)); return this; } /** * Add a response for a particular Certificate ID. * * @param certID certificate ID details * @param thisUpdate date this response was valid on * @param nextUpdate date when next update should be requested * @param certStatus status of the certificate - null if okay * @param singleExtensions optional extensions */ public BasicOCSPRespBuilder addResponse( CertificateID certID, CertificateStatus certStatus, Date thisUpdate, Date nextUpdate, Extensions singleExtensions) { list.add(new ResponseObject(certID, certStatus, thisUpdate, nextUpdate, singleExtensions)); return this; } /** * Set the extensions for the response. * * @param responseExtensions the extension object to carry. */ public BasicOCSPRespBuilder setResponseExtensions( Extensions responseExtensions) { this.responseExtensions = responseExtensions; return this; } public BasicOCSPResp build( ContentSigner signer, X509CertificateHolder[] chain, Date producedAt) throws OCSPException { Iterator it = list.iterator(); ASN1EncodableVector responses = new ASN1EncodableVector(); while (it.hasNext()) { try { responses.add(((ResponseObject)it.next()).toResponse()); } catch (Exception e) { throw new OCSPException("exception creating Request", e); } } ResponseData tbsResp = new ResponseData(responderID.toASN1Object(), new ASN1GeneralizedTime(producedAt), new DERSequence(responses), responseExtensions); DERBitString bitSig; try { OutputStream sigOut = signer.getOutputStream(); sigOut.write(tbsResp.getEncoded(ASN1Encoding.DER)); sigOut.close(); bitSig = new DERBitString(signer.getSignature()); } catch (Exception e) { throw new OCSPException("exception processing TBSRequest: " + e.getMessage(), e); } AlgorithmIdentifier sigAlgId = signer.getAlgorithmIdentifier(); DERSequence chainSeq = null; if (chain != null && chain.length > 0) { ASN1EncodableVector v = new ASN1EncodableVector(); for (int i = 0; i != chain.length; i++) { v.add(chain[i].toASN1Structure()); } chainSeq = new DERSequence(v); } return new BasicOCSPResp(new BasicOCSPResponse(tbsResp, sigAlgId, bitSig, chainSeq)); } } bouncycastle-1.49.orig/src/org/bouncycastle/cert/ocsp/jcajce/0000755000175000017500000000000012152033551023617 5ustar ebourgebourgbouncycastle-1.49.orig/src/org/bouncycastle/cert/ocsp/jcajce/JcaCertificateID.java0000644000175000017500000000130511475102630027540 0ustar ebourgebourgpackage org.bouncycastle.cert.ocsp.jcajce; import java.math.BigInteger; import java.security.cert.CertificateEncodingException; import java.security.cert.X509Certificate; import org.bouncycastle.cert.jcajce.JcaX509CertificateHolder; import org.bouncycastle.cert.ocsp.CertificateID; import org.bouncycastle.cert.ocsp.OCSPException; import org.bouncycastle.operator.DigestCalculator; public class JcaCertificateID extends CertificateID { public JcaCertificateID(DigestCalculator digestCalculator, X509Certificate issuerCert, BigInteger number) throws OCSPException, CertificateEncodingException { super(digestCalculator, new JcaX509CertificateHolder(issuerCert), number); } } bouncycastle-1.49.orig/src/org/bouncycastle/cert/ocsp/jcajce/JcaRespID.java0000644000175000017500000000130511475102677026242 0ustar ebourgebourgpackage org.bouncycastle.cert.ocsp.jcajce; import java.security.PublicKey; import javax.security.auth.x500.X500Principal; import org.bouncycastle.asn1.x500.X500Name; import org.bouncycastle.asn1.x509.SubjectPublicKeyInfo; import org.bouncycastle.cert.ocsp.OCSPException; import org.bouncycastle.cert.ocsp.RespID; import org.bouncycastle.operator.DigestCalculator; public class JcaRespID extends RespID { public JcaRespID(X500Principal name) { super(X500Name.getInstance(name.getEncoded())); } public JcaRespID(PublicKey pubKey, DigestCalculator digCalc) throws OCSPException { super(SubjectPublicKeyInfo.getInstance(pubKey.getEncoded()), digCalc); } } bouncycastle-1.49.orig/src/org/bouncycastle/cert/ocsp/jcajce/JcaBasicOCSPRespBuilder.java0000644000175000017500000000105511475102513030752 0ustar ebourgebourgpackage org.bouncycastle.cert.ocsp.jcajce; import java.security.PublicKey; import org.bouncycastle.asn1.x509.SubjectPublicKeyInfo; import org.bouncycastle.cert.ocsp.BasicOCSPRespBuilder; import org.bouncycastle.cert.ocsp.OCSPException; import org.bouncycastle.operator.DigestCalculator; public class JcaBasicOCSPRespBuilder extends BasicOCSPRespBuilder { public JcaBasicOCSPRespBuilder(PublicKey key, DigestCalculator digCalc) throws OCSPException { super(SubjectPublicKeyInfo.getInstance(key.getEncoded()), digCalc); } } bouncycastle-1.49.orig/src/org/bouncycastle/cert/ocsp/jcajce/package.html0000644000175000017500000000033411501604063026077 0ustar ebourgebourg JCA extensions to the OCSP online certificate status package. bouncycastle-1.49.orig/src/org/bouncycastle/cert/ocsp/OCSPUtils.java0000644000175000017500000000335211736733672025055 0ustar ebourgebourgpackage org.bouncycastle.cert.ocsp; import java.util.ArrayList; import java.util.Arrays; import java.util.Collections; import java.util.Date; import java.util.HashSet; import java.util.List; import java.util.Set; import org.bouncycastle.asn1.ASN1GeneralizedTime; import org.bouncycastle.asn1.x509.Extensions; import org.bouncycastle.cert.X509CertificateHolder; class OCSPUtils { static final X509CertificateHolder[] EMPTY_CERTS = new X509CertificateHolder[0]; static Set EMPTY_SET = Collections.unmodifiableSet(new HashSet()); static List EMPTY_LIST = Collections.unmodifiableList(new ArrayList()); static Date extractDate(ASN1GeneralizedTime time) { try { return time.getDate(); } catch (Exception e) { throw new IllegalStateException("exception processing GeneralizedTime: " + e.getMessage()); } } static Set getCriticalExtensionOIDs(Extensions extensions) { if (extensions == null) { return EMPTY_SET; } return Collections.unmodifiableSet(new HashSet(Arrays.asList(extensions.getCriticalExtensionOIDs()))); } static Set getNonCriticalExtensionOIDs(Extensions extensions) { if (extensions == null) { return EMPTY_SET; } // TODO: should probably produce a set that imposes correct ordering return Collections.unmodifiableSet(new HashSet(Arrays.asList(extensions.getNonCriticalExtensionOIDs()))); } static List getExtensionOIDs(Extensions extensions) { if (extensions == null) { return EMPTY_LIST; } return Collections.unmodifiableList(Arrays.asList(extensions.getExtensionOIDs())); } } bouncycastle-1.49.orig/src/org/bouncycastle/cert/ocsp/OCSPResp.java0000644000175000017500000000701412151251423024642 0ustar ebourgebourgpackage org.bouncycastle.cert.ocsp; import java.io.ByteArrayInputStream; import java.io.IOException; import java.io.InputStream; import org.bouncycastle.asn1.ASN1Exception; import org.bouncycastle.asn1.ASN1InputStream; import org.bouncycastle.asn1.ASN1Primitive; import org.bouncycastle.asn1.ocsp.BasicOCSPResponse; import org.bouncycastle.asn1.ocsp.OCSPObjectIdentifiers; import org.bouncycastle.asn1.ocsp.OCSPResponse; import org.bouncycastle.asn1.ocsp.ResponseBytes; import org.bouncycastle.cert.CertIOException; public class OCSPResp { public static final int SUCCESSFUL = 0; // Response has valid confirmations public static final int MALFORMED_REQUEST = 1; // Illegal confirmation request public static final int INTERNAL_ERROR = 2; // Internal error in issuer public static final int TRY_LATER = 3; // Try again later // (4) is not used public static final int SIG_REQUIRED = 5; // Must sign the request public static final int UNAUTHORIZED = 6; // Request unauthorized private OCSPResponse resp; public OCSPResp( OCSPResponse resp) { this.resp = resp; } public OCSPResp( byte[] resp) throws IOException { this(new ByteArrayInputStream(resp)); } public OCSPResp( InputStream resp) throws IOException { this(new ASN1InputStream(resp)); } private OCSPResp( ASN1InputStream aIn) throws IOException { try { this.resp = OCSPResponse.getInstance(aIn.readObject()); } catch (IllegalArgumentException e) { throw new CertIOException("malformed response: " + e.getMessage(), e); } catch (ClassCastException e) { throw new CertIOException("malformed response: " + e.getMessage(), e); } catch (ASN1Exception e) { throw new CertIOException("malformed response: " + e.getMessage(), e); } if (resp == null) { throw new CertIOException("malformed response: no response data found"); } } public int getStatus() { return this.resp.getResponseStatus().getValue().intValue(); } public Object getResponseObject() throws OCSPException { ResponseBytes rb = this.resp.getResponseBytes(); if (rb == null) { return null; } if (rb.getResponseType().equals(OCSPObjectIdentifiers.id_pkix_ocsp_basic)) { try { ASN1Primitive obj = ASN1Primitive.fromByteArray(rb.getResponse().getOctets()); return new BasicOCSPResp(BasicOCSPResponse.getInstance(obj)); } catch (Exception e) { throw new OCSPException("problem decoding object: " + e, e); } } return rb.getResponse(); } /** * return the ASN.1 encoded representation of this object. */ public byte[] getEncoded() throws IOException { return resp.getEncoded(); } public boolean equals(Object o) { if (o == this) { return true; } if (!(o instanceof OCSPResp)) { return false; } OCSPResp r = (OCSPResp)o; return resp.equals(r.resp); } public int hashCode() { return resp.hashCode(); } public OCSPResponse toASN1Structure() { return resp; } } bouncycastle-1.49.orig/src/org/bouncycastle/cert/ocsp/RevokedStatus.java0000644000175000017500000000257511737275254026077 0ustar ebourgebourgpackage org.bouncycastle.cert.ocsp; import java.util.Date; import org.bouncycastle.asn1.ASN1GeneralizedTime; import org.bouncycastle.asn1.ocsp.RevokedInfo; import org.bouncycastle.asn1.x509.CRLReason; /** * wrapper for the RevokedInfo object */ public class RevokedStatus implements CertificateStatus { RevokedInfo info; public RevokedStatus( RevokedInfo info) { this.info = info; } public RevokedStatus( Date revocationDate, int reason) { this.info = new RevokedInfo(new ASN1GeneralizedTime(revocationDate), CRLReason.lookup(reason)); } public Date getRevocationTime() { return OCSPUtils.extractDate(info.getRevocationTime()); } public boolean hasRevocationReason() { return (info.getRevocationReason() != null); } /** * return the revocation reason. Note: this field is optional, test for it * with hasRevocationReason() first. * @return the revocation reason value. * @exception IllegalStateException if a reason is asked for and none is avaliable */ public int getRevocationReason() { if (info.getRevocationReason() == null) { throw new IllegalStateException("attempt to get a reason where none is available"); } return info.getRevocationReason().getValue().intValue(); } } bouncycastle-1.49.orig/src/org/bouncycastle/cert/ocsp/OCSPException.java0000644000175000017500000000062411474635710025703 0ustar ebourgebourgpackage org.bouncycastle.cert.ocsp; public class OCSPException extends Exception { private Throwable cause; public OCSPException( String name) { super(name); } public OCSPException( String name, Throwable cause) { super(name); this.cause = cause; } public Throwable getCause() { return cause; } } bouncycastle-1.49.orig/src/org/bouncycastle/cert/ocsp/package.html0000644000175000017500000000040211501601756024662 0ustar ebourgebourg Basic support package for handling and creating OCSP (RFC 2560) online certificate status requests. bouncycastle-1.49.orig/src/org/bouncycastle/cert/X509AttributeCertificateHolder.java0000644000175000017500000002521112070232011030121 0ustar ebourgebourgpackage org.bouncycastle.cert; import java.io.IOException; import java.io.OutputStream; import java.math.BigInteger; import java.util.ArrayList; import java.util.Date; import java.util.List; import java.util.Set; import org.bouncycastle.asn1.ASN1ObjectIdentifier; import org.bouncycastle.asn1.ASN1Primitive; import org.bouncycastle.asn1.ASN1Sequence; import org.bouncycastle.asn1.DEROutputStream; import org.bouncycastle.asn1.x509.AlgorithmIdentifier; import org.bouncycastle.asn1.x509.AttCertValidityPeriod; import org.bouncycastle.asn1.x509.Attribute; import org.bouncycastle.asn1.x509.AttributeCertificate; import org.bouncycastle.asn1.x509.AttributeCertificateInfo; import org.bouncycastle.asn1.x509.Extension; import org.bouncycastle.asn1.x509.Extensions; import org.bouncycastle.operator.ContentVerifier; import org.bouncycastle.operator.ContentVerifierProvider; /** * Holding class for an X.509 AttributeCertificate structure. */ public class X509AttributeCertificateHolder { private static Attribute[] EMPTY_ARRAY = new Attribute[0]; private AttributeCertificate attrCert; private Extensions extensions; private static AttributeCertificate parseBytes(byte[] certEncoding) throws IOException { try { return AttributeCertificate.getInstance(ASN1Primitive.fromByteArray(certEncoding)); } catch (ClassCastException e) { throw new CertIOException("malformed data: " + e.getMessage(), e); } catch (IllegalArgumentException e) { throw new CertIOException("malformed data: " + e.getMessage(), e); } } /** * Create a X509AttributeCertificateHolder from the passed in bytes. * * @param certEncoding BER/DER encoding of the certificate. * @throws IOException in the event of corrupted data, or an incorrect structure. */ public X509AttributeCertificateHolder(byte[] certEncoding) throws IOException { this(parseBytes(certEncoding)); } /** * Create a X509AttributeCertificateHolder from the passed in ASN.1 structure. * * @param attrCert an ASN.1 AttributeCertificate structure. */ public X509AttributeCertificateHolder(AttributeCertificate attrCert) { this.attrCert = attrCert; this.extensions = attrCert.getAcinfo().getExtensions(); } /** * Return the ASN.1 encoding of this holder's attribute certificate. * * @return a DER encoded byte array. * @throws IOException if an encoding cannot be generated. */ public byte[] getEncoded() throws IOException { return attrCert.getEncoded(); } public int getVersion() { return attrCert.getAcinfo().getVersion().getValue().intValue() + 1; } /** * Return the serial number of this attribute certificate. * * @return the serial number. */ public BigInteger getSerialNumber() { return attrCert.getAcinfo().getSerialNumber().getValue(); } /** * Return the holder details for this attribute certificate. * * @return this attribute certificate's holder structure. */ public AttributeCertificateHolder getHolder() { return new AttributeCertificateHolder((ASN1Sequence)attrCert.getAcinfo().getHolder().toASN1Primitive()); } /** * Return the issuer details for this attribute certificate. * * @return this attribute certificate's issuer structure, */ public AttributeCertificateIssuer getIssuer() { return new AttributeCertificateIssuer(attrCert.getAcinfo().getIssuer()); } /** * Return the date before which this attribute certificate is not valid. * * @return the start date for the attribute certificate's validity period. */ public Date getNotBefore() { return CertUtils.recoverDate(attrCert.getAcinfo().getAttrCertValidityPeriod().getNotBeforeTime()); } /** * Return the date after which this attribute certificate is not valid. * * @return the final date for the attribute certificate's validity period. */ public Date getNotAfter() { return CertUtils.recoverDate(attrCert.getAcinfo().getAttrCertValidityPeriod().getNotAfterTime()); } /** * Return the attributes, if any associated with this request. * * @return an array of Attribute, zero length if none present. */ public Attribute[] getAttributes() { ASN1Sequence seq = attrCert.getAcinfo().getAttributes(); Attribute[] attrs = new Attribute[seq.size()]; for (int i = 0; i != seq.size(); i++) { attrs[i] = Attribute.getInstance(seq.getObjectAt(i)); } return attrs; } /** * Return an array of attributes matching the passed in type OID. * * @param type the type of the attribute being looked for. * @return an array of Attribute of the requested type, zero length if none present. */ public Attribute[] getAttributes(ASN1ObjectIdentifier type) { ASN1Sequence seq = attrCert.getAcinfo().getAttributes(); List list = new ArrayList(); for (int i = 0; i != seq.size(); i++) { Attribute attr = Attribute.getInstance(seq.getObjectAt(i)); if (attr.getAttrType().equals(type)) { list.add(attr); } } if (list.size() == 0) { return EMPTY_ARRAY; } return (Attribute[])list.toArray(new Attribute[list.size()]); } /** * Return whether or not the holder's attribute certificate contains extensions. * * @return true if extension are present, false otherwise. */ public boolean hasExtensions() { return extensions != null; } /** * Look up the extension associated with the passed in OID. * * @param oid the OID of the extension of interest. * * @return the extension if present, null otherwise. */ public Extension getExtension(ASN1ObjectIdentifier oid) { if (extensions != null) { return extensions.getExtension(oid); } return null; } /** * Return the extensions block associated with this certificate if there is one. * * @return the extensions block, null otherwise. */ public Extensions getExtensions() { return extensions; } /** * Returns a list of ASN1ObjectIdentifier objects representing the OIDs of the * extensions contained in this holder's attribute certificate. * * @return a list of extension OIDs. */ public List getExtensionOIDs() { return CertUtils.getExtensionOIDs(extensions); } /** * Returns a set of ASN1ObjectIdentifier objects representing the OIDs of the * critical extensions contained in this holder's attribute certificate. * * @return a set of critical extension OIDs. */ public Set getCriticalExtensionOIDs() { return CertUtils.getCriticalExtensionOIDs(extensions); } /** * Returns a set of ASN1ObjectIdentifier objects representing the OIDs of the * non-critical extensions contained in this holder's attribute certificate. * * @return a set of non-critical extension OIDs. */ public Set getNonCriticalExtensionOIDs() { return CertUtils.getNonCriticalExtensionOIDs(extensions); } public boolean[] getIssuerUniqueID() { return CertUtils.bitStringToBoolean(attrCert.getAcinfo().getIssuerUniqueID()); } /** * Return the details of the signature algorithm used to create this attribute certificate. * * @return the AlgorithmIdentifier describing the signature algorithm used to create this attribute certificate. */ public AlgorithmIdentifier getSignatureAlgorithm() { return attrCert.getSignatureAlgorithm(); } /** * Return the bytes making up the signature associated with this attribute certificate. * * @return the attribute certificate signature bytes. */ public byte[] getSignature() { return attrCert.getSignatureValue().getBytes(); } /** * Return the underlying ASN.1 structure for the attribute certificate in this holder. * * @return a AttributeCertificate object. */ public AttributeCertificate toASN1Structure() { return attrCert; } /** * Return whether or not this attribute certificate is valid on a particular date. * * @param date the date of interest. * @return true if the attribute certificate is valid, false otherwise. */ public boolean isValidOn(Date date) { AttCertValidityPeriod certValidityPeriod = attrCert.getAcinfo().getAttrCertValidityPeriod(); return !date.before(CertUtils.recoverDate(certValidityPeriod.getNotBeforeTime())) && !date.after(CertUtils.recoverDate(certValidityPeriod.getNotAfterTime())); } /** * Validate the signature on the attribute certificate in this holder. * * @param verifierProvider a ContentVerifierProvider that can generate a verifier for the signature. * @return true if the signature is valid, false otherwise. * @throws CertException if the signature cannot be processed or is inappropriate. */ public boolean isSignatureValid(ContentVerifierProvider verifierProvider) throws CertException { AttributeCertificateInfo acinfo = attrCert.getAcinfo(); if (!CertUtils.isAlgIdEqual(acinfo.getSignature(), attrCert.getSignatureAlgorithm())) { throw new CertException("signature invalid - algorithm identifier mismatch"); } ContentVerifier verifier; try { verifier = verifierProvider.get((acinfo.getSignature())); OutputStream sOut = verifier.getOutputStream(); DEROutputStream dOut = new DEROutputStream(sOut); dOut.writeObject(acinfo); sOut.close(); } catch (Exception e) { throw new CertException("unable to process signature: " + e.getMessage(), e); } return verifier.verify(attrCert.getSignatureValue().getBytes()); } public boolean equals( Object o) { if (o == this) { return true; } if (!(o instanceof X509AttributeCertificateHolder)) { return false; } X509AttributeCertificateHolder other = (X509AttributeCertificateHolder)o; return this.attrCert.equals(other.attrCert); } public int hashCode() { return this.attrCert.hashCode(); } } bouncycastle-1.49.orig/src/org/bouncycastle/cert/X509CRLEntryHolder.java0000644000175000017500000001001512070232011025451 0ustar ebourgebourgpackage org.bouncycastle.cert; import java.math.BigInteger; import java.util.Date; import java.util.List; import java.util.Set; import org.bouncycastle.asn1.ASN1ObjectIdentifier; import org.bouncycastle.asn1.x509.Extension; import org.bouncycastle.asn1.x509.Extensions; import org.bouncycastle.asn1.x509.GeneralNames; import org.bouncycastle.asn1.x509.TBSCertList; /** * Holding class for an X.509 CRL Entry structure. */ public class X509CRLEntryHolder { private TBSCertList.CRLEntry entry; private GeneralNames ca; X509CRLEntryHolder(TBSCertList.CRLEntry entry, boolean isIndirect, GeneralNames previousCA) { this.entry = entry; this.ca = previousCA; if (isIndirect && entry.hasExtensions()) { Extension currentCaName = entry.getExtensions().getExtension(Extension.certificateIssuer); if (currentCaName != null) { ca = GeneralNames.getInstance(currentCaName.getParsedValue()); } } } /** * Return the serial number of the certificate associated with this CRLEntry. * * @return the revoked certificate's serial number. */ public BigInteger getSerialNumber() { return entry.getUserCertificate().getValue(); } /** * Return the date on which the certificate associated with this CRLEntry was revoked. * * @return the revocation date for the revoked certificate. */ public Date getRevocationDate() { return entry.getRevocationDate().getDate(); } /** * Return whether or not the holder's CRL entry contains extensions. * * @return true if extension are present, false otherwise. */ public boolean hasExtensions() { return entry.hasExtensions(); } /** * Return the available names for the certificate issuer for the certificate referred to by this CRL entry. *

    * Note: this will be the issuer of the CRL unless it has been specified that the CRL is indirect * in the IssuingDistributionPoint extension and either a previous entry, or the current one, * has specified a different CA via the certificateIssuer extension. *

    * * @return the revoked certificate's issuer. */ public GeneralNames getCertificateIssuer() { return this.ca; } /** * Look up the extension associated with the passed in OID. * * @param oid the OID of the extension of interest. * * @return the extension if present, null otherwise. */ public Extension getExtension(ASN1ObjectIdentifier oid) { Extensions extensions = entry.getExtensions(); if (extensions != null) { return extensions.getExtension(oid); } return null; } /** * Return the extensions block associated with this CRL entry if there is one. * * @return the extensions block, null otherwise. */ public Extensions getExtensions() { return entry.getExtensions(); } /** * Returns a list of ASN1ObjectIdentifier objects representing the OIDs of the * extensions contained in this holder's CRL entry. * * @return a list of extension OIDs. */ public List getExtensionOIDs() { return CertUtils.getExtensionOIDs(entry.getExtensions()); } /** * Returns a set of ASN1ObjectIdentifier objects representing the OIDs of the * critical extensions contained in this holder's CRL entry. * * @return a set of critical extension OIDs. */ public Set getCriticalExtensionOIDs() { return CertUtils.getCriticalExtensionOIDs(entry.getExtensions()); } /** * Returns a set of ASN1ObjectIdentifier objects representing the OIDs of the * non-critical extensions contained in this holder's CRL entry. * * @return a set of non-critical extension OIDs. */ public Set getNonCriticalExtensionOIDs() { return CertUtils.getNonCriticalExtensionOIDs(entry.getExtensions()); } } bouncycastle-1.49.orig/src/org/bouncycastle/cert/bc/0000755000175000017500000000000012152033551022020 5ustar ebourgebourgbouncycastle-1.49.orig/src/org/bouncycastle/cert/bc/BcX509v1CertificateBuilder.java0000644000175000017500000000255111737275254027541 0ustar ebourgebourgpackage org.bouncycastle.cert.bc; import java.io.IOException; import java.math.BigInteger; import java.util.Date; import org.bouncycastle.asn1.x500.X500Name; import org.bouncycastle.cert.X509v1CertificateBuilder; import org.bouncycastle.crypto.params.AsymmetricKeyParameter; import org.bouncycastle.crypto.util.SubjectPublicKeyInfoFactory; /** * JCA helper class to allow BC lightweight objects to be used in the construction of a Version 1 certificate. */ public class BcX509v1CertificateBuilder extends X509v1CertificateBuilder { /** * Initialise the builder using an AsymmetricKeyParameter. * * @param issuer X500Name representing the issuer of this certificate. * @param serial the serial number for the certificate. * @param notBefore date before which the certificate is not valid. * @param notAfter date after which the certificate is not valid. * @param subject X500Name representing the subject of this certificate. * @param publicKey the public key to be associated with the certificate. */ public BcX509v1CertificateBuilder(X500Name issuer, BigInteger serial, Date notBefore, Date notAfter, X500Name subject, AsymmetricKeyParameter publicKey) throws IOException { super(issuer, serial, notBefore, notAfter, subject, SubjectPublicKeyInfoFactory.createSubjectPublicKeyInfo(publicKey)); } } bouncycastle-1.49.orig/src/org/bouncycastle/cert/bc/BcX509v3CertificateBuilder.java0000644000175000017500000000461511737275254027546 0ustar ebourgebourgpackage org.bouncycastle.cert.bc; import java.io.IOException; import java.math.BigInteger; import java.util.Date; import org.bouncycastle.asn1.x500.X500Name; import org.bouncycastle.cert.X509CertificateHolder; import org.bouncycastle.cert.X509v3CertificateBuilder; import org.bouncycastle.crypto.params.AsymmetricKeyParameter; import org.bouncycastle.crypto.util.SubjectPublicKeyInfoFactory; /** * JCA helper class to allow BC lightweight objects to be used in the construction of a Version 3 certificate. */ public class BcX509v3CertificateBuilder extends X509v3CertificateBuilder { /** * Initialise the builder using a PublicKey. * * @param issuer X500Name representing the issuer of this certificate. * @param serial the serial number for the certificate. * @param notBefore date before which the certificate is not valid. * @param notAfter date after which the certificate is not valid. * @param subject X500Name representing the subject of this certificate. * @param publicKey the public key to be associated with the certificate. */ public BcX509v3CertificateBuilder(X500Name issuer, BigInteger serial, Date notBefore, Date notAfter, X500Name subject, AsymmetricKeyParameter publicKey) throws IOException { super(issuer, serial, notBefore, notAfter, subject, SubjectPublicKeyInfoFactory.createSubjectPublicKeyInfo(publicKey)); } /** * Initialise the builder using the subject from the passed in issuerCert as the issuer, as well as * passing through and converting the other objects provided. * * @param issuerCert holder for certificate who's subject is the issuer of the certificate we are building. * @param serial the serial number for the certificate. * @param notBefore date before which the certificate is not valid. * @param notAfter date after which the certificate is not valid. * @param subject principal representing the subject of this certificate. * @param publicKey the public key to be associated with the certificate. */ public BcX509v3CertificateBuilder(X509CertificateHolder issuerCert, BigInteger serial, Date notBefore, Date notAfter, X500Name subject, AsymmetricKeyParameter publicKey) throws IOException { super(issuerCert.getSubject(), serial, notBefore, notAfter, subject, SubjectPublicKeyInfoFactory.createSubjectPublicKeyInfo(publicKey)); } } bouncycastle-1.49.orig/src/org/bouncycastle/cert/bc/BcX509ExtensionUtils.java0000644000175000017500000000530511736730513026527 0ustar ebourgebourgpackage org.bouncycastle.cert.bc; import java.io.ByteArrayOutputStream; import java.io.IOException; import java.io.OutputStream; import org.bouncycastle.asn1.oiw.OIWObjectIdentifiers; import org.bouncycastle.asn1.x509.AlgorithmIdentifier; import org.bouncycastle.asn1.x509.AuthorityKeyIdentifier; import org.bouncycastle.asn1.x509.SubjectKeyIdentifier; import org.bouncycastle.cert.X509ExtensionUtils; import org.bouncycastle.crypto.Digest; import org.bouncycastle.crypto.digests.SHA1Digest; import org.bouncycastle.crypto.params.AsymmetricKeyParameter; import org.bouncycastle.crypto.util.SubjectPublicKeyInfoFactory; import org.bouncycastle.operator.DigestCalculator; public class BcX509ExtensionUtils extends X509ExtensionUtils { /** * Create a utility class pre-configured with a SHA-1 digest calculator based on the * BC implementation. */ public BcX509ExtensionUtils() { super(new SHA1DigestCalculator()); } public BcX509ExtensionUtils(DigestCalculator calculator) { super(calculator); } public AuthorityKeyIdentifier createAuthorityKeyIdentifier( AsymmetricKeyParameter publicKey) throws IOException { return super.createAuthorityKeyIdentifier(SubjectPublicKeyInfoFactory.createSubjectPublicKeyInfo(publicKey)); } /** * Return a RFC 3280 type 1 key identifier. As in: *
         * (1) The keyIdentifier is composed of the 160-bit SHA-1 hash of the
         * value of the BIT STRING subjectPublicKey (excluding the tag,
         * length, and number of unused bits).
         * 
    * @param publicKey the key object containing the key identifier is to be based on. * @return the key identifier. */ public SubjectKeyIdentifier createSubjectKeyIdentifier( AsymmetricKeyParameter publicKey) throws IOException { return super.createSubjectKeyIdentifier(SubjectPublicKeyInfoFactory.createSubjectPublicKeyInfo(publicKey)); } private static class SHA1DigestCalculator implements DigestCalculator { private ByteArrayOutputStream bOut = new ByteArrayOutputStream(); public AlgorithmIdentifier getAlgorithmIdentifier() { return new AlgorithmIdentifier(OIWObjectIdentifiers.idSHA1); } public OutputStream getOutputStream() { return bOut; } public byte[] getDigest() { byte[] bytes = bOut.toByteArray(); bOut.reset(); Digest sha1 = new SHA1Digest(); sha1.update(bytes, 0, bytes.length); byte[] digest = new byte[sha1.getDigestSize()]; sha1.doFinal(digest, 0); return digest; } } } bouncycastle-1.49.orig/src/org/bouncycastle/cert/CertUtils.java0000644000175000017500000001622011737275254024236 0ustar ebourgebourgpackage org.bouncycastle.cert; import java.io.IOException; import java.io.OutputStream; import java.text.ParseException; import java.util.ArrayList; import java.util.Arrays; import java.util.Collections; import java.util.Date; import java.util.HashSet; import java.util.List; import java.util.Set; import org.bouncycastle.asn1.ASN1Encodable; import org.bouncycastle.asn1.ASN1EncodableVector; import org.bouncycastle.asn1.ASN1GeneralizedTime; import org.bouncycastle.asn1.ASN1ObjectIdentifier; import org.bouncycastle.asn1.DERBitString; import org.bouncycastle.asn1.DERNull; import org.bouncycastle.asn1.DEROutputStream; import org.bouncycastle.asn1.DERSequence; import org.bouncycastle.asn1.x509.AlgorithmIdentifier; import org.bouncycastle.asn1.x509.AttributeCertificate; import org.bouncycastle.asn1.x509.AttributeCertificateInfo; import org.bouncycastle.asn1.x509.Certificate; import org.bouncycastle.asn1.x509.CertificateList; import org.bouncycastle.asn1.x509.Extensions; import org.bouncycastle.asn1.x509.ExtensionsGenerator; import org.bouncycastle.asn1.x509.TBSCertList; import org.bouncycastle.asn1.x509.TBSCertificate; import org.bouncycastle.operator.ContentSigner; class CertUtils { private static Set EMPTY_SET = Collections.unmodifiableSet(new HashSet()); private static List EMPTY_LIST = Collections.unmodifiableList(new ArrayList()); static X509CertificateHolder generateFullCert(ContentSigner signer, TBSCertificate tbsCert) { try { return new X509CertificateHolder(generateStructure(tbsCert, signer.getAlgorithmIdentifier(), generateSig(signer, tbsCert))); } catch (IOException e) { throw new IllegalStateException("cannot produce certificate signature"); } } static X509AttributeCertificateHolder generateFullAttrCert(ContentSigner signer, AttributeCertificateInfo attrInfo) { try { return new X509AttributeCertificateHolder(generateAttrStructure(attrInfo, signer.getAlgorithmIdentifier(), generateSig(signer, attrInfo))); } catch (IOException e) { throw new IllegalStateException("cannot produce attribute certificate signature"); } } static X509CRLHolder generateFullCRL(ContentSigner signer, TBSCertList tbsCertList) { try { return new X509CRLHolder(generateCRLStructure(tbsCertList, signer.getAlgorithmIdentifier(), generateSig(signer, tbsCertList))); } catch (IOException e) { throw new IllegalStateException("cannot produce certificate signature"); } } private static byte[] generateSig(ContentSigner signer, ASN1Encodable tbsObj) throws IOException { OutputStream sOut = signer.getOutputStream(); DEROutputStream dOut = new DEROutputStream(sOut); dOut.writeObject(tbsObj); sOut.close(); return signer.getSignature(); } private static Certificate generateStructure(TBSCertificate tbsCert, AlgorithmIdentifier sigAlgId, byte[] signature) { ASN1EncodableVector v = new ASN1EncodableVector(); v.add(tbsCert); v.add(sigAlgId); v.add(new DERBitString(signature)); return Certificate.getInstance(new DERSequence(v)); } private static AttributeCertificate generateAttrStructure(AttributeCertificateInfo attrInfo, AlgorithmIdentifier sigAlgId, byte[] signature) { ASN1EncodableVector v = new ASN1EncodableVector(); v.add(attrInfo); v.add(sigAlgId); v.add(new DERBitString(signature)); return AttributeCertificate.getInstance(new DERSequence(v)); } private static CertificateList generateCRLStructure(TBSCertList tbsCertList, AlgorithmIdentifier sigAlgId, byte[] signature) { ASN1EncodableVector v = new ASN1EncodableVector(); v.add(tbsCertList); v.add(sigAlgId); v.add(new DERBitString(signature)); return CertificateList.getInstance(new DERSequence(v)); } static Set getCriticalExtensionOIDs(Extensions extensions) { if (extensions == null) { return EMPTY_SET; } return Collections.unmodifiableSet(new HashSet(Arrays.asList(extensions.getCriticalExtensionOIDs()))); } static Set getNonCriticalExtensionOIDs(Extensions extensions) { if (extensions == null) { return EMPTY_SET; } // TODO: should probably produce a set that imposes correct ordering return Collections.unmodifiableSet(new HashSet(Arrays.asList(extensions.getNonCriticalExtensionOIDs()))); } static List getExtensionOIDs(Extensions extensions) { if (extensions == null) { return EMPTY_LIST; } return Collections.unmodifiableList(Arrays.asList(extensions.getExtensionOIDs())); } static void addExtension(ExtensionsGenerator extGenerator, ASN1ObjectIdentifier oid, boolean isCritical, ASN1Encodable value) throws CertIOException { try { extGenerator.addExtension(oid, isCritical, value); } catch (IOException e) { throw new CertIOException("cannot encode extension: " + e.getMessage(), e); } } static DERBitString booleanToBitString(boolean[] id) { byte[] bytes = new byte[(id.length + 7) / 8]; for (int i = 0; i != id.length; i++) { bytes[i / 8] |= (id[i]) ? (1 << ((7 - (i % 8)))) : 0; } int pad = id.length % 8; if (pad == 0) { return new DERBitString(bytes); } else { return new DERBitString(bytes, 8 - pad); } } static boolean[] bitStringToBoolean(DERBitString bitString) { if (bitString != null) { byte[] bytes = bitString.getBytes(); boolean[] boolId = new boolean[bytes.length * 8 - bitString.getPadBits()]; for (int i = 0; i != boolId.length; i++) { boolId[i] = (bytes[i / 8] & (0x80 >>> (i % 8))) != 0; } return boolId; } return null; } static Date recoverDate(ASN1GeneralizedTime time) { try { return time.getDate(); } catch (ParseException e) { throw new IllegalStateException("unable to recover date: " + e.getMessage()); } } static boolean isAlgIdEqual(AlgorithmIdentifier id1, AlgorithmIdentifier id2) { if (!id1.getAlgorithm().equals(id2.getAlgorithm())) { return false; } if (id1.getParameters() == null) { if (id2.getParameters() != null && !id2.getParameters().equals(DERNull.INSTANCE)) { return false; } return true; } if (id2.getParameters() == null) { if (id1.getParameters() != null && !id1.getParameters().equals(DERNull.INSTANCE)) { return false; } return true; } return id1.getParameters().equals(id2.getParameters()); } } bouncycastle-1.49.orig/src/org/bouncycastle/cert/CertRuntimeException.java0000644000175000017500000000047512135144564026435 0ustar ebourgebourgpackage org.bouncycastle.cert; public class CertRuntimeException extends RuntimeException { private Throwable cause; public CertRuntimeException(String msg, Throwable cause) { super(msg); this.cause = cause; } public Throwable getCause() { return cause; } }bouncycastle-1.49.orig/src/org/bouncycastle/cert/X509v3CertificateBuilder.java0000644000175000017500000001154511724561172026706 0ustar ebourgebourgpackage org.bouncycastle.cert; import java.math.BigInteger; import java.util.Date; import org.bouncycastle.asn1.ASN1Encodable; import org.bouncycastle.asn1.ASN1Integer; import org.bouncycastle.asn1.ASN1ObjectIdentifier; import org.bouncycastle.asn1.x500.X500Name; import org.bouncycastle.asn1.x509.Certificate; import org.bouncycastle.asn1.x509.Extension; import org.bouncycastle.asn1.x509.ExtensionsGenerator; import org.bouncycastle.asn1.x509.SubjectPublicKeyInfo; import org.bouncycastle.asn1.x509.Time; import org.bouncycastle.asn1.x509.V3TBSCertificateGenerator; import org.bouncycastle.operator.ContentSigner; /** * class to produce an X.509 Version 3 certificate. */ public class X509v3CertificateBuilder { private V3TBSCertificateGenerator tbsGen; private ExtensionsGenerator extGenerator; /** * Create a builder for a version 3 certificate. * * @param issuer the certificate issuer * @param serial the certificate serial number * @param notBefore the date before which the certificate is not valid * @param notAfter the date after which the certificate is not valid * @param subject the certificate subject * @param publicKeyInfo the info structure for the public key to be associated with this certificate. */ public X509v3CertificateBuilder(X500Name issuer, BigInteger serial, Date notBefore, Date notAfter, X500Name subject, SubjectPublicKeyInfo publicKeyInfo) { tbsGen = new V3TBSCertificateGenerator(); tbsGen.setSerialNumber(new ASN1Integer(serial)); tbsGen.setIssuer(issuer); tbsGen.setStartDate(new Time(notBefore)); tbsGen.setEndDate(new Time(notAfter)); tbsGen.setSubject(subject); tbsGen.setSubjectPublicKeyInfo(publicKeyInfo); extGenerator = new ExtensionsGenerator(); } /** * Set the subjectUniqueID - note: it is very rare that it is correct to do this. * * @param uniqueID a boolean array representing the bits making up the subjectUniqueID. * @return this builder object. */ public X509v3CertificateBuilder setSubjectUniqueID(boolean[] uniqueID) { tbsGen.setSubjectUniqueID(CertUtils.booleanToBitString(uniqueID)); return this; } /** * Set the issuerUniqueID - note: it is very rare that it is correct to do this. * * @param uniqueID a boolean array representing the bits making up the issuerUniqueID. * @return this builder object. */ public X509v3CertificateBuilder setIssuerUniqueID(boolean[] uniqueID) { tbsGen.setIssuerUniqueID(CertUtils.booleanToBitString(uniqueID)); return this; } /** * Add a given extension field for the standard extensions tag (tag 3) * * @param oid the OID defining the extension type. * @param isCritical true if the extension is critical, false otherwise. * @param value the ASN.1 structure that forms the extension's value. * @return this builder object. */ public X509v3CertificateBuilder addExtension( ASN1ObjectIdentifier oid, boolean isCritical, ASN1Encodable value) throws CertIOException { CertUtils.addExtension(extGenerator, oid, isCritical, value); return this; } /** * Add a given extension field for the standard extensions tag (tag 3) * copying the extension value from another certificate. * * @param oid the OID defining the extension type. * @param isCritical true if the copied extension is to be marked as critical, false otherwise. * @param certHolder the holder for the certificate that the extension is to be copied from. * @return this builder object. */ public X509v3CertificateBuilder copyAndAddExtension( ASN1ObjectIdentifier oid, boolean isCritical, X509CertificateHolder certHolder) { Certificate cert = certHolder.toASN1Structure(); Extension extension = cert.getTBSCertificate().getExtensions().getExtension(oid); if (extension == null) { throw new NullPointerException("extension " + oid + " not present"); } extGenerator.addExtension(oid, isCritical, extension.getExtnValue().getOctets()); return this; } /** * Generate an X.509 certificate, based on the current issuer and subject * using the passed in signer. * * @param signer the content signer to be used to generate the signature validating the certificate. * @return a holder containing the resulting signed certificate. */ public X509CertificateHolder build( ContentSigner signer) { tbsGen.setSignature(signer.getAlgorithmIdentifier()); if (!extGenerator.isEmpty()) { tbsGen.setExtensions(extGenerator.generate()); } return CertUtils.generateFullCert(signer, tbsGen.generateTBSCertificate()); } }bouncycastle-1.49.orig/src/org/bouncycastle/cert/X509v2AttributeCertificateBuilder.java0000644000175000017500000000751711737141306030572 0ustar ebourgebourgpackage org.bouncycastle.cert; import java.math.BigInteger; import java.util.Date; import org.bouncycastle.asn1.ASN1Encodable; import org.bouncycastle.asn1.ASN1GeneralizedTime; import org.bouncycastle.asn1.ASN1Integer; import org.bouncycastle.asn1.ASN1ObjectIdentifier; import org.bouncycastle.asn1.DERSet; import org.bouncycastle.asn1.x509.AttCertIssuer; import org.bouncycastle.asn1.x509.Attribute; import org.bouncycastle.asn1.x509.ExtensionsGenerator; import org.bouncycastle.asn1.x509.V2AttributeCertificateInfoGenerator; import org.bouncycastle.operator.ContentSigner; /** * class to produce an X.509 Version 2 AttributeCertificate. */ public class X509v2AttributeCertificateBuilder { private V2AttributeCertificateInfoGenerator acInfoGen; private ExtensionsGenerator extGenerator; public X509v2AttributeCertificateBuilder(AttributeCertificateHolder holder, AttributeCertificateIssuer issuer, BigInteger serialNumber, Date notBefore, Date notAfter) { acInfoGen = new V2AttributeCertificateInfoGenerator(); extGenerator = new ExtensionsGenerator(); acInfoGen.setHolder(holder.holder); acInfoGen.setIssuer(AttCertIssuer.getInstance(issuer.form)); acInfoGen.setSerialNumber(new ASN1Integer(serialNumber)); acInfoGen.setStartDate(new ASN1GeneralizedTime(notBefore)); acInfoGen.setEndDate(new ASN1GeneralizedTime(notAfter)); } /** * Add an attribute to the certification request we are building. * * @param attrType the OID giving the type of the attribute. * @param attrValue the ASN.1 structure that forms the value of the attribute. * @return this builder object. */ public X509v2AttributeCertificateBuilder addAttribute(ASN1ObjectIdentifier attrType, ASN1Encodable attrValue) { acInfoGen.addAttribute(new Attribute(attrType, new DERSet(attrValue))); return this; } /** * Add an attribute with multiple values to the certification request we are building. * * @param attrType the OID giving the type of the attribute. * @param attrValues an array of ASN.1 structures that form the value of the attribute. * @return this builder object. */ public X509v2AttributeCertificateBuilder addAttribute(ASN1ObjectIdentifier attrType, ASN1Encodable[] attrValues) { acInfoGen.addAttribute(new Attribute(attrType, new DERSet(attrValues))); return this; } public void setIssuerUniqueId( boolean[] iui) { acInfoGen.setIssuerUniqueID(CertUtils.booleanToBitString(iui)); } /** * Add a given extension field for the standard extensions tag * * @param oid the OID defining the extension type. * @param isCritical true if the extension is critical, false otherwise. * @param value the ASN.1 structure that forms the extension's value. * @return this builder object. */ public X509v2AttributeCertificateBuilder addExtension( ASN1ObjectIdentifier oid, boolean isCritical, ASN1Encodable value) throws CertIOException { CertUtils.addExtension(extGenerator, oid, isCritical, value); return this; } /** * Generate an X509 certificate, based on the current issuer and subject * using the passed in signer. * * @param signer the content signer to be used to generate the signature validating the certificate. * @return a holder containing the resulting signed certificate. */ public X509AttributeCertificateHolder build( ContentSigner signer) { acInfoGen.setSignature(signer.getAlgorithmIdentifier()); if (!extGenerator.isEmpty()) { acInfoGen.setExtensions(extGenerator.generate()); } return CertUtils.generateFullAttrCert(signer, acInfoGen.generateAttributeCertificateInfo()); } } bouncycastle-1.49.orig/src/org/bouncycastle/cert/jcajce/0000755000175000017500000000000012152033551022653 5ustar ebourgebourgbouncycastle-1.49.orig/src/org/bouncycastle/cert/jcajce/JcaX509CertificateHolder.java0000644000175000017500000000146511724561172030121 0ustar ebourgebourgpackage org.bouncycastle.cert.jcajce; import java.security.cert.CertificateEncodingException; import java.security.cert.X509Certificate; import org.bouncycastle.asn1.x509.Certificate; import org.bouncycastle.cert.X509CertificateHolder; /** * JCA helper class for converting an X509Certificate into a X509CertificateHolder object. */ public class JcaX509CertificateHolder extends X509CertificateHolder { /** * Base constructor. * * @param cert certificate to be used a the source for the holder creation. * @throws CertificateEncodingException if there is a problem extracting the certificate information. */ public JcaX509CertificateHolder(X509Certificate cert) throws CertificateEncodingException { super(Certificate.getInstance(cert.getEncoded())); } } bouncycastle-1.49.orig/src/org/bouncycastle/cert/jcajce/JcaCRLStore.java0000644000175000017500000000303511502555555025605 0ustar ebourgebourgpackage org.bouncycastle.cert.jcajce; import java.io.IOException; import java.security.cert.CRLException; import java.security.cert.X509CRL; import java.util.ArrayList; import java.util.Collection; import java.util.Iterator; import java.util.List; import org.bouncycastle.cert.X509CRLHolder; import org.bouncycastle.util.CollectionStore; /** * Class for storing CRLs for later lookup. *

    * The class will convert X509CRL objects into X509CRLHolder objects. *

    */ public class JcaCRLStore extends CollectionStore { /** * Basic constructor. * * @param collection - initial contents for the store, this is copied. */ public JcaCRLStore(Collection collection) throws CRLException { super(convertCRLs(collection)); } private static Collection convertCRLs(Collection collection) throws CRLException { List list = new ArrayList(collection.size()); for (Iterator it = collection.iterator(); it.hasNext();) { Object crl = it.next(); if (crl instanceof X509CRL) { try { list.add(new X509CRLHolder(((X509CRL)crl).getEncoded())); } catch (IOException e) { throw new CRLException("cannot read encoding: " + e.getMessage()); } } else { list.add((X509CRLHolder)crl); } } return list; } } bouncycastle-1.49.orig/src/org/bouncycastle/cert/jcajce/JcaX509ExtensionUtils.java0000644000175000017500000001022711725030156027524 0ustar ebourgebourgpackage org.bouncycastle.cert.jcajce; import java.io.ByteArrayOutputStream; import java.io.IOException; import java.io.OutputStream; import java.security.MessageDigest; import java.security.NoSuchAlgorithmException; import java.security.PublicKey; import java.security.cert.CertificateEncodingException; import java.security.cert.X509Certificate; import org.bouncycastle.asn1.ASN1OctetString; import org.bouncycastle.asn1.ASN1Primitive; import org.bouncycastle.asn1.oiw.OIWObjectIdentifiers; import org.bouncycastle.asn1.x509.AlgorithmIdentifier; import org.bouncycastle.asn1.x509.AuthorityKeyIdentifier; import org.bouncycastle.asn1.x509.SubjectKeyIdentifier; import org.bouncycastle.asn1.x509.SubjectPublicKeyInfo; import org.bouncycastle.cert.X509ExtensionUtils; import org.bouncycastle.operator.DigestCalculator; public class JcaX509ExtensionUtils extends X509ExtensionUtils { /** * Create a utility class pre-configured with a SHA-1 digest calculator based on the * default implementation. * * @throws NoSuchAlgorithmException */ public JcaX509ExtensionUtils() throws NoSuchAlgorithmException { super(new SHA1DigestCalculator(MessageDigest.getInstance("SHA1"))); } public JcaX509ExtensionUtils(DigestCalculator calculator) { super(calculator); } public AuthorityKeyIdentifier createAuthorityKeyIdentifier( X509Certificate cert) throws CertificateEncodingException { return super.createAuthorityKeyIdentifier(new JcaX509CertificateHolder(cert)); } public AuthorityKeyIdentifier createAuthorityKeyIdentifier( PublicKey pubKey) { return super.createAuthorityKeyIdentifier(SubjectPublicKeyInfo.getInstance(pubKey.getEncoded())); } /** * Return a RFC 3280 type 1 key identifier. As in: *
         * (1) The keyIdentifier is composed of the 160-bit SHA-1 hash of the
         * value of the BIT STRING subjectPublicKey (excluding the tag,
         * length, and number of unused bits).
         * 
    * @param publicKey the key object containing the key identifier is to be based on. * @return the key identifier. */ public SubjectKeyIdentifier createSubjectKeyIdentifier( PublicKey publicKey) { return super.createSubjectKeyIdentifier(SubjectPublicKeyInfo.getInstance(publicKey.getEncoded())); } /** * Return a RFC 3280 type 2 key identifier. As in: *
         * (2) The keyIdentifier is composed of a four bit type field with
         * the value 0100 followed by the least significant 60 bits of the
         * SHA-1 hash of the value of the BIT STRING subjectPublicKey.
         * 
    * @param publicKey the key object of interest. * @return the key identifier. */ public SubjectKeyIdentifier createTruncatedSubjectKeyIdentifier(PublicKey publicKey) { return super.createSubjectKeyIdentifier(SubjectPublicKeyInfo.getInstance(publicKey.getEncoded())); } /** * Return the ASN.1 object contained in a byte[] returned by a getExtensionValue() call. * * @param encExtValue DER encoded OCTET STRING containing the DER encoded extension object. * @return an ASN.1 object * @throws java.io.IOException on a parsing error. */ public static ASN1Primitive parseExtensionValue(byte[] encExtValue) throws IOException { return ASN1Primitive.fromByteArray(ASN1OctetString.getInstance(encExtValue).getOctets()); } private static class SHA1DigestCalculator implements DigestCalculator { private ByteArrayOutputStream bOut = new ByteArrayOutputStream(); private MessageDigest digest; public SHA1DigestCalculator(MessageDigest digest) { this.digest = digest; } public AlgorithmIdentifier getAlgorithmIdentifier() { return new AlgorithmIdentifier(OIWObjectIdentifiers.idSHA1); } public OutputStream getOutputStream() { return bOut; } public byte[] getDigest() { byte[] bytes = digest.digest(bOut.toByteArray()); bOut.reset(); return bytes; } } } bouncycastle-1.49.orig/src/org/bouncycastle/cert/jcajce/JcaCertStore.java0000644000175000017500000000327311502555555026066 0ustar ebourgebourgpackage org.bouncycastle.cert.jcajce; import java.io.IOException; import java.security.cert.CertificateEncodingException; import java.security.cert.X509Certificate; import java.util.ArrayList; import java.util.Collection; import java.util.Iterator; import java.util.List; import org.bouncycastle.cert.X509CertificateHolder; import org.bouncycastle.util.CollectionStore; /** * Class for storing Certificates for later lookup. *

    * The class will convert X509Certificate objects into X509CertificateHolder objects. *

    */ public class JcaCertStore extends CollectionStore { /** * Basic constructor. * * @param collection - initial contents for the store, this is copied. */ public JcaCertStore(Collection collection) throws CertificateEncodingException { super(convertCerts(collection)); } private static Collection convertCerts(Collection collection) throws CertificateEncodingException { List list = new ArrayList(collection.size()); for (Iterator it = collection.iterator(); it.hasNext();) { Object o = it.next(); if (o instanceof X509Certificate) { X509Certificate cert = (X509Certificate)o; try { list.add(new X509CertificateHolder(cert.getEncoded())); } catch (IOException e) { throw new CertificateEncodingException("unable to read encoding: " + e.getMessage()); } } else { list.add((X509CertificateHolder)o); } } return list; } } bouncycastle-1.49.orig/src/org/bouncycastle/cert/jcajce/JcaCertStoreBuilder.java0000644000175000017500000000777712151253000027367 0ustar ebourgebourgpackage org.bouncycastle.cert.jcajce; import java.security.GeneralSecurityException; import java.security.Provider; import java.security.cert.CRLException; import java.security.cert.CertStore; import java.security.cert.CertificateException; import java.security.cert.CollectionCertStoreParameters; import java.util.ArrayList; import java.util.Iterator; import java.util.List; import org.bouncycastle.cert.X509CRLHolder; import org.bouncycastle.cert.X509CertificateHolder; import org.bouncycastle.util.Store; /** * Builder to create a CertStore from certificate and CRL stores. */ public class JcaCertStoreBuilder { private List certs = new ArrayList(); private List crls = new ArrayList(); private Object provider; private JcaX509CertificateConverter certificateConverter = new JcaX509CertificateConverter(); private JcaX509CRLConverter crlConverter = new JcaX509CRLConverter(); private String type = "Collection"; /** * Add a store full of X509CertificateHolder objects. * * @param certStore a store of X509CertificateHolder objects. */ public JcaCertStoreBuilder addCertificates(Store certStore) { certs.addAll(certStore.getMatches(null)); return this; } /** * Add a single certificate. * * @param cert the X509 certificate holder containing the certificate. */ public JcaCertStoreBuilder addCertificate(X509CertificateHolder cert) { certs.add(cert); return this; } /** * Add a store full of X509CRLHolder objects. * @param crlStore a store of X509CRLHolder objects. */ public JcaCertStoreBuilder addCRLs(Store crlStore) { crls.addAll(crlStore.getMatches(null)); return this; } /** * Add a single CRL. * * @param crl the X509 CRL holder containing the CRL. */ public JcaCertStoreBuilder addCRL(X509CRLHolder crl) { crls.add(crl); return this; } public JcaCertStoreBuilder setProvider(String providerName) { certificateConverter.setProvider(providerName); crlConverter.setProvider(providerName); this.provider = providerName; return this; } public JcaCertStoreBuilder setProvider(Provider provider) { certificateConverter.setProvider(provider); crlConverter.setProvider(provider); this.provider = provider; return this; } /** * Set the type of the CertStore generated. By default it is "Collection". * * @param type type of CertStore passed to CertStore.getInstance(). * @return the current builder. */ public JcaCertStoreBuilder setType(String type) { this.type = type; return this; } /** * Build the CertStore from the current inputs. * * @return a CertStore. * @throws GeneralSecurityException */ public CertStore build() throws GeneralSecurityException { CollectionCertStoreParameters params = convertHolders(certificateConverter, crlConverter); if (provider instanceof String) { return CertStore.getInstance(type, params, (String)provider); } if (provider instanceof Provider) { return CertStore.getInstance(type, params, (Provider)provider); } return CertStore.getInstance(type, params); } private CollectionCertStoreParameters convertHolders(JcaX509CertificateConverter certificateConverter, JcaX509CRLConverter crlConverter) throws CertificateException, CRLException { List jcaObjs = new ArrayList(certs.size() + crls.size()); for (Iterator it = certs.iterator(); it.hasNext();) { jcaObjs.add(certificateConverter.getCertificate((X509CertificateHolder)it.next())); } for (Iterator it = crls.iterator(); it.hasNext();) { jcaObjs.add(crlConverter.getCRL((X509CRLHolder)it.next())); } return new CollectionCertStoreParameters(jcaObjs); } } bouncycastle-1.49.orig/src/org/bouncycastle/cert/jcajce/JcaX500NameUtil.java0000644000175000017500000000165111730536470026243 0ustar ebourgebourgpackage org.bouncycastle.cert.jcajce; import java.security.cert.X509Certificate; import org.bouncycastle.asn1.x500.X500Name; import org.bouncycastle.asn1.x500.X500NameStyle; public class JcaX500NameUtil { public static X500Name getIssuer(X509Certificate certificate) { return X500Name.getInstance(certificate.getIssuerX500Principal().getEncoded()); } public static X500Name getSubject(X509Certificate certificate) { return X500Name.getInstance(certificate.getSubjectX500Principal().getEncoded()); } public static X500Name getIssuer(X500NameStyle style, X509Certificate certificate) { return X500Name.getInstance(style, certificate.getIssuerX500Principal().getEncoded()); } public static X500Name getSubject(X500NameStyle style, X509Certificate certificate) { return X500Name.getInstance(style, certificate.getSubjectX500Principal().getEncoded()); } } bouncycastle-1.49.orig/src/org/bouncycastle/cert/jcajce/JcaAttrCertStore.java0000644000175000017500000000305011502555555026712 0ustar ebourgebourgpackage org.bouncycastle.cert.jcajce; import java.io.IOException; import java.util.ArrayList; import java.util.Collection; import java.util.Collections; import java.util.Iterator; import java.util.List; import org.bouncycastle.util.CollectionStore; import org.bouncycastle.x509.X509AttributeCertificate; /** * Class for storing Attribute Certificates for later lookup. *

    * The class will convert X509AttributeCertificate objects into X509AttributeCertificateHolder objects. *

    */ public class JcaAttrCertStore extends CollectionStore { /** * Basic constructor. * * @param collection - initial contents for the store, this is copied. */ public JcaAttrCertStore(Collection collection) throws IOException { super(convertCerts(collection)); } public JcaAttrCertStore(X509AttributeCertificate attrCert) throws IOException { this(Collections.singletonList(attrCert)); } private static Collection convertCerts(Collection collection) throws IOException { List list = new ArrayList(collection.size()); for (Iterator it = collection.iterator(); it.hasNext();) { Object o = it.next(); if (o instanceof X509AttributeCertificate) { X509AttributeCertificate cert = (X509AttributeCertificate)o; list.add(new JcaX509AttributeCertificateHolder(cert)); } else { list.add(o); } } return list; } } bouncycastle-1.49.orig/src/org/bouncycastle/cert/jcajce/JcaX509CertificateConverter.java0000644000175000017500000000614611502555555030656 0ustar ebourgebourgpackage org.bouncycastle.cert.jcajce; import java.io.ByteArrayInputStream; import java.io.IOException; import java.security.NoSuchProviderException; import java.security.Provider; import java.security.cert.CertificateException; import java.security.cert.CertificateFactory; import java.security.cert.CertificateParsingException; import java.security.cert.X509Certificate; import org.bouncycastle.cert.X509CertificateHolder; /** * Converter for producing X509Certificate objects tied to a specific provider from X509CertificateHolder objects. */ public class JcaX509CertificateConverter { private CertHelper helper = new DefaultCertHelper(); /** * Base constructor, configure with the default provider. */ public JcaX509CertificateConverter() { this.helper = new DefaultCertHelper(); } /** * Set the provider to use from a Provider object. * * @param provider the provider to use. * @return the converter instance. */ public JcaX509CertificateConverter setProvider(Provider provider) { this.helper = new ProviderCertHelper(provider); return this; } /** * Set the provider to use by name. * * @param providerName name of the provider to use. * @return the converter instance. */ public JcaX509CertificateConverter setProvider(String providerName) { this.helper = new NamedCertHelper(providerName); return this; } /** * Use the configured converter to produce a X509Certificate object from a X509CertificateHolder object. * * @param certHolder the holder to be converted * @return a X509Certificate object * @throws CertificateException if the conversion is unable to be made. */ public X509Certificate getCertificate(X509CertificateHolder certHolder) throws CertificateException { try { CertificateFactory cFact = helper.getCertificateFactory("X.509"); return (X509Certificate)cFact.generateCertificate(new ByteArrayInputStream(certHolder.getEncoded())); } catch (IOException e) { throw new ExCertificateParsingException("exception parsing certificate: " + e.getMessage(), e); } catch (NoSuchProviderException e) { throw new ExCertificateException("cannot find required provider:" + e.getMessage(), e); } } private class ExCertificateParsingException extends CertificateParsingException { private Throwable cause; public ExCertificateParsingException(String msg, Throwable cause) { super(msg); this.cause = cause; } public Throwable getCause() { return cause; } } private class ExCertificateException extends CertificateException { private Throwable cause; public ExCertificateException(String msg, Throwable cause) { super(msg); this.cause = cause; } public Throwable getCause() { return cause; } } }bouncycastle-1.49.orig/src/org/bouncycastle/cert/jcajce/JcaX509CRLHolder.java0000644000175000017500000000127211502555555026315 0ustar ebourgebourgpackage org.bouncycastle.cert.jcajce; import java.security.cert.CRLException; import java.security.cert.X509CRL; import org.bouncycastle.asn1.x509.CertificateList; import org.bouncycastle.cert.X509CRLHolder; /** * JCA helper class for converting an X509CRL into a X509CRLHolder object. */ public class JcaX509CRLHolder extends X509CRLHolder { /** * Base constructor. * * @param crl CRL to be used a the source for the holder creation. * @throws CRLException if there is a problem extracting the CRL information. */ public JcaX509CRLHolder(X509CRL crl) throws CRLException { super(CertificateList.getInstance(crl.getEncoded())); } } bouncycastle-1.49.orig/src/org/bouncycastle/cert/jcajce/DefaultCertHelper.java0000644000175000017500000000054511442065637027077 0ustar ebourgebourgpackage org.bouncycastle.cert.jcajce; import java.security.cert.CertificateException; import java.security.cert.CertificateFactory; class DefaultCertHelper extends CertHelper { protected CertificateFactory createCertificateFactory(String type) throws CertificateException { return CertificateFactory.getInstance(type); } } bouncycastle-1.49.orig/src/org/bouncycastle/cert/jcajce/JcaX509AttributeCertificateHolder.java0000644000175000017500000000156111502555555032004 0ustar ebourgebourgpackage org.bouncycastle.cert.jcajce; import java.io.IOException; import org.bouncycastle.asn1.x509.AttributeCertificate; import org.bouncycastle.cert.X509AttributeCertificateHolder; import org.bouncycastle.x509.X509AttributeCertificate; /** * JCA helper class for converting an old style X509AttributeCertificate into a X509AttributeCertificateHolder object. */ public class JcaX509AttributeCertificateHolder extends X509AttributeCertificateHolder { /** * Base constructor. * * @param cert AttributeCertificate to be used a the source for the holder creation. * @throws IOException if there is a problem extracting the attribute certificate information. */ public JcaX509AttributeCertificateHolder(X509AttributeCertificate cert) throws IOException { super(AttributeCertificate.getInstance(cert.getEncoded())); } } bouncycastle-1.49.orig/src/org/bouncycastle/cert/jcajce/CertHelper.java0000644000175000017500000000103211442065637025562 0ustar ebourgebourgpackage org.bouncycastle.cert.jcajce; import java.security.NoSuchProviderException; import java.security.cert.CertificateException; import java.security.cert.CertificateFactory; abstract class CertHelper { public CertificateFactory getCertificateFactory(String type) throws NoSuchProviderException, CertificateException { return createCertificateFactory(type); } protected abstract CertificateFactory createCertificateFactory(String type) throws CertificateException, NoSuchProviderException; } bouncycastle-1.49.orig/src/org/bouncycastle/cert/jcajce/JcaX509v3CertificateBuilder.java0000644000175000017500000001153711737201456030544 0ustar ebourgebourgpackage org.bouncycastle.cert.jcajce; import java.math.BigInteger; import java.security.PublicKey; import java.security.cert.CertificateEncodingException; import java.security.cert.X509Certificate; import java.util.Date; import javax.security.auth.x500.X500Principal; import org.bouncycastle.asn1.ASN1ObjectIdentifier; import org.bouncycastle.asn1.x500.X500Name; import org.bouncycastle.asn1.x509.SubjectPublicKeyInfo; import org.bouncycastle.cert.X509v3CertificateBuilder; /** * JCA helper class to allow JCA objects to be used in the construction of a Version 3 certificate. */ public class JcaX509v3CertificateBuilder extends X509v3CertificateBuilder { /** * Initialise the builder using a PublicKey. * * @param issuer X500Name representing the issuer of this certificate. * @param serial the serial number for the certificate. * @param notBefore date before which the certificate is not valid. * @param notAfter date after which the certificate is not valid. * @param subject X500Name representing the subject of this certificate. * @param publicKey the public key to be associated with the certificate. */ public JcaX509v3CertificateBuilder(X500Name issuer, BigInteger serial, Date notBefore, Date notAfter, X500Name subject, PublicKey publicKey) { super(issuer, serial, notBefore, notAfter, subject, SubjectPublicKeyInfo.getInstance(publicKey.getEncoded())); } /** * Initialise the builder using X500Principal objects and a PublicKey. * * @param issuer principal representing the issuer of this certificate. * @param serial the serial number for the certificate. * @param notBefore date before which the certificate is not valid. * @param notAfter date after which the certificate is not valid. * @param subject principal representing the subject of this certificate. * @param publicKey the public key to be associated with the certificate. */ public JcaX509v3CertificateBuilder(X500Principal issuer, BigInteger serial, Date notBefore, Date notAfter, X500Principal subject, PublicKey publicKey) { super(X500Name.getInstance(issuer.getEncoded()), serial, notBefore, notAfter, X500Name.getInstance(subject.getEncoded()), SubjectPublicKeyInfo.getInstance(publicKey.getEncoded())); } /** * Initialise the builder using the subject from the passed in issuerCert as the issuer, as well as * passing through and converting the other objects provided. * * @param issuerCert certificate who's subject is the issuer of the certificate we are building. * @param serial the serial number for the certificate. * @param notBefore date before which the certificate is not valid. * @param notAfter date after which the certificate is not valid. * @param subject principal representing the subject of this certificate. * @param publicKey the public key to be associated with the certificate. */ public JcaX509v3CertificateBuilder(X509Certificate issuerCert, BigInteger serial, Date notBefore, Date notAfter, X500Principal subject, PublicKey publicKey) { this(issuerCert.getSubjectX500Principal(), serial, notBefore, notAfter, subject, publicKey); } /** * Initialise the builder using the subject from the passed in issuerCert as the issuer, as well as * passing through and converting the other objects provided. * * @param issuerCert certificate who's subject is the issuer of the certificate we are building. * @param serial the serial number for the certificate. * @param notBefore date before which the certificate is not valid. * @param notAfter date after which the certificate is not valid. * @param subject principal representing the subject of this certificate. * @param publicKey the public key to be associated with the certificate. */ public JcaX509v3CertificateBuilder(X509Certificate issuerCert, BigInteger serial, Date notBefore, Date notAfter, X500Name subject, PublicKey publicKey) { this(X500Name.getInstance(issuerCert.getSubjectX500Principal().getEncoded()), serial, notBefore, notAfter, subject, publicKey); } /** * Add a given extension field for the standard extensions tag (tag 3) * copying the extension value from another certificate. * * @param oid the type of the extension to be copied. * @param critical true if the extension is to be marked critical, false otherwise. * @param certificate the source of the extension to be copied. * @return the builder instance. */ public JcaX509v3CertificateBuilder copyAndAddExtension( ASN1ObjectIdentifier oid, boolean critical, X509Certificate certificate) throws CertificateEncodingException { this.copyAndAddExtension(oid, critical, new JcaX509CertificateHolder(certificate)); return this; } } bouncycastle-1.49.orig/src/org/bouncycastle/cert/jcajce/NamedCertHelper.java0000644000175000017500000000107711442065637026540 0ustar ebourgebourgpackage org.bouncycastle.cert.jcajce; import java.security.NoSuchProviderException; import java.security.cert.CertificateException; import java.security.cert.CertificateFactory; class NamedCertHelper extends CertHelper { private final String providerName; NamedCertHelper(String providerName) { this.providerName = providerName; } protected CertificateFactory createCertificateFactory(String type) throws CertificateException, NoSuchProviderException { return CertificateFactory.getInstance(type, providerName); } }bouncycastle-1.49.orig/src/org/bouncycastle/cert/jcajce/JcaX509v2CRLBuilder.java0000644000175000017500000000111511737201604026723 0ustar ebourgebourgpackage org.bouncycastle.cert.jcajce; import java.security.cert.X509Certificate; import java.util.Date; import javax.security.auth.x500.X500Principal; import org.bouncycastle.asn1.x500.X500Name; import org.bouncycastle.cert.X509v2CRLBuilder; public class JcaX509v2CRLBuilder extends X509v2CRLBuilder { public JcaX509v2CRLBuilder(X500Principal issuer, Date now) { super(X500Name.getInstance(issuer.getEncoded()), now); } public JcaX509v2CRLBuilder(X509Certificate issuerCert, Date now) { this(issuerCert.getSubjectX500Principal(), now); } } bouncycastle-1.49.orig/src/org/bouncycastle/cert/jcajce/ProviderCertHelper.java0000644000175000017500000000101511442065637027276 0ustar ebourgebourgpackage org.bouncycastle.cert.jcajce; import java.security.Provider; import java.security.cert.CertificateException; import java.security.cert.CertificateFactory; class ProviderCertHelper extends CertHelper { private final Provider provider; ProviderCertHelper(Provider provider) { this.provider = provider; } protected CertificateFactory createCertificateFactory(String type) throws CertificateException { return CertificateFactory.getInstance(type, provider); } }bouncycastle-1.49.orig/src/org/bouncycastle/cert/jcajce/JcaX509CRLConverter.java0000644000175000017500000000527511502555555027056 0ustar ebourgebourgpackage org.bouncycastle.cert.jcajce; import java.io.ByteArrayInputStream; import java.io.IOException; import java.security.NoSuchProviderException; import java.security.Provider; import java.security.cert.CRLException; import java.security.cert.CertificateException; import java.security.cert.CertificateFactory; import java.security.cert.X509CRL; import org.bouncycastle.cert.X509CRLHolder; /** * Class for converting an X509CRLHolder into a corresponding X509CRL object tied to a * particular JCA provider. */ public class JcaX509CRLConverter { private CertHelper helper = new DefaultCertHelper(); /** * Base constructor, configure with the default provider. */ public JcaX509CRLConverter() { this.helper = new DefaultCertHelper(); } /** * Set the provider to use from a Provider object. * * @param provider the provider to use. * @return the converter instance. */ public JcaX509CRLConverter setProvider(Provider provider) { this.helper = new ProviderCertHelper(provider); return this; } /** * Set the provider to use by name. * * @param providerName name of the provider to use. * @return the converter instance. */ public JcaX509CRLConverter setProvider(String providerName) { this.helper = new NamedCertHelper(providerName); return this; } /** * Use the configured converter to produce a X509CRL object from a X509CRLHolder object. * * @param crlHolder the holder to be converted * @return a X509CRL object * @throws CRLException if the conversion is unable to be made. */ public X509CRL getCRL(X509CRLHolder crlHolder) throws CRLException { try { CertificateFactory cFact = helper.getCertificateFactory("X.509"); return (X509CRL)cFact.generateCRL(new ByteArrayInputStream(crlHolder.getEncoded())); } catch (IOException e) { throw new ExCRLException("exception parsing certificate: " + e.getMessage(), e); } catch (NoSuchProviderException e) { throw new ExCRLException("cannot find required provider:" + e.getMessage(), e); } catch (CertificateException e) { throw new ExCRLException("cannot create factory: " + e.getMessage(), e); } } private class ExCRLException extends CRLException { private Throwable cause; public ExCRLException(String msg, Throwable cause) { super(msg); this.cause = cause; } public Throwable getCause() { return cause; } } } bouncycastle-1.49.orig/src/org/bouncycastle/cert/jcajce/JcaX509v1CertificateBuilder.java0000644000175000017500000000421311502555555030535 0ustar ebourgebourgpackage org.bouncycastle.cert.jcajce; import java.math.BigInteger; import java.security.PublicKey; import java.util.Date; import javax.security.auth.x500.X500Principal; import org.bouncycastle.asn1.x500.X500Name; import org.bouncycastle.asn1.x509.SubjectPublicKeyInfo; import org.bouncycastle.cert.X509v1CertificateBuilder; /** * JCA helper class to allow JCA objects to be used in the construction of a Version 1 certificate. */ public class JcaX509v1CertificateBuilder extends X509v1CertificateBuilder { /** * Initialise the builder using a PublicKey. * * @param issuer X500Name representing the issuer of this certificate. * @param serial the serial number for the certificate. * @param notBefore date before which the certificate is not valid. * @param notAfter date after which the certificate is not valid. * @param subject X500Name representing the subject of this certificate. * @param publicKey the public key to be associated with the certificate. */ public JcaX509v1CertificateBuilder(X500Name issuer, BigInteger serial, Date notBefore, Date notAfter, X500Name subject, PublicKey publicKey) { super(issuer, serial, notBefore, notAfter, subject, SubjectPublicKeyInfo.getInstance(publicKey.getEncoded())); } /** * Initialise the builder using X500Principal objects and a PublicKey. * * @param issuer principal representing the issuer of this certificate. * @param serial the serial number for the certificate. * @param notBefore date before which the certificate is not valid. * @param notAfter date after which the certificate is not valid. * @param subject principal representing the subject of this certificate. * @param publicKey the public key to be associated with the certificate. */ public JcaX509v1CertificateBuilder(X500Principal issuer, BigInteger serial, Date notBefore, Date notAfter, X500Principal subject, PublicKey publicKey) { super(X500Name.getInstance(issuer.getEncoded()), serial, notBefore, notAfter, X500Name.getInstance(subject.getEncoded()), SubjectPublicKeyInfo.getInstance(publicKey.getEncoded())); } } bouncycastle-1.49.orig/src/org/bouncycastle/cert/jcajce/package.html0000644000175000017500000000034111501604065025133 0ustar ebourgebourg JCA extensions to the certificate building and processing package. bouncycastle-1.49.orig/src/org/bouncycastle/cert/CertIOException.java0000644000175000017500000000074411501601756025315 0ustar ebourgebourgpackage org.bouncycastle.cert; import java.io.IOException; /** * General IOException thrown in the cert package and its sub-packages. */ public class CertIOException extends IOException { private Throwable cause; public CertIOException(String msg, Throwable cause) { super(msg); this.cause = cause; } public CertIOException(String msg) { super(msg); } public Throwable getCause() { return cause; } } bouncycastle-1.49.orig/src/org/bouncycastle/cert/X509ExtensionUtils.java0000644000175000017500000001030312135144621025661 0ustar ebourgebourgpackage org.bouncycastle.cert; import java.io.IOException; import java.io.OutputStream; import org.bouncycastle.asn1.ASN1OctetString; import org.bouncycastle.asn1.x509.AuthorityKeyIdentifier; import org.bouncycastle.asn1.x509.Extension; import org.bouncycastle.asn1.x509.GeneralName; import org.bouncycastle.asn1.x509.GeneralNames; import org.bouncycastle.asn1.x509.SubjectKeyIdentifier; import org.bouncycastle.asn1.x509.SubjectPublicKeyInfo; import org.bouncycastle.operator.DigestCalculator; /** * General utility class for creating calculated extensions using the standard methods. *

    * Note: This class is not thread safe! *

    */ public class X509ExtensionUtils { private DigestCalculator calculator; public X509ExtensionUtils(DigestCalculator calculator) { this.calculator = calculator; } public AuthorityKeyIdentifier createAuthorityKeyIdentifier( X509CertificateHolder certHolder) { if (certHolder.getVersionNumber() != 3) { GeneralName genName = new GeneralName(certHolder.getIssuer()); SubjectPublicKeyInfo info = certHolder.getSubjectPublicKeyInfo(); return new AuthorityKeyIdentifier( calculateIdentifier(info), new GeneralNames(genName), certHolder.getSerialNumber()); } else { GeneralName genName = new GeneralName(certHolder.getIssuer()); Extension ext = certHolder.getExtension(Extension.subjectKeyIdentifier); if (ext != null) { ASN1OctetString str = ASN1OctetString.getInstance(ext.getParsedValue()); return new AuthorityKeyIdentifier( str.getOctets(), new GeneralNames(genName), certHolder.getSerialNumber()); } else { SubjectPublicKeyInfo info = certHolder.getSubjectPublicKeyInfo(); return new AuthorityKeyIdentifier( calculateIdentifier(info), new GeneralNames(genName), certHolder.getSerialNumber()); } } } public AuthorityKeyIdentifier createAuthorityKeyIdentifier(SubjectPublicKeyInfo publicKeyInfo) { return new AuthorityKeyIdentifier(calculateIdentifier(publicKeyInfo)); } /** * Return a RFC 3280 type 1 key identifier. As in: *
         * (1) The keyIdentifier is composed of the 160-bit SHA-1 hash of the
         * value of the BIT STRING subjectPublicKey (excluding the tag,
         * length, and number of unused bits).
         * 
    * @param publicKeyInfo the key info object containing the subjectPublicKey field. * @return the key identifier. */ public SubjectKeyIdentifier createSubjectKeyIdentifier( SubjectPublicKeyInfo publicKeyInfo) { return new SubjectKeyIdentifier(calculateIdentifier(publicKeyInfo)); } /** * Return a RFC 3280 type 2 key identifier. As in: *
         * (2) The keyIdentifier is composed of a four bit type field with
         * the value 0100 followed by the least significant 60 bits of the
         * SHA-1 hash of the value of the BIT STRING subjectPublicKey.
         * 
    * @param publicKeyInfo the key info object containing the subjectPublicKey field. * @return the key identifier. */ public SubjectKeyIdentifier createTruncatedSubjectKeyIdentifier(SubjectPublicKeyInfo publicKeyInfo) { byte[] digest = calculateIdentifier(publicKeyInfo); byte[] id = new byte[8]; System.arraycopy(digest, digest.length - 8, id, 0, id.length); id[0] &= 0x0f; id[0] |= 0x40; return new SubjectKeyIdentifier(id); } private byte[] calculateIdentifier(SubjectPublicKeyInfo publicKeyInfo) { byte[] bytes = publicKeyInfo.getPublicKeyData().getBytes(); OutputStream cOut = calculator.getOutputStream(); try { cOut.write(bytes); cOut.close(); } catch (IOException e) { // it's hard to imagine this happening, but yes it does! throw new CertRuntimeException("unable to calculate identifier: " + e.getMessage(), e); } return calculator.getDigest(); } } bouncycastle-1.49.orig/src/org/bouncycastle/cert/package.html0000644000175000017500000000022611501575763023732 0ustar ebourgebourg Basic support package for handling and creating X.509 certificates, CRLs, and attribute certificates. bouncycastle-1.49.orig/src/org/bouncycastle/cert/X509CertificateHolder.java0000644000175000017500000002167712070232011026251 0ustar ebourgebourgpackage org.bouncycastle.cert; import java.io.IOException; import java.io.OutputStream; import java.math.BigInteger; import java.util.Date; import java.util.List; import java.util.Set; import org.bouncycastle.asn1.ASN1ObjectIdentifier; import org.bouncycastle.asn1.ASN1Primitive; import org.bouncycastle.asn1.DEROutputStream; import org.bouncycastle.asn1.x500.X500Name; import org.bouncycastle.asn1.x509.AlgorithmIdentifier; import org.bouncycastle.asn1.x509.Certificate; import org.bouncycastle.asn1.x509.Extension; import org.bouncycastle.asn1.x509.Extensions; import org.bouncycastle.asn1.x509.SubjectPublicKeyInfo; import org.bouncycastle.asn1.x509.TBSCertificate; import org.bouncycastle.operator.ContentVerifier; import org.bouncycastle.operator.ContentVerifierProvider; /** * Holding class for an X.509 Certificate structure. */ public class X509CertificateHolder { private Certificate x509Certificate; private Extensions extensions; private static Certificate parseBytes(byte[] certEncoding) throws IOException { try { return Certificate.getInstance(ASN1Primitive.fromByteArray(certEncoding)); } catch (ClassCastException e) { throw new CertIOException("malformed data: " + e.getMessage(), e); } catch (IllegalArgumentException e) { throw new CertIOException("malformed data: " + e.getMessage(), e); } } /** * Create a X509CertificateHolder from the passed in bytes. * * @param certEncoding BER/DER encoding of the certificate. * @throws IOException in the event of corrupted data, or an incorrect structure. */ public X509CertificateHolder(byte[] certEncoding) throws IOException { this(parseBytes(certEncoding)); } /** * Create a X509CertificateHolder from the passed in ASN.1 structure. * * @param x509Certificate an ASN.1 Certificate structure. */ public X509CertificateHolder(Certificate x509Certificate) { this.x509Certificate = x509Certificate; this.extensions = x509Certificate.getTBSCertificate().getExtensions(); } public int getVersionNumber() { return x509Certificate.getVersionNumber(); } /** * @deprecated use getVersionNumber */ public int getVersion() { return x509Certificate.getVersionNumber(); } /** * Return whether or not the holder's certificate contains extensions. * * @return true if extension are present, false otherwise. */ public boolean hasExtensions() { return extensions != null; } /** * Look up the extension associated with the passed in OID. * * @param oid the OID of the extension of interest. * * @return the extension if present, null otherwise. */ public Extension getExtension(ASN1ObjectIdentifier oid) { if (extensions != null) { return extensions.getExtension(oid); } return null; } /** * Return the extensions block associated with this certificate if there is one. * * @return the extensions block, null otherwise. */ public Extensions getExtensions() { return extensions; } /** * Returns a list of ASN1ObjectIdentifier objects representing the OIDs of the * extensions contained in this holder's certificate. * * @return a list of extension OIDs. */ public List getExtensionOIDs() { return CertUtils.getExtensionOIDs(extensions); } /** * Returns a set of ASN1ObjectIdentifier objects representing the OIDs of the * critical extensions contained in this holder's certificate. * * @return a set of critical extension OIDs. */ public Set getCriticalExtensionOIDs() { return CertUtils.getCriticalExtensionOIDs(extensions); } /** * Returns a set of ASN1ObjectIdentifier objects representing the OIDs of the * non-critical extensions contained in this holder's certificate. * * @return a set of non-critical extension OIDs. */ public Set getNonCriticalExtensionOIDs() { return CertUtils.getNonCriticalExtensionOIDs(extensions); } /** * Return the serial number of this attribute certificate. * * @return the serial number. */ public BigInteger getSerialNumber() { return x509Certificate.getSerialNumber().getValue(); } /** * Return the issuer of this certificate. * * @return the certificate issuer. */ public X500Name getIssuer() { return X500Name.getInstance(x509Certificate.getIssuer()); } /** * Return the subject this certificate is for. * * @return the subject for the certificate. */ public X500Name getSubject() { return X500Name.getInstance(x509Certificate.getSubject()); } /** * Return the date before which this certificate is not valid. * * @return the start time for the certificate's validity period. */ public Date getNotBefore() { return x509Certificate.getStartDate().getDate(); } /** * Return the date after which this certificate is not valid. * * @return the final time for the certificate's validity period. */ public Date getNotAfter() { return x509Certificate.getEndDate().getDate(); } /** * Return the SubjectPublicKeyInfo describing the public key this certificate is carrying. * * @return the public key ASN.1 structure contained in the certificate. */ public SubjectPublicKeyInfo getSubjectPublicKeyInfo() { return x509Certificate.getSubjectPublicKeyInfo(); } /** * Return the underlying ASN.1 structure for the certificate in this holder. * * @return a X509CertificateStructure object. */ public Certificate toASN1Structure() { return x509Certificate; } /** * Return the details of the signature algorithm used to create this attribute certificate. * * @return the AlgorithmIdentifier describing the signature algorithm used to create this attribute certificate. */ public AlgorithmIdentifier getSignatureAlgorithm() { return x509Certificate.getSignatureAlgorithm(); } /** * Return the bytes making up the signature associated with this attribute certificate. * * @return the attribute certificate signature bytes. */ public byte[] getSignature() { return x509Certificate.getSignature().getBytes(); } /** * Return whether or not this certificate is valid on a particular date. * * @param date the date of interest. * @return true if the certificate is valid, false otherwise. */ public boolean isValidOn(Date date) { return !date.before(x509Certificate.getStartDate().getDate()) && !date.after(x509Certificate.getEndDate().getDate()); } /** * Validate the signature on the certificate in this holder. * * @param verifierProvider a ContentVerifierProvider that can generate a verifier for the signature. * @return true if the signature is valid, false otherwise. * @throws CertException if the signature cannot be processed or is inappropriate. */ public boolean isSignatureValid(ContentVerifierProvider verifierProvider) throws CertException { TBSCertificate tbsCert = x509Certificate.getTBSCertificate(); if (!CertUtils.isAlgIdEqual(tbsCert.getSignature(), x509Certificate.getSignatureAlgorithm())) { throw new CertException("signature invalid - algorithm identifier mismatch"); } ContentVerifier verifier; try { verifier = verifierProvider.get((tbsCert.getSignature())); OutputStream sOut = verifier.getOutputStream(); DEROutputStream dOut = new DEROutputStream(sOut); dOut.writeObject(tbsCert); sOut.close(); } catch (Exception e) { throw new CertException("unable to process signature: " + e.getMessage(), e); } return verifier.verify(x509Certificate.getSignature().getBytes()); } public boolean equals( Object o) { if (o == this) { return true; } if (!(o instanceof X509CertificateHolder)) { return false; } X509CertificateHolder other = (X509CertificateHolder)o; return this.x509Certificate.equals(other.x509Certificate); } public int hashCode() { return this.x509Certificate.hashCode(); } /** * Return the ASN.1 encoding of this holder's certificate. * * @return a DER encoded byte array. * @throws IOException if an encoding cannot be generated. */ public byte[] getEncoded() throws IOException { return x509Certificate.getEncoded(); } } bouncycastle-1.49.orig/src/org/bouncycastle/pqc/0000755000175000017500000000000012152033551021262 5ustar ebourgebourgbouncycastle-1.49.orig/src/org/bouncycastle/pqc/crypto/0000755000175000017500000000000012152033551022602 5ustar ebourgebourgbouncycastle-1.49.orig/src/org/bouncycastle/pqc/crypto/gmss/0000755000175000017500000000000012152033551023553 5ustar ebourgebourgbouncycastle-1.49.orig/src/org/bouncycastle/pqc/crypto/gmss/GMSSPublicKeyParameters.java0000644000175000017500000000126311777163657031054 0ustar ebourgebourgpackage org.bouncycastle.pqc.crypto.gmss; public class GMSSPublicKeyParameters extends GMSSKeyParameters { /** * The GMSS public key */ private byte[] gmssPublicKey; /** * The constructor. * * @param key a raw GMSS public key * @param gmssParameterSet an instance of GMSSParameterset */ public GMSSPublicKeyParameters(byte[] key, GMSSParameters gmssParameterSet) { super(false, gmssParameterSet); this.gmssPublicKey = key; } /** * Returns the GMSS public key * * @return The GMSS public key */ public byte[] getPublicKey() { return gmssPublicKey; } } bouncycastle-1.49.orig/src/org/bouncycastle/pqc/crypto/gmss/GMSSPrivateKeyParameters.java0000644000175000017500000011045012121454746031231 0ustar ebourgebourgpackage org.bouncycastle.pqc.crypto.gmss; import java.util.Vector; import org.bouncycastle.crypto.Digest; import org.bouncycastle.pqc.crypto.gmss.util.GMSSRandom; import org.bouncycastle.pqc.crypto.gmss.util.WinternitzOTSignature; import org.bouncycastle.util.Arrays; /** * This class provides a specification for a GMSS private key. */ public class GMSSPrivateKeyParameters extends GMSSKeyParameters { private int[] index; private byte[][] currentSeeds; private byte[][] nextNextSeeds; private byte[][][] currentAuthPaths; private byte[][][] nextAuthPaths; private Treehash[][] currentTreehash; private Treehash[][] nextTreehash; private Vector[] currentStack; private Vector[] nextStack; private Vector[][] currentRetain; private Vector[][] nextRetain; private byte[][][] keep; private GMSSLeaf[] nextNextLeaf; private GMSSLeaf[] upperLeaf; private GMSSLeaf[] upperTreehashLeaf; private int[] minTreehash; private GMSSParameters gmssPS; private byte[][] nextRoot; private GMSSRootCalc[] nextNextRoot; private byte[][] currentRootSig; private GMSSRootSig[] nextRootSig; private GMSSDigestProvider digestProvider; private boolean used = false; /** * An array of the heights of the authentication trees of each layer */ private int[] heightOfTrees; /** * An array of the Winternitz parameter 'w' of each layer */ private int[] otsIndex; /** * The parameter K needed for the authentication path computation */ private int[] K; /** * the number of Layers */ private int numLayer; /** * The hash function used to construct the authentication trees */ private Digest messDigestTrees; /** * The message digest length */ private int mdLength; /** * The PRNG used for private key generation */ private GMSSRandom gmssRandom; /** * The number of leafs of one tree of each layer */ private int[] numLeafs; /** * Generates a new GMSS private key * * @param currentSeed seed for the generation of private OTS keys for the * current subtrees * @param nextNextSeed seed for the generation of private OTS keys for the next * subtrees * @param currentAuthPath array of current authentication paths * @param nextAuthPath array of next authentication paths * @param currentTreehash array of current treehash instances * @param nextTreehash array of next treehash instances * @param currentStack array of current shared stacks * @param nextStack array of next shared stacks * @param currentRetain array of current retain stacks * @param nextRetain array of next retain stacks * @param nextRoot the roots of the next subtree * @param currentRootSig array of signatures of the roots of the current subtrees * @param gmssParameterset the GMSS Parameterset * @see org.bouncycastle.pqc.crypto.gmss.GMSSKeyPairGenerator */ public GMSSPrivateKeyParameters(byte[][] currentSeed, byte[][] nextNextSeed, byte[][][] currentAuthPath, byte[][][] nextAuthPath, Treehash[][] currentTreehash, Treehash[][] nextTreehash, Vector[] currentStack, Vector[] nextStack, Vector[][] currentRetain, Vector[][] nextRetain, byte[][] nextRoot, byte[][] currentRootSig, GMSSParameters gmssParameterset, GMSSDigestProvider digestProvider) { this(null, currentSeed, nextNextSeed, currentAuthPath, nextAuthPath, null, currentTreehash, nextTreehash, currentStack, nextStack, currentRetain, nextRetain, null, null, null, null, nextRoot, null, currentRootSig, null, gmssParameterset, digestProvider); } /** * /** * * @param index tree indices * @param keep keep array for the authPath algorithm * @param currentTreehash treehash for authPath algorithm of current tree * @param nextTreehash treehash for authPath algorithm of next tree (TREE+) * @param currentStack shared stack for authPath algorithm of current tree * @param nextStack shared stack for authPath algorithm of next tree (TREE+) * @param currentRetain retain stack for authPath algorithm of current tree * @param nextRetain retain stack for authPath algorithm of next tree (TREE+) * @param nextNextLeaf array of upcoming leafs of the tree after next (LEAF++) of * each layer * @param upperLeaf needed for precomputation of upper nodes * @param upperTreehashLeaf needed for precomputation of upper treehash nodes * @param minTreehash index of next treehash instance to receive an update * @param nextRoot the roots of the next trees (ROOT+) * @param nextNextRoot the roots of the tree after next (ROOT++) * @param currentRootSig array of signatures of the roots of the current subtrees * (SIG) * @param nextRootSig array of signatures of the roots of the next subtree * (SIG+) * @param gmssParameterset the GMSS Parameterset */ public GMSSPrivateKeyParameters(int[] index, byte[][] currentSeeds, byte[][] nextNextSeeds, byte[][][] currentAuthPaths, byte[][][] nextAuthPaths, byte[][][] keep, Treehash[][] currentTreehash, Treehash[][] nextTreehash, Vector[] currentStack, Vector[] nextStack, Vector[][] currentRetain, Vector[][] nextRetain, GMSSLeaf[] nextNextLeaf, GMSSLeaf[] upperLeaf, GMSSLeaf[] upperTreehashLeaf, int[] minTreehash, byte[][] nextRoot, GMSSRootCalc[] nextNextRoot, byte[][] currentRootSig, GMSSRootSig[] nextRootSig, GMSSParameters gmssParameterset, GMSSDigestProvider digestProvider) { super(true, gmssParameterset); // construct message digest this.messDigestTrees = digestProvider.get(); this.mdLength = messDigestTrees.getDigestSize(); // Parameter this.gmssPS = gmssParameterset; this.otsIndex = gmssParameterset.getWinternitzParameter(); this.K = gmssParameterset.getK(); this.heightOfTrees = gmssParameterset.getHeightOfTrees(); // initialize numLayer this.numLayer = gmssPS.getNumOfLayers(); // initialize index if null if (index == null) { this.index = new int[numLayer]; for (int i = 0; i < numLayer; i++) { this.index[i] = 0; } } else { this.index = index; } this.currentSeeds = currentSeeds; this.nextNextSeeds = nextNextSeeds; this.currentAuthPaths = currentAuthPaths; this.nextAuthPaths = nextAuthPaths; // initialize keep if null if (keep == null) { this.keep = new byte[numLayer][][]; for (int i = 0; i < numLayer; i++) { this.keep[i] = new byte[(int)Math.floor(heightOfTrees[i] / 2)][mdLength]; } } else { this.keep = keep; } // initialize stack if null if (currentStack == null) { this.currentStack = new Vector[numLayer]; for (int i = 0; i < numLayer; i++) { this.currentStack[i] = new Vector(); } } else { this.currentStack = currentStack; } // initialize nextStack if null if (nextStack == null) { this.nextStack = new Vector[numLayer - 1]; for (int i = 0; i < numLayer - 1; i++) { this.nextStack[i] = new Vector(); } } else { this.nextStack = nextStack; } this.currentTreehash = currentTreehash; this.nextTreehash = nextTreehash; this.currentRetain = currentRetain; this.nextRetain = nextRetain; this.nextRoot = nextRoot; this.digestProvider = digestProvider; if (nextNextRoot == null) { this.nextNextRoot = new GMSSRootCalc[numLayer - 1]; for (int i = 0; i < numLayer - 1; i++) { this.nextNextRoot[i] = new GMSSRootCalc( this.heightOfTrees[i + 1], this.K[i + 1], this.digestProvider); } } else { this.nextNextRoot = nextNextRoot; } this.currentRootSig = currentRootSig; // calculate numLeafs numLeafs = new int[numLayer]; for (int i = 0; i < numLayer; i++) { numLeafs[i] = 1 << heightOfTrees[i]; } // construct PRNG this.gmssRandom = new GMSSRandom(messDigestTrees); if (numLayer > 1) { // construct the nextNextLeaf (LEAFs++) array for upcoming leafs in // tree after next (TREE++) if (nextNextLeaf == null) { this.nextNextLeaf = new GMSSLeaf[numLayer - 2]; for (int i = 0; i < numLayer - 2; i++) { this.nextNextLeaf[i] = new GMSSLeaf(digestProvider.get(), otsIndex[i + 1], numLeafs[i + 2], this.nextNextSeeds[i]); } } else { this.nextNextLeaf = nextNextLeaf; } } else { this.nextNextLeaf = new GMSSLeaf[0]; } // construct the upperLeaf array for upcoming leafs in tree over the // actual if (upperLeaf == null) { this.upperLeaf = new GMSSLeaf[numLayer - 1]; for (int i = 0; i < numLayer - 1; i++) { this.upperLeaf[i] = new GMSSLeaf(digestProvider.get(), otsIndex[i], numLeafs[i + 1], this.currentSeeds[i]); } } else { this.upperLeaf = upperLeaf; } // construct the leafs for upcoming leafs in treehashs in tree over the // actual if (upperTreehashLeaf == null) { this.upperTreehashLeaf = new GMSSLeaf[numLayer - 1]; for (int i = 0; i < numLayer - 1; i++) { this.upperTreehashLeaf[i] = new GMSSLeaf(digestProvider.get(), otsIndex[i], numLeafs[i + 1]); } } else { this.upperTreehashLeaf = upperTreehashLeaf; } if (minTreehash == null) { this.minTreehash = new int[numLayer - 1]; for (int i = 0; i < numLayer - 1; i++) { this.minTreehash[i] = -1; } } else { this.minTreehash = minTreehash; } // construct the nextRootSig (RootSig++) byte[] dummy = new byte[mdLength]; byte[] OTSseed = new byte[mdLength]; if (nextRootSig == null) { this.nextRootSig = new GMSSRootSig[numLayer - 1]; for (int i = 0; i < numLayer - 1; i++) { System.arraycopy(currentSeeds[i], 0, dummy, 0, mdLength); gmssRandom.nextSeed(dummy); OTSseed = gmssRandom.nextSeed(dummy); this.nextRootSig[i] = new GMSSRootSig(digestProvider.get(), otsIndex[i], heightOfTrees[i + 1]); this.nextRootSig[i].initSign(OTSseed, nextRoot[i]); } } else { this.nextRootSig = nextRootSig; } } // we assume this only gets called from nextKey so used is never copied. private GMSSPrivateKeyParameters(GMSSPrivateKeyParameters original) { super(true, original.getParameters()); this.index = Arrays.clone(original.index); this.currentSeeds = Arrays.clone(original.currentSeeds); this.nextNextSeeds = Arrays.clone(original.nextNextSeeds); this.currentAuthPaths = Arrays.clone(original.currentAuthPaths); this.nextAuthPaths = Arrays.clone(original.nextAuthPaths); this.currentTreehash = original.currentTreehash; this.nextTreehash = original.nextTreehash; this.currentStack = original.currentStack; this.nextStack = original.nextStack; this.currentRetain = original.currentRetain; this.nextRetain = original.nextRetain; this.keep = Arrays.clone(original.keep); this.nextNextLeaf = original.nextNextLeaf; this.upperLeaf = original.upperLeaf; this.upperTreehashLeaf = original.upperTreehashLeaf; this.minTreehash = original.minTreehash; this.gmssPS = original.gmssPS; this.nextRoot = Arrays.clone(original.nextRoot); this.nextNextRoot = original.nextNextRoot; this.currentRootSig = original.currentRootSig; this.nextRootSig = original.nextRootSig; this.digestProvider = original.digestProvider; this.heightOfTrees = original.heightOfTrees; this.otsIndex = original.otsIndex; this.K = original.K; this.numLayer = original.numLayer; this.messDigestTrees = original.messDigestTrees; this.mdLength = original.mdLength; this.gmssRandom = original.gmssRandom; this.numLeafs = original.numLeafs; } public boolean isUsed() { return this.used; } public void markUsed() { this.used = true; } public GMSSPrivateKeyParameters nextKey() { GMSSPrivateKeyParameters nKey = new GMSSPrivateKeyParameters(this); nKey.nextKey(gmssPS.getNumOfLayers() - 1); return nKey; } /** * This method updates the GMSS private key for the next signature * * @param layer the layer where the next key is processed */ private void nextKey(int layer) { // only for lowest layer ( other layers indices are raised in nextTree() // method ) if (layer == numLayer - 1) { index[layer]++; } // else System.out.println(" --- nextKey on layer " + layer + " // index is now : " + index[layer]); // if tree of this layer is depleted if (index[layer] == numLeafs[layer]) { if (numLayer != 1) { nextTree(layer); index[layer] = 0; } } else { updateKey(layer); } } /** * Switch to next subtree if the current one is depleted * * @param layer the layer where the next tree is processed */ private void nextTree(int layer) { // System.out.println("NextTree method called on layer " + layer); // dont create next tree for the top layer if (layer > 0) { // raise index for upper layer index[layer - 1]++; // test if it is already the last tree boolean lastTree = true; int z = layer; do { z--; if (index[z] < numLeafs[z]) { lastTree = false; } } while (lastTree && (z > 0)); // only construct next subtree if last one is not already in use if (!lastTree) { gmssRandom.nextSeed(currentSeeds[layer]); // last step of distributed signature calculation nextRootSig[layer - 1].updateSign(); // last step of distributed leaf calculation for nextNextLeaf if (layer > 1) { nextNextLeaf[layer - 1 - 1] = nextNextLeaf[layer - 1 - 1].nextLeaf(); } // last step of distributed leaf calculation for upper leaf upperLeaf[layer - 1] = upperLeaf[layer - 1].nextLeaf(); // last step of distributed leaf calculation for all treehashs if (minTreehash[layer - 1] >= 0) { upperTreehashLeaf[layer - 1] = upperTreehashLeaf[layer - 1].nextLeaf(); byte[] leaf = this.upperTreehashLeaf[layer - 1].getLeaf(); // if update is required use the precomputed leaf to update // treehash try { currentTreehash[layer - 1][minTreehash[layer - 1]] .update(this.gmssRandom, leaf); // System.out.println("UUUpdated TH " + // minTreehash[layer - 1]); if (currentTreehash[layer - 1][minTreehash[layer - 1]] .wasFinished()) { // System.out.println("FFFinished TH " + // minTreehash[layer - 1]); } } catch (Exception e) { System.out.println(e); } } // last step of nextNextAuthRoot calculation this.updateNextNextAuthRoot(layer); // ******************************************************** / // NOW: advance to next tree on layer 'layer' // NextRootSig --> currentRootSigs this.currentRootSig[layer - 1] = nextRootSig[layer - 1] .getSig(); // ----------------------- // nextTreehash --> currentTreehash // nextNextTreehash --> nextTreehash for (int i = 0; i < heightOfTrees[layer] - K[layer]; i++) { this.currentTreehash[layer][i] = this.nextTreehash[layer - 1][i]; this.nextTreehash[layer - 1][i] = this.nextNextRoot[layer - 1] .getTreehash()[i]; } // NextAuthPath --> currentAuthPath // nextNextAuthPath --> nextAuthPath for (int i = 0; i < heightOfTrees[layer]; i++) { System.arraycopy(nextAuthPaths[layer - 1][i], 0, currentAuthPaths[layer][i], 0, mdLength); System.arraycopy(nextNextRoot[layer - 1].getAuthPath()[i], 0, nextAuthPaths[layer - 1][i], 0, mdLength); } // nextRetain --> currentRetain // nextNextRetain --> nextRetain for (int i = 0; i < K[layer] - 1; i++) { this.currentRetain[layer][i] = this.nextRetain[layer - 1][i]; this.nextRetain[layer - 1][i] = this.nextNextRoot[layer - 1] .getRetain()[i]; } // nextStack --> currentStack this.currentStack[layer] = this.nextStack[layer - 1]; // nextNextStack --> nextStack this.nextStack[layer - 1] = this.nextNextRoot[layer - 1] .getStack(); // nextNextRoot --> nextRoot this.nextRoot[layer - 1] = this.nextNextRoot[layer - 1] .getRoot(); // ----------------------- // ----------------- byte[] OTSseed = new byte[mdLength]; byte[] dummy = new byte[mdLength]; // gmssRandom.setSeed(currentSeeds[layer]); System .arraycopy(currentSeeds[layer - 1], 0, dummy, 0, mdLength); OTSseed = gmssRandom.nextSeed(dummy); // only need OTSSeed OTSseed = gmssRandom.nextSeed(dummy); OTSseed = gmssRandom.nextSeed(dummy); // nextWinSig[layer-1]=new // GMSSWinSig(OTSseed,algNames,otsIndex[layer-1],heightOfTrees[layer],nextRoot[layer-1]); nextRootSig[layer - 1].initSign(OTSseed, nextRoot[layer - 1]); // nextKey for upper layer nextKey(layer - 1); } } } /** * This method computes the authpath (AUTH) for the current tree, * Additionally the root signature for the next tree (SIG+), the authpath * (AUTH++) and root (ROOT++) for the tree after next in layer * layer, and the LEAF++^1 for the next next tree in the * layer above are updated This method is used by nextKey() * * @param layer */ private void updateKey(int layer) { // ----------current tree processing of actual layer--------- // compute upcoming authpath for current Tree (AUTH) computeAuthPaths(layer); // -----------distributed calculations part------------ // not for highest tree layer if (layer > 0) { // compute (partial) next leaf on TREE++ (not on layer 1 and 0) if (layer > 1) { nextNextLeaf[layer - 1 - 1] = nextNextLeaf[layer - 1 - 1].nextLeaf(); } // compute (partial) next leaf on tree above (not on layer 0) upperLeaf[layer - 1] = upperLeaf[layer - 1].nextLeaf(); // compute (partial) next leaf for all treehashs on tree above (not // on layer 0) int t = (int)Math .floor((double)(this.getNumLeafs(layer) * 2) / (double)(this.heightOfTrees[layer - 1] - this.K[layer - 1])); if (index[layer] % t == 1) { // System.out.println(" layer: " + layer + " index: " + // index[layer] + " t : " + t); // take precomputed node for treehash update // ------------------------------------------------ if (index[layer] > 1 && minTreehash[layer - 1] >= 0) { byte[] leaf = this.upperTreehashLeaf[layer - 1].getLeaf(); // if update is required use the precomputed leaf to update // treehash try { currentTreehash[layer - 1][minTreehash[layer - 1]] .update(this.gmssRandom, leaf); // System.out.println("Updated TH " + minTreehash[layer // - 1]); if (currentTreehash[layer - 1][minTreehash[layer - 1]] .wasFinished()) { // System.out.println("Finished TH " + // minTreehash[layer - 1]); } } catch (Exception e) { System.out.println(e); } // ------------------------------------------------ } // initialize next leaf precomputation // ------------------------------------------------ // get lowest index of treehashs this.minTreehash[layer - 1] = getMinTreehashIndex(layer - 1); if (this.minTreehash[layer - 1] >= 0) { // initialize leaf byte[] seed = this.currentTreehash[layer - 1][this.minTreehash[layer - 1]] .getSeedActive(); this.upperTreehashLeaf[layer - 1] = new GMSSLeaf( this.digestProvider.get(), this.otsIndex[layer - 1], t, seed); this.upperTreehashLeaf[layer - 1] = this.upperTreehashLeaf[layer - 1].nextLeaf(); // System.out.println("restarted treehashleaf (" + (layer - // 1) + "," + this.minTreehash[layer - 1] + ")"); } // ------------------------------------------------ } else { // update the upper leaf for the treehash one step if (this.minTreehash[layer - 1] >= 0) { this.upperTreehashLeaf[layer - 1] = this.upperTreehashLeaf[layer - 1].nextLeaf(); // if (minTreehash[layer - 1] > 3) // System.out.print("#"); } } // compute (partial) the signature of ROOT+ (RootSig+) (not on top // layer) nextRootSig[layer - 1].updateSign(); // compute (partial) AUTHPATH++ & ROOT++ (not on top layer) if (index[layer] == 1) { // init root and authpath calculation for tree after next // (AUTH++, ROOT++) this.nextNextRoot[layer - 1].initialize(new Vector()); } // update root and authpath calculation for tree after next (AUTH++, // ROOT++) this.updateNextNextAuthRoot(layer); } // ----------- end distributed calculations part----------------- } /** * This method returns the index of the next Treehash instance that should * receive an update * * @param layer the layer of the GMSS tree * @return index of the treehash instance that should get the update */ private int getMinTreehashIndex(int layer) { int minTreehash = -1; for (int h = 0; h < heightOfTrees[layer] - K[layer]; h++) { if (currentTreehash[layer][h].wasInitialized() && !currentTreehash[layer][h].wasFinished()) { if (minTreehash == -1) { minTreehash = h; } else if (currentTreehash[layer][h].getLowestNodeHeight() < currentTreehash[layer][minTreehash] .getLowestNodeHeight()) { minTreehash = h; } } } return minTreehash; } /** * Computes the upcoming currentAuthpath of layer layer using * the revisited authentication path computation of Dahmen/Schneider 2008 * * @param layer the actual layer */ private void computeAuthPaths(int layer) { int Phi = index[layer]; int H = heightOfTrees[layer]; int K = this.K[layer]; // update all nextSeeds for seed scheduling for (int i = 0; i < H - K; i++) { currentTreehash[layer][i].updateNextSeed(gmssRandom); } // STEP 1 of Algorithm int Tau = heightOfPhi(Phi); byte[] OTSseed = new byte[mdLength]; OTSseed = gmssRandom.nextSeed(currentSeeds[layer]); // STEP 2 of Algorithm // if phi's parent on height tau + 1 if left node, store auth_tau // in keep_tau. // TODO check it, formerly was // int L = Phi / (int) Math.floor(Math.pow(2, Tau + 1)); // L %= 2; int L = (Phi >>> (Tau + 1)) & 1; byte[] tempKeep = new byte[mdLength]; // store the keep node not in keep[layer][tau/2] because it might be in // use // wait until the space is freed in step 4a if (Tau < H - 1 && L == 0) { System.arraycopy(currentAuthPaths[layer][Tau], 0, tempKeep, 0, mdLength); } byte[] help = new byte[mdLength]; // STEP 3 of Algorithm // if phi is left child, compute and store leaf for next currentAuthPath // path, // (obtained by veriying current signature) if (Tau == 0) { // LEAFCALC !!! if (layer == numLayer - 1) { // lowest layer computes the // necessary leaf completely at this // time WinternitzOTSignature ots = new WinternitzOTSignature(OTSseed, digestProvider.get(), otsIndex[layer]); help = ots.getPublicKey(); } else { // other layers use the precomputed leafs in // nextNextLeaf byte[] dummy = new byte[mdLength]; System.arraycopy(currentSeeds[layer], 0, dummy, 0, mdLength); gmssRandom.nextSeed(dummy); help = upperLeaf[layer].getLeaf(); this.upperLeaf[layer].initLeafCalc(dummy); // WinternitzOTSVerify otsver = new // WinternitzOTSVerify(algNames, otsIndex[layer]); // byte[] help2 = otsver.Verify(currentRoot[layer], // currentRootSig[layer]); // System.out.println(" --- " + layer + " " + // ByteUtils.toHexString(help) + " " + // ByteUtils.toHexString(help2)); } System.arraycopy(help, 0, currentAuthPaths[layer][0], 0, mdLength); } else { // STEP 4a of Algorithm // get new left currentAuthPath node on height tau byte[] toBeHashed = new byte[mdLength << 1]; System.arraycopy(currentAuthPaths[layer][Tau - 1], 0, toBeHashed, 0, mdLength); // free the shared keep[layer][tau/2] System.arraycopy(keep[layer][(int)Math.floor((Tau - 1) / 2)], 0, toBeHashed, mdLength, mdLength); messDigestTrees.update(toBeHashed, 0, toBeHashed.length); currentAuthPaths[layer][Tau] = new byte[messDigestTrees.getDigestSize()]; messDigestTrees.doFinal(currentAuthPaths[layer][Tau], 0); // STEP 4b and 4c of Algorithm // copy right nodes to currentAuthPath on height 0..Tau-1 for (int i = 0; i < Tau; i++) { // STEP 4b of Algorithm // 1st: copy from treehashs if (i < H - K) { if (currentTreehash[layer][i].wasFinished()) { System.arraycopy(currentTreehash[layer][i] .getFirstNode(), 0, currentAuthPaths[layer][i], 0, mdLength); currentTreehash[layer][i].destroy(); } else { System.err .println("Treehash (" + layer + "," + i + ") not finished when needed in AuthPathComputation"); } } // 2nd: copy precomputed values from Retain if (i < H - 1 && i >= H - K) { if (currentRetain[layer][i - (H - K)].size() > 0) { // pop element from retain System.arraycopy(currentRetain[layer][i - (H - K)] .lastElement(), 0, currentAuthPaths[layer][i], 0, mdLength); currentRetain[layer][i - (H - K)] .removeElementAt(currentRetain[layer][i - (H - K)].size() - 1); } } // STEP 4c of Algorithm // initialize new stack at heights 0..Tau-1 if (i < H - K) { // create stacks anew int startPoint = Phi + 3 * (1 << i); if (startPoint < numLeafs[layer]) { // if (layer < 2) { // System.out.println("initialized TH " + i + " on layer // " + layer); // } currentTreehash[layer][i].initialize(); } } } } // now keep space is free to use if (Tau < H - 1 && L == 0) { System.arraycopy(tempKeep, 0, keep[layer][(int)Math.floor(Tau / 2)], 0, mdLength); } // only update empty stack at height h if all other stacks have // tailnodes with height >h // finds active stack with lowest node height, choses lower index in // case of tie // on the lowest layer leafs must be computed at once, no precomputation // is possible. So all treehash updates are done at once here if (layer == numLayer - 1) { for (int tmp = 1; tmp <= (H - K) / 2; tmp++) { // index of the treehash instance that receives the next update int minTreehash = getMinTreehashIndex(layer); // if active treehash is found update with a leaf if (minTreehash >= 0) { try { byte[] seed = new byte[mdLength]; System.arraycopy( this.currentTreehash[layer][minTreehash] .getSeedActive(), 0, seed, 0, mdLength); byte[] seed2 = gmssRandom.nextSeed(seed); WinternitzOTSignature ots = new WinternitzOTSignature( seed2, this.digestProvider.get(), this.otsIndex[layer]); byte[] leaf = ots.getPublicKey(); currentTreehash[layer][minTreehash].update( this.gmssRandom, leaf); } catch (Exception e) { System.out.println(e); } } } } else { // on higher layers the updates are done later this.minTreehash[layer] = getMinTreehashIndex(layer); } } /** * Returns the largest h such that 2^h | Phi * * @param Phi the leaf index * @return The largest h with 2^h | Phi if * Phi!=0 else return -1 */ private int heightOfPhi(int Phi) { if (Phi == 0) { return -1; } int Tau = 0; int modul = 1; while (Phi % modul == 0) { modul *= 2; Tau += 1; } return Tau - 1; } /** * Updates the authentication path and root calculation for the tree after * next (AUTH++, ROOT++) in layer layer * * @param layer */ private void updateNextNextAuthRoot(int layer) { byte[] OTSseed = new byte[mdLength]; OTSseed = gmssRandom.nextSeed(nextNextSeeds[layer - 1]); // get the necessary leaf if (layer == numLayer - 1) { // lowest layer computes the necessary // leaf completely at this time WinternitzOTSignature ots = new WinternitzOTSignature(OTSseed, digestProvider.get(), otsIndex[layer]); this.nextNextRoot[layer - 1].update(nextNextSeeds[layer - 1], ots .getPublicKey()); } else { // other layers use the precomputed leafs in nextNextLeaf this.nextNextRoot[layer - 1].update(nextNextSeeds[layer - 1], nextNextLeaf[layer - 1].getLeaf()); this.nextNextLeaf[layer - 1].initLeafCalc(nextNextSeeds[layer - 1]); } } public int[] getIndex() { return index; } /** * @return The current index of layer i */ public int getIndex(int i) { return index[i]; } public byte[][] getCurrentSeeds() { return Arrays.clone(currentSeeds); } public byte[][][] getCurrentAuthPaths() { return Arrays.clone(currentAuthPaths); } /** * @return The one-time signature of the root of the current subtree */ public byte[] getSubtreeRootSig(int i) { return currentRootSig[i]; } public GMSSDigestProvider getName() { return digestProvider; } /** * @return The number of leafs of each tree of layer i */ public int getNumLeafs(int i) { return numLeafs[i]; } } bouncycastle-1.49.orig/src/org/bouncycastle/pqc/crypto/gmss/GMSSKeyGenerationParameters.java0000644000175000017500000000101511775466510031714 0ustar ebourgebourgpackage org.bouncycastle.pqc.crypto.gmss; import java.security.SecureRandom; import org.bouncycastle.crypto.KeyGenerationParameters; public class GMSSKeyGenerationParameters extends KeyGenerationParameters { private GMSSParameters params; public GMSSKeyGenerationParameters( SecureRandom random, GMSSParameters params) { // XXX key size? super(random, 1); this.params = params; } public GMSSParameters getParameters() { return params; } } bouncycastle-1.49.orig/src/org/bouncycastle/pqc/crypto/gmss/util/0000755000175000017500000000000012152033551024530 5ustar ebourgebourgbouncycastle-1.49.orig/src/org/bouncycastle/pqc/crypto/gmss/util/WinternitzOTSVerify.java0000644000175000017500000002405412151551720031332 0ustar ebourgebourgpackage org.bouncycastle.pqc.crypto.gmss.util; import org.bouncycastle.crypto.Digest; /** * This class implements signature verification of the Winternitz one-time * signature scheme (OTSS), described in C.Dods, N.P. Smart, and M. Stam, "Hash * Based Digital Signature Schemes", LNCS 3796, pages 96–115, 2005. The * class is used by the GMSS classes. */ public class WinternitzOTSVerify { private Digest messDigestOTS; /** * The Winternitz parameter */ private int w; /** * The constructor *

    * * @param digest the name of the hash function used by the OTS and the provider * name of the hash function * @param w the Winternitz parameter */ public WinternitzOTSVerify(Digest digest, int w) { this.w = w; messDigestOTS = digest; } /** * @return The length of the one-time signature */ public int getSignatureLength() { int mdsize = messDigestOTS.getDigestSize(); int size = ((mdsize << 3) + (w - 1)) / w; int logs = getLog((size << w) + 1); size += (logs + w - 1) / w; return mdsize * size; } /** * This method computes the public OTS key from the one-time signature of a * message. This is *NOT* a complete OTS signature verification, but it * suffices for usage with CMSS. * * @param message the message * @param signature the one-time signature * @return The public OTS key */ public byte[] Verify(byte[] message, byte[] signature) { int mdsize = messDigestOTS.getDigestSize(); byte[] hash = new byte[mdsize]; // hash of message m // create hash of message m messDigestOTS.update(message, 0, message.length); hash = new byte[messDigestOTS.getDigestSize()]; messDigestOTS.doFinal(hash, 0); int size = ((mdsize << 3) + (w - 1)) / w; int logs = getLog((size << w) + 1); int keysize = size + (logs + w - 1) / w; int testKeySize = mdsize * keysize; if (testKeySize != signature.length) { return null; } byte[] testKey = new byte[testKeySize]; int c = 0; int counter = 0; int test; if (8 % w == 0) { int d = 8 / w; int k = (1 << w) - 1; byte[] hlp = new byte[mdsize]; // verify signature for (int i = 0; i < hash.length; i++) { for (int j = 0; j < d; j++) { test = hash[i] & k; c += test; System.arraycopy(signature, counter * mdsize, hlp, 0, mdsize); while (test < k) { messDigestOTS.update(hlp, 0, hlp.length); hlp = new byte[messDigestOTS.getDigestSize()]; messDigestOTS.doFinal(hlp, 0); test++; } System.arraycopy(hlp, 0, testKey, counter * mdsize, mdsize); hash[i] = (byte)(hash[i] >>> w); counter++; } } c = (size << w) - c; for (int i = 0; i < logs; i += w) { test = c & k; System.arraycopy(signature, counter * mdsize, hlp, 0, mdsize); while (test < k) { messDigestOTS.update(hlp, 0, hlp.length); hlp = new byte[messDigestOTS.getDigestSize()]; messDigestOTS.doFinal(hlp, 0); test++; } System.arraycopy(hlp, 0, testKey, counter * mdsize, mdsize); c >>>= w; counter++; } } else if (w < 8) { int d = mdsize / w; int k = (1 << w) - 1; byte[] hlp = new byte[mdsize]; long big8; int ii = 0; // create signature // first d*w bytes of hash for (int i = 0; i < d; i++) { big8 = 0; for (int j = 0; j < w; j++) { big8 ^= (hash[ii] & 0xff) << (j << 3); ii++; } for (int j = 0; j < 8; j++) { test = (int)(big8 & k); c += test; System.arraycopy(signature, counter * mdsize, hlp, 0, mdsize); while (test < k) { messDigestOTS.update(hlp, 0, hlp.length); hlp = new byte[messDigestOTS.getDigestSize()]; messDigestOTS.doFinal(hlp, 0); test++; } System.arraycopy(hlp, 0, testKey, counter * mdsize, mdsize); big8 >>>= w; counter++; } } // rest of hash d = mdsize % w; big8 = 0; for (int j = 0; j < d; j++) { big8 ^= (hash[ii] & 0xff) << (j << 3); ii++; } d <<= 3; for (int j = 0; j < d; j += w) { test = (int)(big8 & k); c += test; System.arraycopy(signature, counter * mdsize, hlp, 0, mdsize); while (test < k) { messDigestOTS.update(hlp, 0, hlp.length); hlp = new byte[messDigestOTS.getDigestSize()]; messDigestOTS.doFinal(hlp, 0); test++; } System.arraycopy(hlp, 0, testKey, counter * mdsize, mdsize); big8 >>>= w; counter++; } // check bytes c = (size << w) - c; for (int i = 0; i < logs; i += w) { test = c & k; System.arraycopy(signature, counter * mdsize, hlp, 0, mdsize); while (test < k) { messDigestOTS.update(hlp, 0, hlp.length); hlp = new byte[messDigestOTS.getDigestSize()]; messDigestOTS.doFinal(hlp, 0); test++; } System.arraycopy(hlp, 0, testKey, counter * mdsize, mdsize); c >>>= w; counter++; } }// end if(w<8) else if (w < 57) { int d = (mdsize << 3) - w; int k = (1 << w) - 1; byte[] hlp = new byte[mdsize]; long big8, test8; int r = 0; int s, f, rest, ii; // create signature // first a*w bits of hash where a*w <= 8*mdsize < (a+1)*w while (r <= d) { s = r >>> 3; rest = r % 8; r += w; f = (r + 7) >>> 3; big8 = 0; ii = 0; for (int j = s; j < f; j++) { big8 ^= (hash[j] & 0xff) << (ii << 3); ii++; } big8 >>>= rest; test8 = (big8 & k); c += test8; System.arraycopy(signature, counter * mdsize, hlp, 0, mdsize); while (test8 < k) { messDigestOTS.update(hlp, 0, hlp.length); hlp = new byte[messDigestOTS.getDigestSize()]; messDigestOTS.doFinal(hlp, 0); test8++; } System.arraycopy(hlp, 0, testKey, counter * mdsize, mdsize); counter++; } // rest of hash s = r >>> 3; if (s < mdsize) { rest = r % 8; big8 = 0; ii = 0; for (int j = s; j < mdsize; j++) { big8 ^= (hash[j] & 0xff) << (ii << 3); ii++; } big8 >>>= rest; test8 = (big8 & k); c += test8; System.arraycopy(signature, counter * mdsize, hlp, 0, mdsize); while (test8 < k) { messDigestOTS.update(hlp, 0, hlp.length); hlp = new byte[messDigestOTS.getDigestSize()]; messDigestOTS.doFinal(hlp, 0); test8++; } System.arraycopy(hlp, 0, testKey, counter * mdsize, mdsize); counter++; } // check bytes c = (size << w) - c; for (int i = 0; i < logs; i += w) { test8 = (c & k); System.arraycopy(signature, counter * mdsize, hlp, 0, mdsize); while (test8 < k) { messDigestOTS.update(hlp, 0, hlp.length); hlp = new byte[messDigestOTS.getDigestSize()]; messDigestOTS.doFinal(hlp, 0); test8++; } System.arraycopy(hlp, 0, testKey, counter * mdsize, mdsize); c >>>= w; counter++; } }// end if(w<57) byte[] TKey = new byte[mdsize]; messDigestOTS.update(testKey, 0, testKey.length); TKey = new byte[messDigestOTS.getDigestSize()]; messDigestOTS.doFinal(TKey, 0); return TKey; } /** * This method returns the least integer that is greater or equal to the * logarithm to the base 2 of an integer intValue. * * @param intValue an integer * @return The least integer greater or equal to the logarithm to the base * 256 of intValue */ public int getLog(int intValue) { int log = 1; int i = 2; while (i < intValue) { i <<= 1; log++; } return log; } } bouncycastle-1.49.orig/src/org/bouncycastle/pqc/crypto/gmss/util/GMSSUtil.java0000644000175000017500000001013312151551720027002 0ustar ebourgebourgpackage org.bouncycastle.pqc.crypto.gmss.util; /** * This class provides several methods that are required by the GMSS classes. */ public class GMSSUtil { /** * Converts a 32 bit integer into a byte array beginning at * offset (little-endian representation) * * @param value the integer to convert */ public byte[] intToBytesLittleEndian(int value) { byte[] bytes = new byte[4]; bytes[0] = (byte)((value) & 0xff); bytes[1] = (byte)((value >> 8) & 0xff); bytes[2] = (byte)((value >> 16) & 0xff); bytes[3] = (byte)((value >> 24) & 0xff); return bytes; } /** * Converts a byte array beginning at offset into a 32 bit * integer (little-endian representation) * * @param bytes the byte array * @return The resulting integer */ public int bytesToIntLittleEndian(byte[] bytes) { return ((bytes[0] & 0xff)) | ((bytes[1] & 0xff) << 8) | ((bytes[2] & 0xff) << 16) | ((bytes[3] & 0xff)) << 24; } /** * Converts a byte array beginning at offset into a 32 bit * integer (little-endian representation) * * @param bytes the byte array * @param offset the integer offset into the byte array * @return The resulting integer */ public int bytesToIntLittleEndian(byte[] bytes, int offset) { return ((bytes[offset++] & 0xff)) | ((bytes[offset++] & 0xff) << 8) | ((bytes[offset++] & 0xff) << 16) | ((bytes[offset] & 0xff)) << 24; } /** * This method concatenates a 2-dimensional byte array into a 1-dimensional * byte array * * @param arraycp a 2-dimensional byte array. * @return 1-dimensional byte array with concatenated input array */ public byte[] concatenateArray(byte[][] arraycp) { byte[] dest = new byte[arraycp.length * arraycp[0].length]; int indx = 0; for (int i = 0; i < arraycp.length; i++) { System.arraycopy(arraycp[i], 0, dest, indx, arraycp[i].length); indx = indx + arraycp[i].length; } return dest; } /** * This method prints the values of a 2-dimensional byte array * * @param text a String * @param array a 2-dimensional byte array */ public void printArray(String text, byte[][] array) { System.out.println(text); int counter = 0; for (int i = 0; i < array.length; i++) { for (int j = 0; j < array[0].length; j++) { System.out.println(counter + "; " + array[i][j]); counter++; } } } /** * This method prints the values of a 1-dimensional byte array * * @param text a String * @param array a 1-dimensional byte array. */ public void printArray(String text, byte[] array) { System.out.println(text); int counter = 0; for (int i = 0; i < array.length; i++) { System.out.println(counter + "; " + array[i]); counter++; } } /** * This method tests if an integer is a power of 2. * * @param testValue an integer * @return TRUE if testValue is a power of 2, * FALSE otherwise */ public boolean testPowerOfTwo(int testValue) { int a = 1; while (a < testValue) { a <<= 1; } if (testValue == a) { return true; } return false; } /** * This method returns the least integer that is greater or equal to the * logarithm to the base 2 of an integer intValue. * * @param intValue an integer * @return The least integer greater or equal to the logarithm to the base 2 * of intValue */ public int getLog(int intValue) { int log = 1; int i = 2; while (i < intValue) { i <<= 1; log++; } return log; } } bouncycastle-1.49.orig/src/org/bouncycastle/pqc/crypto/gmss/util/GMSSRandom.java0000644000175000017500000000343412151551720027313 0ustar ebourgebourgpackage org.bouncycastle.pqc.crypto.gmss.util; import org.bouncycastle.crypto.Digest; /** * This class provides a PRNG for GMSS */ public class GMSSRandom { /** * Hash function for the construction of the authentication trees */ private Digest messDigestTree; /** * Constructor * * @param messDigestTree2 */ public GMSSRandom(Digest messDigestTree2) { this.messDigestTree = messDigestTree2; } /** * computes the next seed value, returns a random byte array and sets * outseed to the next value * * @param outseed byte array in which ((1 + SEEDin +RAND) mod 2^n) will be * stored * @return byte array of H(SEEDin) */ public byte[] nextSeed(byte[] outseed) { // RAND <-- H(SEEDin) byte[] rand = new byte[outseed.length]; messDigestTree.update(outseed, 0, outseed.length); rand = new byte[messDigestTree.getDigestSize()]; messDigestTree.doFinal(rand, 0); // SEEDout <-- (1 + SEEDin +RAND) mod 2^n addByteArrays(outseed, rand); addOne(outseed); // System.arraycopy(outseed, 0, outseed, 0, outseed.length); return rand; } private void addByteArrays(byte[] a, byte[] b) { byte overflow = 0; int temp; for (int i = 0; i < a.length; i++) { temp = (0xFF & a[i]) + (0xFF & b[i]) + overflow; a[i] = (byte)temp; overflow = (byte)(temp >> 8); } } private void addOne(byte[] a) { byte overflow = 1; int temp; for (int i = 0; i < a.length; i++) { temp = (0xFF & a[i]) + overflow; a[i] = (byte)temp; overflow = (byte)(temp >> 8); } } } bouncycastle-1.49.orig/src/org/bouncycastle/pqc/crypto/gmss/util/WinternitzOTSignature.java0000644000175000017500000003035712151551720031707 0ustar ebourgebourgpackage org.bouncycastle.pqc.crypto.gmss.util; import org.bouncycastle.crypto.Digest; /** * This class implements key pair generation and signature generation of the * Winternitz one-time signature scheme (OTSS), described in C.Dods, N.P. Smart, * and M. Stam, "Hash Based Digital Signature Schemes", LNCS 3796, pages * 96–115, 2005. The class is used by the GMSS classes. */ public class WinternitzOTSignature { /** * The hash function used by the OTS */ private Digest messDigestOTS; /** * The length of the message digest and private key */ private int mdsize, keysize; /** * An array of strings, containing the name of the used hash function, the * name of the PRGN and the names of the corresponding providers */ // private String[] name = new String[2]; /** * The private key */ private byte[][] privateKeyOTS; /** * The Winternitz parameter */ private int w; /** * The source of randomness for OTS private key generation */ private GMSSRandom gmssRandom; /** * Sizes of the message and the checksum, both */ private int messagesize, checksumsize; /** * The constructor generates an OTS key pair, using seed0 and * the PRNG *

    * * @param seed0 the seed for the PRGN * @param digest an array of strings, containing the name of the used hash * function, the name of the PRGN and the names of the * corresponding providers * @param w the Winternitz parameter */ public WinternitzOTSignature(byte[] seed0, Digest digest, int w) { // this.name = name; this.w = w; messDigestOTS = digest; gmssRandom = new GMSSRandom(messDigestOTS); // calulate keysize for private and public key and also the help // array mdsize = messDigestOTS.getDigestSize(); int mdsizeBit = mdsize << 3; messagesize = (int)Math.ceil((double)(mdsizeBit) / (double)w); checksumsize = getLog((messagesize << w) + 1); keysize = messagesize + (int)Math.ceil((double)checksumsize / (double)w); /* * mdsize = messDigestOTS.getDigestLength(); messagesize = * ((mdsize<<3)+(w-1))/w; * * checksumsize = getlog((messagesize< 0) { messDigestOTS.update(hlp, 0, hlp.length); hlp = new byte[messDigestOTS.getDigestSize()]; messDigestOTS.doFinal(hlp, 0); test--; } System.arraycopy(hlp, 0, sign, counter * mdsize, mdsize); hash[i] = (byte)(hash[i] >>> w); counter++; } } c = (messagesize << w) - c; for (int i = 0; i < checksumsize; i += w) { test = c & k; System.arraycopy(privateKeyOTS[counter], 0, hlp, 0, mdsize); while (test > 0) { messDigestOTS.update(hlp, 0, hlp.length); hlp = new byte[messDigestOTS.getDigestSize()]; messDigestOTS.doFinal(hlp, 0); test--; } System.arraycopy(hlp, 0, sign, counter * mdsize, mdsize); c >>>= w; counter++; } } else if (w < 8) { int d = mdsize / w; int k = (1 << w) - 1; byte[] hlp = new byte[mdsize]; long big8; int ii = 0; // create signature // first d*w bytes of hash for (int i = 0; i < d; i++) { big8 = 0; for (int j = 0; j < w; j++) { big8 ^= (hash[ii] & 0xff) << (j << 3); ii++; } for (int j = 0; j < 8; j++) { test = (int)(big8 & k); c += test; System.arraycopy(privateKeyOTS[counter], 0, hlp, 0, mdsize); while (test > 0) { messDigestOTS.update(hlp, 0, hlp.length); hlp = new byte[messDigestOTS.getDigestSize()]; messDigestOTS.doFinal(hlp, 0); test--; } System.arraycopy(hlp, 0, sign, counter * mdsize, mdsize); big8 >>>= w; counter++; } } // rest of hash d = mdsize % w; big8 = 0; for (int j = 0; j < d; j++) { big8 ^= (hash[ii] & 0xff) << (j << 3); ii++; } d <<= 3; for (int j = 0; j < d; j += w) { test = (int)(big8 & k); c += test; System.arraycopy(privateKeyOTS[counter], 0, hlp, 0, mdsize); while (test > 0) { messDigestOTS.update(hlp, 0, hlp.length); hlp = new byte[messDigestOTS.getDigestSize()]; messDigestOTS.doFinal(hlp, 0); test--; } System.arraycopy(hlp, 0, sign, counter * mdsize, mdsize); big8 >>>= w; counter++; } // check bytes c = (messagesize << w) - c; for (int i = 0; i < checksumsize; i += w) { test = c & k; System.arraycopy(privateKeyOTS[counter], 0, hlp, 0, mdsize); while (test > 0) { messDigestOTS.update(hlp, 0, hlp.length); hlp = new byte[messDigestOTS.getDigestSize()]; messDigestOTS.doFinal(hlp, 0); test--; } System.arraycopy(hlp, 0, sign, counter * mdsize, mdsize); c >>>= w; counter++; } }// end if(w<8) else if (w < 57) { int d = (mdsize << 3) - w; int k = (1 << w) - 1; byte[] hlp = new byte[mdsize]; long big8, test8; int r = 0; int s, f, rest, ii; // create signature // first a*w bits of hash where a*w <= 8*mdsize < (a+1)*w while (r <= d) { s = r >>> 3; rest = r % 8; r += w; f = (r + 7) >>> 3; big8 = 0; ii = 0; for (int j = s; j < f; j++) { big8 ^= (hash[j] & 0xff) << (ii << 3); ii++; } big8 >>>= rest; test8 = (big8 & k); c += test8; System.arraycopy(privateKeyOTS[counter], 0, hlp, 0, mdsize); while (test8 > 0) { messDigestOTS.update(hlp, 0, hlp.length); hlp = new byte[messDigestOTS.getDigestSize()]; messDigestOTS.doFinal(hlp, 0); test8--; } System.arraycopy(hlp, 0, sign, counter * mdsize, mdsize); counter++; } // rest of hash s = r >>> 3; if (s < mdsize) { rest = r % 8; big8 = 0; ii = 0; for (int j = s; j < mdsize; j++) { big8 ^= (hash[j] & 0xff) << (ii << 3); ii++; } big8 >>>= rest; test8 = (big8 & k); c += test8; System.arraycopy(privateKeyOTS[counter], 0, hlp, 0, mdsize); while (test8 > 0) { messDigestOTS.update(hlp, 0, hlp.length); hlp = new byte[messDigestOTS.getDigestSize()]; messDigestOTS.doFinal(hlp, 0); test8--; } System.arraycopy(hlp, 0, sign, counter * mdsize, mdsize); counter++; } // check bytes c = (messagesize << w) - c; for (int i = 0; i < checksumsize; i += w) { test8 = (c & k); System.arraycopy(privateKeyOTS[counter], 0, hlp, 0, mdsize); while (test8 > 0) { messDigestOTS.update(hlp, 0, hlp.length); hlp = new byte[messDigestOTS.getDigestSize()]; messDigestOTS.doFinal(hlp, 0); test8--; } System.arraycopy(hlp, 0, sign, counter * mdsize, mdsize); c >>>= w; counter++; } }// end if(w<57) return sign; } /** * This method returns the least integer that is greater or equal to the * logarithm to the base 2 of an integer intValue. * * @param intValue an integer * @return The least integer greater or equal to the logarithm to the base 2 * of intValue */ public int getLog(int intValue) { int log = 1; int i = 2; while (i < intValue) { i <<= 1; log++; } return log; } } bouncycastle-1.49.orig/src/org/bouncycastle/pqc/crypto/gmss/Treehash.java0000644000175000017500000003447112151551720026174 0ustar ebourgebourgpackage org.bouncycastle.pqc.crypto.gmss; import java.util.Vector; import org.bouncycastle.crypto.Digest; import org.bouncycastle.pqc.crypto.gmss.util.GMSSRandom; import org.bouncycastle.util.Integers; import org.bouncycastle.util.encoders.Hex; /** * This class implements a treehash instance for the Merkle tree traversal * algorithm. The first node of the stack is stored in this instance itself, * additional tail nodes are stored on a tailstack. */ public class Treehash { /** * max height of current treehash instance. */ private int maxHeight; /** * Vector element that stores the nodes on the stack */ private Vector tailStack; /** * Vector element that stores the height of the nodes on the stack */ private Vector heightOfNodes; /** * the first node is stored in the treehash instance itself, not on stack */ private byte[] firstNode; /** * seedActive needed for the actual node */ private byte[] seedActive; /** * the seed needed for the next re-initialization of the treehash instance */ private byte[] seedNext; /** * number of nodes stored on the stack and belonging to this treehash * instance */ private int tailLength; /** * the height in the tree of the first node stored in treehash */ private int firstNodeHeight; /** * true if treehash instance was already initialized, false otherwise */ private boolean isInitialized; /** * true if the first node's height equals the maxHeight of the treehash */ private boolean isFinished; /** * true if the nextSeed has been initialized with index 3*2^h needed for the * seed scheduling */ private boolean seedInitialized; /** * denotes the Message Digest used by the tree to create nodes */ private Digest messDigestTree; /** * This constructor regenerates a prior treehash object * * @param name an array of strings, containing the name of the used hash * function and PRNG and the name of the corresponding provider * @param statByte status bytes * @param statInt status ints */ public Treehash(Digest name, byte[][] statByte, int[] statInt) { this.messDigestTree = name; // decode statInt this.maxHeight = statInt[0]; this.tailLength = statInt[1]; this.firstNodeHeight = statInt[2]; if (statInt[3] == 1) { this.isFinished = true; } else { this.isFinished = false; } if (statInt[4] == 1) { this.isInitialized = true; } else { this.isInitialized = false; } if (statInt[5] == 1) { this.seedInitialized = true; } else { this.seedInitialized = false; } this.heightOfNodes = new Vector(); for (int i = 0; i < tailLength; i++) { this.heightOfNodes.addElement(Integers.valueOf(statInt[6 + i])); } // decode statByte this.firstNode = statByte[0]; this.seedActive = statByte[1]; this.seedNext = statByte[2]; this.tailStack = new Vector(); for (int i = 0; i < tailLength; i++) { this.tailStack.addElement(statByte[3 + i]); } } /** * Constructor * * @param tailStack a vector element where the stack nodes are stored * @param maxHeight maximal height of the treehash instance * @param digest an array of strings, containing the name of the used hash * function and PRNG and the name of the corresponding provider */ public Treehash(Vector tailStack, int maxHeight, Digest digest) { this.tailStack = tailStack; this.maxHeight = maxHeight; this.firstNode = null; this.isInitialized = false; this.isFinished = false; this.seedInitialized = false; this.messDigestTree = digest; this.seedNext = new byte[messDigestTree.getDigestSize()]; this.seedActive = new byte[messDigestTree.getDigestSize()]; } /** * Method to initialize the seeds needed for the precomputation of right * nodes. Should be initialized with index 3*2^i for treehash_i * * @param seedIn */ public void initializeSeed(byte[] seedIn) { System.arraycopy(seedIn, 0, this.seedNext, 0, this.messDigestTree .getDigestSize()); this.seedInitialized = true; } /** * initializes the treehash instance. The seeds must already have been * initialized to work correctly. */ public void initialize() { if (!this.seedInitialized) { System.err.println("Seed " + this.maxHeight + " not initialized"); return; } this.heightOfNodes = new Vector(); this.tailLength = 0; this.firstNode = null; this.firstNodeHeight = -1; this.isInitialized = true; System.arraycopy(this.seedNext, 0, this.seedActive, 0, messDigestTree .getDigestSize()); } /** * Calculates one update of the treehash instance, i.e. creates a new leaf * and hashes if possible * * @param gmssRandom an instance of the PRNG * @param leaf The byte value of the leaf needed for the update */ public void update(GMSSRandom gmssRandom, byte[] leaf) { if (this.isFinished) { System.err .println("No more update possible for treehash instance!"); return; } if (!this.isInitialized) { System.err .println("Treehash instance not initialized before update"); return; } byte[] help = new byte[this.messDigestTree.getDigestSize()]; int helpHeight = -1; gmssRandom.nextSeed(this.seedActive); // if treehash gets first update if (this.firstNode == null) { this.firstNode = leaf; this.firstNodeHeight = 0; } else { // store the new node in help array, do not push it on the stack help = leaf; helpHeight = 0; // hash the nodes on the stack if possible while (this.tailLength > 0 && helpHeight == ((Integer)heightOfNodes.lastElement()) .intValue()) { // put top element of the stack and help node in array // 'tobehashed' // and hash them together, put result again in help array byte[] toBeHashed = new byte[this.messDigestTree .getDigestSize() << 1]; // pop element from stack System.arraycopy(this.tailStack.lastElement(), 0, toBeHashed, 0, this.messDigestTree.getDigestSize()); this.tailStack.removeElementAt(this.tailStack.size() - 1); this.heightOfNodes .removeElementAt(this.heightOfNodes.size() - 1); System.arraycopy(help, 0, toBeHashed, this.messDigestTree .getDigestSize(), this.messDigestTree .getDigestSize()); messDigestTree.update(toBeHashed, 0, toBeHashed.length); help = new byte[messDigestTree.getDigestSize()]; messDigestTree.doFinal(help, 0); // increase help height, stack was reduced by one element helpHeight++; this.tailLength--; } // push the new node on the stack this.tailStack.addElement(help); this.heightOfNodes.addElement(Integers.valueOf(helpHeight)); this.tailLength++; // finally check whether the top node on stack and the first node // in treehash have same height. If so hash them together // and store them in treehash if (((Integer)heightOfNodes.lastElement()).intValue() == this.firstNodeHeight) { byte[] toBeHashed = new byte[this.messDigestTree .getDigestSize() << 1]; System.arraycopy(this.firstNode, 0, toBeHashed, 0, this.messDigestTree.getDigestSize()); // pop element from tailStack and copy it into help2 array System.arraycopy(this.tailStack.lastElement(), 0, toBeHashed, this.messDigestTree.getDigestSize(), this.messDigestTree.getDigestSize()); this.tailStack.removeElementAt(this.tailStack.size() - 1); this.heightOfNodes .removeElementAt(this.heightOfNodes.size() - 1); // store new element in firstNode, stack is then empty messDigestTree.update(toBeHashed, 0, toBeHashed.length); this.firstNode = new byte[messDigestTree.getDigestSize()]; messDigestTree.doFinal(this.firstNode, 0); this.firstNodeHeight++; // empty the stack this.tailLength = 0; } } // check if treehash instance is completed if (this.firstNodeHeight == this.maxHeight) { this.isFinished = true; } } /** * Destroys a treehash instance after the top node was taken for * authentication path. */ public void destroy() { this.isInitialized = false; this.isFinished = false; this.firstNode = null; this.tailLength = 0; this.firstNodeHeight = -1; } /** * Returns the height of the lowest node stored either in treehash or on the * stack. It must not be set to infinity (as mentioned in the paper) because * this cases are considered in the computeAuthPaths method of * JDKGMSSPrivateKey * * @return Height of the lowest node */ public int getLowestNodeHeight() { if (this.firstNode == null) { return this.maxHeight; } else if (this.tailLength == 0) { return this.firstNodeHeight; } else { return Math.min(this.firstNodeHeight, ((Integer)heightOfNodes .lastElement()).intValue()); } } /** * Returns the top node height * * @return Height of the first node, the top node */ public int getFirstNodeHeight() { if (firstNode == null) { return maxHeight; } return firstNodeHeight; } /** * Method to check whether the instance has been initialized or not * * @return true if treehash was already initialized */ public boolean wasInitialized() { return this.isInitialized; } /** * Method to check whether the instance has been finished or not * * @return true if treehash has reached its maximum height */ public boolean wasFinished() { return this.isFinished; } /** * returns the first node stored in treehash instance itself * * @return the first node stored in treehash instance itself */ public byte[] getFirstNode() { return this.firstNode; } /** * returns the active seed * * @return the active seed */ public byte[] getSeedActive() { return this.seedActive; } /** * This method sets the first node stored in the treehash instance itself * * @param hash */ public void setFirstNode(byte[] hash) { if (!this.isInitialized) { this.initialize(); } this.firstNode = hash; this.firstNodeHeight = this.maxHeight; this.isFinished = true; } /** * updates the nextSeed of this treehash instance one step needed for the * schedulng of the seeds * * @param gmssRandom the prng used for the seeds */ public void updateNextSeed(GMSSRandom gmssRandom) { gmssRandom.nextSeed(seedNext); } /** * Returns the tailstack * * @return the tailstack */ public Vector getTailStack() { return this.tailStack; } /** * Returns the status byte array used by the GMSSPrivateKeyASN.1 class * * @return The status bytes */ public byte[][] getStatByte() { byte[][] statByte = new byte[3 + tailLength][this.messDigestTree .getDigestSize()]; statByte[0] = firstNode; statByte[1] = seedActive; statByte[2] = seedNext; for (int i = 0; i < tailLength; i++) { statByte[3 + i] = (byte[])tailStack.elementAt(i); } return statByte; } /** * Returns the status int array used by the GMSSPrivateKeyASN.1 class * * @return The status ints */ public int[] getStatInt() { int[] statInt = new int[6 + tailLength]; statInt[0] = maxHeight; statInt[1] = tailLength; statInt[2] = firstNodeHeight; if (this.isFinished) { statInt[3] = 1; } else { statInt[3] = 0; } if (this.isInitialized) { statInt[4] = 1; } else { statInt[4] = 0; } if (this.seedInitialized) { statInt[5] = 1; } else { statInt[5] = 0; } for (int i = 0; i < tailLength; i++) { statInt[6 + i] = ((Integer)heightOfNodes.elementAt(i)).intValue(); } return statInt; } /** * returns a String representation of the treehash instance */ public String toString() { String out = "Treehash : "; for (int i = 0; i < 6 + tailLength; i++) { out = out + this.getStatInt()[i] + " "; } for (int i = 0; i < 3 + tailLength; i++) { if (this.getStatByte()[i] != null) { out = out + new String(Hex.encode((this.getStatByte()[i]))) + " "; } else { out = out + "null "; } } out = out + " " + this.messDigestTree.getDigestSize(); return out; } }bouncycastle-1.49.orig/src/org/bouncycastle/pqc/crypto/gmss/GMSSKeyParameters.java0000644000175000017500000000067511777164121027706 0ustar ebourgebourgpackage org.bouncycastle.pqc.crypto.gmss; import org.bouncycastle.crypto.params.AsymmetricKeyParameter; public class GMSSKeyParameters extends AsymmetricKeyParameter { private GMSSParameters params; public GMSSKeyParameters( boolean isPrivate, GMSSParameters params) { super(isPrivate); this.params = params; } public GMSSParameters getParameters() { return params; } }bouncycastle-1.49.orig/src/org/bouncycastle/pqc/crypto/gmss/GMSSRootSig.java0000644000175000017500000004662312151551720026513 0ustar ebourgebourgpackage org.bouncycastle.pqc.crypto.gmss; import org.bouncycastle.crypto.Digest; import org.bouncycastle.pqc.crypto.gmss.util.GMSSRandom; import org.bouncycastle.util.encoders.Hex; /** * This class implements the distributed signature generation of the Winternitz * one-time signature scheme (OTSS), described in C.Dods, N.P. Smart, and M. * Stam, "Hash Based Digital Signature Schemes", LNCS 3796, pages 96–115, * 2005. The class is used by the GMSS classes. */ public class GMSSRootSig { /** * The hash function used by the OTS */ private Digest messDigestOTS; /** * The length of the message digest and private key */ private int mdsize, keysize; /** * The private key */ private byte[] privateKeyOTS; /** * The message bytes */ private byte[] hash; /** * The signature bytes */ private byte[] sign; /** * The Winternitz parameter */ private int w; /** * The source of randomness for OTS private key generation */ private GMSSRandom gmssRandom; /** * Sizes of the message */ private int messagesize; /** * Some precalculated values */ private int k; /** * Some variables for storing the actual status of distributed signing */ private int r, test, counter, ii; /** * variables for storing big numbers for the actual status of distributed * signing */ private long test8, big8; /** * The necessary steps of each updateSign() call */ private int steps; /** * The checksum part */ private int checksum; /** * The height of the tree */ private int height; /** * The current intern OTSseed */ private byte[] seed; /** * This constructor regenerates a prior GMSSRootSig object used by the * GMSSPrivateKeyASN.1 class * * @param digest an array of strings, containing the digest of the used hash * function, the digest of the PRGN and the names of the * corresponding providers * @param statByte status byte array * @param statInt status int array */ public GMSSRootSig(Digest digest, byte[][] statByte, int[] statInt) { messDigestOTS = digest; gmssRandom = new GMSSRandom(messDigestOTS); this.counter = statInt[0]; this.test = statInt[1]; this.ii = statInt[2]; this.r = statInt[3]; this.steps = statInt[4]; this.keysize = statInt[5]; this.height = statInt[6]; this.w = statInt[7]; this.checksum = statInt[8]; this.mdsize = messDigestOTS.getDigestSize(); this.k = (1 << w) - 1; int mdsizeBit = mdsize << 3; this.messagesize = (int)Math.ceil((double)(mdsizeBit) / (double)w); this.privateKeyOTS = statByte[0]; this.seed = statByte[1]; this.hash = statByte[2]; this.sign = statByte[3]; this.test8 = ((statByte[4][0] & 0xff)) | ((long)(statByte[4][1] & 0xff) << 8) | ((long)(statByte[4][2] & 0xff) << 16) | ((long)(statByte[4][3] & 0xff)) << 24 | ((long)(statByte[4][4] & 0xff)) << 32 | ((long)(statByte[4][5] & 0xff)) << 40 | ((long)(statByte[4][6] & 0xff)) << 48 | ((long)(statByte[4][7] & 0xff)) << 56; this.big8 = ((statByte[4][8] & 0xff)) | ((long)(statByte[4][9] & 0xff) << 8) | ((long)(statByte[4][10] & 0xff) << 16) | ((long)(statByte[4][11] & 0xff)) << 24 | ((long)(statByte[4][12] & 0xff)) << 32 | ((long)(statByte[4][13] & 0xff)) << 40 | ((long)(statByte[4][14] & 0xff)) << 48 | ((long)(statByte[4][15] & 0xff)) << 56; } /** * The constructor generates the PRNG and initializes some variables * * @param digest an array of strings, containing the digest of the used hash * function, the digest of the PRGN and the names of the * corresponding providers * @param w the winternitz parameter * @param height the heigth of the tree */ public GMSSRootSig(Digest digest, int w, int height) { messDigestOTS = digest; gmssRandom = new GMSSRandom(messDigestOTS); this.mdsize = messDigestOTS.getDigestSize(); this.w = w; this.height = height; this.k = (1 << w) - 1; int mdsizeBit = mdsize << 3; this.messagesize = (int)Math.ceil((double)(mdsizeBit) / (double)w); } /** * This method initializes the distributed sigature calculation. Variables * are reseted and necessary steps are calculated * * @param seed0 the initial OTSseed * @param message the massage which will be signed */ public void initSign(byte[] seed0, byte[] message) { // create hash of message m this.hash = new byte[mdsize]; messDigestOTS.update(message, 0, message.length); this.hash = new byte[messDigestOTS.getDigestSize()]; messDigestOTS.doFinal(this.hash, 0); // variables for calculation of steps byte[] messPart = new byte[mdsize]; System.arraycopy(hash, 0, messPart, 0, mdsize); int checkPart = 0; int sumH = 0; int checksumsize = getLog((messagesize << w) + 1); // ------- calculation of necessary steps ------ if (8 % w == 0) { int dt = 8 / w; // message part for (int a = 0; a < mdsize; a++) { // count necessary hashs in 'sumH' for (int b = 0; b < dt; b++) { sumH += messPart[a] & k; messPart[a] = (byte)(messPart[a] >>> w); } } // checksum part this.checksum = (messagesize << w) - sumH; checkPart = checksum; // count necessary hashs in 'sumH' for (int b = 0; b < checksumsize; b += w) { sumH += checkPart & k; checkPart >>>= w; } } // end if ( 8 % w == 0 ) else if (w < 8) { long big8; int ii = 0; int dt = mdsize / w; // first d*w bytes of hash (main message part) for (int i = 0; i < dt; i++) { big8 = 0; for (int j = 0; j < w; j++) { big8 ^= (messPart[ii] & 0xff) << (j << 3); ii++; } // count necessary hashs in 'sumH' for (int j = 0; j < 8; j++) { sumH += (int)(big8 & k); big8 >>>= w; } } // rest of message part dt = mdsize % w; big8 = 0; for (int j = 0; j < dt; j++) { big8 ^= (messPart[ii] & 0xff) << (j << 3); ii++; } dt <<= 3; // count necessary hashs in 'sumH' for (int j = 0; j < dt; j += w) { sumH += (int)(big8 & k); big8 >>>= w; } // checksum part this.checksum = (messagesize << w) - sumH; checkPart = checksum; // count necessary hashs in 'sumH' for (int i = 0; i < checksumsize; i += w) { sumH += checkPart & k; checkPart >>>= w; } }// end if(w<8) else if (w < 57) { long big8; int r = 0; int s, f, rest, ii; // first a*w bits of hash where a*w <= 8*mdsize < (a+1)*w (main // message part) while (r <= ((mdsize << 3) - w)) { s = r >>> 3; rest = r % 8; r += w; f = (r + 7) >>> 3; big8 = 0; ii = 0; for (int j = s; j < f; j++) { big8 ^= (messPart[j] & 0xff) << (ii << 3); ii++; } big8 >>>= rest; // count necessary hashs in 'sumH' sumH += (big8 & k); } // rest of message part s = r >>> 3; if (s < mdsize) { rest = r % 8; big8 = 0; ii = 0; for (int j = s; j < mdsize; j++) { big8 ^= (messPart[j] & 0xff) << (ii << 3); ii++; } big8 >>>= rest; // count necessary hashs in 'sumH' sumH += (big8 & k); } // checksum part this.checksum = (messagesize << w) - sumH; checkPart = checksum; // count necessary hashs in 'sumH' for (int i = 0; i < checksumsize; i += w) { sumH += (checkPart & k); checkPart >>>= w; } }// end if(w<57) // calculate keysize this.keysize = messagesize + (int)Math.ceil((double)checksumsize / (double)w); // calculate steps: 'keysize' times PRNG, 'sumH' times hashing, // (1<steps steps of distributed signature * calculaion * * @return true if signature is generated completly, else false */ public boolean updateSign() { // steps times do for (int s = 0; s < steps; s++) { // do 'step' times if (counter < keysize) { // generate the private key or perform // the next hash oneStep(); } if (counter == keysize) {// finish return true; } } return false; // leaf not finished yet } /** * @return The private OTS key */ public byte[] getSig() { return sign; } /** * @return The one-time signature of the message, generated step by step */ private void oneStep() { // -------- if (8 % w == 0) ---------- if (8 % w == 0) { if (test == 0) { // get current OTSprivateKey this.privateKeyOTS = gmssRandom.nextSeed(seed); // System.arraycopy(privateKeyOTS, 0, hlp, 0, mdsize); if (ii < mdsize) { // for main message part test = hash[ii] & k; hash[ii] = (byte)(hash[ii] >>> w); } else { // for checksum part test = checksum & k; checksum >>>= w; } } else if (test > 0) { // hash the private Key 'test' times (on // time each step) messDigestOTS.update(privateKeyOTS, 0, privateKeyOTS.length); privateKeyOTS = new byte[messDigestOTS.getDigestSize()]; messDigestOTS.doFinal(privateKeyOTS, 0); test--; } if (test == 0) { // if all hashes done copy result to siganture // array System.arraycopy(privateKeyOTS, 0, sign, counter * mdsize, mdsize); counter++; if (counter % (8 / w) == 0) { // raise array index for main // massage part ii++; } } }// ----- end if (8 % w == 0) ----- // ---------- if ( w < 8 ) ---------------- else if (w < 8) { if (test == 0) { if (counter % 8 == 0 && ii < mdsize) { // after every 8th "add // to signature"-step big8 = 0; if (counter < ((mdsize / w) << 3)) {// main massage // (generate w*8 Bits // every time) part for (int j = 0; j < w; j++) { big8 ^= (hash[ii] & 0xff) << (j << 3); ii++; } } else { // rest of massage part (once) for (int j = 0; j < mdsize % w; j++) { big8 ^= (hash[ii] & 0xff) << (j << 3); ii++; } } } if (counter == messagesize) { // checksum part (once) big8 = checksum; } test = (int)(big8 & k); // generate current OTSprivateKey this.privateKeyOTS = gmssRandom.nextSeed(seed); // System.arraycopy(privateKeyOTS, 0, hlp, 0, mdsize); } else if (test > 0) { // hash the private Key 'test' times (on // time each step) messDigestOTS.update(privateKeyOTS, 0, privateKeyOTS.length); privateKeyOTS = new byte[messDigestOTS.getDigestSize()]; messDigestOTS.doFinal(privateKeyOTS, 0); test--; } if (test == 0) { // if all hashes done copy result to siganture // array System.arraycopy(privateKeyOTS, 0, sign, counter * mdsize, mdsize); big8 >>>= w; counter++; } }// ------- end if(w<8)-------------------------------- // --------- if w < 57 ----------------------------- else if (w < 57) { if (test8 == 0) { int s, f, rest; big8 = 0; ii = 0; rest = r % 8; s = r >>> 3; // --- message part--- if (s < mdsize) { if (r <= ((mdsize << 3) - w)) { // first message part r += w; f = (r + 7) >>> 3; } else { // rest of message part (once) f = mdsize; r += w; } // generate long 'big8' with minimum w next bits of the // message array for (int i = s; i < f; i++) { big8 ^= (hash[i] & 0xff) << (ii << 3); ii++; } // delete bits on the right side, which were used already by // the last loop big8 >>>= rest; test8 = (big8 & k); } // --- checksum part else { test8 = (checksum & k); checksum >>>= w; } // generate current OTSprivateKey this.privateKeyOTS = gmssRandom.nextSeed(seed); // System.arraycopy(privateKeyOTS, 0, hlp, 0, mdsize); } else if (test8 > 0) { // hash the private Key 'test' times (on // time each step) messDigestOTS.update(privateKeyOTS, 0, privateKeyOTS.length); privateKeyOTS = new byte[messDigestOTS.getDigestSize()]; messDigestOTS.doFinal(privateKeyOTS, 0); test8--; } if (test8 == 0) { // if all hashes done copy result to siganture // array System.arraycopy(privateKeyOTS, 0, sign, counter * mdsize, mdsize); counter++; } } } /** * This method returns the least integer that is greater or equal to the * logarithm to the base 2 of an integer intValue. * * @param intValue an integer * @return The least integer greater or equal to the logarithm to the base 2 * of intValue */ public int getLog(int intValue) { int log = 1; int i = 2; while (i < intValue) { i <<= 1; log++; } return log; } /** * This method returns the status byte array * * @return statBytes */ public byte[][] getStatByte() { byte[][] statByte = new byte[5][mdsize]; statByte[0] = privateKeyOTS; statByte[1] = seed; statByte[2] = hash; statByte[3] = sign; statByte[4] = this.getStatLong(); return statByte; } /** * This method returns the status int array * * @return statInt */ public int[] getStatInt() { int[] statInt = new int[9]; statInt[0] = counter; statInt[1] = test; statInt[2] = ii; statInt[3] = r; statInt[4] = steps; statInt[5] = keysize; statInt[6] = height; statInt[7] = w; statInt[8] = checksum; return statInt; } /** * Converts the long parameters into byte arrays to store it in * statByte-Array */ public byte[] getStatLong() { byte[] bytes = new byte[16]; bytes[0] = (byte)((test8) & 0xff); bytes[1] = (byte)((test8 >> 8) & 0xff); bytes[2] = (byte)((test8 >> 16) & 0xff); bytes[3] = (byte)((test8 >> 24) & 0xff); bytes[4] = (byte)((test8) >> 32 & 0xff); bytes[5] = (byte)((test8 >> 40) & 0xff); bytes[6] = (byte)((test8 >> 48) & 0xff); bytes[7] = (byte)((test8 >> 56) & 0xff); bytes[8] = (byte)((big8) & 0xff); bytes[9] = (byte)((big8 >> 8) & 0xff); bytes[10] = (byte)((big8 >> 16) & 0xff); bytes[11] = (byte)((big8 >> 24) & 0xff); bytes[12] = (byte)((big8) >> 32 & 0xff); bytes[13] = (byte)((big8 >> 40) & 0xff); bytes[14] = (byte)((big8 >> 48) & 0xff); bytes[15] = (byte)((big8 >> 56) & 0xff); return bytes; } /** * returns a string representation of the instance * * @return a string representation of the instance */ public String toString() { String out = "" + this.big8 + " "; int[] statInt = new int[9]; statInt = this.getStatInt(); byte[][] statByte = new byte[5][mdsize]; statByte = this.getStatByte(); for (int i = 0; i < 9; i++) { out = out + statInt[i] + " "; } for (int i = 0; i < 5; i++) { out = out + new String(Hex.encode(statByte[i])) + " "; } return out; } } bouncycastle-1.49.orig/src/org/bouncycastle/pqc/crypto/gmss/GMSSSigner.java0000644000175000017500000003127412121455232026346 0ustar ebourgebourgpackage org.bouncycastle.pqc.crypto.gmss; import java.security.SecureRandom; import org.bouncycastle.crypto.CipherParameters; import org.bouncycastle.crypto.Digest; import org.bouncycastle.crypto.params.ParametersWithRandom; import org.bouncycastle.pqc.crypto.MessageSigner; import org.bouncycastle.pqc.crypto.gmss.util.GMSSRandom; import org.bouncycastle.pqc.crypto.gmss.util.GMSSUtil; import org.bouncycastle.pqc.crypto.gmss.util.WinternitzOTSVerify; import org.bouncycastle.pqc.crypto.gmss.util.WinternitzOTSignature; import org.bouncycastle.util.Arrays; /** * This class implements the GMSS signature scheme. */ public class GMSSSigner implements MessageSigner { /** * Instance of GMSSParameterSpec */ //private GMSSParameterSpec gmssParameterSpec; /** * Instance of GMSSUtilities */ private GMSSUtil gmssUtil = new GMSSUtil(); /** * The raw GMSS public key */ private byte[] pubKeyBytes; /** * Hash function for the construction of the authentication trees */ private Digest messDigestTrees; /** * The length of the hash function output */ private int mdLength; /** * The number of tree layers */ private int numLayer; /** * The hash function used by the OTS */ private Digest messDigestOTS; /** * An instance of the Winternitz one-time signature */ private WinternitzOTSignature ots; /** * Array of strings containing the name of the hash function used by the OTS * and the corresponding provider name */ private GMSSDigestProvider digestProvider; /** * The current main tree and subtree indices */ private int[] index; /** * Array of the authentication paths for the current trees of all layers */ private byte[][][] currentAuthPaths; /** * The one-time signature of the roots of the current subtrees */ private byte[][] subtreeRootSig; /** * The GMSSParameterset */ private GMSSParameters gmssPS; /** * The PRNG */ private GMSSRandom gmssRandom; GMSSKeyParameters key; // XXX needed? Source of randomness private SecureRandom random; /** * The standard constructor tries to generate the MerkleTree Algorithm * identifier with the corresponding OID. * * @param digest the digest to use */ // TODO public GMSSSigner(GMSSDigestProvider digest) { digestProvider = digest; messDigestTrees = digest.get(); messDigestOTS = messDigestTrees; mdLength = messDigestTrees.getDigestSize(); gmssRandom = new GMSSRandom(messDigestTrees); } public void init(boolean forSigning, CipherParameters param) { if (forSigning) { if (param instanceof ParametersWithRandom) { ParametersWithRandom rParam = (ParametersWithRandom)param; // XXX random needed? this.random = rParam.getRandom(); this.key = (GMSSPrivateKeyParameters)rParam.getParameters(); initSign(); } else { this.random = new SecureRandom(); this.key = (GMSSPrivateKeyParameters)param; initSign(); } } else { this.key = (GMSSPublicKeyParameters)param; initVerify(); } } /** * Initializes the signature algorithm for signing a message. */ private void initSign() { messDigestTrees.reset(); // set private key and take from it ots key, auth, tree and key // counter, rootSign GMSSPrivateKeyParameters gmssPrivateKey = (GMSSPrivateKeyParameters)key; if (gmssPrivateKey.isUsed()) { throw new IllegalStateException("Private key already used"); } // check if last signature has been generated if (gmssPrivateKey.getIndex(0) >= gmssPrivateKey.getNumLeafs(0)) { throw new IllegalStateException("No more signatures can be generated"); } // get Parameterset this.gmssPS = gmssPrivateKey.getParameters(); // get numLayer this.numLayer = gmssPS.getNumOfLayers(); // get OTS Instance of lowest layer byte[] seed = gmssPrivateKey.getCurrentSeeds()[numLayer - 1]; byte[] OTSSeed = new byte[mdLength]; byte[] dummy = new byte[mdLength]; System.arraycopy(seed, 0, dummy, 0, mdLength); OTSSeed = gmssRandom.nextSeed(dummy); // secureRandom.nextBytes(currentSeeds[currentSeeds.length-1]);secureRandom.nextBytes(OTSseed); this.ots = new WinternitzOTSignature(OTSSeed, digestProvider.get(), gmssPS.getWinternitzParameter()[numLayer - 1]); byte[][][] helpCurrentAuthPaths = gmssPrivateKey.getCurrentAuthPaths(); currentAuthPaths = new byte[numLayer][][]; // copy the main tree authentication path for (int j = 0; j < numLayer; j++) { currentAuthPaths[j] = new byte[helpCurrentAuthPaths[j].length][mdLength]; for (int i = 0; i < helpCurrentAuthPaths[j].length; i++) { System.arraycopy(helpCurrentAuthPaths[j][i], 0, currentAuthPaths[j][i], 0, mdLength); } } // copy index index = new int[numLayer]; System.arraycopy(gmssPrivateKey.getIndex(), 0, index, 0, numLayer); // copy subtreeRootSig byte[] helpSubtreeRootSig; subtreeRootSig = new byte[numLayer - 1][]; for (int i = 0; i < numLayer - 1; i++) { helpSubtreeRootSig = gmssPrivateKey.getSubtreeRootSig(i); subtreeRootSig[i] = new byte[helpSubtreeRootSig.length]; System.arraycopy(helpSubtreeRootSig, 0, subtreeRootSig[i], 0, helpSubtreeRootSig.length); } gmssPrivateKey.markUsed(); } /** * Signs a message. *

    * * @return the signature. */ public byte[] generateSignature(byte[] message) { byte[] otsSig = new byte[mdLength]; byte[] authPathBytes; byte[] indexBytes; otsSig = ots.getSignature(message); // get concatenated lowest layer tree authentication path authPathBytes = gmssUtil.concatenateArray(currentAuthPaths[numLayer - 1]); // put lowest layer index into a byte array indexBytes = gmssUtil.intToBytesLittleEndian(index[numLayer - 1]); // create first part of GMSS signature byte[] gmssSigFirstPart = new byte[indexBytes.length + otsSig.length + authPathBytes.length]; System.arraycopy(indexBytes, 0, gmssSigFirstPart, 0, indexBytes.length); System.arraycopy(otsSig, 0, gmssSigFirstPart, indexBytes.length, otsSig.length); System.arraycopy(authPathBytes, 0, gmssSigFirstPart, (indexBytes.length + otsSig.length), authPathBytes.length); // --- end first part // --- next parts of the signature // create initial array with length 0 for iteration byte[] gmssSigNextPart = new byte[0]; for (int i = numLayer - 1 - 1; i >= 0; i--) { // get concatenated next tree authentication path authPathBytes = gmssUtil.concatenateArray(currentAuthPaths[i]); // put next tree index into a byte array indexBytes = gmssUtil.intToBytesLittleEndian(index[i]); // create next part of GMSS signature // create help array and copy actual gmssSig into it byte[] helpGmssSig = new byte[gmssSigNextPart.length]; System.arraycopy(gmssSigNextPart, 0, helpGmssSig, 0, gmssSigNextPart.length); // adjust length of gmssSigNextPart for adding next part gmssSigNextPart = new byte[helpGmssSig.length + indexBytes.length + subtreeRootSig[i].length + authPathBytes.length]; // copy old data (help array) and new data in gmssSigNextPart System.arraycopy(helpGmssSig, 0, gmssSigNextPart, 0, helpGmssSig.length); System.arraycopy(indexBytes, 0, gmssSigNextPart, helpGmssSig.length, indexBytes.length); System.arraycopy(subtreeRootSig[i], 0, gmssSigNextPart, (helpGmssSig.length + indexBytes.length), subtreeRootSig[i].length); System.arraycopy(authPathBytes, 0, gmssSigNextPart, (helpGmssSig.length + indexBytes.length + subtreeRootSig[i].length), authPathBytes.length); } // --- end next parts // concatenate the two parts of the GMSS signature byte[] gmssSig = new byte[gmssSigFirstPart.length + gmssSigNextPart.length]; System.arraycopy(gmssSigFirstPart, 0, gmssSig, 0, gmssSigFirstPart.length); System.arraycopy(gmssSigNextPart, 0, gmssSig, gmssSigFirstPart.length, gmssSigNextPart.length); // return the GMSS signature return gmssSig; } /** * Initializes the signature algorithm for verifying a signature. */ private void initVerify() { messDigestTrees.reset(); GMSSPublicKeyParameters gmssPublicKey = (GMSSPublicKeyParameters)key; pubKeyBytes = gmssPublicKey.getPublicKey(); gmssPS = gmssPublicKey.getParameters(); // get numLayer this.numLayer = gmssPS.getNumOfLayers(); } /** * This function verifies the signature of the message that has been * updated, with the aid of the public key. * * @param message the message * @param signature the signature associated with the message * @return true if the signature has been verified, false otherwise. */ public boolean verifySignature(byte[] message, byte[] signature) { boolean success = false; // int halfSigLength = signature.length >>> 1; messDigestOTS.reset(); WinternitzOTSVerify otsVerify; int otsSigLength; byte[] help = message; byte[] otsSig; byte[] otsPublicKey; byte[][] authPath; byte[] dest; int nextEntry = 0; int index; // Verify signature // --- begin with message = 'message that was signed' // and then in each step message = subtree root for (int j = numLayer - 1; j >= 0; j--) { otsVerify = new WinternitzOTSVerify(digestProvider.get(), gmssPS.getWinternitzParameter()[j]); otsSigLength = otsVerify.getSignatureLength(); message = help; // get the subtree index index = gmssUtil.bytesToIntLittleEndian(signature, nextEntry); // 4 is the number of bytes in integer nextEntry += 4; // get one-time signature otsSig = new byte[otsSigLength]; System.arraycopy(signature, nextEntry, otsSig, 0, otsSigLength); nextEntry += otsSigLength; // compute public OTS key from the one-time signature otsPublicKey = otsVerify.Verify(message, otsSig); // test if OTSsignature is correct if (otsPublicKey == null) { System.err.println("OTS Public Key is null in GMSSSignature.verify"); return false; } // get authentication path from the signature authPath = new byte[gmssPS.getHeightOfTrees()[j]][mdLength]; for (int i = 0; i < authPath.length; i++) { System.arraycopy(signature, nextEntry, authPath[i], 0, mdLength); nextEntry = nextEntry + mdLength; } // compute the root of the subtree from the authentication path help = new byte[mdLength]; help = otsPublicKey; int count = 1 << authPath.length; count = count + index; for (int i = 0; i < authPath.length; i++) { dest = new byte[mdLength << 1]; if ((count % 2) == 0) { System.arraycopy(help, 0, dest, 0, mdLength); System.arraycopy(authPath[i], 0, dest, mdLength, mdLength); count = count / 2; } else { System.arraycopy(authPath[i], 0, dest, 0, mdLength); System.arraycopy(help, 0, dest, mdLength, help.length); count = (count - 1) / 2; } messDigestTrees.update(dest, 0, dest.length); help = new byte[messDigestTrees.getDigestSize()]; messDigestTrees.doFinal(help, 0); } } // now help contains the root of the maintree // test if help is equal to the GMSS public key if (Arrays.areEqual(pubKeyBytes, help)) { success = true; } return success; } }bouncycastle-1.49.orig/src/org/bouncycastle/pqc/crypto/gmss/GMSSParameters.java0000644000175000017500000001064412151551720027222 0ustar ebourgebourgpackage org.bouncycastle.pqc.crypto.gmss; import org.bouncycastle.util.Arrays; /** * This class provides a specification for the GMSS parameters that are used by * the GMSSKeyPairGenerator and GMSSSignature classes. * * @see org.bouncycastle.pqc.crypto.gmss.GMSSKeyPairGenerator */ public class GMSSParameters { /** * The number of authentication tree layers. */ private int numOfLayers; /** * The height of the authentication trees of each layer. */ private int[] heightOfTrees; /** * The Winternitz Parameter 'w' of each layer. */ private int[] winternitzParameter; /** * The parameter K needed for the authentication path computation */ private int[] K; /** * The constructor for the parameters of the GMSSKeyPairGenerator. *

    * * @param layers the number of authentication tree layers * @param heightOfTrees the height of the authentication trees * @param winternitzParameter the Winternitz Parameter 'w' of each layer * @param K parameter for authpath computation */ public GMSSParameters(int layers, int[] heightOfTrees, int[] winternitzParameter, int[] K) throws IllegalArgumentException { init(layers, heightOfTrees, winternitzParameter, K); } private void init(int layers, int[] heightOfTrees, int[] winternitzParameter, int[] K) throws IllegalArgumentException { boolean valid = true; String errMsg = ""; this.numOfLayers = layers; if ((numOfLayers != winternitzParameter.length) || (numOfLayers != heightOfTrees.length) || (numOfLayers != K.length)) { valid = false; errMsg = "Unexpected parameterset format"; } for (int i = 0; i < numOfLayers; i++) { if ((K[i] < 2) || ((heightOfTrees[i] - K[i]) % 2 != 0)) { valid = false; errMsg = "Wrong parameter K (K >= 2 and H-K even required)!"; } if ((heightOfTrees[i] < 4) || (winternitzParameter[i] < 2)) { valid = false; errMsg = "Wrong parameter H or w (H > 3 and w > 1 required)!"; } } if (valid) { this.heightOfTrees = Arrays.clone(heightOfTrees); this.winternitzParameter = Arrays.clone(winternitzParameter); this.K = Arrays.clone(K); } else { throw new IllegalArgumentException(errMsg); } } public GMSSParameters(int keySize) throws IllegalArgumentException { if (keySize <= 10) { // create 2^10 keys int[] defh = {10}; int[] defw = {3}; int[] defk = {2}; this.init(defh.length, defh, defw, defk); } else if (keySize <= 20) { // create 2^20 keys int[] defh = {10, 10}; int[] defw = {5, 4}; int[] defk = {2, 2}; this.init(defh.length, defh, defw, defk); } else { // create 2^40 keys, keygen lasts around 80 seconds int[] defh = {10, 10, 10, 10}; int[] defw = {9, 9, 9, 3}; int[] defk = {2, 2, 2, 2}; this.init(defh.length, defh, defw, defk); } } /** * Returns the number of levels of the authentication trees. * * @return The number of levels of the authentication trees. */ public int getNumOfLayers() { return numOfLayers; } /** * Returns the array of height (for each layer) of the authentication trees * * @return The array of height (for each layer) of the authentication trees */ public int[] getHeightOfTrees() { return Arrays.clone(heightOfTrees); } /** * Returns the array of WinternitzParameter (for each layer) of the * authentication trees * * @return The array of WinternitzParameter (for each layer) of the * authentication trees */ public int[] getWinternitzParameter() { return Arrays.clone(winternitzParameter); } /** * Returns the parameter K needed for authentication path computation * * @return The parameter K needed for authentication path computation */ public int[] getK() { return Arrays.clone(K); } } bouncycastle-1.49.orig/src/org/bouncycastle/pqc/crypto/gmss/GMSSRootCalc.java0000644000175000017500000004024512151551720026625 0ustar ebourgebourgpackage org.bouncycastle.pqc.crypto.gmss; import java.util.Enumeration; import java.util.Vector; import org.bouncycastle.crypto.Digest; import org.bouncycastle.util.Arrays; import org.bouncycastle.util.Integers; import org.bouncycastle.util.encoders.Hex; /** * This class computes a whole Merkle tree and saves the needed values for * AuthPath computation. It is used for precomputation of the root of a * following tree. After initialization, 2^H updates are required to complete * the root. Every update requires one leaf value as parameter. While computing * the root all initial values for the authentication path algorithm (treehash, * auth, retain) are stored for later use. */ public class GMSSRootCalc { /** * max height of the tree */ private int heightOfTree; /** * length of the messageDigest */ private int mdLength; /** * the treehash instances of the tree */ private Treehash[] treehash; /** * stores the retain nodes for authPath computation */ private Vector[] retain; /** * finally stores the root of the tree when finished */ private byte[] root; /** * stores the authentication path y_1(i), i = 0..H-1 */ private byte[][] AuthPath; /** * the value K for the authentication path computation */ private int K; /** * Vector element that stores the nodes on the stack */ private Vector tailStack; /** * stores the height of all nodes laying on the tailStack */ private Vector heightOfNodes; /** * The hash function used for the construction of the authentication trees */ private Digest messDigestTree; /** * An array of strings containing the name of the hash function used to * construct the authentication trees and used by the OTS. */ private GMSSDigestProvider digestProvider; /** * stores the index of the current node on each height of the tree */ private int[] index; /** * true if instance was already initialized, false otherwise */ private boolean isInitialized; /** * true it instance was finished */ private boolean isFinished; /** * Integer that stores the index of the next seed that has to be omitted to * the treehashs */ private int indexForNextSeed; /** * temporary integer that stores the height of the next treehash instance * that gets initialized with a seed */ private int heightOfNextSeed; /** * This constructor regenerates a prior treehash object * * @param digest an array of strings, containing the digest of the used hash * function and PRNG and the digest of the corresponding * provider * @param statByte status bytes * @param statInt status ints */ public GMSSRootCalc(Digest digest, byte[][] statByte, int[] statInt, Treehash[] treeH, Vector[] ret) { this.messDigestTree = digestProvider.get(); this.digestProvider = digestProvider; // decode statInt this.heightOfTree = statInt[0]; this.mdLength = statInt[1]; this.K = statInt[2]; this.indexForNextSeed = statInt[3]; this.heightOfNextSeed = statInt[4]; if (statInt[5] == 1) { this.isFinished = true; } else { this.isFinished = false; } if (statInt[6] == 1) { this.isInitialized = true; } else { this.isInitialized = false; } int tailLength = statInt[7]; this.index = new int[heightOfTree]; for (int i = 0; i < heightOfTree; i++) { this.index[i] = statInt[8 + i]; } this.heightOfNodes = new Vector(); for (int i = 0; i < tailLength; i++) { this.heightOfNodes.addElement(Integers.valueOf(statInt[8 + heightOfTree + i])); } // decode statByte this.root = statByte[0]; this.AuthPath = new byte[heightOfTree][mdLength]; for (int i = 0; i < heightOfTree; i++) { this.AuthPath[i] = statByte[1 + i]; } this.tailStack = new Vector(); for (int i = 0; i < tailLength; i++) { this.tailStack.addElement(statByte[1 + heightOfTree + i]); } // decode treeH this.treehash = GMSSUtils.clone(treeH); // decode ret this.retain = GMSSUtils.clone(ret); } /** * Constructor * * @param heightOfTree maximal height of the tree * @param digestProvider an array of strings, containing the name of the used hash * function and PRNG and the name of the corresponding * provider */ public GMSSRootCalc(int heightOfTree, int K, GMSSDigestProvider digestProvider) { this.heightOfTree = heightOfTree; this.digestProvider = digestProvider; this.messDigestTree = digestProvider.get(); this.mdLength = messDigestTree.getDigestSize(); this.K = K; this.index = new int[heightOfTree]; this.AuthPath = new byte[heightOfTree][mdLength]; this.root = new byte[mdLength]; // this.treehash = new Treehash[this.heightOfTree - this.K]; this.retain = new Vector[this.K - 1]; for (int i = 0; i < K - 1; i++) { this.retain[i] = new Vector(); } } /** * Initializes the calculation of a new root * * @param sharedStack the stack shared by all treehash instances of this tree */ public void initialize(Vector sharedStack) { this.treehash = new Treehash[this.heightOfTree - this.K]; for (int i = 0; i < this.heightOfTree - this.K; i++) { this.treehash[i] = new Treehash(sharedStack, i, this.digestProvider.get()); } this.index = new int[heightOfTree]; this.AuthPath = new byte[heightOfTree][mdLength]; this.root = new byte[mdLength]; this.tailStack = new Vector(); this.heightOfNodes = new Vector(); this.isInitialized = true; this.isFinished = false; for (int i = 0; i < heightOfTree; i++) { this.index[i] = -1; } this.retain = new Vector[this.K - 1]; for (int i = 0; i < K - 1; i++) { this.retain[i] = new Vector(); } this.indexForNextSeed = 3; this.heightOfNextSeed = 0; } /** * updates the root with one leaf and stores needed values in retain, * treehash or authpath. Additionally counts the seeds used. This method is * used when performing the updates for TREE++. * * @param seed the initial seed for treehash: seedNext * @param leaf the height of the treehash */ public void update(byte[] seed, byte[] leaf) { if (this.heightOfNextSeed < (this.heightOfTree - this.K) && this.indexForNextSeed - 2 == index[0]) { this.initializeTreehashSeed(seed, this.heightOfNextSeed); this.heightOfNextSeed++; this.indexForNextSeed *= 2; } // now call the simple update this.update(leaf); } /** * Updates the root with one leaf and stores the needed values in retain, * treehash or authpath */ public void update(byte[] leaf) { if (isFinished) { System.out.print("Too much updates for Tree!!"); return; } if (!isInitialized) { System.err.println("GMSSRootCalc not initialized!"); return; } // a new leaf was omitted, so raise index on lowest layer index[0]++; // store the nodes on the lowest layer in treehash or authpath if (index[0] == 1) { System.arraycopy(leaf, 0, AuthPath[0], 0, mdLength); } else if (index[0] == 3) { // store in treehash only if K < H if (heightOfTree > K) { treehash[0].setFirstNode(leaf); } } if ((index[0] - 3) % 2 == 0 && index[0] >= 3) { // store in retain if K = H if (heightOfTree == K) // TODO: check it { retain[0].insertElementAt(leaf, 0); } } // if first update to this tree is made if (index[0] == 0) { tailStack.addElement(leaf); heightOfNodes.addElement(Integers.valueOf(0)); } else { byte[] help = new byte[mdLength]; byte[] toBeHashed = new byte[mdLength << 1]; // store the new leaf in help System.arraycopy(leaf, 0, help, 0, mdLength); int helpHeight = 0; // while top to nodes have same height while (tailStack.size() > 0 && helpHeight == ((Integer)heightOfNodes.lastElement()) .intValue()) { // help <-- hash(stack top element || help) System.arraycopy(tailStack.lastElement(), 0, toBeHashed, 0, mdLength); tailStack.removeElementAt(tailStack.size() - 1); heightOfNodes.removeElementAt(heightOfNodes.size() - 1); System.arraycopy(help, 0, toBeHashed, mdLength, mdLength); messDigestTree.update(toBeHashed, 0, toBeHashed.length); help = new byte[messDigestTree.getDigestSize()]; messDigestTree.doFinal(help, 0); // the new help node is one step higher helpHeight++; if (helpHeight < heightOfTree) { index[helpHeight]++; // add index 1 element to initial authpath if (index[helpHeight] == 1) { System.arraycopy(help, 0, AuthPath[helpHeight], 0, mdLength); } if (helpHeight >= heightOfTree - K) { if (helpHeight == 0) { System.out.println("M���P"); } // add help element to retain stack if it is a right // node // and not stored in treehash if ((index[helpHeight] - 3) % 2 == 0 && index[helpHeight] >= 3) // TODO: check it { retain[helpHeight - (heightOfTree - K)] .insertElementAt(help, 0); } } else { // if element is third in his line add it to treehash if (index[helpHeight] == 3) { treehash[helpHeight].setFirstNode(help); } } } } // push help element to the stack tailStack.addElement(help); heightOfNodes.addElement(Integers.valueOf(helpHeight)); // is the root calculation finished? if (helpHeight == heightOfTree) { isFinished = true; isInitialized = false; root = (byte[])tailStack.lastElement(); } } } /** * initializes the seeds for the treehashs of the tree precomputed by this * class * * @param seed the initial seed for treehash: seedNext * @param index the height of the treehash */ public void initializeTreehashSeed(byte[] seed, int index) { treehash[index].initializeSeed(seed); } /** * Method to check whether the instance has been initialized or not * * @return true if treehash was already initialized */ public boolean wasInitialized() { return isInitialized; } /** * Method to check whether the instance has been finished or not * * @return true if tree has reached its maximum height */ public boolean wasFinished() { return isFinished; } /** * returns the authentication path of the first leaf of the tree * * @return the authentication path of the first leaf of the tree */ public byte[][] getAuthPath() { return GMSSUtils.clone(AuthPath); } /** * returns the initial treehash instances, storing value y_3(i) * * @return the initial treehash instances, storing value y_3(i) */ public Treehash[] getTreehash() { return GMSSUtils.clone(treehash); } /** * returns the retain stacks storing all right nodes near to the root * * @return the retain stacks storing all right nodes near to the root */ public Vector[] getRetain() { return GMSSUtils.clone(retain); } /** * returns the finished root value * * @return the finished root value */ public byte[] getRoot() { return Arrays.clone(root); } /** * returns the shared stack * * @return the shared stack */ public Vector getStack() { Vector copy = new Vector(); for (Enumeration en = tailStack.elements(); en.hasMoreElements();) { copy.addElement(en.nextElement()); } return copy; } /** * Returns the status byte array used by the GMSSPrivateKeyASN.1 class * * @return The status bytes */ public byte[][] getStatByte() { int tailLength; if (tailStack == null) { tailLength = 0; } else { tailLength = tailStack.size(); } byte[][] statByte = new byte[1 + heightOfTree + tailLength][64]; //FIXME: messDigestTree.getByteLength() statByte[0] = root; for (int i = 0; i < heightOfTree; i++) { statByte[1 + i] = AuthPath[i]; } for (int i = 0; i < tailLength; i++) { statByte[1 + heightOfTree + i] = (byte[])tailStack.elementAt(i); } return statByte; } /** * Returns the status int array used by the GMSSPrivateKeyASN.1 class * * @return The status ints */ public int[] getStatInt() { int tailLength; if (tailStack == null) { tailLength = 0; } else { tailLength = tailStack.size(); } int[] statInt = new int[8 + heightOfTree + tailLength]; statInt[0] = heightOfTree; statInt[1] = mdLength; statInt[2] = K; statInt[3] = indexForNextSeed; statInt[4] = heightOfNextSeed; if (isFinished) { statInt[5] = 1; } else { statInt[5] = 0; } if (isInitialized) { statInt[6] = 1; } else { statInt[6] = 0; } statInt[7] = tailLength; for (int i = 0; i < heightOfTree; i++) { statInt[8 + i] = index[i]; } for (int i = 0; i < tailLength; i++) { statInt[8 + heightOfTree + i] = ((Integer)heightOfNodes .elementAt(i)).intValue(); } return statInt; } /** * @return a human readable version of the structure */ public String toString() { String out = ""; int tailLength; if (tailStack == null) { tailLength = 0; } else { tailLength = tailStack.size(); } for (int i = 0; i < 8 + heightOfTree + tailLength; i++) { out = out + getStatInt()[i] + " "; } for (int i = 0; i < 1 + heightOfTree + tailLength; i++) { out = out + new String(Hex.encode(getStatByte()[i])) + " "; } out = out + " " + digestProvider.get().getDigestSize(); return out; } } bouncycastle-1.49.orig/src/org/bouncycastle/pqc/crypto/gmss/GMSSLeaf.java0000644000175000017500000002524212151551720025766 0ustar ebourgebourgpackage org.bouncycastle.pqc.crypto.gmss; import org.bouncycastle.crypto.Digest; import org.bouncycastle.pqc.crypto.gmss.util.GMSSRandom; import org.bouncycastle.util.Arrays; import org.bouncycastle.util.encoders.Hex; /** * This class implements the distributed computation of the public key of the * Winternitz one-time signature scheme (OTSS). The class is used by the GMSS * classes for calculation of upcoming leafs. */ public class GMSSLeaf { /** * The hash function used by the OTS and the PRNG */ private Digest messDigestOTS; /** * The length of the message digest and private key */ private int mdsize, keysize; /** * The source of randomness for OTS private key generation */ private GMSSRandom gmssRandom; /** * Byte array for distributed computation of the upcoming leaf */ private byte[] leaf; /** * Byte array for storing the concatenated hashes of private key parts */ private byte[] concHashs; /** * indices for distributed computation */ private int i, j; /** * storing 2^w */ private int two_power_w; /** * Winternitz parameter w */ private int w; /** * the amount of distributed computation steps when updateLeaf is called */ private int steps; /** * the internal seed */ private byte[] seed; /** * the OTS privateKey parts */ byte[] privateKeyOTS; /** * This constructor regenerates a prior GMSSLeaf object * * @param digest an array of strings, containing the name of the used hash * function and PRNG and the name of the corresponding * provider * @param otsIndex status bytes * @param numLeafs status ints */ public GMSSLeaf(Digest digest, byte[][] otsIndex, int[] numLeafs) { this.i = numLeafs[0]; this.j = numLeafs[1]; this.steps = numLeafs[2]; this.w = numLeafs[3]; messDigestOTS = digest; gmssRandom = new GMSSRandom(messDigestOTS); // calulate keysize for private key and the help array mdsize = messDigestOTS.getDigestSize(); int mdsizeBit = mdsize << 3; int messagesize = (int)Math.ceil((double)(mdsizeBit) / (double)w); int checksumsize = getLog((messagesize << w) + 1); this.keysize = messagesize + (int)Math.ceil((double)checksumsize / (double)w); this.two_power_w = 1 << w; // calculate steps // ((2^w)-1)*keysize + keysize + 1 / (2^h -1) // initialize arrays this.privateKeyOTS = otsIndex[0]; this.seed = otsIndex[1]; this.concHashs = otsIndex[2]; this.leaf = otsIndex[3]; } /** * The constructor precomputes some needed variables for distributed leaf * calculation * * @param digest an array of strings, containing the digest of the used hash * function and PRNG and the digest of the corresponding * provider * @param w the winterniz parameter of that tree the leaf is computed * for * @param numLeafs the number of leafs of the tree from where the distributed * computation is called */ GMSSLeaf(Digest digest, int w, int numLeafs) { this.w = w; messDigestOTS = digest; gmssRandom = new GMSSRandom(messDigestOTS); // calulate keysize for private key and the help array mdsize = messDigestOTS.getDigestSize(); int mdsizeBit = mdsize << 3; int messagesize = (int)Math.ceil((double)(mdsizeBit) / (double)w); int checksumsize = getLog((messagesize << w) + 1); this.keysize = messagesize + (int)Math.ceil((double)checksumsize / (double)w); this.two_power_w = 1 << w; // calculate steps // ((2^w)-1)*keysize + keysize + 1 / (2^h -1) this.steps = (int)Math .ceil((double)(((1 << w) - 1) * keysize + 1 + keysize) / (double)(numLeafs)); // initialize arrays this.seed = new byte[mdsize]; this.leaf = new byte[mdsize]; this.privateKeyOTS = new byte[mdsize]; this.concHashs = new byte[mdsize * keysize]; } public GMSSLeaf(Digest digest, int w, int numLeafs, byte[] seed0) { this.w = w; messDigestOTS = digest; gmssRandom = new GMSSRandom(messDigestOTS); // calulate keysize for private key and the help array mdsize = messDigestOTS.getDigestSize(); int mdsizeBit = mdsize << 3; int messagesize = (int)Math.ceil((double)(mdsizeBit) / (double)w); int checksumsize = getLog((messagesize << w) + 1); this.keysize = messagesize + (int)Math.ceil((double)checksumsize / (double)w); this.two_power_w = 1 << w; // calculate steps // ((2^w)-1)*keysize + keysize + 1 / (2^h -1) this.steps = (int)Math .ceil((double)(((1 << w) - 1) * keysize + 1 + keysize) / (double)(numLeafs)); // initialize arrays this.seed = new byte[mdsize]; this.leaf = new byte[mdsize]; this.privateKeyOTS = new byte[mdsize]; this.concHashs = new byte[mdsize * keysize]; initLeafCalc(seed0); } private GMSSLeaf(GMSSLeaf original) { this.messDigestOTS = original.messDigestOTS; this.mdsize = original.mdsize; this.keysize = original.keysize; this.gmssRandom = original.gmssRandom; this.leaf = Arrays.clone(original.leaf); this.concHashs = Arrays.clone(original.concHashs); this.i = original.i; this.j = original.j; this.two_power_w = original.two_power_w; this.w = original.w; this.steps = original.steps; this.seed = Arrays.clone(original.seed); this.privateKeyOTS = Arrays.clone(original.privateKeyOTS); } /** * initialize the distributed leaf calculation reset i,j and compute OTSseed * with seed0 * * @param seed0 the starting seed */ // TODO: this really looks like it should be either always called from a constructor or nextLeaf. void initLeafCalc(byte[] seed0) { this.i = 0; this.j = 0; byte[] dummy = new byte[mdsize]; System.arraycopy(seed0, 0, dummy, 0, seed.length); this.seed = gmssRandom.nextSeed(dummy); } GMSSLeaf nextLeaf() { GMSSLeaf nextLeaf = new GMSSLeaf(this); nextLeaf.updateLeafCalc(); return nextLeaf; } /** * Processes steps steps of distributed leaf calculation * * @return true if leaf is completed, else false */ private void updateLeafCalc() { byte[] buf = new byte[messDigestOTS.getDigestSize()]; // steps times do // TODO: this really needs to be looked at, the 10000 has been added as // prior to this the leaf value always ended up as zeros. for (int s = 0; s < steps + 10000; s++) { if (i == keysize && j == two_power_w - 1) { // [3] at last hash the // concatenation messDigestOTS.update(concHashs, 0, concHashs.length); leaf = new byte[messDigestOTS.getDigestSize()]; messDigestOTS.doFinal(leaf, 0); return; } else if (i == 0 || j == two_power_w - 1) { // [1] at the // beginning and // when [2] is // finished: get the // next private key // part i++; j = 0; // get next privKey part this.privateKeyOTS = gmssRandom.nextSeed(seed); } else { // [2] hash the privKey part messDigestOTS.update(privateKeyOTS, 0, privateKeyOTS.length); privateKeyOTS = buf; messDigestOTS.doFinal(privateKeyOTS, 0); j++; if (j == two_power_w - 1) { // after w hashes add to the // concatenated array System.arraycopy(privateKeyOTS, 0, concHashs, mdsize * (i - 1), mdsize); } } } throw new IllegalStateException("unable to updateLeaf in steps: " + steps + " " + i + " " + j); } /** * Returns the leaf value. * * @return the leaf value */ public byte[] getLeaf() { return Arrays.clone(leaf); } /** * This method returns the least integer that is greater or equal to the * logarithm to the base 2 of an integer intValue. * * @param intValue an integer * @return The least integer greater or equal to the logarithm to the base 2 * of intValue */ private int getLog(int intValue) { int log = 1; int i = 2; while (i < intValue) { i <<= 1; log++; } return log; } /** * Returns the status byte array used by the GMSSPrivateKeyASN.1 class * * @return The status bytes */ public byte[][] getStatByte() { byte[][] statByte = new byte[4][]; statByte[0] = new byte[mdsize]; statByte[1] = new byte[mdsize]; statByte[2] = new byte[mdsize * keysize]; statByte[3] = new byte[mdsize]; statByte[0] = privateKeyOTS; statByte[1] = seed; statByte[2] = concHashs; statByte[3] = leaf; return statByte; } /** * Returns the status int array used by the GMSSPrivateKeyASN.1 class * * @return The status ints */ public int[] getStatInt() { int[] statInt = new int[4]; statInt[0] = i; statInt[1] = j; statInt[2] = steps; statInt[3] = w; return statInt; } /** * Returns a String representation of the main part of this element * * @return a String representation of the main part of this element */ public String toString() { String out = ""; for (int i = 0; i < 4; i++) { out = out + this.getStatInt()[i] + " "; } out = out + " " + this.mdsize + " " + this.keysize + " " + this.two_power_w + " "; byte[][] temp = this.getStatByte(); for (int i = 0; i < 4; i++) { if (temp[i] != null) { out = out + new String(Hex.encode(temp[i])) + " "; } else { out = out + "null "; } } return out; } } bouncycastle-1.49.orig/src/org/bouncycastle/pqc/crypto/gmss/GMSSDigestProvider.java0000644000175000017500000000021511777442313030054 0ustar ebourgebourgpackage org.bouncycastle.pqc.crypto.gmss; import org.bouncycastle.crypto.Digest; public interface GMSSDigestProvider { Digest get(); } bouncycastle-1.49.orig/src/org/bouncycastle/pqc/crypto/gmss/GMSSKeyPairGenerator.java0000644000175000017500000004052312151551720030331 0ustar ebourgebourgpackage org.bouncycastle.pqc.crypto.gmss; import java.security.SecureRandom; import java.util.Vector; import org.bouncycastle.crypto.AsymmetricCipherKeyPair; import org.bouncycastle.crypto.AsymmetricCipherKeyPairGenerator; import org.bouncycastle.crypto.Digest; import org.bouncycastle.crypto.KeyGenerationParameters; import org.bouncycastle.pqc.crypto.gmss.util.GMSSRandom; import org.bouncycastle.pqc.crypto.gmss.util.WinternitzOTSVerify; import org.bouncycastle.pqc.crypto.gmss.util.WinternitzOTSignature; /** * This class implements key pair generation of the generalized Merkle signature * scheme (GMSS). * * @see GMSSSigner */ public class GMSSKeyPairGenerator implements AsymmetricCipherKeyPairGenerator { /** * The source of randomness for OTS private key generation */ private GMSSRandom gmssRandom; /** * The hash function used for the construction of the authentication trees */ private Digest messDigestTree; /** * An array of the seeds for the PRGN (for main tree, and all current * subtrees) */ private byte[][] currentSeeds; /** * An array of seeds for the PRGN (for all subtrees after next) */ private byte[][] nextNextSeeds; /** * An array of the RootSignatures */ private byte[][] currentRootSigs; /** * Class of hash function to use */ private GMSSDigestProvider digestProvider; /** * The length of the seed for the PRNG */ private int mdLength; /** * the number of Layers */ private int numLayer; /** * Flag indicating if the class already has been initialized */ private boolean initialized = false; /** * Instance of GMSSParameterset */ private GMSSParameters gmssPS; /** * An array of the heights of the authentication trees of each layer */ private int[] heightOfTrees; /** * An array of the Winternitz parameter 'w' of each layer */ private int[] otsIndex; /** * The parameter K needed for the authentication path computation */ private int[] K; private GMSSKeyGenerationParameters gmssParams; /** * The GMSS OID. */ public static final String OID = "1.3.6.1.4.1.8301.3.1.3.3"; /** * The standard constructor tries to generate the GMSS algorithm identifier * with the corresponding OID. *

    * * @param digestProvider provider for digest implementations. */ public GMSSKeyPairGenerator(GMSSDigestProvider digestProvider) { this.digestProvider = digestProvider; messDigestTree = digestProvider.get(); // set mdLength this.mdLength = messDigestTree.getDigestSize(); // construct randomizer this.gmssRandom = new GMSSRandom(messDigestTree); } /** * Generates the GMSS key pair. The public key is an instance of * JDKGMSSPublicKey, the private key is an instance of JDKGMSSPrivateKey. * * @return Key pair containing a JDKGMSSPublicKey and a JDKGMSSPrivateKey */ private AsymmetricCipherKeyPair genKeyPair() { if (!initialized) { initializeDefault(); } // initialize authenticationPaths and treehash instances byte[][][] currentAuthPaths = new byte[numLayer][][]; byte[][][] nextAuthPaths = new byte[numLayer - 1][][]; Treehash[][] currentTreehash = new Treehash[numLayer][]; Treehash[][] nextTreehash = new Treehash[numLayer - 1][]; Vector[] currentStack = new Vector[numLayer]; Vector[] nextStack = new Vector[numLayer - 1]; Vector[][] currentRetain = new Vector[numLayer][]; Vector[][] nextRetain = new Vector[numLayer - 1][]; for (int i = 0; i < numLayer; i++) { currentAuthPaths[i] = new byte[heightOfTrees[i]][mdLength]; currentTreehash[i] = new Treehash[heightOfTrees[i] - K[i]]; if (i > 0) { nextAuthPaths[i - 1] = new byte[heightOfTrees[i]][mdLength]; nextTreehash[i - 1] = new Treehash[heightOfTrees[i] - K[i]]; } currentStack[i] = new Vector(); if (i > 0) { nextStack[i - 1] = new Vector(); } } // initialize roots byte[][] currentRoots = new byte[numLayer][mdLength]; byte[][] nextRoots = new byte[numLayer - 1][mdLength]; // initialize seeds byte[][] seeds = new byte[numLayer][mdLength]; // initialize seeds[] by copying starting-seeds of first trees of each // layer for (int i = 0; i < numLayer; i++) { System.arraycopy(currentSeeds[i], 0, seeds[i], 0, mdLength); } // initialize rootSigs currentRootSigs = new byte[numLayer - 1][mdLength]; // ------------------------- // ------------------------- // --- calculation of current authpaths and current rootsigs (AUTHPATHS, // SIG)------ // from bottom up to the root for (int h = numLayer - 1; h >= 0; h--) { GMSSRootCalc tree = new GMSSRootCalc(this.heightOfTrees[h], this.K[h], digestProvider); try { // on lowest layer no lower root is available, so just call // the method with null as first parameter if (h == numLayer - 1) { tree = this.generateCurrentAuthpathAndRoot(null, currentStack[h], seeds[h], h); } else // otherwise call the method with the former computed root // value { tree = this.generateCurrentAuthpathAndRoot(currentRoots[h + 1], currentStack[h], seeds[h], h); } } catch (Exception e1) { e1.printStackTrace(); } // set initial values needed for the private key construction for (int i = 0; i < heightOfTrees[h]; i++) { System.arraycopy(tree.getAuthPath()[i], 0, currentAuthPaths[h][i], 0, mdLength); } currentRetain[h] = tree.getRetain(); currentTreehash[h] = tree.getTreehash(); System.arraycopy(tree.getRoot(), 0, currentRoots[h], 0, mdLength); } // --- calculation of next authpaths and next roots (AUTHPATHS+, ROOTS+) // ------ for (int h = numLayer - 2; h >= 0; h--) { GMSSRootCalc tree = this.generateNextAuthpathAndRoot(nextStack[h], seeds[h + 1], h + 1); // set initial values needed for the private key construction for (int i = 0; i < heightOfTrees[h + 1]; i++) { System.arraycopy(tree.getAuthPath()[i], 0, nextAuthPaths[h][i], 0, mdLength); } nextRetain[h] = tree.getRetain(); nextTreehash[h] = tree.getTreehash(); System.arraycopy(tree.getRoot(), 0, nextRoots[h], 0, mdLength); // create seed for the Merkle tree after next (nextNextSeeds) // SEEDs++ System.arraycopy(seeds[h + 1], 0, this.nextNextSeeds[h], 0, mdLength); } // ------------ // generate JDKGMSSPublicKey GMSSPublicKeyParameters publicKey = new GMSSPublicKeyParameters(currentRoots[0], gmssPS); // generate the JDKGMSSPrivateKey GMSSPrivateKeyParameters privateKey = new GMSSPrivateKeyParameters(currentSeeds, nextNextSeeds, currentAuthPaths, nextAuthPaths, currentTreehash, nextTreehash, currentStack, nextStack, currentRetain, nextRetain, nextRoots, currentRootSigs, gmssPS, digestProvider); // return the KeyPair return (new AsymmetricCipherKeyPair(publicKey, privateKey)); } /** * calculates the authpath for tree in layer h which starts with seed[h] * additionally computes the rootSignature of underlaying root * * @param currentStack stack used for the treehash instance created by this method * @param lowerRoot stores the root of the lower tree * @param seed starting seeds * @param h actual layer */ private GMSSRootCalc generateCurrentAuthpathAndRoot(byte[] lowerRoot, Vector currentStack, byte[] seed, int h) { byte[] help = new byte[mdLength]; byte[] OTSseed = new byte[mdLength]; OTSseed = gmssRandom.nextSeed(seed); WinternitzOTSignature ots; // data structure that constructs the whole tree and stores // the initial values for treehash, Auth and retain GMSSRootCalc treeToConstruct = new GMSSRootCalc(this.heightOfTrees[h], this.K[h], digestProvider); treeToConstruct.initialize(currentStack); // generate the first leaf if (h == numLayer - 1) { ots = new WinternitzOTSignature(OTSseed, digestProvider.get(), otsIndex[h]); help = ots.getPublicKey(); } else { // for all layers except the lowest, generate the signature of the // underlying root // and reuse this signature to compute the first leaf of acual layer // more efficiently (by verifiing the signature) ots = new WinternitzOTSignature(OTSseed, digestProvider.get(), otsIndex[h]); currentRootSigs[h] = ots.getSignature(lowerRoot); WinternitzOTSVerify otsver = new WinternitzOTSVerify(digestProvider.get(), otsIndex[h]); help = otsver.Verify(lowerRoot, currentRootSigs[h]); } // update the tree with the first leaf treeToConstruct.update(help); int seedForTreehashIndex = 3; int count = 0; // update the tree 2^(H) - 1 times, from the second to the last leaf for (int i = 1; i < (1 << this.heightOfTrees[h]); i++) { // initialize the seeds for the leaf generation with index 3 * 2^h if (i == seedForTreehashIndex && count < this.heightOfTrees[h] - this.K[h]) { treeToConstruct.initializeTreehashSeed(seed, count); seedForTreehashIndex *= 2; count++; } OTSseed = gmssRandom.nextSeed(seed); ots = new WinternitzOTSignature(OTSseed, digestProvider.get(), otsIndex[h]); treeToConstruct.update(ots.getPublicKey()); } if (treeToConstruct.wasFinished()) { return treeToConstruct; } System.err.println("Baum noch nicht fertig konstruiert!!!"); return null; } /** * calculates the authpath and root for tree in layer h which starts with * seed[h] * * @param nextStack stack used for the treehash instance created by this method * @param seed starting seeds * @param h actual layer */ private GMSSRootCalc generateNextAuthpathAndRoot(Vector nextStack, byte[] seed, int h) { byte[] OTSseed = new byte[numLayer]; WinternitzOTSignature ots; // data structure that constructs the whole tree and stores // the initial values for treehash, Auth and retain GMSSRootCalc treeToConstruct = new GMSSRootCalc(this.heightOfTrees[h], this.K[h], this.digestProvider); treeToConstruct.initialize(nextStack); int seedForTreehashIndex = 3; int count = 0; // update the tree 2^(H) times, from the first to the last leaf for (int i = 0; i < (1 << this.heightOfTrees[h]); i++) { // initialize the seeds for the leaf generation with index 3 * 2^h if (i == seedForTreehashIndex && count < this.heightOfTrees[h] - this.K[h]) { treeToConstruct.initializeTreehashSeed(seed, count); seedForTreehashIndex *= 2; count++; } OTSseed = gmssRandom.nextSeed(seed); ots = new WinternitzOTSignature(OTSseed, digestProvider.get(), otsIndex[h]); treeToConstruct.update(ots.getPublicKey()); } if (treeToConstruct.wasFinished()) { return treeToConstruct; } System.err.println("N�chster Baum noch nicht fertig konstruiert!!!"); return null; } /** * This method initializes the GMSS KeyPairGenerator using an integer value * keySize as input. It provides a simple use of the GMSS for * testing demands. *

    * A given keysize of less than 10 creates an amount 2^10 * signatures. A keySize between 10 and 20 creates 2^20 signatures. Given an * integer greater than 20 the key pair generator creates 2^40 signatures. * * @param keySize Assigns the parameters used for the GMSS signatures. There are * 3 choices:
    * 1. keysize <= 10: creates 2^10 signatures using the * parameterset
    * P = (2, (5, 5), (3, 3), (3, 3))
    * 2. keysize > 10 and <= 20: creates 2^20 signatures using the * parameterset
    * P = (2, (10, 10), (5, 4), (2, 2))
    * 3. keysize > 20: creates 2^40 signatures using the * parameterset
    * P = (2, (10, 10, 10, 10), (9, 9, 9, 3), (2, 2, 2, 2)) * @param secureRandom not used by GMSS, the SHA1PRNG of the SUN Provider is always * used */ public void initialize(int keySize, SecureRandom secureRandom) { KeyGenerationParameters kgp; if (keySize <= 10) { // create 2^10 keys int[] defh = {10}; int[] defw = {3}; int[] defk = {2}; // XXX sec random neede? kgp = new GMSSKeyGenerationParameters(secureRandom, new GMSSParameters(defh.length, defh, defw, defk)); } else if (keySize <= 20) { // create 2^20 keys int[] defh = {10, 10}; int[] defw = {5, 4}; int[] defk = {2, 2}; kgp = new GMSSKeyGenerationParameters(secureRandom, new GMSSParameters(defh.length, defh, defw, defk)); } else { // create 2^40 keys, keygen lasts around 80 seconds int[] defh = {10, 10, 10, 10}; int[] defw = {9, 9, 9, 3}; int[] defk = {2, 2, 2, 2}; kgp = new GMSSKeyGenerationParameters(secureRandom, new GMSSParameters(defh.length, defh, defw, defk)); } // call the initializer with the chosen parameters this.initialize(kgp); } /** * Initalizes the key pair generator using a parameter set as input */ public void initialize(KeyGenerationParameters param) { this.gmssParams = (GMSSKeyGenerationParameters)param; // generate GMSSParameterset this.gmssPS = new GMSSParameters(gmssParams.getParameters().getNumOfLayers(), gmssParams.getParameters().getHeightOfTrees(), gmssParams.getParameters().getWinternitzParameter(), gmssParams.getParameters().getK()); this.numLayer = gmssPS.getNumOfLayers(); this.heightOfTrees = gmssPS.getHeightOfTrees(); this.otsIndex = gmssPS.getWinternitzParameter(); this.K = gmssPS.getK(); // seeds this.currentSeeds = new byte[numLayer][mdLength]; this.nextNextSeeds = new byte[numLayer - 1][mdLength]; // construct SecureRandom for initial seed generation SecureRandom secRan = new SecureRandom(); // generation of initial seeds for (int i = 0; i < numLayer; i++) { secRan.nextBytes(currentSeeds[i]); gmssRandom.nextSeed(currentSeeds[i]); } this.initialized = true; } /** * This method is called by generateKeyPair() in case that no other * initialization method has been called by the user */ private void initializeDefault() { int[] defh = {10, 10, 10, 10}; int[] defw = {3, 3, 3, 3}; int[] defk = {2, 2, 2, 2}; KeyGenerationParameters kgp = new GMSSKeyGenerationParameters(new SecureRandom(), new GMSSParameters(defh.length, defh, defw, defk)); this.initialize(kgp); } public void init(KeyGenerationParameters param) { this.initialize(param); } public AsymmetricCipherKeyPair generateKeyPair() { return genKeyPair(); } } bouncycastle-1.49.orig/src/org/bouncycastle/pqc/crypto/gmss/GMSSUtils.java0000644000175000017500000000557212105026541026220 0ustar ebourgebourgpackage org.bouncycastle.pqc.crypto.gmss; import java.util.Enumeration; import java.util.Vector; import org.bouncycastle.util.Arrays; class GMSSUtils { static GMSSLeaf[] clone(GMSSLeaf[] data) { if (data == null) { return null; } GMSSLeaf[] copy = new GMSSLeaf[data.length]; System.arraycopy(data, 0, copy, 0, data.length); return copy; } static GMSSRootCalc[] clone(GMSSRootCalc[] data) { if (data == null) { return null; } GMSSRootCalc[] copy = new GMSSRootCalc[data.length]; System.arraycopy(data, 0, copy, 0, data.length); return copy; } static GMSSRootSig[] clone(GMSSRootSig[] data) { if (data == null) { return null; } GMSSRootSig[] copy = new GMSSRootSig[data.length]; System.arraycopy(data, 0, copy, 0, data.length); return copy; } static byte[][] clone(byte[][] data) { if (data == null) { return null; } byte[][] copy = new byte[data.length][]; for (int i = 0; i != data.length; i++) { copy[i] = Arrays.clone(data[i]); } return copy; } static byte[][][] clone(byte[][][] data) { if (data == null) { return null; } byte[][][] copy = new byte[data.length][][]; for (int i = 0; i != data.length; i++) { copy[i] = clone(data[i]); } return copy; } static Treehash[] clone(Treehash[] data) { if (data == null) { return null; } Treehash[] copy = new Treehash[data.length]; System.arraycopy(data, 0, copy, 0, data.length); return copy; } static Treehash[][] clone(Treehash[][] data) { if (data == null) { return null; } Treehash[][] copy = new Treehash[data.length][]; for (int i = 0; i != data.length; i++) { copy[i] = clone(data[i]); } return copy; } static Vector[] clone(Vector[] data) { if (data == null) { return null; } Vector[] copy = new Vector[data.length]; for (int i = 0; i != data.length; i++) { copy[i] = new Vector(); for (Enumeration en = data[i].elements(); en.hasMoreElements();) { copy[i].addElement(en.nextElement()); } } return copy; } static Vector[][] clone(Vector[][] data) { if (data == null) { return null; } Vector[][] copy = new Vector[data.length][]; for (int i = 0; i != data.length; i++) { copy[i] = clone(data[i]); } return copy; } } bouncycastle-1.49.orig/src/org/bouncycastle/pqc/crypto/mceliece/0000755000175000017500000000000012152033551024350 5ustar ebourgebourgbouncycastle-1.49.orig/src/org/bouncycastle/pqc/crypto/mceliece/McElieceCCA2KeyPairGenerator.java0000644000175000017500000000760412043372321032415 0ustar ebourgebourgpackage org.bouncycastle.pqc.crypto.mceliece; import java.security.SecureRandom; import org.bouncycastle.crypto.AsymmetricCipherKeyPair; import org.bouncycastle.crypto.AsymmetricCipherKeyPairGenerator; import org.bouncycastle.crypto.KeyGenerationParameters; import org.bouncycastle.pqc.math.linearalgebra.GF2Matrix; import org.bouncycastle.pqc.math.linearalgebra.GF2mField; import org.bouncycastle.pqc.math.linearalgebra.GoppaCode; import org.bouncycastle.pqc.math.linearalgebra.GoppaCode.MaMaPe; import org.bouncycastle.pqc.math.linearalgebra.Permutation; import org.bouncycastle.pqc.math.linearalgebra.PolynomialGF2mSmallM; import org.bouncycastle.pqc.math.linearalgebra.PolynomialRingGF2m; /** * This class implements key pair generation of the McEliece Public Key * Cryptosystem (McEliecePKC). */ public class McElieceCCA2KeyPairGenerator implements AsymmetricCipherKeyPairGenerator { /** * The OID of the algorithm. */ public static final String OID = "1.3.6.1.4.1.8301.3.1.3.4.2"; private McElieceCCA2KeyGenerationParameters mcElieceCCA2Params; // the extension degree of the finite field GF(2^m) private int m; // the length of the code private int n; // the error correction capability private int t; // the field polynomial private int fieldPoly; // the source of randomness private SecureRandom random; // flag indicating whether the key pair generator has been initialized private boolean initialized = false; /** * Default initialization of the key pair generator. */ private void initializeDefault() { McElieceCCA2KeyGenerationParameters mcCCA2Params = new McElieceCCA2KeyGenerationParameters(new SecureRandom(), new McElieceCCA2Parameters()); init(mcCCA2Params); } // TODO public void init( KeyGenerationParameters param) { this.mcElieceCCA2Params = (McElieceCCA2KeyGenerationParameters)param; // set source of randomness this.random = new SecureRandom(); this.m = this.mcElieceCCA2Params.getParameters().getM(); this.n = this.mcElieceCCA2Params.getParameters().getN(); this.t = this.mcElieceCCA2Params.getParameters().getT(); this.fieldPoly = this.mcElieceCCA2Params.getParameters().getFieldPoly(); this.initialized = true; } public AsymmetricCipherKeyPair generateKeyPair() { if (!initialized) { initializeDefault(); } // finite field GF(2^m) GF2mField field = new GF2mField(m, fieldPoly); // irreducible Goppa polynomial PolynomialGF2mSmallM gp = new PolynomialGF2mSmallM(field, t, PolynomialGF2mSmallM.RANDOM_IRREDUCIBLE_POLYNOMIAL, random); PolynomialRingGF2m ring = new PolynomialRingGF2m(field, gp); // matrix for computing square roots in (GF(2^m))^t PolynomialGF2mSmallM[] qInv = ring.getSquareRootMatrix(); // generate canonical check matrix GF2Matrix h = GoppaCode.createCanonicalCheckMatrix(field, gp); // compute short systematic form of check matrix MaMaPe mmp = GoppaCode.computeSystematicForm(h, random); GF2Matrix shortH = mmp.getSecondMatrix(); Permutation p = mmp.getPermutation(); // compute short systematic form of generator matrix GF2Matrix shortG = (GF2Matrix)shortH.computeTranspose(); // obtain number of rows of G (= dimension of the code) int k = shortG.getNumRows(); // generate keys McElieceCCA2PublicKeyParameters pubKey = new McElieceCCA2PublicKeyParameters(OID, n, t, shortG, mcElieceCCA2Params.getParameters()); McElieceCCA2PrivateKeyParameters privKey = new McElieceCCA2PrivateKeyParameters(OID, n, k, field, gp, p, h, qInv, mcElieceCCA2Params.getParameters()); // return key pair return new AsymmetricCipherKeyPair(pubKey, privKey); } } bouncycastle-1.49.orig/src/org/bouncycastle/pqc/crypto/mceliece/McEliecePointchevalCipher.java0000644000175000017500000001524412105020776032222 0ustar ebourgebourgpackage org.bouncycastle.pqc.crypto.mceliece; import java.security.SecureRandom; import org.bouncycastle.crypto.CipherParameters; import org.bouncycastle.crypto.Digest; import org.bouncycastle.crypto.digests.SHA1Digest; import org.bouncycastle.crypto.params.ParametersWithRandom; import org.bouncycastle.crypto.prng.DigestRandomGenerator; import org.bouncycastle.pqc.crypto.MessageEncryptor; import org.bouncycastle.pqc.math.linearalgebra.ByteUtils; import org.bouncycastle.pqc.math.linearalgebra.GF2Vector; /** * This class implements the Pointcheval conversion of the McEliecePKCS. * Pointcheval presents a generic technique to make a CCA2-secure cryptosystem * from any partially trapdoor one-way function in the random oracle model. For * details, see D. Engelbert, R. Overbeck, A. Schmidt, "A summary of the * development of the McEliece Cryptosystem", technical report. */ public class McEliecePointchevalCipher implements MessageEncryptor { /** * The OID of the algorithm. */ public static final String OID = "1.3.6.1.4.1.8301.3.1.3.4.2.2"; private Digest messDigest; private SecureRandom sr; /** * The McEliece main parameters */ private int n, k, t; McElieceCCA2KeyParameters key; public void init(boolean forSigning, CipherParameters param) { if (forSigning) { if (param instanceof ParametersWithRandom) { ParametersWithRandom rParam = (ParametersWithRandom)param; this.sr = rParam.getRandom(); this.key = (McElieceCCA2PublicKeyParameters)rParam.getParameters(); this.initCipherEncrypt((McElieceCCA2PublicKeyParameters)key); } else { this.sr = new SecureRandom(); this.key = (McElieceCCA2PublicKeyParameters)param; this.initCipherEncrypt((McElieceCCA2PublicKeyParameters)key); } } else { this.key = (McElieceCCA2PrivateKeyParameters)param; this.initCipherDecrypt((McElieceCCA2PrivateKeyParameters)key); } } /** * Return the key size of the given key object. * * @param key the McElieceCCA2KeyParameters object * @return the key size of the given key object * @throws IllegalArgumentException if the key is invalid */ public int getKeySize(McElieceCCA2KeyParameters key) throws IllegalArgumentException { if (key instanceof McElieceCCA2PublicKeyParameters) { return ((McElieceCCA2PublicKeyParameters)key).getN(); } if (key instanceof McElieceCCA2PrivateKeyParameters) { return ((McElieceCCA2PrivateKeyParameters)key).getN(); } throw new IllegalArgumentException("unsupported type"); } protected int decryptOutputSize(int inLen) { return 0; } protected int encryptOutputSize(int inLen) { return 0; } public void initCipherEncrypt(McElieceCCA2PublicKeyParameters pubKey) { this.sr = sr != null ? sr : new SecureRandom(); this.messDigest = pubKey.getParameters().getDigest(); n = pubKey.getN(); k = pubKey.getK(); t = pubKey.getT(); } public void initCipherDecrypt(McElieceCCA2PrivateKeyParameters privKey) { this.messDigest = privKey.getParameters().getDigest(); n = privKey.getN(); k = privKey.getK(); t = privKey.getT(); } public byte[] messageEncrypt(byte[] input) throws Exception { int kDiv8 = k >> 3; // generate random r of length k div 8 bytes byte[] r = new byte[kDiv8]; sr.nextBytes(r); // generate random vector r' of length k bits GF2Vector rPrime = new GF2Vector(k, sr); // convert r' to byte array byte[] rPrimeBytes = rPrime.getEncoded(); // compute (input||r) byte[] mr = ByteUtils.concatenate(input, r); // compute H(input||r) messDigest.update(mr, 0, mr.length); byte[] hmr = new byte[messDigest.getDigestSize()]; messDigest.doFinal(hmr, 0); // convert H(input||r) to error vector z GF2Vector z = Conversions.encode(n, t, hmr); // compute c1 = E(rPrime, z) byte[] c1 = McElieceCCA2Primitives.encryptionPrimitive((McElieceCCA2PublicKeyParameters)key, rPrime, z).getEncoded(); // get PRNG object DigestRandomGenerator sr0 = new DigestRandomGenerator(new SHA1Digest()); // seed PRNG with r' sr0.addSeedMaterial(rPrimeBytes); // generate random c2 byte[] c2 = new byte[input.length + kDiv8]; sr0.nextBytes(c2); // XOR with input for (int i = 0; i < input.length; i++) { c2[i] ^= input[i]; } // XOR with r for (int i = 0; i < kDiv8; i++) { c2[input.length + i] ^= r[i]; } // return (c1||c2) return ByteUtils.concatenate(c1, c2); } public byte[] messageDecrypt(byte[] input) throws Exception { int c1Len = (n + 7) >> 3; int c2Len = input.length - c1Len; // split cipher text (c1||c2) byte[][] c1c2 = ByteUtils.split(input, c1Len); byte[] c1 = c1c2[0]; byte[] c2 = c1c2[1]; // decrypt c1 ... GF2Vector c1Vec = GF2Vector.OS2VP(n, c1); GF2Vector[] c1Dec = McElieceCCA2Primitives.decryptionPrimitive((McElieceCCA2PrivateKeyParameters)key, c1Vec); byte[] rPrimeBytes = c1Dec[0].getEncoded(); // ... and obtain error vector z GF2Vector z = c1Dec[1]; // get PRNG object DigestRandomGenerator sr0 = new DigestRandomGenerator(new SHA1Digest()); // seed PRNG with r' sr0.addSeedMaterial(rPrimeBytes); // generate random sequence byte[] mrBytes = new byte[c2Len]; sr0.nextBytes(mrBytes); // XOR with c2 to obtain (m||r) for (int i = 0; i < c2Len; i++) { mrBytes[i] ^= c2[i]; } // compute H(m||r) messDigest.update(mrBytes, 0, mrBytes.length); byte[] hmr = new byte[messDigest.getDigestSize()]; messDigest.doFinal(hmr, 0); // compute Conv(H(m||r)) c1Vec = Conversions.encode(n, t, hmr); // check that Conv(H(m||r)) = z if (!c1Vec.equals(z)) { throw new Exception("Bad Padding: Invalid ciphertext."); } // split (m||r) to obtain m int kDiv8 = k >> 3; byte[][] mr = ByteUtils.split(mrBytes, c2Len - kDiv8); // return plain text m return mr[0]; } } bouncycastle-1.49.orig/src/org/bouncycastle/pqc/crypto/mceliece/McElieceKeyGenerationParameters.java0000644000175000017500000000104612043365070033376 0ustar ebourgebourgpackage org.bouncycastle.pqc.crypto.mceliece; import java.security.SecureRandom; import org.bouncycastle.crypto.KeyGenerationParameters; public class McElieceKeyGenerationParameters extends KeyGenerationParameters { private McElieceParameters params; public McElieceKeyGenerationParameters( SecureRandom random, McElieceParameters params) { // XXX key size? super(random, 256); this.params = params; } public McElieceParameters getParameters() { return params; } } bouncycastle-1.49.orig/src/org/bouncycastle/pqc/crypto/mceliece/McElieceCCA2KeyParameters.java0000644000175000017500000000075512043365070031761 0ustar ebourgebourgpackage org.bouncycastle.pqc.crypto.mceliece; import org.bouncycastle.crypto.params.AsymmetricKeyParameter; public class McElieceCCA2KeyParameters extends AsymmetricKeyParameter { private McElieceCCA2Parameters params; public McElieceCCA2KeyParameters( boolean isPrivate, McElieceCCA2Parameters params) { super(isPrivate); this.params = params; } public McElieceCCA2Parameters getParameters() { return params; } } bouncycastle-1.49.orig/src/org/bouncycastle/pqc/crypto/mceliece/McElieceKobaraImaiCipher.java0000644000175000017500000002207112105017313031732 0ustar ebourgebourgpackage org.bouncycastle.pqc.crypto.mceliece; import java.security.SecureRandom; import org.bouncycastle.crypto.CipherParameters; import org.bouncycastle.crypto.Digest; import org.bouncycastle.crypto.digests.SHA1Digest; import org.bouncycastle.crypto.params.ParametersWithRandom; import org.bouncycastle.crypto.prng.DigestRandomGenerator; import org.bouncycastle.pqc.crypto.MessageEncryptor; import org.bouncycastle.pqc.math.linearalgebra.ByteUtils; import org.bouncycastle.pqc.math.linearalgebra.GF2Vector; import org.bouncycastle.pqc.math.linearalgebra.IntegerFunctions; /** * This class implements the Kobara/Imai conversion of the McEliecePKCS. This is * a conversion of the McEliecePKCS which is CCA2-secure. For details, see D. * Engelbert, R. Overbeck, A. Schmidt, "A summary of the development of the * McEliece Cryptosystem", technical report. */ public class McElieceKobaraImaiCipher implements MessageEncryptor { /** * The OID of the algorithm. */ public static final String OID = "1.3.6.1.4.1.8301.3.1.3.4.2.3"; private static final String DEFAULT_PRNG_NAME = "SHA1PRNG"; /** * A predetermined public constant. */ public static final byte[] PUBLIC_CONSTANT = "a predetermined public constant" .getBytes(); private Digest messDigest; private SecureRandom sr; McElieceCCA2KeyParameters key; /** * The McEliece main parameters */ private int n, k, t; public void init(boolean forSigning, CipherParameters param) { if (forSigning) { if (param instanceof ParametersWithRandom) { ParametersWithRandom rParam = (ParametersWithRandom)param; this.sr = rParam.getRandom(); this.key = (McElieceCCA2PublicKeyParameters)rParam.getParameters(); this.initCipherEncrypt((McElieceCCA2PublicKeyParameters)key); } else { this.sr = new SecureRandom(); this.key = (McElieceCCA2PublicKeyParameters)param; this.initCipherEncrypt((McElieceCCA2PublicKeyParameters)key); } } else { this.key = (McElieceCCA2PrivateKeyParameters)param; this.initCipherDecrypt((McElieceCCA2PrivateKeyParameters)key); } } /** * Return the key size of the given key object. * * @param key the McElieceCCA2KeyParameters object * @return the key size of the given key object */ public int getKeySize(McElieceCCA2KeyParameters key) { if (key instanceof McElieceCCA2PublicKeyParameters) { return ((McElieceCCA2PublicKeyParameters)key).getN(); } if (key instanceof McElieceCCA2PrivateKeyParameters) { return ((McElieceCCA2PrivateKeyParameters)key).getN(); } throw new IllegalArgumentException("unsupported type"); } private void initCipherEncrypt(McElieceCCA2PublicKeyParameters pubKey) { this.messDigest = pubKey.getParameters().getDigest(); n = pubKey.getN(); k = pubKey.getK(); t = pubKey.getT(); } public void initCipherDecrypt(McElieceCCA2PrivateKeyParameters privKey) { this.messDigest = privKey.getParameters().getDigest(); n = privKey.getN(); k = privKey.getK(); t = privKey.getT(); } public byte[] messageEncrypt(byte[] input) throws Exception { int c2Len = messDigest.getDigestSize(); int c4Len = k >> 3; int c5Len = (IntegerFunctions.binomial(n, t).bitLength() - 1) >> 3; int mLen = c4Len + c5Len - c2Len - PUBLIC_CONSTANT.length; if (input.length > mLen) { mLen = input.length; } int c1Len = mLen + PUBLIC_CONSTANT.length; int c6Len = c1Len + c2Len - c4Len - c5Len; // compute (m||const) byte[] mConst = new byte[c1Len]; System.arraycopy(input, 0, mConst, 0, input.length); System.arraycopy(PUBLIC_CONSTANT, 0, mConst, mLen, PUBLIC_CONSTANT.length); // generate random r of length c2Len bytes byte[] r = new byte[c2Len]; sr.nextBytes(r); // get PRNG object // get PRNG object DigestRandomGenerator sr0 = new DigestRandomGenerator(new SHA1Digest()); // seed PRNG with r' sr0.addSeedMaterial(r); // generate random sequence ... byte[] c1 = new byte[c1Len]; sr0.nextBytes(c1); // ... and XOR with (m||const) to obtain c1 for (int i = c1Len - 1; i >= 0; i--) { c1[i] ^= mConst[i]; } // compute H(c1) ... byte[] c2 = new byte[messDigest.getDigestSize()]; messDigest.update(c1, 0, c1.length); messDigest.doFinal(c2, 0); // ... and XOR with r for (int i = c2Len - 1; i >= 0; i--) { c2[i] ^= r[i]; } // compute (c2||c1) byte[] c2c1 = ByteUtils.concatenate(c2, c1); // split (c2||c1) into (c6||c5||c4), where c4Len is k/8 bytes, c5Len is // floor[log(n|t)]/8 bytes, and c6Len is c1Len+c2Len-c4Len-c5Len (may be // 0). byte[] c6 = new byte[0]; if (c6Len > 0) { c6 = new byte[c6Len]; System.arraycopy(c2c1, 0, c6, 0, c6Len); } byte[] c5 = new byte[c5Len]; System.arraycopy(c2c1, c6Len, c5, 0, c5Len); byte[] c4 = new byte[c4Len]; System.arraycopy(c2c1, c6Len + c5Len, c4, 0, c4Len); // convert c4 to vector over GF(2) GF2Vector c4Vec = GF2Vector.OS2VP(k, c4); // convert c5 to error vector z GF2Vector z = Conversions.encode(n, t, c5); // compute encC4 = E(c4, z) byte[] encC4 = McElieceCCA2Primitives.encryptionPrimitive((McElieceCCA2PublicKeyParameters)key, c4Vec, z).getEncoded(); // if c6Len > 0 if (c6Len > 0) { // return (c6||encC4) return ByteUtils.concatenate(c6, encC4); } // else, return encC4 return encC4; } public byte[] messageDecrypt(byte[] input) throws Exception { int nDiv8 = n >> 3; if (input.length < nDiv8) { throw new Exception("Bad Padding: Ciphertext too short."); } int c2Len = messDigest.getDigestSize(); int c4Len = k >> 3; int c6Len = input.length - nDiv8; // split cipher text (c6||encC4), where c6 may be empty byte[] c6, encC4; if (c6Len > 0) { byte[][] c6EncC4 = ByteUtils.split(input, c6Len); c6 = c6EncC4[0]; encC4 = c6EncC4[1]; } else { c6 = new byte[0]; encC4 = input; } // convert encC4 into vector over GF(2) GF2Vector encC4Vec = GF2Vector.OS2VP(n, encC4); // decrypt encC4Vec to obtain c4 and error vector z GF2Vector[] c4z = McElieceCCA2Primitives.decryptionPrimitive((McElieceCCA2PrivateKeyParameters)key, encC4Vec); byte[] c4 = c4z[0].getEncoded(); GF2Vector z = c4z[1]; // if length of c4 is greater than c4Len (because of padding) ... if (c4.length > c4Len) { // ... truncate the padding bytes c4 = ByteUtils.subArray(c4, 0, c4Len); } // compute c5 = Conv^-1(z) byte[] c5 = Conversions.decode(n, t, z); // compute (c6||c5||c4) byte[] c6c5c4 = ByteUtils.concatenate(c6, c5); c6c5c4 = ByteUtils.concatenate(c6c5c4, c4); // split (c6||c5||c4) into (c2||c1), where c2Len = mdLen and c1Len = // input.length-c2Len bytes. int c1Len = c6c5c4.length - c2Len; byte[][] c2c1 = ByteUtils.split(c6c5c4, c2Len); byte[] c2 = c2c1[0]; byte[] c1 = c2c1[1]; // compute H(c1) ... byte[] rPrime = new byte[messDigest.getDigestSize()]; messDigest.update(c1, 0, c1.length); messDigest.doFinal(rPrime, 0); // ... and XOR with c2 to obtain r' for (int i = c2Len - 1; i >= 0; i--) { rPrime[i] ^= c2[i]; } // get PRNG object DigestRandomGenerator sr0 = new DigestRandomGenerator(new SHA1Digest()); // seed PRNG with r' sr0.addSeedMaterial(rPrime); // generate random sequence R(r') ... byte[] mConstPrime = new byte[c1Len]; sr0.nextBytes(mConstPrime); // ... and XOR with c1 to obtain (m||const') for (int i = c1Len - 1; i >= 0; i--) { mConstPrime[i] ^= c1[i]; } if (mConstPrime.length < c1Len) { throw new Exception("Bad Padding: invalid ciphertext"); } byte[][] temp = ByteUtils.split(mConstPrime, c1Len - PUBLIC_CONSTANT.length); byte[] mr = temp[0]; byte[] constPrime = temp[1]; if (!ByteUtils.equals(constPrime, PUBLIC_CONSTANT)) { throw new Exception("Bad Padding: invalid ciphertext"); } return mr; } } bouncycastle-1.49.orig/src/org/bouncycastle/pqc/crypto/mceliece/McEliecePrivateKeyParameters.java0000644000175000017500000001322612043365371032724 0ustar ebourgebourgpackage org.bouncycastle.pqc.crypto.mceliece; import org.bouncycastle.pqc.math.linearalgebra.GF2Matrix; import org.bouncycastle.pqc.math.linearalgebra.GF2mField; import org.bouncycastle.pqc.math.linearalgebra.Permutation; import org.bouncycastle.pqc.math.linearalgebra.PolynomialGF2mSmallM; public class McEliecePrivateKeyParameters extends McElieceKeyParameters { // the OID of the algorithm private String oid; // the length of the code private int n; // the dimension of the code, where k >= n - mt private int k; // the underlying finite field private GF2mField field; // the irreducible Goppa polynomial private PolynomialGF2mSmallM goppaPoly; // a k x k random binary non-singular matrix private GF2Matrix sInv; // the permutation used to generate the systematic check matrix private Permutation p1; // the permutation used to compute the public generator matrix private Permutation p2; // the canonical check matrix of the code private GF2Matrix h; // the matrix used to compute square roots in (GF(2^m))^t private PolynomialGF2mSmallM[] qInv; /** * Constructor. * * @param oid * @param n the length of the code * @param k the dimension of the code * @param field the field polynomial defining the finite field * GF(2m) * @param goppaPoly the irreducible Goppa polynomial * @param sInv the matrix S-1 * @param p1 the permutation used to generate the systematic check * matrix * @param p2 the permutation used to compute the public generator * matrix * @param h the canonical check matrix * @param qInv the matrix used to compute square roots in * (GF(2m))t * @param params McElieceParameters */ public McEliecePrivateKeyParameters(String oid, int n, int k, GF2mField field, PolynomialGF2mSmallM goppaPoly, GF2Matrix sInv, Permutation p1, Permutation p2, GF2Matrix h, PolynomialGF2mSmallM[] qInv, McElieceParameters params) { super(true, params); this.oid = oid; this.k = k; this.n = n; this.field = field; this.goppaPoly = goppaPoly; this.sInv = sInv; this.p1 = p1; this.p2 = p2; this.h = h; this.qInv = qInv; } /** * Constructor (used by the {@link McElieceKeyFactory}). * * @param oid * @param n the length of the code * @param k the dimension of the code * @param encField the encoded field polynomial defining the finite field * GF(2m) * @param encGoppaPoly the encoded irreducible Goppa polynomial * @param encSInv the encoded matrix S-1 * @param encP1 the encoded permutation used to generate the systematic * check matrix * @param encP2 the encoded permutation used to compute the public * generator matrix * @param encH the encoded canonical check matrix * @param encQInv the encoded matrix used to compute square roots in * (GF(2m))t * @param params McElieceParameters */ public McEliecePrivateKeyParameters(String oid, int n, int k, byte[] encField, byte[] encGoppaPoly, byte[] encSInv, byte[] encP1, byte[] encP2, byte[] encH, byte[][] encQInv, McElieceParameters params) { super(true, params); this.oid = oid; this.n = n; this.k = k; field = new GF2mField(encField); goppaPoly = new PolynomialGF2mSmallM(field, encGoppaPoly); sInv = new GF2Matrix(encSInv); p1 = new Permutation(encP1); p2 = new Permutation(encP2); h = new GF2Matrix(encH); qInv = new PolynomialGF2mSmallM[encQInv.length]; for (int i = 0; i < encQInv.length; i++) { qInv[i] = new PolynomialGF2mSmallM(field, encQInv[i]); } } /** * @return the length of the code */ public int getN() { return n; } /** * @return the dimension of the code */ public int getK() { return k; } /** * @return the finite field GF(2m) */ public GF2mField getField() { return field; } /** * @return the irreducible Goppa polynomial */ public PolynomialGF2mSmallM getGoppaPoly() { return goppaPoly; } /** * @return the k x k random binary non-singular matrix S^-1 */ public GF2Matrix getSInv() { return sInv; } /** * @return the permutation used to generate the systematic check matrix */ public Permutation getP1() { return p1; } /** * @return the permutation used to compute the public generator matrix */ public Permutation getP2() { return p2; } /** * @return the canonical check matrix H */ public GF2Matrix getH() { return h; } /** * @return the matrix used to compute square roots in * (GF(2m))t */ public PolynomialGF2mSmallM[] getQInv() { return qInv; } public String getOIDString() { return oid; } } bouncycastle-1.49.orig/src/org/bouncycastle/pqc/crypto/mceliece/McEliecePKCSDigestCipher.java0000644000175000017500000000523712043374601031647 0ustar ebourgebourgpackage org.bouncycastle.pqc.crypto.mceliece; import org.bouncycastle.crypto.CipherParameters; import org.bouncycastle.crypto.Digest; import org.bouncycastle.crypto.params.AsymmetricKeyParameter; import org.bouncycastle.crypto.params.ParametersWithRandom; import org.bouncycastle.pqc.crypto.MessageEncryptor; // TODO should implement some interface? public class McEliecePKCSDigestCipher { private final Digest messDigest; private final MessageEncryptor mcElieceCipher; private boolean forEncrypting; public McEliecePKCSDigestCipher(MessageEncryptor mcElieceCipher, Digest messDigest) { this.mcElieceCipher = mcElieceCipher; this.messDigest = messDigest; } public void init(boolean forEncrypting, CipherParameters param) { this.forEncrypting = forEncrypting; AsymmetricKeyParameter k; if (param instanceof ParametersWithRandom) { k = (AsymmetricKeyParameter)((ParametersWithRandom)param).getParameters(); } else { k = (AsymmetricKeyParameter)param; } if (forEncrypting && k.isPrivate()) { throw new IllegalArgumentException("Encrypting Requires Public Key."); } if (!forEncrypting && !k.isPrivate()) { throw new IllegalArgumentException("Decrypting Requires Private Key."); } reset(); mcElieceCipher.init(forEncrypting, param); } public byte[] messageEncrypt() { if (!forEncrypting) { throw new IllegalStateException("McEliecePKCSDigestCipher not initialised for encrypting."); } byte[] hash = new byte[messDigest.getDigestSize()]; messDigest.doFinal(hash, 0); byte[] enc = null; try { enc = mcElieceCipher.messageEncrypt(hash); } catch (Exception e) { e.printStackTrace(); } return enc; } public byte[] messageDecrypt(byte[] ciphertext) { byte[] output = null; if (forEncrypting) { throw new IllegalStateException("McEliecePKCSDigestCipher not initialised for decrypting."); } try { output = mcElieceCipher.messageDecrypt(ciphertext); } catch (Exception e) { e.printStackTrace(); } return output; } public void update(byte b) { messDigest.update(b); } public void update(byte[] in, int off, int len) { messDigest.update(in, off, len); } public void reset() { messDigest.reset(); } } bouncycastle-1.49.orig/src/org/bouncycastle/pqc/crypto/mceliece/McElieceKeyParameters.java0000644000175000017500000000073112043365070031362 0ustar ebourgebourgpackage org.bouncycastle.pqc.crypto.mceliece; import org.bouncycastle.crypto.params.AsymmetricKeyParameter; public class McElieceKeyParameters extends AsymmetricKeyParameter { private McElieceParameters params; public McElieceKeyParameters( boolean isPrivate, McElieceParameters params) { super(isPrivate); this.params = params; } public McElieceParameters getParameters() { return params; } } bouncycastle-1.49.orig/src/org/bouncycastle/pqc/crypto/mceliece/McElieceCCA2Primitives.java0000644000175000017500000000515712045605136031343 0ustar ebourgebourgpackage org.bouncycastle.pqc.crypto.mceliece; import org.bouncycastle.pqc.math.linearalgebra.GF2Matrix; import org.bouncycastle.pqc.math.linearalgebra.GF2Vector; import org.bouncycastle.pqc.math.linearalgebra.GF2mField; import org.bouncycastle.pqc.math.linearalgebra.GoppaCode; import org.bouncycastle.pqc.math.linearalgebra.Permutation; import org.bouncycastle.pqc.math.linearalgebra.PolynomialGF2mSmallM; import org.bouncycastle.pqc.math.linearalgebra.Vector; /** * Core operations for the CCA-secure variants of McEliece. */ public final class McElieceCCA2Primitives { /** * Default constructor (private). */ private McElieceCCA2Primitives() { } /** * The McEliece encryption primitive. * * @param pubKey the public key * @param m the message vector * @param z the error vector * @return m*G + z */ public static GF2Vector encryptionPrimitive(McElieceCCA2PublicKeyParameters pubKey, GF2Vector m, GF2Vector z) { GF2Matrix matrixG = pubKey.getMatrixG(); Vector mG = matrixG.leftMultiplyLeftCompactForm(m); return (GF2Vector)mG.add(z); } /** * The McEliece decryption primitive. * * @param privKey the private key * @param c the ciphertext vector c = m*G + z * @return the message vector m and the error vector z */ public static GF2Vector[] decryptionPrimitive( McElieceCCA2PrivateKeyParameters privKey, GF2Vector c) { // obtain values from private key int k = privKey.getK(); Permutation p = privKey.getP(); GF2mField field = privKey.getField(); PolynomialGF2mSmallM gp = privKey.getGoppaPoly(); GF2Matrix h = privKey.getH(); PolynomialGF2mSmallM[] q = privKey.getQInv(); // compute inverse permutation P^-1 Permutation pInv = p.computeInverse(); // multiply c with permutation P^-1 GF2Vector cPInv = (GF2Vector)c.multiply(pInv); // compute syndrome of cP^-1 GF2Vector syndVec = (GF2Vector)h.rightMultiply(cPInv); // decode syndrome GF2Vector errors = GoppaCode.syndromeDecode(syndVec, field, gp, q); GF2Vector mG = (GF2Vector)cPInv.add(errors); // multiply codeword and error vector with P mG = (GF2Vector)mG.multiply(p); errors = (GF2Vector)errors.multiply(p); // extract plaintext vector (last k columns of mG) GF2Vector m = mG.extractRightVector(k); // return vectors return new GF2Vector[]{m, errors}; } } bouncycastle-1.49.orig/src/org/bouncycastle/pqc/crypto/mceliece/McElieceFujisakiDigestCipher.java0000644000175000017500000000531312043660545032654 0ustar ebourgebourgpackage org.bouncycastle.pqc.crypto.mceliece; import org.bouncycastle.crypto.CipherParameters; import org.bouncycastle.crypto.Digest; import org.bouncycastle.crypto.params.AsymmetricKeyParameter; import org.bouncycastle.crypto.params.ParametersWithRandom; import org.bouncycastle.pqc.crypto.MessageEncryptor; // TODO should implement some interface? public class McElieceFujisakiDigestCipher { private final Digest messDigest; private final MessageEncryptor mcElieceCCA2Cipher; private boolean forEncrypting; public McElieceFujisakiDigestCipher(MessageEncryptor mcElieceCCA2Cipher, Digest messDigest) { this.mcElieceCCA2Cipher = mcElieceCCA2Cipher; this.messDigest = messDigest; } public void init(boolean forEncrypting, CipherParameters param) { this.forEncrypting = forEncrypting; AsymmetricKeyParameter k; if (param instanceof ParametersWithRandom) { k = (AsymmetricKeyParameter)((ParametersWithRandom)param).getParameters(); } else { k = (AsymmetricKeyParameter)param; } if (forEncrypting && k.isPrivate()) { throw new IllegalArgumentException("Encrypting Requires Public Key."); } if (!forEncrypting && !k.isPrivate()) { throw new IllegalArgumentException("Decrypting Requires Private Key."); } reset(); mcElieceCCA2Cipher.init(forEncrypting, param); } public byte[] messageEncrypt() { if (!forEncrypting) { throw new IllegalStateException("McElieceFujisakiDigestCipher not initialised for encrypting."); } byte[] hash = new byte[messDigest.getDigestSize()]; messDigest.doFinal(hash, 0); byte[] enc = null; try { enc = mcElieceCCA2Cipher.messageEncrypt(hash); } catch (Exception e) { e.printStackTrace(); } return enc; } public byte[] messageDecrypt(byte[] ciphertext) { byte[] output = null; if (forEncrypting) { throw new IllegalStateException("McElieceFujisakiDigestCipher not initialised for decrypting."); } try { output = mcElieceCCA2Cipher.messageDecrypt(ciphertext); } catch (Exception e) { e.printStackTrace(); } return output; } public void update(byte b) { messDigest.update(b); } public void update(byte[] in, int off, int len) { messDigest.update(in, off, len); } public void reset() { messDigest.reset(); } } ././@LongLink0000000000000000000000000000015100000000000011562 Lustar rootrootbouncycastle-1.49.orig/src/org/bouncycastle/pqc/crypto/mceliece/McElieceCCA2KeyGenerationParameters.javabouncycastle-1.49.orig/src/org/bouncycastle/pqc/crypto/mceliece/McElieceCCA2KeyGenerationParameters.0000644000175000017500000000107212043365070033124 0ustar ebourgebourgpackage org.bouncycastle.pqc.crypto.mceliece; import java.security.SecureRandom; import org.bouncycastle.crypto.KeyGenerationParameters; public class McElieceCCA2KeyGenerationParameters extends KeyGenerationParameters { private McElieceCCA2Parameters params; public McElieceCCA2KeyGenerationParameters( SecureRandom random, McElieceCCA2Parameters params) { // XXX key size? super(random, 128); this.params = params; } public McElieceCCA2Parameters getParameters() { return params; } } bouncycastle-1.49.orig/src/org/bouncycastle/pqc/crypto/mceliece/McElieceCCA2PublicKeyParameters.java0000644000175000017500000000377412043365371033130 0ustar ebourgebourgpackage org.bouncycastle.pqc.crypto.mceliece; import org.bouncycastle.pqc.math.linearalgebra.GF2Matrix; /** * * * */ public class McElieceCCA2PublicKeyParameters extends McElieceCCA2KeyParameters { // the OID of the algorithm private String oid; // the length of the code private int n; // the error correction capability of the code private int t; // the generator matrix private GF2Matrix matrixG; /** * Constructor. * * @param n length of the code * @param t error correction capability * @param matrix generator matrix * @param params McElieceCCA2Parameters */ public McElieceCCA2PublicKeyParameters(String oid, int n, int t, GF2Matrix matrix, McElieceCCA2Parameters params) { super(false, params); this.oid = oid; this.n = n; this.t = t; this.matrixG = new GF2Matrix(matrix); } /** * Constructor (used by {@link McElieceKeyFactory}). * * @param n length of the code * @param t error correction capability of the code * @param encMatrix encoded generator matrix * @param params McElieceCCA2Parameters */ public McElieceCCA2PublicKeyParameters(String oid, int n, int t, byte[] encMatrix, McElieceCCA2Parameters params) { super(false, params); this.oid = oid; this.n = n; this.t = t; this.matrixG = new GF2Matrix(encMatrix); } /** * @return the length of the code */ public int getN() { return n; } /** * @return the error correction capability of the code */ public int getT() { return t; } /** * @return the generator matrix */ public GF2Matrix getMatrixG() { return matrixG; } /** * @return the dimension of the code */ public int getK() { return matrixG.getNumRows(); } public String getOIDString() { return oid; } } bouncycastle-1.49.orig/src/org/bouncycastle/pqc/crypto/mceliece/McElieceKeyPairGenerator.java0000644000175000017500000001117512043367271032032 0ustar ebourgebourgpackage org.bouncycastle.pqc.crypto.mceliece; import java.security.SecureRandom; import org.bouncycastle.crypto.AsymmetricCipherKeyPair; import org.bouncycastle.crypto.AsymmetricCipherKeyPairGenerator; import org.bouncycastle.crypto.KeyGenerationParameters; import org.bouncycastle.pqc.math.linearalgebra.GF2Matrix; import org.bouncycastle.pqc.math.linearalgebra.GF2mField; import org.bouncycastle.pqc.math.linearalgebra.GoppaCode; import org.bouncycastle.pqc.math.linearalgebra.GoppaCode.MaMaPe; import org.bouncycastle.pqc.math.linearalgebra.Permutation; import org.bouncycastle.pqc.math.linearalgebra.PolynomialGF2mSmallM; import org.bouncycastle.pqc.math.linearalgebra.PolynomialRingGF2m; /** * This class implements key pair generation of the McEliece Public Key * Cryptosystem (McEliecePKC). */ public class McElieceKeyPairGenerator implements AsymmetricCipherKeyPairGenerator { public McElieceKeyPairGenerator() { } /** * The OID of the algorithm. */ private static final String OID = "1.3.6.1.4.1.8301.3.1.3.4.1"; private McElieceKeyGenerationParameters mcElieceParams; // the extension degree of the finite field GF(2^m) private int m; // the length of the code private int n; // the error correction capability private int t; // the field polynomial private int fieldPoly; // the source of randomness private SecureRandom random; // flag indicating whether the key pair generator has been initialized private boolean initialized = false; /** * Default initialization of the key pair generator. */ private void initializeDefault() { McElieceKeyGenerationParameters mcParams = new McElieceKeyGenerationParameters(new SecureRandom(), new McElieceParameters()); initialize(mcParams); } private void initialize( KeyGenerationParameters param) { this.mcElieceParams = (McElieceKeyGenerationParameters)param; // set source of randomness this.random = new SecureRandom(); this.m = this.mcElieceParams.getParameters().getM(); this.n = this.mcElieceParams.getParameters().getN(); this.t = this.mcElieceParams.getParameters().getT(); this.fieldPoly = this.mcElieceParams.getParameters().getFieldPoly(); this.initialized = true; } private AsymmetricCipherKeyPair genKeyPair() { if (!initialized) { initializeDefault(); } // finite field GF(2^m) GF2mField field = new GF2mField(m, fieldPoly); // irreducible Goppa polynomial PolynomialGF2mSmallM gp = new PolynomialGF2mSmallM(field, t, PolynomialGF2mSmallM.RANDOM_IRREDUCIBLE_POLYNOMIAL, random); PolynomialRingGF2m ring = new PolynomialRingGF2m(field, gp); // matrix used to compute square roots in (GF(2^m))^t PolynomialGF2mSmallM[] sqRootMatrix = ring.getSquareRootMatrix(); // generate canonical check matrix GF2Matrix h = GoppaCode.createCanonicalCheckMatrix(field, gp); // compute short systematic form of check matrix MaMaPe mmp = GoppaCode.computeSystematicForm(h, random); GF2Matrix shortH = mmp.getSecondMatrix(); Permutation p1 = mmp.getPermutation(); // compute short systematic form of generator matrix GF2Matrix shortG = (GF2Matrix)shortH.computeTranspose(); // extend to full systematic form GF2Matrix gPrime = shortG.extendLeftCompactForm(); // obtain number of rows of G (= dimension of the code) int k = shortG.getNumRows(); // generate random invertible (k x k)-matrix S and its inverse S^-1 GF2Matrix[] matrixSandInverse = GF2Matrix .createRandomRegularMatrixAndItsInverse(k, random); // generate random permutation P2 Permutation p2 = new Permutation(n, random); // compute public matrix G=S*G'*P2 GF2Matrix g = (GF2Matrix)matrixSandInverse[0].rightMultiply(gPrime); g = (GF2Matrix)g.rightMultiply(p2); // generate keys McEliecePublicKeyParameters pubKey = new McEliecePublicKeyParameters(OID, n, t, g, mcElieceParams.getParameters()); McEliecePrivateKeyParameters privKey = new McEliecePrivateKeyParameters(OID, n, k, field, gp, matrixSandInverse[1], p1, p2, h, sqRootMatrix, mcElieceParams.getParameters()); // return key pair return new AsymmetricCipherKeyPair(pubKey, privKey); } public void init(KeyGenerationParameters param) { this.initialize(param); } public AsymmetricCipherKeyPair generateKeyPair() { return genKeyPair(); } } bouncycastle-1.49.orig/src/org/bouncycastle/pqc/crypto/mceliece/McEliecePointchevalDigestCipher.java0000644000175000017500000000532712045605570033367 0ustar ebourgebourgpackage org.bouncycastle.pqc.crypto.mceliece; import org.bouncycastle.crypto.CipherParameters; import org.bouncycastle.crypto.Digest; import org.bouncycastle.crypto.params.AsymmetricKeyParameter; import org.bouncycastle.crypto.params.ParametersWithRandom; import org.bouncycastle.pqc.crypto.MessageEncryptor; // TODO should implement some interface? public class McEliecePointchevalDigestCipher { private final Digest messDigest; private final MessageEncryptor mcElieceCCA2Cipher; private boolean forEncrypting; public McEliecePointchevalDigestCipher(MessageEncryptor mcElieceCCA2Cipher, Digest messDigest) { this.mcElieceCCA2Cipher = mcElieceCCA2Cipher; this.messDigest = messDigest; } public void init(boolean forEncrypting, CipherParameters param) { this.forEncrypting = forEncrypting; AsymmetricKeyParameter k; if (param instanceof ParametersWithRandom) { k = (AsymmetricKeyParameter)((ParametersWithRandom)param).getParameters(); } else { k = (AsymmetricKeyParameter)param; } if (forEncrypting && k.isPrivate()) { throw new IllegalArgumentException("Encrypting Requires Public Key."); } if (!forEncrypting && !k.isPrivate()) { throw new IllegalArgumentException("Decrypting Requires Private Key."); } reset(); mcElieceCCA2Cipher.init(forEncrypting, param); } public byte[] messageEncrypt() { if (!forEncrypting) { throw new IllegalStateException("McEliecePointchevalDigestCipher not initialised for encrypting."); } byte[] hash = new byte[messDigest.getDigestSize()]; messDigest.doFinal(hash, 0); byte[] enc = null; try { enc = mcElieceCCA2Cipher.messageEncrypt(hash); } catch (Exception e) { e.printStackTrace(); } return enc; } public byte[] messageDecrypt(byte[] ciphertext) { byte[] output = null; if (forEncrypting) { throw new IllegalStateException("McEliecePointchevalDigestCipher not initialised for decrypting."); } try { output = mcElieceCCA2Cipher.messageDecrypt(ciphertext); } catch (Exception e) { e.printStackTrace(); } return output; } public void update(byte b) { messDigest.update(b); } public void update(byte[] in, int off, int len) { messDigest.update(in, off, len); } public void reset() { messDigest.reset(); } } bouncycastle-1.49.orig/src/org/bouncycastle/pqc/crypto/mceliece/McEliecePKCSCipher.java0000644000175000017500000001500712105356341030503 0ustar ebourgebourgpackage org.bouncycastle.pqc.crypto.mceliece; import java.security.SecureRandom; import org.bouncycastle.crypto.CipherParameters; import org.bouncycastle.crypto.params.ParametersWithRandom; import org.bouncycastle.pqc.crypto.MessageEncryptor; import org.bouncycastle.pqc.math.linearalgebra.GF2Matrix; import org.bouncycastle.pqc.math.linearalgebra.GF2Vector; import org.bouncycastle.pqc.math.linearalgebra.GF2mField; import org.bouncycastle.pqc.math.linearalgebra.GoppaCode; import org.bouncycastle.pqc.math.linearalgebra.Permutation; import org.bouncycastle.pqc.math.linearalgebra.PolynomialGF2mSmallM; import org.bouncycastle.pqc.math.linearalgebra.Vector; /** * This class implements the McEliece Public Key cryptosystem (McEliecePKCS). It * was first described in R.J. McEliece, "A public key cryptosystem based on * algebraic coding theory", DSN progress report, 42-44:114-116, 1978. The * McEliecePKCS is the first cryptosystem which is based on error correcting * codes. The trapdoor for the McEliece cryptosystem using Goppa codes is the * knowledge of the Goppa polynomial used to generate the code. */ public class McEliecePKCSCipher implements MessageEncryptor { /** * The OID of the algorithm. */ public static final String OID = "1.3.6.1.4.1.8301.3.1.3.4.1"; // the source of randomness private SecureRandom sr; // the McEliece main parameters private int n, k, t; // The maximum number of bytes the cipher can decrypt public int maxPlainTextSize; // The maximum number of bytes the cipher can encrypt public int cipherTextSize; McElieceKeyParameters key; public void init(boolean forSigning, CipherParameters param) { if (forSigning) { if (param instanceof ParametersWithRandom) { ParametersWithRandom rParam = (ParametersWithRandom)param; this.sr = rParam.getRandom(); this.key = (McEliecePublicKeyParameters)rParam.getParameters(); this.initCipherEncrypt((McEliecePublicKeyParameters)key); } else { this.sr = new SecureRandom(); this.key = (McEliecePublicKeyParameters)param; this.initCipherEncrypt((McEliecePublicKeyParameters)key); } } else { this.key = (McEliecePrivateKeyParameters)param; this.initCipherDecrypt((McEliecePrivateKeyParameters)key); } } /** * Return the key size of the given key object. * * @param key the McElieceKeyParameters object * @return the keysize of the given key object */ public int getKeySize(McElieceKeyParameters key) { if (key instanceof McEliecePublicKeyParameters) { return ((McEliecePublicKeyParameters)key).getN(); } if (key instanceof McEliecePrivateKeyParameters) { return ((McEliecePrivateKeyParameters)key).getN(); } throw new IllegalArgumentException("unsupported type"); } public void initCipherEncrypt(McEliecePublicKeyParameters pubKey) { this.sr = sr != null ? sr : new SecureRandom(); n = pubKey.getN(); k = pubKey.getK(); t = pubKey.getT(); cipherTextSize = n >> 3; maxPlainTextSize = (k >> 3); } public void initCipherDecrypt(McEliecePrivateKeyParameters privKey) { n = privKey.getN(); k = privKey.getK(); maxPlainTextSize = (k >> 3); cipherTextSize = n >> 3; } /** * Encrypt a plain text. * * @param input the plain text * @return the cipher text */ public byte[] messageEncrypt(byte[] input) { GF2Vector m = computeMessageRepresentative(input); GF2Vector z = new GF2Vector(n, t, sr); GF2Matrix g = ((McEliecePublicKeyParameters)key).getG(); Vector mG = g.leftMultiply(m); GF2Vector mGZ = (GF2Vector)mG.add(z); return mGZ.getEncoded(); } private GF2Vector computeMessageRepresentative(byte[] input) { byte[] data = new byte[maxPlainTextSize + ((k & 0x07) != 0 ? 1 : 0)]; System.arraycopy(input, 0, data, 0, input.length); data[input.length] = 0x01; return GF2Vector.OS2VP(k, data); } /** * Decrypt a cipher text. * * @param input the cipher text * @return the plain text * @throws Exception if the cipher text is invalid. */ public byte[] messageDecrypt(byte[] input) throws Exception { GF2Vector vec = GF2Vector.OS2VP(n, input); McEliecePrivateKeyParameters privKey = (McEliecePrivateKeyParameters)key; GF2mField field = privKey.getField(); PolynomialGF2mSmallM gp = privKey.getGoppaPoly(); GF2Matrix sInv = privKey.getSInv(); Permutation p1 = privKey.getP1(); Permutation p2 = privKey.getP2(); GF2Matrix h = privKey.getH(); PolynomialGF2mSmallM[] qInv = privKey.getQInv(); // compute permutation P = P1 * P2 Permutation p = p1.rightMultiply(p2); // compute P^-1 Permutation pInv = p.computeInverse(); // compute c P^-1 GF2Vector cPInv = (GF2Vector)vec.multiply(pInv); // compute syndrome of c P^-1 GF2Vector syndrome = (GF2Vector)h.rightMultiply(cPInv); // decode syndrome GF2Vector z = GoppaCode.syndromeDecode(syndrome, field, gp, qInv); GF2Vector mSG = (GF2Vector)cPInv.add(z); // multiply codeword with P1 and error vector with P mSG = (GF2Vector)mSG.multiply(p1); z = (GF2Vector)z.multiply(p); // extract mS (last k columns of mSG) GF2Vector mS = mSG.extractRightVector(k); // compute plaintext vector GF2Vector mVec = (GF2Vector)sInv.leftMultiply(mS); // compute and return plaintext return computeMessage(mVec); } private byte[] computeMessage(GF2Vector mr) throws Exception { byte[] mrBytes = mr.getEncoded(); // find first non-zero byte int index; for (index = mrBytes.length - 1; index >= 0 && mrBytes[index] == 0; index--) { ; } // check if padding byte is valid if (mrBytes[index] != 0x01) { throw new Exception("Bad Padding: invalid ciphertext"); } // extract and return message byte[] mBytes = new byte[index]; System.arraycopy(mrBytes, 0, mBytes, 0, index); return mBytes; } } ././@LongLink0000000000000000000000000000014600000000000011566 Lustar rootrootbouncycastle-1.49.orig/src/org/bouncycastle/pqc/crypto/mceliece/McElieceCCA2PrivateKeyParameters.javabouncycastle-1.49.orig/src/org/bouncycastle/pqc/crypto/mceliece/McElieceCCA2PrivateKeyParameters.jav0000644000175000017500000001052212043365070033144 0ustar ebourgebourgpackage org.bouncycastle.pqc.crypto.mceliece; import org.bouncycastle.pqc.math.linearalgebra.GF2Matrix; import org.bouncycastle.pqc.math.linearalgebra.GF2mField; import org.bouncycastle.pqc.math.linearalgebra.Permutation; import org.bouncycastle.pqc.math.linearalgebra.PolynomialGF2mSmallM; /** * * * */ public class McElieceCCA2PrivateKeyParameters extends McElieceCCA2KeyParameters { // the OID of the algorithm private String oid; // the length of the code private int n; // the dimension of the code private int k; // the finte field GF(2^m) private GF2mField field; // the irreducible Goppa polynomial private PolynomialGF2mSmallM goppaPoly; // the permutation private Permutation p; // the canonical check matrix private GF2Matrix h; // the matrix used to compute square roots in (GF(2^m))^t private PolynomialGF2mSmallM[] qInv; /** * Constructor. * * @param n the length of the code * @param k the dimension of the code * @param field the finite field GF(2m) * @param gp the irreducible Goppa polynomial * @param p the permutation * @param h the canonical check matrix * @param qInv the matrix used to compute square roots in * (GF(2^m))^t * @param params McElieceCCA2Parameters */ public McElieceCCA2PrivateKeyParameters(String oid, int n, int k, GF2mField field, PolynomialGF2mSmallM gp, Permutation p, GF2Matrix h, PolynomialGF2mSmallM[] qInv, McElieceCCA2Parameters params) { super(true, params); this.oid = oid; this.n = n; this.k = k; this.field = field; this.goppaPoly = gp; this.p = p; this.h = h; this.qInv = qInv; } /** * Constructor used by the {@link McElieceKeyFactory}. * * @param n the length of the code * @param k the dimension of the code * @param encFieldPoly the encoded field polynomial defining the finite field * GF(2m) * @param encGoppaPoly the encoded irreducible Goppa polynomial * @param encP the encoded permutation * @param encH the encoded canonical check matrix * @param encQInv the encoded matrix used to compute square roots in * (GF(2^m))^t * @param params McElieceCCA2Parameters */ public McElieceCCA2PrivateKeyParameters(String oid, int n, int k, byte[] encFieldPoly, byte[] encGoppaPoly, byte[] encP, byte[] encH, byte[][] encQInv, McElieceCCA2Parameters params) { super(true, params); this.oid = oid; this.n = n; this.k = k; field = new GF2mField(encFieldPoly); goppaPoly = new PolynomialGF2mSmallM(field, encGoppaPoly); p = new Permutation(encP); h = new GF2Matrix(encH); qInv = new PolynomialGF2mSmallM[encQInv.length]; for (int i = 0; i < encQInv.length; i++) { qInv[i] = new PolynomialGF2mSmallM(field, encQInv[i]); } } /** * @return the length of the code */ public int getN() { return n; } /** * @return the dimension of the code */ public int getK() { return k; } /** * @return the degree of the Goppa polynomial (error correcting capability) */ public int getT() { return goppaPoly.getDegree(); } /** * @return the finite field */ public GF2mField getField() { return field; } /** * @return the irreducible Goppa polynomial */ public PolynomialGF2mSmallM getGoppaPoly() { return goppaPoly; } /** * @return the permutation P */ public Permutation getP() { return p; } /** * @return the canonical check matrix H */ public GF2Matrix getH() { return h; } /** * @return the matrix used to compute square roots in (GF(2^m))^t */ public PolynomialGF2mSmallM[] getQInv() { return qInv; } public String getOIDString() { return oid; } } bouncycastle-1.49.orig/src/org/bouncycastle/pqc/crypto/mceliece/McEliecePublicKeyParameters.java0000644000175000017500000000376612043365371032540 0ustar ebourgebourgpackage org.bouncycastle.pqc.crypto.mceliece; import org.bouncycastle.pqc.math.linearalgebra.GF2Matrix; public class McEliecePublicKeyParameters extends McElieceKeyParameters { // the OID of the algorithm private String oid; // the length of the code private int n; // the error correction capability of the code private int t; // the generator matrix private GF2Matrix g; /** * Constructor (used by {@link McElieceKeyFactory}). * * @param oid * @param n the length of the code * @param t the error correction capability of the code * @param g the generator matrix * @param params McElieceParameters */ public McEliecePublicKeyParameters(String oid, int n, int t, GF2Matrix g, McElieceParameters params) { super(false, params); this.oid = oid; this.n = n; this.t = t; this.g = new GF2Matrix(g); } /** * Constructor (used by {@link McElieceKeyFactory}). * * @param oid * @param n the length of the code * @param t the error correction capability of the code * @param encG the encoded generator matrix * @param params McElieceParameters */ public McEliecePublicKeyParameters(String oid, int t, int n, byte[] encG, McElieceParameters params) { super(false, params); this.oid = oid; this.n = n; this.t = t; this.g = new GF2Matrix(encG); } /** * @return the length of the code */ public int getN() { return n; } /** * @return the error correction capability of the code */ public int getT() { return t; } /** * @return the generator matrix */ public GF2Matrix getG() { return g; } public String getOIDString() { return oid; } /** * @return the dimension of the code */ public int getK() { return g.getNumRows(); } } bouncycastle-1.49.orig/src/org/bouncycastle/pqc/crypto/mceliece/McElieceParameters.java0000644000175000017500000001024312105356151030707 0ustar ebourgebourgpackage org.bouncycastle.pqc.crypto.mceliece; import org.bouncycastle.crypto.CipherParameters; import org.bouncycastle.pqc.math.linearalgebra.PolynomialRingGF2; public class McElieceParameters implements CipherParameters { /** * The default extension degree */ public static final int DEFAULT_M = 11; /** * The default error correcting capability. */ public static final int DEFAULT_T = 50; /** * extension degree of the finite field GF(2^m) */ private int m; /** * error correction capability of the code */ private int t; /** * length of the code */ private int n; /** * the field polynomial */ private int fieldPoly; /** * Constructor. Set the default parameters: extension degree. */ public McElieceParameters() { this(DEFAULT_M, DEFAULT_T); } /** * Constructor. * * @param keysize the length of a Goppa code * @throws IllegalArgumentException if keysize < 1. */ public McElieceParameters(int keysize) throws IllegalArgumentException { if (keysize < 1) { throw new IllegalArgumentException("key size must be positive"); } m = 0; n = 1; while (n < keysize) { n <<= 1; m++; } t = n >>> 1; t /= m; fieldPoly = PolynomialRingGF2.getIrreduciblePolynomial(m); } /** * Constructor. * * @param m degree of the finite field GF(2^m) * @param t error correction capability of the code * @throws IllegalArgumentException if m < 1 or m > 32 or * t < 0 or t > n. */ public McElieceParameters(int m, int t) throws IllegalArgumentException { if (m < 1) { throw new IllegalArgumentException("m must be positive"); } if (m > 32) { throw new IllegalArgumentException("m is too large"); } this.m = m; n = 1 << m; if (t < 0) { throw new IllegalArgumentException("t must be positive"); } if (t > n) { throw new IllegalArgumentException("t must be less than n = 2^m"); } this.t = t; fieldPoly = PolynomialRingGF2.getIrreduciblePolynomial(m); } /** * Constructor. * * @param m degree of the finite field GF(2^m) * @param t error correction capability of the code * @param poly the field polynomial * @throws IllegalArgumentException if m < 1 or m > 32 or * t < 0 or t > n or * poly is not an irreducible field polynomial. */ public McElieceParameters(int m, int t, int poly) throws IllegalArgumentException { this.m = m; if (m < 1) { throw new IllegalArgumentException("m must be positive"); } if (m > 32) { throw new IllegalArgumentException(" m is too large"); } this.n = 1 << m; this.t = t; if (t < 0) { throw new IllegalArgumentException("t must be positive"); } if (t > n) { throw new IllegalArgumentException("t must be less than n = 2^m"); } if ((PolynomialRingGF2.degree(poly) == m) && (PolynomialRingGF2.isIrreducible(poly))) { this.fieldPoly = poly; } else { throw new IllegalArgumentException( "polynomial is not a field polynomial for GF(2^m)"); } } /** * @return the extension degree of the finite field GF(2^m) */ public int getM() { return m; } /** * @return the length of the code */ public int getN() { return n; } /** * @return the error correction capability of the code */ public int getT() { return t; } /** * @return the field polynomial */ public int getFieldPoly() { return fieldPoly; } } bouncycastle-1.49.orig/src/org/bouncycastle/pqc/crypto/mceliece/Conversions.java0000644000175000017500000001467312105020536027533 0ustar ebourgebourgpackage org.bouncycastle.pqc.crypto.mceliece; import java.math.BigInteger; import org.bouncycastle.pqc.math.linearalgebra.BigIntUtils; import org.bouncycastle.pqc.math.linearalgebra.GF2Vector; import org.bouncycastle.pqc.math.linearalgebra.IntegerFunctions; /** * Provides methods for CCA2-Secure Conversions of McEliece PKCS */ final class Conversions { private static final BigInteger ZERO = BigInteger.valueOf(0); private static final BigInteger ONE = BigInteger.valueOf(1); /** * Default constructor (private). */ private Conversions() { } /** * Encode a number between 0 and (n|t) (binomial coefficient) into a binary * vector of length n with weight t. The number is given as a byte array. * Only the first s bits are used, where s = floor[log(n|t)]. * * @param n integer * @param t integer * @param m the message as a byte array * @return the encoded message as {@link GF2Vector} */ public static GF2Vector encode(final int n, final int t, final byte[] m) { if (n < t) { throw new IllegalArgumentException("n < t"); } // compute the binomial c = (n|t) BigInteger c = IntegerFunctions.binomial(n, t); // get the number encoded in m BigInteger i = new BigInteger(1, m); // compare if (i.compareTo(c) >= 0) { throw new IllegalArgumentException("Encoded number too large."); } GF2Vector result = new GF2Vector(n); int nn = n; int tt = t; for (int j = 0; j < n; j++) { c = c.multiply(BigInteger.valueOf(nn - tt)).divide( BigInteger.valueOf(nn)); nn--; if (c.compareTo(i) <= 0) { result.setBit(j); i = i.subtract(c); tt--; if (nn == tt) { c = ONE; } else { c = (c.multiply(BigInteger.valueOf(tt + 1))) .divide(BigInteger.valueOf(nn - tt)); } } } return result; } /** * Decode a binary vector of length n and weight t into a number between 0 * and (n|t) (binomial coefficient). The result is given as a byte array of * length floor[(s+7)/8], where s = floor[log(n|t)]. * * @param n integer * @param t integer * @param vec the binary vector * @return the decoded vector as a byte array */ public static byte[] decode(int n, int t, GF2Vector vec) { if ((vec.getLength() != n) || (vec.getHammingWeight() != t)) { throw new IllegalArgumentException( "vector has wrong length or hamming weight"); } int[] vecArray = vec.getVecArray(); BigInteger bc = IntegerFunctions.binomial(n, t); BigInteger d = ZERO; int nn = n; int tt = t; for (int i = 0; i < n; i++) { bc = bc.multiply(BigInteger.valueOf(nn - tt)).divide( BigInteger.valueOf(nn)); nn--; int q = i >> 5; int e = vecArray[q] & (1 << (i & 0x1f)); if (e != 0) { d = d.add(bc); tt--; if (nn == tt) { bc = ONE; } else { bc = bc.multiply(BigInteger.valueOf(tt + 1)).divide( BigInteger.valueOf(nn - tt)); } } } return BigIntUtils.toMinimalByteArray(d); } /** * Compute a message representative of a message given as a vector of length * n bit and of hamming weight t. The result is a * byte array of length (s+7)/8, where * s = floor[log(n|t)]. * * @param n integer * @param t integer * @param m the message vector as a byte array * @return a message representative for m */ public static byte[] signConversion(int n, int t, byte[] m) { if (n < t) { throw new IllegalArgumentException("n < t"); } BigInteger bc = IntegerFunctions.binomial(n, t); // finds s = floor[log(binomial(n,t))] int s = bc.bitLength() - 1; // s = sq*8 + sr; int sq = s >> 3; int sr = s & 7; if (sr == 0) { sq--; sr = 8; } // n = nq*8+nr; int nq = n >> 3; int nr = n & 7; if (nr == 0) { nq--; nr = 8; } // take s bit from m byte[] data = new byte[nq + 1]; if (m.length < data.length) { System.arraycopy(m, 0, data, 0, m.length); for (int i = m.length; i < data.length; i++) { data[i] = 0; } } else { System.arraycopy(m, 0, data, 0, nq); int h = (1 << nr) - 1; data[nq] = (byte)(h & m[nq]); } BigInteger d = ZERO; int nn = n; int tt = t; for (int i = 0; i < n; i++) { bc = (bc.multiply(new BigInteger(Integer.toString(nn - tt)))) .divide(new BigInteger(Integer.toString(nn))); nn--; int q = i >>> 3; int r = i & 7; r = 1 << r; byte e = (byte)(r & data[q]); if (e != 0) { d = d.add(bc); tt--; if (nn == tt) { bc = ONE; } else { bc = (bc .multiply(new BigInteger(Integer.toString(tt + 1)))) .divide(new BigInteger(Integer.toString(nn - tt))); } } } byte[] result = new byte[sq + 1]; byte[] help = d.toByteArray(); if (help.length < result.length) { System.arraycopy(help, 0, result, 0, help.length); for (int i = help.length; i < result.length; i++) { result[i] = 0; } } else { System.arraycopy(help, 0, result, 0, sq); result[sq] = (byte)(((1 << sr) - 1) & help[sq]); } return result; } } bouncycastle-1.49.orig/src/org/bouncycastle/pqc/crypto/mceliece/McElieceKobaraImaiDigestCipher.java0000644000175000017500000000532312043374601033102 0ustar ebourgebourgpackage org.bouncycastle.pqc.crypto.mceliece; import org.bouncycastle.crypto.CipherParameters; import org.bouncycastle.crypto.Digest; import org.bouncycastle.crypto.params.AsymmetricKeyParameter; import org.bouncycastle.crypto.params.ParametersWithRandom; import org.bouncycastle.pqc.crypto.MessageEncryptor; // TODO should implement some interface? public class McElieceKobaraImaiDigestCipher { private final Digest messDigest; private final MessageEncryptor mcElieceCCA2Cipher; private boolean forEncrypting; public McElieceKobaraImaiDigestCipher(MessageEncryptor mcElieceCCA2Cipher, Digest messDigest) { this.mcElieceCCA2Cipher = mcElieceCCA2Cipher; this.messDigest = messDigest; } public void init(boolean forEncrypting, CipherParameters param) { this.forEncrypting = forEncrypting; AsymmetricKeyParameter k; if (param instanceof ParametersWithRandom) { k = (AsymmetricKeyParameter)((ParametersWithRandom)param).getParameters(); } else { k = (AsymmetricKeyParameter)param; } if (forEncrypting && k.isPrivate()) { throw new IllegalArgumentException("Encrypting Requires Public Key."); } if (!forEncrypting && !k.isPrivate()) { throw new IllegalArgumentException("Decrypting Requires Private Key."); } reset(); mcElieceCCA2Cipher.init(forEncrypting, param); } public byte[] messageEncrypt() { if (!forEncrypting) { throw new IllegalStateException("McElieceKobaraImaiDigestCipher not initialised for encrypting."); } byte[] hash = new byte[messDigest.getDigestSize()]; messDigest.doFinal(hash, 0); byte[] enc = null; try { enc = mcElieceCCA2Cipher.messageEncrypt(hash); } catch (Exception e) { e.printStackTrace(); } return enc; } public byte[] messageDecrypt(byte[] ciphertext) { byte[] output = null; if (forEncrypting) { throw new IllegalStateException("McElieceKobaraImaiDigestCipher not initialised for decrypting."); } try { output = mcElieceCCA2Cipher.messageDecrypt(ciphertext); } catch (Exception e) { e.printStackTrace(); } return output; } public void update(byte b) { messDigest.update(b); } public void update(byte[] in, int off, int len) { messDigest.update(in, off, len); } public void reset() { messDigest.reset(); } } bouncycastle-1.49.orig/src/org/bouncycastle/pqc/crypto/mceliece/McElieceCCA2Parameters.java0000644000175000017500000000206012043365067031305 0ustar ebourgebourgpackage org.bouncycastle.pqc.crypto.mceliece; import org.bouncycastle.crypto.Digest; import org.bouncycastle.crypto.digests.SHA256Digest; /** * This class provides a specification for the parameters of the CCA2-secure * variants of the McEliece PKCS that are used with * {@link McElieceFujisakiCipher}, {@link McElieceKobaraImaiCipher}, and * {@link McEliecePointchevalCipher}. * * @see McElieceFujisakiCipher * @see McElieceKobaraImaiCipher * @see McEliecePointchevalCipher */ public class McElieceCCA2Parameters extends McElieceParameters { public Digest digest; /** * Construct the default parameters. * The default message digest is SHA256. */ public McElieceCCA2Parameters() { this.digest = new SHA256Digest(); } public McElieceCCA2Parameters(int m, int t) { super(m, t); this.digest = new SHA256Digest(); } public McElieceCCA2Parameters(Digest digest) { this.digest = digest; } public Digest getDigest() { return this.digest; } } bouncycastle-1.49.orig/src/org/bouncycastle/pqc/crypto/mceliece/McElieceFujisakiCipher.java0000644000175000017500000001410012105021213031464 0ustar ebourgebourgpackage org.bouncycastle.pqc.crypto.mceliece; import java.security.SecureRandom; import org.bouncycastle.crypto.CipherParameters; import org.bouncycastle.crypto.Digest; import org.bouncycastle.crypto.digests.SHA1Digest; import org.bouncycastle.crypto.params.ParametersWithRandom; import org.bouncycastle.crypto.prng.DigestRandomGenerator; import org.bouncycastle.pqc.crypto.MessageEncryptor; import org.bouncycastle.pqc.math.linearalgebra.ByteUtils; import org.bouncycastle.pqc.math.linearalgebra.GF2Vector; /** * This class implements the Fujisaki/Okamoto conversion of the McEliecePKCS. * Fujisaki and Okamoto propose hybrid encryption that merges a symmetric * encryption scheme which is secure in the find-guess model with an asymmetric * one-way encryption scheme which is sufficiently probabilistic to obtain a * public key cryptosystem which is CCA2-secure. For details, see D. Engelbert, * R. Overbeck, A. Schmidt, "A summary of the development of the McEliece * Cryptosystem", technical report. */ public class McElieceFujisakiCipher implements MessageEncryptor { /** * The OID of the algorithm. */ public static final String OID = "1.3.6.1.4.1.8301.3.1.3.4.2.1"; private static final String DEFAULT_PRNG_NAME = "SHA1PRNG"; private Digest messDigest; private SecureRandom sr; /** * The McEliece main parameters */ private int n, k, t; McElieceCCA2KeyParameters key; public void init(boolean forSigning, CipherParameters param) { if (forSigning) { if (param instanceof ParametersWithRandom) { ParametersWithRandom rParam = (ParametersWithRandom)param; this.sr = rParam.getRandom(); this.key = (McElieceCCA2PublicKeyParameters)rParam.getParameters(); this.initCipherEncrypt((McElieceCCA2PublicKeyParameters)key); } else { this.sr = new SecureRandom(); this.key = (McElieceCCA2PublicKeyParameters)param; this.initCipherEncrypt((McElieceCCA2PublicKeyParameters)key); } } else { this.key = (McElieceCCA2PrivateKeyParameters)param; this.initCipherDecrypt((McElieceCCA2PrivateKeyParameters)key); } } public int getKeySize(McElieceCCA2KeyParameters key) throws IllegalArgumentException { if (key instanceof McElieceCCA2PublicKeyParameters) { return ((McElieceCCA2PublicKeyParameters)key).getN(); } if (key instanceof McElieceCCA2PrivateKeyParameters) { return ((McElieceCCA2PrivateKeyParameters)key).getN(); } throw new IllegalArgumentException("unsupported type"); } private void initCipherEncrypt(McElieceCCA2PublicKeyParameters pubKey) { this.sr = sr != null ? sr : new SecureRandom(); this.messDigest = pubKey.getParameters().getDigest(); n = pubKey.getN(); k = pubKey.getK(); t = pubKey.getT(); } public void initCipherDecrypt(McElieceCCA2PrivateKeyParameters privKey) { this.messDigest = privKey.getParameters().getDigest(); n = privKey.getN(); t = privKey.getT(); } public byte[] messageEncrypt(byte[] input) throws Exception { // generate random vector r of length k bits GF2Vector r = new GF2Vector(k, sr); // convert r to byte array byte[] rBytes = r.getEncoded(); // compute (r||input) byte[] rm = ByteUtils.concatenate(rBytes, input); // compute H(r||input) messDigest.update(rm, 0, rm.length); byte[] hrm = new byte[messDigest.getDigestSize()]; messDigest.doFinal(hrm, 0); // convert H(r||input) to error vector z GF2Vector z = Conversions.encode(n, t, hrm); // compute c1 = E(r, z) byte[] c1 = McElieceCCA2Primitives.encryptionPrimitive((McElieceCCA2PublicKeyParameters)key, r, z) .getEncoded(); // get PRNG object DigestRandomGenerator sr0 = new DigestRandomGenerator(new SHA1Digest()); // seed PRNG with r' sr0.addSeedMaterial(rBytes); // generate random c2 byte[] c2 = new byte[input.length]; sr0.nextBytes(c2); // XOR with input for (int i = 0; i < input.length; i++) { c2[i] ^= input[i]; } // return (c1||c2) return ByteUtils.concatenate(c1, c2); } public byte[] messageDecrypt(byte[] input) throws Exception { int c1Len = (n + 7) >> 3; int c2Len = input.length - c1Len; // split ciphertext (c1||c2) byte[][] c1c2 = ByteUtils.split(input, c1Len); byte[] c1 = c1c2[0]; byte[] c2 = c1c2[1]; // decrypt c1 ... GF2Vector hrmVec = GF2Vector.OS2VP(n, c1); GF2Vector[] decC1 = McElieceCCA2Primitives.decryptionPrimitive((McElieceCCA2PrivateKeyParameters)key, hrmVec); byte[] rBytes = decC1[0].getEncoded(); // ... and obtain error vector z GF2Vector z = decC1[1]; // get PRNG object DigestRandomGenerator sr0 = new DigestRandomGenerator(new SHA1Digest()); // seed PRNG with r' sr0.addSeedMaterial(rBytes); // generate random sequence byte[] mBytes = new byte[c2Len]; sr0.nextBytes(mBytes); // XOR with c2 to obtain m for (int i = 0; i < c2Len; i++) { mBytes[i] ^= c2[i]; } // compute H(r||m) byte[] rmBytes = ByteUtils.concatenate(rBytes, mBytes); byte[] hrm = new byte[messDigest.getDigestSize()]; messDigest.update(rmBytes, 0, rmBytes.length); messDigest.doFinal(hrm, 0); // compute Conv(H(r||m)) hrmVec = Conversions.encode(n, t, hrm); // check that Conv(H(m||r)) = z if (!hrmVec.equals(z)) { throw new Exception("Bad Padding: invalid ciphertext"); } // return plaintext m return mBytes; } } bouncycastle-1.49.orig/src/org/bouncycastle/pqc/crypto/MessageSigner.java0000644000175000017500000000176011771773732026227 0ustar ebourgebourgpackage org.bouncycastle.pqc.crypto; import org.bouncycastle.crypto.CipherParameters; public interface MessageSigner { /** * initialise the signer for signature generation or signature * verification. * * @param forSigning true if we are generating a signature, false * otherwise. * @param param key parameters for signature generation. */ public void init(boolean forSigning, CipherParameters param); /** * sign the passed in message (usually the output of a hash function). * * @param message the message to be signed. * @return the signature of the message */ public byte[] generateSignature(byte[] message); /** * verify the message message against the signature values r and s. * * @param message the message that was supposed to have been signed. * @param signature the signature of the message */ public boolean verifySignature(byte[] message, byte[] signature); } bouncycastle-1.49.orig/src/org/bouncycastle/pqc/crypto/rainbow/0000755000175000017500000000000012152033551024243 5ustar ebourgebourgbouncycastle-1.49.orig/src/org/bouncycastle/pqc/crypto/rainbow/util/0000755000175000017500000000000012152033551025220 5ustar ebourgebourgbouncycastle-1.49.orig/src/org/bouncycastle/pqc/crypto/rainbow/util/GF2Field.java0000644000175000017500000001255512151551720027417 0ustar ebourgebourgpackage org.bouncycastle.pqc.crypto.rainbow.util; /** * This class provides the basic operations like addition, multiplication and * finding the multiplicative inverse of an element in GF2^8. *

    * The operations are implemented using the irreducible polynomial * 1+x^2+x^3+x^6+x^8 ( 1 0100 1101 = 0x14d ) *

    * This class makes use of lookup tables(exps and logs) for implementing the * operations in order to increase the efficiency of Rainbow. */ public class GF2Field { public static final int MASK = 0xff; /* * this lookup table is needed for multiplication and computing the * multiplicative inverse */ static final short exps[] = {1, 2, 4, 8, 16, 32, 64, 128, 77, 154, 121, 242, 169, 31, 62, 124, 248, 189, 55, 110, 220, 245, 167, 3, 6, 12, 24, 48, 96, 192, 205, 215, 227, 139, 91, 182, 33, 66, 132, 69, 138, 89, 178, 41, 82, 164, 5, 10, 20, 40, 80, 160, 13, 26, 52, 104, 208, 237, 151, 99, 198, 193, 207, 211, 235, 155, 123, 246, 161, 15, 30, 60, 120, 240, 173, 23, 46, 92, 184, 61, 122, 244, 165, 7, 14, 28, 56, 112, 224, 141, 87, 174, 17, 34, 68, 136, 93, 186, 57, 114, 228, 133, 71, 142, 81, 162, 9, 18, 36, 72, 144, 109, 218, 249, 191, 51, 102, 204, 213, 231, 131, 75, 150, 97, 194, 201, 223, 243, 171, 27, 54, 108, 216, 253, 183, 35, 70, 140, 85, 170, 25, 50, 100, 200, 221, 247, 163, 11, 22, 44, 88, 176, 45, 90, 180, 37, 74, 148, 101, 202, 217, 255, 179, 43, 86, 172, 21, 42, 84, 168, 29, 58, 116, 232, 157, 119, 238, 145, 111, 222, 241, 175, 19, 38, 76, 152, 125, 250, 185, 63, 126, 252, 181, 39, 78, 156, 117, 234, 153, 127, 254, 177, 47, 94, 188, 53, 106, 212, 229, 135, 67, 134, 65, 130, 73, 146, 105, 210, 233, 159, 115, 230, 129, 79, 158, 113, 226, 137, 95, 190, 49, 98, 196, 197, 199, 195, 203, 219, 251, 187, 59, 118, 236, 149, 103, 206, 209, 239, 147, 107, 214, 225, 143, 83, 166, 1}; /* * this lookup table is needed for multiplication and computing the * multiplicative inverse */ static final short logs[] = {0, 0, 1, 23, 2, 46, 24, 83, 3, 106, 47, 147, 25, 52, 84, 69, 4, 92, 107, 182, 48, 166, 148, 75, 26, 140, 53, 129, 85, 170, 70, 13, 5, 36, 93, 135, 108, 155, 183, 193, 49, 43, 167, 163, 149, 152, 76, 202, 27, 230, 141, 115, 54, 205, 130, 18, 86, 98, 171, 240, 71, 79, 14, 189, 6, 212, 37, 210, 94, 39, 136, 102, 109, 214, 156, 121, 184, 8, 194, 223, 50, 104, 44, 253, 168, 138, 164, 90, 150, 41, 153, 34, 77, 96, 203, 228, 28, 123, 231, 59, 142, 158, 116, 244, 55, 216, 206, 249, 131, 111, 19, 178, 87, 225, 99, 220, 172, 196, 241, 175, 72, 10, 80, 66, 15, 186, 190, 199, 7, 222, 213, 120, 38, 101, 211, 209, 95, 227, 40, 33, 137, 89, 103, 252, 110, 177, 215, 248, 157, 243, 122, 58, 185, 198, 9, 65, 195, 174, 224, 219, 51, 68, 105, 146, 45, 82, 254, 22, 169, 12, 139, 128, 165, 74, 91, 181, 151, 201, 42, 162, 154, 192, 35, 134, 78, 188, 97, 239, 204, 17, 229, 114, 29, 61, 124, 235, 232, 233, 60, 234, 143, 125, 159, 236, 117, 30, 245, 62, 56, 246, 217, 63, 207, 118, 250, 31, 132, 160, 112, 237, 20, 144, 179, 126, 88, 251, 226, 32, 100, 208, 221, 119, 173, 218, 197, 64, 242, 57, 176, 247, 73, 180, 11, 127, 81, 21, 67, 145, 16, 113, 187, 238, 191, 133, 200, 161}; /** * This function calculates the sum of two elements as an operation in GF2^8 * * @param x the first element that is to be added * @param y the second element that should be add * @return the sum of the two elements x and y in GF2^8 */ public static short addElem(short x, short y) { return (short)(x ^ y); } /** * This function computes the multiplicative inverse of a given element in * GF2^8 The 0 has no multiplicative inverse and in this case 0 is returned. * * @param x the element which multiplicative inverse is to be computed * @return the multiplicative inverse of the given element, in case it * exists or 0, otherwise */ public static short invElem(short x) { if (x == 0) { return 0; } return (exps[255 - logs[x]]); } /** * This function multiplies two elements in GF2^8. If one of the two * elements is 0, 0 is returned. * * @param x the first element to be multiplied. * @param y the second element to be multiplied. * @return the product of the two input elements in GF2^8. */ public static short multElem(short x, short y) { if (x == 0 || y == 0) { return 0; } else { return (exps[(logs[x] + logs[y]) % 255]); } } /** * This function returns the values of exps-lookup table which correspond to * the input * * @param x the index in the lookup table exps * @return exps-value, corresponding to the input */ public static short getExp(short x) { return exps[x]; } /** * This function returns the values of logs-lookup table which correspond to * the input * * @param x the index in the lookup table logs * @return logs-value, corresponding to the input */ public static short getLog(short x) { return logs[x]; } } bouncycastle-1.49.orig/src/org/bouncycastle/pqc/crypto/rainbow/util/RainbowUtil.java0000644000175000017500000001434511771775301030345 0ustar ebourgebourgpackage org.bouncycastle.pqc.crypto.rainbow.util; /** * This class is needed for the conversions while encoding and decoding, as well as for * comparison between arrays of some dimensions */ public class RainbowUtil { /** * This function converts an one-dimensional array of bytes into a * one-dimensional array of int * * @param in the array to be converted * @return out * the one-dimensional int-array that corresponds the input */ public static int[] convertArraytoInt(byte[] in) { int[] out = new int[in.length]; for (int i = 0; i < in.length; i++) { out[i] = in[i] & GF2Field.MASK; } return out; } /** * This function converts an one-dimensional array of bytes into a * one-dimensional array of type short * * @param in the array to be converted * @return out * one-dimensional short-array that corresponds the input */ public static short[] convertArray(byte[] in) { short[] out = new short[in.length]; for (int i = 0; i < in.length; i++) { out[i] = (short)(in[i] & GF2Field.MASK); } return out; } /** * This function converts a matrix of bytes into a matrix of type short * * @param in the matrix to be converted * @return out * short-matrix that corresponds the input */ public static short[][] convertArray(byte[][] in) { short[][] out = new short[in.length][in[0].length]; for (int i = 0; i < in.length; i++) { for (int j = 0; j < in[0].length; j++) { out[i][j] = (short)(in[i][j] & GF2Field.MASK); } } return out; } /** * This function converts a 3-dimensional array of bytes into a 3-dimensional array of type short * * @param in the array to be converted * @return out * short-array that corresponds the input */ public static short[][][] convertArray(byte[][][] in) { short[][][] out = new short[in.length][in[0].length][in[0][0].length]; for (int i = 0; i < in.length; i++) { for (int j = 0; j < in[0].length; j++) { for (int k = 0; k < in[0][0].length; k++) { out[i][j][k] = (short)(in[i][j][k] & GF2Field.MASK); } } } return out; } /** * This function converts an array of type int into an array of type byte * * @param in the array to be converted * @return out * the byte-array that corresponds the input */ public static byte[] convertIntArray(int[] in) { byte[] out = new byte[in.length]; for (int i = 0; i < in.length; i++) { out[i] = (byte)in[i]; } return out; } /** * This function converts an array of type short into an array of type byte * * @param in the array to be converted * @return out * the byte-array that corresponds the input */ public static byte[] convertArray(short[] in) { byte[] out = new byte[in.length]; for (int i = 0; i < in.length; i++) { out[i] = (byte)in[i]; } return out; } /** * This function converts a matrix of type short into a matrix of type byte * * @param in the matrix to be converted * @return out * the byte-matrix that corresponds the input */ public static byte[][] convertArray(short[][] in) { byte[][] out = new byte[in.length][in[0].length]; for (int i = 0; i < in.length; i++) { for (int j = 0; j < in[0].length; j++) { out[i][j] = (byte)in[i][j]; } } return out; } /** * This function converts a 3-dimensional array of type short into a 3-dimensional array of type byte * * @param in the array to be converted * @return out * the byte-array that corresponds the input */ public static byte[][][] convertArray(short[][][] in) { byte[][][] out = new byte[in.length][in[0].length][in[0][0].length]; for (int i = 0; i < in.length; i++) { for (int j = 0; j < in[0].length; j++) { for (int k = 0; k < in[0][0].length; k++) { out[i][j][k] = (byte)in[i][j][k]; } } } return out; } /** * Compare two short arrays. No null checks are performed. * * @param left the first short array * @param right the second short array * @return the result of the comparison */ public static boolean equals(short[] left, short[] right) { if (left.length != right.length) { return false; } boolean result = true; for (int i = left.length - 1; i >= 0; i--) { result &= left[i] == right[i]; } return result; } /** * Compare two two-dimensional short arrays. No null checks are performed. * * @param left the first short array * @param right the second short array * @return the result of the comparison */ public static boolean equals(short[][] left, short[][] right) { if (left.length != right.length) { return false; } boolean result = true; for (int i = left.length - 1; i >= 0; i--) { result &= equals(left[i], right[i]); } return result; } /** * Compare two three-dimensional short arrays. No null checks are performed. * * @param left the first short array * @param right the second short array * @return the result of the comparison */ public static boolean equals(short[][][] left, short[][][] right) { if (left.length != right.length) { return false; } boolean result = true; for (int i = left.length - 1; i >= 0; i--) { result &= equals(left[i], right[i]); } return result; } } bouncycastle-1.49.orig/src/org/bouncycastle/pqc/crypto/rainbow/util/ComputeInField.java0000644000175000017500000003765611771775301030767 0ustar ebourgebourgpackage org.bouncycastle.pqc.crypto.rainbow.util; /** * This class offers different operations on matrices in field GF2^8. *

    * Implemented are functions: * - finding inverse of a matrix * - solving linear equation systems using the Gauss-Elimination method * - basic operations like matrix multiplication, addition and so on. */ public class ComputeInField { private short[][] A; // used by solveEquation and inverse short[] x; /** * Constructor with no parameters */ public ComputeInField() { } /** * This function finds a solution of the equation Bx = b. * Exception is thrown if the linear equation system has no solution * * @param B this matrix is the left part of the * equation (B in the equation above) * @param b the right part of the equation * (b in the equation above) * @return x the solution of the equation if it is solvable * null otherwise * @throws RuntimeException if LES is not solvable */ public short[] solveEquation(short[][] B, short[] b) { try { if (B.length != b.length) { throw new RuntimeException( "The equation system is not solvable"); } /** initialize **/ // this matrix stores B and b from the equation B*x = b // b is stored as the last column. // B contains one column more than rows. // In this column we store a free coefficient that should be later subtracted from b A = new short[B.length][B.length + 1]; // stores the solution of the LES x = new short[B.length]; /** copy B into the global matrix A **/ for (int i = 0; i < B.length; i++) { // rows for (int j = 0; j < B[0].length; j++) { // cols A[i][j] = B[i][j]; } } /** copy the vector b into the global A **/ //the free coefficient, stored in the last column of A( A[i][b.length] // is to be subtracted from b for (int i = 0; i < b.length; i++) { A[i][b.length] = GF2Field.addElem(b[i], A[i][b.length]); } /** call the methods for gauss elimination and backward substitution **/ computeZerosUnder(false); // obtain zeros under the diagonal substitute(); return x; } catch (RuntimeException rte) { return null; // the LES is not solvable! } } /** * This function computes the inverse of a given matrix using the Gauss- * Elimination method. *

    * An exception is thrown if the matrix has no inverse * * @param coef the matrix which inverse matrix is needed * @return inverse matrix of the input matrix. * If the matrix is singular, null is returned. * @throws RuntimeException if the given matrix is not invertible */ public short[][] inverse(short[][] coef) { try { /** Initialization: **/ short factor; short[][] inverse; A = new short[coef.length][2 * coef.length]; if (coef.length != coef[0].length) { throw new RuntimeException( "The matrix is not invertible. Please choose another one!"); } /** prepare: Copy coef and the identity matrix into the global A. **/ for (int i = 0; i < coef.length; i++) { for (int j = 0; j < coef.length; j++) { //copy the input matrix coef into A A[i][j] = coef[i][j]; } // copy the identity matrix into A. for (int j = coef.length; j < 2 * coef.length; j++) { A[i][j] = 0; } A[i][i + A.length] = 1; } /** Elimination operations to get the identity matrix from the left side of A. **/ // modify A to get 0s under the diagonal. computeZerosUnder(true); // modify A to get only 1s on the diagonal: A[i][j] =A[i][j]/A[i][i]. for (int i = 0; i < A.length; i++) { factor = GF2Field.invElem(A[i][i]); for (int j = i; j < 2 * A.length; j++) { A[i][j] = GF2Field.multElem(A[i][j], factor); } } //modify A to get only 0s above the diagonal. computeZerosAbove(); // copy the result (the second half of A) in the matrix inverse. inverse = new short[A.length][A.length]; for (int i = 0; i < A.length; i++) { for (int j = A.length; j < 2 * A.length; j++) { inverse[i][j - A.length] = A[i][j]; } } return inverse; } catch (RuntimeException rte) { // The matrix is not invertible! A new one should be generated! return null; } } /** * Elimination under the diagonal. * This function changes a matrix so that it contains only zeros under the * diagonal(Ai,i) using only Gauss-Elimination operations. *

    * It is used in solveEquaton as well as in the function for * finding an inverse of a matrix: {@link}inverse. Both of them use the * Gauss-Elimination Method. *

    * The result is stored in the global matrix A * * @param usedForInverse This parameter shows if the function is used by the * solveEquation-function or by the inverse-function and according * to this creates matrices of different sizes. * @throws RuntimeException in case a multiplicative inverse of 0 is needed */ private void computeZerosUnder(boolean usedForInverse) throws RuntimeException { //the number of columns in the global A where the tmp results are stored int length; short tmp = 0; //the function is used in inverse() - A should have 2 times more columns than rows if (usedForInverse) { length = 2 * A.length; } //the function is used in solveEquation - A has 1 column more than rows else { length = A.length + 1; } //elimination operations to modify A so that that it contains only 0s under the diagonal for (int k = 0; k < A.length - 1; k++) { // the fixed row for (int i = k + 1; i < A.length; i++) { // rows short factor1 = A[i][k]; short factor2 = GF2Field.invElem(A[k][k]); //The element which multiplicative inverse is needed, is 0 //in this case is the input matrix not invertible if (factor2 == 0) { throw new RuntimeException("Matrix not invertible! We have to choose another one!"); } for (int j = k; j < length; j++) {// columns // tmp=A[k,j] / A[k,k] tmp = GF2Field.multElem(A[k][j], factor2); // tmp = A[i,k] * A[k,j] / A[k,k] tmp = GF2Field.multElem(factor1, tmp); // A[i,j]=A[i,j]-A[i,k]/A[k,k]*A[k,j]; A[i][j] = GF2Field.addElem(A[i][j], tmp); } } } } /** * Elimination above the diagonal. * This function changes a matrix so that it contains only zeros above the * diagonal(Ai,i) using only Gauss-Elimination operations. *

    * It is used in the inverse-function * The result is stored in the global matrix A * * @throws RuntimeException in case a multiplicative inverse of 0 is needed */ private void computeZerosAbove() throws RuntimeException { short tmp = 0; for (int k = A.length - 1; k > 0; k--) { // the fixed row for (int i = k - 1; i >= 0; i--) { // rows short factor1 = A[i][k]; short factor2 = GF2Field.invElem(A[k][k]); if (factor2 == 0) { throw new RuntimeException("The matrix is not invertible"); } for (int j = k; j < 2 * A.length; j++) { // columns // tmp = A[k,j] / A[k,k] tmp = GF2Field.multElem(A[k][j], factor2); // tmp = A[i,k] * A[k,j] / A[k,k] tmp = GF2Field.multElem(factor1, tmp); // A[i,j] = A[i,j] - A[i,k] / A[k,k] * A[k,j]; A[i][j] = GF2Field.addElem(A[i][j], tmp); } } } } /** * This function uses backward substitution to find x * of the linear equation system (LES) B*x = b, * where A a triangle-matrix is (contains only zeros under the diagonal) * and b is a vector *

    * If the multiplicative inverse of 0 is needed, an exception is thrown. * In this case is the LES not solvable * * @throws RuntimeException in case a multiplicative inverse of 0 is needed */ private void substitute() throws RuntimeException { // for the temporary results of the operations in field short tmp, temp; temp = GF2Field.invElem(A[A.length - 1][A.length - 1]); if (temp == 0) { throw new RuntimeException("The equation system is not solvable"); } /** backward substitution **/ x[A.length - 1] = GF2Field.multElem(A[A.length - 1][A.length], temp); for (int i = A.length - 2; i >= 0; i--) { tmp = A[i][A.length]; for (int j = A.length - 1; j > i; j--) { temp = GF2Field.multElem(A[i][j], x[j]); tmp = GF2Field.addElem(tmp, temp); } temp = GF2Field.invElem(A[i][i]); if (temp == 0) { throw new RuntimeException("Not solvable equation system"); } x[i] = GF2Field.multElem(tmp, temp); } } /** * This function multiplies two given matrices. * If the given matrices cannot be multiplied due * to different sizes, an exception is thrown. * * @param M1 -the 1st matrix * @param M2 -the 2nd matrix * @return A = M1*M2 * @throws RuntimeException in case the given matrices cannot be multiplied * due to different dimensions. */ public short[][] multiplyMatrix(short[][] M1, short[][] M2) throws RuntimeException { if (M1[0].length != M2.length) { throw new RuntimeException("Multiplication is not possible!"); } short tmp = 0; A = new short[M1.length][M2[0].length]; for (int i = 0; i < M1.length; i++) { for (int j = 0; j < M2.length; j++) { for (int k = 0; k < M2[0].length; k++) { tmp = GF2Field.multElem(M1[i][j], M2[j][k]); A[i][k] = GF2Field.addElem(A[i][k], tmp); } } } return A; } /** * This function multiplies a given matrix with a one-dimensional array. *

    * An exception is thrown, if the number of columns in the matrix and * the number of rows in the one-dim. array differ. * * @param M1 the matrix to be multiplied * @param m the one-dimensional array to be multiplied * @return M1*m * @throws RuntimeException in case of dimension inconsistency */ public short[] multiplyMatrix(short[][] M1, short[] m) throws RuntimeException { if (M1[0].length != m.length) { throw new RuntimeException("Multiplication is not possible!"); } short tmp = 0; short[] B = new short[M1.length]; for (int i = 0; i < M1.length; i++) { for (int j = 0; j < m.length; j++) { tmp = GF2Field.multElem(M1[i][j], m[j]); B[i] = GF2Field.addElem(B[i], tmp); } } return B; } /** * Addition of two vectors * * @param vector1 first summand, always of dim n * @param vector2 second summand, always of dim n * @return addition of vector1 and vector2 * @throws RuntimeException in case the addition is impossible * due to inconsistency in the dimensions */ public short[] addVect(short[] vector1, short[] vector2) { if (vector1.length != vector2.length) { throw new RuntimeException("Multiplication is not possible!"); } short rslt[] = new short[vector1.length]; for (int n = 0; n < rslt.length; n++) { rslt[n] = GF2Field.addElem(vector1[n], vector2[n]); } return rslt; } /** * Multiplication of column vector with row vector * * @param vector1 column vector, always n x 1 * @param vector2 row vector, always 1 x n * @return resulting n x n matrix of multiplication * @throws RuntimeException in case the multiplication is impossible due to * inconsistency in the dimensions */ public short[][] multVects(short[] vector1, short[] vector2) { if (vector1.length != vector2.length) { throw new RuntimeException("Multiplication is not possible!"); } short rslt[][] = new short[vector1.length][vector2.length]; for (int i = 0; i < vector1.length; i++) { for (int j = 0; j < vector2.length; j++) { rslt[i][j] = GF2Field.multElem(vector1[i], vector2[j]); } } return rslt; } /** * Multiplies vector with scalar * * @param scalar galois element to multiply vector with * @param vector vector to be multiplied * @return vector multiplied with scalar */ public short[] multVect(short scalar, short[] vector) { short rslt[] = new short[vector.length]; for (int n = 0; n < rslt.length; n++) { rslt[n] = GF2Field.multElem(scalar, vector[n]); } return rslt; } /** * Multiplies matrix with scalar * * @param scalar galois element to multiply matrix with * @param matrix 2-dim n x n matrix to be multiplied * @return matrix multiplied with scalar */ public short[][] multMatrix(short scalar, short[][] matrix) { short[][] rslt = new short[matrix.length][matrix[0].length]; for (int i = 0; i < matrix.length; i++) { for (int j = 0; j < matrix[0].length; j++) { rslt[i][j] = GF2Field.multElem(scalar, matrix[i][j]); } } return rslt; } /** * Adds the n x n matrices matrix1 and matrix2 * * @param matrix1 first summand * @param matrix2 second summand * @return addition of matrix1 and matrix2; both having the dimensions n x n * @throws RuntimeException in case the addition is not possible because of * different dimensions of the matrices */ public short[][] addSquareMatrix(short[][] matrix1, short[][] matrix2) { if (matrix1.length != matrix2.length || matrix1[0].length != matrix2[0].length) { throw new RuntimeException("Addition is not possible!"); } short[][] rslt = new short[matrix1.length][matrix1.length];// for (int i = 0; i < matrix1.length; i++) { for (int j = 0; j < matrix2.length; j++) { rslt[i][j] = GF2Field.addElem(matrix1[i][j], matrix2[i][j]); } } return rslt; } } bouncycastle-1.49.orig/src/org/bouncycastle/pqc/crypto/rainbow/RainbowPublicKeyParameters.java0000644000175000017500000000217611776703514032367 0ustar ebourgebourgpackage org.bouncycastle.pqc.crypto.rainbow; public class RainbowPublicKeyParameters extends RainbowKeyParameters { private short[][] coeffquadratic; private short[][] coeffsingular; private short[] coeffscalar; /** * Constructor * * @param docLength * @param coeffQuadratic * @param coeffSingular * @param coeffScalar */ public RainbowPublicKeyParameters(int docLength, short[][] coeffQuadratic, short[][] coeffSingular, short[] coeffScalar) { super(false, docLength); this.coeffquadratic = coeffQuadratic; this.coeffsingular = coeffSingular; this.coeffscalar = coeffScalar; } /** * @return the coeffquadratic */ public short[][] getCoeffQuadratic() { return coeffquadratic; } /** * @return the coeffsingular */ public short[][] getCoeffSingular() { return coeffsingular; } /** * @return the coeffscalar */ public short[] getCoeffScalar() { return coeffscalar; } } bouncycastle-1.49.orig/src/org/bouncycastle/pqc/crypto/rainbow/RainbowSigner.java0000644000175000017500000002301311776703514027674 0ustar ebourgebourgpackage org.bouncycastle.pqc.crypto.rainbow; import java.security.SecureRandom; import org.bouncycastle.crypto.CipherParameters; import org.bouncycastle.crypto.params.ParametersWithRandom; import org.bouncycastle.pqc.crypto.MessageSigner; import org.bouncycastle.pqc.crypto.rainbow.util.ComputeInField; import org.bouncycastle.pqc.crypto.rainbow.util.GF2Field; /** * It implements the sign and verify functions for the Rainbow Signature Scheme. * Here the message, which has to be signed, is updated. The use of * different hash functions is possible. *

    * Detailed information about the signature and the verify-method is to be found * in the paper of Jintai Ding, Dieter Schmidt: Rainbow, a New Multivariable * Polynomial Signature Scheme. ACNS 2005: 164-175 * (http://dx.doi.org/10.1007/11496137_12) */ public class RainbowSigner implements MessageSigner { // Source of randomness private SecureRandom random; // The length of a document that can be signed with the privKey int signableDocumentLength; // Container for the oil and vinegar variables of all the layers private short[] x; private ComputeInField cf = new ComputeInField(); RainbowKeyParameters key; public void init(boolean forSigning, CipherParameters param) { if (forSigning) { if (param instanceof ParametersWithRandom) { ParametersWithRandom rParam = (ParametersWithRandom)param; this.random = rParam.getRandom(); this.key = (RainbowPrivateKeyParameters)rParam.getParameters(); } else { this.random = new SecureRandom(); this.key = (RainbowPrivateKeyParameters)param; } } else { this.key = (RainbowPublicKeyParameters)param; } this.signableDocumentLength = this.key.getDocLength(); } /** * initial operations before solving the Linear equation system. * * @param layer the current layer for which a LES is to be solved. * @param msg the message that should be signed. * @return Y_ the modified document needed for solving LES, (Y_ = * A1^{-1}*(Y-b1)) linear map L1 = A1 x + b1. */ private short[] initSign(Layer[] layer, short[] msg) { /* preparation: Modifies the document with the inverse of L1 */ // tmp = Y - b1: short[] tmpVec = new short[msg.length]; tmpVec = cf.addVect(((RainbowPrivateKeyParameters)this.key).getB1(), msg); // Y_ = A1^{-1} * (Y - b1) : short[] Y_ = cf.multiplyMatrix(((RainbowPrivateKeyParameters)this.key).getInvA1(), tmpVec); /* generates the vinegar vars of the first layer at random */ for (int i = 0; i < layer[0].getVi(); i++) { x[i] = (short)random.nextInt(); x[i] = (short)(x[i] & GF2Field.MASK); } return Y_; } /** * This function signs the message that has been updated, making use of the * private key. *

    * For computing the signature, L1 and L2 are needed, as well as LES should * be solved for each layer in order to find the Oil-variables in the layer. *

    * The Vinegar-variables of the first layer are random generated. * * @param message the message * @return the signature of the message. */ public byte[] generateSignature(byte[] message) { Layer[] layer = ((RainbowPrivateKeyParameters)this.key).getLayers(); int numberOfLayers = layer.length; x = new short[((RainbowPrivateKeyParameters)this.key).getInvA2().length]; // all variables short[] Y_; // modified document short[] y_i; // part of Y_ each polynomial int counter; // index of the current part of the doc short[] solVec; // the solution of LES pro layer short[] tmpVec; // the signature as an array of shorts: short[] signature; // the signature as a byte-array: byte[] S = new byte[layer[numberOfLayers - 1].getViNext()]; short[] msgHashVals = makeMessageRepresentative(message); // shows if an exception is caught boolean ok; do { ok = true; counter = 0; try { Y_ = initSign(layer, msgHashVals); for (int i = 0; i < numberOfLayers; i++) { y_i = new short[layer[i].getOi()]; solVec = new short[layer[i].getOi()]; // solution of LES /* copy oi elements of Y_ into y_i */ for (int k = 0; k < layer[i].getOi(); k++) { y_i[k] = Y_[counter]; counter++; // current index of Y_ } /* * plug in the vars of the previous layer in order to get * the vars of the current layer */ solVec = cf.solveEquation(layer[i].plugInVinegars(x), y_i); if (solVec == null) { // LES is not solveable throw new Exception("LES is not solveable!"); } /* copy the new vars into the x-array */ for (int j = 0; j < solVec.length; j++) { x[layer[i].getVi() + j] = solVec[j]; } } /* apply the inverse of L2: (signature = A2^{-1}*(b2+x)) */ tmpVec = cf.addVect(((RainbowPrivateKeyParameters)this.key).getB2(), x); signature = cf.multiplyMatrix(((RainbowPrivateKeyParameters)this.key).getInvA2(), tmpVec); /* cast signature from short[] to byte[] */ for (int i = 0; i < S.length; i++) { S[i] = ((byte)signature[i]); } } catch (Exception se) { // if one of the LESs was not solveable - sign again ok = false; } } while (!ok); /* return the signature in bytes */ return S; } /** * This function verifies the signature of the message that has been * updated, with the aid of the public key. * * @param message the message * @param signature the signature of the message * @return true if the signature has been verified, false otherwise. */ public boolean verifySignature(byte[] message, byte[] signature) { short[] sigInt = new short[signature.length]; short tmp; for (int i = 0; i < signature.length; i++) { tmp = (short)signature[i]; tmp &= (short)0xff; sigInt[i] = tmp; } short[] msgHashVal = makeMessageRepresentative(message); // verify short[] verificationResult = verifySignatureIntern(sigInt); // compare boolean verified = true; if (msgHashVal.length != verificationResult.length) { return false; } for (int i = 0; i < msgHashVal.length; i++) { verified = verified && msgHashVal[i] == verificationResult[i]; } return verified; } /** * Signature verification using public key * * @param signature vector of dimension n * @return document hash of length n - v1 */ private short[] verifySignatureIntern(short[] signature) { short[][] coeff_quadratic = ((RainbowPublicKeyParameters)this.key).getCoeffQuadratic(); short[][] coeff_singular = ((RainbowPublicKeyParameters)this.key).getCoeffSingular(); short[] coeff_scalar = ((RainbowPublicKeyParameters)this.key).getCoeffScalar(); short[] rslt = new short[coeff_quadratic.length];// n - v1 int n = coeff_singular[0].length; int offset = 0; // array position short tmp = 0; // for scalar for (int p = 0; p < coeff_quadratic.length; p++) { // no of polynomials offset = 0; for (int x = 0; x < n; x++) { // calculate quadratic terms for (int y = x; y < n; y++) { tmp = GF2Field.multElem(coeff_quadratic[p][offset], GF2Field.multElem(signature[x], signature[y])); rslt[p] = GF2Field.addElem(rslt[p], tmp); offset++; } // calculate singular terms tmp = GF2Field.multElem(coeff_singular[p][x], signature[x]); rslt[p] = GF2Field.addElem(rslt[p], tmp); } // add scalar rslt[p] = GF2Field.addElem(rslt[p], coeff_scalar[p]); } return rslt; } /** * This function creates the representative of the message which gets signed * or verified. * * @param message the message * @return message representative */ private short[] makeMessageRepresentative(byte[] message) { // the message representative short[] output = new short[this.signableDocumentLength]; int h = 0; int i = 0; do { if (i >= message.length) { break; } output[i] = (short)message[h]; output[i] &= (short)0xff; h++; i++; } while (i < output.length); return output; } } bouncycastle-1.49.orig/src/org/bouncycastle/pqc/crypto/rainbow/Layer.java0000644000175000017500000002440211776716536026212 0ustar ebourgebourgpackage org.bouncycastle.pqc.crypto.rainbow; import java.security.SecureRandom; import org.bouncycastle.pqc.crypto.rainbow.util.GF2Field; import org.bouncycastle.pqc.crypto.rainbow.util.RainbowUtil; import org.bouncycastle.util.Arrays; /** * This class represents a layer of the Rainbow Oil- and Vinegar Map. Each Layer * consists of oi polynomials with their coefficients, generated at random. *

    * To sign a document, we solve a LES (linear equation system) for each layer in * order to find the oil variables of that layer and to be able to use the * variables to compute the signature. This functionality is implemented in the * RainbowSignature-class, by the aid of the private key. *

    * Each layer is a part of the private key. *

    * More information about the layer can be found in the paper of Jintai Ding, * Dieter Schmidt: Rainbow, a New Multivariable Polynomial Signature Scheme. * ACNS 2005: 164-175 (http://dx.doi.org/10.1007/11496137_12) */ public class Layer { private int vi; // number of vinegars in this layer private int viNext; // number of vinegars in next layer private int oi; // number of oils in this layer /* * k : index of polynomial * * i,j : indices of oil and vinegar variables */ private short[/* k */][/* i */][/* j */] coeff_alpha; private short[/* k */][/* i */][/* j */] coeff_beta; private short[/* k */][/* i */] coeff_gamma; private short[/* k */] coeff_eta; /** * Constructor * * @param vi number of vinegar variables of this layer * @param viNext number of vinegar variables of next layer. It's the same as * (num of oils) + (num of vinegars) of this layer. * @param coeffAlpha alpha-coefficients in the polynomials of this layer * @param coeffBeta beta-coefficients in the polynomials of this layer * @param coeffGamma gamma-coefficients in the polynomials of this layer * @param coeffEta eta-coefficients in the polynomials of this layer */ public Layer(byte vi, byte viNext, short[][][] coeffAlpha, short[][][] coeffBeta, short[][] coeffGamma, short[] coeffEta) { this.vi = vi & 0xff; this.viNext = viNext & 0xff; this.oi = this.viNext - this.vi; // the secret coefficients of all polynomials in this layer this.coeff_alpha = coeffAlpha; this.coeff_beta = coeffBeta; this.coeff_gamma = coeffGamma; this.coeff_eta = coeffEta; } /** * This function generates the coefficients of all polynomials in this layer * at random using random generator. * * @param sr the random generator which is to be used */ public Layer(int vi, int viNext, SecureRandom sr) { this.vi = vi; this.viNext = viNext; this.oi = viNext - vi; // the coefficients of all polynomials in this layer this.coeff_alpha = new short[this.oi][this.oi][this.vi]; this.coeff_beta = new short[this.oi][this.vi][this.vi]; this.coeff_gamma = new short[this.oi][this.viNext]; this.coeff_eta = new short[this.oi]; int numOfPoly = this.oi; // number of polynomials per layer // Alpha coeffs for (int k = 0; k < numOfPoly; k++) { for (int i = 0; i < this.oi; i++) { for (int j = 0; j < this.vi; j++) { coeff_alpha[k][i][j] = (short)(sr.nextInt() & GF2Field.MASK); } } } // Beta coeffs for (int k = 0; k < numOfPoly; k++) { for (int i = 0; i < this.vi; i++) { for (int j = 0; j < this.vi; j++) { coeff_beta[k][i][j] = (short)(sr.nextInt() & GF2Field.MASK); } } } // Gamma coeffs for (int k = 0; k < numOfPoly; k++) { for (int i = 0; i < this.viNext; i++) { coeff_gamma[k][i] = (short)(sr.nextInt() & GF2Field.MASK); } } // Eta for (int k = 0; k < numOfPoly; k++) { coeff_eta[k] = (short)(sr.nextInt() & GF2Field.MASK); } } /** * This method plugs in the vinegar variables into the polynomials of this * layer and computes the coefficients of the Oil-variables as well as the * free coefficient in each polynomial. *

    * It is needed for computing the Oil variables while signing. * * @param x vinegar variables of this layer that should be plugged into * the polynomials. * @return coeff the coefficients of Oil variables and the free coeff in the * polynomials of this layer. */ public short[][] plugInVinegars(short[] x) { // temporary variable needed for the multiplication short tmpMult = 0; // coeff: 1st index = which polynomial, 2nd index=which variable short[][] coeff = new short[oi][oi + 1]; // gets returned // free coefficient per polynomial short[] sum = new short[oi]; /* * evaluate the beta-part of the polynomials (it contains no oil * variables) */ for (int k = 0; k < oi; k++) { for (int i = 0; i < vi; i++) { for (int j = 0; j < vi; j++) { // tmp = beta * xi (plug in) tmpMult = GF2Field.multElem(coeff_beta[k][i][j], x[i]); // tmp = tmp * xj tmpMult = GF2Field.multElem(tmpMult, x[j]); // accumulate into the array for the free coefficients. sum[k] = GF2Field.addElem(sum[k], tmpMult); } } } /* evaluate the alpha-part (it contains oils) */ for (int k = 0; k < oi; k++) { for (int i = 0; i < oi; i++) { for (int j = 0; j < vi; j++) { // alpha * xj (plug in) tmpMult = GF2Field.multElem(coeff_alpha[k][i][j], x[j]); // accumulate coeff[k][i] = GF2Field.addElem(coeff[k][i], tmpMult); } } } /* evaluate the gama-part of the polynomial (containing no oils) */ for (int k = 0; k < oi; k++) { for (int i = 0; i < vi; i++) { // gamma * xi (plug in) tmpMult = GF2Field.multElem(coeff_gamma[k][i], x[i]); // accumulate in the array for the free coefficients (per // polynomial). sum[k] = GF2Field.addElem(sum[k], tmpMult); } } /* evaluate the gama-part of the polynomial (but containing oils) */ for (int k = 0; k < oi; k++) { for (int i = vi; i < viNext; i++) { // oils // accumulate the coefficients of the oil variables (per // polynomial). coeff[k][i - vi] = GF2Field.addElem(coeff_gamma[k][i], coeff[k][i - vi]); } } /* evaluate the eta-part of the polynomial */ for (int k = 0; k < oi; k++) { // accumulate in the array for the free coefficients per polynomial. sum[k] = GF2Field.addElem(sum[k], coeff_eta[k]); } /* put the free coefficients (sum) into the coeff-array as last column */ for (int k = 0; k < oi; k++) { coeff[k][oi] = sum[k]; } return coeff; } /** * Getter for the number of vinegar variables of this layer. * * @return the number of vinegar variables of this layer. */ public int getVi() { return vi; } /** * Getter for the number of vinegar variables of the next layer. * * @return the number of vinegar variables of the next layer. */ public int getViNext() { return viNext; } /** * Getter for the number of Oil variables of this layer. * * @return the number of oil variables of this layer. */ public int getOi() { return oi; } /** * Getter for the alpha-coefficients of the polynomials in this layer. * * @return the coefficients of alpha-terms of this layer. */ public short[][][] getCoeffAlpha() { return coeff_alpha; } /** * Getter for the beta-coefficients of the polynomials in this layer. * * @return the coefficients of beta-terms of this layer. */ public short[][][] getCoeffBeta() { return coeff_beta; } /** * Getter for the gamma-coefficients of the polynomials in this layer. * * @return the coefficients of gamma-terms of this layer */ public short[][] getCoeffGamma() { return coeff_gamma; } /** * Getter for the eta-coefficients of the polynomials in this layer. * * @return the coefficients eta of this layer */ public short[] getCoeffEta() { return coeff_eta; } /** * This function compares this Layer with another object. * * @param other the other object * @return the result of the comparison */ public boolean equals(Object other) { if (other == null || !(other instanceof Layer)) { return false; } Layer otherLayer = (Layer)other; return vi == otherLayer.getVi() && viNext == otherLayer.getViNext() && oi == otherLayer.getOi() && RainbowUtil.equals(coeff_alpha, otherLayer.getCoeffAlpha()) && RainbowUtil.equals(coeff_beta, otherLayer.getCoeffBeta()) && RainbowUtil.equals(coeff_gamma, otherLayer.getCoeffGamma()) && RainbowUtil.equals(coeff_eta, otherLayer.getCoeffEta()); } public int hashCode() { int hash = vi; hash = hash * 37 + viNext; hash = hash * 37 + oi; hash = hash * 37 + Arrays.hashCode(coeff_alpha); hash = hash * 37 + Arrays.hashCode(coeff_beta); hash = hash * 37 + Arrays.hashCode(coeff_gamma); hash = hash * 37 + Arrays.hashCode(coeff_eta); return hash; } } bouncycastle-1.49.orig/src/org/bouncycastle/pqc/crypto/rainbow/RainbowKeyParameters.java0000644000175000017500000000100312151251423031175 0ustar ebourgebourgpackage org.bouncycastle.pqc.crypto.rainbow; import org.bouncycastle.crypto.params.AsymmetricKeyParameter; public class RainbowKeyParameters extends AsymmetricKeyParameter { private int docLength; public RainbowKeyParameters( boolean isPrivate, int docLength) { super(isPrivate); this.docLength = docLength; } /** * @return the docLength */ public int getDocLength() { return this.docLength; } } bouncycastle-1.49.orig/src/org/bouncycastle/pqc/crypto/rainbow/RainbowParameters.java0000644000175000017500000000467511776702313030561 0ustar ebourgebourgpackage org.bouncycastle.pqc.crypto.rainbow; import org.bouncycastle.crypto.CipherParameters; public class RainbowParameters implements CipherParameters { /** * DEFAULT PARAMS */ /* * Vi = vinegars per layer whereas n is vu (vu = 33 = n) such that * * v1 = 6; o1 = 12-6 = 6 * * v2 = 12; o2 = 17-12 = 5 * * v3 = 17; o3 = 22-17 = 5 * * v4 = 22; o4 = 33-22 = 11 * * v5 = 33; (o5 = 0) */ private final int[] DEFAULT_VI = {6, 12, 17, 22, 33}; private int[] vi;// set of vinegar vars per layer. /** * Default Constructor The elements of the array containing the number of * Vinegar variables in each layer are set to the default values here. */ public RainbowParameters() { this.vi = this.DEFAULT_VI; } /** * Constructor with parameters * * @param vi The elements of the array containing the number of Vinegar * variables per layer are set to the values of the input array. */ public RainbowParameters(int[] vi) { this.vi = vi; try { checkParams(); } catch (Exception e) { e.printStackTrace(); } } private void checkParams() throws Exception { if (vi == null) { throw new Exception("no layers defined."); } if (vi.length > 1) { for (int i = 0; i < vi.length - 1; i++) { if (vi[i] >= vi[i + 1]) { throw new Exception( "v[i] has to be smaller than v[i+1]"); } } } else { throw new Exception( "Rainbow needs at least 1 layer, such that v1 < v2."); } } /** * Getter for the number of layers * * @return the number of layers */ public int getNumOfLayers() { return this.vi.length - 1; } /** * Getter for the number of all the polynomials in Rainbow * * @return the number of the polynomials */ public int getDocLength() { return vi[vi.length - 1] - vi[0]; } /** * Getter for the array containing the number of Vinegar-variables per layer * * @return the numbers of vinegars per layer */ public int[] getVi() { return this.vi; } } bouncycastle-1.49.orig/src/org/bouncycastle/pqc/crypto/rainbow/RainbowKeyPairGenerator.java0000644000175000017500000003612111776716536031674 0ustar ebourgebourgpackage org.bouncycastle.pqc.crypto.rainbow; import java.security.SecureRandom; import org.bouncycastle.crypto.AsymmetricCipherKeyPair; import org.bouncycastle.crypto.AsymmetricCipherKeyPairGenerator; import org.bouncycastle.crypto.KeyGenerationParameters; import org.bouncycastle.pqc.crypto.rainbow.util.ComputeInField; import org.bouncycastle.pqc.crypto.rainbow.util.GF2Field; /** * This class implements AsymmetricCipherKeyPairGenerator. It is used * as a generator for the private and public key of the Rainbow Signature * Scheme. *

    * Detailed information about the key generation is to be found in the paper of * Jintai Ding, Dieter Schmidt: Rainbow, a New Multivariable Polynomial * Signature Scheme. ACNS 2005: 164-175 (http://dx.doi.org/10.1007/11496137_12) */ public class RainbowKeyPairGenerator implements AsymmetricCipherKeyPairGenerator { private boolean initialized = false; private SecureRandom sr; private RainbowKeyGenerationParameters rainbowParams; /* linear affine map L1: */ private short[][] A1; // matrix of the lin. affine map L1(n-v1 x n-v1 matrix) private short[][] A1inv; // inverted A1 private short[] b1; // translation element of the lin.affine map L1 /* linear affine map L2: */ private short[][] A2; // matrix of the lin. affine map (n x n matrix) private short[][] A2inv; // inverted A2 private short[] b2; // translation elemt of the lin.affine map L2 /* components of F: */ private int numOfLayers; // u (number of sets S) private Layer layers[]; // layers of polynomials of F private int[] vi; // set of vinegar vars per layer. /* components of Public Key */ private short[][] pub_quadratic; // quadratic(mixed) coefficients private short[][] pub_singular; // singular coefficients private short[] pub_scalar; // scalars // TODO /** * The standard constructor tries to generate the Rainbow algorithm identifier * with the corresponding OID. *

    */ public RainbowKeyPairGenerator() { } /** * This function generates a Rainbow key pair. * * @return the generated key pair */ public AsymmetricCipherKeyPair genKeyPair() { RainbowPrivateKeyParameters privKey; RainbowPublicKeyParameters pubKey; if (!initialized) { initializeDefault(); } /* choose all coefficients at random */ keygen(); /* now marshall them to PrivateKey */ privKey = new RainbowPrivateKeyParameters(A1inv, b1, A2inv, b2, vi, layers); /* marshall to PublicKey */ pubKey = new RainbowPublicKeyParameters(vi[vi.length - 1] - vi[0], pub_quadratic, pub_singular, pub_scalar); return new AsymmetricCipherKeyPair(pubKey, privKey); } // TODO public void initialize( KeyGenerationParameters param) { this.rainbowParams = (RainbowKeyGenerationParameters)param; // set source of randomness this.sr = new SecureRandom(); // unmarshalling: this.vi = this.rainbowParams.getParameters().getVi(); this.numOfLayers = this.rainbowParams.getParameters().getNumOfLayers(); this.initialized = true; } private void initializeDefault() { RainbowKeyGenerationParameters rbKGParams = new RainbowKeyGenerationParameters(new SecureRandom(), new RainbowParameters()); initialize(rbKGParams); } /** * This function calls the functions for the random generation of the coefficients * and the matrices needed for the private key and the method for computing the public key. */ private void keygen() { generateL1(); generateL2(); generateF(); computePublicKey(); } /** * This function generates the invertible affine linear map L1 = A1*x + b1 *

    * The translation part b1, is stored in a separate array. The inverse of * the matrix-part of L1 A1inv is also computed here. *

    * This linear map hides the output of the map F. It is on k^(n-v1). */ private void generateL1() { // dimension = n-v1 = vi[last] - vi[first] int dim = vi[vi.length - 1] - vi[0]; this.A1 = new short[dim][dim]; this.A1inv = null; ComputeInField c = new ComputeInField(); /* generation of A1 at random */ while (A1inv == null) { for (int i = 0; i < dim; i++) { for (int j = 0; j < dim; j++) { A1[i][j] = (short)(sr.nextInt() & GF2Field.MASK); } } A1inv = c.inverse(A1); } /* generation of the translation vector at random */ b1 = new short[dim]; for (int i = 0; i < dim; i++) { b1[i] = (short)(sr.nextInt() & GF2Field.MASK); } } /** * This function generates the invertible affine linear map L2 = A2*x + b2 *

    * The translation part b2, is stored in a separate array. The inverse of * the matrix-part of L2 A2inv is also computed here. *

    * This linear map hides the output of the map F. It is on k^(n). */ private void generateL2() { // dimension = n = vi[last] int dim = vi[vi.length - 1]; this.A2 = new short[dim][dim]; this.A2inv = null; ComputeInField c = new ComputeInField(); /* generation of A2 at random */ while (this.A2inv == null) { for (int i = 0; i < dim; i++) { for (int j = 0; j < dim; j++) { // one col extra for b A2[i][j] = (short)(sr.nextInt() & GF2Field.MASK); } } this.A2inv = c.inverse(A2); } /* generation of the translation vector at random */ b2 = new short[dim]; for (int i = 0; i < dim; i++) { b2[i] = (short)(sr.nextInt() & GF2Field.MASK); } } /** * This function generates the private map F, which consists of u-1 layers. * Each layer consists of oi polynomials where oi = vi[i+1]-vi[i]. *

    * The methods for the generation of the coefficients of these polynomials * are called here. */ private void generateF() { this.layers = new Layer[this.numOfLayers]; for (int i = 0; i < this.numOfLayers; i++) { layers[i] = new Layer(this.vi[i], this.vi[i + 1], sr); } } /** * This function computes the public key from the private key. *

    * The composition of F with L2 is computed, followed by applying L1 to the * composition's result. The singular and scalar values constitute to the * public key as is, the quadratic terms are compacted in * compactPublicKey() */ private void computePublicKey() { ComputeInField c = new ComputeInField(); int rows = this.vi[this.vi.length - 1] - this.vi[0]; int vars = this.vi[this.vi.length - 1]; // Fpub short[][][] coeff_quadratic_3dim = new short[rows][vars][vars]; this.pub_singular = new short[rows][vars]; this.pub_scalar = new short[rows]; // Coefficients of layers of Private Key F short[][][] coeff_alpha; short[][][] coeff_beta; short[][] coeff_gamma; short[] coeff_eta; // Needed for counters; int oils = 0; int vins = 0; int crnt_row = 0; // current row (polynomial) short vect_tmp[] = new short[vars]; // vector tmp; short sclr_tmp = 0; // Composition of F and L2: Insert L2 = A2*x+b2 in F for (int l = 0; l < this.layers.length; l++) { // get coefficients of current layer coeff_alpha = this.layers[l].getCoeffAlpha(); coeff_beta = this.layers[l].getCoeffBeta(); coeff_gamma = this.layers[l].getCoeffGamma(); coeff_eta = this.layers[l].getCoeffEta(); oils = coeff_alpha[0].length;// this.layers[l].getOi(); vins = coeff_beta[0].length;// this.layers[l].getVi(); // compute polynomials of layer for (int p = 0; p < oils; p++) { // multiply alphas for (int x1 = 0; x1 < oils; x1++) { for (int x2 = 0; x2 < vins; x2++) { // multiply polynomial1 with polynomial2 vect_tmp = c.multVect(coeff_alpha[p][x1][x2], this.A2[x1 + vins]); coeff_quadratic_3dim[crnt_row + p] = c.addSquareMatrix( coeff_quadratic_3dim[crnt_row + p], c .multVects(vect_tmp, this.A2[x2])); // mul poly1 with scalar2 vect_tmp = c.multVect(this.b2[x2], vect_tmp); this.pub_singular[crnt_row + p] = c.addVect(vect_tmp, this.pub_singular[crnt_row + p]); // mul scalar1 with poly2 vect_tmp = c.multVect(coeff_alpha[p][x1][x2], this.A2[x2]); vect_tmp = c.multVect(b2[x1 + vins], vect_tmp); this.pub_singular[crnt_row + p] = c.addVect(vect_tmp, this.pub_singular[crnt_row + p]); // mul scalar1 with scalar2 sclr_tmp = GF2Field.multElem(coeff_alpha[p][x1][x2], this.b2[x1 + vins]); this.pub_scalar[crnt_row + p] = GF2Field.addElem( this.pub_scalar[crnt_row + p], GF2Field .multElem(sclr_tmp, this.b2[x2])); } } // multiply betas for (int x1 = 0; x1 < vins; x1++) { for (int x2 = 0; x2 < vins; x2++) { // multiply polynomial1 with polynomial2 vect_tmp = c.multVect(coeff_beta[p][x1][x2], this.A2[x1]); coeff_quadratic_3dim[crnt_row + p] = c.addSquareMatrix( coeff_quadratic_3dim[crnt_row + p], c .multVects(vect_tmp, this.A2[x2])); // mul poly1 with scalar2 vect_tmp = c.multVect(this.b2[x2], vect_tmp); this.pub_singular[crnt_row + p] = c.addVect(vect_tmp, this.pub_singular[crnt_row + p]); // mul scalar1 with poly2 vect_tmp = c.multVect(coeff_beta[p][x1][x2], this.A2[x2]); vect_tmp = c.multVect(this.b2[x1], vect_tmp); this.pub_singular[crnt_row + p] = c.addVect(vect_tmp, this.pub_singular[crnt_row + p]); // mul scalar1 with scalar2 sclr_tmp = GF2Field.multElem(coeff_beta[p][x1][x2], this.b2[x1]); this.pub_scalar[crnt_row + p] = GF2Field.addElem( this.pub_scalar[crnt_row + p], GF2Field .multElem(sclr_tmp, this.b2[x2])); } } // multiply gammas for (int n = 0; n < vins + oils; n++) { // mul poly with scalar vect_tmp = c.multVect(coeff_gamma[p][n], this.A2[n]); this.pub_singular[crnt_row + p] = c.addVect(vect_tmp, this.pub_singular[crnt_row + p]); // mul scalar with scalar this.pub_scalar[crnt_row + p] = GF2Field.addElem( this.pub_scalar[crnt_row + p], GF2Field.multElem( coeff_gamma[p][n], this.b2[n])); } // add eta this.pub_scalar[crnt_row + p] = GF2Field.addElem( this.pub_scalar[crnt_row + p], coeff_eta[p]); } crnt_row = crnt_row + oils; } // Apply L1 = A1*x+b1 to composition of F and L2 { // temporary coefficient arrays short[][][] tmp_c_quad = new short[rows][vars][vars]; short[][] tmp_c_sing = new short[rows][vars]; short[] tmp_c_scal = new short[rows]; for (int r = 0; r < rows; r++) { for (int q = 0; q < A1.length; q++) { tmp_c_quad[r] = c.addSquareMatrix(tmp_c_quad[r], c .multMatrix(A1[r][q], coeff_quadratic_3dim[q])); tmp_c_sing[r] = c.addVect(tmp_c_sing[r], c.multVect( A1[r][q], this.pub_singular[q])); tmp_c_scal[r] = GF2Field.addElem(tmp_c_scal[r], GF2Field .multElem(A1[r][q], this.pub_scalar[q])); } tmp_c_scal[r] = GF2Field.addElem(tmp_c_scal[r], b1[r]); } // set public key coeff_quadratic_3dim = tmp_c_quad; this.pub_singular = tmp_c_sing; this.pub_scalar = tmp_c_scal; } compactPublicKey(coeff_quadratic_3dim); } /** * The quadratic (or mixed) terms of the public key are compacted from a n x * n matrix per polynomial to an upper diagonal matrix stored in one integer * array of n (n + 1) / 2 elements per polynomial. The ordering of elements * is lexicographic and the result is updating this.pub_quadratic, * which stores the quadratic elements of the public key. * * @param coeff_quadratic_to_compact 3-dimensional array containing a n x n Matrix for each of the * n - v1 polynomials */ private void compactPublicKey(short[][][] coeff_quadratic_to_compact) { int polynomials = coeff_quadratic_to_compact.length; int n = coeff_quadratic_to_compact[0].length; int entries = n * (n + 1) / 2;// the small gauss this.pub_quadratic = new short[polynomials][entries]; int offset = 0; for (int p = 0; p < polynomials; p++) { offset = 0; for (int x = 0; x < n; x++) { for (int y = x; y < n; y++) { if (y == x) { this.pub_quadratic[p][offset] = coeff_quadratic_to_compact[p][x][y]; } else { this.pub_quadratic[p][offset] = GF2Field.addElem( coeff_quadratic_to_compact[p][x][y], coeff_quadratic_to_compact[p][y][x]); } offset++; } } } } public void init(KeyGenerationParameters param) { this.initialize(param); } public AsymmetricCipherKeyPair generateKeyPair() { return genKeyPair(); } } bouncycastle-1.49.orig/src/org/bouncycastle/pqc/crypto/rainbow/RainbowKeyGenerationParameters.java0000644000175000017500000000113511776704564033244 0ustar ebourgebourgpackage org.bouncycastle.pqc.crypto.rainbow; import java.security.SecureRandom; import org.bouncycastle.crypto.KeyGenerationParameters; public class RainbowKeyGenerationParameters extends KeyGenerationParameters { private RainbowParameters params; public RainbowKeyGenerationParameters( SecureRandom random, RainbowParameters params) { // TODO: key size? super(random, params.getVi()[params.getVi().length - 1] - params.getVi()[0]); this.params = params; } public RainbowParameters getParameters() { return params; } } bouncycastle-1.49.orig/src/org/bouncycastle/pqc/crypto/rainbow/RainbowPrivateKeyParameters.java0000644000175000017500000000523311776703514032560 0ustar ebourgebourgpackage org.bouncycastle.pqc.crypto.rainbow; public class RainbowPrivateKeyParameters extends RainbowKeyParameters { /** * Constructor * * @param A1inv the inverse of A1(the matrix part of the affine linear map L1) * (n-v1 x n-v1 matrix) * @param b1 translation vector, part of the linear affine map L1 * @param A2inv the inverse of A2(the matrix part of the affine linear map L2) * (n x n matrix) * @param b2 translation vector, part of the linear affine map L2 * @param vi the number of Vinegar-variables per layer * @param layers the polynomials with their coefficients of private map F */ public RainbowPrivateKeyParameters(short[][] A1inv, short[] b1, short[][] A2inv, short[] b2, int[] vi, Layer[] layers) { super(true, vi[vi.length - 1] - vi[0]); this.A1inv = A1inv; this.b1 = b1; this.A2inv = A2inv; this.b2 = b2; this.vi = vi; this.layers = layers; } /* * invertible affine linear map L1 */ // the inverse of A1, (n-v1 x n-v1 matrix) private short[][] A1inv; // translation vector of L1 private short[] b1; /* * invertible affine linear map L2 */ // the inverse of A2, (n x n matrix) private short[][] A2inv; // translation vector of L2 private short[] b2; /* * components of F */ // the number of Vinegar-variables per layer. private int[] vi; // contains the polynomials with their coefficients of private map F private Layer[] layers; /** * Getter for the translation part of the private quadratic map L1. * * @return b1 the translation part of L1 */ public short[] getB1() { return this.b1; } /** * Getter for the inverse matrix of A1. * * @return the A1inv inverse */ public short[][] getInvA1() { return this.A1inv; } /** * Getter for the translation part of the private quadratic map L2. * * @return b2 the translation part of L2 */ public short[] getB2() { return this.b2; } /** * Getter for the inverse matrix of A2 * * @return the A2inv */ public short[][] getInvA2() { return this.A2inv; } /** * Returns the layers contained in the private key * * @return layers */ public Layer[] getLayers() { return this.layers; } /** * /** Returns the array of vi-s * * @return the vi */ public int[] getVi() { return vi; } } bouncycastle-1.49.orig/src/org/bouncycastle/pqc/crypto/DigestingMessageSigner.java0000644000175000017500000000573511771774534030074 0ustar ebourgebourgpackage org.bouncycastle.pqc.crypto; import org.bouncycastle.crypto.CipherParameters; import org.bouncycastle.crypto.Digest; import org.bouncycastle.crypto.Signer; import org.bouncycastle.crypto.params.AsymmetricKeyParameter; import org.bouncycastle.crypto.params.ParametersWithRandom; /** * Implements the sign and verify functions for a Signature Scheme which can use a hash function. */ public class DigestingMessageSigner implements Signer { private final Digest messDigest; private final MessageSigner messSigner; private boolean forSigning; public DigestingMessageSigner(MessageSigner messSigner, Digest messDigest) { this.messSigner = messSigner; this.messDigest = messDigest; } public void init(boolean forSigning, CipherParameters param) { this.forSigning = forSigning; AsymmetricKeyParameter k; if (param instanceof ParametersWithRandom) { k = (AsymmetricKeyParameter)((ParametersWithRandom)param).getParameters(); } else { k = (AsymmetricKeyParameter)param; } if (forSigning && !k.isPrivate()) { throw new IllegalArgumentException("Signing Requires Private Key."); } if (!forSigning && k.isPrivate()) { throw new IllegalArgumentException("Verification Requires Public Key."); } reset(); messSigner.init(forSigning, param); } /** * This function signs the message that has been updated, making use of the * private key. * * @return the signature of the message. */ public byte[] generateSignature() { if (!forSigning) { throw new IllegalStateException("RainbowDigestSigner not initialised for signature generation."); } byte[] hash = new byte[messDigest.getDigestSize()]; messDigest.doFinal(hash, 0); return messSigner.generateSignature(hash); } /** * This function verifies the signature of the message that has been * updated, with the aid of the public key. * * @param signature the signature of the message is given as a byte array. * @return true if the signature has been verified, false otherwise. */ public boolean verify(byte[] signature) { if (forSigning) { throw new IllegalStateException("RainbowDigestSigner not initialised for verification"); } byte[] hash = new byte[messDigest.getDigestSize()]; messDigest.doFinal(hash, 0); return messSigner.verifySignature(hash, signature); } public void update(byte b) { messDigest.update(b); } public void update(byte[] in, int off, int len) { messDigest.update(in, off, len); } public void reset() { messDigest.reset(); } public boolean verifySignature(byte[] signature) { return this.verify(signature); } } bouncycastle-1.49.orig/src/org/bouncycastle/pqc/crypto/ntru/0000755000175000017500000000000012152033551023572 5ustar ebourgebourgbouncycastle-1.49.orig/src/org/bouncycastle/pqc/crypto/ntru/NTRUSigningKeyGenerationParameters.java0000644000175000017500000003675012113320253033263 0ustar ebourgebourgpackage org.bouncycastle.pqc.crypto.ntru; import java.io.DataInputStream; import java.io.DataOutputStream; import java.io.IOException; import java.io.InputStream; import java.io.OutputStream; import java.security.SecureRandom; import java.text.DecimalFormat; import org.bouncycastle.crypto.Digest; import org.bouncycastle.crypto.KeyGenerationParameters; import org.bouncycastle.crypto.digests.SHA256Digest; import org.bouncycastle.crypto.digests.SHA512Digest; /** * A set of parameters for NtruSign. Several predefined parameter sets are available and new ones can be created as well. */ public class NTRUSigningKeyGenerationParameters extends KeyGenerationParameters implements Cloneable { public static final int BASIS_TYPE_STANDARD = 0; public static final int BASIS_TYPE_TRANSPOSE = 1; public static final int KEY_GEN_ALG_RESULTANT = 0; public static final int KEY_GEN_ALG_FLOAT = 1; /** * Gives 128 bits of security */ public static final NTRUSigningKeyGenerationParameters APR2011_439 = new NTRUSigningKeyGenerationParameters(439, 2048, 146, 1, BASIS_TYPE_TRANSPOSE, 0.165, 400, 280, false, true, KEY_GEN_ALG_RESULTANT, new SHA256Digest()); /** * Like APR2011_439, this parameter set gives 128 bits of security but uses product-form polynomials */ public static final NTRUSigningKeyGenerationParameters APR2011_439_PROD = new NTRUSigningKeyGenerationParameters(439, 2048, 9, 8, 5, 1, BASIS_TYPE_TRANSPOSE, 0.165, 400, 280, false, true, KEY_GEN_ALG_RESULTANT, new SHA256Digest()); /** * Gives 256 bits of security */ public static final NTRUSigningKeyGenerationParameters APR2011_743 = new NTRUSigningKeyGenerationParameters(743, 2048, 248, 1, BASIS_TYPE_TRANSPOSE, 0.127, 405, 360, true, false, KEY_GEN_ALG_RESULTANT, new SHA512Digest()); /** * Like APR2011_439, this parameter set gives 256 bits of security but uses product-form polynomials */ public static final NTRUSigningKeyGenerationParameters APR2011_743_PROD = new NTRUSigningKeyGenerationParameters(743, 2048, 11, 11, 15, 1, BASIS_TYPE_TRANSPOSE, 0.127, 405, 360, true, false, KEY_GEN_ALG_RESULTANT, new SHA512Digest()); /** * Generates key pairs quickly. Use for testing only. */ public static final NTRUSigningKeyGenerationParameters TEST157 = new NTRUSigningKeyGenerationParameters(157, 256, 29, 1, BASIS_TYPE_TRANSPOSE, 0.38, 200, 80, false, false, KEY_GEN_ALG_RESULTANT, new SHA256Digest()); /** * Generates key pairs quickly. Use for testing only. */ public static final NTRUSigningKeyGenerationParameters TEST157_PROD = new NTRUSigningKeyGenerationParameters(157, 256, 5, 5, 8, 1, BASIS_TYPE_TRANSPOSE, 0.38, 200, 80, false, false, KEY_GEN_ALG_RESULTANT, new SHA256Digest()); public int N; public int q; public int d, d1, d2, d3, B; double beta; public double betaSq; double normBound; public double normBoundSq; public int signFailTolerance = 100; double keyNormBound; public double keyNormBoundSq; public boolean primeCheck; // true if N and 2N+1 are prime public int basisType; int bitsF = 6; // max #bits needed to encode one coefficient of the polynomial F public boolean sparse; // whether to treat ternary polynomials as sparsely populated public int keyGenAlg; public Digest hashAlg; public int polyType; /** * Constructs a parameter set that uses ternary private keys (i.e. polyType=SIMPLE). * * @param N number of polynomial coefficients * @param q modulus * @param d number of -1's in the private polynomials f and g * @param B number of perturbations * @param basisType whether to use the standard or transpose lattice * @param beta balancing factor for the transpose lattice * @param normBound maximum norm for valid signatures * @param keyNormBound maximum norm for the ploynomials F and G * @param primeCheck whether 2N+1 is prime * @param sparse whether to treat ternary polynomials as sparsely populated ({@link org.bouncycastle.pqc.math.ntru.polynomial.SparseTernaryPolynomial} vs {@link org.bouncycastle.pqc.math.ntru.polynomial.DenseTernaryPolynomial}) * @param keyGenAlg RESULTANT produces better bases, FLOAT is slightly faster. RESULTANT follows the EESS standard while FLOAT is described in Hoffstein et al: An Introduction to Mathematical Cryptography. * @param hashAlg a valid identifier for a java.security.MessageDigest instance such as SHA-256. The MessageDigest must support the getDigestLength() method. */ public NTRUSigningKeyGenerationParameters(int N, int q, int d, int B, int basisType, double beta, double normBound, double keyNormBound, boolean primeCheck, boolean sparse, int keyGenAlg, Digest hashAlg) { super(new SecureRandom(), N); this.N = N; this.q = q; this.d = d; this.B = B; this.basisType = basisType; this.beta = beta; this.normBound = normBound; this.keyNormBound = keyNormBound; this.primeCheck = primeCheck; this.sparse = sparse; this.keyGenAlg = keyGenAlg; this.hashAlg = hashAlg; polyType = NTRUParameters.TERNARY_POLYNOMIAL_TYPE_SIMPLE; init(); } /** * Constructs a parameter set that uses product-form private keys (i.e. polyType=PRODUCT). * * @param N number of polynomial coefficients * @param q modulus * @param d1 number of -1's in the private polynomials f and g * @param d2 number of -1's in the private polynomials f and g * @param d3 number of -1's in the private polynomials f and g * @param B number of perturbations * @param basisType whether to use the standard or transpose lattice * @param beta balancing factor for the transpose lattice * @param normBound maximum norm for valid signatures * @param keyNormBound maximum norm for the ploynomials F and G * @param primeCheck whether 2N+1 is prime * @param sparse whether to treat ternary polynomials as sparsely populated ({@link org.bouncycastle.pqc.math.ntru.polynomial.SparseTernaryPolynomial} vs {@link org.bouncycastle.pqc.math.ntru.polynomial.DenseTernaryPolynomial}) * @param keyGenAlg RESULTANT produces better bases, FLOAT is slightly faster. RESULTANT follows the EESS standard while FLOAT is described in Hoffstein et al: An Introduction to Mathematical Cryptography. * @param hashAlg a valid identifier for a java.security.MessageDigest instance such as SHA-256. The MessageDigest must support the getDigestLength() method. */ public NTRUSigningKeyGenerationParameters(int N, int q, int d1, int d2, int d3, int B, int basisType, double beta, double normBound, double keyNormBound, boolean primeCheck, boolean sparse, int keyGenAlg, Digest hashAlg) { super(new SecureRandom(), N); this.N = N; this.q = q; this.d1 = d1; this.d2 = d2; this.d3 = d3; this.B = B; this.basisType = basisType; this.beta = beta; this.normBound = normBound; this.keyNormBound = keyNormBound; this.primeCheck = primeCheck; this.sparse = sparse; this.keyGenAlg = keyGenAlg; this.hashAlg = hashAlg; polyType = NTRUParameters.TERNARY_POLYNOMIAL_TYPE_PRODUCT; init(); } private void init() { betaSq = beta * beta; normBoundSq = normBound * normBound; keyNormBoundSq = keyNormBound * keyNormBound; } /** * Reads a parameter set from an input stream. * * @param is an input stream * @throws java.io.IOException */ public NTRUSigningKeyGenerationParameters(InputStream is) throws IOException { super(new SecureRandom(), 0); // TODO: DataInputStream dis = new DataInputStream(is); N = dis.readInt(); q = dis.readInt(); d = dis.readInt(); d1 = dis.readInt(); d2 = dis.readInt(); d3 = dis.readInt(); B = dis.readInt(); basisType = dis.readInt(); beta = dis.readDouble(); normBound = dis.readDouble(); keyNormBound = dis.readDouble(); signFailTolerance = dis.readInt(); primeCheck = dis.readBoolean(); sparse = dis.readBoolean(); bitsF = dis.readInt(); keyGenAlg = dis.read(); String alg = dis.readUTF(); if ("SHA-512".equals(alg)) { hashAlg = new SHA512Digest(); } else if ("SHA-256".equals(alg)) { hashAlg = new SHA256Digest(); } polyType = dis.read(); init(); } /** * Writes the parameter set to an output stream * * @param os an output stream * @throws java.io.IOException */ public void writeTo(OutputStream os) throws IOException { DataOutputStream dos = new DataOutputStream(os); dos.writeInt(N); dos.writeInt(q); dos.writeInt(d); dos.writeInt(d1); dos.writeInt(d2); dos.writeInt(d3); dos.writeInt(B); dos.writeInt(basisType); dos.writeDouble(beta); dos.writeDouble(normBound); dos.writeDouble(keyNormBound); dos.writeInt(signFailTolerance); dos.writeBoolean(primeCheck); dos.writeBoolean(sparse); dos.writeInt(bitsF); dos.write(keyGenAlg); dos.writeUTF(hashAlg.getAlgorithmName()); dos.write(polyType); } public NTRUSigningParameters getSigningParameters() { return new NTRUSigningParameters(N, q, d, B, beta, normBound, hashAlg); } public NTRUSigningKeyGenerationParameters clone() { if (polyType == NTRUParameters.TERNARY_POLYNOMIAL_TYPE_SIMPLE) { return new NTRUSigningKeyGenerationParameters(N, q, d, B, basisType, beta, normBound, keyNormBound, primeCheck, sparse, keyGenAlg, hashAlg); } else { return new NTRUSigningKeyGenerationParameters(N, q, d1, d2, d3, B, basisType, beta, normBound, keyNormBound, primeCheck, sparse, keyGenAlg, hashAlg); } } public int hashCode() { final int prime = 31; int result = 1; result = prime * result + B; result = prime * result + N; result = prime * result + basisType; long temp; temp = Double.doubleToLongBits(beta); result = prime * result + (int)(temp ^ (temp >>> 32)); temp = Double.doubleToLongBits(betaSq); result = prime * result + (int)(temp ^ (temp >>> 32)); result = prime * result + bitsF; result = prime * result + d; result = prime * result + d1; result = prime * result + d2; result = prime * result + d3; result = prime * result + ((hashAlg == null) ? 0 : hashAlg.getAlgorithmName().hashCode()); result = prime * result + keyGenAlg; temp = Double.doubleToLongBits(keyNormBound); result = prime * result + (int)(temp ^ (temp >>> 32)); temp = Double.doubleToLongBits(keyNormBoundSq); result = prime * result + (int)(temp ^ (temp >>> 32)); temp = Double.doubleToLongBits(normBound); result = prime * result + (int)(temp ^ (temp >>> 32)); temp = Double.doubleToLongBits(normBoundSq); result = prime * result + (int)(temp ^ (temp >>> 32)); result = prime * result + polyType; result = prime * result + (primeCheck ? 1231 : 1237); result = prime * result + q; result = prime * result + signFailTolerance; result = prime * result + (sparse ? 1231 : 1237); return result; } public boolean equals(Object obj) { if (this == obj) { return true; } if (obj == null) { return false; } if (!(obj instanceof NTRUSigningKeyGenerationParameters)) { return false; } NTRUSigningKeyGenerationParameters other = (NTRUSigningKeyGenerationParameters)obj; if (B != other.B) { return false; } if (N != other.N) { return false; } if (basisType != other.basisType) { return false; } if (Double.doubleToLongBits(beta) != Double.doubleToLongBits(other.beta)) { return false; } if (Double.doubleToLongBits(betaSq) != Double.doubleToLongBits(other.betaSq)) { return false; } if (bitsF != other.bitsF) { return false; } if (d != other.d) { return false; } if (d1 != other.d1) { return false; } if (d2 != other.d2) { return false; } if (d3 != other.d3) { return false; } if (hashAlg == null) { if (other.hashAlg != null) { return false; } } else if (!hashAlg.getAlgorithmName().equals(other.hashAlg.getAlgorithmName())) { return false; } if (keyGenAlg != other.keyGenAlg) { return false; } if (Double.doubleToLongBits(keyNormBound) != Double.doubleToLongBits(other.keyNormBound)) { return false; } if (Double.doubleToLongBits(keyNormBoundSq) != Double.doubleToLongBits(other.keyNormBoundSq)) { return false; } if (Double.doubleToLongBits(normBound) != Double.doubleToLongBits(other.normBound)) { return false; } if (Double.doubleToLongBits(normBoundSq) != Double.doubleToLongBits(other.normBoundSq)) { return false; } if (polyType != other.polyType) { return false; } if (primeCheck != other.primeCheck) { return false; } if (q != other.q) { return false; } if (signFailTolerance != other.signFailTolerance) { return false; } if (sparse != other.sparse) { return false; } return true; } public String toString() { DecimalFormat format = new DecimalFormat("0.00"); StringBuilder output = new StringBuilder("SignatureParameters(N=" + N + " q=" + q); if (polyType == NTRUParameters.TERNARY_POLYNOMIAL_TYPE_SIMPLE) { output.append(" polyType=SIMPLE d=" + d); } else { output.append(" polyType=PRODUCT d1=" + d1 + " d2=" + d2 + " d3=" + d3); } output.append(" B=" + B + " basisType=" + basisType + " beta=" + format.format(beta) + " normBound=" + format.format(normBound) + " keyNormBound=" + format.format(keyNormBound) + " prime=" + primeCheck + " sparse=" + sparse + " keyGenAlg=" + keyGenAlg + " hashAlg=" + hashAlg + ")"); return output.toString(); } } bouncycastle-1.49.orig/src/org/bouncycastle/pqc/crypto/ntru/NTRUSigningKeyPairGenerator.java0000644000175000017500000002761712113320253031710 0ustar ebourgebourgpackage org.bouncycastle.pqc.crypto.ntru; import java.math.BigDecimal; import java.math.BigInteger; import java.security.SecureRandom; import java.util.ArrayList; import java.util.List; import java.util.concurrent.Callable; import java.util.concurrent.ExecutorService; import java.util.concurrent.Executors; import java.util.concurrent.Future; import org.bouncycastle.crypto.AsymmetricCipherKeyPair; import org.bouncycastle.crypto.AsymmetricCipherKeyPairGenerator; import org.bouncycastle.crypto.KeyGenerationParameters; import org.bouncycastle.pqc.math.ntru.euclid.BigIntEuclidean; import org.bouncycastle.pqc.math.ntru.polynomial.BigDecimalPolynomial; import org.bouncycastle.pqc.math.ntru.polynomial.BigIntPolynomial; import org.bouncycastle.pqc.math.ntru.polynomial.DenseTernaryPolynomial; import org.bouncycastle.pqc.math.ntru.polynomial.IntegerPolynomial; import org.bouncycastle.pqc.math.ntru.polynomial.Polynomial; import org.bouncycastle.pqc.math.ntru.polynomial.ProductFormPolynomial; import org.bouncycastle.pqc.math.ntru.polynomial.Resultant; import static java.math.BigInteger.ONE; import static java.math.BigInteger.ZERO; public class NTRUSigningKeyPairGenerator implements AsymmetricCipherKeyPairGenerator { private NTRUSigningKeyGenerationParameters params; public void init(KeyGenerationParameters param) { this.params = (NTRUSigningKeyGenerationParameters)param; } /** * Generates a new signature key pair. Starts B+1 threads. * * @return a key pair */ public AsymmetricCipherKeyPair generateKeyPair() { NTRUSigningPublicKeyParameters pub = null; ExecutorService executor = Executors.newCachedThreadPool(); List> bases = new ArrayList>(); for (int k = params.B; k >= 0; k--) { bases.add(executor.submit(new BasisGenerationTask())); } executor.shutdown(); List basises = new ArrayList(); for (int k = params.B; k >= 0; k--) { Future basis = bases.get(k); try { basises.add(basis.get()); if (k == params.B) { pub = new NTRUSigningPublicKeyParameters(basis.get().h, params.getSigningParameters()); } } catch (Exception e) { throw new IllegalStateException(e); } } NTRUSigningPrivateKeyParameters priv = new NTRUSigningPrivateKeyParameters(basises, pub); AsymmetricCipherKeyPair kp = new AsymmetricCipherKeyPair(pub, priv); return kp; } /** * Generates a new signature key pair. Runs in a single thread. * * @return a key pair */ public AsymmetricCipherKeyPair generateKeyPairSingleThread() { List basises = new ArrayList(); NTRUSigningPublicKeyParameters pub = null; for (int k = params.B; k >= 0; k--) { NTRUSigningPrivateKeyParameters.Basis basis = generateBoundedBasis(); basises.add(basis); if (k == 0) { pub = new NTRUSigningPublicKeyParameters(basis.h, params.getSigningParameters()); } } NTRUSigningPrivateKeyParameters priv = new NTRUSigningPrivateKeyParameters(basises, pub); return new AsymmetricCipherKeyPair(pub, priv); } /** * Implementation of the optional steps 20 through 26 in EESS1v2.pdf, section 3.5.1.1. * This doesn't seem to have much of an effect and sometimes actually increases the * norm of F, but on average it slightly reduces the norm.
    * This method changes F and g but leaves f and * g unchanged. * * @param f * @param g * @param F * @param G * @param N */ private void minimizeFG(IntegerPolynomial f, IntegerPolynomial g, IntegerPolynomial F, IntegerPolynomial G, int N) { int E = 0; for (int j = 0; j < N; j++) { E += 2 * N * (f.coeffs[j] * f.coeffs[j] + g.coeffs[j] * g.coeffs[j]); } // [f(1)+g(1)]^2 = 4 E -= 4; IntegerPolynomial u = (IntegerPolynomial)f.clone(); IntegerPolynomial v = (IntegerPolynomial)g.clone(); int j = 0; int k = 0; int maxAdjustment = N; while (k < maxAdjustment && j < N) { int D = 0; int i = 0; while (i < N) { int D1 = F.coeffs[i] * f.coeffs[i]; int D2 = G.coeffs[i] * g.coeffs[i]; int D3 = 4 * N * (D1 + D2); D += D3; i++; } // f(1)+g(1) = 2 int D1 = 4 * (F.sumCoeffs() + G.sumCoeffs()); D -= D1; if (D > E) { F.sub(u); G.sub(v); k++; j = 0; } else if (D < -E) { F.add(u); G.add(v); k++; j = 0; } j++; u.rotate1(); v.rotate1(); } } /** * Creates a NTRUSigner basis consisting of polynomials f, g, F, G, h.
    * If KeyGenAlg=FLOAT, the basis may not be valid and this method must be rerun if that is the case.
    * * @see #generateBoundedBasis() */ private FGBasis generateBasis() { int N = params.N; int q = params.q; int d = params.d; int d1 = params.d1; int d2 = params.d2; int d3 = params.d3; int basisType = params.basisType; Polynomial f; IntegerPolynomial fInt; Polynomial g; IntegerPolynomial gInt; IntegerPolynomial fq; Resultant rf; Resultant rg; BigIntEuclidean r; int _2n1 = 2 * N + 1; boolean primeCheck = params.primeCheck; do { do { f = params.polyType== NTRUParameters.TERNARY_POLYNOMIAL_TYPE_SIMPLE ? DenseTernaryPolynomial.generateRandom(N, d + 1, d, new SecureRandom()) : ProductFormPolynomial.generateRandom(N, d1, d2, d3 + 1, d3, new SecureRandom()); fInt = f.toIntegerPolynomial(); } while (primeCheck && fInt.resultant(_2n1).res.equals(ZERO)); fq = fInt.invertFq(q); } while (fq == null); rf = fInt.resultant(); do { do { do { g = params.polyType == NTRUParameters.TERNARY_POLYNOMIAL_TYPE_SIMPLE ? DenseTernaryPolynomial.generateRandom(N, d + 1, d, new SecureRandom()) : ProductFormPolynomial.generateRandom(N, d1, d2, d3 + 1, d3, new SecureRandom()); gInt = g.toIntegerPolynomial(); } while (primeCheck && gInt.resultant(_2n1).res.equals(ZERO)); } while (gInt.invertFq(q) == null); rg = gInt.resultant(); r = BigIntEuclidean.calculate(rf.res, rg.res); } while (!r.gcd.equals(ONE)); BigIntPolynomial A = (BigIntPolynomial)rf.rho.clone(); A.mult(r.x.multiply(BigInteger.valueOf(q))); BigIntPolynomial B = (BigIntPolynomial)rg.rho.clone(); B.mult(r.y.multiply(BigInteger.valueOf(-q))); BigIntPolynomial C; if (params.keyGenAlg == NTRUSigningKeyGenerationParameters.KEY_GEN_ALG_RESULTANT) { int[] fRevCoeffs = new int[N]; int[] gRevCoeffs = new int[N]; fRevCoeffs[0] = fInt.coeffs[0]; gRevCoeffs[0] = gInt.coeffs[0]; for (int i = 1; i < N; i++) { fRevCoeffs[i] = fInt.coeffs[N - i]; gRevCoeffs[i] = gInt.coeffs[N - i]; } IntegerPolynomial fRev = new IntegerPolynomial(fRevCoeffs); IntegerPolynomial gRev = new IntegerPolynomial(gRevCoeffs); IntegerPolynomial t = f.mult(fRev); t.add(g.mult(gRev)); Resultant rt = t.resultant(); C = fRev.mult(B); // fRev.mult(B) is actually faster than new SparseTernaryPolynomial(fRev).mult(B), possibly due to cache locality? C.add(gRev.mult(A)); C = C.mult(rt.rho); C.div(rt.res); } else { // KeyGenAlg.FLOAT // calculate ceil(log10(N)) int log10N = 0; for (int i = 1; i < N; i *= 10) { log10N++; } // * Cdec needs to be accurate to 1 decimal place so it can be correctly rounded; // * fInv loses up to (#digits of longest coeff of B) places in fInv.mult(B); // * multiplying fInv by B also multiplies the rounding error by a factor of N; // so make #decimal places of fInv the sum of the above. BigDecimalPolynomial fInv = rf.rho.div(new BigDecimal(rf.res), B.getMaxCoeffLength() + 1 + log10N); BigDecimalPolynomial gInv = rg.rho.div(new BigDecimal(rg.res), A.getMaxCoeffLength() + 1 + log10N); BigDecimalPolynomial Cdec = fInv.mult(B); Cdec.add(gInv.mult(A)); Cdec.halve(); C = Cdec.round(); } BigIntPolynomial F = (BigIntPolynomial)B.clone(); F.sub(f.mult(C)); BigIntPolynomial G = (BigIntPolynomial)A.clone(); G.sub(g.mult(C)); IntegerPolynomial FInt = new IntegerPolynomial(F); IntegerPolynomial GInt = new IntegerPolynomial(G); minimizeFG(fInt, gInt, FInt, GInt, N); Polynomial fPrime; IntegerPolynomial h; if (basisType == NTRUSigningKeyGenerationParameters.BASIS_TYPE_STANDARD) { fPrime = FInt; h = g.mult(fq, q); } else { fPrime = g; h = FInt.mult(fq, q); } h.modPositive(q); return new FGBasis(f, fPrime, h, FInt, GInt, params); } /** * Creates a basis such that |F| < keyNormBound and |G| < keyNormBound * * @return a NTRUSigner basis */ public NTRUSigningPrivateKeyParameters.Basis generateBoundedBasis() { while (true) { FGBasis basis = generateBasis(); if (basis.isNormOk()) { return basis; } } } private class BasisGenerationTask implements Callable { public NTRUSigningPrivateKeyParameters.Basis call() throws Exception { return generateBoundedBasis(); } } /** * A subclass of Basis that additionally contains the polynomials F and G. */ public class FGBasis extends NTRUSigningPrivateKeyParameters.Basis { public IntegerPolynomial F; public IntegerPolynomial G; FGBasis(Polynomial f, Polynomial fPrime, IntegerPolynomial h, IntegerPolynomial F, IntegerPolynomial G, NTRUSigningKeyGenerationParameters params) { super(f, fPrime, h, params); this.F = F; this.G = G; } /** * Returns true if the norms of the polynomials F and G * are within {@link NTRUSigningKeyGenerationParameters#keyNormBound}. * * @return */ boolean isNormOk() { double keyNormBoundSq = params.keyNormBoundSq; int q = params.q; return (F.centeredNormSq(q) < keyNormBoundSq && G.centeredNormSq(q) < keyNormBoundSq); } } } bouncycastle-1.49.orig/src/org/bouncycastle/pqc/crypto/ntru/NTRUSigningPublicKeyParameters.java0000644000175000017500000000634312151274312032407 0ustar ebourgebourgpackage org.bouncycastle.pqc.crypto.ntru; import java.io.IOException; import java.io.InputStream; import java.io.OutputStream; import org.bouncycastle.crypto.params.AsymmetricKeyParameter; import org.bouncycastle.pqc.math.ntru.polynomial.IntegerPolynomial; /** * A NtruSign public key is essentially a polynomial named h. */ public class NTRUSigningPublicKeyParameters extends AsymmetricKeyParameter { private NTRUSigningParameters params; public IntegerPolynomial h; /** * Constructs a new public key from a polynomial * * @param h the polynomial h which determines the key * @param params the NtruSign parameters to use */ public NTRUSigningPublicKeyParameters(IntegerPolynomial h, NTRUSigningParameters params) { super(false); this.h = h; this.params = params; } /** * Converts a byte array to a polynomial h and constructs a new public key * * @param b an encoded polynomial * @param params the NtruSign parameters to use */ public NTRUSigningPublicKeyParameters(byte[] b, NTRUSigningParameters params) { super(false); h = IntegerPolynomial.fromBinary(b, params.N, params.q); this.params = params; } /** * Reads a polynomial h from an input stream and constructs a new public key * * @param is an input stream * @param params the NtruSign parameters to use */ public NTRUSigningPublicKeyParameters(InputStream is, NTRUSigningParameters params) throws IOException { super(false); h = IntegerPolynomial.fromBinary(is, params.N, params.q); this.params = params; } /** * Converts the key to a byte array * * @return the encoded key */ public byte[] getEncoded() { return h.toBinary(params.q); } /** * Writes the key to an output stream * * @param os an output stream * @throws IOException */ public void writeTo(OutputStream os) throws IOException { os.write(getEncoded()); } @Override public int hashCode() { final int prime = 31; int result = 1; result = prime * result + ((h == null) ? 0 : h.hashCode()); result = prime * result + ((params == null) ? 0 : params.hashCode()); return result; } @Override public boolean equals(Object obj) { if (this == obj) { return true; } if (obj == null) { return false; } if (getClass() != obj.getClass()) { return false; } NTRUSigningPublicKeyParameters other = (NTRUSigningPublicKeyParameters)obj; if (h == null) { if (other.h != null) { return false; } } else if (!h.equals(other.h)) { return false; } if (params == null) { if (other.params != null) { return false; } } else if (!params.equals(other.params)) { return false; } return true; } }bouncycastle-1.49.orig/src/org/bouncycastle/pqc/crypto/ntru/NTRUEncryptionPublicKeyParameters.java0000644000175000017500000000650612113320253033136 0ustar ebourgebourgpackage org.bouncycastle.pqc.crypto.ntru; import java.io.IOException; import java.io.InputStream; import java.io.OutputStream; import org.bouncycastle.pqc.math.ntru.polynomial.IntegerPolynomial; /** * A NtruEncrypt public key is essentially a polynomial named h. */ public class NTRUEncryptionPublicKeyParameters extends NTRUEncryptionKeyParameters { public IntegerPolynomial h; /** * Constructs a new public key from a polynomial * * @param h the polynomial h which determines the key * @param params the NtruEncrypt parameters to use */ public NTRUEncryptionPublicKeyParameters(IntegerPolynomial h, NTRUEncryptionParameters params) { super(false, params); this.h = h; } /** * Converts a byte array to a polynomial h and constructs a new public key * * @param b an encoded polynomial * @param params the NtruEncrypt parameters to use * @see #getEncoded() */ public NTRUEncryptionPublicKeyParameters(byte[] b, NTRUEncryptionParameters params) { super(false, params); h = IntegerPolynomial.fromBinary(b, params.N, params.q); } /** * Reads a polynomial h from an input stream and constructs a new public key * * @param is an input stream * @param params the NtruEncrypt parameters to use * @see #writeTo(OutputStream) */ public NTRUEncryptionPublicKeyParameters(InputStream is, NTRUEncryptionParameters params) throws IOException { super(false, params); h = IntegerPolynomial.fromBinary(is, params.N, params.q); } /** * Converts the key to a byte array * * @return the encoded key * @see #NTRUEncryptionPublicKeyParameters(byte[], NTRUEncryptionParameters) */ public byte[] getEncoded() { return h.toBinary(params.q); } /** * Writes the key to an output stream * * @param os an output stream * @throws IOException * @see #NTRUEncryptionPublicKeyParameters(InputStream, NTRUEncryptionParameters) */ public void writeTo(OutputStream os) throws IOException { os.write(getEncoded()); } public int hashCode() { final int prime = 31; int result = 1; result = prime * result + ((h == null) ? 0 : h.hashCode()); result = prime * result + ((params == null) ? 0 : params.hashCode()); return result; } public boolean equals(Object obj) { if (this == obj) { return true; } if (obj == null) { return false; } if (!(obj instanceof NTRUEncryptionPublicKeyParameters)) { return false; } NTRUEncryptionPublicKeyParameters other = (NTRUEncryptionPublicKeyParameters)obj; if (h == null) { if (other.h != null) { return false; } } else if (!h.equals(other.h)) { return false; } if (params == null) { if (other.params != null) { return false; } } else if (!params.equals(other.params)) { return false; } return true; } }bouncycastle-1.49.orig/src/org/bouncycastle/pqc/crypto/ntru/NTRUSignerPrng.java0000644000175000017500000000274112151274312027231 0ustar ebourgebourgpackage org.bouncycastle.pqc.crypto.ntru; import java.nio.ByteBuffer; import org.bouncycastle.crypto.Digest; /** * An implementation of the deterministic pseudo-random generator in EESS section 3.7.3.1 */ public class NTRUSignerPrng { private int counter; private byte[] seed; private Digest hashAlg; /** * Constructs a new PRNG and seeds it with a byte array. * * @param seed a seed * @param hashAlg the hash algorithm to use */ NTRUSignerPrng(byte[] seed, Digest hashAlg) { counter = 0; this.seed = seed; this.hashAlg = hashAlg; } /** * Returns n random bytes * * @param n number of bytes to return * @return the next n random bytes */ byte[] nextBytes(int n) { ByteBuffer buf = ByteBuffer.allocate(n); while (buf.hasRemaining()) { ByteBuffer cbuf = ByteBuffer.allocate(seed.length + 4); cbuf.put(seed); cbuf.putInt(counter); byte[] array = cbuf.array(); byte[] hash = new byte[hashAlg.getDigestSize()]; hashAlg.update(array, 0, array.length); hashAlg.doFinal(hash, 0); if (buf.remaining() < hash.length) { buf.put(hash, 0, buf.remaining()); } else { buf.put(hash); } counter++; } return buf.array(); } }bouncycastle-1.49.orig/src/org/bouncycastle/pqc/crypto/ntru/NTRUSigningParameters.java0000644000175000017500000002035012113320253030563 0ustar ebourgebourgpackage org.bouncycastle.pqc.crypto.ntru; import java.io.DataInputStream; import java.io.DataOutputStream; import java.io.IOException; import java.io.InputStream; import java.io.OutputStream; import java.text.DecimalFormat; import org.bouncycastle.crypto.Digest; import org.bouncycastle.crypto.digests.SHA256Digest; import org.bouncycastle.crypto.digests.SHA512Digest; /** * A set of parameters for NtruSign. Several predefined parameter sets are available and new ones can be created as well. */ public class NTRUSigningParameters implements Cloneable { public int N; public int q; public int d, d1, d2, d3, B; double beta; public double betaSq; double normBound; public double normBoundSq; public int signFailTolerance = 100; int bitsF = 6; // max #bits needed to encode one coefficient of the polynomial F public Digest hashAlg; /** * Constructs a parameter set that uses ternary private keys (i.e. polyType=SIMPLE). * * @param N number of polynomial coefficients * @param q modulus * @param d number of -1's in the private polynomials f and g * @param B number of perturbations * @param beta balancing factor for the transpose lattice * @param normBound maximum norm for valid signatures * @param hashAlg a valid identifier for a java.security.MessageDigest instance such as SHA-256. The MessageDigest must support the getDigestLength() method. */ public NTRUSigningParameters(int N, int q, int d, int B, double beta, double normBound, Digest hashAlg) { this.N = N; this.q = q; this.d = d; this.B = B; this.beta = beta; this.normBound = normBound; this.hashAlg = hashAlg; init(); } /** * Constructs a parameter set that uses product-form private keys (i.e. polyType=PRODUCT). * * @param N number of polynomial coefficients * @param q modulus * @param d1 number of -1's in the private polynomials f and g * @param d2 number of -1's in the private polynomials f and g * @param d3 number of -1's in the private polynomials f and g * @param B number of perturbations * @param beta balancing factor for the transpose lattice * @param normBound maximum norm for valid signatures * @param keyNormBound maximum norm for the ploynomials F and G * @param hashAlg a valid identifier for a java.security.MessageDigest instance such as SHA-256. The MessageDigest must support the getDigestLength() method. */ public NTRUSigningParameters(int N, int q, int d1, int d2, int d3, int B, double beta, double normBound, double keyNormBound, Digest hashAlg) { this.N = N; this.q = q; this.d1 = d1; this.d2 = d2; this.d3 = d3; this.B = B; this.beta = beta; this.normBound = normBound; this.hashAlg = hashAlg; init(); } private void init() { betaSq = beta * beta; normBoundSq = normBound * normBound; } /** * Reads a parameter set from an input stream. * * @param is an input stream * @throws IOException */ public NTRUSigningParameters(InputStream is) throws IOException { DataInputStream dis = new DataInputStream(is); N = dis.readInt(); q = dis.readInt(); d = dis.readInt(); d1 = dis.readInt(); d2 = dis.readInt(); d3 = dis.readInt(); B = dis.readInt(); beta = dis.readDouble(); normBound = dis.readDouble(); signFailTolerance = dis.readInt(); bitsF = dis.readInt(); String alg = dis.readUTF(); if ("SHA-512".equals(alg)) { hashAlg = new SHA512Digest(); } else if ("SHA-256".equals(alg)) { hashAlg = new SHA256Digest(); } init(); } /** * Writes the parameter set to an output stream * * @param os an output stream * @throws IOException */ public void writeTo(OutputStream os) throws IOException { DataOutputStream dos = new DataOutputStream(os); dos.writeInt(N); dos.writeInt(q); dos.writeInt(d); dos.writeInt(d1); dos.writeInt(d2); dos.writeInt(d3); dos.writeInt(B); dos.writeDouble(beta); dos.writeDouble(normBound); dos.writeInt(signFailTolerance); dos.writeInt(bitsF); dos.writeUTF(hashAlg.getAlgorithmName()); } public NTRUSigningParameters clone() { return new NTRUSigningParameters(N, q, d, B, beta, normBound, hashAlg); } public int hashCode() { final int prime = 31; int result = 1; result = prime * result + B; result = prime * result + N; long temp; temp = Double.doubleToLongBits(beta); result = prime * result + (int)(temp ^ (temp >>> 32)); temp = Double.doubleToLongBits(betaSq); result = prime * result + (int)(temp ^ (temp >>> 32)); result = prime * result + bitsF; result = prime * result + d; result = prime * result + d1; result = prime * result + d2; result = prime * result + d3; result = prime * result + ((hashAlg == null) ? 0 : hashAlg.getAlgorithmName().hashCode()); temp = Double.doubleToLongBits(normBound); result = prime * result + (int)(temp ^ (temp >>> 32)); temp = Double.doubleToLongBits(normBoundSq); result = prime * result + (int)(temp ^ (temp >>> 32)); result = prime * result + q; result = prime * result + signFailTolerance; return result; } public boolean equals(Object obj) { if (this == obj) { return true; } if (obj == null) { return false; } if (!(obj instanceof NTRUSigningParameters)) { return false; } NTRUSigningParameters other = (NTRUSigningParameters)obj; if (B != other.B) { return false; } if (N != other.N) { return false; } if (Double.doubleToLongBits(beta) != Double.doubleToLongBits(other.beta)) { return false; } if (Double.doubleToLongBits(betaSq) != Double.doubleToLongBits(other.betaSq)) { return false; } if (bitsF != other.bitsF) { return false; } if (d != other.d) { return false; } if (d1 != other.d1) { return false; } if (d2 != other.d2) { return false; } if (d3 != other.d3) { return false; } if (hashAlg == null) { if (other.hashAlg != null) { return false; } } else if (!hashAlg.getAlgorithmName().equals(other.hashAlg.getAlgorithmName())) { return false; } if (Double.doubleToLongBits(normBound) != Double.doubleToLongBits(other.normBound)) { return false; } if (Double.doubleToLongBits(normBoundSq) != Double.doubleToLongBits(other.normBoundSq)) { return false; } if (q != other.q) { return false; } if (signFailTolerance != other.signFailTolerance) { return false; } return true; } public String toString() { DecimalFormat format = new DecimalFormat("0.00"); StringBuilder output = new StringBuilder("SignatureParameters(N=" + N + " q=" + q); output.append(" B=" + B + " beta=" + format.format(beta) + " normBound=" + format.format(normBound) + " hashAlg=" + hashAlg + ")"); return output.toString(); } } bouncycastle-1.49.orig/src/org/bouncycastle/pqc/crypto/ntru/NTRUEncryptionParameters.java0000644000175000017500000003212312113320253031320 0ustar ebourgebourgpackage org.bouncycastle.pqc.crypto.ntru; import java.io.DataInputStream; import java.io.DataOutputStream; import java.io.IOException; import java.io.InputStream; import java.io.OutputStream; import java.util.Arrays; import org.bouncycastle.crypto.Digest; import org.bouncycastle.crypto.digests.SHA256Digest; import org.bouncycastle.crypto.digests.SHA512Digest; /** * A set of parameters for NtruEncrypt. Several predefined parameter sets are available and new ones can be created as well. */ public class NTRUEncryptionParameters implements Cloneable { public int N, q, df, df1, df2, df3; public int dr; public int dr1; public int dr2; public int dr3; public int dg; int llen; public int maxMsgLenBytes; public int db; public int bufferLenBits; int bufferLenTrits; public int dm0; public int pkLen; public int c; public int minCallsR; public int minCallsMask; public boolean hashSeed; public byte[] oid; public boolean sparse; public boolean fastFp; public int polyType; public Digest hashAlg; /** * Constructs a parameter set that uses ternary private keys (i.e. polyType=SIMPLE). * * @param N number of polynomial coefficients * @param q modulus * @param df number of ones in the private polynomial f * @param dm0 minimum acceptable number of -1's, 0's, and 1's in the polynomial m' in the last encryption step * @param db number of random bits to prepend to the message * @param c a parameter for the Index Generation Function ({@link org.bouncycastle.pqc.crypto.ntru.IndexGenerator}) * @param minCallsR minimum number of hash calls for the IGF to make * @param minCallsMask minimum number of calls to generate the masking polynomial * @param hashSeed whether to hash the seed in the MGF first (true) or use the seed directly (false) * @param oid three bytes that uniquely identify the parameter set * @param sparse whether to treat ternary polynomials as sparsely populated ({@link org.bouncycastle.pqc.math.ntru.polynomial.SparseTernaryPolynomial} vs {@link org.bouncycastle.pqc.math.ntru.polynomial.DenseTernaryPolynomial}) * @param fastFp whether f=1+p*F for a ternary F (true) or f is ternary (false) * @param hashAlg a valid identifier for a java.security.MessageDigest instance such as SHA-256. The MessageDigest must support the getDigestLength() method. */ public NTRUEncryptionParameters(int N, int q, int df, int dm0, int db, int c, int minCallsR, int minCallsMask, boolean hashSeed, byte[] oid, boolean sparse, boolean fastFp, Digest hashAlg) { this.N = N; this.q = q; this.df = df; this.db = db; this.dm0 = dm0; this.c = c; this.minCallsR = minCallsR; this.minCallsMask = minCallsMask; this.hashSeed = hashSeed; this.oid = oid; this.sparse = sparse; this.fastFp = fastFp; this.polyType = NTRUParameters.TERNARY_POLYNOMIAL_TYPE_SIMPLE; this.hashAlg = hashAlg; init(); } /** * Constructs a parameter set that uses product-form private keys (i.e. polyType=PRODUCT). * * @param N number of polynomial coefficients * @param q modulus * @param df1 number of ones in the private polynomial f1 * @param df2 number of ones in the private polynomial f2 * @param df3 number of ones in the private polynomial f3 * @param dm0 minimum acceptable number of -1's, 0's, and 1's in the polynomial m' in the last encryption step * @param db number of random bits to prepend to the message * @param c a parameter for the Index Generation Function ({@link org.bouncycastle.pqc.crypto.ntru.IndexGenerator}) * @param minCallsR minimum number of hash calls for the IGF to make * @param minCallsMask minimum number of calls to generate the masking polynomial * @param hashSeed whether to hash the seed in the MGF first (true) or use the seed directly (false) * @param oid three bytes that uniquely identify the parameter set * @param sparse whether to treat ternary polynomials as sparsely populated ({@link org.bouncycastle.pqc.math.ntru.polynomial.SparseTernaryPolynomial} vs {@link org.bouncycastle.pqc.math.ntru.polynomial.DenseTernaryPolynomial}) * @param fastFp whether f=1+p*F for a ternary F (true) or f is ternary (false) * @param hashAlg a valid identifier for a java.security.MessageDigest instance such as SHA-256 */ public NTRUEncryptionParameters(int N, int q, int df1, int df2, int df3, int dm0, int db, int c, int minCallsR, int minCallsMask, boolean hashSeed, byte[] oid, boolean sparse, boolean fastFp, Digest hashAlg) { this.N = N; this.q = q; this.df1 = df1; this.df2 = df2; this.df3 = df3; this.db = db; this.dm0 = dm0; this.c = c; this.minCallsR = minCallsR; this.minCallsMask = minCallsMask; this.hashSeed = hashSeed; this.oid = oid; this.sparse = sparse; this.fastFp = fastFp; this.polyType = NTRUParameters.TERNARY_POLYNOMIAL_TYPE_PRODUCT; this.hashAlg = hashAlg; init(); } private void init() { dr = df; dr1 = df1; dr2 = df2; dr3 = df3; dg = N / 3; llen = 1; // ceil(log2(maxMsgLenBytes)) maxMsgLenBytes = N * 3 / 2 / 8 - llen - db / 8 - 1; bufferLenBits = (N * 3 / 2 + 7) / 8 * 8 + 1; bufferLenTrits = N - 1; pkLen = db; } /** * Reads a parameter set from an input stream. * * @param is an input stream * @throws IOException */ public NTRUEncryptionParameters(InputStream is) throws IOException { DataInputStream dis = new DataInputStream(is); N = dis.readInt(); q = dis.readInt(); df = dis.readInt(); df1 = dis.readInt(); df2 = dis.readInt(); df3 = dis.readInt(); db = dis.readInt(); dm0 = dis.readInt(); c = dis.readInt(); minCallsR = dis.readInt(); minCallsMask = dis.readInt(); hashSeed = dis.readBoolean(); oid = new byte[3]; dis.read(oid); sparse = dis.readBoolean(); fastFp = dis.readBoolean(); polyType = dis.read(); String alg = dis.readUTF(); if ("SHA-512".equals(alg)) { hashAlg = new SHA512Digest(); } else if ("SHA-256".equals(alg)) { hashAlg = new SHA256Digest(); } init(); } public NTRUEncryptionParameters clone() { if (polyType == NTRUParameters.TERNARY_POLYNOMIAL_TYPE_SIMPLE) { return new NTRUEncryptionParameters(N, q, df, dm0, db, c, minCallsR, minCallsMask, hashSeed, oid, sparse, fastFp, hashAlg); } else { return new NTRUEncryptionParameters(N, q, df1, df2, df3, dm0, db, c, minCallsR, minCallsMask, hashSeed, oid, sparse, fastFp, hashAlg); } } /** * Returns the maximum length a plaintext message can be with this parameter set. * * @return the maximum length in bytes */ public int getMaxMessageLength() { return maxMsgLenBytes; } /** * Writes the parameter set to an output stream * * @param os an output stream * @throws IOException */ public void writeTo(OutputStream os) throws IOException { DataOutputStream dos = new DataOutputStream(os); dos.writeInt(N); dos.writeInt(q); dos.writeInt(df); dos.writeInt(df1); dos.writeInt(df2); dos.writeInt(df3); dos.writeInt(db); dos.writeInt(dm0); dos.writeInt(c); dos.writeInt(minCallsR); dos.writeInt(minCallsMask); dos.writeBoolean(hashSeed); dos.write(oid); dos.writeBoolean(sparse); dos.writeBoolean(fastFp); dos.write(polyType); dos.writeUTF(hashAlg.getAlgorithmName()); } public int hashCode() { final int prime = 31; int result = 1; result = prime * result + N; result = prime * result + bufferLenBits; result = prime * result + bufferLenTrits; result = prime * result + c; result = prime * result + db; result = prime * result + df; result = prime * result + df1; result = prime * result + df2; result = prime * result + df3; result = prime * result + dg; result = prime * result + dm0; result = prime * result + dr; result = prime * result + dr1; result = prime * result + dr2; result = prime * result + dr3; result = prime * result + (fastFp ? 1231 : 1237); result = prime * result + ((hashAlg == null) ? 0 : hashAlg.getAlgorithmName().hashCode()); result = prime * result + (hashSeed ? 1231 : 1237); result = prime * result + llen; result = prime * result + maxMsgLenBytes; result = prime * result + minCallsMask; result = prime * result + minCallsR; result = prime * result + Arrays.hashCode(oid); result = prime * result + pkLen; result = prime * result + polyType; result = prime * result + q; result = prime * result + (sparse ? 1231 : 1237); return result; } public boolean equals(Object obj) { if (this == obj) { return true; } if (obj == null) { return false; } if (getClass() != obj.getClass()) { return false; } NTRUEncryptionParameters other = (NTRUEncryptionParameters)obj; if (N != other.N) { return false; } if (bufferLenBits != other.bufferLenBits) { return false; } if (bufferLenTrits != other.bufferLenTrits) { return false; } if (c != other.c) { return false; } if (db != other.db) { return false; } if (df != other.df) { return false; } if (df1 != other.df1) { return false; } if (df2 != other.df2) { return false; } if (df3 != other.df3) { return false; } if (dg != other.dg) { return false; } if (dm0 != other.dm0) { return false; } if (dr != other.dr) { return false; } if (dr1 != other.dr1) { return false; } if (dr2 != other.dr2) { return false; } if (dr3 != other.dr3) { return false; } if (fastFp != other.fastFp) { return false; } if (hashAlg == null) { if (other.hashAlg != null) { return false; } } else if (!hashAlg.getAlgorithmName().equals(other.hashAlg.getAlgorithmName())) { return false; } if (hashSeed != other.hashSeed) { return false; } if (llen != other.llen) { return false; } if (maxMsgLenBytes != other.maxMsgLenBytes) { return false; } if (minCallsMask != other.minCallsMask) { return false; } if (minCallsR != other.minCallsR) { return false; } if (!Arrays.equals(oid, other.oid)) { return false; } if (pkLen != other.pkLen) { return false; } if (polyType != other.polyType) { return false; } if (q != other.q) { return false; } if (sparse != other.sparse) { return false; } return true; } public String toString() { StringBuilder output = new StringBuilder("EncryptionParameters(N=" + N + " q=" + q); if (polyType == NTRUParameters.TERNARY_POLYNOMIAL_TYPE_SIMPLE) { output.append(" polyType=SIMPLE df=" + df); } else { output.append(" polyType=PRODUCT df1=" + df1 + " df2=" + df2 + " df3=" + df3); } output.append(" dm0=" + dm0 + " db=" + db + " c=" + c + " minCallsR=" + minCallsR + " minCallsMask=" + minCallsMask + " hashSeed=" + hashSeed + " hashAlg=" + hashAlg + " oid=" + Arrays.toString(oid) + " sparse=" + sparse + ")"); return output.toString(); } } bouncycastle-1.49.orig/src/org/bouncycastle/pqc/crypto/ntru/NTRUEncryptionKeyParameters.java0000644000175000017500000000075112113320253031773 0ustar ebourgebourgpackage org.bouncycastle.pqc.crypto.ntru; import org.bouncycastle.crypto.params.AsymmetricKeyParameter; public class NTRUEncryptionKeyParameters extends AsymmetricKeyParameter { final protected NTRUEncryptionParameters params; public NTRUEncryptionKeyParameters(boolean privateKey, NTRUEncryptionParameters params) { super(privateKey); this.params = params; } public NTRUEncryptionParameters getParameters() { return params; } } bouncycastle-1.49.orig/src/org/bouncycastle/pqc/crypto/ntru/NTRUSigningPrivateKeyParameters.java0000644000175000017500000002557712113320253032607 0ustar ebourgebourgpackage org.bouncycastle.pqc.crypto.ntru; import java.io.ByteArrayInputStream; import java.io.ByteArrayOutputStream; import java.io.IOException; import java.io.InputStream; import java.io.OutputStream; import java.util.ArrayList; import java.util.List; import org.bouncycastle.crypto.params.AsymmetricKeyParameter; import org.bouncycastle.pqc.math.ntru.polynomial.DenseTernaryPolynomial; import org.bouncycastle.pqc.math.ntru.polynomial.IntegerPolynomial; import org.bouncycastle.pqc.math.ntru.polynomial.Polynomial; import org.bouncycastle.pqc.math.ntru.polynomial.ProductFormPolynomial; import org.bouncycastle.pqc.math.ntru.polynomial.SparseTernaryPolynomial; /** * A NtruSign private key comprises one or more {@link NTRUSigningPrivateKeyParameters.Basis} of three polynomials each, * except the zeroth basis for which h is undefined. */ public class NTRUSigningPrivateKeyParameters extends AsymmetricKeyParameter { private List bases; private NTRUSigningPublicKeyParameters publicKey; /** * Constructs a new private key from a byte array * * @param b an encoded private key * @param params the NtruSign parameters to use */ public NTRUSigningPrivateKeyParameters(byte[] b, NTRUSigningKeyGenerationParameters params) throws IOException { this(new ByteArrayInputStream(b), params); } /** * Constructs a new private key from an input stream * * @param is an input stream * @param params the NtruSign parameters to use */ public NTRUSigningPrivateKeyParameters(InputStream is, NTRUSigningKeyGenerationParameters params) throws IOException { super(true); bases = new ArrayList(); for (int i = 0; i <= params.B; i++) // include a public key h[i] in all bases except for the first one { add(new Basis(is, params, i != 0)); } publicKey = new NTRUSigningPublicKeyParameters(is, params.getSigningParameters()); } public NTRUSigningPrivateKeyParameters(List bases, NTRUSigningPublicKeyParameters publicKey) { super(true); this.bases = new ArrayList(bases); this.publicKey = publicKey; } /** * Adds a basis to the key. * * @param b a NtruSign basis */ private void add(Basis b) { bases.add(b); } /** * Returns the i-th basis * * @param i the index * @return the basis at index i */ public Basis getBasis(int i) { return bases.get(i); } public NTRUSigningPublicKeyParameters getPublicKey() { return publicKey; } /** * Converts the key to a byte array * * @return the encoded key */ public byte[] getEncoded() throws IOException { ByteArrayOutputStream os = new ByteArrayOutputStream(); for (int i = 0; i < bases.size(); i++) { // all bases except for the first one contain a public key bases.get(i).encode(os, i != 0); } os.write(publicKey.getEncoded()); return os.toByteArray(); } /** * Writes the key to an output stream * * @param os an output stream * @throws IOException */ public void writeTo(OutputStream os) throws IOException { os.write(getEncoded()); } @Override public int hashCode() { final int prime = 31; int result = 1; result = prime * result + ((bases == null) ? 0 : bases.hashCode()); for (Basis basis : bases) { result += basis.hashCode(); } return result; } @Override public boolean equals(Object obj) { if (this == obj) { return true; } if (obj == null) { return false; } if (getClass() != obj.getClass()) { return false; } NTRUSigningPrivateKeyParameters other = (NTRUSigningPrivateKeyParameters)obj; if (bases == null) { if (other.bases != null) { return false; } } if (bases.size() != other.bases.size()) { return false; } for (int i = 0; i < bases.size(); i++) { Basis basis1 = bases.get(i); Basis basis2 = other.bases.get(i); if (!basis1.f.equals(basis2.f)) { return false; } if (!basis1.fPrime.equals(basis2.fPrime)) { return false; } if (i != 0 && !basis1.h.equals(basis2.h)) // don't compare h for the 0th basis { return false; } if (!basis1.params.equals(basis2.params)) { return false; } } return true; } /** * A NtruSign basis. Contains three polynomials f, f', h. */ public static class Basis { public Polynomial f; public Polynomial fPrime; public IntegerPolynomial h; NTRUSigningKeyGenerationParameters params; /** * Constructs a new basis from polynomials f, f', h. * * @param f * @param fPrime * @param h * @param params NtruSign parameters */ protected Basis(Polynomial f, Polynomial fPrime, IntegerPolynomial h, NTRUSigningKeyGenerationParameters params) { this.f = f; this.fPrime = fPrime; this.h = h; this.params = params; } /** * Reads a basis from an input stream and constructs a new basis. * * @param is an input stream * @param params NtruSign parameters * @param include_h whether to read the polynomial h (true) or only f and f' (false) */ Basis(InputStream is, NTRUSigningKeyGenerationParameters params, boolean include_h) throws IOException { int N = params.N; int q = params.q; int d1 = params.d1; int d2 = params.d2; int d3 = params.d3; boolean sparse = params.sparse; this.params = params; if (params.polyType == NTRUParameters.TERNARY_POLYNOMIAL_TYPE_PRODUCT) { f = ProductFormPolynomial.fromBinary(is, N, d1, d2, d3 + 1, d3); } else { IntegerPolynomial fInt = IntegerPolynomial.fromBinary3Tight(is, N); f = sparse ? new SparseTernaryPolynomial(fInt) : new DenseTernaryPolynomial(fInt); } if (params.basisType == NTRUSigningKeyGenerationParameters.BASIS_TYPE_STANDARD) { IntegerPolynomial fPrimeInt = IntegerPolynomial.fromBinary(is, N, q); for (int i = 0; i < fPrimeInt.coeffs.length; i++) { fPrimeInt.coeffs[i] -= q / 2; } fPrime = fPrimeInt; } else if (params.polyType == NTRUParameters.TERNARY_POLYNOMIAL_TYPE_PRODUCT) { fPrime = ProductFormPolynomial.fromBinary(is, N, d1, d2, d3 + 1, d3); } else { fPrime = IntegerPolynomial.fromBinary3Tight(is, N); } if (include_h) { h = IntegerPolynomial.fromBinary(is, N, q); } } /** * Writes the basis to an output stream * * @param os an output stream * @param include_h whether to write the polynomial h (true) or only f and f' (false) * @throws IOException */ void encode(OutputStream os, boolean include_h) throws IOException { int q = params.q; os.write(getEncoded(f)); if (params.basisType == NTRUSigningKeyGenerationParameters.BASIS_TYPE_STANDARD) { IntegerPolynomial fPrimeInt = fPrime.toIntegerPolynomial(); for (int i = 0; i < fPrimeInt.coeffs.length; i++) { fPrimeInt.coeffs[i] += q / 2; } os.write(fPrimeInt.toBinary(q)); } else { os.write(getEncoded(fPrime)); } if (include_h) { os.write(h.toBinary(q)); } } private byte[] getEncoded(Polynomial p) { if (p instanceof ProductFormPolynomial) { return ((ProductFormPolynomial)p).toBinary(); } else { return p.toIntegerPolynomial().toBinary3Tight(); } } @Override public int hashCode() { final int prime = 31; int result = 1; result = prime * result + ((f == null) ? 0 : f.hashCode()); result = prime * result + ((fPrime == null) ? 0 : fPrime.hashCode()); result = prime * result + ((h == null) ? 0 : h.hashCode()); result = prime * result + ((params == null) ? 0 : params.hashCode()); return result; } @Override public boolean equals(Object obj) { if (this == obj) { return true; } if (obj == null) { return false; } if (!(obj instanceof Basis)) { return false; } Basis other = (Basis)obj; if (f == null) { if (other.f != null) { return false; } } else if (!f.equals(other.f)) { return false; } if (fPrime == null) { if (other.fPrime != null) { return false; } } else if (!fPrime.equals(other.fPrime)) { return false; } if (h == null) { if (other.h != null) { return false; } } else if (!h.equals(other.h)) { return false; } if (params == null) { if (other.params != null) { return false; } } else if (!params.equals(other.params)) { return false; } return true; } } }bouncycastle-1.49.orig/src/org/bouncycastle/pqc/crypto/ntru/IndexGenerator.java0000644000175000017500000001467212113320253027360 0ustar ebourgebourgpackage org.bouncycastle.pqc.crypto.ntru; import org.bouncycastle.crypto.Digest; import org.bouncycastle.util.Arrays; /** * An implementation of the Index Generation Function in IEEE P1363.1. */ public class IndexGenerator { private byte[] seed; private int N; private int c; private int minCallsR; private int totLen; private int remLen; private BitString buf; private int counter; private boolean initialized; private Digest hashAlg; private int hLen; /** * Constructs a new index generator. * * @param seed a seed of arbitrary length to initialize the index generator with * @param params NtruEncrypt parameters */ IndexGenerator(byte[] seed, NTRUEncryptionParameters params) { this.seed = seed; N = params.N; c = params.c; minCallsR = params.minCallsR; totLen = 0; remLen = 0; counter = 0; hashAlg = params.hashAlg; hLen = hashAlg.getDigestSize(); // hash length initialized = false; } /** * Returns a number i such that 0 <= i < N. * * @return */ int nextIndex() { if (!initialized) { buf = new BitString(); byte[] hash = new byte[hashAlg.getDigestSize()]; while (counter < minCallsR) { appendHash(buf, hash); counter++; } totLen = minCallsR * 8 * hLen; remLen = totLen; initialized = true; } while (true) { totLen += c; BitString M = buf.getTrailing(remLen); if (remLen < c) { int tmpLen = c - remLen; int cThreshold = counter + (tmpLen + hLen - 1) / hLen; byte[] hash = new byte[hashAlg.getDigestSize()]; while (counter < cThreshold) { appendHash(M, hash); counter++; if (tmpLen > 8 * hLen) { tmpLen -= 8 * hLen; } } remLen = 8 * hLen - tmpLen; buf = new BitString(); buf.appendBits(hash); } else { remLen -= c; } int i = M.getLeadingAsInt(c); // assume c<32 if (i < (1 << c) - ((1 << c) % N)) { return i % N; } } } private void appendHash(BitString m, byte[] hash) { hashAlg.update(seed, 0, seed.length); putInt(hashAlg, counter); hashAlg.doFinal(hash, 0); m.appendBits(hash); } private void putInt(Digest hashAlg, int counter) { hashAlg.update((byte)(counter >> 24)); hashAlg.update((byte)(counter >> 16)); hashAlg.update((byte)(counter >> 8)); hashAlg.update((byte)counter); } /** * Represents a string of bits and supports appending, reading the head, and reading the tail. */ public static class BitString { byte[] bytes = new byte[4]; int numBytes; // includes the last byte even if only some of its bits are used int lastByteBits; // lastByteBits <= 8 /** * Appends all bits in a byte array to the end of the bit string. * * @param bytes a byte array */ void appendBits(byte[] bytes) { for (int i = 0; i != bytes.length; i++) { appendBits(bytes[i]); } } /** * Appends all bits in a byte to the end of the bit string. * * @param b a byte */ public void appendBits(byte b) { if (numBytes == bytes.length) { bytes = copyOf(bytes, 2 * bytes.length); } if (numBytes == 0) { numBytes = 1; bytes[0] = b; lastByteBits = 8; } else if (lastByteBits == 8) { bytes[numBytes++] = b; } else { int s = 8 - lastByteBits; bytes[numBytes - 1] |= (b & 0xFF) << lastByteBits; bytes[numBytes++] = (byte)((b & 0xFF) >> s); } } /** * Returns the last numBits bits from the end of the bit string. * * @param numBits number of bits * @return a new BitString of length numBits */ public BitString getTrailing(int numBits) { BitString newStr = new BitString(); newStr.numBytes = (numBits + 7) / 8; newStr.bytes = new byte[newStr.numBytes]; for (int i = 0; i < newStr.numBytes; i++) { newStr.bytes[i] = bytes[i]; } newStr.lastByteBits = numBits % 8; if (newStr.lastByteBits == 0) { newStr.lastByteBits = 8; } else { int s = 32 - newStr.lastByteBits; newStr.bytes[newStr.numBytes - 1] = (byte)(newStr.bytes[newStr.numBytes - 1] << s >>> s); } return newStr; } /** * Returns up to 32 bits from the beginning of the bit string. * * @param numBits number of bits * @return an int whose lower numBits bits are the beginning of the bit string */ public int getLeadingAsInt(int numBits) { int startBit = (numBytes - 1) * 8 + lastByteBits - numBits; int startByte = startBit / 8; int startBitInStartByte = startBit % 8; int sum = (bytes[startByte] & 0xFF) >>> startBitInStartByte; int shift = 8 - startBitInStartByte; for (int i = startByte + 1; i < numBytes; i++) { sum |= (bytes[i] & 0xFF) << shift; shift += 8; } return sum; } public byte[] getBytes() { return Arrays.clone(bytes); } } private static byte[] copyOf(byte[] src, int len) { byte[] tmp = new byte[len]; System.arraycopy(src, 0, tmp, 0, len < src.length ? len : src.length); return tmp; } }././@LongLink0000000000000000000000000000014700000000000011567 Lustar rootrootbouncycastle-1.49.orig/src/org/bouncycastle/pqc/crypto/ntru/NTRUEncryptionKeyGenerationParameters.javabouncycastle-1.49.orig/src/org/bouncycastle/pqc/crypto/ntru/NTRUEncryptionKeyGenerationParameters.ja0000644000175000017500000004064612113320253033467 0ustar ebourgebourgpackage org.bouncycastle.pqc.crypto.ntru; import java.io.DataInputStream; import java.io.DataOutputStream; import java.io.IOException; import java.io.InputStream; import java.io.OutputStream; import java.security.SecureRandom; import java.util.Arrays; import org.bouncycastle.crypto.Digest; import org.bouncycastle.crypto.KeyGenerationParameters; import org.bouncycastle.crypto.digests.SHA256Digest; import org.bouncycastle.crypto.digests.SHA512Digest; /** * A set of parameters for NtruEncrypt. Several predefined parameter sets are available and new ones can be created as well. */ public class NTRUEncryptionKeyGenerationParameters extends KeyGenerationParameters implements Cloneable { /** * A conservative (in terms of security) parameter set that gives 256 bits of security and is optimized for key size. */ public static final NTRUEncryptionKeyGenerationParameters EES1087EP2 = new NTRUEncryptionKeyGenerationParameters(1087, 2048, 120, 120, 256, 13, 25, 14, true, new byte[]{0, 6, 3}, true, false, new SHA512Digest()); /** * A conservative (in terms of security) parameter set that gives 256 bits of security and is a tradeoff between key size and encryption/decryption speed. */ public static final NTRUEncryptionKeyGenerationParameters EES1171EP1 = new NTRUEncryptionKeyGenerationParameters(1171, 2048, 106, 106, 256, 13, 20, 15, true, new byte[]{0, 6, 4}, true, false, new SHA512Digest()); /** * A conservative (in terms of security) parameter set that gives 256 bits of security and is optimized for encryption/decryption speed. */ public static final NTRUEncryptionKeyGenerationParameters EES1499EP1 = new NTRUEncryptionKeyGenerationParameters(1499, 2048, 79, 79, 256, 13, 17, 19, true, new byte[]{0, 6, 5}, true, false, new SHA512Digest()); /** * A parameter set that gives 128 bits of security and uses simple ternary polynomials. */ public static final NTRUEncryptionKeyGenerationParameters APR2011_439 = new NTRUEncryptionKeyGenerationParameters(439, 2048, 146, 130, 128, 9, 32, 9, true, new byte[]{0, 7, 101}, true, false, new SHA256Digest()); /** * Like APR2011_439, this parameter set gives 128 bits of security but uses product-form polynomials and f=1+pF. */ public static final NTRUEncryptionKeyGenerationParameters APR2011_439_FAST = new NTRUEncryptionKeyGenerationParameters(439, 2048, 9, 8, 5, 130, 128, 9, 32, 9, true, new byte[]{0, 7, 101}, true, true, new SHA256Digest()); /** * A parameter set that gives 256 bits of security and uses simple ternary polynomials. */ public static final NTRUEncryptionKeyGenerationParameters APR2011_743 = new NTRUEncryptionKeyGenerationParameters(743, 2048, 248, 220, 256, 10, 27, 14, true, new byte[]{0, 7, 105}, false, false, new SHA512Digest()); /** * Like APR2011_743, this parameter set gives 256 bits of security but uses product-form polynomials and f=1+pF. */ public static final NTRUEncryptionKeyGenerationParameters APR2011_743_FAST = new NTRUEncryptionKeyGenerationParameters(743, 2048, 11, 11, 15, 220, 256, 10, 27, 14, true, new byte[]{0, 7, 105}, false, true, new SHA512Digest()); public int N, q, df, df1, df2, df3; public int dr; public int dr1; public int dr2; public int dr3; public int dg; int llen; public int maxMsgLenBytes; public int db; public int bufferLenBits; int bufferLenTrits; public int dm0; public int pkLen; public int c; public int minCallsR; public int minCallsMask; public boolean hashSeed; public byte[] oid; public boolean sparse; public boolean fastFp; public int polyType; public Digest hashAlg; /** * Constructs a parameter set that uses ternary private keys (i.e. polyType=SIMPLE). * * @param N number of polynomial coefficients * @param q modulus * @param df number of ones in the private polynomial f * @param dm0 minimum acceptable number of -1's, 0's, and 1's in the polynomial m' in the last encryption step * @param db number of random bits to prepend to the message * @param c a parameter for the Index Generation Function ({@link org.bouncycastle.pqc.crypto.ntru.IndexGenerator}) * @param minCallsR minimum number of hash calls for the IGF to make * @param minCallsMask minimum number of calls to generate the masking polynomial * @param hashSeed whether to hash the seed in the MGF first (true) or use the seed directly (false) * @param oid three bytes that uniquely identify the parameter set * @param sparse whether to treat ternary polynomials as sparsely populated ({@link org.bouncycastle.pqc.math.ntru.polynomial.SparseTernaryPolynomial} vs {@link org.bouncycastle.pqc.math.ntru.polynomial.DenseTernaryPolynomial}) * @param fastFp whether f=1+p*F for a ternary F (true) or f is ternary (false) * @param hashAlg a valid identifier for a java.security.MessageDigest instance such as SHA-256. The MessageDigest must support the getDigestLength() method. */ public NTRUEncryptionKeyGenerationParameters(int N, int q, int df, int dm0, int db, int c, int minCallsR, int minCallsMask, boolean hashSeed, byte[] oid, boolean sparse, boolean fastFp, Digest hashAlg) { super(new SecureRandom(), db); this.N = N; this.q = q; this.df = df; this.db = db; this.dm0 = dm0; this.c = c; this.minCallsR = minCallsR; this.minCallsMask = minCallsMask; this.hashSeed = hashSeed; this.oid = oid; this.sparse = sparse; this.fastFp = fastFp; this.polyType = NTRUParameters.TERNARY_POLYNOMIAL_TYPE_SIMPLE; this.hashAlg = hashAlg; init(); } /** * Constructs a parameter set that uses product-form private keys (i.e. polyType=PRODUCT). * * @param N number of polynomial coefficients * @param q modulus * @param df1 number of ones in the private polynomial f1 * @param df2 number of ones in the private polynomial f2 * @param df3 number of ones in the private polynomial f3 * @param dm0 minimum acceptable number of -1's, 0's, and 1's in the polynomial m' in the last encryption step * @param db number of random bits to prepend to the message * @param c a parameter for the Index Generation Function ({@link org.bouncycastle.pqc.crypto.ntru.IndexGenerator}) * @param minCallsR minimum number of hash calls for the IGF to make * @param minCallsMask minimum number of calls to generate the masking polynomial * @param hashSeed whether to hash the seed in the MGF first (true) or use the seed directly (false) * @param oid three bytes that uniquely identify the parameter set * @param sparse whether to treat ternary polynomials as sparsely populated ({@link org.bouncycastle.pqc.math.ntru.polynomial.SparseTernaryPolynomial} vs {@link org.bouncycastle.pqc.math.ntru.polynomial.DenseTernaryPolynomial}) * @param fastFp whether f=1+p*F for a ternary F (true) or f is ternary (false) * @param hashAlg a valid identifier for a java.security.MessageDigest instance such as SHA-256 */ public NTRUEncryptionKeyGenerationParameters(int N, int q, int df1, int df2, int df3, int dm0, int db, int c, int minCallsR, int minCallsMask, boolean hashSeed, byte[] oid, boolean sparse, boolean fastFp, Digest hashAlg) { super(new SecureRandom(), db); this.N = N; this.q = q; this.df1 = df1; this.df2 = df2; this.df3 = df3; this.db = db; this.dm0 = dm0; this.c = c; this.minCallsR = minCallsR; this.minCallsMask = minCallsMask; this.hashSeed = hashSeed; this.oid = oid; this.sparse = sparse; this.fastFp = fastFp; this.polyType = NTRUParameters.TERNARY_POLYNOMIAL_TYPE_PRODUCT; this.hashAlg = hashAlg; init(); } private void init() { dr = df; dr1 = df1; dr2 = df2; dr3 = df3; dg = N / 3; llen = 1; // ceil(log2(maxMsgLenBytes)) maxMsgLenBytes = N * 3 / 2 / 8 - llen - db / 8 - 1; bufferLenBits = (N * 3 / 2 + 7) / 8 * 8 + 1; bufferLenTrits = N - 1; pkLen = db; } /** * Reads a parameter set from an input stream. * * @param is an input stream * @throws java.io.IOException */ public NTRUEncryptionKeyGenerationParameters(InputStream is) throws IOException { super(new SecureRandom(), -1); DataInputStream dis = new DataInputStream(is); N = dis.readInt(); q = dis.readInt(); df = dis.readInt(); df1 = dis.readInt(); df2 = dis.readInt(); df3 = dis.readInt(); db = dis.readInt(); dm0 = dis.readInt(); c = dis.readInt(); minCallsR = dis.readInt(); minCallsMask = dis.readInt(); hashSeed = dis.readBoolean(); oid = new byte[3]; dis.read(oid); sparse = dis.readBoolean(); fastFp = dis.readBoolean(); polyType = dis.read(); String alg = dis.readUTF(); if ("SHA-512".equals(alg)) { hashAlg = new SHA512Digest(); } else if ("SHA-256".equals(alg)) { hashAlg = new SHA256Digest(); } init(); } public NTRUEncryptionParameters getEncryptionParameters() { if (polyType == NTRUParameters.TERNARY_POLYNOMIAL_TYPE_SIMPLE) { return new NTRUEncryptionParameters(N, q, df, dm0, db, c, minCallsR, minCallsMask, hashSeed, oid, sparse, fastFp, hashAlg); } else { return new NTRUEncryptionParameters(N, q, df1, df2, df3, dm0, db, c, minCallsR, minCallsMask, hashSeed, oid, sparse, fastFp, hashAlg); } } public NTRUEncryptionKeyGenerationParameters clone() { if (polyType == NTRUParameters.TERNARY_POLYNOMIAL_TYPE_SIMPLE) { return new NTRUEncryptionKeyGenerationParameters(N, q, df, dm0, db, c, minCallsR, minCallsMask, hashSeed, oid, sparse, fastFp, hashAlg); } else { return new NTRUEncryptionKeyGenerationParameters(N, q, df1, df2, df3, dm0, db, c, minCallsR, minCallsMask, hashSeed, oid, sparse, fastFp, hashAlg); } } /** * Returns the maximum length a plaintext message can be with this parameter set. * * @return the maximum length in bytes */ public int getMaxMessageLength() { return maxMsgLenBytes; } /** * Writes the parameter set to an output stream * * @param os an output stream * @throws java.io.IOException */ public void writeTo(OutputStream os) throws IOException { DataOutputStream dos = new DataOutputStream(os); dos.writeInt(N); dos.writeInt(q); dos.writeInt(df); dos.writeInt(df1); dos.writeInt(df2); dos.writeInt(df3); dos.writeInt(db); dos.writeInt(dm0); dos.writeInt(c); dos.writeInt(minCallsR); dos.writeInt(minCallsMask); dos.writeBoolean(hashSeed); dos.write(oid); dos.writeBoolean(sparse); dos.writeBoolean(fastFp); dos.write(polyType); dos.writeUTF(hashAlg.getAlgorithmName()); } public int hashCode() { final int prime = 31; int result = 1; result = prime * result + N; result = prime * result + bufferLenBits; result = prime * result + bufferLenTrits; result = prime * result + c; result = prime * result + db; result = prime * result + df; result = prime * result + df1; result = prime * result + df2; result = prime * result + df3; result = prime * result + dg; result = prime * result + dm0; result = prime * result + dr; result = prime * result + dr1; result = prime * result + dr2; result = prime * result + dr3; result = prime * result + (fastFp ? 1231 : 1237); result = prime * result + ((hashAlg == null) ? 0 : hashAlg.getAlgorithmName().hashCode()); result = prime * result + (hashSeed ? 1231 : 1237); result = prime * result + llen; result = prime * result + maxMsgLenBytes; result = prime * result + minCallsMask; result = prime * result + minCallsR; result = prime * result + Arrays.hashCode(oid); result = prime * result + pkLen; result = prime * result + polyType; result = prime * result + q; result = prime * result + (sparse ? 1231 : 1237); return result; } public boolean equals(Object obj) { if (this == obj) { return true; } if (obj == null) { return false; } if (getClass() != obj.getClass()) { return false; } NTRUEncryptionKeyGenerationParameters other = (NTRUEncryptionKeyGenerationParameters)obj; if (N != other.N) { return false; } if (bufferLenBits != other.bufferLenBits) { return false; } if (bufferLenTrits != other.bufferLenTrits) { return false; } if (c != other.c) { return false; } if (db != other.db) { return false; } if (df != other.df) { return false; } if (df1 != other.df1) { return false; } if (df2 != other.df2) { return false; } if (df3 != other.df3) { return false; } if (dg != other.dg) { return false; } if (dm0 != other.dm0) { return false; } if (dr != other.dr) { return false; } if (dr1 != other.dr1) { return false; } if (dr2 != other.dr2) { return false; } if (dr3 != other.dr3) { return false; } if (fastFp != other.fastFp) { return false; } if (hashAlg == null) { if (other.hashAlg != null) { return false; } } else if (!hashAlg.getAlgorithmName().equals(other.hashAlg.getAlgorithmName())) { return false; } if (hashSeed != other.hashSeed) { return false; } if (llen != other.llen) { return false; } if (maxMsgLenBytes != other.maxMsgLenBytes) { return false; } if (minCallsMask != other.minCallsMask) { return false; } if (minCallsR != other.minCallsR) { return false; } if (!Arrays.equals(oid, other.oid)) { return false; } if (pkLen != other.pkLen) { return false; } if (polyType != other.polyType) { return false; } if (q != other.q) { return false; } if (sparse != other.sparse) { return false; } return true; } public String toString() { StringBuilder output = new StringBuilder("EncryptionParameters(N=" + N + " q=" + q); if (polyType == NTRUParameters.TERNARY_POLYNOMIAL_TYPE_SIMPLE) { output.append(" polyType=SIMPLE df=" + df); } else { output.append(" polyType=PRODUCT df1=" + df1 + " df2=" + df2 + " df3=" + df3); } output.append(" dm0=" + dm0 + " db=" + db + " c=" + c + " minCallsR=" + minCallsR + " minCallsMask=" + minCallsMask + " hashSeed=" + hashSeed + " hashAlg=" + hashAlg + " oid=" + Arrays.toString(oid) + " sparse=" + sparse + ")"); return output.toString(); } } bouncycastle-1.49.orig/src/org/bouncycastle/pqc/crypto/ntru/NTRUEncryptionKeyPairGenerator.java0000644000175000017500000000720512113320253032433 0ustar ebourgebourgpackage org.bouncycastle.pqc.crypto.ntru; import org.bouncycastle.crypto.AsymmetricCipherKeyPair; import org.bouncycastle.crypto.AsymmetricCipherKeyPairGenerator; import org.bouncycastle.crypto.KeyGenerationParameters; import org.bouncycastle.pqc.math.ntru.polynomial.DenseTernaryPolynomial; import org.bouncycastle.pqc.math.ntru.polynomial.IntegerPolynomial; import org.bouncycastle.pqc.math.ntru.polynomial.Polynomial; import org.bouncycastle.pqc.math.ntru.polynomial.ProductFormPolynomial; import org.bouncycastle.pqc.math.ntru.util.Util; /** * Generates key pairs.
    * The parameter p is hardcoded to 3. */ public class NTRUEncryptionKeyPairGenerator implements AsymmetricCipherKeyPairGenerator { private NTRUEncryptionKeyGenerationParameters params; /** * Constructs a new instance with a set of encryption parameters. * * @param param encryption parameters */ public void init(KeyGenerationParameters param) { this.params = (NTRUEncryptionKeyGenerationParameters)param; } /** * Generates a new encryption key pair. * * @return a key pair */ public AsymmetricCipherKeyPair generateKeyPair() { int N = params.N; int q = params.q; int df = params.df; int df1 = params.df1; int df2 = params.df2; int df3 = params.df3; int dg = params.dg; boolean fastFp = params.fastFp; boolean sparse = params.sparse; Polynomial t; IntegerPolynomial fq; IntegerPolynomial fp = null; // choose a random f that is invertible mod 3 and q while (true) { IntegerPolynomial f; // choose random t, calculate f and fp if (fastFp) { // if fastFp=true, f is always invertible mod 3 t = params.polyType == NTRUParameters.TERNARY_POLYNOMIAL_TYPE_SIMPLE ? Util.generateRandomTernary(N, df, df, sparse, params.getRandom()) : ProductFormPolynomial.generateRandom(N, df1, df2, df3, df3, params.getRandom()); f = t.toIntegerPolynomial(); f.mult(3); f.coeffs[0] += 1; } else { t = params.polyType == NTRUParameters.TERNARY_POLYNOMIAL_TYPE_SIMPLE ? Util.generateRandomTernary(N, df, df - 1, sparse, params.getRandom()) : ProductFormPolynomial.generateRandom(N, df1, df2, df3, df3 - 1, params.getRandom()); f = t.toIntegerPolynomial(); fp = f.invertF3(); if (fp == null) { continue; } } fq = f.invertFq(q); if (fq == null) { continue; } break; } // if fastFp=true, fp=1 if (fastFp) { fp = new IntegerPolynomial(N); fp.coeffs[0] = 1; } // choose a random g that is invertible mod q DenseTernaryPolynomial g; while (true) { g = DenseTernaryPolynomial.generateRandom(N, dg, dg - 1, params.getRandom()); if (g.invertFq(q) != null) { break; } } IntegerPolynomial h = g.mult(fq, q); h.mult3(q); h.ensurePositive(q); g.clear(); fq.clear(); NTRUEncryptionPrivateKeyParameters priv = new NTRUEncryptionPrivateKeyParameters(h, t, fp, params.getEncryptionParameters()); NTRUEncryptionPublicKeyParameters pub = new NTRUEncryptionPublicKeyParameters(h, params.getEncryptionParameters()); return new AsymmetricCipherKeyPair(pub, priv); } }bouncycastle-1.49.orig/src/org/bouncycastle/pqc/crypto/ntru/NTRUEncryptionPrivateKeyParameters.java0000644000175000017500000001334212113320253033326 0ustar ebourgebourgpackage org.bouncycastle.pqc.crypto.ntru; import java.io.ByteArrayInputStream; import java.io.IOException; import java.io.InputStream; import java.io.OutputStream; import org.bouncycastle.pqc.math.ntru.polynomial.DenseTernaryPolynomial; import org.bouncycastle.pqc.math.ntru.polynomial.IntegerPolynomial; import org.bouncycastle.pqc.math.ntru.polynomial.Polynomial; import org.bouncycastle.pqc.math.ntru.polynomial.ProductFormPolynomial; import org.bouncycastle.pqc.math.ntru.polynomial.SparseTernaryPolynomial; /** * A NtruEncrypt private key is essentially a polynomial named f * which takes different forms depending on whether product-form polynomials are used, * and on fastP
    * The inverse of f modulo p is precomputed on initialization. */ public class NTRUEncryptionPrivateKeyParameters extends NTRUEncryptionKeyParameters { public Polynomial t; public IntegerPolynomial fp; public IntegerPolynomial h; /** * Constructs a new private key from a polynomial * * @param h the public polynomial for the key. * @param t the polynomial which determines the key: if fastFp=true, f=1+3t; otherwise, f=t * @param fp the inverse of f * @param params the NtruEncrypt parameters to use */ public NTRUEncryptionPrivateKeyParameters(IntegerPolynomial h, Polynomial t, IntegerPolynomial fp, NTRUEncryptionParameters params) { super(true, params); this.h = h; this.t = t; this.fp = fp; } /** * Converts a byte array to a polynomial f and constructs a new private key * * @param b an encoded polynomial * @param params the NtruEncrypt parameters to use * @see #getEncoded() */ public NTRUEncryptionPrivateKeyParameters(byte[] b, NTRUEncryptionParameters params) throws IOException { this(new ByteArrayInputStream(b), params); } /** * Reads a polynomial f from an input stream and constructs a new private key * * @param is an input stream * @param params the NtruEncrypt parameters to use * @see #writeTo(OutputStream) */ public NTRUEncryptionPrivateKeyParameters(InputStream is, NTRUEncryptionParameters params) throws IOException { super(true, params); if (params.polyType == NTRUParameters.TERNARY_POLYNOMIAL_TYPE_PRODUCT) { int N = params.N; int df1 = params.df1; int df2 = params.df2; int df3Ones = params.df3; int df3NegOnes = params.fastFp ? params.df3 : params.df3 - 1; h = IntegerPolynomial.fromBinary(is, params.N, params.q); t = ProductFormPolynomial.fromBinary(is, N, df1, df2, df3Ones, df3NegOnes); } else { h = IntegerPolynomial.fromBinary(is, params.N, params.q); IntegerPolynomial fInt = IntegerPolynomial.fromBinary3Tight(is, params.N); t = params.sparse ? new SparseTernaryPolynomial(fInt) : new DenseTernaryPolynomial(fInt); } init(); } /** * Initializes fp from t. */ private void init() { if (params.fastFp) { fp = new IntegerPolynomial(params.N); fp.coeffs[0] = 1; } else { fp = t.toIntegerPolynomial().invertF3(); } } /** * Converts the key to a byte array * * @return the encoded key * @see #NTRUEncryptionPrivateKeyParameters(byte[], NTRUEncryptionParameters) */ public byte[] getEncoded() { byte[] hBytes = h.toBinary(params.q); byte[] tBytes; if (t instanceof ProductFormPolynomial) { tBytes = ((ProductFormPolynomial)t).toBinary(); } else { tBytes = t.toIntegerPolynomial().toBinary3Tight(); } byte[] res = new byte[hBytes.length + tBytes.length]; System.arraycopy(hBytes, 0, res, 0, hBytes.length); System.arraycopy(tBytes, 0, res, hBytes.length, tBytes.length); return res; } /** * Writes the key to an output stream * * @param os an output stream * @throws IOException * @see #NTRUEncryptionPrivateKeyParameters(InputStream, NTRUEncryptionParameters) */ public void writeTo(OutputStream os) throws IOException { os.write(getEncoded()); } public int hashCode() { final int prime = 31; int result = 1; result = prime * result + ((params == null) ? 0 : params.hashCode()); result = prime * result + ((t == null) ? 0 : t.hashCode()); result = prime * result + ((h == null) ? 0 : h.hashCode()); return result; } public boolean equals(Object obj) { if (this == obj) { return true; } if (obj == null) { return false; } if (!(obj instanceof NTRUEncryptionPrivateKeyParameters)) { return false; } NTRUEncryptionPrivateKeyParameters other = (NTRUEncryptionPrivateKeyParameters)obj; if (params == null) { if (other.params != null) { return false; } } else if (!params.equals(other.params)) { return false; } if (t == null) { if (other.t != null) { return false; } } else if (!t.equals(other.t)) { return false; } if (!h.equals(other.h)) { return false; } return true; } }bouncycastle-1.49.orig/src/org/bouncycastle/pqc/crypto/ntru/NTRUParameters.java0000644000175000017500000000031412113320253027242 0ustar ebourgebourgpackage org.bouncycastle.pqc.crypto.ntru; public class NTRUParameters { public static final int TERNARY_POLYNOMIAL_TYPE_SIMPLE = 0; public static final int TERNARY_POLYNOMIAL_TYPE_PRODUCT = 1; } bouncycastle-1.49.orig/src/org/bouncycastle/pqc/crypto/ntru/NTRUEngine.java0000644000175000017500000003544412113320253026360 0ustar ebourgebourgpackage org.bouncycastle.pqc.crypto.ntru; import java.security.SecureRandom; import org.bouncycastle.crypto.AsymmetricBlockCipher; import org.bouncycastle.crypto.CipherParameters; import org.bouncycastle.crypto.DataLengthException; import org.bouncycastle.crypto.Digest; import org.bouncycastle.crypto.InvalidCipherTextException; import org.bouncycastle.crypto.params.ParametersWithRandom; import org.bouncycastle.pqc.math.ntru.polynomial.DenseTernaryPolynomial; import org.bouncycastle.pqc.math.ntru.polynomial.IntegerPolynomial; import org.bouncycastle.pqc.math.ntru.polynomial.Polynomial; import org.bouncycastle.pqc.math.ntru.polynomial.ProductFormPolynomial; import org.bouncycastle.pqc.math.ntru.polynomial.SparseTernaryPolynomial; import org.bouncycastle.pqc.math.ntru.polynomial.TernaryPolynomial; import org.bouncycastle.util.Arrays; /** * Encrypts, decrypts data and generates key pairs.
    * The parameter p is hardcoded to 3. */ public class NTRUEngine implements AsymmetricBlockCipher { private boolean forEncryption; private NTRUEncryptionParameters params; private NTRUEncryptionPublicKeyParameters pubKey; private NTRUEncryptionPrivateKeyParameters privKey; private SecureRandom random; /** * Constructs a new instance with a set of encryption parameters. * */ public NTRUEngine() { } public void init(boolean forEncryption, CipherParameters parameters) { this.forEncryption = forEncryption; if (forEncryption) { if (parameters instanceof ParametersWithRandom) { ParametersWithRandom p = (ParametersWithRandom)parameters; this.random = p.getRandom(); this.pubKey = (NTRUEncryptionPublicKeyParameters)p.getParameters(); } else { this.random = new SecureRandom(); this.pubKey = (NTRUEncryptionPublicKeyParameters)parameters; } this.params = pubKey.getParameters(); } else { this.privKey = (NTRUEncryptionPrivateKeyParameters)parameters; this.params = privKey.getParameters(); } } public int getInputBlockSize() { return params.maxMsgLenBytes; } public int getOutputBlockSize() { return ((params.N * log2(params.q)) + 7) / 8; } public byte[] processBlock(byte[] in, int inOff, int len) throws InvalidCipherTextException { byte[] tmp = new byte[len]; System.arraycopy(in, inOff, tmp, 0, len); if (forEncryption) { return encrypt(tmp, pubKey); } else { return decrypt(tmp, privKey); } } /** * Encrypts a message.
    * See P1363.1 section 9.2.2. * * @param m The message to encrypt * @param pubKey the public key to encrypt the message with * @return the encrypted message */ private byte[] encrypt(byte[] m, NTRUEncryptionPublicKeyParameters pubKey) { IntegerPolynomial pub = pubKey.h; int N = params.N; int q = params.q; int maxLenBytes = params.maxMsgLenBytes; int db = params.db; int bufferLenBits = params.bufferLenBits; int dm0 = params.dm0; int pkLen = params.pkLen; int minCallsMask = params.minCallsMask; boolean hashSeed = params.hashSeed; byte[] oid = params.oid; int l = m.length; if (maxLenBytes > 255) { throw new IllegalArgumentException("llen values bigger than 1 are not supported"); } if (l > maxLenBytes) { throw new DataLengthException("Message too long: " + l + ">" + maxLenBytes); } while (true) { // M = b|octL|m|p0 byte[] b = new byte[db / 8]; random.nextBytes(b); byte[] p0 = new byte[maxLenBytes + 1 - l]; byte[] M = new byte[bufferLenBits / 8]; System.arraycopy(b, 0, M, 0, b.length); M[b.length] = (byte)l; System.arraycopy(m, 0, M, b.length + 1, m.length); System.arraycopy(p0, 0, M, b.length + 1 + m.length, p0.length); IntegerPolynomial mTrin = IntegerPolynomial.fromBinary3Sves(M, N); // sData = OID|m|b|hTrunc byte[] bh = pub.toBinary(q); byte[] hTrunc = copyOf(bh, pkLen / 8); byte[] sData = buildSData(oid, m, l, b, hTrunc); Polynomial r = generateBlindingPoly(sData, M); IntegerPolynomial R = r.mult(pub, q); IntegerPolynomial R4 = (IntegerPolynomial)R.clone(); R4.modPositive(4); byte[] oR4 = R4.toBinary(4); IntegerPolynomial mask = MGF(oR4, N, minCallsMask, hashSeed); mTrin.add(mask); mTrin.mod3(); if (mTrin.count(-1) < dm0) { continue; } if (mTrin.count(0) < dm0) { continue; } if (mTrin.count(1) < dm0) { continue; } R.add(mTrin, q); R.ensurePositive(q); return R.toBinary(q); } } private byte[] buildSData(byte[] oid, byte[] m, int l, byte[] b, byte[] hTrunc) { byte[] sData = new byte[oid.length + l + b.length + hTrunc.length]; System.arraycopy(oid, 0, sData, 0, oid.length); System.arraycopy(m, 0, sData, oid.length, m.length); System.arraycopy(b, 0, sData, oid.length + m.length, b.length); System.arraycopy(hTrunc, 0, sData, oid.length + m.length + b.length, hTrunc.length); return sData; } protected IntegerPolynomial encrypt(IntegerPolynomial m, TernaryPolynomial r, IntegerPolynomial pubKey) { IntegerPolynomial e = r.mult(pubKey, params.q); e.add(m, params.q); e.ensurePositive(params.q); return e; } /** * Deterministically generates a blinding polynomial from a seed and a message representative. * * @param seed * @param M message representative * @return a blinding polynomial */ private Polynomial generateBlindingPoly(byte[] seed, byte[] M) { IndexGenerator ig = new IndexGenerator(seed, params); if (params.polyType == NTRUParameters.TERNARY_POLYNOMIAL_TYPE_PRODUCT) { SparseTernaryPolynomial r1 = new SparseTernaryPolynomial(generateBlindingCoeffs(ig, params.dr1)); SparseTernaryPolynomial r2 = new SparseTernaryPolynomial(generateBlindingCoeffs(ig, params.dr2)); SparseTernaryPolynomial r3 = new SparseTernaryPolynomial(generateBlindingCoeffs(ig, params.dr3)); return new ProductFormPolynomial(r1, r2, r3); } else { int dr = params.dr; boolean sparse = params.sparse; int[] r = generateBlindingCoeffs(ig, dr); if (sparse) { return new SparseTernaryPolynomial(r); } else { return new DenseTernaryPolynomial(r); } } } /** * Generates an int array containing dr elements equal to 1 * and dr elements equal to -1 using an index generator. * * @param ig an index generator * @param dr number of ones / negative ones * @return an array containing numbers between -1 and 1 */ private int[] generateBlindingCoeffs(IndexGenerator ig, int dr) { int N = params.N; int[] r = new int[N]; for (int coeff = -1; coeff <= 1; coeff += 2) { int t = 0; while (t < dr) { int i = ig.nextIndex(); if (r[i] == 0) { r[i] = coeff; t++; } } } return r; } /** * An implementation of MGF-TP-1 from P1363.1 section 8.4.1.1. * * @param seed * @param N * @param minCallsR * @param hashSeed whether to hash the seed * @return */ private IntegerPolynomial MGF(byte[] seed, int N, int minCallsR, boolean hashSeed) { Digest hashAlg = params.hashAlg; int hashLen = hashAlg.getDigestSize(); byte[] buf = new byte[minCallsR * hashLen]; byte[] Z = hashSeed ? calcHash(hashAlg, seed) : seed; int counter = 0; while (counter < minCallsR) { hashAlg.update(Z, 0, Z.length); putInt(hashAlg, counter); byte[] hash = calcHash(hashAlg); System.arraycopy(hash, 0, buf, counter * hashLen, hashLen); counter++; } IntegerPolynomial i = new IntegerPolynomial(N); while (true) { int cur = 0; for (int index = 0; index != buf.length; index++) { int O = (int)buf[index] & 0xFF; if (O >= 243) // 243 = 3^5 { continue; } for (int terIdx = 0; terIdx < 4; terIdx++) { int rem3 = O % 3; i.coeffs[cur] = rem3 - 1; cur++; if (cur == N) { return i; } O = (O - rem3) / 3; } i.coeffs[cur] = O - 1; cur++; if (cur == N) { return i; } } if (cur >= N) { return i; } hashAlg.update(Z, 0, Z.length); putInt(hashAlg, counter); byte[] hash = calcHash(hashAlg); buf = hash; counter++; } } private void putInt(Digest hashAlg, int counter) { hashAlg.update((byte)(counter >> 24)); hashAlg.update((byte)(counter >> 16)); hashAlg.update((byte)(counter >> 8)); hashAlg.update((byte)counter); } private byte[] calcHash(Digest hashAlg) { byte[] tmp = new byte[hashAlg.getDigestSize()]; hashAlg.doFinal(tmp, 0); return tmp; } private byte[] calcHash(Digest hashAlg, byte[] input) { byte[] tmp = new byte[hashAlg.getDigestSize()]; hashAlg.update(input, 0, input.length); hashAlg.doFinal(tmp, 0); return tmp; } /** * Decrypts a message.
    * See P1363.1 section 9.2.3. * * @param data The message to decrypt * @param privKey the corresponding private key * @return the decrypted message * @throws InvalidCipherTextException if the encrypted data is invalid, or maxLenBytes is greater than 255 */ private byte[] decrypt(byte[] data, NTRUEncryptionPrivateKeyParameters privKey) throws InvalidCipherTextException { Polynomial priv_t = privKey.t; IntegerPolynomial priv_fp = privKey.fp; IntegerPolynomial pub = privKey.h; int N = params.N; int q = params.q; int db = params.db; int maxMsgLenBytes = params.maxMsgLenBytes; int dm0 = params.dm0; int pkLen = params.pkLen; int minCallsMask = params.minCallsMask; boolean hashSeed = params.hashSeed; byte[] oid = params.oid; if (maxMsgLenBytes > 255) { throw new DataLengthException("maxMsgLenBytes values bigger than 255 are not supported"); } int bLen = db / 8; IntegerPolynomial e = IntegerPolynomial.fromBinary(data, N, q); IntegerPolynomial ci = decrypt(e, priv_t, priv_fp); if (ci.count(-1) < dm0) { throw new InvalidCipherTextException("Less than dm0 coefficients equal -1"); } if (ci.count(0) < dm0) { throw new InvalidCipherTextException("Less than dm0 coefficients equal 0"); } if (ci.count(1) < dm0) { throw new InvalidCipherTextException("Less than dm0 coefficients equal 1"); } IntegerPolynomial cR = (IntegerPolynomial)e.clone(); cR.sub(ci); cR.modPositive(q); IntegerPolynomial cR4 = (IntegerPolynomial)cR.clone(); cR4.modPositive(4); byte[] coR4 = cR4.toBinary(4); IntegerPolynomial mask = MGF(coR4, N, minCallsMask, hashSeed); IntegerPolynomial cMTrin = ci; cMTrin.sub(mask); cMTrin.mod3(); byte[] cM = cMTrin.toBinary3Sves(); byte[] cb = new byte[bLen]; System.arraycopy(cM, 0, cb, 0, bLen); int cl = cM[bLen] & 0xFF; // llen=1, so read one byte if (cl > maxMsgLenBytes) { throw new InvalidCipherTextException("Message too long: " + cl + ">" + maxMsgLenBytes); } byte[] cm = new byte[cl]; System.arraycopy(cM, bLen + 1, cm, 0, cl); byte[] p0 = new byte[cM.length - (bLen + 1 + cl)]; System.arraycopy(cM, bLen + 1 + cl, p0, 0, p0.length); if (!Arrays.areEqual(p0, new byte[p0.length])) { throw new InvalidCipherTextException("The message is not followed by zeroes"); } // sData = OID|m|b|hTrunc byte[] bh = pub.toBinary(q); byte[] hTrunc = copyOf(bh, pkLen / 8); byte[] sData = buildSData(oid, cm, cl, cb, hTrunc); Polynomial cr = generateBlindingPoly(sData, cm); IntegerPolynomial cRPrime = cr.mult(pub); cRPrime.modPositive(q); if (!cRPrime.equals(cR)) { throw new InvalidCipherTextException("Invalid message encoding"); } return cm; } /** * @param e * @param priv_t a polynomial such that if fastFp=true, f=1+3*priv_t; otherwise, f=priv_t * @param priv_fp * @return */ protected IntegerPolynomial decrypt(IntegerPolynomial e, Polynomial priv_t, IntegerPolynomial priv_fp) { IntegerPolynomial a; if (params.fastFp) { a = priv_t.mult(e, params.q); a.mult(3); a.add(e); } else { a = priv_t.mult(e, params.q); } a.center0(params.q); a.mod3(); IntegerPolynomial c = params.fastFp ? a : new DenseTernaryPolynomial(a).mult(priv_fp, 3); c.center0(3); return c; } private byte[] copyOf(byte[] src, int len) { byte[] tmp = new byte[len]; System.arraycopy(src, 0, tmp, 0, len < src.length ? len : src.length); return tmp; } private int log2(int value) { if (value == 2048) { return 11; } throw new IllegalStateException("log2 not fully implemented"); } }bouncycastle-1.49.orig/src/org/bouncycastle/pqc/crypto/ntru/NTRUSigner.java0000644000175000017500000001624112113320253026374 0ustar ebourgebourgpackage org.bouncycastle.pqc.crypto.ntru; import java.nio.ByteBuffer; import org.bouncycastle.crypto.CipherParameters; import org.bouncycastle.crypto.Digest; import org.bouncycastle.pqc.math.ntru.polynomial.IntegerPolynomial; import org.bouncycastle.pqc.math.ntru.polynomial.Polynomial; /** * Signs, verifies data and generates key pairs. */ public class NTRUSigner { private NTRUSigningParameters params; private Digest hashAlg; private NTRUSigningPrivateKeyParameters signingKeyPair; private NTRUSigningPublicKeyParameters verificationKey; /** * Constructs a new instance with a set of signature parameters. * * @param params signature parameters */ public NTRUSigner(NTRUSigningParameters params) { this.params = params; } /** * Resets the engine for signing a message. * * @param forSigning * @param params */ public void init(boolean forSigning, CipherParameters params) { if (forSigning) { this.signingKeyPair = (NTRUSigningPrivateKeyParameters)params; } else { this.verificationKey = (NTRUSigningPublicKeyParameters)params; } hashAlg = this.params.hashAlg; hashAlg.reset(); } /** * Adds data to sign or verify. * * @param b data */ public void update(byte b) { if (hashAlg == null) { throw new IllegalStateException("Call initSign or initVerify first!"); } hashAlg.update(b); } /** * Adds data to sign or verify. * * @param m data * @param off offset * @param length number of bytes */ public void update(byte[] m, int off, int length) { if (hashAlg == null) { throw new IllegalStateException("Call initSign or initVerify first!"); } hashAlg.update(m, off, length); } /** * Adds data to sign and computes a signature over this data and any data previously added via {@link #update(byte[], int, int)}. * * @return a signature * @throws IllegalStateException if initSign was not called */ public byte[] generateSignature() { if (hashAlg == null || signingKeyPair == null) { throw new IllegalStateException("Call initSign first!"); } byte[] msgHash = new byte[hashAlg.getDigestSize()]; hashAlg.doFinal(msgHash, 0); return signHash(msgHash, signingKeyPair); } private byte[] signHash(byte[] msgHash, NTRUSigningPrivateKeyParameters kp) { int r = 0; IntegerPolynomial s; IntegerPolynomial i; NTRUSigningPublicKeyParameters kPub = kp.getPublicKey(); do { r++; if (r > params.signFailTolerance) { throw new IllegalStateException("Signing failed: too many retries (max=" + params.signFailTolerance + ")"); } i = createMsgRep(msgHash, r); s = sign(i, kp); } while (!verify(i, s, kPub.h)); byte[] rawSig = s.toBinary(params.q); ByteBuffer sbuf = ByteBuffer.allocate(rawSig.length + 4); sbuf.put(rawSig); sbuf.putInt(r); return sbuf.array(); } private IntegerPolynomial sign(IntegerPolynomial i, NTRUSigningPrivateKeyParameters kp) { int N = params.N; int q = params.q; int perturbationBases = params.B; NTRUSigningPrivateKeyParameters kPriv = kp; NTRUSigningPublicKeyParameters kPub = kp.getPublicKey(); IntegerPolynomial s = new IntegerPolynomial(N); int iLoop = perturbationBases; while (iLoop >= 1) { Polynomial f = kPriv.getBasis(iLoop).f; Polynomial fPrime = kPriv.getBasis(iLoop).fPrime; IntegerPolynomial y = f.mult(i); y.div(q); y = fPrime.mult(y); IntegerPolynomial x = fPrime.mult(i); x.div(q); x = f.mult(x); IntegerPolynomial si = y; si.sub(x); s.add(si); IntegerPolynomial hi = (IntegerPolynomial)kPriv.getBasis(iLoop).h.clone(); if (iLoop > 1) { hi.sub(kPriv.getBasis(iLoop - 1).h); } else { hi.sub(kPub.h); } i = si.mult(hi, q); iLoop--; } Polynomial f = kPriv.getBasis(0).f; Polynomial fPrime = kPriv.getBasis(0).fPrime; IntegerPolynomial y = f.mult(i); y.div(q); y = fPrime.mult(y); IntegerPolynomial x = fPrime.mult(i); x.div(q); x = f.mult(x); y.sub(x); s.add(y); s.modPositive(q); return s; } /** * Verifies a signature for any data previously added via {@link #update(byte[], int, int)}. * * @param sig a signature * @return whether the signature is valid * @throws IllegalStateException if initVerify was not called */ public boolean verifySignature(byte[] sig) { if (hashAlg == null || verificationKey == null) { throw new IllegalStateException("Call initVerify first!"); } byte[] msgHash = new byte[hashAlg.getDigestSize()]; hashAlg.doFinal(msgHash, 0); return verifyHash(msgHash, sig, verificationKey); } private boolean verifyHash(byte[] msgHash, byte[] sig, NTRUSigningPublicKeyParameters pub) { ByteBuffer sbuf = ByteBuffer.wrap(sig); byte[] rawSig = new byte[sig.length - 4]; sbuf.get(rawSig); IntegerPolynomial s = IntegerPolynomial.fromBinary(rawSig, params.N, params.q); int r = sbuf.getInt(); return verify(createMsgRep(msgHash, r), s, pub.h); } private boolean verify(IntegerPolynomial i, IntegerPolynomial s, IntegerPolynomial h) { int q = params.q; double normBoundSq = params.normBoundSq; double betaSq = params.betaSq; IntegerPolynomial t = h.mult(s, q); t.sub(i); long centeredNormSq = (long)(s.centeredNormSq(q) + betaSq * t.centeredNormSq(q)); return centeredNormSq <= normBoundSq; } protected IntegerPolynomial createMsgRep(byte[] msgHash, int r) { int N = params.N; int q = params.q; int c = 31 - Integer.numberOfLeadingZeros(q); int B = (c + 7) / 8; IntegerPolynomial i = new IntegerPolynomial(N); ByteBuffer cbuf = ByteBuffer.allocate(msgHash.length + 4); cbuf.put(msgHash); cbuf.putInt(r); NTRUSignerPrng prng = new NTRUSignerPrng(cbuf.array(), params.hashAlg); for (int t = 0; t < N; t++) { byte[] o = prng.nextBytes(B); int hi = o[o.length - 1]; hi >>= 8 * B - c; hi <<= 8 * B - c; o[o.length - 1] = (byte)hi; ByteBuffer obuf = ByteBuffer.allocate(4); obuf.put(o); obuf.rewind(); // reverse byte order so it matches the endianness of java ints i.coeffs[t] = Integer.reverseBytes(obuf.getInt()); } return i; } } bouncycastle-1.49.orig/src/org/bouncycastle/pqc/crypto/MessageEncryptor.java0000644000175000017500000000130512151251423026735 0ustar ebourgebourgpackage org.bouncycastle.pqc.crypto; import org.bouncycastle.crypto.CipherParameters; public interface MessageEncryptor { /** * * @param forEncrypting true if we are encrypting a signature, false * otherwise. * @param param key parameters for encryption or decryption. */ public void init(boolean forEncrypting, CipherParameters param); /** * * @param message the message to be signed. * @throws Exception */ public byte[] messageEncrypt(byte[] message) throws Exception; /** * * @param cipher the cipher text of the message * @throws Exception */ public byte[] messageDecrypt(byte[] cipher) throws Exception; } bouncycastle-1.49.orig/src/org/bouncycastle/pqc/asn1/0000755000175000017500000000000012152033551022124 5ustar ebourgebourgbouncycastle-1.49.orig/src/org/bouncycastle/pqc/asn1/GMSSPublicKey.java0000644000175000017500000000354412057030033025352 0ustar ebourgebourgpackage org.bouncycastle.pqc.asn1; import org.bouncycastle.asn1.ASN1EncodableVector; import org.bouncycastle.asn1.ASN1Integer; import org.bouncycastle.asn1.ASN1Object; import org.bouncycastle.asn1.ASN1OctetString; import org.bouncycastle.asn1.ASN1Primitive; import org.bouncycastle.asn1.ASN1Sequence; import org.bouncycastle.asn1.DEROctetString; import org.bouncycastle.asn1.DERSequence; import org.bouncycastle.util.Arrays; /** * This class implements an ASN.1 encoded GMSS public key. The ASN.1 definition * of this structure is: *

    *

     *  GMSSPublicKey        ::= SEQUENCE{
     *      version         INTEGER
     *      publicKey       OCTET STRING
     *  }
     * 
    */ public class GMSSPublicKey extends ASN1Object { private ASN1Integer version; private byte[] publicKey; private GMSSPublicKey(ASN1Sequence seq) { if (seq.size() != 2) { throw new IllegalArgumentException("size of seq = " + seq.size()); } this.version = ASN1Integer.getInstance(seq.getObjectAt(0)); this.publicKey = ASN1OctetString.getInstance(seq.getObjectAt(1)).getOctets(); } public GMSSPublicKey(byte[] publicKeyBytes) { this.version = new ASN1Integer(0); this.publicKey = publicKeyBytes; } public static GMSSPublicKey getInstance(Object o) { if (o instanceof GMSSPublicKey) { return (GMSSPublicKey)o; } else if (o != null) { return new GMSSPublicKey(ASN1Sequence.getInstance(o)); } return null; } public byte[] getPublicKey() { return Arrays.clone(publicKey); } public ASN1Primitive toASN1Primitive() { ASN1EncodableVector v = new ASN1EncodableVector(); v.add(version); v.add(new DEROctetString(publicKey)); return new DERSequence(v); } } bouncycastle-1.49.orig/src/org/bouncycastle/pqc/asn1/ParSet.java0000644000175000017500000000727212105025746024202 0ustar ebourgebourgpackage org.bouncycastle.pqc.asn1; import java.math.BigInteger; import org.bouncycastle.asn1.ASN1EncodableVector; import org.bouncycastle.asn1.ASN1Integer; import org.bouncycastle.asn1.ASN1Object; import org.bouncycastle.asn1.ASN1Primitive; import org.bouncycastle.asn1.ASN1Sequence; import org.bouncycastle.asn1.DERSequence; import org.bouncycastle.util.Arrays; /** *
     *  ParSet              ::= SEQUENCE {
     *      T               INTEGER
     *      h               SEQUENCE OF INTEGER
     *      w               SEQUENCE OF INTEGER
     *      K               SEQUENCE OF INTEGER
     *  }
     * 
    */ public class ParSet extends ASN1Object { private static final BigInteger ZERO = BigInteger.valueOf(0); private int t; private int[] h; private int[] w; private int[] k; private static int checkBigIntegerInIntRangeAndPositive(BigInteger b) { if ((b.compareTo(BigInteger.valueOf(Integer.MAX_VALUE)) > 0) || (b.compareTo(ZERO) <= 0)) { throw new IllegalArgumentException("BigInteger not in Range: " + b.toString()); } return b.intValue(); } private ParSet(ASN1Sequence seq) { if (seq.size() != 4) { throw new IllegalArgumentException("sie of seqOfParams = " + seq.size()); } BigInteger asn1int = ((ASN1Integer)seq.getObjectAt(0)).getValue(); t = checkBigIntegerInIntRangeAndPositive(asn1int); ASN1Sequence seqOfPSh = (ASN1Sequence)seq.getObjectAt(1); ASN1Sequence seqOfPSw = (ASN1Sequence)seq.getObjectAt(2); ASN1Sequence seqOfPSK = (ASN1Sequence)seq.getObjectAt(3); if ((seqOfPSh.size() != t) || (seqOfPSw.size() != t) || (seqOfPSK.size() != t)) { throw new IllegalArgumentException("invalid size of sequences"); } h = new int[seqOfPSh.size()]; w = new int[seqOfPSw.size()]; k = new int[seqOfPSK.size()]; for (int i = 0; i < t; i++) { h[i] = checkBigIntegerInIntRangeAndPositive((((ASN1Integer)seqOfPSh.getObjectAt(i))).getValue()); w[i] = checkBigIntegerInIntRangeAndPositive((((ASN1Integer)seqOfPSw.getObjectAt(i))).getValue()); k[i] = checkBigIntegerInIntRangeAndPositive((((ASN1Integer)seqOfPSK.getObjectAt(i))).getValue()); } } public ParSet(int t, int[] h, int[] w, int[] k) { this.t = t; this.h = h; this.w = w; this.k = k; } public static ParSet getInstance(Object o) { if (o instanceof ParSet) { return (ParSet)o; } else if (o != null) { return new ParSet(ASN1Sequence.getInstance(o)); } return null; } public int getT() { return t; } public int[] getH() { return Arrays.clone(h); } public int[] getW() { return Arrays.clone(w); } public int[] getK() { return Arrays.clone(k); } public ASN1Primitive toASN1Primitive() { ASN1EncodableVector seqOfPSh = new ASN1EncodableVector(); ASN1EncodableVector seqOfPSw = new ASN1EncodableVector(); ASN1EncodableVector seqOfPSK = new ASN1EncodableVector(); for (int i = 0; i < h.length; i++) { seqOfPSh.add(new ASN1Integer(h[i])); seqOfPSw.add(new ASN1Integer(w[i])); seqOfPSK.add(new ASN1Integer(k[i])); } ASN1EncodableVector v = new ASN1EncodableVector(); v.add(new ASN1Integer(t)); v.add(new DERSequence(seqOfPSh)); v.add(new DERSequence(seqOfPSw)); v.add(new DERSequence(seqOfPSK)); return new DERSequence(v); } } bouncycastle-1.49.orig/src/org/bouncycastle/pqc/asn1/McElieceCCA2PublicKey.java0000644000175000017500000000434512104635456026655 0ustar ebourgebourgpackage org.bouncycastle.pqc.asn1; import java.math.BigInteger; import org.bouncycastle.asn1.ASN1EncodableVector; import org.bouncycastle.asn1.ASN1Integer; import org.bouncycastle.asn1.ASN1Object; import org.bouncycastle.asn1.ASN1ObjectIdentifier; import org.bouncycastle.asn1.ASN1OctetString; import org.bouncycastle.asn1.ASN1Primitive; import org.bouncycastle.asn1.ASN1Sequence; import org.bouncycastle.asn1.DEROctetString; import org.bouncycastle.asn1.DERSequence; import org.bouncycastle.pqc.math.linearalgebra.GF2Matrix; public class McElieceCCA2PublicKey extends ASN1Object { private ASN1ObjectIdentifier oid; private int n; private int t; private byte[] matrixG; public McElieceCCA2PublicKey(ASN1ObjectIdentifier oid, int n, int t, GF2Matrix g) { this.oid = oid; this.n = n; this.t = t; this.matrixG = g.getEncoded(); } private McElieceCCA2PublicKey(ASN1Sequence seq) { oid = ((ASN1ObjectIdentifier)seq.getObjectAt(0)); BigInteger bigN = ((ASN1Integer)seq.getObjectAt(1)).getValue(); n = bigN.intValue(); BigInteger bigT = ((ASN1Integer)seq.getObjectAt(2)).getValue(); t = bigT.intValue(); matrixG = ((ASN1OctetString)seq.getObjectAt(3)).getOctets(); } public ASN1ObjectIdentifier getOID() { return oid; } public int getN() { return n; } public int getT() { return t; } public GF2Matrix getG() { return new GF2Matrix(matrixG); } public ASN1Primitive toASN1Primitive() { ASN1EncodableVector v = new ASN1EncodableVector(); // encode v.add(oid); // encode v.add(new ASN1Integer(n)); // encode v.add(new ASN1Integer(t)); // encode v.add(new DEROctetString(matrixG)); return new DERSequence(v); } public static McElieceCCA2PublicKey getInstance(Object o) { if (o instanceof McElieceCCA2PublicKey) { return (McElieceCCA2PublicKey)o; } else if (o != null) { return new McElieceCCA2PublicKey(ASN1Sequence.getInstance(o)); } return null; } } bouncycastle-1.49.orig/src/org/bouncycastle/pqc/asn1/McElieceCCA2PrivateKey.java0000644000175000017500000001062212104635456027044 0ustar ebourgebourgpackage org.bouncycastle.pqc.asn1; import java.math.BigInteger; import org.bouncycastle.asn1.ASN1EncodableVector; import org.bouncycastle.asn1.ASN1Integer; import org.bouncycastle.asn1.ASN1Object; import org.bouncycastle.asn1.ASN1ObjectIdentifier; import org.bouncycastle.asn1.ASN1OctetString; import org.bouncycastle.asn1.ASN1Primitive; import org.bouncycastle.asn1.ASN1Sequence; import org.bouncycastle.asn1.DEROctetString; import org.bouncycastle.asn1.DERSequence; import org.bouncycastle.pqc.math.linearalgebra.GF2Matrix; import org.bouncycastle.pqc.math.linearalgebra.GF2mField; import org.bouncycastle.pqc.math.linearalgebra.Permutation; import org.bouncycastle.pqc.math.linearalgebra.PolynomialGF2mSmallM; public class McElieceCCA2PrivateKey extends ASN1Object { private ASN1ObjectIdentifier oid; private int n; private int k; private byte[] encField; private byte[] encGp; private byte[] encP; private byte[] encH; private byte[][] encqInv; public McElieceCCA2PrivateKey(ASN1ObjectIdentifier oid, int n, int k, GF2mField field, PolynomialGF2mSmallM goppaPoly, Permutation p, GF2Matrix h, PolynomialGF2mSmallM[] qInv) { this.oid = oid; this.n = n; this.k = k; this.encField = field.getEncoded(); this.encGp = goppaPoly.getEncoded(); this.encP = p.getEncoded(); this.encH = h.getEncoded(); this.encqInv = new byte[qInv.length][]; for (int i = 0; i != qInv.length; i++) { encqInv[i] = qInv[i].getEncoded(); } } private McElieceCCA2PrivateKey(ASN1Sequence seq) { oid = ((ASN1ObjectIdentifier)seq.getObjectAt(0)); BigInteger bigN = ((ASN1Integer)seq.getObjectAt(1)).getValue(); n = bigN.intValue(); BigInteger bigK = ((ASN1Integer)seq.getObjectAt(2)).getValue(); k = bigK.intValue(); encField = ((ASN1OctetString)seq.getObjectAt(3)).getOctets(); encGp = ((ASN1OctetString)seq.getObjectAt(4)).getOctets(); encP = ((ASN1OctetString)seq.getObjectAt(5)).getOctets(); encH = ((ASN1OctetString)seq.getObjectAt(6)).getOctets(); ASN1Sequence asnQInv = (ASN1Sequence)seq.getObjectAt(7); encqInv = new byte[asnQInv.size()][]; for (int i = 0; i < asnQInv.size(); i++) { encqInv[i] = ((ASN1OctetString)asnQInv.getObjectAt(i)).getOctets(); } } public ASN1ObjectIdentifier getOID() { return oid; } public int getN() { return n; } public int getK() { return k; } public GF2mField getField() { return new GF2mField(encField); } public PolynomialGF2mSmallM getGoppaPoly() { return new PolynomialGF2mSmallM(this.getField(), encGp); } public Permutation getP() { return new Permutation(encP); } public GF2Matrix getH() { return new GF2Matrix(encH); } public PolynomialGF2mSmallM[] getQInv() { PolynomialGF2mSmallM[] qInv = new PolynomialGF2mSmallM[encqInv.length]; GF2mField field = this.getField(); for (int i = 0; i < encqInv.length; i++) { qInv[i] = new PolynomialGF2mSmallM(field, encqInv[i]); } return qInv; } public ASN1Primitive toASN1Primitive() { ASN1EncodableVector v = new ASN1EncodableVector(); // encode v.add(oid); // encode v.add(new ASN1Integer(n)); // encode v.add(new ASN1Integer(k)); // encode v.add(new DEROctetString(encField)); // encode v.add(new DEROctetString(encGp)); // encode

    v.add(new DEROctetString(encP)); // encode v.add(new DEROctetString(encH)); // encode ASN1EncodableVector asnQInv = new ASN1EncodableVector(); for (int i = 0; i < encqInv.length; i++) { asnQInv.add(new DEROctetString(encqInv[i])); } v.add(new DERSequence(asnQInv)); return new DERSequence(v); } public static McElieceCCA2PrivateKey getInstance(Object o) { if (o instanceof McElieceCCA2PrivateKey) { return (McElieceCCA2PrivateKey)o; } else if (o != null) { return new McElieceCCA2PrivateKey(ASN1Sequence.getInstance(o)); } return null; } } bouncycastle-1.49.orig/src/org/bouncycastle/pqc/asn1/RainbowPrivateKey.java0000644000175000017500000002561712057030070026404 0ustar ebourgebourgpackage org.bouncycastle.pqc.asn1; import org.bouncycastle.asn1.ASN1EncodableVector; import org.bouncycastle.asn1.ASN1Integer; import org.bouncycastle.asn1.ASN1Object; import org.bouncycastle.asn1.ASN1ObjectIdentifier; import org.bouncycastle.asn1.ASN1OctetString; import org.bouncycastle.asn1.ASN1Primitive; import org.bouncycastle.asn1.ASN1Sequence; import org.bouncycastle.asn1.DEROctetString; import org.bouncycastle.asn1.DERSequence; import org.bouncycastle.pqc.crypto.rainbow.Layer; import org.bouncycastle.pqc.crypto.rainbow.util.RainbowUtil; /** * Return the key data to encode in the PrivateKeyInfo structure. *

    * The ASN.1 definition of the key structure is *

    *

     *   RainbowPrivateKey ::= SEQUENCE {
     *         CHOICE
     *         {
     *         oid        OBJECT IDENTIFIER         -- OID identifying the algorithm
     *         version    INTEGER                    -- 0
     *         }
     *     A1inv      SEQUENCE OF OCTET STRING  -- inversed matrix of L1
     *     b1         OCTET STRING              -- translation vector of L1
     *     A2inv      SEQUENCE OF OCTET STRING  -- inversed matrix of L2
     *     b2         OCTET STRING              -- translation vector of L2
     *     vi         OCTET STRING              -- num of elmts in each Set S
     *     layers     SEQUENCE OF Layer         -- layers of F
     *   }
     *
     *   Layer             ::= SEQUENCE OF Poly
     *
     *   Poly              ::= SEQUENCE {
     *     alpha      SEQUENCE OF OCTET STRING
     *     beta       SEQUENCE OF OCTET STRING
     *     gamma      OCTET STRING
     *     eta        INTEGER
     *   }
     * 
    */ public class RainbowPrivateKey extends ASN1Object { private ASN1Integer version; private ASN1ObjectIdentifier oid; private byte[][] invA1; private byte[] b1; private byte[][] invA2; private byte[] b2; private byte[] vi; private Layer[] layers; private RainbowPrivateKey(ASN1Sequence seq) { // or version if (seq.getObjectAt(0) instanceof ASN1Integer) { version = ASN1Integer.getInstance(seq.getObjectAt(0)); } else { oid = ASN1ObjectIdentifier.getInstance(seq.getObjectAt(0)); } // ASN1Sequence asnA1 = (ASN1Sequence)seq.getObjectAt(1); invA1 = new byte[asnA1.size()][]; for (int i = 0; i < asnA1.size(); i++) { invA1[i] = ((ASN1OctetString)asnA1.getObjectAt(i)).getOctets(); } // ASN1Sequence asnb1 = (ASN1Sequence)seq.getObjectAt(2); b1 = ((ASN1OctetString)asnb1.getObjectAt(0)).getOctets(); // ASN1Sequence asnA2 = (ASN1Sequence)seq.getObjectAt(3); invA2 = new byte[asnA2.size()][]; for (int j = 0; j < asnA2.size(); j++) { invA2[j] = ((ASN1OctetString)asnA2.getObjectAt(j)).getOctets(); } // ASN1Sequence asnb2 = (ASN1Sequence)seq.getObjectAt(4); b2 = ((ASN1OctetString)asnb2.getObjectAt(0)).getOctets(); // ASN1Sequence asnvi = (ASN1Sequence)seq.getObjectAt(5); vi = ((ASN1OctetString)asnvi.getObjectAt(0)).getOctets(); // ASN1Sequence asnLayers = (ASN1Sequence)seq.getObjectAt(6); byte[][][][] alphas = new byte[asnLayers.size()][][][]; byte[][][][] betas = new byte[asnLayers.size()][][][]; byte[][][] gammas = new byte[asnLayers.size()][][]; byte[][] etas = new byte[asnLayers.size()][]; // a layer: for (int l = 0; l < asnLayers.size(); l++) { ASN1Sequence asnLayer = (ASN1Sequence)asnLayers.getObjectAt(l); // alphas (num of alpha-2d-array = oi) ASN1Sequence alphas3d = (ASN1Sequence)asnLayer.getObjectAt(0); alphas[l] = new byte[alphas3d.size()][][]; for (int m = 0; m < alphas3d.size(); m++) { ASN1Sequence alphas2d = (ASN1Sequence)alphas3d.getObjectAt(m); alphas[l][m] = new byte[alphas2d.size()][]; for (int n = 0; n < alphas2d.size(); n++) { alphas[l][m][n] = ((ASN1OctetString)alphas2d.getObjectAt(n)).getOctets(); } } // betas .... ASN1Sequence betas3d = (ASN1Sequence)asnLayer.getObjectAt(1); betas[l] = new byte[betas3d.size()][][]; for (int mb = 0; mb < betas3d.size(); mb++) { ASN1Sequence betas2d = (ASN1Sequence)betas3d.getObjectAt(mb); betas[l][mb] = new byte[betas2d.size()][]; for (int nb = 0; nb < betas2d.size(); nb++) { betas[l][mb][nb] = ((ASN1OctetString)betas2d.getObjectAt(nb)).getOctets(); } } // gammas ... ASN1Sequence gammas2d = (ASN1Sequence)asnLayer.getObjectAt(2); gammas[l] = new byte[gammas2d.size()][]; for (int mg = 0; mg < gammas2d.size(); mg++) { gammas[l][mg] = ((ASN1OctetString)gammas2d.getObjectAt(mg)).getOctets(); } // eta ... etas[l] = ((ASN1OctetString)asnLayer.getObjectAt(3)).getOctets(); } int numOfLayers = vi.length - 1; this.layers = new Layer[numOfLayers]; for (int i = 0; i < numOfLayers; i++) { Layer l = new Layer(vi[i], vi[i + 1], RainbowUtil.convertArray(alphas[i]), RainbowUtil.convertArray(betas[i]), RainbowUtil.convertArray(gammas[i]), RainbowUtil.convertArray(etas[i])); this.layers[i] = l; } } public RainbowPrivateKey(short[][] invA1, short[] b1, short[][] invA2, short[] b2, int[] vi, Layer[] layers) { this.version = new ASN1Integer(1); this.invA1 = RainbowUtil.convertArray(invA1); this.b1 = RainbowUtil.convertArray(b1); this.invA2 = RainbowUtil.convertArray(invA2); this.b2 = RainbowUtil.convertArray(b2); this.vi = RainbowUtil.convertIntArray(vi); this.layers = layers; } public static RainbowPrivateKey getInstance(Object o) { if (o instanceof RainbowPrivateKey) { return (RainbowPrivateKey)o; } else if (o != null) { return new RainbowPrivateKey(ASN1Sequence.getInstance(o)); } return null; } public ASN1Integer getVersion() { return version; } /** * Getter for the inverse matrix of A1. * * @return the A1inv inverse */ public short[][] getInvA1() { return RainbowUtil.convertArray(invA1); } /** * Getter for the translation part of the private quadratic map L1. * * @return b1 the translation part of L1 */ public short[] getB1() { return RainbowUtil.convertArray(b1); } /** * Getter for the translation part of the private quadratic map L2. * * @return b2 the translation part of L2 */ public short[] getB2() { return RainbowUtil.convertArray(b2); } /** * Getter for the inverse matrix of A2 * * @return the A2inv */ public short[][] getInvA2() { return RainbowUtil.convertArray(invA2); } /** * Returns the layers contained in the private key * * @return layers */ public Layer[] getLayers() { return this.layers; } /** * Returns the array of vi-s * * @return the vi */ public int[] getVi() { return RainbowUtil.convertArraytoInt(vi); } public ASN1Primitive toASN1Primitive() { ASN1EncodableVector v = new ASN1EncodableVector(); // encode or version if (version != null) { v.add(version); } else { v.add(oid); } // encode ASN1EncodableVector asnA1 = new ASN1EncodableVector(); for (int i = 0; i < invA1.length; i++) { asnA1.add(new DEROctetString(invA1[i])); } v.add(new DERSequence(asnA1)); // encode ASN1EncodableVector asnb1 = new ASN1EncodableVector(); asnb1.add(new DEROctetString(b1)); v.add(new DERSequence(asnb1)); // encode ASN1EncodableVector asnA2 = new ASN1EncodableVector(); for (int i = 0; i < invA2.length; i++) { asnA2.add(new DEROctetString(invA2[i])); } v.add(new DERSequence(asnA2)); // encode ASN1EncodableVector asnb2 = new ASN1EncodableVector(); asnb2.add(new DEROctetString(b2)); v.add(new DERSequence(asnb2)); // encode ASN1EncodableVector asnvi = new ASN1EncodableVector(); asnvi.add(new DEROctetString(vi)); v.add(new DERSequence(asnvi)); // encode ASN1EncodableVector asnLayers = new ASN1EncodableVector(); // a layer: for (int l = 0; l < layers.length; l++) { ASN1EncodableVector aLayer = new ASN1EncodableVector(); // alphas (num of alpha-2d-array = oi) byte[][][] alphas = RainbowUtil.convertArray(layers[l].getCoeffAlpha()); ASN1EncodableVector alphas3d = new ASN1EncodableVector(); for (int i = 0; i < alphas.length; i++) { ASN1EncodableVector alphas2d = new ASN1EncodableVector(); for (int j = 0; j < alphas[i].length; j++) { alphas2d.add(new DEROctetString(alphas[i][j])); } alphas3d.add(new DERSequence(alphas2d)); } aLayer.add(new DERSequence(alphas3d)); // betas .... byte[][][] betas = RainbowUtil.convertArray(layers[l].getCoeffBeta()); ASN1EncodableVector betas3d = new ASN1EncodableVector(); for (int i = 0; i < betas.length; i++) { ASN1EncodableVector betas2d = new ASN1EncodableVector(); for (int j = 0; j < betas[i].length; j++) { betas2d.add(new DEROctetString(betas[i][j])); } betas3d.add(new DERSequence(betas2d)); } aLayer.add(new DERSequence(betas3d)); // gammas ... byte[][] gammas = RainbowUtil.convertArray(layers[l].getCoeffGamma()); ASN1EncodableVector asnG = new ASN1EncodableVector(); for (int i = 0; i < gammas.length; i++) { asnG.add(new DEROctetString(gammas[i])); } aLayer.add(new DERSequence(asnG)); // eta aLayer.add(new DEROctetString(RainbowUtil.convertArray(layers[l].getCoeffEta()))); // now, layer built up. add it! asnLayers.add(new DERSequence(aLayer)); } v.add(new DERSequence(asnLayers)); return new DERSequence(v); } } bouncycastle-1.49.orig/src/org/bouncycastle/pqc/asn1/McEliecePrivateKey.java0000644000175000017500000001177612104637137026464 0ustar ebourgebourgpackage org.bouncycastle.pqc.asn1; import java.math.BigInteger; import org.bouncycastle.asn1.ASN1EncodableVector; import org.bouncycastle.asn1.ASN1Integer; import org.bouncycastle.asn1.ASN1Object; import org.bouncycastle.asn1.ASN1ObjectIdentifier; import org.bouncycastle.asn1.ASN1OctetString; import org.bouncycastle.asn1.ASN1Primitive; import org.bouncycastle.asn1.ASN1Sequence; import org.bouncycastle.asn1.DEROctetString; import org.bouncycastle.asn1.DERSequence; import org.bouncycastle.pqc.math.linearalgebra.GF2Matrix; import org.bouncycastle.pqc.math.linearalgebra.GF2mField; import org.bouncycastle.pqc.math.linearalgebra.Permutation; import org.bouncycastle.pqc.math.linearalgebra.PolynomialGF2mSmallM; public class McEliecePrivateKey extends ASN1Object { private ASN1ObjectIdentifier oid; private int n; private int k; private byte[] encField; private byte[] encGp; private byte[] encSInv; private byte[] encP1; private byte[] encP2; private byte[] encH; private byte[][] encqInv; public McEliecePrivateKey(ASN1ObjectIdentifier oid, int n, int k, GF2mField field, PolynomialGF2mSmallM goppaPoly, GF2Matrix sInv, Permutation p1, Permutation p2, GF2Matrix h, PolynomialGF2mSmallM[] qInv) { this.oid = oid; this.n = n; this.k = k; this.encField = field.getEncoded(); this.encGp = goppaPoly.getEncoded(); this.encSInv = sInv.getEncoded(); this.encP1 = p1.getEncoded(); this.encP2 = p2.getEncoded(); this.encH = h.getEncoded(); this.encqInv = new byte[qInv.length][]; for (int i = 0; i != qInv.length; i++) { encqInv[i] = qInv[i].getEncoded(); } } public static McEliecePrivateKey getInstance(Object o) { if (o instanceof McEliecePrivateKey) { return (McEliecePrivateKey)o; } else if (o != null) { return new McEliecePrivateKey(ASN1Sequence.getInstance(o)); } return null; } private McEliecePrivateKey(ASN1Sequence seq) { // oid = ((ASN1ObjectIdentifier)seq.getObjectAt(0)); BigInteger bigN = ((ASN1Integer)seq.getObjectAt(1)).getValue(); n = bigN.intValue(); BigInteger bigK = ((ASN1Integer)seq.getObjectAt(2)).getValue(); k = bigK.intValue(); encField = ((ASN1OctetString)seq.getObjectAt(3)).getOctets(); encGp = ((ASN1OctetString)seq.getObjectAt(4)).getOctets(); encSInv = ((ASN1OctetString)seq.getObjectAt(5)).getOctets(); encP1 = ((ASN1OctetString)seq.getObjectAt(6)).getOctets(); encP2 = ((ASN1OctetString)seq.getObjectAt(7)).getOctets(); encH = ((ASN1OctetString)seq.getObjectAt(8)).getOctets(); ASN1Sequence asnQInv = (ASN1Sequence)seq.getObjectAt(9); encqInv = new byte[asnQInv.size()][]; for (int i = 0; i < asnQInv.size(); i++) { encqInv[i] = ((ASN1OctetString)asnQInv.getObjectAt(i)).getOctets(); } } public ASN1ObjectIdentifier getOID() { return oid; } public int getN() { return n; } public int getK() { return k; } public GF2mField getField() { return new GF2mField(encField); } public PolynomialGF2mSmallM getGoppaPoly() { return new PolynomialGF2mSmallM(this.getField(), encGp); } public GF2Matrix getSInv() { return new GF2Matrix(encSInv); } public Permutation getP1() { return new Permutation(encP1); } public Permutation getP2() { return new Permutation(encP2); } public GF2Matrix getH() { return new GF2Matrix(encH); } public PolynomialGF2mSmallM[] getQInv() { PolynomialGF2mSmallM[] qInv = new PolynomialGF2mSmallM[encqInv.length]; GF2mField field = this.getField(); for (int i = 0; i < encqInv.length; i++) { qInv[i] = new PolynomialGF2mSmallM(field, encqInv[i]); } return qInv; } public ASN1Primitive toASN1Primitive() { ASN1EncodableVector v = new ASN1EncodableVector(); // encode v.add(oid); // encode v.add(new ASN1Integer(n)); // encode v.add(new ASN1Integer(k)); // encode v.add(new DEROctetString(encField)); // encode v.add(new DEROctetString(encGp)); // encode v.add(new DEROctetString(encSInv)); // encode v.add(new DEROctetString(encP1)); // encode v.add(new DEROctetString(encP2)); // encode v.add(new DEROctetString(encH)); // encode ASN1EncodableVector asnQInv = new ASN1EncodableVector(); for (int i = 0; i < encqInv.length; i++) { asnQInv.add(new DEROctetString(encqInv[i])); } v.add(new DERSequence(asnQInv)); return new DERSequence(v); } } bouncycastle-1.49.orig/src/org/bouncycastle/pqc/asn1/PQCObjectIdentifiers.java0000644000175000017500000000260112045616254026736 0ustar ebourgebourgpackage org.bouncycastle.pqc.asn1; import org.bouncycastle.asn1.ASN1ObjectIdentifier; public interface PQCObjectIdentifiers { public static final ASN1ObjectIdentifier rainbow = new ASN1ObjectIdentifier("1.3.6.1.4.1.8301.3.1.3.5.3.2"); public static final ASN1ObjectIdentifier rainbowWithSha1 = rainbow.branch("1"); public static final ASN1ObjectIdentifier rainbowWithSha224 = rainbow.branch("2"); public static final ASN1ObjectIdentifier rainbowWithSha256 = rainbow.branch("3"); public static final ASN1ObjectIdentifier rainbowWithSha384 = rainbow.branch("4"); public static final ASN1ObjectIdentifier rainbowWithSha512 = rainbow.branch("5"); public static final ASN1ObjectIdentifier gmss = new ASN1ObjectIdentifier("1.3.6.1.4.1.8301.3.1.3.3"); public static final ASN1ObjectIdentifier gmssWithSha1 = gmss.branch("1"); public static final ASN1ObjectIdentifier gmssWithSha224 = gmss.branch("2"); public static final ASN1ObjectIdentifier gmssWithSha256 = gmss.branch("3"); public static final ASN1ObjectIdentifier gmssWithSha384 = gmss.branch("4"); public static final ASN1ObjectIdentifier gmssWithSha512 = gmss.branch("5"); public static final ASN1ObjectIdentifier mcEliece = new ASN1ObjectIdentifier("1.3.6.1.4.1.8301.3.1.3.4.1"); public static final ASN1ObjectIdentifier mcElieceCca2 = new ASN1ObjectIdentifier("1.3.6.1.4.1.8301.3.1.3.4.2"); } bouncycastle-1.49.orig/src/org/bouncycastle/pqc/asn1/GMSSPrivateKey.java0000644000175000017500000016720112151274312025554 0ustar ebourgebourgpackage org.bouncycastle.pqc.asn1; import java.math.BigInteger; import java.util.Vector; import org.bouncycastle.asn1.ASN1Encodable; import org.bouncycastle.asn1.ASN1EncodableVector; import org.bouncycastle.asn1.ASN1Integer; import org.bouncycastle.asn1.ASN1Object; import org.bouncycastle.asn1.ASN1Primitive; import org.bouncycastle.asn1.ASN1Sequence; import org.bouncycastle.asn1.DEROctetString; import org.bouncycastle.asn1.DERSequence; import org.bouncycastle.asn1.x509.AlgorithmIdentifier; import org.bouncycastle.pqc.crypto.gmss.GMSSLeaf; import org.bouncycastle.pqc.crypto.gmss.GMSSParameters; import org.bouncycastle.pqc.crypto.gmss.GMSSRootCalc; import org.bouncycastle.pqc.crypto.gmss.GMSSRootSig; import org.bouncycastle.pqc.crypto.gmss.Treehash; public class GMSSPrivateKey extends ASN1Object { private ASN1Primitive primitive; private GMSSPrivateKey(ASN1Sequence mtsPrivateKey) { // --- Decode . ASN1Sequence indexPart = (ASN1Sequence)mtsPrivateKey.getObjectAt(0); int[] index = new int[indexPart.size()]; for (int i = 0; i < indexPart.size(); i++) { index[i] = checkBigIntegerInIntRange(indexPart.getObjectAt(i)); } // --- Decode . ASN1Sequence curSeedsPart = (ASN1Sequence)mtsPrivateKey.getObjectAt(1); byte[][] curSeeds = new byte[curSeedsPart.size()][]; for (int i = 0; i < curSeeds.length; i++) { curSeeds[i] = ((DEROctetString)curSeedsPart.getObjectAt(i)).getOctets(); } // --- Decode . ASN1Sequence nextNextSeedsPart = (ASN1Sequence)mtsPrivateKey.getObjectAt(2); byte[][] nextNextSeeds = new byte[nextNextSeedsPart.size()][]; for (int i = 0; i < nextNextSeeds.length; i++) { nextNextSeeds[i] = ((DEROctetString)nextNextSeedsPart.getObjectAt(i)).getOctets(); } // --- Decode . ASN1Sequence curAuthPart0 = (ASN1Sequence)mtsPrivateKey.getObjectAt(3); ASN1Sequence curAuthPart1; byte[][][] curAuth = new byte[curAuthPart0.size()][][]; for (int i = 0; i < curAuth.length; i++) { curAuthPart1 = (ASN1Sequence)curAuthPart0.getObjectAt(i); curAuth[i] = new byte[curAuthPart1.size()][]; for (int j = 0; j < curAuth[i].length; j++) { curAuth[i][j] = ((DEROctetString)curAuthPart1.getObjectAt(j)).getOctets(); } } // --- Decode . ASN1Sequence nextAuthPart0 = (ASN1Sequence)mtsPrivateKey.getObjectAt(4); ASN1Sequence nextAuthPart1; byte[][][] nextAuth = new byte[nextAuthPart0.size()][][]; for (int i = 0; i < nextAuth.length; i++) { nextAuthPart1 = (ASN1Sequence)nextAuthPart0.getObjectAt(i); nextAuth[i] = new byte[nextAuthPart1.size()][]; for (int j = 0; j < nextAuth[i].length; j++) { nextAuth[i][j] = ((DEROctetString)nextAuthPart1.getObjectAt(j)).getOctets(); } } // --- Decode . ASN1Sequence seqOfcurTreehash0 = (ASN1Sequence)mtsPrivateKey.getObjectAt(5); ASN1Sequence seqOfcurTreehash1; ASN1Sequence seqOfcurTreehashStat; ASN1Sequence seqOfcurTreehashBytes; ASN1Sequence seqOfcurTreehashInts; ASN1Sequence seqOfcurTreehashString; Treehash[][] curTreehash = new Treehash[seqOfcurTreehash0.size()][]; /* for (int i = 0; i < curTreehash.length; i++) { seqOfcurTreehash1 = (ASN1Sequence)seqOfcurTreehash0.getObjectAt(i); curTreehash[i] = new Treehash[seqOfcurTreehash1.size()]; for (int j = 0; j < curTreehash[i].length; j++) { seqOfcurTreehashStat = (ASN1Sequence)seqOfcurTreehash1.getObjectAt(j); seqOfcurTreehashString = (ASN1Sequence)seqOfcurTreehashStat .getObjectAt(0); seqOfcurTreehashBytes = (ASN1Sequence)seqOfcurTreehashStat .getObjectAt(1); seqOfcurTreehashInts = (ASN1Sequence)seqOfcurTreehashStat .getObjectAt(2); String[] name = new String[2]; name[0] = ((DERIA5String)seqOfcurTreehashString.getObjectAt(0)).getString(); name[1] = ((DERIA5String)seqOfcurTreehashString.getObjectAt(1)).getString(); int tailLength = checkBigIntegerInIntRange(seqOfcurTreehashInts.getObjectAt(1)); byte[][] statByte = new byte[3 + tailLength][]; statByte[0] = ((DEROctetString)seqOfcurTreehashBytes.getObjectAt(0)).getOctets(); if (statByte[0].length == 0) { // if null was encoded statByte[0] = null; } statByte[1] = ((DEROctetString)seqOfcurTreehashBytes.getObjectAt(1)).getOctets(); statByte[2] = ((DEROctetString)seqOfcurTreehashBytes.getObjectAt(2)).getOctets(); for (int k = 0; k < tailLength; k++) { statByte[3 + k] = ((DEROctetString)seqOfcurTreehashBytes .getObjectAt(3 + k)).getOctets(); } int[] statInt = new int[6 + tailLength]; statInt[0] = checkBigIntegerInIntRange(seqOfcurTreehashInts.getObjectAt(0)); statInt[1] = tailLength; statInt[2] = checkBigIntegerInIntRange(seqOfcurTreehashInts.getObjectAt(2)); statInt[3] = checkBigIntegerInIntRange(seqOfcurTreehashInts.getObjectAt(3)); statInt[4] = checkBigIntegerInIntRange(seqOfcurTreehashInts.getObjectAt(4)); statInt[5] = checkBigIntegerInIntRange(seqOfcurTreehashInts.getObjectAt(5)); for (int k = 0; k < tailLength; k++) { statInt[6 + k] = checkBigIntegerInIntRange(seqOfcurTreehashInts.getObjectAt(6 + k)); } // TODO: Check if we can do better than throwing away name[1] !!! curTreehash[i][j] = new Treehash(DigestFactory.getDigest(name[0]).getClass(), statByte, statInt); } } // --- Decode . ASN1Sequence seqOfNextTreehash0 = (ASN1Sequence)mtsPrivateKey.getObjectAt(6); ASN1Sequence seqOfNextTreehash1; ASN1Sequence seqOfNextTreehashStat; ASN1Sequence seqOfNextTreehashBytes; ASN1Sequence seqOfNextTreehashInts; ASN1Sequence seqOfNextTreehashString; Treehash[][] nextTreehash = new Treehash[seqOfNextTreehash0.size()][]; for (int i = 0; i < nextTreehash.length; i++) { seqOfNextTreehash1 = (ASN1Sequence)seqOfNextTreehash0.getObjectAt(i); nextTreehash[i] = new Treehash[seqOfNextTreehash1.size()]; for (int j = 0; j < nextTreehash[i].length; j++) { seqOfNextTreehashStat = (ASN1Sequence)seqOfNextTreehash1 .getObjectAt(j); seqOfNextTreehashString = (ASN1Sequence)seqOfNextTreehashStat .getObjectAt(0); seqOfNextTreehashBytes = (ASN1Sequence)seqOfNextTreehashStat .getObjectAt(1); seqOfNextTreehashInts = (ASN1Sequence)seqOfNextTreehashStat .getObjectAt(2); String[] name = new String[2]; name[0] = ((DERIA5String)seqOfNextTreehashString.getObjectAt(0)) .getString(); name[1] = ((DERIA5String)seqOfNextTreehashString.getObjectAt(1)) .getString(); int tailLength = checkBigIntegerInIntRange(seqOfNextTreehashInts.getObjectAt(1)); byte[][] statByte = new byte[3 + tailLength][]; statByte[0] = ((DEROctetString)seqOfNextTreehashBytes.getObjectAt(0)).getOctets(); if (statByte[0].length == 0) { // if null was encoded statByte[0] = null; } statByte[1] = ((DEROctetString)seqOfNextTreehashBytes.getObjectAt(1)).getOctets(); statByte[2] = ((DEROctetString)seqOfNextTreehashBytes.getObjectAt(2)).getOctets(); for (int k = 0; k < tailLength; k++) { statByte[3 + k] = ((DEROctetString)seqOfNextTreehashBytes .getObjectAt(3 + k)).getOctets(); } int[] statInt = new int[6 + tailLength]; statInt[0] = checkBigIntegerInIntRange(seqOfNextTreehashInts.getObjectAt(0)); statInt[1] = tailLength; statInt[2] = checkBigIntegerInIntRange(seqOfNextTreehashInts.getObjectAt(2)); statInt[3] = checkBigIntegerInIntRange(seqOfNextTreehashInts.getObjectAt(3)); statInt[4] = checkBigIntegerInIntRange(seqOfNextTreehashInts.getObjectAt(4)); statInt[5] = checkBigIntegerInIntRange(seqOfNextTreehashInts.getObjectAt(5)); for (int k = 0; k < tailLength; k++) { statInt[6 + k] = checkBigIntegerInIntRange(seqOfNextTreehashInts.getObjectAt(6 + k)); } nextTreehash[i][j] = new Treehash(DigestFactory.getDigest(name[0]).getClass(), statByte, statInt); } } // --- Decode . ASN1Sequence keepPart0 = (ASN1Sequence)mtsPrivateKey.getObjectAt(7); ASN1Sequence keepPart1; byte[][][] keep = new byte[keepPart0.size()][][]; for (int i = 0; i < keep.length; i++) { keepPart1 = (ASN1Sequence)keepPart0.getObjectAt(i); keep[i] = new byte[keepPart1.size()][]; for (int j = 0; j < keep[i].length; j++) { keep[i][j] = ((DEROctetString)keepPart1.getObjectAt(j)).getOctets(); } } // --- Decode . ASN1Sequence curStackPart0 = (ASN1Sequence)mtsPrivateKey.getObjectAt(8); ASN1Sequence curStackPart1; Vector[] curStack = new Vector[curStackPart0.size()]; for (int i = 0; i < curStack.length; i++) { curStackPart1 = (ASN1Sequence)curStackPart0.getObjectAt(i); curStack[i] = new Vector(); for (int j = 0; j < curStackPart1.size(); j++) { curStack[i].addElement(((DEROctetString)curStackPart1.getObjectAt(j)).getOctets()); } } // --- Decode . ASN1Sequence nextStackPart0 = (ASN1Sequence)mtsPrivateKey.getObjectAt(9); ASN1Sequence nextStackPart1; Vector[] nextStack = new Vector[nextStackPart0.size()]; for (int i = 0; i < nextStack.length; i++) { nextStackPart1 = (ASN1Sequence)nextStackPart0.getObjectAt(i); nextStack[i] = new Vector(); for (int j = 0; j < nextStackPart1.size(); j++) { nextStack[i].addElement(((DEROctetString)nextStackPart1 .getObjectAt(j)).getOctets()); } } // --- Decode . ASN1Sequence curRetainPart0 = (ASN1Sequence)mtsPrivateKey.getObjectAt(10); ASN1Sequence curRetainPart1; ASN1Sequence curRetainPart2; Vector[][] curRetain = new Vector[curRetainPart0.size()][]; for (int i = 0; i < curRetain.length; i++) { curRetainPart1 = (ASN1Sequence)curRetainPart0.getObjectAt(i); curRetain[i] = new Vector[curRetainPart1.size()]; for (int j = 0; j < curRetain[i].length; j++) { curRetainPart2 = (ASN1Sequence)curRetainPart1.getObjectAt(j); curRetain[i][j] = new Vector(); for (int k = 0; k < curRetainPart2.size(); k++) { curRetain[i][j] .addElement(((DEROctetString)curRetainPart2 .getObjectAt(k)).getOctets()); } } } // --- Decode . ASN1Sequence nextRetainPart0 = (ASN1Sequence)mtsPrivateKey.getObjectAt(11); ASN1Sequence nextRetainPart1; ASN1Sequence nextRetainPart2; Vector[][] nextRetain = new Vector[nextRetainPart0.size()][]; for (int i = 0; i < nextRetain.length; i++) { nextRetainPart1 = (ASN1Sequence)nextRetainPart0.getObjectAt(i); nextRetain[i] = new Vector[nextRetainPart1.size()]; for (int j = 0; j < nextRetain[i].length; j++) { nextRetainPart2 = (ASN1Sequence)nextRetainPart1.getObjectAt(j); nextRetain[i][j] = new Vector(); for (int k = 0; k < nextRetainPart2.size(); k++) { nextRetain[i][j] .addElement(((DEROctetString)nextRetainPart2 .getObjectAt(k)).getOctets()); } } } // --- Decode . ASN1Sequence seqOfLeafs = (ASN1Sequence)mtsPrivateKey.getObjectAt(12); ASN1Sequence seqOfLeafStat; ASN1Sequence seqOfLeafBytes; ASN1Sequence seqOfLeafInts; ASN1Sequence seqOfLeafString; GMSSLeaf[] nextNextLeaf = new GMSSLeaf[seqOfLeafs.size()]; for (int i = 0; i < nextNextLeaf.length; i++) { seqOfLeafStat = (ASN1Sequence)seqOfLeafs.getObjectAt(i); // nextNextAuth[i]= new byte[nextNextAuthPart1.size()][]; seqOfLeafString = (ASN1Sequence)seqOfLeafStat.getObjectAt(0); seqOfLeafBytes = (ASN1Sequence)seqOfLeafStat.getObjectAt(1); seqOfLeafInts = (ASN1Sequence)seqOfLeafStat.getObjectAt(2); String[] name = new String[2]; name[0] = ((DERIA5String)seqOfLeafString.getObjectAt(0)).getString(); name[1] = ((DERIA5String)seqOfLeafString.getObjectAt(1)).getString(); byte[][] statByte = new byte[4][]; statByte[0] = ((DEROctetString)seqOfLeafBytes.getObjectAt(0)) .getOctets(); statByte[1] = ((DEROctetString)seqOfLeafBytes.getObjectAt(1)) .getOctets(); statByte[2] = ((DEROctetString)seqOfLeafBytes.getObjectAt(2)) .getOctets(); statByte[3] = ((DEROctetString)seqOfLeafBytes.getObjectAt(3)) .getOctets(); int[] statInt = new int[4]; statInt[0] = checkBigIntegerInIntRange(seqOfLeafInts.getObjectAt(0)); statInt[1] = checkBigIntegerInIntRange(seqOfLeafInts.getObjectAt(1)); statInt[2] = checkBigIntegerInIntRange(seqOfLeafInts.getObjectAt(2)); statInt[3] = checkBigIntegerInIntRange(seqOfLeafInts.getObjectAt(3)); nextNextLeaf[i] = new GMSSLeaf(DigestFactory.getDigest(name[0]).getClass(), statByte, statInt); } // --- Decode . ASN1Sequence seqOfUpperLeafs = (ASN1Sequence)mtsPrivateKey.getObjectAt(13); ASN1Sequence seqOfUpperLeafStat; ASN1Sequence seqOfUpperLeafBytes; ASN1Sequence seqOfUpperLeafInts; ASN1Sequence seqOfUpperLeafString; GMSSLeaf[] upperLeaf = new GMSSLeaf[seqOfUpperLeafs.size()]; for (int i = 0; i < upperLeaf.length; i++) { seqOfUpperLeafStat = (ASN1Sequence)seqOfUpperLeafs.getObjectAt(i); seqOfUpperLeafString = (ASN1Sequence)seqOfUpperLeafStat.getObjectAt(0); seqOfUpperLeafBytes = (ASN1Sequence)seqOfUpperLeafStat.getObjectAt(1); seqOfUpperLeafInts = (ASN1Sequence)seqOfUpperLeafStat.getObjectAt(2); String[] name = new String[2]; name[0] = ((DERIA5String)seqOfUpperLeafString.getObjectAt(0)).getString(); name[1] = ((DERIA5String)seqOfUpperLeafString.getObjectAt(1)).getString(); byte[][] statByte = new byte[4][]; statByte[0] = ((DEROctetString)seqOfUpperLeafBytes.getObjectAt(0)) .getOctets(); statByte[1] = ((DEROctetString)seqOfUpperLeafBytes.getObjectAt(1)) .getOctets(); statByte[2] = ((DEROctetString)seqOfUpperLeafBytes.getObjectAt(2)) .getOctets(); statByte[3] = ((DEROctetString)seqOfUpperLeafBytes.getObjectAt(3)) .getOctets(); int[] statInt = new int[4]; statInt[0] = checkBigIntegerInIntRange(seqOfUpperLeafInts.getObjectAt(0)); statInt[1] = checkBigIntegerInIntRange(seqOfUpperLeafInts.getObjectAt(1)); statInt[2] = checkBigIntegerInIntRange(seqOfUpperLeafInts.getObjectAt(2)); statInt[3] = checkBigIntegerInIntRange(seqOfUpperLeafInts.getObjectAt(3)); upperLeaf[i] = new GMSSLeaf(DigestFactory.getDigest(name[0]).getClass(), statByte, statInt); } // --- Decode . ASN1Sequence seqOfUpperTHLeafs = (ASN1Sequence)mtsPrivateKey.getObjectAt(14); ASN1Sequence seqOfUpperTHLeafStat; ASN1Sequence seqOfUpperTHLeafBytes; ASN1Sequence seqOfUpperTHLeafInts; ASN1Sequence seqOfUpperTHLeafString; GMSSLeaf[] upperTHLeaf = new GMSSLeaf[seqOfUpperTHLeafs.size()]; for (int i = 0; i < upperTHLeaf.length; i++) { seqOfUpperTHLeafStat = (ASN1Sequence)seqOfUpperTHLeafs.getObjectAt(i); seqOfUpperTHLeafString = (ASN1Sequence)seqOfUpperTHLeafStat.getObjectAt(0); seqOfUpperTHLeafBytes = (ASN1Sequence)seqOfUpperTHLeafStat.getObjectAt(1); seqOfUpperTHLeafInts = (ASN1Sequence)seqOfUpperTHLeafStat.getObjectAt(2); String[] name = new String[2]; name[0] = ((DERIA5String)seqOfUpperTHLeafString.getObjectAt(0)) .getString(); name[1] = ((DERIA5String)seqOfUpperTHLeafString.getObjectAt(1)) .getString(); byte[][] statByte = new byte[4][]; statByte[0] = ((DEROctetString)seqOfUpperTHLeafBytes.getObjectAt(0)) .getOctets(); statByte[1] = ((DEROctetString)seqOfUpperTHLeafBytes.getObjectAt(1)) .getOctets(); statByte[2] = ((DEROctetString)seqOfUpperTHLeafBytes.getObjectAt(2)) .getOctets(); statByte[3] = ((DEROctetString)seqOfUpperTHLeafBytes.getObjectAt(3)) .getOctets(); int[] statInt = new int[4]; statInt[0] = checkBigIntegerInIntRange(seqOfUpperTHLeafInts.getObjectAt(0)); statInt[1] = checkBigIntegerInIntRange(seqOfUpperTHLeafInts.getObjectAt(1)); statInt[2] = checkBigIntegerInIntRange(seqOfUpperTHLeafInts.getObjectAt(2)); statInt[3] = checkBigIntegerInIntRange(seqOfUpperTHLeafInts.getObjectAt(3)); upperTHLeaf[i] = new GMSSLeaf(DigestFactory.getDigest(name[0]).getClass(), statByte, statInt); } // --- Decode . ASN1Sequence minTreehashPart = (ASN1Sequence)mtsPrivateKey.getObjectAt(15); int[] minTreehash = new int[minTreehashPart.size()]; for (int i = 0; i < minTreehashPart.size(); i++) { minTreehash[i] = checkBigIntegerInIntRange(minTreehashPart.getObjectAt(i)); } // --- Decode . ASN1Sequence seqOfnextRoots = (ASN1Sequence)mtsPrivateKey.getObjectAt(16); byte[][] nextRoot = new byte[seqOfnextRoots.size()][]; for (int i = 0; i < nextRoot.length; i++) { nextRoot[i] = ((DEROctetString)seqOfnextRoots.getObjectAt(i)) .getOctets(); } // --- Decode . ASN1Sequence seqOfnextNextRoot = (ASN1Sequence)mtsPrivateKey.getObjectAt(17); ASN1Sequence seqOfnextNextRootStat; ASN1Sequence seqOfnextNextRootBytes; ASN1Sequence seqOfnextNextRootInts; ASN1Sequence seqOfnextNextRootString; ASN1Sequence seqOfnextNextRootTreeH; ASN1Sequence seqOfnextNextRootRetain; GMSSRootCalc[] nextNextRoot = new GMSSRootCalc[seqOfnextNextRoot.size()]; for (int i = 0; i < nextNextRoot.length; i++) { seqOfnextNextRootStat = (ASN1Sequence)seqOfnextNextRoot.getObjectAt(i); seqOfnextNextRootString = (ASN1Sequence)seqOfnextNextRootStat .getObjectAt(0); seqOfnextNextRootBytes = (ASN1Sequence)seqOfnextNextRootStat .getObjectAt(1); seqOfnextNextRootInts = (ASN1Sequence)seqOfnextNextRootStat.getObjectAt(2); seqOfnextNextRootTreeH = (ASN1Sequence)seqOfnextNextRootStat .getObjectAt(3); seqOfnextNextRootRetain = (ASN1Sequence)seqOfnextNextRootStat .getObjectAt(4); // decode treehash of nextNextRoot // --------------------------------- ASN1Sequence seqOfnextNextRootTreeHStat; ASN1Sequence seqOfnextNextRootTreeHBytes; ASN1Sequence seqOfnextNextRootTreeHInts; ASN1Sequence seqOfnextNextRootTreeHString; Treehash[] nnRTreehash = new Treehash[seqOfnextNextRootTreeH.size()]; for (int k = 0; k < nnRTreehash.length; k++) { seqOfnextNextRootTreeHStat = (ASN1Sequence)seqOfnextNextRootTreeH .getObjectAt(k); seqOfnextNextRootTreeHString = (ASN1Sequence)seqOfnextNextRootTreeHStat .getObjectAt(0); seqOfnextNextRootTreeHBytes = (ASN1Sequence)seqOfnextNextRootTreeHStat .getObjectAt(1); seqOfnextNextRootTreeHInts = (ASN1Sequence)seqOfnextNextRootTreeHStat .getObjectAt(2); String[] name = new String[2]; name[0] = ((DERIA5String)seqOfnextNextRootTreeHString.getObjectAt(0)) .getString(); name[1] = ((DERIA5String)seqOfnextNextRootTreeHString.getObjectAt(1)) .getString(); int tailLength = checkBigIntegerInIntRange(seqOfnextNextRootTreeHInts.getObjectAt(1)); byte[][] statByte = new byte[3 + tailLength][]; statByte[0] = ((DEROctetString)seqOfnextNextRootTreeHBytes .getObjectAt(0)).getOctets(); if (statByte[0].length == 0) { // if null was encoded statByte[0] = null; } statByte[1] = ((DEROctetString)seqOfnextNextRootTreeHBytes .getObjectAt(1)).getOctets(); statByte[2] = ((DEROctetString)seqOfnextNextRootTreeHBytes .getObjectAt(2)).getOctets(); for (int j = 0; j < tailLength; j++) { statByte[3 + j] = ((DEROctetString)seqOfnextNextRootTreeHBytes .getObjectAt(3 + j)).getOctets(); } int[] statInt = new int[6 + tailLength]; statInt[0] = checkBigIntegerInIntRange(seqOfnextNextRootTreeHInts.getObjectAt(0)); statInt[1] = tailLength; statInt[2] = checkBigIntegerInIntRange(seqOfnextNextRootTreeHInts.getObjectAt(2)); statInt[3] = checkBigIntegerInIntRange(seqOfnextNextRootTreeHInts.getObjectAt(3)); statInt[4] = checkBigIntegerInIntRange(seqOfnextNextRootTreeHInts.getObjectAt(4)); statInt[5] = checkBigIntegerInIntRange(seqOfnextNextRootTreeHInts.getObjectAt(5)); for (int j = 0; j < tailLength; j++) { statInt[6 + j] = checkBigIntegerInIntRange(seqOfnextNextRootTreeHInts .getObjectAt(6 + j)); } nnRTreehash[k] = new Treehash(DigestFactory.getDigest(name[0]).getClass(), statByte, statInt); } // --------------------------------- // decode retain of nextNextRoot // --------------------------------- // ASN1Sequence seqOfnextNextRootRetainPart0 = // (ASN1Sequence)seqOfnextNextRootRetain.get(0); ASN1Sequence seqOfnextNextRootRetainPart1; Vector[] nnRRetain = new Vector[seqOfnextNextRootRetain.size()]; for (int j = 0; j < nnRRetain.length; j++) { seqOfnextNextRootRetainPart1 = (ASN1Sequence)seqOfnextNextRootRetain .getObjectAt(j); nnRRetain[j] = new Vector(); for (int k = 0; k < seqOfnextNextRootRetainPart1.size(); k++) { nnRRetain[j] .addElement(((DEROctetString)seqOfnextNextRootRetainPart1 .getObjectAt(k)).getOctets()); } } // --------------------------------- String[] name = new String[2]; name[0] = ((DERIA5String)seqOfnextNextRootString.getObjectAt(0)) .getString(); name[1] = ((DERIA5String)seqOfnextNextRootString.getObjectAt(1)) .getString(); int heightOfTree = checkBigIntegerInIntRange(seqOfnextNextRootInts.getObjectAt(0)); int tailLength = checkBigIntegerInIntRange(seqOfnextNextRootInts.getObjectAt(7)); byte[][] statByte = new byte[1 + heightOfTree + tailLength][]; statByte[0] = ((DEROctetString)seqOfnextNextRootBytes.getObjectAt(0)) .getOctets(); for (int j = 0; j < heightOfTree; j++) { statByte[1 + j] = ((DEROctetString)seqOfnextNextRootBytes .getObjectAt(1 + j)).getOctets(); } for (int j = 0; j < tailLength; j++) { statByte[1 + heightOfTree + j] = ((DEROctetString)seqOfnextNextRootBytes .getObjectAt(1 + heightOfTree + j)).getOctets(); } int[] statInt = new int[8 + heightOfTree + tailLength]; statInt[0] = heightOfTree; statInt[1] = checkBigIntegerInIntRange(seqOfnextNextRootInts.getObjectAt(1)); statInt[2] = checkBigIntegerInIntRange(seqOfnextNextRootInts.getObjectAt(2)); statInt[3] = checkBigIntegerInIntRange(seqOfnextNextRootInts.getObjectAt(3)); statInt[4] = checkBigIntegerInIntRange(seqOfnextNextRootInts.getObjectAt(4)); statInt[5] = checkBigIntegerInIntRange(seqOfnextNextRootInts.getObjectAt(5)); statInt[6] = checkBigIntegerInIntRange(seqOfnextNextRootInts.getObjectAt(6)); statInt[7] = tailLength; for (int j = 0; j < heightOfTree; j++) { statInt[8 + j] = checkBigIntegerInIntRange(seqOfnextNextRootInts.getObjectAt(8 + j)); } for (int j = 0; j < tailLength; j++) { statInt[8 + heightOfTree + j] = checkBigIntegerInIntRange(seqOfnextNextRootInts.getObjectAt(8 + heightOfTree + j)); } nextNextRoot[i] = new GMSSRootCalc(DigestFactory.getDigest(name[0]).getClass(), statByte, statInt, nnRTreehash, nnRRetain); } // --- Decode . ASN1Sequence seqOfcurRootSig = (ASN1Sequence)mtsPrivateKey.getObjectAt(18); byte[][] curRootSig = new byte[seqOfcurRootSig.size()][]; for (int i = 0; i < curRootSig.length; i++) { curRootSig[i] = ((DEROctetString)seqOfcurRootSig.getObjectAt(i)) .getOctets(); } // --- Decode . ASN1Sequence seqOfnextRootSigs = (ASN1Sequence)mtsPrivateKey.getObjectAt(19); ASN1Sequence seqOfnRSStats; ASN1Sequence seqOfnRSStrings; ASN1Sequence seqOfnRSInts; ASN1Sequence seqOfnRSBytes; GMSSRootSig[] nextRootSig = new GMSSRootSig[seqOfnextRootSigs.size()]; for (int i = 0; i < nextRootSig.length; i++) { seqOfnRSStats = (ASN1Sequence)seqOfnextRootSigs.getObjectAt(i); // nextNextAuth[i]= new byte[nextNextAuthPart1.size()][]; seqOfnRSStrings = (ASN1Sequence)seqOfnRSStats.getObjectAt(0); seqOfnRSBytes = (ASN1Sequence)seqOfnRSStats.getObjectAt(1); seqOfnRSInts = (ASN1Sequence)seqOfnRSStats.getObjectAt(2); String[] name = new String[2]; name[0] = ((DERIA5String)seqOfnRSStrings.getObjectAt(0)).getString(); name[1] = ((DERIA5String)seqOfnRSStrings.getObjectAt(1)).getString(); byte[][] statByte = new byte[5][]; statByte[0] = ((DEROctetString)seqOfnRSBytes.getObjectAt(0)) .getOctets(); statByte[1] = ((DEROctetString)seqOfnRSBytes.getObjectAt(1)) .getOctets(); statByte[2] = ((DEROctetString)seqOfnRSBytes.getObjectAt(2)) .getOctets(); statByte[3] = ((DEROctetString)seqOfnRSBytes.getObjectAt(3)) .getOctets(); statByte[4] = ((DEROctetString)seqOfnRSBytes.getObjectAt(4)) .getOctets(); int[] statInt = new int[9]; statInt[0] = checkBigIntegerInIntRange(seqOfnRSInts.getObjectAt(0)); statInt[1] = checkBigIntegerInIntRange(seqOfnRSInts.getObjectAt(1)); statInt[2] = checkBigIntegerInIntRange(seqOfnRSInts.getObjectAt(2)); statInt[3] = checkBigIntegerInIntRange(seqOfnRSInts.getObjectAt(3)); statInt[4] = checkBigIntegerInIntRange(seqOfnRSInts.getObjectAt(4)); statInt[5] = checkBigIntegerInIntRange(seqOfnRSInts.getObjectAt(5)); statInt[6] = checkBigIntegerInIntRange(seqOfnRSInts.getObjectAt(6)); statInt[7] = checkBigIntegerInIntRange(seqOfnRSInts.getObjectAt(7)); statInt[8] = checkBigIntegerInIntRange(seqOfnRSInts.getObjectAt(8)); nextRootSig[i] = new GMSSRootSig(DigestFactory.getDigest(name[0]).getClass(), statByte, statInt); } // --- Decode . // TODO: Really check, why there are multiple algorithms, we only // use the first one!!! ASN1Sequence namePart = (ASN1Sequence)mtsPrivateKey.getObjectAt(20); String[] name = new String[namePart.size()]; for (int i = 0; i < name.length; i++) { name[i] = ((DERIA5String)namePart.getObjectAt(i)).getString(); } */ } public GMSSPrivateKey(int[] index, byte[][] currentSeed, byte[][] nextNextSeed, byte[][][] currentAuthPath, byte[][][] nextAuthPath, Treehash[][] currentTreehash, Treehash[][] nextTreehash, Vector[] currentStack, Vector[] nextStack, Vector[][] currentRetain, Vector[][] nextRetain, byte[][][] keep, GMSSLeaf[] nextNextLeaf, GMSSLeaf[] upperLeaf, GMSSLeaf[] upperTreehashLeaf, int[] minTreehash, byte[][] nextRoot, GMSSRootCalc[] nextNextRoot, byte[][] currentRootSig, GMSSRootSig[] nextRootSig, GMSSParameters gmssParameterset, AlgorithmIdentifier digestAlg) { AlgorithmIdentifier[] names = new AlgorithmIdentifier[] { digestAlg }; this.primitive = encode(index, currentSeed, nextNextSeed, currentAuthPath, nextAuthPath, keep, currentTreehash, nextTreehash, currentStack, nextStack, currentRetain, nextRetain, nextNextLeaf, upperLeaf, upperTreehashLeaf, minTreehash, nextRoot, nextNextRoot, currentRootSig, nextRootSig, gmssParameterset, names); } // TODO: change method signature to something more integrated into BouncyCastle /** * @param index tree indices * @param currentSeeds seed for the generation of private OTS keys for the * current subtrees (TREE) * @param nextNextSeeds seed for the generation of private OTS keys for the * subtrees after next (TREE++) * @param currentAuthPaths array of current authentication paths (AUTHPATH) * @param nextAuthPaths array of next authentication paths (AUTHPATH+) * @param keep keep array for the authPath algorithm * @param currentTreehash treehash for authPath algorithm of current tree * @param nextTreehash treehash for authPath algorithm of next tree (TREE+) * @param currentStack shared stack for authPath algorithm of current tree * @param nextStack shared stack for authPath algorithm of next tree (TREE+) * @param currentRetain retain stack for authPath algorithm of current tree * @param nextRetain retain stack for authPath algorithm of next tree (TREE+) * @param nextNextLeaf array of upcoming leafs of the tree after next (LEAF++) of * each layer * @param upperLeaf needed for precomputation of upper nodes * @param upperTreehashLeaf needed for precomputation of upper treehash nodes * @param minTreehash index of next treehash instance to receive an update * @param nextRoot the roots of the next trees (ROOT+) * @param nextNextRoot the roots of the tree after next (ROOT++) * @param currentRootSig array of signatures of the roots of the current subtrees * (SIG) * @param nextRootSig array of signatures of the roots of the next subtree * (SIG+) * @param gmssParameterset the GMSS Parameterset * @param algorithms An array of algorithm identifiers, containing the hash function details */ private ASN1Primitive encode(int[] index, byte[][] currentSeeds, byte[][] nextNextSeeds, byte[][][] currentAuthPaths, byte[][][] nextAuthPaths, byte[][][] keep, Treehash[][] currentTreehash, Treehash[][] nextTreehash, Vector[] currentStack, Vector[] nextStack, Vector[][] currentRetain, Vector[][] nextRetain, GMSSLeaf[] nextNextLeaf, GMSSLeaf[] upperLeaf, GMSSLeaf[] upperTreehashLeaf, int[] minTreehash, byte[][] nextRoot, GMSSRootCalc[] nextNextRoot, byte[][] currentRootSig, GMSSRootSig[] nextRootSig, GMSSParameters gmssParameterset, AlgorithmIdentifier[] algorithms) { ASN1EncodableVector result = new ASN1EncodableVector(); // --- Encode . ASN1EncodableVector indexPart = new ASN1EncodableVector(); for (int i = 0; i < index.length; i++) { indexPart.add(new ASN1Integer(index[i])); } result.add(new DERSequence(indexPart)); // --- Encode . ASN1EncodableVector curSeedsPart = new ASN1EncodableVector(); for (int i = 0; i < currentSeeds.length; i++) { curSeedsPart.add(new DEROctetString(currentSeeds[i])); } result.add(new DERSequence(curSeedsPart)); // --- Encode . ASN1EncodableVector nextNextSeedsPart = new ASN1EncodableVector(); for (int i = 0; i < nextNextSeeds.length; i++) { nextNextSeedsPart.add(new DEROctetString(nextNextSeeds[i])); } result.add(new DERSequence(nextNextSeedsPart)); // --- Encode . ASN1EncodableVector curAuthPart0 = new ASN1EncodableVector(); ASN1EncodableVector curAuthPart1 = new ASN1EncodableVector(); for (int i = 0; i < currentAuthPaths.length; i++) { for (int j = 0; j < currentAuthPaths[i].length; j++) { curAuthPart0.add(new DEROctetString(currentAuthPaths[i][j])); } curAuthPart1.add(new DERSequence(curAuthPart0)); curAuthPart0 = new ASN1EncodableVector(); } result.add(new DERSequence(curAuthPart1)); // --- Encode . ASN1EncodableVector nextAuthPart0 = new ASN1EncodableVector(); ASN1EncodableVector nextAuthPart1 = new ASN1EncodableVector(); for (int i = 0; i < nextAuthPaths.length; i++) { for (int j = 0; j < nextAuthPaths[i].length; j++) { nextAuthPart0.add(new DEROctetString(nextAuthPaths[i][j])); } nextAuthPart1.add(new DERSequence(nextAuthPart0)); nextAuthPart0 = new ASN1EncodableVector(); } result.add(new DERSequence(nextAuthPart1)); // --- Encode . ASN1EncodableVector seqOfTreehash0 = new ASN1EncodableVector(); ASN1EncodableVector seqOfTreehash1 = new ASN1EncodableVector(); ASN1EncodableVector seqOfStat = new ASN1EncodableVector(); ASN1EncodableVector seqOfByte = new ASN1EncodableVector(); ASN1EncodableVector seqOfInt = new ASN1EncodableVector(); for (int i = 0; i < currentTreehash.length; i++) { for (int j = 0; j < currentTreehash[i].length; j++) { seqOfStat.add(new DERSequence(algorithms[0])); int tailLength = currentTreehash[i][j].getStatInt()[1]; seqOfByte.add(new DEROctetString(currentTreehash[i][j] .getStatByte()[0])); seqOfByte.add(new DEROctetString(currentTreehash[i][j] .getStatByte()[1])); seqOfByte.add(new DEROctetString(currentTreehash[i][j] .getStatByte()[2])); for (int k = 0; k < tailLength; k++) { seqOfByte.add(new DEROctetString(currentTreehash[i][j] .getStatByte()[3 + k])); } seqOfStat.add(new DERSequence(seqOfByte)); seqOfByte = new ASN1EncodableVector(); seqOfInt.add(new ASN1Integer( currentTreehash[i][j].getStatInt()[0])); seqOfInt.add(new ASN1Integer(tailLength)); seqOfInt.add(new ASN1Integer( currentTreehash[i][j].getStatInt()[2])); seqOfInt.add(new ASN1Integer( currentTreehash[i][j].getStatInt()[3])); seqOfInt.add(new ASN1Integer( currentTreehash[i][j].getStatInt()[4])); seqOfInt.add(new ASN1Integer( currentTreehash[i][j].getStatInt()[5])); for (int k = 0; k < tailLength; k++) { seqOfInt.add(new ASN1Integer(currentTreehash[i][j] .getStatInt()[6 + k])); } seqOfStat.add(new DERSequence(seqOfInt)); seqOfInt = new ASN1EncodableVector(); seqOfTreehash1.add(new DERSequence(seqOfStat)); seqOfStat = new ASN1EncodableVector(); } seqOfTreehash0.add(new DERSequence(seqOfTreehash1)); seqOfTreehash1 = new ASN1EncodableVector(); } result.add(new DERSequence(seqOfTreehash0)); // --- Encode . seqOfTreehash0 = new ASN1EncodableVector(); seqOfTreehash1 = new ASN1EncodableVector(); seqOfStat = new ASN1EncodableVector(); seqOfByte = new ASN1EncodableVector(); seqOfInt = new ASN1EncodableVector(); for (int i = 0; i < nextTreehash.length; i++) { for (int j = 0; j < nextTreehash[i].length; j++) { seqOfStat.add(new DERSequence(algorithms[0])); int tailLength = nextTreehash[i][j].getStatInt()[1]; seqOfByte.add(new DEROctetString(nextTreehash[i][j] .getStatByte()[0])); seqOfByte.add(new DEROctetString(nextTreehash[i][j] .getStatByte()[1])); seqOfByte.add(new DEROctetString(nextTreehash[i][j] .getStatByte()[2])); for (int k = 0; k < tailLength; k++) { seqOfByte.add(new DEROctetString(nextTreehash[i][j] .getStatByte()[3 + k])); } seqOfStat.add(new DERSequence(seqOfByte)); seqOfByte = new ASN1EncodableVector(); seqOfInt .add(new ASN1Integer(nextTreehash[i][j].getStatInt()[0])); seqOfInt.add(new ASN1Integer(tailLength)); seqOfInt .add(new ASN1Integer(nextTreehash[i][j].getStatInt()[2])); seqOfInt .add(new ASN1Integer(nextTreehash[i][j].getStatInt()[3])); seqOfInt .add(new ASN1Integer(nextTreehash[i][j].getStatInt()[4])); seqOfInt .add(new ASN1Integer(nextTreehash[i][j].getStatInt()[5])); for (int k = 0; k < tailLength; k++) { seqOfInt.add(new ASN1Integer(nextTreehash[i][j] .getStatInt()[6 + k])); } seqOfStat.add(new DERSequence(seqOfInt)); seqOfInt = new ASN1EncodableVector(); seqOfTreehash1.add(new DERSequence(seqOfStat)); seqOfStat = new ASN1EncodableVector(); } seqOfTreehash0.add(new DERSequence(new DERSequence(seqOfTreehash1))); seqOfTreehash1 = new ASN1EncodableVector(); } result.add(new DERSequence(seqOfTreehash0)); // --- Encode . ASN1EncodableVector keepPart0 = new ASN1EncodableVector(); ASN1EncodableVector keepPart1 = new ASN1EncodableVector(); for (int i = 0; i < keep.length; i++) { for (int j = 0; j < keep[i].length; j++) { keepPart0.add(new DEROctetString(keep[i][j])); } keepPart1.add(new DERSequence(keepPart0)); keepPart0 = new ASN1EncodableVector(); } result.add(new DERSequence(keepPart1)); // --- Encode . ASN1EncodableVector curStackPart0 = new ASN1EncodableVector(); ASN1EncodableVector curStackPart1 = new ASN1EncodableVector(); for (int i = 0; i < currentStack.length; i++) { for (int j = 0; j < currentStack[i].size(); j++) { curStackPart0.add(new DEROctetString((byte[])currentStack[i] .elementAt(j))); } curStackPart1.add(new DERSequence(curStackPart0)); curStackPart0 = new ASN1EncodableVector(); } result.add(new DERSequence(curStackPart1)); // --- Encode . ASN1EncodableVector nextStackPart0 = new ASN1EncodableVector(); ASN1EncodableVector nextStackPart1 = new ASN1EncodableVector(); for (int i = 0; i < nextStack.length; i++) { for (int j = 0; j < nextStack[i].size(); j++) { nextStackPart0.add(new DEROctetString((byte[])nextStack[i] .elementAt(j))); } nextStackPart1.add(new DERSequence(nextStackPart0)); nextStackPart0 = new ASN1EncodableVector(); } result.add(new DERSequence(nextStackPart1)); // --- Encode . ASN1EncodableVector currentRetainPart0 = new ASN1EncodableVector(); ASN1EncodableVector currentRetainPart1 = new ASN1EncodableVector(); ASN1EncodableVector currentRetainPart2 = new ASN1EncodableVector(); for (int i = 0; i < currentRetain.length; i++) { for (int j = 0; j < currentRetain[i].length; j++) { for (int k = 0; k < currentRetain[i][j].size(); k++) { currentRetainPart0.add(new DEROctetString( (byte[])currentRetain[i][j].elementAt(k))); } currentRetainPart1.add(new DERSequence(currentRetainPart0)); currentRetainPart0 = new ASN1EncodableVector(); } currentRetainPart2.add(new DERSequence(currentRetainPart1)); currentRetainPart1 = new ASN1EncodableVector(); } result.add(new DERSequence(currentRetainPart2)); // --- Encode . ASN1EncodableVector nextRetainPart0 = new ASN1EncodableVector(); ASN1EncodableVector nextRetainPart1 = new ASN1EncodableVector(); ASN1EncodableVector nextRetainPart2 = new ASN1EncodableVector(); for (int i = 0; i < nextRetain.length; i++) { for (int j = 0; j < nextRetain[i].length; j++) { for (int k = 0; k < nextRetain[i][j].size(); k++) { nextRetainPart0.add(new DEROctetString( (byte[])nextRetain[i][j].elementAt(k))); } nextRetainPart1.add(new DERSequence(nextRetainPart0)); nextRetainPart0 = new ASN1EncodableVector(); } nextRetainPart2.add(new DERSequence(nextRetainPart1)); nextRetainPart1 = new ASN1EncodableVector(); } result.add(new DERSequence(nextRetainPart2)); // --- Encode . ASN1EncodableVector seqOfLeaf = new ASN1EncodableVector(); seqOfStat = new ASN1EncodableVector(); seqOfByte = new ASN1EncodableVector(); seqOfInt = new ASN1EncodableVector(); for (int i = 0; i < nextNextLeaf.length; i++) { seqOfStat.add(new DERSequence(algorithms[0])); byte[][] tempByte = nextNextLeaf[i].getStatByte(); seqOfByte.add(new DEROctetString(tempByte[0])); seqOfByte.add(new DEROctetString(tempByte[1])); seqOfByte.add(new DEROctetString(tempByte[2])); seqOfByte.add(new DEROctetString(tempByte[3])); seqOfStat.add(new DERSequence(seqOfByte)); seqOfByte = new ASN1EncodableVector(); int[] tempInt = nextNextLeaf[i].getStatInt(); seqOfInt.add(new ASN1Integer(tempInt[0])); seqOfInt.add(new ASN1Integer(tempInt[1])); seqOfInt.add(new ASN1Integer(tempInt[2])); seqOfInt.add(new ASN1Integer(tempInt[3])); seqOfStat.add(new DERSequence(seqOfInt)); seqOfInt = new ASN1EncodableVector(); seqOfLeaf.add(new DERSequence(seqOfStat)); seqOfStat = new ASN1EncodableVector(); } result.add(new DERSequence(seqOfLeaf)); // --- Encode . ASN1EncodableVector seqOfUpperLeaf = new ASN1EncodableVector(); seqOfStat = new ASN1EncodableVector(); seqOfByte = new ASN1EncodableVector(); seqOfInt = new ASN1EncodableVector(); for (int i = 0; i < upperLeaf.length; i++) { seqOfStat.add(new DERSequence(algorithms[0])); byte[][] tempByte = upperLeaf[i].getStatByte(); seqOfByte.add(new DEROctetString(tempByte[0])); seqOfByte.add(new DEROctetString(tempByte[1])); seqOfByte.add(new DEROctetString(tempByte[2])); seqOfByte.add(new DEROctetString(tempByte[3])); seqOfStat.add(new DERSequence(seqOfByte)); seqOfByte = new ASN1EncodableVector(); int[] tempInt = upperLeaf[i].getStatInt(); seqOfInt.add(new ASN1Integer(tempInt[0])); seqOfInt.add(new ASN1Integer(tempInt[1])); seqOfInt.add(new ASN1Integer(tempInt[2])); seqOfInt.add(new ASN1Integer(tempInt[3])); seqOfStat.add(new DERSequence(seqOfInt)); seqOfInt = new ASN1EncodableVector(); seqOfUpperLeaf.add(new DERSequence(seqOfStat)); seqOfStat = new ASN1EncodableVector(); } result.add(new DERSequence(seqOfUpperLeaf)); // encode ASN1EncodableVector seqOfUpperTreehashLeaf = new ASN1EncodableVector(); seqOfStat = new ASN1EncodableVector(); seqOfByte = new ASN1EncodableVector(); seqOfInt = new ASN1EncodableVector(); for (int i = 0; i < upperTreehashLeaf.length; i++) { seqOfStat.add(new DERSequence(algorithms[0])); byte[][] tempByte = upperTreehashLeaf[i].getStatByte(); seqOfByte.add(new DEROctetString(tempByte[0])); seqOfByte.add(new DEROctetString(tempByte[1])); seqOfByte.add(new DEROctetString(tempByte[2])); seqOfByte.add(new DEROctetString(tempByte[3])); seqOfStat.add(new DERSequence(seqOfByte)); seqOfByte = new ASN1EncodableVector(); int[] tempInt = upperTreehashLeaf[i].getStatInt(); seqOfInt.add(new ASN1Integer(tempInt[0])); seqOfInt.add(new ASN1Integer(tempInt[1])); seqOfInt.add(new ASN1Integer(tempInt[2])); seqOfInt.add(new ASN1Integer(tempInt[3])); seqOfStat.add(new DERSequence(seqOfInt)); seqOfInt = new ASN1EncodableVector(); seqOfUpperTreehashLeaf.add(new DERSequence(seqOfStat)); seqOfStat = new ASN1EncodableVector(); } result.add(new DERSequence(seqOfUpperTreehashLeaf)); // --- Encode . ASN1EncodableVector minTreehashPart = new ASN1EncodableVector(); for (int i = 0; i < minTreehash.length; i++) { minTreehashPart.add(new ASN1Integer(minTreehash[i])); } result.add(new DERSequence(minTreehashPart)); // --- Encode . ASN1EncodableVector nextRootPart = new ASN1EncodableVector(); for (int i = 0; i < nextRoot.length; i++) { nextRootPart.add(new DEROctetString(nextRoot[i])); } result.add(new DERSequence(nextRootPart)); // --- Encode . ASN1EncodableVector seqOfnextNextRoot = new ASN1EncodableVector(); ASN1EncodableVector seqOfnnRStats = new ASN1EncodableVector(); ASN1EncodableVector seqOfnnRStrings = new ASN1EncodableVector(); ASN1EncodableVector seqOfnnRBytes = new ASN1EncodableVector(); ASN1EncodableVector seqOfnnRInts = new ASN1EncodableVector(); ASN1EncodableVector seqOfnnRTreehash = new ASN1EncodableVector(); ASN1EncodableVector seqOfnnRRetain = new ASN1EncodableVector(); for (int i = 0; i < nextNextRoot.length; i++) { seqOfnnRStats.add(new DERSequence(algorithms[0])); seqOfnnRStrings = new ASN1EncodableVector(); int heightOfTree = nextNextRoot[i].getStatInt()[0]; int tailLength = nextNextRoot[i].getStatInt()[7]; seqOfnnRBytes.add(new DEROctetString( nextNextRoot[i].getStatByte()[0])); for (int j = 0; j < heightOfTree; j++) { seqOfnnRBytes.add(new DEROctetString(nextNextRoot[i] .getStatByte()[1 + j])); } for (int j = 0; j < tailLength; j++) { seqOfnnRBytes.add(new DEROctetString(nextNextRoot[i] .getStatByte()[1 + heightOfTree + j])); } seqOfnnRStats.add(new DERSequence(seqOfnnRBytes)); seqOfnnRBytes = new ASN1EncodableVector(); seqOfnnRInts.add(new ASN1Integer(heightOfTree)); seqOfnnRInts.add(new ASN1Integer(nextNextRoot[i].getStatInt()[1])); seqOfnnRInts.add(new ASN1Integer(nextNextRoot[i].getStatInt()[2])); seqOfnnRInts.add(new ASN1Integer(nextNextRoot[i].getStatInt()[3])); seqOfnnRInts.add(new ASN1Integer(nextNextRoot[i].getStatInt()[4])); seqOfnnRInts.add(new ASN1Integer(nextNextRoot[i].getStatInt()[5])); seqOfnnRInts.add(new ASN1Integer(nextNextRoot[i].getStatInt()[6])); seqOfnnRInts.add(new ASN1Integer(tailLength)); for (int j = 0; j < heightOfTree; j++) { seqOfnnRInts.add(new ASN1Integer( nextNextRoot[i].getStatInt()[8 + j])); } for (int j = 0; j < tailLength; j++) { seqOfnnRInts.add(new ASN1Integer(nextNextRoot[i].getStatInt()[8 + heightOfTree + j])); } seqOfnnRStats.add(new DERSequence(seqOfnnRInts)); seqOfnnRInts = new ASN1EncodableVector(); // add treehash of nextNextRoot object // ---------------------------- seqOfStat = new ASN1EncodableVector(); seqOfByte = new ASN1EncodableVector(); seqOfInt = new ASN1EncodableVector(); if (nextNextRoot[i].getTreehash() != null) { for (int j = 0; j < nextNextRoot[i].getTreehash().length; j++) { seqOfStat.add(new DERSequence(algorithms[0])); tailLength = nextNextRoot[i].getTreehash()[j].getStatInt()[1]; seqOfByte.add(new DEROctetString(nextNextRoot[i] .getTreehash()[j].getStatByte()[0])); seqOfByte.add(new DEROctetString(nextNextRoot[i] .getTreehash()[j].getStatByte()[1])); seqOfByte.add(new DEROctetString(nextNextRoot[i] .getTreehash()[j].getStatByte()[2])); for (int k = 0; k < tailLength; k++) { seqOfByte.add(new DEROctetString(nextNextRoot[i] .getTreehash()[j].getStatByte()[3 + k])); } seqOfStat.add(new DERSequence(seqOfByte)); seqOfByte = new ASN1EncodableVector(); seqOfInt.add(new ASN1Integer( nextNextRoot[i].getTreehash()[j].getStatInt()[0])); seqOfInt.add(new ASN1Integer(tailLength)); seqOfInt.add(new ASN1Integer( nextNextRoot[i].getTreehash()[j].getStatInt()[2])); seqOfInt.add(new ASN1Integer( nextNextRoot[i].getTreehash()[j].getStatInt()[3])); seqOfInt.add(new ASN1Integer( nextNextRoot[i].getTreehash()[j].getStatInt()[4])); seqOfInt.add(new ASN1Integer( nextNextRoot[i].getTreehash()[j].getStatInt()[5])); for (int k = 0; k < tailLength; k++) { seqOfInt.add(new ASN1Integer(nextNextRoot[i] .getTreehash()[j].getStatInt()[6 + k])); } seqOfStat.add(new DERSequence(seqOfInt)); seqOfInt = new ASN1EncodableVector(); seqOfnnRTreehash.add(new DERSequence(seqOfStat)); seqOfStat = new ASN1EncodableVector(); } } // ---------------------------- seqOfnnRStats.add(new DERSequence(seqOfnnRTreehash)); seqOfnnRTreehash = new ASN1EncodableVector(); // encode retain of nextNextRoot // ---------------------------- // --- Encode . currentRetainPart0 = new ASN1EncodableVector(); if (nextNextRoot[i].getRetain() != null) { for (int j = 0; j < nextNextRoot[i].getRetain().length; j++) { for (int k = 0; k < nextNextRoot[i].getRetain()[j].size(); k++) { currentRetainPart0.add(new DEROctetString( (byte[])nextNextRoot[i].getRetain()[j] .elementAt(k))); } seqOfnnRRetain.add(new DERSequence(currentRetainPart0)); currentRetainPart0 = new ASN1EncodableVector(); } } // ---------------------------- seqOfnnRStats.add(new DERSequence(seqOfnnRRetain)); seqOfnnRRetain = new ASN1EncodableVector(); seqOfnextNextRoot.add(new DERSequence(seqOfnnRStats)); seqOfnnRStats = new ASN1EncodableVector(); } result.add(new DERSequence(seqOfnextNextRoot)); // --- Encode . ASN1EncodableVector curRootSigPart = new ASN1EncodableVector(); for (int i = 0; i < currentRootSig.length; i++) { curRootSigPart.add(new DEROctetString(currentRootSig[i])); } result.add(new DERSequence(curRootSigPart)); // --- Encode . ASN1EncodableVector seqOfnextRootSigs = new ASN1EncodableVector(); ASN1EncodableVector seqOfnRSStats = new ASN1EncodableVector(); ASN1EncodableVector seqOfnRSStrings = new ASN1EncodableVector(); ASN1EncodableVector seqOfnRSBytes = new ASN1EncodableVector(); ASN1EncodableVector seqOfnRSInts = new ASN1EncodableVector(); for (int i = 0; i < nextRootSig.length; i++) { seqOfnRSStats.add(new DERSequence(algorithms[0])); seqOfnRSStrings = new ASN1EncodableVector(); seqOfnRSBytes.add(new DEROctetString( nextRootSig[i].getStatByte()[0])); seqOfnRSBytes.add(new DEROctetString( nextRootSig[i].getStatByte()[1])); seqOfnRSBytes.add(new DEROctetString( nextRootSig[i].getStatByte()[2])); seqOfnRSBytes.add(new DEROctetString( nextRootSig[i].getStatByte()[3])); seqOfnRSBytes.add(new DEROctetString( nextRootSig[i].getStatByte()[4])); seqOfnRSStats.add(new DERSequence(seqOfnRSBytes)); seqOfnRSBytes = new ASN1EncodableVector(); seqOfnRSInts.add(new ASN1Integer(nextRootSig[i].getStatInt()[0])); seqOfnRSInts.add(new ASN1Integer(nextRootSig[i].getStatInt()[1])); seqOfnRSInts.add(new ASN1Integer(nextRootSig[i].getStatInt()[2])); seqOfnRSInts.add(new ASN1Integer(nextRootSig[i].getStatInt()[3])); seqOfnRSInts.add(new ASN1Integer(nextRootSig[i].getStatInt()[4])); seqOfnRSInts.add(new ASN1Integer(nextRootSig[i].getStatInt()[5])); seqOfnRSInts.add(new ASN1Integer(nextRootSig[i].getStatInt()[6])); seqOfnRSInts.add(new ASN1Integer(nextRootSig[i].getStatInt()[7])); seqOfnRSInts.add(new ASN1Integer(nextRootSig[i].getStatInt()[8])); seqOfnRSStats.add(new DERSequence(seqOfnRSInts)); seqOfnRSInts = new ASN1EncodableVector(); seqOfnextRootSigs.add(new DERSequence(seqOfnRSStats)); seqOfnRSStats = new ASN1EncodableVector(); } result.add(new DERSequence(seqOfnextRootSigs)); // --- Encode . ASN1EncodableVector parSetPart0 = new ASN1EncodableVector(); ASN1EncodableVector parSetPart1 = new ASN1EncodableVector(); ASN1EncodableVector parSetPart2 = new ASN1EncodableVector(); ASN1EncodableVector parSetPart3 = new ASN1EncodableVector(); for (int i = 0; i < gmssParameterset.getHeightOfTrees().length; i++) { parSetPart1.add(new ASN1Integer( gmssParameterset.getHeightOfTrees()[i])); parSetPart2.add(new ASN1Integer(gmssParameterset .getWinternitzParameter()[i])); parSetPart3.add(new ASN1Integer(gmssParameterset.getK()[i])); } parSetPart0.add(new ASN1Integer(gmssParameterset.getNumOfLayers())); parSetPart0.add(new DERSequence(parSetPart1)); parSetPart0.add(new DERSequence(parSetPart2)); parSetPart0.add(new DERSequence(parSetPart3)); result.add(new DERSequence(parSetPart0)); // --- Encode . ASN1EncodableVector namesPart = new ASN1EncodableVector(); for (int i = 0; i < algorithms.length; i++) { namesPart.add(algorithms[i]); } result.add(new DERSequence(namesPart)); return new DERSequence(result); } private static int checkBigIntegerInIntRange(ASN1Encodable a) { BigInteger b = ((ASN1Integer)a).getValue(); if ((b.compareTo(BigInteger.valueOf(Integer.MAX_VALUE)) > 0) || (b.compareTo(BigInteger.valueOf(Integer.MIN_VALUE)) < 0)) { throw new IllegalArgumentException("BigInteger not in Range: " + b.toString()); } return b.intValue(); } public ASN1Primitive toASN1Primitive() { return this.primitive; } } bouncycastle-1.49.orig/src/org/bouncycastle/pqc/asn1/RainbowPublicKey.java0000644000175000017500000001233312151251423026201 0ustar ebourgebourgpackage org.bouncycastle.pqc.asn1; import org.bouncycastle.asn1.ASN1EncodableVector; import org.bouncycastle.asn1.ASN1Integer; import org.bouncycastle.asn1.ASN1Object; import org.bouncycastle.asn1.ASN1ObjectIdentifier; import org.bouncycastle.asn1.ASN1OctetString; import org.bouncycastle.asn1.ASN1Primitive; import org.bouncycastle.asn1.ASN1Sequence; import org.bouncycastle.asn1.DEROctetString; import org.bouncycastle.asn1.DERSequence; import org.bouncycastle.pqc.crypto.rainbow.util.RainbowUtil; /** * This class implements an ASN.1 encoded Rainbow public key. The ASN.1 definition * of this structure is: *

    *

     *       RainbowPublicKey ::= SEQUENCE {
     *         CHOICE
     *         {
     *         oid        OBJECT IDENTIFIER         -- OID identifying the algorithm
     *         version    INTEGER                    -- 0
     *         }
     *         docLength        Integer               -- length of the code
     *         coeffquadratic   SEQUENCE OF OCTET STRING -- quadratic (mixed) coefficients
     *         coeffsingular    SEQUENCE OF OCTET STRING -- singular coefficients
     *         coeffscalar    SEQUENCE OF OCTET STRING -- scalar coefficients
     *       }
     * 
    */ public class RainbowPublicKey extends ASN1Object { private ASN1Integer version; private ASN1ObjectIdentifier oid; private ASN1Integer docLength; private byte[][] coeffQuadratic; private byte[][] coeffSingular; private byte[] coeffScalar; private RainbowPublicKey(ASN1Sequence seq) { // or version if (seq.getObjectAt(0) instanceof ASN1Integer) { version = ASN1Integer.getInstance(seq.getObjectAt(0)); } else { oid = ASN1ObjectIdentifier.getInstance(seq.getObjectAt(0)); } docLength = ASN1Integer.getInstance(seq.getObjectAt(1)); ASN1Sequence asnCoeffQuad = ASN1Sequence.getInstance(seq.getObjectAt(2)); coeffQuadratic = new byte[asnCoeffQuad.size()][]; for (int quadSize = 0; quadSize < asnCoeffQuad.size(); quadSize++) { coeffQuadratic[quadSize] = ASN1OctetString.getInstance(asnCoeffQuad.getObjectAt(quadSize)).getOctets(); } ASN1Sequence asnCoeffSing = (ASN1Sequence)seq.getObjectAt(3); coeffSingular = new byte[asnCoeffSing.size()][]; for (int singSize = 0; singSize < asnCoeffSing.size(); singSize++) { coeffSingular[singSize] = ASN1OctetString.getInstance(asnCoeffSing.getObjectAt(singSize)).getOctets(); } ASN1Sequence asnCoeffScalar = (ASN1Sequence)seq.getObjectAt(4); coeffScalar = ASN1OctetString.getInstance(asnCoeffScalar.getObjectAt(0)).getOctets(); } public RainbowPublicKey(int docLength, short[][] coeffQuadratic, short[][] coeffSingular, short[] coeffScalar) { this.version = new ASN1Integer(0); this.docLength = new ASN1Integer(docLength); this.coeffQuadratic = RainbowUtil.convertArray(coeffQuadratic); this.coeffSingular = RainbowUtil.convertArray(coeffSingular); this.coeffScalar = RainbowUtil.convertArray(coeffScalar); } public static RainbowPublicKey getInstance(Object o) { if (o instanceof RainbowPublicKey) { return (RainbowPublicKey)o; } else if (o != null) { return new RainbowPublicKey(ASN1Sequence.getInstance(o)); } return null; } public ASN1Integer getVersion() { return version; } /** * @return the docLength */ public int getDocLength() { return this.docLength.getValue().intValue(); } /** * @return the coeffquadratic */ public short[][] getCoeffQuadratic() { return RainbowUtil.convertArray(coeffQuadratic); } /** * @return the coeffsingular */ public short[][] getCoeffSingular() { return RainbowUtil.convertArray(coeffSingular); } /** * @return the coeffscalar */ public short[] getCoeffScalar() { return RainbowUtil.convertArray(coeffScalar); } public ASN1Primitive toASN1Primitive() { ASN1EncodableVector v = new ASN1EncodableVector(); // encode or version if (version != null) { v.add(version); } else { v.add(oid); } // encode v.add(docLength); // encode ASN1EncodableVector asnCoeffQuad = new ASN1EncodableVector(); for (int i = 0; i < coeffQuadratic.length; i++) { asnCoeffQuad.add(new DEROctetString(coeffQuadratic[i])); } v.add(new DERSequence(asnCoeffQuad)); // encode ASN1EncodableVector asnCoeffSing = new ASN1EncodableVector(); for (int i = 0; i < coeffSingular.length; i++) { asnCoeffSing.add(new DEROctetString(coeffSingular[i])); } v.add(new DERSequence(asnCoeffSing)); // encode ASN1EncodableVector asnCoeffScalar = new ASN1EncodableVector(); asnCoeffScalar.add(new DEROctetString(coeffScalar)); v.add(new DERSequence(asnCoeffScalar)); return new DERSequence(v); } } bouncycastle-1.49.orig/src/org/bouncycastle/pqc/asn1/McEliecePublicKey.java0000644000175000017500000000431212104636446026256 0ustar ebourgebourgpackage org.bouncycastle.pqc.asn1; import java.math.BigInteger; import org.bouncycastle.asn1.ASN1EncodableVector; import org.bouncycastle.asn1.ASN1Integer; import org.bouncycastle.asn1.ASN1Object; import org.bouncycastle.asn1.ASN1ObjectIdentifier; import org.bouncycastle.asn1.ASN1OctetString; import org.bouncycastle.asn1.ASN1Primitive; import org.bouncycastle.asn1.ASN1Sequence; import org.bouncycastle.asn1.DEROctetString; import org.bouncycastle.asn1.DERSequence; import org.bouncycastle.pqc.math.linearalgebra.GF2Matrix; public class McEliecePublicKey extends ASN1Object { private ASN1ObjectIdentifier oid; private int n; private int t; private byte[] matrixG; public McEliecePublicKey(ASN1ObjectIdentifier oid, int n, int t, GF2Matrix g) { this.oid = oid; this.n = n; this.t = t; this.matrixG = g.getEncoded(); } private McEliecePublicKey(ASN1Sequence seq) { oid = ((ASN1ObjectIdentifier)seq.getObjectAt(0)); BigInteger bigN = ((ASN1Integer)seq.getObjectAt(1)).getValue(); n = bigN.intValue(); BigInteger bigT = ((ASN1Integer)seq.getObjectAt(2)).getValue(); t = bigT.intValue(); matrixG = ((ASN1OctetString)seq.getObjectAt(3)).getOctets(); } public ASN1ObjectIdentifier getOID() { return oid; } public int getN() { return n; } public int getT() { return t; } public GF2Matrix getG() { return new GF2Matrix(matrixG); } public ASN1Primitive toASN1Primitive() { ASN1EncodableVector v = new ASN1EncodableVector(); // encode v.add(oid); // encode v.add(new ASN1Integer(n)); // encode v.add(new ASN1Integer(t)); // encode v.add(new DEROctetString(matrixG)); return new DERSequence(v); } public static McEliecePublicKey getInstance(Object o) { if (o instanceof McEliecePublicKey) { return (McEliecePublicKey)o; } else if (o != null) { return new McEliecePublicKey(ASN1Sequence.getInstance(o)); } return null; } } bouncycastle-1.49.orig/src/org/bouncycastle/pqc/math/0000755000175000017500000000000012152033551022213 5ustar ebourgebourgbouncycastle-1.49.orig/src/org/bouncycastle/pqc/math/linearalgebra/0000755000175000017500000000000012152033551025003 5ustar ebourgebourgbouncycastle-1.49.orig/src/org/bouncycastle/pqc/math/linearalgebra/GF2nPolynomial.java0000644000175000017500000004025512043365070030457 0ustar ebourgebourgpackage org.bouncycastle.pqc.math.linearalgebra; /** * This class implements polynomials over GF2nElements. * * @see GF2nElement */ public class GF2nPolynomial { private GF2nElement[] coeff; // keeps the coefficients of this polynomial private int size; // the size of this polynomial /** * Creates a new PolynomialGF2n of size deg and elem as * coefficients. * * @param deg - * the maximum degree + 1 * @param elem - * a GF2nElement */ public GF2nPolynomial(int deg, GF2nElement elem) { size = deg; coeff = new GF2nElement[size]; for (int i = 0; i < size; i++) { coeff[i] = (GF2nElement)elem.clone(); } } /** * Creates a new PolynomialGF2n of size deg. * * @param deg the maximum degree + 1 */ private GF2nPolynomial(int deg) { size = deg; coeff = new GF2nElement[size]; } /** * Creates a new PolynomialGF2n by cloning the given PolynomialGF2n a. * * @param a the PolynomialGF2n to clone */ public GF2nPolynomial(GF2nPolynomial a) { int i; coeff = new GF2nElement[a.size]; size = a.size; for (i = 0; i < size; i++) { coeff[i] = (GF2nElement)a.coeff[i].clone(); } } /** * Creates a new PolynomialGF2n from the given Bitstring polynomial * over the GF2nField B1. * * @param polynomial the Bitstring to use * @param B1 the field */ public GF2nPolynomial(GF2Polynomial polynomial, GF2nField B1) { size = B1.getDegree() + 1; coeff = new GF2nElement[size]; int i; if (B1 instanceof GF2nONBField) { for (i = 0; i < size; i++) { if (polynomial.testBit(i)) { coeff[i] = GF2nONBElement.ONE((GF2nONBField)B1); } else { coeff[i] = GF2nONBElement.ZERO((GF2nONBField)B1); } } } else if (B1 instanceof GF2nPolynomialField) { for (i = 0; i < size; i++) { if (polynomial.testBit(i)) { coeff[i] = GF2nPolynomialElement .ONE((GF2nPolynomialField)B1); } else { coeff[i] = GF2nPolynomialElement .ZERO((GF2nPolynomialField)B1); } } } else { throw new IllegalArgumentException( "PolynomialGF2n(Bitstring, GF2nField): B1 must be " + "an instance of GF2nONBField or GF2nPolynomialField!"); } } public final void assignZeroToElements() { int i; for (i = 0; i < size; i++) { coeff[i].assignZero(); } } /** * Returns the size (=maximum degree + 1) of this PolynomialGF2n. This is * not the degree, use getDegree instead. * * @return the size (=maximum degree + 1) of this PolynomialGF2n. */ public final int size() { return size; } /** * Returns the degree of this PolynomialGF2n. * * @return the degree of this PolynomialGF2n. */ public final int getDegree() { int i; for (i = size - 1; i >= 0; i--) { if (!coeff[i].isZero()) { return i; } } return -1; } /** * Enlarges the size of this PolynomialGF2n to k + 1. * * @param k the new maximum degree */ public final void enlarge(int k) { if (k <= size) { return; } int i; GF2nElement[] res = new GF2nElement[k]; System.arraycopy(coeff, 0, res, 0, size); GF2nField f = coeff[0].getField(); if (coeff[0] instanceof GF2nPolynomialElement) { for (i = size; i < k; i++) { res[i] = GF2nPolynomialElement.ZERO((GF2nPolynomialField)f); } } else if (coeff[0] instanceof GF2nONBElement) { for (i = size; i < k; i++) { res[i] = GF2nONBElement.ZERO((GF2nONBField)f); } } size = k; coeff = res; } public final void shrink() { int i = size - 1; while (coeff[i].isZero() && (i > 0)) { i--; } i++; if (i < size) { GF2nElement[] res = new GF2nElement[i]; System.arraycopy(coeff, 0, res, 0, i); coeff = res; size = i; } } /** * Sets the coefficient at index to elem. * * @param index the index * @param elem the GF2nElement to store as coefficient index */ public final void set(int index, GF2nElement elem) { if (!(elem instanceof GF2nPolynomialElement) && !(elem instanceof GF2nONBElement)) { throw new IllegalArgumentException( "PolynomialGF2n.set f must be an " + "instance of either GF2nPolynomialElement or GF2nONBElement!"); } coeff[index] = (GF2nElement)elem.clone(); } /** * Returns the coefficient at index. * * @param index the index * @return the GF2nElement stored as coefficient index */ public final GF2nElement at(int index) { return coeff[index]; } /** * Returns true if all coefficients equal zero. * * @return true if all coefficients equal zero. */ public final boolean isZero() { int i; for (i = 0; i < size; i++) { if (coeff[i] != null) { if (!coeff[i].isZero()) { return false; } } } return true; } public final boolean equals(Object other) { if (other == null || !(other instanceof GF2nPolynomial)) { return false; } GF2nPolynomial otherPol = (GF2nPolynomial)other; if (getDegree() != otherPol.getDegree()) { return false; } int i; for (i = 0; i < size; i++) { if (!coeff[i].equals(otherPol.coeff[i])) { return false; } } return true; } /** * @return the hash code of this polynomial */ public int hashCode() { return getDegree() + coeff.hashCode(); } /** * Adds the PolynomialGF2n b to this and returns the * result in a new PolynomialGF2n. * * @param b - * the PolynomialGF2n to add * @return this + b * @throws DifferentFieldsException if this and b are not defined over * the same field. */ public final GF2nPolynomial add(GF2nPolynomial b) throws RuntimeException { GF2nPolynomial result; if (size() >= b.size()) { result = new GF2nPolynomial(size()); int i; for (i = 0; i < b.size(); i++) { result.coeff[i] = (GF2nElement)coeff[i].add(b.coeff[i]); } for (; i < size(); i++) { result.coeff[i] = coeff[i]; } } else { result = new GF2nPolynomial(b.size()); int i; for (i = 0; i < size(); i++) { result.coeff[i] = (GF2nElement)coeff[i].add(b.coeff[i]); } for (; i < b.size(); i++) { result.coeff[i] = b.coeff[i]; } } return result; } /** * Multiplies the scalar s to each coefficient of this * PolynomialGF2n and returns the result in a new PolynomialGF2n. * * @param s the scalar to multiply * @return this x s * @throws DifferentFieldsException if this and s are not defined over * the same field. */ public final GF2nPolynomial scalarMultiply(GF2nElement s) throws RuntimeException { GF2nPolynomial result = new GF2nPolynomial(size()); int i; for (i = 0; i < size(); i++) { result.coeff[i] = (GF2nElement)coeff[i].multiply(s); // result[i] // = // a[i]*s } return result; } /** * Multiplies this by b and returns the result in a new * PolynomialGF2n. * * @param b the PolynomialGF2n to multiply * @return this * b * @throws DifferentFieldsException if this and b are not defined over * the same field. */ public final GF2nPolynomial multiply(GF2nPolynomial b) throws RuntimeException { int i, j; int aDegree = size(); int bDegree = b.size(); if (aDegree != bDegree) { throw new IllegalArgumentException( "PolynomialGF2n.multiply: this and b must " + "have the same size!"); } GF2nPolynomial result = new GF2nPolynomial((aDegree << 1) - 1); for (i = 0; i < size(); i++) { for (j = 0; j < b.size(); j++) { if (result.coeff[i + j] == null) { result.coeff[i + j] = (GF2nElement)coeff[i] .multiply(b.coeff[j]); } else { result.coeff[i + j] = (GF2nElement)result.coeff[i + j] .add(coeff[i].multiply(b.coeff[j])); } } } return result; } /** * Multiplies this by b, reduces the result by g and * returns it in a new PolynomialGF2n. * * @param b the PolynomialGF2n to multiply * @param g the modul * @return this * b mod g * @throws DifferentFieldsException if this, b and g are * not all defined over the same field. */ public final GF2nPolynomial multiplyAndReduce(GF2nPolynomial b, GF2nPolynomial g) throws RuntimeException, ArithmeticException { return multiply(b).reduce(g); } /** * Reduces this by g and returns the result in a new * PolynomialGF2n. * * @param g - * the modulus * @return this % g * @throws DifferentFieldsException if this and g are not defined over * the same field. */ public final GF2nPolynomial reduce(GF2nPolynomial g) throws RuntimeException, ArithmeticException { return remainder(g); // return this % g } /** * Shifts left this by amount and stores the result in * this PolynomialGF2n. * * @param amount the amount to shift the coefficients */ public final void shiftThisLeft(int amount) { if (amount > 0) { int i; int oldSize = size; GF2nField f = coeff[0].getField(); enlarge(size + amount); for (i = oldSize - 1; i >= 0; i--) { coeff[i + amount] = coeff[i]; } if (coeff[0] instanceof GF2nPolynomialElement) { for (i = amount - 1; i >= 0; i--) { coeff[i] = GF2nPolynomialElement .ZERO((GF2nPolynomialField)f); } } else if (coeff[0] instanceof GF2nONBElement) { for (i = amount - 1; i >= 0; i--) { coeff[i] = GF2nONBElement.ZERO((GF2nONBField)f); } } } } public final GF2nPolynomial shiftLeft(int amount) { if (amount <= 0) { return new GF2nPolynomial(this); } GF2nPolynomial result = new GF2nPolynomial(size + amount, coeff[0]); result.assignZeroToElements(); for (int i = 0; i < size; i++) { result.coeff[i + amount] = coeff[i]; } return result; } /** * Divides this by b and stores the result in a new * PolynomialGF2n[2], quotient in result[0] and remainder in result[1]. * * @param b the divisor * @return the quotient and remainder of this / b * @throws DifferentFieldsException if this and b are not defined over * the same field. */ public final GF2nPolynomial[] divide(GF2nPolynomial b) throws RuntimeException, ArithmeticException { GF2nPolynomial[] result = new GF2nPolynomial[2]; GF2nPolynomial a = new GF2nPolynomial(this); a.shrink(); GF2nPolynomial shift; GF2nElement factor; int bDegree = b.getDegree(); GF2nElement inv = (GF2nElement)b.coeff[bDegree].invert(); if (a.getDegree() < bDegree) { result[0] = new GF2nPolynomial(this); result[0].assignZeroToElements(); result[0].shrink(); result[1] = new GF2nPolynomial(this); result[1].shrink(); return result; } result[0] = new GF2nPolynomial(this); result[0].assignZeroToElements(); int i = a.getDegree() - bDegree; while (i >= 0) { factor = (GF2nElement)a.coeff[a.getDegree()].multiply(inv); shift = b.scalarMultiply(factor); shift.shiftThisLeft(i); a = a.add(shift); a.shrink(); result[0].coeff[i] = (GF2nElement)factor.clone(); i = a.getDegree() - bDegree; } result[1] = a; result[0].shrink(); return result; } /** * Divides this by b and stores the remainder in a new * PolynomialGF2n. * * @param b the divisor * @return the remainder this % b * @throws DifferentFieldsException if this and b are not defined over * the same field. */ public final GF2nPolynomial remainder(GF2nPolynomial b) throws RuntimeException, ArithmeticException { GF2nPolynomial[] result = new GF2nPolynomial[2]; result = divide(b); return result[1]; } /** * Divides this by b and stores the quotient in a new * PolynomialGF2n. * * @param b the divisor * @return the quotient this / b * @throws DifferentFieldsException if this and b are not defined over * the same field. */ public final GF2nPolynomial quotient(GF2nPolynomial b) throws RuntimeException, ArithmeticException { GF2nPolynomial[] result = new GF2nPolynomial[2]; result = divide(b); return result[0]; } /** * Computes the greatest common divisor of this and g and * returns the result in a new PolynomialGF2n. * * @param g - * a GF2nPolynomial * @return gcd(this, g) * @throws DifferentFieldsException if the coefficients of this and g use * different fields * @throws ArithmeticException if coefficients are zero. */ public final GF2nPolynomial gcd(GF2nPolynomial g) throws RuntimeException, ArithmeticException { GF2nPolynomial a = new GF2nPolynomial(this); GF2nPolynomial b = new GF2nPolynomial(g); a.shrink(); b.shrink(); GF2nPolynomial c; GF2nPolynomial result; GF2nElement alpha; while (!b.isZero()) { c = a.remainder(b); a = b; b = c; } alpha = a.coeff[a.getDegree()]; result = a.scalarMultiply((GF2nElement)alpha.invert()); return result; } } bouncycastle-1.49.orig/src/org/bouncycastle/pqc/math/linearalgebra/GF2Matrix.java0000644000175000017500000010703212043365070027417 0ustar ebourgebourgpackage org.bouncycastle.pqc.math.linearalgebra; import java.security.SecureRandom; /** * This class describes some operations with matrices over finite field GF(2) * and is used in ecc and MQ-PKC (also has some specific methods and * implementation) */ public class GF2Matrix extends Matrix { /** * For the matrix representation the array of type int[][] is used, thus one * element of the array keeps 32 elements of the matrix (from one row and 32 * columns) */ private int[][] matrix; /** * the length of each array representing a row of this matrix, computed as * (numColumns + 31) / 32 */ private int length; /** * Create the matrix from encoded form. * * @param enc the encoded matrix */ public GF2Matrix(byte[] enc) { if (enc.length < 9) { throw new ArithmeticException( "given array is not an encoded matrix over GF(2)"); } numRows = LittleEndianConversions.OS2IP(enc, 0); numColumns = LittleEndianConversions.OS2IP(enc, 4); int n = ((numColumns + 7) >>> 3) * numRows; if ((numRows <= 0) || (n != (enc.length - 8))) { throw new ArithmeticException( "given array is not an encoded matrix over GF(2)"); } length = (numColumns + 31) >>> 5; matrix = new int[numRows][length]; // number of "full" integer int q = numColumns >> 5; // number of bits in non-full integer int r = numColumns & 0x1f; int count = 8; for (int i = 0; i < numRows; i++) { for (int j = 0; j < q; j++, count += 4) { matrix[i][j] = LittleEndianConversions.OS2IP(enc, count); } for (int j = 0; j < r; j += 8) { matrix[i][q] ^= (enc[count++] & 0xff) << j; } } } /** * Create the matrix with the contents of the given array. The matrix is not * copied. Unused coefficients are masked out. * * @param numColumns the number of columns * @param matrix the element array */ public GF2Matrix(int numColumns, int[][] matrix) { if (matrix[0].length != (numColumns + 31) >> 5) { throw new ArithmeticException( "Int array does not match given number of columns."); } this.numColumns = numColumns; numRows = matrix.length; length = matrix[0].length; int rest = numColumns & 0x1f; int bitMask; if (rest == 0) { bitMask = 0xffffffff; } else { bitMask = (1 << rest) - 1; } for (int i = 0; i < numRows; i++) { matrix[i][length - 1] &= bitMask; } this.matrix = matrix; } /** * Create an nxn matrix of the given type. * * @param n the number of rows (and columns) * @param typeOfMatrix the martix type (see {@link Matrix} for predefined * constants) */ public GF2Matrix(int n, char typeOfMatrix) { this(n, typeOfMatrix, new java.security.SecureRandom()); } /** * Create an nxn matrix of the given type. * * @param n the matrix size * @param typeOfMatrix the matrix type * @param sr the source of randomness */ public GF2Matrix(int n, char typeOfMatrix, SecureRandom sr) { if (n <= 0) { throw new ArithmeticException("Size of matrix is non-positive."); } switch (typeOfMatrix) { case Matrix.MATRIX_TYPE_ZERO: assignZeroMatrix(n, n); break; case Matrix.MATRIX_TYPE_UNIT: assignUnitMatrix(n); break; case Matrix.MATRIX_TYPE_RANDOM_LT: assignRandomLowerTriangularMatrix(n, sr); break; case Matrix.MATRIX_TYPE_RANDOM_UT: assignRandomUpperTriangularMatrix(n, sr); break; case Matrix.MATRIX_TYPE_RANDOM_REGULAR: assignRandomRegularMatrix(n, sr); break; default: throw new ArithmeticException("Unknown matrix type."); } } /** * Copy constructor. * * @param a another {@link GF2Matrix} */ public GF2Matrix(GF2Matrix a) { numColumns = a.getNumColumns(); numRows = a.getNumRows(); length = a.length; matrix = new int[a.matrix.length][]; for (int i = 0; i < matrix.length; i++) { matrix[i] = IntUtils.clone(a.matrix[i]); } } /** * create the mxn zero matrix */ private GF2Matrix(int m, int n) { if ((n <= 0) || (m <= 0)) { throw new ArithmeticException("size of matrix is non-positive"); } assignZeroMatrix(m, n); } /** * Create the mxn zero matrix. * * @param m number of rows * @param n number of columns */ private void assignZeroMatrix(int m, int n) { numRows = m; numColumns = n; length = (n + 31) >>> 5; matrix = new int[numRows][length]; for (int i = 0; i < numRows; i++) { for (int j = 0; j < length; j++) { matrix[i][j] = 0; } } } /** * Create the mxn unit matrix. * * @param n number of rows (and columns) */ private void assignUnitMatrix(int n) { numRows = n; numColumns = n; length = (n + 31) >>> 5; matrix = new int[numRows][length]; for (int i = 0; i < numRows; i++) { for (int j = 0; j < length; j++) { matrix[i][j] = 0; } } for (int i = 0; i < numRows; i++) { int rest = i & 0x1f; matrix[i][i >>> 5] = 1 << rest; } } /** * Create a nxn random lower triangular matrix. * * @param n number of rows (and columns) * @param sr source of randomness */ private void assignRandomLowerTriangularMatrix(int n, SecureRandom sr) { numRows = n; numColumns = n; length = (n + 31) >>> 5; matrix = new int[numRows][length]; for (int i = 0; i < numRows; i++) { int q = i >>> 5; int r = i & 0x1f; int s = 31 - r; r = 1 << r; for (int j = 0; j < q; j++) { matrix[i][j] = sr.nextInt(); } matrix[i][q] = (sr.nextInt() >>> s) | r; for (int j = q + 1; j < length; j++) { matrix[i][j] = 0; } } } /** * Create a nxn random upper triangular matrix. * * @param n number of rows (and columns) * @param sr source of randomness */ private void assignRandomUpperTriangularMatrix(int n, SecureRandom sr) { numRows = n; numColumns = n; length = (n + 31) >>> 5; matrix = new int[numRows][length]; int rest = n & 0x1f; int help; if (rest == 0) { help = 0xffffffff; } else { help = (1 << rest) - 1; } for (int i = 0; i < numRows; i++) { int q = i >>> 5; int r = i & 0x1f; int s = r; r = 1 << r; for (int j = 0; j < q; j++) { matrix[i][j] = 0; } matrix[i][q] = (sr.nextInt() << s) | r; for (int j = q + 1; j < length; j++) { matrix[i][j] = sr.nextInt(); } matrix[i][length - 1] &= help; } } /** * Create an nxn random regular matrix. * * @param n number of rows (and columns) * @param sr source of randomness */ private void assignRandomRegularMatrix(int n, SecureRandom sr) { numRows = n; numColumns = n; length = (n + 31) >>> 5; matrix = new int[numRows][length]; GF2Matrix lm = new GF2Matrix(n, Matrix.MATRIX_TYPE_RANDOM_LT, sr); GF2Matrix um = new GF2Matrix(n, Matrix.MATRIX_TYPE_RANDOM_UT, sr); GF2Matrix rm = (GF2Matrix)lm.rightMultiply(um); Permutation perm = new Permutation(n, sr); int[] p = perm.getVector(); for (int i = 0; i < n; i++) { System.arraycopy(rm.matrix[i], 0, matrix[p[i]], 0, length); } } /** * Create a nxn random regular matrix and its inverse. * * @param n number of rows (and columns) * @param sr source of randomness * @return the created random regular matrix and its inverse */ public static GF2Matrix[] createRandomRegularMatrixAndItsInverse(int n, SecureRandom sr) { GF2Matrix[] result = new GF2Matrix[2]; // ------------------------------------ // First part: create regular matrix // ------------------------------------ // ------ int length = (n + 31) >> 5; GF2Matrix lm = new GF2Matrix(n, Matrix.MATRIX_TYPE_RANDOM_LT, sr); GF2Matrix um = new GF2Matrix(n, Matrix.MATRIX_TYPE_RANDOM_UT, sr); GF2Matrix rm = (GF2Matrix)lm.rightMultiply(um); Permutation p = new Permutation(n, sr); int[] pVec = p.getVector(); int[][] matrix = new int[n][length]; for (int i = 0; i < n; i++) { System.arraycopy(rm.matrix[pVec[i]], 0, matrix[i], 0, length); } result[0] = new GF2Matrix(n, matrix); // ------------------------------------ // Second part: create inverse matrix // ------------------------------------ // inverse to lm GF2Matrix invLm = new GF2Matrix(n, Matrix.MATRIX_TYPE_UNIT); for (int i = 0; i < n; i++) { int rest = i & 0x1f; int q = i >>> 5; int r = 1 << rest; for (int j = i + 1; j < n; j++) { int b = (lm.matrix[j][q]) & r; if (b != 0) { for (int k = 0; k <= q; k++) { invLm.matrix[j][k] ^= invLm.matrix[i][k]; } } } } // inverse to um GF2Matrix invUm = new GF2Matrix(n, Matrix.MATRIX_TYPE_UNIT); for (int i = n - 1; i >= 0; i--) { int rest = i & 0x1f; int q = i >>> 5; int r = 1 << rest; for (int j = i - 1; j >= 0; j--) { int b = (um.matrix[j][q]) & r; if (b != 0) { for (int k = q; k < length; k++) { invUm.matrix[j][k] ^= invUm.matrix[i][k]; } } } } // inverse matrix result[1] = (GF2Matrix)invUm.rightMultiply(invLm.rightMultiply(p)); return result; } /** * @return the array keeping the matrix elements */ public int[][] getIntArray() { return matrix; } /** * @return the length of each array representing a row of this matrix */ public int getLength() { return length; } /** * Return the row of this matrix with the given index. * * @param index the index * @return the row of this matrix with the given index */ public int[] getRow(int index) { return matrix[index]; } /** * Returns encoded matrix, i.e., this matrix in byte array form * * @return the encoded matrix */ public byte[] getEncoded() { int n = (numColumns + 7) >>> 3; n *= numRows; n += 8; byte[] enc = new byte[n]; LittleEndianConversions.I2OSP(numRows, enc, 0); LittleEndianConversions.I2OSP(numColumns, enc, 4); // number of "full" integer int q = numColumns >>> 5; // number of bits in non-full integer int r = numColumns & 0x1f; int count = 8; for (int i = 0; i < numRows; i++) { for (int j = 0; j < q; j++, count += 4) { LittleEndianConversions.I2OSP(matrix[i][j], enc, count); } for (int j = 0; j < r; j += 8) { enc[count++] = (byte)((matrix[i][q] >>> j) & 0xff); } } return enc; } /** * Returns the percentage of the number of "ones" in this matrix. * * @return the Hamming weight of this matrix (as a ratio). */ public double getHammingWeight() { double counter = 0.0; double elementCounter = 0.0; int rest = numColumns & 0x1f; int d; if (rest == 0) { d = length; } else { d = length - 1; } for (int i = 0; i < numRows; i++) { for (int j = 0; j < d; j++) { int a = matrix[i][j]; for (int k = 0; k < 32; k++) { int b = (a >>> k) & 1; counter = counter + b; elementCounter = elementCounter + 1; } } int a = matrix[i][length - 1]; for (int k = 0; k < rest; k++) { int b = (a >>> k) & 1; counter = counter + b; elementCounter = elementCounter + 1; } } return counter / elementCounter; } /** * Check if this is the zero matrix (i.e., all entries are zero). * * @return true if this is the zero matrix */ public boolean isZero() { for (int i = 0; i < numRows; i++) { for (int j = 0; j < length; j++) { if (matrix[i][j] != 0) { return false; } } } return true; } /** * Get the quadratic submatrix of this matrix consisting of the leftmost * numRows columns. * * @return the (numRows x numRows) submatrix */ public GF2Matrix getLeftSubMatrix() { if (numColumns <= numRows) { throw new ArithmeticException("empty submatrix"); } int length = (numRows + 31) >> 5; int[][] result = new int[numRows][length]; int bitMask = (1 << (numRows & 0x1f)) - 1; if (bitMask == 0) { bitMask = -1; } for (int i = numRows - 1; i >= 0; i--) { System.arraycopy(matrix[i], 0, result[i], 0, length); result[i][length - 1] &= bitMask; } return new GF2Matrix(numRows, result); } /** * Compute the full form matrix (this | Id) from this matrix in * left compact form, where Id is the k x k identity * matrix and k is the number of rows of this matrix. * * @return (this | Id) */ public GF2Matrix extendLeftCompactForm() { int newNumColumns = numColumns + numRows; GF2Matrix result = new GF2Matrix(numRows, newNumColumns); int ind = numRows - 1 + numColumns; for (int i = numRows - 1; i >= 0; i--, ind--) { // copy this matrix to first columns System.arraycopy(matrix[i], 0, result.matrix[i], 0, length); // store the identity in last columns result.matrix[i][ind >> 5] |= 1 << (ind & 0x1f); } return result; } /** * Get the submatrix of this matrix consisting of the rightmost * numColumns-numRows columns. * * @return the (numRows x (numColumns-numRows)) submatrix */ public GF2Matrix getRightSubMatrix() { if (numColumns <= numRows) { throw new ArithmeticException("empty submatrix"); } int q = numRows >> 5; int r = numRows & 0x1f; GF2Matrix result = new GF2Matrix(numRows, numColumns - numRows); for (int i = numRows - 1; i >= 0; i--) { // if words have to be shifted if (r != 0) { int ind = q; // process all but last word for (int j = 0; j < result.length - 1; j++) { // shift to correct position result.matrix[i][j] = (matrix[i][ind++] >>> r) | (matrix[i][ind] << (32 - r)); } // process last word result.matrix[i][result.length - 1] = matrix[i][ind++] >>> r; if (ind < length) { result.matrix[i][result.length - 1] |= matrix[i][ind] << (32 - r); } } else { // no shifting necessary System.arraycopy(matrix[i], q, result.matrix[i], 0, result.length); } } return result; } /** * Compute the full form matrix (Id | this) from this matrix in * right compact form, where Id is the k x k identity * matrix and k is the number of rows of this matrix. * * @return (Id | this) */ public GF2Matrix extendRightCompactForm() { GF2Matrix result = new GF2Matrix(numRows, numRows + numColumns); int q = numRows >> 5; int r = numRows & 0x1f; for (int i = numRows - 1; i >= 0; i--) { // store the identity in first columns result.matrix[i][i >> 5] |= 1 << (i & 0x1f); // copy this matrix to last columns // if words have to be shifted if (r != 0) { int ind = q; // process all but last word for (int j = 0; j < length - 1; j++) { // obtain matrix word int mw = matrix[i][j]; // shift to correct position result.matrix[i][ind++] |= mw << r; result.matrix[i][ind] |= mw >>> (32 - r); } // process last word int mw = matrix[i][length - 1]; result.matrix[i][ind++] |= mw << r; if (ind < result.length) { result.matrix[i][ind] |= mw >>> (32 - r); } } else { // no shifting necessary System.arraycopy(matrix[i], 0, result.matrix[i], q, length); } } return result; } /** * Compute the transpose of this matrix. * * @return (this)T */ public Matrix computeTranspose() { int[][] result = new int[numColumns][(numRows + 31) >>> 5]; for (int i = 0; i < numRows; i++) { for (int j = 0; j < numColumns; j++) { int qs = j >>> 5; int rs = j & 0x1f; int b = (matrix[i][qs] >>> rs) & 1; int qt = i >>> 5; int rt = i & 0x1f; if (b == 1) { result[j][qt] |= 1 << rt; } } } return new GF2Matrix(numRows, result); } /** * Compute the inverse of this matrix. * * @return the inverse of this matrix (newly created). * @throws ArithmeticException if this matrix is not invertible. */ public Matrix computeInverse() { if (numRows != numColumns) { throw new ArithmeticException("Matrix is not invertible."); } // clone this matrix int[][] tmpMatrix = new int[numRows][length]; for (int i = numRows - 1; i >= 0; i--) { tmpMatrix[i] = IntUtils.clone(matrix[i]); } // initialize inverse matrix as unit matrix int[][] invMatrix = new int[numRows][length]; for (int i = numRows - 1; i >= 0; i--) { int q = i >> 5; int r = i & 0x1f; invMatrix[i][q] = 1 << r; } // simultaneously compute Gaussian reduction of tmpMatrix and unit // matrix for (int i = 0; i < numRows; i++) { // i = q * 32 + (i mod 32) int q = i >> 5; int bitMask = 1 << (i & 0x1f); // if diagonal element is zero if ((tmpMatrix[i][q] & bitMask) == 0) { boolean foundNonZero = false; // find a non-zero element in the same column for (int j = i + 1; j < numRows; j++) { if ((tmpMatrix[j][q] & bitMask) != 0) { // found it, swap rows ... foundNonZero = true; swapRows(tmpMatrix, i, j); swapRows(invMatrix, i, j); // ... and quit searching j = numRows; continue; } } // if no non-zero element was found ... if (!foundNonZero) { // ... the matrix is not invertible throw new ArithmeticException("Matrix is not invertible."); } } // normalize all but i-th row for (int j = numRows - 1; j >= 0; j--) { if ((j != i) && ((tmpMatrix[j][q] & bitMask) != 0)) { addToRow(tmpMatrix[i], tmpMatrix[j], q); addToRow(invMatrix[i], invMatrix[j], 0); } } } return new GF2Matrix(numColumns, invMatrix); } /** * Compute the product of a permutation matrix (which is generated from an * n-permutation) and this matrix. * * @param p the permutation * @return {@link GF2Matrix} P*this */ public Matrix leftMultiply(Permutation p) { int[] pVec = p.getVector(); if (pVec.length != numRows) { throw new ArithmeticException("length mismatch"); } int[][] result = new int[numRows][]; for (int i = numRows - 1; i >= 0; i--) { result[i] = IntUtils.clone(matrix[pVec[i]]); } return new GF2Matrix(numRows, result); } /** * compute product a row vector and this matrix * * @param vec a vector over GF(2) * @return Vector product a*matrix */ public Vector leftMultiply(Vector vec) { if (!(vec instanceof GF2Vector)) { throw new ArithmeticException("vector is not defined over GF(2)"); } if (vec.length != numRows) { throw new ArithmeticException("length mismatch"); } int[] v = ((GF2Vector)vec).getVecArray(); int[] res = new int[length]; int q = numRows >> 5; int r = 1 << (numRows & 0x1f); // compute scalar products with full words of vector int row = 0; for (int i = 0; i < q; i++) { int bitMask = 1; do { int b = v[i] & bitMask; if (b != 0) { for (int j = 0; j < length; j++) { res[j] ^= matrix[row][j]; } } row++; bitMask <<= 1; } while (bitMask != 0); } // compute scalar products with last word of vector int bitMask = 1; while (bitMask != r) { int b = v[q] & bitMask; if (b != 0) { for (int j = 0; j < length; j++) { res[j] ^= matrix[row][j]; } } row++; bitMask <<= 1; } return new GF2Vector(res, numColumns); } /** * Compute the product of the matrix (this | Id) and a column * vector, where Id is a (numRows x numRows) unit * matrix. * * @param vec the vector over GF(2) * @return (this | Id)*vector */ public Vector leftMultiplyLeftCompactForm(Vector vec) { if (!(vec instanceof GF2Vector)) { throw new ArithmeticException("vector is not defined over GF(2)"); } if (vec.length != numRows) { throw new ArithmeticException("length mismatch"); } int[] v = ((GF2Vector)vec).getVecArray(); int[] res = new int[(numRows + numColumns + 31) >>> 5]; // process full words of vector int words = numRows >>> 5; int row = 0; for (int i = 0; i < words; i++) { int bitMask = 1; do { int b = v[i] & bitMask; if (b != 0) { // compute scalar product part for (int j = 0; j < length; j++) { res[j] ^= matrix[row][j]; } // set last bit int q = (numColumns + row) >>> 5; int r = (numColumns + row) & 0x1f; res[q] |= 1 << r; } row++; bitMask <<= 1; } while (bitMask != 0); } // process last word of vector int rem = 1 << (numRows & 0x1f); int bitMask = 1; while (bitMask != rem) { int b = v[words] & bitMask; if (b != 0) { // compute scalar product part for (int j = 0; j < length; j++) { res[j] ^= matrix[row][j]; } // set last bit int q = (numColumns + row) >>> 5; int r = (numColumns + row) & 0x1f; res[q] |= 1 << r; } row++; bitMask <<= 1; } return new GF2Vector(res, numRows + numColumns); } /** * Compute the product of this matrix and a matrix A over GF(2). * * @param mat a matrix A over GF(2) * @return matrix product this*matrixA */ public Matrix rightMultiply(Matrix mat) { if (!(mat instanceof GF2Matrix)) { throw new ArithmeticException("matrix is not defined over GF(2)"); } if (mat.numRows != numColumns) { throw new ArithmeticException("length mismatch"); } GF2Matrix a = (GF2Matrix)mat; GF2Matrix result = new GF2Matrix(numRows, mat.numColumns); int d; int rest = numColumns & 0x1f; if (rest == 0) { d = length; } else { d = length - 1; } for (int i = 0; i < numRows; i++) { int count = 0; for (int j = 0; j < d; j++) { int e = matrix[i][j]; for (int h = 0; h < 32; h++) { int b = e & (1 << h); if (b != 0) { for (int g = 0; g < a.length; g++) { result.matrix[i][g] ^= a.matrix[count][g]; } } count++; } } int e = matrix[i][length - 1]; for (int h = 0; h < rest; h++) { int b = e & (1 << h); if (b != 0) { for (int g = 0; g < a.length; g++) { result.matrix[i][g] ^= a.matrix[count][g]; } } count++; } } return result; } /** * Compute the product of this matrix and a permutation matrix which is * generated from an n-permutation. * * @param p the permutation * @return {@link GF2Matrix} this*P */ public Matrix rightMultiply(Permutation p) { int[] pVec = p.getVector(); if (pVec.length != numColumns) { throw new ArithmeticException("length mismatch"); } GF2Matrix result = new GF2Matrix(numRows, numColumns); for (int i = numColumns - 1; i >= 0; i--) { int q = i >>> 5; int r = i & 0x1f; int pq = pVec[i] >>> 5; int pr = pVec[i] & 0x1f; for (int j = numRows - 1; j >= 0; j--) { result.matrix[j][q] |= ((matrix[j][pq] >>> pr) & 1) << r; } } return result; } /** * Compute the product of this matrix and the given column vector. * * @param vec the vector over GF(2) * @return this*vector */ public Vector rightMultiply(Vector vec) { if (!(vec instanceof GF2Vector)) { throw new ArithmeticException("vector is not defined over GF(2)"); } if (vec.length != numColumns) { throw new ArithmeticException("length mismatch"); } int[] v = ((GF2Vector)vec).getVecArray(); int[] res = new int[(numRows + 31) >>> 5]; for (int i = 0; i < numRows; i++) { // compute full word scalar products int help = 0; for (int j = 0; j < length; j++) { help ^= matrix[i][j] & v[j]; } // compute single word scalar product int bitValue = 0; for (int j = 0; j < 32; j++) { bitValue ^= (help >>> j) & 1; } // set result bit if (bitValue == 1) { res[i >>> 5] |= 1 << (i & 0x1f); } } return new GF2Vector(res, numRows); } /** * Compute the product of the matrix (Id | this) and a column * vector, where Id is a (numRows x numRows) unit * matrix. * * @param vec the vector over GF(2) * @return (Id | this)*vector */ public Vector rightMultiplyRightCompactForm(Vector vec) { if (!(vec instanceof GF2Vector)) { throw new ArithmeticException("vector is not defined over GF(2)"); } if (vec.length != numColumns + numRows) { throw new ArithmeticException("length mismatch"); } int[] v = ((GF2Vector)vec).getVecArray(); int[] res = new int[(numRows + 31) >>> 5]; int q = numRows >> 5; int r = numRows & 0x1f; // for all rows for (int i = 0; i < numRows; i++) { // get vector bit int help = (v[i >> 5] >>> (i & 0x1f)) & 1; // compute full word scalar products int vInd = q; // if words have to be shifted if (r != 0) { int vw = 0; // process all but last word for (int j = 0; j < length - 1; j++) { // shift to correct position vw = (v[vInd++] >>> r) | (v[vInd] << (32 - r)); help ^= matrix[i][j] & vw; } // process last word vw = v[vInd++] >>> r; if (vInd < v.length) { vw |= v[vInd] << (32 - r); } help ^= matrix[i][length - 1] & vw; } else { // no shifting necessary for (int j = 0; j < length; j++) { help ^= matrix[i][j] & v[vInd++]; } } // compute single word scalar product int bitValue = 0; for (int j = 0; j < 32; j++) { bitValue ^= help & 1; help >>>= 1; } // set result bit if (bitValue == 1) { res[i >> 5] |= 1 << (i & 0x1f); } } return new GF2Vector(res, numRows); } /** * Compare this matrix with another object. * * @param other another object * @return the result of the comparison */ public boolean equals(Object other) { if (!(other instanceof GF2Matrix)) { return false; } GF2Matrix otherMatrix = (GF2Matrix)other; if ((numRows != otherMatrix.numRows) || (numColumns != otherMatrix.numColumns) || (length != otherMatrix.length)) { return false; } for (int i = 0; i < numRows; i++) { if (!IntUtils.equals(matrix[i], otherMatrix.matrix[i])) { return false; } } return true; } /** * @return the hash code of this matrix */ public int hashCode() { int hash = (numRows * 31 + numColumns) * 31 + length; for (int i = 0; i < numRows; i++) { hash = hash * 31 + matrix[i].hashCode(); } return hash; } /** * @return a human readable form of the matrix */ public String toString() { int rest = numColumns & 0x1f; int d; if (rest == 0) { d = length; } else { d = length - 1; } StringBuffer buf = new StringBuffer(); for (int i = 0; i < numRows; i++) { buf.append(i + ": "); for (int j = 0; j < d; j++) { int a = matrix[i][j]; for (int k = 0; k < 32; k++) { int b = (a >>> k) & 1; if (b == 0) { buf.append('0'); } else { buf.append('1'); } } buf.append(' '); } int a = matrix[i][length - 1]; for (int k = 0; k < rest; k++) { int b = (a >>> k) & 1; if (b == 0) { buf.append('0'); } else { buf.append('1'); } } buf.append('\n'); } return buf.toString(); } /** * Swap two rows of the given matrix. * * @param matrix the matrix * @param first the index of the first row * @param second the index of the second row */ private static void swapRows(int[][] matrix, int first, int second) { int[] tmp = matrix[first]; matrix[first] = matrix[second]; matrix[second] = tmp; } /** * Partially add one row to another. * * @param fromRow the addend * @param toRow the row to add to * @param startIndex the array index to start from */ private static void addToRow(int[] fromRow, int[] toRow, int startIndex) { for (int i = toRow.length - 1; i >= startIndex; i--) { toRow[i] = fromRow[i] ^ toRow[i]; } } } bouncycastle-1.49.orig/src/org/bouncycastle/pqc/math/linearalgebra/GF2nONBElement.java0000644000175000017500000010012212043365070030252 0ustar ebourgebourgpackage org.bouncycastle.pqc.math.linearalgebra; import java.math.BigInteger; import java.util.Random; /** * This class implements an element of the finite field GF(2n ). * It is represented in an optimal normal basis representation and holds the * pointer mField to its corresponding field. * * @see GF2nField * @see GF2nElement */ public class GF2nONBElement extends GF2nElement { // ///////////////////////////////////////////////////////////////////// // member variables // ///////////////////////////////////////////////////////////////////// private static final long[] mBitmask = new long[]{0x0000000000000001L, 0x0000000000000002L, 0x0000000000000004L, 0x0000000000000008L, 0x0000000000000010L, 0x0000000000000020L, 0x0000000000000040L, 0x0000000000000080L, 0x0000000000000100L, 0x0000000000000200L, 0x0000000000000400L, 0x0000000000000800L, 0x0000000000001000L, 0x0000000000002000L, 0x0000000000004000L, 0x0000000000008000L, 0x0000000000010000L, 0x0000000000020000L, 0x0000000000040000L, 0x0000000000080000L, 0x0000000000100000L, 0x0000000000200000L, 0x0000000000400000L, 0x0000000000800000L, 0x0000000001000000L, 0x0000000002000000L, 0x0000000004000000L, 0x0000000008000000L, 0x0000000010000000L, 0x0000000020000000L, 0x0000000040000000L, 0x0000000080000000L, 0x0000000100000000L, 0x0000000200000000L, 0x0000000400000000L, 0x0000000800000000L, 0x0000001000000000L, 0x0000002000000000L, 0x0000004000000000L, 0x0000008000000000L, 0x0000010000000000L, 0x0000020000000000L, 0x0000040000000000L, 0x0000080000000000L, 0x0000100000000000L, 0x0000200000000000L, 0x0000400000000000L, 0x0000800000000000L, 0x0001000000000000L, 0x0002000000000000L, 0x0004000000000000L, 0x0008000000000000L, 0x0010000000000000L, 0x0020000000000000L, 0x0040000000000000L, 0x0080000000000000L, 0x0100000000000000L, 0x0200000000000000L, 0x0400000000000000L, 0x0800000000000000L, 0x1000000000000000L, 0x2000000000000000L, 0x4000000000000000L, 0x8000000000000000L}; private static final long[] mMaxmask = new long[]{0x0000000000000001L, 0x0000000000000003L, 0x0000000000000007L, 0x000000000000000FL, 0x000000000000001FL, 0x000000000000003FL, 0x000000000000007FL, 0x00000000000000FFL, 0x00000000000001FFL, 0x00000000000003FFL, 0x00000000000007FFL, 0x0000000000000FFFL, 0x0000000000001FFFL, 0x0000000000003FFFL, 0x0000000000007FFFL, 0x000000000000FFFFL, 0x000000000001FFFFL, 0x000000000003FFFFL, 0x000000000007FFFFL, 0x00000000000FFFFFL, 0x00000000001FFFFFL, 0x00000000003FFFFFL, 0x00000000007FFFFFL, 0x0000000000FFFFFFL, 0x0000000001FFFFFFL, 0x0000000003FFFFFFL, 0x0000000007FFFFFFL, 0x000000000FFFFFFFL, 0x000000001FFFFFFFL, 0x000000003FFFFFFFL, 0x000000007FFFFFFFL, 0x00000000FFFFFFFFL, 0x00000001FFFFFFFFL, 0x00000003FFFFFFFFL, 0x00000007FFFFFFFFL, 0x0000000FFFFFFFFFL, 0x0000001FFFFFFFFFL, 0x0000003FFFFFFFFFL, 0x0000007FFFFFFFFFL, 0x000000FFFFFFFFFFL, 0x000001FFFFFFFFFFL, 0x000003FFFFFFFFFFL, 0x000007FFFFFFFFFFL, 0x00000FFFFFFFFFFFL, 0x00001FFFFFFFFFFFL, 0x00003FFFFFFFFFFFL, 0x00007FFFFFFFFFFFL, 0x0000FFFFFFFFFFFFL, 0x0001FFFFFFFFFFFFL, 0x0003FFFFFFFFFFFFL, 0x0007FFFFFFFFFFFFL, 0x000FFFFFFFFFFFFFL, 0x001FFFFFFFFFFFFFL, 0x003FFFFFFFFFFFFFL, 0x007FFFFFFFFFFFFFL, 0x00FFFFFFFFFFFFFFL, 0x01FFFFFFFFFFFFFFL, 0x03FFFFFFFFFFFFFFL, 0x07FFFFFFFFFFFFFFL, 0x0FFFFFFFFFFFFFFFL, 0x1FFFFFFFFFFFFFFFL, 0x3FFFFFFFFFFFFFFFL, 0x7FFFFFFFFFFFFFFFL, 0xFFFFFFFFFFFFFFFFL}; // mIBy64[j * 16 + i] = (j * 16 + i)/64 // i = // 0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 // private static final int[] mIBY64 = new int[]{ // j = 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // 0 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // 1 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // 2 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // 3 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, // 4 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, // 5 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, // 6 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, // 7 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, // 8 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, // 9 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, // 10 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, // 11 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, // 12 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, // 13 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, // 14 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, // 15 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, // 16 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, // 17 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, // 18 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, // 19 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, // 20 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, // 21 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, // 22 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5 // 23 }; private static final int MAXLONG = 64; /** * holds the lenght of the polynomial with 64 bit sized fields. */ private int mLength; /** * holds the value of mDeg % MAXLONG. */ private int mBit; /** * holds this element in ONB representation. */ private long[] mPol; // ///////////////////////////////////////////////////////////////////// // constructors // ///////////////////////////////////////////////////////////////////// /** * Construct a random element over the field gf2n, using the * specified source of randomness. * * @param gf2n the field * @param rand the source of randomness */ public GF2nONBElement(GF2nONBField gf2n, Random rand) { mField = gf2n; mDegree = mField.getDegree(); mLength = gf2n.getONBLength(); mBit = gf2n.getONBBit(); mPol = new long[mLength]; if (mLength > 1) { for (int j = 0; j < mLength - 1; j++) { mPol[j] = rand.nextLong(); } long last = rand.nextLong(); mPol[mLength - 1] = last >>> (MAXLONG - mBit); } else { mPol[0] = rand.nextLong(); mPol[0] = mPol[0] >>> (MAXLONG - mBit); } } /** * Construct a new GF2nONBElement from its encoding. * * @param gf2n the field * @param e the encoded element */ public GF2nONBElement(GF2nONBField gf2n, byte[] e) { mField = gf2n; mDegree = mField.getDegree(); mLength = gf2n.getONBLength(); mBit = gf2n.getONBBit(); mPol = new long[mLength]; assign(e); } /** * Construct the element of the field gf2n with the specified * value val. * * @param gf2n the field * @param val the value represented by a BigInteger */ public GF2nONBElement(GF2nONBField gf2n, BigInteger val) { mField = gf2n; mDegree = mField.getDegree(); mLength = gf2n.getONBLength(); mBit = gf2n.getONBBit(); mPol = new long[mLength]; assign(val); } /** * Construct the element of the field gf2n with the specified * value val. * * @param gf2n the field * @param val the value in ONB representation */ private GF2nONBElement(GF2nONBField gf2n, long[] val) { mField = gf2n; mDegree = mField.getDegree(); mLength = gf2n.getONBLength(); mBit = gf2n.getONBBit(); mPol = val; } // ///////////////////////////////////////////////////////////////////// // pseudo-constructors // ///////////////////////////////////////////////////////////////////// /** * Copy constructor. * * @param gf2n the field */ public GF2nONBElement(GF2nONBElement gf2n) { mField = gf2n.mField; mDegree = mField.getDegree(); mLength = ((GF2nONBField)mField).getONBLength(); mBit = ((GF2nONBField)mField).getONBBit(); mPol = new long[mLength]; assign(gf2n.getElement()); } /** * Create a new GF2nONBElement by cloning this GF2nPolynomialElement. * * @return a copy of this element */ public Object clone() { return new GF2nONBElement(this); } /** * Create the zero element. * * @param gf2n the finite field * @return the zero element in the given finite field */ public static GF2nONBElement ZERO(GF2nONBField gf2n) { long[] polynomial = new long[gf2n.getONBLength()]; return new GF2nONBElement(gf2n, polynomial); } /** * Create the one element. * * @param gf2n the finite field * @return the one element in the given finite field */ public static GF2nONBElement ONE(GF2nONBField gf2n) { int mLength = gf2n.getONBLength(); long[] polynomial = new long[mLength]; // fill mDegree coefficients with one's for (int i = 0; i < mLength - 1; i++) { polynomial[i] = 0xffffffffffffffffL; } polynomial[mLength - 1] = mMaxmask[gf2n.getONBBit() - 1]; return new GF2nONBElement(gf2n, polynomial); } // ///////////////////////////////////////////////////////////////////// // assignments // ///////////////////////////////////////////////////////////////////// /** * assigns to this element the zero element */ void assignZero() { mPol = new long[mLength]; } /** * assigns to this element the one element */ void assignOne() { // fill mDegree coefficients with one's for (int i = 0; i < mLength - 1; i++) { mPol[i] = 0xffffffffffffffffL; } mPol[mLength - 1] = mMaxmask[mBit - 1]; } /** * assigns to this element the value val. * * @param val the value represented by a BigInteger */ private void assign(BigInteger val) { assign(val.toByteArray()); } /** * assigns to this element the value val. * * @param val the value in ONB representation */ private void assign(long[] val) { System.arraycopy(val, 0, mPol, 0, mLength); } /** * assigns to this element the value val. First: inverting the * order of val into reversed[]. That means: reversed[0] = val[length - 1], * ..., reversed[reversed.length - 1] = val[0]. Second: mPol[0] = sum{i = 0, * ... 7} (val[i]<<(i*8)) .... mPol[1] = sum{i = 8, ... 15} (val[i]<<(i*8)) * * @param val the value in ONB representation */ private void assign(byte[] val) { int j; mPol = new long[mLength]; for (j = 0; j < val.length; j++) { mPol[j >>> 3] |= (val[val.length - 1 - j] & 0x00000000000000ffL) << ((j & 0x07) << 3); } } // ///////////////////////////////////////////////////////////////// // comparison // ///////////////////////////////////////////////////////////////// /** * Checks whether this element is zero. * * @return true if this is the zero element */ public boolean isZero() { boolean result = true; for (int i = 0; i < mLength && result; i++) { result = result && ((mPol[i] & 0xFFFFFFFFFFFFFFFFL) == 0); } return result; } /** * Checks whether this element is one. * * @return true if this is the one element */ public boolean isOne() { boolean result = true; for (int i = 0; i < mLength - 1 && result; i++) { result = result && ((mPol[i] & 0xFFFFFFFFFFFFFFFFL) == 0xFFFFFFFFFFFFFFFFL); } if (result) { result = result && ((mPol[mLength - 1] & mMaxmask[mBit - 1]) == mMaxmask[mBit - 1]); } return result; } /** * Compare this element with another object. * * @param other the other object * @return true if the two objects are equal, false * otherwise */ public boolean equals(Object other) { if (other == null || !(other instanceof GF2nONBElement)) { return false; } GF2nONBElement otherElem = (GF2nONBElement)other; for (int i = 0; i < mLength; i++) { if (mPol[i] != otherElem.mPol[i]) { return false; } } return true; } /** * @return the hash code of this element */ public int hashCode() { return mPol.hashCode(); } // ///////////////////////////////////////////////////////////////////// // access // ///////////////////////////////////////////////////////////////////// /** * Returns whether the highest bit of the bit representation is set * * @return true, if the highest bit of mPol is set, false, otherwise */ public boolean testRightmostBit() { // due to the reverse bit order (compared to 1363) this method returns // the value of the leftmost bit return (mPol[mLength - 1] & mBitmask[mBit - 1]) != 0L; } /** * Checks whether the indexed bit of the bit representation is set. Warning: * GF2nONBElement currently stores its bits in reverse order (compared to * 1363) !!! * * @param index the index of the bit to test * @return true if the indexed bit of mPol is set, false * otherwise. */ boolean testBit(int index) { if (index < 0 || index > mDegree) { return false; } long test = mPol[index >>> 6] & mBitmask[index & 0x3f]; return test != 0x0L; } /** * @return this element in its ONB representation */ private long[] getElement() { long[] result = new long[mPol.length]; System.arraycopy(mPol, 0, result, 0, mPol.length); return result; } /** * Returns the ONB representation of this element. The Bit-Order is * exchanged (according to 1363)! * * @return this element in its representation and reverse bit-order */ private long[] getElementReverseOrder() { long[] result = new long[mPol.length]; for (int i = 0; i < mDegree; i++) { if (testBit(mDegree - i - 1)) { result[i >>> 6] |= mBitmask[i & 0x3f]; } } return result; } /** * Reverses the bit-order in this element(according to 1363). This is a * hack! */ void reverseOrder() { mPol = getElementReverseOrder(); } // ///////////////////////////////////////////////////////////////////// // arithmetic // ///////////////////////////////////////////////////////////////////// /** * Compute the sum of this element and addend. * * @param addend the addend * @return this + other (newly created) * @throws DifferentFieldsException if the elements are of different fields. */ public GFElement add(GFElement addend) throws RuntimeException { GF2nONBElement result = new GF2nONBElement(this); result.addToThis(addend); return result; } /** * Compute this + addend (overwrite this). * * @param addend the addend * @throws DifferentFieldsException if the elements are of different fields. */ public void addToThis(GFElement addend) throws RuntimeException { if (!(addend instanceof GF2nONBElement)) { throw new RuntimeException(); } if (!mField.equals(((GF2nONBElement)addend).mField)) { throw new RuntimeException(); } for (int i = 0; i < mLength; i++) { mPol[i] ^= ((GF2nONBElement)addend).mPol[i]; } } /** * returns this element + 1. * * @return this + 1 */ public GF2nElement increase() { GF2nONBElement result = new GF2nONBElement(this); result.increaseThis(); return result; } /** * increases this element. */ public void increaseThis() { addToThis(ONE((GF2nONBField)mField)); } /** * Compute the product of this element and factor. * * @param factor the factor * @return this * factor (newly created) * @throws DifferentFieldsException if the elements are of different fields. */ public GFElement multiply(GFElement factor) throws RuntimeException { GF2nONBElement result = new GF2nONBElement(this); result.multiplyThisBy(factor); return result; } /** * Compute this * factor (overwrite this). * * @param factor the factor * @throws DifferentFieldsException if the elements are of different fields. */ public void multiplyThisBy(GFElement factor) throws RuntimeException { if (!(factor instanceof GF2nONBElement)) { throw new RuntimeException("The elements have different" + " representation: not yet" + " implemented"); } if (!mField.equals(((GF2nONBElement)factor).mField)) { throw new RuntimeException(); } if (equals(factor)) { squareThis(); } else { long[] a = mPol; long[] b = ((GF2nONBElement)factor).mPol; long[] c = new long[mLength]; int[][] m = ((GF2nONBField)mField).mMult; int degf, degb, s, fielda, fieldb, bita, bitb; degf = mLength - 1; degb = mBit - 1; s = 0; long TWOTOMAXLONGM1 = mBitmask[MAXLONG - 1]; long TWOTODEGB = mBitmask[degb]; boolean old, now; // the product c of a and b (a*b = c) is calculated in mDegree // cicles // in every cicle one coefficient of c is calculated and stored // k indicates the coefficient // for (int k = 0; k < mDegree; k++) { s = 0; for (int i = 0; i < mDegree; i++) { // fielda = i / MAXLONG // fielda = mIBY64[i]; // bita = i % MAXLONG // bita = i & (MAXLONG - 1); // fieldb = m[i][0] / MAXLONG // fieldb = mIBY64[m[i][0]]; // bitb = m[i][0] % MAXLONG // bitb = m[i][0] & (MAXLONG - 1); if ((a[fielda] & mBitmask[bita]) != 0) { if ((b[fieldb] & mBitmask[bitb]) != 0) { s ^= 1; } if (m[i][1] != -1) { // fieldb = m[i][1] / MAXLONG // fieldb = mIBY64[m[i][1]]; // bitb = m[i][1] % MAXLONG // bitb = m[i][1] & (MAXLONG - 1); if ((b[fieldb] & mBitmask[bitb]) != 0) { s ^= 1; } } } } fielda = mIBY64[k]; bita = k & (MAXLONG - 1); if (s != 0) { c[fielda] ^= mBitmask[bita]; } // Circular shift of x and y one bit to the right, // respectively. if (mLength > 1) { // Shift x. // old = (a[degf] & 1) == 1; for (int i = degf - 1; i >= 0; i--) { now = (a[i] & 1) != 0; a[i] = a[i] >>> 1; if (old) { a[i] ^= TWOTOMAXLONGM1; } old = now; } a[degf] = a[degf] >>> 1; if (old) { a[degf] ^= TWOTODEGB; } // Shift y. // old = (b[degf] & 1) == 1; for (int i = degf - 1; i >= 0; i--) { now = (b[i] & 1) != 0; b[i] = b[i] >>> 1; if (old) { b[i] ^= TWOTOMAXLONGM1; } old = now; } b[degf] = b[degf] >>> 1; if (old) { b[degf] ^= TWOTODEGB; } } else { old = (a[0] & 1) == 1; a[0] = a[0] >>> 1; if (old) { a[0] ^= TWOTODEGB; } old = (b[0] & 1) == 1; b[0] = b[0] >>> 1; if (old) { b[0] ^= TWOTODEGB; } } } assign(c); } } /** * returns this element to the power of 2. * * @return this2 */ public GF2nElement square() { GF2nONBElement result = new GF2nONBElement(this); result.squareThis(); return result; } /** * squares this element. */ public void squareThis() { long[] pol = getElement(); int f = mLength - 1; int b = mBit - 1; // Shift the coefficients one bit to the left. // long TWOTOMAXLONGM1 = mBitmask[MAXLONG - 1]; boolean old, now; old = (pol[f] & mBitmask[b]) != 0; for (int i = 0; i < f; i++) { now = (pol[i] & TWOTOMAXLONGM1) != 0; pol[i] = pol[i] << 1; if (old) { pol[i] ^= 1; } old = now; } now = (pol[f] & mBitmask[b]) != 0; pol[f] = pol[f] << 1; if (old) { pol[f] ^= 1; } // Set the bit with index mDegree to zero. // if (now) { pol[f] ^= mBitmask[b + 1]; } assign(pol); } /** * Compute the multiplicative inverse of this element. * * @return this-1 (newly created) * @throws ArithmeticException if this is the zero element. */ public GFElement invert() throws ArithmeticException { GF2nONBElement result = new GF2nONBElement(this); result.invertThis(); return result; } /** * Multiplicatively invert of this element (overwrite this). * * @throws ArithmeticException if this is the zero element. */ public void invertThis() throws ArithmeticException { if (isZero()) { throw new ArithmeticException(); } int r = 31; // mDegree kann nur 31 Bits lang sein!!! // Bitlaenge von mDegree: for (boolean found = false; !found && r >= 0; r--) { if (((mDegree - 1) & mBitmask[r]) != 0) { found = true; } } r++; GF2nElement m = ZERO((GF2nONBField)mField); GF2nElement n = new GF2nONBElement(this); int k = 1; for (int i = r - 1; i >= 0; i--) { m = (GF2nElement)n.clone(); for (int j = 1; j <= k; j++) { m.squareThis(); } n.multiplyThisBy(m); k <<= 1; if (((mDegree - 1) & mBitmask[i]) != 0) { n.squareThis(); n.multiplyThisBy(this); k++; } } n.squareThis(); } /** * returns the root ofthis element. * * @return this1/2 */ public GF2nElement squareRoot() { GF2nONBElement result = new GF2nONBElement(this); result.squareRootThis(); return result; } /** * square roots this element. */ public void squareRootThis() { long[] pol = getElement(); int f = mLength - 1; int b = mBit - 1; // Shift the coefficients one bit to the right. // long TWOTOMAXLONGM1 = mBitmask[MAXLONG - 1]; boolean old, now; old = (pol[0] & 1) != 0; for (int i = f; i >= 0; i--) { now = (pol[i] & 1) != 0; pol[i] = pol[i] >>> 1; if (old) { if (i == f) { pol[i] ^= mBitmask[b]; } else { pol[i] ^= TWOTOMAXLONGM1; } } old = now; } assign(pol); } /** * Returns the trace of this element. * * @return the trace of this element */ public int trace() { // trace = sum of coefficients // int result = 0; int max = mLength - 1; for (int i = 0; i < max; i++) { for (int j = 0; j < MAXLONG; j++) { if ((mPol[i] & mBitmask[j]) != 0) { result ^= 1; } } } int b = mBit; for (int j = 0; j < b; j++) { if ((mPol[max] & mBitmask[j]) != 0) { result ^= 1; } } return result; } /** * Solves a quadratic equation.
    * Let z2 + z = this. Then this method returns z. * * @return z with z2 + z = this * @throws NoSolutionException if z2 + z = this does not have a * solution */ public GF2nElement solveQuadraticEquation() throws RuntimeException { if (trace() == 1) { throw new RuntimeException(); } long TWOTOMAXLONGM1 = mBitmask[MAXLONG - 1]; long ZERO = 0L; long ONE = 1L; long[] p = new long[mLength]; long z = 0L; int j = 1; for (int i = 0; i < mLength - 1; i++) { for (j = 1; j < MAXLONG; j++) { // if (!((((mBitmask[j] & mPol[i]) != ZERO) && ((z & mBitmask[j - 1]) != ZERO)) || (((mPol[i] & mBitmask[j]) == ZERO) && ((z & mBitmask[j - 1]) == ZERO)))) { z ^= mBitmask[j]; } } p[i] = z; if (((TWOTOMAXLONGM1 & z) != ZERO && (ONE & mPol[i + 1]) == ONE) || ((TWOTOMAXLONGM1 & z) == ZERO && (ONE & mPol[i + 1]) == ZERO)) { z = ZERO; } else { z = ONE; } } int b = mDegree & (MAXLONG - 1); long LASTLONG = mPol[mLength - 1]; for (j = 1; j < b; j++) { if (!((((mBitmask[j] & LASTLONG) != ZERO) && ((mBitmask[j - 1] & z) != ZERO)) || (((mBitmask[j] & LASTLONG) == ZERO) && ((mBitmask[j - 1] & z) == ZERO)))) { z ^= mBitmask[j]; } } p[mLength - 1] = z; return new GF2nONBElement((GF2nONBField)mField, p); } // ///////////////////////////////////////////////////////////////// // conversion // ///////////////////////////////////////////////////////////////// /** * Returns a String representation of this element. * * @return String representation of this element with the specified radix */ public String toString() { return toString(16); } /** * Returns a String representation of this element. radix * specifies the radix of the String representation.
    * NOTE: ONLY radix = 2 or radix = 16 IS IMPLEMENTED> * * @param radix specifies the radix of the String representation * @return String representation of this element with the specified radix */ public String toString(int radix) { String s = ""; long[] a = getElement(); int b = mBit; if (radix == 2) { for (int j = b - 1; j >= 0; j--) { if ((a[a.length - 1] & ((long)1 << j)) == 0) { s += "0"; } else { s += "1"; } } for (int i = a.length - 2; i >= 0; i--) { for (int j = MAXLONG - 1; j >= 0; j--) { if ((a[i] & mBitmask[j]) == 0) { s += "0"; } else { s += "1"; } } } } else if (radix == 16) { final char[] HEX_CHARS = {'0', '1', '2', '3', '4', '5', '6', '7', '8', '9', 'a', 'b', 'c', 'd', 'e', 'f'}; for (int i = a.length - 1; i >= 0; i--) { s += HEX_CHARS[(int)(a[i] >>> 60) & 0x0f]; s += HEX_CHARS[(int)(a[i] >>> 56) & 0x0f]; s += HEX_CHARS[(int)(a[i] >>> 52) & 0x0f]; s += HEX_CHARS[(int)(a[i] >>> 48) & 0x0f]; s += HEX_CHARS[(int)(a[i] >>> 44) & 0x0f]; s += HEX_CHARS[(int)(a[i] >>> 40) & 0x0f]; s += HEX_CHARS[(int)(a[i] >>> 36) & 0x0f]; s += HEX_CHARS[(int)(a[i] >>> 32) & 0x0f]; s += HEX_CHARS[(int)(a[i] >>> 28) & 0x0f]; s += HEX_CHARS[(int)(a[i] >>> 24) & 0x0f]; s += HEX_CHARS[(int)(a[i] >>> 20) & 0x0f]; s += HEX_CHARS[(int)(a[i] >>> 16) & 0x0f]; s += HEX_CHARS[(int)(a[i] >>> 12) & 0x0f]; s += HEX_CHARS[(int)(a[i] >>> 8) & 0x0f]; s += HEX_CHARS[(int)(a[i] >>> 4) & 0x0f]; s += HEX_CHARS[(int)(a[i]) & 0x0f]; s += " "; } } return s; } /** * Returns this element as FlexiBigInt. The conversion is P1363-conform. * * @return this element as BigInteger */ public BigInteger toFlexiBigInt() { /** @todo this method does not reverse the bit-order as it should!!! */ return new BigInteger(1, toByteArray()); } /** * Returns this element as byte array. The conversion is P1363-conform. * * @return this element as byte array */ public byte[] toByteArray() { /** @todo this method does not reverse the bit-order as it should!!! */ int k = ((mDegree - 1) >> 3) + 1; byte[] result = new byte[k]; int i; for (i = 0; i < k; i++) { result[k - i - 1] = (byte)((mPol[i >>> 3] & (0x00000000000000ffL << ((i & 0x07) << 3))) >>> ((i & 0x07) << 3)); } return result; } } bouncycastle-1.49.orig/src/org/bouncycastle/pqc/math/linearalgebra/GF2nField.java0000644000175000017500000002071012043365070027351 0ustar ebourgebourgpackage org.bouncycastle.pqc.math.linearalgebra; import java.util.Vector; /** * This abstract class defines the finite field GF(2n). It * holds the extension degree n, the characteristic, the irreducible * fieldpolynomial and conversion matrices. GF2nField is implemented by the * classes GF2nPolynomialField and GF2nONBField. * * @see GF2nONBField * @see GF2nPolynomialField */ public abstract class GF2nField { /** * the degree of this field */ protected int mDegree; /** * the irreducible fieldPolynomial stored in normal order (also for ONB) */ protected GF2Polynomial fieldPolynomial; /** * holds a list of GF2nFields to which elements have been converted and thus * a COB-Matrix exists */ protected Vector fields; /** * the COB matrices */ protected Vector matrices; /** * Returns the degree n of this field. * * @return the degree n of this field */ public final int getDegree() { return mDegree; } /** * Returns the fieldpolynomial as a new Bitstring. * * @return a copy of the fieldpolynomial as a new Bitstring */ public final GF2Polynomial getFieldPolynomial() { if (fieldPolynomial == null) { computeFieldPolynomial(); } return new GF2Polynomial(fieldPolynomial); } /** * Decides whether the given object other is the same as this * field. * * @param other another object * @return (this == other) */ public final boolean equals(Object other) { if (other == null || !(other instanceof GF2nField)) { return false; } GF2nField otherField = (GF2nField)other; if (otherField.mDegree != mDegree) { return false; } if (!fieldPolynomial.equals(otherField.fieldPolynomial)) { return false; } if ((this instanceof GF2nPolynomialField) && !(otherField instanceof GF2nPolynomialField)) { return false; } if ((this instanceof GF2nONBField) && !(otherField instanceof GF2nONBField)) { return false; } return true; } /** * @return the hash code of this field */ public int hashCode() { return mDegree + fieldPolynomial.hashCode(); } /** * Computes a random root from the given irreducible fieldpolynomial * according to IEEE 1363 algorithm A.5.6. This cal take very long for big * degrees. * * @param B0FieldPolynomial the fieldpolynomial if the other basis as a Bitstring * @return a random root of BOFieldPolynomial in representation according to * this field * @see "P1363 A.5.6, p103f" */ protected abstract GF2nElement getRandomRoot(GF2Polynomial B0FieldPolynomial); /** * Computes the change-of-basis matrix for basis conversion according to * 1363. The result is stored in the lists fields and matrices. * * @param B1 the GF2nField to convert to * @see "P1363 A.7.3, p111ff" */ protected abstract void computeCOBMatrix(GF2nField B1); /** * Computes the fieldpolynomial. This can take a long time for big degrees. */ protected abstract void computeFieldPolynomial(); /** * Inverts the given matrix represented as bitstrings. * * @param matrix the matrix to invert as a Bitstring[] * @return matrix^(-1) */ protected final GF2Polynomial[] invertMatrix(GF2Polynomial[] matrix) { GF2Polynomial[] a = new GF2Polynomial[matrix.length]; GF2Polynomial[] inv = new GF2Polynomial[matrix.length]; GF2Polynomial dummy; int i, j; // initialize a as a copy of matrix and inv as E(inheitsmatrix) for (i = 0; i < mDegree; i++) { try { a[i] = new GF2Polynomial(matrix[i]); inv[i] = new GF2Polynomial(mDegree); inv[i].setBit(mDegree - 1 - i); } catch (RuntimeException BDNEExc) { BDNEExc.printStackTrace(); } } // construct triangle matrix so that for each a[i] the first i bits are // zero for (i = 0; i < mDegree - 1; i++) { // find column where bit i is set j = i; while ((j < mDegree) && !a[j].testBit(mDegree - 1 - i)) { j++; } if (j >= mDegree) { throw new RuntimeException( "GF2nField.invertMatrix: Matrix cannot be inverted!"); } if (i != j) { // swap a[i]/a[j] and inv[i]/inv[j] dummy = a[i]; a[i] = a[j]; a[j] = dummy; dummy = inv[i]; inv[i] = inv[j]; inv[j] = dummy; } for (j = i + 1; j < mDegree; j++) { // add column i to all columns>i // having their i-th bit set if (a[j].testBit(mDegree - 1 - i)) { a[j].addToThis(a[i]); inv[j].addToThis(inv[i]); } } } // construct Einheitsmatrix from a for (i = mDegree - 1; i > 0; i--) { for (j = i - 1; j >= 0; j--) { // eliminate the i-th bit in all // columns < i if (a[j].testBit(mDegree - 1 - i)) { a[j].addToThis(a[i]); inv[j].addToThis(inv[i]); } } } return inv; } /** * Converts the given element in representation according to this field to a * new element in representation according to B1 using the change-of-basis * matrix calculated by computeCOBMatrix. * * @param elem the GF2nElement to convert * @param basis the basis to convert elem to * @return elem converted to a new element representation * according to basis * @throws DifferentFieldsException if elem cannot be converted according to * basis. * @see GF2nField#computeCOBMatrix * @see GF2nField#getRandomRoot * @see GF2nPolynomial * @see "P1363 A.7 p109ff" */ public final GF2nElement convert(GF2nElement elem, GF2nField basis) throws RuntimeException { if (basis == this) { return (GF2nElement)elem.clone(); } if (fieldPolynomial.equals(basis.fieldPolynomial)) { return (GF2nElement)elem.clone(); } if (mDegree != basis.mDegree) { throw new RuntimeException("GF2nField.convert: B1 has a" + " different degree and thus cannot be coverted to!"); } int i; GF2Polynomial[] COBMatrix; i = fields.indexOf(basis); if (i == -1) { computeCOBMatrix(basis); i = fields.indexOf(basis); } COBMatrix = (GF2Polynomial[])matrices.elementAt(i); GF2nElement elemCopy = (GF2nElement)elem.clone(); if (elemCopy instanceof GF2nONBElement) { // remember: ONB treats its bits in reverse order ((GF2nONBElement)elemCopy).reverseOrder(); } GF2Polynomial bs = new GF2Polynomial(mDegree, elemCopy.toFlexiBigInt()); bs.expandN(mDegree); GF2Polynomial result = new GF2Polynomial(mDegree); for (i = 0; i < mDegree; i++) { if (bs.vectorMult(COBMatrix[i])) { result.setBit(mDegree - 1 - i); } } if (basis instanceof GF2nPolynomialField) { return new GF2nPolynomialElement((GF2nPolynomialField)basis, result); } else if (basis instanceof GF2nONBField) { GF2nONBElement res = new GF2nONBElement((GF2nONBField)basis, result.toFlexiBigInt()); // TODO Remember: ONB treats its Bits in reverse order !!! res.reverseOrder(); return res; } else { throw new RuntimeException( "GF2nField.convert: B1 must be an instance of " + "GF2nPolynomialField or GF2nONBField!"); } } } bouncycastle-1.49.orig/src/org/bouncycastle/pqc/math/linearalgebra/Vector.java0000644000175000017500000000272512043365070027121 0ustar ebourgebourgpackage org.bouncycastle.pqc.math.linearalgebra; /** * This abstract class defines vectors. It holds the length of vector. */ public abstract class Vector { /** * the length of this vector */ protected int length; /** * @return the length of this vector */ public final int getLength() { return length; } /** * @return this vector as byte array */ public abstract byte[] getEncoded(); /** * Return whether this is the zero vector (i.e., all elements are zero). * * @return true if this is the zero vector, false * otherwise */ public abstract boolean isZero(); /** * Add another vector to this vector. * * @param addend the other vector * @return this + addend */ public abstract Vector add(Vector addend); /** * Multiply this vector with a permutation. * * @param p the permutation * @return this*p = p*this */ public abstract Vector multiply(Permutation p); /** * Check if the given object is equal to this vector. * * @param other vector * @return the result of the comparison */ public abstract boolean equals(Object other); /** * @return the hash code of this vector */ public abstract int hashCode(); /** * @return a human readable form of this vector */ public abstract String toString(); } bouncycastle-1.49.orig/src/org/bouncycastle/pqc/math/linearalgebra/Matrix.java0000644000175000017500000000623412043365070027122 0ustar ebourgebourgpackage org.bouncycastle.pqc.math.linearalgebra; /** * This abstract class defines matrices. It holds the number of rows and the * number of columns of the matrix and defines some basic methods. */ public abstract class Matrix { /** * number of rows */ protected int numRows; /** * number of columns */ protected int numColumns; // ---------------------------------------------------- // some constants (matrix types) // ---------------------------------------------------- /** * zero matrix */ public static final char MATRIX_TYPE_ZERO = 'Z'; /** * unit matrix */ public static final char MATRIX_TYPE_UNIT = 'I'; /** * random lower triangular matrix */ public static final char MATRIX_TYPE_RANDOM_LT = 'L'; /** * random upper triangular matrix */ public static final char MATRIX_TYPE_RANDOM_UT = 'U'; /** * random regular matrix */ public static final char MATRIX_TYPE_RANDOM_REGULAR = 'R'; // ---------------------------------------------------- // getters // ---------------------------------------------------- /** * @return the number of rows in the matrix */ public int getNumRows() { return numRows; } /** * @return the number of columns in the binary matrix */ public int getNumColumns() { return numColumns; } /** * @return the encoded matrix, i.e., this matrix in byte array form. */ public abstract byte[] getEncoded(); // ---------------------------------------------------- // arithmetic // ---------------------------------------------------- /** * Compute the inverse of this matrix. * * @return the inverse of this matrix (newly created). */ public abstract Matrix computeInverse(); /** * Check if this is the zero matrix (i.e., all entries are zero). * * @return true if this is the zero matrix */ public abstract boolean isZero(); /** * Compute the product of this matrix and another matrix. * * @param a the other matrix * @return this * a (newly created) */ public abstract Matrix rightMultiply(Matrix a); /** * Compute the product of this matrix and a permutation. * * @param p the permutation * @return this * p (newly created) */ public abstract Matrix rightMultiply(Permutation p); /** * Compute the product of a vector and this matrix. If the length of the * vector is greater than the number of rows of this matrix, the matrix is * multiplied by each m-bit part of the vector. * * @param vector a vector * @return vector * this (newly created) */ public abstract Vector leftMultiply(Vector vector); /** * Compute the product of this matrix and a vector. * * @param vector a vector * @return this * vector (newly created) */ public abstract Vector rightMultiply(Vector vector); /** * @return a human readable form of the matrix. */ public abstract String toString(); } bouncycastle-1.49.orig/src/org/bouncycastle/pqc/math/linearalgebra/ByteUtils.java0000644000175000017500000002624012043366433027605 0ustar ebourgebourgpackage org.bouncycastle.pqc.math.linearalgebra; /** * This class is a utility class for manipulating byte arrays. */ public final class ByteUtils { private static final char[] HEX_CHARS = {'0', '1', '2', '3', '4', '5', '6', '7', '8', '9', 'a', 'b', 'c', 'd', 'e', 'f'}; /** * Default constructor (private) */ private ByteUtils() { // empty } /** * Compare two byte arrays (perform null checks beforehand). * * @param left the first byte array * @param right the second byte array * @return the result of the comparison */ public static boolean equals(byte[] left, byte[] right) { if (left == null) { return right == null; } if (right == null) { return false; } if (left.length != right.length) { return false; } boolean result = true; for (int i = left.length - 1; i >= 0; i--) { result &= left[i] == right[i]; } return result; } /** * Compare two two-dimensional byte arrays. No null checks are performed. * * @param left the first byte array * @param right the second byte array * @return the result of the comparison */ public static boolean equals(byte[][] left, byte[][] right) { if (left.length != right.length) { return false; } boolean result = true; for (int i = left.length - 1; i >= 0; i--) { result &= ByteUtils.equals(left[i], right[i]); } return result; } /** * Compare two three-dimensional byte arrays. No null checks are performed. * * @param left the first byte array * @param right the second byte array * @return the result of the comparison */ public static boolean equals(byte[][][] left, byte[][][] right) { if (left.length != right.length) { return false; } boolean result = true; for (int i = left.length - 1; i >= 0; i--) { if (left[i].length != right[i].length) { return false; } for (int j = left[i].length - 1; j >= 0; j--) { result &= ByteUtils.equals(left[i][j], right[i][j]); } } return result; } /** * Computes a hashcode based on the contents of a one-dimensional byte array * rather than its identity. * * @param array the array to compute the hashcode of * @return the hashcode */ public static int deepHashCode(byte[] array) { int result = 1; for (int i = 0; i < array.length; i++) { result = 31 * result + array[i]; } return result; } /** * Computes a hashcode based on the contents of a two-dimensional byte array * rather than its identity. * * @param array the array to compute the hashcode of * @return the hashcode */ public static int deepHashCode(byte[][] array) { int result = 1; for (int i = 0; i < array.length; i++) { result = 31 * result + deepHashCode(array[i]); } return result; } /** * Computes a hashcode based on the contents of a three-dimensional byte * array rather than its identity. * * @param array the array to compute the hashcode of * @return the hashcode */ public static int deepHashCode(byte[][][] array) { int result = 1; for (int i = 0; i < array.length; i++) { result = 31 * result + deepHashCode(array[i]); } return result; } /** * Return a clone of the given byte array (performs null check beforehand). * * @param array the array to clone * @return the clone of the given array, or null if the array is * null */ public static byte[] clone(byte[] array) { if (array == null) { return null; } byte[] result = new byte[array.length]; System.arraycopy(array, 0, result, 0, array.length); return result; } /** * Convert a string containing hexadecimal characters to a byte-array. * * @param s a hex string * @return a byte array with the corresponding value */ public static byte[] fromHexString(String s) { char[] rawChars = s.toUpperCase().toCharArray(); int hexChars = 0; for (int i = 0; i < rawChars.length; i++) { if ((rawChars[i] >= '0' && rawChars[i] <= '9') || (rawChars[i] >= 'A' && rawChars[i] <= 'F')) { hexChars++; } } byte[] byteString = new byte[(hexChars + 1) >> 1]; int pos = hexChars & 1; for (int i = 0; i < rawChars.length; i++) { if (rawChars[i] >= '0' && rawChars[i] <= '9') { byteString[pos >> 1] <<= 4; byteString[pos >> 1] |= rawChars[i] - '0'; } else if (rawChars[i] >= 'A' && rawChars[i] <= 'F') { byteString[pos >> 1] <<= 4; byteString[pos >> 1] |= rawChars[i] - 'A' + 10; } else { continue; } pos++; } return byteString; } /** * Convert a byte array to the corresponding hexstring. * * @param input the byte array to be converted * @return the corresponding hexstring */ public static String toHexString(byte[] input) { String result = ""; for (int i = 0; i < input.length; i++) { result += HEX_CHARS[(input[i] >>> 4) & 0x0f]; result += HEX_CHARS[(input[i]) & 0x0f]; } return result; } /** * Convert a byte array to the corresponding hex string. * * @param input the byte array to be converted * @param prefix the prefix to put at the beginning of the hex string * @param seperator a separator string * @return the corresponding hex string */ public static String toHexString(byte[] input, String prefix, String seperator) { String result = new String(prefix); for (int i = 0; i < input.length; i++) { result += HEX_CHARS[(input[i] >>> 4) & 0x0f]; result += HEX_CHARS[(input[i]) & 0x0f]; if (i < input.length - 1) { result += seperator; } } return result; } /** * Convert a byte array to the corresponding bit string. * * @param input the byte array to be converted * @return the corresponding bit string */ public static String toBinaryString(byte[] input) { String result = ""; int i; for (i = 0; i < input.length; i++) { int e = input[i]; for (int ii = 0; ii < 8; ii++) { int b = (e >>> ii) & 1; result += b; } if (i != input.length - 1) { result += " "; } } return result; } /** * Compute the bitwise XOR of two arrays of bytes. The arrays have to be of * same length. No length checking is performed. * * @param x1 the first array * @param x2 the second array * @return x1 XOR x2 */ public static byte[] xor(byte[] x1, byte[] x2) { byte[] out = new byte[x1.length]; for (int i = x1.length - 1; i >= 0; i--) { out[i] = (byte)(x1[i] ^ x2[i]); } return out; } /** * Concatenate two byte arrays. No null checks are performed. * * @param x1 the first array * @param x2 the second array * @return (x2||x1) (little-endian order, i.e. x1 is at lower memory * addresses) */ public static byte[] concatenate(byte[] x1, byte[] x2) { byte[] result = new byte[x1.length + x2.length]; System.arraycopy(x1, 0, result, 0, x1.length); System.arraycopy(x2, 0, result, x1.length, x2.length); return result; } /** * Convert a 2-dimensional byte array into a 1-dimensional byte array by * concatenating all entries. * * @param array a 2-dimensional byte array * @return the concatenated input array */ public static byte[] concatenate(byte[][] array) { int rowLength = array[0].length; byte[] result = new byte[array.length * rowLength]; int index = 0; for (int i = 0; i < array.length; i++) { System.arraycopy(array[i], 0, result, index, rowLength); index += rowLength; } return result; } /** * Split a byte array input into two arrays at index, * i.e. the first array will have the lower index bytes, the * second one the higher input.length - index bytes. * * @param input the byte array to be split * @param index the index where the byte array is split * @return the splitted input array as an array of two byte arrays * @throws ArrayIndexOutOfBoundsException if index is out of bounds */ public static byte[][] split(byte[] input, int index) throws ArrayIndexOutOfBoundsException { if (index > input.length) { throw new ArrayIndexOutOfBoundsException(); } byte[][] result = new byte[2][]; result[0] = new byte[index]; result[1] = new byte[input.length - index]; System.arraycopy(input, 0, result[0], 0, index); System.arraycopy(input, index, result[1], 0, input.length - index); return result; } /** * Generate a subarray of a given byte array. * * @param input the input byte array * @param start the start index * @param end the end index * @return a subarray of input, ranging from start * (inclusively) to end (exclusively) */ public static byte[] subArray(byte[] input, int start, int end) { byte[] result = new byte[end - start]; System.arraycopy(input, start, result, 0, end - start); return result; } /** * Generate a subarray of a given byte array. * * @param input the input byte array * @param start the start index * @return a subarray of input, ranging from start to * the end of the array */ public static byte[] subArray(byte[] input, int start) { return subArray(input, start, input.length); } /** * Rewrite a byte array as a char array * * @param input - * the byte array * @return char array */ public static char[] toCharArray(byte[] input) { char[] result = new char[input.length]; for (int i = 0; i < input.length; i++) { result[i] = (char)input[i]; } return result; } } bouncycastle-1.49.orig/src/org/bouncycastle/pqc/math/linearalgebra/BigEndianConversions.java0000644000175000017500000002242212043365070031724 0ustar ebourgebourgpackage org.bouncycastle.pqc.math.linearalgebra; /** * This is a utility class containing data type conversions using big-endian * byte order. * * @see LittleEndianConversions */ public final class BigEndianConversions { /** * Default constructor (private). */ private BigEndianConversions() { // empty } /** * Convert an integer to an octet string of length 4 according to IEEE 1363, * Section 5.5.3. * * @param x the integer to convert * @return the converted integer */ public static byte[] I2OSP(int x) { byte[] result = new byte[4]; result[0] = (byte)(x >>> 24); result[1] = (byte)(x >>> 16); result[2] = (byte)(x >>> 8); result[3] = (byte)x; return result; } /** * Convert an integer to an octet string according to IEEE 1363, Section * 5.5.3. Length checking is performed. * * @param x the integer to convert * @param oLen the desired length of the octet string * @return an octet string of length oLen representing the * integer x, or null if the integer is * negative * @throws ArithmeticException if x can't be encoded into oLen * octets. */ public static byte[] I2OSP(int x, int oLen) throws ArithmeticException { if (x < 0) { return null; } int octL = IntegerFunctions.ceilLog256(x); if (octL > oLen) { throw new ArithmeticException( "Cannot encode given integer into specified number of octets."); } byte[] result = new byte[oLen]; for (int i = oLen - 1; i >= oLen - octL; i--) { result[i] = (byte)(x >>> (8 * (oLen - 1 - i))); } return result; } /** * Convert an integer to an octet string of length 4 according to IEEE 1363, * Section 5.5.3. * * @param input the integer to convert * @param output byte array holding the output * @param outOff offset in output array where the result is stored */ public static void I2OSP(int input, byte[] output, int outOff) { output[outOff++] = (byte)(input >>> 24); output[outOff++] = (byte)(input >>> 16); output[outOff++] = (byte)(input >>> 8); output[outOff] = (byte)input; } /** * Convert an integer to an octet string of length 8 according to IEEE 1363, * Section 5.5.3. * * @param input the integer to convert * @return the converted integer */ public static byte[] I2OSP(long input) { byte[] output = new byte[8]; output[0] = (byte)(input >>> 56); output[1] = (byte)(input >>> 48); output[2] = (byte)(input >>> 40); output[3] = (byte)(input >>> 32); output[4] = (byte)(input >>> 24); output[5] = (byte)(input >>> 16); output[6] = (byte)(input >>> 8); output[7] = (byte)input; return output; } /** * Convert an integer to an octet string of length 8 according to IEEE 1363, * Section 5.5.3. * * @param input the integer to convert * @param output byte array holding the output * @param outOff offset in output array where the result is stored */ public static void I2OSP(long input, byte[] output, int outOff) { output[outOff++] = (byte)(input >>> 56); output[outOff++] = (byte)(input >>> 48); output[outOff++] = (byte)(input >>> 40); output[outOff++] = (byte)(input >>> 32); output[outOff++] = (byte)(input >>> 24); output[outOff++] = (byte)(input >>> 16); output[outOff++] = (byte)(input >>> 8); output[outOff] = (byte)input; } /** * Convert an integer to an octet string of the specified length according * to IEEE 1363, Section 5.5.3. No length checking is performed (i.e., if * the integer cannot be encoded into length octets, it is * truncated). * * @param input the integer to convert * @param output byte array holding the output * @param outOff offset in output array where the result is stored * @param length the length of the encoding */ public static void I2OSP(int input, byte[] output, int outOff, int length) { for (int i = length - 1; i >= 0; i--) { output[outOff + i] = (byte)(input >>> (8 * (length - 1 - i))); } } /** * Convert an octet string to an integer according to IEEE 1363, Section * 5.5.3. * * @param input the byte array holding the octet string * @return an integer representing the octet string input, or * 0 if the represented integer is negative or too large * or the byte array is empty * @throws ArithmeticException if the length of the given octet string is larger than 4. */ public static int OS2IP(byte[] input) { if (input.length > 4) { throw new ArithmeticException("invalid input length"); } if (input.length == 0) { return 0; } int result = 0; for (int j = 0; j < input.length; j++) { result |= (input[j] & 0xff) << (8 * (input.length - 1 - j)); } return result; } /** * Convert a byte array of length 4 beginning at offset into an * integer. * * @param input the byte array * @param inOff the offset into the byte array * @return the resulting integer */ public static int OS2IP(byte[] input, int inOff) { int result = (input[inOff++] & 0xff) << 24; result |= (input[inOff++] & 0xff) << 16; result |= (input[inOff++] & 0xff) << 8; result |= input[inOff] & 0xff; return result; } /** * Convert an octet string to an integer according to IEEE 1363, Section * 5.5.3. * * @param input the byte array holding the octet string * @param inOff the offset in the input byte array where the octet string * starts * @param inLen the length of the encoded integer * @return an integer representing the octet string bytes, or * 0 if the represented integer is negative or too large * or the byte array is empty */ public static int OS2IP(byte[] input, int inOff, int inLen) { if ((input.length == 0) || input.length < inOff + inLen - 1) { return 0; } int result = 0; for (int j = 0; j < inLen; j++) { result |= (input[inOff + j] & 0xff) << (8 * (inLen - j - 1)); } return result; } /** * Convert a byte array of length 8 beginning at inOff into a * long integer. * * @param input the byte array * @param inOff the offset into the byte array * @return the resulting long integer */ public static long OS2LIP(byte[] input, int inOff) { long result = ((long)input[inOff++] & 0xff) << 56; result |= ((long)input[inOff++] & 0xff) << 48; result |= ((long)input[inOff++] & 0xff) << 40; result |= ((long)input[inOff++] & 0xff) << 32; result |= ((long)input[inOff++] & 0xff) << 24; result |= (input[inOff++] & 0xff) << 16; result |= (input[inOff++] & 0xff) << 8; result |= input[inOff] & 0xff; return result; } /** * Convert an int array into a byte array. * * @param input the int array * @return the converted array */ public static byte[] toByteArray(final int[] input) { byte[] result = new byte[input.length << 2]; for (int i = 0; i < input.length; i++) { I2OSP(input[i], result, i << 2); } return result; } /** * Convert an int array into a byte array of the specified length. No length * checking is performed (i.e., if the last integer cannot be encoded into * length % 4 octets, it is truncated). * * @param input the int array * @param length the length of the converted array * @return the converted array */ public static byte[] toByteArray(final int[] input, int length) { final int intLen = input.length; byte[] result = new byte[length]; int index = 0; for (int i = 0; i <= intLen - 2; i++, index += 4) { I2OSP(input[i], result, index); } I2OSP(input[intLen - 1], result, index, length - index); return result; } /** * Convert a byte array into an int array. * * @param input the byte array * @return the converted array */ public static int[] toIntArray(byte[] input) { final int intLen = (input.length + 3) / 4; final int lastLen = input.length & 0x03; int[] result = new int[intLen]; int index = 0; for (int i = 0; i <= intLen - 2; i++, index += 4) { result[i] = OS2IP(input, index); } if (lastLen != 0) { result[intLen - 1] = OS2IP(input, index, lastLen); } else { result[intLen - 1] = OS2IP(input, index); } return result; } } bouncycastle-1.49.orig/src/org/bouncycastle/pqc/math/linearalgebra/Permutation.java0000644000175000017500000001342112105027307030156 0ustar ebourgebourgpackage org.bouncycastle.pqc.math.linearalgebra; import java.security.SecureRandom; /** * This class implements permutations of the set {0,1,...,n-1} for some given n * > 0, i.e., ordered sequences containing each number m (0 <= * m < n) * once and only once. */ public class Permutation { /** * perm holds the elements of the permutation vector, i.e. [perm(0), * perm(1), ..., perm(n-1)] */ private int[] perm; /** * Create the identity permutation of the given size. * * @param n the size of the permutation */ public Permutation(int n) { if (n <= 0) { throw new IllegalArgumentException("invalid length"); } perm = new int[n]; for (int i = n - 1; i >= 0; i--) { perm[i] = i; } } /** * Create a permutation using the given permutation vector. * * @param perm the permutation vector */ public Permutation(int[] perm) { if (!isPermutation(perm)) { throw new IllegalArgumentException( "array is not a permutation vector"); } this.perm = IntUtils.clone(perm); } /** * Create a permutation from an encoded permutation. * * @param enc the encoded permutation */ public Permutation(byte[] enc) { if (enc.length <= 4) { throw new IllegalArgumentException("invalid encoding"); } int n = LittleEndianConversions.OS2IP(enc, 0); int size = IntegerFunctions.ceilLog256(n - 1); if (enc.length != 4 + n * size) { throw new IllegalArgumentException("invalid encoding"); } perm = new int[n]; for (int i = 0; i < n; i++) { perm[i] = LittleEndianConversions.OS2IP(enc, 4 + i * size, size); } if (!isPermutation(perm)) { throw new IllegalArgumentException("invalid encoding"); } } /** * Create a random permutation of the given size. * * @param n the size of the permutation * @param sr the source of randomness */ public Permutation(int n, SecureRandom sr) { if (n <= 0) { throw new IllegalArgumentException("invalid length"); } perm = new int[n]; int[] help = new int[n]; for (int i = 0; i < n; i++) { help[i] = i; } int k = n; for (int j = 0; j < n; j++) { int i = RandUtils.nextInt(sr, k); k--; perm[j] = help[i]; help[i] = help[k]; } } /** * Encode this permutation as byte array. * * @return the encoded permutation */ public byte[] getEncoded() { int n = perm.length; int size = IntegerFunctions.ceilLog256(n - 1); byte[] result = new byte[4 + n * size]; LittleEndianConversions.I2OSP(n, result, 0); for (int i = 0; i < n; i++) { LittleEndianConversions.I2OSP(perm[i], result, 4 + i * size, size); } return result; } /** * @return the permutation vector (perm(0),perm(1),...,perm(n-1)) */ public int[] getVector() { return IntUtils.clone(perm); } /** * Compute the inverse permutation P-1. * * @return this-1 */ public Permutation computeInverse() { Permutation result = new Permutation(perm.length); for (int i = perm.length - 1; i >= 0; i--) { result.perm[perm[i]] = i; } return result; } /** * Compute the product of this permutation and another permutation. * * @param p the other permutation * @return this * p */ public Permutation rightMultiply(Permutation p) { if (p.perm.length != perm.length) { throw new IllegalArgumentException("length mismatch"); } Permutation result = new Permutation(perm.length); for (int i = perm.length - 1; i >= 0; i--) { result.perm[i] = perm[p.perm[i]]; } return result; } /** * checks if given object is equal to this permutation. *

    * The method returns false whenever the given object is not permutation. * * @param other - * permutation * @return true or false */ public boolean equals(Object other) { if (!(other instanceof Permutation)) { return false; } Permutation otherPerm = (Permutation)other; return IntUtils.equals(perm, otherPerm.perm); } /** * @return a human readable form of the permutation */ public String toString() { String result = "[" + perm[0]; for (int i = 1; i < perm.length; i++) { result += ", " + perm[i]; } result += "]"; return result; } /** * @return the hash code of this permutation */ public int hashCode() { return perm.hashCode(); } /** * Check that the given array corresponds to a permutation of the set * {0, 1, ..., n-1}. * * @param perm permutation vector * @return true if perm represents an n-permutation and false otherwise */ private boolean isPermutation(int[] perm) { int n = perm.length; boolean[] onlyOnce = new boolean[n]; for (int i = 0; i < n; i++) { if ((perm[i] < 0) || (perm[i] >= n) || onlyOnce[perm[i]]) { return false; } onlyOnce[perm[i]] = true; } return true; } } bouncycastle-1.49.orig/src/org/bouncycastle/pqc/math/linearalgebra/GoppaCode.java0000644000175000017500000002163412043365070027520 0ustar ebourgebourgpackage org.bouncycastle.pqc.math.linearalgebra; import java.security.SecureRandom; /** * This class describes decoding operations of an irreducible binary Goppa code. * A check matrix H of the Goppa code and an irreducible Goppa polynomial are * used the operations are worked over a finite field GF(2^m) * * @see GF2mField * @see PolynomialGF2mSmallM */ public final class GoppaCode { /** * Default constructor (private). */ private GoppaCode() { // empty } /** * This class is a container for two instances of {@link GF2Matrix} and one * instance of {@link Permutation}. It is used to hold the systematic form * S*H*P = (Id|M) of the check matrix H as returned by * {@link GoppaCode#computeSystematicForm(GF2Matrix, SecureRandom)}. * * @see GF2Matrix * @see Permutation */ public static class MaMaPe { private GF2Matrix s, h; private Permutation p; /** * Construct a new {@link MaMaPe} container with the given parameters. * * @param s the first matrix * @param h the second matrix * @param p the permutation */ public MaMaPe(GF2Matrix s, GF2Matrix h, Permutation p) { this.s = s; this.h = h; this.p = p; } /** * @return the first matrix */ public GF2Matrix getFirstMatrix() { return s; } /** * @return the second matrix */ public GF2Matrix getSecondMatrix() { return h; } /** * @return the permutation */ public Permutation getPermutation() { return p; } } /** * This class is a container for an instance of {@link GF2Matrix} and one * int[]. It is used to hold a generator matrix and the set of indices such * that the submatrix of the generator matrix consisting of the specified * columns is the identity. * * @see GF2Matrix * @see Permutation */ public static class MatrixSet { private GF2Matrix g; private int[] setJ; /** * Construct a new {@link MatrixSet} container with the given * parameters. * * @param g the generator matrix * @param setJ the set of indices such that the submatrix of the * generator matrix consisting of the specified columns * is the identity */ public MatrixSet(GF2Matrix g, int[] setJ) { this.g = g; this.setJ = setJ; } /** * @return the generator matrix */ public GF2Matrix getG() { return g; } /** * @return the set of indices such that the submatrix of the generator * matrix consisting of the specified columns is the identity */ public int[] getSetJ() { return setJ; } } /** * Construct the check matrix of a Goppa code in canonical form from the * irreducible Goppa polynomial over the finite field * GF(2m). * * @param field the finite field * @param gp the irreducible Goppa polynomial */ public static GF2Matrix createCanonicalCheckMatrix(GF2mField field, PolynomialGF2mSmallM gp) { int m = field.getDegree(); int n = 1 << m; int t = gp.getDegree(); /* create matrix H over GF(2^m) */ int[][] hArray = new int[t][n]; // create matrix YZ int[][] yz = new int[t][n]; for (int j = 0; j < n; j++) { // here j is used as index and as element of field GF(2^m) yz[0][j] = field.inverse(gp.evaluateAt(j)); } for (int i = 1; i < t; i++) { for (int j = 0; j < n; j++) { // here j is used as index and as element of field GF(2^m) yz[i][j] = field.mult(yz[i - 1][j], j); } } // create matrix H = XYZ for (int i = 0; i < t; i++) { for (int j = 0; j < n; j++) { for (int k = 0; k <= i; k++) { hArray[i][j] = field.add(hArray[i][j], field.mult(yz[k][j], gp.getCoefficient(t + k - i))); } } } /* convert to matrix over GF(2) */ int[][] result = new int[t * m][(n + 31) >>> 5]; for (int j = 0; j < n; j++) { int q = j >>> 5; int r = 1 << (j & 0x1f); for (int i = 0; i < t; i++) { int e = hArray[i][j]; for (int u = 0; u < m; u++) { int b = (e >>> u) & 1; if (b != 0) { int ind = (i + 1) * m - u - 1; result[ind][q] ^= r; } } } } return new GF2Matrix(n, result); } /** * Given a check matrix H, compute matrices S, * M, and a random permutation P such that * S*H*P = (Id|M). Return S^-1, M, and * P as {@link MaMaPe}. The matrix (Id | M) is called * the systematic form of H. * * @param h the check matrix * @param sr a source of randomness * @return the tuple (S^-1, M, P) */ public static MaMaPe computeSystematicForm(GF2Matrix h, SecureRandom sr) { int n = h.getNumColumns(); GF2Matrix hp, sInv; GF2Matrix s = null; Permutation p; boolean found = false; do { p = new Permutation(n, sr); hp = (GF2Matrix)h.rightMultiply(p); sInv = hp.getLeftSubMatrix(); try { found = true; s = (GF2Matrix)sInv.computeInverse(); } catch (ArithmeticException ae) { found = false; } } while (!found); GF2Matrix shp = (GF2Matrix)s.rightMultiply(hp); GF2Matrix m = shp.getRightSubMatrix(); return new MaMaPe(sInv, m, p); } /** * Find an error vector e over GF(2) from an input * syndrome s over GF(2m). * * @param syndVec the syndrome * @param field the finite field * @param gp the irreducible Goppa polynomial * @param sqRootMatrix the matrix for computing square roots in * (GF(2m))t * @return the error vector */ public static GF2Vector syndromeDecode(GF2Vector syndVec, GF2mField field, PolynomialGF2mSmallM gp, PolynomialGF2mSmallM[] sqRootMatrix) { int n = 1 << field.getDegree(); // the error vector GF2Vector errors = new GF2Vector(n); // if the syndrome vector is zero, the error vector is also zero if (!syndVec.isZero()) { // convert syndrome vector to polynomial over GF(2^m) PolynomialGF2mSmallM syndrome = new PolynomialGF2mSmallM(syndVec .toExtensionFieldVector(field)); // compute T = syndrome^-1 mod gp PolynomialGF2mSmallM t = syndrome.modInverse(gp); // compute tau = sqRoot(T + X) mod gp PolynomialGF2mSmallM tau = t.addMonomial(1); tau = tau.modSquareRootMatrix(sqRootMatrix); // compute polynomials a and b satisfying a + b*tau = 0 mod gp PolynomialGF2mSmallM[] ab = tau.modPolynomialToFracton(gp); // compute the polynomial a^2 + X*b^2 PolynomialGF2mSmallM a2 = ab[0].multiply(ab[0]); PolynomialGF2mSmallM b2 = ab[1].multiply(ab[1]); PolynomialGF2mSmallM xb2 = b2.multWithMonomial(1); PolynomialGF2mSmallM a2plusXb2 = a2.add(xb2); // normalize a^2 + X*b^2 to obtain the error locator polynomial int headCoeff = a2plusXb2.getHeadCoefficient(); int invHeadCoeff = field.inverse(headCoeff); PolynomialGF2mSmallM elp = a2plusXb2.multWithElement(invHeadCoeff); // for all elements i of GF(2^m) for (int i = 0; i < n; i++) { // evaluate the error locator polynomial at i int z = elp.evaluateAt(i); // if polynomial evaluates to zero if (z == 0) { // set the i-th coefficient of the error vector errors.setBit(i); } } } return errors; } } bouncycastle-1.49.orig/src/org/bouncycastle/pqc/math/linearalgebra/LittleEndianConversions.java0000644000175000017500000001560012043365070032460 0ustar ebourgebourgpackage org.bouncycastle.pqc.math.linearalgebra; /** * This is a utility class containing data type conversions using little-endian * byte order. * * @see BigEndianConversions */ public final class LittleEndianConversions { /** * Default constructor (private). */ private LittleEndianConversions() { // empty } /** * Convert an octet string of length 4 to an integer. No length checking is * performed. * * @param input the byte array holding the octet string * @return an integer representing the octet string input * @throws ArithmeticException if the length of the given octet string is larger than 4. */ public static int OS2IP(byte[] input) { return ((input[0] & 0xff)) | ((input[1] & 0xff) << 8) | ((input[2] & 0xff) << 16) | ((input[3] & 0xff)) << 24; } /** * Convert an byte array of length 4 beginning at offset into an * integer. * * @param input the byte array * @param inOff the offset into the byte array * @return the resulting integer */ public static int OS2IP(byte[] input, int inOff) { int result = input[inOff++] & 0xff; result |= (input[inOff++] & 0xff) << 8; result |= (input[inOff++] & 0xff) << 16; result |= (input[inOff] & 0xff) << 24; return result; } /** * Convert a byte array of the given length beginning at offset * into an integer. * * @param input the byte array * @param inOff the offset into the byte array * @param inLen the length of the encoding * @return the resulting integer */ public static int OS2IP(byte[] input, int inOff, int inLen) { int result = 0; for (int i = inLen - 1; i >= 0; i--) { result |= (input[inOff + i] & 0xff) << (8 * i); } return result; } /** * Convert a byte array of length 8 beginning at inOff into a * long integer. * * @param input the byte array * @param inOff the offset into the byte array * @return the resulting long integer */ public static long OS2LIP(byte[] input, int inOff) { long result = input[inOff++] & 0xff; result |= (input[inOff++] & 0xff) << 8; result |= (input[inOff++] & 0xff) << 16; result |= ((long)input[inOff++] & 0xff) << 24; result |= ((long)input[inOff++] & 0xff) << 32; result |= ((long)input[inOff++] & 0xff) << 40; result |= ((long)input[inOff++] & 0xff) << 48; result |= ((long)input[inOff++] & 0xff) << 56; return result; } /** * Convert an integer to an octet string of length 4. * * @param x the integer to convert * @return the converted integer */ public static byte[] I2OSP(int x) { byte[] result = new byte[4]; result[0] = (byte)x; result[1] = (byte)(x >>> 8); result[2] = (byte)(x >>> 16); result[3] = (byte)(x >>> 24); return result; } /** * Convert an integer into a byte array beginning at the specified offset. * * @param value the integer to convert * @param output the byte array to hold the result * @param outOff the integer offset into the byte array */ public static void I2OSP(int value, byte[] output, int outOff) { output[outOff++] = (byte)value; output[outOff++] = (byte)(value >>> 8); output[outOff++] = (byte)(value >>> 16); output[outOff++] = (byte)(value >>> 24); } /** * Convert an integer to a byte array beginning at the specified offset. No * length checking is performed (i.e., if the integer cannot be encoded with * length octets, it is truncated). * * @param value the integer to convert * @param output the byte array to hold the result * @param outOff the integer offset into the byte array * @param outLen the length of the encoding */ public static void I2OSP(int value, byte[] output, int outOff, int outLen) { for (int i = outLen - 1; i >= 0; i--) { output[outOff + i] = (byte)(value >>> (8 * i)); } } /** * Convert an integer to a byte array of length 8. * * @param input the integer to convert * @return the converted integer */ public static byte[] I2OSP(long input) { byte[] output = new byte[8]; output[0] = (byte)input; output[1] = (byte)(input >>> 8); output[2] = (byte)(input >>> 16); output[3] = (byte)(input >>> 24); output[4] = (byte)(input >>> 32); output[5] = (byte)(input >>> 40); output[6] = (byte)(input >>> 48); output[7] = (byte)(input >>> 56); return output; } /** * Convert an integer to a byte array of length 8. * * @param input the integer to convert * @param output byte array holding the output * @param outOff offset in output array where the result is stored */ public static void I2OSP(long input, byte[] output, int outOff) { output[outOff++] = (byte)input; output[outOff++] = (byte)(input >>> 8); output[outOff++] = (byte)(input >>> 16); output[outOff++] = (byte)(input >>> 24); output[outOff++] = (byte)(input >>> 32); output[outOff++] = (byte)(input >>> 40); output[outOff++] = (byte)(input >>> 48); output[outOff] = (byte)(input >>> 56); } /** * Convert an int array to a byte array of the specified length. No length * checking is performed (i.e., if the last integer cannot be encoded with * length % 4 octets, it is truncated). * * @param input the int array * @param outLen the length of the converted array * @return the converted array */ public static byte[] toByteArray(int[] input, int outLen) { int intLen = input.length; byte[] result = new byte[outLen]; int index = 0; for (int i = 0; i <= intLen - 2; i++, index += 4) { I2OSP(input[i], result, index); } I2OSP(input[intLen - 1], result, index, outLen - index); return result; } /** * Convert a byte array to an int array. * * @param input the byte array * @return the converted array */ public static int[] toIntArray(byte[] input) { int intLen = (input.length + 3) / 4; int lastLen = input.length & 0x03; int[] result = new int[intLen]; int index = 0; for (int i = 0; i <= intLen - 2; i++, index += 4) { result[i] = OS2IP(input, index); } if (lastLen != 0) { result[intLen - 1] = OS2IP(input, index, lastLen); } else { result[intLen - 1] = OS2IP(input, index); } return result; } } bouncycastle-1.49.orig/src/org/bouncycastle/pqc/math/linearalgebra/RandUtils.java0000644000175000017500000000100112105027307027543 0ustar ebourgebourgpackage org.bouncycastle.pqc.math.linearalgebra; import java.security.SecureRandom; public class RandUtils { static int nextInt(SecureRandom rand, int n) { if ((n & -n) == n) // i.e., n is a power of 2 { return (int)((n * (long)(rand.nextInt() >>> 1)) >> 31); } int bits, value; do { bits = rand.nextInt() >>> 1; value = bits % n; } while (bits - value + (n - 1) < 0); return value; } } bouncycastle-1.49.orig/src/org/bouncycastle/pqc/math/linearalgebra/GF2mVector.java0000644000175000017500000001405012043365070027567 0ustar ebourgebourgpackage org.bouncycastle.pqc.math.linearalgebra; /** * This class implements vectors over the finite field * GF(2m) for small m (i.e., * 1<m<32). It extends the abstract class {@link Vector}. */ public class GF2mVector extends Vector { /** * the finite field this vector is defined over */ private GF2mField field; /** * the element array */ private int[] vector; /** * creates the vector over GF(2^m) of given length and with elements from * array v (beginning at the first bit) * * @param field finite field * @param v array with elements of vector */ public GF2mVector(GF2mField field, byte[] v) { this.field = new GF2mField(field); // decode vector int d = 8; int count = 1; while (field.getDegree() > d) { count++; d += 8; } if ((v.length % count) != 0) { throw new IllegalArgumentException( "Byte array is not an encoded vector over the given finite field."); } length = v.length / count; vector = new int[length]; count = 0; for (int i = 0; i < vector.length; i++) { for (int j = 0; j < d; j += 8) { vector[i] |= (v[count++] & 0xff) << j; } if (!field.isElementOfThisField(vector[i])) { throw new IllegalArgumentException( "Byte array is not an encoded vector over the given finite field."); } } } /** * Create a new vector over GF(2m) of the given * length and element array. * * @param field the finite field GF(2m) * @param vector the element array */ public GF2mVector(GF2mField field, int[] vector) { this.field = field; length = vector.length; for (int i = vector.length - 1; i >= 0; i--) { if (!field.isElementOfThisField(vector[i])) { throw new ArithmeticException( "Element array is not specified over the given finite field."); } } this.vector = IntUtils.clone(vector); } /** * Copy constructor. * * @param other another {@link GF2mVector} */ public GF2mVector(GF2mVector other) { field = new GF2mField(other.field); length = other.length; vector = IntUtils.clone(other.vector); } /** * @return the finite field this vector is defined over */ public GF2mField getField() { return field; } /** * @return int[] form of this vector */ public int[] getIntArrayForm() { return IntUtils.clone(vector); } /** * @return a byte array encoding of this vector */ public byte[] getEncoded() { int d = 8; int count = 1; while (field.getDegree() > d) { count++; d += 8; } byte[] res = new byte[vector.length * count]; count = 0; for (int i = 0; i < vector.length; i++) { for (int j = 0; j < d; j += 8) { res[count++] = (byte)(vector[i] >>> j); } } return res; } /** * @return whether this is the zero vector (i.e., all elements are zero) */ public boolean isZero() { for (int i = vector.length - 1; i >= 0; i--) { if (vector[i] != 0) { return false; } } return true; } /** * Add another vector to this vector. Method is not yet implemented. * * @param addend the other vector * @return this + addend * @throws ArithmeticException if the other vector is not defined over the same field as * this vector. *

    * TODO: implement this method */ public Vector add(Vector addend) { throw new RuntimeException("not implemented"); } /** * Multiply this vector with a permutation. * * @param p the permutation * @return this*p = p*this */ public Vector multiply(Permutation p) { int[] pVec = p.getVector(); if (length != pVec.length) { throw new ArithmeticException( "permutation size and vector size mismatch"); } int[] result = new int[length]; for (int i = 0; i < pVec.length; i++) { result[i] = vector[pVec[i]]; } return new GF2mVector(field, result); } /** * Compare this vector with another object. * * @param other the other object * @return the result of the comparison */ public boolean equals(Object other) { if (!(other instanceof GF2mVector)) { return false; } GF2mVector otherVec = (GF2mVector)other; if (!field.equals(otherVec.field)) { return false; } return IntUtils.equals(vector, otherVec.vector); } /** * @return the hash code of this vector */ public int hashCode() { int hash = this.field.hashCode(); hash = hash * 31 + vector.hashCode(); return hash; } /** * @return a human readable form of this vector */ public String toString() { StringBuffer buf = new StringBuffer(); for (int i = 0; i < vector.length; i++) { for (int j = 0; j < field.getDegree(); j++) { int r = j & 0x1f; int bitMask = 1 << r; int coeff = vector[i] & bitMask; if (coeff != 0) { buf.append('1'); } else { buf.append('0'); } } buf.append(' '); } return buf.toString(); } } bouncycastle-1.49.orig/src/org/bouncycastle/pqc/math/linearalgebra/PolynomialRingGF2.java0000644000175000017500000001330512043365070031115 0ustar ebourgebourgpackage org.bouncycastle.pqc.math.linearalgebra; /** * This class describes operations with polynomials over finite field GF(2), i e * polynomial ring R = GF(2)[X]. All operations are defined only for polynomials * with degree <=32. For the polynomial representation the map f: R->Z, * poly(X)->poly(2) is used, where integers have the binary representation. For * example: X^7+X^3+X+1 -> (00...0010001011)=139 Also for polynomials type * Integer is used. * * @see GF2mField */ public final class PolynomialRingGF2 { /** * Default constructor (private). */ private PolynomialRingGF2() { // empty } /** * Return sum of two polyomials * * @param p polynomial * @param q polynomial * @return p+q */ public static int add(int p, int q) { return p ^ q; } /** * Return product of two polynomials * * @param p polynomial * @param q polynomial * @return p*q */ public static long multiply(int p, int q) { long result = 0; if (q != 0) { long q1 = q & 0x00000000ffffffffL; while (p != 0) { byte b = (byte)(p & 0x01); if (b == 1) { result ^= q1; } p >>>= 1; q1 <<= 1; } } return result; } /** * Compute the product of two polynomials modulo a third polynomial. * * @param a the first polynomial * @param b the second polynomial * @param r the reduction polynomial * @return a * b mod r */ public static int modMultiply(int a, int b, int r) { int result = 0; int p = remainder(a, r); int q = remainder(b, r); if (q != 0) { int d = 1 << degree(r); while (p != 0) { byte pMod2 = (byte)(p & 0x01); if (pMod2 == 1) { result ^= q; } p >>>= 1; q <<= 1; if (q >= d) { q ^= r; } } } return result; } /** * Return the degree of a polynomial * * @param p polynomial p * @return degree(p) */ public static int degree(int p) { int result = -1; while (p != 0) { result++; p >>>= 1; } return result; } /** * Return the degree of a polynomial * * @param p polynomial p * @return degree(p) */ public static int degree(long p) { int result = 0; while (p != 0) { result++; p >>>= 1; } return result - 1; } /** * Return the remainder of a polynomial division of two polynomials. * * @param p dividend * @param q divisor * @return p mod q */ public static int remainder(int p, int q) { int result = p; if (q == 0) { System.err.println("Error: to be divided by 0"); return 0; } while (degree(result) >= degree(q)) { result ^= q << (degree(result) - degree(q)); } return result; } /** * Return the rest of devision two polynomials * * @param p polinomial * @param q polinomial * @return p mod q */ public static int rest(long p, int q) { long p1 = p; if (q == 0) { System.err.println("Error: to be divided by 0"); return 0; } long q1 = q & 0x00000000ffffffffL; while ((p1 >>> 32) != 0) { p1 ^= q1 << (degree(p1) - degree(q1)); } int result = (int)(p1 & 0xffffffff); while (degree(result) >= degree(q)) { result ^= q << (degree(result) - degree(q)); } return result; } /** * Return the greatest common divisor of two polynomials * * @param p polinomial * @param q polinomial * @return GCD(p, q) */ public static int gcd(int p, int q) { int a, b, c; a = p; b = q; while (b != 0) { c = remainder(a, b); a = b; b = c; } return a; } /** * Checking polynomial for irreducibility * * @param p polinomial * @return true if p is irreducible and false otherwise */ public static boolean isIrreducible(int p) { if (p == 0) { return false; } int d = degree(p) >>> 1; int u = 2; for (int i = 0; i < d; i++) { u = modMultiply(u, u, p); if (gcd(u ^ 2, p) != 1) { return false; } } return true; } /** * Creates irreducible polynomial with degree d * * @param deg polynomial degree * @return irreducible polynomial p */ public static int getIrreduciblePolynomial(int deg) { if (deg < 0) { System.err.println("The Degree is negative"); return 0; } if (deg > 31) { System.err.println("The Degree is more then 31"); return 0; } if (deg == 0) { return 1; } int a = 1 << deg; a++; int b = 1 << (deg + 1); for (int i = a; i < b; i += 2) { if (isIrreducible(i)) { return i; } } return 0; } } bouncycastle-1.49.orig/src/org/bouncycastle/pqc/math/linearalgebra/GF2nPolynomialElement.java0000644000175000017500000007230012043365070031765 0ustar ebourgebourgpackage org.bouncycastle.pqc.math.linearalgebra; import java.math.BigInteger; import java.util.Random; /** * This class implements elements of finite binary fields GF(2n) * using polynomial representation. For more information on the arithmetic see * for example IEEE Standard 1363 or Certicom online-tutorial. * * @see "GF2nField" * @see GF2nPolynomialField * @see GF2nONBElement * @see GF2Polynomial */ public class GF2nPolynomialElement extends GF2nElement { // pre-computed Bitmask for fast masking, bitMask[a]=0x1 << a private static final int[] bitMask = {0x00000001, 0x00000002, 0x00000004, 0x00000008, 0x00000010, 0x00000020, 0x00000040, 0x00000080, 0x00000100, 0x00000200, 0x00000400, 0x00000800, 0x00001000, 0x00002000, 0x00004000, 0x00008000, 0x00010000, 0x00020000, 0x00040000, 0x00080000, 0x00100000, 0x00200000, 0x00400000, 0x00800000, 0x01000000, 0x02000000, 0x04000000, 0x08000000, 0x10000000, 0x20000000, 0x40000000, 0x80000000, 0x00000000}; // the used GF2Polynomial which stores the coefficients private GF2Polynomial polynomial; /** * Create a new random GF2nPolynomialElement using the given field and * source of randomness. * * @param f the GF2nField to use * @param rand the source of randomness */ public GF2nPolynomialElement(GF2nPolynomialField f, Random rand) { mField = f; mDegree = mField.getDegree(); polynomial = new GF2Polynomial(mDegree); randomize(rand); } /** * Creates a new GF2nPolynomialElement using the given field and Bitstring. * * @param f the GF2nPolynomialField to use * @param bs the desired value as Bitstring */ public GF2nPolynomialElement(GF2nPolynomialField f, GF2Polynomial bs) { mField = f; mDegree = mField.getDegree(); polynomial = new GF2Polynomial(bs); polynomial.expandN(mDegree); } /** * Creates a new GF2nPolynomialElement using the given field f and * byte[] os as value. The conversion is done according to 1363. * * @param f the GF2nField to use * @param os the octet string to assign to this GF2nPolynomialElement * @see "P1363 5.5.5 p23, OS2FEP/OS2BSP" */ public GF2nPolynomialElement(GF2nPolynomialField f, byte[] os) { mField = f; mDegree = mField.getDegree(); polynomial = new GF2Polynomial(mDegree, os); polynomial.expandN(mDegree); } /** * Creates a new GF2nPolynomialElement using the given field f and * int[] is as value. * * @param f the GF2nField to use * @param is the integer string to assign to this GF2nPolynomialElement */ public GF2nPolynomialElement(GF2nPolynomialField f, int[] is) { mField = f; mDegree = mField.getDegree(); polynomial = new GF2Polynomial(mDegree, is); polynomial.expandN(f.mDegree); } /** * Creates a new GF2nPolynomialElement by cloning the given * GF2nPolynomialElement b. * * @param other the GF2nPolynomialElement to clone */ public GF2nPolynomialElement(GF2nPolynomialElement other) { mField = other.mField; mDegree = other.mDegree; polynomial = new GF2Polynomial(other.polynomial); } // ///////////////////////////////////////////////////////////////////// // pseudo-constructors // ///////////////////////////////////////////////////////////////////// /** * Creates a new GF2nPolynomialElement by cloning this * GF2nPolynomialElement. * * @return a copy of this element */ public Object clone() { return new GF2nPolynomialElement(this); } // ///////////////////////////////////////////////////////////////////// // assignments // ///////////////////////////////////////////////////////////////////// /** * Assigns the value 'zero' to this Polynomial. */ void assignZero() { polynomial.assignZero(); } /** * Create the zero element. * * @param f the finite field * @return the zero element in the given finite field */ public static GF2nPolynomialElement ZERO(GF2nPolynomialField f) { GF2Polynomial polynomial = new GF2Polynomial(f.getDegree()); return new GF2nPolynomialElement(f, polynomial); } /** * Create the one element. * * @param f the finite field * @return the one element in the given finite field */ public static GF2nPolynomialElement ONE(GF2nPolynomialField f) { GF2Polynomial polynomial = new GF2Polynomial(f.getDegree(), new int[]{1}); return new GF2nPolynomialElement(f, polynomial); } /** * Assigns the value 'one' to this Polynomial. */ void assignOne() { polynomial.assignOne(); } /** * Assign a random value to this GF2nPolynomialElement using the specified * source of randomness. * * @param rand the source of randomness */ private void randomize(Random rand) { polynomial.expandN(mDegree); polynomial.randomize(rand); } // ///////////////////////////////////////////////////////////////////// // comparison // ///////////////////////////////////////////////////////////////////// /** * Checks whether this element is zero. * * @return true if this is the zero element */ public boolean isZero() { return polynomial.isZero(); } /** * Tests if the GF2nPolynomialElement has 'one' as value. * * @return true if this equals one (this == 1) */ public boolean isOne() { return polynomial.isOne(); } /** * Compare this element with another object. * * @param other the other object * @return true if the two objects are equal, false * otherwise */ public boolean equals(Object other) { if (other == null || !(other instanceof GF2nPolynomialElement)) { return false; } GF2nPolynomialElement otherElem = (GF2nPolynomialElement)other; if (mField != otherElem.mField) { if (!mField.getFieldPolynomial().equals( otherElem.mField.getFieldPolynomial())) { return false; } } return polynomial.equals(otherElem.polynomial); } /** * @return the hash code of this element */ public int hashCode() { return mField.hashCode() + polynomial.hashCode(); } // ///////////////////////////////////////////////////////////////////// // access // ///////////////////////////////////////////////////////////////////// /** * Returns the value of this GF2nPolynomialElement in a new Bitstring. * * @return the value of this GF2nPolynomialElement in a new Bitstring */ private GF2Polynomial getGF2Polynomial() { return new GF2Polynomial(polynomial); } /** * Checks whether the indexed bit of the bit representation is set. * * @param index the index of the bit to test * @return true if the indexed bit is set */ boolean testBit(int index) { return polynomial.testBit(index); } /** * Returns whether the rightmost bit of the bit representation is set. This * is needed for data conversion according to 1363. * * @return true if the rightmost bit of this element is set */ public boolean testRightmostBit() { return polynomial.testBit(0); } /** * Compute the sum of this element and addend. * * @param addend the addend * @return this + other (newly created) * @throws DifferentFieldsException if the elements are of different fields. */ public GFElement add(GFElement addend) throws RuntimeException { GF2nPolynomialElement result = new GF2nPolynomialElement(this); result.addToThis(addend); return result; } /** * Compute this + addend (overwrite this). * * @param addend the addend * @throws DifferentFieldsException if the elements are of different fields. */ public void addToThis(GFElement addend) throws RuntimeException { if (!(addend instanceof GF2nPolynomialElement)) { throw new RuntimeException(); } if (!mField.equals(((GF2nPolynomialElement)addend).mField)) { throw new RuntimeException(); } polynomial.addToThis(((GF2nPolynomialElement)addend).polynomial); } /** * Returns this element + 'one". * * @return this + 'one' */ public GF2nElement increase() { GF2nPolynomialElement result = new GF2nPolynomialElement(this); result.increaseThis(); return result; } /** * Increases this element by 'one'. */ public void increaseThis() { polynomial.increaseThis(); } /** * Compute the product of this element and factor. * * @param factor the factor * @return this * factor (newly created) * @throws DifferentFieldsException if the elements are of different fields. */ public GFElement multiply(GFElement factor) throws RuntimeException { GF2nPolynomialElement result = new GF2nPolynomialElement(this); result.multiplyThisBy(factor); return result; } /** * Compute this * factor (overwrite this). * * @param factor the factor * @throws DifferentFieldsException if the elements are of different fields. */ public void multiplyThisBy(GFElement factor) throws RuntimeException { if (!(factor instanceof GF2nPolynomialElement)) { throw new RuntimeException(); } if (!mField.equals(((GF2nPolynomialElement)factor).mField)) { throw new RuntimeException(); } if (equals(factor)) { squareThis(); return; } polynomial = polynomial .multiply(((GF2nPolynomialElement)factor).polynomial); reduceThis(); } /** * Compute the multiplicative inverse of this element. * * @return this-1 (newly created) * @throws ArithmeticException if this is the zero element. * @see GF2nPolynomialElement#invertMAIA * @see GF2nPolynomialElement#invertEEA * @see GF2nPolynomialElement#invertSquare */ public GFElement invert() throws ArithmeticException { return invertMAIA(); } /** * Calculates the multiplicative inverse of this and returns the * result in a new GF2nPolynomialElement. * * @return this^(-1) * @throws ArithmeticException if this equals zero */ public GF2nPolynomialElement invertEEA() throws ArithmeticException { if (isZero()) { throw new ArithmeticException(); } GF2Polynomial b = new GF2Polynomial(mDegree + 32, "ONE"); b.reduceN(); GF2Polynomial c = new GF2Polynomial(mDegree + 32); c.reduceN(); GF2Polynomial u = getGF2Polynomial(); GF2Polynomial v = mField.getFieldPolynomial(); GF2Polynomial h; int j; u.reduceN(); while (!u.isOne()) { u.reduceN(); v.reduceN(); j = u.getLength() - v.getLength(); if (j < 0) { h = u; u = v; v = h; h = b; b = c; c = h; j = -j; c.reduceN(); // this increases the performance } u.shiftLeftAddThis(v, j); b.shiftLeftAddThis(c, j); } b.reduceN(); return new GF2nPolynomialElement((GF2nPolynomialField)mField, b); } /** * Calculates the multiplicative inverse of this and returns the * result in a new GF2nPolynomialElement. * * @return this^(-1) * @throws ArithmeticException if this equals zero */ public GF2nPolynomialElement invertSquare() throws ArithmeticException { GF2nPolynomialElement n; GF2nPolynomialElement u; int i, j, k, b; if (isZero()) { throw new ArithmeticException(); } // b = (n-1) b = mField.getDegree() - 1; // n = a n = new GF2nPolynomialElement(this); n.polynomial.expandN((mDegree << 1) + 32); // increase performance n.polynomial.reduceN(); // k = 1 k = 1; // for i = (r-1) downto 0 do, r=bitlength(b) for (i = IntegerFunctions.floorLog(b) - 1; i >= 0; i--) { // u = n u = new GF2nPolynomialElement(n); // for j = 1 to k do for (j = 1; j <= k; j++) { // u = u^2 u.squareThisPreCalc(); } // n = nu n.multiplyThisBy(u); // k = 2k k <<= 1; // if b(i)==1 if ((b & bitMask[i]) != 0) { // n = n^2 * b n.squareThisPreCalc(); n.multiplyThisBy(this); // k = k+1 k += 1; } } // outpur n^2 n.squareThisPreCalc(); return n; } /** * Calculates the multiplicative inverse of this using the modified * almost inverse algorithm and returns the result in a new * GF2nPolynomialElement. * * @return this^(-1) * @throws ArithmeticException if this equals zero */ public GF2nPolynomialElement invertMAIA() throws ArithmeticException { if (isZero()) { throw new ArithmeticException(); } GF2Polynomial b = new GF2Polynomial(mDegree, "ONE"); GF2Polynomial c = new GF2Polynomial(mDegree); GF2Polynomial u = getGF2Polynomial(); GF2Polynomial v = mField.getFieldPolynomial(); GF2Polynomial h; while (true) { while (!u.testBit(0)) { // x|u (x divides u) u.shiftRightThis(); // u = u / x if (!b.testBit(0)) { b.shiftRightThis(); } else { b.addToThis(mField.getFieldPolynomial()); b.shiftRightThis(); } } if (u.isOne()) { return new GF2nPolynomialElement((GF2nPolynomialField)mField, b); } u.reduceN(); v.reduceN(); if (u.getLength() < v.getLength()) { h = u; u = v; v = h; h = b; b = c; c = h; } u.addToThis(v); b.addToThis(c); } } /** * This method is used internally to map the square()-calls within * GF2nPolynomialElement to one of the possible squaring methods. * * @return this2 (newly created) * @see GF2nPolynomialElement#squarePreCalc */ public GF2nElement square() { return squarePreCalc(); } /** * This method is used internally to map the square()-calls within * GF2nPolynomialElement to one of the possible squaring methods. */ public void squareThis() { squareThisPreCalc(); } /** * Squares this GF2nPolynomialElement using GF2nField's squaring matrix. * This is supposed to be fast when using a polynomial (no tri- or * pentanomial) as fieldpolynomial. Use squarePreCalc when using a tri- or * pentanomial as fieldpolynomial instead. * * @return this2 (newly created) * @see GF2Polynomial#vectorMult * @see GF2nPolynomialElement#squarePreCalc * @see GF2nPolynomialElement#squareBitwise */ public GF2nPolynomialElement squareMatrix() { GF2nPolynomialElement result = new GF2nPolynomialElement(this); result.squareThisMatrix(); result.reduceThis(); return result; } /** * Squares this GF2nPolynomialElement using GF2nFields squaring matrix. This * is supposed to be fast when using a polynomial (no tri- or pentanomial) * as fieldpolynomial. Use squarePreCalc when using a tri- or pentanomial as * fieldpolynomial instead. * * @see GF2Polynomial#vectorMult * @see GF2nPolynomialElement#squarePreCalc * @see GF2nPolynomialElement#squareBitwise */ public void squareThisMatrix() { GF2Polynomial result = new GF2Polynomial(mDegree); for (int i = 0; i < mDegree; i++) { if (polynomial .vectorMult(((GF2nPolynomialField)mField).squaringMatrix[mDegree - i - 1])) { result.setBit(i); } } polynomial = result; } /** * Squares this GF2nPolynomialElement by shifting left its Bitstring and * reducing. This is supposed to be the slowest method. Use squarePreCalc or * squareMatrix instead. * * @return this2 (newly created) * @see GF2nPolynomialElement#squareMatrix * @see GF2nPolynomialElement#squarePreCalc * @see GF2Polynomial#squareThisBitwise */ public GF2nPolynomialElement squareBitwise() { GF2nPolynomialElement result = new GF2nPolynomialElement(this); result.squareThisBitwise(); result.reduceThis(); return result; } /** * Squares this GF2nPolynomialElement by shifting left its Bitstring and * reducing. This is supposed to be the slowest method. Use squarePreCalc or * squareMatrix instead. * * @see GF2nPolynomialElement#squareMatrix * @see GF2nPolynomialElement#squarePreCalc * @see GF2Polynomial#squareThisBitwise */ public void squareThisBitwise() { polynomial.squareThisBitwise(); reduceThis(); } /** * Squares this GF2nPolynomialElement by using precalculated values and * reducing. This is supposed to de fastest when using a trinomial or * pentanomial as field polynomial. Use squareMatrix when using a ordinary * polynomial as field polynomial. * * @return this2 (newly created) * @see GF2nPolynomialElement#squareMatrix * @see GF2Polynomial#squareThisPreCalc */ public GF2nPolynomialElement squarePreCalc() { GF2nPolynomialElement result = new GF2nPolynomialElement(this); result.squareThisPreCalc(); result.reduceThis(); return result; } /** * Squares this GF2nPolynomialElement by using precalculated values and * reducing. This is supposed to de fastest when using a tri- or pentanomial * as fieldpolynomial. Use squareMatrix when using a ordinary polynomial as * fieldpolynomial. * * @see GF2nPolynomialElement#squareMatrix * @see GF2Polynomial#squareThisPreCalc */ public void squareThisPreCalc() { polynomial.squareThisPreCalc(); reduceThis(); } /** * Calculates this to the power of k and returns the result * in a new GF2nPolynomialElement. * * @param k the power * @return this^k in a new GF2nPolynomialElement */ public GF2nPolynomialElement power(int k) { if (k == 1) { return new GF2nPolynomialElement(this); } GF2nPolynomialElement result = GF2nPolynomialElement .ONE((GF2nPolynomialField)mField); if (k == 0) { return result; } GF2nPolynomialElement x = new GF2nPolynomialElement(this); x.polynomial.expandN((x.mDegree << 1) + 32); // increase performance x.polynomial.reduceN(); for (int i = 0; i < mDegree; i++) { if ((k & (1 << i)) != 0) { result.multiplyThisBy(x); } x.square(); } return result; } /** * Compute the square root of this element and return the result in a new * {@link GF2nPolynomialElement}. * * @return this1/2 (newly created) */ public GF2nElement squareRoot() { GF2nPolynomialElement result = new GF2nPolynomialElement(this); result.squareRootThis(); return result; } /** * Compute the square root of this element. */ public void squareRootThis() { // increase performance polynomial.expandN((mDegree << 1) + 32); polynomial.reduceN(); for (int i = 0; i < mField.getDegree() - 1; i++) { squareThis(); } } /** * Solves the quadratic equation z2 + z = this if * such a solution exists. This method returns one of the two possible * solutions. The other solution is z + 1. Use z.increase() to * compute this solution. * * @return a GF2nPolynomialElement representing one z satisfying the * equation z2 + z = this * @throws NoSolutionException if no solution exists * @see "IEEE 1363, Annex A.4.7" */ public GF2nElement solveQuadraticEquation() throws RuntimeException { if (isZero()) { return ZERO((GF2nPolynomialField)mField); } if ((mDegree & 1) == 1) { return halfTrace(); } // TODO this can be sped-up by precomputation of p and w's GF2nPolynomialElement z, w; do { // step 1. GF2nPolynomialElement p = new GF2nPolynomialElement( (GF2nPolynomialField)mField, new Random()); // step 2. z = ZERO((GF2nPolynomialField)mField); w = (GF2nPolynomialElement)p.clone(); // step 3. for (int i = 1; i < mDegree; i++) { // compute z = z^2 + w^2 * this // and w = w^2 + p z.squareThis(); w.squareThis(); z.addToThis(w.multiply(this)); w.addToThis(p); } } while (w.isZero()); // step 4. if (!equals(z.square().add(z))) { throw new RuntimeException(); } // step 5. return z; } /** * Returns the trace of this GF2nPolynomialElement. * * @return the trace of this GF2nPolynomialElement */ public int trace() { GF2nPolynomialElement t = new GF2nPolynomialElement(this); int i; for (i = 1; i < mDegree; i++) { t.squareThis(); t.addToThis(this); } if (t.isOne()) { return 1; } return 0; } /** * Returns the half-trace of this GF2nPolynomialElement. * * @return a GF2nPolynomialElement representing the half-trace of this * GF2nPolynomialElement. * @throws DegreeIsEvenException if the degree of this GF2nPolynomialElement is even. */ private GF2nPolynomialElement halfTrace() throws RuntimeException { if ((mDegree & 0x01) == 0) { throw new RuntimeException(); } int i; GF2nPolynomialElement h = new GF2nPolynomialElement(this); for (i = 1; i <= ((mDegree - 1) >> 1); i++) { h.squareThis(); h.squareThis(); h.addToThis(this); } return h; } /** * Reduces this GF2nPolynomialElement modulo the field-polynomial. * * @see GF2Polynomial#reduceTrinomial * @see GF2Polynomial#reducePentanomial */ private void reduceThis() { if (polynomial.getLength() > mDegree) { // really reduce ? if (((GF2nPolynomialField)mField).isTrinomial()) { // fieldpolonomial // is trinomial int tc; try { tc = ((GF2nPolynomialField)mField).getTc(); } catch (RuntimeException NATExc) { throw new RuntimeException( "GF2nPolynomialElement.reduce: the field" + " polynomial is not a trinomial"); } if (((mDegree - tc) <= 32) // do we have to use slow // bitwise reduction ? || (polynomial.getLength() > (mDegree << 1))) { reduceTrinomialBitwise(tc); return; } polynomial.reduceTrinomial(mDegree, tc); return; } else if (((GF2nPolynomialField)mField).isPentanomial()) { // fieldpolynomial // is // pentanomial int[] pc; try { pc = ((GF2nPolynomialField)mField).getPc(); } catch (RuntimeException NATExc) { throw new RuntimeException( "GF2nPolynomialElement.reduce: the field" + " polynomial is not a pentanomial"); } if (((mDegree - pc[2]) <= 32) // do we have to use slow // bitwise reduction ? || (polynomial.getLength() > (mDegree << 1))) { reducePentanomialBitwise(pc); return; } polynomial.reducePentanomial(mDegree, pc); return; } else { // fieldpolynomial is something else polynomial = polynomial.remainder(mField.getFieldPolynomial()); polynomial.expandN(mDegree); return; } } if (polynomial.getLength() < mDegree) { polynomial.expandN(mDegree); } } /** * Reduce this GF2nPolynomialElement using the trinomial x^n + x^tc + 1 as * fieldpolynomial. The coefficients are reduced bit by bit. */ private void reduceTrinomialBitwise(int tc) { int i; int k = mDegree - tc; for (i = polynomial.getLength() - 1; i >= mDegree; i--) { if (polynomial.testBit(i)) { polynomial.xorBit(i); polynomial.xorBit(i - k); polynomial.xorBit(i - mDegree); } } polynomial.reduceN(); polynomial.expandN(mDegree); } /** * Reduce this GF2nPolynomialElement using the pentanomial x^n + x^pc[2] + * x^pc[1] + x^pc[0] + 1 as fieldpolynomial. The coefficients are reduced * bit by bit. */ private void reducePentanomialBitwise(int[] pc) { int i; int k = mDegree - pc[2]; int l = mDegree - pc[1]; int m = mDegree - pc[0]; for (i = polynomial.getLength() - 1; i >= mDegree; i--) { if (polynomial.testBit(i)) { polynomial.xorBit(i); polynomial.xorBit(i - k); polynomial.xorBit(i - l); polynomial.xorBit(i - m); polynomial.xorBit(i - mDegree); } } polynomial.reduceN(); polynomial.expandN(mDegree); } // ///////////////////////////////////////////////////////////////////// // conversion // ///////////////////////////////////////////////////////////////////// /** * Returns a string representing this Bitstrings value using hexadecimal * radix in MSB-first order. * * @return a String representing this Bitstrings value. */ public String toString() { return polynomial.toString(16); } /** * Returns a string representing this Bitstrings value using hexadecimal or * binary radix in MSB-first order. * * @param radix the radix to use (2 or 16, otherwise 2 is used) * @return a String representing this Bitstrings value. */ public String toString(int radix) { return polynomial.toString(radix); } /** * Converts this GF2nPolynomialElement to a byte[] according to 1363. * * @return a byte[] representing the value of this GF2nPolynomialElement * @see "P1363 5.5.2 p22f BS2OSP, FE2OSP" */ public byte[] toByteArray() { return polynomial.toByteArray(); } /** * Converts this GF2nPolynomialElement to an integer according to 1363. * * @return a BigInteger representing the value of this * GF2nPolynomialElement * @see "P1363 5.5.1 p22 BS2IP" */ public BigInteger toFlexiBigInt() { return polynomial.toFlexiBigInt(); } } bouncycastle-1.49.orig/src/org/bouncycastle/pqc/math/linearalgebra/BigIntUtils.java0000644000175000017500000000726312043365070030056 0ustar ebourgebourgpackage org.bouncycastle.pqc.math.linearalgebra; import java.math.BigInteger; /** * FIXME: is this really necessary?! */ public final class BigIntUtils { /** * Default constructor (private). */ private BigIntUtils() { // empty } /** * Checks if two BigInteger arrays contain the same entries * * @param a first BigInteger array * @param b second BigInteger array * @return true or false */ public static boolean equals(BigInteger[] a, BigInteger[] b) { int flag = 0; if (a.length != b.length) { return false; } for (int i = 0; i < a.length; i++) { // avoid branches here! // problem: compareTo on BigIntegers is not // guaranteed constant-time! flag |= a[i].compareTo(b[i]); } return flag == 0; } /** * Fill the given BigInteger array with the given value. * * @param array the array * @param value the value */ public static void fill(BigInteger[] array, BigInteger value) { for (int i = array.length - 1; i >= 0; i--) { array[i] = value; } } /** * Generates a subarray of a given BigInteger array. * * @param input - * the input BigInteger array * @param start - * the start index * @param end - * the end index * @return a subarray of input, ranging from start to * end */ public static BigInteger[] subArray(BigInteger[] input, int start, int end) { BigInteger[] result = new BigInteger[end - start]; System.arraycopy(input, start, result, 0, end - start); return result; } /** * Converts a BigInteger array into an integer array * * @param input - * the BigInteger array * @return the integer array */ public static int[] toIntArray(BigInteger[] input) { int[] result = new int[input.length]; for (int i = 0; i < input.length; i++) { result[i] = input[i].intValue(); } return result; } /** * Converts a BigInteger array into an integer array, reducing all * BigIntegers mod q. * * @param q - * the modulus * @param input - * the BigInteger array * @return the integer array */ public static int[] toIntArrayModQ(int q, BigInteger[] input) { BigInteger bq = BigInteger.valueOf(q); int[] result = new int[input.length]; for (int i = 0; i < input.length; i++) { result[i] = input[i].mod(bq).intValue(); } return result; } /** * Return the value of big as a byte array. Although BigInteger * has such a method, it uses an extra bit to indicate the sign of the * number. For elliptic curve cryptography, the numbers usually are * positive. Thus, this helper method returns a byte array of minimal * length, ignoring the sign of the number. * * @param value the BigInteger value to be converted to a byte * array * @return the value big as byte array */ public static byte[] toMinimalByteArray(BigInteger value) { byte[] valBytes = value.toByteArray(); if ((valBytes.length == 1) || (value.bitLength() & 0x07) != 0) { return valBytes; } byte[] result = new byte[value.bitLength() >> 3]; System.arraycopy(valBytes, 1, result, 0, result.length); return result; } } bouncycastle-1.49.orig/src/org/bouncycastle/pqc/math/linearalgebra/IntUtils.java0000644000175000017500000001260612043365070027431 0ustar ebourgebourgpackage org.bouncycastle.pqc.math.linearalgebra; import java.math.BigInteger; /** * * * */ public final class IntUtils { /** * Default constructor (private). */ private IntUtils() { // empty } /** * Compare two int arrays. No null checks are performed. * * @param left the first int array * @param right the second int array * @return the result of the comparison */ public static boolean equals(int[] left, int[] right) { if (left.length != right.length) { return false; } boolean result = true; for (int i = left.length - 1; i >= 0; i--) { result &= left[i] == right[i]; } return result; } /** * Return a clone of the given int array. No null checks are performed. * * @param array the array to clone * @return the clone of the given array */ public static int[] clone(int[] array) { int[] result = new int[array.length]; System.arraycopy(array, 0, result, 0, array.length); return result; } /** * Fill the given int array with the given value. * * @param array the array * @param value the value */ public static void fill(int[] array, int value) { for (int i = array.length - 1; i >= 0; i--) { array[i] = value; } } /** * Sorts this array of integers according to the Quicksort algorithm. After * calling this method this array is sorted in ascending order with the * smallest integer taking position 0 in the array. *

    *

    * This implementation is based on the quicksort algorithm as described in * Data Structures In Java by Thomas A. Standish, Chapter 10, * ISBN 0-201-30564-X. * * @param source the array of integers that needs to be sorted. */ public static void quicksort(int[] source) { quicksort(source, 0, source.length - 1); } /** * Sort a subarray of a source array. The subarray is specified by its start * and end index. * * @param source the int array to be sorted * @param left the start index of the subarray * @param right the end index of the subarray */ public static void quicksort(int[] source, int left, int right) { if (right > left) { int index = partition(source, left, right, right); quicksort(source, left, index - 1); quicksort(source, index + 1, right); } } /** * Split a subarray of a source array into two partitions. The left * partition contains elements that have value less than or equal to the * pivot element, the right partition contains the elements that have larger * value. * * @param source the int array whose subarray will be splitted * @param left the start position of the subarray * @param right the end position of the subarray * @param pivotIndex the index of the pivot element inside the array * @return the new index of the pivot element inside the array */ private static int partition(int[] source, int left, int right, int pivotIndex) { int pivot = source[pivotIndex]; source[pivotIndex] = source[right]; source[right] = pivot; int index = left; for (int i = left; i < right; i++) { if (source[i] <= pivot) { int tmp = source[index]; source[index] = source[i]; source[i] = tmp; index++; } } int tmp = source[index]; source[index] = source[right]; source[right] = tmp; return index; } /** * Generates a subarray of a given int array. * * @param input - * the input int array * @param start - * the start index * @param end - * the end index * @return a subarray of input, ranging from start to * end */ public static int[] subArray(final int[] input, final int start, final int end) { int[] result = new int[end - start]; System.arraycopy(input, start, result, 0, end - start); return result; } /** * Convert an int array to a {@link FlexiBigInt} array. * * @param input the int array * @return the {@link FlexiBigInt} array */ public static BigInteger[] toFlexiBigIntArray(int[] input) { BigInteger[] result = new BigInteger[input.length]; for (int i = 0; i < input.length; i++) { result[i] = BigInteger.valueOf(input[i]); } return result; } /** * @param input an int array * @return a human readable form of the given int array */ public static String toString(int[] input) { String result = ""; for (int i = 0; i < input.length; i++) { result += input[i] + " "; } return result; } /** * @param input an int arary * @return the int array as hex string */ public static String toHexString(int[] input) { return ByteUtils.toHexString(BigEndianConversions.toByteArray(input)); } } bouncycastle-1.49.orig/src/org/bouncycastle/pqc/math/linearalgebra/GF2Polynomial.java0000644000175000017500000016366112043365070030310 0ustar ebourgebourgpackage org.bouncycastle.pqc.math.linearalgebra; import java.math.BigInteger; import java.util.Random; /** * This class stores very long strings of bits and does some basic arithmetics. * It is used by GF2nField, GF2nPolynomialField and * GFnPolynomialElement. * * @see GF2nPolynomialElement * @see GF2nField */ public class GF2Polynomial { // number of bits stored in this GF2Polynomial private int len; // number of int used in value private int blocks; // storage private int[] value; // Random source private static Random rand = new Random(); // Lookup-Table for vectorMult: parity[a]= #1(a) mod 2 == 1 private static final boolean[] parity = {false, true, true, false, true, false, false, true, true, false, false, true, false, true, true, false, true, false, false, true, false, true, true, false, false, true, true, false, true, false, false, true, true, false, false, true, false, true, true, false, false, true, true, false, true, false, false, true, false, true, true, false, true, false, false, true, true, false, false, true, false, true, true, false, true, false, false, true, false, true, true, false, false, true, true, false, true, false, false, true, false, true, true, false, true, false, false, true, true, false, false, true, false, true, true, false, false, true, true, false, true, false, false, true, true, false, false, true, false, true, true, false, true, false, false, true, false, true, true, false, false, true, true, false, true, false, false, true, true, false, false, true, false, true, true, false, false, true, true, false, true, false, false, true, false, true, true, false, true, false, false, true, true, false, false, true, false, true, true, false, false, true, true, false, true, false, false, true, true, false, false, true, false, true, true, false, true, false, false, true, false, true, true, false, false, true, true, false, true, false, false, true, false, true, true, false, true, false, false, true, true, false, false, true, false, true, true, false, true, false, false, true, false, true, true, false, false, true, true, false, true, false, false, true, true, false, false, true, false, true, true, false, false, true, true, false, true, false, false, true, false, true, true, false, true, false, false, true, true, false, false, true, false, true, true, false}; // Lookup-Table for Squaring: squaringTable[a]=a^2 private static final short[] squaringTable = {0x0000, 0x0001, 0x0004, 0x0005, 0x0010, 0x0011, 0x0014, 0x0015, 0x0040, 0x0041, 0x0044, 0x0045, 0x0050, 0x0051, 0x0054, 0x0055, 0x0100, 0x0101, 0x0104, 0x0105, 0x0110, 0x0111, 0x0114, 0x0115, 0x0140, 0x0141, 0x0144, 0x0145, 0x0150, 0x0151, 0x0154, 0x0155, 0x0400, 0x0401, 0x0404, 0x0405, 0x0410, 0x0411, 0x0414, 0x0415, 0x0440, 0x0441, 0x0444, 0x0445, 0x0450, 0x0451, 0x0454, 0x0455, 0x0500, 0x0501, 0x0504, 0x0505, 0x0510, 0x0511, 0x0514, 0x0515, 0x0540, 0x0541, 0x0544, 0x0545, 0x0550, 0x0551, 0x0554, 0x0555, 0x1000, 0x1001, 0x1004, 0x1005, 0x1010, 0x1011, 0x1014, 0x1015, 0x1040, 0x1041, 0x1044, 0x1045, 0x1050, 0x1051, 0x1054, 0x1055, 0x1100, 0x1101, 0x1104, 0x1105, 0x1110, 0x1111, 0x1114, 0x1115, 0x1140, 0x1141, 0x1144, 0x1145, 0x1150, 0x1151, 0x1154, 0x1155, 0x1400, 0x1401, 0x1404, 0x1405, 0x1410, 0x1411, 0x1414, 0x1415, 0x1440, 0x1441, 0x1444, 0x1445, 0x1450, 0x1451, 0x1454, 0x1455, 0x1500, 0x1501, 0x1504, 0x1505, 0x1510, 0x1511, 0x1514, 0x1515, 0x1540, 0x1541, 0x1544, 0x1545, 0x1550, 0x1551, 0x1554, 0x1555, 0x4000, 0x4001, 0x4004, 0x4005, 0x4010, 0x4011, 0x4014, 0x4015, 0x4040, 0x4041, 0x4044, 0x4045, 0x4050, 0x4051, 0x4054, 0x4055, 0x4100, 0x4101, 0x4104, 0x4105, 0x4110, 0x4111, 0x4114, 0x4115, 0x4140, 0x4141, 0x4144, 0x4145, 0x4150, 0x4151, 0x4154, 0x4155, 0x4400, 0x4401, 0x4404, 0x4405, 0x4410, 0x4411, 0x4414, 0x4415, 0x4440, 0x4441, 0x4444, 0x4445, 0x4450, 0x4451, 0x4454, 0x4455, 0x4500, 0x4501, 0x4504, 0x4505, 0x4510, 0x4511, 0x4514, 0x4515, 0x4540, 0x4541, 0x4544, 0x4545, 0x4550, 0x4551, 0x4554, 0x4555, 0x5000, 0x5001, 0x5004, 0x5005, 0x5010, 0x5011, 0x5014, 0x5015, 0x5040, 0x5041, 0x5044, 0x5045, 0x5050, 0x5051, 0x5054, 0x5055, 0x5100, 0x5101, 0x5104, 0x5105, 0x5110, 0x5111, 0x5114, 0x5115, 0x5140, 0x5141, 0x5144, 0x5145, 0x5150, 0x5151, 0x5154, 0x5155, 0x5400, 0x5401, 0x5404, 0x5405, 0x5410, 0x5411, 0x5414, 0x5415, 0x5440, 0x5441, 0x5444, 0x5445, 0x5450, 0x5451, 0x5454, 0x5455, 0x5500, 0x5501, 0x5504, 0x5505, 0x5510, 0x5511, 0x5514, 0x5515, 0x5540, 0x5541, 0x5544, 0x5545, 0x5550, 0x5551, 0x5554, 0x5555}; // pre-computed Bitmask for fast masking, bitMask[a]=0x1 << a private static final int[] bitMask = {0x00000001, 0x00000002, 0x00000004, 0x00000008, 0x00000010, 0x00000020, 0x00000040, 0x00000080, 0x00000100, 0x00000200, 0x00000400, 0x00000800, 0x00001000, 0x00002000, 0x00004000, 0x00008000, 0x00010000, 0x00020000, 0x00040000, 0x00080000, 0x00100000, 0x00200000, 0x00400000, 0x00800000, 0x01000000, 0x02000000, 0x04000000, 0x08000000, 0x10000000, 0x20000000, 0x40000000, 0x80000000, 0x00000000}; // pre-computed Bitmask for fast masking, rightMask[a]=0xffffffff >>> (32-a) private static final int[] reverseRightMask = {0x00000000, 0x00000001, 0x00000003, 0x00000007, 0x0000000f, 0x0000001f, 0x0000003f, 0x0000007f, 0x000000ff, 0x000001ff, 0x000003ff, 0x000007ff, 0x00000fff, 0x00001fff, 0x00003fff, 0x00007fff, 0x0000ffff, 0x0001ffff, 0x0003ffff, 0x0007ffff, 0x000fffff, 0x001fffff, 0x003fffff, 0x007fffff, 0x00ffffff, 0x01ffffff, 0x03ffffff, 0x07ffffff, 0x0fffffff, 0x1fffffff, 0x3fffffff, 0x7fffffff, 0xffffffff}; /** * Creates a new GF2Polynomial of the given length and value zero. * * @param length the desired number of bits to store */ public GF2Polynomial(int length) { int l = length; if (l < 1) { l = 1; } blocks = ((l - 1) >> 5) + 1; value = new int[blocks]; len = l; } /** * Creates a new GF2Polynomial of the given length and random value. * * @param length the desired number of bits to store * @param rand SecureRandom to use for randomization */ public GF2Polynomial(int length, Random rand) { int l = length; if (l < 1) { l = 1; } blocks = ((l - 1) >> 5) + 1; value = new int[blocks]; len = l; randomize(rand); } /** * Creates a new GF2Polynomial of the given length and value * selected by value: *

      *
    • ZERO
    • *
    • ONE
    • *
    • RANDOM
    • *
    • X
    • *
    • ALL
    • *
    * * @param length the desired number of bits to store * @param value the value described by a String */ public GF2Polynomial(int length, String value) { int l = length; if (l < 1) { l = 1; } blocks = ((l - 1) >> 5) + 1; this.value = new int[blocks]; len = l; if (value.equalsIgnoreCase("ZERO")) { assignZero(); } else if (value.equalsIgnoreCase("ONE")) { assignOne(); } else if (value.equalsIgnoreCase("RANDOM")) { randomize(); } else if (value.equalsIgnoreCase("X")) { assignX(); } else if (value.equalsIgnoreCase("ALL")) { assignAll(); } else { throw new IllegalArgumentException( "Error: GF2Polynomial was called using " + value + " as value!"); } } /** * Creates a new GF2Polynomial of the given length using the given * int[]. LSB is contained in bs[0]. * * @param length the desired number of bits to store * @param bs contains the desired value, LSB in bs[0] */ public GF2Polynomial(int length, int[] bs) { int leng = length; if (leng < 1) { leng = 1; } blocks = ((leng - 1) >> 5) + 1; value = new int[blocks]; len = leng; int l = Math.min(blocks, bs.length); System.arraycopy(bs, 0, value, 0, l); zeroUnusedBits(); } /** * Creates a new GF2Polynomial by converting the given byte[] os * according to 1363 and using the given length. * * @param length the intended length of this polynomial * @param os the octet string to assign to this polynomial * @see "P1363 5.5.2 p22f, OS2BSP" */ public GF2Polynomial(int length, byte[] os) { int l = length; if (l < 1) { l = 1; } blocks = ((l - 1) >> 5) + 1; value = new int[blocks]; len = l; int i, m; int k = Math.min(((os.length - 1) >> 2) + 1, blocks); for (i = 0; i < k - 1; i++) { m = os.length - (i << 2) - 1; value[i] = (os[m]) & 0x000000ff; value[i] |= (os[m - 1] << 8) & 0x0000ff00; value[i] |= (os[m - 2] << 16) & 0x00ff0000; value[i] |= (os[m - 3] << 24) & 0xff000000; } i = k - 1; m = os.length - (i << 2) - 1; value[i] = os[m] & 0x000000ff; if (m > 0) { value[i] |= (os[m - 1] << 8) & 0x0000ff00; } if (m > 1) { value[i] |= (os[m - 2] << 16) & 0x00ff0000; } if (m > 2) { value[i] |= (os[m - 3] << 24) & 0xff000000; } zeroUnusedBits(); reduceN(); } /** * Creates a new GF2Polynomial by converting the given FlexiBigInt bi * according to 1363 and using the given length. * * @param length the intended length of this polynomial * @param bi the FlexiBigInt to assign to this polynomial * @see "P1363 5.5.1 p22, I2BSP" */ public GF2Polynomial(int length, BigInteger bi) { int l = length; if (l < 1) { l = 1; } blocks = ((l - 1) >> 5) + 1; value = new int[blocks]; len = l; int i; byte[] val = bi.toByteArray(); if (val[0] == 0) { byte[] dummy = new byte[val.length - 1]; System.arraycopy(val, 1, dummy, 0, dummy.length); val = dummy; } int ov = val.length & 0x03; int k = ((val.length - 1) >> 2) + 1; for (i = 0; i < ov; i++) { value[k - 1] |= (val[i] & 0x000000ff) << ((ov - 1 - i) << 3); } int m = 0; for (i = 0; i <= (val.length - 4) >> 2; i++) { m = val.length - 1 - (i << 2); value[i] = (val[m]) & 0x000000ff; value[i] |= ((val[m - 1]) << 8) & 0x0000ff00; value[i] |= ((val[m - 2]) << 16) & 0x00ff0000; value[i] |= ((val[m - 3]) << 24) & 0xff000000; } if ((len & 0x1f) != 0) { value[blocks - 1] &= reverseRightMask[len & 0x1f]; } reduceN(); } /** * Creates a new GF2Polynomial by cloneing the given GF2Polynomial b. * * @param b the GF2Polynomial to clone */ public GF2Polynomial(GF2Polynomial b) { len = b.len; blocks = b.blocks; value = IntUtils.clone(b.value); } /** * @return a copy of this GF2Polynomial */ public Object clone() { return new GF2Polynomial(this); } /** * Returns the length of this GF2Polynomial. The length can be greater than * the degree. To get the degree call reduceN() before calling getLength(). * * @return the length of this GF2Polynomial */ public int getLength() { return len; } /** * Returns the value of this GF2Polynomial in an int[]. * * @return the value of this GF2Polynomial in a new int[], LSB in int[0] */ public int[] toIntegerArray() { int[] result; result = new int[blocks]; System.arraycopy(value, 0, result, 0, blocks); return result; } /** * Returns a string representing this GF2Polynomials value using hexadecimal * or binary radix in MSB-first order. * * @param radix the radix to use (2 or 16, otherwise 2 is used) * @return a String representing this GF2Polynomials value. */ public String toString(int radix) { final char[] HEX_CHARS = {'0', '1', '2', '3', '4', '5', '6', '7', '8', '9', 'a', 'b', 'c', 'd', 'e', 'f'}; final String[] BIN_CHARS = {"0000", "0001", "0010", "0011", "0100", "0101", "0110", "0111", "1000", "1001", "1010", "1011", "1100", "1101", "1110", "1111"}; String res; int i; res = new String(); if (radix == 16) { for (i = blocks - 1; i >= 0; i--) { res += HEX_CHARS[(value[i] >>> 28) & 0x0f]; res += HEX_CHARS[(value[i] >>> 24) & 0x0f]; res += HEX_CHARS[(value[i] >>> 20) & 0x0f]; res += HEX_CHARS[(value[i] >>> 16) & 0x0f]; res += HEX_CHARS[(value[i] >>> 12) & 0x0f]; res += HEX_CHARS[(value[i] >>> 8) & 0x0f]; res += HEX_CHARS[(value[i] >>> 4) & 0x0f]; res += HEX_CHARS[(value[i]) & 0x0f]; res += " "; } } else { for (i = blocks - 1; i >= 0; i--) { res += BIN_CHARS[(value[i] >>> 28) & 0x0f]; res += BIN_CHARS[(value[i] >>> 24) & 0x0f]; res += BIN_CHARS[(value[i] >>> 20) & 0x0f]; res += BIN_CHARS[(value[i] >>> 16) & 0x0f]; res += BIN_CHARS[(value[i] >>> 12) & 0x0f]; res += BIN_CHARS[(value[i] >>> 8) & 0x0f]; res += BIN_CHARS[(value[i] >>> 4) & 0x0f]; res += BIN_CHARS[(value[i]) & 0x0f]; res += " "; } } return res; } /** * Converts this polynomial to a byte[] (octet string) according to 1363. * * @return a byte[] representing the value of this polynomial * @see "P1363 5.5.2 p22f, BS2OSP" */ public byte[] toByteArray() { int k = ((len - 1) >> 3) + 1; int ov = k & 0x03; int m; byte[] res = new byte[k]; int i; for (i = 0; i < (k >> 2); i++) { m = k - (i << 2) - 1; res[m] = (byte)((value[i] & 0x000000ff)); res[m - 1] = (byte)((value[i] & 0x0000ff00) >>> 8); res[m - 2] = (byte)((value[i] & 0x00ff0000) >>> 16); res[m - 3] = (byte)((value[i] & 0xff000000) >>> 24); } for (i = 0; i < ov; i++) { m = (ov - i - 1) << 3; res[i] = (byte)((value[blocks - 1] & (0x000000ff << m)) >>> m); } return res; } /** * Converts this polynomial to an integer according to 1363. * * @return a FlexiBigInt representing the value of this polynomial * @see "P1363 5.5.1 p22, BS2IP" */ public BigInteger toFlexiBigInt() { if (len == 0 || isZero()) { return new BigInteger(0, new byte[0]); } return new BigInteger(1, toByteArray()); } /** * Sets the LSB to 1 and all other to 0, assigning 'one' to this * GF2Polynomial. */ public void assignOne() { int i; for (i = 1; i < blocks; i++) { value[i] = 0x00; } value[0] = 0x01; } /** * Sets Bit 1 to 1 and all other to 0, assigning 'x' to this GF2Polynomial. */ public void assignX() { int i; for (i = 1; i < blocks; i++) { value[i] = 0x00; } value[0] = 0x02; } /** * Sets all Bits to 1. */ public void assignAll() { int i; for (i = 0; i < blocks; i++) { value[i] = 0xffffffff; } zeroUnusedBits(); } /** * Resets all bits to zero. */ public void assignZero() { int i; for (i = 0; i < blocks; i++) { value[i] = 0x00; } } /** * Fills all len bits of this GF2Polynomial with random values. */ public void randomize() { int i; for (i = 0; i < blocks; i++) { value[i] = rand.nextInt(); } zeroUnusedBits(); } /** * Fills all len bits of this GF2Polynomial with random values using the * specified source of randomness. * * @param rand the source of randomness */ public void randomize(Random rand) { int i; for (i = 0; i < blocks; i++) { value[i] = rand.nextInt(); } zeroUnusedBits(); } /** * Returns true if two GF2Polynomials have the same size and value and thus * are equal. * * @param other the other GF2Polynomial * @return true if this GF2Polynomial equals b (this == * b) */ public boolean equals(Object other) { if (other == null || !(other instanceof GF2Polynomial)) { return false; } GF2Polynomial otherPol = (GF2Polynomial)other; if (len != otherPol.len) { return false; } for (int i = 0; i < blocks; i++) { if (value[i] != otherPol.value[i]) { return false; } } return true; } /** * @return the hash code of this polynomial */ public int hashCode() { return len + value.hashCode(); } /** * Tests if all bits equal zero. * * @return true if this GF2Polynomial equals 'zero' (this == 0) */ public boolean isZero() { int i; if (len == 0) { return true; } for (i = 0; i < blocks; i++) { if (value[i] != 0) { return false; } } return true; } /** * Tests if all bits are reset to 0 and LSB is set to 1. * * @return true if this GF2Polynomial equals 'one' (this == 1) */ public boolean isOne() { int i; for (i = 1; i < blocks; i++) { if (value[i] != 0) { return false; } } if (value[0] != 0x01) { return false; } return true; } /** * Adds b to this GF2Polynomial and assigns the result to this * GF2Polynomial. b can be of different size. * * @param b GF2Polynomial to add to this GF2Polynomial */ public void addToThis(GF2Polynomial b) { expandN(b.len); xorThisBy(b); } /** * Adds two GF2Polynomials, this and b, and returns the * result. this and b can be of different size. * * @param b a GF2Polynomial * @return a new GF2Polynomial (this + b) */ public GF2Polynomial add(GF2Polynomial b) { return xor(b); } /** * Subtracts b from this GF2Polynomial and assigns the result to * this GF2Polynomial. b can be of different size. * * @param b a GF2Polynomial */ public void subtractFromThis(GF2Polynomial b) { expandN(b.len); xorThisBy(b); } /** * Subtracts two GF2Polynomials, this and b, and returns the * result in a new GF2Polynomial. this and b can be of * different size. * * @param b a GF2Polynomial * @return a new GF2Polynomial (this - b) */ public GF2Polynomial subtract(GF2Polynomial b) { return xor(b); } /** * Toggles the LSB of this GF2Polynomial, increasing its value by 'one'. */ public void increaseThis() { xorBit(0); } /** * Toggles the LSB of this GF2Polynomial, increasing the value by 'one' and * returns the result in a new GF2Polynomial. * * @return this + 1 */ public GF2Polynomial increase() { GF2Polynomial result = new GF2Polynomial(this); result.increaseThis(); return result; } /** * Multiplies this GF2Polynomial with b and returns the result in a * new GF2Polynomial. This method does not reduce the result in GF(2^N). * This method uses classic multiplication (schoolbook). * * @param b a GF2Polynomial * @return a new GF2Polynomial (this * b) */ public GF2Polynomial multiplyClassic(GF2Polynomial b) { GF2Polynomial result = new GF2Polynomial(Math.max(len, b.len) << 1); GF2Polynomial[] m = new GF2Polynomial[32]; int i, j; m[0] = new GF2Polynomial(this); for (i = 1; i <= 31; i++) { m[i] = m[i - 1].shiftLeft(); } for (i = 0; i < b.blocks; i++) { for (j = 0; j <= 31; j++) { if ((b.value[i] & bitMask[j]) != 0) { result.xorThisBy(m[j]); } } for (j = 0; j <= 31; j++) { m[j].shiftBlocksLeft(); } } return result; } /** * Multiplies this GF2Polynomial with b and returns the result in a * new GF2Polynomial. This method does not reduce the result in GF(2^N). * This method uses Karatzuba multiplication. * * @param b a GF2Polynomial * @return a new GF2Polynomial (this * b) */ public GF2Polynomial multiply(GF2Polynomial b) { int n = Math.max(len, b.len); expandN(n); b.expandN(n); return karaMult(b); } /** * Does the recursion for Karatzuba multiplication. */ private GF2Polynomial karaMult(GF2Polynomial b) { GF2Polynomial result = new GF2Polynomial(len << 1); if (len <= 32) { result.value = mult32(value[0], b.value[0]); return result; } if (len <= 64) { result.value = mult64(value, b.value); return result; } if (len <= 128) { result.value = mult128(value, b.value); return result; } if (len <= 256) { result.value = mult256(value, b.value); return result; } if (len <= 512) { result.value = mult512(value, b.value); return result; } int n = IntegerFunctions.floorLog(len - 1); n = bitMask[n]; GF2Polynomial a0 = lower(((n - 1) >> 5) + 1); GF2Polynomial a1 = upper(((n - 1) >> 5) + 1); GF2Polynomial b0 = b.lower(((n - 1) >> 5) + 1); GF2Polynomial b1 = b.upper(((n - 1) >> 5) + 1); GF2Polynomial c = a1.karaMult(b1); // c = a1*b1 GF2Polynomial e = a0.karaMult(b0); // e = a0*b0 a0.addToThis(a1); // a0 = a0 + a1 b0.addToThis(b1); // b0 = b0 + b1 GF2Polynomial d = a0.karaMult(b0); // d = (a0+a1)*(b0+b1) result.shiftLeftAddThis(c, n << 1); result.shiftLeftAddThis(c, n); result.shiftLeftAddThis(d, n); result.shiftLeftAddThis(e, n); result.addToThis(e); return result; } /** * 16-Integer Version of Karatzuba multiplication. */ private static int[] mult512(int[] a, int[] b) { int[] result = new int[32]; int[] a0 = new int[8]; System.arraycopy(a, 0, a0, 0, Math.min(8, a.length)); int[] a1 = new int[8]; if (a.length > 8) { System.arraycopy(a, 8, a1, 0, Math.min(8, a.length - 8)); } int[] b0 = new int[8]; System.arraycopy(b, 0, b0, 0, Math.min(8, b.length)); int[] b1 = new int[8]; if (b.length > 8) { System.arraycopy(b, 8, b1, 0, Math.min(8, b.length - 8)); } int[] c = mult256(a1, b1); result[31] ^= c[15]; result[30] ^= c[14]; result[29] ^= c[13]; result[28] ^= c[12]; result[27] ^= c[11]; result[26] ^= c[10]; result[25] ^= c[9]; result[24] ^= c[8]; result[23] ^= c[7] ^ c[15]; result[22] ^= c[6] ^ c[14]; result[21] ^= c[5] ^ c[13]; result[20] ^= c[4] ^ c[12]; result[19] ^= c[3] ^ c[11]; result[18] ^= c[2] ^ c[10]; result[17] ^= c[1] ^ c[9]; result[16] ^= c[0] ^ c[8]; result[15] ^= c[7]; result[14] ^= c[6]; result[13] ^= c[5]; result[12] ^= c[4]; result[11] ^= c[3]; result[10] ^= c[2]; result[9] ^= c[1]; result[8] ^= c[0]; a1[0] ^= a0[0]; a1[1] ^= a0[1]; a1[2] ^= a0[2]; a1[3] ^= a0[3]; a1[4] ^= a0[4]; a1[5] ^= a0[5]; a1[6] ^= a0[6]; a1[7] ^= a0[7]; b1[0] ^= b0[0]; b1[1] ^= b0[1]; b1[2] ^= b0[2]; b1[3] ^= b0[3]; b1[4] ^= b0[4]; b1[5] ^= b0[5]; b1[6] ^= b0[6]; b1[7] ^= b0[7]; int[] d = mult256(a1, b1); result[23] ^= d[15]; result[22] ^= d[14]; result[21] ^= d[13]; result[20] ^= d[12]; result[19] ^= d[11]; result[18] ^= d[10]; result[17] ^= d[9]; result[16] ^= d[8]; result[15] ^= d[7]; result[14] ^= d[6]; result[13] ^= d[5]; result[12] ^= d[4]; result[11] ^= d[3]; result[10] ^= d[2]; result[9] ^= d[1]; result[8] ^= d[0]; int[] e = mult256(a0, b0); result[23] ^= e[15]; result[22] ^= e[14]; result[21] ^= e[13]; result[20] ^= e[12]; result[19] ^= e[11]; result[18] ^= e[10]; result[17] ^= e[9]; result[16] ^= e[8]; result[15] ^= e[7] ^ e[15]; result[14] ^= e[6] ^ e[14]; result[13] ^= e[5] ^ e[13]; result[12] ^= e[4] ^ e[12]; result[11] ^= e[3] ^ e[11]; result[10] ^= e[2] ^ e[10]; result[9] ^= e[1] ^ e[9]; result[8] ^= e[0] ^ e[8]; result[7] ^= e[7]; result[6] ^= e[6]; result[5] ^= e[5]; result[4] ^= e[4]; result[3] ^= e[3]; result[2] ^= e[2]; result[1] ^= e[1]; result[0] ^= e[0]; return result; } /** * 8-Integer Version of Karatzuba multiplication. */ private static int[] mult256(int[] a, int[] b) { int[] result = new int[16]; int[] a0 = new int[4]; System.arraycopy(a, 0, a0, 0, Math.min(4, a.length)); int[] a1 = new int[4]; if (a.length > 4) { System.arraycopy(a, 4, a1, 0, Math.min(4, a.length - 4)); } int[] b0 = new int[4]; System.arraycopy(b, 0, b0, 0, Math.min(4, b.length)); int[] b1 = new int[4]; if (b.length > 4) { System.arraycopy(b, 4, b1, 0, Math.min(4, b.length - 4)); } if (a1[3] == 0 && a1[2] == 0 && b1[3] == 0 && b1[2] == 0) { if (a1[1] == 0 && b1[1] == 0) { if (a1[0] != 0 || b1[0] != 0) { // [3]=[2]=[1]=0, [0]!=0 int[] c = mult32(a1[0], b1[0]); result[9] ^= c[1]; result[8] ^= c[0]; result[5] ^= c[1]; result[4] ^= c[0]; } } else { // [3]=[2]=0 [1]!=0, [0]!=0 int[] c = mult64(a1, b1); result[11] ^= c[3]; result[10] ^= c[2]; result[9] ^= c[1]; result[8] ^= c[0]; result[7] ^= c[3]; result[6] ^= c[2]; result[5] ^= c[1]; result[4] ^= c[0]; } } else { // [3]!=0 [2]!=0 [1]!=0, [0]!=0 int[] c = mult128(a1, b1); result[15] ^= c[7]; result[14] ^= c[6]; result[13] ^= c[5]; result[12] ^= c[4]; result[11] ^= c[3] ^ c[7]; result[10] ^= c[2] ^ c[6]; result[9] ^= c[1] ^ c[5]; result[8] ^= c[0] ^ c[4]; result[7] ^= c[3]; result[6] ^= c[2]; result[5] ^= c[1]; result[4] ^= c[0]; } a1[0] ^= a0[0]; a1[1] ^= a0[1]; a1[2] ^= a0[2]; a1[3] ^= a0[3]; b1[0] ^= b0[0]; b1[1] ^= b0[1]; b1[2] ^= b0[2]; b1[3] ^= b0[3]; int[] d = mult128(a1, b1); result[11] ^= d[7]; result[10] ^= d[6]; result[9] ^= d[5]; result[8] ^= d[4]; result[7] ^= d[3]; result[6] ^= d[2]; result[5] ^= d[1]; result[4] ^= d[0]; int[] e = mult128(a0, b0); result[11] ^= e[7]; result[10] ^= e[6]; result[9] ^= e[5]; result[8] ^= e[4]; result[7] ^= e[3] ^ e[7]; result[6] ^= e[2] ^ e[6]; result[5] ^= e[1] ^ e[5]; result[4] ^= e[0] ^ e[4]; result[3] ^= e[3]; result[2] ^= e[2]; result[1] ^= e[1]; result[0] ^= e[0]; return result; } /** * 4-Integer Version of Karatzuba multiplication. */ private static int[] mult128(int[] a, int[] b) { int[] result = new int[8]; int[] a0 = new int[2]; System.arraycopy(a, 0, a0, 0, Math.min(2, a.length)); int[] a1 = new int[2]; if (a.length > 2) { System.arraycopy(a, 2, a1, 0, Math.min(2, a.length - 2)); } int[] b0 = new int[2]; System.arraycopy(b, 0, b0, 0, Math.min(2, b.length)); int[] b1 = new int[2]; if (b.length > 2) { System.arraycopy(b, 2, b1, 0, Math.min(2, b.length - 2)); } if (a1[1] == 0 && b1[1] == 0) { if (a1[0] != 0 || b1[0] != 0) { int[] c = mult32(a1[0], b1[0]); result[5] ^= c[1]; result[4] ^= c[0]; result[3] ^= c[1]; result[2] ^= c[0]; } } else { int[] c = mult64(a1, b1); result[7] ^= c[3]; result[6] ^= c[2]; result[5] ^= c[1] ^ c[3]; result[4] ^= c[0] ^ c[2]; result[3] ^= c[1]; result[2] ^= c[0]; } a1[0] ^= a0[0]; a1[1] ^= a0[1]; b1[0] ^= b0[0]; b1[1] ^= b0[1]; if (a1[1] == 0 && b1[1] == 0) { int[] d = mult32(a1[0], b1[0]); result[3] ^= d[1]; result[2] ^= d[0]; } else { int[] d = mult64(a1, b1); result[5] ^= d[3]; result[4] ^= d[2]; result[3] ^= d[1]; result[2] ^= d[0]; } if (a0[1] == 0 && b0[1] == 0) { int[] e = mult32(a0[0], b0[0]); result[3] ^= e[1]; result[2] ^= e[0]; result[1] ^= e[1]; result[0] ^= e[0]; } else { int[] e = mult64(a0, b0); result[5] ^= e[3]; result[4] ^= e[2]; result[3] ^= e[1] ^ e[3]; result[2] ^= e[0] ^ e[2]; result[1] ^= e[1]; result[0] ^= e[0]; } return result; } /** * 2-Integer Version of Karatzuba multiplication. */ private static int[] mult64(int[] a, int[] b) { int[] result = new int[4]; int a0 = a[0]; int a1 = 0; if (a.length > 1) { a1 = a[1]; } int b0 = b[0]; int b1 = 0; if (b.length > 1) { b1 = b[1]; } if (a1 != 0 || b1 != 0) { int[] c = mult32(a1, b1); result[3] ^= c[1]; result[2] ^= c[0] ^ c[1]; result[1] ^= c[0]; } int[] d = mult32(a0 ^ a1, b0 ^ b1); result[2] ^= d[1]; result[1] ^= d[0]; int[] e = mult32(a0, b0); result[2] ^= e[1]; result[1] ^= e[0] ^ e[1]; result[0] ^= e[0]; return result; } /** * 4-Byte Version of Karatzuba multiplication. Here the actual work is done. */ private static int[] mult32(int a, int b) { int[] result = new int[2]; if (a == 0 || b == 0) { return result; } long b2 = b; b2 &= 0x00000000ffffffffL; int i; long h = 0; for (i = 1; i <= 32; i++) { if ((a & bitMask[i - 1]) != 0) { h ^= b2; } b2 <<= 1; } result[1] = (int)(h >>> 32); result[0] = (int)(h & 0x00000000ffffffffL); return result; } /** * Returns a new GF2Polynomial containing the upper k bytes of this * GF2Polynomial. * * @param k * @return a new GF2Polynomial containing the upper k bytes of this * GF2Polynomial * @see GF2Polynomial#karaMult */ private GF2Polynomial upper(int k) { int j = Math.min(k, blocks - k); GF2Polynomial result = new GF2Polynomial(j << 5); if (blocks >= k) { System.arraycopy(value, k, result.value, 0, j); } return result; } /** * Returns a new GF2Polynomial containing the lower k bytes of this * GF2Polynomial. * * @param k * @return a new GF2Polynomial containing the lower k bytes of this * GF2Polynomial * @see GF2Polynomial#karaMult */ private GF2Polynomial lower(int k) { GF2Polynomial result = new GF2Polynomial(k << 5); System.arraycopy(value, 0, result.value, 0, Math.min(k, blocks)); return result; } /** * Returns the remainder of this divided by g in a new * GF2Polynomial. * * @param g GF2Polynomial != 0 * @return a new GF2Polynomial (this % g) * @throws PolynomialIsZeroException if g equals zero */ public GF2Polynomial remainder(GF2Polynomial g) throws RuntimeException { /* a div b = q / r */ GF2Polynomial a = new GF2Polynomial(this); GF2Polynomial b = new GF2Polynomial(g); GF2Polynomial j; int i; if (b.isZero()) { throw new RuntimeException(); } a.reduceN(); b.reduceN(); if (a.len < b.len) { return a; } i = a.len - b.len; while (i >= 0) { j = b.shiftLeft(i); a.subtractFromThis(j); a.reduceN(); i = a.len - b.len; } return a; } /** * Returns the absolute quotient of this divided by g in a * new GF2Polynomial. * * @param g GF2Polynomial != 0 * @return a new GF2Polynomial |_ this / g _| * @throws PolynomialIsZeroException if g equals zero */ public GF2Polynomial quotient(GF2Polynomial g) throws RuntimeException { /* a div b = q / r */ GF2Polynomial q = new GF2Polynomial(len); GF2Polynomial a = new GF2Polynomial(this); GF2Polynomial b = new GF2Polynomial(g); GF2Polynomial j; int i; if (b.isZero()) { throw new RuntimeException(); } a.reduceN(); b.reduceN(); if (a.len < b.len) { return new GF2Polynomial(0); } i = a.len - b.len; q.expandN(i + 1); while (i >= 0) { j = b.shiftLeft(i); a.subtractFromThis(j); a.reduceN(); q.xorBit(i); i = a.len - b.len; } return q; } /** * Divides this by g and returns the quotient and remainder * in a new GF2Polynomial[2], quotient in [0], remainder in [1]. * * @param g GF2Polynomial != 0 * @return a new GF2Polynomial[2] containing quotient and remainder * @throws PolynomialIsZeroException if g equals zero */ public GF2Polynomial[] divide(GF2Polynomial g) throws RuntimeException { /* a div b = q / r */ GF2Polynomial[] result = new GF2Polynomial[2]; GF2Polynomial q = new GF2Polynomial(len); GF2Polynomial a = new GF2Polynomial(this); GF2Polynomial b = new GF2Polynomial(g); GF2Polynomial j; int i; if (b.isZero()) { throw new RuntimeException(); } a.reduceN(); b.reduceN(); if (a.len < b.len) { result[0] = new GF2Polynomial(0); result[1] = a; return result; } i = a.len - b.len; q.expandN(i + 1); while (i >= 0) { j = b.shiftLeft(i); a.subtractFromThis(j); a.reduceN(); q.xorBit(i); i = a.len - b.len; } result[0] = q; result[1] = a; return result; } /** * Returns the greatest common divisor of this and g in a * new GF2Polynomial. * * @param g GF2Polynomial != 0 * @return a new GF2Polynomial gcd(this,g) * @throws ArithmeticException if this and g both are equal to zero * @throws PolynomialIsZeroException to be API-compliant (should never be thrown). */ public GF2Polynomial gcd(GF2Polynomial g) throws RuntimeException { if (isZero() && g.isZero()) { throw new ArithmeticException("Both operands of gcd equal zero."); } if (isZero()) { return new GF2Polynomial(g); } if (g.isZero()) { return new GF2Polynomial(this); } GF2Polynomial a = new GF2Polynomial(this); GF2Polynomial b = new GF2Polynomial(g); GF2Polynomial c; while (!b.isZero()) { c = a.remainder(b); a = b; b = c; } return a; } /** * Checks if this is irreducible, according to IEEE P1363, A.5.5, * p103.
    * Note: The algorithm from IEEE P1363, A5.5 can be used to check a * polynomial with coefficients in GF(2^r) for irreducibility. As this class * only represents polynomials with coefficients in GF(2), the algorithm is * adapted to the case r=1. * * @return true if this is irreducible * @see "P1363, A.5.5, p103" */ public boolean isIrreducible() { if (isZero()) { return false; } GF2Polynomial f = new GF2Polynomial(this); int d, i; GF2Polynomial u, g; GF2Polynomial dummy; f.reduceN(); d = f.len - 1; u = new GF2Polynomial(f.len, "X"); for (i = 1; i <= (d >> 1); i++) { u.squareThisPreCalc(); u = u.remainder(f); dummy = u.add(new GF2Polynomial(32, "X")); if (!dummy.isZero()) { g = f.gcd(dummy); if (!g.isOne()) { return false; } } else { return false; } } return true; } /** * Reduces this GF2Polynomial using the trinomial x^m + x^tc + * 1. * * @param m the degree of the used field * @param tc degree of the middle x in the trinomial */ void reduceTrinomial(int m, int tc) { int i; int p0, p1; int q0, q1; long t; p0 = m >>> 5; // block which contains 2^m q0 = 32 - (m & 0x1f); // (32-index) of 2^m within block p0 p1 = (m - tc) >>> 5; // block which contains 2^tc q1 = 32 - ((m - tc) & 0x1f); // (32-index) of 2^tc within block q1 int max = ((m << 1) - 2) >>> 5; // block which contains 2^(2m-2) int min = p0; // block which contains 2^m for (i = max; i > min; i--) { // for i = maxBlock to minBlock // reduce coefficients contained in t // t = block[i] t = value[i] & 0x00000000ffffffffL; // block[i-p0-1] ^= t << q0 value[i - p0 - 1] ^= (int)(t << q0); // block[i-p0] ^= t >>> (32-q0) value[i - p0] ^= t >>> (32 - q0); // block[i-p1-1] ^= << q1 value[i - p1 - 1] ^= (int)(t << q1); // block[i-p1] ^= t >>> (32-q1) value[i - p1] ^= t >>> (32 - q1); value[i] = 0x00; } // reduce last coefficients in block containing 2^m t = value[min] & 0x00000000ffffffffL & (0xffffffffL << (m & 0x1f)); // t // contains the last coefficients > m value[0] ^= t >>> (32 - q0); if (min - p1 - 1 >= 0) { value[min - p1 - 1] ^= (int)(t << q1); } value[min - p1] ^= t >>> (32 - q1); value[min] &= reverseRightMask[m & 0x1f]; blocks = ((m - 1) >>> 5) + 1; len = m; } /** * Reduces this GF2Polynomial using the pentanomial x^m + x^pc[2] + * x^pc[1] + x^pc[0] + 1. * * @param m the degree of the used field * @param pc degrees of the middle x's in the pentanomial */ void reducePentanomial(int m, int[] pc) { int i; int p0, p1, p2, p3; int q0, q1, q2, q3; long t; p0 = m >>> 5; q0 = 32 - (m & 0x1f); p1 = (m - pc[0]) >>> 5; q1 = 32 - ((m - pc[0]) & 0x1f); p2 = (m - pc[1]) >>> 5; q2 = 32 - ((m - pc[1]) & 0x1f); p3 = (m - pc[2]) >>> 5; q3 = 32 - ((m - pc[2]) & 0x1f); int max = ((m << 1) - 2) >>> 5; int min = p0; for (i = max; i > min; i--) { t = value[i] & 0x00000000ffffffffL; value[i - p0 - 1] ^= (int)(t << q0); value[i - p0] ^= t >>> (32 - q0); value[i - p1 - 1] ^= (int)(t << q1); value[i - p1] ^= t >>> (32 - q1); value[i - p2 - 1] ^= (int)(t << q2); value[i - p2] ^= t >>> (32 - q2); value[i - p3 - 1] ^= (int)(t << q3); value[i - p3] ^= t >>> (32 - q3); value[i] = 0; } t = value[min] & 0x00000000ffffffffL & (0xffffffffL << (m & 0x1f)); value[0] ^= t >>> (32 - q0); if (min - p1 - 1 >= 0) { value[min - p1 - 1] ^= (int)(t << q1); } value[min - p1] ^= t >>> (32 - q1); if (min - p2 - 1 >= 0) { value[min - p2 - 1] ^= (int)(t << q2); } value[min - p2] ^= t >>> (32 - q2); if (min - p3 - 1 >= 0) { value[min - p3 - 1] ^= (int)(t << q3); } value[min - p3] ^= t >>> (32 - q3); value[min] &= reverseRightMask[m & 0x1f]; blocks = ((m - 1) >>> 5) + 1; len = m; } /** * Reduces len by finding the most significant bit set to one and reducing * len and blocks. */ public void reduceN() { int i, j, h; i = blocks - 1; while ((value[i] == 0) && (i > 0)) { i--; } h = value[i]; j = 0; while (h != 0) { h >>>= 1; j++; } len = (i << 5) + j; blocks = i + 1; } /** * Expands len and int[] value to i. This is useful before adding * two GF2Polynomials of different size. * * @param i the intended length */ public void expandN(int i) { int k; int[] bs; if (len >= i) { return; } len = i; k = ((i - 1) >>> 5) + 1; if (blocks >= k) { return; } if (value.length >= k) { int j; for (j = blocks; j < k; j++) { value[j] = 0; } blocks = k; return; } bs = new int[k]; System.arraycopy(value, 0, bs, 0, blocks); blocks = k; value = null; value = bs; } /** * Squares this GF2Polynomial and expands it accordingly. This method does * not reduce the result in GF(2^N). There exists a faster method for * squaring in GF(2^N). * * @see GF2nPolynomialElement#square */ public void squareThisBitwise() { int i, h, j, k; if (isZero()) { return; } int[] result = new int[blocks << 1]; for (i = blocks - 1; i >= 0; i--) { h = value[i]; j = 0x00000001; for (k = 0; k < 16; k++) { if ((h & 0x01) != 0) { result[i << 1] |= j; } if ((h & 0x00010000) != 0) { result[(i << 1) + 1] |= j; } j <<= 2; h >>>= 1; } } value = null; value = result; blocks = result.length; len = (len << 1) - 1; } /** * Squares this GF2Polynomial by using precomputed values of squaringTable. * This method does not reduce the result in GF(2^N). */ public void squareThisPreCalc() { int i; if (isZero()) { return; } if (value.length >= (blocks << 1)) { for (i = blocks - 1; i >= 0; i--) { value[(i << 1) + 1] = GF2Polynomial.squaringTable[(value[i] & 0x00ff0000) >>> 16] | (GF2Polynomial.squaringTable[(value[i] & 0xff000000) >>> 24] << 16); value[i << 1] = GF2Polynomial.squaringTable[value[i] & 0x000000ff] | (GF2Polynomial.squaringTable[(value[i] & 0x0000ff00) >>> 8] << 16); } blocks <<= 1; len = (len << 1) - 1; } else { int[] result = new int[blocks << 1]; for (i = 0; i < blocks; i++) { result[i << 1] = GF2Polynomial.squaringTable[value[i] & 0x000000ff] | (GF2Polynomial.squaringTable[(value[i] & 0x0000ff00) >>> 8] << 16); result[(i << 1) + 1] = GF2Polynomial.squaringTable[(value[i] & 0x00ff0000) >>> 16] | (GF2Polynomial.squaringTable[(value[i] & 0xff000000) >>> 24] << 16); } value = null; value = result; blocks <<= 1; len = (len << 1) - 1; } } /** * Does a vector-multiplication modulo 2 and returns the result as boolean. * * @param b GF2Polynomial * @return this x b as boolean (1->true, 0->false) * @throws PolynomialsHaveDifferentLengthException if this and b have a different length and * thus cannot be vector-multiplied */ public boolean vectorMult(GF2Polynomial b) throws RuntimeException { int i; int h; boolean result = false; if (len != b.len) { throw new RuntimeException(); } for (i = 0; i < blocks; i++) { h = value[i] & b.value[i]; result ^= parity[h & 0x000000ff]; result ^= parity[(h >>> 8) & 0x000000ff]; result ^= parity[(h >>> 16) & 0x000000ff]; result ^= parity[(h >>> 24) & 0x000000ff]; } return result; } /** * Returns the bitwise exclusive-or of this and b in a new * GF2Polynomial. this and b can be of different size. * * @param b GF2Polynomial * @return a new GF2Polynomial (this ^ b) */ public GF2Polynomial xor(GF2Polynomial b) { int i; GF2Polynomial result; int k = Math.min(blocks, b.blocks); if (len >= b.len) { result = new GF2Polynomial(this); for (i = 0; i < k; i++) { result.value[i] ^= b.value[i]; } } else { result = new GF2Polynomial(b); for (i = 0; i < k; i++) { result.value[i] ^= value[i]; } } // If we xor'ed some bits too many by proceeding blockwise, // restore them to zero: result.zeroUnusedBits(); return result; } /** * Computes the bitwise exclusive-or of this GF2Polynomial and b and * stores the result in this GF2Polynomial. b can be of different * size. * * @param b GF2Polynomial */ public void xorThisBy(GF2Polynomial b) { int i; for (i = 0; i < Math.min(blocks, b.blocks); i++) { value[i] ^= b.value[i]; } // If we xor'ed some bits too many by proceeding blockwise, // restore them to zero: zeroUnusedBits(); } /** * If {@link #len} is not a multiple of the block size (32), some extra bits * of the last block might have been modified during a blockwise operation. * This method compensates for that by restoring these "extra" bits to zero. */ private void zeroUnusedBits() { if ((len & 0x1f) != 0) { value[blocks - 1] &= reverseRightMask[len & 0x1f]; } } /** * Sets the bit at position i. * * @param i int * @throws BitDoesNotExistException if (i < 0) || (i > (len - 1)) */ public void setBit(int i) throws RuntimeException { if (i < 0 || i > (len - 1)) { throw new RuntimeException(); } if (i > (len - 1)) { return; } value[i >>> 5] |= bitMask[i & 0x1f]; return; } /** * Returns the bit at position i. * * @param i int * @return the bit at position i if i is a valid position, 0 * otherwise. */ public int getBit(int i) { if (i < 0 || i > (len - 1)) { return 0; } return ((value[i >>> 5] & bitMask[i & 0x1f]) != 0) ? 1 : 0; } /** * Resets the bit at position i. * * @param i int * @throws BitDoesNotExistException if (i < 0) || (i > (len - 1)) */ public void resetBit(int i) throws RuntimeException { if (i < 0 || i > (len - 1)) { throw new RuntimeException(); } if (i > (len - 1)) { return; } value[i >>> 5] &= ~bitMask[i & 0x1f]; } /** * Xors the bit at position i. * * @param i int * @throws BitDoesNotExistException if (i < 0) || (i > (len - 1)) */ public void xorBit(int i) throws RuntimeException { if (i < 0 || i > (len - 1)) { throw new RuntimeException(); } if (i > (len - 1)) { return; } value[i >>> 5] ^= bitMask[i & 0x1f]; } /** * Tests the bit at position i. * * @param i the position of the bit to be tested * @return true if the bit at position i is set (a(i) == * 1). False if (i < 0) || (i > (len - 1)) */ public boolean testBit(int i) { if (i < 0 || i > (len - 1)) { return false; } return (value[i >>> 5] & bitMask[i & 0x1f]) != 0; } /** * Returns this GF2Polynomial shift-left by 1 in a new GF2Polynomial. * * @return a new GF2Polynomial (this << 1) */ public GF2Polynomial shiftLeft() { GF2Polynomial result = new GF2Polynomial(len + 1, value); int i; for (i = result.blocks - 1; i >= 1; i--) { result.value[i] <<= 1; result.value[i] |= result.value[i - 1] >>> 31; } result.value[0] <<= 1; return result; } /** * Shifts-left this by one and enlarges the size of value if necesary. */ public void shiftLeftThis() { /** @todo This is untested. */ int i; if ((len & 0x1f) == 0) { // check if blocks increases len += 1; blocks += 1; if (blocks > value.length) { // enlarge value int[] bs = new int[blocks]; System.arraycopy(value, 0, bs, 0, value.length); value = null; value = bs; } for (i = blocks - 1; i >= 1; i--) { value[i] |= value[i - 1] >>> 31; value[i - 1] <<= 1; } } else { len += 1; for (i = blocks - 1; i >= 1; i--) { value[i] <<= 1; value[i] |= value[i - 1] >>> 31; } value[0] <<= 1; } } /** * Returns this GF2Polynomial shift-left by k in a new * GF2Polynomial. * * @param k int * @return a new GF2Polynomial (this << k) */ public GF2Polynomial shiftLeft(int k) { // Variant 2, requiring a modified shiftBlocksLeft(k) // In case of modification, consider a rename to doShiftBlocksLeft() // with an explicit note that this method assumes that the polynomial // has already been resized. Or consider doing things inline. // Construct the resulting polynomial of appropriate length: GF2Polynomial result = new GF2Polynomial(len + k, value); // Shift left as many multiples of the block size as possible: if (k >= 32) { result.doShiftBlocksLeft(k >>> 5); } // Shift left by the remaining (<32) amount: final int remaining = k & 0x1f; if (remaining != 0) { for (int i = result.blocks - 1; i >= 1; i--) { result.value[i] <<= remaining; result.value[i] |= result.value[i - 1] >>> (32 - remaining); } result.value[0] <<= remaining; } return result; } /** * Shifts left b and adds the result to Its a fast version of * this = add(b.shl(k)); * * @param b GF2Polynomial to shift and add to this * @param k the amount to shift * @see GF2nPolynomialElement#invertEEA */ public void shiftLeftAddThis(GF2Polynomial b, int k) { if (k == 0) { addToThis(b); return; } int i; expandN(b.len + k); int d = k >>> 5; for (i = b.blocks - 1; i >= 0; i--) { if ((i + d + 1 < blocks) && ((k & 0x1f) != 0)) { value[i + d + 1] ^= b.value[i] >>> (32 - (k & 0x1f)); } value[i + d] ^= b.value[i] << (k & 0x1f); } } /** * Shifts-left this GF2Polynomial's value blockwise 1 block resulting in a * shift-left by 32. * * @see GF2Polynomial#multiply */ void shiftBlocksLeft() { blocks += 1; len += 32; if (blocks <= value.length) { int i; for (i = blocks - 1; i >= 1; i--) { value[i] = value[i - 1]; } value[0] = 0x00; } else { int[] result = new int[blocks]; System.arraycopy(value, 0, result, 1, blocks - 1); value = null; value = result; } } /** * Shifts left this GF2Polynomial's value blockwise b blocks * resulting in a shift-left by b*32. This method assumes that {@link #len} * and {@link #blocks} have already been updated to reflect the final state. * * @param b shift amount (in blocks) */ private void doShiftBlocksLeft(int b) { if (blocks <= value.length) { int i; for (i = blocks - 1; i >= b; i--) { value[i] = value[i - b]; } for (i = 0; i < b; i++) { value[i] = 0x00; } } else { int[] result = new int[blocks]; System.arraycopy(value, 0, result, b, blocks - b); value = null; value = result; } } /** * Returns this GF2Polynomial shift-right by 1 in a new GF2Polynomial. * * @return a new GF2Polynomial (this << 1) */ public GF2Polynomial shiftRight() { GF2Polynomial result = new GF2Polynomial(len - 1); int i; System.arraycopy(value, 0, result.value, 0, result.blocks); for (i = 0; i <= result.blocks - 2; i++) { result.value[i] >>>= 1; result.value[i] |= result.value[i + 1] << 31; } result.value[result.blocks - 1] >>>= 1; if (result.blocks < blocks) { result.value[result.blocks - 1] |= value[result.blocks] << 31; } return result; } /** * Shifts-right this GF2Polynomial by 1. */ public void shiftRightThis() { int i; len -= 1; blocks = ((len - 1) >>> 5) + 1; for (i = 0; i <= blocks - 2; i++) { value[i] >>>= 1; value[i] |= value[i + 1] << 31; } value[blocks - 1] >>>= 1; if ((len & 0x1f) == 0) { value[blocks - 1] |= value[blocks] << 31; } } } bouncycastle-1.49.orig/src/org/bouncycastle/pqc/math/linearalgebra/GF2nElement.java0000644000175000017500000001225212043365070027721 0ustar ebourgebourgpackage org.bouncycastle.pqc.math.linearalgebra; /** * This abstract class implements an element of the finite field GF(2)n * in either optimal normal basis representation (ONB) * or in polynomial representation. It is extended by the classes GF2nONBElement and GF2nPolynomialElement . * * @see GF2nPolynomialElement * @see GF2nONBElement * @see GF2nONBField */ public abstract class GF2nElement implements GFElement { // ///////////////////////////////////////////////////////////////////// // member variables // ///////////////////////////////////////////////////////////////////// /** * holds a pointer to this element's corresponding field. */ protected GF2nField mField; /** * holds the extension degree n of this element's corresponding * field. */ protected int mDegree; // ///////////////////////////////////////////////////////////////////// // pseudo-constructors // ///////////////////////////////////////////////////////////////////// /** * @return a copy of this GF2nElement */ public abstract Object clone(); // ///////////////////////////////////////////////////////////////////// // assignments // ///////////////////////////////////////////////////////////////////// /** * Assign the value 0 to this element. */ abstract void assignZero(); /** * Assigns the value 1 to this element. */ abstract void assignOne(); // ///////////////////////////////////////////////////////////////////// // access // ///////////////////////////////////////////////////////////////////// /** * Returns whether the rightmost bit of the bit representation is set. This * is needed for data conversion according to 1363. * * @return true if the rightmost bit of this element is set */ public abstract boolean testRightmostBit(); /** * Checks whether the indexed bit of the bit representation is set * * @param index the index of the bit to test * @return true if the indexed bit is set */ abstract boolean testBit(int index); /** * Returns the field of this element. * * @return the field of this element */ public final GF2nField getField() { return mField; } // ///////////////////////////////////////////////////////////////////// // arithmetic // ///////////////////////////////////////////////////////////////////// /** * Returns this element + 1. * * @return this + 1 */ public abstract GF2nElement increase(); /** * Increases this element by one. */ public abstract void increaseThis(); /** * Compute the difference of this element and minuend. * * @param minuend the minuend * @return this - minuend (newly created) * @throws DifferentFieldsException if the elements are of different fields. */ public final GFElement subtract(GFElement minuend) throws RuntimeException { return add(minuend); } /** * Compute the difference of this element and minuend, * overwriting this element. * * @param minuend the minuend * @throws DifferentFieldsException if the elements are of different fields. */ public final void subtractFromThis(GFElement minuend) { addToThis(minuend); } /** * Returns this element to the power of 2. * * @return this2 */ public abstract GF2nElement square(); /** * Squares this element. */ public abstract void squareThis(); /** * Compute the square root of this element and return the result in a new * {@link GF2nElement}. * * @return this1/2 (newly created) */ public abstract GF2nElement squareRoot(); /** * Compute the square root of this element. */ public abstract void squareRootThis(); /** * Performs a basis transformation of this element to the given GF2nField * basis. * * @param basis the GF2nField representation to transform this element to * @return this element in the representation of basis * @throws DifferentFieldsException if this cannot be converted according to * basis. */ public final GF2nElement convert(GF2nField basis) throws RuntimeException { return mField.convert(this, basis); } /** * Returns the trace of this element. * * @return the trace of this element */ public abstract int trace(); /** * Solves a quadratic equation.
    * Let z2 + z = this. Then this method returns z. * * @return z with z2 + z = this * @throws NoSolutionException if z2 + z = this does not have a * solution */ public abstract GF2nElement solveQuadraticEquation() throws RuntimeException; } bouncycastle-1.49.orig/src/org/bouncycastle/pqc/math/linearalgebra/GF2Vector.java0000644000175000017500000003171212105027307027413 0ustar ebourgebourgpackage org.bouncycastle.pqc.math.linearalgebra; import java.security.SecureRandom; /** * This class implements the abstract class Vector for the case of * vectors over the finite field GF(2).
    * For the vector representation the array of type int[] is used, thus one * element of the array holds 32 elements of the vector. * * @see Vector */ public class GF2Vector extends Vector { /** * holds the elements of this vector */ private int[] v; /** * Construct the zero vector of the given length. * * @param length the length of the vector */ public GF2Vector(int length) { if (length < 0) { throw new ArithmeticException("Negative length."); } this.length = length; v = new int[(length + 31) >> 5]; } /** * Construct a random GF2Vector of the given length. * * @param length the length of the vector * @param sr the source of randomness */ public GF2Vector(int length, SecureRandom sr) { this.length = length; int size = (length + 31) >> 5; v = new int[size]; // generate random elements for (int i = size - 1; i >= 0; i--) { v[i] = sr.nextInt(); } // erase unused bits int r = length & 0x1f; if (r != 0) { // erase unused bits v[size - 1] &= (1 << r) - 1; } } /** * Construct a random GF2Vector of the given length with the specified * number of non-zero coefficients. * * @param length the length of the vector * @param t the number of non-zero coefficients * @param sr the source of randomness */ public GF2Vector(int length, int t, SecureRandom sr) { if (t > length) { throw new ArithmeticException( "The hamming weight is greater than the length of vector."); } this.length = length; int size = (length + 31) >> 5; v = new int[size]; int[] help = new int[length]; for (int i = 0; i < length; i++) { help[i] = i; } int m = length; for (int i = 0; i < t; i++) { int j = RandUtils.nextInt(sr, m); setBit(help[j]); m--; help[j] = help[m]; } } /** * Construct a GF2Vector of the given length and with elements from the * given array. The array is copied and unused bits are masked out. * * @param length the length of the vector * @param v the element array */ public GF2Vector(int length, int[] v) { if (length < 0) { throw new ArithmeticException("negative length"); } this.length = length; int size = (length + 31) >> 5; if (v.length != size) { throw new ArithmeticException("length mismatch"); } this.v = IntUtils.clone(v); int r = length & 0x1f; if (r != 0) { // erase unused bits this.v[size - 1] &= (1 << r) - 1; } } /** * Copy constructor. * * @param other another {@link GF2Vector} */ public GF2Vector(GF2Vector other) { this.length = other.length; this.v = IntUtils.clone(other.v); } /** * Construct a new {@link GF2Vector} of the given length and with the given * element array. The array is not changed and only a reference to the array * is stored. No length checking is performed either. * * @param v the element array * @param length the length of the vector */ protected GF2Vector(int[] v, int length) { this.v = v; this.length = length; } /** * Construct a new GF2Vector with the given length out of the encoded * vector. * * @param length the length of the vector * @param encVec the encoded vector * @return the decoded vector */ public static GF2Vector OS2VP(int length, byte[] encVec) { if (length < 0) { throw new ArithmeticException("negative length"); } int byteLen = (length + 7) >> 3; if (encVec.length > byteLen) { throw new ArithmeticException("length mismatch"); } return new GF2Vector(length, LittleEndianConversions.toIntArray(encVec)); } /** * Encode this vector as byte array. * * @return the encoded vector */ public byte[] getEncoded() { int byteLen = (length + 7) >> 3; return LittleEndianConversions.toByteArray(v, byteLen); } /** * @return the int array representation of this vector */ public int[] getVecArray() { return v; } /** * Return the Hamming weight of this vector, i.e., compute the number of * units of this vector. * * @return the Hamming weight of this vector */ public int getHammingWeight() { int weight = 0; for (int i = 0; i < v.length; i++) { int e = v[i]; for (int j = 0; j < 32; j++) { int b = e & 1; if (b != 0) { weight++; } e >>>= 1; } } return weight; } /** * @return whether this is the zero vector (i.e., all elements are zero) */ public boolean isZero() { for (int i = v.length - 1; i >= 0; i--) { if (v[i] != 0) { return false; } } return true; } /** * Return the value of the bit of this vector at the specified index. * * @param index the index * @return the value of the bit (0 or 1) */ public int getBit(int index) { if (index >= length) { throw new IndexOutOfBoundsException(); } int q = index >> 5; int r = index & 0x1f; return (v[q] & (1 << r)) >>> r; } /** * Set the coefficient at the given index to 1. If the index is out of * bounds, do nothing. * * @param index the index of the coefficient to set */ public void setBit(int index) { if (index >= length) { throw new IndexOutOfBoundsException(); } v[index >> 5] |= 1 << (index & 0x1f); } /** * Adds another GF2Vector to this vector. * * @param other another GF2Vector * @return this + other * @throws ArithmeticException if the other vector is not a GF2Vector or has another * length. */ public Vector add(Vector other) { if (!(other instanceof GF2Vector)) { throw new ArithmeticException("vector is not defined over GF(2)"); } GF2Vector otherVec = (GF2Vector)other; if (length != otherVec.length) { throw new ArithmeticException("length mismatch"); } int[] vec = IntUtils.clone(((GF2Vector)other).v); for (int i = vec.length - 1; i >= 0; i--) { vec[i] ^= v[i]; } return new GF2Vector(length, vec); } /** * Multiply this vector with a permutation. * * @param p the permutation * @return this*p = p*this */ public Vector multiply(Permutation p) { int[] pVec = p.getVector(); if (length != pVec.length) { throw new ArithmeticException("length mismatch"); } GF2Vector result = new GF2Vector(length); for (int i = 0; i < pVec.length; i++) { int e = v[pVec[i] >> 5] & (1 << (pVec[i] & 0x1f)); if (e != 0) { result.v[i >> 5] |= 1 << (i & 0x1f); } } return result; } /** * Return a new vector consisting of the elements of this vector with the * indices given by the set setJ. * * @param setJ the set of indices of elements to extract * @return the new {@link GF2Vector} * [this_setJ[0], this_setJ[1], ..., this_setJ[#setJ-1]] */ public GF2Vector extractVector(int[] setJ) { int k = setJ.length; if (setJ[k - 1] > length) { throw new ArithmeticException("invalid index set"); } GF2Vector result = new GF2Vector(k); for (int i = 0; i < k; i++) { int e = v[setJ[i] >> 5] & (1 << (setJ[i] & 0x1f)); if (e != 0) { result.v[i >> 5] |= 1 << (i & 0x1f); } } return result; } /** * Return a new vector consisting of the first k elements of this * vector. * * @param k the number of elements to extract * @return a new {@link GF2Vector} consisting of the first k * elements of this vector */ public GF2Vector extractLeftVector(int k) { if (k > length) { throw new ArithmeticException("invalid length"); } if (k == length) { return new GF2Vector(this); } GF2Vector result = new GF2Vector(k); int q = k >> 5; int r = k & 0x1f; System.arraycopy(v, 0, result.v, 0, q); if (r != 0) { result.v[q] = v[q] & ((1 << r) - 1); } return result; } /** * Return a new vector consisting of the last k elements of this * vector. * * @param k the number of elements to extract * @return a new {@link GF2Vector} consisting of the last k * elements of this vector */ public GF2Vector extractRightVector(int k) { if (k > length) { throw new ArithmeticException("invalid length"); } if (k == length) { return new GF2Vector(this); } GF2Vector result = new GF2Vector(k); int q = (length - k) >> 5; int r = (length - k) & 0x1f; int length = (k + 31) >> 5; int ind = q; // if words have to be shifted if (r != 0) { // process all but last word for (int i = 0; i < length - 1; i++) { result.v[i] = (v[ind++] >>> r) | (v[ind] << (32 - r)); } // process last word result.v[length - 1] = v[ind++] >>> r; if (ind < v.length) { result.v[length - 1] |= v[ind] << (32 - r); } } else { // no shift necessary System.arraycopy(v, q, result.v, 0, length); } return result; } /** * Rewrite this vector as a vector over GF(2m) with * t elements. * * @param field the finite field GF(2m) * @return the converted vector over GF(2m) */ public GF2mVector toExtensionFieldVector(GF2mField field) { int m = field.getDegree(); if ((length % m) != 0) { throw new ArithmeticException("conversion is impossible"); } int t = length / m; int[] result = new int[t]; int count = 0; for (int i = t - 1; i >= 0; i--) { for (int j = field.getDegree() - 1; j >= 0; j--) { int q = count >>> 5; int r = count & 0x1f; int e = (v[q] >>> r) & 1; if (e == 1) { result[i] ^= 1 << j; } count++; } } return new GF2mVector(field, result); } /** * Check if the given object is equal to this vector. * * @param other vector * @return the result of the comparison */ public boolean equals(Object other) { if (!(other instanceof GF2Vector)) { return false; } GF2Vector otherVec = (GF2Vector)other; return (length == otherVec.length) && IntUtils.equals(v, otherVec.v); } /** * @return the hash code of this vector */ public int hashCode() { int hash = length; hash = hash * 31 + v.hashCode(); return hash; } /** * @return a human readable form of this vector */ public String toString() { StringBuffer buf = new StringBuffer(); for (int i = 0; i < length; i++) { if ((i != 0) && ((i & 0x1f) == 0)) { buf.append(' '); } int q = i >> 5; int r = i & 0x1f; int bit = v[q] & (1 << r); if (bit == 0) { buf.append('0'); } else { buf.append('1'); } } return buf.toString(); } } bouncycastle-1.49.orig/src/org/bouncycastle/pqc/math/linearalgebra/PolynomialRingGF2m.java0000644000175000017500000001273112043365070031274 0ustar ebourgebourgpackage org.bouncycastle.pqc.math.linearalgebra; /** * This class represents polynomial rings GF(2^m)[X]/p(X) for * m<<;32. If p(X) is irreducible, the polynomial ring * is in fact an extension field of GF(2^m). */ public class PolynomialRingGF2m { /** * the finite field this polynomial ring is defined over */ private GF2mField field; /** * the reduction polynomial */ private PolynomialGF2mSmallM p; /** * the squaring matrix for this polynomial ring (given as the array of its * row vectors) */ protected PolynomialGF2mSmallM[] sqMatrix; /** * the matrix for computing square roots in this polynomial ring (given as * the array of its row vectors). This matrix is computed as the inverse of * the squaring matrix. */ protected PolynomialGF2mSmallM[] sqRootMatrix; /** * Constructor. * * @param field the finite field * @param p the reduction polynomial */ public PolynomialRingGF2m(GF2mField field, PolynomialGF2mSmallM p) { this.field = field; this.p = p; computeSquaringMatrix(); computeSquareRootMatrix(); } /** * @return the squaring matrix for this polynomial ring */ public PolynomialGF2mSmallM[] getSquaringMatrix() { return sqMatrix; } /** * @return the matrix for computing square roots for this polynomial ring */ public PolynomialGF2mSmallM[] getSquareRootMatrix() { return sqRootMatrix; } /** * Compute the squaring matrix for this polynomial ring, using the base * field and the reduction polynomial. */ private void computeSquaringMatrix() { int numColumns = p.getDegree(); sqMatrix = new PolynomialGF2mSmallM[numColumns]; for (int i = 0; i < numColumns >> 1; i++) { int[] monomCoeffs = new int[(i << 1) + 1]; monomCoeffs[i << 1] = 1; sqMatrix[i] = new PolynomialGF2mSmallM(field, monomCoeffs); } for (int i = numColumns >> 1; i < numColumns; i++) { int[] monomCoeffs = new int[(i << 1) + 1]; monomCoeffs[i << 1] = 1; PolynomialGF2mSmallM monomial = new PolynomialGF2mSmallM(field, monomCoeffs); sqMatrix[i] = monomial.mod(p); } } /** * Compute the matrix for computing square roots in this polynomial ring by * inverting the squaring matrix. */ private void computeSquareRootMatrix() { int numColumns = p.getDegree(); // clone squaring matrix PolynomialGF2mSmallM[] tmpMatrix = new PolynomialGF2mSmallM[numColumns]; for (int i = numColumns - 1; i >= 0; i--) { tmpMatrix[i] = new PolynomialGF2mSmallM(sqMatrix[i]); } // initialize square root matrix as unit matrix sqRootMatrix = new PolynomialGF2mSmallM[numColumns]; for (int i = numColumns - 1; i >= 0; i--) { sqRootMatrix[i] = new PolynomialGF2mSmallM(field, i); } // simultaneously compute Gaussian reduction of squaring matrix and unit // matrix for (int i = 0; i < numColumns; i++) { // if diagonal element is zero if (tmpMatrix[i].getCoefficient(i) == 0) { boolean foundNonZero = false; // find a non-zero element in the same row for (int j = i + 1; j < numColumns; j++) { if (tmpMatrix[j].getCoefficient(i) != 0) { // found it, swap columns ... foundNonZero = true; swapColumns(tmpMatrix, i, j); swapColumns(sqRootMatrix, i, j); // ... and quit searching j = numColumns; continue; } } // if no non-zero element was found if (!foundNonZero) { // the matrix is not invertible throw new ArithmeticException( "Squaring matrix is not invertible."); } } // normalize i-th column int coef = tmpMatrix[i].getCoefficient(i); int invCoef = field.inverse(coef); tmpMatrix[i].multThisWithElement(invCoef); sqRootMatrix[i].multThisWithElement(invCoef); // normalize all other columns for (int j = 0; j < numColumns; j++) { if (j != i) { coef = tmpMatrix[j].getCoefficient(i); if (coef != 0) { PolynomialGF2mSmallM tmpSqColumn = tmpMatrix[i] .multWithElement(coef); PolynomialGF2mSmallM tmpInvColumn = sqRootMatrix[i] .multWithElement(coef); tmpMatrix[j].addToThis(tmpSqColumn); sqRootMatrix[j].addToThis(tmpInvColumn); } } } } } private static void swapColumns(PolynomialGF2mSmallM[] matrix, int first, int second) { PolynomialGF2mSmallM tmp = matrix[first]; matrix[first] = matrix[second]; matrix[second] = tmp; } } bouncycastle-1.49.orig/src/org/bouncycastle/pqc/math/linearalgebra/PolynomialGF2mSmallM.java0000644000175000017500000007670312105027307031570 0ustar ebourgebourgpackage org.bouncycastle.pqc.math.linearalgebra; import java.security.SecureRandom; /** * This class describes operations with polynomials from the ring R = * GF(2^m)[X], where 2 <= m <=31. * * @see GF2mField * @see PolynomialRingGF2m */ public class PolynomialGF2mSmallM { /** * the finite field GF(2^m) */ private GF2mField field; /** * the degree of this polynomial */ private int degree; /** * For the polynomial representation the map f: R->Z*, * poly(X) -> [coef_0, coef_1, ...] is used, where * coef_i is the ith coefficient of the polynomial * represented as int (see {@link GF2mField}). The polynomials are stored * as int arrays. */ private int[] coefficients; /* * some types of polynomials */ /** * Constant used for polynomial construction (see constructor * {@link #PolynomialGF2mSmallM(GF2mField, int, char, SecureRandom)}). */ public static final char RANDOM_IRREDUCIBLE_POLYNOMIAL = 'I'; /** * Construct the zero polynomial over the finite field GF(2^m). * * @param field the finite field GF(2^m) */ public PolynomialGF2mSmallM(GF2mField field) { this.field = field; degree = -1; coefficients = new int[1]; } /** * Construct a polynomial over the finite field GF(2^m). * * @param field the finite field GF(2^m) * @param deg degree of polynomial * @param typeOfPolynomial type of polynomial * @param sr PRNG */ public PolynomialGF2mSmallM(GF2mField field, int deg, char typeOfPolynomial, SecureRandom sr) { this.field = field; switch (typeOfPolynomial) { case PolynomialGF2mSmallM.RANDOM_IRREDUCIBLE_POLYNOMIAL: coefficients = createRandomIrreduciblePolynomial(deg, sr); break; default: throw new IllegalArgumentException(" Error: type " + typeOfPolynomial + " is not defined for GF2smallmPolynomial"); } computeDegree(); } /** * Create an irreducible polynomial with the given degree over the field * GF(2^m). * * @param deg polynomial degree * @param sr source of randomness * @return the generated irreducible polynomial */ private int[] createRandomIrreduciblePolynomial(int deg, SecureRandom sr) { int[] resCoeff = new int[deg + 1]; resCoeff[deg] = 1; resCoeff[0] = field.getRandomNonZeroElement(sr); for (int i = 1; i < deg; i++) { resCoeff[i] = field.getRandomElement(sr); } while (!isIrreducible(resCoeff)) { int n = RandUtils.nextInt(sr, deg); if (n == 0) { resCoeff[0] = field.getRandomNonZeroElement(sr); } else { resCoeff[n] = field.getRandomElement(sr); } } return resCoeff; } /** * Construct a monomial of the given degree over the finite field GF(2^m). * * @param field the finite field GF(2^m) * @param degree the degree of the monomial */ public PolynomialGF2mSmallM(GF2mField field, int degree) { this.field = field; this.degree = degree; coefficients = new int[degree + 1]; coefficients[degree] = 1; } /** * Construct the polynomial over the given finite field GF(2^m) from the * given coefficient vector. * * @param field finite field GF2m * @param coeffs the coefficient vector */ public PolynomialGF2mSmallM(GF2mField field, int[] coeffs) { this.field = field; coefficients = normalForm(coeffs); computeDegree(); } /** * Create a polynomial over the finite field GF(2^m). * * @param field the finite field GF(2^m) * @param enc byte[] polynomial in byte array form */ public PolynomialGF2mSmallM(GF2mField field, byte[] enc) { this.field = field; // decodes polynomial int d = 8; int count = 1; while (field.getDegree() > d) { count++; d += 8; } if ((enc.length % count) != 0) { throw new IllegalArgumentException( " Error: byte array is not encoded polynomial over given finite field GF2m"); } coefficients = new int[enc.length / count]; count = 0; for (int i = 0; i < coefficients.length; i++) { for (int j = 0; j < d; j += 8) { coefficients[i] ^= (enc[count++] & 0x000000ff) << j; } if (!this.field.isElementOfThisField(coefficients[i])) { throw new IllegalArgumentException( " Error: byte array is not encoded polynomial over given finite field GF2m"); } } // if HC = 0 for non-zero polynomial, returns error if ((coefficients.length != 1) && (coefficients[coefficients.length - 1] == 0)) { throw new IllegalArgumentException( " Error: byte array is not encoded polynomial over given finite field GF2m"); } computeDegree(); } /** * Copy constructor. * * @param other another {@link PolynomialGF2mSmallM} */ public PolynomialGF2mSmallM(PolynomialGF2mSmallM other) { // field needs not to be cloned since it is immutable field = other.field; degree = other.degree; coefficients = IntUtils.clone(other.coefficients); } /** * Create a polynomial over the finite field GF(2^m) out of the given * coefficient vector. The finite field is also obtained from the * {@link GF2mVector}. * * @param vect the coefficient vector */ public PolynomialGF2mSmallM(GF2mVector vect) { this(vect.getField(), vect.getIntArrayForm()); } /* * ------------------------ */ /** * Return the degree of this polynomial * * @return int degree of this polynomial if this is zero polynomial return * -1 */ public int getDegree() { int d = coefficients.length - 1; if (coefficients[d] == 0) { return -1; } return d; } /** * @return the head coefficient of this polynomial */ public int getHeadCoefficient() { if (degree == -1) { return 0; } return coefficients[degree]; } /** * Return the head coefficient of a polynomial. * * @param a the polynomial * @return the head coefficient of a */ private static int headCoefficient(int[] a) { int degree = computeDegree(a); if (degree == -1) { return 0; } return a[degree]; } /** * Return the coefficient with the given index. * * @param index the index * @return the coefficient with the given index */ public int getCoefficient(int index) { if ((index < 0) || (index > degree)) { return 0; } return coefficients[index]; } /** * Returns encoded polynomial, i.e., this polynomial in byte array form * * @return the encoded polynomial */ public byte[] getEncoded() { int d = 8; int count = 1; while (field.getDegree() > d) { count++; d += 8; } byte[] res = new byte[coefficients.length * count]; count = 0; for (int i = 0; i < coefficients.length; i++) { for (int j = 0; j < d; j += 8) { res[count++] = (byte)(coefficients[i] >>> j); } } return res; } /** * Evaluate this polynomial p at a value e (in * GF(2^m)) with the Horner scheme. * * @param e the element of the finite field GF(2^m) * @return this(e) */ public int evaluateAt(int e) { int result = coefficients[degree]; for (int i = degree - 1; i >= 0; i--) { result = field.mult(result, e) ^ coefficients[i]; } return result; } /** * Compute the sum of this polynomial and the given polynomial. * * @param addend the addend * @return this + a (newly created) */ public PolynomialGF2mSmallM add(PolynomialGF2mSmallM addend) { int[] resultCoeff = add(coefficients, addend.coefficients); return new PolynomialGF2mSmallM(field, resultCoeff); } /** * Add the given polynomial to this polynomial (overwrite this). * * @param addend the addend */ public void addToThis(PolynomialGF2mSmallM addend) { coefficients = add(coefficients, addend.coefficients); computeDegree(); } /** * Compute the sum of two polynomials a and b over the finite field * GF(2^m). * * @param a the first polynomial * @param b the second polynomial * @return a + b */ private int[] add(int[] a, int[] b) { int[] result, addend; if (a.length < b.length) { result = new int[b.length]; System.arraycopy(b, 0, result, 0, b.length); addend = a; } else { result = new int[a.length]; System.arraycopy(a, 0, result, 0, a.length); addend = b; } for (int i = addend.length - 1; i >= 0; i--) { result[i] = field.add(result[i], addend[i]); } return result; } /** * Compute the sum of this polynomial and the monomial of the given degree. * * @param degree the degree of the monomial * @return this + X^k */ public PolynomialGF2mSmallM addMonomial(int degree) { int[] monomial = new int[degree + 1]; monomial[degree] = 1; int[] resultCoeff = add(coefficients, monomial); return new PolynomialGF2mSmallM(field, resultCoeff); } /** * Compute the product of this polynomial with an element from GF(2^m). * * @param element an element of the finite field GF(2^m) * @return this * element (newly created) * @throws ArithmeticException if element is not an element of the finite * field this polynomial is defined over. */ public PolynomialGF2mSmallM multWithElement(int element) { if (!field.isElementOfThisField(element)) { throw new ArithmeticException( "Not an element of the finite field this polynomial is defined over."); } int[] resultCoeff = multWithElement(coefficients, element); return new PolynomialGF2mSmallM(field, resultCoeff); } /** * Multiply this polynomial with an element from GF(2^m). * * @param element an element of the finite field GF(2^m) * @throws ArithmeticException if element is not an element of the finite * field this polynomial is defined over. */ public void multThisWithElement(int element) { if (!field.isElementOfThisField(element)) { throw new ArithmeticException( "Not an element of the finite field this polynomial is defined over."); } coefficients = multWithElement(coefficients, element); computeDegree(); } /** * Compute the product of a polynomial a with an element from the finite * field GF(2^m). * * @param a the polynomial * @param element an element of the finite field GF(2^m) * @return a * element */ private int[] multWithElement(int[] a, int element) { int degree = computeDegree(a); if (degree == -1 || element == 0) { return new int[1]; } if (element == 1) { return IntUtils.clone(a); } int[] result = new int[degree + 1]; for (int i = degree; i >= 0; i--) { result[i] = field.mult(a[i], element); } return result; } /** * Compute the product of this polynomial with a monomial X^k. * * @param k the degree of the monomial * @return this * X^k */ public PolynomialGF2mSmallM multWithMonomial(int k) { int[] resultCoeff = multWithMonomial(coefficients, k); return new PolynomialGF2mSmallM(field, resultCoeff); } /** * Compute the product of a polynomial with a monomial X^k. * * @param a the polynomial * @param k the degree of the monomial * @return a * X^k */ private static int[] multWithMonomial(int[] a, int k) { int d = computeDegree(a); if (d == -1) { return new int[1]; } int[] result = new int[d + k + 1]; System.arraycopy(a, 0, result, k, d + 1); return result; } /** * Divide this polynomial by the given polynomial. * * @param f a polynomial * @return polynomial pair = {q,r} where this = q*f+r and deg(r) < * deg(f); */ public PolynomialGF2mSmallM[] div(PolynomialGF2mSmallM f) { int[][] resultCoeffs = div(coefficients, f.coefficients); return new PolynomialGF2mSmallM[]{ new PolynomialGF2mSmallM(field, resultCoeffs[0]), new PolynomialGF2mSmallM(field, resultCoeffs[1])}; } /** * Compute the result of the division of two polynomials over the field * GF(2^m). * * @param a the first polynomial * @param f the second polynomial * @return int[][] {q,r}, where a = q*f+r and deg(r) < deg(f); */ private int[][] div(int[] a, int[] f) { int df = computeDegree(f); int da = computeDegree(a) + 1; if (df == -1) { throw new ArithmeticException("Division by zero."); } int[][] result = new int[2][]; result[0] = new int[1]; result[1] = new int[da]; int hc = headCoefficient(f); hc = field.inverse(hc); result[0][0] = 0; System.arraycopy(a, 0, result[1], 0, result[1].length); while (df <= computeDegree(result[1])) { int[] q; int[] coeff = new int[1]; coeff[0] = field.mult(headCoefficient(result[1]), hc); q = multWithElement(f, coeff[0]); int n = computeDegree(result[1]) - df; q = multWithMonomial(q, n); coeff = multWithMonomial(coeff, n); result[0] = add(coeff, result[0]); result[1] = add(q, result[1]); } return result; } /** * Return the greatest common divisor of this and a polynomial f * * @param f polynomial * @return GCD(this, f) */ public PolynomialGF2mSmallM gcd(PolynomialGF2mSmallM f) { int[] resultCoeff = gcd(coefficients, f.coefficients); return new PolynomialGF2mSmallM(field, resultCoeff); } /** * Return the greatest common divisor of two polynomials over the field * GF(2^m). * * @param f the first polynomial * @param g the second polynomial * @return gcd(f, g) */ private int[] gcd(int[] f, int[] g) { int[] a = f; int[] b = g; if (computeDegree(a) == -1) { return b; } while (computeDegree(b) != -1) { int[] c = mod(a, b); a = new int[b.length]; System.arraycopy(b, 0, a, 0, a.length); b = new int[c.length]; System.arraycopy(c, 0, b, 0, b.length); } int coeff = field.inverse(headCoefficient(a)); return multWithElement(a, coeff); } /** * Compute the product of this polynomial and the given factor using a * Karatzuba like scheme. * * @param factor the polynomial * @return this * factor */ public PolynomialGF2mSmallM multiply(PolynomialGF2mSmallM factor) { int[] resultCoeff = multiply(coefficients, factor.coefficients); return new PolynomialGF2mSmallM(field, resultCoeff); } /** * Compute the product of two polynomials over the field GF(2^m) * using a Karatzuba like multiplication. * * @param a the first polynomial * @param b the second polynomial * @return a * b */ private int[] multiply(int[] a, int[] b) { int[] mult1, mult2; if (computeDegree(a) < computeDegree(b)) { mult1 = b; mult2 = a; } else { mult1 = a; mult2 = b; } mult1 = normalForm(mult1); mult2 = normalForm(mult2); if (mult2.length == 1) { return multWithElement(mult1, mult2[0]); } int d1 = mult1.length; int d2 = mult2.length; int[] result = new int[d1 + d2 - 1]; if (d2 != d1) { int[] res1 = new int[d2]; int[] res2 = new int[d1 - d2]; System.arraycopy(mult1, 0, res1, 0, res1.length); System.arraycopy(mult1, d2, res2, 0, res2.length); res1 = multiply(res1, mult2); res2 = multiply(res2, mult2); res2 = multWithMonomial(res2, d2); result = add(res1, res2); } else { d2 = (d1 + 1) >>> 1; int d = d1 - d2; int[] firstPartMult1 = new int[d2]; int[] firstPartMult2 = new int[d2]; int[] secondPartMult1 = new int[d]; int[] secondPartMult2 = new int[d]; System .arraycopy(mult1, 0, firstPartMult1, 0, firstPartMult1.length); System.arraycopy(mult1, d2, secondPartMult1, 0, secondPartMult1.length); System .arraycopy(mult2, 0, firstPartMult2, 0, firstPartMult2.length); System.arraycopy(mult2, d2, secondPartMult2, 0, secondPartMult2.length); int[] helpPoly1 = add(firstPartMult1, secondPartMult1); int[] helpPoly2 = add(firstPartMult2, secondPartMult2); int[] res1 = multiply(firstPartMult1, firstPartMult2); int[] res2 = multiply(helpPoly1, helpPoly2); int[] res3 = multiply(secondPartMult1, secondPartMult2); res2 = add(res2, res1); res2 = add(res2, res3); res3 = multWithMonomial(res3, d2); result = add(res2, res3); result = multWithMonomial(result, d2); result = add(result, res1); } return result; } /* * ---------------- PART II ---------------- * */ /** * Check a polynomial for irreducibility over the field GF(2^m). * * @param a the polynomial to check * @return true if a is irreducible, false otherwise */ private boolean isIrreducible(int[] a) { if (a[0] == 0) { return false; } int d = computeDegree(a) >> 1; int[] u = {0, 1}; final int[] Y = {0, 1}; int fieldDegree = field.getDegree(); for (int i = 0; i < d; i++) { for (int j = fieldDegree - 1; j >= 0; j--) { u = modMultiply(u, u, a); } u = normalForm(u); int[] g = gcd(add(u, Y), a); if (computeDegree(g) != 0) { return false; } } return true; } /** * Reduce this polynomial modulo another polynomial. * * @param f the reduction polynomial * @return this mod f */ public PolynomialGF2mSmallM mod(PolynomialGF2mSmallM f) { int[] resultCoeff = mod(coefficients, f.coefficients); return new PolynomialGF2mSmallM(field, resultCoeff); } /** * Reduce a polynomial modulo another polynomial. * * @param a the polynomial * @param f the reduction polynomial * @return a mod f */ private int[] mod(int[] a, int[] f) { int df = computeDegree(f); if (df == -1) { throw new ArithmeticException("Division by zero"); } int[] result = new int[a.length]; int hc = headCoefficient(f); hc = field.inverse(hc); System.arraycopy(a, 0, result, 0, result.length); while (df <= computeDegree(result)) { int[] q; int coeff = field.mult(headCoefficient(result), hc); q = multWithMonomial(f, computeDegree(result) - df); q = multWithElement(q, coeff); result = add(q, result); } return result; } /** * Compute the product of this polynomial and another polynomial modulo a * third polynomial. * * @param a another polynomial * @param b the reduction polynomial * @return this * a mod b */ public PolynomialGF2mSmallM modMultiply(PolynomialGF2mSmallM a, PolynomialGF2mSmallM b) { int[] resultCoeff = modMultiply(coefficients, a.coefficients, b.coefficients); return new PolynomialGF2mSmallM(field, resultCoeff); } /** * Square this polynomial using a squaring matrix. * * @param matrix the squaring matrix * @return this^2 modulo the reduction polynomial implicitly * given via the squaring matrix */ public PolynomialGF2mSmallM modSquareMatrix(PolynomialGF2mSmallM[] matrix) { int length = matrix.length; int[] resultCoeff = new int[length]; int[] thisSquare = new int[length]; // square each entry of this polynomial for (int i = 0; i < coefficients.length; i++) { thisSquare[i] = field.mult(coefficients[i], coefficients[i]); } // do matrix-vector multiplication for (int i = 0; i < length; i++) { // compute scalar product of i-th row and coefficient vector for (int j = 0; j < length; j++) { if (i >= matrix[j].coefficients.length) { continue; } int scalarTerm = field.mult(matrix[j].coefficients[i], thisSquare[j]); resultCoeff[i] = field.add(resultCoeff[i], scalarTerm); } } return new PolynomialGF2mSmallM(field, resultCoeff); } /** * Compute the product of two polynomials modulo a third polynomial over the * finite field GF(2^m). * * @param a the first polynomial * @param b the second polynomial * @param g the reduction polynomial * @return a * b mod g */ private int[] modMultiply(int[] a, int[] b, int[] g) { return mod(multiply(a, b), g); } /** * Compute the square root of this polynomial modulo the given polynomial. * * @param a the reduction polynomial * @return this^(1/2) mod a */ public PolynomialGF2mSmallM modSquareRoot(PolynomialGF2mSmallM a) { int[] resultCoeff = IntUtils.clone(coefficients); int[] help = modMultiply(resultCoeff, resultCoeff, a.coefficients); while (!isEqual(help, coefficients)) { resultCoeff = normalForm(help); help = modMultiply(resultCoeff, resultCoeff, a.coefficients); } return new PolynomialGF2mSmallM(field, resultCoeff); } /** * Compute the square root of this polynomial using a square root matrix. * * @param matrix the matrix for computing square roots in * (GF(2^m))^t the polynomial ring defining the * square root matrix * @return this^(1/2) modulo the reduction polynomial implicitly * given via the square root matrix */ public PolynomialGF2mSmallM modSquareRootMatrix( PolynomialGF2mSmallM[] matrix) { int length = matrix.length; int[] resultCoeff = new int[length]; // do matrix multiplication for (int i = 0; i < length; i++) { // compute scalar product of i-th row and j-th column for (int j = 0; j < length; j++) { if (i >= matrix[j].coefficients.length) { continue; } if (j < coefficients.length) { int scalarTerm = field.mult(matrix[j].coefficients[i], coefficients[j]); resultCoeff[i] = field.add(resultCoeff[i], scalarTerm); } } } // compute the square root of each entry of the result coefficients for (int i = 0; i < length; i++) { resultCoeff[i] = field.sqRoot(resultCoeff[i]); } return new PolynomialGF2mSmallM(field, resultCoeff); } /** * Compute the result of the division of this polynomial by another * polynomial modulo a third polynomial. * * @param divisor the divisor * @param modulus the reduction polynomial * @return this * divisor^(-1) mod modulus */ public PolynomialGF2mSmallM modDiv(PolynomialGF2mSmallM divisor, PolynomialGF2mSmallM modulus) { int[] resultCoeff = modDiv(coefficients, divisor.coefficients, modulus.coefficients); return new PolynomialGF2mSmallM(field, resultCoeff); } /** * Compute the result of the division of two polynomials modulo a third * polynomial over the field GF(2^m). * * @param a the first polynomial * @param b the second polynomial * @param g the reduction polynomial * @return a * b^(-1) mod g */ private int[] modDiv(int[] a, int[] b, int[] g) { int[] r0 = normalForm(g); int[] r1 = mod(b, g); int[] s0 = {0}; int[] s1 = mod(a, g); int[] s2; int[][] q; while (computeDegree(r1) != -1) { q = div(r0, r1); r0 = normalForm(r1); r1 = normalForm(q[1]); s2 = add(s0, modMultiply(q[0], s1, g)); s0 = normalForm(s1); s1 = normalForm(s2); } int hc = headCoefficient(r0); s0 = multWithElement(s0, field.inverse(hc)); return s0; } /** * Compute the inverse of this polynomial modulo the given polynomial. * * @param a the reduction polynomial * @return this^(-1) mod a */ public PolynomialGF2mSmallM modInverse(PolynomialGF2mSmallM a) { int[] unit = {1}; int[] resultCoeff = modDiv(unit, coefficients, a.coefficients); return new PolynomialGF2mSmallM(field, resultCoeff); } /** * Compute a polynomial pair (a,b) from this polynomial and the given * polynomial g with the property b*this = a mod g and deg(a)<=deg(g)/2. * * @param g the reduction polynomial * @return PolynomialGF2mSmallM[] {a,b} with b*this = a mod g and deg(a)<= * deg(g)/2 */ public PolynomialGF2mSmallM[] modPolynomialToFracton(PolynomialGF2mSmallM g) { int dg = g.degree >> 1; int[] a0 = normalForm(g.coefficients); int[] a1 = mod(coefficients, g.coefficients); int[] b0 = {0}; int[] b1 = {1}; while (computeDegree(a1) > dg) { int[][] q = div(a0, a1); a0 = a1; a1 = q[1]; int[] b2 = add(b0, modMultiply(q[0], b1, g.coefficients)); b0 = b1; b1 = b2; } return new PolynomialGF2mSmallM[]{ new PolynomialGF2mSmallM(field, a1), new PolynomialGF2mSmallM(field, b1)}; } /** * checks if given object is equal to this polynomial. *

    * The method returns false whenever the given object is not polynomial over * GF(2^m). * * @param other object * @return true or false */ public boolean equals(Object other) { if (other == null || !(other instanceof PolynomialGF2mSmallM)) { return false; } PolynomialGF2mSmallM p = (PolynomialGF2mSmallM)other; if ((field.equals(p.field)) && (degree == p.degree) && (isEqual(coefficients, p.coefficients))) { return true; } return false; } /** * Compare two polynomials given as int arrays. * * @param a the first polynomial * @param b the second polynomial * @return true if a and b represent the * same polynomials, false otherwise */ private static boolean isEqual(int[] a, int[] b) { int da = computeDegree(a); int db = computeDegree(b); if (da != db) { return false; } for (int i = 0; i <= da; i++) { if (a[i] != b[i]) { return false; } } return true; } /** * @return the hash code of this polynomial */ public int hashCode() { int hash = field.hashCode(); for (int j = 0; j < coefficients.length; j++) { hash = hash * 31 + coefficients[j]; } return hash; } /** * Returns a human readable form of the polynomial. *

    * * @return a human readable form of the polynomial. */ public String toString() { String str = " Polynomial over " + field.toString() + ": \n"; for (int i = 0; i < coefficients.length; i++) { str = str + field.elementToStr(coefficients[i]) + "Y^" + i + "+"; } str = str + ";"; return str; } /** * Compute the degree of this polynomial. If this is the zero polynomial, * the degree is -1. */ private void computeDegree() { for (degree = coefficients.length - 1; degree >= 0 && coefficients[degree] == 0; degree--) { ; } } /** * Compute the degree of a polynomial. * * @param a the polynomial * @return the degree of the polynomial a. If a is * the zero polynomial, return -1. */ private static int computeDegree(int[] a) { int degree; for (degree = a.length - 1; degree >= 0 && a[degree] == 0; degree--) { ; } return degree; } /** * Strip leading zero coefficients from the given polynomial. * * @param a the polynomial * @return the reduced polynomial */ private static int[] normalForm(int[] a) { int d = computeDegree(a); // if a is the zero polynomial if (d == -1) { // return new zero polynomial return new int[1]; } // if a already is in normal form if (a.length == d + 1) { // return a clone of a return IntUtils.clone(a); } // else, reduce a int[] result = new int[d + 1]; System.arraycopy(a, 0, result, 0, d + 1); return result; } } bouncycastle-1.49.orig/src/org/bouncycastle/pqc/math/linearalgebra/CharUtils.java0000644000175000017500000000426012043365070027551 0ustar ebourgebourgpackage org.bouncycastle.pqc.math.linearalgebra; public final class CharUtils { /** * Default constructor (private) */ private CharUtils() { // empty } /** * Return a clone of the given char array. No null checks are performed. * * @param array the array to clone * @return the clone of the given array */ public static char[] clone(char[] array) { char[] result = new char[array.length]; System.arraycopy(array, 0, result, 0, array.length); return result; } /** * Convert the given char array into a byte array. * * @param chars the char array * @return the converted array */ public static byte[] toByteArray(char[] chars) { byte[] result = new byte[chars.length]; for (int i = chars.length - 1; i >= 0; i--) { result[i] = (byte)chars[i]; } return result; } /** * Convert the given char array into a * byte array for use with PBE encryption. * * @param chars the char array * @return the converted array */ public static byte[] toByteArrayForPBE(char[] chars) { byte[] out = new byte[chars.length]; for (int i = 0; i < chars.length; i++) { out[i] = (byte)chars[i]; } int length = out.length * 2; byte[] ret = new byte[length + 2]; int j = 0; for (int i = 0; i < out.length; i++) { j = i * 2; ret[j] = 0; ret[j + 1] = out[i]; } ret[length] = 0; ret[length + 1] = 0; return ret; } /** * Compare two char arrays. No null checks are performed. * * @param left the char byte array * @param right the second char array * @return the result of the comparison */ public static boolean equals(char[] left, char[] right) { if (left.length != right.length) { return false; } boolean result = true; for (int i = left.length - 1; i >= 0; i--) { result &= left[i] == right[i]; } return result; } } bouncycastle-1.49.orig/src/org/bouncycastle/pqc/math/linearalgebra/GFElement.java0000644000175000017500000001063012043365070027457 0ustar ebourgebourgpackage org.bouncycastle.pqc.math.linearalgebra; import java.math.BigInteger; /** * This interface defines a finite field element. It is implemented by the * classes {@link GFPElement} and {@link GF2nElement}. * * @see GFPElement * @see GF2nElement */ public interface GFElement { /** * @return a copy of this GFElement */ Object clone(); // ///////////////////////////////////////////////////////////////// // comparison // ///////////////////////////////////////////////////////////////// /** * Compare this curve with another object. * * @param other the other object * @return the result of the comparison */ boolean equals(Object other); /** * @return the hash code of this element */ int hashCode(); /** * Checks whether this element is zero. * * @return true if this is the zero element */ boolean isZero(); /** * Checks whether this element is one. * * @return true if this is the one element */ boolean isOne(); // ///////////////////////////////////////////////////////////////////// // arithmetic // ///////////////////////////////////////////////////////////////////// /** * Compute the sum of this element and the addend. * * @param addend the addend * @return this + other (newly created) * @throws DifferentFieldsException if the elements are of different fields. */ GFElement add(GFElement addend) throws RuntimeException; /** * Compute the sum of this element and the addend, overwriting this element. * * @param addend the addend * @throws DifferentFieldsException if the elements are of different fields. */ void addToThis(GFElement addend) throws RuntimeException; /** * Compute the difference of this element and minuend. * * @param minuend the minuend * @return this - minuend (newly created) * @throws DifferentFieldsException if the elements are of different fields. */ GFElement subtract(GFElement minuend) throws RuntimeException; /** * Compute the difference of this element and minuend, * overwriting this element. * * @param minuend the minuend * @throws DifferentFieldsException if the elements are of different fields. */ void subtractFromThis(GFElement minuend); /** * Compute the product of this element and factor. * * @param factor the factor * @return this * factor (newly created) * @throws DifferentFieldsException if the elements are of different fields. */ GFElement multiply(GFElement factor) throws RuntimeException; /** * Compute this * factor (overwrite this). * * @param factor the factor * @throws DifferentFieldsException if the elements are of different fields. */ void multiplyThisBy(GFElement factor) throws RuntimeException; /** * Compute the multiplicative inverse of this element. * * @return this-1 (newly created) * @throws ArithmeticException if this is the zero element. */ GFElement invert() throws ArithmeticException; // ///////////////////////////////////////////////////////////////////// // conversion // ///////////////////////////////////////////////////////////////////// /** * Returns this element as FlexiBigInt. The conversion is P1363-conform. * * @return this element as BigInt */ BigInteger toFlexiBigInt(); /** * Returns this element as byte array. The conversion is P1363-conform. * * @return this element as byte array */ byte[] toByteArray(); /** * Return a String representation of this element. * * @return String representation of this element */ String toString(); /** * Return a String representation of this element. radix * specifies the radix of the String representation. * * @param radix specifies the radix of the String representation * @return String representation of this element with the specified radix */ String toString(int radix); } bouncycastle-1.49.orig/src/org/bouncycastle/pqc/math/linearalgebra/GF2mField.java0000644000175000017500000002016512105027554027355 0ustar ebourgebourgpackage org.bouncycastle.pqc.math.linearalgebra; import java.security.SecureRandom; /** * This class describes operations with elements from the finite field F = * GF(2^m). ( GF(2^m)= GF(2)[A] where A is a root of irreducible polynomial with * degree m, each field element B has a polynomial basis representation, i.e. it * is represented by a different binary polynomial of degree less than m, B = * poly(A) ) All operations are defined only for field with 1< m <32. For the * representation of field elements the map f: F->Z, poly(A)->poly(2) is used, * where integers have the binary representation. For example: A^7+A^3+A+1 -> * (00...0010001011)=139 Also for elements type Integer is used. * * @see PolynomialRingGF2 */ public class GF2mField { /* * degree - degree of the field polynomial - the field polynomial ring - * polynomial ring over the finite field GF(2) */ private int degree = 0; private int polynomial; /** * create a finite field GF(2^m) * * @param degree the degree of the field */ public GF2mField(int degree) { if (degree >= 32) { throw new IllegalArgumentException( " Error: the degree of field is too large "); } if (degree < 1) { throw new IllegalArgumentException( " Error: the degree of field is non-positive "); } this.degree = degree; polynomial = PolynomialRingGF2.getIrreduciblePolynomial(degree); } /** * create a finite field GF(2^m) with the fixed field polynomial * * @param degree the degree of the field * @param poly the field polynomial */ public GF2mField(int degree, int poly) { if (degree != PolynomialRingGF2.degree(poly)) { throw new IllegalArgumentException( " Error: the degree is not correct"); } if (!PolynomialRingGF2.isIrreducible(poly)) { throw new IllegalArgumentException( " Error: given polynomial is reducible"); } this.degree = degree; polynomial = poly; } public GF2mField(byte[] enc) { if (enc.length != 4) { throw new IllegalArgumentException( "byte array is not an encoded finite field"); } polynomial = LittleEndianConversions.OS2IP(enc); if (!PolynomialRingGF2.isIrreducible(polynomial)) { throw new IllegalArgumentException( "byte array is not an encoded finite field"); } degree = PolynomialRingGF2.degree(polynomial); } public GF2mField(GF2mField field) { degree = field.degree; polynomial = field.polynomial; } /** * return degree of the field * * @return degree of the field */ public int getDegree() { return degree; } /** * return the field polynomial * * @return the field polynomial */ public int getPolynomial() { return polynomial; } /** * return the encoded form of this field * * @return the field in byte array form */ public byte[] getEncoded() { return LittleEndianConversions.I2OSP(polynomial); } /** * Return sum of two elements * * @param a * @param b * @return a+b */ public int add(int a, int b) { return a ^ b; } /** * Return product of two elements * * @param a * @param b * @return a*b */ public int mult(int a, int b) { return PolynomialRingGF2.modMultiply(a, b, polynomial); } /** * compute exponentiation a^k * * @param a a field element a * @param k k degree * @return a^k */ public int exp(int a, int k) { if (a == 0) { return 0; } if (a == 1) { return 1; } int result = 1; if (k < 0) { a = inverse(a); k = -k; } while (k != 0) { if ((k & 1) == 1) { result = mult(result, a); } a = mult(a, a); k >>>= 1; } return result; } /** * compute the multiplicative inverse of a * * @param a a field element a * @return a-1 */ public int inverse(int a) { int d = (1 << degree) - 2; return exp(a, d); } /** * compute the square root of an integer * * @param a a field element a * @return a1/2 */ public int sqRoot(int a) { for (int i = 1; i < degree; i++) { a = mult(a, a); } return a; } /** * create a random field element using PRNG sr * * @param sr SecureRandom * @return a random element */ public int getRandomElement(SecureRandom sr) { int result = RandUtils.nextInt(sr, 1 << degree); return result; } /** * create a random non-zero field element * * @return a random element */ public int getRandomNonZeroElement() { return getRandomNonZeroElement(new SecureRandom()); } /** * create a random non-zero field element using PRNG sr * * @param sr SecureRandom * @return a random non-zero element */ public int getRandomNonZeroElement(SecureRandom sr) { int controltime = 1 << 20; int count = 0; int result = RandUtils.nextInt(sr, 1 << degree); while ((result == 0) && (count < controltime)) { result = RandUtils.nextInt(sr, 1 << degree); count++; } if (count == controltime) { result = 1; } return result; } /** * @return true if e is encoded element of this field and false otherwise */ public boolean isElementOfThisField(int e) { // e is encoded element of this field iff 0<= e < |2^m| if (degree == 31) { return e >= 0; } return e >= 0 && e < (1 << degree); } /* * help method for visual control */ public String elementToStr(int a) { String s = ""; for (int i = 0; i < degree; i++) { if (((byte)a & 0x01) == 0) { s = "0" + s; } else { s = "1" + s; } a >>>= 1; } return s; } /** * checks if given object is equal to this field. *

    * The method returns false whenever the given object is not GF2m. * * @param other object * @return true or false */ public boolean equals(Object other) { if ((other == null) || !(other instanceof GF2mField)) { return false; } GF2mField otherField = (GF2mField)other; if ((degree == otherField.degree) && (polynomial == otherField.polynomial)) { return true; } return false; } public int hashCode() { return polynomial; } /** * Returns a human readable form of this field. *

    * * @return a human readable form of this field. */ public String toString() { String str = "Finite Field GF(2^" + degree + ") = " + "GF(2)[X]/<" + polyToString(polynomial) + "> "; return str; } private static String polyToString(int p) { String str = ""; if (p == 0) { str = "0"; } else { byte b = (byte)(p & 0x01); if (b == 1) { str = "1"; } p >>>= 1; int i = 1; while (p != 0) { b = (byte)(p & 0x01); if (b == 1) { str = str + "+x^" + i; } p >>>= 1; i++; } } return str; } } bouncycastle-1.49.orig/src/org/bouncycastle/pqc/math/linearalgebra/GF2nPolynomialField.java0000644000175000017500000003736212043365070031430 0ustar ebourgebourgpackage org.bouncycastle.pqc.math.linearalgebra; import java.util.Random; import java.util.Vector; /** * This class implements the abstract class GF2nField for polynomial * representation. It computes the field polynomial and the squaring matrix. * GF2nField is used by GF2nPolynomialElement which implements the elements of * this field. * * @see GF2nField * @see GF2nPolynomialElement */ public class GF2nPolynomialField extends GF2nField { /** * Matrix used for fast squaring */ GF2Polynomial[] squaringMatrix; // field polynomial is a trinomial private boolean isTrinomial = false; // field polynomial is a pentanomial private boolean isPentanomial = false; // middle coefficient of the field polynomial in case it is a trinomial private int tc; // middle 3 coefficients of the field polynomial in case it is a pentanomial private int[] pc = new int[3]; /** * constructs an instance of the finite field with 2deg * elements and characteristic 2. * * @param deg the extention degree of this field */ public GF2nPolynomialField(int deg) { if (deg < 3) { throw new IllegalArgumentException("k must be at least 3"); } mDegree = deg; computeFieldPolynomial(); computeSquaringMatrix(); fields = new Vector(); matrices = new Vector(); } /** * constructs an instance of the finite field with 2deg * elements and characteristic 2. * * @param deg the degree of this field * @param file true if you want to read the field polynomial from the * file false if you want to use a random fielpolynomial * (this can take very long for huge degrees) */ public GF2nPolynomialField(int deg, boolean file) { if (deg < 3) { throw new IllegalArgumentException("k must be at least 3"); } mDegree = deg; if (file) { computeFieldPolynomial(); } else { computeFieldPolynomial2(); } computeSquaringMatrix(); fields = new Vector(); matrices = new Vector(); } /** * Creates a new GF2nField of degree i and uses the given * polynomial as field polynomial. The polynomial is checked * whether it is irreducible. This can take some time if i is huge! * * @param deg degree of the GF2nField * @param polynomial the field polynomial to use * @throws PolynomialIsNotIrreducibleException if the given polynomial is not irreducible in GF(2^i) */ public GF2nPolynomialField(int deg, GF2Polynomial polynomial) throws RuntimeException { if (deg < 3) { throw new IllegalArgumentException("degree must be at least 3"); } if (polynomial.getLength() != deg + 1) { throw new RuntimeException(); } if (!polynomial.isIrreducible()) { throw new RuntimeException(); } mDegree = deg; // fieldPolynomial = new Bitstring(polynomial); fieldPolynomial = polynomial; computeSquaringMatrix(); int k = 2; // check if the polynomial is a trinomial or pentanomial for (int j = 1; j < fieldPolynomial.getLength() - 1; j++) { if (fieldPolynomial.testBit(j)) { k++; if (k == 3) { tc = j; } if (k <= 5) { pc[k - 3] = j; } } } if (k == 3) { isTrinomial = true; } if (k == 5) { isPentanomial = true; } fields = new Vector(); matrices = new Vector(); } /** * Returns true if the field polynomial is a trinomial. The coefficient can * be retrieved using getTc(). * * @return true if the field polynomial is a trinomial */ public boolean isTrinomial() { return isTrinomial; } /** * Returns true if the field polynomial is a pentanomial. The coefficients * can be retrieved using getPc(). * * @return true if the field polynomial is a pentanomial */ public boolean isPentanomial() { return isPentanomial; } /** * Returns the degree of the middle coefficient of the used field trinomial * (x^n + x^(getTc()) + 1). * * @return the middle coefficient of the used field trinomial * @throws GFException if the field polynomial is not a trinomial */ public int getTc() throws RuntimeException { if (!isTrinomial) { throw new RuntimeException(); } return tc; } /** * Returns the degree of the middle coefficients of the used field * pentanomial (x^n + x^(getPc()[2]) + x^(getPc()[1]) + x^(getPc()[0]) + 1). * * @return the middle coefficients of the used field pentanomial * @throws GFException if the field polynomial is not a pentanomial */ public int[] getPc() throws RuntimeException { if (!isPentanomial) { throw new RuntimeException(); } int[] result = new int[3]; System.arraycopy(pc, 0, result, 0, 3); return result; } /** * Return row vector i of the squaring matrix. * * @param i the index of the row vector to return * @return a copy of squaringMatrix[i] * @see GF2nPolynomialElement#squareMatrix */ public GF2Polynomial getSquaringVector(int i) { return new GF2Polynomial(squaringMatrix[i]); } /** * Compute a random root of the given GF2Polynomial. * * @param polynomial the polynomial * @return a random root of polynomial */ protected GF2nElement getRandomRoot(GF2Polynomial polynomial) { // We are in B1!!! GF2nPolynomial c; GF2nPolynomial ut; GF2nElement u; GF2nPolynomial h; int hDegree; // 1. Set g(t) <- f(t) GF2nPolynomial g = new GF2nPolynomial(polynomial, this); int gDegree = g.getDegree(); int i; // 2. while deg(g) > 1 while (gDegree > 1) { do { // 2.1 choose random u (element of) GF(2^m) u = new GF2nPolynomialElement(this, new Random()); ut = new GF2nPolynomial(2, GF2nPolynomialElement.ZERO(this)); // 2.2 Set c(t) <- ut ut.set(1, u); c = new GF2nPolynomial(ut); // 2.3 For i from 1 to m-1 do for (i = 1; i <= mDegree - 1; i++) { // 2.3.1 c(t) <- (c(t)^2 + ut) mod g(t) c = c.multiplyAndReduce(c, g); c = c.add(ut); } // 2.4 set h(t) <- GCD(c(t), g(t)) h = c.gcd(g); // 2.5 if h(t) is constant or deg(g) = deg(h) then go to // step 2.1 hDegree = h.getDegree(); gDegree = g.getDegree(); } while ((hDegree == 0) || (hDegree == gDegree)); // 2.6 If 2deg(h) > deg(g) then set g(t) <- g(t)/h(t) ... if ((hDegree << 1) > gDegree) { g = g.quotient(h); } else { // ... else g(t) <- h(t) g = new GF2nPolynomial(h); } gDegree = g.getDegree(); } // 3. Output g(0) return g.at(0); } /** * Computes the change-of-basis matrix for basis conversion according to * 1363. The result is stored in the lists fields and matrices. * * @param B1 the GF2nField to convert to * @see "P1363 A.7.3, p111ff" */ protected void computeCOBMatrix(GF2nField B1) { // we are in B0 here! if (mDegree != B1.mDegree) { throw new IllegalArgumentException( "GF2nPolynomialField.computeCOBMatrix: B1 has a different " + "degree and thus cannot be coverted to!"); } if (B1 instanceof GF2nONBField) { // speedup (calculation is done in PolynomialElements instead of // ONB) B1.computeCOBMatrix(this); return; } int i, j; GF2nElement[] gamma; GF2nElement u; GF2Polynomial[] COBMatrix = new GF2Polynomial[mDegree]; for (i = 0; i < mDegree; i++) { COBMatrix[i] = new GF2Polynomial(mDegree); } // find Random Root do { // u is in representation according to B1 u = B1.getRandomRoot(fieldPolynomial); } while (u.isZero()); // build gamma matrix by multiplying by u if (u instanceof GF2nONBElement) { gamma = new GF2nONBElement[mDegree]; gamma[mDegree - 1] = GF2nONBElement.ONE((GF2nONBField)B1); } else { gamma = new GF2nPolynomialElement[mDegree]; gamma[mDegree - 1] = GF2nPolynomialElement .ONE((GF2nPolynomialField)B1); } gamma[mDegree - 2] = u; for (i = mDegree - 3; i >= 0; i--) { gamma[i] = (GF2nElement)gamma[i + 1].multiply(u); } if (B1 instanceof GF2nONBField) { // convert horizontal gamma matrix by vertical Bitstrings for (i = 0; i < mDegree; i++) { for (j = 0; j < mDegree; j++) { // TODO remember: ONB treats its Bits in reverse order !!! if (gamma[i].testBit(mDegree - j - 1)) { COBMatrix[mDegree - j - 1].setBit(mDegree - i - 1); } } } } else { // convert horizontal gamma matrix by vertical Bitstrings for (i = 0; i < mDegree; i++) { for (j = 0; j < mDegree; j++) { if (gamma[i].testBit(j)) { COBMatrix[mDegree - j - 1].setBit(mDegree - i - 1); } } } } // store field and matrix for further use fields.addElement(B1); matrices.addElement(COBMatrix); // store field and inverse matrix for further use in B1 B1.fields.addElement(this); B1.matrices.addElement(invertMatrix(COBMatrix)); } /** * Computes a new squaring matrix used for fast squaring. * * @see GF2nPolynomialElement#square */ private void computeSquaringMatrix() { GF2Polynomial[] d = new GF2Polynomial[mDegree - 1]; int i, j; squaringMatrix = new GF2Polynomial[mDegree]; for (i = 0; i < squaringMatrix.length; i++) { squaringMatrix[i] = new GF2Polynomial(mDegree, "ZERO"); } for (i = 0; i < mDegree - 1; i++) { d[i] = new GF2Polynomial(1, "ONE").shiftLeft(mDegree + i) .remainder(fieldPolynomial); } for (i = 1; i <= Math.abs(mDegree >> 1); i++) { for (j = 1; j <= mDegree; j++) { if (d[mDegree - (i << 1)].testBit(mDegree - j)) { squaringMatrix[j - 1].setBit(mDegree - i); } } } for (i = Math.abs(mDegree >> 1) + 1; i <= mDegree; i++) { squaringMatrix[(i << 1) - mDegree - 1].setBit(mDegree - i); } } /** * Computes the field polynomial. This can take a long time for big degrees. */ protected void computeFieldPolynomial() { if (testTrinomials()) { return; } if (testPentanomials()) { return; } testRandom(); } /** * Computes the field polynomial. This can take a long time for big degrees. */ protected void computeFieldPolynomial2() { if (testTrinomials()) { return; } if (testPentanomials()) { return; } testRandom(); } /** * Tests all trinomials of degree (n+1) until a irreducible is found and * stores the result in field polynomial. Returns false if no * irreducible trinomial exists in GF(2^n). This can take very long for huge * degrees. * * @return true if an irreducible trinomial is found */ private boolean testTrinomials() { int i, l; boolean done = false; l = 0; fieldPolynomial = new GF2Polynomial(mDegree + 1); fieldPolynomial.setBit(0); fieldPolynomial.setBit(mDegree); for (i = 1; (i < mDegree) && !done; i++) { fieldPolynomial.setBit(i); done = fieldPolynomial.isIrreducible(); l++; if (done) { isTrinomial = true; tc = i; return done; } fieldPolynomial.resetBit(i); done = fieldPolynomial.isIrreducible(); } return done; } /** * Tests all pentanomials of degree (n+1) until a irreducible is found and * stores the result in field polynomial. Returns false if no * irreducible pentanomial exists in GF(2^n). This can take very long for * huge degrees. * * @return true if an irreducible pentanomial is found */ private boolean testPentanomials() { int i, j, k, l; boolean done = false; l = 0; fieldPolynomial = new GF2Polynomial(mDegree + 1); fieldPolynomial.setBit(0); fieldPolynomial.setBit(mDegree); for (i = 1; (i <= (mDegree - 3)) && !done; i++) { fieldPolynomial.setBit(i); for (j = i + 1; (j <= (mDegree - 2)) && !done; j++) { fieldPolynomial.setBit(j); for (k = j + 1; (k <= (mDegree - 1)) && !done; k++) { fieldPolynomial.setBit(k); if (((mDegree & 1) != 0) | ((i & 1) != 0) | ((j & 1) != 0) | ((k & 1) != 0)) { done = fieldPolynomial.isIrreducible(); l++; if (done) { isPentanomial = true; pc[0] = i; pc[1] = j; pc[2] = k; return done; } } fieldPolynomial.resetBit(k); } fieldPolynomial.resetBit(j); } fieldPolynomial.resetBit(i); } return done; } /** * Tests random polynomials of degree (n+1) until an irreducible is found * and stores the result in field polynomial. This can take very * long for huge degrees. * * @return true */ private boolean testRandom() { int l; boolean done = false; fieldPolynomial = new GF2Polynomial(mDegree + 1); l = 0; while (!done) { l++; fieldPolynomial.randomize(); fieldPolynomial.setBit(mDegree); fieldPolynomial.setBit(0); if (fieldPolynomial.isIrreducible()) { done = true; return done; } } return done; } } bouncycastle-1.49.orig/src/org/bouncycastle/pqc/math/linearalgebra/IntegerFunctions.java0000644000175000017500000012467312105356151031153 0ustar ebourgebourgpackage org.bouncycastle.pqc.math.linearalgebra; import java.math.BigInteger; import java.security.SecureRandom; /** * Class of number-theory related functions for use with integers represented as * int's or BigInteger objects. */ public final class IntegerFunctions { private static final BigInteger ZERO = BigInteger.valueOf(0); private static final BigInteger ONE = BigInteger.valueOf(1); private static final BigInteger TWO = BigInteger.valueOf(2); private static final BigInteger FOUR = BigInteger.valueOf(4); private static final int[] SMALL_PRIMES = {3, 5, 7, 11, 13, 17, 19, 23, 29, 31, 37, 41}; private static final long SMALL_PRIME_PRODUCT = 3L * 5 * 7 * 11 * 13 * 17 * 19 * 23 * 29 * 31 * 37 * 41; private static SecureRandom sr = null; // the jacobi function uses this lookup table private static final int[] jacobiTable = {0, 1, 0, -1, 0, -1, 0, 1}; private IntegerFunctions() { // empty } /** * Computes the value of the Jacobi symbol (A|B). The following properties * hold for the Jacobi symbol which makes it a very efficient way to * evaluate the Legendre symbol *

    * (A|B) = 0 IF gcd(A,B) > 1
    * (-1|B) = 1 IF n = 1 (mod 1)
    * (-1|B) = -1 IF n = 3 (mod 4)
    * (A|B) (C|B) = (AC|B)
    * (A|B) (A|C) = (A|CB)
    * (A|B) = (C|B) IF A = C (mod B)
    * (2|B) = 1 IF N = 1 OR 7 (mod 8)
    * (2|B) = 1 IF N = 3 OR 5 (mod 8) *

    * * @param A integer value * @param B integer value * @return value of the jacobi symbol (A|B) */ public static int jacobi(BigInteger A, BigInteger B) { BigInteger a, b, v; long k = 1; k = 1; // test trivial cases if (B.equals(ZERO)) { a = A.abs(); return a.equals(ONE) ? 1 : 0; } if (!A.testBit(0) && !B.testBit(0)) { return 0; } a = A; b = B; if (b.signum() == -1) { // b < 0 b = b.negate(); // b = -b if (a.signum() == -1) { k = -1; } } v = ZERO; while (!b.testBit(0)) { v = v.add(ONE); // v = v + 1 b = b.divide(TWO); // b = b/2 } if (v.testBit(0)) { k = k * jacobiTable[a.intValue() & 7]; } if (a.signum() < 0) { // a < 0 if (b.testBit(1)) { k = -k; // k = -k } a = a.negate(); // a = -a } // main loop while (a.signum() != 0) { v = ZERO; while (!a.testBit(0)) { // a is even v = v.add(ONE); a = a.divide(TWO); } if (v.testBit(0)) { k = k * jacobiTable[b.intValue() & 7]; } if (a.compareTo(b) < 0) { // a < b // swap and correct intermediate result BigInteger x = a; a = b; b = x; if (a.testBit(1) && b.testBit(1)) { k = -k; } } a = a.subtract(b); } return b.equals(ONE) ? (int)k : 0; } /** * Computes the square root of a BigInteger modulo a prime employing the * Shanks-Tonelli algorithm. * * @param a value out of which we extract the square root * @param p prime modulus that determines the underlying field * @return a number b such that b2 = a (mod p) if * a is a quadratic residue modulo p. * @throws NoQuadraticResidueException if a is a quadratic non-residue modulo p */ public static BigInteger ressol(BigInteger a, BigInteger p) throws IllegalArgumentException { BigInteger v = null; if (a.compareTo(ZERO) < 0) { a = a.add(p); } if (a.equals(ZERO)) { return ZERO; } if (p.equals(TWO)) { return a; } // p = 3 mod 4 if (p.testBit(0) && p.testBit(1)) { if (jacobi(a, p) == 1) { // a quadr. residue mod p v = p.add(ONE); // v = p+1 v = v.shiftRight(2); // v = v/4 return a.modPow(v, p); // return a^v mod p // return --> a^((p+1)/4) mod p } throw new IllegalArgumentException("No quadratic residue: " + a + ", " + p); } long t = 0; // initialization // compute k and s, where p = 2^s (2k+1) +1 BigInteger k = p.subtract(ONE); // k = p-1 long s = 0; while (!k.testBit(0)) { // while k is even s++; // s = s+1 k = k.shiftRight(1); // k = k/2 } k = k.subtract(ONE); // k = k - 1 k = k.shiftRight(1); // k = k/2 // initial values BigInteger r = a.modPow(k, p); // r = a^k mod p BigInteger n = r.multiply(r).remainder(p); // n = r^2 % p n = n.multiply(a).remainder(p); // n = n * a % p r = r.multiply(a).remainder(p); // r = r * a %p if (n.equals(ONE)) { return r; } // non-quadratic residue BigInteger z = TWO; // z = 2 while (jacobi(z, p) == 1) { // while z quadratic residue z = z.add(ONE); // z = z + 1 } v = k; v = v.multiply(TWO); // v = 2k v = v.add(ONE); // v = 2k + 1 BigInteger c = z.modPow(v, p); // c = z^v mod p // iteration while (n.compareTo(ONE) == 1) { // n > 1 k = n; // k = n t = s; // t = s s = 0; while (!k.equals(ONE)) { // k != 1 k = k.multiply(k).mod(p); // k = k^2 % p s++; // s = s + 1 } t -= s; // t = t - s if (t == 0) { throw new IllegalArgumentException("No quadratic residue: " + a + ", " + p); } v = ONE; for (long i = 0; i < t - 1; i++) { v = v.shiftLeft(1); // v = 1 * 2^(t - 1) } c = c.modPow(v, p); // c = c^v mod p r = r.multiply(c).remainder(p); // r = r * c % p c = c.multiply(c).remainder(p); // c = c^2 % p n = n.multiply(c).mod(p); // n = n * c % p } return r; } /** * Computes the greatest common divisor of the two specified integers * * @param u - first integer * @param v - second integer * @return gcd(a, b) */ public static int gcd(int u, int v) { return BigInteger.valueOf(u).gcd(BigInteger.valueOf(v)).intValue(); } /** * Extended euclidian algorithm (computes gcd and representation). * * @param a the first integer * @param b the second integer * @return (g,u,v), where g = gcd(abs(a),abs(b)) = ua + vb */ public static int[] extGCD(int a, int b) { BigInteger ba = BigInteger.valueOf(a); BigInteger bb = BigInteger.valueOf(b); BigInteger[] bresult = extgcd(ba, bb); int[] result = new int[3]; result[0] = bresult[0].intValue(); result[1] = bresult[1].intValue(); result[2] = bresult[2].intValue(); return result; } public static BigInteger divideAndRound(BigInteger a, BigInteger b) { if (a.signum() < 0) { return divideAndRound(a.negate(), b).negate(); } if (b.signum() < 0) { return divideAndRound(a, b.negate()).negate(); } return a.shiftLeft(1).add(b).divide(b.shiftLeft(1)); } public static BigInteger[] divideAndRound(BigInteger[] a, BigInteger b) { BigInteger[] out = new BigInteger[a.length]; for (int i = 0; i < a.length; i++) { out[i] = divideAndRound(a[i], b); } return out; } /** * Compute the smallest integer that is greater than or equal to the * logarithm to the base 2 of the given BigInteger. * * @param a the integer * @return ceil[log(a)] */ public static int ceilLog(BigInteger a) { int result = 0; BigInteger p = ONE; while (p.compareTo(a) < 0) { result++; p = p.shiftLeft(1); } return result; } /** * Compute the smallest integer that is greater than or equal to the * logarithm to the base 2 of the given integer. * * @param a the integer * @return ceil[log(a)] */ public static int ceilLog(int a) { int log = 0; int i = 1; while (i < a) { i <<= 1; log++; } return log; } /** * Compute ceil(log_256 n), the number of bytes needed to encode * the integer n. * * @param n the integer * @return the number of bytes needed to encode n */ public static int ceilLog256(int n) { if (n == 0) { return 1; } int m; if (n < 0) { m = -n; } else { m = n; } int d = 0; while (m > 0) { d++; m >>>= 8; } return d; } /** * Compute ceil(log_256 n), the number of bytes needed to encode * the long integer n. * * @param n the long integer * @return the number of bytes needed to encode n */ public static int ceilLog256(long n) { if (n == 0) { return 1; } long m; if (n < 0) { m = -n; } else { m = n; } int d = 0; while (m > 0) { d++; m >>>= 8; } return d; } /** * Compute the integer part of the logarithm to the base 2 of the given * integer. * * @param a the integer * @return floor[log(a)] */ public static int floorLog(BigInteger a) { int result = -1; BigInteger p = ONE; while (p.compareTo(a) <= 0) { result++; p = p.shiftLeft(1); } return result; } /** * Compute the integer part of the logarithm to the base 2 of the given * integer. * * @param a the integer * @return floor[log(a)] */ public static int floorLog(int a) { int h = 0; if (a <= 0) { return -1; } int p = a >>> 1; while (p > 0) { h++; p >>>= 1; } return h; } /** * Compute the largest h with 2^h | a if a!=0. * * @param a an integer * @return the largest h with 2^h | a if a!=0, * 0 otherwise */ public static int maxPower(int a) { int h = 0; if (a != 0) { int p = 1; while ((a & p) == 0) { h++; p <<= 1; } } return h; } /** * @param a an integer * @return the number of ones in the binary representation of an integer * a */ public static int bitCount(int a) { int h = 0; while (a != 0) { h += a & 1; a >>>= 1; } return h; } /** * determines the order of g modulo p, p prime and 1 < g < p. This algorithm * is only efficient for small p (see X9.62-1998, p. 68). * * @param g an integer with 1 < g < p * @param p a prime * @return the order k of g (that is k is the smallest integer with * gk = 1 mod p */ public static int order(int g, int p) { int b, j; b = g % p; // Reduce g mod p first. j = 1; // Check whether g == 0 mod p (avoiding endless loop). if (b == 0) { throw new IllegalArgumentException(g + " is not an element of Z/(" + p + "Z)^*; it is not meaningful to compute its order."); } // Compute the order of g mod p: while (b != 1) { b *= g; b %= p; if (b < 0) { b += p; } j++; } return j; } /** * Reduces an integer into a given interval * * @param n - the integer * @param begin - left bound of the interval * @param end - right bound of the interval * @return n reduced into [begin,end] */ public static BigInteger reduceInto(BigInteger n, BigInteger begin, BigInteger end) { return n.subtract(begin).mod(end.subtract(begin)).add(begin); } /** * Compute ae. * * @param a the base * @param e the exponent * @return ae */ public static int pow(int a, int e) { int result = 1; while (e > 0) { if ((e & 1) == 1) { result *= a; } a *= a; e >>>= 1; } return result; } /** * Compute ae. * * @param a the base * @param e the exponent * @return ae */ public static long pow(long a, int e) { long result = 1; while (e > 0) { if ((e & 1) == 1) { result *= a; } a *= a; e >>>= 1; } return result; } /** * Compute ae mod n. * * @param a the base * @param e the exponent * @param n the modulus * @return ae mod n */ public static int modPow(int a, int e, int n) { if (n <= 0 || (n * n) > Integer.MAX_VALUE || e < 0) { return 0; } int result = 1; a = (a % n + n) % n; while (e > 0) { if ((e & 1) == 1) { result = (result * a) % n; } a = (a * a) % n; e >>>= 1; } return result; } /** * Extended euclidian algorithm (computes gcd and representation). * * @param a - the first integer * @param b - the second integer * @return (d,u,v), where d = gcd(a,b) = ua + vb */ public static BigInteger[] extgcd(BigInteger a, BigInteger b) { BigInteger u = ONE; BigInteger v = ZERO; BigInteger d = a; if (b.signum() != 0) { BigInteger v1 = ZERO; BigInteger v3 = b; while (v3.signum() != 0) { BigInteger[] tmp = d.divideAndRemainder(v3); BigInteger q = tmp[0]; BigInteger t3 = tmp[1]; BigInteger t1 = u.subtract(q.multiply(v1)); u = v1; d = v3; v1 = t1; v3 = t3; } v = d.subtract(a.multiply(u)).divide(b); } return new BigInteger[]{d, u, v}; } /** * Computation of the least common multiple of a set of BigIntegers. * * @param numbers - the set of numbers * @return the lcm(numbers) */ public static BigInteger leastCommonMultiple(BigInteger[] numbers) { int n = numbers.length; BigInteger result = numbers[0]; for (int i = 1; i < n; i++) { BigInteger gcd = result.gcd(numbers[i]); result = result.multiply(numbers[i]).divide(gcd); } return result; } /** * Returns a long integer whose value is (a mod m). This method * differs from % in that it always returns a non-negative * integer. * * @param a value on which the modulo operation has to be performed. * @param m the modulus. * @return a mod m */ public static long mod(long a, long m) { long result = a % m; if (result < 0) { result += m; } return result; } /** * Computes the modular inverse of an integer a * * @param a - the integer to invert * @param mod - the modulus * @return a-1 mod n */ public static int modInverse(int a, int mod) { return BigInteger.valueOf(a).modInverse(BigInteger.valueOf(mod)) .intValue(); } /** * Computes the modular inverse of an integer a * * @param a - the integer to invert * @param mod - the modulus * @return a-1 mod n */ public static long modInverse(long a, long mod) { return BigInteger.valueOf(a).modInverse(BigInteger.valueOf(mod)) .longValue(); } /** * Tests whether an integer a is power of another integer * p. * * @param a - the first integer * @param p - the second integer * @return n if a = p^n or -1 otherwise */ public static int isPower(int a, int p) { if (a <= 0) { return -1; } int n = 0; int d = a; while (d > 1) { if (d % p != 0) { return -1; } d /= p; n++; } return n; } /** * Find and return the least non-trivial divisor of an integer a. * * @param a - the integer * @return divisor p >1 or 1 if a = -1,0,1 */ public static int leastDiv(int a) { if (a < 0) { a = -a; } if (a == 0) { return 1; } if ((a & 1) == 0) { return 2; } int p = 3; while (p <= (a / p)) { if ((a % p) == 0) { return p; } p += 2; } return a; } /** * Miller-Rabin-Test, determines wether the given integer is probably prime * or composite. This method returns true if the given integer is * prime with probability 1 - 2-20. * * @param n the integer to test for primality * @return true if the given integer is prime with probability * 2-100, false otherwise */ public static boolean isPrime(int n) { if (n < 2) { return false; } if (n == 2) { return true; } if ((n & 1) == 0) { return false; } if (n < 42) { for (int i = 0; i < SMALL_PRIMES.length; i++) { if (n == SMALL_PRIMES[i]) { return true; } } } if ((n % 3 == 0) || (n % 5 == 0) || (n % 7 == 0) || (n % 11 == 0) || (n % 13 == 0) || (n % 17 == 0) || (n % 19 == 0) || (n % 23 == 0) || (n % 29 == 0) || (n % 31 == 0) || (n % 37 == 0) || (n % 41 == 0)) { return false; } return BigInteger.valueOf(n).isProbablePrime(20); } /** * Short trial-division test to find out whether a number is not prime. This * test is usually used before a Miller-Rabin primality test. * * @param candidate the number to test * @return true if the number has no factor of the tested primes, * false if the number is definitely composite */ public static boolean passesSmallPrimeTest(BigInteger candidate) { final int[] smallPrime = {2, 3, 5, 7, 11, 13, 17, 19, 23, 29, 31, 37, 41, 43, 47, 53, 59, 61, 67, 71, 73, 79, 83, 89, 97, 101, 103, 107, 109, 113, 127, 131, 137, 139, 149, 151, 157, 163, 167, 173, 179, 181, 191, 193, 197, 199, 211, 223, 227, 229, 233, 239, 241, 251, 257, 263, 269, 271, 277, 281, 283, 293, 307, 311, 313, 317, 331, 337, 347, 349, 353, 359, 367, 373, 379, 383, 389, 397, 401, 409, 419, 421, 431, 433, 439, 443, 449, 457, 461, 463, 467, 479, 487, 491, 499, 503, 509, 521, 523, 541, 547, 557, 563, 569, 571, 577, 587, 593, 599, 601, 607, 613, 617, 619, 631, 641, 643, 647, 653, 659, 661, 673, 677, 683, 691, 701, 709, 719, 727, 733, 739, 743, 751, 757, 761, 769, 773, 787, 797, 809, 811, 821, 823, 827, 829, 839, 853, 857, 859, 863, 877, 881, 883, 887, 907, 911, 919, 929, 937, 941, 947, 953, 967, 971, 977, 983, 991, 997, 1009, 1013, 1019, 1021, 1031, 1033, 1039, 1049, 1051, 1061, 1063, 1069, 1087, 1091, 1093, 1097, 1103, 1109, 1117, 1123, 1129, 1151, 1153, 1163, 1171, 1181, 1187, 1193, 1201, 1213, 1217, 1223, 1229, 1231, 1237, 1249, 1259, 1277, 1279, 1283, 1289, 1291, 1297, 1301, 1303, 1307, 1319, 1321, 1327, 1361, 1367, 1373, 1381, 1399, 1409, 1423, 1427, 1429, 1433, 1439, 1447, 1451, 1453, 1459, 1471, 1481, 1483, 1487, 1489, 1493, 1499}; for (int i = 0; i < smallPrime.length; i++) { if (candidate.mod(BigInteger.valueOf(smallPrime[i])).equals( ZERO)) { return false; } } return true; } /** * Returns the largest prime smaller than the given integer * * @param n - upper bound * @return the largest prime smaller than n, or 1 if * n <= 2 */ public static int nextSmallerPrime(int n) { if (n <= 2) { return 1; } if (n == 3) { return 2; } if ((n & 1) == 0) { n--; } else { n -= 2; } while (n > 3 & !isPrime(n)) { n -= 2; } return n; } /** * Compute the next probable prime greater than n with the * specified certainty. * * @param n a integer number * @param certainty the certainty that the generated number is prime * @return the next prime greater than n */ public static BigInteger nextProbablePrime(BigInteger n, int certainty) { if (n.signum() < 0 || n.signum() == 0 || n.equals(ONE)) { return TWO; } BigInteger result = n.add(ONE); // Ensure an odd number if (!result.testBit(0)) { result = result.add(ONE); } while (true) { // Do cheap "pre-test" if applicable if (result.bitLength() > 6) { long r = result.remainder( BigInteger.valueOf(SMALL_PRIME_PRODUCT)).longValue(); if ((r % 3 == 0) || (r % 5 == 0) || (r % 7 == 0) || (r % 11 == 0) || (r % 13 == 0) || (r % 17 == 0) || (r % 19 == 0) || (r % 23 == 0) || (r % 29 == 0) || (r % 31 == 0) || (r % 37 == 0) || (r % 41 == 0)) { result = result.add(TWO); continue; // Candidate is composite; try another } } // All candidates of bitLength 2 and 3 are prime by this point if (result.bitLength() < 4) { return result; } // The expensive test if (result.isProbablePrime(certainty)) { return result; } result = result.add(TWO); } } /** * Compute the next probable prime greater than n with the default * certainty (20). * * @param n a integer number * @return the next prime greater than n */ public static BigInteger nextProbablePrime(BigInteger n) { return nextProbablePrime(n, 20); } /** * Computes the next prime greater than n. * * @param n a integer number * @return the next prime greater than n */ public static BigInteger nextPrime(long n) { long i; boolean found = false; long result = 0; if (n <= 1) { return BigInteger.valueOf(2); } if (n == 2) { return BigInteger.valueOf(3); } for (i = n + 1 + (n & 1); (i <= n << 1) && !found; i += 2) { for (long j = 3; (j <= i >> 1) && !found; j += 2) { if (i % j == 0) { found = true; } } if (found) { found = false; } else { result = i; found = true; } } return BigInteger.valueOf(result); } /** * Computes the binomial coefficient (n|t) ("n over t"). Formula:
    *

      *
    • if n !=0 and t != 0 then (n|t) = Mult(i=1, t): (n-(i-1))/i
    • *
    • if t = 0 then (n|t) = 1
    • *
    • if n = 0 and t > 0 then (n|t) = 0
    • *
    * * @param n - the "upper" integer * @param t - the "lower" integer * @return the binomialcoefficient "n over t" as BigInteger */ public static BigInteger binomial(int n, int t) { BigInteger result = ONE; if (n == 0) { if (t == 0) { return result; } return ZERO; } // the property (n|t) = (n|n-t) be used to reduce numbers of operations if (t > (n >>> 1)) { t = n - t; } for (int i = 1; i <= t; i++) { result = (result.multiply(BigInteger.valueOf(n - (i - 1)))) .divide(BigInteger.valueOf(i)); } return result; } public static BigInteger randomize(BigInteger upperBound) { if (sr == null) { sr = new SecureRandom(); } return randomize(upperBound, sr); } public static BigInteger randomize(BigInteger upperBound, SecureRandom prng) { int blen = upperBound.bitLength(); BigInteger randomNum = BigInteger.valueOf(0); if (prng == null) { prng = sr != null ? sr : new SecureRandom(); } for (int i = 0; i < 20; i++) { randomNum = new BigInteger(blen, prng); if (randomNum.compareTo(upperBound) < 0) { return randomNum; } } return randomNum.mod(upperBound); } /** * Extract the truncated square root of a BigInteger. * * @param a - value out of which we extract the square root * @return the truncated square root of a */ public static BigInteger squareRoot(BigInteger a) { int bl; BigInteger result, remainder, b; if (a.compareTo(ZERO) < 0) { throw new ArithmeticException( "cannot extract root of negative number" + a + "."); } bl = a.bitLength(); result = ZERO; remainder = ZERO; // if the bit length is odd then extra step if ((bl & 1) != 0) { result = result.add(ONE); bl--; } while (bl > 0) { remainder = remainder.multiply(FOUR); remainder = remainder.add(BigInteger.valueOf((a.testBit(--bl) ? 2 : 0) + (a.testBit(--bl) ? 1 : 0))); b = result.multiply(FOUR).add(ONE); result = result.multiply(TWO); if (remainder.compareTo(b) != -1) { result = result.add(ONE); remainder = remainder.subtract(b); } } return result; } /** * Takes an approximation of the root from an integer base, using newton's * algorithm * * @param base the base to take the root from * @param root the root, for example 2 for a square root */ public static float intRoot(int base, int root) { float gNew = base / root; float gOld = 0; int counter = 0; while (Math.abs(gOld - gNew) > 0.0001) { float gPow = floatPow(gNew, root); while (Float.isInfinite(gPow)) { gNew = (gNew + gOld) / 2; gPow = floatPow(gNew, root); } counter += 1; gOld = gNew; gNew = gOld - (gPow - base) / (root * floatPow(gOld, root - 1)); } return gNew; } /** * Calculation of a logarithmus of a float param * * @param param * @return */ public static float floatLog(float param) { double arg = (param - 1) / (param + 1); double arg2 = arg; int counter = 1; float result = (float)arg; while (arg2 > 0.001) { counter += 2; arg2 *= arg * arg; result += (1. / counter) * arg2; } return 2 * result; } /** * int power of a base float, only use for small ints * * @param f * @param i * @return */ public static float floatPow(float f, int i) { float g = 1; for (; i > 0; i--) { g *= f; } return g; } /** * calculate the logarithm to the base 2. * * @param x any double value * @return log_2(x) * @deprecated use MathFunctions.log(double) instead */ public static double log(double x) { if (x > 0 && x < 1) { double d = 1 / x; double result = -log(d); return result; } int tmp = 0; double tmp2 = 1; double d = x; while (d > 2) { d = d / 2; tmp += 1; tmp2 *= 2; } double rem = x / tmp2; rem = logBKM(rem); return tmp + rem; } /** * calculate the logarithm to the base 2. * * @param x any long value >=1 * @return log_2(x) * @deprecated use MathFunctions.log(long) instead */ public static double log(long x) { int tmp = floorLog(BigInteger.valueOf(x)); long tmp2 = 1 << tmp; double rem = (double)x / (double)tmp2; rem = logBKM(rem); return tmp + rem; } /** * BKM Algorithm to calculate logarithms to the base 2. * * @param arg a double value with 1<= arg<= 4.768462058 * @return log_2(arg) * @deprecated use MathFunctions.logBKM(double) instead */ private static double logBKM(double arg) { double ae[] = // A_e[k] = log_2 (1 + 0.5^k) { 1.0000000000000000000000000000000000000000000000000000000000000000000000000000, 0.5849625007211561814537389439478165087598144076924810604557526545410982276485, 0.3219280948873623478703194294893901758648313930245806120547563958159347765589, 0.1699250014423123629074778878956330175196288153849621209115053090821964552970, 0.0874628412503394082540660108104043540112672823448206881266090643866965081686, 0.0443941193584534376531019906736094674630459333742491317685543002674288465967, 0.0223678130284545082671320837460849094932677948156179815932199216587899627785, 0.0112272554232541203378805844158839407281095943600297940811823651462712311786, 0.0056245491938781069198591026740666017211096815383520359072957784732489771013, 0.0028150156070540381547362547502839489729507927389771959487826944878598909400, 0.0014081943928083889066101665016890524233311715793462235597709051792834906001, 0.0007042690112466432585379340422201964456668872087249334581924550139514213168, 0.0003521774803010272377989609925281744988670304302127133979341729842842377649, 0.0001760994864425060348637509459678580940163670081839283659942864068257522373, 0.0000880524301221769086378699983597183301490534085738474534831071719854721939, 0.0000440268868273167176441087067175806394819146645511899503059774914593663365, 0.0000220136113603404964890728830697555571275493801909791504158295359319433723, 0.0000110068476674814423006223021573490183469930819844945565597452748333526464, 0.0000055034343306486037230640321058826431606183125807276574241540303833251704, 0.0000027517197895612831123023958331509538486493412831626219340570294203116559, 0.0000013758605508411382010566802834037147561973553922354232704569052932922954, 0.0000006879304394358496786728937442939160483304056131990916985043387874690617, 0.0000003439652607217645360118314743718005315334062644619363447395987584138324, 0.0000001719826406118446361936972479533123619972434705828085978955697643547921, 0.0000000859913228686632156462565208266682841603921494181830811515318381744650, 0.0000000429956620750168703982940244684787907148132725669106053076409624949917, 0.0000000214978311976797556164155504126645192380395989504741781512309853438587, 0.0000000107489156388827085092095702361647949603617203979413516082280717515504, 0.0000000053744578294520620044408178949217773318785601260677517784797554422804, 0.0000000026872289172287079490026152352638891824761667284401180026908031182361, 0.0000000013436144592400232123622589569799954658536700992739887706412976115422, 0.0000000006718072297764289157920422846078078155859484240808550018085324187007, 0.0000000003359036149273187853169587152657145221968468364663464125722491530858, 0.0000000001679518074734354745159899223037458278711244127245990591908996412262, 0.0000000000839759037391617577226571237484864917411614198675604731728132152582, 0.0000000000419879518701918839775296677020135040214077417929807824842667285938, 0.0000000000209939759352486932678195559552767641474249812845414125580747434389, 0.0000000000104969879676625344536740142096218372850561859495065136990936290929, 0.0000000000052484939838408141817781356260462777942148580518406975851213868092, 0.0000000000026242469919227938296243586262369156865545638305682553644113887909, 0.0000000000013121234959619935994960031017850191710121890821178731821983105443, 0.0000000000006560617479811459709189576337295395590603644549624717910616347038, 0.0000000000003280308739906102782522178545328259781415615142931952662153623493, 0.0000000000001640154369953144623242936888032768768777422997704541618141646683, 0.0000000000000820077184976595619616930350508356401599552034612281802599177300, 0.0000000000000410038592488303636807330652208397742314215159774270270147020117, 0.0000000000000205019296244153275153381695384157073687186580546938331088730952, 0.0000000000000102509648122077001764119940017243502120046885379813510430378661, 0.0000000000000051254824061038591928917243090559919209628584150482483994782302, 0.0000000000000025627412030519318726172939815845367496027046030028595094737777, 0.0000000000000012813706015259665053515049475574143952543145124550608158430592, 0.0000000000000006406853007629833949364669629701200556369782295210193569318434, 0.0000000000000003203426503814917330334121037829290364330169106716787999052925, 0.0000000000000001601713251907458754080007074659337446341494733882570243497196, 0.0000000000000000800856625953729399268240176265844257044861248416330071223615, 0.0000000000000000400428312976864705191179247866966320469710511619971334577509, 0.0000000000000000200214156488432353984854413866994246781519154793320684126179, 0.0000000000000000100107078244216177339743404416874899847406043033792202127070, 0.0000000000000000050053539122108088756700751579281894640362199287591340285355, 0.0000000000000000025026769561054044400057638132352058574658089256646014899499, 0.0000000000000000012513384780527022205455634651853807110362316427807660551208, 0.0000000000000000006256692390263511104084521222346348012116229213309001913762, 0.0000000000000000003128346195131755552381436585278035120438976487697544916191, 0.0000000000000000001564173097565877776275512286165232838833090480508502328437, 0.0000000000000000000782086548782938888158954641464170239072244145219054734086, 0.0000000000000000000391043274391469444084776945327473574450334092075712154016, 0.0000000000000000000195521637195734722043713378812583900953755962557525252782, 0.0000000000000000000097760818597867361022187915943503728909029699365320287407, 0.0000000000000000000048880409298933680511176764606054809062553340323879609794, 0.0000000000000000000024440204649466840255609083961603140683286362962192177597, 0.0000000000000000000012220102324733420127809717395445504379645613448652614939, 0.0000000000000000000006110051162366710063906152551383735699323415812152114058, 0.0000000000000000000003055025581183355031953399739107113727036860315024588989, 0.0000000000000000000001527512790591677515976780735407368332862218276873443537, 0.0000000000000000000000763756395295838757988410584167137033767056170417508383, 0.0000000000000000000000381878197647919378994210346199431733717514843471513618, 0.0000000000000000000000190939098823959689497106436628681671067254111334889005, 0.0000000000000000000000095469549411979844748553534196582286585751228071408728, 0.0000000000000000000000047734774705989922374276846068851506055906657137209047, 0.0000000000000000000000023867387352994961187138442777065843718711089344045782, 0.0000000000000000000000011933693676497480593569226324192944532044984865894525, 0.0000000000000000000000005966846838248740296784614396011477934194852481410926, 0.0000000000000000000000002983423419124370148392307506484490384140516252814304, 0.0000000000000000000000001491711709562185074196153830361933046331030629430117, 0.0000000000000000000000000745855854781092537098076934460888486730708440475045, 0.0000000000000000000000000372927927390546268549038472050424734256652501673274, 0.0000000000000000000000000186463963695273134274519237230207489851150821191330, 0.0000000000000000000000000093231981847636567137259618916352525606281553180093, 0.0000000000000000000000000046615990923818283568629809533488457973317312233323, 0.0000000000000000000000000023307995461909141784314904785572277779202790023236, 0.0000000000000000000000000011653997730954570892157452397493151087737428485431, 0.0000000000000000000000000005826998865477285446078726199923328593402722606924, 0.0000000000000000000000000002913499432738642723039363100255852559084863397344, 0.0000000000000000000000000001456749716369321361519681550201473345138307215067, 0.0000000000000000000000000000728374858184660680759840775119123438968122488047, 0.0000000000000000000000000000364187429092330340379920387564158411083803465567, 0.0000000000000000000000000000182093714546165170189960193783228378441837282509, 0.0000000000000000000000000000091046857273082585094980096891901482445902524441, 0.0000000000000000000000000000045523428636541292547490048446022564529197237262, 0.0000000000000000000000000000022761714318270646273745024223029238091160103901}; int n = 53; double x = 1; double y = 0; double z; double s = 1; int k; for (k = 0; k < n; k++) { z = x + x * s; if (z <= arg) { x = z; y += ae[k]; } s *= 0.5; } return y; } public static boolean isIncreasing(int[] a) { for (int i = 1; i < a.length; i++) { if (a[i - 1] >= a[i]) { System.out.println("a[" + (i - 1) + "] = " + a[i - 1] + " >= " + a[i] + " = a[" + i + "]"); return false; } } return true; } public static byte[] integerToOctets(BigInteger val) { byte[] valBytes = val.abs().toByteArray(); // check whether the array includes a sign bit if ((val.bitLength() & 7) != 0) { return valBytes; } // get rid of the sign bit (first byte) byte[] tmp = new byte[val.bitLength() >> 3]; System.arraycopy(valBytes, 1, tmp, 0, tmp.length); return tmp; } public static BigInteger octetsToInteger(byte[] data, int offset, int length) { byte[] val = new byte[length + 1]; val[0] = 0; System.arraycopy(data, offset, val, 1, length); return new BigInteger(val); } public static BigInteger octetsToInteger(byte[] data) { return octetsToInteger(data, 0, data.length); } public static void main(String[] args) { System.out.println("test"); // System.out.println(intRoot(37, 5)); // System.out.println(floatPow((float)2.5, 4)); System.out.println(floatLog(10)); System.out.println("test2"); } } bouncycastle-1.49.orig/src/org/bouncycastle/pqc/math/linearalgebra/GF2nONBField.java0000644000175000017500000004031612043365070027714 0ustar ebourgebourgpackage org.bouncycastle.pqc.math.linearalgebra; import java.util.Random; import java.util.Vector; /** * This class implements the abstract class GF2nField for ONB * representation. It computes the fieldpolynomial, multiplication matrix and * one of its roots mONBRoot, (see for example Certicoms Whitepapers). * GF2nField is used by GF2nONBElement which implements the elements of this * field. * * @see GF2nField * @see GF2nONBElement */ public class GF2nONBField extends GF2nField { // /////////////////////////////////////////////////////////////////// // Hashtable for irreducible normal polynomials // // /////////////////////////////////////////////////////////////////// // i*5 + 0 i*5 + 1 i*5 + 2 i*5 + 3 i*5 + 4 /* * private static int[][] mNB = {{0, 0, 0}, {0, 0, 0}, {1, 0, 0}, {1, 0, 0}, * {1, 0, 0}, // i = 0 {2, 0, 0}, {1, 0, 0}, {1, 0, 0}, {4, 3, 1}, {1, 0, * 0}, // i = 1 {3, 0, 0}, {2, 0, 0}, {3, 0, 0}, {4, 3, 1}, {5, 0, 0}, // i = * 2 {1, 0, 0}, {5, 3, 1}, {3, 0, 0}, {3, 0, 0}, {5, 2, 1}, // i = 3 {3, 0, * 0}, {2, 0, 0}, {1, 0, 0}, {5, 0, 0}, {4, 3, 1}, // i = 4 {3, 0, 0}, {4, * 3, 1}, {5, 2, 1}, {1, 0, 0}, {2, 0, 0}, // i = 5 {1, 0, 0}, {3, 0, 0}, * {7, 3, 2}, {10, 0, 0}, {7, 0, 0}, // i = 6 {2, 0, 0}, {9, 0, 0}, {6, 4, * 1}, {6, 5, 1}, {4, 0, 0}, // i = 7 {5, 4, 3}, {3, 0, 0}, {7, 0, 0}, {6, * 4, 3}, {5, 0, 0}, // i = 8 {4, 3, 1}, {1, 0, 0}, {5, 0, 0}, {5, 3, 2}, * {9, 0, 0}, // i = 9 {4, 3, 2}, {6, 3, 1}, {3, 0, 0}, {6, 2, 1}, {9, 0, * 0}, // i = 10 {7, 0, 0}, {7, 4, 2}, {4, 0, 0}, {19, 0, 0}, {7, 4, 2}, // * i = 11 {1, 0, 0}, {5, 2, 1}, {29, 0, 0}, {1, 0, 0}, {4, 3, 1}, // i = 12 * {18, 0, 0}, {3, 0, 0}, {5, 2, 1}, {9, 0, 0}, {6, 5, 2}, // i = 13 {5, 3, * 1}, {6, 0, 0}, {10, 9, 3}, {25, 0, 0}, {35, 0, 0}, // i = 14 {6, 3, 1}, * {21, 0, 0}, {6, 5, 2}, {6, 5, 3}, {9, 0, 0}, // i = 15 {9, 4, 2}, {4, 0, * 0}, {8, 3, 1}, {7, 4, 2}, {5, 0, 0}, // i = 16 {8, 2, 1}, {21, 0, 0}, * {13, 0, 0}, {7, 6, 2}, {38, 0, 0}, // i = 17 {27, 0, 0}, {8, 5, 1}, {21, * 0, 0}, {2, 0, 0}, {21, 0, 0}, // i = 18 {11, 0, 0}, {10, 9, 6}, {6, 0, * 0}, {11, 0, 0}, {6, 3, 1}, // i = 19 {15, 0, 0}, {7, 6, 1}, {29, 0, 0}, * {9, 0, 0}, {4, 3, 1}, // i = 20 {4, 0, 0}, {15, 0, 0}, {9, 7, 4}, {17, 0, * 0}, {5, 4, 2}, // i = 21 {33, 0, 0}, {10, 0, 0}, {5, 4, 3}, {9, 0, 0}, * {5, 3, 2}, // i = 22 {8, 7, 5}, {4, 2, 1}, {5, 2, 1}, {33, 0, 0}, {8, 0, * 0}, // i = 23 {4, 3, 1}, {18, 0, 0}, {6, 2, 1}, {2, 0, 0}, {19, 0, 0}, // * i = 24 {7, 6, 5}, {21, 0, 0}, {1, 0, 0}, {7, 2, 1}, {5, 0, 0}, // i = 25 * {3, 0, 0}, {8, 3, 2}, {17, 0, 0}, {9, 8, 2}, {57, 0, 0}, // i = 26 {11, * 0, 0}, {5, 3, 2}, {21, 0, 0}, {8, 7, 1}, {8, 5, 3}, // i = 27 {15, 0, 0}, * {10, 4, 1}, {21, 0, 0}, {5, 3, 2}, {7, 4, 2}, // i = 28 {52, 0, 0}, {71, * 0, 0}, {14, 0, 0}, {27, 0, 0}, {10, 9, 7}, // i = 29 {53, 0, 0}, {3, 0, * 0}, {6, 3, 2}, {1, 0, 0}, {15, 0, 0}, // i = 30 {62, 0, 0}, {9, 0, 0}, * {6, 5, 2}, {8, 6, 5}, {31, 0, 0}, // i = 31 {5, 3, 2}, {18, 0, 0 }, {27, * 0, 0}, {7, 6, 3}, {10, 8, 7}, // i = 32 {9, 8, 3}, {37, 0, 0}, {6, 0, 0}, * {15, 3, 2}, {34, 0, 0}, // i = 33 {11, 0, 0}, {6, 5, 2}, {1, 0, 0}, {8, * 5, 2}, {13, 0, 0}, // i = 34 {6, 0, 0}, {11, 3, 2}, {8, 0, 0}, {31, 0, * 0}, {4, 2, 1}, // i = 35 {3, 0, 0}, {7, 6, 1}, {81, 0, 0}, {56, 0, 0}, * {9, 8, 7}, // i = 36 {24, 0, 0}, {11, 0, 0}, {7, 6, 5}, {6, 5, 2}, {6, 5, * 2}, // i = 37 {8, 7, 6}, {9, 0, 0}, {7, 2, 1}, {15, 0, 0}, {87, 0, 0}, // * i = 38 {8, 3, 2}, {3, 0, 0}, {9, 4, 2}, {9, 0, 0}, {34, 0, 0}, // i = 39 * {5, 3, 2}, {14, 0, 0}, {55, 0, 0}, {8, 7, 1}, {27, 0, 0}, // i = 40 {9, * 5, 2}, {10, 9, 5}, {43, 0, 0}, {8, 6, 2}, {6, 0, 0}, // i = 41 {7, 0, 0}, * {11, 10, 8}, {105, 0, 0}, {6, 5, 2}, {73, 0, 0}}; // i = 42 */ // ///////////////////////////////////////////////////////////////////// // member variables // ///////////////////////////////////////////////////////////////////// private static final int MAXLONG = 64; /** * holds the length of the array-representation of degree mDegree. */ private int mLength; /** * holds the number of relevant bits in mONBPol[mLength-1]. */ private int mBit; /** * holds the type of mONB */ private int mType; /** * holds the multiplication matrix */ int[][] mMult; // ///////////////////////////////////////////////////////////////////// // constructors // ///////////////////////////////////////////////////////////////////// /** * constructs an instance of the finite field with 2deg * elements and characteristic 2. * * @param deg - * the extention degree of this field * @throws NoSuchBasisException if an ONB-implementation other than type 1 or type 2 is * requested. */ public GF2nONBField(int deg) throws RuntimeException { if (deg < 3) { throw new IllegalArgumentException("k must be at least 3"); } mDegree = deg; mLength = mDegree / MAXLONG; mBit = mDegree & (MAXLONG - 1); if (mBit == 0) { mBit = MAXLONG; } else { mLength++; } computeType(); // only ONB-implementations for type 1 and type 2 // if (mType < 3) { mMult = new int[mDegree][2]; for (int i = 0; i < mDegree; i++) { mMult[i][0] = -1; mMult[i][1] = -1; } computeMultMatrix(); } else { throw new RuntimeException("\nThe type of this field is " + mType); } computeFieldPolynomial(); fields = new Vector(); matrices = new Vector(); } // ///////////////////////////////////////////////////////////////////// // access // ///////////////////////////////////////////////////////////////////// int getONBLength() { return mLength; } int getONBBit() { return mBit; } // ///////////////////////////////////////////////////////////////////// // arithmetic // ///////////////////////////////////////////////////////////////////// /** * Computes a random root of the given polynomial. * * @param polynomial a polynomial * @return a random root of the polynomial * @see "P1363 A.5.6, p103f" */ protected GF2nElement getRandomRoot(GF2Polynomial polynomial) { // We are in B1!!! GF2nPolynomial c; GF2nPolynomial ut; GF2nElement u; GF2nPolynomial h; int hDegree; // 1. Set g(t) <- f(t) GF2nPolynomial g = new GF2nPolynomial(polynomial, this); int gDegree = g.getDegree(); int i; // 2. while deg(g) > 1 while (gDegree > 1) { do { // 2.1 choose random u (element of) GF(2^m) u = new GF2nONBElement(this, new Random()); ut = new GF2nPolynomial(2, GF2nONBElement.ZERO(this)); // 2.2 Set c(t) <- ut ut.set(1, u); c = new GF2nPolynomial(ut); // 2.3 For i from 1 to m-1 do for (i = 1; i <= mDegree - 1; i++) { // 2.3.1 c(t) <- (c(t)^2 + ut) mod g(t) c = c.multiplyAndReduce(c, g); c = c.add(ut); } // 2.4 set h(t) <- GCD(c(t), g(t)) h = c.gcd(g); // 2.5 if h(t) is constant or deg(g) = deg(h) then go to // step 2.1 hDegree = h.getDegree(); gDegree = g.getDegree(); } while ((hDegree == 0) || (hDegree == gDegree)); // 2.6 If 2deg(h) > deg(g) then set g(t) <- g(t)/h(t) ... if ((hDegree << 1) > gDegree) { g = g.quotient(h); } else { // ... else g(t) <- h(t) g = new GF2nPolynomial(h); } gDegree = g.getDegree(); } // 3. Output g(0) return g.at(0); } /** * Computes the change-of-basis matrix for basis conversion according to * 1363. The result is stored in the lists fields and matrices. * * @param B1 the GF2nField to convert to * @see "P1363 A.7.3, p111ff" */ protected void computeCOBMatrix(GF2nField B1) { // we are in B0 here! if (mDegree != B1.mDegree) { throw new IllegalArgumentException( "GF2nField.computeCOBMatrix: B1 has a " + "different degree and thus cannot be coverted to!"); } int i, j; GF2nElement[] gamma; GF2nElement u; GF2Polynomial[] COBMatrix = new GF2Polynomial[mDegree]; for (i = 0; i < mDegree; i++) { COBMatrix[i] = new GF2Polynomial(mDegree); } // find Random Root do { // u is in representation according to B1 u = B1.getRandomRoot(fieldPolynomial); } while (u.isZero()); gamma = new GF2nPolynomialElement[mDegree]; // build gamma matrix by squaring gamma[0] = (GF2nElement)u.clone(); for (i = 1; i < mDegree; i++) { gamma[i] = gamma[i - 1].square(); } // convert horizontal gamma matrix by vertical Bitstrings for (i = 0; i < mDegree; i++) { for (j = 0; j < mDegree; j++) { if (gamma[i].testBit(j)) { COBMatrix[mDegree - j - 1].setBit(mDegree - i - 1); } } } fields.addElement(B1); matrices.addElement(COBMatrix); B1.fields.addElement(this); B1.matrices.addElement(invertMatrix(COBMatrix)); } /** * Computes the field polynomial for a ONB according to IEEE 1363 A.7.2 * (p110f). * * @see "P1363 A.7.2, p110f" */ protected void computeFieldPolynomial() { if (mType == 1) { fieldPolynomial = new GF2Polynomial(mDegree + 1, "ALL"); } else if (mType == 2) { // 1. q = 1 GF2Polynomial q = new GF2Polynomial(mDegree + 1, "ONE"); // 2. p = t+1 GF2Polynomial p = new GF2Polynomial(mDegree + 1, "X"); p.addToThis(q); GF2Polynomial r; int i; // 3. for i = 1 to (m-1) do for (i = 1; i < mDegree; i++) { // r <- q r = q; // q <- p q = p; // p = tq+r p = q.shiftLeft(); p.addToThis(r); } fieldPolynomial = p; } } /** * Compute the inverse of a matrix a. * * @param a the matrix * @return a-1 */ int[][] invMatrix(int[][] a) { int[][] A = new int[mDegree][mDegree]; A = a; int[][] inv = new int[mDegree][mDegree]; for (int i = 0; i < mDegree; i++) { inv[i][i] = 1; } for (int i = 0; i < mDegree; i++) { for (int j = i; j < mDegree; j++) { A[mDegree - 1 - i][j] = A[i][i]; } } return null; } private void computeType() throws RuntimeException { if ((mDegree & 7) == 0) { throw new RuntimeException( "The extension degree is divisible by 8!"); } // checking for the type int s = 0; int k = 0; mType = 1; for (int d = 0; d != 1; mType++) { s = mType * mDegree + 1; if (IntegerFunctions.isPrime(s)) { k = IntegerFunctions.order(2, s); d = IntegerFunctions.gcd(mType * mDegree / k, mDegree); } } mType--; if (mType == 1) { s = (mDegree << 1) + 1; if (IntegerFunctions.isPrime(s)) { k = IntegerFunctions.order(2, s); int d = IntegerFunctions.gcd((mDegree << 1) / k, mDegree); if (d == 1) { mType++; } } } } private void computeMultMatrix() { if ((mType & 7) != 0) { int p = mType * mDegree + 1; // compute sequence F[1] ... F[p-1] via A.3.7. of 1363. // F[0] will not be filled! // int[] F = new int[p]; int u; if (mType == 1) { u = 1; } else if (mType == 2) { u = p - 1; } else { u = elementOfOrder(mType, p); } int w = 1; int n; for (int j = 0; j < mType; j++) { n = w; for (int i = 0; i < mDegree; i++) { F[n] = i; n = (n << 1) % p; if (n < 0) { n += p; } } w = u * w % p; if (w < 0) { w += p; } } // building the matrix (mDegree * 2) // if (mType == 1) { for (int k = 1; k < p - 1; k++) { if (mMult[F[k + 1]][0] == -1) { mMult[F[k + 1]][0] = F[p - k]; } else { mMult[F[k + 1]][1] = F[p - k]; } } int m_2 = mDegree >> 1; for (int k = 1; k <= m_2; k++) { if (mMult[k - 1][0] == -1) { mMult[k - 1][0] = m_2 + k - 1; } else { mMult[k - 1][1] = m_2 + k - 1; } if (mMult[m_2 + k - 1][0] == -1) { mMult[m_2 + k - 1][0] = k - 1; } else { mMult[m_2 + k - 1][1] = k - 1; } } } else if (mType == 2) { for (int k = 1; k < p - 1; k++) { if (mMult[F[k + 1]][0] == -1) { mMult[F[k + 1]][0] = F[p - k]; } else { mMult[F[k + 1]][1] = F[p - k]; } } } else { throw new RuntimeException("only type 1 or type 2 implemented"); } } else { throw new RuntimeException("bisher nur fuer Gausssche Normalbasen" + " implementiert"); } } private int elementOfOrder(int k, int p) { Random random = new Random(); int m = 0; while (m == 0) { m = random.nextInt(); m %= p - 1; if (m < 0) { m += p - 1; } } int l = IntegerFunctions.order(m, p); while (l % k != 0 || l == 0) { while (m == 0) { m = random.nextInt(); m %= p - 1; if (m < 0) { m += p - 1; } } l = IntegerFunctions.order(m, p); } int r = m; l = k / l; for (int i = 2; i <= l; i++) { r *= m; } return r; } } bouncycastle-1.49.orig/src/org/bouncycastle/pqc/math/linearalgebra/GF2mMatrix.java0000644000175000017500000002370312043365070027576 0ustar ebourgebourgpackage org.bouncycastle.pqc.math.linearalgebra; /** * This class describes some operations with matrices over finite field GF(2m) * with small m (1< m <32). * * @see Matrix */ public class GF2mMatrix extends Matrix { /** * finite field GF(2^m) */ protected GF2mField field; /** * For the matrix representation the array of type int[][] is used, thus * every element of the array keeps one element of the matrix (element from * finite field GF(2^m)) */ protected int[][] matrix; /** * Constructor. * * @param field a finite field GF(2^m) * @param enc byte[] matrix in byte array form */ public GF2mMatrix(GF2mField field, byte[] enc) { this.field = field; // decode matrix int d = 8; int count = 1; while (field.getDegree() > d) { count++; d += 8; } if (enc.length < 5) { throw new IllegalArgumentException( " Error: given array is not encoded matrix over GF(2^m)"); } this.numRows = ((enc[3] & 0xff) << 24) ^ ((enc[2] & 0xff) << 16) ^ ((enc[1] & 0xff) << 8) ^ (enc[0] & 0xff); int n = count * this.numRows; if ((this.numRows <= 0) || (((enc.length - 4) % n) != 0)) { throw new IllegalArgumentException( " Error: given array is not encoded matrix over GF(2^m)"); } this.numColumns = (enc.length - 4) / n; matrix = new int[this.numRows][this.numColumns]; count = 4; for (int i = 0; i < this.numRows; i++) { for (int j = 0; j < this.numColumns; j++) { for (int jj = 0; jj < d; jj += 8) { matrix[i][j] ^= (enc[count++] & 0x000000ff) << jj; } if (!this.field.isElementOfThisField(matrix[i][j])) { throw new IllegalArgumentException( " Error: given array is not encoded matrix over GF(2^m)"); } } } } /** * Copy constructor. * * @param other another {@link GF2mMatrix} */ public GF2mMatrix(GF2mMatrix other) { numRows = other.numRows; numColumns = other.numColumns; field = other.field; matrix = new int[numRows][]; for (int i = 0; i < numRows; i++) { matrix[i] = IntUtils.clone(other.matrix[i]); } } /** * Constructor. * * @param field a finite field GF(2^m) * @param matrix the matrix as int array. Only the reference is copied. */ protected GF2mMatrix(GF2mField field, int[][] matrix) { this.field = field; this.matrix = matrix; numRows = matrix.length; numColumns = matrix[0].length; } /** * @return a byte array encoding of this matrix */ public byte[] getEncoded() { int d = 8; int count = 1; while (field.getDegree() > d) { count++; d += 8; } byte[] bf = new byte[this.numRows * this.numColumns * count + 4]; bf[0] = (byte)(this.numRows & 0xff); bf[1] = (byte)((this.numRows >>> 8) & 0xff); bf[2] = (byte)((this.numRows >>> 16) & 0xff); bf[3] = (byte)((this.numRows >>> 24) & 0xff); count = 4; for (int i = 0; i < this.numRows; i++) { for (int j = 0; j < this.numColumns; j++) { for (int jj = 0; jj < d; jj += 8) { bf[count++] = (byte)(matrix[i][j] >>> jj); } } } return bf; } /** * Check if this is the zero matrix (i.e., all entries are zero). * * @return true if this is the zero matrix */ public boolean isZero() { for (int i = 0; i < numRows; i++) { for (int j = 0; j < numColumns; j++) { if (matrix[i][j] != 0) { return false; } } } return true; } /** * Compute the inverse of this matrix. * * @return the inverse of this matrix (newly created). */ public Matrix computeInverse() { if (numRows != numColumns) { throw new ArithmeticException("Matrix is not invertible."); } // clone this matrix int[][] tmpMatrix = new int[numRows][numRows]; for (int i = numRows - 1; i >= 0; i--) { tmpMatrix[i] = IntUtils.clone(matrix[i]); } // initialize inverse matrix as unit matrix int[][] invMatrix = new int[numRows][numRows]; for (int i = numRows - 1; i >= 0; i--) { invMatrix[i][i] = 1; } // simultaneously compute Gaussian reduction of tmpMatrix and unit // matrix for (int i = 0; i < numRows; i++) { // if diagonal element is zero if (tmpMatrix[i][i] == 0) { boolean foundNonZero = false; // find a non-zero element in the same column for (int j = i + 1; j < numRows; j++) { if (tmpMatrix[j][i] != 0) { // found it, swap rows ... foundNonZero = true; swapColumns(tmpMatrix, i, j); swapColumns(invMatrix, i, j); // ... and quit searching j = numRows; continue; } } // if no non-zero element was found if (!foundNonZero) { // the matrix is not invertible throw new ArithmeticException("Matrix is not invertible."); } } // normalize i-th row int coef = tmpMatrix[i][i]; int invCoef = field.inverse(coef); multRowWithElementThis(tmpMatrix[i], invCoef); multRowWithElementThis(invMatrix[i], invCoef); // normalize all other rows for (int j = 0; j < numRows; j++) { if (j != i) { coef = tmpMatrix[j][i]; if (coef != 0) { int[] tmpRow = multRowWithElement(tmpMatrix[i], coef); int[] tmpInvRow = multRowWithElement(invMatrix[i], coef); addToRow(tmpRow, tmpMatrix[j]); addToRow(tmpInvRow, invMatrix[j]); } } } } return new GF2mMatrix(field, invMatrix); } private static void swapColumns(int[][] matrix, int first, int second) { int[] tmp = matrix[first]; matrix[first] = matrix[second]; matrix[second] = tmp; } private void multRowWithElementThis(int[] row, int element) { for (int i = row.length - 1; i >= 0; i--) { row[i] = field.mult(row[i], element); } } private int[] multRowWithElement(int[] row, int element) { int[] result = new int[row.length]; for (int i = row.length - 1; i >= 0; i--) { result[i] = field.mult(row[i], element); } return result; } /** * Add one row to another. * * @param fromRow the addend * @param toRow the row to add to */ private void addToRow(int[] fromRow, int[] toRow) { for (int i = toRow.length - 1; i >= 0; i--) { toRow[i] = field.add(fromRow[i], toRow[i]); } } public Matrix rightMultiply(Matrix a) { throw new RuntimeException("Not implemented."); } public Matrix rightMultiply(Permutation perm) { throw new RuntimeException("Not implemented."); } public Vector leftMultiply(Vector vector) { throw new RuntimeException("Not implemented."); } public Vector rightMultiply(Vector vector) { throw new RuntimeException("Not implemented."); } /** * Checks if given object is equal to this matrix. The method returns false * whenever the given object is not a matrix over GF(2^m). * * @param other object * @return true or false */ public boolean equals(Object other) { if (other == null || !(other instanceof GF2mMatrix)) { return false; } GF2mMatrix otherMatrix = (GF2mMatrix)other; if ((!this.field.equals(otherMatrix.field)) || (otherMatrix.numRows != this.numColumns) || (otherMatrix.numColumns != this.numColumns)) { return false; } for (int i = 0; i < this.numRows; i++) { for (int j = 0; j < this.numColumns; j++) { if (this.matrix[i][j] != otherMatrix.matrix[i][j]) { return false; } } } return true; } public int hashCode() { int hash = (this.field.hashCode() * 31 + numRows) * 31 + numColumns; for (int i = 0; i < this.numRows; i++) { for (int j = 0; j < this.numColumns; j++) { hash = hash * 31 + matrix[i][j]; } } return hash; } public String toString() { String str = this.numRows + " x " + this.numColumns + " Matrix over " + this.field.toString() + ": \n"; for (int i = 0; i < this.numRows; i++) { for (int j = 0; j < this.numColumns; j++) { str = str + this.field.elementToStr(matrix[i][j]) + " : "; } str = str + "\n"; } return str; } } bouncycastle-1.49.orig/src/org/bouncycastle/pqc/math/ntru/0000755000175000017500000000000012152033551023203 5ustar ebourgebourgbouncycastle-1.49.orig/src/org/bouncycastle/pqc/math/ntru/util/0000755000175000017500000000000012152033551024160 5ustar ebourgebourgbouncycastle-1.49.orig/src/org/bouncycastle/pqc/math/ntru/util/ArrayEncoder.java0000644000175000017500000002355712113311460027410 0ustar ebourgebourgpackage org.bouncycastle.pqc.math.ntru.util; import java.io.IOException; import java.io.InputStream; import java.math.BigInteger; import org.bouncycastle.util.Arrays; /** * Converts a coefficient array to a compact byte array and vice versa. */ public class ArrayEncoder { /** * Bit string to coefficient conversion table from P1363.1. Also found at * {@link http://stackoverflow.com/questions/1562548/how-to-make-a-message-into-a-polynomial} *

    * Convert each three-bit quantity to two ternary coefficients as follows, and concatenate the resulting * ternary quantities to obtain [the output]. *

    * * {0, 0, 0} -> {0, 0}
    * {0, 0, 1} -> {0, 1}
    * {0, 1, 0} -> {0, -1}
    * {0, 1, 1} -> {1, 0}
    * {1, 0, 0} -> {1, 1}
    * {1, 0, 1} -> {1, -1}
    * {1, 1, 0} -> {-1, 0}
    * {1, 1, 1} -> {-1, 1}
    *
    */ private static final int[] COEFF1_TABLE = {0, 0, 0, 1, 1, 1, -1, -1}; private static final int[] COEFF2_TABLE = {0, 1, -1, 0, 1, -1, 0, 1}; /** * Coefficient to bit string conversion table from P1363.1. Also found at * {@link http://stackoverflow.com/questions/1562548/how-to-make-a-message-into-a-polynomial} *

    * Convert each set of two ternary coefficients to three bits as follows, and concatenate the resulting bit * quantities to obtain [the output]: *

    * * {-1, -1} -> set "fail" to 1 and set bit string to {1, 1, 1} * {-1, 0} -> {1, 1, 0}
    * {-1, 1} -> {1, 1, 1}
    * {0, -1} -> {0, 1, 0}
    * {0, 0} -> {0, 0, 0}
    * {0, 1} -> {0, 0, 1}
    * {1, -1} -> {1, 0, 1}
    * {1, 0} -> {0, 1, 1}
    * {1, 1} -> {1, 0, 0}
    *
    */ private static final int[] BIT1_TABLE = {1, 1, 1, 0, 0, 0, 1, 0, 1}; private static final int[] BIT2_TABLE = {1, 1, 1, 1, 0, 0, 0, 1, 0}; private static final int[] BIT3_TABLE = {1, 0, 1, 0, 0, 1, 1, 1, 0}; /** * Encodes an int array whose elements are between 0 and q, * to a byte array leaving no gaps between bits.
    * q must be a power of 2. * * @param a the input array * @param q the modulus * @return the encoded array */ public static byte[] encodeModQ(int[] a, int q) { int bitsPerCoeff = 31 - Integer.numberOfLeadingZeros(q); int numBits = a.length * bitsPerCoeff; int numBytes = (numBits + 7) / 8; byte[] data = new byte[numBytes]; int bitIndex = 0; int byteIndex = 0; for (int i = 0; i < a.length; i++) { for (int j = 0; j < bitsPerCoeff; j++) { int currentBit = (a[i] >> j) & 1; data[byteIndex] |= currentBit << bitIndex; if (bitIndex == 7) { bitIndex = 0; byteIndex++; } else { bitIndex++; } } } return data; } /** * Decodes a byte array encoded with {@link #encodeModQ(int[], int)} back to an int array.
    * N is the number of coefficients. q must be a power of 2.
    * Ignores any excess bytes. * * @param data an encoded ternary polynomial * @param N number of coefficients * @param q * @return an array containing N coefficients between 0 and q-1 */ public static int[] decodeModQ(byte[] data, int N, int q) { int[] coeffs = new int[N]; int bitsPerCoeff = 31 - Integer.numberOfLeadingZeros(q); int numBits = N * bitsPerCoeff; int coeffIndex = 0; for (int bitIndex = 0; bitIndex < numBits; bitIndex++) { if (bitIndex > 0 && bitIndex % bitsPerCoeff == 0) { coeffIndex++; } int bit = getBit(data, bitIndex); coeffs[coeffIndex] += bit << (bitIndex % bitsPerCoeff); } return coeffs; } /** * Decodes data encoded with {@link #encodeModQ(int[], int)} back to an int array.
    * N is the number of coefficients. q must be a power of 2.
    * Ignores any excess bytes. * * @param is an encoded ternary polynomial * @param N number of coefficients * @param q * @return the decoded polynomial */ public static int[] decodeModQ(InputStream is, int N, int q) throws IOException { int qBits = 31 - Integer.numberOfLeadingZeros(q); int size = (N * qBits + 7) / 8; byte[] arr = Util.readFullLength(is, size); return decodeModQ(arr, N, q); } /** * Decodes a byte array encoded with {@link #encodeMod3Sves(int[])} back to an int array * with N coefficients between -1 and 1.
    * Ignores any excess bytes.
    * See P1363.1 section 9.2.2. * * @param data an encoded ternary polynomial * @param N number of coefficients * @return the decoded coefficients */ public static int[] decodeMod3Sves(byte[] data, int N) { int[] coeffs = new int[N]; int coeffIndex = 0; for (int bitIndex = 0; bitIndex < data.length * 8; ) { int bit1 = getBit(data, bitIndex++); int bit2 = getBit(data, bitIndex++); int bit3 = getBit(data, bitIndex++); int coeffTableIndex = bit1 * 4 + bit2 * 2 + bit3; coeffs[coeffIndex++] = COEFF1_TABLE[coeffTableIndex]; coeffs[coeffIndex++] = COEFF2_TABLE[coeffTableIndex]; // ignore bytes that can't fit if (coeffIndex > N - 2) { break; } } return coeffs; } /** * Encodes an int array whose elements are between -1 and 1, to a byte array. * coeffs[2*i] and coeffs[2*i+1] must not both equal -1 for any integer i, * so this method is only safe to use with arrays produced by {@link #decodeMod3Sves(byte[], int)}.
    * See P1363.1 section 9.2.3. * * @param arr * @return the encoded array */ public static byte[] encodeMod3Sves(int[] arr) { int numBits = (arr.length * 3 + 1) / 2; int numBytes = (numBits + 7) / 8; byte[] data = new byte[numBytes]; int bitIndex = 0; int byteIndex = 0; for (int i = 0; i < arr.length / 2 * 2; ) { // if length is an odd number, throw away the highest coeff int coeff1 = arr[i++] + 1; int coeff2 = arr[i++] + 1; if (coeff1 == 0 && coeff2 == 0) { throw new IllegalStateException("Illegal encoding!"); } int bitTableIndex = coeff1 * 3 + coeff2; int[] bits = new int[]{BIT1_TABLE[bitTableIndex], BIT2_TABLE[bitTableIndex], BIT3_TABLE[bitTableIndex]}; for (int j = 0; j < 3; j++) { data[byteIndex] |= bits[j] << bitIndex; if (bitIndex == 7) { bitIndex = 0; byteIndex++; } else { bitIndex++; } } } return data; } /** * Encodes an int array whose elements are between -1 and 1, to a byte array. * * @return the encoded array */ public static byte[] encodeMod3Tight(int[] intArray) { BigInteger sum = BigInteger.ZERO; for (int i = intArray.length - 1; i >= 0; i--) { sum = sum.multiply(BigInteger.valueOf(3)); sum = sum.add(BigInteger.valueOf(intArray[i] + 1)); } int size = (BigInteger.valueOf(3).pow(intArray.length).bitLength() + 7) / 8; byte[] arr = sum.toByteArray(); if (arr.length < size) { // pad with leading zeros so arr.length==size byte[] arr2 = new byte[size]; System.arraycopy(arr, 0, arr2, size - arr.length, arr.length); return arr2; } if (arr.length > size) // drop sign bit { arr = Arrays.copyOfRange(arr, 1, arr.length); } return arr; } /** * Converts a byte array produced by {@link #encodeMod3Tight(int[])} back to an int array. * * @param b a byte array * @param N number of coefficients * @return the decoded array */ public static int[] decodeMod3Tight(byte[] b, int N) { BigInteger sum = new BigInteger(1, b); int[] coeffs = new int[N]; for (int i = 0; i < N; i++) { coeffs[i] = sum.mod(BigInteger.valueOf(3)).intValue() - 1; if (coeffs[i] > 1) { coeffs[i] -= 3; } sum = sum.divide(BigInteger.valueOf(3)); } return coeffs; } /** * Converts data produced by {@link #encodeMod3Tight(int[])} back to an int array. * * @param is an input stream containing the data to decode * @param N number of coefficients * @return the decoded array */ public static int[] decodeMod3Tight(InputStream is, int N) throws IOException { int size = (int)Math.ceil(N * Math.log(3) / Math.log(2) / 8); byte[] arr = Util.readFullLength(is, size); return decodeMod3Tight(arr, N); } private static int getBit(byte[] arr, int bitIndex) { int byteIndex = bitIndex / 8; int arrElem = arr[byteIndex] & 0xFF; return (arrElem >> (bitIndex % 8)) & 1; } }bouncycastle-1.49.orig/src/org/bouncycastle/pqc/math/ntru/util/Util.java0000644000175000017500000001051512113311460025735 0ustar ebourgebourgpackage org.bouncycastle.pqc.math.ntru.util; import java.io.IOException; import java.io.InputStream; import java.security.SecureRandom; import java.util.ArrayList; import java.util.Collections; import java.util.List; import org.bouncycastle.pqc.math.ntru.euclid.IntEuclidean; import org.bouncycastle.pqc.math.ntru.polynomial.DenseTernaryPolynomial; import org.bouncycastle.pqc.math.ntru.polynomial.SparseTernaryPolynomial; import org.bouncycastle.pqc.math.ntru.polynomial.TernaryPolynomial; import org.bouncycastle.util.Integers; public class Util { private static volatile boolean IS_64_BITNESS_KNOWN; private static volatile boolean IS_64_BIT_JVM; /** * Calculates the inverse of n mod modulus */ public static int invert(int n, int modulus) { n %= modulus; if (n < 0) { n += modulus; } return IntEuclidean.calculate(n, modulus).x; } /** * Calculates a^b mod modulus */ public static int pow(int a, int b, int modulus) { int p = 1; for (int i = 0; i < b; i++) { p = (p * a) % modulus; } return p; } /** * Calculates a^b mod modulus */ public static long pow(long a, int b, long modulus) { long p = 1; for (int i = 0; i < b; i++) { p = (p * a) % modulus; } return p; } /** * Generates a "sparse" or "dense" polynomial containing numOnes ints equal to 1, * numNegOnes int equal to -1, and the rest equal to 0. * * @param N * @param numOnes * @param numNegOnes * @param sparse whether to create a {@link SparseTernaryPolynomial} or {@link DenseTernaryPolynomial} * @return a ternary polynomial */ public static TernaryPolynomial generateRandomTernary(int N, int numOnes, int numNegOnes, boolean sparse, SecureRandom random) { if (sparse) { return SparseTernaryPolynomial.generateRandom(N, numOnes, numNegOnes, random); } else { return DenseTernaryPolynomial.generateRandom(N, numOnes, numNegOnes, random); } } /** * Generates an array containing numOnes ints equal to 1, * numNegOnes int equal to -1, and the rest equal to 0. * * @param N * @param numOnes * @param numNegOnes * @return an array of integers */ public static int[] generateRandomTernary(int N, int numOnes, int numNegOnes, SecureRandom random) { Integer one = Integers.valueOf(1); Integer minusOne = Integers.valueOf(-1); Integer zero = Integers.valueOf(0); List list = new ArrayList(); for (int i = 0; i < numOnes; i++) { list.add(one); } for (int i = 0; i < numNegOnes; i++) { list.add(minusOne); } while (list.size() < N) { list.add(zero); } Collections.shuffle(list, random); int[] arr = new int[N]; for (int i = 0; i < N; i++) { arr[i] = ((Integer)list.get(i)).intValue(); } return arr; } /** * Takes an educated guess as to whether 64 bits are supported by the JVM. * * @return true if 64-bit support detected, false otherwise */ public static boolean is64BitJVM() { if (!IS_64_BITNESS_KNOWN) { String arch = System.getProperty("os.arch"); String sunModel = System.getProperty("sun.arch.data.model"); IS_64_BIT_JVM = "amd64".equals(arch) || "x86_64".equals(arch) || "ppc64".equals(arch) || "64".equals(sunModel); IS_64_BITNESS_KNOWN = true; } return IS_64_BIT_JVM; } /** * Reads a given number of bytes from an InputStream. * If there are not enough bytes in the stream, an IOException * is thrown. * * @param is * @param length * @return an array of length length * @throws IOException */ public static byte[] readFullLength(InputStream is, int length) throws IOException { byte[] arr = new byte[length]; if (is.read(arr) != arr.length) { throw new IOException("Not enough bytes to read."); } return arr; } }bouncycastle-1.49.orig/src/org/bouncycastle/pqc/math/ntru/euclid/0000755000175000017500000000000012152033551024450 5ustar ebourgebourgbouncycastle-1.49.orig/src/org/bouncycastle/pqc/math/ntru/euclid/BigIntEuclidean.java0000644000175000017500000000300112113311460030266 0ustar ebourgebourgpackage org.bouncycastle.pqc.math.ntru.euclid; import java.math.BigInteger; /** * Extended Euclidean Algorithm in BigIntegers */ public class BigIntEuclidean { public BigInteger x, y, gcd; private BigIntEuclidean() { } /** * Runs the EEA on two BigIntegers
    * Implemented from pseudocode on Wikipedia. * * @param a * @param b * @return a BigIntEuclidean object that contains the result in the variables x, y, and gcd */ public static BigIntEuclidean calculate(BigInteger a, BigInteger b) { BigInteger x = BigInteger.ZERO; BigInteger lastx = BigInteger.ONE; BigInteger y = BigInteger.ONE; BigInteger lasty = BigInteger.ZERO; while (!b.equals(BigInteger.ZERO)) { BigInteger[] quotientAndRemainder = a.divideAndRemainder(b); BigInteger quotient = quotientAndRemainder[0]; BigInteger temp = a; a = b; b = quotientAndRemainder[1]; temp = x; x = lastx.subtract(quotient.multiply(x)); lastx = temp; temp = y; y = lasty.subtract(quotient.multiply(y)); lasty = temp; } BigIntEuclidean result = new BigIntEuclidean(); result.x = lastx; result.y = lasty; result.gcd = a; return result; } }bouncycastle-1.49.orig/src/org/bouncycastle/pqc/math/ntru/euclid/IntEuclidean.java0000644000175000017500000000226012113311460027652 0ustar ebourgebourgpackage org.bouncycastle.pqc.math.ntru.euclid; /** * Extended Euclidean Algorithm in ints */ public class IntEuclidean { public int x, y, gcd; private IntEuclidean() { } /** * Runs the EEA on two ints
    * Implemented from pseudocode on Wikipedia. * * @param a * @param b * @return a IntEuclidean object that contains the result in the variables x, y, and gcd */ public static IntEuclidean calculate(int a, int b) { int x = 0; int lastx = 1; int y = 1; int lasty = 0; while (b != 0) { int quotient = a / b; int temp = a; a = b; b = temp % b; temp = x; x = lastx - quotient * x; lastx = temp; temp = y; y = lasty - quotient * y; lasty = temp; } IntEuclidean result = new IntEuclidean(); result.x = lastx; result.y = lasty; result.gcd = a; return result; } }bouncycastle-1.49.orig/src/org/bouncycastle/pqc/math/ntru/polynomial/0000755000175000017500000000000012152033551025366 5ustar ebourgebourgbouncycastle-1.49.orig/src/org/bouncycastle/pqc/math/ntru/polynomial/LongPolynomial2.java0000644000175000017500000001730012113311460031252 0ustar ebourgebourgpackage org.bouncycastle.pqc.math.ntru.polynomial; import org.bouncycastle.util.Arrays; /** * A polynomial class that combines two coefficients into one long value for * faster multiplication in 64 bit environments.
    * Coefficients can be between 0 and 2047 and are stored in pairs in the bits 0..10 and 24..34 of a long number. */ public class LongPolynomial2 { private long[] coeffs; // each representing two coefficients in the original IntegerPolynomial private int numCoeffs; /** * Constructs a LongPolynomial2 from a IntegerPolynomial. The two polynomials are independent of each other. * * @param p the original polynomial. Coefficients must be between 0 and 2047. */ public LongPolynomial2(IntegerPolynomial p) { numCoeffs = p.coeffs.length; coeffs = new long[(numCoeffs + 1) / 2]; int idx = 0; for (int pIdx = 0; pIdx < numCoeffs; ) { int c0 = p.coeffs[pIdx++]; while (c0 < 0) { c0 += 2048; } long c1 = pIdx < numCoeffs ? p.coeffs[pIdx++] : 0; while (c1 < 0) { c1 += 2048; } coeffs[idx] = c0 + (c1 << 24); idx++; } } private LongPolynomial2(long[] coeffs) { this.coeffs = coeffs; } private LongPolynomial2(int N) { coeffs = new long[N]; } /** * Multiplies the polynomial with another, taking the indices mod N and the values mod 2048. */ public LongPolynomial2 mult(LongPolynomial2 poly2) { int N = coeffs.length; if (poly2.coeffs.length != N || numCoeffs != poly2.numCoeffs) { throw new IllegalArgumentException("Number of coefficients must be the same"); } LongPolynomial2 c = multRecursive(poly2); if (c.coeffs.length > N) { if (numCoeffs % 2 == 0) { for (int k = N; k < c.coeffs.length; k++) { c.coeffs[k - N] = (c.coeffs[k - N] + c.coeffs[k]) & 0x7FF0007FFL; } c.coeffs = Arrays.copyOf(c.coeffs, N); } else { for (int k = N; k < c.coeffs.length; k++) { c.coeffs[k - N] = c.coeffs[k - N] + (c.coeffs[k - 1] >> 24); c.coeffs[k - N] = c.coeffs[k - N] + ((c.coeffs[k] & 2047) << 24); c.coeffs[k - N] &= 0x7FF0007FFL; } c.coeffs = Arrays.copyOf(c.coeffs, N); c.coeffs[c.coeffs.length - 1] &= 2047; } } c = new LongPolynomial2(c.coeffs); c.numCoeffs = numCoeffs; return c; } public IntegerPolynomial toIntegerPolynomial() { int[] intCoeffs = new int[numCoeffs]; int uIdx = 0; for (int i = 0; i < coeffs.length; i++) { intCoeffs[uIdx++] = (int)(coeffs[i] & 2047); if (uIdx < numCoeffs) { intCoeffs[uIdx++] = (int)((coeffs[i] >> 24) & 2047); } } return new IntegerPolynomial(intCoeffs); } /** * Karazuba multiplication */ private LongPolynomial2 multRecursive(LongPolynomial2 poly2) { long[] a = coeffs; long[] b = poly2.coeffs; int n = poly2.coeffs.length; if (n <= 32) { int cn = 2 * n; LongPolynomial2 c = new LongPolynomial2(new long[cn]); for (int k = 0; k < cn; k++) { for (int i = Math.max(0, k - n + 1); i <= Math.min(k, n - 1); i++) { long c0 = a[k - i] * b[i]; long cu = c0 & 0x7FF000000L + (c0 & 2047); long co = (c0 >>> 48) & 2047; c.coeffs[k] = (c.coeffs[k] + cu) & 0x7FF0007FFL; c.coeffs[k + 1] = (c.coeffs[k + 1] + co) & 0x7FF0007FFL; } } return c; } else { int n1 = n / 2; LongPolynomial2 a1 = new LongPolynomial2(Arrays.copyOf(a, n1)); LongPolynomial2 a2 = new LongPolynomial2(Arrays.copyOfRange(a, n1, n)); LongPolynomial2 b1 = new LongPolynomial2(Arrays.copyOf(b, n1)); LongPolynomial2 b2 = new LongPolynomial2(Arrays.copyOfRange(b, n1, n)); LongPolynomial2 A = (LongPolynomial2)a1.clone(); A.add(a2); LongPolynomial2 B = (LongPolynomial2)b1.clone(); B.add(b2); LongPolynomial2 c1 = a1.multRecursive(b1); LongPolynomial2 c2 = a2.multRecursive(b2); LongPolynomial2 c3 = A.multRecursive(B); c3.sub(c1); c3.sub(c2); LongPolynomial2 c = new LongPolynomial2(2 * n); for (int i = 0; i < c1.coeffs.length; i++) { c.coeffs[i] = c1.coeffs[i] & 0x7FF0007FFL; } for (int i = 0; i < c3.coeffs.length; i++) { c.coeffs[n1 + i] = (c.coeffs[n1 + i] + c3.coeffs[i]) & 0x7FF0007FFL; } for (int i = 0; i < c2.coeffs.length; i++) { c.coeffs[2 * n1 + i] = (c.coeffs[2 * n1 + i] + c2.coeffs[i]) & 0x7FF0007FFL; } return c; } } /** * Adds another polynomial which can have a different number of coefficients. * * @param b another polynomial */ private void add(LongPolynomial2 b) { if (b.coeffs.length > coeffs.length) { coeffs = Arrays.copyOf(coeffs, b.coeffs.length); } for (int i = 0; i < b.coeffs.length; i++) { coeffs[i] = (coeffs[i] + b.coeffs[i]) & 0x7FF0007FFL; } } /** * Subtracts another polynomial which can have a different number of coefficients. * * @param b another polynomial */ private void sub(LongPolynomial2 b) { if (b.coeffs.length > coeffs.length) { coeffs = Arrays.copyOf(coeffs, b.coeffs.length); } for (int i = 0; i < b.coeffs.length; i++) { coeffs[i] = (0x0800000800000L + coeffs[i] - b.coeffs[i]) & 0x7FF0007FFL; } } /** * Subtracts another polynomial which must have the same number of coefficients, * and applies an AND mask to the upper and lower halves of each coefficients. * * @param b another polynomial * @param mask a bit mask less than 2048 to apply to each 11-bit coefficient */ public void subAnd(LongPolynomial2 b, int mask) { long longMask = (((long)mask) << 24) + mask; for (int i = 0; i < b.coeffs.length; i++) { coeffs[i] = (0x0800000800000L + coeffs[i] - b.coeffs[i]) & longMask; } } /** * Multiplies this polynomial by 2 and applies an AND mask to the upper and * lower halves of each coefficients. * * @param mask a bit mask less than 2048 to apply to each 11-bit coefficient */ public void mult2And(int mask) { long longMask = (((long)mask) << 24) + mask; for (int i = 0; i < coeffs.length; i++) { coeffs[i] = (coeffs[i] << 1) & longMask; } } public Object clone() { LongPolynomial2 p = new LongPolynomial2(coeffs.clone()); p.numCoeffs = numCoeffs; return p; } public boolean equals(Object obj) { if (obj instanceof LongPolynomial2) { return Arrays.areEqual(coeffs, ((LongPolynomial2)obj).coeffs); } else { return false; } } } bouncycastle-1.49.orig/src/org/bouncycastle/pqc/math/ntru/polynomial/LongPolynomial5.java0000644000175000017500000001153712113311460031263 0ustar ebourgebourgpackage org.bouncycastle.pqc.math.ntru.polynomial; import org.bouncycastle.util.Arrays; /** * A polynomial class that combines five coefficients into one long value for * faster multiplication by a ternary polynomial.
    * Coefficients can be between 0 and 2047 and are stored in bits 0..11, 12..23, ..., 48..59 of a long number. */ public class LongPolynomial5 { private long[] coeffs; // groups of 5 coefficients private int numCoeffs; /** * Constructs a LongPolynomial5 from a IntegerPolynomial. The two polynomials are independent of each other. * * @param p the original polynomial. Coefficients must be between 0 and 2047. */ public LongPolynomial5(IntegerPolynomial p) { numCoeffs = p.coeffs.length; coeffs = new long[(numCoeffs + 4) / 5]; int cIdx = 0; int shift = 0; for (int i = 0; i < numCoeffs; i++) { coeffs[cIdx] |= ((long)p.coeffs[i]) << shift; shift += 12; if (shift >= 60) { shift = 0; cIdx++; } } } private LongPolynomial5(long[] coeffs, int numCoeffs) { this.coeffs = coeffs; this.numCoeffs = numCoeffs; } /** * Multiplies the polynomial with a TernaryPolynomial, taking the indices mod N and the values mod 2048. */ public LongPolynomial5 mult(TernaryPolynomial poly2) { long[][] prod = new long[5][coeffs.length + (poly2.size() + 4) / 5 - 1]; // intermediate results, the subarrays are shifted by 0,...,4 coefficients // multiply ones int[] ones = poly2.getOnes(); for (int idx = 0; idx != ones.length; idx++) { int pIdx = ones[idx]; int cIdx = pIdx / 5; int m = pIdx - cIdx * 5; // m = pIdx % 5 for (int i = 0; i < coeffs.length; i++) { prod[m][cIdx] = (prod[m][cIdx] + coeffs[i]) & 0x7FF7FF7FF7FF7FFL; cIdx++; } } // multiply negative ones int[] negOnes = poly2.getNegOnes(); for (int idx = 0; idx != negOnes.length; idx++) { int pIdx = negOnes[idx]; int cIdx = pIdx / 5; int m = pIdx - cIdx * 5; // m = pIdx % 5 for (int i = 0; i < coeffs.length; i++) { prod[m][cIdx] = (0x800800800800800L + prod[m][cIdx] - coeffs[i]) & 0x7FF7FF7FF7FF7FFL; cIdx++; } } // combine shifted coefficients (5 arrays) into a single array of length prod[*].length+1 long[] cCoeffs = Arrays.copyOf(prod[0], prod[0].length + 1); for (int m = 1; m <= 4; m++) { int shift = m * 12; int shift60 = 60 - shift; long mask = (1L << shift60) - 1; int pLen = prod[m].length; for (int i = 0; i < pLen; i++) { long upper, lower; upper = prod[m][i] >> shift60; lower = prod[m][i] & mask; cCoeffs[i] = (cCoeffs[i] + (lower << shift)) & 0x7FF7FF7FF7FF7FFL; int nextIdx = i + 1; cCoeffs[nextIdx] = (cCoeffs[nextIdx] + upper) & 0x7FF7FF7FF7FF7FFL; } } // reduce indices of cCoeffs modulo numCoeffs int shift = 12 * (numCoeffs % 5); for (int cIdx = coeffs.length - 1; cIdx < cCoeffs.length; cIdx++) { long iCoeff; // coefficient to shift into the [0..numCoeffs-1] range int newIdx; if (cIdx == coeffs.length - 1) { iCoeff = numCoeffs == 5 ? 0 : cCoeffs[cIdx] >> shift; newIdx = 0; } else { iCoeff = cCoeffs[cIdx]; newIdx = cIdx * 5 - numCoeffs; } int base = newIdx / 5; int m = newIdx - base * 5; // m = newIdx % 5 long lower = iCoeff << (12 * m); long upper = iCoeff >> (12 * (5 - m)); cCoeffs[base] = (cCoeffs[base] + lower) & 0x7FF7FF7FF7FF7FFL; int base1 = base + 1; if (base1 < coeffs.length) { cCoeffs[base1] = (cCoeffs[base1] + upper) & 0x7FF7FF7FF7FF7FFL; } } return new LongPolynomial5(cCoeffs, numCoeffs); } public IntegerPolynomial toIntegerPolynomial() { int[] intCoeffs = new int[numCoeffs]; int cIdx = 0; int shift = 0; for (int i = 0; i < numCoeffs; i++) { intCoeffs[i] = (int)((coeffs[cIdx] >> shift) & 2047); shift += 12; if (shift >= 60) { shift = 0; cIdx++; } } return new IntegerPolynomial(intCoeffs); } } bouncycastle-1.49.orig/src/org/bouncycastle/pqc/math/ntru/polynomial/BigIntPolynomial.java0000644000175000017500000002610612113311460031451 0ustar ebourgebourgpackage org.bouncycastle.pqc.math.ntru.polynomial; import java.math.BigDecimal; import java.math.BigInteger; import java.security.SecureRandom; import java.util.ArrayList; import java.util.Collections; import java.util.List; import org.bouncycastle.util.Arrays; /** * A polynomial with {@link BigInteger} coefficients.
    * Some methods (like add) change the polynomial, others (like mult) do * not but return the result as a new polynomial. */ public class BigIntPolynomial { private final static double LOG_10_2 = Math.log10(2); BigInteger[] coeffs; /** * Constructs a new polynomial with N coefficients initialized to 0. * * @param N the number of coefficients */ BigIntPolynomial(int N) { coeffs = new BigInteger[N]; for (int i = 0; i < N; i++) { coeffs[i] = Constants.BIGINT_ZERO; } } /** * Constructs a new polynomial with a given set of coefficients. * * @param coeffs the coefficients */ BigIntPolynomial(BigInteger[] coeffs) { this.coeffs = coeffs; } /** * Constructs a BigIntPolynomial from a IntegerPolynomial. The two polynomials are * independent of each other. * * @param p the original polynomial */ public BigIntPolynomial(IntegerPolynomial p) { coeffs = new BigInteger[p.coeffs.length]; for (int i = 0; i < coeffs.length; i++) { coeffs[i] = BigInteger.valueOf(p.coeffs[i]); } } /** * Generates a random polynomial with numOnes coefficients equal to 1, * numNegOnes coefficients equal to -1, and the rest equal to 0. * * @param N number of coefficients * @param numOnes number of 1's * @param numNegOnes number of -1's * @return */ static BigIntPolynomial generateRandomSmall(int N, int numOnes, int numNegOnes) { List coeffs = new ArrayList(); for (int i = 0; i < numOnes; i++) { coeffs.add(Constants.BIGINT_ONE); } for (int i = 0; i < numNegOnes; i++) { coeffs.add(BigInteger.valueOf(-1)); } while (coeffs.size() < N) { coeffs.add(Constants.BIGINT_ZERO); } Collections.shuffle(coeffs, new SecureRandom()); BigIntPolynomial poly = new BigIntPolynomial(N); for (int i = 0; i < coeffs.size(); i++) { poly.coeffs[i] = (BigInteger)coeffs.get(i); } return poly; } /** * Multiplies the polynomial by another, taking the indices mod N. Does not * change this polynomial but returns the result as a new polynomial.
    * Both polynomials must have the same number of coefficients. * * @param poly2 the polynomial to multiply by * @return a new polynomial */ public BigIntPolynomial mult(BigIntPolynomial poly2) { int N = coeffs.length; if (poly2.coeffs.length != N) { throw new IllegalArgumentException("Number of coefficients must be the same"); } BigIntPolynomial c = multRecursive(poly2); if (c.coeffs.length > N) { for (int k = N; k < c.coeffs.length; k++) { c.coeffs[k - N] = c.coeffs[k - N].add(c.coeffs[k]); } c.coeffs = Arrays.copyOf(c.coeffs, N); } return c; } /** * Karazuba multiplication */ private BigIntPolynomial multRecursive(BigIntPolynomial poly2) { BigInteger[] a = coeffs; BigInteger[] b = poly2.coeffs; int n = poly2.coeffs.length; if (n <= 1) { BigInteger[] c = Arrays.clone(coeffs); for (int i = 0; i < coeffs.length; i++) { c[i] = c[i].multiply(poly2.coeffs[0]); } return new BigIntPolynomial(c); } else { int n1 = n / 2; BigIntPolynomial a1 = new BigIntPolynomial(Arrays.copyOf(a, n1)); BigIntPolynomial a2 = new BigIntPolynomial(Arrays.copyOfRange(a, n1, n)); BigIntPolynomial b1 = new BigIntPolynomial(Arrays.copyOf(b, n1)); BigIntPolynomial b2 = new BigIntPolynomial(Arrays.copyOfRange(b, n1, n)); BigIntPolynomial A = (BigIntPolynomial)a1.clone(); A.add(a2); BigIntPolynomial B = (BigIntPolynomial)b1.clone(); B.add(b2); BigIntPolynomial c1 = a1.multRecursive(b1); BigIntPolynomial c2 = a2.multRecursive(b2); BigIntPolynomial c3 = A.multRecursive(B); c3.sub(c1); c3.sub(c2); BigIntPolynomial c = new BigIntPolynomial(2 * n - 1); for (int i = 0; i < c1.coeffs.length; i++) { c.coeffs[i] = c1.coeffs[i]; } for (int i = 0; i < c3.coeffs.length; i++) { c.coeffs[n1 + i] = c.coeffs[n1 + i].add(c3.coeffs[i]); } for (int i = 0; i < c2.coeffs.length; i++) { c.coeffs[2 * n1 + i] = c.coeffs[2 * n1 + i].add(c2.coeffs[i]); } return c; } } /** * Adds another polynomial which can have a different number of coefficients, * and takes the coefficient values mod modulus. * * @param b another polynomial */ void add(BigIntPolynomial b, BigInteger modulus) { add(b); mod(modulus); } /** * Adds another polynomial which can have a different number of coefficients. * * @param b another polynomial */ public void add(BigIntPolynomial b) { if (b.coeffs.length > coeffs.length) { int N = coeffs.length; coeffs = Arrays.copyOf(coeffs, b.coeffs.length); for (int i = N; i < coeffs.length; i++) { coeffs[i] = Constants.BIGINT_ZERO; } } for (int i = 0; i < b.coeffs.length; i++) { coeffs[i] = coeffs[i].add(b.coeffs[i]); } } /** * Subtracts another polynomial which can have a different number of coefficients. * * @param b another polynomial */ public void sub(BigIntPolynomial b) { if (b.coeffs.length > coeffs.length) { int N = coeffs.length; coeffs = Arrays.copyOf(coeffs, b.coeffs.length); for (int i = N; i < coeffs.length; i++) { coeffs[i] = Constants.BIGINT_ZERO; } } for (int i = 0; i < b.coeffs.length; i++) { coeffs[i] = coeffs[i].subtract(b.coeffs[i]); } } /** * Multiplies each coefficient by a BigInteger. Does not return a new polynomial but modifies this polynomial. * * @param factor */ public void mult(BigInteger factor) { for (int i = 0; i < coeffs.length; i++) { coeffs[i] = coeffs[i].multiply(factor); } } /** * Multiplies each coefficient by a int. Does not return a new polynomial but modifies this polynomial. * * @param factor */ void mult(int factor) { mult(BigInteger.valueOf(factor)); } /** * Divides each coefficient by a BigInteger and rounds the result to the nearest whole number.
    * Does not return a new polynomial but modifies this polynomial. * * @param divisor the number to divide by */ public void div(BigInteger divisor) { BigInteger d = divisor.add(Constants.BIGINT_ONE).divide(BigInteger.valueOf(2)); for (int i = 0; i < coeffs.length; i++) { coeffs[i] = coeffs[i].compareTo(Constants.BIGINT_ZERO) > 0 ? coeffs[i].add(d) : coeffs[i].add(d.negate()); coeffs[i] = coeffs[i].divide(divisor); } } /** * Divides each coefficient by a BigDecimal and rounds the result to decimalPlaces places. * * @param divisor the number to divide by * @param decimalPlaces the number of fractional digits to round the result to * @return a new BigDecimalPolynomial */ public BigDecimalPolynomial div(BigDecimal divisor, int decimalPlaces) { BigInteger max = maxCoeffAbs(); int coeffLength = (int)(max.bitLength() * LOG_10_2) + 1; // factor = 1/divisor BigDecimal factor = Constants.BIGDEC_ONE.divide(divisor, coeffLength + decimalPlaces + 1, BigDecimal.ROUND_HALF_EVEN); // multiply each coefficient by factor BigDecimalPolynomial p = new BigDecimalPolynomial(coeffs.length); for (int i = 0; i < coeffs.length; i++) // multiply, then truncate after decimalPlaces so subsequent operations aren't slowed down { p.coeffs[i] = new BigDecimal(coeffs[i]).multiply(factor).setScale(decimalPlaces, BigDecimal.ROUND_HALF_EVEN); } return p; } /** * Returns the base10 length of the largest coefficient. * * @return length of the longest coefficient */ public int getMaxCoeffLength() { return (int)(maxCoeffAbs().bitLength() * LOG_10_2) + 1; } private BigInteger maxCoeffAbs() { BigInteger max = coeffs[0].abs(); for (int i = 1; i < coeffs.length; i++) { BigInteger coeff = coeffs[i].abs(); if (coeff.compareTo(max) > 0) { max = coeff; } } return max; } /** * Takes each coefficient modulo a number. * * @param modulus */ public void mod(BigInteger modulus) { for (int i = 0; i < coeffs.length; i++) { coeffs[i] = coeffs[i].mod(modulus); } } /** * Returns the sum of all coefficients, i.e. evaluates the polynomial at 0. * * @return the sum of all coefficients */ BigInteger sumCoeffs() { BigInteger sum = Constants.BIGINT_ZERO; for (int i = 0; i < coeffs.length; i++) { sum = sum.add(coeffs[i]); } return sum; } /** * Makes a copy of the polynomial that is independent of the original. */ public Object clone() { return new BigIntPolynomial(coeffs.clone()); } public int hashCode() { final int prime = 31; int result = 1; result = prime * result + Arrays.hashCode(coeffs); return result; } public boolean equals(Object obj) { if (this == obj) { return true; } if (obj == null) { return false; } if (getClass() != obj.getClass()) { return false; } BigIntPolynomial other = (BigIntPolynomial)obj; if (!Arrays.areEqual(coeffs, other.coeffs)) { return false; } return true; } public BigInteger[] getCoeffs() { return Arrays.clone(coeffs); } } bouncycastle-1.49.orig/src/org/bouncycastle/pqc/math/ntru/polynomial/Polynomial.java0000644000175000017500000000275412113311460030357 0ustar ebourgebourgpackage org.bouncycastle.pqc.math.ntru.polynomial; public interface Polynomial { /** * Multiplies the polynomial by an IntegerPolynomial, * taking the indices mod N. * * @param poly2 a polynomial * @return the product of the two polynomials */ IntegerPolynomial mult(IntegerPolynomial poly2); /** * Multiplies the polynomial by an IntegerPolynomial, * taking the coefficient values mod modulus and the indices mod N. * * @param poly2 a polynomial * @param modulus a modulus to apply * @return the product of the two polynomials */ IntegerPolynomial mult(IntegerPolynomial poly2, int modulus); /** * Returns a polynomial that is equal to this polynomial (in the sense that {@link #mult(IntegerPolynomial, int)} * returns equal IntegerPolynomials). The new polynomial is guaranteed to be independent of the original. * * @return a new IntegerPolynomial. */ IntegerPolynomial toIntegerPolynomial(); /** * Multiplies the polynomial by a BigIntPolynomial, taking the indices mod N. Does not * change this polynomial but returns the result as a new polynomial.
    * Both polynomials must have the same number of coefficients. * * @param poly2 the polynomial to multiply by * @return a new polynomial */ BigIntPolynomial mult(BigIntPolynomial poly2); } bouncycastle-1.49.orig/src/org/bouncycastle/pqc/math/ntru/polynomial/SparseTernaryPolynomial.java0000644000175000017500000002101012113311460033064 0ustar ebourgebourgpackage org.bouncycastle.pqc.math.ntru.polynomial; import java.io.IOException; import java.io.InputStream; import java.math.BigInteger; import java.security.SecureRandom; import org.bouncycastle.pqc.math.ntru.util.ArrayEncoder; import org.bouncycastle.pqc.math.ntru.util.Util; import org.bouncycastle.util.Arrays; /** * A TernaryPolynomial with a "low" number of nonzero coefficients. */ public class SparseTernaryPolynomial implements TernaryPolynomial { /** * Number of bits to use for each coefficient. Determines the upper bound for N. */ private static final int BITS_PER_INDEX = 11; private int N; private int[] ones; private int[] negOnes; /** * Constructs a new polynomial. * * @param N total number of coefficients including zeros * @param ones indices of coefficients equal to 1 * @param negOnes indices of coefficients equal to -1 */ SparseTernaryPolynomial(int N, int[] ones, int[] negOnes) { this.N = N; this.ones = ones; this.negOnes = negOnes; } /** * Constructs a DenseTernaryPolynomial from a IntegerPolynomial. The two polynomials are * independent of each other. * * @param intPoly the original polynomial */ public SparseTernaryPolynomial(IntegerPolynomial intPoly) { this(intPoly.coeffs); } /** * Constructs a new SparseTernaryPolynomial with a given set of coefficients. * * @param coeffs the coefficients */ public SparseTernaryPolynomial(int[] coeffs) { N = coeffs.length; ones = new int[N]; negOnes = new int[N]; int onesIdx = 0; int negOnesIdx = 0; for (int i = 0; i < N; i++) { int c = coeffs[i]; switch (c) { case 1: ones[onesIdx++] = i; break; case -1: negOnes[negOnesIdx++] = i; break; case 0: break; default: throw new IllegalArgumentException("Illegal value: " + c + ", must be one of {-1, 0, 1}"); } } ones = Arrays.copyOf(ones, onesIdx); negOnes = Arrays.copyOf(negOnes, negOnesIdx); } /** * Decodes a byte array encoded with {@link #toBinary()} to a ploynomial. * * @param is an input stream containing an encoded polynomial * @param N number of coefficients including zeros * @param numOnes number of coefficients equal to 1 * @param numNegOnes number of coefficients equal to -1 * @return the decoded polynomial * @throws IOException */ public static SparseTernaryPolynomial fromBinary(InputStream is, int N, int numOnes, int numNegOnes) throws IOException { int maxIndex = 1 << BITS_PER_INDEX; int bitsPerIndex = 32 - Integer.numberOfLeadingZeros(maxIndex - 1); int data1Len = (numOnes * bitsPerIndex + 7) / 8; byte[] data1 = Util.readFullLength(is, data1Len); int[] ones = ArrayEncoder.decodeModQ(data1, numOnes, maxIndex); int data2Len = (numNegOnes * bitsPerIndex + 7) / 8; byte[] data2 = Util.readFullLength(is, data2Len); int[] negOnes = ArrayEncoder.decodeModQ(data2, numNegOnes, maxIndex); return new SparseTernaryPolynomial(N, ones, negOnes); } /** * Generates a random polynomial with numOnes coefficients equal to 1, * numNegOnes coefficients equal to -1, and the rest equal to 0. * * @param N number of coefficients * @param numOnes number of 1's * @param numNegOnes number of -1's */ public static SparseTernaryPolynomial generateRandom(int N, int numOnes, int numNegOnes, SecureRandom random) { int[] coeffs = Util.generateRandomTernary(N, numOnes, numNegOnes, random); return new SparseTernaryPolynomial(coeffs); } public IntegerPolynomial mult(IntegerPolynomial poly2) { int[] b = poly2.coeffs; if (b.length != N) { throw new IllegalArgumentException("Number of coefficients must be the same"); } int[] c = new int[N]; for (int idx = 0; idx != ones.length; idx++) { int i = ones[idx]; int j = N - 1 - i; for (int k = N - 1; k >= 0; k--) { c[k] += b[j]; j--; if (j < 0) { j = N - 1; } } } for (int idx = 0; idx != negOnes.length; idx++) { int i = negOnes[idx]; int j = N - 1 - i; for (int k = N - 1; k >= 0; k--) { c[k] -= b[j]; j--; if (j < 0) { j = N - 1; } } } return new IntegerPolynomial(c); } public IntegerPolynomial mult(IntegerPolynomial poly2, int modulus) { IntegerPolynomial c = mult(poly2); c.mod(modulus); return c; } public BigIntPolynomial mult(BigIntPolynomial poly2) { BigInteger[] b = poly2.coeffs; if (b.length != N) { throw new IllegalArgumentException("Number of coefficients must be the same"); } BigInteger[] c = new BigInteger[N]; for (int i = 0; i < N; i++) { c[i] = BigInteger.ZERO; } for (int idx = 0; idx != ones.length; idx++) { int i = ones[idx]; int j = N - 1 - i; for (int k = N - 1; k >= 0; k--) { c[k] = c[k].add(b[j]); j--; if (j < 0) { j = N - 1; } } } for (int idx = 0; idx != negOnes.length; idx++) { int i = negOnes[idx]; int j = N - 1 - i; for (int k = N - 1; k >= 0; k--) { c[k] = c[k].subtract(b[j]); j--; if (j < 0) { j = N - 1; } } } return new BigIntPolynomial(c); } public int[] getOnes() { return ones; } public int[] getNegOnes() { return negOnes; } /** * Encodes the polynomial to a byte array writing BITS_PER_INDEX bits for each coefficient. * * @return the encoded polynomial */ public byte[] toBinary() { int maxIndex = 1 << BITS_PER_INDEX; byte[] bin1 = ArrayEncoder.encodeModQ(ones, maxIndex); byte[] bin2 = ArrayEncoder.encodeModQ(negOnes, maxIndex); byte[] bin = Arrays.copyOf(bin1, bin1.length + bin2.length); System.arraycopy(bin2, 0, bin, bin1.length, bin2.length); return bin; } public IntegerPolynomial toIntegerPolynomial() { int[] coeffs = new int[N]; for (int idx = 0; idx != ones.length; idx++) { int i = ones[idx]; coeffs[i] = 1; } for (int idx = 0; idx != negOnes.length; idx++) { int i = negOnes[idx]; coeffs[i] = -1; } return new IntegerPolynomial(coeffs); } public int size() { return N; } public void clear() { for (int i = 0; i < ones.length; i++) { ones[i] = 0; } for (int i = 0; i < negOnes.length; i++) { negOnes[i] = 0; } } public int hashCode() { final int prime = 31; int result = 1; result = prime * result + N; result = prime * result + Arrays.hashCode(negOnes); result = prime * result + Arrays.hashCode(ones); return result; } public boolean equals(Object obj) { if (this == obj) { return true; } if (obj == null) { return false; } if (getClass() != obj.getClass()) { return false; } SparseTernaryPolynomial other = (SparseTernaryPolynomial)obj; if (N != other.N) { return false; } if (!Arrays.areEqual(negOnes, other.negOnes)) { return false; } if (!Arrays.areEqual(ones, other.ones)) { return false; } return true; } } bouncycastle-1.49.orig/src/org/bouncycastle/pqc/math/ntru/polynomial/BigDecimalPolynomial.java0000644000175000017500000001615312113311460032256 0ustar ebourgebourgpackage org.bouncycastle.pqc.math.ntru.polynomial; import java.math.BigDecimal; /** * A polynomial with {@link BigDecimal} coefficients. * Some methods (like add) change the polynomial, others (like mult) do * not but return the result as a new polynomial. */ public class BigDecimalPolynomial { private static final BigDecimal ZERO = new BigDecimal("0"); private static final BigDecimal ONE_HALF = new BigDecimal("0.5"); BigDecimal[] coeffs; /** * Constructs a new polynomial with N coefficients initialized to 0. * * @param N the number of coefficients */ BigDecimalPolynomial(int N) { coeffs = new BigDecimal[N]; for (int i = 0; i < N; i++) { coeffs[i] = ZERO; } } /** * Constructs a new polynomial with a given set of coefficients. * * @param coeffs the coefficients */ BigDecimalPolynomial(BigDecimal[] coeffs) { this.coeffs = coeffs; } /** * Constructs a BigDecimalPolynomial from a BigIntPolynomial. The two polynomials are independent of each other. * * @param p the original polynomial */ public BigDecimalPolynomial(BigIntPolynomial p) { int N = p.coeffs.length; coeffs = new BigDecimal[N]; for (int i = 0; i < N; i++) { coeffs[i] = new BigDecimal(p.coeffs[i]); } } /** * Divides all coefficients by 2. */ public void halve() { for (int i = 0; i < coeffs.length; i++) { coeffs[i] = coeffs[i].multiply(ONE_HALF); } } /** * Multiplies the polynomial by another. Does not change this polynomial * but returns the result as a new polynomial. * * @param poly2 the polynomial to multiply by * @return a new polynomial */ public BigDecimalPolynomial mult(BigIntPolynomial poly2) { return mult(new BigDecimalPolynomial(poly2)); } /** * Multiplies the polynomial by another, taking the indices mod N. Does not * change this polynomial but returns the result as a new polynomial. * * @param poly2 the polynomial to multiply by * @return a new polynomial */ public BigDecimalPolynomial mult(BigDecimalPolynomial poly2) { int N = coeffs.length; if (poly2.coeffs.length != N) { throw new IllegalArgumentException("Number of coefficients must be the same"); } BigDecimalPolynomial c = multRecursive(poly2); if (c.coeffs.length > N) { for (int k = N; k < c.coeffs.length; k++) { c.coeffs[k - N] = c.coeffs[k - N].add(c.coeffs[k]); } c.coeffs = copyOf(c.coeffs, N); } return c; } /** * Karazuba multiplication */ private BigDecimalPolynomial multRecursive(BigDecimalPolynomial poly2) { BigDecimal[] a = coeffs; BigDecimal[] b = poly2.coeffs; int n = poly2.coeffs.length; if (n <= 1) { BigDecimal[] c = coeffs.clone(); for (int i = 0; i < coeffs.length; i++) { c[i] = c[i].multiply(poly2.coeffs[0]); } return new BigDecimalPolynomial(c); } else { int n1 = n / 2; BigDecimalPolynomial a1 = new BigDecimalPolynomial(copyOf(a, n1)); BigDecimalPolynomial a2 = new BigDecimalPolynomial(copyOfRange(a, n1, n)); BigDecimalPolynomial b1 = new BigDecimalPolynomial(copyOf(b, n1)); BigDecimalPolynomial b2 = new BigDecimalPolynomial(copyOfRange(b, n1, n)); BigDecimalPolynomial A = (BigDecimalPolynomial)a1.clone(); A.add(a2); BigDecimalPolynomial B = (BigDecimalPolynomial)b1.clone(); B.add(b2); BigDecimalPolynomial c1 = a1.multRecursive(b1); BigDecimalPolynomial c2 = a2.multRecursive(b2); BigDecimalPolynomial c3 = A.multRecursive(B); c3.sub(c1); c3.sub(c2); BigDecimalPolynomial c = new BigDecimalPolynomial(2 * n - 1); for (int i = 0; i < c1.coeffs.length; i++) { c.coeffs[i] = c1.coeffs[i]; } for (int i = 0; i < c3.coeffs.length; i++) { c.coeffs[n1 + i] = c.coeffs[n1 + i].add(c3.coeffs[i]); } for (int i = 0; i < c2.coeffs.length; i++) { c.coeffs[2 * n1 + i] = c.coeffs[2 * n1 + i].add(c2.coeffs[i]); } return c; } } /** * Adds another polynomial which can have a different number of coefficients. * * @param b another polynomial */ public void add(BigDecimalPolynomial b) { if (b.coeffs.length > coeffs.length) { int N = coeffs.length; coeffs = copyOf(coeffs, b.coeffs.length); for (int i = N; i < coeffs.length; i++) { coeffs[i] = ZERO; } } for (int i = 0; i < b.coeffs.length; i++) { coeffs[i] = coeffs[i].add(b.coeffs[i]); } } /** * Subtracts another polynomial which can have a different number of coefficients. * * @param b */ void sub(BigDecimalPolynomial b) { if (b.coeffs.length > coeffs.length) { int N = coeffs.length; coeffs = copyOf(coeffs, b.coeffs.length); for (int i = N; i < coeffs.length; i++) { coeffs[i] = ZERO; } } for (int i = 0; i < b.coeffs.length; i++) { coeffs[i] = coeffs[i].subtract(b.coeffs[i]); } } /** * Rounds all coefficients to the nearest integer. * * @return a new polynomial with BigInteger coefficients */ public BigIntPolynomial round() { int N = coeffs.length; BigIntPolynomial p = new BigIntPolynomial(N); for (int i = 0; i < N; i++) { p.coeffs[i] = coeffs[i].setScale(0, BigDecimal.ROUND_HALF_EVEN).toBigInteger(); } return p; } /** * Makes a copy of the polynomial that is independent of the original. */ public Object clone() { return new BigDecimalPolynomial(coeffs.clone()); } private BigDecimal[] copyOf(BigDecimal[] a, int length) { BigDecimal[] tmp = new BigDecimal[length]; System.arraycopy(a, 0, tmp, 0, a.length < length ? a.length : length); return tmp; } private BigDecimal[] copyOfRange(BigDecimal[] a, int from, int to) { int newLength = to - from; BigDecimal[] tmp = new BigDecimal[to - from]; System.arraycopy(a, from, tmp, 0, (a.length - from) < newLength ? (a.length - from) : newLength); return tmp; } public BigDecimal[] getCoeffs() { BigDecimal[] tmp = new BigDecimal[coeffs.length]; System.arraycopy(coeffs, 0, tmp, 0, coeffs.length); return tmp; } } bouncycastle-1.49.orig/src/org/bouncycastle/pqc/math/ntru/polynomial/ModularResultant.java0000644000175000017500000000271212113311460031533 0ustar ebourgebourgpackage org.bouncycastle.pqc.math.ntru.polynomial; import java.math.BigInteger; import org.bouncycastle.pqc.math.ntru.euclid.BigIntEuclidean; /** * A resultant modulo a BigInteger */ public class ModularResultant extends Resultant { BigInteger modulus; ModularResultant(BigIntPolynomial rho, BigInteger res, BigInteger modulus) { super(rho, res); this.modulus = modulus; } /** * Calculates a rho modulo m1*m2 from * two resultants whose rhos are modulo m1 and m2.
    *
    res is set to null. * * @param modRes1 * @param modRes2 * @return rho modulo modRes1.modulus * modRes2.modulus, and null for res. */ static ModularResultant combineRho(ModularResultant modRes1, ModularResultant modRes2) { BigInteger mod1 = modRes1.modulus; BigInteger mod2 = modRes2.modulus; BigInteger prod = mod1.multiply(mod2); BigIntEuclidean er = BigIntEuclidean.calculate(mod2, mod1); BigIntPolynomial rho1 = (BigIntPolynomial)modRes1.rho.clone(); rho1.mult(er.x.multiply(mod2)); BigIntPolynomial rho2 = (BigIntPolynomial)modRes2.rho.clone(); rho2.mult(er.y.multiply(mod1)); rho1.add(rho2); rho1.mod(prod); return new ModularResultant(rho1, null, prod); } } bouncycastle-1.49.orig/src/org/bouncycastle/pqc/math/ntru/polynomial/IntegerPolynomial.java0000644000175000017500000012053012132450306031672 0ustar ebourgebourgpackage org.bouncycastle.pqc.math.ntru.polynomial; import java.io.IOException; import java.io.InputStream; import java.math.BigInteger; import java.util.ArrayList; import java.util.Iterator; import java.util.LinkedList; import java.util.List; import java.util.concurrent.Callable; import java.util.concurrent.ExecutorService; import java.util.concurrent.Executors; import java.util.concurrent.Future; import java.util.concurrent.LinkedBlockingQueue; import org.bouncycastle.pqc.math.ntru.euclid.BigIntEuclidean; import org.bouncycastle.pqc.math.ntru.util.ArrayEncoder; import org.bouncycastle.pqc.math.ntru.util.Util; import org.bouncycastle.util.Arrays; /** * A polynomial with int coefficients.
    * Some methods (like add) change the polynomial, others (like mult) do * not but return the result as a new polynomial. */ public class IntegerPolynomial implements Polynomial { private static final int NUM_EQUAL_RESULTANTS = 3; /** * Prime numbers > 4500 for resultant computation. Starting them below ~4400 causes incorrect results occasionally. * Fortunately, 4500 is about the optimum number for performance.
    * This array contains enough prime numbers so primes never have to be computed on-line for any standard {@link org.bouncycastle.pqc.crypto.ntru.NTRUSigningParameters}. */ private static final int[] PRIMES = new int[]{ 4507, 4513, 4517, 4519, 4523, 4547, 4549, 4561, 4567, 4583, 4591, 4597, 4603, 4621, 4637, 4639, 4643, 4649, 4651, 4657, 4663, 4673, 4679, 4691, 4703, 4721, 4723, 4729, 4733, 4751, 4759, 4783, 4787, 4789, 4793, 4799, 4801, 4813, 4817, 4831, 4861, 4871, 4877, 4889, 4903, 4909, 4919, 4931, 4933, 4937, 4943, 4951, 4957, 4967, 4969, 4973, 4987, 4993, 4999, 5003, 5009, 5011, 5021, 5023, 5039, 5051, 5059, 5077, 5081, 5087, 5099, 5101, 5107, 5113, 5119, 5147, 5153, 5167, 5171, 5179, 5189, 5197, 5209, 5227, 5231, 5233, 5237, 5261, 5273, 5279, 5281, 5297, 5303, 5309, 5323, 5333, 5347, 5351, 5381, 5387, 5393, 5399, 5407, 5413, 5417, 5419, 5431, 5437, 5441, 5443, 5449, 5471, 5477, 5479, 5483, 5501, 5503, 5507, 5519, 5521, 5527, 5531, 5557, 5563, 5569, 5573, 5581, 5591, 5623, 5639, 5641, 5647, 5651, 5653, 5657, 5659, 5669, 5683, 5689, 5693, 5701, 5711, 5717, 5737, 5741, 5743, 5749, 5779, 5783, 5791, 5801, 5807, 5813, 5821, 5827, 5839, 5843, 5849, 5851, 5857, 5861, 5867, 5869, 5879, 5881, 5897, 5903, 5923, 5927, 5939, 5953, 5981, 5987, 6007, 6011, 6029, 6037, 6043, 6047, 6053, 6067, 6073, 6079, 6089, 6091, 6101, 6113, 6121, 6131, 6133, 6143, 6151, 6163, 6173, 6197, 6199, 6203, 6211, 6217, 6221, 6229, 6247, 6257, 6263, 6269, 6271, 6277, 6287, 6299, 6301, 6311, 6317, 6323, 6329, 6337, 6343, 6353, 6359, 6361, 6367, 6373, 6379, 6389, 6397, 6421, 6427, 6449, 6451, 6469, 6473, 6481, 6491, 6521, 6529, 6547, 6551, 6553, 6563, 6569, 6571, 6577, 6581, 6599, 6607, 6619, 6637, 6653, 6659, 6661, 6673, 6679, 6689, 6691, 6701, 6703, 6709, 6719, 6733, 6737, 6761, 6763, 6779, 6781, 6791, 6793, 6803, 6823, 6827, 6829, 6833, 6841, 6857, 6863, 6869, 6871, 6883, 6899, 6907, 6911, 6917, 6947, 6949, 6959, 6961, 6967, 6971, 6977, 6983, 6991, 6997, 7001, 7013, 7019, 7027, 7039, 7043, 7057, 7069, 7079, 7103, 7109, 7121, 7127, 7129, 7151, 7159, 7177, 7187, 7193, 7207, 7211, 7213, 7219, 7229, 7237, 7243, 7247, 7253, 7283, 7297, 7307, 7309, 7321, 7331, 7333, 7349, 7351, 7369, 7393, 7411, 7417, 7433, 7451, 7457, 7459, 7477, 7481, 7487, 7489, 7499, 7507, 7517, 7523, 7529, 7537, 7541, 7547, 7549, 7559, 7561, 7573, 7577, 7583, 7589, 7591, 7603, 7607, 7621, 7639, 7643, 7649, 7669, 7673, 7681, 7687, 7691, 7699, 7703, 7717, 7723, 7727, 7741, 7753, 7757, 7759, 7789, 7793, 7817, 7823, 7829, 7841, 7853, 7867, 7873, 7877, 7879, 7883, 7901, 7907, 7919, 7927, 7933, 7937, 7949, 7951, 7963, 7993, 8009, 8011, 8017, 8039, 8053, 8059, 8069, 8081, 8087, 8089, 8093, 8101, 8111, 8117, 8123, 8147, 8161, 8167, 8171, 8179, 8191, 8209, 8219, 8221, 8231, 8233, 8237, 8243, 8263, 8269, 8273, 8287, 8291, 8293, 8297, 8311, 8317, 8329, 8353, 8363, 8369, 8377, 8387, 8389, 8419, 8423, 8429, 8431, 8443, 8447, 8461, 8467, 8501, 8513, 8521, 8527, 8537, 8539, 8543, 8563, 8573, 8581, 8597, 8599, 8609, 8623, 8627, 8629, 8641, 8647, 8663, 8669, 8677, 8681, 8689, 8693, 8699, 8707, 8713, 8719, 8731, 8737, 8741, 8747, 8753, 8761, 8779, 8783, 8803, 8807, 8819, 8821, 8831, 8837, 8839, 8849, 8861, 8863, 8867, 8887, 8893, 8923, 8929, 8933, 8941, 8951, 8963, 8969, 8971, 8999, 9001, 9007, 9011, 9013, 9029, 9041, 9043, 9049, 9059, 9067, 9091, 9103, 9109, 9127, 9133, 9137, 9151, 9157, 9161, 9173, 9181, 9187, 9199, 9203, 9209, 9221, 9227, 9239, 9241, 9257, 9277, 9281, 9283, 9293, 9311, 9319, 9323, 9337, 9341, 9343, 9349, 9371, 9377, 9391, 9397, 9403, 9413, 9419, 9421, 9431, 9433, 9437, 9439, 9461, 9463, 9467, 9473, 9479, 9491, 9497, 9511, 9521, 9533, 9539, 9547, 9551, 9587, 9601, 9613, 9619, 9623, 9629, 9631, 9643, 9649, 9661, 9677, 9679, 9689, 9697, 9719, 9721, 9733, 9739, 9743, 9749, 9767, 9769, 9781, 9787, 9791, 9803, 9811, 9817, 9829, 9833, 9839, 9851, 9857, 9859, 9871, 9883, 9887, 9901, 9907, 9923, 9929, 9931, 9941, 9949, 9967, 9973}; private static final List BIGINT_PRIMES; static { BIGINT_PRIMES = new ArrayList(); for (int i = 0; i != PRIMES.length; i++) { BIGINT_PRIMES.add(BigInteger.valueOf(PRIMES[i])); } } public int[] coeffs; /** * Constructs a new polynomial with N coefficients initialized to 0. * * @param N the number of coefficients */ public IntegerPolynomial(int N) { coeffs = new int[N]; } /** * Constructs a new polynomial with a given set of coefficients. * * @param coeffs the coefficients */ public IntegerPolynomial(int[] coeffs) { this.coeffs = coeffs; } /** * Constructs a IntegerPolynomial from a BigIntPolynomial. The two polynomials are independent of each other. * * @param p the original polynomial */ public IntegerPolynomial(BigIntPolynomial p) { coeffs = new int[p.coeffs.length]; for (int i = 0; i < p.coeffs.length; i++) { coeffs[i] = p.coeffs[i].intValue(); } } /** * Decodes a byte array to a polynomial with N ternary coefficients
    * Ignores any excess bytes. * * @param data an encoded ternary polynomial * @param N number of coefficients * @return the decoded polynomial */ public static IntegerPolynomial fromBinary3Sves(byte[] data, int N) { return new IntegerPolynomial(ArrayEncoder.decodeMod3Sves(data, N)); } /** * Converts a byte array produced by {@link #toBinary3Tight()} to a polynomial. * * @param b a byte array * @param N number of coefficients * @return the decoded polynomial */ public static IntegerPolynomial fromBinary3Tight(byte[] b, int N) { return new IntegerPolynomial(ArrayEncoder.decodeMod3Tight(b, N)); } /** * Reads data produced by {@link #toBinary3Tight()} from an input stream and converts it to a polynomial. * * @param is an input stream * @param N number of coefficients * @return the decoded polynomial */ public static IntegerPolynomial fromBinary3Tight(InputStream is, int N) throws IOException { return new IntegerPolynomial(ArrayEncoder.decodeMod3Tight(is, N)); } /** * Returns a polynomial with N coefficients between 0 and q-1.
    * q must be a power of 2.
    * Ignores any excess bytes. * * @param data an encoded ternary polynomial * @param N number of coefficients * @param q * @return the decoded polynomial */ public static IntegerPolynomial fromBinary(byte[] data, int N, int q) { return new IntegerPolynomial(ArrayEncoder.decodeModQ(data, N, q)); } /** * Returns a polynomial with N coefficients between 0 and q-1.
    * q must be a power of 2.
    * Ignores any excess bytes. * * @param is an encoded ternary polynomial * @param N number of coefficients * @param q * @return the decoded polynomial */ public static IntegerPolynomial fromBinary(InputStream is, int N, int q) throws IOException { return new IntegerPolynomial(ArrayEncoder.decodeModQ(is, N, q)); } /** * Encodes a polynomial with ternary coefficients to binary. * coeffs[2*i] and coeffs[2*i+1] must not both equal -1 for any integer i, * so this method is only safe to use with polynomials produced by fromBinary3Sves(). * * @return the encoded polynomial */ public byte[] toBinary3Sves() { return ArrayEncoder.encodeMod3Sves(coeffs); } /** * Converts a polynomial with ternary coefficients to binary. * * @return the encoded polynomial */ public byte[] toBinary3Tight() { BigInteger sum = Constants.BIGINT_ZERO; for (int i = coeffs.length - 1; i >= 0; i--) { sum = sum.multiply(BigInteger.valueOf(3)); sum = sum.add(BigInteger.valueOf(coeffs[i] + 1)); } int size = (BigInteger.valueOf(3).pow(coeffs.length).bitLength() + 7) / 8; byte[] arr = sum.toByteArray(); if (arr.length < size) { // pad with leading zeros so arr.length==size byte[] arr2 = new byte[size]; System.arraycopy(arr, 0, arr2, size - arr.length, arr.length); return arr2; } if (arr.length > size) // drop sign bit { arr = Arrays.copyOfRange(arr, 1, arr.length); } return arr; } /** * Encodes a polynomial whose coefficients are between 0 and q, to binary. q must be a power of 2. * * @param q * @return the encoded polynomial */ public byte[] toBinary(int q) { return ArrayEncoder.encodeModQ(coeffs, q); } /** * Multiplies the polynomial with another, taking the values mod modulus and the indices mod N */ public IntegerPolynomial mult(IntegerPolynomial poly2, int modulus) { IntegerPolynomial c = mult(poly2); c.mod(modulus); return c; } /** * Multiplies the polynomial with another, taking the indices mod N */ public IntegerPolynomial mult(IntegerPolynomial poly2) { int N = coeffs.length; if (poly2.coeffs.length != N) { throw new IllegalArgumentException("Number of coefficients must be the same"); } IntegerPolynomial c = multRecursive(poly2); if (c.coeffs.length > N) { for (int k = N; k < c.coeffs.length; k++) { c.coeffs[k - N] += c.coeffs[k]; } c.coeffs = Arrays.copyOf(c.coeffs, N); } return c; } public BigIntPolynomial mult(BigIntPolynomial poly2) { return new BigIntPolynomial(this).mult(poly2); } /** * Karazuba multiplication */ private IntegerPolynomial multRecursive(IntegerPolynomial poly2) { int[] a = coeffs; int[] b = poly2.coeffs; int n = poly2.coeffs.length; if (n <= 32) { int cn = 2 * n - 1; IntegerPolynomial c = new IntegerPolynomial(new int[cn]); for (int k = 0; k < cn; k++) { for (int i = Math.max(0, k - n + 1); i <= Math.min(k, n - 1); i++) { c.coeffs[k] += b[i] * a[k - i]; } } return c; } else { int n1 = n / 2; IntegerPolynomial a1 = new IntegerPolynomial(Arrays.copyOf(a, n1)); IntegerPolynomial a2 = new IntegerPolynomial(Arrays.copyOfRange(a, n1, n)); IntegerPolynomial b1 = new IntegerPolynomial(Arrays.copyOf(b, n1)); IntegerPolynomial b2 = new IntegerPolynomial(Arrays.copyOfRange(b, n1, n)); IntegerPolynomial A = (IntegerPolynomial)a1.clone(); A.add(a2); IntegerPolynomial B = (IntegerPolynomial)b1.clone(); B.add(b2); IntegerPolynomial c1 = a1.multRecursive(b1); IntegerPolynomial c2 = a2.multRecursive(b2); IntegerPolynomial c3 = A.multRecursive(B); c3.sub(c1); c3.sub(c2); IntegerPolynomial c = new IntegerPolynomial(2 * n - 1); for (int i = 0; i < c1.coeffs.length; i++) { c.coeffs[i] = c1.coeffs[i]; } for (int i = 0; i < c3.coeffs.length; i++) { c.coeffs[n1 + i] += c3.coeffs[i]; } for (int i = 0; i < c2.coeffs.length; i++) { c.coeffs[2 * n1 + i] += c2.coeffs[i]; } return c; } } /** * Computes the inverse mod q; q must be a power of 2.
    * Returns null if the polynomial is not invertible. * * @param q the modulus * @return a new polynomial */ public IntegerPolynomial invertFq(int q) { int N = coeffs.length; int k = 0; IntegerPolynomial b = new IntegerPolynomial(N + 1); b.coeffs[0] = 1; IntegerPolynomial c = new IntegerPolynomial(N + 1); IntegerPolynomial f = new IntegerPolynomial(N + 1); f.coeffs = Arrays.copyOf(coeffs, N + 1); f.modPositive(2); // set g(x) = x^N − 1 IntegerPolynomial g = new IntegerPolynomial(N + 1); g.coeffs[0] = 1; g.coeffs[N] = 1; while (true) { while (f.coeffs[0] == 0) { for (int i = 1; i <= N; i++) { f.coeffs[i - 1] = f.coeffs[i]; // f(x) = f(x) / x c.coeffs[N + 1 - i] = c.coeffs[N - i]; // c(x) = c(x) * x } f.coeffs[N] = 0; c.coeffs[0] = 0; k++; if (f.equalsZero()) { return null; // not invertible } } if (f.equalsOne()) { break; } if (f.degree() < g.degree()) { // exchange f and g IntegerPolynomial temp = f; f = g; g = temp; // exchange b and c temp = b; b = c; c = temp; } f.add(g, 2); b.add(c, 2); } if (b.coeffs[N] != 0) { return null; } // Fq(x) = x^(N-k) * b(x) IntegerPolynomial Fq = new IntegerPolynomial(N); int j = 0; k %= N; for (int i = N - 1; i >= 0; i--) { j = i - k; if (j < 0) { j += N; } Fq.coeffs[j] = b.coeffs[i]; } return mod2ToModq(Fq, q); } /** * Computes the inverse mod q from the inverse mod 2 * * @param Fq * @param q * @return The inverse of this polynomial mod q */ private IntegerPolynomial mod2ToModq(IntegerPolynomial Fq, int q) { if (Util.is64BitJVM() && q == 2048) { LongPolynomial2 thisLong = new LongPolynomial2(this); LongPolynomial2 FqLong = new LongPolynomial2(Fq); int v = 2; while (v < q) { v *= 2; LongPolynomial2 temp = (LongPolynomial2)FqLong.clone(); temp.mult2And(v - 1); FqLong = thisLong.mult(FqLong).mult(FqLong); temp.subAnd(FqLong, v - 1); FqLong = temp; } return FqLong.toIntegerPolynomial(); } else { int v = 2; while (v < q) { v *= 2; IntegerPolynomial temp = new IntegerPolynomial(Arrays.copyOf(Fq.coeffs, Fq.coeffs.length)); temp.mult2(v); Fq = mult(Fq, v).mult(Fq, v); temp.sub(Fq, v); Fq = temp; } return Fq; } } /** * Computes the inverse mod 3. * Returns null if the polynomial is not invertible. * * @return a new polynomial */ public IntegerPolynomial invertF3() { int N = coeffs.length; int k = 0; IntegerPolynomial b = new IntegerPolynomial(N + 1); b.coeffs[0] = 1; IntegerPolynomial c = new IntegerPolynomial(N + 1); IntegerPolynomial f = new IntegerPolynomial(N + 1); f.coeffs = Arrays.copyOf(coeffs, N + 1); f.modPositive(3); // set g(x) = x^N − 1 IntegerPolynomial g = new IntegerPolynomial(N + 1); g.coeffs[0] = -1; g.coeffs[N] = 1; while (true) { while (f.coeffs[0] == 0) { for (int i = 1; i <= N; i++) { f.coeffs[i - 1] = f.coeffs[i]; // f(x) = f(x) / x c.coeffs[N + 1 - i] = c.coeffs[N - i]; // c(x) = c(x) * x } f.coeffs[N] = 0; c.coeffs[0] = 0; k++; if (f.equalsZero()) { return null; // not invertible } } if (f.equalsAbsOne()) { break; } if (f.degree() < g.degree()) { // exchange f and g IntegerPolynomial temp = f; f = g; g = temp; // exchange b and c temp = b; b = c; c = temp; } if (f.coeffs[0] == g.coeffs[0]) { f.sub(g, 3); b.sub(c, 3); } else { f.add(g, 3); b.add(c, 3); } } if (b.coeffs[N] != 0) { return null; } // Fp(x) = [+-] x^(N-k) * b(x) IntegerPolynomial Fp = new IntegerPolynomial(N); int j = 0; k %= N; for (int i = N - 1; i >= 0; i--) { j = i - k; if (j < 0) { j += N; } Fp.coeffs[j] = f.coeffs[0] * b.coeffs[i]; } Fp.ensurePositive(3); return Fp; } /** * Resultant of this polynomial with x^n-1 using a probabilistic algorithm. *

    * Unlike EESS, this implementation does not compute all resultants modulo primes * such that their product exceeds the maximum possible resultant, but rather stops * when NUM_EQUAL_RESULTANTS consecutive modular resultants are equal.
    * This means the return value may be incorrect. Experiments show this happens in * about 1 out of 100 cases when N=439 and NUM_EQUAL_RESULTANTS=2, * so the likelyhood of leaving the loop too early is (1/100)^(NUM_EQUAL_RESULTANTS-1). *

    * Because of the above, callers must verify the output and try a different polynomial if necessary. * * @return (rho, res) satisfying res = rho*this + t*(x^n-1) for some integer t. */ public Resultant resultant() { int N = coeffs.length; // Compute resultants modulo prime numbers. Continue until NUM_EQUAL_RESULTANTS consecutive modular resultants are equal. LinkedList modResultants = new LinkedList(); BigInteger prime = null; BigInteger pProd = Constants.BIGINT_ONE; BigInteger res = Constants.BIGINT_ONE; int numEqual = 1; // number of consecutive modular resultants equal to each other Iterator primes = BIGINT_PRIMES.iterator(); while (true) { prime = primes.hasNext() ? primes.next() : prime.nextProbablePrime(); ModularResultant crr = resultant(prime.intValue()); modResultants.add(crr); BigInteger temp = pProd.multiply(prime); BigIntEuclidean er = BigIntEuclidean.calculate(prime, pProd); BigInteger resPrev = res; res = res.multiply(er.x.multiply(prime)); BigInteger res2 = crr.res.multiply(er.y.multiply(pProd)); res = res.add(res2).mod(temp); pProd = temp; BigInteger pProd2 = pProd.divide(BigInteger.valueOf(2)); BigInteger pProd2n = pProd2.negate(); if (res.compareTo(pProd2) > 0) { res = res.subtract(pProd); } else if (res.compareTo(pProd2n) < 0) { res = res.add(pProd); } if (res.equals(resPrev)) { numEqual++; if (numEqual >= NUM_EQUAL_RESULTANTS) { break; } } else { numEqual = 1; } } // Combine modular rho's to obtain the final rho. // For efficiency, first combine all pairs of small resultants to bigger resultants, // then combine pairs of those, etc. until only one is left. while (modResultants.size() > 1) { ModularResultant modRes1 = modResultants.removeFirst(); ModularResultant modRes2 = modResultants.removeFirst(); ModularResultant modRes3 = ModularResultant.combineRho(modRes1, modRes2); modResultants.addLast(modRes3); } BigIntPolynomial rhoP = modResultants.getFirst().rho; BigInteger pProd2 = pProd.divide(BigInteger.valueOf(2)); BigInteger pProd2n = pProd2.negate(); if (res.compareTo(pProd2) > 0) { res = res.subtract(pProd); } if (res.compareTo(pProd2n) < 0) { res = res.add(pProd); } for (int i = 0; i < N; i++) { BigInteger c = rhoP.coeffs[i]; if (c.compareTo(pProd2) > 0) { rhoP.coeffs[i] = c.subtract(pProd); } if (c.compareTo(pProd2n) < 0) { rhoP.coeffs[i] = c.add(pProd); } } return new Resultant(rhoP, res); } /** * Multithreaded version of {@link #resultant()}. * * @return (rho, res) satisfying res = rho*this + t*(x^n-1) for some integer t. */ public Resultant resultantMultiThread() { int N = coeffs.length; // upper bound for resultant(f, g) = ||f, 2||^deg(g) * ||g, 2||^deg(f) = squaresum(f)^(N/2) * 2^(deg(f)/2) because g(x)=x^N-1 // see http://jondalon.mathematik.uni-osnabrueck.de/staff/phpages/brunsw/CompAlg.pdf chapter 3 BigInteger max = squareSum().pow((N + 1) / 2); max = max.multiply(BigInteger.valueOf(2).pow((degree() + 1) / 2)); BigInteger max2 = max.multiply(BigInteger.valueOf(2)); // compute resultants modulo prime numbers BigInteger prime = BigInteger.valueOf(10000); BigInteger pProd = Constants.BIGINT_ONE; LinkedBlockingQueue> resultantTasks = new LinkedBlockingQueue>(); Iterator primes = BIGINT_PRIMES.iterator(); ExecutorService executor = Executors.newFixedThreadPool(Runtime.getRuntime().availableProcessors()); while (pProd.compareTo(max2) < 0) { if (primes.hasNext()) { prime = primes.next(); } else { prime = prime.nextProbablePrime(); } Future task = executor.submit(new ModResultantTask(prime.intValue())); resultantTasks.add(task); pProd = pProd.multiply(prime); } // Combine modular resultants to obtain the resultant. // For efficiency, first combine all pairs of small resultants to bigger resultants, // then combine pairs of those, etc. until only one is left. ModularResultant overallResultant = null; while (!resultantTasks.isEmpty()) { try { Future modRes1 = resultantTasks.take(); Future modRes2 = resultantTasks.poll(); if (modRes2 == null) { // modRes1 is the only one left overallResultant = modRes1.get(); break; } Future newTask = executor.submit(new CombineTask(modRes1.get(), modRes2.get())); resultantTasks.add(newTask); } catch (Exception e) { throw new IllegalStateException(e.toString()); } } executor.shutdown(); BigInteger res = overallResultant.res; BigIntPolynomial rhoP = overallResultant.rho; BigInteger pProd2 = pProd.divide(BigInteger.valueOf(2)); BigInteger pProd2n = pProd2.negate(); if (res.compareTo(pProd2) > 0) { res = res.subtract(pProd); } if (res.compareTo(pProd2n) < 0) { res = res.add(pProd); } for (int i = 0; i < N; i++) { BigInteger c = rhoP.coeffs[i]; if (c.compareTo(pProd2) > 0) { rhoP.coeffs[i] = c.subtract(pProd); } if (c.compareTo(pProd2n) < 0) { rhoP.coeffs[i] = c.add(pProd); } } return new Resultant(rhoP, res); } /** * Resultant of this polynomial with x^n-1 mod p.
    * * @return (rho, res) satisfying res = rho*this + t*(x^n-1) mod p for some integer t. */ public ModularResultant resultant(int p) { // Add a coefficient as the following operations involve polynomials of degree deg(f)+1 int[] fcoeffs = Arrays.copyOf(coeffs, coeffs.length + 1); IntegerPolynomial f = new IntegerPolynomial(fcoeffs); int N = fcoeffs.length; IntegerPolynomial a = new IntegerPolynomial(N); a.coeffs[0] = -1; a.coeffs[N - 1] = 1; IntegerPolynomial b = new IntegerPolynomial(f.coeffs); IntegerPolynomial v1 = new IntegerPolynomial(N); IntegerPolynomial v2 = new IntegerPolynomial(N); v2.coeffs[0] = 1; int da = N - 1; int db = b.degree(); int ta = da; int c = 0; int r = 1; while (db > 0) { c = Util.invert(b.coeffs[db], p); c = (c * a.coeffs[da]) % p; a.multShiftSub(b, c, da - db, p); v1.multShiftSub(v2, c, da - db, p); da = a.degree(); if (da < db) { r *= Util.pow(b.coeffs[db], ta - da, p); r %= p; if (ta % 2 == 1 && db % 2 == 1) { r = (-r) % p; } IntegerPolynomial temp = a; a = b; b = temp; int tempdeg = da; da = db; temp = v1; v1 = v2; v2 = temp; ta = db; db = tempdeg; } } r *= Util.pow(b.coeffs[0], da, p); r %= p; c = Util.invert(b.coeffs[0], p); v2.mult(c); v2.mod(p); v2.mult(r); v2.mod(p); // drop the highest coefficient so #coeffs matches the original input v2.coeffs = Arrays.copyOf(v2.coeffs, v2.coeffs.length - 1); return new ModularResultant(new BigIntPolynomial(v2), BigInteger.valueOf(r), BigInteger.valueOf(p)); } /** * Computes this-b*c*(x^k) mod p and stores the result in this polynomial.
    * See steps 4a,4b in EESS algorithm 2.2.7.1. * * @param b * @param c * @param k * @param p */ private void multShiftSub(IntegerPolynomial b, int c, int k, int p) { int N = coeffs.length; for (int i = k; i < N; i++) { coeffs[i] = (coeffs[i] - b.coeffs[i - k] * c) % p; } } /** * Adds the squares of all coefficients. * * @return the sum of squares */ private BigInteger squareSum() { BigInteger sum = Constants.BIGINT_ZERO; for (int i = 0; i < coeffs.length; i++) { sum = sum.add(BigInteger.valueOf(coeffs[i] * coeffs[i])); } return sum; } /** * Returns the degree of the polynomial * * @return the degree */ int degree() { int degree = coeffs.length - 1; while (degree > 0 && coeffs[degree] == 0) { degree--; } return degree; } /** * Adds another polynomial which can have a different number of coefficients, * and takes the coefficient values mod modulus. * * @param b another polynomial */ public void add(IntegerPolynomial b, int modulus) { add(b); mod(modulus); } /** * Adds another polynomial which can have a different number of coefficients. * * @param b another polynomial */ public void add(IntegerPolynomial b) { if (b.coeffs.length > coeffs.length) { coeffs = Arrays.copyOf(coeffs, b.coeffs.length); } for (int i = 0; i < b.coeffs.length; i++) { coeffs[i] += b.coeffs[i]; } } /** * Subtracts another polynomial which can have a different number of coefficients, * and takes the coefficient values mod modulus. * * @param b another polynomial */ public void sub(IntegerPolynomial b, int modulus) { sub(b); mod(modulus); } /** * Subtracts another polynomial which can have a different number of coefficients. * * @param b another polynomial */ public void sub(IntegerPolynomial b) { if (b.coeffs.length > coeffs.length) { coeffs = Arrays.copyOf(coeffs, b.coeffs.length); } for (int i = 0; i < b.coeffs.length; i++) { coeffs[i] -= b.coeffs[i]; } } /** * Subtracts a int from each coefficient. Does not return a new polynomial but modifies this polynomial. * * @param b */ void sub(int b) { for (int i = 0; i < coeffs.length; i++) { coeffs[i] -= b; } } /** * Multiplies each coefficient by a int. Does not return a new polynomial but modifies this polynomial. * * @param factor */ public void mult(int factor) { for (int i = 0; i < coeffs.length; i++) { coeffs[i] *= factor; } } /** * Multiplies each coefficient by a 2 and applies a modulus. Does not return a new polynomial but modifies this polynomial. * * @param modulus a modulus */ private void mult2(int modulus) { for (int i = 0; i < coeffs.length; i++) { coeffs[i] *= 2; coeffs[i] %= modulus; } } /** * Multiplies each coefficient by a 2 and applies a modulus. Does not return a new polynomial but modifies this polynomial. * * @param modulus a modulus */ public void mult3(int modulus) { for (int i = 0; i < coeffs.length; i++) { coeffs[i] *= 3; coeffs[i] %= modulus; } } /** * Divides each coefficient by k and rounds to the nearest integer. Does not return a new polynomial but modifies this polynomial. * * @param k the divisor */ public void div(int k) { int k2 = (k + 1) / 2; for (int i = 0; i < coeffs.length; i++) { coeffs[i] += coeffs[i] > 0 ? k2 : -k2; coeffs[i] /= k; } } /** * Takes each coefficient modulo 3 such that all coefficients are ternary. */ public void mod3() { for (int i = 0; i < coeffs.length; i++) { coeffs[i] %= 3; if (coeffs[i] > 1) { coeffs[i] -= 3; } if (coeffs[i] < -1) { coeffs[i] += 3; } } } /** * Ensures all coefficients are between 0 and modulus-1 * * @param modulus a modulus */ public void modPositive(int modulus) { mod(modulus); ensurePositive(modulus); } /** * Reduces all coefficients to the interval [-modulus/2, modulus/2) */ void modCenter(int modulus) { mod(modulus); for (int j = 0; j < coeffs.length; j++) { while (coeffs[j] < modulus / 2) { coeffs[j] += modulus; } while (coeffs[j] >= modulus / 2) { coeffs[j] -= modulus; } } } /** * Takes each coefficient modulo modulus. */ public void mod(int modulus) { for (int i = 0; i < coeffs.length; i++) { coeffs[i] %= modulus; } } /** * Adds modulus until all coefficients are above 0. * * @param modulus a modulus */ public void ensurePositive(int modulus) { for (int i = 0; i < coeffs.length; i++) { while (coeffs[i] < 0) { coeffs[i] += modulus; } } } /** * Computes the centered euclidean norm of the polynomial. * * @param q a modulus * @return the centered norm */ public long centeredNormSq(int q) { int N = coeffs.length; IntegerPolynomial p = (IntegerPolynomial)clone(); p.shiftGap(q); long sum = 0; long sqSum = 0; for (int i = 0; i != p.coeffs.length; i++) { int c = p.coeffs[i]; sum += c; sqSum += c * c; } long centeredNormSq = sqSum - sum * sum / N; return centeredNormSq; } /** * Shifts all coefficients so the largest gap is centered around -q/2. * * @param q a modulus */ void shiftGap(int q) { modCenter(q); int[] sorted = Arrays.clone(coeffs); sort(sorted); int maxrange = 0; int maxrangeStart = 0; for (int i = 0; i < sorted.length - 1; i++) { int range = sorted[i + 1] - sorted[i]; if (range > maxrange) { maxrange = range; maxrangeStart = sorted[i]; } } int pmin = sorted[0]; int pmax = sorted[sorted.length - 1]; int j = q - pmax + pmin; int shift; if (j > maxrange) { shift = (pmax + pmin) / 2; } else { shift = maxrangeStart + maxrange / 2 + q / 2; } sub(shift); } private void sort(int[] ints) { boolean swap = true; while (swap) { swap = false; for (int i = 0; i != ints.length - 1; i++) { if (ints[i] > ints[i+1]) { int tmp = ints[i]; ints[i] = ints[i+1]; ints[i+1] = tmp; swap = true; } } } } /** * Shifts the values of all coefficients to the interval [-q/2, q/2]. * * @param q a modulus */ public void center0(int q) { for (int i = 0; i < coeffs.length; i++) { while (coeffs[i] < -q / 2) { coeffs[i] += q; } while (coeffs[i] > q / 2) { coeffs[i] -= q; } } } /** * Returns the sum of all coefficients, i.e. evaluates the polynomial at 0. * * @return the sum of all coefficients */ public int sumCoeffs() { int sum = 0; for (int i = 0; i < coeffs.length; i++) { sum += coeffs[i]; } return sum; } /** * Tests if p(x) = 0. * * @return true iff all coefficients are zeros */ private boolean equalsZero() { for (int i = 0; i < coeffs.length; i++) { if (coeffs[i] != 0) { return false; } } return true; } /** * Tests if p(x) = 1. * * @return true iff all coefficients are equal to zero, except for the lowest coefficient which must equal 1 */ public boolean equalsOne() { for (int i = 1; i < coeffs.length; i++) { if (coeffs[i] != 0) { return false; } } return coeffs[0] == 1; } /** * Tests if |p(x)| = 1. * * @return true iff all coefficients are equal to zero, except for the lowest coefficient which must equal 1 or -1 */ private boolean equalsAbsOne() { for (int i = 1; i < coeffs.length; i++) { if (coeffs[i] != 0) { return false; } } return Math.abs(coeffs[0]) == 1; } /** * Counts the number of coefficients equal to an integer * * @param value an integer * @return the number of coefficients equal to value */ public int count(int value) { int count = 0; for (int i = 0; i != coeffs.length; i++) { if (coeffs[i] == value) { count++; } } return count; } /** * Multiplication by X in Z[X]/Z[X^n-1]. */ public void rotate1() { int clast = coeffs[coeffs.length - 1]; for (int i = coeffs.length - 1; i > 0; i--) { coeffs[i] = coeffs[i - 1]; } coeffs[0] = clast; } public void clear() { for (int i = 0; i < coeffs.length; i++) { coeffs[i] = 0; } } public IntegerPolynomial toIntegerPolynomial() { return (IntegerPolynomial)clone(); } public Object clone() { return new IntegerPolynomial(coeffs.clone()); } public boolean equals(Object obj) { if (obj instanceof IntegerPolynomial) { return Arrays.areEqual(coeffs, ((IntegerPolynomial)obj).coeffs); } else { return false; } } /** * Calls {@link IntegerPolynomial#resultant(int) */ private class ModResultantTask implements Callable { private int modulus; private ModResultantTask(int modulus) { this.modulus = modulus; } public ModularResultant call() { return resultant(modulus); } } /** * Calls {@link ModularResultant#combineRho(ModularResultant, ModularResultant) */ private class CombineTask implements Callable { private ModularResultant modRes1; private ModularResultant modRes2; private CombineTask(ModularResultant modRes1, ModularResultant modRes2) { this.modRes1 = modRes1; this.modRes2 = modRes2; } public ModularResultant call() { return ModularResultant.combineRho(modRes1, modRes2); } } } bouncycastle-1.49.orig/src/org/bouncycastle/pqc/math/ntru/polynomial/TernaryPolynomial.java0000644000175000017500000000101512113311460031711 0ustar ebourgebourgpackage org.bouncycastle.pqc.math.ntru.polynomial; /** * A polynomial whose coefficients are all equal to -1, 0, or 1 */ public interface TernaryPolynomial extends Polynomial { /** * Multiplies the polynomial by an IntegerPolynomial, taking the indices mod N */ IntegerPolynomial mult(IntegerPolynomial poly2); int[] getOnes(); int[] getNegOnes(); /** * Returns the maximum number of coefficients the polynomial can have */ int size(); void clear(); } bouncycastle-1.49.orig/src/org/bouncycastle/pqc/math/ntru/polynomial/Resultant.java0000644000175000017500000000125112113311460030204 0ustar ebourgebourgpackage org.bouncycastle.pqc.math.ntru.polynomial; import java.math.BigInteger; /** * Contains a resultant and a polynomial rho such that * res = rho*this + t*(x^n-1) for some integer t. * * @see IntegerPolynomial#resultant() * @see IntegerPolynomial#resultant(int) */ public class Resultant { /** * A polynomial such that res = rho*this + t*(x^n-1) for some integer t */ public BigIntPolynomial rho; /** * Resultant of a polynomial with x^n-1 */ public BigInteger res; Resultant(BigIntPolynomial rho, BigInteger res) { this.rho = rho; this.res = res; } } bouncycastle-1.49.orig/src/org/bouncycastle/pqc/math/ntru/polynomial/DenseTernaryPolynomial.java0000644000175000017500000000746112113311460032703 0ustar ebourgebourgpackage org.bouncycastle.pqc.math.ntru.polynomial; import java.security.SecureRandom; import org.bouncycastle.pqc.math.ntru.util.Util; import org.bouncycastle.util.Arrays; /** * A TernaryPolynomial with a "high" number of nonzero coefficients. */ public class DenseTernaryPolynomial extends IntegerPolynomial implements TernaryPolynomial { /** * Constructs a new DenseTernaryPolynomial with N coefficients. * * @param N the number of coefficients */ DenseTernaryPolynomial(int N) { super(N); checkTernarity(); } /** * Constructs a DenseTernaryPolynomial from a IntegerPolynomial. The two polynomials are * independent of each other. * * @param intPoly the original polynomial */ public DenseTernaryPolynomial(IntegerPolynomial intPoly) { this(intPoly.coeffs); } /** * Constructs a new DenseTernaryPolynomial with a given set of coefficients. * * @param coeffs the coefficients */ public DenseTernaryPolynomial(int[] coeffs) { super(coeffs); checkTernarity(); } private void checkTernarity() { for (int i = 0; i != coeffs.length; i++) { int c = coeffs[i]; if (c < -1 || c > 1) { throw new IllegalStateException("Illegal value: " + c + ", must be one of {-1, 0, 1}"); } } } /** * Generates a random polynomial with numOnes coefficients equal to 1, * numNegOnes coefficients equal to -1, and the rest equal to 0. * * @param N number of coefficients * @param numOnes number of 1's * @param numNegOnes number of -1's */ public static DenseTernaryPolynomial generateRandom(int N, int numOnes, int numNegOnes, SecureRandom random) { int[] coeffs = Util.generateRandomTernary(N, numOnes, numNegOnes, random); return new DenseTernaryPolynomial(coeffs); } /** * Generates a polynomial with coefficients randomly selected from {-1, 0, 1}. * * @param N number of coefficients */ public static DenseTernaryPolynomial generateRandom(int N, SecureRandom random) { DenseTernaryPolynomial poly = new DenseTernaryPolynomial(N); for (int i = 0; i < N; i++) { poly.coeffs[i] = random.nextInt(3) - 1; } return poly; } public IntegerPolynomial mult(IntegerPolynomial poly2, int modulus) { // even on 32-bit systems, LongPolynomial5 multiplies faster than IntegerPolynomial if (modulus == 2048) { IntegerPolynomial poly2Pos = (IntegerPolynomial)poly2.clone(); poly2Pos.modPositive(2048); LongPolynomial5 poly5 = new LongPolynomial5(poly2Pos); return poly5.mult(this).toIntegerPolynomial(); } else { return super.mult(poly2, modulus); } } public int[] getOnes() { int N = coeffs.length; int[] ones = new int[N]; int onesIdx = 0; for (int i = 0; i < N; i++) { int c = coeffs[i]; if (c == 1) { ones[onesIdx++] = i; } } return Arrays.copyOf(ones, onesIdx); } public int[] getNegOnes() { int N = coeffs.length; int[] negOnes = new int[N]; int negOnesIdx = 0; for (int i = 0; i < N; i++) { int c = coeffs[i]; if (c == -1) { negOnes[negOnesIdx++] = i; } } return Arrays.copyOf(negOnes, negOnesIdx); } public int size() { return coeffs.length; } } bouncycastle-1.49.orig/src/org/bouncycastle/pqc/math/ntru/polynomial/Constants.java0000644000175000017500000000051412113311460030200 0ustar ebourgebourgpackage org.bouncycastle.pqc.math.ntru.polynomial; import java.math.BigDecimal; import java.math.BigInteger; public class Constants { static final BigInteger BIGINT_ZERO = BigInteger.valueOf(0); static final BigInteger BIGINT_ONE = BigInteger.valueOf(1); static final BigDecimal BIGDEC_ONE = BigDecimal.valueOf(1); } bouncycastle-1.49.orig/src/org/bouncycastle/pqc/math/ntru/polynomial/ProductFormPolynomial.java0000644000175000017500000001047712113311460032545 0ustar ebourgebourgpackage org.bouncycastle.pqc.math.ntru.polynomial; import java.io.ByteArrayInputStream; import java.io.IOException; import java.io.InputStream; import java.security.SecureRandom; import org.bouncycastle.util.Arrays; /** * A polynomial of the form f1*f2+f3, where * f1,f2,f3 are very sparsely populated ternary polynomials. */ public class ProductFormPolynomial implements Polynomial { private SparseTernaryPolynomial f1, f2, f3; public ProductFormPolynomial(SparseTernaryPolynomial f1, SparseTernaryPolynomial f2, SparseTernaryPolynomial f3) { this.f1 = f1; this.f2 = f2; this.f3 = f3; } public static ProductFormPolynomial generateRandom(int N, int df1, int df2, int df3Ones, int df3NegOnes, SecureRandom random) { SparseTernaryPolynomial f1 = SparseTernaryPolynomial.generateRandom(N, df1, df1, random); SparseTernaryPolynomial f2 = SparseTernaryPolynomial.generateRandom(N, df2, df2, random); SparseTernaryPolynomial f3 = SparseTernaryPolynomial.generateRandom(N, df3Ones, df3NegOnes, random); return new ProductFormPolynomial(f1, f2, f3); } public static ProductFormPolynomial fromBinary(byte[] data, int N, int df1, int df2, int df3Ones, int df3NegOnes) throws IOException { return fromBinary(new ByteArrayInputStream(data), N, df1, df2, df3Ones, df3NegOnes); } public static ProductFormPolynomial fromBinary(InputStream is, int N, int df1, int df2, int df3Ones, int df3NegOnes) throws IOException { SparseTernaryPolynomial f1; f1 = SparseTernaryPolynomial.fromBinary(is, N, df1, df1); SparseTernaryPolynomial f2 = SparseTernaryPolynomial.fromBinary(is, N, df2, df2); SparseTernaryPolynomial f3 = SparseTernaryPolynomial.fromBinary(is, N, df3Ones, df3NegOnes); return new ProductFormPolynomial(f1, f2, f3); } public byte[] toBinary() { byte[] f1Bin = f1.toBinary(); byte[] f2Bin = f2.toBinary(); byte[] f3Bin = f3.toBinary(); byte[] all = Arrays.copyOf(f1Bin, f1Bin.length + f2Bin.length + f3Bin.length); System.arraycopy(f2Bin, 0, all, f1Bin.length, f2Bin.length); System.arraycopy(f3Bin, 0, all, f1Bin.length + f2Bin.length, f3Bin.length); return all; } public IntegerPolynomial mult(IntegerPolynomial b) { IntegerPolynomial c = f1.mult(b); c = f2.mult(c); c.add(f3.mult(b)); return c; } public BigIntPolynomial mult(BigIntPolynomial b) { BigIntPolynomial c = f1.mult(b); c = f2.mult(c); c.add(f3.mult(b)); return c; } public IntegerPolynomial toIntegerPolynomial() { IntegerPolynomial i = f1.mult(f2.toIntegerPolynomial()); i.add(f3.toIntegerPolynomial()); return i; } public IntegerPolynomial mult(IntegerPolynomial poly2, int modulus) { IntegerPolynomial c = mult(poly2); c.mod(modulus); return c; } public int hashCode() { final int prime = 31; int result = 1; result = prime * result + ((f1 == null) ? 0 : f1.hashCode()); result = prime * result + ((f2 == null) ? 0 : f2.hashCode()); result = prime * result + ((f3 == null) ? 0 : f3.hashCode()); return result; } public boolean equals(Object obj) { if (this == obj) { return true; } if (obj == null) { return false; } if (getClass() != obj.getClass()) { return false; } ProductFormPolynomial other = (ProductFormPolynomial)obj; if (f1 == null) { if (other.f1 != null) { return false; } } else if (!f1.equals(other.f1)) { return false; } if (f2 == null) { if (other.f2 != null) { return false; } } else if (!f2.equals(other.f2)) { return false; } if (f3 == null) { if (other.f3 != null) { return false; } } else if (!f3.equals(other.f3)) { return false; } return true; } } bouncycastle-1.49.orig/src/org/bouncycastle/pqc/jcajce/0000755000175000017500000000000012152033551022501 5ustar ebourgebourgbouncycastle-1.49.orig/src/org/bouncycastle/pqc/jcajce/provider/0000755000175000017500000000000012152033551024333 5ustar ebourgebourgbouncycastle-1.49.orig/src/org/bouncycastle/pqc/jcajce/provider/McEliece.java0000644000175000017500000001072612057035105026653 0ustar ebourgebourgpackage org.bouncycastle.pqc.jcajce.provider; import org.bouncycastle.jcajce.provider.config.ConfigurableProvider; import org.bouncycastle.jcajce.provider.util.AsymmetricAlgorithmProvider; import org.bouncycastle.pqc.asn1.PQCObjectIdentifiers; public class McEliece { private static final String PREFIX = "org.bouncycastle.pqc.jcajce.provider" + ".mceliece."; public static class Mappings extends AsymmetricAlgorithmProvider { public Mappings() { } public void configure(ConfigurableProvider provider) { // McElieceKobaraImai provider.addAlgorithm("KeyPairGenerator.McElieceKobaraImai", PREFIX + "McElieceKeyPairGeneratorSpi$McElieceCCA2"); // McEliecePointcheval provider.addAlgorithm("KeyPairGenerator.McEliecePointcheval", PREFIX + "McElieceKeyPairGeneratorSpi$McElieceCCA2"); // McElieceFujisaki provider.addAlgorithm("KeyPairGenerator.McElieceFujisaki", PREFIX + "McElieceKeyPairGeneratorSpi$McElieceCCA2"); // McEliecePKCS provider.addAlgorithm("KeyPairGenerator.McEliecePKCS", PREFIX + "McElieceKeyPairGeneratorSpi$McEliece"); provider.addAlgorithm("KeyPairGenerator." + PQCObjectIdentifiers.mcEliece, PREFIX + "McElieceKeyPairGeneratorSpi$McEliece"); provider.addAlgorithm("KeyPairGenerator." + PQCObjectIdentifiers.mcElieceCca2, PREFIX + "McElieceKeyPairGeneratorSpi$McElieceCCA2"); provider.addAlgorithm("Cipher.McEliecePointcheval", PREFIX + "McEliecePointchevalCipherSpi$McEliecePointcheval"); provider.addAlgorithm("Cipher.McEliecePointchevalWithSHA1", PREFIX + "McEliecePointchevalCipherSpi$McEliecePointcheval"); provider.addAlgorithm("Cipher.McEliecePointchevalWithSHA224", PREFIX + "McEliecePointchevalCipherSpi$McEliecePointcheval224"); provider.addAlgorithm("Cipher.McEliecePointchevalWithSHA256", PREFIX + "McEliecePointchevalCipherSpi$McEliecePointcheval256"); provider.addAlgorithm("Cipher.McEliecePointchevalWithSHA384", PREFIX + "McEliecePointchevalCipherSpi$McEliecePointcheval384"); provider.addAlgorithm("Cipher.McEliecePointchevalWithSHA512", PREFIX + "McEliecePointchevalCipherSpi$McEliecePointcheval512"); provider.addAlgorithm("Cipher.McEliecePKCS", PREFIX + "McEliecePKCSCipherSpi$McEliecePKCS"); provider.addAlgorithm("Cipher.McEliecePKCSWithSHA1", PREFIX + "McEliecePKCSCipherSpi$McEliecePKCS"); provider.addAlgorithm("Cipher.McEliecePKCSWithSHA224", PREFIX + "McEliecePKCSCipherSpi$McEliecePKCS224"); provider.addAlgorithm("Cipher.McEliecePKCSWithSHA256", PREFIX + "McEliecePKCSCipherSpi$McEliecePKCS256"); provider.addAlgorithm("Cipher.McEliecePKCSWithSHA384", PREFIX + "McEliecePKCSCipherSpi$McEliecePKCS384"); provider.addAlgorithm("Cipher.McEliecePKCSWithSHA512", PREFIX + "McEliecePKCSCipherSpi$McEliecePKCS512"); provider.addAlgorithm("Cipher.McElieceKobaraImai", PREFIX + "McElieceKobaraImaiCipherSpi$McElieceKobaraImai"); provider.addAlgorithm("Cipher.McElieceKobaraImaiWithSHA1", PREFIX + "McElieceKobaraImaiCipherSpi$McElieceKobaraImai"); provider.addAlgorithm("Cipher.McElieceKobaraImaiWithSHA224", PREFIX + "McElieceKobaraImaiCipherSpi$McElieceKobaraImai224"); provider.addAlgorithm("Cipher.McElieceKobaraImaiWithSHA256", PREFIX + "McElieceKobaraImaiCipherSpi$McElieceKobaraImai256"); provider.addAlgorithm("Cipher.McElieceKobaraImaiWithSHA384", PREFIX + "McElieceKobaraImaiCipherSpi$McElieceKobaraImai384"); provider.addAlgorithm("Cipher.McElieceKobaraImaiWithSHA512", PREFIX + "McElieceKobaraImaiCipherSpi$McElieceKobaraImai512"); provider.addAlgorithm("Cipher.McElieceFujisaki", PREFIX + "McElieceFujisakiCipherSpi$McElieceFujisaki"); provider.addAlgorithm("Cipher.McElieceFujisakiWithSHA1", PREFIX + "McElieceFujisakiCipherSpi$McElieceFujisaki"); provider.addAlgorithm("Cipher.McElieceFujisakiWithSHA224", PREFIX + "McElieceFujisakiCipherSpi$McElieceFujisaki224"); provider.addAlgorithm("Cipher.McElieceFujisakiWithSHA256", PREFIX + "McElieceFujisakiCipherSpi$McElieceFujisaki256"); provider.addAlgorithm("Cipher.McElieceFujisakiWithSHA384", PREFIX + "McElieceFujisakiCipherSpi$McElieceFujisaki384"); provider.addAlgorithm("Cipher.McElieceFujisakiWithSHA512", PREFIX + "McElieceFujisakiCipherSpi$McElieceFujisaki512"); } } } bouncycastle-1.49.orig/src/org/bouncycastle/pqc/jcajce/provider/BouncyCastlePQCProvider.java0000644000175000017500000001111612104146653031655 0ustar ebourgebourgpackage org.bouncycastle.pqc.jcajce.provider; import java.io.IOException; import java.security.AccessController; import java.security.PrivateKey; import java.security.PrivilegedAction; import java.security.Provider; import java.security.PublicKey; import java.util.HashMap; import java.util.Map; import org.bouncycastle.asn1.ASN1ObjectIdentifier; import org.bouncycastle.asn1.pkcs.PrivateKeyInfo; import org.bouncycastle.asn1.x509.SubjectPublicKeyInfo; import org.bouncycastle.jcajce.provider.config.ConfigurableProvider; import org.bouncycastle.jcajce.provider.config.ProviderConfiguration; import org.bouncycastle.jcajce.provider.util.AlgorithmProvider; import org.bouncycastle.jcajce.provider.util.AsymmetricKeyInfoConverter; public class BouncyCastlePQCProvider extends Provider implements ConfigurableProvider { private static String info = "BouncyCastle Post-Quantum Security Provider v1.48"; public static String PROVIDER_NAME = "BCPQC"; public static final ProviderConfiguration CONFIGURATION = null; private static final Map keyInfoConverters = new HashMap(); /* * Configurable symmetric ciphers */ private static final String ALGORITHM_PACKAGE = "org.bouncycastle.pqc.jcajce.provider."; private static final String[] ALGORITHMS = { "Rainbow", "McEliece" }; /** * Construct a new provider. This should only be required when * using runtime registration of the provider using the * Security.addProvider() mechanism. */ public BouncyCastlePQCProvider() { super(PROVIDER_NAME, 1.48, info); AccessController.doPrivileged(new PrivilegedAction() { public Object run() { setup(); return null; } }); } private void setup() { loadAlgorithms(ALGORITHM_PACKAGE, ALGORITHMS); } private void loadAlgorithms(String packageName, String[] names) { for (int i = 0; i != names.length; i++) { Class clazz = null; try { ClassLoader loader = this.getClass().getClassLoader(); if (loader != null) { clazz = loader.loadClass(packageName + names[i] + "$Mappings"); } else { clazz = Class.forName(packageName + names[i] + "$Mappings"); } } catch (ClassNotFoundException e) { // ignore } if (clazz != null) { try { ((AlgorithmProvider)clazz.newInstance()).configure(this); } catch (Exception e) { // this should never ever happen!! throw new InternalError("cannot create instance of " + packageName + names[i] + "$Mappings : " + e); } } } } public void setParameter(String parameterName, Object parameter) { synchronized (CONFIGURATION) { //((BouncyCastleProviderConfiguration)CONFIGURATION).setParameter(parameterName, parameter); } } public boolean hasAlgorithm(String type, String name) { return containsKey(type + "." + name) || containsKey("Alg.Alias." + type + "." + name); } public void addAlgorithm(String key, String value) { if (containsKey(key)) { throw new IllegalStateException("duplicate provider key (" + key + ") found"); } put(key, value); } public void addKeyInfoConverter(ASN1ObjectIdentifier oid, AsymmetricKeyInfoConverter keyInfoConverter) { keyInfoConverters.put(oid, keyInfoConverter); } public static PublicKey getPublicKey(SubjectPublicKeyInfo publicKeyInfo) throws IOException { AsymmetricKeyInfoConverter converter = (AsymmetricKeyInfoConverter)keyInfoConverters.get(publicKeyInfo.getAlgorithm().getAlgorithm()); if (converter == null) { return null; } return converter.generatePublic(publicKeyInfo); } public static PrivateKey getPrivateKey(PrivateKeyInfo privateKeyInfo) throws IOException { AsymmetricKeyInfoConverter converter = (AsymmetricKeyInfoConverter)keyInfoConverters.get(privateKeyInfo.getPrivateKeyAlgorithm().getAlgorithm()); if (converter == null) { return null; } return converter.generatePrivate(privateKeyInfo); } } bouncycastle-1.49.orig/src/org/bouncycastle/pqc/jcajce/provider/util/0000755000175000017500000000000012152033551025310 5ustar ebourgebourgbouncycastle-1.49.orig/src/org/bouncycastle/pqc/jcajce/provider/util/AsymmetricBlockCipher.java0000644000175000017500000004543612045607550032421 0ustar ebourgebourgpackage org.bouncycastle.pqc.jcajce.provider.util; import java.io.ByteArrayOutputStream; import java.security.InvalidAlgorithmParameterException; import java.security.InvalidKeyException; import java.security.InvalidParameterException; import java.security.Key; import java.security.SecureRandom; import java.security.spec.AlgorithmParameterSpec; import javax.crypto.BadPaddingException; import javax.crypto.IllegalBlockSizeException; import javax.crypto.ShortBufferException; /** * The AsymmetricBlockCipher class extends CipherSpiExt. * NOTE: Some Ciphers are using Padding. OneAndZeroesPadding is used as default * padding. However padding can still be specified, but mode is not supported; * if you try to instantiate the cipher with something else than "NONE" as mode * NoSuchAlgorithmException is thrown. */ public abstract class AsymmetricBlockCipher extends CipherSpiExt { /** * ParameterSpec used with this cipher */ protected AlgorithmParameterSpec paramSpec; /** * Internal buffer */ protected ByteArrayOutputStream buf; /** * The maximum number of bytes the cipher can decrypt. */ protected int maxPlainTextSize; /** * The maximum number of bytes the cipher can encrypt. */ protected int cipherTextSize; /** * The AsymmetricBlockCipher() constructor */ public AsymmetricBlockCipher() { buf = new ByteArrayOutputStream(); } /** * Return the block size (in bytes). Note: although the ciphers extending * this class are not block ciphers, the method was adopted to return the * maximal plaintext and ciphertext sizes for non hybrid ciphers. If the * cipher is hybrid, it returns 0. * * @return if the cipher is not a hybrid one the max plain/cipher text size * is returned, otherwise 0 is returned */ public final int getBlockSize() { return opMode == ENCRYPT_MODE ? maxPlainTextSize : cipherTextSize; } /** * @return null since no initialization vector is used. */ public final byte[] getIV() { return null; } /** * Return the length in bytes that an output buffer would need to be in * order to hold the result of the next update or doFinal operation, given * the input length inLen (in bytes). This call takes into * account any unprocessed (buffered) data from a previous update call, and * padding. The actual output length of the next update() or doFinal() call * may be smaller than the length returned by this method. *

    * If the input length plus the length of the buffered data exceeds the * maximum length, 0 is returned. * * @param inLen the length of the input * @return the length of the ciphertext or 0 if the input is too * long. */ public final int getOutputSize(int inLen) { int totalLen = inLen + buf.size(); int maxLen = getBlockSize(); if (totalLen > maxLen) { // the length of the input exceeds the maximal supported length return 0; } return maxLen; } /** *

    * Returns the parameters used with this cipher. *

    * The returned parameters may be the same that were used to initialize this * cipher, or may contain the default set of parameters or a set of randomly * generated parameters used by the underlying cipher implementation * (provided that the underlying cipher implementation uses a default set of * parameters or creates new parameters if it needs parameters but was not * initialized with any). *

    * * @return the parameters used with this cipher, or null if this cipher does * not use any parameters. */ public final AlgorithmParameterSpec getParameters() { return paramSpec; } /** * Initializes the cipher for encryption by forwarding it to * initEncrypt(Key, FlexiSecureRandom). *

    *

    * If this cipher requires any algorithm parameters that cannot be derived * from the given key, the underlying cipher implementation is supposed to * generate the required parameters itself (using provider-specific default * or random values) if it is being initialized for encryption, and raise an * InvalidKeyException if it is being initialized for decryption. The * generated parameters can be retrieved using engineGetParameters or * engineGetIV (if the parameter is an IV). * * @param key the encryption or decryption key. * @throws InvalidKeyException if the given key is inappropriate for initializing this * cipher. */ public final void initEncrypt(Key key) throws InvalidKeyException { try { initEncrypt(key, null, new SecureRandom()); } catch (InvalidAlgorithmParameterException e) { throw new InvalidParameterException( "This cipher needs algorithm parameters for initialization (cannot be null)."); } } /** * Initialize this cipher for encryption by forwarding it to * initEncrypt(Key, FlexiSecureRandom, AlgorithmParameterSpec). *

    * If this cipher requires any algorithm parameters that cannot be derived * from the given key, the underlying cipher implementation is supposed to * generate the required parameters itself (using provider-specific default * or random values) if it is being initialized for encryption, and raise an * InvalidKeyException if it is being initialized for decryption. The * generated parameters can be retrieved using engineGetParameters or * engineGetIV (if the parameter is an IV). * * @param key the encryption or decryption key. * @param random the source of randomness. * @throws InvalidKeyException if the given key is inappropriate for initializing this * cipher. */ public final void initEncrypt(Key key, SecureRandom random) throws InvalidKeyException { try { initEncrypt(key, null, random); } catch (InvalidAlgorithmParameterException iape) { throw new InvalidParameterException( "This cipher needs algorithm parameters for initialization (cannot be null)."); } } /** * Initializes the cipher for encryption by forwarding it to * initEncrypt(Key, FlexiSecureRandom, AlgorithmParameterSpec). * * @param key the encryption or decryption key. * @param params the algorithm parameters. * @throws InvalidKeyException if the given key is inappropriate for initializing this * cipher. * @throws InvalidAlgorithmParameterException if the given algortihm parameters are inappropriate for * this cipher, or if this cipher is being initialized for * decryption and requires algorithm parameters and params * is null. */ public final void initEncrypt(Key key, AlgorithmParameterSpec params) throws InvalidKeyException, InvalidAlgorithmParameterException { initEncrypt(key, params, new SecureRandom()); } /** * This method initializes the AsymmetricBlockCipher with a certain key for * data encryption. *

    * If this cipher (including its underlying feedback or padding scheme) * requires any random bytes (e.g., for parameter generation), it will get * them from random. *

    * Note that when a Cipher object is initialized, it loses all * previously-acquired state. In other words, initializing a Cipher is * equivalent to creating a new instance of that Cipher and initializing it *

    * * @param key the key which has to be used to encrypt data. * @param secureRandom the source of randomness. * @param params the algorithm parameters. * @throws InvalidKeyException if the given key is inappropriate for initializing this * cipher * @throws InvalidAlgorithmParameterException if the given algorithm parameters are inappropriate for * this cipher, or if this cipher is being initialized for * decryption and requires algorithm parameters and params * is null. */ public final void initEncrypt(Key key, AlgorithmParameterSpec params, SecureRandom secureRandom) throws InvalidKeyException, InvalidAlgorithmParameterException { opMode = ENCRYPT_MODE; initCipherEncrypt(key, params, secureRandom); } /** * Initialize the cipher for decryption by forwarding it to * {@link #initDecrypt(Key, AlgorithmParameterSpec)}. *

    * If this cipher requires any algorithm parameters that cannot be derived * from the given key, the underlying cipher implementation is supposed to * generate the required parameters itself (using provider-specific default * or random values) if it is being initialized for encryption, and raise an * InvalidKeyException if it is being initialized for decryption. The * generated parameters can be retrieved using engineGetParameters or * engineGetIV (if the parameter is an IV). * * @param key the encryption or decryption key. * @throws InvalidKeyException if the given key is inappropriate for initializing this * cipher. */ public final void initDecrypt(Key key) throws InvalidKeyException { try { initDecrypt(key, null); } catch (InvalidAlgorithmParameterException iape) { throw new InvalidParameterException( "This cipher needs algorithm parameters for initialization (cannot be null)."); } } /** * This method initializes the AsymmetricBlockCipher with a certain key for * data decryption. *

    * If this cipher (including its underlying feedback or padding scheme) * requires any random bytes (e.g., for parameter generation), it will get * them from random. *

    * Note that when a Cipher object is initialized, it loses all * previously-acquired state. In other words, initializing a Cipher is * equivalent to creating a new instance of that Cipher and initializing it *

    * * @param key the key which has to be used to decrypt data. * @param params the algorithm parameters. * @throws InvalidKeyException if the given key is inappropriate for initializing this * cipher * @throws InvalidAlgorithmParameterException if the given algorithm parameters are inappropriate for * this cipher, or if this cipher is being initialized for * decryption and requires algorithm parameters and params * is null. */ public final void initDecrypt(Key key, AlgorithmParameterSpec params) throws InvalidKeyException, InvalidAlgorithmParameterException { opMode = DECRYPT_MODE; initCipherDecrypt(key, params); } /** * Continue a multiple-part encryption or decryption operation. This method * just writes the input into an internal buffer. * * @param input byte array containing the next part of the input * @param inOff index in the array where the input starts * @param inLen length of the input * @return a new buffer with the result (always empty) */ public final byte[] update(byte[] input, int inOff, int inLen) { if (inLen != 0) { buf.write(input, inOff, inLen); } return new byte[0]; } /** * Continue a multiple-part encryption or decryption operation (depending on * how this cipher was initialized), processing another data part. * * @param input the input buffer * @param inOff the offset where the input starts * @param inLen the input length * @param output the output buffer * @param outOff the offset where the result is stored * @return the length of the output (always 0) */ public final int update(byte[] input, int inOff, int inLen, byte[] output, int outOff) { update(input, inOff, inLen); return 0; } /** * Finish a multiple-part encryption or decryption operation (depending on * how this cipher was initialized). * * @param input the input buffer * @param inOff the offset where the input starts * @param inLen the input length * @return a new buffer with the result * @throws IllegalBlockSizeException if the plaintext or ciphertext size is too large. * @throws BadPaddingException if the ciphertext is invalid. */ public final byte[] doFinal(byte[] input, int inOff, int inLen) throws IllegalBlockSizeException, BadPaddingException { checkLength(inLen); update(input, inOff, inLen); byte[] mBytes = buf.toByteArray(); buf.reset(); switch (opMode) { case ENCRYPT_MODE: return messageEncrypt(mBytes); case DECRYPT_MODE: return messageDecrypt(mBytes); default: return null; } } /** * Finish a multiple-part encryption or decryption operation (depending on * how this cipher was initialized). * * @param input the input buffer * @param inOff the offset where the input starts * @param inLen the input length * @param output the buffer for the result * @param outOff the offset where the result is stored * @return the output length * @throws ShortBufferException if the output buffer is too small to hold the result. * @throws IllegalBlockSizeException if the plaintext or ciphertext size is too large. * @throws BadPaddingException if the ciphertext is invalid. */ public final int doFinal(byte[] input, int inOff, int inLen, byte[] output, int outOff) throws ShortBufferException, IllegalBlockSizeException, BadPaddingException { if (output.length < getOutputSize(inLen)) { throw new ShortBufferException("Output buffer too short."); } byte[] out = doFinal(input, inOff, inLen); System.arraycopy(out, 0, output, outOff, out.length); return out.length; } /** * Since asymmetric block ciphers do not support modes, this method does * nothing. * * @param modeName the cipher mode (unused) */ protected final void setMode(String modeName) { // empty } /** * Since asymmetric block ciphers do not support padding, this method does * nothing. * * @param paddingName the name of the padding scheme (not used) */ protected final void setPadding(String paddingName) { // empty } /** * Check if the message length plus the length of the input length can be * en/decrypted. This method uses the specific values * {@link #maxPlainTextSize} and {@link #cipherTextSize} which are set by * the implementations. If the input length plus the length of the internal * buffer is greater than {@link #maxPlainTextSize} for encryption or not * equal to {@link #cipherTextSize} for decryption, an * {@link IllegalBlockSizeException} will be thrown. * * @param inLen length of the input to check * @throws IllegalBlockSizeException if the input length is invalid. */ protected void checkLength(int inLen) throws IllegalBlockSizeException { int inLength = inLen + buf.size(); if (opMode == ENCRYPT_MODE) { if (inLength > maxPlainTextSize) { throw new IllegalBlockSizeException( "The length of the plaintext (" + inLength + " bytes) is not supported by " + "the cipher (max. " + maxPlainTextSize + " bytes)."); } } else if (opMode == DECRYPT_MODE) { if (inLength != cipherTextSize) { throw new IllegalBlockSizeException( "Illegal ciphertext length (expected " + cipherTextSize + " bytes, was " + inLength + " bytes)."); } } } /** * Initialize the AsymmetricBlockCipher with a certain key for data * encryption. * * @param key the key which has to be used to encrypt data * @param params the algorithm parameters * @param sr the source of randomness * @throws InvalidKeyException if the given key is inappropriate for initializing this * cipher. * @throws InvalidAlgorithmParameterException if the given parameters are inappropriate for * initializing this cipher. */ protected abstract void initCipherEncrypt(Key key, AlgorithmParameterSpec params, SecureRandom sr) throws InvalidKeyException, InvalidAlgorithmParameterException; /** * Initialize the AsymmetricBlockCipher with a certain key for data * encryption. * * @param key the key which has to be used to decrypt data * @param params the algorithm parameters * @throws InvalidKeyException if the given key is inappropriate for initializing this * cipher * @throws InvalidAlgorithmParameterException if the given parameters are inappropriate for * initializing this cipher. */ protected abstract void initCipherDecrypt(Key key, AlgorithmParameterSpec params) throws InvalidKeyException, InvalidAlgorithmParameterException; /** * Encrypt the message stored in input. The method should also perform an * additional length check. * * @param input the message to be encrypted (usually the message length is * less than or equal to maxPlainTextSize) * @return the encrypted message (it has length equal to maxCipherTextSize_) * @throws IllegalBlockSizeException if the input is inappropriate for this cipher. * @throws BadPaddingException if the input format is invalid. */ protected abstract byte[] messageEncrypt(byte[] input) throws IllegalBlockSizeException, BadPaddingException; /** * Decrypt the ciphertext stored in input. The method should also perform an * additional length check. * * @param input the ciphertext to be decrypted (the ciphertext length is * less than or equal to maxCipherTextSize) * @return the decrypted message * @throws IllegalBlockSizeException if the input is inappropriate for this cipher. * @throws BadPaddingException if the input format is invalid. */ protected abstract byte[] messageDecrypt(byte[] input) throws IllegalBlockSizeException, BadPaddingException; } bouncycastle-1.49.orig/src/org/bouncycastle/pqc/jcajce/provider/util/CipherSpiExt.java0000644000175000017500000006342512045603262030537 0ustar ebourgebourgpackage org.bouncycastle.pqc.jcajce.provider.util; import java.security.InvalidAlgorithmParameterException; import java.security.InvalidKeyException; import java.security.InvalidParameterException; import java.security.Key; import java.security.NoSuchAlgorithmException; import java.security.SecureRandom; import java.security.spec.AlgorithmParameterSpec; import javax.crypto.BadPaddingException; import javax.crypto.CipherSpi; import javax.crypto.IllegalBlockSizeException; import javax.crypto.NoSuchPaddingException; import javax.crypto.ShortBufferException; /** * The CipherSpiExt class extends CipherSpi. */ public abstract class CipherSpiExt extends CipherSpi { /** * Constant specifying encrypt mode. */ public static final int ENCRYPT_MODE = javax.crypto.Cipher.ENCRYPT_MODE; /** * Constant specifying decrypt mode. */ public static final int DECRYPT_MODE = javax.crypto.Cipher.DECRYPT_MODE; /** * The operation mode for this cipher ({@link #ENCRYPT_MODE} or * {@link #DECRYPT_MODE}). */ protected int opMode; // **************************************************** // JCA adapter methods // **************************************************** /** * Initialize this cipher object with a proper key and some random seed. * Before a cipher object is ready for data processing, it has to be * initialized according to the desired cryptographic operation, which is * specified by the opMode parameter. *

    * If this cipher (including its underlying mode or padding scheme) requires * any random bytes, it will obtain them from random. *

    * Note: If the mode needs an initialization vector, a blank array is used * in this case. * * @param opMode the operation mode ({@link #ENCRYPT_MODE} or * {@link #DECRYPT_MODE}) * @param key the key * @param random the random seed * @throws java.security.InvalidKeyException if the key is inappropriate for initializing this cipher. */ protected final void engineInit(int opMode, java.security.Key key, java.security.SecureRandom random) throws java.security.InvalidKeyException { try { engineInit(opMode, key, (java.security.spec.AlgorithmParameterSpec)null, random); } catch (java.security.InvalidAlgorithmParameterException e) { throw new InvalidParameterException(e.getMessage()); } } /** * Initialize this cipher with a key, a set of algorithm parameters, and a * source of randomness. The cipher is initialized for encryption or * decryption, depending on the value of opMode. *

    * If this cipher (including its underlying mode or padding scheme) requires * any random bytes, it will obtain them from random. Note that * when a {@link BlockCipher} object is initialized, it loses all * previously-acquired state. In other words, initializing a Cipher is * equivalent to creating a new instance of that Cipher and initializing it. *

    * Note: If the mode needs an initialization vector, a try to retrieve it * from the AlgorithmParametersSpec is made. * * @param opMode the operation mode ({@link #ENCRYPT_MODE} or * {@link #DECRYPT_MODE}) * @param key the key * @param algParams the algorithm parameters * @param random the random seed * @throws java.security.InvalidKeyException if the key is inappropriate for initializing this block * cipher. * @throws java.security.InvalidAlgorithmParameterException if the parameters are inappropriate for initializing this * block cipher. */ protected final void engineInit(int opMode, java.security.Key key, java.security.AlgorithmParameters algParams, java.security.SecureRandom random) throws java.security.InvalidKeyException, java.security.InvalidAlgorithmParameterException { // if algParams are not specified, initialize without them if (algParams == null) { engineInit(opMode, key, random); return; } AlgorithmParameterSpec paramSpec = null; // XXX getting AlgorithmParameterSpec from AlgorithmParameters engineInit(opMode, key, paramSpec, random); } /** * Initialize this cipher with a key, a set of algorithm parameters, and a * source of randomness. The cipher is initialized for one of the following * four operations: encryption, decryption, key wrapping or key unwrapping, * depending on the value of opMode. If this cipher (including its * underlying feedback or padding scheme) requires any random bytes (e.g., * for parameter generation), it will get them from random. Note that when a * Cipher object is initialized, it loses all previously-acquired state. In * other words, initializing a Cipher is equivalent to creating a new * instance of that Cipher and initializing it. * * @param opMode the operation mode ({@link #ENCRYPT_MODE} or * {@link #DECRYPT_MODE}) * @param key the encryption key * @param params the algorithm parameters * @param javaRand the source of randomness * @throws java.security.InvalidKeyException if the given key is inappropriate for initializing this * cipher * @throws java.security.InvalidAlgorithmParameterException if the given algorithm parameters are inappropriate for * this cipher, or if this cipher is being initialized for * decryption and requires algorithm parameters and the * parameters are null. */ protected void engineInit(int opMode, java.security.Key key, java.security.spec.AlgorithmParameterSpec params, java.security.SecureRandom javaRand) throws java.security.InvalidKeyException, java.security.InvalidAlgorithmParameterException { if ((params != null) && !(params instanceof AlgorithmParameterSpec)) { throw new java.security.InvalidAlgorithmParameterException(); } if ((key == null) || !(key instanceof Key)) { throw new java.security.InvalidKeyException(); } this.opMode = opMode; if (opMode == ENCRYPT_MODE) { SecureRandom flexiRand = javaRand; initEncrypt((Key)key, (AlgorithmParameterSpec)params, flexiRand); } else if (opMode == DECRYPT_MODE) { initDecrypt((Key)key, (AlgorithmParameterSpec)params); } } /** * Return the result of the last step of a multi-step en-/decryption * operation or the result of a single-step en-/decryption operation by * processing the given input data and any remaining buffered data. The data * to be processed is given in an input byte array. Beginning at * inputOffset, only the first inputLen bytes are en-/decrypted, including * any buffered bytes of a previous update operation. If necessary, padding * is performed. The result is returned as a output byte array. * * @param input the byte array holding the data to be processed * @param inOff the offset indicating the start position within the input * byte array * @param inLen the number of bytes to be processed * @return the byte array containing the en-/decrypted data * @throws javax.crypto.IllegalBlockSizeException if the ciphertext length is not a multiple of the * blocklength. * @throws javax.crypto.BadPaddingException if unpadding is not possible. */ protected final byte[] engineDoFinal(byte[] input, int inOff, int inLen) throws javax.crypto.IllegalBlockSizeException, javax.crypto.BadPaddingException { return doFinal(input, inOff, inLen); } /** * Perform the last step of a multi-step en-/decryption operation or a * single-step en-/decryption operation by processing the given input data * and any remaining buffered data. The data to be processed is given in an * input byte array. Beginning at inputOffset, only the first inputLen bytes * are en-/decrypted, including any buffered bytes of a previous update * operation. If necessary, padding is performed. The result is stored in * the given output byte array, beginning at outputOffset. The number of * bytes stored in this byte array are returned. * * @param input the byte array holding the data to be processed * @param inOff the offset indicating the start position within the input * byte array * @param inLen the number of bytes to be processed * @param output the byte array for holding the result * @param outOff the offset indicating the start position within the output * byte array to which the en/decrypted data is written * @return the number of bytes stored in the output byte array * @throws javax.crypto.ShortBufferException if the output buffer is too short to hold the output. * @throws javax.crypto.IllegalBlockSizeException if the ciphertext length is not a multiple of the * blocklength. * @throws javax.crypto.BadPaddingException if unpadding is not possible. */ protected final int engineDoFinal(byte[] input, int inOff, int inLen, byte[] output, int outOff) throws javax.crypto.ShortBufferException, javax.crypto.IllegalBlockSizeException, javax.crypto.BadPaddingException { return doFinal(input, inOff, inLen, output, outOff); } /** * @return the block size (in bytes), or 0 if the underlying algorithm is * not a block cipher */ protected final int engineGetBlockSize() { return getBlockSize(); } /** * Return the key size of the given key object in bits. * * @param key the key object * @return the key size in bits of the given key object * @throws java.security.InvalidKeyException if key is invalid. */ protected final int engineGetKeySize(java.security.Key key) throws java.security.InvalidKeyException { if (!(key instanceof Key)) { throw new java.security.InvalidKeyException("Unsupported key."); } return getKeySize((Key)key); } /** * Return the initialization vector. This is useful in the context of * password-based encryption or decryption, where the IV is derived from a * user-provided passphrase. * * @return the initialization vector in a new buffer, or null if * the underlying algorithm does not use an IV, or if the IV has not * yet been set. */ protected final byte[] engineGetIV() { return getIV(); } /** * Return the length in bytes that an output buffer would need to be in * order to hold the result of the next update or doFinal operation, given * the input length inputLen (in bytes). *

    * This call takes into account any unprocessed (buffered) data from a * previous update call, and padding. *

    * The actual output length of the next update or doFinal call may be * smaller than the length returned by this method. * * @param inLen the input length (in bytes) * @return the required output buffer size (in bytes) */ protected final int engineGetOutputSize(int inLen) { return getOutputSize(inLen); } /** * Returns the parameters used with this cipher. *

    * The returned parameters may be the same that were used to initialize this * cipher, or may contain the default set of parameters or a set of randomly * generated parameters used by the underlying cipher implementation * (provided that the underlying cipher implementation uses a default set of * parameters or creates new parameters if it needs parameters but was not * initialized with any). * * @return the parameters used with this cipher, or null if this cipher does * not use any parameters. */ protected final java.security.AlgorithmParameters engineGetParameters() { // TODO return null; } /** * Set the mode of this cipher. * * @param modeName the cipher mode * @throws java.security.NoSuchAlgorithmException if neither the mode with the given name nor the default * mode can be found */ protected final void engineSetMode(String modeName) throws java.security.NoSuchAlgorithmException { setMode(modeName); } /** * Set the padding scheme of this cipher. * * @param paddingName the padding scheme * @throws javax.crypto.NoSuchPaddingException if the requested padding scheme cannot be found. */ protected final void engineSetPadding(String paddingName) throws javax.crypto.NoSuchPaddingException { setPadding(paddingName); } /** * Return the result of the next step of a multi-step en-/decryption * operation. The data to be processed is given in an input byte array. * Beginning at inputOffset, only the first inputLen bytes are * en-/decrypted. The result is returned as a byte array. * * @param input the byte array holding the data to be processed * @param inOff the offset indicating the start position within the input * byte array * @param inLen the number of bytes to be processed * @return the byte array containing the en-/decrypted data */ protected final byte[] engineUpdate(byte[] input, int inOff, int inLen) { return update(input, inOff, inLen); } /** * Perform the next step of a multi-step en-/decryption operation. The data * to be processed is given in an input byte array. Beginning at * inputOffset, only the first inputLen bytes are en-/decrypted. The result * is stored in the given output byte array, beginning at outputOffset. The * number of bytes stored in this output byte array are returned. * * @param input the byte array holding the data to be processed * @param inOff the offset indicating the start position within the input * byte array * @param inLen the number of bytes to be processed * @param output the byte array for holding the result * @param outOff the offset indicating the start position within the output * byte array to which the en-/decrypted data is written * @return the number of bytes that are stored in the output byte array * @throws javax.crypto.ShortBufferException if the output buffer is too short to hold the output. */ protected final int engineUpdate(final byte[] input, final int inOff, final int inLen, byte[] output, final int outOff) throws javax.crypto.ShortBufferException { return update(input, inOff, inLen, output, outOff); } /** * Initialize this cipher with a key, a set of algorithm parameters, and a * source of randomness for encryption. *

    * If this cipher requires any algorithm parameters and paramSpec is null, * the underlying cipher implementation is supposed to generate the required * parameters itself (using provider-specific default or random values) if * it is being initialized for encryption, and raise an * InvalidAlgorithmParameterException if it is being initialized for * decryption. The generated parameters can be retrieved using * engineGetParameters or engineGetIV (if the parameter is an IV). *

    * If this cipher (including its underlying feedback or padding scheme) * requires any random bytes (e.g., for parameter generation), it will get * them from random. *

    * Note that when a {@link BlockCipher} object is initialized, it loses all * previously-acquired state. In other words, initializing a Cipher is * equivalent to creating a new instance of that Cipher and initializing it. * * @param key the encryption key * @param cipherParams the cipher parameters * @param random the source of randomness * @throws InvalidKeyException if the given key is inappropriate for initializing this * block cipher. * @throws InvalidAlgorithmParameterException if the parameters are inappropriate for initializing this * block cipher. */ public abstract void initEncrypt(Key key, AlgorithmParameterSpec cipherParams, SecureRandom random) throws InvalidKeyException, InvalidAlgorithmParameterException; /** * Initialize this cipher with a key, a set of algorithm parameters, and a * source of randomness for decryption. *

    * If this cipher requires any algorithm parameters and paramSpec is null, * the underlying cipher implementation is supposed to generate the required * parameters itself (using provider-specific default or random values) if * it is being initialized for encryption, and throw an * {@link InvalidAlgorithmParameterException} if it is being initialized for * decryption. The generated parameters can be retrieved using * engineGetParameters or engineGetIV (if the parameter is an IV). *

    * If this cipher (including its underlying feedback or padding scheme) * requires any random bytes (e.g., for parameter generation), it will get * them from random. *

    * Note that when a {@link BlockCipher} object is initialized, it loses all * previously-acquired state. In other words, initializing a Cipher is * equivalent to creating a new instance of that Cipher and initializing it. * * @param key the encryption key * @param cipherParams the cipher parameters * @throws InvalidKeyException if the given key is inappropriate for initializing this * block cipher. * @throws InvalidAlgorithmParameterException if the parameters are inappropriate for initializing this * block cipher. */ public abstract void initDecrypt(Key key, AlgorithmParameterSpec cipherParams) throws InvalidKeyException, InvalidAlgorithmParameterException; /** * @return the name of this cipher */ public abstract String getName(); /** * @return the block size (in bytes), or 0 if the underlying algorithm is * not a block cipher */ public abstract int getBlockSize(); /** * Returns the length in bytes that an output buffer would need to be in * order to hold the result of the next update or doFinal operation, given * the input length inputLen (in bytes). *

    * This call takes into account any unprocessed (buffered) data from a * previous update call, and padding. *

    * The actual output length of the next update or doFinal call may be * smaller than the length returned by this method. * * @param inputLen the input length (in bytes) * @return the required output buffer size (in bytes) */ public abstract int getOutputSize(int inputLen); /** * Return the key size of the given key object in bits. * * @param key the key object * @return the key size in bits of the given key object * @throws InvalidKeyException if key is invalid. */ public abstract int getKeySize(Key key) throws InvalidKeyException; /** * Returns the parameters used with this cipher. *

    * The returned parameters may be the same that were used to initialize this * cipher, or may contain the default set of parameters or a set of randomly * generated parameters used by the underlying cipher implementation * (provided that the underlying cipher implementation uses a default set of * parameters or creates new parameters if it needs parameters but was not * initialized with any). * * @return the parameters used with this cipher, or null if this cipher does * not use any parameters. */ public abstract AlgorithmParameterSpec getParameters(); /** * Return the initialization vector. This is useful in the context of * password-based encryption or decryption, where the IV is derived from a * user-provided passphrase. * * @return the initialization vector in a new buffer, or null if * the underlying algorithm does not use an IV, or if the IV has not * yet been set. */ public abstract byte[] getIV(); /** * Set the mode of this cipher. * * @param mode the cipher mode * @throws NoSuchModeException if the requested mode cannot be found. */ protected abstract void setMode(String mode) throws NoSuchAlgorithmException; /** * Set the padding mechanism of this cipher. * * @param padding the padding mechanism * @throws NoSuchPaddingException if the requested padding scheme cannot be found. */ protected abstract void setPadding(String padding) throws NoSuchPaddingException; /** * Continue a multiple-part encryption or decryption operation (depending on * how this cipher was initialized), processing another data part. * * @param input the input buffer * @return a new buffer with the result (maybe an empty byte array) */ public final byte[] update(byte[] input) { return update(input, 0, input.length); } /** * Continue a multiple-part encryption or decryption operation (depending on * how this cipher was initialized), processing another data part. * * @param input the input buffer * @param inOff the offset where the input starts * @param inLen the input length * @return a new buffer with the result (maybe an empty byte array) */ public abstract byte[] update(byte[] input, int inOff, int inLen); /** * Continue a multiple-part encryption or decryption operation (depending on * how this cipher was initialized), processing another data part. * * @param input the input buffer * @param inOff the offset where the input starts * @param inLen the input length * @param output the output buffer * @param outOff the offset where the result is stored * @return the length of the output * @throws ShortBufferException if the output buffer is too small to hold the result. */ public abstract int update(byte[] input, int inOff, int inLen, byte[] output, int outOff) throws ShortBufferException; /** * Finish a multiple-part encryption or decryption operation (depending on * how this cipher was initialized). * * @return a new buffer with the result * @throws IllegalBlockSizeException if this cipher is a block cipher and the total input * length is not a multiple of the block size (for * encryption when no padding is used or for decryption). * @throws BadPaddingException if this cipher is a block cipher and unpadding fails. */ public final byte[] doFinal() throws IllegalBlockSizeException, BadPaddingException { return doFinal(null, 0, 0); } /** * Finish a multiple-part encryption or decryption operation (depending on * how this cipher was initialized). * * @param input the input buffer * @return a new buffer with the result * @throws IllegalBlockSizeException if this cipher is a block cipher and the total input * length is not a multiple of the block size (for * encryption when no padding is used or for decryption). * @throws BadPaddingException if this cipher is a block cipher and unpadding fails. */ public final byte[] doFinal(byte[] input) throws IllegalBlockSizeException, BadPaddingException { return doFinal(input, 0, input.length); } /** * Finish a multiple-part encryption or decryption operation (depending on * how this cipher was initialized). * * @param input the input buffer * @param inOff the offset where the input starts * @param inLen the input length * @return a new buffer with the result * @throws IllegalBlockSizeException if this cipher is a block cipher and the total input * length is not a multiple of the block size (for * encryption when no padding is used or for decryption). * @throws BadPaddingException if this cipher is a block cipher and unpadding fails. */ public abstract byte[] doFinal(byte[] input, int inOff, int inLen) throws IllegalBlockSizeException, BadPaddingException; /** * Finish a multiple-part encryption or decryption operation (depending on * how this cipher was initialized). * * @param input the input buffer * @param inOff the offset where the input starts * @param inLen the input length * @param output the buffer for the result * @param outOff the offset where the result is stored * @return the output length * @throws ShortBufferException if the output buffer is too small to hold the result. * @throws IllegalBlockSizeException if this cipher is a block cipher and the total input * length is not a multiple of the block size (for * encryption when no padding is used or for decryption). * @throws BadPaddingException if this cipher is a block cipher and unpadding fails. */ public abstract int doFinal(byte[] input, int inOff, int inLen, byte[] output, int outOff) throws ShortBufferException, IllegalBlockSizeException, BadPaddingException; } bouncycastle-1.49.orig/src/org/bouncycastle/pqc/jcajce/provider/util/AsymmetricHybridCipher.java0000644000175000017500000003572212045603262032601 0ustar ebourgebourgpackage org.bouncycastle.pqc.jcajce.provider.util; import java.security.InvalidAlgorithmParameterException; import java.security.InvalidKeyException; import java.security.InvalidParameterException; import java.security.Key; import java.security.SecureRandom; import java.security.spec.AlgorithmParameterSpec; import javax.crypto.BadPaddingException; import javax.crypto.ShortBufferException; /** * The AsymmetricHybridCipher class extends CipherSpiExt. * NOTE: Some Ciphers are using Padding. OneAndZeroesPadding is used as default * padding. However padding can still be specified, but mode is not supported; * if you try to instantiate the cipher with something else than "NONE" as mode, * NoSuchAlgorithmException is thrown. */ public abstract class AsymmetricHybridCipher extends CipherSpiExt { /** * ParameterSpec used with this cipher */ protected AlgorithmParameterSpec paramSpec; /** * Since asymmetric hybrid ciphers do not support modes, this method does * nothing. * * @param modeName the cipher mode (unused) */ protected final void setMode(String modeName) { // empty } /** * Since asymmetric hybrid ciphers do not support padding, this method does * nothing. * * @param paddingName the name of the padding scheme (not used) */ protected final void setPadding(String paddingName) { // empty } /** * @return null since no initialization vector is used. */ public final byte[] getIV() { return null; } /** * @return 0 since the implementing algorithms are not block ciphers */ public final int getBlockSize() { return 0; } /** * Return the parameters used with this cipher. *

    * The returned parameters may be the same that were used to initialize this * cipher, or may contain the default set of parameters or a set of randomly * generated parameters used by the underlying cipher implementation * (provided that the underlying cipher implementation uses a default set of * parameters or creates new parameters if it needs parameters but was not * initialized with any). * * @return the parameters used with this cipher, or null if this * cipher does not use any parameters. */ public final AlgorithmParameterSpec getParameters() { return paramSpec; } /** * Return the length in bytes that an output buffer would need to be in * order to hold the result of the next update or doFinal operation, given * the input length inLen (in bytes). This call takes into * account any unprocessed (buffered) data from a previous update call, and * padding. The actual output length of the next update() or doFinal() call * may be smaller than the length returned by this method. * * @param inLen the length of the input * @return the length of the output of the next update() or * doFinal() call */ public final int getOutputSize(int inLen) { return opMode == ENCRYPT_MODE ? encryptOutputSize(inLen) : decryptOutputSize(inLen); } /** * Initialize the cipher for encryption by forwarding it to * {@link #initEncrypt(Key, AlgorithmParameterSpec, SecureRandom)}. *

    * If this cipher requires any algorithm parameters that cannot be derived * from the given key, the underlying cipher implementation is supposed to * generate the required parameters itself (using provider-specific default * or random values) if it is being initialized for encryption, and raise an * InvalidKeyException if it is being initialized for decryption. The * generated parameters can be retrieved using {@link #getParameters()}. * * @param key the encryption key * @throws InvalidKeyException if the given key is inappropriate for initializing this * cipher. * @throws InvalidParameterException if this cipher needs algorithm parameters for * initialization and cannot generate parameters itself. */ public final void initEncrypt(Key key) throws InvalidKeyException { try { initEncrypt(key, null, new SecureRandom()); } catch (InvalidAlgorithmParameterException e) { throw new InvalidParameterException( "This cipher needs algorithm parameters for initialization (cannot be null)."); } } /** * Initialize this cipher for encryption by forwarding it to * {@link #initEncrypt(Key, AlgorithmParameterSpec, SecureRandom)}. *

    * If this cipher requires any algorithm parameters that cannot be derived * from the given key, the underlying cipher implementation is supposed to * generate the required parameters itself (using provider-specific default * or random values) if it is being initialized for encryption, and raise an * InvalidKeyException if it is being initialized for decryption. The * generated parameters can be retrieved using {@link #getParameters()}. * * @param key the encryption key * @param random the source of randomness * @throws InvalidKeyException if the given key is inappropriate for initializing this * cipher. * @throws InvalidParameterException if this cipher needs algorithm parameters for * initialization and cannot generate parameters itself. */ public final void initEncrypt(Key key, SecureRandom random) throws InvalidKeyException { try { initEncrypt(key, null, random); } catch (InvalidAlgorithmParameterException iape) { throw new InvalidParameterException( "This cipher needs algorithm parameters for initialization (cannot be null)."); } } /** * Initialize the cipher for encryption by forwarding it to initEncrypt(Key, * FlexiSecureRandom, AlgorithmParameterSpec). * * @param key the encryption key * @param params the algorithm parameters * @throws InvalidKeyException if the given key is inappropriate for initializing this * cipher. * @throws InvalidAlgorithmParameterException if the given algorithm parameters are inappropriate for * this cipher, or if this cipher is initialized with * null parameters and cannot generate parameters * itself. */ public final void initEncrypt(Key key, AlgorithmParameterSpec params) throws InvalidKeyException, InvalidAlgorithmParameterException { initEncrypt(key, params, new SecureRandom()); } /** * Initialize the cipher with a certain key for data encryption. *

    * If this cipher requires any random bytes (e.g., for parameter * generation), it will get them from random. *

    * Note that when a Cipher object is initialized, it loses all * previously-acquired state. In other words, initializing a Cipher is * equivalent to creating a new instance of that Cipher and initializing it. * * @param key the encryption key * @param random the source of randomness * @param params the algorithm parameters * @throws InvalidKeyException if the given key is inappropriate for initializing this * cipher * @throws InvalidAlgorithmParameterException if the given algorithm parameters are inappropriate for * this cipher, or if this cipher is initialized with * null parameters and cannot generate parameters * itself. */ public final void initEncrypt(Key key, AlgorithmParameterSpec params, SecureRandom random) throws InvalidKeyException, InvalidAlgorithmParameterException { opMode = ENCRYPT_MODE; initCipherEncrypt(key, params, random); } /** * Initialize the cipher for decryption by forwarding it to initDecrypt(Key, * FlexiSecureRandom). *

    * If this cipher requires any algorithm parameters that cannot be derived * from the given key, the underlying cipher implementation is supposed to * generate the required parameters itself (using provider-specific default * or random values) if it is being initialized for encryption, and raise an * InvalidKeyException if it is being initialized for decryption. The * generated parameters can be retrieved using {@link #getParameters()}. * * @param key the decryption key * @throws InvalidKeyException if the given key is inappropriate for initializing this * cipher. */ public final void initDecrypt(Key key) throws InvalidKeyException { try { initDecrypt(key, null); } catch (InvalidAlgorithmParameterException iape) { throw new InvalidParameterException( "This cipher needs algorithm parameters for initialization (cannot be null)."); } } /** * Initialize the cipher with a certain key for data decryption. *

    * If this cipher requires any random bytes (e.g., for parameter * generation), it will get them from random. *

    * Note that when a Cipher object is initialized, it loses all * previously-acquired state. In other words, initializing a Cipher is * equivalent to creating a new instance of that Cipher and initializing it * * @param key the decryption key * @param params the algorithm parameters * @throws InvalidKeyException if the given key is inappropriate for initializing this * cipher * @throws InvalidAlgorithmParameterException if the given algorithm parameters are inappropriate for * this cipher, or if this cipher is initialized with * null parameters and cannot generate parameters * itself. */ public final void initDecrypt(Key key, AlgorithmParameterSpec params) throws InvalidKeyException, InvalidAlgorithmParameterException { opMode = DECRYPT_MODE; initCipherDecrypt(key, params); } /** * Continue a multiple-part encryption or decryption operation (depending on * how this cipher was initialized), processing another data part. * * @param input the input buffer * @param inOff the offset where the input starts * @param inLen the input length * @return a new buffer with the result (maybe an empty byte array) */ public abstract byte[] update(byte[] input, int inOff, int inLen); /** * Continue a multiple-part encryption or decryption operation (depending on * how this cipher was initialized), processing another data part. * * @param input the input buffer * @param inOff the offset where the input starts * @param inLen the input length * @param output the output buffer * @param outOff the offset where the result is stored * @return the length of the output * @throws ShortBufferException if the output buffer is too small to hold the result. */ public final int update(byte[] input, int inOff, int inLen, byte[] output, int outOff) throws ShortBufferException { if (output.length < getOutputSize(inLen)) { throw new ShortBufferException("output"); } byte[] out = update(input, inOff, inLen); System.arraycopy(out, 0, output, outOff, out.length); return out.length; } /** * Finish a multiple-part encryption or decryption operation (depending on * how this cipher was initialized). * * @param input the input buffer * @param inOff the offset where the input starts * @param inLen the input length * @return a new buffer with the result * @throws BadPaddingException if the ciphertext is invalid. */ public abstract byte[] doFinal(byte[] input, int inOff, int inLen) throws BadPaddingException; /** * Finish a multiple-part encryption or decryption operation (depending on * how this cipher was initialized). * * @param input the input buffer * @param inOff the offset where the input starts * @param inLen the input length * @param output the buffer for the result * @param outOff the offset where the result is stored * @return the output length * @throws ShortBufferException if the output buffer is too small to hold the result. * @throws BadPaddingException if the ciphertext is invalid. */ public final int doFinal(byte[] input, int inOff, int inLen, byte[] output, int outOff) throws ShortBufferException, BadPaddingException { if (output.length < getOutputSize(inLen)) { throw new ShortBufferException("Output buffer too short."); } byte[] out = doFinal(input, inOff, inLen); System.arraycopy(out, 0, output, outOff, out.length); return out.length; } /** * Compute the output size of an update() or doFinal() operation of a hybrid * asymmetric cipher in encryption mode when given input of the specified * length. * * @param inLen the length of the input * @return the output size */ protected abstract int encryptOutputSize(int inLen); /** * Compute the output size of an update() or doFinal() operation of a hybrid * asymmetric cipher in decryption mode when given input of the specified * length. * * @param inLen the length of the input * @return the output size */ protected abstract int decryptOutputSize(int inLen); /** * Initialize the AsymmetricHybridCipher with a certain key for data * encryption. * * @param key the key which has to be used to encrypt data * @param params the algorithm parameters * @param sr the source of randomness * @throws InvalidKeyException if the given key is inappropriate for initializing this * cipher. * @throws InvalidAlgorithmParameterException if the given parameters are inappropriate for * initializing this cipher. */ protected abstract void initCipherEncrypt(Key key, AlgorithmParameterSpec params, SecureRandom sr) throws InvalidKeyException, InvalidAlgorithmParameterException; /** * Initialize the AsymmetricHybridCipher with a certain key for data * encryption. * * @param key the key which has to be used to decrypt data * @param params the algorithm parameters * @throws InvalidKeyException if the given key is inappropriate for initializing this * cipher * @throws InvalidAlgorithmParameterException if the given parameters are inappropriate for * initializing this cipher. */ protected abstract void initCipherDecrypt(Key key, AlgorithmParameterSpec params) throws InvalidKeyException, InvalidAlgorithmParameterException; } bouncycastle-1.49.orig/src/org/bouncycastle/pqc/jcajce/provider/util/KeyUtil.java0000644000175000017500000000345111777160164027561 0ustar ebourgebourgpackage org.bouncycastle.pqc.jcajce.provider.util; import org.bouncycastle.asn1.ASN1Encodable; import org.bouncycastle.asn1.ASN1Encoding; import org.bouncycastle.asn1.pkcs.PrivateKeyInfo; import org.bouncycastle.asn1.x509.AlgorithmIdentifier; import org.bouncycastle.asn1.x509.SubjectPublicKeyInfo; public class KeyUtil { public static byte[] getEncodedSubjectPublicKeyInfo(AlgorithmIdentifier algId, ASN1Encodable keyData) { try { return getEncodedSubjectPublicKeyInfo(new SubjectPublicKeyInfo(algId, keyData)); } catch (Exception e) { return null; } } public static byte[] getEncodedSubjectPublicKeyInfo(AlgorithmIdentifier algId, byte[] keyData) { try { return getEncodedSubjectPublicKeyInfo(new SubjectPublicKeyInfo(algId, keyData)); } catch (Exception e) { return null; } } public static byte[] getEncodedSubjectPublicKeyInfo(SubjectPublicKeyInfo info) { try { return info.getEncoded(ASN1Encoding.DER); } catch (Exception e) { return null; } } public static byte[] getEncodedPrivateKeyInfo(AlgorithmIdentifier algId, ASN1Encodable privKey) { try { PrivateKeyInfo info = new PrivateKeyInfo(algId, privKey.toASN1Primitive()); return getEncodedPrivateKeyInfo(info); } catch (Exception e) { return null; } } public static byte[] getEncodedPrivateKeyInfo(PrivateKeyInfo info) { try { return info.getEncoded(ASN1Encoding.DER); } catch (Exception e) { return null; } } } bouncycastle-1.49.orig/src/org/bouncycastle/pqc/jcajce/provider/Rainbow.java0000644000175000017500000000332711776710147026622 0ustar ebourgebourgpackage org.bouncycastle.pqc.jcajce.provider; import org.bouncycastle.jcajce.provider.config.ConfigurableProvider; import org.bouncycastle.jcajce.provider.util.AsymmetricAlgorithmProvider; import org.bouncycastle.jcajce.provider.util.AsymmetricKeyInfoConverter; import org.bouncycastle.pqc.asn1.PQCObjectIdentifiers; import org.bouncycastle.pqc.jcajce.provider.rainbow.RainbowKeyFactorySpi; public class Rainbow { private static final String PREFIX = "org.bouncycastle.pqc.jcajce.provider" + ".rainbow."; public static class Mappings extends AsymmetricAlgorithmProvider { public Mappings() { } public void configure(ConfigurableProvider provider) { provider.addAlgorithm("KeyFactory.Rainbow", PREFIX + "RainbowKeyFactorySpi"); provider.addAlgorithm("KeyPairGenerator.Rainbow", PREFIX + "RainbowKeyPairGeneratorSpi"); addSignatureAlgorithm(provider, "SHA224", "Rainbow", PREFIX + "SignatureSpi$withSha224", PQCObjectIdentifiers.rainbowWithSha224); addSignatureAlgorithm(provider, "SHA256", "Rainbow", PREFIX + "SignatureSpi$withSha256", PQCObjectIdentifiers.rainbowWithSha256); addSignatureAlgorithm(provider, "SHA384", "Rainbow", PREFIX + "SignatureSpi$withSha384", PQCObjectIdentifiers.rainbowWithSha384); addSignatureAlgorithm(provider, "SHA512", "Rainbow", PREFIX + "SignatureSpi$withSha512", PQCObjectIdentifiers.rainbowWithSha512); AsymmetricKeyInfoConverter keyFact = new RainbowKeyFactorySpi(); registerOid(provider, PQCObjectIdentifiers.rainbow, "Rainbow", keyFact); registerOidAlgorithmParameters(provider, PQCObjectIdentifiers.rainbow, "Rainbow"); } } } bouncycastle-1.49.orig/src/org/bouncycastle/pqc/jcajce/provider/gmss/0000755000175000017500000000000012152033551025304 5ustar ebourgebourgbouncycastle-1.49.orig/src/org/bouncycastle/pqc/jcajce/provider/gmss/BCGMSSPublicKey.java0000644000175000017500000000700712151551717030751 0ustar ebourgebourgpackage org.bouncycastle.pqc.jcajce.provider.gmss; import java.security.PublicKey; import org.bouncycastle.asn1.x509.AlgorithmIdentifier; import org.bouncycastle.crypto.CipherParameters; import org.bouncycastle.pqc.asn1.GMSSPublicKey; import org.bouncycastle.pqc.asn1.PQCObjectIdentifiers; import org.bouncycastle.pqc.asn1.ParSet; import org.bouncycastle.pqc.crypto.gmss.GMSSParameters; import org.bouncycastle.pqc.crypto.gmss.GMSSPublicKeyParameters; import org.bouncycastle.pqc.jcajce.provider.util.KeyUtil; import org.bouncycastle.pqc.jcajce.spec.GMSSPublicKeySpec; import org.bouncycastle.util.encoders.Hex; /** * This class implements the GMSS public key and is usually initiated by the GMSSKeyPairGenerator. * * @see org.bouncycastle.pqc.crypto.gmss.GMSSKeyPairGenerator * @see org.bouncycastle.pqc.jcajce.spec.GMSSPublicKeySpec */ public class BCGMSSPublicKey implements CipherParameters, PublicKey { /** * */ private static final long serialVersionUID = 1L; /** * The GMSS public key */ private byte[] publicKeyBytes; /** * The GMSSParameterSet */ private GMSSParameters gmssParameterSet; private GMSSParameters gmssParams; /** * The constructor * * @param pub a raw GMSS public key * @param gmssParameterSet an instance of GMSS Parameterset * @see org.bouncycastle.pqc.crypto.gmss.GMSSKeyPairGenerator */ public BCGMSSPublicKey(byte[] pub, GMSSParameters gmssParameterSet) { this.gmssParameterSet = gmssParameterSet; this.publicKeyBytes = pub; } /** * The constructor * * @param keySpec a GMSS key specification */ protected BCGMSSPublicKey(GMSSPublicKeySpec keySpec) { this(keySpec.getPublicKey(), keySpec.getParameters()); } public BCGMSSPublicKey( GMSSPublicKeyParameters params) { this(params.getPublicKey(), params.getParameters()); } /** * Returns the name of the algorithm * * @return "GMSS" */ public String getAlgorithm() { return "GMSS"; } /** * @return The GMSS public key byte array */ public byte[] getPublicKeyBytes() { return publicKeyBytes; } /** * @return The GMSS Parameterset */ public GMSSParameters getParameterSet() { return gmssParameterSet; } /** * Returns a human readable form of the GMSS public key * * @return A human readable form of the GMSS public key */ public String toString() { String out = "GMSS public key : " + new String(Hex.encode(publicKeyBytes)) + "\n" + "Height of Trees: \n"; for (int i = 0; i < gmssParameterSet.getHeightOfTrees().length; i++) { out = out + "Layer " + i + " : " + gmssParameterSet.getHeightOfTrees()[i] + " WinternitzParameter: " + gmssParameterSet.getWinternitzParameter()[i] + " K: " + gmssParameterSet.getK()[i] + "\n"; } return out; } public byte[] getEncoded() { return KeyUtil.getEncodedSubjectPublicKeyInfo(new AlgorithmIdentifier(PQCObjectIdentifiers.gmss, new ParSet(gmssParameterSet.getNumOfLayers(), gmssParameterSet.getHeightOfTrees(), gmssParameterSet.getWinternitzParameter(), gmssParameterSet.getK()).toASN1Primitive()), new GMSSPublicKey(publicKeyBytes)); } public String getFormat() { return "X.509"; } } bouncycastle-1.49.orig/src/org/bouncycastle/pqc/jcajce/provider/mceliece/0000755000175000017500000000000012152033551026101 5ustar ebourgebourgbouncycastle-1.49.orig/src/org/bouncycastle/pqc/jcajce/provider/mceliece/McEliecePKCSCipherSpi.java0000644000175000017500000001152512057027477032724 0ustar ebourgebourgpackage org.bouncycastle.pqc.jcajce.provider.mceliece; import java.security.InvalidAlgorithmParameterException; import java.security.InvalidKeyException; import java.security.Key; import java.security.PrivateKey; import java.security.PublicKey; import java.security.SecureRandom; import java.security.spec.AlgorithmParameterSpec; import javax.crypto.BadPaddingException; import javax.crypto.IllegalBlockSizeException; import org.bouncycastle.asn1.pkcs.PKCSObjectIdentifiers; import org.bouncycastle.asn1.x509.X509ObjectIdentifiers; import org.bouncycastle.crypto.CipherParameters; import org.bouncycastle.crypto.Digest; import org.bouncycastle.crypto.digests.SHA1Digest; import org.bouncycastle.crypto.digests.SHA224Digest; import org.bouncycastle.crypto.digests.SHA256Digest; import org.bouncycastle.crypto.digests.SHA384Digest; import org.bouncycastle.crypto.digests.SHA512Digest; import org.bouncycastle.crypto.params.ParametersWithRandom; import org.bouncycastle.pqc.crypto.mceliece.McElieceKeyParameters; import org.bouncycastle.pqc.crypto.mceliece.McEliecePKCSCipher; import org.bouncycastle.pqc.jcajce.provider.util.AsymmetricBlockCipher; public class McEliecePKCSCipherSpi extends AsymmetricBlockCipher implements PKCSObjectIdentifiers, X509ObjectIdentifiers { // TODO digest needed? private Digest digest; private McEliecePKCSCipher cipher; public McEliecePKCSCipherSpi(Digest digest, McEliecePKCSCipher cipher) { this.digest = digest; this.cipher = cipher; } protected void initCipherEncrypt(Key key, AlgorithmParameterSpec params, SecureRandom sr) throws InvalidKeyException, InvalidAlgorithmParameterException { CipherParameters param; param = McElieceKeysToParams.generatePublicKeyParameter((PublicKey)key); param = new ParametersWithRandom(param, sr); digest.reset(); cipher.init(true, param); this.maxPlainTextSize = cipher.maxPlainTextSize; this.cipherTextSize = cipher.cipherTextSize; } protected void initCipherDecrypt(Key key, AlgorithmParameterSpec params) throws InvalidKeyException, InvalidAlgorithmParameterException { CipherParameters param; param = McElieceKeysToParams.generatePrivateKeyParameter((PrivateKey)key); digest.reset(); cipher.init(false, param); this.maxPlainTextSize = cipher.maxPlainTextSize; this.cipherTextSize = cipher.cipherTextSize; } protected byte[] messageEncrypt(byte[] input) throws IllegalBlockSizeException, BadPaddingException { byte[] output = null; try { output = cipher.messageEncrypt(input); } catch (Exception e) { e.printStackTrace(); } return output; } protected byte[] messageDecrypt(byte[] input) throws IllegalBlockSizeException, BadPaddingException { byte[] output = null; try { output = cipher.messageDecrypt(input); } catch (Exception e) { e.printStackTrace(); } return output; } public String getName() { return "McEliecePKCS"; } public int getKeySize(Key key) throws InvalidKeyException { McElieceKeyParameters mcElieceKeyParameters; if (key instanceof PublicKey) { mcElieceKeyParameters = (McElieceKeyParameters)McElieceKeysToParams.generatePublicKeyParameter((PublicKey)key); } else { mcElieceKeyParameters = (McElieceKeyParameters)McElieceKeysToParams.generatePrivateKeyParameter((PrivateKey)key); } return cipher.getKeySize(mcElieceKeyParameters); } ////////////////////////////////////////////////////////////////////////////////// static public class McEliecePKCS extends McEliecePKCSCipherSpi { public McEliecePKCS() { super(new SHA1Digest(), new McEliecePKCSCipher()); } } static public class McEliecePKCS224 extends McEliecePKCSCipherSpi { public McEliecePKCS224() { super(new SHA224Digest(), new McEliecePKCSCipher()); } } static public class McEliecePKCS256 extends McEliecePKCSCipherSpi { public McEliecePKCS256() { super(new SHA256Digest(), new McEliecePKCSCipher()); } } static public class McEliecePKCS384 extends McEliecePKCSCipherSpi { public McEliecePKCS384() { super(new SHA384Digest(), new McEliecePKCSCipher()); } } static public class McEliecePKCS512 extends McEliecePKCSCipherSpi { public McEliecePKCS512() { super(new SHA512Digest(), new McEliecePKCSCipher()); } } } ././@LongLink0000000000000000000000000000015000000000000011561 Lustar rootrootbouncycastle-1.49.orig/src/org/bouncycastle/pqc/jcajce/provider/mceliece/McElieceCCA2KeyFactorySpi.javabouncycastle-1.49.orig/src/org/bouncycastle/pqc/jcajce/provider/mceliece/McElieceCCA2KeyFactorySpi.j0000644000175000017500000003072712104635456033012 0ustar ebourgebourgpackage org.bouncycastle.pqc.jcajce.provider.mceliece; import java.io.IOException; import java.math.BigInteger; import java.security.InvalidKeyException; import java.security.Key; import java.security.KeyFactorySpi; import java.security.PrivateKey; import java.security.PublicKey; import java.security.spec.InvalidKeySpecException; import java.security.spec.KeySpec; import java.security.spec.PKCS8EncodedKeySpec; import java.security.spec.X509EncodedKeySpec; import org.bouncycastle.asn1.ASN1Integer; import org.bouncycastle.asn1.ASN1ObjectIdentifier; import org.bouncycastle.asn1.ASN1OctetString; import org.bouncycastle.asn1.ASN1Primitive; import org.bouncycastle.asn1.ASN1Sequence; import org.bouncycastle.asn1.pkcs.PrivateKeyInfo; import org.bouncycastle.asn1.x509.SubjectPublicKeyInfo; import org.bouncycastle.pqc.asn1.McElieceCCA2PrivateKey; import org.bouncycastle.pqc.asn1.McElieceCCA2PublicKey; import org.bouncycastle.pqc.jcajce.spec.McElieceCCA2PrivateKeySpec; import org.bouncycastle.pqc.jcajce.spec.McElieceCCA2PublicKeySpec; /** * This class is used to translate between McEliece CCA2 keys and key * specifications. * * @see BCMcElieceCCA2PrivateKey * @see McElieceCCA2PrivateKeySpec * @see BCMcElieceCCA2PublicKey * @see McElieceCCA2PublicKeySpec */ public class McElieceCCA2KeyFactorySpi extends KeyFactorySpi { /** * The OID of the algorithm. */ public static final String OID = "1.3.6.1.4.1.8301.3.1.3.4.2"; /** * Converts, if possible, a key specification into a * {@link BCMcElieceCCA2PublicKey}. Currently, the following key * specifications are supported: {@link McElieceCCA2PublicKeySpec}, * {@link X509EncodedKeySpec}. * * @param keySpec the key specification * @return the McEliece CCA2 public key * @throws InvalidKeySpecException if the key specification is not supported. */ public PublicKey generatePublic(KeySpec keySpec) throws InvalidKeySpecException { if (keySpec instanceof McElieceCCA2PublicKeySpec) { return new BCMcElieceCCA2PublicKey( (McElieceCCA2PublicKeySpec)keySpec); } else if (keySpec instanceof X509EncodedKeySpec) { // get the DER-encoded Key according to X.509 from the spec byte[] encKey = ((X509EncodedKeySpec)keySpec).getEncoded(); // decode the SubjectPublicKeyInfo data structure to the pki object SubjectPublicKeyInfo pki; try { pki = SubjectPublicKeyInfo.getInstance(ASN1Primitive.fromByteArray(encKey)); } catch (IOException e) { throw new InvalidKeySpecException(e.toString()); } try { // --- Build and return the actual key. ASN1Primitive innerType = pki.parsePublicKey(); ASN1Sequence publicKey = (ASN1Sequence)innerType; // decode oidString (but we don't need it right now) String oidString = ((ASN1ObjectIdentifier)publicKey.getObjectAt(0)) .toString(); // decode BigInteger bigN = ((ASN1Integer)publicKey.getObjectAt(1)).getValue(); int n = bigN.intValue(); // decode BigInteger bigT = ((ASN1Integer)publicKey.getObjectAt(2)).getValue(); int t = bigT.intValue(); // decode byte[] matrixG = ((ASN1OctetString)publicKey.getObjectAt(3)).getOctets(); return new BCMcElieceCCA2PublicKey(new McElieceCCA2PublicKeySpec( OID, n, t, matrixG)); } catch (IOException cce) { throw new InvalidKeySpecException( "Unable to decode X509EncodedKeySpec: " + cce.getMessage()); } } throw new InvalidKeySpecException("Unsupported key specification: " + keySpec.getClass() + "."); } /** * Converts, if possible, a key specification into a * {@link BCMcElieceCCA2PrivateKey}. Currently, the following key * specifications are supported: {@link McElieceCCA2PrivateKeySpec}, * {@link PKCS8EncodedKeySpec}. * * @param keySpec the key specification * @return the McEliece CCA2 private key * @throws InvalidKeySpecException if the KeySpec is not supported. */ public PrivateKey generatePrivate(KeySpec keySpec) throws InvalidKeySpecException { if (keySpec instanceof McElieceCCA2PrivateKeySpec) { return new BCMcElieceCCA2PrivateKey( (McElieceCCA2PrivateKeySpec)keySpec); } else if (keySpec instanceof PKCS8EncodedKeySpec) { // get the DER-encoded Key according to PKCS#8 from the spec byte[] encKey = ((PKCS8EncodedKeySpec)keySpec).getEncoded(); // decode the PKCS#8 data structure to the pki object PrivateKeyInfo pki; try { pki = PrivateKeyInfo.getInstance(ASN1Primitive.fromByteArray(encKey)); } catch (IOException e) { throw new InvalidKeySpecException("Unable to decode PKCS8EncodedKeySpec: " + e); } try { // get the inner type inside the BIT STRING ASN1Primitive innerType = pki.parsePrivateKey().toASN1Primitive(); // build and return the actual key ASN1Sequence privKey = (ASN1Sequence)innerType; // decode oidString (but we don't need it right now) String oidString = ((ASN1ObjectIdentifier)privKey.getObjectAt(0)) .toString(); // decode BigInteger bigN = ((ASN1Integer)privKey.getObjectAt(1)).getValue(); int n = bigN.intValue(); // decode BigInteger bigK = ((ASN1Integer)privKey.getObjectAt(2)).getValue(); int k = bigK.intValue(); // decode byte[] encFieldPoly = ((ASN1OctetString)privKey.getObjectAt(3)) .getOctets(); // decode byte[] encGoppaPoly = ((ASN1OctetString)privKey.getObjectAt(4)) .getOctets(); // decode

    byte[] encP = ((ASN1OctetString)privKey.getObjectAt(5)).getOctets(); // decode byte[] encH = ((ASN1OctetString)privKey.getObjectAt(6)).getOctets(); // decode ASN1Sequence qSeq = (ASN1Sequence)privKey.getObjectAt(7); byte[][] encQInv = new byte[qSeq.size()][]; for (int i = 0; i < qSeq.size(); i++) { encQInv[i] = ((ASN1OctetString)qSeq.getObjectAt(i)).getOctets(); } return new BCMcElieceCCA2PrivateKey( new McElieceCCA2PrivateKeySpec(OID, n, k, encFieldPoly, encGoppaPoly, encP, encH, encQInv)); } catch (IOException cce) { throw new InvalidKeySpecException( "Unable to decode PKCS8EncodedKeySpec."); } } throw new InvalidKeySpecException("Unsupported key specification: " + keySpec.getClass() + "."); } /** * Converts, if possible, a given key into a key specification. Currently, * the following key specifications are supported: *

      *
    • for McElieceCCA2PublicKey: {@link X509EncodedKeySpec}, * {@link McElieceCCA2PublicKeySpec}
    • *
    • for McElieceCCA2PrivateKey: {@link PKCS8EncodedKeySpec}, * {@link McElieceCCA2PrivateKeySpec}
    • . *
    * * @param key the key * @param keySpec the key specification * @return the specification of the McEliece CCA2 key * @throws InvalidKeySpecException if the key type or the key specification is not * supported. * @see BCMcElieceCCA2PrivateKey * @see McElieceCCA2PrivateKeySpec * @see BCMcElieceCCA2PublicKey * @see McElieceCCA2PublicKeySpec */ public KeySpec getKeySpec(Key key, Class keySpec) throws InvalidKeySpecException { if (key instanceof BCMcElieceCCA2PrivateKey) { if (PKCS8EncodedKeySpec.class.isAssignableFrom(keySpec)) { return new PKCS8EncodedKeySpec(key.getEncoded()); } else if (McElieceCCA2PrivateKeySpec.class .isAssignableFrom(keySpec)) { BCMcElieceCCA2PrivateKey privKey = (BCMcElieceCCA2PrivateKey)key; return new McElieceCCA2PrivateKeySpec(OID, privKey.getN(), privKey .getK(), privKey.getField(), privKey.getGoppaPoly(), privKey.getP(), privKey.getH(), privKey.getQInv()); } } else if (key instanceof BCMcElieceCCA2PublicKey) { if (X509EncodedKeySpec.class.isAssignableFrom(keySpec)) { return new X509EncodedKeySpec(key.getEncoded()); } else if (McElieceCCA2PublicKeySpec.class .isAssignableFrom(keySpec)) { BCMcElieceCCA2PublicKey pubKey = (BCMcElieceCCA2PublicKey)key; return new McElieceCCA2PublicKeySpec(OID, pubKey.getN(), pubKey .getT(), pubKey.getG()); } } else { throw new InvalidKeySpecException("Unsupported key type: " + key.getClass() + "."); } throw new InvalidKeySpecException("Unknown key specification: " + keySpec + "."); } /** * Translates a key into a form known by the FlexiProvider. Currently, only * the following "source" keys are supported: {@link BCMcElieceCCA2PrivateKey}, * {@link BCMcElieceCCA2PublicKey}. * * @param key the key * @return a key of a known key type * @throws InvalidKeyException if the key type is not supported. */ public Key translateKey(Key key) throws InvalidKeyException { if ((key instanceof BCMcElieceCCA2PrivateKey) || (key instanceof BCMcElieceCCA2PublicKey)) { return key; } throw new InvalidKeyException("Unsupported key type."); } public PublicKey generatePublic(SubjectPublicKeyInfo pki) throws InvalidKeySpecException { // get the inner type inside the BIT STRING try { ASN1Primitive innerType = pki.parsePublicKey(); McElieceCCA2PublicKey key = McElieceCCA2PublicKey.getInstance((ASN1Sequence)innerType); return new BCMcElieceCCA2PublicKey(key.getOID().getId(), key.getN(), key.getT(), key.getG()); } catch (IOException cce) { throw new InvalidKeySpecException("Unable to decode X509EncodedKeySpec"); } } public PrivateKey generatePrivate(PrivateKeyInfo pki) throws InvalidKeySpecException { // get the inner type inside the BIT STRING try { ASN1Primitive innerType = pki.parsePrivateKey().toASN1Primitive(); McElieceCCA2PrivateKey key = McElieceCCA2PrivateKey.getInstance(innerType); return new BCMcElieceCCA2PrivateKey(key.getOID().getId(), key.getN(), key.getK(), key.getField(), key.getGoppaPoly(), key.getP(), key.getH(), key.getQInv()); } catch (IOException cce) { throw new InvalidKeySpecException("Unable to decode PKCS8EncodedKeySpec"); } } protected PublicKey engineGeneratePublic(KeySpec keySpec) throws InvalidKeySpecException { return null; //To change body of implemented methods use File | Settings | File Templates. } protected PrivateKey engineGeneratePrivate(KeySpec keySpec) throws InvalidKeySpecException { return null; //To change body of implemented methods use File | Settings | File Templates. } protected KeySpec engineGetKeySpec(Key key, Class tClass) throws InvalidKeySpecException { return null; //To change body of implemented methods use File | Settings | File Templates. } protected Key engineTranslateKey(Key key) throws InvalidKeyException { return null; //To change body of implemented methods use File | Settings | File Templates. } } ././@LongLink0000000000000000000000000000015200000000000011563 Lustar rootrootbouncycastle-1.49.orig/src/org/bouncycastle/pqc/jcajce/provider/mceliece/McElieceKeyPairGeneratorSpi.javabouncycastle-1.49.orig/src/org/bouncycastle/pqc/jcajce/provider/mceliece/McElieceKeyPairGeneratorSpi0000644000175000017500000001114512057027445033315 0ustar ebourgebourgpackage org.bouncycastle.pqc.jcajce.provider.mceliece; import java.security.InvalidAlgorithmParameterException; import java.security.KeyPair; import java.security.KeyPairGenerator; import java.security.SecureRandom; import java.security.spec.AlgorithmParameterSpec; import org.bouncycastle.crypto.AsymmetricCipherKeyPair; import org.bouncycastle.pqc.crypto.mceliece.McElieceCCA2KeyGenerationParameters; import org.bouncycastle.pqc.crypto.mceliece.McElieceCCA2KeyPairGenerator; import org.bouncycastle.pqc.crypto.mceliece.McElieceCCA2Parameters; import org.bouncycastle.pqc.crypto.mceliece.McElieceCCA2PrivateKeyParameters; import org.bouncycastle.pqc.crypto.mceliece.McElieceCCA2PublicKeyParameters; import org.bouncycastle.pqc.crypto.mceliece.McElieceKeyGenerationParameters; import org.bouncycastle.pqc.crypto.mceliece.McElieceKeyPairGenerator; import org.bouncycastle.pqc.crypto.mceliece.McElieceParameters; import org.bouncycastle.pqc.crypto.mceliece.McEliecePrivateKeyParameters; import org.bouncycastle.pqc.crypto.mceliece.McEliecePublicKeyParameters; import org.bouncycastle.pqc.jcajce.spec.ECCKeyGenParameterSpec; import org.bouncycastle.pqc.jcajce.spec.McElieceCCA2ParameterSpec; public abstract class McElieceKeyPairGeneratorSpi extends KeyPairGenerator { public McElieceKeyPairGeneratorSpi( String algorithmName) { super(algorithmName); } /** * * * */ public static class McElieceCCA2 extends McElieceKeyPairGeneratorSpi { McElieceCCA2KeyPairGenerator kpg; public McElieceCCA2() { super("McElieceCCA-2"); } public McElieceCCA2(String s) { super(s); } public void initialize(AlgorithmParameterSpec params) throws InvalidAlgorithmParameterException { kpg = new McElieceCCA2KeyPairGenerator(); super.initialize(params); ECCKeyGenParameterSpec ecc = (ECCKeyGenParameterSpec)params; McElieceCCA2KeyGenerationParameters mccca2KGParams = new McElieceCCA2KeyGenerationParameters(new SecureRandom(), new McElieceCCA2Parameters(ecc.getM(), ecc.getT())); kpg.init(mccca2KGParams); } public void initialize(int keySize, SecureRandom random) { McElieceCCA2ParameterSpec paramSpec = new McElieceCCA2ParameterSpec(); // call the initializer with the chosen parameters try { this.initialize(paramSpec); } catch (InvalidAlgorithmParameterException ae) { } } public KeyPair generateKeyPair() { AsymmetricCipherKeyPair generateKeyPair = kpg.generateKeyPair(); McElieceCCA2PrivateKeyParameters sk = (McElieceCCA2PrivateKeyParameters)generateKeyPair.getPrivate(); McElieceCCA2PublicKeyParameters pk = (McElieceCCA2PublicKeyParameters)generateKeyPair.getPublic(); return new KeyPair(new BCMcElieceCCA2PublicKey(pk), new BCMcElieceCCA2PrivateKey(sk)); } } /** * * * */ public static class McEliece extends McElieceKeyPairGeneratorSpi { McElieceKeyPairGenerator kpg; public McEliece() { super("McEliece"); } public void initialize(AlgorithmParameterSpec params) throws InvalidAlgorithmParameterException { kpg = new McElieceKeyPairGenerator(); super.initialize(params); ECCKeyGenParameterSpec ecc = (ECCKeyGenParameterSpec)params; McElieceKeyGenerationParameters mccKGParams = new McElieceKeyGenerationParameters(new SecureRandom(), new McElieceParameters(ecc.getM(), ecc.getT())); kpg.init(mccKGParams); } public void initialize(int keySize, SecureRandom random) { ECCKeyGenParameterSpec paramSpec = new ECCKeyGenParameterSpec(); // call the initializer with the chosen parameters try { this.initialize(paramSpec); } catch (InvalidAlgorithmParameterException ae) { } } public KeyPair generateKeyPair() { AsymmetricCipherKeyPair generateKeyPair = kpg.generateKeyPair(); McEliecePrivateKeyParameters sk = (McEliecePrivateKeyParameters)generateKeyPair.getPrivate(); McEliecePublicKeyParameters pk = (McEliecePublicKeyParameters)generateKeyPair.getPublic(); return new KeyPair(new BCMcEliecePublicKey(pk), new BCMcEliecePrivateKey(sk)); } } } ././@LongLink0000000000000000000000000000015000000000000011561 Lustar rootrootbouncycastle-1.49.orig/src/org/bouncycastle/pqc/jcajce/provider/mceliece/McElieceFujisakiCipherSpi.javabouncycastle-1.49.orig/src/org/bouncycastle/pqc/jcajce/provider/mceliece/McElieceFujisakiCipherSpi.j0000644000175000017500000001546412057027413033235 0ustar ebourgebourgpackage org.bouncycastle.pqc.jcajce.provider.mceliece; import java.io.ByteArrayOutputStream; import java.security.InvalidAlgorithmParameterException; import java.security.InvalidKeyException; import java.security.Key; import java.security.NoSuchAlgorithmException; import java.security.PrivateKey; import java.security.PublicKey; import java.security.SecureRandom; import java.security.spec.AlgorithmParameterSpec; import javax.crypto.BadPaddingException; import javax.crypto.IllegalBlockSizeException; import org.bouncycastle.asn1.pkcs.PKCSObjectIdentifiers; import org.bouncycastle.asn1.x509.X509ObjectIdentifiers; import org.bouncycastle.crypto.CipherParameters; import org.bouncycastle.crypto.Digest; import org.bouncycastle.crypto.digests.SHA1Digest; import org.bouncycastle.crypto.digests.SHA224Digest; import org.bouncycastle.crypto.digests.SHA256Digest; import org.bouncycastle.crypto.digests.SHA384Digest; import org.bouncycastle.crypto.digests.SHA512Digest; import org.bouncycastle.crypto.params.ParametersWithRandom; import org.bouncycastle.pqc.crypto.mceliece.McElieceCCA2KeyParameters; import org.bouncycastle.pqc.crypto.mceliece.McElieceFujisakiCipher; import org.bouncycastle.pqc.jcajce.provider.util.AsymmetricHybridCipher; public class McElieceFujisakiCipherSpi extends AsymmetricHybridCipher implements PKCSObjectIdentifiers, X509ObjectIdentifiers { // TODO digest needed? private Digest digest; private McElieceFujisakiCipher cipher; /** * buffer to store the input data */ private ByteArrayOutputStream buf; protected McElieceFujisakiCipherSpi(Digest digest, McElieceFujisakiCipher cipher) { this.digest = digest; this.cipher = cipher; buf = new ByteArrayOutputStream(); } /** * Continue a multiple-part encryption or decryption operation. * * @param input byte array containing the next part of the input * @param inOff index in the array where the input starts * @param inLen length of the input * @return the processed byte array. */ public byte[] update(byte[] input, int inOff, int inLen) { buf.write(input, inOff, inLen); return new byte[0]; } /** * Encrypts or decrypts data in a single-part operation, or finishes a * multiple-part operation. The data is encrypted or decrypted, depending on * how this cipher was initialized. * * @param input the input buffer * @param inOff the offset in input where the input starts * @param inLen the input length * @return the new buffer with the result * @throws BadPaddingException on deryption errors. */ public byte[] doFinal(byte[] input, int inOff, int inLen) throws BadPaddingException { update(input, inOff, inLen); byte[] data = buf.toByteArray(); buf.reset(); if (opMode == ENCRYPT_MODE) { try { return cipher.messageEncrypt(data); } catch (Exception e) { e.printStackTrace(); } } else if (opMode == DECRYPT_MODE) { try { return cipher.messageDecrypt(data); } catch (Exception e) { e.printStackTrace(); } } return null; } protected int encryptOutputSize(int inLen) { return 0; } protected int decryptOutputSize(int inLen) { return 0; } protected void initCipherEncrypt(Key key, AlgorithmParameterSpec params, SecureRandom sr) throws InvalidKeyException, InvalidAlgorithmParameterException { CipherParameters param; param = McElieceCCA2KeysToParams.generatePublicKeyParameter((PublicKey)key); param = new ParametersWithRandom(param, sr); digest.reset(); cipher.init(true, param); } protected void initCipherDecrypt(Key key, AlgorithmParameterSpec params) throws InvalidKeyException, InvalidAlgorithmParameterException { CipherParameters param; param = McElieceCCA2KeysToParams.generatePrivateKeyParameter((PrivateKey)key); digest.reset(); cipher.init(false, param); } public String getName() { return "McElieceFujisakiCipher"; } public int getKeySize(Key key) throws InvalidKeyException { McElieceCCA2KeyParameters mcElieceCCA2KeyParameters; if (key instanceof PublicKey) { mcElieceCCA2KeyParameters = (McElieceCCA2KeyParameters)McElieceCCA2KeysToParams.generatePublicKeyParameter((PublicKey)key); } else { mcElieceCCA2KeyParameters = (McElieceCCA2KeyParameters)McElieceCCA2KeysToParams.generatePrivateKeyParameter((PrivateKey)key); } return cipher.getKeySize(mcElieceCCA2KeyParameters); } public byte[] messageEncrypt(byte[] input) throws IllegalBlockSizeException, BadPaddingException, NoSuchAlgorithmException { byte[] output = null; try { output = cipher.messageEncrypt(input); } catch (Exception e) { e.printStackTrace(); } return output; } public byte[] messageDecrypt(byte[] input) throws IllegalBlockSizeException, BadPaddingException, NoSuchAlgorithmException { byte[] output = null; try { output = cipher.messageDecrypt(input); } catch (Exception e) { e.printStackTrace(); } return output; } ////////////////////////////////////////////////////////////////////////////////// static public class McElieceFujisaki extends McElieceFujisakiCipherSpi { public McElieceFujisaki() { super(new SHA1Digest(), new McElieceFujisakiCipher()); } } static public class McElieceFujisaki224 extends McElieceFujisakiCipherSpi { public McElieceFujisaki224() { super(new SHA224Digest(), new McElieceFujisakiCipher()); } } static public class McElieceFujisaki256 extends McElieceFujisakiCipherSpi { public McElieceFujisaki256() { super(new SHA256Digest(), new McElieceFujisakiCipher()); } } static public class McElieceFujisaki384 extends McElieceFujisakiCipherSpi { public McElieceFujisaki384() { super(new SHA384Digest(), new McElieceFujisakiCipher()); } } static public class McElieceFujisaki512 extends McElieceFujisakiCipherSpi { public McElieceFujisaki512() { super(new SHA512Digest(), new McElieceFujisakiCipher()); } } } ././@LongLink0000000000000000000000000000015300000000000011564 Lustar rootrootbouncycastle-1.49.orig/src/org/bouncycastle/pqc/jcajce/provider/mceliece/McEliecePointchevalCipherSpi.javabouncycastle-1.49.orig/src/org/bouncycastle/pqc/jcajce/provider/mceliece/McEliecePointchevalCipherSp0000644000175000017500000001563412057027512033342 0ustar ebourgebourgpackage org.bouncycastle.pqc.jcajce.provider.mceliece; import java.io.ByteArrayOutputStream; import java.security.InvalidAlgorithmParameterException; import java.security.InvalidKeyException; import java.security.Key; import java.security.NoSuchAlgorithmException; import java.security.PrivateKey; import java.security.PublicKey; import java.security.SecureRandom; import java.security.spec.AlgorithmParameterSpec; import javax.crypto.BadPaddingException; import javax.crypto.IllegalBlockSizeException; import org.bouncycastle.asn1.pkcs.PKCSObjectIdentifiers; import org.bouncycastle.asn1.x509.X509ObjectIdentifiers; import org.bouncycastle.crypto.CipherParameters; import org.bouncycastle.crypto.Digest; import org.bouncycastle.crypto.digests.SHA1Digest; import org.bouncycastle.crypto.digests.SHA224Digest; import org.bouncycastle.crypto.digests.SHA256Digest; import org.bouncycastle.crypto.digests.SHA384Digest; import org.bouncycastle.crypto.digests.SHA512Digest; import org.bouncycastle.crypto.params.ParametersWithRandom; import org.bouncycastle.pqc.crypto.mceliece.McElieceCCA2KeyParameters; import org.bouncycastle.pqc.crypto.mceliece.McEliecePointchevalCipher; import org.bouncycastle.pqc.jcajce.provider.util.AsymmetricHybridCipher; public class McEliecePointchevalCipherSpi extends AsymmetricHybridCipher implements PKCSObjectIdentifiers, X509ObjectIdentifiers { // TODO digest needed? private Digest digest; private McEliecePointchevalCipher cipher; /** * buffer to store the input data */ private ByteArrayOutputStream buf = new ByteArrayOutputStream(); protected McEliecePointchevalCipherSpi(Digest digest, McEliecePointchevalCipher cipher) { this.digest = digest; this.cipher = cipher; buf = new ByteArrayOutputStream(); } /** * Continue a multiple-part encryption or decryption operation. * * @param input byte array containing the next part of the input * @param inOff index in the array where the input starts * @param inLen length of the input * @return the processed byte array. */ public byte[] update(byte[] input, int inOff, int inLen) { buf.write(input, inOff, inLen); return new byte[0]; } /** * Encrypts or decrypts data in a single-part operation, or finishes a * multiple-part operation. The data is encrypted or decrypted, depending on * how this cipher was initialized. * * @param input the input buffer * @param inOff the offset in input where the input starts * @param inLen the input length * @return the new buffer with the result * @throws BadPaddingException on deryption errors. */ public byte[] doFinal(byte[] input, int inOff, int inLen) throws BadPaddingException { update(input, inOff, inLen); byte[] data = buf.toByteArray(); buf.reset(); if (opMode == ENCRYPT_MODE) { try { return cipher.messageEncrypt(data); } catch (Exception e) { e.printStackTrace(); } } else if (opMode == DECRYPT_MODE) { try { return cipher.messageDecrypt(data); } catch (Exception e) { e.printStackTrace(); } } return null; } protected int encryptOutputSize(int inLen) { return 0; } protected int decryptOutputSize(int inLen) { return 0; } protected void initCipherEncrypt(Key key, AlgorithmParameterSpec params, SecureRandom sr) throws InvalidKeyException, InvalidAlgorithmParameterException { CipherParameters param; param = McElieceCCA2KeysToParams.generatePublicKeyParameter((PublicKey)key); param = new ParametersWithRandom(param, sr); digest.reset(); cipher.init(true, param); } protected void initCipherDecrypt(Key key, AlgorithmParameterSpec params) throws InvalidKeyException, InvalidAlgorithmParameterException { CipherParameters param; param = McElieceCCA2KeysToParams.generatePrivateKeyParameter((PrivateKey)key); digest.reset(); cipher.init(false, param); } public String getName() { return "McEliecePointchevalCipher"; } public int getKeySize(Key key) throws InvalidKeyException { McElieceCCA2KeyParameters mcElieceCCA2KeyParameters; if (key instanceof PublicKey) { mcElieceCCA2KeyParameters = (McElieceCCA2KeyParameters)McElieceCCA2KeysToParams.generatePublicKeyParameter((PublicKey)key); } else { mcElieceCCA2KeyParameters = (McElieceCCA2KeyParameters)McElieceCCA2KeysToParams.generatePrivateKeyParameter((PrivateKey)key); } return cipher.getKeySize(mcElieceCCA2KeyParameters); } public byte[] messageEncrypt(byte[] input) throws IllegalBlockSizeException, BadPaddingException, NoSuchAlgorithmException { byte[] output = null; try { output = cipher.messageEncrypt(input); } catch (Exception e) { e.printStackTrace(); } return output; } public byte[] messageDecrypt(byte[] input) throws IllegalBlockSizeException, BadPaddingException, NoSuchAlgorithmException { byte[] output = null; try { output = cipher.messageDecrypt(input); } catch (Exception e) { e.printStackTrace(); } return output; } //////////////////////////////////////////////////////////////////////////////////77 static public class McEliecePointcheval extends McEliecePointchevalCipherSpi { public McEliecePointcheval() { super(new SHA1Digest(), new McEliecePointchevalCipher()); } } static public class McEliecePointcheval224 extends McEliecePointchevalCipherSpi { public McEliecePointcheval224() { super(new SHA224Digest(), new McEliecePointchevalCipher()); } } static public class McEliecePointcheval256 extends McEliecePointchevalCipherSpi { public McEliecePointcheval256() { super(new SHA256Digest(), new McEliecePointchevalCipher()); } } static public class McEliecePointcheval384 extends McEliecePointchevalCipherSpi { public McEliecePointcheval384() { super(new SHA384Digest(), new McEliecePointchevalCipher()); } } static public class McEliecePointcheval512 extends McEliecePointchevalCipherSpi { public McEliecePointcheval512() { super(new SHA512Digest(), new McEliecePointchevalCipher()); } } } bouncycastle-1.49.orig/src/org/bouncycastle/pqc/jcajce/provider/mceliece/McElieceKeysToParams.java0000644000175000017500000000312712045616616032732 0ustar ebourgebourgpackage org.bouncycastle.pqc.jcajce.provider.mceliece; import java.security.InvalidKeyException; import java.security.PrivateKey; import java.security.PublicKey; import org.bouncycastle.crypto.params.AsymmetricKeyParameter; import org.bouncycastle.pqc.crypto.mceliece.McEliecePrivateKeyParameters; import org.bouncycastle.pqc.crypto.mceliece.McEliecePublicKeyParameters; /** * utility class for converting jce/jca McEliece objects * objects into their org.bouncycastle.crypto counterparts. */ public class McElieceKeysToParams { static public AsymmetricKeyParameter generatePublicKeyParameter( PublicKey key) throws InvalidKeyException { if (key instanceof BCMcEliecePublicKey) { BCMcEliecePublicKey k = (BCMcEliecePublicKey)key; return new McEliecePublicKeyParameters(k.getOIDString(), k.getN(), k.getT(), k.getG(), k.getMcElieceParameters()); } throw new InvalidKeyException("can't identify McEliece public key: " + key.getClass().getName()); } static public AsymmetricKeyParameter generatePrivateKeyParameter( PrivateKey key) throws InvalidKeyException { if (key instanceof BCMcEliecePrivateKey) { BCMcEliecePrivateKey k = (BCMcEliecePrivateKey)key; return new McEliecePrivateKeyParameters(k.getOIDString(), k.getN(), k.getK(), k.getField(), k.getGoppaPoly(), k.getSInv(), k.getP1(), k.getP2(), k.getH(), k.getQInv(), k.getMcElieceParameters()); } throw new InvalidKeyException("can't identify McEliece private key."); } } bouncycastle-1.49.orig/src/org/bouncycastle/pqc/jcajce/provider/mceliece/McElieceCCA2Primitives.java0000644000175000017500000001036512045616616033076 0ustar ebourgebourgpackage org.bouncycastle.pqc.jcajce.provider.mceliece; import org.bouncycastle.pqc.crypto.mceliece.McElieceCCA2PrivateKeyParameters; import org.bouncycastle.pqc.crypto.mceliece.McElieceCCA2PublicKeyParameters; import org.bouncycastle.pqc.math.linearalgebra.GF2Matrix; import org.bouncycastle.pqc.math.linearalgebra.GF2Vector; import org.bouncycastle.pqc.math.linearalgebra.GF2mField; import org.bouncycastle.pqc.math.linearalgebra.GoppaCode; import org.bouncycastle.pqc.math.linearalgebra.Permutation; import org.bouncycastle.pqc.math.linearalgebra.PolynomialGF2mSmallM; import org.bouncycastle.pqc.math.linearalgebra.Vector; /** * Core operations for the CCA-secure variants of McEliece. */ public final class McElieceCCA2Primitives { /** * Default constructor (private). */ private McElieceCCA2Primitives() { } /** * The McEliece encryption primitive. * * @param pubKey the public key * @param m the message vector * @param z the error vector * @return m*G + z */ public static GF2Vector encryptionPrimitive(BCMcElieceCCA2PublicKey pubKey, GF2Vector m, GF2Vector z) { GF2Matrix matrixG = pubKey.getG(); Vector mG = matrixG.leftMultiplyLeftCompactForm(m); return (GF2Vector)mG.add(z); } public static GF2Vector encryptionPrimitive(McElieceCCA2PublicKeyParameters pubKey, GF2Vector m, GF2Vector z) { GF2Matrix matrixG = pubKey.getMatrixG(); Vector mG = matrixG.leftMultiplyLeftCompactForm(m); return (GF2Vector)mG.add(z); } /** * The McEliece decryption primitive. * * @param privKey the private key * @param c the ciphertext vector c = m*G + z * @return the message vector m and the error vector z */ public static GF2Vector[] decryptionPrimitive( BCMcElieceCCA2PrivateKey privKey, GF2Vector c) { // obtain values from private key int k = privKey.getK(); Permutation p = privKey.getP(); GF2mField field = privKey.getField(); PolynomialGF2mSmallM gp = privKey.getGoppaPoly(); GF2Matrix h = privKey.getH(); PolynomialGF2mSmallM[] q = privKey.getQInv(); // compute inverse permutation P^-1 Permutation pInv = p.computeInverse(); // multiply c with permutation P^-1 GF2Vector cPInv = (GF2Vector)c.multiply(pInv); // compute syndrome of cP^-1 GF2Vector syndVec = (GF2Vector)h.rightMultiply(cPInv); // decode syndrome GF2Vector errors = GoppaCode.syndromeDecode(syndVec, field, gp, q); GF2Vector mG = (GF2Vector)cPInv.add(errors); // multiply codeword and error vector with P mG = (GF2Vector)mG.multiply(p); errors = (GF2Vector)errors.multiply(p); // extract plaintext vector (last k columns of mG) GF2Vector m = mG.extractRightVector(k); // return vectors return new GF2Vector[]{m, errors}; } public static GF2Vector[] decryptionPrimitive( McElieceCCA2PrivateKeyParameters privKey, GF2Vector c) { // obtain values from private key int k = privKey.getK(); Permutation p = privKey.getP(); GF2mField field = privKey.getField(); PolynomialGF2mSmallM gp = privKey.getGoppaPoly(); GF2Matrix h = privKey.getH(); PolynomialGF2mSmallM[] q = privKey.getQInv(); // compute inverse permutation P^-1 Permutation pInv = p.computeInverse(); // multiply c with permutation P^-1 GF2Vector cPInv = (GF2Vector)c.multiply(pInv); // compute syndrome of cP^-1 GF2Vector syndVec = (GF2Vector)h.rightMultiply(cPInv); // decode syndrome GF2Vector errors = GoppaCode.syndromeDecode(syndVec, field, gp, q); GF2Vector mG = (GF2Vector)cPInv.add(errors); // multiply codeword and error vector with P mG = (GF2Vector)mG.multiply(p); errors = (GF2Vector)errors.multiply(p); // extract plaintext vector (last k columns of mG) GF2Vector m = mG.extractRightVector(k); // return vectors return new GF2Vector[]{m, errors}; } } ././@LongLink0000000000000000000000000000014600000000000011566 Lustar rootrootbouncycastle-1.49.orig/src/org/bouncycastle/pqc/jcajce/provider/mceliece/BCMcElieceCCA2PublicKey.javabouncycastle-1.49.orig/src/org/bouncycastle/pqc/jcajce/provider/mceliece/BCMcElieceCCA2PublicKey.jav0000644000175000017500000001334212104635456032673 0ustar ebourgebourgpackage org.bouncycastle.pqc.jcajce.provider.mceliece; import java.io.IOException; import java.security.PublicKey; import org.bouncycastle.asn1.ASN1ObjectIdentifier; import org.bouncycastle.asn1.ASN1Primitive; import org.bouncycastle.asn1.DERNull; import org.bouncycastle.asn1.x509.AlgorithmIdentifier; import org.bouncycastle.asn1.x509.SubjectPublicKeyInfo; import org.bouncycastle.crypto.CipherParameters; import org.bouncycastle.pqc.asn1.McElieceCCA2PublicKey; import org.bouncycastle.pqc.crypto.mceliece.McElieceCCA2KeyPairGenerator; import org.bouncycastle.pqc.crypto.mceliece.McElieceCCA2Parameters; import org.bouncycastle.pqc.crypto.mceliece.McElieceCCA2PublicKeyParameters; import org.bouncycastle.pqc.jcajce.spec.McElieceCCA2PublicKeySpec; import org.bouncycastle.pqc.math.linearalgebra.GF2Matrix; /** * This class implements a McEliece CCA2 public key and is usually instantiated * by the {@link McElieceCCA2KeyPairGenerator} or {@link McElieceCCA2KeyFactorySpi}. */ public class BCMcElieceCCA2PublicKey implements CipherParameters, PublicKey { /** * */ private static final long serialVersionUID = 1L; // the OID of the algorithm private String oid; // the length of the code private int n; // the error correction capability of the code private int t; // the generator matrix private GF2Matrix g; private McElieceCCA2Parameters McElieceCCA2Params; /** * Constructor (used by the {@link McElieceCCA2KeyPairGenerator}). * * @param n the length of the code * @param t the error correction capability of the code * @param g the generator matrix */ public BCMcElieceCCA2PublicKey(String oid, int n, int t, GF2Matrix g) { this.oid = oid; this.n = n; this.t = t; this.g = g; } /** * Constructor (used by the {@link McElieceCCA2KeyFactorySpi}). * * @param keySpec a {@link McElieceCCA2PublicKeySpec} */ public BCMcElieceCCA2PublicKey(McElieceCCA2PublicKeySpec keySpec) { this(keySpec.getOIDString(), keySpec.getN(), keySpec.getT(), keySpec.getMatrixG()); } public BCMcElieceCCA2PublicKey(McElieceCCA2PublicKeyParameters params) { this(params.getOIDString(), params.getN(), params.getT(), params.getMatrixG()); this.McElieceCCA2Params = params.getParameters(); } /** * Return the name of the algorithm. * * @return "McEliece" */ public String getAlgorithm() { return "McEliece"; } /** * @return the length of the code */ public int getN() { return n; } /** * @return the dimension of the code */ public int getK() { return g.getNumRows(); } /** * @return the error correction capability of the code */ public int getT() { return t; } /** * @return the generator matrix */ public GF2Matrix getG() { return g; } /** * @return a human readable form of the key */ public String toString() { String result = "McEliecePublicKey:\n"; result += " length of the code : " + n + "\n"; result += " error correction capability: " + t + "\n"; result += " generator matrix : " + g.toString(); return result; } /** * Compare this key with another object. * * @param other the other object * @return the result of the comparison */ public boolean equals(Object other) { if (other == null || !(other instanceof BCMcElieceCCA2PublicKey)) { return false; } BCMcElieceCCA2PublicKey otherKey = (BCMcElieceCCA2PublicKey)other; return (n == otherKey.n) && (t == otherKey.t) && (g.equals(otherKey.g)); } /** * @return the hash code of this key */ public int hashCode() { return n + t + g.hashCode(); } /** * @return the OID of the algorithm */ public String getOIDString() { return oid; } /** * @return the OID to encode in the SubjectPublicKeyInfo structure */ protected ASN1ObjectIdentifier getOID() { return new ASN1ObjectIdentifier(McElieceCCA2KeyFactorySpi.OID); } /** * @return the algorithm parameters to encode in the SubjectPublicKeyInfo * structure */ protected ASN1Primitive getAlgParams() { return null; // FIXME: needed at all? } /** * Return the keyData to encode in the SubjectPublicKeyInfo structure. *

    * The ASN.1 definition of the key structure is *

    *

         *       McEliecePublicKey ::= SEQUENCE {
         *         n           Integer      -- length of the code
         *         t           Integer      -- error correcting capability
         *         matrixG     OctetString  -- generator matrix as octet string
         *       }
         * 
    * * @return the keyData to encode in the SubjectPublicKeyInfo structure */ public byte[] getEncoded() { McElieceCCA2PublicKey key = new McElieceCCA2PublicKey(new ASN1ObjectIdentifier(oid), n, t, g); AlgorithmIdentifier algorithmIdentifier = new AlgorithmIdentifier(this.getOID(), DERNull.INSTANCE); try { SubjectPublicKeyInfo subjectPublicKeyInfo = new SubjectPublicKeyInfo(algorithmIdentifier, key); return subjectPublicKeyInfo.getEncoded(); } catch (IOException e) { return null; } } public String getFormat() { // TODO Auto-generated method stub return null; } public McElieceCCA2Parameters getMcElieceCCA2Parameters() { return McElieceCCA2Params; } } bouncycastle-1.49.orig/src/org/bouncycastle/pqc/jcajce/provider/mceliece/McElieceKeyFactorySpi.java0000644000175000017500000003065512104637137033107 0ustar ebourgebourgpackage org.bouncycastle.pqc.jcajce.provider.mceliece; import java.io.IOException; import java.math.BigInteger; import java.security.InvalidKeyException; import java.security.Key; import java.security.KeyFactorySpi; import java.security.PrivateKey; import java.security.PublicKey; import java.security.spec.InvalidKeySpecException; import java.security.spec.KeySpec; import java.security.spec.PKCS8EncodedKeySpec; import java.security.spec.X509EncodedKeySpec; import org.bouncycastle.asn1.ASN1Integer; import org.bouncycastle.asn1.ASN1ObjectIdentifier; import org.bouncycastle.asn1.ASN1OctetString; import org.bouncycastle.asn1.ASN1Primitive; import org.bouncycastle.asn1.ASN1Sequence; import org.bouncycastle.asn1.pkcs.PrivateKeyInfo; import org.bouncycastle.asn1.x509.SubjectPublicKeyInfo; import org.bouncycastle.pqc.asn1.McEliecePrivateKey; import org.bouncycastle.pqc.asn1.McEliecePublicKey; import org.bouncycastle.pqc.jcajce.spec.McEliecePrivateKeySpec; import org.bouncycastle.pqc.jcajce.spec.McEliecePublicKeySpec; /** * This class is used to translate between McEliece keys and key specifications. * * @see BCMcEliecePrivateKey * @see McEliecePrivateKeySpec * @see BCMcEliecePublicKey * @see McEliecePublicKeySpec */ public class McElieceKeyFactorySpi extends KeyFactorySpi { /** * The OID of the algorithm. */ public static final String OID = "1.3.6.1.4.1.8301.3.1.3.4.1"; /** * Converts, if possible, a key specification into a * {@link BCMcEliecePublicKey}. Currently, the following key specifications * are supported: {@link McEliecePublicKeySpec}, {@link X509EncodedKeySpec}. * * @param keySpec the key specification * @return the McEliece public key * @throws InvalidKeySpecException if the key specification is not supported. */ public PublicKey generatePublic(KeySpec keySpec) throws InvalidKeySpecException { if (keySpec instanceof McEliecePublicKeySpec) { return new BCMcEliecePublicKey((McEliecePublicKeySpec)keySpec); } else if (keySpec instanceof X509EncodedKeySpec) { // get the DER-encoded Key according to X.509 from the spec byte[] encKey = ((X509EncodedKeySpec)keySpec).getEncoded(); // decode the SubjectPublicKeyInfo data structure to the pki object SubjectPublicKeyInfo pki; try { pki = SubjectPublicKeyInfo.getInstance(ASN1Primitive.fromByteArray(encKey)); } catch (IOException e) { throw new InvalidKeySpecException(e.toString()); } try { // --- Build and return the actual key. ASN1Primitive innerType = pki.parsePublicKey(); ASN1Sequence publicKey = (ASN1Sequence)innerType; // decode oidString (but we don't need it right now) String oidString = ((ASN1ObjectIdentifier)publicKey.getObjectAt(0)) .toString(); // decode BigInteger bigN = ((ASN1Integer)publicKey.getObjectAt(1)).getValue(); int n = bigN.intValue(); // decode BigInteger bigT = ((ASN1Integer)publicKey.getObjectAt(2)).getValue(); int t = bigT.intValue(); // decode byte[] matrixG = ((ASN1OctetString)publicKey.getObjectAt(3)).getOctets(); return new BCMcEliecePublicKey(new McEliecePublicKeySpec(OID, t, n, matrixG)); } catch (IOException cce) { throw new InvalidKeySpecException( "Unable to decode X509EncodedKeySpec: " + cce.getMessage()); } } throw new InvalidKeySpecException("Unsupported key specification: " + keySpec.getClass() + "."); } /** * Converts, if possible, a key specification into a * {@link BCMcEliecePrivateKey}. Currently, the following key specifications * are supported: {@link McEliecePrivateKeySpec}, * {@link PKCS8EncodedKeySpec}. * * @param keySpec the key specification * @return the McEliece private key * @throws InvalidKeySpecException if the KeySpec is not supported. */ public PrivateKey generatePrivate(KeySpec keySpec) throws InvalidKeySpecException { if (keySpec instanceof McEliecePrivateKeySpec) { return new BCMcEliecePrivateKey((McEliecePrivateKeySpec)keySpec); } else if (keySpec instanceof PKCS8EncodedKeySpec) { // get the DER-encoded Key according to PKCS#8 from the spec byte[] encKey = ((PKCS8EncodedKeySpec)keySpec).getEncoded(); // decode the PKCS#8 data structure to the pki object PrivateKeyInfo pki; try { pki = PrivateKeyInfo.getInstance(ASN1Primitive.fromByteArray(encKey)); } catch (IOException e) { throw new InvalidKeySpecException("Unable to decode PKCS8EncodedKeySpec: " + e); } try { ASN1Primitive innerType = pki.parsePrivateKey().toASN1Primitive(); // build and return the actual key ASN1Sequence privKey = (ASN1Sequence)innerType; // decode oidString (but we don't need it right now) String oidString = ((ASN1ObjectIdentifier)privKey.getObjectAt(0)) .toString(); // decode BigInteger bigN = ((ASN1Integer)privKey.getObjectAt(1)).getValue(); int n = bigN.intValue(); // decode BigInteger bigK = ((ASN1Integer)privKey.getObjectAt(2)).getValue(); int k = bigK.intValue(); // decode byte[] encFieldPoly = ((ASN1OctetString)privKey.getObjectAt(3)) .getOctets(); // decode byte[] encGoppaPoly = ((ASN1OctetString)privKey.getObjectAt(4)) .getOctets(); // decode byte[] encSInv = ((ASN1OctetString)privKey.getObjectAt(5)).getOctets(); // decode byte[] encP1 = ((ASN1OctetString)privKey.getObjectAt(6)).getOctets(); // decode byte[] encP2 = ((ASN1OctetString)privKey.getObjectAt(7)).getOctets(); //decode byte[] encH = ((ASN1OctetString)privKey.getObjectAt(8)).getOctets(); // decode ASN1Sequence qSeq = (ASN1Sequence)privKey.getObjectAt(9); byte[][] encQInv = new byte[qSeq.size()][]; for (int i = 0; i < qSeq.size(); i++) { encQInv[i] = ((ASN1OctetString)qSeq.getObjectAt(i)).getOctets(); } return new BCMcEliecePrivateKey(new McEliecePrivateKeySpec(OID, n, k, encFieldPoly, encGoppaPoly, encSInv, encP1, encP2, encH, encQInv)); } catch (IOException cce) { throw new InvalidKeySpecException( "Unable to decode PKCS8EncodedKeySpec."); } } throw new InvalidKeySpecException("Unsupported key specification: " + keySpec.getClass() + "."); } /** * Converts, if possible, a given key into a key specification. Currently, * the following key specifications are supported: *
      *
    • for McEliecePublicKey: {@link X509EncodedKeySpec}, * {@link McEliecePublicKeySpec}
    • *
    • for McEliecePrivateKey: {@link PKCS8EncodedKeySpec}, * {@link McEliecePrivateKeySpec}
    • . *
    * * @param key the key * @param keySpec the key specification * @return the specification of the McEliece key * @throws InvalidKeySpecException if the key type or the key specification is not * supported. * @see BCMcEliecePrivateKey * @see McEliecePrivateKeySpec * @see BCMcEliecePublicKey * @see McEliecePublicKeySpec */ public KeySpec getKeySpec(Key key, Class keySpec) throws InvalidKeySpecException { if (key instanceof BCMcEliecePrivateKey) { if (PKCS8EncodedKeySpec.class.isAssignableFrom(keySpec)) { return new PKCS8EncodedKeySpec(key.getEncoded()); } else if (McEliecePrivateKeySpec.class.isAssignableFrom(keySpec)) { BCMcEliecePrivateKey privKey = (BCMcEliecePrivateKey)key; return new McEliecePrivateKeySpec(OID, privKey.getN(), privKey .getK(), privKey.getField(), privKey.getGoppaPoly(), privKey.getSInv(), privKey.getP1(), privKey.getP2(), privKey.getH(), privKey.getQInv()); } } else if (key instanceof BCMcEliecePublicKey) { if (X509EncodedKeySpec.class.isAssignableFrom(keySpec)) { return new X509EncodedKeySpec(key.getEncoded()); } else if (McEliecePublicKeySpec.class.isAssignableFrom(keySpec)) { BCMcEliecePublicKey pubKey = (BCMcEliecePublicKey)key; return new McEliecePublicKeySpec(OID, pubKey.getN(), pubKey.getT(), pubKey.getG()); } } else { throw new InvalidKeySpecException("Unsupported key type: " + key.getClass() + "."); } throw new InvalidKeySpecException("Unknown key specification: " + keySpec + "."); } /** * Translates a key into a form known by the FlexiProvider. Currently, only * the following "source" keys are supported: {@link BCMcEliecePrivateKey}, * {@link BCMcEliecePublicKey}. * * @param key the key * @return a key of a known key type * @throws InvalidKeyException if the key type is not supported. */ public Key translateKey(Key key) throws InvalidKeyException { if ((key instanceof BCMcEliecePrivateKey) || (key instanceof BCMcEliecePublicKey)) { return key; } throw new InvalidKeyException("Unsupported key type."); } public PublicKey generatePublic(SubjectPublicKeyInfo pki) throws InvalidKeySpecException { // get the inner type inside the BIT STRING try { ASN1Primitive innerType = pki.parsePublicKey(); McEliecePublicKey key = McEliecePublicKey.getInstance(innerType); return new BCMcEliecePublicKey(key.getOID().getId(), key.getN(), key.getT(), key.getG()); } catch (IOException cce) { throw new InvalidKeySpecException("Unable to decode X509EncodedKeySpec"); } } public PrivateKey generatePrivate(PrivateKeyInfo pki) throws InvalidKeySpecException { // get the inner type inside the BIT STRING try { ASN1Primitive innerType = pki.parsePrivateKey().toASN1Primitive(); McEliecePrivateKey key = McEliecePrivateKey.getInstance(innerType); return new BCMcEliecePrivateKey(key.getOID().getId(), key.getN(), key.getK(), key.getField(), key.getGoppaPoly(), key.getSInv(), key.getP1(), key.getP2(), key.getH(), key.getQInv()); } catch (IOException cce) { throw new InvalidKeySpecException("Unable to decode PKCS8EncodedKeySpec"); } } protected PublicKey engineGeneratePublic(KeySpec keySpec) throws InvalidKeySpecException { return null; //To change body of implemented methods use File | Settings | File Templates. } protected PrivateKey engineGeneratePrivate(KeySpec keySpec) throws InvalidKeySpecException { return null; //To change body of implemented methods use File | Settings | File Templates. } protected KeySpec engineGetKeySpec(Key key, Class tClass) throws InvalidKeySpecException { return null; //To change body of implemented methods use File | Settings | File Templates. } protected Key engineTranslateKey(Key key) throws InvalidKeyException { return null; //To change body of implemented methods use File | Settings | File Templates. } } bouncycastle-1.49.orig/src/org/bouncycastle/pqc/jcajce/provider/mceliece/BCMcEliecePrivateKey.java0000644000175000017500000002260312104637137032635 0ustar ebourgebourgpackage org.bouncycastle.pqc.jcajce.provider.mceliece; import java.io.IOException; import java.security.PrivateKey; import org.bouncycastle.asn1.ASN1ObjectIdentifier; import org.bouncycastle.asn1.ASN1Primitive; import org.bouncycastle.asn1.DERNull; import org.bouncycastle.asn1.pkcs.PrivateKeyInfo; import org.bouncycastle.asn1.x509.AlgorithmIdentifier; import org.bouncycastle.crypto.CipherParameters; import org.bouncycastle.pqc.asn1.McEliecePrivateKey; import org.bouncycastle.pqc.crypto.mceliece.McElieceKeyPairGenerator; import org.bouncycastle.pqc.crypto.mceliece.McElieceParameters; import org.bouncycastle.pqc.crypto.mceliece.McEliecePrivateKeyParameters; import org.bouncycastle.pqc.jcajce.spec.McEliecePrivateKeySpec; import org.bouncycastle.pqc.math.linearalgebra.GF2Matrix; import org.bouncycastle.pqc.math.linearalgebra.GF2mField; import org.bouncycastle.pqc.math.linearalgebra.Permutation; import org.bouncycastle.pqc.math.linearalgebra.PolynomialGF2mSmallM; /** * This class implements a McEliece private key and is usually instantiated by * the {@link McElieceKeyPairGenerator} or {@link McElieceKeyFactorySpi}. */ public class BCMcEliecePrivateKey implements CipherParameters, PrivateKey { /** * */ private static final long serialVersionUID = 1L; // the OID of the algorithm private String oid; // the length of the code private int n; // the dimension of the code, where k >= n - mt private int k; // the underlying finite field private GF2mField field; // the irreducible Goppa polynomial private PolynomialGF2mSmallM goppaPoly; // the matrix S^-1 private GF2Matrix sInv; // the permutation P1 used to generate the systematic check matrix private Permutation p1; // the permutation P2 used to compute the public generator matrix private Permutation p2; // the canonical check matrix of the code private GF2Matrix h; // the matrix used to compute square roots in (GF(2^m))^t private PolynomialGF2mSmallM[] qInv; private McElieceParameters mcElieceParams; /** * Constructor (used by the {@link McElieceKeyPairGenerator}). * * @param oid * @param n the length of the code * @param k the dimension of the code * @param field the field polynomial defining the finite field * GF(2m) * @param goppaPoly the irreducible Goppa polynomial * @param sInv the matrix S-1 * @param p1 the permutation used to generate the systematic check * matrix * @param p2 the permutation used to compute the public generator * matrix * @param h the canonical check matrix * @param qInv the matrix used to compute square roots in * (GF(2m))t */ public BCMcEliecePrivateKey(String oid, int n, int k, GF2mField field, PolynomialGF2mSmallM goppaPoly, GF2Matrix sInv, Permutation p1, Permutation p2, GF2Matrix h, PolynomialGF2mSmallM[] qInv) { this.oid = oid; this.n = n; this.k = k; this.field = field; this.goppaPoly = goppaPoly; this.sInv = sInv; this.p1 = p1; this.p2 = p2; this.h = h; this.qInv = qInv; } /** * Constructor (used by the {@link McElieceKeyFactorySpi}). * * @param keySpec a {@link McEliecePrivateKeySpec} */ public BCMcEliecePrivateKey(McEliecePrivateKeySpec keySpec) { this(keySpec.getOIDString(), keySpec.getN(), keySpec.getK(), keySpec.getField(), keySpec .getGoppaPoly(), keySpec.getSInv(), keySpec.getP1(), keySpec .getP2(), keySpec.getH(), keySpec.getQInv()); } public BCMcEliecePrivateKey(McEliecePrivateKeyParameters params) { this(params.getOIDString(), params.getN(), params.getK(), params.getField(), params.getGoppaPoly(), params.getSInv(), params.getP1(), params.getP2(), params.getH(), params.getQInv()); this.mcElieceParams = params.getParameters(); } /** * Return the name of the algorithm. * * @return "McEliece" */ public String getAlgorithm() { return "McEliece"; } /** * @return the length of the code */ public int getN() { return n; } /** * @return the dimension of the code */ public int getK() { return k; } /** * @return the finite field */ public GF2mField getField() { return field; } /** * @return the irreducible Goppa polynomial */ public PolynomialGF2mSmallM getGoppaPoly() { return goppaPoly; } /** * @return the k x k random binary non-singular matrix S */ public GF2Matrix getSInv() { return sInv; } /** * @return the permutation used to generate the systematic check matrix */ public Permutation getP1() { return p1; } /** * @return the permutation used to compute the public generator matrix */ public Permutation getP2() { return p2; } /** * @return the canonical check matrix */ public GF2Matrix getH() { return h; } /** * @return the matrix for computing square roots in (GF(2^m))^t */ public PolynomialGF2mSmallM[] getQInv() { return qInv; } /** * @return the OID of the algorithm */ public String getOIDString() { return oid; } /** * @return a human readable form of the key */ public String toString() { String result = " length of the code : " + n + "\n"; result += " dimension of the code : " + k + "\n"; result += " irreducible Goppa polynomial: " + goppaPoly + "\n"; result += " (k x k)-matrix S^-1 : " + sInv + "\n"; result += " permutation P1 : " + p1 + "\n"; result += " permutation P2 : " + p2; return result; } /** * Compare this key with another object. * * @param other the other object * @return the result of the comparison */ public boolean equals(Object other) { if (!(other instanceof BCMcEliecePrivateKey)) { return false; } BCMcEliecePrivateKey otherKey = (BCMcEliecePrivateKey)other; return (n == otherKey.n) && (k == otherKey.k) && field.equals(otherKey.field) && goppaPoly.equals(otherKey.goppaPoly) && sInv.equals(otherKey.sInv) && p1.equals(otherKey.p1) && p2.equals(otherKey.p2) && h.equals(otherKey.h); } /** * @return the hash code of this key */ public int hashCode() { return k + n + field.hashCode() + goppaPoly.hashCode() + sInv.hashCode() + p1.hashCode() + p2.hashCode() + h.hashCode(); } /** * @return the OID to encode in the SubjectPublicKeyInfo structure */ protected ASN1ObjectIdentifier getOID() { return new ASN1ObjectIdentifier(McElieceKeyFactorySpi.OID); } /** * @return the algorithm parameters to encode in the SubjectPublicKeyInfo * structure */ protected ASN1Primitive getAlgParams() { return null; // FIXME: needed at all? } /** * Return the key data to encode in the SubjectPublicKeyInfo structure. *

    * The ASN.1 definition of the key structure is *

    *

         *   McEliecePrivateKey ::= SEQUENCE {
         *     n          INTEGER                   -- length of the code
         *     k          INTEGER                   -- dimension of the code
         *     fieldPoly  OCTET STRING              -- field polynomial defining GF(2ˆm)
         *     goppaPoly  OCTET STRING              -- irreducible Goppa polynomial
         *     sInv       OCTET STRING              -- matrix Sˆ-1
         *     p1         OCTET STRING              -- permutation P1
         *     p2         OCTET STRING              -- permutation P2
         *     h          OCTET STRING              -- canonical check matrix
         *     qInv       SEQUENCE OF OCTET STRING  -- matrix used to compute square roots
         *   }
         * 
    * * @return the key data to encode in the SubjectPublicKeyInfo structure */ public byte[] getEncoded() { McEliecePrivateKey privateKey = new McEliecePrivateKey(new ASN1ObjectIdentifier(oid), n, k, field, goppaPoly, sInv, p1, p2, h, qInv); PrivateKeyInfo pki; try { AlgorithmIdentifier algorithmIdentifier = new AlgorithmIdentifier(this.getOID(), DERNull.INSTANCE); pki = new PrivateKeyInfo(algorithmIdentifier, privateKey); } catch (IOException e) { e.printStackTrace(); return null; } try { byte[] encoded = pki.getEncoded(); return encoded; } catch (IOException e) { e.printStackTrace(); return null; } } public String getFormat() { // TODO Auto-generated method stub return null; } public McElieceParameters getMcElieceParameters() { return mcElieceParams; } } bouncycastle-1.49.orig/src/org/bouncycastle/pqc/jcajce/provider/mceliece/BCMcEliecePublicKey.java0000644000175000017500000001315112104637137032437 0ustar ebourgebourgpackage org.bouncycastle.pqc.jcajce.provider.mceliece; import java.io.IOException; import java.security.PublicKey; import org.bouncycastle.asn1.ASN1ObjectIdentifier; import org.bouncycastle.asn1.ASN1Primitive; import org.bouncycastle.asn1.DERNull; import org.bouncycastle.asn1.x509.AlgorithmIdentifier; import org.bouncycastle.asn1.x509.SubjectPublicKeyInfo; import org.bouncycastle.crypto.CipherParameters; import org.bouncycastle.pqc.asn1.McEliecePublicKey; import org.bouncycastle.pqc.crypto.mceliece.McElieceKeyPairGenerator; import org.bouncycastle.pqc.crypto.mceliece.McElieceParameters; import org.bouncycastle.pqc.crypto.mceliece.McEliecePublicKeyParameters; import org.bouncycastle.pqc.jcajce.spec.McEliecePublicKeySpec; import org.bouncycastle.pqc.math.linearalgebra.GF2Matrix; /** * This class implements a McEliece public key and is usually instantiated by * the {@link McElieceKeyPairGenerator} or {@link McElieceKeyFactorySpi}. */ public class BCMcEliecePublicKey implements CipherParameters, PublicKey { /** * */ private static final long serialVersionUID = 1L; // the OID of the algorithm private String oid; /** * the length of the code */ private int n; /** * the error correction capability of the code */ private int t; /** * the generator matrix */ private GF2Matrix g; private McElieceParameters McElieceParams; /** * Constructor (used by the {@link McElieceKeyPairGenerator}). * * @param oid * @param n the length of the code * @param t the error correction capability of the code * @param g the generator matrix */ public BCMcEliecePublicKey(String oid, int n, int t, GF2Matrix g) { this.oid = oid; this.n = n; this.t = t; this.g = g; } /** * Constructor (used by the {@link McElieceKeyFactorySpi}). * * @param keySpec a {@link McEliecePublicKeySpec} */ public BCMcEliecePublicKey(McEliecePublicKeySpec keySpec) { this(keySpec.getOIDString(), keySpec.getN(), keySpec.getT(), keySpec.getG()); } public BCMcEliecePublicKey(McEliecePublicKeyParameters params) { this(params.getOIDString(), params.getN(), params.getT(), params.getG()); this.McElieceParams = params.getParameters(); } /** * Return the name of the algorithm. * * @return "McEliece" */ public String getAlgorithm() { return "McEliece"; } /** * @return the length of the code */ public int getN() { return n; } /** * @return the dimension of the code */ public int getK() { return g.getNumRows(); } /** * @return the error correction capability of the code */ public int getT() { return t; } /** * @return the generator matrix */ public GF2Matrix getG() { return g; } /** * @return a human readable form of the key */ public String toString() { String result = "McEliecePublicKey:\n"; result += " length of the code : " + n + "\n"; result += " error correction capability: " + t + "\n"; result += " generator matrix : " + g.toString(); return result; } /** * Compare this key with another object. * * @param other the other object * @return the result of the comparison */ public boolean equals(Object other) { if (!(other instanceof BCMcEliecePublicKey)) { return false; } BCMcEliecePublicKey otherKey = (BCMcEliecePublicKey)other; return (n == otherKey.n) && (t == otherKey.t) && g.equals(otherKey.g); } /** * @return the hash code of this key */ public int hashCode() { return n + t + g.hashCode(); } /** * @return the OID of the algorithm */ public String getOIDString() { return oid; } /** * @return the OID to encode in the SubjectPublicKeyInfo structure */ protected ASN1ObjectIdentifier getOID() { return new ASN1ObjectIdentifier(McElieceKeyFactorySpi.OID); } /** * @return the algorithm parameters to encode in the SubjectPublicKeyInfo * structure */ protected ASN1Primitive getAlgParams() { return null; // FIXME: needed at all? } /** * Return the keyData to encode in the SubjectPublicKeyInfo structure. *

    * The ASN.1 definition of the key structure is *

    *

         *       McEliecePublicKey ::= SEQUENCE {
         *         n           Integer      -- length of the code
         *         t           Integer      -- error correcting capability
         *         matrixG     OctetString  -- generator matrix as octet string
         *       }
         * 
    * * @return the keyData to encode in the SubjectPublicKeyInfo structure */ public byte[] getEncoded() { McEliecePublicKey key = new McEliecePublicKey(new ASN1ObjectIdentifier(oid), n, t, g); AlgorithmIdentifier algorithmIdentifier = new AlgorithmIdentifier(this.getOID(), DERNull.INSTANCE); try { SubjectPublicKeyInfo subjectPublicKeyInfo = new SubjectPublicKeyInfo(algorithmIdentifier, key); return subjectPublicKeyInfo.getEncoded(); } catch (IOException e) { return null; } } public String getFormat() { return null; } public McElieceParameters getMcElieceParameters() { return McElieceParams; } } ././@LongLink0000000000000000000000000000014700000000000011567 Lustar rootrootbouncycastle-1.49.orig/src/org/bouncycastle/pqc/jcajce/provider/mceliece/McElieceCCA2KeysToParams.javabouncycastle-1.49.orig/src/org/bouncycastle/pqc/jcajce/provider/mceliece/McElieceCCA2KeysToParams.ja0000644000175000017500000000317612045616616033000 0ustar ebourgebourgpackage org.bouncycastle.pqc.jcajce.provider.mceliece; import java.security.InvalidKeyException; import java.security.PrivateKey; import java.security.PublicKey; import org.bouncycastle.crypto.params.AsymmetricKeyParameter; import org.bouncycastle.pqc.crypto.mceliece.McElieceCCA2PrivateKeyParameters; import org.bouncycastle.pqc.crypto.mceliece.McElieceCCA2PublicKeyParameters; /** * utility class for converting jce/jca McElieceCCA2 objects * objects into their org.bouncycastle.crypto counterparts. */ public class McElieceCCA2KeysToParams { static public AsymmetricKeyParameter generatePublicKeyParameter( PublicKey key) throws InvalidKeyException { if (key instanceof BCMcElieceCCA2PublicKey) { BCMcElieceCCA2PublicKey k = (BCMcElieceCCA2PublicKey)key; return new McElieceCCA2PublicKeyParameters(k.getOIDString(), k.getN(), k.getT(), k.getG(), k.getMcElieceCCA2Parameters()); } throw new InvalidKeyException("can't identify McElieceCCA2 public key: " + key.getClass().getName()); } static public AsymmetricKeyParameter generatePrivateKeyParameter( PrivateKey key) throws InvalidKeyException { if (key instanceof BCMcElieceCCA2PrivateKey) { BCMcElieceCCA2PrivateKey k = (BCMcElieceCCA2PrivateKey)key; return new McElieceCCA2PrivateKeyParameters(k.getOIDString(), k.getN(), k.getK(), k.getField(), k.getGoppaPoly(), k.getP(), k.getH(), k.getQInv(), k.getMcElieceCCA2Parameters()); } throw new InvalidKeyException("can't identify McElieceCCA2 private key."); } } ././@LongLink0000000000000000000000000000014700000000000011567 Lustar rootrootbouncycastle-1.49.orig/src/org/bouncycastle/pqc/jcajce/provider/mceliece/BCMcElieceCCA2PrivateKey.javabouncycastle-1.49.orig/src/org/bouncycastle/pqc/jcajce/provider/mceliece/BCMcElieceCCA2PrivateKey.ja0000644000175000017500000002031712104633515032673 0ustar ebourgebourgpackage org.bouncycastle.pqc.jcajce.provider.mceliece; import java.io.IOException; import java.security.PrivateKey; import org.bouncycastle.asn1.ASN1ObjectIdentifier; import org.bouncycastle.asn1.ASN1Primitive; import org.bouncycastle.asn1.DERNull; import org.bouncycastle.asn1.pkcs.PrivateKeyInfo; import org.bouncycastle.asn1.x509.AlgorithmIdentifier; import org.bouncycastle.crypto.CipherParameters; import org.bouncycastle.pqc.asn1.McElieceCCA2PrivateKey; import org.bouncycastle.pqc.crypto.mceliece.McElieceCCA2KeyPairGenerator; import org.bouncycastle.pqc.crypto.mceliece.McElieceCCA2Parameters; import org.bouncycastle.pqc.crypto.mceliece.McElieceCCA2PrivateKeyParameters; import org.bouncycastle.pqc.jcajce.spec.McElieceCCA2PrivateKeySpec; import org.bouncycastle.pqc.math.linearalgebra.GF2Matrix; import org.bouncycastle.pqc.math.linearalgebra.GF2mField; import org.bouncycastle.pqc.math.linearalgebra.Permutation; import org.bouncycastle.pqc.math.linearalgebra.PolynomialGF2mSmallM; /** * This class implements a McEliece CCA2 private key and is usually instantiated * by the {@link McElieceCCA2KeyPairGenerator} or {@link McElieceCCA2KeyFactorySpi}. * * @see McElieceCCA2KeyPairGenerator */ public class BCMcElieceCCA2PrivateKey implements CipherParameters, PrivateKey { /** * */ private static final long serialVersionUID = 1L; // the OID of the algorithm private String oid; // the length of the code private int n; // the dimension of the code, k>=n-mt private int k; // the finte field GF(2^m) private GF2mField field; // the irreducible Goppa polynomial private PolynomialGF2mSmallM goppaPoly; // the permutation private Permutation p; // the canonical check matrix private GF2Matrix h; // the matrix used to compute square roots in (GF(2^m))^t private PolynomialGF2mSmallM[] qInv; private McElieceCCA2Parameters mcElieceCCA2Params; /** * Constructor (used by the {@link McElieceCCA2KeyPairGenerator}). * * @param n the length of the code * @param k the dimension of the code * @param field the field polynomial * @param gp the irreducible Goppa polynomial * @param p the permutation * @param h the canonical check matrix * @param qInv the matrix used to compute square roots in * (GF(2^m))^t */ public BCMcElieceCCA2PrivateKey(String oid, int n, int k, GF2mField field, PolynomialGF2mSmallM gp, Permutation p, GF2Matrix h, PolynomialGF2mSmallM[] qInv) { this.oid = oid; this.n = n; this.k = k; this.field = field; this.goppaPoly = gp; this.p = p; this.h = h; this.qInv = qInv; } /** * Constructor (used by the {@link McElieceCCA2KeyFactorySpi}). * * @param keySpec a {@link McElieceCCA2PrivateKeySpec} */ public BCMcElieceCCA2PrivateKey(McElieceCCA2PrivateKeySpec keySpec) { this(keySpec.getOIDString(), keySpec.getN(), keySpec.getK(), keySpec.getField(), keySpec .getGoppaPoly(), keySpec.getP(), keySpec.getH(), keySpec .getQInv()); } public BCMcElieceCCA2PrivateKey(McElieceCCA2PrivateKeyParameters params) { this(params.getOIDString(), params.getN(), params.getK(), params.getField(), params.getGoppaPoly(), params.getP(), params.getH(), params.getQInv()); this.mcElieceCCA2Params = params.getParameters(); } /** * Return the name of the algorithm. * * @return "McEliece" */ public String getAlgorithm() { return "McEliece"; } /** * @return the length of the code */ public int getN() { return n; } /** * @return the dimension of the code */ public int getK() { return k; } /** * @return the degree of the Goppa polynomial (error correcting capability) */ public int getT() { return goppaPoly.getDegree(); } /** * @return the finite field */ public GF2mField getField() { return field; } /** * @return the irreducible Goppa polynomial */ public PolynomialGF2mSmallM getGoppaPoly() { return goppaPoly; } /** * @return the permutation vector */ public Permutation getP() { return p; } /** * @return the canonical check matrix */ public GF2Matrix getH() { return h; } /** * @return the matrix used to compute square roots in (GF(2^m))^t */ public PolynomialGF2mSmallM[] getQInv() { return qInv; } /** * @return a human readable form of the key */ public String toString() { String result = ""; result += " extension degree of the field : " + n + "\n"; result += " dimension of the code : " + k + "\n"; result += " irreducible Goppa polynomial : " + goppaPoly + "\n"; return result; } /** * Compare this key with another object. * * @param other the other object * @return the result of the comparison */ public boolean equals(Object other) { if (other == null || !(other instanceof BCMcElieceCCA2PrivateKey)) { return false; } BCMcElieceCCA2PrivateKey otherKey = (BCMcElieceCCA2PrivateKey)other; return (n == otherKey.n) && (k == otherKey.k) && field.equals(otherKey.field) && goppaPoly.equals(otherKey.goppaPoly) && p.equals(otherKey.p) && h.equals(otherKey.h); } /** * @return the hash code of this key */ public int hashCode() { return k + n + field.hashCode() + goppaPoly.hashCode() + p.hashCode() + h.hashCode(); } /** * @return the OID of the algorithm */ public String getOIDString() { return oid; } /** * @return the OID to encode in the SubjectPublicKeyInfo structure */ protected ASN1ObjectIdentifier getOID() { return new ASN1ObjectIdentifier(McElieceCCA2KeyFactorySpi.OID); } /** * @return the algorithm parameters to encode in the SubjectPublicKeyInfo * structure */ protected ASN1Primitive getAlgParams() { return null; // FIXME: needed at all? } /** * Return the keyData to encode in the SubjectPublicKeyInfo structure. *

    * The ASN.1 definition of the key structure is *

    *

         *   McEliecePrivateKey ::= SEQUENCE {
         *     m             INTEGER                  -- extension degree of the field
         *     k             INTEGER                  -- dimension of the code
         *     field         OCTET STRING             -- field polynomial
         *     goppaPoly     OCTET STRING             -- irreducible Goppa polynomial
         *     p             OCTET STRING             -- permutation vector
         *     matrixH       OCTET STRING             -- canonical check matrix
         *     sqRootMatrix  SEQUENCE OF OCTET STRING -- square root matrix
         *   }
         * 
    * * @return the keyData to encode in the SubjectPublicKeyInfo structure */ public byte[] getEncoded() { McElieceCCA2PrivateKey privateKey = new McElieceCCA2PrivateKey(new ASN1ObjectIdentifier(oid), n, k, field, goppaPoly, p, h, qInv); PrivateKeyInfo pki; try { AlgorithmIdentifier algorithmIdentifier = new AlgorithmIdentifier(this.getOID(), DERNull.INSTANCE); pki = new PrivateKeyInfo(algorithmIdentifier, privateKey); } catch (IOException e) { e.printStackTrace(); return null; } try { byte[] encoded = pki.getEncoded(); return encoded; } catch (IOException e) { e.printStackTrace(); return null; } } public String getFormat() { // TODO Auto-generated method stub return null; } public McElieceCCA2Parameters getMcElieceCCA2Parameters() { return mcElieceCCA2Params; } } ././@LongLink0000000000000000000000000000015200000000000011563 Lustar rootrootbouncycastle-1.49.orig/src/org/bouncycastle/pqc/jcajce/provider/mceliece/McElieceKobaraImaiCipherSpi.javabouncycastle-1.49.orig/src/org/bouncycastle/pqc/jcajce/provider/mceliece/McElieceKobaraImaiCipherSpi0000644000175000017500000002055012057027464033235 0ustar ebourgebourgpackage org.bouncycastle.pqc.jcajce.provider.mceliece; import java.io.ByteArrayOutputStream; import java.security.InvalidAlgorithmParameterException; import java.security.InvalidKeyException; import java.security.Key; import java.security.NoSuchAlgorithmException; import java.security.PrivateKey; import java.security.PublicKey; import java.security.SecureRandom; import java.security.spec.AlgorithmParameterSpec; import javax.crypto.BadPaddingException; import javax.crypto.IllegalBlockSizeException; import org.bouncycastle.asn1.pkcs.PKCSObjectIdentifiers; import org.bouncycastle.asn1.x509.X509ObjectIdentifiers; import org.bouncycastle.crypto.CipherParameters; import org.bouncycastle.crypto.Digest; import org.bouncycastle.crypto.digests.SHA1Digest; import org.bouncycastle.crypto.digests.SHA224Digest; import org.bouncycastle.crypto.digests.SHA256Digest; import org.bouncycastle.crypto.digests.SHA384Digest; import org.bouncycastle.crypto.digests.SHA512Digest; import org.bouncycastle.crypto.params.ParametersWithRandom; import org.bouncycastle.pqc.crypto.mceliece.McElieceCCA2KeyParameters; import org.bouncycastle.pqc.crypto.mceliece.McElieceKobaraImaiCipher; import org.bouncycastle.pqc.jcajce.provider.util.AsymmetricHybridCipher; public class McElieceKobaraImaiCipherSpi extends AsymmetricHybridCipher implements PKCSObjectIdentifiers, X509ObjectIdentifiers { // TODO digest needed? private Digest digest; private McElieceKobaraImaiCipher cipher; /** * buffer to store the input data */ private ByteArrayOutputStream buf = new ByteArrayOutputStream(); public McElieceKobaraImaiCipherSpi() { buf = new ByteArrayOutputStream(); } protected McElieceKobaraImaiCipherSpi(Digest digest, McElieceKobaraImaiCipher cipher) { this.digest = digest; this.cipher = cipher; buf = new ByteArrayOutputStream(); } /** * Continue a multiple-part encryption or decryption operation. * * @param input byte array containing the next part of the input * @param inOff index in the array where the input starts * @param inLen length of the input * @return the processed byte array. */ public byte[] update(byte[] input, int inOff, int inLen) { buf.write(input, inOff, inLen); return new byte[0]; } /** * Encrypts or decrypts data in a single-part operation, or finishes a * multiple-part operation. The data is encrypted or decrypted, depending on * how this cipher was initialized. * * @param input the input buffer * @param inOff the offset in input where the input starts * @param inLen the input length * @return the new buffer with the result * @throws BadPaddingException if this cipher is in decryption mode, and (un)padding has * been requested, but the decrypted data is not bounded by * the appropriate padding bytes */ public byte[] doFinal(byte[] input, int inOff, int inLen) throws BadPaddingException { update(input, inOff, inLen); if (opMode == ENCRYPT_MODE) { try { return cipher.messageEncrypt(this.pad()); } catch (Exception e) { e.printStackTrace(); } } else if (opMode == DECRYPT_MODE) { byte[] inputOfDecr = buf.toByteArray(); buf.reset(); try { return unpad(cipher.messageDecrypt(inputOfDecr)); } catch (Exception e) { e.printStackTrace(); } } return null; } protected int encryptOutputSize(int inLen) { return 0; } protected int decryptOutputSize(int inLen) { return 0; } protected void initCipherEncrypt(Key key, AlgorithmParameterSpec params, SecureRandom sr) throws InvalidKeyException, InvalidAlgorithmParameterException { buf.reset(); CipherParameters param; param = McElieceCCA2KeysToParams.generatePublicKeyParameter((PublicKey)key); param = new ParametersWithRandom(param, sr); digest.reset(); cipher.init(true, param); } protected void initCipherDecrypt(Key key, AlgorithmParameterSpec params) throws InvalidKeyException, InvalidAlgorithmParameterException { buf.reset(); CipherParameters param; param = McElieceCCA2KeysToParams.generatePrivateKeyParameter((PrivateKey)key); digest.reset(); cipher.init(false, param); } public String getName() { return "McElieceKobaraImaiCipher"; } public int getKeySize(Key key) throws InvalidKeyException { McElieceCCA2KeyParameters mcElieceCCA2KeyParameters; if (key instanceof PublicKey) { mcElieceCCA2KeyParameters = (McElieceCCA2KeyParameters)McElieceCCA2KeysToParams.generatePublicKeyParameter((PublicKey)key); return cipher.getKeySize(mcElieceCCA2KeyParameters); } else if (key instanceof PrivateKey) { mcElieceCCA2KeyParameters = (McElieceCCA2KeyParameters)McElieceCCA2KeysToParams.generatePrivateKeyParameter((PrivateKey)key); return cipher.getKeySize(mcElieceCCA2KeyParameters); } else { throw new InvalidKeyException(); } } /** * Pad and return the message stored in the message buffer. * * @return the padded message */ private byte[] pad() { buf.write(0x01); byte[] result = buf.toByteArray(); buf.reset(); return result; } /** * Unpad a message. * * @param pmBytes the padded message * @return the message * @throws BadPaddingException if the padded message is invalid. */ private byte[] unpad(byte[] pmBytes) throws BadPaddingException { // find first non-zero byte int index; for (index = pmBytes.length - 1; index >= 0 && pmBytes[index] == 0; index--) { ; } // check if padding byte is valid if (pmBytes[index] != 0x01) { throw new BadPaddingException("invalid ciphertext"); } // extract and return message byte[] mBytes = new byte[index]; System.arraycopy(pmBytes, 0, mBytes, 0, index); return mBytes; } public byte[] messageEncrypt() throws IllegalBlockSizeException, BadPaddingException, NoSuchAlgorithmException { byte[] output = null; try { output = cipher.messageEncrypt((this.pad())); } catch (Exception e) { e.printStackTrace(); } return output; } public byte[] messageDecrypt() throws IllegalBlockSizeException, BadPaddingException, NoSuchAlgorithmException { byte[] output = null; byte[] inputOfDecr = buf.toByteArray(); buf.reset(); try { output = unpad(cipher.messageDecrypt(inputOfDecr)); } catch (Exception e) { e.printStackTrace(); } return output; } static public class McElieceKobaraImai extends McElieceKobaraImaiCipherSpi { public McElieceKobaraImai() { super(new SHA1Digest(), new McElieceKobaraImaiCipher()); } } static public class McElieceKobaraImai224 extends McElieceKobaraImaiCipherSpi { public McElieceKobaraImai224() { super(new SHA224Digest(), new McElieceKobaraImaiCipher()); } } static public class McElieceKobaraImai256 extends McElieceKobaraImaiCipherSpi { public McElieceKobaraImai256() { super(new SHA256Digest(), new McElieceKobaraImaiCipher()); } } static public class McElieceKobaraImai384 extends McElieceKobaraImaiCipherSpi { public McElieceKobaraImai384() { super(new SHA384Digest(), new McElieceKobaraImaiCipher()); } } static public class McElieceKobaraImai512 extends McElieceKobaraImaiCipherSpi { public McElieceKobaraImai512() { super(new SHA512Digest(), new McElieceKobaraImaiCipher()); } } } bouncycastle-1.49.orig/src/org/bouncycastle/pqc/jcajce/provider/rainbow/0000755000175000017500000000000012152033551025774 5ustar ebourgebourg././@LongLink0000000000000000000000000000015000000000000011561 Lustar rootrootbouncycastle-1.49.orig/src/org/bouncycastle/pqc/jcajce/provider/rainbow/RainbowKeyPairGeneratorSpi.javabouncycastle-1.49.orig/src/org/bouncycastle/pqc/jcajce/provider/rainbow/RainbowKeyPairGeneratorSpi.j0000644000175000017500000000460611776712151033401 0ustar ebourgebourgpackage org.bouncycastle.pqc.jcajce.provider.rainbow; import java.security.InvalidAlgorithmParameterException; import java.security.KeyPair; import java.security.SecureRandom; import java.security.spec.AlgorithmParameterSpec; import org.bouncycastle.crypto.AsymmetricCipherKeyPair; import org.bouncycastle.pqc.crypto.rainbow.RainbowKeyGenerationParameters; import org.bouncycastle.pqc.crypto.rainbow.RainbowKeyPairGenerator; import org.bouncycastle.pqc.crypto.rainbow.RainbowParameters; import org.bouncycastle.pqc.crypto.rainbow.RainbowPrivateKeyParameters; import org.bouncycastle.pqc.crypto.rainbow.RainbowPublicKeyParameters; import org.bouncycastle.pqc.jcajce.spec.RainbowParameterSpec; public class RainbowKeyPairGeneratorSpi extends java.security.KeyPairGenerator { RainbowKeyGenerationParameters param; RainbowKeyPairGenerator engine = new RainbowKeyPairGenerator(); int strength = 1024; SecureRandom random = new SecureRandom(); boolean initialised = false; public RainbowKeyPairGeneratorSpi() { super("Rainbow"); } public void initialize( int strength, SecureRandom random) { this.strength = strength; this.random = random; } public void initialize( AlgorithmParameterSpec params, SecureRandom random) throws InvalidAlgorithmParameterException { if (!(params instanceof RainbowParameterSpec)) { throw new InvalidAlgorithmParameterException("parameter object not a RainbowParameterSpec"); } RainbowParameterSpec rainbowParams = (RainbowParameterSpec)params; param = new RainbowKeyGenerationParameters(random, new RainbowParameters(rainbowParams.getVi())); engine.init(param); initialised = true; } public KeyPair generateKeyPair() { if (!initialised) { param = new RainbowKeyGenerationParameters(random, new RainbowParameters(new RainbowParameterSpec().getVi())); engine.init(param); initialised = true; } AsymmetricCipherKeyPair pair = engine.generateKeyPair(); RainbowPublicKeyParameters pub = (RainbowPublicKeyParameters)pair.getPublic(); RainbowPrivateKeyParameters priv = (RainbowPrivateKeyParameters)pair.getPrivate(); return new KeyPair(new BCRainbowPublicKey(pub), new BCRainbowPrivateKey(priv)); } } bouncycastle-1.49.orig/src/org/bouncycastle/pqc/jcajce/provider/rainbow/SignatureSpi.java0000644000175000017500000001020412151551720031253 0ustar ebourgebourgpackage org.bouncycastle.pqc.jcajce.provider.rainbow; import java.security.InvalidKeyException; import java.security.PrivateKey; import java.security.PublicKey; import java.security.SecureRandom; import java.security.SignatureException; import java.security.spec.AlgorithmParameterSpec; import org.bouncycastle.crypto.CipherParameters; import org.bouncycastle.crypto.Digest; import org.bouncycastle.crypto.digests.SHA224Digest; import org.bouncycastle.crypto.digests.SHA256Digest; import org.bouncycastle.crypto.digests.SHA384Digest; import org.bouncycastle.crypto.digests.SHA512Digest; import org.bouncycastle.crypto.params.ParametersWithRandom; import org.bouncycastle.pqc.crypto.rainbow.RainbowSigner; /** * Rainbow Signature class, extending the jce SignatureSpi. */ public class SignatureSpi extends java.security.SignatureSpi { private Digest digest; private RainbowSigner signer; private SecureRandom random; protected SignatureSpi(Digest digest, RainbowSigner signer) { this.digest = digest; this.signer = signer; } protected void engineInitVerify(PublicKey publicKey) throws InvalidKeyException { CipherParameters param; param = RainbowKeysToParams.generatePublicKeyParameter(publicKey); digest.reset(); signer.init(false, param); } protected void engineInitSign(PrivateKey privateKey, SecureRandom random) throws InvalidKeyException { this.random = random; engineInitSign(privateKey); } protected void engineInitSign(PrivateKey privateKey) throws InvalidKeyException { CipherParameters param; param = RainbowKeysToParams.generatePrivateKeyParameter(privateKey); if (random != null) { param = new ParametersWithRandom(param, random); } digest.reset(); signer.init(true, param); } protected void engineUpdate(byte b) throws SignatureException { digest.update(b); } protected void engineUpdate(byte[] b, int off, int len) throws SignatureException { digest.update(b, off, len); } protected byte[] engineSign() throws SignatureException { byte[] hash = new byte[digest.getDigestSize()]; digest.doFinal(hash, 0); try { byte[] sig = signer.generateSignature(hash); return sig; } catch (Exception e) { throw new SignatureException(e.toString()); } } protected boolean engineVerify(byte[] sigBytes) throws SignatureException { byte[] hash = new byte[digest.getDigestSize()]; digest.doFinal(hash, 0); return signer.verifySignature(hash, sigBytes); } protected void engineSetParameter(AlgorithmParameterSpec params) { throw new UnsupportedOperationException("engineSetParameter unsupported"); } /** * @deprecated replaced with */ protected void engineSetParameter(String param, Object value) { throw new UnsupportedOperationException("engineSetParameter unsupported"); } /** * @deprecated */ protected Object engineGetParameter(String param) { throw new UnsupportedOperationException("engineSetParameter unsupported"); } static public class withSha224 extends SignatureSpi { public withSha224() { super(new SHA224Digest(), new RainbowSigner()); } } static public class withSha256 extends SignatureSpi { public withSha256() { super(new SHA256Digest(), new RainbowSigner()); } } static public class withSha384 extends SignatureSpi { public withSha384() { super(new SHA384Digest(), new RainbowSigner()); } } static public class withSha512 extends SignatureSpi { public withSha512() { super(new SHA512Digest(), new RainbowSigner()); } } } bouncycastle-1.49.orig/src/org/bouncycastle/pqc/jcajce/provider/rainbow/RainbowKeyFactorySpi.java0000644000175000017500000002077412151251423032726 0ustar ebourgebourgpackage org.bouncycastle.pqc.jcajce.provider.rainbow; import java.io.IOException; import java.security.InvalidKeyException; import java.security.Key; import java.security.KeyFactorySpi; import java.security.PrivateKey; import java.security.PublicKey; import java.security.spec.InvalidKeySpecException; import java.security.spec.KeySpec; import java.security.spec.PKCS8EncodedKeySpec; import java.security.spec.X509EncodedKeySpec; import org.bouncycastle.asn1.ASN1Primitive; import org.bouncycastle.asn1.pkcs.PrivateKeyInfo; import org.bouncycastle.asn1.x509.SubjectPublicKeyInfo; import org.bouncycastle.jcajce.provider.util.AsymmetricKeyInfoConverter; import org.bouncycastle.pqc.asn1.RainbowPrivateKey; import org.bouncycastle.pqc.asn1.RainbowPublicKey; import org.bouncycastle.pqc.jcajce.spec.RainbowPrivateKeySpec; import org.bouncycastle.pqc.jcajce.spec.RainbowPublicKeySpec; /** * This class transforms Rainbow keys and Rainbow key specifications. * * @see BCRainbowPublicKey * @see RainbowPublicKeySpec * @see BCRainbowPrivateKey * @see RainbowPrivateKeySpec */ public class RainbowKeyFactorySpi extends KeyFactorySpi implements AsymmetricKeyInfoConverter { /** * Converts, if possible, a key specification into a * {@link BCRainbowPrivateKey}. Currently, the following key specifications * are supported: {@link RainbowPrivateKeySpec}, {@link PKCS8EncodedKeySpec}. *

    *

    *

    * The ASN.1 definition of the key structure is *

    *

         *   RainbowPrivateKey ::= SEQUENCE {
         *     oid        OBJECT IDENTIFIER         -- OID identifying the algorithm
         *     A1inv      SEQUENCE OF OCTET STRING  -- inversed matrix of L1
         *     b1         OCTET STRING              -- translation vector of L1
         *     A2inv      SEQUENCE OF OCTET STRING  -- inversed matrix of L2
         *     b2         OCTET STRING              -- translation vector of L2
         *     vi         OCTET STRING              -- num of elmts in each Set S
         *     layers     SEQUENCE OF Layer         -- layers of F
         *   }
         *
         *   Layer             ::= SEQUENCE OF Poly
         *   Poly              ::= SEQUENCE {
         *     alpha      SEQUENCE OF OCTET STRING
         *     beta       SEQUENCE OF OCTET STRING
         *     gamma      OCTET STRING
         *     eta        OCTET
         *   }
         * 
    *

    *

    * * @param keySpec the key specification * @return the Rainbow private key * @throws InvalidKeySpecException if the KeySpec is not supported. */ public PrivateKey engineGeneratePrivate(KeySpec keySpec) throws InvalidKeySpecException { if (keySpec instanceof RainbowPrivateKeySpec) { return new BCRainbowPrivateKey((RainbowPrivateKeySpec)keySpec); } else if (keySpec instanceof PKCS8EncodedKeySpec) { // get the DER-encoded Key according to PKCS#8 from the spec byte[] encKey = ((PKCS8EncodedKeySpec)keySpec).getEncoded(); try { return generatePrivate(PrivateKeyInfo.getInstance(ASN1Primitive.fromByteArray(encKey))); } catch (Exception e) { throw new InvalidKeySpecException(e.toString()); } } throw new InvalidKeySpecException("Unsupported key specification: " + keySpec.getClass() + "."); } /** * Converts, if possible, a key specification into a * {@link BCRainbowPublicKey}. Currently, the following key specifications are * supported:{@link X509EncodedKeySpec}. *

    *

    *

    * The ASN.1 definition of a public key's structure is *

    *

         *    RainbowPublicKey ::= SEQUENCE {
         *      oid            OBJECT IDENTIFIER        -- OID identifying the algorithm
         *      docLength      Integer                  -- length of signable msg
         *      coeffquadratic SEQUENCE OF OCTET STRING -- quadratic (mixed) coefficients
         *      coeffsingular  SEQUENCE OF OCTET STRING -- singular coefficients
         *      coeffscalar       OCTET STRING             -- scalar coefficients
         *       }
         * 
    *

    *

    * * @param keySpec the key specification * @return the Rainbow public key * @throws InvalidKeySpecException if the KeySpec is not supported. */ public PublicKey engineGeneratePublic(KeySpec keySpec) throws InvalidKeySpecException { if (keySpec instanceof RainbowPublicKeySpec) { return new BCRainbowPublicKey((RainbowPublicKeySpec)keySpec); } else if (keySpec instanceof X509EncodedKeySpec) { // get the DER-encoded Key according to X.509 from the spec byte[] encKey = ((X509EncodedKeySpec)keySpec).getEncoded(); // decode the SubjectPublicKeyInfo data structure to the pki object try { return generatePublic(SubjectPublicKeyInfo.getInstance(encKey)); } catch (Exception e) { throw new InvalidKeySpecException(e.toString()); } } throw new InvalidKeySpecException("Unknown key specification: " + keySpec + "."); } /** * Converts a given key into a key specification, if possible. Currently the * following specs are supported: *

      *
    • for RainbowPublicKey: X509EncodedKeySpec, RainbowPublicKeySpec *
    • for RainbowPrivateKey: PKCS8EncodedKeySpec, RainbowPrivateKeySpec *
    * * @param key the key * @param keySpec the key specification * @return the specification of the CMSS key * @throws InvalidKeySpecException if the key type or key specification is not supported. */ public final KeySpec engineGetKeySpec(Key key, Class keySpec) throws InvalidKeySpecException { if (key instanceof BCRainbowPrivateKey) { if (PKCS8EncodedKeySpec.class.isAssignableFrom(keySpec)) { return new PKCS8EncodedKeySpec(key.getEncoded()); } else if (RainbowPrivateKeySpec.class.isAssignableFrom(keySpec)) { BCRainbowPrivateKey privKey = (BCRainbowPrivateKey)key; return new RainbowPrivateKeySpec(privKey.getInvA1(), privKey .getB1(), privKey.getInvA2(), privKey.getB2(), privKey .getVi(), privKey.getLayers()); } } else if (key instanceof BCRainbowPublicKey) { if (X509EncodedKeySpec.class.isAssignableFrom(keySpec)) { return new X509EncodedKeySpec(key.getEncoded()); } else if (RainbowPublicKeySpec.class.isAssignableFrom(keySpec)) { BCRainbowPublicKey pubKey = (BCRainbowPublicKey)key; return new RainbowPublicKeySpec(pubKey.getDocLength(), pubKey .getCoeffQuadratic(), pubKey.getCoeffSingular(), pubKey .getCoeffScalar()); } } else { throw new InvalidKeySpecException("Unsupported key type: " + key.getClass() + "."); } throw new InvalidKeySpecException("Unknown key specification: " + keySpec + "."); } /** * Translates a key into a form known by the FlexiProvider. Currently the * following key types are supported: RainbowPrivateKey, RainbowPublicKey. * * @param key the key * @return a key of a known key type * @throws InvalidKeyException if the key is not supported. */ public final Key engineTranslateKey(Key key) throws InvalidKeyException { if (key instanceof BCRainbowPrivateKey || key instanceof BCRainbowPublicKey) { return key; } throw new InvalidKeyException("Unsupported key type"); } public PrivateKey generatePrivate(PrivateKeyInfo keyInfo) throws IOException { RainbowPrivateKey pKey = RainbowPrivateKey.getInstance(keyInfo.parsePrivateKey()); return new BCRainbowPrivateKey(pKey.getInvA1(), pKey.getB1(), pKey.getInvA2(), pKey.getB2(), pKey.getVi(), pKey.getLayers()); } public PublicKey generatePublic(SubjectPublicKeyInfo keyInfo) throws IOException { RainbowPublicKey pKey = RainbowPublicKey.getInstance(keyInfo.parsePublicKey()); return new BCRainbowPublicKey(pKey.getDocLength(), pKey.getCoeffQuadratic(), pKey.getCoeffSingular(), pKey.getCoeffScalar()); } } bouncycastle-1.49.orig/src/org/bouncycastle/pqc/jcajce/provider/rainbow/RainbowKeysToParams.java0000644000175000017500000000302011776720732032555 0ustar ebourgebourgpackage org.bouncycastle.pqc.jcajce.provider.rainbow; import java.security.InvalidKeyException; import java.security.PrivateKey; import java.security.PublicKey; import org.bouncycastle.crypto.params.AsymmetricKeyParameter; import org.bouncycastle.pqc.crypto.rainbow.RainbowPrivateKeyParameters; import org.bouncycastle.pqc.crypto.rainbow.RainbowPublicKeyParameters; /** * utility class for converting jce/jca Rainbow objects * objects into their org.bouncycastle.crypto counterparts. */ public class RainbowKeysToParams { static public AsymmetricKeyParameter generatePublicKeyParameter( PublicKey key) throws InvalidKeyException { if (key instanceof BCRainbowPublicKey) { BCRainbowPublicKey k = (BCRainbowPublicKey)key; return new RainbowPublicKeyParameters(k.getDocLength(), k.getCoeffQuadratic(), k.getCoeffSingular(), k.getCoeffScalar()); } throw new InvalidKeyException("can't identify Rainbow public key: " + key.getClass().getName()); } static public AsymmetricKeyParameter generatePrivateKeyParameter( PrivateKey key) throws InvalidKeyException { if (key instanceof BCRainbowPrivateKey) { BCRainbowPrivateKey k = (BCRainbowPrivateKey)key; return new RainbowPrivateKeyParameters(k.getInvA1(), k.getB1(), k.getInvA2(), k.getB2(), k.getVi(), k.getLayers()); } throw new InvalidKeyException("can't identify Rainbow private key."); } } bouncycastle-1.49.orig/src/org/bouncycastle/pqc/jcajce/provider/rainbow/BCRainbowPrivateKey.java0000644000175000017500000001434011776714535032476 0ustar ebourgebourgpackage org.bouncycastle.pqc.jcajce.provider.rainbow; import java.io.IOException; import java.security.PrivateKey; import java.util.Arrays; import org.bouncycastle.asn1.DERNull; import org.bouncycastle.asn1.pkcs.PrivateKeyInfo; import org.bouncycastle.asn1.x509.AlgorithmIdentifier; import org.bouncycastle.pqc.asn1.PQCObjectIdentifiers; import org.bouncycastle.pqc.asn1.RainbowPrivateKey; import org.bouncycastle.pqc.crypto.rainbow.Layer; import org.bouncycastle.pqc.crypto.rainbow.RainbowPrivateKeyParameters; import org.bouncycastle.pqc.crypto.rainbow.util.RainbowUtil; import org.bouncycastle.pqc.jcajce.spec.RainbowPrivateKeySpec; /** * The Private key in Rainbow consists of the linear affine maps L1, L2 and the * map F, consisting of quadratic polynomials. In this implementation, we * denote: L1 = A1*x + b1 L2 = A2*x + b2 *

    * The coefficients of the polynomials in F are stored in 3-dimensional arrays * per layer. The indices of these arrays denote the polynomial, and the * variables. *

    * More detailed information about the private key is to be found in the paper * of Jintai Ding, Dieter Schmidt: Rainbow, a New Multivariable Polynomial * Signature Scheme. ACNS 2005: 164-175 (http://dx.doi.org/10.1007/11496137_12) */ public class BCRainbowPrivateKey implements PrivateKey { private static final long serialVersionUID = 1L; // the inverse of L1 private short[][] A1inv; // translation vector element of L1 private short[] b1; // the inverse of L2 private short[][] A2inv; // translation vector of L2 private short[] b2; /* * components of F */ private Layer[] layers; // set of vinegar vars per layer. private int[] vi; /** * Constructor. * * @param A1inv * @param b1 * @param A2inv * @param b2 * @param layers */ public BCRainbowPrivateKey(short[][] A1inv, short[] b1, short[][] A2inv, short[] b2, int[] vi, Layer[] layers) { this.A1inv = A1inv; this.b1 = b1; this.A2inv = A2inv; this.b2 = b2; this.vi = vi; this.layers = layers; } /** * Constructor (used by the {@link RainbowKeyFactorySpi}). * * @param keySpec a {@link RainbowPrivateKeySpec} */ public BCRainbowPrivateKey(RainbowPrivateKeySpec keySpec) { this(keySpec.getInvA1(), keySpec.getB1(), keySpec.getInvA2(), keySpec .getB2(), keySpec.getVi(), keySpec.getLayers()); } public BCRainbowPrivateKey( RainbowPrivateKeyParameters params) { this(params.getInvA1(), params.getB1(), params.getInvA2(), params.getB2(), params.getVi(), params.getLayers()); } /** * Getter for the inverse matrix of A1. * * @return the A1inv inverse */ public short[][] getInvA1() { return this.A1inv; } /** * Getter for the translation part of the private quadratic map L1. * * @return b1 the translation part of L1 */ public short[] getB1() { return this.b1; } /** * Getter for the translation part of the private quadratic map L2. * * @return b2 the translation part of L2 */ public short[] getB2() { return this.b2; } /** * Getter for the inverse matrix of A2 * * @return the A2inv */ public short[][] getInvA2() { return this.A2inv; } /** * Returns the layers contained in the private key * * @return layers */ public Layer[] getLayers() { return this.layers; } /** * Returns the array of vi-s * * @return the vi */ public int[] getVi() { return vi; } /** * Compare this Rainbow private key with another object. * * @param other the other object * @return the result of the comparison */ public boolean equals(Object other) { if (other == null || !(other instanceof BCRainbowPrivateKey)) { return false; } BCRainbowPrivateKey otherKey = (BCRainbowPrivateKey)other; boolean eq = true; // compare using shortcut rule ( && instead of &) eq = eq && RainbowUtil.equals(A1inv, otherKey.getInvA1()); eq = eq && RainbowUtil.equals(A2inv, otherKey.getInvA2()); eq = eq && RainbowUtil.equals(b1, otherKey.getB1()); eq = eq && RainbowUtil.equals(b2, otherKey.getB2()); eq = eq && Arrays.equals(vi, otherKey.getVi()); if (layers.length != otherKey.getLayers().length) { return false; } for (int i = layers.length - 1; i >= 0; i--) { eq &= layers[i].equals(otherKey.getLayers()[i]); } return eq; } public int hashCode() { int hash = layers.length; hash = hash * 37 + org.bouncycastle.util.Arrays.hashCode(A1inv); hash = hash * 37 + org.bouncycastle.util.Arrays.hashCode(b1); hash = hash * 37 + org.bouncycastle.util.Arrays.hashCode(A2inv); hash = hash * 37 + org.bouncycastle.util.Arrays.hashCode(b2); hash = hash * 37 + org.bouncycastle.util.Arrays.hashCode(vi); for (int i = layers.length - 1; i >= 0; i--) { hash = hash * 37 + layers[i].hashCode(); } return hash; } /** * @return name of the algorithm - "Rainbow" */ public final String getAlgorithm() { return "Rainbow"; } public byte[] getEncoded() { RainbowPrivateKey privateKey = new RainbowPrivateKey(A1inv, b1, A2inv, b2, vi, layers); PrivateKeyInfo pki; try { AlgorithmIdentifier algorithmIdentifier = new AlgorithmIdentifier(PQCObjectIdentifiers.rainbow, DERNull.INSTANCE); pki = new PrivateKeyInfo(algorithmIdentifier, privateKey); } catch (IOException e) { e.printStackTrace(); return null; } try { byte[] encoded = pki.getEncoded(); return encoded; } catch (IOException e) { e.printStackTrace(); return null; } } public String getFormat() { return "PKCS#8"; } } bouncycastle-1.49.orig/src/org/bouncycastle/pqc/jcajce/provider/rainbow/BCRainbowPublicKey.java0000644000175000017500000001174212057520161032264 0ustar ebourgebourgpackage org.bouncycastle.pqc.jcajce.provider.rainbow; import java.security.PublicKey; import org.bouncycastle.asn1.DERNull; import org.bouncycastle.asn1.x509.AlgorithmIdentifier; import org.bouncycastle.pqc.asn1.PQCObjectIdentifiers; import org.bouncycastle.pqc.asn1.RainbowPublicKey; import org.bouncycastle.pqc.crypto.rainbow.RainbowParameters; import org.bouncycastle.pqc.crypto.rainbow.RainbowPublicKeyParameters; import org.bouncycastle.pqc.crypto.rainbow.util.RainbowUtil; import org.bouncycastle.pqc.jcajce.provider.util.KeyUtil; import org.bouncycastle.pqc.jcajce.spec.RainbowPublicKeySpec; import org.bouncycastle.util.Arrays; /** * This class implements CipherParameters and PublicKey. *

    * The public key in Rainbow consists of n - v1 polynomial components of the * private key's F and the field structure of the finite field k. *

    * The quadratic (or mixed) coefficients of the polynomials from the public key * are stored in the 2-dimensional array in lexicographical order, requiring n * * (n + 1) / 2 entries for each polynomial. The singular terms are stored in a * 2-dimensional array requiring n entries per polynomial, the scalar term of * each polynomial is stored in a 1-dimensional array. *

    * More detailed information on the public key is to be found in the paper of * Jintai Ding, Dieter Schmidt: Rainbow, a New Multivariable Polynomial * Signature Scheme. ACNS 2005: 164-175 (http://dx.doi.org/10.1007/11496137_12) */ public class BCRainbowPublicKey implements PublicKey { private static final long serialVersionUID = 1L; private short[][] coeffquadratic; private short[][] coeffsingular; private short[] coeffscalar; private int docLength; // length of possible document to sign private RainbowParameters rainbowParams; /** * Constructor * * @param docLength * @param coeffQuadratic * @param coeffSingular * @param coeffScalar */ public BCRainbowPublicKey(int docLength, short[][] coeffQuadratic, short[][] coeffSingular, short[] coeffScalar) { this.docLength = docLength; this.coeffquadratic = coeffQuadratic; this.coeffsingular = coeffSingular; this.coeffscalar = coeffScalar; } /** * Constructor (used by the {@link RainbowKeyFactorySpi}). * * @param keySpec a {@link RainbowPublicKeySpec} */ public BCRainbowPublicKey(RainbowPublicKeySpec keySpec) { this(keySpec.getDocLength(), keySpec.getCoeffQuadratic(), keySpec .getCoeffSingular(), keySpec.getCoeffScalar()); } public BCRainbowPublicKey( RainbowPublicKeyParameters params) { this(params.getDocLength(), params.getCoeffQuadratic(), params.getCoeffSingular(), params.getCoeffScalar()); } /** * @return the docLength */ public int getDocLength() { return this.docLength; } /** * @return the coeffQuadratic */ public short[][] getCoeffQuadratic() { return coeffquadratic; } /** * @return the coeffSingular */ public short[][] getCoeffSingular() { short[][] copy = new short[coeffsingular.length][]; for (int i = 0; i != coeffsingular.length; i++) { copy[i] = Arrays.clone(coeffsingular[i]); } return copy; } /** * @return the coeffScalar */ public short[] getCoeffScalar() { return Arrays.clone(coeffscalar); } /** * Compare this Rainbow public key with another object. * * @param other the other object * @return the result of the comparison */ public boolean equals(Object other) { if (other == null || !(other instanceof BCRainbowPublicKey)) { return false; } BCRainbowPublicKey otherKey = (BCRainbowPublicKey)other; return docLength == otherKey.getDocLength() && RainbowUtil.equals(coeffquadratic, otherKey.getCoeffQuadratic()) && RainbowUtil.equals(coeffsingular, otherKey.getCoeffSingular()) && RainbowUtil.equals(coeffscalar, otherKey.getCoeffScalar()); } public int hashCode() { int hash = docLength; hash = hash * 37 + Arrays.hashCode(coeffquadratic); hash = hash * 37 + Arrays.hashCode(coeffsingular); hash = hash * 37 + Arrays.hashCode(coeffscalar); return hash; } /** * @return name of the algorithm - "Rainbow" */ public final String getAlgorithm() { return "Rainbow"; } public String getFormat() { return "X.509"; } public byte[] getEncoded() { RainbowPublicKey key = new RainbowPublicKey(docLength, coeffquadratic, coeffsingular, coeffscalar); AlgorithmIdentifier algorithmIdentifier = new AlgorithmIdentifier(PQCObjectIdentifiers.rainbow, DERNull.INSTANCE); return KeyUtil.getEncodedSubjectPublicKeyInfo(algorithmIdentifier, key); } } bouncycastle-1.49.orig/src/org/bouncycastle/pqc/jcajce/spec/0000755000175000017500000000000012152033551023433 5ustar ebourgebourgbouncycastle-1.49.orig/src/org/bouncycastle/pqc/jcajce/spec/GMSSPrivateKeySpec.java0000644000175000017500000002233412151551720027674 0ustar ebourgebourgpackage org.bouncycastle.pqc.jcajce.spec; import java.security.spec.KeySpec; import java.util.Vector; import org.bouncycastle.crypto.Digest; import org.bouncycastle.pqc.crypto.gmss.GMSSLeaf; import org.bouncycastle.pqc.crypto.gmss.GMSSParameters; import org.bouncycastle.pqc.crypto.gmss.GMSSRootCalc; import org.bouncycastle.pqc.crypto.gmss.GMSSRootSig; import org.bouncycastle.pqc.crypto.gmss.Treehash; import org.bouncycastle.util.Arrays; /** * This class provides a specification for a GMSS private key. */ public class GMSSPrivateKeySpec implements KeySpec { private int[] index; private byte[][] currentSeed; private byte[][] nextNextSeed; private byte[][][] currentAuthPath; private byte[][][] nextAuthPath; private Treehash[][] currentTreehash; private Treehash[][] nextTreehash; private Vector[] currentStack; private Vector[] nextStack; private Vector[][] currentRetain; private Vector[][] nextRetain; private byte[][][] keep; private GMSSLeaf[] nextNextLeaf; private GMSSLeaf[] upperLeaf; private GMSSLeaf[] upperTreehashLeaf; private int[] minTreehash; private GMSSParameters gmssPS; private byte[][] nextRoot; private GMSSRootCalc[] nextNextRoot; private byte[][] currentRootSig; private GMSSRootSig[] nextRootSig; /** * @param index tree indices * @param currentSeed seed for the generation of private OTS keys for the * current subtrees (TREE) * @param nextNextSeed seed for the generation of private OTS keys for the * subtrees after next (TREE++) * @param currentAuthPath array of current authentication paths (AUTHPATH) * @param nextAuthPath array of next authentication paths (AUTHPATH+) * @param keep keep array for the authPath algorithm * @param currentTreehash treehash for authPath algorithm of current tree * @param nextTreehash treehash for authPath algorithm of next tree (TREE+) * @param currentStack shared stack for authPath algorithm of current tree * @param nextStack shared stack for authPath algorithm of next tree (TREE+) * @param currentRetain retain stack for authPath algorithm of current tree * @param nextRetain retain stack for authPath algorithm of next tree (TREE+) * @param nextNextLeaf array of upcoming leafs of the tree after next (LEAF++) of * each layer * @param upperLeaf needed for precomputation of upper nodes * @param upperTreehashLeaf needed for precomputation of upper treehash nodes * @param minTreehash index of next treehash instance to receive an update * @param nextRoot the roots of the next trees (ROOT+) * @param nextNextRoot the roots of the tree after next (ROOT++) * @param currentRootSig array of signatures of the roots of the current subtrees * (SIG) * @param nextRootSig array of signatures of the roots of the next subtree * (SIG+) * @param gmssParameterset the GMSS Parameterset */ public GMSSPrivateKeySpec(int[] index, byte[][] currentSeed, byte[][] nextNextSeed, byte[][][] currentAuthPath, byte[][][] nextAuthPath, Treehash[][] currentTreehash, Treehash[][] nextTreehash, Vector[] currentStack, Vector[] nextStack, Vector[][] currentRetain, Vector[][] nextRetain, byte[][][] keep, GMSSLeaf[] nextNextLeaf, GMSSLeaf[] upperLeaf, GMSSLeaf[] upperTreehashLeaf, int[] minTreehash, byte[][] nextRoot, GMSSRootCalc[] nextNextRoot, byte[][] currentRootSig, GMSSRootSig[] nextRootSig, GMSSParameters gmssParameterset) { this.index = index; this.currentSeed = currentSeed; this.nextNextSeed = nextNextSeed; this.currentAuthPath = currentAuthPath; this.nextAuthPath = nextAuthPath; this.currentTreehash = currentTreehash; this.nextTreehash = nextTreehash; this.currentStack = currentStack; this.nextStack = nextStack; this.currentRetain = currentRetain; this.nextRetain = nextRetain; this.keep = keep; this.nextNextLeaf = nextNextLeaf; this.upperLeaf = upperLeaf; this.upperTreehashLeaf = upperTreehashLeaf; this.minTreehash = minTreehash; this.nextRoot = nextRoot; this.nextNextRoot = nextNextRoot; this.currentRootSig = currentRootSig; this.nextRootSig = nextRootSig; this.gmssPS = gmssParameterset; } public int[] getIndex() { return Arrays.clone(index); } public byte[][] getCurrentSeed() { return clone(currentSeed); } public byte[][] getNextNextSeed() { return clone(nextNextSeed); } public byte[][][] getCurrentAuthPath() { return clone(currentAuthPath); } public byte[][][] getNextAuthPath() { return clone(nextAuthPath); } public Treehash[][] getCurrentTreehash() { return clone(currentTreehash); } public Treehash[][] getNextTreehash() { return clone(nextTreehash); } public byte[][][] getKeep() { return clone(keep); } public Vector[] getCurrentStack() { return clone(currentStack); } public Vector[] getNextStack() { return clone(nextStack); } public Vector[][] getCurrentRetain() { return clone(currentRetain); } public Vector[][] getNextRetain() { return clone(nextRetain); } public GMSSLeaf[] getNextNextLeaf() { return clone(nextNextLeaf); } public GMSSLeaf[] getUpperLeaf() { return clone(upperLeaf); } public GMSSLeaf[] getUpperTreehashLeaf() { return clone(upperTreehashLeaf); } public int[] getMinTreehash() { return Arrays.clone(minTreehash); } public GMSSRootSig[] getNextRootSig() { return clone(nextRootSig); } public GMSSParameters getGmssPS() { return gmssPS; } public byte[][] getNextRoot() { return clone(nextRoot); } public GMSSRootCalc[] getNextNextRoot() { return clone(nextNextRoot); } public byte[][] getCurrentRootSig() { return clone(currentRootSig); } private static GMSSLeaf[] clone(GMSSLeaf[] data) { if (data == null) { return null; } GMSSLeaf[] copy = new GMSSLeaf[data.length]; System.arraycopy(data, 0, copy, 0, data.length); return copy; } private static GMSSRootCalc[] clone(GMSSRootCalc[] data) { if (data == null) { return null; } GMSSRootCalc[] copy = new GMSSRootCalc[data.length]; System.arraycopy(data, 0, copy, 0, data.length); return copy; } private static GMSSRootSig[] clone(GMSSRootSig[] data) { if (data == null) { return null; } GMSSRootSig[] copy = new GMSSRootSig[data.length]; System.arraycopy(data, 0, copy, 0, data.length); return copy; } private static byte[][] clone(byte[][] data) { if (data == null) { return null; } byte[][] copy = new byte[data.length][]; for (int i = 0; i != data.length; i++) { copy[i] = Arrays.clone(data[i]); } return copy; } private static byte[][][] clone(byte[][][] data) { if (data == null) { return null; } byte[][][] copy = new byte[data.length][][]; for (int i = 0; i != data.length; i++) { copy[i] = clone(data[i]); } return copy; } private static Treehash[] clone(Treehash[] data) { if (data == null) { return null; } Treehash[] copy = new Treehash[data.length]; System.arraycopy(data, 0, copy, 0, data.length); return copy; } private static Treehash[][] clone(Treehash[][] data) { if (data == null) { return null; } Treehash[][] copy = new Treehash[data.length][]; for (int i = 0; i != data.length; i++) { copy[i] = clone(data[i]); } return copy; } private static Vector[] clone(Vector[] data) { if (data == null) { return null; } Vector[] copy = new Vector[data.length]; for (int i = 0; i != data.length; i++) { copy[i] = new Vector(data[i]); } return copy; } private static Vector[][] clone(Vector[][] data) { if (data == null) { return null; } Vector[][] copy = new Vector[data.length][]; for (int i = 0; i != data.length; i++) { copy[i] = clone(data[i]); } return copy; } }bouncycastle-1.49.orig/src/org/bouncycastle/pqc/jcajce/spec/McEliecePrivateKeySpec.java0000644000175000017500000001314012043660247030571 0ustar ebourgebourgpackage org.bouncycastle.pqc.jcajce.spec; import java.security.spec.KeySpec; import org.bouncycastle.pqc.math.linearalgebra.GF2Matrix; import org.bouncycastle.pqc.math.linearalgebra.GF2mField; import org.bouncycastle.pqc.math.linearalgebra.Permutation; import org.bouncycastle.pqc.math.linearalgebra.PolynomialGF2mSmallM; /** * This class provides a specification for a McEliece private key. * * @see org.bouncycastle.pqc.ecc.JDKMcEliecePrivateKey.McEliecePrivateKey * @see KeySpec */ public class McEliecePrivateKeySpec implements KeySpec { // the OID of the algorithm private String oid; // the length of the code private int n; // the dimension of the code, where k >= n - mt private int k; // the underlying finite field private GF2mField field; // the irreducible Goppa polynomial private PolynomialGF2mSmallM goppaPoly; // a k x k random binary non-singular matrix private GF2Matrix sInv; // the permutation used to generate the systematic check matrix private Permutation p1; // the permutation used to compute the public generator matrix private Permutation p2; // the canonical check matrix of the code private GF2Matrix h; // the matrix used to compute square roots in (GF(2^m))^t private PolynomialGF2mSmallM[] qInv; /** * Constructor. * * @param oid * @param n the length of the code * @param k the dimension of the code * @param field the field polynomial defining the finite field * GF(2m) * @param goppaPoly the irreducible Goppa polynomial * @param sInv the matrix S-1 * @param p1 the permutation used to generate the systematic check * matrix * @param p2 the permutation used to compute the public generator * matrix * @param h the canonical check matrix * @param qInv the matrix used to compute square roots in * (GF(2m))t */ public McEliecePrivateKeySpec(String oid, int n, int k, GF2mField field, PolynomialGF2mSmallM goppaPoly, GF2Matrix sInv, Permutation p1, Permutation p2, GF2Matrix h, PolynomialGF2mSmallM[] qInv) { this.oid = oid; this.k = k; this.n = n; this.field = field; this.goppaPoly = goppaPoly; this.sInv = sInv; this.p1 = p1; this.p2 = p2; this.h = h; this.qInv = qInv; } /** * Constructor (used by the {@link McElieceKeyFactory}). * * @param oid * @param n the length of the code * @param k the dimension of the code * @param encField the encoded field polynomial defining the finite field * GF(2m) * @param encGoppaPoly the encoded irreducible Goppa polynomial * @param encSInv the encoded matrix S-1 * @param encP1 the encoded permutation used to generate the systematic * check matrix * @param encP2 the encoded permutation used to compute the public * generator matrix * @param encH the encoded canonical check matrix * @param encQInv the encoded matrix used to compute square roots in * (GF(2m))t */ public McEliecePrivateKeySpec(String oid, int n, int k, byte[] encField, byte[] encGoppaPoly, byte[] encSInv, byte[] encP1, byte[] encP2, byte[] encH, byte[][] encQInv) { this.oid = oid; this.n = n; this.k = k; field = new GF2mField(encField); goppaPoly = new PolynomialGF2mSmallM(field, encGoppaPoly); sInv = new GF2Matrix(encSInv); p1 = new Permutation(encP1); p2 = new Permutation(encP2); h = new GF2Matrix(encH); qInv = new PolynomialGF2mSmallM[encQInv.length]; for (int i = 0; i < encQInv.length; i++) { qInv[i] = new PolynomialGF2mSmallM(field, encQInv[i]); } } /** * @return the length of the code */ public int getN() { return n; } /** * @return the dimension of the code */ public int getK() { return k; } /** * @return the finite field GF(2m) */ public GF2mField getField() { return field; } /** * @return the irreducible Goppa polynomial */ public PolynomialGF2mSmallM getGoppaPoly() { return goppaPoly; } /** * @return the k x k random binary non-singular matrix S^-1 */ public GF2Matrix getSInv() { return sInv; } /** * @return the permutation used to generate the systematic check matrix */ public Permutation getP1() { return p1; } /** * @return the permutation used to compute the public generator matrix */ public Permutation getP2() { return p2; } /** * @return the canonical check matrix H */ public GF2Matrix getH() { return h; } /** * @return the matrix used to compute square roots in * (GF(2m))t */ public PolynomialGF2mSmallM[] getQInv() { return qInv; } public String getOIDString() { return oid; } } bouncycastle-1.49.orig/src/org/bouncycastle/pqc/jcajce/spec/GMSSKeySpec.java0000644000175000017500000000111211777163657026355 0ustar ebourgebourgpackage org.bouncycastle.pqc.jcajce.spec; import java.security.spec.KeySpec; import org.bouncycastle.pqc.crypto.gmss.GMSSParameters; public class GMSSKeySpec implements KeySpec { /** * The GMSSParameterSet */ private GMSSParameters gmssParameterSet; protected GMSSKeySpec(GMSSParameters gmssParameterSet) { this.gmssParameterSet = gmssParameterSet; } /** * Returns the GMSS parameter set * * @return The GMSS parameter set */ public GMSSParameters getParameters() { return gmssParameterSet; } } bouncycastle-1.49.orig/src/org/bouncycastle/pqc/jcajce/spec/GMSSPublicKeySpec.java0000644000175000017500000000153612151551720027501 0ustar ebourgebourgpackage org.bouncycastle.pqc.jcajce.spec; import org.bouncycastle.pqc.crypto.gmss.GMSSParameters; /** * This class provides a specification for a GMSS public key. * * @see org.bouncycastle.pqc.jcajce.provider.gmss.BCGMSSPublicKey */ public class GMSSPublicKeySpec extends GMSSKeySpec { /** * The GMSS public key */ private byte[] gmssPublicKey; /** * The constructor. * * @param key a raw GMSS public key * @param gmssParameterSet an instance of GMSSParameterSet */ public GMSSPublicKeySpec(byte[] key, GMSSParameters gmssParameterSet) { super(gmssParameterSet); this.gmssPublicKey = key; } /** * Returns the GMSS public key * * @return The GMSS public key */ public byte[] getPublicKey() { return gmssPublicKey; } } bouncycastle-1.49.orig/src/org/bouncycastle/pqc/jcajce/spec/McEliecePublicKeySpec.java0000644000175000017500000000364612045616616030412 0ustar ebourgebourgpackage org.bouncycastle.pqc.jcajce.spec; import java.security.spec.KeySpec; import org.bouncycastle.pqc.math.linearalgebra.GF2Matrix; /** * This class provides a specification for a McEliece public key. * * @see org.bouncycastle.pqc.jcajce.provider.mceliece.BCMcEliecePublicKey */ public class McEliecePublicKeySpec implements KeySpec { // the OID of the algorithm private String oid; // the length of the code private int n; // the error correction capability of the code private int t; // the generator matrix private GF2Matrix g; /** * Constructor (used by {@link org.bouncycastle.pqc.jcajce.provider.mceliece.McElieceKeyFactorySpi}). * * @param oid * @param n the length of the code * @param t the error correction capability of the code * @param g the generator matrix */ public McEliecePublicKeySpec(String oid, int n, int t, GF2Matrix g) { this.oid = oid; this.n = n; this.t = t; this.g = new GF2Matrix(g); } /** * Constructor (used by {@link org.bouncycastle.pqc.jcajce.provider.mceliece.McElieceKeyFactorySpi}). * * @param oid * @param n the length of the code * @param t the error correction capability of the code * @param encG the encoded generator matrix */ public McEliecePublicKeySpec(String oid, int t, int n, byte[] encG) { this.oid = oid; this.n = n; this.t = t; this.g = new GF2Matrix(encG); } /** * @return the length of the code */ public int getN() { return n; } /** * @return the error correction capability of the code */ public int getT() { return t; } /** * @return the generator matrix */ public GF2Matrix getG() { return g; } public String getOIDString() { return oid; } } bouncycastle-1.49.orig/src/org/bouncycastle/pqc/jcajce/spec/McElieceCCA2ParameterSpec.java0000644000175000017500000000275112151251423031015 0ustar ebourgebourgpackage org.bouncycastle.pqc.jcajce.spec; import java.security.spec.AlgorithmParameterSpec; /** * This class provides a specification for the parameters of the CCA2-secure * variants of the McEliece PKCS that are used with * {@link McElieceFujisakiCipher}, {@link McElieceKobaraImaiCipher}, and * {@link McEliecePointchevalCipher}. * * @see McElieceFujisakiCipher * @see McElieceKobaraImaiCipher * @see McEliecePointchevalCipher */ public class McElieceCCA2ParameterSpec implements AlgorithmParameterSpec { /** * The default message digest ("SHA256"). */ public static final String DEFAULT_MD = "SHA256"; private String mdName; /** * Construct the default parameters. Choose the */ public McElieceCCA2ParameterSpec() { this(DEFAULT_MD); } /** * Constructor. * * @param mdName the name of the hash function */ public McElieceCCA2ParameterSpec(String mdName) { // check whether message digest is available // TODO: this method not used! // try { // Registry.getMessageDigest(mdName); // } catch (NoSuchAlgorithmException nsae) { // throw new InvalidParameterException("Message digest '" + mdName // + "' not found'."); // } // assign message digest name this.mdName = mdName; } /** * @return the name of the hash function */ public String getMDName() { return mdName; } } bouncycastle-1.49.orig/src/org/bouncycastle/pqc/jcajce/spec/McElieceCCA2PublicKeySpec.java0000644000175000017500000000354612045616616031002 0ustar ebourgebourgpackage org.bouncycastle.pqc.jcajce.spec; import java.security.spec.KeySpec; import org.bouncycastle.pqc.math.linearalgebra.GF2Matrix; /** * This class provides a specification for a McEliece CCA2 public key. * * @see org.bouncycastle.pqc.jcajce.provider.mceliece.BCMcElieceCCA2PublicKey */ public class McElieceCCA2PublicKeySpec implements KeySpec { // the OID of the algorithm private String oid; // the length of the code private int n; // the error correction capability of the code private int t; // the generator matrix private GF2Matrix matrixG; /** * Constructor. * * @param n length of the code * @param t error correction capability * @param matrix generator matrix */ public McElieceCCA2PublicKeySpec(String oid, int n, int t, GF2Matrix matrix) { this.oid = oid; this.n = n; this.t = t; this.matrixG = new GF2Matrix(matrix); } /** * Constructor (used by {@link org.bouncycastle.pqc.jcajce.provider.mceliece.McElieceKeyFactorySpi}). * * @param n length of the code * @param t error correction capability of the code * @param encMatrix encoded generator matrix */ public McElieceCCA2PublicKeySpec(String oid, int n, int t, byte[] encMatrix) { this.oid = oid; this.n = n; this.t = t; this.matrixG = new GF2Matrix(encMatrix); } /** * @return the length of the code */ public int getN() { return n; } /** * @return the error correction capability of the code */ public int getT() { return t; } /** * @return the generator matrix */ public GF2Matrix getMatrixG() { return matrixG; } public String getOIDString() { return oid; } } bouncycastle-1.49.orig/src/org/bouncycastle/pqc/jcajce/spec/McElieceCCA2PrivateKeySpec.java0000644000175000017500000001003312043365070031154 0ustar ebourgebourgpackage org.bouncycastle.pqc.jcajce.spec; import java.security.spec.KeySpec; import org.bouncycastle.pqc.math.linearalgebra.GF2Matrix; import org.bouncycastle.pqc.math.linearalgebra.GF2mField; import org.bouncycastle.pqc.math.linearalgebra.Permutation; import org.bouncycastle.pqc.math.linearalgebra.PolynomialGF2mSmallM; /** * This class provides a specification for a McEliece CCA2 private key. * * @see JDKMcElieceCCA2PrivateKey */ public class McElieceCCA2PrivateKeySpec implements KeySpec { // the OID of the algorithm private String oid; // the length of the code private int n; // the dimension of the code private int k; // the finte field GF(2^m) private GF2mField field; // the irreducible Goppa polynomial private PolynomialGF2mSmallM goppaPoly; // the permutation private Permutation p; // the canonical check matrix private GF2Matrix h; // the matrix used to compute square roots in (GF(2^m))^t private PolynomialGF2mSmallM[] qInv; /** * Constructor. * * @param n the length of the code * @param k the dimension of the code * @param field the finite field GF(2m) * @param gp the irreducible Goppa polynomial * @param p the permutation * @param h the canonical check matrix * @param qInv the matrix used to compute square roots in * (GF(2^m))^t */ public McElieceCCA2PrivateKeySpec(String oid, int n, int k, GF2mField field, PolynomialGF2mSmallM gp, Permutation p, GF2Matrix h, PolynomialGF2mSmallM[] qInv) { this.oid = oid; this.n = n; this.k = k; this.field = field; this.goppaPoly = gp; this.p = p; this.h = h; this.qInv = qInv; } /** * Constructor used by the {@link McElieceKeyFactory}. * * @param n the length of the code * @param k the dimension of the code * @param encFieldPoly the encoded field polynomial defining the finite field * GF(2m) * @param encGoppaPoly the encoded irreducible Goppa polynomial * @param encP the encoded permutation * @param encH the encoded canonical check matrix * @param encQInv the encoded matrix used to compute square roots in * (GF(2^m))^t */ public McElieceCCA2PrivateKeySpec(String oid, int n, int k, byte[] encFieldPoly, byte[] encGoppaPoly, byte[] encP, byte[] encH, byte[][] encQInv) { this.oid = oid; this.n = n; this.k = k; field = new GF2mField(encFieldPoly); goppaPoly = new PolynomialGF2mSmallM(field, encGoppaPoly); p = new Permutation(encP); h = new GF2Matrix(encH); qInv = new PolynomialGF2mSmallM[encQInv.length]; for (int i = 0; i < encQInv.length; i++) { qInv[i] = new PolynomialGF2mSmallM(field, encQInv[i]); } } /** * @return the length of the code */ public int getN() { return n; } /** * @return the dimension of the code */ public int getK() { return k; } /** * @return the finite field */ public GF2mField getField() { return field; } /** * @return the irreducible Goppa polynomial */ public PolynomialGF2mSmallM getGoppaPoly() { return goppaPoly; } /** * @return the permutation P */ public Permutation getP() { return p; } /** * @return the canonical check matrix H */ public GF2Matrix getH() { return h; } /** * @return the matrix used to compute square roots in (GF(2^m))^t */ public PolynomialGF2mSmallM[] getQInv() { return qInv; } public String getOIDString() { return oid; } } bouncycastle-1.49.orig/src/org/bouncycastle/pqc/jcajce/spec/RainbowPrivateKeySpec.java0000644000175000017500000000541511776713757030553 0ustar ebourgebourgpackage org.bouncycastle.pqc.jcajce.spec; import java.security.spec.KeySpec; import org.bouncycastle.pqc.crypto.rainbow.Layer; /** * This class provides a specification for a RainbowSignature private key. * * @see KeySpec */ public class RainbowPrivateKeySpec implements KeySpec { /* * invertible affine linear map L1 */ // the inverse of A1, (n-v1 x n-v1 matrix) private short[][] A1inv; // translation vector of L1 private short[] b1; /* * invertible affine linear map L2 */ // the inverse of A2, (n x n matrix) private short[][] A2inv; // translation vector of L2 private short[] b2; /* * components of F */ // the number of Vinegar-variables per layer. private int[] vi; // contains the polynomials with their coefficients of private map F private Layer[] layers; /** * Constructor * * @param A1inv the inverse of A1(the matrix part of the affine linear map L1) * (n-v1 x n-v1 matrix) * @param b1 translation vector, part of the linear affine map L1 * @param A2inv the inverse of A2(the matrix part of the affine linear map L2) * (n x n matrix) * @param b2 translation vector, part of the linear affine map L2 * @param vi the number of Vinegar-variables per layer * @param layers the polynomials with their coefficients of private map F */ public RainbowPrivateKeySpec(short[][] A1inv, short[] b1, short[][] A2inv, short[] b2, int[] vi, Layer[] layers) { this.A1inv = A1inv; this.b1 = b1; this.A2inv = A2inv; this.b2 = b2; this.vi = vi; this.layers = layers; } /** * Getter for the translation part of the private quadratic map L1. * * @return b1 the translation part of L1 */ public short[] getB1() { return this.b1; } /** * Getter for the inverse matrix of A1. * * @return the A1inv inverse */ public short[][] getInvA1() { return this.A1inv; } /** * Getter for the translation part of the private quadratic map L2. * * @return b2 the translation part of L2 */ public short[] getB2() { return this.b2; } /** * Getter for the inverse matrix of A2 * * @return the A2inv */ public short[][] getInvA2() { return this.A2inv; } /** * Returns the layers contained in the private key * * @return layers */ public Layer[] getLayers() { return this.layers; } /** * /** Returns the array of vi-s * * @return the vi */ public int[] getVi() { return vi; } } bouncycastle-1.49.orig/src/org/bouncycastle/pqc/jcajce/spec/RainbowParameterSpec.java0000644000175000017500000000607111776713757030407 0ustar ebourgebourgpackage org.bouncycastle.pqc.jcajce.spec; import java.security.spec.AlgorithmParameterSpec; import org.bouncycastle.util.Arrays; /** * This class provides methods for setting and getting the Rainbow-parameters * like number of Vinegar-variables in the layers, number of layers and so on. *

    * More detailed information about the needed parameters for the Rainbow * Signature Scheme is to be found in the paper of Jintai Ding, Dieter Schmidt: * Rainbow, a New Multivariable Polynomial Signature Scheme. ACNS 2005: 164-175 * (http://dx.doi.org/10.1007/11496137_12) */ public class RainbowParameterSpec implements AlgorithmParameterSpec { /** * DEFAULT PARAMS */ /* * Vi = vinegars per layer whereas n is vu (vu = 33 = n) such that * * v1 = 6; o1 = 12-6 = 6 * * v2 = 12; o2 = 17-12 = 5 * * v3 = 17; o3 = 22-17 = 5 * * v4 = 22; o4 = 33-22 = 11 * * v5 = 33; (o5 = 0) */ private static final int[] DEFAULT_VI = {6, 12, 17, 22, 33}; private int[] vi;// set of vinegar vars per layer. /** * Default Constructor The elements of the array containing the number of * Vinegar variables in each layer are set to the default values here. */ public RainbowParameterSpec() { this.vi = DEFAULT_VI; } /** * Constructor with parameters * * @param vi The elements of the array containing the number of Vinegar * variables per layer are set to the values of the input array. * @throws IllegalArgumentException if the variables are invalid. */ public RainbowParameterSpec(int[] vi) { this.vi = vi; try { checkParams(); } catch (Exception e) { e.printStackTrace(); } } private void checkParams() throws Exception { if (vi == null) { throw new IllegalArgumentException("no layers defined."); } if (vi.length > 1) { for (int i = 0; i < vi.length - 1; i++) { if (vi[i] >= vi[i + 1]) { throw new IllegalArgumentException( "v[i] has to be smaller than v[i+1]"); } } } else { throw new IllegalArgumentException( "Rainbow needs at least 1 layer, such that v1 < v2."); } } /** * Getter for the number of layers * * @return the number of layers */ public int getNumOfLayers() { return this.vi.length - 1; } /** * Getter for the number of all the polynomials in Rainbow * * @return the number of the polynomials */ public int getDocumentLength() { return vi[vi.length - 1] - vi[0]; } /** * Getter for the array containing the number of Vinegar-variables per layer * * @return the numbers of vinegars per layer */ public int[] getVi() { return Arrays.clone(this.vi); } } bouncycastle-1.49.orig/src/org/bouncycastle/pqc/jcajce/spec/RainbowPublicKeySpec.java0000644000175000017500000000263511776713757030360 0ustar ebourgebourgpackage org.bouncycastle.pqc.jcajce.spec; import java.security.spec.KeySpec; /** * This class provides a specification for a RainbowSignature public key. * * @see KeySpec */ public class RainbowPublicKeySpec implements KeySpec { private short[][] coeffquadratic; private short[][] coeffsingular; private short[] coeffscalar; private int docLength; // length of possible document to sign /** * Constructor * * @param docLength * @param coeffquadratic * @param coeffSingular * @param coeffScalar */ public RainbowPublicKeySpec(int docLength, short[][] coeffquadratic, short[][] coeffSingular, short[] coeffScalar) { this.docLength = docLength; this.coeffquadratic = coeffquadratic; this.coeffsingular = coeffSingular; this.coeffscalar = coeffScalar; } /** * @return the docLength */ public int getDocLength() { return this.docLength; } /** * @return the coeffquadratic */ public short[][] getCoeffQuadratic() { return coeffquadratic; } /** * @return the coeffsingular */ public short[][] getCoeffSingular() { return coeffsingular; } /** * @return the coeffscalar */ public short[] getCoeffScalar() { return coeffscalar; } } bouncycastle-1.49.orig/src/org/bouncycastle/pqc/jcajce/spec/ECCKeyGenParameterSpec.java0000644000175000017500000001115412055035267030461 0ustar ebourgebourgpackage org.bouncycastle.pqc.jcajce.spec; import java.security.InvalidParameterException; import java.security.spec.AlgorithmParameterSpec; import org.bouncycastle.pqc.math.linearalgebra.PolynomialRingGF2; /** * This class provides a specification for the parameters that are used by the * McEliece, McElieceCCA2, and Niederreiter key pair generators. * * @see org.bouncycastle.pqc.ecc.mceliece.McElieceKeyPairGenerator * @see org.bouncycastle.pqc.ecc.mceliece.McElieceCCA2KeyPairGenerator * @see org.bouncycastle.pqc.ecc.niederreiter.NiederreiterKeyPairGenerator */ public class ECCKeyGenParameterSpec implements AlgorithmParameterSpec { /** * The default extension degree */ public static final int DEFAULT_M = 11; /** * The default error correcting capability. */ public static final int DEFAULT_T = 50; /** * extension degree of the finite field GF(2^m) */ private int m; /** * error correction capability of the code */ private int t; /** * length of the code */ private int n; /** * the field polynomial */ private int fieldPoly; /** * Constructor. Set the default parameters: extension degree. */ public ECCKeyGenParameterSpec() { this(DEFAULT_M, DEFAULT_T); } /** * Constructor. * * @param keysize the length of a Goppa code * @throws InvalidParameterException if keysize < 1. */ public ECCKeyGenParameterSpec(int keysize) throws InvalidParameterException { if (keysize < 1) { throw new InvalidParameterException("key size must be positive"); } m = 0; n = 1; while (n < keysize) { n <<= 1; m++; } t = n >>> 1; t /= m; fieldPoly = PolynomialRingGF2.getIrreduciblePolynomial(m); } /** * Constructor. * * @param m degree of the finite field GF(2^m) * @param t error correction capability of the code * @throws InvalidParameterException if m < 1 or m > 32 or * t < 0 or t > n. */ public ECCKeyGenParameterSpec(int m, int t) throws InvalidParameterException { if (m < 1) { throw new InvalidParameterException("m must be positive"); } if (m > 32) { throw new InvalidParameterException("m is too large"); } this.m = m; n = 1 << m; if (t < 0) { throw new InvalidParameterException("t must be positive"); } if (t > n) { throw new InvalidParameterException("t must be less than n = 2^m"); } this.t = t; fieldPoly = PolynomialRingGF2.getIrreduciblePolynomial(m); } /** * Constructor. * * @param m degree of the finite field GF(2^m) * @param t error correction capability of the code * @param poly the field polynomial * @throws InvalidParameterException if m < 1 or m > 32 or * t < 0 or t > n or * poly is not an irreducible field polynomial. */ public ECCKeyGenParameterSpec(int m, int t, int poly) throws InvalidParameterException { this.m = m; if (m < 1) { throw new InvalidParameterException("m must be positive"); } if (m > 32) { throw new InvalidParameterException(" m is too large"); } this.n = 1 << m; this.t = t; if (t < 0) { throw new InvalidParameterException("t must be positive"); } if (t > n) { throw new InvalidParameterException("t must be less than n = 2^m"); } if ((PolynomialRingGF2.degree(poly) == m) && (PolynomialRingGF2.isIrreducible(poly))) { this.fieldPoly = poly; } else { throw new InvalidParameterException( "polynomial is not a field polynomial for GF(2^m)"); } } /** * @return the extension degree of the finite field GF(2^m) */ public int getM() { return m; } /** * @return the length of the code */ public int getN() { return n; } /** * @return the error correction capability of the code */ public int getT() { return t; } /** * @return the field polynomial */ public int getFieldPoly() { return fieldPoly; } } bouncycastle-1.49.orig/src/org/bouncycastle/mail/0000755000175000017500000000000012152033551021421 5ustar ebourgebourgbouncycastle-1.49.orig/src/org/bouncycastle/mail/smime/0000755000175000017500000000000012152033551022533 5ustar ebourgebourgbouncycastle-1.49.orig/src/org/bouncycastle/mail/smime/SMIMEStreamingProcessor.java0000644000175000017500000000032210321675335030027 0ustar ebourgebourgpackage org.bouncycastle.mail.smime; import java.io.IOException; import java.io.OutputStream; public interface SMIMEStreamingProcessor { public void write(OutputStream out) throws IOException; } bouncycastle-1.49.orig/src/org/bouncycastle/mail/smime/validator/0000755000175000017500000000000012152033551024520 5ustar ebourgebourg././@LongLink0000000000000000000000000000015000000000000011561 Lustar rootrootbouncycastle-1.49.orig/src/org/bouncycastle/mail/smime/validator/SignedMailValidatorMessages.propertiesbouncycastle-1.49.orig/src/org/bouncycastle/mail/smime/validator/SignedMailValidatorMessages.propert0000644000175000017500000002713610557030231033517 0ustar ebourgebourg## constructor exception messages # Signature valid SignedMailValidator.sigValid.title = Signature valid SignedMailValidator.sigValid.text = Signature valid SignedMailValidator.sigValid.summary = Signature valid SignedMailValidator.sigValid.details = Signature valid # Signature invalid SignedMailValidator.sigInvalid.title = Signature invalid SignedMailValidator.sigInvalid.text = Signature invalid SignedMailValidator.sigInvalid.summary = Signature invalid SignedMailValidator.sigInvalid.details = Signature invalid # message is not signed SignedMailValidator.noSignedMessage.title = Message is not signed SignedMailValidator.noSignedMessage.text = SignedMailValidator: MimeMessage message is not a signed message. SignedMailValidator.noSignedMessage.summary = SignedMailValidator: MimeMessage message is not a signed message. SignedMailValidator.noSignedMessage.details = SignedMailValidator: MimeMessage message is not a signed message. # exception reading the Mime message # {0} message of the underlying exception # {1} the underlying exception # {2} the name of the exception SignedMailValidator.exceptionReadingMessage.title = Exception reading the MimeMessage SignedMailValidator.exceptionReadingMessage.text = SignedMailValidator: there was a {2} reading the MimeMessage: {0}. SignedMailValidator.exceptionReadingMessage.summary = SignedMailValidator: there was a {2} reading the MimeMessage: {0}. SignedMailValidator.exceptionReadingMessage.details = SignedMailValidator: there was a {2} reading the MimeMessage: {0}. ## exception messages # signer has not signed the mail message SignedMailValidator.wrongSigner.title = Signer has not signed the message SignedMailValidator.wrongSigner.text = The given signer did not sign the mail message. SignedMailValidator.wrongSigner.summary = The given signer did not sign the mail message. SignedMailValidator.wrongSigner.details = The given signer did not sign the mail message. ## notifications messages # short signing key # {0} the key lenght as Integer SignedMailValidator.shortSigningKey.title = Careless short signing key SignedMailValidator.shortSigningKey.text = Warning: The signing key is only {0} bits long. SignedMailValidator.shortSigningKey.summary = Warning: The signing key is only {0} bits long. SignedMailValidator.shortSigningKey.details = Warning: The signing key is only {0} bits long. # signing certificate has very long validity period # {0} notBefore date # {1} notAfter date SignedMailValidator.longValidity.title = Very long validity period SignedMailValidator.longValidity.text = Warning: The signing certificate has a very long validity period: from {0,date} {0,time,full} until {1,date} {1,time,full}. SignedMailValidator.longValidity.summary = Warning: The signing certificate has a very long validity period: from {0,date} {0,time,full} until {1,date} {1,time,full}. SignedMailValidator.longValidity.details = Warning: The signing certificate has a very long validity period: from {0,date} {0,time,full} until {1,date} {1,time,full}. # signed receipt requested SignedMailValidator.signedReceiptRequest.title = Signed Receipt Request SignedMailValidator.signedReceiptRequest.text = The signature contains a signed receipt request. SignedMailValidator.signedReceiptRequest.summary = The signature contains a signed receipt request. SignedMailValidator.signedReceiptRequest.details = The signature contains a signed receipt request as per RFC 2634. ## error messages # no signer certificate found SignedMailValidator.noSignerCert.title = No signer certificate found SignedMailValidator.noSignerCert.text = Signature Validation failed: No signer certificate found. SignedMailValidator.noSignerCert.summary = Signature Validation failed: No signer certificate found. SignedMailValidator.noSignerCert.details = Signature Validation failed: No signer certificate found. # certificate contains no email address SignedMailValidator.noEmailInCert.title = Certificate not usable for email signatures SignedMailValidator.noEmailInCert.text = The signer certificate is not usable for email signatures: it contains no email address. SignedMailValidator.noEmailInCert.summary = The signer certificate is not usable for email signatures: it contains no email address. SignedMailValidator.noEmailInCert.details = The signer certificate is not usable for email signatures: it contains no email address. # certificate email address does not match from email address # {0} from email addresses in the message # {1} email addresses in the certificate SignedMailValidator.emailFromCertMismatch.title = Email address mismatch SignedMailValidator.emailFromCertMismatch.text = Email address in singer certificate does not match the sender address. Signer email: {1}. Sender email: {0}. SignedMailValidator.emailFromCertMismatch.summary = Email address in singer certificate does not match the sender address. Signer email: {1}. Sender email: {0}. SignedMailValidator.emailFromCertMismatch.details = Email address in singer certificate does not match the sender address. Signer email: {1}. Sender email: {0}. # exception extracting email addresses from certificate # {0} message of the underlying exception # {1} the underlying exception # {2} the name of the exception SignedMailValidator.certGetEmailError.title = Exception extracting email addresses from certificate SignedMailValidator.certGetEmailError.text = There was a {2} extracting the email addresses from the certificate. Cause: {0}. SignedMailValidator.certGetEmailError.summary = There was a {2} extracting the email addresses from the certificate. SignedMailValidator.certGetEmailError.details = There was a {2} extracting the email addresses from the certificate. Cause: {0}. # no signing time found SignedMailValidator.noSigningTime.title = No signing time SignedMailValidator.noSigningTime.text = The signature contains no signing time. Using the current time for validating the certificate path. SignedMailValidator.noSigningTime.summary = The signature contains no signing time. SignedMailValidator.noSigningTime.details = The signature contains no signing time. Using the current time for validating the certificate path. # expired at signing time # {0} signing time # {1} not after date SignedMailValidator.certExpired.title = Certificate expired at signing time SignedMailValidator.certExpired.text = The message was signed at {0,date} {0,time,full}. But the certificate expired at {1,date} {1,time,full}. SignedMailValidator.certExpired.summary = The message was signed at {0,date} {0,time,full}. But the certificate expired at {1,date} {1,time,full}. SignedMailValidator.certExpired.details = The message was signed at {0,date} {0,time,full}. But the certificate expired at {1,date} {1,time,full}. # not yet valid at signing time # {0} signing time # {1} notBefore date SignedMailValidator.certNotYetValid.title = Certificate not yet valid at signing time SignedMailValidator.certNotYetValid.text = The message was signed at {0,date} {0,time,full}. But the certificate is not valid before {1,date} {1,time,full}. SignedMailValidator.certNotYetValid.summary = The message was signed at {0,date} {0,time,full}. But the certificate is not valid before {1,date} {1,time,full}. SignedMailValidator.certNotYetValid.details = The message was signed at {0,date} {0,time,full}. But the certificate is not valid before {1,date} {1,time,full}. # exception retrieving the signer certificate # {0} message of the underlying exception # {1} the underlying exception # {2} the name of the exception SignedMailValidator.exceptionRetrievingSignerCert.title = Exception retrieving the signer certificate SignedMailValidator.exceptionRetrievingSignerCert.text = Signature Validation failed. There was a {2} retrieving the signer certificate: {0}. SignedMailValidator.exceptionRetrievingSignerCert.summary = Signature Validation failed. There was a {2} retrieving the signer certificate. SignedMailValidator.exceptionRetrievingSignerCert.details = Signature Validation failed There was a {2} retrieving the signer certificate: {0}. # exception verifying the signature # {0} message of the underlying exception # {1} the underlying exception # {2} the name of the exception SignedMailValidator.exceptionVerifyingSignature.title = Signature not verified SignedMailValidator.exceptionVerifyingSignature.text = Signature not verified. There was a {2}. Cause: {0}. SignedMailValidator.exceptionVerifyingSignature.summary = Signature not verified. There was a {2}. SignedMailValidator.exceptionVerifyingSignature.details = Signature not verified. There was a {2}. Cause: {0}. # signature not verified SignedMailValidator.signatureNotVerified.title = Signature not verified SignedMailValidator.signatureNotVerified.text = Signature not verified. The public key of the signer does not correspond to the signature. SignedMailValidator.signatureNotVerified.summary = Signature not verified. The public key of the signer does not correspond to the signature. SignedMailValidator.signatureNotVerified.details = Signature not verified. The public key of the signer does not correspond to the signature. # certificate key usage does not permit digitalSignature or nonRepudiation SignedMailValidator.signingNotPermitted.title = Key not usable for email signatures SignedMailValidator.signingNotPermitted.text = The key usage extension of signer certificate does not permit using the key for email signatures. SignedMailValidator.signingNotPermitted.summary = The signer key is not usable for email signatures. SignedMailValidator.signingNotPermitted.details = The key usage extension of signer certificate does not permit using the key for email signatures. # certificate extended key usage does not permit emailProtection or anyExtendedKeyUsage SignedMailValidator.extKeyUsageNotPermitted.title = Key not usable for email signatures SignedMailValidator.extKeyUsageNotPermitted.text = The extended key usage extension of the signer certificate does not permit using the key for email signatures. SignedMailValidator.extKeyUsageNotPermitted.summary = The signer key is not usable for email signatures. SignedMailValidator.extKeyUsageNotPermitted.details = The extended key usage extension of the signer certificate does not permit using the key for email signatures. # exception processing the extended key usage extension # {0} message of the underlying exception # {1} the underlying exception # {2} the name of the exception SignedMailValidator.extKeyUsageError.title = Exception processing the extended key usage extension SignedMailValidator.extKeyUsageError.text = There was a {2} processing the extended key usage extension. Cause: {0}. SignedMailValidator.extKeyUsageError.summary = There was a {2} processing the extended key usage extension. SignedMailValidator.extKeyUsageError.details = There was a {2} processing the extended key usage extension. Cause: {0}. # cannot create certificate path (exception) # {0} message of the underlying exception # {1} the underlying exception # {2} the name of the exception SignedMailValidator.exceptionCreateCertPath.title = Certificate path validation failed SignedMailValidator.exceptionCreateCertPath.text = Certificate path validation failed. There was a {2} creating the CertPath: {0}. SignedMailValidator.exceptionCreateCertPath.summary = Certificate path validation failed. There was a {2} creating the CertPath: {0}. SignedMailValidator.exceptionCreateCertPath.details = Certificate path validation failed. There was a {2} creating the CertPath: {0}. # certificate path is invalid SignedMailValidator.certPathInvalid.title = Certificate path invalid SignedMailValidator.certPathInvalid.text = The certificate path is invalid. SignedMailValidator.certPathInvalid.summary = The certificate path is invalid. SignedMailValidator.certPathInvalid.details = The certificate path is invalid. bouncycastle-1.49.orig/src/org/bouncycastle/mail/smime/validator/SignedMailValidatorException.java0000644000175000017500000000072210472271362033134 0ustar ebourgebourgpackage org.bouncycastle.mail.smime.validator; import org.bouncycastle.i18n.ErrorBundle; import org.bouncycastle.i18n.LocalizedException; public class SignedMailValidatorException extends LocalizedException { public SignedMailValidatorException(ErrorBundle errorMessage, Throwable throwable) { super(errorMessage, throwable); } public SignedMailValidatorException(ErrorBundle errorMessage) { super(errorMessage); } } bouncycastle-1.49.orig/src/org/bouncycastle/mail/smime/validator/SignedMailValidator.java0000644000175000017500000010474312103440465031260 0ustar ebourgebourgpackage org.bouncycastle.mail.smime.validator; import java.io.IOException; import java.security.GeneralSecurityException; import java.security.PublicKey; import java.security.cert.CertPath; import java.security.cert.CertStore; import java.security.cert.CertStoreException; import java.security.cert.CertificateEncodingException; import java.security.cert.CertificateExpiredException; import java.security.cert.CertificateFactory; import java.security.cert.CertificateNotYetValidException; import java.security.cert.PKIXParameters; import java.security.cert.TrustAnchor; import java.security.cert.X509CertSelector; import java.security.cert.X509Certificate; import java.security.interfaces.DSAPublicKey; import java.security.interfaces.RSAPublicKey; import java.util.ArrayList; import java.util.Collection; import java.util.Date; import java.util.HashMap; import java.util.HashSet; import java.util.Iterator; import java.util.LinkedHashSet; import java.util.List; import java.util.Map; import java.util.Set; import java.util.Vector; import javax.mail.Address; import javax.mail.MessagingException; import javax.mail.internet.InternetAddress; import javax.mail.internet.MimeMessage; import javax.mail.internet.MimeMultipart; import org.bouncycastle.asn1.ASN1Encoding; import org.bouncycastle.asn1.ASN1InputStream; import org.bouncycastle.asn1.ASN1OctetString; import org.bouncycastle.asn1.ASN1Primitive; import org.bouncycastle.asn1.ASN1Sequence; import org.bouncycastle.asn1.ASN1TaggedObject; import org.bouncycastle.asn1.DERIA5String; import org.bouncycastle.asn1.DEROctetString; import org.bouncycastle.asn1.cms.Attribute; import org.bouncycastle.asn1.cms.AttributeTable; import org.bouncycastle.asn1.cms.CMSAttributes; import org.bouncycastle.asn1.cms.Time; import org.bouncycastle.asn1.pkcs.PKCSObjectIdentifiers; import org.bouncycastle.asn1.x509.AuthorityKeyIdentifier; import org.bouncycastle.asn1.x509.ExtendedKeyUsage; import org.bouncycastle.asn1.x509.KeyPurposeId; import org.bouncycastle.asn1.x509.X509Extensions; import org.bouncycastle.cms.SignerInformation; import org.bouncycastle.cms.SignerInformationStore; import org.bouncycastle.cms.jcajce.JcaX509CertSelectorConverter; import org.bouncycastle.i18n.ErrorBundle; import org.bouncycastle.i18n.filter.TrustedInput; import org.bouncycastle.i18n.filter.UntrustedInput; import org.bouncycastle.jce.PrincipalUtil; import org.bouncycastle.jce.X509Principal; import org.bouncycastle.mail.smime.SMIMESigned; import org.bouncycastle.util.Integers; import org.bouncycastle.x509.CertPathReviewerException; import org.bouncycastle.x509.PKIXCertPathReviewer; public class SignedMailValidator { private static final String RESOURCE_NAME = "org.bouncycastle.mail.smime.validator.SignedMailValidatorMessages"; private static final Class DEFAULT_CERT_PATH_REVIEWER = PKIXCertPathReviewer.class; private static final String EXT_KEY_USAGE = X509Extensions.ExtendedKeyUsage .getId(); private static final String SUBJECT_ALTERNATIVE_NAME = X509Extensions.SubjectAlternativeName .getId(); private static final int shortKeyLength = 512; // (365.25*30)*24*3600*1000 private static final long THIRTY_YEARS_IN_MILLI_SEC = 21915l*12l*3600l*1000l; private static final JcaX509CertSelectorConverter selectorConverter = new JcaX509CertSelectorConverter(); private CertStore certs; private SignerInformationStore signers; private Map results; private String[] fromAddresses; private Class certPathReviewerClass; /** * Validates the signed {@link MimeMessage} message. The * {@link PKIXParameters} from param are used for the certificate path * validation. The actual PKIXParameters used for the certificate path * validation is a copy of param with the followin changes:
    - The * validation date is changed to the signature time
    - A CertStore with * certificates and crls from the mail message is added to the CertStores.
    *
    * In param it's also possible to add additional CertStores * with intermediate Certificates and/or CRLs which then are also used for * the validation. * * @param message * the signed MimeMessage * @param param * the parameters for the certificate path validation * @throws SignedMailValidatorException * if the message is no signed message or if an exception occurs * reading the message */ public SignedMailValidator(MimeMessage message, PKIXParameters param) throws SignedMailValidatorException { this(message, param, DEFAULT_CERT_PATH_REVIEWER); } /** * Validates the signed {@link MimeMessage} message. The * {@link PKIXParameters} from param are used for the certificate path * validation. The actual PKIXParameters used for the certificate path * validation is a copy of param with the followin changes:
    - The * validation date is changed to the signature time
    - A CertStore with * certificates and crls from the mail message is added to the CertStores.
    *
    * In param it's also possible to add additional CertStores * with intermediate Certificates and/or CRLs which then are also used for * the validation. * * @param message * the signed MimeMessage * @param param * the parameters for the certificate path validation * @param certPathReviewerClass * a subclass of {@link PKIXCertPathReviewer}. The SignedMailValidator * uses objects of this type for the cert path vailidation. The class must * have an empty constructor. * @throws SignedMailValidatorException * if the message is no signed message or if an exception occurs * reading the message * @throws IllegalArgumentException if the certPathReviewerClass is not a * subclass of {@link PKIXCertPathReviewer} or objects of * certPathReviewerClass can not be instantiated */ public SignedMailValidator(MimeMessage message, PKIXParameters param, Class certPathReviewerClass) throws SignedMailValidatorException { this.certPathReviewerClass = certPathReviewerClass; boolean isSubclass = DEFAULT_CERT_PATH_REVIEWER.isAssignableFrom(certPathReviewerClass); if(!isSubclass) { throw new IllegalArgumentException("certPathReviewerClass is not a subclass of " + DEFAULT_CERT_PATH_REVIEWER.getName()); } SMIMESigned s; try { // check if message is multipart signed if (message.isMimeType("multipart/signed")) { MimeMultipart mimemp = (MimeMultipart) message.getContent(); s = new SMIMESigned(mimemp); } else if (message.isMimeType("application/pkcs7-mime") || message.isMimeType("application/x-pkcs7-mime")) { s = new SMIMESigned(message); } else { ErrorBundle msg = new ErrorBundle(RESOURCE_NAME, "SignedMailValidator.noSignedMessage"); throw new SignedMailValidatorException(msg); } // save certstore and signerInformationStore certs = s.getCertificatesAndCRLs("Collection", "BC"); signers = s.getSignerInfos(); // save "from" addresses from message Address[] froms = message.getFrom(); InternetAddress sender = null; try { if(message.getHeader("Sender") != null) { sender = new InternetAddress(message.getHeader("Sender")[0]); } } catch (MessagingException ex) { //ignore garbage in Sender: header } fromAddresses = new String[froms.length + (sender!=null?1:0)]; for (int i = 0; i < froms.length; i++) { InternetAddress inetAddr = (InternetAddress) froms[i]; fromAddresses[i] = inetAddr.getAddress(); } if(sender!=null) { fromAddresses[froms.length] = sender.getAddress(); } // initialize results results = new HashMap(); } catch (Exception e) { if (e instanceof SignedMailValidatorException) { throw (SignedMailValidatorException) e; } // exception reading message ErrorBundle msg = new ErrorBundle(RESOURCE_NAME, "SignedMailValidator.exceptionReadingMessage", new Object[] { e.getMessage(), e , e.getClass().getName()}); throw new SignedMailValidatorException(msg, e); } // validate signatues validateSignatures(param); } protected void validateSignatures(PKIXParameters pkixParam) { PKIXParameters usedParameters = (PKIXParameters) pkixParam.clone(); // add crls and certs from mail usedParameters.addCertStore(certs); Collection c = signers.getSigners(); Iterator it = c.iterator(); // check each signer while (it.hasNext()) { List errors = new ArrayList(); List notifications = new ArrayList(); SignerInformation signer = (SignerInformation) it.next(); // signer certificate X509Certificate cert = null; try { Collection certCollection = findCerts(usedParameters .getCertStores(), selectorConverter.getCertSelector(signer.getSID())); Iterator certIt = certCollection.iterator(); if (certIt.hasNext()) { cert = (X509Certificate) certIt.next(); } } catch (CertStoreException cse) { ErrorBundle msg = new ErrorBundle(RESOURCE_NAME, "SignedMailValidator.exceptionRetrievingSignerCert", new Object[] { cse.getMessage(), cse , cse.getClass().getName()}); errors.add(msg); } if (cert != null) { // check signature boolean validSignature = false; try { validSignature = signer.verify(cert.getPublicKey(), "BC"); if (!validSignature) { ErrorBundle msg = new ErrorBundle(RESOURCE_NAME, "SignedMailValidator.signatureNotVerified"); errors.add(msg); } } catch (Exception e) { ErrorBundle msg = new ErrorBundle(RESOURCE_NAME, "SignedMailValidator.exceptionVerifyingSignature", new Object[] { e.getMessage(), e, e.getClass().getName() }); errors.add(msg); } // check signer certificate (mail address, key usage, etc) checkSignerCert(cert, errors, notifications); // notify if a signed receip request is in the message AttributeTable atab = signer.getSignedAttributes(); if (atab != null) { Attribute attr = atab.get(PKCSObjectIdentifiers.id_aa_receiptRequest); if (attr != null) { ErrorBundle msg = new ErrorBundle(RESOURCE_NAME, "SignedMailValidator.signedReceiptRequest"); notifications.add(msg); } } // check certificate path // get signing time if possible, otherwise use current time as // signing time Date signTime = getSignatureTime(signer); if (signTime == null) // no signing time was found { ErrorBundle msg = new ErrorBundle(RESOURCE_NAME, "SignedMailValidator.noSigningTime"); errors.add(msg); signTime = new Date(); } else { // check if certificate was valid at signing time try { cert.checkValidity(signTime); } catch (CertificateExpiredException e) { ErrorBundle msg = new ErrorBundle(RESOURCE_NAME, "SignedMailValidator.certExpired", new Object[] { new TrustedInput(signTime), new TrustedInput(cert.getNotAfter()) }); errors.add(msg); } catch (CertificateNotYetValidException e) { ErrorBundle msg = new ErrorBundle(RESOURCE_NAME, "SignedMailValidator.certNotYetValid", new Object[] { new TrustedInput(signTime), new TrustedInput(cert.getNotBefore()) }); errors.add(msg); } } usedParameters.setDate(signTime); try { // construct cert chain CertPath certPath; List userProvidedList; List userCertStores = new ArrayList(); userCertStores.add(certs); Object[] cpres = createCertPath(cert, usedParameters.getTrustAnchors(), pkixParam.getCertStores(), userCertStores); certPath = (CertPath) cpres[0]; userProvidedList = (List) cpres[1]; // validate cert chain PKIXCertPathReviewer review; try { review = (PKIXCertPathReviewer)certPathReviewerClass.newInstance(); } catch (IllegalAccessException e) { throw new IllegalArgumentException("Cannot instantiate object of type " + certPathReviewerClass.getName() + ": " + e.getMessage()); } catch (InstantiationException e) { throw new IllegalArgumentException("Cannot instantiate object of type " + certPathReviewerClass.getName() + ": " + e.getMessage()); } review.init(certPath, usedParameters); if (!review.isValidCertPath()) { ErrorBundle msg = new ErrorBundle(RESOURCE_NAME, "SignedMailValidator.certPathInvalid"); errors.add(msg); } results.put(signer, new ValidationResult(review, validSignature, errors, notifications, userProvidedList)); } catch (GeneralSecurityException gse) { // cannot create cert path ErrorBundle msg = new ErrorBundle(RESOURCE_NAME, "SignedMailValidator.exceptionCreateCertPath", new Object[] { gse.getMessage(), gse, gse.getClass().getName() }); errors.add(msg); results.put(signer, new ValidationResult(null, validSignature, errors, notifications, null)); } catch (CertPathReviewerException cpre) { // cannot initialize certpathreviewer - wrong parameters errors.add(cpre.getErrorMessage()); results.put(signer, new ValidationResult(null, validSignature, errors, notifications, null)); } } else // no signer certificate found { ErrorBundle msg = new ErrorBundle(RESOURCE_NAME, "SignedMailValidator.noSignerCert"); errors.add(msg); results.put(signer, new ValidationResult(null, false, errors, notifications, null)); } } } public static Set getEmailAddresses(X509Certificate cert) throws IOException, CertificateEncodingException { Set addresses = new HashSet(); X509Principal name = PrincipalUtil.getSubjectX509Principal(cert); Vector oids = name.getOIDs(); Vector names = name.getValues(); for (int i = 0; i < oids.size(); i++) { if (oids.get(i).equals(X509Principal.EmailAddress)) { String email = ((String) names.get(i)).toLowerCase(); addresses.add(email); break; } } byte[] ext = cert.getExtensionValue(SUBJECT_ALTERNATIVE_NAME); if (ext != null) { ASN1Sequence altNames = ASN1Sequence.getInstance(getObject(ext)); for (int j = 0; j < altNames.size(); j++) { ASN1TaggedObject o = (ASN1TaggedObject) altNames .getObjectAt(j); if (o.getTagNo() == 1) { String email = DERIA5String.getInstance(o, false) .getString().toLowerCase(); addresses.add(email); } } } return addresses; } private static ASN1Primitive getObject(byte[] ext) throws IOException { ASN1InputStream aIn = new ASN1InputStream(ext); ASN1OctetString octs = (ASN1OctetString) aIn.readObject(); aIn = new ASN1InputStream(octs.getOctets()); return aIn.readObject(); } protected void checkSignerCert(X509Certificate cert, List errors, List notifications) { // get key length PublicKey key = cert.getPublicKey(); int keyLenght = -1; if (key instanceof RSAPublicKey) { keyLenght = ((RSAPublicKey) key).getModulus().bitLength(); } else if (key instanceof DSAPublicKey) { keyLenght = ((DSAPublicKey) key).getParams().getP().bitLength(); } if (keyLenght != -1 && keyLenght <= shortKeyLength) { ErrorBundle msg = new ErrorBundle(RESOURCE_NAME, "SignedMailValidator.shortSigningKey", new Object[]{Integers.valueOf(keyLenght)}); notifications.add(msg); } // warn if certificate has very long validity period long validityPeriod = cert.getNotAfter().getTime() - cert.getNotBefore().getTime(); if (validityPeriod > THIRTY_YEARS_IN_MILLI_SEC) { ErrorBundle msg = new ErrorBundle(RESOURCE_NAME, "SignedMailValidator.longValidity", new Object[] {new TrustedInput(cert.getNotBefore()), new TrustedInput(cert.getNotAfter())}); notifications.add(msg); } // check key usage if digitalSignature or nonRepudiation is set boolean[] keyUsage = cert.getKeyUsage(); if (keyUsage != null && !keyUsage[0] && !keyUsage[1]) { ErrorBundle msg = new ErrorBundle(RESOURCE_NAME, "SignedMailValidator.signingNotPermitted"); errors.add(msg); } // check extended key usage try { byte[] ext = cert.getExtensionValue(EXT_KEY_USAGE); if (ext != null) { ExtendedKeyUsage extKeyUsage = ExtendedKeyUsage .getInstance(getObject(ext)); if (!extKeyUsage .hasKeyPurposeId(KeyPurposeId.anyExtendedKeyUsage) && !extKeyUsage .hasKeyPurposeId(KeyPurposeId.id_kp_emailProtection)) { ErrorBundle msg = new ErrorBundle(RESOURCE_NAME, "SignedMailValidator.extKeyUsageNotPermitted"); errors.add(msg); } } } catch (Exception e) { ErrorBundle msg = new ErrorBundle(RESOURCE_NAME, "SignedMailValidator.extKeyUsageError", new Object[] { e.getMessage(), e, e.getClass().getName() }); errors.add(msg); } // cert has an email address try { Set certEmails = getEmailAddresses(cert); if (certEmails.isEmpty()) { // error no email address in signing certificate ErrorBundle msg = new ErrorBundle(RESOURCE_NAME, "SignedMailValidator.noEmailInCert"); errors.add(msg); } else { // check if email in cert is equal to the from address in the // message boolean equalsFrom = false; for (int i = 0; i < fromAddresses.length; i++) { if (certEmails.contains(fromAddresses[i].toLowerCase())) { equalsFrom = true; break; } } if (!equalsFrom) { ErrorBundle msg = new ErrorBundle(RESOURCE_NAME, "SignedMailValidator.emailFromCertMismatch", new Object[] { new UntrustedInput( addressesToString(fromAddresses)), new UntrustedInput(certEmails) }); errors.add(msg); } } } catch (Exception e) { ErrorBundle msg = new ErrorBundle(RESOURCE_NAME, "SignedMailValidator.certGetEmailError", new Object[] { e.getMessage(), e, e.getClass().getName() }); errors.add(msg); } } static String addressesToString(Object[] a) { if (a == null) { return "null"; } StringBuffer b = new StringBuffer(); b.append('['); for (int i = 0; i != a.length; i++) { if (i > 0) { b.append(", "); } b.append(String.valueOf(a[i])); } return b.append(']').toString(); } public static Date getSignatureTime(SignerInformation signer) { AttributeTable atab = signer.getSignedAttributes(); Date result = null; if (atab != null) { Attribute attr = atab.get(CMSAttributes.signingTime); if (attr != null) { Time t = Time.getInstance(attr.getAttrValues().getObjectAt(0) .toASN1Primitive()); result = t.getDate(); } } return result; } private static List findCerts(List certStores, X509CertSelector selector) throws CertStoreException { List result = new ArrayList(); Iterator it = certStores.iterator(); while (it.hasNext()) { CertStore store = (CertStore) it.next(); Collection coll = store.getCertificates(selector); result.addAll(coll); } return result; } private static X509Certificate findNextCert(List certStores, X509CertSelector selector, Set certSet) throws CertStoreException { Iterator certIt = findCerts(certStores, selector).iterator(); boolean certFound = false; X509Certificate nextCert = null; while (certIt.hasNext()) { nextCert = (X509Certificate) certIt.next(); if (!certSet.contains(nextCert)) { certFound = true; break; } } return certFound ? nextCert : null; } /** * * @param signerCert the end of the path * @param trustanchors trust anchors for the path * @param certStores * @return the resulting certificate path. * @throws GeneralSecurityException */ public static CertPath createCertPath(X509Certificate signerCert, Set trustanchors, List certStores) throws GeneralSecurityException { Object[] results = createCertPath(signerCert, trustanchors, certStores, null); return (CertPath) results[0]; } /** * Returns an Object array containing a CertPath and a List of Booleans. The list contains the value true * if the corresponding certificate in the CertPath was taken from the user provided CertStores. * @param signerCert the end of the path * @param trustanchors trust anchors for the path * @param systemCertStores list of {@link CertStore} provided by the system * @param userCertStores list of {@link CertStore} provided by the user * @return a CertPath and a List of booleans. * @throws GeneralSecurityException */ public static Object[] createCertPath(X509Certificate signerCert, Set trustanchors, List systemCertStores, List userCertStores) throws GeneralSecurityException { Set certSet = new LinkedHashSet(); List userProvidedList = new ArrayList(); // add signer certificate X509Certificate cert = signerCert; certSet.add(cert); userProvidedList.add(new Boolean(true)); boolean trustAnchorFound = false; X509Certificate taCert = null; // add other certs to the cert path while (cert != null && !trustAnchorFound) { // check if cert Issuer is Trustanchor Iterator trustIt = trustanchors.iterator(); while (trustIt.hasNext()) { TrustAnchor anchor = (TrustAnchor) trustIt.next(); X509Certificate anchorCert = anchor.getTrustedCert(); if (anchorCert != null) { if (anchorCert.getSubjectX500Principal().equals( cert.getIssuerX500Principal())) { try { cert.verify(anchorCert.getPublicKey(), "BC"); trustAnchorFound = true; taCert = anchorCert; break; } catch (Exception e) { // trustanchor not found } } } else { if (anchor.getCAName().equals( cert.getIssuerX500Principal().getName())) { try { cert.verify(anchor.getCAPublicKey(), "BC"); trustAnchorFound = true; break; } catch (Exception e) { // trustanchor not found } } } } if (!trustAnchorFound) { // add next cert to path X509CertSelector select = new X509CertSelector(); try { select.setSubject(cert.getIssuerX500Principal().getEncoded()); } catch (IOException e) { throw new IllegalStateException(e.toString()); } byte[] authKeyIdentBytes = cert.getExtensionValue(X509Extensions.AuthorityKeyIdentifier.getId()); if (authKeyIdentBytes != null) { try { AuthorityKeyIdentifier kid = AuthorityKeyIdentifier.getInstance(getObject(authKeyIdentBytes)); if (kid.getKeyIdentifier() != null) { select.setSubjectKeyIdentifier(new DEROctetString(kid.getKeyIdentifier()).getEncoded(ASN1Encoding.DER)); } } catch (IOException ioe) { // ignore } } boolean userProvided = false; cert = findNextCert(systemCertStores, select, certSet); if (cert == null && userCertStores != null) { userProvided = true; cert = findNextCert(userCertStores, select, certSet); } if (cert != null) { // cert found certSet.add(cert); userProvidedList.add(new Boolean(userProvided)); } } } // if a trustanchor was found - try to find a selfsigned certificate of // the trustanchor if (trustAnchorFound) { if (taCert != null && taCert.getSubjectX500Principal().equals(taCert.getIssuerX500Principal())) { certSet.add(taCert); userProvidedList.add(new Boolean(false)); } else { X509CertSelector select = new X509CertSelector(); try { select.setSubject(cert.getIssuerX500Principal().getEncoded()); select.setIssuer(cert.getIssuerX500Principal().getEncoded()); } catch (IOException e) { throw new IllegalStateException(e.toString()); } boolean userProvided = false; taCert = findNextCert(systemCertStores, select, certSet); if (taCert == null && userCertStores != null) { userProvided = true; taCert = findNextCert(userCertStores, select, certSet); } if (taCert != null) { try { cert.verify(taCert.getPublicKey(), "BC"); certSet.add(taCert); userProvidedList.add(new Boolean(userProvided)); } catch (GeneralSecurityException gse) { // wrong cert } } } } CertPath certPath = CertificateFactory.getInstance("X.509", "BC").generateCertPath(new ArrayList(certSet)); return new Object[] {certPath, userProvidedList}; } public CertStore getCertsAndCRLs() { return certs; } public SignerInformationStore getSignerInformationStore() { return signers; } public ValidationResult getValidationResult(SignerInformation signer) throws SignedMailValidatorException { if (signers.getSigners(signer.getSID()).isEmpty()) { // the signer is not part of the SignerInformationStore // he has not signed the message ErrorBundle msg = new ErrorBundle(RESOURCE_NAME, "SignedMailValidator.wrongSigner"); throw new SignedMailValidatorException(msg); } else { return (ValidationResult) results.get(signer); } } public class ValidationResult { private PKIXCertPathReviewer review; private List errors; private List notifications; private List userProvidedCerts; private boolean signVerified; ValidationResult(PKIXCertPathReviewer review, boolean verified, List errors, List notifications, List userProvidedCerts) { this.review = review; this.errors = errors; this.notifications = notifications; signVerified = verified; this.userProvidedCerts = userProvidedCerts; } /** * Returns a list of error messages of type {@link ErrorBundle}. * * @return List of error messages */ public List getErrors() { return errors; } /** * Returns a list of notification messages of type {@link ErrorBundle}. * * @return List of notification messages */ public List getNotifications() { return notifications; } /** * * @return the PKIXCertPathReviewer for the CertPath of this signature * or null if an Exception occured. */ public PKIXCertPathReviewer getCertPathReview() { return review; } /** * * @return the CertPath for this signature * or null if an Exception occured. */ public CertPath getCertPath() { return review != null ? review.getCertPath() : null; } /** * * @return a List of Booleans that are true if the corresponding certificate in the CertPath was taken from * the CertStore of the SMIME message */ public List getUserProvidedCerts() { return userProvidedCerts; } /** * * @return true if the signature corresponds to the public key of the * signer */ public boolean isVerifiedSignature() { return signVerified; } /** * * @return true if the signature is valid (ie. if it corresponds to the * public key of the signer and the cert path for the signers * certificate is also valid) */ public boolean isValidSignature() { if (review != null) { return signVerified && review.isValidCertPath() && errors.isEmpty(); } else { return false; } } } } ././@LongLink0000000000000000000000000000015300000000000011564 Lustar rootrootbouncycastle-1.49.orig/src/org/bouncycastle/mail/smime/validator/SignedMailValidatorMessages_de.propertiesbouncycastle-1.49.orig/src/org/bouncycastle/mail/smime/validator/SignedMailValidatorMessages_de.prop0000644000175000017500000003037310606356714033465 0ustar ebourgebourg## constructor exception messages # Signatur gültig SignedMailValidator.sigValid.title = Signatur gültig SignedMailValidator.sigValid.text = Signatur gültig SignedMailValidator.sigValid.summary = Signatur gültig SignedMailValidator.sigValid.details = Signatur gültig # Signatur ungültig SignedMailValidator.sigInvalid.title = Signatur ungültig SignedMailValidator.sigInvalid.text = Signatur ungültig SignedMailValidator.sigInvalid.summary = Signatur ungültig SignedMailValidator.sigInvalid.details = Signatur ungültig # message is not signed SignedMailValidator.noSignedMessage.title = Die Nachricht ist nicht signiert SignedMailValidator.noSignedMessage.text = SignedMailValidator: Die MimeMessage message ist nicht signiert. SignedMailValidator.noSignedMessage.summary = SignedMailValidator: Die MimeMessage message ist nicht signiert. SignedMailValidator.noSignedMessage.details = SignedMailValidator: Die MimeMessage message ist nicht signiert. # exception reading the Mime message # {0} message of the underlying exception # {1} the underlying exception # {2} the name of the exception SignedMailValidator.exceptionReadingMessage.title = Fehler beim lesen der MimeMessage SignedMailValidator.exceptionReadingMessage.text = SignedMailValidator: Es gab eine {2} beim lesen der MimeMessage: {0}. SignedMailValidator.exceptionReadingMessage.summary = SignedMailValidator: Es gab eine {2} beim lesen der MimeMessage. SignedMailValidator.exceptionReadingMessage.details = SignedMailValidator: Es gab eine {2} beim lesen der MimeMessage: {0}. ## exception messages # signer has not signed the mail message SignedMailValidator.wrongSigner.title = Falscher Unterzeichner SignedMailValidator.wrongSigner.text = Die Email enhält keine Signatur vom gegebenen Unterzeichner. SignedMailValidator.wrongSigner.summary = Die Email enhält keine Signatur vom gegebenen Unterzeichner. SignedMailValidator.wrongSigner.details = Die Email enhält keine Signatur vom gegebenen Unterzeichner. ## notifications messages # short signing key # {0} the key lenght as Integer SignedMailValidator.shortSigningKey.title = Fahrlässig kurzer Signaturschlüssel SignedMailValidator.shortSigningKey.text = Warnung: Der Signaturschlüssel ist nur {0} bit lang. SignedMailValidator.shortSigningKey.summary = Warnung: Der Signaturschlüssel ist nur {0} bit lang. SignedMailValidator.shortSigningKey.details = Warnung: Der Signaturschlüssel ist nur {0} bit lang. # signing certificate has very long validity period # {0} notBefore date # {1} notAfter date SignedMailValidator.longValidity.title = Sehr lange Gültigkeitsdauer SignedMailValidator.longValidity.text = Warnung: Das Signierzertifikat hat eine sehr lange Gültigkeitsdauer: von {0,date} {0,time,full} bis {1,date} {1,time,full}. SignedMailValidator.longValidity.summary = Warnung: Das Signierzertifikat hat eine sehr lange Gültigkeitsdauer: von {0,date} {0,time,full} bis {1,date} {1,time,full}. SignedMailValidator.longValidity.details = Warnung: Das Signierzertifikat hat eine sehr lange Gültigkeitsdauer: von {0,date} {0,time,full} bis {1,date} {1,time,full}. # signed receipt requested SignedMailValidator.signedReceiptRequest.title = Signed Receipt Request SignedMailValidator.signedReceiptRequest.text = Die Signatur enthält einen signed receipt request. SignedMailValidator.signedReceiptRequest.summary = Die Signatur enthält einen signed receipt request. SignedMailValidator.signedReceiptRequest.details = Die Signatur enthält einen signed receipt request gemäss RFC 2634. ## error messages # no signer certificate found SignedMailValidator.noSignerCert.title = Kein Unterzeichner Zertifikat gefunden SignedMailValidator.noSignerCert.text = Signatur Validierung fehlgeschlagen: Es wurde kein Unterzeichner Zertifikat gefunden. SignedMailValidator.noSignerCert.summary = Signatur Validierung fehlgeschlagen: Es wurde kein Unterzeichner Zertifikat gefunden. SignedMailValidator.noSignerCert.details = Signatur Validierung fehlgeschlagen: Es wurde kein Unterzeichner Zertifikat gefunden. # certificate contains no email address SignedMailValidator.noEmailInCert.title = Zertifikat nicht für Email Signaturen verwendbar SignedMailValidator.noEmailInCert.text = Das Unterzeichner Zertifikat kann nicht für Email Signaturen verwendet werden: Es enthält keine Email Addresse. SignedMailValidator.noEmailInCert.summary = Das Unterzeichner Zertifikat kann nicht für Email Signaturen verwendet werden: Es enthält keine Email Addresse. SignedMailValidator.noEmailInCert.details = Das Unterzeichner Zertifikat kann nicht für Email Signaturen verwendet werden: Es enthält keine Email Addresse. # certificate email address does not match from email address # {0} from email addresses in the message # {1} email addresses in the certificate SignedMailValidator.emailFromCertMismatch.title = Email Addressen stimmen nicht überein SignedMailValidator.emailFromCertMismatch.text = Die Email Addresse im Unterzeichner Zertifikat stimmt nicht mit der Sender Addresse überein. Unterzeichner: {1}. Sender: {0}. SignedMailValidator.emailFromCertMismatch.summary = Die Email Addresse im Unterzeichner Zertifikat stimmt nicht mit der Sender Addresse überein. Unterzeichner: {1}. Sender: {0}. SignedMailValidator.emailFromCertMismatch.details = Die Email Addresse im Unterzeichner Zertifikat stimmt nicht mit der Sender Addresse überein. Unterzeichner: {1}. Sender: {0}. # exception extracting email addresses from certificate # {0} message of the underlying exception # {1} the underlying exception # {2} the name of the exception SignedMailValidator.certGetEmailError.title = Fehler bei extrahieren der Email Addresse vom Zertifikat SignedMailValidator.certGetEmailError.text = Es gab eine {2} beim Extrahieren der Email Addresse vom Zertifikat. Grund: {0}. SignedMailValidator.certGetEmailError.summary = Es gab eine {2} beim Extrahieren der Email Addresse vom Zertifikat. SignedMailValidator.certGetEmailError.details = Es gab eine {2} beim Extrahieren der Email Addresse vom Zertifikat. Grund: {0}. # no signing time found SignedMailValidator.noSigningTime.title = Keine Signierzeit SignedMailValidator.noSigningTime.text = Die Signatur enthält keine Signier Zeit. Benutze die aktuelle Zeit zur Zertifikationpfad Validierung. SignedMailValidator.noSigningTime.summary = Die Signatur enthält keine Signier Zeit. SignedMailValidator.noSigningTime.details = Die Signatur enthält keine Signier Zeit. Benutze die aktuelle Zeit zur Zertifikationpfad Validierung. # expired at signing time # {0} signing time # {1} not after date SignedMailValidator.certExpired.title = Zertifikat zur Signierzeit abgelaufen SignedMailValidator.certExpired.text = Die Nachricht wurde am {0,date} {0,time,full} signiert. Aber das Zertifikat ist am {1,date} {1,time,full} abgelaufen. SignedMailValidator.certExpired.summary = Die Nachricht wurde am {0,date} {0,time,full} signiert. Aber das Zertifikat ist am {1,date} {1,time,full} abgelaufen. SignedMailValidator.certExpired.details = Die Nachricht wurde am {0,date} {0,time,full} signiert. Aber das Zertifikat ist am {1,date} {1,time,full} abgelaufen. # not yet valid at signing time # {0} signing time # {1} notBefore date SignedMailValidator.certNotYetValid.title = Zertifikat noch nicht gültig zur Signierzeit SignedMailValidator.certNotYetValid.text = Die Nachricht wurde am {0,date} {0,time,full} signiert. Aber das Zertifikat ist erst gültig ab {1,date} {1,time,full}. SignedMailValidator.certNotYetValid.summary = Die Nachricht wurde am {0,date} {0,time,full} signiert. Aber das Zertifikat ist erst gültig ab {1,date} {1,time,full}. SignedMailValidator.certNotYetValid.details = Die Nachricht wurde am {0,date} {0,time,full} signiert. Aber das Zertifikat ist erst gültig ab {1,date} {1,time,full}. # exception retrieving the signer certificate # {0} message of the underlying exception # {1} the underlying exception # {2} the name of the exception SignedMailValidator.exceptionRetrievingSignerCert.title = Fehler beim Lesen des Signaturzertifikats SignedMailValidator.exceptionRetrievingSignerCert.text = Signatur Validierung fehlgeschlagen. Es gab eine {2} beim Lesen des Signaturzertifikats: {0}. SignedMailValidator.exceptionRetrievingSignerCert.summary = Signatur Validierung fehlgeschlagen. Es gab eine {2} beim Lesen des Signaturzertifikats. SignedMailValidator.exceptionRetrievingSignerCert.details = Signatur Validierung fehlgeschlagen. Es gab eine {2} beim Lesen des Signaturzertifikats: {0}. # exception verifying the signature # {0} message of the underlying exception # {1} the underlying exception # {2} the name of the exception SignedMailValidator.exceptionVerifyingSignature.title = Signatur nicht verifiziert SignedMailValidator.exceptionVerifyingSignature.text = Signatur nicht verifiziert. Es gab eine {2}. Grund: {0}. SignedMailValidator.exceptionVerifyingSignature.summary = Signatur nicht verifiziert. Es gab eine {2}. SignedMailValidator.exceptionVerifyingSignature.details = Signatur nicht verifiziert. Es gab eine {2}. Grund: {0}. # signature not verified SignedMailValidator.signatureNotVerified.title = Signatur nicht verifiziert SignedMailValidator.signatureNotVerified.text = Signatur nicht verifiziert. Der öffentliche Schlüssel des Unterzeichners passt nicht zur Signatur. SignedMailValidator.signatureNotVerified.summary = Signatur nicht verifiziert. Der öffentliche Schlüssel des Unterzeichners passt nicht zur Signatur. SignedMailValidator.signatureNotVerified.details = Signatur nicht verifiziert. Der öffentliche Schlüssel des Unterzeichners passt nicht zur Signatur. # certificate key usage does not permit digitalSignature or nonRepudiation SignedMailValidator.signingNotPermitted.title = Schlüssel nicht verwendbar für Email Signaturen SignedMailValidator.signingNotPermitted.text = Der Schlüssel des Unterzeichners darf nicht für Email Signaturen verwendet werden. SignedMailValidator.signingNotPermitted.summary = Der Schlüssel des Unterzeichners darf nicht für Email Signaturen verwendet werden. SignedMailValidator.signingNotPermitted.details = Die Schlüsselverwendung des Unterzeichner Zertifikats erlaubt keine Verwendung für Email Signaturen. # certificate extended key usage does not permit emailProtection or anyExtendedKeyUsage SignedMailValidator.extKeyUsageNotPermitted.title = Schlüssel nicht verwendbar für Email Signaturen SignedMailValidator.extKeyUsageNotPermitted.text = Der Schlüssel des Unterzeichners darf nicht für Email Signaturen verwendet werden. SignedMailValidator.extKeyUsageNotPermitted.summary = Der Schlüssel des Unterzeichners darf nicht für Email Signaturen verwendet werden. SignedMailValidator.extKeyUsageNotPermitted.details = Die erweiterte Schlüsselverwendung des Unterzeichner Zertifikats erlaubt keine Verwendung für Email Signaturen. # exception processing the extended key usage extension # {0} message of the underlying exception # {1} the underlying exception # {2} the name of the exception SignedMailValidator.extKeyUsageError.title = Fehler bei der Verarbeitung der Extended key usage Erweiterung SignedMailValidator.extKeyUsageError.text = Es gab eine {2} bei der Verarbeitung der Extended key usage Erweiterung. Grund: {0}. SignedMailValidator.extKeyUsageError.summary = Es gab eine {2} bei der Verarbeitung der Extended key usage Erweiterung. SignedMailValidator.extKeyUsageError.details = Es gab eine {2} bei der Verarbeitung der Extended key usage Erweiterung. Grund: {0}. # cannot create certificate path (exception) # {0} message of the underlying exception # {1} the underlying exception # {2} the name of the exception SignedMailValidator.exceptionCreateCertPath.title = Zertifizierungspfad Validierung fehlgeschlagen SignedMailValidator.exceptionCreateCertPath.text = Die Zertifizierungspfad Validierung ist fehlgeschlagen. Es gab eine {2} beim erstellen des Zertifizierungspfad: {0}. SignedMailValidator.exceptionCreateCertPath.summary = Die Zertifizierungspfad Validierung ist fehlgeschlagen. Es gab eine {2} beim erstellen des Zertifizierungspfad: {0}. SignedMailValidator.exceptionCreateCertPath.details = Die Zertifizierungspfad Validierung ist fehlgeschlagen. Es gab eine {2} beim erstellen des Zertifizierungspfad: {0}. # certificate path is invalid SignedMailValidator.certPathInvalid.title = Zertifikats-Pfad ungültig SignedMailValidator.certPathInvalid.text = Der Zertifikats-Pfad ist ungültig. SignedMailValidator.certPathInvalid.summary = Der Zertifikats-Pfad ist ungültig. SignedMailValidator.certPathInvalid.details = Der Zertifikats-Pfad ist ungültig. bouncycastle-1.49.orig/src/org/bouncycastle/mail/smime/util/0000755000175000017500000000000012152033551023510 5ustar ebourgebourgbouncycastle-1.49.orig/src/org/bouncycastle/mail/smime/util/CRLFOutputStream.java0000644000175000017500000000236010376017271027506 0ustar ebourgebourgpackage org.bouncycastle.mail.smime.util; import java.io.FilterOutputStream; import java.io.IOException; import java.io.OutputStream; public class CRLFOutputStream extends FilterOutputStream { protected int lastb; protected static byte newline[]; public CRLFOutputStream(OutputStream outputstream) { super(outputstream); lastb = -1; } public void write(int i) throws IOException { if (i == '\r') { out.write(newline); } else if (i == '\n') { if (lastb != '\r') { out.write(newline); } } else { out.write(i); } lastb = i; } public void write(byte[] buf) throws IOException { this.write(buf, 0, buf.length); } public void write(byte buf[], int off, int len) throws IOException { for (int i = off; i != off + len; i++) { this.write(buf[i]); } } public void writeln() throws IOException { super.out.write(newline); } static { newline = new byte[2]; newline[0] = '\r'; newline[1] = '\n'; } } bouncycastle-1.49.orig/src/org/bouncycastle/mail/smime/util/SharedFileInputStream.java0000644000175000017500000001213610555325117030567 0ustar ebourgebourgpackage org.bouncycastle.mail.smime.util; import javax.mail.internet.SharedInputStream; import java.io.BufferedInputStream; import java.io.File; import java.io.FileInputStream; import java.io.FilterInputStream; import java.io.IOException; import java.io.InputStream; import java.util.Iterator; import java.util.LinkedList; import java.util.List; public class SharedFileInputStream extends FilterInputStream implements SharedInputStream { private final SharedFileInputStream _parent; private final File _file; private final long _start; private final long _length; private long _position; private long _markedPosition; private List _subStreams = new LinkedList(); public SharedFileInputStream( String fileName) throws IOException { this(new File(fileName)); } public SharedFileInputStream( File file) throws IOException { this(file, 0, file.length()); } private SharedFileInputStream( File file, long start, long length) throws IOException { super(new BufferedInputStream(new FileInputStream(file))); _parent = null; _file = file; _start = start; _length = length; in.skip(start); } private SharedFileInputStream( SharedFileInputStream parent, long start, long length) throws IOException { super(new BufferedInputStream(new FileInputStream(parent._file))); _parent = parent; _file = parent._file; _start = start; _length = length; in.skip(start); } public long getPosition() { return _position; } public InputStream newStream(long start, long finish) { try { SharedFileInputStream stream; if (finish < 0) { if (_length > 0) { stream = new SharedFileInputStream(this, _start + start, _length - start); } else if (_length == 0) { stream = new SharedFileInputStream(this, _start + start, 0); } else { stream = new SharedFileInputStream(this, _start + start, -1); } } else { stream = new SharedFileInputStream(this, _start + start, finish - start); } _subStreams.add(stream); return stream; } catch (IOException e) { throw new IllegalStateException("unable to create shared stream: " + e); } } public int read( byte[] buf) throws IOException { return this.read(buf, 0, buf.length); } public int read( byte[] buf, int off, int len) throws IOException { int count = 0; if (len == 0) { return 0; } while (count < len) { int ch = this.read(); if (ch < 0) { break; } buf[off + count] = (byte)ch; count++; } if (count == 0) { return -1; // EOF } return count; } public int read() throws IOException { if (_position == _length) { return -1; } _position++; return in.read(); } public boolean markSupported() { return true; } public long skip(long n) throws IOException { long count; for (count = 0; count != n; count++) { if (this.read() < 0) { break; } } return count; } public void mark( int readLimit) { _markedPosition = _position; in.mark(readLimit); } public void reset() throws IOException { _position = _markedPosition; in.reset(); } /** * Return the shared stream that represents the top most stream that * this stream inherits from. * @return the base of the shared stream tree. */ public SharedFileInputStream getRoot() { if (_parent != null) { return _parent.getRoot(); } return this; } /** * Close of this stream and any substreams that have been created from it. * @throws IOException on problem closing the main stream. */ public void dispose() throws IOException { Iterator it = _subStreams.iterator(); while (it.hasNext()) { try { ((SharedFileInputStream)it.next()).dispose(); } catch (IOException e) { // ignore } } in.close(); } } bouncycastle-1.49.orig/src/org/bouncycastle/mail/smime/util/FileBackedMimeBodyPart.java0000644000175000017500000001056310675164115030617 0ustar ebourgebourgpackage org.bouncycastle.mail.smime.util; import javax.mail.MessagingException; import javax.mail.internet.InternetHeaders; import javax.mail.internet.MimeBodyPart; import java.io.File; import java.io.FileOutputStream; import java.io.IOException; import java.io.InputStream; import java.io.OutputStream; import java.util.Enumeration; public class FileBackedMimeBodyPart extends MimeBodyPart { private static final int BUF_SIZE = 32760; private final File _file; /** * Create a MimeBodyPart backed by the data in file. * * @param file file containing the body part. * @throws MessagingException an exception occurs parsing file. * @throws IOException an exception occurs accessing file. */ public FileBackedMimeBodyPart( File file) throws MessagingException, IOException { super(new SharedFileInputStream(file)); _file = file; } /** * Create a MimeBodyPart backed by file based on the headers and * content data in content. * * @param content an inputstream containing the body part. * @param file a handle to the backing file to use for storage. * @throws MessagingException an exception occurs parsing the resulting body part in file. * @throws IOException an exception occurs accessing file or content. */ public FileBackedMimeBodyPart( InputStream content, File file) throws MessagingException, IOException { this(saveStreamToFile(content, file)); } /** * Create a MimeBodyPart backed by file, with the headers * given in headers and body content taken from the stream body. * * @param headers headers for the body part. * @param body internal content for the body part. * @param file backing file to use. * * @throws MessagingException if the body part can't be produced. * @throws IOException if there is an issue reading stream or writing to file. */ public FileBackedMimeBodyPart( InternetHeaders headers, InputStream body, File file) throws MessagingException, IOException { this(saveStreamToFile(headers, body, file)); } public void writeTo( OutputStream out) throws IOException, MessagingException { if (!_file.exists()) { throw new IOException("file " + _file.getCanonicalPath() + " no longer exists."); } super.writeTo(out); } /** * Close off the underlying shared streams and remove the backing file. * * @throws IOException if streams cannot be closed or the file cannot be deleted. */ public void dispose() throws IOException { ((SharedFileInputStream)contentStream).getRoot().dispose(); if (_file.exists() && !_file.delete()) { throw new IOException("deletion of underlying file <" + _file.getCanonicalPath() + "> failed."); } } private static File saveStreamToFile(InputStream content, File tempFile) throws IOException { saveContentToStream(new FileOutputStream(tempFile), content); return tempFile; } private static File saveStreamToFile(InternetHeaders headers, InputStream content, File tempFile) throws IOException { OutputStream out = new FileOutputStream(tempFile); Enumeration en = headers.getAllHeaderLines(); while (en.hasMoreElements()) { writeHeader(out, (String)en.nextElement()); } writeSeperator(out); saveContentToStream(out, content); return tempFile; } private static void writeHeader(OutputStream out, String header) throws IOException { for (int i = 0; i != header.length(); i++) { out.write(header.charAt(i)); } writeSeperator(out); } private static void writeSeperator(OutputStream out) throws IOException { out.write('\r'); out.write('\n'); } private static void saveContentToStream( OutputStream out, InputStream content) throws IOException { byte[] buf = new byte[BUF_SIZE]; int len; while ((len = content.read(buf, 0, buf.length)) > 0) { out.write(buf, 0, len); } out.close(); content.close(); } } bouncycastle-1.49.orig/src/org/bouncycastle/mail/smime/SMIMECompressedParser.java0000644000175000017500000000473510402140002027445 0ustar ebourgebourgpackage org.bouncycastle.mail.smime; import java.io.BufferedInputStream; import java.io.IOException; import java.io.InputStream; import javax.mail.MessagingException; import javax.mail.Part; import javax.mail.internet.MimeBodyPart; import javax.mail.internet.MimeMessage; import javax.mail.internet.MimePart; import org.bouncycastle.cms.CMSCompressedDataParser; import org.bouncycastle.cms.CMSException; /** * Stream based containing class for an S/MIME pkcs7-mime compressed MimePart. */ public class SMIMECompressedParser extends CMSCompressedDataParser { private final MimePart message; private static InputStream getInputStream( Part bodyPart, int bufferSize) throws MessagingException { try { InputStream in = bodyPart.getInputStream(); if (bufferSize == 0) { return new BufferedInputStream(in); } else { return new BufferedInputStream(in, bufferSize); } } catch (IOException e) { throw new MessagingException("can't extract input stream: " + e); } } public SMIMECompressedParser( MimeBodyPart message) throws MessagingException, CMSException { this(message, 0); } public SMIMECompressedParser( MimeMessage message) throws MessagingException, CMSException { this(message, 0); } /** * Create a parser from a MimeBodyPart using the passed in buffer size * for reading it. * * @param message body part to be parsed. * @param bufferSize bufferSoze to be used. */ public SMIMECompressedParser( MimeBodyPart message, int bufferSize) throws MessagingException, CMSException { super(getInputStream(message, bufferSize)); this.message = message; } /** * Create a parser from a MimeMessage using the passed in buffer size * for reading it. * * @param message message to be parsed. * @param bufferSize bufferSoze to be used. */ public SMIMECompressedParser( MimeMessage message, int bufferSize) throws MessagingException, CMSException { super(getInputStream(message, bufferSize)); this.message = message; } public MimePart getCompressedContent() { return message; } } bouncycastle-1.49.orig/src/org/bouncycastle/mail/smime/handlers/0000755000175000017500000000000012152033551024333 5ustar ebourgebourgbouncycastle-1.49.orig/src/org/bouncycastle/mail/smime/handlers/pkcs7_signature.java0000644000175000017500000000102510321675356030317 0ustar ebourgebourgpackage org.bouncycastle.mail.smime.handlers; import java.awt.datatransfer.DataFlavor; import javax.activation.ActivationDataFlavor; import javax.mail.internet.MimeBodyPart; public class pkcs7_signature extends PKCS7ContentHandler { private static final ActivationDataFlavor ADF = new ActivationDataFlavor(MimeBodyPart.class, "application/pkcs7-signature", "Signature"); private static final DataFlavor[] DFS = new DataFlavor[] { ADF }; public pkcs7_signature() { super(ADF, DFS); } } bouncycastle-1.49.orig/src/org/bouncycastle/mail/smime/handlers/pkcs7_mime.java0000644000175000017500000000101410321675356027243 0ustar ebourgebourgpackage org.bouncycastle.mail.smime.handlers; import java.awt.datatransfer.DataFlavor; import javax.activation.ActivationDataFlavor; import javax.mail.internet.MimeBodyPart; public class pkcs7_mime extends PKCS7ContentHandler { private static final ActivationDataFlavor ADF = new ActivationDataFlavor(MimeBodyPart.class, "application/pkcs7-mime", "Encrypted Data"); private static final DataFlavor[] DFS = new DataFlavor[] { ADF }; public pkcs7_mime() { super(ADF, DFS); } } bouncycastle-1.49.orig/src/org/bouncycastle/mail/smime/handlers/x_pkcs7_mime.java0000644000175000017500000000102211222021270027546 0ustar ebourgebourgpackage org.bouncycastle.mail.smime.handlers; import java.awt.datatransfer.DataFlavor; import javax.activation.ActivationDataFlavor; import javax.mail.internet.MimeBodyPart; public class x_pkcs7_mime extends PKCS7ContentHandler { private static final ActivationDataFlavor ADF = new ActivationDataFlavor(MimeBodyPart.class, "application/x-pkcs7-mime", "Encrypted Data"); private static final DataFlavor[] DFS = new DataFlavor[] { ADF }; public x_pkcs7_mime() { super(ADF, DFS); } } bouncycastle-1.49.orig/src/org/bouncycastle/mail/smime/handlers/x_pkcs7_signature.java0000644000175000017500000000412110324400070030624 0ustar ebourgebourgpackage org.bouncycastle.mail.smime.handlers; import java.awt.datatransfer.DataFlavor; import java.io.IOException; import java.io.InputStream; import java.io.OutputStream; import javax.activation.ActivationDataFlavor; import javax.activation.DataContentHandler; import javax.activation.DataSource; import javax.mail.MessagingException; import javax.mail.internet.MimeBodyPart; public class x_pkcs7_signature implements DataContentHandler { /* * * VARIABLES * */ private static final ActivationDataFlavor ADF; private static final DataFlavor[] ADFs; static { ADF = new ActivationDataFlavor(MimeBodyPart.class, "application/x-pkcs7-signature", "Signature"); ADFs = new DataFlavor[] { ADF }; } public Object getContent(DataSource _ds) throws IOException { return _ds.getInputStream(); } public Object getTransferData(DataFlavor _df, DataSource _ds) throws IOException { if (ADF.equals(_df)) { return getContent(_ds); } else { return null; } } public DataFlavor[] getTransferDataFlavors() { return ADFs; } public void writeTo(Object _obj, String _mimeType, OutputStream _os) throws IOException { if (_obj instanceof MimeBodyPart) { try { ((MimeBodyPart)_obj).writeTo(_os); } catch (MessagingException ex) { throw new IOException(ex.getMessage()); } } else if (_obj instanceof byte[]) { _os.write((byte[])_obj); } else if (_obj instanceof InputStream) { int b; InputStream in = (InputStream)_obj; while ((b = in.read()) >= 0) { _os.write(b); } } else { throw new IOException("unknown object in writeTo " + _obj); } } } bouncycastle-1.49.orig/src/org/bouncycastle/mail/smime/handlers/multipart_signed.java0000644000175000017500000001603510554373304030564 0ustar ebourgebourgpackage org.bouncycastle.mail.smime.handlers; import org.bouncycastle.mail.smime.SMIMEStreamingProcessor; import javax.activation.ActivationDataFlavor; import javax.activation.DataContentHandler; import javax.activation.DataSource; import javax.mail.MessagingException; import javax.mail.Multipart; import javax.mail.internet.ContentType; import javax.mail.internet.MimeBodyPart; import javax.mail.internet.MimeMultipart; import java.awt.datatransfer.DataFlavor; import java.io.BufferedInputStream; import java.io.FilterOutputStream; import java.io.IOException; import java.io.InputStream; import java.io.OutputStream; import java.util.Enumeration; public class multipart_signed implements DataContentHandler { private static final ActivationDataFlavor ADF = new ActivationDataFlavor(MimeMultipart.class, "multipart/signed", "Multipart Signed"); private static final DataFlavor[] DFS = new DataFlavor[] { ADF }; public Object getContent(DataSource ds) throws IOException { try { return new MimeMultipart(ds); } catch (MessagingException ex) { return null; } } public Object getTransferData(DataFlavor df, DataSource ds) throws IOException { if (ADF.equals(df)) { return getContent(ds); } else { return null; } } public DataFlavor[] getTransferDataFlavors() { return DFS; } public void writeTo(Object obj, String _mimeType, OutputStream os) throws IOException { if (obj instanceof MimeMultipart) { try { outputBodyPart(os, obj); } catch (MessagingException ex) { throw new IOException(ex.getMessage()); } } else if(obj instanceof byte[]) { os.write((byte[])obj); } else if (obj instanceof InputStream) { int b; InputStream in = (InputStream)obj; if (!(in instanceof BufferedInputStream)) { in = new BufferedInputStream(in); } while ((b = in.read()) >= 0) { os.write(b); } } else if (obj instanceof SMIMEStreamingProcessor) { SMIMEStreamingProcessor processor = (SMIMEStreamingProcessor)obj; processor.write(os); } else { throw new IOException("unknown object in writeTo " + obj); } } /* * Output the mulitpart as a collection of leaves to make sure preamble text is not included. */ private void outputBodyPart( OutputStream out, Object bodyPart) throws MessagingException, IOException { if (bodyPart instanceof Multipart) { Multipart mp = (Multipart)bodyPart; ContentType contentType = new ContentType(mp.getContentType()); String boundary = "--" + contentType.getParameter("boundary"); LineOutputStream lOut = new LineOutputStream(out); for (int i = 0; i < mp.getCount(); i++) { lOut.writeln(boundary); outputBodyPart(out, mp.getBodyPart(i)); lOut.writeln(); // CRLF terminator } lOut.writeln(boundary + "--"); return; } MimeBodyPart mimePart = (MimeBodyPart)bodyPart; if (mimePart.getContent() instanceof Multipart) { Multipart mp = (Multipart)mimePart.getContent(); ContentType contentType = new ContentType(mp.getContentType()); String boundary = "--" + contentType.getParameter("boundary"); LineOutputStream lOut = new LineOutputStream(out); Enumeration headers = mimePart.getAllHeaderLines(); while (headers.hasMoreElements()) { lOut.writeln((String)headers.nextElement()); } lOut.writeln(); // CRLF separator outputPreamble(lOut, mimePart, boundary); outputBodyPart(out, mp); return; } mimePart.writeTo(out); } /** * internal preamble is generally included in signatures, while this is technically wrong, * if we find internal preamble we include it by default. */ static void outputPreamble(LineOutputStream lOut, MimeBodyPart part, String boundary) throws MessagingException, IOException { InputStream in; try { in = part.getRawInputStream(); } catch (MessagingException e) { return; // no underlying content, rely on default generation } String line; while ((line = readLine(in)) != null) { if (line.equals(boundary)) { break; } lOut.writeln(line); } in.close(); if (line == null) { throw new MessagingException("no boundary found"); } } /* * read a line of input stripping of the tailing \r\n */ private static String readLine(InputStream in) throws IOException { StringBuffer b = new StringBuffer(); int ch; while ((ch = in.read()) >= 0 && ch != '\n') { if (ch != '\r') { b.append((char)ch); } } if (ch < 0) { return null; } return b.toString(); } private static class LineOutputStream extends FilterOutputStream { private static byte newline[]; public LineOutputStream(OutputStream outputstream) { super(outputstream); } public void writeln(String s) throws MessagingException { try { byte abyte0[] = getBytes(s); super.out.write(abyte0); super.out.write(newline); } catch(Exception exception) { throw new MessagingException("IOException", exception); } } public void writeln() throws MessagingException { try { super.out.write(newline); } catch(Exception exception) { throw new MessagingException("IOException", exception); } } static { newline = new byte[2]; newline[0] = 13; newline[1] = 10; } private static byte[] getBytes(String s) { char ac[] = s.toCharArray(); int i = ac.length; byte abyte0[] = new byte[i]; int j = 0; while (j < i) { abyte0[j] = (byte)ac[j++]; } return abyte0; } } } bouncycastle-1.49.orig/src/org/bouncycastle/mail/smime/handlers/PKCS7ContentHandler.java0000644000175000017500000000532510503210651030657 0ustar ebourgebourgpackage org.bouncycastle.mail.smime.handlers; import java.awt.datatransfer.DataFlavor; import java.io.BufferedInputStream; import java.io.IOException; import java.io.InputStream; import java.io.OutputStream; import javax.activation.ActivationDataFlavor; import javax.activation.DataContentHandler; import javax.activation.DataSource; import javax.mail.MessagingException; import javax.mail.internet.MimeBodyPart; import org.bouncycastle.mail.smime.SMIMEStreamingProcessor; public class PKCS7ContentHandler implements DataContentHandler { private final ActivationDataFlavor _adf; private final DataFlavor[] _dfs; PKCS7ContentHandler( ActivationDataFlavor adf, DataFlavor[] dfs) { _adf = adf; _dfs = dfs; } public Object getContent( DataSource ds) throws IOException { return ds.getInputStream(); } public Object getTransferData( DataFlavor df, DataSource ds) throws IOException { if (_adf.equals(df)) { return getContent(ds); } else { return null; } } public DataFlavor[] getTransferDataFlavors() { return _dfs; } public void writeTo( Object obj, String mimeType, OutputStream os) throws IOException { if (obj instanceof MimeBodyPart) { try { ((MimeBodyPart)obj).writeTo(os); } catch (MessagingException ex) { throw new IOException(ex.getMessage()); } } else if (obj instanceof byte[]) { os.write((byte[])obj); } else if (obj instanceof InputStream) { int b; InputStream in = (InputStream)obj; if (!(in instanceof BufferedInputStream)) { in = new BufferedInputStream(in); } while ((b = in.read()) >= 0) { os.write(b); } } else if (obj instanceof SMIMEStreamingProcessor) { SMIMEStreamingProcessor processor = (SMIMEStreamingProcessor)obj; processor.write(os); } else { // TODO it would be even nicer if we could attach the object to the exception // as well since in deeply nested messages, it is not always clear which // part caused the problem. Thus I guess we would have to subclass the // IOException throw new IOException("unknown object in writeTo " + obj); } } } bouncycastle-1.49.orig/src/org/bouncycastle/mail/smime/handlers/package.html0000644000175000017500000000012610262753175026626 0ustar ebourgebourg S/MIME handlers for the JavaMail API. bouncycastle-1.49.orig/src/org/bouncycastle/mail/smime/SMIMEEnvelopedParser.java0000644000175000017500000000501010402140002027245 0ustar ebourgebourgpackage org.bouncycastle.mail.smime; import java.io.BufferedInputStream; import java.io.IOException; import java.io.InputStream; import javax.mail.MessagingException; import javax.mail.Part; import javax.mail.internet.MimeBodyPart; import javax.mail.internet.MimeMessage; import javax.mail.internet.MimePart; import org.bouncycastle.cms.CMSEnvelopedDataParser; import org.bouncycastle.cms.CMSException; /** * Stream based containing class for an S/MIME pkcs7-mime encrypted MimePart. */ public class SMIMEEnvelopedParser extends CMSEnvelopedDataParser { private final MimePart message; private static InputStream getInputStream( Part bodyPart, int bufferSize) throws MessagingException { try { InputStream in = bodyPart.getInputStream(); if (bufferSize == 0) { return new BufferedInputStream(in); } else { return new BufferedInputStream(in, bufferSize); } } catch (IOException e) { throw new MessagingException("can't extract input stream: " + e); } } public SMIMEEnvelopedParser( MimeBodyPart message) throws IOException, MessagingException, CMSException { this(message, 0); } public SMIMEEnvelopedParser( MimeMessage message) throws IOException, MessagingException, CMSException { this(message, 0); } /** * Create a parser from a MimeBodyPart using the passed in buffer size * for reading it. * * @param message body part to be parsed. * @param bufferSize bufferSoze to be used. */ public SMIMEEnvelopedParser( MimeBodyPart message, int bufferSize) throws IOException, MessagingException, CMSException { super(getInputStream(message, bufferSize)); this.message = message; } /** * Create a parser from a MimeMessage using the passed in buffer size * for reading it. * * @param message message to be parsed. * @param bufferSize bufferSoze to be used. */ public SMIMEEnvelopedParser( MimeMessage message, int bufferSize) throws IOException, MessagingException, CMSException { super(getInputStream(message, bufferSize)); this.message = message; } public MimePart getEncryptedContent() { return message; } } bouncycastle-1.49.orig/src/org/bouncycastle/mail/smime/SMIMESigned.java0000644000175000017500000001643610554373303025422 0ustar ebourgebourgpackage org.bouncycastle.mail.smime; import org.bouncycastle.cms.CMSException; import org.bouncycastle.cms.CMSProcessable; import org.bouncycastle.cms.CMSSignedData; import javax.activation.CommandMap; import javax.activation.MailcapCommandMap; import javax.mail.MessagingException; import javax.mail.Part; import javax.mail.Session; import javax.mail.internet.MimeBodyPart; import javax.mail.internet.MimeMessage; import javax.mail.internet.MimeMultipart; import javax.mail.internet.MimePart; import java.io.ByteArrayInputStream; import java.io.ByteArrayOutputStream; import java.io.IOException; import java.io.InputStream; /** * general class for handling a pkcs7-signature message. *

    * A simple example of usage - note, in the example below the validity of * the certificate isn't verified, just the fact that one of the certs * matches the given signer... *

    *

     *  CertStore               certs = s.getCertificates("Collection", "BC");
     *  SignerInformationStore  signers = s.getSignerInfos();
     *  Collection              c = signers.getSigners();
     *  Iterator                it = c.iterator();
     *  
     *  while (it.hasNext())
     *  {
     *      SignerInformation   signer = (SignerInformation)it.next();
     *      Collection          certCollection = certs.getCertificates(signer.getSID());
     *  
     *      Iterator        certIt = certCollection.iterator();
     *      X509Certificate cert = (X509Certificate)certIt.next();
     *  
     *      if (signer.verify(cert.getPublicKey()))
     *      {
     *          verified++;
     *      }   
     *  }
     * 
    *

    * Note: if you are using this class with AS2 or some other protocol * that does not use 7bit as the default content transfer encoding you * will need to use the constructor that allows you to specify the default * content transfer encoding, such as "binary". *

    */ public class SMIMESigned extends CMSSignedData { Object message; MimeBodyPart content; private static InputStream getInputStream( Part bodyPart) throws MessagingException { try { if (bodyPart.isMimeType("multipart/signed")) { throw new MessagingException("attempt to create signed data object from multipart content - use MimeMultipart constructor."); } return bodyPart.getInputStream(); } catch (IOException e) { throw new MessagingException("can't extract input stream: " + e); } } static { MailcapCommandMap mc = (MailcapCommandMap)CommandMap.getDefaultCommandMap(); mc.addMailcap("application/pkcs7-signature;; x-java-content-handler=org.bouncycastle.mail.smime.handlers.pkcs7_signature"); mc.addMailcap("application/pkcs7-mime;; x-java-content-handler=org.bouncycastle.mail.smime.handlers.pkcs7_mime"); mc.addMailcap("application/x-pkcs7-signature;; x-java-content-handler=org.bouncycastle.mail.smime.handlers.x_pkcs7_signature"); mc.addMailcap("application/x-pkcs7-mime;; x-java-content-handler=org.bouncycastle.mail.smime.handlers.x_pkcs7_mime"); mc.addMailcap("multipart/signed;; x-java-content-handler=org.bouncycastle.mail.smime.handlers.multipart_signed"); CommandMap.setDefaultCommandMap(mc); } /** * base constructor using a defaultContentTransferEncoding of 7bit * * @exception MessagingException on an error extracting the signature or * otherwise processing the message. * @exception CMSException if some other problem occurs. */ public SMIMESigned( MimeMultipart message) throws MessagingException, CMSException { super(new CMSProcessableBodyPartInbound(message.getBodyPart(0)), getInputStream(message.getBodyPart(1))); this.message = message; this.content = (MimeBodyPart)message.getBodyPart(0); } /** * base constructor with settable contentTransferEncoding * * @param message the signed message * @param defaultContentTransferEncoding new default to use * @exception MessagingException on an error extracting the signature or * otherwise processing the message. * @exception CMSException if some other problem occurs. */ public SMIMESigned( MimeMultipart message, String defaultContentTransferEncoding) throws MessagingException, CMSException { super(new CMSProcessableBodyPartInbound(message.getBodyPart(0), defaultContentTransferEncoding), getInputStream(message.getBodyPart(1))); this.message = message; this.content = (MimeBodyPart)message.getBodyPart(0); } /** * base constructor for a signed message with encapsulated content. * * @exception MessagingException on an error extracting the signature or * otherwise processing the message. * @exception SMIMEException if the body part encapsulated in the message cannot be extracted. * @exception CMSException if some other problem occurs. */ public SMIMESigned( Part message) throws MessagingException, CMSException, SMIMEException { super(getInputStream(message)); this.message = message; CMSProcessable cont = this.getSignedContent(); if (cont != null) { byte[] contBytes = (byte[])cont.getContent(); this.content = SMIMEUtil.toMimeBodyPart(contBytes); } } /** * return the content that was signed. */ public MimeBodyPart getContent() { return content; } /** * Return the content that was signed as a mime message. * * @param session * @return a MimeMessage holding the content. * @throws MessagingException */ public MimeMessage getContentAsMimeMessage(Session session) throws MessagingException, IOException { Object content = getSignedContent().getContent(); byte[] contentBytes = null; if (content instanceof byte[]) { contentBytes = (byte[])content; } else if (content instanceof MimePart) { MimePart part = (MimePart)content; ByteArrayOutputStream out; if (part.getSize() > 0) { out = new ByteArrayOutputStream(part.getSize()); } else { out = new ByteArrayOutputStream(); } part.writeTo(out); contentBytes = out.toByteArray(); } else { String type = ""; if (content != null) { type = content.getClass().getName(); } throw new MessagingException( "Could not transfrom content of type " + type + " into MimeMessage."); } if (contentBytes != null) { ByteArrayInputStream in = new ByteArrayInputStream(contentBytes); return new MimeMessage(session, in); } return null; } /** * return the content that was signed - depending on whether this was * unencapsulated or not it will return a MimeMultipart or a MimeBodyPart */ public Object getContentWithSignature() { return message; } } bouncycastle-1.49.orig/src/org/bouncycastle/mail/smime/SMIMECompressedGenerator.java0000644000175000017500000001047310321675335030161 0ustar ebourgebourgpackage org.bouncycastle.mail.smime; import java.io.IOException; import java.io.OutputStream; import javax.activation.CommandMap; import javax.activation.MailcapCommandMap; import javax.mail.MessagingException; import javax.mail.internet.MimeBodyPart; import javax.mail.internet.MimeMessage; import org.bouncycastle.cms.CMSCompressedDataGenerator; import org.bouncycastle.cms.CMSCompressedDataStreamGenerator; /** * General class for generating a pkcs7-mime compressed message. * * A simple example of usage. * *
     *      SMIMECompressedGenerator  fact = new SMIMECompressedGenerator();
     *
     *      MimeBodyPart           smime = fact.generate(content, algorithm);
     * 
    * * Note: Most clients expect the MimeBodyPart to be in a MimeMultipart * when it's sent. */ public class SMIMECompressedGenerator extends SMIMEGenerator { public static final String ZLIB = CMSCompressedDataGenerator.ZLIB; private static final String COMPRESSED_CONTENT_TYPE = "application/pkcs7-mime; name=\"smime.p7z\"; smime-type=compressed-data"; static { MailcapCommandMap mc = (MailcapCommandMap)CommandMap.getDefaultCommandMap(); mc.addMailcap("application/pkcs7-mime;; x-java-content-handler=org.bouncycastle.mail.smime.handlers.pkcs7_mime"); mc.addMailcap("application/x-pkcs7-mime;; x-java-content-handler=org.bouncycastle.mail.smime.handlers.x_pkcs7_mime"); CommandMap.setDefaultCommandMap(mc); } /** * generate an compressed object that contains an SMIME Compressed * object using the given compression algorithm. */ private MimeBodyPart make( MimeBodyPart content, String compressionOID) throws SMIMEException { try { MimeBodyPart data = new MimeBodyPart(); data.setContent(new ContentCompressor(content, compressionOID), COMPRESSED_CONTENT_TYPE); data.addHeader("Content-Type", COMPRESSED_CONTENT_TYPE); data.addHeader("Content-Disposition", "attachment; filename=\"smime.p7z\""); data.addHeader("Content-Description", "S/MIME Compressed Message"); data.addHeader("Content-Transfer-Encoding", encoding); return data; } catch (MessagingException e) { throw new SMIMEException("exception putting multi-part together.", e); } } /** * generate an compressed object that contains an SMIME Compressed * object using the given provider from the contents of the passed in * message */ public MimeBodyPart generate( MimeBodyPart content, String compressionOID) throws SMIMEException { return make(makeContentBodyPart(content), compressionOID); } /** * generate an compressed object that contains an SMIME Compressed * object using the given provider from the contents of the passed in * message */ public MimeBodyPart generate( MimeMessage message, String compressionOID) throws SMIMEException { try { message.saveChanges(); // make sure we're up to date. } catch (MessagingException e) { throw new SMIMEException("unable to save message", e); } return make(makeContentBodyPart(message), compressionOID); } private class ContentCompressor implements SMIMEStreamingProcessor { private final MimeBodyPart _content; private final String _compressionOid; ContentCompressor( MimeBodyPart content, String compressionOid) { _content = content; _compressionOid = compressionOid; } public void write(OutputStream out) throws IOException { CMSCompressedDataStreamGenerator cGen = new CMSCompressedDataStreamGenerator(); OutputStream compressed = cGen.open(out, _compressionOid); try { _content.writeTo(compressed); compressed.close(); } catch (MessagingException e) { throw new IOException(e.toString()); } } } } bouncycastle-1.49.orig/src/org/bouncycastle/mail/smime/SMIMEGenerator.java0000644000175000017500000001434312014551331026122 0ustar ebourgebourgpackage org.bouncycastle.mail.smime; import java.io.IOException; import java.security.NoSuchAlgorithmException; import java.security.Provider; import java.util.Enumeration; import java.util.HashMap; import java.util.Map; import javax.crypto.KeyGenerator; import javax.mail.Header; import javax.mail.MessagingException; import javax.mail.Multipart; import javax.mail.Session; import javax.mail.internet.MimeBodyPart; import javax.mail.internet.MimeMessage; import org.bouncycastle.cms.CMSEnvelopedGenerator; import org.bouncycastle.util.Strings; /** * super class of the various generators. */ public class SMIMEGenerator { private static Map BASE_CIPHER_NAMES = new HashMap(); static { BASE_CIPHER_NAMES.put(CMSEnvelopedGenerator.DES_EDE3_CBC, "DESEDE"); BASE_CIPHER_NAMES.put(CMSEnvelopedGenerator.AES128_CBC, "AES"); BASE_CIPHER_NAMES.put(CMSEnvelopedGenerator.AES192_CBC, "AES"); BASE_CIPHER_NAMES.put(CMSEnvelopedGenerator.AES256_CBC, "AES"); } protected boolean useBase64 = true; protected String encoding = "base64"; // default sets base64 /** * base constructor */ protected SMIMEGenerator() { } /** * set the content-transfer-encoding for the CMS block (enveloped data, signature, etc...) in the message. * * @param encoding the encoding to use, default "base64", use "binary" for a binary encoding. */ public void setContentTransferEncoding( String encoding) { this.encoding = encoding; this.useBase64 = Strings.toLowerCase(encoding).equals("base64"); } /** * Make sure we have a valid content body part - setting the headers * with defaults if neccessary. */ protected MimeBodyPart makeContentBodyPart( MimeBodyPart content) throws SMIMEException { // // add the headers to the body part - if they are missing, in // the event they have already been set the content settings override // any defaults that might be set. // try { MimeMessage msg = new MimeMessage((Session)null); Enumeration e = content.getAllHeaders(); msg.setDataHandler(content.getDataHandler()); while (e.hasMoreElements()) { Header hdr =(Header)e.nextElement(); msg.setHeader(hdr.getName(), hdr.getValue()); } msg.saveChanges(); // // we do this to make sure at least the default headers are // set in the body part. // e = msg.getAllHeaders(); while (e.hasMoreElements()) { Header hdr =(Header)e.nextElement(); if (Strings.toLowerCase(hdr.getName()).startsWith("content-")) { content.setHeader(hdr.getName(), hdr.getValue()); } } } catch (MessagingException e) { throw new SMIMEException("exception saving message state.", e); } return content; } /** * extract an appropriate body part from the passed in MimeMessage */ protected MimeBodyPart makeContentBodyPart( MimeMessage message) throws SMIMEException { MimeBodyPart content = new MimeBodyPart(); // // add the headers to the body part. // try { message.removeHeader("Message-Id"); message.removeHeader("Mime-Version"); // JavaMail has a habit of reparsing some content types, if the bodypart is // a multipart it might be signed, we rebuild the body part using the raw input stream for the message. try { if (message.getContent() instanceof Multipart) { content.setContent(message.getRawInputStream(), message.getContentType()); extractHeaders(content, message); return content; } } catch (MessagingException e) { // fall back to usual method below } content.setContent(message.getContent(), message.getContentType()); content.setDataHandler(message.getDataHandler()); extractHeaders(content, message); } catch (MessagingException e) { throw new SMIMEException("exception saving message state.", e); } catch (IOException e) { throw new SMIMEException("exception getting message content.", e); } return content; } private void extractHeaders(MimeBodyPart content, MimeMessage message) throws MessagingException { Enumeration e = message.getAllHeaders(); while (e.hasMoreElements()) { Header hdr =(Header)e.nextElement(); content.addHeader(hdr.getName(), hdr.getValue()); } } protected KeyGenerator createSymmetricKeyGenerator( String encryptionOID, Provider provider) throws NoSuchAlgorithmException { try { return createKeyGenerator(encryptionOID, provider); } catch (NoSuchAlgorithmException e) { try { String algName = (String)BASE_CIPHER_NAMES.get(encryptionOID); if (algName != null) { return createKeyGenerator(algName, provider); } } catch (NoSuchAlgorithmException ex) { // ignore } if (provider != null) { return createSymmetricKeyGenerator(encryptionOID, null); } throw e; } } private KeyGenerator createKeyGenerator( String algName, Provider provider) throws NoSuchAlgorithmException { if (provider != null) { return KeyGenerator.getInstance(algName, provider); } else { return KeyGenerator.getInstance(algName); } } } bouncycastle-1.49.orig/src/org/bouncycastle/mail/smime/SMIMESignedGenerator.java0000644000175000017500000011332111726022776027267 0ustar ebourgebourgpackage org.bouncycastle.mail.smime; import java.io.IOException; import java.io.OutputStream; import java.security.InvalidKeyException; import java.security.NoSuchAlgorithmException; import java.security.NoSuchProviderException; import java.security.PrivateKey; import java.security.Provider; import java.security.cert.CertStore; import java.security.cert.CertStoreException; import java.security.cert.X509Certificate; import java.util.ArrayList; import java.util.Collections; import java.util.Enumeration; import java.util.HashMap; import java.util.Iterator; import java.util.List; import java.util.Map; import java.util.Set; import java.util.TreeSet; import javax.activation.CommandMap; import javax.activation.MailcapCommandMap; import javax.mail.MessagingException; import javax.mail.Multipart; import javax.mail.internet.ContentType; import javax.mail.internet.MimeBodyPart; import javax.mail.internet.MimeMessage; import javax.mail.internet.MimeMultipart; import org.bouncycastle.asn1.ASN1ObjectIdentifier; import org.bouncycastle.asn1.cms.AttributeTable; import org.bouncycastle.asn1.cryptopro.CryptoProObjectIdentifiers; import org.bouncycastle.asn1.nist.NISTObjectIdentifiers; import org.bouncycastle.asn1.oiw.OIWObjectIdentifiers; import org.bouncycastle.asn1.pkcs.PKCSObjectIdentifiers; import org.bouncycastle.asn1.teletrust.TeleTrusTObjectIdentifiers; import org.bouncycastle.asn1.x9.X9ObjectIdentifiers; import org.bouncycastle.cms.CMSAlgorithm; import org.bouncycastle.cms.CMSException; import org.bouncycastle.cms.CMSSignedDataStreamGenerator; import org.bouncycastle.cms.SignerInfoGenerator; import org.bouncycastle.cms.SignerInformation; import org.bouncycastle.cms.SignerInformationStore; import org.bouncycastle.mail.smime.util.CRLFOutputStream; import org.bouncycastle.util.Store; import org.bouncycastle.x509.X509Store; /** * general class for generating a pkcs7-signature message. *

    * A simple example of usage. * *

     *      X509Certificate signCert = ...
     *      KeyPair         signKP = ...
     *
     *      List certList = new ArrayList();
     *
     *      certList.add(signCert);
     *
     *      Store certs = new JcaCertStore(certList);
     *
     *      SMIMESignedGenerator gen = new SMIMESignedGenerator();
     *
     *      gen.addSignerInfoGenerator(new JcaSimpleSignerInfoGeneratorBuilder().setProvider("BC").build("SHA1withRSA", signKP.getPrivate(), signCert));
     *
     *      gen.addCertificates(certs);
     *
     *      MimeMultipart       smime = fact.generate(content);
     * 
    *

    * Note 1: if you are using this class with AS2 or some other protocol * that does not use "7bit" as the default content transfer encoding you * will need to use the constructor that allows you to specify the default * content transfer encoding, such as "binary". *

    *

    * Note 2: between RFC 3851 and RFC 5751 the values used in the micalg parameter * for signed messages changed. We will accept both, but the default is now to use * RFC 5751. In the event you are dealing with an older style system you will also need * to use a constructor that sets the micalgs table and call it with RFC3851_MICALGS. *

    */ public class SMIMESignedGenerator extends SMIMEGenerator { public static final String DIGEST_SHA1 = OIWObjectIdentifiers.idSHA1.getId(); public static final String DIGEST_MD5 = PKCSObjectIdentifiers.md5.getId(); public static final String DIGEST_SHA224 = NISTObjectIdentifiers.id_sha224.getId(); public static final String DIGEST_SHA256 = NISTObjectIdentifiers.id_sha256.getId(); public static final String DIGEST_SHA384 = NISTObjectIdentifiers.id_sha384.getId(); public static final String DIGEST_SHA512 = NISTObjectIdentifiers.id_sha512.getId(); public static final String DIGEST_GOST3411 = CryptoProObjectIdentifiers.gostR3411.getId(); public static final String DIGEST_RIPEMD128 = TeleTrusTObjectIdentifiers.ripemd128.getId(); public static final String DIGEST_RIPEMD160 = TeleTrusTObjectIdentifiers.ripemd160.getId(); public static final String DIGEST_RIPEMD256 = TeleTrusTObjectIdentifiers.ripemd256.getId(); public static final String ENCRYPTION_RSA = PKCSObjectIdentifiers.rsaEncryption.getId(); public static final String ENCRYPTION_DSA = X9ObjectIdentifiers.id_dsa_with_sha1.getId(); public static final String ENCRYPTION_ECDSA = X9ObjectIdentifiers.ecdsa_with_SHA1.getId(); public static final String ENCRYPTION_RSA_PSS = PKCSObjectIdentifiers.id_RSASSA_PSS.getId(); public static final String ENCRYPTION_GOST3410 = CryptoProObjectIdentifiers.gostR3410_94.getId(); public static final String ENCRYPTION_ECGOST3410 = CryptoProObjectIdentifiers.gostR3410_2001.getId(); private static final String CERTIFICATE_MANAGEMENT_CONTENT = "application/pkcs7-mime; name=smime.p7c; smime-type=certs-only"; private static final String DETACHED_SIGNATURE_TYPE = "application/pkcs7-signature; name=smime.p7s; smime-type=signed-data"; private static final String ENCAPSULATED_SIGNED_CONTENT_TYPE = "application/pkcs7-mime; name=smime.p7m; smime-type=signed-data"; public static final Map RFC3851_MICALGS; public static final Map RFC5751_MICALGS; public static final Map STANDARD_MICALGS; private static MailcapCommandMap addCommands(CommandMap cm) { MailcapCommandMap mc = (MailcapCommandMap)cm; mc.addMailcap("application/pkcs7-signature;; x-java-content-handler=org.bouncycastle.mail.smime.handlers.pkcs7_signature"); mc.addMailcap("application/pkcs7-mime;; x-java-content-handler=org.bouncycastle.mail.smime.handlers.pkcs7_mime"); mc.addMailcap("application/x-pkcs7-signature;; x-java-content-handler=org.bouncycastle.mail.smime.handlers.x_pkcs7_signature"); mc.addMailcap("application/x-pkcs7-mime;; x-java-content-handler=org.bouncycastle.mail.smime.handlers.x_pkcs7_mime"); mc.addMailcap("multipart/signed;; x-java-content-handler=org.bouncycastle.mail.smime.handlers.multipart_signed"); return mc; } static { CommandMap.setDefaultCommandMap(addCommands(CommandMap.getDefaultCommandMap())); Map stdMicAlgs = new HashMap(); stdMicAlgs.put(CMSAlgorithm.MD5, "md5"); stdMicAlgs.put(CMSAlgorithm.SHA1, "sha-1"); stdMicAlgs.put(CMSAlgorithm.SHA224, "sha-224"); stdMicAlgs.put(CMSAlgorithm.SHA256, "sha-256"); stdMicAlgs.put(CMSAlgorithm.SHA384, "sha-384"); stdMicAlgs.put(CMSAlgorithm.SHA512, "sha-512"); stdMicAlgs.put(CMSAlgorithm.GOST3411, "gostr3411-94"); RFC5751_MICALGS = Collections.unmodifiableMap(stdMicAlgs); Map oldMicAlgs = new HashMap(); oldMicAlgs.put(CMSAlgorithm.MD5, "md5"); oldMicAlgs.put(CMSAlgorithm.SHA1, "sha1"); oldMicAlgs.put(CMSAlgorithm.SHA224, "sha224"); oldMicAlgs.put(CMSAlgorithm.SHA256, "sha256"); oldMicAlgs.put(CMSAlgorithm.SHA384, "sha384"); oldMicAlgs.put(CMSAlgorithm.SHA512, "sha512"); oldMicAlgs.put(CMSAlgorithm.GOST3411, "gostr3411-94"); RFC3851_MICALGS = Collections.unmodifiableMap(oldMicAlgs); STANDARD_MICALGS = RFC5751_MICALGS; } private final String defaultContentTransferEncoding; private final Map micAlgs; private List _certStores = new ArrayList(); private List certStores = new ArrayList(); private List crlStores = new ArrayList(); private List attrCertStores = new ArrayList(); private List signerInfoGens = new ArrayList(); private List _signers = new ArrayList(); private List _oldSigners = new ArrayList(); private List _attributeCerts = new ArrayList(); private Map _digests = new HashMap(); /** * base constructor - default content transfer encoding 7bit */ public SMIMESignedGenerator() { this("7bit", STANDARD_MICALGS); } /** * base constructor - default content transfer encoding explicitly set * * @param defaultContentTransferEncoding new default to use. */ public SMIMESignedGenerator( String defaultContentTransferEncoding) { this(defaultContentTransferEncoding, STANDARD_MICALGS); } /** * base constructor - default content transfer encoding explicitly set * * @param micAlgs a map of ANS1ObjectIdentifiers to strings hash algorithm names. */ public SMIMESignedGenerator( Map micAlgs) { this("7bit", micAlgs); } /** * base constructor - default content transfer encoding explicitly set * * @param defaultContentTransferEncoding new default to use. * @param micAlgs a map of ANS1ObjectIdentifiers to strings hash algorithm names. */ public SMIMESignedGenerator( String defaultContentTransferEncoding, Map micAlgs) { this.defaultContentTransferEncoding = defaultContentTransferEncoding; this.micAlgs = micAlgs; } /** * add a signer - no attributes other than the default ones will be * provided here. * * @param key key to use to generate the signature * @param cert the public key certificate associated with the signer's key. * @param digestOID object ID of the digest algorithm to use. * @exception IllegalArgumentException any of the arguments are inappropriate * @deprecated use addSignerInfoGenerator() */ public void addSigner( PrivateKey key, X509Certificate cert, String digestOID) throws IllegalArgumentException { _signers.add(new Signer(key, cert, new ASN1ObjectIdentifier(digestOID), null, null)); } /** * add a signer - no attributes other than the default ones will be * provided here. * * @param key key to use to generate the signature * @param cert the public key certificate associated with the signer's key. * @param encryptionOID object ID of the digest ecnryption algorithm to use. * @param digestOID object ID of the digest algorithm to use. * @exception IllegalArgumentException any of the arguments are inappropriate * @deprecated use addSignerInfoGenerator() */ public void addSigner( PrivateKey key, X509Certificate cert, String encryptionOID, String digestOID) throws IllegalArgumentException { _signers.add(new Signer(key, cert, new ASN1ObjectIdentifier(encryptionOID), new ASN1ObjectIdentifier(digestOID), null, null)); } /** * Add a signer with extra signed/unsigned attributes or overrides * for the standard attributes. For example this method can be used to * explictly set default attributes such as the signing time. * * @param key key to use to generate the signature * @param cert the public key certificate associated with the signer's key. * @param digestOID object ID of the digest algorithm to use. * @param signedAttr signed attributes to be included in the signature. * @param unsignedAttr unsigned attribitues to be included. * @exception IllegalArgumentException any of the arguments are inappropriate * @deprecated use addSignerInfoGenerator() */ public void addSigner( PrivateKey key, X509Certificate cert, String digestOID, AttributeTable signedAttr, AttributeTable unsignedAttr) throws IllegalArgumentException { _signers.add(new Signer(key, cert, new ASN1ObjectIdentifier(digestOID), signedAttr, unsignedAttr)); } /** * Add a signer with extra signed/unsigned attributes or overrides * for the standard attributes and a digest encryption algorithm. For * example this method can be used to explictly set default attributes * such as the signing time. * * @param key key to use to generate the signature * @param cert the public key certificate associated with the signer's key. * @param encryptionOID the digest encryption algorithm OID. * @param digestOID object ID of the digest algorithm to use. * @param signedAttr signed attributes to be included in the signature. * @param unsignedAttr unsigned attribitues to be included. * @exception IllegalArgumentException any of the arguments are inappropriate * @deprecated use addSignerInfoGenerator() */ public void addSigner( PrivateKey key, X509Certificate cert, String encryptionOID, String digestOID, AttributeTable signedAttr, AttributeTable unsignedAttr) throws IllegalArgumentException { _signers.add(new Signer(key, cert, new ASN1ObjectIdentifier(encryptionOID), new ASN1ObjectIdentifier(digestOID), signedAttr, unsignedAttr)); } /** * Add a store of precalculated signers to the generator. * * @param signerStore store of signers */ public void addSigners( SignerInformationStore signerStore) { Iterator it = signerStore.getSigners().iterator(); while (it.hasNext()) { _oldSigners.add(it.next()); } } public void addSignerInfoGenerator(SignerInfoGenerator sigInfoGen) { signerInfoGens.add(sigInfoGen); } /** * add the certificates and CRLs contained in the given CertStore * to the pool that will be included in the encoded signature block. *

    * Note: this assumes the CertStore will support null in the get * methods. *

    * @param certStore CertStore containing the certificates and CRLs to be added. * @deprecated use addCertificates(Store) and addCRLs(Store) */ public void addCertificatesAndCRLs( CertStore certStore) throws CertStoreException, SMIMEException { _certStores.add(certStore); } public void addCertificates( Store certStore) { certStores.add(certStore); } public void addCRLs( Store crlStore) { crlStores.add(crlStore); } public void addAttributeCertificates( Store certStore) { attrCertStores.add(certStore); } /** * Add the attribute certificates contained in the passed in store to the * generator. * * @param store a store of Version 2 attribute certificates * @throws CMSException if an error occurse processing the store. * @deprecated use addAttributeCertificates(Store) */ public void addAttributeCertificates( X509Store store) throws CMSException { _attributeCerts.add(store); } private void addHashHeader( StringBuffer header, List signers) { int count = 0; // // build the hash header // Iterator it = signers.iterator(); Set micAlgSet = new TreeSet(); while (it.hasNext()) { Object signer = it.next(); ASN1ObjectIdentifier digestOID; if (signer instanceof Signer) { digestOID = ((Signer)signer).getDigestOID(); } else if (signer instanceof SignerInformation) { digestOID = ((SignerInformation)signer).getDigestAlgorithmID().getAlgorithm(); } else { digestOID = ((SignerInfoGenerator)signer).getDigestAlgorithm().getAlgorithm(); } String micAlg = (String)micAlgs.get(digestOID); if (micAlg == null) { micAlgSet.add("unknown"); } else { micAlgSet.add(micAlg); } } it = micAlgSet.iterator(); while (it.hasNext()) { String alg = (String)it.next(); if (count == 0) { if (micAlgSet.size() != 1) { header.append("; micalg=\""); } else { header.append("; micalg="); } } else { header.append(','); } header.append(alg); count++; } if (count != 0) { if (micAlgSet.size() != 1) { header.append('\"'); } } } /* * at this point we expect our body part to be well defined. */ private MimeMultipart make( MimeBodyPart content, Provider sigProvider) throws NoSuchAlgorithmException, SMIMEException { try { MimeBodyPart sig = new MimeBodyPart(); sig.setContent(new ContentSigner(content, false, sigProvider), DETACHED_SIGNATURE_TYPE); sig.addHeader("Content-Type", DETACHED_SIGNATURE_TYPE); sig.addHeader("Content-Disposition", "attachment; filename=\"smime.p7s\""); sig.addHeader("Content-Description", "S/MIME Cryptographic Signature"); sig.addHeader("Content-Transfer-Encoding", encoding); // // build the multipart header // StringBuffer header = new StringBuffer( "signed; protocol=\"application/pkcs7-signature\""); List allSigners = new ArrayList(_signers); allSigners.addAll(_oldSigners); allSigners.addAll(signerInfoGens); addHashHeader(header, allSigners); MimeMultipart mm = new MimeMultipart(header.toString()); mm.addBodyPart(content); mm.addBodyPart(sig); return mm; } catch (MessagingException e) { throw new SMIMEException("exception putting multi-part together.", e); } } private MimeMultipart make( MimeBodyPart content) throws SMIMEException { try { MimeBodyPart sig = new MimeBodyPart(); sig.setContent(new ContentSigner(content, false), DETACHED_SIGNATURE_TYPE); sig.addHeader("Content-Type", DETACHED_SIGNATURE_TYPE); sig.addHeader("Content-Disposition", "attachment; filename=\"smime.p7s\""); sig.addHeader("Content-Description", "S/MIME Cryptographic Signature"); sig.addHeader("Content-Transfer-Encoding", encoding); // // build the multipart header // StringBuffer header = new StringBuffer( "signed; protocol=\"application/pkcs7-signature\""); List allSigners = new ArrayList(_signers); allSigners.addAll(_oldSigners); allSigners.addAll(signerInfoGens); addHashHeader(header, allSigners); MimeMultipart mm = new MimeMultipart(header.toString()); mm.addBodyPart(content); mm.addBodyPart(sig); return mm; } catch (MessagingException e) { throw new SMIMEException("exception putting multi-part together.", e); } } /* * at this point we expect our body part to be well defined - generate with data in the signature */ private MimeBodyPart makeEncapsulated( MimeBodyPart content, Provider sigProvider) throws NoSuchAlgorithmException, SMIMEException { try { MimeBodyPart sig = new MimeBodyPart(); sig.setContent(new ContentSigner(content, true, sigProvider), ENCAPSULATED_SIGNED_CONTENT_TYPE); sig.addHeader("Content-Type", ENCAPSULATED_SIGNED_CONTENT_TYPE); sig.addHeader("Content-Disposition", "attachment; filename=\"smime.p7m\""); sig.addHeader("Content-Description", "S/MIME Cryptographic Signed Data"); sig.addHeader("Content-Transfer-Encoding", encoding); return sig; } catch (MessagingException e) { throw new SMIMEException("exception putting body part together.", e); } } /* * at this point we expect our body part to be well defined - generate with data in the signature */ private MimeBodyPart makeEncapsulated( MimeBodyPart content) throws SMIMEException { try { MimeBodyPart sig = new MimeBodyPart(); sig.setContent(new ContentSigner(content, true), ENCAPSULATED_SIGNED_CONTENT_TYPE); sig.addHeader("Content-Type", ENCAPSULATED_SIGNED_CONTENT_TYPE); sig.addHeader("Content-Disposition", "attachment; filename=\"smime.p7m\""); sig.addHeader("Content-Description", "S/MIME Cryptographic Signed Data"); sig.addHeader("Content-Transfer-Encoding", encoding); return sig; } catch (MessagingException e) { throw new SMIMEException("exception putting body part together.", e); } } /** * Return a map of oids and byte arrays representing the digests calculated on the content during * the last generate. * * @return a map of oids (as String objects) and byte[] representing digests. */ public Map getGeneratedDigests() { return new HashMap(_digests); } /** * generate a signed object that contains an SMIME Signed Multipart * object using the given provider. * @param content the MimeBodyPart to be signed. * @param sigProvider the provider to be used for the signature. * @return a Multipart containing the content and signature. * @throws NoSuchAlgorithmException if the required algorithms for the signature cannot be found. * @throws NoSuchProviderException if no provider can be found. * @throws SMIMEException if an exception occurs in processing the signature. * @deprecated use generate(MimeBodyPart) */ public MimeMultipart generate( MimeBodyPart content, String sigProvider) throws NoSuchAlgorithmException, NoSuchProviderException, SMIMEException { return make(makeContentBodyPart(content), SMIMEUtil.getProvider(sigProvider)); } /** * generate a signed object that contains an SMIME Signed Multipart * object using the given provider. * @param content the MimeBodyPart to be signed. * @param sigProvider the provider to be used for the signature. * @return a Multipart containing the content and signature. * @throws NoSuchAlgorithmException if the required algorithms for the signature cannot be found. * @throws SMIMEException if an exception occurs in processing the signature. */ public MimeMultipart generate( MimeBodyPart content, Provider sigProvider) throws NoSuchAlgorithmException, SMIMEException { return make(makeContentBodyPart(content), sigProvider); } /** * generate a signed object that contains an SMIME Signed Multipart * object using the given provider from the given MimeMessage * * @throws NoSuchAlgorithmException if the required algorithms for the signature cannot be found. * @throws NoSuchProviderException if no provider can be found. * @throws SMIMEException if an exception occurs in processing the signature. */ public MimeMultipart generate( MimeMessage message, String sigProvider) throws NoSuchAlgorithmException, NoSuchProviderException, SMIMEException { return generate(message, SMIMEUtil.getProvider(sigProvider)); } /** * generate a signed object that contains an SMIME Signed Multipart * object using the given provider from the given MimeMessage * * @throws NoSuchAlgorithmException if the required algorithms for the signature cannot be found. * @throws NoSuchProviderException if no provider can be found. * @throws SMIMEException if an exception occurs in processing the signature. */ public MimeMultipart generate( MimeMessage message, Provider sigProvider) throws NoSuchAlgorithmException, SMIMEException { try { message.saveChanges(); // make sure we're up to date. } catch (MessagingException e) { throw new SMIMEException("unable to save message", e); } return make(makeContentBodyPart(message), sigProvider); } public MimeMultipart generate( MimeBodyPart content) throws SMIMEException { return make(makeContentBodyPart(content)); } /** * generate a signed message with encapsulated content *

    * Note: doing this is strongly not recommended as it means a * recipient of the message will have to be able to read the signature to read the * message. */ public MimeBodyPart generateEncapsulated( MimeBodyPart content) throws SMIMEException { return makeEncapsulated(makeContentBodyPart(content)); } /** * generate a signed message with encapsulated content *

    * Note: doing this is strongly not recommended as it means a * recipient of the message will have to be able to read the signature to read the * message. * @deprecated use generateEncapsulated(content) */ public MimeBodyPart generateEncapsulated( MimeBodyPart content, String sigProvider) throws NoSuchAlgorithmException, NoSuchProviderException, SMIMEException { return makeEncapsulated(makeContentBodyPart(content), SMIMEUtil.getProvider(sigProvider)); } /** * generate a signed message with encapsulated content *

    * Note: doing this is strongly not recommended as it means a * recipient of the message will have to be able to read the signature to read the * message. * @deprecated use generateEncapsulated(content) */ public MimeBodyPart generateEncapsulated( MimeBodyPart content, Provider sigProvider) throws NoSuchAlgorithmException, NoSuchProviderException, SMIMEException { return makeEncapsulated(makeContentBodyPart(content), sigProvider); } /** * generate a signed object that contains an SMIME Signed Multipart * object using the given provider from the given MimeMessage. *

    * Note: doing this is strongly not recommended as it means a * recipient of the message will have to be able to read the signature to read the * message. * @deprecated use generateEncapsulated(content) */ public MimeBodyPart generateEncapsulated( MimeMessage message, String sigProvider) throws NoSuchAlgorithmException, NoSuchProviderException, SMIMEException { return generateEncapsulated(message, SMIMEUtil.getProvider(sigProvider)); } /** * generate a signed object that contains an SMIME Signed Multipart * object using the given provider from the given MimeMessage. *

    * Note: doing this is strongly not recommended as it means a * recipient of the message will have to be able to read the signature to read the * message. * @deprecated use generateEncapsulated(content) */ public MimeBodyPart generateEncapsulated( MimeMessage message, Provider sigProvider) throws NoSuchAlgorithmException, SMIMEException { try { message.saveChanges(); // make sure we're up to date. } catch (MessagingException e) { throw new SMIMEException("unable to save message", e); } return makeEncapsulated(makeContentBodyPart(message), sigProvider); } /** * Creates a certificate management message which is like a signed message with no content * or signers but that still carries certificates and CRLs. * * @return a MimeBodyPart containing the certs and CRLs. * @deprecated use generateCertificateManagement() */ public MimeBodyPart generateCertificateManagement( String provider) throws SMIMEException, NoSuchProviderException { return generateCertificateManagement(SMIMEUtil.getProvider(provider)); } /** * Creates a certificate management message which is like a signed message with no content * or signers but that still carries certificates and CRLs. * * @return a MimeBodyPart containing the certs and CRLs. * @deprecated use generateCertificateManagement() */ public MimeBodyPart generateCertificateManagement( Provider provider) throws SMIMEException { try { MimeBodyPart sig = new MimeBodyPart(); sig.setContent(new ContentSigner(null, true, provider), CERTIFICATE_MANAGEMENT_CONTENT); sig.addHeader("Content-Type", CERTIFICATE_MANAGEMENT_CONTENT); sig.addHeader("Content-Disposition", "attachment; filename=\"smime.p7c\""); sig.addHeader("Content-Description", "S/MIME Certificate Management Message"); sig.addHeader("Content-Transfer-Encoding", encoding); return sig; } catch (MessagingException e) { throw new SMIMEException("exception putting body part together.", e); } } /** * Creates a certificate management message which is like a signed message with no content * or signers but that still carries certificates and CRLs. * * @return a MimeBodyPart containing the certs and CRLs. */ public MimeBodyPart generateCertificateManagement() throws SMIMEException { try { MimeBodyPart sig = new MimeBodyPart(); sig.setContent(new ContentSigner(null, true), CERTIFICATE_MANAGEMENT_CONTENT); sig.addHeader("Content-Type", CERTIFICATE_MANAGEMENT_CONTENT); sig.addHeader("Content-Disposition", "attachment; filename=\"smime.p7c\""); sig.addHeader("Content-Description", "S/MIME Certificate Management Message"); sig.addHeader("Content-Transfer-Encoding", encoding); return sig; } catch (MessagingException e) { throw new SMIMEException("exception putting body part together.", e); } } private class Signer { final PrivateKey key; final X509Certificate cert; final ASN1ObjectIdentifier encryptionOID; final ASN1ObjectIdentifier digestOID; final AttributeTable signedAttr; final AttributeTable unsignedAttr; Signer( PrivateKey key, X509Certificate cert, ASN1ObjectIdentifier digestOID, AttributeTable signedAttr, AttributeTable unsignedAttr) { this(key, cert, null, digestOID, signedAttr, unsignedAttr); } Signer( PrivateKey key, X509Certificate cert, ASN1ObjectIdentifier encryptionOID, ASN1ObjectIdentifier digestOID, AttributeTable signedAttr, AttributeTable unsignedAttr) { this.key = key; this.cert = cert; this.encryptionOID = encryptionOID; this.digestOID = digestOID; this.signedAttr = signedAttr; this.unsignedAttr = unsignedAttr; } public X509Certificate getCert() { return cert; } public ASN1ObjectIdentifier getEncryptionOID() { return encryptionOID; } public ASN1ObjectIdentifier getDigestOID() { return digestOID; } public PrivateKey getKey() { return key; } public AttributeTable getSignedAttr() { return signedAttr; } public AttributeTable getUnsignedAttr() { return unsignedAttr; } } private class ContentSigner implements SMIMEStreamingProcessor { private final MimeBodyPart content; private final boolean encapsulate; private final Provider provider; private final boolean noProvider; ContentSigner( MimeBodyPart content, boolean encapsulate, Provider provider) { this.content = content; this.encapsulate = encapsulate; this.provider = provider; this.noProvider = false; } ContentSigner( MimeBodyPart content, boolean encapsulate) { this.content = content; this.encapsulate = encapsulate; this.provider = null; this.noProvider = true; } protected CMSSignedDataStreamGenerator getGenerator() throws CMSException, CertStoreException, InvalidKeyException, NoSuchAlgorithmException, NoSuchProviderException { CMSSignedDataStreamGenerator gen = new CMSSignedDataStreamGenerator(); for (Iterator it = _certStores.iterator(); it.hasNext();) { gen.addCertificatesAndCRLs((CertStore)it.next()); } for (Iterator it = certStores.iterator(); it.hasNext();) { gen.addCertificates((Store)it.next()); } for (Iterator it = crlStores.iterator(); it.hasNext();) { gen.addCRLs((Store)it.next()); } for (Iterator it = attrCertStores.iterator(); it.hasNext();) { gen.addAttributeCertificates((Store)it.next()); } for (Iterator it = _attributeCerts.iterator(); it.hasNext();) { gen.addAttributeCertificates((X509Store)it.next()); } for (Iterator it = _signers.iterator(); it.hasNext();) { Signer signer = (Signer)it.next(); if (signer.getEncryptionOID() != null) { gen.addSigner(signer.getKey(), signer.getCert(), signer.getEncryptionOID().getId(), signer.getDigestOID().getId(), signer.getSignedAttr(), signer.getUnsignedAttr(), provider); } else { gen.addSigner(signer.getKey(), signer.getCert(), signer.getDigestOID().getId(), signer.getSignedAttr(), signer.getUnsignedAttr(), provider); } } for (Iterator it = signerInfoGens.iterator(); it.hasNext();) { gen.addSignerInfoGenerator((SignerInfoGenerator)it.next()); } gen.addSigners(new SignerInformationStore(_oldSigners)); return gen; } private void writeBodyPart( OutputStream out, MimeBodyPart bodyPart) throws IOException, MessagingException { if (bodyPart.getContent() instanceof Multipart) { Multipart mp = (Multipart)bodyPart.getContent(); ContentType contentType = new ContentType(mp.getContentType()); String boundary = "--" + contentType.getParameter("boundary"); SMIMEUtil.LineOutputStream lOut = new SMIMEUtil.LineOutputStream(out); Enumeration headers = bodyPart.getAllHeaderLines(); while (headers.hasMoreElements()) { lOut.writeln((String)headers.nextElement()); } lOut.writeln(); // CRLF separator SMIMEUtil.outputPreamble(lOut, bodyPart, boundary); for (int i = 0; i < mp.getCount(); i++) { lOut.writeln(boundary); writeBodyPart(out, (MimeBodyPart)mp.getBodyPart(i)); lOut.writeln(); // CRLF terminator } lOut.writeln(boundary + "--"); } else { if (SMIMEUtil.isCanonicalisationRequired(bodyPart, defaultContentTransferEncoding)) { out = new CRLFOutputStream(out); } bodyPart.writeTo(out); } } public void write(OutputStream out) throws IOException { try { CMSSignedDataStreamGenerator gen = getGenerator(); OutputStream signingStream = gen.open(out, encapsulate); if (content != null) { if (!encapsulate) { writeBodyPart(signingStream, content); } else { content.getDataHandler().setCommandMap(addCommands(CommandMap.getDefaultCommandMap())); content.writeTo(signingStream); } } signingStream.close(); _digests = gen.getGeneratedDigests(); } catch (MessagingException e) { throw new IOException(e.toString()); } catch (NoSuchAlgorithmException e) { throw new IOException(e.toString()); } catch (NoSuchProviderException e) { throw new IOException(e.toString()); } catch (CMSException e) { throw new IOException(e.toString()); } catch (InvalidKeyException e) { throw new IOException(e.toString()); } catch (CertStoreException e) { throw new IOException(e.toString()); } } } } bouncycastle-1.49.orig/src/org/bouncycastle/mail/smime/SMIMEEnveloped.java0000644000175000017500000000246210321675335026126 0ustar ebourgebourgpackage org.bouncycastle.mail.smime; import java.io.IOException; import java.io.InputStream; import javax.mail.MessagingException; import javax.mail.Part; import javax.mail.internet.MimeBodyPart; import javax.mail.internet.MimeMessage; import javax.mail.internet.MimePart; import org.bouncycastle.cms.CMSEnvelopedData; import org.bouncycastle.cms.CMSException; /** * containing class for an S/MIME pkcs7-mime encrypted MimePart. */ public class SMIMEEnveloped extends CMSEnvelopedData { MimePart message; private static InputStream getInputStream( Part bodyPart) throws MessagingException { try { return bodyPart.getInputStream(); } catch (IOException e) { throw new MessagingException("can't extract input stream: " + e); } } public SMIMEEnveloped( MimeBodyPart message) throws MessagingException, CMSException { super(getInputStream(message)); this.message = message; } public SMIMEEnveloped( MimeMessage message) throws MessagingException, CMSException { super(getInputStream(message)); this.message = message; } public MimePart getEncryptedContent() { return message; } } bouncycastle-1.49.orig/src/org/bouncycastle/mail/smime/SMIMECompressed.java0000644000175000017500000000245610262753175026317 0ustar ebourgebourgpackage org.bouncycastle.mail.smime; import java.io.IOException; import java.io.InputStream; import javax.mail.MessagingException; import javax.mail.Part; import javax.mail.internet.MimeBodyPart; import javax.mail.internet.MimeMessage; import javax.mail.internet.MimePart; import org.bouncycastle.cms.CMSCompressedData; import org.bouncycastle.cms.CMSException; /** * containing class for an S/MIME pkcs7-mime MimePart. */ public class SMIMECompressed extends CMSCompressedData { MimePart message; private static InputStream getInputStream( Part bodyPart) throws MessagingException { try { return bodyPart.getInputStream(); } catch (IOException e) { throw new MessagingException("can't extract input stream: " + e); } } public SMIMECompressed( MimeBodyPart message) throws MessagingException, CMSException { super(getInputStream(message)); this.message = message; } public SMIMECompressed( MimeMessage message) throws MessagingException, CMSException { super(getInputStream(message)); this.message = message; } public MimePart getCompressedContent() { return message; } } bouncycastle-1.49.orig/src/org/bouncycastle/mail/smime/SMIMEEnvelopedGenerator.java0000644000175000017500000005212111605460427027772 0ustar ebourgebourgpackage org.bouncycastle.mail.smime; import java.io.IOException; import java.io.OutputStream; import java.security.InvalidKeyException; import java.security.NoSuchAlgorithmException; import java.security.NoSuchProviderException; import java.security.PrivateKey; import java.security.Provider; import java.security.PublicKey; import java.security.cert.CertificateEncodingException; import java.security.cert.X509Certificate; import java.util.ArrayList; import java.util.Iterator; import java.util.List; import javax.activation.CommandMap; import javax.activation.MailcapCommandMap; import javax.crypto.SecretKey; import javax.mail.MessagingException; import javax.mail.internet.MimeBodyPart; import javax.mail.internet.MimeMessage; import org.bouncycastle.asn1.ASN1EncodableVector; import org.bouncycastle.asn1.ASN1ObjectIdentifier; import org.bouncycastle.cms.CMSEnvelopedDataGenerator; import org.bouncycastle.cms.CMSEnvelopedDataStreamGenerator; import org.bouncycastle.cms.CMSException; import org.bouncycastle.cms.RecipientInfoGenerator; import org.bouncycastle.cms.jcajce.JceCMSContentEncryptorBuilder; import org.bouncycastle.cms.jcajce.JceKEKRecipientInfoGenerator; import org.bouncycastle.cms.jcajce.JceKeyAgreeRecipientInfoGenerator; import org.bouncycastle.cms.jcajce.JceKeyTransRecipientInfoGenerator; import org.bouncycastle.operator.OutputEncryptor; /** * General class for generating a pkcs7-mime message. * * A simple example of usage. * *

     *      SMIMEEnvelopedGenerator  fact = new SMIMEEnvelopedGenerator();
     *
     *      fact.addRecipientInfoGenerator(new JceKeyTransRecipientInfoGenerator(recipientCert).setProvider("BC"));
     *
     *      MimeBodyPart mp = fact.generate(content, new JceCMSContentEncryptorBuilder(CMSAlgorithm.RC2_CBC, 40).setProvider("BC").build());
     * 
    * * Note: Most clients expect the MimeBodyPart to be in a MimeMultipart * when it's sent. */ public class SMIMEEnvelopedGenerator extends SMIMEGenerator { public static final String DES_EDE3_CBC = CMSEnvelopedDataGenerator.DES_EDE3_CBC; public static final String RC2_CBC = CMSEnvelopedDataGenerator.RC2_CBC; public static final String IDEA_CBC = CMSEnvelopedDataGenerator.IDEA_CBC; public static final String CAST5_CBC = CMSEnvelopedDataGenerator.CAST5_CBC; public static final String AES128_CBC = CMSEnvelopedDataGenerator.AES128_CBC; public static final String AES192_CBC = CMSEnvelopedDataGenerator.AES192_CBC; public static final String AES256_CBC = CMSEnvelopedDataGenerator.AES256_CBC; public static final String CAMELLIA128_CBC = CMSEnvelopedDataGenerator.CAMELLIA128_CBC; public static final String CAMELLIA192_CBC = CMSEnvelopedDataGenerator.CAMELLIA192_CBC; public static final String CAMELLIA256_CBC = CMSEnvelopedDataGenerator.CAMELLIA256_CBC; public static final String SEED_CBC = CMSEnvelopedDataGenerator.SEED_CBC; public static final String DES_EDE3_WRAP = CMSEnvelopedDataGenerator.DES_EDE3_WRAP; public static final String AES128_WRAP = CMSEnvelopedDataGenerator.AES128_WRAP; public static final String AES256_WRAP = CMSEnvelopedDataGenerator.AES256_WRAP; public static final String CAMELLIA128_WRAP = CMSEnvelopedDataGenerator.CAMELLIA128_WRAP; public static final String CAMELLIA192_WRAP = CMSEnvelopedDataGenerator.CAMELLIA192_WRAP; public static final String CAMELLIA256_WRAP = CMSEnvelopedDataGenerator.CAMELLIA256_WRAP; public static final String SEED_WRAP = CMSEnvelopedDataGenerator.SEED_WRAP; public static final String ECDH_SHA1KDF = CMSEnvelopedDataGenerator.ECDH_SHA1KDF; private static final String ENCRYPTED_CONTENT_TYPE = "application/pkcs7-mime; name=\"smime.p7m\"; smime-type=enveloped-data"; private EnvelopedGenerator fact; private List recipients = new ArrayList(); static { CommandMap.setDefaultCommandMap(addCommands(CommandMap.getDefaultCommandMap())); } private static MailcapCommandMap addCommands(CommandMap cm) { MailcapCommandMap mc = (MailcapCommandMap)cm; mc.addMailcap("application/pkcs7-signature;; x-java-content-handler=org.bouncycastle.mail.smime.handlers.pkcs7_signature"); mc.addMailcap("application/pkcs7-mime;; x-java-content-handler=org.bouncycastle.mail.smime.handlers.pkcs7_mime"); mc.addMailcap("application/x-pkcs7-signature;; x-java-content-handler=org.bouncycastle.mail.smime.handlers.x_pkcs7_signature"); mc.addMailcap("application/x-pkcs7-mime;; x-java-content-handler=org.bouncycastle.mail.smime.handlers.x_pkcs7_mime"); mc.addMailcap("multipart/signed;; x-java-content-handler=org.bouncycastle.mail.smime.handlers.multipart_signed"); return mc; } /** * base constructor */ public SMIMEEnvelopedGenerator() { fact = new EnvelopedGenerator(); } /** * add a recipientInfoGenerator. */ public void addRecipientInfoGenerator( RecipientInfoGenerator recipientInfoGen) throws IllegalArgumentException { fact.addRecipientInfoGenerator(recipientInfoGen); } /** * add a recipient. * @deprecated use addRecipientInfoGenerator() */ public void addKeyTransRecipient( X509Certificate cert) throws IllegalArgumentException { try { JceKeyTransRecipientInfoGenerator infoGenerator = new JceKeyTransRecipientInfoGenerator(cert); recipients.add(infoGenerator); fact.addRecipientInfoGenerator(infoGenerator); } catch (CertificateEncodingException e) { throw new IllegalArgumentException(e.toString()); } } /** * add a recipient - note: this will only work on V3 and later clients. * * @param key the recipient's public key * @param subKeyId the subject key id for the recipient's public key * @deprecated use addRecipientInfoGenerator() */ public void addKeyTransRecipient( PublicKey key, byte[] subKeyId) throws IllegalArgumentException { JceKeyTransRecipientInfoGenerator infoGenerator = new JceKeyTransRecipientInfoGenerator(subKeyId, key); recipients.add(infoGenerator); fact.addRecipientInfoGenerator(infoGenerator); } /** * add a KEK recipient. * @deprecated use addRecipientInfoGenerator() */ public void addKEKRecipient( SecretKey key, byte[] keyIdentifier) throws IllegalArgumentException { JceKEKRecipientInfoGenerator infoGenerator = new JceKEKRecipientInfoGenerator(keyIdentifier, key); recipients.add(infoGenerator); fact.addRecipientInfoGenerator(infoGenerator); } /** * Add a key agreement based recipient. * * @param senderPrivateKey private key to initialise sender side of agreement with. * @param senderPublicKey sender public key to include with message. * @param recipientCert recipient's public key certificate. * @param cekWrapAlgorithm OID for key wrapping algorithm to use. * @param provider provider to use for the agreement calculation. * @deprecated use addRecipientInfoGenerator() */ public void addKeyAgreementRecipient( String agreementAlgorithm, PrivateKey senderPrivateKey, PublicKey senderPublicKey, X509Certificate recipientCert, String cekWrapAlgorithm, String provider) throws NoSuchProviderException, NoSuchAlgorithmException, InvalidKeyException { this.addKeyAgreementRecipient(agreementAlgorithm, senderPrivateKey, senderPublicKey, recipientCert, cekWrapAlgorithm, provider); } /** * Add a key agreement based recipient. * * @param senderPrivateKey private key to initialise sender side of agreement with. * @param senderPublicKey sender public key to include with message. * @param recipientCert recipient's public key certificate. * @param cekWrapAlgorithm OID for key wrapping algorithm to use. * @param provider provider to use for the agreement calculation. * @deprecated use addRecipientInfoGenerator() */ public void addKeyAgreementRecipient( String agreementAlgorithm, PrivateKey senderPrivateKey, PublicKey senderPublicKey, X509Certificate recipientCert, String cekWrapAlgorithm, Provider provider) throws NoSuchProviderException, NoSuchAlgorithmException, InvalidKeyException { try { JceKeyAgreeRecipientInfoGenerator infoGenerator = new JceKeyAgreeRecipientInfoGenerator(new ASN1ObjectIdentifier(agreementAlgorithm), senderPrivateKey, senderPublicKey, new ASN1ObjectIdentifier(cekWrapAlgorithm)); infoGenerator.addRecipient(recipientCert); if (provider != null) { infoGenerator.setProvider(provider); } fact.addRecipientInfoGenerator(infoGenerator); } catch (CertificateEncodingException e) { throw new NoSuchAlgorithmException("cannot set up generator: " + e); } } /** * Use a BER Set to store the recipient information */ public void setBerEncodeRecipients( boolean berEncodeRecipientSet) { fact.setBEREncodeRecipients(berEncodeRecipientSet); } /** * if we get here we expect the Mime body part to be well defined. */ private MimeBodyPart make( MimeBodyPart content, ASN1ObjectIdentifier encryptionOID, int keySize, Provider provider) throws NoSuchAlgorithmException, SMIMEException { // // check the base algorithm and provider is available // createSymmetricKeyGenerator(encryptionOID.getId(), provider); try { MimeBodyPart data = new MimeBodyPart(); data.setContent(new ContentEncryptor(content, encryptionOID, keySize, provider), ENCRYPTED_CONTENT_TYPE); data.addHeader("Content-Type", ENCRYPTED_CONTENT_TYPE); data.addHeader("Content-Disposition", "attachment; filename=\"smime.p7m\""); data.addHeader("Content-Description", "S/MIME Encrypted Message"); data.addHeader("Content-Transfer-Encoding", encoding); return data; } catch (MessagingException e) { throw new SMIMEException("exception putting S/MIME message together.", e); } catch (CMSException e) { throw new SMIMEException("exception putting envelope together.", e); } } /** * if we get here we expect the Mime body part to be well defined. */ private MimeBodyPart make( MimeBodyPart content, OutputEncryptor encryptor) throws SMIMEException { try { MimeBodyPart data = new MimeBodyPart(); data.setContent(new ContentEncryptor(content, encryptor), ENCRYPTED_CONTENT_TYPE); data.addHeader("Content-Type", ENCRYPTED_CONTENT_TYPE); data.addHeader("Content-Disposition", "attachment; filename=\"smime.p7m\""); data.addHeader("Content-Description", "S/MIME Encrypted Message"); data.addHeader("Content-Transfer-Encoding", encoding); return data; } catch (MessagingException e) { throw new SMIMEException("exception putting multi-part together.", e); } } /** * generate an enveloped object that contains an SMIME Enveloped * object using the given content encryptor */ public MimeBodyPart generate( MimeBodyPart content, OutputEncryptor encryptor) throws SMIMEException { return make(makeContentBodyPart(content), encryptor); } /** * generate an enveloped object that contains an SMIME Enveloped * object using the given provider from the contents of the passed in * message */ public MimeBodyPart generate( MimeMessage message, OutputEncryptor encryptor) throws SMIMEException { try { message.saveChanges(); // make sure we're up to date. } catch (MessagingException e) { throw new SMIMEException("unable to save message", e); } return make(makeContentBodyPart(message), encryptor); } /** * generate an enveloped object that contains an SMIME Enveloped * object using the given provider. * @deprecated */ public MimeBodyPart generate( MimeBodyPart content, String encryptionOID, String provider) throws NoSuchAlgorithmException, NoSuchProviderException, SMIMEException { return make(makeContentBodyPart(content), new ASN1ObjectIdentifier(encryptionOID), 0, SMIMEUtil.getProvider(provider)); } /** * generate an enveloped object that contains an SMIME Enveloped * object using the given provider. * @deprecated */ public MimeBodyPart generate( MimeBodyPart content, String encryptionOID, Provider provider) throws NoSuchAlgorithmException, SMIMEException { return make(makeContentBodyPart(content), new ASN1ObjectIdentifier(encryptionOID), 0, provider); } /** * generate an enveloped object that contains an SMIME Enveloped * object using the given provider from the contents of the passed in * message * @deprecated */ public MimeBodyPart generate( MimeMessage message, String encryptionOID, String provider) throws NoSuchAlgorithmException, NoSuchProviderException, SMIMEException { return generate(message, encryptionOID, SMIMEUtil.getProvider(provider)); } /** * generate an enveloped object that contains an SMIME Enveloped * object using the given provider from the contents of the passed in * message * @deprecated */ public MimeBodyPart generate( MimeMessage message, String encryptionOID, Provider provider) throws NoSuchAlgorithmException, NoSuchProviderException, SMIMEException { try { message.saveChanges(); // make sure we're up to date. } catch (MessagingException e) { throw new SMIMEException("unable to save message", e); } return make(makeContentBodyPart(message),new ASN1ObjectIdentifier(encryptionOID), 0, provider); } /** * generate an enveloped object that contains an SMIME Enveloped * object using the given provider. The size of the encryption key * is determined by keysize. * @deprecated */ public MimeBodyPart generate( MimeBodyPart content, String encryptionOID, int keySize, String provider) throws NoSuchAlgorithmException, NoSuchProviderException, SMIMEException { return generate(content, encryptionOID, keySize, SMIMEUtil.getProvider(provider)); } /** * generate an enveloped object that contains an SMIME Enveloped * object using the given provider. The size of the encryption key * is determined by keysize. * @deprecated */ public MimeBodyPart generate( MimeBodyPart content, String encryptionOID, int keySize, Provider provider) throws NoSuchAlgorithmException, NoSuchProviderException, SMIMEException { return make(makeContentBodyPart(content), new ASN1ObjectIdentifier(encryptionOID), keySize, provider); } /** * generate an enveloped object that contains an SMIME Enveloped * object using the given provider from the contents of the passed in * message. The size of the encryption key used to protect the message * is determined by keysize. * @deprecated */ public MimeBodyPart generate( MimeMessage message, String encryptionOID, int keySize, String provider) throws NoSuchAlgorithmException, NoSuchProviderException, SMIMEException { return generate(message, encryptionOID, keySize, SMIMEUtil.getProvider(provider)); } /** * generate an enveloped object that contains an SMIME Enveloped * object using the given provider from the contents of the passed in * message. The size of the encryption key used to protect the message * is determined by keysize. * @deprecated */ public MimeBodyPart generate( MimeMessage message, String encryptionOID, int keySize, Provider provider) throws NoSuchAlgorithmException, SMIMEException { try { message.saveChanges(); // make sure we're up to date. } catch (MessagingException e) { throw new SMIMEException("unable to save message", e); } return make(makeContentBodyPart(message), new ASN1ObjectIdentifier(encryptionOID), keySize, provider); } private class ContentEncryptor implements SMIMEStreamingProcessor { private final MimeBodyPart _content; private OutputEncryptor _encryptor; private boolean _firstTime = true; ContentEncryptor( MimeBodyPart content, ASN1ObjectIdentifier encryptionOid, int keySize, Provider provider) throws CMSException { _content = content; if (keySize == 0) // use the default { _encryptor = new JceCMSContentEncryptorBuilder(encryptionOid).setProvider(provider).build(); } else { _encryptor = new JceCMSContentEncryptorBuilder(encryptionOid, keySize).setProvider(provider).build(); } if (provider != null) { for (Iterator it = recipients.iterator(); it.hasNext();) { RecipientInfoGenerator rd = (RecipientInfoGenerator)it.next(); if (rd instanceof JceKeyTransRecipientInfoGenerator) { ((JceKeyTransRecipientInfoGenerator)rd).setProvider(provider); } else if (rd instanceof JceKEKRecipientInfoGenerator) { ((JceKEKRecipientInfoGenerator)rd).setProvider(provider); } } } } ContentEncryptor( MimeBodyPart content, OutputEncryptor encryptor) { _content = content; _encryptor = encryptor; } public void write(OutputStream out) throws IOException { OutputStream encrypted; try { if (_firstTime) { encrypted = fact.open(out, _encryptor); _firstTime = false; } else { encrypted = fact.regenerate(out, _encryptor); } _content.getDataHandler().setCommandMap(addCommands(CommandMap.getDefaultCommandMap())); _content.writeTo(encrypted); encrypted.close(); } catch (MessagingException e) { throw new WrappingIOException(e.toString(), e); } catch (CMSException e) { throw new WrappingIOException(e.toString(), e); } } } private class EnvelopedGenerator extends CMSEnvelopedDataStreamGenerator { private ASN1ObjectIdentifier dataType; private ASN1EncodableVector recipientInfos; protected OutputStream open( ASN1ObjectIdentifier dataType, OutputStream out, ASN1EncodableVector recipientInfos, OutputEncryptor encryptor) throws IOException { this.dataType = dataType; this.recipientInfos = recipientInfos; return super.open(dataType, out, recipientInfos, encryptor); } OutputStream regenerate( OutputStream out, OutputEncryptor encryptor) throws IOException { return super.open(dataType, out, recipientInfos, encryptor); } } private static class WrappingIOException extends IOException { private Throwable cause; WrappingIOException(String msg, Throwable cause) { super(msg); this.cause = cause; } public Throwable getCause() { return cause; } } } bouncycastle-1.49.orig/src/org/bouncycastle/mail/smime/examples/0000755000175000017500000000000012152033551024351 5ustar ebourgebourgbouncycastle-1.49.orig/src/org/bouncycastle/mail/smime/examples/CreateLargeSignedMail.java0000644000175000017500000001654111725030156031341 0ustar ebourgebourgpackage org.bouncycastle.mail.smime.examples; import java.io.File; import java.io.FileOutputStream; import java.io.IOException; import java.math.BigInteger; import java.security.GeneralSecurityException; import java.security.KeyPair; import java.security.KeyPairGenerator; import java.security.PrivateKey; import java.security.PublicKey; import java.security.SecureRandom; import java.security.cert.X509Certificate; import java.util.ArrayList; import java.util.Date; import java.util.List; import java.util.Properties; import javax.activation.DataHandler; import javax.activation.FileDataSource; import javax.mail.Address; import javax.mail.Message; import javax.mail.Session; import javax.mail.internet.InternetAddress; import javax.mail.internet.MimeBodyPart; import javax.mail.internet.MimeMessage; import javax.mail.internet.MimeMultipart; import org.bouncycastle.asn1.ASN1EncodableVector; import org.bouncycastle.asn1.cms.AttributeTable; import org.bouncycastle.asn1.cms.IssuerAndSerialNumber; import org.bouncycastle.asn1.smime.SMIMECapabilitiesAttribute; import org.bouncycastle.asn1.smime.SMIMECapability; import org.bouncycastle.asn1.smime.SMIMECapabilityVector; import org.bouncycastle.asn1.smime.SMIMEEncryptionKeyPreferenceAttribute; import org.bouncycastle.asn1.x500.X500Name; import org.bouncycastle.asn1.x509.X509Extension; import org.bouncycastle.cert.X509v3CertificateBuilder; import org.bouncycastle.cert.jcajce.JcaCertStore; import org.bouncycastle.cert.jcajce.JcaX509CertificateConverter; import org.bouncycastle.cert.jcajce.JcaX509ExtensionUtils; import org.bouncycastle.cert.jcajce.JcaX509v3CertificateBuilder; import org.bouncycastle.cms.jcajce.JcaSimpleSignerInfoGeneratorBuilder; import org.bouncycastle.mail.smime.SMIMESignedGenerator; import org.bouncycastle.operator.OperatorCreationException; import org.bouncycastle.operator.jcajce.JcaContentSignerBuilder; import org.bouncycastle.util.Store; /** * a simple example that creates a single signed mail message. */ public class CreateLargeSignedMail { // // certificate serial number seed. // static int serialNo = 1; /** * create a basic X509 certificate from the given keys */ static X509Certificate makeCertificate( KeyPair subKP, String subDN, KeyPair issKP, String issDN) throws GeneralSecurityException, IOException, OperatorCreationException { PublicKey subPub = subKP.getPublic(); PrivateKey issPriv = issKP.getPrivate(); PublicKey issPub = issKP.getPublic(); JcaX509ExtensionUtils extUtils = new JcaX509ExtensionUtils(); X509v3CertificateBuilder v3CertGen = new JcaX509v3CertificateBuilder(new X500Name(issDN), BigInteger.valueOf(serialNo++), new Date(System.currentTimeMillis()), new Date(System.currentTimeMillis() + (1000L * 60 * 60 * 24 * 100)), new X500Name(subDN), subPub); v3CertGen.addExtension( X509Extension.subjectKeyIdentifier, false, extUtils.createSubjectKeyIdentifier(subPub)); v3CertGen.addExtension( X509Extension.authorityKeyIdentifier, false, extUtils.createAuthorityKeyIdentifier(issPub)); return new JcaX509CertificateConverter().setProvider("BC").getCertificate(v3CertGen.build(new JcaContentSignerBuilder("MD5withRSA").setProvider("BC").build(issPriv))); } public static void main( String args[]) throws Exception { // // set up our certs // KeyPairGenerator kpg = KeyPairGenerator.getInstance("RSA", "BC"); kpg.initialize(1024, new SecureRandom()); // // cert that issued the signing certificate // String signDN = "O=Bouncy Castle, C=AU"; KeyPair signKP = kpg.generateKeyPair(); X509Certificate signCert = makeCertificate( signKP, signDN, signKP, signDN); // // cert we sign against // String origDN = "CN=Eric H. Echidna, E=eric@bouncycastle.org, O=Bouncy Castle, C=AU"; KeyPair origKP = kpg.generateKeyPair(); X509Certificate origCert = makeCertificate( origKP, origDN, signKP, signDN); List certList = new ArrayList(); certList.add(origCert); certList.add(signCert); // // create a CertStore containing the certificates we want carried // in the signature // Store certs = new JcaCertStore(certList); // // create some smime capabilities in case someone wants to respond // ASN1EncodableVector signedAttrs = new ASN1EncodableVector(); SMIMECapabilityVector caps = new SMIMECapabilityVector(); caps.addCapability(SMIMECapability.dES_EDE3_CBC); caps.addCapability(SMIMECapability.rC2_CBC, 128); caps.addCapability(SMIMECapability.dES_CBC); signedAttrs.add(new SMIMECapabilitiesAttribute(caps)); // // add an encryption key preference for encrypted responses - // normally this would be different from the signing certificate... // IssuerAndSerialNumber issAndSer = new IssuerAndSerialNumber( new X500Name(signDN), origCert.getSerialNumber()); signedAttrs.add(new SMIMEEncryptionKeyPreferenceAttribute(issAndSer)); // // create the generator for creating an smime/signed message // SMIMESignedGenerator gen = new SMIMESignedGenerator(); // // add a signer to the generator - this specifies we are using SHA1 and // adding the smime attributes above to the signed attributes that // will be generated as part of the signature. The encryption algorithm // used is taken from the key - in this RSA with PKCS1Padding // gen.addSignerInfoGenerator(new JcaSimpleSignerInfoGeneratorBuilder().setProvider("BC").setSignedAttributeGenerator(new AttributeTable(signedAttrs)).build("SHA1withRSA", origKP.getPrivate(), origCert)); // // add our pool of certs and cerls (if any) to go with the signature // gen.addCertificates(certs); // // create the base for our message // MimeBodyPart msg = new MimeBodyPart(); msg.setDataHandler(new DataHandler(new FileDataSource(new File(args[0])))); msg.setHeader("Content-Type", "application/octet-stream"); msg.setHeader("Content-Transfer-Encoding", "base64"); // // extract the multipart object from the SMIMESigned object. // MimeMultipart mm = gen.generate(msg); // // Get a Session object and create the mail message // Properties props = System.getProperties(); Session session = Session.getDefaultInstance(props, null); Address fromUser = new InternetAddress("\"Eric H. Echidna\""); Address toUser = new InternetAddress("example@bouncycastle.org"); MimeMessage body = new MimeMessage(session); body.setFrom(fromUser); body.setRecipient(Message.RecipientType.TO, toUser); body.setSubject("example signed message"); body.setContent(mm, mm.getContentType()); body.saveChanges(); body.writeTo(new FileOutputStream("signed.message")); } } bouncycastle-1.49.orig/src/org/bouncycastle/mail/smime/examples/ReadLargeSignedMail.java0000644000175000017500000000746211526421165031016 0ustar ebourgebourgpackage org.bouncycastle.mail.smime.examples; import java.security.cert.X509Certificate; import java.util.Collection; import java.util.Iterator; import java.util.Properties; import javax.mail.Session; import javax.mail.internet.MimeMessage; import javax.mail.internet.MimeMultipart; import org.bouncycastle.cert.X509CertificateHolder; import org.bouncycastle.cert.jcajce.JcaX509CertificateConverter; import org.bouncycastle.cms.SignerInformation; import org.bouncycastle.cms.SignerInformationStore; import org.bouncycastle.cms.jcajce.JcaSimpleSignerInfoVerifierBuilder; import org.bouncycastle.jce.provider.BouncyCastleProvider; import org.bouncycastle.mail.smime.SMIMESignedParser; import org.bouncycastle.mail.smime.util.SharedFileInputStream; import org.bouncycastle.util.Store; /** * a simple example that reads a basic SMIME signed mail file. */ public class ReadLargeSignedMail { private static final String BC = BouncyCastleProvider.PROVIDER_NAME; /** * verify the signature (assuming the cert is contained in the message) */ private static void verify( SMIMESignedParser s) throws Exception { // // extract the information to verify the signatures. // // // certificates and crls passed in the signature - this must happen before // s.getSignerInfos() // Store certs = s.getCertificates(); // // SignerInfo blocks which contain the signatures // SignerInformationStore signers = s.getSignerInfos(); Collection c = signers.getSigners(); Iterator it = c.iterator(); // // check each signer // while (it.hasNext()) { SignerInformation signer = (SignerInformation)it.next(); Collection certCollection = certs.getMatches(signer.getSID()); Iterator certIt = certCollection.iterator(); X509Certificate cert = new JcaX509CertificateConverter().setProvider(BC).getCertificate((X509CertificateHolder)certIt.next()); // // verify that the sig is correct and that it was generated // when the certificate was current // if (signer.verify(new JcaSimpleSignerInfoVerifierBuilder().setProvider(BC).build(cert))) { System.out.println("signature verified"); } else { System.out.println("signature failed!"); } } } public static void main( String[] args) throws Exception { // // Get a Session object with the default properties. // Properties props = System.getProperties(); Session session = Session.getDefaultInstance(props, null); MimeMessage msg = new MimeMessage(session, new SharedFileInputStream("signed.message")); // // make sure this was a multipart/signed message - there should be // two parts as we have one part for the content that was signed and // one part for the actual signature. // if (msg.isMimeType("multipart/signed")) { SMIMESignedParser s = new SMIMESignedParser( (MimeMultipart)msg.getContent()); System.out.println("Status:"); verify(s); } else if (msg.isMimeType("application/pkcs7-mime")) { // // in this case the content is wrapped in the signature block. // SMIMESignedParser s = new SMIMESignedParser(msg); System.out.println("Status:"); verify(s); } else { System.err.println("Not a signed message!"); } } } bouncycastle-1.49.orig/src/org/bouncycastle/mail/smime/examples/ValidateSignedMail.java0000644000175000017500000003035211625346707030723 0ustar ebourgebourgpackage org.bouncycastle.mail.smime.examples; import java.io.FileInputStream; import java.io.InputStream; import java.security.KeyPairGenerator; import java.security.KeyStore; import java.security.PublicKey; import java.security.SecureRandom; import java.security.Security; import java.security.cert.CertStore; import java.security.cert.CertificateFactory; import java.security.cert.CollectionCertStoreParameters; import java.security.cert.PKIXParameters; import java.security.cert.TrustAnchor; import java.security.cert.X509CRL; import java.security.cert.X509Certificate; import java.util.ArrayList; import java.util.HashSet; import java.util.Iterator; import java.util.List; import java.util.Locale; import java.util.Properties; import java.util.Set; import javax.mail.Session; import javax.mail.internet.MimeMessage; import javax.security.auth.x500.X500Principal; import org.bouncycastle.asn1.ASN1Encodable; import org.bouncycastle.asn1.ASN1Encoding; import org.bouncycastle.asn1.x509.X509Extension; import org.bouncycastle.cms.SignerInformation; import org.bouncycastle.i18n.ErrorBundle; import org.bouncycastle.jce.provider.BouncyCastleProvider; import org.bouncycastle.mail.smime.validator.SignedMailValidator; import org.bouncycastle.x509.PKIXCertPathReviewer; import org.bouncycastle.x509.extension.X509ExtensionUtil; /** * An Example that reads a signed mail and validates its signature. Also * validating the certificate path from the signers key to a trusted entity */ public class ValidateSignedMail { /* * Use trusted certificates from $JAVA_HOME/lib/security/cacerts as * trustanchors */ public static final boolean useCaCerts = false; public static void main(String[] args) throws Exception { Security.addProvider(new BouncyCastleProvider()); // // Get a Session object with the default properties. // Properties props = System.getProperties(); Session session = Session.getDefaultInstance(props, null); // read message MimeMessage msg = new MimeMessage(session, new FileInputStream( "signed.message")); // create PKIXparameters PKIXParameters param; if (useCaCerts) { KeyStore caCerts = KeyStore.getInstance("JKS"); String javaHome = System.getProperty("java.home"); caCerts.load( new FileInputStream(javaHome + "/lib/security/cacerts"), "changeit".toCharArray()); param = new PKIXParameters(caCerts); } else { // load trustanchors from files (here we only load one) Set trustanchors = new HashSet(); TrustAnchor trust = getTrustAnchor("trustanchor"); // create a dummy trustanchor if we can not find any trustanchor. so // we can still try to validate the message if (trust == null) { System.out .println("no trustanchor file found, using a dummy trustanchor"); trust = getDummyTrustAnchor(); } trustanchors.add(trust); param = new PKIXParameters(trustanchors); } // load one ore more crls from files (here we only load one crl) List crls = new ArrayList(); X509CRL crl = loadCRL("crl.file"); if (crl != null) { crls.add(crl); } CertStore certStore = CertStore.getInstance("Collection", new CollectionCertStoreParameters(crls), "BC"); // add crls and enable revocation checking param.addCertStore(certStore); param.setRevocationEnabled(true); // or disable revocation checking // param.setRevocationEnabled(false); verifySignedMail(msg, param); } public static final int TITLE = 0; public static final int TEXT = 1; public static final int SUMMARY = 2; public static final int DETAIL = 3; static int dbgLvl = DETAIL; private static final String RESOURCE_NAME = "org.bouncycastle.mail.smime.validator.SignedMailValidatorMessages"; public static void verifySignedMail(MimeMessage msg, PKIXParameters param) throws Exception { // set locale for the output Locale loc = Locale.ENGLISH; // Locale loc = Locale.GERMAN; // validate signatures SignedMailValidator validator = new SignedMailValidator(msg, param); // iterate over all signatures and print results Iterator it = validator.getSignerInformationStore().getSigners() .iterator(); while (it.hasNext()) { SignerInformation signer = (SignerInformation) it.next(); SignedMailValidator.ValidationResult result = validator .getValidationResult(signer); if (result.isValidSignature()) { ErrorBundle errMsg = new ErrorBundle(RESOURCE_NAME, "SignedMailValidator.sigValid"); System.out.println(errMsg.getText(loc)); } else { ErrorBundle errMsg = new ErrorBundle(RESOURCE_NAME, "SignedMailValidator.sigInvalid"); System.out.println(errMsg.getText(loc)); // print errors System.out.println("Errors:"); Iterator errorsIt = result.getErrors().iterator(); while (errorsIt.hasNext()) { ErrorBundle errorMsg = (ErrorBundle) errorsIt.next(); if (dbgLvl == DETAIL) { System.out.println("\t\t" + errorMsg.getDetail(loc)); } else { System.out.println("\t\t" + errorMsg.getText(loc)); } } } if (!result.getNotifications().isEmpty()) { System.out.println("Notifications:"); Iterator notIt = result.getNotifications().iterator(); while (notIt.hasNext()) { ErrorBundle notMsg = (ErrorBundle) notIt.next(); if (dbgLvl == DETAIL) { System.out.println("\t\t" + notMsg.getDetail(loc)); } else { System.out.println("\t\t" + notMsg.getText(loc)); } } } PKIXCertPathReviewer review = result.getCertPathReview(); if (review != null) { if (review.isValidCertPath()) { System.out.println("Certificate path valid"); } else { System.out.println("Certificate path invalid"); } System.out.println("\nCertificate path validation results:"); // global errors System.out.println("Errors:"); Iterator errorsIt = review.getErrors(-1).iterator(); while (errorsIt.hasNext()) { ErrorBundle errorMsg = (ErrorBundle) errorsIt.next(); if (dbgLvl == DETAIL) { System.out.println("\t\t" + errorMsg.getDetail(loc)); } else { System.out.println("\t\t" + errorMsg.getText(loc)); } } System.out.println("Notifications:"); Iterator notificationsIt = review.getNotifications(-1) .iterator(); while (notificationsIt.hasNext()) { ErrorBundle noteMsg = (ErrorBundle) notificationsIt.next(); System.out.println("\t" + noteMsg.getText(loc)); } // per certificate errors and notifications Iterator certIt = review.getCertPath().getCertificates() .iterator(); int i = 0; while (certIt.hasNext()) { X509Certificate cert = (X509Certificate) certIt.next(); System.out.println("\nCertificate " + i + "\n========"); System.out.println("Issuer: " + cert.getIssuerDN().getName()); System.out.println("Subject: " + cert.getSubjectDN().getName()); // errors System.out.println("\tErrors:"); errorsIt = review.getErrors(i).iterator(); while (errorsIt.hasNext()) { ErrorBundle errorMsg = (ErrorBundle) errorsIt.next(); if (dbgLvl == DETAIL) { System.out .println("\t\t" + errorMsg.getDetail(loc)); } else { System.out.println("\t\t" + errorMsg.getText(loc)); } } // notifications System.out.println("\tNotifications:"); notificationsIt = review.getNotifications(i).iterator(); while (notificationsIt.hasNext()) { ErrorBundle noteMsg = (ErrorBundle) notificationsIt .next(); if (dbgLvl == DETAIL) { System.out.println("\t\t" + noteMsg.getDetail(loc)); } else { System.out.println("\t\t" + noteMsg.getText(loc)); } } i++; } } } } protected static TrustAnchor getTrustAnchor(String trustcert) throws Exception { X509Certificate cert = loadCert(trustcert); if (cert != null) { byte[] ncBytes = cert .getExtensionValue(X509Extension.nameConstraints.getId()); if (ncBytes != null) { ASN1Encodable extValue = X509ExtensionUtil .fromExtensionValue(ncBytes); return new TrustAnchor(cert, extValue.toASN1Primitive().getEncoded(ASN1Encoding.DER)); } return new TrustAnchor(cert, null); } return null; } protected static X509Certificate loadCert(String certfile) { X509Certificate cert = null; try { InputStream in = new FileInputStream(certfile); CertificateFactory cf = CertificateFactory.getInstance("X.509", "BC"); cert = (X509Certificate) cf.generateCertificate(in); } catch (Exception e) { System.out.println("certfile \"" + certfile + "\" not found - classpath is " + System.getProperty("java.class.path")); } return cert; } protected static X509CRL loadCRL(String crlfile) { X509CRL crl = null; try { InputStream in = new FileInputStream(crlfile); CertificateFactory cf = CertificateFactory.getInstance("X.509", "BC"); crl = (X509CRL) cf.generateCRL(in); } catch (Exception e) { System.out.println("crlfile \"" + crlfile + "\" not found - classpath is " + System.getProperty("java.class.path")); } return crl; } private static TrustAnchor getDummyTrustAnchor() throws Exception { X500Principal principal = new X500Principal("CN=Dummy Trust Anchor"); KeyPairGenerator kpg = KeyPairGenerator.getInstance("RSA", "BC"); kpg.initialize(1024, new SecureRandom()); PublicKey trustPubKey = kpg.generateKeyPair().getPublic(); return new TrustAnchor(principal, trustPubKey, null); } } bouncycastle-1.49.orig/src/org/bouncycastle/mail/smime/examples/ReadLargeCompressedMail.java0000644000175000017500000000215410323462543031701 0ustar ebourgebourgpackage org.bouncycastle.mail.smime.examples; import java.util.Properties; import javax.mail.Session; import javax.mail.internet.MimeBodyPart; import javax.mail.internet.MimeMessage; import org.bouncycastle.mail.smime.SMIMECompressedParser; import org.bouncycastle.mail.smime.SMIMEUtil; import org.bouncycastle.mail.smime.util.SharedFileInputStream; /** * a simple example that reads an oversize compressed email and writes data contained * in the compressed part into a file. */ public class ReadLargeCompressedMail { public static void main( String args[]) throws Exception { // // Get a Session object with the default properties. // Properties props = System.getProperties(); Session session = Session.getDefaultInstance(props, null); MimeMessage msg = new MimeMessage(session, new SharedFileInputStream("compressed.message")); SMIMECompressedParser m = new SMIMECompressedParser(msg); MimeBodyPart res = SMIMEUtil.toMimeBodyPart(m.getContent()); ExampleUtils.dumpContent(res, args[0]); } } bouncycastle-1.49.orig/src/org/bouncycastle/mail/smime/examples/CreateCompressedMail.java0000644000175000017500000000326710262753175031272 0ustar ebourgebourgpackage org.bouncycastle.mail.smime.examples; import java.io.FileOutputStream; import java.util.Properties; import javax.mail.Address; import javax.mail.Message; import javax.mail.Session; import javax.mail.internet.InternetAddress; import javax.mail.internet.MimeBodyPart; import javax.mail.internet.MimeMessage; import org.bouncycastle.mail.smime.SMIMECompressedGenerator; /** * a simple example that creates a single compressed mail message. */ public class CreateCompressedMail { public static void main( String args[]) throws Exception { // // create the generator for creating an smime/compressed message // SMIMECompressedGenerator gen = new SMIMECompressedGenerator(); // // create the base for our message // MimeBodyPart msg = new MimeBodyPart(); msg.setText("Hello world!"); MimeBodyPart mp = gen.generate(msg, SMIMECompressedGenerator.ZLIB); // // Get a Session object and create the mail message // Properties props = System.getProperties(); Session session = Session.getDefaultInstance(props, null); Address fromUser = new InternetAddress("\"Eric H. Echidna\""); Address toUser = new InternetAddress("example@bouncycastle.org"); MimeMessage body = new MimeMessage(session); body.setFrom(fromUser); body.setRecipient(Message.RecipientType.TO, toUser); body.setSubject("example compressed message"); body.setContent(mp.getContent(), mp.getContentType()); body.saveChanges(); body.writeTo(new FileOutputStream("compressed.message")); } } bouncycastle-1.49.orig/src/org/bouncycastle/mail/smime/examples/ReadLargeEncryptedMail.java0000644000175000017500000000473611521701156031537 0ustar ebourgebourgpackage org.bouncycastle.mail.smime.examples; import java.security.KeyStore; import java.security.PrivateKey; import java.security.cert.X509Certificate; import java.util.Properties; import javax.mail.Session; import javax.mail.internet.MimeBodyPart; import javax.mail.internet.MimeMessage; import org.bouncycastle.cms.RecipientId; import org.bouncycastle.cms.RecipientInformation; import org.bouncycastle.cms.RecipientInformationStore; import org.bouncycastle.cms.jcajce.JceKeyTransEnvelopedRecipient; import org.bouncycastle.cms.jcajce.JceKeyTransRecipientId; import org.bouncycastle.mail.smime.SMIMEEnvelopedParser; import org.bouncycastle.mail.smime.SMIMEUtil; import org.bouncycastle.mail.smime.util.SharedFileInputStream; /** * a simple example that reads an encrypted email using the large file model. *

    * The key store can be created using the class in * org.bouncycastle.jce.examples.PKCS12Example - the program expects only one * key to be present. */ public class ReadLargeEncryptedMail { public static void main( String args[]) throws Exception { if (args.length != 3) { System.err.println("usage: ReadLargeEncryptedMail pkcs12Keystore password outputFile"); System.exit(0); } // // Open the key store // KeyStore ks = KeyStore.getInstance("PKCS12", "BC"); String keyAlias = ExampleUtils.findKeyAlias(ks, args[0], args[1].toCharArray()); // // find the certificate for the private key and generate a // suitable recipient identifier. // X509Certificate cert = (X509Certificate)ks.getCertificate(keyAlias); RecipientId recId = new JceKeyTransRecipientId(cert); // // Get a Session object with the default properties. // Properties props = System.getProperties(); Session session = Session.getDefaultInstance(props, null); MimeMessage msg = new MimeMessage(session, new SharedFileInputStream("encrypted.message")); SMIMEEnvelopedParser m = new SMIMEEnvelopedParser(msg); RecipientInformationStore recipients = m.getRecipientInfos(); RecipientInformation recipient = recipients.get(recId); MimeBodyPart res = SMIMEUtil.toMimeBodyPart(recipient.getContentStream(new JceKeyTransEnvelopedRecipient((PrivateKey)ks.getKey(keyAlias, null)).setProvider("BC"))); ExampleUtils.dumpContent(res, args[2]); } } bouncycastle-1.49.orig/src/org/bouncycastle/mail/smime/examples/ExampleUtils.java0000644000175000017500000000362610323462507027644 0ustar ebourgebourgpackage org.bouncycastle.mail.smime.examples; import java.io.FileInputStream; import java.io.FileOutputStream; import java.io.IOException; import java.io.InputStream; import java.io.OutputStream; import java.security.KeyStore; import java.util.Enumeration; import javax.mail.MessagingException; import javax.mail.internet.MimeBodyPart; public class ExampleUtils { /** * Dump the content of the passed in BodyPart to the file fileName. * * @throws MessagingException * @throws IOException */ public static void dumpContent( MimeBodyPart bodyPart, String fileName) throws MessagingException, IOException { // // print mime type of compressed content // System.out.println("content type: " + bodyPart.getContentType()); // // recover the compressed content // OutputStream out = new FileOutputStream(fileName); InputStream in = bodyPart.getInputStream(); byte[] buf = new byte[10000]; int len; while ((len = in.read(buf, 0, buf.length)) > 0) { out.write(buf, 0, len); } out.close(); } public static String findKeyAlias( KeyStore store, String storeName, char[] password) throws Exception { store.load(new FileInputStream(storeName), password); Enumeration e = store.aliases(); String keyAlias = null; while (e.hasMoreElements()) { String alias = (String)e.nextElement(); if (store.isKeyEntry(alias)) { keyAlias = alias; } } if (keyAlias == null) { throw new IllegalArgumentException("can't find a private key in keyStore: " + storeName); } return keyAlias; } } bouncycastle-1.49.orig/src/org/bouncycastle/mail/smime/examples/SendSignedAndEncryptedMail.java0000644000175000017500000002010611521712237032346 0ustar ebourgebourgpackage org.bouncycastle.mail.smime.examples; import java.io.ByteArrayInputStream; import java.io.ByteArrayOutputStream; import java.io.FileInputStream; import java.security.KeyStore; import java.security.PrivateKey; import java.security.Security; import java.security.cert.Certificate; import java.security.cert.X509Certificate; import java.util.ArrayList; import java.util.Enumeration; import java.util.List; import java.util.Properties; import javax.activation.CommandMap; import javax.activation.MailcapCommandMap; import javax.mail.Message; import javax.mail.Session; import javax.mail.Transport; import javax.mail.internet.InternetAddress; import javax.mail.internet.MimeBodyPart; import javax.mail.internet.MimeMessage; import javax.mail.internet.MimeMultipart; import org.bouncycastle.asn1.ASN1EncodableVector; import org.bouncycastle.asn1.cms.AttributeTable; import org.bouncycastle.asn1.cms.IssuerAndSerialNumber; import org.bouncycastle.asn1.smime.SMIMECapabilitiesAttribute; import org.bouncycastle.asn1.smime.SMIMECapability; import org.bouncycastle.asn1.smime.SMIMECapabilityVector; import org.bouncycastle.asn1.smime.SMIMEEncryptionKeyPreferenceAttribute; import org.bouncycastle.asn1.x500.X500Name; import org.bouncycastle.cert.jcajce.JcaCertStore; import org.bouncycastle.cms.CMSAlgorithm; import org.bouncycastle.cms.jcajce.JcaSimpleSignerInfoGeneratorBuilder; import org.bouncycastle.cms.jcajce.JceCMSContentEncryptorBuilder; import org.bouncycastle.cms.jcajce.JceKeyTransRecipientInfoGenerator; import org.bouncycastle.jce.provider.BouncyCastleProvider; import org.bouncycastle.mail.smime.SMIMEEnvelopedGenerator; import org.bouncycastle.mail.smime.SMIMEException; import org.bouncycastle.mail.smime.SMIMESignedGenerator; import org.bouncycastle.util.Store; import org.bouncycastle.util.Strings; /** * Example that sends a signed and encrypted mail message. */ public class SendSignedAndEncryptedMail { public static void main(String args[]) { if (args.length != 5) { System.err .println("usage: SendSignedAndEncryptedMail "); System.exit(0); } try { MailcapCommandMap mailcap = (MailcapCommandMap)CommandMap .getDefaultCommandMap(); mailcap .addMailcap("application/pkcs7-signature;; x-java-content-handler=org.bouncycastle.mail.smime.handlers.pkcs7_signature"); mailcap .addMailcap("application/pkcs7-mime;; x-java-content-handler=org.bouncycastle.mail.smime.handlers.pkcs7_mime"); mailcap .addMailcap("application/x-pkcs7-signature;; x-java-content-handler=org.bouncycastle.mail.smime.handlers.x_pkcs7_signature"); mailcap .addMailcap("application/x-pkcs7-mime;; x-java-content-handler=org.bouncycastle.mail.smime.handlers.x_pkcs7_mime"); mailcap .addMailcap("multipart/signed;; x-java-content-handler=org.bouncycastle.mail.smime.handlers.multipart_signed"); CommandMap.setDefaultCommandMap(mailcap); /* Add BC */ Security.addProvider(new BouncyCastleProvider()); /* Open the keystore */ KeyStore keystore = KeyStore.getInstance("PKCS12", "BC"); keystore.load(new FileInputStream(args[0]), args[1].toCharArray()); Certificate[] chain = keystore.getCertificateChain(args[2]); /* Get the private key to sign the message with */ PrivateKey privateKey = (PrivateKey)keystore.getKey(args[2], args[1].toCharArray()); if (privateKey == null) { throw new Exception("cannot find private key for alias: " + args[2]); } /* Create the message to sign and encrypt */ Properties props = System.getProperties(); props.put("mail.smtp.host", args[3]); Session session = Session.getDefaultInstance(props, null); MimeMessage body = new MimeMessage(session); body.setFrom(new InternetAddress(args[4])); body.setRecipient(Message.RecipientType.TO, new InternetAddress( args[4])); body.setSubject("example encrypted message"); body.setContent("example encrypted message", "text/plain"); body.saveChanges(); /* Create the SMIMESignedGenerator */ SMIMECapabilityVector capabilities = new SMIMECapabilityVector(); capabilities.addCapability(SMIMECapability.dES_EDE3_CBC); capabilities.addCapability(SMIMECapability.rC2_CBC, 128); capabilities.addCapability(SMIMECapability.dES_CBC); ASN1EncodableVector attributes = new ASN1EncodableVector(); attributes.add(new SMIMEEncryptionKeyPreferenceAttribute( new IssuerAndSerialNumber( new X500Name(((X509Certificate)chain[0]) .getIssuerDN().getName()), ((X509Certificate)chain[0]).getSerialNumber()))); attributes.add(new SMIMECapabilitiesAttribute(capabilities)); SMIMESignedGenerator signer = new SMIMESignedGenerator(); signer.addSignerInfoGenerator(new JcaSimpleSignerInfoGeneratorBuilder().setProvider("BC").setSignedAttributeGenerator(new AttributeTable(attributes)).build("DSA".equals(privateKey.getAlgorithm()) ? "SHA1withDSA" : "MD5withDSA", privateKey, (X509Certificate)chain[0])); /* Add the list of certs to the generator */ List certList = new ArrayList(); certList.add(chain[0]); Store certs = new JcaCertStore(certList); signer.addCertificates(certs); /* Sign the message */ MimeMultipart mm = signer.generate(body, "BC"); MimeMessage signedMessage = new MimeMessage(session); /* Set all original MIME headers in the signed message */ Enumeration headers = body.getAllHeaderLines(); while (headers.hasMoreElements()) { signedMessage.addHeaderLine((String)headers.nextElement()); } /* Set the content of the signed message */ signedMessage.setContent(mm); signedMessage.saveChanges(); /* Create the encrypter */ SMIMEEnvelopedGenerator encrypter = new SMIMEEnvelopedGenerator(); encrypter.addRecipientInfoGenerator(new JceKeyTransRecipientInfoGenerator((X509Certificate)chain[0]).setProvider("BC")); /* Encrypt the message */ MimeBodyPart encryptedPart = encrypter.generate(signedMessage, new JceCMSContentEncryptorBuilder(CMSAlgorithm.RC2_CBC).setProvider("BC").build()); /* * Create a new MimeMessage that contains the encrypted and signed * content */ ByteArrayOutputStream out = new ByteArrayOutputStream(); encryptedPart.writeTo(out); MimeMessage encryptedMessage = new MimeMessage(session, new ByteArrayInputStream(out.toByteArray())); /* Set all original MIME headers in the encrypted message */ headers = body.getAllHeaderLines(); while (headers.hasMoreElements()) { String headerLine = (String)headers.nextElement(); /* * Make sure not to override any content-* headers from the * original message */ if (!Strings.toLowerCase(headerLine).startsWith("content-")) { encryptedMessage.addHeaderLine(headerLine); } } Transport.send(encryptedMessage); } catch (SMIMEException ex) { ex.getUnderlyingException().printStackTrace(System.err); ex.printStackTrace(System.err); } catch (Exception ex) { ex.printStackTrace(System.err); } } } bouncycastle-1.49.orig/src/org/bouncycastle/mail/smime/examples/CreateLargeEncryptedMail.java0000644000175000017500000000673410323462470032071 0ustar ebourgebourgpackage org.bouncycastle.mail.smime.examples; import java.io.File; import java.io.FileOutputStream; import java.security.KeyStore; import java.security.cert.Certificate; import java.security.cert.X509Certificate; import java.util.Properties; import javax.activation.DataHandler; import javax.activation.FileDataSource; import javax.mail.Address; import javax.mail.Message; import javax.mail.Session; import javax.mail.internet.InternetAddress; import javax.mail.internet.MimeBodyPart; import javax.mail.internet.MimeMessage; import org.bouncycastle.mail.smime.SMIMEEnvelopedGenerator; /** * a simple example that creates a single encrypted mail message. *

    * The key store can be created using the class in * org.bouncycastle.jce.examples.PKCS12Example - the program expects only one * key to be present in the key file. *

    * Note: while this means that both the private key is available to * the program, the private key is retrieved from the keystore only for * the purposes of locating the corresponding public key, in normal circumstances * you would only be doing this with a certificate available. */ public class CreateLargeEncryptedMail { public static void main( String args[]) throws Exception { if (args.length != 3) { System.err.println("usage: CreateLargeEncryptedMail pkcs12Keystore password inputFile"); System.exit(0); } // // Open the key store // KeyStore ks = KeyStore.getInstance("PKCS12", "BC"); String keyAlias = ExampleUtils.findKeyAlias(ks, args[0], args[1].toCharArray()); Certificate[] chain = ks.getCertificateChain(keyAlias); // // create the generator for creating an smime/encrypted message // SMIMEEnvelopedGenerator gen = new SMIMEEnvelopedGenerator(); gen.addKeyTransRecipient((X509Certificate)chain[0]); // // create a subject key id - this has to be done the same way as // it is done in the certificate associated with the private key // version 3 only. // /* MessageDigest dig = MessageDigest.getInstance("SHA1", "BC"); dig.update(cert.getPublicKey().getEncoded()); gen.addKeyTransRecipient(cert.getPublicKey(), dig.digest()); */ // // create the base for our message // MimeBodyPart msg = new MimeBodyPart(); msg.setDataHandler(new DataHandler(new FileDataSource(new File(args[2])))); msg.setHeader("Content-Type", "application/octet-stream"); msg.setHeader("Content-Transfer-Encoding", "binary"); MimeBodyPart mp = gen.generate(msg, SMIMEEnvelopedGenerator.RC2_CBC, "BC"); // // Get a Session object and create the mail message // Properties props = System.getProperties(); Session session = Session.getDefaultInstance(props, null); Address fromUser = new InternetAddress("\"Eric H. Echidna\""); Address toUser = new InternetAddress("example@bouncycastle.org"); MimeMessage body = new MimeMessage(session); body.setFrom(fromUser); body.setRecipient(Message.RecipientType.TO, toUser); body.setSubject("example encrypted message"); body.setContent(mp.getContent(), mp.getContentType()); body.saveChanges(); body.writeTo(new FileOutputStream("encrypted.message")); } } bouncycastle-1.49.orig/src/org/bouncycastle/mail/smime/examples/CreateLargeCompressedMail.java0000644000175000017500000000375110323462470032234 0ustar ebourgebourgpackage org.bouncycastle.mail.smime.examples; import java.io.File; import java.io.FileOutputStream; import java.util.Properties; import javax.activation.DataHandler; import javax.activation.FileDataSource; import javax.mail.Address; import javax.mail.Message; import javax.mail.Session; import javax.mail.internet.InternetAddress; import javax.mail.internet.MimeBodyPart; import javax.mail.internet.MimeMessage; import org.bouncycastle.mail.smime.SMIMECompressedGenerator; /** * a simple example that creates a single compressed mail message using the large * file model. */ public class CreateLargeCompressedMail { public static void main( String args[]) throws Exception { // // create the generator for creating an smime/compressed message // SMIMECompressedGenerator gen = new SMIMECompressedGenerator(); // // create the base for our message // MimeBodyPart msg = new MimeBodyPart(); msg.setDataHandler(new DataHandler(new FileDataSource(new File(args[0])))); msg.setHeader("Content-Type", "application/octet-stream"); msg.setHeader("Content-Transfer-Encoding", "binary"); MimeBodyPart mp = gen.generate(msg, SMIMECompressedGenerator.ZLIB); // // Get a Session object and create the mail message // Properties props = System.getProperties(); Session session = Session.getDefaultInstance(props, null); Address fromUser = new InternetAddress("\"Eric H. Echidna\""); Address toUser = new InternetAddress("example@bouncycastle.org"); MimeMessage body = new MimeMessage(session); body.setFrom(fromUser); body.setRecipient(Message.RecipientType.TO, toUser); body.setSubject("example compressed message"); body.setContent(mp.getContent(), mp.getContentType()); body.saveChanges(); body.writeTo(new FileOutputStream("compressed.message")); } } bouncycastle-1.49.orig/src/org/bouncycastle/mail/smime/examples/ReadCompressedMail.java0000644000175000017500000000210610262753175030731 0ustar ebourgebourgpackage org.bouncycastle.mail.smime.examples; import java.io.FileInputStream; import java.util.Properties; import javax.mail.Session; import javax.mail.internet.MimeBodyPart; import javax.mail.internet.MimeMessage; import org.bouncycastle.mail.smime.SMIMECompressed; import org.bouncycastle.mail.smime.SMIMEUtil; /** * a simple example that reads a compressed email. *

    */ public class ReadCompressedMail { public static void main( String args[]) throws Exception { // // Get a Session object with the default properties. // Properties props = System.getProperties(); Session session = Session.getDefaultInstance(props, null); MimeMessage msg = new MimeMessage(session, new FileInputStream("compressed.message")); SMIMECompressed m = new SMIMECompressed(msg); MimeBodyPart res = SMIMEUtil.toMimeBodyPart(m.getContent()); System.out.println("Message Contents"); System.out.println("----------------"); System.out.println(res.getContent()); } } bouncycastle-1.49.orig/src/org/bouncycastle/mail/smime/examples/ReadEncryptedMail.java0000644000175000017500000000560111521700716030555 0ustar ebourgebourgpackage org.bouncycastle.mail.smime.examples; import java.io.FileInputStream; import java.security.KeyStore; import java.security.PrivateKey; import java.security.cert.X509Certificate; import java.util.Enumeration; import java.util.Properties; import javax.mail.Session; import javax.mail.internet.MimeBodyPart; import javax.mail.internet.MimeMessage; import org.bouncycastle.cms.RecipientId; import org.bouncycastle.cms.RecipientInformation; import org.bouncycastle.cms.RecipientInformationStore; import org.bouncycastle.cms.jcajce.JceKeyTransEnvelopedRecipient; import org.bouncycastle.cms.jcajce.JceKeyTransRecipientId; import org.bouncycastle.mail.smime.SMIMEEnveloped; import org.bouncycastle.mail.smime.SMIMEUtil; /** * a simple example that reads an encrypted email. *

    * The key store can be created using the class in * org.bouncycastle.jce.examples.PKCS12Example - the program expects only one * key to be present. */ public class ReadEncryptedMail { public static void main( String args[]) throws Exception { if (args.length != 2) { System.err.println("usage: ReadEncryptedMail pkcs12Keystore password"); System.exit(0); } // // Open the key store // KeyStore ks = KeyStore.getInstance("PKCS12", "BC"); ks.load(new FileInputStream(args[0]), args[1].toCharArray()); Enumeration e = ks.aliases(); String keyAlias = null; while (e.hasMoreElements()) { String alias = (String)e.nextElement(); if (ks.isKeyEntry(alias)) { keyAlias = alias; } } if (keyAlias == null) { System.err.println("can't find a private key!"); System.exit(0); } // // find the certificate for the private key and generate a // suitable recipient identifier. // X509Certificate cert = (X509Certificate)ks.getCertificate(keyAlias); RecipientId recId = new JceKeyTransRecipientId(cert); // // Get a Session object with the default properties. // Properties props = System.getProperties(); Session session = Session.getDefaultInstance(props, null); MimeMessage msg = new MimeMessage(session, new FileInputStream("encrypted.message")); SMIMEEnveloped m = new SMIMEEnveloped(msg); RecipientInformationStore recipients = m.getRecipientInfos(); RecipientInformation recipient = recipients.get(recId); MimeBodyPart res = SMIMEUtil.toMimeBodyPart(recipient.getContent(new JceKeyTransEnvelopedRecipient((PrivateKey)ks.getKey(keyAlias, null)).setProvider("BC"))); System.out.println("Message Contents"); System.out.println("----------------"); System.out.println(res.getContent()); } } bouncycastle-1.49.orig/src/org/bouncycastle/mail/smime/examples/CreateEncryptedMail.java0000644000175000017500000000717710262753175031127 0ustar ebourgebourgpackage org.bouncycastle.mail.smime.examples; import java.io.FileInputStream; import java.io.FileOutputStream; import java.security.KeyStore; import java.security.cert.Certificate; import java.security.cert.X509Certificate; import java.util.Enumeration; import java.util.Properties; import javax.mail.Address; import javax.mail.Message; import javax.mail.Session; import javax.mail.internet.InternetAddress; import javax.mail.internet.MimeBodyPart; import javax.mail.internet.MimeMessage; import org.bouncycastle.mail.smime.SMIMEEnvelopedGenerator; /** * a simple example that creates a single encrypted mail message. *

    * The key store can be created using the class in * org.bouncycastle.jce.examples.PKCS12Example - the program expects only one * key to be present in the key file. *

    * Note: while this means that both the private key is available to * the program, the private key is retrieved from the keystore only for * the purposes of locating the corresponding public key, in normal circumstances * you would only be doing this with a certificate available. */ public class CreateEncryptedMail { public static void main( String args[]) throws Exception { if (args.length != 2) { System.err.println("usage: CreateEncryptedMail pkcs12Keystore password"); System.exit(0); } // // Open the key store // KeyStore ks = KeyStore.getInstance("PKCS12", "BC"); ks.load(new FileInputStream(args[0]), args[1].toCharArray()); Enumeration e = ks.aliases(); String keyAlias = null; while (e.hasMoreElements()) { String alias = (String)e.nextElement(); if (ks.isKeyEntry(alias)) { keyAlias = alias; } } if (keyAlias == null) { System.err.println("can't find a private key!"); System.exit(0); } Certificate[] chain = ks.getCertificateChain(keyAlias); // // create the generator for creating an smime/encrypted message // SMIMEEnvelopedGenerator gen = new SMIMEEnvelopedGenerator(); gen.addKeyTransRecipient((X509Certificate)chain[0]); // // create a subject key id - this has to be done the same way as // it is done in the certificate associated with the private key // version 3 only. // /* MessageDigest dig = MessageDigest.getInstance("SHA1", "BC"); dig.update(cert.getPublicKey().getEncoded()); gen.addKeyTransRecipient(cert.getPublicKey(), dig.digest()); */ // // create the base for our message // MimeBodyPart msg = new MimeBodyPart(); msg.setText("Hello world!"); MimeBodyPart mp = gen.generate(msg, SMIMEEnvelopedGenerator.RC2_CBC, "BC"); // // Get a Session object and create the mail message // Properties props = System.getProperties(); Session session = Session.getDefaultInstance(props, null); Address fromUser = new InternetAddress("\"Eric H. Echidna\""); Address toUser = new InternetAddress("example@bouncycastle.org"); MimeMessage body = new MimeMessage(session); body.setFrom(fromUser); body.setRecipient(Message.RecipientType.TO, toUser); body.setSubject("example encrypted message"); body.setContent(mp.getContent(), mp.getContentType()); body.saveChanges(); body.writeTo(new FileOutputStream("encrypted.message")); } } bouncycastle-1.49.orig/src/org/bouncycastle/mail/smime/examples/ReadSignedMail.java0000644000175000017500000001237711526421165030044 0ustar ebourgebourgpackage org.bouncycastle.mail.smime.examples; import java.io.FileInputStream; import java.security.cert.X509Certificate; import java.util.Collection; import java.util.Iterator; import java.util.Properties; import javax.mail.BodyPart; import javax.mail.Multipart; import javax.mail.Session; import javax.mail.internet.MimeBodyPart; import javax.mail.internet.MimeMessage; import javax.mail.internet.MimeMultipart; import org.bouncycastle.cert.X509CertificateHolder; import org.bouncycastle.cert.jcajce.JcaX509CertificateConverter; import org.bouncycastle.cms.SignerInformation; import org.bouncycastle.cms.SignerInformationStore; import org.bouncycastle.cms.jcajce.JcaSimpleSignerInfoVerifierBuilder; import org.bouncycastle.jce.provider.BouncyCastleProvider; import org.bouncycastle.mail.smime.SMIMESigned; import org.bouncycastle.util.Store; /** * a simple example that reads a basic SMIME signed mail file. */ public class ReadSignedMail { private static final String BC = BouncyCastleProvider.PROVIDER_NAME; /** * verify the signature (assuming the cert is contained in the message) */ private static void verify( SMIMESigned s) throws Exception { // // extract the information to verify the signatures. // // // certificates and crls passed in the signature // Store certs = s.getCertificates(); // // SignerInfo blocks which contain the signatures // SignerInformationStore signers = s.getSignerInfos(); Collection c = signers.getSigners(); Iterator it = c.iterator(); // // check each signer // while (it.hasNext()) { SignerInformation signer = (SignerInformation)it.next(); Collection certCollection = certs.getMatches(signer.getSID()); Iterator certIt = certCollection.iterator(); X509Certificate cert = new JcaX509CertificateConverter().setProvider(BC).getCertificate((X509CertificateHolder)certIt.next()); // // verify that the sig is correct and that it was generated // when the certificate was current // if (signer.verify(new JcaSimpleSignerInfoVerifierBuilder().setProvider(BC).build(cert))) { System.out.println("signature verified"); } else { System.out.println("signature failed!"); } } } public static void main( String[] args) throws Exception { // // Get a Session object with the default properties. // Properties props = System.getProperties(); Session session = Session.getDefaultInstance(props, null); MimeMessage msg = new MimeMessage(session, new FileInputStream("signed.message")); // // make sure this was a multipart/signed message - there should be // two parts as we have one part for the content that was signed and // one part for the actual signature. // if (msg.isMimeType("multipart/signed")) { SMIMESigned s = new SMIMESigned( (MimeMultipart)msg.getContent()); // // extract the content // MimeBodyPart content = s.getContent(); System.out.println("Content:"); Object cont = content.getContent(); if (cont instanceof String) { System.out.println((String)cont); } else if (cont instanceof Multipart) { Multipart mp = (Multipart)cont; int count = mp.getCount(); for (int i = 0; i < count; i++) { BodyPart m = mp.getBodyPart(i); Object part = m.getContent(); System.out.println("Part " + i); System.out.println("---------------------------"); if (part instanceof String) { System.out.println((String)part); } else { System.out.println("can't print..."); } } } System.out.println("Status:"); verify(s); } else if (msg.isMimeType("application/pkcs7-mime") || msg.isMimeType("application/x-pkcs7-mime")) { // // in this case the content is wrapped in the signature block. // SMIMESigned s = new SMIMESigned(msg); // // extract the content // MimeBodyPart content = s.getContent(); System.out.println("Content:"); Object cont = content.getContent(); if (cont instanceof String) { System.out.println((String)cont); } System.out.println("Status:"); verify(s); } else { System.err.println("Not a signed message!"); } } } bouncycastle-1.49.orig/src/org/bouncycastle/mail/smime/examples/CreateSignedMultipartMail.java0000644000175000017500000001734011725030156032266 0ustar ebourgebourgpackage org.bouncycastle.mail.smime.examples; import java.io.FileOutputStream; import java.io.IOException; import java.math.BigInteger; import java.security.GeneralSecurityException; import java.security.KeyPair; import java.security.KeyPairGenerator; import java.security.PrivateKey; import java.security.PublicKey; import java.security.SecureRandom; import java.security.cert.X509Certificate; import java.util.ArrayList; import java.util.Date; import java.util.List; import java.util.Properties; import javax.mail.Address; import javax.mail.Message; import javax.mail.Session; import javax.mail.internet.InternetAddress; import javax.mail.internet.MimeBodyPart; import javax.mail.internet.MimeMessage; import javax.mail.internet.MimeMultipart; import org.bouncycastle.asn1.ASN1EncodableVector; import org.bouncycastle.asn1.cms.AttributeTable; import org.bouncycastle.asn1.cms.IssuerAndSerialNumber; import org.bouncycastle.asn1.smime.SMIMECapabilitiesAttribute; import org.bouncycastle.asn1.smime.SMIMECapability; import org.bouncycastle.asn1.smime.SMIMECapabilityVector; import org.bouncycastle.asn1.smime.SMIMEEncryptionKeyPreferenceAttribute; import org.bouncycastle.asn1.x500.X500Name; import org.bouncycastle.asn1.x509.X509Extension; import org.bouncycastle.cert.X509v3CertificateBuilder; import org.bouncycastle.cert.jcajce.JcaCertStore; import org.bouncycastle.cert.jcajce.JcaX509CertificateConverter; import org.bouncycastle.cert.jcajce.JcaX509ExtensionUtils; import org.bouncycastle.cert.jcajce.JcaX509v3CertificateBuilder; import org.bouncycastle.cms.jcajce.JcaSimpleSignerInfoGeneratorBuilder; import org.bouncycastle.mail.smime.SMIMESignedGenerator; import org.bouncycastle.operator.OperatorCreationException; import org.bouncycastle.operator.jcajce.JcaContentSignerBuilder; import org.bouncycastle.util.Store; /** * a simple example that creates a single signed multipart mail message. */ public class CreateSignedMultipartMail { // // certificate serial number seed. // static int serialNo = 1; /** * create a basic X509 certificate from the given keys */ static X509Certificate makeCertificate( KeyPair subKP, String subDN, KeyPair issKP, String issDN) throws GeneralSecurityException, IOException, OperatorCreationException { PublicKey subPub = subKP.getPublic(); PrivateKey issPriv = issKP.getPrivate(); PublicKey issPub = issKP.getPublic(); JcaX509ExtensionUtils extUtils = new JcaX509ExtensionUtils(); X509v3CertificateBuilder v3CertGen = new JcaX509v3CertificateBuilder(new X500Name(issDN), BigInteger.valueOf(serialNo++), new Date(System.currentTimeMillis()), new Date(System.currentTimeMillis() + (1000L * 60 * 60 * 24 * 100)), new X500Name(subDN), subPub); v3CertGen.addExtension( X509Extension.subjectKeyIdentifier, false, extUtils.createSubjectKeyIdentifier(subPub)); v3CertGen.addExtension( X509Extension.authorityKeyIdentifier, false, extUtils.createAuthorityKeyIdentifier(issPub)); return new JcaX509CertificateConverter().setProvider("BC").getCertificate(v3CertGen.build(new JcaContentSignerBuilder("MD5withRSA").setProvider("BC").build(issPriv))); } public static void main( String args[]) throws Exception { // // set up our certs // KeyPairGenerator kpg = KeyPairGenerator.getInstance("RSA", "BC"); kpg.initialize(1024, new SecureRandom()); // // cert that issued the signing certificate // String signDN = "O=Bouncy Castle, C=AU"; KeyPair signKP = kpg.generateKeyPair(); X509Certificate signCert = makeCertificate( signKP, signDN, signKP, signDN); // // cert we sign against // String origDN = "CN=Eric H. Echidna, E=eric@bouncycastle.org, O=Bouncy Castle, C=AU"; KeyPair origKP = kpg.generateKeyPair(); X509Certificate origCert = makeCertificate( origKP, origDN, signKP, signDN); List certList = new ArrayList(); certList.add(origCert); certList.add(signCert); // // create a CertStore containing the certificates we want carried // in the signature // Store certs = new JcaCertStore(certList); // // create some smime capabilities in case someone wants to respond // ASN1EncodableVector signedAttrs = new ASN1EncodableVector(); SMIMECapabilityVector caps = new SMIMECapabilityVector(); caps.addCapability(SMIMECapability.dES_EDE3_CBC); caps.addCapability(SMIMECapability.rC2_CBC, 128); caps.addCapability(SMIMECapability.dES_CBC); signedAttrs.add(new SMIMECapabilitiesAttribute(caps)); // // add an encryption key preference for encrypted responses - // normally this would be different from the signing certificate... // IssuerAndSerialNumber issAndSer = new IssuerAndSerialNumber( new X500Name(signDN), origCert.getSerialNumber()); signedAttrs.add(new SMIMEEncryptionKeyPreferenceAttribute(issAndSer)); // // create the generator for creating an smime/signed message // SMIMESignedGenerator gen = new SMIMESignedGenerator(); // // add a signer to the generator - this specifies we are using SHA1 and // adding the smime attributes above to the signed attributes that // will be generated as part of the signature. The encryption algorithm // used is taken from the key - in this RSA with PKCS1Padding // gen.addSignerInfoGenerator(new JcaSimpleSignerInfoGeneratorBuilder().setProvider("BC").setSignedAttributeGenerator(new AttributeTable(signedAttrs)).build("SHA1withRSA", origKP.getPrivate(), origCert)); // // add our pool of certs and cerls (if any) to go with the signature // gen.addCertificates(certs); // // create the base for our message // MimeBodyPart msg1 = new MimeBodyPart(); msg1.setText("Hello part 1!"); MimeBodyPart msg2 = new MimeBodyPart(); msg2.setText("Hello part 2!"); MimeMultipart mp = new MimeMultipart(); mp.addBodyPart(msg1); mp.addBodyPart(msg2); MimeBodyPart m = new MimeBodyPart(); // // be careful about setting extra headers here. Some mail clients // ignore the To and From fields (for example) in the body part // that contains the multipart. The result of this will be that the // signature fails to verify... Outlook Express is an example of // a client that exhibits this behaviour. // m.setContent(mp); // // extract the multipart object from the SMIMESigned object. // MimeMultipart mm = gen.generate(m); // // Get a Session object and create the mail message // Properties props = System.getProperties(); Session session = Session.getDefaultInstance(props, null); Address fromUser = new InternetAddress("\"Eric H. Echidna\""); Address toUser = new InternetAddress("example@bouncycastle.org"); MimeMessage body = new MimeMessage(session); body.setFrom(fromUser); body.setRecipient(Message.RecipientType.TO, toUser); body.setSubject("example signed message"); body.setContent(mm, mm.getContentType()); body.saveChanges(); body.writeTo(new FileOutputStream("signed.message")); } } bouncycastle-1.49.orig/src/org/bouncycastle/mail/smime/examples/package.html0000644000175000017500000000020010262753175026635 0ustar ebourgebourg Example code demonstrating the use of the S/MIME package for a variety of uses. bouncycastle-1.49.orig/src/org/bouncycastle/mail/smime/examples/CreateSignedMail.java0000644000175000017500000001770411521704201030361 0ustar ebourgebourgpackage org.bouncycastle.mail.smime.examples; import java.io.ByteArrayInputStream; import java.io.FileOutputStream; import java.io.IOException; import java.math.BigInteger; import java.security.GeneralSecurityException; import java.security.KeyPair; import java.security.KeyPairGenerator; import java.security.PrivateKey; import java.security.PublicKey; import java.security.SecureRandom; import java.security.cert.X509Certificate; import java.util.ArrayList; import java.util.Date; import java.util.List; import java.util.Properties; import javax.mail.Address; import javax.mail.Message; import javax.mail.Session; import javax.mail.internet.InternetAddress; import javax.mail.internet.MimeBodyPart; import javax.mail.internet.MimeMessage; import javax.mail.internet.MimeMultipart; import org.bouncycastle.asn1.ASN1EncodableVector; import org.bouncycastle.asn1.ASN1InputStream; import org.bouncycastle.asn1.ASN1Sequence; import org.bouncycastle.asn1.cms.AttributeTable; import org.bouncycastle.asn1.cms.IssuerAndSerialNumber; import org.bouncycastle.asn1.smime.SMIMECapabilitiesAttribute; import org.bouncycastle.asn1.smime.SMIMECapability; import org.bouncycastle.asn1.smime.SMIMECapabilityVector; import org.bouncycastle.asn1.smime.SMIMEEncryptionKeyPreferenceAttribute; import org.bouncycastle.asn1.x500.X500Name; import org.bouncycastle.asn1.x509.AuthorityKeyIdentifier; import org.bouncycastle.asn1.x509.SubjectKeyIdentifier; import org.bouncycastle.asn1.x509.SubjectPublicKeyInfo; import org.bouncycastle.asn1.x509.X509Extension; import org.bouncycastle.cert.X509v3CertificateBuilder; import org.bouncycastle.cert.jcajce.JcaCertStore; import org.bouncycastle.cert.jcajce.JcaX509CertificateConverter; import org.bouncycastle.cert.jcajce.JcaX509v3CertificateBuilder; import org.bouncycastle.cms.jcajce.JcaSimpleSignerInfoGeneratorBuilder; import org.bouncycastle.mail.smime.SMIMESignedGenerator; import org.bouncycastle.operator.OperatorCreationException; import org.bouncycastle.operator.jcajce.JcaContentSignerBuilder; import org.bouncycastle.util.Store; /** * a simple example that creates a single signed mail message. */ public class CreateSignedMail { // // certificate serial number seed. // static int serialNo = 1; static AuthorityKeyIdentifier createAuthorityKeyId( PublicKey pub) throws IOException { ByteArrayInputStream bIn = new ByteArrayInputStream(pub.getEncoded()); SubjectPublicKeyInfo info = new SubjectPublicKeyInfo( (ASN1Sequence)new ASN1InputStream(bIn).readObject()); return new AuthorityKeyIdentifier(info); } static SubjectKeyIdentifier createSubjectKeyId( PublicKey pub) throws IOException { ByteArrayInputStream bIn = new ByteArrayInputStream(pub.getEncoded()); SubjectPublicKeyInfo info = new SubjectPublicKeyInfo( (ASN1Sequence)new ASN1InputStream(bIn).readObject()); return new SubjectKeyIdentifier(info); } /** * create a basic X509 certificate from the given keys */ static X509Certificate makeCertificate( KeyPair subKP, String subDN, KeyPair issKP, String issDN) throws GeneralSecurityException, IOException, OperatorCreationException { PublicKey subPub = subKP.getPublic(); PrivateKey issPriv = issKP.getPrivate(); PublicKey issPub = issKP.getPublic(); X509v3CertificateBuilder v3CertGen = new JcaX509v3CertificateBuilder(new X500Name(issDN), BigInteger.valueOf(serialNo++), new Date(System.currentTimeMillis()), new Date(System.currentTimeMillis() + (1000L * 60 * 60 * 24 * 100)), new X500Name(subDN), subPub); v3CertGen.addExtension( X509Extension.subjectKeyIdentifier, false, createSubjectKeyId(subPub)); v3CertGen.addExtension( X509Extension.authorityKeyIdentifier, false, createAuthorityKeyId(issPub)); return new JcaX509CertificateConverter().setProvider("BC").getCertificate(v3CertGen.build(new JcaContentSignerBuilder("MD5withRSA").setProvider("BC").build(issPriv))); } public static void main( String args[]) throws Exception { // // set up our certs // KeyPairGenerator kpg = KeyPairGenerator.getInstance("RSA", "BC"); kpg.initialize(1024, new SecureRandom()); // // cert that issued the signing certificate // String signDN = "O=Bouncy Castle, C=AU"; KeyPair signKP = kpg.generateKeyPair(); X509Certificate signCert = makeCertificate( signKP, signDN, signKP, signDN); // // cert we sign against // String origDN = "CN=Eric H. Echidna, E=eric@bouncycastle.org, O=Bouncy Castle, C=AU"; KeyPair origKP = kpg.generateKeyPair(); X509Certificate origCert = makeCertificate( origKP, origDN, signKP, signDN); List certList = new ArrayList(); certList.add(origCert); certList.add(signCert); // // create a CertStore containing the certificates we want carried // in the signature // Store certs = new JcaCertStore(certList); // // create some smime capabilities in case someone wants to respond // ASN1EncodableVector signedAttrs = new ASN1EncodableVector(); SMIMECapabilityVector caps = new SMIMECapabilityVector(); caps.addCapability(SMIMECapability.dES_EDE3_CBC); caps.addCapability(SMIMECapability.rC2_CBC, 128); caps.addCapability(SMIMECapability.dES_CBC); signedAttrs.add(new SMIMECapabilitiesAttribute(caps)); // // add an encryption key preference for encrypted responses - // normally this would be different from the signing certificate... // IssuerAndSerialNumber issAndSer = new IssuerAndSerialNumber( new X500Name(signDN), origCert.getSerialNumber()); signedAttrs.add(new SMIMEEncryptionKeyPreferenceAttribute(issAndSer)); // // create the generator for creating an smime/signed message // SMIMESignedGenerator gen = new SMIMESignedGenerator(); // // add a signer to the generator - this specifies we are using SHA1 and // adding the smime attributes above to the signed attributes that // will be generated as part of the signature. The encryption algorithm // used is taken from the key - in this RSA with PKCS1Padding // gen.addSignerInfoGenerator(new JcaSimpleSignerInfoGeneratorBuilder().setProvider("BC").setSignedAttributeGenerator(new AttributeTable(signedAttrs)).build("SHA1withRSA", origKP.getPrivate(), origCert)); // // add our pool of certs and cerls (if any) to go with the signature // gen.addCertificates(certs); // // create the base for our message // MimeBodyPart msg = new MimeBodyPart(); msg.setText("Hello world!"); // // extract the multipart object from the SMIMESigned object. // MimeMultipart mm = gen.generate(msg); // // Get a Session object and create the mail message // Properties props = System.getProperties(); Session session = Session.getDefaultInstance(props, null); Address fromUser = new InternetAddress("\"Eric H. Echidna\""); Address toUser = new InternetAddress("example@bouncycastle.org"); MimeMessage body = new MimeMessage(session); body.setFrom(fromUser); body.setRecipient(Message.RecipientType.TO, toUser); body.setSubject("example signed message"); body.setContent(mm, mm.getContentType()); body.saveChanges(); body.writeTo(new FileOutputStream("signed.message")); } } bouncycastle-1.49.orig/src/org/bouncycastle/mail/smime/CMSProcessableBodyPartOutbound.java0000644000175000017500000000365711371415401031403 0ustar ebourgebourgpackage org.bouncycastle.mail.smime; import java.io.IOException; import java.io.OutputStream; import javax.mail.BodyPart; import javax.mail.MessagingException; import javax.mail.internet.MimeBodyPart; import org.bouncycastle.cms.CMSException; import org.bouncycastle.cms.CMSProcessable; import org.bouncycastle.mail.smime.util.CRLFOutputStream; /** * a holding class for a BodyPart to be processed which does CRLF canocicalisation if * dealing with non-binary data. */ public class CMSProcessableBodyPartOutbound implements CMSProcessable { private BodyPart bodyPart; private String defaultContentTransferEncoding; /** * Create a processable with the default transfer encoding of 7bit * * @param bodyPart body part to be processed */ public CMSProcessableBodyPartOutbound( BodyPart bodyPart) { this.bodyPart = bodyPart; } /** * Create a processable with the a default transfer encoding of * the passed in value. * * @param bodyPart body part to be processed * @param defaultContentTransferEncoding the new default to use. */ public CMSProcessableBodyPartOutbound( BodyPart bodyPart, String defaultContentTransferEncoding) { this.bodyPart = bodyPart; this.defaultContentTransferEncoding = defaultContentTransferEncoding; } public void write( OutputStream out) throws IOException, CMSException { try { if (SMIMEUtil.isCanonicalisationRequired((MimeBodyPart)bodyPart, defaultContentTransferEncoding)) { out = new CRLFOutputStream(out); } bodyPart.writeTo(out); } catch (MessagingException e) { throw new CMSException("can't write BodyPart to stream.", e); } } public Object getContent() { return bodyPart; } } bouncycastle-1.49.orig/src/org/bouncycastle/mail/smime/SMIMESignedParser.java0000644000175000017500000004257611562373525026611 0ustar ebourgebourgpackage org.bouncycastle.mail.smime; import java.io.BufferedInputStream; import java.io.BufferedOutputStream; import java.io.File; import java.io.FileInputStream; import java.io.FileNotFoundException; import java.io.FileOutputStream; import java.io.IOException; import java.io.InputStream; import java.io.OutputStream; import javax.activation.CommandMap; import javax.activation.MailcapCommandMap; import javax.mail.BodyPart; import javax.mail.MessagingException; import javax.mail.Part; import javax.mail.Session; import javax.mail.internet.MimeBodyPart; import javax.mail.internet.MimeMessage; import javax.mail.internet.MimeMultipart; import org.bouncycastle.cms.CMSException; import org.bouncycastle.cms.CMSSignedDataParser; import org.bouncycastle.cms.CMSTypedStream; import org.bouncycastle.operator.DigestCalculatorProvider; /** * general class for handling a pkcs7-signature message. *

    * A simple example of usage - note, in the example below the validity of * the certificate isn't verified, just the fact that one of the certs * matches the given signer... *

    *

     *  CertStore               certs = s.getCertificates("Collection", "BC");
     *  SignerInformationStore  signers = s.getSignerInfos();
     *  Collection              c = signers.getSigners();
     *  Iterator                it = c.iterator();
     *  
     *  while (it.hasNext())
     *  {
     *      SignerInformation   signer = (SignerInformation)it.next();
     *      Collection          certCollection = certs.getCertificates(signer.getSID());
     *  
     *      Iterator        certIt = certCollection.iterator();
     *      X509Certificate cert = (X509Certificate)certIt.next();
     *  
     *      if (signer.verify(cert.getPublicKey()))
     *      {
     *          verified++;
     *      }   
     *  }
     * 
    *

    * Note: if you are using this class with AS2 or some other protocol * that does not use 7bit as the default content transfer encoding you * will need to use the constructor that allows you to specify the default * content transfer encoding, such as "binary". *

    */ public class SMIMESignedParser extends CMSSignedDataParser { Object message; MimeBodyPart content; private static InputStream getInputStream( Part bodyPart) throws MessagingException { try { if (bodyPart.isMimeType("multipart/signed")) { throw new MessagingException("attempt to create signed data object from multipart content - use MimeMultipart constructor."); } return bodyPart.getInputStream(); } catch (IOException e) { throw new MessagingException("can't extract input stream: " + e); } } private static File getTmpFile() throws MessagingException { try { return File.createTempFile("bcMail", ".mime"); } catch (IOException e) { throw new MessagingException("can't extract input stream: " + e); } } private static CMSTypedStream getSignedInputStream( BodyPart bodyPart, String defaultContentTransferEncoding, File backingFile) throws MessagingException { try { OutputStream out = new BufferedOutputStream(new FileOutputStream(backingFile)); SMIMEUtil.outputBodyPart(out, bodyPart, defaultContentTransferEncoding); out.close(); InputStream in = new TemporaryFileInputStream(backingFile); return new CMSTypedStream(in); } catch (IOException e) { throw new MessagingException("can't extract input stream: " + e); } } static { MailcapCommandMap mc = (MailcapCommandMap)CommandMap.getDefaultCommandMap(); mc.addMailcap("application/pkcs7-signature;; x-java-content-handler=org.bouncycastle.mail.smime.handlers.pkcs7_signature"); mc.addMailcap("application/pkcs7-mime;; x-java-content-handler=org.bouncycastle.mail.smime.handlers.pkcs7_mime"); mc.addMailcap("application/x-pkcs7-signature;; x-java-content-handler=org.bouncycastle.mail.smime.handlers.x_pkcs7_signature"); mc.addMailcap("application/x-pkcs7-mime;; x-java-content-handler=org.bouncycastle.mail.smime.handlers.x_pkcs7_mime"); mc.addMailcap("multipart/signed;; x-java-content-handler=org.bouncycastle.mail.smime.handlers.multipart_signed"); CommandMap.setDefaultCommandMap(mc); } /** * base constructor using a defaultContentTransferEncoding of 7bit. A temporary backing file * will be created for the signed data. * * @param message signed message with signature. * @exception MessagingException on an error extracting the signature or * otherwise processing the message. * @exception CMSException if some other problem occurs. * @deprecated use method that takes a DigestCalculatorProvider */ public SMIMESignedParser( MimeMultipart message) throws MessagingException, CMSException { this(message, getTmpFile()); } /** * base constructor using a defaultContentTransferEncoding of 7bit and a specified backing file. * * @param message signed message with signature. * @param backingFile the temporary file to use to back the signed data. * @exception MessagingException on an error extracting the signature or * otherwise processing the message. * @exception CMSException if some other problem occurs. * @deprecated use method that takes a DigestCalculatorProvider */ public SMIMESignedParser( MimeMultipart message, File backingFile) throws MessagingException, CMSException { this(message, "7bit", backingFile); } /** * base constructor with settable contentTransferEncoding. A temporary backing file will be created * to contain the signed data. * * @param message the signed message with signature. * @param defaultContentTransferEncoding new default to use. * @exception MessagingException on an error extracting the signature or * otherwise processing the message. * @exception CMSException if some other problem occurs. * @deprecated use method that takes a DigestCalculatorProvider */ public SMIMESignedParser( MimeMultipart message, String defaultContentTransferEncoding) throws MessagingException, CMSException { this(message, defaultContentTransferEncoding, getTmpFile()); } /** * base constructor using a defaultContentTransferEncoding of 7bit. A temporary backing file * will be created for the signed data. * * @param digCalcProvider provider for digest calculators. * @param message signed message with signature. * @exception MessagingException on an error extracting the signature or * otherwise processing the message. * @exception CMSException if some other problem occurs. */ public SMIMESignedParser( DigestCalculatorProvider digCalcProvider, MimeMultipart message) throws MessagingException, CMSException { this(message, getTmpFile()); } /** * base constructor using a defaultContentTransferEncoding of 7bit and a specified backing file. * * @param digCalcProvider provider for digest calculators. * @param message signed message with signature. * @param backingFile the temporary file to use to back the signed data. * @exception MessagingException on an error extracting the signature or * otherwise processing the message. * @exception CMSException if some other problem occurs. */ public SMIMESignedParser( DigestCalculatorProvider digCalcProvider, MimeMultipart message, File backingFile) throws MessagingException, CMSException { this(message, "7bit", backingFile); } /** * base constructor with settable contentTransferEncoding. A temporary backing file will be created * to contain the signed data. * * @param digCalcProvider provider for digest calculators. * @param message the signed message with signature. * @param defaultContentTransferEncoding new default to use. * @exception MessagingException on an error extracting the signature or * otherwise processing the message. * @exception CMSException if some other problem occurs.r */ public SMIMESignedParser( DigestCalculatorProvider digCalcProvider, MimeMultipart message, String defaultContentTransferEncoding) throws MessagingException, CMSException { this(digCalcProvider, message, defaultContentTransferEncoding, getTmpFile()); } /** * base constructor with settable contentTransferEncoding and a specified backing file. * * @param message the signed message with signature. * @param defaultContentTransferEncoding new default to use. * @param backingFile the temporary file to use to back the signed data. * @exception MessagingException on an error extracting the signature or * otherwise processing the message. * @exception CMSException if some other problem occurs. * @deprecated use method that takes a DigestCalculatorProvider */ public SMIMESignedParser( MimeMultipart message, String defaultContentTransferEncoding, File backingFile) throws MessagingException, CMSException { super(getSignedInputStream(message.getBodyPart(0), defaultContentTransferEncoding, backingFile), getInputStream(message.getBodyPart(1))); this.message = message; this.content = (MimeBodyPart)message.getBodyPart(0); drainContent(); } /** * base constructor with settable contentTransferEncoding and a specified backing file. * * @param digCalcProvider provider for digest calculators. * @param message the signed message with signature. * @param defaultContentTransferEncoding new default to use. * @param backingFile the temporary file to use to back the signed data. * @exception MessagingException on an error extracting the signature or * otherwise processing the message. * @exception CMSException if some other problem occurs. */ public SMIMESignedParser( DigestCalculatorProvider digCalcProvider, MimeMultipart message, String defaultContentTransferEncoding, File backingFile) throws MessagingException, CMSException { super(digCalcProvider, getSignedInputStream(message.getBodyPart(0), defaultContentTransferEncoding, backingFile), getInputStream(message.getBodyPart(1))); this.message = message; this.content = (MimeBodyPart)message.getBodyPart(0); drainContent(); } /** * base constructor for a signed message with encapsulated content. *

    * Note: in this case the encapsulated MimeBody part will only be suitable for a single * writeTo - once writeTo has been called the file containing the body part will be deleted. If writeTo is not * called the file will be left in the temp directory. *

    * @param message the message containing the encapsulated signed data. * @exception MessagingException on an error extracting the signature or * otherwise processing the message. * @exception SMIMEException if the body part encapsulated in the message cannot be extracted. * @exception CMSException if some other problem occurs. * @deprecated use method that takes a DigestCalculatorProvider */ public SMIMESignedParser( Part message) throws MessagingException, CMSException, SMIMEException { super(getInputStream(message)); this.message = message; CMSTypedStream cont = this.getSignedContent(); if (cont != null) { this.content = SMIMEUtil.toWriteOnceBodyPart(cont); } } /** * base constructor for a signed message with encapsulated content. *

    * Note: in this case the encapsulated MimeBody part will only be suitable for a single * writeTo - once writeTo has been called the file containing the body part will be deleted. If writeTo is not * called the file will be left in the temp directory. *

    * @param digCalcProvider provider for digest calculators. * @param message the message containing the encapsulated signed data. * @exception MessagingException on an error extracting the signature or * otherwise processing the message. * @exception SMIMEException if the body part encapsulated in the message cannot be extracted. * @exception CMSException if some other problem occurs. */ public SMIMESignedParser( DigestCalculatorProvider digCalcProvider, Part message) throws MessagingException, CMSException, SMIMEException { super(digCalcProvider, getInputStream(message)); this.message = message; CMSTypedStream cont = this.getSignedContent(); if (cont != null) { this.content = SMIMEUtil.toWriteOnceBodyPart(cont); } } /** * Constructor for a signed message with encapsulated content. The encapsulated * content, if it exists, is written to the file represented by the File object * passed in. * * @param message the Part containing the signed content. * @param file the file the encapsulated part is to be written to after it has been decoded. * * @exception MessagingException on an error extracting the signature or * otherwise processing the message. * @exception SMIMEException if the body part encapsulated in the message cannot be extracted. * @exception CMSException if some other problem occurs. * @deprecated use method that takes a DigestCalculatorProvider */ public SMIMESignedParser( Part message, File file) throws MessagingException, CMSException, SMIMEException { super(getInputStream(message)); this.message = message; CMSTypedStream cont = this.getSignedContent(); if (cont != null) { this.content = SMIMEUtil.toMimeBodyPart(cont, file); } } /** * Constructor for a signed message with encapsulated content. The encapsulated * content, if it exists, is written to the file represented by the File object * passed in. * * @param digCalcProvider provider for digest calculators. * @param message the Part containing the signed content. * @param file the file the encapsulated part is to be written to after it has been decoded. * * @exception MessagingException on an error extracting the signature or * otherwise processing the message. * @exception SMIMEException if the body part encapsulated in the message cannot be extracted. * @exception CMSException if some other problem occurs. */ public SMIMESignedParser( DigestCalculatorProvider digCalcProvider, Part message, File file) throws MessagingException, CMSException, SMIMEException { super(digCalcProvider, getInputStream(message)); this.message = message; CMSTypedStream cont = this.getSignedContent(); if (cont != null) { this.content = SMIMEUtil.toMimeBodyPart(cont, file); } } /** * return the content that was signed. * @return the signed body part in this message. */ public MimeBodyPart getContent() { return content; } /** * Return the content that was signed as a mime message. * * @param session the session to base the MimeMessage around. * @return a MimeMessage holding the content. * @throws MessagingException if there is an issue creating the MimeMessage. * @throws IOException if there is an issue reading the content. */ public MimeMessage getContentAsMimeMessage(Session session) throws MessagingException, IOException { if (message instanceof MimeMultipart) { BodyPart bp = ((MimeMultipart)message).getBodyPart(0); return new MimeMessage(session, bp.getInputStream()); } else { return new MimeMessage(session, getSignedContent().getContentStream()); } } /** * return the content that was signed with its signature attached. * @return depending on whether this was unencapsulated or not it will return a MimeMultipart * or a MimeBodyPart */ public Object getContentWithSignature() { return message; } private void drainContent() throws CMSException { try { this.getSignedContent().drain(); } catch (IOException e) { throw new CMSException("unable to read content for verification: " + e, e); } } private static class TemporaryFileInputStream extends BufferedInputStream { private final File _file; TemporaryFileInputStream(File file) throws FileNotFoundException { super(new FileInputStream(file)); _file = file; } public void close() throws IOException { super.close(); _file.delete(); } } } bouncycastle-1.49.orig/src/org/bouncycastle/mail/smime/SMIMEException.java0000644000175000017500000000072010517771244026141 0ustar ebourgebourgpackage org.bouncycastle.mail.smime; public class SMIMEException extends Exception { Exception e; public SMIMEException( String name) { super(name); } public SMIMEException( String name, Exception e) { super(name); this.e = e; } public Exception getUnderlyingException() { return e; } public Throwable getCause() { return e; } } bouncycastle-1.49.orig/src/org/bouncycastle/mail/smime/CMSProcessableBodyPart.java0000644000175000017500000000157611371415401027661 0ustar ebourgebourgpackage org.bouncycastle.mail.smime; import java.io.IOException; import java.io.OutputStream; import javax.mail.BodyPart; import javax.mail.MessagingException; import org.bouncycastle.cms.CMSException; import org.bouncycastle.cms.CMSProcessable; /** * a holding class for a BodyPart to be processed. */ public class CMSProcessableBodyPart implements CMSProcessable { private BodyPart bodyPart; public CMSProcessableBodyPart( BodyPart bodyPart) { this.bodyPart = bodyPart; } public void write( OutputStream out) throws IOException, CMSException { try { bodyPart.writeTo(out); } catch (MessagingException e) { throw new CMSException("can't write BodyPart to stream.", e); } } public Object getContent() { return bodyPart; } } bouncycastle-1.49.orig/src/org/bouncycastle/mail/smime/SMIMEUtil.java0000644000175000017500000004121711251631401025110 0ustar ebourgebourgpackage org.bouncycastle.mail.smime; import java.io.ByteArrayInputStream; import java.io.File; import java.io.FilterOutputStream; import java.io.IOException; import java.io.InputStream; import java.io.OutputStream; import java.security.NoSuchProviderException; import java.security.Provider; import java.security.Security; import java.security.cert.CertificateParsingException; import java.security.cert.X509Certificate; import java.util.Enumeration; import javax.mail.BodyPart; import javax.mail.MessagingException; import javax.mail.internet.ContentType; import javax.mail.internet.MimeBodyPart; import javax.mail.internet.MimeMultipart; import org.bouncycastle.asn1.cms.IssuerAndSerialNumber; import org.bouncycastle.cms.CMSTypedStream; import org.bouncycastle.jce.PrincipalUtil; import org.bouncycastle.mail.smime.util.CRLFOutputStream; import org.bouncycastle.mail.smime.util.FileBackedMimeBodyPart; public class SMIMEUtil { private static final int BUF_SIZE = 32760; static boolean isCanonicalisationRequired( MimeBodyPart bodyPart, String defaultContentTransferEncoding) throws MessagingException { String[] cte = bodyPart.getHeader("Content-Transfer-Encoding"); String contentTransferEncoding; if (cte == null) { contentTransferEncoding = defaultContentTransferEncoding; } else { contentTransferEncoding = cte[0]; } return !contentTransferEncoding.equalsIgnoreCase("binary"); } public static Provider getProvider(String providerName) throws NoSuchProviderException { if (providerName != null) { Provider prov = Security.getProvider(providerName); if (prov != null) { return prov; } throw new NoSuchProviderException("provider " + providerName + " not found."); } return null; } static class LineOutputStream extends FilterOutputStream { private static byte newline[]; public LineOutputStream(OutputStream outputstream) { super(outputstream); } public void writeln(String s) throws MessagingException { try { byte abyte0[] = getBytes(s); super.out.write(abyte0); super.out.write(newline); } catch(Exception exception) { throw new MessagingException("IOException", exception); } } public void writeln() throws MessagingException { try { super.out.write(newline); } catch(Exception exception) { throw new MessagingException("IOException", exception); } } static { newline = new byte[2]; newline[0] = 13; newline[1] = 10; } private static byte[] getBytes(String s) { char ac[] = s.toCharArray(); int i = ac.length; byte abyte0[] = new byte[i]; int j = 0; while (j < i) { abyte0[j] = (byte)ac[j++]; } return abyte0; } } /** * internal preamble is generally included in signatures, while this is technically wrong, * if we find internal preamble we include it by default. */ static void outputPreamble(LineOutputStream lOut, MimeBodyPart part, String boundary) throws MessagingException, IOException { InputStream in; try { in = part.getRawInputStream(); } catch (MessagingException e) { return; // no underlying content rely on default generation } String line; while ((line = readLine(in)) != null) { if (line.equals(boundary)) { break; } lOut.writeln(line); } in.close(); if (line == null) { throw new MessagingException("no boundary found"); } } /** * internal postamble is generally included in signatures, while this is technically wrong, * if we find internal postamble we include it by default. */ static void outputPostamble(LineOutputStream lOut, MimeBodyPart part, int count, String boundary) throws MessagingException, IOException { InputStream in; try { in = part.getRawInputStream(); } catch (MessagingException e) { return; // no underlying content rely on default generation } String line; int boundaries = count + 1; while ((line = readLine(in)) != null) { if (line.startsWith(boundary)) { boundaries--; if (boundaries == 0) { break; } } } while ((line = readLine(in)) != null) { lOut.writeln(line); } in.close(); if (boundaries != 0) { throw new MessagingException("all boundaries not found for: " + boundary); } } static void outputPostamble(LineOutputStream lOut, BodyPart parent, String parentBoundary, BodyPart part) throws MessagingException, IOException { InputStream in; try { in = ((MimeBodyPart)parent).getRawInputStream(); } catch (MessagingException e) { return; // no underlying content rely on default generation } MimeMultipart multipart = (MimeMultipart)part.getContent(); ContentType contentType = new ContentType(multipart.getContentType()); String boundary = "--" + contentType.getParameter("boundary"); int count = multipart.getCount() + 1; String line; while (count != 0 && (line = readLine(in)) != null) { if (line.startsWith(boundary)) { count--; } } while ((line = readLine(in)) != null) { if (line.startsWith(parentBoundary)) { break; } lOut.writeln(line); } in.close(); } /* * read a line of input stripping of the tailing \r\n */ private static String readLine(InputStream in) throws IOException { StringBuffer b = new StringBuffer(); int ch; while ((ch = in.read()) >= 0 && ch != '\n') { if (ch != '\r') { b.append((char)ch); } } if (ch < 0 && b.length() == 0) { return null; } return b.toString(); } static void outputBodyPart( OutputStream out, BodyPart bodyPart, String defaultContentTransferEncoding) throws MessagingException, IOException { if (bodyPart instanceof MimeBodyPart) { MimeBodyPart mimePart = (MimeBodyPart)bodyPart; String[] cte = mimePart.getHeader("Content-Transfer-Encoding"); String contentTransferEncoding; if (mimePart.getContent() instanceof MimeMultipart) { MimeMultipart mp = (MimeMultipart)bodyPart.getContent(); ContentType contentType = new ContentType(mp.getContentType()); String boundary = "--" + contentType.getParameter("boundary"); SMIMEUtil.LineOutputStream lOut = new SMIMEUtil.LineOutputStream(out); Enumeration headers = mimePart.getAllHeaderLines(); while (headers.hasMoreElements()) { String header = (String)headers.nextElement(); lOut.writeln(header); } lOut.writeln(); // CRLF separator outputPreamble(lOut, mimePart, boundary); for (int i = 0; i < mp.getCount(); i++) { lOut.writeln(boundary); BodyPart part = mp.getBodyPart(i); outputBodyPart(out, part, defaultContentTransferEncoding); if (!(part.getContent() instanceof MimeMultipart)) { lOut.writeln(); // CRLF terminator needed } else { outputPostamble(lOut, mimePart, boundary, part); } } lOut.writeln(boundary + "--"); outputPostamble(lOut, mimePart, mp.getCount(), boundary); return; } if (cte == null) { contentTransferEncoding = defaultContentTransferEncoding; } else { contentTransferEncoding = cte[0]; } if (!contentTransferEncoding.equalsIgnoreCase("base64") && !contentTransferEncoding.equalsIgnoreCase("quoted-printable")) { if (!contentTransferEncoding.equalsIgnoreCase("binary")) { out = new CRLFOutputStream(out); } bodyPart.writeTo(out); out.flush(); return; } boolean base64 = contentTransferEncoding.equalsIgnoreCase("base64"); // // Write raw content, performing canonicalization // InputStream inRaw; try { inRaw = mimePart.getRawInputStream(); } catch (MessagingException e) { // this is less than ideal, but if the raw output stream is unavailable it's the // best option we've got. out = new CRLFOutputStream(out); bodyPart.writeTo(out); out.flush(); return; } // // Write headers // LineOutputStream outLine = new LineOutputStream(out); for (Enumeration e = mimePart.getAllHeaderLines(); e.hasMoreElements();) { String header = (String)e.nextElement(); outLine.writeln(header); } outLine.writeln(); outLine.flush(); OutputStream outCRLF; if (base64) { outCRLF = new Base64CRLFOutputStream(out); } else { outCRLF = new CRLFOutputStream(out); } byte[] buf = new byte[BUF_SIZE]; int len; while ((len = inRaw.read(buf, 0, buf.length)) > 0) { outCRLF.write(buf, 0, len); } outCRLF.flush(); } else { if (!defaultContentTransferEncoding.equalsIgnoreCase("binary")) { out = new CRLFOutputStream(out); } bodyPart.writeTo(out); out.flush(); } } /** * return the MimeBodyPart described in the raw bytes provided in content */ public static MimeBodyPart toMimeBodyPart( byte[] content) throws SMIMEException { return toMimeBodyPart(new ByteArrayInputStream(content)); } /** * return the MimeBodyPart described in the input stream content */ public static MimeBodyPart toMimeBodyPart( InputStream content) throws SMIMEException { try { return new MimeBodyPart(content); } catch (MessagingException e) { throw new SMIMEException("exception creating body part.", e); } } static FileBackedMimeBodyPart toWriteOnceBodyPart( CMSTypedStream content) throws SMIMEException { try { return new WriteOnceFileBackedMimeBodyPart(content.getContentStream(), File.createTempFile("bcMail", ".mime")); } catch (IOException e) { throw new SMIMEException("IOException creating tmp file:" + e.getMessage(), e); } catch (MessagingException e) { throw new SMIMEException("can't create part: " + e, e); } } /** * return a file backed MimeBodyPart described in {@link CMSTypedStream} content. *

    */ public static FileBackedMimeBodyPart toMimeBodyPart( CMSTypedStream content) throws SMIMEException { try { return toMimeBodyPart(content, File.createTempFile("bcMail", ".mime")); } catch (IOException e) { throw new SMIMEException("IOException creating tmp file:" + e.getMessage(), e); } } /** * Return a file based MimeBodyPart represented by content and backed * by the file represented by file. * * @param content content stream containing body part. * @param file file to store the decoded body part in. * @return the decoded body part. * @throws SMIMEException */ public static FileBackedMimeBodyPart toMimeBodyPart( CMSTypedStream content, File file) throws SMIMEException { try { return new FileBackedMimeBodyPart(content.getContentStream(), file); } catch (IOException e) { throw new SMIMEException("can't save content to file: " + e, e); } catch (MessagingException e) { throw new SMIMEException("can't create part: " + e, e); } } /** * Return a CMS IssuerAndSerialNumber structure for the passed in X.509 certificate. * * @param cert the X.509 certificate to get the issuer and serial number for. * @return an IssuerAndSerialNumber structure representing the certificate. */ public static IssuerAndSerialNumber createIssuerAndSerialNumberFor( X509Certificate cert) throws CertificateParsingException { try { return new IssuerAndSerialNumber(PrincipalUtil.getIssuerX509Principal(cert), cert.getSerialNumber()); } catch (Exception e) { throw new CertificateParsingException("exception extracting issuer and serial number: " + e); } } private static class WriteOnceFileBackedMimeBodyPart extends FileBackedMimeBodyPart { public WriteOnceFileBackedMimeBodyPart(InputStream content, File file) throws MessagingException, IOException { super(content, file); } public void writeTo(OutputStream out) throws MessagingException, IOException { super.writeTo(out); this.dispose(); } } static class Base64CRLFOutputStream extends FilterOutputStream { protected int lastb; protected static byte newline[]; private boolean isCrlfStream; public Base64CRLFOutputStream(OutputStream outputstream) { super(outputstream); lastb = -1; } public void write(int i) throws IOException { if (i == '\r') { out.write(newline); } else if (i == '\n') { if (lastb != '\r') { // imagine my joy... if (!(isCrlfStream && lastb == '\n')) { out.write(newline); } } else { isCrlfStream = true; } } else { out.write(i); } lastb = i; } public void write(byte[] buf) throws IOException { this.write(buf, 0, buf.length); } public void write(byte buf[], int off, int len) throws IOException { for (int i = off; i != off + len; i++) { this.write(buf[i]); } } public void writeln() throws IOException { super.out.write(newline); } static { newline = new byte[2]; newline[0] = '\r'; newline[1] = '\n'; } } } bouncycastle-1.49.orig/src/org/bouncycastle/mail/smime/package.html0000644000175000017500000000074410262753175025034 0ustar ebourgebourg High level classes for dealing with S/MIME objects (RFC 3851).

    There is one thing that is worth commenting about with these. If you're using AS2 on some other standard which specifies a different default content transfer encoding from RFC 2405, make sure you use the constructors on SMIMESigned and SMIMESignedGenerator that allow you to set the default ("binary" in the case of AS2 as opposed to "bit7" which is the default).

    bouncycastle-1.49.orig/src/org/bouncycastle/mail/smime/CMSProcessableBodyPartInbound.java0000644000175000017500000000330311371415401031166 0ustar ebourgebourgpackage org.bouncycastle.mail.smime; import java.io.IOException; import java.io.OutputStream; import javax.mail.BodyPart; import javax.mail.MessagingException; import org.bouncycastle.cms.CMSException; import org.bouncycastle.cms.CMSProcessable; /** * a holding class for a BodyPart to be processed which does CRLF canonicalisation if * dealing with non-binary data. */ public class CMSProcessableBodyPartInbound implements CMSProcessable { private final BodyPart bodyPart; private final String defaultContentTransferEncoding; /** * Create a processable with the default transfer encoding of 7bit * * @param bodyPart body part to be processed */ public CMSProcessableBodyPartInbound( BodyPart bodyPart) { this(bodyPart, "7bit"); } /** * Create a processable with the a default transfer encoding of * the passed in value. * * @param bodyPart body part to be processed * @param defaultContentTransferEncoding the new default to use. */ public CMSProcessableBodyPartInbound( BodyPart bodyPart, String defaultContentTransferEncoding) { this.bodyPart = bodyPart; this.defaultContentTransferEncoding = defaultContentTransferEncoding; } public void write( OutputStream out) throws IOException, CMSException { try { SMIMEUtil.outputBodyPart(out, bodyPart, defaultContentTransferEncoding); } catch (MessagingException e) { throw new CMSException("can't write BodyPart to stream: " + e, e); } } public Object getContent() { return bodyPart; } } bouncycastle-1.49.orig/src/org/bouncycastle/i18n/0000755000175000017500000000000012152033551021256 5ustar ebourgebourgbouncycastle-1.49.orig/src/org/bouncycastle/i18n/LocaleString.java0000644000175000017500000000105410621263377024521 0ustar ebourgebourgpackage org.bouncycastle.i18n; import java.io.UnsupportedEncodingException; import java.util.Locale; public class LocaleString extends LocalizedMessage { public LocaleString(String resource, String id) { super(resource, id); } public LocaleString(String resource, String id, String encoding) throws NullPointerException, UnsupportedEncodingException { super(resource, id, encoding); } public String getLocaleString(Locale locale) { return this.getEntry(null, locale, null); } } bouncycastle-1.49.orig/src/org/bouncycastle/i18n/TextBundle.java0000644000175000017500000000741110574123661024212 0ustar ebourgebourgpackage org.bouncycastle.i18n; import java.io.UnsupportedEncodingException; import java.util.Locale; import java.util.TimeZone; public class TextBundle extends LocalizedMessage { /** * text entry key */ public static final String TEXT_ENTRY = "text"; /** * Constructs a new TextBundle using resource as the base name for the * RessourceBundle and id as the message bundle id the resource file. * @param resource base name of the resource file * @param id the id of the corresponding bundle in the resource file * @throws NullPointerException if resource or id is null */ public TextBundle(String resource, String id) throws NullPointerException { super(resource, id); } /** * Constructs a new TextBundle using resource as the base name for the * RessourceBundle and id as the message bundle id the resource file. * @param resource base name of the resource file * @param id the id of the corresponding bundle in the resource file * @param encoding the encoding of the resource file * @throws NullPointerException if resource or id is null * @throws UnsupportedEncodingException if the encoding is not supported */ public TextBundle(String resource, String id, String encoding) throws NullPointerException, UnsupportedEncodingException { super(resource, id, encoding); } /** * Constructs a new TextBundle using resource as the base name for the * RessourceBundle and id as the message bundle id the resource file. * @param resource base name of the resource file * @param id the id of the corresponding bundle in the resource file * @param arguments an array containing the arguments for the message * @throws NullPointerException if resource or id is null */ public TextBundle(String resource, String id, Object[] arguments) throws NullPointerException { super(resource, id, arguments); } /** * Constructs a new TextBundle using resource as the base name for the * RessourceBundle and id as the message bundle id the resource file. * @param resource base name of the resource file * @param id the id of the corresponding bundle in the resource file * @param encoding the encoding of the resource file * @param arguments an array containing the arguments for the message * @throws NullPointerException if resource or id is null * @throws UnsupportedEncodingException if the encoding is not supported */ public TextBundle(String resource, String id, String encoding, Object[] arguments) throws NullPointerException, UnsupportedEncodingException { super(resource, id, encoding, arguments); } /** * Returns the text message in the given locale and timezone. * @param loc the {@link Locale} * @param timezone the {@link TimeZone} * @return the text message. * @throws MissingEntryException if the message is not available */ public String getText(Locale loc, TimeZone timezone) throws MissingEntryException { return getEntry(TEXT_ENTRY,loc,timezone); } /** * Returns the text message in the given locale and the defaut timezone. * @param loc the {@link Locale} * @return the text message. * @throws MissingEntryException if the message is not available */ public String getText(Locale loc) throws MissingEntryException { return getEntry(TEXT_ENTRY,loc,TimeZone.getDefault()); } } bouncycastle-1.49.orig/src/org/bouncycastle/i18n/ErrorBundle.java0000644000175000017500000001130110574123661024350 0ustar ebourgebourgpackage org.bouncycastle.i18n; import java.io.UnsupportedEncodingException; import java.util.Locale; import java.util.TimeZone; public class ErrorBundle extends MessageBundle { /** * summary entry key */ public static final String SUMMARY_ENTRY = "summary"; /** * detail entry key */ public static final String DETAIL_ENTRY = "details"; /** * Constructs a new ErrorBundle using resource as the base name for the * RessourceBundle and id as the message bundle id the resource file. * @param resource base name of the resource file * @param id the id of the corresponding bundle in the resource file * @throws NullPointerException if resource or id is null */ public ErrorBundle(String resource, String id) throws NullPointerException { super(resource, id); } /** * Constructs a new ErrorBundle using resource as the base name for the * RessourceBundle and id as the message bundle id the resource file. * @param resource base name of the resource file * @param id the id of the corresponding bundle in the resource file * @param encoding the encoding of the resource file * @throws NullPointerException if resource or id is null * @throws UnsupportedEncodingException if the encoding is not supported */ public ErrorBundle(String resource, String id, String encoding) throws NullPointerException, UnsupportedEncodingException { super(resource, id, encoding); } /** * Constructs a new ErrorBundle using resource as the base name for the * RessourceBundle and id as the message bundle id the resource file. * @param resource base name of the resource file * @param id the id of the corresponding bundle in the resource file * @param arguments an array containing the arguments for the message * @throws NullPointerException if resource or id is null */ public ErrorBundle(String resource, String id, Object[] arguments) throws NullPointerException { super(resource, id, arguments); } /** * Constructs a new ErrorBundle using resource as the base name for the * RessourceBundle and id as the message bundle id the resource file. * @param resource base name of the resource file * @param id the id of the corresponding bundle in the resource file * @param encoding the encoding of the resource file * @param arguments an array containing the arguments for the message * @throws NullPointerException if resource or id is null * @throws UnsupportedEncodingException if the encoding is not supported */ public ErrorBundle(String resource, String id, String encoding, Object[] arguments) throws NullPointerException, UnsupportedEncodingException { super(resource, id, encoding, arguments); } /** * Returns the summary message in the given locale and timezone. * @param loc the {@link Locale} * @param timezone the {@link TimeZone} * @return the summary message. * @throws MissingEntryException if the message is not available */ public String getSummary(Locale loc, TimeZone timezone) throws MissingEntryException { return getEntry(SUMMARY_ENTRY,loc,timezone); } /** * Returns the summary message in the given locale and the default timezone. * @param loc the {@link Locale} * @return the summary message. * @throws MissingEntryException if the message is not available */ public String getSummary(Locale loc) throws MissingEntryException { return getEntry(SUMMARY_ENTRY,loc,TimeZone.getDefault()); } /** * Returns the detail message in the given locale and timezone. * @param loc the {@link Locale} * @param timezone the {@link TimeZone} * @return the detail message. * @throws MissingEntryException if the message is not available */ public String getDetail(Locale loc, TimeZone timezone) throws MissingEntryException { return getEntry(DETAIL_ENTRY,loc,timezone); } /** * Returns the detail message in the given locale and the default timezone. * @param loc the {@link Locale} * @return the detail message. * @throws MissingEntryException if the message is not available */ public String getDetail(Locale loc) throws MissingEntryException { return getEntry(DETAIL_ENTRY,loc,TimeZone.getDefault()); } } bouncycastle-1.49.orig/src/org/bouncycastle/i18n/MessageBundle.java0000644000175000017500000000744410574123661024660 0ustar ebourgebourgpackage org.bouncycastle.i18n; import java.io.UnsupportedEncodingException; import java.util.Locale; import java.util.TimeZone; public class MessageBundle extends TextBundle { /** * title entry key */ public static final String TITLE_ENTRY = "title"; /** * Constructs a new MessageBundle using resource as the base name for the * RessourceBundle and id as the message bundle id the resource file. * @param resource base name of the resource file * @param id the id of the corresponding bundle in the resource file * @throws NullPointerException if resource or id is null */ public MessageBundle(String resource, String id) throws NullPointerException { super(resource, id); } /** * Constructs a new MessageBundle using resource as the base name for the * RessourceBundle and id as the message bundle id the resource file. * @param resource base name of the resource file * @param id the id of the corresponding bundle in the resource file * @param encoding the encoding of the resource file * @throws NullPointerException if resource or id is null * @throws UnsupportedEncodingException if the encoding is not supported */ public MessageBundle(String resource, String id, String encoding) throws NullPointerException, UnsupportedEncodingException { super(resource, id, encoding); } /** * Constructs a new MessageBundle using resource as the base name for the * RessourceBundle and id as the message bundle id the resource file. * @param resource base name of the resource file * @param id the id of the corresponding bundle in the resource file * @param arguments an array containing the arguments for the message * @throws NullPointerException if resource or id is null */ public MessageBundle(String resource, String id, Object[] arguments) throws NullPointerException { super(resource, id, arguments); } /** * Constructs a new MessageBundle using resource as the base name for the * RessourceBundle and id as the message bundle id the resource file. * @param resource base name of the resource file * @param id the id of the corresponding bundle in the resource file * @param encoding the encoding of the resource file * @param arguments an array containing the arguments for the message * @throws NullPointerException if resource or id is null * @throws UnsupportedEncodingException if the encoding is not supported */ public MessageBundle(String resource, String id, String encoding, Object[] arguments) throws NullPointerException, UnsupportedEncodingException { super(resource, id, encoding, arguments); } /** * Returns the title message in the given locale and timezone. * @param loc the {@link Locale} * @param timezone the {@link TimeZone} * @return the title message. * @throws MissingEntryException if the message is not available */ public String getTitle(Locale loc,TimeZone timezone) throws MissingEntryException { return getEntry(TITLE_ENTRY,loc,timezone); } /** * Returns the title message in the given locale and the default timezone. * @param loc the {@link Locale} * @return the title message. * @throws MissingEntryException if the message is not available */ public String getTitle(Locale loc) throws MissingEntryException { return getEntry(TITLE_ENTRY,loc,TimeZone.getDefault()); } } bouncycastle-1.49.orig/src/org/bouncycastle/i18n/filter/0000755000175000017500000000000012152033551022543 5ustar ebourgebourgbouncycastle-1.49.orig/src/org/bouncycastle/i18n/filter/SQLFilter.java0000644000175000017500000000311710617010306025212 0ustar ebourgebourg package org.bouncycastle.i18n.filter; /** * Filter for strings to store in a SQL table. * * escapes ' " = - / \ ; \r \n */ public class SQLFilter implements Filter { public String doFilter(String input) { StringBuffer buf = new StringBuffer(input); int i = 0; while (i < buf.length()) { char ch = buf.charAt(i); switch (ch) { case '\'': buf.replace(i,i+1,"\\\'"); i += 1; break; case '\"': buf.replace(i,i+1,"\\\""); i += 1; break; case '=': buf.replace(i,i+1,"\\="); i += 1; break; case '-': buf.replace(i,i+1,"\\-"); i += 1; break; case '/': buf.replace(i,i+1,"\\/"); i += 1; break; case '\\': buf.replace(i,i+1,"\\\\"); i += 1; break; case ';': buf.replace(i,i+1,"\\;"); i += 1; break; case '\r': buf.replace(i,i+1,"\\r"); i += 1; break; case '\n': buf.replace(i,i+1,"\\n"); i += 1; break; default: } i++; } return buf.toString(); } public String doFilterUrl(String input) { return doFilter(input); } } bouncycastle-1.49.orig/src/org/bouncycastle/i18n/filter/UntrustedUrlInput.java0000644000175000017500000000034510617024020027103 0ustar ebourgebourgpackage org.bouncycastle.i18n.filter; /** * * Wrapper class to mark an untrusted Url */ public class UntrustedUrlInput extends UntrustedInput { public UntrustedUrlInput(Object url) { super(url); } } bouncycastle-1.49.orig/src/org/bouncycastle/i18n/filter/UntrustedInput.java0000644000175000017500000000143710500003704026420 0ustar ebourgebourg package org.bouncycastle.i18n.filter; /** * Wrapper class to mark untrusted input. */ public class UntrustedInput { protected Object input; /** * Construct a new UntrustedInput instance. * @param input the untrusted input Object */ public UntrustedInput(Object input) { this.input = input; } /** * Returns the untrusted input as Object. * @return the input as Object */ public Object getInput() { return input; } /** * Returns the untrusted input convertet to a String. * @return the input as String */ public String getString() { return input.toString(); } public String toString() { return input.toString(); } } bouncycastle-1.49.orig/src/org/bouncycastle/i18n/filter/TrustedInput.java0000644000175000017500000000051610617024020026055 0ustar ebourgebourgpackage org.bouncycastle.i18n.filter; public class TrustedInput { protected Object input; public TrustedInput(Object input) { this.input = input; } public Object getInput() { return input; } public String toString() { return input.toString(); } } bouncycastle-1.49.orig/src/org/bouncycastle/i18n/filter/HTMLFilter.java0000644000175000017500000000313310617010306025315 0ustar ebourgebourg package org.bouncycastle.i18n.filter; /** * HTML Filter */ public class HTMLFilter implements Filter { public String doFilter(String input) { StringBuffer buf = new StringBuffer(input); int i = 0; while (i < buf.length()) { char ch = buf.charAt(i); switch (ch) { case '<': buf.replace(i,i+1,"<"); break; case '>': buf.replace(i,i+1,">"); break; case '(': buf.replace(i,i+1,"("); break; case ')': buf.replace(i,i+1,")"); break; case '#': buf.replace(i,i+1,"#"); break; case '&': buf.replace(i,i+1,"&"); break; case '\"': buf.replace(i,i+1,"""); break; case '\'': buf.replace(i,i+1,"'"); break; case '%': buf.replace(i,i+1,"%"); break; case ';': buf.replace(i,i+1,";"); break; case '+': buf.replace(i,i+1,"+"); break; case '-': buf.replace(i,i+1,"-"); break; default: i -= 3; } i += 4; } return buf.toString(); } public String doFilterUrl(String input) { return doFilter(input); } } bouncycastle-1.49.orig/src/org/bouncycastle/i18n/filter/Filter.java0000644000175000017500000000073110617010306024631 0ustar ebourgebourg package org.bouncycastle.i18n.filter; public interface Filter { /** * Runs the filter on the input String and returns the filtered String * @param input input String * @return filtered String */ public String doFilter(String input); /** * Runs the filter on the input url and returns the filtered String * @param input input url String * @return filtered String */ public String doFilterUrl(String input); } bouncycastle-1.49.orig/src/org/bouncycastle/i18n/LocalizedMessage.java0000644000175000017500000003606210735362242025352 0ustar ebourgebourgpackage org.bouncycastle.i18n; import org.bouncycastle.i18n.filter.Filter; import org.bouncycastle.i18n.filter.TrustedInput; import org.bouncycastle.i18n.filter.UntrustedInput; import org.bouncycastle.i18n.filter.UntrustedUrlInput; import java.io.UnsupportedEncodingException; import java.nio.charset.Charset; import java.text.DateFormat; import java.text.Format; import java.text.MessageFormat; import java.util.Locale; import java.util.MissingResourceException; import java.util.ResourceBundle; import java.util.TimeZone; public class LocalizedMessage { protected final String id; protected final String resource; // ISO-8859-1 is the default encoding public static final String DEFAULT_ENCODING = "ISO-8859-1"; protected String encoding = DEFAULT_ENCODING; protected FilteredArguments arguments; protected FilteredArguments extraArgs = null; protected Filter filter = null; protected ClassLoader loader = null; /** * Constructs a new LocalizedMessage using resource as the base name for the * RessourceBundle and id as the message bundle id the resource file. * @param resource base name of the resource file * @param id the id of the corresponding bundle in the resource file * @throws NullPointerException if resource or id is null */ public LocalizedMessage(String resource,String id) throws NullPointerException { if (resource == null || id == null) { throw new NullPointerException(); } this.id = id; this.resource = resource; arguments = new FilteredArguments(); } /** * Constructs a new LocalizedMessage using resource as the base name for the * RessourceBundle and id as the message bundle id the resource file. * @param resource base name of the resource file * @param id the id of the corresponding bundle in the resource file * @param encoding the encoding of the resource file * @throws NullPointerException if resource or id is null * @throws UnsupportedEncodingException if the encoding is not supported */ public LocalizedMessage(String resource,String id, String encoding) throws NullPointerException, UnsupportedEncodingException { if (resource == null || id == null) { throw new NullPointerException(); } this.id = id; this.resource = resource; arguments = new FilteredArguments(); if (!Charset.isSupported(encoding)) { throw new UnsupportedEncodingException("The encoding \"" + encoding + "\" is not supported."); } this.encoding = encoding; } /** * Constructs a new LocalizedMessage using resource as the base name for the * RessourceBundle and id as the message bundle id the resource file. * @param resource base name of the resource file * @param id the id of the corresponding bundle in the resource file * @param arguments an array containing the arguments for the message * @throws NullPointerException if resource or id is null */ public LocalizedMessage(String resource, String id, Object[] arguments) throws NullPointerException { if (resource == null || id == null || arguments == null) { throw new NullPointerException(); } this.id = id; this.resource = resource; this.arguments = new FilteredArguments(arguments); } /** * Constructs a new LocalizedMessage using resource as the base name for the * RessourceBundle and id as the message bundle id the resource file. * @param resource base name of the resource file * @param id the id of the corresponding bundle in the resource file * @param encoding the encoding of the resource file * @param arguments an array containing the arguments for the message * @throws NullPointerException if resource or id is null * @throws UnsupportedEncodingException if the encoding is not supported */ public LocalizedMessage(String resource, String id, String encoding, Object[] arguments) throws NullPointerException, UnsupportedEncodingException { if (resource == null || id == null || arguments == null) { throw new NullPointerException(); } this.id = id; this.resource = resource; this.arguments = new FilteredArguments(arguments); if (!Charset.isSupported(encoding)) { throw new UnsupportedEncodingException("The encoding \"" + encoding + "\" is not supported."); } this.encoding = encoding; } /** * Reads the entry id + "." + key from the resource file and returns a * formated message for the given Locale and TimeZone. * @param key second part of the entry id * @param loc the used {@link Locale} * @param timezone the used {@link TimeZone} * @return a Strng containing the localized message * @throws MissingEntryException if the resource file is not available or the entry does not exist. */ public String getEntry(String key,Locale loc, TimeZone timezone) throws MissingEntryException { String entry = id; if (key != null) { entry += "." + key; } try { ResourceBundle bundle; if (loader == null) { bundle = ResourceBundle.getBundle(resource,loc); } else { bundle = ResourceBundle.getBundle(resource, loc, loader); } String result = bundle.getString(entry); if (!encoding.equals(DEFAULT_ENCODING)) { result = new String(result.getBytes(DEFAULT_ENCODING), encoding); } if (!arguments.isEmpty()) { result = formatWithTimeZone(result,arguments.getFilteredArgs(loc),loc,timezone); } result = addExtraArgs(result, loc); return result; } catch (MissingResourceException mre) { throw new MissingEntryException("Can't find entry " + entry + " in resource file " + resource + ".", resource, entry, loc, loader != null ? loader : this.getClassLoader()); } catch (UnsupportedEncodingException use) { // should never occur - cause we already test this in the constructor throw new RuntimeException(use); } } protected String formatWithTimeZone( String template, Object[] arguments, Locale locale, TimeZone timezone) { MessageFormat mf = new MessageFormat(" "); mf.setLocale(locale); mf.applyPattern(template); if (!timezone.equals(TimeZone.getDefault())) { Format[] formats = mf.getFormats(); for (int i = 0; i < formats.length; i++) { if (formats[i] instanceof DateFormat) { DateFormat temp = (DateFormat) formats[i]; temp.setTimeZone(timezone); mf.setFormat(i,temp); } } } return mf.format(arguments); } protected String addExtraArgs(String msg, Locale locale) { if (extraArgs != null) { StringBuffer sb = new StringBuffer(msg); Object[] filteredArgs = extraArgs.getFilteredArgs(locale); for (int i = 0; i < filteredArgs.length; i++) { sb.append(filteredArgs[i]); } msg = sb.toString(); } return msg; } /** * Sets the {@link Filter} that is used to filter the arguments of this message * @param filter the {@link Filter} to use. null to disable filtering. */ public void setFilter(Filter filter) { arguments.setFilter(filter); if (extraArgs != null) { extraArgs.setFilter(filter); } this.filter = filter; } /** * Returns the current filter. * @return the current filter */ public Filter getFilter() { return filter; } /** * Set the {@link ClassLoader} which loads the resource files. If it is set to null * then the default {@link ClassLoader} is used. * @param loader the {@link ClassLoader} which loads the resource files */ public void setClassLoader(ClassLoader loader) { this.loader = loader; } /** * Returns the {@link ClassLoader} which loads the resource files or null * if the default ClassLoader is used. * @return the {@link ClassLoader} which loads the resource files */ public ClassLoader getClassLoader() { return loader; } /** * Returns the id of the message in the resource bundle. * @return the id of the message */ public String getId() { return id; } /** * Returns the name of the resource bundle for this message * @return name of the resource file */ public String getResource() { return resource; } /** * Returns an Object[] containing the message arguments. * @return the message arguments */ public Object[] getArguments() { return arguments.getArguments(); } /** * * @param extraArg */ public void setExtraArgument(Object extraArg) { setExtraArguments(new Object[] {extraArg}); } /** * * @param extraArgs */ public void setExtraArguments(Object[] extraArgs) { if (extraArgs != null) { this.extraArgs = new FilteredArguments(extraArgs); this.extraArgs.setFilter(filter); } else { this.extraArgs = null; } } /** * * @return */ public Object[] getExtraArgs() { return (extraArgs == null) ? null : extraArgs.getArguments(); } protected class FilteredArguments { protected static final int NO_FILTER = 0; protected static final int FILTER = 1; protected static final int FILTER_URL = 2; protected Filter filter = null; protected boolean[] isLocaleSpecific; protected int[] argFilterType; protected Object[] arguments; protected Object[] unpackedArgs; protected Object[] filteredArgs; FilteredArguments() { this(new Object[0]); } FilteredArguments(Object[] args) { this.arguments = args; this.unpackedArgs = new Object[args.length]; this.filteredArgs = new Object[args.length]; this.isLocaleSpecific = new boolean[args.length]; this.argFilterType = new int[args.length]; for (int i = 0; i < args.length; i++) { if (args[i] instanceof TrustedInput) { this.unpackedArgs[i] = ((TrustedInput) args[i]).getInput(); argFilterType[i] = NO_FILTER; } else if (args[i] instanceof UntrustedInput) { this.unpackedArgs[i] = ((UntrustedInput) args[i]).getInput(); if (args[i] instanceof UntrustedUrlInput) { argFilterType[i] = FILTER_URL; } else { argFilterType[i] = FILTER; } } else { this.unpackedArgs[i] = args[i]; argFilterType[i] = FILTER; } // locale specific this.isLocaleSpecific[i] = (this.unpackedArgs[i] instanceof LocaleString); } } public boolean isEmpty() { return unpackedArgs.length == 0; } public Object[] getArguments() { return arguments; } public Object[] getFilteredArgs(Locale locale) { Object[] result = new Object[unpackedArgs.length]; for (int i = 0; i < unpackedArgs.length; i++) { Object arg; if (filteredArgs[i] != null) { arg = filteredArgs[i]; } else { arg = unpackedArgs[i]; if (isLocaleSpecific[i]) { // get locale arg = ((LocaleString) arg).getLocaleString(locale); arg = filter(argFilterType[i], arg); } else { arg = filter(argFilterType[i], arg); filteredArgs[i] = arg; } } result[i] = arg; } return result; } private Object filter(int type, Object obj) { if (filter != null) { Object o = (null == obj) ? "null" : obj; switch (type) { case NO_FILTER: return o; case FILTER: return filter.doFilter(o.toString()); case FILTER_URL: return filter.doFilterUrl(o.toString()); default: return null; } } else { return obj; } } public Filter getFilter() { return filter; } public void setFilter(Filter filter) { if (filter != this.filter) { for (int i = 0; i < unpackedArgs.length; i++) { filteredArgs[i] = null; } } this.filter = filter; } } public String toString() { StringBuffer sb = new StringBuffer(); sb.append("Resource: \"").append(resource); sb.append("\" Id: \"").append(id).append("\""); sb.append(" Arguments: ").append(arguments.getArguments().length).append(" normal"); if (extraArgs != null && extraArgs.getArguments().length > 0) { sb.append(", ").append(extraArgs.getArguments().length).append(" extra"); } sb.append(" Encoding: ").append(encoding); sb.append(" ClassLoader: ").append(loader); return sb.toString(); } } bouncycastle-1.49.orig/src/org/bouncycastle/i18n/MissingEntryException.java0000644000175000017500000000342510574435405026451 0ustar ebourgebourgpackage org.bouncycastle.i18n; import java.net.URL; import java.net.URLClassLoader; import java.util.Locale; public class MissingEntryException extends RuntimeException { protected final String resource; protected final String key; protected final ClassLoader loader; protected final Locale locale; private String debugMsg; public MissingEntryException(String message, String resource, String key, Locale locale, ClassLoader loader) { super(message); this.resource = resource; this.key = key; this.locale = locale; this.loader = loader; } public MissingEntryException(String message, Throwable cause, String resource, String key, Locale locale, ClassLoader loader) { super(message, cause); this.resource = resource; this.key = key; this.locale = locale; this.loader = loader; } public String getKey() { return key; } public String getResource() { return resource; } public ClassLoader getClassLoader() { return loader; } public Locale getLocale() { return locale; } public String getDebugMsg() { if (debugMsg == null) { debugMsg = "Can not find entry " + key + " in resource file " + resource + " for the locale " + locale + "."; if (loader instanceof URLClassLoader) { URL[] urls = ((URLClassLoader) loader).getURLs(); debugMsg += " The following entries in the classpath were searched: "; for (int i = 0; i != urls.length; i++) { debugMsg += urls[i] + " "; } } } return debugMsg; } } bouncycastle-1.49.orig/src/org/bouncycastle/i18n/LocalizedException.java0000644000175000017500000000244410472271362025721 0ustar ebourgebourgpackage org.bouncycastle.i18n; import java.util.Locale; /** * Base class for all Exceptions with localized messages. */ public class LocalizedException extends Exception { protected ErrorBundle message; private Throwable cause; /** * Constructs a new LocalizedException with the specified localized message. * @param message the {@link ErrorBundle} that contains the message for the exception */ public LocalizedException(ErrorBundle message) { super(message.getText(Locale.getDefault())); this.message = message; } /** * Constructs a new LocalizedException with the specified localized message and cause. * @param message the {@link ErrorBundle} that contains the message for the exception * @param throwable the cause */ public LocalizedException(ErrorBundle message, Throwable throwable) { super(message.getText(Locale.getDefault())); this.message = message; this.cause = throwable; } /** * Returns the localized error message of the exception. * @return the localized error message as {@link ErrorBundle} */ public ErrorBundle getErrorMessage() { return message; } public Throwable getCause() { return cause; } } bouncycastle-1.49.orig/src/org/bouncycastle/ocsp/0000755000175000017500000000000012152033551021443 5ustar ebourgebourgbouncycastle-1.49.orig/src/org/bouncycastle/ocsp/OCSPRespStatus.java0000644000175000017500000000113010262753174025115 0ustar ebourgebourgpackage org.bouncycastle.ocsp; public interface OCSPRespStatus { /** * note 4 is not used. */ public static final int SUCCESSFUL = 0; // --Response has valid confirmations public static final int MALFORMED_REQUEST = 1; // --Illegal confirmation request public static final int INTERNAL_ERROR = 2; // --Internal error in issuer public static final int TRY_LATER = 3; // --Try again later public static final int SIGREQUIRED = 5; // --Must sign the request public static final int UNAUTHORIZED = 6; // --Request unauthorized } bouncycastle-1.49.orig/src/org/bouncycastle/ocsp/CertificateID.java0000644000175000017500000001203411724561171024755 0ustar ebourgebourgpackage org.bouncycastle.ocsp; import java.math.BigInteger; import java.security.MessageDigest; import java.security.PublicKey; import java.security.cert.X509Certificate; import org.bouncycastle.asn1.ASN1InputStream; import org.bouncycastle.asn1.ASN1Integer; import org.bouncycastle.asn1.ASN1OctetString; import org.bouncycastle.asn1.DERNull; import org.bouncycastle.asn1.DERObjectIdentifier; import org.bouncycastle.asn1.DEROctetString; import org.bouncycastle.asn1.ocsp.CertID; import org.bouncycastle.asn1.x509.AlgorithmIdentifier; import org.bouncycastle.asn1.x509.SubjectPublicKeyInfo; import org.bouncycastle.jce.PrincipalUtil; import org.bouncycastle.jce.X509Principal; public class CertificateID { public static final String HASH_SHA1 = "1.3.14.3.2.26"; private final CertID id; public CertificateID( CertID id) { if (id == null) { throw new IllegalArgumentException("'id' cannot be null"); } this.id = id; } /** * create from an issuer certificate and the serial number of the * certificate it signed. * * @param hashAlgorithm hash algorithm to use * @param issuerCert issuing certificate * @param number serial number * @param provider provider to use for hashAlgorithm, null if the default one should be used. * * @exception OCSPException if any problems occur creating the id fields. */ public CertificateID( String hashAlgorithm, X509Certificate issuerCert, BigInteger number, String provider) throws OCSPException { AlgorithmIdentifier hashAlg = new AlgorithmIdentifier( new DERObjectIdentifier(hashAlgorithm), DERNull.INSTANCE); this.id = createCertID(hashAlg, issuerCert, new ASN1Integer(number), provider); } /** * create using the BC provider */ public CertificateID( String hashAlgorithm, X509Certificate issuerCert, BigInteger number) throws OCSPException { this(hashAlgorithm, issuerCert, number, "BC"); } public String getHashAlgOID() { return id.getHashAlgorithm().getObjectId().getId(); } public byte[] getIssuerNameHash() { return id.getIssuerNameHash().getOctets(); } public byte[] getIssuerKeyHash() { return id.getIssuerKeyHash().getOctets(); } /** * return the serial number for the certificate associated * with this request. */ public BigInteger getSerialNumber() { return id.getSerialNumber().getValue(); } public boolean matchesIssuer(X509Certificate issuerCert, String provider) throws OCSPException { return createCertID(id.getHashAlgorithm(), issuerCert, id.getSerialNumber(), provider) .equals(id); } public CertID toASN1Object() { return id; } public boolean equals( Object o) { if (!(o instanceof CertificateID)) { return false; } CertificateID obj = (CertificateID)o; return id.toASN1Primitive().equals(obj.id.toASN1Primitive()); } public int hashCode() { return id.toASN1Primitive().hashCode(); } /** * Create a new CertificateID for a new serial number derived from a previous one * calculated for the same CA certificate. * * @param original the previously calculated CertificateID for the CA. * @param newSerialNumber the serial number for the new certificate of interest. * * @return a new CertificateID for newSerialNumber */ public static CertificateID deriveCertificateID(CertificateID original, BigInteger newSerialNumber) { return new CertificateID(new CertID(original.id.getHashAlgorithm(), original.id.getIssuerNameHash(), original.id.getIssuerKeyHash(), new ASN1Integer(newSerialNumber))); } private static CertID createCertID(AlgorithmIdentifier hashAlg, X509Certificate issuerCert, ASN1Integer serialNumber, String provider) throws OCSPException { try { MessageDigest digest = OCSPUtil.createDigestInstance(hashAlg.getAlgorithm() .getId(), provider); X509Principal issuerName = PrincipalUtil.getSubjectX509Principal(issuerCert); digest.update(issuerName.getEncoded()); ASN1OctetString issuerNameHash = new DEROctetString(digest.digest()); PublicKey issuerKey = issuerCert.getPublicKey(); ASN1InputStream aIn = new ASN1InputStream(issuerKey.getEncoded()); SubjectPublicKeyInfo info = SubjectPublicKeyInfo.getInstance(aIn.readObject()); digest.update(info.getPublicKeyData().getBytes()); ASN1OctetString issuerKeyHash = new DEROctetString(digest.digest()); return new CertID(hashAlg, issuerNameHash, issuerKeyHash, serialNumber); } catch (Exception e) { throw new OCSPException("problem creating ID: " + e, e); } } } bouncycastle-1.49.orig/src/org/bouncycastle/ocsp/UnknownStatus.java0000644000175000017500000000026510262753174025166 0ustar ebourgebourgpackage org.bouncycastle.ocsp; /** * wrapper for the UnknownInfo object */ public class UnknownStatus implements CertificateStatus { public UnknownStatus() { } } bouncycastle-1.49.orig/src/org/bouncycastle/ocsp/RespData.java0000644000175000017500000000666211724330276024033 0ustar ebourgebourgpackage org.bouncycastle.ocsp; import java.text.ParseException; import java.util.Date; import java.util.Enumeration; import java.util.HashSet; import java.util.Set; import org.bouncycastle.asn1.ASN1Encoding; import org.bouncycastle.asn1.ASN1Sequence; import org.bouncycastle.asn1.DERObjectIdentifier; import org.bouncycastle.asn1.ocsp.ResponseData; import org.bouncycastle.asn1.ocsp.SingleResponse; import org.bouncycastle.asn1.x509.X509Extension; import org.bouncycastle.asn1.x509.X509Extensions; public class RespData implements java.security.cert.X509Extension { ResponseData data; public RespData( ResponseData data) { this.data = data; } public int getVersion() { return data.getVersion().getValue().intValue() + 1; } public RespID getResponderId() { return new RespID(data.getResponderID()); } public Date getProducedAt() { try { return data.getProducedAt().getDate(); } catch (ParseException e) { throw new IllegalStateException("ParseException:" + e.getMessage()); } } public SingleResp[] getResponses() { ASN1Sequence s = data.getResponses(); SingleResp[] rs = new SingleResp[s.size()]; for (int i = 0; i != rs.length; i++) { rs[i] = new SingleResp(SingleResponse.getInstance(s.getObjectAt(i))); } return rs; } public X509Extensions getResponseExtensions() { return X509Extensions.getInstance(data.getResponseExtensions()); } /** * RFC 2650 doesn't specify any critical extensions so we return true * if any are encountered. * * @return true if any critical extensions are present. */ public boolean hasUnsupportedCriticalExtension() { Set extns = getCriticalExtensionOIDs(); if (extns != null && !extns.isEmpty()) { return true; } return false; } private Set getExtensionOIDs(boolean critical) { Set set = new HashSet(); X509Extensions extensions = this.getResponseExtensions(); if (extensions != null) { Enumeration e = extensions.oids(); while (e.hasMoreElements()) { DERObjectIdentifier oid = (DERObjectIdentifier)e.nextElement(); X509Extension ext = extensions.getExtension(oid); if (critical == ext.isCritical()) { set.add(oid.getId()); } } } return set; } public Set getCriticalExtensionOIDs() { return getExtensionOIDs(true); } public Set getNonCriticalExtensionOIDs() { return getExtensionOIDs(false); } public byte[] getExtensionValue(String oid) { X509Extensions exts = this.getResponseExtensions(); if (exts != null) { X509Extension ext = exts.getExtension(new DERObjectIdentifier(oid)); if (ext != null) { try { return ext.getValue().getEncoded(ASN1Encoding.DER); } catch (Exception e) { throw new RuntimeException("error encoding " + e.toString()); } } } return null; } } bouncycastle-1.49.orig/src/org/bouncycastle/ocsp/Req.java0000644000175000017500000000515211724337165023054 0ustar ebourgebourgpackage org.bouncycastle.ocsp; import java.util.Enumeration; import java.util.HashSet; import java.util.Set; import org.bouncycastle.asn1.ASN1Encoding; import org.bouncycastle.asn1.DERObjectIdentifier; import org.bouncycastle.asn1.ocsp.Request; import org.bouncycastle.asn1.x509.X509Extension; import org.bouncycastle.asn1.x509.X509Extensions; public class Req implements java.security.cert.X509Extension { private Request req; public Req( Request req) { this.req = req; } public CertificateID getCertID() { return new CertificateID(req.getReqCert()); } public X509Extensions getSingleRequestExtensions() { return X509Extensions.getInstance(req.getSingleRequestExtensions()); } /** * RFC 2650 doesn't specify any critical extensions so we return true * if any are encountered. * * @return true if any critical extensions are present. */ public boolean hasUnsupportedCriticalExtension() { Set extns = getCriticalExtensionOIDs(); if (extns != null && !extns.isEmpty()) { return true; } return false; } private Set getExtensionOIDs(boolean critical) { Set set = new HashSet(); X509Extensions extensions = this.getSingleRequestExtensions(); if (extensions != null) { Enumeration e = extensions.oids(); while (e.hasMoreElements()) { DERObjectIdentifier oid = (DERObjectIdentifier)e.nextElement(); X509Extension ext = extensions.getExtension(oid); if (critical == ext.isCritical()) { set.add(oid.getId()); } } } return set; } public Set getCriticalExtensionOIDs() { return getExtensionOIDs(true); } public Set getNonCriticalExtensionOIDs() { return getExtensionOIDs(false); } public byte[] getExtensionValue(String oid) { X509Extensions exts = this.getSingleRequestExtensions(); if (exts != null) { X509Extension ext = exts.getExtension(new DERObjectIdentifier(oid)); if (ext != null) { try { return ext.getValue().getEncoded(ASN1Encoding.DER); } catch (Exception e) { throw new RuntimeException("error encoding " + e.toString()); } } } return null; } } bouncycastle-1.49.orig/src/org/bouncycastle/ocsp/OCSPUtil.java0000644000175000017500000002145212103437527023723 0ustar ebourgebourgpackage org.bouncycastle.ocsp; import org.bouncycastle.asn1.DERNull; import org.bouncycastle.asn1.DERObjectIdentifier; import org.bouncycastle.asn1.cryptopro.CryptoProObjectIdentifiers; import org.bouncycastle.asn1.nist.NISTObjectIdentifiers; import org.bouncycastle.asn1.pkcs.PKCSObjectIdentifiers; import org.bouncycastle.asn1.teletrust.TeleTrusTObjectIdentifiers; import org.bouncycastle.asn1.x509.AlgorithmIdentifier; import org.bouncycastle.asn1.x9.X9ObjectIdentifiers; import org.bouncycastle.util.Strings; import java.security.InvalidAlgorithmParameterException; import java.security.MessageDigest; import java.security.NoSuchAlgorithmException; import java.security.NoSuchProviderException; import java.security.Signature; import java.security.cert.CertStore; import java.security.cert.CertStoreParameters; import java.security.cert.CertificateException; import java.security.cert.CertificateFactory; import java.util.ArrayList; import java.util.Enumeration; import java.util.HashSet; import java.util.Hashtable; import java.util.Iterator; import java.util.List; import java.util.Set; class OCSPUtil { private static Hashtable algorithms = new Hashtable(); private static Hashtable oids = new Hashtable(); private static Set noParams = new HashSet(); static { algorithms.put("MD2WITHRSAENCRYPTION", PKCSObjectIdentifiers.md2WithRSAEncryption); algorithms.put("MD2WITHRSA", PKCSObjectIdentifiers.md2WithRSAEncryption); algorithms.put("MD5WITHRSAENCRYPTION", PKCSObjectIdentifiers.md5WithRSAEncryption); algorithms.put("MD5WITHRSA", PKCSObjectIdentifiers.md5WithRSAEncryption); algorithms.put("SHA1WITHRSAENCRYPTION", PKCSObjectIdentifiers.sha1WithRSAEncryption); algorithms.put("SHA1WITHRSA", PKCSObjectIdentifiers.sha1WithRSAEncryption); algorithms.put("SHA224WITHRSAENCRYPTION", PKCSObjectIdentifiers.sha224WithRSAEncryption); algorithms.put("SHA224WITHRSA", PKCSObjectIdentifiers.sha224WithRSAEncryption); algorithms.put("SHA256WITHRSAENCRYPTION", PKCSObjectIdentifiers.sha256WithRSAEncryption); algorithms.put("SHA256WITHRSA", PKCSObjectIdentifiers.sha256WithRSAEncryption); algorithms.put("SHA384WITHRSAENCRYPTION", PKCSObjectIdentifiers.sha384WithRSAEncryption); algorithms.put("SHA384WITHRSA", PKCSObjectIdentifiers.sha384WithRSAEncryption); algorithms.put("SHA512WITHRSAENCRYPTION", PKCSObjectIdentifiers.sha512WithRSAEncryption); algorithms.put("SHA512WITHRSA", PKCSObjectIdentifiers.sha512WithRSAEncryption); algorithms.put("RIPEMD160WITHRSAENCRYPTION", TeleTrusTObjectIdentifiers.rsaSignatureWithripemd160); algorithms.put("RIPEMD160WITHRSA", TeleTrusTObjectIdentifiers.rsaSignatureWithripemd160); algorithms.put("RIPEMD128WITHRSAENCRYPTION", TeleTrusTObjectIdentifiers.rsaSignatureWithripemd128); algorithms.put("RIPEMD128WITHRSA", TeleTrusTObjectIdentifiers.rsaSignatureWithripemd128); algorithms.put("RIPEMD256WITHRSAENCRYPTION", TeleTrusTObjectIdentifiers.rsaSignatureWithripemd256); algorithms.put("RIPEMD256WITHRSA", TeleTrusTObjectIdentifiers.rsaSignatureWithripemd256); algorithms.put("SHA1WITHDSA", X9ObjectIdentifiers.id_dsa_with_sha1); algorithms.put("DSAWITHSHA1", X9ObjectIdentifiers.id_dsa_with_sha1); algorithms.put("SHA224WITHDSA", NISTObjectIdentifiers.dsa_with_sha224); algorithms.put("SHA256WITHDSA", NISTObjectIdentifiers.dsa_with_sha256); algorithms.put("SHA1WITHECDSA", X9ObjectIdentifiers.ecdsa_with_SHA1); algorithms.put("ECDSAWITHSHA1", X9ObjectIdentifiers.ecdsa_with_SHA1); algorithms.put("SHA224WITHECDSA", X9ObjectIdentifiers.ecdsa_with_SHA224); algorithms.put("SHA256WITHECDSA", X9ObjectIdentifiers.ecdsa_with_SHA256); algorithms.put("SHA384WITHECDSA", X9ObjectIdentifiers.ecdsa_with_SHA384); algorithms.put("SHA512WITHECDSA", X9ObjectIdentifiers.ecdsa_with_SHA512); algorithms.put("GOST3411WITHGOST3410", CryptoProObjectIdentifiers.gostR3411_94_with_gostR3410_94); algorithms.put("GOST3411WITHGOST3410-94", CryptoProObjectIdentifiers.gostR3411_94_with_gostR3410_94); oids.put(PKCSObjectIdentifiers.md2WithRSAEncryption, "MD2WITHRSA"); oids.put(PKCSObjectIdentifiers.md5WithRSAEncryption, "MD5WITHRSA"); oids.put(PKCSObjectIdentifiers.sha1WithRSAEncryption, "SHA1WITHRSA"); oids.put(PKCSObjectIdentifiers.sha224WithRSAEncryption, "SHA224WITHRSA"); oids.put(PKCSObjectIdentifiers.sha256WithRSAEncryption, "SHA256WITHRSA"); oids.put(PKCSObjectIdentifiers.sha384WithRSAEncryption, "SHA384WITHRSA"); oids.put(PKCSObjectIdentifiers.sha512WithRSAEncryption, "SHA512WITHRSA"); oids.put(TeleTrusTObjectIdentifiers.rsaSignatureWithripemd160, "RIPEMD160WITHRSA"); oids.put(TeleTrusTObjectIdentifiers.rsaSignatureWithripemd128, "RIPEMD128WITHRSA"); oids.put(TeleTrusTObjectIdentifiers.rsaSignatureWithripemd256, "RIPEMD256WITHRSA"); oids.put(X9ObjectIdentifiers.id_dsa_with_sha1, "SHA1WITHDSA"); oids.put(NISTObjectIdentifiers.dsa_with_sha224, "SHA224WITHDSA"); oids.put(NISTObjectIdentifiers.dsa_with_sha256, "SHA256WITHDSA"); oids.put(X9ObjectIdentifiers.ecdsa_with_SHA1, "SHA1WITHECDSA"); oids.put(X9ObjectIdentifiers.ecdsa_with_SHA224, "SHA224WITHECDSA"); oids.put(X9ObjectIdentifiers.ecdsa_with_SHA256, "SHA256WITHECDSA"); oids.put(X9ObjectIdentifiers.ecdsa_with_SHA384, "SHA384WITHECDSA"); oids.put(X9ObjectIdentifiers.ecdsa_with_SHA512, "SHA512WITHECDSA"); oids.put(CryptoProObjectIdentifiers.gostR3411_94_with_gostR3410_94, "GOST3411WITHGOST3410"); // // According to RFC 3279, the ASN.1 encoding SHALL (id-dsa-with-sha1) or MUST (ecdsa-with-SHA*) omit the parameters field. // The parameters field SHALL be NULL for RSA based signature algorithms. // noParams.add(X9ObjectIdentifiers.ecdsa_with_SHA1); noParams.add(X9ObjectIdentifiers.ecdsa_with_SHA224); noParams.add(X9ObjectIdentifiers.ecdsa_with_SHA256); noParams.add(X9ObjectIdentifiers.ecdsa_with_SHA384); noParams.add(X9ObjectIdentifiers.ecdsa_with_SHA512); noParams.add(X9ObjectIdentifiers.id_dsa_with_sha1); noParams.add(NISTObjectIdentifiers.dsa_with_sha224); noParams.add(NISTObjectIdentifiers.dsa_with_sha256); } static DERObjectIdentifier getAlgorithmOID( String algorithmName) { algorithmName = Strings.toUpperCase(algorithmName); if (algorithms.containsKey(algorithmName)) { return (DERObjectIdentifier)algorithms.get(algorithmName); } return new DERObjectIdentifier(algorithmName); } static String getAlgorithmName( DERObjectIdentifier oid) { if (oids.containsKey(oid)) { return (String)oids.get(oid); } return oid.getId(); } static AlgorithmIdentifier getSigAlgID( DERObjectIdentifier sigOid) { if (noParams.contains(sigOid)) { return new AlgorithmIdentifier(sigOid); } else { return new AlgorithmIdentifier(sigOid, DERNull.INSTANCE); } } static Iterator getAlgNames() { Enumeration e = algorithms.keys(); List l = new ArrayList(); while (e.hasMoreElements()) { l.add(e.nextElement()); } return l.iterator(); } static CertStore createCertStoreInstance(String type, CertStoreParameters params, String provider) throws InvalidAlgorithmParameterException, NoSuchAlgorithmException, NoSuchProviderException { if (provider == null) { return CertStore.getInstance(type, params); } return CertStore.getInstance(type, params, provider); } static MessageDigest createDigestInstance(String digestName, String provider) throws NoSuchAlgorithmException, NoSuchProviderException { if (provider == null) { return MessageDigest.getInstance(digestName); } return MessageDigest.getInstance(digestName, provider); } static Signature createSignatureInstance(String sigName, String provider) throws NoSuchAlgorithmException, NoSuchProviderException { if (provider == null) { return Signature.getInstance(sigName); } return Signature.getInstance(sigName, provider); } static CertificateFactory createX509CertificateFactory(String provider) throws CertificateException, NoSuchProviderException { if (provider == null) { return CertificateFactory.getInstance("X.509"); } return CertificateFactory.getInstance("X.509", provider); } } bouncycastle-1.49.orig/src/org/bouncycastle/ocsp/RespID.java0000644000175000017500000000343111475041371023443 0ustar ebourgebourgpackage org.bouncycastle.ocsp; import java.security.MessageDigest; import java.security.PublicKey; import javax.security.auth.x500.X500Principal; import org.bouncycastle.asn1.ASN1InputStream; import org.bouncycastle.asn1.ASN1OctetString; import org.bouncycastle.asn1.DEROctetString; import org.bouncycastle.asn1.ocsp.ResponderID; import org.bouncycastle.asn1.x500.X500Name; import org.bouncycastle.asn1.x509.SubjectPublicKeyInfo; /** * Carrier for a ResponderID. */ public class RespID { ResponderID id; public RespID( ResponderID id) { this.id = id; } public RespID( X500Principal name) { this.id = new ResponderID(X500Name.getInstance(name.getEncoded())); } public RespID( PublicKey key) throws OCSPException { try { // TODO Allow specification of a particular provider MessageDigest digest = OCSPUtil.createDigestInstance("SHA1", null); ASN1InputStream aIn = new ASN1InputStream(key.getEncoded()); SubjectPublicKeyInfo info = SubjectPublicKeyInfo.getInstance(aIn.readObject()); digest.update(info.getPublicKeyData().getBytes()); ASN1OctetString keyHash = new DEROctetString(digest.digest()); this.id = new ResponderID(keyHash); } catch (Exception e) { throw new OCSPException("problem creating ID: " + e, e); } } public ResponderID toASN1Object() { return id; } public boolean equals( Object o) { if (!(o instanceof RespID)) { return false; } RespID obj = (RespID)o; return id.equals(obj.id); } public int hashCode() { return id.hashCode(); } } bouncycastle-1.49.orig/src/org/bouncycastle/ocsp/CertificateStatus.java0000644000175000017500000000017610262753174025752 0ustar ebourgebourgpackage org.bouncycastle.ocsp; public interface CertificateStatus { public static final CertificateStatus GOOD = null; } bouncycastle-1.49.orig/src/org/bouncycastle/ocsp/OCSPReqGenerator.java0000644000175000017500000002127512103437527025407 0ustar ebourgebourgpackage org.bouncycastle.ocsp; import java.io.ByteArrayOutputStream; import java.io.IOException; import java.security.GeneralSecurityException; import java.security.NoSuchProviderException; import java.security.PrivateKey; import java.security.SecureRandom; import java.security.cert.CertificateEncodingException; import java.security.cert.X509Certificate; import java.util.ArrayList; import java.util.Iterator; import java.util.List; import javax.security.auth.x500.X500Principal; import org.bouncycastle.asn1.ASN1EncodableVector; import org.bouncycastle.asn1.ASN1OutputStream; import org.bouncycastle.asn1.ASN1Primitive; import org.bouncycastle.asn1.ASN1Sequence; import org.bouncycastle.asn1.DERBitString; import org.bouncycastle.asn1.DERNull; import org.bouncycastle.asn1.DERObjectIdentifier; import org.bouncycastle.asn1.DERSequence; import org.bouncycastle.asn1.ocsp.OCSPRequest; import org.bouncycastle.asn1.ocsp.Request; import org.bouncycastle.asn1.ocsp.Signature; import org.bouncycastle.asn1.ocsp.TBSRequest; import org.bouncycastle.asn1.x509.AlgorithmIdentifier; import org.bouncycastle.asn1.x509.Extensions; import org.bouncycastle.asn1.x509.GeneralName; import org.bouncycastle.asn1.x509.X509CertificateStructure; import org.bouncycastle.asn1.x509.X509Extensions; import org.bouncycastle.jce.X509Principal; /** * @deprecated use classes in org.bouncycastle.cert.ocsp. */ public class OCSPReqGenerator { private List list = new ArrayList(); private GeneralName requestorName = null; private X509Extensions requestExtensions = null; private class RequestObject { CertificateID certId; X509Extensions extensions; public RequestObject( CertificateID certId, X509Extensions extensions) { this.certId = certId; this.extensions = extensions; } public Request toRequest() throws Exception { return new Request(certId.toASN1Object(), Extensions.getInstance(extensions)); } } /** * Add a request for the given CertificateID. * * @param certId certificate ID of interest */ public void addRequest( CertificateID certId) { list.add(new RequestObject(certId, null)); } /** * Add a request with extensions * * @param certId certificate ID of interest * @param singleRequestExtensions the extensions to attach to the request */ public void addRequest( CertificateID certId, X509Extensions singleRequestExtensions) { list.add(new RequestObject(certId, singleRequestExtensions)); } /** * Set the requestor name to the passed in X500Principal * * @param requestorName a X500Principal representing the requestor name. */ public void setRequestorName( X500Principal requestorName) { try { this.requestorName = new GeneralName(GeneralName.directoryName, new X509Principal(requestorName.getEncoded())); } catch (IOException e) { throw new IllegalArgumentException("cannot encode principal: " + e); } } public void setRequestorName( GeneralName requestorName) { this.requestorName = requestorName; } public void setRequestExtensions( X509Extensions requestExtensions) { this.requestExtensions = requestExtensions; } private OCSPReq generateRequest( DERObjectIdentifier signingAlgorithm, PrivateKey key, X509Certificate[] chain, String provider, SecureRandom random) throws OCSPException, NoSuchProviderException { Iterator it = list.iterator(); ASN1EncodableVector requests = new ASN1EncodableVector(); while (it.hasNext()) { try { requests.add(((RequestObject)it.next()).toRequest()); } catch (Exception e) { throw new OCSPException("exception creating Request", e); } } TBSRequest tbsReq = new TBSRequest(requestorName, new DERSequence(requests), requestExtensions); java.security.Signature sig = null; Signature signature = null; if (signingAlgorithm != null) { if (requestorName == null) { throw new OCSPException("requestorName must be specified if request is signed."); } try { sig = OCSPUtil.createSignatureInstance(signingAlgorithm.getId(), provider); if (random != null) { sig.initSign(key, random); } else { sig.initSign(key); } } catch (NoSuchProviderException e) { // TODO Why this special case? throw e; } catch (GeneralSecurityException e) { throw new OCSPException("exception creating signature: " + e, e); } DERBitString bitSig = null; try { ByteArrayOutputStream bOut = new ByteArrayOutputStream(); ASN1OutputStream aOut = new ASN1OutputStream(bOut); aOut.writeObject(tbsReq); sig.update(bOut.toByteArray()); bitSig = new DERBitString(sig.sign()); } catch (Exception e) { throw new OCSPException("exception processing TBSRequest: " + e, e); } AlgorithmIdentifier sigAlgId = new AlgorithmIdentifier(signingAlgorithm, DERNull.INSTANCE); if (chain != null && chain.length > 0) { ASN1EncodableVector v = new ASN1EncodableVector(); try { for (int i = 0; i != chain.length; i++) { v.add(new X509CertificateStructure( (ASN1Sequence)ASN1Primitive.fromByteArray(chain[i].getEncoded()))); } } catch (IOException e) { throw new OCSPException("error processing certs", e); } catch (CertificateEncodingException e) { throw new OCSPException("error encoding certs", e); } signature = new Signature(sigAlgId, bitSig, new DERSequence(v)); } else { signature = new Signature(sigAlgId, bitSig); } } return new OCSPReq(new OCSPRequest(tbsReq, signature)); } /** * Generate an unsigned request * * @return the OCSPReq * @throws OCSPException */ public OCSPReq generate() throws OCSPException { try { return generateRequest(null, null, null, null, null); } catch (NoSuchProviderException e) { // // this shouldn't happen but... // throw new OCSPException("no provider! - " + e, e); } } public OCSPReq generate( String signingAlgorithm, PrivateKey key, X509Certificate[] chain, String provider) throws OCSPException, NoSuchProviderException, IllegalArgumentException { return generate(signingAlgorithm, key, chain, provider, null); } public OCSPReq generate( String signingAlgorithm, PrivateKey key, X509Certificate[] chain, String provider, SecureRandom random) throws OCSPException, NoSuchProviderException, IllegalArgumentException { if (signingAlgorithm == null) { throw new IllegalArgumentException("no signing algorithm specified"); } try { DERObjectIdentifier oid = OCSPUtil.getAlgorithmOID(signingAlgorithm); return generateRequest(oid, key, chain, provider, random); } catch (IllegalArgumentException e) { throw new IllegalArgumentException("unknown signing algorithm specified: " + signingAlgorithm); } } /** * Return an iterator of the signature names supported by the generator. * * @return an iterator containing recognised names. */ public Iterator getSignatureAlgNames() { return OCSPUtil.getAlgNames(); } } bouncycastle-1.49.orig/src/org/bouncycastle/ocsp/SingleResp.java0000644000175000017500000000776411724330276024407 0ustar ebourgebourgpackage org.bouncycastle.ocsp; import java.text.ParseException; import java.util.Date; import java.util.Enumeration; import java.util.HashSet; import java.util.Set; import org.bouncycastle.asn1.ASN1Encoding; import org.bouncycastle.asn1.DERObjectIdentifier; import org.bouncycastle.asn1.ocsp.CertStatus; import org.bouncycastle.asn1.ocsp.RevokedInfo; import org.bouncycastle.asn1.ocsp.SingleResponse; import org.bouncycastle.asn1.x509.X509Extension; import org.bouncycastle.asn1.x509.X509Extensions; public class SingleResp implements java.security.cert.X509Extension { SingleResponse resp; public SingleResp( SingleResponse resp) { this.resp = resp; } public CertificateID getCertID() { return new CertificateID(resp.getCertID()); } /** * Return the status object for the response - null indicates good. * * @return the status object for the response, null if it is good. */ public Object getCertStatus() { CertStatus s = resp.getCertStatus(); if (s.getTagNo() == 0) { return null; // good } else if (s.getTagNo() == 1) { return new RevokedStatus(RevokedInfo.getInstance(s.getStatus())); } return new UnknownStatus(); } public Date getThisUpdate() { try { return resp.getThisUpdate().getDate(); } catch (ParseException e) { throw new IllegalStateException("ParseException: " + e.getMessage()); } } /** * return the NextUpdate value - note: this is an optional field so may * be returned as null. * * @return nextUpdate, or null if not present. */ public Date getNextUpdate() { if (resp.getNextUpdate() == null) { return null; } try { return resp.getNextUpdate().getDate(); } catch (ParseException e) { throw new IllegalStateException("ParseException: " + e.getMessage()); } } public X509Extensions getSingleExtensions() { return X509Extensions.getInstance(resp.getSingleExtensions()); } /** * RFC 2650 doesn't specify any critical extensions so we return true * if any are encountered. * * @return true if any critical extensions are present. */ public boolean hasUnsupportedCriticalExtension() { Set extns = getCriticalExtensionOIDs(); return extns != null && !extns.isEmpty(); } private Set getExtensionOIDs(boolean critical) { Set set = new HashSet(); X509Extensions extensions = this.getSingleExtensions(); if (extensions != null) { Enumeration e = extensions.oids(); while (e.hasMoreElements()) { DERObjectIdentifier oid = (DERObjectIdentifier)e.nextElement(); X509Extension ext = extensions.getExtension(oid); if (critical == ext.isCritical()) { set.add(oid.getId()); } } } return set; } public Set getCriticalExtensionOIDs() { return getExtensionOIDs(true); } public Set getNonCriticalExtensionOIDs() { return getExtensionOIDs(false); } public byte[] getExtensionValue(String oid) { X509Extensions exts = this.getSingleExtensions(); if (exts != null) { X509Extension ext = exts.getExtension(new DERObjectIdentifier(oid)); if (ext != null) { try { return ext.getValue().getEncoded(ASN1Encoding.DER); } catch (Exception e) { throw new RuntimeException("error encoding " + e.toString()); } } } return null; } } bouncycastle-1.49.orig/src/org/bouncycastle/ocsp/OCSPReq.java0000644000175000017500000002676111710120630023530 0ustar ebourgebourgpackage org.bouncycastle.ocsp; import java.io.ByteArrayInputStream; import java.io.ByteArrayOutputStream; import java.io.IOException; import java.io.InputStream; import java.security.InvalidAlgorithmParameterException; import java.security.NoSuchAlgorithmException; import java.security.NoSuchProviderException; import java.security.PublicKey; import java.security.Signature; import java.security.cert.CertStore; import java.security.cert.CertStoreParameters; import java.security.cert.CertificateException; import java.security.cert.CertificateFactory; import java.security.cert.CollectionCertStoreParameters; import java.security.cert.X509Certificate; import java.util.ArrayList; import java.util.Enumeration; import java.util.HashSet; import java.util.List; import java.util.Set; import org.bouncycastle.asn1.ASN1Encodable; import org.bouncycastle.asn1.ASN1Encoding; import org.bouncycastle.asn1.ASN1InputStream; import org.bouncycastle.asn1.ASN1ObjectIdentifier; import org.bouncycastle.asn1.ASN1OutputStream; import org.bouncycastle.asn1.ASN1Sequence; import org.bouncycastle.asn1.ocsp.OCSPRequest; import org.bouncycastle.asn1.ocsp.Request; import org.bouncycastle.asn1.x509.GeneralName; import org.bouncycastle.asn1.x509.X509Extension; import org.bouncycastle.asn1.x509.X509Extensions; /** *
     * OCSPRequest     ::=     SEQUENCE {
     *       tbsRequest                  TBSRequest,
     *       optionalSignature   [0]     EXPLICIT Signature OPTIONAL }
     *
     *   TBSRequest      ::=     SEQUENCE {
     *       version             [0]     EXPLICIT Version DEFAULT v1,
     *       requestorName       [1]     EXPLICIT GeneralName OPTIONAL,
     *       requestList                 SEQUENCE OF Request,
     *       requestExtensions   [2]     EXPLICIT Extensions OPTIONAL }
     *
     *   Signature       ::=     SEQUENCE {
     *       signatureAlgorithm      AlgorithmIdentifier,
     *       signature               BIT STRING,
     *       certs               [0] EXPLICIT SEQUENCE OF Certificate OPTIONAL}
     *
     *   Version         ::=             INTEGER  {  v1(0) }
     *
     *   Request         ::=     SEQUENCE {
     *       reqCert                     CertID,
     *       singleRequestExtensions     [0] EXPLICIT Extensions OPTIONAL }
     *
     *   CertID          ::=     SEQUENCE {
     *       hashAlgorithm       AlgorithmIdentifier,
     *       issuerNameHash      OCTET STRING, -- Hash of Issuer's DN
     *       issuerKeyHash       OCTET STRING, -- Hash of Issuers public key
     *       serialNumber        CertificateSerialNumber }
     * 
    * * @deprecated use classes in org.bouncycastle.cert.ocsp. */ public class OCSPReq implements java.security.cert.X509Extension { private OCSPRequest req; public OCSPReq( OCSPRequest req) { this.req = req; } public OCSPReq( byte[] req) throws IOException { this(new ASN1InputStream(req)); } public OCSPReq( InputStream in) throws IOException { this(new ASN1InputStream(in)); } private OCSPReq( ASN1InputStream aIn) throws IOException { try { this.req = OCSPRequest.getInstance(aIn.readObject()); } catch (IllegalArgumentException e) { throw new IOException("malformed request: " + e.getMessage()); } catch (ClassCastException e) { throw new IOException("malformed request: " + e.getMessage()); } } /** * Return the DER encoding of the tbsRequest field. * @return DER encoding of tbsRequest * @throws OCSPException in the event of an encoding error. */ public byte[] getTBSRequest() throws OCSPException { try { return req.getTbsRequest().getEncoded(); } catch (IOException e) { throw new OCSPException("problem encoding tbsRequest", e); } } public int getVersion() { return req.getTbsRequest().getVersion().getValue().intValue() + 1; } public GeneralName getRequestorName() { return GeneralName.getInstance(req.getTbsRequest().getRequestorName()); } public Req[] getRequestList() { ASN1Sequence seq = req.getTbsRequest().getRequestList(); Req[] requests = new Req[seq.size()]; for (int i = 0; i != requests.length; i++) { requests[i] = new Req(Request.getInstance(seq.getObjectAt(i))); } return requests; } public X509Extensions getRequestExtensions() { return X509Extensions.getInstance(req.getTbsRequest().getRequestExtensions()); } /** * return the object identifier representing the signature algorithm */ public String getSignatureAlgOID() { if (!this.isSigned()) { return null; } return req.getOptionalSignature().getSignatureAlgorithm().getObjectId().getId(); } public byte[] getSignature() { if (!this.isSigned()) { return null; } return req.getOptionalSignature().getSignature().getBytes(); } private List getCertList( String provider) throws OCSPException, NoSuchProviderException { List certs = new ArrayList(); ByteArrayOutputStream bOut = new ByteArrayOutputStream(); ASN1OutputStream aOut = new ASN1OutputStream(bOut); CertificateFactory cf; try { cf = OCSPUtil.createX509CertificateFactory(provider); } catch (CertificateException ex) { throw new OCSPException("can't get certificate factory.", ex); } // // load the certificates if we have any // ASN1Sequence s = req.getOptionalSignature().getCerts(); if (s != null) { Enumeration e = s.getObjects(); while (e.hasMoreElements()) { try { aOut.writeObject((ASN1Encodable)e.nextElement()); certs.add(cf.generateCertificate( new ByteArrayInputStream(bOut.toByteArray()))); } catch (IOException ex) { throw new OCSPException( "can't re-encode certificate!", ex); } catch (CertificateException ex) { throw new OCSPException( "can't re-encode certificate!", ex); } bOut.reset(); } } return certs; } public X509Certificate[] getCerts( String provider) throws OCSPException, NoSuchProviderException { if (!this.isSigned()) { return null; } List certs = this.getCertList(provider); return (X509Certificate[])certs.toArray(new X509Certificate[certs.size()]); } /** * If the request is signed return a possibly empty CertStore containing the certificates in the * request. If the request is not signed the method returns null. * * @param type type of CertStore to return * @param provider provider to use * @return null if not signed, a CertStore otherwise * @throws NoSuchAlgorithmException * @throws NoSuchProviderException * @throws OCSPException */ public CertStore getCertificates( String type, String provider) throws NoSuchAlgorithmException, NoSuchProviderException, OCSPException { if (!this.isSigned()) { return null; } try { CertStoreParameters params = new CollectionCertStoreParameters(this.getCertList(provider)); return OCSPUtil.createCertStoreInstance(type, params, provider); } catch (InvalidAlgorithmParameterException e) { throw new OCSPException("can't setup the CertStore", e); } } /** * Return whether or not this request is signed. * * @return true if signed false otherwise. */ public boolean isSigned() { return req.getOptionalSignature() != null; } /** * verify the signature against the TBSRequest object we contain. */ public boolean verify( PublicKey key, String sigProvider) throws OCSPException, NoSuchProviderException { if (!this.isSigned()) { throw new OCSPException("attempt to verify signature on unsigned object"); } try { Signature signature = OCSPUtil.createSignatureInstance(this.getSignatureAlgOID(), sigProvider); signature.initVerify(key); ByteArrayOutputStream bOut = new ByteArrayOutputStream(); ASN1OutputStream aOut = new ASN1OutputStream(bOut); aOut.writeObject(req.getTbsRequest()); signature.update(bOut.toByteArray()); return signature.verify(this.getSignature()); } catch (NoSuchProviderException e) { // TODO Why this special case? throw e; } catch (Exception e) { throw new OCSPException("exception processing sig: " + e, e); } } /** * return the ASN.1 encoded representation of this object. */ public byte[] getEncoded() throws IOException { ByteArrayOutputStream bOut = new ByteArrayOutputStream(); ASN1OutputStream aOut = new ASN1OutputStream(bOut); aOut.writeObject(req); return bOut.toByteArray(); } /** * RFC 2650 doesn't specify any critical extensions so we return true * if any are encountered. * * @return true if any critical extensions are present. */ public boolean hasUnsupportedCriticalExtension() { Set extns = getCriticalExtensionOIDs(); if (extns != null && !extns.isEmpty()) { return true; } return false; } private Set getExtensionOIDs(boolean critical) { Set set = new HashSet(); X509Extensions extensions = this.getRequestExtensions(); if (extensions != null) { Enumeration e = extensions.oids(); while (e.hasMoreElements()) { ASN1ObjectIdentifier oid = (ASN1ObjectIdentifier)e.nextElement(); X509Extension ext = extensions.getExtension(oid); if (critical == ext.isCritical()) { set.add(oid.getId()); } } } return set; } public Set getCriticalExtensionOIDs() { return getExtensionOIDs(true); } public Set getNonCriticalExtensionOIDs() { return getExtensionOIDs(false); } public byte[] getExtensionValue(String oid) { X509Extensions exts = this.getRequestExtensions(); if (exts != null) { X509Extension ext = exts.getExtension(new ASN1ObjectIdentifier(oid)); if (ext != null) { try { return ext.getValue().getEncoded(ASN1Encoding.DER); } catch (Exception e) { throw new RuntimeException("error encoding " + e.toString()); } } } return null; } } bouncycastle-1.49.orig/src/org/bouncycastle/ocsp/BasicOCSPResp.java0000644000175000017500000002341012151251423024645 0ustar ebourgebourgpackage org.bouncycastle.ocsp; import java.io.ByteArrayInputStream; import java.io.ByteArrayOutputStream; import java.io.IOException; import java.security.InvalidAlgorithmParameterException; import java.security.NoSuchAlgorithmException; import java.security.NoSuchProviderException; import java.security.PublicKey; import java.security.Signature; import java.security.cert.CertStore; import java.security.cert.CertStoreParameters; import java.security.cert.CertificateException; import java.security.cert.CertificateFactory; import java.security.cert.CollectionCertStoreParameters; import java.security.cert.X509Certificate; import java.text.ParseException; import java.util.ArrayList; import java.util.Date; import java.util.Enumeration; import java.util.HashSet; import java.util.List; import java.util.Set; import org.bouncycastle.asn1.ASN1Encodable; import org.bouncycastle.asn1.ASN1Encoding; import org.bouncycastle.asn1.ASN1OutputStream; import org.bouncycastle.asn1.ASN1Sequence; import org.bouncycastle.asn1.DERObjectIdentifier; import org.bouncycastle.asn1.ocsp.BasicOCSPResponse; import org.bouncycastle.asn1.ocsp.ResponseData; import org.bouncycastle.asn1.ocsp.SingleResponse; import org.bouncycastle.asn1.x509.X509Extension; import org.bouncycastle.asn1.x509.X509Extensions; /** *
     * BasicOCSPResponse       ::= SEQUENCE {
     *    tbsResponseData      ResponseData,
     *    signatureAlgorithm   AlgorithmIdentifier,
     *    signature            BIT STRING,
     *    certs                [0] EXPLICIT SEQUENCE OF Certificate OPTIONAL }
     * 
    * * @deprecated use classes in org.bouncycastle.cert.ocsp. */ public class BasicOCSPResp implements java.security.cert.X509Extension { BasicOCSPResponse resp; ResponseData data; X509Certificate[] chain = null; public BasicOCSPResp( BasicOCSPResponse resp) { this.resp = resp; this.data = resp.getTbsResponseData(); } /** * Return the DER encoding of the tbsResponseData field. * @return DER encoding of tbsResponseData * @throws OCSPException in the event of an encoding error. */ public byte[] getTBSResponseData() throws OCSPException { try { return resp.getTbsResponseData().getEncoded(); } catch (IOException e) { throw new OCSPException("problem encoding tbsResponseData", e); } } public int getVersion() { return data.getVersion().getValue().intValue() + 1; } public RespID getResponderId() { return new RespID(data.getResponderID()); } public Date getProducedAt() { try { return data.getProducedAt().getDate(); } catch (ParseException e) { throw new IllegalStateException("ParseException:" + e.getMessage()); } } public SingleResp[] getResponses() { ASN1Sequence s = data.getResponses(); SingleResp[] rs = new SingleResp[s.size()]; for (int i = 0; i != rs.length; i++) { rs[i] = new SingleResp(SingleResponse.getInstance(s.getObjectAt(i))); } return rs; } public X509Extensions getResponseExtensions() { return X509Extensions.getInstance(data.getResponseExtensions()); } /** * RFC 2650 doesn't specify any critical extensions so we return true * if any are encountered. * * @return true if any critical extensions are present. */ public boolean hasUnsupportedCriticalExtension() { Set extns = getCriticalExtensionOIDs(); if (extns != null && !extns.isEmpty()) { return true; } return false; } private Set getExtensionOIDs(boolean critical) { Set set = new HashSet(); X509Extensions extensions = this.getResponseExtensions(); if (extensions != null) { Enumeration e = extensions.oids(); while (e.hasMoreElements()) { DERObjectIdentifier oid = (DERObjectIdentifier)e.nextElement(); X509Extension ext = extensions.getExtension(oid); if (critical == ext.isCritical()) { set.add(oid.getId()); } } } return set; } public Set getCriticalExtensionOIDs() { return getExtensionOIDs(true); } public Set getNonCriticalExtensionOIDs() { return getExtensionOIDs(false); } public byte[] getExtensionValue(String oid) { X509Extensions exts = this.getResponseExtensions(); if (exts != null) { X509Extension ext = exts.getExtension(new DERObjectIdentifier(oid)); if (ext != null) { try { return ext.getValue().getEncoded(ASN1Encoding.DER); } catch (Exception e) { throw new RuntimeException("error encoding " + e.toString()); } } } return null; } public String getSignatureAlgName() { return OCSPUtil.getAlgorithmName(resp.getSignatureAlgorithm().getObjectId()); } public String getSignatureAlgOID() { return resp.getSignatureAlgorithm().getObjectId().getId(); } /** * @deprecated RespData class is no longer required as all functionality is * available on this class. * @return the RespData object */ public RespData getResponseData() { return new RespData(resp.getTbsResponseData()); } public byte[] getSignature() { return resp.getSignature().getBytes(); } private List getCertList( String provider) throws OCSPException, NoSuchProviderException { List certs = new ArrayList(); ByteArrayOutputStream bOut = new ByteArrayOutputStream(); ASN1OutputStream aOut = new ASN1OutputStream(bOut); CertificateFactory cf; try { cf = OCSPUtil.createX509CertificateFactory(provider); } catch (CertificateException ex) { throw new OCSPException("can't get certificate factory.", ex); } // // load the certificates and revocation lists if we have any // ASN1Sequence s = resp.getCerts(); if (s != null) { Enumeration e = s.getObjects(); while (e.hasMoreElements()) { try { aOut.writeObject((ASN1Encodable)e.nextElement()); certs.add(cf.generateCertificate( new ByteArrayInputStream(bOut.toByteArray()))); } catch (IOException ex) { throw new OCSPException( "can't re-encode certificate!", ex); } catch (CertificateException ex) { throw new OCSPException( "can't re-encode certificate!", ex); } bOut.reset(); } } return certs; } public X509Certificate[] getCerts( String provider) throws OCSPException, NoSuchProviderException { List certs = getCertList(provider); return (X509Certificate[])certs.toArray(new X509Certificate[certs.size()]); } /** * Return the certificates, if any associated with the response. * @param type type of CertStore to create * @param provider provider to use * @return a CertStore, possibly empty * @throws NoSuchAlgorithmException * @throws NoSuchProviderException * @throws OCSPException */ public CertStore getCertificates( String type, String provider) throws NoSuchAlgorithmException, NoSuchProviderException, OCSPException { try { CertStoreParameters params = new CollectionCertStoreParameters(this.getCertList(provider)); return OCSPUtil.createCertStoreInstance(type, params, provider); } catch (InvalidAlgorithmParameterException e) { throw new OCSPException("can't setup the CertStore", e); } } /** * verify the signature against the tbsResponseData object we contain. */ public boolean verify( PublicKey key, String sigProvider) throws OCSPException, NoSuchProviderException { try { Signature signature = OCSPUtil.createSignatureInstance(this.getSignatureAlgName(), sigProvider); signature.initVerify(key); signature.update(resp.getTbsResponseData().getEncoded(ASN1Encoding.DER)); return signature.verify(this.getSignature()); } catch (NoSuchProviderException e) { // TODO Why this special case? throw e; } catch (Exception e) { throw new OCSPException("exception processing sig: " + e, e); } } /** * return the ASN.1 encoded representation of this object. */ public byte[] getEncoded() throws IOException { return resp.getEncoded(); } public boolean equals(Object o) { if (o == this) { return true; } if (!(o instanceof BasicOCSPResp)) { return false; } BasicOCSPResp r = (BasicOCSPResp)o; return resp.equals(r.resp); } public int hashCode() { return resp.hashCode(); } } bouncycastle-1.49.orig/src/org/bouncycastle/ocsp/BasicOCSPRespGenerator.java0000644000175000017500000002524112103437526026527 0ustar ebourgebourgpackage org.bouncycastle.ocsp; import java.io.IOException; import java.security.GeneralSecurityException; import java.security.NoSuchProviderException; import java.security.PrivateKey; import java.security.PublicKey; import java.security.SecureRandom; import java.security.Signature; import java.security.cert.CertificateEncodingException; import java.security.cert.X509Certificate; import java.util.ArrayList; import java.util.Date; import java.util.Iterator; import java.util.List; import org.bouncycastle.asn1.ASN1EncodableVector; import org.bouncycastle.asn1.ASN1Encoding; import org.bouncycastle.asn1.ASN1GeneralizedTime; import org.bouncycastle.asn1.ASN1Primitive; import org.bouncycastle.asn1.ASN1Sequence; import org.bouncycastle.asn1.DERBitString; import org.bouncycastle.asn1.DERGeneralizedTime; import org.bouncycastle.asn1.DERNull; import org.bouncycastle.asn1.DERObjectIdentifier; import org.bouncycastle.asn1.DERSequence; import org.bouncycastle.asn1.ocsp.BasicOCSPResponse; import org.bouncycastle.asn1.ocsp.CertStatus; import org.bouncycastle.asn1.ocsp.ResponseData; import org.bouncycastle.asn1.ocsp.RevokedInfo; import org.bouncycastle.asn1.ocsp.SingleResponse; import org.bouncycastle.asn1.x509.AlgorithmIdentifier; import org.bouncycastle.asn1.x509.CRLReason; import org.bouncycastle.asn1.x509.X509CertificateStructure; import org.bouncycastle.asn1.x509.X509Extensions; /** * Generator for basic OCSP response objects. * * @deprecated use classes in org.bouncycastle.cert.ocsp. */ public class BasicOCSPRespGenerator { private List list = new ArrayList(); private X509Extensions responseExtensions = null; private RespID responderID; private class ResponseObject { CertificateID certId; CertStatus certStatus; DERGeneralizedTime thisUpdate; DERGeneralizedTime nextUpdate; X509Extensions extensions; public ResponseObject( CertificateID certId, CertificateStatus certStatus, Date thisUpdate, Date nextUpdate, X509Extensions extensions) { this.certId = certId; if (certStatus == null) { this.certStatus = new CertStatus(); } else if (certStatus instanceof UnknownStatus) { this.certStatus = new CertStatus(2, DERNull.INSTANCE); } else { RevokedStatus rs = (RevokedStatus)certStatus; if (rs.hasRevocationReason()) { this.certStatus = new CertStatus( new RevokedInfo(new ASN1GeneralizedTime(rs.getRevocationTime()), CRLReason.lookup(rs.getRevocationReason()))); } else { this.certStatus = new CertStatus( new RevokedInfo(new ASN1GeneralizedTime(rs.getRevocationTime()), null)); } } this.thisUpdate = new DERGeneralizedTime(thisUpdate); if (nextUpdate != null) { this.nextUpdate = new DERGeneralizedTime(nextUpdate); } else { this.nextUpdate = null; } this.extensions = extensions; } public SingleResponse toResponse() throws Exception { return new SingleResponse(certId.toASN1Object(), certStatus, thisUpdate, nextUpdate, extensions); } } /** * basic constructor */ public BasicOCSPRespGenerator( RespID responderID) { this.responderID = responderID; } /** * construct with the responderID to be the SHA-1 keyHash of the passed in public key. */ public BasicOCSPRespGenerator( PublicKey key) throws OCSPException { this.responderID = new RespID(key); } /** * Add a response for a particular Certificate ID. * * @param certID certificate ID details * @param certStatus status of the certificate - null if okay */ public void addResponse( CertificateID certID, CertificateStatus certStatus) { list.add(new ResponseObject(certID, certStatus, new Date(), null, null)); } /** * Add a response for a particular Certificate ID. * * @param certID certificate ID details * @param certStatus status of the certificate - null if okay * @param singleExtensions optional extensions */ public void addResponse( CertificateID certID, CertificateStatus certStatus, X509Extensions singleExtensions) { list.add(new ResponseObject(certID, certStatus, new Date(), null, singleExtensions)); } /** * Add a response for a particular Certificate ID. * * @param certID certificate ID details * @param nextUpdate date when next update should be requested * @param certStatus status of the certificate - null if okay * @param singleExtensions optional extensions */ public void addResponse( CertificateID certID, CertificateStatus certStatus, Date nextUpdate, X509Extensions singleExtensions) { list.add(new ResponseObject(certID, certStatus, new Date(), nextUpdate, singleExtensions)); } /** * Add a response for a particular Certificate ID. * * @param certID certificate ID details * @param thisUpdate date this response was valid on * @param nextUpdate date when next update should be requested * @param certStatus status of the certificate - null if okay * @param singleExtensions optional extensions */ public void addResponse( CertificateID certID, CertificateStatus certStatus, Date thisUpdate, Date nextUpdate, X509Extensions singleExtensions) { list.add(new ResponseObject(certID, certStatus, thisUpdate, nextUpdate, singleExtensions)); } /** * Set the extensions for the response. * * @param responseExtensions the extension object to carry. */ public void setResponseExtensions( X509Extensions responseExtensions) { this.responseExtensions = responseExtensions; } private BasicOCSPResp generateResponse( String signatureName, PrivateKey key, X509Certificate[] chain, Date producedAt, String provider, SecureRandom random) throws OCSPException, NoSuchProviderException { Iterator it = list.iterator(); DERObjectIdentifier signingAlgorithm; try { signingAlgorithm = OCSPUtil.getAlgorithmOID(signatureName); } catch (Exception e) { throw new IllegalArgumentException("unknown signing algorithm specified"); } ASN1EncodableVector responses = new ASN1EncodableVector(); while (it.hasNext()) { try { responses.add(((ResponseObject)it.next()).toResponse()); } catch (Exception e) { throw new OCSPException("exception creating Request", e); } } ResponseData tbsResp = new ResponseData(responderID.toASN1Object(), new DERGeneralizedTime(producedAt), new DERSequence(responses), responseExtensions); Signature sig = null; try { sig = OCSPUtil.createSignatureInstance(signatureName, provider); if (random != null) { sig.initSign(key, random); } else { sig.initSign(key); } } catch (NoSuchProviderException e) { // TODO Why this special case? throw e; } catch (GeneralSecurityException e) { throw new OCSPException("exception creating signature: " + e, e); } DERBitString bitSig = null; try { sig.update(tbsResp.getEncoded(ASN1Encoding.DER)); bitSig = new DERBitString(sig.sign()); } catch (Exception e) { throw new OCSPException("exception processing TBSRequest: " + e, e); } AlgorithmIdentifier sigAlgId = OCSPUtil.getSigAlgID(signingAlgorithm); DERSequence chainSeq = null; if (chain != null && chain.length > 0) { ASN1EncodableVector v = new ASN1EncodableVector(); try { for (int i = 0; i != chain.length; i++) { v.add(new X509CertificateStructure( (ASN1Sequence)ASN1Primitive.fromByteArray(chain[i].getEncoded()))); } } catch (IOException e) { throw new OCSPException("error processing certs", e); } catch (CertificateEncodingException e) { throw new OCSPException("error encoding certs", e); } chainSeq = new DERSequence(v); } return new BasicOCSPResp(new BasicOCSPResponse(tbsResp, sigAlgId, bitSig, chainSeq)); } public BasicOCSPResp generate( String signingAlgorithm, PrivateKey key, X509Certificate[] chain, Date thisUpdate, String provider) throws OCSPException, NoSuchProviderException, IllegalArgumentException { return generate(signingAlgorithm, key, chain, thisUpdate, provider, null); } public BasicOCSPResp generate( String signingAlgorithm, PrivateKey key, X509Certificate[] chain, Date producedAt, String provider, SecureRandom random) throws OCSPException, NoSuchProviderException, IllegalArgumentException { if (signingAlgorithm == null) { throw new IllegalArgumentException("no signing algorithm specified"); } return generateResponse(signingAlgorithm, key, chain, producedAt, provider, random); } /** * Return an iterator of the signature names supported by the generator. * * @return an iterator containing recognised names. */ public Iterator getSignatureAlgNames() { return OCSPUtil.getAlgNames(); } } bouncycastle-1.49.orig/src/org/bouncycastle/ocsp/OCSPRespGenerator.java0000644000175000017500000000414111710124420025546 0ustar ebourgebourgpackage org.bouncycastle.ocsp; import java.io.IOException; import org.bouncycastle.asn1.ASN1OctetString; import org.bouncycastle.asn1.DEROctetString; import org.bouncycastle.asn1.ocsp.OCSPObjectIdentifiers; import org.bouncycastle.asn1.ocsp.OCSPResponse; import org.bouncycastle.asn1.ocsp.OCSPResponseStatus; import org.bouncycastle.asn1.ocsp.ResponseBytes; /** * base generator for an OCSP response - at the moment this only supports the * generation of responses containing BasicOCSP responses. * * @deprecated use classes in org.bouncycastle.cert.ocsp. */ public class OCSPRespGenerator { public static final int SUCCESSFUL = 0; // Response has valid confirmations public static final int MALFORMED_REQUEST = 1; // Illegal confirmation request public static final int INTERNAL_ERROR = 2; // Internal error in issuer public static final int TRY_LATER = 3; // Try again later // (4) is not used public static final int SIG_REQUIRED = 5; // Must sign the request public static final int UNAUTHORIZED = 6; // Request unauthorized public OCSPResp generate( int status, Object response) throws OCSPException { if (response == null) { return new OCSPResp(new OCSPResponse(new OCSPResponseStatus(status),null)); } if (response instanceof BasicOCSPResp) { BasicOCSPResp r = (BasicOCSPResp)response; ASN1OctetString octs; try { octs = new DEROctetString(r.getEncoded()); } catch (IOException e) { throw new OCSPException("can't encode object.", e); } ResponseBytes rb = new ResponseBytes( OCSPObjectIdentifiers.id_pkix_ocsp_basic, octs); return new OCSPResp(new OCSPResponse( new OCSPResponseStatus(status), rb)); } throw new OCSPException("unknown response object"); } } bouncycastle-1.49.orig/src/org/bouncycastle/ocsp/OCSPResp.java0000644000175000017500000000556212151251423023713 0ustar ebourgebourgpackage org.bouncycastle.ocsp; import java.io.IOException; import java.io.InputStream; import org.bouncycastle.asn1.ASN1InputStream; import org.bouncycastle.asn1.ASN1Primitive; import org.bouncycastle.asn1.ocsp.BasicOCSPResponse; import org.bouncycastle.asn1.ocsp.OCSPObjectIdentifiers; import org.bouncycastle.asn1.ocsp.OCSPResponse; import org.bouncycastle.asn1.ocsp.ResponseBytes; /** * @deprecated use classes in org.bouncycastle.cert.ocsp. */ public class OCSPResp { private OCSPResponse resp; /** * @deprecated use classes in org.bouncycastle.cert.ocsp. */ public OCSPResp( OCSPResponse resp) { this.resp = resp; } /** * @deprecated use classes in org.bouncycastle.cert.ocsp. */ public OCSPResp( byte[] resp) throws IOException { this(new ASN1InputStream(resp)); } /** * @deprecated use classes in org.bouncycastle.cert.ocsp. */ public OCSPResp( InputStream in) throws IOException { this(new ASN1InputStream(in)); } private OCSPResp( ASN1InputStream aIn) throws IOException { try { this.resp = OCSPResponse.getInstance(aIn.readObject()); } catch (IllegalArgumentException e) { throw new IOException("malformed response: " + e.getMessage()); } catch (ClassCastException e) { throw new IOException("malformed response: " + e.getMessage()); } } public int getStatus() { return this.resp.getResponseStatus().getValue().intValue(); } public Object getResponseObject() throws OCSPException { ResponseBytes rb = this.resp.getResponseBytes(); if (rb == null) { return null; } if (rb.getResponseType().equals(OCSPObjectIdentifiers.id_pkix_ocsp_basic)) { try { ASN1Primitive obj = ASN1Primitive.fromByteArray(rb.getResponse().getOctets()); return new BasicOCSPResp(BasicOCSPResponse.getInstance(obj)); } catch (Exception e) { throw new OCSPException("problem decoding object: " + e, e); } } return rb.getResponse(); } /** * return the ASN.1 encoded representation of this object. */ public byte[] getEncoded() throws IOException { return resp.getEncoded(); } public boolean equals(Object o) { if (o == this) { return true; } if (!(o instanceof OCSPResp)) { return false; } OCSPResp r = (OCSPResp)o; return resp.equals(r.resp); } public int hashCode() { return resp.hashCode(); } } bouncycastle-1.49.orig/src/org/bouncycastle/ocsp/RevokedStatus.java0000644000175000017500000000306611737275254025136 0ustar ebourgebourgpackage org.bouncycastle.ocsp; import java.text.ParseException; import java.util.Date; import org.bouncycastle.asn1.ASN1GeneralizedTime; import org.bouncycastle.asn1.ocsp.RevokedInfo; import org.bouncycastle.asn1.x509.CRLReason; /** * wrapper for the RevokedInfo object */ public class RevokedStatus implements CertificateStatus { RevokedInfo info; public RevokedStatus( RevokedInfo info) { this.info = info; } public RevokedStatus( Date revocationDate, int reason) { this.info = new RevokedInfo(new ASN1GeneralizedTime(revocationDate), CRLReason.lookup(reason)); } public Date getRevocationTime() { try { return info.getRevocationTime().getDate(); } catch (ParseException e) { throw new IllegalStateException("ParseException:" + e.getMessage()); } } public boolean hasRevocationReason() { return (info.getRevocationReason() != null); } /** * return the revocation reason. Note: this field is optional, test for it * with hasRevocationReason() first. * @return the revocation reason value. * @exception IllegalStateException if a reason is asked for and none is avaliable */ public int getRevocationReason() { if (info.getRevocationReason() == null) { throw new IllegalStateException("attempt to get a reason where none is available"); } return info.getRevocationReason().getValue().intValue(); } } bouncycastle-1.49.orig/src/org/bouncycastle/ocsp/OCSPException.java0000644000175000017500000000070010522776170024740 0ustar ebourgebourgpackage org.bouncycastle.ocsp; public class OCSPException extends Exception { Exception e; public OCSPException( String name) { super(name); } public OCSPException( String name, Exception e) { super(name); this.e = e; } public Exception getUnderlyingException() { return e; } public Throwable getCause() { return e; } } bouncycastle-1.49.orig/src/org/bouncycastle/ocsp/package.html0000644000175000017500000000030712151571061023726 0ustar ebourgebourg Deprecated: see the bcpkix distribution (org.bouncycastle.cert.ocsp), classes for dealing Online Certificate Status Protocol (OCSP) - RFC 2560. bouncycastle-1.49.orig/src/org/bouncycastle/cms/0000755000175000017500000000000012152033551021261 5ustar ebourgebourgbouncycastle-1.49.orig/src/org/bouncycastle/cms/CMSAuthenticatedDataStreamGenerator.java0000644000175000017500000003152011676766316031115 0ustar ebourgebourgpackage org.bouncycastle.cms; import java.io.IOException; import java.io.OutputStream; import java.security.NoSuchAlgorithmException; import java.security.NoSuchProviderException; import java.security.Provider; import java.security.SecureRandom; import java.util.Collections; import java.util.HashMap; import java.util.Iterator; import java.util.Map; import org.bouncycastle.asn1.ASN1EncodableVector; import org.bouncycastle.asn1.ASN1Encoding; import org.bouncycastle.asn1.ASN1ObjectIdentifier; import org.bouncycastle.asn1.ASN1Set; import org.bouncycastle.asn1.BERSequenceGenerator; import org.bouncycastle.asn1.BERSet; import org.bouncycastle.asn1.DERInteger; import org.bouncycastle.asn1.DEROctetString; import org.bouncycastle.asn1.DERSet; import org.bouncycastle.asn1.DERTaggedObject; import org.bouncycastle.asn1.cms.AuthenticatedData; import org.bouncycastle.asn1.cms.CMSObjectIdentifiers; import org.bouncycastle.asn1.x509.AlgorithmIdentifier; import org.bouncycastle.cms.jcajce.JceCMSMacCalculatorBuilder; import org.bouncycastle.operator.DigestCalculator; import org.bouncycastle.operator.MacCalculator; import org.bouncycastle.util.io.TeeOutputStream; /** * General class for generating a CMS authenticated-data message stream. *

    * A simple example of usage. *

     *      CMSAuthenticatedDataStreamGenerator edGen = new CMSAuthenticatedDataStreamGenerator();
     *
     *      edGen.addRecipientInfoGenerator(new JceKeyTransRecipientInfoGenerator(cert).setProvider("BC"));
     *
     *      ByteArrayOutputStream  bOut = new ByteArrayOutputStream();
     *
     *      OutputStream out = edGen.open(
     *                              bOut, new JceCMSMacCalculatorBuilder(CMSAlgorithm.DES_EDE3_CBC).setProvider("BC").build());*
     *      out.write(data);
     *
     *      out.close();
     * 
    */ public class CMSAuthenticatedDataStreamGenerator extends CMSAuthenticatedGenerator { // Currently not handled // private Object _originatorInfo = null; // private Object _unprotectedAttributes = null; private int bufferSize; private boolean berEncodeRecipientSet; private MacCalculator macCalculator; /** * base constructor */ public CMSAuthenticatedDataStreamGenerator() { } /** * Set the underlying string size for encapsulated data * * @param bufferSize length of octet strings to buffer the data. */ public void setBufferSize( int bufferSize) { this.bufferSize = bufferSize; } /** * Use a BER Set to store the recipient information. By default recipients are * stored in a DER encoding. * * @param useBerEncodingForRecipients true if a BER set should be used, false if DER. */ public void setBEREncodeRecipients( boolean useBerEncodingForRecipients) { berEncodeRecipientSet = useBerEncodingForRecipients; } /** * generate an authenticated data structure with the encapsulated bytes marked as DATA. * * @param out the stream to store the authenticated structure in. * @param macCalculator calculator for the MAC to be attached to the data. */ public OutputStream open( OutputStream out, MacCalculator macCalculator) throws CMSException { return open(CMSObjectIdentifiers.data, out, macCalculator); } public OutputStream open( OutputStream out, MacCalculator macCalculator, DigestCalculator digestCalculator) throws CMSException { return open(CMSObjectIdentifiers.data, out, macCalculator, digestCalculator); } /** * generate an authenticated data structure with the encapsulated bytes marked as type dataType. * * @param dataType the type of the data been written to the object. * @param out the stream to store the authenticated structure in. * @param macCalculator calculator for the MAC to be attached to the data. */ public OutputStream open( ASN1ObjectIdentifier dataType, OutputStream out, MacCalculator macCalculator) throws CMSException { return open(dataType, out, macCalculator, null); } /** * generate an authenticated data structure with the encapsulated bytes marked as type dataType. * * @param dataType the type of the data been written to the object. * @param out the stream to store the authenticated structure in. * @param macCalculator calculator for the MAC to be attached to the data. * @param digestCalculator calculator for computing digest of the encapsulated data. */ public OutputStream open( ASN1ObjectIdentifier dataType, OutputStream out, MacCalculator macCalculator, DigestCalculator digestCalculator) throws CMSException { this.macCalculator = macCalculator; try { ASN1EncodableVector recipientInfos = new ASN1EncodableVector(); for (Iterator it = recipientInfoGenerators.iterator(); it.hasNext();) { RecipientInfoGenerator recipient = (RecipientInfoGenerator)it.next(); recipientInfos.add(recipient.generate(macCalculator.getKey())); } // // ContentInfo // BERSequenceGenerator cGen = new BERSequenceGenerator(out); cGen.addObject(CMSObjectIdentifiers.authenticatedData); // // Authenticated Data // BERSequenceGenerator authGen = new BERSequenceGenerator(cGen.getRawOutputStream(), 0, true); authGen.addObject(new DERInteger(AuthenticatedData.calculateVersion(originatorInfo))); if (originatorInfo != null) { authGen.addObject(new DERTaggedObject(false, 0, originatorInfo)); } if (berEncodeRecipientSet) { authGen.getRawOutputStream().write(new BERSet(recipientInfos).getEncoded()); } else { authGen.getRawOutputStream().write(new DERSet(recipientInfos).getEncoded()); } AlgorithmIdentifier macAlgId = macCalculator.getAlgorithmIdentifier(); authGen.getRawOutputStream().write(macAlgId.getEncoded()); if (digestCalculator != null) { authGen.addObject(new DERTaggedObject(false, 1, digestCalculator.getAlgorithmIdentifier())); } BERSequenceGenerator eiGen = new BERSequenceGenerator(authGen.getRawOutputStream()); eiGen.addObject(dataType); OutputStream octetStream = CMSUtils.createBEROctetOutputStream( eiGen.getRawOutputStream(), 0, false, bufferSize); OutputStream mOut; if (digestCalculator != null) { mOut = new TeeOutputStream(octetStream, digestCalculator.getOutputStream()); } else { mOut = new TeeOutputStream(octetStream, macCalculator.getOutputStream()); } return new CmsAuthenticatedDataOutputStream(macCalculator, digestCalculator, dataType, mOut, cGen, authGen, eiGen); } catch (IOException e) { throw new CMSException("exception decoding algorithm parameters.", e); } } private class CmsAuthenticatedDataOutputStream extends OutputStream { private OutputStream dataStream; private BERSequenceGenerator cGen; private BERSequenceGenerator envGen; private BERSequenceGenerator eiGen; private MacCalculator macCalculator; private DigestCalculator digestCalculator; private ASN1ObjectIdentifier contentType; public CmsAuthenticatedDataOutputStream( MacCalculator macCalculator, DigestCalculator digestCalculator, ASN1ObjectIdentifier contentType, OutputStream dataStream, BERSequenceGenerator cGen, BERSequenceGenerator envGen, BERSequenceGenerator eiGen) { this.macCalculator = macCalculator; this.digestCalculator = digestCalculator; this.contentType = contentType; this.dataStream = dataStream; this.cGen = cGen; this.envGen = envGen; this.eiGen = eiGen; } public void write( int b) throws IOException { dataStream.write(b); } public void write( byte[] bytes, int off, int len) throws IOException { dataStream.write(bytes, off, len); } public void write( byte[] bytes) throws IOException { dataStream.write(bytes); } public void close() throws IOException { dataStream.close(); eiGen.close(); Map parameters; if (digestCalculator != null) { parameters = Collections.unmodifiableMap(getBaseParameters(contentType, digestCalculator.getAlgorithmIdentifier(), digestCalculator.getDigest())); if (authGen == null) { authGen = new DefaultAuthenticatedAttributeTableGenerator(); } ASN1Set authed = new DERSet(authGen.getAttributes(parameters).toASN1EncodableVector()); OutputStream mOut = macCalculator.getOutputStream(); mOut.write(authed.getEncoded(ASN1Encoding.DER)); mOut.close(); envGen.addObject(new DERTaggedObject(false, 2, authed)); } else { parameters = Collections.unmodifiableMap(new HashMap()); } envGen.addObject(new DEROctetString(macCalculator.getMac())); if (unauthGen != null) { envGen.addObject(new DERTaggedObject(false, 3, new BERSet(unauthGen.getAttributes(parameters).toASN1EncodableVector()))); } envGen.close(); cGen.close(); } } /** * constructor allowing specific source of randomness * @param rand instance of SecureRandom to use * @deprecated no longer of any use, use basic constructor. */ public CMSAuthenticatedDataStreamGenerator( SecureRandom rand) { super(rand); } /** * generate an authenticated object that contains an CMS Authenticated Data * object using the given provider. * @throws java.io.IOException * @deprecated use open(out, MacCalculator) */ public OutputStream open( OutputStream out, String encryptionOID, String provider) throws NoSuchAlgorithmException, NoSuchProviderException, CMSException, IOException { convertOldRecipients(rand, CMSUtils.getProvider(provider)); return open(out, new JceCMSMacCalculatorBuilder(new ASN1ObjectIdentifier(encryptionOID)).setSecureRandom(rand).setProvider(provider).build()); } /** * @deprecated use open(out, MacCalculator) */ public OutputStream open( OutputStream out, String encryptionOID, Provider provider) throws NoSuchAlgorithmException, CMSException, IOException { convertOldRecipients(rand, provider); return open(out, new JceCMSMacCalculatorBuilder(new ASN1ObjectIdentifier(encryptionOID)).setSecureRandom(rand).setProvider(provider).build()); } /** * generate an enveloped object that contains an CMS Enveloped Data * object using the given provider. * @deprecated use open(out, MacCalculator) */ public OutputStream open( OutputStream out, String encryptionOID, int keySize, String provider) throws NoSuchAlgorithmException, NoSuchProviderException, CMSException, IOException { convertOldRecipients(rand, CMSUtils.getProvider(provider)); return open(out, new JceCMSMacCalculatorBuilder(new ASN1ObjectIdentifier(encryptionOID), keySize).setSecureRandom(rand).setProvider(provider).build()); } /** * generate an enveloped object that contains an CMS Enveloped Data * object using the given provider. * @deprecated use open(out, MacCalculator) */ public OutputStream open( OutputStream out, String encryptionOID, int keySize, Provider provider) throws NoSuchAlgorithmException, CMSException, IOException { convertOldRecipients(rand, provider); return open(out, new JceCMSMacCalculatorBuilder(new ASN1ObjectIdentifier(encryptionOID), keySize).setSecureRandom(rand).setProvider(provider).build()); } }bouncycastle-1.49.orig/src/org/bouncycastle/cms/KeyTransRecipientInformation.java0000644000175000017500000000664011605473354027756 0ustar ebourgebourgpackage org.bouncycastle.cms; import java.io.IOException; import java.security.Key; import java.security.NoSuchProviderException; import java.security.PrivateKey; import java.security.Provider; import org.bouncycastle.asn1.ASN1OctetString; import org.bouncycastle.asn1.cms.IssuerAndSerialNumber; import org.bouncycastle.asn1.cms.KeyTransRecipientInfo; import org.bouncycastle.asn1.cms.RecipientIdentifier; import org.bouncycastle.asn1.x509.AlgorithmIdentifier; import org.bouncycastle.cms.jcajce.JceKeyTransAuthenticatedRecipient; import org.bouncycastle.cms.jcajce.JceKeyTransEnvelopedRecipient; import org.bouncycastle.cms.jcajce.JceKeyTransRecipient; /** * the KeyTransRecipientInformation class for a recipient who has been sent a secret * key encrypted using their public key that needs to be used to * extract the message. */ public class KeyTransRecipientInformation extends RecipientInformation { private KeyTransRecipientInfo info; KeyTransRecipientInformation( KeyTransRecipientInfo info, AlgorithmIdentifier messageAlgorithm, CMSSecureReadable secureReadable, AuthAttributesProvider additionalData) { super(info.getKeyEncryptionAlgorithm(), messageAlgorithm, secureReadable, additionalData); this.info = info; RecipientIdentifier r = info.getRecipientIdentifier(); if (r.isTagged()) { ASN1OctetString octs = ASN1OctetString.getInstance(r.getId()); rid = new KeyTransRecipientId(octs.getOctets()); } else { IssuerAndSerialNumber iAnds = IssuerAndSerialNumber.getInstance(r.getId()); rid = new KeyTransRecipientId(iAnds.getName(), iAnds.getSerialNumber().getValue()); } } /** * decrypt the content and return it * @deprecated use getContentStream(Recipient) method */ public CMSTypedStream getContentStream( Key key, String prov) throws CMSException, NoSuchProviderException { return getContentStream(key, CMSUtils.getProvider(prov)); } /** * decrypt the content and return it * @deprecated use getContentStream(Recipient) method */ public CMSTypedStream getContentStream( Key key, Provider prov) throws CMSException { try { JceKeyTransRecipient recipient; if (secureReadable instanceof CMSEnvelopedHelper.CMSEnvelopedSecureReadable) { recipient = new JceKeyTransEnvelopedRecipient((PrivateKey)key); } else { recipient = new JceKeyTransAuthenticatedRecipient((PrivateKey)key); } if (prov != null) { recipient.setProvider(prov); if (prov.getName().equalsIgnoreCase("SunJCE")) { recipient.setContentProvider((String)null); // need to fall back to generic search } } return getContentStream(recipient); } catch (IOException e) { throw new CMSException("encoding error: " + e.getMessage(), e); } } protected RecipientOperator getRecipientOperator(Recipient recipient) throws CMSException { return ((KeyTransRecipient)recipient).getRecipientOperator(keyEncAlg, messageAlgorithm, info.getEncryptedKey().getOctets()); } } bouncycastle-1.49.orig/src/org/bouncycastle/cms/CMSCompressedData.java0000644000175000017500000001134011712066037025372 0ustar ebourgebourgpackage org.bouncycastle.cms; import java.io.IOException; import java.io.InputStream; import java.util.zip.InflaterInputStream; import org.bouncycastle.asn1.ASN1ObjectIdentifier; import org.bouncycastle.asn1.ASN1OctetString; import org.bouncycastle.asn1.cms.CompressedData; import org.bouncycastle.asn1.cms.ContentInfo; import org.bouncycastle.operator.InputExpander; import org.bouncycastle.operator.InputExpanderProvider; /** * containing class for an CMS Compressed Data object *
     *     CMSCompressedData cd = new CMSCompressedData(inputStream);
     *
     *     process(cd.getContent(new ZlibExpanderProvider()));
     * 
    */ public class CMSCompressedData { ContentInfo contentInfo; CompressedData comData; public CMSCompressedData( byte[] compressedData) throws CMSException { this(CMSUtils.readContentInfo(compressedData)); } public CMSCompressedData( InputStream compressedData) throws CMSException { this(CMSUtils.readContentInfo(compressedData)); } public CMSCompressedData( ContentInfo contentInfo) throws CMSException { this.contentInfo = contentInfo; try { this.comData = CompressedData.getInstance(contentInfo.getContent()); } catch (ClassCastException e) { throw new CMSException("Malformed content.", e); } catch (IllegalArgumentException e) { throw new CMSException("Malformed content.", e); } } /** * Return the uncompressed content. * * @return the uncompressed content * @throws CMSException if there is an exception uncompressing the data. * @deprecated use getContent(InputExpanderProvider) */ public byte[] getContent() throws CMSException { ContentInfo content = comData.getEncapContentInfo(); ASN1OctetString bytes = (ASN1OctetString)content.getContent(); InflaterInputStream zIn = new InflaterInputStream(bytes.getOctetStream()); try { return CMSUtils.streamToByteArray(zIn); } catch (IOException e) { throw new CMSException("exception reading compressed stream.", e); } } /** * Return the uncompressed content, throwing an exception if the data size * is greater than the passed in limit. If the content is exceeded getCause() * on the CMSException will contain a StreamOverflowException * * @param limit maximum number of bytes to read * @return the content read * @throws CMSException if there is an exception uncompressing the data. * @deprecated use getContent(InputExpanderProvider) */ public byte[] getContent(int limit) throws CMSException { ContentInfo content = comData.getEncapContentInfo(); ASN1OctetString bytes = (ASN1OctetString)content.getContent(); InflaterInputStream zIn = new InflaterInputStream(bytes.getOctetStream()); try { return CMSUtils.streamToByteArray(zIn, limit); } catch (IOException e) { throw new CMSException("exception reading compressed stream.", e); } } public ASN1ObjectIdentifier getContentType() { return contentInfo.getContentType(); } /** * Return the uncompressed content. * * @param expanderProvider a provider of expander algorithm implementations. * @return the uncompressed content * @throws CMSException if there is an exception un-compressing the data. */ public byte[] getContent(InputExpanderProvider expanderProvider) throws CMSException { ContentInfo content = comData.getEncapContentInfo(); ASN1OctetString bytes = (ASN1OctetString)content.getContent(); InputExpander expander = expanderProvider.get(comData.getCompressionAlgorithmIdentifier()); InputStream zIn = expander.getInputStream(bytes.getOctetStream()); try { return CMSUtils.streamToByteArray(zIn); } catch (IOException e) { throw new CMSException("exception reading compressed stream.", e); } } /** * return the ContentInfo * @deprecated use toASN1Structure() */ public ContentInfo getContentInfo() { return contentInfo; } /** * return the ContentInfo */ public ContentInfo toASN1Structure() { return contentInfo; } /** * return the ASN.1 encoded representation of this object. */ public byte[] getEncoded() throws IOException { return contentInfo.getEncoded(); } } bouncycastle-1.49.orig/src/org/bouncycastle/cms/KeyAgreeRecipientId.java0000644000175000017500000000430511726252156025754 0ustar ebourgebourgpackage org.bouncycastle.cms; import java.math.BigInteger; import org.bouncycastle.asn1.x500.X500Name; import org.bouncycastle.cert.selector.X509CertificateHolderSelector; public class KeyAgreeRecipientId extends RecipientId { private X509CertificateHolderSelector baseSelector; private KeyAgreeRecipientId(X509CertificateHolderSelector baseSelector) { super(keyAgree); this.baseSelector = baseSelector; } /** * Construct a key agree recipient ID with the value of a public key's subjectKeyId. * * @param subjectKeyId a subjectKeyId */ public KeyAgreeRecipientId(byte[] subjectKeyId) { this(null, null, subjectKeyId); } /** * Construct a key agree recipient ID based on the issuer and serial number of the recipient's associated * certificate. * * @param issuer the issuer of the recipient's associated certificate. * @param serialNumber the serial number of the recipient's associated certificate. */ public KeyAgreeRecipientId(X500Name issuer, BigInteger serialNumber) { this(issuer, serialNumber, null); } public KeyAgreeRecipientId(X500Name issuer, BigInteger serialNumber, byte[] subjectKeyId) { this(new X509CertificateHolderSelector(issuer, serialNumber, subjectKeyId)); } public BigInteger getSerialNumber() { return baseSelector.getSerialNumber(); } public byte[] getSubjectKeyIdentifier() { return baseSelector.getSubjectKeyIdentifier(); } public int hashCode() { return baseSelector.hashCode(); } public boolean equals( Object o) { if (!(o instanceof KeyAgreeRecipientId)) { return false; } KeyAgreeRecipientId id = (KeyAgreeRecipientId)o; return this.baseSelector.equals(id.baseSelector); } public Object clone() { return new KeyAgreeRecipientId(baseSelector); } public boolean match(Object obj) { if (obj instanceof KeyAgreeRecipientInformation) { return ((KeyAgreeRecipientInformation)obj).getRID().equals(this); } return baseSelector.match(obj); } } bouncycastle-1.49.orig/src/org/bouncycastle/cms/CMSReadable.java0000644000175000017500000000030411426205501024162 0ustar ebourgebourgpackage org.bouncycastle.cms; import java.io.IOException; import java.io.InputStream; interface CMSReadable { public InputStream getInputStream() throws IOException, CMSException; } bouncycastle-1.49.orig/src/org/bouncycastle/cms/CMSAuthenticatedDataGenerator.java0000644000175000017500000002276011726302174027727 0ustar ebourgebourgpackage org.bouncycastle.cms; import java.io.ByteArrayOutputStream; import java.io.IOException; import java.io.OutputStream; import java.security.NoSuchAlgorithmException; import java.security.NoSuchProviderException; import java.security.Provider; import java.security.SecureRandom; import java.util.Collections; import java.util.HashMap; import java.util.Iterator; import java.util.Map; import javax.crypto.KeyGenerator; import org.bouncycastle.asn1.ASN1EncodableVector; import org.bouncycastle.asn1.ASN1Encoding; import org.bouncycastle.asn1.ASN1ObjectIdentifier; import org.bouncycastle.asn1.ASN1OctetString; import org.bouncycastle.asn1.ASN1Set; import org.bouncycastle.asn1.BEROctetString; import org.bouncycastle.asn1.BERSet; import org.bouncycastle.asn1.DEROctetString; import org.bouncycastle.asn1.DERSet; import org.bouncycastle.asn1.cms.AuthenticatedData; import org.bouncycastle.asn1.cms.CMSObjectIdentifiers; import org.bouncycastle.asn1.cms.ContentInfo; import org.bouncycastle.asn1.x509.AlgorithmIdentifier; import org.bouncycastle.cms.jcajce.JceCMSMacCalculatorBuilder; import org.bouncycastle.operator.DigestCalculator; import org.bouncycastle.operator.DigestCalculatorProvider; import org.bouncycastle.operator.MacCalculator; import org.bouncycastle.operator.OperatorCreationException; import org.bouncycastle.util.io.TeeOutputStream; /** * General class for generating a CMS authenticated-data message. * * A simple example of usage. * *
     *      CMSAuthenticatedDataGenerator  fact = new CMSAuthenticatedDataGenerator();
     *
     *      adGen.addRecipientInfoGenerator(new JceKeyTransRecipientInfoGenerator(recipientCert).setProvider("BC"));
     *
     *      CMSAuthenticatedData         data = fact.generate(new CMSProcessableByteArray(data),
     *                              new JceCMSMacCalculatorBuilder(CMSAlgorithm.DES_EDE3_CBC).setProvider(BC).build()));
     * 
    */ public class CMSAuthenticatedDataGenerator extends CMSAuthenticatedGenerator { /** * base constructor */ public CMSAuthenticatedDataGenerator() { } /** * Generate an authenticated data object from the passed in typedData and MacCalculator. * * @param typedData the data to have a MAC attached. * @param macCalculator the calculator of the MAC to be attached. * @return the resulting CMSAuthenticatedData object. * @throws CMSException on failure in encoding data or processing recipients. */ public CMSAuthenticatedData generate(CMSTypedData typedData, MacCalculator macCalculator) throws CMSException { return generate(typedData, macCalculator, null); } /** * Generate an authenticated data object from the passed in typedData and MacCalculator. * * @param typedData the data to have a MAC attached. * @param macCalculator the calculator of the MAC to be attached. * @param digestCalculator calculator for computing digest of the encapsulated data. * @return the resulting CMSAuthenticatedData object. * @throws CMSException on failure in encoding data or processing recipients. */ public CMSAuthenticatedData generate(CMSTypedData typedData, MacCalculator macCalculator, final DigestCalculator digestCalculator) throws CMSException { ASN1EncodableVector recipientInfos = new ASN1EncodableVector(); ASN1OctetString encContent; ASN1OctetString macResult; for (Iterator it = recipientInfoGenerators.iterator(); it.hasNext();) { RecipientInfoGenerator recipient = (RecipientInfoGenerator)it.next(); recipientInfos.add(recipient.generate(macCalculator.getKey())); } AuthenticatedData authData; if (digestCalculator != null) { try { ByteArrayOutputStream bOut = new ByteArrayOutputStream(); OutputStream out = new TeeOutputStream(digestCalculator.getOutputStream(), bOut); typedData.write(out); out.close(); encContent = new BEROctetString(bOut.toByteArray()); } catch (IOException e) { throw new CMSException("unable to perform digest calculation: " + e.getMessage(), e); } Map parameters = getBaseParameters(typedData.getContentType(), digestCalculator.getAlgorithmIdentifier(), digestCalculator.getDigest()); if (authGen == null) { authGen = new DefaultAuthenticatedAttributeTableGenerator(); } ASN1Set authed = new DERSet(authGen.getAttributes(Collections.unmodifiableMap(parameters)).toASN1EncodableVector()); try { OutputStream mOut = macCalculator.getOutputStream(); mOut.write(authed.getEncoded(ASN1Encoding.DER)); mOut.close(); macResult = new DEROctetString(macCalculator.getMac()); } catch (IOException e) { throw new CMSException("exception decoding algorithm parameters.", e); } ASN1Set unauthed = (unauthGen != null) ? new BERSet(unauthGen.getAttributes(Collections.unmodifiableMap(parameters)).toASN1EncodableVector()) : null; ContentInfo eci = new ContentInfo( CMSObjectIdentifiers.data, encContent); authData = new AuthenticatedData(originatorInfo, new DERSet(recipientInfos), macCalculator.getAlgorithmIdentifier(), digestCalculator.getAlgorithmIdentifier(), eci, authed, macResult, unauthed); } else { try { ByteArrayOutputStream bOut = new ByteArrayOutputStream(); OutputStream mOut = new TeeOutputStream(bOut, macCalculator.getOutputStream()); typedData.write(mOut); mOut.close(); encContent = new BEROctetString(bOut.toByteArray()); macResult = new DEROctetString(macCalculator.getMac()); } catch (IOException e) { throw new CMSException("exception decoding algorithm parameters.", e); } ASN1Set unauthed = (unauthGen != null) ? new BERSet(unauthGen.getAttributes(new HashMap()).toASN1EncodableVector()) : null; ContentInfo eci = new ContentInfo( CMSObjectIdentifiers.data, encContent); authData = new AuthenticatedData(originatorInfo, new DERSet(recipientInfos), macCalculator.getAlgorithmIdentifier(), null, eci, null, macResult, unauthed); } ContentInfo contentInfo = new ContentInfo( CMSObjectIdentifiers.authenticatedData, authData); return new CMSAuthenticatedData(contentInfo, new DigestCalculatorProvider() { public DigestCalculator get(AlgorithmIdentifier digestAlgorithmIdentifier) throws OperatorCreationException { return digestCalculator; } }); } /** * constructor allowing specific source of randomness * @param rand instance of SecureRandom to use * @deprecated no longer required, use simple constructor. */ public CMSAuthenticatedDataGenerator( SecureRandom rand) { super(rand); } /** * generate an authenticated object that contains an CMS Authenticated Data * object using the given provider and the passed in key generator. * @deprecated */ private CMSAuthenticatedData generate( final CMSProcessable content, String macOID, KeyGenerator keyGen, Provider provider) throws NoSuchAlgorithmException, CMSException { Provider encProvider = keyGen.getProvider(); convertOldRecipients(rand, provider); return generate(new CMSTypedData() { public ASN1ObjectIdentifier getContentType() { return CMSObjectIdentifiers.data; } public void write(OutputStream out) throws IOException, CMSException { content.write(out); } public Object getContent() { return content; } }, new JceCMSMacCalculatorBuilder(new ASN1ObjectIdentifier(macOID)).setProvider(encProvider).setSecureRandom(rand).build()); } /** * generate an authenticated object that contains an CMS Authenticated Data * object using the given provider. * @deprecated use addRecipientInfoGenerator method. */ public CMSAuthenticatedData generate( CMSProcessable content, String macOID, String provider) throws NoSuchAlgorithmException, NoSuchProviderException, CMSException { return generate(content, macOID, CMSUtils.getProvider(provider)); } /** * generate an authenticated object that contains an CMS Authenticated Data * object using the given provider * @deprecated use addRecipientInfoGenerator method.. */ public CMSAuthenticatedData generate( CMSProcessable content, String encryptionOID, Provider provider) throws NoSuchAlgorithmException, CMSException { KeyGenerator keyGen = CMSEnvelopedHelper.INSTANCE.createSymmetricKeyGenerator(encryptionOID, provider); return generate(content, encryptionOID, keyGen, provider); } }bouncycastle-1.49.orig/src/org/bouncycastle/cms/CMSProcessable.java0000644000175000017500000000104311414227224024731 0ustar ebourgebourgpackage org.bouncycastle.cms; import java.io.IOException; import java.io.OutputStream; /** * Use CMSTypedData instead of this. See CMSProcessableFile/ByteArray for defaults. */ public interface CMSProcessable { /** * generic routine to copy out the data we want processed - the OutputStream * passed in will do the handling on it's own. *

    * Note: this routine may be called multiple times. */ public void write(OutputStream out) throws IOException, CMSException; public Object getContent(); } bouncycastle-1.49.orig/src/org/bouncycastle/cms/CMSEncryptedGenerator.java0000644000175000017500000000077211727537323026316 0ustar ebourgebourgpackage org.bouncycastle.cms; /** * General class for generating a CMS encrypted-data message. */ public class CMSEncryptedGenerator { protected CMSAttributeTableGenerator unprotectedAttributeGenerator = null; /** * base constructor */ protected CMSEncryptedGenerator() { } public void setUnprotectedAttributeGenerator(CMSAttributeTableGenerator unprotectedAttributeGenerator) { this.unprotectedAttributeGenerator = unprotectedAttributeGenerator; } } bouncycastle-1.49.orig/src/org/bouncycastle/cms/SignerInformation.java0000644000175000017500000006611012052665315025575 0ustar ebourgebourgpackage org.bouncycastle.cms; import java.io.IOException; import java.io.OutputStream; import java.security.NoSuchAlgorithmException; import java.security.NoSuchProviderException; import java.security.Provider; import java.security.PublicKey; import java.security.cert.CertificateExpiredException; import java.security.cert.CertificateNotYetValidException; import java.security.cert.X509Certificate; import java.util.ArrayList; import java.util.Enumeration; import java.util.Iterator; import java.util.List; import org.bouncycastle.asn1.ASN1Encodable; import org.bouncycastle.asn1.ASN1EncodableVector; import org.bouncycastle.asn1.ASN1Encoding; import org.bouncycastle.asn1.ASN1ObjectIdentifier; import org.bouncycastle.asn1.ASN1OctetString; import org.bouncycastle.asn1.ASN1Primitive; import org.bouncycastle.asn1.ASN1Set; import org.bouncycastle.asn1.DERNull; import org.bouncycastle.asn1.DERSet; import org.bouncycastle.asn1.cms.Attribute; import org.bouncycastle.asn1.cms.AttributeTable; import org.bouncycastle.asn1.cms.CMSAttributes; import org.bouncycastle.asn1.cms.IssuerAndSerialNumber; import org.bouncycastle.asn1.cms.SignerIdentifier; import org.bouncycastle.asn1.cms.SignerInfo; import org.bouncycastle.asn1.cms.Time; import org.bouncycastle.asn1.x509.AlgorithmIdentifier; import org.bouncycastle.asn1.x509.DigestInfo; import org.bouncycastle.cert.X509CertificateHolder; import org.bouncycastle.cms.jcajce.JcaSignerInfoVerifierBuilder; import org.bouncycastle.cms.jcajce.JcaSimpleSignerInfoVerifierBuilder; import org.bouncycastle.operator.ContentVerifier; import org.bouncycastle.operator.DigestCalculator; import org.bouncycastle.operator.OperatorCreationException; import org.bouncycastle.operator.RawContentVerifier; import org.bouncycastle.operator.jcajce.JcaDigestCalculatorProviderBuilder; import org.bouncycastle.util.Arrays; import org.bouncycastle.util.io.TeeOutputStream; /** * an expanded SignerInfo block from a CMS Signed message */ public class SignerInformation { private SignerId sid; private SignerInfo info; private AlgorithmIdentifier digestAlgorithm; private AlgorithmIdentifier encryptionAlgorithm; private final ASN1Set signedAttributeSet; private final ASN1Set unsignedAttributeSet; private CMSProcessable content; private byte[] signature; private ASN1ObjectIdentifier contentType; private byte[] resultDigest; // Derived private AttributeTable signedAttributeValues; private AttributeTable unsignedAttributeValues; private boolean isCounterSignature; SignerInformation( SignerInfo info, ASN1ObjectIdentifier contentType, CMSProcessable content, byte[] resultDigest) { this.info = info; this.contentType = contentType; this.isCounterSignature = contentType == null; SignerIdentifier s = info.getSID(); if (s.isTagged()) { ASN1OctetString octs = ASN1OctetString.getInstance(s.getId()); sid = new SignerId(octs.getOctets()); } else { IssuerAndSerialNumber iAnds = IssuerAndSerialNumber.getInstance(s.getId()); sid = new SignerId(iAnds.getName(), iAnds.getSerialNumber().getValue()); } this.digestAlgorithm = info.getDigestAlgorithm(); this.signedAttributeSet = info.getAuthenticatedAttributes(); this.unsignedAttributeSet = info.getUnauthenticatedAttributes(); this.encryptionAlgorithm = info.getDigestEncryptionAlgorithm(); this.signature = info.getEncryptedDigest().getOctets(); this.content = content; this.resultDigest = resultDigest; } public boolean isCounterSignature() { return isCounterSignature; } public ASN1ObjectIdentifier getContentType() { return this.contentType; } private byte[] encodeObj( ASN1Encodable obj) throws IOException { if (obj != null) { return obj.toASN1Primitive().getEncoded(); } return null; } public SignerId getSID() { return sid; } /** * return the version number for this objects underlying SignerInfo structure. */ public int getVersion() { return info.getVersion().getValue().intValue(); } public AlgorithmIdentifier getDigestAlgorithmID() { return digestAlgorithm; } /** * return the object identifier for the signature. */ public String getDigestAlgOID() { return digestAlgorithm.getAlgorithm().getId(); } /** * return the signature parameters, or null if there aren't any. */ public byte[] getDigestAlgParams() { try { return encodeObj(digestAlgorithm.getParameters()); } catch (Exception e) { throw new RuntimeException("exception getting digest parameters " + e); } } /** * return the content digest that was calculated during verification. */ public byte[] getContentDigest() { if (resultDigest == null) { throw new IllegalStateException("method can only be called after verify."); } return (byte[])resultDigest.clone(); } /** * return the object identifier for the signature. */ public String getEncryptionAlgOID() { return encryptionAlgorithm.getAlgorithm().getId(); } /** * return the signature/encryption algorithm parameters, or null if * there aren't any. */ public byte[] getEncryptionAlgParams() { try { return encodeObj(encryptionAlgorithm.getParameters()); } catch (Exception e) { throw new RuntimeException("exception getting encryption parameters " + e); } } /** * return a table of the signed attributes - indexed by * the OID of the attribute. */ public AttributeTable getSignedAttributes() { if (signedAttributeSet != null && signedAttributeValues == null) { signedAttributeValues = new AttributeTable(signedAttributeSet); } return signedAttributeValues; } /** * return a table of the unsigned attributes indexed by * the OID of the attribute. */ public AttributeTable getUnsignedAttributes() { if (unsignedAttributeSet != null && unsignedAttributeValues == null) { unsignedAttributeValues = new AttributeTable(unsignedAttributeSet); } return unsignedAttributeValues; } /** * return the encoded signature */ public byte[] getSignature() { return (byte[])signature.clone(); } /** * Return a SignerInformationStore containing the counter signatures attached to this * signer. If no counter signatures are present an empty store is returned. */ public SignerInformationStore getCounterSignatures() { // TODO There are several checks implied by the RFC3852 comments that are missing /* The countersignature attribute MUST be an unsigned attribute; it MUST NOT be a signed attribute, an authenticated attribute, an unauthenticated attribute, or an unprotected attribute. */ AttributeTable unsignedAttributeTable = getUnsignedAttributes(); if (unsignedAttributeTable == null) { return new SignerInformationStore(new ArrayList(0)); } List counterSignatures = new ArrayList(); /* The UnsignedAttributes syntax is defined as a SET OF Attributes. The UnsignedAttributes in a signerInfo may include multiple instances of the countersignature attribute. */ ASN1EncodableVector allCSAttrs = unsignedAttributeTable.getAll(CMSAttributes.counterSignature); for (int i = 0; i < allCSAttrs.size(); ++i) { Attribute counterSignatureAttribute = (Attribute)allCSAttrs.get(i); /* A countersignature attribute can have multiple attribute values. The syntax is defined as a SET OF AttributeValue, and there MUST be one or more instances of AttributeValue present. */ ASN1Set values = counterSignatureAttribute.getAttrValues(); if (values.size() < 1) { // TODO Throw an appropriate exception? } for (Enumeration en = values.getObjects(); en.hasMoreElements();) { /* Countersignature values have the same meaning as SignerInfo values for ordinary signatures, except that: 1. The signedAttributes field MUST NOT contain a content-type attribute; there is no content type for countersignatures. 2. The signedAttributes field MUST contain a message-digest attribute if it contains any other attributes. 3. The input to the message-digesting process is the contents octets of the DER encoding of the signatureValue field of the SignerInfo value with which the attribute is associated. */ SignerInfo si = SignerInfo.getInstance(en.nextElement()); counterSignatures.add(new SignerInformation(si, null, new CMSProcessableByteArray(getSignature()), null)); } } return new SignerInformationStore(counterSignatures); } /** * return the DER encoding of the signed attributes. * @throws IOException if an encoding error occurs. */ public byte[] getEncodedSignedAttributes() throws IOException { if (signedAttributeSet != null) { return signedAttributeSet.getEncoded(); } return null; } /** * @deprecated */ private boolean doVerify( PublicKey key, Provider sigProvider) throws CMSException, NoSuchAlgorithmException { try { SignerInformationVerifier verifier; if (sigProvider != null) { if (!sigProvider.getName().equalsIgnoreCase("BC")) { verifier = new JcaSignerInfoVerifierBuilder(new JcaDigestCalculatorProviderBuilder().build()).setProvider(sigProvider).build(key); } else { verifier = new JcaSimpleSignerInfoVerifierBuilder().setProvider(sigProvider).build(key); } } else { verifier = new JcaSimpleSignerInfoVerifierBuilder().build(key); } return doVerify(verifier); } catch (OperatorCreationException e) { throw new CMSException("unable to create verifier: " + e.getMessage(), e); } } private boolean doVerify( SignerInformationVerifier verifier) throws CMSException { String encName = CMSSignedHelper.INSTANCE.getEncryptionAlgName(this.getEncryptionAlgOID()); ContentVerifier contentVerifier; try { contentVerifier = verifier.getContentVerifier(encryptionAlgorithm, info.getDigestAlgorithm()); } catch (OperatorCreationException e) { throw new CMSException("can't create content verifier: " + e.getMessage(), e); } try { OutputStream sigOut = contentVerifier.getOutputStream(); if (resultDigest == null) { DigestCalculator calc = verifier.getDigestCalculator(this.getDigestAlgorithmID()); if (content != null) { OutputStream digOut = calc.getOutputStream(); if (signedAttributeSet == null) { if (contentVerifier instanceof RawContentVerifier) { content.write(digOut); } else { OutputStream cOut = new TeeOutputStream(digOut, sigOut); content.write(cOut); cOut.close(); } } else { content.write(digOut); sigOut.write(this.getEncodedSignedAttributes()); } digOut.close(); } else if (signedAttributeSet != null) { sigOut.write(this.getEncodedSignedAttributes()); } else { // TODO Get rid of this exception and just treat content==null as empty not missing? throw new CMSException("data not encapsulated in signature - use detached constructor."); } resultDigest = calc.getDigest(); } else { if (signedAttributeSet == null) { if (content != null) { content.write(sigOut); } } else { sigOut.write(this.getEncodedSignedAttributes()); } } sigOut.close(); } catch (IOException e) { throw new CMSException("can't process mime object to create signature.", e); } catch (OperatorCreationException e) { throw new CMSException("can't create digest calculator: " + e.getMessage(), e); } // RFC 3852 11.1 Check the content-type attribute is correct { ASN1Primitive validContentType = getSingleValuedSignedAttribute( CMSAttributes.contentType, "content-type"); if (validContentType == null) { if (!isCounterSignature && signedAttributeSet != null) { throw new CMSException("The content-type attribute type MUST be present whenever signed attributes are present in signed-data"); } } else { if (isCounterSignature) { throw new CMSException("[For counter signatures,] the signedAttributes field MUST NOT contain a content-type attribute"); } if (!(validContentType instanceof ASN1ObjectIdentifier)) { throw new CMSException("content-type attribute value not of ASN.1 type 'OBJECT IDENTIFIER'"); } ASN1ObjectIdentifier signedContentType = (ASN1ObjectIdentifier)validContentType; if (!signedContentType.equals(contentType)) { throw new CMSException("content-type attribute value does not match eContentType"); } } } // RFC 3852 11.2 Check the message-digest attribute is correct { ASN1Primitive validMessageDigest = getSingleValuedSignedAttribute( CMSAttributes.messageDigest, "message-digest"); if (validMessageDigest == null) { if (signedAttributeSet != null) { throw new CMSException("the message-digest signed attribute type MUST be present when there are any signed attributes present"); } } else { if (!(validMessageDigest instanceof ASN1OctetString)) { throw new CMSException("message-digest attribute value not of ASN.1 type 'OCTET STRING'"); } ASN1OctetString signedMessageDigest = (ASN1OctetString)validMessageDigest; if (!Arrays.constantTimeAreEqual(resultDigest, signedMessageDigest.getOctets())) { throw new CMSSignerDigestMismatchException("message-digest attribute value does not match calculated value"); } } } // RFC 3852 11.4 Validate countersignature attribute(s) { AttributeTable signedAttrTable = this.getSignedAttributes(); if (signedAttrTable != null && signedAttrTable.getAll(CMSAttributes.counterSignature).size() > 0) { throw new CMSException("A countersignature attribute MUST NOT be a signed attribute"); } AttributeTable unsignedAttrTable = this.getUnsignedAttributes(); if (unsignedAttrTable != null) { ASN1EncodableVector csAttrs = unsignedAttrTable.getAll(CMSAttributes.counterSignature); for (int i = 0; i < csAttrs.size(); ++i) { Attribute csAttr = (Attribute)csAttrs.get(i); if (csAttr.getAttrValues().size() < 1) { throw new CMSException("A countersignature attribute MUST contain at least one AttributeValue"); } // Note: We don't recursively validate the countersignature value } } } try { if (signedAttributeSet == null && resultDigest != null) { if (contentVerifier instanceof RawContentVerifier) { RawContentVerifier rawVerifier = (RawContentVerifier)contentVerifier; if (encName.equals("RSA")) { DigestInfo digInfo = new DigestInfo(new AlgorithmIdentifier(digestAlgorithm.getAlgorithm(), DERNull.INSTANCE), resultDigest); return rawVerifier.verify(digInfo.getEncoded(ASN1Encoding.DER), this.getSignature()); } return rawVerifier.verify(resultDigest, this.getSignature()); } } return contentVerifier.verify(this.getSignature()); } catch (IOException e) { throw new CMSException("can't process mime object to create signature.", e); } } /** * verify that the given public key successfully handles and confirms the * signature associated with this signer. * @deprecated use verify(ContentVerifierProvider) */ public boolean verify( PublicKey key, String sigProvider) throws NoSuchAlgorithmException, NoSuchProviderException, CMSException { return verify(key, CMSUtils.getProvider(sigProvider)); } /** * verify that the given public key successfully handles and confirms the * signature associated with this signer * @deprecated use verify(ContentVerifierProvider) */ public boolean verify( PublicKey key, Provider sigProvider) throws NoSuchAlgorithmException, NoSuchProviderException, CMSException { // Optional, but still need to validate if present getSigningTime(); return doVerify(key, sigProvider); } /** * verify that the given certificate successfully handles and confirms * the signature associated with this signer and, if a signingTime * attribute is available, that the certificate was valid at the time the * signature was generated. * @deprecated use verify(ContentVerifierProvider) */ public boolean verify( X509Certificate cert, String sigProvider) throws NoSuchAlgorithmException, NoSuchProviderException, CertificateExpiredException, CertificateNotYetValidException, CMSException { return verify(cert, CMSUtils.getProvider(sigProvider)); } /** * verify that the given certificate successfully handles and confirms * the signature associated with this signer and, if a signingTime * attribute is available, that the certificate was valid at the time the * signature was generated. * @deprecated use verify(ContentVerifierProvider) */ public boolean verify( X509Certificate cert, Provider sigProvider) throws NoSuchAlgorithmException, CertificateExpiredException, CertificateNotYetValidException, CMSException { Time signingTime = getSigningTime(); if (signingTime != null) { cert.checkValidity(signingTime.getDate()); } return doVerify(cert.getPublicKey(), sigProvider); } /** * Verify that the given verifier can successfully verify the signature on * this SignerInformation object. * * @param verifier a suitably configured SignerInformationVerifier. * @return true if the signer information is verified, false otherwise. * @throws org.bouncycastle.cms.CMSVerifierCertificateNotValidException if the provider has an associated certificate and the certificate is not valid at the time given as the SignerInfo's signing time. * @throws org.bouncycastle.cms.CMSException if the verifier is unable to create a ContentVerifiers or DigestCalculators. */ public boolean verify(SignerInformationVerifier verifier) throws CMSException { Time signingTime = getSigningTime(); // has to be validated if present. if (verifier.hasAssociatedCertificate()) { if (signingTime != null) { X509CertificateHolder dcv = verifier.getAssociatedCertificate(); if (!dcv.isValidOn(signingTime.getDate())) { throw new CMSVerifierCertificateNotValidException("verifier not valid at signingTime"); } } } return doVerify(verifier); } /** * Return the base ASN.1 CMS structure that this object contains. * * @return an object containing a CMS SignerInfo structure. * @deprecated use toASN1Structure() */ public SignerInfo toSignerInfo() { return info; } /** * Return the underlying ASN.1 object defining this SignerInformation object. * * @return a SignerInfo. */ public SignerInfo toASN1Structure() { return info; } private ASN1Primitive getSingleValuedSignedAttribute( ASN1ObjectIdentifier attrOID, String printableName) throws CMSException { AttributeTable unsignedAttrTable = this.getUnsignedAttributes(); if (unsignedAttrTable != null && unsignedAttrTable.getAll(attrOID).size() > 0) { throw new CMSException("The " + printableName + " attribute MUST NOT be an unsigned attribute"); } AttributeTable signedAttrTable = this.getSignedAttributes(); if (signedAttrTable == null) { return null; } ASN1EncodableVector v = signedAttrTable.getAll(attrOID); switch (v.size()) { case 0: return null; case 1: { Attribute t = (Attribute)v.get(0); ASN1Set attrValues = t.getAttrValues(); if (attrValues.size() != 1) { throw new CMSException("A " + printableName + " attribute MUST have a single attribute value"); } return attrValues.getObjectAt(0).toASN1Primitive(); } default: throw new CMSException("The SignedAttributes in a signerInfo MUST NOT include multiple instances of the " + printableName + " attribute"); } } private Time getSigningTime() throws CMSException { ASN1Primitive validSigningTime = getSingleValuedSignedAttribute( CMSAttributes.signingTime, "signing-time"); if (validSigningTime == null) { return null; } try { return Time.getInstance(validSigningTime); } catch (IllegalArgumentException e) { throw new CMSException("signing-time attribute value not a valid 'Time' structure"); } } /** * Return a signer information object with the passed in unsigned * attributes replacing the ones that are current associated with * the object passed in. * * @param signerInformation the signerInfo to be used as the basis. * @param unsignedAttributes the unsigned attributes to add. * @return a copy of the original SignerInformationObject with the changed attributes. */ public static SignerInformation replaceUnsignedAttributes( SignerInformation signerInformation, AttributeTable unsignedAttributes) { SignerInfo sInfo = signerInformation.info; ASN1Set unsignedAttr = null; if (unsignedAttributes != null) { unsignedAttr = new DERSet(unsignedAttributes.toASN1EncodableVector()); } return new SignerInformation( new SignerInfo(sInfo.getSID(), sInfo.getDigestAlgorithm(), sInfo.getAuthenticatedAttributes(), sInfo.getDigestEncryptionAlgorithm(), sInfo.getEncryptedDigest(), unsignedAttr), signerInformation.contentType, signerInformation.content, null); } /** * Return a signer information object with passed in SignerInformationStore representing counter * signatures attached as an unsigned attribute. * * @param signerInformation the signerInfo to be used as the basis. * @param counterSigners signer info objects carrying counter signature. * @return a copy of the original SignerInformationObject with the changed attributes. */ public static SignerInformation addCounterSigners( SignerInformation signerInformation, SignerInformationStore counterSigners) { // TODO Perform checks from RFC 3852 11.4 SignerInfo sInfo = signerInformation.info; AttributeTable unsignedAttr = signerInformation.getUnsignedAttributes(); ASN1EncodableVector v; if (unsignedAttr != null) { v = unsignedAttr.toASN1EncodableVector(); } else { v = new ASN1EncodableVector(); } ASN1EncodableVector sigs = new ASN1EncodableVector(); for (Iterator it = counterSigners.getSigners().iterator(); it.hasNext();) { sigs.add(((SignerInformation)it.next()).toASN1Structure()); } v.add(new Attribute(CMSAttributes.counterSignature, new DERSet(sigs))); return new SignerInformation( new SignerInfo(sInfo.getSID(), sInfo.getDigestAlgorithm(), sInfo.getAuthenticatedAttributes(), sInfo.getDigestEncryptionAlgorithm(), sInfo.getEncryptedDigest(), new DERSet(v)), signerInformation.contentType, signerInformation.content, null); } } bouncycastle-1.49.orig/src/org/bouncycastle/cms/RecipientId.java0000644000175000017500000000116211726246306024335 0ustar ebourgebourgpackage org.bouncycastle.cms; import org.bouncycastle.util.Selector; public abstract class RecipientId implements Selector { public static final int keyTrans = 0; public static final int kek = 1; public static final int keyAgree = 2; public static final int password = 3; private final int type; protected RecipientId(int type) { this.type = type; } /** * Return the type code for this recipient ID. * * @return one of keyTrans, kek, keyAgree, password */ public int getType() { return type; } public abstract Object clone(); } bouncycastle-1.49.orig/src/org/bouncycastle/cms/CMSSignedData.java0000644000175000017500000006433012123710431024475 0ustar ebourgebourgpackage org.bouncycastle.cms; import java.io.IOException; import java.io.InputStream; import java.io.OutputStream; import java.security.NoSuchAlgorithmException; import java.security.NoSuchProviderException; import java.security.Provider; import java.security.cert.CertStore; import java.security.cert.CertStoreException; import java.util.ArrayList; import java.util.Collection; import java.util.Iterator; import java.util.List; import java.util.Map; import org.bouncycastle.asn1.ASN1EncodableVector; import org.bouncycastle.asn1.ASN1InputStream; import org.bouncycastle.asn1.ASN1ObjectIdentifier; import org.bouncycastle.asn1.ASN1OctetString; import org.bouncycastle.asn1.ASN1Sequence; import org.bouncycastle.asn1.ASN1Set; import org.bouncycastle.asn1.BERSequence; import org.bouncycastle.asn1.DERSet; import org.bouncycastle.asn1.cms.ContentInfo; import org.bouncycastle.asn1.cms.SignedData; import org.bouncycastle.asn1.cms.SignerInfo; import org.bouncycastle.cert.jcajce.JcaCertStoreBuilder; import org.bouncycastle.operator.DefaultSignatureAlgorithmIdentifierFinder; import org.bouncycastle.operator.OperatorCreationException; import org.bouncycastle.operator.SignatureAlgorithmIdentifierFinder; import org.bouncycastle.util.Store; import org.bouncycastle.x509.NoSuchStoreException; import org.bouncycastle.x509.X509Store; /** * general class for handling a pkcs7-signature message. * * A simple example of usage - note, in the example below the validity of * the certificate isn't verified, just the fact that one of the certs * matches the given signer... * *

     *  Store                   certStore = s.getCertificates();
     *  SignerInformationStore  signers = s.getSignerInfos();
     *  Collection              c = signers.getSigners();
     *  Iterator                it = c.iterator();
     *  
     *  while (it.hasNext())
     *  {
     *      SignerInformation   signer = (SignerInformation)it.next();
     *      Collection          certCollection = certStore.getMatches(signer.getSID());
     *
     *      Iterator              certIt = certCollection.iterator();
     *      X509CertificateHolder cert = (X509CertificateHolder)certIt.next();
     *  
     *      if (signer.verify(new JcaSimpleSignerInfoVerifierBuilder().setProvider("BC").build(cert)))
     *      {
     *          verified++;
     *      }   
     *  }
     * 
    */ public class CMSSignedData { private static final CMSSignedHelper HELPER = CMSSignedHelper.INSTANCE; SignedData signedData; ContentInfo contentInfo; CMSTypedData signedContent; SignerInformationStore signerInfoStore; X509Store attributeStore; X509Store certificateStore; X509Store crlStore; private Map hashes; private CMSSignedData( CMSSignedData c) { this.signedData = c.signedData; this.contentInfo = c.contentInfo; this.signedContent = c.signedContent; this.signerInfoStore = c.signerInfoStore; } public CMSSignedData( byte[] sigBlock) throws CMSException { this(CMSUtils.readContentInfo(sigBlock)); } public CMSSignedData( CMSProcessable signedContent, byte[] sigBlock) throws CMSException { this(signedContent, CMSUtils.readContentInfo(sigBlock)); } /** * Content with detached signature, digests precomputed * * @param hashes a map of precomputed digests for content indexed by name of hash. * @param sigBlock the signature object. */ public CMSSignedData( Map hashes, byte[] sigBlock) throws CMSException { this(hashes, CMSUtils.readContentInfo(sigBlock)); } /** * base constructor - content with detached signature. * * @param signedContent the content that was signed. * @param sigData the signature object. */ public CMSSignedData( CMSProcessable signedContent, InputStream sigData) throws CMSException { this(signedContent, CMSUtils.readContentInfo(new ASN1InputStream(sigData))); } /** * base constructor - with encapsulated content */ public CMSSignedData( InputStream sigData) throws CMSException { this(CMSUtils.readContentInfo(sigData)); } public CMSSignedData( final CMSProcessable signedContent, ContentInfo sigData) throws CMSException { if (signedContent instanceof CMSTypedData) { this.signedContent = (CMSTypedData)signedContent; } else { this.signedContent = new CMSTypedData() { public ASN1ObjectIdentifier getContentType() { return signedData.getEncapContentInfo().getContentType(); } public void write(OutputStream out) throws IOException, CMSException { signedContent.write(out); } public Object getContent() { return signedContent.getContent(); } }; } this.contentInfo = sigData; this.signedData = getSignedData(); } public CMSSignedData( Map hashes, ContentInfo sigData) throws CMSException { this.hashes = hashes; this.contentInfo = sigData; this.signedData = getSignedData(); } public CMSSignedData( ContentInfo sigData) throws CMSException { this.contentInfo = sigData; this.signedData = getSignedData(); // // this can happen if the signed message is sent simply to send a // certificate chain. // if (signedData.getEncapContentInfo().getContent() != null) { this.signedContent = new CMSProcessableByteArray(signedData.getEncapContentInfo().getContentType(), ((ASN1OctetString)(signedData.getEncapContentInfo() .getContent())).getOctets()); } else { this.signedContent = null; } } private SignedData getSignedData() throws CMSException { try { return SignedData.getInstance(contentInfo.getContent()); } catch (ClassCastException e) { throw new CMSException("Malformed content.", e); } catch (IllegalArgumentException e) { throw new CMSException("Malformed content.", e); } } /** * Return the version number for this object */ public int getVersion() { return signedData.getVersion().getValue().intValue(); } /** * return the collection of signers that are associated with the * signatures for the message. */ public SignerInformationStore getSignerInfos() { if (signerInfoStore == null) { ASN1Set s = signedData.getSignerInfos(); List signerInfos = new ArrayList(); SignatureAlgorithmIdentifierFinder sigAlgFinder = new DefaultSignatureAlgorithmIdentifierFinder(); for (int i = 0; i != s.size(); i++) { SignerInfo info = SignerInfo.getInstance(s.getObjectAt(i)); ASN1ObjectIdentifier contentType = signedData.getEncapContentInfo().getContentType(); if (hashes == null) { signerInfos.add(new SignerInformation(info, contentType, signedContent, null)); } else { Object obj = hashes.keySet().iterator().next(); byte[] hash = (obj instanceof String) ? (byte[])hashes.get(info.getDigestAlgorithm().getAlgorithm().getId()) : (byte[])hashes.get(info.getDigestAlgorithm().getAlgorithm()); signerInfos.add(new SignerInformation(info, contentType, null, hash)); } } signerInfoStore = new SignerInformationStore(signerInfos); } return signerInfoStore; } /** * return a X509Store containing the attribute certificates, if any, contained * in this message. * * @param type type of store to create * @param provider name of provider to use * @return a store of attribute certificates * @exception NoSuchProviderException if the provider requested isn't available. * @exception NoSuchStoreException if the store type isn't available. * @exception CMSException if a general exception prevents creation of the X509Store * @deprecated use base Store returning method */ public X509Store getAttributeCertificates( String type, String provider) throws NoSuchStoreException, NoSuchProviderException, CMSException { return getAttributeCertificates(type, CMSUtils.getProvider(provider)); } /** * return a X509Store containing the attribute certificates, if any, contained * in this message. * * @param type type of store to create * @param provider provider to use * @return a store of attribute certificates * @exception NoSuchStoreException if the store type isn't available. * @exception CMSException if a general exception prevents creation of the X509Store * @deprecated use base Store returning method */ public X509Store getAttributeCertificates( String type, Provider provider) throws NoSuchStoreException, CMSException { if (attributeStore == null) { attributeStore = HELPER.createAttributeStore(type, provider, this.getAttributeCertificates()); } return attributeStore; } /** * return a X509Store containing the public key certificates, if any, contained * in this message. * * @param type type of store to create * @param provider name of provider to use * @return a store of public key certificates * @exception NoSuchProviderException if the provider requested isn't available. * @exception NoSuchStoreException if the store type isn't available. * @exception CMSException if a general exception prevents creation of the X509Store * @deprecated use base Store returning method */ public X509Store getCertificates( String type, String provider) throws NoSuchStoreException, NoSuchProviderException, CMSException { return getCertificates(type, CMSUtils.getProvider(provider)); } /** * return a X509Store containing the public key certificates, if any, contained * in this message. * * @param type type of store to create * @param provider provider to use * @return a store of public key certificates * @exception NoSuchStoreException if the store type isn't available. * @exception CMSException if a general exception prevents creation of the X509Store * @deprecated use base Store returning method */ public X509Store getCertificates( String type, Provider provider) throws NoSuchStoreException, CMSException { if (certificateStore == null) { certificateStore = HELPER.createCertificateStore(type, provider, this.getCertificates()); } return certificateStore; } /** * return a X509Store containing CRLs, if any, contained * in this message. * * @param type type of store to create * @param provider name of provider to use * @return a store of CRLs * @exception NoSuchProviderException if the provider requested isn't available. * @exception NoSuchStoreException if the store type isn't available. * @exception CMSException if a general exception prevents creation of the X509Store * @deprecated use base Store returning method */ public X509Store getCRLs( String type, String provider) throws NoSuchStoreException, NoSuchProviderException, CMSException { return getCRLs(type, CMSUtils.getProvider(provider)); } /** * return a X509Store containing CRLs, if any, contained * in this message. * * @param type type of store to create * @param provider provider to use * @return a store of CRLs * @exception NoSuchStoreException if the store type isn't available. * @exception CMSException if a general exception prevents creation of the X509Store * @deprecated use base Store returning method */ public X509Store getCRLs( String type, Provider provider) throws NoSuchStoreException, CMSException { if (crlStore == null) { crlStore = HELPER.createCRLsStore(type, provider, getCRLs()); } return crlStore; } /** * return a CertStore containing the certificates and CRLs associated with * this message. * * @exception NoSuchProviderException if the provider requested isn't available. * @exception NoSuchAlgorithmException if the cert store isn't available. * @exception CMSException if a general exception prevents creation of the CertStore * @deprecated use base Store returning method and org.bouncycastle.cert.jcajce.JcaCertStoreBuilder */ public CertStore getCertificatesAndCRLs( String type, String provider) throws NoSuchAlgorithmException, NoSuchProviderException, CMSException { return getCertificatesAndCRLs(type, CMSUtils.getProvider(provider)); } /** * return a CertStore containing the certificates and CRLs associated with * this message. * * @exception NoSuchAlgorithmException if the cert store isn't available. * @exception CMSException if a general exception prevents creation of the CertStore * @deprecated use base Store returning method and org.bouncycastle.cert.jcajce.JcaCertStoreBuilder */ public CertStore getCertificatesAndCRLs( String type, Provider provider) throws NoSuchAlgorithmException, CMSException { try { JcaCertStoreBuilder certStoreBuilder = new JcaCertStoreBuilder().setType(type); if (provider != null) { certStoreBuilder.setProvider(provider); } certStoreBuilder.addCertificates(this.getCertificates()); certStoreBuilder.addCRLs(this.getCRLs()); return certStoreBuilder.build(); } catch (NoSuchAlgorithmException e) { throw e; } catch (Exception e) { throw new CMSException("exception creating CertStore: " + e.getMessage(), e); } } /** * Return any X.509 certificate objects in this SignedData structure as a Store of X509CertificateHolder objects. * * @return a Store of X509CertificateHolder objects. */ public Store getCertificates() { return HELPER.getCertificates(signedData.getCertificates()); } /** * Return any X.509 CRL objects in this SignedData structure as a Store of X509CRLHolder objects. * * @return a Store of X509CRLHolder objects. */ public Store getCRLs() { return HELPER.getCRLs(signedData.getCRLs()); } /** * Return any X.509 attribute certificate objects in this SignedData structure as a Store of X509AttributeCertificateHolder objects. * * @return a Store of X509AttributeCertificateHolder objects. */ public Store getAttributeCertificates() { return HELPER.getAttributeCertificates(signedData.getCertificates()); } /** * Return any OtherRevocationInfo OtherRevInfo objects of the type indicated by otherRevocationInfoFormat in * this SignedData structure. * * @param otherRevocationInfoFormat OID of the format type been looked for. * * @return a Store of ASN1Encodable objects representing any objects of otherRevocationInfoFormat found. */ public Store getOtherRevocationInfo(ASN1ObjectIdentifier otherRevocationInfoFormat) { return HELPER.getOtherRevocationInfo(otherRevocationInfoFormat, signedData.getCRLs()); } /** * Return the a string representation of the OID associated with the * encapsulated content info structure carried in the signed data. * * @return the OID for the content type. */ public String getSignedContentTypeOID() { return signedData.getEncapContentInfo().getContentType().getId(); } public CMSTypedData getSignedContent() { return signedContent; } /** * return the ContentInfo * @deprecated use toASN1Structure() */ public ContentInfo getContentInfo() { return contentInfo; } /** * return the ContentInfo */ public ContentInfo toASN1Structure() { return contentInfo; } /** * return the ASN.1 encoded representation of this object. */ public byte[] getEncoded() throws IOException { return contentInfo.getEncoded(); } /** * Verify all the SignerInformation objects and their associated counter signatures attached * to this CMS SignedData object. * * @param verifierProvider a provider of SignerInformationVerifier objects. * @return true if all verify, false otherwise. * @throws CMSException if an exception occurs during the verification process. */ public boolean verifySignatures(SignerInformationVerifierProvider verifierProvider) throws CMSException { return verifySignatures(verifierProvider, false); } /** * Verify all the SignerInformation objects and optionally their associated counter signatures attached * to this CMS SignedData object. * * @param verifierProvider a provider of SignerInformationVerifier objects. * @param ignoreCounterSignatures if true don't check counter signatures. If false check counter signatures as well. * @return true if all verify, false otherwise. * @throws CMSException if an exception occurs during the verification process. */ public boolean verifySignatures(SignerInformationVerifierProvider verifierProvider, boolean ignoreCounterSignatures) throws CMSException { Collection signers = this.getSignerInfos().getSigners(); for (Iterator it = signers.iterator(); it.hasNext();) { SignerInformation signer = (SignerInformation)it.next(); try { SignerInformationVerifier verifier = verifierProvider.get(signer.getSID()); if (!signer.verify(verifier)) { return false; } if (!ignoreCounterSignatures) { Collection counterSigners = signer.getCounterSignatures().getSigners(); for (Iterator cIt = counterSigners.iterator(); cIt.hasNext();) { SignerInformation counterSigner = (SignerInformation)cIt.next(); SignerInformationVerifier counterVerifier = verifierProvider.get(signer.getSID()); if (!counterSigner.verify(counterVerifier)) { return false; } } } } catch (OperatorCreationException e) { throw new CMSException("failure in verifier provider: " + e.getMessage(), e); } } return true; } /** * Replace the SignerInformation store associated with this * CMSSignedData object with the new one passed in. You would * probably only want to do this if you wanted to change the unsigned * attributes associated with a signer, or perhaps delete one. * * @param signedData the signed data object to be used as a base. * @param signerInformationStore the new signer information store to use. * @return a new signed data object. */ public static CMSSignedData replaceSigners( CMSSignedData signedData, SignerInformationStore signerInformationStore) { // // copy // CMSSignedData cms = new CMSSignedData(signedData); // // replace the store // cms.signerInfoStore = signerInformationStore; // // replace the signers in the SignedData object // ASN1EncodableVector digestAlgs = new ASN1EncodableVector(); ASN1EncodableVector vec = new ASN1EncodableVector(); Iterator it = signerInformationStore.getSigners().iterator(); while (it.hasNext()) { SignerInformation signer = (SignerInformation)it.next(); digestAlgs.add(CMSSignedHelper.INSTANCE.fixAlgID(signer.getDigestAlgorithmID())); vec.add(signer.toASN1Structure()); } ASN1Set digests = new DERSet(digestAlgs); ASN1Set signers = new DERSet(vec); ASN1Sequence sD = (ASN1Sequence)signedData.signedData.toASN1Primitive(); vec = new ASN1EncodableVector(); // // signers are the last item in the sequence. // vec.add(sD.getObjectAt(0)); // version vec.add(digests); for (int i = 2; i != sD.size() - 1; i++) { vec.add(sD.getObjectAt(i)); } vec.add(signers); cms.signedData = SignedData.getInstance(new BERSequence(vec)); // // replace the contentInfo with the new one // cms.contentInfo = new ContentInfo(cms.contentInfo.getContentType(), cms.signedData); return cms; } /** * Replace the certificate and CRL information associated with this * CMSSignedData object with the new one passed in. * * @param signedData the signed data object to be used as a base. * @param certsAndCrls the new certificates and CRLs to be used. * @return a new signed data object. * @exception CMSException if there is an error processing the CertStore * @deprecated use method taking Store arguments. */ public static CMSSignedData replaceCertificatesAndCRLs( CMSSignedData signedData, CertStore certsAndCrls) throws CMSException { // // copy // CMSSignedData cms = new CMSSignedData(signedData); // // replace the certs and crls in the SignedData object // ASN1Set certs = null; ASN1Set crls = null; try { ASN1Set set = CMSUtils.createBerSetFromList(CMSUtils.getCertificatesFromStore(certsAndCrls)); if (set.size() != 0) { certs = set; } } catch (CertStoreException e) { throw new CMSException("error getting certs from certStore", e); } try { ASN1Set set = CMSUtils.createBerSetFromList(CMSUtils.getCRLsFromStore(certsAndCrls)); if (set.size() != 0) { crls = set; } } catch (CertStoreException e) { throw new CMSException("error getting crls from certStore", e); } // // replace the CMS structure. // cms.signedData = new SignedData(signedData.signedData.getDigestAlgorithms(), signedData.signedData.getEncapContentInfo(), certs, crls, signedData.signedData.getSignerInfos()); // // replace the contentInfo with the new one // cms.contentInfo = new ContentInfo(cms.contentInfo.getContentType(), cms.signedData); return cms; } /** * Replace the certificate and CRL information associated with this * CMSSignedData object with the new one passed in. * * @param signedData the signed data object to be used as a base. * @param certificates the new certificates to be used. * @param attrCerts the new attribute certificates to be used. * @param crls the new CRLs to be used. * @return a new signed data object. * @exception CMSException if there is an error processing the CertStore */ public static CMSSignedData replaceCertificatesAndCRLs( CMSSignedData signedData, Store certificates, Store attrCerts, Store crls) throws CMSException { // // copy // CMSSignedData cms = new CMSSignedData(signedData); // // replace the certs and crls in the SignedData object // ASN1Set certSet = null; ASN1Set crlSet = null; if (certificates != null || attrCerts != null) { List certs = new ArrayList(); if (certificates != null) { certs.addAll(CMSUtils.getCertificatesFromStore(certificates)); } if (attrCerts != null) { certs.addAll(CMSUtils.getAttributeCertificatesFromStore(attrCerts)); } ASN1Set set = CMSUtils.createBerSetFromList(certs); if (set.size() != 0) { certSet = set; } } if (crls != null) { ASN1Set set = CMSUtils.createBerSetFromList(CMSUtils.getCRLsFromStore(crls)); if (set.size() != 0) { crlSet = set; } } // // replace the CMS structure. // cms.signedData = new SignedData(signedData.signedData.getDigestAlgorithms(), signedData.signedData.getEncapContentInfo(), certSet, crlSet, signedData.signedData.getSignerInfos()); // // replace the contentInfo with the new one // cms.contentInfo = new ContentInfo(cms.contentInfo.getContentType(), cms.signedData); return cms; } } bouncycastle-1.49.orig/src/org/bouncycastle/cms/CMSCompressedDataGenerator.java0000644000175000017500000000667311737175743027272 0ustar ebourgebourgpackage org.bouncycastle.cms; import java.io.ByteArrayOutputStream; import java.io.IOException; import java.io.OutputStream; import java.util.zip.DeflaterOutputStream; import org.bouncycastle.asn1.ASN1ObjectIdentifier; import org.bouncycastle.asn1.ASN1OctetString; import org.bouncycastle.asn1.BEROctetString; import org.bouncycastle.asn1.cms.CMSObjectIdentifiers; import org.bouncycastle.asn1.cms.CompressedData; import org.bouncycastle.asn1.cms.ContentInfo; import org.bouncycastle.asn1.x509.AlgorithmIdentifier; import org.bouncycastle.operator.OutputCompressor; /** * General class for generating a compressed CMS message. *

    * A simple example of usage. *

    *

     *      CMSCompressedDataGenerator  fact = new CMSCompressedDataGenerator();
     *
     *      CMSCompressedData           data = fact.generate(content, new ZlibCompressor());
     * 
    */ public class CMSCompressedDataGenerator { public static final String ZLIB = "1.2.840.113549.1.9.16.3.8"; /** * base constructor */ public CMSCompressedDataGenerator() { } /** * generate an object that contains an CMS Compressed Data * @deprecated use generate(CMSTypedData, OutputCompressor) */ public CMSCompressedData generate( CMSProcessable content, String compressionOID) throws CMSException { AlgorithmIdentifier comAlgId; ASN1OctetString comOcts; try { ByteArrayOutputStream bOut = new ByteArrayOutputStream(); DeflaterOutputStream zOut = new DeflaterOutputStream(bOut); content.write(zOut); zOut.close(); comAlgId = new AlgorithmIdentifier(new ASN1ObjectIdentifier(compressionOID)); comOcts = new BEROctetString(bOut.toByteArray()); } catch (IOException e) { throw new CMSException("exception encoding data.", e); } ContentInfo comContent = new ContentInfo( CMSObjectIdentifiers.data, comOcts); ContentInfo contentInfo = new ContentInfo( CMSObjectIdentifiers.compressedData, new CompressedData(comAlgId, comContent)); return new CMSCompressedData(contentInfo); } /** * generate an object that contains an CMS Compressed Data */ public CMSCompressedData generate( CMSTypedData content, OutputCompressor compressor) throws CMSException { AlgorithmIdentifier comAlgId; ASN1OctetString comOcts; try { ByteArrayOutputStream bOut = new ByteArrayOutputStream(); OutputStream zOut = compressor.getOutputStream(bOut); content.write(zOut); zOut.close(); comAlgId = compressor.getAlgorithmIdentifier(); comOcts = new BEROctetString(bOut.toByteArray()); } catch (IOException e) { throw new CMSException("exception encoding data.", e); } ContentInfo comContent = new ContentInfo( content.getContentType(), comOcts); ContentInfo contentInfo = new ContentInfo( CMSObjectIdentifiers.compressedData, new CompressedData(comAlgId, comContent)); return new CMSCompressedData(contentInfo); } } bouncycastle-1.49.orig/src/org/bouncycastle/cms/CMSEncryptedDataGenerator.java0000644000175000017500000000635311730275366027111 0ustar ebourgebourgpackage org.bouncycastle.cms; import java.io.ByteArrayOutputStream; import java.io.IOException; import java.io.OutputStream; import java.util.HashMap; import org.bouncycastle.asn1.ASN1OctetString; import org.bouncycastle.asn1.ASN1Set; import org.bouncycastle.asn1.BEROctetString; import org.bouncycastle.asn1.BERSet; import org.bouncycastle.asn1.cms.AttributeTable; import org.bouncycastle.asn1.cms.CMSObjectIdentifiers; import org.bouncycastle.asn1.cms.ContentInfo; import org.bouncycastle.asn1.cms.EncryptedContentInfo; import org.bouncycastle.asn1.cms.EncryptedData; import org.bouncycastle.asn1.x509.AlgorithmIdentifier; import org.bouncycastle.operator.OutputEncryptor; /** * General class for generating a CMS enveloped-data message. * * A simple example of usage. * *
     *       CMSTypedData msg     = new CMSProcessableByteArray("Hello World!".getBytes());
     *
     *       CMSEncryptedDataGenerator edGen = new CMSEnvelopedDataGenerator();
     *
     *       CMSEncryptedData ed = edGen.generate(
     *                                       msg,
     *                                       new JceCMSContentEncryptorBuilder(CMSAlgorithm.DES_EDE3_CBC)
     *                                              .setProvider("BC").build());
     *
     * 
    */ public class CMSEncryptedDataGenerator extends CMSEncryptedGenerator { /** * base constructor */ public CMSEncryptedDataGenerator() { } private CMSEncryptedData doGenerate( CMSTypedData content, OutputEncryptor contentEncryptor) throws CMSException { AlgorithmIdentifier encAlgId; ASN1OctetString encContent; ByteArrayOutputStream bOut = new ByteArrayOutputStream(); try { OutputStream cOut = contentEncryptor.getOutputStream(bOut); content.write(cOut); cOut.close(); } catch (IOException e) { throw new CMSException(""); } byte[] encryptedContent = bOut.toByteArray(); encAlgId = contentEncryptor.getAlgorithmIdentifier(); encContent = new BEROctetString(encryptedContent); EncryptedContentInfo eci = new EncryptedContentInfo( content.getContentType(), encAlgId, encContent); ASN1Set unprotectedAttrSet = null; if (unprotectedAttributeGenerator != null) { AttributeTable attrTable = unprotectedAttributeGenerator.getAttributes(new HashMap()); unprotectedAttrSet = new BERSet(attrTable.toASN1EncodableVector()); } ContentInfo contentInfo = new ContentInfo( CMSObjectIdentifiers.encryptedData, new EncryptedData(eci, unprotectedAttrSet)); return new CMSEncryptedData(contentInfo); } /** * generate an encrypted object that contains an CMS Encrypted Data structure. * * @param content the content to be encrypted * @param contentEncryptor the symmetric key based encryptor to encrypt the content with. */ public CMSEncryptedData generate( CMSTypedData content, OutputEncryptor contentEncryptor) throws CMSException { return doGenerate(content, contentEncryptor); } } bouncycastle-1.49.orig/src/org/bouncycastle/cms/CMSAuthenticatedData.java0000644000175000017500000002107611726032023026050 0ustar ebourgebourgpackage org.bouncycastle.cms; import java.io.IOException; import java.io.InputStream; import java.security.AlgorithmParameters; import java.security.NoSuchProviderException; import java.security.Provider; import org.bouncycastle.asn1.ASN1Encodable; import org.bouncycastle.asn1.ASN1OctetString; import org.bouncycastle.asn1.ASN1Set; import org.bouncycastle.asn1.cms.AttributeTable; import org.bouncycastle.asn1.cms.AuthenticatedData; import org.bouncycastle.asn1.cms.CMSAttributes; import org.bouncycastle.asn1.cms.ContentInfo; import org.bouncycastle.asn1.x509.AlgorithmIdentifier; import org.bouncycastle.cms.jcajce.JceAlgorithmIdentifierConverter; import org.bouncycastle.operator.DigestCalculatorProvider; import org.bouncycastle.operator.OperatorCreationException; import org.bouncycastle.util.Arrays; /** * containing class for an CMS Authenticated Data object */ public class CMSAuthenticatedData { RecipientInformationStore recipientInfoStore; ContentInfo contentInfo; private AlgorithmIdentifier macAlg; private ASN1Set authAttrs; private ASN1Set unauthAttrs; private byte[] mac; private OriginatorInformation originatorInfo; public CMSAuthenticatedData( byte[] authData) throws CMSException { this(CMSUtils.readContentInfo(authData)); } public CMSAuthenticatedData( byte[] authData, DigestCalculatorProvider digestCalculatorProvider) throws CMSException { this(CMSUtils.readContentInfo(authData), digestCalculatorProvider); } public CMSAuthenticatedData( InputStream authData) throws CMSException { this(CMSUtils.readContentInfo(authData)); } public CMSAuthenticatedData( InputStream authData, DigestCalculatorProvider digestCalculatorProvider) throws CMSException { this(CMSUtils.readContentInfo(authData), digestCalculatorProvider); } public CMSAuthenticatedData( ContentInfo contentInfo) throws CMSException { this(contentInfo, null); } public CMSAuthenticatedData( ContentInfo contentInfo, DigestCalculatorProvider digestCalculatorProvider) throws CMSException { this.contentInfo = contentInfo; AuthenticatedData authData = AuthenticatedData.getInstance(contentInfo.getContent()); if (authData.getOriginatorInfo() != null) { this.originatorInfo = new OriginatorInformation(authData.getOriginatorInfo()); } // // read the recipients // ASN1Set recipientInfos = authData.getRecipientInfos(); this.macAlg = authData.getMacAlgorithm(); this.authAttrs = authData.getAuthAttrs(); this.mac = authData.getMac().getOctets(); this.unauthAttrs = authData.getUnauthAttrs(); // // read the authenticated content info // ContentInfo encInfo = authData.getEncapsulatedContentInfo(); CMSReadable readable = new CMSProcessableByteArray( ASN1OctetString.getInstance(encInfo.getContent()).getOctets()); // // build the RecipientInformationStore // if (authAttrs != null) { if (digestCalculatorProvider == null) { throw new CMSException("a digest calculator provider is required if authenticated attributes are present"); } try { CMSSecureReadable secureReadable = new CMSEnvelopedHelper.CMSDigestAuthenticatedSecureReadable(digestCalculatorProvider.get(authData.getDigestAlgorithm()), readable); this.recipientInfoStore = CMSEnvelopedHelper.buildRecipientInformationStore(recipientInfos, this.macAlg, secureReadable, new AuthAttributesProvider() { public ASN1Set getAuthAttributes() { return authAttrs; } }); } catch (OperatorCreationException e) { throw new CMSException("unable to create digest calculator: " + e.getMessage(), e); } } else { CMSSecureReadable secureReadable = new CMSEnvelopedHelper.CMSAuthenticatedSecureReadable(this.macAlg, readable); this.recipientInfoStore = CMSEnvelopedHelper.buildRecipientInformationStore(recipientInfos, this.macAlg, secureReadable); } } /** * Return the originator information associated with this message if present. * * @return OriginatorInformation, null if not present. */ public OriginatorInformation getOriginatorInfo() { return originatorInfo; } public byte[] getMac() { return Arrays.clone(mac); } private byte[] encodeObj( ASN1Encodable obj) throws IOException { if (obj != null) { return obj.toASN1Primitive().getEncoded(); } return null; } /** * Return the MAC algorithm details for the MAC associated with the data in this object. * * @return AlgorithmIdentifier representing the MAC algorithm. */ public AlgorithmIdentifier getMacAlgorithm() { return macAlg; } /** * return the object identifier for the content MAC algorithm. */ public String getMacAlgOID() { return macAlg.getObjectId().getId(); } /** * return the ASN.1 encoded MAC algorithm parameters, or null if * there aren't any. */ public byte[] getMacAlgParams() { try { return encodeObj(macAlg.getParameters()); } catch (Exception e) { throw new RuntimeException("exception getting encryption parameters " + e); } } /** * Return an AlgorithmParameters object giving the MAC parameters * used to digest the message content. * * @param provider the provider to generate the parameters for. * @return the parameters object, null if there is not one. * @throws org.bouncycastle.cms.CMSException if the algorithm cannot be found, or the parameters can't be parsed. * @throws java.security.NoSuchProviderException if the provider cannot be found. * @deprecated use getMacAlgorithm and JceAlgorithmIdentifierConverter(). */ public AlgorithmParameters getMacAlgorithmParameters( String provider) throws CMSException, NoSuchProviderException { return new JceAlgorithmIdentifierConverter().setProvider(provider).getAlgorithmParameters(macAlg); } /** * Return an AlgorithmParameters object giving the MAC parameters * used to digest the message content. * * @param provider the provider to generate the parameters for. * @return the parameters object, null if there is not one. * @throws org.bouncycastle.cms.CMSException if the algorithm cannot be found, or the parameters can't be parsed. * @deprecated use getMacAlgorithm and JceAlgorithmIdentifierConverter(). */ public AlgorithmParameters getMacAlgorithmParameters( Provider provider) throws CMSException { return new JceAlgorithmIdentifierConverter().setProvider(provider).getAlgorithmParameters(macAlg); } /** * return a store of the intended recipients for this message */ public RecipientInformationStore getRecipientInfos() { return recipientInfoStore; } /** * return the ContentInfo */ public ContentInfo getContentInfo() { return contentInfo; } /** * return a table of the digested attributes indexed by * the OID of the attribute. */ public AttributeTable getAuthAttrs() { if (authAttrs == null) { return null; } return new AttributeTable(authAttrs); } /** * return a table of the undigested attributes indexed by * the OID of the attribute. */ public AttributeTable getUnauthAttrs() { if (unauthAttrs == null) { return null; } return new AttributeTable(unauthAttrs); } /** * return the ASN.1 encoded representation of this object. */ public byte[] getEncoded() throws IOException { return contentInfo.getEncoded(); } public byte[] getContentDigest() { if (authAttrs != null) { return ASN1OctetString.getInstance(getAuthAttrs().get(CMSAttributes.messageDigest).getAttrValues().getObjectAt(0)).getOctets(); } return null; } } bouncycastle-1.49.orig/src/org/bouncycastle/cms/KEKRecipient.java0000644000175000017500000000050211442065637024411 0ustar ebourgebourgpackage org.bouncycastle.cms; import org.bouncycastle.asn1.x509.AlgorithmIdentifier; public interface KEKRecipient extends Recipient { RecipientOperator getRecipientOperator(AlgorithmIdentifier keyEncAlg, AlgorithmIdentifier contentEncryptionAlgorithm, byte[] encryptedContentKey) throws CMSException; } bouncycastle-1.49.orig/src/org/bouncycastle/cms/CMSEncryptedData.java0000644000175000017500000000356212101612747025230 0ustar ebourgebourgpackage org.bouncycastle.cms; import java.io.ByteArrayInputStream; import java.io.IOException; import org.bouncycastle.asn1.cms.ContentInfo; import org.bouncycastle.asn1.cms.EncryptedContentInfo; import org.bouncycastle.asn1.cms.EncryptedData; import org.bouncycastle.operator.InputDecryptor; import org.bouncycastle.operator.InputDecryptorProvider; public class CMSEncryptedData { private ContentInfo contentInfo; private EncryptedData encryptedData; public CMSEncryptedData(ContentInfo contentInfo) { this.contentInfo = contentInfo; this.encryptedData = EncryptedData.getInstance(contentInfo.getContent()); } public byte[] getContent(InputDecryptorProvider inputDecryptorProvider) throws CMSException { try { return CMSUtils.streamToByteArray(getContentStream(inputDecryptorProvider).getContentStream()); } catch (IOException e) { throw new CMSException("unable to parse internal stream: " + e.getMessage(), e); } } public CMSTypedStream getContentStream(InputDecryptorProvider inputDecryptorProvider) throws CMSException { try { EncryptedContentInfo encContentInfo = encryptedData.getEncryptedContentInfo(); InputDecryptor decrytor = inputDecryptorProvider.get(encContentInfo.getContentEncryptionAlgorithm()); ByteArrayInputStream encIn = new ByteArrayInputStream(encContentInfo.getEncryptedContent().getOctets()); return new CMSTypedStream(encContentInfo.getContentType(), decrytor.getInputStream(encIn)); } catch (Exception e) { throw new CMSException("unable to create stream: " + e.getMessage(), e); } } /** * return the ContentInfo */ public ContentInfo toASN1Structure() { return contentInfo; } } bouncycastle-1.49.orig/src/org/bouncycastle/cms/CMSRuntimeException.java0000644000175000017500000000073410760650613026004 0ustar ebourgebourgpackage org.bouncycastle.cms; public class CMSRuntimeException extends RuntimeException { Exception e; public CMSRuntimeException( String name) { super(name); } public CMSRuntimeException( String name, Exception e) { super(name); this.e = e; } public Exception getUnderlyingException() { return e; } public Throwable getCause() { return e; } } bouncycastle-1.49.orig/src/org/bouncycastle/cms/SignerInfoGeneratorBuilder.java0000644000175000017500000001174411651132414027355 0ustar ebourgebourgpackage org.bouncycastle.cms; import org.bouncycastle.asn1.DEROctetString; import org.bouncycastle.asn1.cms.IssuerAndSerialNumber; import org.bouncycastle.asn1.cms.SignerIdentifier; import org.bouncycastle.cert.X509CertificateHolder; import org.bouncycastle.operator.ContentSigner; import org.bouncycastle.operator.DigestCalculatorProvider; import org.bouncycastle.operator.OperatorCreationException; /** * Builder for SignerInfo generator objects. */ public class SignerInfoGeneratorBuilder { private DigestCalculatorProvider digestProvider; private boolean directSignature; private CMSAttributeTableGenerator signedGen; private CMSAttributeTableGenerator unsignedGen; private CMSSignatureEncryptionAlgorithmFinder sigEncAlgFinder; /** * Base constructor. * * @param digestProvider a provider of digest calculators for the algorithms required in the signature and attribute calculations. */ public SignerInfoGeneratorBuilder(DigestCalculatorProvider digestProvider) { this(digestProvider, new DefaultCMSSignatureEncryptionAlgorithmFinder()); } /** * Base constructor. * * @param digestProvider a provider of digest calculators for the algorithms required in the signature and attribute calculations. */ public SignerInfoGeneratorBuilder(DigestCalculatorProvider digestProvider, CMSSignatureEncryptionAlgorithmFinder sigEncAlgFinder) { this.digestProvider = digestProvider; this.sigEncAlgFinder = sigEncAlgFinder; } /** * If the passed in flag is true, the signer signature will be based on the data, not * a collection of signed attributes, and no signed attributes will be included. * * @return the builder object */ public SignerInfoGeneratorBuilder setDirectSignature(boolean hasNoSignedAttributes) { this.directSignature = hasNoSignedAttributes; return this; } /** * Provide a custom signed attribute generator. * * @param signedGen a generator of signed attributes. * @return the builder object */ public SignerInfoGeneratorBuilder setSignedAttributeGenerator(CMSAttributeTableGenerator signedGen) { this.signedGen = signedGen; return this; } /** * Provide a generator of unsigned attributes. * * @param unsignedGen a generator for signed attributes. * @return the builder object */ public SignerInfoGeneratorBuilder setUnsignedAttributeGenerator(CMSAttributeTableGenerator unsignedGen) { this.unsignedGen = unsignedGen; return this; } /** * Build a generator with the passed in certHolder issuer and serial number as the signerIdentifier. * * @param contentSigner operator for generating the final signature in the SignerInfo with. * @param certHolder carrier for the X.509 certificate related to the contentSigner. * @return a SignerInfoGenerator * @throws OperatorCreationException if the generator cannot be built. */ public SignerInfoGenerator build(ContentSigner contentSigner, X509CertificateHolder certHolder) throws OperatorCreationException { SignerIdentifier sigId = new SignerIdentifier(new IssuerAndSerialNumber(certHolder.toASN1Structure())); SignerInfoGenerator sigInfoGen = createGenerator(contentSigner, sigId); sigInfoGen.setAssociatedCertificate(certHolder); return sigInfoGen; } /** * Build a generator with the passed in subjectKeyIdentifier as the signerIdentifier. If used you should * try to follow the calculation described in RFC 5280 section 4.2.1.2. * * @param contentSigner operator for generating the final signature in the SignerInfo with. * @param subjectKeyIdentifier key identifier to identify the public key for verifying the signature. * @return a SignerInfoGenerator * @throws OperatorCreationException if the generator cannot be built. */ public SignerInfoGenerator build(ContentSigner contentSigner, byte[] subjectKeyIdentifier) throws OperatorCreationException { SignerIdentifier sigId = new SignerIdentifier(new DEROctetString(subjectKeyIdentifier)); return createGenerator(contentSigner, sigId); } private SignerInfoGenerator createGenerator(ContentSigner contentSigner, SignerIdentifier sigId) throws OperatorCreationException { if (directSignature) { return new SignerInfoGenerator(sigId, contentSigner, digestProvider, sigEncAlgFinder, true); } if (signedGen != null || unsignedGen != null) { if (signedGen == null) { signedGen = new DefaultSignedAttributeTableGenerator(); } return new SignerInfoGenerator(sigId, contentSigner, digestProvider, sigEncAlgFinder, signedGen, unsignedGen); } return new SignerInfoGenerator(sigId, contentSigner, digestProvider, sigEncAlgFinder); } } bouncycastle-1.49.orig/src/org/bouncycastle/cms/SignerInformationStore.java0000644000175000017500000000533412151124554026606 0ustar ebourgebourgpackage org.bouncycastle.cms; import java.util.ArrayList; import java.util.Collection; import java.util.HashMap; import java.util.Iterator; import java.util.List; import java.util.Map; public class SignerInformationStore { private List all = new ArrayList(); private Map table = new HashMap(); public SignerInformationStore( Collection signerInfos) { Iterator it = signerInfos.iterator(); while (it.hasNext()) { SignerInformation signer = (SignerInformation)it.next(); SignerId sid = signer.getSID(); List list = (ArrayList)table.get(sid); if (list == null) { list = new ArrayList(1); table.put(sid, list); } list.add(signer); } this.all = new ArrayList(signerInfos); } /** * Return the first SignerInformation object that matches the * passed in selector. Null if there are no matches. * * @param selector to identify a signer * @return a single SignerInformation object. Null if none matches. */ public SignerInformation get( SignerId selector) { Collection list = getSigners(selector); return list.size() == 0 ? null : (SignerInformation) list.iterator().next(); } /** * Return the number of signers in the collection. * * @return number of signers identified. */ public int size() { return all.size(); } /** * Return all signers in the collection * * @return a collection of signers. */ public Collection getSigners() { return new ArrayList(all); } /** * Return possible empty collection with signers matching the passed in SignerId * * @param selector a signer id to select against. * @return a collection of SignerInformation objects. */ public Collection getSigners( SignerId selector) { if (selector.getIssuer() != null && selector.getSubjectKeyIdentifier() != null) { List results = new ArrayList(); Collection match1 = getSigners(new SignerId(selector.getIssuer(), selector.getSerialNumber())); if (match1 != null) { results.addAll(match1); } Collection match2 = getSigners(new SignerId(selector.getSubjectKeyIdentifier())); if (match2 != null) { results.addAll(match2); } return results; } else { List list = (ArrayList)table.get(selector); return list == null ? new ArrayList() : new ArrayList(list); } } } bouncycastle-1.49.orig/src/org/bouncycastle/cms/CMSCompressedDataStreamGenerator.java0000644000175000017500000001301300000000154030364 0ustar ebourgebourgpackage org.bouncycastle.cms; import java.io.IOException; import java.io.OutputStream; import java.util.zip.DeflaterOutputStream; import org.bouncycastle.asn1.ASN1Integer; import org.bouncycastle.asn1.ASN1ObjectIdentifier; import org.bouncycastle.asn1.BERSequenceGenerator; import org.bouncycastle.asn1.DERSequenceGenerator; import org.bouncycastle.asn1.cms.CMSObjectIdentifiers; import org.bouncycastle.operator.OutputCompressor; /** * General class for generating a compressed CMS message stream. *

    * A simple example of usage. *

    *
     *      CMSCompressedDataStreamGenerator gen = new CMSCompressedDataStreamGenerator();
     *      
     *      OutputStream cOut = gen.open(outputStream, new ZlibCompressor());
     *      
     *      cOut.write(data);
     *      
     *      cOut.close();
     * 
    */ public class CMSCompressedDataStreamGenerator { public static final String ZLIB = "1.2.840.113549.1.9.16.3.8"; private int _bufferSize; /** * base constructor */ public CMSCompressedDataStreamGenerator() { } /** * Set the underlying string size for encapsulated data * * @param bufferSize length of octet strings to buffer the data. */ public void setBufferSize( int bufferSize) { _bufferSize = bufferSize; } /** * @deprecated use open(OutputStream, ContentCompressor) */ public OutputStream open( OutputStream out, String compressionOID) throws IOException { return open(out, CMSObjectIdentifiers.data.getId(), compressionOID); } /** * @deprecated use open(OutputStream, ASN1ObjectIdentifier, ContentCompressor) */ public OutputStream open( OutputStream out, String contentOID, String compressionOID) throws IOException { BERSequenceGenerator sGen = new BERSequenceGenerator(out); sGen.addObject(CMSObjectIdentifiers.compressedData); // // Compressed Data // BERSequenceGenerator cGen = new BERSequenceGenerator(sGen.getRawOutputStream(), 0, true); cGen.addObject(new ASN1Integer(0)); // // AlgorithmIdentifier // DERSequenceGenerator algGen = new DERSequenceGenerator(cGen.getRawOutputStream()); algGen.addObject(new ASN1ObjectIdentifier(ZLIB)); algGen.close(); // // Encapsulated ContentInfo // BERSequenceGenerator eiGen = new BERSequenceGenerator(cGen.getRawOutputStream()); eiGen.addObject(new ASN1ObjectIdentifier(contentOID)); OutputStream octetStream = CMSUtils.createBEROctetOutputStream( eiGen.getRawOutputStream(), 0, true, _bufferSize); return new CmsCompressedOutputStream( new DeflaterOutputStream(octetStream), sGen, cGen, eiGen); } public OutputStream open( OutputStream out, OutputCompressor compressor) throws IOException { return open(CMSObjectIdentifiers.data, out, compressor); } /** * Open a compressing output stream. * * @param contentOID * @param out * @param compressor * @return * @throws IOException */ public OutputStream open( ASN1ObjectIdentifier contentOID, OutputStream out, OutputCompressor compressor) throws IOException { BERSequenceGenerator sGen = new BERSequenceGenerator(out); sGen.addObject(CMSObjectIdentifiers.compressedData); // // Compressed Data // BERSequenceGenerator cGen = new BERSequenceGenerator(sGen.getRawOutputStream(), 0, true); cGen.addObject(new ASN1Integer(0)); // // AlgorithmIdentifier // cGen.addObject(compressor.getAlgorithmIdentifier()); // // Encapsulated ContentInfo // BERSequenceGenerator eiGen = new BERSequenceGenerator(cGen.getRawOutputStream()); eiGen.addObject(contentOID); OutputStream octetStream = CMSUtils.createBEROctetOutputStream( eiGen.getRawOutputStream(), 0, true, _bufferSize); return new CmsCompressedOutputStream( compressor.getOutputStream(octetStream), sGen, cGen, eiGen); } private class CmsCompressedOutputStream extends OutputStream { private OutputStream _out; private BERSequenceGenerator _sGen; private BERSequenceGenerator _cGen; private BERSequenceGenerator _eiGen; CmsCompressedOutputStream( OutputStream out, BERSequenceGenerator sGen, BERSequenceGenerator cGen, BERSequenceGenerator eiGen) { _out = out; _sGen = sGen; _cGen = cGen; _eiGen = eiGen; } public void write( int b) throws IOException { _out.write(b); } public void write( byte[] bytes, int off, int len) throws IOException { _out.write(bytes, off, len); } public void write( byte[] bytes) throws IOException { _out.write(bytes); } public void close() throws IOException { _out.close(); _eiGen.close(); _cGen.close(); _sGen.close(); } } } bouncycastle-1.49.orig/src/org/bouncycastle/cms/KeyAgreeRecipientInfoGenerator.java0000644000175000017500000000634511737142463030171 0ustar ebourgebourgpackage org.bouncycastle.cms; import java.io.IOException; import org.bouncycastle.asn1.ASN1Encodable; import org.bouncycastle.asn1.ASN1EncodableVector; import org.bouncycastle.asn1.ASN1ObjectIdentifier; import org.bouncycastle.asn1.ASN1Sequence; import org.bouncycastle.asn1.DERNull; import org.bouncycastle.asn1.DEROctetString; import org.bouncycastle.asn1.cms.KeyAgreeRecipientInfo; import org.bouncycastle.asn1.cms.OriginatorIdentifierOrKey; import org.bouncycastle.asn1.cms.OriginatorPublicKey; import org.bouncycastle.asn1.cms.RecipientInfo; import org.bouncycastle.asn1.x509.AlgorithmIdentifier; import org.bouncycastle.asn1.x509.SubjectPublicKeyInfo; import org.bouncycastle.operator.GenericKey; public abstract class KeyAgreeRecipientInfoGenerator implements RecipientInfoGenerator { private ASN1ObjectIdentifier keyAgreementOID; private ASN1ObjectIdentifier keyEncryptionOID; private SubjectPublicKeyInfo originatorKeyInfo; protected KeyAgreeRecipientInfoGenerator(ASN1ObjectIdentifier keyAgreementOID, SubjectPublicKeyInfo originatorKeyInfo, ASN1ObjectIdentifier keyEncryptionOID) { this.originatorKeyInfo = originatorKeyInfo; this.keyAgreementOID = keyAgreementOID; this.keyEncryptionOID = keyEncryptionOID; } public RecipientInfo generate(GenericKey contentEncryptionKey) throws CMSException { OriginatorIdentifierOrKey originator = new OriginatorIdentifierOrKey( createOriginatorPublicKey(originatorKeyInfo)); ASN1EncodableVector params = new ASN1EncodableVector(); params.add(keyEncryptionOID); params.add(DERNull.INSTANCE); AlgorithmIdentifier keyEncAlg = new AlgorithmIdentifier(keyEncryptionOID, DERNull.INSTANCE); AlgorithmIdentifier keyAgreeAlg = new AlgorithmIdentifier(keyAgreementOID, keyEncAlg); ASN1Sequence recipients = generateRecipientEncryptedKeys(keyAgreeAlg, keyEncAlg, contentEncryptionKey); ASN1Encodable userKeyingMaterial = getUserKeyingMaterial(keyAgreeAlg); if (userKeyingMaterial != null) { try { return new RecipientInfo(new KeyAgreeRecipientInfo(originator, new DEROctetString(userKeyingMaterial), keyAgreeAlg, recipients)); } catch (IOException e) { throw new CMSException("unable to encode userKeyingMaterial: " + e.getMessage(), e); } } else { return new RecipientInfo(new KeyAgreeRecipientInfo(originator, null, keyAgreeAlg, recipients)); } } protected OriginatorPublicKey createOriginatorPublicKey(SubjectPublicKeyInfo originatorKeyInfo) { return new OriginatorPublicKey( new AlgorithmIdentifier(originatorKeyInfo.getAlgorithm().getAlgorithm(), DERNull.INSTANCE), originatorKeyInfo.getPublicKeyData().getBytes()); } protected abstract ASN1Sequence generateRecipientEncryptedKeys(AlgorithmIdentifier keyAgreeAlgorithm, AlgorithmIdentifier keyEncAlgorithm, GenericKey contentEncryptionKey) throws CMSException; protected abstract ASN1Encodable getUserKeyingMaterial(AlgorithmIdentifier keyAgreeAlgorithm) throws CMSException; }bouncycastle-1.49.orig/src/org/bouncycastle/cms/CMSUtils.java0000644000175000017500000002517712151127446023611 0ustar ebourgebourgpackage org.bouncycastle.cms; import java.io.IOException; import java.io.InputStream; import java.io.OutputStream; import java.security.NoSuchProviderException; import java.security.Provider; import java.security.Security; import java.security.cert.CRLException; import java.security.cert.CertStore; import java.security.cert.CertStoreException; import java.security.cert.CertificateEncodingException; import java.security.cert.X509CRL; import java.security.cert.X509Certificate; import java.util.ArrayList; import java.util.Collection; import java.util.Iterator; import java.util.List; import org.bouncycastle.asn1.ASN1Encodable; import org.bouncycastle.asn1.ASN1EncodableVector; import org.bouncycastle.asn1.ASN1InputStream; import org.bouncycastle.asn1.ASN1ObjectIdentifier; import org.bouncycastle.asn1.ASN1Primitive; import org.bouncycastle.asn1.ASN1Set; import org.bouncycastle.asn1.BEROctetStringGenerator; import org.bouncycastle.asn1.BERSet; import org.bouncycastle.asn1.DERSet; import org.bouncycastle.asn1.DERTaggedObject; import org.bouncycastle.asn1.cms.CMSObjectIdentifiers; import org.bouncycastle.asn1.cms.ContentInfo; import org.bouncycastle.asn1.cms.IssuerAndSerialNumber; import org.bouncycastle.asn1.cms.OtherRevocationInfoFormat; import org.bouncycastle.asn1.ocsp.OCSPResponse; import org.bouncycastle.asn1.ocsp.OCSPResponseStatus; import org.bouncycastle.asn1.x509.Certificate; import org.bouncycastle.asn1.x509.CertificateList; import org.bouncycastle.asn1.x509.TBSCertificate; import org.bouncycastle.cert.X509AttributeCertificateHolder; import org.bouncycastle.cert.X509CRLHolder; import org.bouncycastle.cert.X509CertificateHolder; import org.bouncycastle.operator.DigestCalculator; import org.bouncycastle.util.Store; import org.bouncycastle.util.io.Streams; import org.bouncycastle.util.io.TeeInputStream; import org.bouncycastle.util.io.TeeOutputStream; class CMSUtils { static ContentInfo readContentInfo( byte[] input) throws CMSException { // enforce limit checking as from a byte array return readContentInfo(new ASN1InputStream(input)); } static ContentInfo readContentInfo( InputStream input) throws CMSException { // enforce some limit checking return readContentInfo(new ASN1InputStream(input)); } static List getCertificatesFromStore(CertStore certStore) throws CertStoreException, CMSException { List certs = new ArrayList(); try { for (Iterator it = certStore.getCertificates(null).iterator(); it.hasNext();) { X509Certificate c = (X509Certificate)it.next(); certs.add(Certificate.getInstance(ASN1Primitive.fromByteArray(c.getEncoded()))); } return certs; } catch (IllegalArgumentException e) { throw new CMSException("error processing certs", e); } catch (IOException e) { throw new CMSException("error processing certs", e); } catch (CertificateEncodingException e) { throw new CMSException("error encoding certs", e); } } static List getCertificatesFromStore(Store certStore) throws CMSException { List certs = new ArrayList(); try { for (Iterator it = certStore.getMatches(null).iterator(); it.hasNext();) { X509CertificateHolder c = (X509CertificateHolder)it.next(); certs.add(c.toASN1Structure()); } return certs; } catch (ClassCastException e) { throw new CMSException("error processing certs", e); } } static List getAttributeCertificatesFromStore(Store attrStore) throws CMSException { List certs = new ArrayList(); try { for (Iterator it = attrStore.getMatches(null).iterator(); it.hasNext();) { X509AttributeCertificateHolder attrCert = (X509AttributeCertificateHolder)it.next(); certs.add(new DERTaggedObject(false, 2, attrCert.toASN1Structure())); } return certs; } catch (ClassCastException e) { throw new CMSException("error processing certs", e); } } static List getCRLsFromStore(CertStore certStore) throws CertStoreException, CMSException { List crls = new ArrayList(); try { for (Iterator it = certStore.getCRLs(null).iterator(); it.hasNext();) { X509CRL c = (X509CRL)it.next(); crls.add(CertificateList.getInstance(ASN1Primitive.fromByteArray(c.getEncoded()))); } return crls; } catch (IllegalArgumentException e) { throw new CMSException("error processing crls", e); } catch (IOException e) { throw new CMSException("error processing crls", e); } catch (CRLException e) { throw new CMSException("error encoding crls", e); } } static List getCRLsFromStore(Store crlStore) throws CMSException { List certs = new ArrayList(); try { for (Iterator it = crlStore.getMatches(null).iterator(); it.hasNext();) { X509CRLHolder c = (X509CRLHolder)it.next(); certs.add(c.toASN1Structure()); } return certs; } catch (ClassCastException e) { throw new CMSException("error processing certs", e); } } static Collection getOthersFromStore(ASN1ObjectIdentifier otherRevocationInfoFormat, Store otherRevocationInfos) { List others = new ArrayList(); for (Iterator it = otherRevocationInfos.getMatches(null).iterator(); it.hasNext();) { ASN1Encodable info = (ASN1Encodable)it.next(); if (CMSObjectIdentifiers.id_ri_ocsp_response.equals(otherRevocationInfoFormat)) { OCSPResponse resp = OCSPResponse.getInstance(info); if (resp.getResponseStatus().getValue().intValue() != OCSPResponseStatus.SUCCESSFUL) { throw new IllegalArgumentException("cannot add unsuccessful OCSP response to CMS SignedData"); } } others.add(new DERTaggedObject(false, 1, new OtherRevocationInfoFormat(otherRevocationInfoFormat, info))); } return others; } static ASN1Set createBerSetFromList(List derObjects) { ASN1EncodableVector v = new ASN1EncodableVector(); for (Iterator it = derObjects.iterator(); it.hasNext();) { v.add((ASN1Encodable)it.next()); } return new BERSet(v); } static ASN1Set createDerSetFromList(List derObjects) { ASN1EncodableVector v = new ASN1EncodableVector(); for (Iterator it = derObjects.iterator(); it.hasNext();) { v.add((ASN1Encodable)it.next()); } return new DERSet(v); } static OutputStream createBEROctetOutputStream(OutputStream s, int tagNo, boolean isExplicit, int bufferSize) throws IOException { BEROctetStringGenerator octGen = new BEROctetStringGenerator(s, tagNo, isExplicit); if (bufferSize != 0) { return octGen.getOctetOutputStream(new byte[bufferSize]); } return octGen.getOctetOutputStream(); } static TBSCertificate getTBSCertificateStructure( X509Certificate cert) { try { return TBSCertificate.getInstance( ASN1Primitive.fromByteArray(cert.getTBSCertificate())); } catch (Exception e) { throw new IllegalArgumentException( "can't extract TBS structure from this cert"); } } static IssuerAndSerialNumber getIssuerAndSerialNumber(X509Certificate cert) { TBSCertificate tbsCert = getTBSCertificateStructure(cert); return new IssuerAndSerialNumber(tbsCert.getIssuer(), tbsCert.getSerialNumber().getValue()); } private static ContentInfo readContentInfo( ASN1InputStream in) throws CMSException { try { return ContentInfo.getInstance(in.readObject()); } catch (IOException e) { throw new CMSException("IOException reading content.", e); } catch (ClassCastException e) { throw new CMSException("Malformed content.", e); } catch (IllegalArgumentException e) { throw new CMSException("Malformed content.", e); } } public static byte[] streamToByteArray( InputStream in) throws IOException { return Streams.readAll(in); } public static byte[] streamToByteArray( InputStream in, int limit) throws IOException { return Streams.readAllLimited(in, limit); } public static Provider getProvider(String providerName) throws NoSuchProviderException { if (providerName != null) { Provider prov = Security.getProvider(providerName); if (prov != null) { return prov; } throw new NoSuchProviderException("provider " + providerName + " not found."); } return null; } static InputStream attachDigestsToInputStream(Collection digests, InputStream s) { InputStream result = s; Iterator it = digests.iterator(); while (it.hasNext()) { DigestCalculator digest = (DigestCalculator)it.next(); result = new TeeInputStream(result, digest.getOutputStream()); } return result; } static OutputStream attachSignersToOutputStream(Collection signers, OutputStream s) { OutputStream result = s; Iterator it = signers.iterator(); while (it.hasNext()) { SignerInfoGenerator signerGen = (SignerInfoGenerator)it.next(); result = getSafeTeeOutputStream(result, signerGen.getCalculatingOutputStream()); } return result; } static OutputStream getSafeOutputStream(OutputStream s) { return s == null ? new NullOutputStream() : s; } static OutputStream getSafeTeeOutputStream(OutputStream s1, OutputStream s2) { return s1 == null ? getSafeOutputStream(s2) : s2 == null ? getSafeOutputStream(s1) : new TeeOutputStream( s1, s2); } } bouncycastle-1.49.orig/src/org/bouncycastle/cms/SignerInformationVerifierProvider.java0000644000175000017500000000107412123710431030767 0ustar ebourgebourgpackage org.bouncycastle.cms; import org.bouncycastle.operator.OperatorCreationException; public interface SignerInformationVerifierProvider { /** * Return a SignerInformationVerifierProvider suitable for the passed in SID. * * @param sid the SignerId we are trying to match for. * @return a verifier if one is available, null otherwise. * @throws OperatorCreationException if creation of the verifier fails when it should suceed. */ public SignerInformationVerifier get(SignerId sid) throws OperatorCreationException; } bouncycastle-1.49.orig/src/org/bouncycastle/cms/CMSConfig.java0000644000175000017500000000213311737144163023705 0ustar ebourgebourgpackage org.bouncycastle.cms; import org.bouncycastle.asn1.ASN1ObjectIdentifier; public class CMSConfig { /** * Set the mapping for the encryption algorithm used in association with a SignedData generation * or interpretation. * * @param oid object identifier to map. * @param algorithmName algorithm name to use. */ public static void setSigningEncryptionAlgorithmMapping(String oid, String algorithmName) { ASN1ObjectIdentifier id = new ASN1ObjectIdentifier(oid); CMSSignedHelper.INSTANCE.setSigningEncryptionAlgorithmMapping(id, algorithmName); } /** * Set the mapping for the digest algorithm to use in conjunction with a SignedData generation * or interpretation. * * @param oid object identifier to map. * @param algorithmName algorithm name to use. */ public static void setSigningDigestAlgorithmMapping(String oid, String algorithmName) { ASN1ObjectIdentifier id = new ASN1ObjectIdentifier(oid); CMSSignedHelper.INSTANCE.setSigningDigestAlgorithmMapping(id, algorithmName); } } bouncycastle-1.49.orig/src/org/bouncycastle/cms/CMSCompressedDataParser.java0000644000175000017500000000655111624615370026561 0ustar ebourgebourgpackage org.bouncycastle.cms; import java.io.ByteArrayInputStream; import java.io.IOException; import java.io.InputStream; import java.util.zip.InflaterInputStream; import org.bouncycastle.asn1.ASN1OctetStringParser; import org.bouncycastle.asn1.ASN1SequenceParser; import org.bouncycastle.asn1.BERTags; import org.bouncycastle.asn1.cms.CompressedDataParser; import org.bouncycastle.asn1.cms.ContentInfoParser; import org.bouncycastle.operator.InputExpander; import org.bouncycastle.operator.InputExpanderProvider; /** * Class for reading a CMS Compressed Data stream. *
     *     CMSCompressedDataParser cp = new CMSCompressedDataParser(inputStream);
     *      
     *     process(cp.getContent(new ZlibExpanderProvider()).getContentStream());
     * 
    * Note: this class does not introduce buffering - if you are processing large files you should create * the parser with: *
     *      CMSCompressedDataParser     ep = new CMSCompressedDataParser(new BufferedInputStream(inputStream, bufSize));
     *  
    * where bufSize is a suitably large buffer size. */ public class CMSCompressedDataParser extends CMSContentInfoParser { public CMSCompressedDataParser( byte[] compressedData) throws CMSException { this(new ByteArrayInputStream(compressedData)); } public CMSCompressedDataParser( InputStream compressedData) throws CMSException { super(compressedData); } /** * @deprecated use getContent(InputExpandedProvider) */ public CMSTypedStream getContent() throws CMSException { try { CompressedDataParser comData = new CompressedDataParser((ASN1SequenceParser)_contentInfo.getContent(BERTags.SEQUENCE)); ContentInfoParser content = comData.getEncapContentInfo(); ASN1OctetStringParser bytes = (ASN1OctetStringParser)content.getContent(BERTags.OCTET_STRING); return new CMSTypedStream(content.getContentType().toString(), new InflaterInputStream(bytes.getOctetStream())); } catch (IOException e) { throw new CMSException("IOException reading compressed content.", e); } } /** * Return a typed stream which will allow the reading of the compressed content in * expanded form. * * @param expanderProvider a provider of expander algorithm implementations. * @return a type stream which will yield the un-compressed content. * @throws CMSException if there is an exception parsing the CompressedData object. */ public CMSTypedStream getContent(InputExpanderProvider expanderProvider) throws CMSException { try { CompressedDataParser comData = new CompressedDataParser((ASN1SequenceParser)_contentInfo.getContent(BERTags.SEQUENCE)); ContentInfoParser content = comData.getEncapContentInfo(); InputExpander expander = expanderProvider.get(comData.getCompressionAlgorithmIdentifier()); ASN1OctetStringParser bytes = (ASN1OctetStringParser)content.getContent(BERTags.OCTET_STRING); return new CMSTypedStream(content.getContentType().getId(), expander.getInputStream(bytes.getOctetStream())); } catch (IOException e) { throw new CMSException("IOException reading compressed content.", e); } } } bouncycastle-1.49.orig/src/org/bouncycastle/cms/CMSAuthEnvelopedData.java0000644000175000017500000000476511605576342026054 0ustar ebourgebourgpackage org.bouncycastle.cms; import java.io.IOException; import java.io.InputStream; import org.bouncycastle.asn1.ASN1Set; import org.bouncycastle.asn1.cms.AuthEnvelopedData; import org.bouncycastle.asn1.cms.ContentInfo; import org.bouncycastle.asn1.cms.EncryptedContentInfo; import org.bouncycastle.asn1.cms.OriginatorInfo; import org.bouncycastle.asn1.x509.AlgorithmIdentifier; /** * containing class for an CMS AuthEnveloped Data object */ class CMSAuthEnvelopedData { RecipientInformationStore recipientInfoStore; ContentInfo contentInfo; private OriginatorInfo originator; private AlgorithmIdentifier authEncAlg; private ASN1Set authAttrs; private byte[] mac; private ASN1Set unauthAttrs; public CMSAuthEnvelopedData(byte[] authEnvData) throws CMSException { this(CMSUtils.readContentInfo(authEnvData)); } public CMSAuthEnvelopedData(InputStream authEnvData) throws CMSException { this(CMSUtils.readContentInfo(authEnvData)); } public CMSAuthEnvelopedData(ContentInfo contentInfo) throws CMSException { this.contentInfo = contentInfo; AuthEnvelopedData authEnvData = AuthEnvelopedData.getInstance(contentInfo.getContent()); this.originator = authEnvData.getOriginatorInfo(); // // read the recipients // ASN1Set recipientInfos = authEnvData.getRecipientInfos(); // // read the auth-encrypted content info // EncryptedContentInfo authEncInfo = authEnvData.getAuthEncryptedContentInfo(); this.authEncAlg = authEncInfo.getContentEncryptionAlgorithm(); // final CMSProcessable processable = new CMSProcessableByteArray( // authEncInfo.getEncryptedContent().getOctets()); CMSSecureReadable secureReadable = new CMSSecureReadable() { public InputStream getInputStream() throws IOException, CMSException { return null; } }; // // build the RecipientInformationStore // this.recipientInfoStore = CMSEnvelopedHelper.buildRecipientInformationStore( recipientInfos, this.authEncAlg, secureReadable); // FIXME These need to be passed to the AEAD cipher as AAD (Additional Authenticated Data) this.authAttrs = authEnvData.getAuthAttrs(); this.mac = authEnvData.getMac().getOctets(); this.unauthAttrs = authEnvData.getUnauthAttrs(); } } bouncycastle-1.49.orig/src/org/bouncycastle/cms/CMSTypedStream.java0000644000175000017500000000363711530416360024743 0ustar ebourgebourgpackage org.bouncycastle.cms; import java.io.BufferedInputStream; import java.io.FilterInputStream; import java.io.IOException; import java.io.InputStream; import org.bouncycastle.asn1.ASN1ObjectIdentifier; import org.bouncycastle.asn1.pkcs.PKCSObjectIdentifiers; import org.bouncycastle.util.io.Streams; public class CMSTypedStream { private static final int BUF_SIZ = 32 * 1024; private final ASN1ObjectIdentifier _oid; private final InputStream _in; public CMSTypedStream( InputStream in) { this(PKCSObjectIdentifiers.data.getId(), in, BUF_SIZ); } public CMSTypedStream( String oid, InputStream in) { this(new ASN1ObjectIdentifier(oid), in, BUF_SIZ); } public CMSTypedStream( String oid, InputStream in, int bufSize) { this(new ASN1ObjectIdentifier(oid), in, bufSize); } public CMSTypedStream( ASN1ObjectIdentifier oid, InputStream in) { this(oid, in, BUF_SIZ); } public CMSTypedStream( ASN1ObjectIdentifier oid, InputStream in, int bufSize) { _oid = oid; _in = new FullReaderStream(new BufferedInputStream(in, bufSize)); } public ASN1ObjectIdentifier getContentType() { return _oid; } public InputStream getContentStream() { return _in; } public void drain() throws IOException { Streams.drain(_in); _in.close(); } private static class FullReaderStream extends FilterInputStream { FullReaderStream(InputStream in) { super(in); } public int read(byte[] buf, int off, int len) throws IOException { int totalRead = Streams.readFully(super.in, buf, off, len); return totalRead > 0 ? totalRead : -1; } } } bouncycastle-1.49.orig/src/org/bouncycastle/cms/CMSSignedDataStreamGenerator.java0000644000175000017500000010764712151251423027533 0ustar ebourgebourgpackage org.bouncycastle.cms; import java.io.IOException; import java.io.OutputStream; import java.security.InvalidKeyException; import java.security.NoSuchAlgorithmException; import java.security.NoSuchProviderException; import java.security.PrivateKey; import java.security.Provider; import java.security.SecureRandom; import java.security.cert.CertificateEncodingException; import java.security.cert.X509Certificate; import java.util.Iterator; import java.util.List; import org.bouncycastle.asn1.ASN1EncodableVector; import org.bouncycastle.asn1.ASN1Integer; import org.bouncycastle.asn1.ASN1ObjectIdentifier; import org.bouncycastle.asn1.ASN1Set; import org.bouncycastle.asn1.ASN1TaggedObject; import org.bouncycastle.asn1.BERSequenceGenerator; import org.bouncycastle.asn1.BERTaggedObject; import org.bouncycastle.asn1.DERSet; import org.bouncycastle.asn1.cms.AttributeTable; import org.bouncycastle.asn1.cms.CMSObjectIdentifiers; import org.bouncycastle.asn1.cms.SignerInfo; import org.bouncycastle.cms.jcajce.JcaSignerInfoGeneratorBuilder; import org.bouncycastle.operator.ContentSigner; import org.bouncycastle.operator.OperatorCreationException; import org.bouncycastle.operator.jcajce.JcaContentSignerBuilder; import org.bouncycastle.operator.jcajce.JcaDigestCalculatorProviderBuilder; /** * General class for generating a pkcs7-signature message stream. *

    * A simple example of usage. *

    *
     *      X509Certificate signCert = ...
     *      certList.add(signCert);
     *
     *      Store           certs = new JcaCertStore(certList);
     *      ContentSigner sha1Signer = new JcaContentSignerBuilder("SHA1withRSA").setProvider("BC").build(signKP.getPrivate());
     *
     *      CMSSignedDataStreamGenerator gen = new CMSSignedDataStreamGenerator();
     *  
     *      gen.addSignerInfoGenerator(
     *                new JcaSignerInfoGeneratorBuilder(
     *                     new JcaDigestCalculatorProviderBuilder().setProvider("BC").build())
     *                     .build(sha1Signer, signCert));
     *
     *      gen.addCertificates(certs);
     *  
     *      OutputStream sigOut = gen.open(bOut);
     *  
     *      sigOut.write("Hello World!".getBytes());
     *      
     *      sigOut.close();
     * 
    */ public class CMSSignedDataStreamGenerator extends CMSSignedGenerator { private int _bufferSize; /** * base constructor */ public CMSSignedDataStreamGenerator() { } /** * constructor allowing specific source of randomness * @param rand instance of SecureRandom to use * @deprecated no longer required if the addSignerInfoGenerator method is used. */ public CMSSignedDataStreamGenerator( SecureRandom rand) { super(rand); } /** * Set the underlying string size for encapsulated data * * @param bufferSize length of octet strings to buffer the data. */ public void setBufferSize( int bufferSize) { _bufferSize = bufferSize; } /** * add a signer - no attributes other than the default ones will be * provided here. * @throws NoSuchProviderException * @throws NoSuchAlgorithmException * @throws InvalidKeyException * @deprecated use addSignedInfoGenerator */ public void addSigner( PrivateKey key, X509Certificate cert, String digestOID, String sigProvider) throws NoSuchAlgorithmException, NoSuchProviderException, InvalidKeyException { addSigner(key, cert, digestOID, CMSUtils.getProvider(sigProvider)); } /** * add a signer - no attributes other than the default ones will be * provided here. * @throws NoSuchAlgorithmException * @throws InvalidKeyException * @deprecated use addSignedInfoGenerator */ public void addSigner( PrivateKey key, X509Certificate cert, String digestOID, Provider sigProvider) throws NoSuchAlgorithmException, NoSuchProviderException, InvalidKeyException { addSigner(key, cert, digestOID, new DefaultSignedAttributeTableGenerator(), (CMSAttributeTableGenerator)null, sigProvider); } /** * add a signer, specifying the digest encryption algorithm - no attributes other than the default ones will be * provided here. * @throws NoSuchProviderException * @throws NoSuchAlgorithmException * @throws InvalidKeyException * @deprecated use addSignedInfoGenerator */ public void addSigner( PrivateKey key, X509Certificate cert, String encryptionOID, String digestOID, String sigProvider) throws NoSuchAlgorithmException, NoSuchProviderException, InvalidKeyException { addSigner(key, cert, encryptionOID, digestOID, CMSUtils.getProvider(sigProvider)); } /** * add a signer, specifying digest encryptionOID - no attributes other than the default ones will be * provided here. * @throws NoSuchAlgorithmException * @throws InvalidKeyException * @deprecated use addSignedInfoGenerator */ public void addSigner( PrivateKey key, X509Certificate cert, String encryptionOID, String digestOID, Provider sigProvider) throws NoSuchAlgorithmException, NoSuchProviderException, InvalidKeyException { addSigner(key, cert, encryptionOID, digestOID, new DefaultSignedAttributeTableGenerator(), (CMSAttributeTableGenerator)null, sigProvider); } /** * add a signer with extra signed/unsigned attributes. * @throws NoSuchProviderException * @throws NoSuchAlgorithmException * @throws InvalidKeyException * @deprecated use addSignedInfoGenerator */ public void addSigner( PrivateKey key, X509Certificate cert, String digestOID, AttributeTable signedAttr, AttributeTable unsignedAttr, String sigProvider) throws NoSuchAlgorithmException, NoSuchProviderException, InvalidKeyException { addSigner(key, cert, digestOID, signedAttr, unsignedAttr, CMSUtils.getProvider(sigProvider)); } /** * add a signer with extra signed/unsigned attributes. * @throws NoSuchAlgorithmException * @throws InvalidKeyException * @deprecated use addSignedInfoGenerator */ public void addSigner( PrivateKey key, X509Certificate cert, String digestOID, AttributeTable signedAttr, AttributeTable unsignedAttr, Provider sigProvider) throws NoSuchAlgorithmException, InvalidKeyException { addSigner(key, cert, digestOID, new DefaultSignedAttributeTableGenerator(signedAttr), new SimpleAttributeTableGenerator(unsignedAttr), sigProvider); } /** * add a signer with extra signed/unsigned attributes - specifying digest * encryption algorithm. * @throws NoSuchProviderException * @throws NoSuchAlgorithmException * @throws InvalidKeyException * @deprecated use addSignedInfoGenerator */ public void addSigner( PrivateKey key, X509Certificate cert, String encryptionOID, String digestOID, AttributeTable signedAttr, AttributeTable unsignedAttr, String sigProvider) throws NoSuchAlgorithmException, NoSuchProviderException, InvalidKeyException { addSigner(key, cert, encryptionOID, digestOID, signedAttr, unsignedAttr, CMSUtils.getProvider(sigProvider)); } /** * add a signer with extra signed/unsigned attributes and the digest encryption algorithm. * @throws NoSuchAlgorithmException * @throws InvalidKeyException * @deprecated use addSignedInfoGenerator */ public void addSigner( PrivateKey key, X509Certificate cert, String encryptionOID, String digestOID, AttributeTable signedAttr, AttributeTable unsignedAttr, Provider sigProvider) throws NoSuchAlgorithmException, InvalidKeyException { addSigner(key, cert, encryptionOID, digestOID, new DefaultSignedAttributeTableGenerator(signedAttr), new SimpleAttributeTableGenerator(unsignedAttr), sigProvider); } /** * @deprecated use addSignedInfoGenerator */ public void addSigner( PrivateKey key, X509Certificate cert, String digestOID, CMSAttributeTableGenerator signedAttrGenerator, CMSAttributeTableGenerator unsignedAttrGenerator, String sigProvider) throws NoSuchAlgorithmException, NoSuchProviderException, InvalidKeyException { addSigner(key, cert, digestOID, signedAttrGenerator, unsignedAttrGenerator, CMSUtils.getProvider(sigProvider)); } /** * @deprecated use addSignedInfoGenerator */ public void addSigner( PrivateKey key, X509Certificate cert, String digestOID, CMSAttributeTableGenerator signedAttrGenerator, CMSAttributeTableGenerator unsignedAttrGenerator, Provider sigProvider) throws NoSuchAlgorithmException, InvalidKeyException { addSigner(key, cert, getEncOID(key, digestOID), digestOID, signedAttrGenerator, unsignedAttrGenerator, sigProvider); } /** * @deprecated use addSignedInfoGenerator */ public void addSigner( PrivateKey key, X509Certificate cert, String encryptionOID, String digestOID, CMSAttributeTableGenerator signedAttrGenerator, CMSAttributeTableGenerator unsignedAttrGenerator, String sigProvider) throws NoSuchAlgorithmException, NoSuchProviderException, InvalidKeyException { addSigner(key, cert, encryptionOID, digestOID, signedAttrGenerator, unsignedAttrGenerator, CMSUtils.getProvider(sigProvider)); } /** * @deprecated use addSignedInfoGenerator */ public void addSigner( PrivateKey key, X509Certificate cert, String encryptionOID, String digestOID, CMSAttributeTableGenerator signedAttrGenerator, CMSAttributeTableGenerator unsignedAttrGenerator, Provider sigProvider) throws NoSuchAlgorithmException, InvalidKeyException { addSigner(key, cert, encryptionOID, digestOID, signedAttrGenerator, unsignedAttrGenerator, sigProvider, sigProvider); } /** * add a signer - no attributes other than the default ones will be * provided here. * @throws NoSuchProviderException * @throws NoSuchAlgorithmException * @throws InvalidKeyException * @deprecated use addSignedInfoGenerator */ public void addSigner( PrivateKey key, byte[] subjectKeyID, String digestOID, String sigProvider) throws NoSuchAlgorithmException, NoSuchProviderException, InvalidKeyException { addSigner(key, subjectKeyID, digestOID, CMSUtils.getProvider(sigProvider)); } /** * add a signer - no attributes other than the default ones will be * provided here. * @throws NoSuchAlgorithmException * @throws InvalidKeyException * @deprecated use addSignedInfoGenerator */ public void addSigner( PrivateKey key, byte[] subjectKeyID, String digestOID, Provider sigProvider) throws NoSuchAlgorithmException, NoSuchProviderException, InvalidKeyException { addSigner(key, subjectKeyID, digestOID, new DefaultSignedAttributeTableGenerator(), (CMSAttributeTableGenerator)null, sigProvider); } /** * add a signer - no attributes other than the default ones will be * provided here. * @throws NoSuchProviderException * @throws NoSuchAlgorithmException * @throws InvalidKeyException * @deprecated use addSignedInfoGenerator */ public void addSigner( PrivateKey key, byte[] subjectKeyID, String encryptionOID, String digestOID, String sigProvider) throws NoSuchAlgorithmException, NoSuchProviderException, InvalidKeyException { addSigner(key, subjectKeyID, encryptionOID, digestOID, CMSUtils.getProvider(sigProvider)); } /** * add a signer - no attributes other than the default ones will be * provided here, specifying the digest encryption algorithm. * * @throws NoSuchAlgorithmException * @throws InvalidKeyException * @deprecated use addSignerInfoGenerator */ public void addSigner( PrivateKey key, byte[] subjectKeyID, String encryptionOID, String digestOID, Provider sigProvider) throws NoSuchAlgorithmException, NoSuchProviderException, InvalidKeyException { addSigner(key, subjectKeyID, encryptionOID, digestOID, new DefaultSignedAttributeTableGenerator(), (CMSAttributeTableGenerator)null, sigProvider); } /** * add a signer with extra signed/unsigned attributes. * @throws NoSuchProviderException * @throws NoSuchAlgorithmException * @throws InvalidKeyException * @deprecated use addSignerInfoGenerator */ public void addSigner( PrivateKey key, byte[] subjectKeyID, String digestOID, AttributeTable signedAttr, AttributeTable unsignedAttr, String sigProvider) throws NoSuchAlgorithmException, NoSuchProviderException, InvalidKeyException { addSigner(key, subjectKeyID, digestOID, signedAttr, unsignedAttr, CMSUtils.getProvider(sigProvider)); } /** * add a signer with extra signed/unsigned attributes. * @throws NoSuchAlgorithmException * @throws InvalidKeyException * @deprecated use addSignerInfoGenerator */ public void addSigner( PrivateKey key, byte[] subjectKeyID, String digestOID, AttributeTable signedAttr, AttributeTable unsignedAttr, Provider sigProvider) throws NoSuchAlgorithmException, InvalidKeyException { addSigner(key, subjectKeyID, digestOID, new DefaultSignedAttributeTableGenerator(signedAttr), new SimpleAttributeTableGenerator(unsignedAttr), sigProvider); } /** * @deprecated use addSignerInfoGenerator */ public void addSigner( PrivateKey key, byte[] subjectKeyID, String digestOID, CMSAttributeTableGenerator signedAttrGenerator, CMSAttributeTableGenerator unsignedAttrGenerator, String sigProvider) throws NoSuchAlgorithmException, NoSuchProviderException, InvalidKeyException { addSigner(key, subjectKeyID, digestOID, signedAttrGenerator, unsignedAttrGenerator, CMSUtils.getProvider(sigProvider)); } /** * @deprecated use addSignerInfoGenerator */ public void addSigner( PrivateKey key, byte[] subjectKeyID, String digestOID, CMSAttributeTableGenerator signedAttrGenerator, CMSAttributeTableGenerator unsignedAttrGenerator, Provider sigProvider) throws NoSuchAlgorithmException, InvalidKeyException { addSigner(key, subjectKeyID, getEncOID(key, digestOID), digestOID, signedAttrGenerator, unsignedAttrGenerator, sigProvider); } /** * @deprecated use addSignerInfoGenerator */ public void addSigner( PrivateKey key, byte[] subjectKeyID, String encryptionOID, String digestOID, CMSAttributeTableGenerator signedAttrGenerator, CMSAttributeTableGenerator unsignedAttrGenerator, String sigProvider) throws NoSuchAlgorithmException, NoSuchProviderException, InvalidKeyException { addSigner(key, subjectKeyID, encryptionOID, digestOID, signedAttrGenerator, unsignedAttrGenerator, CMSUtils.getProvider(sigProvider)); } /** * @deprecated use addSignerInfoGenerator */ public void addSigner( PrivateKey key, byte[] subjectKeyID, String encryptionOID, String digestOID, CMSAttributeTableGenerator signedAttrGenerator, CMSAttributeTableGenerator unsignedAttrGenerator, Provider sigProvider) throws NoSuchAlgorithmException, InvalidKeyException { addSigner(key, subjectKeyID, encryptionOID, digestOID, signedAttrGenerator, unsignedAttrGenerator, sigProvider, sigProvider); } /** * @deprecated use addSignerInfoGenerator */ public void addSigner( PrivateKey key, X509Certificate cert, String encryptionOID, String digestOID, CMSAttributeTableGenerator signedAttrGenerator, CMSAttributeTableGenerator unsignedAttrGenerator, Provider sigProvider, Provider digProvider) throws NoSuchAlgorithmException, InvalidKeyException { doAddSigner(key, cert, encryptionOID, digestOID, signedAttrGenerator, unsignedAttrGenerator, sigProvider, digProvider); } private void doAddSigner(PrivateKey key, Object signerId, String encryptionOID, String digestOID, CMSAttributeTableGenerator signedAttrGenerator, CMSAttributeTableGenerator unsignedAttrGenerator, Provider sigProvider, Provider digProvider) throws NoSuchAlgorithmException, InvalidKeyException { String digestName = CMSSignedHelper.INSTANCE.getDigestAlgName(digestOID); String signatureName = digestName + "with" + CMSSignedHelper.INSTANCE.getEncryptionAlgName(encryptionOID); JcaContentSignerBuilder signerBuilder; try { signerBuilder = new JcaContentSignerBuilder(signatureName).setSecureRandom(rand); } catch (IllegalArgumentException e) { throw new NoSuchAlgorithmException(e.getMessage()); } if (sigProvider != null) { signerBuilder.setProvider(sigProvider); } try { JcaDigestCalculatorProviderBuilder calculatorProviderBuilder = new JcaDigestCalculatorProviderBuilder(); if (digProvider != null && !digProvider.getName().equalsIgnoreCase("SunRsaSign")) { calculatorProviderBuilder.setProvider(digProvider); } JcaSignerInfoGeneratorBuilder builder = new JcaSignerInfoGeneratorBuilder(calculatorProviderBuilder.build()); builder.setSignedAttributeGenerator(signedAttrGenerator); builder.setUnsignedAttributeGenerator(unsignedAttrGenerator); try { ContentSigner contentSigner = signerBuilder.build(key); if (signerId instanceof X509Certificate) { addSignerInfoGenerator(builder.build(contentSigner, (X509Certificate)signerId)); } else { addSignerInfoGenerator(builder.build(contentSigner, (byte[])signerId)); } } catch (OperatorCreationException e) { if (e.getCause() instanceof NoSuchAlgorithmException) { throw (NoSuchAlgorithmException)e.getCause(); } if (e.getCause() instanceof InvalidKeyException) { throw (InvalidKeyException)e.getCause(); } } } catch (OperatorCreationException e) { throw new NoSuchAlgorithmException("unable to create operators: " + e.getMessage()); } catch (CertificateEncodingException e) { throw new IllegalStateException("unable to encode certificate"); } } /** * @deprecated use addSignerInfoGenerator */ public void addSigner( PrivateKey key, byte[] subjectKeyID, String encryptionOID, String digestOID, CMSAttributeTableGenerator signedAttrGenerator, CMSAttributeTableGenerator unsignedAttrGenerator, Provider sigProvider, Provider digProvider) throws NoSuchAlgorithmException, InvalidKeyException { doAddSigner(key, subjectKeyID, encryptionOID, digestOID, signedAttrGenerator, unsignedAttrGenerator, sigProvider, digProvider); } /** * generate a signed object that for a CMS Signed Data * object using the given provider. */ public OutputStream open( OutputStream out) throws IOException { return open(out, false); } /** * generate a signed object that for a CMS Signed Data * object using the given provider - if encapsulate is true a copy * of the message will be included in the signature with the * default content type "data". */ public OutputStream open( OutputStream out, boolean encapsulate) throws IOException { return open(CMSObjectIdentifiers.data, out, encapsulate); } /** * generate a signed object that for a CMS Signed Data * object using the given provider - if encapsulate is true a copy * of the message will be included in the signature with the * default content type "data". If dataOutputStream is non null the data * being signed will be written to the stream as it is processed. * @param out stream the CMS object is to be written to. * @param encapsulate true if data should be encapsulated. * @param dataOutputStream output stream to copy the data being signed to. */ public OutputStream open( OutputStream out, boolean encapsulate, OutputStream dataOutputStream) throws IOException { return open(CMSObjectIdentifiers.data, out, encapsulate, dataOutputStream); } /** * @deprecated use open(ASN1ObjectIdentifier, OutputStream, boolean) */ public OutputStream open( OutputStream out, String eContentType, boolean encapsulate) throws IOException { return open(out, eContentType, encapsulate, null); } /** * generate a signed object that for a CMS Signed Data * object using the given provider - if encapsulate is true a copy * of the message will be included in the signature. The content type * is set according to the OID represented by the string signedContentType. */ public OutputStream open( ASN1ObjectIdentifier eContentType, OutputStream out, boolean encapsulate) throws IOException { return open(eContentType, out, encapsulate, null); } /** * @deprecated use open(ASN1ObjectIdenfier, OutputStream, boolean, OutputStream) */ public OutputStream open( OutputStream out, String eContentType, boolean encapsulate, OutputStream dataOutputStream) throws IOException { return open(new ASN1ObjectIdentifier(eContentType), out, encapsulate, dataOutputStream); } /** * generate a signed object that for a CMS Signed Data * object using the given provider - if encapsulate is true a copy * of the message will be included in the signature. The content type * is set according to the OID represented by the string signedContentType. * @param eContentType OID for data to be signed. * @param out stream the CMS object is to be written to. * @param encapsulate true if data should be encapsulated. * @param dataOutputStream output stream to copy the data being signed to. */ public OutputStream open( ASN1ObjectIdentifier eContentType, OutputStream out, boolean encapsulate, OutputStream dataOutputStream) throws IOException { // TODO // if (_signerInfs.isEmpty()) // { // /* RFC 3852 5.2 // * "In the degenerate case where there are no signers, the // * EncapsulatedContentInfo value being "signed" is irrelevant. In this // * case, the content type within the EncapsulatedContentInfo value being // * "signed" MUST be id-data (as defined in section 4), and the content // * field of the EncapsulatedContentInfo value MUST be omitted." // */ // if (encapsulate) // { // throw new IllegalArgumentException("no signers, encapsulate must be false"); // } // if (!DATA.equals(eContentType)) // { // throw new IllegalArgumentException("no signers, eContentType must be id-data"); // } // } // // if (!DATA.equals(eContentType)) // { // /* RFC 3852 5.3 // * [The 'signedAttrs']... // * field is optional, but it MUST be present if the content type of // * the EncapsulatedContentInfo value being signed is not id-data. // */ // // TODO signedAttrs must be present for all signers // } // // ContentInfo // BERSequenceGenerator sGen = new BERSequenceGenerator(out); sGen.addObject(CMSObjectIdentifiers.signedData); // // Signed Data // BERSequenceGenerator sigGen = new BERSequenceGenerator(sGen.getRawOutputStream(), 0, true); sigGen.addObject(calculateVersion(eContentType)); ASN1EncodableVector digestAlgs = new ASN1EncodableVector(); // // add the precalculated SignerInfo digest algorithms. // for (Iterator it = _signers.iterator(); it.hasNext();) { SignerInformation signer = (SignerInformation)it.next(); digestAlgs.add(CMSSignedHelper.INSTANCE.fixAlgID(signer.getDigestAlgorithmID())); } // // add the new digests // for (Iterator it = signerGens.iterator(); it.hasNext();) { SignerInfoGenerator signerGen = (SignerInfoGenerator)it.next(); digestAlgs.add(signerGen.getDigestAlgorithm()); } sigGen.getRawOutputStream().write(new DERSet(digestAlgs).getEncoded()); BERSequenceGenerator eiGen = new BERSequenceGenerator(sigGen.getRawOutputStream()); eiGen.addObject(eContentType); // If encapsulating, add the data as an octet string in the sequence OutputStream encapStream = encapsulate ? CMSUtils.createBEROctetOutputStream(eiGen.getRawOutputStream(), 0, true, _bufferSize) : null; // Also send the data to 'dataOutputStream' if necessary OutputStream contentStream = CMSUtils.getSafeTeeOutputStream(dataOutputStream, encapStream); // Let all the signers see the data as it is written OutputStream sigStream = CMSUtils.attachSignersToOutputStream(signerGens, contentStream); return new CmsSignedDataOutputStream(sigStream, eContentType, sGen, sigGen, eiGen); } // TODO Make public? void generate( OutputStream out, String eContentType, boolean encapsulate, OutputStream dataOutputStream, CMSProcessable content) throws CMSException, IOException { OutputStream signedOut = open(out, eContentType, encapsulate, dataOutputStream); if (content != null) { content.write(signedOut); } signedOut.close(); } // RFC3852, section 5.1: // IF ((certificates is present) AND // (any certificates with a type of other are present)) OR // ((crls is present) AND // (any crls with a type of other are present)) // THEN version MUST be 5 // ELSE // IF (certificates is present) AND // (any version 2 attribute certificates are present) // THEN version MUST be 4 // ELSE // IF ((certificates is present) AND // (any version 1 attribute certificates are present)) OR // (any SignerInfo structures are version 3) OR // (encapContentInfo eContentType is other than id-data) // THEN version MUST be 3 // ELSE version MUST be 1 // private ASN1Integer calculateVersion( ASN1ObjectIdentifier contentOid) { boolean otherCert = false; boolean otherCrl = false; boolean attrCertV1Found = false; boolean attrCertV2Found = false; if (certs != null) { for (Iterator it = certs.iterator(); it.hasNext();) { Object obj = it.next(); if (obj instanceof ASN1TaggedObject) { ASN1TaggedObject tagged = (ASN1TaggedObject)obj; if (tagged.getTagNo() == 1) { attrCertV1Found = true; } else if (tagged.getTagNo() == 2) { attrCertV2Found = true; } else if (tagged.getTagNo() == 3) { otherCert = true; } } } } if (otherCert) { return new ASN1Integer(5); } if (crls != null) // no need to check if otherCert is true { for (Iterator it = crls.iterator(); it.hasNext();) { Object obj = it.next(); if (obj instanceof ASN1TaggedObject) { otherCrl = true; } } } if (otherCrl) { return new ASN1Integer(5); } if (attrCertV2Found) { return new ASN1Integer(4); } if (attrCertV1Found) { return new ASN1Integer(3); } if (checkForVersion3(_signers, signerGens)) { return new ASN1Integer(3); } if (!CMSObjectIdentifiers.data.equals(contentOid)) { return new ASN1Integer(3); } return new ASN1Integer(1); } private boolean checkForVersion3(List signerInfos, List signerInfoGens) { for (Iterator it = signerInfos.iterator(); it.hasNext();) { SignerInfo s = SignerInfo.getInstance(((SignerInformation)it.next()).toASN1Structure()); if (s.getVersion().getValue().intValue() == 3) { return true; } } for (Iterator it = signerInfoGens.iterator(); it.hasNext();) { SignerInfoGenerator s = (SignerInfoGenerator)it.next(); if (s.getGeneratedVersion().getValue().intValue() == 3) { return true; } } return false; } private class CmsSignedDataOutputStream extends OutputStream { private OutputStream _out; private ASN1ObjectIdentifier _contentOID; private BERSequenceGenerator _sGen; private BERSequenceGenerator _sigGen; private BERSequenceGenerator _eiGen; public CmsSignedDataOutputStream( OutputStream out, ASN1ObjectIdentifier contentOID, BERSequenceGenerator sGen, BERSequenceGenerator sigGen, BERSequenceGenerator eiGen) { _out = out; _contentOID = contentOID; _sGen = sGen; _sigGen = sigGen; _eiGen = eiGen; } public void write( int b) throws IOException { _out.write(b); } public void write( byte[] bytes, int off, int len) throws IOException { _out.write(bytes, off, len); } public void write( byte[] bytes) throws IOException { _out.write(bytes); } public void close() throws IOException { _out.close(); _eiGen.close(); digests.clear(); // clear the current preserved digest state if (certs.size() != 0) { ASN1Set certSet = CMSUtils.createBerSetFromList(certs); _sigGen.getRawOutputStream().write(new BERTaggedObject(false, 0, certSet).getEncoded()); } if (crls.size() != 0) { ASN1Set crlSet = CMSUtils.createBerSetFromList(crls); _sigGen.getRawOutputStream().write(new BERTaggedObject(false, 1, crlSet).getEncoded()); } // // collect all the SignerInfo objects // ASN1EncodableVector signerInfos = new ASN1EncodableVector(); // // add the generated SignerInfo objects // for (Iterator it = signerGens.iterator(); it.hasNext();) { SignerInfoGenerator sigGen = (SignerInfoGenerator)it.next(); try { signerInfos.add(sigGen.generate(_contentOID)); byte[] calculatedDigest = sigGen.getCalculatedDigest(); digests.put(sigGen.getDigestAlgorithm().getAlgorithm().getId(), calculatedDigest); } catch (CMSException e) { throw new CMSStreamException("exception generating signers: " + e.getMessage(), e); } } // // add the precalculated SignerInfo objects // { Iterator it = _signers.iterator(); while (it.hasNext()) { SignerInformation signer = (SignerInformation)it.next(); // TODO Verify the content type and calculated digest match the precalculated SignerInfo // if (!signer.getContentType().equals(_contentOID)) // { // // TODO The precalculated content type did not match - error? // } // // byte[] calculatedDigest = (byte[])_digests.get(signer.getDigestAlgOID()); // if (calculatedDigest == null) // { // // TODO We can't confirm this digest because we didn't calculate it - error? // } // else // { // if (!Arrays.areEqual(signer.getContentDigest(), calculatedDigest)) // { // // TODO The precalculated digest did not match - error? // } // } signerInfos.add(signer.toASN1Structure()); } } _sigGen.getRawOutputStream().write(new DERSet(signerInfos).getEncoded()); _sigGen.close(); _sGen.close(); } } } bouncycastle-1.49.orig/src/org/bouncycastle/cms/CMSProcessableInputStream.java0000644000175000017500000000173511451254551027141 0ustar ebourgebourgpackage org.bouncycastle.cms; import java.io.IOException; import java.io.InputStream; import java.io.OutputStream; import org.bouncycastle.util.io.Streams; class CMSProcessableInputStream implements CMSProcessable, CMSReadable { private InputStream input; private boolean used = false; public CMSProcessableInputStream( InputStream input) { this.input = input; } public InputStream getInputStream() { checkSingleUsage(); return input; } public void write(OutputStream zOut) throws IOException, CMSException { checkSingleUsage(); Streams.pipeAll(input, zOut); input.close(); } public Object getContent() { return getInputStream(); } private synchronized void checkSingleUsage() { if (used) { throw new IllegalStateException("CMSProcessableInputStream can only be used once"); } used = true; } } bouncycastle-1.49.orig/src/org/bouncycastle/cms/CMSContentInfoParser.java0000644000175000017500000000214211524656174026107 0ustar ebourgebourgpackage org.bouncycastle.cms; import java.io.IOException; import java.io.InputStream; import org.bouncycastle.asn1.ASN1SequenceParser; import org.bouncycastle.asn1.ASN1StreamParser; import org.bouncycastle.asn1.cms.ContentInfoParser; public class CMSContentInfoParser { protected ContentInfoParser _contentInfo; protected InputStream _data; protected CMSContentInfoParser( InputStream data) throws CMSException { _data = data; try { ASN1StreamParser in = new ASN1StreamParser(data); _contentInfo = new ContentInfoParser((ASN1SequenceParser)in.readObject()); } catch (IOException e) { throw new CMSException("IOException reading content.", e); } catch (ClassCastException e) { throw new CMSException("Unexpected object reading content.", e); } } /** * Close the underlying data stream. * @throws IOException if the close fails. */ public void close() throws IOException { _data.close(); } } bouncycastle-1.49.orig/src/org/bouncycastle/cms/CMSTypedData.java0000644000175000017500000000027311442065637024363 0ustar ebourgebourgpackage org.bouncycastle.cms; import org.bouncycastle.asn1.ASN1ObjectIdentifier; public interface CMSTypedData extends CMSProcessable { ASN1ObjectIdentifier getContentType(); } bouncycastle-1.49.orig/src/org/bouncycastle/cms/SimpleAttributeTableGenerator.java0000644000175000017500000000103410760650614030066 0ustar ebourgebourgpackage org.bouncycastle.cms; import org.bouncycastle.asn1.cms.AttributeTable; import java.util.Map; /** * Basic generator that just returns a preconstructed attribute table */ public class SimpleAttributeTableGenerator implements CMSAttributeTableGenerator { private final AttributeTable attributes; public SimpleAttributeTableGenerator( AttributeTable attributes) { this.attributes = attributes; } public AttributeTable getAttributes(Map parameters) { return attributes; } } bouncycastle-1.49.orig/src/org/bouncycastle/cms/CMSException.java0000644000175000017500000000067411446776622024456 0ustar ebourgebourgpackage org.bouncycastle.cms; public class CMSException extends Exception { Exception e; public CMSException( String msg) { super(msg); } public CMSException( String msg, Exception e) { super(msg); this.e = e; } public Exception getUnderlyingException() { return e; } public Throwable getCause() { return e; } } bouncycastle-1.49.orig/src/org/bouncycastle/cms/PasswordRecipientInformation.java0000644000175000017500000001730512103440465030007 0ustar ebourgebourgpackage org.bouncycastle.cms; import java.io.IOException; import java.security.AlgorithmParameters; import java.security.Key; import java.security.NoSuchProviderException; import java.security.Provider; import java.util.HashMap; import java.util.Map; import org.bouncycastle.asn1.ASN1Encodable; import org.bouncycastle.asn1.cms.PasswordRecipientInfo; import org.bouncycastle.asn1.pkcs.PBKDF2Params; import org.bouncycastle.asn1.x509.AlgorithmIdentifier; import org.bouncycastle.cms.jcajce.JceAlgorithmIdentifierConverter; import org.bouncycastle.cms.jcajce.JcePasswordAuthenticatedRecipient; import org.bouncycastle.cms.jcajce.JcePasswordEnvelopedRecipient; import org.bouncycastle.cms.jcajce.JcePasswordRecipient; import org.bouncycastle.crypto.PBEParametersGenerator; import org.bouncycastle.crypto.generators.PKCS5S2ParametersGenerator; import org.bouncycastle.crypto.params.KeyParameter; import org.bouncycastle.util.Integers; /** * the RecipientInfo class for a recipient who has been sent a message * encrypted using a password. */ public class PasswordRecipientInformation extends RecipientInformation { static Map KEYSIZES = new HashMap(); static Map BLOCKSIZES = new HashMap(); static { BLOCKSIZES.put(CMSAlgorithm.DES_EDE3_CBC, Integers.valueOf(8)); BLOCKSIZES.put(CMSAlgorithm.AES128_CBC, Integers.valueOf(16)); BLOCKSIZES.put(CMSAlgorithm.AES192_CBC, Integers.valueOf(16)); BLOCKSIZES.put(CMSAlgorithm.AES256_CBC, Integers.valueOf(16)); KEYSIZES.put(CMSAlgorithm.DES_EDE3_CBC, Integers.valueOf(192)); KEYSIZES.put(CMSAlgorithm.AES128_CBC, Integers.valueOf(128)); KEYSIZES.put(CMSAlgorithm.AES192_CBC, Integers.valueOf(192)); KEYSIZES.put(CMSAlgorithm.AES256_CBC, Integers.valueOf(256)); } private PasswordRecipientInfo info; PasswordRecipientInformation( PasswordRecipientInfo info, AlgorithmIdentifier messageAlgorithm, CMSSecureReadable secureReadable, AuthAttributesProvider additionalData) { super(info.getKeyEncryptionAlgorithm(), messageAlgorithm, secureReadable, additionalData); this.info = info; this.rid = new PasswordRecipientId(); } /** * return the object identifier for the key derivation algorithm, or null * if there is none present. * * @return OID for key derivation algorithm, if present. */ public String getKeyDerivationAlgOID() { if (info.getKeyDerivationAlgorithm() != null) { return info.getKeyDerivationAlgorithm().getAlgorithm().getId(); } return null; } /** * return the ASN.1 encoded key derivation algorithm parameters, or null if * there aren't any. * @return ASN.1 encoding of key derivation algorithm parameters. */ public byte[] getKeyDerivationAlgParams() { try { if (info.getKeyDerivationAlgorithm() != null) { ASN1Encodable params = info.getKeyDerivationAlgorithm().getParameters(); if (params != null) { return params.toASN1Primitive().getEncoded(); } } return null; } catch (Exception e) { throw new RuntimeException("exception getting encryption parameters " + e); } } /** * Return the key derivation algorithm details for the key in this recipient. * * @return AlgorithmIdentifier representing the key derivation algorithm. */ public AlgorithmIdentifier getKeyDerivationAlgorithm() { return info.getKeyDerivationAlgorithm(); } /** * return an AlgorithmParameters object representing the parameters to the * key derivation algorithm to the recipient. * * @return AlgorithmParameters object, null if there aren't any. * @deprecated use getKeyDerivationAlgorithm and JceAlgorithmIdentifierConverter(). */ public AlgorithmParameters getKeyDerivationAlgParameters(String provider) throws NoSuchProviderException { return getKeyDerivationAlgParameters(CMSUtils.getProvider(provider)); } /** * return an AlgorithmParameters object representing the parameters to the * key derivation algorithm to the recipient. * * @return AlgorithmParameters object, null if there aren't any. * @deprecated use getKeyDerivationAlgorithm and JceAlgorithmIdentifierConverter(). */ public AlgorithmParameters getKeyDerivationAlgParameters(Provider provider) { try { return new JceAlgorithmIdentifierConverter().setProvider(provider).getAlgorithmParameters(info.getKeyDerivationAlgorithm()); } catch (Exception e) { throw new RuntimeException("exception getting encryption parameters " + e); } } /** * decrypt the content and return an input stream. * @deprecated use getContentStream(Recipient) */ public CMSTypedStream getContentStream( Key key, String prov) throws CMSException, NoSuchProviderException { return getContentStream(key, CMSUtils.getProvider(prov)); } /** * decrypt the content and return an input stream. * @deprecated use getContentStream(Recipient) */ public CMSTypedStream getContentStream( Key key, Provider prov) throws CMSException { try { CMSPBEKey pbeKey = (CMSPBEKey)key; JcePasswordRecipient recipient; if (secureReadable instanceof CMSEnvelopedHelper.CMSEnvelopedSecureReadable) { recipient = new JcePasswordEnvelopedRecipient(pbeKey.getPassword()); } else { recipient = new JcePasswordAuthenticatedRecipient(pbeKey.getPassword()); } recipient.setPasswordConversionScheme((pbeKey instanceof PKCS5Scheme2UTF8PBEKey) ? PasswordRecipient.PKCS5_SCHEME2_UTF8 : PasswordRecipient.PKCS5_SCHEME2); if (prov != null) { recipient.setProvider(prov); } return getContentStream(recipient); } catch (IOException e) { throw new CMSException("encoding error: " + e.getMessage(), e); } } protected RecipientOperator getRecipientOperator(Recipient recipient) throws CMSException, IOException { PasswordRecipient pbeRecipient = (PasswordRecipient)recipient; AlgorithmIdentifier kekAlg = AlgorithmIdentifier.getInstance(info.getKeyEncryptionAlgorithm()); AlgorithmIdentifier kekAlgParams = AlgorithmIdentifier.getInstance(kekAlg.getParameters()); byte[] passwordBytes = getPasswordBytes(pbeRecipient.getPasswordConversionScheme(), pbeRecipient.getPassword()); PBKDF2Params params = PBKDF2Params.getInstance(info.getKeyDerivationAlgorithm().getParameters()); PKCS5S2ParametersGenerator gen = new PKCS5S2ParametersGenerator(); gen.init(passwordBytes, params.getSalt(), params.getIterationCount().intValue()); int keySize = ((Integer)KEYSIZES.get(kekAlgParams.getAlgorithm())).intValue(); byte[] derivedKey = ((KeyParameter)gen.generateDerivedParameters(keySize)).getKey(); return pbeRecipient.getRecipientOperator(kekAlgParams, messageAlgorithm, derivedKey, info.getEncryptedKey().getOctets()); } protected byte[] getPasswordBytes(int scheme, char[] password) { if (scheme == PasswordRecipient.PKCS5_SCHEME2) { return PBEParametersGenerator.PKCS5PasswordToBytes(password); } return PBEParametersGenerator.PKCS5PasswordToUTF8Bytes(password); } } bouncycastle-1.49.orig/src/org/bouncycastle/cms/PasswordRecipientInfoGenerator.java0000644000175000017500000001153511503776043030272 0ustar ebourgebourgpackage org.bouncycastle.cms; import java.security.SecureRandom; import org.bouncycastle.asn1.ASN1EncodableVector; import org.bouncycastle.asn1.ASN1ObjectIdentifier; import org.bouncycastle.asn1.ASN1OctetString; import org.bouncycastle.asn1.DEROctetString; import org.bouncycastle.asn1.DERSequence; import org.bouncycastle.asn1.cms.PasswordRecipientInfo; import org.bouncycastle.asn1.cms.RecipientInfo; import org.bouncycastle.asn1.pkcs.PBKDF2Params; import org.bouncycastle.asn1.pkcs.PKCSObjectIdentifiers; import org.bouncycastle.asn1.x509.AlgorithmIdentifier; import org.bouncycastle.crypto.PBEParametersGenerator; import org.bouncycastle.crypto.generators.PKCS5S2ParametersGenerator; import org.bouncycastle.crypto.params.KeyParameter; import org.bouncycastle.operator.GenericKey; public abstract class PasswordRecipientInfoGenerator implements RecipientInfoGenerator { private char[] password; private AlgorithmIdentifier keyDerivationAlgorithm; private ASN1ObjectIdentifier kekAlgorithm; private SecureRandom random; private int schemeID; private int keySize; private int blockSize; protected PasswordRecipientInfoGenerator(ASN1ObjectIdentifier kekAlgorithm, char[] password) { this(kekAlgorithm, password, getKeySize(kekAlgorithm), ((Integer)PasswordRecipientInformation.BLOCKSIZES.get(kekAlgorithm)).intValue()); } protected PasswordRecipientInfoGenerator(ASN1ObjectIdentifier kekAlgorithm, char[] password, int keySize, int blockSize) { this.password = password; this.schemeID = PasswordRecipient.PKCS5_SCHEME2_UTF8; this.kekAlgorithm = kekAlgorithm; this.keySize = keySize; this.blockSize = blockSize; } private static int getKeySize(ASN1ObjectIdentifier kekAlgorithm) { Integer size = (Integer)PasswordRecipientInformation.KEYSIZES.get(kekAlgorithm); if (size == null) { throw new IllegalArgumentException("cannot find key size for algorithm: " + kekAlgorithm); } return size.intValue(); } public PasswordRecipientInfoGenerator setPasswordConversionScheme(int schemeID) { this.schemeID = schemeID; return this; } public PasswordRecipientInfoGenerator setSaltAndIterationCount(byte[] salt, int iterationCount) { this.keyDerivationAlgorithm = new AlgorithmIdentifier(PKCSObjectIdentifiers.id_PBKDF2, new PBKDF2Params(salt, iterationCount)); return this; } public PasswordRecipientInfoGenerator setSecureRandom(SecureRandom random) { this.random = random; return this; } public RecipientInfo generate(GenericKey contentEncryptionKey) throws CMSException { byte[] iv = new byte[blockSize]; /// TODO: set IV size properly! if (random == null) { random = new SecureRandom(); } random.nextBytes(iv); if (keyDerivationAlgorithm == null) { byte[] salt = new byte[20]; random.nextBytes(salt); keyDerivationAlgorithm = new AlgorithmIdentifier(PKCSObjectIdentifiers.id_PBKDF2, new PBKDF2Params(salt, 1024)); } PBKDF2Params params = PBKDF2Params.getInstance(keyDerivationAlgorithm.getParameters()); byte[] derivedKey; if (schemeID == PasswordRecipient.PKCS5_SCHEME2) { PKCS5S2ParametersGenerator gen = new PKCS5S2ParametersGenerator(); gen.init(PBEParametersGenerator.PKCS5PasswordToBytes(password), params.getSalt(), params.getIterationCount().intValue()); derivedKey = ((KeyParameter)gen.generateDerivedParameters(keySize)).getKey(); } else { PKCS5S2ParametersGenerator gen = new PKCS5S2ParametersGenerator(); gen.init(PBEParametersGenerator.PKCS5PasswordToUTF8Bytes(password), params.getSalt(), params.getIterationCount().intValue()); derivedKey = ((KeyParameter)gen.generateDerivedParameters(keySize)).getKey(); } AlgorithmIdentifier kekAlgorithmId = new AlgorithmIdentifier(kekAlgorithm, new DEROctetString(iv)); byte[] encryptedKeyBytes = generateEncryptedBytes(kekAlgorithmId, derivedKey, contentEncryptionKey); ASN1OctetString encryptedKey = new DEROctetString(encryptedKeyBytes); ASN1EncodableVector v = new ASN1EncodableVector(); v.add(kekAlgorithm); v.add(new DEROctetString(iv)); AlgorithmIdentifier keyEncryptionAlgorithm = new AlgorithmIdentifier( PKCSObjectIdentifiers.id_alg_PWRI_KEK, new DERSequence(v)); return new RecipientInfo(new PasswordRecipientInfo(keyDerivationAlgorithm, keyEncryptionAlgorithm, encryptedKey)); } protected abstract byte[] generateEncryptedBytes(AlgorithmIdentifier algorithm, byte[] derivedKey, GenericKey contentEncryptionKey) throws CMSException; }bouncycastle-1.49.orig/src/org/bouncycastle/cms/CMSAlgorithm.java0000644000175000017500000000732412033223244024421 0ustar ebourgebourgpackage org.bouncycastle.cms; import org.bouncycastle.asn1.ASN1ObjectIdentifier; import org.bouncycastle.asn1.cryptopro.CryptoProObjectIdentifiers; import org.bouncycastle.asn1.kisa.KISAObjectIdentifiers; import org.bouncycastle.asn1.nist.NISTObjectIdentifiers; import org.bouncycastle.asn1.ntt.NTTObjectIdentifiers; import org.bouncycastle.asn1.oiw.OIWObjectIdentifiers; import org.bouncycastle.asn1.pkcs.PKCSObjectIdentifiers; import org.bouncycastle.asn1.teletrust.TeleTrusTObjectIdentifiers; import org.bouncycastle.asn1.x9.X9ObjectIdentifiers; public class CMSAlgorithm { public static final ASN1ObjectIdentifier DES_CBC = OIWObjectIdentifiers.desCBC; public static final ASN1ObjectIdentifier DES_EDE3_CBC = PKCSObjectIdentifiers.des_EDE3_CBC; public static final ASN1ObjectIdentifier RC2_CBC = PKCSObjectIdentifiers.RC2_CBC; public static final ASN1ObjectIdentifier IDEA_CBC = new ASN1ObjectIdentifier("1.3.6.1.4.1.188.7.1.1.2"); public static final ASN1ObjectIdentifier CAST5_CBC = new ASN1ObjectIdentifier("1.2.840.113533.7.66.10"); public static final ASN1ObjectIdentifier AES128_CBC = NISTObjectIdentifiers.id_aes128_CBC; public static final ASN1ObjectIdentifier AES192_CBC = NISTObjectIdentifiers.id_aes192_CBC; public static final ASN1ObjectIdentifier AES256_CBC = NISTObjectIdentifiers.id_aes256_CBC; public static final ASN1ObjectIdentifier CAMELLIA128_CBC = NTTObjectIdentifiers.id_camellia128_cbc; public static final ASN1ObjectIdentifier CAMELLIA192_CBC = NTTObjectIdentifiers.id_camellia192_cbc; public static final ASN1ObjectIdentifier CAMELLIA256_CBC = NTTObjectIdentifiers.id_camellia256_cbc; public static final ASN1ObjectIdentifier SEED_CBC = KISAObjectIdentifiers.id_seedCBC; public static final ASN1ObjectIdentifier DES_EDE3_WRAP = PKCSObjectIdentifiers.id_alg_CMS3DESwrap; public static final ASN1ObjectIdentifier AES128_WRAP = NISTObjectIdentifiers.id_aes128_wrap; public static final ASN1ObjectIdentifier AES192_WRAP = NISTObjectIdentifiers.id_aes192_wrap; public static final ASN1ObjectIdentifier AES256_WRAP = NISTObjectIdentifiers.id_aes256_wrap; public static final ASN1ObjectIdentifier CAMELLIA128_WRAP = NTTObjectIdentifiers.id_camellia128_wrap; public static final ASN1ObjectIdentifier CAMELLIA192_WRAP = NTTObjectIdentifiers.id_camellia192_wrap; public static final ASN1ObjectIdentifier CAMELLIA256_WRAP = NTTObjectIdentifiers.id_camellia256_wrap; public static final ASN1ObjectIdentifier SEED_WRAP = KISAObjectIdentifiers.id_npki_app_cmsSeed_wrap; public static final ASN1ObjectIdentifier ECDH_SHA1KDF = X9ObjectIdentifiers.dhSinglePass_stdDH_sha1kdf_scheme; public static final ASN1ObjectIdentifier ECMQV_SHA1KDF = X9ObjectIdentifiers.mqvSinglePass_sha1kdf_scheme; public static final ASN1ObjectIdentifier SHA1 = OIWObjectIdentifiers.idSHA1; public static final ASN1ObjectIdentifier SHA224 = NISTObjectIdentifiers.id_sha224; public static final ASN1ObjectIdentifier SHA256 = NISTObjectIdentifiers.id_sha256; public static final ASN1ObjectIdentifier SHA384 = NISTObjectIdentifiers.id_sha384; public static final ASN1ObjectIdentifier SHA512 = NISTObjectIdentifiers.id_sha512; public static final ASN1ObjectIdentifier MD5 = PKCSObjectIdentifiers.md5; public static final ASN1ObjectIdentifier GOST3411 = CryptoProObjectIdentifiers.gostR3411; public static final ASN1ObjectIdentifier RIPEMD128 = TeleTrusTObjectIdentifiers.ripemd128; public static final ASN1ObjectIdentifier RIPEMD160 = TeleTrusTObjectIdentifiers.ripemd160; public static final ASN1ObjectIdentifier RIPEMD256 = TeleTrusTObjectIdentifiers.ripemd256; } bouncycastle-1.49.orig/src/org/bouncycastle/cms/OriginatorInfoGenerator.java0000644000175000017500000000261711701213634026733 0ustar ebourgebourgpackage org.bouncycastle.cms; import java.util.ArrayList; import java.util.List; import org.bouncycastle.asn1.cms.OriginatorInfo; import org.bouncycastle.cert.X509CertificateHolder; import org.bouncycastle.util.Store; public class OriginatorInfoGenerator { private final List origCerts; private final List origCRLs; public OriginatorInfoGenerator(X509CertificateHolder origCert) { this.origCerts = new ArrayList(1); this.origCRLs = null; origCerts.add(origCert.toASN1Structure()); } public OriginatorInfoGenerator(Store origCerts) throws CMSException { this(origCerts, null); } public OriginatorInfoGenerator(Store origCerts, Store origCRLs) throws CMSException { this.origCerts = CMSUtils.getCertificatesFromStore(origCerts); if (origCRLs != null) { this.origCRLs = CMSUtils.getCRLsFromStore(origCRLs); } else { this.origCRLs = null; } } public OriginatorInformation generate() { if (origCRLs != null) { return new OriginatorInformation(new OriginatorInfo(CMSUtils.createDerSetFromList(origCerts), CMSUtils.createDerSetFromList(origCRLs))); } else { return new OriginatorInformation(new OriginatorInfo(CMSUtils.createDerSetFromList(origCerts), null)); } } } bouncycastle-1.49.orig/src/org/bouncycastle/cms/KEKRecipientInfoGenerator.java0000644000175000017500000000245511504001347027070 0ustar ebourgebourgpackage org.bouncycastle.cms; import org.bouncycastle.asn1.ASN1OctetString; import org.bouncycastle.asn1.DEROctetString; import org.bouncycastle.asn1.cms.KEKIdentifier; import org.bouncycastle.asn1.cms.KEKRecipientInfo; import org.bouncycastle.asn1.cms.RecipientInfo; import org.bouncycastle.operator.GenericKey; import org.bouncycastle.operator.OperatorException; import org.bouncycastle.operator.SymmetricKeyWrapper; public abstract class KEKRecipientInfoGenerator implements RecipientInfoGenerator { private final KEKIdentifier kekIdentifier; protected final SymmetricKeyWrapper wrapper; protected KEKRecipientInfoGenerator(KEKIdentifier kekIdentifier, SymmetricKeyWrapper wrapper) { this.kekIdentifier = kekIdentifier; this.wrapper = wrapper; } public final RecipientInfo generate(GenericKey contentEncryptionKey) throws CMSException { try { ASN1OctetString encryptedKey = new DEROctetString(wrapper.generateWrappedKey(contentEncryptionKey)); return new RecipientInfo(new KEKRecipientInfo(kekIdentifier, wrapper.getAlgorithmIdentifier(), encryptedKey)); } catch (OperatorException e) { throw new CMSException("exception wrapping content key: " + e.getMessage(), e); } } }bouncycastle-1.49.orig/src/org/bouncycastle/cms/CMSEnvelopedHelper.java0000644000175000017500000002044412103441027025551 0ustar ebourgebourgpackage org.bouncycastle.cms; import java.io.FilterInputStream; import java.io.IOException; import java.io.InputStream; import java.security.NoSuchAlgorithmException; import java.security.Provider; import java.util.ArrayList; import java.util.HashMap; import java.util.List; import java.util.Map; import javax.crypto.KeyGenerator; import org.bouncycastle.asn1.ASN1Encodable; import org.bouncycastle.asn1.ASN1Set; import org.bouncycastle.asn1.cms.KEKRecipientInfo; import org.bouncycastle.asn1.cms.KeyAgreeRecipientInfo; import org.bouncycastle.asn1.cms.KeyTransRecipientInfo; import org.bouncycastle.asn1.cms.PasswordRecipientInfo; import org.bouncycastle.asn1.cms.RecipientInfo; import org.bouncycastle.asn1.x509.AlgorithmIdentifier; import org.bouncycastle.operator.DigestCalculator; import org.bouncycastle.util.Integers; class CMSEnvelopedHelper { static final CMSEnvelopedHelper INSTANCE = new CMSEnvelopedHelper(); private static final Map KEYSIZES = new HashMap(); private static final Map BASE_CIPHER_NAMES = new HashMap(); private static final Map CIPHER_ALG_NAMES = new HashMap(); private static final Map MAC_ALG_NAMES = new HashMap(); static { KEYSIZES.put(CMSEnvelopedGenerator.DES_EDE3_CBC, Integers.valueOf(192)); KEYSIZES.put(CMSEnvelopedGenerator.AES128_CBC, Integers.valueOf(128)); KEYSIZES.put(CMSEnvelopedGenerator.AES192_CBC, Integers.valueOf(192)); KEYSIZES.put(CMSEnvelopedGenerator.AES256_CBC, Integers.valueOf(256)); BASE_CIPHER_NAMES.put(CMSEnvelopedGenerator.DES_EDE3_CBC, "DESEDE"); BASE_CIPHER_NAMES.put(CMSEnvelopedGenerator.AES128_CBC, "AES"); BASE_CIPHER_NAMES.put(CMSEnvelopedGenerator.AES192_CBC, "AES"); BASE_CIPHER_NAMES.put(CMSEnvelopedGenerator.AES256_CBC, "AES"); CIPHER_ALG_NAMES.put(CMSEnvelopedGenerator.DES_EDE3_CBC, "DESEDE/CBC/PKCS5Padding"); CIPHER_ALG_NAMES.put(CMSEnvelopedGenerator.AES128_CBC, "AES/CBC/PKCS5Padding"); CIPHER_ALG_NAMES.put(CMSEnvelopedGenerator.AES192_CBC, "AES/CBC/PKCS5Padding"); CIPHER_ALG_NAMES.put(CMSEnvelopedGenerator.AES256_CBC, "AES/CBC/PKCS5Padding"); MAC_ALG_NAMES.put(CMSEnvelopedGenerator.DES_EDE3_CBC, "DESEDEMac"); MAC_ALG_NAMES.put(CMSEnvelopedGenerator.AES128_CBC, "AESMac"); MAC_ALG_NAMES.put(CMSEnvelopedGenerator.AES192_CBC, "AESMac"); MAC_ALG_NAMES.put(CMSEnvelopedGenerator.AES256_CBC, "AESMac"); } KeyGenerator createSymmetricKeyGenerator( String encryptionOID, Provider provider) throws NoSuchAlgorithmException { try { return createKeyGenerator(encryptionOID, provider); } catch (NoSuchAlgorithmException e) { try { String algName = (String)BASE_CIPHER_NAMES.get(encryptionOID); if (algName != null) { return createKeyGenerator(algName, provider); } } catch (NoSuchAlgorithmException ex) { // ignore } if (provider != null) { return createSymmetricKeyGenerator(encryptionOID, null); } throw e; } } int getKeySize(String oid) { Integer keySize = (Integer)KEYSIZES.get(oid); if (keySize == null) { throw new IllegalArgumentException("no keysize for " + oid); } return keySize.intValue(); } private KeyGenerator createKeyGenerator( String algName, Provider provider) throws NoSuchAlgorithmException { if (provider != null) { return KeyGenerator.getInstance(algName, provider); } else { return KeyGenerator.getInstance(algName); } } static RecipientInformationStore buildRecipientInformationStore( ASN1Set recipientInfos, AlgorithmIdentifier messageAlgorithm, CMSSecureReadable secureReadable) { return buildRecipientInformationStore(recipientInfos, messageAlgorithm, secureReadable, null); } static RecipientInformationStore buildRecipientInformationStore( ASN1Set recipientInfos, AlgorithmIdentifier messageAlgorithm, CMSSecureReadable secureReadable, AuthAttributesProvider additionalData) { List infos = new ArrayList(); for (int i = 0; i != recipientInfos.size(); i++) { RecipientInfo info = RecipientInfo.getInstance(recipientInfos.getObjectAt(i)); readRecipientInfo(infos, info, messageAlgorithm, secureReadable, additionalData); } return new RecipientInformationStore(infos); } private static void readRecipientInfo( List infos, RecipientInfo info, AlgorithmIdentifier messageAlgorithm, CMSSecureReadable secureReadable, AuthAttributesProvider additionalData) { ASN1Encodable recipInfo = info.getInfo(); if (recipInfo instanceof KeyTransRecipientInfo) { infos.add(new KeyTransRecipientInformation( (KeyTransRecipientInfo)recipInfo, messageAlgorithm, secureReadable, additionalData)); } else if (recipInfo instanceof KEKRecipientInfo) { infos.add(new KEKRecipientInformation( (KEKRecipientInfo)recipInfo, messageAlgorithm, secureReadable, additionalData)); } else if (recipInfo instanceof KeyAgreeRecipientInfo) { KeyAgreeRecipientInformation.readRecipientInfo(infos, (KeyAgreeRecipientInfo)recipInfo, messageAlgorithm, secureReadable, additionalData); } else if (recipInfo instanceof PasswordRecipientInfo) { infos.add(new PasswordRecipientInformation( (PasswordRecipientInfo)recipInfo, messageAlgorithm, secureReadable, additionalData)); } } static class CMSDigestAuthenticatedSecureReadable implements CMSSecureReadable { private DigestCalculator digestCalculator; private CMSReadable readable; public CMSDigestAuthenticatedSecureReadable(DigestCalculator digestCalculator, CMSReadable readable) { this.digestCalculator = digestCalculator; this.readable = readable; } public InputStream getInputStream() throws IOException, CMSException { return new FilterInputStream(readable.getInputStream()) { public int read() throws IOException { int b = in.read(); if (b >= 0) { digestCalculator.getOutputStream().write(b); } return b; } public int read(byte[] inBuf, int inOff, int inLen) throws IOException { int n = in.read(inBuf, inOff, inLen); if (n >= 0) { digestCalculator.getOutputStream().write(inBuf, inOff, n); } return n; } }; } public byte[] getDigest() { return digestCalculator.getDigest(); } } static class CMSAuthenticatedSecureReadable implements CMSSecureReadable { private AlgorithmIdentifier algorithm; private CMSReadable readable; CMSAuthenticatedSecureReadable(AlgorithmIdentifier algorithm, CMSReadable readable) { this.algorithm = algorithm; this.readable = readable; } public InputStream getInputStream() throws IOException, CMSException { return readable.getInputStream(); } } static class CMSEnvelopedSecureReadable implements CMSSecureReadable { private AlgorithmIdentifier algorithm; private CMSReadable readable; CMSEnvelopedSecureReadable(AlgorithmIdentifier algorithm, CMSReadable readable) { this.algorithm = algorithm; this.readable = readable; } public InputStream getInputStream() throws IOException, CMSException { return readable.getInputStream(); } } } bouncycastle-1.49.orig/src/org/bouncycastle/cms/OriginatorInformation.java0000644000175000017500000000521611724260460026460 0ustar ebourgebourgpackage org.bouncycastle.cms; import java.util.ArrayList; import java.util.Enumeration; import java.util.List; import org.bouncycastle.asn1.ASN1Encodable; import org.bouncycastle.asn1.ASN1Primitive; import org.bouncycastle.asn1.ASN1Sequence; import org.bouncycastle.asn1.ASN1Set; import org.bouncycastle.asn1.cms.OriginatorInfo; import org.bouncycastle.asn1.x509.Certificate; import org.bouncycastle.asn1.x509.CertificateList; import org.bouncycastle.cert.X509CRLHolder; import org.bouncycastle.cert.X509CertificateHolder; import org.bouncycastle.util.CollectionStore; import org.bouncycastle.util.Store; public class OriginatorInformation { private OriginatorInfo originatorInfo; OriginatorInformation(OriginatorInfo originatorInfo) { this.originatorInfo = originatorInfo; } /** * Return the certificates stored in the underlying OriginatorInfo object. * * @return a Store of X509CertificateHolder objects. */ public Store getCertificates() { ASN1Set certSet = originatorInfo.getCertificates(); if (certSet != null) { List certList = new ArrayList(certSet.size()); for (Enumeration en = certSet.getObjects(); en.hasMoreElements();) { ASN1Primitive obj = ((ASN1Encodable)en.nextElement()).toASN1Primitive(); if (obj instanceof ASN1Sequence) { certList.add(new X509CertificateHolder(Certificate.getInstance(obj))); } } return new CollectionStore(certList); } return new CollectionStore(new ArrayList()); } /** * Return the CRLs stored in the underlying OriginatorInfo object. * * @return a Store of X509CRLHolder objects. */ public Store getCRLs() { ASN1Set crlSet = originatorInfo.getCRLs(); if (crlSet != null) { List crlList = new ArrayList(crlSet.size()); for (Enumeration en = crlSet.getObjects(); en.hasMoreElements();) { ASN1Primitive obj = ((ASN1Encodable)en.nextElement()).toASN1Primitive(); if (obj instanceof ASN1Sequence) { crlList.add(new X509CRLHolder(CertificateList.getInstance(obj))); } } return new CollectionStore(crlList); } return new CollectionStore(new ArrayList()); } /** * Return the underlying ASN.1 object defining this SignerInformation object. * * @return a OriginatorInfo. */ public OriginatorInfo toASN1Structure() { return originatorInfo; } } bouncycastle-1.49.orig/src/org/bouncycastle/cms/CMSSignedGenerator.java0000644000175000017500000003301612152022050025542 0ustar ebourgebourgpackage org.bouncycastle.cms; import java.io.IOException; import java.security.PrivateKey; import java.security.SecureRandom; import java.security.cert.CertStore; import java.security.cert.CertStoreException; import java.security.interfaces.DSAPrivateKey; import java.security.interfaces.RSAPrivateKey; import java.util.ArrayList; import java.util.HashMap; import java.util.HashSet; import java.util.Iterator; import java.util.List; import java.util.Map; import java.util.Set; import org.bouncycastle.asn1.ASN1Encodable; import org.bouncycastle.asn1.ASN1ObjectIdentifier; import org.bouncycastle.asn1.ASN1Primitive; import org.bouncycastle.asn1.ASN1Set; import org.bouncycastle.asn1.DERSet; import org.bouncycastle.asn1.DERTaggedObject; import org.bouncycastle.asn1.cms.AttributeTable; import org.bouncycastle.asn1.cms.CMSObjectIdentifiers; import org.bouncycastle.asn1.cms.OtherRevocationInfoFormat; import org.bouncycastle.asn1.cryptopro.CryptoProObjectIdentifiers; import org.bouncycastle.asn1.nist.NISTObjectIdentifiers; import org.bouncycastle.asn1.oiw.OIWObjectIdentifiers; import org.bouncycastle.asn1.pkcs.PKCSObjectIdentifiers; import org.bouncycastle.asn1.teletrust.TeleTrusTObjectIdentifiers; import org.bouncycastle.asn1.x509.AlgorithmIdentifier; import org.bouncycastle.asn1.x509.AttributeCertificate; import org.bouncycastle.asn1.x9.X9ObjectIdentifiers; import org.bouncycastle.cert.X509AttributeCertificateHolder; import org.bouncycastle.cert.X509CRLHolder; import org.bouncycastle.cert.X509CertificateHolder; import org.bouncycastle.jce.interfaces.GOST3410PrivateKey; import org.bouncycastle.util.Arrays; import org.bouncycastle.util.Store; import org.bouncycastle.x509.X509AttributeCertificate; import org.bouncycastle.x509.X509Store; public class CMSSignedGenerator { /** * Default type for the signed data. */ public static final String DATA = CMSObjectIdentifiers.data.getId(); public static final String DIGEST_SHA1 = OIWObjectIdentifiers.idSHA1.getId(); public static final String DIGEST_SHA224 = NISTObjectIdentifiers.id_sha224.getId(); public static final String DIGEST_SHA256 = NISTObjectIdentifiers.id_sha256.getId(); public static final String DIGEST_SHA384 = NISTObjectIdentifiers.id_sha384.getId(); public static final String DIGEST_SHA512 = NISTObjectIdentifiers.id_sha512.getId(); public static final String DIGEST_MD5 = PKCSObjectIdentifiers.md5.getId(); public static final String DIGEST_GOST3411 = CryptoProObjectIdentifiers.gostR3411.getId(); public static final String DIGEST_RIPEMD128 = TeleTrusTObjectIdentifiers.ripemd128.getId(); public static final String DIGEST_RIPEMD160 = TeleTrusTObjectIdentifiers.ripemd160.getId(); public static final String DIGEST_RIPEMD256 = TeleTrusTObjectIdentifiers.ripemd256.getId(); public static final String ENCRYPTION_RSA = PKCSObjectIdentifiers.rsaEncryption.getId(); public static final String ENCRYPTION_DSA = X9ObjectIdentifiers.id_dsa_with_sha1.getId(); public static final String ENCRYPTION_ECDSA = X9ObjectIdentifiers.ecdsa_with_SHA1.getId(); public static final String ENCRYPTION_RSA_PSS = PKCSObjectIdentifiers.id_RSASSA_PSS.getId(); public static final String ENCRYPTION_GOST3410 = CryptoProObjectIdentifiers.gostR3410_94.getId(); public static final String ENCRYPTION_ECGOST3410 = CryptoProObjectIdentifiers.gostR3410_2001.getId(); private static final String ENCRYPTION_ECDSA_WITH_SHA1 = X9ObjectIdentifiers.ecdsa_with_SHA1.getId(); private static final String ENCRYPTION_ECDSA_WITH_SHA224 = X9ObjectIdentifiers.ecdsa_with_SHA224.getId(); private static final String ENCRYPTION_ECDSA_WITH_SHA256 = X9ObjectIdentifiers.ecdsa_with_SHA256.getId(); private static final String ENCRYPTION_ECDSA_WITH_SHA384 = X9ObjectIdentifiers.ecdsa_with_SHA384.getId(); private static final String ENCRYPTION_ECDSA_WITH_SHA512 = X9ObjectIdentifiers.ecdsa_with_SHA512.getId(); private static final Set NO_PARAMS = new HashSet(); private static final Map EC_ALGORITHMS = new HashMap(); static { NO_PARAMS.add(ENCRYPTION_DSA); NO_PARAMS.add(ENCRYPTION_ECDSA); NO_PARAMS.add(ENCRYPTION_ECDSA_WITH_SHA1); NO_PARAMS.add(ENCRYPTION_ECDSA_WITH_SHA224); NO_PARAMS.add(ENCRYPTION_ECDSA_WITH_SHA256); NO_PARAMS.add(ENCRYPTION_ECDSA_WITH_SHA384); NO_PARAMS.add(ENCRYPTION_ECDSA_WITH_SHA512); EC_ALGORITHMS.put(DIGEST_SHA1, ENCRYPTION_ECDSA_WITH_SHA1); EC_ALGORITHMS.put(DIGEST_SHA224, ENCRYPTION_ECDSA_WITH_SHA224); EC_ALGORITHMS.put(DIGEST_SHA256, ENCRYPTION_ECDSA_WITH_SHA256); EC_ALGORITHMS.put(DIGEST_SHA384, ENCRYPTION_ECDSA_WITH_SHA384); EC_ALGORITHMS.put(DIGEST_SHA512, ENCRYPTION_ECDSA_WITH_SHA512); } protected List certs = new ArrayList(); protected List crls = new ArrayList(); protected List _signers = new ArrayList(); protected List signerGens = new ArrayList(); protected Map digests = new HashMap(); protected final SecureRandom rand; /** * base constructor */ protected CMSSignedGenerator() { this(new SecureRandom()); } /** * constructor allowing specific source of randomness * @param rand instance of SecureRandom to use */ protected CMSSignedGenerator( SecureRandom rand) { this.rand = rand; } protected String getEncOID( PrivateKey key, String digestOID) { String encOID = null; if (key instanceof RSAPrivateKey || "RSA".equalsIgnoreCase(key.getAlgorithm())) { encOID = ENCRYPTION_RSA; } else if (key instanceof DSAPrivateKey || "DSA".equalsIgnoreCase(key.getAlgorithm())) { encOID = ENCRYPTION_DSA; if (!digestOID.equals(DIGEST_SHA1)) { throw new IllegalArgumentException("can't mix DSA with anything but SHA1"); } } else if ("ECDSA".equalsIgnoreCase(key.getAlgorithm()) || "EC".equalsIgnoreCase(key.getAlgorithm())) { encOID = (String)EC_ALGORITHMS.get(digestOID); if (encOID == null) { throw new IllegalArgumentException("can't mix ECDSA with anything but SHA family digests"); } } else if (key instanceof GOST3410PrivateKey || "GOST3410".equalsIgnoreCase(key.getAlgorithm())) { encOID = ENCRYPTION_GOST3410; } else if ("ECGOST3410".equalsIgnoreCase(key.getAlgorithm())) { encOID = ENCRYPTION_ECGOST3410; } return encOID; } protected Map getBaseParameters(ASN1ObjectIdentifier contentType, AlgorithmIdentifier digAlgId, byte[] hash) { Map param = new HashMap(); param.put(CMSAttributeTableGenerator.CONTENT_TYPE, contentType); param.put(CMSAttributeTableGenerator.DIGEST_ALGORITHM_IDENTIFIER, digAlgId); param.put(CMSAttributeTableGenerator.DIGEST, Arrays.clone(hash)); return param; } protected ASN1Set getAttributeSet( AttributeTable attr) { if (attr != null) { return new DERSet(attr.toASN1EncodableVector()); } return null; } /** * add the certificates and CRLs contained in the given CertStore * to the pool that will be included in the encoded signature block. *

    * Note: this assumes the CertStore will support null in the get * methods. * @param certStore CertStore containing the public key certificates and CRLs * @throws java.security.cert.CertStoreException if an issue occurs processing the CertStore * @throws CMSException if an issue occurse transforming data from the CertStore into the message * @deprecated use addCertificates and addCRLs */ public void addCertificatesAndCRLs( CertStore certStore) throws CertStoreException, CMSException { certs.addAll(CMSUtils.getCertificatesFromStore(certStore)); crls.addAll(CMSUtils.getCRLsFromStore(certStore)); } /** * Add a certificate to the certificate set to be included with the generated SignedData message. * * @param certificate the certificate to be included. * @throws CMSException if the certificate cannot be encoded for adding. */ public void addCertificate( X509CertificateHolder certificate) throws CMSException { certs.add(certificate.toASN1Structure()); } /** * Add the certificates in certStore to the certificate set to be included with the generated SignedData message. * * @param certStore the store containing the certificates to be included. * @throws CMSException if the certificates cannot be encoded for adding. */ public void addCertificates( Store certStore) throws CMSException { certs.addAll(CMSUtils.getCertificatesFromStore(certStore)); } /** * Add a CRL to the CRL set to be included with the generated SignedData message. * * @param crl the CRL to be included. */ public void addCRL(X509CRLHolder crl) { crls.add(crl.toASN1Structure()); } /** * Add the CRLs in crlStore to the CRL set to be included with the generated SignedData message. * * @param crlStore the store containing the CRLs to be included. * @throws CMSException if the CRLs cannot be encoded for adding. */ public void addCRLs( Store crlStore) throws CMSException { crls.addAll(CMSUtils.getCRLsFromStore(crlStore)); } /** * Add the attribute certificates in attrStore to the certificate set to be included with the generated SignedData message. * * @param attrCert the store containing the certificates to be included. * @throws CMSException if the attribute certificate cannot be encoded for adding. */ public void addAttributeCertificate( X509AttributeCertificateHolder attrCert) throws CMSException { certs.add(new DERTaggedObject(false, 2, attrCert.toASN1Structure())); } /** * Add the attribute certificates in attrStore to the certificate set to be included with the generated SignedData message. * * @param attrStore the store containing the certificates to be included. * @throws CMSException if the attribute certificate cannot be encoded for adding. */ public void addAttributeCertificates( Store attrStore) throws CMSException { certs.addAll(CMSUtils.getAttributeCertificatesFromStore(attrStore)); } /** * Add a single instance of otherRevocationData to the CRL set to be included with the generated SignedData message. * * @param otherRevocationInfoFormat the OID specifying the format of the otherRevocationInfo data. * @param otherRevocationInfo the otherRevocationInfo ASN.1 structure. */ public void addOtherRevocationInfo( ASN1ObjectIdentifier otherRevocationInfoFormat, ASN1Encodable otherRevocationInfo) { crls.add(new DERTaggedObject(false, 1, new OtherRevocationInfoFormat(otherRevocationInfoFormat, otherRevocationInfo))); } /** * Add a Store of otherRevocationData to the CRL set to be included with the generated SignedData message. * * @param otherRevocationInfoFormat the OID specifying the format of the otherRevocationInfo data. * @param otherRevocationInfos a Store of otherRevocationInfo data to add. */ public void addOtherRevocationInfo( ASN1ObjectIdentifier otherRevocationInfoFormat, Store otherRevocationInfos) { crls.addAll(CMSUtils.getOthersFromStore(otherRevocationInfoFormat, otherRevocationInfos)); } /** * Add the attribute certificates contained in the passed in store to the * generator. * * @param store a store of Version 2 attribute certificates * @throws CMSException if an error occurse processing the store. * @deprecated use basic Store method */ public void addAttributeCertificates( X509Store store) throws CMSException { try { for (Iterator it = store.getMatches(null).iterator(); it.hasNext();) { X509AttributeCertificate attrCert = (X509AttributeCertificate)it.next(); certs.add(new DERTaggedObject(false, 2, AttributeCertificate.getInstance(ASN1Primitive.fromByteArray(attrCert.getEncoded())))); } } catch (IllegalArgumentException e) { throw new CMSException("error processing attribute certs", e); } catch (IOException e) { throw new CMSException("error processing attribute certs", e); } } /** * Add a store of precalculated signers to the generator. * * @param signerStore store of signers */ public void addSigners( SignerInformationStore signerStore) { Iterator it = signerStore.getSigners().iterator(); while (it.hasNext()) { _signers.add(it.next()); } } public void addSignerInfoGenerator(SignerInfoGenerator infoGen) { signerGens.add(infoGen); } /** * Return a map of oids and byte arrays representing the digests calculated on the content during * the last generate. * * @return a map of oids (as String objects) and byte[] representing digests. */ public Map getGeneratedDigests() { return new HashMap(digests); } } bouncycastle-1.49.orig/src/org/bouncycastle/cms/PKCS5Scheme2UTF8PBEKey.java0000644000175000017500000000221411442065637025641 0ustar ebourgebourgpackage org.bouncycastle.cms; import java.security.AlgorithmParameters; import java.security.InvalidAlgorithmParameterException; import org.bouncycastle.crypto.PBEParametersGenerator; import org.bouncycastle.crypto.generators.PKCS5S2ParametersGenerator; import org.bouncycastle.crypto.params.KeyParameter; /** * PKCS5 scheme-2 - password converted to bytes using UTF-8. */ public class PKCS5Scheme2UTF8PBEKey extends CMSPBEKey { public PKCS5Scheme2UTF8PBEKey(char[] password, byte[] salt, int iterationCount) { super(password, salt, iterationCount); } public PKCS5Scheme2UTF8PBEKey(char[] password, AlgorithmParameters pbeParams) throws InvalidAlgorithmParameterException { super(password, getParamSpec(pbeParams)); } byte[] getEncoded(String algorithmOid) { PKCS5S2ParametersGenerator gen = new PKCS5S2ParametersGenerator(); gen.init(PBEParametersGenerator.PKCS5PasswordToUTF8Bytes(this.getPassword()), this.getSalt(), this.getIterationCount()); return ((KeyParameter)gen.generateDerivedParameters(CMSEnvelopedHelper.INSTANCE.getKeySize(algorithmOid))).getKey(); } }bouncycastle-1.49.orig/src/org/bouncycastle/cms/CMSSignedDataGenerator.java0000644000175000017500000006734512116300356026360 0ustar ebourgebourgpackage org.bouncycastle.cms; import java.io.ByteArrayOutputStream; import java.io.IOException; import java.io.OutputStream; import java.security.NoSuchAlgorithmException; import java.security.NoSuchProviderException; import java.security.PrivateKey; import java.security.Provider; import java.security.SecureRandom; import java.security.cert.CertificateEncodingException; import java.security.cert.X509Certificate; import java.util.ArrayList; import java.util.Iterator; import java.util.List; import org.bouncycastle.asn1.ASN1EncodableVector; import org.bouncycastle.asn1.ASN1ObjectIdentifier; import org.bouncycastle.asn1.ASN1OctetString; import org.bouncycastle.asn1.ASN1Set; import org.bouncycastle.asn1.BEROctetString; import org.bouncycastle.asn1.DERSet; import org.bouncycastle.asn1.cms.AttributeTable; import org.bouncycastle.asn1.cms.CMSObjectIdentifiers; import org.bouncycastle.asn1.cms.ContentInfo; import org.bouncycastle.asn1.cms.SignedData; import org.bouncycastle.asn1.cms.SignerInfo; import org.bouncycastle.cms.jcajce.JcaSignerInfoGeneratorBuilder; import org.bouncycastle.operator.ContentSigner; import org.bouncycastle.operator.OperatorCreationException; import org.bouncycastle.operator.bc.BcDigestCalculatorProvider; import org.bouncycastle.operator.jcajce.JcaContentSignerBuilder; /** * general class for generating a pkcs7-signature message. *

    * A simple example of usage, generating a detached signature. * *

     *      List             certList = new ArrayList();
     *      CMSTypedData     msg = new CMSProcessableByteArray("Hello world!".getBytes());
     *
     *      certList.add(signCert);
     *
     *      Store           certs = new JcaCertStore(certList);
     *
     *      CMSSignedDataGenerator gen = new CMSSignedDataGenerator();
     *      ContentSigner sha1Signer = new JcaContentSignerBuilder("SHA1withRSA").setProvider("BC").build(signKP.getPrivate());
     *
     *      gen.addSignerInfoGenerator(
     *                new JcaSignerInfoGeneratorBuilder(
     *                     new JcaDigestCalculatorProviderBuilder().setProvider("BC").build())
     *                     .build(sha1Signer, signCert));
     *
     *      gen.addCertificates(certs);
     *
     *      CMSSignedData sigData = gen.generate(msg, false);
     * 
    */ public class CMSSignedDataGenerator extends CMSSignedGenerator { private List signerInfs = new ArrayList(); private class SignerInf { final PrivateKey key; final Object signerIdentifier; final String digestOID; final String encOID; final CMSAttributeTableGenerator sAttr; final CMSAttributeTableGenerator unsAttr; final AttributeTable baseSignedTable; SignerInf( PrivateKey key, Object signerIdentifier, String digestOID, String encOID, CMSAttributeTableGenerator sAttr, CMSAttributeTableGenerator unsAttr, AttributeTable baseSignedTable) { this.key = key; this.signerIdentifier = signerIdentifier; this.digestOID = digestOID; this.encOID = encOID; this.sAttr = sAttr; this.unsAttr = unsAttr; this.baseSignedTable = baseSignedTable; } SignerInfoGenerator toSignerInfoGenerator( SecureRandom random, Provider sigProvider, boolean addDefaultAttributes) throws IOException, CertificateEncodingException, CMSException, OperatorCreationException, NoSuchAlgorithmException { String digestName = CMSSignedHelper.INSTANCE.getDigestAlgName(digestOID); String signatureName = digestName + "with" + CMSSignedHelper.INSTANCE.getEncryptionAlgName(encOID); JcaSignerInfoGeneratorBuilder builder = new JcaSignerInfoGeneratorBuilder(new BcDigestCalculatorProvider()); if (addDefaultAttributes) { builder.setSignedAttributeGenerator(sAttr); } builder.setDirectSignature(!addDefaultAttributes); builder.setUnsignedAttributeGenerator(unsAttr); JcaContentSignerBuilder signerBuilder; try { signerBuilder = new JcaContentSignerBuilder(signatureName).setSecureRandom(random); } catch (IllegalArgumentException e) { throw new NoSuchAlgorithmException(e.getMessage()); } if (sigProvider != null) { signerBuilder.setProvider(sigProvider); } ContentSigner contentSigner = signerBuilder.build(key); if (signerIdentifier instanceof X509Certificate) { return builder.build(contentSigner, (X509Certificate)signerIdentifier); } else { return builder.build(contentSigner, (byte[])signerIdentifier); } } } /** * base constructor */ public CMSSignedDataGenerator() { } /** * constructor allowing specific source of randomness * @param rand instance of SecureRandom to use * @deprecated rand ignored in new API, use base constructor. */ public CMSSignedDataGenerator( SecureRandom rand) { super(rand); } /** * add a signer - no attributes other than the default ones will be * provided here. * * @param key signing key to use * @param cert certificate containing corresponding public key * @param digestOID digest algorithm OID * @deprecated use addSignerInfoGenerator */ public void addSigner( PrivateKey key, X509Certificate cert, String digestOID) throws IllegalArgumentException { addSigner(key, cert, getEncOID(key, digestOID), digestOID); } /** * add a signer, specifying the digest encryption algorithm to use - no attributes other than the default ones will be * provided here. * * @param key signing key to use * @param cert certificate containing corresponding public key * @param encryptionOID digest encryption algorithm OID * @param digestOID digest algorithm OID * @deprecated use addSignerInfoGenerator */ public void addSigner( PrivateKey key, X509Certificate cert, String encryptionOID, String digestOID) throws IllegalArgumentException { doAddSigner(key, cert, encryptionOID, digestOID, new DefaultSignedAttributeTableGenerator(), null, null); } /** * add a signer - no attributes other than the default ones will be * provided here. * @deprecated use addSignerInfoGenerator */ public void addSigner( PrivateKey key, byte[] subjectKeyID, String digestOID) throws IllegalArgumentException { addSigner(key, subjectKeyID, getEncOID(key, digestOID), digestOID); } /** * add a signer, specifying the digest encryption algorithm to use - no attributes other than the default ones will be * provided here. * @deprecated use addSignerInfoGenerator */ public void addSigner( PrivateKey key, byte[] subjectKeyID, String encryptionOID, String digestOID) throws IllegalArgumentException { doAddSigner(key, subjectKeyID, encryptionOID, digestOID, new DefaultSignedAttributeTableGenerator(), null, null); } /** * add a signer with extra signed/unsigned attributes. * * @param key signing key to use * @param cert certificate containing corresponding public key * @param digestOID digest algorithm OID * @param signedAttr table of attributes to be included in signature * @param unsignedAttr table of attributes to be included as unsigned * @deprecated use addSignerInfoGenerator */ public void addSigner( PrivateKey key, X509Certificate cert, String digestOID, AttributeTable signedAttr, AttributeTable unsignedAttr) throws IllegalArgumentException { addSigner(key, cert, getEncOID(key, digestOID), digestOID, signedAttr, unsignedAttr); } /** * add a signer, specifying the digest encryption algorithm, with extra signed/unsigned attributes. * * @param key signing key to use * @param cert certificate containing corresponding public key * @param encryptionOID digest encryption algorithm OID * @param digestOID digest algorithm OID * @param signedAttr table of attributes to be included in signature * @param unsignedAttr table of attributes to be included as unsigned * @deprecated use addSignerInfoGenerator */ public void addSigner( PrivateKey key, X509Certificate cert, String encryptionOID, String digestOID, AttributeTable signedAttr, AttributeTable unsignedAttr) throws IllegalArgumentException { doAddSigner(key, cert, encryptionOID, digestOID, new DefaultSignedAttributeTableGenerator(signedAttr), new SimpleAttributeTableGenerator(unsignedAttr), signedAttr); } /** * add a signer with extra signed/unsigned attributes. * * @param key signing key to use * @param subjectKeyID subjectKeyID of corresponding public key * @param digestOID digest algorithm OID * @param signedAttr table of attributes to be included in signature * @param unsignedAttr table of attributes to be included as unsigned * @deprecated use addSignerInfoGenerator */ public void addSigner( PrivateKey key, byte[] subjectKeyID, String digestOID, AttributeTable signedAttr, AttributeTable unsignedAttr) throws IllegalArgumentException { addSigner(key, subjectKeyID, getEncOID(key, digestOID), digestOID, signedAttr, unsignedAttr); } /** * add a signer, specifying the digest encryption algorithm, with extra signed/unsigned attributes. * * @param key signing key to use * @param subjectKeyID subjectKeyID of corresponding public key * @param encryptionOID digest encryption algorithm OID * @param digestOID digest algorithm OID * @param signedAttr table of attributes to be included in signature * @param unsignedAttr table of attributes to be included as unsigned * @deprecated use addSignerInfoGenerator */ public void addSigner( PrivateKey key, byte[] subjectKeyID, String encryptionOID, String digestOID, AttributeTable signedAttr, AttributeTable unsignedAttr) throws IllegalArgumentException { doAddSigner(key, subjectKeyID, encryptionOID, digestOID, new DefaultSignedAttributeTableGenerator(signedAttr), new SimpleAttributeTableGenerator(unsignedAttr), signedAttr); } /** * add a signer with extra signed/unsigned attributes based on generators. * @deprecated use addSignerInfoGenerator */ public void addSigner( PrivateKey key, X509Certificate cert, String digestOID, CMSAttributeTableGenerator signedAttrGen, CMSAttributeTableGenerator unsignedAttrGen) throws IllegalArgumentException { addSigner(key, cert, getEncOID(key, digestOID), digestOID, signedAttrGen, unsignedAttrGen); } /** * add a signer, specifying the digest encryption algorithm, with extra signed/unsigned attributes based on generators. * @deprecated use addSignerInfoGenerator */ public void addSigner( PrivateKey key, X509Certificate cert, String encryptionOID, String digestOID, CMSAttributeTableGenerator signedAttrGen, CMSAttributeTableGenerator unsignedAttrGen) throws IllegalArgumentException { doAddSigner(key, cert, encryptionOID, digestOID, signedAttrGen, unsignedAttrGen, null); } /** * add a signer with extra signed/unsigned attributes based on generators. * @deprecated use addSignerInfoGenerator */ public void addSigner( PrivateKey key, byte[] subjectKeyID, String digestOID, CMSAttributeTableGenerator signedAttrGen, CMSAttributeTableGenerator unsignedAttrGen) throws IllegalArgumentException { addSigner(key, subjectKeyID, getEncOID(key, digestOID), digestOID, signedAttrGen, unsignedAttrGen); } /** * add a signer, including digest encryption algorithm, with extra signed/unsigned attributes based on generators. * @deprecated use addSignerInfoGenerator */ public void addSigner( PrivateKey key, byte[] subjectKeyID, String encryptionOID, String digestOID, CMSAttributeTableGenerator signedAttrGen, CMSAttributeTableGenerator unsignedAttrGen) throws IllegalArgumentException { doAddSigner(key, subjectKeyID, encryptionOID, digestOID, signedAttrGen, unsignedAttrGen, null); } private void doAddSigner( PrivateKey key, Object signerIdentifier, String encryptionOID, String digestOID, CMSAttributeTableGenerator signedAttrGen, CMSAttributeTableGenerator unsignedAttrGen, AttributeTable baseSignedTable) throws IllegalArgumentException { signerInfs.add(new SignerInf(key, signerIdentifier, digestOID, encryptionOID, signedAttrGen, unsignedAttrGen, baseSignedTable)); } /** * generate a signed object that for a CMS Signed Data * object using the given provider. * @deprecated use generate() method not taking provider. */ public CMSSignedData generate( CMSProcessable content, String sigProvider) throws NoSuchAlgorithmException, NoSuchProviderException, CMSException { return generate(content, CMSUtils.getProvider(sigProvider)); } /** * generate a signed object that for a CMS Signed Data * object using the given provider. * @deprecated use generate() method not taking provider. */ public CMSSignedData generate( CMSProcessable content, Provider sigProvider) throws NoSuchAlgorithmException, CMSException { return generate(content, false, sigProvider); } /** * generate a signed object that for a CMS Signed Data * object using the given provider - if encapsulate is true a copy * of the message will be included in the signature. The content type * is set according to the OID represented by the string signedContentType. * @deprecated use generate(CMSTypedData, boolean) */ public CMSSignedData generate( String eContentType, CMSProcessable content, boolean encapsulate, String sigProvider) throws NoSuchAlgorithmException, NoSuchProviderException, CMSException { return generate(eContentType, content, encapsulate, CMSUtils.getProvider(sigProvider), true); } /** * generate a signed object that for a CMS Signed Data * object using the given provider - if encapsulate is true a copy * of the message will be included in the signature. The content type * is set according to the OID represented by the string signedContentType. * @deprecated use generate(CMSTypedData, boolean) */ public CMSSignedData generate( String eContentType, CMSProcessable content, boolean encapsulate, Provider sigProvider) throws NoSuchAlgorithmException, CMSException { return generate(eContentType, content, encapsulate, sigProvider, true); } /** * Similar method to the other generate methods. The additional argument * addDefaultAttributes indicates whether or not a default set of signed attributes * need to be added automatically. If the argument is set to false, no * attributes will get added at all. * @deprecated use generate(CMSTypedData, boolean) */ public CMSSignedData generate( String eContentType, CMSProcessable content, boolean encapsulate, String sigProvider, boolean addDefaultAttributes) throws NoSuchAlgorithmException, NoSuchProviderException, CMSException { return generate(eContentType, content, encapsulate, CMSUtils.getProvider(sigProvider), addDefaultAttributes); } /** * Similar method to the other generate methods. The additional argument * addDefaultAttributes indicates whether or not a default set of signed attributes * need to be added automatically. If the argument is set to false, no * attributes will get added at all. * @deprecated use setDirectSignature() on SignerInformationGenerator. */ public CMSSignedData generate( String eContentType, final CMSProcessable content, boolean encapsulate, Provider sigProvider, boolean addDefaultAttributes) throws NoSuchAlgorithmException, CMSException { boolean isCounterSignature = (eContentType == null); final ASN1ObjectIdentifier contentTypeOID = isCounterSignature ? null : new ASN1ObjectIdentifier(eContentType); for (Iterator it = signerInfs.iterator(); it.hasNext();) { SignerInf signer = (SignerInf)it.next(); try { signerGens.add(signer.toSignerInfoGenerator(rand, sigProvider, addDefaultAttributes)); } catch (OperatorCreationException e) { throw new CMSException("exception creating signerInf", e); } catch (IOException e) { throw new CMSException("exception encoding attributes", e); } catch (CertificateEncodingException e) { throw new CMSException("error creating sid.", e); } } signerInfs.clear(); if (content != null) { return generate(new CMSTypedData() { public ASN1ObjectIdentifier getContentType() { return contentTypeOID; } public void write(OutputStream out) throws IOException, CMSException { content.write(out); } public Object getContent() { return content.getContent(); } }, encapsulate); } else { return generate(new CMSAbsentContent(contentTypeOID), encapsulate); } } /** * generate a signed object that for a CMS Signed Data * object using the given provider - if encapsulate is true a copy * of the message will be included in the signature with the * default content type "data". * @deprecated use generate(CMSTypedData, boolean) */ public CMSSignedData generate( CMSProcessable content, boolean encapsulate, String sigProvider) throws NoSuchAlgorithmException, NoSuchProviderException, CMSException { if (content instanceof CMSTypedData) { return this.generate(((CMSTypedData)content).getContentType().getId(), content, encapsulate, sigProvider); } else { return this.generate(DATA, content, encapsulate, sigProvider); } } /** * generate a signed object that for a CMS Signed Data * object using the given provider - if encapsulate is true a copy * of the message will be included in the signature with the * default content type "data". * @deprecated use generate(CMSTypedData, boolean) */ public CMSSignedData generate( CMSProcessable content, boolean encapsulate, Provider sigProvider) throws NoSuchAlgorithmException, CMSException { if (content instanceof CMSTypedData) { return this.generate(((CMSTypedData)content).getContentType().getId(), content, encapsulate, sigProvider); } else { return this.generate(DATA, content, encapsulate, sigProvider); } } public CMSSignedData generate( CMSTypedData content) throws CMSException { return generate(content, false); } public CMSSignedData generate( // FIXME Avoid accessing more than once to support CMSProcessableInputStream CMSTypedData content, boolean encapsulate) throws CMSException { if (!signerInfs.isEmpty()) { throw new IllegalStateException("this method can only be used with SignerInfoGenerator"); } // TODO // if (signerInfs.isEmpty()) // { // /* RFC 3852 5.2 // * "In the degenerate case where there are no signers, the // * EncapsulatedContentInfo value being "signed" is irrelevant. In this // * case, the content type within the EncapsulatedContentInfo value being // * "signed" MUST be id-data (as defined in section 4), and the content // * field of the EncapsulatedContentInfo value MUST be omitted." // */ // if (encapsulate) // { // throw new IllegalArgumentException("no signers, encapsulate must be false"); // } // if (!DATA.equals(eContentType)) // { // throw new IllegalArgumentException("no signers, eContentType must be id-data"); // } // } // // if (!DATA.equals(eContentType)) // { // /* RFC 3852 5.3 // * [The 'signedAttrs']... // * field is optional, but it MUST be present if the content type of // * the EncapsulatedContentInfo value being signed is not id-data. // */ // // TODO signedAttrs must be present for all signers // } ASN1EncodableVector digestAlgs = new ASN1EncodableVector(); ASN1EncodableVector signerInfos = new ASN1EncodableVector(); digests.clear(); // clear the current preserved digest state // // add the precalculated SignerInfo objects. // for (Iterator it = _signers.iterator(); it.hasNext();) { SignerInformation signer = (SignerInformation)it.next(); digestAlgs.add(CMSSignedHelper.INSTANCE.fixAlgID(signer.getDigestAlgorithmID())); // TODO Verify the content type and calculated digest match the precalculated SignerInfo signerInfos.add(signer.toASN1Structure()); } // // add the SignerInfo objects // ASN1ObjectIdentifier contentTypeOID = content.getContentType(); ASN1OctetString octs = null; if (content != null) { ByteArrayOutputStream bOut = null; if (encapsulate) { bOut = new ByteArrayOutputStream(); } OutputStream cOut = CMSUtils.attachSignersToOutputStream(signerGens, bOut); // Just in case it's unencapsulated and there are no signers! cOut = CMSUtils.getSafeOutputStream(cOut); try { content.write(cOut); cOut.close(); } catch (IOException e) { throw new CMSException("data processing exception: " + e.getMessage(), e); } if (encapsulate) { octs = new BEROctetString(bOut.toByteArray()); } } for (Iterator it = signerGens.iterator(); it.hasNext();) { SignerInfoGenerator sGen = (SignerInfoGenerator)it.next(); SignerInfo inf = sGen.generate(contentTypeOID); digestAlgs.add(inf.getDigestAlgorithm()); signerInfos.add(inf); byte[] calcDigest = sGen.getCalculatedDigest(); if (calcDigest != null) { digests.put(inf.getDigestAlgorithm().getAlgorithm().getId(), calcDigest); } } ASN1Set certificates = null; if (certs.size() != 0) { certificates = CMSUtils.createBerSetFromList(certs); } ASN1Set certrevlist = null; if (crls.size() != 0) { certrevlist = CMSUtils.createBerSetFromList(crls); } ContentInfo encInfo = new ContentInfo(contentTypeOID, octs); SignedData sd = new SignedData( new DERSet(digestAlgs), encInfo, certificates, certrevlist, new DERSet(signerInfos)); ContentInfo contentInfo = new ContentInfo( CMSObjectIdentifiers.signedData, sd); return new CMSSignedData(content, contentInfo); } /** * generate a set of one or more SignerInformation objects representing counter signatures on * the passed in SignerInformation object. * * @param signer the signer to be countersigned * @param sigProvider the provider to be used for counter signing. * @return a store containing the signers. * @deprecated use generateCounterSigners(SignerInformation) */ public SignerInformationStore generateCounterSigners(SignerInformation signer, Provider sigProvider) throws NoSuchAlgorithmException, CMSException { return this.generate(null, new CMSProcessableByteArray(signer.getSignature()), false, sigProvider).getSignerInfos(); } /** * generate a set of one or more SignerInformation objects representing counter signatures on * the passed in SignerInformation object. * * @param signer the signer to be countersigned * @param sigProvider the provider to be used for counter signing. * @return a store containing the signers. * @deprecated use generateCounterSigners(SignerInformation) */ public SignerInformationStore generateCounterSigners(SignerInformation signer, String sigProvider) throws NoSuchAlgorithmException, NoSuchProviderException, CMSException { return this.generate(null, new CMSProcessableByteArray(signer.getSignature()), false, CMSUtils.getProvider(sigProvider)).getSignerInfos(); } /** * generate a set of one or more SignerInformation objects representing counter signatures on * the passed in SignerInformation object. * * @param signer the signer to be countersigned * @return a store containing the signers. */ public SignerInformationStore generateCounterSigners(SignerInformation signer) throws CMSException { return this.generate(new CMSProcessableByteArray(null, signer.getSignature()), false).getSignerInfos(); } } bouncycastle-1.49.orig/src/org/bouncycastle/cms/DefaultSignedAttributeTableGenerator.java0000644000175000017500000000630111737173441031360 0ustar ebourgebourgpackage org.bouncycastle.cms; import java.util.Date; import java.util.Hashtable; import java.util.Map; import org.bouncycastle.asn1.ASN1ObjectIdentifier; import org.bouncycastle.asn1.DEROctetString; import org.bouncycastle.asn1.DERSet; import org.bouncycastle.asn1.cms.Attribute; import org.bouncycastle.asn1.cms.AttributeTable; import org.bouncycastle.asn1.cms.CMSAttributes; import org.bouncycastle.asn1.cms.Time; /** * Default signed attributes generator. */ public class DefaultSignedAttributeTableGenerator implements CMSAttributeTableGenerator { private final Hashtable table; /** * Initialise to use all defaults */ public DefaultSignedAttributeTableGenerator() { table = new Hashtable(); } /** * Initialise with some extra attributes or overrides. * * @param attributeTable initial attribute table to use. */ public DefaultSignedAttributeTableGenerator( AttributeTable attributeTable) { if (attributeTable != null) { table = attributeTable.toHashtable(); } else { table = new Hashtable(); } } /** * Create a standard attribute table from the passed in parameters - this will * normally include contentType, signingTime, and messageDigest. If the constructor * using an AttributeTable was used, entries in it for contentType, signingTime, and * messageDigest will override the generated ones. * * @param parameters source parameters for table generation. * * @return a filled in Hashtable of attributes. */ protected Hashtable createStandardAttributeTable( Map parameters) { Hashtable std = (Hashtable)table.clone(); if (!std.containsKey(CMSAttributes.contentType)) { ASN1ObjectIdentifier contentType = ASN1ObjectIdentifier.getInstance( parameters.get(CMSAttributeTableGenerator.CONTENT_TYPE)); // contentType will be null if we're trying to generate a counter signature. if (contentType != null) { Attribute attr = new Attribute(CMSAttributes.contentType, new DERSet(contentType)); std.put(attr.getAttrType(), attr); } } if (!std.containsKey(CMSAttributes.signingTime)) { Date signingTime = new Date(); Attribute attr = new Attribute(CMSAttributes.signingTime, new DERSet(new Time(signingTime))); std.put(attr.getAttrType(), attr); } if (!std.containsKey(CMSAttributes.messageDigest)) { byte[] messageDigest = (byte[])parameters.get( CMSAttributeTableGenerator.DIGEST); Attribute attr = new Attribute(CMSAttributes.messageDigest, new DERSet(new DEROctetString(messageDigest))); std.put(attr.getAttrType(), attr); } return std; } /** * @param parameters source parameters * @return the populated attribute table */ public AttributeTable getAttributes(Map parameters) { return new AttributeTable(createStandardAttributeTable(parameters)); } } bouncycastle-1.49.orig/src/org/bouncycastle/cms/CMSSignerDigestMismatchException.java0000644000175000017500000000031311446776622030442 0ustar ebourgebourgpackage org.bouncycastle.cms; public class CMSSignerDigestMismatchException extends CMSException { public CMSSignerDigestMismatchException( String msg) { super(msg); } } bouncycastle-1.49.orig/src/org/bouncycastle/cms/bc/0000755000175000017500000000000012152033551021645 5ustar ebourgebourgbouncycastle-1.49.orig/src/org/bouncycastle/cms/bc/BcKeyTransRecipient.java0000644000175000017500000000246011737206560026374 0ustar ebourgebourgpackage org.bouncycastle.cms.bc; import org.bouncycastle.asn1.x509.AlgorithmIdentifier; import org.bouncycastle.cms.CMSException; import org.bouncycastle.cms.KeyTransRecipient; import org.bouncycastle.crypto.CipherParameters; import org.bouncycastle.crypto.params.AsymmetricKeyParameter; import org.bouncycastle.operator.AsymmetricKeyUnwrapper; import org.bouncycastle.operator.OperatorException; import org.bouncycastle.operator.bc.BcRSAAsymmetricKeyUnwrapper; public abstract class BcKeyTransRecipient implements KeyTransRecipient { private AsymmetricKeyParameter recipientKey; public BcKeyTransRecipient(AsymmetricKeyParameter recipientKey) { this.recipientKey = recipientKey; } protected CipherParameters extractSecretKey(AlgorithmIdentifier keyEncryptionAlgorithm, AlgorithmIdentifier encryptedKeyAlgorithm, byte[] encryptedEncryptionKey) throws CMSException { AsymmetricKeyUnwrapper unwrapper = new BcRSAAsymmetricKeyUnwrapper(keyEncryptionAlgorithm, recipientKey); try { return CMSUtils.getBcKey(unwrapper.generateUnwrappedKey(encryptedKeyAlgorithm, encryptedEncryptionKey)); } catch (OperatorException e) { throw new CMSException("exception unwrapping key: " + e.getMessage(), e); } } } bouncycastle-1.49.orig/src/org/bouncycastle/cms/bc/BcCMSContentEncryptorBuilder.java0000644000175000017500000000726112103441027030152 0ustar ebourgebourgpackage org.bouncycastle.cms.bc; import java.io.OutputStream; import java.security.SecureRandom; import java.util.HashMap; import java.util.Map; import org.bouncycastle.asn1.ASN1ObjectIdentifier; import org.bouncycastle.asn1.x509.AlgorithmIdentifier; import org.bouncycastle.cms.CMSAlgorithm; import org.bouncycastle.cms.CMSException; import org.bouncycastle.crypto.BufferedBlockCipher; import org.bouncycastle.crypto.CipherKeyGenerator; import org.bouncycastle.crypto.StreamCipher; import org.bouncycastle.crypto.io.CipherOutputStream; import org.bouncycastle.crypto.params.KeyParameter; import org.bouncycastle.operator.GenericKey; import org.bouncycastle.operator.OutputEncryptor; import org.bouncycastle.util.Integers; public class BcCMSContentEncryptorBuilder { private static Map keySizes = new HashMap(); static { keySizes.put(CMSAlgorithm.AES128_CBC, Integers.valueOf(128)); keySizes.put(CMSAlgorithm.AES192_CBC, Integers.valueOf(192)); keySizes.put(CMSAlgorithm.AES256_CBC, Integers.valueOf(256)); keySizes.put(CMSAlgorithm.CAMELLIA128_CBC, Integers.valueOf(128)); keySizes.put(CMSAlgorithm.CAMELLIA192_CBC, Integers.valueOf(192)); keySizes.put(CMSAlgorithm.CAMELLIA256_CBC, Integers.valueOf(256)); } private static int getKeySize(ASN1ObjectIdentifier oid) { Integer size = (Integer)keySizes.get(oid); if (size != null) { return size.intValue(); } return -1; } private final ASN1ObjectIdentifier encryptionOID; private final int keySize; private EnvelopedDataHelper helper = new EnvelopedDataHelper(); private SecureRandom random; public BcCMSContentEncryptorBuilder(ASN1ObjectIdentifier encryptionOID) { this(encryptionOID, getKeySize(encryptionOID)); } public BcCMSContentEncryptorBuilder(ASN1ObjectIdentifier encryptionOID, int keySize) { this.encryptionOID = encryptionOID; this.keySize = keySize; } public BcCMSContentEncryptorBuilder setSecureRandom(SecureRandom random) { this.random = random; return this; } public OutputEncryptor build() throws CMSException { return new CMSOutputEncryptor(encryptionOID, keySize, random); } private class CMSOutputEncryptor implements OutputEncryptor { private KeyParameter encKey; private AlgorithmIdentifier algorithmIdentifier; private Object cipher; CMSOutputEncryptor(ASN1ObjectIdentifier encryptionOID, int keySize, SecureRandom random) throws CMSException { if (random == null) { random = new SecureRandom(); } CipherKeyGenerator keyGen = helper.createKeyGenerator(encryptionOID, random); encKey = new KeyParameter(keyGen.generateKey()); algorithmIdentifier = helper.generateAlgorithmIdentifier(encryptionOID, encKey, random); cipher = helper.createContentCipher(true, encKey, algorithmIdentifier); } public AlgorithmIdentifier getAlgorithmIdentifier() { return algorithmIdentifier; } public OutputStream getOutputStream(OutputStream dOut) { if (cipher instanceof BufferedBlockCipher) { return new CipherOutputStream(dOut, (BufferedBlockCipher)cipher); } else { return new CipherOutputStream(dOut, (StreamCipher)cipher); } } public GenericKey getKey() { return new GenericKey(algorithmIdentifier, encKey.getKey()); } } } bouncycastle-1.49.orig/src/org/bouncycastle/cms/bc/BcKEKRecipientInfoGenerator.java0000644000175000017500000000115011737210072027715 0ustar ebourgebourgpackage org.bouncycastle.cms.bc; import org.bouncycastle.asn1.cms.KEKIdentifier; import org.bouncycastle.cms.KEKRecipientInfoGenerator; import org.bouncycastle.operator.bc.BcSymmetricKeyWrapper; public class BcKEKRecipientInfoGenerator extends KEKRecipientInfoGenerator { public BcKEKRecipientInfoGenerator(KEKIdentifier kekIdentifier, BcSymmetricKeyWrapper kekWrapper) { super(kekIdentifier, kekWrapper); } public BcKEKRecipientInfoGenerator(byte[] keyIdentifier, BcSymmetricKeyWrapper kekWrapper) { this(new KEKIdentifier(keyIdentifier, null, null), kekWrapper); } } bouncycastle-1.49.orig/src/org/bouncycastle/cms/bc/CMSUtils.java0000644000175000017500000000116711737210072024163 0ustar ebourgebourgpackage org.bouncycastle.cms.bc; import org.bouncycastle.crypto.CipherParameters; import org.bouncycastle.crypto.params.KeyParameter; import org.bouncycastle.operator.GenericKey; class CMSUtils { static CipherParameters getBcKey(GenericKey key) { if (key.getRepresentation() instanceof CipherParameters) { return (CipherParameters)key.getRepresentation(); } if (key.getRepresentation() instanceof byte[]) { return new KeyParameter((byte[])key.getRepresentation()); } throw new IllegalArgumentException("unknown generic key type"); } } bouncycastle-1.49.orig/src/org/bouncycastle/cms/bc/EnvelopedDataHelper.java0000644000175000017500000004024111737206351026374 0ustar ebourgebourgpackage org.bouncycastle.cms.bc; import java.security.SecureRandom; import java.util.HashMap; import java.util.Map; import org.bouncycastle.asn1.ASN1Null; import org.bouncycastle.asn1.ASN1ObjectIdentifier; import org.bouncycastle.asn1.ASN1OctetString; import org.bouncycastle.asn1.ASN1Primitive; import org.bouncycastle.asn1.DERNull; import org.bouncycastle.asn1.DEROctetString; import org.bouncycastle.asn1.kisa.KISAObjectIdentifiers; import org.bouncycastle.asn1.misc.CAST5CBCParameters; import org.bouncycastle.asn1.nist.NISTObjectIdentifiers; import org.bouncycastle.asn1.ntt.NTTObjectIdentifiers; import org.bouncycastle.asn1.oiw.OIWObjectIdentifiers; import org.bouncycastle.asn1.pkcs.PKCSObjectIdentifiers; import org.bouncycastle.asn1.pkcs.RC2CBCParameter; import org.bouncycastle.asn1.x509.AlgorithmIdentifier; import org.bouncycastle.cms.CMSAlgorithm; import org.bouncycastle.cms.CMSException; import org.bouncycastle.crypto.BlockCipher; import org.bouncycastle.crypto.BufferedBlockCipher; import org.bouncycastle.crypto.CipherKeyGenerator; import org.bouncycastle.crypto.CipherParameters; import org.bouncycastle.crypto.KeyGenerationParameters; import org.bouncycastle.crypto.StreamCipher; import org.bouncycastle.crypto.Wrapper; import org.bouncycastle.crypto.engines.AESEngine; import org.bouncycastle.crypto.engines.DESEngine; import org.bouncycastle.crypto.engines.DESedeEngine; import org.bouncycastle.crypto.engines.RC2Engine; import org.bouncycastle.crypto.engines.RC4Engine; import org.bouncycastle.crypto.engines.RFC3211WrapEngine; import org.bouncycastle.crypto.generators.DESKeyGenerator; import org.bouncycastle.crypto.generators.DESedeKeyGenerator; import org.bouncycastle.crypto.modes.CBCBlockCipher; import org.bouncycastle.crypto.paddings.PKCS7Padding; import org.bouncycastle.crypto.paddings.PaddedBufferedBlockCipher; import org.bouncycastle.crypto.params.KeyParameter; import org.bouncycastle.crypto.params.ParametersWithIV; import org.bouncycastle.crypto.params.RC2Parameters; class EnvelopedDataHelper { protected static final Map BASE_CIPHER_NAMES = new HashMap(); protected static final Map CIPHER_ALG_NAMES = new HashMap(); protected static final Map MAC_ALG_NAMES = new HashMap(); static { BASE_CIPHER_NAMES.put(CMSAlgorithm.DES_EDE3_CBC, "DESEDE"); BASE_CIPHER_NAMES.put(CMSAlgorithm.AES128_CBC, "AES"); BASE_CIPHER_NAMES.put(CMSAlgorithm.AES192_CBC, "AES"); BASE_CIPHER_NAMES.put(CMSAlgorithm.AES256_CBC, "AES"); CIPHER_ALG_NAMES.put(CMSAlgorithm.DES_EDE3_CBC, "DESEDE/CBC/PKCS5Padding"); CIPHER_ALG_NAMES.put(CMSAlgorithm.AES128_CBC, "AES/CBC/PKCS5Padding"); CIPHER_ALG_NAMES.put(CMSAlgorithm.AES192_CBC, "AES/CBC/PKCS5Padding"); CIPHER_ALG_NAMES.put(CMSAlgorithm.AES256_CBC, "AES/CBC/PKCS5Padding"); CIPHER_ALG_NAMES.put(new ASN1ObjectIdentifier(PKCSObjectIdentifiers.rsaEncryption.getId()), "RSA/ECB/PKCS1Padding"); CIPHER_ALG_NAMES.put(CMSAlgorithm.CAST5_CBC, "CAST5/CBC/PKCS5Padding"); CIPHER_ALG_NAMES.put(CMSAlgorithm.CAMELLIA128_CBC, "Camellia/CBC/PKCS5Padding"); CIPHER_ALG_NAMES.put(CMSAlgorithm.CAMELLIA192_CBC, "Camellia/CBC/PKCS5Padding"); CIPHER_ALG_NAMES.put(CMSAlgorithm.CAMELLIA256_CBC, "Camellia/CBC/PKCS5Padding"); CIPHER_ALG_NAMES.put(CMSAlgorithm.SEED_CBC, "SEED/CBC/PKCS5Padding"); MAC_ALG_NAMES.put(CMSAlgorithm.DES_EDE3_CBC, "DESEDEMac"); MAC_ALG_NAMES.put(CMSAlgorithm.AES128_CBC, "AESMac"); MAC_ALG_NAMES.put(CMSAlgorithm.AES192_CBC, "AESMac"); MAC_ALG_NAMES.put(CMSAlgorithm.AES256_CBC, "AESMac"); MAC_ALG_NAMES.put(CMSAlgorithm.RC2_CBC, "RC2Mac"); } private static final short[] rc2Table = { 0xbd, 0x56, 0xea, 0xf2, 0xa2, 0xf1, 0xac, 0x2a, 0xb0, 0x93, 0xd1, 0x9c, 0x1b, 0x33, 0xfd, 0xd0, 0x30, 0x04, 0xb6, 0xdc, 0x7d, 0xdf, 0x32, 0x4b, 0xf7, 0xcb, 0x45, 0x9b, 0x31, 0xbb, 0x21, 0x5a, 0x41, 0x9f, 0xe1, 0xd9, 0x4a, 0x4d, 0x9e, 0xda, 0xa0, 0x68, 0x2c, 0xc3, 0x27, 0x5f, 0x80, 0x36, 0x3e, 0xee, 0xfb, 0x95, 0x1a, 0xfe, 0xce, 0xa8, 0x34, 0xa9, 0x13, 0xf0, 0xa6, 0x3f, 0xd8, 0x0c, 0x78, 0x24, 0xaf, 0x23, 0x52, 0xc1, 0x67, 0x17, 0xf5, 0x66, 0x90, 0xe7, 0xe8, 0x07, 0xb8, 0x60, 0x48, 0xe6, 0x1e, 0x53, 0xf3, 0x92, 0xa4, 0x72, 0x8c, 0x08, 0x15, 0x6e, 0x86, 0x00, 0x84, 0xfa, 0xf4, 0x7f, 0x8a, 0x42, 0x19, 0xf6, 0xdb, 0xcd, 0x14, 0x8d, 0x50, 0x12, 0xba, 0x3c, 0x06, 0x4e, 0xec, 0xb3, 0x35, 0x11, 0xa1, 0x88, 0x8e, 0x2b, 0x94, 0x99, 0xb7, 0x71, 0x74, 0xd3, 0xe4, 0xbf, 0x3a, 0xde, 0x96, 0x0e, 0xbc, 0x0a, 0xed, 0x77, 0xfc, 0x37, 0x6b, 0x03, 0x79, 0x89, 0x62, 0xc6, 0xd7, 0xc0, 0xd2, 0x7c, 0x6a, 0x8b, 0x22, 0xa3, 0x5b, 0x05, 0x5d, 0x02, 0x75, 0xd5, 0x61, 0xe3, 0x18, 0x8f, 0x55, 0x51, 0xad, 0x1f, 0x0b, 0x5e, 0x85, 0xe5, 0xc2, 0x57, 0x63, 0xca, 0x3d, 0x6c, 0xb4, 0xc5, 0xcc, 0x70, 0xb2, 0x91, 0x59, 0x0d, 0x47, 0x20, 0xc8, 0x4f, 0x58, 0xe0, 0x01, 0xe2, 0x16, 0x38, 0xc4, 0x6f, 0x3b, 0x0f, 0x65, 0x46, 0xbe, 0x7e, 0x2d, 0x7b, 0x82, 0xf9, 0x40, 0xb5, 0x1d, 0x73, 0xf8, 0xeb, 0x26, 0xc7, 0x87, 0x97, 0x25, 0x54, 0xb1, 0x28, 0xaa, 0x98, 0x9d, 0xa5, 0x64, 0x6d, 0x7a, 0xd4, 0x10, 0x81, 0x44, 0xef, 0x49, 0xd6, 0xae, 0x2e, 0xdd, 0x76, 0x5c, 0x2f, 0xa7, 0x1c, 0xc9, 0x09, 0x69, 0x9a, 0x83, 0xcf, 0x29, 0x39, 0xb9, 0xe9, 0x4c, 0xff, 0x43, 0xab }; private static final short[] rc2Ekb = { 0x5d, 0xbe, 0x9b, 0x8b, 0x11, 0x99, 0x6e, 0x4d, 0x59, 0xf3, 0x85, 0xa6, 0x3f, 0xb7, 0x83, 0xc5, 0xe4, 0x73, 0x6b, 0x3a, 0x68, 0x5a, 0xc0, 0x47, 0xa0, 0x64, 0x34, 0x0c, 0xf1, 0xd0, 0x52, 0xa5, 0xb9, 0x1e, 0x96, 0x43, 0x41, 0xd8, 0xd4, 0x2c, 0xdb, 0xf8, 0x07, 0x77, 0x2a, 0xca, 0xeb, 0xef, 0x10, 0x1c, 0x16, 0x0d, 0x38, 0x72, 0x2f, 0x89, 0xc1, 0xf9, 0x80, 0xc4, 0x6d, 0xae, 0x30, 0x3d, 0xce, 0x20, 0x63, 0xfe, 0xe6, 0x1a, 0xc7, 0xb8, 0x50, 0xe8, 0x24, 0x17, 0xfc, 0x25, 0x6f, 0xbb, 0x6a, 0xa3, 0x44, 0x53, 0xd9, 0xa2, 0x01, 0xab, 0xbc, 0xb6, 0x1f, 0x98, 0xee, 0x9a, 0xa7, 0x2d, 0x4f, 0x9e, 0x8e, 0xac, 0xe0, 0xc6, 0x49, 0x46, 0x29, 0xf4, 0x94, 0x8a, 0xaf, 0xe1, 0x5b, 0xc3, 0xb3, 0x7b, 0x57, 0xd1, 0x7c, 0x9c, 0xed, 0x87, 0x40, 0x8c, 0xe2, 0xcb, 0x93, 0x14, 0xc9, 0x61, 0x2e, 0xe5, 0xcc, 0xf6, 0x5e, 0xa8, 0x5c, 0xd6, 0x75, 0x8d, 0x62, 0x95, 0x58, 0x69, 0x76, 0xa1, 0x4a, 0xb5, 0x55, 0x09, 0x78, 0x33, 0x82, 0xd7, 0xdd, 0x79, 0xf5, 0x1b, 0x0b, 0xde, 0x26, 0x21, 0x28, 0x74, 0x04, 0x97, 0x56, 0xdf, 0x3c, 0xf0, 0x37, 0x39, 0xdc, 0xff, 0x06, 0xa4, 0xea, 0x42, 0x08, 0xda, 0xb4, 0x71, 0xb0, 0xcf, 0x12, 0x7a, 0x4e, 0xfa, 0x6c, 0x1d, 0x84, 0x00, 0xc8, 0x7f, 0x91, 0x45, 0xaa, 0x2b, 0xc2, 0xb1, 0x8f, 0xd5, 0xba, 0xf2, 0xad, 0x19, 0xb2, 0x67, 0x36, 0xf7, 0x0f, 0x0a, 0x92, 0x7d, 0xe3, 0x9d, 0xe9, 0x90, 0x3e, 0x23, 0x27, 0x66, 0x13, 0xec, 0x81, 0x15, 0xbd, 0x22, 0xbf, 0x9f, 0x7e, 0xa9, 0x51, 0x4b, 0x4c, 0xfb, 0x02, 0xd3, 0x70, 0x86, 0x31, 0xe7, 0x3b, 0x05, 0x03, 0x54, 0x60, 0x48, 0x65, 0x18, 0xd2, 0xcd, 0x5f, 0x32, 0x88, 0x0e, 0x35, 0xfd }; EnvelopedDataHelper() { } String getBaseCipherName(ASN1ObjectIdentifier algorithm) { String name = (String)BASE_CIPHER_NAMES.get(algorithm); if (name == null) { return algorithm.getId(); } return name; } static BufferedBlockCipher createCipher(ASN1ObjectIdentifier algorithm) throws CMSException { BlockCipher cipher; if (NISTObjectIdentifiers.id_aes128_CBC.equals(algorithm) || NISTObjectIdentifiers.id_aes192_CBC.equals(algorithm) || NISTObjectIdentifiers.id_aes256_CBC.equals(algorithm)) { cipher = new CBCBlockCipher(new AESEngine()); } else if (PKCSObjectIdentifiers.des_EDE3_CBC.equals(algorithm)) { cipher = new CBCBlockCipher(new DESedeEngine()); } else if (OIWObjectIdentifiers.desCBC.equals(algorithm)) { cipher = new CBCBlockCipher(new DESEngine()); } else if (PKCSObjectIdentifiers.RC2_CBC.equals(algorithm)) { cipher = new CBCBlockCipher(new RC2Engine()); } else { throw new CMSException("cannot recognise cipher: " + algorithm); } return new PaddedBufferedBlockCipher(cipher, new PKCS7Padding()); } static Wrapper createRFC3211Wrapper(ASN1ObjectIdentifier algorithm) throws CMSException { if (NISTObjectIdentifiers.id_aes128_CBC.equals(algorithm) || NISTObjectIdentifiers.id_aes192_CBC.equals(algorithm) || NISTObjectIdentifiers.id_aes256_CBC.equals(algorithm)) { return new RFC3211WrapEngine(new AESEngine()); } else if (PKCSObjectIdentifiers.des_EDE3_CBC.equals(algorithm)) { return new RFC3211WrapEngine(new DESedeEngine()); } else if (OIWObjectIdentifiers.desCBC.equals(algorithm)) { return new RFC3211WrapEngine(new DESEngine()); } else if (PKCSObjectIdentifiers.RC2_CBC.equals(algorithm)) { return new RFC3211WrapEngine(new RC2Engine()); } else { throw new CMSException("cannot recognise wrapper: " + algorithm); } } static Object createContentCipher(boolean forEncryption, CipherParameters encKey, AlgorithmIdentifier encryptionAlgID) throws CMSException { ASN1ObjectIdentifier encAlg = encryptionAlgID.getAlgorithm(); if (encAlg.equals(PKCSObjectIdentifiers.rc4)) { StreamCipher cipher = new RC4Engine(); cipher.init(forEncryption, encKey); return cipher; } else { BufferedBlockCipher cipher = createCipher(encryptionAlgID.getAlgorithm()); ASN1Primitive sParams = encryptionAlgID.getParameters().toASN1Primitive(); if (sParams != null && !(sParams instanceof ASN1Null)) { if (encAlg.equals(CMSAlgorithm.DES_EDE3_CBC) || encAlg.equals(CMSAlgorithm.IDEA_CBC) || encAlg.equals(CMSAlgorithm.AES128_CBC) || encAlg.equals(CMSAlgorithm.AES192_CBC) || encAlg.equals(CMSAlgorithm.AES256_CBC) || encAlg.equals(CMSAlgorithm.CAMELLIA128_CBC) || encAlg.equals(CMSAlgorithm.CAMELLIA192_CBC) || encAlg.equals(CMSAlgorithm.CAMELLIA256_CBC) || encAlg.equals(CMSAlgorithm.SEED_CBC) || encAlg.equals(OIWObjectIdentifiers.desCBC)) { cipher.init(forEncryption, new ParametersWithIV(encKey, ASN1OctetString.getInstance(sParams).getOctets())); } else if (encAlg.equals(CMSAlgorithm.CAST5_CBC)) { CAST5CBCParameters cbcParams = CAST5CBCParameters.getInstance(sParams); cipher.init(forEncryption, new ParametersWithIV(encKey, cbcParams.getIV())); } else if (encAlg.equals(CMSAlgorithm.RC2_CBC)) { RC2CBCParameter cbcParams = RC2CBCParameter.getInstance(sParams); cipher.init(forEncryption, new ParametersWithIV(new RC2Parameters(((KeyParameter)encKey).getKey(), rc2Ekb[cbcParams.getRC2ParameterVersion().intValue()]), cbcParams.getIV())); } else { throw new CMSException("cannot match parameters"); } } else { if (encAlg.equals(CMSAlgorithm.DES_EDE3_CBC) || encAlg.equals(CMSAlgorithm.IDEA_CBC) || encAlg.equals(CMSAlgorithm.CAST5_CBC)) { cipher.init(forEncryption, new ParametersWithIV(encKey, new byte[8])); } else { cipher.init(forEncryption, encKey); } } return cipher; } } AlgorithmIdentifier generateAlgorithmIdentifier(ASN1ObjectIdentifier encryptionOID, CipherParameters encKey, SecureRandom random) throws CMSException { if (encryptionOID.equals(CMSAlgorithm.AES128_CBC) || encryptionOID.equals(CMSAlgorithm.AES192_CBC) || encryptionOID.equals(CMSAlgorithm.AES256_CBC) || encryptionOID.equals(CMSAlgorithm.CAMELLIA128_CBC) || encryptionOID.equals(CMSAlgorithm.CAMELLIA192_CBC) || encryptionOID.equals(CMSAlgorithm.CAMELLIA256_CBC) || encryptionOID.equals(CMSAlgorithm.SEED_CBC)) { byte[] iv = new byte[16]; random.nextBytes(iv); return new AlgorithmIdentifier(encryptionOID, new DEROctetString(iv)); } else if (encryptionOID.equals(CMSAlgorithm.DES_EDE3_CBC) || encryptionOID.equals(CMSAlgorithm.IDEA_CBC) || encryptionOID.equals(OIWObjectIdentifiers.desCBC)) { byte[] iv = new byte[8]; random.nextBytes(iv); return new AlgorithmIdentifier(encryptionOID, new DEROctetString(iv)); } else if (encryptionOID.equals(CMSAlgorithm.CAST5_CBC)) { byte[] iv = new byte[8]; random.nextBytes(iv); CAST5CBCParameters cbcParams = new CAST5CBCParameters(iv, ((KeyParameter)encKey).getKey().length * 8); return new AlgorithmIdentifier(encryptionOID, cbcParams); } else if (encryptionOID.equals(PKCSObjectIdentifiers.rc4)) { return new AlgorithmIdentifier(encryptionOID, DERNull.INSTANCE); } else { throw new CMSException("unable to match algorithm"); } } CipherKeyGenerator createKeyGenerator(ASN1ObjectIdentifier algorithm, SecureRandom random) throws CMSException { if (NISTObjectIdentifiers.id_aes128_CBC.equals(algorithm)) { return createCipherKeyGenerator(random, 128); } else if (NISTObjectIdentifiers.id_aes192_CBC.equals(algorithm)) { return createCipherKeyGenerator(random, 192); } else if (NISTObjectIdentifiers.id_aes256_CBC.equals(algorithm)) { return createCipherKeyGenerator(random, 256); } else if (PKCSObjectIdentifiers.des_EDE3_CBC.equals(algorithm)) { DESedeKeyGenerator keyGen = new DESedeKeyGenerator(); keyGen.init(new KeyGenerationParameters(random, 192)); return keyGen; } else if (NTTObjectIdentifiers.id_camellia128_cbc.equals(algorithm)) { return createCipherKeyGenerator(random, 128); } else if (NTTObjectIdentifiers.id_camellia192_cbc.equals(algorithm)) { return createCipherKeyGenerator(random, 192); } else if (NTTObjectIdentifiers.id_camellia256_cbc.equals(algorithm)) { return createCipherKeyGenerator(random, 256); } else if (KISAObjectIdentifiers.id_seedCBC.equals(algorithm)) { return createCipherKeyGenerator(random, 128); } else if (CMSAlgorithm.CAST5_CBC.equals(algorithm)) { return createCipherKeyGenerator(random, 128); } else if (OIWObjectIdentifiers.desCBC.equals(algorithm)) { DESKeyGenerator keyGen = new DESKeyGenerator(); keyGen.init(new KeyGenerationParameters(random, 64)); return keyGen; } else if (PKCSObjectIdentifiers.rc4.equals(algorithm)) { return createCipherKeyGenerator(random, 128); } // else if (PKCSObjectIdentifiers.RC2_CBC.equals(algorithm)) // { // cipher = new CBCBlockCipher(new RC2Engine()); // } else { throw new CMSException("cannot recognise cipher: " + algorithm); } } private CipherKeyGenerator createCipherKeyGenerator(SecureRandom random, int keySize) { CipherKeyGenerator keyGen = new CipherKeyGenerator(); keyGen.init(new KeyGenerationParameters(random, keySize)); return keyGen; } } bouncycastle-1.49.orig/src/org/bouncycastle/cms/bc/BcRSAKeyTransEnvelopedRecipient.java0000644000175000017500000000345711737206560030613 0ustar ebourgebourgpackage org.bouncycastle.cms.bc; import java.io.InputStream; import org.bouncycastle.asn1.x509.AlgorithmIdentifier; import org.bouncycastle.cms.CMSException; import org.bouncycastle.cms.RecipientOperator; import org.bouncycastle.crypto.BufferedBlockCipher; import org.bouncycastle.crypto.CipherParameters; import org.bouncycastle.crypto.StreamCipher; import org.bouncycastle.crypto.io.CipherInputStream; import org.bouncycastle.crypto.params.AsymmetricKeyParameter; import org.bouncycastle.operator.InputDecryptor; public class BcRSAKeyTransEnvelopedRecipient extends BcKeyTransRecipient { public BcRSAKeyTransEnvelopedRecipient(AsymmetricKeyParameter key) { super(key); } public RecipientOperator getRecipientOperator(AlgorithmIdentifier keyEncryptionAlgorithm, final AlgorithmIdentifier contentEncryptionAlgorithm, byte[] encryptedContentEncryptionKey) throws CMSException { CipherParameters secretKey = extractSecretKey(keyEncryptionAlgorithm, contentEncryptionAlgorithm, encryptedContentEncryptionKey); final Object dataCipher = EnvelopedDataHelper.createContentCipher(false, secretKey, contentEncryptionAlgorithm); return new RecipientOperator(new InputDecryptor() { public AlgorithmIdentifier getAlgorithmIdentifier() { return contentEncryptionAlgorithm; } public InputStream getInputStream(InputStream dataIn) { if (dataCipher instanceof BufferedBlockCipher) { return new CipherInputStream(dataIn, (BufferedBlockCipher)dataCipher); } else { return new CipherInputStream(dataIn, (StreamCipher)dataCipher); } } }); } } bouncycastle-1.49.orig/src/org/bouncycastle/cms/bc/BcKEKEnvelopedRecipient.java0000644000175000017500000000346711737206560027120 0ustar ebourgebourgpackage org.bouncycastle.cms.bc; import java.io.InputStream; import org.bouncycastle.asn1.x509.AlgorithmIdentifier; import org.bouncycastle.cms.CMSException; import org.bouncycastle.cms.RecipientOperator; import org.bouncycastle.crypto.BufferedBlockCipher; import org.bouncycastle.crypto.StreamCipher; import org.bouncycastle.crypto.params.KeyParameter; import org.bouncycastle.operator.InputDecryptor; import org.bouncycastle.operator.bc.BcSymmetricKeyUnwrapper; public class BcKEKEnvelopedRecipient extends BcKEKRecipient { public BcKEKEnvelopedRecipient(BcSymmetricKeyUnwrapper unwrapper) { super(unwrapper); } public RecipientOperator getRecipientOperator(AlgorithmIdentifier keyEncryptionAlgorithm, final AlgorithmIdentifier contentEncryptionAlgorithm, byte[] encryptedContentEncryptionKey) throws CMSException { KeyParameter secretKey = (KeyParameter)extractSecretKey(keyEncryptionAlgorithm, contentEncryptionAlgorithm, encryptedContentEncryptionKey); final Object dataCipher = EnvelopedDataHelper.createContentCipher(false, secretKey, contentEncryptionAlgorithm); return new RecipientOperator(new InputDecryptor() { public AlgorithmIdentifier getAlgorithmIdentifier() { return contentEncryptionAlgorithm; } public InputStream getInputStream(InputStream dataOut) { if (dataCipher instanceof BufferedBlockCipher) { return new org.bouncycastle.crypto.io.CipherInputStream(dataOut, (BufferedBlockCipher)dataCipher); } else { return new org.bouncycastle.crypto.io.CipherInputStream(dataOut, (StreamCipher)dataCipher); } } }); } } bouncycastle-1.49.orig/src/org/bouncycastle/cms/bc/BcRSASignerInfoVerifierBuilder.java0000644000175000017500000000372011731765652030413 0ustar ebourgebourgpackage org.bouncycastle.cms.bc; import org.bouncycastle.cert.X509CertificateHolder; import org.bouncycastle.cms.CMSSignatureAlgorithmNameGenerator; import org.bouncycastle.cms.SignerInformationVerifier; import org.bouncycastle.crypto.params.AsymmetricKeyParameter; import org.bouncycastle.operator.DigestAlgorithmIdentifierFinder; import org.bouncycastle.operator.DigestCalculatorProvider; import org.bouncycastle.operator.OperatorCreationException; import org.bouncycastle.operator.SignatureAlgorithmIdentifierFinder; import org.bouncycastle.operator.bc.BcRSAContentVerifierProviderBuilder; public class BcRSASignerInfoVerifierBuilder { private BcRSAContentVerifierProviderBuilder contentVerifierProviderBuilder; private DigestCalculatorProvider digestCalculatorProvider; private CMSSignatureAlgorithmNameGenerator sigAlgNameGen; private SignatureAlgorithmIdentifierFinder sigAlgIdFinder; public BcRSASignerInfoVerifierBuilder(CMSSignatureAlgorithmNameGenerator sigAlgNameGen, SignatureAlgorithmIdentifierFinder sigAlgIdFinder, DigestAlgorithmIdentifierFinder digestAlgorithmFinder, DigestCalculatorProvider digestCalculatorProvider) { this.sigAlgNameGen = sigAlgNameGen; this.sigAlgIdFinder = sigAlgIdFinder; this.contentVerifierProviderBuilder = new BcRSAContentVerifierProviderBuilder(digestAlgorithmFinder); this.digestCalculatorProvider = digestCalculatorProvider; } public SignerInformationVerifier build(X509CertificateHolder certHolder) throws OperatorCreationException { return new SignerInformationVerifier(sigAlgNameGen, sigAlgIdFinder, contentVerifierProviderBuilder.build(certHolder), digestCalculatorProvider); } public SignerInformationVerifier build(AsymmetricKeyParameter pubKey) throws OperatorCreationException { return new SignerInformationVerifier(sigAlgNameGen, sigAlgIdFinder, contentVerifierProviderBuilder.build(pubKey), digestCalculatorProvider); } } bouncycastle-1.49.orig/src/org/bouncycastle/cms/bc/BcKEKRecipient.java0000644000175000017500000000216211737210363025241 0ustar ebourgebourgpackage org.bouncycastle.cms.bc; import org.bouncycastle.asn1.x509.AlgorithmIdentifier; import org.bouncycastle.cms.CMSException; import org.bouncycastle.cms.KEKRecipient; import org.bouncycastle.crypto.CipherParameters; import org.bouncycastle.operator.OperatorException; import org.bouncycastle.operator.SymmetricKeyUnwrapper; import org.bouncycastle.operator.bc.BcSymmetricKeyUnwrapper; public abstract class BcKEKRecipient implements KEKRecipient { private SymmetricKeyUnwrapper unwrapper; public BcKEKRecipient(BcSymmetricKeyUnwrapper unwrapper) { this.unwrapper = unwrapper; } protected CipherParameters extractSecretKey(AlgorithmIdentifier keyEncryptionAlgorithm, AlgorithmIdentifier contentEncryptionAlgorithm, byte[] encryptedContentEncryptionKey) throws CMSException { try { return CMSUtils.getBcKey(unwrapper.generateUnwrappedKey(contentEncryptionAlgorithm, encryptedContentEncryptionKey)); } catch (OperatorException e) { throw new CMSException("exception unwrapping key: " + e.getMessage(), e); } } } bouncycastle-1.49.orig/src/org/bouncycastle/cms/bc/BcPasswordRecipient.java0000644000175000017500000000364011737206560026437 0ustar ebourgebourgpackage org.bouncycastle.cms.bc; import org.bouncycastle.asn1.ASN1OctetString; import org.bouncycastle.asn1.x509.AlgorithmIdentifier; import org.bouncycastle.cms.CMSException; import org.bouncycastle.cms.PasswordRecipient; import org.bouncycastle.crypto.InvalidCipherTextException; import org.bouncycastle.crypto.Wrapper; import org.bouncycastle.crypto.params.KeyParameter; import org.bouncycastle.crypto.params.ParametersWithIV; /** * the RecipientInfo class for a recipient who has been sent a message * encrypted using a password. */ public abstract class BcPasswordRecipient implements PasswordRecipient { private int schemeID = PasswordRecipient.PKCS5_SCHEME2_UTF8; private char[] password; BcPasswordRecipient( char[] password) { this.password = password; } public BcPasswordRecipient setPasswordConversionScheme(int schemeID) { this.schemeID = schemeID; return this; } protected KeyParameter extractSecretKey(AlgorithmIdentifier keyEncryptionAlgorithm, AlgorithmIdentifier contentEncryptionAlgorithm, byte[] derivedKey, byte[] encryptedContentEncryptionKey) throws CMSException { Wrapper keyEncryptionCipher = EnvelopedDataHelper.createRFC3211Wrapper(keyEncryptionAlgorithm.getAlgorithm()); keyEncryptionCipher.init(false, new ParametersWithIV(new KeyParameter(derivedKey), ASN1OctetString.getInstance(keyEncryptionAlgorithm.getParameters()).getOctets())); try { return new KeyParameter(keyEncryptionCipher.unwrap(encryptedContentEncryptionKey, 0, encryptedContentEncryptionKey.length)); } catch (InvalidCipherTextException e) { throw new CMSException("unable to unwrap key: " + e.getMessage(), e); } } public int getPasswordConversionScheme() { return schemeID; } public char[] getPassword() { return password; } } bouncycastle-1.49.orig/src/org/bouncycastle/cms/bc/BcPasswordEnvelopedRecipient.java0000644000175000017500000000340611762273246030304 0ustar ebourgebourgpackage org.bouncycastle.cms.bc; import java.io.InputStream; import org.bouncycastle.asn1.x509.AlgorithmIdentifier; import org.bouncycastle.cms.CMSException; import org.bouncycastle.cms.RecipientOperator; import org.bouncycastle.crypto.BufferedBlockCipher; import org.bouncycastle.crypto.StreamCipher; import org.bouncycastle.crypto.io.CipherInputStream; import org.bouncycastle.crypto.params.KeyParameter; import org.bouncycastle.operator.InputDecryptor; public class BcPasswordEnvelopedRecipient extends BcPasswordRecipient { public BcPasswordEnvelopedRecipient(char[] password) { super(password); } public RecipientOperator getRecipientOperator(AlgorithmIdentifier keyEncryptionAlgorithm, final AlgorithmIdentifier contentEncryptionAlgorithm, byte[] derivedKey, byte[] encryptedContentEncryptionKey) throws CMSException { KeyParameter secretKey = extractSecretKey(keyEncryptionAlgorithm, contentEncryptionAlgorithm, derivedKey, encryptedContentEncryptionKey); final Object dataCipher = EnvelopedDataHelper.createContentCipher(false, secretKey, contentEncryptionAlgorithm); return new RecipientOperator(new InputDecryptor() { public AlgorithmIdentifier getAlgorithmIdentifier() { return contentEncryptionAlgorithm; } public InputStream getInputStream(InputStream dataOut) { if (dataCipher instanceof BufferedBlockCipher) { return new CipherInputStream(dataOut, (BufferedBlockCipher)dataCipher); } else { return new CipherInputStream(dataOut, (StreamCipher)dataCipher); } } }); } } bouncycastle-1.49.orig/src/org/bouncycastle/cms/bc/BcKeyTransRecipientInfoGenerator.java0000644000175000017500000000134111612136056031046 0ustar ebourgebourgpackage org.bouncycastle.cms.bc; import org.bouncycastle.asn1.cms.IssuerAndSerialNumber; import org.bouncycastle.cert.X509CertificateHolder; import org.bouncycastle.cms.KeyTransRecipientInfoGenerator; import org.bouncycastle.operator.bc.BcAsymmetricKeyWrapper; public abstract class BcKeyTransRecipientInfoGenerator extends KeyTransRecipientInfoGenerator { public BcKeyTransRecipientInfoGenerator(X509CertificateHolder recipientCert, BcAsymmetricKeyWrapper wrapper) { super(new IssuerAndSerialNumber(recipientCert.toASN1Structure()), wrapper); } public BcKeyTransRecipientInfoGenerator(byte[] subjectKeyIdentifier, BcAsymmetricKeyWrapper wrapper) { super(subjectKeyIdentifier, wrapper); } }bouncycastle-1.49.orig/src/org/bouncycastle/cms/bc/BcRSAKeyTransRecipientInfoGenerator.java0000644000175000017500000000162711502570636031427 0ustar ebourgebourgpackage org.bouncycastle.cms.bc; import java.io.IOException; import org.bouncycastle.asn1.x509.AlgorithmIdentifier; import org.bouncycastle.cert.X509CertificateHolder; import org.bouncycastle.crypto.params.AsymmetricKeyParameter; import org.bouncycastle.operator.bc.BcRSAAsymmetricKeyWrapper; public class BcRSAKeyTransRecipientInfoGenerator extends BcKeyTransRecipientInfoGenerator { public BcRSAKeyTransRecipientInfoGenerator(byte[] subjectKeyIdentifier, AlgorithmIdentifier encAlgId, AsymmetricKeyParameter publicKey) { super(subjectKeyIdentifier, new BcRSAAsymmetricKeyWrapper(encAlgId, publicKey)); } public BcRSAKeyTransRecipientInfoGenerator(X509CertificateHolder recipientCert) throws IOException { super(recipientCert, new BcRSAAsymmetricKeyWrapper(recipientCert.getSubjectPublicKeyInfo().getAlgorithmId(), recipientCert.getSubjectPublicKeyInfo())); } } bouncycastle-1.49.orig/src/org/bouncycastle/cms/bc/BcPasswordRecipientInfoGenerator.java0000644000175000017500000000257511737206560031130 0ustar ebourgebourgpackage org.bouncycastle.cms.bc; import org.bouncycastle.asn1.ASN1ObjectIdentifier; import org.bouncycastle.asn1.ASN1OctetString; import org.bouncycastle.asn1.x509.AlgorithmIdentifier; import org.bouncycastle.cms.CMSException; import org.bouncycastle.cms.PasswordRecipientInfoGenerator; import org.bouncycastle.crypto.Wrapper; import org.bouncycastle.crypto.params.KeyParameter; import org.bouncycastle.crypto.params.ParametersWithIV; import org.bouncycastle.operator.GenericKey; public class BcPasswordRecipientInfoGenerator extends PasswordRecipientInfoGenerator { public BcPasswordRecipientInfoGenerator(ASN1ObjectIdentifier kekAlgorithm, char[] password) { super(kekAlgorithm, password); } public byte[] generateEncryptedBytes(AlgorithmIdentifier keyEncryptionAlgorithm, byte[] derivedKey, GenericKey contentEncryptionKey) throws CMSException { byte[] contentEncryptionKeySpec = ((KeyParameter)CMSUtils.getBcKey(contentEncryptionKey)).getKey(); Wrapper keyEncryptionCipher = EnvelopedDataHelper.createRFC3211Wrapper(keyEncryptionAlgorithm.getAlgorithm()); keyEncryptionCipher.init(true, new ParametersWithIV(new KeyParameter(derivedKey), ASN1OctetString.getInstance(keyEncryptionAlgorithm.getParameters()).getOctets())); return keyEncryptionCipher.wrap(contentEncryptionKeySpec, 0, contentEncryptionKeySpec.length); } } bouncycastle-1.49.orig/src/org/bouncycastle/cms/KeyAgreeRecipientInformation.java0000644000175000017500000001500011726240050027665 0ustar ebourgebourgpackage org.bouncycastle.cms; import java.io.IOException; import java.security.Key; import java.security.NoSuchProviderException; import java.security.PrivateKey; import java.security.Provider; import java.util.List; import org.bouncycastle.asn1.ASN1OctetString; import org.bouncycastle.asn1.ASN1Sequence; import org.bouncycastle.asn1.cms.IssuerAndSerialNumber; import org.bouncycastle.asn1.cms.KeyAgreeRecipientIdentifier; import org.bouncycastle.asn1.cms.KeyAgreeRecipientInfo; import org.bouncycastle.asn1.cms.OriginatorIdentifierOrKey; import org.bouncycastle.asn1.cms.OriginatorPublicKey; import org.bouncycastle.asn1.cms.RecipientEncryptedKey; import org.bouncycastle.asn1.cms.RecipientKeyIdentifier; import org.bouncycastle.asn1.x509.AlgorithmIdentifier; import org.bouncycastle.asn1.x509.SubjectKeyIdentifier; import org.bouncycastle.asn1.x509.SubjectPublicKeyInfo; import org.bouncycastle.cms.jcajce.JceKeyAgreeAuthenticatedRecipient; import org.bouncycastle.cms.jcajce.JceKeyAgreeEnvelopedRecipient; import org.bouncycastle.cms.jcajce.JceKeyAgreeRecipient; /** * the RecipientInfo class for a recipient who has been sent a message * encrypted using key agreement. */ public class KeyAgreeRecipientInformation extends RecipientInformation { private KeyAgreeRecipientInfo info; private ASN1OctetString encryptedKey; static void readRecipientInfo(List infos, KeyAgreeRecipientInfo info, AlgorithmIdentifier messageAlgorithm, CMSSecureReadable secureReadable, AuthAttributesProvider additionalData) { ASN1Sequence s = info.getRecipientEncryptedKeys(); for (int i = 0; i < s.size(); ++i) { RecipientEncryptedKey id = RecipientEncryptedKey.getInstance( s.getObjectAt(i)); RecipientId rid; KeyAgreeRecipientIdentifier karid = id.getIdentifier(); IssuerAndSerialNumber iAndSN = karid.getIssuerAndSerialNumber(); if (iAndSN != null) { rid = new KeyAgreeRecipientId(iAndSN.getName(), iAndSN.getSerialNumber().getValue()); } else { RecipientKeyIdentifier rKeyID = karid.getRKeyID(); // Note: 'date' and 'other' fields of RecipientKeyIdentifier appear to be only informational rid = new KeyAgreeRecipientId(rKeyID.getSubjectKeyIdentifier().getOctets()); } infos.add(new KeyAgreeRecipientInformation(info, rid, id.getEncryptedKey(), messageAlgorithm, secureReadable, additionalData)); } } KeyAgreeRecipientInformation( KeyAgreeRecipientInfo info, RecipientId rid, ASN1OctetString encryptedKey, AlgorithmIdentifier messageAlgorithm, CMSSecureReadable secureReadable, AuthAttributesProvider additionalData) { super(info.getKeyEncryptionAlgorithm(), messageAlgorithm, secureReadable, additionalData); this.info = info; this.rid = rid; this.encryptedKey = encryptedKey; } private SubjectPublicKeyInfo getSenderPublicKeyInfo(AlgorithmIdentifier recKeyAlgId, OriginatorIdentifierOrKey originator) throws CMSException, IOException { OriginatorPublicKey opk = originator.getOriginatorKey(); if (opk != null) { return getPublicKeyInfoFromOriginatorPublicKey(recKeyAlgId, opk); } OriginatorId origID; IssuerAndSerialNumber iAndSN = originator.getIssuerAndSerialNumber(); if (iAndSN != null) { origID = new OriginatorId(iAndSN.getName(), iAndSN.getSerialNumber().getValue()); } else { SubjectKeyIdentifier ski = originator.getSubjectKeyIdentifier(); origID = new OriginatorId(ski.getKeyIdentifier()); } return getPublicKeyInfoFromOriginatorId(origID); } private SubjectPublicKeyInfo getPublicKeyInfoFromOriginatorPublicKey(AlgorithmIdentifier recKeyAlgId, OriginatorPublicKey originatorPublicKey) { SubjectPublicKeyInfo pubInfo = new SubjectPublicKeyInfo( recKeyAlgId, originatorPublicKey.getPublicKey().getBytes()); return pubInfo; } private SubjectPublicKeyInfo getPublicKeyInfoFromOriginatorId(OriginatorId origID) throws CMSException { // TODO Support all alternatives for OriginatorIdentifierOrKey // see RFC 3852 6.2.2 throw new CMSException("No support for 'originator' as IssuerAndSerialNumber or SubjectKeyIdentifier"); } /** * decrypt the content and return it * @deprecated use getContentStream(Recipient) method */ public CMSTypedStream getContentStream( Key key, String prov) throws CMSException, NoSuchProviderException { return getContentStream(key, CMSUtils.getProvider(prov)); } /** * decrypt the content and return it * @deprecated use getContentStream(Recipient) method */ public CMSTypedStream getContentStream( Key key, Provider prov) throws CMSException { try { JceKeyAgreeRecipient recipient; if (secureReadable instanceof CMSEnvelopedHelper.CMSEnvelopedSecureReadable) { recipient = new JceKeyAgreeEnvelopedRecipient((PrivateKey)key); } else { recipient = new JceKeyAgreeAuthenticatedRecipient((PrivateKey)key); } if (prov != null) { recipient.setProvider(prov); if (prov.getName().equalsIgnoreCase("SunJCE")) { recipient.setContentProvider((String)null); // need to fall back to generic search } } return getContentStream(recipient); } catch (IOException e) { throw new CMSException("encoding error: " + e.getMessage(), e); } } protected RecipientOperator getRecipientOperator(Recipient recipient) throws CMSException, IOException { KeyAgreeRecipient agreeRecipient = (KeyAgreeRecipient)recipient; AlgorithmIdentifier recKeyAlgId = agreeRecipient.getPrivateKeyAlgorithmIdentifier(); return ((KeyAgreeRecipient)recipient).getRecipientOperator(keyEncAlg, messageAlgorithm, getSenderPublicKeyInfo(recKeyAlgId, info.getOriginator()), info.getUserKeyingMaterial(), encryptedKey.getOctets()); } } bouncycastle-1.49.orig/src/org/bouncycastle/cms/CMSAbsentContent.java0000644000175000017500000000170011605224710025235 0ustar ebourgebourgpackage org.bouncycastle.cms; import java.io.IOException; import java.io.InputStream; import java.io.OutputStream; import org.bouncycastle.asn1.ASN1ObjectIdentifier; import org.bouncycastle.asn1.cms.CMSObjectIdentifiers; /** * a class representing null or absent content. */ public class CMSAbsentContent implements CMSTypedData, CMSReadable { private final ASN1ObjectIdentifier type; public CMSAbsentContent() { this(new ASN1ObjectIdentifier(CMSObjectIdentifiers.data.getId())); } public CMSAbsentContent( ASN1ObjectIdentifier type) { this.type = type; } public InputStream getInputStream() { return null; } public void write(OutputStream zOut) throws IOException, CMSException { // do nothing } public Object getContent() { return null; } public ASN1ObjectIdentifier getContentType() { return type; } } bouncycastle-1.49.orig/src/org/bouncycastle/cms/CMSStreamException.java0000644000175000017500000000071411442065637025616 0ustar ebourgebourgpackage org.bouncycastle.cms; import java.io.IOException; public class CMSStreamException extends IOException { private final Throwable underlying; CMSStreamException(String msg) { super(msg); this.underlying = null; } CMSStreamException(String msg, Throwable underlying) { super(msg); this.underlying = underlying; } public Throwable getCause() { return underlying; } } bouncycastle-1.49.orig/src/org/bouncycastle/cms/CMSAttributeTableGenerationException.java0000644000175000017500000000102210760650613031277 0ustar ebourgebourgpackage org.bouncycastle.cms; public class CMSAttributeTableGenerationException extends CMSRuntimeException { Exception e; public CMSAttributeTableGenerationException( String name) { super(name); } public CMSAttributeTableGenerationException( String name, Exception e) { super(name); this.e = e; } public Exception getUnderlyingException() { return e; } public Throwable getCause() { return e; } } bouncycastle-1.49.orig/src/org/bouncycastle/cms/RecipientOperator.java0000644000175000017500000000236511530416361025573 0ustar ebourgebourgpackage org.bouncycastle.cms; import java.io.InputStream; import org.bouncycastle.asn1.x509.AlgorithmIdentifier; import org.bouncycastle.operator.InputDecryptor; import org.bouncycastle.operator.MacCalculator; import org.bouncycastle.util.io.TeeInputStream; public class RecipientOperator { private final AlgorithmIdentifier algorithmIdentifier; private final Object operator; public RecipientOperator(InputDecryptor decryptor) { this.algorithmIdentifier = decryptor.getAlgorithmIdentifier(); this.operator = decryptor; } public RecipientOperator(MacCalculator macCalculator) { this.algorithmIdentifier = macCalculator.getAlgorithmIdentifier(); this.operator = macCalculator; } public InputStream getInputStream(InputStream dataIn) { if (operator instanceof InputDecryptor) { return ((InputDecryptor)operator).getInputStream(dataIn); } else { return new TeeInputStream(dataIn, ((MacCalculator)operator).getOutputStream()); } } public boolean isMacBased() { return operator instanceof MacCalculator; } public byte[] getMac() { return ((MacCalculator)operator).getMac(); } } bouncycastle-1.49.orig/src/org/bouncycastle/cms/DefaultCMSSignatureAlgorithmNameGenerator.java0000644000175000017500000001635011562112721032262 0ustar ebourgebourgpackage org.bouncycastle.cms; import java.util.HashMap; import java.util.Map; import org.bouncycastle.asn1.ASN1ObjectIdentifier; import org.bouncycastle.asn1.cryptopro.CryptoProObjectIdentifiers; import org.bouncycastle.asn1.eac.EACObjectIdentifiers; import org.bouncycastle.asn1.nist.NISTObjectIdentifiers; import org.bouncycastle.asn1.oiw.OIWObjectIdentifiers; import org.bouncycastle.asn1.pkcs.PKCSObjectIdentifiers; import org.bouncycastle.asn1.teletrust.TeleTrusTObjectIdentifiers; import org.bouncycastle.asn1.x509.AlgorithmIdentifier; import org.bouncycastle.asn1.x509.X509ObjectIdentifiers; import org.bouncycastle.asn1.x9.X9ObjectIdentifiers; public class DefaultCMSSignatureAlgorithmNameGenerator implements CMSSignatureAlgorithmNameGenerator { private final Map encryptionAlgs = new HashMap(); private final Map digestAlgs = new HashMap(); private void addEntries(ASN1ObjectIdentifier alias, String digest, String encryption) { digestAlgs.put(alias, digest); encryptionAlgs.put(alias, encryption); } public DefaultCMSSignatureAlgorithmNameGenerator() { addEntries(NISTObjectIdentifiers.dsa_with_sha224, "SHA224", "DSA"); addEntries(NISTObjectIdentifiers.dsa_with_sha256, "SHA256", "DSA"); addEntries(NISTObjectIdentifiers.dsa_with_sha384, "SHA384", "DSA"); addEntries(NISTObjectIdentifiers.dsa_with_sha512, "SHA512", "DSA"); addEntries(OIWObjectIdentifiers.dsaWithSHA1, "SHA1", "DSA"); addEntries(OIWObjectIdentifiers.md4WithRSA, "MD4", "RSA"); addEntries(OIWObjectIdentifiers.md4WithRSAEncryption, "MD4", "RSA"); addEntries(OIWObjectIdentifiers.md5WithRSA, "MD5", "RSA"); addEntries(OIWObjectIdentifiers.sha1WithRSA, "SHA1", "RSA"); addEntries(PKCSObjectIdentifiers.md2WithRSAEncryption, "MD2", "RSA"); addEntries(PKCSObjectIdentifiers.md4WithRSAEncryption, "MD4", "RSA"); addEntries(PKCSObjectIdentifiers.md5WithRSAEncryption, "MD5", "RSA"); addEntries(PKCSObjectIdentifiers.sha1WithRSAEncryption, "SHA1", "RSA"); addEntries(PKCSObjectIdentifiers.sha224WithRSAEncryption, "SHA224", "RSA"); addEntries(PKCSObjectIdentifiers.sha256WithRSAEncryption, "SHA256", "RSA"); addEntries(PKCSObjectIdentifiers.sha384WithRSAEncryption, "SHA384", "RSA"); addEntries(PKCSObjectIdentifiers.sha512WithRSAEncryption, "SHA512", "RSA"); addEntries(X9ObjectIdentifiers.ecdsa_with_SHA1, "SHA1", "ECDSA"); addEntries(X9ObjectIdentifiers.ecdsa_with_SHA224, "SHA224", "ECDSA"); addEntries(X9ObjectIdentifiers.ecdsa_with_SHA256, "SHA256", "ECDSA"); addEntries(X9ObjectIdentifiers.ecdsa_with_SHA384, "SHA384", "ECDSA"); addEntries(X9ObjectIdentifiers.ecdsa_with_SHA512, "SHA512", "ECDSA"); addEntries(X9ObjectIdentifiers.id_dsa_with_sha1, "SHA1", "DSA"); addEntries(EACObjectIdentifiers.id_TA_ECDSA_SHA_1, "SHA1", "ECDSA"); addEntries(EACObjectIdentifiers.id_TA_ECDSA_SHA_224, "SHA224", "ECDSA"); addEntries(EACObjectIdentifiers.id_TA_ECDSA_SHA_256, "SHA256", "ECDSA"); addEntries(EACObjectIdentifiers.id_TA_ECDSA_SHA_384, "SHA384", "ECDSA"); addEntries(EACObjectIdentifiers.id_TA_ECDSA_SHA_512, "SHA512", "ECDSA"); addEntries(EACObjectIdentifiers.id_TA_RSA_v1_5_SHA_1, "SHA1", "RSA"); addEntries(EACObjectIdentifiers.id_TA_RSA_v1_5_SHA_256, "SHA256", "RSA"); addEntries(EACObjectIdentifiers.id_TA_RSA_PSS_SHA_1, "SHA1", "RSAandMGF1"); addEntries(EACObjectIdentifiers.id_TA_RSA_PSS_SHA_256, "SHA256", "RSAandMGF1"); encryptionAlgs.put(X9ObjectIdentifiers.id_dsa, "DSA"); encryptionAlgs.put(PKCSObjectIdentifiers.rsaEncryption, "RSA"); encryptionAlgs.put(TeleTrusTObjectIdentifiers.teleTrusTRSAsignatureAlgorithm, "RSA"); encryptionAlgs.put(X509ObjectIdentifiers.id_ea_rsa, "RSA"); encryptionAlgs.put(PKCSObjectIdentifiers.id_RSASSA_PSS, "RSAandMGF1"); encryptionAlgs.put(CryptoProObjectIdentifiers.gostR3410_94, "GOST3410"); encryptionAlgs.put(CryptoProObjectIdentifiers.gostR3410_2001, "ECGOST3410"); encryptionAlgs.put(new ASN1ObjectIdentifier("1.3.6.1.4.1.5849.1.6.2"), "ECGOST3410"); encryptionAlgs.put(new ASN1ObjectIdentifier("1.3.6.1.4.1.5849.1.1.5"), "GOST3410"); encryptionAlgs.put(CryptoProObjectIdentifiers.gostR3411_94_with_gostR3410_2001, "ECGOST3410"); encryptionAlgs.put(CryptoProObjectIdentifiers.gostR3411_94_with_gostR3410_94, "GOST3410"); digestAlgs.put(PKCSObjectIdentifiers.md2, "MD2"); digestAlgs.put(PKCSObjectIdentifiers.md4, "MD4"); digestAlgs.put(PKCSObjectIdentifiers.md5, "MD5"); digestAlgs.put(OIWObjectIdentifiers.idSHA1, "SHA1"); digestAlgs.put(NISTObjectIdentifiers.id_sha224, "SHA224"); digestAlgs.put(NISTObjectIdentifiers.id_sha256, "SHA256"); digestAlgs.put(NISTObjectIdentifiers.id_sha384, "SHA384"); digestAlgs.put(NISTObjectIdentifiers.id_sha512, "SHA512"); digestAlgs.put(TeleTrusTObjectIdentifiers.ripemd128, "RIPEMD128"); digestAlgs.put(TeleTrusTObjectIdentifiers.ripemd160, "RIPEMD160"); digestAlgs.put(TeleTrusTObjectIdentifiers.ripemd256, "RIPEMD256"); digestAlgs.put(CryptoProObjectIdentifiers.gostR3411, "GOST3411"); digestAlgs.put(new ASN1ObjectIdentifier("1.3.6.1.4.1.5849.1.2.1"), "GOST3411"); } /** * Return the digest algorithm using one of the standard JCA string * representations rather than the algorithm identifier (if possible). */ private String getDigestAlgName( ASN1ObjectIdentifier digestAlgOID) { String algName = (String)digestAlgs.get(digestAlgOID); if (algName != null) { return algName; } return digestAlgOID.getId(); } /** * Return the digest encryption algorithm using one of the standard * JCA string representations rather the the algorithm identifier (if * possible). */ private String getEncryptionAlgName( ASN1ObjectIdentifier encryptionAlgOID) { String algName = (String)encryptionAlgs.get(encryptionAlgOID); if (algName != null) { return algName; } return encryptionAlgOID.getId(); } /** * Set the mapping for the encryption algorithm used in association with a SignedData generation * or interpretation. * * @param oid object identifier to map. * @param algorithmName algorithm name to use. */ protected void setSigningEncryptionAlgorithmMapping(ASN1ObjectIdentifier oid, String algorithmName) { encryptionAlgs.put(oid, algorithmName); } /** * Set the mapping for the digest algorithm to use in conjunction with a SignedData generation * or interpretation. * * @param oid object identifier to map. * @param algorithmName algorithm name to use. */ protected void setSigningDigestAlgorithmMapping(ASN1ObjectIdentifier oid, String algorithmName) { digestAlgs.put(oid, algorithmName); } public String getSignatureName(AlgorithmIdentifier digestAlg, AlgorithmIdentifier encryptionAlg) { return getDigestAlgName(digestAlg.getAlgorithm()) + "with" + getEncryptionAlgName(encryptionAlg.getAlgorithm()); } } bouncycastle-1.49.orig/src/org/bouncycastle/cms/DefaultCMSSignatureEncryptionAlgorithmFinder.java0000644000175000017500000000365511651132414033021 0ustar ebourgebourgpackage org.bouncycastle.cms; import java.util.HashSet; import java.util.Set; import org.bouncycastle.asn1.DERNull; import org.bouncycastle.asn1.oiw.OIWObjectIdentifiers; import org.bouncycastle.asn1.pkcs.PKCSObjectIdentifiers; import org.bouncycastle.asn1.teletrust.TeleTrusTObjectIdentifiers; import org.bouncycastle.asn1.x509.AlgorithmIdentifier; public class DefaultCMSSignatureEncryptionAlgorithmFinder implements CMSSignatureEncryptionAlgorithmFinder { private static final Set RSA_PKCS1d5 = new HashSet(); static { RSA_PKCS1d5.add(PKCSObjectIdentifiers.md2WithRSAEncryption); RSA_PKCS1d5.add(PKCSObjectIdentifiers.md4WithRSAEncryption); RSA_PKCS1d5.add(PKCSObjectIdentifiers.md5WithRSAEncryption); RSA_PKCS1d5.add(PKCSObjectIdentifiers.sha1WithRSAEncryption); RSA_PKCS1d5.add(PKCSObjectIdentifiers.sha224WithRSAEncryption); RSA_PKCS1d5.add(PKCSObjectIdentifiers.sha256WithRSAEncryption); RSA_PKCS1d5.add(PKCSObjectIdentifiers.sha384WithRSAEncryption); RSA_PKCS1d5.add(PKCSObjectIdentifiers.sha512WithRSAEncryption); RSA_PKCS1d5.add(OIWObjectIdentifiers.md4WithRSAEncryption); RSA_PKCS1d5.add(OIWObjectIdentifiers.md4WithRSA); RSA_PKCS1d5.add(OIWObjectIdentifiers.md5WithRSA); RSA_PKCS1d5.add(OIWObjectIdentifiers.sha1WithRSA); RSA_PKCS1d5.add(TeleTrusTObjectIdentifiers.rsaSignatureWithripemd128); RSA_PKCS1d5.add(TeleTrusTObjectIdentifiers.rsaSignatureWithripemd160); RSA_PKCS1d5.add(TeleTrusTObjectIdentifiers.rsaSignatureWithripemd256); } public AlgorithmIdentifier findEncryptionAlgorithm(AlgorithmIdentifier signatureAlgorithm) { // RFC3370 section 3.2 if (RSA_PKCS1d5.contains(signatureAlgorithm.getAlgorithm())) { return new AlgorithmIdentifier(PKCSObjectIdentifiers.rsaEncryption, DERNull.INSTANCE); } return signatureAlgorithm; } } bouncycastle-1.49.orig/src/org/bouncycastle/cms/NullOutputStream.java0000644000175000017500000000070011346623251025436 0ustar ebourgebourg/** * */ package org.bouncycastle.cms; import java.io.IOException; import java.io.OutputStream; class NullOutputStream extends OutputStream { public void write(byte[] buf) throws IOException { // do nothing } public void write(byte[] buf, int off, int len) throws IOException { // do nothing } public void write(int b) throws IOException { // do nothing } }bouncycastle-1.49.orig/src/org/bouncycastle/cms/KeyTransRecipientId.java0000644000175000017500000000531111726252156026016 0ustar ebourgebourgpackage org.bouncycastle.cms; import java.math.BigInteger; import org.bouncycastle.asn1.x500.X500Name; import org.bouncycastle.cert.selector.X509CertificateHolderSelector; public class KeyTransRecipientId extends RecipientId { private X509CertificateHolderSelector baseSelector; private KeyTransRecipientId(X509CertificateHolderSelector baseSelector) { super(keyTrans); this.baseSelector = baseSelector; } /** * Construct a key trans recipient ID with the value of a public key's subjectKeyId. * * @param subjectKeyId a subjectKeyId */ public KeyTransRecipientId(byte[] subjectKeyId) { this(null, null, subjectKeyId); } /** * Construct a key trans recipient ID based on the issuer and serial number of the recipient's associated * certificate. * * @param issuer the issuer of the recipient's associated certificate. * @param serialNumber the serial number of the recipient's associated certificate. */ public KeyTransRecipientId(X500Name issuer, BigInteger serialNumber) { this(issuer, serialNumber, null); } /** * Construct a key trans recipient ID based on the issuer and serial number of the recipient's associated * certificate. * * @param issuer the issuer of the recipient's associated certificate. * @param serialNumber the serial number of the recipient's associated certificate. * @param subjectKeyId the subject key identifier to use to match the recipients associated certificate. */ public KeyTransRecipientId(X500Name issuer, BigInteger serialNumber, byte[] subjectKeyId) { this(new X509CertificateHolderSelector(issuer, serialNumber, subjectKeyId)); } public X500Name getIssuer() { return baseSelector.getIssuer(); } public BigInteger getSerialNumber() { return baseSelector.getSerialNumber(); } public byte[] getSubjectKeyIdentifier() { return baseSelector.getSubjectKeyIdentifier(); } public int hashCode() { return baseSelector.hashCode(); } public boolean equals( Object o) { if (!(o instanceof KeyTransRecipientId)) { return false; } KeyTransRecipientId id = (KeyTransRecipientId)o; return this.baseSelector.equals(id.baseSelector); } public Object clone() { return new KeyTransRecipientId(this.baseSelector); } public boolean match(Object obj) { if (obj instanceof KeyTransRecipientInformation) { return ((KeyTransRecipientInformation)obj).getRID().equals(this); } return baseSelector.match(obj); } } bouncycastle-1.49.orig/src/org/bouncycastle/cms/CMSAuthenticatedGenerator.java0000644000175000017500000000257611737174446027153 0ustar ebourgebourgpackage org.bouncycastle.cms; import java.security.SecureRandom; import java.util.HashMap; import java.util.Map; import org.bouncycastle.asn1.ASN1ObjectIdentifier; import org.bouncycastle.asn1.x509.AlgorithmIdentifier; public class CMSAuthenticatedGenerator extends CMSEnvelopedGenerator { protected CMSAttributeTableGenerator authGen; protected CMSAttributeTableGenerator unauthGen; /** * base constructor */ public CMSAuthenticatedGenerator() { } /** * constructor allowing specific source of randomness * * @param rand instance of SecureRandom to use */ public CMSAuthenticatedGenerator( SecureRandom rand) { super(rand); } public void setAuthenticatedAttributeGenerator(CMSAttributeTableGenerator authGen) { this.authGen = authGen; } public void setUnauthenticatedAttributeGenerator(CMSAttributeTableGenerator unauthGen) { this.unauthGen = unauthGen; } protected Map getBaseParameters(ASN1ObjectIdentifier contentType, AlgorithmIdentifier digAlgId, byte[] hash) { Map param = new HashMap(); param.put(CMSAttributeTableGenerator.CONTENT_TYPE, contentType); param.put(CMSAttributeTableGenerator.DIGEST_ALGORITHM_IDENTIFIER, digAlgId); param.put(CMSAttributeTableGenerator.DIGEST, hash.clone()); return param; } } bouncycastle-1.49.orig/src/org/bouncycastle/cms/SignerId.java0000644000175000017500000000511011726251114023630 0ustar ebourgebourgpackage org.bouncycastle.cms; import java.math.BigInteger; import org.bouncycastle.asn1.x500.X500Name; import org.bouncycastle.cert.selector.X509CertificateHolderSelector; import org.bouncycastle.util.Selector; /** * a basic index for a signer. */ public class SignerId implements Selector { private X509CertificateHolderSelector baseSelector; private SignerId(X509CertificateHolderSelector baseSelector) { this.baseSelector = baseSelector; } /** * Construct a signer ID with the value of a public key's subjectKeyId. * * @param subjectKeyId a subjectKeyId */ public SignerId(byte[] subjectKeyId) { this(null, null, subjectKeyId); } /** * Construct a signer ID based on the issuer and serial number of the signer's associated * certificate. * * @param issuer the issuer of the signer's associated certificate. * @param serialNumber the serial number of the signer's associated certificate. */ public SignerId(X500Name issuer, BigInteger serialNumber) { this(issuer, serialNumber, null); } /** * Construct a signer ID based on the issuer and serial number of the signer's associated * certificate. * * @param issuer the issuer of the signer's associated certificate. * @param serialNumber the serial number of the signer's associated certificate. * @param subjectKeyId the subject key identifier to use to match the signers associated certificate. */ public SignerId(X500Name issuer, BigInteger serialNumber, byte[] subjectKeyId) { this(new X509CertificateHolderSelector(issuer, serialNumber, subjectKeyId)); } public X500Name getIssuer() { return baseSelector.getIssuer(); } public BigInteger getSerialNumber() { return baseSelector.getSerialNumber(); } public byte[] getSubjectKeyIdentifier() { return baseSelector.getSubjectKeyIdentifier(); } public int hashCode() { return baseSelector.hashCode(); } public boolean equals( Object o) { if (!(o instanceof SignerId)) { return false; } SignerId id = (SignerId)o; return this.baseSelector.equals(id.baseSelector); } public boolean match(Object obj) { if (obj instanceof SignerInformation) { return ((SignerInformation)obj).getSID().equals(this); } return baseSelector.match(obj); } public Object clone() { return new SignerId(this.baseSelector); } } bouncycastle-1.49.orig/src/org/bouncycastle/cms/SignerInfoGenerator.java0000644000175000017500000002174312151251423026044 0ustar ebourgebourgpackage org.bouncycastle.cms; import java.io.IOException; import java.io.OutputStream; import java.util.Collections; import java.util.HashMap; import java.util.Map; import org.bouncycastle.asn1.ASN1Encoding; import org.bouncycastle.asn1.ASN1Integer; import org.bouncycastle.asn1.ASN1ObjectIdentifier; import org.bouncycastle.asn1.ASN1Set; import org.bouncycastle.asn1.DEROctetString; import org.bouncycastle.asn1.DERSet; import org.bouncycastle.asn1.cms.AttributeTable; import org.bouncycastle.asn1.cms.SignerIdentifier; import org.bouncycastle.asn1.cms.SignerInfo; import org.bouncycastle.asn1.x509.AlgorithmIdentifier; import org.bouncycastle.cert.X509CertificateHolder; import org.bouncycastle.operator.ContentSigner; import org.bouncycastle.operator.DefaultDigestAlgorithmIdentifierFinder; import org.bouncycastle.operator.DigestAlgorithmIdentifierFinder; import org.bouncycastle.operator.DigestCalculator; import org.bouncycastle.operator.DigestCalculatorProvider; import org.bouncycastle.operator.OperatorCreationException; import org.bouncycastle.util.io.TeeOutputStream; public class SignerInfoGenerator { private final SignerIdentifier signerIdentifier; private final CMSAttributeTableGenerator sAttrGen; private final CMSAttributeTableGenerator unsAttrGen; private final ContentSigner signer; private final DigestCalculator digester; private final DigestAlgorithmIdentifierFinder digAlgFinder = new DefaultDigestAlgorithmIdentifierFinder(); private final CMSSignatureEncryptionAlgorithmFinder sigEncAlgFinder; private byte[] calculatedDigest = null; private X509CertificateHolder certHolder; SignerInfoGenerator( SignerIdentifier signerIdentifier, ContentSigner signer, DigestCalculatorProvider digesterProvider, CMSSignatureEncryptionAlgorithmFinder sigEncAlgFinder) throws OperatorCreationException { this(signerIdentifier, signer, digesterProvider, sigEncAlgFinder, false); } SignerInfoGenerator( SignerIdentifier signerIdentifier, ContentSigner signer, DigestCalculatorProvider digesterProvider, CMSSignatureEncryptionAlgorithmFinder sigEncAlgFinder, boolean isDirectSignature) throws OperatorCreationException { this.signerIdentifier = signerIdentifier; this.signer = signer; if (digesterProvider != null) { this.digester = digesterProvider.get(digAlgFinder.find(signer.getAlgorithmIdentifier())); } else { this.digester = null; } if (isDirectSignature) { this.sAttrGen = null; this.unsAttrGen = null; } else { this.sAttrGen = new DefaultSignedAttributeTableGenerator(); this.unsAttrGen = null; } this.sigEncAlgFinder = sigEncAlgFinder; } public SignerInfoGenerator( SignerInfoGenerator original, CMSAttributeTableGenerator sAttrGen, CMSAttributeTableGenerator unsAttrGen) { this.signerIdentifier = original.signerIdentifier; this.signer = original.signer; this.digester = original.digester; this.sigEncAlgFinder = original.sigEncAlgFinder; this.sAttrGen = sAttrGen; this.unsAttrGen = unsAttrGen; } SignerInfoGenerator( SignerIdentifier signerIdentifier, ContentSigner signer, DigestCalculatorProvider digesterProvider, CMSSignatureEncryptionAlgorithmFinder sigEncAlgFinder, CMSAttributeTableGenerator sAttrGen, CMSAttributeTableGenerator unsAttrGen) throws OperatorCreationException { this.signerIdentifier = signerIdentifier; this.signer = signer; if (digesterProvider != null) { this.digester = digesterProvider.get(digAlgFinder.find(signer.getAlgorithmIdentifier())); } else { this.digester = null; } this.sAttrGen = sAttrGen; this.unsAttrGen = unsAttrGen; this.sigEncAlgFinder = sigEncAlgFinder; } public SignerIdentifier getSID() { return signerIdentifier; } public ASN1Integer getGeneratedVersion() { return new ASN1Integer(signerIdentifier.isTagged() ? 3 : 1); } public boolean hasAssociatedCertificate() { return certHolder != null; } public X509CertificateHolder getAssociatedCertificate() { return certHolder; } public AlgorithmIdentifier getDigestAlgorithm() { if (digester != null) { return digester.getAlgorithmIdentifier(); } return digAlgFinder.find(signer.getAlgorithmIdentifier()); } public OutputStream getCalculatingOutputStream() { if (digester != null) { if (sAttrGen == null) { return new TeeOutputStream(digester.getOutputStream(), signer.getOutputStream()); } return digester.getOutputStream(); } else { return signer.getOutputStream(); } } public SignerInfo generate(ASN1ObjectIdentifier contentType) throws CMSException { try { /* RFC 3852 5.4 * The result of the message digest calculation process depends on * whether the signedAttrs field is present. When the field is absent, * the result is just the message digest of the content as described * * above. When the field is present, however, the result is the message * digest of the complete DER encoding of the SignedAttrs value * contained in the signedAttrs field. */ ASN1Set signedAttr = null; AlgorithmIdentifier digestAlg = null; if (sAttrGen != null) { digestAlg = digester.getAlgorithmIdentifier(); calculatedDigest = digester.getDigest(); Map parameters = getBaseParameters(contentType, digester.getAlgorithmIdentifier(), calculatedDigest); AttributeTable signed = sAttrGen.getAttributes(Collections.unmodifiableMap(parameters)); signedAttr = getAttributeSet(signed); // sig must be composed from the DER encoding. OutputStream sOut = signer.getOutputStream(); sOut.write(signedAttr.getEncoded(ASN1Encoding.DER)); sOut.close(); } else { if (digester != null) { digestAlg = digester.getAlgorithmIdentifier(); calculatedDigest = digester.getDigest(); } else { digestAlg = digAlgFinder.find(signer.getAlgorithmIdentifier()); calculatedDigest = null; } } byte[] sigBytes = signer.getSignature(); ASN1Set unsignedAttr = null; if (unsAttrGen != null) { Map parameters = getBaseParameters(contentType, digestAlg, calculatedDigest); parameters.put(CMSAttributeTableGenerator.SIGNATURE, sigBytes.clone()); AttributeTable unsigned = unsAttrGen.getAttributes(Collections.unmodifiableMap(parameters)); unsignedAttr = getAttributeSet(unsigned); } AlgorithmIdentifier digestEncryptionAlgorithm = sigEncAlgFinder.findEncryptionAlgorithm(signer.getAlgorithmIdentifier()); return new SignerInfo(signerIdentifier, digestAlg, signedAttr, digestEncryptionAlgorithm, new DEROctetString(sigBytes), unsignedAttr); } catch (IOException e) { throw new CMSException("encoding error.", e); } } void setAssociatedCertificate(X509CertificateHolder certHolder) { this.certHolder = certHolder; } private ASN1Set getAttributeSet( AttributeTable attr) { if (attr != null) { return new DERSet(attr.toASN1EncodableVector()); } return null; } private Map getBaseParameters(ASN1ObjectIdentifier contentType, AlgorithmIdentifier digAlgId, byte[] hash) { Map param = new HashMap(); if (contentType != null) { param.put(CMSAttributeTableGenerator.CONTENT_TYPE, contentType); } param.put(CMSAttributeTableGenerator.DIGEST_ALGORITHM_IDENTIFIER, digAlgId); param.put(CMSAttributeTableGenerator.DIGEST, hash.clone()); return param; } public byte[] getCalculatedDigest() { if (calculatedDigest != null) { return (byte[])calculatedDigest.clone(); } return null; } public CMSAttributeTableGenerator getSignedAttributeTableGenerator() { return sAttrGen; } public CMSAttributeTableGenerator getUnsignedAttributeTableGenerator() { return unsAttrGen; } } bouncycastle-1.49.orig/src/org/bouncycastle/cms/CMSEnvelopedGenerator.java0000644000175000017500000003755011726302401026270 0ustar ebourgebourgpackage org.bouncycastle.cms; import java.io.IOException; import java.security.AlgorithmParameters; import java.security.InvalidKeyException; import java.security.NoSuchAlgorithmException; import java.security.NoSuchProviderException; import java.security.PrivateKey; import java.security.Provider; import java.security.PublicKey; import java.security.SecureRandom; import java.security.cert.CertificateEncodingException; import java.security.cert.X509Certificate; import java.util.ArrayList; import java.util.Collection; import java.util.Iterator; import java.util.List; import javax.crypto.SecretKey; import org.bouncycastle.asn1.ASN1Encodable; import org.bouncycastle.asn1.ASN1ObjectIdentifier; import org.bouncycastle.asn1.ASN1Primitive; import org.bouncycastle.asn1.DERNull; import org.bouncycastle.asn1.cms.KEKIdentifier; import org.bouncycastle.asn1.cms.OriginatorInfo; import org.bouncycastle.asn1.kisa.KISAObjectIdentifiers; import org.bouncycastle.asn1.nist.NISTObjectIdentifiers; import org.bouncycastle.asn1.ntt.NTTObjectIdentifiers; import org.bouncycastle.asn1.pkcs.PKCSObjectIdentifiers; import org.bouncycastle.asn1.x509.AlgorithmIdentifier; import org.bouncycastle.asn1.x9.X9ObjectIdentifiers; import org.bouncycastle.cms.jcajce.JceKEKRecipientInfoGenerator; import org.bouncycastle.cms.jcajce.JceKeyAgreeRecipientInfoGenerator; import org.bouncycastle.cms.jcajce.JceKeyTransRecipientInfoGenerator; import org.bouncycastle.cms.jcajce.JcePasswordRecipientInfoGenerator; /** * General class for generating a CMS enveloped-data message. */ public class CMSEnvelopedGenerator { public static final String DES_EDE3_CBC = PKCSObjectIdentifiers.des_EDE3_CBC.getId(); public static final String RC2_CBC = PKCSObjectIdentifiers.RC2_CBC.getId(); public static final String IDEA_CBC = "1.3.6.1.4.1.188.7.1.1.2"; public static final String CAST5_CBC = "1.2.840.113533.7.66.10"; public static final String AES128_CBC = NISTObjectIdentifiers.id_aes128_CBC.getId(); public static final String AES192_CBC = NISTObjectIdentifiers.id_aes192_CBC.getId(); public static final String AES256_CBC = NISTObjectIdentifiers.id_aes256_CBC.getId(); public static final String CAMELLIA128_CBC = NTTObjectIdentifiers.id_camellia128_cbc.getId(); public static final String CAMELLIA192_CBC = NTTObjectIdentifiers.id_camellia192_cbc.getId(); public static final String CAMELLIA256_CBC = NTTObjectIdentifiers.id_camellia256_cbc.getId(); public static final String SEED_CBC = KISAObjectIdentifiers.id_seedCBC.getId(); public static final String DES_EDE3_WRAP = PKCSObjectIdentifiers.id_alg_CMS3DESwrap.getId(); public static final String AES128_WRAP = NISTObjectIdentifiers.id_aes128_wrap.getId(); public static final String AES192_WRAP = NISTObjectIdentifiers.id_aes192_wrap.getId(); public static final String AES256_WRAP = NISTObjectIdentifiers.id_aes256_wrap.getId(); public static final String CAMELLIA128_WRAP = NTTObjectIdentifiers.id_camellia128_wrap.getId(); public static final String CAMELLIA192_WRAP = NTTObjectIdentifiers.id_camellia192_wrap.getId(); public static final String CAMELLIA256_WRAP = NTTObjectIdentifiers.id_camellia256_wrap.getId(); public static final String SEED_WRAP = KISAObjectIdentifiers.id_npki_app_cmsSeed_wrap.getId(); public static final String ECDH_SHA1KDF = X9ObjectIdentifiers.dhSinglePass_stdDH_sha1kdf_scheme.getId(); public static final String ECMQV_SHA1KDF = X9ObjectIdentifiers.mqvSinglePass_sha1kdf_scheme.getId(); final List oldRecipientInfoGenerators = new ArrayList(); final List recipientInfoGenerators = new ArrayList(); protected CMSAttributeTableGenerator unprotectedAttributeGenerator = null; final SecureRandom rand; protected OriginatorInfo originatorInfo; /** * base constructor */ public CMSEnvelopedGenerator() { this(new SecureRandom()); } /** * constructor allowing specific source of randomness * @param rand instance of SecureRandom to use */ public CMSEnvelopedGenerator( SecureRandom rand) { this.rand = rand; } public void setUnprotectedAttributeGenerator(CMSAttributeTableGenerator unprotectedAttributeGenerator) { this.unprotectedAttributeGenerator = unprotectedAttributeGenerator; } public void setOriginatorInfo(OriginatorInformation originatorInfo) { this.originatorInfo = originatorInfo.toASN1Structure(); } /** * add a recipient. * * @deprecated use the addRecipientGenerator and JceKeyTransRecipientInfoGenerator * @param cert recipient's public key certificate * @exception IllegalArgumentException if there is a problem with the certificate */ public void addKeyTransRecipient( X509Certificate cert) throws IllegalArgumentException { try { oldRecipientInfoGenerators.add(new JceKeyTransRecipientInfoGenerator(cert)); } catch (CertificateEncodingException e) { throw new IllegalArgumentException("unable to encode certificate: " + e.getMessage()); } } /** * add a recipient * * @deprecated use the addRecipientGenerator and JceKeyTransRecipientInfoGenerator * @param key the public key used by the recipient * @param subKeyId the identifier for the recipient's public key * @exception IllegalArgumentException if there is a problem with the key */ public void addKeyTransRecipient( PublicKey key, byte[] subKeyId) throws IllegalArgumentException { oldRecipientInfoGenerators.add(new JceKeyTransRecipientInfoGenerator(subKeyId, key)); } /** * add a KEK recipient. * * @deprecated use the addRecipientGenerator and JceKEKRecipientInfoGenerator * @param key the secret key to use for wrapping * @param keyIdentifier the byte string that identifies the key */ public void addKEKRecipient( SecretKey key, byte[] keyIdentifier) { addKEKRecipient(key, new KEKIdentifier(keyIdentifier, null, null)); } /** * add a KEK recipient. * * @deprecated use the addRecipientGenerator and JceKEKRecipientInfoGenerator * @param key the secret key to use for wrapping * @param kekIdentifier a KEKIdentifier structure (identifies the key) */ public void addKEKRecipient( SecretKey key, KEKIdentifier kekIdentifier) { oldRecipientInfoGenerators.add(new JceKEKRecipientInfoGenerator(kekIdentifier, key)); } /** * @deprecated use addRecipientGenerator and JcePasswordRecipientInfoGenerator * @param pbeKey PBE key * @param kekAlgorithmOid key encryption algorithm to use. */ public void addPasswordRecipient( CMSPBEKey pbeKey, String kekAlgorithmOid) { oldRecipientInfoGenerators.add(new JcePasswordRecipientInfoGenerator(new ASN1ObjectIdentifier(kekAlgorithmOid), pbeKey.getPassword()) .setSaltAndIterationCount(pbeKey.getSalt(), pbeKey.getIterationCount()) .setPasswordConversionScheme((pbeKey instanceof PKCS5Scheme2UTF8PBEKey) ? PasswordRecipient.PKCS5_SCHEME2_UTF8 : PasswordRecipient.PKCS5_SCHEME2)); } /** * Add a key agreement based recipient. * * @deprecated use the addRecipientGenerator and JceKeyAgreeRecipientInfoGenerator * @param agreementAlgorithm key agreement algorithm to use. * @param senderPrivateKey private key to initialise sender side of agreement with. * @param senderPublicKey sender public key to include with message. * @param recipientCert recipient's public key certificate. * @param cekWrapAlgorithm OID for key wrapping algorithm to use. * @param provider provider to use for the agreement calculation. * @exception NoSuchProviderException if the specified provider cannot be found * @exception NoSuchAlgorithmException if the algorithm requested cannot be found * @exception InvalidKeyException if the keys are inappropriate for the algorithm specified */ public void addKeyAgreementRecipient( String agreementAlgorithm, PrivateKey senderPrivateKey, PublicKey senderPublicKey, X509Certificate recipientCert, String cekWrapAlgorithm, String provider) throws NoSuchProviderException, NoSuchAlgorithmException, InvalidKeyException { addKeyAgreementRecipient(agreementAlgorithm, senderPrivateKey, senderPublicKey, recipientCert, cekWrapAlgorithm, CMSUtils.getProvider(provider)); } /** * Add a key agreement based recipient. * * @deprecated use the addRecipientGenerator and JceKeyAgreeRecipientInfoGenerator * @param agreementAlgorithm key agreement algorithm to use. * @param senderPrivateKey private key to initialise sender side of agreement with. * @param senderPublicKey sender public key to include with message. * @param recipientCert recipient's public key certificate. * @param cekWrapAlgorithm OID for key wrapping algorithm to use. * @param provider provider to use for the agreement calculation. * @exception NoSuchAlgorithmException if the algorithm requested cannot be found * @exception InvalidKeyException if the keys are inappropriate for the algorithm specified */ public void addKeyAgreementRecipient( String agreementAlgorithm, PrivateKey senderPrivateKey, PublicKey senderPublicKey, X509Certificate recipientCert, String cekWrapAlgorithm, Provider provider) throws NoSuchAlgorithmException, InvalidKeyException { List recipients = new ArrayList(); recipients.add(recipientCert); addKeyAgreementRecipients(agreementAlgorithm, senderPrivateKey, senderPublicKey, recipients, cekWrapAlgorithm, provider); } /** * Add multiple key agreement based recipients (sharing a single KeyAgreeRecipientInfo structure). * * @deprecated use the addRecipientGenerator and JceKeyAgreeRecipientInfoGenerator * @param agreementAlgorithm key agreement algorithm to use. * @param senderPrivateKey private key to initialise sender side of agreement with. * @param senderPublicKey sender public key to include with message. * @param recipientCerts recipients' public key certificates. * @param cekWrapAlgorithm OID for key wrapping algorithm to use. * @param provider provider to use for the agreement calculation. * @exception NoSuchAlgorithmException if the algorithm requested cannot be found * @exception InvalidKeyException if the keys are inappropriate for the algorithm specified */ public void addKeyAgreementRecipients( String agreementAlgorithm, PrivateKey senderPrivateKey, PublicKey senderPublicKey, Collection recipientCerts, String cekWrapAlgorithm, String provider) throws NoSuchProviderException, NoSuchAlgorithmException, InvalidKeyException { addKeyAgreementRecipients(agreementAlgorithm, senderPrivateKey, senderPublicKey, recipientCerts, cekWrapAlgorithm, CMSUtils.getProvider(provider)); } /** * Add multiple key agreement based recipients (sharing a single KeyAgreeRecipientInfo structure). * * @deprecated use the addRecipientGenerator and JceKeyAgreeRecipientInfoGenerator * @param agreementAlgorithm key agreement algorithm to use. * @param senderPrivateKey private key to initialise sender side of agreement with. * @param senderPublicKey sender public key to include with message. * @param recipientCerts recipients' public key certificates. * @param cekWrapAlgorithm OID for key wrapping algorithm to use. * @param provider provider to use for the agreement calculation. * @exception NoSuchAlgorithmException if the algorithm requested cannot be found * @exception InvalidKeyException if the keys are inappropriate for the algorithm specified */ public void addKeyAgreementRecipients( String agreementAlgorithm, PrivateKey senderPrivateKey, PublicKey senderPublicKey, Collection recipientCerts, String cekWrapAlgorithm, Provider provider) throws NoSuchAlgorithmException, InvalidKeyException { JceKeyAgreeRecipientInfoGenerator recipientInfoGenerator = new JceKeyAgreeRecipientInfoGenerator(new ASN1ObjectIdentifier(agreementAlgorithm), senderPrivateKey, senderPublicKey, new ASN1ObjectIdentifier(cekWrapAlgorithm)).setProvider(provider); for (Iterator it = recipientCerts.iterator(); it.hasNext();) { try { recipientInfoGenerator.addRecipient((X509Certificate)it.next()); } catch (CertificateEncodingException e) { throw new IllegalArgumentException("unable to encode certificate: " + e.getMessage()); } } oldRecipientInfoGenerators.add(recipientInfoGenerator); } /** * Add a generator to produce the recipient info required. * * @param recipientGenerator a generator of a recipient info object. */ public void addRecipientInfoGenerator(RecipientInfoGenerator recipientGenerator) { recipientInfoGenerators.add(recipientGenerator); } protected AlgorithmIdentifier getAlgorithmIdentifier(String encryptionOID, AlgorithmParameters params) throws IOException { ASN1Encodable asn1Params; if (params != null) { asn1Params = ASN1Primitive.fromByteArray(params.getEncoded("ASN.1")); } else { asn1Params = DERNull.INSTANCE; } return new AlgorithmIdentifier( new ASN1ObjectIdentifier(encryptionOID), asn1Params); } protected void convertOldRecipients(SecureRandom rand, Provider provider) { for (Iterator it = oldRecipientInfoGenerators.iterator(); it.hasNext();) { Object recipient = it.next(); if (recipient instanceof JceKeyTransRecipientInfoGenerator) { JceKeyTransRecipientInfoGenerator recip = (JceKeyTransRecipientInfoGenerator)recipient; if (provider != null) { recip.setProvider(provider); } recipientInfoGenerators.add(recip); } else if (recipient instanceof KEKRecipientInfoGenerator) { JceKEKRecipientInfoGenerator recip = (JceKEKRecipientInfoGenerator)recipient; if (provider != null) { recip.setProvider(provider); } recip.setSecureRandom(rand); recipientInfoGenerators.add(recip); } else if (recipient instanceof JcePasswordRecipientInfoGenerator) { JcePasswordRecipientInfoGenerator recip = (JcePasswordRecipientInfoGenerator)recipient; if (provider != null) { recip.setProvider(provider); } recip.setSecureRandom(rand); recipientInfoGenerators.add(recip); } else if (recipient instanceof JceKeyAgreeRecipientInfoGenerator) { JceKeyAgreeRecipientInfoGenerator recip = (JceKeyAgreeRecipientInfoGenerator)recipient; if (provider != null) { recip.setProvider(provider); } recip.setSecureRandom(rand); recipientInfoGenerators.add(recip); } } oldRecipientInfoGenerators.clear(); } } bouncycastle-1.49.orig/src/org/bouncycastle/cms/CMSSignedDataParser.java0000644000175000017500000010113412120234407025645 0ustar ebourgebourgpackage org.bouncycastle.cms; import java.io.ByteArrayInputStream; import java.io.IOException; import java.io.InputStream; import java.io.OutputStream; import java.security.NoSuchAlgorithmException; import java.security.NoSuchProviderException; import java.security.Provider; import java.security.cert.CertStore; import java.security.cert.CertStoreException; import java.util.ArrayList; import java.util.HashMap; import java.util.Iterator; import java.util.List; import java.util.Map; import org.bouncycastle.asn1.ASN1Encodable; import org.bouncycastle.asn1.ASN1EncodableVector; import org.bouncycastle.asn1.ASN1Generator; import org.bouncycastle.asn1.ASN1ObjectIdentifier; import org.bouncycastle.asn1.ASN1OctetStringParser; import org.bouncycastle.asn1.ASN1SequenceParser; import org.bouncycastle.asn1.ASN1Set; import org.bouncycastle.asn1.ASN1SetParser; import org.bouncycastle.asn1.ASN1StreamParser; import org.bouncycastle.asn1.BERSequenceGenerator; import org.bouncycastle.asn1.BERSetParser; import org.bouncycastle.asn1.BERTaggedObject; import org.bouncycastle.asn1.BERTags; import org.bouncycastle.asn1.DERSet; import org.bouncycastle.asn1.DERTaggedObject; import org.bouncycastle.asn1.cms.CMSObjectIdentifiers; import org.bouncycastle.asn1.cms.ContentInfoParser; import org.bouncycastle.asn1.cms.SignedDataParser; import org.bouncycastle.asn1.cms.SignerInfo; import org.bouncycastle.asn1.x509.AlgorithmIdentifier; import org.bouncycastle.cert.jcajce.JcaCertStoreBuilder; import org.bouncycastle.operator.DigestCalculator; import org.bouncycastle.operator.DigestCalculatorProvider; import org.bouncycastle.operator.OperatorCreationException; import org.bouncycastle.operator.bc.BcDigestCalculatorProvider; import org.bouncycastle.util.Store; import org.bouncycastle.util.io.Streams; import org.bouncycastle.x509.NoSuchStoreException; import org.bouncycastle.x509.X509Store; /** * Parsing class for an CMS Signed Data object from an input stream. *

    * Note: that because we are in a streaming mode only one signer can be tried and it is important * that the methods on the parser are called in the appropriate order. *

    *

    * A simple example of usage for an encapsulated signature. *

    *

    * Two notes: first, in the example below the validity of * the certificate isn't verified, just the fact that one of the certs * matches the given signer, and, second, because we are in a streaming * mode the order of the operations is important. *

    *
     *      CMSSignedDataParser     sp = new CMSSignedDataParser(new JcaDigestCalculatorProviderBuilder().setProvider("BC").build(), encapSigData);
     *
     *      sp.getSignedContent().drain();
     *
     *      Store                   certStore = sp.getCertificates();
     *      SignerInformationStore  signers = sp.getSignerInfos();
     *      
     *      Collection              c = signers.getSigners();
     *      Iterator                it = c.iterator();
     *
     *      while (it.hasNext())
     *      {
     *          SignerInformation   signer = (SignerInformation)it.next();
     *          Collection          certCollection = certStore.getMatches(signer.getSID());
     *
     *          Iterator        certIt = certCollection.iterator();
     *          X509CertificateHolder cert = (X509CertificateHolder)certIt.next();
     *
     *          System.out.println("verify returns: " + signer.verify(new JcaSimpleSignerInfoVerifierBuilder().setProvider("BC").build(cert)));
     *      }
     * 
    * Note also: this class does not introduce buffering - if you are processing large files you should create * the parser with: *
     *          CMSSignedDataParser     ep = new CMSSignedDataParser(new BufferedInputStream(encapSigData, bufSize));
     *  
    * where bufSize is a suitably large buffer size. */ public class CMSSignedDataParser extends CMSContentInfoParser { private static final CMSSignedHelper HELPER = CMSSignedHelper.INSTANCE; private SignedDataParser _signedData; private ASN1ObjectIdentifier _signedContentType; private CMSTypedStream _signedContent; private Map digests; private SignerInformationStore _signerInfoStore; private X509Store _attributeStore; private ASN1Set _certSet, _crlSet; private boolean _isCertCrlParsed; private X509Store _certificateStore; private X509Store _crlStore; /** * @deprecated use method taking a DigestCalculatorProvider */ public CMSSignedDataParser( byte[] sigBlock) throws CMSException { this(createDefaultDigestProvider(), new ByteArrayInputStream(sigBlock)); } public CMSSignedDataParser( DigestCalculatorProvider digestCalculatorProvider, byte[] sigBlock) throws CMSException { this(digestCalculatorProvider, new ByteArrayInputStream(sigBlock)); } /** * @deprecated use method taking digest calculator provider. * @param signedContent * @param sigBlock * @throws CMSException */ public CMSSignedDataParser( CMSTypedStream signedContent, byte[] sigBlock) throws CMSException { this(createDefaultDigestProvider(), signedContent, new ByteArrayInputStream(sigBlock)); } public CMSSignedDataParser( DigestCalculatorProvider digestCalculatorProvider, CMSTypedStream signedContent, byte[] sigBlock) throws CMSException { this(digestCalculatorProvider, signedContent, new ByteArrayInputStream(sigBlock)); } private static DigestCalculatorProvider createDefaultDigestProvider() throws CMSException { return new BcDigestCalculatorProvider(); } /** * base constructor - with encapsulated content * * @deprecated use method taking a DigestCalculatorProvider */ public CMSSignedDataParser( InputStream sigData) throws CMSException { this(createDefaultDigestProvider(), null, sigData); } /** * base constructor - with encapsulated content */ public CMSSignedDataParser( DigestCalculatorProvider digestCalculatorProvider, InputStream sigData) throws CMSException { this(digestCalculatorProvider, null, sigData); } /** * base constructor * * @param signedContent the content that was signed. * @param sigData the signature object stream. * * * @deprecated use method taking a DigestCalculatorProvider */ public CMSSignedDataParser( CMSTypedStream signedContent, InputStream sigData) throws CMSException { this(createDefaultDigestProvider(), signedContent, sigData); } /** * base constructor * * @param digestCalculatorProvider for generating accumulating digests * @param signedContent the content that was signed. * @param sigData the signature object stream. */ public CMSSignedDataParser( DigestCalculatorProvider digestCalculatorProvider, CMSTypedStream signedContent, InputStream sigData) throws CMSException { super(sigData); try { _signedContent = signedContent; _signedData = SignedDataParser.getInstance(_contentInfo.getContent(BERTags.SEQUENCE)); digests = new HashMap(); ASN1SetParser digAlgs = _signedData.getDigestAlgorithms(); ASN1Encodable o; while ((o = digAlgs.readObject()) != null) { AlgorithmIdentifier algId = AlgorithmIdentifier.getInstance(o); try { DigestCalculator calculator = digestCalculatorProvider.get(algId); if (calculator != null) { this.digests.put(algId.getAlgorithm(), calculator); } } catch (OperatorCreationException e) { // ignore } } // // If the message is simply a certificate chain message getContent() may return null. // ContentInfoParser cont = _signedData.getEncapContentInfo(); ASN1OctetStringParser octs = (ASN1OctetStringParser) cont.getContent(BERTags.OCTET_STRING); if (octs != null) { CMSTypedStream ctStr = new CMSTypedStream( cont.getContentType().getId(), octs.getOctetStream()); if (_signedContent == null) { _signedContent = ctStr; } else { // // content passed in, need to read past empty encapsulated content info object if present // ctStr.drain(); } } if (signedContent == null) { _signedContentType = cont.getContentType(); } else { _signedContentType = _signedContent.getContentType(); } } catch (IOException e) { throw new CMSException("io exception: " + e.getMessage(), e); } if (digests.isEmpty()) { throw new CMSException("no digests could be created for message."); } } /** * Return the version number for the SignedData object * * @return the version number */ public int getVersion() { return _signedData.getVersion().getValue().intValue(); } /** * return the collection of signers that are associated with the * signatures for the message. * @throws CMSException */ public SignerInformationStore getSignerInfos() throws CMSException { if (_signerInfoStore == null) { populateCertCrlSets(); List signerInfos = new ArrayList(); Map hashes = new HashMap(); Iterator it = digests.keySet().iterator(); while (it.hasNext()) { Object digestKey = it.next(); hashes.put(digestKey, ((DigestCalculator)digests.get(digestKey)).getDigest()); } try { ASN1SetParser s = _signedData.getSignerInfos(); ASN1Encodable o; while ((o = s.readObject()) != null) { SignerInfo info = SignerInfo.getInstance(o.toASN1Primitive()); byte[] hash = (byte[])hashes.get(info.getDigestAlgorithm().getAlgorithm()); signerInfos.add(new SignerInformation(info, _signedContentType, null, hash)); } } catch (IOException e) { throw new CMSException("io exception: " + e.getMessage(), e); } _signerInfoStore = new SignerInformationStore(signerInfos); } return _signerInfoStore; } /** * return a X509Store containing the attribute certificates, if any, contained * in this message. * * @param type type of store to create * @param provider name of provider to use * @return a store of attribute certificates * @exception NoSuchProviderException if the provider requested isn't available. * @exception org.bouncycastle.x509.NoSuchStoreException if the store type isn't available. * @exception CMSException if a general exception prevents creation of the X509Store * @deprecated use getAttributeCertificates() */ public X509Store getAttributeCertificates( String type, String provider) throws NoSuchStoreException, NoSuchProviderException, CMSException { return getAttributeCertificates(type, CMSUtils.getProvider(provider)); } /** * return a X509Store containing the attribute certificates, if any, contained * in this message. * * @param type type of store to create * @param provider provider to use * @return a store of attribute certificates * @exception org.bouncycastle.x509.NoSuchStoreException if the store type isn't available. * @exception CMSException if a general exception prevents creation of the X509Store * @deprecated use getAttributeCertificates() */ public X509Store getAttributeCertificates( String type, Provider provider) throws NoSuchStoreException, CMSException { if (_attributeStore == null) { populateCertCrlSets(); _attributeStore = HELPER.createAttributeStore(type, provider, this.getAttributeCertificates()); } return _attributeStore; } /** * return a X509Store containing the public key certificates, if any, contained * in this message. * * @param type type of store to create * @param provider provider to use * @return a store of public key certificates * @exception NoSuchProviderException if the provider requested isn't available. * @exception NoSuchStoreException if the store type isn't available. * @exception CMSException if a general exception prevents creation of the X509Store * @deprecated use getCertificates() */ public X509Store getCertificates( String type, String provider) throws NoSuchStoreException, NoSuchProviderException, CMSException { return getCertificates(type, CMSUtils.getProvider(provider)); } /** * return a X509Store containing the public key certificates, if any, contained * in this message. * * @param type type of store to create * @param provider provider to use * @return a store of public key certificates * @exception NoSuchStoreException if the store type isn't available. * @exception CMSException if a general exception prevents creation of the X509Store * @deprecated use getCertificates() */ public X509Store getCertificates( String type, Provider provider) throws NoSuchStoreException, CMSException { if (_certificateStore == null) { populateCertCrlSets(); _certificateStore = HELPER.createCertificateStore(type, provider, this.getCertificates()); } return _certificateStore; } /** * return a X509Store containing CRLs, if any, contained * in this message. * * @param type type of store to create * @param provider name of provider to use * @return a store of CRLs * @exception NoSuchProviderException if the provider requested isn't available. * @exception NoSuchStoreException if the store type isn't available. * @exception CMSException if a general exception prevents creation of the X509Store * @deprecated use getCRLs() */ public X509Store getCRLs( String type, String provider) throws NoSuchStoreException, NoSuchProviderException, CMSException { return getCRLs(type, CMSUtils.getProvider(provider)); } /** * return a X509Store containing CRLs, if any, contained * in this message. * * @param type type of store to create * @param provider provider to use * @return a store of CRLs * @exception NoSuchStoreException if the store type isn't available. * @exception CMSException if a general exception prevents creation of the X509Store * @deprecated use getCRLs() */ public X509Store getCRLs( String type, Provider provider) throws NoSuchStoreException, CMSException { if (_crlStore == null) { populateCertCrlSets(); _crlStore = HELPER.createCRLsStore(type, provider, getCRLs()); } return _crlStore; } /** * return a CertStore containing the certificates and CRLs associated with * this message. * * @exception NoSuchProviderException if the provider requested isn't available. * @exception NoSuchAlgorithmException if the cert store isn't available. * @exception CMSException if a general exception prevents creation of the CertStore * @deprecated use getCertificates() and org.bouncycastle.cert.jcajce.JcaCertStoreBuilder */ public CertStore getCertificatesAndCRLs( String type, String provider) throws NoSuchAlgorithmException, NoSuchProviderException, CMSException { return getCertificatesAndCRLs(type, CMSUtils.getProvider(provider)); } /** * return a CertStore containing the certificates and CRLs associated with * this message. * * @exception NoSuchProviderException if the provider requested isn't available. * @exception NoSuchAlgorithmException if the cert store isn't available. * @exception CMSException if a general exception prevents creation of the CertStore * @deprecated use getCertificates() and org.bouncycastle.cert.jcajce.JcaCertStoreBuilder */ public CertStore getCertificatesAndCRLs( String type, Provider provider) throws NoSuchAlgorithmException, NoSuchProviderException, CMSException { populateCertCrlSets(); try { JcaCertStoreBuilder certStoreBuilder = new JcaCertStoreBuilder().setType(type); if (provider != null) { certStoreBuilder.setProvider(provider); } certStoreBuilder.addCertificates(this.getCertificates()); certStoreBuilder.addCRLs(this.getCRLs()); return certStoreBuilder.build(); } catch (NoSuchAlgorithmException e) { throw e; } catch (Exception e) { throw new CMSException("exception creating CertStore: " + e.getMessage(), e); } } /** * Return any X.509 certificate objects in this SignedData structure as a Store of X509CertificateHolder objects. * * @return a Store of X509CertificateHolder objects. */ public Store getCertificates() throws CMSException { populateCertCrlSets(); return HELPER.getCertificates(_certSet); } /** * Return any X.509 CRL objects in this SignedData structure as a Store of X509CRLHolder objects. * * @return a Store of X509CRLHolder objects. */ public Store getCRLs() throws CMSException { populateCertCrlSets(); return HELPER.getCRLs(_crlSet); } /** * Return any X.509 attribute certificate objects in this SignedData structure as a Store of X509AttributeCertificateHolder objects. * * @return a Store of X509AttributeCertificateHolder objects. */ public Store getAttributeCertificates() throws CMSException { populateCertCrlSets(); return HELPER.getAttributeCertificates(_certSet); } /** * Return any OtherRevocationInfo OtherRevInfo objects of the type indicated by otherRevocationInfoFormat in * this SignedData structure. * * @param otherRevocationInfoFormat OID of the format type been looked for. * * @return a Store of ASN1Encodable objects representing any objects of otherRevocationInfoFormat found. */ public Store getOtherRevocationInfo(ASN1ObjectIdentifier otherRevocationInfoFormat) throws CMSException { populateCertCrlSets(); return HELPER.getOtherRevocationInfo(otherRevocationInfoFormat, _crlSet); } private void populateCertCrlSets() throws CMSException { if (_isCertCrlParsed) { return; } _isCertCrlParsed = true; try { // care! Streaming - these must be done in exactly this order. _certSet = getASN1Set(_signedData.getCertificates()); _crlSet = getASN1Set(_signedData.getCrls()); } catch (IOException e) { throw new CMSException("problem parsing cert/crl sets", e); } } /** * Return the a string representation of the OID associated with the * encapsulated content info structure carried in the signed data. * * @return the OID for the content type. */ public String getSignedContentTypeOID() { return _signedContentType.getId(); } public CMSTypedStream getSignedContent() { if (_signedContent == null) { return null; } InputStream digStream = CMSUtils.attachDigestsToInputStream( digests.values(), _signedContent.getContentStream()); return new CMSTypedStream(_signedContent.getContentType(), digStream); } /** * Replace the signerinformation store associated with the passed * in message contained in the stream original with the new one passed in. * You would probably only want to do this if you wanted to change the unsigned * attributes associated with a signer, or perhaps delete one. *

    * The output stream is returned unclosed. *

    * @param original the signed data stream to be used as a base. * @param signerInformationStore the new signer information store to use. * @param out the stream to write the new signed data object to. * @return out. */ public static OutputStream replaceSigners( InputStream original, SignerInformationStore signerInformationStore, OutputStream out) throws CMSException, IOException { ASN1StreamParser in = new ASN1StreamParser(original); ContentInfoParser contentInfo = new ContentInfoParser((ASN1SequenceParser)in.readObject()); SignedDataParser signedData = SignedDataParser.getInstance(contentInfo.getContent(BERTags.SEQUENCE)); BERSequenceGenerator sGen = new BERSequenceGenerator(out); sGen.addObject(CMSObjectIdentifiers.signedData); BERSequenceGenerator sigGen = new BERSequenceGenerator(sGen.getRawOutputStream(), 0, true); // version number sigGen.addObject(signedData.getVersion()); // digests signedData.getDigestAlgorithms().toASN1Primitive(); // skip old ones ASN1EncodableVector digestAlgs = new ASN1EncodableVector(); for (Iterator it = signerInformationStore.getSigners().iterator(); it.hasNext();) { SignerInformation signer = (SignerInformation)it.next(); digestAlgs.add(CMSSignedHelper.INSTANCE.fixAlgID(signer.getDigestAlgorithmID())); } sigGen.getRawOutputStream().write(new DERSet(digestAlgs).getEncoded()); // encap content info ContentInfoParser encapContentInfo = signedData.getEncapContentInfo(); BERSequenceGenerator eiGen = new BERSequenceGenerator(sigGen.getRawOutputStream()); eiGen.addObject(encapContentInfo.getContentType()); pipeEncapsulatedOctetString(encapContentInfo, eiGen.getRawOutputStream()); eiGen.close(); writeSetToGeneratorTagged(sigGen, signedData.getCertificates(), 0); writeSetToGeneratorTagged(sigGen, signedData.getCrls(), 1); ASN1EncodableVector signerInfos = new ASN1EncodableVector(); for (Iterator it = signerInformationStore.getSigners().iterator(); it.hasNext();) { SignerInformation signer = (SignerInformation)it.next(); signerInfos.add(signer.toASN1Structure()); } sigGen.getRawOutputStream().write(new DERSet(signerInfos).getEncoded()); sigGen.close(); sGen.close(); return out; } /** * Replace the certificate and CRL information associated with this * CMSSignedData object with the new one passed in. *

    * The output stream is returned unclosed. *

    * @param original the signed data stream to be used as a base. * @param certsAndCrls the new certificates and CRLs to be used. * @param out the stream to write the new signed data object to. * @return out. * @exception CMSException if there is an error processing the CertStore * @deprecated use method that takes Store objects. */ public static OutputStream replaceCertificatesAndCRLs( InputStream original, CertStore certsAndCrls, OutputStream out) throws CMSException, IOException { ASN1StreamParser in = new ASN1StreamParser(original); ContentInfoParser contentInfo = new ContentInfoParser((ASN1SequenceParser)in.readObject()); SignedDataParser signedData = SignedDataParser.getInstance(contentInfo.getContent(BERTags.SEQUENCE)); BERSequenceGenerator sGen = new BERSequenceGenerator(out); sGen.addObject(CMSObjectIdentifiers.signedData); BERSequenceGenerator sigGen = new BERSequenceGenerator(sGen.getRawOutputStream(), 0, true); // version number sigGen.addObject(signedData.getVersion()); // digests sigGen.getRawOutputStream().write(signedData.getDigestAlgorithms().toASN1Primitive().getEncoded()); // encap content info ContentInfoParser encapContentInfo = signedData.getEncapContentInfo(); BERSequenceGenerator eiGen = new BERSequenceGenerator(sigGen.getRawOutputStream()); eiGen.addObject(encapContentInfo.getContentType()); pipeEncapsulatedOctetString(encapContentInfo, eiGen.getRawOutputStream()); eiGen.close(); // // skip existing certs and CRLs // getASN1Set(signedData.getCertificates()); getASN1Set(signedData.getCrls()); // // replace the certs and crls in the SignedData object // ASN1Set certs; try { certs = CMSUtils.createBerSetFromList(CMSUtils.getCertificatesFromStore(certsAndCrls)); } catch (CertStoreException e) { throw new CMSException("error getting certs from certStore", e); } if (certs.size() > 0) { sigGen.getRawOutputStream().write(new DERTaggedObject(false, 0, certs).getEncoded()); } ASN1Set crls; try { crls = CMSUtils.createBerSetFromList(CMSUtils.getCRLsFromStore(certsAndCrls)); } catch (CertStoreException e) { throw new CMSException("error getting crls from certStore", e); } if (crls.size() > 0) { sigGen.getRawOutputStream().write(new DERTaggedObject(false, 1, crls).getEncoded()); } sigGen.getRawOutputStream().write(signedData.getSignerInfos().toASN1Primitive().getEncoded()); sigGen.close(); sGen.close(); return out; } /** * Replace the certificate and CRL information associated with this * CMSSignedData object with the new one passed in. *

    * The output stream is returned unclosed. *

    * @param original the signed data stream to be used as a base. * @param certs new certificates to be used, if any. * @param crls new CRLs to be used, if any. * @param attrCerts new attribute certificates to be used, if any. * @param out the stream to write the new signed data object to. * @return out. * @exception CMSException if there is an error processing the CertStore */ public static OutputStream replaceCertificatesAndCRLs( InputStream original, Store certs, Store crls, Store attrCerts, OutputStream out) throws CMSException, IOException { ASN1StreamParser in = new ASN1StreamParser(original); ContentInfoParser contentInfo = new ContentInfoParser((ASN1SequenceParser)in.readObject()); SignedDataParser signedData = SignedDataParser.getInstance(contentInfo.getContent(BERTags.SEQUENCE)); BERSequenceGenerator sGen = new BERSequenceGenerator(out); sGen.addObject(CMSObjectIdentifiers.signedData); BERSequenceGenerator sigGen = new BERSequenceGenerator(sGen.getRawOutputStream(), 0, true); // version number sigGen.addObject(signedData.getVersion()); // digests sigGen.getRawOutputStream().write(signedData.getDigestAlgorithms().toASN1Primitive().getEncoded()); // encap content info ContentInfoParser encapContentInfo = signedData.getEncapContentInfo(); BERSequenceGenerator eiGen = new BERSequenceGenerator(sigGen.getRawOutputStream()); eiGen.addObject(encapContentInfo.getContentType()); pipeEncapsulatedOctetString(encapContentInfo, eiGen.getRawOutputStream()); eiGen.close(); // // skip existing certs and CRLs // getASN1Set(signedData.getCertificates()); getASN1Set(signedData.getCrls()); // // replace the certs and crls in the SignedData object // if (certs != null || attrCerts != null) { List certificates = new ArrayList(); if (certs != null) { certificates.addAll(CMSUtils.getCertificatesFromStore(certs)); } if (attrCerts != null) { certificates.addAll(CMSUtils.getAttributeCertificatesFromStore(attrCerts)); } ASN1Set asn1Certs = CMSUtils.createBerSetFromList(certificates); if (asn1Certs.size() > 0) { sigGen.getRawOutputStream().write(new DERTaggedObject(false, 0, asn1Certs).getEncoded()); } } if (crls != null) { ASN1Set asn1Crls = CMSUtils.createBerSetFromList(CMSUtils.getCRLsFromStore(crls)); if (asn1Crls.size() > 0) { sigGen.getRawOutputStream().write(new DERTaggedObject(false, 1, asn1Crls).getEncoded()); } } sigGen.getRawOutputStream().write(signedData.getSignerInfos().toASN1Primitive().getEncoded()); sigGen.close(); sGen.close(); return out; } private static void writeSetToGeneratorTagged( ASN1Generator asn1Gen, ASN1SetParser asn1SetParser, int tagNo) throws IOException { ASN1Set asn1Set = getASN1Set(asn1SetParser); if (asn1Set != null) { if (asn1SetParser instanceof BERSetParser) { asn1Gen.getRawOutputStream().write(new BERTaggedObject(false, tagNo, asn1Set).getEncoded()); } else { asn1Gen.getRawOutputStream().write(new DERTaggedObject(false, tagNo, asn1Set).getEncoded()); } } } private static ASN1Set getASN1Set( ASN1SetParser asn1SetParser) { return asn1SetParser == null ? null : ASN1Set.getInstance(asn1SetParser.toASN1Primitive()); } private static void pipeEncapsulatedOctetString(ContentInfoParser encapContentInfo, OutputStream rawOutputStream) throws IOException { ASN1OctetStringParser octs = (ASN1OctetStringParser) encapContentInfo.getContent(BERTags.OCTET_STRING); if (octs != null) { pipeOctetString(octs, rawOutputStream); } // BERTaggedObjectParser contentObject = (BERTaggedObjectParser)encapContentInfo.getContentObject(); // if (contentObject != null) // { // // Handle IndefiniteLengthInputStream safely // InputStream input = ASN1StreamParser.getSafeRawInputStream(contentObject.getContentStream(true)); // // // TODO BerTaggedObjectGenerator? // BEROutputStream berOut = new BEROutputStream(rawOutputStream); // berOut.write(DERTags.CONSTRUCTED | DERTags.TAGGED | 0); // berOut.write(0x80); // // pipeRawOctetString(input, rawOutputStream); // // berOut.write(0x00); // berOut.write(0x00); // // input.close(); // } } private static void pipeOctetString( ASN1OctetStringParser octs, OutputStream output) throws IOException { // TODO Allow specification of a specific fragment size? OutputStream outOctets = CMSUtils.createBEROctetOutputStream( output, 0, true, 0); Streams.pipeAll(octs.getOctetStream(), outOctets); outOctets.close(); } // private static void pipeRawOctetString( // InputStream rawInput, // OutputStream rawOutput) // throws IOException // { // InputStream tee = new TeeInputStream(rawInput, rawOutput); // ASN1StreamParser sp = new ASN1StreamParser(tee); // ASN1OctetStringParser octs = (ASN1OctetStringParser)sp.readObject(); // Streams.drain(octs.getOctetStream()); // } } bouncycastle-1.49.orig/src/org/bouncycastle/cms/CMSAuthenticatedDataParser.java0000644000175000017500000003007511726032023027224 0ustar ebourgebourgpackage org.bouncycastle.cms; import java.io.ByteArrayInputStream; import java.io.IOException; import java.io.InputStream; import java.security.AlgorithmParameters; import java.security.NoSuchProviderException; import java.security.Provider; import org.bouncycastle.asn1.ASN1Encodable; import org.bouncycastle.asn1.ASN1EncodableVector; import org.bouncycastle.asn1.ASN1OctetString; import org.bouncycastle.asn1.ASN1OctetStringParser; import org.bouncycastle.asn1.ASN1SequenceParser; import org.bouncycastle.asn1.ASN1Set; import org.bouncycastle.asn1.ASN1SetParser; import org.bouncycastle.asn1.BERTags; import org.bouncycastle.asn1.DERSet; import org.bouncycastle.asn1.cms.AttributeTable; import org.bouncycastle.asn1.cms.AuthenticatedDataParser; import org.bouncycastle.asn1.cms.CMSAttributes; import org.bouncycastle.asn1.cms.ContentInfoParser; import org.bouncycastle.asn1.cms.OriginatorInfo; import org.bouncycastle.asn1.x509.AlgorithmIdentifier; import org.bouncycastle.cms.jcajce.JceAlgorithmIdentifierConverter; import org.bouncycastle.operator.DigestCalculatorProvider; import org.bouncycastle.operator.OperatorCreationException; import org.bouncycastle.util.Arrays; /** * Parsing class for an CMS Authenticated Data object from an input stream. *

    * Note: that because we are in a streaming mode only one recipient can be tried and it is important * that the methods on the parser are called in the appropriate order. *

    *

    * Example of use - assuming the first recipient matches the private key we have. *

     *      CMSAuthenticatedDataParser     ad = new CMSAuthenticatedDataParser(inputStream);
     *
     *      RecipientInformationStore  recipients = ad.getRecipientInfos();
     *
     *      Collection  c = recipients.getRecipients();
     *      Iterator    it = c.iterator();
     *
     *      if (it.hasNext())
     *      {
     *          RecipientInformation   recipient = (RecipientInformation)it.next();
     *
     *          CMSTypedStream recData = recipient.getContentStream(new JceKeyTransAuthenticatedRecipient(privateKey).setProvider("BC"));
     *
     *          processDataStream(recData.getContentStream());
     *
     *          if (!Arrays.equals(ad.getMac(), recipient.getMac())
     *          {
     *              System.err.println("Data corrupted!!!!");
     *          }
     *      }
     *  
    * Note: this class does not introduce buffering - if you are processing large files you should create * the parser with: *
     *          CMSAuthenticatedDataParser     ep = new CMSAuthenticatedDataParser(new BufferedInputStream(inputStream, bufSize));
     *  
    * where bufSize is a suitably large buffer size. */ public class CMSAuthenticatedDataParser extends CMSContentInfoParser { RecipientInformationStore recipientInfoStore; AuthenticatedDataParser authData; private AlgorithmIdentifier macAlg; private byte[] mac; private AttributeTable authAttrs; private ASN1Set authAttrSet; private AttributeTable unauthAttrs; private boolean authAttrNotRead; private boolean unauthAttrNotRead; private OriginatorInformation originatorInfo; public CMSAuthenticatedDataParser( byte[] envelopedData) throws CMSException, IOException { this(new ByteArrayInputStream(envelopedData)); } public CMSAuthenticatedDataParser( byte[] envelopedData, DigestCalculatorProvider digestCalculatorProvider) throws CMSException, IOException { this(new ByteArrayInputStream(envelopedData), digestCalculatorProvider); } public CMSAuthenticatedDataParser( InputStream envelopedData) throws CMSException, IOException { this(envelopedData, null); } public CMSAuthenticatedDataParser( InputStream envelopedData, DigestCalculatorProvider digestCalculatorProvider) throws CMSException, IOException { super(envelopedData); this.authAttrNotRead = true; this.authData = new AuthenticatedDataParser((ASN1SequenceParser)_contentInfo.getContent(BERTags.SEQUENCE)); // TODO Validate version? //DERInteger version = this.authData.getVersion(); OriginatorInfo info = authData.getOriginatorInfo(); if (info != null) { this.originatorInfo = new OriginatorInformation(info); } // // read the recipients // ASN1Set recipientInfos = ASN1Set.getInstance(authData.getRecipientInfos().toASN1Primitive()); this.macAlg = authData.getMacAlgorithm(); // // build the RecipientInformationStore // AlgorithmIdentifier digestAlgorithm = authData.getDigestAlgorithm(); if (digestAlgorithm != null) { if (digestCalculatorProvider == null) { throw new CMSException("a digest calculator provider is required if authenticated attributes are present"); } // // read the authenticated content info // ContentInfoParser data = authData.getEnapsulatedContentInfo(); CMSReadable readable = new CMSProcessableInputStream( ((ASN1OctetStringParser)data.getContent(BERTags.OCTET_STRING)).getOctetStream()); try { CMSSecureReadable secureReadable = new CMSEnvelopedHelper.CMSDigestAuthenticatedSecureReadable(digestCalculatorProvider.get(digestAlgorithm), readable); this.recipientInfoStore = CMSEnvelopedHelper.buildRecipientInformationStore(recipientInfos, this.macAlg, secureReadable, new AuthAttributesProvider() { public ASN1Set getAuthAttributes() { try { return getAuthAttrSet(); } catch (IOException e) { throw new IllegalStateException("can't parse authenticated attributes!"); } } }); } catch (OperatorCreationException e) { throw new CMSException("unable to create digest calculator: " + e.getMessage(), e); } } else { // // read the authenticated content info // ContentInfoParser data = authData.getEnapsulatedContentInfo(); CMSReadable readable = new CMSProcessableInputStream( ((ASN1OctetStringParser)data.getContent(BERTags.OCTET_STRING)).getOctetStream()); CMSSecureReadable secureReadable = new CMSEnvelopedHelper.CMSAuthenticatedSecureReadable(this.macAlg, readable); this.recipientInfoStore = CMSEnvelopedHelper.buildRecipientInformationStore(recipientInfos, this.macAlg, secureReadable); } } /** * Return the originator information associated with this message if present. * * @return OriginatorInformation, null if not present. */ public OriginatorInformation getOriginatorInfo() { return originatorInfo; } /** * Return the MAC algorithm details for the MAC associated with the data in this object. * * @return AlgorithmIdentifier representing the MAC algorithm. */ public AlgorithmIdentifier getMacAlgorithm() { return macAlg; } /** * return the object identifier for the mac algorithm. */ public String getMacAlgOID() { return macAlg.getAlgorithm().toString(); } /** * return the ASN.1 encoded encryption algorithm parameters, or null if * there aren't any. */ public byte[] getMacAlgParams() { try { return encodeObj(macAlg.getParameters()); } catch (Exception e) { throw new RuntimeException("exception getting encryption parameters " + e); } } /** * Return an AlgorithmParameters object giving the encryption parameters * used to encrypt the message content. * * @param provider the name of the provider to generate the parameters for. * @return the parameters object, null if there is not one. * @throws org.bouncycastle.cms.CMSException if the algorithm cannot be found, or the parameters can't be parsed. * @throws java.security.NoSuchProviderException if the provider cannot be found. * @deprecated use getMacAlgorithm and JceAlgorithmIdentifierConverter(). */ public AlgorithmParameters getMacAlgorithmParameters( String provider) throws CMSException, NoSuchProviderException { return new JceAlgorithmIdentifierConverter().setProvider(provider).getAlgorithmParameters(macAlg); } /** * Return an AlgorithmParameters object giving the encryption parameters * used to encrypt the message content. * * @param provider the provider to generate the parameters for. * @return the parameters object, null if there is not one. * @throws org.bouncycastle.cms.CMSException if the algorithm cannot be found, or the parameters can't be parsed. * @deprecated use getMacAlgorithm and JceAlgorithmIdentifierConverter(). */ public AlgorithmParameters getMacAlgorithmParameters( Provider provider) throws CMSException { return new JceAlgorithmIdentifierConverter().setProvider(provider).getAlgorithmParameters(macAlg); } /** * return a store of the intended recipients for this message */ public RecipientInformationStore getRecipientInfos() { return recipientInfoStore; } public byte[] getMac() throws IOException { if (mac == null) { getAuthAttrs(); mac = authData.getMac().getOctets(); } return Arrays.clone(mac); } private ASN1Set getAuthAttrSet() throws IOException { if (authAttrs == null && authAttrNotRead) { ASN1SetParser set = authData.getAuthAttrs(); if (set != null) { authAttrSet = (ASN1Set)set.toASN1Primitive(); } authAttrNotRead = false; } return authAttrSet; } /** * return a table of the unauthenticated attributes indexed by * the OID of the attribute. * @exception java.io.IOException */ public AttributeTable getAuthAttrs() throws IOException { if (authAttrs == null && authAttrNotRead) { ASN1Set set = getAuthAttrSet(); if (set != null) { authAttrs = new AttributeTable(set); } } return authAttrs; } /** * return a table of the unauthenticated attributes indexed by * the OID of the attribute. * @exception java.io.IOException */ public AttributeTable getUnauthAttrs() throws IOException { if (unauthAttrs == null && unauthAttrNotRead) { ASN1SetParser set = authData.getUnauthAttrs(); unauthAttrNotRead = false; if (set != null) { ASN1EncodableVector v = new ASN1EncodableVector(); ASN1Encodable o; while ((o = set.readObject()) != null) { ASN1SequenceParser seq = (ASN1SequenceParser)o; v.add(seq.toASN1Primitive()); } unauthAttrs = new AttributeTable(new DERSet(v)); } } return unauthAttrs; } private byte[] encodeObj( ASN1Encodable obj) throws IOException { if (obj != null) { return obj.toASN1Primitive().getEncoded(); } return null; } /** * This will only be valid after the content has been read. * * @return the contents of the messageDigest attribute, if available. Null if not present. */ public byte[] getContentDigest() { if (authAttrs != null) { return ASN1OctetString.getInstance(authAttrs.get(CMSAttributes.messageDigest).getAttrValues().getObjectAt(0)).getOctets(); } return null; } } bouncycastle-1.49.orig/src/org/bouncycastle/cms/KEKRecipientId.java0000644000175000017500000000242411726246511024670 0ustar ebourgebourgpackage org.bouncycastle.cms; import org.bouncycastle.util.Arrays; public class KEKRecipientId extends RecipientId { private byte[] keyIdentifier; /** * Construct a recipient ID with the key identifier of a KEK recipient. * * @param keyIdentifier a subjectKeyId */ public KEKRecipientId(byte[] keyIdentifier) { super(kek); this.keyIdentifier = keyIdentifier; } public int hashCode() { return Arrays.hashCode(keyIdentifier); } public boolean equals( Object o) { if (!(o instanceof KEKRecipientId)) { return false; } KEKRecipientId id = (KEKRecipientId)o; return Arrays.areEqual(keyIdentifier, id.keyIdentifier); } public byte[] getKeyIdentifier() { return Arrays.clone(keyIdentifier); } public Object clone() { return new KEKRecipientId(keyIdentifier); } public boolean match(Object obj) { if (obj instanceof byte[]) { return Arrays.areEqual(keyIdentifier, (byte[])obj); } else if (obj instanceof KEKRecipientInformation) { return ((KEKRecipientInformation)obj).getRID().equals(this); } return false; } } bouncycastle-1.49.orig/src/org/bouncycastle/cms/SignerInformationVerifier.java0000644000175000017500000000374711562115504027273 0ustar ebourgebourgpackage org.bouncycastle.cms; import org.bouncycastle.asn1.x509.AlgorithmIdentifier; import org.bouncycastle.cert.X509CertificateHolder; import org.bouncycastle.operator.ContentVerifier; import org.bouncycastle.operator.ContentVerifierProvider; import org.bouncycastle.operator.DigestCalculator; import org.bouncycastle.operator.DigestCalculatorProvider; import org.bouncycastle.operator.OperatorCreationException; import org.bouncycastle.operator.SignatureAlgorithmIdentifierFinder; public class SignerInformationVerifier { private ContentVerifierProvider verifierProvider; private DigestCalculatorProvider digestProvider; private SignatureAlgorithmIdentifierFinder sigAlgorithmFinder; private CMSSignatureAlgorithmNameGenerator sigNameGenerator; public SignerInformationVerifier(CMSSignatureAlgorithmNameGenerator sigNameGenerator, SignatureAlgorithmIdentifierFinder sigAlgorithmFinder, ContentVerifierProvider verifierProvider, DigestCalculatorProvider digestProvider) { this.sigNameGenerator = sigNameGenerator; this.sigAlgorithmFinder = sigAlgorithmFinder; this.verifierProvider = verifierProvider; this.digestProvider = digestProvider; } public boolean hasAssociatedCertificate() { return verifierProvider.hasAssociatedCertificate(); } public X509CertificateHolder getAssociatedCertificate() { return verifierProvider.getAssociatedCertificate(); } public ContentVerifier getContentVerifier(AlgorithmIdentifier signingAlgorithm, AlgorithmIdentifier digestAlgorithm) throws OperatorCreationException { String signatureName = sigNameGenerator.getSignatureName(digestAlgorithm, signingAlgorithm); return verifierProvider.get(sigAlgorithmFinder.find(signatureName)); } public DigestCalculator getDigestCalculator(AlgorithmIdentifier algorithmIdentifier) throws OperatorCreationException { return digestProvider.get(algorithmIdentifier); } } bouncycastle-1.49.orig/src/org/bouncycastle/cms/CMSVerifierCertificateNotValidException.java0000644000175000017500000000033111507207100031716 0ustar ebourgebourgpackage org.bouncycastle.cms; public class CMSVerifierCertificateNotValidException extends CMSException { public CMSVerifierCertificateNotValidException( String msg) { super(msg); } } bouncycastle-1.49.orig/src/org/bouncycastle/cms/CMSAuthEnvelopedGenerator.java0000644000175000017500000000122311276513417027111 0ustar ebourgebourgpackage org.bouncycastle.cms; import org.bouncycastle.asn1.nist.NISTObjectIdentifiers; class CMSAuthEnvelopedGenerator { public static final String AES128_CCM = NISTObjectIdentifiers.id_aes128_CCM.getId(); public static final String AES192_CCM = NISTObjectIdentifiers.id_aes192_CCM.getId(); public static final String AES256_CCM = NISTObjectIdentifiers.id_aes256_CCM.getId(); public static final String AES128_GCM = NISTObjectIdentifiers.id_aes128_GCM.getId(); public static final String AES192_GCM = NISTObjectIdentifiers.id_aes192_GCM.getId(); public static final String AES256_GCM = NISTObjectIdentifiers.id_aes256_GCM.getId(); } bouncycastle-1.49.orig/src/org/bouncycastle/cms/CMSSignatureEncryptionAlgorithmFinder.java0000644000175000017500000000132311651132414031502 0ustar ebourgebourgpackage org.bouncycastle.cms; import org.bouncycastle.asn1.x509.AlgorithmIdentifier; /** * Finder which is used to look up the algorithm identifiers representing the encryption algorithms that * are associated with a particular signature algorithm. */ public interface CMSSignatureEncryptionAlgorithmFinder { /** * Return the encryption algorithm identifier associated with the passed in signatureAlgorithm * @param signatureAlgorithm the algorithm identifier of the signature of interest * @return the algorithm identifier to be associated with the encryption algorithm used in signature creation. */ AlgorithmIdentifier findEncryptionAlgorithm(AlgorithmIdentifier signatureAlgorithm); } bouncycastle-1.49.orig/src/org/bouncycastle/cms/CMSEnvelopedDataParser.java0000644000175000017500000002011211726032656026366 0ustar ebourgebourgpackage org.bouncycastle.cms; import java.io.ByteArrayInputStream; import java.io.IOException; import java.io.InputStream; import java.security.AlgorithmParameters; import java.security.NoSuchProviderException; import java.security.Provider; import org.bouncycastle.asn1.ASN1Encodable; import org.bouncycastle.asn1.ASN1EncodableVector; import org.bouncycastle.asn1.ASN1OctetStringParser; import org.bouncycastle.asn1.ASN1SequenceParser; import org.bouncycastle.asn1.ASN1Set; import org.bouncycastle.asn1.ASN1SetParser; import org.bouncycastle.asn1.BERTags; import org.bouncycastle.asn1.DERSet; import org.bouncycastle.asn1.cms.AttributeTable; import org.bouncycastle.asn1.cms.EncryptedContentInfoParser; import org.bouncycastle.asn1.cms.EnvelopedDataParser; import org.bouncycastle.asn1.cms.OriginatorInfo; import org.bouncycastle.asn1.x509.AlgorithmIdentifier; import org.bouncycastle.cms.jcajce.JceAlgorithmIdentifierConverter; /** * Parsing class for an CMS Enveloped Data object from an input stream. *

    * Note: that because we are in a streaming mode only one recipient can be tried and it is important * that the methods on the parser are called in the appropriate order. *

    *

    * Example of use - assuming the first recipient matches the private key we have. *

     *      CMSEnvelopedDataParser     ep = new CMSEnvelopedDataParser(inputStream);
     *
     *      RecipientInformationStore  recipients = ep.getRecipientInfos();
     *
     *      Collection  c = recipients.getRecipients();
     *      Iterator    it = c.iterator();
     *      
     *      if (it.hasNext())
     *      {
     *          RecipientInformation   recipient = (RecipientInformation)it.next();
     *
     *          CMSTypedStream recData = recipient.getContentStream(new JceKeyTransEnvelopedRecipient(privateKey).setProvider("BC"));
     *          
     *          processDataStream(recData.getContentStream());
     *      }
     *  
    * Note: this class does not introduce buffering - if you are processing large files you should create * the parser with: *
     *          CMSEnvelopedDataParser     ep = new CMSEnvelopedDataParser(new BufferedInputStream(inputStream, bufSize));
     *  
    * where bufSize is a suitably large buffer size. */ public class CMSEnvelopedDataParser extends CMSContentInfoParser { RecipientInformationStore recipientInfoStore; EnvelopedDataParser envelopedData; private AlgorithmIdentifier encAlg; private AttributeTable unprotectedAttributes; private boolean attrNotRead; private OriginatorInformation originatorInfo; public CMSEnvelopedDataParser( byte[] envelopedData) throws CMSException, IOException { this(new ByteArrayInputStream(envelopedData)); } public CMSEnvelopedDataParser( InputStream envelopedData) throws CMSException, IOException { super(envelopedData); this.attrNotRead = true; this.envelopedData = new EnvelopedDataParser((ASN1SequenceParser)_contentInfo.getContent(BERTags.SEQUENCE)); // TODO Validate version? //DERInteger version = this._envelopedData.getVersion(); OriginatorInfo info = this.envelopedData.getOriginatorInfo(); if (info != null) { this.originatorInfo = new OriginatorInformation(info); } // // read the recipients // ASN1Set recipientInfos = ASN1Set.getInstance(this.envelopedData.getRecipientInfos().toASN1Primitive()); // // read the encrypted content info // EncryptedContentInfoParser encInfo = this.envelopedData.getEncryptedContentInfo(); this.encAlg = encInfo.getContentEncryptionAlgorithm(); CMSReadable readable = new CMSProcessableInputStream( ((ASN1OctetStringParser)encInfo.getEncryptedContent(BERTags.OCTET_STRING)).getOctetStream()); CMSSecureReadable secureReadable = new CMSEnvelopedHelper.CMSEnvelopedSecureReadable( this.encAlg, readable); // // build the RecipientInformationStore // this.recipientInfoStore = CMSEnvelopedHelper.buildRecipientInformationStore( recipientInfos, this.encAlg, secureReadable); } /** * return the object identifier for the content encryption algorithm. */ public String getEncryptionAlgOID() { return encAlg.getAlgorithm().toString(); } /** * return the ASN.1 encoded encryption algorithm parameters, or null if * there aren't any. */ public byte[] getEncryptionAlgParams() { try { return encodeObj(encAlg.getParameters()); } catch (Exception e) { throw new RuntimeException("exception getting encryption parameters " + e); } } /** * Return the content encryption algorithm details for the data in this object. * * @return AlgorithmIdentifier representing the content encryption algorithm. */ public AlgorithmIdentifier getContentEncryptionAlgorithm() { return encAlg; } /** * Return an AlgorithmParameters object giving the encryption parameters * used to encrypt the message content. * * @param provider the provider to generate the parameters for. * @return the parameters object, null if there is not one. * @throws CMSException if the algorithm cannot be found, or the parameters can't be parsed. * @throws NoSuchProviderException if the provider cannot be found. * @deprecated use getContentEncryptionAlgorithm and JceAlgorithmIdentifierConverter(). */ public AlgorithmParameters getEncryptionAlgorithmParameters( String provider) throws CMSException, NoSuchProviderException { return new JceAlgorithmIdentifierConverter().setProvider(provider).getAlgorithmParameters(encAlg); } /** * Return an AlgorithmParameters object giving the encryption parameters * used to encrypt the message content. * * @param provider the provider to generate the parameters for. * @return the parameters object, null if there is not one. * @throws CMSException if the algorithm cannot be found, or the parameters can't be parsed. * @deprecated use getContentEncryptionAlgorithm and JceAlgorithmIdentifierConverter(). */ public AlgorithmParameters getEncryptionAlgorithmParameters( Provider provider) throws CMSException { return new JceAlgorithmIdentifierConverter().setProvider(provider).getAlgorithmParameters(encAlg); } /** * Return the originator information associated with this message if present. * * @return OriginatorInformation, null if not present. */ public OriginatorInformation getOriginatorInfo() { return originatorInfo; } /** * return a store of the intended recipients for this message */ public RecipientInformationStore getRecipientInfos() { return recipientInfoStore; } /** * return a table of the unprotected attributes indexed by * the OID of the attribute. * @exception IOException */ public AttributeTable getUnprotectedAttributes() throws IOException { if (unprotectedAttributes == null && attrNotRead) { ASN1SetParser set = envelopedData.getUnprotectedAttrs(); attrNotRead = false; if (set != null) { ASN1EncodableVector v = new ASN1EncodableVector(); ASN1Encodable o; while ((o = set.readObject()) != null) { ASN1SequenceParser seq = (ASN1SequenceParser)o; v.add(seq.toASN1Primitive()); } unprotectedAttributes = new AttributeTable(new DERSet(v)); } } return unprotectedAttributes; } private byte[] encodeObj( ASN1Encodable obj) throws IOException { if (obj != null) { return obj.toASN1Primitive().getEncoded(); } return null; } } bouncycastle-1.49.orig/src/org/bouncycastle/cms/RecipientInformationStore.java0000644000175000017500000000625612151551722027306 0ustar ebourgebourgpackage org.bouncycastle.cms; import java.util.ArrayList; import java.util.Collection; import java.util.HashMap; import java.util.Iterator; import java.util.List; import java.util.Map; import org.bouncycastle.asn1.x500.X500Name; public class RecipientInformationStore { private final List all; //ArrayList[RecipientInformation] private final Map table = new HashMap(); // HashMap[RecipientID, ArrayList[RecipientInformation]] public RecipientInformationStore( Collection recipientInfos) { Iterator it = recipientInfos.iterator(); while (it.hasNext()) { RecipientInformation recipientInformation = (RecipientInformation)it.next(); RecipientId rid = recipientInformation.getRID(); List list = (ArrayList)table.get(rid); if (list == null) { list = new ArrayList(1); table.put(rid, list); } list.add(recipientInformation); } this.all = new ArrayList(recipientInfos); } /** * Return the first RecipientInformation object that matches the * passed in selector. Null if there are no matches. * * @param selector to identify a recipient * @return a single RecipientInformation object. Null if none matches. */ public RecipientInformation get( RecipientId selector) { Collection list = getRecipients(selector); return list.size() == 0 ? null : (RecipientInformation)list.iterator().next(); } /** * Return the number of recipients in the collection. * * @return number of recipients identified. */ public int size() { return all.size(); } /** * Return all recipients in the collection * * @return a collection of recipients. */ public Collection getRecipients() { return new ArrayList(all); } /** * Return possible empty collection with recipients matching the passed in RecipientId * * @param selector a recipient id to select against. * @return a collection of RecipientInformation objects. */ public Collection getRecipients( RecipientId selector) { if (selector instanceof KeyTransRecipientId) { KeyTransRecipientId keyTrans = (KeyTransRecipientId)selector; X500Name issuer = keyTrans.getIssuer(); byte[] subjectKeyId = keyTrans.getSubjectKeyIdentifier(); if (issuer != null && subjectKeyId != null) { List results = new ArrayList(); Collection match1 = getRecipients(new KeyTransRecipientId(issuer, keyTrans.getSerialNumber())); if (match1 != null) { results.addAll(match1); } Collection match2 = getRecipients(new KeyTransRecipientId(subjectKeyId)); if (match2 != null) { results.addAll(match2); } return results; } } List list = (ArrayList)table.get(selector); return list == null ? new ArrayList() : new ArrayList(list); } } bouncycastle-1.49.orig/src/org/bouncycastle/cms/CMSAttributeTableGenerator.java0000644000175000017500000000107410760650613027262 0ustar ebourgebourgpackage org.bouncycastle.cms; import org.bouncycastle.asn1.cms.AttributeTable; import java.util.Map; /** * Note: The SIGNATURE parameter is only available when generating unsigned attributes. */ public interface CMSAttributeTableGenerator { static final String CONTENT_TYPE = "contentType"; static final String DIGEST = "digest"; static final String SIGNATURE = "encryptedDigest"; static final String DIGEST_ALGORITHM_IDENTIFIER = "digestAlgID"; AttributeTable getAttributes(Map parameters) throws CMSAttributeTableGenerationException; } bouncycastle-1.49.orig/src/org/bouncycastle/cms/OriginatorId.java0000644000175000017500000000561711726257322024541 0ustar ebourgebourgpackage org.bouncycastle.cms; import java.math.BigInteger; import org.bouncycastle.asn1.x500.X500Name; import org.bouncycastle.util.Arrays; import org.bouncycastle.util.Selector; /** * a basic index for an originator. */ class OriginatorId implements Selector { private byte[] subjectKeyId; private X500Name issuer; private BigInteger serialNumber; /** * Construct a signer ID with the value of a public key's subjectKeyId. * * @param subjectKeyId a subjectKeyId */ public OriginatorId(byte[] subjectKeyId) { setSubjectKeyID(subjectKeyId); } private void setSubjectKeyID(byte[] subjectKeyId) { this.subjectKeyId = subjectKeyId; } /** * Construct a signer ID based on the issuer and serial number of the signer's associated * certificate. * * @param issuer the issuer of the signer's associated certificate. * @param serialNumber the serial number of the signer's associated certificate. */ public OriginatorId(X500Name issuer, BigInteger serialNumber) { setIssuerAndSerial(issuer, serialNumber); } private void setIssuerAndSerial(X500Name issuer, BigInteger serialNumber) { this.issuer = issuer; this.serialNumber = serialNumber; } /** * Construct a signer ID based on the issuer and serial number of the signer's associated * certificate. * * @param issuer the issuer of the signer's associated certificate. * @param serialNumber the serial number of the signer's associated certificate. * @param subjectKeyId the subject key identifier to use to match the signers associated certificate. */ public OriginatorId(X500Name issuer, BigInteger serialNumber, byte[] subjectKeyId) { setIssuerAndSerial(issuer, serialNumber); setSubjectKeyID(subjectKeyId); } public X500Name getIssuer() { return issuer; } public Object clone() { return new OriginatorId(this.issuer, this.serialNumber, this.subjectKeyId); } public int hashCode() { int code = Arrays.hashCode(subjectKeyId); if (this.serialNumber != null) { code ^= this.serialNumber.hashCode(); } if (this.issuer != null) { code ^= this.issuer.hashCode(); } return code; } public boolean equals( Object o) { if (!(o instanceof OriginatorId)) { return false; } OriginatorId id = (OriginatorId)o; return Arrays.areEqual(subjectKeyId, id.subjectKeyId) && equalsObj(this.serialNumber, id.serialNumber) && equalsObj(this.issuer, id.issuer); } private boolean equalsObj(Object a, Object b) { return (a != null) ? a.equals(b) : b == null; } public boolean match(Object obj) { return false; } } bouncycastle-1.49.orig/src/org/bouncycastle/cms/DefaultAuthenticatedAttributeTableGenerator.java0000644000175000017500000000527211737144163032736 0ustar ebourgebourgpackage org.bouncycastle.cms; import java.util.Hashtable; import java.util.Map; import org.bouncycastle.asn1.ASN1ObjectIdentifier; import org.bouncycastle.asn1.DEROctetString; import org.bouncycastle.asn1.DERSet; import org.bouncycastle.asn1.cms.Attribute; import org.bouncycastle.asn1.cms.AttributeTable; import org.bouncycastle.asn1.cms.CMSAttributes; /** * Default authenticated attributes generator. */ public class DefaultAuthenticatedAttributeTableGenerator implements CMSAttributeTableGenerator { private final Hashtable table; /** * Initialise to use all defaults */ public DefaultAuthenticatedAttributeTableGenerator() { table = new Hashtable(); } /** * Initialise with some extra attributes or overrides. * * @param attributeTable initial attribute table to use. */ public DefaultAuthenticatedAttributeTableGenerator( AttributeTable attributeTable) { if (attributeTable != null) { table = attributeTable.toHashtable(); } else { table = new Hashtable(); } } /** * Create a standard attribute table from the passed in parameters - this will * normally include contentType and messageDigest. If the constructor * using an AttributeTable was used, entries in it for contentType and * messageDigest will override the generated ones. * * @param parameters source parameters for table generation. * * @return a filled in Hashtable of attributes. */ protected Hashtable createStandardAttributeTable( Map parameters) { Hashtable std = (Hashtable)table.clone(); if (!std.containsKey(CMSAttributes.contentType)) { ASN1ObjectIdentifier contentType = ASN1ObjectIdentifier.getInstance( parameters.get(CMSAttributeTableGenerator.CONTENT_TYPE)); Attribute attr = new Attribute(CMSAttributes.contentType, new DERSet(contentType)); std.put(attr.getAttrType(), attr); } if (!std.containsKey(CMSAttributes.messageDigest)) { byte[] messageDigest = (byte[])parameters.get( CMSAttributeTableGenerator.DIGEST); Attribute attr = new Attribute(CMSAttributes.messageDigest, new DERSet(new DEROctetString(messageDigest))); std.put(attr.getAttrType(), attr); } return std; } /** * @param parameters source parameters * @return the populated attribute table */ public AttributeTable getAttributes(Map parameters) { return new AttributeTable(createStandardAttributeTable(parameters)); } } bouncycastle-1.49.orig/src/org/bouncycastle/cms/CMSPBEKey.java0000644000175000017500000000320211222021263023535 0ustar ebourgebourgpackage org.bouncycastle.cms; import java.security.AlgorithmParameters; import java.security.InvalidAlgorithmParameterException; import java.security.spec.InvalidParameterSpecException; import javax.crypto.interfaces.PBEKey; import javax.crypto.spec.PBEParameterSpec; public abstract class CMSPBEKey implements PBEKey { private char[] password; private byte[] salt; private int iterationCount; protected static PBEParameterSpec getParamSpec(AlgorithmParameters algParams) throws InvalidAlgorithmParameterException { try { return (PBEParameterSpec)algParams.getParameterSpec(PBEParameterSpec.class); } catch (InvalidParameterSpecException e) { throw new InvalidAlgorithmParameterException("cannot process PBE spec: " + e.getMessage()); } } public CMSPBEKey(char[] password, byte[] salt, int iterationCount) { this.password = password; this.salt = salt; this.iterationCount = iterationCount; } public CMSPBEKey(char[] password, PBEParameterSpec pbeSpec) { this(password, pbeSpec.getSalt(), pbeSpec.getIterationCount()); } public char[] getPassword() { return password; } public byte[] getSalt() { return salt; } public int getIterationCount() { return iterationCount; } public String getAlgorithm() { return "PKCS5S2"; } public String getFormat() { return "RAW"; } public byte[] getEncoded() { return null; } abstract byte[] getEncoded(String algorithmOid); } bouncycastle-1.49.orig/src/org/bouncycastle/cms/CMSSignatureAlgorithmNameGenerator.java0000644000175000017500000000102211562115575030755 0ustar ebourgebourgpackage org.bouncycastle.cms; import org.bouncycastle.asn1.x509.AlgorithmIdentifier; public interface CMSSignatureAlgorithmNameGenerator { /** * Return the digest algorithm using one of the standard string * representations rather than the algorithm object identifier (if possible). * * @param digestAlg the digest algorithm id. * @param encryptionAlg the encryption, or signing, algorithm id. */ String getSignatureName(AlgorithmIdentifier digestAlg, AlgorithmIdentifier encryptionAlg); } bouncycastle-1.49.orig/src/org/bouncycastle/cms/CMSEnvelopedDataGenerator.java0000644000175000017500000002036111727534714027071 0ustar ebourgebourgpackage org.bouncycastle.cms; import java.io.ByteArrayOutputStream; import java.io.IOException; import java.io.OutputStream; import java.security.NoSuchAlgorithmException; import java.security.NoSuchProviderException; import java.security.Provider; import java.security.SecureRandom; import java.util.HashMap; import java.util.Iterator; import javax.crypto.KeyGenerator; import org.bouncycastle.asn1.ASN1EncodableVector; import org.bouncycastle.asn1.ASN1ObjectIdentifier; import org.bouncycastle.asn1.ASN1OctetString; import org.bouncycastle.asn1.ASN1Set; import org.bouncycastle.asn1.BEROctetString; import org.bouncycastle.asn1.BERSet; import org.bouncycastle.asn1.DERSet; import org.bouncycastle.asn1.cms.AttributeTable; import org.bouncycastle.asn1.cms.CMSObjectIdentifiers; import org.bouncycastle.asn1.cms.ContentInfo; import org.bouncycastle.asn1.cms.EncryptedContentInfo; import org.bouncycastle.asn1.cms.EnvelopedData; import org.bouncycastle.asn1.x509.AlgorithmIdentifier; import org.bouncycastle.cms.jcajce.JceCMSContentEncryptorBuilder; import org.bouncycastle.operator.GenericKey; import org.bouncycastle.operator.OutputEncryptor; /** * General class for generating a CMS enveloped-data message. * * A simple example of usage. * *
     *       CMSTypedData msg     = new CMSProcessableByteArray("Hello World!".getBytes());
     *
     *       CMSEnvelopedDataGenerator edGen = new CMSEnvelopedDataGenerator();
     *
     *       edGen.addRecipientInfoGenerator(new JceKeyTransRecipientInfoGenerator(recipientCert).setProvider("BC"));
     *
     *       CMSEnvelopedData ed = edGen.generate(
     *                                       msg,
     *                                       new JceCMSContentEncryptorBuilder(CMSAlgorithm.DES_EDE3_CBC)
     *                                              .setProvider("BC").build());
     *
     * 
    */ public class CMSEnvelopedDataGenerator extends CMSEnvelopedGenerator { /** * base constructor */ public CMSEnvelopedDataGenerator() { } /** * constructor allowing specific source of randomness * @param rand instance of SecureRandom to use * @deprecated use no args constructor. */ public CMSEnvelopedDataGenerator( SecureRandom rand) { super(rand); } /** * generate an enveloped object that contains an CMS Enveloped Data * object using the given provider and the passed in key generator. */ private CMSEnvelopedData generate( final CMSProcessable content, String encryptionOID, int keySize, Provider encProvider, Provider provider) throws NoSuchAlgorithmException, CMSException { convertOldRecipients(rand, provider); JceCMSContentEncryptorBuilder builder; if (keySize != -1) { builder = new JceCMSContentEncryptorBuilder(new ASN1ObjectIdentifier(encryptionOID), keySize); } else { builder = new JceCMSContentEncryptorBuilder(new ASN1ObjectIdentifier(encryptionOID)); } builder.setProvider(encProvider); builder.setSecureRandom(rand); return doGenerate(new CMSTypedData() { public ASN1ObjectIdentifier getContentType() { return CMSObjectIdentifiers.data; } public void write(OutputStream out) throws IOException, CMSException { content.write(out); } public Object getContent() { return content; } }, builder.build()); } private CMSEnvelopedData doGenerate( CMSTypedData content, OutputEncryptor contentEncryptor) throws CMSException { if (!oldRecipientInfoGenerators.isEmpty()) { throw new IllegalStateException("can only use addRecipientGenerator() with this method"); } ASN1EncodableVector recipientInfos = new ASN1EncodableVector(); AlgorithmIdentifier encAlgId; ASN1OctetString encContent; ByteArrayOutputStream bOut = new ByteArrayOutputStream(); try { OutputStream cOut = contentEncryptor.getOutputStream(bOut); content.write(cOut); cOut.close(); } catch (IOException e) { throw new CMSException(""); } byte[] encryptedContent = bOut.toByteArray(); encAlgId = contentEncryptor.getAlgorithmIdentifier(); encContent = new BEROctetString(encryptedContent); GenericKey encKey = contentEncryptor.getKey(); for (Iterator it = recipientInfoGenerators.iterator(); it.hasNext();) { RecipientInfoGenerator recipient = (RecipientInfoGenerator)it.next(); recipientInfos.add(recipient.generate(encKey)); } EncryptedContentInfo eci = new EncryptedContentInfo( content.getContentType(), encAlgId, encContent); ASN1Set unprotectedAttrSet = null; if (unprotectedAttributeGenerator != null) { AttributeTable attrTable = unprotectedAttributeGenerator.getAttributes(new HashMap()); unprotectedAttrSet = new BERSet(attrTable.toASN1EncodableVector()); } ContentInfo contentInfo = new ContentInfo( CMSObjectIdentifiers.envelopedData, new EnvelopedData(originatorInfo, new DERSet(recipientInfos), eci, unprotectedAttrSet)); return new CMSEnvelopedData(contentInfo); } /** * generate an enveloped object that contains an CMS Enveloped Data * object using the given provider. * @deprecated use OutputEncryptor method. */ public CMSEnvelopedData generate( CMSProcessable content, String encryptionOID, String provider) throws NoSuchAlgorithmException, NoSuchProviderException, CMSException { return generate(content, encryptionOID, CMSUtils.getProvider(provider)); } /** * generate an enveloped object that contains an CMS Enveloped Data * object using the given provider. * @deprecated use OutputEncryptor method. */ public CMSEnvelopedData generate( CMSProcessable content, String encryptionOID, Provider provider) throws NoSuchAlgorithmException, CMSException { KeyGenerator keyGen = CMSEnvelopedHelper.INSTANCE.createSymmetricKeyGenerator(encryptionOID, provider); return generate(content, encryptionOID, -1, keyGen.getProvider(), provider); } /** * generate an enveloped object that contains an CMS Enveloped Data * object using the given provider. * @deprecated use OutputEncryptor method. */ public CMSEnvelopedData generate( CMSProcessable content, String encryptionOID, int keySize, String provider) throws NoSuchAlgorithmException, NoSuchProviderException, CMSException { return generate(content, encryptionOID, keySize, CMSUtils.getProvider(provider)); } /** * generate an enveloped object that contains an CMS Enveloped Data * object using the given provider. * @deprecated use OutputEncryptor method. */ public CMSEnvelopedData generate( CMSProcessable content, String encryptionOID, int keySize, Provider provider) throws NoSuchAlgorithmException, NoSuchProviderException, CMSException { KeyGenerator keyGen = CMSEnvelopedHelper.INSTANCE.createSymmetricKeyGenerator(encryptionOID, provider); return generate(content, encryptionOID, keySize, keyGen.getProvider(), provider); } /** * generate an enveloped object that contains an CMS Enveloped Data * object using the given provider. * * @param content the content to be encrypted * @param contentEncryptor the symmetric key based encryptor to encrypt the content with. */ public CMSEnvelopedData generate( CMSTypedData content, OutputEncryptor contentEncryptor) throws CMSException { return doGenerate(content, contentEncryptor); } } bouncycastle-1.49.orig/src/org/bouncycastle/cms/RecipientInfoGenerator.java0000644000175000017500000000040211436576461026545 0ustar ebourgebourgpackage org.bouncycastle.cms; import org.bouncycastle.asn1.cms.RecipientInfo; import org.bouncycastle.operator.GenericKey; public interface RecipientInfoGenerator { RecipientInfo generate(GenericKey contentEncryptionKey) throws CMSException; } bouncycastle-1.49.orig/src/org/bouncycastle/cms/jcajce/0000755000175000017500000000000012152033551022500 5ustar ebourgebourgbouncycastle-1.49.orig/src/org/bouncycastle/cms/jcajce/JceKEKRecipient.java0000644000175000017500000000553411723553745026270 0ustar ebourgebourgpackage org.bouncycastle.cms.jcajce; import java.security.Key; import java.security.Provider; import javax.crypto.SecretKey; import org.bouncycastle.asn1.x509.AlgorithmIdentifier; import org.bouncycastle.cms.CMSException; import org.bouncycastle.cms.KEKRecipient; import org.bouncycastle.operator.OperatorException; import org.bouncycastle.operator.SymmetricKeyUnwrapper; public abstract class JceKEKRecipient implements KEKRecipient { private SecretKey recipientKey; protected EnvelopedDataHelper helper = new EnvelopedDataHelper(new DefaultJcaJceExtHelper()); protected EnvelopedDataHelper contentHelper = helper; public JceKEKRecipient(SecretKey recipientKey) { this.recipientKey = recipientKey; } /** * Set the provider to use for key recovery and content processing. * * @param provider provider to use. * @return this recipient. */ public JceKEKRecipient setProvider(Provider provider) { this.helper = new EnvelopedDataHelper(new ProviderJcaJceExtHelper(provider)); this.contentHelper = helper; return this; } /** * Set the provider to use for key recovery and content processing. * * @param providerName the name of the provider to use. * @return this recipient. */ public JceKEKRecipient setProvider(String providerName) { this.helper = new EnvelopedDataHelper(new NamedJcaJceExtHelper(providerName)); this.contentHelper = helper; return this; } /** * Set the provider to use for content processing. * * @param provider the provider to use. * @return this recipient. */ public JceKEKRecipient setContentProvider(Provider provider) { this.contentHelper = new EnvelopedDataHelper(new ProviderJcaJceExtHelper(provider)); return this; } /** * Set the provider to use for content processing. * * @param providerName the name of the provider to use. * @return this recipient. */ public JceKEKRecipient setContentProvider(String providerName) { this.contentHelper = new EnvelopedDataHelper(new NamedJcaJceExtHelper(providerName)); return this; } protected Key extractSecretKey(AlgorithmIdentifier keyEncryptionAlgorithm, AlgorithmIdentifier contentEncryptionAlgorithm, byte[] encryptedContentEncryptionKey) throws CMSException { SymmetricKeyUnwrapper unwrapper = helper.createSymmetricUnwrapper(keyEncryptionAlgorithm, recipientKey); try { return helper.getJceKey(contentEncryptionAlgorithm.getAlgorithm(), unwrapper.generateUnwrappedKey(contentEncryptionAlgorithm, encryptedContentEncryptionKey)); } catch (OperatorException e) { throw new CMSException("exception unwrapping key: " + e.getMessage(), e); } } } bouncycastle-1.49.orig/src/org/bouncycastle/cms/jcajce/JceKeyTransRecipient.java0000644000175000017500000001044611723553745027414 0ustar ebourgebourgpackage org.bouncycastle.cms.jcajce; import java.security.Key; import java.security.PrivateKey; import java.security.Provider; import java.util.HashMap; import java.util.Iterator; import java.util.Map; import org.bouncycastle.asn1.ASN1ObjectIdentifier; import org.bouncycastle.asn1.x509.AlgorithmIdentifier; import org.bouncycastle.cms.CMSException; import org.bouncycastle.cms.KeyTransRecipient; import org.bouncycastle.operator.OperatorException; import org.bouncycastle.operator.jcajce.JceAsymmetricKeyUnwrapper; public abstract class JceKeyTransRecipient implements KeyTransRecipient { private PrivateKey recipientKey; protected EnvelopedDataHelper helper = new EnvelopedDataHelper(new DefaultJcaJceExtHelper()); protected EnvelopedDataHelper contentHelper = helper; protected Map extraMappings = new HashMap(); public JceKeyTransRecipient(PrivateKey recipientKey) { this.recipientKey = recipientKey; } /** * Set the provider to use for key recovery and content processing. * * @param provider provider to use. * @return this recipient. */ public JceKeyTransRecipient setProvider(Provider provider) { this.helper = new EnvelopedDataHelper(new ProviderJcaJceExtHelper(provider)); this.contentHelper = helper; return this; } /** * Set the provider to use for key recovery and content processing. * * @param providerName the name of the provider to use. * @return this recipient. */ public JceKeyTransRecipient setProvider(String providerName) { this.helper = new EnvelopedDataHelper(new NamedJcaJceExtHelper(providerName)); this.contentHelper = helper; return this; } /** * Internally algorithm ids are converted into cipher names using a lookup table. For some providers * the standard lookup table won't work. Use this method to establish a specific mapping from an * algorithm identifier to a specific algorithm. *

    * For example: *

         *     unwrapper.setAlgorithmMapping(PKCSObjectIdentifiers.rsaEncryption, "RSA");
         * 
    *

    * @param algorithm OID of algorithm in recipient. * @param algorithmName JCE algorithm name to use. * @return the current Recipient. */ public JceKeyTransRecipient setAlgorithmMapping(ASN1ObjectIdentifier algorithm, String algorithmName) { extraMappings.put(algorithm, algorithmName); return this; } /** * Set the provider to use for content processing. If providerName is null a "no provider" search will be * used to satisfy getInstance calls. * * @param provider the provider to use. * @return this recipient. */ public JceKeyTransRecipient setContentProvider(Provider provider) { this.contentHelper = CMSUtils.createContentHelper(provider); return this; } /** * Set the provider to use for content processing. If providerName is null a "no provider" search will be * used to satisfy getInstance calls. * * @param providerName the name of the provider to use. * @return this recipient. */ public JceKeyTransRecipient setContentProvider(String providerName) { this.contentHelper = CMSUtils.createContentHelper(providerName); return this; } protected Key extractSecretKey(AlgorithmIdentifier keyEncryptionAlgorithm, AlgorithmIdentifier encryptedKeyAlgorithm, byte[] encryptedEncryptionKey) throws CMSException { JceAsymmetricKeyUnwrapper unwrapper = helper.createAsymmetricUnwrapper(keyEncryptionAlgorithm, recipientKey); if (!extraMappings.isEmpty()) { for (Iterator it = extraMappings.keySet().iterator(); it.hasNext();) { ASN1ObjectIdentifier algorithm = (ASN1ObjectIdentifier)it.next(); unwrapper.setAlgorithmMapping(algorithm, (String)extraMappings.get(algorithm)); } } try { return helper.getJceKey(encryptedKeyAlgorithm.getAlgorithm(), unwrapper.generateUnwrappedKey(encryptedKeyAlgorithm, encryptedEncryptionKey)); } catch (OperatorException e) { throw new CMSException("exception unwrapping key: " + e.getMessage(), e); } } } bouncycastle-1.49.orig/src/org/bouncycastle/cms/jcajce/JcaSignerInfoVerifierBuilder.java0000644000175000017500000001470011564655621031047 0ustar ebourgebourgpackage org.bouncycastle.cms.jcajce; import java.security.Provider; import java.security.PublicKey; import java.security.cert.CertificateException; import java.security.cert.X509Certificate; import org.bouncycastle.cert.X509CertificateHolder; import org.bouncycastle.cms.CMSSignatureAlgorithmNameGenerator; import org.bouncycastle.cms.DefaultCMSSignatureAlgorithmNameGenerator; import org.bouncycastle.cms.SignerInformationVerifier; import org.bouncycastle.operator.ContentVerifierProvider; import org.bouncycastle.operator.DefaultSignatureAlgorithmIdentifierFinder; import org.bouncycastle.operator.DigestCalculatorProvider; import org.bouncycastle.operator.OperatorCreationException; import org.bouncycastle.operator.SignatureAlgorithmIdentifierFinder; import org.bouncycastle.operator.jcajce.JcaContentVerifierProviderBuilder; import org.bouncycastle.operator.jcajce.JcaDigestCalculatorProviderBuilder; public class JcaSignerInfoVerifierBuilder { private Helper helper = new Helper(); private DigestCalculatorProvider digestProvider; private CMSSignatureAlgorithmNameGenerator sigAlgNameGen = new DefaultCMSSignatureAlgorithmNameGenerator(); private SignatureAlgorithmIdentifierFinder sigAlgIDFinder = new DefaultSignatureAlgorithmIdentifierFinder(); public JcaSignerInfoVerifierBuilder(DigestCalculatorProvider digestProvider) { this.digestProvider = digestProvider; } public JcaSignerInfoVerifierBuilder setProvider(Provider provider) { this.helper = new ProviderHelper(provider); return this; } public JcaSignerInfoVerifierBuilder setProvider(String providerName) { this.helper = new NamedHelper(providerName); return this; } /** * Override the default signature algorithm name generator. * * @param sigAlgNameGen the algorithm name generator to use. * @return the current builder. */ public JcaSignerInfoVerifierBuilder setSignatureAlgorithmNameGenerator(CMSSignatureAlgorithmNameGenerator sigAlgNameGen) { this.sigAlgNameGen = sigAlgNameGen; return this; } public JcaSignerInfoVerifierBuilder setSignatureAlgorithmFinder(SignatureAlgorithmIdentifierFinder sigAlgIDFinder) { this.sigAlgIDFinder = sigAlgIDFinder; return this; } public SignerInformationVerifier build(X509CertificateHolder certHolder) throws OperatorCreationException, CertificateException { return new SignerInformationVerifier(sigAlgNameGen, sigAlgIDFinder, helper.createContentVerifierProvider(certHolder), digestProvider); } public SignerInformationVerifier build(X509Certificate certificate) throws OperatorCreationException { return new SignerInformationVerifier(sigAlgNameGen, sigAlgIDFinder, helper.createContentVerifierProvider(certificate), digestProvider); } public SignerInformationVerifier build(PublicKey pubKey) throws OperatorCreationException { return new SignerInformationVerifier(sigAlgNameGen, sigAlgIDFinder, helper.createContentVerifierProvider(pubKey), digestProvider); } private class Helper { ContentVerifierProvider createContentVerifierProvider(PublicKey publicKey) throws OperatorCreationException { return new JcaContentVerifierProviderBuilder().build(publicKey); } ContentVerifierProvider createContentVerifierProvider(X509Certificate certificate) throws OperatorCreationException { return new JcaContentVerifierProviderBuilder().build(certificate); } ContentVerifierProvider createContentVerifierProvider(X509CertificateHolder certHolder) throws OperatorCreationException, CertificateException { return new JcaContentVerifierProviderBuilder().build(certHolder); } DigestCalculatorProvider createDigestCalculatorProvider() throws OperatorCreationException { return new JcaDigestCalculatorProviderBuilder().build(); } } private class NamedHelper extends Helper { private final String providerName; public NamedHelper(String providerName) { this.providerName = providerName; } ContentVerifierProvider createContentVerifierProvider(PublicKey publicKey) throws OperatorCreationException { return new JcaContentVerifierProviderBuilder().setProvider(providerName).build(publicKey); } ContentVerifierProvider createContentVerifierProvider(X509Certificate certificate) throws OperatorCreationException { return new JcaContentVerifierProviderBuilder().setProvider(providerName).build(certificate); } DigestCalculatorProvider createDigestCalculatorProvider() throws OperatorCreationException { return new JcaDigestCalculatorProviderBuilder().setProvider(providerName).build(); } ContentVerifierProvider createContentVerifierProvider(X509CertificateHolder certHolder) throws OperatorCreationException, CertificateException { return new JcaContentVerifierProviderBuilder().setProvider(providerName).build(certHolder); } } private class ProviderHelper extends Helper { private final Provider provider; public ProviderHelper(Provider provider) { this.provider = provider; } ContentVerifierProvider createContentVerifierProvider(PublicKey publicKey) throws OperatorCreationException { return new JcaContentVerifierProviderBuilder().setProvider(provider).build(publicKey); } ContentVerifierProvider createContentVerifierProvider(X509Certificate certificate) throws OperatorCreationException { return new JcaContentVerifierProviderBuilder().setProvider(provider).build(certificate); } DigestCalculatorProvider createDigestCalculatorProvider() throws OperatorCreationException { return new JcaDigestCalculatorProviderBuilder().setProvider(provider).build(); } ContentVerifierProvider createContentVerifierProvider(X509CertificateHolder certHolder) throws OperatorCreationException, CertificateException { return new JcaContentVerifierProviderBuilder().setProvider(provider).build(certHolder); } } } bouncycastle-1.49.orig/src/org/bouncycastle/cms/jcajce/JceKeyTransAuthenticatedRecipient.java0000644000175000017500000000344511507246212032104 0ustar ebourgebourgpackage org.bouncycastle.cms.jcajce; import java.io.OutputStream; import java.security.Key; import java.security.PrivateKey; import javax.crypto.Mac; import org.bouncycastle.asn1.x509.AlgorithmIdentifier; import org.bouncycastle.cms.CMSException; import org.bouncycastle.cms.RecipientOperator; import org.bouncycastle.jcajce.io.MacOutputStream; import org.bouncycastle.operator.GenericKey; import org.bouncycastle.operator.MacCalculator; /** * the KeyTransRecipientInformation class for a recipient who has been sent a secret * key encrypted using their public key that needs to be used to * extract the message. */ public class JceKeyTransAuthenticatedRecipient extends JceKeyTransRecipient { public JceKeyTransAuthenticatedRecipient(PrivateKey recipientKey) { super(recipientKey); } public RecipientOperator getRecipientOperator(AlgorithmIdentifier keyEncryptionAlgorithm, final AlgorithmIdentifier contentMacAlgorithm, byte[] encryptedContentEncryptionKey) throws CMSException { final Key secretKey = extractSecretKey(keyEncryptionAlgorithm, contentMacAlgorithm, encryptedContentEncryptionKey); final Mac dataMac = contentHelper.createContentMac(secretKey, contentMacAlgorithm); return new RecipientOperator(new MacCalculator() { public AlgorithmIdentifier getAlgorithmIdentifier() { return contentMacAlgorithm; } public GenericKey getKey() { return new GenericKey(secretKey); } public OutputStream getOutputStream() { return new MacOutputStream(dataMac); } public byte[] getMac() { return dataMac.doFinal(); } }); } } bouncycastle-1.49.orig/src/org/bouncycastle/cms/jcajce/JcaSignerId.java0000644000175000017500000000335211726255132025477 0ustar ebourgebourgpackage org.bouncycastle.cms.jcajce; import java.math.BigInteger; import java.security.cert.X509Certificate; import javax.security.auth.x500.X500Principal; import org.bouncycastle.asn1.x500.X500Name; import org.bouncycastle.cms.SignerId; public class JcaSignerId extends SignerId { /** * Construct a signer identifier based on the issuer, serial number and subject key identifier (if present) of the passed in * certificate. * * @param certificate certificate providing the issue and serial number and subject key identifier. */ public JcaSignerId(X509Certificate certificate) { super(convertPrincipal(certificate.getIssuerX500Principal()), certificate.getSerialNumber(), CMSUtils.getSubjectKeyId(certificate)); } /** * Construct a signer identifier based on the provided issuer and serial number.. * * @param issuer the issuer to use. * @param serialNumber the serial number to use. */ public JcaSignerId(X500Principal issuer, BigInteger serialNumber) { super(convertPrincipal(issuer), serialNumber); } /** * Construct a signer identifier based on the provided issuer, serial number, and subjectKeyId.. * * @param issuer the issuer to use. * @param serialNumber the serial number to use. * @param subjectKeyId the subject key ID to use. */ public JcaSignerId(X500Principal issuer, BigInteger serialNumber, byte[] subjectKeyId) { super(convertPrincipal(issuer), serialNumber, subjectKeyId); } private static X500Name convertPrincipal(X500Principal issuer) { if (issuer == null) { return null; } return X500Name.getInstance(issuer.getEncoded()); } } bouncycastle-1.49.orig/src/org/bouncycastle/cms/jcajce/JcaX509CertSelectorConverter.java0000644000175000017500000000136311726254712030652 0ustar ebourgebourgpackage org.bouncycastle.cms.jcajce; import java.security.cert.X509CertSelector; import org.bouncycastle.cms.KeyTransRecipientId; import org.bouncycastle.cms.SignerId; public class JcaX509CertSelectorConverter extends org.bouncycastle.cert.selector.jcajce.JcaX509CertSelectorConverter { public JcaX509CertSelectorConverter() { } public X509CertSelector getCertSelector(KeyTransRecipientId recipientId) { return doConversion(recipientId.getIssuer(), recipientId.getSerialNumber(), recipientId.getSubjectKeyIdentifier()); } public X509CertSelector getCertSelector(SignerId signerId) { return doConversion(signerId.getIssuer(), signerId.getSerialNumber(), signerId.getSubjectKeyIdentifier()); } } bouncycastle-1.49.orig/src/org/bouncycastle/cms/jcajce/JceKeyAgreeRecipientInfoGenerator.java0000644000175000017500000002004311723553745032025 0ustar ebourgebourgpackage org.bouncycastle.cms.jcajce; import java.security.GeneralSecurityException; import java.security.InvalidAlgorithmParameterException; import java.security.KeyPair; import java.security.KeyPairGenerator; import java.security.PrivateKey; import java.security.Provider; import java.security.PublicKey; import java.security.SecureRandom; import java.security.cert.CertificateEncodingException; import java.security.cert.X509Certificate; import java.security.interfaces.ECPublicKey; import java.security.spec.ECParameterSpec; import java.util.ArrayList; import java.util.List; import javax.crypto.Cipher; import javax.crypto.KeyAgreement; import javax.crypto.SecretKey; import org.bouncycastle.asn1.ASN1Encodable; import org.bouncycastle.asn1.ASN1EncodableVector; import org.bouncycastle.asn1.ASN1ObjectIdentifier; import org.bouncycastle.asn1.ASN1OctetString; import org.bouncycastle.asn1.ASN1Sequence; import org.bouncycastle.asn1.DEROctetString; import org.bouncycastle.asn1.DERSequence; import org.bouncycastle.asn1.cms.KeyAgreeRecipientIdentifier; import org.bouncycastle.asn1.cms.RecipientEncryptedKey; import org.bouncycastle.asn1.cms.RecipientKeyIdentifier; import org.bouncycastle.asn1.cms.ecc.MQVuserKeyingMaterial; import org.bouncycastle.asn1.x509.AlgorithmIdentifier; import org.bouncycastle.asn1.x509.SubjectPublicKeyInfo; import org.bouncycastle.cms.CMSAlgorithm; import org.bouncycastle.cms.CMSEnvelopedGenerator; import org.bouncycastle.cms.CMSException; import org.bouncycastle.cms.KeyAgreeRecipientInfoGenerator; import org.bouncycastle.jce.spec.MQVPrivateKeySpec; import org.bouncycastle.jce.spec.MQVPublicKeySpec; import org.bouncycastle.operator.GenericKey; public class JceKeyAgreeRecipientInfoGenerator extends KeyAgreeRecipientInfoGenerator { private List recipientIDs = new ArrayList(); private List recipientKeys = new ArrayList(); private PublicKey senderPublicKey; private PrivateKey senderPrivateKey; private EnvelopedDataHelper helper = new EnvelopedDataHelper(new DefaultJcaJceExtHelper()); private SecureRandom random; private KeyPair ephemeralKP; public JceKeyAgreeRecipientInfoGenerator(ASN1ObjectIdentifier keyAgreementOID, PrivateKey senderPrivateKey, PublicKey senderPublicKey, ASN1ObjectIdentifier keyEncryptionOID) { super(keyAgreementOID, SubjectPublicKeyInfo.getInstance(senderPublicKey.getEncoded()), keyEncryptionOID); this.senderPublicKey = senderPublicKey; this.senderPrivateKey = senderPrivateKey; } public JceKeyAgreeRecipientInfoGenerator setProvider(Provider provider) { this.helper = new EnvelopedDataHelper(new ProviderJcaJceExtHelper(provider)); return this; } public JceKeyAgreeRecipientInfoGenerator setProvider(String providerName) { this.helper = new EnvelopedDataHelper(new NamedJcaJceExtHelper(providerName)); return this; } public JceKeyAgreeRecipientInfoGenerator setSecureRandom(SecureRandom random) { this.random = random; return this; } /** * Add a recipient based on the passed in certificate's public key and its issuer and serial number. * * @param recipientCert recipient's certificate * @return the current instance. * @throws CertificateEncodingException if the necessary data cannot be extracted from the certificate. */ public JceKeyAgreeRecipientInfoGenerator addRecipient(X509Certificate recipientCert) throws CertificateEncodingException { recipientIDs.add(new KeyAgreeRecipientIdentifier(CMSUtils.getIssuerAndSerialNumber(recipientCert))); recipientKeys.add(recipientCert.getPublicKey()); return this; } /** * Add a recipient identified by the passed in subjectKeyID and the for the passed in public key. * * @param subjectKeyID identifier actual recipient will use to match the private key. * @param publicKey the public key for encrypting the secret key. * @return the current instance. * @throws CertificateEncodingException */ public JceKeyAgreeRecipientInfoGenerator addRecipient(byte[] subjectKeyID, PublicKey publicKey) throws CertificateEncodingException { recipientIDs.add(new KeyAgreeRecipientIdentifier(new RecipientKeyIdentifier(subjectKeyID))); recipientKeys.add(publicKey); return this; } public ASN1Sequence generateRecipientEncryptedKeys(AlgorithmIdentifier keyAgreeAlgorithm, AlgorithmIdentifier keyEncryptionAlgorithm, GenericKey contentEncryptionKey) throws CMSException { init(keyAgreeAlgorithm.getAlgorithm()); PrivateKey senderPrivateKey = this.senderPrivateKey; ASN1ObjectIdentifier keyAgreementOID = keyAgreeAlgorithm.getAlgorithm(); if (keyAgreementOID.getId().equals(CMSEnvelopedGenerator.ECMQV_SHA1KDF)) { senderPrivateKey = new MQVPrivateKeySpec( senderPrivateKey, ephemeralKP.getPrivate(), ephemeralKP.getPublic()); } ASN1EncodableVector recipientEncryptedKeys = new ASN1EncodableVector(); for (int i = 0; i != recipientIDs.size(); i++) { PublicKey recipientPublicKey = (PublicKey)recipientKeys.get(i); KeyAgreeRecipientIdentifier karId = (KeyAgreeRecipientIdentifier)recipientIDs.get(i); if (keyAgreementOID.getId().equals(CMSEnvelopedGenerator.ECMQV_SHA1KDF)) { recipientPublicKey = new MQVPublicKeySpec(recipientPublicKey, recipientPublicKey); } try { // Use key agreement to choose a wrap key for this recipient KeyAgreement keyAgreement = helper.createKeyAgreement(keyAgreementOID); keyAgreement.init(senderPrivateKey, random); keyAgreement.doPhase(recipientPublicKey, true); SecretKey keyEncryptionKey = keyAgreement.generateSecret(keyEncryptionAlgorithm.getAlgorithm().getId()); // Wrap the content encryption key with the agreement key Cipher keyEncryptionCipher = helper.createCipher(keyEncryptionAlgorithm.getAlgorithm()); keyEncryptionCipher.init(Cipher.WRAP_MODE, keyEncryptionKey, random); byte[] encryptedKeyBytes = keyEncryptionCipher.wrap(helper.getJceKey(contentEncryptionKey)); ASN1OctetString encryptedKey = new DEROctetString(encryptedKeyBytes); recipientEncryptedKeys.add(new RecipientEncryptedKey(karId, encryptedKey)); } catch (GeneralSecurityException e) { throw new CMSException("cannot perform agreement step: " + e.getMessage(), e); } } return new DERSequence(recipientEncryptedKeys); } protected ASN1Encodable getUserKeyingMaterial(AlgorithmIdentifier keyAgreeAlg) throws CMSException { init(keyAgreeAlg.getAlgorithm()); if (ephemeralKP != null) { return new MQVuserKeyingMaterial( createOriginatorPublicKey(SubjectPublicKeyInfo.getInstance(ephemeralKP.getPublic().getEncoded())), null); } return null; } private void init(ASN1ObjectIdentifier keyAgreementOID) throws CMSException { if (random == null) { random = new SecureRandom(); } if (keyAgreementOID.equals(CMSAlgorithm.ECMQV_SHA1KDF)) { if (ephemeralKP == null) { try { ECParameterSpec ecParamSpec = ((ECPublicKey)senderPublicKey).getParams(); KeyPairGenerator ephemKPG = helper.createKeyPairGenerator(keyAgreementOID); ephemKPG.initialize(ecParamSpec, random); ephemeralKP = ephemKPG.generateKeyPair(); } catch (InvalidAlgorithmParameterException e) { throw new CMSException( "cannot determine MQV ephemeral key pair parameters from public key: " + e); } } } } }bouncycastle-1.49.orig/src/org/bouncycastle/cms/jcajce/JceKeyAgreeAuthenticatedRecipient.java0000644000175000017500000000357611737175743032064 0ustar ebourgebourgpackage org.bouncycastle.cms.jcajce; import java.io.OutputStream; import java.security.Key; import java.security.PrivateKey; import javax.crypto.Mac; import org.bouncycastle.asn1.ASN1OctetString; import org.bouncycastle.asn1.x509.AlgorithmIdentifier; import org.bouncycastle.asn1.x509.SubjectPublicKeyInfo; import org.bouncycastle.cms.CMSException; import org.bouncycastle.cms.RecipientOperator; import org.bouncycastle.jcajce.io.MacOutputStream; import org.bouncycastle.operator.GenericKey; import org.bouncycastle.operator.MacCalculator; import org.bouncycastle.operator.jcajce.JceGenericKey; public class JceKeyAgreeAuthenticatedRecipient extends JceKeyAgreeRecipient { public JceKeyAgreeAuthenticatedRecipient(PrivateKey recipientKey) { super(recipientKey); } public RecipientOperator getRecipientOperator(AlgorithmIdentifier keyEncryptionAlgorithm, final AlgorithmIdentifier contentMacAlgorithm, SubjectPublicKeyInfo senderPublicKey, ASN1OctetString userKeyingMaterial, byte[] encryptedContentKey) throws CMSException { final Key secretKey = extractSecretKey(keyEncryptionAlgorithm, contentMacAlgorithm, senderPublicKey, userKeyingMaterial, encryptedContentKey); final Mac dataMac = contentHelper.createContentMac(secretKey, contentMacAlgorithm); return new RecipientOperator(new MacCalculator() { public AlgorithmIdentifier getAlgorithmIdentifier() { return contentMacAlgorithm; } public GenericKey getKey() { return new JceGenericKey(contentMacAlgorithm, secretKey); } public OutputStream getOutputStream() { return new MacOutputStream(dataMac); } public byte[] getMac() { return dataMac.doFinal(); } }); } } bouncycastle-1.49.orig/src/org/bouncycastle/cms/jcajce/JceKeyTransRecipientId.java0000644000175000017500000000343611726255654027673 0ustar ebourgebourgpackage org.bouncycastle.cms.jcajce; import java.math.BigInteger; import java.security.cert.X509Certificate; import javax.security.auth.x500.X500Principal; import org.bouncycastle.asn1.x500.X500Name; import org.bouncycastle.cms.KeyTransRecipientId; public class JceKeyTransRecipientId extends KeyTransRecipientId { /** * Construct a recipient id based on the issuer, serial number and subject key identifier (if present) of the passed in * certificate. * * @param certificate certificate providing the issue and serial number and subject key identifier. */ public JceKeyTransRecipientId(X509Certificate certificate) { super(convertPrincipal(certificate.getIssuerX500Principal()), certificate.getSerialNumber(), CMSUtils.getSubjectKeyId(certificate)); } /** * Construct a recipient id based on the provided issuer and serial number.. * * @param issuer the issuer to use. * @param serialNumber the serial number to use. */ public JceKeyTransRecipientId(X500Principal issuer, BigInteger serialNumber) { super(convertPrincipal(issuer), serialNumber); } /** * Construct a recipient id based on the provided issuer, serial number, and subjectKeyId.. * * @param issuer the issuer to use. * @param serialNumber the serial number to use. * @param subjectKeyId the subject key ID to use. */ public JceKeyTransRecipientId(X500Principal issuer, BigInteger serialNumber, byte[] subjectKeyId) { super(convertPrincipal(issuer), serialNumber, subjectKeyId); } private static X500Name convertPrincipal(X500Principal issuer) { if (issuer == null) { return null; } return X500Name.getInstance(issuer.getEncoded()); } } bouncycastle-1.49.orig/src/org/bouncycastle/cms/jcajce/JceCMSContentEncryptorBuilder.java0000644000175000017500000001135012103440746031163 0ustar ebourgebourgpackage org.bouncycastle.cms.jcajce; import java.io.OutputStream; import java.security.AlgorithmParameters; import java.security.GeneralSecurityException; import java.security.Provider; import java.security.SecureRandom; import java.util.HashMap; import java.util.Map; import javax.crypto.Cipher; import javax.crypto.CipherOutputStream; import javax.crypto.KeyGenerator; import javax.crypto.SecretKey; import org.bouncycastle.asn1.ASN1ObjectIdentifier; import org.bouncycastle.asn1.x509.AlgorithmIdentifier; import org.bouncycastle.cms.CMSAlgorithm; import org.bouncycastle.cms.CMSException; import org.bouncycastle.operator.GenericKey; import org.bouncycastle.operator.OutputEncryptor; import org.bouncycastle.operator.jcajce.JceGenericKey; import org.bouncycastle.util.Integers; public class JceCMSContentEncryptorBuilder { private static Map keySizes = new HashMap(); static { keySizes.put(CMSAlgorithm.AES128_CBC, Integers.valueOf(128)); keySizes.put(CMSAlgorithm.AES192_CBC, Integers.valueOf(192)); keySizes.put(CMSAlgorithm.AES256_CBC, Integers.valueOf(256)); keySizes.put(CMSAlgorithm.CAMELLIA128_CBC, Integers.valueOf(128)); keySizes.put(CMSAlgorithm.CAMELLIA192_CBC, Integers.valueOf(192)); keySizes.put(CMSAlgorithm.CAMELLIA256_CBC, Integers.valueOf(256)); } private static int getKeySize(ASN1ObjectIdentifier oid) { Integer size = (Integer)keySizes.get(oid); if (size != null) { return size.intValue(); } return -1; } private final ASN1ObjectIdentifier encryptionOID; private final int keySize; private EnvelopedDataHelper helper = new EnvelopedDataHelper(new DefaultJcaJceExtHelper()); private SecureRandom random; public JceCMSContentEncryptorBuilder(ASN1ObjectIdentifier encryptionOID) { this(encryptionOID, getKeySize(encryptionOID)); } public JceCMSContentEncryptorBuilder(ASN1ObjectIdentifier encryptionOID, int keySize) { this.encryptionOID = encryptionOID; this.keySize = keySize; } public JceCMSContentEncryptorBuilder setProvider(Provider provider) { this.helper = new EnvelopedDataHelper(new ProviderJcaJceExtHelper(provider)); return this; } public JceCMSContentEncryptorBuilder setProvider(String providerName) { this.helper = new EnvelopedDataHelper(new NamedJcaJceExtHelper(providerName)); return this; } public JceCMSContentEncryptorBuilder setSecureRandom(SecureRandom random) { this.random = random; return this; } public OutputEncryptor build() throws CMSException { return new CMSOutputEncryptor(encryptionOID, keySize, random); } private class CMSOutputEncryptor implements OutputEncryptor { private SecretKey encKey; private AlgorithmIdentifier algorithmIdentifier; private Cipher cipher; CMSOutputEncryptor(ASN1ObjectIdentifier encryptionOID, int keySize, SecureRandom random) throws CMSException { KeyGenerator keyGen = helper.createKeyGenerator(encryptionOID); if (random == null) { random = new SecureRandom(); } if (keySize < 0) { keyGen.init(random); } else { keyGen.init(keySize, random); } cipher = helper.createCipher(encryptionOID); encKey = keyGen.generateKey(); AlgorithmParameters params = helper.generateParameters(encryptionOID, encKey, random); try { cipher.init(Cipher.ENCRYPT_MODE, encKey, params, random); } catch (GeneralSecurityException e) { throw new CMSException("unable to initialize cipher: " + e.getMessage(), e); } // // If params are null we try and second guess on them as some providers don't provide // algorithm parameter generation explicity but instead generate them under the hood. // if (params == null) { params = cipher.getParameters(); } algorithmIdentifier = helper.getAlgorithmIdentifier(encryptionOID, params); } public AlgorithmIdentifier getAlgorithmIdentifier() { return algorithmIdentifier; } public OutputStream getOutputStream(OutputStream dOut) { return new CipherOutputStream(dOut, cipher); } public GenericKey getKey() { return new JceGenericKey(algorithmIdentifier, encKey); } } } bouncycastle-1.49.orig/src/org/bouncycastle/cms/jcajce/JceKeyTransEnvelopedRecipient.java0000644000175000017500000000261500000000112031206 0ustar ebourgebourgpackage org.bouncycastle.cms.jcajce; import java.io.InputStream; import java.security.Key; import java.security.PrivateKey; import javax.crypto.Cipher; import javax.crypto.CipherInputStream; import org.bouncycastle.asn1.x509.AlgorithmIdentifier; import org.bouncycastle.cms.CMSException; import org.bouncycastle.cms.RecipientOperator; import org.bouncycastle.operator.InputDecryptor; public class JceKeyTransEnvelopedRecipient extends JceKeyTransRecipient { public JceKeyTransEnvelopedRecipient(PrivateKey recipientKey) { super(recipientKey); } public RecipientOperator getRecipientOperator(AlgorithmIdentifier keyEncryptionAlgorithm, final AlgorithmIdentifier contentEncryptionAlgorithm, byte[] encryptedContentEncryptionKey) throws CMSException { Key secretKey = extractSecretKey(keyEncryptionAlgorithm, contentEncryptionAlgorithm, encryptedContentEncryptionKey); final Cipher dataCipher = contentHelper.createContentCipher(secretKey, contentEncryptionAlgorithm); return new RecipientOperator(new InputDecryptor() { public AlgorithmIdentifier getAlgorithmIdentifier() { return contentEncryptionAlgorithm; } public InputStream getInputStream(InputStream dataIn) { return new CipherInputStream(dataIn, dataCipher); } }); } } bouncycastle-1.49.orig/src/org/bouncycastle/cms/jcajce/DefaultJcaJceExtHelper.java0000644000175000017500000000170311724025607027620 0ustar ebourgebourgpackage org.bouncycastle.cms.jcajce; import java.security.PrivateKey; import javax.crypto.SecretKey; import org.bouncycastle.asn1.x509.AlgorithmIdentifier; import org.bouncycastle.jcajce.DefaultJcaJceHelper; import org.bouncycastle.operator.SymmetricKeyUnwrapper; import org.bouncycastle.operator.jcajce.JceAsymmetricKeyUnwrapper; import org.bouncycastle.operator.jcajce.JceSymmetricKeyUnwrapper; class DefaultJcaJceExtHelper extends DefaultJcaJceHelper implements JcaJceExtHelper { public JceAsymmetricKeyUnwrapper createAsymmetricUnwrapper(AlgorithmIdentifier keyEncryptionAlgorithm, PrivateKey keyEncryptionKey) { return new JceAsymmetricKeyUnwrapper(keyEncryptionAlgorithm, keyEncryptionKey); } public SymmetricKeyUnwrapper createSymmetricUnwrapper(AlgorithmIdentifier keyEncryptionAlgorithm, SecretKey keyEncryptionKey) { return new JceSymmetricKeyUnwrapper(keyEncryptionAlgorithm, keyEncryptionKey); } } bouncycastle-1.49.orig/src/org/bouncycastle/cms/jcajce/CMSUtils.java0000644000175000017500000000372411726257322025026 0ustar ebourgebourgpackage org.bouncycastle.cms.jcajce; import java.security.Provider; import java.security.cert.CertificateEncodingException; import java.security.cert.X509Certificate; import org.bouncycastle.asn1.ASN1OctetString; import org.bouncycastle.asn1.cms.IssuerAndSerialNumber; import org.bouncycastle.asn1.x509.Certificate; import org.bouncycastle.asn1.x509.TBSCertificateStructure; import org.bouncycastle.asn1.x509.X509Extension; class CMSUtils { static TBSCertificateStructure getTBSCertificateStructure( X509Certificate cert) throws CertificateEncodingException { return TBSCertificateStructure.getInstance(cert.getTBSCertificate()); } static IssuerAndSerialNumber getIssuerAndSerialNumber(X509Certificate cert) throws CertificateEncodingException { Certificate certStruct = Certificate.getInstance(cert.getEncoded()); return new IssuerAndSerialNumber(certStruct.getIssuer(), cert.getSerialNumber()); } static byte[] getSubjectKeyId(X509Certificate cert) { byte[] ext = cert.getExtensionValue(X509Extension.subjectKeyIdentifier.getId()); if (ext != null) { return ASN1OctetString.getInstance(ASN1OctetString.getInstance(ext).getOctets()).getOctets(); } else { return null; } } static EnvelopedDataHelper createContentHelper(Provider provider) { if (provider != null) { return new EnvelopedDataHelper(new ProviderJcaJceExtHelper(provider)); } else { return new EnvelopedDataHelper(new DefaultJcaJceExtHelper()); } } static EnvelopedDataHelper createContentHelper(String providerName) { if (providerName != null) { return new EnvelopedDataHelper(new NamedJcaJceExtHelper(providerName)); } else { return new EnvelopedDataHelper(new DefaultJcaJceExtHelper()); } } }bouncycastle-1.49.orig/src/org/bouncycastle/cms/jcajce/EnvelopedDataHelper.java0000644000175000017500000006052312033230714027222 0ustar ebourgebourgpackage org.bouncycastle.cms.jcajce; import java.io.IOException; import java.security.AlgorithmParameterGenerator; import java.security.AlgorithmParameters; import java.security.GeneralSecurityException; import java.security.InvalidAlgorithmParameterException; import java.security.InvalidKeyException; import java.security.Key; import java.security.KeyFactory; import java.security.KeyPairGenerator; import java.security.NoSuchAlgorithmException; import java.security.NoSuchProviderException; import java.security.PrivateKey; import java.security.SecureRandom; import java.security.spec.AlgorithmParameterSpec; import java.security.spec.InvalidParameterSpecException; import java.util.HashMap; import java.util.Map; import javax.crypto.Cipher; import javax.crypto.KeyAgreement; import javax.crypto.KeyGenerator; import javax.crypto.Mac; import javax.crypto.NoSuchPaddingException; import javax.crypto.SecretKey; import javax.crypto.spec.IvParameterSpec; import javax.crypto.spec.RC2ParameterSpec; import javax.crypto.spec.SecretKeySpec; import org.bouncycastle.asn1.ASN1Encodable; import org.bouncycastle.asn1.ASN1Null; import org.bouncycastle.asn1.ASN1ObjectIdentifier; import org.bouncycastle.asn1.ASN1OctetString; import org.bouncycastle.asn1.ASN1Primitive; import org.bouncycastle.asn1.DERNull; import org.bouncycastle.asn1.DEROctetString; import org.bouncycastle.asn1.pkcs.PKCSObjectIdentifiers; import org.bouncycastle.asn1.pkcs.RC2CBCParameter; import org.bouncycastle.asn1.x509.AlgorithmIdentifier; import org.bouncycastle.cms.CMSAlgorithm; import org.bouncycastle.cms.CMSEnvelopedDataGenerator; import org.bouncycastle.cms.CMSException; import org.bouncycastle.operator.GenericKey; import org.bouncycastle.operator.SymmetricKeyUnwrapper; import org.bouncycastle.operator.jcajce.JceAsymmetricKeyUnwrapper; class EnvelopedDataHelper { protected static final Map BASE_CIPHER_NAMES = new HashMap(); protected static final Map CIPHER_ALG_NAMES = new HashMap(); protected static final Map MAC_ALG_NAMES = new HashMap(); static { BASE_CIPHER_NAMES.put(CMSAlgorithm.DES_CBC, "DES"); BASE_CIPHER_NAMES.put(CMSAlgorithm.DES_EDE3_CBC, "DESEDE"); BASE_CIPHER_NAMES.put(CMSAlgorithm.AES128_CBC, "AES"); BASE_CIPHER_NAMES.put(CMSAlgorithm.AES192_CBC, "AES"); BASE_CIPHER_NAMES.put(CMSAlgorithm.AES256_CBC, "AES"); BASE_CIPHER_NAMES.put(CMSAlgorithm.RC2_CBC, "RC2"); BASE_CIPHER_NAMES.put(CMSAlgorithm.CAST5_CBC, "CAST5"); BASE_CIPHER_NAMES.put(CMSAlgorithm.CAMELLIA128_CBC, "Camellia"); BASE_CIPHER_NAMES.put(CMSAlgorithm.CAMELLIA192_CBC, "Camellia"); BASE_CIPHER_NAMES.put(CMSAlgorithm.CAMELLIA256_CBC, "Camellia"); BASE_CIPHER_NAMES.put(CMSAlgorithm.SEED_CBC, "SEED"); CIPHER_ALG_NAMES.put(CMSAlgorithm.DES_CBC, "DES/CBC/PKCS5Padding"); CIPHER_ALG_NAMES.put(CMSAlgorithm.DES_EDE3_CBC, "DESEDE/CBC/PKCS5Padding"); CIPHER_ALG_NAMES.put(CMSAlgorithm.AES128_CBC, "AES/CBC/PKCS5Padding"); CIPHER_ALG_NAMES.put(CMSAlgorithm.AES192_CBC, "AES/CBC/PKCS5Padding"); CIPHER_ALG_NAMES.put(CMSAlgorithm.AES256_CBC, "AES/CBC/PKCS5Padding"); CIPHER_ALG_NAMES.put(PKCSObjectIdentifiers.rsaEncryption, "RSA/ECB/PKCS1Padding"); CIPHER_ALG_NAMES.put(CMSAlgorithm.CAST5_CBC, "CAST5/CBC/PKCS5Padding"); CIPHER_ALG_NAMES.put(CMSAlgorithm.CAMELLIA128_CBC, "Camellia/CBC/PKCS5Padding"); CIPHER_ALG_NAMES.put(CMSAlgorithm.CAMELLIA192_CBC, "Camellia/CBC/PKCS5Padding"); CIPHER_ALG_NAMES.put(CMSAlgorithm.CAMELLIA256_CBC, "Camellia/CBC/PKCS5Padding"); CIPHER_ALG_NAMES.put(CMSAlgorithm.SEED_CBC, "SEED/CBC/PKCS5Padding"); MAC_ALG_NAMES.put(CMSAlgorithm.DES_EDE3_CBC, "DESEDEMac"); MAC_ALG_NAMES.put(CMSAlgorithm.AES128_CBC, "AESMac"); MAC_ALG_NAMES.put(CMSAlgorithm.AES192_CBC, "AESMac"); MAC_ALG_NAMES.put(CMSAlgorithm.AES256_CBC, "AESMac"); MAC_ALG_NAMES.put(CMSAlgorithm.RC2_CBC, "RC2Mac"); } private static final short[] rc2Table = { 0xbd, 0x56, 0xea, 0xf2, 0xa2, 0xf1, 0xac, 0x2a, 0xb0, 0x93, 0xd1, 0x9c, 0x1b, 0x33, 0xfd, 0xd0, 0x30, 0x04, 0xb6, 0xdc, 0x7d, 0xdf, 0x32, 0x4b, 0xf7, 0xcb, 0x45, 0x9b, 0x31, 0xbb, 0x21, 0x5a, 0x41, 0x9f, 0xe1, 0xd9, 0x4a, 0x4d, 0x9e, 0xda, 0xa0, 0x68, 0x2c, 0xc3, 0x27, 0x5f, 0x80, 0x36, 0x3e, 0xee, 0xfb, 0x95, 0x1a, 0xfe, 0xce, 0xa8, 0x34, 0xa9, 0x13, 0xf0, 0xa6, 0x3f, 0xd8, 0x0c, 0x78, 0x24, 0xaf, 0x23, 0x52, 0xc1, 0x67, 0x17, 0xf5, 0x66, 0x90, 0xe7, 0xe8, 0x07, 0xb8, 0x60, 0x48, 0xe6, 0x1e, 0x53, 0xf3, 0x92, 0xa4, 0x72, 0x8c, 0x08, 0x15, 0x6e, 0x86, 0x00, 0x84, 0xfa, 0xf4, 0x7f, 0x8a, 0x42, 0x19, 0xf6, 0xdb, 0xcd, 0x14, 0x8d, 0x50, 0x12, 0xba, 0x3c, 0x06, 0x4e, 0xec, 0xb3, 0x35, 0x11, 0xa1, 0x88, 0x8e, 0x2b, 0x94, 0x99, 0xb7, 0x71, 0x74, 0xd3, 0xe4, 0xbf, 0x3a, 0xde, 0x96, 0x0e, 0xbc, 0x0a, 0xed, 0x77, 0xfc, 0x37, 0x6b, 0x03, 0x79, 0x89, 0x62, 0xc6, 0xd7, 0xc0, 0xd2, 0x7c, 0x6a, 0x8b, 0x22, 0xa3, 0x5b, 0x05, 0x5d, 0x02, 0x75, 0xd5, 0x61, 0xe3, 0x18, 0x8f, 0x55, 0x51, 0xad, 0x1f, 0x0b, 0x5e, 0x85, 0xe5, 0xc2, 0x57, 0x63, 0xca, 0x3d, 0x6c, 0xb4, 0xc5, 0xcc, 0x70, 0xb2, 0x91, 0x59, 0x0d, 0x47, 0x20, 0xc8, 0x4f, 0x58, 0xe0, 0x01, 0xe2, 0x16, 0x38, 0xc4, 0x6f, 0x3b, 0x0f, 0x65, 0x46, 0xbe, 0x7e, 0x2d, 0x7b, 0x82, 0xf9, 0x40, 0xb5, 0x1d, 0x73, 0xf8, 0xeb, 0x26, 0xc7, 0x87, 0x97, 0x25, 0x54, 0xb1, 0x28, 0xaa, 0x98, 0x9d, 0xa5, 0x64, 0x6d, 0x7a, 0xd4, 0x10, 0x81, 0x44, 0xef, 0x49, 0xd6, 0xae, 0x2e, 0xdd, 0x76, 0x5c, 0x2f, 0xa7, 0x1c, 0xc9, 0x09, 0x69, 0x9a, 0x83, 0xcf, 0x29, 0x39, 0xb9, 0xe9, 0x4c, 0xff, 0x43, 0xab }; private static final short[] rc2Ekb = { 0x5d, 0xbe, 0x9b, 0x8b, 0x11, 0x99, 0x6e, 0x4d, 0x59, 0xf3, 0x85, 0xa6, 0x3f, 0xb7, 0x83, 0xc5, 0xe4, 0x73, 0x6b, 0x3a, 0x68, 0x5a, 0xc0, 0x47, 0xa0, 0x64, 0x34, 0x0c, 0xf1, 0xd0, 0x52, 0xa5, 0xb9, 0x1e, 0x96, 0x43, 0x41, 0xd8, 0xd4, 0x2c, 0xdb, 0xf8, 0x07, 0x77, 0x2a, 0xca, 0xeb, 0xef, 0x10, 0x1c, 0x16, 0x0d, 0x38, 0x72, 0x2f, 0x89, 0xc1, 0xf9, 0x80, 0xc4, 0x6d, 0xae, 0x30, 0x3d, 0xce, 0x20, 0x63, 0xfe, 0xe6, 0x1a, 0xc7, 0xb8, 0x50, 0xe8, 0x24, 0x17, 0xfc, 0x25, 0x6f, 0xbb, 0x6a, 0xa3, 0x44, 0x53, 0xd9, 0xa2, 0x01, 0xab, 0xbc, 0xb6, 0x1f, 0x98, 0xee, 0x9a, 0xa7, 0x2d, 0x4f, 0x9e, 0x8e, 0xac, 0xe0, 0xc6, 0x49, 0x46, 0x29, 0xf4, 0x94, 0x8a, 0xaf, 0xe1, 0x5b, 0xc3, 0xb3, 0x7b, 0x57, 0xd1, 0x7c, 0x9c, 0xed, 0x87, 0x40, 0x8c, 0xe2, 0xcb, 0x93, 0x14, 0xc9, 0x61, 0x2e, 0xe5, 0xcc, 0xf6, 0x5e, 0xa8, 0x5c, 0xd6, 0x75, 0x8d, 0x62, 0x95, 0x58, 0x69, 0x76, 0xa1, 0x4a, 0xb5, 0x55, 0x09, 0x78, 0x33, 0x82, 0xd7, 0xdd, 0x79, 0xf5, 0x1b, 0x0b, 0xde, 0x26, 0x21, 0x28, 0x74, 0x04, 0x97, 0x56, 0xdf, 0x3c, 0xf0, 0x37, 0x39, 0xdc, 0xff, 0x06, 0xa4, 0xea, 0x42, 0x08, 0xda, 0xb4, 0x71, 0xb0, 0xcf, 0x12, 0x7a, 0x4e, 0xfa, 0x6c, 0x1d, 0x84, 0x00, 0xc8, 0x7f, 0x91, 0x45, 0xaa, 0x2b, 0xc2, 0xb1, 0x8f, 0xd5, 0xba, 0xf2, 0xad, 0x19, 0xb2, 0x67, 0x36, 0xf7, 0x0f, 0x0a, 0x92, 0x7d, 0xe3, 0x9d, 0xe9, 0x90, 0x3e, 0x23, 0x27, 0x66, 0x13, 0xec, 0x81, 0x15, 0xbd, 0x22, 0xbf, 0x9f, 0x7e, 0xa9, 0x51, 0x4b, 0x4c, 0xfb, 0x02, 0xd3, 0x70, 0x86, 0x31, 0xe7, 0x3b, 0x05, 0x03, 0x54, 0x60, 0x48, 0x65, 0x18, 0xd2, 0xcd, 0x5f, 0x32, 0x88, 0x0e, 0x35, 0xfd }; private JcaJceExtHelper helper; EnvelopedDataHelper(JcaJceExtHelper helper) { this.helper = helper; } String getBaseCipherName(ASN1ObjectIdentifier algorithm) { String name = (String)BASE_CIPHER_NAMES.get(algorithm); if (name == null) { return algorithm.getId(); } return name; } Key getJceKey(GenericKey key) { if (key.getRepresentation() instanceof Key) { return (Key)key.getRepresentation(); } if (key.getRepresentation() instanceof byte[]) { return new SecretKeySpec((byte[])key.getRepresentation(), "ENC"); } throw new IllegalArgumentException("unknown generic key type"); } Key getJceKey(ASN1ObjectIdentifier algorithm, GenericKey key) { if (key.getRepresentation() instanceof Key) { return (Key)key.getRepresentation(); } if (key.getRepresentation() instanceof byte[]) { return new SecretKeySpec((byte[])key.getRepresentation(), getBaseCipherName(algorithm)); } throw new IllegalArgumentException("unknown generic key type"); } Cipher createCipher(ASN1ObjectIdentifier algorithm) throws CMSException { try { String cipherName = (String)CIPHER_ALG_NAMES.get(algorithm); if (cipherName != null) { try { // this is reversed as the Sun policy files now allow unlimited strength RSA return helper.createCipher(cipherName); } catch (NoSuchAlgorithmException e) { // Ignore } } return helper.createCipher(algorithm.getId()); } catch (GeneralSecurityException e) { throw new CMSException("cannot create cipher: " + e.getMessage(), e); } } Mac createMac(ASN1ObjectIdentifier algorithm) throws CMSException { try { String macName = (String)MAC_ALG_NAMES.get(algorithm); if (macName != null) { try { // this is reversed as the Sun policy files now allow unlimited strength RSA return helper.createMac(macName); } catch (NoSuchAlgorithmException e) { // Ignore } } return helper.createMac(algorithm.getId()); } catch (GeneralSecurityException e) { throw new CMSException("cannot create mac: " + e.getMessage(), e); } } Cipher createRFC3211Wrapper(ASN1ObjectIdentifier algorithm) throws CMSException { String cipherName = (String)BASE_CIPHER_NAMES.get(algorithm); if (cipherName == null) { throw new CMSException("no name for " + algorithm); } cipherName += "RFC3211Wrap"; try { return helper.createCipher(cipherName); } catch (GeneralSecurityException e) { throw new CMSException("cannot create cipher: " + e.getMessage(), e); } } KeyAgreement createKeyAgreement(ASN1ObjectIdentifier algorithm) throws CMSException { try { String agreementName = (String)BASE_CIPHER_NAMES.get(algorithm); if (agreementName != null) { try { // this is reversed as the Sun policy files now allow unlimited strength RSA return helper.createKeyAgreement(agreementName); } catch (NoSuchAlgorithmException e) { // Ignore } } return helper.createKeyAgreement(algorithm.getId()); } catch (GeneralSecurityException e) { throw new CMSException("cannot create key pair generator: " + e.getMessage(), e); } } AlgorithmParameterGenerator createAlgorithmParameterGenerator(ASN1ObjectIdentifier algorithm) throws GeneralSecurityException { String algorithmName = (String)BASE_CIPHER_NAMES.get(algorithm); if (algorithmName != null) { try { // this is reversed as the Sun policy files now allow unlimited strength RSA return helper.createAlgorithmParameterGenerator(algorithmName); } catch (NoSuchAlgorithmException e) { // Ignore } } return helper.createAlgorithmParameterGenerator(algorithm.getId()); } Cipher createContentCipher(final Key sKey, final AlgorithmIdentifier encryptionAlgID) throws CMSException { return (Cipher)execute(new JCECallback() { public Object doInJCE() throws CMSException, InvalidAlgorithmParameterException, InvalidKeyException, InvalidParameterSpecException, NoSuchAlgorithmException, NoSuchPaddingException, NoSuchProviderException { Cipher cipher = createCipher(encryptionAlgID.getAlgorithm()); ASN1Encodable sParams = encryptionAlgID.getParameters(); String encAlg = encryptionAlgID.getAlgorithm().getId(); if (sParams != null && !(sParams instanceof ASN1Null)) { try { AlgorithmParameters params = createAlgorithmParameters(encryptionAlgID.getAlgorithm()); try { params.init(sParams.toASN1Primitive().getEncoded(), "ASN.1"); } catch (IOException e) { throw new CMSException("error decoding algorithm parameters.", e); } cipher.init(Cipher.DECRYPT_MODE, sKey, params); } catch (NoSuchAlgorithmException e) { if (encAlg.equals(CMSAlgorithm.DES_CBC.getId()) || encAlg.equals(CMSEnvelopedDataGenerator.DES_EDE3_CBC) || encAlg.equals(CMSEnvelopedDataGenerator.IDEA_CBC) || encAlg.equals(CMSEnvelopedDataGenerator.AES128_CBC) || encAlg.equals(CMSEnvelopedDataGenerator.AES192_CBC) || encAlg.equals(CMSEnvelopedDataGenerator.AES256_CBC)) { cipher.init(Cipher.DECRYPT_MODE, sKey, new IvParameterSpec( ASN1OctetString.getInstance(sParams).getOctets())); } else { throw e; } } } else { if (encAlg.equals(CMSAlgorithm.DES_CBC.getId()) || encAlg.equals(CMSEnvelopedDataGenerator.DES_EDE3_CBC) || encAlg.equals(CMSEnvelopedDataGenerator.IDEA_CBC) || encAlg.equals(CMSEnvelopedDataGenerator.CAST5_CBC)) { cipher.init(Cipher.DECRYPT_MODE, sKey, new IvParameterSpec(new byte[8])); } else { cipher.init(Cipher.DECRYPT_MODE, sKey); } } return cipher; } }); } Mac createContentMac(final Key sKey, final AlgorithmIdentifier macAlgId) throws CMSException { return (Mac)execute(new JCECallback() { public Object doInJCE() throws CMSException, InvalidAlgorithmParameterException, InvalidKeyException, InvalidParameterSpecException, NoSuchAlgorithmException, NoSuchPaddingException, NoSuchProviderException { Mac mac = createMac(macAlgId.getAlgorithm()); ASN1Encodable sParams = macAlgId.getParameters(); String macAlg = macAlgId.getAlgorithm().getId(); if (sParams != null && !(sParams instanceof ASN1Null)) { try { AlgorithmParameters params = createAlgorithmParameters(macAlgId.getAlgorithm()); try { params.init(sParams.toASN1Primitive().getEncoded(), "ASN.1"); } catch (IOException e) { throw new CMSException("error decoding algorithm parameters.", e); } mac.init(sKey, params.getParameterSpec(IvParameterSpec.class)); } catch (NoSuchAlgorithmException e) { throw e; } } else { mac.init(sKey); } return mac; } }); } AlgorithmParameters createAlgorithmParameters(ASN1ObjectIdentifier algorithm) throws NoSuchAlgorithmException, NoSuchProviderException { String algorithmName = (String)BASE_CIPHER_NAMES.get(algorithm); if (algorithmName != null) { try { // this is reversed as the Sun policy files now allow unlimited strength RSA return helper.createAlgorithmParameters(algorithmName); } catch (NoSuchAlgorithmException e) { // Ignore } } return helper.createAlgorithmParameters(algorithm.getId()); } KeyPairGenerator createKeyPairGenerator(ASN1ObjectIdentifier algorithm) throws CMSException { try { String cipherName = (String)BASE_CIPHER_NAMES.get(algorithm); if (cipherName != null) { try { // this is reversed as the Sun policy files now allow unlimited strength RSA return helper.createKeyPairGenerator(cipherName); } catch (NoSuchAlgorithmException e) { // Ignore } } return helper.createKeyPairGenerator(algorithm.getId()); } catch (GeneralSecurityException e) { throw new CMSException("cannot create key pair generator: " + e.getMessage(), e); } } public KeyGenerator createKeyGenerator(ASN1ObjectIdentifier algorithm) throws CMSException { try { String cipherName = (String)BASE_CIPHER_NAMES.get(algorithm); if (cipherName != null) { try { // this is reversed as the Sun policy files now allow unlimited strength RSA return helper.createKeyGenerator(cipherName); } catch (NoSuchAlgorithmException e) { // Ignore } } return helper.createKeyGenerator(algorithm.getId()); } catch (GeneralSecurityException e) { throw new CMSException("cannot create key generator: " + e.getMessage(), e); } } AlgorithmParameters generateParameters(ASN1ObjectIdentifier encryptionOID, SecretKey encKey, SecureRandom rand) throws CMSException { try { AlgorithmParameterGenerator pGen = createAlgorithmParameterGenerator(encryptionOID); if (encryptionOID.equals(CMSEnvelopedDataGenerator.RC2_CBC)) { byte[] iv = new byte[8]; rand.nextBytes(iv); try { pGen.init(new RC2ParameterSpec(encKey.getEncoded().length * 8, iv), rand); } catch (InvalidAlgorithmParameterException e) { throw new CMSException("parameters generation error: " + e, e); } } return pGen.generateParameters(); } catch (NoSuchAlgorithmException e) { return null; } catch (GeneralSecurityException e) { throw new CMSException("exception creating algorithm parameter generator: " + e, e); } } AlgorithmIdentifier getAlgorithmIdentifier(ASN1ObjectIdentifier encryptionOID, AlgorithmParameters params) throws CMSException { ASN1Encodable asn1Params; if (params != null) { try { asn1Params = ASN1Primitive.fromByteArray(params.getEncoded("ASN.1")); } catch (IOException e) { throw new CMSException("cannot encode parameters: " + e.getMessage(), e); } } else { asn1Params = DERNull.INSTANCE; } return new AlgorithmIdentifier( encryptionOID, asn1Params); } static Object execute(JCECallback callback) throws CMSException { try { return callback.doInJCE(); } catch (NoSuchAlgorithmException e) { throw new CMSException("can't find algorithm.", e); } catch (InvalidKeyException e) { throw new CMSException("key invalid in message.", e); } catch (NoSuchProviderException e) { throw new CMSException("can't find provider.", e); } catch (NoSuchPaddingException e) { throw new CMSException("required padding not supported.", e); } catch (InvalidAlgorithmParameterException e) { throw new CMSException("algorithm parameters invalid.", e); } catch (InvalidParameterSpecException e) { throw new CMSException("MAC algorithm parameter spec invalid.", e); } } public KeyFactory createKeyFactory(ASN1ObjectIdentifier algorithm) throws CMSException { try { String cipherName = (String)BASE_CIPHER_NAMES.get(algorithm); if (cipherName != null) { try { // this is reversed as the Sun policy files now allow unlimited strength RSA return helper.createKeyFactory(cipherName); } catch (NoSuchAlgorithmException e) { // Ignore } } return helper.createKeyFactory(algorithm.getId()); } catch (GeneralSecurityException e) { throw new CMSException("cannot create key factory: " + e.getMessage(), e); } } public JceAsymmetricKeyUnwrapper createAsymmetricUnwrapper(AlgorithmIdentifier keyEncryptionAlgorithm, PrivateKey keyEncryptionKey) { return helper.createAsymmetricUnwrapper(keyEncryptionAlgorithm, keyEncryptionKey); } public SymmetricKeyUnwrapper createSymmetricUnwrapper(AlgorithmIdentifier keyEncryptionAlgorithm, SecretKey keyEncryptionKey) { return helper.createSymmetricUnwrapper(keyEncryptionAlgorithm, keyEncryptionKey); } public AlgorithmIdentifier getAlgorithmIdentifier(ASN1ObjectIdentifier macOID, AlgorithmParameterSpec paramSpec) { if (paramSpec instanceof IvParameterSpec) { return new AlgorithmIdentifier(macOID, new DEROctetString(((IvParameterSpec)paramSpec).getIV())); } if (paramSpec instanceof RC2ParameterSpec) { RC2ParameterSpec rc2Spec = (RC2ParameterSpec)paramSpec; int effKeyBits = ((RC2ParameterSpec)paramSpec).getEffectiveKeyBits(); if (effKeyBits != -1) { int parameterVersion; if (effKeyBits < 256) { parameterVersion = rc2Table[effKeyBits]; } else { parameterVersion = effKeyBits; } return new AlgorithmIdentifier(macOID, new RC2CBCParameter(parameterVersion, rc2Spec.getIV())); } return new AlgorithmIdentifier(macOID, new RC2CBCParameter(rc2Spec.getIV())); } throw new IllegalStateException("unknown parameter spec: " + paramSpec); } static interface JCECallback { Object doInJCE() throws CMSException, InvalidAlgorithmParameterException, InvalidKeyException, InvalidParameterSpecException, NoSuchAlgorithmException, NoSuchPaddingException, NoSuchProviderException; } } bouncycastle-1.49.orig/src/org/bouncycastle/cms/jcajce/JceCMSMacCalculatorBuilder.java0000644000175000017500000001050212045642260030353 0ustar ebourgebourgpackage org.bouncycastle.cms.jcajce; import java.io.OutputStream; import java.security.AlgorithmParameterGenerator; import java.security.AlgorithmParameters; import java.security.GeneralSecurityException; import java.security.Provider; import java.security.SecureRandom; import java.security.spec.AlgorithmParameterSpec; import javax.crypto.KeyGenerator; import javax.crypto.Mac; import javax.crypto.SecretKey; import javax.crypto.spec.IvParameterSpec; import javax.crypto.spec.RC2ParameterSpec; import org.bouncycastle.asn1.ASN1ObjectIdentifier; import org.bouncycastle.asn1.pkcs.PKCSObjectIdentifiers; import org.bouncycastle.asn1.x509.AlgorithmIdentifier; import org.bouncycastle.cms.CMSException; import org.bouncycastle.jcajce.io.MacOutputStream; import org.bouncycastle.operator.GenericKey; import org.bouncycastle.operator.MacCalculator; import org.bouncycastle.operator.jcajce.JceGenericKey; public class JceCMSMacCalculatorBuilder { private final ASN1ObjectIdentifier macOID; private final int keySize; private EnvelopedDataHelper helper = new EnvelopedDataHelper(new DefaultJcaJceExtHelper()); private SecureRandom random; public JceCMSMacCalculatorBuilder(ASN1ObjectIdentifier macOID) { this(macOID, -1); } public JceCMSMacCalculatorBuilder(ASN1ObjectIdentifier macOID, int keySize) { this.macOID = macOID; this.keySize = keySize; } public JceCMSMacCalculatorBuilder setProvider(Provider provider) { this.helper = new EnvelopedDataHelper(new ProviderJcaJceExtHelper(provider)); return this; } public JceCMSMacCalculatorBuilder setProvider(String providerName) { this.helper = new EnvelopedDataHelper(new NamedJcaJceExtHelper(providerName)); return this; } public JceCMSMacCalculatorBuilder setSecureRandom(SecureRandom random) { this.random = random; return this; } public MacCalculator build() throws CMSException { return new CMSMacCalculator(macOID, keySize, random); } private class CMSMacCalculator implements MacCalculator { private SecretKey encKey; private AlgorithmIdentifier algorithmIdentifier; private Mac mac; private SecureRandom random; CMSMacCalculator(ASN1ObjectIdentifier macOID, int keySize, SecureRandom random) throws CMSException { KeyGenerator keyGen = helper.createKeyGenerator(macOID); if (random == null) { random = new SecureRandom(); } this.random = random; if (keySize < 0) { keyGen.init(random); } else { keyGen.init(keySize, random); } encKey = keyGen.generateKey(); AlgorithmParameterSpec paramSpec = generateParameterSpec(macOID, encKey); algorithmIdentifier = helper.getAlgorithmIdentifier(macOID, paramSpec); mac = helper.createContentMac(encKey, algorithmIdentifier); } public AlgorithmIdentifier getAlgorithmIdentifier() { return algorithmIdentifier; } public OutputStream getOutputStream() { return new MacOutputStream(mac); } public byte[] getMac() { return mac.doFinal(); } public GenericKey getKey() { return new JceGenericKey(algorithmIdentifier, encKey); } protected AlgorithmParameterSpec generateParameterSpec(ASN1ObjectIdentifier macOID, SecretKey encKey) throws CMSException { try { if (macOID.equals(PKCSObjectIdentifiers.RC2_CBC)) { byte[] iv = new byte[8]; random.nextBytes(iv); return new RC2ParameterSpec(encKey.getEncoded().length * 8, iv); } AlgorithmParameterGenerator pGen = helper.createAlgorithmParameterGenerator(macOID); AlgorithmParameters p = pGen.generateParameters(); return p.getParameterSpec(IvParameterSpec.class); } catch (GeneralSecurityException e) { return null; } } } } bouncycastle-1.49.orig/src/org/bouncycastle/cms/jcajce/ZlibExpanderProvider.java0000644000175000017500000000610511530416362027453 0ustar ebourgebourgpackage org.bouncycastle.cms.jcajce; import java.io.FilterInputStream; import java.io.IOException; import java.io.InputStream; import java.util.zip.InflaterInputStream; import org.bouncycastle.asn1.x509.AlgorithmIdentifier; import org.bouncycastle.operator.InputExpander; import org.bouncycastle.operator.InputExpanderProvider; import org.bouncycastle.util.io.StreamOverflowException; public class ZlibExpanderProvider implements InputExpanderProvider { private final long limit; public ZlibExpanderProvider() { this.limit = -1; } /** * Create a provider which caps the number of expanded bytes that can be produced when the * compressed stream is parsed. * * @param limit max number of bytes allowed in an expanded stream. */ public ZlibExpanderProvider(long limit) { this.limit = limit; } public InputExpander get(final AlgorithmIdentifier algorithm) { return new InputExpander() { public AlgorithmIdentifier getAlgorithmIdentifier() { return algorithm; } public InputStream getInputStream(InputStream comIn) { InputStream s = new InflaterInputStream(comIn); if (limit >= 0) { s = new LimitedInputStream(s, limit); } return s; } }; } private static class LimitedInputStream extends FilterInputStream { private long remaining; public LimitedInputStream(InputStream input, long limit) { super(input); this.remaining = limit; } public int read() throws IOException { // Only a single 'extra' byte will ever be read if (remaining >= 0) { int b = super.in.read(); if (b < 0 || --remaining >= 0) { return b; } } throw new StreamOverflowException("expanded byte limit exceeded"); } public int read(byte[] buf, int off, int len) throws IOException { if (len < 1) { // This will give correct exceptions/returns for strange lengths return super.read(buf, off, len); } if (remaining < 1) { // Will either return EOF or throw exception read(); return -1; } /* * Limit the underlying request to 'remaining' bytes. This ensures the * caller will see the full 'limit' bytes before getting an exception. * Also, only one extra byte will ever be read. */ int actualLen = (remaining > len ? len : (int)remaining); int numRead = super.in.read(buf, off, actualLen); if (numRead > 0) { remaining -= numRead; } return numRead; } } } bouncycastle-1.49.orig/src/org/bouncycastle/cms/jcajce/JcePasswordRecipient.java0000644000175000017500000000475311723553745027462 0ustar ebourgebourgpackage org.bouncycastle.cms.jcajce; import java.security.GeneralSecurityException; import java.security.Key; import java.security.Provider; import javax.crypto.Cipher; import javax.crypto.spec.IvParameterSpec; import javax.crypto.spec.SecretKeySpec; import org.bouncycastle.asn1.ASN1OctetString; import org.bouncycastle.asn1.x509.AlgorithmIdentifier; import org.bouncycastle.cms.CMSException; import org.bouncycastle.cms.PasswordRecipient; /** * the RecipientInfo class for a recipient who has been sent a message * encrypted using a password. */ public abstract class JcePasswordRecipient implements PasswordRecipient { private int schemeID = PasswordRecipient.PKCS5_SCHEME2_UTF8; protected EnvelopedDataHelper helper = new EnvelopedDataHelper(new DefaultJcaJceExtHelper()); private char[] password; JcePasswordRecipient( char[] password) { this.password = password; } public JcePasswordRecipient setPasswordConversionScheme(int schemeID) { this.schemeID = schemeID; return this; } public JcePasswordRecipient setProvider(Provider provider) { this.helper = new EnvelopedDataHelper(new ProviderJcaJceExtHelper(provider)); return this; } public JcePasswordRecipient setProvider(String providerName) { this.helper = new EnvelopedDataHelper(new NamedJcaJceExtHelper(providerName)); return this; } protected Key extractSecretKey(AlgorithmIdentifier keyEncryptionAlgorithm, AlgorithmIdentifier contentEncryptionAlgorithm, byte[] derivedKey, byte[] encryptedContentEncryptionKey) throws CMSException { Cipher keyEncryptionCipher = helper.createRFC3211Wrapper(keyEncryptionAlgorithm.getAlgorithm()); try { IvParameterSpec ivSpec = new IvParameterSpec(ASN1OctetString.getInstance(keyEncryptionAlgorithm.getParameters()).getOctets()); keyEncryptionCipher.init(Cipher.UNWRAP_MODE, new SecretKeySpec(derivedKey, keyEncryptionCipher.getAlgorithm()), ivSpec); return keyEncryptionCipher.unwrap(encryptedContentEncryptionKey, contentEncryptionAlgorithm.getAlgorithm().getId(), Cipher.SECRET_KEY); } catch (GeneralSecurityException e) { throw new CMSException("cannot process content encryption key: " + e.getMessage(), e); } } public int getPasswordConversionScheme() { return schemeID; } public char[] getPassword() { return password; } } bouncycastle-1.49.orig/src/org/bouncycastle/cms/jcajce/JceAlgorithmIdentifierConverter.java0000644000175000017500000000366211726031253031620 0ustar ebourgebourgpackage org.bouncycastle.cms.jcajce; import java.io.IOException; import java.security.AlgorithmParameters; import java.security.NoSuchAlgorithmException; import java.security.NoSuchProviderException; import java.security.Provider; import java.security.SecureRandom; import org.bouncycastle.asn1.ASN1Encodable; import org.bouncycastle.asn1.x509.AlgorithmIdentifier; import org.bouncycastle.cms.CMSException; public class JceAlgorithmIdentifierConverter { private EnvelopedDataHelper helper = new EnvelopedDataHelper(new DefaultJcaJceExtHelper()); private SecureRandom random; public JceAlgorithmIdentifierConverter() { } public JceAlgorithmIdentifierConverter setProvider(Provider provider) { this.helper = new EnvelopedDataHelper(new ProviderJcaJceExtHelper(provider)); return this; } public JceAlgorithmIdentifierConverter setProvider(String providerName) { this.helper = new EnvelopedDataHelper(new NamedJcaJceExtHelper(providerName)); return this; } public AlgorithmParameters getAlgorithmParameters(AlgorithmIdentifier algorithmIdentifier) throws CMSException { ASN1Encodable parameters = algorithmIdentifier.getParameters(); if (parameters == null) { return null; } try { AlgorithmParameters params = helper.createAlgorithmParameters(algorithmIdentifier.getAlgorithm()); params.init(parameters.toASN1Primitive().getEncoded(), "ASN.1"); return params; } catch (NoSuchAlgorithmException e) { throw new CMSException("can't find parameters for algorithm", e); } catch (IOException e) { throw new CMSException("can't parse parameters", e); } catch (NoSuchProviderException e) { throw new CMSException("can't find provider for algorithm", e); } } } bouncycastle-1.49.orig/src/org/bouncycastle/cms/jcajce/JceKeyAgreeRecipient.java0000644000175000017500000001572311737174250027346 0ustar ebourgebourgpackage org.bouncycastle.cms.jcajce; import java.io.IOException; import java.security.GeneralSecurityException; import java.security.InvalidKeyException; import java.security.Key; import java.security.KeyFactory; import java.security.NoSuchAlgorithmException; import java.security.PrivateKey; import java.security.Provider; import java.security.PublicKey; import java.security.spec.InvalidKeySpecException; import java.security.spec.X509EncodedKeySpec; import javax.crypto.Cipher; import javax.crypto.KeyAgreement; import javax.crypto.NoSuchPaddingException; import javax.crypto.SecretKey; import org.bouncycastle.asn1.ASN1ObjectIdentifier; import org.bouncycastle.asn1.ASN1OctetString; import org.bouncycastle.asn1.ASN1Primitive; import org.bouncycastle.asn1.cms.ecc.MQVuserKeyingMaterial; import org.bouncycastle.asn1.pkcs.PrivateKeyInfo; import org.bouncycastle.asn1.x509.AlgorithmIdentifier; import org.bouncycastle.asn1.x509.SubjectPublicKeyInfo; import org.bouncycastle.cms.CMSEnvelopedGenerator; import org.bouncycastle.cms.CMSException; import org.bouncycastle.cms.KeyAgreeRecipient; import org.bouncycastle.jce.spec.MQVPrivateKeySpec; import org.bouncycastle.jce.spec.MQVPublicKeySpec; public abstract class JceKeyAgreeRecipient implements KeyAgreeRecipient { private PrivateKey recipientKey; protected EnvelopedDataHelper helper = new EnvelopedDataHelper(new DefaultJcaJceExtHelper()); protected EnvelopedDataHelper contentHelper = helper; public JceKeyAgreeRecipient(PrivateKey recipientKey) { this.recipientKey = recipientKey; } /** * Set the provider to use for key recovery and content processing. * * @param provider provider to use. * @return this recipient. */ public JceKeyAgreeRecipient setProvider(Provider provider) { this.helper = new EnvelopedDataHelper(new ProviderJcaJceExtHelper(provider)); this.contentHelper = helper; return this; } /** * Set the provider to use for key recovery and content processing. * * @param providerName the name of the provider to use. * @return this recipient. */ public JceKeyAgreeRecipient setProvider(String providerName) { this.helper = new EnvelopedDataHelper(new NamedJcaJceExtHelper(providerName)); this.contentHelper = helper; return this; } /** * Set the provider to use for content processing. If providerName is null a "no provider" search will be * used to satisfy getInstance calls. * * @param provider the provider to use. * @return this recipient. */ public JceKeyAgreeRecipient setContentProvider(Provider provider) { this.contentHelper = CMSUtils.createContentHelper(provider); return this; } /** * Set the provider to use for content processing. If providerName is null a "no provider" search will be * used to satisfy getInstance calls. * * @param providerName the name of the provider to use. * @return this recipient. */ public JceKeyAgreeRecipient setContentProvider(String providerName) { this.contentHelper = CMSUtils.createContentHelper(providerName); return this; } private SecretKey calculateAgreedWrapKey(AlgorithmIdentifier keyEncAlg, ASN1ObjectIdentifier wrapAlg, PublicKey senderPublicKey, ASN1OctetString userKeyingMaterial, PrivateKey receiverPrivateKey) throws CMSException, GeneralSecurityException, IOException { String agreeAlg = keyEncAlg.getAlgorithm().getId(); if (agreeAlg.equals(CMSEnvelopedGenerator.ECMQV_SHA1KDF)) { byte[] ukmEncoding = userKeyingMaterial.getOctets(); MQVuserKeyingMaterial ukm = MQVuserKeyingMaterial.getInstance( ASN1Primitive.fromByteArray(ukmEncoding)); SubjectPublicKeyInfo pubInfo = new SubjectPublicKeyInfo( getPrivateKeyAlgorithmIdentifier(), ukm.getEphemeralPublicKey().getPublicKey().getBytes()); X509EncodedKeySpec pubSpec = new X509EncodedKeySpec(pubInfo.getEncoded()); KeyFactory fact = helper.createKeyFactory(keyEncAlg.getAlgorithm()); PublicKey ephemeralKey = fact.generatePublic(pubSpec); senderPublicKey = new MQVPublicKeySpec(senderPublicKey, ephemeralKey); receiverPrivateKey = new MQVPrivateKeySpec(receiverPrivateKey, receiverPrivateKey); } KeyAgreement agreement = helper.createKeyAgreement(keyEncAlg.getAlgorithm()); agreement.init(receiverPrivateKey); agreement.doPhase(senderPublicKey, true); return agreement.generateSecret(wrapAlg.getId()); } private Key unwrapSessionKey(ASN1ObjectIdentifier wrapAlg, SecretKey agreedKey, ASN1ObjectIdentifier contentEncryptionAlgorithm, byte[] encryptedContentEncryptionKey) throws CMSException, InvalidKeyException, NoSuchAlgorithmException { Cipher keyCipher = helper.createCipher(wrapAlg); keyCipher.init(Cipher.UNWRAP_MODE, agreedKey); return keyCipher.unwrap(encryptedContentEncryptionKey, helper.getBaseCipherName(contentEncryptionAlgorithm), Cipher.SECRET_KEY); } protected Key extractSecretKey(AlgorithmIdentifier keyEncryptionAlgorithm, AlgorithmIdentifier contentEncryptionAlgorithm, SubjectPublicKeyInfo senderKey, ASN1OctetString userKeyingMaterial, byte[] encryptedContentEncryptionKey) throws CMSException { try { ASN1ObjectIdentifier wrapAlg = AlgorithmIdentifier.getInstance(keyEncryptionAlgorithm.getParameters()).getAlgorithm(); X509EncodedKeySpec pubSpec = new X509EncodedKeySpec(senderKey.getEncoded()); KeyFactory fact = helper.createKeyFactory(keyEncryptionAlgorithm.getAlgorithm()); PublicKey senderPublicKey = fact.generatePublic(pubSpec); SecretKey agreedWrapKey = calculateAgreedWrapKey(keyEncryptionAlgorithm, wrapAlg, senderPublicKey, userKeyingMaterial, recipientKey); return unwrapSessionKey(wrapAlg, agreedWrapKey, contentEncryptionAlgorithm.getAlgorithm(), encryptedContentEncryptionKey); } catch (NoSuchAlgorithmException e) { throw new CMSException("can't find algorithm.", e); } catch (InvalidKeyException e) { throw new CMSException("key invalid in message.", e); } catch (InvalidKeySpecException e) { throw new CMSException("originator key spec invalid.", e); } catch (NoSuchPaddingException e) { throw new CMSException("required padding not supported.", e); } catch (Exception e) { throw new CMSException("originator key invalid.", e); } } public AlgorithmIdentifier getPrivateKeyAlgorithmIdentifier() { return PrivateKeyInfo.getInstance(recipientKey.getEncoded()).getPrivateKeyAlgorithm(); } } bouncycastle-1.49.orig/src/org/bouncycastle/cms/jcajce/JcaJceExtHelper.java0000644000175000017500000000120511723553745026320 0ustar ebourgebourgpackage org.bouncycastle.cms.jcajce; import java.security.PrivateKey; import javax.crypto.SecretKey; import org.bouncycastle.asn1.x509.AlgorithmIdentifier; import org.bouncycastle.jcajce.JcaJceHelper; import org.bouncycastle.operator.SymmetricKeyUnwrapper; import org.bouncycastle.operator.jcajce.JceAsymmetricKeyUnwrapper; public interface JcaJceExtHelper extends JcaJceHelper { JceAsymmetricKeyUnwrapper createAsymmetricUnwrapper(AlgorithmIdentifier keyEncryptionAlgorithm, PrivateKey keyEncryptionKey); SymmetricKeyUnwrapper createSymmetricUnwrapper(AlgorithmIdentifier keyEncryptionAlgorithm, SecretKey keyEncryptionKey); } bouncycastle-1.49.orig/src/org/bouncycastle/cms/jcajce/JceKEKEnvelopedRecipient.java0000644000175000017500000000257511504015246030116 0ustar ebourgebourgpackage org.bouncycastle.cms.jcajce; import java.io.InputStream; import java.security.Key; import javax.crypto.Cipher; import javax.crypto.CipherInputStream; import javax.crypto.SecretKey; import org.bouncycastle.asn1.x509.AlgorithmIdentifier; import org.bouncycastle.cms.CMSException; import org.bouncycastle.cms.RecipientOperator; import org.bouncycastle.operator.InputDecryptor; public class JceKEKEnvelopedRecipient extends JceKEKRecipient { public JceKEKEnvelopedRecipient(SecretKey recipientKey) { super(recipientKey); } public RecipientOperator getRecipientOperator(AlgorithmIdentifier keyEncryptionAlgorithm, final AlgorithmIdentifier contentEncryptionAlgorithm, byte[] encryptedContentEncryptionKey) throws CMSException { Key secretKey = extractSecretKey(keyEncryptionAlgorithm, contentEncryptionAlgorithm, encryptedContentEncryptionKey); final Cipher dataCipher = contentHelper.createContentCipher(secretKey, contentEncryptionAlgorithm); return new RecipientOperator(new InputDecryptor() { public AlgorithmIdentifier getAlgorithmIdentifier() { return contentEncryptionAlgorithm; } public InputStream getInputStream(InputStream dataOut) { return new CipherInputStream(dataOut, dataCipher); } }); } } bouncycastle-1.49.orig/src/org/bouncycastle/cms/jcajce/ProviderJcaJceExtHelper.java0000644000175000017500000000215411724025646030032 0ustar ebourgebourgpackage org.bouncycastle.cms.jcajce; import java.security.PrivateKey; import java.security.Provider; import javax.crypto.SecretKey; import org.bouncycastle.asn1.x509.AlgorithmIdentifier; import org.bouncycastle.jcajce.ProviderJcaJceHelper; import org.bouncycastle.operator.SymmetricKeyUnwrapper; import org.bouncycastle.operator.jcajce.JceAsymmetricKeyUnwrapper; import org.bouncycastle.operator.jcajce.JceSymmetricKeyUnwrapper; class ProviderJcaJceExtHelper extends ProviderJcaJceHelper implements JcaJceExtHelper { public ProviderJcaJceExtHelper(Provider provider) { super(provider); } public JceAsymmetricKeyUnwrapper createAsymmetricUnwrapper(AlgorithmIdentifier keyEncryptionAlgorithm, PrivateKey keyEncryptionKey) { return new JceAsymmetricKeyUnwrapper(keyEncryptionAlgorithm, keyEncryptionKey).setProvider(provider); } public SymmetricKeyUnwrapper createSymmetricUnwrapper(AlgorithmIdentifier keyEncryptionAlgorithm, SecretKey keyEncryptionKey) { return new JceSymmetricKeyUnwrapper(keyEncryptionAlgorithm, keyEncryptionKey).setProvider(provider); } }bouncycastle-1.49.orig/src/org/bouncycastle/cms/jcajce/JcaSimpleSignerInfoVerifierBuilder.java0000644000175000017500000001315711562116544032220 0ustar ebourgebourgpackage org.bouncycastle.cms.jcajce; import java.security.Provider; import java.security.PublicKey; import java.security.cert.CertificateException; import java.security.cert.X509Certificate; import org.bouncycastle.cert.X509CertificateHolder; import org.bouncycastle.cms.DefaultCMSSignatureAlgorithmNameGenerator; import org.bouncycastle.cms.SignerInformationVerifier; import org.bouncycastle.operator.ContentVerifierProvider; import org.bouncycastle.operator.DefaultSignatureAlgorithmIdentifierFinder; import org.bouncycastle.operator.DigestCalculatorProvider; import org.bouncycastle.operator.OperatorCreationException; import org.bouncycastle.operator.jcajce.JcaContentVerifierProviderBuilder; import org.bouncycastle.operator.jcajce.JcaDigestCalculatorProviderBuilder; public class JcaSimpleSignerInfoVerifierBuilder { private Helper helper = new Helper(); public JcaSimpleSignerInfoVerifierBuilder setProvider(Provider provider) { this.helper = new ProviderHelper(provider); return this; } public JcaSimpleSignerInfoVerifierBuilder setProvider(String providerName) { this.helper = new NamedHelper(providerName); return this; } public SignerInformationVerifier build(X509CertificateHolder certHolder) throws OperatorCreationException, CertificateException { return new SignerInformationVerifier(new DefaultCMSSignatureAlgorithmNameGenerator(), new DefaultSignatureAlgorithmIdentifierFinder(), helper.createContentVerifierProvider(certHolder), helper.createDigestCalculatorProvider()); } public SignerInformationVerifier build(X509Certificate certificate) throws OperatorCreationException { return new SignerInformationVerifier(new DefaultCMSSignatureAlgorithmNameGenerator(), new DefaultSignatureAlgorithmIdentifierFinder(), helper.createContentVerifierProvider(certificate), helper.createDigestCalculatorProvider()); } public SignerInformationVerifier build(PublicKey pubKey) throws OperatorCreationException { return new SignerInformationVerifier(new DefaultCMSSignatureAlgorithmNameGenerator(), new DefaultSignatureAlgorithmIdentifierFinder(), helper.createContentVerifierProvider(pubKey), helper.createDigestCalculatorProvider()); } private class Helper { ContentVerifierProvider createContentVerifierProvider(PublicKey publicKey) throws OperatorCreationException { return new JcaContentVerifierProviderBuilder().build(publicKey); } ContentVerifierProvider createContentVerifierProvider(X509Certificate certificate) throws OperatorCreationException { return new JcaContentVerifierProviderBuilder().build(certificate); } ContentVerifierProvider createContentVerifierProvider(X509CertificateHolder certHolder) throws OperatorCreationException, CertificateException { return new JcaContentVerifierProviderBuilder().build(certHolder); } DigestCalculatorProvider createDigestCalculatorProvider() throws OperatorCreationException { return new JcaDigestCalculatorProviderBuilder().build(); } } private class NamedHelper extends Helper { private final String providerName; public NamedHelper(String providerName) { this.providerName = providerName; } ContentVerifierProvider createContentVerifierProvider(PublicKey publicKey) throws OperatorCreationException { return new JcaContentVerifierProviderBuilder().setProvider(providerName).build(publicKey); } ContentVerifierProvider createContentVerifierProvider(X509Certificate certificate) throws OperatorCreationException { return new JcaContentVerifierProviderBuilder().setProvider(providerName).build(certificate); } DigestCalculatorProvider createDigestCalculatorProvider() throws OperatorCreationException { return new JcaDigestCalculatorProviderBuilder().setProvider(providerName).build(); } ContentVerifierProvider createContentVerifierProvider(X509CertificateHolder certHolder) throws OperatorCreationException, CertificateException { return new JcaContentVerifierProviderBuilder().setProvider(providerName).build(certHolder); } } private class ProviderHelper extends Helper { private final Provider provider; public ProviderHelper(Provider provider) { this.provider = provider; } ContentVerifierProvider createContentVerifierProvider(PublicKey publicKey) throws OperatorCreationException { return new JcaContentVerifierProviderBuilder().setProvider(provider).build(publicKey); } ContentVerifierProvider createContentVerifierProvider(X509Certificate certificate) throws OperatorCreationException { return new JcaContentVerifierProviderBuilder().setProvider(provider).build(certificate); } DigestCalculatorProvider createDigestCalculatorProvider() throws OperatorCreationException { return new JcaDigestCalculatorProviderBuilder().setProvider(provider).build(); } ContentVerifierProvider createContentVerifierProvider(X509CertificateHolder certHolder) throws OperatorCreationException, CertificateException { return new JcaContentVerifierProviderBuilder().setProvider(provider).build(certHolder); } } } bouncycastle-1.49.orig/src/org/bouncycastle/cms/jcajce/NamedJcaJceExtHelper.java0000644000175000017500000000211711724025646027263 0ustar ebourgebourgpackage org.bouncycastle.cms.jcajce; import java.security.PrivateKey; import javax.crypto.SecretKey; import org.bouncycastle.asn1.x509.AlgorithmIdentifier; import org.bouncycastle.jcajce.NamedJcaJceHelper; import org.bouncycastle.operator.SymmetricKeyUnwrapper; import org.bouncycastle.operator.jcajce.JceAsymmetricKeyUnwrapper; import org.bouncycastle.operator.jcajce.JceSymmetricKeyUnwrapper; class NamedJcaJceExtHelper extends NamedJcaJceHelper implements JcaJceExtHelper { public NamedJcaJceExtHelper(String providerName) { super(providerName); } public JceAsymmetricKeyUnwrapper createAsymmetricUnwrapper(AlgorithmIdentifier keyEncryptionAlgorithm, PrivateKey keyEncryptionKey) { return new JceAsymmetricKeyUnwrapper(keyEncryptionAlgorithm, keyEncryptionKey).setProvider(providerName); } public SymmetricKeyUnwrapper createSymmetricUnwrapper(AlgorithmIdentifier keyEncryptionAlgorithm, SecretKey keyEncryptionKey) { return new JceSymmetricKeyUnwrapper(keyEncryptionAlgorithm, keyEncryptionKey).setProvider(providerName); } }bouncycastle-1.49.orig/src/org/bouncycastle/cms/jcajce/ZlibCompressor.java0000644000175000017500000000123511526127344026331 0ustar ebourgebourgpackage org.bouncycastle.cms.jcajce; import java.io.OutputStream; import java.util.zip.DeflaterOutputStream; import org.bouncycastle.asn1.ASN1ObjectIdentifier; import org.bouncycastle.asn1.x509.AlgorithmIdentifier; import org.bouncycastle.operator.OutputCompressor; public class ZlibCompressor implements OutputCompressor { private static final String ZLIB = "1.2.840.113549.1.9.16.3.8"; public AlgorithmIdentifier getAlgorithmIdentifier() { return new AlgorithmIdentifier(new ASN1ObjectIdentifier(ZLIB)); } public OutputStream getOutputStream(OutputStream comOut) { return new DeflaterOutputStream(comOut); } } bouncycastle-1.49.orig/src/org/bouncycastle/cms/jcajce/JcePasswordRecipientInfoGenerator.java0000644000175000017500000000421511723553745032136 0ustar ebourgebourgpackage org.bouncycastle.cms.jcajce; import java.security.GeneralSecurityException; import java.security.Key; import java.security.Provider; import javax.crypto.Cipher; import javax.crypto.spec.IvParameterSpec; import javax.crypto.spec.SecretKeySpec; import org.bouncycastle.asn1.ASN1ObjectIdentifier; import org.bouncycastle.asn1.ASN1OctetString; import org.bouncycastle.asn1.x509.AlgorithmIdentifier; import org.bouncycastle.cms.CMSException; import org.bouncycastle.cms.PasswordRecipientInfoGenerator; import org.bouncycastle.operator.GenericKey; public class JcePasswordRecipientInfoGenerator extends PasswordRecipientInfoGenerator { private EnvelopedDataHelper helper = new EnvelopedDataHelper(new DefaultJcaJceExtHelper()); public JcePasswordRecipientInfoGenerator(ASN1ObjectIdentifier kekAlgorithm, char[] password) { super(kekAlgorithm, password); } public JcePasswordRecipientInfoGenerator setProvider(Provider provider) { this.helper = new EnvelopedDataHelper(new ProviderJcaJceExtHelper(provider)); return this; } public JcePasswordRecipientInfoGenerator setProvider(String providerName) { this.helper = new EnvelopedDataHelper(new NamedJcaJceExtHelper(providerName)); return this; } public byte[] generateEncryptedBytes(AlgorithmIdentifier keyEncryptionAlgorithm, byte[] derivedKey, GenericKey contentEncryptionKey) throws CMSException { Key contentEncryptionKeySpec = helper.getJceKey(contentEncryptionKey); Cipher keyEncryptionCipher = helper.createRFC3211Wrapper(keyEncryptionAlgorithm.getAlgorithm()); try { IvParameterSpec ivSpec = new IvParameterSpec(ASN1OctetString.getInstance(keyEncryptionAlgorithm.getParameters()).getOctets()); keyEncryptionCipher.init(Cipher.WRAP_MODE, new SecretKeySpec(derivedKey, keyEncryptionCipher.getAlgorithm()), ivSpec); return keyEncryptionCipher.wrap(contentEncryptionKeySpec); } catch (GeneralSecurityException e) { throw new CMSException("cannot process content encryption key: " + e.getMessage(), e); } } }bouncycastle-1.49.orig/src/org/bouncycastle/cms/jcajce/JcaSignerInfoGeneratorBuilder.java0000644000175000017500000000443711510520555031214 0ustar ebourgebourgpackage org.bouncycastle.cms.jcajce; import java.security.cert.CertificateEncodingException; import java.security.cert.X509Certificate; import org.bouncycastle.cert.X509CertificateHolder; import org.bouncycastle.cert.jcajce.JcaX509CertificateHolder; import org.bouncycastle.cms.CMSAttributeTableGenerator; import org.bouncycastle.cms.SignerInfoGenerator; import org.bouncycastle.cms.SignerInfoGeneratorBuilder; import org.bouncycastle.operator.ContentSigner; import org.bouncycastle.operator.DigestCalculatorProvider; import org.bouncycastle.operator.OperatorCreationException; public class JcaSignerInfoGeneratorBuilder { private SignerInfoGeneratorBuilder builder; public JcaSignerInfoGeneratorBuilder(DigestCalculatorProvider digestProvider) { builder = new SignerInfoGeneratorBuilder(digestProvider); } /** * If the passed in flag is true, the signer signature will be based on the data, not * a collection of signed attributes, and no signed attributes will be included. * * @return the builder object */ public JcaSignerInfoGeneratorBuilder setDirectSignature(boolean hasNoSignedAttributes) { builder.setDirectSignature(hasNoSignedAttributes); return this; } public JcaSignerInfoGeneratorBuilder setSignedAttributeGenerator(CMSAttributeTableGenerator signedGen) { builder.setSignedAttributeGenerator(signedGen); return this; } public JcaSignerInfoGeneratorBuilder setUnsignedAttributeGenerator(CMSAttributeTableGenerator unsignedGen) { builder.setUnsignedAttributeGenerator(unsignedGen); return this; } public SignerInfoGenerator build(ContentSigner contentSigner, X509CertificateHolder certHolder) throws OperatorCreationException { return builder.build(contentSigner, certHolder); } public SignerInfoGenerator build(ContentSigner contentSigner, byte[] keyIdentifier) throws OperatorCreationException { return builder.build(contentSigner, keyIdentifier); } public SignerInfoGenerator build(ContentSigner contentSigner, X509Certificate certificate) throws OperatorCreationException, CertificateEncodingException { return this.build(contentSigner, new JcaX509CertificateHolder(certificate)); } } bouncycastle-1.49.orig/src/org/bouncycastle/cms/jcajce/JceKeyAgreeRecipientId.java0000644000175000017500000000121111507223636027604 0ustar ebourgebourgpackage org.bouncycastle.cms.jcajce; import java.math.BigInteger; import java.security.cert.X509Certificate; import javax.security.auth.x500.X500Principal; import org.bouncycastle.asn1.x500.X500Name; import org.bouncycastle.cms.KeyAgreeRecipientId; public class JceKeyAgreeRecipientId extends KeyAgreeRecipientId { public JceKeyAgreeRecipientId(X509Certificate certificate) { this(certificate.getIssuerX500Principal(), certificate.getSerialNumber()); } public JceKeyAgreeRecipientId(X500Principal issuer, BigInteger serialNumber) { super(X500Name.getInstance(issuer.getEncoded()), serialNumber); } } bouncycastle-1.49.orig/src/org/bouncycastle/cms/jcajce/JceKEKRecipientInfoGenerator.java0000644000175000017500000000242111504001347030722 0ustar ebourgebourgpackage org.bouncycastle.cms.jcajce; import java.security.Provider; import java.security.SecureRandom; import javax.crypto.SecretKey; import org.bouncycastle.asn1.cms.KEKIdentifier; import org.bouncycastle.cms.KEKRecipientInfoGenerator; import org.bouncycastle.operator.jcajce.JceSymmetricKeyWrapper; public class JceKEKRecipientInfoGenerator extends KEKRecipientInfoGenerator { public JceKEKRecipientInfoGenerator(KEKIdentifier kekIdentifier, SecretKey keyEncryptionKey) { super(kekIdentifier, new JceSymmetricKeyWrapper(keyEncryptionKey)); } public JceKEKRecipientInfoGenerator(byte[] keyIdentifier, SecretKey keyEncryptionKey) { this(new KEKIdentifier(keyIdentifier, null, null), keyEncryptionKey); } public JceKEKRecipientInfoGenerator setProvider(Provider provider) { ((JceSymmetricKeyWrapper)this.wrapper).setProvider(provider); return this; } public JceKEKRecipientInfoGenerator setProvider(String providerName) { ((JceSymmetricKeyWrapper)this.wrapper).setProvider(providerName); return this; } public JceKEKRecipientInfoGenerator setSecureRandom(SecureRandom random) { ((JceSymmetricKeyWrapper)this.wrapper).setSecureRandom(random); return this; } } bouncycastle-1.49.orig/src/org/bouncycastle/cms/jcajce/JceKeyTransRecipientInfoGenerator.java0000644000175000017500000000435611714337313032071 0ustar ebourgebourgpackage org.bouncycastle.cms.jcajce; import java.security.Provider; import java.security.PublicKey; import java.security.cert.CertificateEncodingException; import java.security.cert.X509Certificate; import org.bouncycastle.asn1.ASN1ObjectIdentifier; import org.bouncycastle.asn1.cms.IssuerAndSerialNumber; import org.bouncycastle.cert.jcajce.JcaX509CertificateHolder; import org.bouncycastle.cms.KeyTransRecipientInfoGenerator; import org.bouncycastle.operator.jcajce.JceAsymmetricKeyWrapper; public class JceKeyTransRecipientInfoGenerator extends KeyTransRecipientInfoGenerator { public JceKeyTransRecipientInfoGenerator(X509Certificate recipientCert) throws CertificateEncodingException { super(new IssuerAndSerialNumber(new JcaX509CertificateHolder(recipientCert).toASN1Structure()), new JceAsymmetricKeyWrapper(recipientCert.getPublicKey())); } public JceKeyTransRecipientInfoGenerator(byte[] subjectKeyIdentifier, PublicKey publicKey) { super(subjectKeyIdentifier, new JceAsymmetricKeyWrapper(publicKey)); } public JceKeyTransRecipientInfoGenerator setProvider(String providerName) { ((JceAsymmetricKeyWrapper)this.wrapper).setProvider(providerName); return this; } public JceKeyTransRecipientInfoGenerator setProvider(Provider provider) { ((JceAsymmetricKeyWrapper)this.wrapper).setProvider(provider); return this; } /** * Internally algorithm ids are converted into cipher names using a lookup table. For some providers * the standard lookup table won't work. Use this method to establish a specific mapping from an * algorithm identifier to a specific algorithm. *

    * For example: *

         *     unwrapper.setAlgorithmMapping(PKCSObjectIdentifiers.rsaEncryption, "RSA");
         * 
    *

    * @param algorithm OID of algorithm in recipient. * @param algorithmName JCE algorithm name to use. * @return the current RecipientInfoGenerator. */ public JceKeyTransRecipientInfoGenerator setAlgorithmMapping(ASN1ObjectIdentifier algorithm, String algorithmName) { ((JceAsymmetricKeyWrapper)this.wrapper).setAlgorithmMapping(algorithm, algorithmName); return this; } }bouncycastle-1.49.orig/src/org/bouncycastle/cms/jcajce/JceKeyAgreeEnvelopedRecipient.java0000644000175000017500000000312011504015246031163 0ustar ebourgebourgpackage org.bouncycastle.cms.jcajce; import java.io.InputStream; import java.security.Key; import java.security.PrivateKey; import javax.crypto.Cipher; import javax.crypto.CipherInputStream; import org.bouncycastle.asn1.ASN1OctetString; import org.bouncycastle.asn1.x509.AlgorithmIdentifier; import org.bouncycastle.asn1.x509.SubjectPublicKeyInfo; import org.bouncycastle.cms.CMSException; import org.bouncycastle.cms.RecipientOperator; import org.bouncycastle.operator.InputDecryptor; public class JceKeyAgreeEnvelopedRecipient extends JceKeyAgreeRecipient { public JceKeyAgreeEnvelopedRecipient(PrivateKey recipientKey) { super(recipientKey); } public RecipientOperator getRecipientOperator(AlgorithmIdentifier keyEncryptionAlgorithm, final AlgorithmIdentifier contentEncryptionAlgorithm, SubjectPublicKeyInfo senderPublicKey, ASN1OctetString userKeyingMaterial, byte[] encryptedContentKey) throws CMSException { Key secretKey = extractSecretKey(keyEncryptionAlgorithm, contentEncryptionAlgorithm, senderPublicKey, userKeyingMaterial, encryptedContentKey); final Cipher dataCipher = contentHelper.createContentCipher(secretKey, contentEncryptionAlgorithm); return new RecipientOperator(new InputDecryptor() { public AlgorithmIdentifier getAlgorithmIdentifier() { return contentEncryptionAlgorithm; } public InputStream getInputStream(InputStream dataOut) { return new CipherInputStream(dataOut, dataCipher); } }); } } bouncycastle-1.49.orig/src/org/bouncycastle/cms/jcajce/JcePasswordAuthenticatedRecipient.java0000644000175000017500000000325011737175743032157 0ustar ebourgebourgpackage org.bouncycastle.cms.jcajce; import java.io.OutputStream; import java.security.Key; import javax.crypto.Mac; import org.bouncycastle.asn1.x509.AlgorithmIdentifier; import org.bouncycastle.cms.CMSException; import org.bouncycastle.cms.RecipientOperator; import org.bouncycastle.jcajce.io.MacOutputStream; import org.bouncycastle.operator.GenericKey; import org.bouncycastle.operator.MacCalculator; import org.bouncycastle.operator.jcajce.JceGenericKey; public class JcePasswordAuthenticatedRecipient extends JcePasswordRecipient { public JcePasswordAuthenticatedRecipient(char[] password) { super(password); } public RecipientOperator getRecipientOperator(AlgorithmIdentifier keyEncryptionAlgorithm, final AlgorithmIdentifier contentMacAlgorithm, byte[] derivedKey, byte[] encryptedContentEncryptionKey) throws CMSException { final Key secretKey = extractSecretKey(keyEncryptionAlgorithm, contentMacAlgorithm, derivedKey, encryptedContentEncryptionKey); final Mac dataMac = helper.createContentMac(secretKey, contentMacAlgorithm); return new RecipientOperator(new MacCalculator() { public AlgorithmIdentifier getAlgorithmIdentifier() { return contentMacAlgorithm; } public GenericKey getKey() { return new JceGenericKey(contentMacAlgorithm, secretKey); } public OutputStream getOutputStream() { return new MacOutputStream(dataMac); } public byte[] getMac() { return dataMac.doFinal(); } }); } } bouncycastle-1.49.orig/src/org/bouncycastle/cms/jcajce/JcaSimpleSignerInfoGeneratorBuilder.java0000644000175000017500000001525211473371134032370 0ustar ebourgebourgpackage org.bouncycastle.cms.jcajce; import java.security.PrivateKey; import java.security.Provider; import java.security.cert.CertificateEncodingException; import java.security.cert.X509Certificate; import org.bouncycastle.asn1.cms.AttributeTable; import org.bouncycastle.cert.jcajce.JcaX509CertificateHolder; import org.bouncycastle.cms.CMSAttributeTableGenerator; import org.bouncycastle.cms.DefaultSignedAttributeTableGenerator; import org.bouncycastle.cms.SignerInfoGenerator; import org.bouncycastle.cms.SignerInfoGeneratorBuilder; import org.bouncycastle.operator.ContentSigner; import org.bouncycastle.operator.DigestCalculatorProvider; import org.bouncycastle.operator.OperatorCreationException; import org.bouncycastle.operator.jcajce.JcaContentSignerBuilder; import org.bouncycastle.operator.jcajce.JcaDigestCalculatorProviderBuilder; /** * Use this class if you are using a provider that has all the facilities you * need. *

    * For example: *

     *      CMSSignedDataGenerator gen = new CMSSignedDataGenerator();
     *      ContentSigner sha1Signer = new JcaContentSignerBuilder("SHA1withRSA").setProvider("BC").build(signKP.getPrivate());
     *
     *      gen.addSignerInfoGenerator(
     *                new JcaSignerInfoGeneratorBuilder(
     *                     new JcaDigestCalculatorProviderBuilder().setProvider("BC").build())
     *                     .build(sha1Signer, signCert));
     * 
    * becomes: *
     *      CMSSignedDataGenerator gen = new CMSSignedDataGenerator();
     *
     *      gen.addSignerInfoGenerator(
     *                new JcaSimpleSignerInfoGeneratorBuilder()
     *                     .setProvider("BC")
     *                     .build("SHA1withRSA", signKP.getPrivate(), signCert));
     * 
    */ public class JcaSimpleSignerInfoGeneratorBuilder { private Helper helper; private boolean hasNoSignedAttributes; private CMSAttributeTableGenerator signedGen; private CMSAttributeTableGenerator unsignedGen; public JcaSimpleSignerInfoGeneratorBuilder() throws OperatorCreationException { this.helper = new Helper(); } public JcaSimpleSignerInfoGeneratorBuilder setProvider(String providerName) throws OperatorCreationException { this.helper = new NamedHelper(providerName); return this; } public JcaSimpleSignerInfoGeneratorBuilder setProvider(Provider provider) throws OperatorCreationException { this.helper = new ProviderHelper(provider); return this; } /** * If the passed in flag is true, the signer signature will be based on the data, not * a collection of signed attributes, and no signed attributes will be included. * * @return the builder object */ public JcaSimpleSignerInfoGeneratorBuilder setDirectSignature(boolean hasNoSignedAttributes) { this.hasNoSignedAttributes = hasNoSignedAttributes; return this; } public JcaSimpleSignerInfoGeneratorBuilder setSignedAttributeGenerator(CMSAttributeTableGenerator signedGen) { this.signedGen = signedGen; return this; } /** * set up a DefaultSignedAttributeTableGenerator primed with the passed in AttributeTable. * * @param attrTable table of attributes for priming generator * @return this. */ public JcaSimpleSignerInfoGeneratorBuilder setSignedAttributeGenerator(AttributeTable attrTable) { this.signedGen = new DefaultSignedAttributeTableGenerator(attrTable); return this; } public JcaSimpleSignerInfoGeneratorBuilder setUnsignedAttributeGenerator(CMSAttributeTableGenerator unsignedGen) { this.unsignedGen = unsignedGen; return this; } public SignerInfoGenerator build(String algorithmName, PrivateKey privateKey, X509Certificate certificate) throws OperatorCreationException, CertificateEncodingException { ContentSigner contentSigner = helper.createContentSigner(algorithmName, privateKey); return configureAndBuild().build(contentSigner, new JcaX509CertificateHolder(certificate)); } public SignerInfoGenerator build(String algorithmName, PrivateKey privateKey, byte[] keyIdentifier) throws OperatorCreationException, CertificateEncodingException { ContentSigner contentSigner = helper.createContentSigner(algorithmName, privateKey); return configureAndBuild().build(contentSigner, keyIdentifier); } private SignerInfoGeneratorBuilder configureAndBuild() throws OperatorCreationException { SignerInfoGeneratorBuilder infoGeneratorBuilder = new SignerInfoGeneratorBuilder(helper.createDigestCalculatorProvider()); infoGeneratorBuilder.setDirectSignature(hasNoSignedAttributes); infoGeneratorBuilder.setSignedAttributeGenerator(signedGen); infoGeneratorBuilder.setUnsignedAttributeGenerator(unsignedGen); return infoGeneratorBuilder; } private class Helper { ContentSigner createContentSigner(String algorithm, PrivateKey privateKey) throws OperatorCreationException { return new JcaContentSignerBuilder(algorithm).build(privateKey); } DigestCalculatorProvider createDigestCalculatorProvider() throws OperatorCreationException { return new JcaDigestCalculatorProviderBuilder().build(); } } private class NamedHelper extends Helper { private final String providerName; public NamedHelper(String providerName) { this.providerName = providerName; } ContentSigner createContentSigner(String algorithm, PrivateKey privateKey) throws OperatorCreationException { return new JcaContentSignerBuilder(algorithm).setProvider(providerName).build(privateKey); } DigestCalculatorProvider createDigestCalculatorProvider() throws OperatorCreationException { return new JcaDigestCalculatorProviderBuilder().setProvider(providerName).build(); } } private class ProviderHelper extends Helper { private final Provider provider; public ProviderHelper(Provider provider) { this.provider = provider; } ContentSigner createContentSigner(String algorithm, PrivateKey privateKey) throws OperatorCreationException { return new JcaContentSignerBuilder(algorithm).setProvider(provider).build(privateKey); } DigestCalculatorProvider createDigestCalculatorProvider() throws OperatorCreationException { return new JcaDigestCalculatorProviderBuilder().setProvider(provider).build(); } } } bouncycastle-1.49.orig/src/org/bouncycastle/cms/jcajce/JcePasswordEnvelopedRecipient.java0000644000175000017500000000257211442065640031307 0ustar ebourgebourgpackage org.bouncycastle.cms.jcajce; import java.io.InputStream; import java.security.Key; import javax.crypto.Cipher; import javax.crypto.CipherInputStream; import org.bouncycastle.asn1.x509.AlgorithmIdentifier; import org.bouncycastle.cms.CMSException; import org.bouncycastle.cms.RecipientOperator; import org.bouncycastle.operator.InputDecryptor; public class JcePasswordEnvelopedRecipient extends JcePasswordRecipient { public JcePasswordEnvelopedRecipient(char[] password) { super(password); } public RecipientOperator getRecipientOperator(AlgorithmIdentifier keyEncryptionAlgorithm, final AlgorithmIdentifier contentEncryptionAlgorithm, byte[] derivedKey, byte[] encryptedContentEncryptionKey) throws CMSException { Key secretKey = extractSecretKey(keyEncryptionAlgorithm, contentEncryptionAlgorithm, derivedKey, encryptedContentEncryptionKey); final Cipher dataCipher = helper.createContentCipher(secretKey, contentEncryptionAlgorithm); return new RecipientOperator(new InputDecryptor() { public AlgorithmIdentifier getAlgorithmIdentifier() { return contentEncryptionAlgorithm; } public InputStream getInputStream(InputStream dataOut) { return new CipherInputStream(dataOut, dataCipher); } }); } } bouncycastle-1.49.orig/src/org/bouncycastle/cms/jcajce/JceKEKAuthenticatedRecipient.java0000644000175000017500000000354211737175743030773 0ustar ebourgebourgpackage org.bouncycastle.cms.jcajce; import java.io.OutputStream; import java.security.Key; import javax.crypto.Mac; import javax.crypto.SecretKey; import org.bouncycastle.asn1.x509.AlgorithmIdentifier; import org.bouncycastle.cms.CMSException; import org.bouncycastle.cms.RecipientOperator; import org.bouncycastle.jcajce.io.MacOutputStream; import org.bouncycastle.operator.GenericKey; import org.bouncycastle.operator.MacCalculator; import org.bouncycastle.operator.jcajce.JceGenericKey; /** * the KeyTransRecipientInformation class for a recipient who has been sent a secret * key encrypted using their public key that needs to be used to * extract the message. */ public class JceKEKAuthenticatedRecipient extends JceKEKRecipient { public JceKEKAuthenticatedRecipient(SecretKey recipientKey) { super(recipientKey); } public RecipientOperator getRecipientOperator(AlgorithmIdentifier keyEncryptionAlgorithm, final AlgorithmIdentifier contentMacAlgorithm, byte[] encryptedContentEncryptionKey) throws CMSException { final Key secretKey = extractSecretKey(keyEncryptionAlgorithm, contentMacAlgorithm, encryptedContentEncryptionKey); final Mac dataMac = contentHelper.createContentMac(secretKey, contentMacAlgorithm); return new RecipientOperator(new MacCalculator() { public AlgorithmIdentifier getAlgorithmIdentifier() { return contentMacAlgorithm; } public GenericKey getKey() { return new JceGenericKey(contentMacAlgorithm, secretKey); } public OutputStream getOutputStream() { return new MacOutputStream(dataMac); } public byte[] getMac() { return dataMac.doFinal(); } }); } } bouncycastle-1.49.orig/src/org/bouncycastle/cms/jcajce/JcaSelectorConverter.java0000644000175000017500000000350011726521301027430 0ustar ebourgebourgpackage org.bouncycastle.cms.jcajce; import java.io.IOException; import java.security.cert.X509CertSelector; import org.bouncycastle.asn1.ASN1OctetString; import org.bouncycastle.asn1.x500.X500Name; import org.bouncycastle.cms.KeyTransRecipientId; import org.bouncycastle.cms.SignerId; public class JcaSelectorConverter { public JcaSelectorConverter() { } public SignerId getSignerId(X509CertSelector certSelector) { try { if (certSelector.getSubjectKeyIdentifier() != null) { return new SignerId(X500Name.getInstance(certSelector.getIssuerAsBytes()), certSelector.getSerialNumber(), ASN1OctetString.getInstance(certSelector.getSubjectKeyIdentifier()).getOctets()); } else { return new SignerId(X500Name.getInstance(certSelector.getIssuerAsBytes()), certSelector.getSerialNumber()); } } catch (IOException e) { throw new IllegalArgumentException("unable to convert issuer: " + e.getMessage()); } } public KeyTransRecipientId getKeyTransRecipientId(X509CertSelector certSelector) { try { if (certSelector.getSubjectKeyIdentifier() != null) { return new KeyTransRecipientId(X500Name.getInstance(certSelector.getIssuerAsBytes()), certSelector.getSerialNumber(), ASN1OctetString.getInstance(certSelector.getSubjectKeyIdentifier()).getOctets()); } else { return new KeyTransRecipientId(X500Name.getInstance(certSelector.getIssuerAsBytes()), certSelector.getSerialNumber()); } } catch (IOException e) { throw new IllegalArgumentException("unable to convert issuer: " + e.getMessage()); } } } bouncycastle-1.49.orig/src/org/bouncycastle/cms/KeyAgreeRecipient.java0000644000175000017500000000106411442065637025477 0ustar ebourgebourgpackage org.bouncycastle.cms; import org.bouncycastle.asn1.ASN1OctetString; import org.bouncycastle.asn1.x509.AlgorithmIdentifier; import org.bouncycastle.asn1.x509.SubjectPublicKeyInfo; public interface KeyAgreeRecipient extends Recipient { RecipientOperator getRecipientOperator(AlgorithmIdentifier keyEncAlg, AlgorithmIdentifier contentEncryptionAlgorithm, SubjectPublicKeyInfo senderPublicKey, ASN1OctetString userKeyingMaterial, byte[] encryptedContentKey) throws CMSException; AlgorithmIdentifier getPrivateKeyAlgorithmIdentifier(); } bouncycastle-1.49.orig/src/org/bouncycastle/cms/RecipientInformation.java0000644000175000017500000002065212103446476026273 0ustar ebourgebourgpackage org.bouncycastle.cms; import java.io.ByteArrayInputStream; import java.io.IOException; import java.security.AlgorithmParameters; import java.security.Key; import java.security.NoSuchProviderException; import java.security.Provider; import org.bouncycastle.asn1.ASN1Encodable; import org.bouncycastle.asn1.ASN1Encoding; import org.bouncycastle.asn1.x509.AlgorithmIdentifier; import org.bouncycastle.cms.jcajce.JceAlgorithmIdentifierConverter; import org.bouncycastle.util.io.Streams; public abstract class RecipientInformation { protected RecipientId rid; protected AlgorithmIdentifier keyEncAlg; protected AlgorithmIdentifier messageAlgorithm; protected CMSSecureReadable secureReadable; private AuthAttributesProvider additionalData; private byte[] resultMac; private RecipientOperator operator; RecipientInformation( AlgorithmIdentifier keyEncAlg, AlgorithmIdentifier messageAlgorithm, CMSSecureReadable secureReadable, AuthAttributesProvider additionalData) { this.keyEncAlg = keyEncAlg; this.messageAlgorithm = messageAlgorithm; this.secureReadable = secureReadable; this.additionalData = additionalData; } public RecipientId getRID() { return rid; } private byte[] encodeObj( ASN1Encodable obj) throws IOException { if (obj != null) { return obj.toASN1Primitive().getEncoded(); } return null; } /** * Return the key encryption algorithm details for the key in this recipient. * * @return AlgorithmIdentifier representing the key encryption algorithm. */ public AlgorithmIdentifier getKeyEncryptionAlgorithm() { return keyEncAlg; } /** * return the object identifier for the key encryption algorithm. * * @return OID for key encryption algorithm. */ public String getKeyEncryptionAlgOID() { return keyEncAlg.getObjectId().getId(); } /** * return the ASN.1 encoded key encryption algorithm parameters, or null if * there aren't any. * * @return ASN.1 encoding of key encryption algorithm parameters. */ public byte[] getKeyEncryptionAlgParams() { try { return encodeObj(keyEncAlg.getParameters()); } catch (Exception e) { throw new RuntimeException("exception getting encryption parameters " + e); } } /** * Return an AlgorithmParameters object giving the encryption parameters * used to encrypt the key this recipient holds. * * @param provider the provider to generate the parameters for. * @return the parameters object, null if there is not one. * @throws CMSException if the algorithm cannot be found, or the parameters can't be parsed. * @throws NoSuchProviderException if the provider cannot be found. * @deprecated use getKeyEncryptionAlgorithm and JceAlgorithmIdentifierConverter(). */ public AlgorithmParameters getKeyEncryptionAlgorithmParameters( String provider) throws CMSException, NoSuchProviderException { return new JceAlgorithmIdentifierConverter().setProvider(provider).getAlgorithmParameters(keyEncAlg); } /** * Return an AlgorithmParameters object giving the encryption parameters * used to encrypt the key this recipient holds. * * @param provider the provider to generate the parameters for. * @return the parameters object, null if there is not one. * @throws CMSException if the algorithm cannot be found, or the parameters can't be parsed. * @deprecated use getKeyEncryptionAlgorithm and JceAlgorithmIdentifierConverter(). */ public AlgorithmParameters getKeyEncryptionAlgorithmParameters( Provider provider) throws CMSException { return new JceAlgorithmIdentifierConverter().setProvider(provider).getAlgorithmParameters(keyEncAlg); } /** * @deprecated use getContent(Recipient) */ public byte[] getContent( Key key, String provider) throws CMSException, NoSuchProviderException { return getContent(key, CMSUtils.getProvider(provider)); } /** * @deprecated use getContent(Recipient) */ public byte[] getContent( Key key, Provider provider) throws CMSException { try { return CMSUtils.streamToByteArray(getContentStream(key, provider).getContentStream()); } catch (IOException e) { throw new RuntimeException("unable to parse internal stream: " + e); } } /** * Return the content digest calculated during the read of the content if one has been generated. This will * only happen if we are dealing with authenticated data and authenticated attributes are present. * * @return byte array containing the digest. */ public byte[] getContentDigest() { if (secureReadable instanceof CMSEnvelopedHelper.CMSDigestAuthenticatedSecureReadable) { return ((CMSEnvelopedHelper.CMSDigestAuthenticatedSecureReadable)secureReadable).getDigest(); } return null; } /** * Return the MAC calculated for the recipient. Note: this call is only meaningful once all * the content has been read. * * @return byte array containing the mac. */ public byte[] getMac() { if (resultMac == null) { if (operator.isMacBased()) { if (additionalData != null) { try { Streams.drain(operator.getInputStream(new ByteArrayInputStream(additionalData.getAuthAttributes().getEncoded(ASN1Encoding.DER)))); } catch (IOException e) { throw new IllegalStateException("unable to drain input: " + e.getMessage()); } } resultMac = operator.getMac(); } } return resultMac; } /** * Return the decrypted/encapsulated content in the EnvelopedData after recovering the content * encryption/MAC key using the passed in Recipient. * * @param recipient recipient object to use to recover content encryption key * @return the content inside the EnvelopedData this RecipientInformation is associated with. * @throws CMSException if the content-encryption/MAC key cannot be recovered. */ public byte[] getContent( Recipient recipient) throws CMSException { try { return CMSUtils.streamToByteArray(getContentStream(recipient).getContentStream()); } catch (IOException e) { throw new CMSException("unable to parse internal stream: " + e.getMessage(), e); } } /** * decrypt the content and return it * @deprecated use getContentStream(Recipient) method */ public CMSTypedStream getContentStream(Key key, String provider) throws CMSException, NoSuchProviderException { return getContentStream(key, CMSUtils.getProvider(provider)); } /** * decrypt the content and return it * @deprecated use getContentStream(Recipient) method */ public abstract CMSTypedStream getContentStream(Key key, Provider provider) throws CMSException; /** * Return a CMSTypedStream representing the content in the EnvelopedData after recovering the content * encryption/MAC key using the passed in Recipient. * * @param recipient recipient object to use to recover content encryption key * @return the content inside the EnvelopedData this RecipientInformation is associated with. * @throws CMSException if the content-encryption/MAC key cannot be recovered. */ public CMSTypedStream getContentStream(Recipient recipient) throws CMSException, IOException { operator = getRecipientOperator(recipient); if (additionalData != null) { return new CMSTypedStream(secureReadable.getInputStream()); } return new CMSTypedStream(operator.getInputStream(secureReadable.getInputStream())); } protected abstract RecipientOperator getRecipientOperator(Recipient recipient) throws CMSException, IOException; } bouncycastle-1.49.orig/src/org/bouncycastle/cms/CMSProcessableByteArray.java0000644000175000017500000000231411732524151026560 0ustar ebourgebourgpackage org.bouncycastle.cms; import java.io.ByteArrayInputStream; import java.io.IOException; import java.io.InputStream; import java.io.OutputStream; import org.bouncycastle.asn1.ASN1ObjectIdentifier; import org.bouncycastle.asn1.cms.CMSObjectIdentifiers; import org.bouncycastle.util.Arrays; /** * a holding class for a byte array of data to be processed. */ public class CMSProcessableByteArray implements CMSTypedData, CMSReadable { private final ASN1ObjectIdentifier type; private final byte[] bytes; public CMSProcessableByteArray( byte[] bytes) { this(new ASN1ObjectIdentifier(CMSObjectIdentifiers.data.getId()), bytes); } public CMSProcessableByteArray( ASN1ObjectIdentifier type, byte[] bytes) { this.type = type; this.bytes = bytes; } public InputStream getInputStream() { return new ByteArrayInputStream(bytes); } public void write(OutputStream zOut) throws IOException, CMSException { zOut.write(bytes); } public Object getContent() { return Arrays.clone(bytes); } public ASN1ObjectIdentifier getContentType() { return type; } } bouncycastle-1.49.orig/src/org/bouncycastle/cms/KeyTransRecipientInfoGenerator.java0000644000175000017500000000362511503775651030235 0ustar ebourgebourgpackage org.bouncycastle.cms; import org.bouncycastle.asn1.DEROctetString; import org.bouncycastle.asn1.cms.IssuerAndSerialNumber; import org.bouncycastle.asn1.cms.KeyTransRecipientInfo; import org.bouncycastle.asn1.cms.RecipientIdentifier; import org.bouncycastle.asn1.cms.RecipientInfo; import org.bouncycastle.operator.AsymmetricKeyWrapper; import org.bouncycastle.operator.GenericKey; import org.bouncycastle.operator.OperatorException; public abstract class KeyTransRecipientInfoGenerator implements RecipientInfoGenerator { protected final AsymmetricKeyWrapper wrapper; private IssuerAndSerialNumber issuerAndSerial; private byte[] subjectKeyIdentifier; protected KeyTransRecipientInfoGenerator(IssuerAndSerialNumber issuerAndSerial, AsymmetricKeyWrapper wrapper) { this.issuerAndSerial = issuerAndSerial; this.wrapper = wrapper; } protected KeyTransRecipientInfoGenerator(byte[] subjectKeyIdentifier, AsymmetricKeyWrapper wrapper) { this.subjectKeyIdentifier = subjectKeyIdentifier; this.wrapper = wrapper; } public final RecipientInfo generate(GenericKey contentEncryptionKey) throws CMSException { byte[] encryptedKeyBytes; try { encryptedKeyBytes = wrapper.generateWrappedKey(contentEncryptionKey); } catch (OperatorException e) { throw new CMSException("exception wrapping content key: " + e.getMessage(), e); } RecipientIdentifier recipId; if (issuerAndSerial != null) { recipId = new RecipientIdentifier(issuerAndSerial); } else { recipId = new RecipientIdentifier(new DEROctetString(subjectKeyIdentifier)); } return new RecipientInfo(new KeyTransRecipientInfo(recipId, wrapper.getAlgorithmIdentifier(), new DEROctetString(encryptedKeyBytes))); } }bouncycastle-1.49.orig/src/org/bouncycastle/cms/KeyTransRecipient.java0000644000175000017500000000050711442065637025544 0ustar ebourgebourgpackage org.bouncycastle.cms; import org.bouncycastle.asn1.x509.AlgorithmIdentifier; public interface KeyTransRecipient extends Recipient { RecipientOperator getRecipientOperator(AlgorithmIdentifier keyEncAlg, AlgorithmIdentifier contentEncryptionAlgorithm, byte[] encryptedContentKey) throws CMSException; } bouncycastle-1.49.orig/src/org/bouncycastle/cms/AuthAttributesProvider.java0000644000175000017500000000021411530577645026624 0ustar ebourgebourgpackage org.bouncycastle.cms; import org.bouncycastle.asn1.ASN1Set; interface AuthAttributesProvider { ASN1Set getAuthAttributes(); } bouncycastle-1.49.orig/src/org/bouncycastle/cms/CMSEnvelopedData.java0000644000175000017500000001666011726036241025220 0ustar ebourgebourgpackage org.bouncycastle.cms; import java.io.IOException; import java.io.InputStream; import java.security.AlgorithmParameters; import java.security.NoSuchProviderException; import java.security.Provider; import org.bouncycastle.asn1.ASN1Encodable; import org.bouncycastle.asn1.ASN1Set; import org.bouncycastle.asn1.cms.AttributeTable; import org.bouncycastle.asn1.cms.ContentInfo; import org.bouncycastle.asn1.cms.EncryptedContentInfo; import org.bouncycastle.asn1.cms.EnvelopedData; import org.bouncycastle.asn1.x509.AlgorithmIdentifier; import org.bouncycastle.cms.jcajce.JceAlgorithmIdentifierConverter; /** * containing class for an CMS Enveloped Data object *

    * Example of use - assuming the first recipient matches the private key we have. *

     *      CMSEnvelopedData     ed = new CMSEnvelopedData(inputStream);
     *
     *      RecipientInformationStore  recipients = ed.getRecipientInfos();
     *
     *      Collection  c = recipients.getRecipients();
     *      Iterator    it = c.iterator();
     *
     *      if (it.hasNext())
     *      {
     *          RecipientInformation   recipient = (RecipientInformation)it.next();
     *
     *          byte[] recData = recipient.getContent(new JceKeyTransEnvelopedRecipient(privateKey).setProvider("BC"));
     *
     *          processData(recData);
     *      }
     *  
    */ public class CMSEnvelopedData { RecipientInformationStore recipientInfoStore; ContentInfo contentInfo; private AlgorithmIdentifier encAlg; private ASN1Set unprotectedAttributes; private OriginatorInformation originatorInfo; public CMSEnvelopedData( byte[] envelopedData) throws CMSException { this(CMSUtils.readContentInfo(envelopedData)); } public CMSEnvelopedData( InputStream envelopedData) throws CMSException { this(CMSUtils.readContentInfo(envelopedData)); } /** * Construct a CMSEnvelopedData object from a content info object. * * @param contentInfo the contentInfo containing the CMS EnvelopedData object. * @throws CMSException in the case where malformed content is encountered. */ public CMSEnvelopedData( ContentInfo contentInfo) throws CMSException { this.contentInfo = contentInfo; try { EnvelopedData envData = EnvelopedData.getInstance(contentInfo.getContent()); if (envData.getOriginatorInfo() != null) { originatorInfo = new OriginatorInformation(envData.getOriginatorInfo()); } // // read the recipients // ASN1Set recipientInfos = envData.getRecipientInfos(); // // read the encrypted content info // EncryptedContentInfo encInfo = envData.getEncryptedContentInfo(); this.encAlg = encInfo.getContentEncryptionAlgorithm(); CMSReadable readable = new CMSProcessableByteArray(encInfo.getEncryptedContent().getOctets()); CMSSecureReadable secureReadable = new CMSEnvelopedHelper.CMSEnvelopedSecureReadable( this.encAlg, readable); // // build the RecipientInformationStore // this.recipientInfoStore = CMSEnvelopedHelper.buildRecipientInformationStore( recipientInfos, this.encAlg, secureReadable); this.unprotectedAttributes = envData.getUnprotectedAttrs(); } catch (ClassCastException e) { throw new CMSException("Malformed content.", e); } catch (IllegalArgumentException e) { throw new CMSException("Malformed content.", e); } } private byte[] encodeObj( ASN1Encodable obj) throws IOException { if (obj != null) { return obj.toASN1Primitive().getEncoded(); } return null; } /** * Return the originator information associated with this message if present. * * @return OriginatorInformation, null if not present. */ public OriginatorInformation getOriginatorInfo() { return originatorInfo; } /** * Return the content encryption algorithm details for the data in this object. * * @return AlgorithmIdentifier representing the content encryption algorithm. */ public AlgorithmIdentifier getContentEncryptionAlgorithm() { return encAlg; } /** * return the object identifier for the content encryption algorithm. */ public String getEncryptionAlgOID() { return encAlg.getAlgorithm().getId(); } /** * return the ASN.1 encoded encryption algorithm parameters, or null if * there aren't any. */ public byte[] getEncryptionAlgParams() { try { return encodeObj(encAlg.getParameters()); } catch (Exception e) { throw new RuntimeException("exception getting encryption parameters " + e); } } /** * Return an AlgorithmParameters object giving the encryption parameters * used to encrypt the message content. * * @param provider the provider to generate the parameters for. * @return the parameters object, null if there is not one. * @throws CMSException if the algorithm cannot be found, or the parameters can't be parsed. * @throws NoSuchProviderException if the provider cannot be found. * @deprecated use getContentEncryptionAlgorithm and JceAlgorithmIdentifierConverter(). */ public AlgorithmParameters getEncryptionAlgorithmParameters( String provider) throws CMSException, NoSuchProviderException { return new JceAlgorithmIdentifierConverter().setProvider(provider).getAlgorithmParameters(encAlg); } /** * Return an AlgorithmParameters object giving the encryption parameters * used to encrypt the message content. * * @param provider the provider to generate the parameters for. * @return the parameters object, null if there is not one. * @throws CMSException if the algorithm cannot be found, or the parameters can't be parsed. * @deprecated use getContentEncryptionAlgorithm and JceAlgorithmIdentifierConverter(). */ public AlgorithmParameters getEncryptionAlgorithmParameters( Provider provider) throws CMSException { return new JceAlgorithmIdentifierConverter().setProvider(provider).getAlgorithmParameters(encAlg); } /** * return a store of the intended recipients for this message */ public RecipientInformationStore getRecipientInfos() { return recipientInfoStore; } /** * return the ContentInfo * @deprecated use toASN1Structure() */ public ContentInfo getContentInfo() { return contentInfo; } /** * return the ContentInfo */ public ContentInfo toASN1Structure() { return contentInfo; } /** * return a table of the unprotected attributes indexed by * the OID of the attribute. */ public AttributeTable getUnprotectedAttributes() { if (unprotectedAttributes == null) { return null; } return new AttributeTable(unprotectedAttributes); } /** * return the ASN.1 encoded representation of this object. */ public byte[] getEncoded() throws IOException { return contentInfo.getEncoded(); } } bouncycastle-1.49.orig/src/org/bouncycastle/cms/CMSSignedHelper.java0000644000175000017500000003444212120233253025043 0ustar ebourgebourgpackage org.bouncycastle.cms; import java.io.IOException; import java.security.Provider; import java.security.cert.CRLException; import java.security.cert.CertificateException; import java.util.ArrayList; import java.util.Collection; import java.util.Enumeration; import java.util.HashMap; import java.util.Iterator; import java.util.List; import java.util.Map; import org.bouncycastle.asn1.ASN1Encodable; import org.bouncycastle.asn1.ASN1ObjectIdentifier; import org.bouncycastle.asn1.ASN1Primitive; import org.bouncycastle.asn1.ASN1Sequence; import org.bouncycastle.asn1.ASN1Set; import org.bouncycastle.asn1.ASN1TaggedObject; import org.bouncycastle.asn1.DERNull; import org.bouncycastle.asn1.cms.OtherRevocationInfoFormat; import org.bouncycastle.asn1.cryptopro.CryptoProObjectIdentifiers; import org.bouncycastle.asn1.eac.EACObjectIdentifiers; import org.bouncycastle.asn1.nist.NISTObjectIdentifiers; import org.bouncycastle.asn1.oiw.OIWObjectIdentifiers; import org.bouncycastle.asn1.pkcs.PKCSObjectIdentifiers; import org.bouncycastle.asn1.teletrust.TeleTrusTObjectIdentifiers; import org.bouncycastle.asn1.x509.AlgorithmIdentifier; import org.bouncycastle.asn1.x509.AttributeCertificate; import org.bouncycastle.asn1.x509.Certificate; import org.bouncycastle.asn1.x509.CertificateList; import org.bouncycastle.asn1.x509.X509ObjectIdentifiers; import org.bouncycastle.asn1.x9.X9ObjectIdentifiers; import org.bouncycastle.cert.X509AttributeCertificateHolder; import org.bouncycastle.cert.X509CRLHolder; import org.bouncycastle.cert.X509CertificateHolder; import org.bouncycastle.cert.jcajce.JcaX509CRLConverter; import org.bouncycastle.cert.jcajce.JcaX509CertificateConverter; import org.bouncycastle.util.CollectionStore; import org.bouncycastle.util.Store; import org.bouncycastle.x509.NoSuchStoreException; import org.bouncycastle.x509.X509CollectionStoreParameters; import org.bouncycastle.x509.X509Store; import org.bouncycastle.x509.X509V2AttributeCertificate; class CMSSignedHelper { static final CMSSignedHelper INSTANCE = new CMSSignedHelper(); private static final Map encryptionAlgs = new HashMap(); private static final Map digestAlgs = new HashMap(); private static final Map digestAliases = new HashMap(); private static void addEntries(ASN1ObjectIdentifier alias, String digest, String encryption) { digestAlgs.put(alias.getId(), digest); encryptionAlgs.put(alias.getId(), encryption); } static { addEntries(NISTObjectIdentifiers.dsa_with_sha224, "SHA224", "DSA"); addEntries(NISTObjectIdentifiers.dsa_with_sha256, "SHA256", "DSA"); addEntries(NISTObjectIdentifiers.dsa_with_sha384, "SHA384", "DSA"); addEntries(NISTObjectIdentifiers.dsa_with_sha512, "SHA512", "DSA"); addEntries(OIWObjectIdentifiers.dsaWithSHA1, "SHA1", "DSA"); addEntries(OIWObjectIdentifiers.md4WithRSA, "MD4", "RSA"); addEntries(OIWObjectIdentifiers.md4WithRSAEncryption, "MD4", "RSA"); addEntries(OIWObjectIdentifiers.md5WithRSA, "MD5", "RSA"); addEntries(OIWObjectIdentifiers.sha1WithRSA, "SHA1", "RSA"); addEntries(PKCSObjectIdentifiers.md2WithRSAEncryption, "MD2", "RSA"); addEntries(PKCSObjectIdentifiers.md4WithRSAEncryption, "MD4", "RSA"); addEntries(PKCSObjectIdentifiers.md5WithRSAEncryption, "MD5", "RSA"); addEntries(PKCSObjectIdentifiers.sha1WithRSAEncryption, "SHA1", "RSA"); addEntries(PKCSObjectIdentifiers.sha224WithRSAEncryption, "SHA224", "RSA"); addEntries(PKCSObjectIdentifiers.sha256WithRSAEncryption, "SHA256", "RSA"); addEntries(PKCSObjectIdentifiers.sha384WithRSAEncryption, "SHA384", "RSA"); addEntries(PKCSObjectIdentifiers.sha512WithRSAEncryption, "SHA512", "RSA"); addEntries(X9ObjectIdentifiers.ecdsa_with_SHA1, "SHA1", "ECDSA"); addEntries(X9ObjectIdentifiers.ecdsa_with_SHA224, "SHA224", "ECDSA"); addEntries(X9ObjectIdentifiers.ecdsa_with_SHA256, "SHA256", "ECDSA"); addEntries(X9ObjectIdentifiers.ecdsa_with_SHA384, "SHA384", "ECDSA"); addEntries(X9ObjectIdentifiers.ecdsa_with_SHA512, "SHA512", "ECDSA"); addEntries(X9ObjectIdentifiers.id_dsa_with_sha1, "SHA1", "DSA"); addEntries(EACObjectIdentifiers.id_TA_ECDSA_SHA_1, "SHA1", "ECDSA"); addEntries(EACObjectIdentifiers.id_TA_ECDSA_SHA_224, "SHA224", "ECDSA"); addEntries(EACObjectIdentifiers.id_TA_ECDSA_SHA_256, "SHA256", "ECDSA"); addEntries(EACObjectIdentifiers.id_TA_ECDSA_SHA_384, "SHA384", "ECDSA"); addEntries(EACObjectIdentifiers.id_TA_ECDSA_SHA_512, "SHA512", "ECDSA"); addEntries(EACObjectIdentifiers.id_TA_RSA_v1_5_SHA_1, "SHA1", "RSA"); addEntries(EACObjectIdentifiers.id_TA_RSA_v1_5_SHA_256, "SHA256", "RSA"); addEntries(EACObjectIdentifiers.id_TA_RSA_PSS_SHA_1, "SHA1", "RSAandMGF1"); addEntries(EACObjectIdentifiers.id_TA_RSA_PSS_SHA_256, "SHA256", "RSAandMGF1"); encryptionAlgs.put(X9ObjectIdentifiers.id_dsa.getId(), "DSA"); encryptionAlgs.put(PKCSObjectIdentifiers.rsaEncryption.getId(), "RSA"); encryptionAlgs.put(TeleTrusTObjectIdentifiers.teleTrusTRSAsignatureAlgorithm, "RSA"); encryptionAlgs.put(X509ObjectIdentifiers.id_ea_rsa.getId(), "RSA"); encryptionAlgs.put(CMSSignedDataGenerator.ENCRYPTION_RSA_PSS, "RSAandMGF1"); encryptionAlgs.put(CryptoProObjectIdentifiers.gostR3410_94.getId(), "GOST3410"); encryptionAlgs.put(CryptoProObjectIdentifiers.gostR3410_2001.getId(), "ECGOST3410"); encryptionAlgs.put("1.3.6.1.4.1.5849.1.6.2", "ECGOST3410"); encryptionAlgs.put("1.3.6.1.4.1.5849.1.1.5", "GOST3410"); encryptionAlgs.put(CryptoProObjectIdentifiers.gostR3411_94_with_gostR3410_2001.getId(), "ECGOST3410"); encryptionAlgs.put(CryptoProObjectIdentifiers.gostR3411_94_with_gostR3410_94.getId(), "GOST3410"); digestAlgs.put(PKCSObjectIdentifiers.md2.getId(), "MD2"); digestAlgs.put(PKCSObjectIdentifiers.md4.getId(), "MD4"); digestAlgs.put(PKCSObjectIdentifiers.md5.getId(), "MD5"); digestAlgs.put(OIWObjectIdentifiers.idSHA1.getId(), "SHA1"); digestAlgs.put(NISTObjectIdentifiers.id_sha224.getId(), "SHA224"); digestAlgs.put(NISTObjectIdentifiers.id_sha256.getId(), "SHA256"); digestAlgs.put(NISTObjectIdentifiers.id_sha384.getId(), "SHA384"); digestAlgs.put(NISTObjectIdentifiers.id_sha512.getId(), "SHA512"); digestAlgs.put(TeleTrusTObjectIdentifiers.ripemd128.getId(), "RIPEMD128"); digestAlgs.put(TeleTrusTObjectIdentifiers.ripemd160.getId(), "RIPEMD160"); digestAlgs.put(TeleTrusTObjectIdentifiers.ripemd256.getId(), "RIPEMD256"); digestAlgs.put(CryptoProObjectIdentifiers.gostR3411.getId(), "GOST3411"); digestAlgs.put("1.3.6.1.4.1.5849.1.2.1", "GOST3411"); digestAliases.put("SHA1", new String[] { "SHA-1" }); digestAliases.put("SHA224", new String[] { "SHA-224" }); digestAliases.put("SHA256", new String[] { "SHA-256" }); digestAliases.put("SHA384", new String[] { "SHA-384" }); digestAliases.put("SHA512", new String[] { "SHA-512" }); } /** * Return the digest algorithm using one of the standard JCA string * representations rather than the algorithm identifier (if possible). */ String getDigestAlgName( String digestAlgOID) { String algName = (String)digestAlgs.get(digestAlgOID); if (algName != null) { return algName; } return digestAlgOID; } /** * Return the digest encryption algorithm using one of the standard * JCA string representations rather the the algorithm identifier (if * possible). */ String getEncryptionAlgName( String encryptionAlgOID) { String algName = (String)encryptionAlgs.get(encryptionAlgOID); if (algName != null) { return algName; } return encryptionAlgOID; } X509Store createAttributeStore( String type, Provider provider, Store certStore) throws NoSuchStoreException, CMSException { try { Collection certHldrs = certStore.getMatches(null); List certs = new ArrayList(certHldrs.size()); for (Iterator it = certHldrs.iterator(); it.hasNext();) { certs.add(new X509V2AttributeCertificate(((X509AttributeCertificateHolder)it.next()).getEncoded())); } return X509Store.getInstance( "AttributeCertificate/" +type, new X509CollectionStoreParameters(certs), provider); } catch (IllegalArgumentException e) { throw new CMSException("can't setup the X509Store", e); } catch (IOException e) { throw new CMSException("can't setup the X509Store", e); } } X509Store createCertificateStore( String type, Provider provider, Store certStore) throws NoSuchStoreException, CMSException { try { JcaX509CertificateConverter converter = new JcaX509CertificateConverter().setProvider(provider); Collection certHldrs = certStore.getMatches(null); List certs = new ArrayList(certHldrs.size()); for (Iterator it = certHldrs.iterator(); it.hasNext();) { certs.add(converter.getCertificate((X509CertificateHolder)it.next())); } return X509Store.getInstance( "Certificate/" +type, new X509CollectionStoreParameters(certs), provider); } catch (IllegalArgumentException e) { throw new CMSException("can't setup the X509Store", e); } catch (CertificateException e) { throw new CMSException("can't setup the X509Store", e); } } X509Store createCRLsStore( String type, Provider provider, Store crlStore) throws NoSuchStoreException, CMSException { try { JcaX509CRLConverter converter = new JcaX509CRLConverter().setProvider(provider); Collection crlHldrs = crlStore.getMatches(null); List crls = new ArrayList(crlHldrs.size()); for (Iterator it = crlHldrs.iterator(); it.hasNext();) { crls.add(converter.getCRL((X509CRLHolder)it.next())); } return X509Store.getInstance( "CRL/" +type, new X509CollectionStoreParameters(crls), provider); } catch (IllegalArgumentException e) { throw new CMSException("can't setup the X509Store", e); } catch (CRLException e) { throw new CMSException("can't setup the X509Store", e); } } AlgorithmIdentifier fixAlgID(AlgorithmIdentifier algId) { if (algId.getParameters() == null) { return new AlgorithmIdentifier(algId.getAlgorithm(), DERNull.INSTANCE); } return algId; } void setSigningEncryptionAlgorithmMapping(ASN1ObjectIdentifier oid, String algorithmName) { encryptionAlgs.put(oid.getId(), algorithmName); } void setSigningDigestAlgorithmMapping(ASN1ObjectIdentifier oid, String algorithmName) { digestAlgs.put(oid.getId(), algorithmName); } Store getCertificates(ASN1Set certSet) { if (certSet != null) { List certList = new ArrayList(certSet.size()); for (Enumeration en = certSet.getObjects(); en.hasMoreElements();) { ASN1Primitive obj = ((ASN1Encodable)en.nextElement()).toASN1Primitive(); if (obj instanceof ASN1Sequence) { certList.add(new X509CertificateHolder(Certificate.getInstance(obj))); } } return new CollectionStore(certList); } return new CollectionStore(new ArrayList()); } Store getAttributeCertificates(ASN1Set certSet) { if (certSet != null) { List certList = new ArrayList(certSet.size()); for (Enumeration en = certSet.getObjects(); en.hasMoreElements();) { ASN1Primitive obj = ((ASN1Encodable)en.nextElement()).toASN1Primitive(); if (obj instanceof ASN1TaggedObject) { certList.add(new X509AttributeCertificateHolder(AttributeCertificate.getInstance(((ASN1TaggedObject)obj).getObject()))); } } return new CollectionStore(certList); } return new CollectionStore(new ArrayList()); } Store getCRLs(ASN1Set crlSet) { if (crlSet != null) { List crlList = new ArrayList(crlSet.size()); for (Enumeration en = crlSet.getObjects(); en.hasMoreElements();) { ASN1Primitive obj = ((ASN1Encodable)en.nextElement()).toASN1Primitive(); if (obj instanceof ASN1Sequence) { crlList.add(new X509CRLHolder(CertificateList.getInstance(obj))); } } return new CollectionStore(crlList); } return new CollectionStore(new ArrayList()); } Store getOtherRevocationInfo(ASN1ObjectIdentifier otherRevocationInfoFormat, ASN1Set crlSet) { if (crlSet != null) { List crlList = new ArrayList(crlSet.size()); for (Enumeration en = crlSet.getObjects(); en.hasMoreElements();) { ASN1Primitive obj = ((ASN1Encodable)en.nextElement()).toASN1Primitive(); if (obj instanceof ASN1TaggedObject) { ASN1TaggedObject tObj = ASN1TaggedObject.getInstance(obj); if (tObj.getTagNo() == 1) { OtherRevocationInfoFormat other = OtherRevocationInfoFormat.getInstance(tObj, false); if (otherRevocationInfoFormat.equals(other.getInfoFormat())) { crlList.add(other.getInfo()); } } } } return new CollectionStore(crlList); } return new CollectionStore(new ArrayList()); } } bouncycastle-1.49.orig/src/org/bouncycastle/cms/CMSEnvelopedDataStreamGenerator.java0000644000175000017500000003072411737173441030246 0ustar ebourgebourgpackage org.bouncycastle.cms; import java.io.IOException; import java.io.OutputStream; import java.security.NoSuchAlgorithmException; import java.security.NoSuchProviderException; import java.security.Provider; import java.security.SecureRandom; import java.util.HashMap; import java.util.Iterator; import javax.crypto.KeyGenerator; import org.bouncycastle.asn1.ASN1EncodableVector; import org.bouncycastle.asn1.ASN1Integer; import org.bouncycastle.asn1.ASN1ObjectIdentifier; import org.bouncycastle.asn1.ASN1Set; import org.bouncycastle.asn1.BERSequenceGenerator; import org.bouncycastle.asn1.BERSet; import org.bouncycastle.asn1.DERSet; import org.bouncycastle.asn1.DERTaggedObject; import org.bouncycastle.asn1.cms.AttributeTable; import org.bouncycastle.asn1.cms.CMSObjectIdentifiers; import org.bouncycastle.asn1.cms.EnvelopedData; import org.bouncycastle.asn1.x509.AlgorithmIdentifier; import org.bouncycastle.cms.jcajce.JceCMSContentEncryptorBuilder; import org.bouncycastle.operator.GenericKey; import org.bouncycastle.operator.OutputEncryptor; /** * General class for generating a CMS enveloped-data message stream. *

    * A simple example of usage. *

     *      CMSEnvelopedDataStreamGenerator edGen = new CMSEnvelopedDataStreamGenerator();
     *
     *      edGen.addRecipientInfoGenerator(new JceKeyTransRecipientInfoGenerator(recipientCert).setProvider("BC"));
     *
     *      ByteArrayOutputStream  bOut = new ByteArrayOutputStream();
     *      
     *      OutputStream out = edGen.open(
     *                              bOut, new JceCMSContentEncryptorBuilder(CMSAlgorithm.DES_EDE3_CBC)
     *                                              .setProvider("BC").build());
     *      out.write(data);
     *      
     *      out.close();
     * 
    */ public class CMSEnvelopedDataStreamGenerator extends CMSEnvelopedGenerator { private ASN1Set _unprotectedAttributes = null; private int _bufferSize; private boolean _berEncodeRecipientSet; /** * base constructor */ public CMSEnvelopedDataStreamGenerator() { } /** * constructor allowing specific source of randomness * @param rand instance of SecureRandom to use * @deprecated no longer required - specify randomness via RecipientInfoGenerator or ContentEncryptor. */ public CMSEnvelopedDataStreamGenerator( SecureRandom rand) { super(rand); } /** * Set the underlying string size for encapsulated data * * @param bufferSize length of octet strings to buffer the data. */ public void setBufferSize( int bufferSize) { _bufferSize = bufferSize; } /** * Use a BER Set to store the recipient information */ public void setBEREncodeRecipients( boolean berEncodeRecipientSet) { _berEncodeRecipientSet = berEncodeRecipientSet; } private ASN1Integer getVersion() { if (originatorInfo != null || _unprotectedAttributes != null) { return new ASN1Integer(2); } else { return new ASN1Integer(0); } } /** * generate an enveloped object that contains an CMS Enveloped Data * object using the given provider and the passed in key generator. * @throws IOException * @deprecated */ private OutputStream open( OutputStream out, String encryptionOID, int keySize, Provider encProvider, Provider provider) throws NoSuchAlgorithmException, CMSException, IOException { convertOldRecipients(rand, provider); JceCMSContentEncryptorBuilder builder; if (keySize != -1) { builder = new JceCMSContentEncryptorBuilder(new ASN1ObjectIdentifier(encryptionOID), keySize); } else { builder = new JceCMSContentEncryptorBuilder(new ASN1ObjectIdentifier(encryptionOID)); } builder.setProvider(encProvider); builder.setSecureRandom(rand); return doOpen(CMSObjectIdentifiers.data, out, builder.build()); } private OutputStream doOpen( ASN1ObjectIdentifier dataType, OutputStream out, OutputEncryptor encryptor) throws IOException, CMSException { ASN1EncodableVector recipientInfos = new ASN1EncodableVector(); GenericKey encKey = encryptor.getKey(); Iterator it = recipientInfoGenerators.iterator(); while (it.hasNext()) { RecipientInfoGenerator recipient = (RecipientInfoGenerator)it.next(); recipientInfos.add(recipient.generate(encKey)); } return open(dataType, out, recipientInfos, encryptor); } protected OutputStream open( ASN1ObjectIdentifier dataType, OutputStream out, ASN1EncodableVector recipientInfos, OutputEncryptor encryptor) throws IOException { // // ContentInfo // BERSequenceGenerator cGen = new BERSequenceGenerator(out); cGen.addObject(CMSObjectIdentifiers.envelopedData); // // Encrypted Data // BERSequenceGenerator envGen = new BERSequenceGenerator(cGen.getRawOutputStream(), 0, true); envGen.addObject(getVersion()); if (originatorInfo != null) { envGen.addObject(new DERTaggedObject(false, 0, originatorInfo)); } if (_berEncodeRecipientSet) { envGen.getRawOutputStream().write(new BERSet(recipientInfos).getEncoded()); } else { envGen.getRawOutputStream().write(new DERSet(recipientInfos).getEncoded()); } BERSequenceGenerator eiGen = new BERSequenceGenerator(envGen.getRawOutputStream()); eiGen.addObject(dataType); AlgorithmIdentifier encAlgId = encryptor.getAlgorithmIdentifier(); eiGen.getRawOutputStream().write(encAlgId.getEncoded()); OutputStream octetStream = CMSUtils.createBEROctetOutputStream( eiGen.getRawOutputStream(), 0, false, _bufferSize); OutputStream cOut = encryptor.getOutputStream(octetStream); return new CmsEnvelopedDataOutputStream(cOut, cGen, envGen, eiGen); } protected OutputStream open( OutputStream out, ASN1EncodableVector recipientInfos, OutputEncryptor encryptor) throws CMSException { try { // // ContentInfo // BERSequenceGenerator cGen = new BERSequenceGenerator(out); cGen.addObject(CMSObjectIdentifiers.envelopedData); // // Encrypted Data // BERSequenceGenerator envGen = new BERSequenceGenerator(cGen.getRawOutputStream(), 0, true); ASN1Set recipients; if (_berEncodeRecipientSet) { recipients = new BERSet(recipientInfos); } else { recipients = new DERSet(recipientInfos); } envGen.addObject(new ASN1Integer(EnvelopedData.calculateVersion(originatorInfo, recipients, _unprotectedAttributes))); if (originatorInfo != null) { envGen.addObject(new DERTaggedObject(false, 0, originatorInfo)); } envGen.getRawOutputStream().write(recipients.getEncoded()); BERSequenceGenerator eiGen = new BERSequenceGenerator(envGen.getRawOutputStream()); eiGen.addObject(CMSObjectIdentifiers.data); AlgorithmIdentifier encAlgId = encryptor.getAlgorithmIdentifier(); eiGen.getRawOutputStream().write(encAlgId.getEncoded()); OutputStream octetStream = CMSUtils.createBEROctetOutputStream( eiGen.getRawOutputStream(), 0, false, _bufferSize); return new CmsEnvelopedDataOutputStream(encryptor.getOutputStream(octetStream), cGen, envGen, eiGen); } catch (IOException e) { throw new CMSException("exception decoding algorithm parameters.", e); } } /** * generate an enveloped object that contains an CMS Enveloped Data * object using the given provider. * @throws IOException * @deprecated */ public OutputStream open( OutputStream out, String encryptionOID, String provider) throws NoSuchAlgorithmException, NoSuchProviderException, CMSException, IOException { return open(out, encryptionOID, CMSUtils.getProvider(provider)); } /** * @deprecated */ public OutputStream open( OutputStream out, String encryptionOID, Provider provider) throws NoSuchAlgorithmException, CMSException, IOException { KeyGenerator keyGen = CMSEnvelopedHelper.INSTANCE.createSymmetricKeyGenerator(encryptionOID, provider); keyGen.init(rand); return open(out, encryptionOID, -1, keyGen.getProvider(), provider); } /** * generate an enveloped object that contains an CMS Enveloped Data * object using the given provider. * @deprecated */ public OutputStream open( OutputStream out, String encryptionOID, int keySize, String provider) throws NoSuchAlgorithmException, NoSuchProviderException, CMSException, IOException { return open(out, encryptionOID, keySize, CMSUtils.getProvider(provider)); } /** * generate an enveloped object that contains an CMS Enveloped Data * object using the given provider. * @deprecated */ public OutputStream open( OutputStream out, String encryptionOID, int keySize, Provider provider) throws NoSuchAlgorithmException, CMSException, IOException { KeyGenerator keyGen = CMSEnvelopedHelper.INSTANCE.createSymmetricKeyGenerator(encryptionOID, provider); keyGen.init(keySize, rand); return open(out, encryptionOID, -1, keyGen.getProvider(), provider); } /** * generate an enveloped object that contains an CMS Enveloped Data * object using the given encryptor. */ public OutputStream open( OutputStream out, OutputEncryptor encryptor) throws CMSException, IOException { return doOpen(new ASN1ObjectIdentifier(CMSObjectIdentifiers.data.getId()), out, encryptor); } /** * generate an enveloped object that contains an CMS Enveloped Data * object using the given encryptor and marking the data as being of the passed * in type. */ public OutputStream open( ASN1ObjectIdentifier dataType, OutputStream out, OutputEncryptor encryptor) throws CMSException, IOException { return doOpen(dataType, out, encryptor); } private class CmsEnvelopedDataOutputStream extends OutputStream { private OutputStream _out; private BERSequenceGenerator _cGen; private BERSequenceGenerator _envGen; private BERSequenceGenerator _eiGen; public CmsEnvelopedDataOutputStream( OutputStream out, BERSequenceGenerator cGen, BERSequenceGenerator envGen, BERSequenceGenerator eiGen) { _out = out; _cGen = cGen; _envGen = envGen; _eiGen = eiGen; } public void write( int b) throws IOException { _out.write(b); } public void write( byte[] bytes, int off, int len) throws IOException { _out.write(bytes, off, len); } public void write( byte[] bytes) throws IOException { _out.write(bytes); } public void close() throws IOException { _out.close(); _eiGen.close(); if (unprotectedAttributeGenerator != null) { AttributeTable attrTable = unprotectedAttributeGenerator.getAttributes(new HashMap()); ASN1Set unprotectedAttrs = new BERSet(attrTable.toASN1EncodableVector()); _envGen.addObject(new DERTaggedObject(false, 1, unprotectedAttrs)); } _envGen.close(); _cGen.close(); } } } bouncycastle-1.49.orig/src/org/bouncycastle/cms/KEKRecipientInformation.java0000644000175000017500000000524111605466467026633 0ustar ebourgebourgpackage org.bouncycastle.cms; import java.io.IOException; import java.security.Key; import java.security.NoSuchProviderException; import java.security.Provider; import javax.crypto.SecretKey; import org.bouncycastle.asn1.cms.KEKIdentifier; import org.bouncycastle.asn1.cms.KEKRecipientInfo; import org.bouncycastle.asn1.x509.AlgorithmIdentifier; import org.bouncycastle.cms.jcajce.JceKEKAuthenticatedRecipient; import org.bouncycastle.cms.jcajce.JceKEKEnvelopedRecipient; import org.bouncycastle.cms.jcajce.JceKEKRecipient; /** * the RecipientInfo class for a recipient who has been sent a message * encrypted using a secret key known to the other side. */ public class KEKRecipientInformation extends RecipientInformation { private KEKRecipientInfo info; KEKRecipientInformation( KEKRecipientInfo info, AlgorithmIdentifier messageAlgorithm, CMSSecureReadable secureReadable, AuthAttributesProvider additionalData) { super(info.getKeyEncryptionAlgorithm(), messageAlgorithm, secureReadable, additionalData); this.info = info; KEKIdentifier kekId = info.getKekid(); this.rid = new KEKRecipientId(kekId.getKeyIdentifier().getOctets()); } /** * decrypt the content and return an input stream. */ public CMSTypedStream getContentStream( Key key, String prov) throws CMSException, NoSuchProviderException { return getContentStream(key, CMSUtils.getProvider(prov)); } /** * decrypt the content and return an input stream. * @deprecated use getContentStream(Recipient) */ public CMSTypedStream getContentStream( Key key, Provider prov) throws CMSException { try { JceKEKRecipient recipient; if (secureReadable instanceof CMSEnvelopedHelper.CMSEnvelopedSecureReadable) { recipient = new JceKEKEnvelopedRecipient((SecretKey)key); } else { recipient = new JceKEKAuthenticatedRecipient((SecretKey)key); } if (prov != null) { recipient.setProvider(prov); } return getContentStream(recipient); } catch (IOException e) { throw new CMSException("encoding error: " + e.getMessage(), e); } } protected RecipientOperator getRecipientOperator(Recipient recipient) throws CMSException, IOException { return ((KEKRecipient)recipient).getRecipientOperator(keyEncAlg, messageAlgorithm, info.getEncryptedKey().getOctets()); } } bouncycastle-1.49.orig/src/org/bouncycastle/cms/PKCS5Scheme2PBEKey.java0000644000175000017500000000220011222021263025144 0ustar ebourgebourgpackage org.bouncycastle.cms; import java.security.AlgorithmParameters; import java.security.InvalidAlgorithmParameterException; import org.bouncycastle.crypto.PBEParametersGenerator; import org.bouncycastle.crypto.generators.PKCS5S2ParametersGenerator; import org.bouncycastle.crypto.params.KeyParameter; /** * PKCS5 scheme-2 - password converted to bytes assuming ASCII. */ public class PKCS5Scheme2PBEKey extends CMSPBEKey { public PKCS5Scheme2PBEKey(char[] password, byte[] salt, int iterationCount) { super(password, salt, iterationCount); } public PKCS5Scheme2PBEKey(char[] password, AlgorithmParameters pbeParams) throws InvalidAlgorithmParameterException { super(password, getParamSpec(pbeParams)); } byte[] getEncoded(String algorithmOid) { PKCS5S2ParametersGenerator gen = new PKCS5S2ParametersGenerator(); gen.init(PBEParametersGenerator.PKCS5PasswordToBytes(this.getPassword()), this.getSalt(), this.getIterationCount()); return ((KeyParameter)gen.generateDerivedParameters(CMSEnvelopedHelper.INSTANCE.getKeySize(algorithmOid))).getKey(); } } bouncycastle-1.49.orig/src/org/bouncycastle/cms/CMSDigestedData.java0000644000175000017500000000711112053027274025016 0ustar ebourgebourgpackage org.bouncycastle.cms; import java.io.IOException; import java.io.InputStream; import java.io.OutputStream; import org.bouncycastle.asn1.ASN1ObjectIdentifier; import org.bouncycastle.asn1.ASN1OctetString; import org.bouncycastle.asn1.cms.ContentInfo; import org.bouncycastle.asn1.cms.DigestedData; import org.bouncycastle.asn1.x509.AlgorithmIdentifier; import org.bouncycastle.operator.DigestCalculator; import org.bouncycastle.operator.DigestCalculatorProvider; import org.bouncycastle.operator.OperatorCreationException; import org.bouncycastle.util.Arrays; /** * containing class for an CMS Digested Data object *
     *     CMSDigestedData cd = new CMSDigestedData(inputStream);
     *
     *
     *     process(cd.getContent());
     * 
    */ public class CMSDigestedData { private ContentInfo contentInfo; private DigestedData digestedData; public CMSDigestedData( byte[] compressedData) throws CMSException { this(CMSUtils.readContentInfo(compressedData)); } public CMSDigestedData( InputStream compressedData) throws CMSException { this(CMSUtils.readContentInfo(compressedData)); } public CMSDigestedData( ContentInfo contentInfo) throws CMSException { this.contentInfo = contentInfo; try { this.digestedData = DigestedData.getInstance(contentInfo.getContent()); } catch (ClassCastException e) { throw new CMSException("Malformed content.", e); } catch (IllegalArgumentException e) { throw new CMSException("Malformed content.", e); } } public ASN1ObjectIdentifier getContentType() { return contentInfo.getContentType(); } public AlgorithmIdentifier getDigestAlgorithm() { return digestedData.getDigestAlgorithm(); } /** * Return the digested content * * @return the digested content * @throws CMSException if there is an exception un-compressing the data. */ public CMSProcessable getDigestedContent() throws CMSException { ContentInfo content = digestedData.getEncapContentInfo(); try { return new CMSProcessableByteArray(content.getContentType(), ((ASN1OctetString)content.getContent()).getOctets()); } catch (Exception e) { throw new CMSException("exception reading digested stream.", e); } } /** * return the ContentInfo */ public ContentInfo toASN1Structure() { return contentInfo; } /** * return the ASN.1 encoded representation of this object. */ public byte[] getEncoded() throws IOException { return contentInfo.getEncoded(); } public boolean verify(DigestCalculatorProvider calculatorProvider) throws CMSException { try { ContentInfo content = digestedData.getEncapContentInfo(); DigestCalculator calc = calculatorProvider.get(digestedData.getDigestAlgorithm()); OutputStream dOut = calc.getOutputStream(); dOut.write(((ASN1OctetString)content.getContent()).getOctets()); return Arrays.areEqual(digestedData.getDigest(), calc.getDigest()); } catch (OperatorCreationException e) { throw new CMSException("unable to create digest calculator: " + e.getMessage(), e); } catch (IOException e) { throw new CMSException("unable process content: " + e.getMessage(), e); } } } bouncycastle-1.49.orig/src/org/bouncycastle/cms/CMSSecureReadable.java0000644000175000017500000000030711607170365025346 0ustar ebourgebourgpackage org.bouncycastle.cms; import java.io.IOException; import java.io.InputStream; interface CMSSecureReadable { InputStream getInputStream() throws IOException, CMSException; } bouncycastle-1.49.orig/src/org/bouncycastle/cms/Recipient.java0000644000175000017500000000007611442065637024064 0ustar ebourgebourgpackage org.bouncycastle.cms; public interface Recipient { } bouncycastle-1.49.orig/src/org/bouncycastle/cms/PasswordRecipientId.java0000644000175000017500000000133711726247204026062 0ustar ebourgebourgpackage org.bouncycastle.cms; public class PasswordRecipientId extends RecipientId { /** * Construct a recipient ID of the password type. */ public PasswordRecipientId() { super(password); } public int hashCode() { return password; } public boolean equals( Object o) { if (!(o instanceof PasswordRecipientId)) { return false; } return true; } public Object clone() { return new PasswordRecipientId(); } public boolean match(Object obj) { if (obj instanceof PasswordRecipientInformation) { return true; } return false; } } bouncycastle-1.49.orig/src/org/bouncycastle/cms/package.html0000644000175000017500000000026610760650614023556 0ustar ebourgebourg A package for processing RFC 3852 Cryptographic Message Syntax (CMS) objects - also referred to as PKCS#7 (formerly RFC 2630, 3369). bouncycastle-1.49.orig/src/org/bouncycastle/cms/PasswordRecipient.java0000644000175000017500000000102711442065637025604 0ustar ebourgebourgpackage org.bouncycastle.cms; import org.bouncycastle.asn1.x509.AlgorithmIdentifier; public interface PasswordRecipient extends Recipient { public static final int PKCS5_SCHEME2 = 0; public static final int PKCS5_SCHEME2_UTF8 = 1; RecipientOperator getRecipientOperator(AlgorithmIdentifier keyEncryptionAlgorithm, AlgorithmIdentifier contentEncryptionAlgorithm, byte[] derivedKey, byte[] encryptedEncryptedContentKey) throws CMSException; int getPasswordConversionScheme(); char[] getPassword(); } bouncycastle-1.49.orig/src/org/bouncycastle/cms/CMSProcessableFile.java0000644000175000017500000000343211426205501025532 0ustar ebourgebourgpackage org.bouncycastle.cms; import java.io.BufferedInputStream; import java.io.File; import java.io.FileInputStream; import java.io.IOException; import java.io.InputStream; import java.io.OutputStream; import org.bouncycastle.asn1.ASN1ObjectIdentifier; import org.bouncycastle.asn1.cms.CMSObjectIdentifiers; /** * a holding class for a file of data to be processed. */ public class CMSProcessableFile implements CMSTypedData, CMSReadable { private static final int DEFAULT_BUF_SIZE = 32 * 1024; private final ASN1ObjectIdentifier type; private final File file; private final byte[] buf; public CMSProcessableFile( File file) { this(file, DEFAULT_BUF_SIZE); } public CMSProcessableFile( File file, int bufSize) { this(new ASN1ObjectIdentifier(CMSObjectIdentifiers.data.getId()), file, bufSize); } public CMSProcessableFile( ASN1ObjectIdentifier type, File file, int bufSize) { this.type = type; this.file = file; buf = new byte[bufSize]; } public InputStream getInputStream() throws IOException, CMSException { return new BufferedInputStream(new FileInputStream(file), DEFAULT_BUF_SIZE); } public void write(OutputStream zOut) throws IOException, CMSException { FileInputStream fIn = new FileInputStream(file); int len; while ((len = fIn.read(buf, 0, buf.length)) > 0) { zOut.write(buf, 0, len); } fIn.close(); } /** * Return the file handle. */ public Object getContent() { return file; } public ASN1ObjectIdentifier getContentType() { return type; } } bouncycastle-1.49.orig/src/org/bouncycastle/tsp/0000755000175000017500000000000012152033551021305 5ustar ebourgebourgbouncycastle-1.49.orig/src/org/bouncycastle/tsp/TimeStampResponseGenerator.java0000644000175000017500000003421612117505273027455 0ustar ebourgebourgpackage org.bouncycastle.tsp; import java.io.ByteArrayInputStream; import java.io.IOException; import java.math.BigInteger; import java.security.NoSuchAlgorithmException; import java.security.NoSuchProviderException; import java.util.Date; import java.util.HashSet; import java.util.Iterator; import java.util.Set; import org.bouncycastle.asn1.ASN1EncodableVector; import org.bouncycastle.asn1.ASN1InputStream; import org.bouncycastle.asn1.ASN1ObjectIdentifier; import org.bouncycastle.asn1.DERBitString; import org.bouncycastle.asn1.DERInteger; import org.bouncycastle.asn1.DERSequence; import org.bouncycastle.asn1.DERUTF8String; import org.bouncycastle.asn1.cmp.PKIFailureInfo; import org.bouncycastle.asn1.cmp.PKIFreeText; import org.bouncycastle.asn1.cmp.PKIStatus; import org.bouncycastle.asn1.cmp.PKIStatusInfo; import org.bouncycastle.asn1.cms.ContentInfo; import org.bouncycastle.asn1.tsp.TimeStampResp; /** * Generator for RFC 3161 Time Stamp Responses. *

    * New generate methods have been introduced to give people more control over what ends up in the message. * Unfortunately it turns out that in some cases fields like statusString must be left out otherwise a an * otherwise valid timestamp will be rejected. *

    * If you're after the most control with generating a response use: *
     *    TimeStampResponse tsResp;
     *
     *    try
     *    {
     *       tsResp = tsRespGen.generateGrantedResponse(request, new BigInteger("23"), new Date());
     *    }
     *    catch (Exception e)
     *    {
     *        tsResp = tsRespGen.generateRejectedResponse(e);
     *    }
     * 
    * The generate method does this, but provides a status string of "Operation Okay". *

    * It should be pointed out that generateRejectedResponse() may also, on very rare occasions throw a TSPException. * In the event that happens, there's a serious internal problem with your responder. *

    */ public class TimeStampResponseGenerator { int status; ASN1EncodableVector statusStrings; int failInfo; private TimeStampTokenGenerator tokenGenerator; private Set acceptedAlgorithms; private Set acceptedPolicies; private Set acceptedExtensions; /** * * @param tokenGenerator * @param acceptedAlgorithms a set of OIDs giving accepted algorithms. */ public TimeStampResponseGenerator( TimeStampTokenGenerator tokenGenerator, Set acceptedAlgorithms) { this(tokenGenerator, acceptedAlgorithms, null, null); } /** * * @param tokenGenerator * @param acceptedAlgorithms a set of OIDs giving accepted algorithms. * @param acceptedPolicies if non-null a set of policies OIDs we are willing to sign under. */ public TimeStampResponseGenerator( TimeStampTokenGenerator tokenGenerator, Set acceptedAlgorithms, Set acceptedPolicies) { this(tokenGenerator, acceptedAlgorithms, acceptedPolicies, null); } /** * * @param tokenGenerator * @param acceptedAlgorithms a set of OIDs giving accepted algorithms. * @param acceptedPolicies if non-null a set of policies OIDs we are willing to sign under. * @param acceptedExtensions if non-null a set of extensions OIDs we are willing to accept. */ public TimeStampResponseGenerator( TimeStampTokenGenerator tokenGenerator, Set acceptedAlgorithms, Set acceptedPolicies, Set acceptedExtensions) { this.tokenGenerator = tokenGenerator; this.acceptedAlgorithms = convert(acceptedAlgorithms); this.acceptedPolicies = convert(acceptedPolicies); this.acceptedExtensions = convert(acceptedExtensions); statusStrings = new ASN1EncodableVector(); } private void addStatusString(String statusString) { statusStrings.add(new DERUTF8String(statusString)); } private void setFailInfoField(int field) { failInfo = failInfo | field; } private PKIStatusInfo getPKIStatusInfo() { ASN1EncodableVector v = new ASN1EncodableVector(); v.add(new DERInteger(status)); if (statusStrings.size() > 0) { v.add(PKIFreeText.getInstance(new DERSequence(statusStrings))); } if (failInfo != 0) { DERBitString failInfoBitString = new FailInfo(failInfo); v.add(failInfoBitString); } return PKIStatusInfo.getInstance(new DERSequence(v)); } /** * Return an appropriate TimeStampResponse. *

    * If genTime is null a timeNotAvailable error response will be returned. * * @param request the request this response is for. * @param serialNumber serial number for the response token. * @param genTime generation time for the response token. * @param provider provider to use for signature calculation. * @deprecated use method that does not require provider * @return * @throws NoSuchAlgorithmException * @throws NoSuchProviderException * @throws TSPException */ public TimeStampResponse generate( TimeStampRequest request, BigInteger serialNumber, Date genTime, String provider) throws NoSuchAlgorithmException, NoSuchProviderException, TSPException { TimeStampResp resp; try { if (genTime == null) { throw new TSPValidationException("The time source is not available.", PKIFailureInfo.timeNotAvailable); } request.validate(acceptedAlgorithms, acceptedPolicies, acceptedExtensions, provider); status = PKIStatus.GRANTED; this.addStatusString("Operation Okay"); PKIStatusInfo pkiStatusInfo = getPKIStatusInfo(); ContentInfo tstTokenContentInfo = null; try { ByteArrayInputStream bIn = new ByteArrayInputStream(tokenGenerator.generate(request, serialNumber, genTime, provider).toCMSSignedData().getEncoded()); ASN1InputStream aIn = new ASN1InputStream(bIn); tstTokenContentInfo = ContentInfo.getInstance(aIn.readObject()); } catch (java.io.IOException ioEx) { throw new TSPException( "Timestamp token received cannot be converted to ContentInfo", ioEx); } resp = new TimeStampResp(pkiStatusInfo, tstTokenContentInfo); } catch (TSPValidationException e) { status = PKIStatus.REJECTION; this.setFailInfoField(e.getFailureCode()); this.addStatusString(e.getMessage()); PKIStatusInfo pkiStatusInfo = getPKIStatusInfo(); resp = new TimeStampResp(pkiStatusInfo, null); } try { return new TimeStampResponse(resp); } catch (IOException e) { throw new TSPException("created badly formatted response!"); } } /** * Return an appropriate TimeStampResponse. *

    * If genTime is null a timeNotAvailable error response will be returned. Calling generate() is the * equivalent of: *

         *    TimeStampResponse tsResp;
         *
         *    try
         *    {
         *       tsResp = tsRespGen.generateGrantedResponse(request, serialNumber, genTime, "Operation Okay");
         *    }
         *    catch (Exception e)
         *    {
         *        tsResp = tsRespGen.generateRejectedResponse(e);
         *    }
         * 
    * @param request the request this response is for. * @param serialNumber serial number for the response token. * @param genTime generation time for the response token. * @return a TimeStampResponse. * @throws TSPException */ public TimeStampResponse generate( TimeStampRequest request, BigInteger serialNumber, Date genTime) throws TSPException { try { return this.generateGrantedResponse(request, serialNumber, genTime, "Operation Okay"); } catch (Exception e) { return this.generateRejectedResponse(e); } } /** * Return a granted response, if the passed in request passes validation. *

    * If genTime is null a timeNotAvailable or a validation exception occurs a TSPValidationException will * be thrown. The parent TSPException will only occur on some sort of system failure. *

    * @param request the request this response is for. * @param serialNumber serial number for the response token. * @param genTime generation time for the response token. * @return the TimeStampResponse with a status of PKIStatus.GRANTED * @throws TSPException on validation exception or internal error. */ public TimeStampResponse generateGrantedResponse( TimeStampRequest request, BigInteger serialNumber, Date genTime) throws TSPException { return generateGrantedResponse(request, serialNumber, genTime, null); } /** * Return a granted response, if the passed in request passes validation with the passed in status string. *

    * If genTime is null a timeNotAvailable or a validation exception occurs a TSPValidationException will * be thrown. The parent TSPException will only occur on some sort of system failure. *

    * @param request the request this response is for. * @param serialNumber serial number for the response token. * @param genTime generation time for the response token. * @return the TimeStampResponse with a status of PKIStatus.GRANTED * @throws TSPException on validation exception or internal error. */ public TimeStampResponse generateGrantedResponse( TimeStampRequest request, BigInteger serialNumber, Date genTime, String statusString) throws TSPException { if (genTime == null) { throw new TSPValidationException("The time source is not available.", PKIFailureInfo.timeNotAvailable); } request.validate(acceptedAlgorithms, acceptedPolicies, acceptedExtensions); status = PKIStatus.GRANTED; statusStrings = new ASN1EncodableVector(); if (statusString != null) { this.addStatusString(statusString); } PKIStatusInfo pkiStatusInfo = getPKIStatusInfo(); ContentInfo tstTokenContentInfo; try { tstTokenContentInfo = tokenGenerator.generate(request, serialNumber, genTime).toCMSSignedData().toASN1Structure(); } catch (TSPException e) { throw e; } catch (Exception e) { throw new TSPException( "Timestamp token received cannot be converted to ContentInfo", e); } TimeStampResp resp = new TimeStampResp(pkiStatusInfo, tstTokenContentInfo); try { return new TimeStampResponse(resp); } catch (IOException e) { throw new TSPException("created badly formatted response!"); } } /** * Generate a generic rejection response based on a TSPValidationException or * an Exception. Exceptions which are not an instance of TSPValidationException * will be treated as systemFailure. The return value of exception.getMessage() will * be used as the status string for the response. * * @param exception the exception thrown on validating the request. * @return a TimeStampResponse. * @throws TSPException if a failure response cannot be generated. */ public TimeStampResponse generateRejectedResponse(Exception exception) throws TSPException { if (exception instanceof TSPValidationException) { return generateFailResponse(PKIStatus.REJECTION, ((TSPValidationException)exception).getFailureCode(), exception.getMessage()); } else { return generateFailResponse(PKIStatus.REJECTION, PKIFailureInfo.systemFailure, exception.getMessage()); } } /** * Generate a non-granted TimeStampResponse with chosen status and FailInfoField. * * @param status the PKIStatus to set. * @param failInfoField the FailInfoField to set. * @param statusString an optional string describing the failure. * @return a TimeStampResponse with a failInfoField and optional statusString * @throws TSPException in case the response could not be created */ public TimeStampResponse generateFailResponse(int status, int failInfoField, String statusString) throws TSPException { this.status = status; this.statusStrings = new ASN1EncodableVector(); this.setFailInfoField(failInfoField); if (statusString != null) { this.addStatusString(statusString); } PKIStatusInfo pkiStatusInfo = getPKIStatusInfo(); TimeStampResp resp = new TimeStampResp(pkiStatusInfo, null); try { return new TimeStampResponse(resp); } catch (IOException e) { throw new TSPException("created badly formatted response!"); } } private Set convert(Set orig) { if (orig == null) { return orig; } Set con = new HashSet(orig.size()); for (Iterator it = orig.iterator(); it.hasNext();) { Object o = it.next(); if (o instanceof String) { con.add(new ASN1ObjectIdentifier((String)o)); } else { con.add(o); } } return con; } class FailInfo extends DERBitString { FailInfo(int failInfoValue) { super(getBytes(failInfoValue), getPadBits(failInfoValue)); } } } bouncycastle-1.49.orig/src/org/bouncycastle/tsp/TimeStampRequest.java0000644000175000017500000002074711724561171025446 0ustar ebourgebourgpackage org.bouncycastle.tsp; import java.io.ByteArrayInputStream; import java.io.IOException; import java.io.InputStream; import java.math.BigInteger; import java.security.NoSuchProviderException; import java.util.Arrays; import java.util.Collections; import java.util.Enumeration; import java.util.HashSet; import java.util.Iterator; import java.util.List; import java.util.Set; import org.bouncycastle.asn1.ASN1InputStream; import org.bouncycastle.asn1.ASN1ObjectIdentifier; import org.bouncycastle.asn1.DERObjectIdentifier; import org.bouncycastle.asn1.cmp.PKIFailureInfo; import org.bouncycastle.asn1.tsp.TimeStampReq; import org.bouncycastle.asn1.x509.Extension; import org.bouncycastle.asn1.x509.Extensions; /** * Base class for an RFC 3161 Time Stamp Request. */ public class TimeStampRequest { private static Set EMPTY_SET = Collections.unmodifiableSet(new HashSet()); private TimeStampReq req; private Extensions extensions; public TimeStampRequest(TimeStampReq req) { this.req = req; this.extensions = req.getExtensions(); } /** * Create a TimeStampRequest from the past in byte array. * * @param req byte array containing the request. * @throws IOException if the request is malformed. */ public TimeStampRequest(byte[] req) throws IOException { this(new ByteArrayInputStream(req)); } /** * Create a TimeStampRequest from the past in input stream. * * @param in input stream containing the request. * @throws IOException if the request is malformed. */ public TimeStampRequest(InputStream in) throws IOException { try { this.req = TimeStampReq.getInstance(new ASN1InputStream(in).readObject()); } catch (ClassCastException e) { throw new IOException("malformed request: " + e); } catch (IllegalArgumentException e) { throw new IOException("malformed request: " + e); } } public int getVersion() { return req.getVersion().getValue().intValue(); } public ASN1ObjectIdentifier getMessageImprintAlgOID() { return req.getMessageImprint().getHashAlgorithm().getAlgorithm(); } public byte[] getMessageImprintDigest() { return req.getMessageImprint().getHashedMessage(); } public ASN1ObjectIdentifier getReqPolicy() { if (req.getReqPolicy() != null) { return req.getReqPolicy(); } else { return null; } } public BigInteger getNonce() { if (req.getNonce() != null) { return req.getNonce().getValue(); } else { return null; } } public boolean getCertReq() { if (req.getCertReq() != null) { return req.getCertReq().isTrue(); } else { return false; } } /** * Validate the timestamp request, checking the digest to see if it is of an * accepted type and whether it is of the correct length for the algorithm specified. * * @param algorithms a set of String OIDS giving accepted algorithms. * @param policies if non-null a set of policies we are willing to sign under. * @param extensions if non-null a set of extensions we are willing to accept. * @param provider the provider to confirm the digest size against. * @throws TSPException if the request is invalid, or processing fails. * @deprecated use validate method without provider argument. */ public void validate( Set algorithms, Set policies, Set extensions, String provider) throws TSPException, NoSuchProviderException { validate(algorithms, policies, extensions); } /** * Validate the timestamp request, checking the digest to see if it is of an * accepted type and whether it is of the correct length for the algorithm specified. * * @param algorithms a set of OIDs giving accepted algorithms. * @param policies if non-null a set of policies OIDs we are willing to sign under. * @param extensions if non-null a set of extensions OIDs we are willing to accept. * @throws TSPException if the request is invalid, or processing fails. */ public void validate( Set algorithms, Set policies, Set extensions) throws TSPException { algorithms = convert(algorithms); policies = convert(policies); extensions = convert(extensions); if (!algorithms.contains(this.getMessageImprintAlgOID())) { throw new TSPValidationException("request contains unknown algorithm.", PKIFailureInfo.badAlg); } if (policies != null && this.getReqPolicy() != null && !policies.contains(this.getReqPolicy())) { throw new TSPValidationException("request contains unknown policy.", PKIFailureInfo.unacceptedPolicy); } if (this.getExtensions() != null && extensions != null) { Enumeration en = this.getExtensions().oids(); while(en.hasMoreElements()) { String oid = ((DERObjectIdentifier)en.nextElement()).getId(); if (!extensions.contains(oid)) { throw new TSPValidationException("request contains unknown extension.", PKIFailureInfo.unacceptedExtension); } } } int digestLength = TSPUtil.getDigestLength(this.getMessageImprintAlgOID().getId()); if (digestLength != this.getMessageImprintDigest().length) { throw new TSPValidationException("imprint digest the wrong length.", PKIFailureInfo.badDataFormat); } } /** * return the ASN.1 encoded representation of this object. * @return the default ASN,1 byte encoding for the object. */ public byte[] getEncoded() throws IOException { return req.getEncoded(); } Extensions getExtensions() { return extensions; } public boolean hasExtensions() { return extensions != null; } public Extension getExtension(ASN1ObjectIdentifier oid) { if (extensions != null) { return extensions.getExtension(oid); } return null; } public List getExtensionOIDs() { return TSPUtil.getExtensionOIDs(extensions); } /* (non-Javadoc) * @see java.security.cert.X509Extension#getExtensionValue(java.lang.String) * @deprecated use getExtension(ASN1ObjectIdentifier) */ public byte[] getExtensionValue(String oid) { Extensions exts = req.getExtensions(); if (exts != null) { Extension ext = exts.getExtension(new ASN1ObjectIdentifier(oid)); if (ext != null) { try { return ext.getExtnValue().getEncoded(); } catch (Exception e) { throw new RuntimeException("error encoding " + e.toString()); } } } return null; } /** * Returns a set of ASN1ObjectIdentifiers giving the non-critical extensions. * @return a set of ASN1ObjectIdentifiers. */ public Set getNonCriticalExtensionOIDs() { if (extensions == null) { return EMPTY_SET; } return Collections.unmodifiableSet(new HashSet(Arrays.asList(extensions.getNonCriticalExtensionOIDs()))); } /** * Returns a set of ASN1ObjectIdentifiers giving the critical extensions. * @return a set of ASN1ObjectIdentifiers. */ public Set getCriticalExtensionOIDs() { if (extensions == null) { return EMPTY_SET; } return Collections.unmodifiableSet(new HashSet(Arrays.asList(extensions.getCriticalExtensionOIDs()))); } private Set convert(Set orig) { if (orig == null) { return orig; } Set con = new HashSet(orig.size()); for (Iterator it = orig.iterator(); it.hasNext();) { Object o = it.next(); if (o instanceof String) { con.add(new ASN1ObjectIdentifier((String)o)); } else { con.add(o); } } return con; } } bouncycastle-1.49.orig/src/org/bouncycastle/tsp/TimeStampTokenGenerator.java0000644000175000017500000005173012117510172026731 0ustar ebourgebourgpackage org.bouncycastle.tsp; import java.io.ByteArrayOutputStream; import java.io.IOException; import java.io.OutputStream; import java.math.BigInteger; import java.security.MessageDigest; import java.security.NoSuchAlgorithmException; import java.security.NoSuchProviderException; import java.security.PrivateKey; import java.security.cert.CRLException; import java.security.cert.CertStore; import java.security.cert.CertStoreException; import java.security.cert.CertificateEncodingException; import java.security.cert.X509CRL; import java.security.cert.X509Certificate; import java.security.interfaces.DSAPrivateKey; import java.security.interfaces.RSAPrivateKey; import java.util.ArrayList; import java.util.Collection; import java.util.Date; import java.util.Hashtable; import java.util.Iterator; import java.util.List; import java.util.Map; import org.bouncycastle.asn1.ASN1Boolean; import org.bouncycastle.asn1.ASN1Encoding; import org.bouncycastle.asn1.ASN1GeneralizedTime; import org.bouncycastle.asn1.ASN1Integer; import org.bouncycastle.asn1.ASN1ObjectIdentifier; import org.bouncycastle.asn1.DERNull; import org.bouncycastle.asn1.DERSet; import org.bouncycastle.asn1.cms.Attribute; import org.bouncycastle.asn1.cms.AttributeTable; import org.bouncycastle.asn1.ess.ESSCertID; import org.bouncycastle.asn1.ess.ESSCertIDv2; import org.bouncycastle.asn1.ess.SigningCertificate; import org.bouncycastle.asn1.ess.SigningCertificateV2; import org.bouncycastle.asn1.oiw.OIWObjectIdentifiers; import org.bouncycastle.asn1.pkcs.PKCSObjectIdentifiers; import org.bouncycastle.asn1.tsp.Accuracy; import org.bouncycastle.asn1.tsp.MessageImprint; import org.bouncycastle.asn1.tsp.TSTInfo; import org.bouncycastle.asn1.x509.AlgorithmIdentifier; import org.bouncycastle.asn1.x509.GeneralName; import org.bouncycastle.cert.jcajce.JcaX509CRLHolder; import org.bouncycastle.cert.jcajce.JcaX509CertificateHolder; import org.bouncycastle.cms.CMSAttributeTableGenerationException; import org.bouncycastle.cms.CMSAttributeTableGenerator; import org.bouncycastle.cms.CMSException; import org.bouncycastle.cms.CMSProcessableByteArray; import org.bouncycastle.cms.CMSSignedData; import org.bouncycastle.cms.CMSSignedDataGenerator; import org.bouncycastle.cms.CMSSignedGenerator; import org.bouncycastle.cms.DefaultSignedAttributeTableGenerator; import org.bouncycastle.cms.SignerInfoGenerator; import org.bouncycastle.cms.SimpleAttributeTableGenerator; import org.bouncycastle.cms.jcajce.JcaSignerInfoGeneratorBuilder; import org.bouncycastle.jce.interfaces.GOST3410PrivateKey; import org.bouncycastle.operator.DigestCalculator; import org.bouncycastle.operator.OperatorCreationException; import org.bouncycastle.operator.jcajce.JcaContentSignerBuilder; import org.bouncycastle.operator.jcajce.JcaDigestCalculatorProviderBuilder; import org.bouncycastle.util.CollectionStore; import org.bouncycastle.util.Store; /** * Currently the class supports ESSCertID by if a digest calculator based on SHA1 is passed in, otherwise it uses * ESSCertIDv2. In the event you need to pass both types, you will need to override the SignedAttributeGenerator * for the SignerInfoGeneratorBuilder you are using. For the default for ESSCertIDv2 the code will look something * like the following: *
     * final ESSCertID essCertid = new ESSCertID(certHashSha1, issuerSerial);
     * final ESSCertIDv2 essCertidV2 = new ESSCertIDv2(certHashSha256, issuerSerial);
     *
     * signerInfoGenBuilder.setSignedAttributeGenerator(new CMSAttributeTableGenerator()
     * {
     *     public AttributeTable getAttributes(Map parameters)
     *         throws CMSAttributeTableGenerationException
     *     {
     *         CMSAttributeTableGenerator attrGen = new DefaultSignedAttributeTableGenerator();
     *
     *         AttributeTable table = attrGen.getAttributes(parameters);
     *
     *         table = table.add(PKCSObjectIdentifiers.id_aa_signingCertificate, new SigningCertificate(essCertid));
     *         table = table.add(PKCSObjectIdentifiers.id_aa_signingCertificateV2, new SigningCertificateV2(essCertidV2));
     *
     *         return table;
     *     }
     * });
     * 
    */ public class TimeStampTokenGenerator { int accuracySeconds = -1; int accuracyMillis = -1; int accuracyMicros = -1; boolean ordering = false; GeneralName tsa = null; private ASN1ObjectIdentifier tsaPolicyOID; PrivateKey key; X509Certificate cert; String digestOID; AttributeTable signedAttr; AttributeTable unsignedAttr; private List certs = new ArrayList(); private List crls = new ArrayList(); private List attrCerts = new ArrayList(); private SignerInfoGenerator signerInfoGen; /** * Basic Constructor - set up a calculator based on signerInfoGen with a ESSCertID calculated from * the signer's associated certificate using the sha1DigestCalculator. If alternate values are required * for id-aa-signingCertificate they should be added to the signerInfoGen object before it is passed in, * otherwise a standard digest based value will be added. * * @param signerInfoGen the generator for the signer we are using. * @param digestCalculator calculator for to use for digest of certificate. * @param tsaPolicy tasPolicy to send. * @throws IllegalArgumentException if calculator is not SHA-1 or there is no associated certificate for the signer, * @throws TSPException if the signer certificate cannot be processed. */ public TimeStampTokenGenerator( final SignerInfoGenerator signerInfoGen, DigestCalculator digestCalculator, ASN1ObjectIdentifier tsaPolicy) throws IllegalArgumentException, TSPException { this.signerInfoGen = signerInfoGen; this.tsaPolicyOID = tsaPolicy; if (!signerInfoGen.hasAssociatedCertificate()) { throw new IllegalArgumentException("SignerInfoGenerator must have an associated certificate"); } TSPUtil.validateCertificate(signerInfoGen.getAssociatedCertificate()); try { OutputStream dOut = digestCalculator.getOutputStream(); dOut.write(signerInfoGen.getAssociatedCertificate().getEncoded()); dOut.close(); if (digestCalculator.getAlgorithmIdentifier().getAlgorithm().equals(OIWObjectIdentifiers.idSHA1)) { final ESSCertID essCertid = new ESSCertID(digestCalculator.getDigest()); this.signerInfoGen = new SignerInfoGenerator(signerInfoGen, new CMSAttributeTableGenerator() { public AttributeTable getAttributes(Map parameters) throws CMSAttributeTableGenerationException { AttributeTable table = signerInfoGen.getSignedAttributeTableGenerator().getAttributes(parameters); if (table.get(PKCSObjectIdentifiers.id_aa_signingCertificate) == null) { return table.add(PKCSObjectIdentifiers.id_aa_signingCertificate, new SigningCertificate(essCertid)); } return table; } }, signerInfoGen.getUnsignedAttributeTableGenerator()); } else { AlgorithmIdentifier digAlgID = new AlgorithmIdentifier(digestCalculator.getAlgorithmIdentifier().getAlgorithm()); final ESSCertIDv2 essCertid = new ESSCertIDv2(digAlgID, digestCalculator.getDigest()); this.signerInfoGen = new SignerInfoGenerator(signerInfoGen, new CMSAttributeTableGenerator() { public AttributeTable getAttributes(Map parameters) throws CMSAttributeTableGenerationException { AttributeTable table = signerInfoGen.getSignedAttributeTableGenerator().getAttributes(parameters); if (table.get(PKCSObjectIdentifiers.id_aa_signingCertificateV2) == null) { return table.add(PKCSObjectIdentifiers.id_aa_signingCertificateV2, new SigningCertificateV2(essCertid)); } return table; } }, signerInfoGen.getUnsignedAttributeTableGenerator()); } } catch (IOException e) { throw new TSPException("Exception processing certificate.", e); } } /** * Basic Constructor - set up a calculator based on signerInfoGen with a ESSCertID calculated from * the signer's associated certificate using the sha1DigestCalculator. * * @param sha1DigestCalculator calculator for SHA-1 of certificate. * @param signerInfoGen the generator for the signer we are using. * @param tsaPolicy tasPolicy to send. * @throws IllegalArgumentException if calculator is not SHA-1 or there is no associated certificate for the signer, * @throws TSPException if the signer certificate cannot be processed. * @deprecated use constructor taking signerInfoGen first. */ public TimeStampTokenGenerator( DigestCalculator sha1DigestCalculator, final SignerInfoGenerator signerInfoGen, ASN1ObjectIdentifier tsaPolicy) throws IllegalArgumentException, TSPException { this(signerInfoGen, sha1DigestCalculator, tsaPolicy); } /** * basic creation - only the default attributes will be included here. * @deprecated use SignerInfoGenerator constructor that takes a digest calculator */ public TimeStampTokenGenerator( final SignerInfoGenerator signerInfoGen, ASN1ObjectIdentifier tsaPolicy) throws IllegalArgumentException, TSPException { this(new DigestCalculator() { private ByteArrayOutputStream bOut = new ByteArrayOutputStream(); public AlgorithmIdentifier getAlgorithmIdentifier() { return new AlgorithmIdentifier(OIWObjectIdentifiers.idSHA1, DERNull.INSTANCE); } public OutputStream getOutputStream() { return bOut; } public byte[] getDigest() { try { return MessageDigest.getInstance("SHA-1").digest(bOut.toByteArray()); } catch (NoSuchAlgorithmException e) { throw new IllegalStateException("cannot find sha-1: "+ e.getMessage()); } } }, signerInfoGen, tsaPolicy); } /** * basic creation - only the default attributes will be included here. * @deprecated use SignerInfoGenerator constructor that takes a digest calculator. */ public TimeStampTokenGenerator( PrivateKey key, X509Certificate cert, String digestOID, String tsaPolicyOID) throws IllegalArgumentException, TSPException { this(key, cert, digestOID, tsaPolicyOID, null, null); } /** * basic creation - only the default attributes will be included here. * @deprecated use SignerInfoGenerator constructor that takes a digest calculator. */ public TimeStampTokenGenerator( PrivateKey key, X509Certificate cert, ASN1ObjectIdentifier digestOID, String tsaPolicyOID) throws IllegalArgumentException, TSPException { this(key, cert, digestOID.getId(), tsaPolicyOID, null, null); } /** * create with a signer with extra signed/unsigned attributes. * @deprecated use SignerInfoGenerator constructor that takes a digest calculator. */ public TimeStampTokenGenerator( PrivateKey key, X509Certificate cert, String digestOID, String tsaPolicyOID, AttributeTable signedAttr, AttributeTable unsignedAttr) throws IllegalArgumentException, TSPException { this.key = key; this.cert = cert; this.digestOID = digestOID; this.tsaPolicyOID = new ASN1ObjectIdentifier(tsaPolicyOID); this.unsignedAttr = unsignedAttr; // // add the essCertid // Hashtable signedAttrs = null; if (signedAttr != null) { signedAttrs = signedAttr.toHashtable(); } else { signedAttrs = new Hashtable(); } TSPUtil.validateCertificate(cert); try { ESSCertID essCertid = new ESSCertID(MessageDigest.getInstance("SHA-1").digest(cert.getEncoded())); signedAttrs.put(PKCSObjectIdentifiers.id_aa_signingCertificate, new Attribute( PKCSObjectIdentifiers.id_aa_signingCertificate, new DERSet(new SigningCertificate(essCertid)))); } catch (NoSuchAlgorithmException e) { throw new TSPException("Can't find a SHA-1 implementation.", e); } catch (CertificateEncodingException e) { throw new TSPException("Exception processing certificate.", e); } this.signedAttr = new AttributeTable(signedAttrs); } /** * @deprecated use addCertificates and addCRLs * @param certificates * @throws CertStoreException * @throws TSPException */ public void setCertificatesAndCRLs(CertStore certificates) throws CertStoreException, TSPException { Collection c1 = certificates.getCertificates(null); for (Iterator it = c1.iterator(); it.hasNext();) { try { certs.add(new JcaX509CertificateHolder((X509Certificate)it.next())); } catch (CertificateEncodingException e) { throw new TSPException("cannot encode certificate: " + e.getMessage(), e); } } c1 = certificates.getCRLs(null); for (Iterator it = c1.iterator(); it.hasNext();) { try { crls.add(new JcaX509CRLHolder((X509CRL)it.next())); } catch (CRLException e) { throw new TSPException("cannot encode CRL: " + e.getMessage(), e); } } } /** * Add the store of X509 Certificates to the generator. * * @param certStore a Store containing X509CertificateHolder objects */ public void addCertificates( Store certStore) { certs.addAll(certStore.getMatches(null)); } /** * * @param crlStore a Store containing X509CRLHolder objects. */ public void addCRLs( Store crlStore) { crls.addAll(crlStore.getMatches(null)); } /** * * @param attrStore a Store containing X509AttributeCertificate objects. */ public void addAttributeCertificates( Store attrStore) { attrCerts.addAll(attrStore.getMatches(null)); } public void setAccuracySeconds(int accuracySeconds) { this.accuracySeconds = accuracySeconds; } public void setAccuracyMillis(int accuracyMillis) { this.accuracyMillis = accuracyMillis; } public void setAccuracyMicros(int accuracyMicros) { this.accuracyMicros = accuracyMicros; } public void setOrdering(boolean ordering) { this.ordering = ordering; } public void setTSA(GeneralName tsa) { this.tsa = tsa; } //------------------------------------------------------------------------------ public TimeStampToken generate( TimeStampRequest request, BigInteger serialNumber, Date genTime, String provider) throws NoSuchAlgorithmException, NoSuchProviderException, TSPException { if (signerInfoGen == null) { try { JcaSignerInfoGeneratorBuilder sigBuilder = new JcaSignerInfoGeneratorBuilder(new JcaDigestCalculatorProviderBuilder().setProvider(provider).build()); sigBuilder.setSignedAttributeGenerator(new DefaultSignedAttributeTableGenerator(signedAttr)); if (unsignedAttr != null) { sigBuilder.setUnsignedAttributeGenerator(new SimpleAttributeTableGenerator(unsignedAttr)); } signerInfoGen = sigBuilder.build(new JcaContentSignerBuilder(getSigAlgorithm(key, digestOID)).setProvider(provider).build(key), cert); } catch (OperatorCreationException e) { throw new TSPException("Error generating signing operator", e); } catch (CertificateEncodingException e) { throw new TSPException("Error encoding certificate", e); } } return generate(request, serialNumber, genTime); } public TimeStampToken generate( TimeStampRequest request, BigInteger serialNumber, Date genTime) throws TSPException { if (signerInfoGen == null) { throw new IllegalStateException("can only use this method with SignerInfoGenerator constructor"); } ASN1ObjectIdentifier digestAlgOID = request.getMessageImprintAlgOID(); AlgorithmIdentifier algID = new AlgorithmIdentifier(digestAlgOID, DERNull.INSTANCE); MessageImprint messageImprint = new MessageImprint(algID, request.getMessageImprintDigest()); Accuracy accuracy = null; if (accuracySeconds > 0 || accuracyMillis > 0 || accuracyMicros > 0) { ASN1Integer seconds = null; if (accuracySeconds > 0) { seconds = new ASN1Integer(accuracySeconds); } ASN1Integer millis = null; if (accuracyMillis > 0) { millis = new ASN1Integer(accuracyMillis); } ASN1Integer micros = null; if (accuracyMicros > 0) { micros = new ASN1Integer(accuracyMicros); } accuracy = new Accuracy(seconds, millis, micros); } ASN1Boolean derOrdering = null; if (ordering) { derOrdering = new ASN1Boolean(ordering); } ASN1Integer nonce = null; if (request.getNonce() != null) { nonce = new ASN1Integer(request.getNonce()); } ASN1ObjectIdentifier tsaPolicy = tsaPolicyOID; if (request.getReqPolicy() != null) { tsaPolicy = request.getReqPolicy(); } TSTInfo tstInfo = new TSTInfo(tsaPolicy, messageImprint, new ASN1Integer(serialNumber), new ASN1GeneralizedTime(genTime), accuracy, derOrdering, nonce, tsa, request.getExtensions()); try { CMSSignedDataGenerator signedDataGenerator = new CMSSignedDataGenerator(); if (request.getCertReq()) { // TODO: do we need to check certs non-empty? signedDataGenerator.addCertificates(new CollectionStore(certs)); signedDataGenerator.addCRLs(new CollectionStore(crls)); signedDataGenerator.addAttributeCertificates(new CollectionStore(attrCerts)); } else { signedDataGenerator.addCRLs(new CollectionStore(crls)); } signedDataGenerator.addSignerInfoGenerator(signerInfoGen); byte[] derEncodedTSTInfo = tstInfo.getEncoded(ASN1Encoding.DER); CMSSignedData signedData = signedDataGenerator.generate(new CMSProcessableByteArray(PKCSObjectIdentifiers.id_ct_TSTInfo, derEncodedTSTInfo), true); return new TimeStampToken(signedData); } catch (CMSException cmsEx) { throw new TSPException("Error generating time-stamp token", cmsEx); } catch (IOException e) { throw new TSPException("Exception encoding info", e); } } private String getSigAlgorithm( PrivateKey key, String digestOID) { String enc = null; if (key instanceof RSAPrivateKey || "RSA".equalsIgnoreCase(key.getAlgorithm())) { enc = "RSA"; } else if (key instanceof DSAPrivateKey || "DSA".equalsIgnoreCase(key.getAlgorithm())) { enc = "DSA"; } else if ("ECDSA".equalsIgnoreCase(key.getAlgorithm()) || "EC".equalsIgnoreCase(key.getAlgorithm())) { enc = "ECDSA"; } else if (key instanceof GOST3410PrivateKey || "GOST3410".equalsIgnoreCase(key.getAlgorithm())) { enc = "GOST3410"; } else if ("ECGOST3410".equalsIgnoreCase(key.getAlgorithm())) { enc = CMSSignedGenerator.ENCRYPTION_ECGOST3410; } return TSPUtil.getDigestAlgName(digestOID) + "with" + enc; } } bouncycastle-1.49.orig/src/org/bouncycastle/tsp/cms/0000755000175000017500000000000012152033551022067 5ustar ebourgebourgbouncycastle-1.49.orig/src/org/bouncycastle/tsp/cms/CMSTimeStampedDataParser.java0000644000175000017500000001457711624652552027511 0ustar ebourgebourgpackage org.bouncycastle.tsp.cms; import java.io.ByteArrayInputStream; import java.io.IOException; import java.io.InputStream; import java.net.URI; import java.net.URISyntaxException; import org.bouncycastle.asn1.BERTags; import org.bouncycastle.asn1.DERIA5String; import org.bouncycastle.asn1.cms.AttributeTable; import org.bouncycastle.asn1.cms.CMSObjectIdentifiers; import org.bouncycastle.asn1.cms.ContentInfoParser; import org.bouncycastle.asn1.cms.TimeStampedDataParser; import org.bouncycastle.cms.CMSContentInfoParser; import org.bouncycastle.cms.CMSException; import org.bouncycastle.operator.DigestCalculator; import org.bouncycastle.operator.DigestCalculatorProvider; import org.bouncycastle.operator.OperatorCreationException; import org.bouncycastle.tsp.TimeStampToken; import org.bouncycastle.util.io.Streams; public class CMSTimeStampedDataParser extends CMSContentInfoParser { private TimeStampedDataParser timeStampedData; private TimeStampDataUtil util; public CMSTimeStampedDataParser(InputStream in) throws CMSException { super(in); initialize(_contentInfo); } public CMSTimeStampedDataParser(byte[] baseData) throws CMSException { this(new ByteArrayInputStream(baseData)); } private void initialize(ContentInfoParser contentInfo) throws CMSException { try { if (CMSObjectIdentifiers.timestampedData.equals(contentInfo.getContentType())) { this.timeStampedData = TimeStampedDataParser.getInstance(contentInfo.getContent(BERTags.SEQUENCE)); } else { throw new IllegalArgumentException("Malformed content - type must be " + CMSObjectIdentifiers.timestampedData.getId()); } } catch (IOException e) { throw new CMSException("parsing exception: " + e.getMessage(), e); } } public byte[] calculateNextHash(DigestCalculator calculator) throws CMSException { return util.calculateNextHash(calculator); } public InputStream getContent() { if (timeStampedData.getContent() != null) { return timeStampedData.getContent().getOctetStream(); } return null; } public URI getDataUri() throws URISyntaxException { DERIA5String dataURI = this.timeStampedData.getDataUri(); if (dataURI != null) { return new URI(dataURI.getString()); } return null; } public String getFileName() { return util.getFileName(); } public String getMediaType() { return util.getMediaType(); } public AttributeTable getOtherMetaData() { return util.getOtherMetaData(); } /** * Initialise the passed in calculator with the MetaData for this message, if it is * required as part of the initial message imprint calculation. * * @param calculator the digest calculator to be initialised. * @throws CMSException if the MetaData is required and cannot be processed */ public void initialiseMessageImprintDigestCalculator(DigestCalculator calculator) throws CMSException { util.initialiseMessageImprintDigestCalculator(calculator); } /** * Returns an appropriately initialised digest calculator based on the message imprint algorithm * described in the first time stamp in the TemporalData for this message. If the metadata is required * to be included in the digest calculation, the returned calculator will be pre-initialised. * * @param calculatorProvider a provider of DigestCalculator objects. * @return an initialised digest calculator. * @throws OperatorCreationException if the provider is unable to create the calculator. */ public DigestCalculator getMessageImprintDigestCalculator(DigestCalculatorProvider calculatorProvider) throws OperatorCreationException { try { parseTimeStamps(); } catch (CMSException e) { throw new OperatorCreationException("unable to extract algorithm ID: " + e.getMessage(), e); } return util.getMessageImprintDigestCalculator(calculatorProvider); } public TimeStampToken[] getTimeStampTokens() throws CMSException { parseTimeStamps(); return util.getTimeStampTokens(); } /** * Validate the digests present in the TimeStampTokens contained in the CMSTimeStampedData. * * @param calculatorProvider provider for digest calculators * @param dataDigest the calculated data digest for the message * @throws ImprintDigestInvalidException if an imprint digest fails to compare * @throws CMSException if an exception occurs processing the message. */ public void validate(DigestCalculatorProvider calculatorProvider, byte[] dataDigest) throws ImprintDigestInvalidException, CMSException { parseTimeStamps(); util.validate(calculatorProvider, dataDigest); } /** * Validate the passed in timestamp token against the tokens and data present in the message. * * @param calculatorProvider provider for digest calculators * @param dataDigest the calculated data digest for the message. * @param timeStampToken the timestamp token of interest. * @throws ImprintDigestInvalidException if the token is not present in the message, or an imprint digest fails to compare. * @throws CMSException if an exception occurs processing the message. */ public void validate(DigestCalculatorProvider calculatorProvider, byte[] dataDigest, TimeStampToken timeStampToken) throws ImprintDigestInvalidException, CMSException { parseTimeStamps(); util.validate(calculatorProvider, dataDigest, timeStampToken); } private void parseTimeStamps() throws CMSException { try { if (util == null) { InputStream cont = this.getContent(); if (cont != null) { Streams.drain(cont); } util = new TimeStampDataUtil(timeStampedData); } } catch (IOException e) { throw new CMSException("unable to parse evidence block: " + e.getMessage(), e); } } } bouncycastle-1.49.orig/src/org/bouncycastle/tsp/cms/CMSTimeStampedGenerator.java0000644000175000017500000000567711737275252027415 0ustar ebourgebourgpackage org.bouncycastle.tsp.cms; import java.net.URI; import org.bouncycastle.asn1.ASN1Boolean; import org.bouncycastle.asn1.DERIA5String; import org.bouncycastle.asn1.DERUTF8String; import org.bouncycastle.asn1.cms.Attributes; import org.bouncycastle.asn1.cms.MetaData; import org.bouncycastle.cms.CMSException; import org.bouncycastle.operator.DigestCalculator; public class CMSTimeStampedGenerator { protected MetaData metaData; protected URI dataUri; /** * Set the dataURI to be included in message. * * @param dataUri URI for the data the initial message imprint digest is based on. */ public void setDataUri(URI dataUri) { this.dataUri = dataUri; } /** * Set the MetaData for the generated message. * * @param hashProtected true if the MetaData should be included in first imprint calculation, false otherwise. * @param fileName optional file name, may be null. * @param mediaType optional media type, may be null. */ public void setMetaData(boolean hashProtected, String fileName, String mediaType) { setMetaData(hashProtected, fileName, mediaType, null); } /** * Set the MetaData for the generated message. * * @param hashProtected true if the MetaData should be included in first imprint calculation, false otherwise. * @param fileName optional file name, may be null. * @param mediaType optional media type, may be null. * @param attributes optional attributes, may be null. */ public void setMetaData(boolean hashProtected, String fileName, String mediaType, Attributes attributes) { DERUTF8String asn1FileName = null; if (fileName != null) { asn1FileName = new DERUTF8String(fileName); } DERIA5String asn1MediaType = null; if (mediaType != null) { asn1MediaType = new DERIA5String(mediaType); } setMetaData(hashProtected, asn1FileName, asn1MediaType, attributes); } private void setMetaData(boolean hashProtected, DERUTF8String fileName, DERIA5String mediaType, Attributes attributes) { this.metaData = new MetaData(ASN1Boolean.getInstance(hashProtected), fileName, mediaType, attributes); } /** * Initialise the passed in calculator with the MetaData for this message, if it is * required as part of the initial message imprint calculation. After initialisation the * calculator can then be used to calculate the initial message imprint digest for the first * timestamp. * * @param calculator the digest calculator to be initialised. * @throws CMSException if the MetaData is required and cannot be processed */ public void initialiseMessageImprintDigestCalculator(DigestCalculator calculator) throws CMSException { MetaDataUtil util = new MetaDataUtil(metaData); util.initialiseMessageImprintDigestCalculator(calculator); } } bouncycastle-1.49.orig/src/org/bouncycastle/tsp/cms/CMSTimeStampedData.java0000644000175000017500000001541312150036566026316 0ustar ebourgebourgpackage org.bouncycastle.tsp.cms; import java.io.ByteArrayInputStream; import java.io.IOException; import java.io.InputStream; import java.net.URI; import java.net.URISyntaxException; import org.bouncycastle.asn1.ASN1InputStream; import org.bouncycastle.asn1.DERIA5String; import org.bouncycastle.asn1.cms.AttributeTable; import org.bouncycastle.asn1.cms.CMSObjectIdentifiers; import org.bouncycastle.asn1.cms.ContentInfo; import org.bouncycastle.asn1.cms.Evidence; import org.bouncycastle.asn1.cms.TimeStampAndCRL; import org.bouncycastle.asn1.cms.TimeStampTokenEvidence; import org.bouncycastle.asn1.cms.TimeStampedData; import org.bouncycastle.cms.CMSException; import org.bouncycastle.operator.DigestCalculator; import org.bouncycastle.operator.DigestCalculatorProvider; import org.bouncycastle.operator.OperatorCreationException; import org.bouncycastle.tsp.TimeStampToken; public class CMSTimeStampedData { private TimeStampedData timeStampedData; private ContentInfo contentInfo; private TimeStampDataUtil util; public CMSTimeStampedData(ContentInfo contentInfo) { this.initialize(contentInfo); } public CMSTimeStampedData(InputStream in) throws IOException { try { initialize(ContentInfo.getInstance(new ASN1InputStream(in).readObject())); } catch (ClassCastException e) { throw new IOException("Malformed content: " + e); } catch (IllegalArgumentException e) { throw new IOException("Malformed content: " + e); } } public CMSTimeStampedData(byte[] baseData) throws IOException { this(new ByteArrayInputStream(baseData)); } private void initialize(ContentInfo contentInfo) { this.contentInfo = contentInfo; if (CMSObjectIdentifiers.timestampedData.equals(contentInfo.getContentType())) { this.timeStampedData = TimeStampedData.getInstance(contentInfo.getContent()); } else { throw new IllegalArgumentException("Malformed content - type must be " + CMSObjectIdentifiers.timestampedData.getId()); } util = new TimeStampDataUtil(this.timeStampedData); } public byte[] calculateNextHash(DigestCalculator calculator) throws CMSException { return util.calculateNextHash(calculator); } /** * Return a new timeStampedData object with the additional token attached. * * @throws CMSException */ public CMSTimeStampedData addTimeStamp(TimeStampToken token) throws CMSException { TimeStampAndCRL[] timeStamps = util.getTimeStamps(); TimeStampAndCRL[] newTimeStamps = new TimeStampAndCRL[timeStamps.length + 1]; System.arraycopy(timeStamps, 0, newTimeStamps, 0, timeStamps.length); newTimeStamps[timeStamps.length] = new TimeStampAndCRL(token.toCMSSignedData().toASN1Structure()); return new CMSTimeStampedData(new ContentInfo(CMSObjectIdentifiers.timestampedData, new TimeStampedData(timeStampedData.getDataUri(), timeStampedData.getMetaData(), timeStampedData.getContent(), new Evidence(new TimeStampTokenEvidence(newTimeStamps))))); } public byte[] getContent() { if (timeStampedData.getContent() != null) { return timeStampedData.getContent().getOctets(); } return null; } public URI getDataUri() throws URISyntaxException { DERIA5String dataURI = this.timeStampedData.getDataUri(); if (dataURI != null) { return new URI(dataURI.getString()); } return null; } public String getFileName() { return util.getFileName(); } public String getMediaType() { return util.getMediaType(); } public AttributeTable getOtherMetaData() { return util.getOtherMetaData(); } public TimeStampToken[] getTimeStampTokens() throws CMSException { return util.getTimeStampTokens(); } /** * Initialise the passed in calculator with the MetaData for this message, if it is * required as part of the initial message imprint calculation. * * @param calculator the digest calculator to be initialised. * @throws CMSException if the MetaData is required and cannot be processed */ public void initialiseMessageImprintDigestCalculator(DigestCalculator calculator) throws CMSException { util.initialiseMessageImprintDigestCalculator(calculator); } /** * Returns an appropriately initialised digest calculator based on the message imprint algorithm * described in the first time stamp in the TemporalData for this message. If the metadata is required * to be included in the digest calculation, the returned calculator will be pre-initialised. * * @param calculatorProvider a provider of DigestCalculator objects. * @return an initialised digest calculator. * @throws OperatorCreationException if the provider is unable to create the calculator. */ public DigestCalculator getMessageImprintDigestCalculator(DigestCalculatorProvider calculatorProvider) throws OperatorCreationException { return util.getMessageImprintDigestCalculator(calculatorProvider); } /** * Validate the digests present in the TimeStampTokens contained in the CMSTimeStampedData. * * @param calculatorProvider provider for digest calculators * @param dataDigest the calculated data digest for the message * @throws ImprintDigestInvalidException if an imprint digest fails to compare * @throws CMSException if an exception occurs processing the message. */ public void validate(DigestCalculatorProvider calculatorProvider, byte[] dataDigest) throws ImprintDigestInvalidException, CMSException { util.validate(calculatorProvider, dataDigest); } /** * Validate the passed in timestamp token against the tokens and data present in the message. * * @param calculatorProvider provider for digest calculators * @param dataDigest the calculated data digest for the message. * @param timeStampToken the timestamp token of interest. * @throws ImprintDigestInvalidException if the token is not present in the message, or an imprint digest fails to compare. * @throws CMSException if an exception occurs processing the message. */ public void validate(DigestCalculatorProvider calculatorProvider, byte[] dataDigest, TimeStampToken timeStampToken) throws ImprintDigestInvalidException, CMSException { util.validate(calculatorProvider, dataDigest, timeStampToken); } public byte[] getEncoded() throws IOException { return contentInfo.getEncoded(); } } bouncycastle-1.49.orig/src/org/bouncycastle/tsp/cms/CMSTimeStampedDataGenerator.java0000644000175000017500000000436411732006605030164 0ustar ebourgebourgpackage org.bouncycastle.tsp.cms; import java.io.ByteArrayInputStream; import java.io.ByteArrayOutputStream; import java.io.IOException; import java.io.InputStream; import org.bouncycastle.asn1.ASN1OctetString; import org.bouncycastle.asn1.BEROctetString; import org.bouncycastle.asn1.DERIA5String; import org.bouncycastle.asn1.cms.CMSObjectIdentifiers; import org.bouncycastle.asn1.cms.ContentInfo; import org.bouncycastle.asn1.cms.Evidence; import org.bouncycastle.asn1.cms.TimeStampAndCRL; import org.bouncycastle.asn1.cms.TimeStampTokenEvidence; import org.bouncycastle.asn1.cms.TimeStampedData; import org.bouncycastle.cms.CMSException; import org.bouncycastle.tsp.TimeStampToken; import org.bouncycastle.util.io.Streams; public class CMSTimeStampedDataGenerator extends CMSTimeStampedGenerator { public CMSTimeStampedData generate(TimeStampToken timeStamp) throws CMSException { return generate(timeStamp, (InputStream)null); } public CMSTimeStampedData generate(TimeStampToken timeStamp, byte[] content) throws CMSException { return generate(timeStamp, new ByteArrayInputStream(content)); } public CMSTimeStampedData generate(TimeStampToken timeStamp, InputStream content) throws CMSException { ByteArrayOutputStream contentOut = new ByteArrayOutputStream(); if (content != null) { try { Streams.pipeAll(content, contentOut); } catch (IOException e) { throw new CMSException("exception encapsulating content: " + e.getMessage(), e); } } ASN1OctetString encContent = null; if (contentOut.size() != 0) { encContent = new BEROctetString(contentOut.toByteArray()); } TimeStampAndCRL stamp = new TimeStampAndCRL(timeStamp.toCMSSignedData().toASN1Structure()); DERIA5String asn1DataUri = null; if (dataUri != null) { asn1DataUri = new DERIA5String(dataUri.toString()); } return new CMSTimeStampedData(new ContentInfo(CMSObjectIdentifiers.timestampedData, new TimeStampedData(asn1DataUri, metaData, encContent, new Evidence(new TimeStampTokenEvidence(stamp))))); } } bouncycastle-1.49.orig/src/org/bouncycastle/tsp/cms/MetaDataUtil.java0000644000175000017500000000316511625107245025263 0ustar ebourgebourgpackage org.bouncycastle.tsp.cms; import java.io.IOException; import org.bouncycastle.asn1.ASN1Encoding; import org.bouncycastle.asn1.ASN1String; import org.bouncycastle.asn1.cms.Attributes; import org.bouncycastle.asn1.cms.MetaData; import org.bouncycastle.cms.CMSException; import org.bouncycastle.operator.DigestCalculator; class MetaDataUtil { private final MetaData metaData; MetaDataUtil(MetaData metaData) { this.metaData = metaData; } void initialiseMessageImprintDigestCalculator(DigestCalculator calculator) throws CMSException { if (metaData != null && metaData.isHashProtected()) { try { calculator.getOutputStream().write(metaData.getEncoded(ASN1Encoding.DER)); } catch (IOException e) { throw new CMSException("unable to initialise calculator from metaData: " + e.getMessage(), e); } } } String getFileName() { if (metaData != null) { return convertString(metaData.getFileName()); } return null; } String getMediaType() { if (metaData != null) { return convertString(metaData.getMediaType()); } return null; } Attributes getOtherMetaData() { if (metaData != null) { return metaData.getOtherMetaData(); } return null; } private String convertString(ASN1String s) { if (s != null) { return s.toString(); } return null; } } bouncycastle-1.49.orig/src/org/bouncycastle/tsp/cms/TimeStampDataUtil.java0000644000175000017500000001775011724237047026311 0ustar ebourgebourgpackage org.bouncycastle.tsp.cms; import java.io.IOException; import java.io.OutputStream; import org.bouncycastle.asn1.ASN1Encoding; import org.bouncycastle.asn1.ASN1ObjectIdentifier; import org.bouncycastle.asn1.cms.AttributeTable; import org.bouncycastle.asn1.cms.ContentInfo; import org.bouncycastle.asn1.cms.Evidence; import org.bouncycastle.asn1.cms.TimeStampAndCRL; import org.bouncycastle.asn1.cms.TimeStampedData; import org.bouncycastle.asn1.cms.TimeStampedDataParser; import org.bouncycastle.asn1.x509.AlgorithmIdentifier; import org.bouncycastle.cms.CMSException; import org.bouncycastle.operator.DigestCalculator; import org.bouncycastle.operator.DigestCalculatorProvider; import org.bouncycastle.operator.OperatorCreationException; import org.bouncycastle.tsp.TSPException; import org.bouncycastle.tsp.TimeStampToken; import org.bouncycastle.tsp.TimeStampTokenInfo; import org.bouncycastle.util.Arrays; class TimeStampDataUtil { private final TimeStampAndCRL[] timeStamps; private final MetaDataUtil metaDataUtil; TimeStampDataUtil(TimeStampedData timeStampedData) { this.metaDataUtil = new MetaDataUtil(timeStampedData.getMetaData()); Evidence evidence = timeStampedData.getTemporalEvidence(); this.timeStamps = evidence.getTstEvidence().toTimeStampAndCRLArray(); } TimeStampDataUtil(TimeStampedDataParser timeStampedData) throws IOException { this.metaDataUtil = new MetaDataUtil(timeStampedData.getMetaData()); Evidence evidence = timeStampedData.getTemporalEvidence(); this.timeStamps = evidence.getTstEvidence().toTimeStampAndCRLArray(); } TimeStampToken getTimeStampToken(TimeStampAndCRL timeStampAndCRL) throws CMSException { ContentInfo timeStampToken = timeStampAndCRL.getTimeStampToken(); try { TimeStampToken token = new TimeStampToken(timeStampToken); return token; } catch (IOException e) { throw new CMSException("unable to parse token data: " + e.getMessage(), e); } catch (TSPException e) { if (e.getCause() instanceof CMSException) { throw (CMSException)e.getCause(); } throw new CMSException("token data invalid: " + e.getMessage(), e); } catch (IllegalArgumentException e) { throw new CMSException("token data invalid: " + e.getMessage(), e); } } void initialiseMessageImprintDigestCalculator(DigestCalculator calculator) throws CMSException { metaDataUtil.initialiseMessageImprintDigestCalculator(calculator); } DigestCalculator getMessageImprintDigestCalculator(DigestCalculatorProvider calculatorProvider) throws OperatorCreationException { TimeStampToken token; try { token = this.getTimeStampToken(timeStamps[0]); TimeStampTokenInfo info = token.getTimeStampInfo(); ASN1ObjectIdentifier algOID = info.getMessageImprintAlgOID(); DigestCalculator calc = calculatorProvider.get(new AlgorithmIdentifier(algOID)); initialiseMessageImprintDigestCalculator(calc); return calc; } catch (CMSException e) { throw new OperatorCreationException("unable to extract algorithm ID: " + e.getMessage(), e); } } TimeStampToken[] getTimeStampTokens() throws CMSException { TimeStampToken[] tokens = new TimeStampToken[timeStamps.length]; for (int i = 0; i < timeStamps.length; i++) { tokens[i] = this.getTimeStampToken(timeStamps[i]); } return tokens; } TimeStampAndCRL[] getTimeStamps() { return timeStamps; } byte[] calculateNextHash(DigestCalculator calculator) throws CMSException { TimeStampAndCRL tspToken = timeStamps[timeStamps.length - 1]; OutputStream out = calculator.getOutputStream(); try { out.write(tspToken.getEncoded(ASN1Encoding.DER)); out.close(); return calculator.getDigest(); } catch (IOException e) { throw new CMSException("exception calculating hash: " + e.getMessage(), e); } } /** * Validate the digests present in the TimeStampTokens contained in the CMSTimeStampedData. */ void validate(DigestCalculatorProvider calculatorProvider, byte[] dataDigest) throws ImprintDigestInvalidException, CMSException { byte[] currentDigest = dataDigest; for (int i = 0; i < timeStamps.length; i++) { try { TimeStampToken token = this.getTimeStampToken(timeStamps[i]); if (i > 0) { TimeStampTokenInfo info = token.getTimeStampInfo(); DigestCalculator calculator = calculatorProvider.get(info.getHashAlgorithm()); calculator.getOutputStream().write(timeStamps[i - 1].getEncoded(ASN1Encoding.DER)); currentDigest = calculator.getDigest(); } this.compareDigest(token, currentDigest); } catch (IOException e) { throw new CMSException("exception calculating hash: " + e.getMessage(), e); } catch (OperatorCreationException e) { throw new CMSException("cannot create digest: " + e.getMessage(), e); } } } void validate(DigestCalculatorProvider calculatorProvider, byte[] dataDigest, TimeStampToken timeStampToken) throws ImprintDigestInvalidException, CMSException { byte[] currentDigest = dataDigest; byte[] encToken; try { encToken = timeStampToken.getEncoded(); } catch (IOException e) { throw new CMSException("exception encoding timeStampToken: " + e.getMessage(), e); } for (int i = 0; i < timeStamps.length; i++) { try { TimeStampToken token = this.getTimeStampToken(timeStamps[i]); if (i > 0) { TimeStampTokenInfo info = token.getTimeStampInfo(); DigestCalculator calculator = calculatorProvider.get(info.getHashAlgorithm()); calculator.getOutputStream().write(timeStamps[i - 1].getEncoded(ASN1Encoding.DER)); currentDigest = calculator.getDigest(); } this.compareDigest(token, currentDigest); if (Arrays.areEqual(token.getEncoded(), encToken)) { return; } } catch (IOException e) { throw new CMSException("exception calculating hash: " + e.getMessage(), e); } catch (OperatorCreationException e) { throw new CMSException("cannot create digest: " + e.getMessage(), e); } } throw new ImprintDigestInvalidException("passed in token not associated with timestamps present", timeStampToken); } private void compareDigest(TimeStampToken timeStampToken, byte[] digest) throws ImprintDigestInvalidException { TimeStampTokenInfo info = timeStampToken.getTimeStampInfo(); byte[] tsrMessageDigest = info.getMessageImprintDigest(); if (!Arrays.areEqual(digest, tsrMessageDigest)) { throw new ImprintDigestInvalidException("hash calculated is different from MessageImprintDigest found in TimeStampToken", timeStampToken); } } String getFileName() { return metaDataUtil.getFileName(); } String getMediaType() { return metaDataUtil.getMediaType(); } AttributeTable getOtherMetaData() { return new AttributeTable(metaDataUtil.getOtherMetaData()); } } bouncycastle-1.49.orig/src/org/bouncycastle/tsp/cms/package.html0000644000175000017500000000017612126667214024366 0ustar ebourgebourg Classes for dealing Syntax for Binding Documents with Time-Stamps - RFC 5544. bouncycastle-1.49.orig/src/org/bouncycastle/tsp/cms/ImprintDigestInvalidException.java0000644000175000017500000000063111524654001030703 0ustar ebourgebourgpackage org.bouncycastle.tsp.cms; import org.bouncycastle.tsp.TimeStampToken; public class ImprintDigestInvalidException extends Exception { private TimeStampToken token; public ImprintDigestInvalidException(String message, TimeStampToken token) { super(message); this.token = token; } public TimeStampToken getTimeStampToken() { return token; } } bouncycastle-1.49.orig/src/org/bouncycastle/tsp/TSPIOException.java0000644000175000017500000000103611724315643024736 0ustar ebourgebourgpackage org.bouncycastle.tsp; import java.io.IOException; public class TSPIOException extends IOException { Throwable underlyingException; public TSPIOException(String message) { super(message); } public TSPIOException(String message, Throwable e) { super(message); underlyingException = e; } public Exception getUnderlyingException() { return (Exception)underlyingException; } public Throwable getCause() { return underlyingException; } } bouncycastle-1.49.orig/src/org/bouncycastle/tsp/TimeStampTokenInfo.java0000644000175000017500000000471711724237264025714 0ustar ebourgebourgpackage org.bouncycastle.tsp; import java.io.IOException; import java.math.BigInteger; import java.text.ParseException; import java.util.Date; import org.bouncycastle.asn1.ASN1ObjectIdentifier; import org.bouncycastle.asn1.tsp.Accuracy; import org.bouncycastle.asn1.tsp.TSTInfo; import org.bouncycastle.asn1.x509.AlgorithmIdentifier; import org.bouncycastle.asn1.x509.GeneralName; public class TimeStampTokenInfo { TSTInfo tstInfo; Date genTime; TimeStampTokenInfo(TSTInfo tstInfo) throws TSPException, IOException { this.tstInfo = tstInfo; try { this.genTime = tstInfo.getGenTime().getDate(); } catch (ParseException e) { throw new TSPException("unable to parse genTime field"); } } public boolean isOrdered() { return tstInfo.getOrdering().isTrue(); } public Accuracy getAccuracy() { return tstInfo.getAccuracy(); } public Date getGenTime() { return genTime; } public GenTimeAccuracy getGenTimeAccuracy() { if (this.getAccuracy() != null) { return new GenTimeAccuracy(this.getAccuracy()); } return null; } public ASN1ObjectIdentifier getPolicy() { return tstInfo.getPolicy(); } public BigInteger getSerialNumber() { return tstInfo.getSerialNumber().getValue(); } public GeneralName getTsa() { return tstInfo.getTsa(); } /** * @return the nonce value, null if there isn't one. */ public BigInteger getNonce() { if (tstInfo.getNonce() != null) { return tstInfo.getNonce().getValue(); } return null; } public AlgorithmIdentifier getHashAlgorithm() { return tstInfo.getMessageImprint().getHashAlgorithm(); } public ASN1ObjectIdentifier getMessageImprintAlgOID() { return tstInfo.getMessageImprint().getHashAlgorithm().getAlgorithm(); } public byte[] getMessageImprintDigest() { return tstInfo.getMessageImprint().getHashedMessage(); } public byte[] getEncoded() throws IOException { return tstInfo.getEncoded(); } /** * @deprecated use toASN1Structure * @return */ public TSTInfo toTSTInfo() { return tstInfo; } public TSTInfo toASN1Structure() { return tstInfo; } } bouncycastle-1.49.orig/src/org/bouncycastle/tsp/TimeStampToken.java0000644000175000017500000003766700000000752025061 0ustar ebourgebourgpackage org.bouncycastle.tsp; import java.io.ByteArrayInputStream; import java.io.ByteArrayOutputStream; import java.io.IOException; import java.io.OutputStream; import java.security.MessageDigest; import java.security.NoSuchAlgorithmException; import java.security.NoSuchProviderException; import java.security.cert.CertStore; import java.security.cert.CertificateEncodingException; import java.security.cert.CertificateExpiredException; import java.security.cert.CertificateNotYetValidException; import java.security.cert.X509Certificate; import java.util.Collection; import java.util.Date; import org.bouncycastle.asn1.ASN1InputStream; import org.bouncycastle.asn1.cms.Attribute; import org.bouncycastle.asn1.cms.AttributeTable; import org.bouncycastle.asn1.cms.ContentInfo; import org.bouncycastle.asn1.cms.IssuerAndSerialNumber; import org.bouncycastle.asn1.ess.ESSCertID; import org.bouncycastle.asn1.ess.ESSCertIDv2; import org.bouncycastle.asn1.ess.SigningCertificate; import org.bouncycastle.asn1.ess.SigningCertificateV2; import org.bouncycastle.asn1.nist.NISTObjectIdentifiers; import org.bouncycastle.asn1.oiw.OIWObjectIdentifiers; import org.bouncycastle.asn1.pkcs.PKCSObjectIdentifiers; import org.bouncycastle.asn1.tsp.TSTInfo; import org.bouncycastle.asn1.x500.X500Name; import org.bouncycastle.asn1.x509.AlgorithmIdentifier; import org.bouncycastle.asn1.x509.GeneralName; import org.bouncycastle.asn1.x509.IssuerSerial; import org.bouncycastle.asn1.x509.X509Name; import org.bouncycastle.cert.X509CertificateHolder; import org.bouncycastle.cms.CMSException; import org.bouncycastle.cms.CMSProcessable; import org.bouncycastle.cms.CMSSignedData; import org.bouncycastle.cms.SignerId; import org.bouncycastle.cms.SignerInformation; import org.bouncycastle.cms.SignerInformationVerifier; import org.bouncycastle.jce.PrincipalUtil; import org.bouncycastle.jce.X509Principal; import org.bouncycastle.operator.DigestCalculator; import org.bouncycastle.operator.OperatorCreationException; import org.bouncycastle.util.Arrays; import org.bouncycastle.util.Store; public class TimeStampToken { CMSSignedData tsToken; SignerInformation tsaSignerInfo; Date genTime; TimeStampTokenInfo tstInfo; CertID certID; public TimeStampToken(ContentInfo contentInfo) throws TSPException, IOException { this(getSignedData(contentInfo)); } private static CMSSignedData getSignedData(ContentInfo contentInfo) throws TSPException { try { return new CMSSignedData(contentInfo); } catch (CMSException e) { throw new TSPException("TSP parsing error: " + e.getMessage(), e.getCause()); } } public TimeStampToken(CMSSignedData signedData) throws TSPException, IOException { this.tsToken = signedData; if (!this.tsToken.getSignedContentTypeOID().equals(PKCSObjectIdentifiers.id_ct_TSTInfo.getId())) { throw new TSPValidationException("ContentInfo object not for a time stamp."); } Collection signers = tsToken.getSignerInfos().getSigners(); if (signers.size() != 1) { throw new IllegalArgumentException("Time-stamp token signed by " + signers.size() + " signers, but it must contain just the TSA signature."); } tsaSignerInfo = (SignerInformation)signers.iterator().next(); try { CMSProcessable content = tsToken.getSignedContent(); ByteArrayOutputStream bOut = new ByteArrayOutputStream(); content.write(bOut); ASN1InputStream aIn = new ASN1InputStream(new ByteArrayInputStream(bOut.toByteArray())); this.tstInfo = new TimeStampTokenInfo(TSTInfo.getInstance(aIn.readObject())); Attribute attr = tsaSignerInfo.getSignedAttributes().get(PKCSObjectIdentifiers.id_aa_signingCertificate); if (attr != null) { SigningCertificate signCert = SigningCertificate.getInstance(attr.getAttrValues().getObjectAt(0)); this.certID = new CertID(ESSCertID.getInstance(signCert.getCerts()[0])); } else { attr = tsaSignerInfo.getSignedAttributes().get(PKCSObjectIdentifiers.id_aa_signingCertificateV2); if (attr == null) { throw new TSPValidationException("no signing certificate attribute found, time stamp invalid."); } SigningCertificateV2 signCertV2 = SigningCertificateV2.getInstance(attr.getAttrValues().getObjectAt(0)); this.certID = new CertID(ESSCertIDv2.getInstance(signCertV2.getCerts()[0])); } } catch (CMSException e) { throw new TSPException(e.getMessage(), e.getUnderlyingException()); } } public TimeStampTokenInfo getTimeStampInfo() { return tstInfo; } public SignerId getSID() { return tsaSignerInfo.getSID(); } public AttributeTable getSignedAttributes() { return tsaSignerInfo.getSignedAttributes(); } public AttributeTable getUnsignedAttributes() { return tsaSignerInfo.getUnsignedAttributes(); } /** * @deprecated use getCertificates() or getCRLs() */ public CertStore getCertificatesAndCRLs( String type, String provider) throws NoSuchAlgorithmException, NoSuchProviderException, CMSException { return tsToken.getCertificatesAndCRLs(type, provider); } public Store getCertificates() { return tsToken.getCertificates(); } public Store getCRLs() { return tsToken.getCRLs(); } public Store getAttributeCertificates() { return tsToken.getAttributeCertificates(); } /** * Validate the time stamp token. *

    * To be valid the token must be signed by the passed in certificate and * the certificate must be the one referred to by the SigningCertificate * attribute included in the hashed attributes of the token. The * certificate must also have the ExtendedKeyUsageExtension with only * KeyPurposeId.id_kp_timeStamping and have been valid at the time the * timestamp was created. *

    *

    * A successful call to validate means all the above are true. *

    * @deprecated */ public void validate( X509Certificate cert, String provider) throws TSPException, TSPValidationException, CertificateExpiredException, CertificateNotYetValidException, NoSuchProviderException { try { if (!Arrays.constantTimeAreEqual(certID.getCertHash(), MessageDigest.getInstance(certID.getHashAlgorithmName()).digest(cert.getEncoded()))) { throw new TSPValidationException("certificate hash does not match certID hash."); } if (certID.getIssuerSerial() != null) { if (!certID.getIssuerSerial().getSerial().getValue().equals(cert.getSerialNumber())) { throw new TSPValidationException("certificate serial number does not match certID for signature."); } GeneralName[] names = certID.getIssuerSerial().getIssuer().getNames(); X509Principal principal = PrincipalUtil.getIssuerX509Principal(cert); boolean found = false; for (int i = 0; i != names.length; i++) { if (names[i].getTagNo() == 4 && new X509Principal(X509Name.getInstance(names[i].getName())).equals(principal)) { found = true; break; } } if (!found) { throw new TSPValidationException("certificate name does not match certID for signature. "); } } TSPUtil.validateCertificate(cert); cert.checkValidity(tstInfo.getGenTime()); if (!tsaSignerInfo.verify(cert, provider)) { throw new TSPValidationException("signature not created by certificate."); } } catch (CMSException e) { if (e.getUnderlyingException() != null) { throw new TSPException(e.getMessage(), e.getUnderlyingException()); } else { throw new TSPException("CMS exception: " + e, e); } } catch (NoSuchAlgorithmException e) { throw new TSPException("cannot find algorithm: " + e, e); } catch (CertificateEncodingException e) { throw new TSPException("problem processing certificate: " + e, e); } } /** * Validate the time stamp token. *

    * To be valid the token must be signed by the passed in certificate and * the certificate must be the one referred to by the SigningCertificate * attribute included in the hashed attributes of the token. The * certificate must also have the ExtendedKeyUsageExtension with only * KeyPurposeId.id_kp_timeStamping and have been valid at the time the * timestamp was created. *

    *

    * A successful call to validate means all the above are true. *

    * * @param sigVerifier the content verifier create the objects required to verify the CMS object in the timestamp. * @throws TSPException if an exception occurs in processing the token. * @throws TSPValidationException if the certificate or signature fail to be valid. * @throws IllegalArgumentException if the sigVerifierProvider has no associated certificate. */ public void validate( SignerInformationVerifier sigVerifier) throws TSPException, TSPValidationException { if (!sigVerifier.hasAssociatedCertificate()) { throw new IllegalArgumentException("verifier provider needs an associated certificate"); } try { X509CertificateHolder certHolder = sigVerifier.getAssociatedCertificate(); DigestCalculator calc = sigVerifier.getDigestCalculator(certID.getHashAlgorithm()); OutputStream cOut = calc.getOutputStream(); cOut.write(certHolder.getEncoded()); cOut.close(); if (!Arrays.constantTimeAreEqual(certID.getCertHash(), calc.getDigest())) { throw new TSPValidationException("certificate hash does not match certID hash."); } if (certID.getIssuerSerial() != null) { IssuerAndSerialNumber issuerSerial = new IssuerAndSerialNumber(certHolder.toASN1Structure()); if (!certID.getIssuerSerial().getSerial().equals(issuerSerial.getSerialNumber())) { throw new TSPValidationException("certificate serial number does not match certID for signature."); } GeneralName[] names = certID.getIssuerSerial().getIssuer().getNames(); boolean found = false; for (int i = 0; i != names.length; i++) { if (names[i].getTagNo() == 4 && X500Name.getInstance(names[i].getName()).equals(X500Name.getInstance(issuerSerial.getName()))) { found = true; break; } } if (!found) { throw new TSPValidationException("certificate name does not match certID for signature. "); } } TSPUtil.validateCertificate(certHolder); if (!certHolder.isValidOn(tstInfo.getGenTime())) { throw new TSPValidationException("certificate not valid when time stamp created."); } if (!tsaSignerInfo.verify(sigVerifier)) { throw new TSPValidationException("signature not created by certificate."); } } catch (CMSException e) { if (e.getUnderlyingException() != null) { throw new TSPException(e.getMessage(), e.getUnderlyingException()); } else { throw new TSPException("CMS exception: " + e, e); } } catch (IOException e) { throw new TSPException("problem processing certificate: " + e, e); } catch (OperatorCreationException e) { throw new TSPException("unable to create digest: " + e.getMessage(), e); } } /** * Return true if the signature on time stamp token is valid. *

    * Note: this is a much weaker proof of correctness than calling validate(). *

    * * @param sigVerifier the content verifier create the objects required to verify the CMS object in the timestamp. * @return true if the signature matches, false otherwise. * @throws TSPException if the signature cannot be processed or the provider cannot match the algorithm. */ public boolean isSignatureValid( SignerInformationVerifier sigVerifier) throws TSPException { try { return tsaSignerInfo.verify(sigVerifier); } catch (CMSException e) { if (e.getUnderlyingException() != null) { throw new TSPException(e.getMessage(), e.getUnderlyingException()); } else { throw new TSPException("CMS exception: " + e, e); } } } /** * Return the underlying CMSSignedData object. * * @return the underlying CMS structure. */ public CMSSignedData toCMSSignedData() { return tsToken; } /** * Return a ASN.1 encoded byte stream representing the encoded object. * * @throws IOException if encoding fails. */ public byte[] getEncoded() throws IOException { return tsToken.getEncoded(); } // perhaps this should be done using an interface on the ASN.1 classes... private class CertID { private ESSCertID certID; private ESSCertIDv2 certIDv2; CertID(ESSCertID certID) { this.certID = certID; this.certIDv2 = null; } CertID(ESSCertIDv2 certID) { this.certIDv2 = certID; this.certID = null; } public String getHashAlgorithmName() { if (certID != null) { return "SHA-1"; } else { if (NISTObjectIdentifiers.id_sha256.equals(certIDv2.getHashAlgorithm().getAlgorithm())) { return "SHA-256"; } return certIDv2.getHashAlgorithm().getAlgorithm().getId(); } } public AlgorithmIdentifier getHashAlgorithm() { if (certID != null) { return new AlgorithmIdentifier(OIWObjectIdentifiers.idSHA1); } else { return certIDv2.getHashAlgorithm(); } } public byte[] getCertHash() { if (certID != null) { return certID.getCertHash(); } else { return certIDv2.getCertHash(); } } public IssuerSerial getIssuerSerial() { if (certID != null) { return certID.getIssuerSerial(); } else { return certIDv2.getIssuerSerial(); } } } } bouncycastle-1.49.orig/src/org/bouncycastle/tsp/TSPAlgorithms.java0000644000175000017500000000316311724076664024673 0ustar ebourgebourgpackage org.bouncycastle.tsp; import java.util.Arrays; import java.util.HashSet; import java.util.Set; import org.bouncycastle.asn1.ASN1ObjectIdentifier; import org.bouncycastle.asn1.cryptopro.CryptoProObjectIdentifiers; import org.bouncycastle.asn1.nist.NISTObjectIdentifiers; import org.bouncycastle.asn1.oiw.OIWObjectIdentifiers; import org.bouncycastle.asn1.pkcs.PKCSObjectIdentifiers; import org.bouncycastle.asn1.teletrust.TeleTrusTObjectIdentifiers; /** * Recognised hash algorithms for the time stamp protocol. */ public interface TSPAlgorithms { public static final ASN1ObjectIdentifier MD5 = PKCSObjectIdentifiers.md5; public static final ASN1ObjectIdentifier SHA1 = OIWObjectIdentifiers.idSHA1; public static final ASN1ObjectIdentifier SHA224 = NISTObjectIdentifiers.id_sha224; public static final ASN1ObjectIdentifier SHA256 = NISTObjectIdentifiers.id_sha256; public static final ASN1ObjectIdentifier SHA384 = NISTObjectIdentifiers.id_sha384; public static final ASN1ObjectIdentifier SHA512 = NISTObjectIdentifiers.id_sha512; public static final ASN1ObjectIdentifier RIPEMD128 = TeleTrusTObjectIdentifiers.ripemd128; public static final ASN1ObjectIdentifier RIPEMD160 = TeleTrusTObjectIdentifiers.ripemd160; public static final ASN1ObjectIdentifier RIPEMD256 = TeleTrusTObjectIdentifiers.ripemd256; public static final ASN1ObjectIdentifier GOST3411 = CryptoProObjectIdentifiers.gostR3411; public static final Set ALLOWED = new HashSet(Arrays.asList(new ASN1ObjectIdentifier[] { GOST3411, MD5, SHA1, SHA224, SHA256, SHA384, SHA512, RIPEMD128, RIPEMD160, RIPEMD256 })); } bouncycastle-1.49.orig/src/org/bouncycastle/tsp/TSPException.java0000644000175000017500000000077111711656037024514 0ustar ebourgebourgpackage org.bouncycastle.tsp; public class TSPException extends Exception { Throwable underlyingException; public TSPException(String message) { super(message); } public TSPException(String message, Throwable e) { super(message); underlyingException = e; } public Exception getUnderlyingException() { return (Exception)underlyingException; } public Throwable getCause() { return underlyingException; } } bouncycastle-1.49.orig/src/org/bouncycastle/tsp/TimeStampResponse.java0000644000175000017500000001401511600026671025575 0ustar ebourgebourgpackage org.bouncycastle.tsp; import java.io.ByteArrayInputStream; import java.io.IOException; import java.io.InputStream; import org.bouncycastle.asn1.ASN1InputStream; import org.bouncycastle.asn1.cmp.PKIFailureInfo; import org.bouncycastle.asn1.cmp.PKIFreeText; import org.bouncycastle.asn1.cmp.PKIStatus; import org.bouncycastle.asn1.cms.Attribute; import org.bouncycastle.asn1.pkcs.PKCSObjectIdentifiers; import org.bouncycastle.asn1.tsp.TimeStampResp; import org.bouncycastle.util.Arrays; /** * Base class for an RFC 3161 Time Stamp Response object. */ public class TimeStampResponse { TimeStampResp resp; TimeStampToken timeStampToken; public TimeStampResponse(TimeStampResp resp) throws TSPException, IOException { this.resp = resp; if (resp.getTimeStampToken() != null) { timeStampToken = new TimeStampToken(resp.getTimeStampToken()); } } /** * Create a TimeStampResponse from a byte array containing an ASN.1 encoding. * * @param resp the byte array containing the encoded response. * @throws TSPException if the response is malformed. * @throws IOException if the byte array doesn't represent an ASN.1 encoding. */ public TimeStampResponse(byte[] resp) throws TSPException, IOException { this(new ByteArrayInputStream(resp)); } /** * Create a TimeStampResponse from an input stream containing an ASN.1 encoding. * * @param in the input stream containing the encoded response. * @throws TSPException if the response is malformed. * @throws IOException if the stream doesn't represent an ASN.1 encoding. */ public TimeStampResponse(InputStream in) throws TSPException, IOException { this(readTimeStampResp(in)); } private static TimeStampResp readTimeStampResp( InputStream in) throws IOException, TSPException { try { return TimeStampResp.getInstance(new ASN1InputStream(in).readObject()); } catch (IllegalArgumentException e) { throw new TSPException("malformed timestamp response: " + e, e); } catch (ClassCastException e) { throw new TSPException("malformed timestamp response: " + e, e); } } public int getStatus() { return resp.getStatus().getStatus().intValue(); } public String getStatusString() { if (resp.getStatus().getStatusString() != null) { StringBuffer statusStringBuf = new StringBuffer(); PKIFreeText text = resp.getStatus().getStatusString(); for (int i = 0; i != text.size(); i++) { statusStringBuf.append(text.getStringAt(i).getString()); } return statusStringBuf.toString(); } else { return null; } } public PKIFailureInfo getFailInfo() { if (resp.getStatus().getFailInfo() != null) { return new PKIFailureInfo(resp.getStatus().getFailInfo()); } return null; } public TimeStampToken getTimeStampToken() { return timeStampToken; } /** * Check this response against to see if it a well formed response for * the passed in request. Validation will include checking the time stamp * token if the response status is GRANTED or GRANTED_WITH_MODS. * * @param request the request to be checked against * @throws TSPException if the request can not match this response. */ public void validate( TimeStampRequest request) throws TSPException { TimeStampToken tok = this.getTimeStampToken(); if (tok != null) { TimeStampTokenInfo tstInfo = tok.getTimeStampInfo(); if (request.getNonce() != null && !request.getNonce().equals(tstInfo.getNonce())) { throw new TSPValidationException("response contains wrong nonce value."); } if (this.getStatus() != PKIStatus.GRANTED && this.getStatus() != PKIStatus.GRANTED_WITH_MODS) { throw new TSPValidationException("time stamp token found in failed request."); } if (!Arrays.constantTimeAreEqual(request.getMessageImprintDigest(), tstInfo.getMessageImprintDigest())) { throw new TSPValidationException("response for different message imprint digest."); } if (!tstInfo.getMessageImprintAlgOID().equals(request.getMessageImprintAlgOID())) { throw new TSPValidationException("response for different message imprint algorithm."); } Attribute scV1 = tok.getSignedAttributes().get(PKCSObjectIdentifiers.id_aa_signingCertificate); Attribute scV2 = tok.getSignedAttributes().get(PKCSObjectIdentifiers.id_aa_signingCertificateV2); if (scV1 == null && scV2 == null) { throw new TSPValidationException("no signing certificate attribute present."); } if (scV1 != null && scV2 != null) { /* * RFC 5035 5.4. If both attributes exist in a single message, * they are independently evaluated. */ } if (request.getReqPolicy() != null && !request.getReqPolicy().equals(tstInfo.getPolicy())) { throw new TSPValidationException("TSA policy wrong for request."); } } else if (this.getStatus() == PKIStatus.GRANTED || this.getStatus() == PKIStatus.GRANTED_WITH_MODS) { throw new TSPValidationException("no time stamp token found and one expected."); } } /** * return the ASN.1 encoded representation of this object. */ public byte[] getEncoded() throws IOException { return resp.getEncoded(); } }bouncycastle-1.49.orig/src/org/bouncycastle/tsp/GenTimeAccuracy.java0000644000175000017500000000215711732005406025161 0ustar ebourgebourgpackage org.bouncycastle.tsp; import org.bouncycastle.asn1.DERInteger; import org.bouncycastle.asn1.tsp.Accuracy; public class GenTimeAccuracy { private Accuracy accuracy; public GenTimeAccuracy(Accuracy accuracy) { this.accuracy = accuracy; } public int getSeconds() { return getTimeComponent(accuracy.getSeconds()); } public int getMillis() { return getTimeComponent(accuracy.getMillis()); } public int getMicros() { return getTimeComponent(accuracy.getMicros()); } private int getTimeComponent( DERInteger time) { if (time != null) { return time.getValue().intValue(); } return 0; } public String toString() { // digits return getSeconds() + "." + format(getMillis()) + format(getMicros()); } private String format(int v) { if (v < 10) { return "00" + v; } if (v < 100) { return "0" + v; } return Integer.toString(v); } } bouncycastle-1.49.orig/src/org/bouncycastle/tsp/TSPUtil.java0000644000175000017500000003617012103440465023465 0ustar ebourgebourgpackage org.bouncycastle.tsp; import java.io.ByteArrayInputStream; import java.io.IOException; import java.io.OutputStream; import java.security.MessageDigest; import java.security.NoSuchAlgorithmException; import java.security.Provider; import java.security.cert.X509Certificate; import java.util.ArrayList; import java.util.Collection; import java.util.Collections; import java.util.HashMap; import java.util.HashSet; import java.util.List; import java.util.Map; import java.util.Set; import org.bouncycastle.asn1.ASN1Encodable; import org.bouncycastle.asn1.ASN1EncodableVector; import org.bouncycastle.asn1.ASN1InputStream; import org.bouncycastle.asn1.ASN1ObjectIdentifier; import org.bouncycastle.asn1.ASN1OctetString; import org.bouncycastle.asn1.ASN1Set; import org.bouncycastle.asn1.cms.Attribute; import org.bouncycastle.asn1.cms.AttributeTable; import org.bouncycastle.asn1.cms.ContentInfo; import org.bouncycastle.asn1.cryptopro.CryptoProObjectIdentifiers; import org.bouncycastle.asn1.nist.NISTObjectIdentifiers; import org.bouncycastle.asn1.oiw.OIWObjectIdentifiers; import org.bouncycastle.asn1.pkcs.PKCSObjectIdentifiers; import org.bouncycastle.asn1.teletrust.TeleTrusTObjectIdentifiers; import org.bouncycastle.asn1.x509.ExtendedKeyUsage; import org.bouncycastle.asn1.x509.Extension; import org.bouncycastle.asn1.x509.Extensions; import org.bouncycastle.asn1.x509.ExtensionsGenerator; import org.bouncycastle.asn1.x509.KeyPurposeId; import org.bouncycastle.asn1.x509.X509Extensions; import org.bouncycastle.cert.X509CertificateHolder; import org.bouncycastle.cms.SignerInformation; import org.bouncycastle.operator.DigestCalculator; import org.bouncycastle.operator.DigestCalculatorProvider; import org.bouncycastle.operator.OperatorCreationException; import org.bouncycastle.util.Arrays; import org.bouncycastle.util.Integers; public class TSPUtil { private static Set EMPTY_SET = Collections.unmodifiableSet(new HashSet()); private static List EMPTY_LIST = Collections.unmodifiableList(new ArrayList()); private static final Map digestLengths = new HashMap(); private static final Map digestNames = new HashMap(); static { digestLengths.put(PKCSObjectIdentifiers.md5.getId(), Integers.valueOf(16)); digestLengths.put(OIWObjectIdentifiers.idSHA1.getId(), Integers.valueOf(20)); digestLengths.put(NISTObjectIdentifiers.id_sha224.getId(), Integers.valueOf(28)); digestLengths.put(NISTObjectIdentifiers.id_sha256.getId(), Integers.valueOf(32)); digestLengths.put(NISTObjectIdentifiers.id_sha384.getId(), Integers.valueOf(48)); digestLengths.put(NISTObjectIdentifiers.id_sha512.getId(), Integers.valueOf(64)); digestLengths.put(TeleTrusTObjectIdentifiers.ripemd128.getId(), Integers.valueOf(16)); digestLengths.put(TeleTrusTObjectIdentifiers.ripemd160.getId(), Integers.valueOf(20)); digestLengths.put(TeleTrusTObjectIdentifiers.ripemd256.getId(), Integers.valueOf(32)); digestLengths.put(CryptoProObjectIdentifiers.gostR3411.getId(), Integers.valueOf(32)); digestNames.put(PKCSObjectIdentifiers.md5.getId(), "MD5"); digestNames.put(OIWObjectIdentifiers.idSHA1.getId(), "SHA1"); digestNames.put(NISTObjectIdentifiers.id_sha224.getId(), "SHA224"); digestNames.put(NISTObjectIdentifiers.id_sha256.getId(), "SHA256"); digestNames.put(NISTObjectIdentifiers.id_sha384.getId(), "SHA384"); digestNames.put(NISTObjectIdentifiers.id_sha512.getId(), "SHA512"); digestNames.put(PKCSObjectIdentifiers.sha1WithRSAEncryption.getId(), "SHA1"); digestNames.put(PKCSObjectIdentifiers.sha224WithRSAEncryption.getId(), "SHA224"); digestNames.put(PKCSObjectIdentifiers.sha256WithRSAEncryption.getId(), "SHA256"); digestNames.put(PKCSObjectIdentifiers.sha384WithRSAEncryption.getId(), "SHA384"); digestNames.put(PKCSObjectIdentifiers.sha512WithRSAEncryption.getId(), "SHA512"); digestNames.put(TeleTrusTObjectIdentifiers.ripemd128.getId(), "RIPEMD128"); digestNames.put(TeleTrusTObjectIdentifiers.ripemd160.getId(), "RIPEMD160"); digestNames.put(TeleTrusTObjectIdentifiers.ripemd256.getId(), "RIPEMD256"); digestNames.put(CryptoProObjectIdentifiers.gostR3411.getId(), "GOST3411"); } /** * Fetches the signature time-stamp attributes from a SignerInformation object. * Checks that the MessageImprint for each time-stamp matches the signature field. * (see RFC 3161 Appendix A). * * @param signerInfo a SignerInformation to search for time-stamps * @param provider an optional provider to use to create MessageDigest instances * @return a collection of TimeStampToken objects * @throws TSPValidationException * @deprecated use getSignatureTimestamps(SignerInformation, DigestCalculatorProvider) */ public static Collection getSignatureTimestamps(SignerInformation signerInfo, Provider provider) throws TSPValidationException { List timestamps = new ArrayList(); AttributeTable unsignedAttrs = signerInfo.getUnsignedAttributes(); if (unsignedAttrs != null) { ASN1EncodableVector allTSAttrs = unsignedAttrs.getAll( PKCSObjectIdentifiers.id_aa_signatureTimeStampToken); for (int i = 0; i < allTSAttrs.size(); ++i) { Attribute tsAttr = (Attribute)allTSAttrs.get(i); ASN1Set tsAttrValues = tsAttr.getAttrValues(); for (int j = 0; j < tsAttrValues.size(); ++j) { try { ContentInfo contentInfo = ContentInfo.getInstance(tsAttrValues.getObjectAt(j)); TimeStampToken timeStampToken = new TimeStampToken(contentInfo); TimeStampTokenInfo tstInfo = timeStampToken.getTimeStampInfo(); MessageDigest digest = createDigestInstance(tstInfo.getMessageImprintAlgOID().getId(), provider); byte[] expectedDigest = digest.digest(signerInfo.getSignature()); if (!Arrays.constantTimeAreEqual(expectedDigest, tstInfo.getMessageImprintDigest())) { throw new TSPValidationException("Incorrect digest in message imprint"); } timestamps.add(timeStampToken); } catch (NoSuchAlgorithmException e) { throw new TSPValidationException("Unknown hash algorithm specified in timestamp"); } catch (Exception e) { throw new TSPValidationException("Timestamp could not be parsed"); } } } } return timestamps; } /** * Fetches the signature time-stamp attributes from a SignerInformation object. * Checks that the MessageImprint for each time-stamp matches the signature field. * (see RFC 3161 Appendix A). * * @param signerInfo a SignerInformation to search for time-stamps * @param digCalcProvider provider for digest calculators * @return a collection of TimeStampToken objects * @throws TSPValidationException */ public static Collection getSignatureTimestamps(SignerInformation signerInfo, DigestCalculatorProvider digCalcProvider) throws TSPValidationException { List timestamps = new ArrayList(); AttributeTable unsignedAttrs = signerInfo.getUnsignedAttributes(); if (unsignedAttrs != null) { ASN1EncodableVector allTSAttrs = unsignedAttrs.getAll( PKCSObjectIdentifiers.id_aa_signatureTimeStampToken); for (int i = 0; i < allTSAttrs.size(); ++i) { Attribute tsAttr = (Attribute)allTSAttrs.get(i); ASN1Set tsAttrValues = tsAttr.getAttrValues(); for (int j = 0; j < tsAttrValues.size(); ++j) { try { ContentInfo contentInfo = ContentInfo.getInstance(tsAttrValues.getObjectAt(j)); TimeStampToken timeStampToken = new TimeStampToken(contentInfo); TimeStampTokenInfo tstInfo = timeStampToken.getTimeStampInfo(); DigestCalculator digCalc = digCalcProvider.get(tstInfo.getHashAlgorithm()); OutputStream dOut = digCalc.getOutputStream(); dOut.write(signerInfo.getSignature()); dOut.close(); byte[] expectedDigest = digCalc.getDigest(); if (!Arrays.constantTimeAreEqual(expectedDigest, tstInfo.getMessageImprintDigest())) { throw new TSPValidationException("Incorrect digest in message imprint"); } timestamps.add(timeStampToken); } catch (OperatorCreationException e) { throw new TSPValidationException("Unknown hash algorithm specified in timestamp"); } catch (Exception e) { throw new TSPValidationException("Timestamp could not be parsed"); } } } } return timestamps; } /** * Validate the passed in certificate as being of the correct type to be used * for time stamping. To be valid it must have an ExtendedKeyUsage extension * which has a key purpose identifier of id-kp-timeStamping. * * @param cert the certificate of interest. * @throws TSPValidationException if the certicate fails on one of the check points. */ public static void validateCertificate( X509Certificate cert) throws TSPValidationException { if (cert.getVersion() != 3) { throw new IllegalArgumentException("Certificate must have an ExtendedKeyUsage extension."); } byte[] ext = cert.getExtensionValue(X509Extensions.ExtendedKeyUsage.getId()); if (ext == null) { throw new TSPValidationException("Certificate must have an ExtendedKeyUsage extension."); } if (!cert.getCriticalExtensionOIDs().contains(X509Extensions.ExtendedKeyUsage.getId())) { throw new TSPValidationException("Certificate must have an ExtendedKeyUsage extension marked as critical."); } ASN1InputStream aIn = new ASN1InputStream(new ByteArrayInputStream(ext)); try { aIn = new ASN1InputStream(new ByteArrayInputStream(((ASN1OctetString)aIn.readObject()).getOctets())); ExtendedKeyUsage extKey = ExtendedKeyUsage.getInstance(aIn.readObject()); if (!extKey.hasKeyPurposeId(KeyPurposeId.id_kp_timeStamping) || extKey.size() != 1) { throw new TSPValidationException("ExtendedKeyUsage not solely time stamping."); } } catch (IOException e) { throw new TSPValidationException("cannot process ExtendedKeyUsage extension"); } } /** * Validate the passed in certificate as being of the correct type to be used * for time stamping. To be valid it must have an ExtendedKeyUsage extension * which has a key purpose identifier of id-kp-timeStamping. * * @param cert the certificate of interest. * @throws TSPValidationException if the certicate fails on one of the check points. */ public static void validateCertificate( X509CertificateHolder cert) throws TSPValidationException { if (cert.toASN1Structure().getVersionNumber() != 3) { throw new IllegalArgumentException("Certificate must have an ExtendedKeyUsage extension."); } Extension ext = cert.getExtension(Extension.extendedKeyUsage); if (ext == null) { throw new TSPValidationException("Certificate must have an ExtendedKeyUsage extension."); } if (!ext.isCritical()) { throw new TSPValidationException("Certificate must have an ExtendedKeyUsage extension marked as critical."); } ExtendedKeyUsage extKey = ExtendedKeyUsage.getInstance(ext.getParsedValue()); if (!extKey.hasKeyPurposeId(KeyPurposeId.id_kp_timeStamping) || extKey.size() != 1) { throw new TSPValidationException("ExtendedKeyUsage not solely time stamping."); } } /* * Return the digest algorithm using one of the standard JCA string * representations rather than the algorithm identifier (if possible). */ static String getDigestAlgName( String digestAlgOID) { String digestName = (String)digestNames.get(digestAlgOID); if (digestName != null) { return digestName; } return digestAlgOID; } static int getDigestLength( String digestAlgOID) throws TSPException { Integer length = (Integer)digestLengths.get(digestAlgOID); if (length != null) { return length.intValue(); } throw new TSPException("digest algorithm cannot be found."); } static MessageDigest createDigestInstance(String digestAlgOID, Provider provider) throws NoSuchAlgorithmException { String digestName = TSPUtil.getDigestAlgName(digestAlgOID); if (provider != null) { try { return MessageDigest.getInstance(digestName, provider); } catch (NoSuchAlgorithmException e) { // Ignore } } return MessageDigest.getInstance(digestName); } static Set getCriticalExtensionOIDs(X509Extensions extensions) { if (extensions == null) { return EMPTY_SET; } return Collections.unmodifiableSet(new HashSet(java.util.Arrays.asList(extensions.getCriticalExtensionOIDs()))); } static Set getNonCriticalExtensionOIDs(X509Extensions extensions) { if (extensions == null) { return EMPTY_SET; } // TODO: should probably produce a set that imposes correct ordering return Collections.unmodifiableSet(new HashSet(java.util.Arrays.asList(extensions.getNonCriticalExtensionOIDs()))); } static List getExtensionOIDs(Extensions extensions) { if (extensions == null) { return EMPTY_LIST; } return Collections.unmodifiableList(java.util.Arrays.asList(extensions.getExtensionOIDs())); } static void addExtension(ExtensionsGenerator extGenerator, ASN1ObjectIdentifier oid, boolean isCritical, ASN1Encodable value) throws TSPIOException { try { extGenerator.addExtension(oid, isCritical, value); } catch (IOException e) { throw new TSPIOException("cannot encode extension: " + e.getMessage(), e); } } } bouncycastle-1.49.orig/src/org/bouncycastle/tsp/TSPValidationException.java0000644000175000017500000000143211524636431026520 0ustar ebourgebourgpackage org.bouncycastle.tsp; /** * Exception thrown if a TSP request or response fails to validate. *

    * If a failure code is associated with the exception it can be retrieved using * the getFailureCode() method. */ public class TSPValidationException extends TSPException { private int failureCode = -1; public TSPValidationException(String message) { super(message); } public TSPValidationException(String message, int failureCode) { super(message); this.failureCode = failureCode; } /** * Return the failure code associated with this exception - if one is set. * * @return the failure code if set, -1 otherwise. */ public int getFailureCode() { return failureCode; } } bouncycastle-1.49.orig/src/org/bouncycastle/tsp/package.html0000644000175000017500000000015210262753174023576 0ustar ebourgebourg Classes for dealing Time Stamp Protocol (TSP) - RFC 3161. bouncycastle-1.49.orig/src/org/bouncycastle/tsp/TimeStampRequestGenerator.java0000644000175000017500000001114512103437526027303 0ustar ebourgebourgpackage org.bouncycastle.tsp; import java.io.IOException; import java.math.BigInteger; import org.bouncycastle.asn1.ASN1Boolean; import org.bouncycastle.asn1.ASN1Encodable; import org.bouncycastle.asn1.ASN1Integer; import org.bouncycastle.asn1.ASN1ObjectIdentifier; import org.bouncycastle.asn1.DERNull; import org.bouncycastle.asn1.tsp.MessageImprint; import org.bouncycastle.asn1.tsp.TimeStampReq; import org.bouncycastle.asn1.x509.AlgorithmIdentifier; import org.bouncycastle.asn1.x509.Extensions; import org.bouncycastle.asn1.x509.ExtensionsGenerator; /** * Generator for RFC 3161 Time Stamp Request objects. */ public class TimeStampRequestGenerator { private ASN1ObjectIdentifier reqPolicy; private ASN1Boolean certReq; private ExtensionsGenerator extGenerator = new ExtensionsGenerator(); public TimeStampRequestGenerator() { } /** * @deprecated use method taking ASN1ObjectIdentifier * @param reqPolicy */ public void setReqPolicy( String reqPolicy) { this.reqPolicy= new ASN1ObjectIdentifier(reqPolicy); } public void setReqPolicy( ASN1ObjectIdentifier reqPolicy) { this.reqPolicy= reqPolicy; } public void setCertReq( boolean certReq) { this.certReq = ASN1Boolean.getInstance(certReq); } /** * add a given extension field for the standard extensions tag (tag 3) * @throws IOException * @deprecated use method taking ASN1ObjectIdentifier */ public void addExtension( String OID, boolean critical, ASN1Encodable value) throws IOException { this.addExtension(OID, critical, value.toASN1Primitive().getEncoded()); } /** * add a given extension field for the standard extensions tag * The value parameter becomes the contents of the octet string associated * with the extension. * @deprecated use method taking ASN1ObjectIdentifier */ public void addExtension( String OID, boolean critical, byte[] value) { extGenerator.addExtension(new ASN1ObjectIdentifier(OID), critical, value); } /** * add a given extension field for the standard extensions tag (tag 3) * @throws TSPIOException */ public void addExtension( ASN1ObjectIdentifier oid, boolean isCritical, ASN1Encodable value) throws TSPIOException { TSPUtil.addExtension(extGenerator, oid, isCritical, value); } /** * add a given extension field for the standard extensions tag * The value parameter becomes the contents of the octet string associated * with the extension. */ public void addExtension( ASN1ObjectIdentifier oid, boolean isCritical, byte[] value) { extGenerator.addExtension(oid, isCritical, value); } /** * @deprecated use method taking ANS1ObjectIdentifier */ public TimeStampRequest generate( String digestAlgorithm, byte[] digest) { return this.generate(digestAlgorithm, digest, null); } /** * @deprecated use method taking ANS1ObjectIdentifier */ public TimeStampRequest generate( String digestAlgorithmOID, byte[] digest, BigInteger nonce) { if (digestAlgorithmOID == null) { throw new IllegalArgumentException("No digest algorithm specified"); } ASN1ObjectIdentifier digestAlgOID = new ASN1ObjectIdentifier(digestAlgorithmOID); AlgorithmIdentifier algID = new AlgorithmIdentifier(digestAlgOID, DERNull.INSTANCE); MessageImprint messageImprint = new MessageImprint(algID, digest); Extensions ext = null; if (!extGenerator.isEmpty()) { ext = extGenerator.generate(); } if (nonce != null) { return new TimeStampRequest(new TimeStampReq(messageImprint, reqPolicy, new ASN1Integer(nonce), certReq, ext)); } else { return new TimeStampRequest(new TimeStampReq(messageImprint, reqPolicy, null, certReq, ext)); } } public TimeStampRequest generate(ASN1ObjectIdentifier digestAlgorithm, byte[] digest) { return generate(digestAlgorithm.getId(), digest); } public TimeStampRequest generate(ASN1ObjectIdentifier digestAlgorithm, byte[] digest, BigInteger nonce) { return generate(digestAlgorithm.getId(), digest, nonce); } } bouncycastle-1.49.orig/src/org/bouncycastle/eac/0000755000175000017500000000000012152033551021227 5ustar ebourgebourgbouncycastle-1.49.orig/src/org/bouncycastle/eac/EACCertificateHolder.java0000644000175000017500000000444211643173610025774 0ustar ebourgebourgpackage org.bouncycastle.eac; import java.io.IOException; import java.io.OutputStream; import org.bouncycastle.asn1.ASN1Encoding; import org.bouncycastle.asn1.ASN1ParsingException; import org.bouncycastle.asn1.eac.CVCertificate; import org.bouncycastle.asn1.eac.PublicKeyDataObject; import org.bouncycastle.eac.operator.EACSignatureVerifier; public class EACCertificateHolder { private CVCertificate cvCertificate; private static CVCertificate parseBytes(byte[] certEncoding) throws IOException { try { return CVCertificate.getInstance(certEncoding); } catch (ClassCastException e) { throw new EACIOException("malformed data: " + e.getMessage(), e); } catch (IllegalArgumentException e) { throw new EACIOException("malformed data: " + e.getMessage(), e); } catch (ASN1ParsingException e) { if (e.getCause() instanceof IOException) { throw (IOException)e.getCause(); } else { throw new EACIOException("malformed data: " + e.getMessage(), e); } } } public EACCertificateHolder(byte[] certEncoding) throws IOException { this(parseBytes(certEncoding)); } public EACCertificateHolder(CVCertificate cvCertificate) { this.cvCertificate = cvCertificate; } /** * Return the underlying ASN.1 structure for the certificate in this holder. * * @return a X509CertificateStructure object. */ public CVCertificate toASN1Structure() { return cvCertificate; } public PublicKeyDataObject getPublicKeyDataObject() { return cvCertificate.getBody().getPublicKey(); } public boolean isSignatureValid(EACSignatureVerifier verifier) throws EACException { try { OutputStream vOut = verifier.getOutputStream(); vOut.write(cvCertificate.getBody().getEncoded(ASN1Encoding.DER)); vOut.close(); return verifier.verify(cvCertificate.getSignature()); } catch (Exception e) { throw new EACException("unable to process signature: " + e.getMessage(), e); } } } bouncycastle-1.49.orig/src/org/bouncycastle/eac/EACException.java0000644000175000017500000000070111642475401024346 0ustar ebourgebourgpackage org.bouncycastle.eac; /** * General checked Exception thrown in the cert package and its sub-packages. */ public class EACException extends Exception { private Throwable cause; public EACException(String msg, Throwable cause) { super(msg); this.cause = cause; } public EACException(String msg) { super(msg); } public Throwable getCause() { return cause; } } bouncycastle-1.49.orig/src/org/bouncycastle/eac/EACIOException.java0000644000175000017500000000074011642466020024576 0ustar ebourgebourgpackage org.bouncycastle.eac; import java.io.IOException; /** * General IOException thrown in the cert package and its sub-packages. */ public class EACIOException extends IOException { private Throwable cause; public EACIOException(String msg, Throwable cause) { super(msg); this.cause = cause; } public EACIOException(String msg) { super(msg); } public Throwable getCause() { return cause; } } bouncycastle-1.49.orig/src/org/bouncycastle/eac/operator/0000755000175000017500000000000012152033551023062 5ustar ebourgebourgbouncycastle-1.49.orig/src/org/bouncycastle/eac/operator/EACSigner.java0000644000175000017500000000133211643462504025474 0ustar ebourgebourgpackage org.bouncycastle.eac.operator; import java.io.OutputStream; import org.bouncycastle.asn1.ASN1ObjectIdentifier; public interface EACSigner { ASN1ObjectIdentifier getUsageIdentifier(); /** * Returns a stream that will accept data for the purpose of calculating * a signature. Use org.bouncycastle.util.io.TeeOutputStream if you want to accumulate * the data on the fly as well. * * @return an OutputStream */ OutputStream getOutputStream(); /** * Returns a signature based on the current data written to the stream, since the * start or the last call to getSignature(). * * @return bytes representing the signature. */ byte[] getSignature(); } bouncycastle-1.49.orig/src/org/bouncycastle/eac/operator/jcajce/0000755000175000017500000000000012152033551024301 5ustar ebourgebourgbouncycastle-1.49.orig/src/org/bouncycastle/eac/operator/jcajce/EACUtil.java0000644000175000017500000000010111642755461026400 0ustar ebourgebourgpackage org.bouncycastle.eac.operator.jcajce; class EACUtil { } bouncycastle-1.49.orig/src/org/bouncycastle/eac/operator/jcajce/JcaEACSignerBuilder.java0000644000175000017500000001526412151274313030643 0ustar ebourgebourgpackage org.bouncycastle.eac.operator.jcajce; import java.io.IOException; import java.io.OutputStream; import java.math.BigInteger; import java.security.InvalidKeyException; import java.security.NoSuchAlgorithmException; import java.security.NoSuchProviderException; import java.security.PrivateKey; import java.security.Provider; import java.security.Signature; import java.security.SignatureException; import java.util.Arrays; import java.util.Hashtable; import org.bouncycastle.asn1.ASN1Integer; import org.bouncycastle.asn1.ASN1ObjectIdentifier; import org.bouncycastle.asn1.ASN1Sequence; import org.bouncycastle.asn1.eac.EACObjectIdentifiers; import org.bouncycastle.eac.operator.EACSigner; import org.bouncycastle.operator.OperatorCreationException; import org.bouncycastle.operator.OperatorStreamException; import org.bouncycastle.operator.RuntimeOperatorException; public class JcaEACSignerBuilder { private static final Hashtable sigNames = new Hashtable(); static { sigNames.put("SHA1withRSA", EACObjectIdentifiers.id_TA_RSA_v1_5_SHA_1); sigNames.put("SHA256withRSA", EACObjectIdentifiers.id_TA_RSA_v1_5_SHA_256); sigNames.put("SHA1withRSAandMGF1", EACObjectIdentifiers.id_TA_RSA_PSS_SHA_1); sigNames.put("SHA256withRSAandMGF1", EACObjectIdentifiers.id_TA_RSA_PSS_SHA_256); sigNames.put("SHA512withRSA", EACObjectIdentifiers.id_TA_RSA_v1_5_SHA_512); sigNames.put("SHA512withRSAandMGF1", EACObjectIdentifiers.id_TA_RSA_PSS_SHA_512); sigNames.put("SHA1withECDSA", EACObjectIdentifiers.id_TA_ECDSA_SHA_1); sigNames.put("SHA224withECDSA", EACObjectIdentifiers.id_TA_ECDSA_SHA_224); sigNames.put("SHA256withECDSA", EACObjectIdentifiers.id_TA_ECDSA_SHA_256); sigNames.put("SHA384withECDSA", EACObjectIdentifiers.id_TA_ECDSA_SHA_384); sigNames.put("SHA512withECDSA", EACObjectIdentifiers.id_TA_ECDSA_SHA_512); } private EACHelper helper = new DefaultEACHelper(); public JcaEACSignerBuilder setProvider(String providerName) { this.helper = new NamedEACHelper(providerName); return this; } public JcaEACSignerBuilder setProvider(Provider provider) { this.helper = new ProviderEACHelper(provider); return this; } public EACSigner build(String algorithm, PrivateKey privKey) throws OperatorCreationException { return build((ASN1ObjectIdentifier)sigNames.get(algorithm), privKey); } public EACSigner build(final ASN1ObjectIdentifier usageOid, PrivateKey privKey) throws OperatorCreationException { Signature sig; try { sig = helper.getSignature(usageOid); sig.initSign(privKey); } catch (NoSuchAlgorithmException e) { throw new OperatorCreationException("unable to find algorithm: " + e.getMessage(), e); } catch (NoSuchProviderException e) { throw new OperatorCreationException("unable to find provider: " + e.getMessage(), e); } catch (InvalidKeyException e) { throw new OperatorCreationException("invalid key: " + e.getMessage(), e); } final SignatureOutputStream sigStream = new SignatureOutputStream(sig); return new EACSigner() { public ASN1ObjectIdentifier getUsageIdentifier() { return usageOid; } public OutputStream getOutputStream() { return sigStream; } public byte[] getSignature() { try { byte[] signature = sigStream.getSignature(); if (usageOid.on(EACObjectIdentifiers.id_TA_ECDSA)) { return reencode(signature); } return signature; } catch (SignatureException e) { throw new RuntimeOperatorException("exception obtaining signature: " + e.getMessage(), e); } } }; } public static int max(int el1, int el2) { return el1 > el2 ? el1 : el2; } private static byte[] reencode(byte[] rawSign) { ASN1Sequence sData = ASN1Sequence.getInstance(rawSign); BigInteger r = ASN1Integer.getInstance(sData.getObjectAt(0)).getValue(); BigInteger s = ASN1Integer.getInstance(sData.getObjectAt(1)).getValue(); byte[] rB = r.toByteArray(); byte[] sB = s.toByteArray(); int rLen = unsignedIntLength(rB); int sLen = unsignedIntLength(sB); byte[] ret; int len = max(rLen, sLen); ret = new byte[len * 2]; Arrays.fill(ret, (byte)0); copyUnsignedInt(rB, ret, len - rLen); copyUnsignedInt(sB, ret, 2 * len - sLen); return ret; } private static int unsignedIntLength(byte[] i) { int len = i.length; if (i[0] == 0) { len--; } return len; } private static void copyUnsignedInt(byte[] src, byte[] dst, int offset) { int len = src.length; int readoffset = 0; if (src[0] == 0) { len--; readoffset = 1; } System.arraycopy(src, readoffset, dst, offset, len); } private class SignatureOutputStream extends OutputStream { private Signature sig; SignatureOutputStream(Signature sig) { this.sig = sig; } public void write(byte[] bytes, int off, int len) throws IOException { try { sig.update(bytes, off, len); } catch (SignatureException e) { throw new OperatorStreamException("exception in content signer: " + e.getMessage(), e); } } public void write(byte[] bytes) throws IOException { try { sig.update(bytes); } catch (SignatureException e) { throw new OperatorStreamException("exception in content signer: " + e.getMessage(), e); } } public void write(int b) throws IOException { try { sig.update((byte)b); } catch (SignatureException e) { throw new OperatorStreamException("exception in content signer: " + e.getMessage(), e); } } byte[] getSignature() throws SignatureException { return sig.sign(); } } } bouncycastle-1.49.orig/src/org/bouncycastle/eac/operator/jcajce/EACHelper.java0000644000175000017500000000321411642756730026712 0ustar ebourgebourgpackage org.bouncycastle.eac.operator.jcajce; import java.security.NoSuchAlgorithmException; import java.security.NoSuchProviderException; import java.security.Signature; import java.util.Hashtable; import org.bouncycastle.asn1.ASN1ObjectIdentifier; import org.bouncycastle.asn1.eac.EACObjectIdentifiers; abstract class EACHelper { private static final Hashtable sigNames = new Hashtable(); static { sigNames.put(EACObjectIdentifiers.id_TA_RSA_v1_5_SHA_1, "SHA1withRSA"); sigNames.put(EACObjectIdentifiers.id_TA_RSA_v1_5_SHA_256, "SHA256withRSA"); sigNames.put(EACObjectIdentifiers.id_TA_RSA_PSS_SHA_1, "SHA1withRSAandMGF1"); sigNames.put(EACObjectIdentifiers.id_TA_RSA_PSS_SHA_256, "SHA256withRSAandMGF1"); sigNames.put(EACObjectIdentifiers.id_TA_RSA_v1_5_SHA_512, "SHA512withRSA"); sigNames.put(EACObjectIdentifiers.id_TA_RSA_PSS_SHA_512, "SHA512withRSAandMGF1"); sigNames.put(EACObjectIdentifiers.id_TA_ECDSA_SHA_1, "SHA1withECDSA"); sigNames.put(EACObjectIdentifiers.id_TA_ECDSA_SHA_224, "SHA224withECDSA"); sigNames.put(EACObjectIdentifiers.id_TA_ECDSA_SHA_256, "SHA256withECDSA"); sigNames.put(EACObjectIdentifiers.id_TA_ECDSA_SHA_384, "SHA384withECDSA"); sigNames.put(EACObjectIdentifiers.id_TA_ECDSA_SHA_512, "SHA512withECDSA"); } public Signature getSignature(ASN1ObjectIdentifier oid) throws NoSuchProviderException, NoSuchAlgorithmException { return createSignature((String)sigNames.get(oid)); } protected abstract Signature createSignature(String type) throws NoSuchProviderException, NoSuchAlgorithmException; } bouncycastle-1.49.orig/src/org/bouncycastle/eac/operator/jcajce/NamedEACHelper.java0000644000175000017500000000103611643462505027652 0ustar ebourgebourgpackage org.bouncycastle.eac.operator.jcajce; import java.security.NoSuchAlgorithmException; import java.security.NoSuchProviderException; import java.security.Signature; class NamedEACHelper extends EACHelper { private final String providerName; NamedEACHelper(String providerName) { this.providerName = providerName; } protected Signature createSignature(String type) throws NoSuchProviderException, NoSuchAlgorithmException { return Signature.getInstance(type, providerName); } }bouncycastle-1.49.orig/src/org/bouncycastle/eac/operator/jcajce/JcaEACSignatureVerifierBuilder.java0000644000175000017500000001227412151251423033044 0ustar ebourgebourgpackage org.bouncycastle.eac.operator.jcajce; import java.io.IOException; import java.io.OutputStream; import java.math.BigInteger; import java.security.InvalidKeyException; import java.security.NoSuchAlgorithmException; import java.security.NoSuchProviderException; import java.security.Provider; import java.security.PublicKey; import java.security.Signature; import java.security.SignatureException; import org.bouncycastle.asn1.ASN1EncodableVector; import org.bouncycastle.asn1.ASN1ObjectIdentifier; import org.bouncycastle.asn1.DERInteger; import org.bouncycastle.asn1.DERSequence; import org.bouncycastle.asn1.eac.EACObjectIdentifiers; import org.bouncycastle.eac.operator.EACSignatureVerifier; import org.bouncycastle.operator.OperatorCreationException; import org.bouncycastle.operator.OperatorStreamException; import org.bouncycastle.operator.RuntimeOperatorException; public class JcaEACSignatureVerifierBuilder { private EACHelper helper = new DefaultEACHelper(); public JcaEACSignatureVerifierBuilder setProvider(String providerName) { this.helper = new NamedEACHelper(providerName); return this; } public JcaEACSignatureVerifierBuilder setProvider(Provider provider) { this.helper = new ProviderEACHelper(provider); return this; } public EACSignatureVerifier build(final ASN1ObjectIdentifier usageOid, PublicKey pubKey) throws OperatorCreationException { Signature sig; try { sig = helper.getSignature(usageOid); sig.initVerify(pubKey); } catch (NoSuchAlgorithmException e) { throw new OperatorCreationException("unable to find algorithm: " + e.getMessage(), e); } catch (NoSuchProviderException e) { throw new OperatorCreationException("unable to find provider: " + e.getMessage(), e); } catch (InvalidKeyException e) { throw new OperatorCreationException("invalid key: " + e.getMessage(), e); } final SignatureOutputStream sigStream = new SignatureOutputStream(sig); return new EACSignatureVerifier() { public ASN1ObjectIdentifier getUsageIdentifier() { return usageOid; } public OutputStream getOutputStream() { return sigStream; } public boolean verify(byte[] expected) { try { if (usageOid.on(EACObjectIdentifiers.id_TA_ECDSA)) { try { byte[] reencoded = derEncode(expected); return sigStream.verify(reencoded); } catch (Exception e) { return false; } } else { return sigStream.verify(expected); } } catch (SignatureException e) { throw new RuntimeOperatorException("exception obtaining signature: " + e.getMessage(), e); } } }; } private static byte[] derEncode(byte[] rawSign) throws IOException { int len = rawSign.length / 2; byte[] r = new byte[len]; byte[] s = new byte[len]; System.arraycopy(rawSign, 0, r, 0, len); System.arraycopy(rawSign, len, s, 0, len); ASN1EncodableVector v = new ASN1EncodableVector(); v.add(new DERInteger(new BigInteger(1, r))); v.add(new DERInteger(new BigInteger(1, s))); DERSequence seq = new DERSequence(v); return seq.getEncoded(); } private class SignatureOutputStream extends OutputStream { private Signature sig; SignatureOutputStream(Signature sig) { this.sig = sig; } public void write(byte[] bytes, int off, int len) throws IOException { try { sig.update(bytes, off, len); } catch (SignatureException e) { throw new OperatorStreamException("exception in content signer: " + e.getMessage(), e); } } public void write(byte[] bytes) throws IOException { try { sig.update(bytes); } catch (SignatureException e) { throw new OperatorStreamException("exception in content signer: " + e.getMessage(), e); } } public void write(int b) throws IOException { try { sig.update((byte)b); } catch (SignatureException e) { throw new OperatorStreamException("exception in content signer: " + e.getMessage(), e); } } boolean verify(byte[] expected) throws SignatureException { return sig.verify(expected); } } } bouncycastle-1.49.orig/src/org/bouncycastle/eac/operator/jcajce/ProviderEACHelper.java0000644000175000017500000000075411643462505030426 0ustar ebourgebourgpackage org.bouncycastle.eac.operator.jcajce; import java.security.NoSuchAlgorithmException; import java.security.Provider; import java.security.Signature; class ProviderEACHelper extends EACHelper { private final Provider provider; ProviderEACHelper(Provider provider) { this.provider = provider; } protected Signature createSignature(String type) throws NoSuchAlgorithmException { return Signature.getInstance(type, provider); } }bouncycastle-1.49.orig/src/org/bouncycastle/eac/operator/jcajce/DefaultEACHelper.java0000644000175000017500000000050511642756730030217 0ustar ebourgebourgpackage org.bouncycastle.eac.operator.jcajce; import java.security.NoSuchAlgorithmException; import java.security.Signature; class DefaultEACHelper extends EACHelper { protected Signature createSignature(String type) throws NoSuchAlgorithmException { return Signature.getInstance(type); } } bouncycastle-1.49.orig/src/org/bouncycastle/eac/operator/EACSignatureVerifier.java0000644000175000017500000000147111643462505027707 0ustar ebourgebourgpackage org.bouncycastle.eac.operator; import java.io.OutputStream; import org.bouncycastle.asn1.ASN1ObjectIdentifier; public interface EACSignatureVerifier { /** * Return the usage OID specifying the signature type. * * @return algorithm oid. */ ASN1ObjectIdentifier getUsageIdentifier(); /** * Returns a stream that will accept data for the purpose of calculating * a signature for later verification. Use org.bouncycastle.util.io.TeeOutputStream if you want to accumulate * the data on the fly as well. * * @return an OutputStream */ OutputStream getOutputStream(); /** * @param expected expected value of the signature on the data. * @return true if the signature verifies, false otherwise */ boolean verify(byte[] expected); }bouncycastle-1.49.orig/src/org/bouncycastle/eac/jcajce/0000755000175000017500000000000012152033551022446 5ustar ebourgebourgbouncycastle-1.49.orig/src/org/bouncycastle/eac/jcajce/EACHelper.java0000644000175000017500000000045411723625227025056 0ustar ebourgebourgpackage org.bouncycastle.eac.jcajce; import java.security.KeyFactory; import java.security.NoSuchAlgorithmException; import java.security.NoSuchProviderException; interface EACHelper { KeyFactory createKeyFactory(String type) throws NoSuchProviderException, NoSuchAlgorithmException; } bouncycastle-1.49.orig/src/org/bouncycastle/eac/jcajce/NamedEACHelper.java0000644000175000017500000000103111723625227026013 0ustar ebourgebourgpackage org.bouncycastle.eac.jcajce; import java.security.KeyFactory; import java.security.NoSuchAlgorithmException; import java.security.NoSuchProviderException; class NamedEACHelper implements EACHelper { private final String providerName; NamedEACHelper(String providerName) { this.providerName = providerName; } public KeyFactory createKeyFactory(String type) throws NoSuchProviderException, NoSuchAlgorithmException { return KeyFactory.getInstance(type, providerName); } }bouncycastle-1.49.orig/src/org/bouncycastle/eac/jcajce/ProviderEACHelper.java0000644000175000017500000000074711723625227026576 0ustar ebourgebourgpackage org.bouncycastle.eac.jcajce; import java.security.KeyFactory; import java.security.NoSuchAlgorithmException; import java.security.Provider; class ProviderEACHelper implements EACHelper { private final Provider provider; ProviderEACHelper(Provider provider) { this.provider = provider; } public KeyFactory createKeyFactory(String type) throws NoSuchAlgorithmException { return KeyFactory.getInstance(type, provider); } }bouncycastle-1.49.orig/src/org/bouncycastle/eac/jcajce/JcaPublicKeyConverter.java0000644000175000017500000001304012151251423027503 0ustar ebourgebourgpackage org.bouncycastle.eac.jcajce; import java.math.BigInteger; import java.security.KeyFactory; import java.security.NoSuchAlgorithmException; import java.security.NoSuchProviderException; import java.security.Provider; import java.security.PublicKey; import java.security.interfaces.ECPublicKey; import java.security.spec.ECField; import java.security.spec.ECFieldFp; import java.security.spec.EllipticCurve; import java.security.spec.InvalidKeySpecException; import java.security.spec.RSAPublicKeySpec; import org.bouncycastle.asn1.ASN1ObjectIdentifier; import org.bouncycastle.asn1.eac.EACObjectIdentifiers; import org.bouncycastle.asn1.eac.ECDSAPublicKey; import org.bouncycastle.asn1.eac.PublicKeyDataObject; import org.bouncycastle.asn1.eac.RSAPublicKey; import org.bouncycastle.eac.EACException; import org.bouncycastle.jce.spec.ECParameterSpec; import org.bouncycastle.jce.spec.ECPublicKeySpec; import org.bouncycastle.math.ec.ECCurve; import org.bouncycastle.math.ec.ECPoint; public class JcaPublicKeyConverter { private EACHelper helper = new DefaultEACHelper(); public JcaPublicKeyConverter setProvider(String providerName) { this.helper = new NamedEACHelper(providerName); return this; } public JcaPublicKeyConverter setProvider(Provider provider) { this.helper = new ProviderEACHelper(provider); return this; } public PublicKey getKey(PublicKeyDataObject publicKeyDataObject) throws EACException, InvalidKeySpecException { if (publicKeyDataObject.getUsage().on(EACObjectIdentifiers.id_TA_ECDSA)) { return getECPublicKeyPublicKey((ECDSAPublicKey)publicKeyDataObject); } else { RSAPublicKey pubKey = (RSAPublicKey)publicKeyDataObject; RSAPublicKeySpec pubKeySpec = new RSAPublicKeySpec(pubKey.getModulus(), pubKey.getPublicExponent()); try { KeyFactory factk = helper.createKeyFactory("RSA"); return factk.generatePublic(pubKeySpec); } catch (NoSuchProviderException e) { throw new EACException("cannot find provider: " + e.getMessage(), e); } catch (NoSuchAlgorithmException e) { throw new EACException("cannot find algorithm ECDSA: " + e.getMessage(), e); } } } private PublicKey getECPublicKeyPublicKey(ECDSAPublicKey key) throws EACException, InvalidKeySpecException { ECParameterSpec spec = getParams(key); ECCurve curve = spec.getCurve(); ECPoint point = curve.decodePoint(key.getPublicPointY()); ECPublicKeySpec pubKeySpec = new ECPublicKeySpec(point, spec); KeyFactory factk; try { factk = helper.createKeyFactory("ECDSA"); } catch (NoSuchProviderException e) { throw new EACException("cannot find provider: " + e.getMessage(), e); } catch (NoSuchAlgorithmException e) { throw new EACException("cannot find algorithm ECDSA: " + e.getMessage(), e); } return factk.generatePublic(pubKeySpec); } private ECParameterSpec getParams(ECDSAPublicKey key) { if (!key.hasParameters()) { throw new IllegalArgumentException("Public key does not contains EC Params"); } BigInteger p = key.getPrimeModulusP(); ECCurve.Fp curve = new ECCurve.Fp(p, key.getFirstCoefA(), key.getSecondCoefB()); ECPoint G = curve.decodePoint(key.getBasePointG()); BigInteger order = key.getOrderOfBasePointR(); BigInteger coFactor = key.getCofactorF(); // TODO: update to use JDK 1.5 EC API ECParameterSpec ecspec = new ECParameterSpec(curve, G, order, coFactor); return ecspec; } public PublicKeyDataObject getPublicKeyDataObject(ASN1ObjectIdentifier usage, PublicKey publicKey) { if (publicKey instanceof java.security.interfaces.RSAPublicKey) { java.security.interfaces.RSAPublicKey pubKey = (java.security.interfaces.RSAPublicKey)publicKey; return new RSAPublicKey(usage, pubKey.getModulus(), pubKey.getPublicExponent()); } else { ECPublicKey pubKey = (ECPublicKey)publicKey; java.security.spec.ECParameterSpec params = pubKey.getParams(); return new ECDSAPublicKey( usage, ((ECFieldFp)params.getCurve().getField()).getP(), params.getCurve().getA(), params.getCurve().getB(), convertPoint(convertCurve(params.getCurve()), params.getGenerator(), false).getEncoded(), params.getOrder(), convertPoint(convertCurve(params.getCurve()), pubKey.getW(), false).getEncoded(), params.getCofactor()); } } private static org.bouncycastle.math.ec.ECPoint convertPoint( ECCurve curve, java.security.spec.ECPoint point, boolean withCompression) { return curve.createPoint(point.getAffineX(), point.getAffineY(), withCompression); } private static ECCurve convertCurve( EllipticCurve ec) { ECField field = ec.getField(); BigInteger a = ec.getA(); BigInteger b = ec.getB(); if (field instanceof ECFieldFp) { return new ECCurve.Fp(((ECFieldFp)field).getP(), a, b); } else { throw new IllegalStateException("not implemented yet!!!"); } } } bouncycastle-1.49.orig/src/org/bouncycastle/eac/jcajce/DefaultEACHelper.java0000644000175000017500000000050011723625227026353 0ustar ebourgebourgpackage org.bouncycastle.eac.jcajce; import java.security.KeyFactory; import java.security.NoSuchAlgorithmException; class DefaultEACHelper implements EACHelper { public KeyFactory createKeyFactory(String type) throws NoSuchAlgorithmException { return KeyFactory.getInstance(type); } } bouncycastle-1.49.orig/src/org/bouncycastle/eac/package.html0000644000175000017500000000041311730300521023501 0ustar ebourgebourg Base classes Extended Access Control (EAC) Certificates as described in "Technical Guideline, Advanced Security Mechanisms for Machine Readable Travel Documents, Extended Access Control (EAC), Version 1.0.1, BSI 2006". bouncycastle-1.49.orig/src/org/bouncycastle/eac/EACCertificateBuilder.java0000644000175000017500000000575312151251423026145 0ustar ebourgebourgpackage org.bouncycastle.eac; import java.io.OutputStream; import org.bouncycastle.asn1.ASN1Encoding; import org.bouncycastle.asn1.DERApplicationSpecific; import org.bouncycastle.asn1.eac.CVCertificate; import org.bouncycastle.asn1.eac.CertificateBody; import org.bouncycastle.asn1.eac.CertificateHolderAuthorization; import org.bouncycastle.asn1.eac.CertificateHolderReference; import org.bouncycastle.asn1.eac.CertificationAuthorityReference; import org.bouncycastle.asn1.eac.EACTags; import org.bouncycastle.asn1.eac.PackedDate; import org.bouncycastle.asn1.eac.PublicKeyDataObject; import org.bouncycastle.eac.operator.EACSigner; public class EACCertificateBuilder { private static final byte [] ZeroArray = new byte [] {0}; private PublicKeyDataObject publicKey; private CertificateHolderAuthorization certificateHolderAuthorization; private PackedDate certificateEffectiveDate; private PackedDate certificateExpirationDate; private CertificateHolderReference certificateHolderReference; private CertificationAuthorityReference certificationAuthorityReference; public EACCertificateBuilder( CertificationAuthorityReference certificationAuthorityReference, PublicKeyDataObject publicKey, CertificateHolderReference certificateHolderReference, CertificateHolderAuthorization certificateHolderAuthorization, PackedDate certificateEffectiveDate, PackedDate certificateExpirationDate) { this.certificationAuthorityReference = certificationAuthorityReference; this.publicKey = publicKey; this.certificateHolderReference = certificateHolderReference; this.certificateHolderAuthorization = certificateHolderAuthorization; this.certificateEffectiveDate = certificateEffectiveDate; this.certificateExpirationDate = certificateExpirationDate; } private CertificateBody buildBody() { DERApplicationSpecific certificateProfileIdentifier; certificateProfileIdentifier = new DERApplicationSpecific( EACTags.INTERCHANGE_PROFILE, ZeroArray); CertificateBody body = new CertificateBody( certificateProfileIdentifier, certificationAuthorityReference, publicKey, certificateHolderReference, certificateHolderAuthorization, certificateEffectiveDate, certificateExpirationDate); return body; } public EACCertificateHolder build(EACSigner signer) throws EACException { try { CertificateBody body = buildBody(); OutputStream vOut = signer.getOutputStream(); vOut.write(body.getEncoded(ASN1Encoding.DER)); vOut.close(); return new EACCertificateHolder(new CVCertificate(body, signer.getSignature())); } catch (Exception e) { throw new EACException("unable to process signature: " + e.getMessage(), e); } } } bouncycastle-1.49.orig/src/org/bouncycastle/eac/EACCertificateRequestHolder.java0000644000175000017500000000450211643177311027344 0ustar ebourgebourgpackage org.bouncycastle.eac; import java.io.IOException; import java.io.OutputStream; import org.bouncycastle.asn1.ASN1Encoding; import org.bouncycastle.asn1.ASN1ParsingException; import org.bouncycastle.asn1.eac.CVCertificateRequest; import org.bouncycastle.asn1.eac.PublicKeyDataObject; import org.bouncycastle.eac.operator.EACSignatureVerifier; public class EACCertificateRequestHolder { private CVCertificateRequest request; private static CVCertificateRequest parseBytes(byte[] requestEncoding) throws IOException { try { return CVCertificateRequest.getInstance(requestEncoding); } catch (ClassCastException e) { throw new EACIOException("malformed data: " + e.getMessage(), e); } catch (IllegalArgumentException e) { throw new EACIOException("malformed data: " + e.getMessage(), e); } catch (ASN1ParsingException e) { if (e.getCause() instanceof IOException) { throw (IOException)e.getCause(); } else { throw new EACIOException("malformed data: " + e.getMessage(), e); } } } public EACCertificateRequestHolder(byte[] certEncoding) throws IOException { this(parseBytes(certEncoding)); } public EACCertificateRequestHolder(CVCertificateRequest request) { this.request = request; } /** * Return the underlying ASN.1 structure for the certificate in this holder. * * @return a X509CertificateStructure object. */ public CVCertificateRequest toASN1Structure() { return request; } public PublicKeyDataObject getPublicKeyDataObject() { return request.getPublicKey(); } public boolean isInnerSignatureValid(EACSignatureVerifier verifier) throws EACException { try { OutputStream vOut = verifier.getOutputStream(); vOut.write(request.getCertificateBody().getEncoded(ASN1Encoding.DER)); vOut.close(); return verifier.verify(request.getInnerSignature()); } catch (Exception e) { throw new EACException("unable to process signature: " + e.getMessage(), e); } } } bouncycastle-1.49.orig/src/org/bouncycastle/x509/0000755000175000017500000000000012152033551021204 5ustar ebourgebourgbouncycastle-1.49.orig/src/org/bouncycastle/x509/AttributeCertificateIssuer.java0000644000175000017500000001235611725024063027362 0ustar ebourgebourgpackage org.bouncycastle.x509; import java.io.IOException; import java.security.Principal; import java.security.cert.CertSelector; import java.security.cert.Certificate; import java.security.cert.X509Certificate; import java.util.ArrayList; import java.util.List; import javax.security.auth.x500.X500Principal; import org.bouncycastle.asn1.ASN1Encodable; import org.bouncycastle.asn1.DERSequence; import org.bouncycastle.asn1.x509.AttCertIssuer; import org.bouncycastle.asn1.x509.GeneralName; import org.bouncycastle.asn1.x509.GeneralNames; import org.bouncycastle.asn1.x509.V2Form; import org.bouncycastle.jce.X509Principal; import org.bouncycastle.util.Selector; /** * Carrying class for an attribute certificate issuer. * @deprecated use org.bouncycastle.cert.AttributeCertificateIssuer */ public class AttributeCertificateIssuer implements CertSelector, Selector { final ASN1Encodable form; /** * Set the issuer directly with the ASN.1 structure. * * @param issuer The issuer */ public AttributeCertificateIssuer(AttCertIssuer issuer) { form = issuer.getIssuer(); } public AttributeCertificateIssuer(X500Principal principal) throws IOException { this(new X509Principal(principal.getEncoded())); } public AttributeCertificateIssuer(X509Principal principal) { form = new V2Form(GeneralNames.getInstance(new DERSequence(new GeneralName(principal)))); } private Object[] getNames() { GeneralNames name; if (form instanceof V2Form) { name = ((V2Form)form).getIssuerName(); } else { name = (GeneralNames)form; } GeneralName[] names = name.getNames(); List l = new ArrayList(names.length); for (int i = 0; i != names.length; i++) { if (names[i].getTagNo() == GeneralName.directoryName) { try { l.add(new X500Principal( ((ASN1Encodable)names[i].getName()).toASN1Primitive().getEncoded())); } catch (IOException e) { throw new RuntimeException("badly formed Name object"); } } } return l.toArray(new Object[l.size()]); } /** * Return any principal objects inside the attribute certificate issuer * object. * * @return an array of Principal objects (usually X500Principal) */ public Principal[] getPrincipals() { Object[] p = this.getNames(); List l = new ArrayList(); for (int i = 0; i != p.length; i++) { if (p[i] instanceof Principal) { l.add(p[i]); } } return (Principal[])l.toArray(new Principal[l.size()]); } private boolean matchesDN(X500Principal subject, GeneralNames targets) { GeneralName[] names = targets.getNames(); for (int i = 0; i != names.length; i++) { GeneralName gn = names[i]; if (gn.getTagNo() == GeneralName.directoryName) { try { if (new X500Principal(((ASN1Encodable)gn.getName()).toASN1Primitive().getEncoded()).equals(subject)) { return true; } } catch (IOException e) { } } } return false; } public Object clone() { return new AttributeCertificateIssuer(AttCertIssuer.getInstance(form)); } public boolean match(Certificate cert) { if (!(cert instanceof X509Certificate)) { return false; } X509Certificate x509Cert = (X509Certificate)cert; if (form instanceof V2Form) { V2Form issuer = (V2Form)form; if (issuer.getBaseCertificateID() != null) { return issuer.getBaseCertificateID().getSerial().getValue().equals(x509Cert.getSerialNumber()) && matchesDN(x509Cert.getIssuerX500Principal(), issuer.getBaseCertificateID().getIssuer()); } GeneralNames name = issuer.getIssuerName(); if (matchesDN(x509Cert.getSubjectX500Principal(), name)) { return true; } } else { GeneralNames name = (GeneralNames)form; if (matchesDN(x509Cert.getSubjectX500Principal(), name)) { return true; } } return false; } public boolean equals(Object obj) { if (obj == this) { return true; } if (!(obj instanceof AttributeCertificateIssuer)) { return false; } AttributeCertificateIssuer other = (AttributeCertificateIssuer)obj; return this.form.equals(other.form); } public int hashCode() { return this.form.hashCode(); } public boolean match(Object obj) { if (!(obj instanceof X509Certificate)) { return false; } return match((Certificate)obj); } } bouncycastle-1.49.orig/src/org/bouncycastle/x509/CertPathReviewerMessages.properties0000644000175000017500000012356411251104502030242 0ustar ebourgebourg ## constructor exceptions # cert path is empty CertPathReviewer.emptyCertPath.title = CertPath is empty CertPathReviewer.emptyCertPath.text = PKIXCertPathReviewer: the CertPath is empty. CertPathReviewer.emptyCertPath.summary = PKIXCertPathReviewer: the CertPath is empty. CertPathReviewer.emptyCertPath.details = PKIXCertPathReviewer: the CertPath is empty. ## name constraints processing errors # cert DN is not in the permitted tree # {0} DN as String CertPathReviewer.notPermittedDN.title = Name constraint error: certificate DN is not permitted CertPathReviewer.notPermittedDN.text = Name constraint error: the certificate DN {0} is not permitted. CertPathReviewer.notPermittedDN.summary = Name constraint error: certificate DN is not permitted. CertPathReviewer.notPermittedDN.details = Name constraint checking error. The certificate DN {0} is not in the permitted set of DNs. # cert DN is in the excluded tree # {0} DN as String CertPathReviewer.excludedDN.title = Name constraint error: certificate DN is excluded CertPathReviewer.excludedDN.text = Name constraint error: The certificate DN {0} is excluded. CertPathReviewer.excludedDN.summary = Name constraint error: certificate DN is excluded. CertPathReviewer.excludedDN.details = Name constraint checking error. The certificate DN {0} is inside of the excluded set of DNs. # cert email is not in the permitted tree # {0} email address as String CertPathReviewer.notPermittedEmail.title = Name constraint error: not permitted email address CertPathReviewer.notPermittedEmail.text = Name constraint error: certificate contains the not permitted email address {0}. CertPathReviewer.notPermittedEmail.summary = Name constraint error: not permitted email address. CertPathReviewer.notPermittedEmail.details = Name constraint checking error. The certificate contains the email address {0} which is not in the permitted set of email addresses. # cert email is in the excluded tree # {0} email as String CertPathReviewer.excludedEmail.title = Name constraint error: excluded email address CertPathReviewer.excludedEmail.text = Name constraint error: certificate contains the excluded email address {0}. CertPathReviewer.excludedEmail.summary = Name constraint error: excluded email address. CertPathReviewer.excludedEmail.details = Name constraint checking error. The certificate contains the email address {0} which is in the excluded set of email addresses. # cert IP is not in the permitted tree # {0} ip address as String CertPathReviewer.notPermittedIP.title = Name constraint error: not permitted IP address CertPathReviewer.notPermittedIP.text = Name constraint error: certificate contains the not permitted IP address {0}. CertPathReviewer.notPermittedIP.summary = Name constraint error: not permitted IP address. CertPathReviewer.notPermittedIP.details = Name constraint checking error. The certificate contains the IP address {0} which is not in the permitted set of IP addresses. # cert ip is in the excluded tree # {0} ip address as String CertPathReviewer.excludedIP.title = Name constraint error: excluded IP address CertPathReviewer.excludedIP.text = Name constraint error: certificate contains the excluded IP address {0}. CertPathReviewer.excludedIP.summary = Name constraint error: excluded IP address. CertPathReviewer.excludedIP.details = Name constraint checking error. The certificate contains the IP address {0} which is in the excluded set of IP addresses. # error processing the name constraints extension CertPathReviewer.ncExtError.title = Name constraint checking failed CertPathReviewer.ncExtError.text = Name constraint checking failed: there was an error processing the name constraints extension of the certificate. CertPathReviewer.ncExtError.summary = Error processing the name constraints extension. CertPathReviewer.ncExtError.details = Name constraint checking failed: there was an error processing the name constraints extension of the certificate. # error processing the subject alternative name extension CertPathReviewer.subjAltNameExtError.title = Name constraint checking failed CertPathReviewer.subjAltNameExtError.text = Name constraint checking failed: there was an error processing the subject alternative name extension of the certificate. CertPathReviewer.subjAltNameExtError.summary = Error processing the subject alternative name extension. CertPathReviewer.subjAltNameExtError.details = Name constraint checking failed: there was an error processing the subject alternative name extension of the certificate. # exception extracting subject name when checking subtrees # {0} subject Principal CertPathReviewer.ncSubjectNameError.title = Name constraint checking failed CertPathReviewer.ncSubjectNameError.text = Name constraint checking failed: there was an exception extracting the DN from the certificate. CertPathReviewer.ncSubjectNameError.summary = Name constraint checking failed: exception extracting the DN. CertPathReviewer.ncSubjectNameError.details = Name constraint checking failed: there was an exception extracting the DN from the certificate. ## path length errors # max path length extended CertPathReviewer.pathLenghtExtended.title = Maximum path length extended CertPathReviewer.pathLenghtExtended.text = Certificate path invalid: Maximum path length extended. CertPathReviewer.pathLenghtExtended.summary = Certificate path invalid: Maximum path length extended. CertPathReviewer.pathLenghtExtended.details = Certificate path invalid: Maximum path length extended. # error reading length constraint from basic constraint extension CertPathReviewer.processLengthConstError.title = Path length checking failed CertPathReviewer.processLengthConstError.text = Path length checking failed: there was an error processing the basic constraint extension of the certificate. CertPathReviewer.processLengthConstError.summary = Error processing the subject alternative name extension. CertPathReviewer.processLengthConstError.details = Path length checking failed: there was an error processing the basic constraint extension of the certificate. ## path length notifications # total path length as defined in rfc 3280 # {0} the path length as Integer CertPathReviewer.totalPathLength.title = Total path length CertPathReviewer.totalPathLength.text = The total path length without self-signed certificates is {0}. CertPathReviewer.totalPathLength.summary = The total path length without self-signed certificates is {0}. CertPathReviewer.totalPathLength.details = The total path length without self-signed certificates, as defined in RFC 3280, is {0}. ## critical extensions errors # one unknown critical extension # {0} extension as String CertPathReviewer.unknownCriticalExt.title = Unknown critical extension CertPathReviewer.unknownCriticalExt.text = The certificate contains the unknown critical extension {0}. CertPathReviewer.unknownCriticalExt.summary = Unknown critical extension: {0}. CertPathReviewer.unknownCriticalExt.details = The certificate contains the unknown critical extension with the OID {0}. # more unknown critical extensions # {0} extensions as Set of Strings CertPathReviewer.unknownCriticalExts.title = Unknown critical extensions CertPathReviewer.unknownCriticalExts.text = The certificate contains two or more unknown critical extensions: {0}. CertPathReviewer.unknownCriticalExts.summary = Unknown critical extensions: {0}. CertPathReviewer.unknownCriticalExts.details = The certificate contains two or more unknown critical extensions with the OIDs: {0}. # error processing critical extension # {0} the message of the underlying exception # {1} the underlying exception # {2} the name of the exception CertPathReviewer.criticalExtensionError.title = Error processing a critical extension CertPathReviewer.criticalExtensionError.text = Error processing a critical extension. A {0} occurred. CertPathReviewer.criticalExtensionError.summary = Error processing a critical extension. A {0} occurred. CertPathReviewer.criticalExtensionError.details = Error processing a critical extension. A {0} occurred. Cause: {0}. # error initializing the certpath checkers # {0} the message of the underlying exception # {1} the underlying exception # {2} the name of the exception CertPathReviewer.certPathCheckerError.title = Checking critical extensions failed CertPathReviewer.certPathCheckerError.text = Checking critical extensions failed: there was a {2} initializing a CertPathChecker. CertPathReviewer.certPathCheckerError.summary = Checking critical extensions failed: {2} initializing a CertPathChecker CertPathReviewer.certPathCheckerError.details = Checking critical extensions failed: there was an {2} initializing a CertPathChecker. Cause: {0} ## check signature errors CertPathReviewer.rootKeyIsValidButNotATrustAnchor.title = Root key with valid signature but no trust anchor CertPathReviewer.rootKeyIsValidButNotATrustAnchor.text = The certificate has a valid signature, but is no trust anchor CertPathReviewer.rootKeyIsValidButNotATrustAnchor.summary = The certificate has a valid signature, but is no trust anchor CertPathReviewer.rootKeyIsValidButNotATrustAnchor.details = The certificate has a valid signature, but is no trust anchor # trustanchor found, but certificate validation failed CertPathReviewer.trustButInvalidCert.title = Trust anchor found, but different public key CertPathReviewer.trustButInvalidCert.text = A trust anchor was found. But it has a different public key, than was used to issue the first certificate of the cert path. CertPathReviewer.trustButInvalidCert.summary = A trust anchor was found. But it has a different public key, than was used to issue the first certificate of the cert path. CertPathReviewer.trustButInvalidCert.details = A trust anchor was found. But it has a different public key, than was used to issue the first certificate of the cert path. # trustanchor - cannot extract issuer CertPathReviewer.trustAnchorIssuerError.title = Finding trust anchor failed CertPathReviewer.trustAnchorIssuerError.text = Finding trust anchor failed: cannot extract issuer from certificate. CertPathReviewer.trustAnchorIssuerError.summary = Finding trust anchor failed: cannot extract issuer from certificate. CertPathReviewer.trustAnchorIssuerError.details = Finding trust anchor failed: cannot extract issuer from certificate. # no trustanchor was found for the certificate path # {0} issuer of the root certificate of the path # {1} number of trusted root certificates (trustanchors) provided CertPathReviewer.noTrustAnchorFound.title = No trusted root certificate found CertPathReviewer.noTrustAnchorFound.text = The root certificate of the certificate path was issued by a CA that is not in the the trusted-root-certificate-store used for the path validation. The name of the CA is "{0}". CertPathReviewer.noTrustAnchorFound.summary = The root certificate of the certificate path was issued by a CA that is not in the the trusted-root-certificate-store used for the path validation. CertPathReviewer.noTrustAnchorFound.details = The root certificate of the certificate path was issued by a CA that is not in the the trusted-root-certificate-store used for the path validation. The name of the CA is "{0}". The trusted-root-certificate store contains {1} CA(s). # conflicting trust anchors # {0} number of trustanchors found (Integer) # {1} the ca name CertPathReviewer.conflictingTrustAnchors.title = Corrupt trust root store CertPathReviewer.conflictingTrustAnchors.text = Warning: corrupt trust root store: There are {0} trusted public keys for the CA "{1}" - please ensure with CA which is the correct key. CertPathReviewer.conflictingTrustAnchors.summary = Warning: corrupt trust root store: There are {0} trusted public keys for the CA "{1}" - please ensure with CA which is the correct key. CertPathReviewer.conflictingTrustAnchors.details = Warning: corrupt trust root store: There are {0} trusted public keys for the CA "{1}" - please ensure with CA which is the correct key. # trustanchor DN is invalid # {0} DN of the Trustanchor CertPathReviewer.trustDNInvalid.title = DN of TrustAnchor is improperly specified CertPathReviewer.trustDNInvalid.text = The DN of the TrustAnchor is improperly specified: {0}. CertPathReviewer.trustDNInvalid.summary = The DN of the TrustAnchor is improperly specified. CertPathReviewer.trustDNInvalid.details = The DN of the TrustAnchor is improperly specified: {0}. It's not a valid X.500 name. See RFC 1779 or RFC 2253. # trustanchor public key algorithm error CertPathReviewer.trustPubKeyError.title = Error processing public key of the trust anchor CertPathReviewer.trustPubKeyError.text = Error processing public key of the trust anchor. CertPathReviewer.trustPubKeyError.summary = Error processing public key of the trust anchor. CertPathReviewer.trustPubKeyError.details = Error processing public key of the trust anchor. Could not extract the AlorithmIdentifier for the key. # can not verifiy signature: issuer public key unknown CertPathReviewer.NoIssuerPublicKey.title = Can not verify the certificate signature CertPathReviewer.NoIssuerPublicKey.text = Can not verify the certificate signature: Issuer public key is unknown. CertPathReviewer.NoIssuerPublicKey.summary = Can not verify the certificate signature: Issuer public key is unknown. CertPathReviewer.NoIssuerPublicKey.details = Can not verify the certificate signature: Issuer public key is unknown. # signature can not be verified # {0} message of the underlying exception (english) # {1} the underlying exception # {2} the name of the exception CertPathReviewer.signatureNotVerified.title = Certificate signature invalid CertPathReviewer.signatureNotVerified.text = The certificate signature is invalid. A {2} occurred. CertPathReviewer.signatureNotVerified.summary = The certificate signature is invalid. CertPathReviewer.signatureNotVerified.details = The certificate signature is invalid. A {2} occurred. Cause: {0} # certificate expired # {0} the date the certificate expired CertPathReviewer.certificateExpired.title = Certificate is expired CertPathReviewer.certificateExpired.text = Could not validate the certificate. Certificate expired on {0,date} {0,time,full}. CertPathReviewer.certificateExpired.summary = Certificate expired on {0,date} {0,time,full}. CertPathReviewer.certificateExpired.details = Could not validate the certificate. Certificate expired on {0,date} {0,time,full}. # certificate not yet valid # {0} the date from which on the certificate is valid CertPathReviewer.certificateNotYetValid.title = Certificate is not yet valid CertPathReviewer.certificateNotYetValid.text = Could not validate the certificate. Certificate is not valid until {0,date} {0,time,full}. CertPathReviewer.certificateNotYetValid.summary = Certificate is not valid until {0,date} {0,time,full}. CertPathReviewer.certificateNotYetValid.details = Could not validate the certificate. Certificate is not valid until {0,date} {0,time,full}. # certificate invalid issuer DN # {0} expected issuer DN as String # {1} found issuer DN as String CertPathReviewer.certWrongIssuer.title = Issuer of certificate not valid CertPathReviewer.certWrongIssuer.text = Issuer of certificate is not valid. Expected {0}, but found {1}. CertPathReviewer.certWrongIssuer.summary = Issuer of certificate is not valid. CertPathReviewer.certWrongIssuer.details = Issuer of certificate is not valid. Expected {0}, but found {1}. # intermediate certificate is no ca cert CertPathReviewer.noCACert.title = Certificate is no CA certificate CertPathReviewer.noCACert.text = Intermediate certificate is no CA certificate. CertPathReviewer.noCACert.summary = The certificate is no CA certificate. CertPathReviewer.noCACert.details = The certificate is no CA certificate but used as one. # cert laks basic constraints CertPathReviewer.noBasicConstraints.title = Certificate has no basic constraints CertPathReviewer.noBasicConstraints.text = Intermediate certificate has no basic constraints. CertPathReviewer.noBasicConstraints.summary = Intermediate certificate has no basic constraints. CertPathReviewer.noBasicConstraints.details = Intermediate certificate has no basic constraints. # error processing basic constraints CertPathReviewer.errorProcesingBC.title = Error processing the basic constraints extension CertPathReviewer.errorProcesingBC.text = There was an error while processing the basic constraints extension of this certificate. CertPathReviewer.errorProcesingBC.summary = Error processing the basic constraints extension. CertPathReviewer.errorProcesingBC.details = There was an error while processing the basic constraints extension of this certificate. # certificate not usable for signing certs CertPathReviewer.noCertSign.title = Key not usable for signing certificates CertPathReviewer.noCertSign.text = The key usage constraint does not allow the use of this certificate key for signing certificates. CertPathReviewer.noCertSign.summary = The certificate key can not be used for signing certificates. CertPathReviewer.noCertSign.details = The key usage constraint does not allow the use of this certificate key for signing certificates. # error processing public key CertPathReviewer.pubKeyError.title = Error processing public key CertPathReviewer.pubKeyError.text = Error processing public key of the certificate. CertPathReviewer.pubKeyError.summary = Error processing public key of the certificate. CertPathReviewer.pubKeyError.details = Error processing public key of the certificate. Could not extract the AlorithmIdentifier for the key. ## check signatures notifications # # trust anchor has no keyusage certSign CertPathReviewer.trustKeyUsage.title = Trust anchor key usage CertPathReviewer.trustKeyUsage.text = The trust anchor is not alloed to sign certificates. CertPathReviewer.trustKeyUsage.summary = The trust anchor is not alloed to sign certificates. CertPathReviewer.trustKeyUsage.details = The trust anchor is not alloed to sign certificates. # certificate path validation date # {0} date for which the cert path is validated # {1} current date CertPathReviewer.certPathValidDate.title = Certificate path validation date CertPathReviewer.certPathValidDate.text = The certificate path was applied on {0,date} {0,time,full}. It was checked at {1,date} {1,time,full}. CertPathReviewer.certPathValidDate.summary = The certificate path was validated for {0,date} {0,time,full}. It was checked at {1,date} {1,time,full}. CertPathReviewer.certPathValidDate.details = The certificate path was validated for {0,date} {0,time,full}. It was checked at {1,date} {1,time,full}. ## check policy errors # error processing certificate policy extension CertPathReviewer.policyExtError.title = Policy checking failed CertPathReviewer.policyExtError.text = Policy checking failed: there was an error processing the certificate policy extension. CertPathReviewer.policyExtError.summary = Error processing the certificate policy extension. CertPathReviewer.policyExtError.details = Policy checking failed: there was an error processing the certificate policy extension. # error processing policy constraints extension CertPathReviewer.policyConstExtError.title = Policy checking failed CertPathReviewer.policyConstExtError.text = Policy checking failed: there was an error processing the policy constraints extension. CertPathReviewer.policyConstExtError.summary = Error processing the policy constraints extension. CertPathReviewer.policyConstExtError.details = Policy checking failed: there was an error processing the policy constraints extension. # error processing policy mapping extension CertPathReviewer.policyMapExtError.title = Policy checking failed CertPathReviewer.policyMapExtError.text = Policy checking failed: there was an error processing the policy mapping extension. CertPathReviewer.policyMapExtError.summary = Error processing the policy mapping extension. CertPathReviewer.policyMapExtError.details = Policy checking failed: there was an error processing the policy mapping extension. # error processing inhibit any policy extension CertPathReviewer.policyInhibitExtError.title = Policy checking failed CertPathReviewer.policyInhibitExtError.text = Policy checking failed: there was an error processing the inhibit any policy extension. CertPathReviewer.policyInhibitExtError.summary = Error processing the inhibit any policy extension. CertPathReviewer.policyInhibitExtError.details = Policy checking failed: there was an error processing the inhibit any policy extension. # error building qualifier set CertPathReviewer.policyQualifierError.title = Policy checking failed CertPathReviewer.policyQualifierError.text = Policy checking failed: error building the policy qualifier set. CertPathReviewer.policyQualifierError.summary = Policy checking failed: error building the policy qualifier set. CertPathReviewer.policyQualifierError.details = Policy checking failed: error building the policy qualifier set. # no valid policy tree - explicit policy required CertPathReviewer.noValidPolicyTree.title = Policy checking failed CertPathReviewer.noValidPolicyTree.text = Policy checking failed: no valid policy tree found when one expected. CertPathReviewer.noValidPolicyTree.summary = Policy checking failed: no valid policy tree found when one expected. CertPathReviewer.noValidPolicyTree.details = Policy checking failed: no valid policy tree found when one expected. # expicit policy requested, but no policy available CertPathReviewer.explicitPolicy.title = Policy checking failed CertPathReviewer.explicitPolicy.text = Policy checking failed: explicit policy requested but no policy available. CertPathReviewer.explicitPolicy.summary = Policy checking failed: explicit policy requested but no policy available. CertPathReviewer.explicitPolicy.details = Policy checking failed: explicit policy requested but no policy available. # path processing failed on policy CertPathReviewer.invalidPolicy.title = Path processing failed on policy CertPathReviewer.invalidPolicy.text = Path processing failed on policy. CertPathReviewer.invalidPolicy.summary = Path processing failed on policy. CertPathReviewer.invalidPolicy.details = Path processing failed on policy. # invalid policy mapping CertPathReviewer.invalidPolicyMapping.title = Invalid policy mapping CertPathReviewer.invalidPolicyMapping.text = Certificate contains an invalid policy mapping. CertPathReviewer.invalidPolicyMapping.summary = Certificate contains an invalid policy mapping. CertPathReviewer.invalidPolicyMapping.details = Certificate contains a policy mapping including the value any policy which is invalid. ## check CRL notifications # found local valid CRL # {0} thisUpdate of the CRL # {1} nextUpdate of the CRL CertPathReviewer.localValidCRL.title = Found valid local CRL CertPathReviewer.localValidCRL.text = Found a valid CRL in local certstore. Issued on {0,date}, next update {1,date}. CertPathReviewer.localValidCRL.summary = Found a valid CRL in local certstore. Issued on {0,date}, next update {1,date}. CertPathReviewer.localValidCRL.details = Found a valid CRL in local certstore. Issued on {0,date}, next update {1,date}. # found matching CRL, but not valid # {0} thisUpdate of the CRL # {1} nextUpdate of the CRL CertPathReviewer.localInvalidCRL.title = Local CRL outdated CertPathReviewer.localInvalidCRL.text = Did not use a matching CRL in a local certstore, because it is outdated. Issued on {0,date}, next update {1,date}. CertPathReviewer.localInvalidCRL.summary = Did not use a matching CRL in a local certstore, because it is outdated. Issued on {0,date}, next update {1,date}. CertPathReviewer.localInvalidCRL.details = Did not use a matching CRL in a local certstore, because it is outdated. Issued on {0,date}, next update {1,date}. # found a valid crl at crl distribution point # {0} thisUpdate of the CRL # {1} nextUpdate of the CRL # {2} the url of the distribution point CertPathReviewer.onlineValidCRL.title = Found valid CRL at CRL distribution point CertPathReviewer.onlineValidCRL.text = Found a valid CRL at: {2}. Issued on {0,date}, next update on {1,date}. CertPathReviewer.onlineValidCRL.summary = Found a valid CRL at: {2}. Issued on {0,date}, next update on {1,date}. CertPathReviewer.onlineValidCRL.details = Found a valid CRL at: {2}. Issued on {0,date}, next update on {1,date}. # found an invalid CRL at crl distribution point # {0} thisUpdate of the CRL # {1} nextUpdate of the CRL # {2} the url of the distribution point CertPathReviewer.onlineInvalidCRL.title = Outdated CRL at CRL distribution point CertPathReviewer.onlineInvalidCRL.text = The CRL loaded from {2} was outdated. Issued on {0,date}, next update on {1,date}. CertPathReviewer.onlineInvalidCRL.summary = The CRL loaded from {2} was outdated. Issued on {0,date}, next update on {1,date}. CertPathReviewer.onlineInvalidCRL.details = The CRL loaded from {2} was outdated. Issued on {0,date}, next update on {1,date}. #found a CRL at a crl distribution point, but issued by another CA # {0} issuer of the CRL # {1} expected issuer # {2} the url of the distribution point CertPathReviewer.onlineCRLWrongCA.title = CRL from wrong issuer at CRL distribution point CertPathReviewer.onlineCRLWrongCA.text = The CRL loaded from {2} has was issued by {0}, excpected {1}. CertPathReviewer.onlineCRLWrongCA.summary = The CRL loaded from {2} has a wrong issuer. CertPathReviewer.onlineCRLWrongCA.details = The CRL loaded from {2} has was issued by {0}, excpected {1}. # Certificate not revoked CertPathReviewer.notRevoked.title = Certificate not revoked CertPathReviewer.notRevoked.text = The certificate was not revoked. CertPathReviewer.notRevoked.summary = The certificate was not revoked. CertPathReviewer.notRevoked.details = The certificate was not revoked. # CRL found: certificate was revoked, but after the validationDate # {0} the date the certificate was revoked # {1} the reason for revoking the certificate CertPathReviewer.revokedAfterValidation.title = Certificate was revoked after the validation date CertPathReviewer.revokedAfterValidation.text = The certificate was revoked after the validation date at {0,date} {0,time,full}. Reason: {1}. CertPathReviewer.revokedAfterValidation.summary = The certificate was revoked after the validation date at {0,date} {0,time,full}. CertPathReviewer.revokedAfterValidation.details = The certificate was revoked after the validation date at {0,date} {0,time,full}. Reason: {1}. # updated crl available # {0} date since when the update is available CertPathReviewer.crlUpdateAvailable.title = CRL update available CertPathReviewer.crlUpdateAvailable.text = An update for the CRL of this certificate is available since {0,date} {0,time,full}. CertPathReviewer.crlUpdateAvailable.summary = An update for the CRL of this certificate is available since {0,date} {0,time,full}. CertPathReviewer.crlUpdateAvailable.details = An update for the CRL of this certificate is available since {0,date} {0,time,full}. # crl distribution point url # {0} the crl distribution point url as String CertPathReviewer.crlDistPoint.title = CRL distribution point CertPathReviewer.crlDistPoint.text = A CRL can be obtained from: {0}. CertPathReviewer.crlDistPoint.summary = A CRL can be obtained from: {0}. CertPathReviewer.crlDistPoint.details = A CRL can be obtained from: {0}. # ocsp location # {0} the url on which the ocsp service can be found CertPathReviewer.ocspLocation.title = OCSP responder location CertPathReviewer.ocspLocation.text = OCSP responder location: {0}. CertPathReviewer.ocspLocation.summary = OCSP responder location: {0}. CertPathReviewer.ocspLocation.details = OCSP responder location: {0}. # unable to get crl from crl distribution point # {0} the url of the distribution point # {1} the message of the occurred exception # {2} the occurred exception # {3} the name of the exception CertPathReviewer.loadCrlDistPointError.title = Cannot load CRL from CRL distribution point CertPathReviewer.loadCrlDistPointError.text = Unable to load a CRL from: {0}. A {3} occurred. CertPathReviewer.loadCrlDistPointError.summary = Unable to load a CRL from: {0}. A {3} occurred. CertPathReviewer.loadCrlDistPointError.details = Unable to load a CRL from: {0}. A {3} occurred. Cause: {1}. # no crl found in certstores # {0} the issuers which we searched for # {1} list of crl issuer names that are found in the certstores # {2} number of crls in the certstores CertPathReviewer.noCrlInCertstore.title = No matching CRL found in local CRL store CertPathReviewer.noCrlInCertstore.text = No matching CRL was found in the provided local CRL store. CertPathReviewer.noCrlInCertstore.summary = No matching CRL was found in the provided local CRL store. CertPathReviewer.noCrlInCertstore.details = No matching CRL was found in the provided local CRL store. \ No CRL was found for the selector "{0}". The {2} CRL(s) in the certstores are from "{1}". ## check CRL exceptions # cannot extract issuer from certificate CertPathReviewer.crlIssuerException.title = CRL checking failed CertPathReviewer.crlIssuerException.text = CRL checking failed: cannot extract issuer from certificate. CertPathReviewer.crlIssuerException.summary = CRL checking failed: cannot extract issuer from certificate. CertPathReviewer.crlIssuerException.details = CRL checking failed: cannot extract issuer from certificate. # cannot extract crls # {0} message from the underlying exception # {1} the underlying exception # {2} the name of the exception CertPathReviewer.crlExtractionError.title = CRL checking failed CertPathReviewer.crlExtractionError.text = CRL checking failed: Cannot extract CRL from CertStore. There was a {2}. CertPathReviewer.crlExtractionError.summary = CRL checking failed: Cannot extract CRL from CertStore. There was a {2}. CertPathReviewer.crlExtractionError.details = CRL checking failed: Cannot extract CRL from CertStore. There was a {2}. Cause: {0}. # Issuer certificate key usage extension does not permit crl signing CertPathReviewer.noCrlSigningPermited.title = CRL checking failed CertPathReviewer.noCrlSigningPermited.text = CRL checking failed: issuer certificate does not permit CRL signing. CertPathReviewer.noCrlSigningPermited.summary = CRL checking failed: issuer certificate does not permit CRL signing. CertPathReviewer.noCrlSigningPermited.details = CRL checking failed: issuer certificate does not permit CRL signing. # can not verify crl: issuer public key unknown CertPathReviewer.crlNoIssuerPublicKey.title = CRL checking failed CertPathReviewer.crlNoIssuerPublicKey.text = CRL checking failed: Can not verify the CRL: Issuer public key is unknown. CertPathReviewer.crlNoIssuerPublicKey.summary = CRL checking failed: Can not verify the CRL: Issuer public key is unknown. CertPathReviewer.crlNoIssuerPublicKey.details = CRL checking failed: Can not verify the CRL: Issuer public key is unknown. # crl verification failed CertPathReviewer.crlVerifyFailed.title = CRL checking failed CertPathReviewer.crlVerifyFailed.text = CRL checking failed: CRL signature is invalid. CertPathReviewer.crlVerifyFailed.summary = CRL checking failed: CRL signature is invalid. CertPathReviewer.crlVerifyFailed.details = CRL checking failed: CRL signature is invalid. # no valid CRL found CertPathReviewer.noValidCrlFound.title = CRL checking failed CertPathReviewer.noValidCrlFound.text = CRL checking failed: no valid CRL found. CertPathReviewer.noValidCrlFound.summary = CRL checking failed: no valid CRL found. CertPathReviewer.noValidCrlFound.details = CRL checking failed: no valid CRL found. # No base CRL for delta CRL CertPathReviewer.noBaseCRL.title = CRL checking failed CertPathReviewer.noBaseCRL.text = CRL checking failed: no base CRL found for delta CRL. CertPathReviewer.noBaseCRL.summary = CRL checking failed: no base CRL found for delta CRL. CertPathReviewer.noBaseCRL.details = CRL checking failed: no base CRL found for delta CRL. # certificate revoked # {0} the date the certificate was revoked # {1} the reason for revoking the certificate CertPathReviewer.certRevoked.title = Certificate was revoked CertPathReviewer.certRevoked.text = The certificate was revoked at {0,date} {0,time,full}. Reason: {1}. CertPathReviewer.certRevoked.summary = The certificate was revoked at {0,date} {0,time,full}. CertPathReviewer.certRevoked.details = The certificate was revoked at {0,date} {0,time,full}. Reason: {1}. # error processing issuing distribution point extension CertPathReviewer.distrPtExtError.title = CRL checking failed CertPathReviewer.distrPtExtError.text = CRL checking failed: there was an error processing the issuing distribution point extension. CertPathReviewer.distrPtExtError.summary = Error processing the issuing distribution point extension. CertPathReviewer.distrPtExtError.details = CRL checking failed: there was an error processing the issuing distribution point extension. # error processing crl distribution points extension CertPathReviewer.crlDistPtExtError.title = CRL checking failed CertPathReviewer.crlDistPtExtError.text = CRL checking failed: there was an error processing the crl distribution points extension. CertPathReviewer.crlDistPtExtError.summary = Error processing the crl distribution points extension. CertPathReviewer.crlDistPtExtError.details = CRL checking failed: there was an error processing the crl distribution points extension. # error processing the authority info access extension CertPathReviewer.crlAuthInfoAccError.title = CRL checking failed CertPathReviewer.crlAuthInfoAccError.text = CRL checking failed: there was an error processing the authority info access extension. CertPathReviewer.crlAuthInfoAccError.summary = Error processing the authority info access extension. CertPathReviewer.crlAuthInfoAccError.details = CRL checking failed: there was an error processing the authority info access extension. # error processing delta crl indicator extension CertPathReviewer.deltaCrlExtError.title = CRL checking failed CertPathReviewer.deltaCrlExtError.text = CRL checking failed: there was an error processing the delta CRL indicator extension. CertPathReviewer.deltaCrlExtError.summary = Error processing the delta CRL indicator extension. CertPathReviewer.deltaCrlExtError.details = CRL checking failed: there was an error processing the delta CRL indicator extension. # error porcessing crl number extension CertPathReviewer.crlNbrExtError.title = CRL checking failed CertPathReviewer.crlNbrExtError.text = CRL checking failed: there was an error processing the CRL number extension. CertPathReviewer.crlNbrExtError.summary = Error processing the CRL number extension. CertPathReviewer.crlNbrExtError.details = CRL checking failed: there was an error processing the CRL number extension. # error processing crl reason code extension CertPathReviewer.crlReasonExtError.title = CRL checking failed CertPathReviewer.crlReasonExtError.text = CRL checking failed: there was an error processing the CRL reason code extension. CertPathReviewer.crlReasonExtError.summary = Error processing the CRL reason code extension. CertPathReviewer.crlReasonExtError.details = CRL checking failed: there was an error processing the CRL reason code extension. # error processing basic constraints extension CertPathReviewer.crlBCExtError.title = CRL checking failed CertPathReviewer.crlBCExtError.text = CRL checking failed: there was an error processing the basic constraints extension. CertPathReviewer.crlBCExtError.summary = Error processing the basic constraints extension. CertPathReviewer.crlBCExtError.details = CRL checking failed: there was an error processing the basic constraints extension. # CA Cert CRL only contains user certificates CertPathReviewer.crlOnlyUserCert.title = CRL checking failed CertPathReviewer.crlOnlyUserCert.text = CRL checking failed: CRL only contains user certificates. CertPathReviewer.crlOnlyUserCert.summary = CRL checking failed: CRL only contains user certificates. CertPathReviewer.crlOnlyUserCert.details = CRL checking failed: CRL for CA certificate only contains user certificates. # End CRL only contains CA certificates CertPathReviewer.crlOnlyCaCert.title = CRL checking failed CertPathReviewer.crlOnlyCaCert.text = CRL checking failed: CRL only contains CA certificates. CertPathReviewer.crlOnlyCaCert.summary = CRL checking failed: CRL only contains CA certificates. CertPathReviewer.crlOnlyCaCert.details = CRL checking failed: CRL for end certificate only contains CA certificates. # onlyContainsAttributeCerts boolean is asserted CertPathReviewer.crlOnlyAttrCert.title = CRL checking failed CertPathReviewer.crlOnlyAttrCert.text = CRL checking failed: CRL only contains attribute certificates. CertPathReviewer.crlOnlyAttrCert.summary = CRL checking failed: CRL only contains attribute certificates. CertPathReviewer.crlOnlyAttrCert.details = CRL checking failed: CRL only contains attribute certificates. ## QcStatement notifications # unkown statement # {0} statement OID # {1} statement as ANS1Sequence CertPathReviewer.QcUnknownStatement.title = Unknown statement in QcStatement extension CertPathReviewer.QcUnknownStatement.text = Unknown statement in QcStatement extension: OID = {0} CertPathReviewer.QcUnknownStatement.summary = Unknown statement in QcStatement extension: OID = {0} CertPathReviewer.QcUnknownStatement.details = Unknown statement in QcStatement extension: OID = {0}, statement = {1} # QcLimitValue Alpha currency code # {0} currency code # {1} limit value # {2} monetary value as MonetaryValue CertPathReviewer.QcLimitValueAlpha.title = Transaction Value Limit CertPathReviewer.QcLimitValueAlpha.text = This certificate has a limit for the transaction value: {1,number, ###,###,###,##0.00#} {0}. CertPathReviewer.QcLimitValueAlpha.summary = Transaction value limit: {1,number, ###,###,###,##0.00#} {0}. CertPathReviewer.QcLimitValueAlpha.details = This certificate has a limitation on the value of transaction for which this certificate can be used to the specified amount, according to the Directive 1999/93/EC of the European Parliament and of the Council of 13 December 1999 on a Community framework for electronic signatures, as implemented in the law of the country specified in the issuer field of this certificate. The limit for this certificate is {1,number, ###,###,###,##0.00#} {0}. # QcLimitValue Numeric currency code # {0} currency code # {1} limit value # {2} monetary value as MonetaryValue CertPathReviewer.QcLimitValueNum.title = Transaction Value Limit CertPathReviewer.QcLimitValueNum.text = This certificate has a limit for the transaction value: {1,number, ###,###,###,##0.00#} of currency {0} (See RFC 4217 for currency codes). CertPathReviewer.QcLimitValueNum.summary = Transaction value limit: {1,number, ###,###,###,##0.00#} of currency {0} (See RFC 4217 for currency codes). CertPathReviewer.QcLimitValueNum.details = This certificate has a limitation on the value of transaction for which this certificate can be used to the specified amount, according to the Directive 1999/93/EC of the European Parliament and of the Council of 13 December 1999 on a Community framework for electronic signatures, as implemented in the law of the country specified in the issuer field of this certificate. The limit for this certificate is {1,number, ###,###,###,##0.00#} of currency {0} (See RFC 4217 for currency codes). # QcSSCD CertPathReviewer.QcSSCD.title = QcSSCD Statement CertPathReviewer.QcSSCD.text = (SSCD) The issuer claims that for the certificate where this statement appears that the private key associated with the public key in the certificate is protected according to Annex III of the Directive 1999/93/EC of the European Parliament and of the Council of 13 December 1999 on a Community framework for electronic signatures. CertPathReviewer.QcSSCD.summary = (SSCD) The issuer claims that for the certificate where this statement appears that the private key associated with the public key in the certificate is protected according to Annex III of the Directive 1999/93/EC of the European Parliament and of the Council of 13 December 1999 on a Community framework for electronic signatures. CertPathReviewer.QcSSCD.details = (SSCD) The issuer claims that for the certificate where this statement appears that the private key associated with the public key in the certificate is protected according to Annex III of the Directive 1999/93/EC of the European Parliament and of the Council of 13 December 1999 on a Community framework for electronic signatures. # QcEuCompliance CertPathReviewer.QcEuCompliance.title = Qualified Certificate CertPathReviewer.QcEuCompliance.text = This certificate is issued as a Qualified Certificate according Annex I and II of the Directive 1999/93/EC of the European Parliament and of the Council of 13 December 1999 on a Community framework for electronic signatures, as implemented in the law of the country specified in the issuer field of this certificate. CertPathReviewer.QcEuCompliance.summary = This certificate is issued as a Qualified Certificate according Annex I and II of the Directive 1999/93/EC of the European Parliament and of the Council of 13 December 1999 on a Community framework for electronic signatures, as implemented in the law of the country specified in the issuer field of this certificate. CertPathReviewer.QcEuCompliance.details = This certificate is issued as a Qualified Certificate according Annex I and II of the Directive 1999/93/EC of the European Parliament and of the Council of 13 December 1999 on a Community framework for electronic signatures, as implemented in the law of the country specified in the issuer field of this certificate. ## QcStatement errors # error processing the QcStatement extension CertPathReviewer.QcStatementExtError.title = Error processing the qc statements extension CertPathReviewer.QcStatementExtError.text = Error processing the qc statements extension. CertPathReviewer.QcStatementExtError.summary = Error processing the qc statements extension. CertPathReviewer.QcStatementExtError.details = Error processing the qc statements extension. ## unknown/generic errors CertPathReviewer.unknown.title = Unexpected Error CertPathReviewer.unknown.text = Unexpected Error {0} CertPathReviewer.unknown.summary = Unexpected Error CertPathReviewer.unknown.details = Unexpected Error {0} # # crl reasons # unspecified = Unspecified keyCompromise = Key Compromise cACompromise = CA Compromise affiliationChanged = Affiliation Changed superseded = Superseded cessationOfOperation = Cessation of Operation certificateHold = Certificate Hold unknown = Unknown removeFromCRL = Remove from CRL privilegeWithdrawn = Privilege Withdrawn aACompromise = AA Compromise # # # missingIssuer = The missing certificate was issued by missingSerial = with the serial number bouncycastle-1.49.orig/src/org/bouncycastle/x509/util/0000755000175000017500000000000012152033551022161 5ustar ebourgebourgbouncycastle-1.49.orig/src/org/bouncycastle/x509/util/StreamParsingException.java0000644000175000017500000000045210771545644027503 0ustar ebourgebourgpackage org.bouncycastle.x509.util; public class StreamParsingException extends Exception { Throwable _e; public StreamParsingException(String message, Throwable e) { super(message); _e = e; } public Throwable getCause() { return _e; } } bouncycastle-1.49.orig/src/org/bouncycastle/x509/util/StreamParser.java0000644000175000017500000000031710771545644025455 0ustar ebourgebourgpackage org.bouncycastle.x509.util; import java.util.Collection; public interface StreamParser { Object read() throws StreamParsingException; Collection readAll() throws StreamParsingException; } bouncycastle-1.49.orig/src/org/bouncycastle/x509/util/LDAPStoreHelper.java0000644000175000017500000011615111737275254025746 0ustar ebourgebourgpackage org.bouncycastle.x509.util; import java.io.ByteArrayInputStream; import java.io.IOException; import java.security.Principal; import java.security.cert.CertificateParsingException; import java.security.cert.X509CRL; import java.security.cert.X509Certificate; import java.sql.Date; import java.util.ArrayList; import java.util.Collection; import java.util.HashMap; import java.util.HashSet; import java.util.Iterator; import java.util.List; import java.util.Map; import java.util.Properties; import java.util.Set; import javax.naming.Context; import javax.naming.NamingEnumeration; import javax.naming.NamingException; import javax.naming.directory.Attribute; import javax.naming.directory.DirContext; import javax.naming.directory.InitialDirContext; import javax.naming.directory.SearchControls; import javax.naming.directory.SearchResult; import javax.security.auth.x500.X500Principal; import org.bouncycastle.asn1.ASN1InputStream; import org.bouncycastle.asn1.x509.Certificate; import org.bouncycastle.asn1.x509.CertificatePair; import org.bouncycastle.jce.X509LDAPCertStoreParameters; import org.bouncycastle.jce.provider.X509AttrCertParser; import org.bouncycastle.jce.provider.X509CRLParser; import org.bouncycastle.jce.provider.X509CertPairParser; import org.bouncycastle.jce.provider.X509CertParser; import org.bouncycastle.util.StoreException; import org.bouncycastle.x509.X509AttributeCertStoreSelector; import org.bouncycastle.x509.X509AttributeCertificate; import org.bouncycastle.x509.X509CRLStoreSelector; import org.bouncycastle.x509.X509CertPairStoreSelector; import org.bouncycastle.x509.X509CertStoreSelector; import org.bouncycastle.x509.X509CertificatePair; /** * This is a general purpose implementation to get X.509 certificates, CRLs, * attribute certificates and cross certificates from a LDAP location. *

    * At first a search is performed in the ldap*AttributeNames of the * {@link org.bouncycastle.jce.X509LDAPCertStoreParameters} with the given * information of the subject (for all kind of certificates) or issuer (for * CRLs), respectively, if a {@link org.bouncycastle.x509.X509CertStoreSelector} or * {@link org.bouncycastle.x509.X509AttributeCertificate} is given with that * details. *

    * For the used schemes see: *

    */ public class LDAPStoreHelper { // TODO: cache results private X509LDAPCertStoreParameters params; public LDAPStoreHelper(X509LDAPCertStoreParameters params) { this.params = params; } /** * Initial Context Factory. */ private static String LDAP_PROVIDER = "com.sun.jndi.ldap.LdapCtxFactory"; /** * Processing referrals.. */ private static String REFERRALS_IGNORE = "ignore"; /** * Security level to be used for LDAP connections. */ private static final String SEARCH_SECURITY_LEVEL = "none"; /** * Package Prefix for loading URL context factories. */ private static final String URL_CONTEXT_PREFIX = "com.sun.jndi.url"; private DirContext connectLDAP() throws NamingException { Properties props = new Properties(); props.setProperty(Context.INITIAL_CONTEXT_FACTORY, LDAP_PROVIDER); props.setProperty(Context.BATCHSIZE, "0"); props.setProperty(Context.PROVIDER_URL, params.getLdapURL()); props.setProperty(Context.URL_PKG_PREFIXES, URL_CONTEXT_PREFIX); props.setProperty(Context.REFERRAL, REFERRALS_IGNORE); props.setProperty(Context.SECURITY_AUTHENTICATION, SEARCH_SECURITY_LEVEL); DirContext ctx = new InitialDirContext(props); return ctx; } private String parseDN(String subject, String dNAttributeName) { String temp = subject; int begin = temp.toLowerCase().indexOf( dNAttributeName.toLowerCase() + "="); if (begin == -1) { return ""; } temp = temp.substring(begin + dNAttributeName.length()); int end = temp.indexOf(','); if (end == -1) { end = temp.length(); } while (temp.charAt(end - 1) == '\\') { end = temp.indexOf(',', end + 1); if (end == -1) { end = temp.length(); } } temp = temp.substring(0, end); begin = temp.indexOf('='); temp = temp.substring(begin + 1); if (temp.charAt(0) == ' ') { temp = temp.substring(1); } if (temp.startsWith("\"")) { temp = temp.substring(1); } if (temp.endsWith("\"")) { temp = temp.substring(0, temp.length() - 1); } return temp; } private Set createCerts(List list, X509CertStoreSelector xselector) throws StoreException { Set certSet = new HashSet(); Iterator it = list.iterator(); X509CertParser parser = new X509CertParser(); while (it.hasNext()) { try { parser.engineInit(new ByteArrayInputStream((byte[])it .next())); X509Certificate cert = (X509Certificate)parser .engineRead(); if (xselector.match((Object)cert)) { certSet.add(cert); } } catch (Exception e) { } } return certSet; } /** * Can use the subject and serial and the subject and serialNumber of the * certificate of the given of the X509CertStoreSelector. If a certificate * for checking is given this has higher precedence. * * @param xselector The selector with the search criteria. * @param attrs Attributes which contain the certificates in the LDAP * directory. * @param attrNames Attribute names in teh LDAP directory which correspond to the * subjectAttributeNames. * @param subjectAttributeNames Subject attribute names (like "CN", "O", "OU") to use to * search in the LDAP directory * @return A list of found DER encoded certificates. * @throws StoreException if an error occurs while searching. */ private List certSubjectSerialSearch(X509CertStoreSelector xselector, String[] attrs, String attrNames[], String subjectAttributeNames[]) throws StoreException { // TODO: support also subjectAltNames? List list = new ArrayList(); String subject = null; String serial = null; subject = getSubjectAsString(xselector); if (xselector.getSerialNumber() != null) { serial = xselector.getSerialNumber().toString(); } if (xselector.getCertificate() != null) { subject = xselector.getCertificate().getSubjectX500Principal().getName("RFC1779"); serial = xselector.getCertificate().getSerialNumber().toString(); } String attrValue = null; if (subject != null) { for (int i = 0; i < subjectAttributeNames.length; i++) { attrValue = parseDN(subject, subjectAttributeNames[i]); list .addAll(search(attrNames, "*" + attrValue + "*", attrs)); } } if (serial != null && params.getSearchForSerialNumberIn() != null) { attrValue = serial; list.addAll(search( splitString(params.getSearchForSerialNumberIn()), attrValue, attrs)); } if (serial == null && subject == null) { list.addAll(search(attrNames, "*", attrs)); } return list; } /** * Can use the subject of the forward certificate of the set certificate * pair or the subject of the forward * {@link org.bouncycastle.x509.X509CertStoreSelector} of the given * selector. * * @param xselector The selector with the search criteria. * @param attrs Attributes which contain the attribute certificates in the * LDAP directory. * @param attrNames Attribute names in the LDAP directory which correspond to the * subjectAttributeNames. * @param subjectAttributeNames Subject attribute names (like "CN", "O", "OU") to use to * search in the LDAP directory * @return A list of found DER encoded certificate pairs. * @throws StoreException if an error occurs while searching. */ private List crossCertificatePairSubjectSearch( X509CertPairStoreSelector xselector, String[] attrs, String attrNames[], String subjectAttributeNames[]) throws StoreException { List list = new ArrayList(); // search for subject String subject = null; if (xselector.getForwardSelector() != null) { subject = getSubjectAsString(xselector.getForwardSelector()); } if (xselector.getCertPair() != null) { if (xselector.getCertPair().getForward() != null) { subject = xselector.getCertPair().getForward() .getSubjectX500Principal().getName("RFC1779"); } } String attrValue = null; if (subject != null) { for (int i = 0; i < subjectAttributeNames.length; i++) { attrValue = parseDN(subject, subjectAttributeNames[i]); list .addAll(search(attrNames, "*" + attrValue + "*", attrs)); } } if (subject == null) { list.addAll(search(attrNames, "*", attrs)); } return list; } /** * Can use the entityName of the holder of the attribute certificate, the * serialNumber of attribute certificate and the serialNumber of the * associated certificate of the given of the X509AttributeCertSelector. * * @param xselector The selector with the search criteria. * @param attrs Attributes which contain the attribute certificates in the * LDAP directory. * @param attrNames Attribute names in the LDAP directory which correspond to the * subjectAttributeNames. * @param subjectAttributeNames Subject attribute names (like "CN", "O", "OU") to use to * search in the LDAP directory * @return A list of found DER encoded attribute certificates. * @throws StoreException if an error occurs while searching. */ private List attrCertSubjectSerialSearch( X509AttributeCertStoreSelector xselector, String[] attrs, String attrNames[], String subjectAttributeNames[]) throws StoreException { List list = new ArrayList(); // search for serialNumber of associated cert, // serialNumber of the attribute certificate or DN in the entityName // of the holder String subject = null; String serial = null; Collection serials = new HashSet(); Principal principals[] = null; if (xselector.getHolder() != null) { // serialNumber of associated cert if (xselector.getHolder().getSerialNumber() != null) { serials.add(xselector.getHolder().getSerialNumber() .toString()); } // DN in the entityName of the holder if (xselector.getHolder().getEntityNames() != null) { principals = xselector.getHolder().getEntityNames(); } } if (xselector.getAttributeCert() != null) { if (xselector.getAttributeCert().getHolder().getEntityNames() != null) { principals = xselector.getAttributeCert().getHolder() .getEntityNames(); } // serialNumber of the attribute certificate serials.add(xselector.getAttributeCert().getSerialNumber() .toString()); } if (principals != null) { // only first should be relevant if (principals[0] instanceof X500Principal) { subject = ((X500Principal)principals[0]) .getName("RFC1779"); } else { // strange ... subject = principals[0].getName(); } } if (xselector.getSerialNumber() != null) { serials.add(xselector.getSerialNumber().toString()); } String attrValue = null; if (subject != null) { for (int i = 0; i < subjectAttributeNames.length; i++) { attrValue = parseDN(subject, subjectAttributeNames[i]); list .addAll(search(attrNames, "*" + attrValue + "*", attrs)); } } if (serials.size() > 0 && params.getSearchForSerialNumberIn() != null) { Iterator it = serials.iterator(); while (it.hasNext()) { serial = (String)it.next(); list.addAll(search(splitString(params.getSearchForSerialNumberIn()), serial, attrs)); } } if (serials.size() == 0 && subject == null) { list.addAll(search(attrNames, "*", attrs)); } return list; } /** * Can use the issuer of the given of the X509CRLStoreSelector. * * @param xselector The selector with the search criteria. * @param attrs Attributes which contain the attribute certificates in the * LDAP directory. * @param attrNames Attribute names in the LDAP directory which correspond to the * subjectAttributeNames. * @param issuerAttributeNames Issuer attribute names (like "CN", "O", "OU") to use to search * in the LDAP directory * @return A list of found DER encoded CRLs. * @throws StoreException if an error occurs while searching. */ private List cRLIssuerSearch(X509CRLStoreSelector xselector, String[] attrs, String attrNames[], String issuerAttributeNames[]) throws StoreException { List list = new ArrayList(); String issuer = null; Collection issuers = new HashSet(); if (xselector.getIssuers() != null) { issuers.addAll(xselector.getIssuers()); } if (xselector.getCertificateChecking() != null) { issuers.add(getCertificateIssuer(xselector.getCertificateChecking())); } if (xselector.getAttrCertificateChecking() != null) { Principal principals[] = xselector.getAttrCertificateChecking().getIssuer().getPrincipals(); for (int i=0; iList
    of encodings of the certificates, attribute * certificates, CRL or certificate pairs. * * @param attributeNames The attribute names to look for in the LDAP. * @param attributeValue The value the attribute name must have. * @param attrs The attributes in the LDAP which hold the certificate, * attribute certificate, certificate pair or CRL in a found * entry. * @return A List of byte arrays with the encodings. * @throws StoreException if an error occurs getting the results from the LDAP * directory. */ private List search(String attributeNames[], String attributeValue, String[] attrs) throws StoreException { String filter = null; if (attributeNames == null) { filter = null; } else { filter = ""; if (attributeValue.equals("**")) { attributeValue = "*"; } for (int i = 0; i < attributeNames.length; i++) { filter += "(" + attributeNames[i] + "=" + attributeValue + ")"; } filter = "(|" + filter + ")"; } String filter2 = ""; for (int i = 0; i < attrs.length; i++) { filter2 += "(" + attrs[i] + "=*)"; } filter2 = "(|" + filter2 + ")"; String filter3 = "(&" + filter + "" + filter2 + ")"; if (filter == null) { filter3 = filter2; } List list; list = getFromCache(filter3); if (list != null) { return list; } DirContext ctx = null; list = new ArrayList(); try { ctx = connectLDAP(); SearchControls constraints = new SearchControls(); constraints.setSearchScope(SearchControls.SUBTREE_SCOPE); constraints.setCountLimit(0); constraints.setReturningAttributes(attrs); NamingEnumeration results = ctx.search(params.getBaseDN(), filter3, constraints); while (results.hasMoreElements()) { SearchResult sr = (SearchResult)results.next(); NamingEnumeration enumeration = ((Attribute)(sr .getAttributes().getAll().next())).getAll(); while (enumeration.hasMore()) { list.add(enumeration.next()); } } addToCache(filter3, list); } catch (NamingException e) { // skip exception, unfortunately if an attribute type is not // supported an exception is thrown } finally { try { if (null != ctx) { ctx.close(); } } catch (Exception e) { } } return list; } private Set createCRLs(List list, X509CRLStoreSelector xselector) throws StoreException { Set crlSet = new HashSet(); X509CRLParser parser = new X509CRLParser(); Iterator it = list.iterator(); while (it.hasNext()) { try { parser.engineInit(new ByteArrayInputStream((byte[])it .next())); X509CRL crl = (X509CRL)parser.engineRead(); if (xselector.match((Object)crl)) { crlSet.add(crl); } } catch (StreamParsingException e) { } } return crlSet; } private Set createCrossCertificatePairs(List list, X509CertPairStoreSelector xselector) throws StoreException { Set certPairSet = new HashSet(); int i = 0; while (i < list.size()) { X509CertificatePair pair; try { // first try to decode it as certificate pair try { X509CertPairParser parser = new X509CertPairParser(); parser.engineInit(new ByteArrayInputStream( (byte[])list.get(i))); pair = (X509CertificatePair)parser.engineRead(); } catch (StreamParsingException e) { // now try it to construct it the forward and reverse // certificate byte[] forward = (byte[])list.get(i); byte[] reverse = (byte[])list.get(i + 1); pair = new X509CertificatePair(new CertificatePair( Certificate .getInstance(new ASN1InputStream( forward).readObject()), Certificate .getInstance(new ASN1InputStream( reverse).readObject()))); i++; } if (xselector.match((Object)pair)) { certPairSet.add(pair); } } catch (CertificateParsingException e) { // try next } catch (IOException e) { // try next } i++; } return certPairSet; } private Set createAttributeCertificates(List list, X509AttributeCertStoreSelector xselector) throws StoreException { Set certSet = new HashSet(); Iterator it = list.iterator(); X509AttrCertParser parser = new X509AttrCertParser(); while (it.hasNext()) { try { parser.engineInit(new ByteArrayInputStream((byte[])it .next())); X509AttributeCertificate cert = (X509AttributeCertificate)parser .engineRead(); if (xselector.match((Object)cert)) { certSet.add(cert); } } catch (StreamParsingException e) { } } return certSet; } /** * Returns the CRLs for issued certificates for other CAs matching the given * selector.
    * The authorityRevocationList attribute includes revocation information * regarding certificates issued to other CAs. * * @param selector The CRL selector to use to find the CRLs. * @return A possible empty collection with CRLs * @throws StoreException */ public Collection getAuthorityRevocationLists(X509CRLStoreSelector selector) throws StoreException { String[] attrs = splitString(params.getAuthorityRevocationListAttribute()); String attrNames[] = splitString(params .getLdapAuthorityRevocationListAttributeName()); String issuerAttributeNames[] = splitString(params .getAuthorityRevocationListIssuerAttributeName()); List list = cRLIssuerSearch(selector, attrs, attrNames, issuerAttributeNames); Set resultSet = createCRLs(list, selector); if (resultSet.size() == 0) { X509CRLStoreSelector emptySelector = new X509CRLStoreSelector(); list = cRLIssuerSearch(emptySelector, attrs, attrNames, issuerAttributeNames); resultSet.addAll(createCRLs(list, selector)); } return resultSet; } /** * Returns the revocation list for revoked attribute certificates. *

    * The attributeCertificateRevocationList holds a list of attribute * certificates that have been revoked. * * @param selector The CRL selector to use to find the CRLs. * @return A possible empty collection with CRLs. * @throws StoreException */ public Collection getAttributeCertificateRevocationLists( X509CRLStoreSelector selector) throws StoreException { String[] attrs = splitString(params .getAttributeCertificateRevocationListAttribute()); String attrNames[] = splitString(params .getLdapAttributeCertificateRevocationListAttributeName()); String issuerAttributeNames[] = splitString(params .getAttributeCertificateRevocationListIssuerAttributeName()); List list = cRLIssuerSearch(selector, attrs, attrNames, issuerAttributeNames); Set resultSet = createCRLs(list, selector); if (resultSet.size() == 0) { X509CRLStoreSelector emptySelector = new X509CRLStoreSelector(); list = cRLIssuerSearch(emptySelector, attrs, attrNames, issuerAttributeNames); resultSet.addAll(createCRLs(list, selector)); } return resultSet; } /** * Returns the revocation list for revoked attribute certificates for an * attribute authority *

    * The attributeAuthorityList holds a list of AA certificates that have been * revoked. * * @param selector The CRL selector to use to find the CRLs. * @return A possible empty collection with CRLs * @throws StoreException */ public Collection getAttributeAuthorityRevocationLists( X509CRLStoreSelector selector) throws StoreException { String[] attrs = splitString(params.getAttributeAuthorityRevocationListAttribute()); String attrNames[] = splitString(params .getLdapAttributeAuthorityRevocationListAttributeName()); String issuerAttributeNames[] = splitString(params .getAttributeAuthorityRevocationListIssuerAttributeName()); List list = cRLIssuerSearch(selector, attrs, attrNames, issuerAttributeNames); Set resultSet = createCRLs(list, selector); if (resultSet.size() == 0) { X509CRLStoreSelector emptySelector = new X509CRLStoreSelector(); list = cRLIssuerSearch(emptySelector, attrs, attrNames, issuerAttributeNames); resultSet.addAll(createCRLs(list, selector)); } return resultSet; } /** * Returns cross certificate pairs. * * @param selector The selector to use to find the cross certificates. * @return A possible empty collection with {@link X509CertificatePair}s * @throws StoreException */ public Collection getCrossCertificatePairs( X509CertPairStoreSelector selector) throws StoreException { String[] attrs = splitString(params.getCrossCertificateAttribute()); String attrNames[] = splitString(params.getLdapCrossCertificateAttributeName()); String subjectAttributeNames[] = splitString(params .getCrossCertificateSubjectAttributeName()); List list = crossCertificatePairSubjectSearch(selector, attrs, attrNames, subjectAttributeNames); Set resultSet = createCrossCertificatePairs(list, selector); if (resultSet.size() == 0) { X509CertStoreSelector emptyCertselector = new X509CertStoreSelector(); X509CertPairStoreSelector emptySelector = new X509CertPairStoreSelector(); emptySelector.setForwardSelector(emptyCertselector); emptySelector.setReverseSelector(emptyCertselector); list = crossCertificatePairSubjectSearch(emptySelector, attrs, attrNames, subjectAttributeNames); resultSet.addAll(createCrossCertificatePairs(list, selector)); } return resultSet; } /** * Returns end certificates. *

    * The attributeDescriptorCertificate is self signed by a source of * authority and holds a description of the privilege and its delegation * rules. * * @param selector The selector to find the certificates. * @return A possible empty collection with certificates. * @throws StoreException */ public Collection getUserCertificates(X509CertStoreSelector selector) throws StoreException { String[] attrs = splitString(params.getUserCertificateAttribute()); String attrNames[] = splitString(params.getLdapUserCertificateAttributeName()); String subjectAttributeNames[] = splitString(params .getUserCertificateSubjectAttributeName()); List list = certSubjectSerialSearch(selector, attrs, attrNames, subjectAttributeNames); Set resultSet = createCerts(list, selector); if (resultSet.size() == 0) { X509CertStoreSelector emptySelector = new X509CertStoreSelector(); list = certSubjectSerialSearch(emptySelector, attrs, attrNames, subjectAttributeNames); resultSet.addAll(createCerts(list, selector)); } return resultSet; } /** * Returns attribute certificates for an attribute authority *

    * The aAcertificate holds the privileges of an attribute authority. * * @param selector The selector to find the attribute certificates. * @return A possible empty collection with attribute certificates. * @throws StoreException */ public Collection getAACertificates(X509AttributeCertStoreSelector selector) throws StoreException { String[] attrs = splitString(params.getAACertificateAttribute()); String attrNames[] = splitString(params.getLdapAACertificateAttributeName()); String subjectAttributeNames[] = splitString(params.getAACertificateSubjectAttributeName()); List list = attrCertSubjectSerialSearch(selector, attrs, attrNames, subjectAttributeNames); Set resultSet = createAttributeCertificates(list, selector); if (resultSet.size() == 0) { X509AttributeCertStoreSelector emptySelector = new X509AttributeCertStoreSelector(); list = attrCertSubjectSerialSearch(emptySelector, attrs, attrNames, subjectAttributeNames); resultSet.addAll(createAttributeCertificates(list, selector)); } return resultSet; } /** * Returns an attribute certificate for an authority *

    * The attributeDescriptorCertificate is self signed by a source of * authority and holds a description of the privilege and its delegation * rules. * * @param selector The selector to find the attribute certificates. * @return A possible empty collection with attribute certificates. * @throws StoreException */ public Collection getAttributeDescriptorCertificates( X509AttributeCertStoreSelector selector) throws StoreException { String[] attrs = splitString(params.getAttributeDescriptorCertificateAttribute()); String attrNames[] = splitString(params .getLdapAttributeDescriptorCertificateAttributeName()); String subjectAttributeNames[] = splitString(params .getAttributeDescriptorCertificateSubjectAttributeName()); List list = attrCertSubjectSerialSearch(selector, attrs, attrNames, subjectAttributeNames); Set resultSet = createAttributeCertificates(list, selector); if (resultSet.size() == 0) { X509AttributeCertStoreSelector emptySelector = new X509AttributeCertStoreSelector(); list = attrCertSubjectSerialSearch(emptySelector, attrs, attrNames, subjectAttributeNames); resultSet.addAll(createAttributeCertificates(list, selector)); } return resultSet; } /** * Returns CA certificates. *

    * The cACertificate attribute of a CA's directory entry shall be used to * store self-issued certificates (if any) and certificates issued to this * CA by CAs in the same realm as this CA. * * @param selector The selector to find the certificates. * @return A possible empty collection with certificates. * @throws StoreException */ public Collection getCACertificates(X509CertStoreSelector selector) throws StoreException { String[] attrs = splitString(params.getCACertificateAttribute()); String attrNames[] = splitString(params.getLdapCACertificateAttributeName()); String subjectAttributeNames[] = splitString(params .getCACertificateSubjectAttributeName()); List list = certSubjectSerialSearch(selector, attrs, attrNames, subjectAttributeNames); Set resultSet = createCerts(list, selector); if (resultSet.size() == 0) { X509CertStoreSelector emptySelector = new X509CertStoreSelector(); list = certSubjectSerialSearch(emptySelector, attrs, attrNames, subjectAttributeNames); resultSet.addAll(createCerts(list, selector)); } return resultSet; } /** * Returns the delta revocation list for revoked certificates. * * @param selector The CRL selector to use to find the CRLs. * @return A possible empty collection with CRLs. * @throws StoreException */ public Collection getDeltaCertificateRevocationLists( X509CRLStoreSelector selector) throws StoreException { String[] attrs = splitString(params.getDeltaRevocationListAttribute()); String attrNames[] = splitString(params.getLdapDeltaRevocationListAttributeName()); String issuerAttributeNames[] = splitString(params .getDeltaRevocationListIssuerAttributeName()); List list = cRLIssuerSearch(selector, attrs, attrNames, issuerAttributeNames); Set resultSet = createCRLs(list, selector); if (resultSet.size() == 0) { X509CRLStoreSelector emptySelector = new X509CRLStoreSelector(); list = cRLIssuerSearch(emptySelector, attrs, attrNames, issuerAttributeNames); resultSet.addAll(createCRLs(list, selector)); } return resultSet; } /** * Returns an attribute certificate for an user. *

    * The attributeCertificateAttribute holds the privileges of a user * * @param selector The selector to find the attribute certificates. * @return A possible empty collection with attribute certificates. * @throws StoreException */ public Collection getAttributeCertificateAttributes( X509AttributeCertStoreSelector selector) throws StoreException { String[] attrs = splitString(params.getAttributeCertificateAttributeAttribute()); String attrNames[] = splitString(params .getLdapAttributeCertificateAttributeAttributeName()); String subjectAttributeNames[] = splitString(params .getAttributeCertificateAttributeSubjectAttributeName()); List list = attrCertSubjectSerialSearch(selector, attrs, attrNames, subjectAttributeNames); Set resultSet = createAttributeCertificates(list, selector); if (resultSet.size() == 0) { X509AttributeCertStoreSelector emptySelector = new X509AttributeCertStoreSelector(); list = attrCertSubjectSerialSearch(emptySelector, attrs, attrNames, subjectAttributeNames); resultSet.addAll(createAttributeCertificates(list, selector)); } return resultSet; } /** * Returns the certificate revocation lists for revoked certificates. * * @param selector The CRL selector to use to find the CRLs. * @return A possible empty collection with CRLs. * @throws StoreException */ public Collection getCertificateRevocationLists( X509CRLStoreSelector selector) throws StoreException { String[] attrs = splitString(params.getCertificateRevocationListAttribute()); String attrNames[] = splitString(params .getLdapCertificateRevocationListAttributeName()); String issuerAttributeNames[] = splitString(params .getCertificateRevocationListIssuerAttributeName()); List list = cRLIssuerSearch(selector, attrs, attrNames, issuerAttributeNames); Set resultSet = createCRLs(list, selector); if (resultSet.size() == 0) { X509CRLStoreSelector emptySelector = new X509CRLStoreSelector(); list = cRLIssuerSearch(emptySelector, attrs, attrNames, issuerAttributeNames); resultSet.addAll(createCRLs(list, selector)); } return resultSet; } private Map cacheMap = new HashMap(cacheSize); private static int cacheSize = 32; private static long lifeTime = 60 * 1000; private synchronized void addToCache(String searchCriteria, List list) { Date now = new Date(System.currentTimeMillis()); List cacheEntry = new ArrayList(); cacheEntry.add(now); cacheEntry.add(list); if (cacheMap.containsKey(searchCriteria)) { cacheMap.put(searchCriteria, cacheEntry); } else { if (cacheMap.size() >= cacheSize) { // replace oldest Iterator it = cacheMap.entrySet().iterator(); long oldest = now.getTime(); Object replace = null; while (it.hasNext()) { Map.Entry entry = (Map.Entry)it.next(); long current = ((Date)((List)entry.getValue()).get(0)) .getTime(); if (current < oldest) { oldest = current; replace = entry.getKey(); } } cacheMap.remove(replace); } cacheMap.put(searchCriteria, cacheEntry); } } private List getFromCache(String searchCriteria) { List entry = (List)cacheMap.get(searchCriteria); long now = System.currentTimeMillis(); if (entry != null) { // too old if (((Date)entry.get(0)).getTime() < (now - lifeTime)) { return null; } return (List)entry.get(1); } return null; } /* * spilt string based on spaces */ private String[] splitString(String str) { return str.split("\\s+"); } private String getSubjectAsString(X509CertStoreSelector xselector) { try { byte[] encSubject = xselector.getSubjectAsBytes(); if (encSubject != null) { return new X500Principal(encSubject).getName("RFC1779"); } } catch (IOException e) { throw new StoreException("exception processing name: " + e.getMessage(), e); } return null; } private X500Principal getCertificateIssuer(X509Certificate cert) { return cert.getIssuerX500Principal(); } } bouncycastle-1.49.orig/src/org/bouncycastle/x509/X509StoreSpi.java0000644000175000017500000000042710522776714024226 0ustar ebourgebourgpackage org.bouncycastle.x509; import org.bouncycastle.util.Selector; import java.util.Collection; public abstract class X509StoreSpi { public abstract void engineInit(X509StoreParameters parameters); public abstract Collection engineGetMatches(Selector selector); } bouncycastle-1.49.orig/src/org/bouncycastle/x509/AttributeCertificateHolder.java0000644000175000017500000003035411726003011027312 0ustar ebourgebourgpackage org.bouncycastle.x509; import java.io.IOException; import java.math.BigInteger; import java.security.MessageDigest; import java.security.Principal; import java.security.cert.CertSelector; import java.security.cert.Certificate; import java.security.cert.CertificateEncodingException; import java.security.cert.CertificateParsingException; import java.security.cert.X509Certificate; import java.util.ArrayList; import java.util.List; import javax.security.auth.x500.X500Principal; import org.bouncycastle.asn1.ASN1Encodable; import org.bouncycastle.asn1.ASN1Integer; import org.bouncycastle.asn1.ASN1ObjectIdentifier; import org.bouncycastle.asn1.ASN1Sequence; import org.bouncycastle.asn1.DERSequence; import org.bouncycastle.asn1.x509.AlgorithmIdentifier; import org.bouncycastle.asn1.x509.GeneralName; import org.bouncycastle.asn1.x509.GeneralNames; import org.bouncycastle.asn1.x509.Holder; import org.bouncycastle.asn1.x509.IssuerSerial; import org.bouncycastle.asn1.x509.ObjectDigestInfo; import org.bouncycastle.jce.PrincipalUtil; import org.bouncycastle.jce.X509Principal; import org.bouncycastle.util.Arrays; import org.bouncycastle.util.Selector; /** * The Holder object. * *

     *          Holder ::= SEQUENCE {
     *                baseCertificateID   [0] IssuerSerial OPTIONAL,
     *                         -- the issuer and serial number of
     *                         -- the holder's Public Key Certificate
     *                entityName          [1] GeneralNames OPTIONAL,
     *                         -- the name of the claimant or role
     *                objectDigestInfo    [2] ObjectDigestInfo OPTIONAL
     *                         -- used to directly authenticate the holder,
     *                         -- for example, an executable
     *          }
     * 
    * @deprecated use org.bouncycastle.cert.AttributeCertificateHolder */ public class AttributeCertificateHolder implements CertSelector, Selector { final Holder holder; AttributeCertificateHolder(ASN1Sequence seq) { holder = Holder.getInstance(seq); } public AttributeCertificateHolder(X509Principal issuerName, BigInteger serialNumber) { holder = new org.bouncycastle.asn1.x509.Holder(new IssuerSerial( GeneralNames.getInstance(new DERSequence(new GeneralName(issuerName))), new ASN1Integer(serialNumber))); } public AttributeCertificateHolder(X500Principal issuerName, BigInteger serialNumber) { this(X509Util.convertPrincipal(issuerName), serialNumber); } public AttributeCertificateHolder(X509Certificate cert) throws CertificateParsingException { X509Principal name; try { name = PrincipalUtil.getIssuerX509Principal(cert); } catch (Exception e) { throw new CertificateParsingException(e.getMessage()); } holder = new Holder(new IssuerSerial(generateGeneralNames(name), new ASN1Integer(cert.getSerialNumber()))); } public AttributeCertificateHolder(X509Principal principal) { holder = new Holder(generateGeneralNames(principal)); } public AttributeCertificateHolder(X500Principal principal) { this(X509Util.convertPrincipal(principal)); } /** * Constructs a holder for v2 attribute certificates with a hash value for * some type of object. *

    * digestedObjectType can be one of the following: *

      *
    • 0 - publicKey - A hash of the public key of the holder must be * passed. *
    • 1 - publicKeyCert - A hash of the public key certificate of the * holder must be passed. *
    • 2 - otherObjectDigest - A hash of some other object type must be * passed. otherObjectTypeID must not be empty. *
    *

    * This cannot be used if a v1 attribute certificate is used. * * @param digestedObjectType The digest object type. * @param digestAlgorithm The algorithm identifier for the hash. * @param otherObjectTypeID The object type ID if * digestedObjectType is * otherObjectDigest. * @param objectDigest The hash value. */ public AttributeCertificateHolder(int digestedObjectType, String digestAlgorithm, String otherObjectTypeID, byte[] objectDigest) { holder = new Holder(new ObjectDigestInfo(digestedObjectType, new ASN1ObjectIdentifier(otherObjectTypeID), new AlgorithmIdentifier(digestAlgorithm), Arrays .clone(objectDigest))); } /** * Returns the digest object type if an object digest info is used. *

    *

      *
    • 0 - publicKey - A hash of the public key of the holder must be * passed. *
    • 1 - publicKeyCert - A hash of the public key certificate of the * holder must be passed. *
    • 2 - otherObjectDigest - A hash of some other object type must be * passed. otherObjectTypeID must not be empty. *
    * * @return The digest object type or -1 if no object digest info is set. */ public int getDigestedObjectType() { if (holder.getObjectDigestInfo() != null) { return holder.getObjectDigestInfo().getDigestedObjectType() .getValue().intValue(); } return -1; } /** * Returns the other object type ID if an object digest info is used. * * @return The other object type ID or null if no object * digest info is set. */ public String getDigestAlgorithm() { if (holder.getObjectDigestInfo() != null) { return holder.getObjectDigestInfo().getDigestAlgorithm().getObjectId() .getId(); } return null; } /** * Returns the hash if an object digest info is used. * * @return The hash or null if no object digest info is set. */ public byte[] getObjectDigest() { if (holder.getObjectDigestInfo() != null) { return holder.getObjectDigestInfo().getObjectDigest().getBytes(); } return null; } /** * Returns the digest algorithm ID if an object digest info is used. * * @return The digest algorithm ID or null if no object * digest info is set. */ public String getOtherObjectTypeID() { if (holder.getObjectDigestInfo() != null) { holder.getObjectDigestInfo().getOtherObjectTypeID().getId(); } return null; } private GeneralNames generateGeneralNames(X509Principal principal) { return GeneralNames.getInstance(new DERSequence(new GeneralName(principal))); } private boolean matchesDN(X509Principal subject, GeneralNames targets) { GeneralName[] names = targets.getNames(); for (int i = 0; i != names.length; i++) { GeneralName gn = names[i]; if (gn.getTagNo() == GeneralName.directoryName) { try { if (new X509Principal(((ASN1Encodable)gn.getName()).toASN1Primitive() .getEncoded()).equals(subject)) { return true; } } catch (IOException e) { } } } return false; } private Object[] getNames(GeneralName[] names) { List l = new ArrayList(names.length); for (int i = 0; i != names.length; i++) { if (names[i].getTagNo() == GeneralName.directoryName) { try { l.add(new X500Principal( ((ASN1Encodable)names[i].getName()).toASN1Primitive().getEncoded())); } catch (IOException e) { throw new RuntimeException("badly formed Name object"); } } } return l.toArray(new Object[l.size()]); } private Principal[] getPrincipals(GeneralNames names) { Object[] p = this.getNames(names.getNames()); List l = new ArrayList(); for (int i = 0; i != p.length; i++) { if (p[i] instanceof Principal) { l.add(p[i]); } } return (Principal[])l.toArray(new Principal[l.size()]); } /** * Return any principal objects inside the attribute certificate holder * entity names field. * * @return an array of Principal objects (usually X500Principal), null if no * entity names field is set. */ public Principal[] getEntityNames() { if (holder.getEntityName() != null) { return getPrincipals(holder.getEntityName()); } return null; } /** * Return the principals associated with the issuer attached to this holder * * @return an array of principals, null if no BaseCertificateID is set. */ public Principal[] getIssuer() { if (holder.getBaseCertificateID() != null) { return getPrincipals(holder.getBaseCertificateID().getIssuer()); } return null; } /** * Return the serial number associated with the issuer attached to this * holder. * * @return the certificate serial number, null if no BaseCertificateID is * set. */ public BigInteger getSerialNumber() { if (holder.getBaseCertificateID() != null) { return holder.getBaseCertificateID().getSerial().getValue(); } return null; } public Object clone() { return new AttributeCertificateHolder((ASN1Sequence)holder .toASN1Object()); } public boolean match(Certificate cert) { if (!(cert instanceof X509Certificate)) { return false; } X509Certificate x509Cert = (X509Certificate)cert; try { if (holder.getBaseCertificateID() != null) { return holder.getBaseCertificateID().getSerial().getValue().equals(x509Cert.getSerialNumber()) && matchesDN(PrincipalUtil.getIssuerX509Principal(x509Cert), holder.getBaseCertificateID().getIssuer()); } if (holder.getEntityName() != null) { if (matchesDN(PrincipalUtil.getSubjectX509Principal(x509Cert), holder.getEntityName())) { return true; } } if (holder.getObjectDigestInfo() != null) { MessageDigest md = null; try { md = MessageDigest.getInstance(getDigestAlgorithm(), "BC"); } catch (Exception e) { return false; } switch (getDigestedObjectType()) { case ObjectDigestInfo.publicKey: // TODO: DSA Dss-parms md.update(cert.getPublicKey().getEncoded()); break; case ObjectDigestInfo.publicKeyCert: md.update(cert.getEncoded()); break; } if (!Arrays.areEqual(md.digest(), getObjectDigest())) { return false; } } } catch (CertificateEncodingException e) { return false; } return false; } public boolean equals(Object obj) { if (obj == this) { return true; } if (!(obj instanceof AttributeCertificateHolder)) { return false; } AttributeCertificateHolder other = (AttributeCertificateHolder)obj; return this.holder.equals(other.holder); } public int hashCode() { return this.holder.hashCode(); } public boolean match(Object obj) { if (!(obj instanceof X509Certificate)) { return false; } return match((Certificate)obj); } } bouncycastle-1.49.orig/src/org/bouncycastle/x509/X509CertificatePair.java0000644000175000017500000001073011737206705025507 0ustar ebourgebourgpackage org.bouncycastle.x509; import java.io.IOException; import java.security.cert.CertificateEncodingException; import java.security.cert.CertificateParsingException; import java.security.cert.X509Certificate; import org.bouncycastle.asn1.ASN1Encoding; import org.bouncycastle.asn1.ASN1InputStream; import org.bouncycastle.asn1.x509.Certificate; import org.bouncycastle.asn1.x509.CertificatePair; import org.bouncycastle.jce.provider.X509CertificateObject; /** * This class contains a cross certificate pair. Cross certificates pairs may * contain two cross signed certificates from two CAs. A certificate from the * other CA to this CA is contained in the forward certificate, the certificate * from this CA to the other CA is contained in the reverse certificate. */ public class X509CertificatePair { private X509Certificate forward; private X509Certificate reverse; /** * Constructor. * * @param forward Certificate from the other CA to this CA. * @param reverse Certificate from this CA to the other CA. */ public X509CertificatePair( X509Certificate forward, X509Certificate reverse) { this.forward = forward; this.reverse = reverse; } /** * Constructor from a ASN.1 CertificatePair structure. * * @param pair The CertificatePair ASN.1 object. */ public X509CertificatePair( CertificatePair pair) throws CertificateParsingException { if (pair.getForward() != null) { this.forward = new X509CertificateObject(pair.getForward()); } if (pair.getReverse() != null) { this.reverse = new X509CertificateObject(pair.getReverse()); } } public byte[] getEncoded() throws CertificateEncodingException { Certificate f = null; Certificate r = null; try { if (forward != null) { f = Certificate.getInstance(new ASN1InputStream( forward.getEncoded()).readObject()); if (f == null) { throw new CertificateEncodingException("unable to get encoding for forward"); } } if (reverse != null) { r = Certificate.getInstance(new ASN1InputStream( reverse.getEncoded()).readObject()); if (r == null) { throw new CertificateEncodingException("unable to get encoding for reverse"); } } return new CertificatePair(f, r).getEncoded(ASN1Encoding.DER); } catch (IllegalArgumentException e) { throw new ExtCertificateEncodingException(e.toString(), e); } catch (IOException e) { throw new ExtCertificateEncodingException(e.toString(), e); } } /** * Returns the certificate from the other CA to this CA. * * @return Returns the forward certificate. */ public X509Certificate getForward() { return forward; } /** * Return the certificate from this CA to the other CA. * * @return Returns the reverse certificate. */ public X509Certificate getReverse() { return reverse; } public boolean equals(Object o) { if (o == null) { return false; } if (!(o instanceof X509CertificatePair)) { return false; } X509CertificatePair pair = (X509CertificatePair)o; boolean equalReverse = true; boolean equalForward = true; if (forward != null) { equalForward = this.forward.equals(pair.forward); } else { if (pair.forward != null) { equalForward = false; } } if (reverse != null) { equalReverse = this.reverse.equals(pair.reverse); } else { if (pair.reverse != null) { equalReverse = false; } } return equalForward && equalReverse; } public int hashCode() { int hash = -1; if (forward != null) { hash ^= forward.hashCode(); } if (reverse != null) { hash *= 17; hash ^= reverse.hashCode(); } return hash; } } bouncycastle-1.49.orig/src/org/bouncycastle/x509/PKIXCertPathReviewer.java0000644000175000017500000027765112103441027026005 0ustar ebourgebourgpackage org.bouncycastle.x509; import java.io.ByteArrayInputStream; import java.io.IOException; import java.math.BigInteger; import java.net.HttpURLConnection; import java.net.InetAddress; import java.net.URL; import java.security.GeneralSecurityException; import java.security.PublicKey; import java.security.SignatureException; import java.security.cert.CertPath; import java.security.cert.CertPathValidatorException; import java.security.cert.CertificateExpiredException; import java.security.cert.CertificateFactory; import java.security.cert.CertificateNotYetValidException; import java.security.cert.PKIXCertPathChecker; import java.security.cert.PKIXParameters; import java.security.cert.PolicyNode; import java.security.cert.TrustAnchor; import java.security.cert.X509CRL; import java.security.cert.X509CRLEntry; import java.security.cert.X509CertSelector; import java.security.cert.X509Certificate; import java.util.ArrayList; import java.util.Collection; import java.util.Date; import java.util.Enumeration; import java.util.HashMap; import java.util.HashSet; import java.util.Iterator; import java.util.List; import java.util.Map; import java.util.Set; import java.util.Vector; import javax.security.auth.x500.X500Principal; import org.bouncycastle.asn1.ASN1Encodable; import org.bouncycastle.asn1.ASN1InputStream; import org.bouncycastle.asn1.ASN1OctetString; import org.bouncycastle.asn1.ASN1Primitive; import org.bouncycastle.asn1.ASN1Sequence; import org.bouncycastle.asn1.ASN1TaggedObject; import org.bouncycastle.asn1.DEREnumerated; import org.bouncycastle.asn1.DERIA5String; import org.bouncycastle.asn1.DERInteger; import org.bouncycastle.asn1.DERObjectIdentifier; import org.bouncycastle.asn1.DEROctetString; import org.bouncycastle.asn1.x509.AccessDescription; import org.bouncycastle.asn1.x509.AlgorithmIdentifier; import org.bouncycastle.asn1.x509.AuthorityInformationAccess; import org.bouncycastle.asn1.x509.AuthorityKeyIdentifier; import org.bouncycastle.asn1.x509.BasicConstraints; import org.bouncycastle.asn1.x509.CRLDistPoint; import org.bouncycastle.asn1.x509.DistributionPoint; import org.bouncycastle.asn1.x509.DistributionPointName; import org.bouncycastle.asn1.x509.GeneralName; import org.bouncycastle.asn1.x509.GeneralNames; import org.bouncycastle.asn1.x509.GeneralSubtree; import org.bouncycastle.asn1.x509.IssuingDistributionPoint; import org.bouncycastle.asn1.x509.NameConstraints; import org.bouncycastle.asn1.x509.PolicyInformation; import org.bouncycastle.asn1.x509.X509Extensions; import org.bouncycastle.asn1.x509.qualified.Iso4217CurrencyCode; import org.bouncycastle.asn1.x509.qualified.MonetaryValue; import org.bouncycastle.asn1.x509.qualified.QCStatement; import org.bouncycastle.i18n.ErrorBundle; import org.bouncycastle.i18n.LocaleString; import org.bouncycastle.i18n.filter.TrustedInput; import org.bouncycastle.i18n.filter.UntrustedInput; import org.bouncycastle.i18n.filter.UntrustedUrlInput; import org.bouncycastle.jce.provider.AnnotatedException; import org.bouncycastle.jce.provider.CertPathValidatorUtilities; import org.bouncycastle.jce.provider.PKIXNameConstraintValidator; import org.bouncycastle.jce.provider.PKIXNameConstraintValidatorException; import org.bouncycastle.jce.provider.PKIXPolicyNode; import org.bouncycastle.util.Integers; import org.bouncycastle.x509.extension.X509ExtensionUtil; /** * PKIXCertPathReviewer
    * Validation of X.509 Certificate Paths. Tries to find as much errors in the Path as possible. */ public class PKIXCertPathReviewer extends CertPathValidatorUtilities { private static final String QC_STATEMENT = X509Extensions.QCStatements.getId(); private static final String CRL_DIST_POINTS = X509Extensions.CRLDistributionPoints.getId(); private static final String AUTH_INFO_ACCESS = X509Extensions.AuthorityInfoAccess.getId(); private static final String RESOURCE_NAME = "org.bouncycastle.x509.CertPathReviewerMessages"; // input parameters protected CertPath certPath; protected PKIXParameters pkixParams; protected Date validDate; // state variables protected List certs; protected int n; // output variables protected List[] notifications; protected List[] errors; protected TrustAnchor trustAnchor; protected PublicKey subjectPublicKey; protected PolicyNode policyTree; private boolean initialized; /** * Initializes the PKIXCertPathReviewer with the given {@link CertPath} and {@link PKIXParameters} params * @param certPath the {@link CertPath} to validate * @param params the {@link PKIXParameters} to use * @throws CertPathReviewerException if the certPath is empty * @throws IllegalStateException if the {@link PKIXCertPathReviewer} is already initialized */ public void init(CertPath certPath, PKIXParameters params) throws CertPathReviewerException { if (initialized) { throw new IllegalStateException("object is already initialized!"); } initialized = true; // check input parameters if (certPath == null) { throw new NullPointerException("certPath was null"); } this.certPath = certPath; certs = certPath.getCertificates(); n = certs.size(); if (certs.isEmpty()) { throw new CertPathReviewerException( new ErrorBundle(RESOURCE_NAME,"CertPathReviewer.emptyCertPath")); } pkixParams = (PKIXParameters) params.clone(); // 6.1.1 - Inputs // a) done // b) validDate = getValidDate(pkixParams); // c) part of pkixParams // d) done at the beginning of checkSignatures // e) f) g) part of pkixParams // initialize output parameters notifications = null; errors = null; trustAnchor = null; subjectPublicKey = null; policyTree = null; } /** * Creates a PKIXCertPathReviewer and initializes it with the given {@link CertPath} and {@link PKIXParameters} params * @param certPath the {@link CertPath} to validate * @param params the {@link PKIXParameters} to use * @throws CertPathReviewerException if the certPath is empty */ public PKIXCertPathReviewer(CertPath certPath, PKIXParameters params) throws CertPathReviewerException { init(certPath, params); } /** * Creates an empty PKIXCertPathReviewer. Don't forget to call init() to initialize the object. */ public PKIXCertPathReviewer() { // do nothing } /** * * @return the CertPath that was validated */ public CertPath getCertPath() { return certPath; } /** * * @return the size of the CertPath */ public int getCertPathSize() { return n; } /** * Returns an Array of Lists which contains a List of global error messages * and a List of error messages for each certificate in the path. * The global error List is at index 0. The error lists for each certificate at index 1 to n. * The error messages are of type. * @return the Array of Lists which contain the error messages * @throws IllegalStateException if the {@link PKIXCertPathReviewer} was not initialized */ public List[] getErrors() { doChecks(); return errors; } /** * Returns an List of error messages for the certificate at the given index in the CertPath. * If index == -1 then the list of global errors is returned with errors not specific to a certificate. * @param index the index of the certificate in the CertPath * @return List of error messages for the certificate * @throws IllegalStateException if the {@link PKIXCertPathReviewer} was not initialized */ public List getErrors(int index) { doChecks(); return errors[index + 1]; } /** * Returns an Array of Lists which contains a List of global notification messages * and a List of botification messages for each certificate in the path. * The global notificatio List is at index 0. The notification lists for each certificate at index 1 to n. * The error messages are of type. * @return the Array of Lists which contain the notification messages * @throws IllegalStateException if the {@link PKIXCertPathReviewer} was not initialized */ public List[] getNotifications() { doChecks(); return notifications; } /** * Returns an List of notification messages for the certificate at the given index in the CertPath. * If index == -1 then the list of global notifications is returned with notifications not specific to a certificate. * @param index the index of the certificate in the CertPath * @return List of notification messages for the certificate * @throws IllegalStateException if the {@link PKIXCertPathReviewer} was not initialized */ public List getNotifications(int index) { doChecks(); return notifications[index + 1]; } /** * * @return the valid policy tree, null if no valid policy exists. * @throws IllegalStateException if the {@link PKIXCertPathReviewer} was not initialized */ public PolicyNode getPolicyTree() { doChecks(); return policyTree; } /** * * @return the PublicKey if the last certificate in the CertPath * @throws IllegalStateException if the {@link PKIXCertPathReviewer} was not initialized */ public PublicKey getSubjectPublicKey() { doChecks(); return subjectPublicKey; } /** * * @return the TrustAnchor for the CertPath, null if no valid TrustAnchor was found. * @throws IllegalStateException if the {@link PKIXCertPathReviewer} was not initialized */ public TrustAnchor getTrustAnchor() { doChecks(); return trustAnchor; } /** * * @return if the CertPath is valid * @throws IllegalStateException if the {@link PKIXCertPathReviewer} was not initialized */ public boolean isValidCertPath() { doChecks(); boolean valid = true; for (int i = 0; i < errors.length; i++) { if (!errors[i].isEmpty()) { valid = false; break; } } return valid; } protected void addNotification(ErrorBundle msg) { notifications[0].add(msg); } protected void addNotification(ErrorBundle msg, int index) { if (index < -1 || index >= n) { throw new IndexOutOfBoundsException(); } notifications[index + 1].add(msg); } protected void addError(ErrorBundle msg) { errors[0].add(msg); } protected void addError(ErrorBundle msg, int index) { if (index < -1 || index >= n) { throw new IndexOutOfBoundsException(); } errors[index + 1].add(msg); } protected void doChecks() { if (!initialized) { throw new IllegalStateException("Object not initialized. Call init() first."); } if (notifications == null) { // initialize lists notifications = new List[n+1]; errors = new List[n+1]; for (int i = 0; i < notifications.length; i++) { notifications[i] = new ArrayList(); errors[i] = new ArrayList(); } // check Signatures checkSignatures(); // check Name Constraints checkNameConstraints(); // check Path Length checkPathLength(); // check Policy checkPolicy(); // check other critical extensions checkCriticalExtensions(); } } private void checkNameConstraints() { X509Certificate cert = null; // // Setup // // (b) and (c) PKIXNameConstraintValidator nameConstraintValidator = new PKIXNameConstraintValidator(); // // process each certificate except the last in the path // int index; int i; try { for (index = certs.size()-1; index>0; index--) { i = n - index; // // certificate processing // cert = (X509Certificate) certs.get(index); // b),c) if (!isSelfIssued(cert)) { X500Principal principal = getSubjectPrincipal(cert); ASN1InputStream aIn = new ASN1InputStream(new ByteArrayInputStream(principal.getEncoded())); ASN1Sequence dns; try { dns = (ASN1Sequence)aIn.readObject(); } catch (IOException e) { ErrorBundle msg = new ErrorBundle(RESOURCE_NAME,"CertPathReviewer.ncSubjectNameError", new Object[] {new UntrustedInput(principal)}); throw new CertPathReviewerException(msg,e,certPath,index); } try { nameConstraintValidator.checkPermittedDN(dns); } catch (PKIXNameConstraintValidatorException cpve) { ErrorBundle msg = new ErrorBundle(RESOURCE_NAME,"CertPathReviewer.notPermittedDN", new Object[] {new UntrustedInput(principal.getName())}); throw new CertPathReviewerException(msg,cpve,certPath,index); } try { nameConstraintValidator.checkExcludedDN(dns); } catch (PKIXNameConstraintValidatorException cpve) { ErrorBundle msg = new ErrorBundle(RESOURCE_NAME,"CertPathReviewer.excludedDN", new Object[] {new UntrustedInput(principal.getName())}); throw new CertPathReviewerException(msg,cpve,certPath,index); } ASN1Sequence altName; try { altName = (ASN1Sequence)getExtensionValue(cert, SUBJECT_ALTERNATIVE_NAME); } catch (AnnotatedException ae) { ErrorBundle msg = new ErrorBundle(RESOURCE_NAME,"CertPathReviewer.subjAltNameExtError"); throw new CertPathReviewerException(msg,ae,certPath,index); } if (altName != null) { for (int j = 0; j < altName.size(); j++) { GeneralName name = GeneralName.getInstance(altName.getObjectAt(j)); try { nameConstraintValidator.checkPermitted(name); nameConstraintValidator.checkExcluded(name); } catch (PKIXNameConstraintValidatorException cpve) { ErrorBundle msg = new ErrorBundle(RESOURCE_NAME,"CertPathReviewer.notPermittedEmail", new Object[] {new UntrustedInput(name)}); throw new CertPathReviewerException(msg,cpve,certPath,index); } // switch(o.getTagNo()) TODO - move resources to PKIXNameConstraints // { // case 1: // String email = DERIA5String.getInstance(o, true).getString(); // // try // { // checkPermittedEmail(permittedSubtreesEmail, email); // } // catch (CertPathValidatorException cpve) // { // ErrorBundle msg = new ErrorBundle(RESOURCE_NAME,"CertPathReviewer.notPermittedEmail", // new Object[] {new UntrustedInput(email)}); // throw new CertPathReviewerException(msg,cpve,certPath,index); // } // // try // { // checkExcludedEmail(excludedSubtreesEmail, email); // } // catch (CertPathValidatorException cpve) // { // ErrorBundle msg = new ErrorBundle(RESOURCE_NAME,"CertPathReviewer.excludedEmail", // new Object[] {new UntrustedInput(email)}); // throw new CertPathReviewerException(msg,cpve,certPath,index); // } // // break; // case 4: // ASN1Sequence altDN = ASN1Sequence.getInstance(o, true); // // try // { // checkPermittedDN(permittedSubtreesDN, altDN); // } // catch (CertPathValidatorException cpve) // { // X509Name altDNName = new X509Name(altDN); // ErrorBundle msg = new ErrorBundle(RESOURCE_NAME,"CertPathReviewer.notPermittedDN", // new Object[] {new UntrustedInput(altDNName)}); // throw new CertPathReviewerException(msg,cpve,certPath,index); // } // // try // { // checkExcludedDN(excludedSubtreesDN, altDN); // } // catch (CertPathValidatorException cpve) // { // X509Name altDNName = new X509Name(altDN); // ErrorBundle msg = new ErrorBundle(RESOURCE_NAME,"CertPathReviewer.excludedDN", // new Object[] {new UntrustedInput(altDNName)}); // throw new CertPathReviewerException(msg,cpve,certPath,index); // } // // break; // case 7: // byte[] ip = ASN1OctetString.getInstance(o, true).getOctets(); // // try // { // checkPermittedIP(permittedSubtreesIP, ip); // } // catch (CertPathValidatorException cpve) // { // ErrorBundle msg = new ErrorBundle(RESOURCE_NAME,"CertPathReviewer.notPermittedIP", // new Object[] {IPtoString(ip)}); // throw new CertPathReviewerException(msg,cpve,certPath,index); // } // // try // { // checkExcludedIP(excludedSubtreesIP, ip); // } // catch (CertPathValidatorException cpve) // { // ErrorBundle msg = new ErrorBundle(RESOURCE_NAME,"CertPathReviewer.excludedIP", // new Object[] {IPtoString(ip)}); // throw new CertPathReviewerException(msg,cpve,certPath,index); // } // } } } } // // prepare for next certificate // // // (g) handle the name constraints extension // ASN1Sequence ncSeq; try { ncSeq = (ASN1Sequence)getExtensionValue(cert, NAME_CONSTRAINTS); } catch (AnnotatedException ae) { ErrorBundle msg = new ErrorBundle(RESOURCE_NAME,"CertPathReviewer.ncExtError"); throw new CertPathReviewerException(msg,ae,certPath,index); } if (ncSeq != null) { NameConstraints nc = NameConstraints.getInstance(ncSeq); // // (g) (1) permitted subtrees // GeneralSubtree[] permitted = nc.getPermittedSubtrees(); if (permitted != null) { nameConstraintValidator.intersectPermittedSubtree(permitted); } // // (g) (2) excluded subtrees // GeneralSubtree[] excluded = nc.getExcludedSubtrees(); if (excluded != null) { for (int c = 0; c != excluded.length; c++) { nameConstraintValidator.addExcludedSubtree(excluded[c]); } } } } // for } catch (CertPathReviewerException cpre) { addError(cpre.getErrorMessage(),cpre.getIndex()); } } /* * checks: - path length constraints and reports - total path length */ private void checkPathLength() { // init int maxPathLength = n; int totalPathLength = 0; X509Certificate cert = null; int i; for (int index = certs.size() - 1; index > 0; index--) { i = n - index; cert = (X509Certificate) certs.get(index); // l) if (!isSelfIssued(cert)) { if (maxPathLength <= 0) { ErrorBundle msg = new ErrorBundle(RESOURCE_NAME,"CertPathReviewer.pathLenghtExtended"); addError(msg); } maxPathLength--; totalPathLength++; } // m) BasicConstraints bc; try { bc = BasicConstraints.getInstance(getExtensionValue(cert, BASIC_CONSTRAINTS)); } catch (AnnotatedException ae) { ErrorBundle msg = new ErrorBundle(RESOURCE_NAME,"CertPathReviewer.processLengthConstError"); addError(msg,index); bc = null; } if (bc != null) { BigInteger _pathLengthConstraint = bc.getPathLenConstraint(); if (_pathLengthConstraint != null) { int _plc = _pathLengthConstraint.intValue(); if (_plc < maxPathLength) { maxPathLength = _plc; } } } } ErrorBundle msg = new ErrorBundle(RESOURCE_NAME,"CertPathReviewer.totalPathLength", new Object[]{Integers.valueOf(totalPathLength)}); addNotification(msg); } /* * checks: - signatures - name chaining - validity of certificates - todo: * if certificate revoked (if specified in the parameters) */ private void checkSignatures() { // 1.6.1 - Inputs // d) TrustAnchor trust = null; X500Principal trustPrincipal = null; // validation date { ErrorBundle msg = new ErrorBundle(RESOURCE_NAME,"CertPathReviewer.certPathValidDate", new Object[] {new TrustedInput(validDate), new TrustedInput(new Date())}); addNotification(msg); } // find trust anchors try { X509Certificate cert = (X509Certificate) certs.get(certs.size() - 1); Collection trustColl = getTrustAnchors(cert,pkixParams.getTrustAnchors()); if (trustColl.size() > 1) { // conflicting trust anchors ErrorBundle msg = new ErrorBundle(RESOURCE_NAME, "CertPathReviewer.conflictingTrustAnchors", new Object[]{Integers.valueOf(trustColl.size()), new UntrustedInput(cert.getIssuerX500Principal())}); addError(msg); } else if (trustColl.isEmpty()) { ErrorBundle msg = new ErrorBundle(RESOURCE_NAME, "CertPathReviewer.noTrustAnchorFound", new Object[]{new UntrustedInput(cert.getIssuerX500Principal()), Integers.valueOf(pkixParams.getTrustAnchors().size())}); addError(msg); } else { PublicKey trustPublicKey; trust = (TrustAnchor) trustColl.iterator().next(); if (trust.getTrustedCert() != null) { trustPublicKey = trust.getTrustedCert().getPublicKey(); } else { trustPublicKey = trust.getCAPublicKey(); } try { CertPathValidatorUtilities.verifyX509Certificate(cert, trustPublicKey, pkixParams.getSigProvider()); } catch (SignatureException e) { ErrorBundle msg = new ErrorBundle(RESOURCE_NAME,"CertPathReviewer.trustButInvalidCert"); addError(msg); } catch (Exception e) { // do nothing, error occurs again later } } } catch (CertPathReviewerException cpre) { addError(cpre.getErrorMessage()); } catch (Throwable t) { ErrorBundle msg = new ErrorBundle(RESOURCE_NAME, "CertPathReviewer.unknown", new Object[] {new UntrustedInput(t.getMessage()), new UntrustedInput(t)}); addError(msg); } if (trust != null) { // get the name of the trustAnchor X509Certificate sign = trust.getTrustedCert(); try { if (sign != null) { trustPrincipal = getSubjectPrincipal(sign); } else { trustPrincipal = new X500Principal(trust.getCAName()); } } catch (IllegalArgumentException ex) { ErrorBundle msg = new ErrorBundle(RESOURCE_NAME,"CertPathReviewer.trustDNInvalid", new Object[] {new UntrustedInput(trust.getCAName())}); addError(msg); } // test key usages of the trust anchor if (sign != null) { boolean[] ku = sign.getKeyUsage(); if (ku != null && !ku[5]) { ErrorBundle msg = new ErrorBundle(RESOURCE_NAME, "CertPathReviewer.trustKeyUsage"); addNotification(msg); } } } // 1.6.2 - Initialization PublicKey workingPublicKey = null; X500Principal workingIssuerName = trustPrincipal; X509Certificate sign = null; AlgorithmIdentifier workingAlgId = null; DERObjectIdentifier workingPublicKeyAlgorithm = null; ASN1Encodable workingPublicKeyParameters = null; if (trust != null) { sign = trust.getTrustedCert(); if (sign != null) { workingPublicKey = sign.getPublicKey(); } else { workingPublicKey = trust.getCAPublicKey(); } try { workingAlgId = getAlgorithmIdentifier(workingPublicKey); workingPublicKeyAlgorithm = workingAlgId.getObjectId(); workingPublicKeyParameters = workingAlgId.getParameters(); } catch (CertPathValidatorException ex) { ErrorBundle msg = new ErrorBundle(RESOURCE_NAME,"CertPathReviewer.trustPubKeyError"); addError(msg); workingAlgId = null; } } // Basic cert checks X509Certificate cert = null; int i; for (int index = certs.size() - 1; index >= 0; index--) { // // i as defined in the algorithm description // i = n - index; // // set certificate to be checked in this round // sign and workingPublicKey and workingIssuerName are set // at the end of the for loop and initialied the // first time from the TrustAnchor // cert = (X509Certificate) certs.get(index); // verify signature if (workingPublicKey != null) { try { CertPathValidatorUtilities.verifyX509Certificate(cert, workingPublicKey, pkixParams.getSigProvider()); } catch (GeneralSecurityException ex) { ErrorBundle msg = new ErrorBundle(RESOURCE_NAME,"CertPathReviewer.signatureNotVerified", new Object[] {ex.getMessage(),ex,ex.getClass().getName()}); addError(msg,index); } } else if (isSelfIssued(cert)) { try { CertPathValidatorUtilities.verifyX509Certificate(cert, cert.getPublicKey(), pkixParams.getSigProvider()); ErrorBundle msg = new ErrorBundle(RESOURCE_NAME,"CertPathReviewer.rootKeyIsValidButNotATrustAnchor"); addError(msg, index); } catch (GeneralSecurityException ex) { ErrorBundle msg = new ErrorBundle(RESOURCE_NAME,"CertPathReviewer.signatureNotVerified", new Object[] {ex.getMessage(),ex,ex.getClass().getName()}); addError(msg,index); } } else { ErrorBundle msg = new ErrorBundle(RESOURCE_NAME,"CertPathReviewer.NoIssuerPublicKey"); // if there is an authority key extension add the serial and issuer of the missing certificate byte[] akiBytes = cert.getExtensionValue(X509Extensions.AuthorityKeyIdentifier.getId()); if (akiBytes != null) { try { AuthorityKeyIdentifier aki = AuthorityKeyIdentifier.getInstance( X509ExtensionUtil.fromExtensionValue(akiBytes)); GeneralNames issuerNames = aki.getAuthorityCertIssuer(); if (issuerNames != null) { GeneralName name = issuerNames.getNames()[0]; BigInteger serial = aki.getAuthorityCertSerialNumber(); if (serial != null) { Object[] extraArgs = {new LocaleString(RESOURCE_NAME, "missingIssuer"), " \"", name , "\" ", new LocaleString(RESOURCE_NAME, "missingSerial") , " ", serial}; msg.setExtraArguments(extraArgs); } } } catch (IOException e) { // ignore } } addError(msg,index); } // certificate valid? try { cert.checkValidity(validDate); } catch (CertificateNotYetValidException cnve) { ErrorBundle msg = new ErrorBundle(RESOURCE_NAME,"CertPathReviewer.certificateNotYetValid", new Object[] {new TrustedInput(cert.getNotBefore())}); addError(msg,index); } catch (CertificateExpiredException cee) { ErrorBundle msg = new ErrorBundle(RESOURCE_NAME,"CertPathReviewer.certificateExpired", new Object[] {new TrustedInput(cert.getNotAfter())}); addError(msg,index); } // certificate revoked? if (pkixParams.isRevocationEnabled()) { // read crl distribution points extension CRLDistPoint crlDistPoints = null; try { ASN1Primitive crl_dp = getExtensionValue(cert,CRL_DIST_POINTS); if (crl_dp != null) { crlDistPoints = CRLDistPoint.getInstance(crl_dp); } } catch (AnnotatedException ae) { ErrorBundle msg = new ErrorBundle(RESOURCE_NAME,"CertPathReviewer.crlDistPtExtError"); addError(msg,index); } // read authority information access extension AuthorityInformationAccess authInfoAcc = null; try { ASN1Primitive auth_info_acc = getExtensionValue(cert,AUTH_INFO_ACCESS); if (auth_info_acc != null) { authInfoAcc = AuthorityInformationAccess.getInstance(auth_info_acc); } } catch (AnnotatedException ae) { ErrorBundle msg = new ErrorBundle(RESOURCE_NAME,"CertPathReviewer.crlAuthInfoAccError"); addError(msg,index); } Vector crlDistPointUrls = getCRLDistUrls(crlDistPoints); Vector ocspUrls = getOCSPUrls(authInfoAcc); // add notifications with the crl distribution points // output crl distribution points Iterator urlIt = crlDistPointUrls.iterator(); while (urlIt.hasNext()) { ErrorBundle msg = new ErrorBundle(RESOURCE_NAME,"CertPathReviewer.crlDistPoint", new Object[] {new UntrustedUrlInput(urlIt.next())}); addNotification(msg,index); } // output ocsp urls urlIt = ocspUrls.iterator(); while (urlIt.hasNext()) { ErrorBundle msg = new ErrorBundle(RESOURCE_NAME,"CertPathReviewer.ocspLocation", new Object[] {new UntrustedUrlInput(urlIt.next())}); addNotification(msg,index); } // TODO also support Netscapes revocation-url and/or OCSP instead of CRLs for revocation checking // check CRLs try { checkRevocation(pkixParams, cert, validDate, sign, workingPublicKey, crlDistPointUrls, ocspUrls, index); } catch (CertPathReviewerException cpre) { addError(cpre.getErrorMessage(),index); } } // certificate issuer correct if (workingIssuerName != null && !cert.getIssuerX500Principal().equals(workingIssuerName)) { ErrorBundle msg = new ErrorBundle(RESOURCE_NAME,"CertPathReviewer.certWrongIssuer", new Object[] {workingIssuerName.getName(), cert.getIssuerX500Principal().getName()}); addError(msg,index); } // // prepare for next certificate // if (i != n) { if (cert != null && cert.getVersion() == 1) { ErrorBundle msg = new ErrorBundle(RESOURCE_NAME,"CertPathReviewer.noCACert"); addError(msg,index); } // k) BasicConstraints bc; try { bc = BasicConstraints.getInstance(getExtensionValue(cert, BASIC_CONSTRAINTS)); if (bc != null) { if (!bc.isCA()) { ErrorBundle msg = new ErrorBundle(RESOURCE_NAME,"CertPathReviewer.noCACert"); addError(msg,index); } } else { ErrorBundle msg = new ErrorBundle(RESOURCE_NAME,"CertPathReviewer.noBasicConstraints"); addError(msg,index); } } catch (AnnotatedException ae) { ErrorBundle msg = new ErrorBundle(RESOURCE_NAME,"CertPathReviewer.errorProcesingBC"); addError(msg,index); } // n) boolean[] _usage = cert.getKeyUsage(); if ((_usage != null) && !_usage[KEY_CERT_SIGN]) { ErrorBundle msg = new ErrorBundle(RESOURCE_NAME,"CertPathReviewer.noCertSign"); addError(msg,index); } } // if // set signing certificate for next round sign = cert; // c) workingIssuerName = cert.getSubjectX500Principal(); // d) e) f) try { workingPublicKey = getNextWorkingKey(certs, index); workingAlgId = getAlgorithmIdentifier(workingPublicKey); workingPublicKeyAlgorithm = workingAlgId.getObjectId(); workingPublicKeyParameters = workingAlgId.getParameters(); } catch (CertPathValidatorException ex) { ErrorBundle msg = new ErrorBundle(RESOURCE_NAME,"CertPathReviewer.pubKeyError"); addError(msg,index); workingAlgId = null; workingPublicKeyAlgorithm = null; workingPublicKeyParameters = null; } } // for trustAnchor = trust; subjectPublicKey = workingPublicKey; } private void checkPolicy() { // // 6.1.1 Inputs // // c) Initial Policy Set Set userInitialPolicySet = pkixParams.getInitialPolicies(); // e) f) g) are part of pkixParams // // 6.1.2 Initialization // // a) valid policy tree List[] policyNodes = new ArrayList[n + 1]; for (int j = 0; j < policyNodes.length; j++) { policyNodes[j] = new ArrayList(); } Set policySet = new HashSet(); policySet.add(ANY_POLICY); PKIXPolicyNode validPolicyTree = new PKIXPolicyNode(new ArrayList(), 0, policySet, null, new HashSet(), ANY_POLICY, false); policyNodes[0].add(validPolicyTree); // d) explicit policy int explicitPolicy; if (pkixParams.isExplicitPolicyRequired()) { explicitPolicy = 0; } else { explicitPolicy = n + 1; } // e) inhibit any policy int inhibitAnyPolicy; if (pkixParams.isAnyPolicyInhibited()) { inhibitAnyPolicy = 0; } else { inhibitAnyPolicy = n + 1; } // f) policy mapping int policyMapping; if (pkixParams.isPolicyMappingInhibited()) { policyMapping = 0; } else { policyMapping = n + 1; } Set acceptablePolicies = null; // // 6.1.3 Basic Certificate processing // X509Certificate cert = null; int index; int i; try { for (index = certs.size() - 1; index >= 0; index--) { // i as defined in the algorithm description i = n - index; // set certificate to be checked in this round cert = (X509Certificate) certs.get(index); // d) process policy information ASN1Sequence certPolicies; try { certPolicies = (ASN1Sequence) getExtensionValue( cert, CERTIFICATE_POLICIES); } catch (AnnotatedException ae) { ErrorBundle msg = new ErrorBundle(RESOURCE_NAME,"CertPathReviewer.policyExtError"); throw new CertPathReviewerException(msg,ae,certPath,index); } if (certPolicies != null && validPolicyTree != null) { // d) 1) Enumeration e = certPolicies.getObjects(); Set pols = new HashSet(); while (e.hasMoreElements()) { PolicyInformation pInfo = PolicyInformation.getInstance(e.nextElement()); DERObjectIdentifier pOid = pInfo.getPolicyIdentifier(); pols.add(pOid.getId()); if (!ANY_POLICY.equals(pOid.getId())) { Set pq; try { pq = getQualifierSet(pInfo.getPolicyQualifiers()); } catch (CertPathValidatorException cpve) { ErrorBundle msg = new ErrorBundle(RESOURCE_NAME,"CertPathReviewer.policyQualifierError"); throw new CertPathReviewerException(msg,cpve,certPath,index); } boolean match = processCertD1i(i, policyNodes, pOid, pq); if (!match) { processCertD1ii(i, policyNodes, pOid, pq); } } } if (acceptablePolicies == null || acceptablePolicies.contains(ANY_POLICY)) { acceptablePolicies = pols; } else { Iterator it = acceptablePolicies.iterator(); Set t1 = new HashSet(); while (it.hasNext()) { Object o = it.next(); if (pols.contains(o)) { t1.add(o); } } acceptablePolicies = t1; } // d) 2) if ((inhibitAnyPolicy > 0) || ((i < n) && isSelfIssued(cert))) { e = certPolicies.getObjects(); while (e.hasMoreElements()) { PolicyInformation pInfo = PolicyInformation.getInstance(e.nextElement()); if (ANY_POLICY.equals(pInfo.getPolicyIdentifier().getId())) { Set _apq; try { _apq = getQualifierSet(pInfo.getPolicyQualifiers()); } catch (CertPathValidatorException cpve) { ErrorBundle msg = new ErrorBundle(RESOURCE_NAME,"CertPathReviewer.policyQualifierError"); throw new CertPathReviewerException(msg,cpve,certPath,index); } List _nodes = policyNodes[i - 1]; for (int k = 0; k < _nodes.size(); k++) { PKIXPolicyNode _node = (PKIXPolicyNode) _nodes.get(k); Iterator _policySetIter = _node.getExpectedPolicies().iterator(); while (_policySetIter.hasNext()) { Object _tmp = _policySetIter.next(); String _policy; if (_tmp instanceof String) { _policy = (String) _tmp; } else if (_tmp instanceof DERObjectIdentifier) { _policy = ((DERObjectIdentifier) _tmp).getId(); } else { continue; } boolean _found = false; Iterator _childrenIter = _node .getChildren(); while (_childrenIter.hasNext()) { PKIXPolicyNode _child = (PKIXPolicyNode) _childrenIter.next(); if (_policy.equals(_child.getValidPolicy())) { _found = true; } } if (!_found) { Set _newChildExpectedPolicies = new HashSet(); _newChildExpectedPolicies.add(_policy); PKIXPolicyNode _newChild = new PKIXPolicyNode( new ArrayList(), i, _newChildExpectedPolicies, _node, _apq, _policy, false); _node.addChild(_newChild); policyNodes[i].add(_newChild); } } } break; } } } // // (d) (3) // for (int j = (i - 1); j >= 0; j--) { List nodes = policyNodes[j]; for (int k = 0; k < nodes.size(); k++) { PKIXPolicyNode node = (PKIXPolicyNode) nodes.get(k); if (!node.hasChildren()) { validPolicyTree = removePolicyNode( validPolicyTree, policyNodes, node); if (validPolicyTree == null) { break; } } } } // // d (4) // Set criticalExtensionOids = cert.getCriticalExtensionOIDs(); if (criticalExtensionOids != null) { boolean critical = criticalExtensionOids.contains(CERTIFICATE_POLICIES); List nodes = policyNodes[i]; for (int j = 0; j < nodes.size(); j++) { PKIXPolicyNode node = (PKIXPolicyNode) nodes.get(j); node.setCritical(critical); } } } // e) if (certPolicies == null) { validPolicyTree = null; } // f) if (explicitPolicy <= 0 && validPolicyTree == null) { ErrorBundle msg = new ErrorBundle(RESOURCE_NAME,"CertPathReviewer.noValidPolicyTree"); throw new CertPathReviewerException(msg); } // // 6.1.4 preparation for next Certificate // if (i != n) { // a) ASN1Primitive pm; try { pm = getExtensionValue(cert, POLICY_MAPPINGS); } catch (AnnotatedException ae) { ErrorBundle msg = new ErrorBundle(RESOURCE_NAME,"CertPathReviewer.policyMapExtError"); throw new CertPathReviewerException(msg,ae,certPath,index); } if (pm != null) { ASN1Sequence mappings = (ASN1Sequence) pm; for (int j = 0; j < mappings.size(); j++) { ASN1Sequence mapping = (ASN1Sequence) mappings.getObjectAt(j); DERObjectIdentifier ip_id = (DERObjectIdentifier) mapping.getObjectAt(0); DERObjectIdentifier sp_id = (DERObjectIdentifier) mapping.getObjectAt(1); if (ANY_POLICY.equals(ip_id.getId())) { ErrorBundle msg = new ErrorBundle(RESOURCE_NAME,"CertPathReviewer.invalidPolicyMapping"); throw new CertPathReviewerException(msg,certPath,index); } if (ANY_POLICY.equals(sp_id.getId())) { ErrorBundle msg = new ErrorBundle(RESOURCE_NAME,"CertPathReviewer.invalidPolicyMapping"); throw new CertPathReviewerException(msg,certPath,index); } } } // b) if (pm != null) { ASN1Sequence mappings = (ASN1Sequence)pm; Map m_idp = new HashMap(); Set s_idp = new HashSet(); for (int j = 0; j < mappings.size(); j++) { ASN1Sequence mapping = (ASN1Sequence)mappings.getObjectAt(j); String id_p = ((DERObjectIdentifier)mapping.getObjectAt(0)).getId(); String sd_p = ((DERObjectIdentifier)mapping.getObjectAt(1)).getId(); Set tmp; if (!m_idp.containsKey(id_p)) { tmp = new HashSet(); tmp.add(sd_p); m_idp.put(id_p, tmp); s_idp.add(id_p); } else { tmp = (Set)m_idp.get(id_p); tmp.add(sd_p); } } Iterator it_idp = s_idp.iterator(); while (it_idp.hasNext()) { String id_p = (String)it_idp.next(); // // (1) // if (policyMapping > 0) { try { prepareNextCertB1(i,policyNodes,id_p,m_idp,cert); } catch (AnnotatedException ae) { // error processing certificate policies extension ErrorBundle msg = new ErrorBundle(RESOURCE_NAME,"CertPathReviewer.policyExtError"); throw new CertPathReviewerException(msg,ae,certPath,index); } catch (CertPathValidatorException cpve) { // error building qualifier set ErrorBundle msg = new ErrorBundle(RESOURCE_NAME,"CertPathReviewer.policyQualifierError"); throw new CertPathReviewerException(msg,cpve,certPath,index); } // // (2) // } else if (policyMapping <= 0) { validPolicyTree = prepareNextCertB2(i,policyNodes,id_p,validPolicyTree); } } } // // h) // if (!isSelfIssued(cert)) { // (1) if (explicitPolicy != 0) { explicitPolicy--; } // (2) if (policyMapping != 0) { policyMapping--; } // (3) if (inhibitAnyPolicy != 0) { inhibitAnyPolicy--; } } // // i) // try { ASN1Sequence pc = (ASN1Sequence) getExtensionValue(cert,POLICY_CONSTRAINTS); if (pc != null) { Enumeration policyConstraints = pc.getObjects(); while (policyConstraints.hasMoreElements()) { ASN1TaggedObject constraint = (ASN1TaggedObject) policyConstraints.nextElement(); int tmpInt; switch (constraint.getTagNo()) { case 0: tmpInt = DERInteger.getInstance(constraint, false).getValue().intValue(); if (tmpInt < explicitPolicy) { explicitPolicy = tmpInt; } break; case 1: tmpInt = DERInteger.getInstance(constraint, false).getValue().intValue(); if (tmpInt < policyMapping) { policyMapping = tmpInt; } break; } } } } catch (AnnotatedException ae) { ErrorBundle msg = new ErrorBundle(RESOURCE_NAME,"CertPathReviewer.policyConstExtError"); throw new CertPathReviewerException(msg,certPath,index); } // // j) // try { DERInteger iap = (DERInteger)getExtensionValue(cert, INHIBIT_ANY_POLICY); if (iap != null) { int _inhibitAnyPolicy = iap.getValue().intValue(); if (_inhibitAnyPolicy < inhibitAnyPolicy) { inhibitAnyPolicy = _inhibitAnyPolicy; } } } catch (AnnotatedException ae) { ErrorBundle msg = new ErrorBundle(RESOURCE_NAME,"CertPathReviewer.policyInhibitExtError"); throw new CertPathReviewerException(msg,certPath,index); } } } // // 6.1.5 Wrap up // // // a) // if (!isSelfIssued(cert) && explicitPolicy > 0) { explicitPolicy--; } // // b) // try { ASN1Sequence pc = (ASN1Sequence) getExtensionValue(cert, POLICY_CONSTRAINTS); if (pc != null) { Enumeration policyConstraints = pc.getObjects(); while (policyConstraints.hasMoreElements()) { ASN1TaggedObject constraint = (ASN1TaggedObject)policyConstraints.nextElement(); switch (constraint.getTagNo()) { case 0: int tmpInt = DERInteger.getInstance(constraint, false).getValue().intValue(); if (tmpInt == 0) { explicitPolicy = 0; } break; } } } } catch (AnnotatedException e) { ErrorBundle msg = new ErrorBundle(RESOURCE_NAME,"CertPathReviewer.policyConstExtError"); throw new CertPathReviewerException(msg,certPath,index); } // // (g) // PKIXPolicyNode intersection; // // (g) (i) // if (validPolicyTree == null) { if (pkixParams.isExplicitPolicyRequired()) { ErrorBundle msg = new ErrorBundle(RESOURCE_NAME,"CertPathReviewer.explicitPolicy"); throw new CertPathReviewerException(msg,certPath,index); } intersection = null; } else if (isAnyPolicy(userInitialPolicySet)) // (g) (ii) { if (pkixParams.isExplicitPolicyRequired()) { if (acceptablePolicies.isEmpty()) { ErrorBundle msg = new ErrorBundle(RESOURCE_NAME,"CertPathReviewer.explicitPolicy"); throw new CertPathReviewerException(msg,certPath,index); } else { Set _validPolicyNodeSet = new HashSet(); for (int j = 0; j < policyNodes.length; j++) { List _nodeDepth = policyNodes[j]; for (int k = 0; k < _nodeDepth.size(); k++) { PKIXPolicyNode _node = (PKIXPolicyNode)_nodeDepth.get(k); if (ANY_POLICY.equals(_node.getValidPolicy())) { Iterator _iter = _node.getChildren(); while (_iter.hasNext()) { _validPolicyNodeSet.add(_iter.next()); } } } } Iterator _vpnsIter = _validPolicyNodeSet.iterator(); while (_vpnsIter.hasNext()) { PKIXPolicyNode _node = (PKIXPolicyNode)_vpnsIter.next(); String _validPolicy = _node.getValidPolicy(); if (!acceptablePolicies.contains(_validPolicy)) { //validPolicyTree = removePolicyNode(validPolicyTree, policyNodes, _node); } } if (validPolicyTree != null) { for (int j = (n - 1); j >= 0; j--) { List nodes = policyNodes[j]; for (int k = 0; k < nodes.size(); k++) { PKIXPolicyNode node = (PKIXPolicyNode)nodes.get(k); if (!node.hasChildren()) { validPolicyTree = removePolicyNode(validPolicyTree, policyNodes, node); } } } } } } intersection = validPolicyTree; } else { // // (g) (iii) // // This implementation is not exactly same as the one described in RFC3280. // However, as far as the validation result is concerned, both produce // adequate result. The only difference is whether AnyPolicy is remain // in the policy tree or not. // // (g) (iii) 1 // Set _validPolicyNodeSet = new HashSet(); for (int j = 0; j < policyNodes.length; j++) { List _nodeDepth = policyNodes[j]; for (int k = 0; k < _nodeDepth.size(); k++) { PKIXPolicyNode _node = (PKIXPolicyNode)_nodeDepth.get(k); if (ANY_POLICY.equals(_node.getValidPolicy())) { Iterator _iter = _node.getChildren(); while (_iter.hasNext()) { PKIXPolicyNode _c_node = (PKIXPolicyNode)_iter.next(); if (!ANY_POLICY.equals(_c_node.getValidPolicy())) { _validPolicyNodeSet.add(_c_node); } } } } } // // (g) (iii) 2 // Iterator _vpnsIter = _validPolicyNodeSet.iterator(); while (_vpnsIter.hasNext()) { PKIXPolicyNode _node = (PKIXPolicyNode)_vpnsIter.next(); String _validPolicy = _node.getValidPolicy(); if (!userInitialPolicySet.contains(_validPolicy)) { validPolicyTree = removePolicyNode(validPolicyTree, policyNodes, _node); } } // // (g) (iii) 4 // if (validPolicyTree != null) { for (int j = (n - 1); j >= 0; j--) { List nodes = policyNodes[j]; for (int k = 0; k < nodes.size(); k++) { PKIXPolicyNode node = (PKIXPolicyNode)nodes.get(k); if (!node.hasChildren()) { validPolicyTree = removePolicyNode(validPolicyTree, policyNodes, node); } } } } intersection = validPolicyTree; } if ((explicitPolicy <= 0) && (intersection == null)) { ErrorBundle msg = new ErrorBundle(RESOURCE_NAME,"CertPathReviewer.invalidPolicy"); throw new CertPathReviewerException(msg); } validPolicyTree = intersection; } catch (CertPathReviewerException cpre) { addError(cpre.getErrorMessage(),cpre.getIndex()); validPolicyTree = null; } } private void checkCriticalExtensions() { // // initialise CertPathChecker's // List pathCheckers = pkixParams.getCertPathCheckers(); Iterator certIter = pathCheckers.iterator(); try { try { while (certIter.hasNext()) { ((PKIXCertPathChecker)certIter.next()).init(false); } } catch (CertPathValidatorException cpve) { ErrorBundle msg = new ErrorBundle(RESOURCE_NAME,"CertPathReviewer.certPathCheckerError", new Object[] {cpve.getMessage(),cpve,cpve.getClass().getName()}); throw new CertPathReviewerException(msg,cpve); } // // process critical extesions for each certificate // X509Certificate cert = null; int index; for (index = certs.size()-1; index >= 0; index--) { cert = (X509Certificate) certs.get(index); Set criticalExtensions = cert.getCriticalExtensionOIDs(); if (criticalExtensions == null || criticalExtensions.isEmpty()) { continue; } // remove already processed extensions criticalExtensions.remove(KEY_USAGE); criticalExtensions.remove(CERTIFICATE_POLICIES); criticalExtensions.remove(POLICY_MAPPINGS); criticalExtensions.remove(INHIBIT_ANY_POLICY); criticalExtensions.remove(ISSUING_DISTRIBUTION_POINT); criticalExtensions.remove(DELTA_CRL_INDICATOR); criticalExtensions.remove(POLICY_CONSTRAINTS); criticalExtensions.remove(BASIC_CONSTRAINTS); criticalExtensions.remove(SUBJECT_ALTERNATIVE_NAME); criticalExtensions.remove(NAME_CONSTRAINTS); // process qcStatements extension if (criticalExtensions.contains(QC_STATEMENT)) { if (processQcStatements(cert,index)) { criticalExtensions.remove(QC_STATEMENT); } } Iterator tmpIter = pathCheckers.iterator(); while (tmpIter.hasNext()) { try { ((PKIXCertPathChecker)tmpIter.next()).check(cert, criticalExtensions); } catch (CertPathValidatorException e) { ErrorBundle msg = new ErrorBundle(RESOURCE_NAME,"CertPathReviewer.criticalExtensionError", new Object[] {e.getMessage(),e,e.getClass().getName()}); throw new CertPathReviewerException(msg,e.getCause(),certPath,index); } } if (!criticalExtensions.isEmpty()) { ErrorBundle msg; Iterator it = criticalExtensions.iterator(); while (it.hasNext()) { msg = new ErrorBundle(RESOURCE_NAME,"CertPathReviewer.unknownCriticalExt", new Object[] {new DERObjectIdentifier((String) it.next())}); addError(msg, index); } } } } catch (CertPathReviewerException cpre) { addError(cpre.getErrorMessage(),cpre.getIndex()); } } private boolean processQcStatements( X509Certificate cert, int index) { try { boolean unknownStatement = false; ASN1Sequence qcSt = (ASN1Sequence) getExtensionValue(cert,QC_STATEMENT); for (int j = 0; j < qcSt.size(); j++) { QCStatement stmt = QCStatement.getInstance(qcSt.getObjectAt(j)); if (QCStatement.id_etsi_qcs_QcCompliance.equals(stmt.getStatementId())) { // process statement - just write a notification that the certificate contains this statement ErrorBundle msg = new ErrorBundle(RESOURCE_NAME,"CertPathReviewer.QcEuCompliance"); addNotification(msg,index); } else if (QCStatement.id_qcs_pkixQCSyntax_v1.equals(stmt.getStatementId())) { // process statement - just recognize the statement } else if (QCStatement.id_etsi_qcs_QcSSCD.equals(stmt.getStatementId())) { // process statement - just write a notification that the certificate contains this statement ErrorBundle msg = new ErrorBundle(RESOURCE_NAME,"CertPathReviewer.QcSSCD"); addNotification(msg,index); } else if (QCStatement.id_etsi_qcs_LimiteValue.equals(stmt.getStatementId())) { // process statement - write a notification containing the limit value MonetaryValue limit = MonetaryValue.getInstance(stmt.getStatementInfo()); Iso4217CurrencyCode currency = limit.getCurrency(); double value = limit.getAmount().doubleValue() * Math.pow(10,limit.getExponent().doubleValue()); ErrorBundle msg; if (limit.getCurrency().isAlphabetic()) { msg = new ErrorBundle(RESOURCE_NAME,"CertPathReviewer.QcLimitValueAlpha", new Object[] {limit.getCurrency().getAlphabetic(), new TrustedInput(new Double(value)), limit}); } else { msg = new ErrorBundle(RESOURCE_NAME,"CertPathReviewer.QcLimitValueNum", new Object[]{Integers.valueOf(limit.getCurrency().getNumeric()), new TrustedInput(new Double(value)), limit}); } addNotification(msg,index); } else { ErrorBundle msg = new ErrorBundle(RESOURCE_NAME,"CertPathReviewer.QcUnknownStatement", new Object[] {stmt.getStatementId(),new UntrustedInput(stmt)}); addNotification(msg,index); unknownStatement = true; } } return !unknownStatement; } catch (AnnotatedException ae) { ErrorBundle msg = new ErrorBundle(RESOURCE_NAME,"CertPathReviewer.QcStatementExtError"); addError(msg,index); } return false; } private String IPtoString(byte[] ip) { String result; try { result = InetAddress.getByAddress(ip).getHostAddress(); } catch (Exception e) { StringBuffer b = new StringBuffer(); for (int i = 0; i != ip.length; i++) { b.append(Integer.toHexString(ip[i] & 0xff)); b.append(' '); } result = b.toString(); } return result; } protected void checkRevocation(PKIXParameters paramsPKIX, X509Certificate cert, Date validDate, X509Certificate sign, PublicKey workingPublicKey, Vector crlDistPointUrls, Vector ocspUrls, int index) throws CertPathReviewerException { checkCRLs(paramsPKIX, cert, validDate, sign, workingPublicKey, crlDistPointUrls, index); } protected void checkCRLs( PKIXParameters paramsPKIX, X509Certificate cert, Date validDate, X509Certificate sign, PublicKey workingPublicKey, Vector crlDistPointUrls, int index) throws CertPathReviewerException { X509CRLStoreSelector crlselect; crlselect = new X509CRLStoreSelector(); try { crlselect.addIssuerName(getEncodedIssuerPrincipal(cert).getEncoded()); } catch (IOException e) { ErrorBundle msg = new ErrorBundle(RESOURCE_NAME,"CertPathReviewer.crlIssuerException"); throw new CertPathReviewerException(msg,e); } crlselect.setCertificateChecking(cert); Iterator crl_iter; try { Collection crl_coll = CRL_UTIL.findCRLs(crlselect, paramsPKIX); crl_iter = crl_coll.iterator(); if (crl_coll.isEmpty()) { // notifcation - no local crls found crl_coll = CRL_UTIL.findCRLs(new X509CRLStoreSelector(),paramsPKIX); Iterator it = crl_coll.iterator(); List nonMatchingCrlNames = new ArrayList(); while (it.hasNext()) { nonMatchingCrlNames.add(((X509CRL) it.next()).getIssuerX500Principal()); } int numbOfCrls = nonMatchingCrlNames.size(); ErrorBundle msg = new ErrorBundle(RESOURCE_NAME, "CertPathReviewer.noCrlInCertstore", new Object[]{new UntrustedInput(crlselect.getIssuerNames()), new UntrustedInput(nonMatchingCrlNames), Integers.valueOf(numbOfCrls)}); addNotification(msg,index); } } catch (AnnotatedException ae) { ErrorBundle msg = new ErrorBundle(RESOURCE_NAME,"CertPathReviewer.crlExtractionError", new Object[] {ae.getCause().getMessage(),ae.getCause(),ae.getCause().getClass().getName()}); addError(msg,index); crl_iter = new ArrayList().iterator(); } boolean validCrlFound = false; X509CRL crl = null; while (crl_iter.hasNext()) { crl = (X509CRL)crl_iter.next(); if (crl.getNextUpdate() == null || paramsPKIX.getDate().before(crl.getNextUpdate())) { validCrlFound = true; ErrorBundle msg = new ErrorBundle(RESOURCE_NAME, "CertPathReviewer.localValidCRL", new Object[] {new TrustedInput(crl.getThisUpdate()), new TrustedInput(crl.getNextUpdate())}); addNotification(msg,index); break; } else { ErrorBundle msg = new ErrorBundle(RESOURCE_NAME, "CertPathReviewer.localInvalidCRL", new Object[] {new TrustedInput(crl.getThisUpdate()), new TrustedInput(crl.getNextUpdate())}); addNotification(msg,index); } } // if no valid crl was found in the CertStores try to get one from a // crl distribution point if (!validCrlFound) { X509CRL onlineCRL = null; Iterator urlIt = crlDistPointUrls.iterator(); while (urlIt.hasNext()) { try { String location = (String) urlIt.next(); onlineCRL = getCRL(location); if (onlineCRL != null) { // check if crl issuer is correct if (!cert.getIssuerX500Principal().equals(onlineCRL.getIssuerX500Principal())) { ErrorBundle msg = new ErrorBundle(RESOURCE_NAME, "CertPathReviewer.onlineCRLWrongCA", new Object[] {new UntrustedInput(onlineCRL.getIssuerX500Principal().getName()), new UntrustedInput(cert.getIssuerX500Principal().getName()), new UntrustedUrlInput(location)}); addNotification(msg,index); continue; } if (onlineCRL.getNextUpdate() == null || pkixParams.getDate().before(onlineCRL.getNextUpdate())) { validCrlFound = true; ErrorBundle msg = new ErrorBundle(RESOURCE_NAME, "CertPathReviewer.onlineValidCRL", new Object[] {new TrustedInput(onlineCRL.getThisUpdate()), new TrustedInput(onlineCRL.getNextUpdate()), new UntrustedUrlInput(location)}); addNotification(msg,index); crl = onlineCRL; break; } else { ErrorBundle msg = new ErrorBundle(RESOURCE_NAME, "CertPathReviewer.onlineInvalidCRL", new Object[] {new TrustedInput(onlineCRL.getThisUpdate()), new TrustedInput(onlineCRL.getNextUpdate()), new UntrustedUrlInput(location)}); addNotification(msg,index); } } } catch (CertPathReviewerException cpre) { addNotification(cpre.getErrorMessage(),index); } } } // check the crl X509CRLEntry crl_entry; if (crl != null) { if (sign != null) { boolean[] keyusage = sign.getKeyUsage(); if (keyusage != null && (keyusage.length < 7 || !keyusage[CRL_SIGN])) { ErrorBundle msg = new ErrorBundle(RESOURCE_NAME,"CertPathReviewer.noCrlSigningPermited"); throw new CertPathReviewerException(msg); } } if (workingPublicKey != null) { try { crl.verify(workingPublicKey, "BC"); } catch (Exception e) { ErrorBundle msg = new ErrorBundle(RESOURCE_NAME,"CertPathReviewer.crlVerifyFailed"); throw new CertPathReviewerException(msg,e); } } else // issuer public key not known { ErrorBundle msg = new ErrorBundle(RESOURCE_NAME,"CertPathReviewer.crlNoIssuerPublicKey"); throw new CertPathReviewerException(msg); } crl_entry = crl.getRevokedCertificate(cert.getSerialNumber()); if (crl_entry != null) { String reason = null; if (crl_entry.hasExtensions()) { DEREnumerated reasonCode; try { reasonCode = DEREnumerated.getInstance(getExtensionValue(crl_entry, X509Extensions.ReasonCode.getId())); } catch (AnnotatedException ae) { ErrorBundle msg = new ErrorBundle(RESOURCE_NAME,"CertPathReviewer.crlReasonExtError"); throw new CertPathReviewerException(msg,ae); } if (reasonCode != null) { reason = crlReasons[reasonCode.getValue().intValue()]; } } if (reason == null) { reason = crlReasons[7]; // unknown } // i18n reason LocaleString ls = new LocaleString(RESOURCE_NAME, reason); if (!validDate.before(crl_entry.getRevocationDate())) { ErrorBundle msg = new ErrorBundle(RESOURCE_NAME,"CertPathReviewer.certRevoked", new Object[] {new TrustedInput(crl_entry.getRevocationDate()),ls}); throw new CertPathReviewerException(msg); } else // cert was revoked after validation date { ErrorBundle msg = new ErrorBundle(RESOURCE_NAME,"CertPathReviewer.revokedAfterValidation", new Object[] {new TrustedInput(crl_entry.getRevocationDate()),ls}); addNotification(msg,index); } } else // cert is not revoked { ErrorBundle msg = new ErrorBundle(RESOURCE_NAME,"CertPathReviewer.notRevoked"); addNotification(msg,index); } // // warn if a new crl is available // if (crl.getNextUpdate() != null && crl.getNextUpdate().before(pkixParams.getDate())) { ErrorBundle msg = new ErrorBundle(RESOURCE_NAME,"CertPathReviewer.crlUpdateAvailable", new Object[] {new TrustedInput(crl.getNextUpdate())}); addNotification(msg,index); } // // check the DeltaCRL indicator, base point and the issuing distribution point // ASN1Primitive idp; try { idp = getExtensionValue(crl, ISSUING_DISTRIBUTION_POINT); } catch (AnnotatedException ae) { ErrorBundle msg = new ErrorBundle(RESOURCE_NAME,"CertPathReviewer.distrPtExtError"); throw new CertPathReviewerException(msg); } ASN1Primitive dci; try { dci = getExtensionValue(crl, DELTA_CRL_INDICATOR); } catch (AnnotatedException ae) { ErrorBundle msg = new ErrorBundle(RESOURCE_NAME,"CertPathReviewer.deltaCrlExtError"); throw new CertPathReviewerException(msg); } if (dci != null) { X509CRLStoreSelector baseSelect = new X509CRLStoreSelector(); try { baseSelect.addIssuerName(getIssuerPrincipal(crl).getEncoded()); } catch (IOException e) { ErrorBundle msg = new ErrorBundle(RESOURCE_NAME,"CertPathReviewer.crlIssuerException"); throw new CertPathReviewerException(msg,e); } baseSelect.setMinCRLNumber(((DERInteger)dci).getPositiveValue()); try { baseSelect.setMaxCRLNumber(((DERInteger)getExtensionValue(crl, CRL_NUMBER)).getPositiveValue().subtract(BigInteger.valueOf(1))); } catch (AnnotatedException ae) { ErrorBundle msg = new ErrorBundle(RESOURCE_NAME,"CertPathReviewer.crlNbrExtError"); throw new CertPathReviewerException(msg,ae); } boolean foundBase = false; Iterator it; try { it = CRL_UTIL.findCRLs(baseSelect, paramsPKIX).iterator(); } catch (AnnotatedException ae) { ErrorBundle msg = new ErrorBundle(RESOURCE_NAME,"CertPathReviewer.crlExtractionError"); throw new CertPathReviewerException(msg,ae); } while (it.hasNext()) { X509CRL base = (X509CRL)it.next(); ASN1Primitive baseIdp; try { baseIdp = getExtensionValue(base, ISSUING_DISTRIBUTION_POINT); } catch (AnnotatedException ae) { ErrorBundle msg = new ErrorBundle(RESOURCE_NAME,"CertPathReviewer.distrPtExtError"); throw new CertPathReviewerException(msg,ae); } if (idp == null) { if (baseIdp == null) { foundBase = true; break; } } else { if (idp.equals(baseIdp)) { foundBase = true; break; } } } if (!foundBase) { ErrorBundle msg = new ErrorBundle(RESOURCE_NAME,"CertPathReviewer.noBaseCRL"); throw new CertPathReviewerException(msg); } } if (idp != null) { IssuingDistributionPoint p = IssuingDistributionPoint.getInstance(idp); BasicConstraints bc = null; try { bc = BasicConstraints.getInstance(getExtensionValue(cert, BASIC_CONSTRAINTS)); } catch (AnnotatedException ae) { ErrorBundle msg = new ErrorBundle(RESOURCE_NAME,"CertPathReviewer.crlBCExtError"); throw new CertPathReviewerException(msg,ae); } if (p.onlyContainsUserCerts() && (bc != null && bc.isCA())) { ErrorBundle msg = new ErrorBundle(RESOURCE_NAME,"CertPathReviewer.crlOnlyUserCert"); throw new CertPathReviewerException(msg); } if (p.onlyContainsCACerts() && (bc == null || !bc.isCA())) { ErrorBundle msg = new ErrorBundle(RESOURCE_NAME,"CertPathReviewer.crlOnlyCaCert"); throw new CertPathReviewerException(msg); } if (p.onlyContainsAttributeCerts()) { ErrorBundle msg = new ErrorBundle(RESOURCE_NAME,"CertPathReviewer.crlOnlyAttrCert"); throw new CertPathReviewerException(msg); } } } if (!validCrlFound) { ErrorBundle msg = new ErrorBundle(RESOURCE_NAME,"CertPathReviewer.noValidCrlFound"); throw new CertPathReviewerException(msg); } } protected Vector getCRLDistUrls(CRLDistPoint crlDistPoints) { Vector urls = new Vector(); if (crlDistPoints != null) { DistributionPoint[] distPoints = crlDistPoints.getDistributionPoints(); for (int i = 0; i < distPoints.length; i++) { DistributionPointName dp_name = distPoints[i].getDistributionPoint(); if (dp_name.getType() == DistributionPointName.FULL_NAME) { GeneralName[] generalNames = GeneralNames.getInstance(dp_name.getName()).getNames(); for (int j = 0; j < generalNames.length; j++) { if (generalNames[j].getTagNo() == GeneralName.uniformResourceIdentifier) { String url = ((DERIA5String) generalNames[j].getName()).getString(); urls.add(url); } } } } } return urls; } protected Vector getOCSPUrls(AuthorityInformationAccess authInfoAccess) { Vector urls = new Vector(); if (authInfoAccess != null) { AccessDescription[] ads = authInfoAccess.getAccessDescriptions(); for (int i = 0; i < ads.length; i++) { if (ads[i].getAccessMethod().equals(AccessDescription.id_ad_ocsp)) { GeneralName name = ads[i].getAccessLocation(); if (name.getTagNo() == GeneralName.uniformResourceIdentifier) { String url = ((DERIA5String) name.getName()).getString(); urls.add(url); } } } } return urls; } private X509CRL getCRL(String location) throws CertPathReviewerException { X509CRL result = null; try { URL url = new URL(location); if (url.getProtocol().equals("http") || url.getProtocol().equals("https")) { HttpURLConnection conn = (HttpURLConnection) url.openConnection(); conn.setUseCaches(false); //conn.setConnectTimeout(2000); conn.setDoInput(true); conn.connect(); if (conn.getResponseCode() == HttpURLConnection.HTTP_OK) { CertificateFactory cf = CertificateFactory.getInstance("X.509","BC"); result = (X509CRL) cf.generateCRL(conn.getInputStream()); } else { throw new Exception(conn.getResponseMessage()); } } } catch (Exception e) { ErrorBundle msg = new ErrorBundle(RESOURCE_NAME, "CertPathReviewer.loadCrlDistPointError", new Object[] {new UntrustedInput(location), e.getMessage(),e,e.getClass().getName()}); throw new CertPathReviewerException(msg); } return result; } protected Collection getTrustAnchors(X509Certificate cert, Set trustanchors) throws CertPathReviewerException { Collection trustColl = new ArrayList(); Iterator it = trustanchors.iterator(); X509CertSelector certSelectX509 = new X509CertSelector(); try { certSelectX509.setSubject(getEncodedIssuerPrincipal(cert).getEncoded()); byte[] ext = cert.getExtensionValue(X509Extensions.AuthorityKeyIdentifier.getId()); if (ext != null) { ASN1OctetString oct = (ASN1OctetString)ASN1Primitive.fromByteArray(ext); AuthorityKeyIdentifier authID = AuthorityKeyIdentifier.getInstance(ASN1Primitive.fromByteArray(oct.getOctets())); certSelectX509.setSerialNumber(authID.getAuthorityCertSerialNumber()); byte[] keyID = authID.getKeyIdentifier(); if (keyID != null) { certSelectX509.setSubjectKeyIdentifier(new DEROctetString(keyID).getEncoded()); } } } catch (IOException ex) { ErrorBundle msg = new ErrorBundle(RESOURCE_NAME,"CertPathReviewer.trustAnchorIssuerError"); throw new CertPathReviewerException(msg); } while (it.hasNext()) { TrustAnchor trust = (TrustAnchor) it.next(); if (trust.getTrustedCert() != null) { if (certSelectX509.match(trust.getTrustedCert())) { trustColl.add(trust); } } else if (trust.getCAName() != null && trust.getCAPublicKey() != null) { X500Principal certIssuer = getEncodedIssuerPrincipal(cert); X500Principal caName = new X500Principal(trust.getCAName()); if (certIssuer.equals(caName)) { trustColl.add(trust); } } } return trustColl; } } bouncycastle-1.49.orig/src/org/bouncycastle/x509/X509CRLStoreSelector.java0000644000175000017500000002431210617033353025601 0ustar ebourgebourgpackage org.bouncycastle.x509; import org.bouncycastle.asn1.DERInteger; import org.bouncycastle.asn1.x509.X509Extensions; import org.bouncycastle.util.Arrays; import org.bouncycastle.util.Selector; import org.bouncycastle.x509.extension.X509ExtensionUtil; import java.io.IOException; import java.math.BigInteger; import java.security.cert.CRL; import java.security.cert.X509CRL; import java.security.cert.X509CRLSelector; /** * This class is a Selector implementation for X.509 certificate revocation * lists. * * @see org.bouncycastle.util.Selector * @see org.bouncycastle.x509.X509Store * @see org.bouncycastle.jce.provider.X509StoreCRLCollection */ public class X509CRLStoreSelector extends X509CRLSelector implements Selector { private boolean deltaCRLIndicator = false; private boolean completeCRLEnabled = false; private BigInteger maxBaseCRLNumber = null; private byte[] issuingDistributionPoint = null; private boolean issuingDistributionPointEnabled = false; private X509AttributeCertificate attrCertChecking; /** * Returns if the issuing distribution point criteria should be applied. * Defaults to false. *

    * You may also set the issuing distribution point criteria if not a missing * issuing distribution point should be assumed. * * @return Returns if the issuing distribution point check is enabled. */ public boolean isIssuingDistributionPointEnabled() { return issuingDistributionPointEnabled; } /** * Enables or disables the issuing distribution point check. * * @param issuingDistributionPointEnabled true to enable the * issuing distribution point check. */ public void setIssuingDistributionPointEnabled( boolean issuingDistributionPointEnabled) { this.issuingDistributionPointEnabled = issuingDistributionPointEnabled; } /** * Sets the attribute certificate being checked. This is not a criterion. * Rather, it is optional information that may help a {@link X509Store} find * CRLs that would be relevant when checking revocation for the specified * attribute certificate. If null is specified, then no such * optional information is provided. * * @param attrCert the X509AttributeCertificate being checked (or * null) * @see #getAttrCertificateChecking() */ public void setAttrCertificateChecking(X509AttributeCertificate attrCert) { attrCertChecking = attrCert; } /** * Returns the attribute certificate being checked. * * @return Returns the attribute certificate being checked. * @see #setAttrCertificateChecking(X509AttributeCertificate) */ public X509AttributeCertificate getAttrCertificateChecking() { return attrCertChecking; } public boolean match(Object obj) { if (!(obj instanceof X509CRL)) { return false; } X509CRL crl = (X509CRL)obj; DERInteger dci = null; try { byte[] bytes = crl .getExtensionValue(X509Extensions.DeltaCRLIndicator.getId()); if (bytes != null) { dci = DERInteger.getInstance(X509ExtensionUtil .fromExtensionValue(bytes)); } } catch (Exception e) { return false; } if (isDeltaCRLIndicatorEnabled()) { if (dci == null) { return false; } } if (isCompleteCRLEnabled()) { if (dci != null) { return false; } } if (dci != null) { if (maxBaseCRLNumber != null) { if (dci.getPositiveValue().compareTo(maxBaseCRLNumber) == 1) { return false; } } } if (issuingDistributionPointEnabled) { byte[] idp = crl .getExtensionValue(X509Extensions.IssuingDistributionPoint .getId()); if (issuingDistributionPoint == null) { if (idp != null) { return false; } } else { if (!Arrays.areEqual(idp, issuingDistributionPoint)) { return false; } } } return super.match((X509CRL)obj); } public boolean match(CRL crl) { return match((Object)crl); } /** * Returns if this selector must match CRLs with the delta CRL indicator * extension set. Defaults to false. * * @return Returns true if only CRLs with the delta CRL * indicator extension are selected. */ public boolean isDeltaCRLIndicatorEnabled() { return deltaCRLIndicator; } /** * If this is set to true the CRL reported contains the delta * CRL indicator CRL extension. *

    * {@link #setCompleteCRLEnabled(boolean)} and * {@link #setDeltaCRLIndicatorEnabled(boolean)} excluded each other. * * @param deltaCRLIndicator true if the delta CRL indicator * extension must be in the CRL. */ public void setDeltaCRLIndicatorEnabled(boolean deltaCRLIndicator) { this.deltaCRLIndicator = deltaCRLIndicator; } /** * Returns an instance of this from a X509CRLSelector. * * @param selector A X509CRLSelector instance. * @return An instance of an X509CRLStoreSelector. * @exception IllegalArgumentException if selector is null or creation * fails. */ public static X509CRLStoreSelector getInstance(X509CRLSelector selector) { if (selector == null) { throw new IllegalArgumentException( "cannot create from null selector"); } X509CRLStoreSelector cs = new X509CRLStoreSelector(); cs.setCertificateChecking(selector.getCertificateChecking()); cs.setDateAndTime(selector.getDateAndTime()); try { cs.setIssuerNames(selector.getIssuerNames()); } catch (IOException e) { // cannot happen throw new IllegalArgumentException(e.getMessage()); } cs.setIssuers(selector.getIssuers()); cs.setMaxCRLNumber(selector.getMaxCRL()); cs.setMinCRLNumber(selector.getMinCRL()); return cs; } public Object clone() { X509CRLStoreSelector sel = X509CRLStoreSelector.getInstance(this); sel.deltaCRLIndicator = deltaCRLIndicator; sel.completeCRLEnabled = completeCRLEnabled; sel.maxBaseCRLNumber = maxBaseCRLNumber; sel.attrCertChecking = attrCertChecking; sel.issuingDistributionPointEnabled = issuingDistributionPointEnabled; sel.issuingDistributionPoint = Arrays.clone(issuingDistributionPoint); return sel; } /** * If true only complete CRLs are returned. Defaults to * false. * * @return true if only complete CRLs are returned. */ public boolean isCompleteCRLEnabled() { return completeCRLEnabled; } /** * If set to true only complete CRLs are returned. *

    * {@link #setCompleteCRLEnabled(boolean)} and * {@link #setDeltaCRLIndicatorEnabled(boolean)} excluded each other. * * @param completeCRLEnabled true if only complete CRLs * should be returned. */ public void setCompleteCRLEnabled(boolean completeCRLEnabled) { this.completeCRLEnabled = completeCRLEnabled; } /** * Get the maximum base CRL number. Defaults to null. * * @return Returns the maximum base CRL number. * @see #setMaxBaseCRLNumber(BigInteger) */ public BigInteger getMaxBaseCRLNumber() { return maxBaseCRLNumber; } /** * Sets the maximum base CRL number. Setting to null disables * this cheack. *

    * This is only meaningful for delta CRLs. Complete CRLs must have a CRL * number which is greater or equal than the base number of the * corresponding CRL. * * @param maxBaseCRLNumber The maximum base CRL number to set. */ public void setMaxBaseCRLNumber(BigInteger maxBaseCRLNumber) { this.maxBaseCRLNumber = maxBaseCRLNumber; } /** * Returns the issuing distribution point. Defaults to null, * which is a missing issuing distribution point extension. *

    * The internal byte array is cloned before it is returned. *

    * The criteria must be enable with * {@link #setIssuingDistributionPointEnabled(boolean)}. * * @return Returns the issuing distribution point. * @see #setIssuingDistributionPoint(byte[]) */ public byte[] getIssuingDistributionPoint() { return Arrays.clone(issuingDistributionPoint); } /** * Sets the issuing distribution point. *

    * The issuing distribution point extension is a CRL extension which * identifies the scope and the distribution point of a CRL. The scope * contains among others information about revocation reasons contained in * the CRL. Delta CRLs and complete CRLs must have matching issuing * distribution points. *

    * The byte array is cloned to protect against subsequent modifications. *

    * You must also enable or disable this criteria with * {@link #setIssuingDistributionPointEnabled(boolean)}. * * @param issuingDistributionPoint The issuing distribution point to set. * This is the DER encoded OCTET STRING extension value. * @see #getIssuingDistributionPoint() */ public void setIssuingDistributionPoint(byte[] issuingDistributionPoint) { this.issuingDistributionPoint = Arrays.clone(issuingDistributionPoint); } } bouncycastle-1.49.orig/src/org/bouncycastle/x509/X509CertStoreSelector.java0000644000175000017500000000555511144506355026071 0ustar ebourgebourgpackage org.bouncycastle.x509; import org.bouncycastle.util.Selector; import java.io.IOException; import java.security.cert.Certificate; import java.security.cert.X509CertSelector; import java.security.cert.X509Certificate; /** * This class is a Selector implementation for X.509 certificates. * * @see org.bouncycastle.util.Selector * @see org.bouncycastle.x509.X509Store * @see org.bouncycastle.jce.provider.X509StoreCertCollection */ public class X509CertStoreSelector extends X509CertSelector implements Selector { public boolean match(Object obj) { if (!(obj instanceof X509Certificate)) { return false; } X509Certificate other = (X509Certificate)obj; return super.match(other); } public boolean match(Certificate cert) { return match((Object)cert); } public Object clone() { X509CertStoreSelector selector = (X509CertStoreSelector)super.clone(); return selector; } /** * Returns an instance of this from a X509CertSelector. * * @param selector A X509CertSelector instance. * @return An instance of an X509CertStoreSelector. * @exception IllegalArgumentException if selector is null or creation fails. */ public static X509CertStoreSelector getInstance(X509CertSelector selector) { if (selector == null) { throw new IllegalArgumentException("cannot create from null selector"); } X509CertStoreSelector cs = new X509CertStoreSelector(); cs.setAuthorityKeyIdentifier(selector.getAuthorityKeyIdentifier()); cs.setBasicConstraints(selector.getBasicConstraints()); cs.setCertificate(selector.getCertificate()); cs.setCertificateValid(selector.getCertificateValid()); cs.setMatchAllSubjectAltNames(selector.getMatchAllSubjectAltNames()); try { cs.setPathToNames(selector.getPathToNames()); cs.setExtendedKeyUsage(selector.getExtendedKeyUsage()); cs.setNameConstraints(selector.getNameConstraints()); cs.setPolicy(selector.getPolicy()); cs.setSubjectPublicKeyAlgID(selector.getSubjectPublicKeyAlgID()); cs.setSubjectAlternativeNames(selector.getSubjectAlternativeNames()); } catch (IOException e) { throw new IllegalArgumentException("error in passed in selector: " + e); } cs.setIssuer(selector.getIssuer()); cs.setKeyUsage(selector.getKeyUsage()); cs.setPrivateKeyValid(selector.getPrivateKeyValid()); cs.setSerialNumber(selector.getSerialNumber()); cs.setSubject(selector.getSubject()); cs.setSubjectKeyIdentifier(selector.getSubjectKeyIdentifier()); cs.setSubjectPublicKey(selector.getSubjectPublicKey()); return cs; } } bouncycastle-1.49.orig/src/org/bouncycastle/x509/X509StoreParameters.java0000644000175000017500000000011110522776714025564 0ustar ebourgebourgpackage org.bouncycastle.x509; public interface X509StoreParameters { } bouncycastle-1.49.orig/src/org/bouncycastle/x509/X509CertPairStoreSelector.java0000644000175000017500000000767010552603061026677 0ustar ebourgebourgpackage org.bouncycastle.x509; import org.bouncycastle.util.Selector; /** * This class is an Selector like implementation to select * certificates pairs, which are e.g. used for cross certificates. The set of * criteria is given from two * {@link org.bouncycastle.x509.X509CertStoreSelector}s which must be both * matched. * * @see org.bouncycastle.x509.X509AttributeCertificate * @see org.bouncycastle.x509.X509Store */ public class X509CertPairStoreSelector implements Selector { private X509CertStoreSelector forwardSelector; private X509CertStoreSelector reverseSelector; private X509CertificatePair certPair; public X509CertPairStoreSelector() { } /** * Returns the certificate pair which is used for testing on equality. * * @return Returns the certificate pair which is checked. */ public X509CertificatePair getCertPair() { return certPair; } /** * Set the certificate pair which is used for testing on equality. * * @param certPair The certPairChecking to set. */ public void setCertPair(X509CertificatePair certPair) { this.certPair = certPair; } /** * @param forwardSelector The certificate selector for the forward part in * the pair. */ public void setForwardSelector(X509CertStoreSelector forwardSelector) { this.forwardSelector = forwardSelector; } /** * @param reverseSelector The certificate selector for the reverse part in * the pair. */ public void setReverseSelector(X509CertStoreSelector reverseSelector) { this.reverseSelector = reverseSelector; } /** * Returns a clone of this selector. * * @return A clone of this selector. * @see java.lang.Object#clone() */ public Object clone() { X509CertPairStoreSelector cln = new X509CertPairStoreSelector(); cln.certPair = certPair; if (forwardSelector != null) { cln.setForwardSelector((X509CertStoreSelector) forwardSelector .clone()); } if (reverseSelector != null) { cln.setReverseSelector((X509CertStoreSelector) reverseSelector .clone()); } return cln; } /** * Decides if the given certificate pair should be selected. If * obj is not a {@link X509CertificatePair} this method * returns false. * * @param obj The {@link X509CertificatePair} which should be tested. * @return true if the object matches this selector. */ public boolean match(Object obj) { try { if (!(obj instanceof X509CertificatePair)) { return false; } X509CertificatePair pair = (X509CertificatePair)obj; if (forwardSelector != null && !forwardSelector.match((Object)pair.getForward())) { return false; } if (reverseSelector != null && !reverseSelector.match((Object)pair.getReverse())) { return false; } if (certPair != null) { return certPair.equals(obj); } return true; } catch (Exception e) { return false; } } /** * Returns the certicate selector for the forward part. * * @return Returns the certicate selector for the forward part. */ public X509CertStoreSelector getForwardSelector() { return forwardSelector; } /** * Returns the certicate selector for the reverse part. * * @return Returns the reverse selector for teh reverse part. */ public X509CertStoreSelector getReverseSelector() { return reverseSelector; } } bouncycastle-1.49.orig/src/org/bouncycastle/x509/ExtendedPKIXParameters.java0000644000175000017500000005175611222021271026336 0ustar ebourgebourgpackage org.bouncycastle.x509; import org.bouncycastle.util.Selector; import org.bouncycastle.util.Store; import java.security.InvalidAlgorithmParameterException; import java.security.cert.CertSelector; import java.security.cert.CertStore; import java.security.cert.PKIXParameters; import java.security.cert.TrustAnchor; import java.security.cert.X509CertSelector; import java.util.ArrayList; import java.util.Collections; import java.util.HashSet; import java.util.Iterator; import java.util.List; import java.util.Set; /** * This class extends the PKIXParameters with a validity model parameter. */ public class ExtendedPKIXParameters extends PKIXParameters { private List stores; private Selector selector; private boolean additionalLocationsEnabled; private List additionalStores; private Set trustedACIssuers; private Set necessaryACAttributes; private Set prohibitedACAttributes; private Set attrCertCheckers; /** * Creates an instance of PKIXParameters with the specified * Set of most-trusted CAs. Each element of the set is a * {@link TrustAnchor TrustAnchor}.

    Note that the Set * is copied to protect against subsequent modifications. * * @param trustAnchors a Set of TrustAnchors * @throws InvalidAlgorithmParameterException if the specified * Set is empty. * @throws NullPointerException if the specified Set is * null * @throws ClassCastException if any of the elements in the Set * is not of type java.security.cert.TrustAnchor */ public ExtendedPKIXParameters(Set trustAnchors) throws InvalidAlgorithmParameterException { super(trustAnchors); stores = new ArrayList(); additionalStores = new ArrayList(); trustedACIssuers = new HashSet(); necessaryACAttributes = new HashSet(); prohibitedACAttributes = new HashSet(); attrCertCheckers = new HashSet(); } /** * Returns an instance with the parameters of a given * PKIXParameters object. * * @param pkixParams The given PKIXParameters * @return an extended PKIX params object */ public static ExtendedPKIXParameters getInstance(PKIXParameters pkixParams) { ExtendedPKIXParameters params; try { params = new ExtendedPKIXParameters(pkixParams.getTrustAnchors()); } catch (Exception e) { // cannot happen throw new RuntimeException(e.getMessage()); } params.setParams(pkixParams); return params; } /** * Method to support clone() under J2ME. * super.clone() does not exist and fields are not copied. * * @param params Parameters to set. If this are * ExtendedPKIXParameters they are copied to. */ protected void setParams(PKIXParameters params) { setDate(params.getDate()); setCertPathCheckers(params.getCertPathCheckers()); setCertStores(params.getCertStores()); setAnyPolicyInhibited(params.isAnyPolicyInhibited()); setExplicitPolicyRequired(params.isExplicitPolicyRequired()); setPolicyMappingInhibited(params.isPolicyMappingInhibited()); setRevocationEnabled(params.isRevocationEnabled()); setInitialPolicies(params.getInitialPolicies()); setPolicyQualifiersRejected(params.getPolicyQualifiersRejected()); setSigProvider(params.getSigProvider()); setTargetCertConstraints(params.getTargetCertConstraints()); try { setTrustAnchors(params.getTrustAnchors()); } catch (Exception e) { // cannot happen throw new RuntimeException(e.getMessage()); } if (params instanceof ExtendedPKIXParameters) { ExtendedPKIXParameters _params = (ExtendedPKIXParameters) params; validityModel = _params.validityModel; useDeltas = _params.useDeltas; additionalLocationsEnabled = _params.additionalLocationsEnabled; selector = _params.selector == null ? null : (Selector) _params.selector.clone(); stores = new ArrayList(_params.stores); additionalStores = new ArrayList(_params.additionalStores); trustedACIssuers = new HashSet(_params.trustedACIssuers); prohibitedACAttributes = new HashSet(_params.prohibitedACAttributes); necessaryACAttributes = new HashSet(_params.necessaryACAttributes); attrCertCheckers = new HashSet(_params.attrCertCheckers); } } /** * This is the default PKIX validity model. Actually there are two variants * of this: The PKIX model and the modified PKIX model. The PKIX model * verifies that all involved certificates must have been valid at the * current time. The modified PKIX model verifies that all involved * certificates were valid at the signing time. Both are indirectly choosen * with the {@link PKIXParameters#setDate(java.util.Date)} method, so this * methods sets the Date when all certificates must have been * valid. */ public static final int PKIX_VALIDITY_MODEL = 0; /** * This model uses the following validity model. Each certificate must have * been valid at the moment where is was used. That means the end * certificate must have been valid at the time the signature was done. The * CA certificate which signed the end certificate must have been valid, * when the end certificate was signed. The CA (or Root CA) certificate must * have been valid, when the CA certificate was signed and so on. So the * {@link PKIXParameters#setDate(java.util.Date)} method sets the time, when * the end certificate must have been valid.

    It is used e.g. * in the German signature law. */ public static final int CHAIN_VALIDITY_MODEL = 1; private int validityModel = PKIX_VALIDITY_MODEL; private boolean useDeltas = false; /** * Defaults to false. * * @return Returns if delta CRLs should be used. */ public boolean isUseDeltasEnabled() { return useDeltas; } /** * Sets if delta CRLs should be used for checking the revocation status. * * @param useDeltas true if delta CRLs should be used. */ public void setUseDeltasEnabled(boolean useDeltas) { this.useDeltas = useDeltas; } /** * @return Returns the validity model. * @see #CHAIN_VALIDITY_MODEL * @see #PKIX_VALIDITY_MODEL */ public int getValidityModel() { return validityModel; } /** * Sets the Java CertStore to this extended PKIX parameters. * * @throws ClassCastException if an element of stores is not * a CertStore. */ public void setCertStores(List stores) { if (stores != null) { Iterator it = stores.iterator(); while (it.hasNext()) { addCertStore((CertStore)it.next()); } } } /** * Sets the Bouncy Castle Stores for finding CRLs, certificates, attribute * certificates or cross certificates. *

    * The List is cloned. * * @param stores A list of stores to use. * @see #getStores * @throws ClassCastException if an element of stores is not * a {@link Store}. */ public void setStores(List stores) { if (stores == null) { this.stores = new ArrayList(); } else { for (Iterator i = stores.iterator(); i.hasNext();) { if (!(i.next() instanceof Store)) { throw new ClassCastException( "All elements of list must be " + "of type org.bouncycastle.util.Store."); } } this.stores = new ArrayList(stores); } } /** * Adds a Bouncy Castle {@link Store} to find CRLs, certificates, attribute * certificates or cross certificates. *

    * This method should be used to add local stores, like collection based * X.509 stores, if available. Local stores should be considered first, * before trying to use additional (remote) locations, because they do not * need possible additional network traffic. *

    * If store is null it is ignored. * * @param store The store to add. * @see #getStores */ public void addStore(Store store) { if (store != null) { stores.add(store); } } /** * Adds an additional Bouncy Castle {@link Store} to find CRLs, certificates, * attribute certificates or cross certificates. *

    * You should not use this method. This method is used for adding additional * X.509 stores, which are used to add (remote) locations, e.g. LDAP, found * during X.509 object processing, e.g. in certificates or CRLs. This method * is used in PKIX certification path processing. *

    * If store is null it is ignored. * * @param store The store to add. * @see #getStores() */ public void addAdditionalStore(Store store) { if (store != null) { additionalStores.add(store); } } /** * @deprecated */ public void addAddionalStore(Store store) { addAdditionalStore(store); } /** * Returns an immutable List of additional Bouncy Castle * Stores used for finding CRLs, certificates, attribute * certificates or cross certificates. * * @return an immutable List of additional Bouncy Castle * Stores. Never null. * * @see #addAdditionalStore(Store) */ public List getAdditionalStores() { return Collections.unmodifiableList(additionalStores); } /** * Returns an immutable List of Bouncy Castle * Stores used for finding CRLs, certificates, attribute * certificates or cross certificates. * * @return an immutable List of Bouncy Castle * Stores. Never null. * * @see #setStores(List) */ public List getStores() { return Collections.unmodifiableList(new ArrayList(stores)); } /** * @param validityModel The validity model to set. * @see #CHAIN_VALIDITY_MODEL * @see #PKIX_VALIDITY_MODEL */ public void setValidityModel(int validityModel) { this.validityModel = validityModel; } public Object clone() { ExtendedPKIXParameters params; try { params = new ExtendedPKIXParameters(getTrustAnchors()); } catch (Exception e) { // cannot happen throw new RuntimeException(e.getMessage()); } params.setParams(this); return params; } /** * Returns if additional {@link X509Store}s for locations like LDAP found * in certificates or CRLs should be used. * * @return Returns true if additional stores are used. */ public boolean isAdditionalLocationsEnabled() { return additionalLocationsEnabled; } /** * Sets if additional {@link X509Store}s for locations like LDAP found in * certificates or CRLs should be used. * * @param enabled true if additional stores are used. */ public void setAdditionalLocationsEnabled(boolean enabled) { additionalLocationsEnabled = enabled; } /** * Returns the required constraints on the target certificate or attribute * certificate. The constraints are returned as an instance of * Selector. If null, no constraints are * defined. * *

    * The target certificate in a PKIX path may be a certificate or an * attribute certificate. *

    * Note that the Selector returned is cloned to protect * against subsequent modifications. * * @return a Selector specifying the constraints on the * target certificate or attribute certificate (or null) * @see #setTargetConstraints * @see X509CertStoreSelector * @see X509AttributeCertStoreSelector */ public Selector getTargetConstraints() { if (selector != null) { return (Selector) selector.clone(); } else { return null; } } /** * Sets the required constraints on the target certificate or attribute * certificate. The constraints are specified as an instance of * Selector. If null, no constraints are * defined. *

    * The target certificate in a PKIX path may be a certificate or an * attribute certificate. *

    * Note that the Selector specified is cloned to protect * against subsequent modifications. * * @param selector a Selector specifying the constraints on * the target certificate or attribute certificate (or * null) * @see #getTargetConstraints * @see X509CertStoreSelector * @see X509AttributeCertStoreSelector */ public void setTargetConstraints(Selector selector) { if (selector != null) { this.selector = (Selector) selector.clone(); } else { this.selector = null; } } /** * Sets the required constraints on the target certificate. The constraints * are specified as an instance of X509CertSelector. If * null, no constraints are defined. * *

    * This method wraps the given X509CertSelector into a * X509CertStoreSelector. *

    * Note that the X509CertSelector specified is cloned to * protect against subsequent modifications. * * @param selector a X509CertSelector specifying the * constraints on the target certificate (or null) * @see #getTargetCertConstraints * @see X509CertStoreSelector */ public void setTargetCertConstraints(CertSelector selector) { super.setTargetCertConstraints(selector); if (selector != null) { this.selector = X509CertStoreSelector .getInstance((X509CertSelector) selector); } else { this.selector = null; } } /** * Returns the trusted attribute certificate issuers. If attribute * certificates is verified the trusted AC issuers must be set. *

    * The returned Set consists of TrustAnchors. *

    * The returned Set is immutable. Never null * * @return Returns an immutable set of the trusted AC issuers. */ public Set getTrustedACIssuers() { return Collections.unmodifiableSet(trustedACIssuers); } /** * Sets the trusted attribute certificate issuers. If attribute certificates * is verified the trusted AC issuers must be set. *

    * The trustedACIssuers must be a Set of * TrustAnchor *

    * The given set is cloned. * * @param trustedACIssuers The trusted AC issuers to set. Is never * null. * @throws ClassCastException if an element of stores is not * a TrustAnchor. */ public void setTrustedACIssuers(Set trustedACIssuers) { if (trustedACIssuers == null) { this.trustedACIssuers.clear(); return; } for (Iterator it = trustedACIssuers.iterator(); it.hasNext();) { if (!(it.next() instanceof TrustAnchor)) { throw new ClassCastException("All elements of set must be " + "of type " + TrustAnchor.class.getName() + "."); } } this.trustedACIssuers.clear(); this.trustedACIssuers.addAll(trustedACIssuers); } /** * Returns the neccessary attributes which must be contained in an attribute * certificate. *

    * The returned Set is immutable and contains * Strings with the OIDs. * * @return Returns the necessary AC attributes. */ public Set getNecessaryACAttributes() { return Collections.unmodifiableSet(necessaryACAttributes); } /** * Sets the neccessary which must be contained in an attribute certificate. *

    * The Set must contain Strings with the * OIDs. *

    * The set is cloned. * * @param necessaryACAttributes The necessary AC attributes to set. * @throws ClassCastException if an element of * necessaryACAttributes is not a * String. */ public void setNecessaryACAttributes(Set necessaryACAttributes) { if (necessaryACAttributes == null) { this.necessaryACAttributes.clear(); return; } for (Iterator it = necessaryACAttributes.iterator(); it.hasNext();) { if (!(it.next() instanceof String)) { throw new ClassCastException("All elements of set must be " + "of type String."); } } this.necessaryACAttributes.clear(); this.necessaryACAttributes.addAll(necessaryACAttributes); } /** * Returns the attribute certificates which are not allowed. *

    * The returned Set is immutable and contains * Strings with the OIDs. * * @return Returns the prohibited AC attributes. Is never null. */ public Set getProhibitedACAttributes() { return Collections.unmodifiableSet(prohibitedACAttributes); } /** * Sets the attribute certificates which are not allowed. *

    * The Set must contain Strings with the * OIDs. *

    * The set is cloned. * * @param prohibitedACAttributes The prohibited AC attributes to set. * @throws ClassCastException if an element of * prohibitedACAttributes is not a * String. */ public void setProhibitedACAttributes(Set prohibitedACAttributes) { if (prohibitedACAttributes == null) { this.prohibitedACAttributes.clear(); return; } for (Iterator it = prohibitedACAttributes.iterator(); it.hasNext();) { if (!(it.next() instanceof String)) { throw new ClassCastException("All elements of set must be " + "of type String."); } } this.prohibitedACAttributes.clear(); this.prohibitedACAttributes.addAll(prohibitedACAttributes); } /** * Returns the attribute certificate checker. The returned set contains * {@link PKIXAttrCertChecker}s and is immutable. * * @return Returns the attribute certificate checker. Is never * null. */ public Set getAttrCertCheckers() { return Collections.unmodifiableSet(attrCertCheckers); } /** * Sets the attribute certificate checkers. *

    * All elements in the Set must a {@link PKIXAttrCertChecker}. *

    * The given set is cloned. * * @param attrCertCheckers The attribute certificate checkers to set. Is * never null. * @throws ClassCastException if an element of attrCertCheckers * is not a PKIXAttrCertChecker. */ public void setAttrCertCheckers(Set attrCertCheckers) { if (attrCertCheckers == null) { this.attrCertCheckers.clear(); return; } for (Iterator it = attrCertCheckers.iterator(); it.hasNext();) { if (!(it.next() instanceof PKIXAttrCertChecker)) { throw new ClassCastException("All elements of set must be " + "of type " + PKIXAttrCertChecker.class.getName() + "."); } } this.attrCertCheckers.clear(); this.attrCertCheckers.addAll(attrCertCheckers); } } bouncycastle-1.49.orig/src/org/bouncycastle/x509/X509StreamParserSpi.java0000644000175000017500000000257110772037032025532 0ustar ebourgebourgpackage org.bouncycastle.x509; import org.bouncycastle.x509.util.StreamParsingException; import java.io.InputStream; import java.util.Collection; /** * This abstract class defines the service provider interface (SPI) for * X509StreamParser. * * @see org.bouncycastle.x509.X509StreamParser * */ public abstract class X509StreamParserSpi { /** * Initializes this stream parser with the input stream. * * @param in The input stream. */ public abstract void engineInit(InputStream in); /** * Returns the next X.509 object of the type of this SPI from the given * input stream. * * @return the next X.509 object in the stream or null if the * end of the stream is reached. * @exception StreamParsingException * if the object cannot be created from input stream. */ public abstract Object engineRead() throws StreamParsingException; /** * Returns all X.509 objects of the type of this SPI from * the given input stream. * * @return A collection of all X.509 objects in the input stream or * null if the end of the stream is reached. * @exception StreamParsingException * if an object cannot be created from input stream. */ public abstract Collection engineReadAll() throws StreamParsingException; } bouncycastle-1.49.orig/src/org/bouncycastle/x509/X509Util.java0000644000175000017500000003550112103437527023365 0ustar ebourgebourgpackage org.bouncycastle.x509; import java.io.IOException; import java.security.InvalidKeyException; import java.security.NoSuchAlgorithmException; import java.security.NoSuchProviderException; import java.security.PrivateKey; import java.security.Provider; import java.security.SecureRandom; import java.security.Security; import java.security.Signature; import java.security.SignatureException; import java.util.ArrayList; import java.util.Enumeration; import java.util.HashSet; import java.util.Hashtable; import java.util.Iterator; import java.util.List; import java.util.Set; import javax.security.auth.x500.X500Principal; import org.bouncycastle.asn1.ASN1Encodable; import org.bouncycastle.asn1.ASN1Encoding; import org.bouncycastle.asn1.ASN1Integer; import org.bouncycastle.asn1.DERNull; import org.bouncycastle.asn1.DERObjectIdentifier; import org.bouncycastle.asn1.cryptopro.CryptoProObjectIdentifiers; import org.bouncycastle.asn1.nist.NISTObjectIdentifiers; import org.bouncycastle.asn1.oiw.OIWObjectIdentifiers; import org.bouncycastle.asn1.pkcs.PKCSObjectIdentifiers; import org.bouncycastle.asn1.pkcs.RSASSAPSSparams; import org.bouncycastle.asn1.teletrust.TeleTrusTObjectIdentifiers; import org.bouncycastle.asn1.x509.AlgorithmIdentifier; import org.bouncycastle.asn1.x9.X9ObjectIdentifiers; import org.bouncycastle.jce.X509Principal; import org.bouncycastle.util.Strings; class X509Util { private static Hashtable algorithms = new Hashtable(); private static Hashtable params = new Hashtable(); private static Set noParams = new HashSet(); static { algorithms.put("MD2WITHRSAENCRYPTION", PKCSObjectIdentifiers.md2WithRSAEncryption); algorithms.put("MD2WITHRSA", PKCSObjectIdentifiers.md2WithRSAEncryption); algorithms.put("MD5WITHRSAENCRYPTION", PKCSObjectIdentifiers.md5WithRSAEncryption); algorithms.put("MD5WITHRSA", PKCSObjectIdentifiers.md5WithRSAEncryption); algorithms.put("SHA1WITHRSAENCRYPTION", PKCSObjectIdentifiers.sha1WithRSAEncryption); algorithms.put("SHA1WITHRSA", PKCSObjectIdentifiers.sha1WithRSAEncryption); algorithms.put("SHA224WITHRSAENCRYPTION", PKCSObjectIdentifiers.sha224WithRSAEncryption); algorithms.put("SHA224WITHRSA", PKCSObjectIdentifiers.sha224WithRSAEncryption); algorithms.put("SHA256WITHRSAENCRYPTION", PKCSObjectIdentifiers.sha256WithRSAEncryption); algorithms.put("SHA256WITHRSA", PKCSObjectIdentifiers.sha256WithRSAEncryption); algorithms.put("SHA384WITHRSAENCRYPTION", PKCSObjectIdentifiers.sha384WithRSAEncryption); algorithms.put("SHA384WITHRSA", PKCSObjectIdentifiers.sha384WithRSAEncryption); algorithms.put("SHA512WITHRSAENCRYPTION", PKCSObjectIdentifiers.sha512WithRSAEncryption); algorithms.put("SHA512WITHRSA", PKCSObjectIdentifiers.sha512WithRSAEncryption); algorithms.put("SHA1WITHRSAANDMGF1", PKCSObjectIdentifiers.id_RSASSA_PSS); algorithms.put("SHA224WITHRSAANDMGF1", PKCSObjectIdentifiers.id_RSASSA_PSS); algorithms.put("SHA256WITHRSAANDMGF1", PKCSObjectIdentifiers.id_RSASSA_PSS); algorithms.put("SHA384WITHRSAANDMGF1", PKCSObjectIdentifiers.id_RSASSA_PSS); algorithms.put("SHA512WITHRSAANDMGF1", PKCSObjectIdentifiers.id_RSASSA_PSS); algorithms.put("RIPEMD160WITHRSAENCRYPTION", TeleTrusTObjectIdentifiers.rsaSignatureWithripemd160); algorithms.put("RIPEMD160WITHRSA", TeleTrusTObjectIdentifiers.rsaSignatureWithripemd160); algorithms.put("RIPEMD128WITHRSAENCRYPTION", TeleTrusTObjectIdentifiers.rsaSignatureWithripemd128); algorithms.put("RIPEMD128WITHRSA", TeleTrusTObjectIdentifiers.rsaSignatureWithripemd128); algorithms.put("RIPEMD256WITHRSAENCRYPTION", TeleTrusTObjectIdentifiers.rsaSignatureWithripemd256); algorithms.put("RIPEMD256WITHRSA", TeleTrusTObjectIdentifiers.rsaSignatureWithripemd256); algorithms.put("SHA1WITHDSA", X9ObjectIdentifiers.id_dsa_with_sha1); algorithms.put("DSAWITHSHA1", X9ObjectIdentifiers.id_dsa_with_sha1); algorithms.put("SHA224WITHDSA", NISTObjectIdentifiers.dsa_with_sha224); algorithms.put("SHA256WITHDSA", NISTObjectIdentifiers.dsa_with_sha256); algorithms.put("SHA384WITHDSA", NISTObjectIdentifiers.dsa_with_sha384); algorithms.put("SHA512WITHDSA", NISTObjectIdentifiers.dsa_with_sha512); algorithms.put("SHA1WITHECDSA", X9ObjectIdentifiers.ecdsa_with_SHA1); algorithms.put("ECDSAWITHSHA1", X9ObjectIdentifiers.ecdsa_with_SHA1); algorithms.put("SHA224WITHECDSA", X9ObjectIdentifiers.ecdsa_with_SHA224); algorithms.put("SHA256WITHECDSA", X9ObjectIdentifiers.ecdsa_with_SHA256); algorithms.put("SHA384WITHECDSA", X9ObjectIdentifiers.ecdsa_with_SHA384); algorithms.put("SHA512WITHECDSA", X9ObjectIdentifiers.ecdsa_with_SHA512); algorithms.put("GOST3411WITHGOST3410", CryptoProObjectIdentifiers.gostR3411_94_with_gostR3410_94); algorithms.put("GOST3411WITHGOST3410-94", CryptoProObjectIdentifiers.gostR3411_94_with_gostR3410_94); algorithms.put("GOST3411WITHECGOST3410", CryptoProObjectIdentifiers.gostR3411_94_with_gostR3410_2001); algorithms.put("GOST3411WITHECGOST3410-2001", CryptoProObjectIdentifiers.gostR3411_94_with_gostR3410_2001); algorithms.put("GOST3411WITHGOST3410-2001", CryptoProObjectIdentifiers.gostR3411_94_with_gostR3410_2001); // // According to RFC 3279, the ASN.1 encoding SHALL (id-dsa-with-sha1) or MUST (ecdsa-with-SHA*) omit the parameters field. // The parameters field SHALL be NULL for RSA based signature algorithms. // noParams.add(X9ObjectIdentifiers.ecdsa_with_SHA1); noParams.add(X9ObjectIdentifiers.ecdsa_with_SHA224); noParams.add(X9ObjectIdentifiers.ecdsa_with_SHA256); noParams.add(X9ObjectIdentifiers.ecdsa_with_SHA384); noParams.add(X9ObjectIdentifiers.ecdsa_with_SHA512); noParams.add(X9ObjectIdentifiers.id_dsa_with_sha1); noParams.add(NISTObjectIdentifiers.dsa_with_sha224); noParams.add(NISTObjectIdentifiers.dsa_with_sha256); noParams.add(NISTObjectIdentifiers.dsa_with_sha384); noParams.add(NISTObjectIdentifiers.dsa_with_sha512); // // RFC 4491 // noParams.add(CryptoProObjectIdentifiers.gostR3411_94_with_gostR3410_94); noParams.add(CryptoProObjectIdentifiers.gostR3411_94_with_gostR3410_2001); // // explicit params // AlgorithmIdentifier sha1AlgId = new AlgorithmIdentifier(OIWObjectIdentifiers.idSHA1, DERNull.INSTANCE); params.put("SHA1WITHRSAANDMGF1", creatPSSParams(sha1AlgId, 20)); AlgorithmIdentifier sha224AlgId = new AlgorithmIdentifier(NISTObjectIdentifiers.id_sha224, DERNull.INSTANCE); params.put("SHA224WITHRSAANDMGF1", creatPSSParams(sha224AlgId, 28)); AlgorithmIdentifier sha256AlgId = new AlgorithmIdentifier(NISTObjectIdentifiers.id_sha256, DERNull.INSTANCE); params.put("SHA256WITHRSAANDMGF1", creatPSSParams(sha256AlgId, 32)); AlgorithmIdentifier sha384AlgId = new AlgorithmIdentifier(NISTObjectIdentifiers.id_sha384, DERNull.INSTANCE); params.put("SHA384WITHRSAANDMGF1", creatPSSParams(sha384AlgId, 48)); AlgorithmIdentifier sha512AlgId = new AlgorithmIdentifier(NISTObjectIdentifiers.id_sha512, DERNull.INSTANCE); params.put("SHA512WITHRSAANDMGF1", creatPSSParams(sha512AlgId, 64)); } private static RSASSAPSSparams creatPSSParams(AlgorithmIdentifier hashAlgId, int saltSize) { return new RSASSAPSSparams( hashAlgId, new AlgorithmIdentifier(PKCSObjectIdentifiers.id_mgf1, hashAlgId), new ASN1Integer(saltSize), new ASN1Integer(1)); } static DERObjectIdentifier getAlgorithmOID( String algorithmName) { algorithmName = Strings.toUpperCase(algorithmName); if (algorithms.containsKey(algorithmName)) { return (DERObjectIdentifier)algorithms.get(algorithmName); } return new DERObjectIdentifier(algorithmName); } static AlgorithmIdentifier getSigAlgID( DERObjectIdentifier sigOid, String algorithmName) { if (noParams.contains(sigOid)) { return new AlgorithmIdentifier(sigOid); } algorithmName = Strings.toUpperCase(algorithmName); if (params.containsKey(algorithmName)) { return new AlgorithmIdentifier(sigOid, (ASN1Encodable)params.get(algorithmName)); } else { return new AlgorithmIdentifier(sigOid, DERNull.INSTANCE); } } static Iterator getAlgNames() { Enumeration e = algorithms.keys(); List l = new ArrayList(); while (e.hasMoreElements()) { l.add(e.nextElement()); } return l.iterator(); } static Signature getSignatureInstance( String algorithm) throws NoSuchAlgorithmException { return Signature.getInstance(algorithm); } static Signature getSignatureInstance( String algorithm, String provider) throws NoSuchProviderException, NoSuchAlgorithmException { if (provider != null) { return Signature.getInstance(algorithm, provider); } else { return Signature.getInstance(algorithm); } } static byte[] calculateSignature( DERObjectIdentifier sigOid, String sigName, PrivateKey key, SecureRandom random, ASN1Encodable object) throws IOException, NoSuchAlgorithmException, InvalidKeyException, SignatureException { Signature sig; if (sigOid == null) { throw new IllegalStateException("no signature algorithm specified"); } sig = X509Util.getSignatureInstance(sigName); if (random != null) { sig.initSign(key, random); } else { sig.initSign(key); } sig.update(object.toASN1Primitive().getEncoded(ASN1Encoding.DER)); return sig.sign(); } static byte[] calculateSignature( DERObjectIdentifier sigOid, String sigName, String provider, PrivateKey key, SecureRandom random, ASN1Encodable object) throws IOException, NoSuchProviderException, NoSuchAlgorithmException, InvalidKeyException, SignatureException { Signature sig; if (sigOid == null) { throw new IllegalStateException("no signature algorithm specified"); } sig = X509Util.getSignatureInstance(sigName, provider); if (random != null) { sig.initSign(key, random); } else { sig.initSign(key); } sig.update(object.toASN1Primitive().getEncoded(ASN1Encoding.DER)); return sig.sign(); } static X509Principal convertPrincipal( X500Principal principal) { try { return new X509Principal(principal.getEncoded()); } catch (IOException e) { throw new IllegalArgumentException("cannot convert principal"); } } static class Implementation { Object engine; Provider provider; Implementation( Object engine, Provider provider) { this.engine = engine; this.provider = provider; } Object getEngine() { return engine; } Provider getProvider() { return provider; } } /** * see if we can find an algorithm (or its alias and what it represents) in * the property table for the given provider. */ static Implementation getImplementation( String baseName, String algorithm, Provider prov) throws NoSuchAlgorithmException { algorithm = Strings.toUpperCase(algorithm); String alias; while ((alias = prov.getProperty("Alg.Alias." + baseName + "." + algorithm)) != null) { algorithm = alias; } String className = prov.getProperty(baseName + "." + algorithm); if (className != null) { try { Class cls; ClassLoader clsLoader = prov.getClass().getClassLoader(); if (clsLoader != null) { cls = clsLoader.loadClass(className); } else { cls = Class.forName(className); } return new Implementation(cls.newInstance(), prov); } catch (ClassNotFoundException e) { throw new IllegalStateException( "algorithm " + algorithm + " in provider " + prov.getName() + " but no class \"" + className + "\" found!"); } catch (Exception e) { throw new IllegalStateException( "algorithm " + algorithm + " in provider " + prov.getName() + " but class \"" + className + "\" inaccessible!"); } } throw new NoSuchAlgorithmException("cannot find implementation " + algorithm + " for provider " + prov.getName()); } /** * return an implementation for a given algorithm/provider. * If the provider is null, we grab the first avalaible who has the required algorithm. */ static Implementation getImplementation( String baseName, String algorithm) throws NoSuchAlgorithmException { Provider[] prov = Security.getProviders(); // // search every provider looking for the algorithm we want. // for (int i = 0; i != prov.length; i++) { // // try case insensitive // Implementation imp = getImplementation(baseName, Strings.toUpperCase(algorithm), prov[i]); if (imp != null) { return imp; } try { imp = getImplementation(baseName, algorithm, prov[i]); } catch (NoSuchAlgorithmException e) { // continue } } throw new NoSuchAlgorithmException("cannot find implementation " + algorithm); } static Provider getProvider(String provider) throws NoSuchProviderException { Provider prov = Security.getProvider(provider); if (prov == null) { throw new NoSuchProviderException("Provider " + provider + " not found"); } return prov; } } bouncycastle-1.49.orig/src/org/bouncycastle/x509/X509V2AttributeCertificateGenerator.java0000644000175000017500000002007311737210072030627 0ustar ebourgebourgpackage org.bouncycastle.x509; import java.io.IOException; import java.math.BigInteger; import java.security.GeneralSecurityException; import java.security.InvalidKeyException; import java.security.NoSuchAlgorithmException; import java.security.NoSuchProviderException; import java.security.PrivateKey; import java.security.SecureRandom; import java.security.SignatureException; import java.security.cert.CertificateEncodingException; import java.util.Date; import java.util.Iterator; import org.bouncycastle.asn1.ASN1Encodable; import org.bouncycastle.asn1.ASN1EncodableVector; import org.bouncycastle.asn1.ASN1GeneralizedTime; import org.bouncycastle.asn1.ASN1Integer; import org.bouncycastle.asn1.ASN1ObjectIdentifier; import org.bouncycastle.asn1.DERBitString; import org.bouncycastle.asn1.DERObjectIdentifier; import org.bouncycastle.asn1.DERSequence; import org.bouncycastle.asn1.x509.AlgorithmIdentifier; import org.bouncycastle.asn1.x509.AttCertIssuer; import org.bouncycastle.asn1.x509.Attribute; import org.bouncycastle.asn1.x509.AttributeCertificate; import org.bouncycastle.asn1.x509.AttributeCertificateInfo; import org.bouncycastle.asn1.x509.V2AttributeCertificateInfoGenerator; import org.bouncycastle.asn1.x509.X509ExtensionsGenerator; /** * class to produce an X.509 Version 2 AttributeCertificate. * @deprecated use org.bouncycastle.cert.X509v2AttributeCertificateBuilder */ public class X509V2AttributeCertificateGenerator { private V2AttributeCertificateInfoGenerator acInfoGen; private DERObjectIdentifier sigOID; private AlgorithmIdentifier sigAlgId; private String signatureAlgorithm; private X509ExtensionsGenerator extGenerator; public X509V2AttributeCertificateGenerator() { acInfoGen = new V2AttributeCertificateInfoGenerator(); extGenerator = new X509ExtensionsGenerator(); } /** * reset the generator */ public void reset() { acInfoGen = new V2AttributeCertificateInfoGenerator(); extGenerator.reset(); } /** * Set the Holder of this Attribute Certificate */ public void setHolder( AttributeCertificateHolder holder) { acInfoGen.setHolder(holder.holder); } /** * Set the issuer */ public void setIssuer( AttributeCertificateIssuer issuer) { acInfoGen.setIssuer(AttCertIssuer.getInstance(issuer.form)); } /** * set the serial number for the certificate. */ public void setSerialNumber( BigInteger serialNumber) { acInfoGen.setSerialNumber(new ASN1Integer(serialNumber)); } public void setNotBefore( Date date) { acInfoGen.setStartDate(new ASN1GeneralizedTime(date)); } public void setNotAfter( Date date) { acInfoGen.setEndDate(new ASN1GeneralizedTime(date)); } /** * Set the signature algorithm. This can be either a name or an OID, names * are treated as case insensitive. * * @param signatureAlgorithm string representation of the algorithm name. */ public void setSignatureAlgorithm( String signatureAlgorithm) { this.signatureAlgorithm = signatureAlgorithm; try { sigOID = X509Util.getAlgorithmOID(signatureAlgorithm); } catch (Exception e) { throw new IllegalArgumentException("Unknown signature type requested"); } sigAlgId = X509Util.getSigAlgID(sigOID, signatureAlgorithm); acInfoGen.setSignature(sigAlgId); } /** * add an attribute */ public void addAttribute( X509Attribute attribute) { acInfoGen.addAttribute(Attribute.getInstance(attribute.toASN1Object())); } public void setIssuerUniqueId( boolean[] iui) { // [TODO] convert boolean array to bit string //acInfoGen.setIssuerUniqueID(iui); throw new RuntimeException("not implemented (yet)"); } /** * add a given extension field for the standard extensions tag * @throws IOException */ public void addExtension( String oid, boolean critical, ASN1Encodable value) throws IOException { extGenerator.addExtension(new ASN1ObjectIdentifier(oid), critical, value); } /** * add a given extension field for the standard extensions tag * The value parameter becomes the contents of the octet string associated * with the extension. */ public void addExtension( String oid, boolean critical, byte[] value) { extGenerator.addExtension(new ASN1ObjectIdentifier(oid), critical, value); } /** * generate an X509 certificate, based on the current issuer and subject, * using the passed in provider for the signing. * @deprecated use generate() */ public X509AttributeCertificate generateCertificate( PrivateKey key, String provider) throws NoSuchProviderException, SecurityException, SignatureException, InvalidKeyException { return generateCertificate(key, provider, null); } /** * generate an X509 certificate, based on the current issuer and subject, * using the passed in provider for the signing and the supplied source * of randomness, if required. * @deprecated use generate() */ public X509AttributeCertificate generateCertificate( PrivateKey key, String provider, SecureRandom random) throws NoSuchProviderException, SecurityException, SignatureException, InvalidKeyException { try { return generate(key, provider, random); } catch (NoSuchProviderException e) { throw e; } catch (SignatureException e) { throw e; } catch (InvalidKeyException e) { throw e; } catch (GeneralSecurityException e) { throw new SecurityException("exception creating certificate: " + e); } } /** * generate an X509 certificate, based on the current issuer and subject, * using the passed in provider for the signing. */ public X509AttributeCertificate generate( PrivateKey key, String provider) throws CertificateEncodingException, IllegalStateException, NoSuchProviderException, SignatureException, InvalidKeyException, NoSuchAlgorithmException { return generate(key, provider, null); } /** * generate an X509 certificate, based on the current issuer and subject, * using the passed in provider for the signing and the supplied source * of randomness, if required. */ public X509AttributeCertificate generate( PrivateKey key, String provider, SecureRandom random) throws CertificateEncodingException, IllegalStateException, NoSuchProviderException, NoSuchAlgorithmException, SignatureException, InvalidKeyException { if (!extGenerator.isEmpty()) { acInfoGen.setExtensions(extGenerator.generate()); } AttributeCertificateInfo acInfo = acInfoGen.generateAttributeCertificateInfo(); ASN1EncodableVector v = new ASN1EncodableVector(); v.add(acInfo); v.add(sigAlgId); try { v.add(new DERBitString(X509Util.calculateSignature(sigOID, signatureAlgorithm, provider, key, random, acInfo))); return new X509V2AttributeCertificate(new AttributeCertificate(new DERSequence(v))); } catch (IOException e) { throw new ExtCertificateEncodingException("constructed invalid certificate", e); } } /** * Return an iterator of the signature names supported by the generator. * * @return an iterator containing recognised names. */ public Iterator getSignatureAlgNames() { return X509Util.getAlgNames(); } } bouncycastle-1.49.orig/src/org/bouncycastle/x509/ExtendedPKIXBuilderParameters.java0000644000175000017500000001602310575646437027664 0ustar ebourgebourgpackage org.bouncycastle.x509; import org.bouncycastle.util.Selector; import java.security.InvalidAlgorithmParameterException; import java.security.InvalidParameterException; import java.security.cert.PKIXBuilderParameters; import java.security.cert.PKIXParameters; import java.security.cert.TrustAnchor; import java.security.cert.X509CertSelector; import java.util.Collections; import java.util.HashSet; import java.util.Set; /** * This class contains extended parameters for PKIX certification path builders. * * @see java.security.cert.PKIXBuilderParameters * @see org.bouncycastle.jce.provider.PKIXCertPathBuilderSpi */ public class ExtendedPKIXBuilderParameters extends ExtendedPKIXParameters { private int maxPathLength = 5; private Set excludedCerts = Collections.EMPTY_SET; /** * Excluded certificates are not used for building a certification path. *

    * The returned set is immutable. * * @return Returns the excluded certificates. */ public Set getExcludedCerts() { return Collections.unmodifiableSet(excludedCerts); } /** * Sets the excluded certificates which are not used for building a * certification path. If the Set is null an * empty set is assumed. *

    * The given set is cloned to protect it against subsequent modifications. * * @param excludedCerts The excluded certificates to set. */ public void setExcludedCerts(Set excludedCerts) { if (excludedCerts == null) { excludedCerts = Collections.EMPTY_SET; } else { this.excludedCerts = new HashSet(excludedCerts); } } /** * Creates an instance of PKIXBuilderParameters with the * specified Set of most-trusted CAs. Each element of the set * is a {@link TrustAnchor TrustAnchor}. * *

    * Note that the Set is copied to protect against subsequent * modifications. * * @param trustAnchors a Set of TrustAnchors * @param targetConstraints a Selector specifying the * constraints on the target certificate or attribute * certificate. * @throws InvalidAlgorithmParameterException if trustAnchors * is empty. * @throws NullPointerException if trustAnchors is * null * @throws ClassCastException if any of the elements of * trustAnchors is not of type * java.security.cert.TrustAnchor */ public ExtendedPKIXBuilderParameters(Set trustAnchors, Selector targetConstraints) throws InvalidAlgorithmParameterException { super(trustAnchors); setTargetConstraints(targetConstraints); } /** * Sets the maximum number of intermediate non-self-issued certificates in a * certification path. The PKIX CertPathBuilder must not * build paths longer then this length. *

    * A value of 0 implies that the path can only contain a single certificate. * A value of -1 does not limit the length. The default length is 5. * *

    * * The basic constraints extension of a CA certificate overrides this value * if smaller. * * @param maxPathLength the maximum number of non-self-issued intermediate * certificates in the certification path * @throws InvalidParameterException if maxPathLength is set * to a value less than -1 * * @see org.bouncycastle.jce.provider.PKIXCertPathBuilderSpi * @see #getMaxPathLength */ public void setMaxPathLength(int maxPathLength) { if (maxPathLength < -1) { throw new InvalidParameterException("The maximum path " + "length parameter can not be less than -1."); } this.maxPathLength = maxPathLength; } /** * Returns the value of the maximum number of intermediate non-self-issued * certificates in the certification path. * * @return the maximum number of non-self-issued intermediate certificates * in the certification path, or -1 if no limit exists. * * @see #setMaxPathLength(int) */ public int getMaxPathLength() { return maxPathLength; } /** * Can alse handle ExtendedPKIXBuilderParameters and * PKIXBuilderParameters. * * @param params Parameters to set. * @see org.bouncycastle.x509.ExtendedPKIXParameters#setParams(java.security.cert.PKIXParameters) */ protected void setParams(PKIXParameters params) { super.setParams(params); if (params instanceof ExtendedPKIXBuilderParameters) { ExtendedPKIXBuilderParameters _params = (ExtendedPKIXBuilderParameters) params; maxPathLength = _params.maxPathLength; excludedCerts = new HashSet(_params.excludedCerts); } if (params instanceof PKIXBuilderParameters) { PKIXBuilderParameters _params = (PKIXBuilderParameters) params; maxPathLength = _params.getMaxPathLength(); } } /** * Makes a copy of this PKIXParameters object. Changes to the * copy will not affect the original and vice versa. * * @return a copy of this PKIXParameters object */ public Object clone() { ExtendedPKIXBuilderParameters params = null; try { params = new ExtendedPKIXBuilderParameters(getTrustAnchors(), getTargetConstraints()); } catch (Exception e) { // cannot happen throw new RuntimeException(e.getMessage()); } params.setParams(this); return params; } /** * Returns an instance of ExtendedPKIXParameters which can be * safely casted to ExtendedPKIXBuilderParameters. *

    * This method can be used to get a copy from other * PKIXBuilderParameters, PKIXParameters, * and ExtendedPKIXParameters instances. * * @param pkixParams The PKIX parameters to create a copy of. * @return An ExtendedPKIXBuilderParameters instance. */ public static ExtendedPKIXParameters getInstance(PKIXParameters pkixParams) { ExtendedPKIXBuilderParameters params; try { params = new ExtendedPKIXBuilderParameters(pkixParams .getTrustAnchors(), X509CertStoreSelector .getInstance((X509CertSelector) pkixParams .getTargetCertConstraints())); } catch (Exception e) { // cannot happen throw new RuntimeException(e.getMessage()); } params.setParams(pkixParams); return params; } } bouncycastle-1.49.orig/src/org/bouncycastle/x509/NoSuchParserException.java0000644000175000017500000000026210522776714026320 0ustar ebourgebourgpackage org.bouncycastle.x509; public class NoSuchParserException extends Exception { public NoSuchParserException(String message) { super(message); } } bouncycastle-1.49.orig/src/org/bouncycastle/x509/PKIXAttrCertChecker.java0000644000175000017500000000434010557030447025571 0ustar ebourgebourgpackage org.bouncycastle.x509; import java.security.cert.CertPath; import java.security.cert.CertPathValidatorException; import java.util.Collection; import java.util.Set; public abstract class PKIXAttrCertChecker implements Cloneable { /** * Returns an immutable Set of X.509 attribute certificate * extensions that this PKIXAttrCertChecker supports or * null if no extensions are supported. *

    * Each element of the set is a String representing the * Object Identifier (OID) of the X.509 extension that is supported. *

    * All X.509 attribute certificate extensions that a * PKIXAttrCertChecker might possibly be able to process * should be included in the set. * * @return an immutable Set of X.509 extension OIDs (in * String format) supported by this * PKIXAttrCertChecker, or null if no * extensions are supported */ public abstract Set getSupportedExtensions(); /** * Performs checks on the specified attribute certificate. Every handled * extension is rmeoved from the unresolvedCritExts * collection. * * @param attrCert The attribute certificate to be checked. * @param certPath The certificate path which belongs to the attribute * certificate issuer public key certificate. * @param holderCertPath The certificate path which belongs to the holder * certificate. * @param unresolvedCritExts a Collection of OID strings * representing the current set of unresolved critical extensions * @throws CertPathValidatorException if the specified attribute certificate * does not pass the check. */ public abstract void check(X509AttributeCertificate attrCert, CertPath certPath, CertPath holderCertPath, Collection unresolvedCritExts) throws CertPathValidatorException; /** * Returns a clone of this object. * * @return a copy of this PKIXAttrCertChecker */ public abstract Object clone(); } bouncycastle-1.49.orig/src/org/bouncycastle/x509/ExtCertificateEncodingException.java0000644000175000017500000000061210521124111030266 0ustar ebourgebourgpackage org.bouncycastle.x509; import java.security.cert.CertificateEncodingException; class ExtCertificateEncodingException extends CertificateEncodingException { Throwable cause; ExtCertificateEncodingException(String message, Throwable cause) { super(message); this.cause = cause; } public Throwable getCause() { return cause; } } bouncycastle-1.49.orig/src/org/bouncycastle/x509/X509AttributeCertificate.java0000644000175000017500000000552410542454120026551 0ustar ebourgebourgpackage org.bouncycastle.x509; import java.io.IOException; import java.math.BigInteger; import java.security.InvalidKeyException; import java.security.NoSuchAlgorithmException; import java.security.NoSuchProviderException; import java.security.PublicKey; import java.security.SignatureException; import java.security.cert.CertificateException; import java.security.cert.CertificateExpiredException; import java.security.cert.CertificateNotYetValidException; import java.security.cert.X509Extension; import java.util.Date; /** * Interface for an X.509 Attribute Certificate. */ public interface X509AttributeCertificate extends X509Extension { /** * Return the version number for the certificate. * * @return the version number. */ public int getVersion(); /** * Return the serial number for the certificate. * * @return the serial number. */ public BigInteger getSerialNumber(); /** * Return the date before which the certificate is not valid. * * @return the "not valid before" date. */ public Date getNotBefore(); /** * Return the date after which the certificate is not valid. * * @return the "not valid afer" date. */ public Date getNotAfter(); /** * Return the holder of the certificate. * * @return the holder. */ public AttributeCertificateHolder getHolder(); /** * Return the issuer details for the certificate. * * @return the issuer details. */ public AttributeCertificateIssuer getIssuer(); /** * Return the attributes contained in the attribute block in the certificate. * * @return an array of attributes. */ public X509Attribute[] getAttributes(); /** * Return the attributes with the same type as the passed in oid. * * @param oid the object identifier we wish to match. * @return an array of matched attributes, null if there is no match. */ public X509Attribute[] getAttributes(String oid); public boolean[] getIssuerUniqueID(); public void checkValidity() throws CertificateExpiredException, CertificateNotYetValidException; public void checkValidity(Date date) throws CertificateExpiredException, CertificateNotYetValidException; public byte[] getSignature(); public void verify(PublicKey key, String provider) throws CertificateException, NoSuchAlgorithmException, InvalidKeyException, NoSuchProviderException, SignatureException; /** * Return an ASN.1 encoded byte array representing the attribute certificate. * * @return an ASN.1 encoded byte array. * @throws IOException if the certificate cannot be encoded. */ public byte[] getEncoded() throws IOException; } bouncycastle-1.49.orig/src/org/bouncycastle/x509/CertPathReviewerException.java0000644000175000017500000000334510472271362027165 0ustar ebourgebourgpackage org.bouncycastle.x509; import java.security.cert.CertPath; import org.bouncycastle.i18n.ErrorBundle; import org.bouncycastle.i18n.LocalizedException; public class CertPathReviewerException extends LocalizedException { private int index = -1; private CertPath certPath = null; public CertPathReviewerException(ErrorBundle errorMessage, Throwable throwable) { super(errorMessage, throwable); } public CertPathReviewerException(ErrorBundle errorMessage) { super(errorMessage); } public CertPathReviewerException( ErrorBundle errorMessage, Throwable throwable, CertPath certPath, int index) { super(errorMessage, throwable); if (certPath == null || index == -1) { throw new IllegalArgumentException(); } if (index < -1 || (certPath != null && index >= certPath.getCertificates().size())) { throw new IndexOutOfBoundsException(); } this.certPath = certPath; this.index = index; } public CertPathReviewerException( ErrorBundle errorMessage, CertPath certPath, int index) { super(errorMessage); if (certPath == null || index == -1) { throw new IllegalArgumentException(); } if (index < -1 || (certPath != null && index >= certPath.getCertificates().size())) { throw new IndexOutOfBoundsException(); } this.certPath = certPath; this.index = index; } public CertPath getCertPath() { return certPath; } public int getIndex() { return index; } } bouncycastle-1.49.orig/src/org/bouncycastle/x509/X509Attribute.java0000644000175000017500000000417011624633162024411 0ustar ebourgebourgpackage org.bouncycastle.x509; import org.bouncycastle.asn1.ASN1Encodable; import org.bouncycastle.asn1.ASN1EncodableVector; import org.bouncycastle.asn1.ASN1Object; import org.bouncycastle.asn1.ASN1ObjectIdentifier; import org.bouncycastle.asn1.ASN1Primitive; import org.bouncycastle.asn1.ASN1Set; import org.bouncycastle.asn1.DERSet; import org.bouncycastle.asn1.x509.Attribute; /** * Class for carrying the values in an X.509 Attribute. */ public class X509Attribute extends ASN1Object { Attribute attr; /** * @param at an object representing an attribute. */ X509Attribute( ASN1Encodable at) { this.attr = Attribute.getInstance(at); } /** * Create an X.509 Attribute with the type given by the passed in oid and * the value represented by an ASN.1 Set containing value. * * @param oid type of the attribute * @param value value object to go into the atribute's value set. */ public X509Attribute( String oid, ASN1Encodable value) { this.attr = new Attribute(new ASN1ObjectIdentifier(oid), new DERSet(value)); } /** * Create an X.59 Attribute with the type given by the passed in oid and the * value represented by an ASN.1 Set containing the objects in value. * * @param oid type of the attribute * @param value vector of values to go in the attribute's value set. */ public X509Attribute( String oid, ASN1EncodableVector value) { this.attr = new Attribute(new ASN1ObjectIdentifier(oid), new DERSet(value)); } public String getOID() { return attr.getAttrType().getId(); } public ASN1Encodable[] getValues() { ASN1Set s = attr.getAttrValues(); ASN1Encodable[] values = new ASN1Encodable[s.size()]; for (int i = 0; i != s.size(); i++) { values[i] = (ASN1Encodable)s.getObjectAt(i); } return values; } public ASN1Primitive toASN1Primitive() { return attr.toASN1Primitive(); } } bouncycastle-1.49.orig/src/org/bouncycastle/x509/examples/0000755000175000017500000000000012152033551023022 5ustar ebourgebourgbouncycastle-1.49.orig/src/org/bouncycastle/x509/examples/AttrCertExample.java0000644000175000017500000003060211345576307026750 0ustar ebourgebourgpackage org.bouncycastle.x509.examples; import java.math.BigInteger; import java.security.KeyFactory; import java.security.PrivateKey; import java.security.PublicKey; import java.security.Security; import java.security.cert.X509Certificate; import java.security.spec.RSAPrivateCrtKeySpec; import java.security.spec.RSAPublicKeySpec; import java.util.Date; import java.util.Hashtable; import java.util.Vector; import org.bouncycastle.asn1.ASN1EncodableVector; import org.bouncycastle.asn1.DERSequence; import org.bouncycastle.asn1.misc.MiscObjectIdentifiers; import org.bouncycastle.asn1.misc.NetscapeCertType; import org.bouncycastle.asn1.x509.GeneralName; import org.bouncycastle.jce.X509Principal; import org.bouncycastle.jce.provider.BouncyCastleProvider; import org.bouncycastle.x509.AttributeCertificateHolder; import org.bouncycastle.x509.AttributeCertificateIssuer; import org.bouncycastle.x509.X509Attribute; import org.bouncycastle.x509.X509V1CertificateGenerator; import org.bouncycastle.x509.X509V2AttributeCertificate; import org.bouncycastle.x509.X509V2AttributeCertificateGenerator; import org.bouncycastle.x509.X509V3CertificateGenerator; /** * A simple example that generates an attribute certificate. */ public class AttrCertExample { static X509V1CertificateGenerator v1CertGen = new X509V1CertificateGenerator(); static X509V3CertificateGenerator v3CertGen = new X509V3CertificateGenerator(); /** * we generate the AC issuer's certificate */ public static X509Certificate createAcIssuerCert( PublicKey pubKey, PrivateKey privKey) throws Exception { // // signers name // String issuer = "C=AU, O=The Legion of the Bouncy Castle, OU=Bouncy Primary Certificate"; // // subjects name - the same as we are self signed. // String subject = "C=AU, O=The Legion of the Bouncy Castle, OU=Bouncy Primary Certificate"; // // create the certificate - version 1 // v1CertGen.setSerialNumber(BigInteger.valueOf(10)); v1CertGen.setIssuerDN(new X509Principal(issuer)); v1CertGen.setNotBefore(new Date(System.currentTimeMillis() - 1000L * 60 * 60 * 24 * 30)); v1CertGen.setNotAfter(new Date(System.currentTimeMillis() + (1000L * 60 * 60 * 24 * 30))); v1CertGen.setSubjectDN(new X509Principal(subject)); v1CertGen.setPublicKey(pubKey); v1CertGen.setSignatureAlgorithm("SHA1WithRSAEncryption"); X509Certificate cert = v1CertGen.generate(privKey); cert.checkValidity(new Date()); cert.verify(pubKey); return cert; } /** * we generate a certificate signed by our CA's intermediate certficate */ public static X509Certificate createClientCert( PublicKey pubKey, PrivateKey caPrivKey, PublicKey caPubKey) throws Exception { // // issuer // String issuer = "C=AU, O=The Legion of the Bouncy Castle, OU=Bouncy Primary Certificate"; // // subjects name table. // Hashtable attrs = new Hashtable(); Vector order = new Vector(); attrs.put(X509Principal.C, "AU"); attrs.put(X509Principal.O, "The Legion of the Bouncy Castle"); attrs.put(X509Principal.L, "Melbourne"); attrs.put(X509Principal.CN, "Eric H. Echidna"); attrs.put(X509Principal.EmailAddress, "feedback-crypto@bouncycastle.org"); order.addElement(X509Principal.C); order.addElement(X509Principal.O); order.addElement(X509Principal.L); order.addElement(X509Principal.CN); order.addElement(X509Principal.EmailAddress); // // create the certificate - version 3 // v3CertGen.reset(); v3CertGen.setSerialNumber(BigInteger.valueOf(20)); v3CertGen.setIssuerDN(new X509Principal(issuer)); v3CertGen.setNotBefore(new Date(System.currentTimeMillis() - 1000L * 60 * 60 * 24 * 30)); v3CertGen.setNotAfter(new Date(System.currentTimeMillis() + (1000L * 60 * 60 * 24 * 30))); v3CertGen.setSubjectDN(new X509Principal(order, attrs)); v3CertGen.setPublicKey(pubKey); v3CertGen.setSignatureAlgorithm("SHA1WithRSAEncryption"); // // add the extensions // v3CertGen.addExtension( MiscObjectIdentifiers.netscapeCertType, false, new NetscapeCertType(NetscapeCertType.objectSigning | NetscapeCertType.smime)); X509Certificate cert = v3CertGen.generate(caPrivKey); cert.checkValidity(new Date()); cert.verify(caPubKey); return cert; } public static void main(String args[]) throws Exception { Security.addProvider(new BouncyCastleProvider()); // // personal keys // RSAPublicKeySpec pubKeySpec = new RSAPublicKeySpec( new BigInteger("b4a7e46170574f16a97082b22be58b6a2a629798419be12872a4bdba626cfae9900f76abfb12139dce5de56564fab2b6543165a040c606887420e33d91ed7ed7", 16), new BigInteger("11", 16)); RSAPrivateCrtKeySpec privKeySpec = new RSAPrivateCrtKeySpec( new BigInteger("b4a7e46170574f16a97082b22be58b6a2a629798419be12872a4bdba626cfae9900f76abfb12139dce5de56564fab2b6543165a040c606887420e33d91ed7ed7", 16), new BigInteger("11", 16), new BigInteger("9f66f6b05410cd503b2709e88115d55daced94d1a34d4e32bf824d0dde6028ae79c5f07b580f5dce240d7111f7ddb130a7945cd7d957d1920994da389f490c89", 16), new BigInteger("c0a0758cdf14256f78d4708c86becdead1b50ad4ad6c5c703e2168fbf37884cb", 16), new BigInteger("f01734d7960ea60070f1b06f2bb81bfac48ff192ae18451d5e56c734a5aab8a5", 16), new BigInteger("b54bb9edff22051d9ee60f9351a48591b6500a319429c069a3e335a1d6171391", 16), new BigInteger("d3d83daf2a0cecd3367ae6f8ae1aeb82e9ac2f816c6fc483533d8297dd7884cd", 16), new BigInteger("b8f52fc6f38593dabb661d3f50f8897f8106eee68b1bce78a95b132b4e5b5d19", 16)); // // ca keys // RSAPublicKeySpec caPubKeySpec = new RSAPublicKeySpec( new BigInteger("b259d2d6e627a768c94be36164c2d9fc79d97aab9253140e5bf17751197731d6f7540d2509e7b9ffee0a70a6e26d56e92d2edd7f85aba85600b69089f35f6bdbf3c298e05842535d9f064e6b0391cb7d306e0a2d20c4dfb4e7b49a9640bdea26c10ad69c3f05007ce2513cee44cfe01998e62b6c3637d3fc0391079b26ee36d5", 16), new BigInteger("11", 16)); RSAPrivateCrtKeySpec caPrivKeySpec = new RSAPrivateCrtKeySpec( new BigInteger("b259d2d6e627a768c94be36164c2d9fc79d97aab9253140e5bf17751197731d6f7540d2509e7b9ffee0a70a6e26d56e92d2edd7f85aba85600b69089f35f6bdbf3c298e05842535d9f064e6b0391cb7d306e0a2d20c4dfb4e7b49a9640bdea26c10ad69c3f05007ce2513cee44cfe01998e62b6c3637d3fc0391079b26ee36d5", 16), new BigInteger("11", 16), new BigInteger("92e08f83cc9920746989ca5034dcb384a094fb9c5a6288fcc4304424ab8f56388f72652d8fafc65a4b9020896f2cde297080f2a540e7b7ce5af0b3446e1258d1dd7f245cf54124b4c6e17da21b90a0ebd22605e6f45c9f136d7a13eaac1c0f7487de8bd6d924972408ebb58af71e76fd7b012a8d0e165f3ae2e5077a8648e619", 16), new BigInteger("f75e80839b9b9379f1cf1128f321639757dba514642c206bbbd99f9a4846208b3e93fbbe5e0527cc59b1d4b929d9555853004c7c8b30ee6a213c3d1bb7415d03", 16), new BigInteger("b892d9ebdbfc37e397256dd8a5d3123534d1f03726284743ddc6be3a709edb696fc40c7d902ed804c6eee730eee3d5b20bf6bd8d87a296813c87d3b3cc9d7947", 16), new BigInteger("1d1a2d3ca8e52068b3094d501c9a842fec37f54db16e9a67070a8b3f53cc03d4257ad252a1a640eadd603724d7bf3737914b544ae332eedf4f34436cac25ceb5", 16), new BigInteger("6c929e4e81672fef49d9c825163fec97c4b7ba7acb26c0824638ac22605d7201c94625770984f78a56e6e25904fe7db407099cad9b14588841b94f5ab498dded", 16), new BigInteger("dae7651ee69ad1d081ec5e7188ae126f6004ff39556bde90e0b870962fa7b926d070686d8244fe5a9aa709a95686a104614834b0ada4b10f53197a5cb4c97339", 16)); // // set up the keys // KeyFactory fact = KeyFactory.getInstance("RSA", "BC"); PrivateKey caPrivKey = fact.generatePrivate(caPrivKeySpec); PublicKey caPubKey = fact.generatePublic(caPubKeySpec); PrivateKey privKey = fact.generatePrivate(privKeySpec); PublicKey pubKey = fact.generatePublic(pubKeySpec); // // note in this case we are using the CA certificate for both the client cetificate // and the attribute certificate. This is to make the vcode simpler to read, in practice // the CA for the attribute certificate should be different to that of the client certificate // X509Certificate caCert = createAcIssuerCert(caPubKey, caPrivKey); X509Certificate clientCert = createClientCert(pubKey, caPrivKey, caPubKey); // Instantiate a new AC generator X509V2AttributeCertificateGenerator acGen = new X509V2AttributeCertificateGenerator(); acGen.reset(); // // Holder: here we use the IssuerSerial form // acGen.setHolder(new AttributeCertificateHolder(clientCert)); // set the Issuer acGen.setIssuer(new AttributeCertificateIssuer(caCert.getSubjectX500Principal())); // // serial number (as it's an example we don't have to keep track of the // serials anyway // acGen.setSerialNumber(new BigInteger("1")); // not Before acGen.setNotBefore(new Date(System.currentTimeMillis() - 50000)); // not After acGen.setNotAfter(new Date(System.currentTimeMillis() + 50000)); // signature Algorithmus acGen.setSignatureAlgorithm("SHA1WithRSAEncryption"); // the actual attributes GeneralName roleName = new GeneralName(GeneralName.rfc822Name, "DAU123456789"); ASN1EncodableVector roleSyntax = new ASN1EncodableVector(); roleSyntax.add(roleName); // roleSyntax OID: 2.5.24.72 X509Attribute attributes = new X509Attribute("2.5.24.72", new DERSequence(roleSyntax)); acGen.addAttribute(attributes); // finally create the AC X509V2AttributeCertificate att = (X509V2AttributeCertificate)acGen .generate(caPrivKey, "BC"); // // starting here, we parse the newly generated AC // // Holder AttributeCertificateHolder h = att.getHolder(); if (h.match(clientCert)) { if (h.getEntityNames() != null) { System.out.println(h.getEntityNames().length + " entity names found"); } if (h.getIssuer() != null) { System.out.println(h.getIssuer().length + " issuer names found, serial number " + h.getSerialNumber()); } System.out.println("Matches original client x509 cert"); } // Issuer AttributeCertificateIssuer issuer = att.getIssuer(); if (issuer.match(caCert)) { if (issuer.getPrincipals() != null) { System.out.println(issuer.getPrincipals().length + " entity names found"); } System.out.println("Matches original ca x509 cert"); } // Dates System.out.println("valid not before: " + att.getNotBefore()); System.out.println("valid not before: " + att.getNotAfter()); // check the dates, an exception is thrown in checkValidity()... try { att.checkValidity(); att.checkValidity(new Date()); } catch (Exception e) { System.out.println(e); } // verify try { att.verify(caPubKey, "BC"); } catch (Exception e) { System.out.println(e); } // Attribute X509Attribute[] attribs = att.getAttributes(); System.out.println("cert has " + attribs.length + " attributes:"); for (int i = 0; i < attribs.length; i++) { X509Attribute a = attribs[i]; System.out.println("OID: " + a.getOID()); // currently we only check for the presence of a 'RoleSyntax' attribute if (a.getOID().equals("2.5.24.72")) { System.out.println("rolesyntax read from cert!"); } } } }bouncycastle-1.49.orig/src/org/bouncycastle/x509/examples/package.html0000644000175000017500000000014310262753174025313 0ustar ebourgebourg

    Examples for X.509 attribute certificates.

    bouncycastle-1.49.orig/src/org/bouncycastle/x509/X509Store.java0000644000175000017500000000410011043256123023524 0ustar ebourgebourgpackage org.bouncycastle.x509; import org.bouncycastle.util.Selector; import org.bouncycastle.util.Store; import java.security.NoSuchAlgorithmException; import java.security.NoSuchProviderException; import java.security.Provider; import java.util.Collection; public class X509Store implements Store { public static X509Store getInstance(String type, X509StoreParameters parameters) throws NoSuchStoreException { try { X509Util.Implementation impl = X509Util.getImplementation("X509Store", type); return createStore(impl, parameters); } catch (NoSuchAlgorithmException e) { throw new NoSuchStoreException(e.getMessage()); } } public static X509Store getInstance(String type, X509StoreParameters parameters, String provider) throws NoSuchStoreException, NoSuchProviderException { return getInstance(type, parameters, X509Util.getProvider(provider)); } public static X509Store getInstance(String type, X509StoreParameters parameters, Provider provider) throws NoSuchStoreException { try { X509Util.Implementation impl = X509Util.getImplementation("X509Store", type, provider); return createStore(impl, parameters); } catch (NoSuchAlgorithmException e) { throw new NoSuchStoreException(e.getMessage()); } } private static X509Store createStore(X509Util.Implementation impl, X509StoreParameters parameters) { X509StoreSpi spi = (X509StoreSpi)impl.getEngine(); spi.engineInit(parameters); return new X509Store(impl.getProvider(), spi); } private Provider _provider; private X509StoreSpi _spi; private X509Store( Provider provider, X509StoreSpi spi) { _provider = provider; _spi = spi; } public Provider getProvider() { return _provider; } public Collection getMatches(Selector selector) { return _spi.engineGetMatches(selector); } } bouncycastle-1.49.orig/src/org/bouncycastle/x509/X509V2CRLGenerator.java0000644000175000017500000003243612132656275025160 0ustar ebourgebourgpackage org.bouncycastle.x509; import java.io.IOException; import java.math.BigInteger; import java.security.GeneralSecurityException; import java.security.InvalidKeyException; import java.security.NoSuchAlgorithmException; import java.security.NoSuchProviderException; import java.security.PrivateKey; import java.security.SecureRandom; import java.security.SignatureException; import java.security.cert.CRLException; import java.security.cert.X509CRL; import java.security.cert.X509CRLEntry; import java.util.Date; import java.util.Iterator; import java.util.Set; import javax.security.auth.x500.X500Principal; import org.bouncycastle.asn1.ASN1Encodable; import org.bouncycastle.asn1.ASN1EncodableVector; import org.bouncycastle.asn1.ASN1GeneralizedTime; import org.bouncycastle.asn1.ASN1InputStream; import org.bouncycastle.asn1.ASN1Integer; import org.bouncycastle.asn1.ASN1ObjectIdentifier; import org.bouncycastle.asn1.ASN1Sequence; import org.bouncycastle.asn1.DERBitString; import org.bouncycastle.asn1.DERObjectIdentifier; import org.bouncycastle.asn1.DERSequence; import org.bouncycastle.asn1.x509.AlgorithmIdentifier; import org.bouncycastle.asn1.x509.CertificateList; import org.bouncycastle.asn1.x509.Extensions; import org.bouncycastle.asn1.x509.TBSCertList; import org.bouncycastle.asn1.x509.Time; import org.bouncycastle.asn1.x509.V2TBSCertListGenerator; import org.bouncycastle.asn1.x509.X509Extensions; import org.bouncycastle.asn1.x509.X509ExtensionsGenerator; import org.bouncycastle.asn1.x509.X509Name; import org.bouncycastle.jce.X509Principal; import org.bouncycastle.jce.provider.X509CRLObject; /** * class to produce an X.509 Version 2 CRL. * @deprecated use org.bouncycastle.cert.X509v2CRLBuilder. */ public class X509V2CRLGenerator { private V2TBSCertListGenerator tbsGen; private DERObjectIdentifier sigOID; private AlgorithmIdentifier sigAlgId; private String signatureAlgorithm; private X509ExtensionsGenerator extGenerator; public X509V2CRLGenerator() { tbsGen = new V2TBSCertListGenerator(); extGenerator = new X509ExtensionsGenerator(); } /** * reset the generator */ public void reset() { tbsGen = new V2TBSCertListGenerator(); extGenerator.reset(); } /** * Set the issuer distinguished name - the issuer is the entity whose private key is used to sign the * certificate. */ public void setIssuerDN( X500Principal issuer) { try { tbsGen.setIssuer(new X509Principal(issuer.getEncoded())); } catch (IOException e) { throw new IllegalArgumentException("can't process principal: " + e); } } /** * Set the issuer distinguished name - the issuer is the entity whose private key is used to sign the * certificate. */ public void setIssuerDN( X509Name issuer) { tbsGen.setIssuer(issuer); } public void setThisUpdate( Date date) { tbsGen.setThisUpdate(new Time(date)); } public void setNextUpdate( Date date) { tbsGen.setNextUpdate(new Time(date)); } /** * Reason being as indicated by CRLReason, i.e. CRLReason.keyCompromise * or 0 if CRLReason is not to be used **/ public void addCRLEntry(BigInteger userCertificate, Date revocationDate, int reason) { tbsGen.addCRLEntry(new ASN1Integer(userCertificate), new Time(revocationDate), reason); } /** * Add a CRL entry with an Invalidity Date extension as well as a CRLReason extension. * Reason being as indicated by CRLReason, i.e. CRLReason.keyCompromise * or 0 if CRLReason is not to be used **/ public void addCRLEntry(BigInteger userCertificate, Date revocationDate, int reason, Date invalidityDate) { tbsGen.addCRLEntry(new ASN1Integer(userCertificate), new Time(revocationDate), reason, new ASN1GeneralizedTime(invalidityDate)); } /** * Add a CRL entry with extensions. **/ public void addCRLEntry(BigInteger userCertificate, Date revocationDate, X509Extensions extensions) { tbsGen.addCRLEntry(new ASN1Integer(userCertificate), new Time(revocationDate), Extensions.getInstance(extensions)); } /** * Add the CRLEntry objects contained in a previous CRL. * * @param other the X509CRL to source the other entries from. */ public void addCRL(X509CRL other) throws CRLException { Set revocations = other.getRevokedCertificates(); if (revocations != null) { Iterator it = revocations.iterator(); while (it.hasNext()) { X509CRLEntry entry = (X509CRLEntry)it.next(); ASN1InputStream aIn = new ASN1InputStream(entry.getEncoded()); try { tbsGen.addCRLEntry(ASN1Sequence.getInstance(aIn.readObject())); } catch (IOException e) { throw new CRLException("exception processing encoding of CRL: " + e.toString()); } } } } /** * Set the signature algorithm. This can be either a name or an OID, names * are treated as case insensitive. * * @param signatureAlgorithm string representation of the algorithm name. */ public void setSignatureAlgorithm( String signatureAlgorithm) { this.signatureAlgorithm = signatureAlgorithm; try { sigOID = X509Util.getAlgorithmOID(signatureAlgorithm); } catch (Exception e) { throw new IllegalArgumentException("Unknown signature type requested"); } sigAlgId = X509Util.getSigAlgID(sigOID, signatureAlgorithm); tbsGen.setSignature(sigAlgId); } /** * add a given extension field for the standard extensions tag (tag 0) */ public void addExtension( String oid, boolean critical, ASN1Encodable value) { this.addExtension(new DERObjectIdentifier(oid), critical, value); } /** * add a given extension field for the standard extensions tag (tag 0) */ public void addExtension( DERObjectIdentifier oid, boolean critical, ASN1Encodable value) { extGenerator.addExtension(new ASN1ObjectIdentifier(oid.getId()), critical, value); } /** * add a given extension field for the standard extensions tag (tag 0) */ public void addExtension( String oid, boolean critical, byte[] value) { this.addExtension(new DERObjectIdentifier(oid), critical, value); } /** * add a given extension field for the standard extensions tag (tag 0) */ public void addExtension( DERObjectIdentifier oid, boolean critical, byte[] value) { extGenerator.addExtension(new ASN1ObjectIdentifier(oid.getId()), critical, value); } /** * generate an X509 CRL, based on the current issuer and subject * using the default provider "BC". * @deprecated use generate(key, "BC") */ public X509CRL generateX509CRL( PrivateKey key) throws SecurityException, SignatureException, InvalidKeyException { try { return generateX509CRL(key, "BC", null); } catch (NoSuchProviderException e) { throw new SecurityException("BC provider not installed!"); } } /** * generate an X509 CRL, based on the current issuer and subject * using the default provider "BC" and an user defined SecureRandom object as * source of randomness. * @deprecated use generate(key, random, "BC") */ public X509CRL generateX509CRL( PrivateKey key, SecureRandom random) throws SecurityException, SignatureException, InvalidKeyException { try { return generateX509CRL(key, "BC", random); } catch (NoSuchProviderException e) { throw new SecurityException("BC provider not installed!"); } } /** * generate an X509 certificate, based on the current issuer and subject * using the passed in provider for the signing. * @deprecated use generate() */ public X509CRL generateX509CRL( PrivateKey key, String provider) throws NoSuchProviderException, SecurityException, SignatureException, InvalidKeyException { return generateX509CRL(key, provider, null); } /** * generate an X509 CRL, based on the current issuer and subject, * using the passed in provider for the signing. * @deprecated use generate() */ public X509CRL generateX509CRL( PrivateKey key, String provider, SecureRandom random) throws NoSuchProviderException, SecurityException, SignatureException, InvalidKeyException { try { return generate(key, provider, random); } catch (NoSuchProviderException e) { throw e; } catch (SignatureException e) { throw e; } catch (InvalidKeyException e) { throw e; } catch (GeneralSecurityException e) { throw new SecurityException("exception: " + e); } } /** * generate an X509 CRL, based on the current issuer and subject * using the default provider. *

    * Note: this differs from the deprecated method in that the default provider is * used - not "BC". *

    */ public X509CRL generate( PrivateKey key) throws CRLException, IllegalStateException, NoSuchAlgorithmException, SignatureException, InvalidKeyException { return generate(key, (SecureRandom)null); } /** * generate an X509 CRL, based on the current issuer and subject * using the default provider and an user defined SecureRandom object as * source of randomness. *

    * Note: this differs from the deprecated method in that the default provider is * used - not "BC". *

    */ public X509CRL generate( PrivateKey key, SecureRandom random) throws CRLException, IllegalStateException, NoSuchAlgorithmException, SignatureException, InvalidKeyException { TBSCertList tbsCrl = generateCertList(); byte[] signature; try { signature = X509Util.calculateSignature(sigOID, signatureAlgorithm, key, random, tbsCrl); } catch (IOException e) { throw new ExtCRLException("cannot generate CRL encoding", e); } return generateJcaObject(tbsCrl, signature); } /** * generate an X509 certificate, based on the current issuer and subject * using the passed in provider for the signing. */ public X509CRL generate( PrivateKey key, String provider) throws CRLException, IllegalStateException, NoSuchProviderException, NoSuchAlgorithmException, SignatureException, InvalidKeyException { return generate(key, provider, null); } /** * generate an X509 CRL, based on the current issuer and subject, * using the passed in provider for the signing. */ public X509CRL generate( PrivateKey key, String provider, SecureRandom random) throws CRLException, IllegalStateException, NoSuchProviderException, NoSuchAlgorithmException, SignatureException, InvalidKeyException { TBSCertList tbsCrl = generateCertList(); byte[] signature; try { signature = X509Util.calculateSignature(sigOID, signatureAlgorithm, provider, key, random, tbsCrl); } catch (IOException e) { throw new ExtCRLException("cannot generate CRL encoding", e); } return generateJcaObject(tbsCrl, signature); } private TBSCertList generateCertList() { if (!extGenerator.isEmpty()) { tbsGen.setExtensions(extGenerator.generate()); } return tbsGen.generateTBSCertList(); } private X509CRL generateJcaObject(TBSCertList tbsCrl, byte[] signature) throws CRLException { ASN1EncodableVector v = new ASN1EncodableVector(); v.add(tbsCrl); v.add(sigAlgId); v.add(new DERBitString(signature)); return new X509CRLObject(new CertificateList(new DERSequence(v))); } /** * Return an iterator of the signature names supported by the generator. * * @return an iterator containing recognised names. */ public Iterator getSignatureAlgNames() { return X509Util.getAlgNames(); } private static class ExtCRLException extends CRLException { Throwable cause; ExtCRLException(String message, Throwable cause) { super(message); this.cause = cause; } public Throwable getCause() { return cause; } } } bouncycastle-1.49.orig/src/org/bouncycastle/x509/NoSuchStoreException.java0000644000175000017500000000026010522776714026156 0ustar ebourgebourgpackage org.bouncycastle.x509; public class NoSuchStoreException extends Exception { public NoSuchStoreException(String message) { super(message); } } bouncycastle-1.49.orig/src/org/bouncycastle/x509/X509V2AttributeCertificate.java0000644000175000017500000002225011724262747026773 0ustar ebourgebourgpackage org.bouncycastle.x509; import java.io.ByteArrayInputStream; import java.io.IOException; import java.io.InputStream; import java.math.BigInteger; import java.security.InvalidKeyException; import java.security.NoSuchAlgorithmException; import java.security.NoSuchProviderException; import java.security.PublicKey; import java.security.Signature; import java.security.SignatureException; import java.security.cert.CertificateException; import java.security.cert.CertificateExpiredException; import java.security.cert.CertificateNotYetValidException; import java.text.ParseException; import java.util.ArrayList; import java.util.Date; import java.util.Enumeration; import java.util.HashSet; import java.util.List; import java.util.Set; import org.bouncycastle.asn1.ASN1Encodable; import org.bouncycastle.asn1.ASN1Encoding; import org.bouncycastle.asn1.ASN1InputStream; import org.bouncycastle.asn1.ASN1ObjectIdentifier; import org.bouncycastle.asn1.ASN1Sequence; import org.bouncycastle.asn1.DERBitString; import org.bouncycastle.asn1.x509.AttributeCertificate; import org.bouncycastle.asn1.x509.Extension; import org.bouncycastle.asn1.x509.Extensions; import org.bouncycastle.util.Arrays; /** * An implementation of a version 2 X.509 Attribute Certificate. * @deprecated use org.bouncycastle.cert.X509AttributeCertificateHolder */ public class X509V2AttributeCertificate implements X509AttributeCertificate { private AttributeCertificate cert; private Date notBefore; private Date notAfter; private static AttributeCertificate getObject(InputStream in) throws IOException { try { return AttributeCertificate.getInstance(new ASN1InputStream(in).readObject()); } catch (IOException e) { throw e; } catch (Exception e) { throw new IOException("exception decoding certificate structure: " + e.toString()); } } public X509V2AttributeCertificate( InputStream encIn) throws IOException { this(getObject(encIn)); } public X509V2AttributeCertificate( byte[] encoded) throws IOException { this(new ByteArrayInputStream(encoded)); } X509V2AttributeCertificate( AttributeCertificate cert) throws IOException { this.cert = cert; try { this.notAfter = cert.getAcinfo().getAttrCertValidityPeriod().getNotAfterTime().getDate(); this.notBefore = cert.getAcinfo().getAttrCertValidityPeriod().getNotBeforeTime().getDate(); } catch (ParseException e) { throw new IOException("invalid data structure in certificate!"); } } public int getVersion() { return cert.getAcinfo().getVersion().getValue().intValue() + 1; } public BigInteger getSerialNumber() { return cert.getAcinfo().getSerialNumber().getValue(); } public AttributeCertificateHolder getHolder() { return new AttributeCertificateHolder((ASN1Sequence)cert.getAcinfo().getHolder().toASN1Object()); } public AttributeCertificateIssuer getIssuer() { return new AttributeCertificateIssuer(cert.getAcinfo().getIssuer()); } public Date getNotBefore() { return notBefore; } public Date getNotAfter() { return notAfter; } public boolean[] getIssuerUniqueID() { DERBitString id = cert.getAcinfo().getIssuerUniqueID(); if (id != null) { byte[] bytes = id.getBytes(); boolean[] boolId = new boolean[bytes.length * 8 - id.getPadBits()]; for (int i = 0; i != boolId.length; i++) { boolId[i] = (bytes[i / 8] & (0x80 >>> (i % 8))) != 0; } return boolId; } return null; } public void checkValidity() throws CertificateExpiredException, CertificateNotYetValidException { this.checkValidity(new Date()); } public void checkValidity( Date date) throws CertificateExpiredException, CertificateNotYetValidException { if (date.after(this.getNotAfter())) { throw new CertificateExpiredException("certificate expired on " + this.getNotAfter()); } if (date.before(this.getNotBefore())) { throw new CertificateNotYetValidException("certificate not valid till " + this.getNotBefore()); } } public byte[] getSignature() { return cert.getSignatureValue().getBytes(); } public final void verify( PublicKey key, String provider) throws CertificateException, NoSuchAlgorithmException, InvalidKeyException, NoSuchProviderException, SignatureException { Signature signature = null; if (!cert.getSignatureAlgorithm().equals(cert.getAcinfo().getSignature())) { throw new CertificateException("Signature algorithm in certificate info not same as outer certificate"); } signature = Signature.getInstance(cert.getSignatureAlgorithm().getObjectId().getId(), provider); signature.initVerify(key); try { signature.update(cert.getAcinfo().getEncoded()); } catch (IOException e) { throw new SignatureException("Exception encoding certificate info object"); } if (!signature.verify(this.getSignature())) { throw new InvalidKeyException("Public key presented not for certificate signature"); } } public byte[] getEncoded() throws IOException { return cert.getEncoded(); } public byte[] getExtensionValue(String oid) { Extensions extensions = cert.getAcinfo().getExtensions(); if (extensions != null) { Extension ext = extensions.getExtension(new ASN1ObjectIdentifier(oid)); if (ext != null) { try { return ext.getExtnValue().getEncoded(ASN1Encoding.DER); } catch (Exception e) { throw new RuntimeException("error encoding " + e.toString()); } } } return null; } private Set getExtensionOIDs( boolean critical) { Extensions extensions = cert.getAcinfo().getExtensions(); if (extensions != null) { Set set = new HashSet(); Enumeration e = extensions.oids(); while (e.hasMoreElements()) { ASN1ObjectIdentifier oid = (ASN1ObjectIdentifier)e.nextElement(); Extension ext = extensions.getExtension(oid); if (ext.isCritical() == critical) { set.add(oid.getId()); } } return set; } return null; } public Set getNonCriticalExtensionOIDs() { return getExtensionOIDs(false); } public Set getCriticalExtensionOIDs() { return getExtensionOIDs(true); } public boolean hasUnsupportedCriticalExtension() { Set extensions = getCriticalExtensionOIDs(); return extensions != null && !extensions.isEmpty(); } public X509Attribute[] getAttributes() { ASN1Sequence seq = cert.getAcinfo().getAttributes(); X509Attribute[] attrs = new X509Attribute[seq.size()]; for (int i = 0; i != seq.size(); i++) { attrs[i] = new X509Attribute((ASN1Encodable)seq.getObjectAt(i)); } return attrs; } public X509Attribute[] getAttributes(String oid) { ASN1Sequence seq = cert.getAcinfo().getAttributes(); List list = new ArrayList(); for (int i = 0; i != seq.size(); i++) { X509Attribute attr = new X509Attribute((ASN1Encodable)seq.getObjectAt(i)); if (attr.getOID().equals(oid)) { list.add(attr); } } if (list.size() == 0) { return null; } return (X509Attribute[])list.toArray(new X509Attribute[list.size()]); } public boolean equals( Object o) { if (o == this) { return true; } if (!(o instanceof X509AttributeCertificate)) { return false; } X509AttributeCertificate other = (X509AttributeCertificate)o; try { byte[] b1 = this.getEncoded(); byte[] b2 = other.getEncoded(); return Arrays.areEqual(b1, b2); } catch (IOException e) { return false; } } public int hashCode() { try { return Arrays.hashCode(this.getEncoded()); } catch (IOException e) { return 0; } } } bouncycastle-1.49.orig/src/org/bouncycastle/x509/X509V1CertificateGenerator.java0000644000175000017500000002670312132656275026761 0ustar ebourgebourgpackage org.bouncycastle.x509; import java.io.ByteArrayInputStream; import java.io.IOException; import java.math.BigInteger; import java.security.GeneralSecurityException; import java.security.InvalidKeyException; import java.security.NoSuchAlgorithmException; import java.security.NoSuchProviderException; import java.security.PrivateKey; import java.security.PublicKey; import java.security.SecureRandom; import java.security.SignatureException; import java.security.cert.CertificateEncodingException; import java.security.cert.CertificateParsingException; import java.security.cert.X509Certificate; import java.util.Date; import java.util.Iterator; import javax.security.auth.x500.X500Principal; import org.bouncycastle.asn1.ASN1EncodableVector; import org.bouncycastle.asn1.ASN1InputStream; import org.bouncycastle.asn1.ASN1Integer; import org.bouncycastle.asn1.ASN1Sequence; import org.bouncycastle.asn1.DERBitString; import org.bouncycastle.asn1.DERObjectIdentifier; import org.bouncycastle.asn1.DERSequence; import org.bouncycastle.asn1.x509.AlgorithmIdentifier; import org.bouncycastle.asn1.x509.Certificate; import org.bouncycastle.asn1.x509.SubjectPublicKeyInfo; import org.bouncycastle.asn1.x509.TBSCertificate; import org.bouncycastle.asn1.x509.Time; import org.bouncycastle.asn1.x509.V1TBSCertificateGenerator; import org.bouncycastle.asn1.x509.X509Name; import org.bouncycastle.jce.X509Principal; import org.bouncycastle.jce.provider.X509CertificateObject; /** * class to produce an X.509 Version 1 certificate. * @deprecated use org.bouncycastle.cert.X509v1CertificateBuilder. */ public class X509V1CertificateGenerator { private V1TBSCertificateGenerator tbsGen; private DERObjectIdentifier sigOID; private AlgorithmIdentifier sigAlgId; private String signatureAlgorithm; public X509V1CertificateGenerator() { tbsGen = new V1TBSCertificateGenerator(); } /** * reset the generator */ public void reset() { tbsGen = new V1TBSCertificateGenerator(); } /** * set the serial number for the certificate. */ public void setSerialNumber( BigInteger serialNumber) { if (serialNumber.compareTo(BigInteger.ZERO) <= 0) { throw new IllegalArgumentException("serial number must be a positive integer"); } tbsGen.setSerialNumber(new ASN1Integer(serialNumber)); } /** * Set the issuer distinguished name - the issuer is the entity whose private key is used to sign the * certificate. */ public void setIssuerDN( X500Principal issuer) { try { tbsGen.setIssuer(new X509Principal(issuer.getEncoded())); } catch (IOException e) { throw new IllegalArgumentException("can't process principal: " + e); } } /** * Set the issuer distinguished name - the issuer is the entity whose private key is used to sign the * certificate. */ public void setIssuerDN( X509Name issuer) { tbsGen.setIssuer(issuer); } public void setNotBefore( Date date) { tbsGen.setStartDate(new Time(date)); } public void setNotAfter( Date date) { tbsGen.setEndDate(new Time(date)); } /** * Set the subject distinguished name. The subject describes the entity associated with the public key. */ public void setSubjectDN( X500Principal subject) { try { tbsGen.setSubject(new X509Principal(subject.getEncoded())); } catch (IOException e) { throw new IllegalArgumentException("can't process principal: " + e); } } /** * Set the subject distinguished name. The subject describes the entity associated with the public key. */ public void setSubjectDN( X509Name subject) { tbsGen.setSubject(subject); } public void setPublicKey( PublicKey key) { try { tbsGen.setSubjectPublicKeyInfo(new SubjectPublicKeyInfo((ASN1Sequence)new ASN1InputStream( new ByteArrayInputStream(key.getEncoded())).readObject())); } catch (Exception e) { throw new IllegalArgumentException("unable to process key - " + e.toString()); } } /** * Set the signature algorithm. This can be either a name or an OID, names * are treated as case insensitive. * * @param signatureAlgorithm string representation of the algorithm name. */ public void setSignatureAlgorithm( String signatureAlgorithm) { this.signatureAlgorithm = signatureAlgorithm; try { sigOID = X509Util.getAlgorithmOID(signatureAlgorithm); } catch (Exception e) { throw new IllegalArgumentException("Unknown signature type requested"); } sigAlgId = X509Util.getSigAlgID(sigOID, signatureAlgorithm); tbsGen.setSignature(sigAlgId); } /** * generate an X509 certificate, based on the current issuer and subject * using the default provider "BC". * @deprecated use generate(key, "BC") */ public X509Certificate generateX509Certificate( PrivateKey key) throws SecurityException, SignatureException, InvalidKeyException { try { return generateX509Certificate(key, "BC", null); } catch (NoSuchProviderException e) { throw new SecurityException("BC provider not installed!"); } } /** * generate an X509 certificate, based on the current issuer and subject * using the default provider "BC" and the passed in source of randomness * @deprecated use generate(key, random, "BC") */ public X509Certificate generateX509Certificate( PrivateKey key, SecureRandom random) throws SecurityException, SignatureException, InvalidKeyException { try { return generateX509Certificate(key, "BC", random); } catch (NoSuchProviderException e) { throw new SecurityException("BC provider not installed!"); } } /** * generate an X509 certificate, based on the current issuer and subject, * using the passed in provider for the signing, and the passed in source * of randomness (if required). * @deprecated use generate() */ public X509Certificate generateX509Certificate( PrivateKey key, String provider) throws NoSuchProviderException, SecurityException, SignatureException, InvalidKeyException { return generateX509Certificate(key, provider, null); } /** * generate an X509 certificate, based on the current issuer and subject, * using the passed in provider for the signing, and the passed in source * of randomness (if required). * @deprecated use generate() */ public X509Certificate generateX509Certificate( PrivateKey key, String provider, SecureRandom random) throws NoSuchProviderException, SecurityException, SignatureException, InvalidKeyException { try { return generate(key, provider, random); } catch (NoSuchProviderException e) { throw e; } catch (SignatureException e) { throw e; } catch (InvalidKeyException e) { throw e; } catch (GeneralSecurityException e) { throw new SecurityException("exception: " + e); } } /** * generate an X509 certificate, based on the current issuer and subject * using the default provider. *

    * Note: this differs from the deprecated method in that the default provider is * used - not "BC". *

    */ public X509Certificate generate( PrivateKey key) throws CertificateEncodingException, IllegalStateException, NoSuchAlgorithmException, SignatureException, InvalidKeyException { return generate(key, (SecureRandom)null); } /** * generate an X509 certificate, based on the current issuer and subject * using the default provider and the passed in source of randomness *

    * Note: this differs from the deprecated method in that the default provider is * used - not "BC". *

    */ public X509Certificate generate( PrivateKey key, SecureRandom random) throws CertificateEncodingException, IllegalStateException, NoSuchAlgorithmException, SignatureException, InvalidKeyException { TBSCertificate tbsCert = tbsGen.generateTBSCertificate(); byte[] signature; try { signature = X509Util.calculateSignature(sigOID, signatureAlgorithm, key, random, tbsCert); } catch (IOException e) { throw new ExtCertificateEncodingException("exception encoding TBS cert", e); } return generateJcaObject(tbsCert, signature); } /** * generate an X509 certificate, based on the current issuer and subject, * using the passed in provider for the signing, and the passed in source * of randomness (if required). */ public X509Certificate generate( PrivateKey key, String provider) throws CertificateEncodingException, IllegalStateException, NoSuchProviderException, NoSuchAlgorithmException, SignatureException, InvalidKeyException { return generate(key, provider, null); } /** * generate an X509 certificate, based on the current issuer and subject, * using the passed in provider for the signing, and the passed in source * of randomness (if required). */ public X509Certificate generate( PrivateKey key, String provider, SecureRandom random) throws CertificateEncodingException, IllegalStateException, NoSuchProviderException, NoSuchAlgorithmException, SignatureException, InvalidKeyException { TBSCertificate tbsCert = tbsGen.generateTBSCertificate(); byte[] signature; try { signature = X509Util.calculateSignature(sigOID, signatureAlgorithm, provider, key, random, tbsCert); } catch (IOException e) { throw new ExtCertificateEncodingException("exception encoding TBS cert", e); } return generateJcaObject(tbsCert, signature); } private X509Certificate generateJcaObject(TBSCertificate tbsCert, byte[] signature) throws CertificateEncodingException { ASN1EncodableVector v = new ASN1EncodableVector(); v.add(tbsCert); v.add(sigAlgId); v.add(new DERBitString(signature)); try { return new X509CertificateObject(Certificate.getInstance(new DERSequence(v))); } catch (CertificateParsingException e) { throw new ExtCertificateEncodingException("exception producing certificate object", e); } } /** * Return an iterator of the signature names supported by the generator. * * @return an iterator containing recognised names. */ public Iterator getSignatureAlgNames() { return X509Util.getAlgNames(); } } bouncycastle-1.49.orig/src/org/bouncycastle/x509/X509AttributeCertStoreSelector.java0000644000175000017500000003522411624572761027760 0ustar ebourgebourgpackage org.bouncycastle.x509; import java.io.IOException; import java.math.BigInteger; import java.security.cert.CertificateExpiredException; import java.security.cert.CertificateNotYetValidException; import java.util.Collection; import java.util.Collections; import java.util.Date; import java.util.HashSet; import java.util.Iterator; import java.util.Set; import org.bouncycastle.asn1.ASN1InputStream; import org.bouncycastle.asn1.ASN1Primitive; import org.bouncycastle.asn1.DEROctetString; import org.bouncycastle.asn1.x509.GeneralName; import org.bouncycastle.asn1.x509.Target; import org.bouncycastle.asn1.x509.TargetInformation; import org.bouncycastle.asn1.x509.Targets; import org.bouncycastle.asn1.x509.X509Extensions; import org.bouncycastle.util.Selector; /** * This class is an Selector like implementation to select * attribute certificates from a given set of criteria. * * @see org.bouncycastle.x509.X509AttributeCertificate * @see org.bouncycastle.x509.X509Store * @deprecated use org.bouncycastle.cert.X509AttributeCertificateSelector and org.bouncycastle.cert.X509AttributeCertificateSelectorBuilder. */ public class X509AttributeCertStoreSelector implements Selector { // TODO: name constraints??? private AttributeCertificateHolder holder; private AttributeCertificateIssuer issuer; private BigInteger serialNumber; private Date attributeCertificateValid; private X509AttributeCertificate attributeCert; private Collection targetNames = new HashSet(); private Collection targetGroups = new HashSet(); public X509AttributeCertStoreSelector() { super(); } /** * Decides if the given attribute certificate should be selected. * * @param obj The attribute certificate which should be checked. * @return true if the attribute certificate can be selected, * false otherwise. */ public boolean match(Object obj) { if (!(obj instanceof X509AttributeCertificate)) { return false; } X509AttributeCertificate attrCert = (X509AttributeCertificate) obj; if (this.attributeCert != null) { if (!this.attributeCert.equals(attrCert)) { return false; } } if (serialNumber != null) { if (!attrCert.getSerialNumber().equals(serialNumber)) { return false; } } if (holder != null) { if (!attrCert.getHolder().equals(holder)) { return false; } } if (issuer != null) { if (!attrCert.getIssuer().equals(issuer)) { return false; } } if (attributeCertificateValid != null) { try { attrCert.checkValidity(attributeCertificateValid); } catch (CertificateExpiredException e) { return false; } catch (CertificateNotYetValidException e) { return false; } } if (!targetNames.isEmpty() || !targetGroups.isEmpty()) { byte[] targetInfoExt = attrCert .getExtensionValue(X509Extensions.TargetInformation.getId()); if (targetInfoExt != null) { TargetInformation targetinfo; try { targetinfo = TargetInformation .getInstance(new ASN1InputStream( ((DEROctetString) DEROctetString .fromByteArray(targetInfoExt)).getOctets()) .readObject()); } catch (IOException e) { return false; } catch (IllegalArgumentException e) { return false; } Targets[] targetss = targetinfo.getTargetsObjects(); if (!targetNames.isEmpty()) { boolean found = false; for (int i=0; inull is * given any will do. * * @param attributeCert The attribute certificate to set. */ public void setAttributeCert(X509AttributeCertificate attributeCert) { this.attributeCert = attributeCert; } /** * Get the criteria for the validity. * * @return Returns the attributeCertificateValid. */ public Date getAttributeCertificateValid() { if (attributeCertificateValid != null) { return new Date(attributeCertificateValid.getTime()); } return null; } /** * Set the time, when the certificate must be valid. If null * is given any will do. * * @param attributeCertificateValid The attribute certificate validation * time to set. */ public void setAttributeCertificateValid(Date attributeCertificateValid) { if (attributeCertificateValid != null) { this.attributeCertificateValid = new Date(attributeCertificateValid .getTime()); } else { this.attributeCertificateValid = null; } } /** * Gets the holder. * * @return Returns the holder. */ public AttributeCertificateHolder getHolder() { return holder; } /** * Sets the holder. If null is given any will do. * * @param holder The holder to set. */ public void setHolder(AttributeCertificateHolder holder) { this.holder = holder; } /** * Returns the issuer criterion. * * @return Returns the issuer. */ public AttributeCertificateIssuer getIssuer() { return issuer; } /** * Sets the issuer the attribute certificate must have. If null * is given any will do. * * @param issuer The issuer to set. */ public void setIssuer(AttributeCertificateIssuer issuer) { this.issuer = issuer; } /** * Gets the serial number the attribute certificate must have. * * @return Returns the serialNumber. */ public BigInteger getSerialNumber() { return serialNumber; } /** * Sets the serial number the attribute certificate must have. If * null is given any will do. * * @param serialNumber The serialNumber to set. */ public void setSerialNumber(BigInteger serialNumber) { this.serialNumber = serialNumber; } /** * Adds a target name criterion for the attribute certificate to the target * information extension criteria. The X509AttributeCertificate * must contain at least one of the specified target names. *

    * Each attribute certificate may contain a target information extension * limiting the servers where this attribute certificate can be used. If * this extension is not present, the attribute certificate is not targeted * and may be accepted by any server. * * @param name The name as a GeneralName (not null) */ public void addTargetName(GeneralName name) { targetNames.add(name); } /** * Adds a target name criterion for the attribute certificate to the target * information extension criteria. The X509AttributeCertificate * must contain at least one of the specified target names. *

    * Each attribute certificate may contain a target information extension * limiting the servers where this attribute certificate can be used. If * this extension is not present, the attribute certificate is not targeted * and may be accepted by any server. * * @param name a byte array containing the name in ASN.1 DER encoded form of a GeneralName * @throws IOException if a parsing error occurs. */ public void addTargetName(byte[] name) throws IOException { addTargetName(GeneralName.getInstance(ASN1Primitive.fromByteArray(name))); } /** * Adds a collection with target names criteria. If null is * given any will do. *

    * The collection consists of either GeneralName objects or byte[] arrays representing * DER encoded GeneralName structures. * * @param names A collection of target names. * @throws IOException if a parsing error occurs. * @see #addTargetName(byte[]) * @see #addTargetName(GeneralName) */ public void setTargetNames(Collection names) throws IOException { targetNames = extractGeneralNames(names); } /** * Gets the target names. The collection consists of GeneralName * objects. *

    * The returned collection is immutable. * * @return The collection of target names * @see #setTargetNames(Collection) */ public Collection getTargetNames() { return Collections.unmodifiableCollection(targetNames); } /** * Adds a target group criterion for the attribute certificate to the target * information extension criteria. The X509AttributeCertificate * must contain at least one of the specified target groups. *

    * Each attribute certificate may contain a target information extension * limiting the servers where this attribute certificate can be used. If * this extension is not present, the attribute certificate is not targeted * and may be accepted by any server. * * @param group The group as GeneralName form (not null) */ public void addTargetGroup(GeneralName group) { targetGroups.add(group); } /** * Adds a target group criterion for the attribute certificate to the target * information extension criteria. The X509AttributeCertificate * must contain at least one of the specified target groups. *

    * Each attribute certificate may contain a target information extension * limiting the servers where this attribute certificate can be used. If * this extension is not present, the attribute certificate is not targeted * and may be accepted by any server. * * @param name a byte array containing the group in ASN.1 DER encoded form of a GeneralName * @throws IOException if a parsing error occurs. */ public void addTargetGroup(byte[] name) throws IOException { addTargetGroup(GeneralName.getInstance(ASN1Primitive.fromByteArray(name))); } /** * Adds a collection with target groups criteria. If null is * given any will do. *

    * The collection consists of GeneralName objects or byte[]GeneralName objects. *

    * The returned collection is immutable. * * @return The collection of target groups. * @see #setTargetGroups(Collection) */ public Collection getTargetGroups() { return Collections.unmodifiableCollection(targetGroups); } private Set extractGeneralNames(Collection names) throws IOException { if (names == null || names.isEmpty()) { return new HashSet(); } Set temp = new HashSet(); for (Iterator it = names.iterator(); it.hasNext();) { Object o = it.next(); if (o instanceof GeneralName) { temp.add(o); } else { temp.add(GeneralName.getInstance(ASN1Primitive.fromByteArray((byte[])o))); } } return temp; } } bouncycastle-1.49.orig/src/org/bouncycastle/x509/X509V3CertificateGenerator.java0000644000175000017500000003726012132656275026763 0ustar ebourgebourgpackage org.bouncycastle.x509; import java.io.IOException; import java.math.BigInteger; import java.security.GeneralSecurityException; import java.security.InvalidKeyException; import java.security.NoSuchAlgorithmException; import java.security.NoSuchProviderException; import java.security.PrivateKey; import java.security.PublicKey; import java.security.SecureRandom; import java.security.SignatureException; import java.security.cert.CertificateEncodingException; import java.security.cert.CertificateParsingException; import java.security.cert.X509Certificate; import java.util.Date; import java.util.Iterator; import javax.security.auth.x500.X500Principal; import org.bouncycastle.asn1.ASN1Encodable; import org.bouncycastle.asn1.ASN1EncodableVector; import org.bouncycastle.asn1.ASN1InputStream; import org.bouncycastle.asn1.ASN1Integer; import org.bouncycastle.asn1.ASN1ObjectIdentifier; import org.bouncycastle.asn1.DERBitString; import org.bouncycastle.asn1.DERObjectIdentifier; import org.bouncycastle.asn1.DERSequence; import org.bouncycastle.asn1.x509.AlgorithmIdentifier; import org.bouncycastle.asn1.x509.Certificate; import org.bouncycastle.asn1.x509.SubjectPublicKeyInfo; import org.bouncycastle.asn1.x509.TBSCertificate; import org.bouncycastle.asn1.x509.Time; import org.bouncycastle.asn1.x509.V3TBSCertificateGenerator; import org.bouncycastle.asn1.x509.X509ExtensionsGenerator; import org.bouncycastle.asn1.x509.X509Name; import org.bouncycastle.jce.X509Principal; import org.bouncycastle.jce.provider.X509CertificateObject; import org.bouncycastle.x509.extension.X509ExtensionUtil; /** * class to produce an X.509 Version 3 certificate. * @deprecated use org.bouncycastle.cert.X509v3CertificateBuilder. */ public class X509V3CertificateGenerator { private V3TBSCertificateGenerator tbsGen; private DERObjectIdentifier sigOID; private AlgorithmIdentifier sigAlgId; private String signatureAlgorithm; private X509ExtensionsGenerator extGenerator; public X509V3CertificateGenerator() { tbsGen = new V3TBSCertificateGenerator(); extGenerator = new X509ExtensionsGenerator(); } /** * reset the generator */ public void reset() { tbsGen = new V3TBSCertificateGenerator(); extGenerator.reset(); } /** * set the serial number for the certificate. */ public void setSerialNumber( BigInteger serialNumber) { if (serialNumber.compareTo(BigInteger.ZERO) <= 0) { throw new IllegalArgumentException("serial number must be a positive integer"); } tbsGen.setSerialNumber(new ASN1Integer(serialNumber)); } /** * Set the issuer distinguished name - the issuer is the entity whose private key is used to sign the * certificate. */ public void setIssuerDN( X500Principal issuer) { try { tbsGen.setIssuer(new X509Principal(issuer.getEncoded())); } catch (IOException e) { throw new IllegalArgumentException("can't process principal: " + e); } } /** * Set the issuer distinguished name - the issuer is the entity whose private key is used to sign the * certificate. */ public void setIssuerDN( X509Name issuer) { tbsGen.setIssuer(issuer); } public void setNotBefore( Date date) { tbsGen.setStartDate(new Time(date)); } public void setNotAfter( Date date) { tbsGen.setEndDate(new Time(date)); } /** * Set the subject distinguished name. The subject describes the entity associated with the public key. */ public void setSubjectDN( X500Principal subject) { try { tbsGen.setSubject(new X509Principal(subject.getEncoded())); } catch (IOException e) { throw new IllegalArgumentException("can't process principal: " + e); } } /** * Set the subject distinguished name. The subject describes the entity associated with the public key. */ public void setSubjectDN( X509Name subject) { tbsGen.setSubject(subject); } public void setPublicKey( PublicKey key) throws IllegalArgumentException { try { tbsGen.setSubjectPublicKeyInfo( SubjectPublicKeyInfo.getInstance(new ASN1InputStream(key.getEncoded()).readObject())); } catch (Exception e) { throw new IllegalArgumentException("unable to process key - " + e.toString()); } } /** * Set the signature algorithm. This can be either a name or an OID, names * are treated as case insensitive. * * @param signatureAlgorithm string representation of the algorithm name. */ public void setSignatureAlgorithm( String signatureAlgorithm) { this.signatureAlgorithm = signatureAlgorithm; try { sigOID = X509Util.getAlgorithmOID(signatureAlgorithm); } catch (Exception e) { throw new IllegalArgumentException("Unknown signature type requested: " + signatureAlgorithm); } sigAlgId = X509Util.getSigAlgID(sigOID, signatureAlgorithm); tbsGen.setSignature(sigAlgId); } /** * Set the subject unique ID - note: it is very rare that it is correct to do this. */ public void setSubjectUniqueID(boolean[] uniqueID) { tbsGen.setSubjectUniqueID(booleanToBitString(uniqueID)); } /** * Set the issuer unique ID - note: it is very rare that it is correct to do this. */ public void setIssuerUniqueID(boolean[] uniqueID) { tbsGen.setIssuerUniqueID(booleanToBitString(uniqueID)); } private DERBitString booleanToBitString(boolean[] id) { byte[] bytes = new byte[(id.length + 7) / 8]; for (int i = 0; i != id.length; i++) { bytes[i / 8] |= (id[i]) ? (1 << ((7 - (i % 8)))) : 0; } int pad = id.length % 8; if (pad == 0) { return new DERBitString(bytes); } else { return new DERBitString(bytes, 8 - pad); } } /** * add a given extension field for the standard extensions tag (tag 3) */ public void addExtension( String oid, boolean critical, ASN1Encodable value) { this.addExtension(new DERObjectIdentifier(oid), critical, value); } /** * add a given extension field for the standard extensions tag (tag 3) */ public void addExtension( DERObjectIdentifier oid, boolean critical, ASN1Encodable value) { extGenerator.addExtension(new ASN1ObjectIdentifier(oid.getId()), critical, value); } /** * add a given extension field for the standard extensions tag (tag 3) * The value parameter becomes the contents of the octet string associated * with the extension. */ public void addExtension( String oid, boolean critical, byte[] value) { this.addExtension(new DERObjectIdentifier(oid), critical, value); } /** * add a given extension field for the standard extensions tag (tag 3) */ public void addExtension( DERObjectIdentifier oid, boolean critical, byte[] value) { extGenerator.addExtension(new ASN1ObjectIdentifier(oid.getId()), critical, value); } /** * add a given extension field for the standard extensions tag (tag 3) * copying the extension value from another certificate. * @throws CertificateParsingException if the extension cannot be extracted. */ public void copyAndAddExtension( String oid, boolean critical, X509Certificate cert) throws CertificateParsingException { byte[] extValue = cert.getExtensionValue(oid); if (extValue == null) { throw new CertificateParsingException("extension " + oid + " not present"); } try { ASN1Encodable value = X509ExtensionUtil.fromExtensionValue(extValue); this.addExtension(oid, critical, value); } catch (IOException e) { throw new CertificateParsingException(e.toString()); } } /** * add a given extension field for the standard extensions tag (tag 3) * copying the extension value from another certificate. * @throws CertificateParsingException if the extension cannot be extracted. */ public void copyAndAddExtension( DERObjectIdentifier oid, boolean critical, X509Certificate cert) throws CertificateParsingException { this.copyAndAddExtension(oid.getId(), critical, cert); } /** * generate an X509 certificate, based on the current issuer and subject * using the default provider "BC". * @deprecated use generate(key, "BC") */ public X509Certificate generateX509Certificate( PrivateKey key) throws SecurityException, SignatureException, InvalidKeyException { try { return generateX509Certificate(key, "BC", null); } catch (NoSuchProviderException e) { throw new SecurityException("BC provider not installed!"); } } /** * generate an X509 certificate, based on the current issuer and subject * using the default provider "BC", and the passed in source of randomness * (if required). * @deprecated use generate(key, random, "BC") */ public X509Certificate generateX509Certificate( PrivateKey key, SecureRandom random) throws SecurityException, SignatureException, InvalidKeyException { try { return generateX509Certificate(key, "BC", random); } catch (NoSuchProviderException e) { throw new SecurityException("BC provider not installed!"); } } /** * generate an X509 certificate, based on the current issuer and subject, * using the passed in provider for the signing. * @deprecated use generate() */ public X509Certificate generateX509Certificate( PrivateKey key, String provider) throws NoSuchProviderException, SecurityException, SignatureException, InvalidKeyException { return generateX509Certificate(key, provider, null); } /** * generate an X509 certificate, based on the current issuer and subject, * using the passed in provider for the signing and the supplied source * of randomness, if required. * @deprecated use generate() */ public X509Certificate generateX509Certificate( PrivateKey key, String provider, SecureRandom random) throws NoSuchProviderException, SecurityException, SignatureException, InvalidKeyException { try { return generate(key, provider, random); } catch (NoSuchProviderException e) { throw e; } catch (SignatureException e) { throw e; } catch (InvalidKeyException e) { throw e; } catch (GeneralSecurityException e) { throw new SecurityException("exception: " + e); } } /** * generate an X509 certificate, based on the current issuer and subject * using the default provider. *

    * Note: this differs from the deprecated method in that the default provider is * used - not "BC". *

    */ public X509Certificate generate( PrivateKey key) throws CertificateEncodingException, IllegalStateException, NoSuchAlgorithmException, SignatureException, InvalidKeyException { return generate(key, (SecureRandom)null); } /** * generate an X509 certificate, based on the current issuer and subject * using the default provider, and the passed in source of randomness * (if required). *

    * Note: this differs from the deprecated method in that the default provider is * used - not "BC". *

    */ public X509Certificate generate( PrivateKey key, SecureRandom random) throws CertificateEncodingException, IllegalStateException, NoSuchAlgorithmException, SignatureException, InvalidKeyException { TBSCertificate tbsCert = generateTbsCert(); byte[] signature; try { signature = X509Util.calculateSignature(sigOID, signatureAlgorithm, key, random, tbsCert); } catch (IOException e) { throw new ExtCertificateEncodingException("exception encoding TBS cert", e); } try { return generateJcaObject(tbsCert, signature); } catch (CertificateParsingException e) { throw new ExtCertificateEncodingException("exception producing certificate object", e); } } /** * generate an X509 certificate, based on the current issuer and subject, * using the passed in provider for the signing. */ public X509Certificate generate( PrivateKey key, String provider) throws CertificateEncodingException, IllegalStateException, NoSuchProviderException, NoSuchAlgorithmException, SignatureException, InvalidKeyException { return generate(key, provider, null); } /** * generate an X509 certificate, based on the current issuer and subject, * using the passed in provider for the signing and the supplied source * of randomness, if required. */ public X509Certificate generate( PrivateKey key, String provider, SecureRandom random) throws CertificateEncodingException, IllegalStateException, NoSuchProviderException, NoSuchAlgorithmException, SignatureException, InvalidKeyException { TBSCertificate tbsCert = generateTbsCert(); byte[] signature; try { signature = X509Util.calculateSignature(sigOID, signatureAlgorithm, provider, key, random, tbsCert); } catch (IOException e) { throw new ExtCertificateEncodingException("exception encoding TBS cert", e); } try { return generateJcaObject(tbsCert, signature); } catch (CertificateParsingException e) { throw new ExtCertificateEncodingException("exception producing certificate object", e); } } private TBSCertificate generateTbsCert() { if (!extGenerator.isEmpty()) { tbsGen.setExtensions(extGenerator.generate()); } return tbsGen.generateTBSCertificate(); } private X509Certificate generateJcaObject(TBSCertificate tbsCert, byte[] signature) throws CertificateParsingException { ASN1EncodableVector v = new ASN1EncodableVector(); v.add(tbsCert); v.add(sigAlgId); v.add(new DERBitString(signature)); return new X509CertificateObject(Certificate.getInstance(new DERSequence(v))); } /** * Return an iterator of the signature names supported by the generator. * * @return an iterator containing recognised names. */ public Iterator getSignatureAlgNames() { return X509Util.getAlgNames(); } } bouncycastle-1.49.orig/src/org/bouncycastle/x509/CertPathReviewerMessages_de.properties0000644000175000017500000014071011251104466030713 0ustar ebourgebourg ## constructor exceptions # cert path is empty CertPathReviewer.emptyCertPath.title = Zertifizierungspfad ist leer CertPathReviewer.emptyCertPath.text = PKIXCertPathReviewer: der Zertifizierungspfad ist leer. CertPathReviewer.emptyCertPath.summary = PKIXCertPathReviewer: der Zertifizierungspfad ist leer. CertPathReviewer.emptyCertPath.details = PKIXCertPathReviewer: der Zertifizierungspfad ist leer. ## name constraints processing errors # cert DN is not in the permitted tree # {0} DN as String CertPathReviewer.notPermittedDN.title = Fehler bei der Namensbeschränkung: Zertifikats DN ist nicht erlaubt CertPathReviewer.notPermittedDN.text = Fehler bei der Namensbeschränkung: Der Zertifikats DN {0} ist nicht erlaubt. CertPathReviewer.notPermittedDN.summary = Fehler bei der Namensbeschränkung: Der Zertifikats DN ist nicht erlaubt. CertPathReviewer.notPermittedDN.details = Fehler bei der Namensbeschränkung: Der Zertifikats DN {0} ist nicht im Set der erlaubten DNs. # cert DN is in the excluded tree # {0} DN as String CertPathReviewer.excludedDN.title = Fehler bei der Namensbeschränkung: Zertifikats DN ist ausgeschlossen CertPathReviewer.excludedDN.text = Fehler bei der Namensbeschränkung: Der Zertifikats DN {0} ist ausgeschlossen. CertPathReviewer.excludedDN.summary = Fehler bei der Namensbeschränkung: Der Zertifikats DN ist ausgeschlossen CertPathReviewer.excludedDN.details = Fehler bei der Namensbeschränkung: Der Zertifikats DN ist {0} is innerhalb des Sets von ausgeschlossenen DNs. # cert email is not in the permitted tree # {0} email address as String CertPathReviewer.notPermittedEmail.title = Fehler bei der Namensbeschränkung: nicht erlaubte Email Addresse CertPathReviewer.notPermittedEmail.text = Fehler bei der Namensbeschränkung: Das Zertifikat enthält die nicht erlaubte Email Addresse {0}. CertPathReviewer.notPermittedEmail.summary = Fehler bei der Namensbeschränkung: Die Email Addresse ist nicht erlaubt. CertPathReviewer.notPermittedEmail.details = Fehler bei der Namensbeschränkung: Das Zertifikat enthält die Email Addresse {0}, welche nicht im Set der erlaubten Email Addressen ist. # cert email is in the excluded tree # {0} email as String CertPathReviewer.excludedEmail.title = Fehler bei der Namensbeschränkung: Email Addresse ausgeschlossen CertPathReviewer.excludedEmail.text = Fehler bei der Namensbeschränkung: Die Email Addresse {0} im Zertifikat ist ausgeschlossen. CertPathReviewer.excludedEmail.summary = Fehler bei der Namensbeschränkung: Die Email Addresse ist ausgeschlossen. CertPathReviewer.excludedEmail.details = Fehler bei der Namensbeschränkung: Das Zertifikat enthält die Email Addresse {0}, welche im Set der ausgeschlossenen Email Addressen ist. # cert IP is not in the permitted tree # {0} ip address as String CertPathReviewer.notPermittedIP.title = Fehler bei der Namensbeschränkung: nicht erlaubte IP Addresse CertPathReviewer.notPermittedIP.text = Fehler bei der Namensbeschränkung: Das Zertifikat enthält die nicht erlaubte IP Addresse {0}. CertPathReviewer.notPermittedIP.summary = Fehler bei der Namensbeschränkung: Die IP Addresse ist nicht erlaubt. CertPathReviewer.notPermittedIP.details = Fehler bei der Namensbeschränkung: Das Zertifikat enthält die IP Addresse {0}, welche nicht im Set der erlaubten IP Addressen ist. # cert ip is in the excluded tree # {0} ip address as String CertPathReviewer.excludedIP.title = Fehler bei der Namensbeschränkung: Ausgeschlossene IP Addresse CertPathReviewer.excludedIP.text = Fehler bei der Namensbeschränkung: Das Zertifikat enhält die ausgeschlossene IP Addresse {0}. CertPathReviewer.excludedIP.summary = Fehler bei der Namensbeschränkung: Die IP Addresse im Zertifikat ist ausgeschlossen. CertPathReviewer.excludedIP.details = Fehler bei der Namensbeschränkung: Das Zertifikat enthält die IP Addresse {0}, welche im Set der ausgeschlossenen IP Addressen ist. # error processing the name constraints extension CertPathReviewer.ncExtError.title = Prüfen der Namensbeschränkungen fehlgeschlagen CertPathReviewer.ncExtError.text = Prüfen der Namensbeschränkungen fehlgeschlagen: Es gab Fehler bei der Verarbeitung der Name Constraints Erweiterung des Zertifikats. CertPathReviewer.ncExtError.summary = Prüfen der Namensbeschränkungen fehlgeschlagen: Fehler bei der Verarbeitung der Name Constraints Erweiterung. CertPathReviewer.ncExtError.details = Prüfen der Namensbeschränkungen fehlgeschlagen: Es gab Fehler bei der Verarbeitung der Name Constraints Erweiterung des Zertifikats. # error processing the subject alternative name extension CertPathReviewer.subjAltNameExtError.title = Prüfen der Namensbeschränkungen fehlgeschlagen CertPathReviewer.subjAltNameExtError.text = Prüfen der Namensbeschränkungen fehlgeschlagen: Es gab Fehler bei der Verarbeitung der Subject Alternative Name Erweiterung des Zertifikats. CertPathReviewer.subjAltNameExtError.summary = Prüfen der Namensbeschränkungen fehlgeschlagen: Fehler bei der Verarbeitung der Subject Alternative Name Erweiterung. CertPathReviewer.subjAltNameExtError.details = Prüfen der Namensbeschränkungen fehlgeschlagen: Es gab Fehler bei der Verarbeitung der Subject Alternative Name Erweiterung des Zertifikats. # exception extracting subject name when checking subtrees # {0} subject Principal CertPathReviewer.ncSubjectNameError.title = Prüfen der Namensbeschränkungen fehlgeschlagen CertPathReviewer.ncSubjectNameError.text = Prüfen der Namensbeschränkungen fehlgeschlagen: Es gab einen Fehler beim auslesen des DN des Zertifikats. CertPathReviewer.ncSubjectNameError.summary = Prüfen der Namensbeschränkungen fehlgeschlagen: Fehler beim auslesen des DNs. CertPathReviewer.ncSubjectNameError.details = Prüfen der Namensbeschränkungen fehlgeschlagen: Es gab einen Fehler beim auslesen des DN des Zertifikats. ## path length errors # max path length extended CertPathReviewer.pathLenghtExtended.title = Maximale Pfadlänge überschritten CertPathReviewer.pathLenghtExtended.text = Zertifizierungspfad ungültig: die Maximale Pfadlänge ist überschritten. CertPathReviewer.pathLenghtExtended.summary = Zertifizierungspfad ungültig: die Maximale Pfadlänge ist überschritten. CertPathReviewer.pathLenghtExtended.details = Zertifizierungspfad ungültig: die Maximale Pfadlänge ist überschritten. # error reading length constraint from basic constraint extension CertPathReviewer.processLengthConstError.title = Prüfen der Pfadlänge fehlgeschlagen CertPathReviewer.processLengthConstError.text = Prüfen der Pfadlänge fehlgeschlagen: Es gab einen Fehler bei der Verarbeitung der subject alternative name Erweiterung des Zertifikats. CertPathReviewer.processLengthConstError.summary = Fehler bei der Verarbeitung der subject alternative name Erweiterung. CertPathReviewer.processLengthConstError.details = Prüfen der Pfadlänge fehlgeschlagen: Es gab einen Fehler bei der Verarbeitung der subject alternative name Erweiterung des Zertifikats. ## path length notifications # total path length as defined in rfc 3280 # {0} the path length as Integer CertPathReviewer.totalPathLength.title = Totale Pfadlänge CertPathReviewer.totalPathLength.text = Die totale Pfadlänge ohne self-signed Zertifikate ist {0}. CertPathReviewer.totalPathLength.summary = Die totale Pfadlänge ohne self-signed Zertifikate ist {0}. CertPathReviewer.totalPathLength.details = Die totale Pfadlänge ohne self-signed Zertifikate, wie beschrieben in RFC 3280, ist {0}. ## critical extensions errors # one unknown critical extension # {0} extension as String CertPathReviewer.unknownCriticalExt.title = Unbekannte kritische Erweiterung CertPathReviewer.unknownCriticalExt.text = Das Zertifikat enhält eine unbekannte kritische Erweiterung mit der OID {0}. CertPathReviewer.unknownCriticalExt.summary = Unbekannte kritische Erweiterung: {0}. CertPathReviewer.unknownCriticalExt.details = Das Zertifikat enhält eine unbekannte kritische Erweiterung mit der OID {0}. # more unknown critical extensions # {0} extensions as Set of Strings CertPathReviewer.unknownCriticalExts.title = Unbekannte kritische Erweiterung CertPathReviewer.unknownCriticalExts.text = Das Zertifikat enhält zwei oder mehr unbekannte kritische Erweiterungen mit den OIDs {0}. CertPathReviewer.unknownCriticalExts.summary = Unbekannte kritische Erweiterungen: {0}. CertPathReviewer.unknownCriticalExts.details = Das Zertifikat enhält zwei oder mehr unbekannte kritische Erweiterungen mit den OIDs {0}. # error processing critical extension # {0} the message of the underlying exception # {1} the underlying exception # {2} the name of the exception CertPathReviewer.criticalExtensionError.title = Fehler bei der Verarbeitung einer kritischen Erweiterung CertPathReviewer.criticalExtensionError.text = Fehler bei der Verarbeitung einer kritischen Erweiterung. Es gab eine {2}. CertPathReviewer.criticalExtensionError.summary = Fehler bei der Verarbeitung einer kritischen Erweiterung. Es gab eine {2}. CertPathReviewer.criticalExtensionError.details = Fehler bei der Verarbeitung einer kritischen Erweiterung. Es gab eine {2}. Grund: {0}. # error initializing the certpath checkers # {0} the message of the underlying exception # {1} the underlying exception # {2} the name of the exception CertPathReviewer.certPathCheckerError.title = Prüfen der kritischen Erweiterungen fehlgeschlagen CertPathReviewer.certPathCheckerError.text = Prüfen der kritischen Erweiterungen fehlgeschlagen: Es gab eine {2} bei der Initialisierung eines CertPathChecker. CertPathReviewer.certPathCheckerError.summary = Prüfen der kritischen Erweiterungen fehlgeschlagen: {2} bei der Initialisierung eines CertPathChecker. CertPathReviewer.certPathCheckerError.details = Prüfen der kritischen Erweiterungen fehlgeschlagen: Es gab eine {2} bei der Initialisierung eines CertPathChecker. Grund: {0} ## check signature errors CertPathReviewer.rootKeyIsValidButNotATrustAnchor.title = rootKeyIsValidButNotATrustAnchor CertPathReviewer.rootKeyIsValidButNotATrustAnchor.text = Das Zertifikat hat eine gültige Signatur, ist aber kein vertrauenswürdiges Root Zertifikat. CertPathReviewer.rootKeyIsValidButNotATrustAnchor.summary = Das Zertifikat hat eine gültige Signatur, ist aber kein vertrauenswürdiges Root Zertifikat. CertPathReviewer.rootKeyIsValidButNotATrustAnchor.details = Das Zertifikat hat eine gültige Signatur, ist aber kein vertrauenswürdiges Root Zertifikat. # trustanchor found, but certificate validation failed CertPathReviewer.trustButInvalidCert.title = Vertrauenswürdiges Root Zertifikat invalid CertPathReviewer.trustButInvalidCert.text = Ein Root Zertifikat wurde gefunden. Es hat aber einen anderen öffentlichen Schlüssel als verwendet wurde um das erste Zertifikat des Zertifizierungspfades zu signieren. CertPathReviewer.trustButInvalidCert.summary = Ein Root Zertifikat wurde gefunden. Es hat aber einen anderen öffentlichen Schlüssel als verwendet wurde um das erste Zertifikat des Zertifizierungspfades zu signieren. CertPathReviewer.trustButInvalidCert.details = Ein Root Zertifikat wurde gefunden. Es hat aber einen anderen öffentlichen Schlüssel als verwendet wurde um das erste Zertifikat des Zertifizierungspfades zu signieren. # trustanchor - cannot extract issuer CertPathReviewer.trustAnchorIssuerError.title = Kann kein vertrauenswürdiges Root Zertifikat finden CertPathReviewer.trustAnchorIssuerError.text = Kann kein vertrauenswürdiges Root Zertifikat finden: Der Herausgeber vom Zertifikat kann nicht auslesen werden. CertPathReviewer.trustAnchorIssuerError.summary = Kann kein vertrauenswürdiges Root Zertifikat finden: Der Herausgeber vom Zertifikat kann nicht auslesen werden. CertPathReviewer.trustAnchorIssuerError.details = Kann kein vertrauenswürdiges Root Zertifikat finden: Der Herausgeber vom Zertifikat kann nicht auslesen werden. # no trustanchor was found for the certificate path # {0} issuer of the root certificate of the path # {1} number of trusted root certificates (trustanchors) provided CertPathReviewer.noTrustAnchorFound.title = Kein vertrauenswürdiges Root Zertifikat gefunden CertPathReviewer.noTrustAnchorFound.text = Das Root Zertifikat der Zertifizierungspfads wurde nicht von einer vertrauenswürdigen CA ausgestellt. Der Name der CA ist "{0}". CertPathReviewer.noTrustAnchorFound.summary = Das Root Zertifikat der Zertifizierungspfads wurde nicht von einer vertrauenswürdigen CA ausgestellt. CertPathReviewer.noTrustAnchorFound.details = Das Root Zertifikat der Zertifizierungspfads wurde nicht von einer vertrauenswürdigen CA ausgestellt. Der Name der CA ist "{0}". Der Root-Zertifikat-Speicher enthält {1} CA(s). # conflicting trust anchors # {0} number of trustanchors found (Integer) # {1} the ca name CertPathReviewer.conflictingTrustAnchors.title = Korrupter Root-Zertifikat-Speicher CertPathReviewer.conflictingTrustAnchors.text = Warnung: Es sind {0} öffentliche Schlüssel für die CA "{1}" im Root-Zertifikat-Speicher vorhanden - bitte prüfen Sie mit der CA welches der richtige Schlüssel ist. CertPathReviewer.conflictingTrustAnchors.summary = Warnung: Es sind {0} öffentliche Schlüssel für die CA "{1}" im Root-Zertifikat-Speicher vorhanden - bitte prüfen Sie mit der CA welches der richtige Schlüssel ist. CertPathReviewer.conflictingTrustAnchors.details = Warnung: Es sind {0} öffentliche Schlüssel für die CA "{1}" im Root-Zertifikat-Speicher vorhanden - bitte prüfen Sie mit der CA welches der richtige Schlüssel ist. # trustanchor DN is invalid # {0} DN of the Trustanchor CertPathReviewer.trustDNInvalid.title = DN des vertrauenswürdigen Root Zertifikats mit falschem Format. CertPathReviewer.trustDNInvalid.text = Der DN des vertrauenswürdigen Root Zertifikats hat ein falsches Format: {0}. CertPathReviewer.trustDNInvalid.summary = Der DN des vertrauenswürdigen Root Zertifikats hat ein falsches Format: {0}. CertPathReviewer.trustDNInvalid.details = Der DN des vertrauenswürdigen Root Zertifikats hat ein falsches Format: {0}. Es ist kein gültiger X.500 Name. Siehe RFC 1779 oder RFC 2253. # trustanchor public key algorithm error CertPathReviewer.trustPubKeyError.title = Fehler bei der Verarbeitung des öffentlichen Schlüssels der vertrauenswürdigen Root Zertifikats CertPathReviewer.trustPubKeyError.text = Fehler bei der Verarbeitung des öffentlichen Schlüssels der vertrauenswürdigen Root Zertifikats. CertPathReviewer.trustPubKeyError.summary = Fehler bei der Verarbeitung des öffentlichen Schlüssels der vertrauenswürdigen Root Zertifikats. CertPathReviewer.trustPubKeyError.details = Fehler bei der Verarbeitung des öffentlichen Schlüssels der vertrauenswürdigen Root Zertifikats. Der AlorithmIdentifier vom Schlüssel kann nicht ausgelesen werden. # can not verifiy signature: issuer public key unknown CertPathReviewer.NoIssuerPublicKey.title = Zertifikats Signatur kann nicht geprüft werden CertPathReviewer.NoIssuerPublicKey.text = Die Zertifikats Signatur kann nicht geprüft werden: Der öffentliche Schlüssel des Herausgebers ist unbekannt. CertPathReviewer.NoIssuerPublicKey.summary = Die Zertifikats Signatur kann nicht geprüft werden: Der öffentliche Schlüssel des Herausgebers ist unbekannt. CertPathReviewer.NoIssuerPublicKey.details = Die Zertifikats Signatur kann nicht geprüft werden: Der öffentliche Schlüssel des Herausgebers ist unbekannt. # signature can not be verified # {0} message of the underlying exception (english) # {1} the underlying exception # {2} the name of the exception CertPathReviewer.signatureNotVerified.title = Zertifikats Signatur ist ungültig CertPathReviewer.signatureNotVerified.text = Die Zertifikats Signatur ist ungültig. Es gab eine {2}. CertPathReviewer.signatureNotVerified.summary = Die Zertifikats Signatur ist ungültig. CertPathReviewer.signatureNotVerified.details = Die Zertifikats Signatur ist ungültig. Es gab eine {2}. Grund: {0} # certificate expired # {0} the date the certificate expired CertPathReviewer.certificateExpired.title = Zertifikat ist abgelaufen CertPathReviewer.certificateExpired.text = Das Zertifikat ist ungültig. Es ist am {0,date} {0,time,full} abgelaufen. CertPathReviewer.certificateExpired.summary = Das Zertifikat ist abgelaufen am {0,date} {0,time,full}. CertPathReviewer.certificateExpired.details = Das Zertifikat ist ungültig. Es ist am {0,date} {0,time,full} abgelaufen. # certificate not yet valid # {0} the date from which on the certificate is valid CertPathReviewer.certificateNotYetValid.title = Das Zertifikat ist noch nicht gültig CertPathReviewer.certificateNotYetValid.text = Das Zertifikat ist ungültig. Es ist erst gültig ab {0,date} {0,time,full}. CertPathReviewer.certificateNotYetValid.summary = Das Zertifikat ist nicht gültig bis {0,date} {0,time,full}. CertPathReviewer.certificateNotYetValid.details = Das Zertifikat ist ungültig. Es ist erst gültig ab {0,date} {0,time,full}. # certificate invalid issuer DN # {0} expected issuer DN as String # {1} found issuer DN as String CertPathReviewer.certWrongIssuer.title = Falscher Herausgeber CertPathReviewer.certWrongIssuer.text = Das Herausgeber des Zertifikats ist ungültig. Erwartet {0}, gefunden {1}. CertPathReviewer.certWrongIssuer.summary = Das Herausgeber des Zertifikats ist ungültig. CertPathReviewer.certWrongIssuer.details = Das Herausgeber des Zertifikats ist ungültig. Erwartet {0}, gefunden {1}. # intermediate certificate is no ca cert CertPathReviewer.noCACert.title = Zertifikat ist kein CA Zertifikat CertPathReviewer.noCACert.text = Das Zertifikat ist kein CA Zertifikat. CertPathReviewer.noCACert.summary = Das Zertifikat ist kein CA Zertifikat. CertPathReviewer.noCACert.details = Das Zertifikat ist kein CA Zertifikat, wird aber wie eines gebraucht. # cert laks basic constraints CertPathReviewer.noBasicConstraints.title = Zertifikat hat keine Basiseinschränkungen CertPathReviewer.noBasicConstraints.text = Das Zertifikat hat keine Basiseinschränkungen. CertPathReviewer.noBasicConstraints.summary = Das Zertifikat hat keine Basiseinschränkungen. CertPathReviewer.noBasicConstraints.details = Das Zertifikat hat keine Basiseinschränkungen. # error processing basic constraints CertPathReviewer.errorProcesingBC.title = Fehler bei der Verarbeitung der Basiseinschränkungen CertPathReviewer.errorProcesingBC.text = Es gab einen Fehler bei der Verarbeitung der Basiseinschränkungen des Zertifikats. CertPathReviewer.errorProcesingBC.summary = Fehler bei der Verarbeitung der Basiseinschränkungen CertPathReviewer.errorProcesingBC.details = Es gab einen Fehler bei der Verarbeitung der Basiseinschränkungen des Zertifikats. # certificate not usable for signing certs CertPathReviewer.noCertSign.title = Schlüssel nicht nutzbar für Zertifikatssignaturen CertPathReviewer.noCertSign.text = Der Schlüssel kann nicht zum Signieren von Zertifikaten verwendet werden. CertPathReviewer.noCertSign.summary = Der Schlüssel kann nicht zum Signieren von Zertifikaten verwendet werden. CertPathReviewer.noCertSign.details = Der Schlüssel kann nicht zum Signieren von Zertifikaten verwendet werden. # error processing public key CertPathReviewer.pubKeyError.title = Fehler bei der Verarbeitung des öffentlichen Schlüssels CertPathReviewer.pubKeyError.text = Fehler bei der Verarbeitung des öffentlichen Schlüssels des Zertifikats. CertPathReviewer.pubKeyError.summary = Fehler bei der Verarbeitung des öffentlichen Schlüssels des Zertifikats. CertPathReviewer.pubKeyError.details = Fehler bei der Verarbeitung des öffentlichen Schlüssels des Zertifikats. Der AlorithmIdentifier konnte nicht extrahiert werden. ## check signatures notifications # # trust anchor has no keyusage certSign CertPathReviewer.trustKeyUsage.title = Root-Zertifikat Schlüsselverwendung CertPathReviewer.trustKeyUsage.text = Das Root-Zertifikat darf nicht zum Signieren von Zertifikaten verwendet werden. CertPathReviewer.trustKeyUsage.summary = Das Root-Zertifikat darf nicht zum Signieren von Zertifikaten verwendet werden. CertPathReviewer.trustKeyUsage.details = Das Root-Zertifikat darf nicht zum Signieren von Zertifikaten verwendet werden. # certificate path validation date # {0} date for which the cert path is validated # {1} current date CertPathReviewer.certPathValidDate.title = Datum der Zertifikatspfad Validierung CertPathReviewer.certPathValidDate.text = Der Zertifikatspfad wurde am {0,date} {0,time,full} angewendet. Er wurde am {1,date} {1,time,full} geprüft. CertPathReviewer.certPathValidDate.summary = Der Zertifikatspfad wurde am {0,date} {0,time,full} angewendet. Er wurde am {1,date} {1,time,full} geprüft. CertPathReviewer.certPathValidDate.details = Der Zertifikatspfad wurde am {0,date} {0,time,full} angewendet. Er wurde am {1,date} {1,time,full} geprüft. ## check policy errors # error processing certificate policy extension CertPathReviewer.policyExtError.title = Prüfen der Policy fehlgeschlagen CertPathReviewer.policyExtError.text = Prüfen der Policy fehlgeschlagen: Es gab einen Fehler bei der Verarbeitung der Policy Erweiterung. CertPathReviewer.policyExtError.summary = Fehler bei der Verarbeitung der Policy Erweiterung. CertPathReviewer.policyExtError.details = Prüfen der Policy fehlgeschlagen: Es gab einen Fehler bei der Verarbeitung der Policy Erweiterung. # error processing policy constraints extension CertPathReviewer.policyConstExtError.title = Prüfen der Policy fehlgeschlagen CertPathReviewer.policyConstExtError.text = Prüfen der Policy fehlgeschlagen: Es gab einen Fehler bei der Verarbeitung der Policy Constraints Erweiterung. CertPathReviewer.policyConstExtError.summary = Fehler bei der Verarbeitung der Policy Constraints Erweiterung. CertPathReviewer.policyConstExtError.details = Prüfen der Policy fehlgeschlagen: Es gab einen Fehler bei der Verarbeitung der Policy Constraints Erweiterung. # error processing policy mapping extension CertPathReviewer.policyMapExtError.title = Prüfen der Policy fehlgeschlagen CertPathReviewer.policyMapExtError.text = Prüfen der Policy fehlgeschlagen: Es gab einen Fehler bei der Verarbeitung der Policy Mapping Erweiterung. CertPathReviewer.policyMapExtError.summary = Fehler bei der Verarbeitung der Policy Mapping Erweiterung. CertPathReviewer.policyMapExtError.details = Prüfen der Policy fehlgeschlagen: Es gab einen Fehler bei der Verarbeitung der Policy Mapping Erweiterung. # error processing inhibit any policy extension CertPathReviewer.policyInhibitExtError.title = Prüfen der Policy fehlgeschlagen CertPathReviewer.policyInhibitExtError.text = Prüfen der Policy fehlgeschlagen: Es gab einen Fehler bei der Verarbeitung der Inhibit Any Policy Erweiterung. CertPathReviewer.policyInhibitExtError.summary = Fehler bei der Verarbeitung der Inhibit Any Policy Erweiterung. CertPathReviewer.policyInhibitExtError.details = Prüfen der Policy fehlgeschlagen: Es gab einen Fehler bei der Verarbeitung der Inhibit Any Policy Erweiterung. # error building qualifier set CertPathReviewer.policyQualifierError.title = Prüfen der Policy fehlgeschlagen CertPathReviewer.policyQualifierError.text = Prüfen der Policy fehlgeschlagen: Fehler beim erstellen des Policy Qualifier Set. CertPathReviewer.policyQualifierError.summary = Prüfen der Policy fehlgeschlagen: Fehler beim erstellen des Policy Qualifier Set. CertPathReviewer.policyQualifierError.details = Prüfen der Policy fehlgeschlagen: Fehler beim erstellen des Policy Qualifier Set. # no valid policy tree - explicit policy required CertPathReviewer.noValidPolicyTree.title = Prüfen der Policy fehlgeschlagen CertPathReviewer.noValidPolicyTree.text = Prüfen der Policy fehlgeschlagen: Kein gültiger Policy Baum gefunden, als einer erwartet wurde. CertPathReviewer.noValidPolicyTree.summary = Prüfen der Policy fehlgeschlagen: Kein gültiger Policy Baum gefunden, als einer erwartet wurde. CertPathReviewer.noValidPolicyTree.details = Prüfen der Policy fehlgeschlagen: Kein gültiger Policy Baum gefunden, als einer erwartet wurde. # expicit policy requested, but no policy available CertPathReviewer.explicitPolicy.title = Prüfen der Policy fehlgeschlagen CertPathReviewer.explicitPolicy.text = Prüfen der Policy fehlgeschlagen: Policy verlang, aber keine Policy vorhanden. CertPathReviewer.explicitPolicy.summary = Prüfen der Policy fehlgeschlagen: Policy verlang, aber keine Policy vorhanden. CertPathReviewer.explicitPolicy.details = Prüfen der Policy fehlgeschlagen: Policy verlang, aber keine Policy vorhanden. # path processing failed on policy CertPathReviewer.invalidPolicy.title = Pfad Validierung wegen der Policy fehlgeschlagen CertPathReviewer.invalidPolicy.text = Pfad Validierung wegen der Policy fehlgeschlagen. CertPathReviewer.invalidPolicy.summary = Pfad Validierung wegen der Policy fehlgeschlagen. CertPathReviewer.invalidPolicy.details = Pfad Validierung wegen der Policy fehlgeschlagen. # invalid policy mapping CertPathReviewer.invalidPolicyMapping.title = Ungültiges Policy Mapping CertPathReviewer.invalidPolicyMapping.text = Das Zertifikat enthält ein Ungültiges Policy Mapping. CertPathReviewer.invalidPolicyMapping.summary = Das Zertifikat enthält ein Ungültiges Policy Mapping. CertPathReviewer.invalidPolicyMapping.details = Das Zertifikat enthält ein Ungültiges Policy Mapping, das den Wert Any Policy enthält. ## check CRL notifications # found local valid CRL # {0} thisUpdate of the CRL # {1} nextUpdate of the CRL CertPathReviewer.localValidCRL.title = Gültige Zertifikatssperrliste (CRL) gefunden CertPathReviewer.localValidCRL.text = Gültige Zertifikatssperrliste (CRL) im lokalen Speicher gefunden. Herausgegeben am {0,date}, nächstes Update am {1,date}. CertPathReviewer.localValidCRL.summary = Gültige Zertifikatssperrliste (CRL) im lokalen Speicher gefunden. Herausgegeben am {0,date}, nächstes Update am {1,date}. CertPathReviewer.localValidCRL.details = Gültige Zertifikatssperrliste (CRL) im lokalen Speicher gefunden. Herausgegeben am {0,date}, nächstes Update am {1,date}. # found matching CRL, but not valid # {0} thisUpdate of the CRL # {1} nextUpdate of the CRL CertPathReviewer.localInvalidCRL.title = Lokale Zertifikatssperrliste (CRL) veraltet CertPathReviewer.localInvalidCRL.text = Eine lokale Zertifikatssperrliste (CRL) wurde nicht genutzt, da sie veraltet ist. Herausgegeben am {0,date}, nächstes Update am {1,date}. CertPathReviewer.localInvalidCRL.summary = Eine lokale Zertifikatssperrliste (CRL) wurde nicht genutzt, da sie veraltet ist. Herausgegeben am {0,date}, nächstes Update am {1,date}. CertPathReviewer.localInvalidCRL.details = Eine lokale Zertifikatssperrliste (CRL) wurde nicht genutzt, da sie veraltet ist. Herausgegeben am {0,date}, nächstes Update am {1,date}. # found a valid crl at crl distribution point # {0} thisUpdate of the CRL # {1} nextUpdate of the CRL # {2} the url of the distribution point CertPathReviewer.onlineValidCRL.title = Gültige Zertifikatssperrliste (CRL) von einem CDP CertPathReviewer.onlineValidCRL.text = Gültige Zertifikatssperrliste (CRL) gefunden von: {2}. Herausgegeben am {0,date}, nächstes Update am {1,date}. CertPathReviewer.onlineValidCRL.summary = Gültige Zertifikatssperrliste (CRL) gefunden von: {2}. Herausgegeben am {0,date}, nächstes Update am {1,date}. CertPathReviewer.onlineValidCRL.details = Gültige Zertifikatssperrliste (CRL) gefunden von: {2}. Herausgegeben am {0,date}, nächstes Update am {1,date}. # found an invalid CRL at crl distribution point # {0} thisUpdate of the CRL # {1} nextUpdate of the CRL # {2} the url of the distribution point CertPathReviewer.onlineInvalidCRL.title = Veraltete Zertifikatssperrliste (CRL) von einem CDP CertPathReviewer.onlineInvalidCRL.text = Die Zertifikatssperrliste (CRL) von {2} ist veraltet. Herausgegeben am {0,date}, nächstes Update am {1,date}. CertPathReviewer.onlineInvalidCRL.summary = Die Zertifikatssperrliste (CRL) von {2} ist veraltet. Herausgegeben am {0,date}, nächstes Update am {1,date}. CertPathReviewer.onlineInvalidCRL.details = Die Zertifikatssperrliste (CRL) von {2} ist veraltet. Herausgegeben am {0,date}, nächstes Update am {1,date}. #found a CRL at a crl distribution point, but issued by another CA # {0} issuer of the CRL # {1} expected issuer # {2} the url of the distribution point CertPathReviewer.onlineCRLWrongCA.title = Zertifikatssperrliste (CRL) von CDP mit falschem Herausgeber CertPathReviewer.onlineCRLWrongCA.text = Die Zertifikatssperrliste (CRL) von {2} wurde von {0} herausgegeben, erwartet wurde {1}. CertPathReviewer.onlineCRLWrongCA.summary = Die Zertifikatssperrliste (CRL) von {2} hat einen falschen Herausgeber. CertPathReviewer.onlineCRLWrongCA.details = Die Zertifikatssperrliste (CRL) von {2} wurde von {0} herausgegeben, erwartet wurde {1}. # Certificate not revoked CertPathReviewer.notRevoked.title = Zertifikat nicht revoziert CertPathReviewer.notRevoked.text = Das Zertifikat ist nicht revoziert. CertPathReviewer.notRevoked.summary = Das Zertifikat ist nicht revoziert. CertPathReviewer.notRevoked.details = Das Zertifikat ist nicht revoziert. # CRL found: certificate was revoked, but after the validationDate # {0} the date the certificate was revoked # {1} the reason for revoking the certificate CertPathReviewer.revokedAfterValidation.title = Zertifikat revoziert nach dem Validierungdatum CertPathReviewer.revokedAfterValidation.text = Das Zertifikat wurde nach dem Validierungdatum am {0,date} {0,time,full} revoziert. Grund: {1}. CertPathReviewer.revokedAfterValidation.summary = Das Zertifikat wurde nach dem Validierungdatum am {0,date} {0,time,full} revoziert. CertPathReviewer.revokedAfterValidation.details = Das Zertifikat wurde nach dem Validierungdatum am {0,date} {0,time,full} revoziert. Grund: {1}. # updated crl available # {0} date since when the update is available CertPathReviewer.crlUpdateAvailable.title = Zertifikatssperrlisten (CRL) Update erhältlich CertPathReviewer.crlUpdateAvailable.text = Ein Update für die Zertifikatssperrliste (CRL) für dieses Zertifikat ist erhältlich seit {0,date} {0,time,full}. CertPathReviewer.crlUpdateAvailable.summary = Ein Update für die Zertifikatssperrliste (CRL) für dieses Zertifikat ist erhältlich seit {0,date} {0,time,full}. CertPathReviewer.crlUpdateAvailable.details = Ein Update für die Zertifikatssperrliste (CRL) für dieses Zertifikat ist erhältlich seit {0,date} {0,time,full}. # crl distribution point url # {0} the crl distribution point url as String CertPathReviewer.crlDistPoint.title = CDP CertPathReviewer.crlDistPoint.text = Eine Zertifikatssperrliste (CRL) kann von {0} geladen werden. CertPathReviewer.crlDistPoint.summary = Eine Zertifikatssperrliste (CRL) kann von {0} geladen werden. CertPathReviewer.crlDistPoint.details = Eine Zertifikatssperrliste (CRL) kann von {0} geladen werden. # ocsp location # {0} the url on which the ocsp service can be found CertPathReviewer.ocspLocation.title = OCSP Server CertPathReviewer.ocspLocation.text = OCSP Server: {0}. CertPathReviewer.ocspLocation.summary = OCSP Server: {0}. CertPathReviewer.ocspLocation.details = OCSP Server: {0}. # unable to get crl from crl distribution point # {0} the url of the distribution point # {1} the message of the occurred exception # {2} the occurred exception # {3} the name of the exception CertPathReviewer.loadCrlDistPointError.title = Kann Zertifikatssperrliste (CRL) nicht von CDP laden CertPathReviewer.loadCrlDistPointError.text = Kann die Zertifikatssperrliste (CRL) von {0} nicht laden. Es gab eine {2}. CertPathReviewer.loadCrlDistPointError.summary = Kann die Zertifikatssperrliste (CRL) von {0} nicht laden. Es gab eine {2}. CertPathReviewer.loadCrlDistPointError.details = Kann die Zertifikatssperrliste (CRL) von {0} nicht laden. Es gab eine {2}. Grund: {1}. # no crl found in certstores # {0} the issuers which we searched for # {1} list of crl issuer names that are found in the certstores # {2} number of crls in the certstores CertPathReviewer.noCrlInCertstore.title = Keine Zertifikatssperrliste (CRL) im lokalen Speicher CertPathReviewer.noCrlInCertstore.text = Es wurde keine Zertifikatssperrliste (CRL) im lokalen Speicher gefunden. CertPathReviewer.noCrlInCertstore.summary = Es wurde keine Zertifikatssperrliste (CRL) im lokalen Speicher gefunden. CertPathReviewer.noCrlInCertstore.details = Es wurde keine Zertifikatssperrliste (CRL) für den Herausgeber {0} im lokalen Speicher gefunden. \ Die {2} Zertifikatssperrlisten im lokalen Speicher wurden hearusgegeben von {1}. ## check CRL exceptions # cannot extract issuer from certificate CertPathReviewer.crlIssuerException.title = Prüfung der Zertifikatssperrliste (CRL) fehlgeschlagen CertPathReviewer.crlIssuerException.text = Prüfung der Zertifikatssperrliste (CRL) fehlgeschlagen: Kann den Herausgeber vom Zertifikat nicht extrahieren. CertPathReviewer.crlIssuerException.summary = Prüfung der Zertifikatssperrliste (CRL) fehlgeschlagen: Kann den Herausgeber vom Zertifikat nicht extrahieren. CertPathReviewer.crlIssuerException.details = Prüfung der Zertifikatssperrliste (CRL) fehlgeschlagen: Kann den Herausgeber vom Zertifikat nicht extrahieren. # cannot extract crls # {0} message from the underlying exception # {1} the underlying exception # {2} the name of the exception CertPathReviewer.crlExtractionError.title = Prüfung der Zertifikatssperrliste (CRL) fehlgeschlagen CertPathReviewer.crlExtractionError.text = Prüfung der Zertifikatssperrliste (CRL) fehlgeschlagen: Es gab eine {2} beim laden der Zertifikatssperrliste (CRL) aus dem lokalen Speicher. CertPathReviewer.crlExtractionError.summary = Prüfung der Zertifikatssperrliste (CRL) fehlgeschlagen: Es gab eine {2} beim laden der Zertifikatssperrliste (CRL) aus dem lokalen Speicher. CertPathReviewer.crlExtractionError.details = Prüfung der Zertifikatssperrliste (CRL) fehlgeschlagen: Es gab eine {2} beim laden der Zertifikatssperrliste (CRL) aus dem lokalen Speicher. Grund: {0}. # Issuer certificate key usage extension does not permit crl signing CertPathReviewer.noCrlSigningPermited.title = Prüfung der Zertifikatssperrliste (CRL) fehlgeschlagen CertPathReviewer.noCrlSigningPermited.text = Prüfung der Zertifikatssperrliste (CRL) fehlgeschlagen: Das Herausgeber Zertifikat erlaubt keine Signieren von Zertifikatssperrlisten (CRL). CertPathReviewer.noCrlSigningPermited.summary = Prüfung der Zertifikatssperrliste (CRL) fehlgeschlagen: Das Herausgeber Zertifikat erlaubt keine Signieren von Zertifikatssperrlisten (CRL). CertPathReviewer.noCrlSigningPermited.details = Prüfung der Zertifikatssperrliste (CRL) fehlgeschlagen: Das Herausgeber Zertifikat erlaubt keine Signieren von Zertifikatssperrlisten (CRL). # can not verify crl: issuer public key unknown CertPathReviewer.crlNoIssuerPublicKey.title = Prüfung der Zertifikatssperrliste (CRL) fehlgeschlagen CertPathReviewer.crlNoIssuerPublicKey.text = Prüfung der Zertifikatssperrliste (CRL) fehlgeschlagen: Kann die Zertifikatssperrliste (CRL) nicht verifizieren. Der öffentliche Schlüssel des Herausgebers ist unbekannt. CertPathReviewer.crlNoIssuerPublicKey.summary = Prüfung der Zertifikatssperrliste (CRL) fehlgeschlagen: Kann die Zertifikatssperrliste (CRL) nicht verifizieren. Der öffentliche Schlüssel des Herausgebers ist unbekannt. CertPathReviewer.crlNoIssuerPublicKey.details = Prüfung der Zertifikatssperrliste (CRL) fehlgeschlagen: Kann die Zertifikatssperrliste (CRL) nicht verifizieren. Der öffentliche Schlüssel des Herausgebers ist unbekannt. # crl verification failed CertPathReviewer.crlVerifyFailed.title = Prüfung der Zertifikatssperrliste (CRL) fehlgeschlagen CertPathReviewer.crlVerifyFailed.text = Prüfung der Zertifikatssperrliste (CRL) fehlgeschlagen: Die Signatur der Zertifikatssperrliste (CRL) ist ungültig. CertPathReviewer.crlVerifyFailed.summary = Prüfung der Zertifikatssperrliste (CRL) fehlgeschlagen: Die Signatur der Zertifikatssperrliste (CRL) ist ungültig. CertPathReviewer.crlVerifyFailed.details = Prüfung der Zertifikatssperrliste (CRL) fehlgeschlagen: Die Signatur der Zertifikatssperrliste (CRL) ist ungültig. # no valid CRL found CertPathReviewer.noValidCrlFound.title = Prüfung der Zertifikatssperrliste (CRL) fehlgeschlagen CertPathReviewer.noValidCrlFound.text = Prüfung der Zertifikatssperrliste (CRL) fehlgeschlagen: keine gültige Zertifikatssperrliste (CRL) gefunden. CertPathReviewer.noValidCrlFound.summary = Prüfung der Zertifikatssperrliste (CRL) fehlgeschlagen: keine gültige Zertifikatssperrliste (CRL) gefunden. CertPathReviewer.noValidCrlFound.details = Prüfung der Zertifikatssperrliste (CRL) fehlgeschlagen: keine gültige Zertifikatssperrliste (CRL) gefunden. # No base CRL for delta CRL CertPathReviewer.noBaseCRL.title = Prüfung der Zertifikatssperrliste (CRL) fehlgeschlagen CertPathReviewer.noBaseCRL.text = Prüfung der Zertifikatssperrliste (CRL) fehlgeschlagen: keine Basis CRL für die Delta CRL gefunden. CertPathReviewer.noBaseCRL.summary = Prüfung der Zertifikatssperrliste (CRL) fehlgeschlagen: keine Basis CRL für die Delta CRL gefunden. CertPathReviewer.noBaseCRL.details = Prüfung der Zertifikatssperrliste (CRL) fehlgeschlagen: keine Basis CRL für die Delta CRL gefunden. # certificate revoked # {0} the date the certificate was revoked # {1} the reason for revoking the certificate CertPathReviewer.certRevoked.title = Zertifikat wurde revoziert CertPathReviewer.certRevoked.text = Das Zertifikat wurde am {0,date} {0,time,full} revoziert. Grund: {1}. CertPathReviewer.certRevoked.summary = Das Zertifikat wurde am {0,date} {0,time,full} revoziert. CertPathReviewer.certRevoked.details = Das Zertifikat wurde am {0,date} {0,time,full} revoziert. Grund: {1}. # error processing issuing distribution point extension CertPathReviewer.distrPtExtError.title = Prüfung der Zertifikatssperrliste (CRL) fehlgeschlagen CertPathReviewer.distrPtExtError.text = Prüfung der Zertifikatssperrliste (CRL) fehlgeschlagen: Es gab einen Fehler bei der Verarbeitung der Issuing Distribution Point Erweiterung. CertPathReviewer.distrPtExtError.summary = Fehler bei der Verarbeitung der Issuing Distribution Point Erweiterung. CertPathReviewer.distrPtExtError.details = Prüfung der Zertifikatssperrliste (CRL) fehlgeschlagen: Es gab einen Fehler bei der Verarbeitung der Issuing Distribution Point Erweiterung. # error processing crl distribution points extension CertPathReviewer.crlDistPtExtError.title = Prüfung der Zertifikatssperrliste (CRL) fehlgeschlagen CertPathReviewer.crlDistPtExtError.text = Prüfung der Zertifikatssperrliste (CRL) fehlgeschlagen: Es gab einen Fehler bei der Verarbeitung der CRL Distribution Points Erweiterung. CertPathReviewer.crlDistPtExtError.summary = Fehler bei der Verarbeitung der CRL Distribution Points Erweiterung. CertPathReviewer.crlDistPtExtError.details = Prüfung der Zertifikatssperrliste (CRL) fehlgeschlagen: Es gab einen Fehler bei der Verarbeitung der CRL Distribution Points Erweiterung. # error processing the authority info access extension CertPathReviewer.crlAuthInfoAccError.title = Prüfung der Zertifikatssperrliste (CRL) fehlgeschlagen CertPathReviewer.crlAuthInfoAccError.text = Prüfung der Zertifikatssperrliste (CRL) fehlgeschlagen: Es gab einen Fehler bei der Verarbeitung der Authority Info Access Erweiterung. CertPathReviewer.crlAuthInfoAccError.summary = Fehler bei der Verarbeitung der Authority Info Access Erweiterung. CertPathReviewer.crlAuthInfoAccError.details = Prüfung der Zertifikatssperrliste (CRL) fehlgeschlagen: Es gab einen Fehler bei der Verarbeitung der Authority Info Access Erweiterung. # error processing delta crl indicator extension CertPathReviewer.deltaCrlExtError.title = Prüfung der Zertifikatssperrliste (CRL) fehlgeschlagen CertPathReviewer.deltaCrlExtError.text = Prüfung der Zertifikatssperrliste (CRL) fehlgeschlagen: Es gab einen Fehler bei der Verarbeitung der Delta CRL Indicator Erweiterung. CertPathReviewer.deltaCrlExtError.summary = Fehler bei der Verarbeitung der Delta CRL Indicator Erweiterung. CertPathReviewer.deltaCrlExtError.details = Prüfung der Zertifikatssperrliste (CRL) fehlgeschlagen: Es gab einen Fehler bei der Verarbeitung der Delta CRL Indicator Erweiterung. # error porcessing crl number extension CertPathReviewer.crlNbrExtError.title = Prüfung der Zertifikatssperrliste (CRL) fehlgeschlagen CertPathReviewer.crlNbrExtError.text = Prüfung der Zertifikatssperrliste (CRL) fehlgeschlagen: Es gab einen Fehler bei der Verarbeitung der CRL Number Erweiterung. CertPathReviewer.crlNbrExtError.summary = Fehler bei der Verarbeitung der CRL Number Erweiterung. CertPathReviewer.crlNbrExtError.details = Prüfung der Zertifikatssperrliste (CRL) fehlgeschlagen: Es gab einen Fehler bei der Verarbeitung der CRL Number Erweiterung. # error processing crl reason code extension CertPathReviewer.crlReasonExtError.title = Prüfung der Zertifikatssperrliste (CRL) fehlgeschlagen CertPathReviewer.crlReasonExtError.text = Prüfung der Zertifikatssperrliste (CRL) fehlgeschlagen: Es gab einen Fehler bei der Verarbeitung der CRL Reason Code Erweiterung. CertPathReviewer.crlReasonExtError.summary = Fehler bei der Verarbeitung der CRL Reason Code Erweiterung. CertPathReviewer.crlReasonExtError.details = Prüfung der Zertifikatssperrliste (CRL) fehlgeschlagen: Es gab einen Fehler bei der Verarbeitung der CRL Reason Code Erweiterung. # error processing basic constraints extension CertPathReviewer.crlBCExtError.title = Prüfung der Zertifikatssperrliste (CRL) fehlgeschlagen CertPathReviewer.crlBCExtError.text = Prüfung der Zertifikatssperrliste (CRL) fehlgeschlagen: Es gab einen Fehler bei der Verarbeitung der CRL Reason Code Erweiterung. CertPathReviewer.crlBCExtError.summary = Fehler bei der Verarbeitung der CRL Reason Code Erweiterung. CertPathReviewer.crlBCExtError.details = Prüfung der Zertifikatssperrliste (CRL) fehlgeschlagen: Es gab einen Fehler bei der Verarbeitung der CRL Reason Code Erweiterung. # CA Cert CRL only contains user certificates CertPathReviewer.crlOnlyUserCert.title = Prüfung der Zertifikatssperrliste (CRL) fehlgeschlagen CertPathReviewer.crlOnlyUserCert.text = Prüfung der Zertifikatssperrliste (CRL) fehlgeschlagen: Die Zertifikatssperrliste (CRL) enthält nur User Zertifikate. CertPathReviewer.crlOnlyUserCert.summary = Prüfung der Zertifikatssperrliste (CRL) fehlgeschlagen: Die Zertifikatssperrliste (CRL) enthält nur User Zertifikate. CertPathReviewer.crlOnlyUserCert.details = Prüfung der Zertifikatssperrliste (CRL) fehlgeschlagen: Die Zertifikatssperrliste (CRL) enthält nur User Zertifikate. # End CRL only contains CA certificates CertPathReviewer.crlOnlyCaCert.title = Prüfung der Zertifikatssperrliste (CRL) fehlgeschlagen CertPathReviewer.crlOnlyCaCert.text = Prüfung der Zertifikatssperrliste (CRL) fehlgeschlagen: Die Zertifikatssperrliste (CRL) enthält nur CA Zertifikate. CertPathReviewer.crlOnlyCaCert.summary = Prüfung der Zertifikatssperrliste (CRL) fehlgeschlagen: Die Zertifikatssperrliste (CRL) enthält nur CA Zertifikate. CertPathReviewer.crlOnlyCaCert.details = Prüfung der Zertifikatssperrliste (CRL) fehlgeschlagen: Die Zertifikatssperrliste (CRL) enthält nur CA Zertifikate. # onlyContainsAttributeCerts boolean is asserted CertPathReviewer.crlOnlyAttrCert.title = Prüfung der Zertifikatssperrliste (CRL) fehlgeschlagen CertPathReviewer.crlOnlyAttrCert.text = Prüfung der Zertifikatssperrliste (CRL) fehlgeschlagen: Die Zertifikatssperrliste (CRL) enthält nur Attribut Zertifikate. CertPathReviewer.crlOnlyAttrCert.summary = Prüfung der Zertifikatssperrliste (CRL) fehlgeschlagen: Die Zertifikatssperrliste (CRL) enthält nur Attribut Zertifikate. CertPathReviewer.crlOnlyAttrCert.details = Prüfung der Zertifikatssperrliste (CRL) fehlgeschlagen: Die Zertifikatssperrliste (CRL) enthält nur Attribut Zertifikate. ## QcStatement notifications # unkown statement # {0} statement OID # {1} statement as ANS1Sequence CertPathReviewer.QcUnknownStatement.title = Unbekanntes Statement in der QcStatement Erweiterung CertPathReviewer.QcUnknownStatement.text = Unbekanntes Statement in der QcStatement Erweiterung: OID = {0} CertPathReviewer.QcUnknownStatement.summary = Unbekanntes Statement in der QcStatement Erweiterung: OID = {0} CertPathReviewer.QcUnknownStatement.details = Unbekanntes Statement in der QcStatement Erweiterung: OID = {0}, statement = {1} # QcLimitValue Alpha currency code # {0} currency code # {1} limit value # {2} monetary value as MonetaryValue CertPathReviewer.QcLimitValueAlpha.title = Transaction Value Limit CertPathReviewer.QcLimitValueAlpha.text = Dieses Zertifikat hat ein Wertlimite von {1,number, ###,###,###,##0.00#} {0} für Transaktionen. CertPathReviewer.QcLimitValueAlpha.summary = Wertlimite von {1,number, ###,###,###,##0.00#} {0} für Transaktionen. CertPathReviewer.QcLimitValueAlpha.details = Dieses Zertifikat hat eine Wertlimite für Transaktionen für welche\ das Zertifikat genutzt werden kann, gemäss der Richtlinie 1999/93/EG des Europäischen Parlaments und\ des Rates über gemeinschaftliche Rahmenbedingungen für elektronische Signaturen und gemäss der Umsetzung der\ Richtlinie im Land, das im Herausgeber dieses Zertifikats angegeben ist. Die Limite für diese Zertifikat ist {1,number, ###,###,###,##0.00#} {0}. # QcLimitValue Numeric currency code # {0} currency code # {1} limit value # {2} monetary value as MonetaryValue CertPathReviewer.QcLimitValueNum.title = Transaction Value Limit CertPathReviewer.QcLimitValueNum.text = Dieses Zertifikat hat eine Wertlimite für Transaktionen von {1,number, ###,###,###,##0.00#} der Währung {0} (Siehe RFC 4217 für Währungscodes). CertPathReviewer.QcLimitValueNum.summary = Wertlimite für Transaktionen von {1,number, ###,###,###,##0.00#} der Währung {0} (Siehe RFC 4217 für Währungscodes). CertPathReviewer.QcLimitValueNum.details = Dieses Zertifikat hat eine Wertlimite für Transaktionen für welche\ das Zertifikat genutzt werden kann, gemäss der Richtlinie 1999/93/EG des Europäischen Parlaments und\ des Rates über gemeinschaftliche Rahmenbedingungen für elektronische Signaturen und gemäss der Umsetzung der\ Richtlinie im Land, das im Herausgeber dieses Zertifikats angegeben ist. Die Limite für diese Zertifikat ist {1,number, ###,###,###,##0.00#} der Währung {0} (Siehe RFC 4217 für Währungscodes). # QcSSCD CertPathReviewer.QcSSCD.title = QcSSCD Statement CertPathReviewer.QcSSCD.text = (SSCD) Der Herausgeber macht geltend, dass der Private Schlüssel, der mit diesem Zertifikat verbunden ist, nach den Anforderungen die im Anhang III der Richtlinie 1999/93/EG des Europäischen Parlaments und des Rates über gemeinschaftliche Rahmenbedingungen für elektronische Signaturen geschützt ist. CertPathReviewer.QcSSCD.summary = (SSCD) Der Herausgeber macht geltend, dass der Private Schlüssel, der mit diesem Zertifikat verbunden ist, nach den Anforderungen die im Anhang III der Richtlinie 1999/93/EG des Europäischen Parlaments und des Rates über gemeinschaftliche Rahmenbedingungen für elektronische Signaturen geschützt ist. CertPathReviewer.QcSSCD.details = (SSCD) Der Herausgeber macht geltend, dass der Private Schlüssel, der mit diesem Zertifikat verbunden ist, nach den Anforderungen die im Anhang III der Richtlinie 1999/93/EG des Europäischen Parlaments und des Rates über gemeinschaftliche Rahmenbedingungen für elektronische Signaturen geschützt ist. # QcEuCompliance CertPathReviewer.QcEuCompliance.title = Qualifiziertes Zertifikat CertPathReviewer.QcEuCompliance.text = Dieses Zertifikat wurde als Qualifiziertes Zertifikat herausgegeben gemäss Anhang I und II der Richtlinie 1999/93/EG des Europäischen Parlaments und des Rates über gemeinschaftliche Rahmenbedingungen für elektronische Signaturen und gemäss der Umsetzung der Richtlinie im Land, das im Herausgeber dieses Zertifikats angegeben ist. CertPathReviewer.QcEuCompliance.summary = Dieses Zertifikat wurde als Qualifiziertes Zertifikat herausgegeben gemäss Anhang I und II der Richtlinie 1999/93/EG des Europäischen Parlaments und des Rates über gemeinschaftliche Rahmenbedingungen für elektronische Signaturen und gemäss der Umsetzung der Richtlinie in dem Land, das im Herausgeber dieses Zertifikats angegeben ist. CertPathReviewer.QcEuCompliance.details = Dieses Zertifikat wurde als Qualifiziertes Zertifikat herausgegeben gemäss Anhang I und II der Richtlinie 1999/93/EG des Europäischen Parlaments und des Rates über gemeinschaftliche Rahmenbedingungen für elektronische Signaturen und gemäss der Umsetzung der Richtlinie in dem Land, das im Herausgeber dieses Zertifikats angegeben ist. ## QcStatement errors # error processing the QcStatement extension CertPathReviewer.QcStatementExtError.title = Fehler bei der Verarbeitung der QcStatement Erweiterung CertPathReviewer.QcStatementExtError.text = Fehler bei der Verarbeitung der QcStatement Erweiterung. CertPathReviewer.QcStatementExtError.summary = Fehler bei der Verarbeitung der QcStatement Erweiterung. CertPathReviewer.QcStatementExtError.details = Fehler bei der Verarbeitung der QcStatement Erweiterung. ## unknown/generic errors CertPathReviewer.unknown.title = Unbekannter Fehler CertPathReviewer.unknown.text = Unbekannter Fehler {0} CertPathReviewer.unknown.summary = Unbekannter Fehler CertPathReviewer.unknown.details = Unbekannter Fehler {0} # # crl reasons # unspecified = Nicht spezifiziert keyCompromise = Schlüssel Kompromittierung cACompromise = CA Kompromittierung affiliationChanged = Veränderte Zugehörigkeit superseded = Ersetzt cessationOfOperation = Einstellen der Tätigkeiten certificateHold = Zertifikat vorübergehend gesperrt unknown = Unbekannt removeFromCRL = Entferne von der CRL privilegeWithdrawn = Zurückgezogene Rechte aACompromise = AA Kompromittierung # # # missingIssuer = The missing certificate was issued by missingSerial = with the serial number bouncycastle-1.49.orig/src/org/bouncycastle/x509/package.html0000644000175000017500000000033312151571016023466 0ustar ebourgebourg

    Deprecated: see bcpkix distribution (org.bouncycastle.cert), classes for supporting the generation of X.509 certificates and X.509 attribute certificates.

    bouncycastle-1.49.orig/src/org/bouncycastle/x509/extension/0000755000175000017500000000000012152033551023220 5ustar ebourgebourgbouncycastle-1.49.orig/src/org/bouncycastle/x509/extension/AuthorityKeyIdentifierStructure.java0000644000175000017500000001266611725023121032460 0ustar ebourgebourgpackage org.bouncycastle.x509.extension; import java.io.IOException; import java.security.InvalidKeyException; import java.security.PublicKey; import java.security.cert.CertificateParsingException; import java.security.cert.X509Certificate; import org.bouncycastle.asn1.ASN1InputStream; import org.bouncycastle.asn1.ASN1OctetString; import org.bouncycastle.asn1.ASN1Sequence; import org.bouncycastle.asn1.x509.AuthorityKeyIdentifier; import org.bouncycastle.asn1.x509.Extension; import org.bouncycastle.asn1.x509.GeneralName; import org.bouncycastle.asn1.x509.GeneralNames; import org.bouncycastle.asn1.x509.SubjectPublicKeyInfo; import org.bouncycastle.asn1.x509.X509Extension; import org.bouncycastle.asn1.x509.X509Extensions; import org.bouncycastle.jce.PrincipalUtil; /** * A high level authority key identifier. * @deprecated use JcaX509ExtensionUtils and AuthorityKeyIdentifier.getInstance() */ public class AuthorityKeyIdentifierStructure extends AuthorityKeyIdentifier { /** * Constructor which will take the byte[] returned from getExtensionValue() * * @param encodedValue a DER octet encoded string with the extension structure in it. * @throws IOException on parsing errors. */ public AuthorityKeyIdentifierStructure( byte[] encodedValue) throws IOException { super((ASN1Sequence)X509ExtensionUtil.fromExtensionValue(encodedValue)); } /** * Constructor which will take an extension * * @param extension a X509Extension object containing an AuthorityKeyIdentifier. * @deprecated use constructor that takes Extension */ public AuthorityKeyIdentifierStructure( X509Extension extension) { super((ASN1Sequence)extension.getParsedValue()); } /** * Constructor which will take an extension * * @param extension a X509Extension object containing an AuthorityKeyIdentifier. */ public AuthorityKeyIdentifierStructure( Extension extension) { super((ASN1Sequence)extension.getParsedValue()); } private static ASN1Sequence fromCertificate( X509Certificate certificate) throws CertificateParsingException { try { if (certificate.getVersion() != 3) { GeneralName genName = new GeneralName(PrincipalUtil.getIssuerX509Principal(certificate)); SubjectPublicKeyInfo info = new SubjectPublicKeyInfo( (ASN1Sequence)new ASN1InputStream(certificate.getPublicKey().getEncoded()).readObject()); return (ASN1Sequence)new AuthorityKeyIdentifier( info, new GeneralNames(genName), certificate.getSerialNumber()).toASN1Object(); } else { GeneralName genName = new GeneralName(PrincipalUtil.getIssuerX509Principal(certificate)); byte[] ext = certificate.getExtensionValue(X509Extensions.SubjectKeyIdentifier.getId()); if (ext != null) { ASN1OctetString str = (ASN1OctetString)X509ExtensionUtil.fromExtensionValue(ext); return (ASN1Sequence)new AuthorityKeyIdentifier( str.getOctets(), new GeneralNames(genName), certificate.getSerialNumber()).toASN1Object(); } else { SubjectPublicKeyInfo info = new SubjectPublicKeyInfo( (ASN1Sequence)new ASN1InputStream(certificate.getPublicKey().getEncoded()).readObject()); return (ASN1Sequence)new AuthorityKeyIdentifier( info, new GeneralNames(genName), certificate.getSerialNumber()).toASN1Object(); } } } catch (Exception e) { throw new CertificateParsingException("Exception extracting certificate details: " + e.toString()); } } private static ASN1Sequence fromKey( PublicKey pubKey) throws InvalidKeyException { try { SubjectPublicKeyInfo info = new SubjectPublicKeyInfo( (ASN1Sequence)new ASN1InputStream(pubKey.getEncoded()).readObject()); return (ASN1Sequence)new AuthorityKeyIdentifier(info).toASN1Object(); } catch (Exception e) { throw new InvalidKeyException("can't process key: " + e); } } /** * Create an AuthorityKeyIdentifier using the passed in certificate's public * key, issuer and serial number. * * @param certificate the certificate providing the information. * @throws CertificateParsingException if there is a problem processing the certificate */ public AuthorityKeyIdentifierStructure( X509Certificate certificate) throws CertificateParsingException { super(fromCertificate(certificate)); } /** * Create an AuthorityKeyIdentifier using just the hash of the * public key. * * @param pubKey the key to generate the hash from. * @throws InvalidKeyException if there is a problem using the key. */ public AuthorityKeyIdentifierStructure( PublicKey pubKey) throws InvalidKeyException { super(fromKey(pubKey)); } } bouncycastle-1.49.orig/src/org/bouncycastle/x509/extension/SubjectKeyIdentifierStructure.java0000644000175000017500000000306511725023121032060 0ustar ebourgebourgpackage org.bouncycastle.x509.extension; import java.io.IOException; import java.security.InvalidKeyException; import java.security.PublicKey; import org.bouncycastle.asn1.ASN1OctetString; import org.bouncycastle.asn1.x509.SubjectKeyIdentifier; import org.bouncycastle.asn1.x509.SubjectPublicKeyInfo; /** * A high level subject key identifier. * @deprecated use JcaX509ExtensionUtils andSubjectKeyIdentifier.getInstance() */ public class SubjectKeyIdentifierStructure extends SubjectKeyIdentifier { /** * Constructor which will take the byte[] returned from getExtensionValue() * * @param encodedValue a DER octet encoded string with the extension structure in it. * @throws IOException on parsing errors. */ public SubjectKeyIdentifierStructure( byte[] encodedValue) throws IOException { super((ASN1OctetString)X509ExtensionUtil.fromExtensionValue(encodedValue)); } private static ASN1OctetString fromPublicKey( PublicKey pubKey) throws InvalidKeyException { try { SubjectPublicKeyInfo info = SubjectPublicKeyInfo.getInstance(pubKey.getEncoded()); return (ASN1OctetString)(new SubjectKeyIdentifier(info).toASN1Object()); } catch (Exception e) { throw new InvalidKeyException("Exception extracting key details: " + e.toString()); } } public SubjectKeyIdentifierStructure( PublicKey pubKey) throws InvalidKeyException { super(fromPublicKey(pubKey)); } } bouncycastle-1.49.orig/src/org/bouncycastle/x509/extension/X509ExtensionUtil.java0000644000175000017500000000707312103440746027276 0ustar ebourgebourgpackage org.bouncycastle.x509.extension; import java.io.IOException; import java.security.cert.CertificateParsingException; import java.security.cert.X509Certificate; import java.util.ArrayList; import java.util.Collection; import java.util.Collections; import java.util.Enumeration; import java.util.List; import org.bouncycastle.asn1.ASN1ObjectIdentifier; import org.bouncycastle.asn1.ASN1OctetString; import org.bouncycastle.asn1.ASN1Primitive; import org.bouncycastle.asn1.ASN1String; import org.bouncycastle.asn1.DEROctetString; import org.bouncycastle.asn1.DERSequence; import org.bouncycastle.asn1.x500.X500Name; import org.bouncycastle.asn1.x509.GeneralName; import org.bouncycastle.asn1.x509.X509Extension; import org.bouncycastle.util.Integers; public class X509ExtensionUtil { public static ASN1Primitive fromExtensionValue( byte[] encodedValue) throws IOException { ASN1OctetString octs = (ASN1OctetString)ASN1Primitive.fromByteArray(encodedValue); return ASN1Primitive.fromByteArray(octs.getOctets()); } public static Collection getIssuerAlternativeNames(X509Certificate cert) throws CertificateParsingException { byte[] extVal = cert.getExtensionValue(X509Extension.issuerAlternativeName.getId()); return getAlternativeNames(extVal); } public static Collection getSubjectAlternativeNames(X509Certificate cert) throws CertificateParsingException { byte[] extVal = cert.getExtensionValue(X509Extension.subjectAlternativeName.getId()); return getAlternativeNames(extVal); } private static Collection getAlternativeNames(byte[] extVal) throws CertificateParsingException { if (extVal == null) { return Collections.EMPTY_LIST; } try { Collection temp = new ArrayList(); Enumeration it = DERSequence.getInstance(fromExtensionValue(extVal)).getObjects(); while (it.hasMoreElements()) { GeneralName genName = GeneralName.getInstance(it.nextElement()); List list = new ArrayList(); list.add(Integers.valueOf(genName.getTagNo())); switch (genName.getTagNo()) { case GeneralName.ediPartyName: case GeneralName.x400Address: case GeneralName.otherName: list.add(genName.getName().toASN1Primitive()); break; case GeneralName.directoryName: list.add(X500Name.getInstance(genName.getName()).toString()); break; case GeneralName.dNSName: case GeneralName.rfc822Name: case GeneralName.uniformResourceIdentifier: list.add(((ASN1String)genName.getName()).getString()); break; case GeneralName.registeredID: list.add(ASN1ObjectIdentifier.getInstance(genName.getName()).getId()); break; case GeneralName.iPAddress: list.add(DEROctetString.getInstance(genName.getName()).getOctets()); break; default: throw new IOException("Bad tag number: " + genName.getTagNo()); } temp.add(list); } return Collections.unmodifiableCollection(temp); } catch (Exception e) { throw new CertificateParsingException(e.getMessage()); } } } bouncycastle-1.49.orig/src/org/bouncycastle/x509/extension/package.html0000644000175000017500000000025612151570777025523 0ustar ebourgebourg Deprecated: see bcpkix distribution (org.bouncycastle.cert), helper classes for dealing with common X.509 extensions. bouncycastle-1.49.orig/src/org/bouncycastle/x509/X509CollectionStoreParameters.java0000644000175000017500000000340110527200222027562 0ustar ebourgebourgpackage org.bouncycastle.x509; import java.util.ArrayList; import java.util.Collection; /** * This class contains a collection for collection based X509Stores. * * @see org.bouncycastle.x509.X509Store * */ public class X509CollectionStoreParameters implements X509StoreParameters { private Collection collection; /** * Constructor. *

    * The collection is copied. *

    * * @param collection * The collection containing X.509 object types. * @throws NullPointerException if collection is null. */ public X509CollectionStoreParameters(Collection collection) { if (collection == null) { throw new NullPointerException("collection cannot be null"); } this.collection = collection; } /** * Returns a shallow clone. The returned contents are not copied, so adding * or removing objects will effect this. * * @return a shallow clone. */ public Object clone() { return new X509CollectionStoreParameters(collection); } /** * Returns a copy of the Collection. * * @return The Collection. Is never null. */ public Collection getCollection() { return new ArrayList(collection); } /** * Returns a formatted string describing the parameters. * * @return a formatted string describing the parameters */ public String toString() { StringBuffer sb = new StringBuffer(); sb.append("X509CollectionStoreParameters: [\n"); sb.append(" collection: " + collection + "\n"); sb.append("]"); return sb.toString(); } } bouncycastle-1.49.orig/src/org/bouncycastle/x509/X509StreamParser.java0000644000175000017500000001141010772037032025046 0ustar ebourgebourgpackage org.bouncycastle.x509; import org.bouncycastle.x509.util.StreamParser; import org.bouncycastle.x509.util.StreamParsingException; import java.io.ByteArrayInputStream; import java.io.InputStream; import java.security.NoSuchAlgorithmException; import java.security.NoSuchProviderException; import java.security.Provider; import java.util.Collection; /** * * This class allows access to different implementations for reading X.509 * objects from streams. *

    * A X509StreamParser is used to read a collection of objects or a single object * of a certain X.509 object structure. E.g. one X509StreamParser can read * certificates, another one CRLs, certification paths, attribute certificates * and so on. The kind of object structure is specified with the * algorithm parameter to the getInstance methods. *

    * Implementations must implement the * {@link org.bouncycastle.x509.X509StreamParserSpi}. */ public class X509StreamParser implements StreamParser { /** * Generates a StreamParser object that implements the specified type. If * the default provider package provides an implementation of the requested * type, an instance of StreamParser containing that implementation is * returned. If the type is not available in the default package, other * packages are searched. * * @param type * The name of the requested X.509 object type. * @return a StreamParser object for the specified type. * * @exception NoSuchParserException * if the requested type is not available in the default * provider package or any of the other provider packages * that were searched. */ public static X509StreamParser getInstance(String type) throws NoSuchParserException { try { X509Util.Implementation impl = X509Util.getImplementation("X509StreamParser", type); return createParser(impl); } catch (NoSuchAlgorithmException e) { throw new NoSuchParserException(e.getMessage()); } } /** * Generates a X509StreamParser object for the specified type from the * specified provider. * * @param type * the name of the requested X.509 object type. * @param provider * the name of the provider. * * @return a X509StreamParser object for the specified type. * * @exception NoSuchParserException * if the type is not available from the specified provider. * * @exception NoSuchProviderException * if the provider can not be found. * * @see Provider */ public static X509StreamParser getInstance(String type, String provider) throws NoSuchParserException, NoSuchProviderException { return getInstance(type, X509Util.getProvider(provider)); } /** * Generates a X509StreamParser object for the specified type from the * specified provider. * * @param type * the name of the requested X.509 object type. * @param provider * the Provider to use. * * @return a X509StreamParser object for the specified type. * * @exception NoSuchParserException * if the type is not available from the specified provider. * * @see Provider */ public static X509StreamParser getInstance(String type, Provider provider) throws NoSuchParserException { try { X509Util.Implementation impl = X509Util.getImplementation("X509StreamParser", type, provider); return createParser(impl); } catch (NoSuchAlgorithmException e) { throw new NoSuchParserException(e.getMessage()); } } private static X509StreamParser createParser(X509Util.Implementation impl) { X509StreamParserSpi spi = (X509StreamParserSpi)impl.getEngine(); return new X509StreamParser(impl.getProvider(), spi); } private Provider _provider; private X509StreamParserSpi _spi; private X509StreamParser( Provider provider, X509StreamParserSpi spi) { _provider = provider; _spi = spi; } public Provider getProvider() { return _provider; } public void init(InputStream stream) { _spi.engineInit(stream); } public void init(byte[] data) { _spi.engineInit(new ByteArrayInputStream(data)); } public Object read() throws StreamParsingException { return _spi.engineRead(); } public Collection readAll() throws StreamParsingException { return _spi.engineReadAll(); } } bouncycastle-1.49.orig/src/org/bouncycastle/LICENSE.java0000644000175000017500000000647300000001145022415 0ustar ebourgebourgpackage org.bouncycastle; /** * The Bouncy Castle License * * Copyright (c) 2000-2012 The Legion Of The Bouncy Castle (http://www.bouncycastle.org) *

    * Permission is hereby granted, free of charge, to any person obtaining a copy of this software * and associated documentation files (the "Software"), to deal in the Software without restriction, * including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, * and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, * subject to the following conditions: *

    * The above copyright notice and this permission notice shall be included in all copies or substantial * portions of the Software. *

    * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, * INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR * PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE * LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR * OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER * DEALINGS IN THE SOFTWARE. */ public class LICENSE { public static String licenseText = "Copyright (c) 2000-2012 The Legion Of The Bouncy Castle (http://www.bouncycastle.org) " + System.getProperty("line.separator") + System.getProperty("line.separator") + "Permission is hereby granted, free of charge, to any person obtaining a copy of this software " + System.getProperty("line.separator") + "and associated documentation files (the \"Software\"), to deal in the Software without restriction, " + System.getProperty("line.separator") + "including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, " + System.getProperty("line.separator") + "and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so," + System.getProperty("line.separator") + "subject to the following conditions:" + System.getProperty("line.separator") + System.getProperty("line.separator") + "The above copyright notice and this permission notice shall be included in all copies or substantial" + System.getProperty("line.separator") + "portions of the Software." + System.getProperty("line.separator") + System.getProperty("line.separator") + "THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED," + System.getProperty("line.separator") + "INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR" + System.getProperty("line.separator") + "PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE" + System.getProperty("line.separator") + "LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR" + System.getProperty("line.separator") + "OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER" + System.getProperty("line.separator") + "DEALINGS IN THE SOFTWARE."; public static void main( String[] args) { System.out.println(licenseText); } } bouncycastle-1.49.orig/src/org/bouncycastle/math/0000755000175000017500000000000012152033551021430 5ustar ebourgebourgbouncycastle-1.49.orig/src/org/bouncycastle/math/ec/0000755000175000017500000000000012152033551022017 5ustar ebourgebourgbouncycastle-1.49.orig/src/org/bouncycastle/math/ec/WNafPreCompInfo.java0000644000175000017500000000210310662310167025620 0ustar ebourgebourgpackage org.bouncycastle.math.ec; /** * Class holding precomputation data for the WNAF (Window Non-Adjacent Form) * algorithm. */ class WNafPreCompInfo implements PreCompInfo { /** * Array holding the precomputed ECPoints used for the Window * NAF multiplication in * {@link org.bouncycastle.math.ec.multiplier.WNafMultiplier.multiply() * WNafMultiplier.multiply()}. */ private ECPoint[] preComp = null; /** * Holds an ECPoint representing twice(this). Used for the * Window NAF multiplication in * {@link org.bouncycastle.math.ec.multiplier.WNafMultiplier.multiply() * WNafMultiplier.multiply()}. */ private ECPoint twiceP = null; protected ECPoint[] getPreComp() { return preComp; } protected void setPreComp(ECPoint[] preComp) { this.preComp = preComp; } protected ECPoint getTwiceP() { return twiceP; } protected void setTwiceP(ECPoint twiceThis) { this.twiceP = twiceThis; } } bouncycastle-1.49.orig/src/org/bouncycastle/math/ec/IntArray.java0000644000175000017500000003104411013207437024416 0ustar ebourgebourgpackage org.bouncycastle.math.ec; import org.bouncycastle.util.Arrays; import java.math.BigInteger; class IntArray { // TODO make m fixed for the IntArray, and hence compute T once and for all private int[] m_ints; public IntArray(int intLen) { m_ints = new int[intLen]; } public IntArray(int[] ints) { m_ints = ints; } public IntArray(BigInteger bigInt) { this(bigInt, 0); } public IntArray(BigInteger bigInt, int minIntLen) { if (bigInt.signum() == -1) { throw new IllegalArgumentException("Only positive Integers allowed"); } if (bigInt.equals(ECConstants.ZERO)) { m_ints = new int[] { 0 }; return; } byte[] barr = bigInt.toByteArray(); int barrLen = barr.length; int barrStart = 0; if (barr[0] == 0) { // First byte is 0 to enforce highest (=sign) bit is zero. // In this case ignore barr[0]. barrLen--; barrStart = 1; } int intLen = (barrLen + 3) / 4; if (intLen < minIntLen) { m_ints = new int[minIntLen]; } else { m_ints = new int[intLen]; } int iarrJ = intLen - 1; int rem = barrLen % 4 + barrStart; int temp = 0; int barrI = barrStart; if (barrStart < rem) { for (; barrI < rem; barrI++) { temp <<= 8; int barrBarrI = barr[barrI]; if (barrBarrI < 0) { barrBarrI += 256; } temp |= barrBarrI; } m_ints[iarrJ--] = temp; } for (; iarrJ >= 0; iarrJ--) { temp = 0; for (int i = 0; i < 4; i++) { temp <<= 8; int barrBarrI = barr[barrI++]; if (barrBarrI < 0) { barrBarrI += 256; } temp |= barrBarrI; } m_ints[iarrJ] = temp; } } public boolean isZero() { return m_ints.length == 0 || (m_ints[0] == 0 && getUsedLength() == 0); } public int getUsedLength() { int highestIntPos = m_ints.length; if (highestIntPos < 1) { return 0; } // Check if first element will act as sentinel if (m_ints[0] != 0) { while (m_ints[--highestIntPos] == 0) { } return highestIntPos + 1; } do { if (m_ints[--highestIntPos] != 0) { return highestIntPos + 1; } } while (highestIntPos > 0); return 0; } public int bitLength() { // JDK 1.5: see Integer.numberOfLeadingZeros() int intLen = getUsedLength(); if (intLen == 0) { return 0; } int last = intLen - 1; int highest = m_ints[last]; int bits = (last << 5) + 1; // A couple of binary search steps if ((highest & 0xffff0000) != 0) { if ((highest & 0xff000000) != 0) { bits += 24; highest >>>= 24; } else { bits += 16; highest >>>= 16; } } else if (highest > 0x000000ff) { bits += 8; highest >>>= 8; } while (highest != 1) { ++bits; highest >>>= 1; } return bits; } private int[] resizedInts(int newLen) { int[] newInts = new int[newLen]; int oldLen = m_ints.length; int copyLen = oldLen < newLen ? oldLen : newLen; System.arraycopy(m_ints, 0, newInts, 0, copyLen); return newInts; } public BigInteger toBigInteger() { int usedLen = getUsedLength(); if (usedLen == 0) { return ECConstants.ZERO; } int highestInt = m_ints[usedLen - 1]; byte[] temp = new byte[4]; int barrI = 0; boolean trailingZeroBytesDone = false; for (int j = 3; j >= 0; j--) { byte thisByte = (byte) (highestInt >>> (8 * j)); if (trailingZeroBytesDone || (thisByte != 0)) { trailingZeroBytesDone = true; temp[barrI++] = thisByte; } } int barrLen = 4 * (usedLen - 1) + barrI; byte[] barr = new byte[barrLen]; for (int j = 0; j < barrI; j++) { barr[j] = temp[j]; } // Highest value int is done now for (int iarrJ = usedLen - 2; iarrJ >= 0; iarrJ--) { for (int j = 3; j >= 0; j--) { barr[barrI++] = (byte) (m_ints[iarrJ] >>> (8 * j)); } } return new BigInteger(1, barr); } public void shiftLeft() { int usedLen = getUsedLength(); if (usedLen == 0) { return; } if (m_ints[usedLen - 1] < 0) { // highest bit of highest used byte is set, so shifting left will // make the IntArray one byte longer usedLen++; if (usedLen > m_ints.length) { // make the m_ints one byte longer, because we need one more // byte which is not available in m_ints m_ints = resizedInts(m_ints.length + 1); } } boolean carry = false; for (int i = 0; i < usedLen; i++) { // nextCarry is true if highest bit is set boolean nextCarry = m_ints[i] < 0; m_ints[i] <<= 1; if (carry) { // set lowest bit m_ints[i] |= 1; } carry = nextCarry; } } public IntArray shiftLeft(int n) { int usedLen = getUsedLength(); if (usedLen == 0) { return this; } if (n == 0) { return this; } if (n > 31) { throw new IllegalArgumentException("shiftLeft() for max 31 bits " + ", " + n + "bit shift is not possible"); } int[] newInts = new int[usedLen + 1]; int nm32 = 32 - n; newInts[0] = m_ints[0] << n; for (int i = 1; i < usedLen; i++) { newInts[i] = (m_ints[i] << n) | (m_ints[i - 1] >>> nm32); } newInts[usedLen] = m_ints[usedLen - 1] >>> nm32; return new IntArray(newInts); } public void addShifted(IntArray other, int shift) { int usedLenOther = other.getUsedLength(); int newMinUsedLen = usedLenOther + shift; if (newMinUsedLen > m_ints.length) { m_ints = resizedInts(newMinUsedLen); //System.out.println("Resize required"); } for (int i = 0; i < usedLenOther; i++) { m_ints[i + shift] ^= other.m_ints[i]; } } public int getLength() { return m_ints.length; } public boolean testBit(int n) { // theInt = n / 32 int theInt = n >> 5; // theBit = n % 32 int theBit = n & 0x1F; int tester = 1 << theBit; return ((m_ints[theInt] & tester) != 0); } public void flipBit(int n) { // theInt = n / 32 int theInt = n >> 5; // theBit = n % 32 int theBit = n & 0x1F; int flipper = 1 << theBit; m_ints[theInt] ^= flipper; } public void setBit(int n) { // theInt = n / 32 int theInt = n >> 5; // theBit = n % 32 int theBit = n & 0x1F; int setter = 1 << theBit; m_ints[theInt] |= setter; } public IntArray multiply(IntArray other, int m) { // Lenght of c is 2m bits rounded up to the next int (32 bit) int t = (m + 31) >> 5; if (m_ints.length < t) { m_ints = resizedInts(t); } IntArray b = new IntArray(other.resizedInts(other.getLength() + 1)); IntArray c = new IntArray((m + m + 31) >> 5); // IntArray c = new IntArray(t + t); int testBit = 1; for (int k = 0; k < 32; k++) { for (int j = 0; j < t; j++) { if ((m_ints[j] & testBit) != 0) { // The kth bit of m_ints[j] is set c.addShifted(b, j); } } testBit <<= 1; b.shiftLeft(); } return c; } // public IntArray multiplyLeftToRight(IntArray other, int m) { // // Lenght of c is 2m bits rounded up to the next int (32 bit) // int t = (m + 31) / 32; // if (m_ints.length < t) { // m_ints = resizedInts(t); // } // // IntArray b = new IntArray(other.resizedInts(other.getLength() + 1)); // IntArray c = new IntArray((m + m + 31) / 32); // // IntArray c = new IntArray(t + t); // int testBit = 1 << 31; // for (int k = 31; k >= 0; k--) { // for (int j = 0; j < t; j++) { // if ((m_ints[j] & testBit) != 0) { // // The kth bit of m_ints[j] is set // c.addShifted(b, j); // } // } // testBit >>>= 1; // if (k > 0) { // c.shiftLeft(); // } // } // return c; // } // TODO note, redPol.length must be 3 for TPB and 5 for PPB public void reduce(int m, int[] redPol) { for (int i = m + m - 2; i >= m; i--) { if (testBit(i)) { int bit = i - m; flipBit(bit); flipBit(i); int l = redPol.length; while (--l >= 0) { flipBit(redPol[l] + bit); } } } m_ints = resizedInts((m + 31) >> 5); } public IntArray square(int m) { // TODO make the table static final final int[] table = { 0x0, 0x1, 0x4, 0x5, 0x10, 0x11, 0x14, 0x15, 0x40, 0x41, 0x44, 0x45, 0x50, 0x51, 0x54, 0x55 }; int t = (m + 31) >> 5; if (m_ints.length < t) { m_ints = resizedInts(t); } IntArray c = new IntArray(t + t); // TODO twice the same code, put in separate private method for (int i = 0; i < t; i++) { int v0 = 0; for (int j = 0; j < 4; j++) { v0 = v0 >>> 8; int u = (m_ints[i] >>> (j * 4)) & 0xF; int w = table[u] << 24; v0 |= w; } c.m_ints[i + i] = v0; v0 = 0; int upper = m_ints[i] >>> 16; for (int j = 0; j < 4; j++) { v0 = v0 >>> 8; int u = (upper >>> (j * 4)) & 0xF; int w = table[u] << 24; v0 |= w; } c.m_ints[i + i + 1] = v0; } return c; } public boolean equals(Object o) { if (!(o instanceof IntArray)) { return false; } IntArray other = (IntArray) o; int usedLen = getUsedLength(); if (other.getUsedLength() != usedLen) { return false; } for (int i = 0; i < usedLen; i++) { if (m_ints[i] != other.m_ints[i]) { return false; } } return true; } public int hashCode() { int usedLen = getUsedLength(); int hash = 1; for (int i = 0; i < usedLen; i++) { hash = hash * 31 + m_ints[i]; } return hash; } public Object clone() { return new IntArray(Arrays.clone(m_ints)); } public String toString() { int usedLen = getUsedLength(); if (usedLen == 0) { return "0"; } StringBuffer sb = new StringBuffer(Integer .toBinaryString(m_ints[usedLen - 1])); for (int iarrJ = usedLen - 2; iarrJ >= 0; iarrJ--) { String hexString = Integer.toBinaryString(m_ints[iarrJ]); // Add leading zeroes, except for highest significant int for (int i = hexString.length(); i < 8; i++) { hexString = "0" + hexString; } sb.append(hexString); } return sb.toString(); } } bouncycastle-1.49.orig/src/org/bouncycastle/math/ec/PreCompInfo.java0000644000175000017500000000034510662310167025052 0ustar ebourgebourgpackage org.bouncycastle.math.ec; /** * Interface for classes storing precomputation data for multiplication * algorithms. Used as a Memento (see GOF patterns) for * WNafMultiplier. */ interface PreCompInfo { } bouncycastle-1.49.orig/src/org/bouncycastle/math/ec/WNafMultiplier.java0000644000175000017500000001653210675113137025602 0ustar ebourgebourgpackage org.bouncycastle.math.ec; import java.math.BigInteger; /** * Class implementing the WNAF (Window Non-Adjacent Form) multiplication * algorithm. */ class WNafMultiplier implements ECMultiplier { /** * Computes the Window NAF (non-adjacent Form) of an integer. * @param width The width w of the Window NAF. The width is * defined as the minimal number w, such that for any * w consecutive digits in the resulting representation, at * most one is non-zero. * @param k The integer of which the Window NAF is computed. * @return The Window NAF of the given width, such that the following holds: * k = ∑i=0l-1 ki2i * , where the ki denote the elements of the * returned byte[]. */ public byte[] windowNaf(byte width, BigInteger k) { // The window NAF is at most 1 element longer than the binary // representation of the integer k. byte can be used instead of short or // int unless the window width is larger than 8. For larger width use // short or int. However, a width of more than 8 is not efficient for // m = log2(q) smaller than 2305 Bits. Note: Values for m larger than // 1000 Bits are currently not used in practice. byte[] wnaf = new byte[k.bitLength() + 1]; // 2^width as short and BigInteger short pow2wB = (short)(1 << width); BigInteger pow2wBI = BigInteger.valueOf(pow2wB); int i = 0; // The actual length of the WNAF int length = 0; // while k >= 1 while (k.signum() > 0) { // if k is odd if (k.testBit(0)) { // k mod 2^width BigInteger remainder = k.mod(pow2wBI); // if remainder > 2^(width - 1) - 1 if (remainder.testBit(width - 1)) { wnaf[i] = (byte)(remainder.intValue() - pow2wB); } else { wnaf[i] = (byte)remainder.intValue(); } // wnaf[i] is now in [-2^(width-1), 2^(width-1)-1] k = k.subtract(BigInteger.valueOf(wnaf[i])); length = i; } else { wnaf[i] = 0; } // k = k/2 k = k.shiftRight(1); i++; } length++; // Reduce the WNAF array to its actual length byte[] wnafShort = new byte[length]; System.arraycopy(wnaf, 0, wnafShort, 0, length); return wnafShort; } /** * Multiplies this by an integer k using the * Window NAF method. * @param k The integer by which this is multiplied. * @return A new ECPoint which equals this * multiplied by k. */ public ECPoint multiply(ECPoint p, BigInteger k, PreCompInfo preCompInfo) { WNafPreCompInfo wnafPreCompInfo; if ((preCompInfo != null) && (preCompInfo instanceof WNafPreCompInfo)) { wnafPreCompInfo = (WNafPreCompInfo)preCompInfo; } else { // Ignore empty PreCompInfo or PreCompInfo of incorrect type wnafPreCompInfo = new WNafPreCompInfo(); } // floor(log2(k)) int m = k.bitLength(); // width of the Window NAF byte width; // Required length of precomputation array int reqPreCompLen; // Determine optimal width and corresponding length of precomputation // array based on literature values if (m < 13) { width = 2; reqPreCompLen = 1; } else { if (m < 41) { width = 3; reqPreCompLen = 2; } else { if (m < 121) { width = 4; reqPreCompLen = 4; } else { if (m < 337) { width = 5; reqPreCompLen = 8; } else { if (m < 897) { width = 6; reqPreCompLen = 16; } else { if (m < 2305) { width = 7; reqPreCompLen = 32; } else { width = 8; reqPreCompLen = 127; } } } } } } // The length of the precomputation array int preCompLen = 1; ECPoint[] preComp = wnafPreCompInfo.getPreComp(); ECPoint twiceP = wnafPreCompInfo.getTwiceP(); // Check if the precomputed ECPoints already exist if (preComp == null) { // Precomputation must be performed from scratch, create an empty // precomputation array of desired length preComp = new ECPoint[]{ p }; } else { // Take the already precomputed ECPoints to start with preCompLen = preComp.length; } if (twiceP == null) { // Compute twice(p) twiceP = p.twice(); } if (preCompLen < reqPreCompLen) { // Precomputation array must be made bigger, copy existing preComp // array into the larger new preComp array ECPoint[] oldPreComp = preComp; preComp = new ECPoint[reqPreCompLen]; System.arraycopy(oldPreComp, 0, preComp, 0, preCompLen); for (int i = preCompLen; i < reqPreCompLen; i++) { // Compute the new ECPoints for the precomputation array. // The values 1, 3, 5, ..., 2^(width-1)-1 times p are // computed preComp[i] = twiceP.add(preComp[i - 1]); } } // Compute the Window NAF of the desired width byte[] wnaf = windowNaf(width, k); int l = wnaf.length; // Apply the Window NAF to p using the precomputed ECPoint values. ECPoint q = p.getCurve().getInfinity(); for (int i = l - 1; i >= 0; i--) { q = q.twice(); if (wnaf[i] != 0) { if (wnaf[i] > 0) { q = q.add(preComp[(wnaf[i] - 1)/2]); } else { // wnaf[i] < 0 q = q.subtract(preComp[(-wnaf[i] - 1)/2]); } } } // Set PreCompInfo in ECPoint, such that it is available for next // multiplication. wnafPreCompInfo.setPreComp(preComp); wnafPreCompInfo.setTwiceP(twiceP); p.setPreCompInfo(wnafPreCompInfo); return q; } } bouncycastle-1.49.orig/src/org/bouncycastle/math/ec/ReferenceMultiplier.java0000644000175000017500000000152510675113261026637 0ustar ebourgebourgpackage org.bouncycastle.math.ec; import java.math.BigInteger; class ReferenceMultiplier implements ECMultiplier { /** * Simple shift-and-add multiplication. Serves as reference implementation * to verify (possibly faster) implementations in * {@link org.bouncycastle.math.ec.ECPoint ECPoint}. * * @param p The point to multiply. * @param k The factor by which to multiply. * @return The result of the point multiplication k * p. */ public ECPoint multiply(ECPoint p, BigInteger k, PreCompInfo preCompInfo) { ECPoint q = p.getCurve().getInfinity(); int t = k.bitLength(); for (int i = 0; i < t; i++) { if (k.testBit(i)) { q = q.add(p); } p = p.twice(); } return q; } } bouncycastle-1.49.orig/src/org/bouncycastle/math/ec/FpNafMultiplier.java0000644000175000017500000000175210675113261025735 0ustar ebourgebourgpackage org.bouncycastle.math.ec; import java.math.BigInteger; /** * Class implementing the NAF (Non-Adjacent Form) multiplication algorithm. */ class FpNafMultiplier implements ECMultiplier { /** * D.3.2 pg 101 * @see org.bouncycastle.math.ec.ECMultiplier#multiply(org.bouncycastle.math.ec.ECPoint, java.math.BigInteger) */ public ECPoint multiply(ECPoint p, BigInteger k, PreCompInfo preCompInfo) { // TODO Probably should try to add this // BigInteger e = k.mod(n); // n == order of p BigInteger e = k; BigInteger h = e.multiply(BigInteger.valueOf(3)); ECPoint neg = p.negate(); ECPoint R = p; for (int i = h.bitLength() - 2; i > 0; --i) { R = R.twice(); boolean hBit = h.testBit(i); boolean eBit = e.testBit(i); if (hBit != eBit) { R = R.add(hBit ? p : neg); } } return R; } } bouncycastle-1.49.orig/src/org/bouncycastle/math/ec/ZTauElement.java0000644000175000017500000000203510662552433025070 0ustar ebourgebourgpackage org.bouncycastle.math.ec; import java.math.BigInteger; /** * Class representing an element of Z[τ]. Let * λ be an element of Z[τ]. Then * λ is given as λ = u + vτ. The * components u and v may be used directly, there * are no accessor methods. * Immutable class. */ class ZTauElement { /** * The "real" part of λ. */ public final BigInteger u; /** * The "τ-adic" part of λ. */ public final BigInteger v; /** * Constructor for an element λ of * Z[τ]. * @param u The "real" part of λ. * @param v The "τ-adic" part of * λ. */ public ZTauElement(BigInteger u, BigInteger v) { this.u = u; this.v = v; } } bouncycastle-1.49.orig/src/org/bouncycastle/math/ec/ECConstants.java0000644000175000017500000000064610510433146025054 0ustar ebourgebourgpackage org.bouncycastle.math.ec; import java.math.BigInteger; public interface ECConstants { public static final BigInteger ZERO = BigInteger.valueOf(0); public static final BigInteger ONE = BigInteger.valueOf(1); public static final BigInteger TWO = BigInteger.valueOf(2); public static final BigInteger THREE = BigInteger.valueOf(3); public static final BigInteger FOUR = BigInteger.valueOf(4); } bouncycastle-1.49.orig/src/org/bouncycastle/math/ec/SimpleBigDecimal.java0000644000175000017500000001533310714457775026045 0ustar ebourgebourgpackage org.bouncycastle.math.ec; import java.math.BigInteger; /** * Class representing a simple version of a big decimal. A * SimpleBigDecimal is basically a * {@link java.math.BigInteger BigInteger} with a few digits on the right of * the decimal point. The number of (binary) digits on the right of the decimal * point is called the scale of the SimpleBigDecimal. * Unlike in {@link java.math.BigDecimal BigDecimal}, the scale is not adjusted * automatically, but must be set manually. All SimpleBigDecimals * taking part in the same arithmetic operation must have equal scale. The * result of a multiplication of two SimpleBigDecimals returns a * SimpleBigDecimal with double scale. */ class SimpleBigDecimal //extends Number // not in J2ME - add compatibility class? { private static final long serialVersionUID = 1L; private final BigInteger bigInt; private final int scale; /** * Returns a SimpleBigDecimal representing the same numerical * value as value. * @param value The value of the SimpleBigDecimal to be * created. * @param scale The scale of the SimpleBigDecimal to be * created. * @return The such created SimpleBigDecimal. */ public static SimpleBigDecimal getInstance(BigInteger value, int scale) { return new SimpleBigDecimal(value.shiftLeft(scale), scale); } /** * Constructor for SimpleBigDecimal. The value of the * constructed SimpleBigDecimal equals bigInt / * 2scale. * @param bigInt The bigInt value parameter. * @param scale The scale of the constructed SimpleBigDecimal. */ public SimpleBigDecimal(BigInteger bigInt, int scale) { if (scale < 0) { throw new IllegalArgumentException("scale may not be negative"); } this.bigInt = bigInt; this.scale = scale; } private SimpleBigDecimal(SimpleBigDecimal limBigDec) { bigInt = limBigDec.bigInt; scale = limBigDec.scale; } private void checkScale(SimpleBigDecimal b) { if (scale != b.scale) { throw new IllegalArgumentException("Only SimpleBigDecimal of " + "same scale allowed in arithmetic operations"); } } public SimpleBigDecimal adjustScale(int newScale) { if (newScale < 0) { throw new IllegalArgumentException("scale may not be negative"); } if (newScale == scale) { return new SimpleBigDecimal(this); } return new SimpleBigDecimal(bigInt.shiftLeft(newScale - scale), newScale); } public SimpleBigDecimal add(SimpleBigDecimal b) { checkScale(b); return new SimpleBigDecimal(bigInt.add(b.bigInt), scale); } public SimpleBigDecimal add(BigInteger b) { return new SimpleBigDecimal(bigInt.add(b.shiftLeft(scale)), scale); } public SimpleBigDecimal negate() { return new SimpleBigDecimal(bigInt.negate(), scale); } public SimpleBigDecimal subtract(SimpleBigDecimal b) { return add(b.negate()); } public SimpleBigDecimal subtract(BigInteger b) { return new SimpleBigDecimal(bigInt.subtract(b.shiftLeft(scale)), scale); } public SimpleBigDecimal multiply(SimpleBigDecimal b) { checkScale(b); return new SimpleBigDecimal(bigInt.multiply(b.bigInt), scale + scale); } public SimpleBigDecimal multiply(BigInteger b) { return new SimpleBigDecimal(bigInt.multiply(b), scale); } public SimpleBigDecimal divide(SimpleBigDecimal b) { checkScale(b); BigInteger dividend = bigInt.shiftLeft(scale); return new SimpleBigDecimal(dividend.divide(b.bigInt), scale); } public SimpleBigDecimal divide(BigInteger b) { return new SimpleBigDecimal(bigInt.divide(b), scale); } public SimpleBigDecimal shiftLeft(int n) { return new SimpleBigDecimal(bigInt.shiftLeft(n), scale); } public int compareTo(SimpleBigDecimal val) { checkScale(val); return bigInt.compareTo(val.bigInt); } public int compareTo(BigInteger val) { return bigInt.compareTo(val.shiftLeft(scale)); } public BigInteger floor() { return bigInt.shiftRight(scale); } public BigInteger round() { SimpleBigDecimal oneHalf = new SimpleBigDecimal(ECConstants.ONE, 1); return add(oneHalf.adjustScale(scale)).floor(); } public int intValue() { return floor().intValue(); } public long longValue() { return floor().longValue(); } /* NON-J2ME compliant. public double doubleValue() { return Double.valueOf(toString()).doubleValue(); } public float floatValue() { return Float.valueOf(toString()).floatValue(); } */ public int getScale() { return scale; } public String toString() { if (scale == 0) { return bigInt.toString(); } BigInteger floorBigInt = floor(); BigInteger fract = bigInt.subtract(floorBigInt.shiftLeft(scale)); if (bigInt.signum() == -1) { fract = ECConstants.ONE.shiftLeft(scale).subtract(fract); } if ((floorBigInt.signum() == -1) && (!(fract.equals(ECConstants.ZERO)))) { floorBigInt = floorBigInt.add(ECConstants.ONE); } String leftOfPoint = floorBigInt.toString(); char[] fractCharArr = new char[scale]; String fractStr = fract.toString(2); int fractLen = fractStr.length(); int zeroes = scale - fractLen; for (int i = 0; i < zeroes; i++) { fractCharArr[i] = '0'; } for (int j = 0; j < fractLen; j++) { fractCharArr[zeroes + j] = fractStr.charAt(j); } String rightOfPoint = new String(fractCharArr); StringBuffer sb = new StringBuffer(leftOfPoint); sb.append("."); sb.append(rightOfPoint); return sb.toString(); } public boolean equals(Object o) { if (this == o) { return true; } if (!(o instanceof SimpleBigDecimal)) { return false; } SimpleBigDecimal other = (SimpleBigDecimal)o; return ((bigInt.equals(other.bigInt)) && (scale == other.scale)); } public int hashCode() { return bigInt.hashCode() ^ scale; } } bouncycastle-1.49.orig/src/org/bouncycastle/math/ec/WTauNafMultiplier.java0000644000175000017500000000736410675113137026257 0ustar ebourgebourgpackage org.bouncycastle.math.ec; import java.math.BigInteger; /** * Class implementing the WTNAF (Window * τ-adic Non-Adjacent Form) algorithm. */ class WTauNafMultiplier implements ECMultiplier { /** * Multiplies a {@link org.bouncycastle.math.ec.ECPoint.F2m ECPoint.F2m} * by k using the reduced τ-adic NAF (RTNAF) * method. * @param p The ECPoint.F2m to multiply. * @param k The integer by which to multiply k. * @return p multiplied by k. */ public ECPoint multiply(ECPoint point, BigInteger k, PreCompInfo preCompInfo) { if (!(point instanceof ECPoint.F2m)) { throw new IllegalArgumentException("Only ECPoint.F2m can be " + "used in WTauNafMultiplier"); } ECPoint.F2m p = (ECPoint.F2m)point; ECCurve.F2m curve = (ECCurve.F2m) p.getCurve(); int m = curve.getM(); byte a = curve.getA().toBigInteger().byteValue(); byte mu = curve.getMu(); BigInteger[] s = curve.getSi(); ZTauElement rho = Tnaf.partModReduction(k, m, a, s, mu, (byte)10); return multiplyWTnaf(p, rho, preCompInfo, a, mu); } /** * Multiplies a {@link org.bouncycastle.math.ec.ECPoint.F2m ECPoint.F2m} * by an element λ of Z[τ] using * the τ-adic NAF (TNAF) method. * @param p The ECPoint.F2m to multiply. * @param lambda The element λ of * Z[τ] of which to compute the * [τ]-adic NAF. * @return p multiplied by λ. */ private ECPoint.F2m multiplyWTnaf(ECPoint.F2m p, ZTauElement lambda, PreCompInfo preCompInfo, byte a, byte mu) { ZTauElement[] alpha; if (a == 0) { alpha = Tnaf.alpha0; } else { // a == 1 alpha = Tnaf.alpha1; } BigInteger tw = Tnaf.getTw(mu, Tnaf.WIDTH); byte[]u = Tnaf.tauAdicWNaf(mu, lambda, Tnaf.WIDTH, BigInteger.valueOf(Tnaf.POW_2_WIDTH), tw, alpha); return multiplyFromWTnaf(p, u, preCompInfo); } /** * Multiplies a {@link org.bouncycastle.math.ec.ECPoint.F2m ECPoint.F2m} * by an element λ of Z[τ] * using the window τ-adic NAF (TNAF) method, given the * WTNAF of λ. * @param p The ECPoint.F2m to multiply. * @param u The the WTNAF of λ.. * @return λ * p */ private static ECPoint.F2m multiplyFromWTnaf(ECPoint.F2m p, byte[] u, PreCompInfo preCompInfo) { ECCurve.F2m curve = (ECCurve.F2m)p.getCurve(); byte a = curve.getA().toBigInteger().byteValue(); ECPoint.F2m[] pu; if ((preCompInfo == null) || !(preCompInfo instanceof WTauNafPreCompInfo)) { pu = Tnaf.getPreComp(p, a); p.setPreCompInfo(new WTauNafPreCompInfo(pu)); } else { pu = ((WTauNafPreCompInfo)preCompInfo).getPreComp(); } // q = infinity ECPoint.F2m q = (ECPoint.F2m) p.getCurve().getInfinity(); for (int i = u.length - 1; i >= 0; i--) { q = Tnaf.tau(q); if (u[i] != 0) { if (u[i] > 0) { q = q.addSimple(pu[u[i]]); } else { // u[i] < 0 q = q.subtractSimple(pu[-u[i]]); } } } return q; } } bouncycastle-1.49.orig/src/org/bouncycastle/math/ec/ECMultiplier.java0000644000175000017500000000113610662310167025226 0ustar ebourgebourgpackage org.bouncycastle.math.ec; import java.math.BigInteger; /** * Interface for classes encapsulating a point multiplication algorithm * for ECPoints. */ interface ECMultiplier { /** * Multiplies the ECPoint p by k, i.e. * p is added k times to itself. * @param p The ECPoint to be multiplied. * @param k The factor by which p i multiplied. * @return p multiplied by k. */ ECPoint multiply(ECPoint p, BigInteger k, PreCompInfo preCompInfo); } bouncycastle-1.49.orig/src/org/bouncycastle/math/ec/Tnaf.java0000644000175000017500000006352210714106672023571 0ustar ebourgebourgpackage org.bouncycastle.math.ec; import java.math.BigInteger; /** * Class holding methods for point multiplication based on the window * τ-adic nonadjacent form (WTNAF). The algorithms are based on the * paper "Improved Algorithms for Arithmetic on Anomalous Binary Curves" * by Jerome A. Solinas. The paper first appeared in the Proceedings of * Crypto 1997. */ class Tnaf { private static final BigInteger MINUS_ONE = ECConstants.ONE.negate(); private static final BigInteger MINUS_TWO = ECConstants.TWO.negate(); private static final BigInteger MINUS_THREE = ECConstants.THREE.negate(); /** * The window width of WTNAF. The standard value of 4 is slightly less * than optimal for running time, but keeps space requirements for * precomputation low. For typical curves, a value of 5 or 6 results in * a better running time. When changing this value, the * αu's must be computed differently, see * e.g. "Guide to Elliptic Curve Cryptography", Darrel Hankerson, * Alfred Menezes, Scott Vanstone, Springer-Verlag New York Inc., 2004, * p. 121-122 */ public static final byte WIDTH = 4; /** * 24 */ public static final byte POW_2_WIDTH = 16; /** * The αu's for a=0 as an array * of ZTauElements. */ public static final ZTauElement[] alpha0 = { null, new ZTauElement(ECConstants.ONE, ECConstants.ZERO), null, new ZTauElement(MINUS_THREE, MINUS_ONE), null, new ZTauElement(MINUS_ONE, MINUS_ONE), null, new ZTauElement(ECConstants.ONE, MINUS_ONE), null }; /** * The αu's for a=0 as an array * of TNAFs. */ public static final byte[][] alpha0Tnaf = { null, {1}, null, {-1, 0, 1}, null, {1, 0, 1}, null, {-1, 0, 0, 1} }; /** * The αu's for a=1 as an array * of ZTauElements. */ public static final ZTauElement[] alpha1 = {null, new ZTauElement(ECConstants.ONE, ECConstants.ZERO), null, new ZTauElement(MINUS_THREE, ECConstants.ONE), null, new ZTauElement(MINUS_ONE, ECConstants.ONE), null, new ZTauElement(ECConstants.ONE, ECConstants.ONE), null }; /** * The αu's for a=1 as an array * of TNAFs. */ public static final byte[][] alpha1Tnaf = { null, {1}, null, {-1, 0, 1}, null, {1, 0, 1}, null, {-1, 0, 0, -1} }; /** * Computes the norm of an element λ of * Z[τ]. * @param mu The parameter μ of the elliptic curve. * @param lambda The element λ of * Z[τ]. * @return The norm of λ. */ public static BigInteger norm(final byte mu, ZTauElement lambda) { BigInteger norm; // s1 = u^2 BigInteger s1 = lambda.u.multiply(lambda.u); // s2 = u * v BigInteger s2 = lambda.u.multiply(lambda.v); // s3 = 2 * v^2 BigInteger s3 = lambda.v.multiply(lambda.v).shiftLeft(1); if (mu == 1) { norm = s1.add(s2).add(s3); } else if (mu == -1) { norm = s1.subtract(s2).add(s3); } else { throw new IllegalArgumentException("mu must be 1 or -1"); } return norm; } /** * Computes the norm of an element λ of * R[τ], where λ = u + vτ * and u and u are real numbers (elements of * R). * @param mu The parameter μ of the elliptic curve. * @param u The real part of the element λ of * R[τ]. * @param v The τ-adic part of the element * λ of R[τ]. * @return The norm of λ. */ public static SimpleBigDecimal norm(final byte mu, SimpleBigDecimal u, SimpleBigDecimal v) { SimpleBigDecimal norm; // s1 = u^2 SimpleBigDecimal s1 = u.multiply(u); // s2 = u * v SimpleBigDecimal s2 = u.multiply(v); // s3 = 2 * v^2 SimpleBigDecimal s3 = v.multiply(v).shiftLeft(1); if (mu == 1) { norm = s1.add(s2).add(s3); } else if (mu == -1) { norm = s1.subtract(s2).add(s3); } else { throw new IllegalArgumentException("mu must be 1 or -1"); } return norm; } /** * Rounds an element λ of R[τ] * to an element of Z[τ], such that their difference * has minimal norm. λ is given as * λ = λ0 + λ1τ. * @param lambda0 The component λ0. * @param lambda1 The component λ1. * @param mu The parameter μ of the elliptic curve. Must * equal 1 or -1. * @return The rounded element of Z[τ]. * @throws IllegalArgumentException if lambda0 and * lambda1 do not have same scale. */ public static ZTauElement round(SimpleBigDecimal lambda0, SimpleBigDecimal lambda1, byte mu) { int scale = lambda0.getScale(); if (lambda1.getScale() != scale) { throw new IllegalArgumentException("lambda0 and lambda1 do not " + "have same scale"); } if (!((mu == 1) || (mu == -1))) { throw new IllegalArgumentException("mu must be 1 or -1"); } BigInteger f0 = lambda0.round(); BigInteger f1 = lambda1.round(); SimpleBigDecimal eta0 = lambda0.subtract(f0); SimpleBigDecimal eta1 = lambda1.subtract(f1); // eta = 2*eta0 + mu*eta1 SimpleBigDecimal eta = eta0.add(eta0); if (mu == 1) { eta = eta.add(eta1); } else { // mu == -1 eta = eta.subtract(eta1); } // check1 = eta0 - 3*mu*eta1 // check2 = eta0 + 4*mu*eta1 SimpleBigDecimal threeEta1 = eta1.add(eta1).add(eta1); SimpleBigDecimal fourEta1 = threeEta1.add(eta1); SimpleBigDecimal check1; SimpleBigDecimal check2; if (mu == 1) { check1 = eta0.subtract(threeEta1); check2 = eta0.add(fourEta1); } else { // mu == -1 check1 = eta0.add(threeEta1); check2 = eta0.subtract(fourEta1); } byte h0 = 0; byte h1 = 0; // if eta >= 1 if (eta.compareTo(ECConstants.ONE) >= 0) { if (check1.compareTo(MINUS_ONE) < 0) { h1 = mu; } else { h0 = 1; } } else { // eta < 1 if (check2.compareTo(ECConstants.TWO) >= 0) { h1 = mu; } } // if eta < -1 if (eta.compareTo(MINUS_ONE) < 0) { if (check1.compareTo(ECConstants.ONE) >= 0) { h1 = (byte)-mu; } else { h0 = -1; } } else { // eta >= -1 if (check2.compareTo(MINUS_TWO) < 0) { h1 = (byte)-mu; } } BigInteger q0 = f0.add(BigInteger.valueOf(h0)); BigInteger q1 = f1.add(BigInteger.valueOf(h1)); return new ZTauElement(q0, q1); } /** * Approximate division by n. For an integer * k, the value λ = s k / n is * computed to c bits of accuracy. * @param k The parameter k. * @param s The curve parameter s0 or * s1. * @param vm The Lucas Sequence element Vm. * @param a The parameter a of the elliptic curve. * @param m The bit length of the finite field * Fm. * @param c The number of bits of accuracy, i.e. the scale of the returned * SimpleBigDecimal. * @return The value λ = s k / n computed to * c bits of accuracy. */ public static SimpleBigDecimal approximateDivisionByN(BigInteger k, BigInteger s, BigInteger vm, byte a, int m, int c) { int _k = (m + 5)/2 + c; BigInteger ns = k.shiftRight(m - _k - 2 + a); BigInteger gs = s.multiply(ns); BigInteger hs = gs.shiftRight(m); BigInteger js = vm.multiply(hs); BigInteger gsPlusJs = gs.add(js); BigInteger ls = gsPlusJs.shiftRight(_k-c); if (gsPlusJs.testBit(_k-c-1)) { // round up ls = ls.add(ECConstants.ONE); } return new SimpleBigDecimal(ls, c); } /** * Computes the τ-adic NAF (non-adjacent form) of an * element λ of Z[τ]. * @param mu The parameter μ of the elliptic curve. * @param lambda The element λ of * Z[τ]. * @return The τ-adic NAF of λ. */ public static byte[] tauAdicNaf(byte mu, ZTauElement lambda) { if (!((mu == 1) || (mu == -1))) { throw new IllegalArgumentException("mu must be 1 or -1"); } BigInteger norm = norm(mu, lambda); // Ceiling of log2 of the norm int log2Norm = norm.bitLength(); // If length(TNAF) > 30, then length(TNAF) < log2Norm + 3.52 int maxLength = log2Norm > 30 ? log2Norm + 4 : 34; // The array holding the TNAF byte[] u = new byte[maxLength]; int i = 0; // The actual length of the TNAF int length = 0; BigInteger r0 = lambda.u; BigInteger r1 = lambda.v; while(!((r0.equals(ECConstants.ZERO)) && (r1.equals(ECConstants.ZERO)))) { // If r0 is odd if (r0.testBit(0)) { u[i] = (byte) ECConstants.TWO.subtract((r0.subtract(r1.shiftLeft(1))).mod(ECConstants.FOUR)).intValue(); // r0 = r0 - u[i] if (u[i] == 1) { r0 = r0.clearBit(0); } else { // u[i] == -1 r0 = r0.add(ECConstants.ONE); } length = i; } else { u[i] = 0; } BigInteger t = r0; BigInteger s = r0.shiftRight(1); if (mu == 1) { r0 = r1.add(s); } else { // mu == -1 r0 = r1.subtract(s); } r1 = t.shiftRight(1).negate(); i++; } length++; // Reduce the TNAF array to its actual length byte[] tnaf = new byte[length]; System.arraycopy(u, 0, tnaf, 0, length); return tnaf; } /** * Applies the operation τ() to an * ECPoint.F2m. * @param p The ECPoint.F2m to which τ() is applied. * @return τ(p) */ public static ECPoint.F2m tau(ECPoint.F2m p) { if (p.isInfinity()) { return p; } ECFieldElement x = p.getX(); ECFieldElement y = p.getY(); return new ECPoint.F2m(p.getCurve(), x.square(), y.square(), p.isCompressed()); } /** * Returns the parameter μ of the elliptic curve. * @param curve The elliptic curve from which to obtain μ. * The curve must be a Koblitz curve, i.e. a equals * 0 or 1 and b equals * 1. * @return μ of the elliptic curve. * @throws IllegalArgumentException if the given ECCurve is not a Koblitz * curve. */ public static byte getMu(ECCurve.F2m curve) { BigInteger a = curve.getA().toBigInteger(); byte mu; if (a.equals(ECConstants.ZERO)) { mu = -1; } else if (a.equals(ECConstants.ONE)) { mu = 1; } else { throw new IllegalArgumentException("No Koblitz curve (ABC), " + "TNAF multiplication not possible"); } return mu; } /** * Calculates the Lucas Sequence elements Uk-1 and * Uk or Vk-1 and * Vk. * @param mu The parameter μ of the elliptic curve. * @param k The index of the second element of the Lucas Sequence to be * returned. * @param doV If set to true, computes Vk-1 and * Vk, otherwise Uk-1 and * Uk. * @return An array with 2 elements, containing Uk-1 * and Uk or Vk-1 * and Vk. */ public static BigInteger[] getLucas(byte mu, int k, boolean doV) { if (!((mu == 1) || (mu == -1))) { throw new IllegalArgumentException("mu must be 1 or -1"); } BigInteger u0; BigInteger u1; BigInteger u2; if (doV) { u0 = ECConstants.TWO; u1 = BigInteger.valueOf(mu); } else { u0 = ECConstants.ZERO; u1 = ECConstants.ONE; } for (int i = 1; i < k; i++) { // u2 = mu*u1 - 2*u0; BigInteger s = null; if (mu == 1) { s = u1; } else { // mu == -1 s = u1.negate(); } u2 = s.subtract(u0.shiftLeft(1)); u0 = u1; u1 = u2; // System.out.println(i + ": " + u2); // System.out.println(); } BigInteger[] retVal = {u0, u1}; return retVal; } /** * Computes the auxiliary value tw. If the width is * 4, then for mu = 1, tw = 6 and for * mu = -1, tw = 10 * @param mu The parameter μ of the elliptic curve. * @param w The window width of the WTNAF. * @return the auxiliary value tw */ public static BigInteger getTw(byte mu, int w) { if (w == 4) { if (mu == 1) { return BigInteger.valueOf(6); } else { // mu == -1 return BigInteger.valueOf(10); } } else { // For w <> 4, the values must be computed BigInteger[] us = getLucas(mu, w, false); BigInteger twoToW = ECConstants.ZERO.setBit(w); BigInteger u1invert = us[1].modInverse(twoToW); BigInteger tw; tw = ECConstants.TWO.multiply(us[0]).multiply(u1invert).mod(twoToW); // System.out.println("mu = " + mu); // System.out.println("tw = " + tw); return tw; } } /** * Computes the auxiliary values s0 and * s1 used for partial modular reduction. * @param curve The elliptic curve for which to compute * s0 and s1. * @throws IllegalArgumentException if curve is not a * Koblitz curve (Anomalous Binary Curve, ABC). */ public static BigInteger[] getSi(ECCurve.F2m curve) { if (!curve.isKoblitz()) { throw new IllegalArgumentException("si is defined for Koblitz curves only"); } int m = curve.getM(); int a = curve.getA().toBigInteger().intValue(); byte mu = curve.getMu(); int h = curve.getH().intValue(); int index = m + 3 - a; BigInteger[] ui = getLucas(mu, index, false); BigInteger dividend0; BigInteger dividend1; if (mu == 1) { dividend0 = ECConstants.ONE.subtract(ui[1]); dividend1 = ECConstants.ONE.subtract(ui[0]); } else if (mu == -1) { dividend0 = ECConstants.ONE.add(ui[1]); dividend1 = ECConstants.ONE.add(ui[0]); } else { throw new IllegalArgumentException("mu must be 1 or -1"); } BigInteger[] si = new BigInteger[2]; if (h == 2) { si[0] = dividend0.shiftRight(1); si[1] = dividend1.shiftRight(1).negate(); } else if (h == 4) { si[0] = dividend0.shiftRight(2); si[1] = dividend1.shiftRight(2).negate(); } else { throw new IllegalArgumentException("h (Cofactor) must be 2 or 4"); } return si; } /** * Partial modular reduction modulo * m - 1)/(τ - 1). * @param k The integer to be reduced. * @param m The bitlength of the underlying finite field. * @param a The parameter a of the elliptic curve. * @param s The auxiliary values s0 and * s1. * @param mu The parameter μ of the elliptic curve. * @param c The precision (number of bits of accuracy) of the partial * modular reduction. * @return ρ := k partmod (τm - 1)/(τ - 1) */ public static ZTauElement partModReduction(BigInteger k, int m, byte a, BigInteger[] s, byte mu, byte c) { // d0 = s[0] + mu*s[1]; mu is either 1 or -1 BigInteger d0; if (mu == 1) { d0 = s[0].add(s[1]); } else { d0 = s[0].subtract(s[1]); } BigInteger[] v = getLucas(mu, m, true); BigInteger vm = v[1]; SimpleBigDecimal lambda0 = approximateDivisionByN( k, s[0], vm, a, m, c); SimpleBigDecimal lambda1 = approximateDivisionByN( k, s[1], vm, a, m, c); ZTauElement q = round(lambda0, lambda1, mu); // r0 = n - d0*q0 - 2*s1*q1 BigInteger r0 = k.subtract(d0.multiply(q.u)).subtract( BigInteger.valueOf(2).multiply(s[1]).multiply(q.v)); // r1 = s1*q0 - s0*q1 BigInteger r1 = s[1].multiply(q.u).subtract(s[0].multiply(q.v)); return new ZTauElement(r0, r1); } /** * Multiplies a {@link org.bouncycastle.math.ec.ECPoint.F2m ECPoint.F2m} * by a BigInteger using the reduced τ-adic * NAF (RTNAF) method. * @param p The ECPoint.F2m to multiply. * @param k The BigInteger by which to multiply p. * @return k * p */ public static ECPoint.F2m multiplyRTnaf(ECPoint.F2m p, BigInteger k) { ECCurve.F2m curve = (ECCurve.F2m) p.getCurve(); int m = curve.getM(); byte a = (byte) curve.getA().toBigInteger().intValue(); byte mu = curve.getMu(); BigInteger[] s = curve.getSi(); ZTauElement rho = partModReduction(k, m, a, s, mu, (byte)10); return multiplyTnaf(p, rho); } /** * Multiplies a {@link org.bouncycastle.math.ec.ECPoint.F2m ECPoint.F2m} * by an element λ of Z[τ] * using the τ-adic NAF (TNAF) method. * @param p The ECPoint.F2m to multiply. * @param lambda The element λ of * Z[τ]. * @return λ * p */ public static ECPoint.F2m multiplyTnaf(ECPoint.F2m p, ZTauElement lambda) { ECCurve.F2m curve = (ECCurve.F2m)p.getCurve(); byte mu = curve.getMu(); byte[] u = tauAdicNaf(mu, lambda); ECPoint.F2m q = multiplyFromTnaf(p, u); return q; } /** * Multiplies a {@link org.bouncycastle.math.ec.ECPoint.F2m ECPoint.F2m} * by an element λ of Z[τ] * using the τ-adic NAF (TNAF) method, given the TNAF * of λ. * @param p The ECPoint.F2m to multiply. * @param u The the TNAF of λ.. * @return λ * p */ public static ECPoint.F2m multiplyFromTnaf(ECPoint.F2m p, byte[] u) { ECCurve.F2m curve = (ECCurve.F2m)p.getCurve(); ECPoint.F2m q = (ECPoint.F2m) curve.getInfinity(); for (int i = u.length - 1; i >= 0; i--) { q = tau(q); if (u[i] == 1) { q = (ECPoint.F2m)q.addSimple(p); } else if (u[i] == -1) { q = (ECPoint.F2m)q.subtractSimple(p); } } return q; } /** * Computes the [τ]-adic window NAF of an element * λ of Z[τ]. * @param mu The parameter μ of the elliptic curve. * @param lambda The element λ of * Z[τ] of which to compute the * [τ]-adic NAF. * @param width The window width of the resulting WNAF. * @param pow2w 2width. * @param tw The auxiliary value tw. * @param alpha The αu's for the window width. * @return The [τ]-adic window NAF of * λ. */ public static byte[] tauAdicWNaf(byte mu, ZTauElement lambda, byte width, BigInteger pow2w, BigInteger tw, ZTauElement[] alpha) { if (!((mu == 1) || (mu == -1))) { throw new IllegalArgumentException("mu must be 1 or -1"); } BigInteger norm = norm(mu, lambda); // Ceiling of log2 of the norm int log2Norm = norm.bitLength(); // If length(TNAF) > 30, then length(TNAF) < log2Norm + 3.52 int maxLength = log2Norm > 30 ? log2Norm + 4 + width : 34 + width; // The array holding the TNAF byte[] u = new byte[maxLength]; // 2^(width - 1) BigInteger pow2wMin1 = pow2w.shiftRight(1); // Split lambda into two BigIntegers to simplify calculations BigInteger r0 = lambda.u; BigInteger r1 = lambda.v; int i = 0; // while lambda <> (0, 0) while (!((r0.equals(ECConstants.ZERO))&&(r1.equals(ECConstants.ZERO)))) { // if r0 is odd if (r0.testBit(0)) { // uUnMod = r0 + r1*tw mod 2^width BigInteger uUnMod = r0.add(r1.multiply(tw)).mod(pow2w); byte uLocal; // if uUnMod >= 2^(width - 1) if (uUnMod.compareTo(pow2wMin1) >= 0) { uLocal = (byte) uUnMod.subtract(pow2w).intValue(); } else { uLocal = (byte) uUnMod.intValue(); } // uLocal is now in [-2^(width-1), 2^(width-1)-1] u[i] = uLocal; boolean s = true; if (uLocal < 0) { s = false; uLocal = (byte)-uLocal; } // uLocal is now >= 0 if (s) { r0 = r0.subtract(alpha[uLocal].u); r1 = r1.subtract(alpha[uLocal].v); } else { r0 = r0.add(alpha[uLocal].u); r1 = r1.add(alpha[uLocal].v); } } else { u[i] = 0; } BigInteger t = r0; if (mu == 1) { r0 = r1.add(r0.shiftRight(1)); } else { // mu == -1 r0 = r1.subtract(r0.shiftRight(1)); } r1 = t.shiftRight(1).negate(); i++; } return u; } /** * Does the precomputation for WTNAF multiplication. * @param p The ECPoint for which to do the precomputation. * @param a The parameter a of the elliptic curve. * @return The precomputation array for p. */ public static ECPoint.F2m[] getPreComp(ECPoint.F2m p, byte a) { ECPoint.F2m[] pu; pu = new ECPoint.F2m[16]; pu[1] = p; byte[][] alphaTnaf; if (a == 0) { alphaTnaf = Tnaf.alpha0Tnaf; } else { // a == 1 alphaTnaf = Tnaf.alpha1Tnaf; } int precompLen = alphaTnaf.length; for (int i = 3; i < precompLen; i = i + 2) { pu[i] = Tnaf.multiplyFromTnaf(p, alphaTnaf[i]); } return pu; } } bouncycastle-1.49.orig/src/org/bouncycastle/math/ec/WTauNafPreCompInfo.java0000644000175000017500000000236210675113137026303 0ustar ebourgebourgpackage org.bouncycastle.math.ec; /** * Class holding precomputation data for the WTNAF (Window * τ-adic Non-Adjacent Form) algorithm. */ class WTauNafPreCompInfo implements PreCompInfo { /** * Array holding the precomputed ECPoint.F2ms used for the * WTNAF multiplication in * {@link org.bouncycastle.math.ec.multiplier.WTauNafMultiplier.multiply() * WTauNafMultiplier.multiply()}. */ private ECPoint.F2m[] preComp = null; /** * Constructor for WTauNafPreCompInfo * @param preComp Array holding the precomputed ECPoint.F2ms * used for the WTNAF multiplication in * {@link org.bouncycastle.math.ec.multiplier.WTauNafMultiplier.multiply() * WTauNafMultiplier.multiply()}. */ WTauNafPreCompInfo(ECPoint.F2m[] preComp) { this.preComp = preComp; } /** * @return the array holding the precomputed ECPoint.F2ms * used for the WTNAF multiplication in * {@link org.bouncycastle.math.ec.multiplier.WTauNafMultiplier.multiply() * WTauNafMultiplier.multiply()}. */ protected ECPoint.F2m[] getPreComp() { return preComp; } } bouncycastle-1.49.orig/src/org/bouncycastle/math/ec/ECCurve.java0000644000175000017500000004642112151551722024171 0ustar ebourgebourgpackage org.bouncycastle.math.ec; import java.math.BigInteger; import java.util.Random; /** * base class for an elliptic curve */ public abstract class ECCurve { ECFieldElement a, b; public abstract int getFieldSize(); public abstract ECFieldElement fromBigInteger(BigInteger x); public abstract ECPoint createPoint(BigInteger x, BigInteger y, boolean withCompression); public abstract ECPoint getInfinity(); public ECFieldElement getA() { return a; } public ECFieldElement getB() { return b; } protected abstract ECPoint decompressPoint(int yTilde, BigInteger X1); /** * Decode a point on this curve from its ASN.1 encoding. The different * encodings are taken account of, including point compression for * Fp (X9.62 s 4.2.1 pg 17). * @return The decoded point. */ public ECPoint decodePoint(byte[] encoded) { ECPoint p = null; int expectedLength = (getFieldSize() + 7) / 8; switch (encoded[0]) { case 0x00: // infinity { if (encoded.length != 1) { throw new IllegalArgumentException("Incorrect length for infinity encoding"); } p = getInfinity(); break; } case 0x02: // compressed case 0x03: // compressed { if (encoded.length != (expectedLength + 1)) { throw new IllegalArgumentException("Incorrect length for compressed encoding"); } int yTilde = encoded[0] & 1; BigInteger X1 = fromArray(encoded, 1, expectedLength); p = decompressPoint(yTilde, X1); break; } case 0x04: // uncompressed case 0x06: // hybrid case 0x07: // hybrid { if (encoded.length != (2 * expectedLength + 1)) { throw new IllegalArgumentException("Incorrect length for uncompressed/hybrid encoding"); } BigInteger X1 = fromArray(encoded, 1, expectedLength); BigInteger Y1 = fromArray(encoded, 1 + expectedLength, expectedLength); p = createPoint(X1, Y1, false); break; } default: throw new IllegalArgumentException("Invalid point encoding 0x" + Integer.toString(encoded[0], 16)); } return p; } private static BigInteger fromArray(byte[] buf, int off, int length) { byte[] mag = new byte[length]; System.arraycopy(buf, off, mag, 0, length); return new BigInteger(1, mag); } /** * Elliptic curve over Fp */ public static class Fp extends ECCurve { BigInteger q; ECPoint.Fp infinity; public Fp(BigInteger q, BigInteger a, BigInteger b) { this.q = q; this.a = fromBigInteger(a); this.b = fromBigInteger(b); this.infinity = new ECPoint.Fp(this, null, null); } public BigInteger getQ() { return q; } public int getFieldSize() { return q.bitLength(); } public ECFieldElement fromBigInteger(BigInteger x) { return new ECFieldElement.Fp(this.q, x); } public ECPoint createPoint(BigInteger x, BigInteger y, boolean withCompression) { return new ECPoint.Fp(this, fromBigInteger(x), fromBigInteger(y), withCompression); } protected ECPoint decompressPoint(int yTilde, BigInteger X1) { ECFieldElement x = fromBigInteger(X1); ECFieldElement alpha = x.multiply(x.square().add(a)).add(b); ECFieldElement beta = alpha.sqrt(); // // if we can't find a sqrt we haven't got a point on the // curve - run! // if (beta == null) { throw new RuntimeException("Invalid point compression"); } BigInteger betaValue = beta.toBigInteger(); int bit0 = betaValue.testBit(0) ? 1 : 0; if (bit0 != yTilde) { // Use the other root beta = fromBigInteger(q.subtract(betaValue)); } return new ECPoint.Fp(this, x, beta, true); } public ECPoint getInfinity() { return infinity; } public boolean equals( Object anObject) { if (anObject == this) { return true; } if (!(anObject instanceof ECCurve.Fp)) { return false; } ECCurve.Fp other = (ECCurve.Fp) anObject; return this.q.equals(other.q) && a.equals(other.a) && b.equals(other.b); } public int hashCode() { return a.hashCode() ^ b.hashCode() ^ q.hashCode(); } } /** * Elliptic curves over F2m. The Weierstrass equation is given by * y2 + xy = x3 + ax2 + b. */ public static class F2m extends ECCurve { /** * The exponent m of F2m. */ private int m; // can't be final - JDK 1.1 /** * TPB: The integer k where xm + * xk + 1 represents the reduction polynomial * f(z).
    * PPB: The integer k1 where xm + * xk3 + xk2 + xk1 + 1 * represents the reduction polynomial f(z).
    */ private int k1; // can't be final - JDK 1.1 /** * TPB: Always set to 0
    * PPB: The integer k2 where xm + * xk3 + xk2 + xk1 + 1 * represents the reduction polynomial f(z).
    */ private int k2; // can't be final - JDK 1.1 /** * TPB: Always set to 0
    * PPB: The integer k3 where xm + * xk3 + xk2 + xk1 + 1 * represents the reduction polynomial f(z).
    */ private int k3; // can't be final - JDK 1.1 /** * The order of the base point of the curve. */ private BigInteger n; // can't be final - JDK 1.1 /** * The cofactor of the curve. */ private BigInteger h; // can't be final - JDK 1.1 /** * The point at infinity on this curve. */ private ECPoint.F2m infinity; // can't be final - JDK 1.1 /** * The parameter μ of the elliptic curve if this is * a Koblitz curve. */ private byte mu = 0; /** * The auxiliary values s0 and * s1 used for partial modular reduction for * Koblitz curves. */ private BigInteger[] si = null; /** * Constructor for Trinomial Polynomial Basis (TPB). * @param m The exponent m of * F2m. * @param k The integer k where xm + * xk + 1 represents the reduction * polynomial f(z). * @param a The coefficient a in the Weierstrass equation * for non-supersingular elliptic curves over * F2m. * @param b The coefficient b in the Weierstrass equation * for non-supersingular elliptic curves over * F2m. */ public F2m( int m, int k, BigInteger a, BigInteger b) { this(m, k, 0, 0, a, b, null, null); } /** * Constructor for Trinomial Polynomial Basis (TPB). * @param m The exponent m of * F2m. * @param k The integer k where xm + * xk + 1 represents the reduction * polynomial f(z). * @param a The coefficient a in the Weierstrass equation * for non-supersingular elliptic curves over * F2m. * @param b The coefficient b in the Weierstrass equation * for non-supersingular elliptic curves over * F2m. * @param n The order of the main subgroup of the elliptic curve. * @param h The cofactor of the elliptic curve, i.e. * #Ea(F2m) = h * n. */ public F2m( int m, int k, BigInteger a, BigInteger b, BigInteger n, BigInteger h) { this(m, k, 0, 0, a, b, n, h); } /** * Constructor for Pentanomial Polynomial Basis (PPB). * @param m The exponent m of * F2m. * @param k1 The integer k1 where xm + * xk3 + xk2 + xk1 + 1 * represents the reduction polynomial f(z). * @param k2 The integer k2 where xm + * xk3 + xk2 + xk1 + 1 * represents the reduction polynomial f(z). * @param k3 The integer k3 where xm + * xk3 + xk2 + xk1 + 1 * represents the reduction polynomial f(z). * @param a The coefficient a in the Weierstrass equation * for non-supersingular elliptic curves over * F2m. * @param b The coefficient b in the Weierstrass equation * for non-supersingular elliptic curves over * F2m. */ public F2m( int m, int k1, int k2, int k3, BigInteger a, BigInteger b) { this(m, k1, k2, k3, a, b, null, null); } /** * Constructor for Pentanomial Polynomial Basis (PPB). * @param m The exponent m of * F2m. * @param k1 The integer k1 where xm + * xk3 + xk2 + xk1 + 1 * represents the reduction polynomial f(z). * @param k2 The integer k2 where xm + * xk3 + xk2 + xk1 + 1 * represents the reduction polynomial f(z). * @param k3 The integer k3 where xm + * xk3 + xk2 + xk1 + 1 * represents the reduction polynomial f(z). * @param a The coefficient a in the Weierstrass equation * for non-supersingular elliptic curves over * F2m. * @param b The coefficient b in the Weierstrass equation * for non-supersingular elliptic curves over * F2m. * @param n The order of the main subgroup of the elliptic curve. * @param h The cofactor of the elliptic curve, i.e. * #Ea(F2m) = h * n. */ public F2m( int m, int k1, int k2, int k3, BigInteger a, BigInteger b, BigInteger n, BigInteger h) { this.m = m; this.k1 = k1; this.k2 = k2; this.k3 = k3; this.n = n; this.h = h; if (k1 == 0) { throw new IllegalArgumentException("k1 must be > 0"); } if (k2 == 0) { if (k3 != 0) { throw new IllegalArgumentException("k3 must be 0 if k2 == 0"); } } else { if (k2 <= k1) { throw new IllegalArgumentException("k2 must be > k1"); } if (k3 <= k2) { throw new IllegalArgumentException("k3 must be > k2"); } } this.a = fromBigInteger(a); this.b = fromBigInteger(b); this.infinity = new ECPoint.F2m(this, null, null); } public int getFieldSize() { return m; } public ECFieldElement fromBigInteger(BigInteger x) { return new ECFieldElement.F2m(this.m, this.k1, this.k2, this.k3, x); } public ECPoint createPoint(BigInteger x, BigInteger y, boolean withCompression) { return new ECPoint.F2m(this, fromBigInteger(x), fromBigInteger(y), withCompression); } public ECPoint getInfinity() { return infinity; } /** * Returns true if this is a Koblitz curve (ABC curve). * @return true if this is a Koblitz curve (ABC curve), false otherwise */ public boolean isKoblitz() { return ((n != null) && (h != null) && ((a.toBigInteger().equals(ECConstants.ZERO)) || (a.toBigInteger().equals(ECConstants.ONE))) && (b.toBigInteger().equals(ECConstants.ONE))); } /** * Returns the parameter μ of the elliptic curve. * @return μ of the elliptic curve. * @throws IllegalArgumentException if the given ECCurve is not a * Koblitz curve. */ synchronized byte getMu() { if (mu == 0) { mu = Tnaf.getMu(this); } return mu; } /** * @return the auxiliary values s0 and * s1 used for partial modular reduction for * Koblitz curves. */ synchronized BigInteger[] getSi() { if (si == null) { si = Tnaf.getSi(this); } return si; } /** * Decompresses a compressed point P = (xp, yp) (X9.62 s 4.2.2). * * @param yTilde * ~yp, an indication bit for the decompression of yp. * @param X1 * The field element xp. * @return the decompressed point. */ protected ECPoint decompressPoint(int yTilde, BigInteger X1) { ECFieldElement xp = fromBigInteger(X1); ECFieldElement yp = null; if (xp.toBigInteger().equals(ECConstants.ZERO)) { yp = (ECFieldElement.F2m)b; for (int i = 0; i < m - 1; i++) { yp = yp.square(); } } else { ECFieldElement beta = xp.add(a).add(b.multiply(xp.square().invert())); ECFieldElement z = solveQuadradicEquation(beta); if (z == null) { throw new IllegalArgumentException("Invalid point compression"); } int zBit = z.toBigInteger().testBit(0) ? 1 : 0; if (zBit != yTilde) { z = z.add(fromBigInteger(ECConstants.ONE)); } yp = xp.multiply(z); } return new ECPoint.F2m(this, xp, yp, true); } /** * Solves a quadratic equation z2 + z = beta(X9.62 * D.1.6) The other solution is z + 1. * * @param beta * The value to solve the qradratic equation for. * @return the solution for z2 + z = beta or * null if no solution exists. */ private ECFieldElement solveQuadradicEquation(ECFieldElement beta) { ECFieldElement zeroElement = new ECFieldElement.F2m( this.m, this.k1, this.k2, this.k3, ECConstants.ZERO); if (beta.toBigInteger().equals(ECConstants.ZERO)) { return zeroElement; } ECFieldElement z = null; ECFieldElement gamma = zeroElement; Random rand = new Random(); do { ECFieldElement t = new ECFieldElement.F2m(this.m, this.k1, this.k2, this.k3, new BigInteger(m, rand)); z = zeroElement; ECFieldElement w = beta; for (int i = 1; i <= m - 1; i++) { ECFieldElement w2 = w.square(); z = z.square().add(w2.multiply(t)); w = w2.add(beta); } if (!w.toBigInteger().equals(ECConstants.ZERO)) { return null; } gamma = z.square().add(z); } while (gamma.toBigInteger().equals(ECConstants.ZERO)); return z; } public boolean equals( Object anObject) { if (anObject == this) { return true; } if (!(anObject instanceof ECCurve.F2m)) { return false; } ECCurve.F2m other = (ECCurve.F2m)anObject; return (this.m == other.m) && (this.k1 == other.k1) && (this.k2 == other.k2) && (this.k3 == other.k3) && a.equals(other.a) && b.equals(other.b); } public int hashCode() { return this.a.hashCode() ^ this.b.hashCode() ^ m ^ k1 ^ k2 ^ k3; } public int getM() { return m; } /** * Return true if curve uses a Trinomial basis. * * @return true if curve Trinomial, false otherwise. */ public boolean isTrinomial() { return k2 == 0 && k3 == 0; } public int getK1() { return k1; } public int getK2() { return k2; } public int getK3() { return k3; } public BigInteger getN() { return n; } public BigInteger getH() { return h; } } } bouncycastle-1.49.orig/src/org/bouncycastle/math/ec/ECPoint.java0000644000175000017500000004211112132366322024165 0ustar ebourgebourgpackage org.bouncycastle.math.ec; import java.math.BigInteger; import org.bouncycastle.asn1.x9.X9IntegerConverter; /** * base class for points on elliptic curves. */ public abstract class ECPoint { ECCurve curve; ECFieldElement x; ECFieldElement y; protected boolean withCompression; protected ECMultiplier multiplier = null; protected PreCompInfo preCompInfo = null; private static X9IntegerConverter converter = new X9IntegerConverter(); protected ECPoint(ECCurve curve, ECFieldElement x, ECFieldElement y) { this.curve = curve; this.x = x; this.y = y; } public ECCurve getCurve() { return curve; } public ECFieldElement getX() { return x; } public ECFieldElement getY() { return y; } public boolean isInfinity() { return x == null && y == null; } public boolean isCompressed() { return withCompression; } public boolean equals( Object other) { if (other == this) { return true; } if (!(other instanceof ECPoint)) { return false; } ECPoint o = (ECPoint)other; if (this.isInfinity()) { return o.isInfinity(); } return x.equals(o.x) && y.equals(o.y); } public int hashCode() { if (this.isInfinity()) { return 0; } return x.hashCode() ^ y.hashCode(); } // /** // * Mainly for testing. Explicitly set the ECMultiplier. // * @param multiplier The ECMultiplier to be used to multiply // * this ECPoint. // */ // public void setECMultiplier(ECMultiplier multiplier) // { // this.multiplier = multiplier; // } /** * Sets the PreCompInfo. Used by ECMultipliers * to save the precomputation for this ECPoint to store the * precomputation result for use by subsequent multiplication. * @param preCompInfo The values precomputed by the * ECMultiplier. */ void setPreCompInfo(PreCompInfo preCompInfo) { this.preCompInfo = preCompInfo; } public byte[] getEncoded() { return getEncoded(withCompression); } public abstract byte[] getEncoded(boolean compressed); public abstract ECPoint add(ECPoint b); public abstract ECPoint subtract(ECPoint b); public abstract ECPoint negate(); public abstract ECPoint twice(); /** * Sets the default ECMultiplier, unless already set. */ synchronized void assertECMultiplier() { if (this.multiplier == null) { this.multiplier = new FpNafMultiplier(); } } /** * Multiplies this ECPoint by the given number. * @param k The multiplicator. * @return k * this. */ public ECPoint multiply(BigInteger k) { if (k.signum() < 0) { throw new IllegalArgumentException("The multiplicator cannot be negative"); } if (this.isInfinity()) { return this; } if (k.signum() == 0) { return this.curve.getInfinity(); } assertECMultiplier(); return this.multiplier.multiply(this, k, preCompInfo); } /** * Elliptic curve points over Fp */ public static class Fp extends ECPoint { /** * Create a point which encodes with point compression. * * @param curve the curve to use * @param x affine x co-ordinate * @param y affine y co-ordinate */ public Fp(ECCurve curve, ECFieldElement x, ECFieldElement y) { this(curve, x, y, false); } /** * Create a point that encodes with or without point compresion. * * @param curve the curve to use * @param x affine x co-ordinate * @param y affine y co-ordinate * @param withCompression if true encode with point compression */ public Fp(ECCurve curve, ECFieldElement x, ECFieldElement y, boolean withCompression) { super(curve, x, y); if ((x != null && y == null) || (x == null && y != null)) { throw new IllegalArgumentException("Exactly one of the field elements is null"); } this.withCompression = withCompression; } /** * return the field element encoded with point compression. (S 4.3.6) */ public byte[] getEncoded(boolean compressed) { if (this.isInfinity()) { return new byte[1]; } int qLength = converter.getByteLength(x); if (compressed) { byte PC; if (this.getY().toBigInteger().testBit(0)) { PC = 0x03; } else { PC = 0x02; } byte[] X = converter.integerToBytes(this.getX().toBigInteger(), qLength); byte[] PO = new byte[X.length + 1]; PO[0] = PC; System.arraycopy(X, 0, PO, 1, X.length); return PO; } else { byte[] X = converter.integerToBytes(this.getX().toBigInteger(), qLength); byte[] Y = converter.integerToBytes(this.getY().toBigInteger(), qLength); byte[] PO = new byte[X.length + Y.length + 1]; PO[0] = 0x04; System.arraycopy(X, 0, PO, 1, X.length); System.arraycopy(Y, 0, PO, X.length + 1, Y.length); return PO; } } // B.3 pg 62 public ECPoint add(ECPoint b) { if (this.isInfinity()) { return b; } if (b.isInfinity()) { return this; } // Check if b = this or b = -this if (this.x.equals(b.x)) { if (this.y.equals(b.y)) { // this = b, i.e. this must be doubled return this.twice(); } // this = -b, i.e. the result is the point at infinity return this.curve.getInfinity(); } ECFieldElement gamma = b.y.subtract(this.y).divide(b.x.subtract(this.x)); ECFieldElement x3 = gamma.square().subtract(this.x).subtract(b.x); ECFieldElement y3 = gamma.multiply(this.x.subtract(x3)).subtract(this.y); return new ECPoint.Fp(curve, x3, y3, withCompression); } // B.3 pg 62 public ECPoint twice() { if (this.isInfinity()) { // Twice identity element (point at infinity) is identity return this; } if (this.y.toBigInteger().signum() == 0) { // if y1 == 0, then (x1, y1) == (x1, -y1) // and hence this = -this and thus 2(x1, y1) == infinity return this.curve.getInfinity(); } ECFieldElement TWO = this.curve.fromBigInteger(BigInteger.valueOf(2)); ECFieldElement THREE = this.curve.fromBigInteger(BigInteger.valueOf(3)); ECFieldElement gamma = this.x.square().multiply(THREE).add(curve.a).divide(y.multiply(TWO)); ECFieldElement x3 = gamma.square().subtract(this.x.multiply(TWO)); ECFieldElement y3 = gamma.multiply(this.x.subtract(x3)).subtract(this.y); return new ECPoint.Fp(curve, x3, y3, this.withCompression); } // D.3.2 pg 102 (see Note:) public ECPoint subtract(ECPoint b) { if (b.isInfinity()) { return this; } // Add -b return add(b.negate()); } public ECPoint negate() { return new ECPoint.Fp(curve, this.x, this.y.negate(), this.withCompression); } /** * Sets the default ECMultiplier, unless already set. */ synchronized void assertECMultiplier() { if (this.multiplier == null) { this.multiplier = new WNafMultiplier(); } } } /** * Elliptic curve points over F2m */ public static class F2m extends ECPoint { /** * @param curve base curve * @param x x point * @param y y point */ public F2m(ECCurve curve, ECFieldElement x, ECFieldElement y) { this(curve, x, y, false); } /** * @param curve base curve * @param x x point * @param y y point * @param withCompression true if encode with point compression. */ public F2m(ECCurve curve, ECFieldElement x, ECFieldElement y, boolean withCompression) { super(curve, x, y); if ((x != null && y == null) || (x == null && y != null)) { throw new IllegalArgumentException("Exactly one of the field elements is null"); } if (x != null) { // Check if x and y are elements of the same field ECFieldElement.F2m.checkFieldElements(this.x, this.y); // Check if x and a are elements of the same field if (curve != null) { ECFieldElement.F2m.checkFieldElements(this.x, this.curve.getA()); } } this.withCompression = withCompression; } /* (non-Javadoc) * @see org.bouncycastle.math.ec.ECPoint#getEncoded() */ public byte[] getEncoded(boolean compressed) { if (this.isInfinity()) { return new byte[1]; } int byteCount = converter.getByteLength(this.x); byte[] X = converter.integerToBytes(this.getX().toBigInteger(), byteCount); byte[] PO; if (compressed) { // See X9.62 4.3.6 and 4.2.2 PO = new byte[byteCount + 1]; PO[0] = 0x02; // X9.62 4.2.2 and 4.3.6: // if x = 0 then ypTilde := 0, else ypTilde is the rightmost // bit of y * x^(-1) // if ypTilde = 0, then PC := 02, else PC := 03 // Note: PC === PO[0] if (!(this.getX().toBigInteger().equals(ECConstants.ZERO))) { if (this.getY().multiply(this.getX().invert()) .toBigInteger().testBit(0)) { // ypTilde = 1, hence PC = 03 PO[0] = 0x03; } } System.arraycopy(X, 0, PO, 1, byteCount); } else { byte[] Y = converter.integerToBytes(this.getY().toBigInteger(), byteCount); PO = new byte[byteCount + byteCount + 1]; PO[0] = 0x04; System.arraycopy(X, 0, PO, 1, byteCount); System.arraycopy(Y, 0, PO, byteCount + 1, byteCount); } return PO; } /** * Check, if two ECPoints can be added or subtracted. * @param a The first ECPoint to check. * @param b The second ECPoint to check. * @throws IllegalArgumentException if a and b * cannot be added. */ private static void checkPoints(ECPoint a, ECPoint b) { // Check, if points are on the same curve if (!(a.curve.equals(b.curve))) { throw new IllegalArgumentException("Only points on the same " + "curve can be added or subtracted"); } // ECFieldElement.F2m.checkFieldElements(a.x, b.x); } /* (non-Javadoc) * @see org.bouncycastle.math.ec.ECPoint#add(org.bouncycastle.math.ec.ECPoint) */ public ECPoint add(ECPoint b) { checkPoints(this, b); return addSimple((ECPoint.F2m)b); } /** * Adds another ECPoints.F2m to this without * checking if both points are on the same curve. Used by multiplication * algorithms, because there all points are a multiple of the same point * and hence the checks can be omitted. * @param b The other ECPoints.F2m to add to * this. * @return this + b */ public ECPoint.F2m addSimple(ECPoint.F2m b) { ECPoint.F2m other = b; if (this.isInfinity()) { return other; } if (other.isInfinity()) { return this; } ECFieldElement.F2m x2 = (ECFieldElement.F2m)other.getX(); ECFieldElement.F2m y2 = (ECFieldElement.F2m)other.getY(); // Check if other = this or other = -this if (this.x.equals(x2)) { if (this.y.equals(y2)) { // this = other, i.e. this must be doubled return (ECPoint.F2m)this.twice(); } // this = -other, i.e. the result is the point at infinity return (ECPoint.F2m)this.curve.getInfinity(); } ECFieldElement.F2m lambda = (ECFieldElement.F2m)(this.y.add(y2)).divide(this.x.add(x2)); ECFieldElement.F2m x3 = (ECFieldElement.F2m)lambda.square().add(lambda).add(this.x).add(x2).add(this.curve.getA()); ECFieldElement.F2m y3 = (ECFieldElement.F2m)lambda.multiply(this.x.add(x3)).add(x3).add(this.y); return new ECPoint.F2m(curve, x3, y3, withCompression); } /* (non-Javadoc) * @see org.bouncycastle.math.ec.ECPoint#subtract(org.bouncycastle.math.ec.ECPoint) */ public ECPoint subtract(ECPoint b) { checkPoints(this, b); return subtractSimple((ECPoint.F2m)b); } /** * Subtracts another ECPoints.F2m from this * without checking if both points are on the same curve. Used by * multiplication algorithms, because there all points are a multiple * of the same point and hence the checks can be omitted. * @param b The other ECPoints.F2m to subtract from * this. * @return this - b */ public ECPoint.F2m subtractSimple(ECPoint.F2m b) { if (b.isInfinity()) { return this; } // Add -b return addSimple((ECPoint.F2m)b.negate()); } /* (non-Javadoc) * @see org.bouncycastle.math.ec.ECPoint#twice() */ public ECPoint twice() { if (this.isInfinity()) { // Twice identity element (point at infinity) is identity return this; } if (this.x.toBigInteger().signum() == 0) { // if x1 == 0, then (x1, y1) == (x1, x1 + y1) // and hence this = -this and thus 2(x1, y1) == infinity return this.curve.getInfinity(); } ECFieldElement.F2m lambda = (ECFieldElement.F2m)this.x.add(this.y.divide(this.x)); ECFieldElement.F2m x3 = (ECFieldElement.F2m)lambda.square().add(lambda). add(this.curve.getA()); ECFieldElement ONE = this.curve.fromBigInteger(ECConstants.ONE); ECFieldElement.F2m y3 = (ECFieldElement.F2m)this.x.square().add( x3.multiply(lambda.add(ONE))); return new ECPoint.F2m(this.curve, x3, y3, withCompression); } public ECPoint negate() { return new ECPoint.F2m(curve, this.getX(), this.getY().add(this.getX()), withCompression); } /** * Sets the appropriate ECMultiplier, unless already set. */ synchronized void assertECMultiplier() { if (this.multiplier == null) { if (((ECCurve.F2m)this.curve).isKoblitz()) { this.multiplier = new WTauNafMultiplier(); } else { this.multiplier = new WNafMultiplier(); } } } } } bouncycastle-1.49.orig/src/org/bouncycastle/math/ec/ECAlgorithms.java0000644000175000017500000000472311357214332025215 0ustar ebourgebourgpackage org.bouncycastle.math.ec; import java.math.BigInteger; public class ECAlgorithms { public static ECPoint sumOfTwoMultiplies(ECPoint P, BigInteger a, ECPoint Q, BigInteger b) { ECCurve c = P.getCurve(); if (!c.equals(Q.getCurve())) { throw new IllegalArgumentException("P and Q must be on same curve"); } // Point multiplication for Koblitz curves (using WTNAF) beats Shamir's trick if (c instanceof ECCurve.F2m) { ECCurve.F2m f2mCurve = (ECCurve.F2m)c; if (f2mCurve.isKoblitz()) { return P.multiply(a).add(Q.multiply(b)); } } return implShamirsTrick(P, a, Q, b); } /* * "Shamir's Trick", originally due to E. G. Straus * (Addition chains of vectors. American Mathematical Monthly, * 71(7):806-808, Aug./Sept. 1964) *

         * Input: The points P, Q, scalar k = (km?, ... , k1, k0)
         * and scalar l = (lm?, ... , l1, l0).
         * Output: R = k * P + l * Q.
         * 1: Z <- P + Q
         * 2: R <- O
         * 3: for i from m-1 down to 0 do
         * 4:        R <- R + R        {point doubling}
         * 5:        if (ki = 1) and (li = 0) then R <- R + P end if
         * 6:        if (ki = 0) and (li = 1) then R <- R + Q end if
         * 7:        if (ki = 1) and (li = 1) then R <- R + Z end if
         * 8: end for
         * 9: return R
         * 
    */ public static ECPoint shamirsTrick(ECPoint P, BigInteger k, ECPoint Q, BigInteger l) { if (!P.getCurve().equals(Q.getCurve())) { throw new IllegalArgumentException("P and Q must be on same curve"); } return implShamirsTrick(P, k, Q, l); } private static ECPoint implShamirsTrick(ECPoint P, BigInteger k, ECPoint Q, BigInteger l) { int m = Math.max(k.bitLength(), l.bitLength()); ECPoint Z = P.add(Q); ECPoint R = P.getCurve().getInfinity(); for (int i = m - 1; i >= 0; --i) { R = R.twice(); if (k.testBit(i)) { if (l.testBit(i)) { R = R.add(Z); } else { R = R.add(P); } } else { if (l.testBit(i)) { R = R.add(Q); } } } return R; } } bouncycastle-1.49.orig/src/org/bouncycastle/math/ec/package.html0000644000175000017500000000012110262753175024305 0ustar ebourgebourg Math support for Elliptic Curve. bouncycastle-1.49.orig/src/org/bouncycastle/math/ec/ECFieldElement.java0000644000175000017500000011555711274173337025460 0ustar ebourgebourgpackage org.bouncycastle.math.ec; import java.math.BigInteger; import java.util.Random; public abstract class ECFieldElement implements ECConstants { public abstract BigInteger toBigInteger(); public abstract String getFieldName(); public abstract int getFieldSize(); public abstract ECFieldElement add(ECFieldElement b); public abstract ECFieldElement subtract(ECFieldElement b); public abstract ECFieldElement multiply(ECFieldElement b); public abstract ECFieldElement divide(ECFieldElement b); public abstract ECFieldElement negate(); public abstract ECFieldElement square(); public abstract ECFieldElement invert(); public abstract ECFieldElement sqrt(); public String toString() { return this.toBigInteger().toString(2); } public static class Fp extends ECFieldElement { BigInteger x; BigInteger q; public Fp(BigInteger q, BigInteger x) { this.x = x; if (x.compareTo(q) >= 0) { throw new IllegalArgumentException("x value too large in field element"); } this.q = q; } public BigInteger toBigInteger() { return x; } /** * return the field name for this field. * * @return the string "Fp". */ public String getFieldName() { return "Fp"; } public int getFieldSize() { return q.bitLength(); } public BigInteger getQ() { return q; } public ECFieldElement add(ECFieldElement b) { return new Fp(q, x.add(b.toBigInteger()).mod(q)); } public ECFieldElement subtract(ECFieldElement b) { return new Fp(q, x.subtract(b.toBigInteger()).mod(q)); } public ECFieldElement multiply(ECFieldElement b) { return new Fp(q, x.multiply(b.toBigInteger()).mod(q)); } public ECFieldElement divide(ECFieldElement b) { return new Fp(q, x.multiply(b.toBigInteger().modInverse(q)).mod(q)); } public ECFieldElement negate() { return new Fp(q, x.negate().mod(q)); } public ECFieldElement square() { return new Fp(q, x.multiply(x).mod(q)); } public ECFieldElement invert() { return new Fp(q, x.modInverse(q)); } // D.1.4 91 /** * return a sqrt root - the routine verifies that the calculation * returns the right value - if none exists it returns null. */ public ECFieldElement sqrt() { if (!q.testBit(0)) { throw new RuntimeException("not done yet"); } // note: even though this class implements ECConstants don't be tempted to // remove the explicit declaration, some J2ME environments don't cope. // p mod 4 == 3 if (q.testBit(1)) { // z = g^(u+1) + p, p = 4u + 3 ECFieldElement z = new Fp(q, x.modPow(q.shiftRight(2).add(ECConstants.ONE), q)); return z.square().equals(this) ? z : null; } // p mod 4 == 1 BigInteger qMinusOne = q.subtract(ECConstants.ONE); BigInteger legendreExponent = qMinusOne.shiftRight(1); if (!(x.modPow(legendreExponent, q).equals(ECConstants.ONE))) { return null; } BigInteger u = qMinusOne.shiftRight(2); BigInteger k = u.shiftLeft(1).add(ECConstants.ONE); BigInteger Q = this.x; BigInteger fourQ = Q.shiftLeft(2).mod(q); BigInteger U, V; Random rand = new Random(); do { BigInteger P; do { P = new BigInteger(q.bitLength(), rand); } while (P.compareTo(q) >= 0 || !(P.multiply(P).subtract(fourQ).modPow(legendreExponent, q).equals(qMinusOne))); BigInteger[] result = lucasSequence(q, P, Q, k); U = result[0]; V = result[1]; if (V.multiply(V).mod(q).equals(fourQ)) { // Integer division by 2, mod q if (V.testBit(0)) { V = V.add(q); } V = V.shiftRight(1); //assert V.multiply(V).mod(q).equals(x); return new ECFieldElement.Fp(q, V); } } while (U.equals(ECConstants.ONE) || U.equals(qMinusOne)); return null; // BigInteger qMinusOne = q.subtract(ECConstants.ONE); // BigInteger legendreExponent = qMinusOne.shiftRight(1); //divide(ECConstants.TWO); // if (!(x.modPow(legendreExponent, q).equals(ECConstants.ONE))) // { // return null; // } // // Random rand = new Random(); // BigInteger fourX = x.shiftLeft(2); // // BigInteger r; // do // { // r = new BigInteger(q.bitLength(), rand); // } // while (r.compareTo(q) >= 0 // || !(r.multiply(r).subtract(fourX).modPow(legendreExponent, q).equals(qMinusOne))); // // BigInteger n1 = qMinusOne.shiftRight(2); //.divide(ECConstants.FOUR); // BigInteger n2 = n1.add(ECConstants.ONE); //q.add(ECConstants.THREE).divide(ECConstants.FOUR); // // BigInteger wOne = WOne(r, x, q); // BigInteger wSum = W(n1, wOne, q).add(W(n2, wOne, q)).mod(q); // BigInteger twoR = r.shiftLeft(1); //ECConstants.TWO.multiply(r); // // BigInteger root = twoR.modPow(q.subtract(ECConstants.TWO), q) // .multiply(x).mod(q) // .multiply(wSum).mod(q); // // return new Fp(q, root); } // private static BigInteger W(BigInteger n, BigInteger wOne, BigInteger p) // { // if (n.equals(ECConstants.ONE)) // { // return wOne; // } // boolean isEven = !n.testBit(0); // n = n.shiftRight(1);//divide(ECConstants.TWO); // if (isEven) // { // BigInteger w = W(n, wOne, p); // return w.multiply(w).subtract(ECConstants.TWO).mod(p); // } // BigInteger w1 = W(n.add(ECConstants.ONE), wOne, p); // BigInteger w2 = W(n, wOne, p); // return w1.multiply(w2).subtract(wOne).mod(p); // } // // private BigInteger WOne(BigInteger r, BigInteger x, BigInteger p) // { // return r.multiply(r).multiply(x.modPow(q.subtract(ECConstants.TWO), q)).subtract(ECConstants.TWO).mod(p); // } private static BigInteger[] lucasSequence( BigInteger p, BigInteger P, BigInteger Q, BigInteger k) { int n = k.bitLength(); int s = k.getLowestSetBit(); BigInteger Uh = ECConstants.ONE; BigInteger Vl = ECConstants.TWO; BigInteger Vh = P; BigInteger Ql = ECConstants.ONE; BigInteger Qh = ECConstants.ONE; for (int j = n - 1; j >= s + 1; --j) { Ql = Ql.multiply(Qh).mod(p); if (k.testBit(j)) { Qh = Ql.multiply(Q).mod(p); Uh = Uh.multiply(Vh).mod(p); Vl = Vh.multiply(Vl).subtract(P.multiply(Ql)).mod(p); Vh = Vh.multiply(Vh).subtract(Qh.shiftLeft(1)).mod(p); } else { Qh = Ql; Uh = Uh.multiply(Vl).subtract(Ql).mod(p); Vh = Vh.multiply(Vl).subtract(P.multiply(Ql)).mod(p); Vl = Vl.multiply(Vl).subtract(Ql.shiftLeft(1)).mod(p); } } Ql = Ql.multiply(Qh).mod(p); Qh = Ql.multiply(Q).mod(p); Uh = Uh.multiply(Vl).subtract(Ql).mod(p); Vl = Vh.multiply(Vl).subtract(P.multiply(Ql)).mod(p); Ql = Ql.multiply(Qh).mod(p); for (int j = 1; j <= s; ++j) { Uh = Uh.multiply(Vl).mod(p); Vl = Vl.multiply(Vl).subtract(Ql.shiftLeft(1)).mod(p); Ql = Ql.multiply(Ql).mod(p); } return new BigInteger[]{ Uh, Vl }; } public boolean equals(Object other) { if (other == this) { return true; } if (!(other instanceof ECFieldElement.Fp)) { return false; } ECFieldElement.Fp o = (ECFieldElement.Fp)other; return q.equals(o.q) && x.equals(o.x); } public int hashCode() { return q.hashCode() ^ x.hashCode(); } } // /** // * Class representing the Elements of the finite field // * F2m in polynomial basis (PB) // * representation. Both trinomial (TPB) and pentanomial (PPB) polynomial // * basis representations are supported. Gaussian normal basis (GNB) // * representation is not supported. // */ // public static class F2m extends ECFieldElement // { // BigInteger x; // // /** // * Indicates gaussian normal basis representation (GNB). Number chosen // * according to X9.62. GNB is not implemented at present. // */ // public static final int GNB = 1; // // /** // * Indicates trinomial basis representation (TPB). Number chosen // * according to X9.62. // */ // public static final int TPB = 2; // // /** // * Indicates pentanomial basis representation (PPB). Number chosen // * according to X9.62. // */ // public static final int PPB = 3; // // /** // * TPB or PPB. // */ // private int representation; // // /** // * The exponent m of F2m. // */ // private int m; // // /** // * TPB: The integer k where xm + // * xk + 1 represents the reduction polynomial // * f(z).
    // * PPB: The integer k1 where xm + // * xk3 + xk2 + xk1 + 1 // * represents the reduction polynomial f(z).
    // */ // private int k1; // // /** // * TPB: Always set to 0
    // * PPB: The integer k2 where xm + // * xk3 + xk2 + xk1 + 1 // * represents the reduction polynomial f(z).
    // */ // private int k2; // // /** // * TPB: Always set to 0
    // * PPB: The integer k3 where xm + // * xk3 + xk2 + xk1 + 1 // * represents the reduction polynomial f(z).
    // */ // private int k3; // // /** // * Constructor for PPB. // * @param m The exponent m of // * F2m. // * @param k1 The integer k1 where xm + // * xk3 + xk2 + xk1 + 1 // * represents the reduction polynomial f(z). // * @param k2 The integer k2 where xm + // * xk3 + xk2 + xk1 + 1 // * represents the reduction polynomial f(z). // * @param k3 The integer k3 where xm + // * xk3 + xk2 + xk1 + 1 // * represents the reduction polynomial f(z). // * @param x The BigInteger representing the value of the field element. // */ // public F2m( // int m, // int k1, // int k2, // int k3, // BigInteger x) // { //// super(x); // this.x = x; // // if ((k2 == 0) && (k3 == 0)) // { // this.representation = TPB; // } // else // { // if (k2 >= k3) // { // throw new IllegalArgumentException( // "k2 must be smaller than k3"); // } // if (k2 <= 0) // { // throw new IllegalArgumentException( // "k2 must be larger than 0"); // } // this.representation = PPB; // } // // if (x.signum() < 0) // { // throw new IllegalArgumentException("x value cannot be negative"); // } // // this.m = m; // this.k1 = k1; // this.k2 = k2; // this.k3 = k3; // } // // /** // * Constructor for TPB. // * @param m The exponent m of // * F2m. // * @param k The integer k where xm + // * xk + 1 represents the reduction // * polynomial f(z). // * @param x The BigInteger representing the value of the field element. // */ // public F2m(int m, int k, BigInteger x) // { // // Set k1 to k, and set k2 and k3 to 0 // this(m, k, 0, 0, x); // } // // public BigInteger toBigInteger() // { // return x; // } // // public String getFieldName() // { // return "F2m"; // } // // public int getFieldSize() // { // return m; // } // // /** // * Checks, if the ECFieldElements a and b // * are elements of the same field F2m // * (having the same representation). // * @param a field element. // * @param b field element to be compared. // * @throws IllegalArgumentException if a and b // * are not elements of the same field // * F2m (having the same // * representation). // */ // public static void checkFieldElements( // ECFieldElement a, // ECFieldElement b) // { // if ((!(a instanceof F2m)) || (!(b instanceof F2m))) // { // throw new IllegalArgumentException("Field elements are not " // + "both instances of ECFieldElement.F2m"); // } // // if ((a.toBigInteger().signum() < 0) || (b.toBigInteger().signum() < 0)) // { // throw new IllegalArgumentException( // "x value may not be negative"); // } // // ECFieldElement.F2m aF2m = (ECFieldElement.F2m)a; // ECFieldElement.F2m bF2m = (ECFieldElement.F2m)b; // // if ((aF2m.m != bF2m.m) || (aF2m.k1 != bF2m.k1) // || (aF2m.k2 != bF2m.k2) || (aF2m.k3 != bF2m.k3)) // { // throw new IllegalArgumentException("Field elements are not " // + "elements of the same field F2m"); // } // // if (aF2m.representation != bF2m.representation) // { // // Should never occur // throw new IllegalArgumentException( // "One of the field " // + "elements are not elements has incorrect representation"); // } // } // // /** // * Computes z * a(z) mod f(z), where f(z) is // * the reduction polynomial of this. // * @param a The polynomial a(z) to be multiplied by // * z mod f(z). // * @return z * a(z) mod f(z) // */ // private BigInteger multZModF(final BigInteger a) // { // // Left-shift of a(z) // BigInteger az = a.shiftLeft(1); // if (az.testBit(this.m)) // { // // If the coefficient of z^m in a(z) equals 1, reduction // // modulo f(z) is performed: Add f(z) to to a(z): // // Step 1: Unset mth coeffient of a(z) // az = az.clearBit(this.m); // // // Step 2: Add r(z) to a(z), where r(z) is defined as // // f(z) = z^m + r(z), and k1, k2, k3 are the positions of // // the non-zero coefficients in r(z) // az = az.flipBit(0); // az = az.flipBit(this.k1); // if (this.representation == PPB) // { // az = az.flipBit(this.k2); // az = az.flipBit(this.k3); // } // } // return az; // } // // public ECFieldElement add(final ECFieldElement b) // { // // No check performed here for performance reasons. Instead the // // elements involved are checked in ECPoint.F2m // // checkFieldElements(this, b); // if (b.toBigInteger().signum() == 0) // { // return this; // } // // return new F2m(this.m, this.k1, this.k2, this.k3, this.x.xor(b.toBigInteger())); // } // // public ECFieldElement subtract(final ECFieldElement b) // { // // Addition and subtraction are the same in F2m // return add(b); // } // // // public ECFieldElement multiply(final ECFieldElement b) // { // // Left-to-right shift-and-add field multiplication in F2m // // Input: Binary polynomials a(z) and b(z) of degree at most m-1 // // Output: c(z) = a(z) * b(z) mod f(z) // // // No check performed here for performance reasons. Instead the // // elements involved are checked in ECPoint.F2m // // checkFieldElements(this, b); // final BigInteger az = this.x; // BigInteger bz = b.toBigInteger(); // BigInteger cz; // // // Compute c(z) = a(z) * b(z) mod f(z) // if (az.testBit(0)) // { // cz = bz; // } // else // { // cz = ECConstants.ZERO; // } // // for (int i = 1; i < this.m; i++) // { // // b(z) := z * b(z) mod f(z) // bz = multZModF(bz); // // if (az.testBit(i)) // { // // If the coefficient of x^i in a(z) equals 1, b(z) is added // // to c(z) // cz = cz.xor(bz); // } // } // return new ECFieldElement.F2m(m, this.k1, this.k2, this.k3, cz); // } // // // public ECFieldElement divide(final ECFieldElement b) // { // // There may be more efficient implementations // ECFieldElement bInv = b.invert(); // return multiply(bInv); // } // // public ECFieldElement negate() // { // // -x == x holds for all x in F2m // return this; // } // // public ECFieldElement square() // { // // Naive implementation, can probably be speeded up using modular // // reduction // return multiply(this); // } // // public ECFieldElement invert() // { // // Inversion in F2m using the extended Euclidean algorithm // // Input: A nonzero polynomial a(z) of degree at most m-1 // // Output: a(z)^(-1) mod f(z) // // // u(z) := a(z) // BigInteger uz = this.x; // if (uz.signum() <= 0) // { // throw new ArithmeticException("x is zero or negative, " + // "inversion is impossible"); // } // // // v(z) := f(z) // BigInteger vz = ECConstants.ZERO.setBit(m); // vz = vz.setBit(0); // vz = vz.setBit(this.k1); // if (this.representation == PPB) // { // vz = vz.setBit(this.k2); // vz = vz.setBit(this.k3); // } // // // g1(z) := 1, g2(z) := 0 // BigInteger g1z = ECConstants.ONE; // BigInteger g2z = ECConstants.ZERO; // // // while u != 1 // while (!(uz.equals(ECConstants.ZERO))) // { // // j := deg(u(z)) - deg(v(z)) // int j = uz.bitLength() - vz.bitLength(); // // // If j < 0 then: u(z) <-> v(z), g1(z) <-> g2(z), j := -j // if (j < 0) // { // final BigInteger uzCopy = uz; // uz = vz; // vz = uzCopy; // // final BigInteger g1zCopy = g1z; // g1z = g2z; // g2z = g1zCopy; // // j = -j; // } // // // u(z) := u(z) + z^j * v(z) // // Note, that no reduction modulo f(z) is required, because // // deg(u(z) + z^j * v(z)) <= max(deg(u(z)), j + deg(v(z))) // // = max(deg(u(z)), deg(u(z)) - deg(v(z)) + deg(v(z)) // // = deg(u(z)) // uz = uz.xor(vz.shiftLeft(j)); // // // g1(z) := g1(z) + z^j * g2(z) // g1z = g1z.xor(g2z.shiftLeft(j)); //// if (g1z.bitLength() > this.m) { //// throw new ArithmeticException( //// "deg(g1z) >= m, g1z = " + g1z.toString(2)); //// } // } // return new ECFieldElement.F2m( // this.m, this.k1, this.k2, this.k3, g2z); // } // // public ECFieldElement sqrt() // { // throw new RuntimeException("Not implemented"); // } // // /** // * @return the representation of the field // * F2m, either of // * TPB (trinomial // * basis representation) or // * PPB (pentanomial // * basis representation). // */ // public int getRepresentation() // { // return this.representation; // } // // /** // * @return the degree m of the reduction polynomial // * f(z). // */ // public int getM() // { // return this.m; // } // // /** // * @return TPB: The integer k where xm + // * xk + 1 represents the reduction polynomial // * f(z).
    // * PPB: The integer k1 where xm + // * xk3 + xk2 + xk1 + 1 // * represents the reduction polynomial f(z).
    // */ // public int getK1() // { // return this.k1; // } // // /** // * @return TPB: Always returns 0
    // * PPB: The integer k2 where xm + // * xk3 + xk2 + xk1 + 1 // * represents the reduction polynomial f(z).
    // */ // public int getK2() // { // return this.k2; // } // // /** // * @return TPB: Always set to 0
    // * PPB: The integer k3 where xm + // * xk3 + xk2 + xk1 + 1 // * represents the reduction polynomial f(z).
    // */ // public int getK3() // { // return this.k3; // } // // public boolean equals(Object anObject) // { // if (anObject == this) // { // return true; // } // // if (!(anObject instanceof ECFieldElement.F2m)) // { // return false; // } // // ECFieldElement.F2m b = (ECFieldElement.F2m)anObject; // // return ((this.m == b.m) && (this.k1 == b.k1) && (this.k2 == b.k2) // && (this.k3 == b.k3) // && (this.representation == b.representation) // && (this.x.equals(b.x))); // } // // public int hashCode() // { // return x.hashCode() ^ m ^ k1 ^ k2 ^ k3; // } // } /** * Class representing the Elements of the finite field * F2m in polynomial basis (PB) * representation. Both trinomial (TPB) and pentanomial (PPB) polynomial * basis representations are supported. Gaussian normal basis (GNB) * representation is not supported. */ public static class F2m extends ECFieldElement { /** * Indicates gaussian normal basis representation (GNB). Number chosen * according to X9.62. GNB is not implemented at present. */ public static final int GNB = 1; /** * Indicates trinomial basis representation (TPB). Number chosen * according to X9.62. */ public static final int TPB = 2; /** * Indicates pentanomial basis representation (PPB). Number chosen * according to X9.62. */ public static final int PPB = 3; /** * TPB or PPB. */ private int representation; /** * The exponent m of F2m. */ private int m; /** * TPB: The integer k where xm + * xk + 1 represents the reduction polynomial * f(z).
    * PPB: The integer k1 where xm + * xk3 + xk2 + xk1 + 1 * represents the reduction polynomial f(z).
    */ private int k1; /** * TPB: Always set to 0
    * PPB: The integer k2 where xm + * xk3 + xk2 + xk1 + 1 * represents the reduction polynomial f(z).
    */ private int k2; /** * TPB: Always set to 0
    * PPB: The integer k3 where xm + * xk3 + xk2 + xk1 + 1 * represents the reduction polynomial f(z).
    */ private int k3; /** * The IntArray holding the bits. */ private IntArray x; /** * The number of ints required to hold m bits. */ private int t; /** * Constructor for PPB. * @param m The exponent m of * F2m. * @param k1 The integer k1 where xm + * xk3 + xk2 + xk1 + 1 * represents the reduction polynomial f(z). * @param k2 The integer k2 where xm + * xk3 + xk2 + xk1 + 1 * represents the reduction polynomial f(z). * @param k3 The integer k3 where xm + * xk3 + xk2 + xk1 + 1 * represents the reduction polynomial f(z). * @param x The BigInteger representing the value of the field element. */ public F2m( int m, int k1, int k2, int k3, BigInteger x) { // t = m / 32 rounded up to the next integer t = (m + 31) >> 5; this.x = new IntArray(x, t); if ((k2 == 0) && (k3 == 0)) { this.representation = TPB; } else { if (k2 >= k3) { throw new IllegalArgumentException( "k2 must be smaller than k3"); } if (k2 <= 0) { throw new IllegalArgumentException( "k2 must be larger than 0"); } this.representation = PPB; } if (x.signum() < 0) { throw new IllegalArgumentException("x value cannot be negative"); } this.m = m; this.k1 = k1; this.k2 = k2; this.k3 = k3; } /** * Constructor for TPB. * @param m The exponent m of * F2m. * @param k The integer k where xm + * xk + 1 represents the reduction * polynomial f(z). * @param x The BigInteger representing the value of the field element. */ public F2m(int m, int k, BigInteger x) { // Set k1 to k, and set k2 and k3 to 0 this(m, k, 0, 0, x); } private F2m(int m, int k1, int k2, int k3, IntArray x) { t = (m + 31) >> 5; this.x = x; this.m = m; this.k1 = k1; this.k2 = k2; this.k3 = k3; if ((k2 == 0) && (k3 == 0)) { this.representation = TPB; } else { this.representation = PPB; } } public BigInteger toBigInteger() { return x.toBigInteger(); } public String getFieldName() { return "F2m"; } public int getFieldSize() { return m; } /** * Checks, if the ECFieldElements a and b * are elements of the same field F2m * (having the same representation). * @param a field element. * @param b field element to be compared. * @throws IllegalArgumentException if a and b * are not elements of the same field * F2m (having the same * representation). */ public static void checkFieldElements( ECFieldElement a, ECFieldElement b) { if ((!(a instanceof F2m)) || (!(b instanceof F2m))) { throw new IllegalArgumentException("Field elements are not " + "both instances of ECFieldElement.F2m"); } ECFieldElement.F2m aF2m = (ECFieldElement.F2m)a; ECFieldElement.F2m bF2m = (ECFieldElement.F2m)b; if ((aF2m.m != bF2m.m) || (aF2m.k1 != bF2m.k1) || (aF2m.k2 != bF2m.k2) || (aF2m.k3 != bF2m.k3)) { throw new IllegalArgumentException("Field elements are not " + "elements of the same field F2m"); } if (aF2m.representation != bF2m.representation) { // Should never occur throw new IllegalArgumentException( "One of the field " + "elements are not elements has incorrect representation"); } } public ECFieldElement add(final ECFieldElement b) { // No check performed here for performance reasons. Instead the // elements involved are checked in ECPoint.F2m // checkFieldElements(this, b); IntArray iarrClone = (IntArray)this.x.clone(); F2m bF2m = (F2m)b; iarrClone.addShifted(bF2m.x, 0); return new F2m(m, k1, k2, k3, iarrClone); } public ECFieldElement subtract(final ECFieldElement b) { // Addition and subtraction are the same in F2m return add(b); } public ECFieldElement multiply(final ECFieldElement b) { // Right-to-left comb multiplication in the IntArray // Input: Binary polynomials a(z) and b(z) of degree at most m-1 // Output: c(z) = a(z) * b(z) mod f(z) // No check performed here for performance reasons. Instead the // elements involved are checked in ECPoint.F2m // checkFieldElements(this, b); F2m bF2m = (F2m)b; IntArray mult = x.multiply(bF2m.x, m); mult.reduce(m, new int[]{k1, k2, k3}); return new F2m(m, k1, k2, k3, mult); } public ECFieldElement divide(final ECFieldElement b) { // There may be more efficient implementations ECFieldElement bInv = b.invert(); return multiply(bInv); } public ECFieldElement negate() { // -x == x holds for all x in F2m return this; } public ECFieldElement square() { IntArray squared = x.square(m); squared.reduce(m, new int[]{k1, k2, k3}); return new F2m(m, k1, k2, k3, squared); } public ECFieldElement invert() { // Inversion in F2m using the extended Euclidean algorithm // Input: A nonzero polynomial a(z) of degree at most m-1 // Output: a(z)^(-1) mod f(z) // u(z) := a(z) IntArray uz = (IntArray)this.x.clone(); // v(z) := f(z) IntArray vz = new IntArray(t); vz.setBit(m); vz.setBit(0); vz.setBit(this.k1); if (this.representation == PPB) { vz.setBit(this.k2); vz.setBit(this.k3); } // g1(z) := 1, g2(z) := 0 IntArray g1z = new IntArray(t); g1z.setBit(0); IntArray g2z = new IntArray(t); // while u != 0 while (!uz.isZero()) // while (uz.getUsedLength() > 0) // while (uz.bitLength() > 1) { // j := deg(u(z)) - deg(v(z)) int j = uz.bitLength() - vz.bitLength(); // If j < 0 then: u(z) <-> v(z), g1(z) <-> g2(z), j := -j if (j < 0) { final IntArray uzCopy = uz; uz = vz; vz = uzCopy; final IntArray g1zCopy = g1z; g1z = g2z; g2z = g1zCopy; j = -j; } // u(z) := u(z) + z^j * v(z) // Note, that no reduction modulo f(z) is required, because // deg(u(z) + z^j * v(z)) <= max(deg(u(z)), j + deg(v(z))) // = max(deg(u(z)), deg(u(z)) - deg(v(z)) + deg(v(z)) // = deg(u(z)) // uz = uz.xor(vz.shiftLeft(j)); // jInt = n / 32 int jInt = j >> 5; // jInt = n % 32 int jBit = j & 0x1F; IntArray vzShift = vz.shiftLeft(jBit); uz.addShifted(vzShift, jInt); // g1(z) := g1(z) + z^j * g2(z) // g1z = g1z.xor(g2z.shiftLeft(j)); IntArray g2zShift = g2z.shiftLeft(jBit); g1z.addShifted(g2zShift, jInt); } return new ECFieldElement.F2m( this.m, this.k1, this.k2, this.k3, g2z); } public ECFieldElement sqrt() { throw new RuntimeException("Not implemented"); } /** * @return the representation of the field * F2m, either of * TPB (trinomial * basis representation) or * PPB (pentanomial * basis representation). */ public int getRepresentation() { return this.representation; } /** * @return the degree m of the reduction polynomial * f(z). */ public int getM() { return this.m; } /** * @return TPB: The integer k where xm + * xk + 1 represents the reduction polynomial * f(z).
    * PPB: The integer k1 where xm + * xk3 + xk2 + xk1 + 1 * represents the reduction polynomial f(z).
    */ public int getK1() { return this.k1; } /** * @return TPB: Always returns 0
    * PPB: The integer k2 where xm + * xk3 + xk2 + xk1 + 1 * represents the reduction polynomial f(z).
    */ public int getK2() { return this.k2; } /** * @return TPB: Always set to 0
    * PPB: The integer k3 where xm + * xk3 + xk2 + xk1 + 1 * represents the reduction polynomial f(z).
    */ public int getK3() { return this.k3; } public boolean equals(Object anObject) { if (anObject == this) { return true; } if (!(anObject instanceof ECFieldElement.F2m)) { return false; } ECFieldElement.F2m b = (ECFieldElement.F2m)anObject; return ((this.m == b.m) && (this.k1 == b.k1) && (this.k2 == b.k2) && (this.k3 == b.k3) && (this.representation == b.representation) && (this.x.equals(b.x))); } public int hashCode() { return x.hashCode() ^ m ^ k1 ^ k2 ^ k3; } } } bouncycastle-1.49.orig/src/org/bouncycastle/bcpg/0000755000175000017500000000000012152033551021412 5ustar ebourgebourgbouncycastle-1.49.orig/src/org/bouncycastle/bcpg/ExperimentalPacket.java0000644000175000017500000000152412132365645026056 0ustar ebourgebourgpackage org.bouncycastle.bcpg; import java.io.IOException; import org.bouncycastle.util.Arrays; /** * basic packet for an experimental packet. */ public class ExperimentalPacket extends ContainedPacket implements PublicKeyAlgorithmTags { private int tag; private byte[] contents; /** * * @param in * @throws IOException */ ExperimentalPacket( int tag, BCPGInputStream in) throws IOException { this.tag = tag; this.contents = in.readAll(); } public int getTag() { return tag; } public byte[] getContents() { return Arrays.clone(contents); } public void encode( BCPGOutputStream out) throws IOException { out.writePacket(tag, contents, true); } } bouncycastle-1.49.orig/src/org/bouncycastle/bcpg/SymmetricKeyAlgorithmTags.java0000644000175000017500000000177610262753175027416 0ustar ebourgebourgpackage org.bouncycastle.bcpg; /** * Basic tags for symmetric key algorithms */ public interface SymmetricKeyAlgorithmTags { public static final int NULL = 0; // Plaintext or unencrypted data public static final int IDEA = 1; // IDEA [IDEA] public static final int TRIPLE_DES = 2; // Triple-DES (DES-EDE, as per spec -168 bit key derived from 192) public static final int CAST5 = 3; // CAST5 (128 bit key, as per RFC 2144) public static final int BLOWFISH = 4; // Blowfish (128 bit key, 16 rounds) [BLOWFISH] public static final int SAFER = 5; // SAFER-SK128 (13 rounds) [SAFER] public static final int DES = 6; // Reserved for DES/SK public static final int AES_128 = 7; // Reserved for AES with 128-bit key public static final int AES_192 = 8; // Reserved for AES with 192-bit key public static final int AES_256 = 9; // Reserved for AES with 256-bit key public static final int TWOFISH = 10; // Reserved for Twofish } bouncycastle-1.49.orig/src/org/bouncycastle/bcpg/BCPGKey.java0000644000175000017500000000122710324400070023434 0ustar ebourgebourgpackage org.bouncycastle.bcpg; /** * base interface for a PGP key */ public interface BCPGKey { /** * Return the base format for this key - in the case of the symmetric keys it will generally * be raw indicating that the key is just a straight byte representation, for an asymmetric * key the format will be PGP, indicating the key is a string of MPIs encoded in PGP format. * * @return "RAW" or "PGP" */ public String getFormat(); /** * return a string of bytes giving the encoded format of the key, as described by it's format. * * @return byte[] */ public byte[] getEncoded(); } bouncycastle-1.49.orig/src/org/bouncycastle/bcpg/HashAlgorithmTags.java0000644000175000017500000000146510514706261025641 0ustar ebourgebourgpackage org.bouncycastle.bcpg; /** * basic tags for hash algorithms */ public interface HashAlgorithmTags { public static final int MD5 = 1; // MD5 public static final int SHA1 = 2; // SHA-1 public static final int RIPEMD160 = 3; // RIPE-MD/160 public static final int DOUBLE_SHA = 4; // Reserved for double-width SHA (experimental) public static final int MD2 = 5; // MD2 public static final int TIGER_192 = 6; // Reserved for TIGER/192 public static final int HAVAL_5_160 = 7; // Reserved for HAVAL (5 pass, 160-bit) public static final int SHA256 = 8; // SHA-256 public static final int SHA384 = 9; // SHA-384 public static final int SHA512 = 10; // SHA-512 public static final int SHA224 = 11; // SHA-224 } bouncycastle-1.49.orig/src/org/bouncycastle/bcpg/MPInteger.java0000644000175000017500000000237510627303743024126 0ustar ebourgebourgpackage org.bouncycastle.bcpg; import java.io.*; import java.math.BigInteger; /** * a multiple precision integer */ public class MPInteger extends BCPGObject { BigInteger value = null; public MPInteger( BCPGInputStream in) throws IOException { int length = (in.read() << 8) | in.read(); byte[] bytes = new byte[(length + 7) / 8]; in.readFully(bytes); value = new BigInteger(1, bytes); } public MPInteger( BigInteger value) { if (value == null || value.signum() < 0) { throw new IllegalArgumentException("value must not be null, or negative"); } this.value = value; } public BigInteger getValue() { return value; } public void encode( BCPGOutputStream out) throws IOException { int length = value.bitLength(); out.write(length >> 8); out.write(length); byte[] bytes = value.toByteArray(); if (bytes[0] == 0) { out.write(bytes, 1, bytes.length - 1); } else { out.write(bytes, 0, bytes.length); } } } bouncycastle-1.49.orig/src/org/bouncycastle/bcpg/PacketTags.java0000644000175000017500000000366210262753175024325 0ustar ebourgebourgpackage org.bouncycastle.bcpg; /** * Basic PGP packet tag types. */ public interface PacketTags { public static final int RESERVED = 0 ; // Reserved - a packet tag must not have this value public static final int PUBLIC_KEY_ENC_SESSION = 1; // Public-Key Encrypted Session Key Packet public static final int SIGNATURE = 2; // Signature Packet public static final int SYMMETRIC_KEY_ENC_SESSION = 3; // Symmetric-Key Encrypted Session Key Packet public static final int ONE_PASS_SIGNATURE = 4 ; // One-Pass Signature Packet public static final int SECRET_KEY = 5; // Secret Key Packet public static final int PUBLIC_KEY = 6 ; // Public Key Packet public static final int SECRET_SUBKEY = 7; // Secret Subkey Packet public static final int COMPRESSED_DATA = 8; // Compressed Data Packet public static final int SYMMETRIC_KEY_ENC = 9; // Symmetrically Encrypted Data Packet public static final int MARKER = 10; // Marker Packet public static final int LITERAL_DATA = 11; // Literal Data Packet public static final int TRUST = 12; // Trust Packet public static final int USER_ID = 13; // User ID Packet public static final int PUBLIC_SUBKEY = 14; // Public Subkey Packet public static final int USER_ATTRIBUTE = 17; // User attribute public static final int SYM_ENC_INTEGRITY_PRO = 18; // Symmetric encrypted, integrity protected public static final int MOD_DETECTION_CODE = 19; // Modification detection code public static final int EXPERIMENTAL_1 = 60; // Private or Experimental Values public static final int EXPERIMENTAL_2 = 61; public static final int EXPERIMENTAL_3 = 62; public static final int EXPERIMENTAL_4 = 63; } bouncycastle-1.49.orig/src/org/bouncycastle/bcpg/BCPGInputStream.java0000644000175000017500000002273712145534723025210 0ustar ebourgebourgpackage org.bouncycastle.bcpg; import java.io.EOFException; import java.io.IOException; import java.io.InputStream; import org.bouncycastle.util.io.Streams; /** * reader for PGP objects */ public class BCPGInputStream extends InputStream implements PacketTags { InputStream in; boolean next = false; int nextB; public BCPGInputStream( InputStream in) { this.in = in; } public int available() throws IOException { return in.available(); } public int read() throws IOException { if (next) { next = false; return nextB; } else { return in.read(); } } public int read( byte[] buf, int off, int len) throws IOException { if (len == 0) { return 0; } if (!next) { return in.read(buf, off, len); } // We have next byte waiting, so return it if (nextB < 0) { return -1; // EOF } buf[off] = (byte)nextB; // May throw NullPointerException... next = false; // ...so only set this afterwards return 1; } public void readFully( byte[] buf, int off, int len) throws IOException { if (Streams.readFully(this, buf, off, len) < len) { throw new EOFException(); } } public byte[] readAll() throws IOException { return Streams.readAll(this); } public void readFully( byte[] buf) throws IOException { readFully(buf, 0, buf.length); } /** * returns the next packet tag in the stream. * * @return the tag number. * * @throws IOException */ public int nextPacketTag() throws IOException { if (!next) { try { nextB = in.read(); } catch (EOFException e) { nextB = -1; } } next = true; if (nextB >= 0) { if ((nextB & 0x40) != 0) // new { return (nextB & 0x3f); } else // old { return ((nextB & 0x3f) >> 2); } } return nextB; } public Packet readPacket() throws IOException { int hdr = this.read(); if (hdr < 0) { return null; } if ((hdr & 0x80) == 0) { throw new IOException("invalid header encountered"); } boolean newPacket = (hdr & 0x40) != 0; int tag = 0; int bodyLen = 0; boolean partial = false; if (newPacket) { tag = hdr & 0x3f; int l = this.read(); if (l < 192) { bodyLen = l; } else if (l <= 223) { int b = in.read(); bodyLen = ((l - 192) << 8) + (b) + 192; } else if (l == 255) { bodyLen = (in.read() << 24) | (in.read() << 16) | (in.read() << 8) | in.read(); } else { partial = true; bodyLen = 1 << (l & 0x1f); } } else { int lengthType = hdr & 0x3; tag = (hdr & 0x3f) >> 2; switch (lengthType) { case 0: bodyLen = this.read(); break; case 1: bodyLen = (this.read() << 8) | this.read(); break; case 2: bodyLen = (this.read() << 24) | (this.read() << 16) | (this.read() << 8) | this.read(); break; case 3: partial = true; break; default: throw new IOException("unknown length type encountered"); } } BCPGInputStream objStream; if (bodyLen == 0 && partial) { objStream = this; } else { objStream = new BCPGInputStream(new PartialInputStream(this, partial, bodyLen)); } switch (tag) { case RESERVED: return new InputStreamPacket(objStream); case PUBLIC_KEY_ENC_SESSION: return new PublicKeyEncSessionPacket(objStream); case SIGNATURE: return new SignaturePacket(objStream); case SYMMETRIC_KEY_ENC_SESSION: return new SymmetricKeyEncSessionPacket(objStream); case ONE_PASS_SIGNATURE: return new OnePassSignaturePacket(objStream); case SECRET_KEY: return new SecretKeyPacket(objStream); case PUBLIC_KEY: return new PublicKeyPacket(objStream); case SECRET_SUBKEY: return new SecretSubkeyPacket(objStream); case COMPRESSED_DATA: return new CompressedDataPacket(objStream); case SYMMETRIC_KEY_ENC: return new SymmetricEncDataPacket(objStream); case MARKER: return new MarkerPacket(objStream); case LITERAL_DATA: return new LiteralDataPacket(objStream); case TRUST: return new TrustPacket(objStream); case USER_ID: return new UserIDPacket(objStream); case USER_ATTRIBUTE: return new UserAttributePacket(objStream); case PUBLIC_SUBKEY: return new PublicSubkeyPacket(objStream); case SYM_ENC_INTEGRITY_PRO: return new SymmetricEncIntegrityPacket(objStream); case MOD_DETECTION_CODE: return new ModDetectionCodePacket(objStream); case EXPERIMENTAL_1: case EXPERIMENTAL_2: case EXPERIMENTAL_3: case EXPERIMENTAL_4: return new ExperimentalPacket(tag, objStream); default: throw new IOException("unknown packet type encountered: " + tag); } } public void close() throws IOException { in.close(); } /** * a stream that overlays our input stream, allowing the user to only read a segment of it. * * NB: dataLength will be negative if the segment length is in the upper range above 2**31. */ private static class PartialInputStream extends InputStream { private BCPGInputStream in; private boolean partial; private int dataLength; PartialInputStream( BCPGInputStream in, boolean partial, int dataLength) { this.in = in; this.partial = partial; this.dataLength = dataLength; } public int available() throws IOException { int avail = in.available(); if (avail <= dataLength || dataLength < 0) { return avail; } else { if (partial && dataLength == 0) { return 1; } return dataLength; } } private int loadDataLength() throws IOException { int l = in.read(); if (l < 0) { return -1; } partial = false; if (l < 192) { dataLength = l; } else if (l <= 223) { dataLength = ((l - 192) << 8) + (in.read()) + 192; } else if (l == 255) { dataLength = (in.read() << 24) | (in.read() << 16) | (in.read() << 8) | in.read(); } else { partial = true; dataLength = 1 << (l & 0x1f); } return dataLength; } public int read(byte[] buf, int offset, int len) throws IOException { do { if (dataLength != 0) { int readLen = (dataLength > len || dataLength < 0) ? len : dataLength; readLen = in.read(buf, offset, readLen); if (readLen < 0) { throw new EOFException("premature end of stream in PartialInputStream"); } dataLength -= readLen; return readLen; } } while (partial && loadDataLength() >= 0); return -1; } public int read() throws IOException { do { if (dataLength != 0) { int ch = in.read(); if (ch < 0) { throw new EOFException("premature end of stream in PartialInputStream"); } dataLength--; return ch; } } while (partial && loadDataLength() >= 0); return -1; } } } bouncycastle-1.49.orig/src/org/bouncycastle/bcpg/UserAttributeSubpacketTags.java0000644000175000017500000000027410262753175027556 0ustar ebourgebourgpackage org.bouncycastle.bcpg; /** * Basic PGP user attribute sub-packet tag types. */ public interface UserAttributeSubpacketTags { public static final int IMAGE_ATTRIBUTE = 1; } bouncycastle-1.49.orig/src/org/bouncycastle/bcpg/SymmetricEncDataPacket.java0000644000175000017500000000040110262753175026607 0ustar ebourgebourgpackage org.bouncycastle.bcpg; /** * Basic type for a symmetric key encrypted packet */ public class SymmetricEncDataPacket extends InputStreamPacket { public SymmetricEncDataPacket( BCPGInputStream in) { super(in); } } bouncycastle-1.49.orig/src/org/bouncycastle/bcpg/PublicKeyAlgorithmTags.java0000644000175000017500000000261511056705150026641 0ustar ebourgebourgpackage org.bouncycastle.bcpg; /** * Public Key Algorithm tag numbers */ public interface PublicKeyAlgorithmTags { public static final int RSA_GENERAL = 1; // RSA (Encrypt or Sign) public static final int RSA_ENCRYPT = 2; // RSA Encrypt-Only public static final int RSA_SIGN = 3; // RSA Sign-Only public static final int ELGAMAL_ENCRYPT = 16; // Elgamal (Encrypt-Only), see [ELGAMAL] public static final int DSA = 17; // DSA (Digital Signature Standard) public static final int EC = 18; // Reserved for Elliptic Curve public static final int ECDSA = 19; // Reserved for ECDSA public static final int ELGAMAL_GENERAL = 20; // Elgamal (Encrypt or Sign) public static final int DIFFIE_HELLMAN = 21; // Reserved for Diffie-Hellman (X9.42, as defined for IETF-S/MIME) public static final int EXPERIMENTAL_1 = 100; public static final int EXPERIMENTAL_2 = 101; public static final int EXPERIMENTAL_3 = 102; public static final int EXPERIMENTAL_4 = 103; public static final int EXPERIMENTAL_5 = 104; public static final int EXPERIMENTAL_6 = 105; public static final int EXPERIMENTAL_7 = 106; public static final int EXPERIMENTAL_8 = 107; public static final int EXPERIMENTAL_9 = 108; public static final int EXPERIMENTAL_10 = 109; public static final int EXPERIMENTAL_11 = 110; } bouncycastle-1.49.orig/src/org/bouncycastle/bcpg/ModDetectionCodePacket.java0000644000175000017500000000172710535263035026572 0ustar ebourgebourgpackage org.bouncycastle.bcpg; import java.io.*; /** * basic packet for a modification detection code packet. */ public class ModDetectionCodePacket extends ContainedPacket { private byte[] digest; ModDetectionCodePacket( BCPGInputStream in) throws IOException { this.digest = new byte[20]; in.readFully(this.digest); } public ModDetectionCodePacket( byte[] digest) throws IOException { this.digest = new byte[digest.length]; System.arraycopy(digest, 0, this.digest, 0, this.digest.length); } public byte[] getDigest() { byte[] tmp = new byte[digest.length]; System.arraycopy(digest, 0, tmp, 0, tmp.length); return tmp; } public void encode( BCPGOutputStream out) throws IOException { out.writePacket(MOD_DETECTION_CODE, digest, false); } } bouncycastle-1.49.orig/src/org/bouncycastle/bcpg/BCPGOutputStream.java0000644000175000017500000002065512151274313025377 0ustar ebourgebourgpackage org.bouncycastle.bcpg; import java.io.IOException; import java.io.OutputStream; /** * Basic output stream. */ public class BCPGOutputStream extends OutputStream implements PacketTags, CompressionAlgorithmTags { OutputStream out; private byte[] partialBuffer; private int partialBufferLength; private int partialPower; private int partialOffset; private static final int BUF_SIZE_POWER = 16; // 2^16 size buffer on long files public BCPGOutputStream( OutputStream out) { this.out = out; } /** * Create a stream representing an old style partial object. * * @param tag the packet tag for the object. */ public BCPGOutputStream( OutputStream out, int tag) throws IOException { this.out = out; this.writeHeader(tag, true, true, 0); } /** * Create a stream representing a general packet. * * @param out * @param tag * @param length * @param oldFormat * @throws IOException */ public BCPGOutputStream( OutputStream out, int tag, long length, boolean oldFormat) throws IOException { this.out = out; if (length > 0xFFFFFFFFL) { this.writeHeader(tag, false, true, 0); this.partialBufferLength = 1 << BUF_SIZE_POWER; this.partialBuffer = new byte[partialBufferLength]; this.partialPower = BUF_SIZE_POWER; this.partialOffset = 0; } else { this.writeHeader(tag, oldFormat, false, length); } } /** * * @param tag * @param length * @throws IOException */ public BCPGOutputStream( OutputStream out, int tag, long length) throws IOException { this.out = out; this.writeHeader(tag, false, false, length); } /** * Create a new style partial input stream buffered into chunks. * * @param out output stream to write to. * @param tag packet tag. * @param buffer size of chunks making up the packet. * @throws IOException */ public BCPGOutputStream( OutputStream out, int tag, byte[] buffer) throws IOException { this.out = out; this.writeHeader(tag, false, true, 0); this.partialBuffer = buffer; int length = partialBuffer.length; for (partialPower = 0; length != 1; partialPower++) { length >>>= 1; } if (partialPower > 30) { throw new IOException("Buffer cannot be greater than 2^30 in length."); } this.partialBufferLength = 1 << partialPower; this.partialOffset = 0; } private void writeNewPacketLength( long bodyLen) throws IOException { if (bodyLen < 192) { out.write((byte)bodyLen); } else if (bodyLen <= 8383) { bodyLen -= 192; out.write((byte)(((bodyLen >> 8) & 0xff) + 192)); out.write((byte)bodyLen); } else { out.write(0xff); out.write((byte)(bodyLen >> 24)); out.write((byte)(bodyLen >> 16)); out.write((byte)(bodyLen >> 8)); out.write((byte)bodyLen); } } private void writeHeader( int tag, boolean oldPackets, boolean partial, long bodyLen) throws IOException { int hdr = 0x80; if (partialBuffer != null) { partialFlush(true); partialBuffer = null; } if (oldPackets) { hdr |= tag << 2; if (partial) { this.write(hdr | 0x03); } else { if (bodyLen <= 0xff) { this.write(hdr); this.write((byte)bodyLen); } else if (bodyLen <= 0xffff) { this.write(hdr | 0x01); this.write((byte)(bodyLen >> 8)); this.write((byte)(bodyLen)); } else { this.write(hdr | 0x02); this.write((byte)(bodyLen >> 24)); this.write((byte)(bodyLen >> 16)); this.write((byte)(bodyLen >> 8)); this.write((byte)bodyLen); } } } else { hdr |= 0x40 | tag; this.write(hdr); if (partial) { partialOffset = 0; } else { this.writeNewPacketLength(bodyLen); } } } private void partialFlush( boolean isLast) throws IOException { if (isLast) { writeNewPacketLength(partialOffset); out.write(partialBuffer, 0, partialOffset); } else { out.write(0xE0 | partialPower); out.write(partialBuffer, 0, partialBufferLength); } partialOffset = 0; } private void writePartial( byte b) throws IOException { if (partialOffset == partialBufferLength) { partialFlush(false); } partialBuffer[partialOffset++] = b; } private void writePartial( byte[] buf, int off, int len) throws IOException { if (partialOffset == partialBufferLength) { partialFlush(false); } if (len <= (partialBufferLength - partialOffset)) { System.arraycopy(buf, off, partialBuffer, partialOffset, len); partialOffset += len; } else { System.arraycopy(buf, off, partialBuffer, partialOffset, partialBufferLength - partialOffset); off += partialBufferLength - partialOffset; len -= partialBufferLength - partialOffset; partialFlush(false); while (len > partialBufferLength) { System.arraycopy(buf, off, partialBuffer, 0, partialBufferLength); off += partialBufferLength; len -= partialBufferLength; partialFlush(false); } System.arraycopy(buf, off, partialBuffer, 0, len); partialOffset += len; } } public void write( int b) throws IOException { if (partialBuffer != null) { writePartial((byte)b); } else { out.write(b); } } public void write( byte[] bytes, int off, int len) throws IOException { if (partialBuffer != null) { writePartial(bytes, off, len); } else { out.write(bytes, off, len); } } public void writePacket( ContainedPacket p) throws IOException { p.encode(this); } void writePacket( int tag, byte[] body, boolean oldFormat) throws IOException { this.writeHeader(tag, oldFormat, false, body.length); this.write(body); } public void writeObject( BCPGObject o) throws IOException { o.encode(this); } /** * Flush the underlying stream. */ public void flush() throws IOException { out.flush(); } /** * Finish writing out the current packet without closing the underlying stream. */ public void finish() throws IOException { if (partialBuffer != null) { partialFlush(true); partialBuffer = null; } } public void close() throws IOException { this.finish(); out.flush(); out.close(); } } bouncycastle-1.49.orig/src/org/bouncycastle/bcpg/RSAPublicBCPGKey.java0000644000175000017500000000343410262753175025165 0ustar ebourgebourgpackage org.bouncycastle.bcpg; import java.math.BigInteger; import java.io.*; /** * base class for an RSA Public Key. */ public class RSAPublicBCPGKey extends BCPGObject implements BCPGKey { MPInteger n; MPInteger e; /** * Construct an RSA public key from the passed in stream. * * @param in * @throws IOException */ public RSAPublicBCPGKey( BCPGInputStream in) throws IOException { this.n = new MPInteger(in); this.e = new MPInteger(in); } /** * * @param n the modulus * @param e the public exponent */ public RSAPublicBCPGKey( BigInteger n, BigInteger e) { this.n = new MPInteger(n); this.e = new MPInteger(e); } public BigInteger getPublicExponent() { return e.getValue(); } public BigInteger getModulus() { return n.getValue(); } /** * return "PGP" * * @see org.bouncycastle.bcpg.BCPGKey#getFormat() */ public String getFormat() { return "PGP"; } /** * return the standard PGP encoding of the key. * * @see org.bouncycastle.bcpg.BCPGKey#getEncoded() */ public byte[] getEncoded() { try { ByteArrayOutputStream bOut = new ByteArrayOutputStream(); BCPGOutputStream pgpOut = new BCPGOutputStream(bOut); pgpOut.writeObject(this); return bOut.toByteArray(); } catch (IOException e) { return null; } } public void encode( BCPGOutputStream out) throws IOException { out.writeObject(n); out.writeObject(e); } } bouncycastle-1.49.orig/src/org/bouncycastle/bcpg/ContainedPacket.java0000644000175000017500000000112212151274313025307 0ustar ebourgebourgpackage org.bouncycastle.bcpg; import java.io.ByteArrayOutputStream; import java.io.IOException; /** * Basic type for a PGP packet. */ public abstract class ContainedPacket extends Packet { public byte[] getEncoded() throws IOException { ByteArrayOutputStream bOut = new ByteArrayOutputStream(); BCPGOutputStream pOut = new BCPGOutputStream(bOut); pOut.writePacket(this); return bOut.toByteArray(); } public abstract void encode( BCPGOutputStream pOut) throws IOException; } bouncycastle-1.49.orig/src/org/bouncycastle/bcpg/SignatureSubpacketTags.java0000644000175000017500000000371711056705114026712 0ustar ebourgebourgpackage org.bouncycastle.bcpg; /** * Basic PGP signature sub-packet tag types. */ public interface SignatureSubpacketTags { public static final int CREATION_TIME = 2; // signature creation time public static final int EXPIRE_TIME = 3; // signature expiration time public static final int EXPORTABLE = 4; // exportable certification public static final int TRUST_SIG = 5; // trust signature public static final int REG_EXP = 6; // regular expression public static final int REVOCABLE = 7; // revocable public static final int KEY_EXPIRE_TIME = 9; // key expiration time public static final int PLACEHOLDER = 10; // placeholder for backward compatibility public static final int PREFERRED_SYM_ALGS = 11; // preferred symmetric algorithms public static final int REVOCATION_KEY = 12; // revocation key public static final int ISSUER_KEY_ID = 16; // issuer key ID public static final int NOTATION_DATA = 20; // notation data public static final int PREFERRED_HASH_ALGS = 21; // preferred hash algorithms public static final int PREFERRED_COMP_ALGS = 22; // preferred compression algorithms public static final int KEY_SERVER_PREFS = 23; // key server preferences public static final int PREFERRED_KEY_SERV = 24; // preferred key server public static final int PRIMARY_USER_ID = 25; // primary user id public static final int POLICY_URL = 26; // policy URL public static final int KEY_FLAGS = 27; // key flags public static final int SIGNER_USER_ID = 28; // signer's user id public static final int REVOCATION_REASON = 29; // reason for revocation public static final int FEATURES = 30; // features public static final int SIGNATURE_TARGET = 31; // signature target public static final int EMBEDDED_SIGNATURE = 32; // embedded signature } bouncycastle-1.49.orig/src/org/bouncycastle/bcpg/SecretKeyPacket.java0000644000175000017500000001023012132365613025304 0ustar ebourgebourgpackage org.bouncycastle.bcpg; import java.io.ByteArrayOutputStream; import java.io.IOException; /** * basic packet for a PGP secret key */ public class SecretKeyPacket extends ContainedPacket implements PublicKeyAlgorithmTags { public static final int USAGE_NONE = 0x00; public static final int USAGE_CHECKSUM = 0xff; public static final int USAGE_SHA1 = 0xfe; private PublicKeyPacket pubKeyPacket; private byte[] secKeyData; private int s2kUsage; private int encAlgorithm; private S2K s2k; private byte[] iv; /** * * @param in * @throws IOException */ SecretKeyPacket( BCPGInputStream in) throws IOException { if (this instanceof SecretSubkeyPacket) { pubKeyPacket = new PublicSubkeyPacket(in); } else { pubKeyPacket = new PublicKeyPacket(in); } s2kUsage = in.read(); if (s2kUsage == USAGE_CHECKSUM || s2kUsage == USAGE_SHA1) { encAlgorithm = in.read(); s2k = new S2K(in); } else { encAlgorithm = s2kUsage; } if (!(s2k != null && s2k.getType() == S2K.GNU_DUMMY_S2K && s2k.getProtectionMode() == 0x01)) { if (s2kUsage != 0) { if (encAlgorithm < 7) { iv = new byte[8]; } else { iv = new byte[16]; } in.readFully(iv, 0, iv.length); } } this.secKeyData = in.readAll(); } /** * * @param pubKeyPacket * @param encAlgorithm * @param s2k * @param iv * @param secKeyData */ public SecretKeyPacket( PublicKeyPacket pubKeyPacket, int encAlgorithm, S2K s2k, byte[] iv, byte[] secKeyData) { this.pubKeyPacket = pubKeyPacket; this.encAlgorithm = encAlgorithm; if (encAlgorithm != SymmetricKeyAlgorithmTags.NULL) { this.s2kUsage = USAGE_CHECKSUM; } else { this.s2kUsage = USAGE_NONE; } this.s2k = s2k; this.iv = iv; this.secKeyData = secKeyData; } public SecretKeyPacket( PublicKeyPacket pubKeyPacket, int encAlgorithm, int s2kUsage, S2K s2k, byte[] iv, byte[] secKeyData) { this.pubKeyPacket = pubKeyPacket; this.encAlgorithm = encAlgorithm; this.s2kUsage = s2kUsage; this.s2k = s2k; this.iv = iv; this.secKeyData = secKeyData; } public int getEncAlgorithm() { return encAlgorithm; } public int getS2KUsage() { return s2kUsage; } public byte[] getIV() { return iv; } public S2K getS2K() { return s2k; } public PublicKeyPacket getPublicKeyPacket() { return pubKeyPacket; } public byte[] getSecretKeyData() { return secKeyData; } public byte[] getEncodedContents() throws IOException { ByteArrayOutputStream bOut = new ByteArrayOutputStream(); BCPGOutputStream pOut = new BCPGOutputStream(bOut); pOut.write(pubKeyPacket.getEncodedContents()); pOut.write(s2kUsage); if (s2kUsage == USAGE_CHECKSUM || s2kUsage == USAGE_SHA1) { pOut.write(encAlgorithm); pOut.writeObject(s2k); } if (iv != null) { pOut.write(iv); } if (secKeyData != null && secKeyData.length > 0) { pOut.write(secKeyData); } return bOut.toByteArray(); } public void encode( BCPGOutputStream out) throws IOException { out.writePacket(SECRET_KEY, getEncodedContents(), true); } } bouncycastle-1.49.orig/src/org/bouncycastle/bcpg/UserAttributePacket.java0000644000175000017500000000300210262753175026215 0ustar ebourgebourgpackage org.bouncycastle.bcpg; import java.io.ByteArrayOutputStream; import java.io.IOException; import java.util.Vector; /** * Basic type for a user attribute packet. */ public class UserAttributePacket extends ContainedPacket { private UserAttributeSubpacket[] subpackets; public UserAttributePacket( BCPGInputStream in) throws IOException { UserAttributeSubpacketInputStream sIn = new UserAttributeSubpacketInputStream(in); UserAttributeSubpacket sub; Vector v= new Vector(); while ((sub = sIn.readPacket()) != null) { v.addElement(sub); } subpackets = new UserAttributeSubpacket[v.size()]; for (int i = 0; i != subpackets.length; i++) { subpackets[i] = (UserAttributeSubpacket)v.elementAt(i); } } public UserAttributePacket( UserAttributeSubpacket[] subpackets) { this.subpackets = subpackets; } public UserAttributeSubpacket[] getSubpackets() { return subpackets; } public void encode( BCPGOutputStream out) throws IOException { ByteArrayOutputStream bOut = new ByteArrayOutputStream(); for (int i = 0; i != subpackets.length; i++) { subpackets[i].encode(bOut); } out.writePacket(USER_ATTRIBUTE, bOut.toByteArray(), false); } } bouncycastle-1.49.orig/src/org/bouncycastle/bcpg/MarkerPacket.java0000644000175000017500000000102010262753175024632 0ustar ebourgebourgpackage org.bouncycastle.bcpg; import java.io.IOException; /** * Basic type for a marker packet */ public class MarkerPacket extends ContainedPacket { // "PGP" byte[] marker = { (byte)0x50, (byte)0x47, (byte)0x50 }; public MarkerPacket( BCPGInputStream in) throws IOException { in.readFully(marker); } public void encode( BCPGOutputStream out) throws IOException { out.writePacket(MARKER, marker, true); } } bouncycastle-1.49.orig/src/org/bouncycastle/bcpg/ElGamalPublicBCPGKey.java0000644000175000017500000000346210262753175026043 0ustar ebourgebourgpackage org.bouncycastle.bcpg; import java.io.*; import java.math.BigInteger; /** * base class for an ElGamal Public Key. */ public class ElGamalPublicBCPGKey extends BCPGObject implements BCPGKey { MPInteger p; MPInteger g; MPInteger y; /** * */ public ElGamalPublicBCPGKey( BCPGInputStream in) throws IOException { this.p = new MPInteger(in); this.g = new MPInteger(in); this.y = new MPInteger(in); } public ElGamalPublicBCPGKey( BigInteger p, BigInteger g, BigInteger y) { this.p = new MPInteger(p); this.g = new MPInteger(g); this.y = new MPInteger(y); } /** * return "PGP" * * @see org.bouncycastle.bcpg.BCPGKey#getFormat() */ public String getFormat() { return "PGP"; } /** * return the standard PGP encoding of the key. * * @see org.bouncycastle.bcpg.BCPGKey#getEncoded() */ public byte[] getEncoded() { try { ByteArrayOutputStream bOut = new ByteArrayOutputStream(); BCPGOutputStream pgpOut = new BCPGOutputStream(bOut); pgpOut.writeObject(this); return bOut.toByteArray(); } catch (IOException e) { return null; } } public BigInteger getP() { return p.getValue(); } public BigInteger getG() { return g.getValue(); } public BigInteger getY() { return y.getValue(); } public void encode( BCPGOutputStream out) throws IOException { out.writeObject(p); out.writeObject(g); out.writeObject(y); } } bouncycastle-1.49.orig/src/org/bouncycastle/bcpg/UserAttributeSubpacket.java0000644000175000017500000000346510717053655026745 0ustar ebourgebourgpackage org.bouncycastle.bcpg; import org.bouncycastle.util.Arrays; import java.io.IOException; import java.io.OutputStream; /** * Basic type for a user attribute sub-packet. */ public class UserAttributeSubpacket { int type; protected byte[] data; protected UserAttributeSubpacket( int type, byte[] data) { this.type = type; this.data = data; } public int getType() { return type; } /** * return the generic data making up the packet. */ public byte[] getData() { return data; } public void encode( OutputStream out) throws IOException { int bodyLen = data.length + 1; if (bodyLen < 192) { out.write((byte)bodyLen); } else if (bodyLen <= 8383) { bodyLen -= 192; out.write((byte)(((bodyLen >> 8) & 0xff) + 192)); out.write((byte)bodyLen); } else { out.write(0xff); out.write((byte)(bodyLen >> 24)); out.write((byte)(bodyLen >> 16)); out.write((byte)(bodyLen >> 8)); out.write((byte)bodyLen); } out.write(type); out.write(data); } public boolean equals( Object o) { if (o == this) { return true; } if (!(o instanceof UserAttributeSubpacket)) { return false; } UserAttributeSubpacket other = (UserAttributeSubpacket)o; return this.type == other.type && Arrays.areEqual(this.data, other.data); } public int hashCode() { return type ^ Arrays.hashCode(data); } } bouncycastle-1.49.orig/src/org/bouncycastle/bcpg/CRC24.java0000644000175000017500000000140010532757034023036 0ustar ebourgebourgpackage org.bouncycastle.bcpg; public class CRC24 { private static final int CRC24_INIT = 0x0b704ce; private static final int CRC24_POLY = 0x1864cfb; private int crc = CRC24_INIT; public CRC24() { } public void update( int b) { crc ^= b << 16; for (int i = 0; i < 8; i++) { crc <<= 1; if ((crc & 0x1000000) != 0) { crc ^= CRC24_POLY; } } } public int getValue() { return crc; } public void reset() { crc = CRC24_INIT; } } bouncycastle-1.49.orig/src/org/bouncycastle/bcpg/attr/0000755000175000017500000000000012152033551022364 5ustar ebourgebourgbouncycastle-1.49.orig/src/org/bouncycastle/bcpg/attr/ImageAttribute.java0000644000175000017500000000344010721675266026155 0ustar ebourgebourgpackage org.bouncycastle.bcpg.attr; import org.bouncycastle.bcpg.UserAttributeSubpacket; import org.bouncycastle.bcpg.UserAttributeSubpacketTags; import java.io.ByteArrayOutputStream; import java.io.IOException; /** * Basic type for a image attribute packet. */ public class ImageAttribute extends UserAttributeSubpacket { public static final int JPEG = 1; private static final byte[] ZEROES = new byte[12]; private int hdrLength; private int version; private int encoding; private byte[] imageData; public ImageAttribute( byte[] data) { super(UserAttributeSubpacketTags.IMAGE_ATTRIBUTE, data); hdrLength = ((data[1] & 0xff) << 8) | (data[0] & 0xff); version = data[2] & 0xff; encoding = data[3] & 0xff; imageData = new byte[data.length - hdrLength]; System.arraycopy(data, hdrLength, imageData, 0, imageData.length); } public ImageAttribute( int imageType, byte[] imageData) { this(toByteArray(imageType, imageData)); } private static byte[] toByteArray(int imageType, byte[] imageData) { ByteArrayOutputStream bOut = new ByteArrayOutputStream(); try { bOut.write(0x10); bOut.write(0x00); bOut.write(0x01); bOut.write(imageType); bOut.write(ZEROES); bOut.write(imageData); } catch (IOException e) { throw new RuntimeException("unable to encode to byte array!"); } return bOut.toByteArray(); } public int version() { return version; } public int getEncoding() { return encoding; } public byte[] getImageData() { return imageData; } } bouncycastle-1.49.orig/src/org/bouncycastle/bcpg/attr/package.html0000644000175000017500000000015410262753175024660 0ustar ebourgebourg Low level classes for dealing with OpenPGP user attributes. bouncycastle-1.49.orig/src/org/bouncycastle/bcpg/BCPGObject.java0000644000175000017500000000105510262753175024133 0ustar ebourgebourgpackage org.bouncycastle.bcpg; import java.io.ByteArrayOutputStream; import java.io.IOException; /** * base class for a PGP object. */ public abstract class BCPGObject { public byte[] getEncoded() throws IOException { ByteArrayOutputStream bOut = new ByteArrayOutputStream(); BCPGOutputStream pOut = new BCPGOutputStream(bOut); pOut.writeObject(this); return bOut.toByteArray(); } public abstract void encode(BCPGOutputStream out) throws IOException; } bouncycastle-1.49.orig/src/org/bouncycastle/bcpg/InputStreamPacket.java0000644000175000017500000000064110262753175025674 0ustar ebourgebourgpackage org.bouncycastle.bcpg; /** * */ public class InputStreamPacket extends Packet { private BCPGInputStream in; public InputStreamPacket( BCPGInputStream in) { this.in = in; } /** * Note: you can only read from this once... * * @return the InputStream */ public BCPGInputStream getInputStream() { return in; } } bouncycastle-1.49.orig/src/org/bouncycastle/bcpg/S2K.java0000644000175000017500000000577712151274313022676 0ustar ebourgebourgpackage org.bouncycastle.bcpg; import java.io.DataInputStream; import java.io.IOException; import java.io.InputStream; /** * The string to key specifier class */ public class S2K extends BCPGObject { private static final int EXPBIAS = 6; public static final int SIMPLE = 0; public static final int SALTED = 1; public static final int SALTED_AND_ITERATED = 3; public static final int GNU_DUMMY_S2K = 101; int type; int algorithm; byte[] iv; int itCount = -1; int protectionMode = -1; S2K( InputStream in) throws IOException { DataInputStream dIn = new DataInputStream(in); type = dIn.read(); algorithm = dIn.read(); // // if this happens we have a dummy-S2K packet. // if (type != GNU_DUMMY_S2K) { if (type != 0) { iv = new byte[8]; dIn.readFully(iv, 0, iv.length); if (type == 3) { itCount = dIn.read(); } } } else { dIn.read(); // G dIn.read(); // N dIn.read(); // U protectionMode = dIn.read(); // protection mode } } public S2K( int algorithm) { this.type = 0; this.algorithm = algorithm; } public S2K( int algorithm, byte[] iv) { this.type = 1; this.algorithm = algorithm; this.iv = iv; } public S2K( int algorithm, byte[] iv, int itCount) { this.type = 3; this.algorithm = algorithm; this.iv = iv; this.itCount = itCount; } public int getType() { return type; } /** * return the hash algorithm for this S2K */ public int getHashAlgorithm() { return algorithm; } /** * return the iv for the key generation algorithm */ public byte[] getIV() { return iv; } /** * return the iteration count */ public long getIterationCount() { return (16 + (itCount & 15)) << ((itCount >> 4) + EXPBIAS); } /** * the protection mode - only if GNU_DUMMY_S2K */ public int getProtectionMode() { return protectionMode; } public void encode( BCPGOutputStream out) throws IOException { out.write(type); out.write(algorithm); if (type != GNU_DUMMY_S2K) { if (type != 0) { out.write(iv); } if (type == 3) { out.write(itCount); } } else { out.write('G'); out.write('N'); out.write('U'); out.write(protectionMode); } } } bouncycastle-1.49.orig/src/org/bouncycastle/bcpg/LiteralDataPacket.java0000644000175000017500000000264611271742332025610 0ustar ebourgebourgpackage org.bouncycastle.bcpg; import java.io.IOException; import org.bouncycastle.util.Strings; /** * generic literal data packet. */ public class LiteralDataPacket extends InputStreamPacket { int format; byte[] fileName; long modDate; LiteralDataPacket( BCPGInputStream in) throws IOException { super(in); format = in.read(); int l = in.read(); fileName = new byte[l]; for (int i = 0; i != fileName.length; i++) { fileName[i] = (byte)in.read(); } modDate = ((long)in.read() << 24) | (in.read() << 16) | (in.read() << 8) | in.read(); } /** * return the format tag value. * * @return format tag value. */ public int getFormat() { return format; } /** * Return the modification time of the file in milli-seconds. * * @return the modification time in millis */ public long getModificationTime() { return modDate * 1000L; } /** * @return filename */ public String getFileName() { return Strings.fromUTF8ByteArray(fileName); } public byte[] getRawFileName() { byte[] tmp = new byte[fileName.length]; for (int i = 0; i != tmp.length; i++) { tmp[i] = fileName[i]; } return tmp; } } bouncycastle-1.49.orig/src/org/bouncycastle/bcpg/PublicKeyPacket.java0000644000175000017500000000543210262753175025313 0ustar ebourgebourgpackage org.bouncycastle.bcpg; import java.io.*; import java.util.Date; /** * basic packet for a PGP public key */ public class PublicKeyPacket extends ContainedPacket implements PublicKeyAlgorithmTags { private int version; private long time; private int validDays; private int algorithm; private BCPGKey key; PublicKeyPacket( BCPGInputStream in) throws IOException { version = in.read(); time = ((long)in.read() << 24) | (in.read() << 16) | (in.read() << 8) | in.read(); if (version <= 3) { validDays = (in.read() << 8) | in.read(); } algorithm = (byte)in.read(); switch (algorithm) { case RSA_ENCRYPT: case RSA_GENERAL: case RSA_SIGN: key = new RSAPublicBCPGKey(in); break; case DSA: key = new DSAPublicBCPGKey(in); break; case ELGAMAL_ENCRYPT: case ELGAMAL_GENERAL: key = new ElGamalPublicBCPGKey(in); break; default: throw new IOException("unknown PGP public key algorithm encountered"); } } /** * Construct version 4 public key packet. * * @param algorithm * @param time * @param key */ public PublicKeyPacket( int algorithm, Date time, BCPGKey key) { this.version = 4; this.time = time.getTime() / 1000; this.algorithm = algorithm; this.key = key; } public int getVersion() { return version; } public int getAlgorithm() { return algorithm; } public int getValidDays() { return validDays; } public Date getTime() { return new Date(time * 1000); } public BCPGKey getKey() { return key; } public byte[] getEncodedContents() throws IOException { ByteArrayOutputStream bOut = new ByteArrayOutputStream(); BCPGOutputStream pOut = new BCPGOutputStream(bOut); pOut.write(version); pOut.write((byte)(time >> 24)); pOut.write((byte)(time >> 16)); pOut.write((byte)(time >> 8)); pOut.write((byte)time); if (version <= 3) { pOut.write((byte)(validDays >> 8)); pOut.write((byte)validDays); } pOut.write(algorithm); pOut.writeObject((BCPGObject)key); return bOut.toByteArray(); } public void encode( BCPGOutputStream out) throws IOException { out.writePacket(PUBLIC_KEY, getEncodedContents(), true); } } bouncycastle-1.49.orig/src/org/bouncycastle/bcpg/PublicKeyEncSessionPacket.java0000644000175000017500000000543110262753175027304 0ustar ebourgebourgpackage org.bouncycastle.bcpg; import java.io.*; import java.math.BigInteger; /** * basic packet for a PGP public key */ public class PublicKeyEncSessionPacket extends ContainedPacket implements PublicKeyAlgorithmTags { private int version; private long keyID; private int algorithm; private BigInteger[] data; PublicKeyEncSessionPacket( BCPGInputStream in) throws IOException { version = in.read(); keyID |= (long)in.read() << 56; keyID |= (long)in.read() << 48; keyID |= (long)in.read() << 40; keyID |= (long)in.read() << 32; keyID |= (long)in.read() << 24; keyID |= (long)in.read() << 16; keyID |= (long)in.read() << 8; keyID |= in.read(); algorithm = in.read(); switch (algorithm) { case RSA_ENCRYPT: case RSA_GENERAL: data = new BigInteger[1]; data[0] = new MPInteger(in).getValue(); break; case ELGAMAL_ENCRYPT: case ELGAMAL_GENERAL: data = new BigInteger[2]; data[0] = new MPInteger(in).getValue(); data[1] = new MPInteger(in).getValue(); break; default: throw new IOException("unknown PGP public key algorithm encountered"); } } public PublicKeyEncSessionPacket( long keyID, int algorithm, BigInteger[] data) { this.version = 3; this.keyID = keyID; this.algorithm = algorithm; this.data = data; } public int getVersion() { return version; } public long getKeyID() { return keyID; } public int getAlgorithm() { return algorithm; } public BigInteger[] getEncSessionKey() { return data; } public void encode( BCPGOutputStream out) throws IOException { ByteArrayOutputStream bOut = new ByteArrayOutputStream(); BCPGOutputStream pOut = new BCPGOutputStream(bOut); pOut.write(version); pOut.write((byte)(keyID >> 56)); pOut.write((byte)(keyID >> 48)); pOut.write((byte)(keyID >> 40)); pOut.write((byte)(keyID >> 32)); pOut.write((byte)(keyID >> 24)); pOut.write((byte)(keyID >> 16)); pOut.write((byte)(keyID >> 8)); pOut.write((byte)(keyID)); pOut.write(algorithm); for (int i = 0; i != data.length; i++) { pOut.writeObject(new MPInteger(data[i])); } out.writePacket(PUBLIC_KEY_ENC_SESSION , bOut.toByteArray(), true); } } bouncycastle-1.49.orig/src/org/bouncycastle/bcpg/CompressedDataPacket.java0000644000175000017500000000102312151274313026301 0ustar ebourgebourgpackage org.bouncycastle.bcpg; import java.io.IOException; /** * generic compressed data object. */ public class CompressedDataPacket extends InputStreamPacket { int algorithm; CompressedDataPacket( BCPGInputStream in) throws IOException { super(in); algorithm = in.read(); } /** * return the algorithm tag value. * * @return algorithm tag value. */ public int getAlgorithm() { return algorithm; } } bouncycastle-1.49.orig/src/org/bouncycastle/bcpg/sig/0000755000175000017500000000000012152033551022174 5ustar ebourgebourgbouncycastle-1.49.orig/src/org/bouncycastle/bcpg/sig/EmbeddedSignature.java0000644000175000017500000000063311442065637026427 0ustar ebourgebourgpackage org.bouncycastle.bcpg.sig; import org.bouncycastle.bcpg.SignatureSubpacket; import org.bouncycastle.bcpg.SignatureSubpacketTags; /** * Packet embedded signature */ public class EmbeddedSignature extends SignatureSubpacket { public EmbeddedSignature( boolean critical, byte[] data) { super(SignatureSubpacketTags.EMBEDDED_SIGNATURE, critical, data); } }bouncycastle-1.49.orig/src/org/bouncycastle/bcpg/sig/Revocable.java0000644000175000017500000000170311251332510024736 0ustar ebourgebourgpackage org.bouncycastle.bcpg.sig; import org.bouncycastle.bcpg.SignatureSubpacket; import org.bouncycastle.bcpg.SignatureSubpacketTags; /** * packet giving whether or not is revocable. */ public class Revocable extends SignatureSubpacket { private static byte[] booleanToByteArray( boolean value) { byte[] data = new byte[1]; if (value) { data[0] = 1; return data; } else { return data; } } public Revocable( boolean critical, byte[] data) { super(SignatureSubpacketTags.REVOCABLE, critical, data); } public Revocable( boolean critical, boolean isRevocable) { super(SignatureSubpacketTags.REVOCABLE, critical, booleanToByteArray(isRevocable)); } public boolean isRevocable() { return data[0] != 0; } } bouncycastle-1.49.orig/src/org/bouncycastle/bcpg/sig/KeyFlags.java0000644000175000017500000000332211042510504024537 0ustar ebourgebourgpackage org.bouncycastle.bcpg.sig; import org.bouncycastle.bcpg.SignatureSubpacket; import org.bouncycastle.bcpg.SignatureSubpacketTags; /** * Packet holding the key flag values. */ public class KeyFlags extends SignatureSubpacket { public static final int CERTIFY_OTHER = 0x01; public static final int SIGN_DATA = 0x02; public static final int ENCRYPT_COMMS = 0x04; public static final int ENCRYPT_STORAGE = 0x08; public static final int SPLIT = 0x10; public static final int AUTHENTICATION = 0x20; public static final int SHARED = 0x80; private static byte[] intToByteArray( int v) { byte[] tmp = new byte[4]; int size = 0; for (int i = 0; i != 4; i++) { tmp[i] = (byte)(v >> (i * 8)); if (tmp[i] != 0) { size = i; } } byte[] data = new byte[size + 1]; System.arraycopy(tmp, 0, data, 0, data.length); return data; } public KeyFlags( boolean critical, byte[] data) { super(SignatureSubpacketTags.KEY_FLAGS, critical, data); } public KeyFlags( boolean critical, int flags) { super(SignatureSubpacketTags.KEY_FLAGS, critical, intToByteArray(flags)); } /** * Return the flag values contained in the first 4 octets (note: at the moment * the standard only uses the first one). * * @return flag values. */ public int getFlags() { int flags = 0; for (int i = 0; i != data.length; i++) { flags |= (data[i] & 0xff) << (i * 8); } return flags; } } bouncycastle-1.49.orig/src/org/bouncycastle/bcpg/sig/RevocationReason.java0000644000175000017500000000262211604525611026326 0ustar ebourgebourgpackage org.bouncycastle.bcpg.sig; import org.bouncycastle.bcpg.SignatureSubpacket; import org.bouncycastle.bcpg.SignatureSubpacketTags; import org.bouncycastle.util.Strings; /** * Represents revocation reason OpenPGP signature sub packet. */ public class RevocationReason extends SignatureSubpacket { public RevocationReason(boolean isCritical, byte[] data) { super(SignatureSubpacketTags.REVOCATION_REASON, isCritical, data); } public RevocationReason(boolean isCritical, byte reason, String description) { super(SignatureSubpacketTags.REVOCATION_REASON, isCritical, createData(reason, description)); } private static byte[] createData(byte reason, String description) { byte[] descriptionBytes = Strings.toUTF8ByteArray(description); byte[] data = new byte[1 + descriptionBytes.length]; data[0] = reason; System.arraycopy(descriptionBytes, 0, data, 1, descriptionBytes.length); return data; } public byte getRevocationReason() { return getData()[0]; } public String getRevocationDescription() { byte[] data = getData(); if (data.length == 1) { return ""; } byte[] description = new byte[data.length - 1]; System.arraycopy(data, 1, description, 0, description.length); return Strings.fromUTF8ByteArray(description); } } bouncycastle-1.49.orig/src/org/bouncycastle/bcpg/sig/KeyExpirationTime.java0000644000175000017500000000236210262753175026467 0ustar ebourgebourgpackage org.bouncycastle.bcpg.sig; import org.bouncycastle.bcpg.SignatureSubpacket; import org.bouncycastle.bcpg.SignatureSubpacketTags; /** * packet giving time after creation at which the key expires. */ public class KeyExpirationTime extends SignatureSubpacket { protected static byte[] timeToBytes( long t) { byte[] data = new byte[4]; data[0] = (byte)(t >> 24); data[1] = (byte)(t >> 16); data[2] = (byte)(t >> 8); data[3] = (byte)t; return data; } public KeyExpirationTime( boolean critical, byte[] data) { super(SignatureSubpacketTags.KEY_EXPIRE_TIME, critical, data); } public KeyExpirationTime( boolean critical, long seconds) { super(SignatureSubpacketTags.KEY_EXPIRE_TIME, critical, timeToBytes(seconds)); } /** * Return the number of seconds after creation time a key is valid for. * * @return second count for key validity. */ public long getTime() { long time = ((long)(data[0] & 0xff) << 24) | ((data[1] & 0xff) << 16) | ((data[2] & 0xff) << 8) | (data[3] & 0xff); return time; } } bouncycastle-1.49.orig/src/org/bouncycastle/bcpg/sig/Features.java0000644000175000017500000000505512151551721024625 0ustar ebourgebourgpackage org.bouncycastle.bcpg.sig; import org.bouncycastle.bcpg.SignatureSubpacket; import org.bouncycastle.bcpg.SignatureSubpacketTags; public class Features extends SignatureSubpacket { /** Identifier for the modification detection feature */ public static final byte FEATURE_MODIFICATION_DETECTION = 1; private static final byte[] featureToByteArray(byte feature) { byte[] data = new byte[1]; data[0] = feature; return data; } public Features(boolean critical, byte[] data) { super(SignatureSubpacketTags.FEATURES, critical, data); } public Features(boolean critical, byte feature) { super(SignatureSubpacketTags.FEATURES, critical, featureToByteArray(feature)); } /** * Returns if modification detection is supported. */ public boolean supportsModificationDetection() { return supportsFeature(FEATURE_MODIFICATION_DETECTION); } // /** Class should be immutable. // * Set modification detection support. // */ // public void setSupportsModificationDetection(boolean support) // { // setSupportsFeature(FEATURE_MODIFICATION_DETECTION, support); // } /** * Returns if a particular feature is supported. */ public boolean supportsFeature(byte feature) { for (int i = 0; i < data.length; i++) { if (data[i] == feature) { return true; } } return false; } /** * Sets support for a particular feature. */ private void setSupportsFeature(byte feature, boolean support) { if (feature == 0) { throw new IllegalArgumentException("feature == 0"); } if (supportsFeature(feature) != support) { if (support == true) { byte[] temp = new byte[data.length + 1]; System.arraycopy(data, 0, temp, 0, data.length); temp[data.length] = feature; data = temp; } else { for (int i = 0; i < data.length; i++) { if (data[i] == feature) { byte[] temp = new byte[data.length - 1]; System.arraycopy(data, 0, temp, 0, i); System.arraycopy(data, i + 1, temp, i, temp.length - i); data = temp; break; } } } } } } bouncycastle-1.49.orig/src/org/bouncycastle/bcpg/sig/RevocationKey.java0000644000175000017500000000274211604525611025632 0ustar ebourgebourgpackage org.bouncycastle.bcpg.sig; import org.bouncycastle.bcpg.SignatureSubpacket; import org.bouncycastle.bcpg.SignatureSubpacketTags; /** * Represents revocation key OpenPGP signature sub packet. */ public class RevocationKey extends SignatureSubpacket { // 1 octet of class, // 1 octet of public-key algorithm ID, // 20 octets of fingerprint public RevocationKey(boolean isCritical, byte[] data) { super(SignatureSubpacketTags.REVOCATION_KEY, isCritical, data); } public RevocationKey(boolean isCritical, byte signatureClass, int keyAlgorithm, byte[] fingerprint) { super(SignatureSubpacketTags.REVOCATION_KEY, isCritical, createData(signatureClass, (byte)(keyAlgorithm & 0xff), fingerprint)); } private static byte[] createData(byte signatureClass, byte keyAlgorithm, byte[] fingerprint) { byte[] data = new byte[2 + fingerprint.length]; data[0] = signatureClass; data[1] = keyAlgorithm; System.arraycopy(fingerprint, 0, data, 2, fingerprint.length); return data; } public byte getSignatureClass() { return this.getData()[0]; } public int getAlgorithm() { return this.getData()[1]; } public byte[] getFingerprint() { byte[] data = this.getData(); byte[] fingerprint = new byte[data.length - 2]; System.arraycopy(data, 2, fingerprint, 0, fingerprint.length); return fingerprint; } } bouncycastle-1.49.orig/src/org/bouncycastle/bcpg/sig/PreferredAlgorithms.java0000644000175000017500000000223511251332510027005 0ustar ebourgebourgpackage org.bouncycastle.bcpg.sig; import org.bouncycastle.bcpg.SignatureSubpacket; /** * packet giving signature creation time. */ public class PreferredAlgorithms extends SignatureSubpacket { private static byte[] intToByteArray( int[] v) { byte[] data = new byte[v.length]; for (int i = 0; i != v.length; i++) { data[i] = (byte)v[i]; } return data; } public PreferredAlgorithms( int type, boolean critical, byte[] data) { super(type, critical, data); } public PreferredAlgorithms( int type, boolean critical, int[] preferrences) { super(type, critical, intToByteArray(preferrences)); } /** * @deprecated mispelt! */ public int[] getPreferrences() { return getPreferences(); } public int[] getPreferences() { int[] v = new int[data.length]; for (int i = 0; i != v.length; i++) { v[i] = data[i] & 0xff; } return v; } } bouncycastle-1.49.orig/src/org/bouncycastle/bcpg/sig/SignatureExpirationTime.java0000644000175000017500000000226510262753175027702 0ustar ebourgebourgpackage org.bouncycastle.bcpg.sig; import org.bouncycastle.bcpg.SignatureSubpacket; import org.bouncycastle.bcpg.SignatureSubpacketTags; /** * packet giving signature expiration time. */ public class SignatureExpirationTime extends SignatureSubpacket { protected static byte[] timeToBytes( long t) { byte[] data = new byte[4]; data[0] = (byte)(t >> 24); data[1] = (byte)(t >> 16); data[2] = (byte)(t >> 8); data[3] = (byte)t; return data; } public SignatureExpirationTime( boolean critical, byte[] data) { super(SignatureSubpacketTags.EXPIRE_TIME, critical, data); } public SignatureExpirationTime( boolean critical, long seconds) { super(SignatureSubpacketTags.EXPIRE_TIME, critical, timeToBytes(seconds)); } /** * return time in seconds before signature expires after creation time. */ public long getTime() { long time = ((long)(data[0] & 0xff) << 24) | ((data[1] & 0xff) << 16) | ((data[2] & 0xff) << 8) | (data[3] & 0xff); return time; } } bouncycastle-1.49.orig/src/org/bouncycastle/bcpg/sig/RevocationReasonTags.java0000644000175000017500000000123011604525611027137 0ustar ebourgebourgpackage org.bouncycastle.bcpg.sig; public interface RevocationReasonTags { public static final byte NO_REASON = 0; // No reason specified (key revocations or cert revocations) public static final byte KEY_SUPERSEDED = 1; // Key is superseded (key revocations) public static final byte KEY_COMPROMISED = 2; // Key material has been compromised (key revocations) public static final byte KEY_RETIRED = 3; // Key is retired and no longer used (key revocations) public static final byte USER_NO_LONGER_VALID = 32; // User ID information is no longer valid (cert revocations) // 100-110 - Private Use } bouncycastle-1.49.orig/src/org/bouncycastle/bcpg/sig/PrimaryUserID.java0000644000175000017500000000203411251332510025531 0ustar ebourgebourgpackage org.bouncycastle.bcpg.sig; import org.bouncycastle.bcpg.SignatureSubpacket; import org.bouncycastle.bcpg.SignatureSubpacketTags; /** * packet giving whether or not the signature is signed using the primary user ID for the key. */ public class PrimaryUserID extends SignatureSubpacket { private static byte[] booleanToByteArray( boolean value) { byte[] data = new byte[1]; if (value) { data[0] = 1; return data; } else { return data; } } public PrimaryUserID( boolean critical, byte[] data) { super(SignatureSubpacketTags.PRIMARY_USER_ID, critical, data); } public PrimaryUserID( boolean critical, boolean isPrimaryUserID) { super(SignatureSubpacketTags.PRIMARY_USER_ID, critical, booleanToByteArray(isPrimaryUserID)); } public boolean isPrimaryUserID() { return data[0] != 0; } } bouncycastle-1.49.orig/src/org/bouncycastle/bcpg/sig/Exportable.java0000644000175000017500000000170711251332510025145 0ustar ebourgebourgpackage org.bouncycastle.bcpg.sig; import org.bouncycastle.bcpg.SignatureSubpacket; import org.bouncycastle.bcpg.SignatureSubpacketTags; /** * packet giving signature creation time. */ public class Exportable extends SignatureSubpacket { private static byte[] booleanToByteArray( boolean value) { byte[] data = new byte[1]; if (value) { data[0] = 1; return data; } else { return data; } } public Exportable( boolean critical, byte[] data) { super(SignatureSubpacketTags.EXPORTABLE, critical, data); } public Exportable( boolean critical, boolean isExportable) { super(SignatureSubpacketTags.EXPORTABLE, critical, booleanToByteArray(isExportable)); } public boolean isExportable() { return data[0] != 0; } } bouncycastle-1.49.orig/src/org/bouncycastle/bcpg/sig/NotationData.java0000644000175000017500000000620311061700122025416 0ustar ebourgebourgpackage org.bouncycastle.bcpg.sig; import org.bouncycastle.bcpg.SignatureSubpacket; import org.bouncycastle.bcpg.SignatureSubpacketTags; import org.bouncycastle.util.Strings; import java.io.ByteArrayOutputStream; /** * Class provided a NotationData object according to * RFC2440, Chapter 5.2.3.15. Notation Data */ public class NotationData extends SignatureSubpacket { public static final int HEADER_FLAG_LENGTH = 4; public static final int HEADER_NAME_LENGTH = 2; public static final int HEADER_VALUE_LENGTH = 2; public NotationData(boolean critical, byte[] data) { super(SignatureSubpacketTags.NOTATION_DATA, critical, data); } public NotationData( boolean critical, boolean humanReadable, String notationName, String notationValue) { super(SignatureSubpacketTags.NOTATION_DATA, critical, createData(humanReadable, notationName, notationValue)); } private static byte[] createData(boolean humanReadable, String notationName, String notationValue) { ByteArrayOutputStream out = new ByteArrayOutputStream(); // (4 octets of flags, 2 octets of name length (M), // 2 octets of value length (N), // M octets of name data, // N octets of value data) // flags out.write(humanReadable ? 0x80 : 0x00); out.write(0x0); out.write(0x0); out.write(0x0); byte[] nameData, valueData = null; int nameLength, valueLength; nameData = Strings.toUTF8ByteArray(notationName); nameLength = Math.min(nameData.length, 0xFF); valueData = Strings.toUTF8ByteArray(notationValue); valueLength = Math.min(valueData.length, 0xFF); // name length out.write((nameLength >>> 8) & 0xFF); out.write((nameLength >>> 0) & 0xFF); // value length out.write((valueLength >>> 8) & 0xFF); out.write((valueLength >>> 0) & 0xFF); // name out.write(nameData, 0, nameLength); // value out.write(valueData, 0, valueLength); return out.toByteArray(); } public boolean isHumanReadable() { return data[0] == (byte)0x80; } public String getNotationName() { int nameLength = ((data[HEADER_FLAG_LENGTH] << 8) + (data[HEADER_FLAG_LENGTH + 1] << 0)); byte bName[] = new byte[nameLength]; System.arraycopy(data, HEADER_FLAG_LENGTH + HEADER_NAME_LENGTH + HEADER_VALUE_LENGTH, bName, 0, nameLength); return Strings.fromUTF8ByteArray(bName); } public String getNotationValue() { return Strings.fromUTF8ByteArray(getNotationValueBytes()); } public byte[] getNotationValueBytes() { int nameLength = ((data[HEADER_FLAG_LENGTH] << 8) + (data[HEADER_FLAG_LENGTH + 1] << 0)); int valueLength = ((data[HEADER_FLAG_LENGTH + HEADER_NAME_LENGTH] << 8) + (data[HEADER_FLAG_LENGTH + HEADER_NAME_LENGTH + 1] << 0)); byte bValue[] = new byte[valueLength]; System.arraycopy(data, HEADER_FLAG_LENGTH + HEADER_NAME_LENGTH + HEADER_VALUE_LENGTH + nameLength, bValue, 0, valueLength); return bValue; } } bouncycastle-1.49.orig/src/org/bouncycastle/bcpg/sig/RevocationKeyTags.java0000644000175000017500000000030011604525611026435 0ustar ebourgebourgpackage org.bouncycastle.bcpg.sig; public interface RevocationKeyTags { public static final byte CLASS_DEFAULT = (byte)0x80; public static final byte CLASS_SENSITIVE = (byte)0x40; } bouncycastle-1.49.orig/src/org/bouncycastle/bcpg/sig/TrustSignature.java0000644000175000017500000000175711251332510026050 0ustar ebourgebourgpackage org.bouncycastle.bcpg.sig; import org.bouncycastle.bcpg.SignatureSubpacket; import org.bouncycastle.bcpg.SignatureSubpacketTags; /** * packet giving trust. */ public class TrustSignature extends SignatureSubpacket { private static byte[] intToByteArray( int v1, int v2) { byte[] data = new byte[2]; data[0] = (byte)v1; data[1] = (byte)v2; return data; } public TrustSignature( boolean critical, byte[] data) { super(SignatureSubpacketTags.TRUST_SIG, critical, data); } public TrustSignature( boolean critical, int depth, int trustAmount) { super(SignatureSubpacketTags.TRUST_SIG, critical, intToByteArray(depth, trustAmount)); } public int getDepth() { return data[0] & 0xff; } public int getTrustAmount() { return data[1] & 0xff; } } bouncycastle-1.49.orig/src/org/bouncycastle/bcpg/sig/SignatureCreationTime.java0000644000175000017500000000225010262753175027316 0ustar ebourgebourgpackage org.bouncycastle.bcpg.sig; import java.util.Date; import org.bouncycastle.bcpg.SignatureSubpacket; import org.bouncycastle.bcpg.SignatureSubpacketTags; /** * packet giving signature creation time. */ public class SignatureCreationTime extends SignatureSubpacket { protected static byte[] timeToBytes( Date date) { byte[] data = new byte[4]; long t = date.getTime() / 1000; data[0] = (byte)(t >> 24); data[1] = (byte)(t >> 16); data[2] = (byte)(t >> 8); data[3] = (byte)t; return data; } public SignatureCreationTime( boolean critical, byte[] data) { super(SignatureSubpacketTags.CREATION_TIME, critical, data); } public SignatureCreationTime( boolean critical, Date date) { super(SignatureSubpacketTags.CREATION_TIME, critical, timeToBytes(date)); } public Date getTime() { long time = ((long)(data[0] & 0xff) << 24) | ((data[1] & 0xff) << 16) | ((data[2] & 0xff) << 8) | (data[3] & 0xff); return new Date(time * 1000); } } bouncycastle-1.49.orig/src/org/bouncycastle/bcpg/sig/IssuerKeyID.java0000644000175000017500000000261210262753175025213 0ustar ebourgebourgpackage org.bouncycastle.bcpg.sig; import org.bouncycastle.bcpg.SignatureSubpacket; import org.bouncycastle.bcpg.SignatureSubpacketTags; /** * packet giving signature creation time. */ public class IssuerKeyID extends SignatureSubpacket { protected static byte[] keyIDToBytes( long keyId) { byte[] data = new byte[8]; data[0] = (byte)(keyId >> 56); data[1] = (byte)(keyId >> 48); data[2] = (byte)(keyId >> 40); data[3] = (byte)(keyId >> 32); data[4] = (byte)(keyId >> 24); data[5] = (byte)(keyId >> 16); data[6] = (byte)(keyId >> 8); data[7] = (byte)keyId; return data; } public IssuerKeyID( boolean critical, byte[] data) { super(SignatureSubpacketTags.ISSUER_KEY_ID, critical, data); } public IssuerKeyID( boolean critical, long keyID) { super(SignatureSubpacketTags.ISSUER_KEY_ID, critical, keyIDToBytes(keyID)); } public long getKeyID() { long keyID = ((long)(data[0] & 0xff) << 56) | ((long)(data[1] & 0xff) << 48) | ((long)(data[2] & 0xff) << 40) | ((long)(data[3] & 0xff) << 32) | ((long)(data[4] & 0xff) << 24) | ((data[5] & 0xff) << 16) | ((data[6] & 0xff) << 8) | (data[7] & 0xff); return keyID; } } bouncycastle-1.49.orig/src/org/bouncycastle/bcpg/sig/package.html0000644000175000017500000000016110262753175024466 0ustar ebourgebourg Low level classes for dealing with OpenPGP signature attributes. bouncycastle-1.49.orig/src/org/bouncycastle/bcpg/sig/SignerUserID.java0000644000175000017500000000216510262753175025361 0ustar ebourgebourgpackage org.bouncycastle.bcpg.sig; import org.bouncycastle.bcpg.SignatureSubpacket; import org.bouncycastle.bcpg.SignatureSubpacketTags; /** * packet giving the User ID of the signer. */ public class SignerUserID extends SignatureSubpacket { private static byte[] userIDToBytes( String id) { byte[] idData = new byte[id.length()]; for (int i = 0; i != id.length(); i++) { idData[i] = (byte)id.charAt(i); } return idData; } public SignerUserID( boolean critical, byte[] data) { super(SignatureSubpacketTags.SIGNER_USER_ID, critical, data); } public SignerUserID( boolean critical, String userID) { super(SignatureSubpacketTags.SIGNER_USER_ID, critical, userIDToBytes(userID)); } public String getID() { char[] chars = new char[data.length]; for (int i = 0; i != chars.length; i++) { chars[i] = (char)(data[i] & 0xff); } return new String(chars); } } bouncycastle-1.49.orig/src/org/bouncycastle/bcpg/Packet.java0000644000175000017500000000013310262753175023474 0ustar ebourgebourgpackage org.bouncycastle.bcpg; /** */ public class Packet implements PacketTags { } bouncycastle-1.49.orig/src/org/bouncycastle/bcpg/DSAPublicBCPGKey.java0000644000175000017500000000424210535262032025133 0ustar ebourgebourgpackage org.bouncycastle.bcpg; import java.io.*; import java.math.BigInteger; /** * base class for a DSA Public Key. */ public class DSAPublicBCPGKey extends BCPGObject implements BCPGKey { MPInteger p; MPInteger q; MPInteger g; MPInteger y; /** * @param in the stream to read the packet from. */ public DSAPublicBCPGKey( BCPGInputStream in) throws IOException { this.p = new MPInteger(in); this.q = new MPInteger(in); this.g = new MPInteger(in); this.y = new MPInteger(in); } public DSAPublicBCPGKey( BigInteger p, BigInteger q, BigInteger g, BigInteger y) { this.p = new MPInteger(p); this.q = new MPInteger(q); this.g = new MPInteger(g); this.y = new MPInteger(y); } /** * return "PGP" * * @see org.bouncycastle.bcpg.BCPGKey#getFormat() */ public String getFormat() { return "PGP"; } /** * return the standard PGP encoding of the key. * * @see org.bouncycastle.bcpg.BCPGKey#getEncoded() */ public byte[] getEncoded() { try { ByteArrayOutputStream bOut = new ByteArrayOutputStream(); BCPGOutputStream pgpOut = new BCPGOutputStream(bOut); pgpOut.writeObject(this); return bOut.toByteArray(); } catch (IOException e) { return null; } } public void encode( BCPGOutputStream out) throws IOException { out.writeObject(p); out.writeObject(q); out.writeObject(g); out.writeObject(y); } /** * @return g */ public BigInteger getG() { return g.getValue(); } /** * @return p */ public BigInteger getP() { return p.getValue(); } /** * @return q */ public BigInteger getQ() { return q.getValue(); } /** * @return g */ public BigInteger getY() { return y.getValue(); } } bouncycastle-1.49.orig/src/org/bouncycastle/bcpg/PublicSubkeyPacket.java0000644000175000017500000000137410262753175026026 0ustar ebourgebourgpackage org.bouncycastle.bcpg; import java.io.*; import java.util.Date; /** * basic packet for a PGP public key */ public class PublicSubkeyPacket extends PublicKeyPacket { PublicSubkeyPacket( BCPGInputStream in) throws IOException { super(in); } /** * Construct version 4 public key packet. * * @param algorithm * @param time * @param key */ public PublicSubkeyPacket( int algorithm, Date time, BCPGKey key) { super(algorithm, time, key); } public void encode( BCPGOutputStream out) throws IOException { out.writePacket(PUBLIC_SUBKEY, getEncodedContents(), true); } } bouncycastle-1.49.orig/src/org/bouncycastle/bcpg/TrustPacket.java0000644000175000017500000000177510574410741024546 0ustar ebourgebourgpackage org.bouncycastle.bcpg; import java.io.ByteArrayOutputStream; import java.io.IOException; /** * Basic type for a trust packet */ public class TrustPacket extends ContainedPacket { byte[] levelAndTrustAmount; public TrustPacket( BCPGInputStream in) throws IOException { ByteArrayOutputStream bOut = new ByteArrayOutputStream(); int ch; while ((ch = in.read()) >= 0) { bOut.write(ch); } levelAndTrustAmount = bOut.toByteArray(); } public TrustPacket( int trustCode) { this.levelAndTrustAmount = new byte[1]; this.levelAndTrustAmount[0] = (byte)trustCode; } public byte[] getLevelAndTrustAmount() { return levelAndTrustAmount; } public void encode( BCPGOutputStream out) throws IOException { out.writePacket(TRUST, levelAndTrustAmount, true); } } bouncycastle-1.49.orig/src/org/bouncycastle/bcpg/UserIDPacket.java0000644000175000017500000000132412132365553024550 0ustar ebourgebourgpackage org.bouncycastle.bcpg; import java.io.IOException; import org.bouncycastle.util.Strings; /** * Basic type for a user ID packet. */ public class UserIDPacket extends ContainedPacket { private byte[] idData; public UserIDPacket( BCPGInputStream in) throws IOException { this.idData = in.readAll(); } public UserIDPacket( String id) { this.idData = Strings.toUTF8ByteArray(id); } public String getID() { return Strings.fromUTF8ByteArray(idData); } public void encode( BCPGOutputStream out) throws IOException { out.writePacket(USER_ID, idData, true); } } bouncycastle-1.49.orig/src/org/bouncycastle/bcpg/SecretSubkeyPacket.java0000644000175000017500000000236010503732355026024 0ustar ebourgebourgpackage org.bouncycastle.bcpg; import java.io.*; /** * basic packet for a PGP secret key */ public class SecretSubkeyPacket extends SecretKeyPacket { /** * * @param in * @throws IOException */ SecretSubkeyPacket( BCPGInputStream in) throws IOException { super(in); } /** * * @param pubKeyPacket * @param encAlgorithm * @param s2k * @param iv * @param secKeyData */ public SecretSubkeyPacket( PublicKeyPacket pubKeyPacket, int encAlgorithm, S2K s2k, byte[] iv, byte[] secKeyData) { super(pubKeyPacket, encAlgorithm, s2k, iv, secKeyData); } public SecretSubkeyPacket( PublicKeyPacket pubKeyPacket, int encAlgorithm, int s2kUsage, S2K s2k, byte[] iv, byte[] secKeyData) { super(pubKeyPacket, encAlgorithm, s2kUsage, s2k, iv, secKeyData); } public void encode( BCPGOutputStream out) throws IOException { out.writePacket(SECRET_SUBKEY, getEncodedContents(), true); } } bouncycastle-1.49.orig/src/org/bouncycastle/bcpg/ArmoredOutputStream.java0000644000175000017500000002471012151274313026251 0ustar ebourgebourgpackage org.bouncycastle.bcpg; import java.io.IOException; import java.io.OutputStream; import java.util.Enumeration; import java.util.Hashtable; /** * Basic output stream. */ public class ArmoredOutputStream extends OutputStream { private static final byte[] encodingTable = { (byte)'A', (byte)'B', (byte)'C', (byte)'D', (byte)'E', (byte)'F', (byte)'G', (byte)'H', (byte)'I', (byte)'J', (byte)'K', (byte)'L', (byte)'M', (byte)'N', (byte)'O', (byte)'P', (byte)'Q', (byte)'R', (byte)'S', (byte)'T', (byte)'U', (byte)'V', (byte)'W', (byte)'X', (byte)'Y', (byte)'Z', (byte)'a', (byte)'b', (byte)'c', (byte)'d', (byte)'e', (byte)'f', (byte)'g', (byte)'h', (byte)'i', (byte)'j', (byte)'k', (byte)'l', (byte)'m', (byte)'n', (byte)'o', (byte)'p', (byte)'q', (byte)'r', (byte)'s', (byte)'t', (byte)'u', (byte)'v', (byte)'w', (byte)'x', (byte)'y', (byte)'z', (byte)'0', (byte)'1', (byte)'2', (byte)'3', (byte)'4', (byte)'5', (byte)'6', (byte)'7', (byte)'8', (byte)'9', (byte)'+', (byte)'/' }; /** * encode the input data producing a base 64 encoded byte array. */ private void encode( OutputStream out, int[] data, int len) throws IOException { int d1, d2, d3; switch (len) { case 0: /* nothing left to do */ break; case 1: d1 = data[0]; out.write(encodingTable[(d1 >>> 2) & 0x3f]); out.write(encodingTable[(d1 << 4) & 0x3f]); out.write('='); out.write('='); break; case 2: d1 = data[0]; d2 = data[1]; out.write(encodingTable[(d1 >>> 2) & 0x3f]); out.write(encodingTable[((d1 << 4) | (d2 >>> 4)) & 0x3f]); out.write(encodingTable[(d2 << 2) & 0x3f]); out.write('='); break; case 3: d1 = data[0]; d2 = data[1]; d3 = data[2]; out.write(encodingTable[(d1 >>> 2) & 0x3f]); out.write(encodingTable[((d1 << 4) | (d2 >>> 4)) & 0x3f]); out.write(encodingTable[((d2 << 2) | (d3 >>> 6)) & 0x3f]); out.write(encodingTable[d3 & 0x3f]); break; default: throw new IOException("unknown length in encode"); } } OutputStream out; int[] buf = new int[3]; int bufPtr = 0; CRC24 crc = new CRC24(); int chunkCount = 0; int lastb; boolean start = true; boolean clearText = false; boolean newLine = false; String nl = System.getProperty("line.separator"); String type; String headerStart = "-----BEGIN PGP "; String headerTail = "-----"; String footerStart = "-----END PGP "; String footerTail = "-----"; String version = "BCPG v@RELEASE_NAME@"; Hashtable headers = new Hashtable(); public ArmoredOutputStream( OutputStream out) { this.out = out; if (nl == null) { nl = "\r\n"; } resetHeaders(); } public ArmoredOutputStream( OutputStream out, Hashtable headers) { this(out); Enumeration e = headers.keys(); while (e.hasMoreElements()) { Object key = e.nextElement(); this.headers.put(key, headers.get(key)); } } /** * Set an additional header entry. * * @param name the name of the header entry. * @param value the value of the header entry. */ public void setHeader( String name, String value) { this.headers.put(name, value); } /** * Reset the headers to only contain a Version string. */ public void resetHeaders() { headers.clear(); headers.put("Version", version); } /** * Start a clear text signed message. * @param hashAlgorithm */ public void beginClearText( int hashAlgorithm) throws IOException { String hash; switch (hashAlgorithm) { case HashAlgorithmTags.SHA1: hash = "SHA1"; break; case HashAlgorithmTags.SHA256: hash = "SHA256"; break; case HashAlgorithmTags.SHA384: hash = "SHA384"; break; case HashAlgorithmTags.SHA512: hash = "SHA512"; break; case HashAlgorithmTags.MD2: hash = "MD2"; break; case HashAlgorithmTags.MD5: hash = "MD5"; break; case HashAlgorithmTags.RIPEMD160: hash = "RIPEMD160"; break; default: throw new IOException("unknown hash algorithm tag in beginClearText: " + hashAlgorithm); } String armorHdr = "-----BEGIN PGP SIGNED MESSAGE-----" + nl; String hdrs = "Hash: " + hash + nl + nl; for (int i = 0; i != armorHdr.length(); i++) { out.write(armorHdr.charAt(i)); } for (int i = 0; i != hdrs.length(); i++) { out.write(hdrs.charAt(i)); } clearText = true; newLine = true; lastb = 0; } public void endClearText() { clearText = false; } private void writeHeaderEntry( String name, String value) throws IOException { for (int i = 0; i != name.length(); i++) { out.write(name.charAt(i)); } out.write(':'); out.write(' '); for (int i = 0; i != value.length(); i++) { out.write(value.charAt(i)); } for (int i = 0; i != nl.length(); i++) { out.write(nl.charAt(i)); } } public void write( int b) throws IOException { if (clearText) { out.write(b); if (newLine) { if (!(b == '\n' && lastb == '\r')) { newLine = false; } if (b == '-') { out.write(' '); out.write('-'); // dash escape } } if (b == '\r' || (b == '\n' && lastb != '\r')) { newLine = true; } lastb = b; return; } if (start) { boolean newPacket = (b & 0x40) != 0; int tag = 0; if (newPacket) { tag = b & 0x3f; } else { tag = (b & 0x3f) >> 2; } switch (tag) { case PacketTags.PUBLIC_KEY: type = "PUBLIC KEY BLOCK"; break; case PacketTags.SECRET_KEY: type = "PRIVATE KEY BLOCK"; break; case PacketTags.SIGNATURE: type = "SIGNATURE"; break; default: type = "MESSAGE"; } for (int i = 0; i != headerStart.length(); i++) { out.write(headerStart.charAt(i)); } for (int i = 0; i != type.length(); i++) { out.write(type.charAt(i)); } for (int i = 0; i != headerTail.length(); i++) { out.write(headerTail.charAt(i)); } for (int i = 0; i != nl.length(); i++) { out.write(nl.charAt(i)); } writeHeaderEntry("Version", (String)headers.get("Version")); Enumeration e = headers.keys(); while (e.hasMoreElements()) { String key = (String)e.nextElement(); if (!key.equals("Version")) { writeHeaderEntry(key, (String)headers.get(key)); } } for (int i = 0; i != nl.length(); i++) { out.write(nl.charAt(i)); } start = false; } if (bufPtr == 3) { encode(out, buf, bufPtr); bufPtr = 0; if ((++chunkCount & 0xf) == 0) { for (int i = 0; i != nl.length(); i++) { out.write(nl.charAt(i)); } } } crc.update(b); buf[bufPtr++] = b & 0xff; } public void flush() throws IOException { } /** * Note: close does nor close the underlying stream. So it is possible to write * multiple objects using armoring to a single stream. */ public void close() throws IOException { if (type != null) { encode(out, buf, bufPtr); for (int i = 0; i != nl.length(); i++) { out.write(nl.charAt(i)); } out.write('='); int crcV = crc.getValue(); buf[0] = ((crcV >> 16) & 0xff); buf[1] = ((crcV >> 8) & 0xff); buf[2] = (crcV & 0xff); encode(out, buf, 3); for (int i = 0; i != nl.length(); i++) { out.write(nl.charAt(i)); } for (int i = 0; i != footerStart.length(); i++) { out.write(footerStart.charAt(i)); } for (int i = 0; i != type.length(); i++) { out.write(type.charAt(i)); } for (int i = 0; i != footerTail.length(); i++) { out.write(footerTail.charAt(i)); } for (int i = 0; i != nl.length(); i++) { out.write(nl.charAt(i)); } out.flush(); type = null; start = true; } } } bouncycastle-1.49.orig/src/org/bouncycastle/bcpg/SymmetricKeyEncSessionPacket.java0000644000175000017500000000346212132365674030045 0ustar ebourgebourgpackage org.bouncycastle.bcpg; import java.io.ByteArrayOutputStream; import java.io.IOException; /** * Basic type for a symmetric encrypted session key packet */ public class SymmetricKeyEncSessionPacket extends ContainedPacket { private int version; private int encAlgorithm; private S2K s2k; private byte[] secKeyData; public SymmetricKeyEncSessionPacket( BCPGInputStream in) throws IOException { version = in.read(); encAlgorithm = in.read(); s2k = new S2K(in); this.secKeyData = in.readAll(); } public SymmetricKeyEncSessionPacket( int encAlgorithm, S2K s2k, byte[] secKeyData) { this.version = 4; this.encAlgorithm = encAlgorithm; this.s2k = s2k; this.secKeyData = secKeyData; } /** * @return int */ public int getEncAlgorithm() { return encAlgorithm; } /** * @return S2K */ public S2K getS2K() { return s2k; } /** * @return byte[] */ public byte[] getSecKeyData() { return secKeyData; } /** * @return int */ public int getVersion() { return version; } public void encode( BCPGOutputStream out) throws IOException { ByteArrayOutputStream bOut = new ByteArrayOutputStream(); BCPGOutputStream pOut = new BCPGOutputStream(bOut); pOut.write(version); pOut.write(encAlgorithm); pOut.writeObject(s2k); if (secKeyData != null && secKeyData.length > 0) { pOut.write(secKeyData); } out.writePacket(SYMMETRIC_KEY_ENC_SESSION, bOut.toByteArray(), true); } } bouncycastle-1.49.orig/src/org/bouncycastle/bcpg/ArmoredInputStream.java0000644000175000017500000002703412151274313026052 0ustar ebourgebourgpackage org.bouncycastle.bcpg; import java.io.EOFException; import java.io.IOException; import java.io.InputStream; import java.util.Vector; /** * reader for Base64 armored objects - read the headers and then start returning * bytes when the data is reached. An IOException is thrown if the CRC check * fails. */ public class ArmoredInputStream extends InputStream { /* * set up the decoding table. */ private static final byte[] decodingTable; static { decodingTable = new byte[128]; for (int i = 'A'; i <= 'Z'; i++) { decodingTable[i] = (byte)(i - 'A'); } for (int i = 'a'; i <= 'z'; i++) { decodingTable[i] = (byte)(i - 'a' + 26); } for (int i = '0'; i <= '9'; i++) { decodingTable[i] = (byte)(i - '0' + 52); } decodingTable['+'] = 62; decodingTable['/'] = 63; } /** * decode the base 64 encoded input data. * * @return the offset the data starts in out. */ private int decode( int in0, int in1, int in2, int in3, int[] out) throws EOFException { int b1, b2, b3, b4; if (in3 < 0) { throw new EOFException("unexpected end of file in armored stream."); } if (in2 == '=') { b1 = decodingTable[in0] &0xff; b2 = decodingTable[in1] & 0xff; out[2] = ((b1 << 2) | (b2 >> 4)) & 0xff; return 2; } else if (in3 == '=') { b1 = decodingTable[in0]; b2 = decodingTable[in1]; b3 = decodingTable[in2]; out[1] = ((b1 << 2) | (b2 >> 4)) & 0xff; out[2] = ((b2 << 4) | (b3 >> 2)) & 0xff; return 1; } else { b1 = decodingTable[in0]; b2 = decodingTable[in1]; b3 = decodingTable[in2]; b4 = decodingTable[in3]; out[0] = ((b1 << 2) | (b2 >> 4)) & 0xff; out[1] = ((b2 << 4) | (b3 >> 2)) & 0xff; out[2] = ((b3 << 6) | b4) & 0xff; return 0; } } InputStream in; boolean start = true; int[] outBuf = new int[3]; int bufPtr = 3; CRC24 crc = new CRC24(); boolean crcFound = false; boolean hasHeaders = true; String header = null; boolean newLineFound = false; boolean clearText = false; boolean restart = false; Vector headerList= new Vector(); int lastC = 0; boolean isEndOfStream; /** * Create a stream for reading a PGP armoured message, parsing up to a header * and then reading the data that follows. * * @param in */ public ArmoredInputStream( InputStream in) throws IOException { this(in, true); } /** * Create an armoured input stream which will assume the data starts * straight away, or parse for headers first depending on the value of * hasHeaders. * * @param in * @param hasHeaders true if headers are to be looked for, false otherwise. */ public ArmoredInputStream( InputStream in, boolean hasHeaders) throws IOException { this.in = in; this.hasHeaders = hasHeaders; if (hasHeaders) { parseHeaders(); } start = false; } public int available() throws IOException { return in.available(); } private boolean parseHeaders() throws IOException { header = null; int c; int last = 0; boolean headerFound = false; headerList = new Vector(); // // if restart we already have a header // if (restart) { headerFound = true; } else { while ((c = in.read()) >= 0) { if (c == '-' && (last == 0 || last == '\n' || last == '\r')) { headerFound = true; break; } last = c; } } if (headerFound) { StringBuffer buf = new StringBuffer("-"); boolean eolReached = false; boolean crLf = false; if (restart) // we've had to look ahead two '-' { buf.append('-'); } while ((c = in.read()) >= 0) { if (last == '\r' && c == '\n') { crLf = true; } if (eolReached && (last != '\r' && c == '\n')) { break; } if (eolReached && c == '\r') { break; } if (c == '\r' || (last != '\r' && c == '\n')) { String line = buf.toString(); if (line.trim().length() == 0) { break; } headerList.addElement(line); buf.setLength(0); } if (c != '\n' && c != '\r') { buf.append((char)c); eolReached = false; } else { if (c == '\r' || (last != '\r' && c == '\n')) { eolReached = true; } } last = c; } if (crLf) { in.read(); // skip last \n } } if (headerList.size() > 0) { header = (String)headerList.elementAt(0); } clearText = "-----BEGIN PGP SIGNED MESSAGE-----".equals(header); newLineFound = true; return headerFound; } /** * @return true if we are inside the clear text section of a PGP * signed message. */ public boolean isClearText() { return clearText; } /** * @return true if the stream is actually at end of file. */ public boolean isEndOfStream() { return isEndOfStream; } /** * Return the armor header line (if there is one) * @return the armor header line, null if none present. */ public String getArmorHeaderLine() { return header; } /** * Return the armor headers (the lines after the armor header line), * @return an array of armor headers, null if there aren't any. */ public String[] getArmorHeaders() { if (headerList.size() <= 1) { return null; } String[] hdrs = new String[headerList.size() - 1]; for (int i = 0; i != hdrs.length; i++) { hdrs[i] = (String)headerList.elementAt(i + 1); } return hdrs; } private int readIgnoreSpace() throws IOException { int c = in.read(); while (c == ' ' || c == '\t') { c = in.read(); } return c; } public int read() throws IOException { int c; if (start) { if (hasHeaders) { parseHeaders(); } crc.reset(); start = false; } if (clearText) { c = in.read(); if (c == '\r' || (c == '\n' && lastC != '\r')) { newLineFound = true; } else if (newLineFound && c == '-') { c = in.read(); if (c == '-') // a header, not dash escaped { clearText = false; start = true; restart = true; } else // a space - must be a dash escape { c = in.read(); } newLineFound = false; } else { if (c != '\n' && lastC != '\r') { newLineFound = false; } } lastC = c; if (c < 0) { isEndOfStream = true; } return c; } if (bufPtr > 2 || crcFound) { c = readIgnoreSpace(); if (c == '\r' || c == '\n') { c = readIgnoreSpace(); while (c == '\n' || c == '\r') { c = readIgnoreSpace(); } if (c < 0) // EOF { isEndOfStream = true; return -1; } if (c == '=') // crc reached { bufPtr = decode(readIgnoreSpace(), readIgnoreSpace(), readIgnoreSpace(), readIgnoreSpace(), outBuf); if (bufPtr == 0) { int i = ((outBuf[0] & 0xff) << 16) | ((outBuf[1] & 0xff) << 8) | (outBuf[2] & 0xff); crcFound = true; if (i != crc.getValue()) { throw new IOException("crc check failed in armored message."); } return read(); } else { throw new IOException("no crc found in armored message."); } } else if (c == '-') // end of record reached { while ((c = in.read()) >= 0) { if (c == '\n' || c == '\r') { break; } } if (!crcFound) { throw new IOException("crc check not found."); } crcFound = false; start = true; bufPtr = 3; if (c < 0) { isEndOfStream = true; } return -1; } else // data { bufPtr = decode(c, readIgnoreSpace(), readIgnoreSpace(), readIgnoreSpace(), outBuf); } } else { if (c >= 0) { bufPtr = decode(c, readIgnoreSpace(), readIgnoreSpace(), readIgnoreSpace(), outBuf); } else { isEndOfStream = true; return -1; } } } c = outBuf[bufPtr++]; crc.update(c); return c; } public void close() throws IOException { in.close(); } } bouncycastle-1.49.orig/src/org/bouncycastle/bcpg/SymmetricEncIntegrityPacket.java0000644000175000017500000000052212151274313027707 0ustar ebourgebourgpackage org.bouncycastle.bcpg; import java.io.IOException; /** */ public class SymmetricEncIntegrityPacket extends InputStreamPacket { int version; SymmetricEncIntegrityPacket( BCPGInputStream in) throws IOException { super(in); version = in.read(); } } bouncycastle-1.49.orig/src/org/bouncycastle/bcpg/SignatureSubpacket.java0000644000175000017500000000312312151274313026061 0ustar ebourgebourgpackage org.bouncycastle.bcpg; import java.io.IOException; import java.io.OutputStream; /** * Basic type for a PGP Signature sub-packet. */ public class SignatureSubpacket { int type; boolean critical; protected byte[] data; protected SignatureSubpacket( int type, boolean critical, byte[] data) { this.type = type; this.critical = critical; this.data = data; } public int getType() { return type; } public boolean isCritical() { return critical; } /** * return the generic data making up the packet. */ public byte[] getData() { return data; } public void encode( OutputStream out) throws IOException { int bodyLen = data.length + 1; if (bodyLen < 192) { out.write((byte)bodyLen); } else if (bodyLen <= 8383) { bodyLen -= 192; out.write((byte)(((bodyLen >> 8) & 0xff) + 192)); out.write((byte)bodyLen); } else { out.write(0xff); out.write((byte)(bodyLen >> 24)); out.write((byte)(bodyLen >> 16)); out.write((byte)(bodyLen >> 8)); out.write((byte)bodyLen); } if (critical) { out.write(0x80 | type); } else { out.write(type); } out.write(data); } } bouncycastle-1.49.orig/src/org/bouncycastle/bcpg/SignatureSubpacketInputStream.java0000644000175000017500000000660010757376723030302 0ustar ebourgebourgpackage org.bouncycastle.bcpg; import org.bouncycastle.bcpg.sig.Exportable; import org.bouncycastle.bcpg.sig.IssuerKeyID; import org.bouncycastle.bcpg.sig.KeyExpirationTime; import org.bouncycastle.bcpg.sig.KeyFlags; import org.bouncycastle.bcpg.sig.NotationData; import org.bouncycastle.bcpg.sig.PreferredAlgorithms; import org.bouncycastle.bcpg.sig.PrimaryUserID; import org.bouncycastle.bcpg.sig.Revocable; import org.bouncycastle.bcpg.sig.SignatureCreationTime; import org.bouncycastle.bcpg.sig.SignatureExpirationTime; import org.bouncycastle.bcpg.sig.SignerUserID; import org.bouncycastle.bcpg.sig.TrustSignature; import org.bouncycastle.util.io.Streams; import java.io.EOFException; import java.io.IOException; import java.io.InputStream; /** * reader for signature sub-packets */ public class SignatureSubpacketInputStream extends InputStream implements SignatureSubpacketTags { InputStream in; public SignatureSubpacketInputStream( InputStream in) { this.in = in; } public int available() throws IOException { return in.available(); } public int read() throws IOException { return in.read(); } public SignatureSubpacket readPacket() throws IOException { int l = this.read(); int bodyLen = 0; if (l < 0) { return null; } if (l < 192) { bodyLen = l; } else if (l <= 223) { bodyLen = ((l - 192) << 8) + (in.read()) + 192; } else if (l == 255) { bodyLen = (in.read() << 24) | (in.read() << 16) | (in.read() << 8) | in.read(); } else { // TODO Error? } int tag = in.read(); if (tag < 0) { throw new EOFException("unexpected EOF reading signature sub packet"); } byte[] data = new byte[bodyLen - 1]; if (Streams.readFully(in, data) < data.length) { throw new EOFException(); } boolean isCritical = ((tag & 0x80) != 0); int type = tag & 0x7f; switch (type) { case CREATION_TIME: return new SignatureCreationTime(isCritical, data); case KEY_EXPIRE_TIME: return new KeyExpirationTime(isCritical, data); case EXPIRE_TIME: return new SignatureExpirationTime(isCritical, data); case REVOCABLE: return new Revocable(isCritical, data); case EXPORTABLE: return new Exportable(isCritical, data); case ISSUER_KEY_ID: return new IssuerKeyID(isCritical, data); case TRUST_SIG: return new TrustSignature(isCritical, data); case PREFERRED_COMP_ALGS: case PREFERRED_HASH_ALGS: case PREFERRED_SYM_ALGS: return new PreferredAlgorithms(type, isCritical, data); case KEY_FLAGS: return new KeyFlags(isCritical, data); case PRIMARY_USER_ID: return new PrimaryUserID(isCritical, data); case SIGNER_USER_ID: return new SignerUserID(isCritical, data); case NOTATION_DATA: return new NotationData(isCritical, data); } return new SignatureSubpacket(type, isCritical, data); } } bouncycastle-1.49.orig/src/org/bouncycastle/bcpg/ElGamalSecretBCPGKey.java0000644000175000017500000000272410262753175026052 0ustar ebourgebourgpackage org.bouncycastle.bcpg; import java.io.*; import java.math.BigInteger; /** * base class for an ElGamal Secret Key. */ public class ElGamalSecretBCPGKey extends BCPGObject implements BCPGKey { MPInteger x; /** * * @param in * @throws IOException */ public ElGamalSecretBCPGKey( BCPGInputStream in) throws IOException { this.x = new MPInteger(in); } /** * * @param x */ public ElGamalSecretBCPGKey( BigInteger x) { this.x = new MPInteger(x); } /** * return "PGP" * * @see org.bouncycastle.bcpg.BCPGKey#getFormat() */ public String getFormat() { return "PGP"; } public BigInteger getX() { return x.getValue(); } /** * return the standard PGP encoding of the key. * * @see org.bouncycastle.bcpg.BCPGKey#getEncoded() */ public byte[] getEncoded() { try { ByteArrayOutputStream bOut = new ByteArrayOutputStream(); BCPGOutputStream pgpOut = new BCPGOutputStream(bOut); pgpOut.writeObject(this); return bOut.toByteArray(); } catch (IOException e) { return null; } } public void encode( BCPGOutputStream out) throws IOException { out.writeObject(x); } } bouncycastle-1.49.orig/src/org/bouncycastle/bcpg/DSASecretBCPGKey.java0000644000175000017500000000273410535262032025146 0ustar ebourgebourgpackage org.bouncycastle.bcpg; import java.io.*; import java.math.BigInteger; /** * base class for a DSA Secret Key. */ public class DSASecretBCPGKey extends BCPGObject implements BCPGKey { MPInteger x; /** * * @param in * @throws IOException */ public DSASecretBCPGKey( BCPGInputStream in) throws IOException { this.x = new MPInteger(in); } /** * * @param x */ public DSASecretBCPGKey( BigInteger x) { this.x = new MPInteger(x); } /** * return "PGP" * * @see org.bouncycastle.bcpg.BCPGKey#getFormat() */ public String getFormat() { return "PGP"; } /** * return the standard PGP encoding of the key. * * @see org.bouncycastle.bcpg.BCPGKey#getEncoded() */ public byte[] getEncoded() { try { ByteArrayOutputStream bOut = new ByteArrayOutputStream(); BCPGOutputStream pgpOut = new BCPGOutputStream(bOut); pgpOut.writeObject(this); return bOut.toByteArray(); } catch (IOException e) { return null; } } public void encode( BCPGOutputStream out) throws IOException { out.writeObject(x); } /** * @return x */ public BigInteger getX() { return x.getValue(); } } bouncycastle-1.49.orig/src/org/bouncycastle/bcpg/SignaturePacket.java0000644000175000017500000003631311027574562025370 0ustar ebourgebourgpackage org.bouncycastle.bcpg; import org.bouncycastle.bcpg.sig.IssuerKeyID; import org.bouncycastle.bcpg.sig.SignatureCreationTime; import org.bouncycastle.util.Arrays; import java.io.ByteArrayInputStream; import java.io.ByteArrayOutputStream; import java.io.IOException; import java.util.Vector; /** * generic signature packet */ public class SignaturePacket extends ContainedPacket implements PublicKeyAlgorithmTags { private int version; private int signatureType; private long creationTime; private long keyID; private int keyAlgorithm; private int hashAlgorithm; private MPInteger[] signature; private byte[] fingerPrint; private SignatureSubpacket[] hashedData; private SignatureSubpacket[] unhashedData; private byte[] signatureEncoding; SignaturePacket( BCPGInputStream in) throws IOException { version = in.read(); if (version == 3 || version == 2) { int l = in.read(); signatureType = in.read(); creationTime = (((long)in.read() << 24) | (in.read() << 16) | (in.read() << 8) | in.read()) * 1000; keyID |= (long)in.read() << 56; keyID |= (long)in.read() << 48; keyID |= (long)in.read() << 40; keyID |= (long)in.read() << 32; keyID |= (long)in.read() << 24; keyID |= (long)in.read() << 16; keyID |= (long)in.read() << 8; keyID |= in.read(); keyAlgorithm = in.read(); hashAlgorithm = in.read(); } else if (version == 4) { signatureType = in.read(); keyAlgorithm = in.read(); hashAlgorithm = in.read(); int hashedLength = (in.read() << 8) | in.read(); byte[] hashed = new byte[hashedLength]; in.readFully(hashed); // // read the signature sub packet data. // SignatureSubpacket sub; SignatureSubpacketInputStream sIn = new SignatureSubpacketInputStream( new ByteArrayInputStream(hashed)); Vector v = new Vector(); while ((sub = sIn.readPacket()) != null) { v.addElement(sub); } hashedData = new SignatureSubpacket[v.size()]; for (int i = 0; i != hashedData.length; i++) { SignatureSubpacket p = (SignatureSubpacket)v.elementAt(i); if (p instanceof IssuerKeyID) { keyID = ((IssuerKeyID)p).getKeyID(); } else if (p instanceof SignatureCreationTime) { creationTime = ((SignatureCreationTime)p).getTime().getTime(); } hashedData[i] = p; } int unhashedLength = (in.read() << 8) | in.read(); byte[] unhashed = new byte[unhashedLength]; in.readFully(unhashed); sIn = new SignatureSubpacketInputStream( new ByteArrayInputStream(unhashed)); v.removeAllElements(); while ((sub = sIn.readPacket()) != null) { v.addElement(sub); } unhashedData = new SignatureSubpacket[v.size()]; for (int i = 0; i != unhashedData.length; i++) { SignatureSubpacket p = (SignatureSubpacket)v.elementAt(i); if (p instanceof IssuerKeyID) { keyID = ((IssuerKeyID)p).getKeyID(); } unhashedData[i] = p; } } else { throw new RuntimeException("unsupported version: " + version); } fingerPrint = new byte[2]; in.readFully(fingerPrint); switch (keyAlgorithm) { case RSA_GENERAL: case RSA_SIGN: MPInteger v = new MPInteger(in); signature = new MPInteger[1]; signature[0] = v; break; case DSA: MPInteger r = new MPInteger(in); MPInteger s = new MPInteger(in); signature = new MPInteger[2]; signature[0] = r; signature[1] = s; break; case ELGAMAL_ENCRYPT: // yep, this really does happen sometimes. case ELGAMAL_GENERAL: MPInteger p = new MPInteger(in); MPInteger g = new MPInteger(in); MPInteger y = new MPInteger(in); signature = new MPInteger[3]; signature[0] = p; signature[1] = g; signature[2] = y; break; default: if (keyAlgorithm >= PublicKeyAlgorithmTags.EXPERIMENTAL_1 && keyAlgorithm <= PublicKeyAlgorithmTags.EXPERIMENTAL_11) { signature = null; ByteArrayOutputStream bOut = new ByteArrayOutputStream(); int ch; while ((ch = in.read()) >= 0) { bOut.write(ch); } signatureEncoding = bOut.toByteArray(); } else { throw new IOException("unknown signature key algorithm: " + keyAlgorithm); } } } /** * Generate a version 4 signature packet. * * @param signatureType * @param keyAlgorithm * @param hashAlgorithm * @param hashedData * @param unhashedData * @param fingerPrint * @param signature */ public SignaturePacket( int signatureType, long keyID, int keyAlgorithm, int hashAlgorithm, SignatureSubpacket[] hashedData, SignatureSubpacket[] unhashedData, byte[] fingerPrint, MPInteger[] signature) { this(4, signatureType, keyID, keyAlgorithm, hashAlgorithm, hashedData, unhashedData, fingerPrint, signature); } /** * Generate a version 2/3 signature packet. * * @param signatureType * @param keyAlgorithm * @param hashAlgorithm * @param fingerPrint * @param signature */ public SignaturePacket( int version, int signatureType, long keyID, int keyAlgorithm, int hashAlgorithm, long creationTime, byte[] fingerPrint, MPInteger[] signature) { this(version, signatureType, keyID, keyAlgorithm, hashAlgorithm, null, null, fingerPrint, signature); this.creationTime = creationTime; } public SignaturePacket( int version, int signatureType, long keyID, int keyAlgorithm, int hashAlgorithm, SignatureSubpacket[] hashedData, SignatureSubpacket[] unhashedData, byte[] fingerPrint, MPInteger[] signature) { this.version = version; this.signatureType = signatureType; this.keyID = keyID; this.keyAlgorithm = keyAlgorithm; this.hashAlgorithm = hashAlgorithm; this.hashedData = hashedData; this.unhashedData = unhashedData; this.fingerPrint = fingerPrint; this.signature = signature; if (hashedData != null) { setCreationTime(); } } /** * get the version number */ public int getVersion() { return version; } /** * return the signature type. */ public int getSignatureType() { return signatureType; } /** * return the keyID * @return the keyID that created the signature. */ public long getKeyID() { return keyID; } /** * return the signature trailer that must be included with the data * to reconstruct the signature * * @return byte[] */ public byte[] getSignatureTrailer() { byte[] trailer = null; if (version == 3 || version == 2) { trailer = new byte[5]; long time = creationTime / 1000; trailer[0] = (byte)signatureType; trailer[1] = (byte)(time >> 24); trailer[2] = (byte)(time >> 16); trailer[3] = (byte)(time >> 8); trailer[4] = (byte)(time); } else { ByteArrayOutputStream sOut = new ByteArrayOutputStream(); try { sOut.write((byte)this.getVersion()); sOut.write((byte)this.getSignatureType()); sOut.write((byte)this.getKeyAlgorithm()); sOut.write((byte)this.getHashAlgorithm()); ByteArrayOutputStream hOut = new ByteArrayOutputStream(); SignatureSubpacket[] hashed = this.getHashedSubPackets(); for (int i = 0; i != hashed.length; i++) { hashed[i].encode(hOut); } byte[] data = hOut.toByteArray(); sOut.write((byte)(data.length >> 8)); sOut.write((byte)data.length); sOut.write(data); byte[] hData = sOut.toByteArray(); sOut.write((byte)this.getVersion()); sOut.write((byte)0xff); sOut.write((byte)(hData.length>> 24)); sOut.write((byte)(hData.length >> 16)); sOut.write((byte)(hData.length >> 8)); sOut.write((byte)(hData.length)); } catch (IOException e) { throw new RuntimeException("exception generating trailer: " + e); } trailer = sOut.toByteArray(); } return trailer; } /** * return the encryption algorithm tag */ public int getKeyAlgorithm() { return keyAlgorithm; } /** * return the hashAlgorithm tag */ public int getHashAlgorithm() { return hashAlgorithm; } /** * return the signature as a set of integers - note this is normalised to be the * ASN.1 encoding of what appears in the signature packet. */ public MPInteger[] getSignature() { return signature; } /** * Return the byte encoding of the signature section. * @return uninterpreted signature bytes. */ public byte[] getSignatureBytes() { if (signatureEncoding == null) { ByteArrayOutputStream bOut = new ByteArrayOutputStream(); BCPGOutputStream bcOut = new BCPGOutputStream(bOut); for (int i = 0; i != signature.length; i++) { try { bcOut.writeObject(signature[i]); } catch (IOException e) { throw new RuntimeException("internal error: " + e); } } return bOut.toByteArray(); } else { return Arrays.clone(signatureEncoding); } } public SignatureSubpacket[] getHashedSubPackets() { return hashedData; } public SignatureSubpacket[] getUnhashedSubPackets() { return unhashedData; } /** * Return the creation time of the signature in milli-seconds. * * @return the creation time in millis */ public long getCreationTime() { return creationTime; } public void encode( BCPGOutputStream out) throws IOException { ByteArrayOutputStream bOut = new ByteArrayOutputStream(); BCPGOutputStream pOut = new BCPGOutputStream(bOut); pOut.write(version); if (version == 3 || version == 2) { pOut.write(5); // the length of the next block long time = creationTime / 1000; pOut.write(signatureType); pOut.write((byte)(time >> 24)); pOut.write((byte)(time >> 16)); pOut.write((byte)(time >> 8)); pOut.write((byte)time); pOut.write((byte)(keyID >> 56)); pOut.write((byte)(keyID >> 48)); pOut.write((byte)(keyID >> 40)); pOut.write((byte)(keyID >> 32)); pOut.write((byte)(keyID >> 24)); pOut.write((byte)(keyID >> 16)); pOut.write((byte)(keyID >> 8)); pOut.write((byte)(keyID)); pOut.write(keyAlgorithm); pOut.write(hashAlgorithm); } else if (version == 4) { pOut.write(signatureType); pOut.write(keyAlgorithm); pOut.write(hashAlgorithm); ByteArrayOutputStream sOut = new ByteArrayOutputStream(); for (int i = 0; i != hashedData.length; i++) { hashedData[i].encode(sOut); } byte[] data = sOut.toByteArray(); pOut.write(data.length >> 8); pOut.write(data.length); pOut.write(data); sOut.reset(); for (int i = 0; i != unhashedData.length; i++) { unhashedData[i].encode(sOut); } data = sOut.toByteArray(); pOut.write(data.length >> 8); pOut.write(data.length); pOut.write(data); } else { throw new IOException("unknown version: " + version); } pOut.write(fingerPrint); if (signature != null) { for (int i = 0; i != signature.length; i++) { pOut.writeObject(signature[i]); } } else { pOut.write(signatureEncoding); } out.writePacket(SIGNATURE, bOut.toByteArray(), true); } private void setCreationTime() { for (int i = 0; i != hashedData.length; i++) { if (hashedData[i] instanceof SignatureCreationTime) { creationTime = ((SignatureCreationTime)hashedData[i]).getTime().getTime(); break; } } } } bouncycastle-1.49.orig/src/org/bouncycastle/bcpg/CompressionAlgorithmTags.java0000644000175000017500000000063010514707006027246 0ustar ebourgebourgpackage org.bouncycastle.bcpg; /** * Basic tags for compression algorithms */ public interface CompressionAlgorithmTags { public static final int UNCOMPRESSED = 0; // Uncompressed public static final int ZIP = 1; // ZIP (RFC 1951) public static final int ZLIB = 2; // ZLIB (RFC 1950) public static final int BZIP2 = 3; // BZ2 } bouncycastle-1.49.orig/src/org/bouncycastle/bcpg/RSASecretBCPGKey.java0000644000175000017500000000710110631520456025161 0ustar ebourgebourgpackage org.bouncycastle.bcpg; import java.io.*; import java.math.BigInteger; /** * base class for an RSA Secret (or Private) Key. */ public class RSASecretBCPGKey extends BCPGObject implements BCPGKey { MPInteger d; MPInteger p; MPInteger q; MPInteger u; BigInteger expP, expQ, crt; /** * * @param in * @throws IOException */ public RSASecretBCPGKey( BCPGInputStream in) throws IOException { this.d = new MPInteger(in); this.p = new MPInteger(in); this.q = new MPInteger(in); this.u = new MPInteger(in); expP = d.getValue().remainder(p.getValue().subtract(BigInteger.valueOf(1))); expQ = d.getValue().remainder(q.getValue().subtract(BigInteger.valueOf(1))); crt = q.getValue().modInverse(p.getValue()); } /** * * @param d * @param p * @param q */ public RSASecretBCPGKey( BigInteger d, BigInteger p, BigInteger q) { // // pgp requires (p < q) // int cmp = p.compareTo(q); if (cmp >= 0) { if (cmp == 0) { throw new IllegalArgumentException("p and q cannot be equal"); } BigInteger tmp = p; p = q; q = tmp; } this.d = new MPInteger(d); this.p = new MPInteger(p); this.q = new MPInteger(q); this.u = new MPInteger(p.modInverse(q)); expP = d.remainder(p.subtract(BigInteger.valueOf(1))); expQ = d.remainder(q.subtract(BigInteger.valueOf(1))); crt = q.modInverse(p); } /** * return the modulus for this key. * * @return BigInteger */ public BigInteger getModulus() { return p.getValue().multiply(q.getValue()); } /** * return the private exponent for this key. * * @return BigInteger */ public BigInteger getPrivateExponent() { return d.getValue(); } /** * return the prime P */ public BigInteger getPrimeP() { return p.getValue(); } /** * return the prime Q */ public BigInteger getPrimeQ() { return q.getValue(); } /** * return the prime exponent of p */ public BigInteger getPrimeExponentP() { return expP; } /** * return the prime exponent of q */ public BigInteger getPrimeExponentQ() { return expQ; } /** * return the crt coefficient */ public BigInteger getCrtCoefficient() { return crt; } /** * return "PGP" * * @see org.bouncycastle.bcpg.BCPGKey#getFormat() */ public String getFormat() { return "PGP"; } /** * return the standard PGP encoding of the key. * * @see org.bouncycastle.bcpg.BCPGKey#getEncoded() */ public byte[] getEncoded() { try { ByteArrayOutputStream bOut = new ByteArrayOutputStream(); BCPGOutputStream pgpOut = new BCPGOutputStream(bOut); pgpOut.writeObject(this); return bOut.toByteArray(); } catch (IOException e) { return null; } } public void encode( BCPGOutputStream out) throws IOException { out.writeObject(d); out.writeObject(p); out.writeObject(q); out.writeObject(u); } } bouncycastle-1.49.orig/src/org/bouncycastle/bcpg/UserAttributeSubpacketInputStream.java0000644000175000017500000000445610757376723031152 0ustar ebourgebourgpackage org.bouncycastle.bcpg; import java.io.*; import org.bouncycastle.bcpg.attr.ImageAttribute; /** * reader for user attribute sub-packets */ public class UserAttributeSubpacketInputStream extends InputStream implements UserAttributeSubpacketTags { InputStream in; public UserAttributeSubpacketInputStream( InputStream in) { this.in = in; } public int available() throws IOException { return in.available(); } public int read() throws IOException { return in.read(); } private void readFully( byte[] buf, int off, int len) throws IOException { if (len > 0) { int b = this.read(); if (b < 0) { throw new EOFException(); } buf[off] = (byte)b; off++; len--; } while (len > 0) { int l = in.read(buf, off, len); if (l < 0) { throw new EOFException(); } off += l; len -= l; } } public UserAttributeSubpacket readPacket() throws IOException { int l = this.read(); int bodyLen = 0; if (l < 0) { return null; } if (l < 192) { bodyLen = l; } else if (l <= 223) { bodyLen = ((l - 192) << 8) + (in.read()) + 192; } else if (l == 255) { bodyLen = (in.read() << 24) | (in.read() << 16) | (in.read() << 8) | in.read(); } else { // TODO Error? } int tag = in.read(); if (tag < 0) { throw new EOFException("unexpected EOF reading user attribute sub packet"); } byte[] data = new byte[bodyLen - 1]; this.readFully(data, 0, data.length); int type = tag; switch (type) { case IMAGE_ATTRIBUTE: return new ImageAttribute(data); } return new UserAttributeSubpacket(type, data); } } bouncycastle-1.49.orig/src/org/bouncycastle/bcpg/OutputStreamPacket.java0000644000175000017500000000057110262753175026077 0ustar ebourgebourgpackage org.bouncycastle.bcpg; import java.io.IOException; public abstract class OutputStreamPacket { protected BCPGOutputStream out; public OutputStreamPacket( BCPGOutputStream out) { this.out = out; } public abstract BCPGOutputStream open() throws IOException; public abstract void close() throws IOException; } bouncycastle-1.49.orig/src/org/bouncycastle/bcpg/package.html0000644000175000017500000000042710262753175023711 0ustar ebourgebourg Low level classes for dealing with OpenPGP objects.

    These classes deal with things at a raw OpenPGP packet level. For the most part you are probably better off looking at the org.bouncycastle.openpgp package for what you want. bouncycastle-1.49.orig/src/org/bouncycastle/bcpg/OnePassSignaturePacket.java0000644000175000017500000000517510262753175026662 0ustar ebourgebourgpackage org.bouncycastle.bcpg; import java.io.*; /** * generic signature object */ public class OnePassSignaturePacket extends ContainedPacket { private int version; private int sigType; private int hashAlgorithm; private int keyAlgorithm; private long keyID; private int nested; OnePassSignaturePacket( BCPGInputStream in) throws IOException { version = in.read(); sigType = in.read(); hashAlgorithm = in.read(); keyAlgorithm = in.read(); keyID |= (long)in.read() << 56; keyID |= (long)in.read() << 48; keyID |= (long)in.read() << 40; keyID |= (long)in.read() << 32; keyID |= (long)in.read() << 24; keyID |= (long)in.read() << 16; keyID |= (long)in.read() << 8; keyID |= in.read(); nested = in.read(); } public OnePassSignaturePacket( int sigType, int hashAlgorithm, int keyAlgorithm, long keyID, boolean isNested) { this.version = 3; this.sigType = sigType; this.hashAlgorithm = hashAlgorithm; this.keyAlgorithm = keyAlgorithm; this.keyID = keyID; this.nested = (isNested) ? 0 : 1; } /** * Return the signature type. * @return the signature type */ public int getSignatureType() { return sigType; } /** * return the encryption algorithm tag */ public int getKeyAlgorithm() { return keyAlgorithm; } /** * return the hashAlgorithm tag */ public int getHashAlgorithm() { return hashAlgorithm; } /** * @return long */ public long getKeyID() { return keyID; } /** * */ public void encode( BCPGOutputStream out) throws IOException { ByteArrayOutputStream bOut = new ByteArrayOutputStream(); BCPGOutputStream pOut = new BCPGOutputStream(bOut); pOut.write(version); pOut.write(sigType); pOut.write(hashAlgorithm); pOut.write(keyAlgorithm); pOut.write((byte)(keyID >> 56)); pOut.write((byte)(keyID >> 48)); pOut.write((byte)(keyID >> 40)); pOut.write((byte)(keyID >> 32)); pOut.write((byte)(keyID >> 24)); pOut.write((byte)(keyID >> 16)); pOut.write((byte)(keyID >> 8)); pOut.write((byte)(keyID)); pOut.write(nested); out.writePacket(ONE_PASS_SIGNATURE, bOut.toByteArray(), true); } } bouncycastle-1.49.orig/src/org/bouncycastle/operator/0000755000175000017500000000000012152033551022332 5ustar ebourgebourgbouncycastle-1.49.orig/src/org/bouncycastle/operator/AsymmetricKeyWrapper.java0000644000175000017500000000065411442363447027344 0ustar ebourgebourgpackage org.bouncycastle.operator; import org.bouncycastle.asn1.x509.AlgorithmIdentifier; public abstract class AsymmetricKeyWrapper implements KeyWrapper { private AlgorithmIdentifier algorithmId; protected AsymmetricKeyWrapper(AlgorithmIdentifier algorithmId) { this.algorithmId = algorithmId; } public AlgorithmIdentifier getAlgorithmIdentifier() { return algorithmId; } } bouncycastle-1.49.orig/src/org/bouncycastle/operator/DefaultSignatureAlgorithmIdentifierFinder.java0000644000175000017500000002707312132366675033474 0ustar ebourgebourgpackage org.bouncycastle.operator; import java.util.HashMap; import java.util.HashSet; import java.util.Map; import java.util.Set; import org.bouncycastle.asn1.ASN1Encodable; import org.bouncycastle.asn1.ASN1Integer; import org.bouncycastle.asn1.ASN1ObjectIdentifier; import org.bouncycastle.asn1.DERNull; import org.bouncycastle.asn1.cryptopro.CryptoProObjectIdentifiers; import org.bouncycastle.asn1.nist.NISTObjectIdentifiers; import org.bouncycastle.asn1.oiw.OIWObjectIdentifiers; import org.bouncycastle.asn1.pkcs.PKCSObjectIdentifiers; import org.bouncycastle.asn1.pkcs.RSASSAPSSparams; import org.bouncycastle.asn1.teletrust.TeleTrusTObjectIdentifiers; import org.bouncycastle.asn1.x509.AlgorithmIdentifier; import org.bouncycastle.asn1.x9.X9ObjectIdentifiers; import org.bouncycastle.util.Strings; public class DefaultSignatureAlgorithmIdentifierFinder implements SignatureAlgorithmIdentifierFinder { private static Map algorithms = new HashMap(); private static Set noParams = new HashSet(); private static Map params = new HashMap(); private static Set pkcs15RsaEncryption = new HashSet(); private static Map digestOids = new HashMap(); private static final ASN1ObjectIdentifier ENCRYPTION_RSA = PKCSObjectIdentifiers.rsaEncryption; private static final ASN1ObjectIdentifier ENCRYPTION_DSA = X9ObjectIdentifiers.id_dsa_with_sha1; private static final ASN1ObjectIdentifier ENCRYPTION_ECDSA = X9ObjectIdentifiers.ecdsa_with_SHA1; private static final ASN1ObjectIdentifier ENCRYPTION_RSA_PSS = PKCSObjectIdentifiers.id_RSASSA_PSS; private static final ASN1ObjectIdentifier ENCRYPTION_GOST3410 = CryptoProObjectIdentifiers.gostR3410_94; private static final ASN1ObjectIdentifier ENCRYPTION_ECGOST3410 = CryptoProObjectIdentifiers.gostR3410_2001; static { algorithms.put("MD2WITHRSAENCRYPTION", PKCSObjectIdentifiers.md2WithRSAEncryption); algorithms.put("MD2WITHRSA", PKCSObjectIdentifiers.md2WithRSAEncryption); algorithms.put("MD5WITHRSAENCRYPTION", PKCSObjectIdentifiers.md5WithRSAEncryption); algorithms.put("MD5WITHRSA", PKCSObjectIdentifiers.md5WithRSAEncryption); algorithms.put("SHA1WITHRSAENCRYPTION", PKCSObjectIdentifiers.sha1WithRSAEncryption); algorithms.put("SHA1WITHRSA", PKCSObjectIdentifiers.sha1WithRSAEncryption); algorithms.put("SHA224WITHRSAENCRYPTION", PKCSObjectIdentifiers.sha224WithRSAEncryption); algorithms.put("SHA224WITHRSA", PKCSObjectIdentifiers.sha224WithRSAEncryption); algorithms.put("SHA256WITHRSAENCRYPTION", PKCSObjectIdentifiers.sha256WithRSAEncryption); algorithms.put("SHA256WITHRSA", PKCSObjectIdentifiers.sha256WithRSAEncryption); algorithms.put("SHA384WITHRSAENCRYPTION", PKCSObjectIdentifiers.sha384WithRSAEncryption); algorithms.put("SHA384WITHRSA", PKCSObjectIdentifiers.sha384WithRSAEncryption); algorithms.put("SHA512WITHRSAENCRYPTION", PKCSObjectIdentifiers.sha512WithRSAEncryption); algorithms.put("SHA512WITHRSA", PKCSObjectIdentifiers.sha512WithRSAEncryption); algorithms.put("SHA1WITHRSAANDMGF1", PKCSObjectIdentifiers.id_RSASSA_PSS); algorithms.put("SHA224WITHRSAANDMGF1", PKCSObjectIdentifiers.id_RSASSA_PSS); algorithms.put("SHA256WITHRSAANDMGF1", PKCSObjectIdentifiers.id_RSASSA_PSS); algorithms.put("SHA384WITHRSAANDMGF1", PKCSObjectIdentifiers.id_RSASSA_PSS); algorithms.put("SHA512WITHRSAANDMGF1", PKCSObjectIdentifiers.id_RSASSA_PSS); algorithms.put("RIPEMD160WITHRSAENCRYPTION", TeleTrusTObjectIdentifiers.rsaSignatureWithripemd160); algorithms.put("RIPEMD160WITHRSA", TeleTrusTObjectIdentifiers.rsaSignatureWithripemd160); algorithms.put("RIPEMD128WITHRSAENCRYPTION", TeleTrusTObjectIdentifiers.rsaSignatureWithripemd128); algorithms.put("RIPEMD128WITHRSA", TeleTrusTObjectIdentifiers.rsaSignatureWithripemd128); algorithms.put("RIPEMD256WITHRSAENCRYPTION", TeleTrusTObjectIdentifiers.rsaSignatureWithripemd256); algorithms.put("RIPEMD256WITHRSA", TeleTrusTObjectIdentifiers.rsaSignatureWithripemd256); algorithms.put("SHA1WITHDSA", X9ObjectIdentifiers.id_dsa_with_sha1); algorithms.put("DSAWITHSHA1", X9ObjectIdentifiers.id_dsa_with_sha1); algorithms.put("SHA224WITHDSA", NISTObjectIdentifiers.dsa_with_sha224); algorithms.put("SHA256WITHDSA", NISTObjectIdentifiers.dsa_with_sha256); algorithms.put("SHA384WITHDSA", NISTObjectIdentifiers.dsa_with_sha384); algorithms.put("SHA512WITHDSA", NISTObjectIdentifiers.dsa_with_sha512); algorithms.put("SHA1WITHECDSA", X9ObjectIdentifiers.ecdsa_with_SHA1); algorithms.put("ECDSAWITHSHA1", X9ObjectIdentifiers.ecdsa_with_SHA1); algorithms.put("SHA224WITHECDSA", X9ObjectIdentifiers.ecdsa_with_SHA224); algorithms.put("SHA256WITHECDSA", X9ObjectIdentifiers.ecdsa_with_SHA256); algorithms.put("SHA384WITHECDSA", X9ObjectIdentifiers.ecdsa_with_SHA384); algorithms.put("SHA512WITHECDSA", X9ObjectIdentifiers.ecdsa_with_SHA512); algorithms.put("GOST3411WITHGOST3410", CryptoProObjectIdentifiers.gostR3411_94_with_gostR3410_94); algorithms.put("GOST3411WITHGOST3410-94", CryptoProObjectIdentifiers.gostR3411_94_with_gostR3410_94); algorithms.put("GOST3411WITHECGOST3410", CryptoProObjectIdentifiers.gostR3411_94_with_gostR3410_2001); algorithms.put("GOST3411WITHECGOST3410-2001", CryptoProObjectIdentifiers.gostR3411_94_with_gostR3410_2001); algorithms.put("GOST3411WITHGOST3410-2001", CryptoProObjectIdentifiers.gostR3411_94_with_gostR3410_2001); // // According to RFC 3279, the ASN.1 encoding SHALL (id-dsa-with-sha1) or MUST (ecdsa-with-SHA*) omit the parameters field. // The parameters field SHALL be NULL for RSA based signature algorithms. // noParams.add(X9ObjectIdentifiers.ecdsa_with_SHA1); noParams.add(X9ObjectIdentifiers.ecdsa_with_SHA224); noParams.add(X9ObjectIdentifiers.ecdsa_with_SHA256); noParams.add(X9ObjectIdentifiers.ecdsa_with_SHA384); noParams.add(X9ObjectIdentifiers.ecdsa_with_SHA512); noParams.add(X9ObjectIdentifiers.id_dsa_with_sha1); noParams.add(NISTObjectIdentifiers.dsa_with_sha224); noParams.add(NISTObjectIdentifiers.dsa_with_sha256); noParams.add(NISTObjectIdentifiers.dsa_with_sha384); noParams.add(NISTObjectIdentifiers.dsa_with_sha512); // // RFC 4491 // noParams.add(CryptoProObjectIdentifiers.gostR3411_94_with_gostR3410_94); noParams.add(CryptoProObjectIdentifiers.gostR3411_94_with_gostR3410_2001); // // PKCS 1.5 encrypted algorithms // pkcs15RsaEncryption.add(PKCSObjectIdentifiers.sha1WithRSAEncryption); pkcs15RsaEncryption.add(PKCSObjectIdentifiers.sha224WithRSAEncryption); pkcs15RsaEncryption.add(PKCSObjectIdentifiers.sha256WithRSAEncryption); pkcs15RsaEncryption.add(PKCSObjectIdentifiers.sha384WithRSAEncryption); pkcs15RsaEncryption.add(PKCSObjectIdentifiers.sha512WithRSAEncryption); pkcs15RsaEncryption.add(TeleTrusTObjectIdentifiers.rsaSignatureWithripemd128); pkcs15RsaEncryption.add(TeleTrusTObjectIdentifiers.rsaSignatureWithripemd160); pkcs15RsaEncryption.add(TeleTrusTObjectIdentifiers.rsaSignatureWithripemd256); // // explicit params // AlgorithmIdentifier sha1AlgId = new AlgorithmIdentifier(OIWObjectIdentifiers.idSHA1, DERNull.INSTANCE); params.put("SHA1WITHRSAANDMGF1", createPSSParams(sha1AlgId, 20)); AlgorithmIdentifier sha224AlgId = new AlgorithmIdentifier(NISTObjectIdentifiers.id_sha224, DERNull.INSTANCE); params.put("SHA224WITHRSAANDMGF1", createPSSParams(sha224AlgId, 28)); AlgorithmIdentifier sha256AlgId = new AlgorithmIdentifier(NISTObjectIdentifiers.id_sha256, DERNull.INSTANCE); params.put("SHA256WITHRSAANDMGF1", createPSSParams(sha256AlgId, 32)); AlgorithmIdentifier sha384AlgId = new AlgorithmIdentifier(NISTObjectIdentifiers.id_sha384, DERNull.INSTANCE); params.put("SHA384WITHRSAANDMGF1", createPSSParams(sha384AlgId, 48)); AlgorithmIdentifier sha512AlgId = new AlgorithmIdentifier(NISTObjectIdentifiers.id_sha512, DERNull.INSTANCE); params.put("SHA512WITHRSAANDMGF1", createPSSParams(sha512AlgId, 64)); // // digests // digestOids.put(PKCSObjectIdentifiers.sha224WithRSAEncryption, NISTObjectIdentifiers.id_sha224); digestOids.put(PKCSObjectIdentifiers.sha256WithRSAEncryption, NISTObjectIdentifiers.id_sha256); digestOids.put(PKCSObjectIdentifiers.sha384WithRSAEncryption, NISTObjectIdentifiers.id_sha384); digestOids.put(PKCSObjectIdentifiers.sha512WithRSAEncryption, NISTObjectIdentifiers.id_sha512); digestOids.put(PKCSObjectIdentifiers.md2WithRSAEncryption, PKCSObjectIdentifiers.md2); digestOids.put(PKCSObjectIdentifiers.md4WithRSAEncryption, PKCSObjectIdentifiers.md4); digestOids.put(PKCSObjectIdentifiers.md5WithRSAEncryption, PKCSObjectIdentifiers.md5); digestOids.put(PKCSObjectIdentifiers.sha1WithRSAEncryption, OIWObjectIdentifiers.idSHA1); digestOids.put(TeleTrusTObjectIdentifiers.rsaSignatureWithripemd128, TeleTrusTObjectIdentifiers.ripemd128); digestOids.put(TeleTrusTObjectIdentifiers.rsaSignatureWithripemd160, TeleTrusTObjectIdentifiers.ripemd160); digestOids.put(TeleTrusTObjectIdentifiers.rsaSignatureWithripemd256, TeleTrusTObjectIdentifiers.ripemd256); digestOids.put(CryptoProObjectIdentifiers.gostR3411_94_with_gostR3410_94, CryptoProObjectIdentifiers.gostR3411); digestOids.put(CryptoProObjectIdentifiers.gostR3411_94_with_gostR3410_2001, CryptoProObjectIdentifiers.gostR3411); } private static AlgorithmIdentifier generate(String signatureAlgorithm) { AlgorithmIdentifier sigAlgId; AlgorithmIdentifier encAlgId; AlgorithmIdentifier digAlgId; String algorithmName = Strings.toUpperCase(signatureAlgorithm); ASN1ObjectIdentifier sigOID = (ASN1ObjectIdentifier)algorithms.get(algorithmName); if (sigOID == null) { throw new IllegalArgumentException("Unknown signature type requested: " + algorithmName); } if (noParams.contains(sigOID)) { sigAlgId = new AlgorithmIdentifier(sigOID); } else if (params.containsKey(algorithmName)) { sigAlgId = new AlgorithmIdentifier(sigOID, (ASN1Encodable)params.get(algorithmName)); } else { sigAlgId = new AlgorithmIdentifier(sigOID, DERNull.INSTANCE); } if (pkcs15RsaEncryption.contains(sigOID)) { encAlgId = new AlgorithmIdentifier(PKCSObjectIdentifiers.rsaEncryption, DERNull.INSTANCE); } else { encAlgId = sigAlgId; } if (sigAlgId.getAlgorithm().equals(PKCSObjectIdentifiers.id_RSASSA_PSS)) { digAlgId = ((RSASSAPSSparams)sigAlgId.getParameters()).getHashAlgorithm(); } else { digAlgId = new AlgorithmIdentifier((ASN1ObjectIdentifier)digestOids.get(sigOID), DERNull.INSTANCE); } return sigAlgId; } private static RSASSAPSSparams createPSSParams(AlgorithmIdentifier hashAlgId, int saltSize) { return new RSASSAPSSparams( hashAlgId, new AlgorithmIdentifier(PKCSObjectIdentifiers.id_mgf1, hashAlgId), new ASN1Integer(saltSize), new ASN1Integer(1)); } public AlgorithmIdentifier find(String sigAlgName) { return generate(sigAlgName); } }bouncycastle-1.49.orig/src/org/bouncycastle/operator/RawContentVerifier.java0000644000175000017500000000110511442065640026757 0ustar ebourgebourgpackage org.bouncycastle.operator; /** * Interface for ContentVerifiers that also support raw signatures that can be * verified using the digest of the calculated data. */ public interface RawContentVerifier { /** * Verify that the expected signature value was derived from the passed in digest. * * @param digest digest calculated from the content. * @param expected expected value of the signature * @return true if the expected signature is derived from the digest, false otherwise. */ boolean verify(byte[] digest, byte[] expected); } bouncycastle-1.49.orig/src/org/bouncycastle/operator/ContentVerifierProvider.java0000644000175000017500000000220011502012161030000 0ustar ebourgebourgpackage org.bouncycastle.operator; import org.bouncycastle.asn1.x509.AlgorithmIdentifier; import org.bouncycastle.cert.X509CertificateHolder; /** * General interface for providers of ContentVerifier objects. */ public interface ContentVerifierProvider { /** * Return whether or not this verifier has a certificate associated with it. * * @return true if there is an associated certificate, false otherwise. */ boolean hasAssociatedCertificate(); /** * Return the associated certificate if there is one. * * @return a holder containing the associated certificate if there is one, null if there is not. */ X509CertificateHolder getAssociatedCertificate(); /** * Return a ContentVerifier that matches the passed in algorithm identifier, * * @param verifierAlgorithmIdentifier the algorithm and parameters required. * @return a matching ContentVerifier * @throws OperatorCreationException if the required ContentVerifier cannot be created. */ ContentVerifier get(AlgorithmIdentifier verifierAlgorithmIdentifier) throws OperatorCreationException; } bouncycastle-1.49.orig/src/org/bouncycastle/operator/OperatorCreationException.java0000644000175000017500000000045011444262526030344 0ustar ebourgebourgpackage org.bouncycastle.operator; public class OperatorCreationException extends OperatorException { public OperatorCreationException(String msg, Throwable cause) { super(msg, cause); } public OperatorCreationException(String msg) { super(msg); } } bouncycastle-1.49.orig/src/org/bouncycastle/operator/DigestAlgorithmIdentifierFinder.java0000644000175000017500000000140111727572137031431 0ustar ebourgebourgpackage org.bouncycastle.operator; import org.bouncycastle.asn1.x509.AlgorithmIdentifier; public interface DigestAlgorithmIdentifierFinder { /** * Find the digest algorithm identifier that matches with * the passed in signature algorithm identifier. * * @param sigAlgId the signature algorithm of interest. * @return an algorithm identifier for the corresponding digest. */ AlgorithmIdentifier find(AlgorithmIdentifier sigAlgId); /** * Find the algorithm identifier that matches with * the passed in digest name. * * @param digAlgName the name of the digest algorithm of interest. * @return an algorithm identifier for the digest signature. */ AlgorithmIdentifier find(String digAlgName); }bouncycastle-1.49.orig/src/org/bouncycastle/operator/KeyWrapper.java0000644000175000017500000000041111442065640025267 0ustar ebourgebourgpackage org.bouncycastle.operator; import org.bouncycastle.asn1.x509.AlgorithmIdentifier; public interface KeyWrapper { AlgorithmIdentifier getAlgorithmIdentifier(); byte[] generateWrappedKey(GenericKey encryptionKey) throws OperatorException; } bouncycastle-1.49.orig/src/org/bouncycastle/operator/SecretKeySizeProvider.java0000644000175000017500000000030412115077000027432 0ustar ebourgebourgpackage org.bouncycastle.operator; import org.bouncycastle.asn1.x509.AlgorithmIdentifier; public interface SecretKeySizeProvider { int getKeySize(AlgorithmIdentifier algorithmIdentifier); } bouncycastle-1.49.orig/src/org/bouncycastle/operator/OperatorException.java0000644000175000017500000000057711444262526026671 0ustar ebourgebourgpackage org.bouncycastle.operator; public class OperatorException extends Exception { private Throwable cause; public OperatorException(String msg, Throwable cause) { super(msg); this.cause = cause; } public OperatorException(String msg) { super(msg); } public Throwable getCause() { return cause; } } bouncycastle-1.49.orig/src/org/bouncycastle/operator/OperatorStreamException.java0000644000175000017500000000054111442065640030030 0ustar ebourgebourgpackage org.bouncycastle.operator; import java.io.IOException; public class OperatorStreamException extends IOException { private Throwable cause; public OperatorStreamException(String msg, Throwable cause) { super(msg); this.cause = cause; } public Throwable getCause() { return cause; } } bouncycastle-1.49.orig/src/org/bouncycastle/operator/ContentSigner.java0000644000175000017500000000134111442065640025763 0ustar ebourgebourgpackage org.bouncycastle.operator; import java.io.OutputStream; import org.bouncycastle.asn1.x509.AlgorithmIdentifier; public interface ContentSigner { AlgorithmIdentifier getAlgorithmIdentifier(); /** * Returns a stream that will accept data for the purpose of calculating * a signature. Use org.bouncycastle.util.io.TeeOutputStream if you want to accumulate * the data on the fly as well. * * @return an OutputStream */ OutputStream getOutputStream(); /** * Returns a signature based on the current data written to the stream, since the * start or the last call to getSignature(). * * @return bytes representing the signature. */ byte[] getSignature(); } bouncycastle-1.49.orig/src/org/bouncycastle/operator/DigestCalculator.java0000644000175000017500000000166411502011336026430 0ustar ebourgebourgpackage org.bouncycastle.operator; import java.io.OutputStream; import org.bouncycastle.asn1.x509.AlgorithmIdentifier; /** * General interface for an operator that is able to calculate a digest from * a stream of output. */ public interface DigestCalculator { /** * Return the algorithm identifier representing the digest implemented by * this calculator. * * @return algorithm id and parameters. */ AlgorithmIdentifier getAlgorithmIdentifier(); /** * Returns a stream that will accept data for the purpose of calculating * a digest. Use org.bouncycastle.util.io.TeeOutputStream if you want to accumulate * the data on the fly as well. * * @return an OutputStream */ OutputStream getOutputStream(); /** * Return the digest calculated on what has been written to the calculator's output stream. * * @return a digest. */ byte[] getDigest(); } bouncycastle-1.49.orig/src/org/bouncycastle/operator/OutputEncryptor.java0000644000175000017500000000172011502011336026376 0ustar ebourgebourgpackage org.bouncycastle.operator; import java.io.OutputStream; import org.bouncycastle.asn1.x509.AlgorithmIdentifier; /** * General interface for an operator that is able to produce * an OutputStream that will output encrypted data. */ public interface OutputEncryptor { /** * Return the algorithm identifier describing the encryption * algorithm and parameters this encryptor uses. * * @return algorithm oid and parameters. */ AlgorithmIdentifier getAlgorithmIdentifier(); /** * Wrap the passed in output stream encOut, returning an output stream * that encrypts anything passed in before sending on to encOut. * * @param encOut output stream for encrypted output. * @return an encrypting OutputStream */ OutputStream getOutputStream(OutputStream encOut); /** * Return the key used for encrypting the output. * * @return the encryption key. */ GenericKey getKey(); } bouncycastle-1.49.orig/src/org/bouncycastle/operator/InputDecryptorProvider.java0000644000175000017500000000035712101607672027715 0ustar ebourgebourgpackage org.bouncycastle.operator; import org.bouncycastle.asn1.x509.AlgorithmIdentifier; public interface InputDecryptorProvider { public InputDecryptor get(AlgorithmIdentifier algorithm) throws OperatorCreationException; } bouncycastle-1.49.orig/src/org/bouncycastle/operator/ContentVerifier.java0000644000175000017500000000160311526123454026311 0ustar ebourgebourgpackage org.bouncycastle.operator; import java.io.OutputStream; import org.bouncycastle.asn1.x509.AlgorithmIdentifier; public interface ContentVerifier { /** * Return the algorithm identifier describing the signature * algorithm and parameters this expander supports. * * @return algorithm oid and parameters. */ AlgorithmIdentifier getAlgorithmIdentifier(); /** * Returns a stream that will accept data for the purpose of calculating * a signature for later verification. Use org.bouncycastle.util.io.TeeOutputStream if you want to accumulate * the data on the fly as well. * * @return an OutputStream */ OutputStream getOutputStream(); /** * @param expected expected value of the signature on the data. * @return true if the signature verifies, false otherwise */ boolean verify(byte[] expected); }bouncycastle-1.49.orig/src/org/bouncycastle/operator/SignatureAlgorithmIdentifierFinder.java0000644000175000017500000000073511727572137032164 0ustar ebourgebourgpackage org.bouncycastle.operator; import org.bouncycastle.asn1.x509.AlgorithmIdentifier; public interface SignatureAlgorithmIdentifierFinder { /** * Find the signature algorithm identifier that matches with * the passed in signature algorithm name. * * @param sigAlgName the name of the signature algorithm of interest. * @return an algorithm identifier for the corresponding signature. */ AlgorithmIdentifier find(String sigAlgName); }bouncycastle-1.49.orig/src/org/bouncycastle/operator/MacCalculator.java0000644000175000017500000000144511504531150025711 0ustar ebourgebourgpackage org.bouncycastle.operator; import java.io.OutputStream; import org.bouncycastle.asn1.x509.AlgorithmIdentifier; public interface MacCalculator { AlgorithmIdentifier getAlgorithmIdentifier(); /** * Returns a stream that will accept data for the purpose of calculating * the MAC for later verification. Use org.bouncycastle.util.io.TeeOutputStream if you want to accumulate * the data on the fly as well. * * @return an OutputStream */ OutputStream getOutputStream(); /** * Return the calculated MAC based on what has been written to the stream. * * @return calculated MAC. */ byte[] getMac(); /** * Return the key used for calculating the MAC. * * @return the MAC key. */ GenericKey getKey(); }bouncycastle-1.49.orig/src/org/bouncycastle/operator/AsymmetricKeyUnwrapper.java0000644000175000017500000000066211504011407027667 0ustar ebourgebourgpackage org.bouncycastle.operator; import org.bouncycastle.asn1.x509.AlgorithmIdentifier; public abstract class AsymmetricKeyUnwrapper implements KeyUnwrapper { private AlgorithmIdentifier algorithmId; protected AsymmetricKeyUnwrapper(AlgorithmIdentifier algorithmId) { this.algorithmId = algorithmId; } public AlgorithmIdentifier getAlgorithmIdentifier() { return algorithmId; } } bouncycastle-1.49.orig/src/org/bouncycastle/operator/bc/0000755000175000017500000000000012152033551022716 5ustar ebourgebourgbouncycastle-1.49.orig/src/org/bouncycastle/operator/bc/BcAESSymmetricKeyUnwrapper.java0000644000175000017500000000061011737210072030710 0ustar ebourgebourgpackage org.bouncycastle.operator.bc; import org.bouncycastle.crypto.engines.AESWrapEngine; import org.bouncycastle.crypto.params.KeyParameter; public class BcAESSymmetricKeyUnwrapper extends BcSymmetricKeyUnwrapper { public BcAESSymmetricKeyUnwrapper(KeyParameter wrappingKey) { super(AESUtil.determineKeyEncAlg(wrappingKey), new AESWrapEngine(), wrappingKey); } } bouncycastle-1.49.orig/src/org/bouncycastle/operator/bc/SEEDUtil.java0000644000175000017500000000055511737205541025154 0ustar ebourgebourgpackage org.bouncycastle.operator.bc; import org.bouncycastle.asn1.kisa.KISAObjectIdentifiers; import org.bouncycastle.asn1.x509.AlgorithmIdentifier; class SEEDUtil { static AlgorithmIdentifier determineKeyEncAlg() { // parameters absent return new AlgorithmIdentifier( KISAObjectIdentifiers.id_npki_app_cmsSeed_wrap); } } bouncycastle-1.49.orig/src/org/bouncycastle/operator/bc/BcSymmetricKeyWrapper.java0000644000175000017500000000267211737205541030033 0ustar ebourgebourgpackage org.bouncycastle.operator.bc; import java.security.SecureRandom; import org.bouncycastle.asn1.x509.AlgorithmIdentifier; import org.bouncycastle.crypto.Wrapper; import org.bouncycastle.crypto.params.KeyParameter; import org.bouncycastle.crypto.params.ParametersWithRandom; import org.bouncycastle.operator.GenericKey; import org.bouncycastle.operator.OperatorException; import org.bouncycastle.operator.SymmetricKeyWrapper; public class BcSymmetricKeyWrapper extends SymmetricKeyWrapper { private SecureRandom random; private Wrapper wrapper; private KeyParameter wrappingKey; public BcSymmetricKeyWrapper(AlgorithmIdentifier wrappingAlgorithm, Wrapper wrapper, KeyParameter wrappingKey) { super(wrappingAlgorithm); this.wrapper = wrapper; this.wrappingKey = wrappingKey; } public BcSymmetricKeyWrapper setSecureRandom(SecureRandom random) { this.random = random; return this; } public byte[] generateWrappedKey(GenericKey encryptionKey) throws OperatorException { byte[] contentEncryptionKeySpec = OperatorUtils.getKeyBytes(encryptionKey); if (random == null) { wrapper.init(true, wrappingKey); } else { wrapper.init(true, new ParametersWithRandom(wrappingKey, random)); } return wrapper.wrap(contentEncryptionKeySpec, 0, contentEncryptionKeySpec.length); } } bouncycastle-1.49.orig/src/org/bouncycastle/operator/bc/BcDefaultDigestProvider.java0000644000175000017500000001170612147304176030302 0ustar ebourgebourgpackage org.bouncycastle.operator.bc; import java.util.Collections; import java.util.HashMap; import java.util.Map; import org.bouncycastle.asn1.cryptopro.CryptoProObjectIdentifiers; import org.bouncycastle.asn1.nist.NISTObjectIdentifiers; import org.bouncycastle.asn1.oiw.OIWObjectIdentifiers; import org.bouncycastle.asn1.pkcs.PKCSObjectIdentifiers; import org.bouncycastle.asn1.teletrust.TeleTrusTObjectIdentifiers; import org.bouncycastle.asn1.x509.AlgorithmIdentifier; import org.bouncycastle.crypto.ExtendedDigest; import org.bouncycastle.crypto.digests.GOST3411Digest; import org.bouncycastle.crypto.digests.MD2Digest; import org.bouncycastle.crypto.digests.MD4Digest; import org.bouncycastle.crypto.digests.MD5Digest; import org.bouncycastle.crypto.digests.RIPEMD128Digest; import org.bouncycastle.crypto.digests.RIPEMD160Digest; import org.bouncycastle.crypto.digests.RIPEMD256Digest; import org.bouncycastle.crypto.digests.SHA1Digest; import org.bouncycastle.crypto.digests.SHA224Digest; import org.bouncycastle.crypto.digests.SHA256Digest; import org.bouncycastle.crypto.digests.SHA384Digest; import org.bouncycastle.crypto.digests.SHA512Digest; import org.bouncycastle.operator.OperatorCreationException; public class BcDefaultDigestProvider implements BcDigestProvider { private static final Map lookup = createTable(); private static Map createTable() { Map table = new HashMap(); table.put(OIWObjectIdentifiers.idSHA1, new BcDigestProvider() { public ExtendedDigest get(AlgorithmIdentifier digestAlgorithmIdentifier) { return new SHA1Digest(); } }); table.put(NISTObjectIdentifiers.id_sha224, new BcDigestProvider() { public ExtendedDigest get(AlgorithmIdentifier digestAlgorithmIdentifier) { return new SHA224Digest(); } }); table.put(NISTObjectIdentifiers.id_sha256, new BcDigestProvider() { public ExtendedDigest get(AlgorithmIdentifier digestAlgorithmIdentifier) { return new SHA256Digest(); } }); table.put(NISTObjectIdentifiers.id_sha384, new BcDigestProvider() { public ExtendedDigest get(AlgorithmIdentifier digestAlgorithmIdentifier) { return new SHA384Digest(); } }); table.put(NISTObjectIdentifiers.id_sha512, new BcDigestProvider() { public ExtendedDigest get(AlgorithmIdentifier digestAlgorithmIdentifier) { return new SHA512Digest(); } }); table.put(PKCSObjectIdentifiers.md5, new BcDigestProvider() { public ExtendedDigest get(AlgorithmIdentifier digestAlgorithmIdentifier) { return new MD5Digest(); } }); table.put(PKCSObjectIdentifiers.md4, new BcDigestProvider() { public ExtendedDigest get(AlgorithmIdentifier digestAlgorithmIdentifier) { return new MD4Digest(); } }); table.put(PKCSObjectIdentifiers.md2, new BcDigestProvider() { public ExtendedDigest get(AlgorithmIdentifier digestAlgorithmIdentifier) { return new MD2Digest(); } }); table.put(CryptoProObjectIdentifiers.gostR3411, new BcDigestProvider() { public ExtendedDigest get(AlgorithmIdentifier digestAlgorithmIdentifier) { return new GOST3411Digest(); } }); table.put(TeleTrusTObjectIdentifiers.ripemd128, new BcDigestProvider() { public ExtendedDigest get(AlgorithmIdentifier digestAlgorithmIdentifier) { return new RIPEMD128Digest(); } }); table.put(TeleTrusTObjectIdentifiers.ripemd160, new BcDigestProvider() { public ExtendedDigest get(AlgorithmIdentifier digestAlgorithmIdentifier) { return new RIPEMD160Digest(); } }); table.put(TeleTrusTObjectIdentifiers.ripemd256, new BcDigestProvider() { public ExtendedDigest get(AlgorithmIdentifier digestAlgorithmIdentifier) { return new RIPEMD256Digest(); } }); return Collections.unmodifiableMap(table); } public static final BcDigestProvider INSTANCE = new BcDefaultDigestProvider(); private BcDefaultDigestProvider() { } public ExtendedDigest get(AlgorithmIdentifier digestAlgorithmIdentifier) throws OperatorCreationException { BcDigestProvider extProv = (BcDigestProvider)lookup.get(digestAlgorithmIdentifier.getAlgorithm()); if (extProv == null) { throw new OperatorCreationException("cannot recognise digest"); } return extProv.get(digestAlgorithmIdentifier); } } bouncycastle-1.49.orig/src/org/bouncycastle/operator/bc/BcAsymmetricKeyUnwrapper.java0000644000175000017500000000346411737205541030537 0ustar ebourgebourgpackage org.bouncycastle.operator.bc; import org.bouncycastle.asn1.ASN1ObjectIdentifier; import org.bouncycastle.asn1.pkcs.PKCSObjectIdentifiers; import org.bouncycastle.asn1.x509.AlgorithmIdentifier; import org.bouncycastle.crypto.AsymmetricBlockCipher; import org.bouncycastle.crypto.InvalidCipherTextException; import org.bouncycastle.crypto.params.AsymmetricKeyParameter; import org.bouncycastle.operator.AsymmetricKeyUnwrapper; import org.bouncycastle.operator.GenericKey; import org.bouncycastle.operator.OperatorException; public abstract class BcAsymmetricKeyUnwrapper extends AsymmetricKeyUnwrapper { private AsymmetricKeyParameter privateKey; public BcAsymmetricKeyUnwrapper(AlgorithmIdentifier encAlgId, AsymmetricKeyParameter privateKey) { super(encAlgId); this.privateKey = privateKey; } public GenericKey generateUnwrappedKey(AlgorithmIdentifier encryptedKeyAlgorithm, byte[] encryptedKey) throws OperatorException { AsymmetricBlockCipher keyCipher = createAsymmetricUnwrapper(this.getAlgorithmIdentifier().getAlgorithm()); keyCipher.init(false, privateKey); try { byte[] key = keyCipher.processBlock(encryptedKey, 0, encryptedKey.length); if (encryptedKeyAlgorithm.getAlgorithm().equals(PKCSObjectIdentifiers.des_EDE3_CBC)) { return new GenericKey(encryptedKeyAlgorithm, key); } else { return new GenericKey(encryptedKeyAlgorithm, key); } } catch (InvalidCipherTextException e) { throw new OperatorException("unable to recover secret key: " + e.getMessage(), e); } } protected abstract AsymmetricBlockCipher createAsymmetricUnwrapper(ASN1ObjectIdentifier algorithm); } bouncycastle-1.49.orig/src/org/bouncycastle/operator/bc/BcAsymmetricKeyWrapper.java0000644000175000017500000000365311502570667030200 0ustar ebourgebourgpackage org.bouncycastle.operator.bc; import java.security.SecureRandom; import org.bouncycastle.asn1.ASN1ObjectIdentifier; import org.bouncycastle.asn1.x509.AlgorithmIdentifier; import org.bouncycastle.crypto.AsymmetricBlockCipher; import org.bouncycastle.crypto.CipherParameters; import org.bouncycastle.crypto.InvalidCipherTextException; import org.bouncycastle.crypto.params.AsymmetricKeyParameter; import org.bouncycastle.crypto.params.ParametersWithRandom; import org.bouncycastle.operator.AsymmetricKeyWrapper; import org.bouncycastle.operator.GenericKey; import org.bouncycastle.operator.OperatorException; public abstract class BcAsymmetricKeyWrapper extends AsymmetricKeyWrapper { private AsymmetricKeyParameter publicKey; private SecureRandom random; public BcAsymmetricKeyWrapper(AlgorithmIdentifier encAlgId, AsymmetricKeyParameter publicKey) { super(encAlgId); this.publicKey = publicKey; } public BcAsymmetricKeyWrapper setSecureRandom(SecureRandom random) { this.random = random; return this; } public byte[] generateWrappedKey(GenericKey encryptionKey) throws OperatorException { AsymmetricBlockCipher keyEncryptionCipher = createAsymmetricWrapper(getAlgorithmIdentifier().getAlgorithm()); CipherParameters params = publicKey; if (random != null) { params = new ParametersWithRandom(params, random); } try { byte[] keyEnc = OperatorUtils.getKeyBytes(encryptionKey); keyEncryptionCipher.init(true, publicKey); return keyEncryptionCipher.processBlock(keyEnc, 0, keyEnc.length); } catch (InvalidCipherTextException e) { throw new OperatorException("unable to encrypt contents key", e); } } protected abstract AsymmetricBlockCipher createAsymmetricWrapper(ASN1ObjectIdentifier algorithm); } bouncycastle-1.49.orig/src/org/bouncycastle/operator/bc/BcDSAContentVerifierProviderBuilder.java0000644000175000017500000000263712115035561032520 0ustar ebourgebourgpackage org.bouncycastle.operator.bc; import java.io.IOException; import org.bouncycastle.asn1.x509.AlgorithmIdentifier; import org.bouncycastle.asn1.x509.SubjectPublicKeyInfo; import org.bouncycastle.crypto.Digest; import org.bouncycastle.crypto.Signer; import org.bouncycastle.crypto.params.AsymmetricKeyParameter; import org.bouncycastle.crypto.signers.DSADigestSigner; import org.bouncycastle.crypto.signers.DSASigner; import org.bouncycastle.crypto.util.PublicKeyFactory; import org.bouncycastle.operator.DigestAlgorithmIdentifierFinder; import org.bouncycastle.operator.OperatorCreationException; public class BcDSAContentVerifierProviderBuilder extends BcContentVerifierProviderBuilder { private DigestAlgorithmIdentifierFinder digestAlgorithmFinder; public BcDSAContentVerifierProviderBuilder(DigestAlgorithmIdentifierFinder digestAlgorithmFinder) { this.digestAlgorithmFinder = digestAlgorithmFinder; } protected Signer createSigner(AlgorithmIdentifier sigAlgId) throws OperatorCreationException { AlgorithmIdentifier digAlg = digestAlgorithmFinder.find(sigAlgId); Digest dig = digestProvider.get(digAlg); return new DSADigestSigner(new DSASigner(), dig); } protected AsymmetricKeyParameter extractKeyParameters(SubjectPublicKeyInfo publicKeyInfo) throws IOException { return PublicKeyFactory.createKey(publicKeyInfo); } } bouncycastle-1.49.orig/src/org/bouncycastle/operator/bc/BcSignerOutputStream.java0000644000175000017500000000160311444344530027657 0ustar ebourgebourgpackage org.bouncycastle.operator.bc; import java.io.IOException; import java.io.OutputStream; import org.bouncycastle.crypto.CryptoException; import org.bouncycastle.crypto.Signer; public class BcSignerOutputStream extends OutputStream { private Signer sig; BcSignerOutputStream(Signer sig) { this.sig = sig; } public void write(byte[] bytes, int off, int len) throws IOException { sig.update(bytes, off, len); } public void write(byte[] bytes) throws IOException { sig.update(bytes, 0, bytes.length); } public void write(int b) throws IOException { sig.update((byte)b); } byte[] getSignature() throws CryptoException { return sig.generateSignature(); } boolean verify(byte[] expected) { return sig.verifySignature(expected); } }bouncycastle-1.49.orig/src/org/bouncycastle/operator/bc/BcRSAAsymmetricKeyUnwrapper.java0000644000175000017500000000137111737303571031102 0ustar ebourgebourgpackage org.bouncycastle.operator.bc; import org.bouncycastle.asn1.ASN1ObjectIdentifier; import org.bouncycastle.asn1.x509.AlgorithmIdentifier; import org.bouncycastle.crypto.AsymmetricBlockCipher; import org.bouncycastle.crypto.encodings.PKCS1Encoding; import org.bouncycastle.crypto.engines.RSAEngine; import org.bouncycastle.crypto.params.AsymmetricKeyParameter; public class BcRSAAsymmetricKeyUnwrapper extends BcAsymmetricKeyUnwrapper { public BcRSAAsymmetricKeyUnwrapper(AlgorithmIdentifier encAlgId, AsymmetricKeyParameter privateKey) { super(encAlgId, privateKey); } protected AsymmetricBlockCipher createAsymmetricUnwrapper(ASN1ObjectIdentifier algorithm) { return new PKCS1Encoding(new RSAEngine()); } } bouncycastle-1.49.orig/src/org/bouncycastle/operator/bc/BcDigestProvider.java0000644000175000017500000000054012115034666026766 0ustar ebourgebourgpackage org.bouncycastle.operator.bc; import org.bouncycastle.asn1.x509.AlgorithmIdentifier; import org.bouncycastle.crypto.ExtendedDigest; import org.bouncycastle.operator.OperatorCreationException; public interface BcDigestProvider { ExtendedDigest get(AlgorithmIdentifier digestAlgorithmIdentifier) throws OperatorCreationException; } bouncycastle-1.49.orig/src/org/bouncycastle/operator/bc/AESUtil.java0000644000175000017500000000166311737205541025045 0ustar ebourgebourgpackage org.bouncycastle.operator.bc; import org.bouncycastle.asn1.ASN1ObjectIdentifier; import org.bouncycastle.asn1.nist.NISTObjectIdentifiers; import org.bouncycastle.asn1.x509.AlgorithmIdentifier; import org.bouncycastle.crypto.params.KeyParameter; class AESUtil { static AlgorithmIdentifier determineKeyEncAlg(KeyParameter key) { int length = key.getKey().length * 8; ASN1ObjectIdentifier wrapOid; if (length == 128) { wrapOid = NISTObjectIdentifiers.id_aes128_wrap; } else if (length == 192) { wrapOid = NISTObjectIdentifiers.id_aes192_wrap; } else if (length == 256) { wrapOid = NISTObjectIdentifiers.id_aes256_wrap; } else { throw new IllegalArgumentException("illegal keysize in AES"); } return new AlgorithmIdentifier(wrapOid); // parameters absent } } bouncycastle-1.49.orig/src/org/bouncycastle/operator/bc/BcDigestCalculatorProvider.java0000644000175000017500000000373012115203326030773 0ustar ebourgebourgpackage org.bouncycastle.operator.bc; import java.io.IOException; import java.io.OutputStream; import java.util.Map; import org.bouncycastle.asn1.x509.AlgorithmIdentifier; import org.bouncycastle.crypto.Digest; import org.bouncycastle.crypto.ExtendedDigest; import org.bouncycastle.operator.DigestCalculator; import org.bouncycastle.operator.DigestCalculatorProvider; import org.bouncycastle.operator.OperatorCreationException; public class BcDigestCalculatorProvider implements DigestCalculatorProvider { private BcDigestProvider digestProvider = BcDefaultDigestProvider.INSTANCE; public DigestCalculator get(final AlgorithmIdentifier algorithm) throws OperatorCreationException { Digest dig = digestProvider.get(algorithm); final DigestOutputStream stream = new DigestOutputStream(dig); return new DigestCalculator() { public AlgorithmIdentifier getAlgorithmIdentifier() { return algorithm; } public OutputStream getOutputStream() { return stream; } public byte[] getDigest() { return stream.getDigest(); } }; } private class DigestOutputStream extends OutputStream { private Digest dig; DigestOutputStream(Digest dig) { this.dig = dig; } public void write(byte[] bytes, int off, int len) throws IOException { dig.update(bytes, off, len); } public void write(byte[] bytes) throws IOException { dig.update(bytes, 0, bytes.length); } public void write(int b) throws IOException { dig.update((byte)b); } byte[] getDigest() { byte[] d = new byte[dig.getDigestSize()]; dig.doFinal(d, 0); return d; } } }bouncycastle-1.49.orig/src/org/bouncycastle/operator/bc/BcDSAContentSignerBuilder.java0000644000175000017500000000146312115035561030455 0ustar ebourgebourgpackage org.bouncycastle.operator.bc; import org.bouncycastle.asn1.x509.AlgorithmIdentifier; import org.bouncycastle.crypto.Digest; import org.bouncycastle.crypto.Signer; import org.bouncycastle.crypto.signers.DSADigestSigner; import org.bouncycastle.crypto.signers.DSASigner; import org.bouncycastle.operator.OperatorCreationException; public class BcDSAContentSignerBuilder extends BcContentSignerBuilder { public BcDSAContentSignerBuilder(AlgorithmIdentifier sigAlgId, AlgorithmIdentifier digAlgId) { super(sigAlgId, digAlgId); } protected Signer createSigner(AlgorithmIdentifier sigAlgId, AlgorithmIdentifier digAlgId) throws OperatorCreationException { Digest dig = digestProvider.get(digAlgId); return new DSADigestSigner(new DSASigner(), dig); } } bouncycastle-1.49.orig/src/org/bouncycastle/operator/bc/BcRSAContentSignerBuilder.java0000644000175000017500000000136012115035420030461 0ustar ebourgebourgpackage org.bouncycastle.operator.bc; import org.bouncycastle.asn1.x509.AlgorithmIdentifier; import org.bouncycastle.crypto.Digest; import org.bouncycastle.crypto.Signer; import org.bouncycastle.crypto.signers.RSADigestSigner; import org.bouncycastle.operator.OperatorCreationException; public class BcRSAContentSignerBuilder extends BcContentSignerBuilder { public BcRSAContentSignerBuilder(AlgorithmIdentifier sigAlgId, AlgorithmIdentifier digAlgId) { super(sigAlgId, digAlgId); } protected Signer createSigner(AlgorithmIdentifier sigAlgId, AlgorithmIdentifier digAlgId) throws OperatorCreationException { Digest dig = digestProvider.get(digAlgId); return new RSADigestSigner(dig); } } bouncycastle-1.49.orig/src/org/bouncycastle/operator/bc/OperatorUtils.java0000644000175000017500000000102211444561601026375 0ustar ebourgebourgpackage org.bouncycastle.operator.bc; import java.security.Key; import org.bouncycastle.operator.GenericKey; class OperatorUtils { static byte[] getKeyBytes(GenericKey key) { if (key.getRepresentation() instanceof Key) { return ((Key)key.getRepresentation()).getEncoded(); } if (key.getRepresentation() instanceof byte[]) { return (byte[])key.getRepresentation(); } throw new IllegalArgumentException("unknown generic key type"); } }bouncycastle-1.49.orig/src/org/bouncycastle/operator/bc/CamelliaUtil.java0000644000175000017500000000175311737205541026144 0ustar ebourgebourgpackage org.bouncycastle.operator.bc; import org.bouncycastle.asn1.ASN1ObjectIdentifier; import org.bouncycastle.asn1.ntt.NTTObjectIdentifiers; import org.bouncycastle.asn1.x509.AlgorithmIdentifier; import org.bouncycastle.crypto.params.KeyParameter; class CamelliaUtil { static AlgorithmIdentifier determineKeyEncAlg(KeyParameter key) { int length = key.getKey().length * 8; ASN1ObjectIdentifier wrapOid; if (length == 128) { wrapOid = NTTObjectIdentifiers.id_camellia128_wrap; } else if (length == 192) { wrapOid = NTTObjectIdentifiers.id_camellia192_wrap; } else if (length == 256) { wrapOid = NTTObjectIdentifiers.id_camellia256_wrap; } else { throw new IllegalArgumentException( "illegal keysize in Camellia"); } return new AlgorithmIdentifier(wrapOid); // parameters must be // absent } } bouncycastle-1.49.orig/src/org/bouncycastle/operator/bc/BcRSAAsymmetricKeyWrapper.java0000644000175000017500000000211511502570636030532 0ustar ebourgebourgpackage org.bouncycastle.operator.bc; import java.io.IOException; import org.bouncycastle.asn1.ASN1ObjectIdentifier; import org.bouncycastle.asn1.x509.AlgorithmIdentifier; import org.bouncycastle.asn1.x509.SubjectPublicKeyInfo; import org.bouncycastle.crypto.AsymmetricBlockCipher; import org.bouncycastle.crypto.encodings.PKCS1Encoding; import org.bouncycastle.crypto.engines.RSAEngine; import org.bouncycastle.crypto.params.AsymmetricKeyParameter; import org.bouncycastle.crypto.util.PublicKeyFactory; public class BcRSAAsymmetricKeyWrapper extends BcAsymmetricKeyWrapper { public BcRSAAsymmetricKeyWrapper(AlgorithmIdentifier encAlgId, AsymmetricKeyParameter publicKey) { super(encAlgId, publicKey); } public BcRSAAsymmetricKeyWrapper(AlgorithmIdentifier encAlgId, SubjectPublicKeyInfo publicKeyInfo) throws IOException { super(encAlgId, PublicKeyFactory.createKey(publicKeyInfo)); } protected AsymmetricBlockCipher createAsymmetricWrapper(ASN1ObjectIdentifier algorithm) { return new PKCS1Encoding(new RSAEngine()); } } bouncycastle-1.49.orig/src/org/bouncycastle/operator/bc/BcRSAContentVerifierProviderBuilder.java0000644000175000017500000000253312115035561032531 0ustar ebourgebourgpackage org.bouncycastle.operator.bc; import java.io.IOException; import org.bouncycastle.asn1.x509.AlgorithmIdentifier; import org.bouncycastle.asn1.x509.SubjectPublicKeyInfo; import org.bouncycastle.crypto.Digest; import org.bouncycastle.crypto.Signer; import org.bouncycastle.crypto.params.AsymmetricKeyParameter; import org.bouncycastle.crypto.signers.RSADigestSigner; import org.bouncycastle.crypto.util.PublicKeyFactory; import org.bouncycastle.operator.DigestAlgorithmIdentifierFinder; import org.bouncycastle.operator.OperatorCreationException; public class BcRSAContentVerifierProviderBuilder extends BcContentVerifierProviderBuilder { private DigestAlgorithmIdentifierFinder digestAlgorithmFinder; public BcRSAContentVerifierProviderBuilder(DigestAlgorithmIdentifierFinder digestAlgorithmFinder) { this.digestAlgorithmFinder = digestAlgorithmFinder; } protected Signer createSigner(AlgorithmIdentifier sigAlgId) throws OperatorCreationException { AlgorithmIdentifier digAlg = digestAlgorithmFinder.find(sigAlgId); Digest dig = digestProvider.get(digAlg); return new RSADigestSigner(dig); } protected AsymmetricKeyParameter extractKeyParameters(SubjectPublicKeyInfo publicKeyInfo) throws IOException { return PublicKeyFactory.createKey(publicKeyInfo); } }bouncycastle-1.49.orig/src/org/bouncycastle/operator/bc/BcSymmetricKeyUnwrapper.java0000644000175000017500000000270411737205541030372 0ustar ebourgebourgpackage org.bouncycastle.operator.bc; import java.security.SecureRandom; import org.bouncycastle.asn1.x509.AlgorithmIdentifier; import org.bouncycastle.crypto.InvalidCipherTextException; import org.bouncycastle.crypto.Wrapper; import org.bouncycastle.crypto.params.KeyParameter; import org.bouncycastle.operator.GenericKey; import org.bouncycastle.operator.OperatorException; import org.bouncycastle.operator.SymmetricKeyUnwrapper; public class BcSymmetricKeyUnwrapper extends SymmetricKeyUnwrapper { private SecureRandom random; private Wrapper wrapper; private KeyParameter wrappingKey; public BcSymmetricKeyUnwrapper(AlgorithmIdentifier wrappingAlgorithm, Wrapper wrapper, KeyParameter wrappingKey) { super(wrappingAlgorithm); this.wrapper = wrapper; this.wrappingKey = wrappingKey; } public BcSymmetricKeyUnwrapper setSecureRandom(SecureRandom random) { this.random = random; return this; } public GenericKey generateUnwrappedKey(AlgorithmIdentifier encryptedKeyAlgorithm, byte[] encryptedKey) throws OperatorException { wrapper.init(false, wrappingKey); try { return new GenericKey(encryptedKeyAlgorithm, wrapper.unwrap(encryptedKey, 0, encryptedKey.length)); } catch (InvalidCipherTextException e) { throw new OperatorException("unable to unwrap key: " + e.getMessage(), e); } } } bouncycastle-1.49.orig/src/org/bouncycastle/operator/bc/BcAESSymmetricKeyWrapper.java0000644000175000017500000000060211737205541030353 0ustar ebourgebourgpackage org.bouncycastle.operator.bc; import org.bouncycastle.crypto.engines.AESWrapEngine; import org.bouncycastle.crypto.params.KeyParameter; public class BcAESSymmetricKeyWrapper extends BcSymmetricKeyWrapper { public BcAESSymmetricKeyWrapper(KeyParameter wrappingKey) { super(AESUtil.determineKeyEncAlg(wrappingKey), new AESWrapEngine(), wrappingKey); } } bouncycastle-1.49.orig/src/org/bouncycastle/operator/bc/BcContentSignerBuilder.java0000644000175000017500000000460312115035420030116 0ustar ebourgebourgpackage org.bouncycastle.operator.bc; import java.io.OutputStream; import java.security.SecureRandom; import java.util.Map; import org.bouncycastle.asn1.x509.AlgorithmIdentifier; import org.bouncycastle.crypto.CryptoException; import org.bouncycastle.crypto.Signer; import org.bouncycastle.crypto.params.AsymmetricKeyParameter; import org.bouncycastle.crypto.params.ParametersWithRandom; import org.bouncycastle.operator.ContentSigner; import org.bouncycastle.operator.OperatorCreationException; import org.bouncycastle.operator.RuntimeOperatorException; public abstract class BcContentSignerBuilder { private SecureRandom random; private AlgorithmIdentifier sigAlgId; private AlgorithmIdentifier digAlgId; protected BcDigestProvider digestProvider; public BcContentSignerBuilder(AlgorithmIdentifier sigAlgId, AlgorithmIdentifier digAlgId) { this.sigAlgId = sigAlgId; this.digAlgId = digAlgId; this.digestProvider = BcDefaultDigestProvider.INSTANCE; } public BcContentSignerBuilder setSecureRandom(SecureRandom random) { this.random = random; return this; } public ContentSigner build(AsymmetricKeyParameter privateKey) throws OperatorCreationException { final Signer sig = createSigner(sigAlgId, digAlgId); if (random != null) { sig.init(true, new ParametersWithRandom(privateKey, random)); } else { sig.init(true, privateKey); } return new ContentSigner() { private BcSignerOutputStream stream = new BcSignerOutputStream(sig); public AlgorithmIdentifier getAlgorithmIdentifier() { return sigAlgId; } public OutputStream getOutputStream() { return stream; } public byte[] getSignature() { try { return stream.getSignature(); } catch (CryptoException e) { throw new RuntimeOperatorException("exception obtaining signature: " + e.getMessage(), e); } } }; } protected abstract Signer createSigner(AlgorithmIdentifier sigAlgId, AlgorithmIdentifier algorithmIdentifier) throws OperatorCreationException; } bouncycastle-1.49.orig/src/org/bouncycastle/operator/bc/BcContentVerifierProviderBuilder.java0000644000175000017500000001074612115035561032170 0ustar ebourgebourgpackage org.bouncycastle.operator.bc; import java.io.IOException; import java.io.OutputStream; import org.bouncycastle.asn1.x509.AlgorithmIdentifier; import org.bouncycastle.asn1.x509.SubjectPublicKeyInfo; import org.bouncycastle.cert.X509CertificateHolder; import org.bouncycastle.crypto.Signer; import org.bouncycastle.crypto.params.AsymmetricKeyParameter; import org.bouncycastle.operator.ContentVerifier; import org.bouncycastle.operator.ContentVerifierProvider; import org.bouncycastle.operator.OperatorCreationException; public abstract class BcContentVerifierProviderBuilder { protected BcDigestProvider digestProvider; public BcContentVerifierProviderBuilder() { this.digestProvider = BcDefaultDigestProvider.INSTANCE; } public ContentVerifierProvider build(final X509CertificateHolder certHolder) throws OperatorCreationException { return new ContentVerifierProvider() { public boolean hasAssociatedCertificate() { return true; } public X509CertificateHolder getAssociatedCertificate() { return certHolder; } public ContentVerifier get(AlgorithmIdentifier algorithm) throws OperatorCreationException { try { AsymmetricKeyParameter publicKey = extractKeyParameters(certHolder.getSubjectPublicKeyInfo()); BcSignerOutputStream stream = createSignatureStream(algorithm, publicKey); return new SigVerifier(algorithm, stream); } catch (IOException e) { throw new OperatorCreationException("exception on setup: " + e, e); } } }; } public ContentVerifierProvider build(final AsymmetricKeyParameter publicKey) throws OperatorCreationException { return new ContentVerifierProvider() { public boolean hasAssociatedCertificate() { return false; } public X509CertificateHolder getAssociatedCertificate() { return null; } public ContentVerifier get(AlgorithmIdentifier algorithm) throws OperatorCreationException { BcSignerOutputStream stream = createSignatureStream(algorithm, publicKey); return new SigVerifier(algorithm, stream); } }; } private BcSignerOutputStream createSignatureStream(AlgorithmIdentifier algorithm, AsymmetricKeyParameter publicKey) throws OperatorCreationException { Signer sig = createSigner(algorithm); sig.init(false, publicKey); return new BcSignerOutputStream(sig); } /** * Extract an AsymmetricKeyParameter from the passed in SubjectPublicKeyInfo structure. * * @param publicKeyInfo a publicKeyInfo structure describing the public key required. * @return an AsymmetricKeyParameter object containing the appropriate public key. * @throws IOException if the publicKeyInfo data cannot be parsed, */ protected abstract AsymmetricKeyParameter extractKeyParameters(SubjectPublicKeyInfo publicKeyInfo) throws IOException; /** * Create the correct signer for the algorithm identifier sigAlgId. * * @param sigAlgId the algorithm details for the signature we want to verify. * @return a Signer object. * @throws OperatorCreationException if the Signer cannot be constructed. */ protected abstract Signer createSigner(AlgorithmIdentifier sigAlgId) throws OperatorCreationException; private class SigVerifier implements ContentVerifier { private BcSignerOutputStream stream; private AlgorithmIdentifier algorithm; SigVerifier(AlgorithmIdentifier algorithm, BcSignerOutputStream stream) { this.algorithm = algorithm; this.stream = stream; } public AlgorithmIdentifier getAlgorithmIdentifier() { return algorithm; } public OutputStream getOutputStream() { if (stream == null) { throw new IllegalStateException("verifier not initialised"); } return stream; } public boolean verify(byte[] expected) { return stream.verify(expected); } } }bouncycastle-1.49.orig/src/org/bouncycastle/operator/SymmetricKeyUnwrapper.java0000644000175000017500000000066011504015270027526 0ustar ebourgebourgpackage org.bouncycastle.operator; import org.bouncycastle.asn1.x509.AlgorithmIdentifier; public abstract class SymmetricKeyUnwrapper implements KeyUnwrapper { private AlgorithmIdentifier algorithmId; protected SymmetricKeyUnwrapper(AlgorithmIdentifier algorithmId) { this.algorithmId = algorithmId; } public AlgorithmIdentifier getAlgorithmIdentifier() { return algorithmId; } } bouncycastle-1.49.orig/src/org/bouncycastle/operator/InputExpander.java0000644000175000017500000000145411527077100025772 0ustar ebourgebourgpackage org.bouncycastle.operator; import java.io.InputStream; import org.bouncycastle.asn1.x509.AlgorithmIdentifier; /** * General interface for an operator that is able to produce * an InputStream that will produce uncompressed data. */ public interface InputExpander { /** * Return the algorithm identifier describing the compression * algorithm and parameters this expander supports. * * @return algorithm oid and parameters. */ AlgorithmIdentifier getAlgorithmIdentifier(); /** * Wrap the passed in input stream comIn, returning an input stream * that expands anything read in from comIn. * * @param comIn the compressed input data stream.. * @return an expanding InputStream. */ InputStream getInputStream(InputStream comIn); } bouncycastle-1.49.orig/src/org/bouncycastle/operator/DigestCalculatorProvider.java0000644000175000017500000000037411442065640030152 0ustar ebourgebourgpackage org.bouncycastle.operator; import org.bouncycastle.asn1.x509.AlgorithmIdentifier; public interface DigestCalculatorProvider { DigestCalculator get(AlgorithmIdentifier digestAlgorithmIdentifier) throws OperatorCreationException; } bouncycastle-1.49.orig/src/org/bouncycastle/operator/GenericKey.java0000644000175000017500000000203211737175743025241 0ustar ebourgebourgpackage org.bouncycastle.operator; import org.bouncycastle.asn1.x509.AlgorithmIdentifier; public class GenericKey { private AlgorithmIdentifier algorithmIdentifier; private Object representation; /** * @deprecated provide an AlgorithmIdentifier. * @param representation key data */ public GenericKey(Object representation) { this.algorithmIdentifier = null; this.representation = representation; } public GenericKey(AlgorithmIdentifier algorithmIdentifier, byte[] representation) { this.algorithmIdentifier = algorithmIdentifier; this.representation = representation; } protected GenericKey(AlgorithmIdentifier algorithmIdentifier, Object representation) { this.algorithmIdentifier = algorithmIdentifier; this.representation = representation; } public AlgorithmIdentifier getAlgorithmIdentifier() { return algorithmIdentifier; } public Object getRepresentation() { return representation; } } bouncycastle-1.49.orig/src/org/bouncycastle/operator/RuntimeOperatorException.java0000644000175000017500000000063311770512530030221 0ustar ebourgebourgpackage org.bouncycastle.operator; public class RuntimeOperatorException extends RuntimeException { private Throwable cause; public RuntimeOperatorException(String msg) { super(msg); } public RuntimeOperatorException(String msg, Throwable cause) { super(msg); this.cause = cause; } public Throwable getCause() { return cause; } } bouncycastle-1.49.orig/src/org/bouncycastle/operator/InputExpanderProvider.java0000644000175000017500000000027511526126067027513 0ustar ebourgebourgpackage org.bouncycastle.operator; import org.bouncycastle.asn1.x509.AlgorithmIdentifier; public interface InputExpanderProvider { InputExpander get(AlgorithmIdentifier algorithm); } bouncycastle-1.49.orig/src/org/bouncycastle/operator/MacCalculatorProvider.java0000644000175000017500000000030411730262015027417 0ustar ebourgebourgpackage org.bouncycastle.operator; import org.bouncycastle.asn1.x509.AlgorithmIdentifier; public interface MacCalculatorProvider { public MacCalculator get(AlgorithmIdentifier algorithm); } bouncycastle-1.49.orig/src/org/bouncycastle/operator/OutputCompressor.java0000644000175000017500000000151511526123454026562 0ustar ebourgebourgpackage org.bouncycastle.operator; import java.io.OutputStream; import org.bouncycastle.asn1.x509.AlgorithmIdentifier; /** * General interface for an operator that is able to produce * an OutputStream that will output compressed data. */ public interface OutputCompressor { /** * Return the algorithm identifier describing the compression * algorithm and parameters this compressor uses. * * @return algorithm oid and parameters. */ AlgorithmIdentifier getAlgorithmIdentifier(); /** * Wrap the passed in output stream comOut, returning an output stream * that compresses anything passed in before sending on to comOut. * * @param comOut output stream for compressed output. * @return a compressing OutputStream */ OutputStream getOutputStream(OutputStream comOut); } bouncycastle-1.49.orig/src/org/bouncycastle/operator/jcajce/0000755000175000017500000000000012152033551023551 5ustar ebourgebourgbouncycastle-1.49.orig/src/org/bouncycastle/operator/jcajce/JcaDigestCalculatorProviderBuilder.java0000644000175000017500000000607311724026312033314 0ustar ebourgebourgpackage org.bouncycastle.operator.jcajce; import java.io.IOException; import java.io.OutputStream; import java.security.GeneralSecurityException; import java.security.MessageDigest; import java.security.Provider; import org.bouncycastle.asn1.x509.AlgorithmIdentifier; import org.bouncycastle.jcajce.DefaultJcaJceHelper; import org.bouncycastle.jcajce.NamedJcaJceHelper; import org.bouncycastle.jcajce.ProviderJcaJceHelper; import org.bouncycastle.operator.DigestCalculator; import org.bouncycastle.operator.DigestCalculatorProvider; import org.bouncycastle.operator.OperatorCreationException; public class JcaDigestCalculatorProviderBuilder { private OperatorHelper helper = new OperatorHelper(new DefaultJcaJceHelper()); public JcaDigestCalculatorProviderBuilder() { } public JcaDigestCalculatorProviderBuilder setProvider(Provider provider) { this.helper = new OperatorHelper(new ProviderJcaJceHelper(provider)); return this; } public JcaDigestCalculatorProviderBuilder setProvider(String providerName) { this.helper = new OperatorHelper(new NamedJcaJceHelper(providerName)); return this; } public DigestCalculatorProvider build() throws OperatorCreationException { return new DigestCalculatorProvider() { public DigestCalculator get(final AlgorithmIdentifier algorithm) throws OperatorCreationException { final DigestOutputStream stream; try { MessageDigest dig = helper.createDigest(algorithm); stream = new DigestOutputStream(dig); } catch (GeneralSecurityException e) { throw new OperatorCreationException("exception on setup: " + e, e); } return new DigestCalculator() { public AlgorithmIdentifier getAlgorithmIdentifier() { return algorithm; } public OutputStream getOutputStream() { return stream; } public byte[] getDigest() { return stream.getDigest(); } }; } }; } private class DigestOutputStream extends OutputStream { private MessageDigest dig; DigestOutputStream(MessageDigest dig) { this.dig = dig; } public void write(byte[] bytes, int off, int len) throws IOException { dig.update(bytes, off, len); } public void write(byte[] bytes) throws IOException { dig.update(bytes); } public void write(int b) throws IOException { dig.update((byte)b); } byte[] getDigest() { return dig.digest(); } } }bouncycastle-1.49.orig/src/org/bouncycastle/operator/jcajce/JcaContentVerifierProviderBuilder.java0000644000175000017500000002104411724026312033164 0ustar ebourgebourgpackage org.bouncycastle.operator.jcajce; import java.io.IOException; import java.io.OutputStream; import java.security.GeneralSecurityException; import java.security.Provider; import java.security.PublicKey; import java.security.Signature; import java.security.SignatureException; import java.security.cert.CertificateEncodingException; import java.security.cert.CertificateException; import java.security.cert.X509Certificate; import org.bouncycastle.asn1.x509.AlgorithmIdentifier; import org.bouncycastle.cert.X509CertificateHolder; import org.bouncycastle.cert.jcajce.JcaX509CertificateHolder; import org.bouncycastle.jcajce.DefaultJcaJceHelper; import org.bouncycastle.jcajce.NamedJcaJceHelper; import org.bouncycastle.jcajce.ProviderJcaJceHelper; import org.bouncycastle.operator.ContentVerifier; import org.bouncycastle.operator.ContentVerifierProvider; import org.bouncycastle.operator.OperatorCreationException; import org.bouncycastle.operator.OperatorStreamException; import org.bouncycastle.operator.RawContentVerifier; import org.bouncycastle.operator.RuntimeOperatorException; public class JcaContentVerifierProviderBuilder { private OperatorHelper helper = new OperatorHelper(new DefaultJcaJceHelper()); public JcaContentVerifierProviderBuilder() { } public JcaContentVerifierProviderBuilder setProvider(Provider provider) { this.helper = new OperatorHelper(new ProviderJcaJceHelper(provider)); return this; } public JcaContentVerifierProviderBuilder setProvider(String providerName) { this.helper = new OperatorHelper(new NamedJcaJceHelper(providerName)); return this; } public ContentVerifierProvider build(X509CertificateHolder certHolder) throws OperatorCreationException, CertificateException { return build(helper.convertCertificate(certHolder)); } public ContentVerifierProvider build(final X509Certificate certificate) throws OperatorCreationException { final X509CertificateHolder certHolder; try { certHolder = new JcaX509CertificateHolder(certificate); } catch (CertificateEncodingException e) { throw new OperatorCreationException("cannot process certificate: " + e.getMessage(), e); } return new ContentVerifierProvider() { private SignatureOutputStream stream; public boolean hasAssociatedCertificate() { return true; } public X509CertificateHolder getAssociatedCertificate() { return certHolder; } public ContentVerifier get(AlgorithmIdentifier algorithm) throws OperatorCreationException { try { Signature sig = helper.createSignature(algorithm); sig.initVerify(certificate.getPublicKey()); stream = new SignatureOutputStream(sig); } catch (GeneralSecurityException e) { throw new OperatorCreationException("exception on setup: " + e, e); } Signature rawSig = createRawSig(algorithm, certificate.getPublicKey()); if (rawSig != null) { return new RawSigVerifier(algorithm, stream, rawSig); } else { return new SigVerifier(algorithm, stream); } } }; } public ContentVerifierProvider build(final PublicKey publicKey) throws OperatorCreationException { return new ContentVerifierProvider() { public boolean hasAssociatedCertificate() { return false; } public X509CertificateHolder getAssociatedCertificate() { return null; } public ContentVerifier get(AlgorithmIdentifier algorithm) throws OperatorCreationException { SignatureOutputStream stream = createSignatureStream(algorithm, publicKey); Signature rawSig = createRawSig(algorithm, publicKey); if (rawSig != null) { return new RawSigVerifier(algorithm, stream, rawSig); } else { return new SigVerifier(algorithm, stream); } } }; } private SignatureOutputStream createSignatureStream(AlgorithmIdentifier algorithm, PublicKey publicKey) throws OperatorCreationException { try { Signature sig = helper.createSignature(algorithm); sig.initVerify(publicKey); return new SignatureOutputStream(sig); } catch (GeneralSecurityException e) { throw new OperatorCreationException("exception on setup: " + e, e); } } private Signature createRawSig(AlgorithmIdentifier algorithm, PublicKey publicKey) { Signature rawSig; try { rawSig = helper.createRawSignature(algorithm); if (rawSig != null) { rawSig.initVerify(publicKey); } } catch (Exception e) { rawSig = null; } return rawSig; } private class SigVerifier implements ContentVerifier { private SignatureOutputStream stream; private AlgorithmIdentifier algorithm; SigVerifier(AlgorithmIdentifier algorithm, SignatureOutputStream stream) { this.algorithm = algorithm; this.stream = stream; } public AlgorithmIdentifier getAlgorithmIdentifier() { return algorithm; } public OutputStream getOutputStream() { if (stream == null) { throw new IllegalStateException("verifier not initialised"); } return stream; } public boolean verify(byte[] expected) { try { return stream.verify(expected); } catch (SignatureException e) { throw new RuntimeOperatorException("exception obtaining signature: " + e.getMessage(), e); } } } private class RawSigVerifier extends SigVerifier implements RawContentVerifier { private Signature rawSignature; RawSigVerifier(AlgorithmIdentifier algorithm, SignatureOutputStream stream, Signature rawSignature) { super(algorithm, stream); this.rawSignature = rawSignature; } public boolean verify(byte[] digest, byte[] expected) { try { rawSignature.update(digest); return rawSignature.verify(expected); } catch (SignatureException e) { throw new RuntimeOperatorException("exception obtaining raw signature: " + e.getMessage(), e); } } } private class SignatureOutputStream extends OutputStream { private Signature sig; SignatureOutputStream(Signature sig) { this.sig = sig; } public void write(byte[] bytes, int off, int len) throws IOException { try { sig.update(bytes, off, len); } catch (SignatureException e) { throw new OperatorStreamException("exception in content signer: " + e.getMessage(), e); } } public void write(byte[] bytes) throws IOException { try { sig.update(bytes); } catch (SignatureException e) { throw new OperatorStreamException("exception in content signer: " + e.getMessage(), e); } } public void write(int b) throws IOException { try { sig.update((byte)b); } catch (SignatureException e) { throw new OperatorStreamException("exception in content signer: " + e.getMessage(), e); } } boolean verify(byte[] expected) throws SignatureException { return sig.verify(expected); } } }bouncycastle-1.49.orig/src/org/bouncycastle/operator/jcajce/JceGenericKey.java0000644000175000017500000000144011737010455027070 0ustar ebourgebourgpackage org.bouncycastle.operator.jcajce; import java.security.Key; import org.bouncycastle.asn1.x509.AlgorithmIdentifier; import org.bouncycastle.operator.GenericKey; public class JceGenericKey extends GenericKey { /** * Attempt to simplify the key representation if possible. * * @param key a provider based key * @return the byte encoding if one exists, key object otherwise. */ private static Object getRepresentation(Key key) { byte[] keyBytes = key.getEncoded(); if (keyBytes != null) { return keyBytes; } return key; } public JceGenericKey(AlgorithmIdentifier algorithmIdentifier, Key representation) { super(algorithmIdentifier, getRepresentation(representation)); } } bouncycastle-1.49.orig/src/org/bouncycastle/operator/jcajce/JceAsymmetricKeyWrapper.java0000644000175000017500000000755211724026312031177 0ustar ebourgebourgpackage org.bouncycastle.operator.jcajce; import java.security.GeneralSecurityException; import java.security.Provider; import java.security.ProviderException; import java.security.PublicKey; import java.security.SecureRandom; import java.security.cert.X509Certificate; import java.util.HashMap; import java.util.Map; import javax.crypto.Cipher; import org.bouncycastle.asn1.ASN1ObjectIdentifier; import org.bouncycastle.asn1.x509.SubjectPublicKeyInfo; import org.bouncycastle.jcajce.DefaultJcaJceHelper; import org.bouncycastle.jcajce.NamedJcaJceHelper; import org.bouncycastle.jcajce.ProviderJcaJceHelper; import org.bouncycastle.operator.AsymmetricKeyWrapper; import org.bouncycastle.operator.GenericKey; import org.bouncycastle.operator.OperatorException; public class JceAsymmetricKeyWrapper extends AsymmetricKeyWrapper { private OperatorHelper helper = new OperatorHelper(new DefaultJcaJceHelper()); private Map extraMappings = new HashMap(); private PublicKey publicKey; private SecureRandom random; public JceAsymmetricKeyWrapper(PublicKey publicKey) { super(SubjectPublicKeyInfo.getInstance(publicKey.getEncoded()).getAlgorithm()); this.publicKey = publicKey; } public JceAsymmetricKeyWrapper(X509Certificate certificate) { this(certificate.getPublicKey()); } public JceAsymmetricKeyWrapper setProvider(Provider provider) { this.helper = new OperatorHelper(new ProviderJcaJceHelper(provider)); return this; } public JceAsymmetricKeyWrapper setProvider(String providerName) { this.helper = new OperatorHelper(new NamedJcaJceHelper(providerName)); return this; } public JceAsymmetricKeyWrapper setSecureRandom(SecureRandom random) { this.random = random; return this; } /** * Internally algorithm ids are converted into cipher names using a lookup table. For some providers * the standard lookup table won't work. Use this method to establish a specific mapping from an * algorithm identifier to a specific algorithm. *

    * For example: *

         *     unwrapper.setAlgorithmMapping(PKCSObjectIdentifiers.rsaEncryption, "RSA");
         * 
    *

    * @param algorithm OID of algorithm in recipient. * @param algorithmName JCE algorithm name to use. * @return the current Wrapper. */ public JceAsymmetricKeyWrapper setAlgorithmMapping(ASN1ObjectIdentifier algorithm, String algorithmName) { extraMappings.put(algorithm, algorithmName); return this; } public byte[] generateWrappedKey(GenericKey encryptionKey) throws OperatorException { Cipher keyEncryptionCipher = helper.createAsymmetricWrapper(getAlgorithmIdentifier().getAlgorithm(), extraMappings); byte[] encryptedKeyBytes = null; try { keyEncryptionCipher.init(Cipher.WRAP_MODE, publicKey, random); encryptedKeyBytes = keyEncryptionCipher.wrap(OperatorUtils.getJceKey(encryptionKey)); } catch (GeneralSecurityException e) { } catch (IllegalStateException e) { } catch (UnsupportedOperationException e) { } catch (ProviderException e) { } // some providers do not support WRAP (this appears to be only for asymmetric algorithms) if (encryptedKeyBytes == null) { try { keyEncryptionCipher.init(Cipher.ENCRYPT_MODE, publicKey, random); encryptedKeyBytes = keyEncryptionCipher.doFinal(OperatorUtils.getJceKey(encryptionKey).getEncoded()); } catch (GeneralSecurityException e) { throw new OperatorException("unable to encrypt contents key", e); } } return encryptedKeyBytes; } } bouncycastle-1.49.orig/src/org/bouncycastle/operator/jcajce/JceSymmetricKeyWrapper.java0000644000175000017500000001137212103437526031036 0ustar ebourgebourgpackage org.bouncycastle.operator.jcajce; import java.security.GeneralSecurityException; import java.security.Key; import java.security.Provider; import java.security.SecureRandom; import javax.crypto.Cipher; import javax.crypto.SecretKey; import org.bouncycastle.asn1.ASN1Integer; import org.bouncycastle.asn1.ASN1ObjectIdentifier; import org.bouncycastle.asn1.DERNull; import org.bouncycastle.asn1.kisa.KISAObjectIdentifiers; import org.bouncycastle.asn1.nist.NISTObjectIdentifiers; import org.bouncycastle.asn1.ntt.NTTObjectIdentifiers; import org.bouncycastle.asn1.x509.AlgorithmIdentifier; import org.bouncycastle.jcajce.DefaultJcaJceHelper; import org.bouncycastle.jcajce.NamedJcaJceHelper; import org.bouncycastle.jcajce.ProviderJcaJceHelper; import org.bouncycastle.operator.GenericKey; import org.bouncycastle.operator.OperatorException; import org.bouncycastle.operator.SymmetricKeyWrapper; public class JceSymmetricKeyWrapper extends SymmetricKeyWrapper { private OperatorHelper helper = new OperatorHelper(new DefaultJcaJceHelper()); private SecureRandom random; private SecretKey wrappingKey; public JceSymmetricKeyWrapper(SecretKey wrappingKey) { super(determineKeyEncAlg(wrappingKey)); this.wrappingKey = wrappingKey; } public JceSymmetricKeyWrapper setProvider(Provider provider) { this.helper = new OperatorHelper(new ProviderJcaJceHelper(provider)); return this; } public JceSymmetricKeyWrapper setProvider(String providerName) { this.helper = new OperatorHelper(new NamedJcaJceHelper(providerName)); return this; } public JceSymmetricKeyWrapper setSecureRandom(SecureRandom random) { this.random = random; return this; } public byte[] generateWrappedKey(GenericKey encryptionKey) throws OperatorException { Key contentEncryptionKeySpec = OperatorUtils.getJceKey(encryptionKey); Cipher keyEncryptionCipher = helper.createSymmetricWrapper(this.getAlgorithmIdentifier().getAlgorithm()); try { keyEncryptionCipher.init(Cipher.WRAP_MODE, wrappingKey, random); return keyEncryptionCipher.wrap(contentEncryptionKeySpec); } catch (GeneralSecurityException e) { throw new OperatorException("cannot wrap key: " + e.getMessage(), e); } } private static AlgorithmIdentifier determineKeyEncAlg(SecretKey key) { String algorithm = key.getAlgorithm(); if (algorithm.startsWith("DES")) { return new AlgorithmIdentifier(new ASN1ObjectIdentifier( "1.2.840.113549.1.9.16.3.6"), DERNull.INSTANCE); } else if (algorithm.startsWith("RC2")) { return new AlgorithmIdentifier(new ASN1ObjectIdentifier( "1.2.840.113549.1.9.16.3.7"), new ASN1Integer(58)); } else if (algorithm.startsWith("AES")) { int length = key.getEncoded().length * 8; ASN1ObjectIdentifier wrapOid; if (length == 128) { wrapOid = NISTObjectIdentifiers.id_aes128_wrap; } else if (length == 192) { wrapOid = NISTObjectIdentifiers.id_aes192_wrap; } else if (length == 256) { wrapOid = NISTObjectIdentifiers.id_aes256_wrap; } else { throw new IllegalArgumentException("illegal keysize in AES"); } return new AlgorithmIdentifier(wrapOid); // parameters absent } else if (algorithm.startsWith("SEED")) { // parameters absent return new AlgorithmIdentifier( KISAObjectIdentifiers.id_npki_app_cmsSeed_wrap); } else if (algorithm.startsWith("Camellia")) { int length = key.getEncoded().length * 8; ASN1ObjectIdentifier wrapOid; if (length == 128) { wrapOid = NTTObjectIdentifiers.id_camellia128_wrap; } else if (length == 192) { wrapOid = NTTObjectIdentifiers.id_camellia192_wrap; } else if (length == 256) { wrapOid = NTTObjectIdentifiers.id_camellia256_wrap; } else { throw new IllegalArgumentException( "illegal keysize in Camellia"); } return new AlgorithmIdentifier(wrapOid); // parameters must be // absent } else { throw new IllegalArgumentException("unknown algorithm"); } } } bouncycastle-1.49.orig/src/org/bouncycastle/operator/jcajce/OperatorUtils.java0000644000175000017500000000110511442065640027232 0ustar ebourgebourgpackage org.bouncycastle.operator.jcajce; import java.security.Key; import javax.crypto.spec.SecretKeySpec; import org.bouncycastle.operator.GenericKey; class OperatorUtils { static Key getJceKey(GenericKey key) { if (key.getRepresentation() instanceof Key) { return (Key)key.getRepresentation(); } if (key.getRepresentation() instanceof byte[]) { return new SecretKeySpec((byte[])key.getRepresentation(), "ENC"); } throw new IllegalArgumentException("unknown generic key type"); } }bouncycastle-1.49.orig/src/org/bouncycastle/operator/jcajce/JceSymmetricKeyUnwrapper.java0000644000175000017500000000411011737175743031405 0ustar ebourgebourgpackage org.bouncycastle.operator.jcajce; import java.security.InvalidKeyException; import java.security.NoSuchAlgorithmException; import java.security.Provider; import javax.crypto.Cipher; import javax.crypto.SecretKey; import org.bouncycastle.asn1.x509.AlgorithmIdentifier; import org.bouncycastle.jcajce.DefaultJcaJceHelper; import org.bouncycastle.jcajce.NamedJcaJceHelper; import org.bouncycastle.jcajce.ProviderJcaJceHelper; import org.bouncycastle.operator.GenericKey; import org.bouncycastle.operator.OperatorException; import org.bouncycastle.operator.SymmetricKeyUnwrapper; public class JceSymmetricKeyUnwrapper extends SymmetricKeyUnwrapper { private OperatorHelper helper = new OperatorHelper(new DefaultJcaJceHelper()); private SecretKey secretKey; public JceSymmetricKeyUnwrapper(AlgorithmIdentifier algorithmIdentifier, SecretKey secretKey) { super(algorithmIdentifier); this.secretKey = secretKey; } public JceSymmetricKeyUnwrapper setProvider(Provider provider) { this.helper = new OperatorHelper(new ProviderJcaJceHelper(provider)); return this; } public JceSymmetricKeyUnwrapper setProvider(String providerName) { this.helper = new OperatorHelper(new NamedJcaJceHelper(providerName)); return this; } public GenericKey generateUnwrappedKey(AlgorithmIdentifier encryptedKeyAlgorithm, byte[] encryptedKey) throws OperatorException { try { Cipher keyCipher = helper.createSymmetricWrapper(this.getAlgorithmIdentifier().getAlgorithm()); keyCipher.init(Cipher.UNWRAP_MODE, secretKey); return new JceGenericKey(encryptedKeyAlgorithm, keyCipher.unwrap(encryptedKey, helper.getKeyAlgorithmName(encryptedKeyAlgorithm.getAlgorithm()), Cipher.SECRET_KEY)); } catch (InvalidKeyException e) { throw new OperatorException("key invalid in message.", e); } catch (NoSuchAlgorithmException e) { throw new OperatorException("can't find algorithm.", e); } } } bouncycastle-1.49.orig/src/org/bouncycastle/operator/jcajce/JceAsymmetricKeyUnwrapper.java0000644000175000017500000001010711737175743031551 0ustar ebourgebourgpackage org.bouncycastle.operator.jcajce; import java.security.GeneralSecurityException; import java.security.InvalidKeyException; import java.security.Key; import java.security.PrivateKey; import java.security.Provider; import java.security.ProviderException; import java.util.HashMap; import java.util.Map; import javax.crypto.BadPaddingException; import javax.crypto.Cipher; import javax.crypto.IllegalBlockSizeException; import javax.crypto.spec.SecretKeySpec; import org.bouncycastle.asn1.ASN1ObjectIdentifier; import org.bouncycastle.asn1.x509.AlgorithmIdentifier; import org.bouncycastle.jcajce.DefaultJcaJceHelper; import org.bouncycastle.jcajce.NamedJcaJceHelper; import org.bouncycastle.jcajce.ProviderJcaJceHelper; import org.bouncycastle.operator.AsymmetricKeyUnwrapper; import org.bouncycastle.operator.GenericKey; import org.bouncycastle.operator.OperatorException; public class JceAsymmetricKeyUnwrapper extends AsymmetricKeyUnwrapper { private OperatorHelper helper = new OperatorHelper(new DefaultJcaJceHelper()); private Map extraMappings = new HashMap(); private PrivateKey privKey; public JceAsymmetricKeyUnwrapper(AlgorithmIdentifier algorithmIdentifier, PrivateKey privKey) { super(algorithmIdentifier); this.privKey = privKey; } public JceAsymmetricKeyUnwrapper setProvider(Provider provider) { this.helper = new OperatorHelper(new ProviderJcaJceHelper(provider)); return this; } public JceAsymmetricKeyUnwrapper setProvider(String providerName) { this.helper = new OperatorHelper(new NamedJcaJceHelper(providerName)); return this; } /** * Internally algorithm ids are converted into cipher names using a lookup table. For some providers * the standard lookup table won't work. Use this method to establish a specific mapping from an * algorithm identifier to a specific algorithm. *

    * For example: *

         *     unwrapper.setAlgorithmMapping(PKCSObjectIdentifiers.rsaEncryption, "RSA");
         * 
    *

    * @param algorithm OID of algorithm in recipient. * @param algorithmName JCE algorithm name to use. * @return the current Unwrapper. */ public JceAsymmetricKeyUnwrapper setAlgorithmMapping(ASN1ObjectIdentifier algorithm, String algorithmName) { extraMappings.put(algorithm, algorithmName); return this; } public GenericKey generateUnwrappedKey(AlgorithmIdentifier encryptedKeyAlgorithm, byte[] encryptedKey) throws OperatorException { try { Key sKey = null; Cipher keyCipher = helper.createAsymmetricWrapper(this.getAlgorithmIdentifier().getAlgorithm(), extraMappings); try { keyCipher.init(Cipher.UNWRAP_MODE, privKey); sKey = keyCipher.unwrap(encryptedKey, helper.getKeyAlgorithmName(encryptedKeyAlgorithm.getAlgorithm()), Cipher.SECRET_KEY); } catch (GeneralSecurityException e) { } catch (IllegalStateException e) { } catch (UnsupportedOperationException e) { } catch (ProviderException e) { } // some providers do not support UNWRAP (this appears to be only for asymmetric algorithms) if (sKey == null) { keyCipher.init(Cipher.DECRYPT_MODE, privKey); sKey = new SecretKeySpec(keyCipher.doFinal(encryptedKey), encryptedKeyAlgorithm.getAlgorithm().getId()); } return new JceGenericKey(encryptedKeyAlgorithm, sKey); } catch (InvalidKeyException e) { throw new OperatorException("key invalid: " + e.getMessage(), e); } catch (IllegalBlockSizeException e) { throw new OperatorException("illegal blocksize: " + e.getMessage(), e); } catch (BadPaddingException e) { throw new OperatorException("bad padding: " + e.getMessage(), e); } } } bouncycastle-1.49.orig/src/org/bouncycastle/operator/jcajce/OperatorHelper.java0000644000175000017500000003321600000000120027323 0ustar ebourgebourgpackage org.bouncycastle.operator.jcajce; import java.io.ByteArrayInputStream; import java.io.IOException; import java.security.AlgorithmParameters; import java.security.GeneralSecurityException; import java.security.MessageDigest; import java.security.NoSuchAlgorithmException; import java.security.NoSuchProviderException; import java.security.Signature; import java.security.cert.CertificateException; import java.security.cert.CertificateFactory; import java.security.cert.X509Certificate; import java.security.spec.PSSParameterSpec; import java.util.HashMap; import java.util.Map; import javax.crypto.Cipher; import org.bouncycastle.asn1.ASN1Encodable; import org.bouncycastle.asn1.ASN1ObjectIdentifier; import org.bouncycastle.asn1.DERNull; import org.bouncycastle.asn1.cryptopro.CryptoProObjectIdentifiers; import org.bouncycastle.asn1.kisa.KISAObjectIdentifiers; import org.bouncycastle.asn1.nist.NISTObjectIdentifiers; import org.bouncycastle.asn1.ntt.NTTObjectIdentifiers; import org.bouncycastle.asn1.oiw.OIWObjectIdentifiers; import org.bouncycastle.asn1.pkcs.PKCSObjectIdentifiers; import org.bouncycastle.asn1.pkcs.RSASSAPSSparams; import org.bouncycastle.asn1.teletrust.TeleTrusTObjectIdentifiers; import org.bouncycastle.asn1.x509.AlgorithmIdentifier; import org.bouncycastle.asn1.x9.X9ObjectIdentifiers; import org.bouncycastle.cert.X509CertificateHolder; import org.bouncycastle.jcajce.JcaJceHelper; import org.bouncycastle.operator.OperatorCreationException; class OperatorHelper { private static final Map oids = new HashMap(); private static final Map asymmetricWrapperAlgNames = new HashMap(); private static final Map symmetricWrapperAlgNames = new HashMap(); private static final Map symmetricKeyAlgNames = new HashMap(); static { // // reverse mappings // oids.put(new ASN1ObjectIdentifier("1.2.840.113549.1.1.5"), "SHA1WITHRSA"); oids.put(PKCSObjectIdentifiers.sha224WithRSAEncryption, "SHA224WITHRSA"); oids.put(PKCSObjectIdentifiers.sha256WithRSAEncryption, "SHA256WITHRSA"); oids.put(PKCSObjectIdentifiers.sha384WithRSAEncryption, "SHA384WITHRSA"); oids.put(PKCSObjectIdentifiers.sha512WithRSAEncryption, "SHA512WITHRSA"); oids.put(CryptoProObjectIdentifiers.gostR3411_94_with_gostR3410_94, "GOST3411WITHGOST3410"); oids.put(CryptoProObjectIdentifiers.gostR3411_94_with_gostR3410_2001, "GOST3411WITHECGOST3410"); oids.put(new ASN1ObjectIdentifier("1.2.840.113549.1.1.4"), "MD5WITHRSA"); oids.put(new ASN1ObjectIdentifier("1.2.840.113549.1.1.2"), "MD2WITHRSA"); oids.put(new ASN1ObjectIdentifier("1.2.840.10040.4.3"), "SHA1WITHDSA"); oids.put(X9ObjectIdentifiers.ecdsa_with_SHA1, "SHA1WITHECDSA"); oids.put(X9ObjectIdentifiers.ecdsa_with_SHA224, "SHA224WITHECDSA"); oids.put(X9ObjectIdentifiers.ecdsa_with_SHA256, "SHA256WITHECDSA"); oids.put(X9ObjectIdentifiers.ecdsa_with_SHA384, "SHA384WITHECDSA"); oids.put(X9ObjectIdentifiers.ecdsa_with_SHA512, "SHA512WITHECDSA"); oids.put(OIWObjectIdentifiers.sha1WithRSA, "SHA1WITHRSA"); oids.put(OIWObjectIdentifiers.dsaWithSHA1, "SHA1WITHDSA"); oids.put(NISTObjectIdentifiers.dsa_with_sha224, "SHA224WITHDSA"); oids.put(NISTObjectIdentifiers.dsa_with_sha256, "SHA256WITHDSA"); oids.put(OIWObjectIdentifiers.idSHA1, "SHA-1"); oids.put(NISTObjectIdentifiers.id_sha224, "SHA-224"); oids.put(NISTObjectIdentifiers.id_sha256, "SHA-256"); oids.put(NISTObjectIdentifiers.id_sha384, "SHA-384"); oids.put(NISTObjectIdentifiers.id_sha512, "SHA-512"); oids.put(TeleTrusTObjectIdentifiers.ripemd128, "RIPEMD-128"); oids.put(TeleTrusTObjectIdentifiers.ripemd160, "RIPEMD-160"); oids.put(TeleTrusTObjectIdentifiers.ripemd256, "RIPEMD-256"); asymmetricWrapperAlgNames.put(PKCSObjectIdentifiers.rsaEncryption, "RSA/ECB/PKCS1Padding"); symmetricWrapperAlgNames.put(PKCSObjectIdentifiers.id_alg_CMS3DESwrap, "DESEDEWrap"); symmetricWrapperAlgNames.put(PKCSObjectIdentifiers.id_alg_CMSRC2wrap, "RC2Wrap"); symmetricWrapperAlgNames.put(NISTObjectIdentifiers.id_aes128_wrap, "AESWrap"); symmetricWrapperAlgNames.put(NISTObjectIdentifiers.id_aes192_wrap, "AESWrap"); symmetricWrapperAlgNames.put(NISTObjectIdentifiers.id_aes256_wrap, "AESWrap"); symmetricWrapperAlgNames.put(NTTObjectIdentifiers.id_camellia128_wrap, "CamelliaWrap"); symmetricWrapperAlgNames.put(NTTObjectIdentifiers.id_camellia192_wrap, "CamelliaWrap"); symmetricWrapperAlgNames.put(NTTObjectIdentifiers.id_camellia256_wrap, "CamelliaWrap"); symmetricWrapperAlgNames.put(KISAObjectIdentifiers.id_npki_app_cmsSeed_wrap, "SEEDWrap"); symmetricWrapperAlgNames.put(PKCSObjectIdentifiers.des_EDE3_CBC, "DESede"); symmetricKeyAlgNames.put(NISTObjectIdentifiers.aes, "AES"); symmetricKeyAlgNames.put(NISTObjectIdentifiers.id_aes128_CBC, "AES"); symmetricKeyAlgNames.put(NISTObjectIdentifiers.id_aes192_CBC, "AES"); symmetricKeyAlgNames.put(NISTObjectIdentifiers.id_aes256_CBC, "AES"); symmetricKeyAlgNames.put(PKCSObjectIdentifiers.des_EDE3_CBC, "DESede"); symmetricKeyAlgNames.put(PKCSObjectIdentifiers.RC2_CBC, "RC2"); } private JcaJceHelper helper; OperatorHelper(JcaJceHelper helper) { this.helper = helper; } Cipher createAsymmetricWrapper(ASN1ObjectIdentifier algorithm, Map extraAlgNames) throws OperatorCreationException { try { String cipherName = null; if (!extraAlgNames.isEmpty()) { cipherName = (String)extraAlgNames.get(algorithm); } if (cipherName == null) { cipherName = (String)asymmetricWrapperAlgNames.get(algorithm); } if (cipherName != null) { try { // this is reversed as the Sun policy files now allow unlimited strength RSA return helper.createCipher(cipherName); } catch (NoSuchAlgorithmException e) { // try alternate for RSA if (cipherName.equals("RSA/ECB/PKCS1Padding")) { try { return helper.createCipher("RSA/NONE/PKCS1Padding"); } catch (NoSuchAlgorithmException ex) { // Ignore } } // Ignore } } return helper.createCipher(algorithm.getId()); } catch (GeneralSecurityException e) { throw new OperatorCreationException("cannot create cipher: " + e.getMessage(), e); } } Cipher createSymmetricWrapper(ASN1ObjectIdentifier algorithm) throws OperatorCreationException { try { String cipherName = (String)symmetricWrapperAlgNames.get(algorithm); if (cipherName != null) { try { // this is reversed as the Sun policy files now allow unlimited strength RSA return helper.createCipher(cipherName); } catch (NoSuchAlgorithmException e) { // Ignore } } return helper.createCipher(algorithm.getId()); } catch (GeneralSecurityException e) { throw new OperatorCreationException("cannot create cipher: " + e.getMessage(), e); } } MessageDigest createDigest(AlgorithmIdentifier digAlgId) throws GeneralSecurityException { MessageDigest dig; try { dig = helper.createDigest(getDigestAlgName(digAlgId.getAlgorithm())); } catch (NoSuchAlgorithmException e) { // // try an alternate // if (oids.get(digAlgId.getAlgorithm()) != null) { String digestAlgorithm = (String)oids.get(digAlgId.getAlgorithm()); dig = helper.createDigest(digestAlgorithm); } else { throw e; } } return dig; } Signature createSignature(AlgorithmIdentifier sigAlgId) throws GeneralSecurityException { Signature sig; try { sig = helper.createSignature(getSignatureName(sigAlgId)); } catch (NoSuchAlgorithmException e) { // // try an alternate // if (oids.get(sigAlgId.getAlgorithm()) != null) { String signatureAlgorithm = (String)oids.get(sigAlgId.getAlgorithm()); sig = helper.createSignature(signatureAlgorithm); } else { throw e; } } return sig; } public Signature createRawSignature(AlgorithmIdentifier algorithm) { Signature sig; try { String algName = getSignatureName(algorithm); algName = "NONE" + algName.substring(algName.indexOf("WITH")); sig = helper.createSignature(algName); // RFC 4056 // When the id-RSASSA-PSS algorithm identifier is used for a signature, // the AlgorithmIdentifier parameters field MUST contain RSASSA-PSS-params. if (algorithm.getAlgorithm().equals(PKCSObjectIdentifiers.id_RSASSA_PSS)) { AlgorithmParameters params = helper.createAlgorithmParameters(algName); params.init(algorithm.getParameters().toASN1Primitive().getEncoded(), "ASN.1"); PSSParameterSpec spec = (PSSParameterSpec)params.getParameterSpec(PSSParameterSpec.class); sig.setParameter(spec); } } catch (Exception e) { return null; } return sig; } private static String getSignatureName( AlgorithmIdentifier sigAlgId) { ASN1Encodable params = sigAlgId.getParameters(); if (params != null && !DERNull.INSTANCE.equals(params)) { if (sigAlgId.getAlgorithm().equals(PKCSObjectIdentifiers.id_RSASSA_PSS)) { RSASSAPSSparams rsaParams = RSASSAPSSparams.getInstance(params); return getDigestAlgName(rsaParams.getHashAlgorithm().getAlgorithm()) + "WITHRSAANDMGF1"; } } if (oids.containsKey(sigAlgId.getAlgorithm())) { return (String)oids.get(sigAlgId.getAlgorithm()); } return sigAlgId.getAlgorithm().getId(); } private static String getDigestAlgName( ASN1ObjectIdentifier digestAlgOID) { if (PKCSObjectIdentifiers.md5.equals(digestAlgOID)) { return "MD5"; } else if (OIWObjectIdentifiers.idSHA1.equals(digestAlgOID)) { return "SHA1"; } else if (NISTObjectIdentifiers.id_sha224.equals(digestAlgOID)) { return "SHA224"; } else if (NISTObjectIdentifiers.id_sha256.equals(digestAlgOID)) { return "SHA256"; } else if (NISTObjectIdentifiers.id_sha384.equals(digestAlgOID)) { return "SHA384"; } else if (NISTObjectIdentifiers.id_sha512.equals(digestAlgOID)) { return "SHA512"; } else if (TeleTrusTObjectIdentifiers.ripemd128.equals(digestAlgOID)) { return "RIPEMD128"; } else if (TeleTrusTObjectIdentifiers.ripemd160.equals(digestAlgOID)) { return "RIPEMD160"; } else if (TeleTrusTObjectIdentifiers.ripemd256.equals(digestAlgOID)) { return "RIPEMD256"; } else if (CryptoProObjectIdentifiers.gostR3411.equals(digestAlgOID)) { return "GOST3411"; } else { return digestAlgOID.getId(); } } public X509Certificate convertCertificate(X509CertificateHolder certHolder) throws CertificateException { try { CertificateFactory certFact = helper.createCertificateFactory("X.509"); return (X509Certificate)certFact.generateCertificate(new ByteArrayInputStream(certHolder.getEncoded())); } catch (IOException e) { throw new OpCertificateException("cannot get encoded form of certificate: " + e.getMessage(), e); } catch (NoSuchAlgorithmException e) { throw new OpCertificateException("cannot create certificate factory: " + e.getMessage(), e); } catch (NoSuchProviderException e) { throw new OpCertificateException("cannot find factory provider: " + e.getMessage(), e); } } // TODO: put somewhere public so cause easily accessed private static class OpCertificateException extends CertificateException { private Throwable cause; public OpCertificateException(String msg, Throwable cause) { super(msg); this.cause = cause; } public Throwable getCause() { return cause; } } String getKeyAlgorithmName(ASN1ObjectIdentifier oid) { String name = (String)symmetricKeyAlgNames.get(oid); if (name != null) { return name; } return oid.getId(); } } bouncycastle-1.49.orig/src/org/bouncycastle/operator/jcajce/JcaContentSignerBuilder.java0000644000175000017500000001074111724025607031135 0ustar ebourgebourgpackage org.bouncycastle.operator.jcajce; import java.io.IOException; import java.io.OutputStream; import java.security.GeneralSecurityException; import java.security.PrivateKey; import java.security.Provider; import java.security.SecureRandom; import java.security.Signature; import java.security.SignatureException; import org.bouncycastle.asn1.x509.AlgorithmIdentifier; import org.bouncycastle.jcajce.DefaultJcaJceHelper; import org.bouncycastle.jcajce.NamedJcaJceHelper; import org.bouncycastle.jcajce.ProviderJcaJceHelper; import org.bouncycastle.operator.ContentSigner; import org.bouncycastle.operator.DefaultSignatureAlgorithmIdentifierFinder; import org.bouncycastle.operator.OperatorCreationException; import org.bouncycastle.operator.OperatorStreamException; import org.bouncycastle.operator.RuntimeOperatorException; public class JcaContentSignerBuilder { private OperatorHelper helper = new OperatorHelper(new DefaultJcaJceHelper()); private SecureRandom random; private String signatureAlgorithm; private AlgorithmIdentifier sigAlgId; public JcaContentSignerBuilder(String signatureAlgorithm) { this.signatureAlgorithm = signatureAlgorithm; this.sigAlgId = new DefaultSignatureAlgorithmIdentifierFinder().find(signatureAlgorithm); } public JcaContentSignerBuilder setProvider(Provider provider) { this.helper = new OperatorHelper(new ProviderJcaJceHelper(provider)); return this; } public JcaContentSignerBuilder setProvider(String providerName) { this.helper = new OperatorHelper(new NamedJcaJceHelper(providerName)); return this; } public JcaContentSignerBuilder setSecureRandom(SecureRandom random) { this.random = random; return this; } public ContentSigner build(PrivateKey privateKey) throws OperatorCreationException { try { final Signature sig = helper.createSignature(sigAlgId); if (random != null) { sig.initSign(privateKey, random); } else { sig.initSign(privateKey); } return new ContentSigner() { private SignatureOutputStream stream = new SignatureOutputStream(sig); public AlgorithmIdentifier getAlgorithmIdentifier() { return sigAlgId; } public OutputStream getOutputStream() { return stream; } public byte[] getSignature() { try { return stream.getSignature(); } catch (SignatureException e) { throw new RuntimeOperatorException("exception obtaining signature: " + e.getMessage(), e); } } }; } catch (GeneralSecurityException e) { throw new OperatorCreationException("cannot create signer: " + e.getMessage(), e); } } private class SignatureOutputStream extends OutputStream { private Signature sig; SignatureOutputStream(Signature sig) { this.sig = sig; } public void write(byte[] bytes, int off, int len) throws IOException { try { sig.update(bytes, off, len); } catch (SignatureException e) { throw new OperatorStreamException("exception in content signer: " + e.getMessage(), e); } } public void write(byte[] bytes) throws IOException { try { sig.update(bytes); } catch (SignatureException e) { throw new OperatorStreamException("exception in content signer: " + e.getMessage(), e); } } public void write(int b) throws IOException { try { sig.update((byte)b); } catch (SignatureException e) { throw new OperatorStreamException("exception in content signer: " + e.getMessage(), e); } } byte[] getSignature() throws SignatureException { return sig.sign(); } } } bouncycastle-1.49.orig/src/org/bouncycastle/operator/KeyUnwrapper.java0000644000175000017500000000047011504011407025626 0ustar ebourgebourgpackage org.bouncycastle.operator; import org.bouncycastle.asn1.x509.AlgorithmIdentifier; public interface KeyUnwrapper { AlgorithmIdentifier getAlgorithmIdentifier(); GenericKey generateUnwrappedKey(AlgorithmIdentifier encryptionKeyAlgorithm, byte[] encryptedKey) throws OperatorException; } bouncycastle-1.49.orig/src/org/bouncycastle/operator/SymmetricKeyWrapper.java0000644000175000017500000000065211504000442027157 0ustar ebourgebourgpackage org.bouncycastle.operator; import org.bouncycastle.asn1.x509.AlgorithmIdentifier; public abstract class SymmetricKeyWrapper implements KeyWrapper { private AlgorithmIdentifier algorithmId; protected SymmetricKeyWrapper(AlgorithmIdentifier algorithmId) { this.algorithmId = algorithmId; } public AlgorithmIdentifier getAlgorithmIdentifier() { return algorithmId; } } bouncycastle-1.49.orig/src/org/bouncycastle/operator/DefaultSecretKeyProvider.java0000644000175000017500000000341012115100007030077 0ustar ebourgebourgpackage org.bouncycastle.operator; import java.util.Collections; import java.util.HashMap; import java.util.Map; import org.bouncycastle.asn1.ASN1ObjectIdentifier; import org.bouncycastle.asn1.nist.NISTObjectIdentifiers; import org.bouncycastle.asn1.ntt.NTTObjectIdentifiers; import org.bouncycastle.asn1.pkcs.PKCSObjectIdentifiers; import org.bouncycastle.asn1.x509.AlgorithmIdentifier; import org.bouncycastle.util.Integers; public class DefaultSecretKeyProvider implements SecretKeySizeProvider { public static final SecretKeySizeProvider INSTANCE = new DefaultSecretKeyProvider(); private static final Map KEY_SIZES; static { Map keySizes = new HashMap(); keySizes.put(new ASN1ObjectIdentifier("1.2.840.113533.7.66.10"), Integers.valueOf(128)); keySizes.put(PKCSObjectIdentifiers.des_EDE3_CBC.getId(), Integers.valueOf(192)); keySizes.put(NISTObjectIdentifiers.id_aes128_CBC, Integers.valueOf(128)); keySizes.put(NISTObjectIdentifiers.id_aes192_CBC, Integers.valueOf(192)); keySizes.put(NISTObjectIdentifiers.id_aes256_CBC, Integers.valueOf(256)); keySizes.put(NTTObjectIdentifiers.id_camellia128_cbc, Integers.valueOf(128)); keySizes.put(NTTObjectIdentifiers.id_camellia192_cbc, Integers.valueOf(192)); keySizes.put(NTTObjectIdentifiers.id_camellia256_cbc, Integers.valueOf(256)); KEY_SIZES = Collections.unmodifiableMap(keySizes); } public int getKeySize(AlgorithmIdentifier algorithmIdentifier) { // TODO: not all ciphers/oid relationships are this simple. Integer keySize = (Integer)KEY_SIZES.get(algorithmIdentifier.getAlgorithm()); if (keySize != null) { return keySize.intValue(); } return -1; } } bouncycastle-1.49.orig/src/org/bouncycastle/operator/package.html0000644000175000017500000000016611502012161024606 0ustar ebourgebourg Basic operators for doing encryption, signing, and digest operations. bouncycastle-1.49.orig/src/org/bouncycastle/operator/DefaultDigestAlgorithmIdentifierFinder.java0000644000175000017500000001174312103437526032737 0ustar ebourgebourgpackage org.bouncycastle.operator; import java.util.HashMap; import java.util.Map; import org.bouncycastle.asn1.ASN1ObjectIdentifier; import org.bouncycastle.asn1.DERNull; import org.bouncycastle.asn1.cryptopro.CryptoProObjectIdentifiers; import org.bouncycastle.asn1.nist.NISTObjectIdentifiers; import org.bouncycastle.asn1.oiw.OIWObjectIdentifiers; import org.bouncycastle.asn1.pkcs.PKCSObjectIdentifiers; import org.bouncycastle.asn1.pkcs.RSASSAPSSparams; import org.bouncycastle.asn1.teletrust.TeleTrusTObjectIdentifiers; import org.bouncycastle.asn1.x509.AlgorithmIdentifier; import org.bouncycastle.asn1.x9.X9ObjectIdentifiers; public class DefaultDigestAlgorithmIdentifierFinder implements DigestAlgorithmIdentifierFinder { private static Map digestOids = new HashMap(); private static Map digestNameToOids = new HashMap(); static { // // digests // digestOids.put(OIWObjectIdentifiers.md4WithRSAEncryption, PKCSObjectIdentifiers.md4); digestOids.put(OIWObjectIdentifiers.md4WithRSA, PKCSObjectIdentifiers.md4); digestOids.put(OIWObjectIdentifiers.sha1WithRSA, OIWObjectIdentifiers.idSHA1); digestOids.put(PKCSObjectIdentifiers.sha224WithRSAEncryption, NISTObjectIdentifiers.id_sha224); digestOids.put(PKCSObjectIdentifiers.sha256WithRSAEncryption, NISTObjectIdentifiers.id_sha256); digestOids.put(PKCSObjectIdentifiers.sha384WithRSAEncryption, NISTObjectIdentifiers.id_sha384); digestOids.put(PKCSObjectIdentifiers.sha512WithRSAEncryption, NISTObjectIdentifiers.id_sha512); digestOids.put(PKCSObjectIdentifiers.md2WithRSAEncryption, PKCSObjectIdentifiers.md2); digestOids.put(PKCSObjectIdentifiers.md4WithRSAEncryption, PKCSObjectIdentifiers.md4); digestOids.put(PKCSObjectIdentifiers.md5WithRSAEncryption, PKCSObjectIdentifiers.md5); digestOids.put(PKCSObjectIdentifiers.sha1WithRSAEncryption, OIWObjectIdentifiers.idSHA1); digestOids.put(X9ObjectIdentifiers.ecdsa_with_SHA1, OIWObjectIdentifiers.idSHA1); digestOids.put(X9ObjectIdentifiers.ecdsa_with_SHA224, NISTObjectIdentifiers.id_sha224); digestOids.put(X9ObjectIdentifiers.ecdsa_with_SHA256, NISTObjectIdentifiers.id_sha256); digestOids.put(X9ObjectIdentifiers.ecdsa_with_SHA384, NISTObjectIdentifiers.id_sha384); digestOids.put(X9ObjectIdentifiers.ecdsa_with_SHA512, NISTObjectIdentifiers.id_sha512); digestOids.put(X9ObjectIdentifiers.id_dsa_with_sha1, OIWObjectIdentifiers.idSHA1); digestOids.put(NISTObjectIdentifiers.dsa_with_sha224, NISTObjectIdentifiers.id_sha224); digestOids.put(NISTObjectIdentifiers.dsa_with_sha256, NISTObjectIdentifiers.id_sha256); digestOids.put(NISTObjectIdentifiers.dsa_with_sha384, NISTObjectIdentifiers.id_sha384); digestOids.put(NISTObjectIdentifiers.dsa_with_sha512, NISTObjectIdentifiers.id_sha512); digestOids.put(TeleTrusTObjectIdentifiers.rsaSignatureWithripemd128, TeleTrusTObjectIdentifiers.ripemd128); digestOids.put(TeleTrusTObjectIdentifiers.rsaSignatureWithripemd160, TeleTrusTObjectIdentifiers.ripemd160); digestOids.put(TeleTrusTObjectIdentifiers.rsaSignatureWithripemd256, TeleTrusTObjectIdentifiers.ripemd256); digestOids.put(CryptoProObjectIdentifiers.gostR3411_94_with_gostR3410_94, CryptoProObjectIdentifiers.gostR3411); digestOids.put(CryptoProObjectIdentifiers.gostR3411_94_with_gostR3410_2001, CryptoProObjectIdentifiers.gostR3411); digestNameToOids.put("SHA-1", OIWObjectIdentifiers.idSHA1); digestNameToOids.put("SHA-224", NISTObjectIdentifiers.id_sha224); digestNameToOids.put("SHA-256", NISTObjectIdentifiers.id_sha256); digestNameToOids.put("SHA-384", NISTObjectIdentifiers.id_sha384); digestNameToOids.put("SHA-512", NISTObjectIdentifiers.id_sha512); digestNameToOids.put("GOST3411", CryptoProObjectIdentifiers.gostR3411); digestNameToOids.put("MD2", PKCSObjectIdentifiers.md2); digestNameToOids.put("MD4", PKCSObjectIdentifiers.md4); digestNameToOids.put("MD5", PKCSObjectIdentifiers.md5); digestNameToOids.put("RIPEMD128", TeleTrusTObjectIdentifiers.ripemd128); digestNameToOids.put("RIPEMD160", TeleTrusTObjectIdentifiers.ripemd160); digestNameToOids.put("RIPEMD256", TeleTrusTObjectIdentifiers.ripemd256); } public AlgorithmIdentifier find(AlgorithmIdentifier sigAlgId) { AlgorithmIdentifier digAlgId; if (sigAlgId.getAlgorithm().equals(PKCSObjectIdentifiers.id_RSASSA_PSS)) { digAlgId = RSASSAPSSparams.getInstance(sigAlgId.getParameters()).getHashAlgorithm(); } else { digAlgId = new AlgorithmIdentifier((ASN1ObjectIdentifier)digestOids.get(sigAlgId.getAlgorithm()), DERNull.INSTANCE); } return digAlgId; } public AlgorithmIdentifier find(String digAlgName) { return new AlgorithmIdentifier((ASN1ObjectIdentifier)digestNameToOids.get(digAlgName), DERNull.INSTANCE); } }bouncycastle-1.49.orig/src/org/bouncycastle/operator/InputDecryptor.java0000644000175000017500000000152011502011336026161 0ustar ebourgebourgpackage org.bouncycastle.operator; import java.io.InputStream; import org.bouncycastle.asn1.x509.AlgorithmIdentifier; /** * General interface for an operator that is able to produce * an InputStream that will decrypt a stream of encrypted data. */ public interface InputDecryptor { /** * Return the algorithm identifier describing the encryption * algorithm and parameters this decryptor can process. * * @return algorithm oid and parameters. */ AlgorithmIdentifier getAlgorithmIdentifier(); /** * Wrap the passed in input stream encIn, returning an input stream * that decrypts what it reads from encIn before returning it. * * @param encIn InputStream containing encrypted input. * @return an decrypting InputStream */ InputStream getInputStream(InputStream encIn); } bouncycastle-1.49.orig/src/org/bouncycastle/jcajce/0000755000175000017500000000000012152033551021716 5ustar ebourgebourgbouncycastle-1.49.orig/src/org/bouncycastle/jcajce/provider/0000755000175000017500000000000012152033551023550 5ustar ebourgebourgbouncycastle-1.49.orig/src/org/bouncycastle/jcajce/provider/config/0000755000175000017500000000000012152033551025015 5ustar ebourgebourgbouncycastle-1.49.orig/src/org/bouncycastle/jcajce/provider/config/PKCS12StoreParameter.java0000644000175000017500000000255212107337610031450 0ustar ebourgebourgpackage org.bouncycastle.jcajce.provider.config; import java.io.OutputStream; import java.security.KeyStore; import java.security.KeyStore.LoadStoreParameter; import java.security.KeyStore.ProtectionParameter; public class PKCS12StoreParameter implements LoadStoreParameter { private final OutputStream out; private final ProtectionParameter protectionParameter; private final boolean forDEREncoding; public PKCS12StoreParameter(OutputStream out, char[] password) { this(out, password, false); } public PKCS12StoreParameter(OutputStream out, ProtectionParameter protectionParameter) { this(out, protectionParameter, false); } public PKCS12StoreParameter(OutputStream out, char[] password, boolean forDEREncoding) { this(out, new KeyStore.PasswordProtection(password), forDEREncoding); } public PKCS12StoreParameter(OutputStream out, ProtectionParameter protectionParameter, boolean forDEREncoding) { this.out = out; this.protectionParameter = protectionParameter; this.forDEREncoding = forDEREncoding; } public OutputStream getOutputStream() { return out; } public ProtectionParameter getProtectionParameter() { return protectionParameter; } public boolean isForDEREncoding() { return forDEREncoding; } } ././@LongLink0000000000000000000000000000015000000000000011561 Lustar rootrootbouncycastle-1.49.orig/src/org/bouncycastle/jcajce/provider/config/ProviderConfigurationPermission.javabouncycastle-1.49.orig/src/org/bouncycastle/jcajce/provider/config/ProviderConfigurationPermission.j0000644000175000017500000001061011701463555033573 0ustar ebourgebourgpackage org.bouncycastle.jcajce.provider.config; import java.security.BasicPermission; import java.security.Permission; import java.util.StringTokenizer; import org.bouncycastle.util.Strings; /** * A permission class to define what can be done with the ConfigurableProvider interface. *

    * Available permissions are "threadLocalEcImplicitlyCa" and "ecImplicitlyCa" which allow the setting * of the thread local and global ecImplicitlyCa parameters respectively. *

    *

    * Examples: *

      *
    • ProviderConfigurationPermission("BC"); // enable all permissions
    • *
    • ProviderConfigurationPermission("BC", "threadLocalEcImplicitlyCa"); // enable thread local only
    • *
    • ProviderConfigurationPermission("BC", "ecImplicitlyCa"); // enable global setting only
    • *
    • ProviderConfigurationPermission("BC", "threadLocalEcImplicitlyCa, ecImplicitlyCa"); // enable both explicitly
    • *
    *

    * Note: permission checks are only enforced if a security manager is present. *

    */ public class ProviderConfigurationPermission extends BasicPermission { private static final int THREAD_LOCAL_EC_IMPLICITLY_CA = 0x01; private static final int EC_IMPLICITLY_CA = 0x02; private static final int THREAD_LOCAL_DH_DEFAULT_PARAMS = 0x04; private static final int DH_DEFAULT_PARAMS = 0x08; private static final int ALL = THREAD_LOCAL_EC_IMPLICITLY_CA | EC_IMPLICITLY_CA | THREAD_LOCAL_DH_DEFAULT_PARAMS | DH_DEFAULT_PARAMS; private static final String THREAD_LOCAL_EC_IMPLICITLY_CA_STR = "threadlocalecimplicitlyca"; private static final String EC_IMPLICITLY_CA_STR = "ecimplicitlyca"; private static final String THREAD_LOCAL_DH_DEFAULT_PARAMS_STR = "threadlocaldhdefaultparams"; private static final String DH_DEFAULT_PARAMS_STR = "dhdefaultparams"; private static final String ALL_STR = "all"; private final String actions; private final int permissionMask; public ProviderConfigurationPermission(String name) { super(name); this.actions = "all"; this.permissionMask = ALL; } public ProviderConfigurationPermission(String name, String actions) { super(name, actions); this.actions = actions; this.permissionMask = calculateMask(actions); } private int calculateMask( String actions) { StringTokenizer tok = new StringTokenizer(Strings.toLowerCase(actions), " ,"); int mask = 0; while (tok.hasMoreTokens()) { String s = tok.nextToken(); if (s.equals(THREAD_LOCAL_EC_IMPLICITLY_CA_STR)) { mask |= THREAD_LOCAL_EC_IMPLICITLY_CA; } else if (s.equals(EC_IMPLICITLY_CA_STR)) { mask |= EC_IMPLICITLY_CA; } else if (s.equals(THREAD_LOCAL_DH_DEFAULT_PARAMS_STR)) { mask |= THREAD_LOCAL_DH_DEFAULT_PARAMS; } else if (s.equals(DH_DEFAULT_PARAMS_STR)) { mask |= DH_DEFAULT_PARAMS; } else if (s.equals(ALL_STR)) { mask |= ALL; } } if (mask == 0) { throw new IllegalArgumentException("unknown permissions passed to mask"); } return mask; } public String getActions() { return actions; } public boolean implies( Permission permission) { if (!(permission instanceof ProviderConfigurationPermission)) { return false; } if (!this.getName().equals(permission.getName())) { return false; } ProviderConfigurationPermission other = (ProviderConfigurationPermission)permission; return (this.permissionMask & other.permissionMask) == other.permissionMask; } public boolean equals( Object obj) { if (obj == this) { return true; } if (obj instanceof ProviderConfigurationPermission) { ProviderConfigurationPermission other = (ProviderConfigurationPermission)obj; return this.permissionMask == other.permissionMask && this.getName().equals(other.getName()); } return false; } public int hashCode() { return this.getName().hashCode() + this.permissionMask; } } bouncycastle-1.49.orig/src/org/bouncycastle/jcajce/provider/config/ProviderConfiguration.java0000644000175000017500000000043612063223102032177 0ustar ebourgebourgpackage org.bouncycastle.jcajce.provider.config; import javax.crypto.spec.DHParameterSpec; import org.bouncycastle.jce.spec.ECParameterSpec; public interface ProviderConfiguration { ECParameterSpec getEcImplicitlyCa(); DHParameterSpec getDHDefaultParameters(int keySize); } bouncycastle-1.49.orig/src/org/bouncycastle/jcajce/provider/config/ConfigurableProvider.java0000644000175000017500000000232112107067566032006 0ustar ebourgebourgpackage org.bouncycastle.jcajce.provider.config; import org.bouncycastle.asn1.ASN1ObjectIdentifier; import org.bouncycastle.jcajce.provider.util.AsymmetricKeyInfoConverter; /** * Implemented by the BC provider. This allows setting of hidden parameters, * such as the ImplicitCA parameters from X.962, if used. */ public interface ConfigurableProvider { /** * Elliptic Curve CA parameters - thread local version */ static final String THREAD_LOCAL_EC_IMPLICITLY_CA = "threadLocalEcImplicitlyCa"; /** * Elliptic Curve CA parameters - thread local version */ static final String EC_IMPLICITLY_CA = "ecImplicitlyCa"; /** * Diffie-Hellman Default Parameters - thread local version */ static final String THREAD_LOCAL_DH_DEFAULT_PARAMS = "threadLocalDhDefaultParams"; /** * Diffie-Hellman Default Parameters - VM wide version */ static final String DH_DEFAULT_PARAMS = "DhDefaultParams"; void setParameter(String parameterName, Object parameter); void addAlgorithm(String key, String value); boolean hasAlgorithm(String type, String name); void addKeyInfoConverter(ASN1ObjectIdentifier oid, AsymmetricKeyInfoConverter keyInfoConverter); } bouncycastle-1.49.orig/src/org/bouncycastle/jcajce/provider/util/0000755000175000017500000000000012152033551024525 5ustar ebourgebourgbouncycastle-1.49.orig/src/org/bouncycastle/jcajce/provider/util/SecretKeyUtil.java0000644000175000017500000000240212110310733030114 0ustar ebourgebourgpackage org.bouncycastle.jcajce.provider.util; import java.util.HashMap; import java.util.Map; import org.bouncycastle.asn1.ASN1ObjectIdentifier; import org.bouncycastle.asn1.nist.NISTObjectIdentifiers; import org.bouncycastle.asn1.ntt.NTTObjectIdentifiers; import org.bouncycastle.asn1.pkcs.PKCSObjectIdentifiers; import org.bouncycastle.util.Integers; public class SecretKeyUtil { private static Map keySizes = new HashMap(); static { keySizes.put(PKCSObjectIdentifiers.des_EDE3_CBC.getId(), Integers.valueOf(192)); keySizes.put(NISTObjectIdentifiers.id_aes128_CBC, Integers.valueOf(128)); keySizes.put(NISTObjectIdentifiers.id_aes192_CBC, Integers.valueOf(192)); keySizes.put(NISTObjectIdentifiers.id_aes256_CBC, Integers.valueOf(256)); keySizes.put(NTTObjectIdentifiers.id_camellia128_cbc, Integers.valueOf(128)); keySizes.put(NTTObjectIdentifiers.id_camellia192_cbc, Integers.valueOf(192)); keySizes.put(NTTObjectIdentifiers.id_camellia256_cbc, Integers.valueOf(256)); } public static int getKeySize(ASN1ObjectIdentifier oid) { Integer size = (Integer)keySizes.get(oid); if (size != null) { return size.intValue(); } return -1; } } bouncycastle-1.49.orig/src/org/bouncycastle/jcajce/provider/util/AsymmetricAlgorithmProvider.java0000644000175000017500000000337511701431716033103 0ustar ebourgebourgpackage org.bouncycastle.jcajce.provider.util; import org.bouncycastle.asn1.ASN1ObjectIdentifier; import org.bouncycastle.jcajce.provider.config.ConfigurableProvider; public abstract class AsymmetricAlgorithmProvider extends AlgorithmProvider { protected void addSignatureAlgorithm( ConfigurableProvider provider, String digest, String algorithm, String className, ASN1ObjectIdentifier oid) { String mainName = digest + "WITH" + algorithm; String jdk11Variation1 = digest + "with" + algorithm; String jdk11Variation2 = digest + "With" + algorithm; String alias = digest + "/" + algorithm; provider.addAlgorithm("Signature." + mainName, className); provider.addAlgorithm("Alg.Alias.Signature." + jdk11Variation1, mainName); provider.addAlgorithm("Alg.Alias.Signature." + jdk11Variation2, mainName); provider.addAlgorithm("Alg.Alias.Signature." + alias, mainName); provider.addAlgorithm("Alg.Alias.Signature." + oid, mainName); provider.addAlgorithm("Alg.Alias.Signature.OID." + oid, mainName); } protected void registerOid(ConfigurableProvider provider, ASN1ObjectIdentifier oid, String name, AsymmetricKeyInfoConverter keyFactory) { provider.addAlgorithm("Alg.Alias.KeyFactory." + oid, name); provider.addAlgorithm("Alg.Alias.KeyPairGenerator." + oid, name); provider.addKeyInfoConverter(oid, keyFactory); } protected void registerOidAlgorithmParameters(ConfigurableProvider provider, ASN1ObjectIdentifier oid, String name) { provider.addAlgorithm("Alg.Alias.AlgorithmParameterGenerator." + oid, name); provider.addAlgorithm("Alg.Alias.AlgorithmParameters." + oid, name); } } bouncycastle-1.49.orig/src/org/bouncycastle/jcajce/provider/util/AsymmetricKeyInfoConverter.java0000644000175000017500000000072411631303612032664 0ustar ebourgebourgpackage org.bouncycastle.jcajce.provider.util; import java.io.IOException; import java.security.PrivateKey; import java.security.PublicKey; import org.bouncycastle.asn1.pkcs.PrivateKeyInfo; import org.bouncycastle.asn1.x509.SubjectPublicKeyInfo; public interface AsymmetricKeyInfoConverter { PrivateKey generatePrivate(PrivateKeyInfo keyInfo) throws IOException; PublicKey generatePublic(SubjectPublicKeyInfo keyInfo) throws IOException; } bouncycastle-1.49.orig/src/org/bouncycastle/jcajce/provider/util/AlgorithmProvider.java0000644000175000017500000000034511701431716031037 0ustar ebourgebourgpackage org.bouncycastle.jcajce.provider.util; import org.bouncycastle.jcajce.provider.config.ConfigurableProvider; public abstract class AlgorithmProvider { public abstract void configure(ConfigurableProvider provider); } bouncycastle-1.49.orig/src/org/bouncycastle/jcajce/provider/util/DigestFactory.java0000644000175000017500000001065411625105230030143 0ustar ebourgebourgpackage org.bouncycastle.jcajce.provider.util; import java.util.HashMap; import java.util.HashSet; import java.util.Map; import java.util.Set; import org.bouncycastle.asn1.ASN1ObjectIdentifier; import org.bouncycastle.asn1.nist.NISTObjectIdentifiers; import org.bouncycastle.asn1.oiw.OIWObjectIdentifiers; import org.bouncycastle.asn1.pkcs.PKCSObjectIdentifiers; import org.bouncycastle.crypto.Digest; import org.bouncycastle.crypto.digests.MD5Digest; import org.bouncycastle.crypto.digests.SHA1Digest; import org.bouncycastle.crypto.digests.SHA224Digest; import org.bouncycastle.crypto.digests.SHA256Digest; import org.bouncycastle.crypto.digests.SHA384Digest; import org.bouncycastle.crypto.digests.SHA512Digest; import org.bouncycastle.util.Strings; public class DigestFactory { private static Set md5 = new HashSet(); private static Set sha1 = new HashSet(); private static Set sha224 = new HashSet(); private static Set sha256 = new HashSet(); private static Set sha384 = new HashSet(); private static Set sha512 = new HashSet(); private static Map oids = new HashMap(); static { md5.add("MD5"); md5.add(PKCSObjectIdentifiers.md5.getId()); sha1.add("SHA1"); sha1.add("SHA-1"); sha1.add(OIWObjectIdentifiers.idSHA1.getId()); sha224.add("SHA224"); sha224.add("SHA-224"); sha224.add(NISTObjectIdentifiers.id_sha224.getId()); sha256.add("SHA256"); sha256.add("SHA-256"); sha256.add(NISTObjectIdentifiers.id_sha256.getId()); sha384.add("SHA384"); sha384.add("SHA-384"); sha384.add(NISTObjectIdentifiers.id_sha384.getId()); sha512.add("SHA512"); sha512.add("SHA-512"); sha512.add(NISTObjectIdentifiers.id_sha512.getId()); oids.put("MD5", PKCSObjectIdentifiers.md5); oids.put(PKCSObjectIdentifiers.md5.getId(), PKCSObjectIdentifiers.md5); oids.put("SHA1", OIWObjectIdentifiers.idSHA1); oids.put("SHA-1", OIWObjectIdentifiers.idSHA1); oids.put(OIWObjectIdentifiers.idSHA1.getId(), OIWObjectIdentifiers.idSHA1); oids.put("SHA224", NISTObjectIdentifiers.id_sha224); oids.put("SHA-224", NISTObjectIdentifiers.id_sha224); oids.put(NISTObjectIdentifiers.id_sha224.getId(), NISTObjectIdentifiers.id_sha224); oids.put("SHA256", NISTObjectIdentifiers.id_sha256); oids.put("SHA-256", NISTObjectIdentifiers.id_sha256); oids.put(NISTObjectIdentifiers.id_sha256.getId(), NISTObjectIdentifiers.id_sha256); oids.put("SHA384", NISTObjectIdentifiers.id_sha384); oids.put("SHA-384", NISTObjectIdentifiers.id_sha384); oids.put(NISTObjectIdentifiers.id_sha384.getId(), NISTObjectIdentifiers.id_sha384); oids.put("SHA512", NISTObjectIdentifiers.id_sha512); oids.put("SHA-512", NISTObjectIdentifiers.id_sha512); oids.put(NISTObjectIdentifiers.id_sha512.getId(), NISTObjectIdentifiers.id_sha512); } public static Digest getDigest( String digestName) { digestName = Strings.toUpperCase(digestName); if (sha1.contains(digestName)) { return new SHA1Digest(); } if (md5.contains(digestName)) { return new MD5Digest(); } if (sha224.contains(digestName)) { return new SHA224Digest(); } if (sha256.contains(digestName)) { return new SHA256Digest(); } if (sha384.contains(digestName)) { return new SHA384Digest(); } if (sha512.contains(digestName)) { return new SHA512Digest(); } return null; } public static boolean isSameDigest( String digest1, String digest2) { return (sha1.contains(digest1) && sha1.contains(digest2)) || (sha224.contains(digest1) && sha224.contains(digest2)) || (sha256.contains(digest1) && sha256.contains(digest2)) || (sha384.contains(digest1) && sha384.contains(digest2)) || (sha512.contains(digest1) && sha512.contains(digest2)) || (md5.contains(digest1) && md5.contains(digest2)); } public static ASN1ObjectIdentifier getOID( String digestName) { return (ASN1ObjectIdentifier)oids.get(digestName); } } bouncycastle-1.49.orig/src/org/bouncycastle/jcajce/provider/asymmetric/0000755000175000017500000000000012152033551025725 5ustar ebourgebourgbouncycastle-1.49.orig/src/org/bouncycastle/jcajce/provider/asymmetric/ECGOST.java0000644000175000017500000000351711705435502027567 0ustar ebourgebourgpackage org.bouncycastle.jcajce.provider.asymmetric; import org.bouncycastle.asn1.cryptopro.CryptoProObjectIdentifiers; import org.bouncycastle.jcajce.provider.asymmetric.ecgost.KeyFactorySpi; import org.bouncycastle.jcajce.provider.config.ConfigurableProvider; import org.bouncycastle.jcajce.provider.util.AsymmetricAlgorithmProvider; public class ECGOST { private static final String PREFIX = "org.bouncycastle.jcajce.provider.asymmetric" + ".ecgost."; public static class Mappings extends AsymmetricAlgorithmProvider { public Mappings() { } public void configure(ConfigurableProvider provider) { provider.addAlgorithm("KeyFactory.ECGOST3410", PREFIX + "KeyFactorySpi"); provider.addAlgorithm("Alg.Alias.KeyFactory.GOST-3410-2001", "ECGOST3410"); provider.addAlgorithm("Alg.Alias.KeyFactory.ECGOST-3410", "ECGOST3410"); registerOid(provider, CryptoProObjectIdentifiers.gostR3410_2001, "ECGOST3410", new KeyFactorySpi()); registerOidAlgorithmParameters(provider, CryptoProObjectIdentifiers.gostR3410_2001, "ECGOST3410"); provider.addAlgorithm("KeyPairGenerator.ECGOST3410", PREFIX + "KeyPairGeneratorSpi"); provider.addAlgorithm("Alg.Alias.KeyPairGenerator.ECGOST-3410", "ECGOST3410"); provider.addAlgorithm("Alg.Alias.KeyPairGenerator.GOST-3410-2001", "ECGOST3410"); provider.addAlgorithm("Signature.ECGOST3410", PREFIX + "SignatureSpi"); provider.addAlgorithm("Alg.Alias.Signature.ECGOST-3410", "ECGOST3410"); provider.addAlgorithm("Alg.Alias.Signature.GOST-3410-2001", "ECGOST3410"); addSignatureAlgorithm(provider, "GOST3411", "ECGOST3410", PREFIX + "SignatureSpi", CryptoProObjectIdentifiers.gostR3411_94_with_gostR3410_2001); } } } bouncycastle-1.49.orig/src/org/bouncycastle/jcajce/provider/asymmetric/util/0000755000175000017500000000000012152033551026702 5ustar ebourgebourg././@LongLink0000000000000000000000000000015700000000000011570 Lustar rootrootbouncycastle-1.49.orig/src/org/bouncycastle/jcajce/provider/asymmetric/util/PKCS12BagAttributeCarrierImpl.javabouncycastle-1.49.orig/src/org/bouncycastle/jcajce/provider/asymmetric/util/PKCS12BagAttributeCarrie0000644000175000017500000000636611736773417033212 0ustar ebourgebourgpackage org.bouncycastle.jcajce.provider.asymmetric.util; import java.io.ByteArrayOutputStream; import java.io.IOException; import java.io.ObjectInputStream; import java.io.ObjectOutputStream; import java.util.Enumeration; import java.util.Hashtable; import java.util.Vector; import org.bouncycastle.asn1.ASN1Encodable; import org.bouncycastle.asn1.ASN1InputStream; import org.bouncycastle.asn1.ASN1ObjectIdentifier; import org.bouncycastle.asn1.ASN1OutputStream; import org.bouncycastle.asn1.DERObjectIdentifier; import org.bouncycastle.jce.interfaces.PKCS12BagAttributeCarrier; public class PKCS12BagAttributeCarrierImpl implements PKCS12BagAttributeCarrier { private Hashtable pkcs12Attributes; private Vector pkcs12Ordering; PKCS12BagAttributeCarrierImpl(Hashtable attributes, Vector ordering) { this.pkcs12Attributes = attributes; this.pkcs12Ordering = ordering; } public PKCS12BagAttributeCarrierImpl() { this(new Hashtable(), new Vector()); } public void setBagAttribute( ASN1ObjectIdentifier oid, ASN1Encodable attribute) { if (pkcs12Attributes.containsKey(oid)) { // preserve original ordering pkcs12Attributes.put(oid, attribute); } else { pkcs12Attributes.put(oid, attribute); pkcs12Ordering.addElement(oid); } } public ASN1Encodable getBagAttribute( ASN1ObjectIdentifier oid) { return (ASN1Encodable)pkcs12Attributes.get(oid); } public Enumeration getBagAttributeKeys() { return pkcs12Ordering.elements(); } int size() { return pkcs12Ordering.size(); } Hashtable getAttributes() { return pkcs12Attributes; } Vector getOrdering() { return pkcs12Ordering; } public void writeObject(ObjectOutputStream out) throws IOException { if (pkcs12Ordering.size() == 0) { out.writeObject(new Hashtable()); out.writeObject(new Vector()); } else { ByteArrayOutputStream bOut = new ByteArrayOutputStream(); ASN1OutputStream aOut = new ASN1OutputStream(bOut); Enumeration e = this.getBagAttributeKeys(); while (e.hasMoreElements()) { DERObjectIdentifier oid = (DERObjectIdentifier)e.nextElement(); aOut.writeObject(oid); aOut.writeObject((ASN1Encodable)pkcs12Attributes.get(oid)); } out.writeObject(bOut.toByteArray()); } } public void readObject(ObjectInputStream in) throws IOException, ClassNotFoundException { Object obj = in.readObject(); if (obj instanceof Hashtable) { this.pkcs12Attributes = (Hashtable)obj; this.pkcs12Ordering = (Vector)in.readObject(); } else { ASN1InputStream aIn = new ASN1InputStream((byte[])obj); ASN1ObjectIdentifier oid; while ((oid = (ASN1ObjectIdentifier)aIn.readObject()) != null) { this.setBagAttribute(oid, aIn.readObject()); } } } } bouncycastle-1.49.orig/src/org/bouncycastle/jcajce/provider/asymmetric/util/BaseCipherSpi.java0000644000175000017500000001424711634006570032243 0ustar ebourgebourgpackage org.bouncycastle.jcajce.provider.asymmetric.util; import java.security.AlgorithmParameters; import java.security.InvalidKeyException; import java.security.Key; import java.security.KeyFactory; import java.security.NoSuchAlgorithmException; import java.security.NoSuchProviderException; import java.security.PrivateKey; import java.security.spec.InvalidKeySpecException; import java.security.spec.PKCS8EncodedKeySpec; import java.security.spec.X509EncodedKeySpec; import javax.crypto.BadPaddingException; import javax.crypto.Cipher; import javax.crypto.CipherSpi; import javax.crypto.IllegalBlockSizeException; import javax.crypto.NoSuchPaddingException; import javax.crypto.spec.IvParameterSpec; import javax.crypto.spec.PBEParameterSpec; import javax.crypto.spec.RC2ParameterSpec; import javax.crypto.spec.RC5ParameterSpec; import javax.crypto.spec.SecretKeySpec; import org.bouncycastle.asn1.pkcs.PrivateKeyInfo; import org.bouncycastle.crypto.InvalidCipherTextException; import org.bouncycastle.crypto.Wrapper; import org.bouncycastle.jce.provider.BouncyCastleProvider; public abstract class BaseCipherSpi extends CipherSpi { // // specs we can handle. // private Class[] availableSpecs = { IvParameterSpec.class, PBEParameterSpec.class, RC2ParameterSpec.class, RC5ParameterSpec.class }; protected AlgorithmParameters engineParams = null; protected Wrapper wrapEngine = null; private int ivSize; private byte[] iv; protected BaseCipherSpi() { } protected int engineGetBlockSize() { return 0; } protected byte[] engineGetIV() { return null; } protected int engineGetKeySize( Key key) { return key.getEncoded().length; } protected int engineGetOutputSize( int inputLen) { return -1; } protected AlgorithmParameters engineGetParameters() { return null; } protected void engineSetMode( String mode) throws NoSuchAlgorithmException { throw new NoSuchAlgorithmException("can't support mode " + mode); } protected void engineSetPadding( String padding) throws NoSuchPaddingException { throw new NoSuchPaddingException("Padding " + padding + " unknown."); } protected byte[] engineWrap( Key key) throws IllegalBlockSizeException, InvalidKeyException { byte[] encoded = key.getEncoded(); if (encoded == null) { throw new InvalidKeyException("Cannot wrap key, null encoding."); } try { if (wrapEngine == null) { return engineDoFinal(encoded, 0, encoded.length); } else { return wrapEngine.wrap(encoded, 0, encoded.length); } } catch (BadPaddingException e) { throw new IllegalBlockSizeException(e.getMessage()); } } protected Key engineUnwrap( byte[] wrappedKey, String wrappedKeyAlgorithm, int wrappedKeyType) throws InvalidKeyException { byte[] encoded; try { if (wrapEngine == null) { encoded = engineDoFinal(wrappedKey, 0, wrappedKey.length); } else { encoded = wrapEngine.unwrap(wrappedKey, 0, wrappedKey.length); } } catch (InvalidCipherTextException e) { throw new InvalidKeyException(e.getMessage()); } catch (BadPaddingException e) { throw new InvalidKeyException(e.getMessage()); } catch (IllegalBlockSizeException e2) { throw new InvalidKeyException(e2.getMessage()); } if (wrappedKeyType == Cipher.SECRET_KEY) { return new SecretKeySpec(encoded, wrappedKeyAlgorithm); } else if (wrappedKeyAlgorithm.equals("") && wrappedKeyType == Cipher.PRIVATE_KEY) { /* * The caller doesn't know the algorithm as it is part of * the encrypted data. */ try { PrivateKeyInfo in = PrivateKeyInfo.getInstance(encoded); PrivateKey privKey = BouncyCastleProvider.getPrivateKey(in); if (privKey != null) { return privKey; } else { throw new InvalidKeyException("algorithm " + in.getPrivateKeyAlgorithm().getAlgorithm() + " not supported"); } } catch (Exception e) { throw new InvalidKeyException("Invalid key encoding."); } } else { try { KeyFactory kf = KeyFactory.getInstance(wrappedKeyAlgorithm, BouncyCastleProvider.PROVIDER_NAME); if (wrappedKeyType == Cipher.PUBLIC_KEY) { return kf.generatePublic(new X509EncodedKeySpec(encoded)); } else if (wrappedKeyType == Cipher.PRIVATE_KEY) { return kf.generatePrivate(new PKCS8EncodedKeySpec(encoded)); } } catch (NoSuchProviderException e) { throw new InvalidKeyException("Unknown key type " + e.getMessage()); } catch (NoSuchAlgorithmException e) { throw new InvalidKeyException("Unknown key type " + e.getMessage()); } catch (InvalidKeySpecException e2) { throw new InvalidKeyException("Unknown key type " + e2.getMessage()); } throw new InvalidKeyException("Unknown key type " + wrappedKeyType); } } } bouncycastle-1.49.orig/src/org/bouncycastle/jcajce/provider/asymmetric/util/IESUtil.java0000644000175000017500000000236112040117012031014 0ustar ebourgebourgpackage org.bouncycastle.jcajce.provider.asymmetric.util; import org.bouncycastle.crypto.engines.IESEngine; import org.bouncycastle.jce.spec.IESParameterSpec; public class IESUtil { public static IESParameterSpec guessParameterSpec(IESEngine engine) { if (engine.getCipher() == null) { return new IESParameterSpec(null, null, 128); } else if (engine.getCipher().getUnderlyingCipher().getAlgorithmName().equals("DES") || engine.getCipher().getUnderlyingCipher().getAlgorithmName().equals("RC2") || engine.getCipher().getUnderlyingCipher().getAlgorithmName().equals("RC5-32") || engine.getCipher().getUnderlyingCipher().getAlgorithmName().equals("RC5-64")) { return new IESParameterSpec(null, null, 64, 64); } else if (engine.getCipher().getUnderlyingCipher().getAlgorithmName().equals("SKIPJACK")) { return new IESParameterSpec(null, null, 80, 80); } else if (engine.getCipher().getUnderlyingCipher().getAlgorithmName().equals("GOST28147")) { return new IESParameterSpec(null, null, 256, 256); } return new IESParameterSpec(null, null, 128, 128); } } bouncycastle-1.49.orig/src/org/bouncycastle/jcajce/provider/asymmetric/util/DSAEncoder.java0000644000175000017500000000044011624652555031470 0ustar ebourgebourgpackage org.bouncycastle.jcajce.provider.asymmetric.util; import java.io.IOException; import java.math.BigInteger; public interface DSAEncoder { byte[] encode(BigInteger r, BigInteger s) throws IOException; BigInteger[] decode(byte[] sig) throws IOException; } bouncycastle-1.49.orig/src/org/bouncycastle/jcajce/provider/asymmetric/util/BaseKeyFactorySpi.java0000644000175000017500000000463012103432230033070 0ustar ebourgebourgpackage org.bouncycastle.jcajce.provider.asymmetric.util; import java.io.IOException; import java.security.Key; import java.security.PrivateKey; import java.security.PublicKey; import java.security.spec.InvalidKeySpecException; import java.security.spec.KeySpec; import java.security.spec.PKCS8EncodedKeySpec; import java.security.spec.X509EncodedKeySpec; import org.bouncycastle.asn1.pkcs.PrivateKeyInfo; import org.bouncycastle.asn1.x509.SubjectPublicKeyInfo; import org.bouncycastle.jcajce.provider.util.AsymmetricKeyInfoConverter; public abstract class BaseKeyFactorySpi extends java.security.KeyFactorySpi implements AsymmetricKeyInfoConverter { protected PrivateKey engineGeneratePrivate( KeySpec keySpec) throws InvalidKeySpecException { if (keySpec instanceof PKCS8EncodedKeySpec) { try { return generatePrivate(PrivateKeyInfo.getInstance(((PKCS8EncodedKeySpec)keySpec).getEncoded())); } catch (Exception e) { throw new InvalidKeySpecException("encoded key spec not recognised"); } } else { throw new InvalidKeySpecException("key spec not recognised"); } } protected PublicKey engineGeneratePublic( KeySpec keySpec) throws InvalidKeySpecException { if (keySpec instanceof X509EncodedKeySpec) { try { return generatePublic(SubjectPublicKeyInfo.getInstance(((X509EncodedKeySpec)keySpec).getEncoded())); } catch (Exception e) { throw new InvalidKeySpecException("encoded key spec not recognised"); } } else { throw new InvalidKeySpecException("key spec not recognised"); } } protected KeySpec engineGetKeySpec( Key key, Class spec) throws InvalidKeySpecException { if (spec.isAssignableFrom(PKCS8EncodedKeySpec.class) && key.getFormat().equals("PKCS#8")) { return new PKCS8EncodedKeySpec(key.getEncoded()); } else if (spec.isAssignableFrom(X509EncodedKeySpec.class) && key.getFormat().equals("X.509")) { return new X509EncodedKeySpec(key.getEncoded()); } throw new InvalidKeySpecException("not implemented yet " + key + " " + spec); } } bouncycastle-1.49.orig/src/org/bouncycastle/jcajce/provider/asymmetric/util/EC5Util.java0000644000175000017500000001006312110037231030750 0ustar ebourgebourgpackage org.bouncycastle.jcajce.provider.asymmetric.util; import java.math.BigInteger; import java.security.spec.ECField; import java.security.spec.ECFieldF2m; import java.security.spec.ECFieldFp; import java.security.spec.ECParameterSpec; import java.security.spec.ECPoint; import java.security.spec.EllipticCurve; import org.bouncycastle.jce.spec.ECNamedCurveParameterSpec; import org.bouncycastle.jce.spec.ECNamedCurveSpec; import org.bouncycastle.math.ec.ECCurve; public class EC5Util { public static EllipticCurve convertCurve( ECCurve curve, byte[] seed) { // TODO: the Sun EC implementation doesn't currently handle the seed properly // so at the moment it's set to null. Should probably look at making this configurable if (curve instanceof ECCurve.Fp) { return new EllipticCurve(new ECFieldFp(((ECCurve.Fp)curve).getQ()), curve.getA().toBigInteger(), curve.getB().toBigInteger(), null); } else { ECCurve.F2m curveF2m = (ECCurve.F2m)curve; int ks[]; if (curveF2m.isTrinomial()) { ks = new int[] { curveF2m.getK1() }; return new EllipticCurve(new ECFieldF2m(curveF2m.getM(), ks), curve.getA().toBigInteger(), curve.getB().toBigInteger(), null); } else { ks = new int[] { curveF2m.getK3(), curveF2m.getK2(), curveF2m.getK1() }; return new EllipticCurve(new ECFieldF2m(curveF2m.getM(), ks), curve.getA().toBigInteger(), curve.getB().toBigInteger(), null); } } } public static ECCurve convertCurve( EllipticCurve ec) { ECField field = ec.getField(); BigInteger a = ec.getA(); BigInteger b = ec.getB(); if (field instanceof ECFieldFp) { return new ECCurve.Fp(((ECFieldFp)field).getP(), a, b); } else { ECFieldF2m fieldF2m = (ECFieldF2m)field; int m = fieldF2m.getM(); int ks[] = ECUtil.convertMidTerms(fieldF2m.getMidTermsOfReductionPolynomial()); return new ECCurve.F2m(m, ks[0], ks[1], ks[2], a, b); } } public static ECParameterSpec convertSpec( EllipticCurve ellipticCurve, org.bouncycastle.jce.spec.ECParameterSpec spec) { if (spec instanceof ECNamedCurveParameterSpec) { return new ECNamedCurveSpec( ((ECNamedCurveParameterSpec)spec).getName(), ellipticCurve, new ECPoint( spec.getG().getX().toBigInteger(), spec.getG().getY().toBigInteger()), spec.getN(), spec.getH()); } else { return new ECParameterSpec( ellipticCurve, new ECPoint( spec.getG().getX().toBigInteger(), spec.getG().getY().toBigInteger()), spec.getN(), spec.getH().intValue()); } } public static org.bouncycastle.jce.spec.ECParameterSpec convertSpec( ECParameterSpec ecSpec, boolean withCompression) { ECCurve curve = convertCurve(ecSpec.getCurve()); return new org.bouncycastle.jce.spec.ECParameterSpec( curve, convertPoint(curve, ecSpec.getGenerator(), withCompression), ecSpec.getOrder(), BigInteger.valueOf(ecSpec.getCofactor()), ecSpec.getCurve().getSeed()); } public static org.bouncycastle.math.ec.ECPoint convertPoint( ECParameterSpec ecSpec, ECPoint point, boolean withCompression) { return convertPoint(convertCurve(ecSpec.getCurve()), point, withCompression); } public static org.bouncycastle.math.ec.ECPoint convertPoint( ECCurve curve, ECPoint point, boolean withCompression) { return curve.createPoint(point.getAffineX(), point.getAffineY(), withCompression); } } bouncycastle-1.49.orig/src/org/bouncycastle/jcajce/provider/asymmetric/util/DHUtil.java0000644000175000017500000000315412110037370030676 0ustar ebourgebourgpackage org.bouncycastle.jcajce.provider.asymmetric.util; import java.security.InvalidKeyException; import java.security.PrivateKey; import java.security.PublicKey; import javax.crypto.interfaces.DHPrivateKey; import javax.crypto.interfaces.DHPublicKey; import org.bouncycastle.crypto.params.AsymmetricKeyParameter; import org.bouncycastle.crypto.params.DHParameters; import org.bouncycastle.crypto.params.DHPrivateKeyParameters; import org.bouncycastle.crypto.params.DHPublicKeyParameters; /** * utility class for converting jce/jca DH objects * objects into their org.bouncycastle.crypto counterparts. */ public class DHUtil { static public AsymmetricKeyParameter generatePublicKeyParameter( PublicKey key) throws InvalidKeyException { if (key instanceof DHPublicKey) { DHPublicKey k = (DHPublicKey)key; return new DHPublicKeyParameters(k.getY(), new DHParameters(k.getParams().getP(), k.getParams().getG(), null, k.getParams().getL())); } throw new InvalidKeyException("can't identify DH public key."); } static public AsymmetricKeyParameter generatePrivateKeyParameter( PrivateKey key) throws InvalidKeyException { if (key instanceof DHPrivateKey) { DHPrivateKey k = (DHPrivateKey)key; return new DHPrivateKeyParameters(k.getX(), new DHParameters(k.getParams().getP(), k.getParams().getG(), null, k.getParams().getL())); } throw new InvalidKeyException("can't identify DH private key."); } } ././@LongLink0000000000000000000000000000016100000000000011563 Lustar rootrootbouncycastle-1.49.orig/src/org/bouncycastle/jcajce/provider/asymmetric/util/ExtendedInvalidKeySpecException.javabouncycastle-1.49.orig/src/org/bouncycastle/jcajce/provider/asymmetric/util/ExtendedInvalidKeySpecEx0000644000175000017500000000065211624570455033474 0ustar ebourgebourgpackage org.bouncycastle.jcajce.provider.asymmetric.util; import java.security.spec.InvalidKeySpecException; public class ExtendedInvalidKeySpecException extends InvalidKeySpecException { private Throwable cause; public ExtendedInvalidKeySpecException(String msg, Throwable cause) { super(msg); this.cause = cause; } public Throwable getCause() { return cause; } } bouncycastle-1.49.orig/src/org/bouncycastle/jcajce/provider/asymmetric/util/GOST3410Util.java0000644000175000017500000000370312110035175031470 0ustar ebourgebourgpackage org.bouncycastle.jcajce.provider.asymmetric.util; import java.security.InvalidKeyException; import java.security.PrivateKey; import java.security.PublicKey; import org.bouncycastle.crypto.params.AsymmetricKeyParameter; import org.bouncycastle.crypto.params.GOST3410Parameters; import org.bouncycastle.crypto.params.GOST3410PrivateKeyParameters; import org.bouncycastle.crypto.params.GOST3410PublicKeyParameters; import org.bouncycastle.jce.interfaces.GOST3410PrivateKey; import org.bouncycastle.jce.interfaces.GOST3410PublicKey; import org.bouncycastle.jce.spec.GOST3410PublicKeyParameterSetSpec; /** * utility class for converting jce/jca GOST3410-94 objects * objects into their org.bouncycastle.crypto counterparts. */ public class GOST3410Util { static public AsymmetricKeyParameter generatePublicKeyParameter( PublicKey key) throws InvalidKeyException { if (key instanceof GOST3410PublicKey) { GOST3410PublicKey k = (GOST3410PublicKey)key; GOST3410PublicKeyParameterSetSpec p = k.getParameters().getPublicKeyParameters(); return new GOST3410PublicKeyParameters(k.getY(), new GOST3410Parameters(p.getP(), p.getQ(), p.getA())); } throw new InvalidKeyException("can't identify GOST3410 public key: " + key.getClass().getName()); } static public AsymmetricKeyParameter generatePrivateKeyParameter( PrivateKey key) throws InvalidKeyException { if (key instanceof GOST3410PrivateKey) { GOST3410PrivateKey k = (GOST3410PrivateKey)key; GOST3410PublicKeyParameterSetSpec p = k.getParameters().getPublicKeyParameters(); return new GOST3410PrivateKeyParameters(k.getX(), new GOST3410Parameters(p.getP(), p.getQ(), p.getA())); } throw new InvalidKeyException("can't identify GOST3410 private key."); } } bouncycastle-1.49.orig/src/org/bouncycastle/jcajce/provider/asymmetric/util/ECUtil.java0000644000175000017500000002166112110037231030671 0ustar ebourgebourgpackage org.bouncycastle.jcajce.provider.asymmetric.util; import java.security.InvalidKeyException; import java.security.PrivateKey; import java.security.PublicKey; import org.bouncycastle.asn1.ASN1ObjectIdentifier; import org.bouncycastle.asn1.cryptopro.ECGOST3410NamedCurves; import org.bouncycastle.asn1.nist.NISTNamedCurves; import org.bouncycastle.asn1.pkcs.PrivateKeyInfo; import org.bouncycastle.asn1.sec.SECNamedCurves; import org.bouncycastle.asn1.teletrust.TeleTrusTNamedCurves; import org.bouncycastle.asn1.x509.SubjectPublicKeyInfo; import org.bouncycastle.asn1.x9.X962NamedCurves; import org.bouncycastle.asn1.x9.X9ECParameters; import org.bouncycastle.crypto.params.AsymmetricKeyParameter; import org.bouncycastle.crypto.params.ECDomainParameters; import org.bouncycastle.crypto.params.ECPrivateKeyParameters; import org.bouncycastle.crypto.params.ECPublicKeyParameters; import org.bouncycastle.jcajce.provider.asymmetric.ec.BCECPublicKey; import org.bouncycastle.jce.interfaces.ECPrivateKey; import org.bouncycastle.jce.interfaces.ECPublicKey; import org.bouncycastle.jce.provider.BouncyCastleProvider; import org.bouncycastle.jce.spec.ECParameterSpec; /** * utility class for converting jce/jca ECDSA, ECDH, and ECDHC * objects into their org.bouncycastle.crypto counterparts. */ public class ECUtil { /** * Returns a sorted array of middle terms of the reduction polynomial. * @param k The unsorted array of middle terms of the reduction polynomial * of length 1 or 3. * @return the sorted array of middle terms of the reduction polynomial. * This array always has length 3. */ static int[] convertMidTerms( int[] k) { int[] res = new int[3]; if (k.length == 1) { res[0] = k[0]; } else { if (k.length != 3) { throw new IllegalArgumentException("Only Trinomials and pentanomials supported"); } if (k[0] < k[1] && k[0] < k[2]) { res[0] = k[0]; if (k[1] < k[2]) { res[1] = k[1]; res[2] = k[2]; } else { res[1] = k[2]; res[2] = k[1]; } } else if (k[1] < k[2]) { res[0] = k[1]; if (k[0] < k[2]) { res[1] = k[0]; res[2] = k[2]; } else { res[1] = k[2]; res[2] = k[0]; } } else { res[0] = k[2]; if (k[0] < k[1]) { res[1] = k[0]; res[2] = k[1]; } else { res[1] = k[1]; res[2] = k[0]; } } } return res; } public static AsymmetricKeyParameter generatePublicKeyParameter( PublicKey key) throws InvalidKeyException { if (key instanceof ECPublicKey) { ECPublicKey k = (ECPublicKey)key; ECParameterSpec s = k.getParameters(); if (s == null) { s = BouncyCastleProvider.CONFIGURATION.getEcImplicitlyCa(); return new ECPublicKeyParameters( ((BCECPublicKey)k).engineGetQ(), new ECDomainParameters(s.getCurve(), s.getG(), s.getN(), s.getH(), s.getSeed())); } else { return new ECPublicKeyParameters( k.getQ(), new ECDomainParameters(s.getCurve(), s.getG(), s.getN(), s.getH(), s.getSeed())); } } else if (key instanceof java.security.interfaces.ECPublicKey) { java.security.interfaces.ECPublicKey pubKey = (java.security.interfaces.ECPublicKey)key; ECParameterSpec s = EC5Util.convertSpec(pubKey.getParams(), false); return new ECPublicKeyParameters( EC5Util.convertPoint(pubKey.getParams(), pubKey.getW(), false), new ECDomainParameters(s.getCurve(), s.getG(), s.getN(), s.getH(), s.getSeed())); } else { // see if we can build a key from key.getEncoded() try { byte[] bytes = key.getEncoded(); if (bytes == null) { throw new InvalidKeyException("no encoding for EC public key"); } PublicKey publicKey = BouncyCastleProvider.getPublicKey(SubjectPublicKeyInfo.getInstance(bytes)); if (publicKey instanceof java.security.interfaces.ECPublicKey) { return ECUtil.generatePublicKeyParameter(publicKey); } } catch (Exception e) { throw new InvalidKeyException("cannot identify EC public key: " + e.toString()); } } throw new InvalidKeyException("cannot identify EC public key."); } public static AsymmetricKeyParameter generatePrivateKeyParameter( PrivateKey key) throws InvalidKeyException { if (key instanceof ECPrivateKey) { ECPrivateKey k = (ECPrivateKey)key; ECParameterSpec s = k.getParameters(); if (s == null) { s = BouncyCastleProvider.CONFIGURATION.getEcImplicitlyCa(); } return new ECPrivateKeyParameters( k.getD(), new ECDomainParameters(s.getCurve(), s.getG(), s.getN(), s.getH(), s.getSeed())); } else if (key instanceof java.security.interfaces.ECPrivateKey) { java.security.interfaces.ECPrivateKey privKey = (java.security.interfaces.ECPrivateKey)key; ECParameterSpec s = EC5Util.convertSpec(privKey.getParams(), false); return new ECPrivateKeyParameters( privKey.getS(), new ECDomainParameters(s.getCurve(), s.getG(), s.getN(), s.getH(), s.getSeed())); } else { // see if we can build a key from key.getEncoded() try { byte[] bytes = key.getEncoded(); if (bytes == null) { throw new InvalidKeyException("no encoding for EC private key"); } PrivateKey privateKey = BouncyCastleProvider.getPrivateKey(PrivateKeyInfo.getInstance(bytes)); if (privateKey instanceof java.security.interfaces.ECPrivateKey) { return ECUtil.generatePrivateKeyParameter(privateKey); } } catch (Exception e) { throw new InvalidKeyException("cannot identify EC private key: " + e.toString()); } } throw new InvalidKeyException("can't identify EC private key."); } public static ASN1ObjectIdentifier getNamedCurveOid( String name) { ASN1ObjectIdentifier oid = X962NamedCurves.getOID(name); if (oid == null) { oid = SECNamedCurves.getOID(name); if (oid == null) { oid = NISTNamedCurves.getOID(name); } if (oid == null) { oid = TeleTrusTNamedCurves.getOID(name); } if (oid == null) { oid = ECGOST3410NamedCurves.getOID(name); } } return oid; } public static X9ECParameters getNamedCurveByOid( ASN1ObjectIdentifier oid) { X9ECParameters params = X962NamedCurves.getByOID(oid); if (params == null) { params = SECNamedCurves.getByOID(oid); if (params == null) { params = NISTNamedCurves.getByOID(oid); } if (params == null) { params = TeleTrusTNamedCurves.getByOID(oid); } } return params; } public static String getCurveName( ASN1ObjectIdentifier oid) { String name = X962NamedCurves.getName(oid); if (name == null) { name = SECNamedCurves.getName(oid); if (name == null) { name = NISTNamedCurves.getName(oid); } if (name == null) { name = TeleTrusTNamedCurves.getName(oid); } if (name == null) { name = ECGOST3410NamedCurves.getName(oid); } } return name; } } bouncycastle-1.49.orig/src/org/bouncycastle/jcajce/provider/asymmetric/util/DSABase.java0000644000175000017500000000535711703457346030776 0ustar ebourgebourgpackage org.bouncycastle.jcajce.provider.asymmetric.util; import java.math.BigInteger; import java.security.SignatureException; import java.security.SignatureSpi; import java.security.spec.AlgorithmParameterSpec; import org.bouncycastle.asn1.pkcs.PKCSObjectIdentifiers; import org.bouncycastle.asn1.x509.X509ObjectIdentifiers; import org.bouncycastle.crypto.DSA; import org.bouncycastle.crypto.Digest; public abstract class DSABase extends SignatureSpi implements PKCSObjectIdentifiers, X509ObjectIdentifiers { protected Digest digest; protected DSA signer; protected DSAEncoder encoder; protected DSABase( Digest digest, DSA signer, DSAEncoder encoder) { this.digest = digest; this.signer = signer; this.encoder = encoder; } protected void engineUpdate( byte b) throws SignatureException { digest.update(b); } protected void engineUpdate( byte[] b, int off, int len) throws SignatureException { digest.update(b, off, len); } protected byte[] engineSign() throws SignatureException { byte[] hash = new byte[digest.getDigestSize()]; digest.doFinal(hash, 0); try { BigInteger[] sig = signer.generateSignature(hash); return encoder.encode(sig[0], sig[1]); } catch (Exception e) { throw new SignatureException(e.toString()); } } protected boolean engineVerify( byte[] sigBytes) throws SignatureException { byte[] hash = new byte[digest.getDigestSize()]; digest.doFinal(hash, 0); BigInteger[] sig; try { sig = encoder.decode(sigBytes); } catch (Exception e) { throw new SignatureException("error decoding signature bytes."); } return signer.verifySignature(hash, sig[0], sig[1]); } protected void engineSetParameter( AlgorithmParameterSpec params) { throw new UnsupportedOperationException("engineSetParameter unsupported"); } /** * @deprecated replaced with */ protected void engineSetParameter( String param, Object value) { throw new UnsupportedOperationException("engineSetParameter unsupported"); } /** * @deprecated */ protected Object engineGetParameter( String param) { throw new UnsupportedOperationException("engineSetParameter unsupported"); } } bouncycastle-1.49.orig/src/org/bouncycastle/jcajce/provider/asymmetric/util/KeyUtil.java0000644000175000017500000000346011624702635031147 0ustar ebourgebourgpackage org.bouncycastle.jcajce.provider.asymmetric.util; import org.bouncycastle.asn1.ASN1Encodable; import org.bouncycastle.asn1.ASN1Encoding; import org.bouncycastle.asn1.pkcs.PrivateKeyInfo; import org.bouncycastle.asn1.x509.AlgorithmIdentifier; import org.bouncycastle.asn1.x509.SubjectPublicKeyInfo; public class KeyUtil { public static byte[] getEncodedSubjectPublicKeyInfo(AlgorithmIdentifier algId, ASN1Encodable keyData) { try { return getEncodedSubjectPublicKeyInfo(new SubjectPublicKeyInfo(algId, keyData)); } catch (Exception e) { return null; } } public static byte[] getEncodedSubjectPublicKeyInfo(AlgorithmIdentifier algId, byte[] keyData) { try { return getEncodedSubjectPublicKeyInfo(new SubjectPublicKeyInfo(algId, keyData)); } catch (Exception e) { return null; } } public static byte[] getEncodedSubjectPublicKeyInfo(SubjectPublicKeyInfo info) { try { return info.getEncoded(ASN1Encoding.DER); } catch (Exception e) { return null; } } public static byte[] getEncodedPrivateKeyInfo(AlgorithmIdentifier algId, ASN1Encodable privKey) { try { PrivateKeyInfo info = new PrivateKeyInfo(algId, privKey.toASN1Primitive()); return getEncodedPrivateKeyInfo(info); } catch (Exception e) { return null; } } public static byte[] getEncodedPrivateKeyInfo(PrivateKeyInfo info) { try { return info.getEncoded(ASN1Encoding.DER); } catch (Exception e) { return null; } } } bouncycastle-1.49.orig/src/org/bouncycastle/jcajce/provider/asymmetric/IES.java0000644000175000017500000000130312110034463027202 0ustar ebourgebourgpackage org.bouncycastle.jcajce.provider.asymmetric; import org.bouncycastle.jcajce.provider.config.ConfigurableProvider; import org.bouncycastle.jcajce.provider.util.AsymmetricAlgorithmProvider; public class IES { private static final String PREFIX = "org.bouncycastle.jcajce.provider.asymmetric" + ".ies."; public static class Mappings extends AsymmetricAlgorithmProvider { public Mappings() { } public void configure(ConfigurableProvider provider) { provider.addAlgorithm("AlgorithmParameters.IES", PREFIX + "AlgorithmParametersSpi"); provider.addAlgorithm("Cipher.IES", PREFIX + "CipherSpi$IES"); } } } bouncycastle-1.49.orig/src/org/bouncycastle/jcajce/provider/asymmetric/ecgost/0000755000175000017500000000000012152033551027211 5ustar ebourgebourg././@LongLink0000000000000000000000000000015100000000000011562 Lustar rootrootbouncycastle-1.49.orig/src/org/bouncycastle/jcajce/provider/asymmetric/ecgost/BCECGOST3410PublicKey.javabouncycastle-1.49.orig/src/org/bouncycastle/jcajce/provider/asymmetric/ecgost/BCECGOST3410PublicKey.0000644000175000017500000004140512110037231032520 0ustar ebourgebourgpackage org.bouncycastle.jcajce.provider.asymmetric.ecgost; import java.io.IOException; import java.io.ObjectInputStream; import java.io.ObjectOutputStream; import java.math.BigInteger; import java.security.interfaces.ECPublicKey; import java.security.spec.ECParameterSpec; import java.security.spec.ECPoint; import java.security.spec.ECPublicKeySpec; import java.security.spec.EllipticCurve; import org.bouncycastle.asn1.ASN1Encodable; import org.bouncycastle.asn1.ASN1ObjectIdentifier; import org.bouncycastle.asn1.ASN1OctetString; import org.bouncycastle.asn1.ASN1Primitive; import org.bouncycastle.asn1.ASN1Sequence; import org.bouncycastle.asn1.DERBitString; import org.bouncycastle.asn1.DERNull; import org.bouncycastle.asn1.DEROctetString; import org.bouncycastle.asn1.cryptopro.CryptoProObjectIdentifiers; import org.bouncycastle.asn1.cryptopro.ECGOST3410NamedCurves; import org.bouncycastle.asn1.cryptopro.GOST3410PublicKeyAlgParameters; import org.bouncycastle.asn1.x509.AlgorithmIdentifier; import org.bouncycastle.asn1.x509.SubjectPublicKeyInfo; import org.bouncycastle.asn1.x9.X962Parameters; import org.bouncycastle.asn1.x9.X9ECParameters; import org.bouncycastle.asn1.x9.X9ECPoint; import org.bouncycastle.asn1.x9.X9IntegerConverter; import org.bouncycastle.asn1.x9.X9ObjectIdentifiers; import org.bouncycastle.crypto.params.ECDomainParameters; import org.bouncycastle.crypto.params.ECPublicKeyParameters; import org.bouncycastle.jcajce.provider.asymmetric.util.EC5Util; import org.bouncycastle.jcajce.provider.asymmetric.util.ECUtil; import org.bouncycastle.jcajce.provider.asymmetric.util.KeyUtil; import org.bouncycastle.jce.ECGOST3410NamedCurveTable; import org.bouncycastle.jce.interfaces.ECPointEncoder; import org.bouncycastle.jce.provider.BouncyCastleProvider; import org.bouncycastle.jce.spec.ECNamedCurveParameterSpec; import org.bouncycastle.jce.spec.ECNamedCurveSpec; import org.bouncycastle.math.ec.ECCurve; public class BCECGOST3410PublicKey implements ECPublicKey, org.bouncycastle.jce.interfaces.ECPublicKey, ECPointEncoder { static final long serialVersionUID = 7026240464295649314L; private String algorithm = "ECGOST3410"; private boolean withCompression; private transient org.bouncycastle.math.ec.ECPoint q; private transient ECParameterSpec ecSpec; private transient GOST3410PublicKeyAlgParameters gostParams; public BCECGOST3410PublicKey( BCECGOST3410PublicKey key) { this.q = key.q; this.ecSpec = key.ecSpec; this.withCompression = key.withCompression; this.gostParams = key.gostParams; } public BCECGOST3410PublicKey( ECPublicKeySpec spec) { this.ecSpec = spec.getParams(); this.q = EC5Util.convertPoint(ecSpec, spec.getW(), false); } public BCECGOST3410PublicKey( org.bouncycastle.jce.spec.ECPublicKeySpec spec) { this.q = spec.getQ(); if (spec.getParams() != null) // can be null if implictlyCa { ECCurve curve = spec.getParams().getCurve(); EllipticCurve ellipticCurve = EC5Util.convertCurve(curve, spec.getParams().getSeed()); this.ecSpec = EC5Util.convertSpec(ellipticCurve, spec.getParams()); } else { if (q.getCurve() == null) { org.bouncycastle.jce.spec.ECParameterSpec s = BouncyCastleProvider.CONFIGURATION.getEcImplicitlyCa(); q = s.getCurve().createPoint(q.getX().toBigInteger(), q.getY().toBigInteger(), false); } this.ecSpec = null; } } public BCECGOST3410PublicKey( String algorithm, ECPublicKeyParameters params, ECParameterSpec spec) { ECDomainParameters dp = params.getParameters(); this.algorithm = algorithm; this.q = params.getQ(); if (spec == null) { EllipticCurve ellipticCurve = EC5Util.convertCurve(dp.getCurve(), dp.getSeed()); this.ecSpec = createSpec(ellipticCurve, dp); } else { this.ecSpec = spec; } } public BCECGOST3410PublicKey( String algorithm, ECPublicKeyParameters params, org.bouncycastle.jce.spec.ECParameterSpec spec) { ECDomainParameters dp = params.getParameters(); this.algorithm = algorithm; this.q = params.getQ(); if (spec == null) { EllipticCurve ellipticCurve = EC5Util.convertCurve(dp.getCurve(), dp.getSeed()); this.ecSpec = createSpec(ellipticCurve, dp); } else { EllipticCurve ellipticCurve = EC5Util.convertCurve(spec.getCurve(), spec.getSeed()); this.ecSpec = EC5Util.convertSpec(ellipticCurve, spec); } } /* * called for implicitCA */ public BCECGOST3410PublicKey( String algorithm, ECPublicKeyParameters params) { this.algorithm = algorithm; this.q = params.getQ(); this.ecSpec = null; } private ECParameterSpec createSpec(EllipticCurve ellipticCurve, ECDomainParameters dp) { return new ECParameterSpec( ellipticCurve, new ECPoint( dp.getG().getX().toBigInteger(), dp.getG().getY().toBigInteger()), dp.getN(), dp.getH().intValue()); } public BCECGOST3410PublicKey( ECPublicKey key) { this.algorithm = key.getAlgorithm(); this.ecSpec = key.getParams(); this.q = EC5Util.convertPoint(this.ecSpec, key.getW(), false); } BCECGOST3410PublicKey( SubjectPublicKeyInfo info) { populateFromPubKeyInfo(info); } private void populateFromPubKeyInfo(SubjectPublicKeyInfo info) { if (info.getAlgorithm().getAlgorithm().equals(CryptoProObjectIdentifiers.gostR3410_2001)) { DERBitString bits = info.getPublicKeyData(); ASN1OctetString key; this.algorithm = "ECGOST3410"; try { key = (ASN1OctetString) ASN1Primitive.fromByteArray(bits.getBytes()); } catch (IOException ex) { throw new IllegalArgumentException("error recovering public key"); } byte[] keyEnc = key.getOctets(); byte[] x = new byte[32]; byte[] y = new byte[32]; for (int i = 0; i != x.length; i++) { x[i] = keyEnc[32 - 1 - i]; } for (int i = 0; i != y.length; i++) { y[i] = keyEnc[64 - 1 - i]; } gostParams = new GOST3410PublicKeyAlgParameters((ASN1Sequence)info.getAlgorithm().getParameters()); ECNamedCurveParameterSpec spec = ECGOST3410NamedCurveTable.getParameterSpec(ECGOST3410NamedCurves.getName(gostParams.getPublicKeyParamSet())); ECCurve curve = spec.getCurve(); EllipticCurve ellipticCurve = EC5Util.convertCurve(curve, spec.getSeed()); this.q = curve.createPoint(new BigInteger(1, x), new BigInteger(1, y), false); ecSpec = new ECNamedCurveSpec( ECGOST3410NamedCurves.getName(gostParams.getPublicKeyParamSet()), ellipticCurve, new ECPoint( spec.getG().getX().toBigInteger(), spec.getG().getY().toBigInteger()), spec.getN(), spec.getH()); } else { X962Parameters params = new X962Parameters((ASN1Primitive)info.getAlgorithm().getParameters()); ECCurve curve; EllipticCurve ellipticCurve; if (params.isNamedCurve()) { ASN1ObjectIdentifier oid = (ASN1ObjectIdentifier)params.getParameters(); X9ECParameters ecP = ECUtil.getNamedCurveByOid(oid); curve = ecP.getCurve(); ellipticCurve = EC5Util.convertCurve(curve, ecP.getSeed()); ecSpec = new ECNamedCurveSpec( ECUtil.getCurveName(oid), ellipticCurve, new ECPoint( ecP.getG().getX().toBigInteger(), ecP.getG().getY().toBigInteger()), ecP.getN(), ecP.getH()); } else if (params.isImplicitlyCA()) { ecSpec = null; curve = BouncyCastleProvider.CONFIGURATION.getEcImplicitlyCa().getCurve(); } else { X9ECParameters ecP = X9ECParameters.getInstance(params.getParameters()); curve = ecP.getCurve(); ellipticCurve = EC5Util.convertCurve(curve, ecP.getSeed()); this.ecSpec = new ECParameterSpec( ellipticCurve, new ECPoint( ecP.getG().getX().toBigInteger(), ecP.getG().getY().toBigInteger()), ecP.getN(), ecP.getH().intValue()); } DERBitString bits = info.getPublicKeyData(); byte[] data = bits.getBytes(); ASN1OctetString key = new DEROctetString(data); // // extra octet string - one of our old certs... // if (data[0] == 0x04 && data[1] == data.length - 2 && (data[2] == 0x02 || data[2] == 0x03)) { int qLength = new X9IntegerConverter().getByteLength(curve); if (qLength >= data.length - 3) { try { key = (ASN1OctetString) ASN1Primitive.fromByteArray(data); } catch (IOException ex) { throw new IllegalArgumentException("error recovering public key"); } } } X9ECPoint derQ = new X9ECPoint(curve, key); this.q = derQ.getPoint(); } } public String getAlgorithm() { return algorithm; } public String getFormat() { return "X.509"; } public byte[] getEncoded() { ASN1Encodable params; SubjectPublicKeyInfo info; if (algorithm.equals("ECGOST3410")) { if (gostParams != null) { params = gostParams; } else { if (ecSpec instanceof ECNamedCurveSpec) { params = new GOST3410PublicKeyAlgParameters( ECGOST3410NamedCurves.getOID(((ECNamedCurveSpec)ecSpec).getName()), CryptoProObjectIdentifiers.gostR3411_94_CryptoProParamSet); } else { // strictly speaking this may not be applicable... ECCurve curve = EC5Util.convertCurve(ecSpec.getCurve()); X9ECParameters ecP = new X9ECParameters( curve, EC5Util.convertPoint(curve, ecSpec.getGenerator(), withCompression), ecSpec.getOrder(), BigInteger.valueOf(ecSpec.getCofactor()), ecSpec.getCurve().getSeed()); params = new X962Parameters(ecP); } } BigInteger bX = this.q.getX().toBigInteger(); BigInteger bY = this.q.getY().toBigInteger(); byte[] encKey = new byte[64]; extractBytes(encKey, 0, bX); extractBytes(encKey, 32, bY); try { info = new SubjectPublicKeyInfo(new AlgorithmIdentifier(CryptoProObjectIdentifiers.gostR3410_2001, params), new DEROctetString(encKey)); } catch (IOException e) { return null; } } else { if (ecSpec instanceof ECNamedCurveSpec) { ASN1ObjectIdentifier curveOid = ECUtil.getNamedCurveOid(((ECNamedCurveSpec)ecSpec).getName()); if (curveOid == null) { curveOid = new ASN1ObjectIdentifier(((ECNamedCurveSpec)ecSpec).getName()); } params = new X962Parameters(curveOid); } else if (ecSpec == null) { params = new X962Parameters(DERNull.INSTANCE); } else { ECCurve curve = EC5Util.convertCurve(ecSpec.getCurve()); X9ECParameters ecP = new X9ECParameters( curve, EC5Util.convertPoint(curve, ecSpec.getGenerator(), withCompression), ecSpec.getOrder(), BigInteger.valueOf(ecSpec.getCofactor()), ecSpec.getCurve().getSeed()); params = new X962Parameters(ecP); } ECCurve curve = this.engineGetQ().getCurve(); ASN1OctetString p = (ASN1OctetString) new X9ECPoint(curve.createPoint(this.getQ().getX().toBigInteger(), this.getQ().getY().toBigInteger(), withCompression)).toASN1Primitive(); info = new SubjectPublicKeyInfo(new AlgorithmIdentifier(X9ObjectIdentifiers.id_ecPublicKey, params), p.getOctets()); } return KeyUtil.getEncodedSubjectPublicKeyInfo(info); } private void extractBytes(byte[] encKey, int offSet, BigInteger bI) { byte[] val = bI.toByteArray(); if (val.length < 32) { byte[] tmp = new byte[32]; System.arraycopy(val, 0, tmp, tmp.length - val.length, val.length); val = tmp; } for (int i = 0; i != 32; i++) { encKey[offSet + i] = val[val.length - 1 - i]; } } public ECParameterSpec getParams() { return ecSpec; } public org.bouncycastle.jce.spec.ECParameterSpec getParameters() { if (ecSpec == null) // implictlyCA { return null; } return EC5Util.convertSpec(ecSpec, withCompression); } public ECPoint getW() { return new ECPoint(q.getX().toBigInteger(), q.getY().toBigInteger()); } public org.bouncycastle.math.ec.ECPoint getQ() { if (ecSpec == null) { if (q instanceof org.bouncycastle.math.ec.ECPoint.Fp) { return new org.bouncycastle.math.ec.ECPoint.Fp(null, q.getX(), q.getY()); } else { return new org.bouncycastle.math.ec.ECPoint.F2m(null, q.getX(), q.getY()); } } return q; } public org.bouncycastle.math.ec.ECPoint engineGetQ() { return q; } org.bouncycastle.jce.spec.ECParameterSpec engineGetSpec() { if (ecSpec != null) { return EC5Util.convertSpec(ecSpec, withCompression); } return BouncyCastleProvider.CONFIGURATION.getEcImplicitlyCa(); } public String toString() { StringBuffer buf = new StringBuffer(); String nl = System.getProperty("line.separator"); buf.append("EC Public Key").append(nl); buf.append(" X: ").append(this.q.getX().toBigInteger().toString(16)).append(nl); buf.append(" Y: ").append(this.q.getY().toBigInteger().toString(16)).append(nl); return buf.toString(); } public void setPointFormat(String style) { withCompression = !("UNCOMPRESSED".equalsIgnoreCase(style)); } public boolean equals(Object o) { if (!(o instanceof BCECGOST3410PublicKey)) { return false; } BCECGOST3410PublicKey other = (BCECGOST3410PublicKey)o; return engineGetQ().equals(other.engineGetQ()) && (engineGetSpec().equals(other.engineGetSpec())); } public int hashCode() { return engineGetQ().hashCode() ^ engineGetSpec().hashCode(); } private void readObject( ObjectInputStream in) throws IOException, ClassNotFoundException { in.defaultReadObject(); byte[] enc = (byte[])in.readObject(); populateFromPubKeyInfo(SubjectPublicKeyInfo.getInstance(ASN1Primitive.fromByteArray(enc))); } private void writeObject( ObjectOutputStream out) throws IOException { out.defaultWriteObject(); out.writeObject(this.getEncoded()); } } bouncycastle-1.49.orig/src/org/bouncycastle/jcajce/provider/asymmetric/ecgost/SignatureSpi.java0000644000175000017500000001374112110037231032470 0ustar ebourgebourgpackage org.bouncycastle.jcajce.provider.asymmetric.ecgost; import java.math.BigInteger; import java.security.InvalidKeyException; import java.security.PrivateKey; import java.security.PublicKey; import java.security.SignatureException; import java.security.spec.AlgorithmParameterSpec; import org.bouncycastle.asn1.pkcs.PKCSObjectIdentifiers; import org.bouncycastle.asn1.x509.SubjectPublicKeyInfo; import org.bouncycastle.asn1.x509.X509ObjectIdentifiers; import org.bouncycastle.crypto.CipherParameters; import org.bouncycastle.crypto.DSA; import org.bouncycastle.crypto.Digest; import org.bouncycastle.crypto.digests.GOST3411Digest; import org.bouncycastle.crypto.params.ParametersWithRandom; import org.bouncycastle.crypto.signers.ECGOST3410Signer; import org.bouncycastle.jcajce.provider.asymmetric.util.ECUtil; import org.bouncycastle.jce.interfaces.ECKey; import org.bouncycastle.jce.interfaces.ECPublicKey; import org.bouncycastle.jce.interfaces.GOST3410Key; import org.bouncycastle.jce.provider.BouncyCastleProvider; import org.bouncycastle.jcajce.provider.asymmetric.util.GOST3410Util; public class SignatureSpi extends java.security.SignatureSpi implements PKCSObjectIdentifiers, X509ObjectIdentifiers { private Digest digest; private DSA signer; public SignatureSpi() { this.digest = new GOST3411Digest(); this.signer = new ECGOST3410Signer(); } protected void engineInitVerify( PublicKey publicKey) throws InvalidKeyException { CipherParameters param; if (publicKey instanceof ECPublicKey) { param = ECUtil.generatePublicKeyParameter(publicKey); } else if (publicKey instanceof GOST3410Key) { param = GOST3410Util.generatePublicKeyParameter(publicKey); } else { try { byte[] bytes = publicKey.getEncoded(); publicKey = BouncyCastleProvider.getPublicKey(SubjectPublicKeyInfo.getInstance(bytes)); if (publicKey instanceof ECPublicKey) { param = ECUtil.generatePublicKeyParameter(publicKey); } else { throw new InvalidKeyException("can't recognise key type in DSA based signer"); } } catch (Exception e) { throw new InvalidKeyException("can't recognise key type in DSA based signer"); } } digest.reset(); signer.init(false, param); } protected void engineInitSign( PrivateKey privateKey) throws InvalidKeyException { CipherParameters param; if (privateKey instanceof ECKey) { param = ECUtil.generatePrivateKeyParameter(privateKey); } else { param = GOST3410Util.generatePrivateKeyParameter(privateKey); } digest.reset(); if (appRandom != null) { signer.init(true, new ParametersWithRandom(param, appRandom)); } else { signer.init(true, param); } } protected void engineUpdate( byte b) throws SignatureException { digest.update(b); } protected void engineUpdate( byte[] b, int off, int len) throws SignatureException { digest.update(b, off, len); } protected byte[] engineSign() throws SignatureException { byte[] hash = new byte[digest.getDigestSize()]; digest.doFinal(hash, 0); try { byte[] sigBytes = new byte[64]; BigInteger[] sig = signer.generateSignature(hash); byte[] r = sig[0].toByteArray(); byte[] s = sig[1].toByteArray(); if (s[0] != 0) { System.arraycopy(s, 0, sigBytes, 32 - s.length, s.length); } else { System.arraycopy(s, 1, sigBytes, 32 - (s.length - 1), s.length - 1); } if (r[0] != 0) { System.arraycopy(r, 0, sigBytes, 64 - r.length, r.length); } else { System.arraycopy(r, 1, sigBytes, 64 - (r.length - 1), r.length - 1); } return sigBytes; } catch (Exception e) { throw new SignatureException(e.toString()); } } protected boolean engineVerify( byte[] sigBytes) throws SignatureException { byte[] hash = new byte[digest.getDigestSize()]; digest.doFinal(hash, 0); BigInteger[] sig; try { byte[] r = new byte[32]; byte[] s = new byte[32]; System.arraycopy(sigBytes, 0, s, 0, 32); System.arraycopy(sigBytes, 32, r, 0, 32); sig = new BigInteger[2]; sig[0] = new BigInteger(1, r); sig[1] = new BigInteger(1, s); } catch (Exception e) { throw new SignatureException("error decoding signature bytes."); } return signer.verifySignature(hash, sig[0], sig[1]); } protected void engineSetParameter( AlgorithmParameterSpec params) { throw new UnsupportedOperationException("engineSetParameter unsupported"); } /** * @deprecated replaced with */ protected void engineSetParameter( String param, Object value) { throw new UnsupportedOperationException("engineSetParameter unsupported"); } /** * @deprecated */ protected Object engineGetParameter( String param) { throw new UnsupportedOperationException("engineSetParameter unsupported"); } } bouncycastle-1.49.orig/src/org/bouncycastle/jcajce/provider/asymmetric/ecgost/KeyFactorySpi.java0000644000175000017500000001347512110037231032613 0ustar ebourgebourgpackage org.bouncycastle.jcajce.provider.asymmetric.ecgost; import java.io.IOException; import java.security.InvalidKeyException; import java.security.Key; import java.security.PrivateKey; import java.security.PublicKey; import java.security.interfaces.ECPrivateKey; import java.security.interfaces.ECPublicKey; import java.security.spec.InvalidKeySpecException; import java.security.spec.KeySpec; import org.bouncycastle.asn1.ASN1ObjectIdentifier; import org.bouncycastle.asn1.cryptopro.CryptoProObjectIdentifiers; import org.bouncycastle.asn1.pkcs.PrivateKeyInfo; import org.bouncycastle.asn1.x509.SubjectPublicKeyInfo; import org.bouncycastle.jcajce.provider.asymmetric.util.EC5Util; import org.bouncycastle.jcajce.provider.asymmetric.util.BaseKeyFactorySpi; import org.bouncycastle.jce.provider.BouncyCastleProvider; import org.bouncycastle.jce.spec.ECParameterSpec; import org.bouncycastle.jce.spec.ECPrivateKeySpec; import org.bouncycastle.jce.spec.ECPublicKeySpec; public class KeyFactorySpi extends BaseKeyFactorySpi { public KeyFactorySpi() { } protected KeySpec engineGetKeySpec( Key key, Class spec) throws InvalidKeySpecException { if (spec.isAssignableFrom(java.security.spec.ECPublicKeySpec.class) && key instanceof ECPublicKey) { ECPublicKey k = (ECPublicKey)key; if (k.getParams() != null) { return new java.security.spec.ECPublicKeySpec(k.getW(), k.getParams()); } else { ECParameterSpec implicitSpec = BouncyCastleProvider.CONFIGURATION.getEcImplicitlyCa(); return new java.security.spec.ECPublicKeySpec(k.getW(), EC5Util.convertSpec(EC5Util.convertCurve(implicitSpec.getCurve(), implicitSpec.getSeed()), implicitSpec)); } } else if (spec.isAssignableFrom(java.security.spec.ECPrivateKeySpec.class) && key instanceof ECPrivateKey) { ECPrivateKey k = (ECPrivateKey)key; if (k.getParams() != null) { return new java.security.spec.ECPrivateKeySpec(k.getS(), k.getParams()); } else { ECParameterSpec implicitSpec = BouncyCastleProvider.CONFIGURATION.getEcImplicitlyCa(); return new java.security.spec.ECPrivateKeySpec(k.getS(), EC5Util.convertSpec(EC5Util.convertCurve(implicitSpec.getCurve(), implicitSpec.getSeed()), implicitSpec)); } } else if (spec.isAssignableFrom(org.bouncycastle.jce.spec.ECPublicKeySpec.class) && key instanceof ECPublicKey) { ECPublicKey k = (ECPublicKey)key; if (k.getParams() != null) { return new org.bouncycastle.jce.spec.ECPublicKeySpec(EC5Util.convertPoint(k.getParams(), k.getW(), false), EC5Util.convertSpec(k.getParams(), false)); } else { ECParameterSpec implicitSpec = BouncyCastleProvider.CONFIGURATION.getEcImplicitlyCa(); return new org.bouncycastle.jce.spec.ECPublicKeySpec(EC5Util.convertPoint(k.getParams(), k.getW(), false), implicitSpec); } } else if (spec.isAssignableFrom(org.bouncycastle.jce.spec.ECPrivateKeySpec.class) && key instanceof ECPrivateKey) { ECPrivateKey k = (ECPrivateKey)key; if (k.getParams() != null) { return new org.bouncycastle.jce.spec.ECPrivateKeySpec(k.getS(), EC5Util.convertSpec(k.getParams(), false)); } else { ECParameterSpec implicitSpec = BouncyCastleProvider.CONFIGURATION.getEcImplicitlyCa(); return new org.bouncycastle.jce.spec.ECPrivateKeySpec(k.getS(), implicitSpec); } } return super.engineGetKeySpec(key, spec); } protected Key engineTranslateKey( Key key) throws InvalidKeyException { throw new InvalidKeyException("key type unknown"); } protected PrivateKey engineGeneratePrivate( KeySpec keySpec) throws InvalidKeySpecException { if (keySpec instanceof ECPrivateKeySpec) { return new BCECGOST3410PrivateKey((ECPrivateKeySpec)keySpec); } else if (keySpec instanceof java.security.spec.ECPrivateKeySpec) { return new BCECGOST3410PrivateKey((java.security.spec.ECPrivateKeySpec)keySpec); } return super.engineGeneratePrivate(keySpec); } protected PublicKey engineGeneratePublic( KeySpec keySpec) throws InvalidKeySpecException { if (keySpec instanceof ECPublicKeySpec) { return new BCECGOST3410PublicKey((ECPublicKeySpec)keySpec); } else if (keySpec instanceof java.security.spec.ECPublicKeySpec) { return new BCECGOST3410PublicKey((java.security.spec.ECPublicKeySpec)keySpec); } return super.engineGeneratePublic(keySpec); } public PrivateKey generatePrivate(PrivateKeyInfo keyInfo) throws IOException { ASN1ObjectIdentifier algOid = keyInfo.getPrivateKeyAlgorithm().getAlgorithm(); if (algOid.equals(CryptoProObjectIdentifiers.gostR3410_2001)) { return new BCECGOST3410PrivateKey(keyInfo); } else { throw new IOException("algorithm identifier " + algOid + " in key not recognised"); } } public PublicKey generatePublic(SubjectPublicKeyInfo keyInfo) throws IOException { ASN1ObjectIdentifier algOid = keyInfo.getAlgorithm().getAlgorithm(); if (algOid.equals(CryptoProObjectIdentifiers.gostR3410_2001)) { return new BCECGOST3410PublicKey(keyInfo); } else { throw new IOException("algorithm identifier " + algOid + " in key not recognised"); } } } ././@LongLink0000000000000000000000000000014700000000000011567 Lustar rootrootbouncycastle-1.49.orig/src/org/bouncycastle/jcajce/provider/asymmetric/ecgost/KeyPairGeneratorSpi.javabouncycastle-1.49.orig/src/org/bouncycastle/jcajce/provider/asymmetric/ecgost/KeyPairGeneratorSpi.ja0000644000175000017500000001474412110037231033417 0ustar ebourgebourgpackage org.bouncycastle.jcajce.provider.asymmetric.ecgost; import java.math.BigInteger; import java.security.InvalidAlgorithmParameterException; import java.security.InvalidParameterException; import java.security.KeyPair; import java.security.SecureRandom; import java.security.spec.AlgorithmParameterSpec; import java.security.spec.ECGenParameterSpec; import org.bouncycastle.asn1.cryptopro.ECGOST3410NamedCurves; import org.bouncycastle.crypto.AsymmetricCipherKeyPair; import org.bouncycastle.crypto.generators.ECKeyPairGenerator; import org.bouncycastle.crypto.params.ECDomainParameters; import org.bouncycastle.crypto.params.ECKeyGenerationParameters; import org.bouncycastle.crypto.params.ECPrivateKeyParameters; import org.bouncycastle.crypto.params.ECPublicKeyParameters; import org.bouncycastle.jcajce.provider.asymmetric.util.EC5Util; import org.bouncycastle.jce.provider.BouncyCastleProvider; import org.bouncycastle.jce.spec.ECNamedCurveGenParameterSpec; import org.bouncycastle.jce.spec.ECNamedCurveSpec; import org.bouncycastle.jce.spec.ECParameterSpec; import org.bouncycastle.math.ec.ECCurve; import org.bouncycastle.math.ec.ECPoint; public class KeyPairGeneratorSpi extends java.security.KeyPairGenerator { Object ecParams = null; ECKeyPairGenerator engine = new ECKeyPairGenerator(); String algorithm = "ECGOST3410"; ECKeyGenerationParameters param; int strength = 239; SecureRandom random = null; boolean initialised = false; public KeyPairGeneratorSpi() { super("ECGOST3410"); } public void initialize( int strength, SecureRandom random) { this.strength = strength; this.random = random; if (ecParams != null) { try { initialize((ECGenParameterSpec)ecParams, random); } catch (InvalidAlgorithmParameterException e) { throw new InvalidParameterException("key size not configurable."); } } else { throw new InvalidParameterException("unknown key size."); } } public void initialize( AlgorithmParameterSpec params, SecureRandom random) throws InvalidAlgorithmParameterException { if (params instanceof ECParameterSpec) { ECParameterSpec p = (ECParameterSpec)params; this.ecParams = params; param = new ECKeyGenerationParameters(new ECDomainParameters(p.getCurve(), p.getG(), p.getN()), random); engine.init(param); initialised = true; } else if (params instanceof java.security.spec.ECParameterSpec) { java.security.spec.ECParameterSpec p = (java.security.spec.ECParameterSpec)params; this.ecParams = params; ECCurve curve = EC5Util.convertCurve(p.getCurve()); ECPoint g = EC5Util.convertPoint(curve, p.getGenerator(), false); param = new ECKeyGenerationParameters(new ECDomainParameters(curve, g, p.getOrder(), BigInteger.valueOf(p.getCofactor())), random); engine.init(param); initialised = true; } else if (params instanceof ECGenParameterSpec || params instanceof ECNamedCurveGenParameterSpec) { String curveName; if (params instanceof ECGenParameterSpec) { curveName = ((ECGenParameterSpec)params).getName(); } else { curveName = ((ECNamedCurveGenParameterSpec)params).getName(); } ECDomainParameters ecP = ECGOST3410NamedCurves.getByName(curveName); if (ecP == null) { throw new InvalidAlgorithmParameterException("unknown curve name: " + curveName); } this.ecParams = new ECNamedCurveSpec( curveName, ecP.getCurve(), ecP.getG(), ecP.getN(), ecP.getH(), ecP.getSeed()); java.security.spec.ECParameterSpec p = (java.security.spec.ECParameterSpec)ecParams; ECCurve curve = EC5Util.convertCurve(p.getCurve()); ECPoint g = EC5Util.convertPoint(curve, p.getGenerator(), false); param = new ECKeyGenerationParameters(new ECDomainParameters(curve, g, p.getOrder(), BigInteger.valueOf(p.getCofactor())), random); engine.init(param); initialised = true; } else if (params == null && BouncyCastleProvider.CONFIGURATION.getEcImplicitlyCa() != null) { ECParameterSpec p = BouncyCastleProvider.CONFIGURATION.getEcImplicitlyCa(); this.ecParams = params; param = new ECKeyGenerationParameters(new ECDomainParameters(p.getCurve(), p.getG(), p.getN()), random); engine.init(param); initialised = true; } else if (params == null && BouncyCastleProvider.CONFIGURATION.getEcImplicitlyCa() == null) { throw new InvalidAlgorithmParameterException("null parameter passed but no implicitCA set"); } else { throw new InvalidAlgorithmParameterException("parameter object not a ECParameterSpec: " + params.getClass().getName()); } } public KeyPair generateKeyPair() { if (!initialised) { throw new IllegalStateException("EC Key Pair Generator not initialised"); } AsymmetricCipherKeyPair pair = engine.generateKeyPair(); ECPublicKeyParameters pub = (ECPublicKeyParameters)pair.getPublic(); ECPrivateKeyParameters priv = (ECPrivateKeyParameters)pair.getPrivate(); if (ecParams instanceof ECParameterSpec) { ECParameterSpec p = (ECParameterSpec)ecParams; BCECGOST3410PublicKey pubKey = new BCECGOST3410PublicKey(algorithm, pub, p); return new KeyPair(pubKey, new BCECGOST3410PrivateKey(algorithm, priv, pubKey, p)); } else if (ecParams == null) { return new KeyPair(new BCECGOST3410PublicKey(algorithm, pub), new BCECGOST3410PrivateKey(algorithm, priv)); } else { java.security.spec.ECParameterSpec p = (java.security.spec.ECParameterSpec)ecParams; BCECGOST3410PublicKey pubKey = new BCECGOST3410PublicKey(algorithm, pub, p); return new KeyPair(pubKey, new BCECGOST3410PrivateKey(algorithm, priv, pubKey, p)); } } } ././@LongLink0000000000000000000000000000015200000000000011563 Lustar rootrootbouncycastle-1.49.orig/src/org/bouncycastle/jcajce/provider/asymmetric/ecgost/BCECGOST3410PrivateKey.javabouncycastle-1.49.orig/src/org/bouncycastle/jcajce/provider/asymmetric/ecgost/BCECGOST3410PrivateKey0000644000175000017500000003405712110037231032643 0ustar ebourgebourgpackage org.bouncycastle.jcajce.provider.asymmetric.ecgost; import java.io.IOException; import java.io.ObjectInputStream; import java.io.ObjectOutputStream; import java.math.BigInteger; import java.security.interfaces.ECPrivateKey; import java.security.spec.ECParameterSpec; import java.security.spec.ECPoint; import java.security.spec.ECPrivateKeySpec; import java.security.spec.EllipticCurve; import java.util.Enumeration; import org.bouncycastle.asn1.ASN1Encodable; import org.bouncycastle.asn1.ASN1Encoding; import org.bouncycastle.asn1.ASN1ObjectIdentifier; import org.bouncycastle.asn1.ASN1Primitive; import org.bouncycastle.asn1.DERBitString; import org.bouncycastle.asn1.DERInteger; import org.bouncycastle.asn1.DERNull; import org.bouncycastle.asn1.DERObjectIdentifier; import org.bouncycastle.asn1.cryptopro.CryptoProObjectIdentifiers; import org.bouncycastle.asn1.cryptopro.ECGOST3410NamedCurves; import org.bouncycastle.asn1.pkcs.PrivateKeyInfo; import org.bouncycastle.asn1.x509.AlgorithmIdentifier; import org.bouncycastle.asn1.x509.SubjectPublicKeyInfo; import org.bouncycastle.asn1.x9.X962Parameters; import org.bouncycastle.asn1.x9.X9ECParameters; import org.bouncycastle.asn1.x9.X9ObjectIdentifiers; import org.bouncycastle.crypto.params.ECDomainParameters; import org.bouncycastle.crypto.params.ECPrivateKeyParameters; import org.bouncycastle.jcajce.provider.asymmetric.util.EC5Util; import org.bouncycastle.jcajce.provider.asymmetric.util.ECUtil; import org.bouncycastle.jcajce.provider.asymmetric.util.PKCS12BagAttributeCarrierImpl; import org.bouncycastle.jce.interfaces.ECPointEncoder; import org.bouncycastle.jce.interfaces.PKCS12BagAttributeCarrier; import org.bouncycastle.jce.provider.BouncyCastleProvider; import org.bouncycastle.jce.spec.ECNamedCurveSpec; import org.bouncycastle.math.ec.ECCurve; public class BCECGOST3410PrivateKey implements ECPrivateKey, org.bouncycastle.jce.interfaces.ECPrivateKey, PKCS12BagAttributeCarrier, ECPointEncoder { static final long serialVersionUID = 7245981689601667138L; private String algorithm = "ECGOST3410"; private boolean withCompression; private transient BigInteger d; private transient ECParameterSpec ecSpec; private transient DERBitString publicKey; private transient PKCS12BagAttributeCarrierImpl attrCarrier = new PKCS12BagAttributeCarrierImpl(); protected BCECGOST3410PrivateKey() { } public BCECGOST3410PrivateKey( ECPrivateKey key) { this.d = key.getS(); this.algorithm = key.getAlgorithm(); this.ecSpec = key.getParams(); } public BCECGOST3410PrivateKey( org.bouncycastle.jce.spec.ECPrivateKeySpec spec) { this.d = spec.getD(); if (spec.getParams() != null) // can be null if implicitlyCA { ECCurve curve = spec.getParams().getCurve(); EllipticCurve ellipticCurve; ellipticCurve = EC5Util.convertCurve(curve, spec.getParams().getSeed()); this.ecSpec = EC5Util.convertSpec(ellipticCurve, spec.getParams()); } else { this.ecSpec = null; } } public BCECGOST3410PrivateKey( ECPrivateKeySpec spec) { this.d = spec.getS(); this.ecSpec = spec.getParams(); } public BCECGOST3410PrivateKey( BCECGOST3410PrivateKey key) { this.d = key.d; this.ecSpec = key.ecSpec; this.withCompression = key.withCompression; this.attrCarrier = key.attrCarrier; this.publicKey = key.publicKey; } public BCECGOST3410PrivateKey( String algorithm, ECPrivateKeyParameters params, BCECGOST3410PublicKey pubKey, ECParameterSpec spec) { ECDomainParameters dp = params.getParameters(); this.algorithm = algorithm; this.d = params.getD(); if (spec == null) { EllipticCurve ellipticCurve = EC5Util.convertCurve(dp.getCurve(), dp.getSeed()); this.ecSpec = new ECParameterSpec( ellipticCurve, new ECPoint( dp.getG().getX().toBigInteger(), dp.getG().getY().toBigInteger()), dp.getN(), dp.getH().intValue()); } else { this.ecSpec = spec; } publicKey = getPublicKeyDetails(pubKey); } public BCECGOST3410PrivateKey( String algorithm, ECPrivateKeyParameters params, BCECGOST3410PublicKey pubKey, org.bouncycastle.jce.spec.ECParameterSpec spec) { ECDomainParameters dp = params.getParameters(); this.algorithm = algorithm; this.d = params.getD(); if (spec == null) { EllipticCurve ellipticCurve = EC5Util.convertCurve(dp.getCurve(), dp.getSeed()); this.ecSpec = new ECParameterSpec( ellipticCurve, new ECPoint( dp.getG().getX().toBigInteger(), dp.getG().getY().toBigInteger()), dp.getN(), dp.getH().intValue()); } else { EllipticCurve ellipticCurve = EC5Util.convertCurve(spec.getCurve(), spec.getSeed()); this.ecSpec = new ECParameterSpec( ellipticCurve, new ECPoint( spec.getG().getX().toBigInteger(), spec.getG().getY().toBigInteger()), spec.getN(), spec.getH().intValue()); } publicKey = getPublicKeyDetails(pubKey); } public BCECGOST3410PrivateKey( String algorithm, ECPrivateKeyParameters params) { this.algorithm = algorithm; this.d = params.getD(); this.ecSpec = null; } BCECGOST3410PrivateKey( PrivateKeyInfo info) throws IOException { populateFromPrivKeyInfo(info); } private void populateFromPrivKeyInfo(PrivateKeyInfo info) throws IOException { X962Parameters params = new X962Parameters((ASN1Primitive)info.getPrivateKeyAlgorithm().getParameters()); if (params.isNamedCurve()) { ASN1ObjectIdentifier oid = ASN1ObjectIdentifier.getInstance(params.getParameters()); X9ECParameters ecP = ECUtil.getNamedCurveByOid(oid); if (ecP == null) // GOST Curve { ECDomainParameters gParam = ECGOST3410NamedCurves.getByOID(oid); EllipticCurve ellipticCurve = EC5Util.convertCurve(gParam.getCurve(), gParam.getSeed()); ecSpec = new ECNamedCurveSpec( ECGOST3410NamedCurves.getName(oid), ellipticCurve, new ECPoint( gParam.getG().getX().toBigInteger(), gParam.getG().getY().toBigInteger()), gParam.getN(), gParam.getH()); } else { EllipticCurve ellipticCurve = EC5Util.convertCurve(ecP.getCurve(), ecP.getSeed()); ecSpec = new ECNamedCurveSpec( ECUtil.getCurveName(oid), ellipticCurve, new ECPoint( ecP.getG().getX().toBigInteger(), ecP.getG().getY().toBigInteger()), ecP.getN(), ecP.getH()); } } else if (params.isImplicitlyCA()) { ecSpec = null; } else { X9ECParameters ecP = X9ECParameters.getInstance(params.getParameters()); EllipticCurve ellipticCurve = EC5Util.convertCurve(ecP.getCurve(), ecP.getSeed()); this.ecSpec = new ECParameterSpec( ellipticCurve, new ECPoint( ecP.getG().getX().toBigInteger(), ecP.getG().getY().toBigInteger()), ecP.getN(), ecP.getH().intValue()); } ASN1Encodable privKey = info.parsePrivateKey(); if (privKey instanceof DERInteger) { DERInteger derD = DERInteger.getInstance(privKey); this.d = derD.getValue(); } else { org.bouncycastle.asn1.sec.ECPrivateKey ec = org.bouncycastle.asn1.sec.ECPrivateKey.getInstance(privKey); this.d = ec.getKey(); this.publicKey = ec.getPublicKey(); } } public String getAlgorithm() { return algorithm; } /** * return the encoding format we produce in getEncoded(). * * @return the string "PKCS#8" */ public String getFormat() { return "PKCS#8"; } /** * Return a PKCS8 representation of the key. The sequence returned * represents a full PrivateKeyInfo object. * * @return a PKCS8 representation of the key. */ public byte[] getEncoded() { X962Parameters params; if (ecSpec instanceof ECNamedCurveSpec) { DERObjectIdentifier curveOid = ECUtil.getNamedCurveOid(((ECNamedCurveSpec)ecSpec).getName()); if (curveOid == null) // guess it's the OID { curveOid = new DERObjectIdentifier(((ECNamedCurveSpec)ecSpec).getName()); } params = new X962Parameters(curveOid); } else if (ecSpec == null) { params = new X962Parameters(DERNull.INSTANCE); } else { ECCurve curve = EC5Util.convertCurve(ecSpec.getCurve()); X9ECParameters ecP = new X9ECParameters( curve, EC5Util.convertPoint(curve, ecSpec.getGenerator(), withCompression), ecSpec.getOrder(), BigInteger.valueOf(ecSpec.getCofactor()), ecSpec.getCurve().getSeed()); params = new X962Parameters(ecP); } PrivateKeyInfo info; org.bouncycastle.asn1.sec.ECPrivateKey keyStructure; if (publicKey != null) { keyStructure = new org.bouncycastle.asn1.sec.ECPrivateKey(this.getS(), publicKey, params); } else { keyStructure = new org.bouncycastle.asn1.sec.ECPrivateKey(this.getS(), params); } try { if (algorithm.equals("ECGOST3410")) { info = new PrivateKeyInfo(new AlgorithmIdentifier(CryptoProObjectIdentifiers.gostR3410_2001, params.toASN1Primitive()), keyStructure.toASN1Primitive()); } else { info = new PrivateKeyInfo(new AlgorithmIdentifier(X9ObjectIdentifiers.id_ecPublicKey, params.toASN1Primitive()), keyStructure.toASN1Primitive()); } return info.getEncoded(ASN1Encoding.DER); } catch (IOException e) { return null; } } public ECParameterSpec getParams() { return ecSpec; } public org.bouncycastle.jce.spec.ECParameterSpec getParameters() { if (ecSpec == null) { return null; } return EC5Util.convertSpec(ecSpec, withCompression); } org.bouncycastle.jce.spec.ECParameterSpec engineGetSpec() { if (ecSpec != null) { return EC5Util.convertSpec(ecSpec, withCompression); } return BouncyCastleProvider.CONFIGURATION.getEcImplicitlyCa(); } public BigInteger getS() { return d; } public BigInteger getD() { return d; } public void setBagAttribute( ASN1ObjectIdentifier oid, ASN1Encodable attribute) { attrCarrier.setBagAttribute(oid, attribute); } public ASN1Encodable getBagAttribute( ASN1ObjectIdentifier oid) { return attrCarrier.getBagAttribute(oid); } public Enumeration getBagAttributeKeys() { return attrCarrier.getBagAttributeKeys(); } public void setPointFormat(String style) { withCompression = !("UNCOMPRESSED".equalsIgnoreCase(style)); } public boolean equals(Object o) { if (!(o instanceof BCECGOST3410PrivateKey)) { return false; } BCECGOST3410PrivateKey other = (BCECGOST3410PrivateKey)o; return getD().equals(other.getD()) && (engineGetSpec().equals(other.engineGetSpec())); } public int hashCode() { return getD().hashCode() ^ engineGetSpec().hashCode(); } public String toString() { StringBuffer buf = new StringBuffer(); String nl = System.getProperty("line.separator"); buf.append("EC Private Key").append(nl); buf.append(" S: ").append(this.d.toString(16)).append(nl); return buf.toString(); } private DERBitString getPublicKeyDetails(BCECGOST3410PublicKey pub) { try { SubjectPublicKeyInfo info = SubjectPublicKeyInfo.getInstance(ASN1Primitive.fromByteArray(pub.getEncoded())); return info.getPublicKeyData(); } catch (IOException e) { // should never happen return null; } } private void readObject( ObjectInputStream in) throws IOException, ClassNotFoundException { in.defaultReadObject(); byte[] enc = (byte[])in.readObject(); populateFromPrivKeyInfo(PrivateKeyInfo.getInstance(ASN1Primitive.fromByteArray(enc))); this.attrCarrier = new PKCS12BagAttributeCarrierImpl(); } private void writeObject( ObjectOutputStream out) throws IOException { out.defaultWriteObject(); out.writeObject(this.getEncoded()); } } bouncycastle-1.49.orig/src/org/bouncycastle/jcajce/provider/asymmetric/rsa/0000755000175000017500000000000012152033551026512 5ustar ebourgebourgbouncycastle-1.49.orig/src/org/bouncycastle/jcajce/provider/asymmetric/rsa/DigestSignatureSpi.java0000644000175000017500000002340000000000107033105 0ustar ebourgebourgpackage org.bouncycastle.jcajce.provider.asymmetric.rsa; import java.io.IOException; import java.security.AlgorithmParameters; import java.security.InvalidKeyException; import java.security.PrivateKey; import java.security.PublicKey; import java.security.SignatureException; import java.security.SignatureSpi; import java.security.interfaces.RSAPrivateKey; import java.security.interfaces.RSAPublicKey; import java.security.spec.AlgorithmParameterSpec; import org.bouncycastle.asn1.ASN1Encoding; import org.bouncycastle.asn1.ASN1ObjectIdentifier; import org.bouncycastle.asn1.DERNull; import org.bouncycastle.asn1.nist.NISTObjectIdentifiers; import org.bouncycastle.asn1.oiw.OIWObjectIdentifiers; import org.bouncycastle.asn1.pkcs.PKCSObjectIdentifiers; import org.bouncycastle.asn1.teletrust.TeleTrusTObjectIdentifiers; import org.bouncycastle.asn1.x509.AlgorithmIdentifier; import org.bouncycastle.asn1.x509.DigestInfo; import org.bouncycastle.crypto.AsymmetricBlockCipher; import org.bouncycastle.crypto.CipherParameters; import org.bouncycastle.crypto.Digest; import org.bouncycastle.crypto.digests.MD2Digest; import org.bouncycastle.crypto.digests.MD4Digest; import org.bouncycastle.crypto.digests.MD5Digest; import org.bouncycastle.crypto.digests.NullDigest; import org.bouncycastle.crypto.digests.RIPEMD128Digest; import org.bouncycastle.crypto.digests.RIPEMD160Digest; import org.bouncycastle.crypto.digests.RIPEMD256Digest; import org.bouncycastle.crypto.digests.SHA1Digest; import org.bouncycastle.crypto.digests.SHA224Digest; import org.bouncycastle.crypto.digests.SHA256Digest; import org.bouncycastle.crypto.digests.SHA384Digest; import org.bouncycastle.crypto.digests.SHA512Digest; import org.bouncycastle.crypto.encodings.PKCS1Encoding; import org.bouncycastle.crypto.engines.RSABlindedEngine; public class DigestSignatureSpi extends SignatureSpi { private Digest digest; private AsymmetricBlockCipher cipher; private AlgorithmIdentifier algId; // care - this constructor is actually used by outside organisations protected DigestSignatureSpi( Digest digest, AsymmetricBlockCipher cipher) { this.digest = digest; this.cipher = cipher; this.algId = null; } // care - this constructor is actually used by outside organisations protected DigestSignatureSpi( ASN1ObjectIdentifier objId, Digest digest, AsymmetricBlockCipher cipher) { this.digest = digest; this.cipher = cipher; this.algId = new AlgorithmIdentifier(objId, DERNull.INSTANCE); } protected void engineInitVerify( PublicKey publicKey) throws InvalidKeyException { if (!(publicKey instanceof RSAPublicKey)) { throw new InvalidKeyException("Supplied key (" + getType(publicKey) + ") is not a RSAPublicKey instance"); } CipherParameters param = RSAUtil.generatePublicKeyParameter((RSAPublicKey)publicKey); digest.reset(); cipher.init(false, param); } protected void engineInitSign( PrivateKey privateKey) throws InvalidKeyException { if (!(privateKey instanceof RSAPrivateKey)) { throw new InvalidKeyException("Supplied key (" + getType(privateKey) + ") is not a RSAPrivateKey instance"); } CipherParameters param = RSAUtil.generatePrivateKeyParameter((RSAPrivateKey)privateKey); digest.reset(); cipher.init(true, param); } private String getType( Object o) { if (o == null) { return null; } return o.getClass().getName(); } protected void engineUpdate( byte b) throws SignatureException { digest.update(b); } protected void engineUpdate( byte[] b, int off, int len) throws SignatureException { digest.update(b, off, len); } protected byte[] engineSign() throws SignatureException { byte[] hash = new byte[digest.getDigestSize()]; digest.doFinal(hash, 0); try { byte[] bytes = derEncode(hash); return cipher.processBlock(bytes, 0, bytes.length); } catch (ArrayIndexOutOfBoundsException e) { throw new SignatureException("key too small for signature type"); } catch (Exception e) { throw new SignatureException(e.toString()); } } protected boolean engineVerify( byte[] sigBytes) throws SignatureException { byte[] hash = new byte[digest.getDigestSize()]; digest.doFinal(hash, 0); byte[] sig; byte[] expected; try { sig = cipher.processBlock(sigBytes, 0, sigBytes.length); expected = derEncode(hash); } catch (Exception e) { return false; } if (sig.length == expected.length) { for (int i = 0; i < sig.length; i++) { if (sig[i] != expected[i]) { return false; } } } else if (sig.length == expected.length - 2) // NULL left out { int sigOffset = sig.length - hash.length - 2; int expectedOffset = expected.length - hash.length - 2; expected[1] -= 2; // adjust lengths expected[3] -= 2; for (int i = 0; i < hash.length; i++) { if (sig[sigOffset + i] != expected[expectedOffset + i]) // check hash { return false; } } for (int i = 0; i < sigOffset; i++) { if (sig[i] != expected[i]) // check header less NULL { return false; } } } else { return false; } return true; } protected void engineSetParameter( AlgorithmParameterSpec params) { throw new UnsupportedOperationException("engineSetParameter unsupported"); } /** * @deprecated replaced with */ protected void engineSetParameter( String param, Object value) { throw new UnsupportedOperationException("engineSetParameter unsupported"); } /** * @deprecated */ protected Object engineGetParameter( String param) { return null; } protected AlgorithmParameters engineGetParameters() { return null; } private byte[] derEncode( byte[] hash) throws IOException { if (algId == null) { // For raw RSA, the DigestInfo must be prepared externally return hash; } DigestInfo dInfo = new DigestInfo(algId, hash); return dInfo.getEncoded(ASN1Encoding.DER); } static public class SHA1 extends DigestSignatureSpi { public SHA1() { super(OIWObjectIdentifiers.idSHA1, new SHA1Digest(), new PKCS1Encoding(new RSABlindedEngine())); } } static public class SHA224 extends DigestSignatureSpi { public SHA224() { super(NISTObjectIdentifiers.id_sha224, new SHA224Digest(), new PKCS1Encoding(new RSABlindedEngine())); } } static public class SHA256 extends DigestSignatureSpi { public SHA256() { super(NISTObjectIdentifiers.id_sha256, new SHA256Digest(), new PKCS1Encoding(new RSABlindedEngine())); } } static public class SHA384 extends DigestSignatureSpi { public SHA384() { super(NISTObjectIdentifiers.id_sha384, new SHA384Digest(), new PKCS1Encoding(new RSABlindedEngine())); } } static public class SHA512 extends DigestSignatureSpi { public SHA512() { super(NISTObjectIdentifiers.id_sha512, new SHA512Digest(), new PKCS1Encoding(new RSABlindedEngine())); } } static public class MD2 extends DigestSignatureSpi { public MD2() { super(PKCSObjectIdentifiers.md2, new MD2Digest(), new PKCS1Encoding(new RSABlindedEngine())); } } static public class MD4 extends DigestSignatureSpi { public MD4() { super(PKCSObjectIdentifiers.md4, new MD4Digest(), new PKCS1Encoding(new RSABlindedEngine())); } } static public class MD5 extends DigestSignatureSpi { public MD5() { super(PKCSObjectIdentifiers.md5, new MD5Digest(), new PKCS1Encoding(new RSABlindedEngine())); } } static public class RIPEMD160 extends DigestSignatureSpi { public RIPEMD160() { super(TeleTrusTObjectIdentifiers.ripemd160, new RIPEMD160Digest(), new PKCS1Encoding(new RSABlindedEngine())); } } static public class RIPEMD128 extends DigestSignatureSpi { public RIPEMD128() { super(TeleTrusTObjectIdentifiers.ripemd128, new RIPEMD128Digest(), new PKCS1Encoding(new RSABlindedEngine())); } } static public class RIPEMD256 extends DigestSignatureSpi { public RIPEMD256() { super(TeleTrusTObjectIdentifiers.ripemd256, new RIPEMD256Digest(), new PKCS1Encoding(new RSABlindedEngine())); } } static public class noneRSA extends DigestSignatureSpi { public noneRSA() { super(new NullDigest(), new PKCS1Encoding(new RSABlindedEngine())); } } } bouncycastle-1.49.orig/src/org/bouncycastle/jcajce/provider/asymmetric/rsa/ISOSignatureSpi.java0000644000175000017500000000710211625630143032351 0ustar ebourgebourgpackage org.bouncycastle.jcajce.provider.asymmetric.rsa; import java.security.InvalidKeyException; import java.security.PrivateKey; import java.security.PublicKey; import java.security.SignatureException; import java.security.SignatureSpi; import java.security.interfaces.RSAPrivateKey; import java.security.interfaces.RSAPublicKey; import java.security.spec.AlgorithmParameterSpec; import org.bouncycastle.crypto.AsymmetricBlockCipher; import org.bouncycastle.crypto.CipherParameters; import org.bouncycastle.crypto.Digest; import org.bouncycastle.crypto.digests.MD5Digest; import org.bouncycastle.crypto.digests.RIPEMD160Digest; import org.bouncycastle.crypto.digests.SHA1Digest; import org.bouncycastle.crypto.engines.RSABlindedEngine; import org.bouncycastle.crypto.signers.ISO9796d2Signer; public class ISOSignatureSpi extends SignatureSpi { private ISO9796d2Signer signer; protected ISOSignatureSpi( Digest digest, AsymmetricBlockCipher cipher) { signer = new ISO9796d2Signer(cipher, digest, true); } protected void engineInitVerify( PublicKey publicKey) throws InvalidKeyException { CipherParameters param = RSAUtil.generatePublicKeyParameter((RSAPublicKey)publicKey); signer.init(false, param); } protected void engineInitSign( PrivateKey privateKey) throws InvalidKeyException { CipherParameters param = RSAUtil.generatePrivateKeyParameter((RSAPrivateKey)privateKey); signer.init(true, param); } protected void engineUpdate( byte b) throws SignatureException { signer.update(b); } protected void engineUpdate( byte[] b, int off, int len) throws SignatureException { signer.update(b, off, len); } protected byte[] engineSign() throws SignatureException { try { byte[] sig = signer.generateSignature(); return sig; } catch (Exception e) { throw new SignatureException(e.toString()); } } protected boolean engineVerify( byte[] sigBytes) throws SignatureException { boolean yes = signer.verifySignature(sigBytes); return yes; } protected void engineSetParameter( AlgorithmParameterSpec params) { throw new UnsupportedOperationException("engineSetParameter unsupported"); } /** * @deprecated replaced with */ protected void engineSetParameter( String param, Object value) { throw new UnsupportedOperationException("engineSetParameter unsupported"); } /** * @deprecated */ protected Object engineGetParameter( String param) { throw new UnsupportedOperationException("engineSetParameter unsupported"); } static public class SHA1WithRSAEncryption extends ISOSignatureSpi { public SHA1WithRSAEncryption() { super(new SHA1Digest(), new RSABlindedEngine()); } } static public class MD5WithRSAEncryption extends ISOSignatureSpi { public MD5WithRSAEncryption() { super(new MD5Digest(), new RSABlindedEngine()); } } static public class RIPEMD160WithRSAEncryption extends ISOSignatureSpi { public RIPEMD160WithRSAEncryption() { super(new RIPEMD160Digest(), new RSABlindedEngine()); } } } bouncycastle-1.49.orig/src/org/bouncycastle/jcajce/provider/asymmetric/rsa/BCRSAPrivateKey.java0000644000175000017500000000701512103437526032224 0ustar ebourgebourgpackage org.bouncycastle.jcajce.provider.asymmetric.rsa; import java.io.IOException; import java.io.ObjectInputStream; import java.io.ObjectOutputStream; import java.math.BigInteger; import java.security.interfaces.RSAPrivateKey; import java.security.spec.RSAPrivateKeySpec; import java.util.Enumeration; import org.bouncycastle.asn1.ASN1Encodable; import org.bouncycastle.asn1.ASN1ObjectIdentifier; import org.bouncycastle.asn1.DERNull; import org.bouncycastle.asn1.pkcs.PKCSObjectIdentifiers; import org.bouncycastle.asn1.x509.AlgorithmIdentifier; import org.bouncycastle.crypto.params.RSAKeyParameters; import org.bouncycastle.jcajce.provider.asymmetric.util.KeyUtil; import org.bouncycastle.jcajce.provider.asymmetric.util.PKCS12BagAttributeCarrierImpl; import org.bouncycastle.jce.interfaces.PKCS12BagAttributeCarrier; public class BCRSAPrivateKey implements RSAPrivateKey, PKCS12BagAttributeCarrier { static final long serialVersionUID = 5110188922551353628L; private static BigInteger ZERO = BigInteger.valueOf(0); protected BigInteger modulus; protected BigInteger privateExponent; private transient PKCS12BagAttributeCarrierImpl attrCarrier = new PKCS12BagAttributeCarrierImpl(); protected BCRSAPrivateKey() { } BCRSAPrivateKey( RSAKeyParameters key) { this.modulus = key.getModulus(); this.privateExponent = key.getExponent(); } BCRSAPrivateKey( RSAPrivateKeySpec spec) { this.modulus = spec.getModulus(); this.privateExponent = spec.getPrivateExponent(); } BCRSAPrivateKey( RSAPrivateKey key) { this.modulus = key.getModulus(); this.privateExponent = key.getPrivateExponent(); } public BigInteger getModulus() { return modulus; } public BigInteger getPrivateExponent() { return privateExponent; } public String getAlgorithm() { return "RSA"; } public String getFormat() { return "PKCS#8"; } public byte[] getEncoded() { return KeyUtil.getEncodedPrivateKeyInfo(new AlgorithmIdentifier(PKCSObjectIdentifiers.rsaEncryption, DERNull.INSTANCE), new org.bouncycastle.asn1.pkcs.RSAPrivateKey(getModulus(), ZERO, getPrivateExponent(), ZERO, ZERO, ZERO, ZERO, ZERO)); } public boolean equals(Object o) { if (!(o instanceof RSAPrivateKey)) { return false; } if (o == this) { return true; } RSAPrivateKey key = (RSAPrivateKey)o; return getModulus().equals(key.getModulus()) && getPrivateExponent().equals(key.getPrivateExponent()); } public int hashCode() { return getModulus().hashCode() ^ getPrivateExponent().hashCode(); } public void setBagAttribute( ASN1ObjectIdentifier oid, ASN1Encodable attribute) { attrCarrier.setBagAttribute(oid, attribute); } public ASN1Encodable getBagAttribute( ASN1ObjectIdentifier oid) { return attrCarrier.getBagAttribute(oid); } public Enumeration getBagAttributeKeys() { return attrCarrier.getBagAttributeKeys(); } private void readObject( ObjectInputStream in) throws IOException, ClassNotFoundException { in.defaultReadObject(); this.attrCarrier = new PKCS12BagAttributeCarrierImpl(); } private void writeObject( ObjectOutputStream out) throws IOException { out.defaultWriteObject(); } } bouncycastle-1.49.orig/src/org/bouncycastle/jcajce/provider/asymmetric/rsa/BCRSAPrivateCrtKey.java0000644000175000017500000001632412103437526032700 0ustar ebourgebourgpackage org.bouncycastle.jcajce.provider.asymmetric.rsa; import java.io.IOException; import java.math.BigInteger; import java.security.interfaces.RSAPrivateCrtKey; import java.security.spec.RSAPrivateCrtKeySpec; import org.bouncycastle.asn1.DERNull; import org.bouncycastle.asn1.pkcs.PKCSObjectIdentifiers; import org.bouncycastle.asn1.pkcs.PrivateKeyInfo; import org.bouncycastle.asn1.pkcs.RSAPrivateKey; import org.bouncycastle.asn1.x509.AlgorithmIdentifier; import org.bouncycastle.crypto.params.RSAPrivateCrtKeyParameters; import org.bouncycastle.jcajce.provider.asymmetric.util.KeyUtil; /** * A provider representation for a RSA private key, with CRT factors included. */ public class BCRSAPrivateCrtKey extends BCRSAPrivateKey implements RSAPrivateCrtKey { static final long serialVersionUID = 7834723820638524718L; private BigInteger publicExponent; private BigInteger primeP; private BigInteger primeQ; private BigInteger primeExponentP; private BigInteger primeExponentQ; private BigInteger crtCoefficient; /** * construct a private key from it's org.bouncycastle.crypto equivalent. * * @param key the parameters object representing the private key. */ BCRSAPrivateCrtKey( RSAPrivateCrtKeyParameters key) { super(key); this.publicExponent = key.getPublicExponent(); this.primeP = key.getP(); this.primeQ = key.getQ(); this.primeExponentP = key.getDP(); this.primeExponentQ = key.getDQ(); this.crtCoefficient = key.getQInv(); } /** * construct a private key from an RSAPrivateCrtKeySpec * * @param spec the spec to be used in construction. */ BCRSAPrivateCrtKey( RSAPrivateCrtKeySpec spec) { this.modulus = spec.getModulus(); this.publicExponent = spec.getPublicExponent(); this.privateExponent = spec.getPrivateExponent(); this.primeP = spec.getPrimeP(); this.primeQ = spec.getPrimeQ(); this.primeExponentP = spec.getPrimeExponentP(); this.primeExponentQ = spec.getPrimeExponentQ(); this.crtCoefficient = spec.getCrtCoefficient(); } /** * construct a private key from another RSAPrivateCrtKey. * * @param key the object implementing the RSAPrivateCrtKey interface. */ BCRSAPrivateCrtKey( RSAPrivateCrtKey key) { this.modulus = key.getModulus(); this.publicExponent = key.getPublicExponent(); this.privateExponent = key.getPrivateExponent(); this.primeP = key.getPrimeP(); this.primeQ = key.getPrimeQ(); this.primeExponentP = key.getPrimeExponentP(); this.primeExponentQ = key.getPrimeExponentQ(); this.crtCoefficient = key.getCrtCoefficient(); } /** * construct an RSA key from a private key info object. */ BCRSAPrivateCrtKey( PrivateKeyInfo info) throws IOException { this(RSAPrivateKey.getInstance(info.parsePrivateKey())); } /** * construct an RSA key from a ASN.1 RSA private key object. */ BCRSAPrivateCrtKey( RSAPrivateKey key) { this.modulus = key.getModulus(); this.publicExponent = key.getPublicExponent(); this.privateExponent = key.getPrivateExponent(); this.primeP = key.getPrime1(); this.primeQ = key.getPrime2(); this.primeExponentP = key.getExponent1(); this.primeExponentQ = key.getExponent2(); this.crtCoefficient = key.getCoefficient(); } /** * return the encoding format we produce in getEncoded(). * * @return the encoding format we produce in getEncoded(). */ public String getFormat() { return "PKCS#8"; } /** * Return a PKCS8 representation of the key. The sequence returned * represents a full PrivateKeyInfo object. * * @return a PKCS8 representation of the key. */ public byte[] getEncoded() { return KeyUtil.getEncodedPrivateKeyInfo(new AlgorithmIdentifier(PKCSObjectIdentifiers.rsaEncryption, DERNull.INSTANCE), new RSAPrivateKey(getModulus(), getPublicExponent(), getPrivateExponent(), getPrimeP(), getPrimeQ(), getPrimeExponentP(), getPrimeExponentQ(), getCrtCoefficient())); } /** * return the public exponent. * * @return the public exponent. */ public BigInteger getPublicExponent() { return publicExponent; } /** * return the prime P. * * @return the prime P. */ public BigInteger getPrimeP() { return primeP; } /** * return the prime Q. * * @return the prime Q. */ public BigInteger getPrimeQ() { return primeQ; } /** * return the prime exponent for P. * * @return the prime exponent for P. */ public BigInteger getPrimeExponentP() { return primeExponentP; } /** * return the prime exponent for Q. * * @return the prime exponent for Q. */ public BigInteger getPrimeExponentQ() { return primeExponentQ; } /** * return the CRT coefficient. * * @return the CRT coefficient. */ public BigInteger getCrtCoefficient() { return crtCoefficient; } public int hashCode() { return this.getModulus().hashCode() ^ this.getPublicExponent().hashCode() ^ this.getPrivateExponent().hashCode(); } public boolean equals(Object o) { if (o == this) { return true; } if (!(o instanceof RSAPrivateCrtKey)) { return false; } RSAPrivateCrtKey key = (RSAPrivateCrtKey)o; return this.getModulus().equals(key.getModulus()) && this.getPublicExponent().equals(key.getPublicExponent()) && this.getPrivateExponent().equals(key.getPrivateExponent()) && this.getPrimeP().equals(key.getPrimeP()) && this.getPrimeQ().equals(key.getPrimeQ()) && this.getPrimeExponentP().equals(key.getPrimeExponentP()) && this.getPrimeExponentQ().equals(key.getPrimeExponentQ()) && this.getCrtCoefficient().equals(key.getCrtCoefficient()); } public String toString() { StringBuffer buf = new StringBuffer(); String nl = System.getProperty("line.separator"); buf.append("RSA Private CRT Key").append(nl); buf.append(" modulus: ").append(this.getModulus().toString(16)).append(nl); buf.append(" public exponent: ").append(this.getPublicExponent().toString(16)).append(nl); buf.append(" private exponent: ").append(this.getPrivateExponent().toString(16)).append(nl); buf.append(" primeP: ").append(this.getPrimeP().toString(16)).append(nl); buf.append(" primeQ: ").append(this.getPrimeQ().toString(16)).append(nl); buf.append(" primeExponentP: ").append(this.getPrimeExponentP().toString(16)).append(nl); buf.append(" primeExponentQ: ").append(this.getPrimeExponentQ().toString(16)).append(nl); buf.append(" crtCoefficient: ").append(this.getCrtCoefficient().toString(16)).append(nl); return buf.toString(); } } ././@LongLink0000000000000000000000000000014700000000000011567 Lustar rootrootbouncycastle-1.49.orig/src/org/bouncycastle/jcajce/provider/asymmetric/rsa/AlgorithmParametersSpi.javabouncycastle-1.49.orig/src/org/bouncycastle/jcajce/provider/asymmetric/rsa/AlgorithmParametersSpi.ja0000644000175000017500000002341212103437527033465 0ustar ebourgebourgpackage org.bouncycastle.jcajce.provider.asymmetric.rsa; import java.io.IOException; import java.security.spec.AlgorithmParameterSpec; import java.security.spec.InvalidParameterSpecException; import java.security.spec.MGF1ParameterSpec; import java.security.spec.PSSParameterSpec; import javax.crypto.spec.OAEPParameterSpec; import javax.crypto.spec.PSource; import org.bouncycastle.asn1.ASN1Encoding; import org.bouncycastle.asn1.ASN1Integer; import org.bouncycastle.asn1.ASN1OctetString; import org.bouncycastle.asn1.DERNull; import org.bouncycastle.asn1.DEROctetString; import org.bouncycastle.asn1.pkcs.PKCSObjectIdentifiers; import org.bouncycastle.asn1.pkcs.RSAESOAEPparams; import org.bouncycastle.asn1.pkcs.RSASSAPSSparams; import org.bouncycastle.asn1.x509.AlgorithmIdentifier; import org.bouncycastle.jcajce.provider.util.DigestFactory; public abstract class AlgorithmParametersSpi extends java.security.AlgorithmParametersSpi { protected boolean isASN1FormatString(String format) { return format == null || format.equals("ASN.1"); } protected AlgorithmParameterSpec engineGetParameterSpec( Class paramSpec) throws InvalidParameterSpecException { if (paramSpec == null) { throw new NullPointerException("argument to getParameterSpec must not be null"); } return localEngineGetParameterSpec(paramSpec); } protected abstract AlgorithmParameterSpec localEngineGetParameterSpec(Class paramSpec) throws InvalidParameterSpecException; public static class OAEP extends AlgorithmParametersSpi { OAEPParameterSpec currentSpec; /** * Return the PKCS#1 ASN.1 structure RSAES-OAEP-params. */ protected byte[] engineGetEncoded() { AlgorithmIdentifier hashAlgorithm = new AlgorithmIdentifier( DigestFactory.getOID(currentSpec.getDigestAlgorithm()), DERNull.INSTANCE); MGF1ParameterSpec mgfSpec = (MGF1ParameterSpec)currentSpec.getMGFParameters(); AlgorithmIdentifier maskGenAlgorithm = new AlgorithmIdentifier( PKCSObjectIdentifiers.id_mgf1, new AlgorithmIdentifier(DigestFactory.getOID(mgfSpec.getDigestAlgorithm()), DERNull.INSTANCE)); PSource.PSpecified pSource = (PSource.PSpecified)currentSpec.getPSource(); AlgorithmIdentifier pSourceAlgorithm = new AlgorithmIdentifier( PKCSObjectIdentifiers.id_pSpecified, new DEROctetString(pSource.getValue())); RSAESOAEPparams oaepP = new RSAESOAEPparams(hashAlgorithm, maskGenAlgorithm, pSourceAlgorithm); try { return oaepP.getEncoded(ASN1Encoding.DER); } catch (IOException e) { throw new RuntimeException("Error encoding OAEPParameters"); } } protected byte[] engineGetEncoded( String format) { if (isASN1FormatString(format) || format.equalsIgnoreCase("X.509")) { return engineGetEncoded(); } return null; } protected AlgorithmParameterSpec localEngineGetParameterSpec( Class paramSpec) throws InvalidParameterSpecException { if (paramSpec == OAEPParameterSpec.class && currentSpec != null) { return currentSpec; } throw new InvalidParameterSpecException("unknown parameter spec passed to OAEP parameters object."); } protected void engineInit( AlgorithmParameterSpec paramSpec) throws InvalidParameterSpecException { if (!(paramSpec instanceof OAEPParameterSpec)) { throw new InvalidParameterSpecException("OAEPParameterSpec required to initialise an OAEP algorithm parameters object"); } this.currentSpec = (OAEPParameterSpec)paramSpec; } protected void engineInit( byte[] params) throws IOException { try { RSAESOAEPparams oaepP = RSAESOAEPparams.getInstance(params); currentSpec = new OAEPParameterSpec( oaepP.getHashAlgorithm().getAlgorithm().getId(), oaepP.getMaskGenAlgorithm().getAlgorithm().getId(), new MGF1ParameterSpec(AlgorithmIdentifier.getInstance(oaepP.getMaskGenAlgorithm().getParameters()).getAlgorithm().getId()), new PSource.PSpecified(ASN1OctetString.getInstance(oaepP.getPSourceAlgorithm().getParameters()).getOctets())); } catch (ClassCastException e) { throw new IOException("Not a valid OAEP Parameter encoding."); } catch (ArrayIndexOutOfBoundsException e) { throw new IOException("Not a valid OAEP Parameter encoding."); } } protected void engineInit( byte[] params, String format) throws IOException { if (format.equalsIgnoreCase("X.509") || format.equalsIgnoreCase("ASN.1")) { engineInit(params); } else { throw new IOException("Unknown parameter format " + format); } } protected String engineToString() { return "OAEP Parameters"; } } public static class PSS extends AlgorithmParametersSpi { PSSParameterSpec currentSpec; /** * Return the PKCS#1 ASN.1 structure RSASSA-PSS-params. */ protected byte[] engineGetEncoded() throws IOException { PSSParameterSpec pssSpec = currentSpec; AlgorithmIdentifier hashAlgorithm = new AlgorithmIdentifier( DigestFactory.getOID(pssSpec.getDigestAlgorithm()), DERNull.INSTANCE); MGF1ParameterSpec mgfSpec = (MGF1ParameterSpec)pssSpec.getMGFParameters(); AlgorithmIdentifier maskGenAlgorithm = new AlgorithmIdentifier( PKCSObjectIdentifiers.id_mgf1, new AlgorithmIdentifier(DigestFactory.getOID(mgfSpec.getDigestAlgorithm()), DERNull.INSTANCE)); RSASSAPSSparams pssP = new RSASSAPSSparams(hashAlgorithm, maskGenAlgorithm, new ASN1Integer(pssSpec.getSaltLength()), new ASN1Integer(pssSpec.getTrailerField())); return pssP.getEncoded("DER"); } protected byte[] engineGetEncoded( String format) throws IOException { if (format.equalsIgnoreCase("X.509") || format.equalsIgnoreCase("ASN.1")) { return engineGetEncoded(); } return null; } protected AlgorithmParameterSpec localEngineGetParameterSpec( Class paramSpec) throws InvalidParameterSpecException { if (paramSpec == PSSParameterSpec.class && currentSpec != null) { return currentSpec; } throw new InvalidParameterSpecException("unknown parameter spec passed to PSS parameters object."); } protected void engineInit( AlgorithmParameterSpec paramSpec) throws InvalidParameterSpecException { if (!(paramSpec instanceof PSSParameterSpec)) { throw new InvalidParameterSpecException("PSSParameterSpec required to initialise an PSS algorithm parameters object"); } this.currentSpec = (PSSParameterSpec)paramSpec; } protected void engineInit( byte[] params) throws IOException { try { RSASSAPSSparams pssP = RSASSAPSSparams.getInstance(params); currentSpec = new PSSParameterSpec( pssP.getHashAlgorithm().getAlgorithm().getId(), pssP.getMaskGenAlgorithm().getAlgorithm().getId(), new MGF1ParameterSpec(AlgorithmIdentifier.getInstance(pssP.getMaskGenAlgorithm().getParameters()).getAlgorithm().getId()), pssP.getSaltLength().intValue(), pssP.getTrailerField().intValue()); } catch (ClassCastException e) { throw new IOException("Not a valid PSS Parameter encoding."); } catch (ArrayIndexOutOfBoundsException e) { throw new IOException("Not a valid PSS Parameter encoding."); } } protected void engineInit( byte[] params, String format) throws IOException { if (isASN1FormatString(format) || format.equalsIgnoreCase("X.509")) { engineInit(params); } else { throw new IOException("Unknown parameter format " + format); } } protected String engineToString() { return "PSS Parameters"; } } } bouncycastle-1.49.orig/src/org/bouncycastle/jcajce/provider/asymmetric/rsa/KeyFactorySpi.java0000644000175000017500000001234611625627770032137 0ustar ebourgebourgpackage org.bouncycastle.jcajce.provider.asymmetric.rsa; import java.io.IOException; import java.security.InvalidKeyException; import java.security.Key; import java.security.PrivateKey; import java.security.PublicKey; import java.security.interfaces.RSAPrivateCrtKey; import java.security.interfaces.RSAPublicKey; import java.security.spec.InvalidKeySpecException; import java.security.spec.KeySpec; import java.security.spec.PKCS8EncodedKeySpec; import java.security.spec.RSAPrivateCrtKeySpec; import java.security.spec.RSAPrivateKeySpec; import java.security.spec.RSAPublicKeySpec; import org.bouncycastle.asn1.ASN1ObjectIdentifier; import org.bouncycastle.asn1.pkcs.PrivateKeyInfo; import org.bouncycastle.asn1.pkcs.RSAPrivateKey; import org.bouncycastle.asn1.x509.SubjectPublicKeyInfo; import org.bouncycastle.jcajce.provider.asymmetric.util.BaseKeyFactorySpi; import org.bouncycastle.jcajce.provider.asymmetric.util.ExtendedInvalidKeySpecException; public class KeyFactorySpi extends BaseKeyFactorySpi { public KeyFactorySpi() { } protected KeySpec engineGetKeySpec( Key key, Class spec) throws InvalidKeySpecException { if (spec.isAssignableFrom(RSAPublicKeySpec.class) && key instanceof RSAPublicKey) { RSAPublicKey k = (RSAPublicKey)key; return new RSAPublicKeySpec(k.getModulus(), k.getPublicExponent()); } else if (spec.isAssignableFrom(RSAPrivateKeySpec.class) && key instanceof java.security.interfaces.RSAPrivateKey) { java.security.interfaces.RSAPrivateKey k = (java.security.interfaces.RSAPrivateKey)key; return new RSAPrivateKeySpec(k.getModulus(), k.getPrivateExponent()); } else if (spec.isAssignableFrom(RSAPrivateCrtKeySpec.class) && key instanceof RSAPrivateCrtKey) { RSAPrivateCrtKey k = (RSAPrivateCrtKey)key; return new RSAPrivateCrtKeySpec( k.getModulus(), k.getPublicExponent(), k.getPrivateExponent(), k.getPrimeP(), k.getPrimeQ(), k.getPrimeExponentP(), k.getPrimeExponentQ(), k.getCrtCoefficient()); } return super.engineGetKeySpec(key, spec); } protected Key engineTranslateKey( Key key) throws InvalidKeyException { if (key instanceof RSAPublicKey) { return new BCRSAPublicKey((RSAPublicKey)key); } else if (key instanceof RSAPrivateCrtKey) { return new BCRSAPrivateCrtKey((RSAPrivateCrtKey)key); } else if (key instanceof java.security.interfaces.RSAPrivateKey) { return new BCRSAPrivateKey((java.security.interfaces.RSAPrivateKey)key); } throw new InvalidKeyException("key type unknown"); } protected PrivateKey engineGeneratePrivate( KeySpec keySpec) throws InvalidKeySpecException { if (keySpec instanceof PKCS8EncodedKeySpec) { try { return generatePrivate(PrivateKeyInfo.getInstance(((PKCS8EncodedKeySpec)keySpec).getEncoded())); } catch (Exception e) { // // in case it's just a RSAPrivateKey object... -- openSSL produces these // try { return new BCRSAPrivateCrtKey( RSAPrivateKey.getInstance(((PKCS8EncodedKeySpec)keySpec).getEncoded())); } catch (Exception ex) { throw new ExtendedInvalidKeySpecException("unable to process key spec: " + e.toString(), e); } } } else if (keySpec instanceof RSAPrivateCrtKeySpec) { return new BCRSAPrivateCrtKey((RSAPrivateCrtKeySpec)keySpec); } else if (keySpec instanceof RSAPrivateKeySpec) { return new BCRSAPrivateKey((RSAPrivateKeySpec)keySpec); } throw new InvalidKeySpecException("Unknown KeySpec type: " + keySpec.getClass().getName()); } protected PublicKey engineGeneratePublic( KeySpec keySpec) throws InvalidKeySpecException { if (keySpec instanceof RSAPublicKeySpec) { return new BCRSAPublicKey((RSAPublicKeySpec)keySpec); } return super.engineGeneratePublic(keySpec); } public PrivateKey generatePrivate(PrivateKeyInfo keyInfo) throws IOException { ASN1ObjectIdentifier algOid = keyInfo.getPrivateKeyAlgorithm().getAlgorithm(); if (RSAUtil.isRsaOid(algOid)) { return new BCRSAPrivateCrtKey(keyInfo); } else { throw new IOException("algorithm identifier " + algOid + " in key not recognised"); } } public PublicKey generatePublic(SubjectPublicKeyInfo keyInfo) throws IOException { ASN1ObjectIdentifier algOid = keyInfo.getAlgorithm().getAlgorithm(); if (RSAUtil.isRsaOid(algOid)) { return new BCRSAPublicKey(keyInfo); } else { throw new IOException("algorithm identifier " + algOid + " in key not recognised"); } } } bouncycastle-1.49.orig/src/org/bouncycastle/jcajce/provider/asymmetric/rsa/PSSSignatureSpi.java0000644000175000017500000002626611731776521032411 0ustar ebourgebourgpackage org.bouncycastle.jcajce.provider.asymmetric.rsa; import java.io.ByteArrayOutputStream; import java.security.AlgorithmParameters; import java.security.InvalidKeyException; import java.security.InvalidParameterException; import java.security.PrivateKey; import java.security.PublicKey; import java.security.SecureRandom; import java.security.SignatureException; import java.security.SignatureSpi; import java.security.interfaces.RSAPrivateKey; import java.security.interfaces.RSAPublicKey; import java.security.spec.AlgorithmParameterSpec; import java.security.spec.MGF1ParameterSpec; import java.security.spec.PSSParameterSpec; import org.bouncycastle.asn1.pkcs.PKCSObjectIdentifiers; import org.bouncycastle.crypto.AsymmetricBlockCipher; import org.bouncycastle.crypto.CryptoException; import org.bouncycastle.crypto.Digest; import org.bouncycastle.crypto.engines.RSABlindedEngine; import org.bouncycastle.crypto.params.ParametersWithRandom; import org.bouncycastle.jcajce.provider.util.DigestFactory; import org.bouncycastle.jce.provider.BouncyCastleProvider; public class PSSSignatureSpi extends SignatureSpi { private AlgorithmParameters engineParams; private PSSParameterSpec paramSpec; private PSSParameterSpec originalSpec; private AsymmetricBlockCipher signer; private Digest contentDigest; private Digest mgfDigest; private int saltLength; private byte trailer; private boolean isRaw; private org.bouncycastle.crypto.signers.PSSSigner pss; private byte getTrailer( int trailerField) { if (trailerField == 1) { return org.bouncycastle.crypto.signers.PSSSigner.TRAILER_IMPLICIT; } throw new IllegalArgumentException("unknown trailer field"); } private void setupContentDigest() { if (isRaw) { this.contentDigest = new NullPssDigest(mgfDigest); } else { this.contentDigest = mgfDigest; } } // care - this constructor is actually used by outside organisations protected PSSSignatureSpi( AsymmetricBlockCipher signer, PSSParameterSpec paramSpecArg) { this(signer, paramSpecArg, false); } // care - this constructor is actually used by outside organisations protected PSSSignatureSpi( AsymmetricBlockCipher signer, PSSParameterSpec baseParamSpec, boolean isRaw) { this.signer = signer; this.originalSpec = baseParamSpec; if (baseParamSpec == null) { this.paramSpec = PSSParameterSpec.DEFAULT; } else { this.paramSpec = baseParamSpec; } this.mgfDigest = DigestFactory.getDigest(paramSpec.getDigestAlgorithm()); this.saltLength = paramSpec.getSaltLength(); this.trailer = getTrailer(paramSpec.getTrailerField()); this.isRaw = isRaw; setupContentDigest(); } protected void engineInitVerify( PublicKey publicKey) throws InvalidKeyException { if (!(publicKey instanceof RSAPublicKey)) { throw new InvalidKeyException("Supplied key is not a RSAPublicKey instance"); } pss = new org.bouncycastle.crypto.signers.PSSSigner(signer, contentDigest, mgfDigest, saltLength, trailer); pss.init(false, RSAUtil.generatePublicKeyParameter((RSAPublicKey)publicKey)); } protected void engineInitSign( PrivateKey privateKey, SecureRandom random) throws InvalidKeyException { if (!(privateKey instanceof RSAPrivateKey)) { throw new InvalidKeyException("Supplied key is not a RSAPrivateKey instance"); } pss = new org.bouncycastle.crypto.signers.PSSSigner(signer, contentDigest, mgfDigest, saltLength, trailer); pss.init(true, new ParametersWithRandom(RSAUtil.generatePrivateKeyParameter((RSAPrivateKey)privateKey), random)); } protected void engineInitSign( PrivateKey privateKey) throws InvalidKeyException { if (!(privateKey instanceof RSAPrivateKey)) { throw new InvalidKeyException("Supplied key is not a RSAPrivateKey instance"); } pss = new org.bouncycastle.crypto.signers.PSSSigner(signer, contentDigest, mgfDigest, saltLength, trailer); pss.init(true, RSAUtil.generatePrivateKeyParameter((RSAPrivateKey)privateKey)); } protected void engineUpdate( byte b) throws SignatureException { pss.update(b); } protected void engineUpdate( byte[] b, int off, int len) throws SignatureException { pss.update(b, off, len); } protected byte[] engineSign() throws SignatureException { try { return pss.generateSignature(); } catch (CryptoException e) { throw new SignatureException(e.getMessage()); } } protected boolean engineVerify( byte[] sigBytes) throws SignatureException { return pss.verifySignature(sigBytes); } protected void engineSetParameter( AlgorithmParameterSpec params) throws InvalidParameterException { if (params instanceof PSSParameterSpec) { PSSParameterSpec newParamSpec = (PSSParameterSpec)params; if (originalSpec != null) { if (!DigestFactory.isSameDigest(originalSpec.getDigestAlgorithm(), newParamSpec.getDigestAlgorithm())) { throw new InvalidParameterException("parameter must be using " + originalSpec.getDigestAlgorithm()); } } if (!newParamSpec.getMGFAlgorithm().equalsIgnoreCase("MGF1") && !newParamSpec.getMGFAlgorithm().equals(PKCSObjectIdentifiers.id_mgf1.getId())) { throw new InvalidParameterException("unknown mask generation function specified"); } if (!(newParamSpec.getMGFParameters() instanceof MGF1ParameterSpec)) { throw new InvalidParameterException("unkown MGF parameters"); } MGF1ParameterSpec mgfParams = (MGF1ParameterSpec)newParamSpec.getMGFParameters(); if (!DigestFactory.isSameDigest(mgfParams.getDigestAlgorithm(), newParamSpec.getDigestAlgorithm())) { throw new InvalidParameterException("digest algorithm for MGF should be the same as for PSS parameters."); } Digest newDigest = DigestFactory.getDigest(mgfParams.getDigestAlgorithm()); if (newDigest == null) { throw new InvalidParameterException("no match on MGF digest algorithm: "+ mgfParams.getDigestAlgorithm()); } this.engineParams = null; this.paramSpec = newParamSpec; this.mgfDigest = newDigest; this.saltLength = paramSpec.getSaltLength(); this.trailer = getTrailer(paramSpec.getTrailerField()); setupContentDigest(); } else { throw new InvalidParameterException("Only PSSParameterSpec supported"); } } protected AlgorithmParameters engineGetParameters() { if (engineParams == null) { if (paramSpec != null) { try { engineParams = AlgorithmParameters.getInstance("PSS", BouncyCastleProvider.PROVIDER_NAME); engineParams.init(paramSpec); } catch (Exception e) { throw new RuntimeException(e.toString()); } } } return engineParams; } /** * @deprecated replaced with */ protected void engineSetParameter( String param, Object value) { throw new UnsupportedOperationException("engineSetParameter unsupported"); } protected Object engineGetParameter( String param) { throw new UnsupportedOperationException("engineGetParameter unsupported"); } static public class nonePSS extends PSSSignatureSpi { public nonePSS() { super(new RSABlindedEngine(), null, true); } } static public class PSSwithRSA extends PSSSignatureSpi { public PSSwithRSA() { super(new RSABlindedEngine(), null); } } static public class SHA1withRSA extends PSSSignatureSpi { public SHA1withRSA() { super(new RSABlindedEngine(), PSSParameterSpec.DEFAULT); } } static public class SHA224withRSA extends PSSSignatureSpi { public SHA224withRSA() { super(new RSABlindedEngine(), new PSSParameterSpec("SHA-224", "MGF1", new MGF1ParameterSpec("SHA-224"), 28, 1)); } } static public class SHA256withRSA extends PSSSignatureSpi { public SHA256withRSA() { super(new RSABlindedEngine(), new PSSParameterSpec("SHA-256", "MGF1", new MGF1ParameterSpec("SHA-256"), 32, 1)); } } static public class SHA384withRSA extends PSSSignatureSpi { public SHA384withRSA() { super(new RSABlindedEngine(), new PSSParameterSpec("SHA-384", "MGF1", new MGF1ParameterSpec("SHA-384"), 48, 1)); } } static public class SHA512withRSA extends PSSSignatureSpi { public SHA512withRSA() { super(new RSABlindedEngine(), new PSSParameterSpec("SHA-512", "MGF1", new MGF1ParameterSpec("SHA-512"), 64, 1)); } } private class NullPssDigest implements Digest { private ByteArrayOutputStream bOut = new ByteArrayOutputStream(); private Digest baseDigest; private boolean oddTime = true; public NullPssDigest(Digest mgfDigest) { this.baseDigest = mgfDigest; } public String getAlgorithmName() { return "NULL"; } public int getDigestSize() { return baseDigest.getDigestSize(); } public void update(byte in) { bOut.write(in); } public void update(byte[] in, int inOff, int len) { bOut.write(in, inOff, len); } public int doFinal(byte[] out, int outOff) { byte[] res = bOut.toByteArray(); if (oddTime) { System.arraycopy(res, 0, out, outOff, res.length); } else { baseDigest.update(res, 0, res.length); baseDigest.doFinal(out, outOff); } reset(); oddTime = !oddTime; return res.length; } public void reset() { bOut.reset(); baseDigest.reset(); } public int getByteLength() { return 0; } } } bouncycastle-1.49.orig/src/org/bouncycastle/jcajce/provider/asymmetric/rsa/CipherSpi.java0000644000175000017500000004177712054773142031273 0ustar ebourgebourgpackage org.bouncycastle.jcajce.provider.asymmetric.rsa; import java.io.ByteArrayOutputStream; import java.security.AlgorithmParameters; import java.security.InvalidAlgorithmParameterException; import java.security.InvalidKeyException; import java.security.InvalidParameterException; import java.security.Key; import java.security.NoSuchAlgorithmException; import java.security.SecureRandom; import java.security.interfaces.RSAPrivateKey; import java.security.interfaces.RSAPublicKey; import java.security.spec.AlgorithmParameterSpec; import java.security.spec.InvalidParameterSpecException; import java.security.spec.MGF1ParameterSpec; import javax.crypto.BadPaddingException; import javax.crypto.Cipher; import javax.crypto.IllegalBlockSizeException; import javax.crypto.NoSuchPaddingException; import javax.crypto.spec.OAEPParameterSpec; import javax.crypto.spec.PSource; import org.bouncycastle.asn1.pkcs.PKCSObjectIdentifiers; import org.bouncycastle.crypto.AsymmetricBlockCipher; import org.bouncycastle.crypto.CipherParameters; import org.bouncycastle.crypto.Digest; import org.bouncycastle.crypto.InvalidCipherTextException; import org.bouncycastle.crypto.encodings.ISO9796d1Encoding; import org.bouncycastle.crypto.encodings.OAEPEncoding; import org.bouncycastle.crypto.encodings.PKCS1Encoding; import org.bouncycastle.crypto.engines.RSABlindedEngine; import org.bouncycastle.crypto.params.ParametersWithRandom; import org.bouncycastle.jcajce.provider.asymmetric.util.BaseCipherSpi; import org.bouncycastle.jcajce.provider.util.DigestFactory; import org.bouncycastle.jce.provider.BouncyCastleProvider; import org.bouncycastle.util.Strings; public class CipherSpi extends BaseCipherSpi { private AsymmetricBlockCipher cipher; private AlgorithmParameterSpec paramSpec; private AlgorithmParameters engineParams; private boolean publicKeyOnly = false; private boolean privateKeyOnly = false; private ByteArrayOutputStream bOut = new ByteArrayOutputStream(); public CipherSpi( AsymmetricBlockCipher engine) { cipher = engine; } public CipherSpi( OAEPParameterSpec pSpec) { try { initFromSpec(pSpec); } catch (NoSuchPaddingException e) { throw new IllegalArgumentException(e.getMessage()); } } public CipherSpi( boolean publicKeyOnly, boolean privateKeyOnly, AsymmetricBlockCipher engine) { this.publicKeyOnly = publicKeyOnly; this.privateKeyOnly = privateKeyOnly; cipher = engine; } private void initFromSpec( OAEPParameterSpec pSpec) throws NoSuchPaddingException { MGF1ParameterSpec mgfParams = (MGF1ParameterSpec)pSpec.getMGFParameters(); Digest digest = DigestFactory.getDigest(mgfParams.getDigestAlgorithm()); if (digest == null) { throw new NoSuchPaddingException("no match on OAEP constructor for digest algorithm: "+ mgfParams.getDigestAlgorithm()); } cipher = new OAEPEncoding(new RSABlindedEngine(), digest, ((PSource.PSpecified)pSpec.getPSource()).getValue()); paramSpec = pSpec; } protected int engineGetBlockSize() { try { return cipher.getInputBlockSize(); } catch (NullPointerException e) { throw new IllegalStateException("RSA Cipher not initialised"); } } protected int engineGetKeySize( Key key) { if (key instanceof RSAPrivateKey) { RSAPrivateKey k = (RSAPrivateKey)key; return k.getModulus().bitLength(); } else if (key instanceof RSAPublicKey) { RSAPublicKey k = (RSAPublicKey)key; return k.getModulus().bitLength(); } throw new IllegalArgumentException("not an RSA key!"); } protected int engineGetOutputSize( int inputLen) { try { return cipher.getOutputBlockSize(); } catch (NullPointerException e) { throw new IllegalStateException("RSA Cipher not initialised"); } } protected AlgorithmParameters engineGetParameters() { if (engineParams == null) { if (paramSpec != null) { try { engineParams = AlgorithmParameters.getInstance("OAEP", BouncyCastleProvider.PROVIDER_NAME); engineParams.init(paramSpec); } catch (Exception e) { throw new RuntimeException(e.toString()); } } } return engineParams; } protected void engineSetMode( String mode) throws NoSuchAlgorithmException { String md = Strings.toUpperCase(mode); if (md.equals("NONE") || md.equals("ECB")) { return; } if (md.equals("1")) { privateKeyOnly = true; publicKeyOnly = false; return; } else if (md.equals("2")) { privateKeyOnly = false; publicKeyOnly = true; return; } throw new NoSuchAlgorithmException("can't support mode " + mode); } protected void engineSetPadding( String padding) throws NoSuchPaddingException { String pad = Strings.toUpperCase(padding); if (pad.equals("NOPADDING")) { cipher = new RSABlindedEngine(); } else if (pad.equals("PKCS1PADDING")) { cipher = new PKCS1Encoding(new RSABlindedEngine()); } else if (pad.equals("ISO9796-1PADDING")) { cipher = new ISO9796d1Encoding(new RSABlindedEngine()); } else if (pad.equals("OAEPWITHMD5ANDMGF1PADDING")) { initFromSpec(new OAEPParameterSpec("MD5", "MGF1", new MGF1ParameterSpec("MD5"), PSource.PSpecified.DEFAULT)); } else if (pad.equals("OAEPPADDING")) { initFromSpec(OAEPParameterSpec.DEFAULT); } else if (pad.equals("OAEPWITHSHA1ANDMGF1PADDING") || pad.equals("OAEPWITHSHA-1ANDMGF1PADDING")) { initFromSpec(OAEPParameterSpec.DEFAULT); } else if (pad.equals("OAEPWITHSHA224ANDMGF1PADDING") || pad.equals("OAEPWITHSHA-224ANDMGF1PADDING")) { initFromSpec(new OAEPParameterSpec("SHA-224", "MGF1", new MGF1ParameterSpec("SHA-224"), PSource.PSpecified.DEFAULT)); } else if (pad.equals("OAEPWITHSHA256ANDMGF1PADDING") || pad.equals("OAEPWITHSHA-256ANDMGF1PADDING")) { initFromSpec(new OAEPParameterSpec("SHA-256", "MGF1", MGF1ParameterSpec.SHA256, PSource.PSpecified.DEFAULT)); } else if (pad.equals("OAEPWITHSHA384ANDMGF1PADDING") || pad.equals("OAEPWITHSHA-384ANDMGF1PADDING")) { initFromSpec(new OAEPParameterSpec("SHA-384", "MGF1", MGF1ParameterSpec.SHA384, PSource.PSpecified.DEFAULT)); } else if (pad.equals("OAEPWITHSHA512ANDMGF1PADDING") || pad.equals("OAEPWITHSHA-512ANDMGF1PADDING")) { initFromSpec(new OAEPParameterSpec("SHA-512", "MGF1", MGF1ParameterSpec.SHA512, PSource.PSpecified.DEFAULT)); } else { throw new NoSuchPaddingException(padding + " unavailable with RSA."); } } protected void engineInit( int opmode, Key key, AlgorithmParameterSpec params, SecureRandom random) throws InvalidKeyException, InvalidAlgorithmParameterException { CipherParameters param; if (params == null || params instanceof OAEPParameterSpec) { if (key instanceof RSAPublicKey) { if (privateKeyOnly && opmode == Cipher.ENCRYPT_MODE) { throw new InvalidKeyException( "mode 1 requires RSAPrivateKey"); } param = RSAUtil.generatePublicKeyParameter((RSAPublicKey)key); } else if (key instanceof RSAPrivateKey) { if (publicKeyOnly && opmode == Cipher.ENCRYPT_MODE) { throw new InvalidKeyException( "mode 2 requires RSAPublicKey"); } param = RSAUtil.generatePrivateKeyParameter((RSAPrivateKey)key); } else { throw new InvalidKeyException("unknown key type passed to RSA"); } if (params != null) { OAEPParameterSpec spec = (OAEPParameterSpec)params; paramSpec = params; if (!spec.getMGFAlgorithm().equalsIgnoreCase("MGF1") && !spec.getMGFAlgorithm().equals(PKCSObjectIdentifiers.id_mgf1.getId())) { throw new InvalidAlgorithmParameterException("unknown mask generation function specified"); } if (!(spec.getMGFParameters() instanceof MGF1ParameterSpec)) { throw new InvalidAlgorithmParameterException("unkown MGF parameters"); } Digest digest = DigestFactory.getDigest(spec.getDigestAlgorithm()); if (digest == null) { throw new InvalidAlgorithmParameterException("no match on digest algorithm: "+ spec.getDigestAlgorithm()); } MGF1ParameterSpec mgfParams = (MGF1ParameterSpec)spec.getMGFParameters(); Digest mgfDigest = DigestFactory.getDigest(mgfParams.getDigestAlgorithm()); if (mgfDigest == null) { throw new InvalidAlgorithmParameterException("no match on MGF digest algorithm: "+ mgfParams.getDigestAlgorithm()); } cipher = new OAEPEncoding(new RSABlindedEngine(), digest, mgfDigest, ((PSource.PSpecified)spec.getPSource()).getValue()); } } else { throw new IllegalArgumentException("unknown parameter type."); } if (!(cipher instanceof RSABlindedEngine)) { if (random != null) { param = new ParametersWithRandom(param, random); } else { param = new ParametersWithRandom(param, new SecureRandom()); } } bOut.reset(); switch (opmode) { case Cipher.ENCRYPT_MODE: case Cipher.WRAP_MODE: cipher.init(true, param); break; case Cipher.DECRYPT_MODE: case Cipher.UNWRAP_MODE: cipher.init(false, param); break; default: throw new InvalidParameterException("unknown opmode " + opmode + " passed to RSA"); } } protected void engineInit( int opmode, Key key, AlgorithmParameters params, SecureRandom random) throws InvalidKeyException, InvalidAlgorithmParameterException { AlgorithmParameterSpec paramSpec = null; if (params != null) { try { paramSpec = params.getParameterSpec(OAEPParameterSpec.class); } catch (InvalidParameterSpecException e) { throw new InvalidAlgorithmParameterException("cannot recognise parameters: " + e.toString(), e); } } engineParams = params; engineInit(opmode, key, paramSpec, random); } protected void engineInit( int opmode, Key key, SecureRandom random) throws InvalidKeyException { try { engineInit(opmode, key, (AlgorithmParameterSpec)null, random); } catch (InvalidAlgorithmParameterException e) { // this shouldn't happen throw new InvalidKeyException("Eeeek! " + e.toString(), e); } } protected byte[] engineUpdate( byte[] input, int inputOffset, int inputLen) { bOut.write(input, inputOffset, inputLen); if (cipher instanceof RSABlindedEngine) { if (bOut.size() > cipher.getInputBlockSize() + 1) { throw new ArrayIndexOutOfBoundsException("too much data for RSA block"); } } else { if (bOut.size() > cipher.getInputBlockSize()) { throw new ArrayIndexOutOfBoundsException("too much data for RSA block"); } } return null; } protected int engineUpdate( byte[] input, int inputOffset, int inputLen, byte[] output, int outputOffset) { bOut.write(input, inputOffset, inputLen); if (cipher instanceof RSABlindedEngine) { if (bOut.size() > cipher.getInputBlockSize() + 1) { throw new ArrayIndexOutOfBoundsException("too much data for RSA block"); } } else { if (bOut.size() > cipher.getInputBlockSize()) { throw new ArrayIndexOutOfBoundsException("too much data for RSA block"); } } return 0; } protected byte[] engineDoFinal( byte[] input, int inputOffset, int inputLen) throws IllegalBlockSizeException, BadPaddingException { if (input != null) { bOut.write(input, inputOffset, inputLen); } if (cipher instanceof RSABlindedEngine) { if (bOut.size() > cipher.getInputBlockSize() + 1) { throw new ArrayIndexOutOfBoundsException("too much data for RSA block"); } } else { if (bOut.size() > cipher.getInputBlockSize()) { throw new ArrayIndexOutOfBoundsException("too much data for RSA block"); } } try { byte[] bytes = bOut.toByteArray(); bOut.reset(); return cipher.processBlock(bytes, 0, bytes.length); } catch (InvalidCipherTextException e) { throw new BadPaddingException(e.getMessage()); } } protected int engineDoFinal( byte[] input, int inputOffset, int inputLen, byte[] output, int outputOffset) throws IllegalBlockSizeException, BadPaddingException { if (input != null) { bOut.write(input, inputOffset, inputLen); } if (cipher instanceof RSABlindedEngine) { if (bOut.size() > cipher.getInputBlockSize() + 1) { throw new ArrayIndexOutOfBoundsException("too much data for RSA block"); } } else { if (bOut.size() > cipher.getInputBlockSize()) { throw new ArrayIndexOutOfBoundsException("too much data for RSA block"); } } byte[] out; try { byte[] bytes = bOut.toByteArray(); out = cipher.processBlock(bytes, 0, bytes.length); } catch (InvalidCipherTextException e) { throw new BadPaddingException(e.getMessage()); } finally { bOut.reset(); } for (int i = 0; i != out.length; i++) { output[outputOffset + i] = out[i]; } return out.length; } /** * classes that inherit from us. */ static public class NoPadding extends CipherSpi { public NoPadding() { super(new RSABlindedEngine()); } } static public class PKCS1v1_5Padding extends CipherSpi { public PKCS1v1_5Padding() { super(new PKCS1Encoding(new RSABlindedEngine())); } } static public class PKCS1v1_5Padding_PrivateOnly extends CipherSpi { public PKCS1v1_5Padding_PrivateOnly() { super(false, true, new PKCS1Encoding(new RSABlindedEngine())); } } static public class PKCS1v1_5Padding_PublicOnly extends CipherSpi { public PKCS1v1_5Padding_PublicOnly() { super(true, false, new PKCS1Encoding(new RSABlindedEngine())); } } static public class OAEPPadding extends CipherSpi { public OAEPPadding() { super(OAEPParameterSpec.DEFAULT); } } static public class ISO9796d1Padding extends CipherSpi { public ISO9796d1Padding() { super(new ISO9796d1Encoding(new RSABlindedEngine())); } } } bouncycastle-1.49.orig/src/org/bouncycastle/jcajce/provider/asymmetric/rsa/KeyPairGeneratorSpi.java0000644000175000017500000000463411625630011033251 0ustar ebourgebourgpackage org.bouncycastle.jcajce.provider.asymmetric.rsa; import java.math.BigInteger; import java.security.InvalidAlgorithmParameterException; import java.security.KeyPair; import java.security.SecureRandom; import java.security.spec.AlgorithmParameterSpec; import java.security.spec.RSAKeyGenParameterSpec; import org.bouncycastle.crypto.AsymmetricCipherKeyPair; import org.bouncycastle.crypto.generators.RSAKeyPairGenerator; import org.bouncycastle.crypto.params.RSAKeyGenerationParameters; import org.bouncycastle.crypto.params.RSAKeyParameters; import org.bouncycastle.crypto.params.RSAPrivateCrtKeyParameters; public class KeyPairGeneratorSpi extends java.security.KeyPairGenerator { public KeyPairGeneratorSpi( String algorithmName) { super(algorithmName); } final static BigInteger defaultPublicExponent = BigInteger.valueOf(0x10001); final static int defaultTests = 12; RSAKeyGenerationParameters param; RSAKeyPairGenerator engine; public KeyPairGeneratorSpi() { super("RSA"); engine = new RSAKeyPairGenerator(); param = new RSAKeyGenerationParameters(defaultPublicExponent, new SecureRandom(), 2048, defaultTests); engine.init(param); } public void initialize( int strength, SecureRandom random) { param = new RSAKeyGenerationParameters(defaultPublicExponent, random, strength, defaultTests); engine.init(param); } public void initialize( AlgorithmParameterSpec params, SecureRandom random) throws InvalidAlgorithmParameterException { if (!(params instanceof RSAKeyGenParameterSpec)) { throw new InvalidAlgorithmParameterException("parameter object not a RSAKeyGenParameterSpec"); } RSAKeyGenParameterSpec rsaParams = (RSAKeyGenParameterSpec)params; param = new RSAKeyGenerationParameters( rsaParams.getPublicExponent(), random, rsaParams.getKeysize(), defaultTests); engine.init(param); } public KeyPair generateKeyPair() { AsymmetricCipherKeyPair pair = engine.generateKeyPair(); RSAKeyParameters pub = (RSAKeyParameters)pair.getPublic(); RSAPrivateCrtKeyParameters priv = (RSAPrivateCrtKeyParameters)pair.getPrivate(); return new KeyPair(new BCRSAPublicKey(pub), new BCRSAPrivateCrtKey(priv)); } } bouncycastle-1.49.orig/src/org/bouncycastle/jcajce/provider/asymmetric/rsa/BCRSAPublicKey.java0000644000175000017500000000642712103437526032036 0ustar ebourgebourgpackage org.bouncycastle.jcajce.provider.asymmetric.rsa; import java.io.IOException; import java.math.BigInteger; import java.security.interfaces.RSAPublicKey; import java.security.spec.RSAPublicKeySpec; import org.bouncycastle.asn1.DERNull; import org.bouncycastle.asn1.pkcs.PKCSObjectIdentifiers; import org.bouncycastle.asn1.x509.AlgorithmIdentifier; import org.bouncycastle.asn1.x509.SubjectPublicKeyInfo; import org.bouncycastle.crypto.params.RSAKeyParameters; import org.bouncycastle.jcajce.provider.asymmetric.util.KeyUtil; public class BCRSAPublicKey implements RSAPublicKey { static final long serialVersionUID = 2675817738516720772L; private BigInteger modulus; private BigInteger publicExponent; BCRSAPublicKey( RSAKeyParameters key) { this.modulus = key.getModulus(); this.publicExponent = key.getExponent(); } BCRSAPublicKey( RSAPublicKeySpec spec) { this.modulus = spec.getModulus(); this.publicExponent = spec.getPublicExponent(); } BCRSAPublicKey( RSAPublicKey key) { this.modulus = key.getModulus(); this.publicExponent = key.getPublicExponent(); } BCRSAPublicKey( SubjectPublicKeyInfo info) { try { org.bouncycastle.asn1.pkcs.RSAPublicKey pubKey = org.bouncycastle.asn1.pkcs.RSAPublicKey.getInstance(info.parsePublicKey()); this.modulus = pubKey.getModulus(); this.publicExponent = pubKey.getPublicExponent(); } catch (IOException e) { throw new IllegalArgumentException("invalid info structure in RSA public key"); } } /** * return the modulus. * * @return the modulus. */ public BigInteger getModulus() { return modulus; } /** * return the public exponent. * * @return the public exponent. */ public BigInteger getPublicExponent() { return publicExponent; } public String getAlgorithm() { return "RSA"; } public String getFormat() { return "X.509"; } public byte[] getEncoded() { return KeyUtil.getEncodedSubjectPublicKeyInfo(new AlgorithmIdentifier(PKCSObjectIdentifiers.rsaEncryption, DERNull.INSTANCE), new org.bouncycastle.asn1.pkcs.RSAPublicKey(getModulus(), getPublicExponent())); } public int hashCode() { return this.getModulus().hashCode() ^ this.getPublicExponent().hashCode(); } public boolean equals(Object o) { if (o == this) { return true; } if (!(o instanceof RSAPublicKey)) { return false; } RSAPublicKey key = (RSAPublicKey)o; return getModulus().equals(key.getModulus()) && getPublicExponent().equals(key.getPublicExponent()); } public String toString() { StringBuffer buf = new StringBuffer(); String nl = System.getProperty("line.separator"); buf.append("RSA Public Key").append(nl); buf.append(" modulus: ").append(this.getModulus().toString(16)).append(nl); buf.append(" public exponent: ").append(this.getPublicExponent().toString(16)).append(nl); return buf.toString(); } } bouncycastle-1.49.orig/src/org/bouncycastle/jcajce/provider/asymmetric/rsa/RSAUtil.java0000644000175000017500000000365011624574042030654 0ustar ebourgebourgpackage org.bouncycastle.jcajce.provider.asymmetric.rsa; import java.security.interfaces.RSAPrivateCrtKey; import java.security.interfaces.RSAPrivateKey; import java.security.interfaces.RSAPublicKey; import org.bouncycastle.asn1.ASN1ObjectIdentifier; import org.bouncycastle.asn1.pkcs.PKCSObjectIdentifiers; import org.bouncycastle.asn1.x509.X509ObjectIdentifiers; import org.bouncycastle.crypto.params.RSAKeyParameters; import org.bouncycastle.crypto.params.RSAPrivateCrtKeyParameters; /** * utility class for converting java.security RSA objects into their * org.bouncycastle.crypto counterparts. */ public class RSAUtil { public static final ASN1ObjectIdentifier[] rsaOids = { PKCSObjectIdentifiers.rsaEncryption, X509ObjectIdentifiers.id_ea_rsa, PKCSObjectIdentifiers.id_RSAES_OAEP, PKCSObjectIdentifiers.id_RSASSA_PSS }; public static boolean isRsaOid( ASN1ObjectIdentifier algOid) { for (int i = 0; i != rsaOids.length; i++) { if (algOid.equals(rsaOids[i])) { return true; } } return false; } static RSAKeyParameters generatePublicKeyParameter( RSAPublicKey key) { return new RSAKeyParameters(false, key.getModulus(), key.getPublicExponent()); } static RSAKeyParameters generatePrivateKeyParameter( RSAPrivateKey key) { if (key instanceof RSAPrivateCrtKey) { RSAPrivateCrtKey k = (RSAPrivateCrtKey)key; return new RSAPrivateCrtKeyParameters(k.getModulus(), k.getPublicExponent(), k.getPrivateExponent(), k.getPrimeP(), k.getPrimeQ(), k.getPrimeExponentP(), k.getPrimeExponentQ(), k.getCrtCoefficient()); } else { RSAPrivateKey k = key; return new RSAKeyParameters(true, k.getModulus(), k.getPrivateExponent()); } } } bouncycastle-1.49.orig/src/org/bouncycastle/jcajce/provider/asymmetric/gost/0000755000175000017500000000000012152033551026701 5ustar ebourgebourgbouncycastle-1.49.orig/src/org/bouncycastle/jcajce/provider/asymmetric/gost/BCGOST3410PublicKey.java0000644000175000017500000001623711737274347032700 0ustar ebourgebourgpackage org.bouncycastle.jcajce.provider.asymmetric.gost; import java.io.IOException; import java.io.ObjectInputStream; import java.io.ObjectOutputStream; import java.math.BigInteger; import org.bouncycastle.asn1.ASN1ObjectIdentifier; import org.bouncycastle.asn1.ASN1Sequence; import org.bouncycastle.asn1.DEROctetString; import org.bouncycastle.asn1.cryptopro.CryptoProObjectIdentifiers; import org.bouncycastle.asn1.cryptopro.GOST3410PublicKeyAlgParameters; import org.bouncycastle.asn1.x509.AlgorithmIdentifier; import org.bouncycastle.asn1.x509.SubjectPublicKeyInfo; import org.bouncycastle.crypto.params.GOST3410PublicKeyParameters; import org.bouncycastle.jcajce.provider.asymmetric.util.KeyUtil; import org.bouncycastle.jce.interfaces.GOST3410Params; import org.bouncycastle.jce.interfaces.GOST3410PublicKey; import org.bouncycastle.jce.spec.GOST3410ParameterSpec; import org.bouncycastle.jce.spec.GOST3410PublicKeyParameterSetSpec; import org.bouncycastle.jce.spec.GOST3410PublicKeySpec; public class BCGOST3410PublicKey implements GOST3410PublicKey { static final long serialVersionUID = -6251023343619275990L; private BigInteger y; private transient GOST3410Params gost3410Spec; BCGOST3410PublicKey( GOST3410PublicKeySpec spec) { this.y = spec.getY(); this.gost3410Spec = new GOST3410ParameterSpec(new GOST3410PublicKeyParameterSetSpec(spec.getP(), spec.getQ(), spec.getA())); } BCGOST3410PublicKey( GOST3410PublicKey key) { this.y = key.getY(); this.gost3410Spec = key.getParameters(); } BCGOST3410PublicKey( GOST3410PublicKeyParameters params, GOST3410ParameterSpec spec) { this.y = params.getY(); this.gost3410Spec = spec; } BCGOST3410PublicKey( BigInteger y, GOST3410ParameterSpec gost3410Spec) { this.y = y; this.gost3410Spec = gost3410Spec; } BCGOST3410PublicKey( SubjectPublicKeyInfo info) { GOST3410PublicKeyAlgParameters params = new GOST3410PublicKeyAlgParameters((ASN1Sequence)info.getAlgorithmId().getParameters()); DEROctetString derY; try { derY = (DEROctetString)info.parsePublicKey(); byte[] keyEnc = derY.getOctets(); byte[] keyBytes = new byte[keyEnc.length]; for (int i = 0; i != keyEnc.length; i++) { keyBytes[i] = keyEnc[keyEnc.length - 1 - i]; // was little endian } this.y = new BigInteger(1, keyBytes); } catch (IOException e) { throw new IllegalArgumentException("invalid info structure in GOST3410 public key"); } this.gost3410Spec = GOST3410ParameterSpec.fromPublicKeyAlg(params); } public String getAlgorithm() { return "GOST3410"; } public String getFormat() { return "X.509"; } public byte[] getEncoded() { SubjectPublicKeyInfo info; byte[] keyEnc = this.getY().toByteArray(); byte[] keyBytes; if (keyEnc[0] == 0) { keyBytes = new byte[keyEnc.length - 1]; } else { keyBytes = new byte[keyEnc.length]; } for (int i = 0; i != keyBytes.length; i++) { keyBytes[i] = keyEnc[keyEnc.length - 1 - i]; // must be little endian } try { if (gost3410Spec instanceof GOST3410ParameterSpec) { if (gost3410Spec.getEncryptionParamSetOID() != null) { info = new SubjectPublicKeyInfo(new AlgorithmIdentifier(CryptoProObjectIdentifiers.gostR3410_94, new GOST3410PublicKeyAlgParameters(new ASN1ObjectIdentifier(gost3410Spec.getPublicKeyParamSetOID()), new ASN1ObjectIdentifier(gost3410Spec.getDigestParamSetOID()), new ASN1ObjectIdentifier(gost3410Spec.getEncryptionParamSetOID()))), new DEROctetString(keyBytes)); } else { info = new SubjectPublicKeyInfo(new AlgorithmIdentifier(CryptoProObjectIdentifiers.gostR3410_94, new GOST3410PublicKeyAlgParameters(new ASN1ObjectIdentifier(gost3410Spec.getPublicKeyParamSetOID()), new ASN1ObjectIdentifier(gost3410Spec.getDigestParamSetOID()))), new DEROctetString(keyBytes)); } } else { info = new SubjectPublicKeyInfo(new AlgorithmIdentifier(CryptoProObjectIdentifiers.gostR3410_94), new DEROctetString(keyBytes)); } return KeyUtil.getEncodedSubjectPublicKeyInfo(info); } catch (IOException e) { return null; } } public GOST3410Params getParameters() { return gost3410Spec; } public BigInteger getY() { return y; } public String toString() { StringBuffer buf = new StringBuffer(); String nl = System.getProperty("line.separator"); buf.append("GOST3410 Public Key").append(nl); buf.append(" y: ").append(this.getY().toString(16)).append(nl); return buf.toString(); } public boolean equals(Object o) { if (o instanceof BCGOST3410PublicKey) { BCGOST3410PublicKey other = (BCGOST3410PublicKey)o; return this.y.equals(other.y) && this.gost3410Spec.equals(other.gost3410Spec); } return false; } public int hashCode() { return y.hashCode() ^ gost3410Spec.hashCode(); } private void readObject( ObjectInputStream in) throws IOException, ClassNotFoundException { in.defaultReadObject(); String publicKeyParamSetOID = (String)in.readObject(); if (publicKeyParamSetOID != null) { this.gost3410Spec = new GOST3410ParameterSpec(publicKeyParamSetOID, (String)in.readObject(), (String)in.readObject()); } else { this.gost3410Spec = new GOST3410ParameterSpec(new GOST3410PublicKeyParameterSetSpec((BigInteger)in.readObject(), (BigInteger)in.readObject(), (BigInteger)in.readObject())); in.readObject(); in.readObject(); } } private void writeObject( ObjectOutputStream out) throws IOException { out.defaultWriteObject(); if (gost3410Spec.getPublicKeyParamSetOID() != null) { out.writeObject(gost3410Spec.getPublicKeyParamSetOID()); out.writeObject(gost3410Spec.getDigestParamSetOID()); out.writeObject(gost3410Spec.getEncryptionParamSetOID()); } else { out.writeObject(null); out.writeObject(gost3410Spec.getPublicKeyParameters().getP()); out.writeObject(gost3410Spec.getPublicKeyParameters().getQ()); out.writeObject(gost3410Spec.getPublicKeyParameters().getA()); out.writeObject(gost3410Spec.getDigestParamSetOID()); out.writeObject(gost3410Spec.getEncryptionParamSetOID()); } } } bouncycastle-1.49.orig/src/org/bouncycastle/jcajce/provider/asymmetric/gost/SignatureSpi.java0000644000175000017500000001437512110037231032164 0ustar ebourgebourgpackage org.bouncycastle.jcajce.provider.asymmetric.gost; import java.math.BigInteger; import java.security.InvalidKeyException; import java.security.PrivateKey; import java.security.PublicKey; import java.security.SecureRandom; import java.security.SignatureException; import java.security.spec.AlgorithmParameterSpec; import org.bouncycastle.asn1.pkcs.PKCSObjectIdentifiers; import org.bouncycastle.asn1.x509.SubjectPublicKeyInfo; import org.bouncycastle.asn1.x509.X509ObjectIdentifiers; import org.bouncycastle.crypto.CipherParameters; import org.bouncycastle.crypto.DSA; import org.bouncycastle.crypto.Digest; import org.bouncycastle.crypto.digests.GOST3411Digest; import org.bouncycastle.crypto.params.ParametersWithRandom; import org.bouncycastle.crypto.signers.GOST3410Signer; import org.bouncycastle.jcajce.provider.asymmetric.util.ECUtil; import org.bouncycastle.jce.interfaces.ECKey; import org.bouncycastle.jce.interfaces.ECPublicKey; import org.bouncycastle.jce.interfaces.GOST3410Key; import org.bouncycastle.jce.provider.BouncyCastleProvider; import org.bouncycastle.jcajce.provider.asymmetric.util.GOST3410Util; public class SignatureSpi extends java.security.SignatureSpi implements PKCSObjectIdentifiers, X509ObjectIdentifiers { private Digest digest; private DSA signer; private SecureRandom random; public SignatureSpi() { this.digest = new GOST3411Digest(); this.signer = new GOST3410Signer(); } protected void engineInitVerify( PublicKey publicKey) throws InvalidKeyException { CipherParameters param; if (publicKey instanceof ECPublicKey) { param = ECUtil.generatePublicKeyParameter(publicKey); } else if (publicKey instanceof GOST3410Key) { param = GOST3410Util.generatePublicKeyParameter(publicKey); } else { try { byte[] bytes = publicKey.getEncoded(); publicKey = BouncyCastleProvider.getPublicKey(SubjectPublicKeyInfo.getInstance(bytes)); if (publicKey instanceof ECPublicKey) { param = ECUtil.generatePublicKeyParameter(publicKey); } else { throw new InvalidKeyException("can't recognise key type in DSA based signer"); } } catch (Exception e) { throw new InvalidKeyException("can't recognise key type in DSA based signer"); } } digest.reset(); signer.init(false, param); } protected void engineInitSign( PrivateKey privateKey, SecureRandom random) throws InvalidKeyException { this.random = random; engineInitSign(privateKey); } protected void engineInitSign( PrivateKey privateKey) throws InvalidKeyException { CipherParameters param; if (privateKey instanceof ECKey) { param = ECUtil.generatePrivateKeyParameter(privateKey); } else { param = GOST3410Util.generatePrivateKeyParameter(privateKey); } digest.reset(); if (random != null) { signer.init(true, new ParametersWithRandom(param, random)); } else { signer.init(true, param); } } protected void engineUpdate( byte b) throws SignatureException { digest.update(b); } protected void engineUpdate( byte[] b, int off, int len) throws SignatureException { digest.update(b, off, len); } protected byte[] engineSign() throws SignatureException { byte[] hash = new byte[digest.getDigestSize()]; digest.doFinal(hash, 0); try { byte[] sigBytes = new byte[64]; BigInteger[] sig = signer.generateSignature(hash); byte[] r = sig[0].toByteArray(); byte[] s = sig[1].toByteArray(); if (s[0] != 0) { System.arraycopy(s, 0, sigBytes, 32 - s.length, s.length); } else { System.arraycopy(s, 1, sigBytes, 32 - (s.length - 1), s.length - 1); } if (r[0] != 0) { System.arraycopy(r, 0, sigBytes, 64 - r.length, r.length); } else { System.arraycopy(r, 1, sigBytes, 64 - (r.length - 1), r.length - 1); } return sigBytes; } catch (Exception e) { throw new SignatureException(e.toString()); } } protected boolean engineVerify( byte[] sigBytes) throws SignatureException { byte[] hash = new byte[digest.getDigestSize()]; digest.doFinal(hash, 0); BigInteger[] sig; try { byte[] r = new byte[32]; byte[] s = new byte[32]; System.arraycopy(sigBytes, 0, s, 0, 32); System.arraycopy(sigBytes, 32, r, 0, 32); sig = new BigInteger[2]; sig[0] = new BigInteger(1, r); sig[1] = new BigInteger(1, s); } catch (Exception e) { throw new SignatureException("error decoding signature bytes."); } return signer.verifySignature(hash, sig[0], sig[1]); } protected void engineSetParameter( AlgorithmParameterSpec params) { throw new UnsupportedOperationException("engineSetParameter unsupported"); } /** * @deprecated replaced with */ protected void engineSetParameter( String param, Object value) { throw new UnsupportedOperationException("engineSetParameter unsupported"); } /** * @deprecated */ protected Object engineGetParameter( String param) { throw new UnsupportedOperationException("engineSetParameter unsupported"); } } ././@LongLink0000000000000000000000000000016000000000000011562 Lustar rootrootbouncycastle-1.49.orig/src/org/bouncycastle/jcajce/provider/asymmetric/gost/AlgorithmParameterGeneratorSpi.javabouncycastle-1.49.orig/src/org/bouncycastle/jcajce/provider/asymmetric/gost/AlgorithmParameterGenera0000644000175000017500000000373211634271714033553 0ustar ebourgebourgpackage org.bouncycastle.jcajce.provider.asymmetric.gost; import java.security.AlgorithmParameters; import java.security.InvalidAlgorithmParameterException; import java.security.SecureRandom; import java.security.spec.AlgorithmParameterSpec; import org.bouncycastle.crypto.generators.GOST3410ParametersGenerator; import org.bouncycastle.crypto.params.GOST3410Parameters; import org.bouncycastle.jce.provider.BouncyCastleProvider; import org.bouncycastle.jce.spec.GOST3410ParameterSpec; import org.bouncycastle.jce.spec.GOST3410PublicKeyParameterSetSpec; public abstract class AlgorithmParameterGeneratorSpi extends java.security.AlgorithmParameterGeneratorSpi { protected SecureRandom random; protected int strength = 1024; protected void engineInit( int strength, SecureRandom random) { this.strength = strength; this.random = random; } protected void engineInit( AlgorithmParameterSpec genParamSpec, SecureRandom random) throws InvalidAlgorithmParameterException { throw new InvalidAlgorithmParameterException("No supported AlgorithmParameterSpec for GOST3410 parameter generation."); } protected AlgorithmParameters engineGenerateParameters() { GOST3410ParametersGenerator pGen = new GOST3410ParametersGenerator(); if (random != null) { pGen.init(strength, 2, random); } else { pGen.init(strength, 2, new SecureRandom()); } GOST3410Parameters p = pGen.generateParameters(); AlgorithmParameters params; try { params = AlgorithmParameters.getInstance("GOST3410", BouncyCastleProvider.PROVIDER_NAME); params.init(new GOST3410ParameterSpec(new GOST3410PublicKeyParameterSetSpec(p.getP(), p.getQ(), p.getA()))); } catch (Exception e) { throw new RuntimeException(e.getMessage()); } return params; } } ././@LongLink0000000000000000000000000000015000000000000011561 Lustar rootrootbouncycastle-1.49.orig/src/org/bouncycastle/jcajce/provider/asymmetric/gost/AlgorithmParametersSpi.javabouncycastle-1.49.orig/src/org/bouncycastle/jcajce/provider/asymmetric/gost/AlgorithmParametersSpi.j0000644000175000017500000001001011634270640033500 0ustar ebourgebourgpackage org.bouncycastle.jcajce.provider.asymmetric.gost; import java.io.IOException; import java.security.spec.AlgorithmParameterSpec; import java.security.spec.InvalidParameterSpecException; import org.bouncycastle.asn1.ASN1Encoding; import org.bouncycastle.asn1.ASN1ObjectIdentifier; import org.bouncycastle.asn1.ASN1Primitive; import org.bouncycastle.asn1.ASN1Sequence; import org.bouncycastle.asn1.cryptopro.GOST3410PublicKeyAlgParameters; import org.bouncycastle.jce.spec.GOST3410ParameterSpec; import org.bouncycastle.jce.spec.GOST3410PublicKeyParameterSetSpec; public class AlgorithmParametersSpi extends java.security.AlgorithmParametersSpi { GOST3410ParameterSpec currentSpec; protected boolean isASN1FormatString(String format) { return format == null || format.equals("ASN.1"); } protected AlgorithmParameterSpec engineGetParameterSpec( Class paramSpec) throws InvalidParameterSpecException { if (paramSpec == null) { throw new NullPointerException("argument to getParameterSpec must not be null"); } return localEngineGetParameterSpec(paramSpec); } /** * Return the X.509 ASN.1 structure GOST3410Parameter. *

    *

         *  GOST3410Parameter ::= SEQUENCE {
         *                   prime INTEGER, -- p
         *                   subprime INTEGER, -- q
         *                   base INTEGER, -- a}
         * 
    */ protected byte[] engineGetEncoded() { GOST3410PublicKeyAlgParameters gost3410P = new GOST3410PublicKeyAlgParameters(new ASN1ObjectIdentifier(currentSpec.getPublicKeyParamSetOID()), new ASN1ObjectIdentifier(currentSpec.getDigestParamSetOID()), new ASN1ObjectIdentifier(currentSpec.getEncryptionParamSetOID())); try { return gost3410P.getEncoded(ASN1Encoding.DER); } catch (IOException e) { throw new RuntimeException("Error encoding GOST3410Parameters"); } } protected byte[] engineGetEncoded( String format) { if (isASN1FormatString(format) || format.equalsIgnoreCase("X.509")) { return engineGetEncoded(); } return null; } protected AlgorithmParameterSpec localEngineGetParameterSpec( Class paramSpec) throws InvalidParameterSpecException { if (paramSpec == GOST3410PublicKeyParameterSetSpec.class) { return currentSpec; } throw new InvalidParameterSpecException("unknown parameter spec passed to GOST3410 parameters object."); } protected void engineInit( AlgorithmParameterSpec paramSpec) throws InvalidParameterSpecException { if (!(paramSpec instanceof GOST3410ParameterSpec)) { throw new InvalidParameterSpecException("GOST3410ParameterSpec required to initialise a GOST3410 algorithm parameters object"); } this.currentSpec = (GOST3410ParameterSpec)paramSpec; } protected void engineInit( byte[] params) throws IOException { try { ASN1Sequence seq = (ASN1Sequence)ASN1Primitive.fromByteArray(params); this.currentSpec = GOST3410ParameterSpec.fromPublicKeyAlg( new GOST3410PublicKeyAlgParameters(seq)); } catch (ClassCastException e) { throw new IOException("Not a valid GOST3410 Parameter encoding."); } catch (ArrayIndexOutOfBoundsException e) { throw new IOException("Not a valid GOST3410 Parameter encoding."); } } protected void engineInit( byte[] params, String format) throws IOException { if (isASN1FormatString(format) || format.equalsIgnoreCase("X.509")) { engineInit(params); } else { throw new IOException("Unknown parameter format " + format); } } protected String engineToString() { return "GOST3410 Parameters"; } } bouncycastle-1.49.orig/src/org/bouncycastle/jcajce/provider/asymmetric/gost/KeyFactorySpi.java0000644000175000017500000000764311631272022032311 0ustar ebourgebourgpackage org.bouncycastle.jcajce.provider.asymmetric.gost; import java.io.IOException; import java.security.InvalidKeyException; import java.security.Key; import java.security.PrivateKey; import java.security.PublicKey; import java.security.spec.InvalidKeySpecException; import java.security.spec.KeySpec; import org.bouncycastle.asn1.ASN1ObjectIdentifier; import org.bouncycastle.asn1.cryptopro.CryptoProObjectIdentifiers; import org.bouncycastle.asn1.pkcs.PrivateKeyInfo; import org.bouncycastle.asn1.x509.SubjectPublicKeyInfo; import org.bouncycastle.jcajce.provider.asymmetric.util.BaseKeyFactorySpi; import org.bouncycastle.jce.interfaces.GOST3410PrivateKey; import org.bouncycastle.jce.interfaces.GOST3410PublicKey; import org.bouncycastle.jce.spec.GOST3410PrivateKeySpec; import org.bouncycastle.jce.spec.GOST3410PublicKeyParameterSetSpec; import org.bouncycastle.jce.spec.GOST3410PublicKeySpec; public class KeyFactorySpi extends BaseKeyFactorySpi { public KeyFactorySpi() { } protected KeySpec engineGetKeySpec( Key key, Class spec) throws InvalidKeySpecException { if (spec.isAssignableFrom(GOST3410PublicKeySpec.class) && key instanceof GOST3410PublicKey) { GOST3410PublicKey k = (GOST3410PublicKey)key; GOST3410PublicKeyParameterSetSpec parameters = k.getParameters().getPublicKeyParameters(); return new GOST3410PublicKeySpec(k.getY(), parameters.getP(), parameters.getQ(), parameters.getA()); } else if (spec.isAssignableFrom(GOST3410PrivateKeySpec.class) && key instanceof GOST3410PrivateKey) { GOST3410PrivateKey k = (GOST3410PrivateKey)key; GOST3410PublicKeyParameterSetSpec parameters = k.getParameters().getPublicKeyParameters(); return new GOST3410PrivateKeySpec(k.getX(), parameters.getP(), parameters.getQ(), parameters.getA()); } return super.engineGetKeySpec(key, spec); } protected Key engineTranslateKey( Key key) throws InvalidKeyException { if (key instanceof GOST3410PublicKey) { return new BCGOST3410PublicKey((GOST3410PublicKey)key); } else if (key instanceof GOST3410PrivateKey) { return new BCGOST3410PrivateKey((GOST3410PrivateKey)key); } throw new InvalidKeyException("key type unknown"); } protected PrivateKey engineGeneratePrivate( KeySpec keySpec) throws InvalidKeySpecException { if (keySpec instanceof GOST3410PrivateKeySpec) { return new BCGOST3410PrivateKey((GOST3410PrivateKeySpec)keySpec); } return super.engineGeneratePrivate(keySpec); } protected PublicKey engineGeneratePublic( KeySpec keySpec) throws InvalidKeySpecException { if (keySpec instanceof GOST3410PublicKeySpec) { return new BCGOST3410PublicKey((GOST3410PublicKeySpec)keySpec); } return super.engineGeneratePublic(keySpec); } public PrivateKey generatePrivate(PrivateKeyInfo keyInfo) throws IOException { ASN1ObjectIdentifier algOid = keyInfo.getPrivateKeyAlgorithm().getAlgorithm(); if (algOid.equals(CryptoProObjectIdentifiers.gostR3410_94)) { return new BCGOST3410PrivateKey(keyInfo); } else { throw new IOException("algorithm identifier " + algOid + " in key not recognised"); } } public PublicKey generatePublic(SubjectPublicKeyInfo keyInfo) throws IOException { ASN1ObjectIdentifier algOid = keyInfo.getAlgorithm().getAlgorithm(); if (algOid.equals(CryptoProObjectIdentifiers.gostR3410_94)) { return new BCGOST3410PublicKey(keyInfo); } else { throw new IOException("algorithm identifier " + algOid + " in key not recognised"); } } } ././@LongLink0000000000000000000000000000014600000000000011566 Lustar rootrootbouncycastle-1.49.orig/src/org/bouncycastle/jcajce/provider/asymmetric/gost/BCGOST3410PrivateKey.javabouncycastle-1.49.orig/src/org/bouncycastle/jcajce/provider/asymmetric/gost/BCGOST3410PrivateKey.jav0000644000175000017500000001736211736773417032734 0ustar ebourgebourgpackage org.bouncycastle.jcajce.provider.asymmetric.gost; import java.io.IOException; import java.io.ObjectInputStream; import java.io.ObjectOutputStream; import java.math.BigInteger; import java.util.Enumeration; import org.bouncycastle.asn1.ASN1Encodable; import org.bouncycastle.asn1.ASN1Encoding; import org.bouncycastle.asn1.ASN1ObjectIdentifier; import org.bouncycastle.asn1.ASN1OctetString; import org.bouncycastle.asn1.ASN1Sequence; import org.bouncycastle.asn1.DEROctetString; import org.bouncycastle.asn1.cryptopro.CryptoProObjectIdentifiers; import org.bouncycastle.asn1.cryptopro.GOST3410PublicKeyAlgParameters; import org.bouncycastle.asn1.pkcs.PrivateKeyInfo; import org.bouncycastle.asn1.x509.AlgorithmIdentifier; import org.bouncycastle.crypto.params.GOST3410PrivateKeyParameters; import org.bouncycastle.jcajce.provider.asymmetric.util.PKCS12BagAttributeCarrierImpl; import org.bouncycastle.jce.interfaces.GOST3410Params; import org.bouncycastle.jce.interfaces.GOST3410PrivateKey; import org.bouncycastle.jce.interfaces.PKCS12BagAttributeCarrier; import org.bouncycastle.jce.spec.GOST3410ParameterSpec; import org.bouncycastle.jce.spec.GOST3410PrivateKeySpec; import org.bouncycastle.jce.spec.GOST3410PublicKeyParameterSetSpec; public class BCGOST3410PrivateKey implements GOST3410PrivateKey, PKCS12BagAttributeCarrier { static final long serialVersionUID = 8581661527592305464L; private BigInteger x; private transient GOST3410Params gost3410Spec; private transient PKCS12BagAttributeCarrier attrCarrier = new PKCS12BagAttributeCarrierImpl(); protected BCGOST3410PrivateKey() { } BCGOST3410PrivateKey( GOST3410PrivateKey key) { this.x = key.getX(); this.gost3410Spec = key.getParameters(); } BCGOST3410PrivateKey( GOST3410PrivateKeySpec spec) { this.x = spec.getX(); this.gost3410Spec = new GOST3410ParameterSpec(new GOST3410PublicKeyParameterSetSpec(spec.getP(), spec.getQ(), spec.getA())); } BCGOST3410PrivateKey( PrivateKeyInfo info) throws IOException { GOST3410PublicKeyAlgParameters params = new GOST3410PublicKeyAlgParameters((ASN1Sequence)info.getAlgorithmId().getParameters()); ASN1OctetString derX = ASN1OctetString.getInstance(info.parsePrivateKey()); byte[] keyEnc = derX.getOctets(); byte[] keyBytes = new byte[keyEnc.length]; for (int i = 0; i != keyEnc.length; i++) { keyBytes[i] = keyEnc[keyEnc.length - 1 - i]; // was little endian } this.x = new BigInteger(1, keyBytes); this.gost3410Spec = GOST3410ParameterSpec.fromPublicKeyAlg(params); } BCGOST3410PrivateKey( GOST3410PrivateKeyParameters params, GOST3410ParameterSpec spec) { this.x = params.getX(); this.gost3410Spec = spec; if (spec == null) { throw new IllegalArgumentException("spec is null"); } } public String getAlgorithm() { return "GOST3410"; } /** * return the encoding format we produce in getEncoded(). * * @return the string "PKCS#8" */ public String getFormat() { return "PKCS#8"; } /** * Return a PKCS8 representation of the key. The sequence returned * represents a full PrivateKeyInfo object. * * @return a PKCS8 representation of the key. */ public byte[] getEncoded() { PrivateKeyInfo info; byte[] keyEnc = this.getX().toByteArray(); byte[] keyBytes; if (keyEnc[0] == 0) { keyBytes = new byte[keyEnc.length - 1]; } else { keyBytes = new byte[keyEnc.length]; } for (int i = 0; i != keyBytes.length; i++) { keyBytes[i] = keyEnc[keyEnc.length - 1 - i]; // must be little endian } try { if (gost3410Spec instanceof GOST3410ParameterSpec) { info = new PrivateKeyInfo(new AlgorithmIdentifier(CryptoProObjectIdentifiers.gostR3410_94, new GOST3410PublicKeyAlgParameters(new ASN1ObjectIdentifier(gost3410Spec.getPublicKeyParamSetOID()), new ASN1ObjectIdentifier(gost3410Spec.getDigestParamSetOID()))), new DEROctetString(keyBytes)); } else { info = new PrivateKeyInfo(new AlgorithmIdentifier(CryptoProObjectIdentifiers.gostR3410_94), new DEROctetString(keyBytes)); } return info.getEncoded(ASN1Encoding.DER); } catch (IOException e) { return null; } } public GOST3410Params getParameters() { return gost3410Spec; } public BigInteger getX() { return x; } public boolean equals( Object o) { if (!(o instanceof GOST3410PrivateKey)) { return false; } GOST3410PrivateKey other = (GOST3410PrivateKey)o; return this.getX().equals(other.getX()) && this.getParameters().getPublicKeyParameters().equals(other.getParameters().getPublicKeyParameters()) && this.getParameters().getDigestParamSetOID().equals(other.getParameters().getDigestParamSetOID()) && compareObj(this.getParameters().getEncryptionParamSetOID(), other.getParameters().getEncryptionParamSetOID()); } private boolean compareObj(Object o1, Object o2) { if (o1 == o2) { return true; } if (o1 == null) { return false; } return o1.equals(o2); } public int hashCode() { return this.getX().hashCode() ^ gost3410Spec.hashCode(); } public void setBagAttribute( ASN1ObjectIdentifier oid, ASN1Encodable attribute) { attrCarrier.setBagAttribute(oid, attribute); } public ASN1Encodable getBagAttribute( ASN1ObjectIdentifier oid) { return attrCarrier.getBagAttribute(oid); } public Enumeration getBagAttributeKeys() { return attrCarrier.getBagAttributeKeys(); } private void readObject( ObjectInputStream in) throws IOException, ClassNotFoundException { in.defaultReadObject(); String publicKeyParamSetOID = (String)in.readObject(); if (publicKeyParamSetOID != null) { this.gost3410Spec = new GOST3410ParameterSpec(publicKeyParamSetOID, (String)in.readObject(), (String)in.readObject()); } else { this.gost3410Spec = new GOST3410ParameterSpec(new GOST3410PublicKeyParameterSetSpec((BigInteger)in.readObject(), (BigInteger)in.readObject(), (BigInteger)in.readObject())); in.readObject(); in.readObject(); } this.attrCarrier = new PKCS12BagAttributeCarrierImpl(); } private void writeObject( ObjectOutputStream out) throws IOException { out.defaultWriteObject(); if (gost3410Spec.getPublicKeyParamSetOID() != null) { out.writeObject(gost3410Spec.getPublicKeyParamSetOID()); out.writeObject(gost3410Spec.getDigestParamSetOID()); out.writeObject(gost3410Spec.getEncryptionParamSetOID()); } else { out.writeObject(null); out.writeObject(gost3410Spec.getPublicKeyParameters().getP()); out.writeObject(gost3410Spec.getPublicKeyParameters().getQ()); out.writeObject(gost3410Spec.getPublicKeyParameters().getA()); out.writeObject(gost3410Spec.getDigestParamSetOID()); out.writeObject(gost3410Spec.getEncryptionParamSetOID()); } } } bouncycastle-1.49.orig/src/org/bouncycastle/jcajce/provider/asymmetric/gost/KeyPairGeneratorSpi.java0000644000175000017500000000530611627611622033446 0ustar ebourgebourgpackage org.bouncycastle.jcajce.provider.asymmetric.gost; import java.security.InvalidAlgorithmParameterException; import java.security.KeyPair; import java.security.SecureRandom; import java.security.spec.AlgorithmParameterSpec; import org.bouncycastle.asn1.cryptopro.CryptoProObjectIdentifiers; import org.bouncycastle.crypto.AsymmetricCipherKeyPair; import org.bouncycastle.crypto.generators.GOST3410KeyPairGenerator; import org.bouncycastle.crypto.params.GOST3410KeyGenerationParameters; import org.bouncycastle.crypto.params.GOST3410Parameters; import org.bouncycastle.crypto.params.GOST3410PrivateKeyParameters; import org.bouncycastle.crypto.params.GOST3410PublicKeyParameters; import org.bouncycastle.jce.spec.GOST3410ParameterSpec; import org.bouncycastle.jce.spec.GOST3410PublicKeyParameterSetSpec; public class KeyPairGeneratorSpi extends java.security.KeyPairGenerator { GOST3410KeyGenerationParameters param; GOST3410KeyPairGenerator engine = new GOST3410KeyPairGenerator(); GOST3410ParameterSpec gost3410Params; int strength = 1024; SecureRandom random = null; boolean initialised = false; public KeyPairGeneratorSpi() { super("GOST3410"); } public void initialize( int strength, SecureRandom random) { this.strength = strength; this.random = random; } private void init( GOST3410ParameterSpec gParams, SecureRandom random) { GOST3410PublicKeyParameterSetSpec spec = gParams.getPublicKeyParameters(); param = new GOST3410KeyGenerationParameters(random, new GOST3410Parameters(spec.getP(), spec.getQ(), spec.getA())); engine.init(param); initialised = true; gost3410Params = gParams; } public void initialize( AlgorithmParameterSpec params, SecureRandom random) throws InvalidAlgorithmParameterException { if (!(params instanceof GOST3410ParameterSpec)) { throw new InvalidAlgorithmParameterException("parameter object not a GOST3410ParameterSpec"); } init((GOST3410ParameterSpec)params, random); } public KeyPair generateKeyPair() { if (!initialised) { init(new GOST3410ParameterSpec(CryptoProObjectIdentifiers.gostR3410_94_CryptoPro_A.getId()), new SecureRandom()); } AsymmetricCipherKeyPair pair = engine.generateKeyPair(); GOST3410PublicKeyParameters pub = (GOST3410PublicKeyParameters)pair.getPublic(); GOST3410PrivateKeyParameters priv = (GOST3410PrivateKeyParameters)pair.getPrivate(); return new KeyPair(new BCGOST3410PublicKey(pub, gost3410Params), new BCGOST3410PrivateKey(priv, gost3410Params)); } } bouncycastle-1.49.orig/src/org/bouncycastle/jcajce/provider/asymmetric/RSA.java0000644000175000017500000003043700000000035027200 0ustar ebourgebourgpackage org.bouncycastle.jcajce.provider.asymmetric; import org.bouncycastle.asn1.ASN1ObjectIdentifier; import org.bouncycastle.asn1.oiw.OIWObjectIdentifiers; import org.bouncycastle.asn1.pkcs.PKCSObjectIdentifiers; import org.bouncycastle.asn1.teletrust.TeleTrusTObjectIdentifiers; import org.bouncycastle.asn1.x509.X509ObjectIdentifiers; import org.bouncycastle.jcajce.provider.asymmetric.rsa.KeyFactorySpi; import org.bouncycastle.jcajce.provider.config.ConfigurableProvider; import org.bouncycastle.jcajce.provider.util.AsymmetricAlgorithmProvider; import org.bouncycastle.jcajce.provider.util.AsymmetricKeyInfoConverter; public class RSA { private static final String PREFIX = "org.bouncycastle.jcajce.provider.asymmetric" + ".rsa."; public static class Mappings extends AsymmetricAlgorithmProvider { public Mappings() { } public void configure(ConfigurableProvider provider) { provider.addAlgorithm("AlgorithmParameters.OAEP", PREFIX + "AlgorithmParametersSpi$OAEP"); provider.addAlgorithm("AlgorithmParameters.PSS", PREFIX + "AlgorithmParametersSpi$PSS"); provider.addAlgorithm("Alg.Alias.AlgorithmParameters.RSAPSS", "PSS"); provider.addAlgorithm("Alg.Alias.AlgorithmParameters.RSASSA-PSS", "PSS"); provider.addAlgorithm("Alg.Alias.AlgorithmParameters.SHA224withRSA/PSS", "PSS"); provider.addAlgorithm("Alg.Alias.AlgorithmParameters.SHA256withRSA/PSS", "PSS"); provider.addAlgorithm("Alg.Alias.AlgorithmParameters.SHA384withRSA/PSS", "PSS"); provider.addAlgorithm("Alg.Alias.AlgorithmParameters.SHA512withRSA/PSS", "PSS"); provider.addAlgorithm("Alg.Alias.AlgorithmParameters.SHA224WITHRSAANDMGF1", "PSS"); provider.addAlgorithm("Alg.Alias.AlgorithmParameters.SHA256WITHRSAANDMGF1", "PSS"); provider.addAlgorithm("Alg.Alias.AlgorithmParameters.SHA384WITHRSAANDMGF1", "PSS"); provider.addAlgorithm("Alg.Alias.AlgorithmParameters.SHA512WITHRSAANDMGF1", "PSS"); provider.addAlgorithm("Alg.Alias.AlgorithmParameters.RAWRSAPSS", "PSS"); provider.addAlgorithm("Alg.Alias.AlgorithmParameters.NONEWITHRSAPSS", "PSS"); provider.addAlgorithm("Alg.Alias.AlgorithmParameters.NONEWITHRSASSA-PSS", "PSS"); provider.addAlgorithm("Alg.Alias.AlgorithmParameters.NONEWITHRSAANDMGF1", "PSS"); provider.addAlgorithm("Cipher.RSA", PREFIX + "CipherSpi$NoPadding"); provider.addAlgorithm("Cipher.RSA/RAW", PREFIX + "CipherSpi$NoPadding"); provider.addAlgorithm("Cipher.RSA/PKCS1", PREFIX + "CipherSpi$PKCS1v1_5Padding"); provider.addAlgorithm("Cipher.1.2.840.113549.1.1.1", PREFIX + "CipherSpi$PKCS1v1_5Padding"); provider.addAlgorithm("Cipher.2.5.8.1.1", PREFIX + "CipherSpi$PKCS1v1_5Padding"); provider.addAlgorithm("Cipher.RSA/1", PREFIX + "CipherSpi$PKCS1v1_5Padding_PrivateOnly"); provider.addAlgorithm("Cipher.RSA/2", PREFIX + "CipherSpi$PKCS1v1_5Padding_PublicOnly"); provider.addAlgorithm("Cipher.RSA/OAEP", PREFIX + "CipherSpi$OAEPPadding"); provider.addAlgorithm("Cipher." + PKCSObjectIdentifiers.id_RSAES_OAEP, PREFIX + "CipherSpi$OAEPPadding"); provider.addAlgorithm("Cipher.RSA/ISO9796-1", PREFIX + "CipherSpi$ISO9796d1Padding"); provider.addAlgorithm("Alg.Alias.Cipher.RSA//RAW", "RSA"); provider.addAlgorithm("Alg.Alias.Cipher.RSA//NOPADDING", "RSA"); provider.addAlgorithm("Alg.Alias.Cipher.RSA//PKCS1PADDING", "RSA/PKCS1"); provider.addAlgorithm("Alg.Alias.Cipher.RSA//OAEPPADDING", "RSA/OAEP"); provider.addAlgorithm("Alg.Alias.Cipher.RSA//ISO9796-1PADDING", "RSA/ISO9796-1"); provider.addAlgorithm("KeyFactory.RSA", PREFIX + "KeyFactorySpi"); provider.addAlgorithm("KeyPairGenerator.RSA", PREFIX + "KeyPairGeneratorSpi"); AsymmetricKeyInfoConverter keyFact = new KeyFactorySpi(); registerOid(provider, PKCSObjectIdentifiers.rsaEncryption, "RSA", keyFact); registerOid(provider, X509ObjectIdentifiers.id_ea_rsa, "RSA", keyFact); registerOid(provider, PKCSObjectIdentifiers.id_RSAES_OAEP, "RSA", keyFact); registerOid(provider, PKCSObjectIdentifiers.id_RSASSA_PSS, "RSA", keyFact); registerOidAlgorithmParameters(provider, PKCSObjectIdentifiers.rsaEncryption, "RSA"); registerOidAlgorithmParameters(provider, X509ObjectIdentifiers.id_ea_rsa, "RSA"); registerOidAlgorithmParameters(provider, PKCSObjectIdentifiers.id_RSAES_OAEP, "OAEP"); registerOidAlgorithmParameters(provider, PKCSObjectIdentifiers.id_RSASSA_PSS, "PSS"); provider.addAlgorithm("Signature.RSASSA-PSS", PREFIX + "PSSSignatureSpi$PSSwithRSA"); provider.addAlgorithm("Signature." + PKCSObjectIdentifiers.id_RSASSA_PSS, PREFIX + "PSSSignatureSpi$PSSwithRSA"); provider.addAlgorithm("Signature.OID." + PKCSObjectIdentifiers.id_RSASSA_PSS, PREFIX + "PSSSignatureSpi$PSSwithRSA"); provider.addAlgorithm("Signature.SHA224withRSA/PSS", PREFIX + "PSSSignatureSpi$SHA224withRSA"); provider.addAlgorithm("Signature.SHA256withRSA/PSS", PREFIX + "PSSSignatureSpi$SHA256withRSA"); provider.addAlgorithm("Signature.SHA384withRSA/PSS", PREFIX + "PSSSignatureSpi$SHA384withRSA"); provider.addAlgorithm("Signature.SHA512withRSA/PSS", PREFIX + "PSSSignatureSpi$SHA512withRSA"); provider.addAlgorithm("Signature.RSA", PREFIX + "DigestSignatureSpi$noneRSA"); provider.addAlgorithm("Signature.RAWRSASSA-PSS", PREFIX + "PSSSignatureSpi$nonePSS"); provider.addAlgorithm("Alg.Alias.Signature.RAWRSA", "RSA"); provider.addAlgorithm("Alg.Alias.Signature.NONEWITHRSA", "RSA"); provider.addAlgorithm("Alg.Alias.Signature.RAWRSAPSS", "RAWRSASSA-PSS"); provider.addAlgorithm("Alg.Alias.Signature.NONEWITHRSAPSS", "RAWRSASSA-PSS"); provider.addAlgorithm("Alg.Alias.Signature.NONEWITHRSASSA-PSS", "RAWRSASSA-PSS"); provider.addAlgorithm("Alg.Alias.Signature.NONEWITHRSAANDMGF1", "RAWRSASSA-PSS"); provider.addAlgorithm("Alg.Alias.Signature.RSAPSS", "RSASSA-PSS"); provider.addAlgorithm("Alg.Alias.Signature.SHA224withRSAandMGF1", "SHA224withRSA/PSS"); provider.addAlgorithm("Alg.Alias.Signature.SHA256withRSAandMGF1", "SHA256withRSA/PSS"); provider.addAlgorithm("Alg.Alias.Signature.SHA384withRSAandMGF1", "SHA384withRSA/PSS"); provider.addAlgorithm("Alg.Alias.Signature.SHA512withRSAandMGF1", "SHA512withRSA/PSS"); provider.addAlgorithm("Alg.Alias.Signature.SHA224WITHRSAANDMGF1", "SHA224withRSA/PSS"); provider.addAlgorithm("Alg.Alias.Signature.SHA256WITHRSAANDMGF1", "SHA256withRSA/PSS"); provider.addAlgorithm("Alg.Alias.Signature.SHA384WITHRSAANDMGF1", "SHA384withRSA/PSS"); provider.addAlgorithm("Alg.Alias.Signature.SHA512WITHRSAANDMGF1", "SHA512withRSA/PSS"); if (provider.hasAlgorithm("MessageDigest", "MD2")) { addDigestSignature(provider, "MD2", PREFIX + "DigestSignatureSpi$MD2", PKCSObjectIdentifiers.md2WithRSAEncryption); } if (provider.hasAlgorithm("MessageDigest", "MD4")) { addDigestSignature(provider, "MD4", PREFIX + "DigestSignatureSpi$MD4", PKCSObjectIdentifiers.md4WithRSAEncryption); } if (provider.hasAlgorithm("MessageDigest", "MD5")) { addDigestSignature(provider, "MD5", PREFIX + "DigestSignatureSpi$MD5", PKCSObjectIdentifiers.md5WithRSAEncryption); provider.addAlgorithm("Signature.MD5withRSA/ISO9796-2", PREFIX + "ISOSignatureSpi$MD5WithRSAEncryption"); provider.addAlgorithm("Alg.Alias.Signature.MD5WithRSA/ISO9796-2", "MD5withRSA/ISO9796-2"); } if (provider.hasAlgorithm("MessageDigest", "SHA1")) { provider.addAlgorithm("Alg.Alias.AlgorithmParameters.SHA1withRSA/PSS", "PSS"); provider.addAlgorithm("Alg.Alias.AlgorithmParameters.SHA1WITHRSAANDMGF1", "PSS"); provider.addAlgorithm("Signature.SHA1withRSA/PSS", PREFIX + "PSSSignatureSpi$SHA1withRSA"); provider.addAlgorithm("Alg.Alias.Signature.SHA1withRSAandMGF1", "SHA1withRSA/PSS"); provider.addAlgorithm("Alg.Alias.Signature.SHA1WITHRSAANDMGF1", "SHA1withRSA/PSS"); addDigestSignature(provider, "SHA1", PREFIX + "DigestSignatureSpi$SHA1", PKCSObjectIdentifiers.sha1WithRSAEncryption); provider.addAlgorithm("Alg.Alias.Signature.SHA1WithRSA/ISO9796-2", "SHA1withRSA/ISO9796-2"); provider.addAlgorithm("Signature.SHA1withRSA/ISO9796-2", PREFIX + "ISOSignatureSpi$SHA1WithRSAEncryption"); provider.addAlgorithm("Alg.Alias.Signature." + OIWObjectIdentifiers.sha1WithRSA, "SHA1WITHRSA"); provider.addAlgorithm("Alg.Alias.Signature.OID." + OIWObjectIdentifiers.sha1WithRSA, "SHA1WITHRSA"); } addDigestSignature(provider, "SHA224", PREFIX + "DigestSignatureSpi$SHA224", PKCSObjectIdentifiers.sha224WithRSAEncryption); addDigestSignature(provider, "SHA256", PREFIX + "DigestSignatureSpi$SHA256", PKCSObjectIdentifiers.sha256WithRSAEncryption); addDigestSignature(provider, "SHA384", PREFIX + "DigestSignatureSpi$SHA384", PKCSObjectIdentifiers.sha384WithRSAEncryption); addDigestSignature(provider, "SHA512", PREFIX + "DigestSignatureSpi$SHA512", PKCSObjectIdentifiers.sha512WithRSAEncryption); if (provider.hasAlgorithm("MessageDigest", "RIPEMD128")) { addDigestSignature(provider, "RIPEMD128", PREFIX + "DigestSignatureSpi$RIPEMD128", TeleTrusTObjectIdentifiers.rsaSignatureWithripemd128); addDigestSignature(provider, "RMD128", PREFIX + "DigestSignatureSpi$RIPEMD128", null); } if (provider.hasAlgorithm("MessageDigest", "RIPEMD160")) { addDigestSignature(provider, "RIPEMD160", PREFIX + "DigestSignatureSpi$RIPEMD160", TeleTrusTObjectIdentifiers.rsaSignatureWithripemd160); addDigestSignature(provider, "RMD160", PREFIX + "DigestSignatureSpi$RIPEMD160", null); provider.addAlgorithm("Alg.Alias.Signature.RIPEMD160WithRSA/ISO9796-2", "RIPEMD160withRSA/ISO9796-2"); provider.addAlgorithm("Signature.RIPEMD160withRSA/ISO9796-2", PREFIX + "ISOSignatureSpi$RIPEMD160WithRSAEncryption"); } if (provider.hasAlgorithm("MessageDigest", "RIPEMD256")) { addDigestSignature(provider, "RIPEMD256", PREFIX + "DigestSignatureSpi$RIPEMD256", TeleTrusTObjectIdentifiers.rsaSignatureWithripemd256); addDigestSignature(provider, "RMD256", PREFIX + "DigestSignatureSpi$RIPEMD256", null); } } private void addDigestSignature( ConfigurableProvider provider, String digest, String className, ASN1ObjectIdentifier oid) { String mainName = digest + "WITHRSA"; String jdk11Variation1 = digest + "withRSA"; String jdk11Variation2 = digest + "WithRSA"; String alias = digest + "/" + "RSA"; String longName = digest + "WITHRSAENCRYPTION"; String longJdk11Variation1 = digest + "withRSAEncryption"; String longJdk11Variation2 = digest + "WithRSAEncryption"; provider.addAlgorithm("Signature." + mainName, className); provider.addAlgorithm("Alg.Alias.Signature." + jdk11Variation1, mainName); provider.addAlgorithm("Alg.Alias.Signature." + jdk11Variation2, mainName); provider.addAlgorithm("Alg.Alias.Signature." + longName, mainName); provider.addAlgorithm("Alg.Alias.Signature." + longJdk11Variation1, mainName); provider.addAlgorithm("Alg.Alias.Signature." + longJdk11Variation2, mainName); provider.addAlgorithm("Alg.Alias.Signature." + alias, mainName); if (oid != null) { provider.addAlgorithm("Alg.Alias.Signature." + oid, mainName); provider.addAlgorithm("Alg.Alias.Signature.OID." + oid, mainName); } } } } bouncycastle-1.49.orig/src/org/bouncycastle/jcajce/provider/asymmetric/ec/0000755000175000017500000000000012152033551026314 5ustar ebourgebourgbouncycastle-1.49.orig/src/org/bouncycastle/jcajce/provider/asymmetric/ec/SignatureSpi.java0000644000175000017500000001762112151457135031612 0ustar ebourgebourgpackage org.bouncycastle.jcajce.provider.asymmetric.ec; import java.io.IOException; import java.math.BigInteger; import java.security.InvalidKeyException; import java.security.PrivateKey; import java.security.PublicKey; import org.bouncycastle.asn1.ASN1EncodableVector; import org.bouncycastle.asn1.ASN1Encoding; import org.bouncycastle.asn1.ASN1Integer; import org.bouncycastle.asn1.ASN1Primitive; import org.bouncycastle.asn1.ASN1Sequence; import org.bouncycastle.asn1.DERSequence; import org.bouncycastle.crypto.CipherParameters; import org.bouncycastle.crypto.DSA; import org.bouncycastle.crypto.Digest; import org.bouncycastle.crypto.digests.NullDigest; import org.bouncycastle.crypto.digests.RIPEMD160Digest; import org.bouncycastle.crypto.digests.SHA1Digest; import org.bouncycastle.crypto.digests.SHA224Digest; import org.bouncycastle.crypto.digests.SHA256Digest; import org.bouncycastle.crypto.digests.SHA384Digest; import org.bouncycastle.crypto.digests.SHA512Digest; import org.bouncycastle.crypto.params.ParametersWithRandom; import org.bouncycastle.crypto.signers.ECDSASigner; import org.bouncycastle.crypto.signers.ECNRSigner; import org.bouncycastle.jcajce.provider.asymmetric.util.DSABase; import org.bouncycastle.jcajce.provider.asymmetric.util.DSAEncoder; import org.bouncycastle.jcajce.provider.asymmetric.util.ECUtil; public class SignatureSpi extends DSABase { SignatureSpi(Digest digest, DSA signer, DSAEncoder encoder) { super(digest, signer, encoder); } protected void engineInitVerify(PublicKey publicKey) throws InvalidKeyException { CipherParameters param = ECUtil.generatePublicKeyParameter(publicKey); digest.reset(); signer.init(false, param); } protected void engineInitSign( PrivateKey privateKey) throws InvalidKeyException { CipherParameters param = ECUtil.generatePrivateKeyParameter(privateKey); digest.reset(); if (appRandom != null) { signer.init(true, new ParametersWithRandom(param, appRandom)); } else { signer.init(true, param); } } static public class ecDSA extends SignatureSpi { public ecDSA() { super(new SHA1Digest(), new ECDSASigner(), new StdDSAEncoder()); } } static public class ecDSAnone extends SignatureSpi { public ecDSAnone() { super(new NullDigest(), new ECDSASigner(), new StdDSAEncoder()); } } static public class ecDSA224 extends SignatureSpi { public ecDSA224() { super(new SHA224Digest(), new ECDSASigner(), new StdDSAEncoder()); } } static public class ecDSA256 extends SignatureSpi { public ecDSA256() { super(new SHA256Digest(), new ECDSASigner(), new StdDSAEncoder()); } } static public class ecDSA384 extends SignatureSpi { public ecDSA384() { super(new SHA384Digest(), new ECDSASigner(), new StdDSAEncoder()); } } static public class ecDSA512 extends SignatureSpi { public ecDSA512() { super(new SHA512Digest(), new ECDSASigner(), new StdDSAEncoder()); } } static public class ecDSARipeMD160 extends SignatureSpi { public ecDSARipeMD160() { super(new RIPEMD160Digest(), new ECDSASigner(), new StdDSAEncoder()); } } static public class ecNR extends SignatureSpi { public ecNR() { super(new SHA1Digest(), new ECNRSigner(), new StdDSAEncoder()); } } static public class ecNR224 extends SignatureSpi { public ecNR224() { super(new SHA224Digest(), new ECNRSigner(), new StdDSAEncoder()); } } static public class ecNR256 extends SignatureSpi { public ecNR256() { super(new SHA256Digest(), new ECNRSigner(), new StdDSAEncoder()); } } static public class ecNR384 extends SignatureSpi { public ecNR384() { super(new SHA384Digest(), new ECNRSigner(), new StdDSAEncoder()); } } static public class ecNR512 extends SignatureSpi { public ecNR512() { super(new SHA512Digest(), new ECNRSigner(), new StdDSAEncoder()); } } static public class ecCVCDSA extends SignatureSpi { public ecCVCDSA() { super(new SHA1Digest(), new ECDSASigner(), new CVCDSAEncoder()); } } static public class ecCVCDSA224 extends SignatureSpi { public ecCVCDSA224() { super(new SHA224Digest(), new ECDSASigner(), new CVCDSAEncoder()); } } static public class ecCVCDSA256 extends SignatureSpi { public ecCVCDSA256() { super(new SHA256Digest(), new ECDSASigner(), new CVCDSAEncoder()); } } static public class ecCVCDSA384 extends SignatureSpi { public ecCVCDSA384() { super(new SHA384Digest(), new ECDSASigner(), new CVCDSAEncoder()); } } static public class ecCVCDSA512 extends SignatureSpi { public ecCVCDSA512() { super(new SHA512Digest(), new ECDSASigner(), new CVCDSAEncoder()); } } private static class StdDSAEncoder implements DSAEncoder { public byte[] encode( BigInteger r, BigInteger s) throws IOException { ASN1EncodableVector v = new ASN1EncodableVector(); v.add(new ASN1Integer(r)); v.add(new ASN1Integer(s)); return new DERSequence(v).getEncoded(ASN1Encoding.DER); } public BigInteger[] decode( byte[] encoding) throws IOException { ASN1Sequence s = (ASN1Sequence)ASN1Primitive.fromByteArray(encoding); BigInteger[] sig = new BigInteger[2]; sig[0] = ASN1Integer.getInstance(s.getObjectAt(0)).getValue(); sig[1] = ASN1Integer.getInstance(s.getObjectAt(1)).getValue(); return sig; } } private static class CVCDSAEncoder implements DSAEncoder { public byte[] encode( BigInteger r, BigInteger s) throws IOException { byte[] first = makeUnsigned(r); byte[] second = makeUnsigned(s); byte[] res; if (first.length > second.length) { res = new byte[first.length * 2]; } else { res = new byte[second.length * 2]; } System.arraycopy(first, 0, res, res.length / 2 - first.length, first.length); System.arraycopy(second, 0, res, res.length - second.length, second.length); return res; } private byte[] makeUnsigned(BigInteger val) { byte[] res = val.toByteArray(); if (res[0] == 0) { byte[] tmp = new byte[res.length - 1]; System.arraycopy(res, 1, tmp, 0, tmp.length); return tmp; } return res; } public BigInteger[] decode( byte[] encoding) throws IOException { BigInteger[] sig = new BigInteger[2]; byte[] first = new byte[encoding.length / 2]; byte[] second = new byte[encoding.length / 2]; System.arraycopy(encoding, 0, first, 0, first.length); System.arraycopy(encoding, first.length, second, 0, second.length); sig[0] = new BigInteger(1, first); sig[1] = new BigInteger(1, second); return sig; } } }bouncycastle-1.49.orig/src/org/bouncycastle/jcajce/provider/asymmetric/ec/IESCipher.java0000600000175000017500000003405212151127023030723 0ustar ebourgebourgpackage org.bouncycastle.jcajce.provider.asymmetric.ec; import java.io.ByteArrayOutputStream; import java.security.AlgorithmParameters; import java.security.InvalidAlgorithmParameterException; import java.security.InvalidKeyException; import java.security.Key; import java.security.NoSuchAlgorithmException; import java.security.PrivateKey; import java.security.PublicKey; import java.security.SecureRandom; import java.security.spec.AlgorithmParameterSpec; import javax.crypto.BadPaddingException; import javax.crypto.Cipher; import javax.crypto.CipherSpi; import javax.crypto.IllegalBlockSizeException; import javax.crypto.NoSuchPaddingException; import javax.crypto.ShortBufferException; import org.bouncycastle.crypto.InvalidCipherTextException; import org.bouncycastle.crypto.KeyEncoder; import org.bouncycastle.crypto.agreement.ECDHBasicAgreement; import org.bouncycastle.crypto.digests.SHA1Digest; import org.bouncycastle.crypto.engines.AESEngine; import org.bouncycastle.crypto.engines.DESedeEngine; import org.bouncycastle.crypto.engines.IESEngine; import org.bouncycastle.crypto.generators.ECKeyPairGenerator; import org.bouncycastle.crypto.generators.EphemeralKeyPairGenerator; import org.bouncycastle.crypto.generators.KDF2BytesGenerator; import org.bouncycastle.crypto.macs.HMac; import org.bouncycastle.crypto.paddings.PaddedBufferedBlockCipher; import org.bouncycastle.crypto.params.AsymmetricKeyParameter; import org.bouncycastle.crypto.params.ECDomainParameters; import org.bouncycastle.crypto.params.ECKeyGenerationParameters; import org.bouncycastle.crypto.params.ECKeyParameters; import org.bouncycastle.crypto.params.ECPublicKeyParameters; import org.bouncycastle.crypto.params.IESParameters; import org.bouncycastle.crypto.params.IESWithCipherParameters; import org.bouncycastle.crypto.parsers.ECIESPublicKeyParser; import org.bouncycastle.jcajce.provider.asymmetric.util.ECUtil; import org.bouncycastle.jcajce.provider.asymmetric.util.IESUtil; import org.bouncycastle.jce.interfaces.ECKey; import org.bouncycastle.jce.interfaces.ECPrivateKey; import org.bouncycastle.jce.interfaces.ECPublicKey; import org.bouncycastle.jce.interfaces.IESKey; import org.bouncycastle.jce.provider.BouncyCastleProvider; import org.bouncycastle.jce.spec.IESParameterSpec; import org.bouncycastle.util.Strings; public class IESCipher extends CipherSpi { private IESEngine engine; private int state = -1; private ByteArrayOutputStream buffer = new ByteArrayOutputStream(); private AlgorithmParameters engineParam = null; private IESParameterSpec engineSpec = null; private AsymmetricKeyParameter key; private SecureRandom random; private boolean dhaesMode = false; private AsymmetricKeyParameter otherKeyParameter = null; public IESCipher(IESEngine engine) { this.engine = engine; } public int engineGetBlockSize() { if (engine.getCipher() != null) { return engine.getCipher().getBlockSize(); } else { return 0; } } public int engineGetKeySize(Key key) { if (key instanceof ECKey) { return ((ECKey)key).getParameters().getCurve().getFieldSize(); } else { throw new IllegalArgumentException("not an EC key"); } } public byte[] engineGetIV() { return null; } public AlgorithmParameters engineGetParameters() { if (engineParam == null && engineSpec != null) { try { engineParam = AlgorithmParameters.getInstance("IES", BouncyCastleProvider.PROVIDER_NAME); engineParam.init(engineSpec); } catch (Exception e) { throw new RuntimeException(e.toString()); } } return engineParam; } public void engineSetMode(String mode) throws NoSuchAlgorithmException { String modeName = Strings.toUpperCase(mode); if (modeName.equals("NONE")) { dhaesMode = false; } else if (modeName.equals("DHAES")) { dhaesMode = true; } else { throw new IllegalArgumentException("can't support mode " + mode); } } public int engineGetOutputSize(int inputLen) { int len1, len2, len3; len1 = engine.getMac().getMacSize(); if (key != null) { len2 = 1 + 2 * (((ECKey)key).getParameters().getCurve().getFieldSize() + 7) / 8; } else { throw new IllegalStateException("cipher not initialised"); } if (engine.getCipher() == null) { len3 = inputLen; } else if (state == Cipher.ENCRYPT_MODE || state == Cipher.WRAP_MODE) { len3 = engine.getCipher().getOutputSize(inputLen); } else if (state == Cipher.DECRYPT_MODE || state == Cipher.UNWRAP_MODE) { len3 = engine.getCipher().getOutputSize(inputLen - len1 - len2); } else { throw new IllegalStateException("cipher not initialised"); } if (state == Cipher.ENCRYPT_MODE || state == Cipher.WRAP_MODE) { return buffer.size() + len1 + len2 + len3; } else if (state == Cipher.DECRYPT_MODE || state == Cipher.UNWRAP_MODE) { return buffer.size() - len1 - len2 + len3; } else { throw new IllegalStateException("cipher not initialised"); } } public void engineSetPadding(String padding) throws NoSuchPaddingException { String paddingName = Strings.toUpperCase(padding); // TDOD: make this meaningful... if (paddingName.equals("NOPADDING")) { } else if (paddingName.equals("PKCS5PADDING") || paddingName.equals("PKCS7PADDING")) { } else { throw new NoSuchPaddingException("padding not available with IESCipher"); } } // Initialisation methods public void engineInit( int opmode, Key key, AlgorithmParameters params, SecureRandom random) throws InvalidKeyException, InvalidAlgorithmParameterException { AlgorithmParameterSpec paramSpec = null; if (params != null) { try { paramSpec = params.getParameterSpec(IESParameterSpec.class); } catch (Exception e) { throw new InvalidAlgorithmParameterException("cannot recognise parameters: " + e.toString()); } } engineParam = params; engineInit(opmode, key, paramSpec, random); } public void engineInit( int opmode, Key key, AlgorithmParameterSpec engineSpec, SecureRandom random) throws InvalidAlgorithmParameterException, InvalidKeyException { otherKeyParameter = null; // Use default parameters (including cipher key size) if none are specified if (engineSpec == null) { this.engineSpec = IESUtil.guessParameterSpec(engine); } else if (engineSpec instanceof IESParameterSpec) { this.engineSpec = (IESParameterSpec)engineSpec; } else { throw new InvalidAlgorithmParameterException("must be passed IES parameters"); } // Parse the recipient's key if (opmode == Cipher.ENCRYPT_MODE || opmode == Cipher.WRAP_MODE) { if (key instanceof ECPublicKey) { this.key = ECUtil.generatePublicKeyParameter((PublicKey)key); } else if (key instanceof IESKey) { IESKey ieKey = (IESKey)key; this.key = ECUtil.generatePublicKeyParameter(ieKey.getPublic()); this.otherKeyParameter = ECUtil.generatePrivateKeyParameter(ieKey.getPrivate()); } else { throw new InvalidKeyException("must be passed recipient's public EC key for encryption"); } } else if (opmode == Cipher.DECRYPT_MODE || opmode == Cipher.UNWRAP_MODE) { if (key instanceof ECPrivateKey) { this.key = ECUtil.generatePrivateKeyParameter((PrivateKey)key); } else if (key instanceof IESKey) { IESKey ieKey = (IESKey)key; this.otherKeyParameter = ECUtil.generatePublicKeyParameter(ieKey.getPublic()); this.key = ECUtil.generatePrivateKeyParameter(ieKey.getPrivate()); } else { throw new InvalidKeyException("must be passed recipient's private EC key for decryption"); } } else { throw new InvalidKeyException("must be passed EC key"); } this.random = random; this.state = opmode; buffer.reset(); } public void engineInit( int opmode, Key key, SecureRandom random) throws InvalidKeyException { try { engineInit(opmode, key, (AlgorithmParameterSpec)null, random); } catch (InvalidAlgorithmParameterException e) { throw new IllegalArgumentException("can't handle supplied parameter spec"); } } // Update methods - buffer the input public byte[] engineUpdate( byte[] input, int inputOffset, int inputLen) { buffer.write(input, inputOffset, inputLen); return null; } public int engineUpdate( byte[] input, int inputOffset, int inputLen, byte[] output, int outputOffset) { buffer.write(input, inputOffset, inputLen); return 0; } // Finalisation methods public byte[] engineDoFinal( byte[] input, int inputOffset, int inputLen) throws IllegalBlockSizeException, BadPaddingException { if (inputLen != 0) { buffer.write(input, inputOffset, inputLen); } final byte[] in = buffer.toByteArray(); buffer.reset(); // Convert parameters for use in IESEngine IESParameters params = new IESWithCipherParameters(engineSpec.getDerivationV(), engineSpec.getEncodingV(), engineSpec.getMacKeySize(), engineSpec.getCipherKeySize()); final ECDomainParameters ecParams = ((ECKeyParameters)key).getParameters(); final byte[] V; if (otherKeyParameter != null) { try { if (state == Cipher.ENCRYPT_MODE || state == Cipher.WRAP_MODE) { engine.init(true, otherKeyParameter, key, params); } else { engine.init(false, key, otherKeyParameter, params); } return engine.processBlock(in, 0, in.length); } catch (Exception e) { throw new BadPaddingException(e.getMessage()); } } if (state == Cipher.ENCRYPT_MODE || state == Cipher.WRAP_MODE) { // Generate the ephemeral key pair ECKeyPairGenerator gen = new ECKeyPairGenerator(); gen.init(new ECKeyGenerationParameters(ecParams, random)); EphemeralKeyPairGenerator kGen = new EphemeralKeyPairGenerator(gen, new KeyEncoder() { public byte[] getEncoded(AsymmetricKeyParameter keyParameter) { return ((ECPublicKeyParameters)keyParameter).getQ().getEncoded(); } }); // Encrypt the buffer try { engine.init(key, params, kGen); return engine.processBlock(in, 0, in.length); } catch (Exception e) { throw new BadPaddingException(e.getMessage()); } } else if (state == Cipher.DECRYPT_MODE || state == Cipher.UNWRAP_MODE) { // Decrypt the buffer try { engine.init(key, params, new ECIESPublicKeyParser(ecParams)); return engine.processBlock(in, 0, in.length); } catch (InvalidCipherTextException e) { throw new BadPaddingException(e.getMessage()); } } else { throw new IllegalStateException("cipher not initialised"); } } public int engineDoFinal( byte[] input, int inputOffset, int inputLength, byte[] output, int outputOffset) throws ShortBufferException, IllegalBlockSizeException, BadPaddingException { byte[] buf = engineDoFinal(input, inputOffset, inputLength); System.arraycopy(buf, 0, output, outputOffset, buf.length); return buf.length; } /** * Classes that inherit from us */ static public class ECIES extends IESCipher { public ECIES() { super(new IESEngine(new ECDHBasicAgreement(), new KDF2BytesGenerator(new SHA1Digest()), new HMac(new SHA1Digest()))); } } static public class ECIESwithDESede extends IESCipher { public ECIESwithDESede() { super(new IESEngine(new ECDHBasicAgreement(), new KDF2BytesGenerator(new SHA1Digest()), new HMac(new SHA1Digest()), new PaddedBufferedBlockCipher(new DESedeEngine()))); } } static public class ECIESwithAES extends IESCipher { public ECIESwithAES() { super(new IESEngine(new ECDHBasicAgreement(), new KDF2BytesGenerator(new SHA1Digest()), new HMac(new SHA1Digest()), new PaddedBufferedBlockCipher(new AESEngine()))); } } } bouncycastle-1.49.orig/src/org/bouncycastle/jcajce/provider/asymmetric/ec/KeyFactorySpi.java0000644000175000017500000001714012110037231031707 0ustar ebourgebourgpackage org.bouncycastle.jcajce.provider.asymmetric.ec; import java.io.IOException; import java.security.InvalidKeyException; import java.security.Key; import java.security.PrivateKey; import java.security.PublicKey; import java.security.interfaces.ECPrivateKey; import java.security.interfaces.ECPublicKey; import java.security.spec.InvalidKeySpecException; import java.security.spec.KeySpec; import org.bouncycastle.asn1.ASN1ObjectIdentifier; import org.bouncycastle.asn1.pkcs.PrivateKeyInfo; import org.bouncycastle.asn1.x509.SubjectPublicKeyInfo; import org.bouncycastle.asn1.x9.X9ObjectIdentifiers; import org.bouncycastle.jcajce.provider.asymmetric.util.BaseKeyFactorySpi; import org.bouncycastle.jcajce.provider.asymmetric.util.EC5Util; import org.bouncycastle.jcajce.provider.config.ProviderConfiguration; import org.bouncycastle.jcajce.provider.util.AsymmetricKeyInfoConverter; import org.bouncycastle.jce.provider.BouncyCastleProvider; import org.bouncycastle.jce.spec.ECParameterSpec; import org.bouncycastle.jce.spec.ECPrivateKeySpec; import org.bouncycastle.jce.spec.ECPublicKeySpec; public class KeyFactorySpi extends BaseKeyFactorySpi implements AsymmetricKeyInfoConverter { String algorithm; ProviderConfiguration configuration; KeyFactorySpi( String algorithm, ProviderConfiguration configuration) { this.algorithm = algorithm; this.configuration = configuration; } protected Key engineTranslateKey( Key key) throws InvalidKeyException { if (key instanceof ECPublicKey) { return new BCECPublicKey((ECPublicKey)key, configuration); } else if (key instanceof ECPrivateKey) { return new BCECPrivateKey((ECPrivateKey)key, configuration); } throw new InvalidKeyException("key type unknown"); } protected KeySpec engineGetKeySpec( Key key, Class spec) throws InvalidKeySpecException { if (spec.isAssignableFrom(java.security.spec.ECPublicKeySpec.class) && key instanceof ECPublicKey) { ECPublicKey k = (ECPublicKey)key; if (k.getParams() != null) { return new java.security.spec.ECPublicKeySpec(k.getW(), k.getParams()); } else { ECParameterSpec implicitSpec = BouncyCastleProvider.CONFIGURATION.getEcImplicitlyCa(); return new java.security.spec.ECPublicKeySpec(k.getW(), EC5Util.convertSpec(EC5Util.convertCurve(implicitSpec.getCurve(), implicitSpec.getSeed()), implicitSpec)); } } else if (spec.isAssignableFrom(java.security.spec.ECPrivateKeySpec.class) && key instanceof ECPrivateKey) { ECPrivateKey k = (ECPrivateKey)key; if (k.getParams() != null) { return new java.security.spec.ECPrivateKeySpec(k.getS(), k.getParams()); } else { ECParameterSpec implicitSpec = BouncyCastleProvider.CONFIGURATION.getEcImplicitlyCa(); return new java.security.spec.ECPrivateKeySpec(k.getS(), EC5Util.convertSpec(EC5Util.convertCurve(implicitSpec.getCurve(), implicitSpec.getSeed()), implicitSpec)); } } else if (spec.isAssignableFrom(org.bouncycastle.jce.spec.ECPublicKeySpec.class) && key instanceof ECPublicKey) { ECPublicKey k = (ECPublicKey)key; if (k.getParams() != null) { return new org.bouncycastle.jce.spec.ECPublicKeySpec(EC5Util.convertPoint(k.getParams(), k.getW(), false), EC5Util.convertSpec(k.getParams(), false)); } else { ECParameterSpec implicitSpec = BouncyCastleProvider.CONFIGURATION.getEcImplicitlyCa(); return new org.bouncycastle.jce.spec.ECPublicKeySpec(EC5Util.convertPoint(k.getParams(), k.getW(), false), implicitSpec); } } else if (spec.isAssignableFrom(org.bouncycastle.jce.spec.ECPrivateKeySpec.class) && key instanceof ECPrivateKey) { ECPrivateKey k = (ECPrivateKey)key; if (k.getParams() != null) { return new org.bouncycastle.jce.spec.ECPrivateKeySpec(k.getS(), EC5Util.convertSpec(k.getParams(), false)); } else { ECParameterSpec implicitSpec = BouncyCastleProvider.CONFIGURATION.getEcImplicitlyCa(); return new org.bouncycastle.jce.spec.ECPrivateKeySpec(k.getS(), implicitSpec); } } return super.engineGetKeySpec(key, spec); } protected PrivateKey engineGeneratePrivate( KeySpec keySpec) throws InvalidKeySpecException { if (keySpec instanceof ECPrivateKeySpec) { return new BCECPrivateKey(algorithm, (ECPrivateKeySpec)keySpec, configuration); } else if (keySpec instanceof java.security.spec.ECPrivateKeySpec) { return new BCECPrivateKey(algorithm, (java.security.spec.ECPrivateKeySpec)keySpec, configuration); } return super.engineGeneratePrivate(keySpec); } protected PublicKey engineGeneratePublic( KeySpec keySpec) throws InvalidKeySpecException { if (keySpec instanceof ECPublicKeySpec) { return new BCECPublicKey(algorithm, (ECPublicKeySpec)keySpec, configuration); } else if (keySpec instanceof java.security.spec.ECPublicKeySpec) { return new BCECPublicKey(algorithm, (java.security.spec.ECPublicKeySpec)keySpec, configuration); } return super.engineGeneratePublic(keySpec); } public PrivateKey generatePrivate(PrivateKeyInfo keyInfo) throws IOException { ASN1ObjectIdentifier algOid = keyInfo.getPrivateKeyAlgorithm().getAlgorithm(); if (algOid.equals(X9ObjectIdentifiers.id_ecPublicKey)) { return new BCECPrivateKey(algorithm, keyInfo, configuration); } else { throw new IOException("algorithm identifier " + algOid + " in key not recognised"); } } public PublicKey generatePublic(SubjectPublicKeyInfo keyInfo) throws IOException { ASN1ObjectIdentifier algOid = keyInfo.getAlgorithm().getAlgorithm(); if (algOid.equals(X9ObjectIdentifiers.id_ecPublicKey)) { return new BCECPublicKey(algorithm, keyInfo, configuration); } else { throw new IOException("algorithm identifier " + algOid + " in key not recognised"); } } public static class EC extends KeyFactorySpi { public EC() { super("EC", BouncyCastleProvider.CONFIGURATION); } } public static class ECDSA extends KeyFactorySpi { public ECDSA() { super("ECDSA", BouncyCastleProvider.CONFIGURATION); } } public static class ECGOST3410 extends KeyFactorySpi { public ECGOST3410() { super("ECGOST3410", BouncyCastleProvider.CONFIGURATION); } } public static class ECDH extends KeyFactorySpi { public ECDH() { super("ECDH", BouncyCastleProvider.CONFIGURATION); } } public static class ECDHC extends KeyFactorySpi { public ECDHC() { super("ECDHC", BouncyCastleProvider.CONFIGURATION); } } public static class ECMQV extends KeyFactorySpi { public ECMQV() { super("ECMQV", BouncyCastleProvider.CONFIGURATION); } } }bouncycastle-1.49.orig/src/org/bouncycastle/jcajce/provider/asymmetric/ec/BCECPrivateKey.java0000644000175000017500000003601112110037231031651 0ustar ebourgebourgpackage org.bouncycastle.jcajce.provider.asymmetric.ec; import java.io.IOException; import java.io.ObjectInputStream; import java.io.ObjectOutputStream; import java.math.BigInteger; import java.security.interfaces.ECPrivateKey; import java.security.spec.ECParameterSpec; import java.security.spec.ECPoint; import java.security.spec.ECPrivateKeySpec; import java.security.spec.EllipticCurve; import java.util.Enumeration; import org.bouncycastle.asn1.ASN1Encodable; import org.bouncycastle.asn1.ASN1Encoding; import org.bouncycastle.asn1.ASN1ObjectIdentifier; import org.bouncycastle.asn1.ASN1Primitive; import org.bouncycastle.asn1.DERBitString; import org.bouncycastle.asn1.DERInteger; import org.bouncycastle.asn1.DERNull; import org.bouncycastle.asn1.DERObjectIdentifier; import org.bouncycastle.asn1.cryptopro.CryptoProObjectIdentifiers; import org.bouncycastle.asn1.cryptopro.ECGOST3410NamedCurves; import org.bouncycastle.asn1.pkcs.PrivateKeyInfo; import org.bouncycastle.asn1.x509.AlgorithmIdentifier; import org.bouncycastle.asn1.x509.SubjectPublicKeyInfo; import org.bouncycastle.asn1.x9.X962Parameters; import org.bouncycastle.asn1.x9.X9ECParameters; import org.bouncycastle.asn1.x9.X9ObjectIdentifiers; import org.bouncycastle.crypto.params.ECDomainParameters; import org.bouncycastle.crypto.params.ECPrivateKeyParameters; import org.bouncycastle.jcajce.provider.asymmetric.util.EC5Util; import org.bouncycastle.jcajce.provider.asymmetric.util.ECUtil; import org.bouncycastle.jcajce.provider.asymmetric.util.PKCS12BagAttributeCarrierImpl; import org.bouncycastle.jcajce.provider.config.ProviderConfiguration; import org.bouncycastle.jce.interfaces.ECPointEncoder; import org.bouncycastle.jce.interfaces.PKCS12BagAttributeCarrier; import org.bouncycastle.jce.provider.BouncyCastleProvider; import org.bouncycastle.jce.spec.ECNamedCurveSpec; import org.bouncycastle.math.ec.ECCurve; public class BCECPrivateKey implements ECPrivateKey, org.bouncycastle.jce.interfaces.ECPrivateKey, PKCS12BagAttributeCarrier, ECPointEncoder { static final long serialVersionUID = 994553197664784084L; private String algorithm = "EC"; private boolean withCompression; private transient BigInteger d; private transient ECParameterSpec ecSpec; private transient ProviderConfiguration configuration; private transient DERBitString publicKey; private transient PKCS12BagAttributeCarrierImpl attrCarrier = new PKCS12BagAttributeCarrierImpl(); protected BCECPrivateKey() { } public BCECPrivateKey( ECPrivateKey key, ProviderConfiguration configuration) { this.d = key.getS(); this.algorithm = key.getAlgorithm(); this.ecSpec = key.getParams(); this.configuration = configuration; } public BCECPrivateKey( String algorithm, org.bouncycastle.jce.spec.ECPrivateKeySpec spec, ProviderConfiguration configuration) { this.algorithm = algorithm; this.d = spec.getD(); if (spec.getParams() != null) // can be null if implicitlyCA { ECCurve curve = spec.getParams().getCurve(); EllipticCurve ellipticCurve; ellipticCurve = EC5Util.convertCurve(curve, spec.getParams().getSeed()); this.ecSpec = EC5Util.convertSpec(ellipticCurve, spec.getParams()); } else { this.ecSpec = null; } this.configuration = configuration; } public BCECPrivateKey( String algorithm, ECPrivateKeySpec spec, ProviderConfiguration configuration) { this.algorithm = algorithm; this.d = spec.getS(); this.ecSpec = spec.getParams(); this.configuration = configuration; } public BCECPrivateKey( String algorithm, BCECPrivateKey key) { this.algorithm = algorithm; this.d = key.d; this.ecSpec = key.ecSpec; this.withCompression = key.withCompression; this.attrCarrier = key.attrCarrier; this.publicKey = key.publicKey; this.configuration = key.configuration; } public BCECPrivateKey( String algorithm, ECPrivateKeyParameters params, BCECPublicKey pubKey, ECParameterSpec spec, ProviderConfiguration configuration) { ECDomainParameters dp = params.getParameters(); this.algorithm = algorithm; this.d = params.getD(); this.configuration = configuration; if (spec == null) { EllipticCurve ellipticCurve = EC5Util.convertCurve(dp.getCurve(), dp.getSeed()); this.ecSpec = new ECParameterSpec( ellipticCurve, new ECPoint( dp.getG().getX().toBigInteger(), dp.getG().getY().toBigInteger()), dp.getN(), dp.getH().intValue()); } else { this.ecSpec = spec; } publicKey = getPublicKeyDetails(pubKey); } public BCECPrivateKey( String algorithm, ECPrivateKeyParameters params, BCECPublicKey pubKey, org.bouncycastle.jce.spec.ECParameterSpec spec, ProviderConfiguration configuration) { ECDomainParameters dp = params.getParameters(); this.algorithm = algorithm; this.d = params.getD(); this.configuration = configuration; if (spec == null) { EllipticCurve ellipticCurve = EC5Util.convertCurve(dp.getCurve(), dp.getSeed()); this.ecSpec = new ECParameterSpec( ellipticCurve, new ECPoint( dp.getG().getX().toBigInteger(), dp.getG().getY().toBigInteger()), dp.getN(), dp.getH().intValue()); } else { EllipticCurve ellipticCurve = EC5Util.convertCurve(spec.getCurve(), spec.getSeed()); this.ecSpec = new ECParameterSpec( ellipticCurve, new ECPoint( spec.getG().getX().toBigInteger(), spec.getG().getY().toBigInteger()), spec.getN(), spec.getH().intValue()); } publicKey = getPublicKeyDetails(pubKey); } public BCECPrivateKey( String algorithm, ECPrivateKeyParameters params, ProviderConfiguration configuration) { this.algorithm = algorithm; this.d = params.getD(); this.ecSpec = null; this.configuration = configuration; } BCECPrivateKey( String algorithm, PrivateKeyInfo info, ProviderConfiguration configuration) throws IOException { this.algorithm = algorithm; this.configuration = configuration; populateFromPrivKeyInfo(info); } private void populateFromPrivKeyInfo(PrivateKeyInfo info) throws IOException { X962Parameters params = X962Parameters.getInstance(info.getPrivateKeyAlgorithm().getParameters()); if (params.isNamedCurve()) { ASN1ObjectIdentifier oid = ASN1ObjectIdentifier.getInstance(params.getParameters()); X9ECParameters ecP = ECUtil.getNamedCurveByOid(oid); if (ecP == null) // GOST Curve { ECDomainParameters gParam = ECGOST3410NamedCurves.getByOID(oid); EllipticCurve ellipticCurve = EC5Util.convertCurve(gParam.getCurve(), gParam.getSeed()); ecSpec = new ECNamedCurveSpec( ECGOST3410NamedCurves.getName(oid), ellipticCurve, new ECPoint( gParam.getG().getX().toBigInteger(), gParam.getG().getY().toBigInteger()), gParam.getN(), gParam.getH()); } else { EllipticCurve ellipticCurve = EC5Util.convertCurve(ecP.getCurve(), ecP.getSeed()); ecSpec = new ECNamedCurveSpec( ECUtil.getCurveName(oid), ellipticCurve, new ECPoint( ecP.getG().getX().toBigInteger(), ecP.getG().getY().toBigInteger()), ecP.getN(), ecP.getH()); } } else if (params.isImplicitlyCA()) { ecSpec = null; } else { X9ECParameters ecP = X9ECParameters.getInstance(params.getParameters()); EllipticCurve ellipticCurve = EC5Util.convertCurve(ecP.getCurve(), ecP.getSeed()); this.ecSpec = new ECParameterSpec( ellipticCurve, new ECPoint( ecP.getG().getX().toBigInteger(), ecP.getG().getY().toBigInteger()), ecP.getN(), ecP.getH().intValue()); } ASN1Encodable privKey = info.parsePrivateKey(); if (privKey instanceof DERInteger) { DERInteger derD = DERInteger.getInstance(privKey); this.d = derD.getValue(); } else { org.bouncycastle.asn1.sec.ECPrivateKey ec = org.bouncycastle.asn1.sec.ECPrivateKey.getInstance(privKey); this.d = ec.getKey(); this.publicKey = ec.getPublicKey(); } } public String getAlgorithm() { return algorithm; } /** * return the encoding format we produce in getEncoded(). * * @return the string "PKCS#8" */ public String getFormat() { return "PKCS#8"; } /** * Return a PKCS8 representation of the key. The sequence returned * represents a full PrivateKeyInfo object. * * @return a PKCS8 representation of the key. */ public byte[] getEncoded() { X962Parameters params; if (ecSpec instanceof ECNamedCurveSpec) { DERObjectIdentifier curveOid = ECUtil.getNamedCurveOid(((ECNamedCurveSpec)ecSpec).getName()); if (curveOid == null) // guess it's the OID { curveOid = new DERObjectIdentifier(((ECNamedCurveSpec)ecSpec).getName()); } params = new X962Parameters(curveOid); } else if (ecSpec == null) { params = new X962Parameters(DERNull.INSTANCE); } else { ECCurve curve = EC5Util.convertCurve(ecSpec.getCurve()); X9ECParameters ecP = new X9ECParameters( curve, EC5Util.convertPoint(curve, ecSpec.getGenerator(), withCompression), ecSpec.getOrder(), BigInteger.valueOf(ecSpec.getCofactor()), ecSpec.getCurve().getSeed()); params = new X962Parameters(ecP); } PrivateKeyInfo info; org.bouncycastle.asn1.sec.ECPrivateKey keyStructure; if (publicKey != null) { keyStructure = new org.bouncycastle.asn1.sec.ECPrivateKey(this.getS(), publicKey, params); } else { keyStructure = new org.bouncycastle.asn1.sec.ECPrivateKey(this.getS(), params); } try { if (algorithm.equals("ECGOST3410")) { info = new PrivateKeyInfo(new AlgorithmIdentifier(CryptoProObjectIdentifiers.gostR3410_2001, params.toASN1Primitive()), keyStructure.toASN1Primitive()); } else { info = new PrivateKeyInfo(new AlgorithmIdentifier(X9ObjectIdentifiers.id_ecPublicKey, params.toASN1Primitive()), keyStructure.toASN1Primitive()); } return info.getEncoded(ASN1Encoding.DER); } catch (IOException e) { return null; } } public ECParameterSpec getParams() { return ecSpec; } public org.bouncycastle.jce.spec.ECParameterSpec getParameters() { if (ecSpec == null) { return null; } return EC5Util.convertSpec(ecSpec, withCompression); } org.bouncycastle.jce.spec.ECParameterSpec engineGetSpec() { if (ecSpec != null) { return EC5Util.convertSpec(ecSpec, withCompression); } return configuration.getEcImplicitlyCa(); } public BigInteger getS() { return d; } public BigInteger getD() { return d; } public void setBagAttribute( ASN1ObjectIdentifier oid, ASN1Encodable attribute) { attrCarrier.setBagAttribute(oid, attribute); } public ASN1Encodable getBagAttribute( ASN1ObjectIdentifier oid) { return attrCarrier.getBagAttribute(oid); } public Enumeration getBagAttributeKeys() { return attrCarrier.getBagAttributeKeys(); } public void setPointFormat(String style) { withCompression = !("UNCOMPRESSED".equalsIgnoreCase(style)); } public boolean equals(Object o) { if (!(o instanceof BCECPrivateKey)) { return false; } BCECPrivateKey other = (BCECPrivateKey)o; return getD().equals(other.getD()) && (engineGetSpec().equals(other.engineGetSpec())); } public int hashCode() { return getD().hashCode() ^ engineGetSpec().hashCode(); } public String toString() { StringBuffer buf = new StringBuffer(); String nl = System.getProperty("line.separator"); buf.append("EC Private Key").append(nl); buf.append(" S: ").append(this.d.toString(16)).append(nl); return buf.toString(); } private DERBitString getPublicKeyDetails(BCECPublicKey pub) { try { SubjectPublicKeyInfo info = SubjectPublicKeyInfo.getInstance(ASN1Primitive.fromByteArray(pub.getEncoded())); return info.getPublicKeyData(); } catch (IOException e) { // should never happen return null; } } private void readObject( ObjectInputStream in) throws IOException, ClassNotFoundException { in.defaultReadObject(); byte[] enc = (byte[])in.readObject(); populateFromPrivKeyInfo(PrivateKeyInfo.getInstance(ASN1Primitive.fromByteArray(enc))); this.configuration = BouncyCastleProvider.CONFIGURATION; this.attrCarrier = new PKCS12BagAttributeCarrierImpl(); } private void writeObject( ObjectOutputStream out) throws IOException { out.defaultWriteObject(); out.writeObject(this.getEncoded()); } } bouncycastle-1.49.orig/src/org/bouncycastle/jcajce/provider/asymmetric/ec/KeyAgreementSpi.java0000644000175000017500000002461012110037231032207 0ustar ebourgebourgpackage org.bouncycastle.jcajce.provider.asymmetric.ec; import java.math.BigInteger; import java.security.InvalidAlgorithmParameterException; import java.security.InvalidKeyException; import java.security.Key; import java.security.NoSuchAlgorithmException; import java.security.PrivateKey; import java.security.PublicKey; import java.security.SecureRandom; import java.security.spec.AlgorithmParameterSpec; import java.util.Hashtable; import javax.crypto.SecretKey; import javax.crypto.ShortBufferException; import javax.crypto.spec.SecretKeySpec; import org.bouncycastle.asn1.DERObjectIdentifier; import org.bouncycastle.asn1.nist.NISTObjectIdentifiers; import org.bouncycastle.asn1.pkcs.PKCSObjectIdentifiers; import org.bouncycastle.asn1.x9.X9IntegerConverter; import org.bouncycastle.crypto.BasicAgreement; import org.bouncycastle.crypto.CipherParameters; import org.bouncycastle.crypto.DerivationFunction; import org.bouncycastle.crypto.agreement.ECDHBasicAgreement; import org.bouncycastle.crypto.agreement.ECDHCBasicAgreement; import org.bouncycastle.crypto.agreement.ECMQVBasicAgreement; import org.bouncycastle.crypto.agreement.kdf.DHKDFParameters; import org.bouncycastle.crypto.agreement.kdf.ECDHKEKGenerator; import org.bouncycastle.crypto.digests.SHA1Digest; import org.bouncycastle.crypto.params.ECDomainParameters; import org.bouncycastle.crypto.params.ECPrivateKeyParameters; import org.bouncycastle.crypto.params.ECPublicKeyParameters; import org.bouncycastle.crypto.params.MQVPrivateParameters; import org.bouncycastle.crypto.params.MQVPublicParameters; import org.bouncycastle.jcajce.provider.asymmetric.util.ECUtil; import org.bouncycastle.jce.interfaces.ECPrivateKey; import org.bouncycastle.jce.interfaces.ECPublicKey; import org.bouncycastle.jce.interfaces.MQVPrivateKey; import org.bouncycastle.jce.interfaces.MQVPublicKey; import org.bouncycastle.util.Integers; /** * Diffie-Hellman key agreement using elliptic curve keys, ala IEEE P1363 * both the simple one, and the simple one with cofactors are supported. * * Also, MQV key agreement per SEC-1 */ public class KeyAgreementSpi extends javax.crypto.KeyAgreementSpi { private static final X9IntegerConverter converter = new X9IntegerConverter(); private static final Hashtable algorithms = new Hashtable(); static { Integer i128 = Integers.valueOf(128); Integer i192 = Integers.valueOf(192); Integer i256 = Integers.valueOf(256); algorithms.put(NISTObjectIdentifiers.id_aes128_CBC.getId(), i128); algorithms.put(NISTObjectIdentifiers.id_aes192_CBC.getId(), i192); algorithms.put(NISTObjectIdentifiers.id_aes256_CBC.getId(), i256); algorithms.put(NISTObjectIdentifiers.id_aes128_wrap.getId(), i128); algorithms.put(NISTObjectIdentifiers.id_aes192_wrap.getId(), i192); algorithms.put(NISTObjectIdentifiers.id_aes256_wrap.getId(), i256); algorithms.put(PKCSObjectIdentifiers.id_alg_CMS3DESwrap.getId(), i192); } private String kaAlgorithm; private BigInteger result; private ECDomainParameters parameters; private BasicAgreement agreement; private DerivationFunction kdf; private byte[] bigIntToBytes( BigInteger r) { return converter.integerToBytes(r, converter.getByteLength(parameters.getG().getX())); } protected KeyAgreementSpi( String kaAlgorithm, BasicAgreement agreement, DerivationFunction kdf) { this.kaAlgorithm = kaAlgorithm; this.agreement = agreement; this.kdf = kdf; } protected Key engineDoPhase( Key key, boolean lastPhase) throws InvalidKeyException, IllegalStateException { if (parameters == null) { throw new IllegalStateException(kaAlgorithm + " not initialised."); } if (!lastPhase) { throw new IllegalStateException(kaAlgorithm + " can only be between two parties."); } CipherParameters pubKey; if (agreement instanceof ECMQVBasicAgreement) { if (!(key instanceof MQVPublicKey)) { throw new InvalidKeyException(kaAlgorithm + " key agreement requires " + getSimpleName(MQVPublicKey.class) + " for doPhase"); } MQVPublicKey mqvPubKey = (MQVPublicKey)key; ECPublicKeyParameters staticKey = (ECPublicKeyParameters) ECUtil.generatePublicKeyParameter(mqvPubKey.getStaticKey()); ECPublicKeyParameters ephemKey = (ECPublicKeyParameters) ECUtil.generatePublicKeyParameter(mqvPubKey.getEphemeralKey()); pubKey = new MQVPublicParameters(staticKey, ephemKey); // TODO Validate that all the keys are using the same parameters? } else { if (!(key instanceof PublicKey)) { throw new InvalidKeyException(kaAlgorithm + " key agreement requires " + getSimpleName(ECPublicKey.class) + " for doPhase"); } pubKey = ECUtil.generatePublicKeyParameter((PublicKey)key); // TODO Validate that all the keys are using the same parameters? } result = agreement.calculateAgreement(pubKey); return null; } protected byte[] engineGenerateSecret() throws IllegalStateException { if (kdf != null) { throw new UnsupportedOperationException( "KDF can only be used when algorithm is known"); } return bigIntToBytes(result); } protected int engineGenerateSecret( byte[] sharedSecret, int offset) throws IllegalStateException, ShortBufferException { byte[] secret = engineGenerateSecret(); if (sharedSecret.length - offset < secret.length) { throw new ShortBufferException(kaAlgorithm + " key agreement: need " + secret.length + " bytes"); } System.arraycopy(secret, 0, sharedSecret, offset, secret.length); return secret.length; } protected SecretKey engineGenerateSecret( String algorithm) throws NoSuchAlgorithmException { byte[] secret = bigIntToBytes(result); if (kdf != null) { if (!algorithms.containsKey(algorithm)) { throw new NoSuchAlgorithmException("unknown algorithm encountered: " + algorithm); } int keySize = ((Integer)algorithms.get(algorithm)).intValue(); DHKDFParameters params = new DHKDFParameters(new DERObjectIdentifier(algorithm), keySize, secret); byte[] keyBytes = new byte[keySize / 8]; kdf.init(params); kdf.generateBytes(keyBytes, 0, keyBytes.length); secret = keyBytes; } else { // TODO Should we be ensuring the key is the right length? } return new SecretKeySpec(secret, algorithm); } protected void engineInit( Key key, AlgorithmParameterSpec params, SecureRandom random) throws InvalidKeyException, InvalidAlgorithmParameterException { initFromKey(key); } protected void engineInit( Key key, SecureRandom random) throws InvalidKeyException { initFromKey(key); } private void initFromKey(Key key) throws InvalidKeyException { if (agreement instanceof ECMQVBasicAgreement) { if (!(key instanceof MQVPrivateKey)) { throw new InvalidKeyException(kaAlgorithm + " key agreement requires " + getSimpleName(MQVPrivateKey.class) + " for initialisation"); } MQVPrivateKey mqvPrivKey = (MQVPrivateKey)key; ECPrivateKeyParameters staticPrivKey = (ECPrivateKeyParameters) ECUtil.generatePrivateKeyParameter(mqvPrivKey.getStaticPrivateKey()); ECPrivateKeyParameters ephemPrivKey = (ECPrivateKeyParameters) ECUtil.generatePrivateKeyParameter(mqvPrivKey.getEphemeralPrivateKey()); ECPublicKeyParameters ephemPubKey = null; if (mqvPrivKey.getEphemeralPublicKey() != null) { ephemPubKey = (ECPublicKeyParameters) ECUtil.generatePublicKeyParameter(mqvPrivKey.getEphemeralPublicKey()); } MQVPrivateParameters localParams = new MQVPrivateParameters(staticPrivKey, ephemPrivKey, ephemPubKey); this.parameters = staticPrivKey.getParameters(); // TODO Validate that all the keys are using the same parameters? agreement.init(localParams); } else { if (!(key instanceof PrivateKey)) { throw new InvalidKeyException(kaAlgorithm + " key agreement requires " + getSimpleName(ECPrivateKey.class) + " for initialisation"); } ECPrivateKeyParameters privKey = (ECPrivateKeyParameters)ECUtil.generatePrivateKeyParameter((PrivateKey)key); this.parameters = privKey.getParameters(); agreement.init(privKey); } } private static String getSimpleName(Class clazz) { String fullName = clazz.getName(); return fullName.substring(fullName.lastIndexOf('.') + 1); } public static class DH extends KeyAgreementSpi { public DH() { super("ECDH", new ECDHBasicAgreement(), null); } } public static class DHC extends KeyAgreementSpi { public DHC() { super("ECDHC", new ECDHCBasicAgreement(), null); } } public static class MQV extends KeyAgreementSpi { public MQV() { super("ECMQV", new ECMQVBasicAgreement(), null); } } public static class DHwithSHA1KDF extends KeyAgreementSpi { public DHwithSHA1KDF() { super("ECDHwithSHA1KDF", new ECDHBasicAgreement(), new ECDHKEKGenerator(new SHA1Digest())); } } public static class MQVwithSHA1KDF extends KeyAgreementSpi { public MQVwithSHA1KDF() { super("ECMQVwithSHA1KDF", new ECMQVBasicAgreement(), new ECDHKEKGenerator(new SHA1Digest())); } } } bouncycastle-1.49.orig/src/org/bouncycastle/jcajce/provider/asymmetric/ec/BCECPublicKey.java0000644000175000017500000003250412110037231031460 0ustar ebourgebourgpackage org.bouncycastle.jcajce.provider.asymmetric.ec; import java.io.IOException; import java.io.ObjectInputStream; import java.io.ObjectOutputStream; import java.math.BigInteger; import java.security.interfaces.ECPublicKey; import java.security.spec.ECParameterSpec; import java.security.spec.ECPoint; import java.security.spec.ECPublicKeySpec; import java.security.spec.EllipticCurve; import org.bouncycastle.asn1.ASN1Encodable; import org.bouncycastle.asn1.ASN1ObjectIdentifier; import org.bouncycastle.asn1.ASN1OctetString; import org.bouncycastle.asn1.ASN1Primitive; import org.bouncycastle.asn1.DERBitString; import org.bouncycastle.asn1.DERNull; import org.bouncycastle.asn1.DEROctetString; import org.bouncycastle.asn1.x509.AlgorithmIdentifier; import org.bouncycastle.asn1.x509.SubjectPublicKeyInfo; import org.bouncycastle.asn1.x9.X962Parameters; import org.bouncycastle.asn1.x9.X9ECParameters; import org.bouncycastle.asn1.x9.X9ECPoint; import org.bouncycastle.asn1.x9.X9IntegerConverter; import org.bouncycastle.asn1.x9.X9ObjectIdentifiers; import org.bouncycastle.crypto.params.ECDomainParameters; import org.bouncycastle.crypto.params.ECPublicKeyParameters; import org.bouncycastle.jcajce.provider.asymmetric.util.EC5Util; import org.bouncycastle.jcajce.provider.asymmetric.util.ECUtil; import org.bouncycastle.jcajce.provider.asymmetric.util.KeyUtil; import org.bouncycastle.jcajce.provider.config.ProviderConfiguration; import org.bouncycastle.jce.interfaces.ECPointEncoder; import org.bouncycastle.jce.provider.BouncyCastleProvider; import org.bouncycastle.jce.spec.ECNamedCurveSpec; import org.bouncycastle.math.ec.ECCurve; public class BCECPublicKey implements ECPublicKey, org.bouncycastle.jce.interfaces.ECPublicKey, ECPointEncoder { static final long serialVersionUID = 2422789860422731812L; private String algorithm = "EC"; private boolean withCompression; private transient org.bouncycastle.math.ec.ECPoint q; private transient ECParameterSpec ecSpec; private transient ProviderConfiguration configuration; public BCECPublicKey( String algorithm, BCECPublicKey key) { this.algorithm = algorithm; this.q = key.q; this.ecSpec = key.ecSpec; this.withCompression = key.withCompression; this.configuration = key.configuration; } public BCECPublicKey( String algorithm, ECPublicKeySpec spec, ProviderConfiguration configuration) { this.algorithm = algorithm; this.ecSpec = spec.getParams(); this.q = EC5Util.convertPoint(ecSpec, spec.getW(), false); this.configuration = configuration; } public BCECPublicKey( String algorithm, org.bouncycastle.jce.spec.ECPublicKeySpec spec, ProviderConfiguration configuration) { this.algorithm = algorithm; this.q = spec.getQ(); if (spec.getParams() != null) // can be null if implictlyCa { ECCurve curve = spec.getParams().getCurve(); EllipticCurve ellipticCurve = EC5Util.convertCurve(curve, spec.getParams().getSeed()); this.ecSpec = EC5Util.convertSpec(ellipticCurve, spec.getParams()); } else { if (q.getCurve() == null) { org.bouncycastle.jce.spec.ECParameterSpec s = configuration.getEcImplicitlyCa(); q = s.getCurve().createPoint(q.getX().toBigInteger(), q.getY().toBigInteger(), false); } this.ecSpec = null; } this.configuration = configuration; } public BCECPublicKey( String algorithm, ECPublicKeyParameters params, ECParameterSpec spec, ProviderConfiguration configuration) { ECDomainParameters dp = params.getParameters(); this.algorithm = algorithm; this.q = params.getQ(); if (spec == null) { EllipticCurve ellipticCurve = EC5Util.convertCurve(dp.getCurve(), dp.getSeed()); this.ecSpec = createSpec(ellipticCurve, dp); } else { this.ecSpec = spec; } this.configuration = configuration; } public BCECPublicKey( String algorithm, ECPublicKeyParameters params, org.bouncycastle.jce.spec.ECParameterSpec spec, ProviderConfiguration configuration) { ECDomainParameters dp = params.getParameters(); this.algorithm = algorithm; this.q = params.getQ(); if (spec == null) { EllipticCurve ellipticCurve = EC5Util.convertCurve(dp.getCurve(), dp.getSeed()); this.ecSpec = createSpec(ellipticCurve, dp); } else { EllipticCurve ellipticCurve = EC5Util.convertCurve(spec.getCurve(), spec.getSeed()); this.ecSpec = EC5Util.convertSpec(ellipticCurve, spec); } this.configuration = configuration; } /* * called for implicitCA */ public BCECPublicKey( String algorithm, ECPublicKeyParameters params, ProviderConfiguration configuration) { this.algorithm = algorithm; this.q = params.getQ(); this.ecSpec = null; this.configuration = configuration; } public BCECPublicKey( ECPublicKey key, ProviderConfiguration configuration) { this.algorithm = key.getAlgorithm(); this.ecSpec = key.getParams(); this.q = EC5Util.convertPoint(this.ecSpec, key.getW(), false); } BCECPublicKey( String algorithm, SubjectPublicKeyInfo info, ProviderConfiguration configuration) { this.algorithm = algorithm; this.configuration = configuration; populateFromPubKeyInfo(info); } private ECParameterSpec createSpec(EllipticCurve ellipticCurve, ECDomainParameters dp) { return new ECParameterSpec( ellipticCurve, new ECPoint( dp.getG().getX().toBigInteger(), dp.getG().getY().toBigInteger()), dp.getN(), dp.getH().intValue()); } private void populateFromPubKeyInfo(SubjectPublicKeyInfo info) { X962Parameters params = new X962Parameters((ASN1Primitive)info.getAlgorithm().getParameters()); ECCurve curve; EllipticCurve ellipticCurve; if (params.isNamedCurve()) { ASN1ObjectIdentifier oid = (ASN1ObjectIdentifier)params.getParameters(); X9ECParameters ecP = ECUtil.getNamedCurveByOid(oid); curve = ecP.getCurve(); ellipticCurve = EC5Util.convertCurve(curve, ecP.getSeed()); ecSpec = new ECNamedCurveSpec( ECUtil.getCurveName(oid), ellipticCurve, new ECPoint( ecP.getG().getX().toBigInteger(), ecP.getG().getY().toBigInteger()), ecP.getN(), ecP.getH()); } else if (params.isImplicitlyCA()) { ecSpec = null; curve = configuration.getEcImplicitlyCa().getCurve(); } else { X9ECParameters ecP = X9ECParameters.getInstance(params.getParameters()); curve = ecP.getCurve(); ellipticCurve = EC5Util.convertCurve(curve, ecP.getSeed()); this.ecSpec = new ECParameterSpec( ellipticCurve, new ECPoint( ecP.getG().getX().toBigInteger(), ecP.getG().getY().toBigInteger()), ecP.getN(), ecP.getH().intValue()); } DERBitString bits = info.getPublicKeyData(); byte[] data = bits.getBytes(); ASN1OctetString key = new DEROctetString(data); // // extra octet string - one of our old certs... // if (data[0] == 0x04 && data[1] == data.length - 2 && (data[2] == 0x02 || data[2] == 0x03)) { int qLength = new X9IntegerConverter().getByteLength(curve); if (qLength >= data.length - 3) { try { key = (ASN1OctetString) ASN1Primitive.fromByteArray(data); } catch (IOException ex) { throw new IllegalArgumentException("error recovering public key"); } } } X9ECPoint derQ = new X9ECPoint(curve, key); this.q = derQ.getPoint(); } public String getAlgorithm() { return algorithm; } public String getFormat() { return "X.509"; } public byte[] getEncoded() { ASN1Encodable params; SubjectPublicKeyInfo info; if (ecSpec instanceof ECNamedCurveSpec) { ASN1ObjectIdentifier curveOid = ECUtil.getNamedCurveOid(((ECNamedCurveSpec)ecSpec).getName()); if (curveOid == null) { curveOid = new ASN1ObjectIdentifier(((ECNamedCurveSpec)ecSpec).getName()); } params = new X962Parameters(curveOid); } else if (ecSpec == null) { params = new X962Parameters(DERNull.INSTANCE); } else { ECCurve curve = EC5Util.convertCurve(ecSpec.getCurve()); X9ECParameters ecP = new X9ECParameters( curve, EC5Util.convertPoint(curve, ecSpec.getGenerator(), withCompression), ecSpec.getOrder(), BigInteger.valueOf(ecSpec.getCofactor()), ecSpec.getCurve().getSeed()); params = new X962Parameters(ecP); } ECCurve curve = this.engineGetQ().getCurve(); ASN1OctetString p = (ASN1OctetString) new X9ECPoint(curve.createPoint(this.getQ().getX().toBigInteger(), this.getQ().getY().toBigInteger(), withCompression)).toASN1Primitive(); info = new SubjectPublicKeyInfo(new AlgorithmIdentifier(X9ObjectIdentifiers.id_ecPublicKey, params), p.getOctets()); return KeyUtil.getEncodedSubjectPublicKeyInfo(info); } private void extractBytes(byte[] encKey, int offSet, BigInteger bI) { byte[] val = bI.toByteArray(); if (val.length < 32) { byte[] tmp = new byte[32]; System.arraycopy(val, 0, tmp, tmp.length - val.length, val.length); val = tmp; } for (int i = 0; i != 32; i++) { encKey[offSet + i] = val[val.length - 1 - i]; } } public ECParameterSpec getParams() { return ecSpec; } public org.bouncycastle.jce.spec.ECParameterSpec getParameters() { if (ecSpec == null) // implictlyCA { return null; } return EC5Util.convertSpec(ecSpec, withCompression); } public ECPoint getW() { return new ECPoint(q.getX().toBigInteger(), q.getY().toBigInteger()); } public org.bouncycastle.math.ec.ECPoint getQ() { if (ecSpec == null) { if (q instanceof org.bouncycastle.math.ec.ECPoint.Fp) { return new org.bouncycastle.math.ec.ECPoint.Fp(null, q.getX(), q.getY()); } else { return new org.bouncycastle.math.ec.ECPoint.F2m(null, q.getX(), q.getY()); } } return q; } public org.bouncycastle.math.ec.ECPoint engineGetQ() { return q; } org.bouncycastle.jce.spec.ECParameterSpec engineGetSpec() { if (ecSpec != null) { return EC5Util.convertSpec(ecSpec, withCompression); } return configuration.getEcImplicitlyCa(); } public String toString() { StringBuffer buf = new StringBuffer(); String nl = System.getProperty("line.separator"); buf.append("EC Public Key").append(nl); buf.append(" X: ").append(this.q.getX().toBigInteger().toString(16)).append(nl); buf.append(" Y: ").append(this.q.getY().toBigInteger().toString(16)).append(nl); return buf.toString(); } public void setPointFormat(String style) { withCompression = !("UNCOMPRESSED".equalsIgnoreCase(style)); } public boolean equals(Object o) { if (!(o instanceof BCECPublicKey)) { return false; } BCECPublicKey other = (BCECPublicKey)o; return engineGetQ().equals(other.engineGetQ()) && (engineGetSpec().equals(other.engineGetSpec())); } public int hashCode() { return engineGetQ().hashCode() ^ engineGetSpec().hashCode(); } private void readObject( ObjectInputStream in) throws IOException, ClassNotFoundException { in.defaultReadObject(); byte[] enc = (byte[])in.readObject(); populateFromPubKeyInfo(SubjectPublicKeyInfo.getInstance(ASN1Primitive.fromByteArray(enc))); this.configuration = BouncyCastleProvider.CONFIGURATION; } private void writeObject( ObjectOutputStream out) throws IOException { out.defaultWriteObject(); out.writeObject(this.getEncoded()); } } bouncycastle-1.49.orig/src/org/bouncycastle/jcajce/provider/asymmetric/ec/KeyPairGeneratorSpi.java0000644000175000017500000002631512110037231033046 0ustar ebourgebourgpackage org.bouncycastle.jcajce.provider.asymmetric.ec; import java.math.BigInteger; import java.security.InvalidAlgorithmParameterException; import java.security.InvalidParameterException; import java.security.KeyPair; import java.security.SecureRandom; import java.security.spec.AlgorithmParameterSpec; import java.security.spec.ECGenParameterSpec; import java.util.Hashtable; import org.bouncycastle.asn1.ASN1ObjectIdentifier; import org.bouncycastle.asn1.nist.NISTNamedCurves; import org.bouncycastle.asn1.sec.SECNamedCurves; import org.bouncycastle.asn1.teletrust.TeleTrusTNamedCurves; import org.bouncycastle.asn1.x9.X962NamedCurves; import org.bouncycastle.asn1.x9.X9ECParameters; import org.bouncycastle.crypto.AsymmetricCipherKeyPair; import org.bouncycastle.crypto.generators.ECKeyPairGenerator; import org.bouncycastle.crypto.params.ECDomainParameters; import org.bouncycastle.crypto.params.ECKeyGenerationParameters; import org.bouncycastle.crypto.params.ECPrivateKeyParameters; import org.bouncycastle.crypto.params.ECPublicKeyParameters; import org.bouncycastle.jcajce.provider.asymmetric.util.EC5Util; import org.bouncycastle.jcajce.provider.config.ProviderConfiguration; import org.bouncycastle.jce.provider.BouncyCastleProvider; import org.bouncycastle.jce.spec.ECNamedCurveGenParameterSpec; import org.bouncycastle.jce.spec.ECNamedCurveSpec; import org.bouncycastle.jce.spec.ECParameterSpec; import org.bouncycastle.math.ec.ECCurve; import org.bouncycastle.math.ec.ECPoint; import org.bouncycastle.util.Integers; public abstract class KeyPairGeneratorSpi extends java.security.KeyPairGenerator { public KeyPairGeneratorSpi(String algorithmName) { super(algorithmName); } public static class EC extends KeyPairGeneratorSpi { ECKeyGenerationParameters param; ECKeyPairGenerator engine = new ECKeyPairGenerator(); Object ecParams = null; int strength = 239; int certainty = 50; SecureRandom random = new SecureRandom(); boolean initialised = false; String algorithm; ProviderConfiguration configuration; static private Hashtable ecParameters; static { ecParameters = new Hashtable(); ecParameters.put(Integers.valueOf(192), new ECGenParameterSpec("prime192v1")); // a.k.a P-192 ecParameters.put(Integers.valueOf(239), new ECGenParameterSpec("prime239v1")); ecParameters.put(Integers.valueOf(256), new ECGenParameterSpec("prime256v1")); // a.k.a P-256 ecParameters.put(Integers.valueOf(224), new ECGenParameterSpec("P-224")); ecParameters.put(Integers.valueOf(384), new ECGenParameterSpec("P-384")); ecParameters.put(Integers.valueOf(521), new ECGenParameterSpec("P-521")); } public EC() { super("EC"); this.algorithm = "EC"; this.configuration = BouncyCastleProvider.CONFIGURATION; } public EC( String algorithm, ProviderConfiguration configuration) { super(algorithm); this.algorithm = algorithm; this.configuration = configuration; } public void initialize( int strength, SecureRandom random) { this.strength = strength; this.random = random; ECGenParameterSpec ecParams = (ECGenParameterSpec)ecParameters.get(Integers.valueOf(strength)); if (ecParams != null) { try { initialize(ecParams, random); } catch (InvalidAlgorithmParameterException e) { throw new InvalidParameterException("key size not configurable."); } } else { throw new InvalidParameterException("unknown key size."); } } public void initialize( AlgorithmParameterSpec params, SecureRandom random) throws InvalidAlgorithmParameterException { if (params instanceof ECParameterSpec) { ECParameterSpec p = (ECParameterSpec)params; this.ecParams = params; param = new ECKeyGenerationParameters(new ECDomainParameters(p.getCurve(), p.getG(), p.getN()), random); engine.init(param); initialised = true; } else if (params instanceof java.security.spec.ECParameterSpec) { java.security.spec.ECParameterSpec p = (java.security.spec.ECParameterSpec)params; this.ecParams = params; ECCurve curve = EC5Util.convertCurve(p.getCurve()); ECPoint g = EC5Util.convertPoint(curve, p.getGenerator(), false); param = new ECKeyGenerationParameters(new ECDomainParameters(curve, g, p.getOrder(), BigInteger.valueOf(p.getCofactor())), random); engine.init(param); initialised = true; } else if (params instanceof ECGenParameterSpec || params instanceof ECNamedCurveGenParameterSpec) { String curveName; if (params instanceof ECGenParameterSpec) { curveName = ((ECGenParameterSpec)params).getName(); } else { curveName = ((ECNamedCurveGenParameterSpec)params).getName(); } X9ECParameters ecP = X962NamedCurves.getByName(curveName); if (ecP == null) { ecP = SECNamedCurves.getByName(curveName); if (ecP == null) { ecP = NISTNamedCurves.getByName(curveName); } if (ecP == null) { ecP = TeleTrusTNamedCurves.getByName(curveName); } if (ecP == null) { // See if it's actually an OID string (SunJSSE ServerHandshaker setupEphemeralECDHKeys bug) try { ASN1ObjectIdentifier oid = new ASN1ObjectIdentifier(curveName); ecP = X962NamedCurves.getByOID(oid); if (ecP == null) { ecP = SECNamedCurves.getByOID(oid); } if (ecP == null) { ecP = NISTNamedCurves.getByOID(oid); } if (ecP == null) { ecP = TeleTrusTNamedCurves.getByOID(oid); } if (ecP == null) { throw new InvalidAlgorithmParameterException("unknown curve OID: " + curveName); } } catch (IllegalArgumentException ex) { throw new InvalidAlgorithmParameterException("unknown curve name: " + curveName); } } } this.ecParams = new ECNamedCurveSpec( curveName, ecP.getCurve(), ecP.getG(), ecP.getN(), ecP.getH(), null); // ecP.getSeed()); Work-around JDK bug -- it won't look up named curves properly if seed is present java.security.spec.ECParameterSpec p = (java.security.spec.ECParameterSpec)ecParams; ECCurve curve = EC5Util.convertCurve(p.getCurve()); ECPoint g = EC5Util.convertPoint(curve, p.getGenerator(), false); param = new ECKeyGenerationParameters(new ECDomainParameters(curve, g, p.getOrder(), BigInteger.valueOf(p.getCofactor())), random); engine.init(param); initialised = true; } else if (params == null && configuration.getEcImplicitlyCa() != null) { ECParameterSpec p = configuration.getEcImplicitlyCa(); this.ecParams = params; param = new ECKeyGenerationParameters(new ECDomainParameters(p.getCurve(), p.getG(), p.getN()), random); engine.init(param); initialised = true; } else if (params == null && configuration.getEcImplicitlyCa() == null) { throw new InvalidAlgorithmParameterException("null parameter passed but no implicitCA set"); } else { throw new InvalidAlgorithmParameterException("parameter object not a ECParameterSpec"); } } public KeyPair generateKeyPair() { if (!initialised) { initialize(strength, new SecureRandom()); } AsymmetricCipherKeyPair pair = engine.generateKeyPair(); ECPublicKeyParameters pub = (ECPublicKeyParameters)pair.getPublic(); ECPrivateKeyParameters priv = (ECPrivateKeyParameters)pair.getPrivate(); if (ecParams instanceof ECParameterSpec) { ECParameterSpec p = (ECParameterSpec)ecParams; BCECPublicKey pubKey = new BCECPublicKey(algorithm, pub, p, configuration); return new KeyPair(pubKey, new BCECPrivateKey(algorithm, priv, pubKey, p, configuration)); } else if (ecParams == null) { return new KeyPair(new BCECPublicKey(algorithm, pub, configuration), new BCECPrivateKey(algorithm, priv, configuration)); } else { java.security.spec.ECParameterSpec p = (java.security.spec.ECParameterSpec)ecParams; BCECPublicKey pubKey = new BCECPublicKey(algorithm, pub, p, configuration); return new KeyPair(pubKey, new BCECPrivateKey(algorithm, priv, pubKey, p, configuration)); } } } public static class ECDSA extends EC { public ECDSA() { super("ECDSA", BouncyCastleProvider.CONFIGURATION); } } public static class ECDH extends EC { public ECDH() { super("ECDH", BouncyCastleProvider.CONFIGURATION); } } public static class ECDHC extends EC { public ECDHC() { super("ECDHC", BouncyCastleProvider.CONFIGURATION); } } public static class ECMQV extends EC { public ECMQV() { super("ECMQV", BouncyCastleProvider.CONFIGURATION); } } }bouncycastle-1.49.orig/src/org/bouncycastle/jcajce/provider/asymmetric/x509/0000755000175000017500000000000012152033551026432 5ustar ebourgebourgbouncycastle-1.49.orig/src/org/bouncycastle/jcajce/provider/asymmetric/x509/X509CRLObject.java0000644000175000017500000004251612110047042031434 0ustar ebourgebourgpackage org.bouncycastle.jcajce.provider.asymmetric.x509; import java.io.IOException; import java.math.BigInteger; import java.security.InvalidKeyException; import java.security.NoSuchAlgorithmException; import java.security.NoSuchProviderException; import java.security.Principal; import java.security.PublicKey; import java.security.Signature; import java.security.SignatureException; import java.security.cert.CRLException; import java.security.cert.Certificate; import java.security.cert.CertificateEncodingException; import java.security.cert.X509CRL; import java.security.cert.X509CRLEntry; import java.security.cert.X509Certificate; import java.util.Collections; import java.util.Date; import java.util.Enumeration; import java.util.HashSet; import java.util.Iterator; import java.util.Set; import javax.security.auth.x500.X500Principal; import org.bouncycastle.asn1.ASN1Encodable; import org.bouncycastle.asn1.ASN1Encoding; import org.bouncycastle.asn1.ASN1InputStream; import org.bouncycastle.asn1.ASN1Integer; import org.bouncycastle.asn1.ASN1ObjectIdentifier; import org.bouncycastle.asn1.ASN1OctetString; import org.bouncycastle.asn1.util.ASN1Dump; import org.bouncycastle.asn1.x500.X500Name; import org.bouncycastle.asn1.x509.CRLDistPoint; import org.bouncycastle.asn1.x509.CRLNumber; import org.bouncycastle.asn1.x509.CertificateList; import org.bouncycastle.asn1.x509.Extension; import org.bouncycastle.asn1.x509.Extensions; import org.bouncycastle.asn1.x509.GeneralNames; import org.bouncycastle.asn1.x509.IssuingDistributionPoint; import org.bouncycastle.asn1.x509.TBSCertList; import org.bouncycastle.jce.X509Principal; import org.bouncycastle.jce.provider.BouncyCastleProvider; import org.bouncycastle.jce.provider.RFC3280CertPathUtilities; import org.bouncycastle.util.encoders.Hex; /** * The following extensions are listed in RFC 2459 as relevant to CRLs * * Authority Key Identifier * Issuer Alternative Name * CRL Number * Delta CRL Indicator (critical) * Issuing Distribution Point (critical) */ class X509CRLObject extends X509CRL { private CertificateList c; private String sigAlgName; private byte[] sigAlgParams; private boolean isIndirect; static boolean isIndirectCRL(X509CRL crl) throws CRLException { try { byte[] idp = crl.getExtensionValue(Extension.issuingDistributionPoint.getId()); return idp != null && IssuingDistributionPoint.getInstance(ASN1OctetString.getInstance(idp).getOctets()).isIndirectCRL(); } catch (Exception e) { throw new ExtCRLException( "Exception reading IssuingDistributionPoint", e); } } public X509CRLObject( CertificateList c) throws CRLException { this.c = c; try { this.sigAlgName = X509SignatureUtil.getSignatureName(c.getSignatureAlgorithm()); if (c.getSignatureAlgorithm().getParameters() != null) { this.sigAlgParams = ((ASN1Encodable)c.getSignatureAlgorithm().getParameters()).toASN1Primitive().getEncoded(ASN1Encoding.DER); } else { this.sigAlgParams = null; } this.isIndirect = isIndirectCRL(this); } catch (Exception e) { throw new CRLException("CRL contents invalid: " + e); } } /** * Will return true if any extensions are present and marked * as critical as we currently dont handle any extensions! */ public boolean hasUnsupportedCriticalExtension() { Set extns = getCriticalExtensionOIDs(); if (extns == null) { return false; } extns.remove(RFC3280CertPathUtilities.ISSUING_DISTRIBUTION_POINT); extns.remove(RFC3280CertPathUtilities.DELTA_CRL_INDICATOR); return !extns.isEmpty(); } private Set getExtensionOIDs(boolean critical) { if (this.getVersion() == 2) { Extensions extensions = c.getTBSCertList().getExtensions(); if (extensions != null) { Set set = new HashSet(); Enumeration e = extensions.oids(); while (e.hasMoreElements()) { ASN1ObjectIdentifier oid = (ASN1ObjectIdentifier)e.nextElement(); Extension ext = extensions.getExtension(oid); if (critical == ext.isCritical()) { set.add(oid.getId()); } } return set; } } return null; } public Set getCriticalExtensionOIDs() { return getExtensionOIDs(true); } public Set getNonCriticalExtensionOIDs() { return getExtensionOIDs(false); } public byte[] getExtensionValue(String oid) { Extensions exts = c.getTBSCertList().getExtensions(); if (exts != null) { Extension ext = exts.getExtension(new ASN1ObjectIdentifier(oid)); if (ext != null) { try { return ext.getExtnValue().getEncoded(); } catch (Exception e) { throw new IllegalStateException("error parsing " + e.toString()); } } } return null; } public byte[] getEncoded() throws CRLException { try { return c.getEncoded(ASN1Encoding.DER); } catch (IOException e) { throw new CRLException(e.toString()); } } public void verify(PublicKey key) throws CRLException, NoSuchAlgorithmException, InvalidKeyException, NoSuchProviderException, SignatureException { verify(key, BouncyCastleProvider.PROVIDER_NAME); } public void verify(PublicKey key, String sigProvider) throws CRLException, NoSuchAlgorithmException, InvalidKeyException, NoSuchProviderException, SignatureException { if (!c.getSignatureAlgorithm().equals(c.getTBSCertList().getSignature())) { throw new CRLException("Signature algorithm on CertificateList does not match TBSCertList."); } Signature sig; if (sigProvider != null) { sig = Signature.getInstance(getSigAlgName(), sigProvider); } else { sig = Signature.getInstance(getSigAlgName()); } sig.initVerify(key); sig.update(this.getTBSCertList()); if (!sig.verify(this.getSignature())) { throw new SignatureException("CRL does not verify with supplied public key."); } } public int getVersion() { return c.getVersionNumber(); } public Principal getIssuerDN() { return new X509Principal(X500Name.getInstance(c.getIssuer().toASN1Primitive())); } public X500Principal getIssuerX500Principal() { try { return new X500Principal(c.getIssuer().getEncoded()); } catch (IOException e) { throw new IllegalStateException("can't encode issuer DN"); } } public Date getThisUpdate() { return c.getThisUpdate().getDate(); } public Date getNextUpdate() { if (c.getNextUpdate() != null) { return c.getNextUpdate().getDate(); } return null; } private Set loadCRLEntries() { Set entrySet = new HashSet(); Enumeration certs = c.getRevokedCertificateEnumeration(); X500Name previousCertificateIssuer = null; // the issuer while (certs.hasMoreElements()) { TBSCertList.CRLEntry entry = (TBSCertList.CRLEntry)certs.nextElement(); X509CRLEntryObject crlEntry = new X509CRLEntryObject(entry, isIndirect, previousCertificateIssuer); entrySet.add(crlEntry); if (isIndirect && entry.hasExtensions()) { Extension currentCaName = entry.getExtensions().getExtension(Extension.certificateIssuer); if (currentCaName != null) { previousCertificateIssuer = X500Name.getInstance(GeneralNames.getInstance(currentCaName.getParsedValue()).getNames()[0].getName()); } } } return entrySet; } public X509CRLEntry getRevokedCertificate(BigInteger serialNumber) { Enumeration certs = c.getRevokedCertificateEnumeration(); X500Name previousCertificateIssuer = null; // the issuer while (certs.hasMoreElements()) { TBSCertList.CRLEntry entry = (TBSCertList.CRLEntry)certs.nextElement(); if (serialNumber.equals(entry.getUserCertificate().getValue())) { return new X509CRLEntryObject(entry, isIndirect, previousCertificateIssuer); } if (isIndirect && entry.hasExtensions()) { Extension currentCaName = entry.getExtensions().getExtension(Extension.certificateIssuer); if (currentCaName != null) { previousCertificateIssuer = X500Name.getInstance(GeneralNames.getInstance(currentCaName.getParsedValue()).getNames()[0].getName()); } } } return null; } public Set getRevokedCertificates() { Set entrySet = loadCRLEntries(); if (!entrySet.isEmpty()) { return Collections.unmodifiableSet(entrySet); } return null; } public byte[] getTBSCertList() throws CRLException { try { return c.getTBSCertList().getEncoded("DER"); } catch (IOException e) { throw new CRLException(e.toString()); } } public byte[] getSignature() { return c.getSignature().getBytes(); } public String getSigAlgName() { return sigAlgName; } public String getSigAlgOID() { return c.getSignatureAlgorithm().getAlgorithm().getId(); } public byte[] getSigAlgParams() { if (sigAlgParams != null) { byte[] tmp = new byte[sigAlgParams.length]; System.arraycopy(sigAlgParams, 0, tmp, 0, tmp.length); return tmp; } return null; } /** * Returns a string representation of this CRL. * * @return a string representation of this CRL. */ public String toString() { StringBuffer buf = new StringBuffer(); String nl = System.getProperty("line.separator"); buf.append(" Version: ").append(this.getVersion()).append( nl); buf.append(" IssuerDN: ").append(this.getIssuerDN()) .append(nl); buf.append(" This update: ").append(this.getThisUpdate()) .append(nl); buf.append(" Next update: ").append(this.getNextUpdate()) .append(nl); buf.append(" Signature Algorithm: ").append(this.getSigAlgName()) .append(nl); byte[] sig = this.getSignature(); buf.append(" Signature: ").append( new String(Hex.encode(sig, 0, 20))).append(nl); for (int i = 20; i < sig.length; i += 20) { if (i < sig.length - 20) { buf.append(" ").append( new String(Hex.encode(sig, i, 20))).append(nl); } else { buf.append(" ").append( new String(Hex.encode(sig, i, sig.length - i))).append(nl); } } Extensions extensions = c.getTBSCertList().getExtensions(); if (extensions != null) { Enumeration e = extensions.oids(); if (e.hasMoreElements()) { buf.append(" Extensions: ").append(nl); } while (e.hasMoreElements()) { ASN1ObjectIdentifier oid = (ASN1ObjectIdentifier) e.nextElement(); Extension ext = extensions.getExtension(oid); if (ext.getExtnValue() != null) { byte[] octs = ext.getExtnValue().getOctets(); ASN1InputStream dIn = new ASN1InputStream(octs); buf.append(" critical(").append( ext.isCritical()).append(") "); try { if (oid.equals(Extension.cRLNumber)) { buf.append( new CRLNumber(ASN1Integer.getInstance( dIn.readObject()).getPositiveValue())) .append(nl); } else if (oid.equals(Extension.deltaCRLIndicator)) { buf.append( "Base CRL: " + new CRLNumber(ASN1Integer.getInstance( dIn.readObject()).getPositiveValue())) .append(nl); } else if (oid .equals(Extension.issuingDistributionPoint)) { buf.append( IssuingDistributionPoint.getInstance(dIn.readObject())).append(nl); } else if (oid .equals(Extension.cRLDistributionPoints)) { buf.append( CRLDistPoint.getInstance(dIn.readObject())).append(nl); } else if (oid.equals(Extension.freshestCRL)) { buf.append( CRLDistPoint.getInstance(dIn.readObject())).append(nl); } else { buf.append(oid.getId()); buf.append(" value = ").append( ASN1Dump.dumpAsString(dIn.readObject())) .append(nl); } } catch (Exception ex) { buf.append(oid.getId()); buf.append(" value = ").append("*****").append(nl); } } else { buf.append(nl); } } } Set set = getRevokedCertificates(); if (set != null) { Iterator it = set.iterator(); while (it.hasNext()) { buf.append(it.next()); buf.append(nl); } } return buf.toString(); } /** * Checks whether the given certificate is on this CRL. * * @param cert the certificate to check for. * @return true if the given certificate is on this CRL, * false otherwise. */ public boolean isRevoked(Certificate cert) { if (!cert.getType().equals("X.509")) { throw new RuntimeException("X.509 CRL used with non X.509 Cert"); } TBSCertList.CRLEntry[] certs = c.getRevokedCertificates(); X500Name caName = c.getIssuer(); if (certs != null) { BigInteger serial = ((X509Certificate)cert).getSerialNumber(); for (int i = 0; i < certs.length; i++) { if (isIndirect && certs[i].hasExtensions()) { Extension currentCaName = certs[i].getExtensions().getExtension(Extension.certificateIssuer); if (currentCaName != null) { caName = X500Name.getInstance(GeneralNames.getInstance(currentCaName.getParsedValue()).getNames()[0].getName()); } } if (certs[i].getUserCertificate().getValue().equals(serial)) { X500Name issuer; if (cert instanceof X509Certificate) { issuer = X500Name.getInstance(((X509Certificate)cert).getIssuerX500Principal().getEncoded()); } else { try { issuer = org.bouncycastle.asn1.x509.Certificate.getInstance(cert.getEncoded()).getIssuer(); } catch (CertificateEncodingException e) { throw new RuntimeException("Cannot process certificate"); } } if (!caName.equals(issuer)) { return false; } return true; } } } return false; } } bouncycastle-1.49.orig/src/org/bouncycastle/jcajce/provider/asymmetric/x509/CertificateFactory.java0000644000175000017500000002525312111522605033054 0ustar ebourgebourgpackage org.bouncycastle.jcajce.provider.asymmetric.x509; import java.io.IOException; import java.io.InputStream; import java.io.PushbackInputStream; import java.security.cert.CRL; import java.security.cert.CRLException; import java.security.cert.CertPath; import java.security.cert.CertificateException; import java.security.cert.CertificateFactorySpi; import java.security.cert.CertificateParsingException; import java.security.cert.X509Certificate; import java.util.ArrayList; import java.util.Collection; import java.util.Iterator; import java.util.List; import org.bouncycastle.asn1.ASN1InputStream; import org.bouncycastle.asn1.ASN1ObjectIdentifier; import org.bouncycastle.asn1.ASN1Sequence; import org.bouncycastle.asn1.ASN1Set; import org.bouncycastle.asn1.ASN1TaggedObject; import org.bouncycastle.asn1.pkcs.PKCSObjectIdentifiers; import org.bouncycastle.asn1.pkcs.SignedData; import org.bouncycastle.asn1.x509.Certificate; import org.bouncycastle.asn1.x509.CertificateList; /** * class for dealing with X509 certificates. *

    * At the moment this will deal with "-----BEGIN CERTIFICATE-----" to "-----END CERTIFICATE-----" * base 64 encoded certs, as well as the BER binaries of certificates and some classes of PKCS#7 * objects. */ public class CertificateFactory extends CertificateFactorySpi { private static final PEMUtil PEM_CERT_PARSER = new PEMUtil("CERTIFICATE"); private static final PEMUtil PEM_CRL_PARSER = new PEMUtil("CRL"); private ASN1Set sData = null; private int sDataObjectCount = 0; private InputStream currentStream = null; private ASN1Set sCrlData = null; private int sCrlDataObjectCount = 0; private InputStream currentCrlStream = null; private java.security.cert.Certificate readDERCertificate( ASN1InputStream dIn) throws IOException, CertificateParsingException { ASN1Sequence seq = (ASN1Sequence)dIn.readObject(); if (seq.size() > 1 && seq.getObjectAt(0) instanceof ASN1ObjectIdentifier) { if (seq.getObjectAt(0).equals(PKCSObjectIdentifiers.signedData)) { sData = SignedData.getInstance(ASN1Sequence.getInstance( (ASN1TaggedObject)seq.getObjectAt(1), true)).getCertificates(); return getCertificate(); } } return new X509CertificateObject( Certificate.getInstance(seq)); } private java.security.cert.Certificate getCertificate() throws CertificateParsingException { if (sData != null) { while (sDataObjectCount < sData.size()) { Object obj = sData.getObjectAt(sDataObjectCount++); if (obj instanceof ASN1Sequence) { return new X509CertificateObject( Certificate.getInstance(obj)); } } } return null; } private java.security.cert.Certificate readPEMCertificate( InputStream in) throws IOException, CertificateParsingException { ASN1Sequence seq = PEM_CERT_PARSER.readPEMObject(in); if (seq != null) { return new X509CertificateObject( Certificate.getInstance(seq)); } return null; } protected CRL createCRL(CertificateList c) throws CRLException { return new X509CRLObject(c); } private CRL readPEMCRL( InputStream in) throws IOException, CRLException { ASN1Sequence seq = PEM_CRL_PARSER.readPEMObject(in); if (seq != null) { return createCRL( CertificateList.getInstance(seq)); } return null; } private CRL readDERCRL( ASN1InputStream aIn) throws IOException, CRLException { ASN1Sequence seq = (ASN1Sequence)aIn.readObject(); if (seq.size() > 1 && seq.getObjectAt(0) instanceof ASN1ObjectIdentifier) { if (seq.getObjectAt(0).equals(PKCSObjectIdentifiers.signedData)) { sCrlData = SignedData.getInstance(ASN1Sequence.getInstance( (ASN1TaggedObject)seq.getObjectAt(1), true)).getCRLs(); return getCRL(); } } return createCRL( CertificateList.getInstance(seq)); } private CRL getCRL() throws CRLException { if (sCrlData == null || sCrlDataObjectCount >= sCrlData.size()) { return null; } return createCRL( CertificateList.getInstance( sCrlData.getObjectAt(sCrlDataObjectCount++))); } /** * Generates a certificate object and initializes it with the data * read from the input stream inStream. */ public java.security.cert.Certificate engineGenerateCertificate( InputStream in) throws CertificateException { if (currentStream == null) { currentStream = in; sData = null; sDataObjectCount = 0; } else if (currentStream != in) // reset if input stream has changed { currentStream = in; sData = null; sDataObjectCount = 0; } try { if (sData != null) { if (sDataObjectCount != sData.size()) { return getCertificate(); } else { sData = null; sDataObjectCount = 0; return null; } } PushbackInputStream pis = new PushbackInputStream(in); int tag = pis.read(); if (tag == -1) { return null; } pis.unread(tag); if (tag != 0x30) // assume ascii PEM encoded. { return readPEMCertificate(pis); } else { return readDERCertificate(new ASN1InputStream(pis)); } } catch (Exception e) { throw new ExCertificateException(e); } } /** * Returns a (possibly empty) collection view of the certificates * read from the given input stream inStream. */ public Collection engineGenerateCertificates( InputStream inStream) throws CertificateException { java.security.cert.Certificate cert; List certs = new ArrayList(); while ((cert = engineGenerateCertificate(inStream)) != null) { certs.add(cert); } return certs; } /** * Generates a certificate revocation list (CRL) object and initializes * it with the data read from the input stream inStream. */ public CRL engineGenerateCRL( InputStream inStream) throws CRLException { if (currentCrlStream == null) { currentCrlStream = inStream; sCrlData = null; sCrlDataObjectCount = 0; } else if (currentCrlStream != inStream) // reset if input stream has changed { currentCrlStream = inStream; sCrlData = null; sCrlDataObjectCount = 0; } try { if (sCrlData != null) { if (sCrlDataObjectCount != sCrlData.size()) { return getCRL(); } else { sCrlData = null; sCrlDataObjectCount = 0; return null; } } PushbackInputStream pis = new PushbackInputStream(inStream); int tag = pis.read(); if (tag == -1) { return null; } pis.unread(tag); if (tag != 0x30) // assume ascii PEM encoded. { return readPEMCRL(pis); } else { // lazy evaluate to help processing of large CRLs return readDERCRL(new ASN1InputStream(pis, true)); } } catch (CRLException e) { throw e; } catch (Exception e) { throw new CRLException(e.toString()); } } /** * Returns a (possibly empty) collection view of the CRLs read from * the given input stream inStream. * * The inStream may contain a sequence of DER-encoded CRLs, or * a PKCS#7 CRL set. This is a PKCS#7 SignedData object, with the * only signficant field being crls. In particular the signature * and the contents are ignored. */ public Collection engineGenerateCRLs( InputStream inStream) throws CRLException { CRL crl; List crls = new ArrayList(); while ((crl = engineGenerateCRL(inStream)) != null) { crls.add(crl); } return crls; } public Iterator engineGetCertPathEncodings() { return PKIXCertPath.certPathEncodings.iterator(); } public CertPath engineGenerateCertPath( InputStream inStream) throws CertificateException { return engineGenerateCertPath(inStream, "PkiPath"); } public CertPath engineGenerateCertPath( InputStream inStream, String encoding) throws CertificateException { return new PKIXCertPath(inStream, encoding); } public CertPath engineGenerateCertPath( List certificates) throws CertificateException { Iterator iter = certificates.iterator(); Object obj; while (iter.hasNext()) { obj = iter.next(); if (obj != null) { if (!(obj instanceof X509Certificate)) { throw new CertificateException("list contains non X509Certificate object while creating CertPath\n" + obj.toString()); } } } return new PKIXCertPath(certificates); } private class ExCertificateException extends CertificateException { private Throwable cause; public ExCertificateException(Throwable cause) { this.cause = cause; } public ExCertificateException(String msg, Throwable cause) { super(msg); this.cause = cause; } public Throwable getCause() { return cause; } } } bouncycastle-1.49.orig/src/org/bouncycastle/jcajce/provider/asymmetric/x509/PKIXCertPath.java0000644000175000017500000002734412110046726031517 0ustar ebourgebourgpackage org.bouncycastle.jcajce.provider.asymmetric.x509; import java.io.BufferedInputStream; import java.io.ByteArrayInputStream; import java.io.ByteArrayOutputStream; import java.io.IOException; import java.io.InputStream; import java.io.OutputStreamWriter; import java.security.NoSuchProviderException; import java.security.cert.CertPath; import java.security.cert.Certificate; import java.security.cert.CertificateEncodingException; import java.security.cert.CertificateException; import java.security.cert.CertificateFactory; import java.security.cert.X509Certificate; import java.util.ArrayList; import java.util.Collections; import java.util.Enumeration; import java.util.Iterator; import java.util.List; import java.util.ListIterator; import javax.security.auth.x500.X500Principal; import org.bouncycastle.asn1.ASN1Encodable; import org.bouncycastle.asn1.ASN1EncodableVector; import org.bouncycastle.asn1.ASN1Encoding; import org.bouncycastle.asn1.ASN1InputStream; import org.bouncycastle.asn1.ASN1Integer; import org.bouncycastle.asn1.ASN1Primitive; import org.bouncycastle.asn1.ASN1Sequence; import org.bouncycastle.asn1.DERSequence; import org.bouncycastle.asn1.DERSet; import org.bouncycastle.asn1.pkcs.ContentInfo; import org.bouncycastle.asn1.pkcs.PKCSObjectIdentifiers; import org.bouncycastle.asn1.pkcs.SignedData; import org.bouncycastle.jce.provider.BouncyCastleProvider; import org.bouncycastle.util.io.pem.PemObject; import org.bouncycastle.util.io.pem.PemWriter; /** * CertPath implementation for X.509 certificates. *
    **/ public class PKIXCertPath extends CertPath { static final List certPathEncodings; static { List encodings = new ArrayList(); encodings.add("PkiPath"); encodings.add("PEM"); encodings.add("PKCS7"); certPathEncodings = Collections.unmodifiableList(encodings); } private List certificates; /** * @param certs */ private List sortCerts( List certs) { if (certs.size() < 2) { return certs; } X500Principal issuer = ((X509Certificate)certs.get(0)).getIssuerX500Principal(); boolean okay = true; for (int i = 1; i != certs.size(); i++) { X509Certificate cert = (X509Certificate)certs.get(i); if (issuer.equals(cert.getSubjectX500Principal())) { issuer = ((X509Certificate)certs.get(i)).getIssuerX500Principal(); } else { okay = false; break; } } if (okay) { return certs; } // find end-entity cert List retList = new ArrayList(certs.size()); List orig = new ArrayList(certs); for (int i = 0; i < certs.size(); i++) { X509Certificate cert = (X509Certificate)certs.get(i); boolean found = false; X500Principal subject = cert.getSubjectX500Principal(); for (int j = 0; j != certs.size(); j++) { X509Certificate c = (X509Certificate)certs.get(j); if (c.getIssuerX500Principal().equals(subject)) { found = true; break; } } if (!found) { retList.add(cert); certs.remove(i); } } // can only have one end entity cert - something's wrong, give up. if (retList.size() > 1) { return orig; } for (int i = 0; i != retList.size(); i++) { issuer = ((X509Certificate)retList.get(i)).getIssuerX500Principal(); for (int j = 0; j < certs.size(); j++) { X509Certificate c = (X509Certificate)certs.get(j); if (issuer.equals(c.getSubjectX500Principal())) { retList.add(c); certs.remove(j); break; } } } // make sure all certificates are accounted for. if (certs.size() > 0) { return orig; } return retList; } PKIXCertPath(List certificates) { super("X.509"); this.certificates = sortCerts(new ArrayList(certificates)); } /** * Creates a CertPath of the specified type. * This constructor is protected because most users should use * a CertificateFactory to create CertPaths. **/ PKIXCertPath( InputStream inStream, String encoding) throws CertificateException { super("X.509"); try { if (encoding.equalsIgnoreCase("PkiPath")) { ASN1InputStream derInStream = new ASN1InputStream(inStream); ASN1Primitive derObject = derInStream.readObject(); if (!(derObject instanceof ASN1Sequence)) { throw new CertificateException("input stream does not contain a ASN1 SEQUENCE while reading PkiPath encoded data to load CertPath"); } Enumeration e = ((ASN1Sequence)derObject).getObjects(); certificates = new ArrayList(); CertificateFactory certFactory = CertificateFactory.getInstance("X.509", BouncyCastleProvider.PROVIDER_NAME); while (e.hasMoreElements()) { ASN1Encodable element = (ASN1Encodable)e.nextElement(); byte[] encoded = element.toASN1Primitive().getEncoded(ASN1Encoding.DER); certificates.add(0, certFactory.generateCertificate( new ByteArrayInputStream(encoded))); } } else if (encoding.equalsIgnoreCase("PKCS7") || encoding.equalsIgnoreCase("PEM")) { inStream = new BufferedInputStream(inStream); certificates = new ArrayList(); CertificateFactory certFactory= CertificateFactory.getInstance("X.509", BouncyCastleProvider.PROVIDER_NAME); Certificate cert; while ((cert = certFactory.generateCertificate(inStream)) != null) { certificates.add(cert); } } else { throw new CertificateException("unsupported encoding: " + encoding); } } catch (IOException ex) { throw new CertificateException("IOException throw while decoding CertPath:\n" + ex.toString()); } catch (NoSuchProviderException ex) { throw new CertificateException("BouncyCastle provider not found while trying to get a CertificateFactory:\n" + ex.toString()); } this.certificates = sortCerts(certificates); } /** * Returns an iteration of the encodings supported by this * certification path, with the default encoding * first. Attempts to modify the returned Iterator via its * remove method result in an UnsupportedOperationException. * * @return an Iterator over the names of the supported encodings (as Strings) **/ public Iterator getEncodings() { return certPathEncodings.iterator(); } /** * Returns the encoded form of this certification path, using * the default encoding. * * @return the encoded bytes * @exception java.security.cert.CertificateEncodingException if an encoding error occurs **/ public byte[] getEncoded() throws CertificateEncodingException { Iterator iter = getEncodings(); if (iter.hasNext()) { Object enc = iter.next(); if (enc instanceof String) { return getEncoded((String)enc); } } return null; } /** * Returns the encoded form of this certification path, using * the specified encoding. * * @param encoding the name of the encoding to use * @return the encoded bytes * @exception java.security.cert.CertificateEncodingException if an encoding error * occurs or the encoding requested is not supported * **/ public byte[] getEncoded(String encoding) throws CertificateEncodingException { if (encoding.equalsIgnoreCase("PkiPath")) { ASN1EncodableVector v = new ASN1EncodableVector(); ListIterator iter = certificates.listIterator(certificates.size()); while (iter.hasPrevious()) { v.add(toASN1Object((X509Certificate)iter.previous())); } return toDEREncoded(new DERSequence(v)); } else if (encoding.equalsIgnoreCase("PKCS7")) { ContentInfo encInfo = new ContentInfo(PKCSObjectIdentifiers.data, null); ASN1EncodableVector v = new ASN1EncodableVector(); for (int i = 0; i != certificates.size(); i++) { v.add(toASN1Object((X509Certificate)certificates.get(i))); } SignedData sd = new SignedData( new ASN1Integer(1), new DERSet(), encInfo, new DERSet(v), null, new DERSet()); return toDEREncoded(new ContentInfo( PKCSObjectIdentifiers.signedData, sd)); } else if (encoding.equalsIgnoreCase("PEM")) { ByteArrayOutputStream bOut = new ByteArrayOutputStream(); PemWriter pWrt = new PemWriter(new OutputStreamWriter(bOut)); try { for (int i = 0; i != certificates.size(); i++) { pWrt.writeObject(new PemObject("CERTIFICATE", ((X509Certificate)certificates.get(i)).getEncoded())); } pWrt.close(); } catch (Exception e) { throw new CertificateEncodingException("can't encode certificate for PEM encoded path"); } return bOut.toByteArray(); } else { throw new CertificateEncodingException("unsupported encoding: " + encoding); } } /** * Returns the list of certificates in this certification * path. The List returned must be immutable and thread-safe. * * @return an immutable List of Certificates (may be empty, but not null) **/ public List getCertificates() { return Collections.unmodifiableList(new ArrayList(certificates)); } /** * Return a DERObject containing the encoded certificate. * * @param cert the X509Certificate object to be encoded * * @return the DERObject **/ private ASN1Primitive toASN1Object( X509Certificate cert) throws CertificateEncodingException { try { return new ASN1InputStream(cert.getEncoded()).readObject(); } catch (Exception e) { throw new CertificateEncodingException("Exception while encoding certificate: " + e.toString()); } } private byte[] toDEREncoded(ASN1Encodable obj) throws CertificateEncodingException { try { return obj.toASN1Primitive().getEncoded(ASN1Encoding.DER); } catch (IOException e) { throw new CertificateEncodingException("Exception thrown: " + e); } } } ././@LongLink0000000000000000000000000000014700000000000011567 Lustar rootrootbouncycastle-1.49.orig/src/org/bouncycastle/jcajce/provider/asymmetric/x509/X509CertificateObject.javabouncycastle-1.49.orig/src/org/bouncycastle/jcajce/provider/asymmetric/x509/X509CertificateObject.ja0000644000175000017500000006636112151633765032735 0ustar ebourgebourgpackage org.bouncycastle.jcajce.provider.asymmetric.x509; import java.io.ByteArrayOutputStream; import java.io.IOException; import java.math.BigInteger; import java.net.InetAddress; import java.net.UnknownHostException; import java.security.InvalidKeyException; import java.security.NoSuchAlgorithmException; import java.security.NoSuchProviderException; import java.security.Principal; import java.security.Provider; import java.security.PublicKey; import java.security.Security; import java.security.Signature; import java.security.SignatureException; import java.security.cert.Certificate; import java.security.cert.CertificateEncodingException; import java.security.cert.CertificateException; import java.security.cert.CertificateExpiredException; import java.security.cert.CertificateNotYetValidException; import java.security.cert.CertificateParsingException; import java.security.cert.X509Certificate; import java.util.ArrayList; import java.util.Collection; import java.util.Collections; import java.util.Date; import java.util.Enumeration; import java.util.HashSet; import java.util.List; import java.util.Set; import javax.security.auth.x500.X500Principal; import org.bouncycastle.asn1.ASN1Encodable; import org.bouncycastle.asn1.ASN1Encoding; import org.bouncycastle.asn1.ASN1InputStream; import org.bouncycastle.asn1.ASN1ObjectIdentifier; import org.bouncycastle.asn1.ASN1OutputStream; import org.bouncycastle.asn1.ASN1Primitive; import org.bouncycastle.asn1.ASN1Sequence; import org.bouncycastle.asn1.ASN1String; import org.bouncycastle.asn1.DERBitString; import org.bouncycastle.asn1.DERIA5String; import org.bouncycastle.asn1.DERNull; import org.bouncycastle.asn1.DEROctetString; import org.bouncycastle.asn1.misc.MiscObjectIdentifiers; import org.bouncycastle.asn1.misc.NetscapeCertType; import org.bouncycastle.asn1.misc.NetscapeRevocationURL; import org.bouncycastle.asn1.misc.VerisignCzagExtension; import org.bouncycastle.asn1.util.ASN1Dump; import org.bouncycastle.asn1.x500.X500Name; import org.bouncycastle.asn1.x500.style.RFC4519Style; import org.bouncycastle.asn1.x509.AlgorithmIdentifier; import org.bouncycastle.asn1.x509.BasicConstraints; import org.bouncycastle.asn1.x509.Extension; import org.bouncycastle.asn1.x509.Extensions; import org.bouncycastle.asn1.x509.GeneralName; import org.bouncycastle.asn1.x509.KeyUsage; import org.bouncycastle.jcajce.provider.asymmetric.util.PKCS12BagAttributeCarrierImpl; import org.bouncycastle.jce.X509Principal; import org.bouncycastle.jce.interfaces.PKCS12BagAttributeCarrier; import org.bouncycastle.jce.provider.BouncyCastleProvider; import org.bouncycastle.jce.provider.RFC3280CertPathUtilities; import org.bouncycastle.util.Arrays; import org.bouncycastle.util.Integers; import org.bouncycastle.util.encoders.Hex; class X509CertificateObject extends X509Certificate implements PKCS12BagAttributeCarrier { private org.bouncycastle.asn1.x509.Certificate c; private BasicConstraints basicConstraints; private boolean[] keyUsage; private boolean hashValueSet; private int hashValue; private PKCS12BagAttributeCarrier attrCarrier = new PKCS12BagAttributeCarrierImpl(); public X509CertificateObject( org.bouncycastle.asn1.x509.Certificate c) throws CertificateParsingException { this.c = c; try { byte[] bytes = this.getExtensionBytes("2.5.29.19"); if (bytes != null) { basicConstraints = BasicConstraints.getInstance(ASN1Primitive.fromByteArray(bytes)); } } catch (Exception e) { throw new CertificateParsingException("cannot construct BasicConstraints: " + e); } try { byte[] bytes = this.getExtensionBytes("2.5.29.15"); if (bytes != null) { DERBitString bits = DERBitString.getInstance(ASN1Primitive.fromByteArray(bytes)); bytes = bits.getBytes(); int length = (bytes.length * 8) - bits.getPadBits(); keyUsage = new boolean[(length < 9) ? 9 : length]; for (int i = 0; i != length; i++) { keyUsage[i] = (bytes[i / 8] & (0x80 >>> (i % 8))) != 0; } } else { keyUsage = null; } } catch (Exception e) { throw new CertificateParsingException("cannot construct KeyUsage: " + e); } } public void checkValidity() throws CertificateExpiredException, CertificateNotYetValidException { this.checkValidity(new Date()); } public void checkValidity( Date date) throws CertificateExpiredException, CertificateNotYetValidException { if (date.getTime() > this.getNotAfter().getTime()) // for other VM compatibility { throw new CertificateExpiredException("certificate expired on " + c.getEndDate().getTime()); } if (date.getTime() < this.getNotBefore().getTime()) { throw new CertificateNotYetValidException("certificate not valid till " + c.getStartDate().getTime()); } } public int getVersion() { return c.getVersionNumber(); } public BigInteger getSerialNumber() { return c.getSerialNumber().getValue(); } public Principal getIssuerDN() { try { return new X509Principal(X500Name.getInstance(c.getIssuer().getEncoded())); } catch (IOException e) { return null; } } public X500Principal getIssuerX500Principal() { try { ByteArrayOutputStream bOut = new ByteArrayOutputStream(); ASN1OutputStream aOut = new ASN1OutputStream(bOut); aOut.writeObject(c.getIssuer()); return new X500Principal(bOut.toByteArray()); } catch (IOException e) { throw new IllegalStateException("can't encode issuer DN"); } } public Principal getSubjectDN() { return new X509Principal(X500Name.getInstance(c.getSubject().toASN1Primitive())); } public X500Principal getSubjectX500Principal() { try { ByteArrayOutputStream bOut = new ByteArrayOutputStream(); ASN1OutputStream aOut = new ASN1OutputStream(bOut); aOut.writeObject(c.getSubject()); return new X500Principal(bOut.toByteArray()); } catch (IOException e) { throw new IllegalStateException("can't encode issuer DN"); } } public Date getNotBefore() { return c.getStartDate().getDate(); } public Date getNotAfter() { return c.getEndDate().getDate(); } public byte[] getTBSCertificate() throws CertificateEncodingException { try { return c.getTBSCertificate().getEncoded(ASN1Encoding.DER); } catch (IOException e) { throw new CertificateEncodingException(e.toString()); } } public byte[] getSignature() { return c.getSignature().getBytes(); } /** * return a more "meaningful" representation for the signature algorithm used in * the certficate. */ public String getSigAlgName() { Provider prov = Security.getProvider(BouncyCastleProvider.PROVIDER_NAME); if (prov != null) { String algName = prov.getProperty("Alg.Alias.Signature." + this.getSigAlgOID()); if (algName != null) { return algName; } } Provider[] provs = Security.getProviders(); // // search every provider looking for a real algorithm // for (int i = 0; i != provs.length; i++) { String algName = provs[i].getProperty("Alg.Alias.Signature." + this.getSigAlgOID()); if (algName != null) { return algName; } } return this.getSigAlgOID(); } /** * return the object identifier for the signature. */ public String getSigAlgOID() { return c.getSignatureAlgorithm().getAlgorithm().getId(); } /** * return the signature parameters, or null if there aren't any. */ public byte[] getSigAlgParams() { if (c.getSignatureAlgorithm().getParameters() != null) { try { return c.getSignatureAlgorithm().getParameters().toASN1Primitive().getEncoded(ASN1Encoding.DER); } catch (IOException e) { return null; } } else { return null; } } public boolean[] getIssuerUniqueID() { DERBitString id = c.getTBSCertificate().getIssuerUniqueId(); if (id != null) { byte[] bytes = id.getBytes(); boolean[] boolId = new boolean[bytes.length * 8 - id.getPadBits()]; for (int i = 0; i != boolId.length; i++) { boolId[i] = (bytes[i / 8] & (0x80 >>> (i % 8))) != 0; } return boolId; } return null; } public boolean[] getSubjectUniqueID() { DERBitString id = c.getTBSCertificate().getSubjectUniqueId(); if (id != null) { byte[] bytes = id.getBytes(); boolean[] boolId = new boolean[bytes.length * 8 - id.getPadBits()]; for (int i = 0; i != boolId.length; i++) { boolId[i] = (bytes[i / 8] & (0x80 >>> (i % 8))) != 0; } return boolId; } return null; } public boolean[] getKeyUsage() { return keyUsage; } public List getExtendedKeyUsage() throws CertificateParsingException { byte[] bytes = this.getExtensionBytes("2.5.29.37"); if (bytes != null) { try { ASN1InputStream dIn = new ASN1InputStream(bytes); ASN1Sequence seq = (ASN1Sequence)dIn.readObject(); List list = new ArrayList(); for (int i = 0; i != seq.size(); i++) { list.add(((ASN1ObjectIdentifier)seq.getObjectAt(i)).getId()); } return Collections.unmodifiableList(list); } catch (Exception e) { throw new CertificateParsingException("error processing extended key usage extension"); } } return null; } public int getBasicConstraints() { if (basicConstraints != null) { if (basicConstraints.isCA()) { if (basicConstraints.getPathLenConstraint() == null) { return Integer.MAX_VALUE; } else { return basicConstraints.getPathLenConstraint().intValue(); } } else { return -1; } } return -1; } public Collection getSubjectAlternativeNames() throws CertificateParsingException { return getAlternativeNames(getExtensionBytes(Extension.subjectAlternativeName.getId())); } public Collection getIssuerAlternativeNames() throws CertificateParsingException { return getAlternativeNames(getExtensionBytes(Extension.issuerAlternativeName.getId())); } public Set getCriticalExtensionOIDs() { if (this.getVersion() == 3) { Set set = new HashSet(); Extensions extensions = c.getTBSCertificate().getExtensions(); if (extensions != null) { Enumeration e = extensions.oids(); while (e.hasMoreElements()) { ASN1ObjectIdentifier oid = (ASN1ObjectIdentifier)e.nextElement(); Extension ext = extensions.getExtension(oid); if (ext.isCritical()) { set.add(oid.getId()); } } return set; } } return null; } private byte[] getExtensionBytes(String oid) { Extensions exts = c.getTBSCertificate().getExtensions(); if (exts != null) { Extension ext = exts.getExtension(new ASN1ObjectIdentifier(oid)); if (ext != null) { return ext.getExtnValue().getOctets(); } } return null; } public byte[] getExtensionValue(String oid) { Extensions exts = c.getTBSCertificate().getExtensions(); if (exts != null) { Extension ext = exts.getExtension(new ASN1ObjectIdentifier(oid)); if (ext != null) { try { return ext.getExtnValue().getEncoded(); } catch (Exception e) { throw new IllegalStateException("error parsing " + e.toString()); } } } return null; } public Set getNonCriticalExtensionOIDs() { if (this.getVersion() == 3) { Set set = new HashSet(); Extensions extensions = c.getTBSCertificate().getExtensions(); if (extensions != null) { Enumeration e = extensions.oids(); while (e.hasMoreElements()) { ASN1ObjectIdentifier oid = (ASN1ObjectIdentifier)e.nextElement(); Extension ext = extensions.getExtension(oid); if (!ext.isCritical()) { set.add(oid.getId()); } } return set; } } return null; } public boolean hasUnsupportedCriticalExtension() { if (this.getVersion() == 3) { Extensions extensions = c.getTBSCertificate().getExtensions(); if (extensions != null) { Enumeration e = extensions.oids(); while (e.hasMoreElements()) { ASN1ObjectIdentifier oid = (ASN1ObjectIdentifier)e.nextElement(); String oidId = oid.getId(); if (oidId.equals(RFC3280CertPathUtilities.KEY_USAGE) || oidId.equals(RFC3280CertPathUtilities.CERTIFICATE_POLICIES) || oidId.equals(RFC3280CertPathUtilities.POLICY_MAPPINGS) || oidId.equals(RFC3280CertPathUtilities.INHIBIT_ANY_POLICY) || oidId.equals(RFC3280CertPathUtilities.CRL_DISTRIBUTION_POINTS) || oidId.equals(RFC3280CertPathUtilities.ISSUING_DISTRIBUTION_POINT) || oidId.equals(RFC3280CertPathUtilities.DELTA_CRL_INDICATOR) || oidId.equals(RFC3280CertPathUtilities.POLICY_CONSTRAINTS) || oidId.equals(RFC3280CertPathUtilities.BASIC_CONSTRAINTS) || oidId.equals(RFC3280CertPathUtilities.SUBJECT_ALTERNATIVE_NAME) || oidId.equals(RFC3280CertPathUtilities.NAME_CONSTRAINTS)) { continue; } Extension ext = extensions.getExtension(oid); if (ext.isCritical()) { return true; } } } } return false; } public PublicKey getPublicKey() { try { return BouncyCastleProvider.getPublicKey(c.getSubjectPublicKeyInfo()); } catch (IOException e) { return null; // should never happen... } } public byte[] getEncoded() throws CertificateEncodingException { try { return c.getEncoded(ASN1Encoding.DER); } catch (IOException e) { throw new CertificateEncodingException(e.toString()); } } public boolean equals( Object o) { if (o == this) { return true; } if (!(o instanceof Certificate)) { return false; } Certificate other = (Certificate)o; try { byte[] b1 = this.getEncoded(); byte[] b2 = other.getEncoded(); return Arrays.areEqual(b1, b2); } catch (CertificateEncodingException e) { return false; } } public synchronized int hashCode() { if (!hashValueSet) { hashValue = calculateHashCode(); hashValueSet = true; } return hashValue; } private int calculateHashCode() { try { int hashCode = 0; byte[] certData = this.getEncoded(); for (int i = 1; i < certData.length; i++) { hashCode += certData[i] * i; } return hashCode; } catch (CertificateEncodingException e) { return 0; } } public void setBagAttribute( ASN1ObjectIdentifier oid, ASN1Encodable attribute) { attrCarrier.setBagAttribute(oid, attribute); } public ASN1Encodable getBagAttribute( ASN1ObjectIdentifier oid) { return attrCarrier.getBagAttribute(oid); } public Enumeration getBagAttributeKeys() { return attrCarrier.getBagAttributeKeys(); } public String toString() { StringBuffer buf = new StringBuffer(); String nl = System.getProperty("line.separator"); buf.append(" [0] Version: ").append(this.getVersion()).append(nl); buf.append(" SerialNumber: ").append(this.getSerialNumber()).append(nl); buf.append(" IssuerDN: ").append(this.getIssuerDN()).append(nl); buf.append(" Start Date: ").append(this.getNotBefore()).append(nl); buf.append(" Final Date: ").append(this.getNotAfter()).append(nl); buf.append(" SubjectDN: ").append(this.getSubjectDN()).append(nl); buf.append(" Public Key: ").append(this.getPublicKey()).append(nl); buf.append(" Signature Algorithm: ").append(this.getSigAlgName()).append(nl); byte[] sig = this.getSignature(); buf.append(" Signature: ").append(new String(Hex.encode(sig, 0, 20))).append(nl); for (int i = 20; i < sig.length; i += 20) { if (i < sig.length - 20) { buf.append(" ").append(new String(Hex.encode(sig, i, 20))).append(nl); } else { buf.append(" ").append(new String(Hex.encode(sig, i, sig.length - i))).append(nl); } } Extensions extensions = c.getTBSCertificate().getExtensions(); if (extensions != null) { Enumeration e = extensions.oids(); if (e.hasMoreElements()) { buf.append(" Extensions: \n"); } while (e.hasMoreElements()) { ASN1ObjectIdentifier oid = (ASN1ObjectIdentifier)e.nextElement(); Extension ext = extensions.getExtension(oid); if (ext.getExtnValue() != null) { byte[] octs = ext.getExtnValue().getOctets(); ASN1InputStream dIn = new ASN1InputStream(octs); buf.append(" critical(").append(ext.isCritical()).append(") "); try { if (oid.equals(Extension.basicConstraints)) { buf.append(BasicConstraints.getInstance(dIn.readObject())).append(nl); } else if (oid.equals(Extension.keyUsage)) { buf.append(KeyUsage.getInstance(dIn.readObject())).append(nl); } else if (oid.equals(MiscObjectIdentifiers.netscapeCertType)) { buf.append(new NetscapeCertType((DERBitString)dIn.readObject())).append(nl); } else if (oid.equals(MiscObjectIdentifiers.netscapeRevocationURL)) { buf.append(new NetscapeRevocationURL((DERIA5String)dIn.readObject())).append(nl); } else if (oid.equals(MiscObjectIdentifiers.verisignCzagExtension)) { buf.append(new VerisignCzagExtension((DERIA5String)dIn.readObject())).append(nl); } else { buf.append(oid.getId()); buf.append(" value = ").append(ASN1Dump.dumpAsString(dIn.readObject())).append(nl); //buf.append(" value = ").append("*****").append(nl); } } catch (Exception ex) { buf.append(oid.getId()); // buf.append(" value = ").append(new String(Hex.encode(ext.getExtnValue().getOctets()))).append(nl); buf.append(" value = ").append("*****").append(nl); } } else { buf.append(nl); } } } return buf.toString(); } public final void verify( PublicKey key) throws CertificateException, NoSuchAlgorithmException, InvalidKeyException, NoSuchProviderException, SignatureException { Signature signature; String sigName = X509SignatureUtil.getSignatureName(c.getSignatureAlgorithm()); try { signature = Signature.getInstance(sigName, BouncyCastleProvider.PROVIDER_NAME); } catch (Exception e) { signature = Signature.getInstance(sigName); } checkSignature(key, signature); } public final void verify( PublicKey key, String sigProvider) throws CertificateException, NoSuchAlgorithmException, InvalidKeyException, NoSuchProviderException, SignatureException { String sigName = X509SignatureUtil.getSignatureName(c.getSignatureAlgorithm()); Signature signature = Signature.getInstance(sigName, sigProvider); checkSignature(key, signature); } private void checkSignature( PublicKey key, Signature signature) throws CertificateException, NoSuchAlgorithmException, SignatureException, InvalidKeyException { if (!isAlgIdEqual(c.getSignatureAlgorithm(), c.getTBSCertificate().getSignature())) { throw new CertificateException("signature algorithm in TBS cert not same as outer cert"); } ASN1Encodable params = c.getSignatureAlgorithm().getParameters(); // TODO This should go after the initVerify? X509SignatureUtil.setSignatureParameters(signature, params); signature.initVerify(key); signature.update(this.getTBSCertificate()); if (!signature.verify(this.getSignature())) { throw new SignatureException("certificate does not verify with supplied key"); } } private boolean isAlgIdEqual(AlgorithmIdentifier id1, AlgorithmIdentifier id2) { if (!id1.getAlgorithm().equals(id2.getAlgorithm())) { return false; } if (id1.getParameters() == null) { if (id2.getParameters() != null && !id2.getParameters().equals(DERNull.INSTANCE)) { return false; } return true; } if (id2.getParameters() == null) { if (id1.getParameters() != null && !id1.getParameters().equals(DERNull.INSTANCE)) { return false; } return true; } return id1.getParameters().equals(id2.getParameters()); } private static Collection getAlternativeNames(byte[] extVal) throws CertificateParsingException { if (extVal == null) { return null; } try { Collection temp = new ArrayList(); Enumeration it = ASN1Sequence.getInstance(extVal).getObjects(); while (it.hasMoreElements()) { GeneralName genName = GeneralName.getInstance(it.nextElement()); List list = new ArrayList(); list.add(Integers.valueOf(genName.getTagNo())); switch (genName.getTagNo()) { case GeneralName.ediPartyName: case GeneralName.x400Address: case GeneralName.otherName: list.add(genName.getEncoded()); break; case GeneralName.directoryName: list.add(X500Name.getInstance(RFC4519Style.INSTANCE, genName.getName()).toString()); break; case GeneralName.dNSName: case GeneralName.rfc822Name: case GeneralName.uniformResourceIdentifier: list.add(((ASN1String)genName.getName()).getString()); break; case GeneralName.registeredID: list.add(ASN1ObjectIdentifier.getInstance(genName.getName()).getId()); break; case GeneralName.iPAddress: byte[] addrBytes = DEROctetString.getInstance(genName.getName()).getOctets(); final String addr; try { addr = InetAddress.getByAddress(addrBytes).getHostAddress(); } catch (UnknownHostException e) { continue; } list.add(addr); break; default: throw new IOException("Bad tag number: " + genName.getTagNo()); } temp.add(Collections.unmodifiableList(list)); } if (temp.size() == 0) { return null; } return Collections.unmodifiableCollection(temp); } catch (Exception e) { throw new CertificateParsingException(e.getMessage()); } } } bouncycastle-1.49.orig/src/org/bouncycastle/jcajce/provider/asymmetric/x509/ExtCRLException.java0000644000175000017500000000054512110037305032254 0ustar ebourgebourgpackage org.bouncycastle.jcajce.provider.asymmetric.x509; import java.security.cert.CRLException; class ExtCRLException extends CRLException { Throwable cause; ExtCRLException(String message, Throwable cause) { super(message); this.cause = cause; } public Throwable getCause() { return cause; } } bouncycastle-1.49.orig/src/org/bouncycastle/jcajce/provider/asymmetric/x509/KeyFactory.java0000644000175000017500000000610611631332404031360 0ustar ebourgebourgpackage org.bouncycastle.jcajce.provider.asymmetric.x509; import java.security.InvalidKeyException; import java.security.Key; import java.security.KeyFactorySpi; import java.security.PrivateKey; import java.security.PublicKey; import java.security.spec.InvalidKeySpecException; import java.security.spec.KeySpec; import java.security.spec.PKCS8EncodedKeySpec; import java.security.spec.X509EncodedKeySpec; import org.bouncycastle.asn1.pkcs.PrivateKeyInfo; import org.bouncycastle.asn1.x509.SubjectPublicKeyInfo; import org.bouncycastle.jce.provider.BouncyCastleProvider; public class KeyFactory extends KeyFactorySpi { protected PrivateKey engineGeneratePrivate( KeySpec keySpec) throws InvalidKeySpecException { if (keySpec instanceof PKCS8EncodedKeySpec) { try { PrivateKeyInfo info = PrivateKeyInfo.getInstance(((PKCS8EncodedKeySpec)keySpec).getEncoded()); PrivateKey key = BouncyCastleProvider.getPrivateKey(info); if (key != null) { return key; } throw new InvalidKeySpecException("no factory found for OID: " + info.getPrivateKeyAlgorithm().getAlgorithm()); } catch (Exception e) { throw new InvalidKeySpecException(e.toString()); } } throw new InvalidKeySpecException("Unknown KeySpec type: " + keySpec.getClass().getName()); } protected PublicKey engineGeneratePublic( KeySpec keySpec) throws InvalidKeySpecException { if (keySpec instanceof X509EncodedKeySpec) { try { SubjectPublicKeyInfo info = SubjectPublicKeyInfo.getInstance(((X509EncodedKeySpec)keySpec).getEncoded()); PublicKey key = BouncyCastleProvider.getPublicKey(info); if (key != null) { return key; } throw new InvalidKeySpecException("no factory found for OID: " + info.getAlgorithm().getAlgorithm()); } catch (Exception e) { throw new InvalidKeySpecException(e.toString()); } } throw new InvalidKeySpecException("Unknown KeySpec type: " + keySpec.getClass().getName()); } protected KeySpec engineGetKeySpec(Key key, Class keySpec) throws InvalidKeySpecException { if (keySpec.isAssignableFrom(PKCS8EncodedKeySpec.class) && key.getFormat().equals("PKCS#8")) { return new PKCS8EncodedKeySpec(key.getEncoded()); } else if (keySpec.isAssignableFrom(X509EncodedKeySpec.class) && key.getFormat().equals("X.509")) { return new X509EncodedKeySpec(key.getEncoded()); } throw new InvalidKeySpecException("not implemented yet " + key + " " + keySpec); } protected Key engineTranslateKey(Key key) throws InvalidKeyException { throw new InvalidKeyException("not implemented yet " + key); } }bouncycastle-1.49.orig/src/org/bouncycastle/jcajce/provider/asymmetric/x509/X509SignatureUtil.java0000644000175000017500000001123112110036731032455 0ustar ebourgebourgpackage org.bouncycastle.jcajce.provider.asymmetric.x509; import java.io.IOException; import java.security.AlgorithmParameters; import java.security.GeneralSecurityException; import java.security.InvalidKeyException; import java.security.NoSuchAlgorithmException; import java.security.Signature; import java.security.SignatureException; import java.security.spec.PSSParameterSpec; import org.bouncycastle.asn1.ASN1Encodable; import org.bouncycastle.asn1.ASN1Null; import org.bouncycastle.asn1.ASN1Sequence; import org.bouncycastle.asn1.DERNull; import org.bouncycastle.asn1.DERObjectIdentifier; import org.bouncycastle.asn1.cryptopro.CryptoProObjectIdentifiers; import org.bouncycastle.asn1.nist.NISTObjectIdentifiers; import org.bouncycastle.asn1.oiw.OIWObjectIdentifiers; import org.bouncycastle.asn1.pkcs.PKCSObjectIdentifiers; import org.bouncycastle.asn1.pkcs.RSASSAPSSparams; import org.bouncycastle.asn1.teletrust.TeleTrusTObjectIdentifiers; import org.bouncycastle.asn1.x509.AlgorithmIdentifier; import org.bouncycastle.asn1.x9.X9ObjectIdentifiers; class X509SignatureUtil { private static final ASN1Null derNull = DERNull.INSTANCE; static void setSignatureParameters( Signature signature, ASN1Encodable params) throws NoSuchAlgorithmException, SignatureException, InvalidKeyException { if (params != null && !derNull.equals(params)) { AlgorithmParameters sigParams = AlgorithmParameters.getInstance(signature.getAlgorithm(), signature.getProvider()); try { sigParams.init(params.toASN1Primitive().getEncoded()); } catch (IOException e) { throw new SignatureException("IOException decoding parameters: " + e.getMessage()); } if (signature.getAlgorithm().endsWith("MGF1")) { try { signature.setParameter(sigParams.getParameterSpec(PSSParameterSpec.class)); } catch (GeneralSecurityException e) { throw new SignatureException("Exception extracting parameters: " + e.getMessage()); } } } } static String getSignatureName( AlgorithmIdentifier sigAlgId) { ASN1Encodable params = sigAlgId.getParameters(); if (params != null && !derNull.equals(params)) { if (sigAlgId.getAlgorithm().equals(PKCSObjectIdentifiers.id_RSASSA_PSS)) { RSASSAPSSparams rsaParams = RSASSAPSSparams.getInstance(params); return getDigestAlgName(rsaParams.getHashAlgorithm().getAlgorithm()) + "withRSAandMGF1"; } if (sigAlgId.getAlgorithm().equals(X9ObjectIdentifiers.ecdsa_with_SHA2)) { ASN1Sequence ecDsaParams = ASN1Sequence.getInstance(params); return getDigestAlgName((DERObjectIdentifier)ecDsaParams.getObjectAt(0)) + "withECDSA"; } } return sigAlgId.getAlgorithm().getId(); } /** * Return the digest algorithm using one of the standard JCA string * representations rather the the algorithm identifier (if possible). */ private static String getDigestAlgName( DERObjectIdentifier digestAlgOID) { if (PKCSObjectIdentifiers.md5.equals(digestAlgOID)) { return "MD5"; } else if (OIWObjectIdentifiers.idSHA1.equals(digestAlgOID)) { return "SHA1"; } else if (NISTObjectIdentifiers.id_sha224.equals(digestAlgOID)) { return "SHA224"; } else if (NISTObjectIdentifiers.id_sha256.equals(digestAlgOID)) { return "SHA256"; } else if (NISTObjectIdentifiers.id_sha384.equals(digestAlgOID)) { return "SHA384"; } else if (NISTObjectIdentifiers.id_sha512.equals(digestAlgOID)) { return "SHA512"; } else if (TeleTrusTObjectIdentifiers.ripemd128.equals(digestAlgOID)) { return "RIPEMD128"; } else if (TeleTrusTObjectIdentifiers.ripemd160.equals(digestAlgOID)) { return "RIPEMD160"; } else if (TeleTrusTObjectIdentifiers.ripemd256.equals(digestAlgOID)) { return "RIPEMD256"; } else if (CryptoProObjectIdentifiers.gostR3411.equals(digestAlgOID)) { return "GOST3411"; } else { return digestAlgOID.getId(); } } } bouncycastle-1.49.orig/src/org/bouncycastle/jcajce/provider/asymmetric/x509/X509CRLEntryObject.java0000644000175000017500000002123112110036363032451 0ustar ebourgebourgpackage org.bouncycastle.jcajce.provider.asymmetric.x509; import java.io.IOException; import java.math.BigInteger; import java.security.cert.CRLException; import java.security.cert.X509CRLEntry; import java.util.Date; import java.util.Enumeration; import java.util.HashSet; import java.util.Set; import javax.security.auth.x500.X500Principal; import org.bouncycastle.asn1.ASN1Encoding; import org.bouncycastle.asn1.ASN1Enumerated; import org.bouncycastle.asn1.ASN1InputStream; import org.bouncycastle.asn1.ASN1ObjectIdentifier; import org.bouncycastle.asn1.util.ASN1Dump; import org.bouncycastle.asn1.x500.X500Name; import org.bouncycastle.asn1.x509.CRLReason; import org.bouncycastle.asn1.x509.Extension; import org.bouncycastle.asn1.x509.Extensions; import org.bouncycastle.asn1.x509.GeneralName; import org.bouncycastle.asn1.x509.GeneralNames; import org.bouncycastle.asn1.x509.TBSCertList; import org.bouncycastle.asn1.x509.X509Extension; /** * The following extensions are listed in RFC 2459 as relevant to CRL Entries * * ReasonCode Hode Instruction Code Invalidity Date Certificate Issuer * (critical) */ class X509CRLEntryObject extends X509CRLEntry { private TBSCertList.CRLEntry c; private X500Name certificateIssuer; private int hashValue; private boolean isHashValueSet; public X509CRLEntryObject(TBSCertList.CRLEntry c) { this.c = c; this.certificateIssuer = null; } /** * Constructor for CRLEntries of indirect CRLs. If isIndirect * is false {@link #getCertificateIssuer()} will always * return null, previousCertificateIssuer is * ignored. If this isIndirect is specified and this CRLEntry * has no certificate issuer CRL entry extension * previousCertificateIssuer is returned by * {@link #getCertificateIssuer()}. * * @param c * TBSCertList.CRLEntry object. * @param isIndirect * true if the corresponding CRL is a indirect * CRL. * @param previousCertificateIssuer * Certificate issuer of the previous CRLEntry. */ public X509CRLEntryObject( TBSCertList.CRLEntry c, boolean isIndirect, X500Name previousCertificateIssuer) { this.c = c; this.certificateIssuer = loadCertificateIssuer(isIndirect, previousCertificateIssuer); } /** * Will return true if any extensions are present and marked as critical as * we currently don't handle any extensions! */ public boolean hasUnsupportedCriticalExtension() { Set extns = getCriticalExtensionOIDs(); return extns != null && !extns.isEmpty(); } private X500Name loadCertificateIssuer(boolean isIndirect, X500Name previousCertificateIssuer) { if (!isIndirect) { return null; } Extension ext = getExtension(Extension.certificateIssuer); if (ext == null) { return previousCertificateIssuer; } try { GeneralName[] names = GeneralNames.getInstance(ext.getParsedValue()).getNames(); for (int i = 0; i < names.length; i++) { if (names[i].getTagNo() == GeneralName.directoryName) { return X500Name.getInstance(names[i].getName()); } } return null; } catch (Exception e) { return null; } } public X500Principal getCertificateIssuer() { if (certificateIssuer == null) { return null; } try { return new X500Principal(certificateIssuer.getEncoded()); } catch (IOException e) { return null; } } private Set getExtensionOIDs(boolean critical) { Extensions extensions = c.getExtensions(); if (extensions != null) { Set set = new HashSet(); Enumeration e = extensions.oids(); while (e.hasMoreElements()) { ASN1ObjectIdentifier oid = (ASN1ObjectIdentifier) e.nextElement(); Extension ext = extensions.getExtension(oid); if (critical == ext.isCritical()) { set.add(oid.getId()); } } return set; } return null; } public Set getCriticalExtensionOIDs() { return getExtensionOIDs(true); } public Set getNonCriticalExtensionOIDs() { return getExtensionOIDs(false); } private Extension getExtension(ASN1ObjectIdentifier oid) { Extensions exts = c.getExtensions(); if (exts != null) { return exts.getExtension(oid); } return null; } public byte[] getExtensionValue(String oid) { Extension ext = getExtension(new ASN1ObjectIdentifier(oid)); if (ext != null) { try { return ext.getExtnValue().getEncoded(); } catch (Exception e) { throw new RuntimeException("error encoding " + e.toString()); } } return null; } /** * Cache the hashCode value - calculating it with the standard method. * @return calculated hashCode. */ public int hashCode() { if (!isHashValueSet) { hashValue = super.hashCode(); isHashValueSet = true; } return hashValue; } public byte[] getEncoded() throws CRLException { try { return c.getEncoded(ASN1Encoding.DER); } catch (IOException e) { throw new CRLException(e.toString()); } } public BigInteger getSerialNumber() { return c.getUserCertificate().getValue(); } public Date getRevocationDate() { return c.getRevocationDate().getDate(); } public boolean hasExtensions() { return c.getExtensions() != null; } public String toString() { StringBuffer buf = new StringBuffer(); String nl = System.getProperty("line.separator"); buf.append(" userCertificate: ").append(this.getSerialNumber()).append(nl); buf.append(" revocationDate: ").append(this.getRevocationDate()).append(nl); buf.append(" certificateIssuer: ").append(this.getCertificateIssuer()).append(nl); Extensions extensions = c.getExtensions(); if (extensions != null) { Enumeration e = extensions.oids(); if (e.hasMoreElements()) { buf.append(" crlEntryExtensions:").append(nl); while (e.hasMoreElements()) { ASN1ObjectIdentifier oid = (ASN1ObjectIdentifier)e.nextElement(); Extension ext = extensions.getExtension(oid); if (ext.getExtnValue() != null) { byte[] octs = ext.getExtnValue().getOctets(); ASN1InputStream dIn = new ASN1InputStream(octs); buf.append(" critical(").append(ext.isCritical()).append(") "); try { if (oid.equals(X509Extension.reasonCode)) { buf.append(CRLReason.getInstance(ASN1Enumerated.getInstance(dIn.readObject()))).append(nl); } else if (oid.equals(X509Extension.certificateIssuer)) { buf.append("Certificate issuer: ").append(GeneralNames.getInstance(dIn.readObject())).append(nl); } else { buf.append(oid.getId()); buf.append(" value = ").append(ASN1Dump.dumpAsString(dIn.readObject())).append(nl); } } catch (Exception ex) { buf.append(oid.getId()); buf.append(" value = ").append("*****").append(nl); } } else { buf.append(nl); } } } } return buf.toString(); } } bouncycastle-1.49.orig/src/org/bouncycastle/jcajce/provider/asymmetric/x509/PEMUtil.java0000644000175000017500000000410111624574334030564 0ustar ebourgebourgpackage org.bouncycastle.jcajce.provider.asymmetric.x509; import java.io.IOException; import java.io.InputStream; import org.bouncycastle.asn1.ASN1Sequence; import org.bouncycastle.util.encoders.Base64; public class PEMUtil { private final String _header1; private final String _header2; private final String _footer1; private final String _footer2; PEMUtil( String type) { _header1 = "-----BEGIN " + type + "-----"; _header2 = "-----BEGIN X509 " + type + "-----"; _footer1 = "-----END " + type + "-----"; _footer2 = "-----END X509 " + type + "-----"; } private String readLine( InputStream in) throws IOException { int c; StringBuffer l = new StringBuffer(); do { while (((c = in.read()) != '\r') && c != '\n' && (c >= 0)) { if (c == '\r') { continue; } l.append((char)c); } } while (c >= 0 && l.length() == 0); if (c < 0) { return null; } return l.toString(); } ASN1Sequence readPEMObject( InputStream in) throws IOException { String line; StringBuffer pemBuf = new StringBuffer(); while ((line = readLine(in)) != null) { if (line.startsWith(_header1) || line.startsWith(_header2)) { break; } } while ((line = readLine(in)) != null) { if (line.startsWith(_footer1) || line.startsWith(_footer2)) { break; } pemBuf.append(line); } if (pemBuf.length() != 0) { try { return ASN1Sequence.getInstance(Base64.decode(pemBuf.toString())); } catch (Exception e) { throw new IOException("malformed PEM data encountered"); } } return null; } } bouncycastle-1.49.orig/src/org/bouncycastle/jcajce/provider/asymmetric/dstu/0000755000175000017500000000000012152033551026704 5ustar ebourgebourgbouncycastle-1.49.orig/src/org/bouncycastle/jcajce/provider/asymmetric/dstu/SignatureSpi.java0000644000175000017500000001524612110037231032165 0ustar ebourgebourgpackage org.bouncycastle.jcajce.provider.asymmetric.dstu; import java.math.BigInteger; import java.security.InvalidKeyException; import java.security.PrivateKey; import java.security.PublicKey; import java.security.SignatureException; import java.security.spec.AlgorithmParameterSpec; import org.bouncycastle.asn1.ASN1OctetString; import org.bouncycastle.asn1.DEROctetString; import org.bouncycastle.asn1.pkcs.PKCSObjectIdentifiers; import org.bouncycastle.asn1.x509.SubjectPublicKeyInfo; import org.bouncycastle.asn1.x509.X509ObjectIdentifiers; import org.bouncycastle.crypto.CipherParameters; import org.bouncycastle.crypto.DSA; import org.bouncycastle.crypto.Digest; import org.bouncycastle.crypto.digests.GOST3411Digest; import org.bouncycastle.crypto.params.ParametersWithRandom; import org.bouncycastle.crypto.signers.DSTU4145Signer; import org.bouncycastle.jcajce.provider.asymmetric.util.ECUtil; import org.bouncycastle.jce.interfaces.ECKey; import org.bouncycastle.jce.interfaces.ECPublicKey; import org.bouncycastle.jce.provider.BouncyCastleProvider; public class SignatureSpi extends java.security.SignatureSpi implements PKCSObjectIdentifiers, X509ObjectIdentifiers { private Digest digest; private DSA signer; private static byte[] DEFAULT_SBOX = { 0xa, 0x9, 0xd, 0x6, 0xe, 0xb, 0x4, 0x5, 0xf, 0x1, 0x3, 0xc, 0x7, 0x0, 0x8, 0x2, 0x8, 0x0, 0xc, 0x4, 0x9, 0x6, 0x7, 0xb, 0x2, 0x3, 0x1, 0xf, 0x5, 0xe, 0xa, 0xd, 0xf, 0x6, 0x5, 0x8, 0xe, 0xb, 0xa, 0x4, 0xc, 0x0, 0x3, 0x7, 0x2, 0x9, 0x1, 0xd, 0x3, 0x8, 0xd, 0x9, 0x6, 0xb, 0xf, 0x0, 0x2, 0x5, 0xc, 0xa, 0x4, 0xe, 0x1, 0x7, 0xf, 0x8, 0xe, 0x9, 0x7, 0x2, 0x0, 0xd, 0xc, 0x6, 0x1, 0x5, 0xb, 0x4, 0x3, 0xa, 0x2, 0x8, 0x9, 0x7, 0x5, 0xf, 0x0, 0xb, 0xc, 0x1, 0xd, 0xe, 0xa, 0x3, 0x6, 0x4, 0x3, 0x8, 0xb, 0x5, 0x6, 0x4, 0xe, 0xa, 0x2, 0xc, 0x1, 0x7, 0x9, 0xf, 0xd, 0x0, 0x1, 0x2, 0x3, 0xe, 0x6, 0xd, 0xb, 0x8, 0xf, 0xa, 0xc, 0x5, 0x7, 0x9, 0x0, 0x4 }; public SignatureSpi() { //TODO: Add default ua s-box //this.digest = new GOST3411Digest(DEFAULT_SBOX); this.signer = new DSTU4145Signer(); } protected void engineInitVerify( PublicKey publicKey) throws InvalidKeyException { CipherParameters param; if (publicKey instanceof ECPublicKey) { param = ECUtil.generatePublicKeyParameter(publicKey); } else { try { byte[] bytes = publicKey.getEncoded(); publicKey = BouncyCastleProvider.getPublicKey(SubjectPublicKeyInfo.getInstance(bytes)); if (publicKey instanceof ECPublicKey) { param = ECUtil.generatePublicKeyParameter(publicKey); } else { throw new InvalidKeyException("can't recognise key type in DSA based signer"); } } catch (Exception e) { throw new InvalidKeyException("can't recognise key type in DSA based signer"); } } digest = new GOST3411Digest(expandSbox(((BCDSTU4145PublicKey)publicKey).getSbox())); signer.init(false, param); } byte[] expandSbox(byte[] compressed) { byte[] expanded = new byte[128]; for (int i = 0; i < compressed.length; i++) { expanded[i * 2] = (byte)((compressed[i] >> 4) & 0xf); expanded[i * 2 + 1] = (byte)(compressed[i] & 0xf); } return expanded; } protected void engineInitSign( PrivateKey privateKey) throws InvalidKeyException { CipherParameters param = null; if (privateKey instanceof ECKey) { param = ECUtil.generatePrivateKeyParameter(privateKey); } digest = new GOST3411Digest(DEFAULT_SBOX); if (appRandom != null) { signer.init(true, new ParametersWithRandom(param, appRandom)); } else { signer.init(true, param); } } protected void engineUpdate( byte b) throws SignatureException { digest.update(b); } protected void engineUpdate( byte[] b, int off, int len) throws SignatureException { digest.update(b, off, len); } protected byte[] engineSign() throws SignatureException { byte[] hash = new byte[digest.getDigestSize()]; digest.doFinal(hash, 0); try { BigInteger[] sig = signer.generateSignature(hash); byte[] r = sig[0].toByteArray(); byte[] s = sig[1].toByteArray(); byte[] sigBytes = new byte[(r.length > s.length ? r.length * 2 : s.length * 2)]; System.arraycopy(s, 0, sigBytes, (sigBytes.length / 2) - s.length, s.length); System.arraycopy(r, 0, sigBytes, sigBytes.length - r.length, r.length); return new DEROctetString(sigBytes).getEncoded(); } catch (Exception e) { throw new SignatureException(e.toString()); } } protected boolean engineVerify( byte[] sigBytes) throws SignatureException { byte[] hash = new byte[digest.getDigestSize()]; digest.doFinal(hash, 0); BigInteger[] sig; try { byte[] bytes = ((ASN1OctetString)ASN1OctetString.fromByteArray(sigBytes)).getOctets(); byte[] r = new byte[bytes.length / 2]; byte[] s = new byte[bytes.length / 2]; System.arraycopy(bytes, 0, s, 0, bytes.length / 2); System.arraycopy(bytes, bytes.length / 2, r, 0, bytes.length / 2); sig = new BigInteger[2]; sig[0] = new BigInteger(1, r); sig[1] = new BigInteger(1, s); } catch (Exception e) { throw new SignatureException("error decoding signature bytes."); } return signer.verifySignature(hash, sig[0], sig[1]); } protected void engineSetParameter( AlgorithmParameterSpec params) { throw new UnsupportedOperationException("engineSetParameter unsupported"); } /** * @deprecated replaced with
    */ protected void engineSetParameter( String param, Object value) { throw new UnsupportedOperationException("engineSetParameter unsupported"); } /** * @deprecated */ protected Object engineGetParameter( String param) { throw new UnsupportedOperationException("engineSetParameter unsupported"); } } bouncycastle-1.49.orig/src/org/bouncycastle/jcajce/provider/asymmetric/dstu/BCDSTU4145PublicKey.java0000644000175000017500000004352512110037231032663 0ustar ebourgebourgpackage org.bouncycastle.jcajce.provider.asymmetric.dstu; import java.io.IOException; import java.io.ObjectInputStream; import java.io.ObjectOutputStream; import java.math.BigInteger; import java.security.interfaces.ECPublicKey; import java.security.spec.ECParameterSpec; import java.security.spec.ECPoint; import java.security.spec.ECPublicKeySpec; import java.security.spec.EllipticCurve; import org.bouncycastle.asn1.ASN1Encodable; import org.bouncycastle.asn1.ASN1ObjectIdentifier; import org.bouncycastle.asn1.ASN1OctetString; import org.bouncycastle.asn1.ASN1Primitive; import org.bouncycastle.asn1.ASN1Sequence; import org.bouncycastle.asn1.DERBitString; import org.bouncycastle.asn1.DERNull; import org.bouncycastle.asn1.DEROctetString; import org.bouncycastle.asn1.ua.DSTU4145BinaryField; import org.bouncycastle.asn1.ua.DSTU4145ECBinary; import org.bouncycastle.asn1.ua.DSTU4145NamedCurves; import org.bouncycastle.asn1.ua.DSTU4145Params; import org.bouncycastle.asn1.ua.DSTU4145PointEncoder; import org.bouncycastle.asn1.ua.UAObjectIdentifiers; import org.bouncycastle.asn1.x509.AlgorithmIdentifier; import org.bouncycastle.asn1.x509.SubjectPublicKeyInfo; import org.bouncycastle.asn1.x9.X962Parameters; import org.bouncycastle.asn1.x9.X9ECParameters; import org.bouncycastle.asn1.x9.X9ECPoint; import org.bouncycastle.asn1.x9.X9IntegerConverter; import org.bouncycastle.asn1.x9.X9ObjectIdentifiers; import org.bouncycastle.crypto.params.ECDomainParameters; import org.bouncycastle.crypto.params.ECPublicKeyParameters; import org.bouncycastle.jcajce.provider.asymmetric.util.EC5Util; import org.bouncycastle.jcajce.provider.asymmetric.util.ECUtil; import org.bouncycastle.jcajce.provider.asymmetric.util.KeyUtil; import org.bouncycastle.jce.interfaces.ECPointEncoder; import org.bouncycastle.jce.provider.BouncyCastleProvider; import org.bouncycastle.jce.spec.ECNamedCurveParameterSpec; import org.bouncycastle.jce.spec.ECNamedCurveSpec; import org.bouncycastle.math.ec.ECCurve; public class BCDSTU4145PublicKey implements ECPublicKey, org.bouncycastle.jce.interfaces.ECPublicKey, ECPointEncoder { static final long serialVersionUID = 7026240464295649314L; private String algorithm = "DSTU4145"; private boolean withCompression; private transient org.bouncycastle.math.ec.ECPoint q; private transient ECParameterSpec ecSpec; private transient DSTU4145Params dstuParams; public BCDSTU4145PublicKey( BCDSTU4145PublicKey key) { this.q = key.q; this.ecSpec = key.ecSpec; this.withCompression = key.withCompression; this.dstuParams = key.dstuParams; } public BCDSTU4145PublicKey( ECPublicKeySpec spec) { this.ecSpec = spec.getParams(); this.q = EC5Util.convertPoint(ecSpec, spec.getW(), false); } public BCDSTU4145PublicKey( org.bouncycastle.jce.spec.ECPublicKeySpec spec) { this.q = spec.getQ(); if (spec.getParams() != null) // can be null if implictlyCa { ECCurve curve = spec.getParams().getCurve(); EllipticCurve ellipticCurve = EC5Util.convertCurve(curve, spec.getParams().getSeed()); this.ecSpec = EC5Util.convertSpec(ellipticCurve, spec.getParams()); } else { if (q.getCurve() == null) { org.bouncycastle.jce.spec.ECParameterSpec s = BouncyCastleProvider.CONFIGURATION.getEcImplicitlyCa(); q = s.getCurve().createPoint(q.getX().toBigInteger(), q.getY().toBigInteger(), false); } this.ecSpec = null; } } public BCDSTU4145PublicKey( String algorithm, ECPublicKeyParameters params, ECParameterSpec spec) { ECDomainParameters dp = params.getParameters(); this.algorithm = algorithm; this.q = params.getQ(); if (spec == null) { EllipticCurve ellipticCurve = EC5Util.convertCurve(dp.getCurve(), dp.getSeed()); this.ecSpec = createSpec(ellipticCurve, dp); } else { this.ecSpec = spec; } } public BCDSTU4145PublicKey( String algorithm, ECPublicKeyParameters params, org.bouncycastle.jce.spec.ECParameterSpec spec) { ECDomainParameters dp = params.getParameters(); this.algorithm = algorithm; this.q = params.getQ(); if (spec == null) { EllipticCurve ellipticCurve = EC5Util.convertCurve(dp.getCurve(), dp.getSeed()); this.ecSpec = createSpec(ellipticCurve, dp); } else { EllipticCurve ellipticCurve = EC5Util.convertCurve(spec.getCurve(), spec.getSeed()); this.ecSpec = EC5Util.convertSpec(ellipticCurve, spec); } } /* * called for implicitCA */ public BCDSTU4145PublicKey( String algorithm, ECPublicKeyParameters params) { this.algorithm = algorithm; this.q = params.getQ(); this.ecSpec = null; } private ECParameterSpec createSpec(EllipticCurve ellipticCurve, ECDomainParameters dp) { return new ECParameterSpec( ellipticCurve, new ECPoint( dp.getG().getX().toBigInteger(), dp.getG().getY().toBigInteger()), dp.getN(), dp.getH().intValue()); } public BCDSTU4145PublicKey( ECPublicKey key) { this.algorithm = key.getAlgorithm(); this.ecSpec = key.getParams(); this.q = EC5Util.convertPoint(this.ecSpec, key.getW(), false); } BCDSTU4145PublicKey( SubjectPublicKeyInfo info) { populateFromPubKeyInfo(info); } private void reverseBytes(byte[] bytes) { byte tmp; for (int i = 0; i < bytes.length / 2; i++) { tmp = bytes[i]; bytes[i] = bytes[bytes.length - 1 - i]; bytes[bytes.length - 1 - i] = tmp; } } private void populateFromPubKeyInfo(SubjectPublicKeyInfo info) { if (info.getAlgorithm().getAlgorithm().equals(UAObjectIdentifiers.dstu4145be) || info.getAlgorithm().getAlgorithm().equals(UAObjectIdentifiers.dstu4145le)) { DERBitString bits = info.getPublicKeyData(); ASN1OctetString key; this.algorithm = "DSTU4145"; try { key = (ASN1OctetString)ASN1Primitive.fromByteArray(bits.getBytes()); } catch (IOException ex) { throw new IllegalArgumentException("error recovering public key"); } byte[] keyEnc = key.getOctets(); if (info.getAlgorithm().getAlgorithm().equals(UAObjectIdentifiers.dstu4145le)) { reverseBytes(keyEnc); } dstuParams = DSTU4145Params.getInstance((ASN1Sequence)info.getAlgorithm().getParameters()); //ECNamedCurveParameterSpec spec = ECGOST3410NamedCurveTable.getParameterSpec(ECGOST3410NamedCurves.getName(gostParams.getPublicKeyParamSet())); org.bouncycastle.jce.spec.ECParameterSpec spec = null; if (dstuParams.isNamedCurve()) { ASN1ObjectIdentifier curveOid = dstuParams.getNamedCurve(); ECDomainParameters ecP = DSTU4145NamedCurves.getByOID(curveOid); spec = new ECNamedCurveParameterSpec(curveOid.getId(), ecP.getCurve(), ecP.getG(), ecP.getN(), ecP.getH(), ecP.getSeed()); } else { DSTU4145ECBinary binary = dstuParams.getECBinary(); byte[] b_bytes = binary.getB(); if (info.getAlgorithm().getAlgorithm().equals(UAObjectIdentifiers.dstu4145le)) { reverseBytes(b_bytes); } DSTU4145BinaryField field = binary.getField(); ECCurve curve = new ECCurve.F2m(field.getM(), field.getK1(), field.getK2(), field.getK3(), binary.getA(), new BigInteger(1, b_bytes)); byte[] g_bytes = binary.getG(); if (info.getAlgorithm().getAlgorithm().equals(UAObjectIdentifiers.dstu4145le)) { reverseBytes(g_bytes); } spec = new org.bouncycastle.jce.spec.ECParameterSpec(curve, DSTU4145PointEncoder.decodePoint(curve, g_bytes), binary.getN()); } ECCurve curve = spec.getCurve(); EllipticCurve ellipticCurve = EC5Util.convertCurve(curve, spec.getSeed()); //this.q = curve.createPoint(new BigInteger(1, x), new BigInteger(1, y), false); this.q = DSTU4145PointEncoder.decodePoint(curve, keyEnc); if (dstuParams.isNamedCurve()) { ecSpec = new ECNamedCurveSpec( dstuParams.getNamedCurve().getId(), ellipticCurve, new ECPoint( spec.getG().getX().toBigInteger(), spec.getG().getY().toBigInteger()), spec.getN(), spec.getH()); } else { ecSpec = new ECParameterSpec( ellipticCurve, new ECPoint( spec.getG().getX().toBigInteger(), spec.getG().getY().toBigInteger()), spec.getN(), spec.getH().intValue()); } } else { X962Parameters params = new X962Parameters((ASN1Primitive)info.getAlgorithm().getParameters()); ECCurve curve; EllipticCurve ellipticCurve; if (params.isNamedCurve()) { ASN1ObjectIdentifier oid = (ASN1ObjectIdentifier)params.getParameters(); X9ECParameters ecP = ECUtil.getNamedCurveByOid(oid); curve = ecP.getCurve(); ellipticCurve = EC5Util.convertCurve(curve, ecP.getSeed()); ecSpec = new ECNamedCurveSpec( ECUtil.getCurveName(oid), ellipticCurve, new ECPoint( ecP.getG().getX().toBigInteger(), ecP.getG().getY().toBigInteger()), ecP.getN(), ecP.getH()); } else if (params.isImplicitlyCA()) { ecSpec = null; curve = BouncyCastleProvider.CONFIGURATION.getEcImplicitlyCa().getCurve(); } else { X9ECParameters ecP = X9ECParameters.getInstance(params.getParameters()); curve = ecP.getCurve(); ellipticCurve = EC5Util.convertCurve(curve, ecP.getSeed()); this.ecSpec = new ECParameterSpec( ellipticCurve, new ECPoint( ecP.getG().getX().toBigInteger(), ecP.getG().getY().toBigInteger()), ecP.getN(), ecP.getH().intValue()); } DERBitString bits = info.getPublicKeyData(); byte[] data = bits.getBytes(); ASN1OctetString key = new DEROctetString(data); // // extra octet string - one of our old certs... // if (data[0] == 0x04 && data[1] == data.length - 2 && (data[2] == 0x02 || data[2] == 0x03)) { int qLength = new X9IntegerConverter().getByteLength(curve); if (qLength >= data.length - 3) { try { key = (ASN1OctetString)ASN1Primitive.fromByteArray(data); } catch (IOException ex) { throw new IllegalArgumentException("error recovering public key"); } } } X9ECPoint derQ = new X9ECPoint(curve, key); this.q = derQ.getPoint(); } } public byte[] getSbox() { if (null != dstuParams) { return dstuParams.getDKE(); } else { return DSTU4145Params.getDefaultDKE(); } } public String getAlgorithm() { return algorithm; } public String getFormat() { return "X.509"; } public byte[] getEncoded() { ASN1Encodable params; SubjectPublicKeyInfo info; if (algorithm.equals("DSTU4145")) { if (dstuParams != null) { params = dstuParams; } else { if (ecSpec instanceof ECNamedCurveSpec) { params = new DSTU4145Params(new ASN1ObjectIdentifier(((ECNamedCurveSpec)ecSpec).getName())); } else { // strictly speaking this may not be applicable... ECCurve curve = EC5Util.convertCurve(ecSpec.getCurve()); X9ECParameters ecP = new X9ECParameters( curve, EC5Util.convertPoint(curve, ecSpec.getGenerator(), withCompression), ecSpec.getOrder(), BigInteger.valueOf(ecSpec.getCofactor()), ecSpec.getCurve().getSeed()); params = new X962Parameters(ecP); } } byte[] encKey = DSTU4145PointEncoder.encodePoint(this.q); try { info = new SubjectPublicKeyInfo(new AlgorithmIdentifier(UAObjectIdentifiers.dstu4145be, params), new DEROctetString(encKey)); } catch (IOException e) { return null; } } else { if (ecSpec instanceof ECNamedCurveSpec) { ASN1ObjectIdentifier curveOid = ECUtil.getNamedCurveOid(((ECNamedCurveSpec)ecSpec).getName()); if (curveOid == null) { curveOid = new ASN1ObjectIdentifier(((ECNamedCurveSpec)ecSpec).getName()); } params = new X962Parameters(curveOid); } else if (ecSpec == null) { params = new X962Parameters(DERNull.INSTANCE); } else { ECCurve curve = EC5Util.convertCurve(ecSpec.getCurve()); X9ECParameters ecP = new X9ECParameters( curve, EC5Util.convertPoint(curve, ecSpec.getGenerator(), withCompression), ecSpec.getOrder(), BigInteger.valueOf(ecSpec.getCofactor()), ecSpec.getCurve().getSeed()); params = new X962Parameters(ecP); } ECCurve curve = this.engineGetQ().getCurve(); ASN1OctetString p = (ASN1OctetString) new X9ECPoint(curve.createPoint(this.getQ().getX().toBigInteger(), this.getQ().getY().toBigInteger(), withCompression)).toASN1Primitive(); info = new SubjectPublicKeyInfo(new AlgorithmIdentifier(X9ObjectIdentifiers.id_ecPublicKey, params), p.getOctets()); } return KeyUtil.getEncodedSubjectPublicKeyInfo(info); } public ECParameterSpec getParams() { return ecSpec; } public org.bouncycastle.jce.spec.ECParameterSpec getParameters() { if (ecSpec == null) // implictlyCA { return null; } return EC5Util.convertSpec(ecSpec, withCompression); } public ECPoint getW() { return new ECPoint(q.getX().toBigInteger(), q.getY().toBigInteger()); } public org.bouncycastle.math.ec.ECPoint getQ() { if (ecSpec == null) { if (q instanceof org.bouncycastle.math.ec.ECPoint.Fp) { return new org.bouncycastle.math.ec.ECPoint.Fp(null, q.getX(), q.getY()); } else { return new org.bouncycastle.math.ec.ECPoint.F2m(null, q.getX(), q.getY()); } } return q; } public org.bouncycastle.math.ec.ECPoint engineGetQ() { return q; } org.bouncycastle.jce.spec.ECParameterSpec engineGetSpec() { if (ecSpec != null) { return EC5Util.convertSpec(ecSpec, withCompression); } return BouncyCastleProvider.CONFIGURATION.getEcImplicitlyCa(); } public String toString() { StringBuffer buf = new StringBuffer(); String nl = System.getProperty("line.separator"); buf.append("EC Public Key").append(nl); buf.append(" X: ").append(this.q.getX().toBigInteger().toString(16)).append(nl); buf.append(" Y: ").append(this.q.getY().toBigInteger().toString(16)).append(nl); return buf.toString(); } public void setPointFormat(String style) { withCompression = !("UNCOMPRESSED".equalsIgnoreCase(style)); } public boolean equals(Object o) { if (!(o instanceof BCDSTU4145PublicKey)) { return false; } BCDSTU4145PublicKey other = (BCDSTU4145PublicKey)o; return engineGetQ().equals(other.engineGetQ()) && (engineGetSpec().equals(other.engineGetSpec())); } public int hashCode() { return engineGetQ().hashCode() ^ engineGetSpec().hashCode(); } private void readObject( ObjectInputStream in) throws IOException, ClassNotFoundException { in.defaultReadObject(); byte[] enc = (byte[])in.readObject(); populateFromPubKeyInfo(SubjectPublicKeyInfo.getInstance(ASN1Primitive.fromByteArray(enc))); } private void writeObject( ObjectOutputStream out) throws IOException { out.defaultWriteObject(); out.writeObject(this.getEncoded()); } } bouncycastle-1.49.orig/src/org/bouncycastle/jcajce/provider/asymmetric/dstu/KeyFactorySpi.java0000644000175000017500000001364212110037231032302 0ustar ebourgebourgpackage org.bouncycastle.jcajce.provider.asymmetric.dstu; import java.io.IOException; import java.security.InvalidKeyException; import java.security.Key; import java.security.PrivateKey; import java.security.PublicKey; import java.security.interfaces.ECPrivateKey; import java.security.interfaces.ECPublicKey; import java.security.spec.InvalidKeySpecException; import java.security.spec.KeySpec; import org.bouncycastle.asn1.ASN1ObjectIdentifier; import org.bouncycastle.asn1.pkcs.PrivateKeyInfo; import org.bouncycastle.asn1.ua.UAObjectIdentifiers; import org.bouncycastle.asn1.x509.SubjectPublicKeyInfo; import org.bouncycastle.jcajce.provider.asymmetric.util.EC5Util; import org.bouncycastle.jcajce.provider.asymmetric.util.BaseKeyFactorySpi; import org.bouncycastle.jce.provider.BouncyCastleProvider; import org.bouncycastle.jce.spec.ECParameterSpec; import org.bouncycastle.jce.spec.ECPrivateKeySpec; import org.bouncycastle.jce.spec.ECPublicKeySpec; public class KeyFactorySpi extends BaseKeyFactorySpi { public KeyFactorySpi() { } protected KeySpec engineGetKeySpec( Key key, Class spec) throws InvalidKeySpecException { if (spec.isAssignableFrom(java.security.spec.ECPublicKeySpec.class) && key instanceof ECPublicKey) { ECPublicKey k = (ECPublicKey)key; if (k.getParams() != null) { return new java.security.spec.ECPublicKeySpec(k.getW(), k.getParams()); } else { ECParameterSpec implicitSpec = BouncyCastleProvider.CONFIGURATION.getEcImplicitlyCa(); return new java.security.spec.ECPublicKeySpec(k.getW(), EC5Util.convertSpec(EC5Util.convertCurve(implicitSpec.getCurve(), implicitSpec.getSeed()), implicitSpec)); } } else if (spec.isAssignableFrom(java.security.spec.ECPrivateKeySpec.class) && key instanceof ECPrivateKey) { ECPrivateKey k = (ECPrivateKey)key; if (k.getParams() != null) { return new java.security.spec.ECPrivateKeySpec(k.getS(), k.getParams()); } else { ECParameterSpec implicitSpec = BouncyCastleProvider.CONFIGURATION.getEcImplicitlyCa(); return new java.security.spec.ECPrivateKeySpec(k.getS(), EC5Util.convertSpec(EC5Util.convertCurve(implicitSpec.getCurve(), implicitSpec.getSeed()), implicitSpec)); } } else if (spec.isAssignableFrom(org.bouncycastle.jce.spec.ECPublicKeySpec.class) && key instanceof ECPublicKey) { ECPublicKey k = (ECPublicKey)key; if (k.getParams() != null) { return new org.bouncycastle.jce.spec.ECPublicKeySpec(EC5Util.convertPoint(k.getParams(), k.getW(), false), EC5Util.convertSpec(k.getParams(), false)); } else { ECParameterSpec implicitSpec = BouncyCastleProvider.CONFIGURATION.getEcImplicitlyCa(); return new org.bouncycastle.jce.spec.ECPublicKeySpec(EC5Util.convertPoint(k.getParams(), k.getW(), false), implicitSpec); } } else if (spec.isAssignableFrom(org.bouncycastle.jce.spec.ECPrivateKeySpec.class) && key instanceof ECPrivateKey) { ECPrivateKey k = (ECPrivateKey)key; if (k.getParams() != null) { return new org.bouncycastle.jce.spec.ECPrivateKeySpec(k.getS(), EC5Util.convertSpec(k.getParams(), false)); } else { ECParameterSpec implicitSpec = BouncyCastleProvider.CONFIGURATION.getEcImplicitlyCa(); return new org.bouncycastle.jce.spec.ECPrivateKeySpec(k.getS(), implicitSpec); } } return super.engineGetKeySpec(key, spec); } protected Key engineTranslateKey( Key key) throws InvalidKeyException { throw new InvalidKeyException("key type unknown"); } protected PrivateKey engineGeneratePrivate( KeySpec keySpec) throws InvalidKeySpecException { if (keySpec instanceof ECPrivateKeySpec) { return new BCDSTU4145PrivateKey((ECPrivateKeySpec)keySpec); } else if (keySpec instanceof java.security.spec.ECPrivateKeySpec) { return new BCDSTU4145PrivateKey((java.security.spec.ECPrivateKeySpec)keySpec); } return super.engineGeneratePrivate(keySpec); } protected PublicKey engineGeneratePublic( KeySpec keySpec) throws InvalidKeySpecException { if (keySpec instanceof ECPublicKeySpec) { return new BCDSTU4145PublicKey((ECPublicKeySpec)keySpec); } else if (keySpec instanceof java.security.spec.ECPublicKeySpec) { return new BCDSTU4145PublicKey((java.security.spec.ECPublicKeySpec)keySpec); } return super.engineGeneratePublic(keySpec); } public PrivateKey generatePrivate(PrivateKeyInfo keyInfo) throws IOException { ASN1ObjectIdentifier algOid = keyInfo.getPrivateKeyAlgorithm().getAlgorithm(); if (algOid.equals(UAObjectIdentifiers.dstu4145le) || algOid.equals(UAObjectIdentifiers.dstu4145be)) { return new BCDSTU4145PrivateKey(keyInfo); } else { throw new IOException("algorithm identifier " + algOid + " in key not recognised"); } } public PublicKey generatePublic(SubjectPublicKeyInfo keyInfo) throws IOException { ASN1ObjectIdentifier algOid = keyInfo.getAlgorithm().getAlgorithm(); if (algOid.equals(UAObjectIdentifiers.dstu4145le) || algOid.equals(UAObjectIdentifiers.dstu4145be)) { return new BCDSTU4145PublicKey(keyInfo); } else { throw new IOException("algorithm identifier " + algOid + " in key not recognised"); } } } bouncycastle-1.49.orig/src/org/bouncycastle/jcajce/provider/asymmetric/dstu/SignatureSpiLe.java0000644000175000017500000000317512057027626032465 0ustar ebourgebourgpackage org.bouncycastle.jcajce.provider.asymmetric.dstu; import java.io.IOException; import java.security.SignatureException; import org.bouncycastle.asn1.ASN1OctetString; import org.bouncycastle.asn1.DEROctetString; public class SignatureSpiLe extends SignatureSpi { void reverseBytes(byte[] bytes) { byte tmp; for (int i = 0; i < bytes.length / 2; i++) { tmp = bytes[i]; bytes[i] = bytes[bytes.length - 1 - i]; bytes[bytes.length - 1 - i] = tmp; } } protected byte[] engineSign() throws SignatureException { byte[] signature = ASN1OctetString.getInstance(super.engineSign()).getOctets(); reverseBytes(signature); try { return (new DEROctetString(signature)).getEncoded(); } catch (Exception e) { throw new SignatureException(e.toString()); } } protected boolean engineVerify( byte[] sigBytes) throws SignatureException { byte[] bytes = null; try { bytes = ((ASN1OctetString)ASN1OctetString.fromByteArray(sigBytes)).getOctets(); } catch (IOException e) { throw new SignatureException("error decoding signature bytes."); } reverseBytes(bytes); try { return super.engineVerify((new DEROctetString(bytes)).getEncoded()); } catch (SignatureException e) { throw e; } catch (Exception e) { throw new SignatureException(e.toString()); } } } ././@LongLink0000000000000000000000000000014600000000000011566 Lustar rootrootbouncycastle-1.49.orig/src/org/bouncycastle/jcajce/provider/asymmetric/dstu/BCDSTU4145PrivateKey.javabouncycastle-1.49.orig/src/org/bouncycastle/jcajce/provider/asymmetric/dstu/BCDSTU4145PrivateKey.jav0000644000175000017500000003277412110037231032722 0ustar ebourgebourgpackage org.bouncycastle.jcajce.provider.asymmetric.dstu; import java.io.IOException; import java.io.ObjectInputStream; import java.io.ObjectOutputStream; import java.math.BigInteger; import java.security.interfaces.ECPrivateKey; import java.security.spec.ECParameterSpec; import java.security.spec.ECPoint; import java.security.spec.ECPrivateKeySpec; import java.security.spec.EllipticCurve; import java.util.Enumeration; import org.bouncycastle.asn1.ASN1Encodable; import org.bouncycastle.asn1.ASN1Encoding; import org.bouncycastle.asn1.ASN1ObjectIdentifier; import org.bouncycastle.asn1.ASN1Primitive; import org.bouncycastle.asn1.DERBitString; import org.bouncycastle.asn1.DERInteger; import org.bouncycastle.asn1.DERNull; import org.bouncycastle.asn1.DERObjectIdentifier; import org.bouncycastle.asn1.pkcs.PrivateKeyInfo; import org.bouncycastle.asn1.ua.DSTU4145NamedCurves; import org.bouncycastle.asn1.ua.UAObjectIdentifiers; import org.bouncycastle.asn1.x509.AlgorithmIdentifier; import org.bouncycastle.asn1.x509.SubjectPublicKeyInfo; import org.bouncycastle.asn1.x9.X962Parameters; import org.bouncycastle.asn1.x9.X9ECParameters; import org.bouncycastle.asn1.x9.X9ObjectIdentifiers; import org.bouncycastle.crypto.params.ECDomainParameters; import org.bouncycastle.crypto.params.ECPrivateKeyParameters; import org.bouncycastle.jcajce.provider.asymmetric.util.EC5Util; import org.bouncycastle.jcajce.provider.asymmetric.util.ECUtil; import org.bouncycastle.jcajce.provider.asymmetric.util.PKCS12BagAttributeCarrierImpl; import org.bouncycastle.jce.interfaces.ECPointEncoder; import org.bouncycastle.jce.interfaces.PKCS12BagAttributeCarrier; import org.bouncycastle.jce.provider.BouncyCastleProvider; import org.bouncycastle.jce.spec.ECNamedCurveSpec; import org.bouncycastle.math.ec.ECCurve; public class BCDSTU4145PrivateKey implements ECPrivateKey, org.bouncycastle.jce.interfaces.ECPrivateKey, PKCS12BagAttributeCarrier, ECPointEncoder { static final long serialVersionUID = 7245981689601667138L; private String algorithm = "DSTU4145"; private boolean withCompression; private transient BigInteger d; private transient ECParameterSpec ecSpec; private transient DERBitString publicKey; private transient PKCS12BagAttributeCarrierImpl attrCarrier = new PKCS12BagAttributeCarrierImpl(); protected BCDSTU4145PrivateKey() { } public BCDSTU4145PrivateKey( ECPrivateKey key) { this.d = key.getS(); this.algorithm = key.getAlgorithm(); this.ecSpec = key.getParams(); } public BCDSTU4145PrivateKey( org.bouncycastle.jce.spec.ECPrivateKeySpec spec) { this.d = spec.getD(); if (spec.getParams() != null) // can be null if implicitlyCA { ECCurve curve = spec.getParams().getCurve(); EllipticCurve ellipticCurve; ellipticCurve = EC5Util.convertCurve(curve, spec.getParams().getSeed()); this.ecSpec = EC5Util.convertSpec(ellipticCurve, spec.getParams()); } else { this.ecSpec = null; } } public BCDSTU4145PrivateKey( ECPrivateKeySpec spec) { this.d = spec.getS(); this.ecSpec = spec.getParams(); } public BCDSTU4145PrivateKey( BCDSTU4145PrivateKey key) { this.d = key.d; this.ecSpec = key.ecSpec; this.withCompression = key.withCompression; this.attrCarrier = key.attrCarrier; this.publicKey = key.publicKey; } public BCDSTU4145PrivateKey( String algorithm, ECPrivateKeyParameters params, BCDSTU4145PublicKey pubKey, ECParameterSpec spec) { ECDomainParameters dp = params.getParameters(); this.algorithm = algorithm; this.d = params.getD(); if (spec == null) { EllipticCurve ellipticCurve = EC5Util.convertCurve(dp.getCurve(), dp.getSeed()); this.ecSpec = new ECParameterSpec( ellipticCurve, new ECPoint( dp.getG().getX().toBigInteger(), dp.getG().getY().toBigInteger()), dp.getN(), dp.getH().intValue()); } else { this.ecSpec = spec; } publicKey = getPublicKeyDetails(pubKey); } public BCDSTU4145PrivateKey( String algorithm, ECPrivateKeyParameters params, BCDSTU4145PublicKey pubKey, org.bouncycastle.jce.spec.ECParameterSpec spec) { ECDomainParameters dp = params.getParameters(); this.algorithm = algorithm; this.d = params.getD(); if (spec == null) { EllipticCurve ellipticCurve = EC5Util.convertCurve(dp.getCurve(), dp.getSeed()); this.ecSpec = new ECParameterSpec( ellipticCurve, new ECPoint( dp.getG().getX().toBigInteger(), dp.getG().getY().toBigInteger()), dp.getN(), dp.getH().intValue()); } else { EllipticCurve ellipticCurve = EC5Util.convertCurve(spec.getCurve(), spec.getSeed()); this.ecSpec = new ECParameterSpec( ellipticCurve, new ECPoint( spec.getG().getX().toBigInteger(), spec.getG().getY().toBigInteger()), spec.getN(), spec.getH().intValue()); } publicKey = getPublicKeyDetails(pubKey); } public BCDSTU4145PrivateKey( String algorithm, ECPrivateKeyParameters params) { this.algorithm = algorithm; this.d = params.getD(); this.ecSpec = null; } BCDSTU4145PrivateKey( PrivateKeyInfo info) throws IOException { populateFromPrivKeyInfo(info); } private void populateFromPrivKeyInfo(PrivateKeyInfo info) throws IOException { X962Parameters params = new X962Parameters((ASN1Primitive)info.getPrivateKeyAlgorithm().getParameters()); if (params.isNamedCurve()) { ASN1ObjectIdentifier oid = ASN1ObjectIdentifier.getInstance(params.getParameters()); X9ECParameters ecP = ECUtil.getNamedCurveByOid(oid); if (ecP == null) // DSTU Curve { ECDomainParameters gParam = DSTU4145NamedCurves.getByOID(oid); EllipticCurve ellipticCurve = EC5Util.convertCurve(gParam.getCurve(), gParam.getSeed()); ecSpec = new ECNamedCurveSpec( oid.getId(), ellipticCurve, new ECPoint( gParam.getG().getX().toBigInteger(), gParam.getG().getY().toBigInteger()), gParam.getN(), gParam.getH()); } else { EllipticCurve ellipticCurve = EC5Util.convertCurve(ecP.getCurve(), ecP.getSeed()); ecSpec = new ECNamedCurveSpec( ECUtil.getCurveName(oid), ellipticCurve, new ECPoint( ecP.getG().getX().toBigInteger(), ecP.getG().getY().toBigInteger()), ecP.getN(), ecP.getH()); } } else if (params.isImplicitlyCA()) { ecSpec = null; } else { X9ECParameters ecP = X9ECParameters.getInstance(params.getParameters()); EllipticCurve ellipticCurve = EC5Util.convertCurve(ecP.getCurve(), ecP.getSeed()); this.ecSpec = new ECParameterSpec( ellipticCurve, new ECPoint( ecP.getG().getX().toBigInteger(), ecP.getG().getY().toBigInteger()), ecP.getN(), ecP.getH().intValue()); } ASN1Encodable privKey = info.parsePrivateKey(); if (privKey instanceof DERInteger) { DERInteger derD = DERInteger.getInstance(privKey); this.d = derD.getValue(); } else { org.bouncycastle.asn1.sec.ECPrivateKey ec = org.bouncycastle.asn1.sec.ECPrivateKey.getInstance(privKey); this.d = ec.getKey(); this.publicKey = ec.getPublicKey(); } } public String getAlgorithm() { return algorithm; } /** * return the encoding format we produce in getEncoded(). * * @return the string "PKCS#8" */ public String getFormat() { return "PKCS#8"; } /** * Return a PKCS8 representation of the key. The sequence returned * represents a full PrivateKeyInfo object. * * @return a PKCS8 representation of the key. */ public byte[] getEncoded() { X962Parameters params; if (ecSpec instanceof ECNamedCurveSpec) { DERObjectIdentifier curveOid = ECUtil.getNamedCurveOid(((ECNamedCurveSpec)ecSpec).getName()); if (curveOid == null) // guess it's the OID { curveOid = new DERObjectIdentifier(((ECNamedCurveSpec)ecSpec).getName()); } params = new X962Parameters(curveOid); } else if (ecSpec == null) { params = new X962Parameters(DERNull.INSTANCE); } else { ECCurve curve = EC5Util.convertCurve(ecSpec.getCurve()); X9ECParameters ecP = new X9ECParameters( curve, EC5Util.convertPoint(curve, ecSpec.getGenerator(), withCompression), ecSpec.getOrder(), BigInteger.valueOf(ecSpec.getCofactor()), ecSpec.getCurve().getSeed()); params = new X962Parameters(ecP); } PrivateKeyInfo info; org.bouncycastle.asn1.sec.ECPrivateKey keyStructure; if (publicKey != null) { keyStructure = new org.bouncycastle.asn1.sec.ECPrivateKey(this.getS(), publicKey, params); } else { keyStructure = new org.bouncycastle.asn1.sec.ECPrivateKey(this.getS(), params); } try { if (algorithm.equals("DSTU4145")) { info = new PrivateKeyInfo(new AlgorithmIdentifier(UAObjectIdentifiers.dstu4145be, params.toASN1Primitive()), keyStructure.toASN1Primitive()); } else { info = new PrivateKeyInfo(new AlgorithmIdentifier(X9ObjectIdentifiers.id_ecPublicKey, params.toASN1Primitive()), keyStructure.toASN1Primitive()); } return info.getEncoded(ASN1Encoding.DER); } catch (IOException e) { return null; } } public ECParameterSpec getParams() { return ecSpec; } public org.bouncycastle.jce.spec.ECParameterSpec getParameters() { if (ecSpec == null) { return null; } return EC5Util.convertSpec(ecSpec, withCompression); } org.bouncycastle.jce.spec.ECParameterSpec engineGetSpec() { if (ecSpec != null) { return EC5Util.convertSpec(ecSpec, withCompression); } return BouncyCastleProvider.CONFIGURATION.getEcImplicitlyCa(); } public BigInteger getS() { return d; } public BigInteger getD() { return d; } public void setBagAttribute( ASN1ObjectIdentifier oid, ASN1Encodable attribute) { attrCarrier.setBagAttribute(oid, attribute); } public ASN1Encodable getBagAttribute( ASN1ObjectIdentifier oid) { return attrCarrier.getBagAttribute(oid); } public Enumeration getBagAttributeKeys() { return attrCarrier.getBagAttributeKeys(); } public void setPointFormat(String style) { withCompression = !("UNCOMPRESSED".equalsIgnoreCase(style)); } public boolean equals(Object o) { if (!(o instanceof BCDSTU4145PrivateKey)) { return false; } BCDSTU4145PrivateKey other = (BCDSTU4145PrivateKey)o; return getD().equals(other.getD()) && (engineGetSpec().equals(other.engineGetSpec())); } public int hashCode() { return getD().hashCode() ^ engineGetSpec().hashCode(); } public String toString() { StringBuffer buf = new StringBuffer(); String nl = System.getProperty("line.separator"); buf.append("EC Private Key").append(nl); buf.append(" S: ").append(this.d.toString(16)).append(nl); return buf.toString(); } private DERBitString getPublicKeyDetails(BCDSTU4145PublicKey pub) { try { SubjectPublicKeyInfo info = SubjectPublicKeyInfo.getInstance(ASN1Primitive.fromByteArray(pub.getEncoded())); return info.getPublicKeyData(); } catch (IOException e) { // should never happen return null; } } private void readObject( ObjectInputStream in) throws IOException, ClassNotFoundException { in.defaultReadObject(); byte[] enc = (byte[])in.readObject(); populateFromPrivKeyInfo(PrivateKeyInfo.getInstance(ASN1Primitive.fromByteArray(enc))); this.attrCarrier = new PKCS12BagAttributeCarrierImpl(); } private void writeObject( ObjectOutputStream out) throws IOException { out.defaultWriteObject(); out.writeObject(this.getEncoded()); } } bouncycastle-1.49.orig/src/org/bouncycastle/jcajce/provider/asymmetric/dstu/KeyPairGeneratorSpi.java0000644000175000017500000001521612110037231033434 0ustar ebourgebourgpackage org.bouncycastle.jcajce.provider.asymmetric.dstu; import java.math.BigInteger; import java.security.InvalidAlgorithmParameterException; import java.security.InvalidParameterException; import java.security.KeyPair; import java.security.SecureRandom; import java.security.spec.AlgorithmParameterSpec; import java.security.spec.ECGenParameterSpec; import org.bouncycastle.asn1.ASN1ObjectIdentifier; import org.bouncycastle.asn1.ua.DSTU4145NamedCurves; import org.bouncycastle.crypto.AsymmetricCipherKeyPair; import org.bouncycastle.crypto.generators.DSTU4145KeyPairGenerator; import org.bouncycastle.crypto.generators.ECKeyPairGenerator; import org.bouncycastle.crypto.params.ECDomainParameters; import org.bouncycastle.crypto.params.ECKeyGenerationParameters; import org.bouncycastle.crypto.params.ECPrivateKeyParameters; import org.bouncycastle.crypto.params.ECPublicKeyParameters; import org.bouncycastle.jcajce.provider.asymmetric.util.EC5Util; import org.bouncycastle.jce.provider.BouncyCastleProvider; import org.bouncycastle.jce.spec.ECNamedCurveGenParameterSpec; import org.bouncycastle.jce.spec.ECNamedCurveSpec; import org.bouncycastle.jce.spec.ECParameterSpec; import org.bouncycastle.math.ec.ECCurve; import org.bouncycastle.math.ec.ECPoint; public class KeyPairGeneratorSpi extends java.security.KeyPairGenerator { Object ecParams = null; ECKeyPairGenerator engine = new DSTU4145KeyPairGenerator(); String algorithm = "DSTU4145"; ECKeyGenerationParameters param; //int strength = 239; SecureRandom random = null; boolean initialised = false; public KeyPairGeneratorSpi() { super("DSTU4145"); } public void initialize( int strength, SecureRandom random) { this.random = random; if (ecParams != null) { try { initialize((ECGenParameterSpec)ecParams, random); } catch (InvalidAlgorithmParameterException e) { throw new InvalidParameterException("key size not configurable."); } } else { throw new InvalidParameterException("unknown key size."); } } public void initialize( AlgorithmParameterSpec params, SecureRandom random) throws InvalidAlgorithmParameterException { if (params instanceof ECParameterSpec) { ECParameterSpec p = (ECParameterSpec)params; this.ecParams = params; param = new ECKeyGenerationParameters(new ECDomainParameters(p.getCurve(), p.getG(), p.getN()), random); engine.init(param); initialised = true; } else if (params instanceof java.security.spec.ECParameterSpec) { java.security.spec.ECParameterSpec p = (java.security.spec.ECParameterSpec)params; this.ecParams = params; ECCurve curve = EC5Util.convertCurve(p.getCurve()); ECPoint g = EC5Util.convertPoint(curve, p.getGenerator(), false); param = new ECKeyGenerationParameters(new ECDomainParameters(curve, g, p.getOrder(), BigInteger.valueOf(p.getCofactor())), random); engine.init(param); initialised = true; } else if (params instanceof ECGenParameterSpec || params instanceof ECNamedCurveGenParameterSpec) { String curveName; if (params instanceof ECGenParameterSpec) { curveName = ((ECGenParameterSpec)params).getName(); } else { curveName = ((ECNamedCurveGenParameterSpec)params).getName(); } //ECDomainParameters ecP = ECGOST3410NamedCurves.getByName(curveName); ECDomainParameters ecP = DSTU4145NamedCurves.getByOID(new ASN1ObjectIdentifier(curveName)); if (ecP == null) { throw new InvalidAlgorithmParameterException("unknown curve name: " + curveName); } this.ecParams = new ECNamedCurveSpec( curveName, ecP.getCurve(), ecP.getG(), ecP.getN(), ecP.getH(), ecP.getSeed()); java.security.spec.ECParameterSpec p = (java.security.spec.ECParameterSpec)ecParams; ECCurve curve = EC5Util.convertCurve(p.getCurve()); ECPoint g = EC5Util.convertPoint(curve, p.getGenerator(), false); param = new ECKeyGenerationParameters(new ECDomainParameters(curve, g, p.getOrder(), BigInteger.valueOf(p.getCofactor())), random); engine.init(param); initialised = true; } else if (params == null && BouncyCastleProvider.CONFIGURATION.getEcImplicitlyCa() != null) { ECParameterSpec p = BouncyCastleProvider.CONFIGURATION.getEcImplicitlyCa(); this.ecParams = params; param = new ECKeyGenerationParameters(new ECDomainParameters(p.getCurve(), p.getG(), p.getN()), random); engine.init(param); initialised = true; } else if (params == null && BouncyCastleProvider.CONFIGURATION.getEcImplicitlyCa() == null) { throw new InvalidAlgorithmParameterException("null parameter passed but no implicitCA set"); } else { throw new InvalidAlgorithmParameterException("parameter object not a ECParameterSpec: " + params.getClass().getName()); } } public KeyPair generateKeyPair() { if (!initialised) { throw new IllegalStateException("DSTU Key Pair Generator not initialised"); } AsymmetricCipherKeyPair pair = engine.generateKeyPair(); ECPublicKeyParameters pub = (ECPublicKeyParameters)pair.getPublic(); ECPrivateKeyParameters priv = (ECPrivateKeyParameters)pair.getPrivate(); if (ecParams instanceof ECParameterSpec) { ECParameterSpec p = (ECParameterSpec)ecParams; BCDSTU4145PublicKey pubKey = new BCDSTU4145PublicKey(algorithm, pub, p); return new KeyPair(pubKey, new BCDSTU4145PrivateKey(algorithm, priv, pubKey, p)); } else if (ecParams == null) { return new KeyPair(new BCDSTU4145PublicKey(algorithm, pub), new BCDSTU4145PrivateKey(algorithm, priv)); } else { java.security.spec.ECParameterSpec p = (java.security.spec.ECParameterSpec)ecParams; BCDSTU4145PublicKey pubKey = new BCDSTU4145PublicKey(algorithm, pub, p); return new KeyPair(pubKey, new BCDSTU4145PrivateKey(algorithm, priv, pubKey, p)); } } } bouncycastle-1.49.orig/src/org/bouncycastle/jcajce/provider/asymmetric/DSA.java0000644000175000017500000000617512057012767027222 0ustar ebourgebourgpackage org.bouncycastle.jcajce.provider.asymmetric; import org.bouncycastle.asn1.nist.NISTObjectIdentifiers; import org.bouncycastle.jcajce.provider.asymmetric.dsa.DSAUtil; import org.bouncycastle.jcajce.provider.asymmetric.dsa.KeyFactorySpi; import org.bouncycastle.jcajce.provider.config.ConfigurableProvider; import org.bouncycastle.jcajce.provider.util.AsymmetricAlgorithmProvider; import org.bouncycastle.jcajce.provider.util.AsymmetricKeyInfoConverter; public class DSA { private static final String PREFIX = "org.bouncycastle.jcajce.provider.asymmetric" + ".dsa."; public static class Mappings extends AsymmetricAlgorithmProvider { public Mappings() { } public void configure(ConfigurableProvider provider) { provider.addAlgorithm("AlgorithmParameters.DSA", PREFIX + "AlgorithmParametersSpi"); provider.addAlgorithm("AlgorithmParameterGenerator.DSA", PREFIX + "AlgorithmParameterGeneratorSpi"); provider.addAlgorithm("KeyPairGenerator.DSA", PREFIX + "KeyPairGeneratorSpi"); provider.addAlgorithm("KeyFactory.DSA", PREFIX + "KeyFactorySpi"); provider.addAlgorithm("Signature.DSA", PREFIX + "DSASigner$stdDSA"); provider.addAlgorithm("Signature.NONEWITHDSA", PREFIX + "DSASigner$noneDSA"); provider.addAlgorithm("Alg.Alias.Signature.RAWDSA", "NONEWITHDSA"); addSignatureAlgorithm(provider, "SHA224", "DSA", PREFIX + "DSASigner$dsa224", NISTObjectIdentifiers.dsa_with_sha224); addSignatureAlgorithm(provider, "SHA256", "DSA", PREFIX + "DSASigner$dsa256", NISTObjectIdentifiers.dsa_with_sha256); addSignatureAlgorithm(provider, "SHA384", "DSA", PREFIX + "DSASigner$dsa384", NISTObjectIdentifiers.dsa_with_sha384); addSignatureAlgorithm(provider, "SHA512", "DSA", PREFIX + "DSASigner$dsa512", NISTObjectIdentifiers.dsa_with_sha512); provider.addAlgorithm("Alg.Alias.Signature.SHA/DSA", "DSA"); provider.addAlgorithm("Alg.Alias.Signature.SHA1withDSA", "DSA"); provider.addAlgorithm("Alg.Alias.Signature.SHA1WITHDSA", "DSA"); provider.addAlgorithm("Alg.Alias.Signature.1.3.14.3.2.26with1.2.840.10040.4.1", "DSA"); provider.addAlgorithm("Alg.Alias.Signature.1.3.14.3.2.26with1.2.840.10040.4.3", "DSA"); provider.addAlgorithm("Alg.Alias.Signature.DSAwithSHA1", "DSA"); provider.addAlgorithm("Alg.Alias.Signature.DSAWITHSHA1", "DSA"); provider.addAlgorithm("Alg.Alias.Signature.SHA1WithDSA", "DSA"); provider.addAlgorithm("Alg.Alias.Signature.DSAWithSHA1", "DSA"); provider.addAlgorithm("Alg.Alias.Signature.1.2.840.10040.4.3", "DSA"); AsymmetricKeyInfoConverter keyFact = new KeyFactorySpi(); for (int i = 0; i != DSAUtil.dsaOids.length; i++) { provider.addAlgorithm("Alg.Alias.Signature." + DSAUtil.dsaOids[i], "DSA"); registerOid(provider, DSAUtil.dsaOids[i], "DSA", keyFact); registerOidAlgorithmParameters(provider, DSAUtil.dsaOids[i], "DSA"); } } } } bouncycastle-1.49.orig/src/org/bouncycastle/jcajce/provider/asymmetric/elgamal/0000755000175000017500000000000012152033551027327 5ustar ebourgebourg././@LongLink0000000000000000000000000000014700000000000011567 Lustar rootrootbouncycastle-1.49.orig/src/org/bouncycastle/jcajce/provider/asymmetric/elgamal/BCElGamalPublicKey.javabouncycastle-1.49.orig/src/org/bouncycastle/jcajce/provider/asymmetric/elgamal/BCElGamalPublicKey.ja0000644000175000017500000001117411727733105033177 0ustar ebourgebourgpackage org.bouncycastle.jcajce.provider.asymmetric.elgamal; import java.io.IOException; import java.io.ObjectInputStream; import java.io.ObjectOutputStream; import java.math.BigInteger; import javax.crypto.interfaces.DHPublicKey; import javax.crypto.spec.DHParameterSpec; import javax.crypto.spec.DHPublicKeySpec; import org.bouncycastle.asn1.ASN1Encoding; import org.bouncycastle.asn1.ASN1Sequence; import org.bouncycastle.asn1.DERInteger; import org.bouncycastle.asn1.oiw.ElGamalParameter; import org.bouncycastle.asn1.oiw.OIWObjectIdentifiers; import org.bouncycastle.asn1.x509.AlgorithmIdentifier; import org.bouncycastle.asn1.x509.SubjectPublicKeyInfo; import org.bouncycastle.crypto.params.ElGamalPublicKeyParameters; import org.bouncycastle.jce.interfaces.ElGamalPublicKey; import org.bouncycastle.jce.spec.ElGamalParameterSpec; import org.bouncycastle.jce.spec.ElGamalPublicKeySpec; public class BCElGamalPublicKey implements ElGamalPublicKey, DHPublicKey { static final long serialVersionUID = 8712728417091216948L; private BigInteger y; private transient ElGamalParameterSpec elSpec; BCElGamalPublicKey( ElGamalPublicKeySpec spec) { this.y = spec.getY(); this.elSpec = new ElGamalParameterSpec(spec.getParams().getP(), spec.getParams().getG()); } BCElGamalPublicKey( DHPublicKeySpec spec) { this.y = spec.getY(); this.elSpec = new ElGamalParameterSpec(spec.getP(), spec.getG()); } BCElGamalPublicKey( ElGamalPublicKey key) { this.y = key.getY(); this.elSpec = key.getParameters(); } BCElGamalPublicKey( DHPublicKey key) { this.y = key.getY(); this.elSpec = new ElGamalParameterSpec(key.getParams().getP(), key.getParams().getG()); } BCElGamalPublicKey( ElGamalPublicKeyParameters params) { this.y = params.getY(); this.elSpec = new ElGamalParameterSpec(params.getParameters().getP(), params.getParameters().getG()); } BCElGamalPublicKey( BigInteger y, ElGamalParameterSpec elSpec) { this.y = y; this.elSpec = elSpec; } BCElGamalPublicKey( SubjectPublicKeyInfo info) { ElGamalParameter params = new ElGamalParameter((ASN1Sequence)info.getAlgorithmId().getParameters()); DERInteger derY = null; try { derY = (DERInteger)info.parsePublicKey(); } catch (IOException e) { throw new IllegalArgumentException("invalid info structure in DSA public key"); } this.y = derY.getValue(); this.elSpec = new ElGamalParameterSpec(params.getP(), params.getG()); } public String getAlgorithm() { return "ElGamal"; } public String getFormat() { return "X.509"; } public byte[] getEncoded() { try { SubjectPublicKeyInfo info = new SubjectPublicKeyInfo(new AlgorithmIdentifier(OIWObjectIdentifiers.elGamalAlgorithm, new ElGamalParameter(elSpec.getP(), elSpec.getG())), new DERInteger(y)); return info.getEncoded(ASN1Encoding.DER); } catch (IOException e) { return null; } } public ElGamalParameterSpec getParameters() { return elSpec; } public DHParameterSpec getParams() { return new DHParameterSpec(elSpec.getP(), elSpec.getG()); } public BigInteger getY() { return y; } public int hashCode() { return this.getY().hashCode() ^ this.getParams().getG().hashCode() ^ this.getParams().getP().hashCode() ^ this.getParams().getL(); } public boolean equals( Object o) { if (!(o instanceof DHPublicKey)) { return false; } DHPublicKey other = (DHPublicKey)o; return this.getY().equals(other.getY()) && this.getParams().getG().equals(other.getParams().getG()) && this.getParams().getP().equals(other.getParams().getP()) && this.getParams().getL() == other.getParams().getL(); } private void readObject( ObjectInputStream in) throws IOException, ClassNotFoundException { in.defaultReadObject(); this.elSpec = new ElGamalParameterSpec((BigInteger)in.readObject(), (BigInteger)in.readObject()); } private void writeObject( ObjectOutputStream out) throws IOException { out.defaultWriteObject(); out.writeObject(elSpec.getP()); out.writeObject(elSpec.getG()); } } ././@LongLink0000000000000000000000000000016300000000000011565 Lustar rootrootbouncycastle-1.49.orig/src/org/bouncycastle/jcajce/provider/asymmetric/elgamal/AlgorithmParameterGeneratorSpi.javabouncycastle-1.49.orig/src/org/bouncycastle/jcajce/provider/asymmetric/elgamal/AlgorithmParameterGen0000644000175000017500000000423511630055253033502 0ustar ebourgebourgpackage org.bouncycastle.jcajce.provider.asymmetric.elgamal; import java.security.AlgorithmParameters; import java.security.InvalidAlgorithmParameterException; import java.security.SecureRandom; import java.security.spec.AlgorithmParameterSpec; import javax.crypto.spec.DHGenParameterSpec; import javax.crypto.spec.DHParameterSpec; import org.bouncycastle.crypto.generators.ElGamalParametersGenerator; import org.bouncycastle.crypto.params.ElGamalParameters; import org.bouncycastle.jce.provider.BouncyCastleProvider; public class AlgorithmParameterGeneratorSpi extends java.security.AlgorithmParameterGeneratorSpi { protected SecureRandom random; protected int strength = 1024; private int l = 0; protected void engineInit( int strength, SecureRandom random) { this.strength = strength; this.random = random; } protected void engineInit( AlgorithmParameterSpec genParamSpec, SecureRandom random) throws InvalidAlgorithmParameterException { if (!(genParamSpec instanceof DHGenParameterSpec)) { throw new InvalidAlgorithmParameterException("DH parameter generator requires a DHGenParameterSpec for initialisation"); } DHGenParameterSpec spec = (DHGenParameterSpec)genParamSpec; this.strength = spec.getPrimeSize(); this.l = spec.getExponentSize(); this.random = random; } protected AlgorithmParameters engineGenerateParameters() { ElGamalParametersGenerator pGen = new ElGamalParametersGenerator(); if (random != null) { pGen.init(strength, 20, random); } else { pGen.init(strength, 20, new SecureRandom()); } ElGamalParameters p = pGen.generateParameters(); AlgorithmParameters params; try { params = AlgorithmParameters.getInstance("ElGamal", BouncyCastleProvider.PROVIDER_NAME); params.init(new DHParameterSpec(p.getP(), p.getG(), l)); } catch (Exception e) { throw new RuntimeException(e.getMessage()); } return params; } } bouncycastle-1.49.orig/src/org/bouncycastle/jcajce/provider/asymmetric/elgamal/ElGamalUtil.java0000644000175000017500000000444312110036731032334 0ustar ebourgebourgpackage org.bouncycastle.jcajce.provider.asymmetric.elgamal; import java.security.InvalidKeyException; import java.security.PrivateKey; import java.security.PublicKey; import javax.crypto.interfaces.DHPrivateKey; import javax.crypto.interfaces.DHPublicKey; import org.bouncycastle.crypto.params.AsymmetricKeyParameter; import org.bouncycastle.crypto.params.ElGamalParameters; import org.bouncycastle.crypto.params.ElGamalPrivateKeyParameters; import org.bouncycastle.crypto.params.ElGamalPublicKeyParameters; import org.bouncycastle.jce.interfaces.ElGamalPrivateKey; import org.bouncycastle.jce.interfaces.ElGamalPublicKey; /** * utility class for converting jce/jca ElGamal objects * objects into their org.bouncycastle.crypto counterparts. */ public class ElGamalUtil { static public AsymmetricKeyParameter generatePublicKeyParameter( PublicKey key) throws InvalidKeyException { if (key instanceof ElGamalPublicKey) { ElGamalPublicKey k = (ElGamalPublicKey)key; return new ElGamalPublicKeyParameters(k.getY(), new ElGamalParameters(k.getParameters().getP(), k.getParameters().getG())); } else if (key instanceof DHPublicKey) { DHPublicKey k = (DHPublicKey)key; return new ElGamalPublicKeyParameters(k.getY(), new ElGamalParameters(k.getParams().getP(), k.getParams().getG())); } throw new InvalidKeyException("can't identify public key for El Gamal."); } static public AsymmetricKeyParameter generatePrivateKeyParameter( PrivateKey key) throws InvalidKeyException { if (key instanceof ElGamalPrivateKey) { ElGamalPrivateKey k = (ElGamalPrivateKey)key; return new ElGamalPrivateKeyParameters(k.getX(), new ElGamalParameters(k.getParameters().getP(), k.getParameters().getG())); } else if (key instanceof DHPrivateKey) { DHPrivateKey k = (DHPrivateKey)key; return new ElGamalPrivateKeyParameters(k.getX(), new ElGamalParameters(k.getParams().getP(), k.getParams().getG())); } throw new InvalidKeyException("can't identify private key for El Gamal."); } } ././@LongLink0000000000000000000000000000015300000000000011564 Lustar rootrootbouncycastle-1.49.orig/src/org/bouncycastle/jcajce/provider/asymmetric/elgamal/AlgorithmParametersSpi.javabouncycastle-1.49.orig/src/org/bouncycastle/jcajce/provider/asymmetric/elgamal/AlgorithmParametersSp0000644000175000017500000000725112110040104033516 0ustar ebourgebourgpackage org.bouncycastle.jcajce.provider.asymmetric.elgamal; import java.io.IOException; import java.security.spec.AlgorithmParameterSpec; import java.security.spec.InvalidParameterSpecException; import javax.crypto.spec.DHParameterSpec; import org.bouncycastle.asn1.ASN1Encoding; import org.bouncycastle.asn1.ASN1Primitive; import org.bouncycastle.asn1.ASN1Sequence; import org.bouncycastle.asn1.oiw.ElGamalParameter; import org.bouncycastle.jcajce.provider.symmetric.util.BaseAlgorithmParameters; import org.bouncycastle.jce.spec.ElGamalParameterSpec; public class AlgorithmParametersSpi extends BaseAlgorithmParameters { ElGamalParameterSpec currentSpec; /** * Return the X.509 ASN.1 structure ElGamalParameter. *

    *

         *  ElGamalParameter ::= SEQUENCE {
         *                   prime INTEGER, -- p
         *                   base INTEGER, -- g}
         * 
    */ protected byte[] engineGetEncoded() { ElGamalParameter elP = new ElGamalParameter(currentSpec.getP(), currentSpec.getG()); try { return elP.getEncoded(ASN1Encoding.DER); } catch (IOException e) { throw new RuntimeException("Error encoding ElGamalParameters"); } } protected byte[] engineGetEncoded( String format) { if (isASN1FormatString(format) || format.equalsIgnoreCase("X.509")) { return engineGetEncoded(); } return null; } protected AlgorithmParameterSpec localEngineGetParameterSpec( Class paramSpec) throws InvalidParameterSpecException { if (paramSpec == ElGamalParameterSpec.class) { return currentSpec; } else if (paramSpec == DHParameterSpec.class) { return new DHParameterSpec(currentSpec.getP(), currentSpec.getG()); } throw new InvalidParameterSpecException("unknown parameter spec passed to ElGamal parameters object."); } protected void engineInit( AlgorithmParameterSpec paramSpec) throws InvalidParameterSpecException { if (!(paramSpec instanceof ElGamalParameterSpec) && !(paramSpec instanceof DHParameterSpec)) { throw new InvalidParameterSpecException("DHParameterSpec required to initialise a ElGamal algorithm parameters object"); } if (paramSpec instanceof ElGamalParameterSpec) { this.currentSpec = (ElGamalParameterSpec)paramSpec; } else { DHParameterSpec s = (DHParameterSpec)paramSpec; this.currentSpec = new ElGamalParameterSpec(s.getP(), s.getG()); } } protected void engineInit( byte[] params) throws IOException { try { ElGamalParameter elP = new ElGamalParameter((ASN1Sequence)ASN1Primitive.fromByteArray(params)); currentSpec = new ElGamalParameterSpec(elP.getP(), elP.getG()); } catch (ClassCastException e) { throw new IOException("Not a valid ElGamal Parameter encoding."); } catch (ArrayIndexOutOfBoundsException e) { throw new IOException("Not a valid ElGamal Parameter encoding."); } } protected void engineInit( byte[] params, String format) throws IOException { if (isASN1FormatString(format) || format.equalsIgnoreCase("X.509")) { engineInit(params); } else { throw new IOException("Unknown parameter format " + format); } } protected String engineToString() { return "ElGamal Parameters"; } } bouncycastle-1.49.orig/src/org/bouncycastle/jcajce/provider/asymmetric/elgamal/KeyFactorySpi.java0000644000175000017500000001155011625105230032726 0ustar ebourgebourgpackage org.bouncycastle.jcajce.provider.asymmetric.elgamal; import java.io.IOException; import java.security.InvalidKeyException; import java.security.Key; import java.security.PrivateKey; import java.security.PublicKey; import java.security.spec.InvalidKeySpecException; import java.security.spec.KeySpec; import javax.crypto.interfaces.DHPrivateKey; import javax.crypto.interfaces.DHPublicKey; import javax.crypto.spec.DHPrivateKeySpec; import javax.crypto.spec.DHPublicKeySpec; import org.bouncycastle.asn1.ASN1ObjectIdentifier; import org.bouncycastle.asn1.oiw.OIWObjectIdentifiers; import org.bouncycastle.asn1.pkcs.PKCSObjectIdentifiers; import org.bouncycastle.asn1.pkcs.PrivateKeyInfo; import org.bouncycastle.asn1.x509.SubjectPublicKeyInfo; import org.bouncycastle.asn1.x9.X9ObjectIdentifiers; import org.bouncycastle.jcajce.provider.asymmetric.util.BaseKeyFactorySpi; import org.bouncycastle.jce.interfaces.ElGamalPrivateKey; import org.bouncycastle.jce.interfaces.ElGamalPublicKey; import org.bouncycastle.jce.spec.ElGamalPrivateKeySpec; import org.bouncycastle.jce.spec.ElGamalPublicKeySpec; public class KeyFactorySpi extends BaseKeyFactorySpi { public KeyFactorySpi() { } protected PrivateKey engineGeneratePrivate( KeySpec keySpec) throws InvalidKeySpecException { if (keySpec instanceof ElGamalPrivateKeySpec) { return new BCElGamalPrivateKey((ElGamalPrivateKeySpec)keySpec); } else if (keySpec instanceof DHPrivateKeySpec) { return new BCElGamalPrivateKey((DHPrivateKeySpec)keySpec); } return super.engineGeneratePrivate(keySpec); } protected PublicKey engineGeneratePublic( KeySpec keySpec) throws InvalidKeySpecException { if (keySpec instanceof ElGamalPublicKeySpec) { return new BCElGamalPublicKey((ElGamalPublicKeySpec)keySpec); } else if (keySpec instanceof DHPublicKeySpec) { return new BCElGamalPublicKey((DHPublicKeySpec)keySpec); } return super.engineGeneratePublic(keySpec); } protected KeySpec engineGetKeySpec( Key key, Class spec) throws InvalidKeySpecException { if (spec.isAssignableFrom(DHPrivateKeySpec.class) && key instanceof DHPrivateKey) { DHPrivateKey k = (DHPrivateKey)key; return new DHPrivateKeySpec(k.getX(), k.getParams().getP(), k.getParams().getG()); } else if (spec.isAssignableFrom(DHPublicKeySpec.class) && key instanceof DHPublicKey) { DHPublicKey k = (DHPublicKey)key; return new DHPublicKeySpec(k.getY(), k.getParams().getP(), k.getParams().getG()); } return super.engineGetKeySpec(key, spec); } protected Key engineTranslateKey( Key key) throws InvalidKeyException { if (key instanceof DHPublicKey) { return new BCElGamalPublicKey((DHPublicKey)key); } else if (key instanceof DHPrivateKey) { return new BCElGamalPrivateKey((DHPrivateKey)key); } else if (key instanceof ElGamalPublicKey) { return new BCElGamalPublicKey((ElGamalPublicKey)key); } else if (key instanceof ElGamalPrivateKey) { return new BCElGamalPrivateKey((ElGamalPrivateKey)key); } throw new InvalidKeyException("key type unknown"); } public PrivateKey generatePrivate(PrivateKeyInfo info) throws IOException { ASN1ObjectIdentifier algOid = info.getPrivateKeyAlgorithm().getAlgorithm(); if (algOid.equals(PKCSObjectIdentifiers.dhKeyAgreement)) { return new BCElGamalPrivateKey(info); } else if (algOid.equals(X9ObjectIdentifiers.dhpublicnumber)) { return new BCElGamalPrivateKey(info); } else if (algOid.equals(OIWObjectIdentifiers.elGamalAlgorithm)) { return new BCElGamalPrivateKey(info); } else { throw new IOException("algorithm identifier " + algOid + " in key not recognised"); } } public PublicKey generatePublic(SubjectPublicKeyInfo info) throws IOException { ASN1ObjectIdentifier algOid = info.getAlgorithm().getAlgorithm(); if (algOid.equals(PKCSObjectIdentifiers.dhKeyAgreement)) { return new BCElGamalPublicKey(info); } else if (algOid.equals(X9ObjectIdentifiers.dhpublicnumber)) { return new BCElGamalPublicKey(info); } else if (algOid.equals(OIWObjectIdentifiers.elGamalAlgorithm)) { return new BCElGamalPublicKey(info); } else { throw new IOException("algorithm identifier " + algOid + " in key not recognised"); } } } ././@LongLink0000000000000000000000000000015000000000000011561 Lustar rootrootbouncycastle-1.49.orig/src/org/bouncycastle/jcajce/provider/asymmetric/elgamal/BCElGamalPrivateKey.javabouncycastle-1.49.orig/src/org/bouncycastle/jcajce/provider/asymmetric/elgamal/BCElGamalPrivateKey.j0000644000175000017500000001311111736773417033235 0ustar ebourgebourgpackage org.bouncycastle.jcajce.provider.asymmetric.elgamal; import java.io.IOException; import java.io.ObjectInputStream; import java.io.ObjectOutputStream; import java.math.BigInteger; import java.util.Enumeration; import javax.crypto.interfaces.DHPrivateKey; import javax.crypto.spec.DHParameterSpec; import javax.crypto.spec.DHPrivateKeySpec; import org.bouncycastle.asn1.ASN1Encodable; import org.bouncycastle.asn1.ASN1Encoding; import org.bouncycastle.asn1.ASN1Integer; import org.bouncycastle.asn1.ASN1ObjectIdentifier; import org.bouncycastle.asn1.ASN1Sequence; import org.bouncycastle.asn1.DERInteger; import org.bouncycastle.asn1.oiw.ElGamalParameter; import org.bouncycastle.asn1.oiw.OIWObjectIdentifiers; import org.bouncycastle.asn1.pkcs.PrivateKeyInfo; import org.bouncycastle.asn1.x509.AlgorithmIdentifier; import org.bouncycastle.crypto.params.ElGamalPrivateKeyParameters; import org.bouncycastle.jcajce.provider.asymmetric.util.PKCS12BagAttributeCarrierImpl; import org.bouncycastle.jce.interfaces.ElGamalPrivateKey; import org.bouncycastle.jce.interfaces.PKCS12BagAttributeCarrier; import org.bouncycastle.jce.spec.ElGamalParameterSpec; import org.bouncycastle.jce.spec.ElGamalPrivateKeySpec; public class BCElGamalPrivateKey implements ElGamalPrivateKey, DHPrivateKey, PKCS12BagAttributeCarrier { static final long serialVersionUID = 4819350091141529678L; private BigInteger x; private transient ElGamalParameterSpec elSpec; private transient PKCS12BagAttributeCarrierImpl attrCarrier = new PKCS12BagAttributeCarrierImpl(); protected BCElGamalPrivateKey() { } BCElGamalPrivateKey( ElGamalPrivateKey key) { this.x = key.getX(); this.elSpec = key.getParameters(); } BCElGamalPrivateKey( DHPrivateKey key) { this.x = key.getX(); this.elSpec = new ElGamalParameterSpec(key.getParams().getP(), key.getParams().getG()); } BCElGamalPrivateKey( ElGamalPrivateKeySpec spec) { this.x = spec.getX(); this.elSpec = new ElGamalParameterSpec(spec.getParams().getP(), spec.getParams().getG()); } BCElGamalPrivateKey( DHPrivateKeySpec spec) { this.x = spec.getX(); this.elSpec = new ElGamalParameterSpec(spec.getP(), spec.getG()); } BCElGamalPrivateKey( PrivateKeyInfo info) throws IOException { ElGamalParameter params = new ElGamalParameter((ASN1Sequence)info.getAlgorithmId().getParameters()); DERInteger derX = ASN1Integer.getInstance(info.parsePrivateKey()); this.x = derX.getValue(); this.elSpec = new ElGamalParameterSpec(params.getP(), params.getG()); } BCElGamalPrivateKey( ElGamalPrivateKeyParameters params) { this.x = params.getX(); this.elSpec = new ElGamalParameterSpec(params.getParameters().getP(), params.getParameters().getG()); } public String getAlgorithm() { return "ElGamal"; } /** * return the encoding format we produce in getEncoded(). * * @return the string "PKCS#8" */ public String getFormat() { return "PKCS#8"; } /** * Return a PKCS8 representation of the key. The sequence returned * represents a full PrivateKeyInfo object. * * @return a PKCS8 representation of the key. */ public byte[] getEncoded() { try { PrivateKeyInfo info = new PrivateKeyInfo(new AlgorithmIdentifier(OIWObjectIdentifiers.elGamalAlgorithm, new ElGamalParameter(elSpec.getP(), elSpec.getG())), new DERInteger(getX())); return info.getEncoded(ASN1Encoding.DER); } catch (IOException e) { return null; } } public ElGamalParameterSpec getParameters() { return elSpec; } public DHParameterSpec getParams() { return new DHParameterSpec(elSpec.getP(), elSpec.getG()); } public BigInteger getX() { return x; } public boolean equals( Object o) { if (!(o instanceof DHPrivateKey)) { return false; } DHPrivateKey other = (DHPrivateKey)o; return this.getX().equals(other.getX()) && this.getParams().getG().equals(other.getParams().getG()) && this.getParams().getP().equals(other.getParams().getP()) && this.getParams().getL() == other.getParams().getL(); } public int hashCode() { return this.getX().hashCode() ^ this.getParams().getG().hashCode() ^ this.getParams().getP().hashCode() ^ this.getParams().getL(); } private void readObject( ObjectInputStream in) throws IOException, ClassNotFoundException { in.defaultReadObject(); this.elSpec = new ElGamalParameterSpec((BigInteger)in.readObject(), (BigInteger)in.readObject()); this.attrCarrier = new PKCS12BagAttributeCarrierImpl(); } private void writeObject( ObjectOutputStream out) throws IOException { out.defaultWriteObject(); out.writeObject(elSpec.getP()); out.writeObject(elSpec.getG()); } public void setBagAttribute( ASN1ObjectIdentifier oid, ASN1Encodable attribute) { attrCarrier.setBagAttribute(oid, attribute); } public ASN1Encodable getBagAttribute( ASN1ObjectIdentifier oid) { return attrCarrier.getBagAttribute(oid); } public Enumeration getBagAttributeKeys() { return attrCarrier.getBagAttributeKeys(); } } bouncycastle-1.49.orig/src/org/bouncycastle/jcajce/provider/asymmetric/elgamal/CipherSpi.java0000644000175000017500000002416712110036731032067 0ustar ebourgebourgpackage org.bouncycastle.jcajce.provider.asymmetric.elgamal; import java.security.AlgorithmParameters; import java.security.InvalidAlgorithmParameterException; import java.security.InvalidKeyException; import java.security.InvalidParameterException; import java.security.Key; import java.security.NoSuchAlgorithmException; import java.security.PrivateKey; import java.security.PublicKey; import java.security.SecureRandom; import java.security.spec.AlgorithmParameterSpec; import java.security.spec.MGF1ParameterSpec; import javax.crypto.BadPaddingException; import javax.crypto.IllegalBlockSizeException; import javax.crypto.NoSuchPaddingException; import javax.crypto.interfaces.DHKey; import javax.crypto.spec.OAEPParameterSpec; import javax.crypto.spec.PSource; import org.bouncycastle.crypto.AsymmetricBlockCipher; import org.bouncycastle.crypto.BufferedAsymmetricBlockCipher; import org.bouncycastle.crypto.CipherParameters; import org.bouncycastle.crypto.Digest; import org.bouncycastle.crypto.InvalidCipherTextException; import org.bouncycastle.crypto.encodings.ISO9796d1Encoding; import org.bouncycastle.crypto.encodings.OAEPEncoding; import org.bouncycastle.crypto.encodings.PKCS1Encoding; import org.bouncycastle.crypto.engines.ElGamalEngine; import org.bouncycastle.crypto.params.ParametersWithRandom; import org.bouncycastle.jcajce.provider.asymmetric.util.BaseCipherSpi; import org.bouncycastle.jcajce.provider.util.DigestFactory; import org.bouncycastle.jce.interfaces.ElGamalKey; import org.bouncycastle.jce.interfaces.ElGamalPrivateKey; import org.bouncycastle.jce.interfaces.ElGamalPublicKey; import org.bouncycastle.jce.provider.BouncyCastleProvider; import org.bouncycastle.util.Strings; public class CipherSpi extends BaseCipherSpi { private BufferedAsymmetricBlockCipher cipher; private AlgorithmParameterSpec paramSpec; private AlgorithmParameters engineParams; public CipherSpi( AsymmetricBlockCipher engine) { cipher = new BufferedAsymmetricBlockCipher(engine); } private void initFromSpec( OAEPParameterSpec pSpec) throws NoSuchPaddingException { MGF1ParameterSpec mgfParams = (MGF1ParameterSpec)pSpec.getMGFParameters(); Digest digest = DigestFactory.getDigest(mgfParams.getDigestAlgorithm()); if (digest == null) { throw new NoSuchPaddingException("no match on OAEP constructor for digest algorithm: "+ mgfParams.getDigestAlgorithm()); } cipher = new BufferedAsymmetricBlockCipher(new OAEPEncoding(new ElGamalEngine(), digest, ((PSource.PSpecified)pSpec.getPSource()).getValue())); paramSpec = pSpec; } protected int engineGetBlockSize() { return cipher.getInputBlockSize(); } protected int engineGetKeySize( Key key) { if (key instanceof ElGamalKey) { ElGamalKey k = (ElGamalKey)key; return k.getParameters().getP().bitLength(); } else if (key instanceof DHKey) { DHKey k = (DHKey)key; return k.getParams().getP().bitLength(); } throw new IllegalArgumentException("not an ElGamal key!"); } protected int engineGetOutputSize( int inputLen) { return cipher.getOutputBlockSize(); } protected AlgorithmParameters engineGetParameters() { if (engineParams == null) { if (paramSpec != null) { try { engineParams = AlgorithmParameters.getInstance("OAEP", BouncyCastleProvider.PROVIDER_NAME); engineParams.init(paramSpec); } catch (Exception e) { throw new RuntimeException(e.toString()); } } } return engineParams; } protected void engineSetMode( String mode) throws NoSuchAlgorithmException { String md = Strings.toUpperCase(mode); if (md.equals("NONE") || md.equals("ECB")) { return; } throw new NoSuchAlgorithmException("can't support mode " + mode); } protected void engineSetPadding( String padding) throws NoSuchPaddingException { String pad = Strings.toUpperCase(padding); if (pad.equals("NOPADDING")) { cipher = new BufferedAsymmetricBlockCipher(new ElGamalEngine()); } else if (pad.equals("PKCS1PADDING")) { cipher = new BufferedAsymmetricBlockCipher(new PKCS1Encoding(new ElGamalEngine())); } else if (pad.equals("ISO9796-1PADDING")) { cipher = new BufferedAsymmetricBlockCipher(new ISO9796d1Encoding(new ElGamalEngine())); } else if (pad.equals("OAEPPADDING")) { initFromSpec(OAEPParameterSpec.DEFAULT); } else if (pad.equals("OAEPWITHMD5ANDMGF1PADDING")) { initFromSpec(new OAEPParameterSpec("MD5", "MGF1", new MGF1ParameterSpec("MD5"), PSource.PSpecified.DEFAULT)); } else if (pad.equals("OAEPWITHSHA1ANDMGF1PADDING")) { initFromSpec(OAEPParameterSpec.DEFAULT); } else if (pad.equals("OAEPWITHSHA224ANDMGF1PADDING")) { initFromSpec(new OAEPParameterSpec("SHA-224", "MGF1", new MGF1ParameterSpec("SHA-224"), PSource.PSpecified.DEFAULT)); } else if (pad.equals("OAEPWITHSHA256ANDMGF1PADDING")) { initFromSpec(new OAEPParameterSpec("SHA-256", "MGF1", MGF1ParameterSpec.SHA256, PSource.PSpecified.DEFAULT)); } else if (pad.equals("OAEPWITHSHA384ANDMGF1PADDING")) { initFromSpec(new OAEPParameterSpec("SHA-384", "MGF1", MGF1ParameterSpec.SHA384, PSource.PSpecified.DEFAULT)); } else if (pad.equals("OAEPWITHSHA512ANDMGF1PADDING")) { initFromSpec(new OAEPParameterSpec("SHA-512", "MGF1", MGF1ParameterSpec.SHA512, PSource.PSpecified.DEFAULT)); } else { throw new NoSuchPaddingException(padding + " unavailable with ElGamal."); } } protected void engineInit( int opmode, Key key, AlgorithmParameterSpec params, SecureRandom random) throws InvalidKeyException { CipherParameters param; if (params == null) { if (key instanceof ElGamalPublicKey) { param = ElGamalUtil.generatePublicKeyParameter((PublicKey)key); } else if (key instanceof ElGamalPrivateKey) { param = ElGamalUtil.generatePrivateKeyParameter((PrivateKey)key); } else { throw new InvalidKeyException("unknown key type passed to ElGamal"); } } else { throw new IllegalArgumentException("unknown parameter type."); } if (random != null) { param = new ParametersWithRandom(param, random); } switch (opmode) { case javax.crypto.Cipher.ENCRYPT_MODE: case javax.crypto.Cipher.WRAP_MODE: cipher.init(true, param); break; case javax.crypto.Cipher.DECRYPT_MODE: case javax.crypto.Cipher.UNWRAP_MODE: cipher.init(false, param); break; default: throw new InvalidParameterException("unknown opmode " + opmode + " passed to ElGamal"); } } protected void engineInit( int opmode, Key key, AlgorithmParameters params, SecureRandom random) throws InvalidKeyException, InvalidAlgorithmParameterException { throw new InvalidAlgorithmParameterException("can't handle parameters in ElGamal"); } protected void engineInit( int opmode, Key key, SecureRandom random) throws InvalidKeyException { engineInit(opmode, key, (AlgorithmParameterSpec)null, random); } protected byte[] engineUpdate( byte[] input, int inputOffset, int inputLen) { cipher.processBytes(input, inputOffset, inputLen); return null; } protected int engineUpdate( byte[] input, int inputOffset, int inputLen, byte[] output, int outputOffset) { cipher.processBytes(input, inputOffset, inputLen); return 0; } protected byte[] engineDoFinal( byte[] input, int inputOffset, int inputLen) throws IllegalBlockSizeException, BadPaddingException { cipher.processBytes(input, inputOffset, inputLen); try { return cipher.doFinal(); } catch (InvalidCipherTextException e) { throw new BadPaddingException(e.getMessage()); } } protected int engineDoFinal( byte[] input, int inputOffset, int inputLen, byte[] output, int outputOffset) throws IllegalBlockSizeException, BadPaddingException { byte[] out; cipher.processBytes(input, inputOffset, inputLen); try { out = cipher.doFinal(); } catch (InvalidCipherTextException e) { throw new BadPaddingException(e.getMessage()); } for (int i = 0; i != out.length; i++) { output[outputOffset + i] = out[i]; } return out.length; } /** * classes that inherit from us. */ static public class NoPadding extends CipherSpi { public NoPadding() { super(new ElGamalEngine()); } } static public class PKCS1v1_5Padding extends CipherSpi { public PKCS1v1_5Padding() { super(new PKCS1Encoding(new ElGamalEngine())); } } } ././@LongLink0000000000000000000000000000015000000000000011561 Lustar rootrootbouncycastle-1.49.orig/src/org/bouncycastle/jcajce/provider/asymmetric/elgamal/KeyPairGeneratorSpi.javabouncycastle-1.49.orig/src/org/bouncycastle/jcajce/provider/asymmetric/elgamal/KeyPairGeneratorSpi.j0000644000175000017500000000660012063224071033373 0ustar ebourgebourgpackage org.bouncycastle.jcajce.provider.asymmetric.elgamal; import java.security.InvalidAlgorithmParameterException; import java.security.KeyPair; import java.security.SecureRandom; import java.security.spec.AlgorithmParameterSpec; import javax.crypto.spec.DHParameterSpec; import org.bouncycastle.crypto.AsymmetricCipherKeyPair; import org.bouncycastle.crypto.generators.ElGamalKeyPairGenerator; import org.bouncycastle.crypto.generators.ElGamalParametersGenerator; import org.bouncycastle.crypto.params.ElGamalKeyGenerationParameters; import org.bouncycastle.crypto.params.ElGamalParameters; import org.bouncycastle.crypto.params.ElGamalPrivateKeyParameters; import org.bouncycastle.crypto.params.ElGamalPublicKeyParameters; import org.bouncycastle.jce.provider.BouncyCastleProvider; import org.bouncycastle.jce.spec.ElGamalParameterSpec; public class KeyPairGeneratorSpi extends java.security.KeyPairGenerator { ElGamalKeyGenerationParameters param; ElGamalKeyPairGenerator engine = new ElGamalKeyPairGenerator(); int strength = 1024; int certainty = 20; SecureRandom random = new SecureRandom(); boolean initialised = false; public KeyPairGeneratorSpi() { super("ElGamal"); } public void initialize( int strength, SecureRandom random) { this.strength = strength; this.random = random; } public void initialize( AlgorithmParameterSpec params, SecureRandom random) throws InvalidAlgorithmParameterException { if (!(params instanceof ElGamalParameterSpec) && !(params instanceof DHParameterSpec)) { throw new InvalidAlgorithmParameterException("parameter object not a DHParameterSpec or an ElGamalParameterSpec"); } if (params instanceof ElGamalParameterSpec) { ElGamalParameterSpec elParams = (ElGamalParameterSpec)params; param = new ElGamalKeyGenerationParameters(random, new ElGamalParameters(elParams.getP(), elParams.getG())); } else { DHParameterSpec dhParams = (DHParameterSpec)params; param = new ElGamalKeyGenerationParameters(random, new ElGamalParameters(dhParams.getP(), dhParams.getG(), dhParams.getL())); } engine.init(param); initialised = true; } public KeyPair generateKeyPair() { if (!initialised) { DHParameterSpec dhParams = BouncyCastleProvider.CONFIGURATION.getDHDefaultParameters(strength); if (dhParams != null) { param = new ElGamalKeyGenerationParameters(random, new ElGamalParameters(dhParams.getP(), dhParams.getG(), dhParams.getL())); } else { ElGamalParametersGenerator pGen = new ElGamalParametersGenerator(); pGen.init(strength, certainty, random); param = new ElGamalKeyGenerationParameters(random, pGen.generateParameters()); } engine.init(param); initialised = true; } AsymmetricCipherKeyPair pair = engine.generateKeyPair(); ElGamalPublicKeyParameters pub = (ElGamalPublicKeyParameters)pair.getPublic(); ElGamalPrivateKeyParameters priv = (ElGamalPrivateKeyParameters)pair.getPrivate(); return new KeyPair(new BCElGamalPublicKey(pub), new BCElGamalPrivateKey(priv)); } } bouncycastle-1.49.orig/src/org/bouncycastle/jcajce/provider/asymmetric/DH.java0000644000175000017500000000340212110034123027050 0ustar ebourgebourgpackage org.bouncycastle.jcajce.provider.asymmetric; import org.bouncycastle.jcajce.provider.config.ConfigurableProvider; import org.bouncycastle.jcajce.provider.util.AsymmetricAlgorithmProvider; public class DH { private static final String PREFIX = "org.bouncycastle.jcajce.provider.asymmetric" + ".dh."; public static class Mappings extends AsymmetricAlgorithmProvider { public Mappings() { } public void configure(ConfigurableProvider provider) { provider.addAlgorithm("KeyPairGenerator.DH", PREFIX + "KeyPairGeneratorSpi"); provider.addAlgorithm("Alg.Alias.KeyPairGenerator.DIFFIEHELLMAN", "DH"); provider.addAlgorithm("KeyAgreement.DH", PREFIX + "KeyAgreementSpi"); provider.addAlgorithm("Alg.Alias.KeyAgreement.DIFFIEHELLMAN", "DH"); provider.addAlgorithm("KeyFactory.DH", PREFIX + "KeyFactorySpi"); provider.addAlgorithm("Alg.Alias.KeyFactory.DIFFIEHELLMAN", "DH"); provider.addAlgorithm("AlgorithmParameters.DH", PREFIX + "AlgorithmParametersSpi"); provider.addAlgorithm("Alg.Alias.AlgorithmParameters.DIFFIEHELLMAN", "DH"); provider.addAlgorithm("Alg.Alias.AlgorithmParameterGenerator.DIFFIEHELLMAN", "DH"); provider.addAlgorithm("AlgorithmParameterGenerator.DH", PREFIX + "AlgorithmParameterGeneratorSpi"); provider.addAlgorithm("Cipher.DHIES", PREFIX + "IESCipher$IES"); provider.addAlgorithm("Cipher.DHIESwithAES", PREFIX + "IESCipher$IESwithAES"); provider.addAlgorithm("Cipher.DHIESWITHAES", PREFIX + "IESCipher$IESwithAES"); provider.addAlgorithm("Cipher.DHIESWITHDESEDE", PREFIX + "IESCipher$IESwithDESede"); } } } bouncycastle-1.49.orig/src/org/bouncycastle/jcajce/provider/asymmetric/EC.java0000644000175000017500000001435012143620165027065 0ustar ebourgebourgpackage org.bouncycastle.jcajce.provider.asymmetric; import org.bouncycastle.asn1.eac.EACObjectIdentifiers; import org.bouncycastle.asn1.teletrust.TeleTrusTObjectIdentifiers; import org.bouncycastle.asn1.x9.X9ObjectIdentifiers; import org.bouncycastle.jcajce.provider.asymmetric.ec.KeyFactorySpi; import org.bouncycastle.jcajce.provider.config.ConfigurableProvider; import org.bouncycastle.jcajce.provider.util.AsymmetricAlgorithmProvider; public class EC { private static final String PREFIX = "org.bouncycastle.jcajce.provider.asymmetric" + ".ec."; public static class Mappings extends AsymmetricAlgorithmProvider { public Mappings() { } public void configure(ConfigurableProvider provider) { provider.addAlgorithm("KeyAgreement.ECDH", PREFIX + "KeyAgreementSpi$DH"); provider.addAlgorithm("KeyAgreement.ECDHC", PREFIX + "KeyAgreementSpi$DHC"); provider.addAlgorithm("KeyAgreement.ECMQV", PREFIX + "KeyAgreementSpi$MQV"); provider.addAlgorithm("KeyAgreement." + X9ObjectIdentifiers.dhSinglePass_stdDH_sha1kdf_scheme, PREFIX + "KeyAgreementSpi$DHwithSHA1KDF"); provider.addAlgorithm("KeyAgreement." + X9ObjectIdentifiers.mqvSinglePass_sha1kdf_scheme, PREFIX + "KeyAgreementSpi$MQVwithSHA1KDF"); registerOid(provider, X9ObjectIdentifiers.id_ecPublicKey, "EC", new KeyFactorySpi.EC()); // TODO Should this be an alias for ECDH? registerOid(provider, X9ObjectIdentifiers.dhSinglePass_stdDH_sha1kdf_scheme, "EC", new KeyFactorySpi.EC()); registerOid(provider, X9ObjectIdentifiers.mqvSinglePass_sha1kdf_scheme, "ECMQV", new KeyFactorySpi.ECMQV()); registerOidAlgorithmParameters(provider, X9ObjectIdentifiers.id_ecPublicKey, "EC"); // TODO Should this be an alias for ECDH? registerOidAlgorithmParameters(provider, X9ObjectIdentifiers.dhSinglePass_stdDH_sha1kdf_scheme, "EC"); registerOidAlgorithmParameters(provider, X9ObjectIdentifiers.mqvSinglePass_sha1kdf_scheme, "EC"); provider.addAlgorithm("KeyFactory.EC", PREFIX + "KeyFactorySpi$EC"); provider.addAlgorithm("KeyFactory.ECDSA", PREFIX + "KeyFactorySpi$ECDSA"); provider.addAlgorithm("KeyFactory.ECDH", PREFIX + "KeyFactorySpi$ECDH"); provider.addAlgorithm("KeyFactory.ECDHC", PREFIX + "KeyFactorySpi$ECDHC"); provider.addAlgorithm("KeyFactory.ECMQV", PREFIX + "KeyFactorySpi$ECMQV"); provider.addAlgorithm("KeyPairGenerator.EC", PREFIX + "KeyPairGeneratorSpi$EC"); provider.addAlgorithm("KeyPairGenerator.ECDSA", PREFIX + "KeyPairGeneratorSpi$ECDSA"); provider.addAlgorithm("KeyPairGenerator.ECDH", PREFIX + "KeyPairGeneratorSpi$ECDH"); provider.addAlgorithm("KeyPairGenerator.ECDHC", PREFIX + "KeyPairGeneratorSpi$ECDHC"); provider.addAlgorithm("KeyPairGenerator.ECIES", PREFIX + "KeyPairGeneratorSpi$ECDH"); provider.addAlgorithm("KeyPairGenerator.ECMQV", PREFIX + "KeyPairGeneratorSpi$ECMQV"); provider.addAlgorithm("Cipher.ECIES", PREFIX + "IESCipher$ECIES"); provider.addAlgorithm("Cipher.ECIESwithAES", PREFIX + "IESCipher$ECIESwithAES"); provider.addAlgorithm("Cipher.ECIESWITHAES", PREFIX + "IESCipher$ECIESwithAES"); provider.addAlgorithm("Cipher.ECIESwithDESEDE", PREFIX + "IESCipher$ECIESwithDESede"); provider.addAlgorithm("Cipher.ECIESWITHDESEDE", PREFIX + "IESCipher$ECIESwithDESede"); provider.addAlgorithm("Signature.ECDSA", PREFIX + "SignatureSpi$ecDSA"); provider.addAlgorithm("Signature.NONEwithECDSA", PREFIX + "SignatureSpi$ecDSAnone"); provider.addAlgorithm("Alg.Alias.Signature.SHA1withECDSA", "ECDSA"); provider.addAlgorithm("Alg.Alias.Signature.ECDSAwithSHA1", "ECDSA"); provider.addAlgorithm("Alg.Alias.Signature.SHA1WITHECDSA", "ECDSA"); provider.addAlgorithm("Alg.Alias.Signature.ECDSAWITHSHA1", "ECDSA"); provider.addAlgorithm("Alg.Alias.Signature.SHA1WithECDSA", "ECDSA"); provider.addAlgorithm("Alg.Alias.Signature.ECDSAWithSHA1", "ECDSA"); provider.addAlgorithm("Alg.Alias.Signature.1.2.840.10045.4.1", "ECDSA"); provider.addAlgorithm("Alg.Alias.Signature." + TeleTrusTObjectIdentifiers.ecSignWithSha1, "ECDSA"); addSignatureAlgorithm(provider, "SHA224", "ECDSA", PREFIX + "SignatureSpi$ecDSA224", X9ObjectIdentifiers.ecdsa_with_SHA224); addSignatureAlgorithm(provider, "SHA256", "ECDSA", PREFIX + "SignatureSpi$ecDSA256", X9ObjectIdentifiers.ecdsa_with_SHA256); addSignatureAlgorithm(provider, "SHA384", "ECDSA", PREFIX + "SignatureSpi$ecDSA384", X9ObjectIdentifiers.ecdsa_with_SHA384); addSignatureAlgorithm(provider, "SHA512", "ECDSA", PREFIX + "SignatureSpi$ecDSA512", X9ObjectIdentifiers.ecdsa_with_SHA512); addSignatureAlgorithm(provider, "RIPEMD160", "ECDSA", PREFIX + "SignatureSpi$ecDSARipeMD160",TeleTrusTObjectIdentifiers.ecSignWithRipemd160); provider.addAlgorithm("Signature.SHA1WITHECNR", PREFIX + "SignatureSpi$ecNR"); provider.addAlgorithm("Signature.SHA224WITHECNR", PREFIX + "SignatureSpi$ecNR224"); provider.addAlgorithm("Signature.SHA256WITHECNR", PREFIX + "SignatureSpi$ecNR256"); provider.addAlgorithm("Signature.SHA384WITHECNR", PREFIX + "SignatureSpi$ecNR384"); provider.addAlgorithm("Signature.SHA512WITHECNR", PREFIX + "SignatureSpi$ecNR512"); addSignatureAlgorithm(provider, "SHA1", "CVC-ECDSA", PREFIX + "SignatureSpi$ecCVCDSA", EACObjectIdentifiers.id_TA_ECDSA_SHA_1); addSignatureAlgorithm(provider, "SHA224", "CVC-ECDSA", PREFIX + "SignatureSpi$ecCVCDSA224", EACObjectIdentifiers.id_TA_ECDSA_SHA_224); addSignatureAlgorithm(provider, "SHA256", "CVC-ECDSA", PREFIX + "SignatureSpi$ecCVCDSA256", EACObjectIdentifiers.id_TA_ECDSA_SHA_256); addSignatureAlgorithm(provider, "SHA384", "CVC-ECDSA", PREFIX + "SignatureSpi$ecCVCDSA384", EACObjectIdentifiers.id_TA_ECDSA_SHA_384); addSignatureAlgorithm(provider, "SHA512", "CVC-ECDSA", PREFIX + "SignatureSpi$ecCVCDSA512", EACObjectIdentifiers.id_TA_ECDSA_SHA_512); } } } bouncycastle-1.49.orig/src/org/bouncycastle/jcajce/provider/asymmetric/dsa/0000755000175000017500000000000012152033551026474 5ustar ebourgebourgbouncycastle-1.49.orig/src/org/bouncycastle/jcajce/provider/asymmetric/dsa/BCDSAPublicKey.java0000644000175000017500000001131311726500225031765 0ustar ebourgebourgpackage org.bouncycastle.jcajce.provider.asymmetric.dsa; import java.io.IOException; import java.io.ObjectInputStream; import java.io.ObjectOutputStream; import java.math.BigInteger; import java.security.interfaces.DSAParams; import java.security.interfaces.DSAPublicKey; import java.security.spec.DSAParameterSpec; import java.security.spec.DSAPublicKeySpec; import org.bouncycastle.asn1.ASN1Encodable; import org.bouncycastle.asn1.ASN1Integer; import org.bouncycastle.asn1.DERNull; import org.bouncycastle.asn1.x509.AlgorithmIdentifier; import org.bouncycastle.asn1.x509.DSAParameter; import org.bouncycastle.asn1.x509.SubjectPublicKeyInfo; import org.bouncycastle.asn1.x9.X9ObjectIdentifiers; import org.bouncycastle.crypto.params.DSAPublicKeyParameters; import org.bouncycastle.jcajce.provider.asymmetric.util.KeyUtil; public class BCDSAPublicKey implements DSAPublicKey { private static final long serialVersionUID = 1752452449903495175L; private BigInteger y; private transient DSAParams dsaSpec; BCDSAPublicKey( DSAPublicKeySpec spec) { this.y = spec.getY(); this.dsaSpec = new DSAParameterSpec(spec.getP(), spec.getQ(), spec.getG()); } BCDSAPublicKey( DSAPublicKey key) { this.y = key.getY(); this.dsaSpec = key.getParams(); } BCDSAPublicKey( DSAPublicKeyParameters params) { this.y = params.getY(); this.dsaSpec = new DSAParameterSpec(params.getParameters().getP(), params.getParameters().getQ(), params.getParameters().getG()); } BCDSAPublicKey( BigInteger y, DSAParameterSpec dsaSpec) { this.y = y; this.dsaSpec = dsaSpec; } public BCDSAPublicKey( SubjectPublicKeyInfo info) { ASN1Integer derY; try { derY = (ASN1Integer)info.parsePublicKey(); } catch (IOException e) { throw new IllegalArgumentException("invalid info structure in DSA public key"); } this.y = derY.getValue(); if (isNotNull(info.getAlgorithm().getParameters())) { DSAParameter params = DSAParameter.getInstance(info.getAlgorithm().getParameters()); this.dsaSpec = new DSAParameterSpec(params.getP(), params.getQ(), params.getG()); } } private boolean isNotNull(ASN1Encodable parameters) { return parameters != null && !DERNull.INSTANCE.equals(parameters.toASN1Primitive()); } public String getAlgorithm() { return "DSA"; } public String getFormat() { return "X.509"; } public byte[] getEncoded() { if (dsaSpec == null) { return KeyUtil.getEncodedSubjectPublicKeyInfo(new AlgorithmIdentifier(X9ObjectIdentifiers.id_dsa), new ASN1Integer(y)); } return KeyUtil.getEncodedSubjectPublicKeyInfo(new AlgorithmIdentifier(X9ObjectIdentifiers.id_dsa, new DSAParameter(dsaSpec.getP(), dsaSpec.getQ(), dsaSpec.getG()).toASN1Primitive()), new ASN1Integer(y)); } public DSAParams getParams() { return dsaSpec; } public BigInteger getY() { return y; } public String toString() { StringBuffer buf = new StringBuffer(); String nl = System.getProperty("line.separator"); buf.append("DSA Public Key").append(nl); buf.append(" y: ").append(this.getY().toString(16)).append(nl); return buf.toString(); } public int hashCode() { return this.getY().hashCode() ^ this.getParams().getG().hashCode() ^ this.getParams().getP().hashCode() ^ this.getParams().getQ().hashCode(); } public boolean equals( Object o) { if (!(o instanceof DSAPublicKey)) { return false; } DSAPublicKey other = (DSAPublicKey)o; return this.getY().equals(other.getY()) && this.getParams().getG().equals(other.getParams().getG()) && this.getParams().getP().equals(other.getParams().getP()) && this.getParams().getQ().equals(other.getParams().getQ()); } private void readObject( ObjectInputStream in) throws IOException, ClassNotFoundException { in.defaultReadObject(); this.dsaSpec = new DSAParameterSpec((BigInteger)in.readObject(), (BigInteger)in.readObject(), (BigInteger)in.readObject()); } private void writeObject( ObjectOutputStream out) throws IOException { out.defaultWriteObject(); out.writeObject(dsaSpec.getP()); out.writeObject(dsaSpec.getQ()); out.writeObject(dsaSpec.getG()); } } bouncycastle-1.49.orig/src/org/bouncycastle/jcajce/provider/asymmetric/dsa/DSAUtil.java0000644000175000017500000000433111631272023030605 0ustar ebourgebourgpackage org.bouncycastle.jcajce.provider.asymmetric.dsa; import java.security.InvalidKeyException; import java.security.PrivateKey; import java.security.PublicKey; import java.security.interfaces.DSAPrivateKey; import java.security.interfaces.DSAPublicKey; import org.bouncycastle.asn1.ASN1ObjectIdentifier; import org.bouncycastle.asn1.oiw.OIWObjectIdentifiers; import org.bouncycastle.asn1.x9.X9ObjectIdentifiers; import org.bouncycastle.crypto.params.AsymmetricKeyParameter; import org.bouncycastle.crypto.params.DSAParameters; import org.bouncycastle.crypto.params.DSAPrivateKeyParameters; import org.bouncycastle.crypto.params.DSAPublicKeyParameters; /** * utility class for converting jce/jca DSA objects * objects into their org.bouncycastle.crypto counterparts. */ public class DSAUtil { public static final ASN1ObjectIdentifier[] dsaOids = { X9ObjectIdentifiers.id_dsa, OIWObjectIdentifiers.dsaWithSHA1 }; public static boolean isDsaOid( ASN1ObjectIdentifier algOid) { for (int i = 0; i != dsaOids.length; i++) { if (algOid.equals(dsaOids[i])) { return true; } } return false; } static public AsymmetricKeyParameter generatePublicKeyParameter( PublicKey key) throws InvalidKeyException { if (key instanceof DSAPublicKey) { DSAPublicKey k = (DSAPublicKey)key; return new DSAPublicKeyParameters(k.getY(), new DSAParameters(k.getParams().getP(), k.getParams().getQ(), k.getParams().getG())); } throw new InvalidKeyException("can't identify DSA public key: " + key.getClass().getName()); } static public AsymmetricKeyParameter generatePrivateKeyParameter( PrivateKey key) throws InvalidKeyException { if (key instanceof DSAPrivateKey) { DSAPrivateKey k = (DSAPrivateKey)key; return new DSAPrivateKeyParameters(k.getX(), new DSAParameters(k.getParams().getP(), k.getParams().getQ(), k.getParams().getG())); } throw new InvalidKeyException("can't identify DSA private key."); } } ././@LongLink0000000000000000000000000000015700000000000011570 Lustar rootrootbouncycastle-1.49.orig/src/org/bouncycastle/jcajce/provider/asymmetric/dsa/AlgorithmParameterGeneratorSpi.javabouncycastle-1.49.orig/src/org/bouncycastle/jcajce/provider/asymmetric/dsa/AlgorithmParameterGenerat0000644000175000017500000000577312144051301033522 0ustar ebourgebourgpackage org.bouncycastle.jcajce.provider.asymmetric.dsa; import java.security.AlgorithmParameters; import java.security.InvalidAlgorithmParameterException; import java.security.InvalidParameterException; import java.security.SecureRandom; import java.security.spec.AlgorithmParameterSpec; import java.security.spec.DSAParameterSpec; import org.bouncycastle.crypto.digests.SHA256Digest; import org.bouncycastle.crypto.generators.DSAParametersGenerator; import org.bouncycastle.crypto.params.DSAParameterGenerationParameters; import org.bouncycastle.crypto.params.DSAParameters; import org.bouncycastle.jce.provider.BouncyCastleProvider; public class AlgorithmParameterGeneratorSpi extends java.security.AlgorithmParameterGeneratorSpi { protected SecureRandom random; protected int strength = 1024; protected DSAParameterGenerationParameters params; protected void engineInit( int strength, SecureRandom random) { if (strength < 512 || strength > 3072) { throw new InvalidParameterException("strength must be from 512 - 3072"); } if (strength <= 1024 && strength % 64 != 0) { throw new InvalidParameterException("strength must be a multiple of 64 below 1024 bits."); } if (strength > 1024 && strength % 1024 != 0) { throw new InvalidParameterException("strength must be a multiple of 1024 above 1024 bits."); } this.strength = strength; this.random = random; } protected void engineInit( AlgorithmParameterSpec genParamSpec, SecureRandom random) throws InvalidAlgorithmParameterException { throw new InvalidAlgorithmParameterException("No supported AlgorithmParameterSpec for DSA parameter generation."); } protected AlgorithmParameters engineGenerateParameters() { DSAParametersGenerator pGen; if (strength <= 1024) { pGen = new DSAParametersGenerator(); } else { pGen = new DSAParametersGenerator(new SHA256Digest()); } if (random == null) { random = new SecureRandom(); } if (strength == 1024) { params = new DSAParameterGenerationParameters(1024, 160, 80, random); pGen.init(params); } else if (strength > 1024) { params = new DSAParameterGenerationParameters(strength, 256, 80, random); pGen.init(params); } else { pGen.init(strength, 20, random); } DSAParameters p = pGen.generateParameters(); AlgorithmParameters params; try { params = AlgorithmParameters.getInstance("DSA", BouncyCastleProvider.PROVIDER_NAME); params.init(new DSAParameterSpec(p.getP(), p.getQ(), p.getG())); } catch (Exception e) { throw new RuntimeException(e.getMessage()); } return params; } } ././@LongLink0000000000000000000000000000014700000000000011567 Lustar rootrootbouncycastle-1.49.orig/src/org/bouncycastle/jcajce/provider/asymmetric/dsa/AlgorithmParametersSpi.javabouncycastle-1.49.orig/src/org/bouncycastle/jcajce/provider/asymmetric/dsa/AlgorithmParametersSpi.ja0000644000175000017500000000677712151274314033462 0ustar ebourgebourgpackage org.bouncycastle.jcajce.provider.asymmetric.dsa; import java.io.IOException; import java.security.spec.AlgorithmParameterSpec; import java.security.spec.DSAParameterSpec; import java.security.spec.InvalidParameterSpecException; import org.bouncycastle.asn1.ASN1Encoding; import org.bouncycastle.asn1.ASN1Primitive; import org.bouncycastle.asn1.x509.DSAParameter; public class AlgorithmParametersSpi extends java.security.AlgorithmParametersSpi { DSAParameterSpec currentSpec; protected boolean isASN1FormatString(String format) { return format == null || format.equals("ASN.1"); } protected AlgorithmParameterSpec engineGetParameterSpec( Class paramSpec) throws InvalidParameterSpecException { if (paramSpec == null) { throw new NullPointerException("argument to getParameterSpec must not be null"); } return localEngineGetParameterSpec(paramSpec); } /** * Return the X.509 ASN.1 structure DSAParameter. *

    *

         *  DSAParameter ::= SEQUENCE {
         *                   prime INTEGER, -- p
         *                   subprime INTEGER, -- q
         *                   base INTEGER, -- g}
         * 
    */ protected byte[] engineGetEncoded() { DSAParameter dsaP = new DSAParameter(currentSpec.getP(), currentSpec.getQ(), currentSpec.getG()); try { return dsaP.getEncoded(ASN1Encoding.DER); } catch (IOException e) { throw new RuntimeException("Error encoding DSAParameters"); } } protected byte[] engineGetEncoded( String format) { if (isASN1FormatString(format)) { return engineGetEncoded(); } return null; } protected AlgorithmParameterSpec localEngineGetParameterSpec( Class paramSpec) throws InvalidParameterSpecException { if (paramSpec == DSAParameterSpec.class) { return currentSpec; } throw new InvalidParameterSpecException("unknown parameter spec passed to DSA parameters object."); } protected void engineInit( AlgorithmParameterSpec paramSpec) throws InvalidParameterSpecException { if (!(paramSpec instanceof DSAParameterSpec)) { throw new InvalidParameterSpecException("DSAParameterSpec required to initialise a DSA algorithm parameters object"); } this.currentSpec = (DSAParameterSpec)paramSpec; } protected void engineInit( byte[] params) throws IOException { try { DSAParameter dsaP = DSAParameter.getInstance(ASN1Primitive.fromByteArray(params)); currentSpec = new DSAParameterSpec(dsaP.getP(), dsaP.getQ(), dsaP.getG()); } catch (ClassCastException e) { throw new IOException("Not a valid DSA Parameter encoding."); } catch (ArrayIndexOutOfBoundsException e) { throw new IOException("Not a valid DSA Parameter encoding."); } } protected void engineInit( byte[] params, String format) throws IOException { if (isASN1FormatString(format) || format.equalsIgnoreCase("X.509")) { engineInit(params); } else { throw new IOException("Unknown parameter format " + format); } } protected String engineToString() { return "DSA Parameters"; } } bouncycastle-1.49.orig/src/org/bouncycastle/jcajce/provider/asymmetric/dsa/KeyFactorySpi.java0000644000175000017500000000670011634310377032106 0ustar ebourgebourgpackage org.bouncycastle.jcajce.provider.asymmetric.dsa; import java.io.IOException; import java.security.InvalidKeyException; import java.security.Key; import java.security.PrivateKey; import java.security.PublicKey; import java.security.interfaces.DSAPrivateKey; import java.security.interfaces.DSAPublicKey; import java.security.spec.DSAPrivateKeySpec; import java.security.spec.DSAPublicKeySpec; import java.security.spec.InvalidKeySpecException; import java.security.spec.KeySpec; import org.bouncycastle.asn1.ASN1ObjectIdentifier; import org.bouncycastle.asn1.pkcs.PrivateKeyInfo; import org.bouncycastle.asn1.x509.SubjectPublicKeyInfo; import org.bouncycastle.jcajce.provider.asymmetric.util.BaseKeyFactorySpi; public class KeyFactorySpi extends BaseKeyFactorySpi { public KeyFactorySpi() { } protected KeySpec engineGetKeySpec( Key key, Class spec) throws InvalidKeySpecException { if (spec.isAssignableFrom(DSAPublicKeySpec.class) && key instanceof DSAPublicKey) { DSAPublicKey k = (DSAPublicKey)key; return new DSAPublicKeySpec(k.getY(), k.getParams().getP(), k.getParams().getQ(), k.getParams().getG()); } else if (spec.isAssignableFrom(DSAPrivateKeySpec.class) && key instanceof java.security.interfaces.DSAPrivateKey) { java.security.interfaces.DSAPrivateKey k = (java.security.interfaces.DSAPrivateKey)key; return new DSAPrivateKeySpec(k.getX(), k.getParams().getP(), k.getParams().getQ(), k.getParams().getG()); } return super.engineGetKeySpec(key, spec); } protected Key engineTranslateKey( Key key) throws InvalidKeyException { if (key instanceof DSAPublicKey) { return new BCDSAPublicKey((DSAPublicKey)key); } else if (key instanceof DSAPrivateKey) { return new BCDSAPrivateKey((DSAPrivateKey)key); } throw new InvalidKeyException("key type unknown"); } public PrivateKey generatePrivate(PrivateKeyInfo keyInfo) throws IOException { ASN1ObjectIdentifier algOid = keyInfo.getPrivateKeyAlgorithm().getAlgorithm(); if (DSAUtil.isDsaOid(algOid)) { return new BCDSAPrivateKey(keyInfo); } else { throw new IOException("algorithm identifier " + algOid + " in key not recognised"); } } public PublicKey generatePublic(SubjectPublicKeyInfo keyInfo) throws IOException { ASN1ObjectIdentifier algOid = keyInfo.getAlgorithm().getAlgorithm(); if (DSAUtil.isDsaOid(algOid)) { return new BCDSAPublicKey(keyInfo); } else { throw new IOException("algorithm identifier " + algOid + " in key not recognised"); } } protected PrivateKey engineGeneratePrivate( KeySpec keySpec) throws InvalidKeySpecException { if (keySpec instanceof DSAPrivateKeySpec) { return new BCDSAPrivateKey((DSAPrivateKeySpec)keySpec); } return super.engineGeneratePrivate(keySpec); } protected PublicKey engineGeneratePublic( KeySpec keySpec) throws InvalidKeySpecException { if (keySpec instanceof DSAPublicKeySpec) { return new BCDSAPublicKey((DSAPublicKeySpec)keySpec); } return super.engineGeneratePublic(keySpec); } } bouncycastle-1.49.orig/src/org/bouncycastle/jcajce/provider/asymmetric/dsa/BCDSAPrivateKey.java0000644000175000017500000001144411736773417032206 0ustar ebourgebourgpackage org.bouncycastle.jcajce.provider.asymmetric.dsa; import java.io.IOException; import java.io.ObjectInputStream; import java.io.ObjectOutputStream; import java.math.BigInteger; import java.security.interfaces.DSAParams; import java.security.interfaces.DSAPrivateKey; import java.security.spec.DSAParameterSpec; import java.security.spec.DSAPrivateKeySpec; import java.util.Enumeration; import org.bouncycastle.asn1.ASN1Encodable; import org.bouncycastle.asn1.ASN1Integer; import org.bouncycastle.asn1.ASN1ObjectIdentifier; import org.bouncycastle.asn1.pkcs.PrivateKeyInfo; import org.bouncycastle.asn1.x509.AlgorithmIdentifier; import org.bouncycastle.asn1.x509.DSAParameter; import org.bouncycastle.asn1.x9.X9ObjectIdentifiers; import org.bouncycastle.crypto.params.DSAPrivateKeyParameters; import org.bouncycastle.jcajce.provider.asymmetric.util.KeyUtil; import org.bouncycastle.jcajce.provider.asymmetric.util.PKCS12BagAttributeCarrierImpl; import org.bouncycastle.jce.interfaces.PKCS12BagAttributeCarrier; public class BCDSAPrivateKey implements DSAPrivateKey, PKCS12BagAttributeCarrier { private static final long serialVersionUID = -4677259546958385734L; private BigInteger x; private transient DSAParams dsaSpec; private transient PKCS12BagAttributeCarrierImpl attrCarrier = new PKCS12BagAttributeCarrierImpl(); protected BCDSAPrivateKey() { } BCDSAPrivateKey( DSAPrivateKey key) { this.x = key.getX(); this.dsaSpec = key.getParams(); } BCDSAPrivateKey( DSAPrivateKeySpec spec) { this.x = spec.getX(); this.dsaSpec = new DSAParameterSpec(spec.getP(), spec.getQ(), spec.getG()); } public BCDSAPrivateKey( PrivateKeyInfo info) throws IOException { DSAParameter params = DSAParameter.getInstance(info.getPrivateKeyAlgorithm().getParameters()); ASN1Integer derX = (ASN1Integer)info.parsePrivateKey(); this.x = derX.getValue(); this.dsaSpec = new DSAParameterSpec(params.getP(), params.getQ(), params.getG()); } BCDSAPrivateKey( DSAPrivateKeyParameters params) { this.x = params.getX(); this.dsaSpec = new DSAParameterSpec(params.getParameters().getP(), params.getParameters().getQ(), params.getParameters().getG()); } public String getAlgorithm() { return "DSA"; } /** * return the encoding format we produce in getEncoded(). * * @return the string "PKCS#8" */ public String getFormat() { return "PKCS#8"; } /** * Return a PKCS8 representation of the key. The sequence returned * represents a full PrivateKeyInfo object. * * @return a PKCS8 representation of the key. */ public byte[] getEncoded() { return KeyUtil.getEncodedPrivateKeyInfo(new AlgorithmIdentifier(X9ObjectIdentifiers.id_dsa, new DSAParameter(dsaSpec.getP(), dsaSpec.getQ(), dsaSpec.getG()).toASN1Primitive()), new ASN1Integer(getX())); } public DSAParams getParams() { return dsaSpec; } public BigInteger getX() { return x; } public boolean equals( Object o) { if (!(o instanceof DSAPrivateKey)) { return false; } DSAPrivateKey other = (DSAPrivateKey)o; return this.getX().equals(other.getX()) && this.getParams().getG().equals(other.getParams().getG()) && this.getParams().getP().equals(other.getParams().getP()) && this.getParams().getQ().equals(other.getParams().getQ()); } public int hashCode() { return this.getX().hashCode() ^ this.getParams().getG().hashCode() ^ this.getParams().getP().hashCode() ^ this.getParams().getQ().hashCode(); } public void setBagAttribute( ASN1ObjectIdentifier oid, ASN1Encodable attribute) { attrCarrier.setBagAttribute(oid, attribute); } public ASN1Encodable getBagAttribute( ASN1ObjectIdentifier oid) { return attrCarrier.getBagAttribute(oid); } public Enumeration getBagAttributeKeys() { return attrCarrier.getBagAttributeKeys(); } private void readObject( ObjectInputStream in) throws IOException, ClassNotFoundException { in.defaultReadObject(); this.dsaSpec = new DSAParameterSpec((BigInteger)in.readObject(), (BigInteger)in.readObject(), (BigInteger)in.readObject()); this.attrCarrier = new PKCS12BagAttributeCarrierImpl(); } private void writeObject( ObjectOutputStream out) throws IOException { out.defaultWriteObject(); out.writeObject(dsaSpec.getP()); out.writeObject(dsaSpec.getQ()); out.writeObject(dsaSpec.getG()); } } bouncycastle-1.49.orig/src/org/bouncycastle/jcajce/provider/asymmetric/dsa/KeyPairGeneratorSpi.java0000644000175000017500000000530111630055417033232 0ustar ebourgebourgpackage org.bouncycastle.jcajce.provider.asymmetric.dsa; import java.security.InvalidAlgorithmParameterException; import java.security.InvalidParameterException; import java.security.KeyPair; import java.security.SecureRandom; import java.security.spec.AlgorithmParameterSpec; import java.security.spec.DSAParameterSpec; import org.bouncycastle.crypto.AsymmetricCipherKeyPair; import org.bouncycastle.crypto.generators.DSAKeyPairGenerator; import org.bouncycastle.crypto.generators.DSAParametersGenerator; import org.bouncycastle.crypto.params.DSAKeyGenerationParameters; import org.bouncycastle.crypto.params.DSAParameters; import org.bouncycastle.crypto.params.DSAPrivateKeyParameters; import org.bouncycastle.crypto.params.DSAPublicKeyParameters; public class KeyPairGeneratorSpi extends java.security.KeyPairGenerator { DSAKeyGenerationParameters param; DSAKeyPairGenerator engine = new DSAKeyPairGenerator(); int strength = 1024; int certainty = 20; SecureRandom random = new SecureRandom(); boolean initialised = false; public KeyPairGeneratorSpi() { super("DSA"); } public void initialize( int strength, SecureRandom random) { if (strength < 512 || strength > 1024 || strength % 64 != 0) { throw new InvalidParameterException("strength must be from 512 - 1024 and a multiple of 64"); } this.strength = strength; this.random = random; } public void initialize( AlgorithmParameterSpec params, SecureRandom random) throws InvalidAlgorithmParameterException { if (!(params instanceof DSAParameterSpec)) { throw new InvalidAlgorithmParameterException("parameter object not a DSAParameterSpec"); } DSAParameterSpec dsaParams = (DSAParameterSpec)params; param = new DSAKeyGenerationParameters(random, new DSAParameters(dsaParams.getP(), dsaParams.getQ(), dsaParams.getG())); engine.init(param); initialised = true; } public KeyPair generateKeyPair() { if (!initialised) { DSAParametersGenerator pGen = new DSAParametersGenerator(); pGen.init(strength, certainty, random); param = new DSAKeyGenerationParameters(random, pGen.generateParameters()); engine.init(param); initialised = true; } AsymmetricCipherKeyPair pair = engine.generateKeyPair(); DSAPublicKeyParameters pub = (DSAPublicKeyParameters)pair.getPublic(); DSAPrivateKeyParameters priv = (DSAPrivateKeyParameters)pair.getPrivate(); return new KeyPair(new BCDSAPublicKey(pub), new BCDSAPrivateKey(priv)); } } bouncycastle-1.49.orig/src/org/bouncycastle/jcajce/provider/asymmetric/dsa/DSASigner.java0000644000175000017500000001561112144051440031120 0ustar ebourgebourgpackage org.bouncycastle.jcajce.provider.asymmetric.dsa; import java.io.IOException; import java.math.BigInteger; import java.security.InvalidKeyException; import java.security.PrivateKey; import java.security.PublicKey; import java.security.SecureRandom; import java.security.SignatureException; import java.security.SignatureSpi; import java.security.interfaces.DSAKey; import java.security.spec.AlgorithmParameterSpec; import org.bouncycastle.asn1.ASN1Encoding; import org.bouncycastle.asn1.ASN1Integer; import org.bouncycastle.asn1.ASN1Primitive; import org.bouncycastle.asn1.ASN1Sequence; import org.bouncycastle.asn1.DERSequence; import org.bouncycastle.asn1.pkcs.PKCSObjectIdentifiers; import org.bouncycastle.asn1.x509.SubjectPublicKeyInfo; import org.bouncycastle.asn1.x509.X509ObjectIdentifiers; import org.bouncycastle.crypto.CipherParameters; import org.bouncycastle.crypto.DSA; import org.bouncycastle.crypto.Digest; import org.bouncycastle.crypto.digests.NullDigest; import org.bouncycastle.crypto.digests.SHA1Digest; import org.bouncycastle.crypto.digests.SHA224Digest; import org.bouncycastle.crypto.digests.SHA256Digest; import org.bouncycastle.crypto.digests.SHA384Digest; import org.bouncycastle.crypto.digests.SHA512Digest; import org.bouncycastle.crypto.params.ParametersWithRandom; public class DSASigner extends SignatureSpi implements PKCSObjectIdentifiers, X509ObjectIdentifiers { private Digest digest; private DSA signer; private SecureRandom random; protected DSASigner( Digest digest, DSA signer) { this.digest = digest; this.signer = signer; } protected void engineInitVerify( PublicKey publicKey) throws InvalidKeyException { CipherParameters param; if (publicKey instanceof DSAKey) { param = DSAUtil.generatePublicKeyParameter(publicKey); } else { try { byte[] bytes = publicKey.getEncoded(); publicKey = new BCDSAPublicKey(SubjectPublicKeyInfo.getInstance(bytes)); if (publicKey instanceof DSAKey) { param = DSAUtil.generatePublicKeyParameter(publicKey); } else { throw new InvalidKeyException("can't recognise key type in DSA based signer"); } } catch (Exception e) { throw new InvalidKeyException("can't recognise key type in DSA based signer"); } } digest.reset(); signer.init(false, param); } protected void engineInitSign( PrivateKey privateKey, SecureRandom random) throws InvalidKeyException { this.random = random; engineInitSign(privateKey); } protected void engineInitSign( PrivateKey privateKey) throws InvalidKeyException { CipherParameters param; param = DSAUtil.generatePrivateKeyParameter(privateKey); if (random != null) { param = new ParametersWithRandom(param, random); } digest.reset(); signer.init(true, param); } protected void engineUpdate( byte b) throws SignatureException { digest.update(b); } protected void engineUpdate( byte[] b, int off, int len) throws SignatureException { digest.update(b, off, len); } protected byte[] engineSign() throws SignatureException { byte[] hash = new byte[digest.getDigestSize()]; digest.doFinal(hash, 0); try { BigInteger[] sig = signer.generateSignature(hash); return derEncode(sig[0], sig[1]); } catch (Exception e) { throw new SignatureException(e.toString()); } } protected boolean engineVerify( byte[] sigBytes) throws SignatureException { byte[] hash = new byte[digest.getDigestSize()]; digest.doFinal(hash, 0); BigInteger[] sig; try { sig = derDecode(sigBytes); } catch (Exception e) { throw new SignatureException("error decoding signature bytes."); } return signer.verifySignature(hash, sig[0], sig[1]); } protected void engineSetParameter( AlgorithmParameterSpec params) { throw new UnsupportedOperationException("engineSetParameter unsupported"); } /** * @deprecated replaced with
    */ protected void engineSetParameter( String param, Object value) { throw new UnsupportedOperationException("engineSetParameter unsupported"); } /** * @deprecated */ protected Object engineGetParameter( String param) { throw new UnsupportedOperationException("engineSetParameter unsupported"); } private byte[] derEncode( BigInteger r, BigInteger s) throws IOException { ASN1Integer[] rs = new ASN1Integer[]{ new ASN1Integer(r), new ASN1Integer(s) }; return new DERSequence(rs).getEncoded(ASN1Encoding.DER); } private BigInteger[] derDecode( byte[] encoding) throws IOException { ASN1Sequence s = (ASN1Sequence)ASN1Primitive.fromByteArray(encoding); return new BigInteger[]{ ((ASN1Integer)s.getObjectAt(0)).getValue(), ((ASN1Integer)s.getObjectAt(1)).getValue() }; } static public class stdDSA extends DSASigner { public stdDSA() { super(new SHA1Digest(), new org.bouncycastle.crypto.signers.DSASigner()); } } static public class dsa224 extends DSASigner { public dsa224() { super(new SHA224Digest(), new org.bouncycastle.crypto.signers.DSASigner()); } } static public class dsa256 extends DSASigner { public dsa256() { super(new SHA256Digest(), new org.bouncycastle.crypto.signers.DSASigner()); } } static public class dsa384 extends DSASigner { public dsa384() { super(new SHA384Digest(), new org.bouncycastle.crypto.signers.DSASigner()); } } static public class dsa512 extends DSASigner { public dsa512() { super(new SHA512Digest(), new org.bouncycastle.crypto.signers.DSASigner()); } } static public class noneDSA extends DSASigner { public noneDSA() { super(new NullDigest(), new org.bouncycastle.crypto.signers.DSASigner()); } } } bouncycastle-1.49.orig/src/org/bouncycastle/jcajce/provider/asymmetric/X509.java0000644000175000017500000000175511726011610027243 0ustar ebourgebourgpackage org.bouncycastle.jcajce.provider.asymmetric; import org.bouncycastle.jcajce.provider.config.ConfigurableProvider; import org.bouncycastle.jcajce.provider.util.AsymmetricAlgorithmProvider; /** * For some reason the class path project thinks that such a KeyFactory will exist. */ public class X509 { public static class Mappings extends AsymmetricAlgorithmProvider { public Mappings() { } public void configure(ConfigurableProvider provider) { provider.addAlgorithm("KeyFactory.X.509", "org.bouncycastle.jcajce.provider.asymmetric.x509.KeyFactory"); provider.addAlgorithm("Alg.Alias.KeyFactory.X509", "X.509"); // // certificate factories. // provider.addAlgorithm("CertificateFactory.X.509", "org.bouncycastle.jcajce.provider.asymmetric.x509.CertificateFactory"); provider.addAlgorithm("Alg.Alias.CertificateFactory.X509", "X.509"); } } } bouncycastle-1.49.orig/src/org/bouncycastle/jcajce/provider/asymmetric/dh/0000755000175000017500000000000012152033551026320 5ustar ebourgebourgbouncycastle-1.49.orig/src/org/bouncycastle/jcajce/provider/asymmetric/dh/IESCipher.java0000600000175000017500000003501412151274313030733 0ustar ebourgebourgpackage org.bouncycastle.jcajce.provider.asymmetric.dh; import java.io.ByteArrayOutputStream; import java.security.AlgorithmParameters; import java.security.InvalidAlgorithmParameterException; import java.security.InvalidKeyException; import java.security.Key; import java.security.NoSuchAlgorithmException; import java.security.PrivateKey; import java.security.PublicKey; import java.security.SecureRandom; import java.security.spec.AlgorithmParameterSpec; import javax.crypto.BadPaddingException; import javax.crypto.Cipher; import javax.crypto.CipherSpi; import javax.crypto.IllegalBlockSizeException; import javax.crypto.NoSuchPaddingException; import javax.crypto.ShortBufferException; import javax.crypto.interfaces.DHKey; import javax.crypto.interfaces.DHPrivateKey; import javax.crypto.interfaces.DHPublicKey; import org.bouncycastle.crypto.InvalidCipherTextException; import org.bouncycastle.crypto.KeyEncoder; import org.bouncycastle.crypto.agreement.DHBasicAgreement; import org.bouncycastle.crypto.digests.SHA1Digest; import org.bouncycastle.crypto.engines.AESEngine; import org.bouncycastle.crypto.engines.DESedeEngine; import org.bouncycastle.crypto.engines.IESEngine; import org.bouncycastle.crypto.generators.DHKeyPairGenerator; import org.bouncycastle.crypto.generators.EphemeralKeyPairGenerator; import org.bouncycastle.crypto.generators.KDF2BytesGenerator; import org.bouncycastle.crypto.macs.HMac; import org.bouncycastle.crypto.paddings.PaddedBufferedBlockCipher; import org.bouncycastle.crypto.params.AsymmetricKeyParameter; import org.bouncycastle.crypto.params.DHKeyGenerationParameters; import org.bouncycastle.crypto.params.DHKeyParameters; import org.bouncycastle.crypto.params.DHParameters; import org.bouncycastle.crypto.params.DHPublicKeyParameters; import org.bouncycastle.crypto.params.IESParameters; import org.bouncycastle.crypto.params.IESWithCipherParameters; import org.bouncycastle.crypto.parsers.DHIESPublicKeyParser; import org.bouncycastle.jcajce.provider.asymmetric.util.DHUtil; import org.bouncycastle.jcajce.provider.asymmetric.util.IESUtil; import org.bouncycastle.jce.interfaces.IESKey; import org.bouncycastle.jce.provider.BouncyCastleProvider; import org.bouncycastle.jce.spec.IESParameterSpec; import org.bouncycastle.util.BigIntegers; import org.bouncycastle.util.Strings; public class IESCipher extends CipherSpi { private IESEngine engine; private int state = -1; private ByteArrayOutputStream buffer = new ByteArrayOutputStream(); private AlgorithmParameters engineParam = null; private IESParameterSpec engineSpec = null; private AsymmetricKeyParameter key; private SecureRandom random; private boolean dhaesMode = false; private AsymmetricKeyParameter otherKeyParameter = null; public IESCipher(IESEngine engine) { this.engine = engine; } public int engineGetBlockSize() { if (engine.getCipher() != null) { return engine.getCipher().getBlockSize(); } else { return 0; } } public int engineGetKeySize(Key key) { if (key instanceof DHKey) { return ((DHKey)key).getParams().getP().bitLength(); } else { throw new IllegalArgumentException("not a DH key"); } } public byte[] engineGetIV() { return null; } public AlgorithmParameters engineGetParameters() { if (engineParam == null && engineSpec != null) { try { engineParam = AlgorithmParameters.getInstance("IES", BouncyCastleProvider.PROVIDER_NAME); engineParam.init(engineSpec); } catch (Exception e) { throw new RuntimeException(e.toString()); } } return engineParam; } public void engineSetMode(String mode) throws NoSuchAlgorithmException { String modeName = Strings.toUpperCase(mode); if (modeName.equals("NONE")) { dhaesMode = false; } else if (modeName.equals("DHAES")) { dhaesMode = true; } else { throw new IllegalArgumentException("can't support mode " + mode); } } public int engineGetOutputSize(int inputLen) { int len1, len2, len3; len1 = engine.getMac().getMacSize(); if (key != null) { len2 = ((DHKey)key).getParams().getP().bitLength() / 8 + 1; } else { throw new IllegalStateException("cipher not initialised"); } if (engine.getCipher() == null) { len3 = inputLen; } else if (state == Cipher.ENCRYPT_MODE || state == Cipher.WRAP_MODE) { len3 = engine.getCipher().getOutputSize(inputLen); } else if (state == Cipher.DECRYPT_MODE || state == Cipher.UNWRAP_MODE) { len3 = engine.getCipher().getOutputSize(inputLen - len1 - len2); } else { throw new IllegalStateException("cipher not initialised"); } if (state == Cipher.ENCRYPT_MODE || state == Cipher.WRAP_MODE) { return buffer.size() + len1 + len2 + len3; } else if (state == Cipher.DECRYPT_MODE || state == Cipher.UNWRAP_MODE) { return buffer.size() - len1 - len2 + len3; } else { throw new IllegalStateException("IESCipher not initialised"); } } public void engineSetPadding(String padding) throws NoSuchPaddingException { String paddingName = Strings.toUpperCase(padding); // TDOD: make this meaningful... if (paddingName.equals("NOPADDING")) { } else if (paddingName.equals("PKCS5PADDING") || paddingName.equals("PKCS7PADDING")) { } else { throw new NoSuchPaddingException("padding not available with IESCipher"); } } // Initialisation methods public void engineInit( int opmode, Key key, AlgorithmParameters params, SecureRandom random) throws InvalidKeyException, InvalidAlgorithmParameterException { AlgorithmParameterSpec paramSpec = null; if (params != null) { try { paramSpec = params.getParameterSpec(IESParameterSpec.class); } catch (Exception e) { throw new InvalidAlgorithmParameterException("cannot recognise parameters: " + e.toString()); } } engineParam = params; engineInit(opmode, key, paramSpec, random); } public void engineInit( int opmode, Key key, AlgorithmParameterSpec engineSpec, SecureRandom random) throws InvalidAlgorithmParameterException, InvalidKeyException { // Use default parameters (including cipher key size) if none are specified if (engineSpec == null) { this.engineSpec = IESUtil.guessParameterSpec(engine); } else if (engineSpec instanceof IESParameterSpec) { this.engineSpec = (IESParameterSpec)engineSpec; } else { throw new InvalidAlgorithmParameterException("must be passed IES parameters"); } // Parse the recipient's key if (opmode == Cipher.ENCRYPT_MODE || opmode == Cipher.WRAP_MODE) { if (key instanceof DHPublicKey) { this.key = DHUtil.generatePublicKeyParameter((PublicKey)key); } else if (key instanceof IESKey) { IESKey ieKey = (IESKey)key; this.key = DHUtil.generatePublicKeyParameter(ieKey.getPublic()); this.otherKeyParameter = DHUtil.generatePrivateKeyParameter(ieKey.getPrivate()); } else { throw new InvalidKeyException("must be passed recipient's public DH key for encryption"); } } else if (opmode == Cipher.DECRYPT_MODE || opmode == Cipher.UNWRAP_MODE) { if (key instanceof DHPrivateKey) { this.key = DHUtil.generatePrivateKeyParameter((PrivateKey)key); } else if (key instanceof IESKey) { IESKey ieKey = (IESKey)key; this.otherKeyParameter = DHUtil.generatePublicKeyParameter(ieKey.getPublic()); this.key = DHUtil.generatePrivateKeyParameter(ieKey.getPrivate()); } else { throw new InvalidKeyException("must be passed recipient's private DH key for decryption"); } } else { throw new InvalidKeyException("must be passed EC key"); } this.random = random; this.state = opmode; buffer.reset(); } public void engineInit( int opmode, Key key, SecureRandom random) throws InvalidKeyException { try { engineInit(opmode, key, (AlgorithmParameterSpec)null, random); } catch (InvalidAlgorithmParameterException e) { throw new IllegalArgumentException("can't handle supplied parameter spec"); } } // Update methods - buffer the input public byte[] engineUpdate( byte[] input, int inputOffset, int inputLen) { buffer.write(input, inputOffset, inputLen); return null; } public int engineUpdate( byte[] input, int inputOffset, int inputLen, byte[] output, int outputOffset) { buffer.write(input, inputOffset, inputLen); return 0; } // Finalisation methods public byte[] engineDoFinal( byte[] input, int inputOffset, int inputLen) throws IllegalBlockSizeException, BadPaddingException { if (inputLen != 0) { buffer.write(input, inputOffset, inputLen); } byte[] in = buffer.toByteArray(); buffer.reset(); // Convert parameters for use in IESEngine IESParameters params = new IESWithCipherParameters(engineSpec.getDerivationV(), engineSpec.getEncodingV(), engineSpec.getMacKeySize(), engineSpec.getCipherKeySize()); DHParameters dhParams = ((DHKeyParameters)key).getParameters(); byte[] V; if (otherKeyParameter != null) { try { if (state == Cipher.ENCRYPT_MODE || state == Cipher.WRAP_MODE) { engine.init(true, otherKeyParameter, key, params); } else { engine.init(false, key, otherKeyParameter, params); } return engine.processBlock(in, 0, in.length); } catch (Exception e) { throw new BadPaddingException(e.getMessage()); } } if (state == Cipher.ENCRYPT_MODE || state == Cipher.WRAP_MODE) { // Generate the ephemeral key pair DHKeyPairGenerator gen = new DHKeyPairGenerator(); gen.init(new DHKeyGenerationParameters(random, dhParams)); EphemeralKeyPairGenerator kGen = new EphemeralKeyPairGenerator(gen, new KeyEncoder() { public byte[] getEncoded(AsymmetricKeyParameter keyParameter) { byte[] Vloc = new byte[(((DHKeyParameters)keyParameter).getParameters().getP().bitLength() + 7) / 8]; byte[] Vtmp = BigIntegers.asUnsignedByteArray(((DHPublicKeyParameters)keyParameter).getY()); if (Vtmp.length > Vloc.length) { throw new IllegalArgumentException("Senders's public key longer than expected."); } else { System.arraycopy(Vtmp, 0, Vloc, Vloc.length - Vtmp.length, Vtmp.length); } return Vloc; } }); // Encrypt the buffer try { engine.init(key, params, kGen); return engine.processBlock(in, 0, in.length); } catch (Exception e) { throw new BadPaddingException(e.getMessage()); } } else if (state == Cipher.DECRYPT_MODE || state == Cipher.UNWRAP_MODE) { // Decrypt the buffer try { engine.init(key, params, new DHIESPublicKeyParser(((DHKeyParameters)key).getParameters())); return engine.processBlock(in, 0, in.length); } catch (InvalidCipherTextException e) { throw new BadPaddingException(e.getMessage()); } } else { throw new IllegalStateException("IESCipher not initialised"); } } public int engineDoFinal( byte[] input, int inputOffset, int inputLength, byte[] output, int outputOffset) throws ShortBufferException, IllegalBlockSizeException, BadPaddingException { byte[] buf = engineDoFinal(input, inputOffset, inputLength); System.arraycopy(buf, 0, output, outputOffset, buf.length); return buf.length; } /** * Classes that inherit from us */ static public class IES extends IESCipher { public IES() { super(new IESEngine(new DHBasicAgreement(), new KDF2BytesGenerator(new SHA1Digest()), new HMac(new SHA1Digest()))); } } static public class IESwithDESede extends IESCipher { public IESwithDESede() { super(new IESEngine(new DHBasicAgreement(), new KDF2BytesGenerator(new SHA1Digest()), new HMac(new SHA1Digest()), new PaddedBufferedBlockCipher(new DESedeEngine()))); } } static public class IESwithAES extends IESCipher { public IESwithAES() { super(new IESEngine(new DHBasicAgreement(), new KDF2BytesGenerator(new SHA1Digest()), new HMac(new SHA1Digest()), new PaddedBufferedBlockCipher(new AESEngine()))); } } } ././@LongLink0000000000000000000000000000015600000000000011567 Lustar rootrootbouncycastle-1.49.orig/src/org/bouncycastle/jcajce/provider/asymmetric/dh/AlgorithmParameterGeneratorSpi.javabouncycastle-1.49.orig/src/org/bouncycastle/jcajce/provider/asymmetric/dh/AlgorithmParameterGenerato0000644000175000017500000000417311634266241033534 0ustar ebourgebourgpackage org.bouncycastle.jcajce.provider.asymmetric.dh; import java.security.AlgorithmParameters; import java.security.InvalidAlgorithmParameterException; import java.security.SecureRandom; import java.security.spec.AlgorithmParameterSpec; import javax.crypto.spec.DHGenParameterSpec; import javax.crypto.spec.DHParameterSpec; import org.bouncycastle.crypto.generators.DHParametersGenerator; import org.bouncycastle.crypto.params.DHParameters; import org.bouncycastle.jce.provider.BouncyCastleProvider; public class AlgorithmParameterGeneratorSpi extends java.security.AlgorithmParameterGeneratorSpi { protected SecureRandom random; protected int strength = 1024; private int l = 0; protected void engineInit( int strength, SecureRandom random) { this.strength = strength; this.random = random; } protected void engineInit( AlgorithmParameterSpec genParamSpec, SecureRandom random) throws InvalidAlgorithmParameterException { if (!(genParamSpec instanceof DHGenParameterSpec)) { throw new InvalidAlgorithmParameterException("DH parameter generator requires a DHGenParameterSpec for initialisation"); } DHGenParameterSpec spec = (DHGenParameterSpec)genParamSpec; this.strength = spec.getPrimeSize(); this.l = spec.getExponentSize(); this.random = random; } protected AlgorithmParameters engineGenerateParameters() { DHParametersGenerator pGen = new DHParametersGenerator(); if (random != null) { pGen.init(strength, 20, random); } else { pGen.init(strength, 20, new SecureRandom()); } DHParameters p = pGen.generateParameters(); AlgorithmParameters params; try { params = AlgorithmParameters.getInstance("DH", BouncyCastleProvider.PROVIDER_NAME); params.init(new DHParameterSpec(p.getP(), p.getG(), l)); } catch (Exception e) { throw new RuntimeException(e.getMessage()); } return params; } } ././@LongLink0000000000000000000000000000014600000000000011566 Lustar rootrootbouncycastle-1.49.orig/src/org/bouncycastle/jcajce/provider/asymmetric/dh/AlgorithmParametersSpi.javabouncycastle-1.49.orig/src/org/bouncycastle/jcajce/provider/asymmetric/dh/AlgorithmParametersSpi.jav0000644000175000017500000000775111634266241033472 0ustar ebourgebourgpackage org.bouncycastle.jcajce.provider.asymmetric.dh; import java.io.IOException; import java.security.spec.AlgorithmParameterSpec; import java.security.spec.InvalidParameterSpecException; import javax.crypto.spec.DHParameterSpec; import org.bouncycastle.asn1.ASN1Encoding; import org.bouncycastle.asn1.pkcs.DHParameter; public class AlgorithmParametersSpi extends java.security.AlgorithmParametersSpi { DHParameterSpec currentSpec; protected boolean isASN1FormatString(String format) { return format == null || format.equals("ASN.1"); } protected AlgorithmParameterSpec engineGetParameterSpec( Class paramSpec) throws InvalidParameterSpecException { if (paramSpec == null) { throw new NullPointerException("argument to getParameterSpec must not be null"); } return localEngineGetParameterSpec(paramSpec); } /** * Return the PKCS#3 ASN.1 structure DHParameter. *

    *

             *  DHParameter ::= SEQUENCE {
             *                   prime INTEGER, -- p
             *                   base INTEGER, -- g
             *                   privateValueLength INTEGER OPTIONAL}
             * 
    */ protected byte[] engineGetEncoded() { DHParameter dhP = new DHParameter(currentSpec.getP(), currentSpec.getG(), currentSpec.getL()); try { return dhP.getEncoded(ASN1Encoding.DER); } catch (IOException e) { throw new RuntimeException("Error encoding DHParameters"); } } protected byte[] engineGetEncoded( String format) { if (isASN1FormatString(format)) { return engineGetEncoded(); } return null; } protected AlgorithmParameterSpec localEngineGetParameterSpec( Class paramSpec) throws InvalidParameterSpecException { if (paramSpec == DHParameterSpec.class) { return currentSpec; } throw new InvalidParameterSpecException("unknown parameter spec passed to DH parameters object."); } protected void engineInit( AlgorithmParameterSpec paramSpec) throws InvalidParameterSpecException { if (!(paramSpec instanceof DHParameterSpec)) { throw new InvalidParameterSpecException("DHParameterSpec required to initialise a Diffie-Hellman algorithm parameters object"); } this.currentSpec = (DHParameterSpec)paramSpec; } protected void engineInit( byte[] params) throws IOException { try { DHParameter dhP = DHParameter.getInstance(params); if (dhP.getL() != null) { currentSpec = new DHParameterSpec(dhP.getP(), dhP.getG(), dhP.getL().intValue()); } else { currentSpec = new DHParameterSpec(dhP.getP(), dhP.getG()); } } catch (ClassCastException e) { throw new IOException("Not a valid DH Parameter encoding."); } catch (ArrayIndexOutOfBoundsException e) { throw new IOException("Not a valid DH Parameter encoding."); } } protected void engineInit( byte[] params, String format) throws IOException { if (isASN1FormatString(format)) { engineInit(params); } else { throw new IOException("Unknown parameter format " + format); } } protected String engineToString() { return "Diffie-Hellman Parameters"; } } bouncycastle-1.49.orig/src/org/bouncycastle/jcajce/provider/asymmetric/dh/KeyFactorySpi.java0000644000175000017500000000733411634257460031741 0ustar ebourgebourgpackage org.bouncycastle.jcajce.provider.asymmetric.dh; import java.io.IOException; import java.security.InvalidKeyException; import java.security.Key; import java.security.PrivateKey; import java.security.PublicKey; import java.security.spec.InvalidKeySpecException; import java.security.spec.KeySpec; import javax.crypto.interfaces.DHPrivateKey; import javax.crypto.interfaces.DHPublicKey; import javax.crypto.spec.DHPrivateKeySpec; import javax.crypto.spec.DHPublicKeySpec; import org.bouncycastle.asn1.ASN1ObjectIdentifier; import org.bouncycastle.asn1.pkcs.PKCSObjectIdentifiers; import org.bouncycastle.asn1.pkcs.PrivateKeyInfo; import org.bouncycastle.asn1.x509.SubjectPublicKeyInfo; import org.bouncycastle.asn1.x9.X9ObjectIdentifiers; import org.bouncycastle.jcajce.provider.asymmetric.util.BaseKeyFactorySpi; public class KeyFactorySpi extends BaseKeyFactorySpi { public KeyFactorySpi() { } protected KeySpec engineGetKeySpec( Key key, Class spec) throws InvalidKeySpecException { if (spec.isAssignableFrom(DHPrivateKeySpec.class) && key instanceof DHPrivateKey) { DHPrivateKey k = (DHPrivateKey)key; return new DHPrivateKeySpec(k.getX(), k.getParams().getP(), k.getParams().getG()); } else if (spec.isAssignableFrom(DHPublicKeySpec.class) && key instanceof DHPublicKey) { DHPublicKey k = (DHPublicKey)key; return new DHPublicKeySpec(k.getY(), k.getParams().getP(), k.getParams().getG()); } return super.engineGetKeySpec(key, spec); } protected Key engineTranslateKey( Key key) throws InvalidKeyException { if (key instanceof DHPublicKey) { return new BCDHPublicKey((DHPublicKey)key); } else if (key instanceof DHPrivateKey) { return new BCDHPrivateKey((DHPrivateKey)key); } throw new InvalidKeyException("key type unknown"); } protected PrivateKey engineGeneratePrivate( KeySpec keySpec) throws InvalidKeySpecException { if (keySpec instanceof DHPrivateKeySpec) { return new BCDHPrivateKey((DHPrivateKeySpec)keySpec); } return super.engineGeneratePrivate(keySpec); } protected PublicKey engineGeneratePublic( KeySpec keySpec) throws InvalidKeySpecException { if (keySpec instanceof DHPublicKeySpec) { return new BCDHPublicKey((DHPublicKeySpec)keySpec); } return super.engineGeneratePublic(keySpec); } public PrivateKey generatePrivate(PrivateKeyInfo keyInfo) throws IOException { ASN1ObjectIdentifier algOid = keyInfo.getPrivateKeyAlgorithm().getAlgorithm(); if (algOid.equals(PKCSObjectIdentifiers.dhKeyAgreement)) { return new BCDHPrivateKey(keyInfo); } else if (algOid.equals(X9ObjectIdentifiers.dhpublicnumber)) { return new BCDHPrivateKey(keyInfo); } else { throw new IOException("algorithm identifier " + algOid + " in key not recognised"); } } public PublicKey generatePublic(SubjectPublicKeyInfo keyInfo) throws IOException { ASN1ObjectIdentifier algOid = keyInfo.getAlgorithm().getAlgorithm(); if (algOid.equals(PKCSObjectIdentifiers.dhKeyAgreement)) { return new BCDHPublicKey(keyInfo); } else if (algOid.equals(X9ObjectIdentifiers.dhpublicnumber)) { return new BCDHPublicKey(keyInfo); } else { throw new IOException("algorithm identifier " + algOid + " in key not recognised"); } } } bouncycastle-1.49.orig/src/org/bouncycastle/jcajce/provider/asymmetric/dh/KeyAgreementSpi.java0000644000175000017500000001346712103440465032234 0ustar ebourgebourgpackage org.bouncycastle.jcajce.provider.asymmetric.dh; import java.math.BigInteger; import java.security.InvalidAlgorithmParameterException; import java.security.InvalidKeyException; import java.security.Key; import java.security.SecureRandom; import java.security.spec.AlgorithmParameterSpec; import java.util.Hashtable; import javax.crypto.SecretKey; import javax.crypto.ShortBufferException; import javax.crypto.interfaces.DHPrivateKey; import javax.crypto.interfaces.DHPublicKey; import javax.crypto.spec.DHParameterSpec; import javax.crypto.spec.SecretKeySpec; import org.bouncycastle.crypto.params.DESParameters; import org.bouncycastle.util.Integers; import org.bouncycastle.util.Strings; /** * Diffie-Hellman key agreement. There's actually a better way of doing this * if you are using long term public keys, see the light-weight version for * details. */ public class KeyAgreementSpi extends javax.crypto.KeyAgreementSpi { private BigInteger x; private BigInteger p; private BigInteger g; private BigInteger result; private static final Hashtable algorithms = new Hashtable(); static { Integer i64 = Integers.valueOf(64); Integer i192 = Integers.valueOf(192); Integer i128 = Integers.valueOf(128); Integer i256 = Integers.valueOf(256); algorithms.put("DES", i64); algorithms.put("DESEDE", i192); algorithms.put("BLOWFISH", i128); algorithms.put("AES", i256); } private byte[] bigIntToBytes( BigInteger r) { byte[] tmp = r.toByteArray(); if (tmp[0] == 0) { byte[] ntmp = new byte[tmp.length - 1]; System.arraycopy(tmp, 1, ntmp, 0, ntmp.length); return ntmp; } return tmp; } protected Key engineDoPhase( Key key, boolean lastPhase) throws InvalidKeyException, IllegalStateException { if (x == null) { throw new IllegalStateException("Diffie-Hellman not initialised."); } if (!(key instanceof DHPublicKey)) { throw new InvalidKeyException("DHKeyAgreement doPhase requires DHPublicKey"); } DHPublicKey pubKey = (DHPublicKey)key; if (!pubKey.getParams().getG().equals(g) || !pubKey.getParams().getP().equals(p)) { throw new InvalidKeyException("DHPublicKey not for this KeyAgreement!"); } if (lastPhase) { result = ((DHPublicKey)key).getY().modPow(x, p); return null; } else { result = ((DHPublicKey)key).getY().modPow(x, p); } return new BCDHPublicKey(result, pubKey.getParams()); } protected byte[] engineGenerateSecret() throws IllegalStateException { if (x == null) { throw new IllegalStateException("Diffie-Hellman not initialised."); } return bigIntToBytes(result); } protected int engineGenerateSecret( byte[] sharedSecret, int offset) throws IllegalStateException, ShortBufferException { if (x == null) { throw new IllegalStateException("Diffie-Hellman not initialised."); } byte[] secret = bigIntToBytes(result); if (sharedSecret.length - offset < secret.length) { throw new ShortBufferException("DHKeyAgreement - buffer too short"); } System.arraycopy(secret, 0, sharedSecret, offset, secret.length); return secret.length; } protected SecretKey engineGenerateSecret( String algorithm) { if (x == null) { throw new IllegalStateException("Diffie-Hellman not initialised."); } String algKey = Strings.toUpperCase(algorithm); byte[] res = bigIntToBytes(result); if (algorithms.containsKey(algKey)) { Integer length = (Integer)algorithms.get(algKey); byte[] key = new byte[length.intValue() / 8]; System.arraycopy(res, 0, key, 0, key.length); if (algKey.startsWith("DES")) { DESParameters.setOddParity(key); } return new SecretKeySpec(key, algorithm); } return new SecretKeySpec(res, algorithm); } protected void engineInit( Key key, AlgorithmParameterSpec params, SecureRandom random) throws InvalidKeyException, InvalidAlgorithmParameterException { if (!(key instanceof DHPrivateKey)) { throw new InvalidKeyException("DHKeyAgreement requires DHPrivateKey for initialisation"); } DHPrivateKey privKey = (DHPrivateKey)key; if (params != null) { if (!(params instanceof DHParameterSpec)) { throw new InvalidAlgorithmParameterException("DHKeyAgreement only accepts DHParameterSpec"); } DHParameterSpec p = (DHParameterSpec)params; this.p = p.getP(); this.g = p.getG(); } else { this.p = privKey.getParams().getP(); this.g = privKey.getParams().getG(); } this.x = this.result = privKey.getX(); } protected void engineInit( Key key, SecureRandom random) throws InvalidKeyException { if (!(key instanceof DHPrivateKey)) { throw new InvalidKeyException("DHKeyAgreement requires DHPrivateKey"); } DHPrivateKey privKey = (DHPrivateKey)key; this.p = privKey.getParams().getP(); this.g = privKey.getParams().getG(); this.x = this.result = privKey.getX(); } } bouncycastle-1.49.orig/src/org/bouncycastle/jcajce/provider/asymmetric/dh/BCDHPublicKey.java0000644000175000017500000001306411727733125031512 0ustar ebourgebourgpackage org.bouncycastle.jcajce.provider.asymmetric.dh; import java.io.IOException; import java.io.ObjectInputStream; import java.io.ObjectOutputStream; import java.math.BigInteger; import javax.crypto.interfaces.DHPublicKey; import javax.crypto.spec.DHParameterSpec; import javax.crypto.spec.DHPublicKeySpec; import org.bouncycastle.asn1.ASN1Integer; import org.bouncycastle.asn1.ASN1ObjectIdentifier; import org.bouncycastle.asn1.ASN1Sequence; import org.bouncycastle.asn1.pkcs.DHParameter; import org.bouncycastle.asn1.pkcs.PKCSObjectIdentifiers; import org.bouncycastle.asn1.x509.AlgorithmIdentifier; import org.bouncycastle.asn1.x509.SubjectPublicKeyInfo; import org.bouncycastle.asn1.x9.DHDomainParameters; import org.bouncycastle.asn1.x9.X9ObjectIdentifiers; import org.bouncycastle.crypto.params.DHPublicKeyParameters; import org.bouncycastle.jcajce.provider.asymmetric.util.KeyUtil; public class BCDHPublicKey implements DHPublicKey { static final long serialVersionUID = -216691575254424324L; private BigInteger y; private transient DHParameterSpec dhSpec; private transient SubjectPublicKeyInfo info; BCDHPublicKey( DHPublicKeySpec spec) { this.y = spec.getY(); this.dhSpec = new DHParameterSpec(spec.getP(), spec.getG()); } BCDHPublicKey( DHPublicKey key) { this.y = key.getY(); this.dhSpec = key.getParams(); } BCDHPublicKey( DHPublicKeyParameters params) { this.y = params.getY(); this.dhSpec = new DHParameterSpec(params.getParameters().getP(), params.getParameters().getG(), params.getParameters().getL()); } BCDHPublicKey( BigInteger y, DHParameterSpec dhSpec) { this.y = y; this.dhSpec = dhSpec; } public BCDHPublicKey( SubjectPublicKeyInfo info) { this.info = info; ASN1Integer derY; try { derY = (ASN1Integer)info.parsePublicKey(); } catch (IOException e) { throw new IllegalArgumentException("invalid info structure in DH public key"); } this.y = derY.getValue(); ASN1Sequence seq = ASN1Sequence.getInstance(info.getAlgorithm().getParameters()); ASN1ObjectIdentifier id = info.getAlgorithm().getAlgorithm(); // we need the PKCS check to handle older keys marked with the X9 oid. if (id.equals(PKCSObjectIdentifiers.dhKeyAgreement) || isPKCSParam(seq)) { DHParameter params = DHParameter.getInstance(seq); if (params.getL() != null) { this.dhSpec = new DHParameterSpec(params.getP(), params.getG(), params.getL().intValue()); } else { this.dhSpec = new DHParameterSpec(params.getP(), params.getG()); } } else if (id.equals(X9ObjectIdentifiers.dhpublicnumber)) { DHDomainParameters params = DHDomainParameters.getInstance(seq); this.dhSpec = new DHParameterSpec(params.getP().getValue(), params.getG().getValue()); } else { throw new IllegalArgumentException("unknown algorithm type: " + id); } } public String getAlgorithm() { return "DH"; } public String getFormat() { return "X.509"; } public byte[] getEncoded() { if (info != null) { return KeyUtil.getEncodedSubjectPublicKeyInfo(info); } return KeyUtil.getEncodedSubjectPublicKeyInfo(new AlgorithmIdentifier(PKCSObjectIdentifiers.dhKeyAgreement, new DHParameter(dhSpec.getP(), dhSpec.getG(), dhSpec.getL()).toASN1Primitive()), new ASN1Integer(y)); } public DHParameterSpec getParams() { return dhSpec; } public BigInteger getY() { return y; } private boolean isPKCSParam(ASN1Sequence seq) { if (seq.size() == 2) { return true; } if (seq.size() > 3) { return false; } ASN1Integer l = ASN1Integer.getInstance(seq.getObjectAt(2)); ASN1Integer p = ASN1Integer.getInstance(seq.getObjectAt(0)); if (l.getValue().compareTo(BigInteger.valueOf(p.getValue().bitLength())) > 0) { return false; } return true; } public int hashCode() { return this.getY().hashCode() ^ this.getParams().getG().hashCode() ^ this.getParams().getP().hashCode() ^ this.getParams().getL(); } public boolean equals( Object o) { if (!(o instanceof DHPublicKey)) { return false; } DHPublicKey other = (DHPublicKey)o; return this.getY().equals(other.getY()) && this.getParams().getG().equals(other.getParams().getG()) && this.getParams().getP().equals(other.getParams().getP()) && this.getParams().getL() == other.getParams().getL(); } private void readObject( ObjectInputStream in) throws IOException, ClassNotFoundException { in.defaultReadObject(); this.dhSpec = new DHParameterSpec((BigInteger)in.readObject(), (BigInteger)in.readObject(), in.readInt()); this.info = null; } private void writeObject( ObjectOutputStream out) throws IOException { out.defaultWriteObject(); out.writeObject(dhSpec.getP()); out.writeObject(dhSpec.getG()); out.writeInt(dhSpec.getL()); } } bouncycastle-1.49.orig/src/org/bouncycastle/jcajce/provider/asymmetric/dh/BCDHPrivateKey.java0000644000175000017500000001371711736773417031723 0ustar ebourgebourgpackage org.bouncycastle.jcajce.provider.asymmetric.dh; import java.io.IOException; import java.io.ObjectInputStream; import java.io.ObjectOutputStream; import java.math.BigInteger; import java.util.Enumeration; import javax.crypto.interfaces.DHPrivateKey; import javax.crypto.spec.DHParameterSpec; import javax.crypto.spec.DHPrivateKeySpec; import org.bouncycastle.asn1.ASN1Encodable; import org.bouncycastle.asn1.ASN1Encoding; import org.bouncycastle.asn1.ASN1Integer; import org.bouncycastle.asn1.ASN1ObjectIdentifier; import org.bouncycastle.asn1.ASN1Sequence; import org.bouncycastle.asn1.pkcs.DHParameter; import org.bouncycastle.asn1.pkcs.PKCSObjectIdentifiers; import org.bouncycastle.asn1.pkcs.PrivateKeyInfo; import org.bouncycastle.asn1.x509.AlgorithmIdentifier; import org.bouncycastle.asn1.x9.DHDomainParameters; import org.bouncycastle.asn1.x9.X9ObjectIdentifiers; import org.bouncycastle.crypto.params.DHPrivateKeyParameters; import org.bouncycastle.jcajce.provider.asymmetric.util.PKCS12BagAttributeCarrierImpl; import org.bouncycastle.jce.interfaces.PKCS12BagAttributeCarrier; public class BCDHPrivateKey implements DHPrivateKey, PKCS12BagAttributeCarrier { static final long serialVersionUID = 311058815616901812L; private BigInteger x; private transient DHParameterSpec dhSpec; private transient PrivateKeyInfo info; private transient PKCS12BagAttributeCarrierImpl attrCarrier = new PKCS12BagAttributeCarrierImpl(); protected BCDHPrivateKey() { } BCDHPrivateKey( DHPrivateKey key) { this.x = key.getX(); this.dhSpec = key.getParams(); } BCDHPrivateKey( DHPrivateKeySpec spec) { this.x = spec.getX(); this.dhSpec = new DHParameterSpec(spec.getP(), spec.getG()); } public BCDHPrivateKey( PrivateKeyInfo info) throws IOException { ASN1Sequence seq = ASN1Sequence.getInstance(info.getPrivateKeyAlgorithm().getParameters()); ASN1Integer derX = (ASN1Integer)info.parsePrivateKey(); ASN1ObjectIdentifier id = info.getPrivateKeyAlgorithm().getAlgorithm(); this.info = info; this.x = derX.getValue(); if (id.equals(PKCSObjectIdentifiers.dhKeyAgreement)) { DHParameter params = DHParameter.getInstance(seq); if (params.getL() != null) { this.dhSpec = new DHParameterSpec(params.getP(), params.getG(), params.getL().intValue()); } else { this.dhSpec = new DHParameterSpec(params.getP(), params.getG()); } } else if (id.equals(X9ObjectIdentifiers.dhpublicnumber)) { DHDomainParameters params = DHDomainParameters.getInstance(seq); this.dhSpec = new DHParameterSpec(params.getP().getValue(), params.getG().getValue()); } else { throw new IllegalArgumentException("unknown algorithm type: " + id); } } BCDHPrivateKey( DHPrivateKeyParameters params) { this.x = params.getX(); this.dhSpec = new DHParameterSpec(params.getParameters().getP(), params.getParameters().getG(), params.getParameters().getL()); } public String getAlgorithm() { return "DH"; } /** * return the encoding format we produce in getEncoded(). * * @return the string "PKCS#8" */ public String getFormat() { return "PKCS#8"; } /** * Return a PKCS8 representation of the key. The sequence returned * represents a full PrivateKeyInfo object. * * @return a PKCS8 representation of the key. */ public byte[] getEncoded() { try { if (info != null) { return info.getEncoded(ASN1Encoding.DER); } PrivateKeyInfo info = new PrivateKeyInfo(new AlgorithmIdentifier(PKCSObjectIdentifiers.dhKeyAgreement, new DHParameter(dhSpec.getP(), dhSpec.getG(), dhSpec.getL()).toASN1Primitive()), new ASN1Integer(getX())); return info.getEncoded(ASN1Encoding.DER); } catch (Exception e) { return null; } } public DHParameterSpec getParams() { return dhSpec; } public BigInteger getX() { return x; } public boolean equals( Object o) { if (!(o instanceof DHPrivateKey)) { return false; } DHPrivateKey other = (DHPrivateKey)o; return this.getX().equals(other.getX()) && this.getParams().getG().equals(other.getParams().getG()) && this.getParams().getP().equals(other.getParams().getP()) && this.getParams().getL() == other.getParams().getL(); } public int hashCode() { return this.getX().hashCode() ^ this.getParams().getG().hashCode() ^ this.getParams().getP().hashCode() ^ this.getParams().getL(); } public void setBagAttribute( ASN1ObjectIdentifier oid, ASN1Encodable attribute) { attrCarrier.setBagAttribute(oid, attribute); } public ASN1Encodable getBagAttribute( ASN1ObjectIdentifier oid) { return attrCarrier.getBagAttribute(oid); } public Enumeration getBagAttributeKeys() { return attrCarrier.getBagAttributeKeys(); } private void readObject( ObjectInputStream in) throws IOException, ClassNotFoundException { in.defaultReadObject(); this.dhSpec = new DHParameterSpec((BigInteger)in.readObject(), (BigInteger)in.readObject(), in.readInt()); this.info = null; this.attrCarrier = new PKCS12BagAttributeCarrierImpl(); } private void writeObject( ObjectOutputStream out) throws IOException { out.defaultWriteObject(); out.writeObject(dhSpec.getP()); out.writeObject(dhSpec.getG()); out.writeInt(dhSpec.getL()); } } bouncycastle-1.49.orig/src/org/bouncycastle/jcajce/provider/asymmetric/dh/KeyPairGeneratorSpi.java0000644000175000017500000000764212103440465033065 0ustar ebourgebourgpackage org.bouncycastle.jcajce.provider.asymmetric.dh; import java.security.InvalidAlgorithmParameterException; import java.security.KeyPair; import java.security.SecureRandom; import java.security.spec.AlgorithmParameterSpec; import java.util.Hashtable; import javax.crypto.spec.DHParameterSpec; import org.bouncycastle.crypto.AsymmetricCipherKeyPair; import org.bouncycastle.crypto.generators.DHBasicKeyPairGenerator; import org.bouncycastle.crypto.generators.DHParametersGenerator; import org.bouncycastle.crypto.params.DHKeyGenerationParameters; import org.bouncycastle.crypto.params.DHParameters; import org.bouncycastle.crypto.params.DHPrivateKeyParameters; import org.bouncycastle.crypto.params.DHPublicKeyParameters; import org.bouncycastle.jce.provider.BouncyCastleProvider; import org.bouncycastle.util.Integers; public class KeyPairGeneratorSpi extends java.security.KeyPairGenerator { private static Hashtable params = new Hashtable(); private static Object lock = new Object(); DHKeyGenerationParameters param; DHBasicKeyPairGenerator engine = new DHBasicKeyPairGenerator(); int strength = 1024; int certainty = 20; SecureRandom random = new SecureRandom(); boolean initialised = false; public KeyPairGeneratorSpi() { super("DH"); } public void initialize( int strength, SecureRandom random) { this.strength = strength; this.random = random; } public void initialize( AlgorithmParameterSpec params, SecureRandom random) throws InvalidAlgorithmParameterException { if (!(params instanceof DHParameterSpec)) { throw new InvalidAlgorithmParameterException("parameter object not a DHParameterSpec"); } DHParameterSpec dhParams = (DHParameterSpec)params; param = new DHKeyGenerationParameters(random, new DHParameters(dhParams.getP(), dhParams.getG(), null, dhParams.getL())); engine.init(param); initialised = true; } public KeyPair generateKeyPair() { if (!initialised) { Integer paramStrength = Integers.valueOf(strength); if (params.containsKey(paramStrength)) { param = (DHKeyGenerationParameters)params.get(paramStrength); } else { DHParameterSpec dhParams = BouncyCastleProvider.CONFIGURATION.getDHDefaultParameters(strength); if (dhParams != null) { param = new DHKeyGenerationParameters(random, new DHParameters(dhParams.getP(), dhParams.getG(), null, dhParams.getL())); } else { synchronized (lock) { // we do the check again in case we were blocked by a generator for // our key size. if (params.containsKey(paramStrength)) { param = (DHKeyGenerationParameters)params.get(paramStrength); } else { DHParametersGenerator pGen = new DHParametersGenerator(); pGen.init(strength, certainty, random); param = new DHKeyGenerationParameters(random, pGen.generateParameters()); params.put(paramStrength, param); } } } } engine.init(param); initialised = true; } AsymmetricCipherKeyPair pair = engine.generateKeyPair(); DHPublicKeyParameters pub = (DHPublicKeyParameters)pair.getPublic(); DHPrivateKeyParameters priv = (DHPrivateKeyParameters)pair.getPrivate(); return new KeyPair(new BCDHPublicKey(pub), new BCDHPrivateKey(priv)); } } bouncycastle-1.49.orig/src/org/bouncycastle/jcajce/provider/asymmetric/ies/0000755000175000017500000000000012152033551026505 5ustar ebourgebourg././@LongLink0000000000000000000000000000014700000000000011567 Lustar rootrootbouncycastle-1.49.orig/src/org/bouncycastle/jcajce/provider/asymmetric/ies/AlgorithmParametersSpi.javabouncycastle-1.49.orig/src/org/bouncycastle/jcajce/provider/asymmetric/ies/AlgorithmParametersSpi.ja0000644000175000017500000000762512110043136033453 0ustar ebourgebourgpackage org.bouncycastle.jcajce.provider.asymmetric.ies; import java.io.IOException; import java.security.spec.AlgorithmParameterSpec; import java.security.spec.InvalidParameterSpecException; import org.bouncycastle.asn1.ASN1EncodableVector; import org.bouncycastle.asn1.ASN1Encoding; import org.bouncycastle.asn1.ASN1OctetString; import org.bouncycastle.asn1.ASN1Primitive; import org.bouncycastle.asn1.ASN1Sequence; import org.bouncycastle.asn1.DERInteger; import org.bouncycastle.asn1.DEROctetString; import org.bouncycastle.asn1.DERSequence; import org.bouncycastle.jce.spec.IESParameterSpec; public class AlgorithmParametersSpi extends java.security.AlgorithmParametersSpi { protected boolean isASN1FormatString(String format) { return format == null || format.equals("ASN.1"); } protected AlgorithmParameterSpec engineGetParameterSpec( Class paramSpec) throws InvalidParameterSpecException { if (paramSpec == null) { throw new NullPointerException("argument to getParameterSpec must not be null"); } return localEngineGetParameterSpec(paramSpec); } IESParameterSpec currentSpec; /** * in the absence of a standard way of doing it this will do for * now... */ protected byte[] engineGetEncoded() { try { ASN1EncodableVector v = new ASN1EncodableVector(); v.add(new DEROctetString(currentSpec.getDerivationV())); v.add(new DEROctetString(currentSpec.getEncodingV())); v.add(new DERInteger(currentSpec.getMacKeySize())); return new DERSequence(v).getEncoded(ASN1Encoding.DER); } catch (IOException e) { throw new RuntimeException("Error encoding IESParameters"); } } protected byte[] engineGetEncoded( String format) { if (isASN1FormatString(format) || format.equalsIgnoreCase("X.509")) { return engineGetEncoded(); } return null; } protected AlgorithmParameterSpec localEngineGetParameterSpec( Class paramSpec) throws InvalidParameterSpecException { if (paramSpec == IESParameterSpec.class) { return currentSpec; } throw new InvalidParameterSpecException("unknown parameter spec passed to ElGamal parameters object."); } protected void engineInit( AlgorithmParameterSpec paramSpec) throws InvalidParameterSpecException { if (!(paramSpec instanceof IESParameterSpec)) { throw new InvalidParameterSpecException("IESParameterSpec required to initialise a IES algorithm parameters object"); } this.currentSpec = (IESParameterSpec)paramSpec; } protected void engineInit( byte[] params) throws IOException { try { ASN1Sequence s = (ASN1Sequence)ASN1Primitive.fromByteArray(params); this.currentSpec = new IESParameterSpec( ((ASN1OctetString)s.getObjectAt(0)).getOctets(), ((ASN1OctetString)s.getObjectAt(0)).getOctets(), ((DERInteger)s.getObjectAt(0)).getValue().intValue()); } catch (ClassCastException e) { throw new IOException("Not a valid IES Parameter encoding."); } catch (ArrayIndexOutOfBoundsException e) { throw new IOException("Not a valid IES Parameter encoding."); } } protected void engineInit( byte[] params, String format) throws IOException { if (isASN1FormatString(format) || format.equalsIgnoreCase("X.509")) { engineInit(params); } else { throw new IOException("Unknown parameter format " + format); } } protected String engineToString() { return "IES Parameters"; } } bouncycastle-1.49.orig/src/org/bouncycastle/jcajce/provider/asymmetric/ies/CipherSpi.java0000644000175000017500000002374512110047042031243 0ustar ebourgebourgpackage org.bouncycastle.jcajce.provider.asymmetric.ies; import java.io.ByteArrayOutputStream; import java.security.AlgorithmParameters; import java.security.InvalidAlgorithmParameterException; import java.security.InvalidKeyException; import java.security.Key; import java.security.SecureRandom; import java.security.spec.AlgorithmParameterSpec; import javax.crypto.BadPaddingException; import javax.crypto.Cipher; import javax.crypto.IllegalBlockSizeException; import javax.crypto.NoSuchPaddingException; import javax.crypto.interfaces.DHPrivateKey; import org.bouncycastle.crypto.CipherParameters; import org.bouncycastle.crypto.InvalidCipherTextException; import org.bouncycastle.crypto.agreement.DHBasicAgreement; import org.bouncycastle.crypto.digests.SHA1Digest; import org.bouncycastle.crypto.engines.IESEngine; import org.bouncycastle.crypto.generators.KDF2BytesGenerator; import org.bouncycastle.crypto.macs.HMac; import org.bouncycastle.crypto.params.IESParameters; import org.bouncycastle.jce.provider.BouncyCastleProvider; import org.bouncycastle.jcajce.provider.asymmetric.util.DHUtil; import org.bouncycastle.jcajce.provider.asymmetric.util.ECUtil; import org.bouncycastle.jce.interfaces.ECPrivateKey; import org.bouncycastle.jce.interfaces.ECPublicKey; import org.bouncycastle.jce.interfaces.IESKey; import org.bouncycastle.jce.spec.IESParameterSpec; public class CipherSpi extends javax.crypto.CipherSpi { private IESEngine cipher; private int state = -1; private ByteArrayOutputStream buffer = new ByteArrayOutputStream(); private AlgorithmParameters engineParam = null; private IESParameterSpec engineParams = null; // // specs we can handle. // private Class[] availableSpecs = { IESParameterSpec.class }; public CipherSpi( IESEngine engine) { cipher = engine; } protected int engineGetBlockSize() { return 0; } protected byte[] engineGetIV() { return null; } protected int engineGetKeySize( Key key) { if (!(key instanceof IESKey)) { throw new IllegalArgumentException("must be passed IE key"); } IESKey ieKey = (IESKey)key; if (ieKey.getPrivate() instanceof DHPrivateKey) { DHPrivateKey k = (DHPrivateKey)ieKey.getPrivate(); return k.getX().bitLength(); } else if (ieKey.getPrivate() instanceof ECPrivateKey) { ECPrivateKey k = (ECPrivateKey)ieKey.getPrivate(); return k.getD().bitLength(); } throw new IllegalArgumentException("not an IE key!"); } protected int engineGetOutputSize( int inputLen) { if (state == Cipher.ENCRYPT_MODE || state == Cipher.WRAP_MODE) { return buffer.size() + inputLen + 20; /* SHA1 MAC size */ } else if (state == Cipher.DECRYPT_MODE || state == Cipher.UNWRAP_MODE) { return buffer.size() + inputLen - 20; } else { throw new IllegalStateException("cipher not initialised"); } } protected AlgorithmParameters engineGetParameters() { if (engineParam == null) { if (engineParams != null) { String name = "IES"; try { engineParam = AlgorithmParameters.getInstance(name, BouncyCastleProvider.PROVIDER_NAME); engineParam.init(engineParams); } catch (Exception e) { throw new RuntimeException(e.toString()); } } } return engineParam; } protected void engineSetMode( String mode) { throw new IllegalArgumentException("can't support mode " + mode); } protected void engineSetPadding( String padding) throws NoSuchPaddingException { throw new NoSuchPaddingException(padding + " unavailable with RSA."); } protected void engineInit( int opmode, Key key, AlgorithmParameterSpec params, SecureRandom random) throws InvalidKeyException, InvalidAlgorithmParameterException { if (!(key instanceof IESKey)) { throw new InvalidKeyException("must be passed IES key"); } if (params == null && (opmode == Cipher.ENCRYPT_MODE || opmode == Cipher.WRAP_MODE)) { // // if nothing is specified we set up for a 128 bit mac, with // 128 bit derivation vectors. // byte[] d = new byte[16]; byte[] e = new byte[16]; if (random == null) { random = new SecureRandom(); } random.nextBytes(d); random.nextBytes(e); params = new IESParameterSpec(d, e, 128); } else if (!(params instanceof IESParameterSpec)) { throw new InvalidAlgorithmParameterException("must be passed IES parameters"); } IESKey ieKey = (IESKey)key; CipherParameters pubKey; CipherParameters privKey; if (ieKey.getPublic() instanceof ECPublicKey) { pubKey = ECUtil.generatePublicKeyParameter(ieKey.getPublic()); privKey = ECUtil.generatePrivateKeyParameter(ieKey.getPrivate()); } else { pubKey = DHUtil.generatePublicKeyParameter(ieKey.getPublic()); privKey = DHUtil.generatePrivateKeyParameter(ieKey.getPrivate()); } this.engineParams = (IESParameterSpec)params; IESParameters p = new IESParameters(engineParams.getDerivationV(), engineParams.getEncodingV(), engineParams.getMacKeySize()); this.state = opmode; buffer.reset(); switch (opmode) { case Cipher.ENCRYPT_MODE: case Cipher.WRAP_MODE: cipher.init(true, privKey, pubKey, p); break; case Cipher.DECRYPT_MODE: case Cipher.UNWRAP_MODE: cipher.init(false, privKey, pubKey, p); break; default: System.out.println("eeek!"); } } protected void engineInit( int opmode, Key key, AlgorithmParameters params, SecureRandom random) throws InvalidKeyException, InvalidAlgorithmParameterException { AlgorithmParameterSpec paramSpec = null; if (params != null) { for (int i = 0; i != availableSpecs.length; i++) { try { paramSpec = params.getParameterSpec(availableSpecs[i]); break; } catch (Exception e) { continue; } } if (paramSpec == null) { throw new InvalidAlgorithmParameterException("can't handle parameter " + params.toString()); } } engineParam = params; engineInit(opmode, key, paramSpec, random); } protected void engineInit( int opmode, Key key, SecureRandom random) throws InvalidKeyException { if (opmode == Cipher.ENCRYPT_MODE || opmode == Cipher.WRAP_MODE) { try { engineInit(opmode, key, (AlgorithmParameterSpec)null, random); return; } catch (InvalidAlgorithmParameterException e) { // fall through... } } throw new IllegalArgumentException("can't handle null parameter spec in IES"); } protected byte[] engineUpdate( byte[] input, int inputOffset, int inputLen) { buffer.write(input, inputOffset, inputLen); return null; } protected int engineUpdate( byte[] input, int inputOffset, int inputLen, byte[] output, int outputOffset) { buffer.write(input, inputOffset, inputLen); return 0; } protected byte[] engineDoFinal( byte[] input, int inputOffset, int inputLen) throws IllegalBlockSizeException, BadPaddingException { if (inputLen != 0) { buffer.write(input, inputOffset, inputLen); } try { byte[] buf = buffer.toByteArray(); buffer.reset(); return cipher.processBlock(buf, 0, buf.length); } catch (InvalidCipherTextException e) { throw new BadPaddingException(e.getMessage()); } } protected int engineDoFinal( byte[] input, int inputOffset, int inputLen, byte[] output, int outputOffset) throws IllegalBlockSizeException, BadPaddingException { if (inputLen != 0) { buffer.write(input, inputOffset, inputLen); } try { byte[] buf = buffer.toByteArray(); buffer.reset(); buf = cipher.processBlock(buf, 0, buf.length); System.arraycopy(buf, 0, output, outputOffset, buf.length); return buf.length; } catch (InvalidCipherTextException e) { throw new BadPaddingException(e.getMessage()); } } static public class IES extends CipherSpi { public IES() { super(new IESEngine( new DHBasicAgreement(), new KDF2BytesGenerator(new SHA1Digest()), new HMac(new SHA1Digest()))); } } } bouncycastle-1.49.orig/src/org/bouncycastle/jcajce/provider/asymmetric/DSTU4145.java0000644000175000017500000000407312151251423027670 0ustar ebourgebourgpackage org.bouncycastle.jcajce.provider.asymmetric; import org.bouncycastle.asn1.ua.UAObjectIdentifiers; import org.bouncycastle.jcajce.provider.asymmetric.dstu.KeyFactorySpi; import org.bouncycastle.jcajce.provider.config.ConfigurableProvider; import org.bouncycastle.jcajce.provider.util.AsymmetricAlgorithmProvider; public class DSTU4145 { private static final String PREFIX = "org.bouncycastle.jcajce.provider.asymmetric" + ".dstu."; public static class Mappings extends AsymmetricAlgorithmProvider { public Mappings() { } public void configure(ConfigurableProvider provider) { provider.addAlgorithm("KeyFactory.DSTU4145", PREFIX + "KeyFactorySpi"); provider.addAlgorithm("Alg.Alias.KeyFactory.DSTU-4145-2002", "DSTU4145"); provider.addAlgorithm("Alg.Alias.KeyFactory.DSTU4145-3410", "DSTU4145"); registerOid(provider, UAObjectIdentifiers.dstu4145le, "DSTU4145", new KeyFactorySpi()); registerOidAlgorithmParameters(provider, UAObjectIdentifiers.dstu4145le, "DSTU4145"); registerOid(provider, UAObjectIdentifiers.dstu4145be, "DSTU4145", new KeyFactorySpi()); registerOidAlgorithmParameters(provider, UAObjectIdentifiers.dstu4145be, "DSTU4145"); provider.addAlgorithm("KeyPairGenerator.DSTU4145", PREFIX + "KeyPairGeneratorSpi"); provider.addAlgorithm("Alg.Alias.KeyPairGenerator.DSTU-4145", "DSTU4145"); provider.addAlgorithm("Alg.Alias.KeyPairGenerator.DSTU-4145-2002", "DSTU4145"); provider.addAlgorithm("Signature.DSTU4145", PREFIX + "SignatureSpi"); provider.addAlgorithm("Alg.Alias.Signature.DSTU-4145", "DSTU4145"); provider.addAlgorithm("Alg.Alias.Signature.DSTU-4145-2002", "DSTU4145"); addSignatureAlgorithm(provider, "GOST3411", "DSTU4145LE", PREFIX + "SignatureSpiLe", UAObjectIdentifiers.dstu4145le); addSignatureAlgorithm(provider, "GOST3411", "DSTU4145", PREFIX + "SignatureSpi", UAObjectIdentifiers.dstu4145be); } } } bouncycastle-1.49.orig/src/org/bouncycastle/jcajce/provider/asymmetric/ElGamal.java0000644000175000017500000000450211705660264030105 0ustar ebourgebourgpackage org.bouncycastle.jcajce.provider.asymmetric; import org.bouncycastle.asn1.oiw.OIWObjectIdentifiers; import org.bouncycastle.jcajce.provider.asymmetric.elgamal.KeyFactorySpi; import org.bouncycastle.jcajce.provider.config.ConfigurableProvider; import org.bouncycastle.jcajce.provider.util.AsymmetricAlgorithmProvider; import org.bouncycastle.jcajce.provider.util.AsymmetricKeyInfoConverter; public class ElGamal { private static final String PREFIX = "org.bouncycastle.jcajce.provider.asymmetric" + ".elgamal."; public static class Mappings extends AsymmetricAlgorithmProvider { public Mappings() { } public void configure(ConfigurableProvider provider) { provider.addAlgorithm("AlgorithmParameterGenerator.ELGAMAL", PREFIX + "AlgorithmParameterGeneratorSpi"); provider.addAlgorithm("AlgorithmParameterGenerator.ElGamal", PREFIX + "AlgorithmParameterGeneratorSpi"); provider.addAlgorithm("AlgorithmParameters.ELGAMAL", PREFIX + "AlgorithmParametersSpi"); provider.addAlgorithm("AlgorithmParameters.ElGamal", PREFIX + "AlgorithmParametersSpi"); provider.addAlgorithm("Cipher.ELGAMAL", PREFIX + "CipherSpi$NoPadding"); provider.addAlgorithm("Cipher.ElGamal", PREFIX + "CipherSpi$NoPadding"); provider.addAlgorithm("Alg.Alias.Cipher.ELGAMAL/ECB/PKCS1PADDING", "ELGAMAL/PKCS1"); provider.addAlgorithm("Alg.Alias.Cipher.ELGAMAL/NONE/PKCS1PADDING", "ELGAMAL/PKCS1"); provider.addAlgorithm("Alg.Alias.Cipher.ELGAMAL/NONE/NOPADDING", "ELGAMAL"); provider.addAlgorithm("Cipher.ELGAMAL/PKCS1", PREFIX + "CipherSpi$PKCS1v1_5Padding"); provider.addAlgorithm("KeyFactory.ELGAMAL", PREFIX + "KeyFactorySpi"); provider.addAlgorithm("KeyFactory.ElGamal", PREFIX + "KeyFactorySpi"); provider.addAlgorithm("KeyPairGenerator.ELGAMAL", PREFIX + "KeyPairGeneratorSpi"); provider.addAlgorithm("KeyPairGenerator.ElGamal", PREFIX + "KeyPairGeneratorSpi"); AsymmetricKeyInfoConverter keyFact = new KeyFactorySpi(); registerOid(provider, OIWObjectIdentifiers.elGamalAlgorithm, "ELGAMAL", keyFact); registerOidAlgorithmParameters(provider, OIWObjectIdentifiers.elGamalAlgorithm, "ELGAMAL"); } } } bouncycastle-1.49.orig/src/org/bouncycastle/jcajce/provider/asymmetric/GOST.java0000644000175000017500000000466511705435502027364 0ustar ebourgebourgpackage org.bouncycastle.jcajce.provider.asymmetric; import org.bouncycastle.asn1.cryptopro.CryptoProObjectIdentifiers; import org.bouncycastle.jcajce.provider.asymmetric.gost.KeyFactorySpi; import org.bouncycastle.jcajce.provider.config.ConfigurableProvider; import org.bouncycastle.jcajce.provider.util.AsymmetricAlgorithmProvider; public class GOST { private static final String PREFIX = "org.bouncycastle.jcajce.provider.asymmetric" + ".gost."; public static class Mappings extends AsymmetricAlgorithmProvider { public Mappings() { } public void configure(ConfigurableProvider provider) { provider.addAlgorithm("KeyPairGenerator.GOST3410", PREFIX + "KeyPairGeneratorSpi"); provider.addAlgorithm("Alg.Alias.KeyPairGenerator.GOST-3410", "GOST3410"); provider.addAlgorithm("Alg.Alias.KeyPairGenerator.GOST-3410-94", "GOST3410"); provider.addAlgorithm("KeyFactory.GOST3410", PREFIX + "KeyFactorySpi"); provider.addAlgorithm("Alg.Alias.KeyFactory.GOST-3410", "GOST3410"); provider.addAlgorithm("Alg.Alias.KeyFactory.GOST-3410-94", "GOST3410"); provider.addAlgorithm("AlgorithmParameters.GOST3410", PREFIX + "AlgorithmParametersSpi"); provider.addAlgorithm("AlgorithmParameterGenerator.GOST3410", PREFIX + "AlgorithmParameterGeneratorSpi"); registerOid(provider, CryptoProObjectIdentifiers.gostR3410_94, "GOST3410", new KeyFactorySpi()); registerOidAlgorithmParameters(provider, CryptoProObjectIdentifiers.gostR3410_94, "GOST3410"); provider.addAlgorithm("Signature.GOST3410", PREFIX + "SignatureSpi"); provider.addAlgorithm("Alg.Alias.Signature.GOST-3410", "GOST3410"); provider.addAlgorithm("Alg.Alias.Signature.GOST-3410-94", "GOST3410"); provider.addAlgorithm("Alg.Alias.Signature.GOST3411withGOST3410", "GOST3410"); provider.addAlgorithm("Alg.Alias.Signature.GOST3411WITHGOST3410", "GOST3410"); provider.addAlgorithm("Alg.Alias.Signature.GOST3411WithGOST3410", "GOST3410"); provider.addAlgorithm("Alg.Alias.Signature." + CryptoProObjectIdentifiers.gostR3411_94_with_gostR3410_94, "GOST3410"); provider.addAlgorithm("Alg.Alias.AlgorithmParameterGenerator.GOST-3410", "GOST3410"); provider.addAlgorithm("Alg.Alias.AlgorithmParameters.GOST-3410", "GOST3410"); } } } bouncycastle-1.49.orig/src/org/bouncycastle/jcajce/provider/keystore/0000755000175000017500000000000012152033551025415 5ustar ebourgebourgbouncycastle-1.49.orig/src/org/bouncycastle/jcajce/provider/keystore/PKCS12.java0000644000175000017500000000245512107336317027177 0ustar ebourgebourgpackage org.bouncycastle.jcajce.provider.keystore; import org.bouncycastle.jcajce.provider.config.ConfigurableProvider; import org.bouncycastle.jcajce.provider.util.AsymmetricAlgorithmProvider; public class PKCS12 { private static final String PREFIX = "org.bouncycastle.jcajce.provider.keystore" + ".pkcs12."; public static class Mappings extends AsymmetricAlgorithmProvider { public Mappings() { } public void configure(ConfigurableProvider provider) { provider.addAlgorithm("KeyStore.PKCS12", PREFIX + "PKCS12KeyStoreSpi$BCPKCS12KeyStore"); provider.addAlgorithm("KeyStore.BCPKCS12", PREFIX + "PKCS12KeyStoreSpi$BCPKCS12KeyStore"); provider.addAlgorithm("KeyStore.PKCS12-DEF", PREFIX + "PKCS12KeyStoreSpi$DefPKCS12KeyStore"); provider.addAlgorithm("KeyStore.PKCS12-3DES-40RC2", PREFIX + "PKCS12KeyStoreSpi$BCPKCS12KeyStore"); provider.addAlgorithm("KeyStore.PKCS12-3DES-3DES", PREFIX + "PKCS12KeyStoreSpi$BCPKCS12KeyStore3DES"); provider.addAlgorithm("KeyStore.PKCS12-DEF-3DES-40RC2", PREFIX + "PKCS12KeyStoreSpi$DefPKCS12KeyStore"); provider.addAlgorithm("KeyStore.PKCS12-DEF-3DES-3DES", PREFIX + "PKCS12KeyStoreSpi$DefPKCS12KeyStore3DES"); } } } bouncycastle-1.49.orig/src/org/bouncycastle/jcajce/provider/keystore/bc/0000755000175000017500000000000012152033551026001 5ustar ebourgebourgbouncycastle-1.49.orig/src/org/bouncycastle/jcajce/provider/keystore/bc/BcKeyStoreSpi.java0000644000175000017500000007350612115720207031345 0ustar ebourgebourgpackage org.bouncycastle.jcajce.provider.keystore.bc; import java.io.ByteArrayInputStream; import java.io.ByteArrayOutputStream; import java.io.DataInputStream; import java.io.DataOutputStream; import java.io.IOException; import java.io.InputStream; import java.io.OutputStream; import java.security.Key; import java.security.KeyFactory; import java.security.KeyStoreException; import java.security.KeyStoreSpi; import java.security.NoSuchAlgorithmException; import java.security.NoSuchProviderException; import java.security.PrivateKey; import java.security.PublicKey; import java.security.SecureRandom; import java.security.UnrecoverableKeyException; import java.security.cert.Certificate; import java.security.cert.CertificateEncodingException; import java.security.cert.CertificateException; import java.security.cert.CertificateFactory; import java.security.spec.KeySpec; import java.security.spec.PKCS8EncodedKeySpec; import java.security.spec.X509EncodedKeySpec; import java.util.Date; import java.util.Enumeration; import java.util.Hashtable; import javax.crypto.Cipher; import javax.crypto.CipherInputStream; import javax.crypto.CipherOutputStream; import javax.crypto.SecretKeyFactory; import javax.crypto.spec.PBEKeySpec; import javax.crypto.spec.PBEParameterSpec; import javax.crypto.spec.SecretKeySpec; import org.bouncycastle.crypto.CipherParameters; import org.bouncycastle.crypto.Digest; import org.bouncycastle.crypto.PBEParametersGenerator; import org.bouncycastle.crypto.digests.SHA1Digest; import org.bouncycastle.crypto.generators.PKCS12ParametersGenerator; import org.bouncycastle.crypto.io.DigestInputStream; import org.bouncycastle.crypto.io.DigestOutputStream; import org.bouncycastle.crypto.io.MacInputStream; import org.bouncycastle.crypto.io.MacOutputStream; import org.bouncycastle.crypto.macs.HMac; import org.bouncycastle.jce.interfaces.BCKeyStore; import org.bouncycastle.jce.provider.BouncyCastleProvider; import org.bouncycastle.util.Arrays; import org.bouncycastle.util.io.Streams; import org.bouncycastle.util.io.TeeOutputStream; public class BcKeyStoreSpi extends KeyStoreSpi implements BCKeyStore { private static final int STORE_VERSION = 2; private static final int STORE_SALT_SIZE = 20; private static final String STORE_CIPHER = "PBEWithSHAAndTwofish-CBC"; private static final int KEY_SALT_SIZE = 20; private static final int MIN_ITERATIONS = 1024; private static final String KEY_CIPHER = "PBEWithSHAAnd3-KeyTripleDES-CBC"; // // generic object types // static final int NULL = 0; static final int CERTIFICATE = 1; static final int KEY = 2; static final int SECRET = 3; static final int SEALED = 4; // // key types // static final int KEY_PRIVATE = 0; static final int KEY_PUBLIC = 1; static final int KEY_SECRET = 2; protected Hashtable table = new Hashtable(); protected SecureRandom random = new SecureRandom(); protected int version; public BcKeyStoreSpi(int version) { this.version = version; } private class StoreEntry { int type; String alias; Object obj; Certificate[] certChain; Date date = new Date(); StoreEntry( String alias, Certificate obj) { this.type = CERTIFICATE; this.alias = alias; this.obj = obj; this.certChain = null; } StoreEntry( String alias, byte[] obj, Certificate[] certChain) { this.type = SECRET; this.alias = alias; this.obj = obj; this.certChain = certChain; } StoreEntry( String alias, Key key, char[] password, Certificate[] certChain) throws Exception { this.type = SEALED; this.alias = alias; this.certChain = certChain; byte[] salt = new byte[KEY_SALT_SIZE]; random.setSeed(System.currentTimeMillis()); random.nextBytes(salt); int iterationCount = MIN_ITERATIONS + (random.nextInt() & 0x3ff); ByteArrayOutputStream bOut = new ByteArrayOutputStream(); DataOutputStream dOut = new DataOutputStream(bOut); dOut.writeInt(salt.length); dOut.write(salt); dOut.writeInt(iterationCount); Cipher cipher = makePBECipher(KEY_CIPHER, Cipher.ENCRYPT_MODE, password, salt, iterationCount); CipherOutputStream cOut = new CipherOutputStream(dOut, cipher); dOut = new DataOutputStream(cOut); encodeKey(key, dOut); dOut.close(); obj = bOut.toByteArray(); } StoreEntry( String alias, Date date, int type, Object obj) { this.alias = alias; this.date = date; this.type = type; this.obj = obj; } StoreEntry( String alias, Date date, int type, Object obj, Certificate[] certChain) { this.alias = alias; this.date = date; this.type = type; this.obj = obj; this.certChain = certChain; } int getType() { return type; } String getAlias() { return alias; } Object getObject() { return obj; } Object getObject( char[] password) throws NoSuchAlgorithmException, UnrecoverableKeyException { if (password == null || password.length == 0) { if (obj instanceof Key) { return obj; } } if (type == SEALED) { ByteArrayInputStream bIn = new ByteArrayInputStream((byte[])obj); DataInputStream dIn = new DataInputStream(bIn); try { byte[] salt = new byte[dIn.readInt()]; dIn.readFully(salt); int iterationCount = dIn.readInt(); Cipher cipher = makePBECipher(KEY_CIPHER, Cipher.DECRYPT_MODE, password, salt, iterationCount); CipherInputStream cIn = new CipherInputStream(dIn, cipher); try { return decodeKey(new DataInputStream(cIn)); } catch (Exception x) { bIn = new ByteArrayInputStream((byte[])obj); dIn = new DataInputStream(bIn); salt = new byte[dIn.readInt()]; dIn.readFully(salt); iterationCount = dIn.readInt(); cipher = makePBECipher("Broken" + KEY_CIPHER, Cipher.DECRYPT_MODE, password, salt, iterationCount); cIn = new CipherInputStream(dIn, cipher); Key k = null; try { k = decodeKey(new DataInputStream(cIn)); } catch (Exception y) { bIn = new ByteArrayInputStream((byte[])obj); dIn = new DataInputStream(bIn); salt = new byte[dIn.readInt()]; dIn.readFully(salt); iterationCount = dIn.readInt(); cipher = makePBECipher("Old" + KEY_CIPHER, Cipher.DECRYPT_MODE, password, salt, iterationCount); cIn = new CipherInputStream(dIn, cipher); k = decodeKey(new DataInputStream(cIn)); } // // reencrypt key with correct cipher. // if (k != null) { ByteArrayOutputStream bOut = new ByteArrayOutputStream(); DataOutputStream dOut = new DataOutputStream(bOut); dOut.writeInt(salt.length); dOut.write(salt); dOut.writeInt(iterationCount); Cipher out = makePBECipher(KEY_CIPHER, Cipher.ENCRYPT_MODE, password, salt, iterationCount); CipherOutputStream cOut = new CipherOutputStream(dOut, out); dOut = new DataOutputStream(cOut); encodeKey(k, dOut); dOut.close(); obj = bOut.toByteArray(); return k; } else { throw new UnrecoverableKeyException("no match"); } } } catch (Exception e) { throw new UnrecoverableKeyException("no match"); } } else { throw new RuntimeException("forget something!"); // TODO // if we get to here key was saved as byte data, which // according to the docs means it must be a private key // in EncryptedPrivateKeyInfo (PKCS8 format), later... // } } Certificate[] getCertificateChain() { return certChain; } Date getDate() { return date; } } private void encodeCertificate( Certificate cert, DataOutputStream dOut) throws IOException { try { byte[] cEnc = cert.getEncoded(); dOut.writeUTF(cert.getType()); dOut.writeInt(cEnc.length); dOut.write(cEnc); } catch (CertificateEncodingException ex) { throw new IOException(ex.toString()); } } private Certificate decodeCertificate( DataInputStream dIn) throws IOException { String type = dIn.readUTF(); byte[] cEnc = new byte[dIn.readInt()]; dIn.readFully(cEnc); try { CertificateFactory cFact = CertificateFactory.getInstance(type, BouncyCastleProvider.PROVIDER_NAME); ByteArrayInputStream bIn = new ByteArrayInputStream(cEnc); return cFact.generateCertificate(bIn); } catch (NoSuchProviderException ex) { throw new IOException(ex.toString()); } catch (CertificateException ex) { throw new IOException(ex.toString()); } } private void encodeKey( Key key, DataOutputStream dOut) throws IOException { byte[] enc = key.getEncoded(); if (key instanceof PrivateKey) { dOut.write(KEY_PRIVATE); } else if (key instanceof PublicKey) { dOut.write(KEY_PUBLIC); } else { dOut.write(KEY_SECRET); } dOut.writeUTF(key.getFormat()); dOut.writeUTF(key.getAlgorithm()); dOut.writeInt(enc.length); dOut.write(enc); } private Key decodeKey( DataInputStream dIn) throws IOException { int keyType = dIn.read(); String format = dIn.readUTF(); String algorithm = dIn.readUTF(); byte[] enc = new byte[dIn.readInt()]; KeySpec spec; dIn.readFully(enc); if (format.equals("PKCS#8") || format.equals("PKCS8")) { spec = new PKCS8EncodedKeySpec(enc); } else if (format.equals("X.509") || format.equals("X509")) { spec = new X509EncodedKeySpec(enc); } else if (format.equals("RAW")) { return new SecretKeySpec(enc, algorithm); } else { throw new IOException("Key format " + format + " not recognised!"); } try { switch (keyType) { case KEY_PRIVATE: return KeyFactory.getInstance(algorithm, BouncyCastleProvider.PROVIDER_NAME).generatePrivate(spec); case KEY_PUBLIC: return KeyFactory.getInstance(algorithm, BouncyCastleProvider.PROVIDER_NAME).generatePublic(spec); case KEY_SECRET: return SecretKeyFactory.getInstance(algorithm, BouncyCastleProvider.PROVIDER_NAME).generateSecret(spec); default: throw new IOException("Key type " + keyType + " not recognised!"); } } catch (Exception e) { throw new IOException("Exception creating key: " + e.toString()); } } protected Cipher makePBECipher( String algorithm, int mode, char[] password, byte[] salt, int iterationCount) throws IOException { try { PBEKeySpec pbeSpec = new PBEKeySpec(password); SecretKeyFactory keyFact = SecretKeyFactory.getInstance(algorithm, BouncyCastleProvider.PROVIDER_NAME); PBEParameterSpec defParams = new PBEParameterSpec(salt, iterationCount); Cipher cipher = Cipher.getInstance(algorithm, BouncyCastleProvider.PROVIDER_NAME); cipher.init(mode, keyFact.generateSecret(pbeSpec), defParams); return cipher; } catch (Exception e) { throw new IOException("Error initialising store of key store: " + e); } } public void setRandom( SecureRandom rand) { this.random = rand; } public Enumeration engineAliases() { return table.keys(); } public boolean engineContainsAlias( String alias) { return (table.get(alias) != null); } public void engineDeleteEntry( String alias) throws KeyStoreException { Object entry = table.get(alias); if (entry == null) { return; } table.remove(alias); } public Certificate engineGetCertificate( String alias) { StoreEntry entry = (StoreEntry)table.get(alias); if (entry != null) { if (entry.getType() == CERTIFICATE) { return (Certificate)entry.getObject(); } else { Certificate[] chain = entry.getCertificateChain(); if (chain != null) { return chain[0]; } } } return null; } public String engineGetCertificateAlias( Certificate cert) { Enumeration e = table.elements(); while (e.hasMoreElements()) { StoreEntry entry = (StoreEntry)e.nextElement(); if (entry.getObject() instanceof Certificate) { Certificate c = (Certificate)entry.getObject(); if (c.equals(cert)) { return entry.getAlias(); } } else { Certificate[] chain = entry.getCertificateChain(); if (chain != null && chain[0].equals(cert)) { return entry.getAlias(); } } } return null; } public Certificate[] engineGetCertificateChain( String alias) { StoreEntry entry = (StoreEntry)table.get(alias); if (entry != null) { return entry.getCertificateChain(); } return null; } public Date engineGetCreationDate(String alias) { StoreEntry entry = (StoreEntry)table.get(alias); if (entry != null) { return entry.getDate(); } return null; } public Key engineGetKey( String alias, char[] password) throws NoSuchAlgorithmException, UnrecoverableKeyException { StoreEntry entry = (StoreEntry)table.get(alias); if (entry == null || entry.getType() == CERTIFICATE) { return null; } return (Key)entry.getObject(password); } public boolean engineIsCertificateEntry( String alias) { StoreEntry entry = (StoreEntry)table.get(alias); if (entry != null && entry.getType() == CERTIFICATE) { return true; } return false; } public boolean engineIsKeyEntry( String alias) { StoreEntry entry = (StoreEntry)table.get(alias); if (entry != null && entry.getType() != CERTIFICATE) { return true; } return false; } public void engineSetCertificateEntry( String alias, Certificate cert) throws KeyStoreException { StoreEntry entry = (StoreEntry)table.get(alias); if (entry != null && entry.getType() != CERTIFICATE) { throw new KeyStoreException("key store already has a key entry with alias " + alias); } table.put(alias, new StoreEntry(alias, cert)); } public void engineSetKeyEntry( String alias, byte[] key, Certificate[] chain) throws KeyStoreException { table.put(alias, new StoreEntry(alias, key, chain)); } public void engineSetKeyEntry( String alias, Key key, char[] password, Certificate[] chain) throws KeyStoreException { if ((key instanceof PrivateKey) && (chain == null)) { throw new KeyStoreException("no certificate chain for private key"); } try { table.put(alias, new StoreEntry(alias, key, password, chain)); } catch (Exception e) { throw new KeyStoreException(e.toString()); } } public int engineSize() { return table.size(); } protected void loadStore( InputStream in) throws IOException { DataInputStream dIn = new DataInputStream(in); int type = dIn.read(); while (type > NULL) { String alias = dIn.readUTF(); Date date = new Date(dIn.readLong()); int chainLength = dIn.readInt(); Certificate[] chain = null; if (chainLength != 0) { chain = new Certificate[chainLength]; for (int i = 0; i != chainLength; i++) { chain[i] = decodeCertificate(dIn); } } switch (type) { case CERTIFICATE: Certificate cert = decodeCertificate(dIn); table.put(alias, new StoreEntry(alias, date, CERTIFICATE, cert)); break; case KEY: Key key = decodeKey(dIn); table.put(alias, new StoreEntry(alias, date, KEY, key, chain)); break; case SECRET: case SEALED: byte[] b = new byte[dIn.readInt()]; dIn.readFully(b); table.put(alias, new StoreEntry(alias, date, type, b, chain)); break; default: throw new RuntimeException("Unknown object type in store."); } type = dIn.read(); } } protected void saveStore( OutputStream out) throws IOException { Enumeration e = table.elements(); DataOutputStream dOut = new DataOutputStream(out); while (e.hasMoreElements()) { StoreEntry entry = (StoreEntry)e.nextElement(); dOut.write(entry.getType()); dOut.writeUTF(entry.getAlias()); dOut.writeLong(entry.getDate().getTime()); Certificate[] chain = entry.getCertificateChain(); if (chain == null) { dOut.writeInt(0); } else { dOut.writeInt(chain.length); for (int i = 0; i != chain.length; i++) { encodeCertificate(chain[i], dOut); } } switch (entry.getType()) { case CERTIFICATE: encodeCertificate((Certificate)entry.getObject(), dOut); break; case KEY: encodeKey((Key)entry.getObject(), dOut); break; case SEALED: case SECRET: byte[] b = (byte[])entry.getObject(); dOut.writeInt(b.length); dOut.write(b); break; default: throw new RuntimeException("Unknown object type in store."); } } dOut.write(NULL); } public void engineLoad( InputStream stream, char[] password) throws IOException { table.clear(); if (stream == null) // just initialising { return; } DataInputStream dIn = new DataInputStream(stream); int version = dIn.readInt(); if (version != STORE_VERSION) { if (version != 0 && version != 1) { throw new IOException("Wrong version of key store."); } } int saltLength = dIn.readInt(); if (saltLength <= 0) { throw new IOException("Invalid salt detected"); } byte[] salt = new byte[saltLength]; dIn.readFully(salt); int iterationCount = dIn.readInt(); // // we only do an integrity check if the password is provided. // HMac hMac = new HMac(new SHA1Digest()); if (password != null && password.length != 0) { byte[] passKey = PBEParametersGenerator.PKCS12PasswordToBytes(password); PBEParametersGenerator pbeGen = new PKCS12ParametersGenerator(new SHA1Digest()); pbeGen.init(passKey, salt, iterationCount); CipherParameters macParams; if (version != 2) { macParams = pbeGen.generateDerivedMacParameters(hMac.getMacSize()); } else { macParams = pbeGen.generateDerivedMacParameters(hMac.getMacSize() * 8); } Arrays.fill(passKey, (byte)0); hMac.init(macParams); MacInputStream mIn = new MacInputStream(dIn, hMac); loadStore(mIn); // Finalise our mac calculation byte[] mac = new byte[hMac.getMacSize()]; hMac.doFinal(mac, 0); // TODO Should this actually be reading the remainder of the stream? // Read the original mac from the stream byte[] oldMac = new byte[hMac.getMacSize()]; dIn.readFully(oldMac); if (!Arrays.constantTimeAreEqual(mac, oldMac)) { table.clear(); throw new IOException("KeyStore integrity check failed."); } } else { loadStore(dIn); // TODO Should this actually be reading the remainder of the stream? // Parse the original mac from the stream too byte[] oldMac = new byte[hMac.getMacSize()]; dIn.readFully(oldMac); } } public void engineStore(OutputStream stream, char[] password) throws IOException { DataOutputStream dOut = new DataOutputStream(stream); byte[] salt = new byte[STORE_SALT_SIZE]; int iterationCount = MIN_ITERATIONS + (random.nextInt() & 0x3ff); random.nextBytes(salt); dOut.writeInt(version); dOut.writeInt(salt.length); dOut.write(salt); dOut.writeInt(iterationCount); HMac hMac = new HMac(new SHA1Digest()); MacOutputStream mOut = new MacOutputStream(hMac); PBEParametersGenerator pbeGen = new PKCS12ParametersGenerator(new SHA1Digest()); byte[] passKey = PBEParametersGenerator.PKCS12PasswordToBytes(password); pbeGen.init(passKey, salt, iterationCount); if (version < 2) { hMac.init(pbeGen.generateDerivedMacParameters(hMac.getMacSize())); } else { hMac.init(pbeGen.generateDerivedMacParameters(hMac.getMacSize() * 8)); } for (int i = 0; i != passKey.length; i++) { passKey[i] = 0; } saveStore(new TeeOutputStream(dOut, mOut)); byte[] mac = new byte[hMac.getMacSize()]; hMac.doFinal(mac, 0); dOut.write(mac); dOut.close(); } /** * the BouncyCastle store. This wont work with the key tool as the * store is stored encrypted on disk, so the password is mandatory, * however if you hard drive is in a bad part of town and you absolutely, * positively, don't want nobody peeking at your things, this is the * one to use, no problem! After all in a Bouncy Castle nothing can * touch you. * * Also referred to by the alias UBER. */ public static class BouncyCastleStore extends BcKeyStoreSpi { public BouncyCastleStore() { super(1); } public void engineLoad( InputStream stream, char[] password) throws IOException { table.clear(); if (stream == null) // just initialising { return; } DataInputStream dIn = new DataInputStream(stream); int version = dIn.readInt(); if (version != STORE_VERSION) { if (version != 0 && version != 1) { throw new IOException("Wrong version of key store."); } } byte[] salt = new byte[dIn.readInt()]; if (salt.length != STORE_SALT_SIZE) { throw new IOException("Key store corrupted."); } dIn.readFully(salt); int iterationCount = dIn.readInt(); if ((iterationCount < 0) || (iterationCount > 4 * MIN_ITERATIONS)) { throw new IOException("Key store corrupted."); } String cipherAlg; if (version == 0) { cipherAlg = "Old" + STORE_CIPHER; } else { cipherAlg = STORE_CIPHER; } Cipher cipher = this.makePBECipher(cipherAlg, Cipher.DECRYPT_MODE, password, salt, iterationCount); CipherInputStream cIn = new CipherInputStream(dIn, cipher); Digest dig = new SHA1Digest(); DigestInputStream dgIn = new DigestInputStream(cIn, dig); this.loadStore(dgIn); // Finalise our digest calculation byte[] hash = new byte[dig.getDigestSize()]; dig.doFinal(hash, 0); // TODO Should this actually be reading the remainder of the stream? // Read the original digest from the stream byte[] oldHash = new byte[dig.getDigestSize()]; Streams.readFully(cIn, oldHash); if (!Arrays.constantTimeAreEqual(hash, oldHash)) { table.clear(); throw new IOException("KeyStore integrity check failed."); } } public void engineStore(OutputStream stream, char[] password) throws IOException { Cipher cipher; DataOutputStream dOut = new DataOutputStream(stream); byte[] salt = new byte[STORE_SALT_SIZE]; int iterationCount = MIN_ITERATIONS + (random.nextInt() & 0x3ff); random.nextBytes(salt); dOut.writeInt(version); dOut.writeInt(salt.length); dOut.write(salt); dOut.writeInt(iterationCount); cipher = this.makePBECipher(STORE_CIPHER, Cipher.ENCRYPT_MODE, password, salt, iterationCount); CipherOutputStream cOut = new CipherOutputStream(dOut, cipher); DigestOutputStream dgOut = new DigestOutputStream(new SHA1Digest()); this.saveStore(new TeeOutputStream(cOut, dgOut)); byte[] dig = dgOut.getDigest(); cOut.write(dig); cOut.close(); } } public static class Std extends BcKeyStoreSpi { public Std() { super(STORE_VERSION); } } public static class Version1 extends BcKeyStoreSpi { public Version1() { super(1); } } } bouncycastle-1.49.orig/src/org/bouncycastle/jcajce/provider/keystore/pkcs12/0000755000175000017500000000000012152033551026520 5ustar ebourgebourgbouncycastle-1.49.orig/src/org/bouncycastle/jcajce/provider/keystore/pkcs12/PKCS12KeyStoreSpi.java0000644000175000017500000016115712110324571032442 0ustar ebourgebourgpackage org.bouncycastle.jcajce.provider.keystore.pkcs12; import java.io.BufferedInputStream; import java.io.ByteArrayInputStream; import java.io.ByteArrayOutputStream; import java.io.IOException; import java.io.InputStream; import java.io.OutputStream; import java.security.Key; import java.security.KeyStore; import java.security.KeyStore.LoadStoreParameter; import java.security.KeyStore.ProtectionParameter; import java.security.KeyStoreException; import java.security.KeyStoreSpi; import java.security.NoSuchAlgorithmException; import java.security.Principal; import java.security.PrivateKey; import java.security.Provider; import java.security.PublicKey; import java.security.SecureRandom; import java.security.UnrecoverableKeyException; import java.security.cert.Certificate; import java.security.cert.CertificateEncodingException; import java.security.cert.CertificateException; import java.security.cert.CertificateFactory; import java.security.cert.X509Certificate; import java.util.Date; import java.util.Enumeration; import java.util.Hashtable; import java.util.Vector; import javax.crypto.Cipher; import javax.crypto.Mac; import javax.crypto.SecretKey; import javax.crypto.SecretKeyFactory; import javax.crypto.spec.IvParameterSpec; import javax.crypto.spec.PBEKeySpec; import javax.crypto.spec.PBEParameterSpec; import org.bouncycastle.asn1.ASN1Encodable; import org.bouncycastle.asn1.ASN1EncodableVector; import org.bouncycastle.asn1.ASN1Encoding; import org.bouncycastle.asn1.ASN1InputStream; import org.bouncycastle.asn1.ASN1ObjectIdentifier; import org.bouncycastle.asn1.ASN1OctetString; import org.bouncycastle.asn1.ASN1Primitive; import org.bouncycastle.asn1.ASN1Sequence; import org.bouncycastle.asn1.ASN1Set; import org.bouncycastle.asn1.BEROctetString; import org.bouncycastle.asn1.BEROutputStream; import org.bouncycastle.asn1.DERBMPString; import org.bouncycastle.asn1.DERNull; import org.bouncycastle.asn1.DEROctetString; import org.bouncycastle.asn1.DEROutputStream; import org.bouncycastle.asn1.DERSequence; import org.bouncycastle.asn1.DERSet; import org.bouncycastle.asn1.pkcs.AuthenticatedSafe; import org.bouncycastle.asn1.pkcs.CertBag; import org.bouncycastle.asn1.pkcs.ContentInfo; import org.bouncycastle.asn1.pkcs.EncryptedData; import org.bouncycastle.asn1.pkcs.MacData; import org.bouncycastle.asn1.pkcs.PBES2Parameters; import org.bouncycastle.asn1.pkcs.PBKDF2Params; import org.bouncycastle.asn1.pkcs.PKCS12PBEParams; import org.bouncycastle.asn1.pkcs.PKCSObjectIdentifiers; import org.bouncycastle.asn1.pkcs.Pfx; import org.bouncycastle.asn1.pkcs.SafeBag; import org.bouncycastle.asn1.util.ASN1Dump; import org.bouncycastle.asn1.x509.AlgorithmIdentifier; import org.bouncycastle.asn1.x509.AuthorityKeyIdentifier; import org.bouncycastle.asn1.x509.DigestInfo; import org.bouncycastle.asn1.x509.Extension; import org.bouncycastle.asn1.x509.SubjectKeyIdentifier; import org.bouncycastle.asn1.x509.SubjectPublicKeyInfo; import org.bouncycastle.asn1.x509.X509ObjectIdentifiers; import org.bouncycastle.jcajce.provider.config.PKCS12StoreParameter; import org.bouncycastle.jcajce.provider.symmetric.util.BCPBEKey; import org.bouncycastle.jcajce.provider.util.SecretKeyUtil; import org.bouncycastle.jce.interfaces.BCKeyStore; import org.bouncycastle.jce.interfaces.PKCS12BagAttributeCarrier; import org.bouncycastle.jce.provider.BouncyCastleProvider; import org.bouncycastle.jce.provider.JDKPKCS12StoreParameter; import org.bouncycastle.util.Arrays; import org.bouncycastle.util.Strings; import org.bouncycastle.util.encoders.Hex; public class PKCS12KeyStoreSpi extends KeyStoreSpi implements PKCSObjectIdentifiers, X509ObjectIdentifiers, BCKeyStore { private static final int SALT_SIZE = 20; private static final int MIN_ITERATIONS = 1024; private static final Provider bcProvider = new BouncyCastleProvider(); private IgnoresCaseHashtable keys = new IgnoresCaseHashtable(); private Hashtable localIds = new Hashtable(); private IgnoresCaseHashtable certs = new IgnoresCaseHashtable(); private Hashtable chainCerts = new Hashtable(); private Hashtable keyCerts = new Hashtable(); // // generic object types // static final int NULL = 0; static final int CERTIFICATE = 1; static final int KEY = 2; static final int SECRET = 3; static final int SEALED = 4; // // key types // static final int KEY_PRIVATE = 0; static final int KEY_PUBLIC = 1; static final int KEY_SECRET = 2; protected SecureRandom random = new SecureRandom(); // use of final causes problems with JDK 1.2 compiler private CertificateFactory certFact; private ASN1ObjectIdentifier keyAlgorithm; private ASN1ObjectIdentifier certAlgorithm; private class CertId { byte[] id; CertId( PublicKey key) { this.id = createSubjectKeyId(key).getKeyIdentifier(); } CertId( byte[] id) { this.id = id; } public int hashCode() { return Arrays.hashCode(id); } public boolean equals( Object o) { if (o == this) { return true; } if (!(o instanceof CertId)) { return false; } CertId cId = (CertId)o; return Arrays.areEqual(id, cId.id); } } public PKCS12KeyStoreSpi( Provider provider, ASN1ObjectIdentifier keyAlgorithm, ASN1ObjectIdentifier certAlgorithm) { this.keyAlgorithm = keyAlgorithm; this.certAlgorithm = certAlgorithm; try { if (provider != null) { certFact = CertificateFactory.getInstance("X.509", provider); } else { certFact = CertificateFactory.getInstance("X.509"); } } catch (Exception e) { throw new IllegalArgumentException("can't create cert factory - " + e.toString()); } } private SubjectKeyIdentifier createSubjectKeyId( PublicKey pubKey) { try { SubjectPublicKeyInfo info = new SubjectPublicKeyInfo( (ASN1Sequence)ASN1Primitive.fromByteArray(pubKey.getEncoded())); return new SubjectKeyIdentifier(info); } catch (Exception e) { throw new RuntimeException("error creating key"); } } public void setRandom( SecureRandom rand) { this.random = rand; } public Enumeration engineAliases() { Hashtable tab = new Hashtable(); Enumeration e = certs.keys(); while (e.hasMoreElements()) { tab.put(e.nextElement(), "cert"); } e = keys.keys(); while (e.hasMoreElements()) { String a = (String)e.nextElement(); if (tab.get(a) == null) { tab.put(a, "key"); } } return tab.keys(); } public boolean engineContainsAlias( String alias) { return (certs.get(alias) != null || keys.get(alias) != null); } /** * this is not quite complete - we should follow up on the chain, a bit * tricky if a certificate appears in more than one chain... */ public void engineDeleteEntry( String alias) throws KeyStoreException { Key k = (Key)keys.remove(alias); Certificate c = (Certificate)certs.remove(alias); if (c != null) { chainCerts.remove(new CertId(c.getPublicKey())); } if (k != null) { String id = (String)localIds.remove(alias); if (id != null) { c = (Certificate)keyCerts.remove(id); } if (c != null) { chainCerts.remove(new CertId(c.getPublicKey())); } } } /** * simply return the cert for the private key */ public Certificate engineGetCertificate( String alias) { if (alias == null) { throw new IllegalArgumentException("null alias passed to getCertificate."); } Certificate c = (Certificate)certs.get(alias); // // look up the key table - and try the local key id // if (c == null) { String id = (String)localIds.get(alias); if (id != null) { c = (Certificate)keyCerts.get(id); } else { c = (Certificate)keyCerts.get(alias); } } return c; } public String engineGetCertificateAlias( Certificate cert) { Enumeration c = certs.elements(); Enumeration k = certs.keys(); while (c.hasMoreElements()) { Certificate tc = (Certificate)c.nextElement(); String ta = (String)k.nextElement(); if (tc.equals(cert)) { return ta; } } c = keyCerts.elements(); k = keyCerts.keys(); while (c.hasMoreElements()) { Certificate tc = (Certificate)c.nextElement(); String ta = (String)k.nextElement(); if (tc.equals(cert)) { return ta; } } return null; } public Certificate[] engineGetCertificateChain( String alias) { if (alias == null) { throw new IllegalArgumentException("null alias passed to getCertificateChain."); } if (!engineIsKeyEntry(alias)) { return null; } Certificate c = engineGetCertificate(alias); if (c != null) { Vector cs = new Vector(); while (c != null) { X509Certificate x509c = (X509Certificate)c; Certificate nextC = null; byte[] bytes = x509c.getExtensionValue(Extension.authorityKeyIdentifier.getId()); if (bytes != null) { try { ASN1InputStream aIn = new ASN1InputStream(bytes); byte[] authBytes = ((ASN1OctetString)aIn.readObject()).getOctets(); aIn = new ASN1InputStream(authBytes); AuthorityKeyIdentifier id = AuthorityKeyIdentifier.getInstance(aIn.readObject()); if (id.getKeyIdentifier() != null) { nextC = (Certificate)chainCerts.get(new CertId(id.getKeyIdentifier())); } } catch (IOException e) { throw new RuntimeException(e.toString()); } } if (nextC == null) { // // no authority key id, try the Issuer DN // Principal i = x509c.getIssuerDN(); Principal s = x509c.getSubjectDN(); if (!i.equals(s)) { Enumeration e = chainCerts.keys(); while (e.hasMoreElements()) { X509Certificate crt = (X509Certificate)chainCerts.get(e.nextElement()); Principal sub = crt.getSubjectDN(); if (sub.equals(i)) { try { x509c.verify(crt.getPublicKey()); nextC = crt; break; } catch (Exception ex) { // continue } } } } } cs.addElement(c); if (nextC != c) // self signed - end of the chain { c = nextC; } else { c = null; } } Certificate[] certChain = new Certificate[cs.size()]; for (int i = 0; i != certChain.length; i++) { certChain[i] = (Certificate)cs.elementAt(i); } return certChain; } return null; } public Date engineGetCreationDate(String alias) { if (alias == null) { throw new NullPointerException("alias == null"); } if (keys.get(alias) == null && certs.get(alias) == null) { return null; } return new Date(); } public Key engineGetKey( String alias, char[] password) throws NoSuchAlgorithmException, UnrecoverableKeyException { if (alias == null) { throw new IllegalArgumentException("null alias passed to getKey."); } return (Key)keys.get(alias); } public boolean engineIsCertificateEntry( String alias) { return (certs.get(alias) != null && keys.get(alias) == null); } public boolean engineIsKeyEntry( String alias) { return (keys.get(alias) != null); } public void engineSetCertificateEntry( String alias, Certificate cert) throws KeyStoreException { if (keys.get(alias) != null) { throw new KeyStoreException("There is a key entry with the name " + alias + "."); } certs.put(alias, cert); chainCerts.put(new CertId(cert.getPublicKey()), cert); } public void engineSetKeyEntry( String alias, byte[] key, Certificate[] chain) throws KeyStoreException { throw new RuntimeException("operation not supported"); } public void engineSetKeyEntry( String alias, Key key, char[] password, Certificate[] chain) throws KeyStoreException { if (!(key instanceof PrivateKey)) { throw new KeyStoreException("PKCS12 does not support non-PrivateKeys"); } if ((key instanceof PrivateKey) && (chain == null)) { throw new KeyStoreException("no certificate chain for private key"); } if (keys.get(alias) != null) { engineDeleteEntry(alias); } keys.put(alias, key); if (chain != null) { certs.put(alias, chain[0]); for (int i = 0; i != chain.length; i++) { chainCerts.put(new CertId(chain[i].getPublicKey()), chain[i]); } } } public int engineSize() { Hashtable tab = new Hashtable(); Enumeration e = certs.keys(); while (e.hasMoreElements()) { tab.put(e.nextElement(), "cert"); } e = keys.keys(); while (e.hasMoreElements()) { String a = (String)e.nextElement(); if (tab.get(a) == null) { tab.put(a, "key"); } } return tab.size(); } protected PrivateKey unwrapKey( AlgorithmIdentifier algId, byte[] data, char[] password, boolean wrongPKCS12Zero) throws IOException { ASN1ObjectIdentifier algorithm = algId.getAlgorithm(); try { if (algorithm.on(PKCSObjectIdentifiers.pkcs_12PbeIds)) { PKCS12PBEParams pbeParams = PKCS12PBEParams.getInstance(algId.getParameters()); PBEKeySpec pbeSpec = new PBEKeySpec(password); PrivateKey out; SecretKeyFactory keyFact = SecretKeyFactory.getInstance( algorithm.getId(), bcProvider); PBEParameterSpec defParams = new PBEParameterSpec( pbeParams.getIV(), pbeParams.getIterations().intValue()); SecretKey k = keyFact.generateSecret(pbeSpec); ((BCPBEKey)k).setTryWrongPKCS12Zero(wrongPKCS12Zero); Cipher cipher = Cipher.getInstance(algorithm.getId(), bcProvider); cipher.init(Cipher.UNWRAP_MODE, k, defParams); // we pass "" as the key algorithm type as it is unknown at this point return (PrivateKey)cipher.unwrap(data, "", Cipher.PRIVATE_KEY); } else if (algorithm.equals(PKCSObjectIdentifiers.id_PBES2)) { PBES2Parameters alg = PBES2Parameters.getInstance(algId.getParameters()); PBKDF2Params func = PBKDF2Params.getInstance(alg.getKeyDerivationFunc().getParameters()); SecretKeyFactory keyFact = SecretKeyFactory.getInstance(alg.getKeyDerivationFunc().getAlgorithm().getId(), bcProvider); SecretKey k = keyFact.generateSecret(new PBEKeySpec(password, func.getSalt(), func.getIterationCount().intValue(), SecretKeyUtil.getKeySize(alg.getEncryptionScheme().getAlgorithm()))); Cipher cipher = Cipher.getInstance(alg.getEncryptionScheme().getAlgorithm().getId(), bcProvider); cipher.init(Cipher.UNWRAP_MODE, k, new IvParameterSpec(ASN1OctetString.getInstance(alg.getEncryptionScheme().getParameters()).getOctets())); // we pass "" as the key algorithm type as it is unknown at this point return (PrivateKey)cipher.unwrap(data, "", Cipher.PRIVATE_KEY); } } catch (Exception e) { throw new IOException("exception unwrapping private key - " + e.toString()); } throw new IOException("exception unwrapping private key - cannot recognise: " + algorithm); } protected byte[] wrapKey( String algorithm, Key key, PKCS12PBEParams pbeParams, char[] password) throws IOException { PBEKeySpec pbeSpec = new PBEKeySpec(password); byte[] out; try { SecretKeyFactory keyFact = SecretKeyFactory.getInstance( algorithm, bcProvider); PBEParameterSpec defParams = new PBEParameterSpec( pbeParams.getIV(), pbeParams.getIterations().intValue()); Cipher cipher = Cipher.getInstance(algorithm, bcProvider); cipher.init(Cipher.WRAP_MODE, keyFact.generateSecret(pbeSpec), defParams); out = cipher.wrap(key); } catch (Exception e) { throw new IOException("exception encrypting data - " + e.toString()); } return out; } protected byte[] cryptData( boolean forEncryption, AlgorithmIdentifier algId, char[] password, boolean wrongPKCS12Zero, byte[] data) throws IOException { String algorithm = algId.getAlgorithm().getId(); PKCS12PBEParams pbeParams = PKCS12PBEParams.getInstance(algId.getParameters()); PBEKeySpec pbeSpec = new PBEKeySpec(password); try { SecretKeyFactory keyFact = SecretKeyFactory.getInstance(algorithm, bcProvider); PBEParameterSpec defParams = new PBEParameterSpec( pbeParams.getIV(), pbeParams.getIterations().intValue()); BCPBEKey key = (BCPBEKey)keyFact.generateSecret(pbeSpec); key.setTryWrongPKCS12Zero(wrongPKCS12Zero); Cipher cipher = Cipher.getInstance(algorithm, bcProvider); int mode = forEncryption ? Cipher.ENCRYPT_MODE : Cipher.DECRYPT_MODE; cipher.init(mode, key, defParams); return cipher.doFinal(data); } catch (Exception e) { throw new IOException("exception decrypting data - " + e.toString()); } } public void engineLoad( InputStream stream, char[] password) throws IOException { if (stream == null) // just initialising { return; } if (password == null) { throw new NullPointerException("No password supplied for PKCS#12 KeyStore."); } BufferedInputStream bufIn = new BufferedInputStream(stream); bufIn.mark(10); int head = bufIn.read(); if (head != 0x30) { throw new IOException("stream does not represent a PKCS12 key store"); } bufIn.reset(); ASN1InputStream bIn = new ASN1InputStream(bufIn); ASN1Sequence obj = (ASN1Sequence)bIn.readObject(); Pfx bag = Pfx.getInstance(obj); ContentInfo info = bag.getAuthSafe(); Vector chain = new Vector(); boolean unmarkedKey = false; boolean wrongPKCS12Zero = false; if (bag.getMacData() != null) // check the mac code { MacData mData = bag.getMacData(); DigestInfo dInfo = mData.getMac(); AlgorithmIdentifier algId = dInfo.getAlgorithmId(); byte[] salt = mData.getSalt(); int itCount = mData.getIterationCount().intValue(); byte[] data = ((ASN1OctetString)info.getContent()).getOctets(); try { byte[] res = calculatePbeMac(algId.getAlgorithm(), salt, itCount, password, false, data); byte[] dig = dInfo.getDigest(); if (!Arrays.constantTimeAreEqual(res, dig)) { if (password.length > 0) { throw new IOException("PKCS12 key store mac invalid - wrong password or corrupted file."); } // Try with incorrect zero length password res = calculatePbeMac(algId.getAlgorithm(), salt, itCount, password, true, data); if (!Arrays.constantTimeAreEqual(res, dig)) { throw new IOException("PKCS12 key store mac invalid - wrong password or corrupted file."); } wrongPKCS12Zero = true; } } catch (IOException e) { throw e; } catch (Exception e) { throw new IOException("error constructing MAC: " + e.toString()); } } keys = new IgnoresCaseHashtable(); localIds = new Hashtable(); if (info.getContentType().equals(data)) { bIn = new ASN1InputStream(((ASN1OctetString)info.getContent()).getOctets()); AuthenticatedSafe authSafe = AuthenticatedSafe.getInstance(bIn.readObject()); ContentInfo[] c = authSafe.getContentInfo(); for (int i = 0; i != c.length; i++) { if (c[i].getContentType().equals(data)) { ASN1InputStream dIn = new ASN1InputStream(((ASN1OctetString)c[i].getContent()).getOctets()); ASN1Sequence seq = (ASN1Sequence)dIn.readObject(); for (int j = 0; j != seq.size(); j++) { SafeBag b = SafeBag.getInstance(seq.getObjectAt(j)); if (b.getBagId().equals(pkcs8ShroudedKeyBag)) { org.bouncycastle.asn1.pkcs.EncryptedPrivateKeyInfo eIn = org.bouncycastle.asn1.pkcs.EncryptedPrivateKeyInfo.getInstance(b.getBagValue()); PrivateKey privKey = unwrapKey(eIn.getEncryptionAlgorithm(), eIn.getEncryptedData(), password, wrongPKCS12Zero); // // set the attributes on the key // PKCS12BagAttributeCarrier bagAttr = (PKCS12BagAttributeCarrier)privKey; String alias = null; ASN1OctetString localId = null; if (b.getBagAttributes() != null) { Enumeration e = b.getBagAttributes().getObjects(); while (e.hasMoreElements()) { ASN1Sequence sq = (ASN1Sequence)e.nextElement(); ASN1ObjectIdentifier aOid = (ASN1ObjectIdentifier)sq.getObjectAt(0); ASN1Set attrSet = (ASN1Set)sq.getObjectAt(1); ASN1Primitive attr = null; if (attrSet.size() > 0) { attr = (ASN1Primitive)attrSet.getObjectAt(0); ASN1Encodable existing = bagAttr.getBagAttribute(aOid); if (existing != null) { // OK, but the value has to be the same if (!existing.toASN1Primitive().equals(attr)) { throw new IOException( "attempt to add existing attribute with different value"); } } else { bagAttr.setBagAttribute(aOid, attr); } } if (aOid.equals(pkcs_9_at_friendlyName)) { alias = ((DERBMPString)attr).getString(); keys.put(alias, privKey); } else if (aOid.equals(pkcs_9_at_localKeyId)) { localId = (ASN1OctetString)attr; } } } if (localId != null) { String name = new String(Hex.encode(localId.getOctets())); if (alias == null) { keys.put(name, privKey); } else { localIds.put(alias, name); } } else { unmarkedKey = true; keys.put("unmarked", privKey); } } else if (b.getBagId().equals(certBag)) { chain.addElement(b); } else { System.out.println("extra in data " + b.getBagId()); System.out.println(ASN1Dump.dumpAsString(b)); } } } else if (c[i].getContentType().equals(encryptedData)) { EncryptedData d = EncryptedData.getInstance(c[i].getContent()); byte[] octets = cryptData(false, d.getEncryptionAlgorithm(), password, wrongPKCS12Zero, d.getContent().getOctets()); ASN1Sequence seq = (ASN1Sequence)ASN1Primitive.fromByteArray(octets); for (int j = 0; j != seq.size(); j++) { SafeBag b = SafeBag.getInstance(seq.getObjectAt(j)); if (b.getBagId().equals(certBag)) { chain.addElement(b); } else if (b.getBagId().equals(pkcs8ShroudedKeyBag)) { org.bouncycastle.asn1.pkcs.EncryptedPrivateKeyInfo eIn = org.bouncycastle.asn1.pkcs.EncryptedPrivateKeyInfo.getInstance(b.getBagValue()); PrivateKey privKey = unwrapKey(eIn.getEncryptionAlgorithm(), eIn.getEncryptedData(), password, wrongPKCS12Zero); // // set the attributes on the key // PKCS12BagAttributeCarrier bagAttr = (PKCS12BagAttributeCarrier)privKey; String alias = null; ASN1OctetString localId = null; Enumeration e = b.getBagAttributes().getObjects(); while (e.hasMoreElements()) { ASN1Sequence sq = (ASN1Sequence)e.nextElement(); ASN1ObjectIdentifier aOid = (ASN1ObjectIdentifier)sq.getObjectAt(0); ASN1Set attrSet = (ASN1Set)sq.getObjectAt(1); ASN1Primitive attr = null; if (attrSet.size() > 0) { attr = (ASN1Primitive)attrSet.getObjectAt(0); ASN1Encodable existing = bagAttr.getBagAttribute(aOid); if (existing != null) { // OK, but the value has to be the same if (!existing.toASN1Primitive().equals(attr)) { throw new IOException( "attempt to add existing attribute with different value"); } } else { bagAttr.setBagAttribute(aOid, attr); } } if (aOid.equals(pkcs_9_at_friendlyName)) { alias = ((DERBMPString)attr).getString(); keys.put(alias, privKey); } else if (aOid.equals(pkcs_9_at_localKeyId)) { localId = (ASN1OctetString)attr; } } String name = new String(Hex.encode(localId.getOctets())); if (alias == null) { keys.put(name, privKey); } else { localIds.put(alias, name); } } else if (b.getBagId().equals(keyBag)) { org.bouncycastle.asn1.pkcs.PrivateKeyInfo kInfo = org.bouncycastle.asn1.pkcs.PrivateKeyInfo.getInstance(b.getBagValue()); PrivateKey privKey = BouncyCastleProvider.getPrivateKey(kInfo); // // set the attributes on the key // PKCS12BagAttributeCarrier bagAttr = (PKCS12BagAttributeCarrier)privKey; String alias = null; ASN1OctetString localId = null; Enumeration e = b.getBagAttributes().getObjects(); while (e.hasMoreElements()) { ASN1Sequence sq = (ASN1Sequence)e.nextElement(); ASN1ObjectIdentifier aOid = (ASN1ObjectIdentifier)sq.getObjectAt(0); ASN1Set attrSet = (ASN1Set)sq.getObjectAt(1); ASN1Primitive attr = null; if (attrSet.size() > 0) { attr = (ASN1Primitive)attrSet.getObjectAt(0); ASN1Encodable existing = bagAttr.getBagAttribute(aOid); if (existing != null) { // OK, but the value has to be the same if (!existing.toASN1Primitive().equals(attr)) { throw new IOException( "attempt to add existing attribute with different value"); } } else { bagAttr.setBagAttribute(aOid, attr); } } if (aOid.equals(pkcs_9_at_friendlyName)) { alias = ((DERBMPString)attr).getString(); keys.put(alias, privKey); } else if (aOid.equals(pkcs_9_at_localKeyId)) { localId = (ASN1OctetString)attr; } } String name = new String(Hex.encode(localId.getOctets())); if (alias == null) { keys.put(name, privKey); } else { localIds.put(alias, name); } } else { System.out.println("extra in encryptedData " + b.getBagId()); System.out.println(ASN1Dump.dumpAsString(b)); } } } else { System.out.println("extra " + c[i].getContentType().getId()); System.out.println("extra " + ASN1Dump.dumpAsString(c[i].getContent())); } } } certs = new IgnoresCaseHashtable(); chainCerts = new Hashtable(); keyCerts = new Hashtable(); for (int i = 0; i != chain.size(); i++) { SafeBag b = (SafeBag)chain.elementAt(i); CertBag cb = CertBag.getInstance(b.getBagValue()); if (!cb.getCertId().equals(x509Certificate)) { throw new RuntimeException("Unsupported certificate type: " + cb.getCertId()); } Certificate cert; try { ByteArrayInputStream cIn = new ByteArrayInputStream( ((ASN1OctetString)cb.getCertValue()).getOctets()); cert = certFact.generateCertificate(cIn); } catch (Exception e) { throw new RuntimeException(e.toString()); } // // set the attributes // ASN1OctetString localId = null; String alias = null; if (b.getBagAttributes() != null) { Enumeration e = b.getBagAttributes().getObjects(); while (e.hasMoreElements()) { ASN1Sequence sq = (ASN1Sequence)e.nextElement(); ASN1ObjectIdentifier oid = (ASN1ObjectIdentifier)sq.getObjectAt(0); ASN1Primitive attr = (ASN1Primitive)((ASN1Set)sq.getObjectAt(1)).getObjectAt(0); PKCS12BagAttributeCarrier bagAttr = null; if (cert instanceof PKCS12BagAttributeCarrier) { bagAttr = (PKCS12BagAttributeCarrier)cert; ASN1Encodable existing = bagAttr.getBagAttribute(oid); if (existing != null) { // OK, but the value has to be the same if (!existing.toASN1Primitive().equals(attr)) { throw new IOException( "attempt to add existing attribute with different value"); } } else { bagAttr.setBagAttribute(oid, attr); } } if (oid.equals(pkcs_9_at_friendlyName)) { alias = ((DERBMPString)attr).getString(); } else if (oid.equals(pkcs_9_at_localKeyId)) { localId = (ASN1OctetString)attr; } } } chainCerts.put(new CertId(cert.getPublicKey()), cert); if (unmarkedKey) { if (keyCerts.isEmpty()) { String name = new String(Hex.encode(createSubjectKeyId(cert.getPublicKey()).getKeyIdentifier())); keyCerts.put(name, cert); keys.put(name, keys.remove("unmarked")); } } else { // // the local key id needs to override the friendly name // if (localId != null) { String name = new String(Hex.encode(localId.getOctets())); keyCerts.put(name, cert); } if (alias != null) { certs.put(alias, cert); } } } } public void engineStore(LoadStoreParameter param) throws IOException, NoSuchAlgorithmException, CertificateException { if (param == null) { throw new IllegalArgumentException("'param' arg cannot be null"); } if (!(param instanceof PKCS12StoreParameter || param instanceof JDKPKCS12StoreParameter)) { throw new IllegalArgumentException( "No support for 'param' of type " + param.getClass().getName()); } PKCS12StoreParameter bcParam; if (param instanceof PKCS12StoreParameter) { bcParam = (PKCS12StoreParameter)param; } else { bcParam = new PKCS12StoreParameter(((JDKPKCS12StoreParameter)param).getOutputStream(), param.getProtectionParameter(), ((JDKPKCS12StoreParameter)param).isUseDEREncoding()); } char[] password; ProtectionParameter protParam = param.getProtectionParameter(); if (protParam == null) { password = null; } else if (protParam instanceof KeyStore.PasswordProtection) { password = ((KeyStore.PasswordProtection)protParam).getPassword(); } else { throw new IllegalArgumentException( "No support for protection parameter of type " + protParam.getClass().getName()); } doStore(bcParam.getOutputStream(), password, bcParam.isForDEREncoding()); } public void engineStore(OutputStream stream, char[] password) throws IOException { doStore(stream, password, false); } private void doStore(OutputStream stream, char[] password, boolean useDEREncoding) throws IOException { if (password == null) { throw new NullPointerException("No password supplied for PKCS#12 KeyStore."); } // // handle the key // ASN1EncodableVector keyS = new ASN1EncodableVector(); Enumeration ks = keys.keys(); while (ks.hasMoreElements()) { byte[] kSalt = new byte[SALT_SIZE]; random.nextBytes(kSalt); String name = (String)ks.nextElement(); PrivateKey privKey = (PrivateKey)keys.get(name); PKCS12PBEParams kParams = new PKCS12PBEParams(kSalt, MIN_ITERATIONS); byte[] kBytes = wrapKey(keyAlgorithm.getId(), privKey, kParams, password); AlgorithmIdentifier kAlgId = new AlgorithmIdentifier(keyAlgorithm, kParams.toASN1Primitive()); org.bouncycastle.asn1.pkcs.EncryptedPrivateKeyInfo kInfo = new org.bouncycastle.asn1.pkcs.EncryptedPrivateKeyInfo(kAlgId, kBytes); boolean attrSet = false; ASN1EncodableVector kName = new ASN1EncodableVector(); if (privKey instanceof PKCS12BagAttributeCarrier) { PKCS12BagAttributeCarrier bagAttrs = (PKCS12BagAttributeCarrier)privKey; // // make sure we are using the local alias on store // DERBMPString nm = (DERBMPString)bagAttrs.getBagAttribute(pkcs_9_at_friendlyName); if (nm == null || !nm.getString().equals(name)) { bagAttrs.setBagAttribute(pkcs_9_at_friendlyName, new DERBMPString(name)); } // // make sure we have a local key-id // if (bagAttrs.getBagAttribute(pkcs_9_at_localKeyId) == null) { Certificate ct = engineGetCertificate(name); bagAttrs.setBagAttribute(pkcs_9_at_localKeyId, createSubjectKeyId(ct.getPublicKey())); } Enumeration e = bagAttrs.getBagAttributeKeys(); while (e.hasMoreElements()) { ASN1ObjectIdentifier oid = (ASN1ObjectIdentifier)e.nextElement(); ASN1EncodableVector kSeq = new ASN1EncodableVector(); kSeq.add(oid); kSeq.add(new DERSet(bagAttrs.getBagAttribute(oid))); attrSet = true; kName.add(new DERSequence(kSeq)); } } if (!attrSet) { // // set a default friendly name (from the key id) and local id // ASN1EncodableVector kSeq = new ASN1EncodableVector(); Certificate ct = engineGetCertificate(name); kSeq.add(pkcs_9_at_localKeyId); kSeq.add(new DERSet(createSubjectKeyId(ct.getPublicKey()))); kName.add(new DERSequence(kSeq)); kSeq = new ASN1EncodableVector(); kSeq.add(pkcs_9_at_friendlyName); kSeq.add(new DERSet(new DERBMPString(name))); kName.add(new DERSequence(kSeq)); } SafeBag kBag = new SafeBag(pkcs8ShroudedKeyBag, kInfo.toASN1Primitive(), new DERSet(kName)); keyS.add(kBag); } byte[] keySEncoded = new DERSequence(keyS).getEncoded(ASN1Encoding.DER); BEROctetString keyString = new BEROctetString(keySEncoded); // // certificate processing // byte[] cSalt = new byte[SALT_SIZE]; random.nextBytes(cSalt); ASN1EncodableVector certSeq = new ASN1EncodableVector(); PKCS12PBEParams cParams = new PKCS12PBEParams(cSalt, MIN_ITERATIONS); AlgorithmIdentifier cAlgId = new AlgorithmIdentifier(certAlgorithm, cParams.toASN1Primitive()); Hashtable doneCerts = new Hashtable(); Enumeration cs = keys.keys(); while (cs.hasMoreElements()) { try { String name = (String)cs.nextElement(); Certificate cert = engineGetCertificate(name); boolean cAttrSet = false; CertBag cBag = new CertBag( x509Certificate, new DEROctetString(cert.getEncoded())); ASN1EncodableVector fName = new ASN1EncodableVector(); if (cert instanceof PKCS12BagAttributeCarrier) { PKCS12BagAttributeCarrier bagAttrs = (PKCS12BagAttributeCarrier)cert; // // make sure we are using the local alias on store // DERBMPString nm = (DERBMPString)bagAttrs.getBagAttribute(pkcs_9_at_friendlyName); if (nm == null || !nm.getString().equals(name)) { bagAttrs.setBagAttribute(pkcs_9_at_friendlyName, new DERBMPString(name)); } // // make sure we have a local key-id // if (bagAttrs.getBagAttribute(pkcs_9_at_localKeyId) == null) { bagAttrs.setBagAttribute(pkcs_9_at_localKeyId, createSubjectKeyId(cert.getPublicKey())); } Enumeration e = bagAttrs.getBagAttributeKeys(); while (e.hasMoreElements()) { ASN1ObjectIdentifier oid = (ASN1ObjectIdentifier)e.nextElement(); ASN1EncodableVector fSeq = new ASN1EncodableVector(); fSeq.add(oid); fSeq.add(new DERSet(bagAttrs.getBagAttribute(oid))); fName.add(new DERSequence(fSeq)); cAttrSet = true; } } if (!cAttrSet) { ASN1EncodableVector fSeq = new ASN1EncodableVector(); fSeq.add(pkcs_9_at_localKeyId); fSeq.add(new DERSet(createSubjectKeyId(cert.getPublicKey()))); fName.add(new DERSequence(fSeq)); fSeq = new ASN1EncodableVector(); fSeq.add(pkcs_9_at_friendlyName); fSeq.add(new DERSet(new DERBMPString(name))); fName.add(new DERSequence(fSeq)); } SafeBag sBag = new SafeBag(certBag, cBag.toASN1Primitive(), new DERSet(fName)); certSeq.add(sBag); doneCerts.put(cert, cert); } catch (CertificateEncodingException e) { throw new IOException("Error encoding certificate: " + e.toString()); } } cs = certs.keys(); while (cs.hasMoreElements()) { try { String certId = (String)cs.nextElement(); Certificate cert = (Certificate)certs.get(certId); boolean cAttrSet = false; if (keys.get(certId) != null) { continue; } CertBag cBag = new CertBag( x509Certificate, new DEROctetString(cert.getEncoded())); ASN1EncodableVector fName = new ASN1EncodableVector(); if (cert instanceof PKCS12BagAttributeCarrier) { PKCS12BagAttributeCarrier bagAttrs = (PKCS12BagAttributeCarrier)cert; // // make sure we are using the local alias on store // DERBMPString nm = (DERBMPString)bagAttrs.getBagAttribute(pkcs_9_at_friendlyName); if (nm == null || !nm.getString().equals(certId)) { bagAttrs.setBagAttribute(pkcs_9_at_friendlyName, new DERBMPString(certId)); } Enumeration e = bagAttrs.getBagAttributeKeys(); while (e.hasMoreElements()) { ASN1ObjectIdentifier oid = (ASN1ObjectIdentifier)e.nextElement(); // a certificate not immediately linked to a key doesn't require // a localKeyID and will confuse some PKCS12 implementations. // // If we find one, we'll prune it out. if (oid.equals(PKCSObjectIdentifiers.pkcs_9_at_localKeyId)) { continue; } ASN1EncodableVector fSeq = new ASN1EncodableVector(); fSeq.add(oid); fSeq.add(new DERSet(bagAttrs.getBagAttribute(oid))); fName.add(new DERSequence(fSeq)); cAttrSet = true; } } if (!cAttrSet) { ASN1EncodableVector fSeq = new ASN1EncodableVector(); fSeq.add(pkcs_9_at_friendlyName); fSeq.add(new DERSet(new DERBMPString(certId))); fName.add(new DERSequence(fSeq)); } SafeBag sBag = new SafeBag(certBag, cBag.toASN1Primitive(), new DERSet(fName)); certSeq.add(sBag); doneCerts.put(cert, cert); } catch (CertificateEncodingException e) { throw new IOException("Error encoding certificate: " + e.toString()); } } cs = chainCerts.keys(); while (cs.hasMoreElements()) { try { CertId certId = (CertId)cs.nextElement(); Certificate cert = (Certificate)chainCerts.get(certId); if (doneCerts.get(cert) != null) { continue; } CertBag cBag = new CertBag( x509Certificate, new DEROctetString(cert.getEncoded())); ASN1EncodableVector fName = new ASN1EncodableVector(); if (cert instanceof PKCS12BagAttributeCarrier) { PKCS12BagAttributeCarrier bagAttrs = (PKCS12BagAttributeCarrier)cert; Enumeration e = bagAttrs.getBagAttributeKeys(); while (e.hasMoreElements()) { ASN1ObjectIdentifier oid = (ASN1ObjectIdentifier)e.nextElement(); // a certificate not immediately linked to a key doesn't require // a localKeyID and will confuse some PKCS12 implementations. // // If we find one, we'll prune it out. if (oid.equals(PKCSObjectIdentifiers.pkcs_9_at_localKeyId)) { continue; } ASN1EncodableVector fSeq = new ASN1EncodableVector(); fSeq.add(oid); fSeq.add(new DERSet(bagAttrs.getBagAttribute(oid))); fName.add(new DERSequence(fSeq)); } } SafeBag sBag = new SafeBag(certBag, cBag.toASN1Primitive(), new DERSet(fName)); certSeq.add(sBag); } catch (CertificateEncodingException e) { throw new IOException("Error encoding certificate: " + e.toString()); } } byte[] certSeqEncoded = new DERSequence(certSeq).getEncoded(ASN1Encoding.DER); byte[] certBytes = cryptData(true, cAlgId, password, false, certSeqEncoded); EncryptedData cInfo = new EncryptedData(data, cAlgId, new BEROctetString(certBytes)); ContentInfo[] info = new ContentInfo[] { new ContentInfo(data, keyString), new ContentInfo(encryptedData, cInfo.toASN1Primitive()) }; AuthenticatedSafe auth = new AuthenticatedSafe(info); ByteArrayOutputStream bOut = new ByteArrayOutputStream(); DEROutputStream asn1Out; if (useDEREncoding) { asn1Out = new DEROutputStream(bOut); } else { asn1Out = new BEROutputStream(bOut); } asn1Out.writeObject(auth); byte[] pkg = bOut.toByteArray(); ContentInfo mainInfo = new ContentInfo(data, new BEROctetString(pkg)); // // create the mac // byte[] mSalt = new byte[20]; int itCount = MIN_ITERATIONS; random.nextBytes(mSalt); byte[] data = ((ASN1OctetString)mainInfo.getContent()).getOctets(); MacData mData; try { byte[] res = calculatePbeMac(id_SHA1, mSalt, itCount, password, false, data); AlgorithmIdentifier algId = new AlgorithmIdentifier(id_SHA1, DERNull.INSTANCE); DigestInfo dInfo = new DigestInfo(algId, res); mData = new MacData(dInfo, mSalt, itCount); } catch (Exception e) { throw new IOException("error constructing MAC: " + e.toString()); } // // output the Pfx // Pfx pfx = new Pfx(mainInfo, mData); if (useDEREncoding) { asn1Out = new DEROutputStream(stream); } else { asn1Out = new BEROutputStream(stream); } asn1Out.writeObject(pfx); } private static byte[] calculatePbeMac( ASN1ObjectIdentifier oid, byte[] salt, int itCount, char[] password, boolean wrongPkcs12Zero, byte[] data) throws Exception { SecretKeyFactory keyFact = SecretKeyFactory.getInstance(oid.getId(), bcProvider); PBEParameterSpec defParams = new PBEParameterSpec(salt, itCount); PBEKeySpec pbeSpec = new PBEKeySpec(password); BCPBEKey key = (BCPBEKey)keyFact.generateSecret(pbeSpec); key.setTryWrongPKCS12Zero(wrongPkcs12Zero); Mac mac = Mac.getInstance(oid.getId(), bcProvider); mac.init(key, defParams); mac.update(data); return mac.doFinal(); } public static class BCPKCS12KeyStore extends PKCS12KeyStoreSpi { public BCPKCS12KeyStore() { super(bcProvider, pbeWithSHAAnd3_KeyTripleDES_CBC, pbeWithSHAAnd40BitRC2_CBC); } } public static class BCPKCS12KeyStore3DES extends PKCS12KeyStoreSpi { public BCPKCS12KeyStore3DES() { super(bcProvider, pbeWithSHAAnd3_KeyTripleDES_CBC, pbeWithSHAAnd3_KeyTripleDES_CBC); } } public static class DefPKCS12KeyStore extends PKCS12KeyStoreSpi { public DefPKCS12KeyStore() { super(null, pbeWithSHAAnd3_KeyTripleDES_CBC, pbeWithSHAAnd40BitRC2_CBC); } } public static class DefPKCS12KeyStore3DES extends PKCS12KeyStoreSpi { public DefPKCS12KeyStore3DES() { super(null, pbeWithSHAAnd3_KeyTripleDES_CBC, pbeWithSHAAnd3_KeyTripleDES_CBC); } } private static class IgnoresCaseHashtable { private Hashtable orig = new Hashtable(); private Hashtable keys = new Hashtable(); public void put(String key, Object value) { String lower = (key == null) ? null : Strings.toLowerCase(key); String k = (String)keys.get(lower); if (k != null) { orig.remove(k); } keys.put(lower, key); orig.put(key, value); } public Enumeration keys() { return orig.keys(); } public Object remove(String alias) { String k = (String)keys.remove(alias == null ? null : Strings.toLowerCase(alias)); if (k == null) { return null; } return orig.remove(k); } public Object get(String alias) { String k = (String)keys.get(alias == null ? null : Strings.toLowerCase(alias)); if (k == null) { return null; } return orig.get(k); } public Enumeration elements() { return orig.elements(); } } } bouncycastle-1.49.orig/src/org/bouncycastle/jcajce/provider/keystore/BC.java0000644000175000017500000000203512115720207026544 0ustar ebourgebourgpackage org.bouncycastle.jcajce.provider.keystore; import org.bouncycastle.jcajce.provider.config.ConfigurableProvider; import org.bouncycastle.jcajce.provider.util.AsymmetricAlgorithmProvider; public class BC { private static final String PREFIX = "org.bouncycastle.jcajce.provider.keystore" + ".bc."; public static class Mappings extends AsymmetricAlgorithmProvider { public Mappings() { } public void configure(ConfigurableProvider provider) { provider.addAlgorithm("KeyStore.BKS", PREFIX + "BcKeyStoreSpi$Std"); provider.addAlgorithm("KeyStore.BKS-V1", PREFIX + "BcKeyStoreSpi$Version1"); provider.addAlgorithm("KeyStore.BouncyCastle", PREFIX + "BcKeyStoreSpi$BouncyCastleStore"); provider.addAlgorithm("Alg.Alias.KeyStore.UBER", "BouncyCastle"); provider.addAlgorithm("Alg.Alias.KeyStore.BOUNCYCASTLE", "BouncyCastle"); provider.addAlgorithm("Alg.Alias.KeyStore.bouncycastle", "BouncyCastle"); } } } bouncycastle-1.49.orig/src/org/bouncycastle/jcajce/provider/digest/0000755000175000017500000000000012152033551025027 5ustar ebourgebourgbouncycastle-1.49.orig/src/org/bouncycastle/jcajce/provider/digest/BCMessageDigest.java0000644000175000017500000000153111634006704030627 0ustar ebourgebourgpackage org.bouncycastle.jcajce.provider.digest; import java.security.MessageDigest; import org.bouncycastle.crypto.Digest; public class BCMessageDigest extends MessageDigest { protected Digest digest; protected BCMessageDigest( Digest digest) { super(digest.getAlgorithmName()); this.digest = digest; } public void engineReset() { digest.reset(); } public void engineUpdate( byte input) { digest.update(input); } public void engineUpdate( byte[] input, int offset, int len) { digest.update(input, offset, len); } public byte[] engineDigest() { byte[] digestBytes = new byte[digest.getDigestSize()]; digest.doFinal(digestBytes, 0); return digestBytes; } } bouncycastle-1.49.orig/src/org/bouncycastle/jcajce/provider/digest/SHA512.java0000644000175000017500000001132212114015744026536 0ustar ebourgebourgpackage org.bouncycastle.jcajce.provider.digest; import org.bouncycastle.asn1.nist.NISTObjectIdentifiers; import org.bouncycastle.asn1.pkcs.PKCSObjectIdentifiers; import org.bouncycastle.crypto.CipherKeyGenerator; import org.bouncycastle.crypto.digests.SHA512Digest; import org.bouncycastle.crypto.digests.SHA512tDigest; import org.bouncycastle.crypto.macs.HMac; import org.bouncycastle.crypto.macs.OldHMac; import org.bouncycastle.jcajce.provider.config.ConfigurableProvider; import org.bouncycastle.jcajce.provider.symmetric.util.BaseKeyGenerator; import org.bouncycastle.jcajce.provider.symmetric.util.BaseMac; public class SHA512 { private SHA512() { } static public class Digest extends BCMessageDigest implements Cloneable { public Digest() { super(new SHA512Digest()); } public Object clone() throws CloneNotSupportedException { Digest d = (Digest)super.clone(); d.digest = new SHA512Digest((SHA512Digest)digest); return d; } } static public class DigestT extends BCMessageDigest implements Cloneable { public DigestT(int bitLength) { super(new SHA512tDigest(bitLength)); } public Object clone() throws CloneNotSupportedException { DigestT d = (DigestT)super.clone(); d.digest = new SHA512tDigest((SHA512tDigest)digest); return d; } } static public class DigestT224 extends DigestT { public DigestT224() { super(224); } } static public class DigestT256 extends DigestT { public DigestT256() { super(256); } } public static class HashMac extends BaseMac { public HashMac() { super(new HMac(new SHA512Digest())); } } public static class HashMacT224 extends BaseMac { public HashMacT224() { super(new HMac(new SHA512tDigest(224))); } } public static class HashMacT256 extends BaseMac { public HashMacT256() { super(new HMac(new SHA512tDigest(256))); } } /** * SHA-512 HMac */ public static class OldSHA512 extends BaseMac { public OldSHA512() { super(new OldHMac(new SHA512Digest())); } } /** * HMACSHA512 */ public static class KeyGenerator extends BaseKeyGenerator { public KeyGenerator() { super("HMACSHA512", 512, new CipherKeyGenerator()); } } public static class KeyGeneratorT224 extends BaseKeyGenerator { public KeyGeneratorT224() { super("HMACSHA512/224", 224, new CipherKeyGenerator()); } } public static class KeyGeneratorT256 extends BaseKeyGenerator { public KeyGeneratorT256() { super("HMACSHA512/256", 256, new CipherKeyGenerator()); } } public static class Mappings extends DigestAlgorithmProvider { private static final String PREFIX = SHA512.class.getName(); public Mappings() { } public void configure(ConfigurableProvider provider) { provider.addAlgorithm("MessageDigest.SHA-512", PREFIX + "$Digest"); provider.addAlgorithm("Alg.Alias.MessageDigest.SHA512", "SHA-512"); provider.addAlgorithm("Alg.Alias.MessageDigest." + NISTObjectIdentifiers.id_sha512, "SHA-512"); provider.addAlgorithm("MessageDigest.SHA-512/224", PREFIX + "$DigestT224"); provider.addAlgorithm("Alg.Alias.MessageDigest.SHA512/224", "SHA-512/224"); provider.addAlgorithm("Alg.Alias.MessageDigest." + NISTObjectIdentifiers.id_sha512_224, "SHA-512/224"); provider.addAlgorithm("MessageDigest.SHA-512/256", PREFIX + "$DigestT256"); provider.addAlgorithm("Alg.Alias.MessageDigest.SHA512256", "SHA-512/256"); provider.addAlgorithm("Alg.Alias.MessageDigest." + NISTObjectIdentifiers.id_sha512_256, "SHA-512/256"); provider.addAlgorithm("Mac.OLDHMACSHA512", PREFIX + "$OldSHA512"); addHMACAlgorithm(provider, "SHA512", PREFIX + "$HashMac", PREFIX + "$KeyGenerator"); addHMACAlias(provider, "SHA512", PKCSObjectIdentifiers.id_hmacWithSHA512); addHMACAlgorithm(provider, "SHA512/224", PREFIX + "$HashMacT224", PREFIX + "$KeyGeneratorT224"); addHMACAlgorithm(provider, "SHA512/256", PREFIX + "$HashMacT256", PREFIX + "$KeyGeneratorT256"); } } } bouncycastle-1.49.orig/src/org/bouncycastle/jcajce/provider/digest/GOST3411.java0000644000175000017500000000421412114015744026762 0ustar ebourgebourgpackage org.bouncycastle.jcajce.provider.digest; import org.bouncycastle.asn1.cryptopro.CryptoProObjectIdentifiers; import org.bouncycastle.crypto.CipherKeyGenerator; import org.bouncycastle.crypto.digests.GOST3411Digest; import org.bouncycastle.crypto.macs.HMac; import org.bouncycastle.jcajce.provider.config.ConfigurableProvider; import org.bouncycastle.jcajce.provider.symmetric.util.BaseKeyGenerator; import org.bouncycastle.jcajce.provider.symmetric.util.BaseMac; public class GOST3411 { private GOST3411() { } static public class Digest extends BCMessageDigest implements Cloneable { public Digest() { super(new GOST3411Digest()); } public Object clone() throws CloneNotSupportedException { Digest d = (Digest)super.clone(); d.digest = new GOST3411Digest((GOST3411Digest)digest); return d; } } /** * GOST3411 HMac */ public static class HashMac extends BaseMac { public HashMac() { super(new HMac(new GOST3411Digest())); } } public static class KeyGenerator extends BaseKeyGenerator { public KeyGenerator() { super("HMACGOST3411", 256, new CipherKeyGenerator()); } } public static class Mappings extends DigestAlgorithmProvider { private static final String PREFIX = GOST3411.class.getName(); public Mappings() { } public void configure(ConfigurableProvider provider) { provider.addAlgorithm("MessageDigest.GOST3411", PREFIX + "$Digest"); provider.addAlgorithm("Alg.Alias.MessageDigest.GOST", "GOST3411"); provider.addAlgorithm("Alg.Alias.MessageDigest.GOST-3411", "GOST3411"); provider.addAlgorithm("Alg.Alias.MessageDigest." + CryptoProObjectIdentifiers.gostR3411, "GOST3411"); addHMACAlgorithm(provider, "GOST3411", PREFIX + "$HashMac", PREFIX + "$KeyGenerator"); addHMACAlias(provider, "GOST3411", CryptoProObjectIdentifiers.gostR3411); } } } bouncycastle-1.49.orig/src/org/bouncycastle/jcajce/provider/digest/SHA384.java0000644000175000017500000000456212114015744026555 0ustar ebourgebourgpackage org.bouncycastle.jcajce.provider.digest; import org.bouncycastle.asn1.nist.NISTObjectIdentifiers; import org.bouncycastle.asn1.pkcs.PKCSObjectIdentifiers; import org.bouncycastle.crypto.CipherKeyGenerator; import org.bouncycastle.crypto.digests.SHA384Digest; import org.bouncycastle.crypto.macs.HMac; import org.bouncycastle.crypto.macs.OldHMac; import org.bouncycastle.jcajce.provider.config.ConfigurableProvider; import org.bouncycastle.jcajce.provider.symmetric.util.BaseKeyGenerator; import org.bouncycastle.jcajce.provider.symmetric.util.BaseMac; public class SHA384 { private SHA384() { } static public class Digest extends BCMessageDigest implements Cloneable { public Digest() { super(new SHA384Digest()); } public Object clone() throws CloneNotSupportedException { Digest d = (Digest)super.clone(); d.digest = new SHA384Digest((SHA384Digest)digest); return d; } } public static class HashMac extends BaseMac { public HashMac() { super(new HMac(new SHA384Digest())); } } /** * HMACSHA384 */ public static class KeyGenerator extends BaseKeyGenerator { public KeyGenerator() { super("HMACSHA384", 384, new CipherKeyGenerator()); } } public static class OldSHA384 extends BaseMac { public OldSHA384() { super(new OldHMac(new SHA384Digest())); } } public static class Mappings extends DigestAlgorithmProvider { private static final String PREFIX = SHA384.class.getName(); public Mappings() { } public void configure(ConfigurableProvider provider) { provider.addAlgorithm("MessageDigest.SHA-384", PREFIX + "$Digest"); provider.addAlgorithm("Alg.Alias.MessageDigest.SHA384", "SHA-384"); provider.addAlgorithm("Alg.Alias.MessageDigest." + NISTObjectIdentifiers.id_sha384, "SHA-384"); provider.addAlgorithm("Mac.OLDHMACSHA384", PREFIX + "$OldSHA384"); addHMACAlgorithm(provider, "SHA384", PREFIX + "$HashMac", PREFIX + "$KeyGenerator"); addHMACAlias(provider, "SHA384", PKCSObjectIdentifiers.id_hmacWithSHA384); } } } bouncycastle-1.49.orig/src/org/bouncycastle/jcajce/provider/digest/SHA3.java0000644000175000017500000001022412151126367026376 0ustar ebourgebourgpackage org.bouncycastle.jcajce.provider.digest; import org.bouncycastle.crypto.CipherKeyGenerator; import org.bouncycastle.crypto.digests.SHA3Digest; import org.bouncycastle.crypto.macs.HMac; import org.bouncycastle.jcajce.provider.config.ConfigurableProvider; import org.bouncycastle.jcajce.provider.symmetric.util.BaseKeyGenerator; import org.bouncycastle.jcajce.provider.symmetric.util.BaseMac; public class SHA3 { private SHA3() { } static public class DigestSHA3 extends BCMessageDigest implements Cloneable { public DigestSHA3(int size) { super(new SHA3Digest(size)); } public Object clone() throws CloneNotSupportedException { BCMessageDigest d = (BCMessageDigest)super.clone(); d.digest = new SHA3Digest((SHA3Digest)digest); return d; } } static public class Digest224 extends DigestSHA3 { public Digest224() { super(224); } } static public class Digest256 extends DigestSHA3 { public Digest256() { super(256); } } static public class Digest384 extends DigestSHA3 { public Digest384() { super(384); } } static public class Digest512 extends DigestSHA3 { public Digest512() { super(512); } } /** * SHA3 HMac */ public static class HashMac224 extends BaseMac { public HashMac224() { super(new HMac(new SHA3Digest(224))); } } public static class HashMac256 extends BaseMac { public HashMac256() { super(new HMac(new SHA3Digest(256))); } } public static class HashMac384 extends BaseMac { public HashMac384() { super(new HMac(new SHA3Digest(384))); } } public static class HashMac512 extends BaseMac { public HashMac512() { super(new HMac(new SHA3Digest(512))); } } public static class KeyGenerator224 extends BaseKeyGenerator { public KeyGenerator224() { super("HMACSHA3-224", 224, new CipherKeyGenerator()); } } public static class KeyGenerator256 extends BaseKeyGenerator { public KeyGenerator256() { super("HMACSHA3-256", 256, new CipherKeyGenerator()); } } public static class KeyGenerator384 extends BaseKeyGenerator { public KeyGenerator384() { super("HMACSHA3-384", 384, new CipherKeyGenerator()); } } public static class KeyGenerator512 extends BaseKeyGenerator { public KeyGenerator512() { super("HMACSHA3-512", 512, new CipherKeyGenerator()); } } public static class Mappings extends DigestAlgorithmProvider { private static final String PREFIX = SHA3.class.getName(); public Mappings() { } public void configure(ConfigurableProvider provider) { provider.addAlgorithm("MessageDigest.SHA3-224", PREFIX + "$Digest224"); provider.addAlgorithm("MessageDigest.SHA3-256", PREFIX + "$Digest256"); provider.addAlgorithm("MessageDigest.SHA3-384", PREFIX + "$Digest384"); provider.addAlgorithm("MessageDigest.SHA3-512", PREFIX + "$Digest512"); // look for an object identifier (NIST???) for SHA3 family // provider.addAlgorithm("Alg.Alias.MessageDigest." + OIWObjectIdentifiers.idSHA3, "SHA3-224"); // ***** addHMACAlgorithm(provider, "SHA3-224", PREFIX + "$HashMac224", PREFIX + "$KeyGenerator224"); addHMACAlgorithm(provider, "SHA3-256", PREFIX + "$HashMac256", PREFIX + "$KeyGenerator256"); addHMACAlgorithm(provider, "SHA3-384", PREFIX + "$HashMac384", PREFIX + "$KeyGenerator384"); addHMACAlgorithm(provider, "SHA3-512", PREFIX + "$HashMac512", PREFIX + "$KeyGenerator512"); } } } bouncycastle-1.49.orig/src/org/bouncycastle/jcajce/provider/digest/DigestAlgorithmProvider.java0000644000175000017500000000250312002413713032467 0ustar ebourgebourgpackage org.bouncycastle.jcajce.provider.digest; import org.bouncycastle.asn1.ASN1ObjectIdentifier; import org.bouncycastle.jcajce.provider.config.ConfigurableProvider; import org.bouncycastle.jcajce.provider.util.AlgorithmProvider; abstract class DigestAlgorithmProvider extends AlgorithmProvider { protected void addHMACAlgorithm( ConfigurableProvider provider, String algorithm, String algorithmClassName, String keyGeneratorClassName) { String mainName = "HMAC" + algorithm; provider.addAlgorithm("Mac." + mainName, algorithmClassName); provider.addAlgorithm("Alg.Alias.Mac.HMAC-" + algorithm, mainName); provider.addAlgorithm("Alg.Alias.Mac.HMAC/" + algorithm, mainName); provider.addAlgorithm("KeyGenerator." + mainName, keyGeneratorClassName); provider.addAlgorithm("Alg.Alias.KeyGenerator.HMAC-" + algorithm, mainName); provider.addAlgorithm("Alg.Alias.KeyGenerator.HMAC/" + algorithm, mainName); } protected void addHMACAlias( ConfigurableProvider provider, String algorithm, ASN1ObjectIdentifier oid) { String mainName = "HMAC" + algorithm; provider.addAlgorithm("Alg.Alias.Mac." + oid, mainName); provider.addAlgorithm("Alg.Alias.KeyGenerator." + oid, mainName); } } bouncycastle-1.49.orig/src/org/bouncycastle/jcajce/provider/digest/MD5.java0000644000175000017500000000370312114015744026264 0ustar ebourgebourgpackage org.bouncycastle.jcajce.provider.digest; import org.bouncycastle.asn1.iana.IANAObjectIdentifiers; import org.bouncycastle.asn1.pkcs.PKCSObjectIdentifiers; import org.bouncycastle.crypto.CipherKeyGenerator; import org.bouncycastle.crypto.digests.MD5Digest; import org.bouncycastle.crypto.macs.HMac; import org.bouncycastle.jcajce.provider.config.ConfigurableProvider; import org.bouncycastle.jcajce.provider.symmetric.util.BaseKeyGenerator; import org.bouncycastle.jcajce.provider.symmetric.util.BaseMac; public class MD5 { private MD5() { } /** * MD5 HashMac */ public static class HashMac extends BaseMac { public HashMac() { super(new HMac(new MD5Digest())); } } public static class KeyGenerator extends BaseKeyGenerator { public KeyGenerator() { super("HMACMD5", 128, new CipherKeyGenerator()); } } static public class Digest extends BCMessageDigest implements Cloneable { public Digest() { super(new MD5Digest()); } public Object clone() throws CloneNotSupportedException { Digest d = (Digest)super.clone(); d.digest = new MD5Digest((MD5Digest)digest); return d; } } public static class Mappings extends DigestAlgorithmProvider { private static final String PREFIX = MD5.class.getName(); public Mappings() { } public void configure(ConfigurableProvider provider) { provider.addAlgorithm("MessageDigest.MD5", PREFIX + "$Digest"); provider.addAlgorithm("Alg.Alias.MessageDigest." + PKCSObjectIdentifiers.md5, "MD5"); addHMACAlgorithm(provider, "MD5", PREFIX + "$HashMac", PREFIX + "$KeyGenerator"); addHMACAlias(provider, "MD5", IANAObjectIdentifiers.hmacMD5); } } } bouncycastle-1.49.orig/src/org/bouncycastle/jcajce/provider/digest/MD2.java0000644000175000017500000000347512114015744026267 0ustar ebourgebourgpackage org.bouncycastle.jcajce.provider.digest; import org.bouncycastle.asn1.pkcs.PKCSObjectIdentifiers; import org.bouncycastle.crypto.CipherKeyGenerator; import org.bouncycastle.crypto.digests.MD2Digest; import org.bouncycastle.crypto.macs.HMac; import org.bouncycastle.jcajce.provider.config.ConfigurableProvider; import org.bouncycastle.jcajce.provider.symmetric.util.BaseKeyGenerator; import org.bouncycastle.jcajce.provider.symmetric.util.BaseMac; public class MD2 { private MD2() { } static public class Digest extends BCMessageDigest implements Cloneable { public Digest() { super(new MD2Digest()); } public Object clone() throws CloneNotSupportedException { Digest d = (Digest)super.clone(); d.digest = new MD2Digest((MD2Digest)digest); return d; } } /** * MD2 HMac */ public static class HashMac extends BaseMac { public HashMac() { super(new HMac(new MD2Digest())); } } public static class KeyGenerator extends BaseKeyGenerator { public KeyGenerator() { super("HMACMD2", 128, new CipherKeyGenerator()); } } public static class Mappings extends DigestAlgorithmProvider { private static final String PREFIX = MD2.class.getName(); public Mappings() { } public void configure(ConfigurableProvider provider) { provider.addAlgorithm("MessageDigest.MD2", PREFIX + "$Digest"); provider.addAlgorithm("Alg.Alias.MessageDigest." + PKCSObjectIdentifiers.md2, "MD2"); addHMACAlgorithm(provider, "MD2", PREFIX + "$HashMac", PREFIX + "$KeyGenerator"); } } } bouncycastle-1.49.orig/src/org/bouncycastle/jcajce/provider/digest/Tiger.java0000644000175000017500000000542112114014713026743 0ustar ebourgebourgpackage org.bouncycastle.jcajce.provider.digest; import org.bouncycastle.asn1.iana.IANAObjectIdentifiers; import org.bouncycastle.crypto.CipherKeyGenerator; import org.bouncycastle.crypto.digests.TigerDigest; import org.bouncycastle.crypto.macs.HMac; import org.bouncycastle.jcajce.provider.config.ConfigurableProvider; import org.bouncycastle.jcajce.provider.symmetric.util.BaseKeyGenerator; import org.bouncycastle.jcajce.provider.symmetric.util.BaseMac; import org.bouncycastle.jcajce.provider.symmetric.util.PBESecretKeyFactory; public class Tiger { private Tiger() { } static public class Digest extends BCMessageDigest implements Cloneable { public Digest() { super(new TigerDigest()); } public Object clone() throws CloneNotSupportedException { Digest d = (Digest)super.clone(); d.digest = new TigerDigest((TigerDigest)digest); return d; } } /** * Tiger HMac */ public static class HashMac extends BaseMac { public HashMac() { super(new HMac(new TigerDigest())); } } public static class KeyGenerator extends BaseKeyGenerator { public KeyGenerator() { super("HMACTIGER", 192, new CipherKeyGenerator()); } } /** * Tiger HMac */ public static class TigerHmac extends BaseMac { public TigerHmac() { super(new HMac(new TigerDigest())); } } /** * PBEWithHmacTiger */ public static class PBEWithMacKeyFactory extends PBESecretKeyFactory { public PBEWithMacKeyFactory() { super("PBEwithHmacTiger", null, false, PKCS12, TIGER, 192, 0); } } /** * PBEWithHmacTiger */ public static class PBEWithHashMac extends BaseMac { public PBEWithHashMac() { super(new HMac(new TigerDigest()), PKCS12, TIGER, 192); } } public static class Mappings extends DigestAlgorithmProvider { private static final String PREFIX = Tiger.class.getName(); public Mappings() { } public void configure(ConfigurableProvider provider) { provider.addAlgorithm("MessageDigest.TIGER", PREFIX + "$Digest"); provider.addAlgorithm("MessageDigest.Tiger", PREFIX + "$Digest"); // JDK 1.1. addHMACAlgorithm(provider, "TIGER", PREFIX + "$HashMac", PREFIX + "$KeyGenerator"); addHMACAlias(provider, "TIGER", IANAObjectIdentifiers.hmacTIGER); provider.addAlgorithm("SecretKeyFactory.PBEWITHHMACTIGER", PREFIX + "$PBEWithMacKeyFactory"); } } } bouncycastle-1.49.orig/src/org/bouncycastle/jcajce/provider/digest/SHA224.java0000644000175000017500000000405312114015744026541 0ustar ebourgebourgpackage org.bouncycastle.jcajce.provider.digest; import org.bouncycastle.asn1.nist.NISTObjectIdentifiers; import org.bouncycastle.asn1.pkcs.PKCSObjectIdentifiers; import org.bouncycastle.crypto.CipherKeyGenerator; import org.bouncycastle.crypto.digests.SHA224Digest; import org.bouncycastle.crypto.macs.HMac; import org.bouncycastle.jcajce.provider.config.ConfigurableProvider; import org.bouncycastle.jcajce.provider.symmetric.util.BaseKeyGenerator; import org.bouncycastle.jcajce.provider.symmetric.util.BaseMac; public class SHA224 { private SHA224() { } static public class Digest extends BCMessageDigest implements Cloneable { public Digest() { super(new SHA224Digest()); } public Object clone() throws CloneNotSupportedException { Digest d = (Digest)super.clone(); d.digest = new SHA224Digest((SHA224Digest)digest); return d; } } public static class HashMac extends BaseMac { public HashMac() { super(new HMac(new SHA224Digest())); } } public static class KeyGenerator extends BaseKeyGenerator { public KeyGenerator() { super("HMACSHA224", 224, new CipherKeyGenerator()); } } public static class Mappings extends DigestAlgorithmProvider { private static final String PREFIX = SHA224.class.getName(); public Mappings() { } public void configure(ConfigurableProvider provider) { provider.addAlgorithm("MessageDigest.SHA-224", PREFIX + "$Digest"); provider.addAlgorithm("Alg.Alias.MessageDigest.SHA224", "SHA-224"); provider.addAlgorithm("Alg.Alias.MessageDigest." + NISTObjectIdentifiers.id_sha224, "SHA-224"); addHMACAlgorithm(provider, "SHA224", PREFIX + "$HashMac", PREFIX + "$KeyGenerator"); addHMACAlias(provider, "SHA224", PKCSObjectIdentifiers.id_hmacWithSHA224); } } } bouncycastle-1.49.orig/src/org/bouncycastle/jcajce/provider/digest/SHA1.java0000644000175000017500000001462612151776166026416 0ustar ebourgebourgpackage org.bouncycastle.jcajce.provider.digest; import java.security.spec.InvalidKeySpecException; import java.security.spec.KeySpec; import javax.crypto.SecretKey; import javax.crypto.spec.PBEKeySpec; import org.bouncycastle.asn1.iana.IANAObjectIdentifiers; import org.bouncycastle.asn1.oiw.OIWObjectIdentifiers; import org.bouncycastle.asn1.pkcs.PKCSObjectIdentifiers; import org.bouncycastle.crypto.CipherKeyGenerator; import org.bouncycastle.crypto.CipherParameters; import org.bouncycastle.crypto.digests.SHA1Digest; import org.bouncycastle.crypto.macs.HMac; import org.bouncycastle.jcajce.provider.config.ConfigurableProvider; import org.bouncycastle.jcajce.provider.symmetric.util.BCPBEKey; import org.bouncycastle.jcajce.provider.symmetric.util.BaseKeyGenerator; import org.bouncycastle.jcajce.provider.symmetric.util.BaseMac; import org.bouncycastle.jcajce.provider.symmetric.util.BaseSecretKeyFactory; import org.bouncycastle.jcajce.provider.symmetric.util.PBE; import org.bouncycastle.jcajce.provider.symmetric.util.PBESecretKeyFactory; public class SHA1 { private SHA1() { } static public class Digest extends BCMessageDigest implements Cloneable { public Digest() { super(new SHA1Digest()); } public Object clone() throws CloneNotSupportedException { Digest d = (Digest)super.clone(); d.digest = new SHA1Digest((SHA1Digest)digest); return d; } } /** * SHA1 HMac */ public static class HashMac extends BaseMac { public HashMac() { super(new HMac(new SHA1Digest())); } } public static class KeyGenerator extends BaseKeyGenerator { public KeyGenerator() { super("HMACSHA1", 160, new CipherKeyGenerator()); } } /** * SHA1 HMac */ public static class SHA1Mac extends BaseMac { public SHA1Mac() { super(new HMac(new SHA1Digest())); } } /** * PBEWithHmacSHA */ public static class PBEWithMacKeyFactory extends PBESecretKeyFactory { public PBEWithMacKeyFactory() { super("PBEwithHmacSHA", null, false, PKCS12, SHA1, 160, 0); } } public static class BasePBKDF2WithHmacSHA1 extends BaseSecretKeyFactory { private int scheme; public BasePBKDF2WithHmacSHA1(String name, int scheme) { super(name, PKCSObjectIdentifiers.id_PBKDF2); this.scheme = scheme; } protected SecretKey engineGenerateSecret( KeySpec keySpec) throws InvalidKeySpecException { if (keySpec instanceof PBEKeySpec) { PBEKeySpec pbeSpec = (PBEKeySpec)keySpec; if (pbeSpec.getSalt() == null) { throw new InvalidKeySpecException("missing required salt"); } if (pbeSpec.getIterationCount() <= 0) { throw new InvalidKeySpecException("positive iteration count required: " + pbeSpec.getIterationCount()); } if (pbeSpec.getKeyLength() <= 0) { throw new InvalidKeySpecException("positive key length required: " + pbeSpec.getKeyLength()); } if (pbeSpec.getPassword().length == 0) { throw new IllegalArgumentException("password empty"); } int digest = SHA1; int keySize = pbeSpec.getKeyLength(); int ivSize = -1; // JDK 1,2 and earlier does not understand simplified version. CipherParameters param = PBE.Util.makePBEMacParameters(pbeSpec, scheme, digest, keySize); return new BCPBEKey(this.algName, this.algOid, scheme, digest, keySize, ivSize, pbeSpec, param); } throw new InvalidKeySpecException("Invalid KeySpec"); } } public static class PBKDF2WithHmacSHA1UTF8 extends BasePBKDF2WithHmacSHA1 { public PBKDF2WithHmacSHA1UTF8() { super("PBKDF2WithHmacSHA1", PKCS5S2_UTF8); } } public static class PBKDF2WithHmacSHA18BIT extends BasePBKDF2WithHmacSHA1 { public PBKDF2WithHmacSHA18BIT() { super("PBKDF2WithHmacSHA1And8bit", PKCS5S2); } } public static class Mappings extends DigestAlgorithmProvider { private static final String PREFIX = SHA1.class.getName(); public Mappings() { } public void configure(ConfigurableProvider provider) { provider.addAlgorithm("MessageDigest.SHA-1", PREFIX + "$Digest"); provider.addAlgorithm("Alg.Alias.MessageDigest.SHA1", "SHA-1"); provider.addAlgorithm("Alg.Alias.MessageDigest.SHA", "SHA-1"); provider.addAlgorithm("Alg.Alias.MessageDigest." + OIWObjectIdentifiers.idSHA1, "SHA-1"); addHMACAlgorithm(provider, "SHA1", PREFIX + "$HashMac", PREFIX + "$KeyGenerator"); addHMACAlias(provider, "SHA1", PKCSObjectIdentifiers.id_hmacWithSHA1); addHMACAlias(provider, "SHA1", IANAObjectIdentifiers.hmacSHA1); provider.addAlgorithm("Mac.PBEWITHHMACSHA", PREFIX + "$SHA1Mac"); provider.addAlgorithm("Mac.PBEWITHHMACSHA1", PREFIX + "$SHA1Mac"); provider.addAlgorithm("Alg.Alias.SecretKeyFactory.PBEWITHHMACSHA", "PBEWITHHMACSHA1"); provider.addAlgorithm("Alg.Alias.SecretKeyFactory." + OIWObjectIdentifiers.idSHA1, "PBEWITHHMACSHA1"); provider.addAlgorithm("Alg.Alias.Mac." + OIWObjectIdentifiers.idSHA1, "PBEWITHHMACSHA"); provider.addAlgorithm("SecretKeyFactory.PBEWITHHMACSHA1", PREFIX + "$PBEWithMacKeyFactory"); provider.addAlgorithm("SecretKeyFactory.PBKDF2WithHmacSHA1", PREFIX + "$PBKDF2WithHmacSHA1UTF8"); provider.addAlgorithm("Alg.Alias.SecretKeyFactory." + PKCSObjectIdentifiers.id_PBKDF2, "PBKDF2WithHmacSHA1"); provider.addAlgorithm("Alg.Alias.SecretKeyFactory.PBKDF2WithHmacSHA1AndUTF8", "PBKDF2WithHmacSHA1"); provider.addAlgorithm("SecretKeyFactory.PBKDF2WithHmacSHA1And8BIT", PREFIX + "$PBKDF2WithHmacSHA18BIT"); } } } bouncycastle-1.49.orig/src/org/bouncycastle/jcajce/provider/digest/RIPEMD320.java0000644000175000017500000000335212114015744027104 0ustar ebourgebourgpackage org.bouncycastle.jcajce.provider.digest; import org.bouncycastle.crypto.CipherKeyGenerator; import org.bouncycastle.crypto.digests.RIPEMD320Digest; import org.bouncycastle.crypto.macs.HMac; import org.bouncycastle.jcajce.provider.config.ConfigurableProvider; import org.bouncycastle.jcajce.provider.symmetric.util.BaseKeyGenerator; import org.bouncycastle.jcajce.provider.symmetric.util.BaseMac; public class RIPEMD320 { private RIPEMD320() { } static public class Digest extends BCMessageDigest implements Cloneable { public Digest() { super(new RIPEMD320Digest()); } public Object clone() throws CloneNotSupportedException { Digest d = (Digest)super.clone(); d.digest = new RIPEMD320Digest((RIPEMD320Digest)digest); return d; } } /** * RIPEMD320 HMac */ public static class HashMac extends BaseMac { public HashMac() { super(new HMac(new RIPEMD320Digest())); } } public static class KeyGenerator extends BaseKeyGenerator { public KeyGenerator() { super("HMACRIPEMD320", 320, new CipherKeyGenerator()); } } public static class Mappings extends DigestAlgorithmProvider { private static final String PREFIX = RIPEMD320.class.getName(); public Mappings() { } public void configure(ConfigurableProvider provider) { provider.addAlgorithm("MessageDigest.RIPEMD320", PREFIX + "$Digest"); addHMACAlgorithm(provider, "RIPEMD320", PREFIX + "$HashMac", PREFIX + "$KeyGenerator"); } } } bouncycastle-1.49.orig/src/org/bouncycastle/jcajce/provider/digest/RIPEMD256.java0000644000175000017500000000364012114015744027114 0ustar ebourgebourgpackage org.bouncycastle.jcajce.provider.digest; import org.bouncycastle.asn1.teletrust.TeleTrusTObjectIdentifiers; import org.bouncycastle.crypto.CipherKeyGenerator; import org.bouncycastle.crypto.digests.RIPEMD256Digest; import org.bouncycastle.crypto.macs.HMac; import org.bouncycastle.jcajce.provider.config.ConfigurableProvider; import org.bouncycastle.jcajce.provider.symmetric.util.BaseKeyGenerator; import org.bouncycastle.jcajce.provider.symmetric.util.BaseMac; public class RIPEMD256 { private RIPEMD256() { } static public class Digest extends BCMessageDigest implements Cloneable { public Digest() { super(new RIPEMD256Digest()); } public Object clone() throws CloneNotSupportedException { Digest d = (Digest)super.clone(); d.digest = new RIPEMD256Digest((RIPEMD256Digest)digest); return d; } } /** * RIPEMD256 HMac */ public static class HashMac extends BaseMac { public HashMac() { super(new HMac(new RIPEMD256Digest())); } } public static class KeyGenerator extends BaseKeyGenerator { public KeyGenerator() { super("HMACRIPEMD256", 256, new CipherKeyGenerator()); } } public static class Mappings extends DigestAlgorithmProvider { private static final String PREFIX = RIPEMD256.class.getName(); public Mappings() { } public void configure(ConfigurableProvider provider) { provider.addAlgorithm("MessageDigest.RIPEMD256", PREFIX + "$Digest"); provider.addAlgorithm("Alg.Alias.MessageDigest." + TeleTrusTObjectIdentifiers.ripemd256, "RIPEMD256"); addHMACAlgorithm(provider, "RIPEMD256", PREFIX + "$HashMac", PREFIX + "$KeyGenerator"); } } } bouncycastle-1.49.orig/src/org/bouncycastle/jcajce/provider/digest/MD4.java0000644000175000017500000000350012114015744026256 0ustar ebourgebourgpackage org.bouncycastle.jcajce.provider.digest; import org.bouncycastle.asn1.pkcs.PKCSObjectIdentifiers; import org.bouncycastle.crypto.CipherKeyGenerator; import org.bouncycastle.crypto.digests.MD4Digest; import org.bouncycastle.crypto.macs.HMac; import org.bouncycastle.jcajce.provider.config.ConfigurableProvider; import org.bouncycastle.jcajce.provider.symmetric.util.BaseKeyGenerator; import org.bouncycastle.jcajce.provider.symmetric.util.BaseMac; public class MD4 { private MD4() { } /** * MD4 HashMac */ public static class HashMac extends BaseMac { public HashMac() { super(new HMac(new MD4Digest())); } } public static class KeyGenerator extends BaseKeyGenerator { public KeyGenerator() { super("HMACMD4", 128, new CipherKeyGenerator()); } } static public class Digest extends BCMessageDigest implements Cloneable { public Digest() { super(new MD4Digest()); } public Object clone() throws CloneNotSupportedException { Digest d = (Digest)super.clone(); d.digest = new MD4Digest((MD4Digest)digest); return d; } } public static class Mappings extends DigestAlgorithmProvider { private static final String PREFIX = MD4.class.getName(); public Mappings() { } public void configure(ConfigurableProvider provider) { provider.addAlgorithm("MessageDigest.MD4", PREFIX + "$Digest"); provider.addAlgorithm("Alg.Alias.MessageDigest." + PKCSObjectIdentifiers.md4, "MD4"); addHMACAlgorithm(provider, "MD4", PREFIX + "$HashMac", PREFIX + "$KeyGenerator"); } } } bouncycastle-1.49.orig/src/org/bouncycastle/jcajce/provider/digest/RIPEMD160.java0000644000175000017500000000576412114015744027117 0ustar ebourgebourgpackage org.bouncycastle.jcajce.provider.digest; import org.bouncycastle.asn1.iana.IANAObjectIdentifiers; import org.bouncycastle.asn1.teletrust.TeleTrusTObjectIdentifiers; import org.bouncycastle.crypto.CipherKeyGenerator; import org.bouncycastle.crypto.digests.RIPEMD160Digest; import org.bouncycastle.crypto.macs.HMac; import org.bouncycastle.jcajce.provider.config.ConfigurableProvider; import org.bouncycastle.jcajce.provider.symmetric.util.BaseKeyGenerator; import org.bouncycastle.jcajce.provider.symmetric.util.BaseMac; import org.bouncycastle.jcajce.provider.symmetric.util.PBESecretKeyFactory; public class RIPEMD160 { private RIPEMD160() { } static public class Digest extends BCMessageDigest implements Cloneable { public Digest() { super(new RIPEMD160Digest()); } public Object clone() throws CloneNotSupportedException { Digest d = (Digest)super.clone(); d.digest = new RIPEMD160Digest((RIPEMD160Digest)digest); return d; } } /** * RIPEMD160 HMac */ public static class HashMac extends BaseMac { public HashMac() { super(new HMac(new RIPEMD160Digest())); } } public static class KeyGenerator extends BaseKeyGenerator { public KeyGenerator() { super("HMACRIPEMD160", 160, new CipherKeyGenerator()); } } // // PKCS12 states that the same algorithm should be used // for the key generation as is used in the HMAC, so that // is what we do here. // /** * PBEWithHmacRIPEMD160 */ public static class PBEWithHmac extends BaseMac { public PBEWithHmac() { super(new HMac(new RIPEMD160Digest()), PKCS12, RIPEMD160, 160); } } /** * PBEWithHmacRIPEMD160 */ public static class PBEWithHmacKeyFactory extends PBESecretKeyFactory { public PBEWithHmacKeyFactory() { super("PBEwithHmacRIPEMD160", null, false, PKCS12, RIPEMD160, 160, 0); } } public static class Mappings extends DigestAlgorithmProvider { private static final String PREFIX = RIPEMD160.class.getName(); public Mappings() { } public void configure(ConfigurableProvider provider) { provider.addAlgorithm("MessageDigest.RIPEMD160", PREFIX + "$Digest"); provider.addAlgorithm("Alg.Alias.MessageDigest." + TeleTrusTObjectIdentifiers.ripemd160, "RIPEMD160"); addHMACAlgorithm(provider, "RIPEMD160", PREFIX + "$HashMac", PREFIX + "$KeyGenerator"); addHMACAlias(provider, "RIPEMD160", IANAObjectIdentifiers.hmacRIPEMD160); provider.addAlgorithm("SecretKeyFactory.PBEWITHHMACRIPEMD160", PREFIX + "$PBEWithHmacKeyFactory"); provider.addAlgorithm("Mac.PBEWITHHMACRIPEMD160", PREFIX + "$PBEWithHmac"); } } } bouncycastle-1.49.orig/src/org/bouncycastle/jcajce/provider/digest/RIPEMD128.java0000644000175000017500000000365712114015744027122 0ustar ebourgebourgpackage org.bouncycastle.jcajce.provider.digest; import org.bouncycastle.asn1.teletrust.TeleTrusTObjectIdentifiers; import org.bouncycastle.crypto.CipherKeyGenerator; import org.bouncycastle.crypto.digests.RIPEMD128Digest; import org.bouncycastle.crypto.macs.HMac; import org.bouncycastle.jcajce.provider.config.ConfigurableProvider; import org.bouncycastle.jcajce.provider.symmetric.util.BaseKeyGenerator; import org.bouncycastle.jcajce.provider.symmetric.util.BaseMac; public class RIPEMD128 { private RIPEMD128() { } static public class Digest extends BCMessageDigest implements Cloneable { public Digest() { super(new RIPEMD128Digest()); } public Object clone() throws CloneNotSupportedException { Digest d = (Digest)super.clone(); d.digest = new RIPEMD128Digest((RIPEMD128Digest)digest); return d; } } /** * RIPEMD128 HashMac */ public static class HashMac extends BaseMac { public HashMac() { super(new HMac(new RIPEMD128Digest())); } } public static class KeyGenerator extends BaseKeyGenerator { public KeyGenerator() { super("HMACRIPEMD128", 128, new CipherKeyGenerator()); } } public static class Mappings extends DigestAlgorithmProvider { private static final String PREFIX = RIPEMD128.class.getName(); public Mappings() { } public void configure(ConfigurableProvider provider) { provider.addAlgorithm("MessageDigest.RIPEMD128", PREFIX + "$Digest"); provider.addAlgorithm("Alg.Alias.MessageDigest." + TeleTrusTObjectIdentifiers.ripemd128, "RIPEMD128"); addHMACAlgorithm(provider, "RIPEMD128", PREFIX + "$HashMac", PREFIX + "$KeyGenerator"); } } } bouncycastle-1.49.orig/src/org/bouncycastle/jcajce/provider/digest/SHA256.java0000644000175000017500000000550012151274313026544 0ustar ebourgebourgpackage org.bouncycastle.jcajce.provider.digest; import org.bouncycastle.asn1.nist.NISTObjectIdentifiers; import org.bouncycastle.asn1.pkcs.PKCSObjectIdentifiers; import org.bouncycastle.crypto.CipherKeyGenerator; import org.bouncycastle.crypto.digests.SHA256Digest; import org.bouncycastle.crypto.macs.HMac; import org.bouncycastle.jcajce.provider.config.ConfigurableProvider; import org.bouncycastle.jcajce.provider.symmetric.util.BaseKeyGenerator; import org.bouncycastle.jcajce.provider.symmetric.util.BaseMac; import org.bouncycastle.jcajce.provider.symmetric.util.PBESecretKeyFactory; public class SHA256 { private SHA256() { } static public class Digest extends BCMessageDigest implements Cloneable { public Digest() { super(new SHA256Digest()); } public Object clone() throws CloneNotSupportedException { Digest d = (Digest)super.clone(); d.digest = new SHA256Digest((SHA256Digest)digest); return d; } } public static class HashMac extends BaseMac { public HashMac() { super(new HMac(new SHA256Digest())); } } /** * PBEWithHmacSHA */ public static class PBEWithMacKeyFactory extends PBESecretKeyFactory { public PBEWithMacKeyFactory() { super("PBEwithHmacSHA256", null, false, PKCS12, SHA256, 256, 0); } } /** * HMACSHA256 */ public static class KeyGenerator extends BaseKeyGenerator { public KeyGenerator() { super("HMACSHA256", 256, new CipherKeyGenerator()); } } public static class Mappings extends DigestAlgorithmProvider { private static final String PREFIX = SHA256.class.getName(); public Mappings() { } public void configure(ConfigurableProvider provider) { provider.addAlgorithm("MessageDigest.SHA-256", PREFIX + "$Digest"); provider.addAlgorithm("Alg.Alias.MessageDigest.SHA256", "SHA-256"); provider.addAlgorithm("Alg.Alias.MessageDigest." + NISTObjectIdentifiers.id_sha256, "SHA-256"); provider.addAlgorithm("SecretKeyFactory.PBEWITHHMACSHA256", PREFIX + "$PBEWithMacKeyFactory"); provider.addAlgorithm("Alg.Alias.SecretKeyFactory.PBEWITHHMACSHA-256", "PBEWITHHMACSHA256"); provider.addAlgorithm("Alg.Alias.SecretKeyFactory." + NISTObjectIdentifiers.id_sha256, "PBEWITHHMACSHA256"); addHMACAlgorithm(provider, "SHA256", PREFIX + "$HashMac", PREFIX + "$KeyGenerator"); addHMACAlias(provider, "SHA256", PKCSObjectIdentifiers.id_hmacWithSHA256); addHMACAlias(provider, "SHA256", NISTObjectIdentifiers.id_sha256); } } } bouncycastle-1.49.orig/src/org/bouncycastle/jcajce/provider/digest/Whirlpool.java0000644000175000017500000000334612114014605027654 0ustar ebourgebourgpackage org.bouncycastle.jcajce.provider.digest; import org.bouncycastle.crypto.CipherKeyGenerator; import org.bouncycastle.crypto.digests.WhirlpoolDigest; import org.bouncycastle.crypto.macs.HMac; import org.bouncycastle.jcajce.provider.config.ConfigurableProvider; import org.bouncycastle.jcajce.provider.symmetric.util.BaseKeyGenerator; import org.bouncycastle.jcajce.provider.symmetric.util.BaseMac; public class Whirlpool { private Whirlpool() { } static public class Digest extends BCMessageDigest implements Cloneable { public Digest() { super(new WhirlpoolDigest()); } public Object clone() throws CloneNotSupportedException { Digest d = (Digest)super.clone(); d.digest = new WhirlpoolDigest((WhirlpoolDigest)digest); return d; } } /** * Tiger HMac */ public static class HashMac extends BaseMac { public HashMac() { super(new HMac(new WhirlpoolDigest())); } } public static class KeyGenerator extends BaseKeyGenerator { public KeyGenerator() { super("HMACWHIRLPOOL", 512, new CipherKeyGenerator()); } } public static class Mappings extends DigestAlgorithmProvider { private static final String PREFIX = Whirlpool.class.getName(); public Mappings() { } public void configure(ConfigurableProvider provider) { provider.addAlgorithm("MessageDigest.WHIRLPOOL", PREFIX + "$Digest"); addHMACAlgorithm(provider, "WHIRLPOOL", PREFIX + "$HashMac", PREFIX + "$KeyGenerator"); } } } bouncycastle-1.49.orig/src/org/bouncycastle/jcajce/provider/symmetric/0000755000175000017500000000000012152033551025564 5ustar ebourgebourgbouncycastle-1.49.orig/src/org/bouncycastle/jcajce/provider/symmetric/Blowfish.java0000644000175000017500000000413311701431716030211 0ustar ebourgebourgpackage org.bouncycastle.jcajce.provider.symmetric; import org.bouncycastle.crypto.CipherKeyGenerator; import org.bouncycastle.crypto.engines.BlowfishEngine; import org.bouncycastle.crypto.modes.CBCBlockCipher; import org.bouncycastle.jcajce.provider.config.ConfigurableProvider; import org.bouncycastle.jcajce.provider.symmetric.util.BaseBlockCipher; import org.bouncycastle.jcajce.provider.symmetric.util.BaseKeyGenerator; import org.bouncycastle.jcajce.provider.symmetric.util.IvAlgorithmParameters; import org.bouncycastle.jcajce.provider.util.AlgorithmProvider; public final class Blowfish { private Blowfish() { } public static class ECB extends BaseBlockCipher { public ECB() { super(new BlowfishEngine()); } } public static class CBC extends BaseBlockCipher { public CBC() { super(new CBCBlockCipher(new BlowfishEngine()), 64); } } public static class KeyGen extends BaseKeyGenerator { public KeyGen() { super("Blowfish", 128, new CipherKeyGenerator()); } } public static class AlgParams extends IvAlgorithmParameters { protected String engineToString() { return "Blowfish IV"; } } public static class Mappings extends AlgorithmProvider { private static final String PREFIX = Blowfish.class.getName(); public Mappings() { } public void configure(ConfigurableProvider provider) { provider.addAlgorithm("Cipher.BLOWFISH", PREFIX + "$ECB"); provider.addAlgorithm("Cipher.1.3.6.1.4.1.3029.1.2", PREFIX + "$CBC"); provider.addAlgorithm("KeyGenerator.BLOWFISH", PREFIX + "$KeyGen"); provider.addAlgorithm("Alg.Alias.KeyGenerator.1.3.6.1.4.1.3029.1.2", "BLOWFISH"); provider.addAlgorithm("AlgorithmParameters.BLOWFISH", PREFIX + "$AlgParams"); provider.addAlgorithm("Alg.Alias.AlgorithmParameters.1.3.6.1.4.1.3029.1.2", "BLOWFISH"); } } } bouncycastle-1.49.orig/src/org/bouncycastle/jcajce/provider/symmetric/Rijndael.java0000644000175000017500000000356412132366003030166 0ustar ebourgebourgpackage org.bouncycastle.jcajce.provider.symmetric; import org.bouncycastle.crypto.BlockCipher; import org.bouncycastle.crypto.CipherKeyGenerator; import org.bouncycastle.crypto.engines.RijndaelEngine; import org.bouncycastle.jcajce.provider.config.ConfigurableProvider; import org.bouncycastle.jcajce.provider.symmetric.util.BaseBlockCipher; import org.bouncycastle.jcajce.provider.symmetric.util.BaseKeyGenerator; import org.bouncycastle.jcajce.provider.symmetric.util.BlockCipherProvider; import org.bouncycastle.jcajce.provider.symmetric.util.IvAlgorithmParameters; import org.bouncycastle.jcajce.provider.util.AlgorithmProvider; public final class Rijndael { private Rijndael() { } public static class ECB extends BaseBlockCipher { public ECB() { super(new BlockCipherProvider() { public BlockCipher get() { return new RijndaelEngine(); } }); } } public static class KeyGen extends BaseKeyGenerator { public KeyGen() { super("Rijndael", 192, new CipherKeyGenerator()); } } public static class AlgParams extends IvAlgorithmParameters { protected String engineToString() { return "Rijndael IV"; } } public static class Mappings extends AlgorithmProvider { private static final String PREFIX = Rijndael.class.getName(); public Mappings() { } public void configure(ConfigurableProvider provider) { provider.addAlgorithm("Cipher.RIJNDAEL", PREFIX + "$ECB"); provider.addAlgorithm("KeyGenerator.RIJNDAEL", PREFIX + "$KeyGen"); provider.addAlgorithm("AlgorithmParameters.RIJNDAEL", PREFIX + "$AlgParams"); } } } bouncycastle-1.49.orig/src/org/bouncycastle/jcajce/provider/symmetric/Serpent.java0000644000175000017500000000436212146275676030077 0ustar ebourgebourgpackage org.bouncycastle.jcajce.provider.symmetric; import org.bouncycastle.crypto.BlockCipher; import org.bouncycastle.crypto.CipherKeyGenerator; import org.bouncycastle.crypto.engines.SerpentEngine; import org.bouncycastle.crypto.macs.GMac; import org.bouncycastle.crypto.modes.GCMBlockCipher; import org.bouncycastle.jcajce.provider.config.ConfigurableProvider; import org.bouncycastle.jcajce.provider.symmetric.util.BaseBlockCipher; import org.bouncycastle.jcajce.provider.symmetric.util.BaseKeyGenerator; import org.bouncycastle.jcajce.provider.symmetric.util.BaseMac; import org.bouncycastle.jcajce.provider.symmetric.util.BlockCipherProvider; import org.bouncycastle.jcajce.provider.symmetric.util.IvAlgorithmParameters; public final class Serpent { private Serpent() { } public static class ECB extends BaseBlockCipher { public ECB() { super(new BlockCipherProvider() { public BlockCipher get() { return new SerpentEngine(); } }); } } public static class KeyGen extends BaseKeyGenerator { public KeyGen() { super("Serpent", 192, new CipherKeyGenerator()); } } public static class SerpentGMAC extends BaseMac { public SerpentGMAC() { super(new GMac(new GCMBlockCipher(new SerpentEngine()))); } } public static class AlgParams extends IvAlgorithmParameters { protected String engineToString() { return "Serpent IV"; } } public static class Mappings extends SymmetricAlgorithmProvider { private static final String PREFIX = Serpent.class.getName(); public Mappings() { } public void configure(ConfigurableProvider provider) { provider.addAlgorithm("Cipher.Serpent", PREFIX + "$ECB"); provider.addAlgorithm("KeyGenerator.Serpent", PREFIX + "$KeyGen"); provider.addAlgorithm("AlgorithmParameters.Serpent", PREFIX + "$AlgParams"); addGMacAlgorithm(provider, "SERPENT", PREFIX + "$SerpentGMAC", PREFIX + "$KeyGen"); } } } bouncycastle-1.49.orig/src/org/bouncycastle/jcajce/provider/symmetric/util/0000755000175000017500000000000012152033551026541 5ustar ebourgebourg././@LongLink0000000000000000000000000000014600000000000011566 Lustar rootrootbouncycastle-1.49.orig/src/org/bouncycastle/jcajce/provider/symmetric/util/IvAlgorithmParameters.javabouncycastle-1.49.orig/src/org/bouncycastle/jcajce/provider/symmetric/util/IvAlgorithmParameters.jav0000644000175000017500000000567611624600531033533 0ustar ebourgebourgpackage org.bouncycastle.jcajce.provider.symmetric.util; import java.io.IOException; import java.security.spec.AlgorithmParameterSpec; import java.security.spec.InvalidParameterSpecException; import javax.crypto.spec.IvParameterSpec; import org.bouncycastle.asn1.ASN1OctetString; import org.bouncycastle.asn1.ASN1Primitive; import org.bouncycastle.asn1.DEROctetString; import org.bouncycastle.util.Arrays; public class IvAlgorithmParameters extends BaseAlgorithmParameters { private byte[] iv; protected byte[] engineGetEncoded() throws IOException { return engineGetEncoded("ASN.1"); } protected byte[] engineGetEncoded( String format) throws IOException { if (isASN1FormatString(format)) { return new DEROctetString(engineGetEncoded("RAW")).getEncoded(); } if (format.equals("RAW")) { return Arrays.clone(iv); } return null; } protected AlgorithmParameterSpec localEngineGetParameterSpec( Class paramSpec) throws InvalidParameterSpecException { if (paramSpec == IvParameterSpec.class) { return new IvParameterSpec(iv); } throw new InvalidParameterSpecException("unknown parameter spec passed to IV parameters object."); } protected void engineInit( AlgorithmParameterSpec paramSpec) throws InvalidParameterSpecException { if (!(paramSpec instanceof IvParameterSpec)) { throw new InvalidParameterSpecException("IvParameterSpec required to initialise a IV parameters algorithm parameters object"); } this.iv = ((IvParameterSpec)paramSpec).getIV(); } protected void engineInit( byte[] params) throws IOException { // // check that we don't have a DER encoded octet string // if ((params.length % 8) != 0 && params[0] == 0x04 && params[1] == params.length - 2) { ASN1OctetString oct = (ASN1OctetString)ASN1Primitive.fromByteArray(params); params = oct.getOctets(); } this.iv = Arrays.clone(params); } protected void engineInit( byte[] params, String format) throws IOException { if (isASN1FormatString(format)) { try { ASN1OctetString oct = (ASN1OctetString)ASN1Primitive.fromByteArray(params); engineInit(oct.getOctets()); } catch (Exception e) { throw new IOException("Exception decoding: " + e); } return; } if (format.equals("RAW")) { engineInit(params); return; } throw new IOException("Unknown parameters format in IV parameters object"); } protected String engineToString() { return "IV Parameters"; } } bouncycastle-1.49.orig/src/org/bouncycastle/jcajce/provider/symmetric/util/BaseBlockCipher.java0000644000175000017500000007203512131461467032403 0ustar ebourgebourgpackage org.bouncycastle.jcajce.provider.symmetric.util; import java.security.AlgorithmParameters; import java.security.InvalidAlgorithmParameterException; import java.security.InvalidKeyException; import java.security.InvalidParameterException; import java.security.Key; import java.security.NoSuchAlgorithmException; import java.security.SecureRandom; import java.security.spec.AlgorithmParameterSpec; import javax.crypto.BadPaddingException; import javax.crypto.Cipher; import javax.crypto.IllegalBlockSizeException; import javax.crypto.NoSuchPaddingException; import javax.crypto.SecretKey; import javax.crypto.ShortBufferException; import javax.crypto.spec.IvParameterSpec; import javax.crypto.spec.PBEParameterSpec; import javax.crypto.spec.RC2ParameterSpec; import javax.crypto.spec.RC5ParameterSpec; import org.bouncycastle.crypto.BlockCipher; import org.bouncycastle.crypto.BufferedBlockCipher; import org.bouncycastle.crypto.CipherParameters; import org.bouncycastle.crypto.DataLengthException; import org.bouncycastle.crypto.InvalidCipherTextException; import org.bouncycastle.crypto.OutputLengthException; import org.bouncycastle.crypto.modes.AEADBlockCipher; import org.bouncycastle.crypto.modes.CBCBlockCipher; import org.bouncycastle.crypto.modes.CCMBlockCipher; import org.bouncycastle.crypto.modes.CFBBlockCipher; import org.bouncycastle.crypto.modes.CTSBlockCipher; import org.bouncycastle.crypto.modes.EAXBlockCipher; import org.bouncycastle.crypto.modes.GCMBlockCipher; import org.bouncycastle.crypto.modes.GOFBBlockCipher; import org.bouncycastle.crypto.modes.OCBBlockCipher; import org.bouncycastle.crypto.modes.OFBBlockCipher; import org.bouncycastle.crypto.modes.OpenPGPCFBBlockCipher; import org.bouncycastle.crypto.modes.PGPCFBBlockCipher; import org.bouncycastle.crypto.modes.SICBlockCipher; import org.bouncycastle.crypto.paddings.BlockCipherPadding; import org.bouncycastle.crypto.paddings.ISO10126d2Padding; import org.bouncycastle.crypto.paddings.ISO7816d4Padding; import org.bouncycastle.crypto.paddings.PaddedBufferedBlockCipher; import org.bouncycastle.crypto.paddings.TBCPadding; import org.bouncycastle.crypto.paddings.X923Padding; import org.bouncycastle.crypto.paddings.ZeroBytePadding; import org.bouncycastle.crypto.params.KeyParameter; import org.bouncycastle.crypto.params.ParametersWithIV; import org.bouncycastle.crypto.params.ParametersWithRandom; import org.bouncycastle.crypto.params.ParametersWithSBox; import org.bouncycastle.crypto.params.RC2Parameters; import org.bouncycastle.crypto.params.RC5Parameters; import org.bouncycastle.jce.provider.BouncyCastleProvider; import org.bouncycastle.jce.spec.GOST28147ParameterSpec; import org.bouncycastle.jce.spec.RepeatedSecretKeySpec; import org.bouncycastle.util.Strings; public class BaseBlockCipher extends BaseWrapCipher implements PBE { // // specs we can handle. // private Class[] availableSpecs = { RC2ParameterSpec.class, RC5ParameterSpec.class, IvParameterSpec.class, PBEParameterSpec.class, GOST28147ParameterSpec.class }; private BlockCipher baseEngine; private BlockCipherProvider engineProvider; private GenericBlockCipher cipher; private ParametersWithIV ivParam; private int ivLength = 0; private boolean padded; private PBEParameterSpec pbeSpec = null; private String pbeAlgorithm = null; private String modeName = null; protected BaseBlockCipher( BlockCipher engine) { baseEngine = engine; cipher = new BufferedGenericBlockCipher(engine); } protected BaseBlockCipher( BlockCipherProvider provider) { baseEngine = provider.get(); engineProvider = provider; cipher = new BufferedGenericBlockCipher(provider.get()); } protected BaseBlockCipher( org.bouncycastle.crypto.BlockCipher engine, int ivLength) { baseEngine = engine; this.cipher = new BufferedGenericBlockCipher(engine); this.ivLength = ivLength / 8; } protected BaseBlockCipher( BufferedBlockCipher engine, int ivLength) { baseEngine = engine.getUnderlyingCipher(); this.cipher = new BufferedGenericBlockCipher(engine); this.ivLength = ivLength / 8; } protected int engineGetBlockSize() { return baseEngine.getBlockSize(); } protected byte[] engineGetIV() { return (ivParam != null) ? ivParam.getIV() : null; } protected int engineGetKeySize( Key key) { return key.getEncoded().length * 8; } protected int engineGetOutputSize( int inputLen) { return cipher.getOutputSize(inputLen); } protected AlgorithmParameters engineGetParameters() { if (engineParams == null) { if (pbeSpec != null) { try { engineParams = AlgorithmParameters.getInstance(pbeAlgorithm, BouncyCastleProvider.PROVIDER_NAME); engineParams.init(pbeSpec); } catch (Exception e) { return null; } } else if (ivParam != null) { String name = cipher.getUnderlyingCipher().getAlgorithmName(); if (name.indexOf('/') >= 0) { name = name.substring(0, name.indexOf('/')); } try { engineParams = AlgorithmParameters.getInstance(name, BouncyCastleProvider.PROVIDER_NAME); engineParams.init(ivParam.getIV()); } catch (Exception e) { throw new RuntimeException(e.toString()); } } } return engineParams; } protected void engineSetMode( String mode) throws NoSuchAlgorithmException { modeName = Strings.toUpperCase(mode); if (modeName.equals("ECB")) { ivLength = 0; cipher = new BufferedGenericBlockCipher(baseEngine); } else if (modeName.equals("CBC")) { ivLength = baseEngine.getBlockSize(); cipher = new BufferedGenericBlockCipher( new CBCBlockCipher(baseEngine)); } else if (modeName.startsWith("OFB")) { ivLength = baseEngine.getBlockSize(); if (modeName.length() != 3) { int wordSize = Integer.parseInt(modeName.substring(3)); cipher = new BufferedGenericBlockCipher( new OFBBlockCipher(baseEngine, wordSize)); } else { cipher = new BufferedGenericBlockCipher( new OFBBlockCipher(baseEngine, 8 * baseEngine.getBlockSize())); } } else if (modeName.startsWith("CFB")) { ivLength = baseEngine.getBlockSize(); if (modeName.length() != 3) { int wordSize = Integer.parseInt(modeName.substring(3)); cipher = new BufferedGenericBlockCipher( new CFBBlockCipher(baseEngine, wordSize)); } else { cipher = new BufferedGenericBlockCipher( new CFBBlockCipher(baseEngine, 8 * baseEngine.getBlockSize())); } } else if (modeName.startsWith("PGP")) { boolean inlineIV = modeName.equalsIgnoreCase("PGPCFBwithIV"); ivLength = baseEngine.getBlockSize(); cipher = new BufferedGenericBlockCipher( new PGPCFBBlockCipher(baseEngine, inlineIV)); } else if (modeName.equalsIgnoreCase("OpenPGPCFB")) { ivLength = 0; cipher = new BufferedGenericBlockCipher( new OpenPGPCFBBlockCipher(baseEngine)); } else if (modeName.startsWith("SIC")) { ivLength = baseEngine.getBlockSize(); if (ivLength < 16) { throw new IllegalArgumentException("Warning: SIC-Mode can become a twotime-pad if the blocksize of the cipher is too small. Use a cipher with a block size of at least 128 bits (e.g. AES)"); } cipher = new BufferedGenericBlockCipher(new BufferedBlockCipher( new SICBlockCipher(baseEngine))); } else if (modeName.startsWith("CTR")) { ivLength = baseEngine.getBlockSize(); cipher = new BufferedGenericBlockCipher(new BufferedBlockCipher( new SICBlockCipher(baseEngine))); } else if (modeName.startsWith("GOFB")) { ivLength = baseEngine.getBlockSize(); cipher = new BufferedGenericBlockCipher(new BufferedBlockCipher( new GOFBBlockCipher(baseEngine))); } else if (modeName.startsWith("CTS")) { ivLength = baseEngine.getBlockSize(); cipher = new BufferedGenericBlockCipher(new CTSBlockCipher(new CBCBlockCipher(baseEngine))); } else if (modeName.startsWith("CCM")) { ivLength = baseEngine.getBlockSize(); cipher = new AEADGenericBlockCipher(new CCMBlockCipher(baseEngine)); } else if (modeName.startsWith("OCB")) { if (engineProvider != null) { ivLength = baseEngine.getBlockSize(); cipher = new AEADGenericBlockCipher(new OCBBlockCipher(baseEngine, engineProvider.get())); } else { throw new NoSuchAlgorithmException("can't support mode " + mode); } } else if (modeName.startsWith("EAX")) { ivLength = baseEngine.getBlockSize(); cipher = new AEADGenericBlockCipher(new EAXBlockCipher(baseEngine)); } else if (modeName.startsWith("GCM")) { ivLength = baseEngine.getBlockSize(); cipher = new AEADGenericBlockCipher(new GCMBlockCipher(baseEngine)); } else { throw new NoSuchAlgorithmException("can't support mode " + mode); } } protected void engineSetPadding( String padding) throws NoSuchPaddingException { String paddingName = Strings.toUpperCase(padding); if (paddingName.equals("NOPADDING")) { if (cipher.wrapOnNoPadding()) { cipher = new BufferedGenericBlockCipher(new BufferedBlockCipher(cipher.getUnderlyingCipher())); } } else if (paddingName.equals("WITHCTS")) { cipher = new BufferedGenericBlockCipher(new CTSBlockCipher(cipher.getUnderlyingCipher())); } else { padded = true; if (isAEADModeName(modeName)) { throw new NoSuchPaddingException("Only NoPadding can be used with AEAD modes."); } else if (paddingName.equals("PKCS5PADDING") || paddingName.equals("PKCS7PADDING")) { cipher = new BufferedGenericBlockCipher(cipher.getUnderlyingCipher()); } else if (paddingName.equals("ZEROBYTEPADDING")) { cipher = new BufferedGenericBlockCipher(cipher.getUnderlyingCipher(), new ZeroBytePadding()); } else if (paddingName.equals("ISO10126PADDING") || paddingName.equals("ISO10126-2PADDING")) { cipher = new BufferedGenericBlockCipher(cipher.getUnderlyingCipher(), new ISO10126d2Padding()); } else if (paddingName.equals("X9.23PADDING") || paddingName.equals("X923PADDING")) { cipher = new BufferedGenericBlockCipher(cipher.getUnderlyingCipher(), new X923Padding()); } else if (paddingName.equals("ISO7816-4PADDING") || paddingName.equals("ISO9797-1PADDING")) { cipher = new BufferedGenericBlockCipher(cipher.getUnderlyingCipher(), new ISO7816d4Padding()); } else if (paddingName.equals("TBCPADDING")) { cipher = new BufferedGenericBlockCipher(cipher.getUnderlyingCipher(), new TBCPadding()); } else { throw new NoSuchPaddingException("Padding " + padding + " unknown."); } } } protected void engineInit( int opmode, Key key, AlgorithmParameterSpec params, SecureRandom random) throws InvalidKeyException, InvalidAlgorithmParameterException { CipherParameters param; this.pbeSpec = null; this.pbeAlgorithm = null; this.engineParams = null; // // basic key check // if (!(key instanceof SecretKey)) { throw new InvalidKeyException("Key for algorithm " + key.getAlgorithm() + " not suitable for symmetric enryption."); } // // for RC5-64 we must have some default parameters // if (params == null && baseEngine.getAlgorithmName().startsWith("RC5-64")) { throw new InvalidAlgorithmParameterException("RC5 requires an RC5ParametersSpec to be passed in."); } // // a note on iv's - if ivLength is zero the IV gets ignored (we don't use it). // if (key instanceof BCPBEKey) { BCPBEKey k = (BCPBEKey)key; if (k.getOID() != null) { pbeAlgorithm = k.getOID().getId(); } else { pbeAlgorithm = k.getAlgorithm(); } if (k.getParam() != null) { param = k.getParam(); if (params instanceof IvParameterSpec) { IvParameterSpec iv = (IvParameterSpec)params; param = new ParametersWithIV(param, iv.getIV()); } } else if (params instanceof PBEParameterSpec) { pbeSpec = (PBEParameterSpec)params; param = PBE.Util.makePBEParameters(k, params, cipher.getUnderlyingCipher().getAlgorithmName()); } else { throw new InvalidAlgorithmParameterException("PBE requires PBE parameters to be set."); } if (param instanceof ParametersWithIV) { ivParam = (ParametersWithIV)param; } } else if (params == null) { param = new KeyParameter(key.getEncoded()); } else if (params instanceof IvParameterSpec) { if (ivLength != 0) { IvParameterSpec p = (IvParameterSpec)params; if (p.getIV().length != ivLength && !isAEADModeName(modeName)) { throw new InvalidAlgorithmParameterException("IV must be " + ivLength + " bytes long."); } if (key instanceof RepeatedSecretKeySpec) { param = new ParametersWithIV(null, p.getIV()); ivParam = (ParametersWithIV)param; } else { param = new ParametersWithIV(new KeyParameter(key.getEncoded()), p.getIV()); ivParam = (ParametersWithIV)param; } } else { if (modeName != null && modeName.equals("ECB")) { throw new InvalidAlgorithmParameterException("ECB mode does not use an IV"); } param = new KeyParameter(key.getEncoded()); } } else if (params instanceof GOST28147ParameterSpec) { GOST28147ParameterSpec gost28147Param = (GOST28147ParameterSpec)params; param = new ParametersWithSBox( new KeyParameter(key.getEncoded()), ((GOST28147ParameterSpec)params).getSbox()); if (gost28147Param.getIV() != null && ivLength != 0) { param = new ParametersWithIV(param, gost28147Param.getIV()); ivParam = (ParametersWithIV)param; } } else if (params instanceof RC2ParameterSpec) { RC2ParameterSpec rc2Param = (RC2ParameterSpec)params; param = new RC2Parameters(key.getEncoded(), ((RC2ParameterSpec)params).getEffectiveKeyBits()); if (rc2Param.getIV() != null && ivLength != 0) { param = new ParametersWithIV(param, rc2Param.getIV()); ivParam = (ParametersWithIV)param; } } else if (params instanceof RC5ParameterSpec) { RC5ParameterSpec rc5Param = (RC5ParameterSpec)params; param = new RC5Parameters(key.getEncoded(), ((RC5ParameterSpec)params).getRounds()); if (baseEngine.getAlgorithmName().startsWith("RC5")) { if (baseEngine.getAlgorithmName().equals("RC5-32")) { if (rc5Param.getWordSize() != 32) { throw new InvalidAlgorithmParameterException("RC5 already set up for a word size of 32 not " + rc5Param.getWordSize() + "."); } } else if (baseEngine.getAlgorithmName().equals("RC5-64")) { if (rc5Param.getWordSize() != 64) { throw new InvalidAlgorithmParameterException("RC5 already set up for a word size of 64 not " + rc5Param.getWordSize() + "."); } } } else { throw new InvalidAlgorithmParameterException("RC5 parameters passed to a cipher that is not RC5."); } if ((rc5Param.getIV() != null) && (ivLength != 0)) { param = new ParametersWithIV(param, rc5Param.getIV()); ivParam = (ParametersWithIV)param; } } else { throw new InvalidAlgorithmParameterException("unknown parameter type."); } if ((ivLength != 0) && !(param instanceof ParametersWithIV)) { SecureRandom ivRandom = random; if (ivRandom == null) { ivRandom = new SecureRandom(); } if ((opmode == Cipher.ENCRYPT_MODE) || (opmode == Cipher.WRAP_MODE)) { byte[] iv = new byte[ivLength]; ivRandom.nextBytes(iv); param = new ParametersWithIV(param, iv); ivParam = (ParametersWithIV)param; } else if (cipher.getUnderlyingCipher().getAlgorithmName().indexOf("PGPCFB") < 0) { throw new InvalidAlgorithmParameterException("no IV set when one expected"); } } if (random != null && padded) { param = new ParametersWithRandom(param, random); } try { switch (opmode) { case Cipher.ENCRYPT_MODE: case Cipher.WRAP_MODE: cipher.init(true, param); break; case Cipher.DECRYPT_MODE: case Cipher.UNWRAP_MODE: cipher.init(false, param); break; default: throw new InvalidParameterException("unknown opmode " + opmode + " passed"); } } catch (Exception e) { throw new InvalidKeyException(e.getMessage()); } } protected void engineInit( int opmode, Key key, AlgorithmParameters params, SecureRandom random) throws InvalidKeyException, InvalidAlgorithmParameterException { AlgorithmParameterSpec paramSpec = null; if (params != null) { for (int i = 0; i != availableSpecs.length; i++) { try { paramSpec = params.getParameterSpec(availableSpecs[i]); break; } catch (Exception e) { // try again if possible } } if (paramSpec == null) { throw new InvalidAlgorithmParameterException("can't handle parameter " + params.toString()); } } engineInit(opmode, key, paramSpec, random); engineParams = params; } protected void engineInit( int opmode, Key key, SecureRandom random) throws InvalidKeyException { try { engineInit(opmode, key, (AlgorithmParameterSpec)null, random); } catch (InvalidAlgorithmParameterException e) { throw new InvalidKeyException(e.getMessage()); } } protected byte[] engineUpdate( byte[] input, int inputOffset, int inputLen) { int length = cipher.getUpdateOutputSize(inputLen); if (length > 0) { byte[] out = new byte[length]; int len = cipher.processBytes(input, inputOffset, inputLen, out, 0); if (len == 0) { return null; } else if (len != out.length) { byte[] tmp = new byte[len]; System.arraycopy(out, 0, tmp, 0, len); return tmp; } return out; } cipher.processBytes(input, inputOffset, inputLen, null, 0); return null; } protected int engineUpdate( byte[] input, int inputOffset, int inputLen, byte[] output, int outputOffset) throws ShortBufferException { try { return cipher.processBytes(input, inputOffset, inputLen, output, outputOffset); } catch (DataLengthException e) { throw new ShortBufferException(e.getMessage()); } } protected byte[] engineDoFinal( byte[] input, int inputOffset, int inputLen) throws IllegalBlockSizeException, BadPaddingException { int len = 0; byte[] tmp = new byte[engineGetOutputSize(inputLen)]; if (inputLen != 0) { len = cipher.processBytes(input, inputOffset, inputLen, tmp, 0); } try { len += cipher.doFinal(tmp, len); } catch (DataLengthException e) { throw new IllegalBlockSizeException(e.getMessage()); } catch (InvalidCipherTextException e) { throw new BadPaddingException(e.getMessage()); } if (len == tmp.length) { return tmp; } byte[] out = new byte[len]; System.arraycopy(tmp, 0, out, 0, len); return out; } protected int engineDoFinal( byte[] input, int inputOffset, int inputLen, byte[] output, int outputOffset) throws IllegalBlockSizeException, BadPaddingException, ShortBufferException { try { int len = 0; if (inputLen != 0) { len = cipher.processBytes(input, inputOffset, inputLen, output, outputOffset); } return (len + cipher.doFinal(output, outputOffset + len)); } catch (OutputLengthException e) { throw new ShortBufferException(e.getMessage()); } catch (DataLengthException e) { throw new IllegalBlockSizeException(e.getMessage()); } catch (InvalidCipherTextException e) { throw new BadPaddingException(e.getMessage()); } } private boolean isAEADModeName( String modeName) { return "CCM".equals(modeName) || "EAX".equals(modeName) || "GCM".equals(modeName) || "OCB".equals(modeName); } /* * The ciphers that inherit from us. */ static private interface GenericBlockCipher { public void init(boolean forEncryption, CipherParameters params) throws IllegalArgumentException; public boolean wrapOnNoPadding(); public String getAlgorithmName(); public org.bouncycastle.crypto.BlockCipher getUnderlyingCipher(); public int getOutputSize(int len); public int getUpdateOutputSize(int len); public int processByte(byte in, byte[] out, int outOff) throws DataLengthException; public int processBytes(byte[] in, int inOff, int len, byte[] out, int outOff) throws DataLengthException; public int doFinal(byte[] out, int outOff) throws IllegalStateException, InvalidCipherTextException; } private static class BufferedGenericBlockCipher implements GenericBlockCipher { private BufferedBlockCipher cipher; BufferedGenericBlockCipher(BufferedBlockCipher cipher) { this.cipher = cipher; } BufferedGenericBlockCipher(org.bouncycastle.crypto.BlockCipher cipher) { this.cipher = new PaddedBufferedBlockCipher(cipher); } BufferedGenericBlockCipher(org.bouncycastle.crypto.BlockCipher cipher, BlockCipherPadding padding) { this.cipher = new PaddedBufferedBlockCipher(cipher, padding); } public void init(boolean forEncryption, CipherParameters params) throws IllegalArgumentException { cipher.init(forEncryption, params); } public boolean wrapOnNoPadding() { return !(cipher instanceof CTSBlockCipher); } public String getAlgorithmName() { return cipher.getUnderlyingCipher().getAlgorithmName(); } public org.bouncycastle.crypto.BlockCipher getUnderlyingCipher() { return cipher.getUnderlyingCipher(); } public int getOutputSize(int len) { return cipher.getOutputSize(len); } public int getUpdateOutputSize(int len) { return cipher.getUpdateOutputSize(len); } public int processByte(byte in, byte[] out, int outOff) throws DataLengthException { return cipher.processByte(in, out, outOff); } public int processBytes(byte[] in, int inOff, int len, byte[] out, int outOff) throws DataLengthException { return cipher.processBytes(in, inOff, len, out, outOff); } public int doFinal(byte[] out, int outOff) throws IllegalStateException, InvalidCipherTextException { return cipher.doFinal(out, outOff); } } private static class AEADGenericBlockCipher implements GenericBlockCipher { private AEADBlockCipher cipher; AEADGenericBlockCipher(AEADBlockCipher cipher) { this.cipher = cipher; } public void init(boolean forEncryption, CipherParameters params) throws IllegalArgumentException { cipher.init(forEncryption, params); } public String getAlgorithmName() { return cipher.getUnderlyingCipher().getAlgorithmName(); } public boolean wrapOnNoPadding() { return false; } public org.bouncycastle.crypto.BlockCipher getUnderlyingCipher() { return cipher.getUnderlyingCipher(); } public int getOutputSize(int len) { return cipher.getOutputSize(len); } public int getUpdateOutputSize(int len) { return cipher.getUpdateOutputSize(len); } public int processByte(byte in, byte[] out, int outOff) throws DataLengthException { return cipher.processByte(in, out, outOff); } public int processBytes(byte[] in, int inOff, int len, byte[] out, int outOff) throws DataLengthException { return cipher.processBytes(in, inOff, len, out, outOff); } public int doFinal(byte[] out, int outOff) throws IllegalStateException, InvalidCipherTextException { return cipher.doFinal(out, outOff); } } } bouncycastle-1.49.orig/src/org/bouncycastle/jcajce/provider/symmetric/util/PBESecretKeyFactory.java0000644000175000017500000000347411736770056033210 0ustar ebourgebourgpackage org.bouncycastle.jcajce.provider.symmetric.util; import java.security.spec.InvalidKeySpecException; import java.security.spec.KeySpec; import javax.crypto.SecretKey; import javax.crypto.spec.PBEKeySpec; import org.bouncycastle.asn1.ASN1ObjectIdentifier; import org.bouncycastle.crypto.CipherParameters; public class PBESecretKeyFactory extends BaseSecretKeyFactory implements PBE { private boolean forCipher; private int scheme; private int digest; private int keySize; private int ivSize; public PBESecretKeyFactory( String algorithm, ASN1ObjectIdentifier oid, boolean forCipher, int scheme, int digest, int keySize, int ivSize) { super(algorithm, oid); this.forCipher = forCipher; this.scheme = scheme; this.digest = digest; this.keySize = keySize; this.ivSize = ivSize; } protected SecretKey engineGenerateSecret( KeySpec keySpec) throws InvalidKeySpecException { if (keySpec instanceof PBEKeySpec) { PBEKeySpec pbeSpec = (PBEKeySpec)keySpec; CipherParameters param; if (pbeSpec.getSalt() == null) { return new BCPBEKey(this.algName, this.algOid, scheme, digest, keySize, ivSize, pbeSpec, null); } if (forCipher) { param = PBE.Util.makePBEParameters(pbeSpec, scheme, digest, keySize, ivSize); } else { param = PBE.Util.makePBEMacParameters(pbeSpec, scheme, digest, keySize); } return new BCPBEKey(this.algName, this.algOid, scheme, digest, keySize, ivSize, pbeSpec, param); } throw new InvalidKeySpecException("Invalid KeySpec"); } } bouncycastle-1.49.orig/src/org/bouncycastle/jcajce/provider/symmetric/util/BaseStreamCipher.java0000644000175000017500000002272211705435502032577 0ustar ebourgebourgpackage org.bouncycastle.jcajce.provider.symmetric.util; import java.security.AlgorithmParameters; import java.security.InvalidAlgorithmParameterException; import java.security.InvalidKeyException; import java.security.Key; import java.security.SecureRandom; import java.security.spec.AlgorithmParameterSpec; import javax.crypto.Cipher; import javax.crypto.NoSuchPaddingException; import javax.crypto.SecretKey; import javax.crypto.ShortBufferException; import javax.crypto.spec.IvParameterSpec; import javax.crypto.spec.PBEParameterSpec; import javax.crypto.spec.RC2ParameterSpec; import javax.crypto.spec.RC5ParameterSpec; import org.bouncycastle.crypto.BlockCipher; import org.bouncycastle.crypto.CipherParameters; import org.bouncycastle.crypto.DataLengthException; import org.bouncycastle.crypto.StreamBlockCipher; import org.bouncycastle.crypto.StreamCipher; import org.bouncycastle.crypto.params.KeyParameter; import org.bouncycastle.crypto.params.ParametersWithIV; import org.bouncycastle.jce.provider.BouncyCastleProvider; public class BaseStreamCipher extends BaseWrapCipher implements PBE { // // specs we can handle. // private Class[] availableSpecs = { RC2ParameterSpec.class, RC5ParameterSpec.class, IvParameterSpec.class, PBEParameterSpec.class }; private StreamCipher cipher; private ParametersWithIV ivParam; private int ivLength = 0; private PBEParameterSpec pbeSpec = null; private String pbeAlgorithm = null; protected BaseStreamCipher( StreamCipher engine, int ivLength) { cipher = engine; this.ivLength = ivLength; } protected BaseStreamCipher( BlockCipher engine, int ivLength) { this.ivLength = ivLength; cipher = new StreamBlockCipher(engine); } protected int engineGetBlockSize() { return 0; } protected byte[] engineGetIV() { return (ivParam != null) ? ivParam.getIV() : null; } protected int engineGetKeySize( Key key) { return key.getEncoded().length * 8; } protected int engineGetOutputSize( int inputLen) { return inputLen; } protected AlgorithmParameters engineGetParameters() { if (engineParams == null) { if (pbeSpec != null) { try { AlgorithmParameters engineParams = AlgorithmParameters.getInstance(pbeAlgorithm, BouncyCastleProvider.PROVIDER_NAME); engineParams.init(pbeSpec); return engineParams; } catch (Exception e) { return null; } } } return engineParams; } /** * should never be called. */ protected void engineSetMode( String mode) { if (!mode.equalsIgnoreCase("ECB")) { throw new IllegalArgumentException("can't support mode " + mode); } } /** * should never be called. */ protected void engineSetPadding( String padding) throws NoSuchPaddingException { if (!padding.equalsIgnoreCase("NoPadding")) { throw new NoSuchPaddingException("Padding " + padding + " unknown."); } } protected void engineInit( int opmode, Key key, AlgorithmParameterSpec params, SecureRandom random) throws InvalidKeyException, InvalidAlgorithmParameterException { CipherParameters param; this.pbeSpec = null; this.pbeAlgorithm = null; this.engineParams = null; // // basic key check // if (!(key instanceof SecretKey)) { throw new InvalidKeyException("Key for algorithm " + key.getAlgorithm() + " not suitable for symmetric enryption."); } if (key instanceof BCPBEKey) { BCPBEKey k = (BCPBEKey)key; if (k.getOID() != null) { pbeAlgorithm = k.getOID().getId(); } else { pbeAlgorithm = k.getAlgorithm(); } if (k.getParam() != null) { param = k.getParam(); pbeSpec = new PBEParameterSpec(k.getSalt(), k.getIterationCount()); } else if (params instanceof PBEParameterSpec) { param = PBE.Util.makePBEParameters(k, params, cipher.getAlgorithmName()); pbeSpec = (PBEParameterSpec)params; } else { throw new InvalidAlgorithmParameterException("PBE requires PBE parameters to be set."); } if (k.getIvSize() != 0) { ivParam = (ParametersWithIV)param; } } else if (params == null) { param = new KeyParameter(key.getEncoded()); } else if (params instanceof IvParameterSpec) { param = new ParametersWithIV(new KeyParameter(key.getEncoded()), ((IvParameterSpec)params).getIV()); ivParam = (ParametersWithIV)param; } else { throw new IllegalArgumentException("unknown parameter type."); } if ((ivLength != 0) && !(param instanceof ParametersWithIV)) { SecureRandom ivRandom = random; if (ivRandom == null) { ivRandom = new SecureRandom(); } if ((opmode == Cipher.ENCRYPT_MODE) || (opmode == Cipher.WRAP_MODE)) { byte[] iv = new byte[ivLength]; ivRandom.nextBytes(iv); param = new ParametersWithIV(param, iv); ivParam = (ParametersWithIV)param; } else { throw new InvalidAlgorithmParameterException("no IV set when one expected"); } } switch (opmode) { case Cipher.ENCRYPT_MODE: case Cipher.WRAP_MODE: cipher.init(true, param); break; case Cipher.DECRYPT_MODE: case Cipher.UNWRAP_MODE: cipher.init(false, param); break; default: System.out.println("eeek!"); } } protected void engineInit( int opmode, Key key, AlgorithmParameters params, SecureRandom random) throws InvalidKeyException, InvalidAlgorithmParameterException { AlgorithmParameterSpec paramSpec = null; if (params != null) { for (int i = 0; i != availableSpecs.length; i++) { try { paramSpec = params.getParameterSpec(availableSpecs[i]); break; } catch (Exception e) { continue; } } if (paramSpec == null) { throw new InvalidAlgorithmParameterException("can't handle parameter " + params.toString()); } } engineInit(opmode, key, paramSpec, random); engineParams = params; } protected void engineInit( int opmode, Key key, SecureRandom random) throws InvalidKeyException { try { engineInit(opmode, key, (AlgorithmParameterSpec)null, random); } catch (InvalidAlgorithmParameterException e) { throw new InvalidKeyException(e.getMessage()); } } protected byte[] engineUpdate( byte[] input, int inputOffset, int inputLen) { byte[] out = new byte[inputLen]; cipher.processBytes(input, inputOffset, inputLen, out, 0); return out; } protected int engineUpdate( byte[] input, int inputOffset, int inputLen, byte[] output, int outputOffset) throws ShortBufferException { try { cipher.processBytes(input, inputOffset, inputLen, output, outputOffset); return inputLen; } catch (DataLengthException e) { throw new ShortBufferException(e.getMessage()); } } protected byte[] engineDoFinal( byte[] input, int inputOffset, int inputLen) { if (inputLen != 0) { byte[] out = engineUpdate(input, inputOffset, inputLen); cipher.reset(); return out; } cipher.reset(); return new byte[0]; } protected int engineDoFinal( byte[] input, int inputOffset, int inputLen, byte[] output, int outputOffset) { if (inputLen != 0) { cipher.processBytes(input, inputOffset, inputLen, output, outputOffset); } cipher.reset(); return inputLen; } } bouncycastle-1.49.orig/src/org/bouncycastle/jcajce/provider/symmetric/util/BaseKeyGenerator.java0000644000175000017500000000435312103442311032575 0ustar ebourgebourgpackage org.bouncycastle.jcajce.provider.symmetric.util; import java.security.InvalidAlgorithmParameterException; import java.security.InvalidParameterException; import java.security.SecureRandom; import java.security.spec.AlgorithmParameterSpec; import javax.crypto.KeyGeneratorSpi; import javax.crypto.SecretKey; import javax.crypto.spec.SecretKeySpec; import org.bouncycastle.crypto.CipherKeyGenerator; import org.bouncycastle.crypto.KeyGenerationParameters; public class BaseKeyGenerator extends KeyGeneratorSpi { protected String algName; protected int keySize; protected int defaultKeySize; protected CipherKeyGenerator engine; protected boolean uninitialised = true; protected BaseKeyGenerator( String algName, int defaultKeySize, CipherKeyGenerator engine) { this.algName = algName; this.keySize = this.defaultKeySize = defaultKeySize; this.engine = engine; } protected void engineInit( AlgorithmParameterSpec params, SecureRandom random) throws InvalidAlgorithmParameterException { throw new InvalidAlgorithmParameterException("Not Implemented"); } protected void engineInit( SecureRandom random) { if (random != null) { engine.init(new KeyGenerationParameters(random, defaultKeySize)); uninitialised = false; } } protected void engineInit( int keySize, SecureRandom random) { try { if (random == null) { random = new SecureRandom(); } engine.init(new KeyGenerationParameters(random, keySize)); uninitialised = false; } catch (IllegalArgumentException e) { throw new InvalidParameterException(e.getMessage()); } } protected SecretKey engineGenerateKey() { if (uninitialised) { engine.init(new KeyGenerationParameters(new SecureRandom(), defaultKeySize)); uninitialised = false; } return new SecretKeySpec(engine.generateKey(), algName); } } bouncycastle-1.49.orig/src/org/bouncycastle/jcajce/provider/symmetric/util/BCPBEKey.java0000644000175000017500000000657612151772307030716 0ustar ebourgebourgpackage org.bouncycastle.jcajce.provider.symmetric.util; import javax.crypto.interfaces.PBEKey; import javax.crypto.spec.PBEKeySpec; import org.bouncycastle.asn1.ASN1ObjectIdentifier; import org.bouncycastle.crypto.CipherParameters; import org.bouncycastle.crypto.PBEParametersGenerator; import org.bouncycastle.crypto.params.KeyParameter; import org.bouncycastle.crypto.params.ParametersWithIV; public class BCPBEKey implements PBEKey { String algorithm; ASN1ObjectIdentifier oid; int type; int digest; int keySize; int ivSize; CipherParameters param; PBEKeySpec pbeKeySpec; boolean tryWrong = false; /** * @param param */ public BCPBEKey( String algorithm, ASN1ObjectIdentifier oid, int type, int digest, int keySize, int ivSize, PBEKeySpec pbeKeySpec, CipherParameters param) { this.algorithm = algorithm; this.oid = oid; this.type = type; this.digest = digest; this.keySize = keySize; this.ivSize = ivSize; this.pbeKeySpec = pbeKeySpec; this.param = param; } public String getAlgorithm() { return algorithm; } public String getFormat() { return "RAW"; } public byte[] getEncoded() { if (param != null) { KeyParameter kParam; if (param instanceof ParametersWithIV) { kParam = (KeyParameter)((ParametersWithIV)param).getParameters(); } else { kParam = (KeyParameter)param; } return kParam.getKey(); } else { if (type == PBE.PKCS12) { return PBEParametersGenerator.PKCS12PasswordToBytes(pbeKeySpec.getPassword()); } else if (type == PBE.PKCS5S2_UTF8) { return PBEParametersGenerator.PKCS5PasswordToUTF8Bytes(pbeKeySpec.getPassword()); } else { return PBEParametersGenerator.PKCS5PasswordToBytes(pbeKeySpec.getPassword()); } } } int getType() { return type; } int getDigest() { return digest; } int getKeySize() { return keySize; } public int getIvSize() { return ivSize; } public CipherParameters getParam() { return param; } /* (non-Javadoc) * @see javax.crypto.interfaces.PBEKey#getPassword() */ public char[] getPassword() { return pbeKeySpec.getPassword(); } /* (non-Javadoc) * @see javax.crypto.interfaces.PBEKey#getSalt() */ public byte[] getSalt() { return pbeKeySpec.getSalt(); } /* (non-Javadoc) * @see javax.crypto.interfaces.PBEKey#getIterationCount() */ public int getIterationCount() { return pbeKeySpec.getIterationCount(); } public ASN1ObjectIdentifier getOID() { return oid; } public void setTryWrongPKCS12Zero(boolean tryWrong) { this.tryWrong = tryWrong; } boolean shouldTryWrongPKCS12() { return tryWrong; } } bouncycastle-1.49.orig/src/org/bouncycastle/jcajce/provider/symmetric/util/PBE.java0000644000175000017500000002364612152002234030017 0ustar ebourgebourgpackage org.bouncycastle.jcajce.provider.symmetric.util; import java.security.spec.AlgorithmParameterSpec; import javax.crypto.spec.PBEKeySpec; import javax.crypto.spec.PBEParameterSpec; import org.bouncycastle.crypto.CipherParameters; import org.bouncycastle.crypto.PBEParametersGenerator; import org.bouncycastle.crypto.digests.GOST3411Digest; import org.bouncycastle.crypto.digests.MD2Digest; import org.bouncycastle.crypto.digests.MD5Digest; import org.bouncycastle.crypto.digests.RIPEMD160Digest; import org.bouncycastle.crypto.digests.SHA1Digest; import org.bouncycastle.crypto.digests.SHA256Digest; import org.bouncycastle.crypto.digests.TigerDigest; import org.bouncycastle.crypto.generators.OpenSSLPBEParametersGenerator; import org.bouncycastle.crypto.generators.PKCS12ParametersGenerator; import org.bouncycastle.crypto.generators.PKCS5S1ParametersGenerator; import org.bouncycastle.crypto.generators.PKCS5S2ParametersGenerator; import org.bouncycastle.crypto.params.DESParameters; import org.bouncycastle.crypto.params.KeyParameter; import org.bouncycastle.crypto.params.ParametersWithIV; public interface PBE { // // PBE Based encryption constants - by default we do PKCS12 with SHA-1 // static final int MD5 = 0; static final int SHA1 = 1; static final int RIPEMD160 = 2; static final int TIGER = 3; static final int SHA256 = 4; static final int MD2 = 5; static final int GOST3411 = 6; static final int PKCS5S1 = 0; static final int PKCS5S2 = 1; static final int PKCS12 = 2; static final int OPENSSL = 3; static final int PKCS5S1_UTF8 = 4; static final int PKCS5S2_UTF8 = 5; /** * uses the appropriate mixer to generate the key and IV if necessary. */ static class Util { static private PBEParametersGenerator makePBEGenerator( int type, int hash) { PBEParametersGenerator generator; if (type == PKCS5S1 || type == PKCS5S1_UTF8) { switch (hash) { case MD2: generator = new PKCS5S1ParametersGenerator(new MD2Digest()); break; case MD5: generator = new PKCS5S1ParametersGenerator(new MD5Digest()); break; case SHA1: generator = new PKCS5S1ParametersGenerator(new SHA1Digest()); break; default: throw new IllegalStateException("PKCS5 scheme 1 only supports MD2, MD5 and SHA1."); } } else if (type == PKCS5S2 || type == PKCS5S2_UTF8) { generator = new PKCS5S2ParametersGenerator(); } else if (type == PKCS12) { switch (hash) { case MD2: generator = new PKCS12ParametersGenerator(new MD2Digest()); break; case MD5: generator = new PKCS12ParametersGenerator(new MD5Digest()); break; case SHA1: generator = new PKCS12ParametersGenerator(new SHA1Digest()); break; case RIPEMD160: generator = new PKCS12ParametersGenerator(new RIPEMD160Digest()); break; case TIGER: generator = new PKCS12ParametersGenerator(new TigerDigest()); break; case SHA256: generator = new PKCS12ParametersGenerator(new SHA256Digest()); break; case GOST3411: generator = new PKCS12ParametersGenerator(new GOST3411Digest()); break; default: throw new IllegalStateException("unknown digest scheme for PBE encryption."); } } else { generator = new OpenSSLPBEParametersGenerator(); } return generator; } /** * construct a key and iv (if necessary) suitable for use with a * Cipher. */ public static CipherParameters makePBEParameters( BCPBEKey pbeKey, AlgorithmParameterSpec spec, String targetAlgorithm) { if ((spec == null) || !(spec instanceof PBEParameterSpec)) { throw new IllegalArgumentException("Need a PBEParameter spec with a PBE key."); } PBEParameterSpec pbeParam = (PBEParameterSpec)spec; PBEParametersGenerator generator = makePBEGenerator(pbeKey.getType(), pbeKey.getDigest()); byte[] key = pbeKey.getEncoded(); CipherParameters param; if (pbeKey.shouldTryWrongPKCS12()) { key = new byte[2]; } generator.init(key, pbeParam.getSalt(), pbeParam.getIterationCount()); if (pbeKey.getIvSize() != 0) { param = generator.generateDerivedParameters(pbeKey.getKeySize(), pbeKey.getIvSize()); } else { param = generator.generateDerivedParameters(pbeKey.getKeySize()); } if (targetAlgorithm.startsWith("DES")) { if (param instanceof ParametersWithIV) { KeyParameter kParam = (KeyParameter)((ParametersWithIV)param).getParameters(); DESParameters.setOddParity(kParam.getKey()); } else { KeyParameter kParam = (KeyParameter)param; DESParameters.setOddParity(kParam.getKey()); } } for (int i = 0; i != key.length; i++) { key[i] = 0; } return param; } /** * generate a PBE based key suitable for a MAC algorithm, the * key size is chosen according the MAC size, or the hashing algorithm, * whichever is greater. */ public static CipherParameters makePBEMacParameters( BCPBEKey pbeKey, AlgorithmParameterSpec spec) { if ((spec == null) || !(spec instanceof PBEParameterSpec)) { throw new IllegalArgumentException("Need a PBEParameter spec with a PBE key."); } PBEParameterSpec pbeParam = (PBEParameterSpec)spec; PBEParametersGenerator generator = makePBEGenerator(pbeKey.getType(), pbeKey.getDigest()); byte[] key = pbeKey.getEncoded(); CipherParameters param; if (pbeKey.shouldTryWrongPKCS12()) { key = new byte[2]; } generator.init(key, pbeParam.getSalt(), pbeParam.getIterationCount()); param = generator.generateDerivedMacParameters(pbeKey.getKeySize()); for (int i = 0; i != key.length; i++) { key[i] = 0; } return param; } /** * construct a key and iv (if necessary) suitable for use with a * Cipher. */ public static CipherParameters makePBEParameters( PBEKeySpec keySpec, int type, int hash, int keySize, int ivSize) { PBEParametersGenerator generator = makePBEGenerator(type, hash); byte[] key; CipherParameters param; key = convertPassword(type, keySpec); generator.init(key, keySpec.getSalt(), keySpec.getIterationCount()); if (ivSize != 0) { param = generator.generateDerivedParameters(keySize, ivSize); } else { param = generator.generateDerivedParameters(keySize); } for (int i = 0; i != key.length; i++) { key[i] = 0; } return param; } /** * generate a PBE based key suitable for a MAC algorithm, the * key size is chosen according the MAC size, or the hashing algorithm, * whichever is greater. */ public static CipherParameters makePBEMacParameters( PBEKeySpec keySpec, int type, int hash, int keySize) { PBEParametersGenerator generator = makePBEGenerator(type, hash); byte[] key; CipherParameters param; key = convertPassword(type, keySpec); generator.init(key, keySpec.getSalt(), keySpec.getIterationCount()); param = generator.generateDerivedMacParameters(keySize); for (int i = 0; i != key.length; i++) { key[i] = 0; } return param; } private static byte[] convertPassword(int type, PBEKeySpec keySpec) { byte[] key; if (type == PKCS12) { key = PBEParametersGenerator.PKCS12PasswordToBytes(keySpec.getPassword()); } else if (type == PKCS5S2_UTF8 || type == PKCS5S1_UTF8) { key = PBEParametersGenerator.PKCS5PasswordToUTF8Bytes(keySpec.getPassword()); } else { key = PBEParametersGenerator.PKCS5PasswordToBytes(keySpec.getPassword()); } return key; } } } bouncycastle-1.49.orig/src/org/bouncycastle/jcajce/provider/symmetric/util/BlockCipherProvider.java0000644000175000017500000000024712131445667033323 0ustar ebourgebourgpackage org.bouncycastle.jcajce.provider.symmetric.util; import org.bouncycastle.crypto.BlockCipher; public interface BlockCipherProvider { BlockCipher get(); } bouncycastle-1.49.orig/src/org/bouncycastle/jcajce/provider/symmetric/util/BaseMac.java0000644000175000017500000000570112151127323030702 0ustar ebourgebourgpackage org.bouncycastle.jcajce.provider.symmetric.util; import java.security.InvalidAlgorithmParameterException; import java.security.InvalidKeyException; import java.security.Key; import java.security.spec.AlgorithmParameterSpec; import javax.crypto.MacSpi; import javax.crypto.spec.IvParameterSpec; import javax.crypto.spec.PBEParameterSpec; import org.bouncycastle.crypto.CipherParameters; import org.bouncycastle.crypto.Mac; import org.bouncycastle.crypto.params.KeyParameter; import org.bouncycastle.crypto.params.ParametersWithIV; public class BaseMac extends MacSpi implements PBE { private Mac macEngine; private int pbeType = PKCS12; private int pbeHash = SHA1; private int keySize = 160; protected BaseMac( Mac macEngine) { this.macEngine = macEngine; } protected BaseMac( Mac macEngine, int pbeType, int pbeHash, int keySize) { this.macEngine = macEngine; this.pbeType = pbeType; this.pbeHash = pbeHash; this.keySize = keySize; } protected void engineInit( Key key, AlgorithmParameterSpec params) throws InvalidKeyException, InvalidAlgorithmParameterException { CipherParameters param; if (key == null) { throw new InvalidKeyException("key is null"); } if (key instanceof BCPBEKey) { BCPBEKey k = (BCPBEKey)key; if (k.getParam() != null) { param = k.getParam(); } else if (params instanceof PBEParameterSpec) { param = PBE.Util.makePBEMacParameters(k, params); } else { throw new InvalidAlgorithmParameterException("PBE requires PBE parameters to be set."); } } else if (params instanceof IvParameterSpec) { param = new ParametersWithIV(new KeyParameter(key.getEncoded()), ((IvParameterSpec)params).getIV()); } else if (params == null) { param = new KeyParameter(key.getEncoded()); } else { throw new InvalidAlgorithmParameterException("unknown parameter type."); } macEngine.init(param); } protected int engineGetMacLength() { return macEngine.getMacSize(); } protected void engineReset() { macEngine.reset(); } protected void engineUpdate( byte input) { macEngine.update(input); } protected void engineUpdate( byte[] input, int offset, int len) { macEngine.update(input, offset, len); } protected byte[] engineDoFinal() { byte[] out = new byte[engineGetMacLength()]; macEngine.doFinal(out, 0); return out; } } ././@LongLink0000000000000000000000000000016000000000000011562 Lustar rootrootbouncycastle-1.49.orig/src/org/bouncycastle/jcajce/provider/symmetric/util/BaseAlgorithmParameterGenerator.javabouncycastle-1.49.orig/src/org/bouncycastle/jcajce/provider/symmetric/util/BaseAlgorithmParameterGen0000644000175000017500000000076711701474563033525 0ustar ebourgebourgpackage org.bouncycastle.jcajce.provider.symmetric.util; import java.security.AlgorithmParameterGeneratorSpi; import java.security.SecureRandom; public abstract class BaseAlgorithmParameterGenerator extends AlgorithmParameterGeneratorSpi { protected SecureRandom random; protected int strength = 1024; protected void engineInit( int strength, SecureRandom random) { this.strength = strength; this.random = random; } } bouncycastle-1.49.orig/src/org/bouncycastle/jcajce/provider/symmetric/util/BaseSecretKeyFactory.java0000644000175000017500000000453412151126231033430 0ustar ebourgebourgpackage org.bouncycastle.jcajce.provider.symmetric.util; import java.lang.reflect.Constructor; import java.security.InvalidKeyException; import java.security.spec.InvalidKeySpecException; import java.security.spec.KeySpec; import javax.crypto.SecretKey; import javax.crypto.SecretKeyFactorySpi; import javax.crypto.spec.SecretKeySpec; import org.bouncycastle.asn1.ASN1ObjectIdentifier; public class BaseSecretKeyFactory extends SecretKeyFactorySpi implements PBE { protected String algName; protected ASN1ObjectIdentifier algOid; protected BaseSecretKeyFactory( String algName, ASN1ObjectIdentifier algOid) { this.algName = algName; this.algOid = algOid; } protected SecretKey engineGenerateSecret( KeySpec keySpec) throws InvalidKeySpecException { if (keySpec instanceof SecretKeySpec) { return (SecretKey)keySpec; } throw new InvalidKeySpecException("Invalid KeySpec"); } protected KeySpec engineGetKeySpec( SecretKey key, Class keySpec) throws InvalidKeySpecException { if (keySpec == null) { throw new InvalidKeySpecException("keySpec parameter is null"); } if (key == null) { throw new InvalidKeySpecException("key parameter is null"); } if (SecretKeySpec.class.isAssignableFrom(keySpec)) { return new SecretKeySpec(key.getEncoded(), algName); } try { Class[] parameters = { byte[].class }; Constructor c = keySpec.getConstructor(parameters); Object[] p = new Object[1]; p[0] = key.getEncoded(); return (KeySpec)c.newInstance(p); } catch (Exception e) { throw new InvalidKeySpecException(e.toString()); } } protected SecretKey engineTranslateKey( SecretKey key) throws InvalidKeyException { if (key == null) { throw new InvalidKeyException("key parameter is null"); } if (!key.getAlgorithm().equalsIgnoreCase(algName)) { throw new InvalidKeyException("Key not of type " + algName + "."); } return new SecretKeySpec(key.getEncoded(), algName); } } bouncycastle-1.49.orig/src/org/bouncycastle/jcajce/provider/symmetric/util/BaseWrapCipher.java0000644000175000017500000002555712103432470032260 0ustar ebourgebourgpackage org.bouncycastle.jcajce.provider.symmetric.util; import java.security.AlgorithmParameters; import java.security.InvalidAlgorithmParameterException; import java.security.InvalidKeyException; import java.security.Key; import java.security.KeyFactory; import java.security.NoSuchAlgorithmException; import java.security.NoSuchProviderException; import java.security.PrivateKey; import java.security.SecureRandom; import java.security.spec.AlgorithmParameterSpec; import java.security.spec.InvalidKeySpecException; import java.security.spec.PKCS8EncodedKeySpec; import java.security.spec.X509EncodedKeySpec; import javax.crypto.BadPaddingException; import javax.crypto.Cipher; import javax.crypto.CipherSpi; import javax.crypto.IllegalBlockSizeException; import javax.crypto.NoSuchPaddingException; import javax.crypto.ShortBufferException; import javax.crypto.spec.IvParameterSpec; import javax.crypto.spec.PBEParameterSpec; import javax.crypto.spec.RC2ParameterSpec; import javax.crypto.spec.RC5ParameterSpec; import javax.crypto.spec.SecretKeySpec; import org.bouncycastle.asn1.pkcs.PrivateKeyInfo; import org.bouncycastle.crypto.CipherParameters; import org.bouncycastle.crypto.InvalidCipherTextException; import org.bouncycastle.crypto.Wrapper; import org.bouncycastle.crypto.params.KeyParameter; import org.bouncycastle.crypto.params.ParametersWithIV; import org.bouncycastle.jce.provider.BouncyCastleProvider; public abstract class BaseWrapCipher extends CipherSpi implements PBE { // // specs we can handle. // private Class[] availableSpecs = { IvParameterSpec.class, PBEParameterSpec.class, RC2ParameterSpec.class, RC5ParameterSpec.class }; protected int pbeType = PKCS12; protected int pbeHash = SHA1; protected int pbeKeySize; protected int pbeIvSize; protected AlgorithmParameters engineParams = null; protected Wrapper wrapEngine = null; private int ivSize; private byte[] iv; protected BaseWrapCipher() { } protected BaseWrapCipher( Wrapper wrapEngine) { this(wrapEngine, 0); } protected BaseWrapCipher( Wrapper wrapEngine, int ivSize) { this.wrapEngine = wrapEngine; this.ivSize = ivSize; } protected int engineGetBlockSize() { return 0; } protected byte[] engineGetIV() { return (byte[])iv.clone(); } protected int engineGetKeySize( Key key) { return key.getEncoded().length; } protected int engineGetOutputSize( int inputLen) { return -1; } protected AlgorithmParameters engineGetParameters() { return null; } protected void engineSetMode( String mode) throws NoSuchAlgorithmException { throw new NoSuchAlgorithmException("can't support mode " + mode); } protected void engineSetPadding( String padding) throws NoSuchPaddingException { throw new NoSuchPaddingException("Padding " + padding + " unknown."); } protected void engineInit( int opmode, Key key, AlgorithmParameterSpec params, SecureRandom random) throws InvalidKeyException, InvalidAlgorithmParameterException { CipherParameters param; if (key instanceof BCPBEKey) { BCPBEKey k = (BCPBEKey)key; if (params instanceof PBEParameterSpec) { param = PBE.Util.makePBEParameters(k, params, wrapEngine.getAlgorithmName()); } else if (k.getParam() != null) { param = k.getParam(); } else { throw new InvalidAlgorithmParameterException("PBE requires PBE parameters to be set."); } } else { param = new KeyParameter(key.getEncoded()); } if (params instanceof IvParameterSpec) { IvParameterSpec iv = (IvParameterSpec) params; param = new ParametersWithIV(param, iv.getIV()); } if (param instanceof KeyParameter && ivSize != 0) { iv = new byte[ivSize]; random.nextBytes(iv); param = new ParametersWithIV(param, iv); } switch (opmode) { case Cipher.WRAP_MODE: wrapEngine.init(true, param); break; case Cipher.UNWRAP_MODE: wrapEngine.init(false, param); break; case Cipher.ENCRYPT_MODE: case Cipher.DECRYPT_MODE: throw new IllegalArgumentException("engine only valid for wrapping"); default: System.out.println("eeek!"); } } protected void engineInit( int opmode, Key key, AlgorithmParameters params, SecureRandom random) throws InvalidKeyException, InvalidAlgorithmParameterException { AlgorithmParameterSpec paramSpec = null; if (params != null) { for (int i = 0; i != availableSpecs.length; i++) { try { paramSpec = params.getParameterSpec(availableSpecs[i]); break; } catch (Exception e) { // try next spec } } if (paramSpec == null) { throw new InvalidAlgorithmParameterException("can't handle parameter " + params.toString()); } } engineParams = params; engineInit(opmode, key, paramSpec, random); } protected void engineInit( int opmode, Key key, SecureRandom random) throws InvalidKeyException { try { engineInit(opmode, key, (AlgorithmParameterSpec)null, random); } catch (InvalidAlgorithmParameterException e) { throw new IllegalArgumentException(e.getMessage()); } } protected byte[] engineUpdate( byte[] input, int inputOffset, int inputLen) { throw new RuntimeException("not supported for wrapping"); } protected int engineUpdate( byte[] input, int inputOffset, int inputLen, byte[] output, int outputOffset) throws ShortBufferException { throw new RuntimeException("not supported for wrapping"); } protected byte[] engineDoFinal( byte[] input, int inputOffset, int inputLen) throws IllegalBlockSizeException, BadPaddingException { return null; } protected int engineDoFinal( byte[] input, int inputOffset, int inputLen, byte[] output, int outputOffset) throws IllegalBlockSizeException, BadPaddingException, ShortBufferException { return 0; } protected byte[] engineWrap( Key key) throws IllegalBlockSizeException, InvalidKeyException { byte[] encoded = key.getEncoded(); if (encoded == null) { throw new InvalidKeyException("Cannot wrap key, null encoding."); } try { if (wrapEngine == null) { return engineDoFinal(encoded, 0, encoded.length); } else { return wrapEngine.wrap(encoded, 0, encoded.length); } } catch (BadPaddingException e) { throw new IllegalBlockSizeException(e.getMessage()); } } protected Key engineUnwrap( byte[] wrappedKey, String wrappedKeyAlgorithm, int wrappedKeyType) throws InvalidKeyException, NoSuchAlgorithmException { byte[] encoded; try { if (wrapEngine == null) { encoded = engineDoFinal(wrappedKey, 0, wrappedKey.length); } else { encoded = wrapEngine.unwrap(wrappedKey, 0, wrappedKey.length); } } catch (InvalidCipherTextException e) { throw new InvalidKeyException(e.getMessage()); } catch (BadPaddingException e) { throw new InvalidKeyException(e.getMessage()); } catch (IllegalBlockSizeException e2) { throw new InvalidKeyException(e2.getMessage()); } if (wrappedKeyType == Cipher.SECRET_KEY) { return new SecretKeySpec(encoded, wrappedKeyAlgorithm); } else if (wrappedKeyAlgorithm.equals("") && wrappedKeyType == Cipher.PRIVATE_KEY) { /* * The caller doesn't know the algorithm as it is part of * the encrypted data. */ try { PrivateKeyInfo in = PrivateKeyInfo.getInstance(encoded); PrivateKey privKey = BouncyCastleProvider.getPrivateKey(in); if (privKey != null) { return privKey; } else { throw new InvalidKeyException("algorithm " + in.getPrivateKeyAlgorithm().getAlgorithm() + " not supported"); } } catch (Exception e) { throw new InvalidKeyException("Invalid key encoding."); } } else { try { KeyFactory kf = KeyFactory.getInstance(wrappedKeyAlgorithm, BouncyCastleProvider.PROVIDER_NAME); if (wrappedKeyType == Cipher.PUBLIC_KEY) { return kf.generatePublic(new X509EncodedKeySpec(encoded)); } else if (wrappedKeyType == Cipher.PRIVATE_KEY) { return kf.generatePrivate(new PKCS8EncodedKeySpec(encoded)); } } catch (NoSuchProviderException e) { throw new InvalidKeyException("Unknown key type " + e.getMessage()); } catch (InvalidKeySpecException e2) { throw new InvalidKeyException("Unknown key type " + e2.getMessage()); } throw new InvalidKeyException("Unknown key type " + wrappedKeyType); } } } ././@LongLink0000000000000000000000000000015000000000000011561 Lustar rootrootbouncycastle-1.49.orig/src/org/bouncycastle/jcajce/provider/symmetric/util/BaseAlgorithmParameters.javabouncycastle-1.49.orig/src/org/bouncycastle/jcajce/provider/symmetric/util/BaseAlgorithmParameters.j0000644000175000017500000000160712151126324033465 0ustar ebourgebourgpackage org.bouncycastle.jcajce.provider.symmetric.util; import java.security.AlgorithmParametersSpi; import java.security.spec.AlgorithmParameterSpec; import java.security.spec.InvalidParameterSpecException; public abstract class BaseAlgorithmParameters extends AlgorithmParametersSpi { protected boolean isASN1FormatString(String format) { return format == null || format.equals("ASN.1"); } protected AlgorithmParameterSpec engineGetParameterSpec( Class paramSpec) throws InvalidParameterSpecException { if (paramSpec == null) { throw new NullPointerException("argument to getParameterSpec must not be null"); } return localEngineGetParameterSpec(paramSpec); } protected abstract AlgorithmParameterSpec localEngineGetParameterSpec(Class paramSpec) throws InvalidParameterSpecException; } bouncycastle-1.49.orig/src/org/bouncycastle/jcajce/provider/symmetric/Twofish.java0000644000175000017500000000640212146275676030077 0ustar ebourgebourgpackage org.bouncycastle.jcajce.provider.symmetric; import org.bouncycastle.crypto.BlockCipher; import org.bouncycastle.crypto.CipherKeyGenerator; import org.bouncycastle.crypto.engines.TwofishEngine; import org.bouncycastle.crypto.macs.GMac; import org.bouncycastle.crypto.modes.CBCBlockCipher; import org.bouncycastle.crypto.modes.GCMBlockCipher; import org.bouncycastle.jcajce.provider.config.ConfigurableProvider; import org.bouncycastle.jcajce.provider.symmetric.util.BaseBlockCipher; import org.bouncycastle.jcajce.provider.symmetric.util.BaseKeyGenerator; import org.bouncycastle.jcajce.provider.symmetric.util.BaseMac; import org.bouncycastle.jcajce.provider.symmetric.util.BlockCipherProvider; import org.bouncycastle.jcajce.provider.symmetric.util.IvAlgorithmParameters; import org.bouncycastle.jcajce.provider.symmetric.util.PBESecretKeyFactory; public final class Twofish { private Twofish() { } public static class ECB extends BaseBlockCipher { public ECB() { super(new BlockCipherProvider() { public BlockCipher get() { return new TwofishEngine(); } }); } } public static class KeyGen extends BaseKeyGenerator { public KeyGen() { super("Twofish", 256, new CipherKeyGenerator()); } } public static class GMAC extends BaseMac { public GMAC() { super(new GMac(new GCMBlockCipher(new TwofishEngine()))); } } /** * PBEWithSHAAndTwofish-CBC */ static public class PBEWithSHAKeyFactory extends PBESecretKeyFactory { public PBEWithSHAKeyFactory() { super("PBEwithSHAandTwofish-CBC", null, true, PKCS12, SHA1, 256, 128); } } /** * PBEWithSHAAndTwofish-CBC */ static public class PBEWithSHA extends BaseBlockCipher { public PBEWithSHA() { super(new CBCBlockCipher(new TwofishEngine())); } } public static class AlgParams extends IvAlgorithmParameters { protected String engineToString() { return "Twofish IV"; } } public static class Mappings extends SymmetricAlgorithmProvider { private static final String PREFIX = Twofish.class.getName(); public Mappings() { } public void configure(ConfigurableProvider provider) { provider.addAlgorithm("Cipher.Twofish", PREFIX + "$ECB"); provider.addAlgorithm("KeyGenerator.Twofish", PREFIX + "$KeyGen"); provider.addAlgorithm("AlgorithmParameters.Twofish", PREFIX + "$AlgParams"); provider.addAlgorithm("Alg.Alias.AlgorithmParameters.PBEWITHSHAANDTWOFISH", "PKCS12PBE"); provider.addAlgorithm("Alg.Alias.AlgorithmParameters.PBEWITHSHAANDTWOFISH-CBC", "PKCS12PBE"); provider.addAlgorithm("Cipher.PBEWITHSHAANDTWOFISH-CBC", PREFIX + "$PBEWithSHA"); provider.addAlgorithm("SecretKeyFactory.PBEWITHSHAANDTWOFISH-CBC", PREFIX + "$PBEWithSHAKeyFactory"); addGMacAlgorithm(provider, "Twofish", PREFIX + "$GMAC", PREFIX + "$KeyGen"); } } } bouncycastle-1.49.orig/src/org/bouncycastle/jcajce/provider/symmetric/HC128.java0000644000175000017500000000235711701431716027167 0ustar ebourgebourgpackage org.bouncycastle.jcajce.provider.symmetric; import org.bouncycastle.crypto.CipherKeyGenerator; import org.bouncycastle.crypto.engines.HC128Engine; import org.bouncycastle.jcajce.provider.config.ConfigurableProvider; import org.bouncycastle.jcajce.provider.symmetric.util.BaseKeyGenerator; import org.bouncycastle.jcajce.provider.symmetric.util.BaseStreamCipher; import org.bouncycastle.jcajce.provider.util.AlgorithmProvider; public final class HC128 { private HC128() { } public static class Base extends BaseStreamCipher { public Base() { super(new HC128Engine(), 16); } } public static class KeyGen extends BaseKeyGenerator { public KeyGen() { super("HC128", 128, new CipherKeyGenerator()); } } public static class Mappings extends AlgorithmProvider { private static final String PREFIX = HC128.class.getName(); public Mappings() { } public void configure(ConfigurableProvider provider) { provider.addAlgorithm("Cipher.HC128", PREFIX + "$Base"); provider.addAlgorithm("KeyGenerator.HC128", PREFIX + "$KeyGen"); } } } bouncycastle-1.49.orig/src/org/bouncycastle/jcajce/provider/symmetric/HC256.java0000644000175000017500000000235711701431716027171 0ustar ebourgebourgpackage org.bouncycastle.jcajce.provider.symmetric; import org.bouncycastle.crypto.CipherKeyGenerator; import org.bouncycastle.crypto.engines.HC256Engine; import org.bouncycastle.jcajce.provider.config.ConfigurableProvider; import org.bouncycastle.jcajce.provider.symmetric.util.BaseKeyGenerator; import org.bouncycastle.jcajce.provider.symmetric.util.BaseStreamCipher; import org.bouncycastle.jcajce.provider.util.AlgorithmProvider; public final class HC256 { private HC256() { } public static class Base extends BaseStreamCipher { public Base() { super(new HC256Engine(), 32); } } public static class KeyGen extends BaseKeyGenerator { public KeyGen() { super("HC256", 256, new CipherKeyGenerator()); } } public static class Mappings extends AlgorithmProvider { private static final String PREFIX = HC256.class.getName(); public Mappings() { } public void configure(ConfigurableProvider provider) { provider.addAlgorithm("Cipher.HC256", PREFIX + "$Base"); provider.addAlgorithm("KeyGenerator.HC256", PREFIX + "$KeyGen"); } } } bouncycastle-1.49.orig/src/org/bouncycastle/jcajce/provider/symmetric/ARC4.java0000644000175000017500000001105112107307611027117 0ustar ebourgebourgpackage org.bouncycastle.jcajce.provider.symmetric; import org.bouncycastle.asn1.pkcs.PKCSObjectIdentifiers; import org.bouncycastle.crypto.CipherKeyGenerator; import org.bouncycastle.crypto.engines.RC4Engine; import org.bouncycastle.jcajce.provider.config.ConfigurableProvider; import org.bouncycastle.jcajce.provider.symmetric.util.BaseKeyGenerator; import org.bouncycastle.jcajce.provider.symmetric.util.BaseStreamCipher; import org.bouncycastle.jcajce.provider.symmetric.util.PBESecretKeyFactory; import org.bouncycastle.jcajce.provider.util.AlgorithmProvider; public final class ARC4 { private ARC4() { } public static class Base extends BaseStreamCipher { public Base() { super(new RC4Engine(), 0); } } public static class KeyGen extends BaseKeyGenerator { public KeyGen() { super("RC4", 128, new CipherKeyGenerator()); } } /** * PBEWithSHAAnd128BitRC4 */ static public class PBEWithSHAAnd128BitKeyFactory extends PBESecretKeyFactory { public PBEWithSHAAnd128BitKeyFactory() { super("PBEWithSHAAnd128BitRC4", PKCSObjectIdentifiers.pbeWithSHAAnd128BitRC4, true, PKCS12, SHA1, 128, 0); } } /** * PBEWithSHAAnd40BitRC4 */ static public class PBEWithSHAAnd40BitKeyFactory extends PBESecretKeyFactory { public PBEWithSHAAnd40BitKeyFactory() { super("PBEWithSHAAnd128BitRC4", PKCSObjectIdentifiers.pbeWithSHAAnd128BitRC4, true, PKCS12, SHA1, 40, 0); } } /** * PBEWithSHAAnd128BitRC4 */ static public class PBEWithSHAAnd128Bit extends BaseStreamCipher { public PBEWithSHAAnd128Bit() { super(new RC4Engine(), 0); } } /** * PBEWithSHAAnd40BitRC4 */ static public class PBEWithSHAAnd40Bit extends BaseStreamCipher { public PBEWithSHAAnd40Bit() { super(new RC4Engine(), 0); } } public static class Mappings extends AlgorithmProvider { private static final String PREFIX = ARC4.class.getName(); public Mappings() { } public void configure(ConfigurableProvider provider) { provider.addAlgorithm("Cipher.ARC4", PREFIX + "$Base"); provider.addAlgorithm("Alg.Alias.Cipher." + PKCSObjectIdentifiers.rc4, "ARC4"); provider.addAlgorithm("Alg.Alias.Cipher.ARCFOUR", "ARC4"); provider.addAlgorithm("Alg.Alias.Cipher.RC4", "ARC4"); provider.addAlgorithm("KeyGenerator.ARC4", PREFIX + "$KeyGen"); provider.addAlgorithm("Alg.Alias.KeyGenerator.RC4", "ARC4"); provider.addAlgorithm("Alg.Alias.KeyGenerator.1.2.840.113549.3.4", "ARC4"); provider.addAlgorithm("SecretKeyFactory.PBEWITHSHAAND128BITRC4", PREFIX + "$PBEWithSHAAnd128BitKeyFactory"); provider.addAlgorithm("SecretKeyFactory.PBEWITHSHAAND40BITRC4", PREFIX + "$PBEWithSHAAnd40BitKeyFactory"); provider.addAlgorithm("Alg.Alias.AlgorithmParameters." + PKCSObjectIdentifiers.pbeWithSHAAnd128BitRC4, "PKCS12PBE"); provider.addAlgorithm("Alg.Alias.AlgorithmParameters." + PKCSObjectIdentifiers.pbeWithSHAAnd40BitRC4, "PKCS12PBE"); provider.addAlgorithm("Alg.Alias.AlgorithmParameters.PBEWITHSHAAND40BITRC4", "PKCS12PBE"); provider.addAlgorithm("Alg.Alias.AlgorithmParameters.PBEWITHSHAAND128BITRC4", "PKCS12PBE"); provider.addAlgorithm("Alg.Alias.AlgorithmParameters.PBEWITHSHAANDRC4", "PKCS12PBE"); provider.addAlgorithm("Cipher.PBEWITHSHAAND128BITRC4", PREFIX + "$PBEWithSHAAnd128Bit"); provider.addAlgorithm("Cipher.PBEWITHSHAAND40BITRC4", PREFIX + "$PBEWithSHAAnd40Bit"); provider.addAlgorithm("Alg.Alias.SecretKeyFactory." + PKCSObjectIdentifiers.pbeWithSHAAnd128BitRC4, "PBEWITHSHAAND128BITRC4"); provider.addAlgorithm("Alg.Alias.SecretKeyFactory." + PKCSObjectIdentifiers.pbeWithSHAAnd40BitRC4, "PBEWITHSHAAND40BITRC4"); provider.addAlgorithm("Alg.Alias.Cipher.PBEWITHSHA1AND128BITRC4", "PBEWITHSHAAND128BITRC4"); provider.addAlgorithm("Alg.Alias.Cipher.PBEWITHSHA1AND40BITRC4", "PBEWITHSHAAND40BITRC4"); provider.addAlgorithm("Alg.Alias.Cipher." + PKCSObjectIdentifiers.pbeWithSHAAnd128BitRC4, "PBEWITHSHAAND128BITRC4"); provider.addAlgorithm("Alg.Alias.Cipher." + PKCSObjectIdentifiers.pbeWithSHAAnd40BitRC4, "PBEWITHSHAAND40BITRC4"); } } } bouncycastle-1.49.orig/src/org/bouncycastle/jcajce/provider/symmetric/SipHash.java0000644000175000017500000000221012123723262027764 0ustar ebourgebourgpackage org.bouncycastle.jcajce.provider.symmetric; import org.bouncycastle.jcajce.provider.config.ConfigurableProvider; import org.bouncycastle.jcajce.provider.symmetric.util.BaseMac; import org.bouncycastle.jcajce.provider.util.AlgorithmProvider; public final class SipHash { private SipHash() { } public static class Mac extends BaseMac { public Mac() { super(new org.bouncycastle.crypto.macs.SipHash()); } } public static class Mac48 extends BaseMac { public Mac48() { super(new org.bouncycastle.crypto.macs.SipHash(4, 8)); } } public static class Mappings extends AlgorithmProvider { private static final String PREFIX = SipHash.class.getName(); public Mappings() { } public void configure(ConfigurableProvider provider) { provider.addAlgorithm("Mac.SIPHASH", PREFIX + "$Mac"); provider.addAlgorithm("Alg.Alias.Mac.SIPHASH-2-4", "SIPHASH"); provider.addAlgorithm("Mac.SIPHASH-4-8", PREFIX + "$Mac48"); } } } bouncycastle-1.49.orig/src/org/bouncycastle/jcajce/provider/symmetric/PBEPBKDF2.java0000644000175000017500000000702712114016050027665 0ustar ebourgebourgpackage org.bouncycastle.jcajce.provider.symmetric; import java.io.IOException; import java.security.spec.AlgorithmParameterSpec; import java.security.spec.InvalidParameterSpecException; import javax.crypto.spec.PBEParameterSpec; import org.bouncycastle.asn1.ASN1Encoding; import org.bouncycastle.asn1.ASN1Primitive; import org.bouncycastle.asn1.pkcs.PBKDF2Params; import org.bouncycastle.asn1.pkcs.PKCSObjectIdentifiers; import org.bouncycastle.jcajce.provider.config.ConfigurableProvider; import org.bouncycastle.jcajce.provider.symmetric.util.BaseAlgorithmParameters; import org.bouncycastle.jcajce.provider.util.AlgorithmProvider; public class PBEPBKDF2 { private PBEPBKDF2() { } public static class AlgParams extends BaseAlgorithmParameters { PBKDF2Params params; protected byte[] engineGetEncoded() { try { return params.getEncoded(ASN1Encoding.DER); } catch (IOException e) { throw new RuntimeException("Oooops! " + e.toString()); } } protected byte[] engineGetEncoded( String format) { if (this.isASN1FormatString(format)) { return engineGetEncoded(); } return null; } protected AlgorithmParameterSpec localEngineGetParameterSpec( Class paramSpec) throws InvalidParameterSpecException { if (paramSpec == PBEParameterSpec.class) { return new PBEParameterSpec(params.getSalt(), params.getIterationCount().intValue()); } throw new InvalidParameterSpecException("unknown parameter spec passed to PBKDF2 PBE parameters object."); } protected void engineInit( AlgorithmParameterSpec paramSpec) throws InvalidParameterSpecException { if (!(paramSpec instanceof PBEParameterSpec)) { throw new InvalidParameterSpecException("PBEParameterSpec required to initialise a PBKDF2 PBE parameters algorithm parameters object"); } PBEParameterSpec pbeSpec = (PBEParameterSpec)paramSpec; this.params = new PBKDF2Params(pbeSpec.getSalt(), pbeSpec.getIterationCount()); } protected void engineInit( byte[] params) throws IOException { this.params = PBKDF2Params.getInstance(ASN1Primitive.fromByteArray(params)); } protected void engineInit( byte[] params, String format) throws IOException { if (this.isASN1FormatString(format)) { engineInit(params); return; } throw new IOException("Unknown parameters format in PBKDF2 parameters object"); } protected String engineToString() { return "PBKDF2 Parameters"; } } public static class Mappings extends AlgorithmProvider { private static final String PREFIX = PBEPBKDF2.class.getName(); public Mappings() { } public void configure(ConfigurableProvider provider) { provider.addAlgorithm("AlgorithmParameters.PBKDF2", PREFIX + "$AlgParams"); provider.addAlgorithm("Alg.Alias.AlgorithmParameters." + PKCSObjectIdentifiers.id_PBKDF2, "PBKDF2"); } } } bouncycastle-1.49.orig/src/org/bouncycastle/jcajce/provider/symmetric/DES.java0000644000175000017500000004010212107307611027040 0ustar ebourgebourgpackage org.bouncycastle.jcajce.provider.symmetric; import java.security.AlgorithmParameters; import java.security.InvalidAlgorithmParameterException; import java.security.SecureRandom; import java.security.spec.AlgorithmParameterSpec; import java.security.spec.InvalidKeySpecException; import java.security.spec.KeySpec; import javax.crypto.SecretKey; import javax.crypto.spec.DESKeySpec; import javax.crypto.spec.IvParameterSpec; import javax.crypto.spec.PBEKeySpec; import javax.crypto.spec.SecretKeySpec; import org.bouncycastle.asn1.ASN1ObjectIdentifier; import org.bouncycastle.asn1.oiw.OIWObjectIdentifiers; import org.bouncycastle.asn1.pkcs.PKCSObjectIdentifiers; import org.bouncycastle.crypto.CipherParameters; import org.bouncycastle.crypto.KeyGenerationParameters; import org.bouncycastle.crypto.engines.DESEngine; import org.bouncycastle.crypto.engines.RFC3211WrapEngine; import org.bouncycastle.crypto.generators.DESKeyGenerator; import org.bouncycastle.crypto.macs.CBCBlockCipherMac; import org.bouncycastle.crypto.macs.CFBBlockCipherMac; import org.bouncycastle.crypto.macs.CMac; import org.bouncycastle.crypto.macs.ISO9797Alg3Mac; import org.bouncycastle.crypto.modes.CBCBlockCipher; import org.bouncycastle.crypto.paddings.ISO7816d4Padding; import org.bouncycastle.crypto.params.DESParameters; import org.bouncycastle.crypto.params.KeyParameter; import org.bouncycastle.crypto.params.ParametersWithIV; import org.bouncycastle.jcajce.provider.config.ConfigurableProvider; import org.bouncycastle.jcajce.provider.symmetric.util.BCPBEKey; import org.bouncycastle.jcajce.provider.symmetric.util.BaseAlgorithmParameterGenerator; import org.bouncycastle.jcajce.provider.symmetric.util.BaseBlockCipher; import org.bouncycastle.jcajce.provider.symmetric.util.BaseKeyGenerator; import org.bouncycastle.jcajce.provider.symmetric.util.BaseMac; import org.bouncycastle.jcajce.provider.symmetric.util.BaseSecretKeyFactory; import org.bouncycastle.jcajce.provider.symmetric.util.BaseWrapCipher; import org.bouncycastle.jcajce.provider.symmetric.util.PBE; import org.bouncycastle.jcajce.provider.util.AlgorithmProvider; import org.bouncycastle.jce.provider.BouncyCastleProvider; public final class DES { private DES() { } static public class ECB extends BaseBlockCipher { public ECB() { super(new DESEngine()); } } static public class CBC extends BaseBlockCipher { public CBC() { super(new CBCBlockCipher(new DESEngine()), 64); } } /** * DES CFB8 */ public static class DESCFB8 extends BaseMac { public DESCFB8() { super(new CFBBlockCipherMac(new DESEngine())); } } /** * DES64 */ public static class DES64 extends BaseMac { public DES64() { super(new CBCBlockCipherMac(new DESEngine(), 64)); } } /** * DES64with7816-4Padding */ public static class DES64with7816d4 extends BaseMac { public DES64with7816d4() { super(new CBCBlockCipherMac(new DESEngine(), 64, new ISO7816d4Padding())); } } public static class CBCMAC extends BaseMac { public CBCMAC() { super(new CBCBlockCipherMac(new DESEngine())); } } static public class CMAC extends BaseMac { public CMAC() { super(new CMac(new DESEngine())); } } /** * DES9797Alg3with7816-4Padding */ public static class DES9797Alg3with7816d4 extends BaseMac { public DES9797Alg3with7816d4() { super(new ISO9797Alg3Mac(new DESEngine(), new ISO7816d4Padding())); } } /** * DES9797Alg3 */ public static class DES9797Alg3 extends BaseMac { public DES9797Alg3() { super(new ISO9797Alg3Mac(new DESEngine())); } } public static class RFC3211 extends BaseWrapCipher { public RFC3211() { super(new RFC3211WrapEngine(new DESEngine()), 8); } } public static class AlgParamGen extends BaseAlgorithmParameterGenerator { protected void engineInit( AlgorithmParameterSpec genParamSpec, SecureRandom random) throws InvalidAlgorithmParameterException { throw new InvalidAlgorithmParameterException("No supported AlgorithmParameterSpec for DES parameter generation."); } protected AlgorithmParameters engineGenerateParameters() { byte[] iv = new byte[8]; if (random == null) { random = new SecureRandom(); } random.nextBytes(iv); AlgorithmParameters params; try { params = AlgorithmParameters.getInstance("DES", BouncyCastleProvider.PROVIDER_NAME); params.init(new IvParameterSpec(iv)); } catch (Exception e) { throw new RuntimeException(e.getMessage()); } return params; } } /** * DES - the default for this is to generate a key in * a-b-a format that's 24 bytes long but has 16 bytes of * key material (the first 8 bytes is repeated as the last * 8 bytes). If you give it a size, you'll get just what you * asked for. */ public static class KeyGenerator extends BaseKeyGenerator { public KeyGenerator() { super("DES", 64, new DESKeyGenerator()); } protected void engineInit( int keySize, SecureRandom random) { super.engineInit(keySize, random); } protected SecretKey engineGenerateKey() { if (uninitialised) { engine.init(new KeyGenerationParameters(new SecureRandom(), defaultKeySize)); uninitialised = false; } return new SecretKeySpec(engine.generateKey(), algName); } } static public class KeyFactory extends BaseSecretKeyFactory { public KeyFactory() { super("DES", null); } protected KeySpec engineGetKeySpec( SecretKey key, Class keySpec) throws InvalidKeySpecException { if (keySpec == null) { throw new InvalidKeySpecException("keySpec parameter is null"); } if (key == null) { throw new InvalidKeySpecException("key parameter is null"); } if (SecretKeySpec.class.isAssignableFrom(keySpec)) { return new SecretKeySpec(key.getEncoded(), algName); } else if (DESKeySpec.class.isAssignableFrom(keySpec)) { byte[] bytes = key.getEncoded(); try { return new DESKeySpec(bytes); } catch (Exception e) { throw new InvalidKeySpecException(e.toString()); } } throw new InvalidKeySpecException("Invalid KeySpec"); } protected SecretKey engineGenerateSecret( KeySpec keySpec) throws InvalidKeySpecException { if (keySpec instanceof DESKeySpec) { DESKeySpec desKeySpec = (DESKeySpec)keySpec; return new SecretKeySpec(desKeySpec.getKey(), "DES"); } return super.engineGenerateSecret(keySpec); } } static public class DESPBEKeyFactory extends BaseSecretKeyFactory { private boolean forCipher; private int scheme; private int digest; private int keySize; private int ivSize; public DESPBEKeyFactory( String algorithm, ASN1ObjectIdentifier oid, boolean forCipher, int scheme, int digest, int keySize, int ivSize) { super(algorithm, oid); this.forCipher = forCipher; this.scheme = scheme; this.digest = digest; this.keySize = keySize; this.ivSize = ivSize; } protected SecretKey engineGenerateSecret( KeySpec keySpec) throws InvalidKeySpecException { if (keySpec instanceof PBEKeySpec) { PBEKeySpec pbeSpec = (PBEKeySpec)keySpec; CipherParameters param; if (pbeSpec.getSalt() == null) { return new BCPBEKey(this.algName, this.algOid, scheme, digest, keySize, ivSize, pbeSpec, null); } if (forCipher) { param = PBE.Util.makePBEParameters(pbeSpec, scheme, digest, keySize, ivSize); } else { param = PBE.Util.makePBEMacParameters(pbeSpec, scheme, digest, keySize); } KeyParameter kParam; if (param instanceof ParametersWithIV) { kParam = (KeyParameter)((ParametersWithIV)param).getParameters(); } else { kParam = (KeyParameter)param; } DESParameters.setOddParity(kParam.getKey()); return new BCPBEKey(this.algName, this.algOid, scheme, digest, keySize, ivSize, pbeSpec, param); } throw new InvalidKeySpecException("Invalid KeySpec"); } } /** * PBEWithMD2AndDES */ static public class PBEWithMD2KeyFactory extends DESPBEKeyFactory { public PBEWithMD2KeyFactory() { super("PBEwithMD2andDES", PKCSObjectIdentifiers.pbeWithMD2AndDES_CBC, true, PKCS5S1, MD2, 64, 64); } } /** * PBEWithMD5AndDES */ static public class PBEWithMD5KeyFactory extends DESPBEKeyFactory { public PBEWithMD5KeyFactory() { super("PBEwithMD5andDES", PKCSObjectIdentifiers.pbeWithMD5AndDES_CBC, true, PKCS5S1, MD5, 64, 64); } } /** * PBEWithSHA1AndDES */ static public class PBEWithSHA1KeyFactory extends DESPBEKeyFactory { public PBEWithSHA1KeyFactory() { super("PBEwithSHA1andDES", PKCSObjectIdentifiers.pbeWithSHA1AndDES_CBC, true, PKCS5S1, SHA1, 64, 64); } } /** * PBEWithMD2AndDES */ static public class PBEWithMD2 extends BaseBlockCipher { public PBEWithMD2() { super(new CBCBlockCipher(new DESEngine())); } } /** * PBEWithMD5AndDES */ static public class PBEWithMD5 extends BaseBlockCipher { public PBEWithMD5() { super(new CBCBlockCipher(new DESEngine())); } } /** * PBEWithSHA1AndDES */ static public class PBEWithSHA1 extends BaseBlockCipher { public PBEWithSHA1() { super(new CBCBlockCipher(new DESEngine())); } } public static class Mappings extends AlgorithmProvider { private static final String PREFIX = DES.class.getName(); private static final String PACKAGE = "org.bouncycastle.jcajce.provider.symmetric"; // JDK 1.2 public Mappings() { } public void configure(ConfigurableProvider provider) { provider.addAlgorithm("Cipher.DES", PREFIX + "$ECB"); provider.addAlgorithm("Cipher." + OIWObjectIdentifiers.desCBC, PREFIX + "$CBC"); addAlias(provider, OIWObjectIdentifiers.desCBC, "DES"); provider.addAlgorithm("Cipher.DESRFC3211WRAP", PREFIX + "$RFC3211"); provider.addAlgorithm("KeyGenerator.DES", PREFIX + "$KeyGenerator"); provider.addAlgorithm("SecretKeyFactory.DES", PREFIX + "$KeyFactory"); provider.addAlgorithm("Mac.DESCMAC", PREFIX + "$CMAC"); provider.addAlgorithm("Mac.DESMAC", PREFIX + "$CBCMAC"); provider.addAlgorithm("Alg.Alias.Mac.DES", "DESMAC"); provider.addAlgorithm("Mac.DESMAC/CFB8", PREFIX + "$DESCFB8"); provider.addAlgorithm("Alg.Alias.Mac.DES/CFB8", "DESMAC/CFB8"); provider.addAlgorithm("Mac.DESMAC64", PREFIX + "$DES64"); provider.addAlgorithm("Alg.Alias.Mac.DES64", "DESMAC64"); provider.addAlgorithm("Mac.DESMAC64WITHISO7816-4PADDING", PREFIX + "$DES64with7816d4"); provider.addAlgorithm("Alg.Alias.Mac.DES64WITHISO7816-4PADDING", "DESMAC64WITHISO7816-4PADDING"); provider.addAlgorithm("Alg.Alias.Mac.DESISO9797ALG1MACWITHISO7816-4PADDING", "DESMAC64WITHISO7816-4PADDING"); provider.addAlgorithm("Alg.Alias.Mac.DESISO9797ALG1WITHISO7816-4PADDING", "DESMAC64WITHISO7816-4PADDING"); provider.addAlgorithm("Mac.DESWITHISO9797", PREFIX + "$DES9797Alg3"); provider.addAlgorithm("Alg.Alias.Mac.DESISO9797MAC", "DESWITHISO9797"); provider.addAlgorithm("Mac.ISO9797ALG3MAC", PREFIX + "$DES9797Alg3"); provider.addAlgorithm("Alg.Alias.Mac.ISO9797ALG3", "ISO9797ALG3MAC"); provider.addAlgorithm("Mac.ISO9797ALG3WITHISO7816-4PADDING", PREFIX + "$DES9797Alg3with7816d4"); provider.addAlgorithm("Alg.Alias.Mac.ISO9797ALG3MACWITHISO7816-4PADDING", "ISO9797ALG3WITHISO7816-4PADDING"); provider.addAlgorithm("AlgorithmParameters.DES", PACKAGE + ".util.IvAlgorithmParameters"); provider.addAlgorithm("Alg.Alias.AlgorithmParameters." + OIWObjectIdentifiers.desCBC, "DES"); provider.addAlgorithm("AlgorithmParameterGenerator.DES", PREFIX + "$AlgParamGen"); provider.addAlgorithm("Alg.Alias.AlgorithmParameterGenerator." + OIWObjectIdentifiers.desCBC, "DES"); provider.addAlgorithm("Cipher.PBEWITHMD2ANDDES", PREFIX + "$PBEWithMD2"); provider.addAlgorithm("Cipher.PBEWITHMD5ANDDES", PREFIX + "$PBEWithMD5"); provider.addAlgorithm("Cipher.PBEWITHSHA1ANDDES", PREFIX + "$PBEWithSHA1"); provider.addAlgorithm("Alg.Alias.Cipher." + PKCSObjectIdentifiers.pbeWithMD2AndDES_CBC, "PBEWITHMD2ANDDES"); provider.addAlgorithm("Alg.Alias.Cipher." + PKCSObjectIdentifiers.pbeWithMD5AndDES_CBC, "PBEWITHMD5ANDDES"); provider.addAlgorithm("Alg.Alias.Cipher." + PKCSObjectIdentifiers.pbeWithSHA1AndDES_CBC, "PBEWITHSHA1ANDDES"); provider.addAlgorithm("SecretKeyFactory.PBEWITHMD2ANDDES", PREFIX + "$PBEWithMD2KeyFactory"); provider.addAlgorithm("SecretKeyFactory.PBEWITHMD5ANDDES", PREFIX + "$PBEWithMD5KeyFactory"); provider.addAlgorithm("SecretKeyFactory.PBEWITHSHA1ANDDES", PREFIX + "$PBEWithSHA1KeyFactory"); provider.addAlgorithm("Alg.Alias.SecretKeyFactory.PBEWITHMD2ANDDES-CBC", "PBEWITHMD2ANDDES"); provider.addAlgorithm("Alg.Alias.SecretKeyFactory.PBEWITHMD5ANDDES-CBC", "PBEWITHMD5ANDDES"); provider.addAlgorithm("Alg.Alias.SecretKeyFactory.PBEWITHSHA1ANDDES-CBC", "PBEWITHSHA1ANDDES"); provider.addAlgorithm("Alg.Alias.SecretKeyFactory." + PKCSObjectIdentifiers.pbeWithMD2AndDES_CBC, "PBEWITHMD2ANDDES"); provider.addAlgorithm("Alg.Alias.SecretKeyFactory." + PKCSObjectIdentifiers.pbeWithMD5AndDES_CBC, "PBEWITHMD5ANDDES"); provider.addAlgorithm("Alg.Alias.SecretKeyFactory." + PKCSObjectIdentifiers.pbeWithSHA1AndDES_CBC, "PBEWITHSHA1ANDDES"); } private void addAlias(ConfigurableProvider provider, ASN1ObjectIdentifier oid, String name) { provider.addAlgorithm("Alg.Alias.KeyGenerator." + oid.getId(), name); provider.addAlgorithm("Alg.Alias.KeyFactory." + oid.getId(), name); } } } bouncycastle-1.49.orig/src/org/bouncycastle/jcajce/provider/symmetric/Grain128.java0000644000175000017500000000240711701431716027731 0ustar ebourgebourgpackage org.bouncycastle.jcajce.provider.symmetric; import org.bouncycastle.crypto.CipherKeyGenerator; import org.bouncycastle.crypto.engines.Grain128Engine; import org.bouncycastle.jcajce.provider.config.ConfigurableProvider; import org.bouncycastle.jcajce.provider.symmetric.util.BaseKeyGenerator; import org.bouncycastle.jcajce.provider.symmetric.util.BaseStreamCipher; import org.bouncycastle.jcajce.provider.util.AlgorithmProvider; public final class Grain128 { private Grain128() { } public static class Base extends BaseStreamCipher { public Base() { super(new Grain128Engine(), 12); } } public static class KeyGen extends BaseKeyGenerator { public KeyGen() { super("Grain128", 128, new CipherKeyGenerator()); } } public static class Mappings extends AlgorithmProvider { private static final String PREFIX = Grain128.class.getName(); public Mappings() { } public void configure(ConfigurableProvider provider) { provider.addAlgorithm("Cipher.Grain128", PREFIX + "$Base"); provider.addAlgorithm("KeyGenerator.Grain128", PREFIX + "$KeyGen"); } } } bouncycastle-1.49.orig/src/org/bouncycastle/jcajce/provider/symmetric/PBEPKCS12.java0000644000175000017500000000653712114016050027665 0ustar ebourgebourgpackage org.bouncycastle.jcajce.provider.symmetric; import java.io.IOException; import java.security.spec.AlgorithmParameterSpec; import java.security.spec.InvalidParameterSpecException; import javax.crypto.spec.PBEParameterSpec; import org.bouncycastle.asn1.ASN1Encoding; import org.bouncycastle.asn1.ASN1Primitive; import org.bouncycastle.asn1.pkcs.PKCS12PBEParams; import org.bouncycastle.jcajce.provider.config.ConfigurableProvider; import org.bouncycastle.jcajce.provider.symmetric.util.BaseAlgorithmParameters; import org.bouncycastle.jcajce.provider.util.AlgorithmProvider; public class PBEPKCS12 { private PBEPKCS12() { } public static class AlgParams extends BaseAlgorithmParameters { PKCS12PBEParams params; protected byte[] engineGetEncoded() { try { return params.getEncoded(ASN1Encoding.DER); } catch (IOException e) { throw new RuntimeException("Oooops! " + e.toString()); } } protected byte[] engineGetEncoded( String format) { if (this.isASN1FormatString(format)) { return engineGetEncoded(); } return null; } protected AlgorithmParameterSpec localEngineGetParameterSpec( Class paramSpec) throws InvalidParameterSpecException { if (paramSpec == PBEParameterSpec.class) { return new PBEParameterSpec(params.getIV(), params.getIterations().intValue()); } throw new InvalidParameterSpecException("unknown parameter spec passed to PKCS12 PBE parameters object."); } protected void engineInit( AlgorithmParameterSpec paramSpec) throws InvalidParameterSpecException { if (!(paramSpec instanceof PBEParameterSpec)) { throw new InvalidParameterSpecException("PBEParameterSpec required to initialise a PKCS12 PBE parameters algorithm parameters object"); } PBEParameterSpec pbeSpec = (PBEParameterSpec)paramSpec; this.params = new PKCS12PBEParams(pbeSpec.getSalt(), pbeSpec.getIterationCount()); } protected void engineInit( byte[] params) throws IOException { this.params = PKCS12PBEParams.getInstance(ASN1Primitive.fromByteArray(params)); } protected void engineInit( byte[] params, String format) throws IOException { if (this.isASN1FormatString(format)) { engineInit(params); return; } throw new IOException("Unknown parameters format in PKCS12 PBE parameters object"); } protected String engineToString() { return "PKCS12 PBE Parameters"; } } public static class Mappings extends AlgorithmProvider { private static final String PREFIX = PBEPKCS12.class.getName(); public Mappings() { } public void configure(ConfigurableProvider provider) { provider.addAlgorithm("AlgorithmParameters.PKCS12PBE", PREFIX + "$AlgParams"); } } } bouncycastle-1.49.orig/src/org/bouncycastle/jcajce/provider/symmetric/XTEA.java0000644000175000017500000000306511701431716027200 0ustar ebourgebourgpackage org.bouncycastle.jcajce.provider.symmetric; import org.bouncycastle.crypto.CipherKeyGenerator; import org.bouncycastle.crypto.engines.XTEAEngine; import org.bouncycastle.jcajce.provider.config.ConfigurableProvider; import org.bouncycastle.jcajce.provider.symmetric.util.BaseBlockCipher; import org.bouncycastle.jcajce.provider.symmetric.util.BaseKeyGenerator; import org.bouncycastle.jcajce.provider.symmetric.util.IvAlgorithmParameters; import org.bouncycastle.jcajce.provider.util.AlgorithmProvider; public final class XTEA { private XTEA() { } public static class ECB extends BaseBlockCipher { public ECB() { super(new XTEAEngine()); } } public static class KeyGen extends BaseKeyGenerator { public KeyGen() { super("XTEA", 128, new CipherKeyGenerator()); } } public static class AlgParams extends IvAlgorithmParameters { protected String engineToString() { return "XTEA IV"; } } public static class Mappings extends AlgorithmProvider { private static final String PREFIX = XTEA.class.getName(); public Mappings() { } public void configure(ConfigurableProvider provider) { provider.addAlgorithm("Cipher.XTEA", PREFIX + "$ECB"); provider.addAlgorithm("KeyGenerator.XTEA", PREFIX + "$KeyGen"); provider.addAlgorithm("AlgorithmParameters.XTEA", PREFIX + "$AlgParams"); } } } bouncycastle-1.49.orig/src/org/bouncycastle/jcajce/provider/symmetric/Grainv1.java0000644000175000017500000000237511701431716027751 0ustar ebourgebourgpackage org.bouncycastle.jcajce.provider.symmetric; import org.bouncycastle.crypto.CipherKeyGenerator; import org.bouncycastle.crypto.engines.Grainv1Engine; import org.bouncycastle.jcajce.provider.config.ConfigurableProvider; import org.bouncycastle.jcajce.provider.symmetric.util.BaseKeyGenerator; import org.bouncycastle.jcajce.provider.symmetric.util.BaseStreamCipher; import org.bouncycastle.jcajce.provider.util.AlgorithmProvider; public final class Grainv1 { private Grainv1() { } public static class Base extends BaseStreamCipher { public Base() { super(new Grainv1Engine(), 8); } } public static class KeyGen extends BaseKeyGenerator { public KeyGen() { super("Grainv1", 80, new CipherKeyGenerator()); } } public static class Mappings extends AlgorithmProvider { private static final String PREFIX = Grainv1.class.getName(); public Mappings() { } public void configure(ConfigurableProvider provider) { provider.addAlgorithm("Cipher.Grainv1", PREFIX + "$Base"); provider.addAlgorithm("KeyGenerator.Grainv1", PREFIX + "$KeyGen"); } } } bouncycastle-1.49.orig/src/org/bouncycastle/jcajce/provider/symmetric/IDEA.java0000644000175000017500000001765511705207421027151 0ustar ebourgebourgpackage org.bouncycastle.jcajce.provider.symmetric; import java.io.IOException; import java.security.AlgorithmParameters; import java.security.InvalidAlgorithmParameterException; import java.security.SecureRandom; import java.security.spec.AlgorithmParameterSpec; import java.security.spec.InvalidParameterSpecException; import javax.crypto.spec.IvParameterSpec; import org.bouncycastle.asn1.ASN1InputStream; import org.bouncycastle.asn1.ASN1Sequence; import org.bouncycastle.asn1.misc.IDEACBCPar; import org.bouncycastle.crypto.CipherKeyGenerator; import org.bouncycastle.crypto.engines.IDEAEngine; import org.bouncycastle.crypto.macs.CBCBlockCipherMac; import org.bouncycastle.crypto.macs.CFBBlockCipherMac; import org.bouncycastle.crypto.modes.CBCBlockCipher; import org.bouncycastle.jcajce.provider.config.ConfigurableProvider; import org.bouncycastle.jcajce.provider.symmetric.util.BaseAlgorithmParameterGenerator; import org.bouncycastle.jcajce.provider.symmetric.util.BaseAlgorithmParameters; import org.bouncycastle.jcajce.provider.symmetric.util.BaseBlockCipher; import org.bouncycastle.jcajce.provider.symmetric.util.BaseKeyGenerator; import org.bouncycastle.jcajce.provider.symmetric.util.BaseMac; import org.bouncycastle.jcajce.provider.symmetric.util.PBESecretKeyFactory; import org.bouncycastle.jcajce.provider.util.AlgorithmProvider; import org.bouncycastle.jce.provider.BouncyCastleProvider; public final class IDEA { private IDEA() { } public static class ECB extends BaseBlockCipher { public ECB() { super(new IDEAEngine()); } } public static class CBC extends BaseBlockCipher { public CBC() { super(new CBCBlockCipher(new IDEAEngine()), 64); } } public static class KeyGen extends BaseKeyGenerator { public KeyGen() { super("IDEA", 128, new CipherKeyGenerator()); } } public static class PBEWithSHAAndIDEAKeyGen extends PBESecretKeyFactory { public PBEWithSHAAndIDEAKeyGen() { super("PBEwithSHAandIDEA-CBC", null, true, PKCS12, SHA1, 128, 64); } } static public class PBEWithSHAAndIDEA extends BaseBlockCipher { public PBEWithSHAAndIDEA() { super(new CBCBlockCipher(new IDEAEngine())); } } public static class AlgParamGen extends BaseAlgorithmParameterGenerator { protected void engineInit( AlgorithmParameterSpec genParamSpec, SecureRandom random) throws InvalidAlgorithmParameterException { throw new InvalidAlgorithmParameterException("No supported AlgorithmParameterSpec for IDEA parameter generation."); } protected AlgorithmParameters engineGenerateParameters() { byte[] iv = new byte[8]; if (random == null) { random = new SecureRandom(); } random.nextBytes(iv); AlgorithmParameters params; try { params = AlgorithmParameters.getInstance("IDEA", BouncyCastleProvider.PROVIDER_NAME); params.init(new IvParameterSpec(iv)); } catch (Exception e) { throw new RuntimeException(e.getMessage()); } return params; } } public static class AlgParams extends BaseAlgorithmParameters { private byte[] iv; protected byte[] engineGetEncoded() throws IOException { return engineGetEncoded("ASN.1"); } protected byte[] engineGetEncoded( String format) throws IOException { if (this.isASN1FormatString(format)) { return new IDEACBCPar(engineGetEncoded("RAW")).getEncoded(); } if (format.equals("RAW")) { byte[] tmp = new byte[iv.length]; System.arraycopy(iv, 0, tmp, 0, iv.length); return tmp; } return null; } protected AlgorithmParameterSpec localEngineGetParameterSpec( Class paramSpec) throws InvalidParameterSpecException { if (paramSpec == IvParameterSpec.class) { return new IvParameterSpec(iv); } throw new InvalidParameterSpecException("unknown parameter spec passed to IV parameters object."); } protected void engineInit( AlgorithmParameterSpec paramSpec) throws InvalidParameterSpecException { if (!(paramSpec instanceof IvParameterSpec)) { throw new InvalidParameterSpecException("IvParameterSpec required to initialise a IV parameters algorithm parameters object"); } this.iv = ((IvParameterSpec)paramSpec).getIV(); } protected void engineInit( byte[] params) throws IOException { this.iv = new byte[params.length]; System.arraycopy(params, 0, iv, 0, iv.length); } protected void engineInit( byte[] params, String format) throws IOException { if (format.equals("RAW")) { engineInit(params); return; } if (format.equals("ASN.1")) { ASN1InputStream aIn = new ASN1InputStream(params); IDEACBCPar oct = new IDEACBCPar((ASN1Sequence)aIn.readObject()); engineInit(oct.getIV()); return; } throw new IOException("Unknown parameters format in IV parameters object"); } protected String engineToString() { return "IDEA Parameters"; } } public static class Mac extends BaseMac { public Mac() { super(new CBCBlockCipherMac(new IDEAEngine())); } } public static class CFB8Mac extends BaseMac { public CFB8Mac() { super(new CFBBlockCipherMac(new IDEAEngine())); } } public static class Mappings extends AlgorithmProvider { private static final String PREFIX = IDEA.class.getName(); public Mappings() { } public void configure(ConfigurableProvider provider) { provider.addAlgorithm("AlgorithmParameterGenerator.IDEA", PREFIX + "$AlgParamGen"); provider.addAlgorithm("AlgorithmParameterGenerator.1.3.6.1.4.1.188.7.1.1.2", PREFIX + "$AlgParamGen"); provider.addAlgorithm("AlgorithmParameters.IDEA", PREFIX + "$AlgParams"); provider.addAlgorithm("AlgorithmParameters.1.3.6.1.4.1.188.7.1.1.2", PREFIX + "$AlgParams"); provider.addAlgorithm("Alg.Alias.AlgorithmParameters.PBEWITHSHAANDIDEA", "PKCS12PBE"); provider.addAlgorithm("Alg.Alias.AlgorithmParameters.PBEWITHSHAANDIDEA-CBC", "PKCS12PBE"); provider.addAlgorithm("Cipher.IDEA", PREFIX + "$ECB"); provider.addAlgorithm("Cipher.1.3.6.1.4.1.188.7.1.1.2", PREFIX + "$CBC"); provider.addAlgorithm("Cipher.PBEWITHSHAANDIDEA-CBC", PREFIX + "$PBEWithSHAAndIDEA"); provider.addAlgorithm("KeyGenerator.IDEA", PREFIX + "$KeyGen"); provider.addAlgorithm("KeyGenerator.1.3.6.1.4.1.188.7.1.1.2", PREFIX + "$KeyGen"); provider.addAlgorithm("SecretKeyFactory.PBEWITHSHAANDIDEA-CBC", PREFIX + "$PBEWithSHAAndIDEAKeyGen"); provider.addAlgorithm("Mac.IDEAMAC", PREFIX + "$Mac"); provider.addAlgorithm("Alg.Alias.Mac.IDEA", "IDEAMAC"); provider.addAlgorithm("Mac.IDEAMAC/CFB8", PREFIX + "$CFB8Mac"); provider.addAlgorithm("Alg.Alias.Mac.IDEA/CFB8", "IDEAMAC/CFB8"); } } } bouncycastle-1.49.orig/src/org/bouncycastle/jcajce/provider/symmetric/Camellia.java0000644000175000017500000001645612146275676030175 0ustar ebourgebourgpackage org.bouncycastle.jcajce.provider.symmetric; import java.security.AlgorithmParameters; import java.security.InvalidAlgorithmParameterException; import java.security.SecureRandom; import java.security.spec.AlgorithmParameterSpec; import javax.crypto.spec.IvParameterSpec; import org.bouncycastle.asn1.ntt.NTTObjectIdentifiers; import org.bouncycastle.crypto.BlockCipher; import org.bouncycastle.crypto.CipherKeyGenerator; import org.bouncycastle.crypto.engines.CamelliaEngine; import org.bouncycastle.crypto.engines.CamelliaWrapEngine; import org.bouncycastle.crypto.engines.RFC3211WrapEngine; import org.bouncycastle.crypto.macs.GMac; import org.bouncycastle.crypto.modes.CBCBlockCipher; import org.bouncycastle.crypto.modes.GCMBlockCipher; import org.bouncycastle.jcajce.provider.config.ConfigurableProvider; import org.bouncycastle.jcajce.provider.symmetric.util.BaseAlgorithmParameterGenerator; import org.bouncycastle.jcajce.provider.symmetric.util.BaseBlockCipher; import org.bouncycastle.jcajce.provider.symmetric.util.BaseKeyGenerator; import org.bouncycastle.jcajce.provider.symmetric.util.BaseMac; import org.bouncycastle.jcajce.provider.symmetric.util.BaseWrapCipher; import org.bouncycastle.jcajce.provider.symmetric.util.BlockCipherProvider; import org.bouncycastle.jcajce.provider.symmetric.util.IvAlgorithmParameters; import org.bouncycastle.jce.provider.BouncyCastleProvider; public final class Camellia { private Camellia() { } public static class ECB extends BaseBlockCipher { public ECB() { super(new BlockCipherProvider() { public BlockCipher get() { return new CamelliaEngine(); } }); } } public static class CBC extends BaseBlockCipher { public CBC() { super(new CBCBlockCipher(new CamelliaEngine()), 128); } } public static class Wrap extends BaseWrapCipher { public Wrap() { super(new CamelliaWrapEngine()); } } public static class RFC3211Wrap extends BaseWrapCipher { public RFC3211Wrap() { super(new RFC3211WrapEngine(new CamelliaEngine()), 16); } } public static class GMAC extends BaseMac { public GMAC() { super(new GMac(new GCMBlockCipher(new CamelliaEngine()))); } } public static class KeyGen extends BaseKeyGenerator { public KeyGen() { this(256); } public KeyGen(int keySize) { super("Camellia", keySize, new CipherKeyGenerator()); } } public static class KeyGen128 extends KeyGen { public KeyGen128() { super(128); } } public static class KeyGen192 extends KeyGen { public KeyGen192() { super(192); } } public static class KeyGen256 extends KeyGen { public KeyGen256() { super(256); } } public static class AlgParamGen extends BaseAlgorithmParameterGenerator { protected void engineInit( AlgorithmParameterSpec genParamSpec, SecureRandom random) throws InvalidAlgorithmParameterException { throw new InvalidAlgorithmParameterException("No supported AlgorithmParameterSpec for Camellia parameter generation."); } protected AlgorithmParameters engineGenerateParameters() { byte[] iv = new byte[16]; if (random == null) { random = new SecureRandom(); } random.nextBytes(iv); AlgorithmParameters params; try { params = AlgorithmParameters.getInstance("Camellia", BouncyCastleProvider.PROVIDER_NAME); params.init(new IvParameterSpec(iv)); } catch (Exception e) { throw new RuntimeException(e.getMessage()); } return params; } } public static class AlgParams extends IvAlgorithmParameters { protected String engineToString() { return "Camellia IV"; } } public static class Mappings extends SymmetricAlgorithmProvider { private static final String PREFIX = Camellia.class.getName(); public Mappings() { } public void configure(ConfigurableProvider provider) { provider.addAlgorithm("AlgorithmParameters.CAMELLIA", PREFIX + "$AlgParams"); provider.addAlgorithm("Alg.Alias.AlgorithmParameters." + NTTObjectIdentifiers.id_camellia128_cbc, "CAMELLIA"); provider.addAlgorithm("Alg.Alias.AlgorithmParameters." + NTTObjectIdentifiers.id_camellia192_cbc, "CAMELLIA"); provider.addAlgorithm("Alg.Alias.AlgorithmParameters." + NTTObjectIdentifiers.id_camellia256_cbc, "CAMELLIA"); provider.addAlgorithm("AlgorithmParameterGenerator.CAMELLIA", PREFIX + "$AlgParamGen"); provider.addAlgorithm("Alg.Alias.AlgorithmParameterGenerator." + NTTObjectIdentifiers.id_camellia128_cbc, "CAMELLIA"); provider.addAlgorithm("Alg.Alias.AlgorithmParameterGenerator." + NTTObjectIdentifiers.id_camellia192_cbc, "CAMELLIA"); provider.addAlgorithm("Alg.Alias.AlgorithmParameterGenerator." + NTTObjectIdentifiers.id_camellia256_cbc, "CAMELLIA"); provider.addAlgorithm("Cipher.CAMELLIA", PREFIX + "$ECB"); provider.addAlgorithm("Cipher." + NTTObjectIdentifiers.id_camellia128_cbc, PREFIX + "$CBC"); provider.addAlgorithm("Cipher." + NTTObjectIdentifiers.id_camellia192_cbc, PREFIX + "$CBC"); provider.addAlgorithm("Cipher." + NTTObjectIdentifiers.id_camellia256_cbc, PREFIX + "$CBC"); provider.addAlgorithm("Cipher.CAMELLIARFC3211WRAP", PREFIX + "$RFC3211Wrap"); provider.addAlgorithm("Cipher.CAMELLIAWRAP", PREFIX + "$Wrap"); provider.addAlgorithm("Alg.Alias.Cipher." + NTTObjectIdentifiers.id_camellia128_wrap, "CAMELLIAWRAP"); provider.addAlgorithm("Alg.Alias.Cipher." + NTTObjectIdentifiers.id_camellia192_wrap, "CAMELLIAWRAP"); provider.addAlgorithm("Alg.Alias.Cipher." + NTTObjectIdentifiers.id_camellia256_wrap, "CAMELLIAWRAP"); provider.addAlgorithm("KeyGenerator.CAMELLIA", PREFIX + "$KeyGen"); provider.addAlgorithm("KeyGenerator." + NTTObjectIdentifiers.id_camellia128_wrap, PREFIX + "$KeyGen128"); provider.addAlgorithm("KeyGenerator." + NTTObjectIdentifiers.id_camellia192_wrap, PREFIX + "$KeyGen192"); provider.addAlgorithm("KeyGenerator." + NTTObjectIdentifiers.id_camellia256_wrap, PREFIX + "$KeyGen256"); provider.addAlgorithm("KeyGenerator." + NTTObjectIdentifiers.id_camellia128_cbc, PREFIX + "$KeyGen128"); provider.addAlgorithm("KeyGenerator." + NTTObjectIdentifiers.id_camellia192_cbc, PREFIX + "$KeyGen192"); provider.addAlgorithm("KeyGenerator." + NTTObjectIdentifiers.id_camellia256_cbc, PREFIX + "$KeyGen256"); addGMacAlgorithm(provider, "CAMELLIA", PREFIX + "$GMAC", PREFIX + "$KeyGen"); } } } bouncycastle-1.49.orig/src/org/bouncycastle/jcajce/provider/symmetric/AES.java0000644000175000017500000005627512146275676027101 0ustar ebourgebourgpackage org.bouncycastle.jcajce.provider.symmetric; import java.security.AlgorithmParameters; import java.security.InvalidAlgorithmParameterException; import java.security.SecureRandom; import java.security.spec.AlgorithmParameterSpec; import javax.crypto.spec.IvParameterSpec; import org.bouncycastle.asn1.bc.BCObjectIdentifiers; import org.bouncycastle.asn1.nist.NISTObjectIdentifiers; import org.bouncycastle.crypto.BlockCipher; import org.bouncycastle.crypto.BufferedBlockCipher; import org.bouncycastle.crypto.CipherKeyGenerator; import org.bouncycastle.crypto.engines.AESFastEngine; import org.bouncycastle.crypto.engines.AESWrapEngine; import org.bouncycastle.crypto.engines.RFC3211WrapEngine; import org.bouncycastle.crypto.macs.CMac; import org.bouncycastle.crypto.macs.GMac; import org.bouncycastle.crypto.modes.CBCBlockCipher; import org.bouncycastle.crypto.modes.CFBBlockCipher; import org.bouncycastle.crypto.modes.GCMBlockCipher; import org.bouncycastle.crypto.modes.OFBBlockCipher; import org.bouncycastle.jcajce.provider.config.ConfigurableProvider; import org.bouncycastle.jcajce.provider.symmetric.util.BaseAlgorithmParameterGenerator; import org.bouncycastle.jcajce.provider.symmetric.util.BaseBlockCipher; import org.bouncycastle.jcajce.provider.symmetric.util.BaseKeyGenerator; import org.bouncycastle.jcajce.provider.symmetric.util.BaseMac; import org.bouncycastle.jcajce.provider.symmetric.util.BaseWrapCipher; import org.bouncycastle.jcajce.provider.symmetric.util.BlockCipherProvider; import org.bouncycastle.jcajce.provider.symmetric.util.IvAlgorithmParameters; import org.bouncycastle.jcajce.provider.symmetric.util.PBESecretKeyFactory; import org.bouncycastle.jce.provider.BouncyCastleProvider; public final class AES { private AES() { } public static class ECB extends BaseBlockCipher { public ECB() { super(new BlockCipherProvider() { public BlockCipher get() { return new AESFastEngine(); } }); } } public static class CBC extends BaseBlockCipher { public CBC() { super(new CBCBlockCipher(new AESFastEngine()), 128); } } static public class CFB extends BaseBlockCipher { public CFB() { super(new BufferedBlockCipher(new CFBBlockCipher(new AESFastEngine(), 128)), 128); } } static public class OFB extends BaseBlockCipher { public OFB() { super(new BufferedBlockCipher(new OFBBlockCipher(new AESFastEngine(), 128)), 128); } } public static class AESCMAC extends BaseMac { public AESCMAC() { super(new CMac(new AESFastEngine())); } } public static class AESGMAC extends BaseMac { public AESGMAC() { super(new GMac(new GCMBlockCipher(new AESFastEngine()))); } } static public class Wrap extends BaseWrapCipher { public Wrap() { super(new AESWrapEngine()); } } public static class RFC3211Wrap extends BaseWrapCipher { public RFC3211Wrap() { super(new RFC3211WrapEngine(new AESFastEngine()), 16); } } /** * PBEWithAES-CBC */ static public class PBEWithAESCBC extends BaseBlockCipher { public PBEWithAESCBC() { super(new CBCBlockCipher(new AESFastEngine())); } } public static class KeyGen extends BaseKeyGenerator { public KeyGen() { this(192); } public KeyGen(int keySize) { super("AES", keySize, new CipherKeyGenerator()); } } public static class KeyGen128 extends KeyGen { public KeyGen128() { super(128); } } public static class KeyGen192 extends KeyGen { public KeyGen192() { super(192); } } public static class KeyGen256 extends KeyGen { public KeyGen256() { super(256); } } /** * PBEWithSHA1And128BitAES-BC */ static public class PBEWithSHAAnd128BitAESBC extends PBESecretKeyFactory { public PBEWithSHAAnd128BitAESBC() { super("PBEWithSHA1And128BitAES-CBC-BC", null, true, PKCS12, SHA1, 128, 128); } } /** * PBEWithSHA1And192BitAES-BC */ static public class PBEWithSHAAnd192BitAESBC extends PBESecretKeyFactory { public PBEWithSHAAnd192BitAESBC() { super("PBEWithSHA1And192BitAES-CBC-BC", null, true, PKCS12, SHA1, 192, 128); } } /** * PBEWithSHA1And256BitAES-BC */ static public class PBEWithSHAAnd256BitAESBC extends PBESecretKeyFactory { public PBEWithSHAAnd256BitAESBC() { super("PBEWithSHA1And256BitAES-CBC-BC", null, true, PKCS12, SHA1, 256, 128); } } /** * PBEWithSHA256And128BitAES-BC */ static public class PBEWithSHA256And128BitAESBC extends PBESecretKeyFactory { public PBEWithSHA256And128BitAESBC() { super("PBEWithSHA256And128BitAES-CBC-BC", null, true, PKCS12, SHA256, 128, 128); } } /** * PBEWithSHA256And192BitAES-BC */ static public class PBEWithSHA256And192BitAESBC extends PBESecretKeyFactory { public PBEWithSHA256And192BitAESBC() { super("PBEWithSHA256And192BitAES-CBC-BC", null, true, PKCS12, SHA256, 192, 128); } } /** * PBEWithSHA256And256BitAES-BC */ static public class PBEWithSHA256And256BitAESBC extends PBESecretKeyFactory { public PBEWithSHA256And256BitAESBC() { super("PBEWithSHA256And256BitAES-CBC-BC", null, true, PKCS12, SHA256, 256, 128); } } /** * PBEWithMD5And128BitAES-OpenSSL */ static public class PBEWithMD5And128BitAESCBCOpenSSL extends PBESecretKeyFactory { public PBEWithMD5And128BitAESCBCOpenSSL() { super("PBEWithMD5And128BitAES-CBC-OpenSSL", null, true, OPENSSL, MD5, 128, 128); } } /** * PBEWithMD5And192BitAES-OpenSSL */ static public class PBEWithMD5And192BitAESCBCOpenSSL extends PBESecretKeyFactory { public PBEWithMD5And192BitAESCBCOpenSSL() { super("PBEWithMD5And192BitAES-CBC-OpenSSL", null, true, OPENSSL, MD5, 192, 128); } } /** * PBEWithMD5And256BitAES-OpenSSL */ static public class PBEWithMD5And256BitAESCBCOpenSSL extends PBESecretKeyFactory { public PBEWithMD5And256BitAESCBCOpenSSL() { super("PBEWithMD5And256BitAES-CBC-OpenSSL", null, true, OPENSSL, MD5, 256, 128); } } public static class AlgParamGen extends BaseAlgorithmParameterGenerator { protected void engineInit( AlgorithmParameterSpec genParamSpec, SecureRandom random) throws InvalidAlgorithmParameterException { throw new InvalidAlgorithmParameterException("No supported AlgorithmParameterSpec for AES parameter generation."); } protected AlgorithmParameters engineGenerateParameters() { byte[] iv = new byte[16]; if (random == null) { random = new SecureRandom(); } random.nextBytes(iv); AlgorithmParameters params; try { params = AlgorithmParameters.getInstance("AES", BouncyCastleProvider.PROVIDER_NAME); params.init(new IvParameterSpec(iv)); } catch (Exception e) { throw new RuntimeException(e.getMessage()); } return params; } } public static class AlgParams extends IvAlgorithmParameters { protected String engineToString() { return "AES IV"; } } public static class Mappings extends SymmetricAlgorithmProvider { private static final String PREFIX = AES.class.getName(); /** * These three got introduced in some messages as a result of a typo in an * early document. We don't produce anything using these OID values, but we'll * read them. */ private static final String wrongAES128 = "2.16.840.1.101.3.4.2"; private static final String wrongAES192 = "2.16.840.1.101.3.4.22"; private static final String wrongAES256 = "2.16.840.1.101.3.4.42"; public Mappings() { } public void configure(ConfigurableProvider provider) { provider.addAlgorithm("AlgorithmParameters.AES", PREFIX + "$AlgParams"); provider.addAlgorithm("Alg.Alias.AlgorithmParameters." + wrongAES128, "AES"); provider.addAlgorithm("Alg.Alias.AlgorithmParameters." + wrongAES192, "AES"); provider.addAlgorithm("Alg.Alias.AlgorithmParameters." + wrongAES256, "AES"); provider.addAlgorithm("Alg.Alias.AlgorithmParameters." + NISTObjectIdentifiers.id_aes128_CBC, "AES"); provider.addAlgorithm("Alg.Alias.AlgorithmParameters." + NISTObjectIdentifiers.id_aes192_CBC, "AES"); provider.addAlgorithm("Alg.Alias.AlgorithmParameters." + NISTObjectIdentifiers.id_aes256_CBC, "AES"); provider.addAlgorithm("AlgorithmParameterGenerator.AES", PREFIX + "$AlgParamGen"); provider.addAlgorithm("Alg.Alias.AlgorithmParameterGenerator." + wrongAES128, "AES"); provider.addAlgorithm("Alg.Alias.AlgorithmParameterGenerator." + wrongAES192, "AES"); provider.addAlgorithm("Alg.Alias.AlgorithmParameterGenerator." + wrongAES256, "AES"); provider.addAlgorithm("Alg.Alias.AlgorithmParameterGenerator." + NISTObjectIdentifiers.id_aes128_CBC, "AES"); provider.addAlgorithm("Alg.Alias.AlgorithmParameterGenerator." + NISTObjectIdentifiers.id_aes192_CBC, "AES"); provider.addAlgorithm("Alg.Alias.AlgorithmParameterGenerator." + NISTObjectIdentifiers.id_aes256_CBC, "AES"); provider.addAlgorithm("Cipher.AES", PREFIX + "$ECB"); provider.addAlgorithm("Alg.Alias.Cipher." + wrongAES128, "AES"); provider.addAlgorithm("Alg.Alias.Cipher." + wrongAES192, "AES"); provider.addAlgorithm("Alg.Alias.Cipher." + wrongAES256, "AES"); provider.addAlgorithm("Cipher." + NISTObjectIdentifiers.id_aes128_ECB, PREFIX + "$ECB"); provider.addAlgorithm("Cipher." + NISTObjectIdentifiers.id_aes192_ECB, PREFIX + "$ECB"); provider.addAlgorithm("Cipher." + NISTObjectIdentifiers.id_aes256_ECB, PREFIX + "$ECB"); provider.addAlgorithm("Cipher." + NISTObjectIdentifiers.id_aes128_CBC, PREFIX + "$CBC"); provider.addAlgorithm("Cipher." + NISTObjectIdentifiers.id_aes192_CBC, PREFIX + "$CBC"); provider.addAlgorithm("Cipher." + NISTObjectIdentifiers.id_aes256_CBC, PREFIX + "$CBC"); provider.addAlgorithm("Cipher." + NISTObjectIdentifiers.id_aes128_OFB, PREFIX + "$OFB"); provider.addAlgorithm("Cipher." + NISTObjectIdentifiers.id_aes192_OFB, PREFIX + "$OFB"); provider.addAlgorithm("Cipher." + NISTObjectIdentifiers.id_aes256_OFB, PREFIX + "$OFB"); provider.addAlgorithm("Cipher." + NISTObjectIdentifiers.id_aes128_CFB, PREFIX + "$CFB"); provider.addAlgorithm("Cipher." + NISTObjectIdentifiers.id_aes192_CFB, PREFIX + "$CFB"); provider.addAlgorithm("Cipher." + NISTObjectIdentifiers.id_aes256_CFB, PREFIX + "$CFB"); provider.addAlgorithm("Cipher.AESWRAP", PREFIX + "$Wrap"); provider.addAlgorithm("Alg.Alias.Cipher." + NISTObjectIdentifiers.id_aes128_wrap, "AESWRAP"); provider.addAlgorithm("Alg.Alias.Cipher." + NISTObjectIdentifiers.id_aes192_wrap, "AESWRAP"); provider.addAlgorithm("Alg.Alias.Cipher." + NISTObjectIdentifiers.id_aes256_wrap, "AESWRAP"); provider.addAlgorithm("Cipher.AESRFC3211WRAP", PREFIX + "$RFC3211Wrap"); provider.addAlgorithm("KeyGenerator.AES", PREFIX + "$KeyGen"); provider.addAlgorithm("KeyGenerator." + wrongAES128, PREFIX + "$KeyGen128"); provider.addAlgorithm("KeyGenerator." + wrongAES192, PREFIX + "$KeyGen192"); provider.addAlgorithm("KeyGenerator." + wrongAES256, PREFIX + "$KeyGen256"); provider.addAlgorithm("KeyGenerator." + NISTObjectIdentifiers.id_aes128_ECB, PREFIX + "$KeyGen128"); provider.addAlgorithm("KeyGenerator." + NISTObjectIdentifiers.id_aes128_CBC, PREFIX + "$KeyGen128"); provider.addAlgorithm("KeyGenerator." + NISTObjectIdentifiers.id_aes128_OFB, PREFIX + "$KeyGen128"); provider.addAlgorithm("KeyGenerator." + NISTObjectIdentifiers.id_aes128_CFB, PREFIX + "$KeyGen128"); provider.addAlgorithm("KeyGenerator." + NISTObjectIdentifiers.id_aes192_ECB, PREFIX + "$KeyGen192"); provider.addAlgorithm("KeyGenerator." + NISTObjectIdentifiers.id_aes192_CBC, PREFIX + "$KeyGen192"); provider.addAlgorithm("KeyGenerator." + NISTObjectIdentifiers.id_aes192_OFB, PREFIX + "$KeyGen192"); provider.addAlgorithm("KeyGenerator." + NISTObjectIdentifiers.id_aes192_CFB, PREFIX + "$KeyGen192"); provider.addAlgorithm("KeyGenerator." + NISTObjectIdentifiers.id_aes256_ECB, PREFIX + "$KeyGen256"); provider.addAlgorithm("KeyGenerator." + NISTObjectIdentifiers.id_aes256_CBC, PREFIX + "$KeyGen256"); provider.addAlgorithm("KeyGenerator." + NISTObjectIdentifiers.id_aes256_OFB, PREFIX + "$KeyGen256"); provider.addAlgorithm("KeyGenerator." + NISTObjectIdentifiers.id_aes256_CFB, PREFIX + "$KeyGen256"); provider.addAlgorithm("KeyGenerator.AESWRAP", PREFIX + "$KeyGen"); provider.addAlgorithm("KeyGenerator." + NISTObjectIdentifiers.id_aes128_wrap, PREFIX + "$KeyGen128"); provider.addAlgorithm("KeyGenerator." + NISTObjectIdentifiers.id_aes192_wrap, PREFIX + "$KeyGen192"); provider.addAlgorithm("KeyGenerator." + NISTObjectIdentifiers.id_aes256_wrap, PREFIX + "$KeyGen256"); provider.addAlgorithm("Mac.AESCMAC", PREFIX + "$AESCMAC"); provider.addAlgorithm("Alg.Alias.Cipher." + BCObjectIdentifiers.bc_pbe_sha1_pkcs12_aes128_cbc.getId(), "PBEWITHSHAAND128BITAES-CBC-BC"); provider.addAlgorithm("Alg.Alias.Cipher." + BCObjectIdentifiers.bc_pbe_sha1_pkcs12_aes192_cbc.getId(), "PBEWITHSHAAND192BITAES-CBC-BC"); provider.addAlgorithm("Alg.Alias.Cipher." + BCObjectIdentifiers.bc_pbe_sha1_pkcs12_aes256_cbc.getId(), "PBEWITHSHAAND256BITAES-CBC-BC"); provider.addAlgorithm("Alg.Alias.Cipher." + BCObjectIdentifiers.bc_pbe_sha256_pkcs12_aes128_cbc.getId(), "PBEWITHSHA256AND128BITAES-CBC-BC"); provider.addAlgorithm("Alg.Alias.Cipher." + BCObjectIdentifiers.bc_pbe_sha256_pkcs12_aes192_cbc.getId(), "PBEWITHSHA256AND192BITAES-CBC-BC"); provider.addAlgorithm("Alg.Alias.Cipher." + BCObjectIdentifiers.bc_pbe_sha256_pkcs12_aes256_cbc.getId(), "PBEWITHSHA256AND256BITAES-CBC-BC"); provider.addAlgorithm("Cipher.PBEWITHSHAAND128BITAES-CBC-BC", PREFIX + "$PBEWithAESCBC"); provider.addAlgorithm("Cipher.PBEWITHSHAAND192BITAES-CBC-BC", PREFIX + "$PBEWithAESCBC"); provider.addAlgorithm("Cipher.PBEWITHSHAAND256BITAES-CBC-BC", PREFIX + "$PBEWithAESCBC"); provider.addAlgorithm("Cipher.PBEWITHSHA256AND128BITAES-CBC-BC", PREFIX + "$PBEWithAESCBC"); provider.addAlgorithm("Cipher.PBEWITHSHA256AND192BITAES-CBC-BC", PREFIX + "$PBEWithAESCBC"); provider.addAlgorithm("Cipher.PBEWITHSHA256AND256BITAES-CBC-BC", PREFIX + "$PBEWithAESCBC"); provider.addAlgorithm("Alg.Alias.Cipher.PBEWITHSHA1AND128BITAES-CBC-BC","PBEWITHSHAAND128BITAES-CBC-BC"); provider.addAlgorithm("Alg.Alias.Cipher.PBEWITHSHA1AND192BITAES-CBC-BC","PBEWITHSHAAND192BITAES-CBC-BC"); provider.addAlgorithm("Alg.Alias.Cipher.PBEWITHSHA1AND256BITAES-CBC-BC","PBEWITHSHAAND256BITAES-CBC-BC"); provider.addAlgorithm("Alg.Alias.Cipher.PBEWITHSHA-1AND128BITAES-CBC-BC","PBEWITHSHAAND128BITAES-CBC-BC"); provider.addAlgorithm("Alg.Alias.Cipher.PBEWITHSHA-1AND192BITAES-CBC-BC","PBEWITHSHAAND192BITAES-CBC-BC"); provider.addAlgorithm("Alg.Alias.Cipher.PBEWITHSHA-1AND256BITAES-CBC-BC","PBEWITHSHAAND256BITAES-CBC-BC"); provider.addAlgorithm("Alg.Alias.Cipher.PBEWITHSHA-256AND128BITAES-CBC-BC","PBEWITHSHA256AND128BITAES-CBC-BC"); provider.addAlgorithm("Alg.Alias.Cipher.PBEWITHSHA-256AND192BITAES-CBC-BC","PBEWITHSHA256AND192BITAES-CBC-BC"); provider.addAlgorithm("Alg.Alias.Cipher.PBEWITHSHA-256AND256BITAES-CBC-BC","PBEWITHSHA256AND256BITAES-CBC-BC"); provider.addAlgorithm("Cipher.PBEWITHMD5AND128BITAES-CBC-OPENSSL", PREFIX + "$PBEWithAESCBC"); provider.addAlgorithm("Cipher.PBEWITHMD5AND192BITAES-CBC-OPENSSL", PREFIX + "$PBEWithAESCBC"); provider.addAlgorithm("Cipher.PBEWITHMD5AND256BITAES-CBC-OPENSSL", PREFIX + "$PBEWithAESCBC"); provider.addAlgorithm("SecretKeyFactory.PBEWITHMD5AND128BITAES-CBC-OPENSSL", PREFIX + "$PBEWithMD5And128BitAESCBCOpenSSL"); provider.addAlgorithm("SecretKeyFactory.PBEWITHMD5AND192BITAES-CBC-OPENSSL", PREFIX + "$PBEWithMD5And192BitAESCBCOpenSSL"); provider.addAlgorithm("SecretKeyFactory.PBEWITHMD5AND256BITAES-CBC-OPENSSL", PREFIX + "$PBEWithMD5And256BitAESCBCOpenSSL"); provider.addAlgorithm("SecretKeyFactory.PBEWITHSHAAND128BITAES-CBC-BC", PREFIX + "$PBEWithSHAAnd128BitAESBC"); provider.addAlgorithm("SecretKeyFactory.PBEWITHSHAAND192BITAES-CBC-BC", PREFIX + "$PBEWithSHAAnd192BitAESBC"); provider.addAlgorithm("SecretKeyFactory.PBEWITHSHAAND256BITAES-CBC-BC", PREFIX + "$PBEWithSHAAnd256BitAESBC"); provider.addAlgorithm("SecretKeyFactory.PBEWITHSHA256AND128BITAES-CBC-BC", PREFIX + "$PBEWithSHA256And128BitAESBC"); provider.addAlgorithm("SecretKeyFactory.PBEWITHSHA256AND192BITAES-CBC-BC", PREFIX + "$PBEWithSHA256And192BitAESBC"); provider.addAlgorithm("SecretKeyFactory.PBEWITHSHA256AND256BITAES-CBC-BC", PREFIX + "$PBEWithSHA256And256BitAESBC"); provider.addAlgorithm("Alg.Alias.SecretKeyFactory.PBEWITHSHA1AND128BITAES-CBC-BC","PBEWITHSHAAND128BITAES-CBC-BC"); provider.addAlgorithm("Alg.Alias.SecretKeyFactory.PBEWITHSHA1AND192BITAES-CBC-BC","PBEWITHSHAAND192BITAES-CBC-BC"); provider.addAlgorithm("Alg.Alias.SecretKeyFactory.PBEWITHSHA1AND256BITAES-CBC-BC","PBEWITHSHAAND256BITAES-CBC-BC"); provider.addAlgorithm("Alg.Alias.SecretKeyFactory.PBEWITHSHA-1AND128BITAES-CBC-BC","PBEWITHSHAAND128BITAES-CBC-BC"); provider.addAlgorithm("Alg.Alias.SecretKeyFactory.PBEWITHSHA-1AND192BITAES-CBC-BC","PBEWITHSHAAND192BITAES-CBC-BC"); provider.addAlgorithm("Alg.Alias.SecretKeyFactory.PBEWITHSHA-1AND256BITAES-CBC-BC","PBEWITHSHAAND256BITAES-CBC-BC"); provider.addAlgorithm("Alg.Alias.SecretKeyFactory.PBEWITHSHA-256AND128BITAES-CBC-BC","PBEWITHSHA256AND128BITAES-CBC-BC"); provider.addAlgorithm("Alg.Alias.SecretKeyFactory.PBEWITHSHA-256AND192BITAES-CBC-BC","PBEWITHSHA256AND192BITAES-CBC-BC"); provider.addAlgorithm("Alg.Alias.SecretKeyFactory.PBEWITHSHA-256AND256BITAES-CBC-BC","PBEWITHSHA256AND256BITAES-CBC-BC"); provider.addAlgorithm("Alg.Alias.SecretKeyFactory." + BCObjectIdentifiers.bc_pbe_sha1_pkcs12_aes128_cbc.getId(), "PBEWITHSHAAND128BITAES-CBC-BC"); provider.addAlgorithm("Alg.Alias.SecretKeyFactory." + BCObjectIdentifiers.bc_pbe_sha1_pkcs12_aes192_cbc.getId(), "PBEWITHSHAAND192BITAES-CBC-BC"); provider.addAlgorithm("Alg.Alias.SecretKeyFactory." + BCObjectIdentifiers.bc_pbe_sha1_pkcs12_aes256_cbc.getId(), "PBEWITHSHAAND256BITAES-CBC-BC"); provider.addAlgorithm("Alg.Alias.SecretKeyFactory." + BCObjectIdentifiers.bc_pbe_sha256_pkcs12_aes128_cbc.getId(), "PBEWITHSHA256AND128BITAES-CBC-BC"); provider.addAlgorithm("Alg.Alias.SecretKeyFactory." + BCObjectIdentifiers.bc_pbe_sha256_pkcs12_aes192_cbc.getId(), "PBEWITHSHA256AND192BITAES-CBC-BC"); provider.addAlgorithm("Alg.Alias.SecretKeyFactory." + BCObjectIdentifiers.bc_pbe_sha256_pkcs12_aes256_cbc.getId(), "PBEWITHSHA256AND256BITAES-CBC-BC"); provider.addAlgorithm("Alg.Alias.AlgorithmParameters.PBEWITHSHAAND128BITAES-CBC-BC", "PKCS12PBE"); provider.addAlgorithm("Alg.Alias.AlgorithmParameters.PBEWITHSHAAND192BITAES-CBC-BC", "PKCS12PBE"); provider.addAlgorithm("Alg.Alias.AlgorithmParameters.PBEWITHSHAAND256BITAES-CBC-BC", "PKCS12PBE"); provider.addAlgorithm("Alg.Alias.AlgorithmParameters.PBEWITHSHA256AND128BITAES-CBC-BC", "PKCS12PBE"); provider.addAlgorithm("Alg.Alias.AlgorithmParameters.PBEWITHSHA256AND192BITAES-CBC-BC", "PKCS12PBE"); provider.addAlgorithm("Alg.Alias.AlgorithmParameters.PBEWITHSHA256AND256BITAES-CBC-BC", "PKCS12PBE"); provider.addAlgorithm("Alg.Alias.AlgorithmParameters.PBEWITHSHA1AND128BITAES-CBC-BC","PKCS12PBE"); provider.addAlgorithm("Alg.Alias.AlgorithmParameters.PBEWITHSHA1AND192BITAES-CBC-BC","PKCS12PBE"); provider.addAlgorithm("Alg.Alias.AlgorithmParameters.PBEWITHSHA1AND256BITAES-CBC-BC","PKCS12PBE"); provider.addAlgorithm("Alg.Alias.AlgorithmParameters.PBEWITHSHA-1AND128BITAES-CBC-BC","PKCS12PBE"); provider.addAlgorithm("Alg.Alias.AlgorithmParameters.PBEWITHSHA-1AND192BITAES-CBC-BC","PKCS12PBE"); provider.addAlgorithm("Alg.Alias.AlgorithmParameters.PBEWITHSHA-1AND256BITAES-CBC-BC","PKCS12PBE"); provider.addAlgorithm("Alg.Alias.AlgorithmParameters.PBEWITHSHA-256AND128BITAES-CBC-BC","PKCS12PBE"); provider.addAlgorithm("Alg.Alias.AlgorithmParameters.PBEWITHSHA-256AND192BITAES-CBC-BC","PKCS12PBE"); provider.addAlgorithm("Alg.Alias.AlgorithmParameters.PBEWITHSHA-256AND256BITAES-CBC-BC","PKCS12PBE"); provider.addAlgorithm("Alg.Alias.AlgorithmParameters." + BCObjectIdentifiers.bc_pbe_sha1_pkcs12_aes128_cbc.getId(), "PKCS12PBE"); provider.addAlgorithm("Alg.Alias.AlgorithmParameters." + BCObjectIdentifiers.bc_pbe_sha1_pkcs12_aes192_cbc.getId(), "PKCS12PBE"); provider.addAlgorithm("Alg.Alias.AlgorithmParameters." + BCObjectIdentifiers.bc_pbe_sha1_pkcs12_aes256_cbc.getId(), "PKCS12PBE"); provider.addAlgorithm("Alg.Alias.AlgorithmParameters." + BCObjectIdentifiers.bc_pbe_sha256_pkcs12_aes128_cbc.getId(), "PKCS12PBE"); provider.addAlgorithm("Alg.Alias.AlgorithmParameters." + BCObjectIdentifiers.bc_pbe_sha256_pkcs12_aes192_cbc.getId(), "PKCS12PBE"); provider.addAlgorithm("Alg.Alias.AlgorithmParameters." + BCObjectIdentifiers.bc_pbe_sha256_pkcs12_aes256_cbc.getId(), "PKCS12PBE"); addGMacAlgorithm(provider, "AES", PREFIX + "$AESGMAC", PREFIX + "$KeyGen128"); } } } bouncycastle-1.49.orig/src/org/bouncycastle/jcajce/provider/symmetric/Skipjack.java0000644000175000017500000000463711701431716030204 0ustar ebourgebourgpackage org.bouncycastle.jcajce.provider.symmetric; import org.bouncycastle.crypto.CipherKeyGenerator; import org.bouncycastle.crypto.engines.SkipjackEngine; import org.bouncycastle.crypto.macs.CBCBlockCipherMac; import org.bouncycastle.crypto.macs.CFBBlockCipherMac; import org.bouncycastle.jcajce.provider.config.ConfigurableProvider; import org.bouncycastle.jcajce.provider.symmetric.util.BaseBlockCipher; import org.bouncycastle.jcajce.provider.symmetric.util.BaseKeyGenerator; import org.bouncycastle.jcajce.provider.symmetric.util.BaseMac; import org.bouncycastle.jcajce.provider.symmetric.util.IvAlgorithmParameters; import org.bouncycastle.jcajce.provider.util.AlgorithmProvider; public final class Skipjack { private Skipjack() { } public static class ECB extends BaseBlockCipher { public ECB() { super(new SkipjackEngine()); } } public static class KeyGen extends BaseKeyGenerator { public KeyGen() { super("Skipjack", 80, new CipherKeyGenerator()); } } public static class AlgParams extends IvAlgorithmParameters { protected String engineToString() { return "Skipjack IV"; } } public static class Mac extends BaseMac { public Mac() { super(new CBCBlockCipherMac(new SkipjackEngine())); } } public static class MacCFB8 extends BaseMac { public MacCFB8() { super(new CFBBlockCipherMac(new SkipjackEngine())); } } public static class Mappings extends AlgorithmProvider { private static final String PREFIX = Skipjack.class.getName(); public Mappings() { } public void configure(ConfigurableProvider provider) { provider.addAlgorithm("Cipher.SKIPJACK", PREFIX + "$ECB"); provider.addAlgorithm("KeyGenerator.SKIPJACK", PREFIX + "$KeyGen"); provider.addAlgorithm("AlgorithmParameters.SKIPJACK", PREFIX + "$AlgParams"); provider.addAlgorithm("Mac.SKIPJACKMAC", PREFIX + "$Mac"); provider.addAlgorithm("Alg.Alias.Mac.SKIPJACK", "SKIPJACKMAC"); provider.addAlgorithm("Mac.SKIPJACKMAC/CFB8", PREFIX + "$MacCFB8"); provider.addAlgorithm("Alg.Alias.Mac.SKIPJACK/CFB8", "SKIPJACKMAC/CFB8"); } } } bouncycastle-1.49.orig/src/org/bouncycastle/jcajce/provider/symmetric/RC2.java0000644000175000017500000004633312107311656027033 0ustar ebourgebourgpackage org.bouncycastle.jcajce.provider.symmetric; import java.io.IOException; import java.security.AlgorithmParameters; import java.security.InvalidAlgorithmParameterException; import java.security.SecureRandom; import java.security.spec.AlgorithmParameterSpec; import java.security.spec.InvalidParameterSpecException; import javax.crypto.spec.IvParameterSpec; import javax.crypto.spec.RC2ParameterSpec; import org.bouncycastle.asn1.ASN1Primitive; import org.bouncycastle.asn1.pkcs.PKCSObjectIdentifiers; import org.bouncycastle.asn1.pkcs.RC2CBCParameter; import org.bouncycastle.crypto.CipherKeyGenerator; import org.bouncycastle.crypto.engines.RC2Engine; import org.bouncycastle.crypto.engines.RC2WrapEngine; import org.bouncycastle.crypto.macs.CBCBlockCipherMac; import org.bouncycastle.crypto.macs.CFBBlockCipherMac; import org.bouncycastle.crypto.modes.CBCBlockCipher; import org.bouncycastle.jcajce.provider.config.ConfigurableProvider; import org.bouncycastle.jcajce.provider.symmetric.util.BaseAlgorithmParameterGenerator; import org.bouncycastle.jcajce.provider.symmetric.util.BaseAlgorithmParameters; import org.bouncycastle.jcajce.provider.symmetric.util.BaseBlockCipher; import org.bouncycastle.jcajce.provider.symmetric.util.BaseKeyGenerator; import org.bouncycastle.jcajce.provider.symmetric.util.BaseMac; import org.bouncycastle.jcajce.provider.symmetric.util.BaseWrapCipher; import org.bouncycastle.jcajce.provider.symmetric.util.PBESecretKeyFactory; import org.bouncycastle.jcajce.provider.util.AlgorithmProvider; import org.bouncycastle.jce.provider.BouncyCastleProvider; import org.bouncycastle.util.Arrays; public final class RC2 { private RC2() { } /** * RC2 */ static public class ECB extends BaseBlockCipher { public ECB() { super(new RC2Engine()); } } /** * RC2CBC */ static public class CBC extends BaseBlockCipher { public CBC() { super(new CBCBlockCipher(new RC2Engine()), 64); } } public static class Wrap extends BaseWrapCipher { public Wrap() { super(new RC2WrapEngine()); } } /** * RC2 */ public static class CBCMAC extends BaseMac { public CBCMAC() { super(new CBCBlockCipherMac(new RC2Engine())); } } public static class CFB8MAC extends BaseMac { public CFB8MAC() { super(new CFBBlockCipherMac(new RC2Engine())); } } /** * PBEWithSHA1AndRC2 */ static public class PBEWithSHA1KeyFactory extends PBESecretKeyFactory { public PBEWithSHA1KeyFactory() { super("PBEwithSHA1andRC2", PKCSObjectIdentifiers.pbeWithSHA1AndRC2_CBC, true, PKCS5S1, SHA1, 64, 64); } } /** * PBEWithSHAAnd128BitRC2-CBC */ static public class PBEWithSHAAnd128BitKeyFactory extends PBESecretKeyFactory { public PBEWithSHAAnd128BitKeyFactory() { super("PBEwithSHAand128BitRC2-CBC", PKCSObjectIdentifiers.pbeWithSHAAnd128BitRC2_CBC, true, PKCS12, SHA1, 128, 64); } } /** * PBEWithSHAAnd40BitRC2-CBC */ static public class PBEWithSHAAnd40BitKeyFactory extends PBESecretKeyFactory { public PBEWithSHAAnd40BitKeyFactory() { super("PBEwithSHAand40BitRC2-CBC", PKCSObjectIdentifiers.pbeWithSHAAnd40BitRC2_CBC, true, PKCS12, SHA1, 40, 64); } } /** * PBEWithMD5AndRC2 */ static public class PBEWithMD5AndRC2 extends BaseBlockCipher { public PBEWithMD5AndRC2() { super(new CBCBlockCipher(new RC2Engine())); } } /** * PBEWithSHA1AndRC2 */ static public class PBEWithSHA1AndRC2 extends BaseBlockCipher { public PBEWithSHA1AndRC2() { super(new CBCBlockCipher(new RC2Engine())); } } /** * PBEWithSHAAnd128BitRC2-CBC */ static public class PBEWithSHAAnd128BitRC2 extends BaseBlockCipher { public PBEWithSHAAnd128BitRC2() { super(new CBCBlockCipher(new RC2Engine())); } } /** * PBEWithSHAAnd40BitRC2-CBC */ static public class PBEWithSHAAnd40BitRC2 extends BaseBlockCipher { public PBEWithSHAAnd40BitRC2() { super(new CBCBlockCipher(new RC2Engine())); } } /** * PBEWithMD2AndRC2 */ static public class PBEWithMD2KeyFactory extends PBESecretKeyFactory { public PBEWithMD2KeyFactory() { super("PBEwithMD2andRC2", PKCSObjectIdentifiers.pbeWithMD2AndRC2_CBC, true, PKCS5S1, MD2, 64, 64); } } /** * PBEWithMD5AndRC2 */ static public class PBEWithMD5KeyFactory extends PBESecretKeyFactory { public PBEWithMD5KeyFactory() { super("PBEwithMD5andRC2", PKCSObjectIdentifiers.pbeWithMD5AndRC2_CBC, true, PKCS5S1, MD5, 64, 64); } } public static class AlgParamGen extends BaseAlgorithmParameterGenerator { RC2ParameterSpec spec = null; protected void engineInit( AlgorithmParameterSpec genParamSpec, SecureRandom random) throws InvalidAlgorithmParameterException { if (genParamSpec instanceof RC2ParameterSpec) { spec = (RC2ParameterSpec)genParamSpec; return; } throw new InvalidAlgorithmParameterException("No supported AlgorithmParameterSpec for RC2 parameter generation."); } protected AlgorithmParameters engineGenerateParameters() { AlgorithmParameters params; if (spec == null) { byte[] iv = new byte[8]; if (random == null) { random = new SecureRandom(); } random.nextBytes(iv); try { params = AlgorithmParameters.getInstance("RC2", BouncyCastleProvider.PROVIDER_NAME); params.init(new IvParameterSpec(iv)); } catch (Exception e) { throw new RuntimeException(e.getMessage()); } } else { try { params = AlgorithmParameters.getInstance("RC2", BouncyCastleProvider.PROVIDER_NAME); params.init(spec); } catch (Exception e) { throw new RuntimeException(e.getMessage()); } } return params; } } public static class KeyGenerator extends BaseKeyGenerator { public KeyGenerator() { super("RC2", 128, new CipherKeyGenerator()); } } public static class AlgParams extends BaseAlgorithmParameters { private static final short[] table = { 0xbd, 0x56, 0xea, 0xf2, 0xa2, 0xf1, 0xac, 0x2a, 0xb0, 0x93, 0xd1, 0x9c, 0x1b, 0x33, 0xfd, 0xd0, 0x30, 0x04, 0xb6, 0xdc, 0x7d, 0xdf, 0x32, 0x4b, 0xf7, 0xcb, 0x45, 0x9b, 0x31, 0xbb, 0x21, 0x5a, 0x41, 0x9f, 0xe1, 0xd9, 0x4a, 0x4d, 0x9e, 0xda, 0xa0, 0x68, 0x2c, 0xc3, 0x27, 0x5f, 0x80, 0x36, 0x3e, 0xee, 0xfb, 0x95, 0x1a, 0xfe, 0xce, 0xa8, 0x34, 0xa9, 0x13, 0xf0, 0xa6, 0x3f, 0xd8, 0x0c, 0x78, 0x24, 0xaf, 0x23, 0x52, 0xc1, 0x67, 0x17, 0xf5, 0x66, 0x90, 0xe7, 0xe8, 0x07, 0xb8, 0x60, 0x48, 0xe6, 0x1e, 0x53, 0xf3, 0x92, 0xa4, 0x72, 0x8c, 0x08, 0x15, 0x6e, 0x86, 0x00, 0x84, 0xfa, 0xf4, 0x7f, 0x8a, 0x42, 0x19, 0xf6, 0xdb, 0xcd, 0x14, 0x8d, 0x50, 0x12, 0xba, 0x3c, 0x06, 0x4e, 0xec, 0xb3, 0x35, 0x11, 0xa1, 0x88, 0x8e, 0x2b, 0x94, 0x99, 0xb7, 0x71, 0x74, 0xd3, 0xe4, 0xbf, 0x3a, 0xde, 0x96, 0x0e, 0xbc, 0x0a, 0xed, 0x77, 0xfc, 0x37, 0x6b, 0x03, 0x79, 0x89, 0x62, 0xc6, 0xd7, 0xc0, 0xd2, 0x7c, 0x6a, 0x8b, 0x22, 0xa3, 0x5b, 0x05, 0x5d, 0x02, 0x75, 0xd5, 0x61, 0xe3, 0x18, 0x8f, 0x55, 0x51, 0xad, 0x1f, 0x0b, 0x5e, 0x85, 0xe5, 0xc2, 0x57, 0x63, 0xca, 0x3d, 0x6c, 0xb4, 0xc5, 0xcc, 0x70, 0xb2, 0x91, 0x59, 0x0d, 0x47, 0x20, 0xc8, 0x4f, 0x58, 0xe0, 0x01, 0xe2, 0x16, 0x38, 0xc4, 0x6f, 0x3b, 0x0f, 0x65, 0x46, 0xbe, 0x7e, 0x2d, 0x7b, 0x82, 0xf9, 0x40, 0xb5, 0x1d, 0x73, 0xf8, 0xeb, 0x26, 0xc7, 0x87, 0x97, 0x25, 0x54, 0xb1, 0x28, 0xaa, 0x98, 0x9d, 0xa5, 0x64, 0x6d, 0x7a, 0xd4, 0x10, 0x81, 0x44, 0xef, 0x49, 0xd6, 0xae, 0x2e, 0xdd, 0x76, 0x5c, 0x2f, 0xa7, 0x1c, 0xc9, 0x09, 0x69, 0x9a, 0x83, 0xcf, 0x29, 0x39, 0xb9, 0xe9, 0x4c, 0xff, 0x43, 0xab }; private static final short[] ekb = { 0x5d, 0xbe, 0x9b, 0x8b, 0x11, 0x99, 0x6e, 0x4d, 0x59, 0xf3, 0x85, 0xa6, 0x3f, 0xb7, 0x83, 0xc5, 0xe4, 0x73, 0x6b, 0x3a, 0x68, 0x5a, 0xc0, 0x47, 0xa0, 0x64, 0x34, 0x0c, 0xf1, 0xd0, 0x52, 0xa5, 0xb9, 0x1e, 0x96, 0x43, 0x41, 0xd8, 0xd4, 0x2c, 0xdb, 0xf8, 0x07, 0x77, 0x2a, 0xca, 0xeb, 0xef, 0x10, 0x1c, 0x16, 0x0d, 0x38, 0x72, 0x2f, 0x89, 0xc1, 0xf9, 0x80, 0xc4, 0x6d, 0xae, 0x30, 0x3d, 0xce, 0x20, 0x63, 0xfe, 0xe6, 0x1a, 0xc7, 0xb8, 0x50, 0xe8, 0x24, 0x17, 0xfc, 0x25, 0x6f, 0xbb, 0x6a, 0xa3, 0x44, 0x53, 0xd9, 0xa2, 0x01, 0xab, 0xbc, 0xb6, 0x1f, 0x98, 0xee, 0x9a, 0xa7, 0x2d, 0x4f, 0x9e, 0x8e, 0xac, 0xe0, 0xc6, 0x49, 0x46, 0x29, 0xf4, 0x94, 0x8a, 0xaf, 0xe1, 0x5b, 0xc3, 0xb3, 0x7b, 0x57, 0xd1, 0x7c, 0x9c, 0xed, 0x87, 0x40, 0x8c, 0xe2, 0xcb, 0x93, 0x14, 0xc9, 0x61, 0x2e, 0xe5, 0xcc, 0xf6, 0x5e, 0xa8, 0x5c, 0xd6, 0x75, 0x8d, 0x62, 0x95, 0x58, 0x69, 0x76, 0xa1, 0x4a, 0xb5, 0x55, 0x09, 0x78, 0x33, 0x82, 0xd7, 0xdd, 0x79, 0xf5, 0x1b, 0x0b, 0xde, 0x26, 0x21, 0x28, 0x74, 0x04, 0x97, 0x56, 0xdf, 0x3c, 0xf0, 0x37, 0x39, 0xdc, 0xff, 0x06, 0xa4, 0xea, 0x42, 0x08, 0xda, 0xb4, 0x71, 0xb0, 0xcf, 0x12, 0x7a, 0x4e, 0xfa, 0x6c, 0x1d, 0x84, 0x00, 0xc8, 0x7f, 0x91, 0x45, 0xaa, 0x2b, 0xc2, 0xb1, 0x8f, 0xd5, 0xba, 0xf2, 0xad, 0x19, 0xb2, 0x67, 0x36, 0xf7, 0x0f, 0x0a, 0x92, 0x7d, 0xe3, 0x9d, 0xe9, 0x90, 0x3e, 0x23, 0x27, 0x66, 0x13, 0xec, 0x81, 0x15, 0xbd, 0x22, 0xbf, 0x9f, 0x7e, 0xa9, 0x51, 0x4b, 0x4c, 0xfb, 0x02, 0xd3, 0x70, 0x86, 0x31, 0xe7, 0x3b, 0x05, 0x03, 0x54, 0x60, 0x48, 0x65, 0x18, 0xd2, 0xcd, 0x5f, 0x32, 0x88, 0x0e, 0x35, 0xfd }; private byte[] iv; private int parameterVersion = 58; protected byte[] engineGetEncoded() { return Arrays.clone(iv); } protected byte[] engineGetEncoded( String format) throws IOException { if (this.isASN1FormatString(format)) { if (parameterVersion == -1) { return new RC2CBCParameter(engineGetEncoded()).getEncoded(); } else { return new RC2CBCParameter(parameterVersion, engineGetEncoded()).getEncoded(); } } if (format.equals("RAW")) { return engineGetEncoded(); } return null; } protected AlgorithmParameterSpec localEngineGetParameterSpec( Class paramSpec) throws InvalidParameterSpecException { if (paramSpec == RC2ParameterSpec.class) { if (parameterVersion != -1) { if (parameterVersion < 256) { return new RC2ParameterSpec(ekb[parameterVersion], iv); } else { return new RC2ParameterSpec(parameterVersion, iv); } } } if (paramSpec == IvParameterSpec.class) { return new IvParameterSpec(iv); } throw new InvalidParameterSpecException("unknown parameter spec passed to RC2 parameters object."); } protected void engineInit( AlgorithmParameterSpec paramSpec) throws InvalidParameterSpecException { if (paramSpec instanceof IvParameterSpec) { this.iv = ((IvParameterSpec)paramSpec).getIV(); } else if (paramSpec instanceof RC2ParameterSpec) { int effKeyBits = ((RC2ParameterSpec)paramSpec).getEffectiveKeyBits(); if (effKeyBits != -1) { if (effKeyBits < 256) { parameterVersion = table[effKeyBits]; } else { parameterVersion = effKeyBits; } } this.iv = ((RC2ParameterSpec)paramSpec).getIV(); } else { throw new InvalidParameterSpecException("IvParameterSpec or RC2ParameterSpec required to initialise a RC2 parameters algorithm parameters object"); } } protected void engineInit( byte[] params) throws IOException { this.iv = Arrays.clone(params); } protected void engineInit( byte[] params, String format) throws IOException { if (this.isASN1FormatString(format)) { RC2CBCParameter p = RC2CBCParameter.getInstance(ASN1Primitive.fromByteArray(params)); if (p.getRC2ParameterVersion() != null) { parameterVersion = p.getRC2ParameterVersion().intValue(); } iv = p.getIV(); return; } if (format.equals("RAW")) { engineInit(params); return; } throw new IOException("Unknown parameters format in IV parameters object"); } protected String engineToString() { return "RC2 Parameters"; } } public static class Mappings extends AlgorithmProvider { private static final String PREFIX = RC2.class.getName(); public Mappings() { } public void configure(ConfigurableProvider provider) { provider.addAlgorithm("AlgorithmParameterGenerator.RC2", PREFIX + "$AlgParamGen"); provider.addAlgorithm("AlgorithmParameterGenerator.1.2.840.113549.3.2", PREFIX + "$AlgParamGen"); provider.addAlgorithm("KeyGenerator.RC2", PREFIX + "$KeyGenerator"); provider.addAlgorithm("KeyGenerator.1.2.840.113549.3.2", PREFIX + "$KeyGenerator"); provider.addAlgorithm("AlgorithmParameters.RC2", PREFIX + "$AlgParams"); provider.addAlgorithm("AlgorithmParameters.1.2.840.113549.3.2", PREFIX + "$AlgParams"); provider.addAlgorithm("Cipher.RC2", PREFIX + "$ECB"); provider.addAlgorithm("Cipher.RC2WRAP", PREFIX + "$Wrap"); provider.addAlgorithm("Alg.Alias.Cipher." + PKCSObjectIdentifiers.id_alg_CMSRC2wrap, "RC2WRAP"); provider.addAlgorithm("Cipher.1.2.840.113549.3.2", PREFIX + "$CBC"); provider.addAlgorithm("Mac.RC2MAC", PREFIX + "$CBCMAC"); provider.addAlgorithm("Alg.Alias.Mac.RC2", "RC2MAC"); provider.addAlgorithm("Mac.RC2MAC/CFB8", PREFIX + "$CFB8MAC"); provider.addAlgorithm("Alg.Alias.Mac.RC2/CFB8", "RC2MAC/CFB8"); provider.addAlgorithm("Alg.Alias.SecretKeyFactory.PBEWITHMD2ANDRC2-CBC", "PBEWITHMD2ANDRC2"); provider.addAlgorithm("Alg.Alias.SecretKeyFactory.PBEWITHMD5ANDRC2-CBC", "PBEWITHMD5ANDRC2"); provider.addAlgorithm("Alg.Alias.SecretKeyFactory.PBEWITHSHA1ANDRC2-CBC", "PBEWITHSHA1ANDRC2"); provider.addAlgorithm("Alg.Alias.SecretKeyFactory." + PKCSObjectIdentifiers.pbeWithMD2AndRC2_CBC, "PBEWITHMD2ANDRC2"); provider.addAlgorithm("Alg.Alias.SecretKeyFactory." + PKCSObjectIdentifiers.pbeWithMD5AndRC2_CBC, "PBEWITHMD5ANDRC2"); provider.addAlgorithm("Alg.Alias.SecretKeyFactory." + PKCSObjectIdentifiers.pbeWithSHA1AndRC2_CBC, "PBEWITHSHA1ANDRC2"); provider.addAlgorithm("Alg.Alias.SecretKeyFactory.1.2.840.113549.1.12.1.5", "PBEWITHSHAAND128BITRC2-CBC"); provider.addAlgorithm("Alg.Alias.SecretKeyFactory.1.2.840.113549.1.12.1.6", "PBEWITHSHAAND40BITRC2-CBC"); provider.addAlgorithm("SecretKeyFactory.PBEWITHMD2ANDRC2", PREFIX + "$PBEWithMD2KeyFactory"); provider.addAlgorithm("SecretKeyFactory.PBEWITHMD5ANDRC2", PREFIX + "$PBEWithMD5KeyFactory"); provider.addAlgorithm("SecretKeyFactory.PBEWITHSHA1ANDRC2", PREFIX + "$PBEWithSHA1KeyFactory"); provider.addAlgorithm("SecretKeyFactory.PBEWITHSHAAND128BITRC2-CBC", PREFIX + "$PBEWithSHAAnd128BitKeyFactory"); provider.addAlgorithm("SecretKeyFactory.PBEWITHSHAAND40BITRC2-CBC", PREFIX + "$PBEWithSHAAnd40BitKeyFactory"); provider.addAlgorithm("Alg.Alias.Cipher." + PKCSObjectIdentifiers.pbeWithMD2AndRC2_CBC, "PBEWITHMD2ANDRC2"); provider.addAlgorithm("Alg.Alias.Cipher." + PKCSObjectIdentifiers.pbeWithMD5AndRC2_CBC, "PBEWITHMD5ANDRC2"); provider.addAlgorithm("Alg.Alias.Cipher." + PKCSObjectIdentifiers.pbeWithSHA1AndRC2_CBC, "PBEWITHSHA1ANDRC2"); provider.addAlgorithm("Alg.Alias.AlgorithmParameters.1.2.840.113549.1.12.1.5", "PKCS12PBE"); provider.addAlgorithm("Alg.Alias.AlgorithmParameters.1.2.840.113549.1.12.1.6", "PKCS12PBE"); provider.addAlgorithm("Alg.Alias.AlgorithmParameters.PBEWithSHAAnd3KeyTripleDES", "PKCS12PBE"); provider.addAlgorithm("Alg.Alias.Cipher.1.2.840.113549.1.12.1.5", "PBEWITHSHAAND128BITRC2-CBC"); provider.addAlgorithm("Alg.Alias.Cipher.1.2.840.113549.1.12.1.6", "PBEWITHSHAAND40BITRC2-CBC"); provider.addAlgorithm("Alg.Alias.Cipher.PBEWITHSHA1AND128BITRC2-CBC", "PBEWITHSHAAND128BITRC2-CBC"); provider.addAlgorithm("Alg.Alias.Cipher.PBEWITHSHA1AND40BITRC2-CBC", "PBEWITHSHAAND40BITRC2-CBC"); provider.addAlgorithm("Cipher.PBEWITHSHA1ANDRC2", PREFIX + "$PBEWithSHA1AndRC2"); provider.addAlgorithm("Cipher.PBEWITHSHAAND128BITRC2-CBC", PREFIX + "$PBEWithSHAAnd128BitRC2"); provider.addAlgorithm("Cipher.PBEWITHSHAAND40BITRC2-CBC", PREFIX + "$PBEWithSHAAnd40BitRC2"); provider.addAlgorithm("Cipher.PBEWITHMD5ANDRC2", PREFIX + "$PBEWithMD5AndRC2"); provider.addAlgorithm("Alg.Alias.AlgorithmParameters.PBEWITHSHA1ANDRC2", "PKCS12PBE"); provider.addAlgorithm("Alg.Alias.AlgorithmParameters.PBEWITHSHAANDRC2", "PKCS12PBE"); provider.addAlgorithm("Alg.Alias.AlgorithmParameters.PBEWITHSHA1ANDRC2-CBC", "PKCS12PBE"); provider.addAlgorithm("Alg.Alias.AlgorithmParameters.PBEWITHSHAAND40BITRC2-CBC", "PKCS12PBE"); provider.addAlgorithm("Alg.Alias.AlgorithmParameters.PBEWITHSHAAND128BITRC2-CBC", "PKCS12PBE"); } } } bouncycastle-1.49.orig/src/org/bouncycastle/jcajce/provider/symmetric/GOST28147.java0000644000175000017500000001041012107311163027603 0ustar ebourgebourgpackage org.bouncycastle.jcajce.provider.symmetric; import java.security.AlgorithmParameters; import java.security.InvalidAlgorithmParameterException; import java.security.SecureRandom; import java.security.spec.AlgorithmParameterSpec; import javax.crypto.spec.IvParameterSpec; import org.bouncycastle.asn1.cryptopro.CryptoProObjectIdentifiers; import org.bouncycastle.crypto.CipherKeyGenerator; import org.bouncycastle.crypto.engines.GOST28147Engine; import org.bouncycastle.crypto.macs.GOST28147Mac; import org.bouncycastle.crypto.modes.CBCBlockCipher; import org.bouncycastle.jcajce.provider.config.ConfigurableProvider; import org.bouncycastle.jcajce.provider.symmetric.util.BaseAlgorithmParameterGenerator; import org.bouncycastle.jcajce.provider.symmetric.util.BaseBlockCipher; import org.bouncycastle.jcajce.provider.symmetric.util.BaseKeyGenerator; import org.bouncycastle.jcajce.provider.symmetric.util.BaseMac; import org.bouncycastle.jcajce.provider.symmetric.util.IvAlgorithmParameters; import org.bouncycastle.jcajce.provider.util.AlgorithmProvider; import org.bouncycastle.jce.provider.BouncyCastleProvider; public final class GOST28147 { private GOST28147() { } public static class ECB extends BaseBlockCipher { public ECB() { super(new GOST28147Engine()); } } public static class CBC extends BaseBlockCipher { public CBC() { super(new CBCBlockCipher(new GOST28147Engine()), 64); } } /** * GOST28147 */ public static class Mac extends BaseMac { public Mac() { super(new GOST28147Mac()); } } public static class KeyGen extends BaseKeyGenerator { public KeyGen() { this(256); } public KeyGen(int keySize) { super("GOST28147", keySize, new CipherKeyGenerator()); } } public static class AlgParamGen extends BaseAlgorithmParameterGenerator { protected void engineInit( AlgorithmParameterSpec genParamSpec, SecureRandom random) throws InvalidAlgorithmParameterException { throw new InvalidAlgorithmParameterException("No supported AlgorithmParameterSpec for AES parameter generation."); } protected AlgorithmParameters engineGenerateParameters() { byte[] iv = new byte[16]; if (random == null) { random = new SecureRandom(); } random.nextBytes(iv); AlgorithmParameters params; try { params = AlgorithmParameters.getInstance("GOST28147", BouncyCastleProvider.PROVIDER_NAME); params.init(new IvParameterSpec(iv)); } catch (Exception e) { throw new RuntimeException(e.getMessage()); } return params; } } public static class AlgParams extends IvAlgorithmParameters { protected String engineToString() { return "GOST IV"; } } public static class Mappings extends AlgorithmProvider { private static final String PREFIX = GOST28147.class.getName(); public Mappings() { } public void configure(ConfigurableProvider provider) { provider.addAlgorithm("Cipher.GOST28147", PREFIX + "$ECB"); provider.addAlgorithm("Alg.Alias.Cipher.GOST", "GOST28147"); provider.addAlgorithm("Alg.Alias.Cipher.GOST-28147", "GOST28147"); provider.addAlgorithm("Cipher." + CryptoProObjectIdentifiers.gostR28147_cbc, PREFIX + "$CBC"); provider.addAlgorithm("KeyGenerator.GOST28147", PREFIX + "$KeyGen"); provider.addAlgorithm("Alg.Alias.KeyGenerator.GOST", "GOST28147"); provider.addAlgorithm("Alg.Alias.KeyGenerator.GOST-28147", "GOST28147"); provider.addAlgorithm("Alg.Alias.KeyGenerator." + CryptoProObjectIdentifiers.gostR28147_cbc, "GOST28147"); provider.addAlgorithm("Mac.GOST28147MAC", PREFIX + "$Mac"); provider.addAlgorithm("Alg.Alias.Mac.GOST28147", "GOST28147MAC"); } } } bouncycastle-1.49.orig/src/org/bouncycastle/jcajce/provider/symmetric/SEED.java0000644000175000017500000001174512146275676027202 0ustar ebourgebourgpackage org.bouncycastle.jcajce.provider.symmetric; import java.security.AlgorithmParameters; import java.security.InvalidAlgorithmParameterException; import java.security.SecureRandom; import java.security.spec.AlgorithmParameterSpec; import javax.crypto.spec.IvParameterSpec; import org.bouncycastle.asn1.kisa.KISAObjectIdentifiers; import org.bouncycastle.crypto.BlockCipher; import org.bouncycastle.crypto.CipherKeyGenerator; import org.bouncycastle.crypto.engines.SEEDEngine; import org.bouncycastle.crypto.engines.SEEDWrapEngine; import org.bouncycastle.crypto.macs.GMac; import org.bouncycastle.crypto.modes.CBCBlockCipher; import org.bouncycastle.crypto.modes.GCMBlockCipher; import org.bouncycastle.jcajce.provider.config.ConfigurableProvider; import org.bouncycastle.jcajce.provider.symmetric.util.BaseAlgorithmParameterGenerator; import org.bouncycastle.jcajce.provider.symmetric.util.BaseBlockCipher; import org.bouncycastle.jcajce.provider.symmetric.util.BaseKeyGenerator; import org.bouncycastle.jcajce.provider.symmetric.util.BaseMac; import org.bouncycastle.jcajce.provider.symmetric.util.BaseWrapCipher; import org.bouncycastle.jcajce.provider.symmetric.util.BlockCipherProvider; import org.bouncycastle.jcajce.provider.symmetric.util.IvAlgorithmParameters; import org.bouncycastle.jce.provider.BouncyCastleProvider; public final class SEED { private SEED() { } public static class ECB extends BaseBlockCipher { public ECB() { super(new BlockCipherProvider() { public BlockCipher get() { return new SEEDEngine(); } }); } } public static class CBC extends BaseBlockCipher { public CBC() { super(new CBCBlockCipher(new SEEDEngine()), 128); } } public static class Wrap extends BaseWrapCipher { public Wrap() { super(new SEEDWrapEngine()); } } public static class KeyGen extends BaseKeyGenerator { public KeyGen() { super("SEED", 128, new CipherKeyGenerator()); } } public static class GMAC extends BaseMac { public GMAC() { super(new GMac(new GCMBlockCipher(new SEEDEngine()))); } } public static class AlgParamGen extends BaseAlgorithmParameterGenerator { protected void engineInit( AlgorithmParameterSpec genParamSpec, SecureRandom random) throws InvalidAlgorithmParameterException { throw new InvalidAlgorithmParameterException("No supported AlgorithmParameterSpec for SEED parameter generation."); } protected AlgorithmParameters engineGenerateParameters() { byte[] iv = new byte[16]; if (random == null) { random = new SecureRandom(); } random.nextBytes(iv); AlgorithmParameters params; try { params = AlgorithmParameters.getInstance("SEED", BouncyCastleProvider.PROVIDER_NAME); params.init(new IvParameterSpec(iv)); } catch (Exception e) { throw new RuntimeException(e.getMessage()); } return params; } } public static class AlgParams extends IvAlgorithmParameters { protected String engineToString() { return "SEED IV"; } } public static class Mappings extends SymmetricAlgorithmProvider { private static final String PREFIX = SEED.class.getName(); public Mappings() { } public void configure(ConfigurableProvider provider) { provider.addAlgorithm("AlgorithmParameters.SEED", PREFIX + "$AlgParams"); provider.addAlgorithm("Alg.Alias.AlgorithmParameters." + KISAObjectIdentifiers.id_seedCBC, "SEED"); provider.addAlgorithm("AlgorithmParameterGenerator.SEED", PREFIX + "$AlgParamGen"); provider.addAlgorithm("Alg.Alias.AlgorithmParameterGenerator." + KISAObjectIdentifiers.id_seedCBC, "SEED"); provider.addAlgorithm("Cipher.SEED", PREFIX + "$ECB"); provider.addAlgorithm("Cipher." + KISAObjectIdentifiers.id_seedCBC, PREFIX + "$CBC"); provider.addAlgorithm("Cipher.SEEDWRAP", PREFIX + "$Wrap"); provider.addAlgorithm("Alg.Alias.Cipher." + KISAObjectIdentifiers.id_npki_app_cmsSeed_wrap, "SEEDWRAP"); provider.addAlgorithm("KeyGenerator.SEED", PREFIX + "$KeyGen"); provider.addAlgorithm("KeyGenerator." + KISAObjectIdentifiers.id_seedCBC, PREFIX + "$KeyGen"); provider.addAlgorithm("KeyGenerator." + KISAObjectIdentifiers.id_npki_app_cmsSeed_wrap, PREFIX + "$KeyGen"); addGMacAlgorithm(provider, "SEED", PREFIX + "$GMAC", PREFIX + "$KeyGen"); } } } bouncycastle-1.49.orig/src/org/bouncycastle/jcajce/provider/symmetric/VMPC.java0000644000175000017500000000326111701431716027202 0ustar ebourgebourgpackage org.bouncycastle.jcajce.provider.symmetric; import org.bouncycastle.crypto.CipherKeyGenerator; import org.bouncycastle.crypto.engines.VMPCEngine; import org.bouncycastle.crypto.macs.VMPCMac; import org.bouncycastle.jcajce.provider.config.ConfigurableProvider; import org.bouncycastle.jcajce.provider.symmetric.util.BaseKeyGenerator; import org.bouncycastle.jcajce.provider.symmetric.util.BaseMac; import org.bouncycastle.jcajce.provider.symmetric.util.BaseStreamCipher; import org.bouncycastle.jcajce.provider.util.AlgorithmProvider; public final class VMPC { private VMPC() { } public static class Base extends BaseStreamCipher { public Base() { super(new VMPCEngine(), 16); } } public static class KeyGen extends BaseKeyGenerator { public KeyGen() { super("VMPC", 128, new CipherKeyGenerator()); } } public static class Mac extends BaseMac { public Mac() { super(new VMPCMac()); } } public static class Mappings extends AlgorithmProvider { private static final String PREFIX = VMPC.class.getName(); public Mappings() { } public void configure(ConfigurableProvider provider) { provider.addAlgorithm("Cipher.VMPC", PREFIX + "$Base"); provider.addAlgorithm("KeyGenerator.VMPC", PREFIX + "$KeyGen"); provider.addAlgorithm("Mac.VMPCMAC", PREFIX + "$Mac"); provider.addAlgorithm("Alg.Alias.Mac.VMPC", "VMPCMAC"); provider.addAlgorithm("Alg.Alias.Mac.VMPC-MAC", "VMPCMAC"); } } } bouncycastle-1.49.orig/src/org/bouncycastle/jcajce/provider/symmetric/Salsa20.java0000644000175000017500000000240011701431716027634 0ustar ebourgebourgpackage org.bouncycastle.jcajce.provider.symmetric; import org.bouncycastle.crypto.CipherKeyGenerator; import org.bouncycastle.crypto.engines.Salsa20Engine; import org.bouncycastle.jcajce.provider.config.ConfigurableProvider; import org.bouncycastle.jcajce.provider.symmetric.util.BaseKeyGenerator; import org.bouncycastle.jcajce.provider.symmetric.util.BaseStreamCipher; import org.bouncycastle.jcajce.provider.util.AlgorithmProvider; public final class Salsa20 { private Salsa20() { } public static class Base extends BaseStreamCipher { public Base() { super(new Salsa20Engine(), 8); } } public static class KeyGen extends BaseKeyGenerator { public KeyGen() { super("Salsa20", 128, new CipherKeyGenerator()); } } public static class Mappings extends AlgorithmProvider { private static final String PREFIX = Salsa20.class.getName(); public Mappings() { } public void configure(ConfigurableProvider provider) { provider.addAlgorithm("Cipher.SALSA20", PREFIX + "$Base"); provider.addAlgorithm("KeyGenerator.SALSA20", PREFIX + "$KeyGen"); } } } bouncycastle-1.49.orig/src/org/bouncycastle/jcajce/provider/symmetric/CAST6.java0000644000175000017500000000312612146275676027274 0ustar ebourgebourgpackage org.bouncycastle.jcajce.provider.symmetric; import org.bouncycastle.crypto.CipherKeyGenerator; import org.bouncycastle.crypto.engines.CAST6Engine; import org.bouncycastle.crypto.macs.GMac; import org.bouncycastle.crypto.modes.GCMBlockCipher; import org.bouncycastle.jcajce.provider.config.ConfigurableProvider; import org.bouncycastle.jcajce.provider.symmetric.util.BaseBlockCipher; import org.bouncycastle.jcajce.provider.symmetric.util.BaseKeyGenerator; import org.bouncycastle.jcajce.provider.symmetric.util.BaseMac; public final class CAST6 { private CAST6() { } public static class ECB extends BaseBlockCipher { public ECB() { super(new CAST6Engine()); } } public static class KeyGen extends BaseKeyGenerator { public KeyGen() { super("CAST6", 256, new CipherKeyGenerator()); } } public static class GMAC extends BaseMac { public GMAC() { super(new GMac(new GCMBlockCipher(new CAST6Engine()))); } } public static class Mappings extends SymmetricAlgorithmProvider { private static final String PREFIX = CAST6.class.getName(); public Mappings() { } public void configure(ConfigurableProvider provider) { provider.addAlgorithm("Cipher.CAST6", PREFIX + "$ECB"); provider.addAlgorithm("KeyGenerator.CAST6", PREFIX + "$KeyGen"); addGMacAlgorithm(provider, "CAST6", PREFIX + "$GMAC", PREFIX + "$KeyGen"); } } } bouncycastle-1.49.orig/src/org/bouncycastle/jcajce/provider/symmetric/VMPCKSA3.java0000644000175000017500000000241411701431716027623 0ustar ebourgebourgpackage org.bouncycastle.jcajce.provider.symmetric; import org.bouncycastle.crypto.CipherKeyGenerator; import org.bouncycastle.crypto.engines.VMPCKSA3Engine; import org.bouncycastle.jcajce.provider.config.ConfigurableProvider; import org.bouncycastle.jcajce.provider.symmetric.util.BaseKeyGenerator; import org.bouncycastle.jcajce.provider.symmetric.util.BaseStreamCipher; import org.bouncycastle.jcajce.provider.util.AlgorithmProvider; public final class VMPCKSA3 { private VMPCKSA3() { } public static class Base extends BaseStreamCipher { public Base() { super(new VMPCKSA3Engine(), 16); } } public static class KeyGen extends BaseKeyGenerator { public KeyGen() { super("VMPC-KSA3", 128, new CipherKeyGenerator()); } } public static class Mappings extends AlgorithmProvider { private static final String PREFIX = VMPCKSA3.class.getName(); public Mappings() { } public void configure(ConfigurableProvider provider) { provider.addAlgorithm("Cipher.VMPC-KSA3", PREFIX + "$Base"); provider.addAlgorithm("KeyGenerator.VMPC-KSA3", PREFIX + "$KeyGen"); } } } ././@LongLink0000000000000000000000000000014600000000000011566 Lustar rootrootbouncycastle-1.49.orig/src/org/bouncycastle/jcajce/provider/symmetric/SymmetricAlgorithmProvider.javabouncycastle-1.49.orig/src/org/bouncycastle/jcajce/provider/symmetric/SymmetricAlgorithmProvider.jav0000644000175000017500000000146112146275676033651 0ustar ebourgebourgpackage org.bouncycastle.jcajce.provider.symmetric; import org.bouncycastle.jcajce.provider.config.ConfigurableProvider; import org.bouncycastle.jcajce.provider.util.AlgorithmProvider; abstract class SymmetricAlgorithmProvider extends AlgorithmProvider { protected void addGMacAlgorithm( ConfigurableProvider provider, String algorithm, String algorithmClassName, String keyGeneratorClassName) { provider.addAlgorithm("Mac." + algorithm + "-GMAC", algorithmClassName); provider.addAlgorithm("Alg.Alias.Mac." + algorithm + "GMAC", algorithm + "-GMAC"); provider.addAlgorithm("KeyGenerator." + algorithm + "-GMAC", keyGeneratorClassName); provider.addAlgorithm("Alg.Alias.KeyGenerator." + algorithm + "GMAC", algorithm + "-GMAC"); } } bouncycastle-1.49.orig/src/org/bouncycastle/jcajce/provider/symmetric/RC5.java0000644000175000017500000001151011701431716027022 0ustar ebourgebourgpackage org.bouncycastle.jcajce.provider.symmetric; import java.security.AlgorithmParameters; import java.security.InvalidAlgorithmParameterException; import java.security.SecureRandom; import java.security.spec.AlgorithmParameterSpec; import javax.crypto.spec.IvParameterSpec; import org.bouncycastle.crypto.CipherKeyGenerator; import org.bouncycastle.crypto.engines.RC532Engine; import org.bouncycastle.crypto.engines.RC564Engine; import org.bouncycastle.crypto.macs.CBCBlockCipherMac; import org.bouncycastle.crypto.macs.CFBBlockCipherMac; import org.bouncycastle.crypto.modes.CBCBlockCipher; import org.bouncycastle.jcajce.provider.config.ConfigurableProvider; import org.bouncycastle.jcajce.provider.symmetric.util.BaseAlgorithmParameterGenerator; import org.bouncycastle.jcajce.provider.symmetric.util.BaseBlockCipher; import org.bouncycastle.jcajce.provider.symmetric.util.BaseKeyGenerator; import org.bouncycastle.jcajce.provider.symmetric.util.BaseMac; import org.bouncycastle.jcajce.provider.symmetric.util.IvAlgorithmParameters; import org.bouncycastle.jcajce.provider.util.AlgorithmProvider; import org.bouncycastle.jce.provider.BouncyCastleProvider; public final class RC5 { private RC5() { } /** * RC5 */ public static class ECB32 extends BaseBlockCipher { public ECB32() { super(new RC532Engine()); } } /** * RC564 */ public static class ECB64 extends BaseBlockCipher { public ECB64() { super(new RC564Engine()); } } public static class CBC32 extends BaseBlockCipher { public CBC32() { super(new CBCBlockCipher(new RC532Engine()), 64); } } public static class KeyGen32 extends BaseKeyGenerator { public KeyGen32() { super("RC5", 128, new CipherKeyGenerator()); } } /** * RC5 */ public static class KeyGen64 extends BaseKeyGenerator { public KeyGen64() { super("RC5-64", 256, new CipherKeyGenerator()); } } public static class AlgParamGen extends BaseAlgorithmParameterGenerator { protected void engineInit( AlgorithmParameterSpec genParamSpec, SecureRandom random) throws InvalidAlgorithmParameterException { throw new InvalidAlgorithmParameterException("No supported AlgorithmParameterSpec for RC5 parameter generation."); } protected AlgorithmParameters engineGenerateParameters() { byte[] iv = new byte[8]; if (random == null) { random = new SecureRandom(); } random.nextBytes(iv); AlgorithmParameters params; try { params = AlgorithmParameters.getInstance("RC5", BouncyCastleProvider.PROVIDER_NAME); params.init(new IvParameterSpec(iv)); } catch (Exception e) { throw new RuntimeException(e.getMessage()); } return params; } } public static class Mac32 extends BaseMac { public Mac32() { super(new CBCBlockCipherMac(new RC532Engine())); } } public static class CFB8Mac32 extends BaseMac { public CFB8Mac32() { super(new CFBBlockCipherMac(new RC532Engine())); } } public static class AlgParams extends IvAlgorithmParameters { protected String engineToString() { return "RC5 IV"; } } public static class Mappings extends AlgorithmProvider { private static final String PREFIX = RC5.class.getName(); public Mappings() { } public void configure(ConfigurableProvider provider) { provider.addAlgorithm("Cipher.RC5", PREFIX + "$ECB32"); provider.addAlgorithm("Alg.Alias.Cipher.RC5-32", "RC5"); provider.addAlgorithm("Cipher.RC5-64", PREFIX + "$ECB64"); provider.addAlgorithm("KeyGenerator.RC5", PREFIX + "$KeyGen32"); provider.addAlgorithm("Alg.Alias.KeyGenerator.RC5-32", "RC5"); provider.addAlgorithm("KeyGenerator.RC5-64", PREFIX + "$KeyGen64"); provider.addAlgorithm("AlgorithmParameters.RC5", PREFIX + "$AlgParams"); provider.addAlgorithm("AlgorithmParameters.RC5-64", PREFIX + "$AlgParams"); provider.addAlgorithm("Mac.RC5MAC", PREFIX + "$Mac32"); provider.addAlgorithm("Alg.Alias.Mac.RC5", "RC5MAC"); provider.addAlgorithm("Mac.RC5MAC/CFB8", PREFIX + "$CFB8Mac32"); provider.addAlgorithm("Alg.Alias.Mac.RC5/CFB8", "RC5MAC/CFB8"); } } } bouncycastle-1.49.orig/src/org/bouncycastle/jcajce/provider/symmetric/RC6.java0000644000175000017500000001055512146275676027052 0ustar ebourgebourgpackage org.bouncycastle.jcajce.provider.symmetric; import java.security.AlgorithmParameters; import java.security.InvalidAlgorithmParameterException; import java.security.SecureRandom; import java.security.spec.AlgorithmParameterSpec; import javax.crypto.spec.IvParameterSpec; import org.bouncycastle.crypto.BlockCipher; import org.bouncycastle.crypto.BufferedBlockCipher; import org.bouncycastle.crypto.CipherKeyGenerator; import org.bouncycastle.crypto.engines.RC6Engine; import org.bouncycastle.crypto.macs.GMac; import org.bouncycastle.crypto.modes.CBCBlockCipher; import org.bouncycastle.crypto.modes.CFBBlockCipher; import org.bouncycastle.crypto.modes.GCMBlockCipher; import org.bouncycastle.crypto.modes.OFBBlockCipher; import org.bouncycastle.jcajce.provider.config.ConfigurableProvider; import org.bouncycastle.jcajce.provider.symmetric.util.BaseAlgorithmParameterGenerator; import org.bouncycastle.jcajce.provider.symmetric.util.BaseBlockCipher; import org.bouncycastle.jcajce.provider.symmetric.util.BaseKeyGenerator; import org.bouncycastle.jcajce.provider.symmetric.util.BaseMac; import org.bouncycastle.jcajce.provider.symmetric.util.BlockCipherProvider; import org.bouncycastle.jcajce.provider.symmetric.util.IvAlgorithmParameters; import org.bouncycastle.jce.provider.BouncyCastleProvider; public final class RC6 { private RC6() { } public static class ECB extends BaseBlockCipher { public ECB() { super(new BlockCipherProvider() { public BlockCipher get() { return new RC6Engine(); } }); } } public static class CBC extends BaseBlockCipher { public CBC() { super(new CBCBlockCipher(new RC6Engine()), 128); } } static public class CFB extends BaseBlockCipher { public CFB() { super(new BufferedBlockCipher(new CFBBlockCipher(new RC6Engine(), 128)), 128); } } static public class OFB extends BaseBlockCipher { public OFB() { super(new BufferedBlockCipher(new OFBBlockCipher(new RC6Engine(), 128)), 128); } } public static class GMAC extends BaseMac { public GMAC() { super(new GMac(new GCMBlockCipher(new RC6Engine()))); } } public static class KeyGen extends BaseKeyGenerator { public KeyGen() { super("RC6", 256, new CipherKeyGenerator()); } } public static class AlgParamGen extends BaseAlgorithmParameterGenerator { protected void engineInit( AlgorithmParameterSpec genParamSpec, SecureRandom random) throws InvalidAlgorithmParameterException { throw new InvalidAlgorithmParameterException("No supported AlgorithmParameterSpec for RC6 parameter generation."); } protected AlgorithmParameters engineGenerateParameters() { byte[] iv = new byte[16]; if (random == null) { random = new SecureRandom(); } random.nextBytes(iv); AlgorithmParameters params; try { params = AlgorithmParameters.getInstance("RC6", BouncyCastleProvider.PROVIDER_NAME); params.init(new IvParameterSpec(iv)); } catch (Exception e) { throw new RuntimeException(e.getMessage()); } return params; } } public static class AlgParams extends IvAlgorithmParameters { protected String engineToString() { return "RC6 IV"; } } public static class Mappings extends SymmetricAlgorithmProvider { private static final String PREFIX = RC6.class.getName(); public Mappings() { } public void configure(ConfigurableProvider provider) { provider.addAlgorithm("Cipher.RC6", PREFIX + "$ECB"); provider.addAlgorithm("KeyGenerator.RC6", PREFIX + "$KeyGen"); provider.addAlgorithm("AlgorithmParameters.RC6", PREFIX + "$AlgParams"); addGMacAlgorithm(provider, "RC6", PREFIX + "$GMAC", PREFIX + "$KeyGen"); } } } bouncycastle-1.49.orig/src/org/bouncycastle/jcajce/provider/symmetric/Noekeon.java0000644000175000017500000000672412146275676030061 0ustar ebourgebourgpackage org.bouncycastle.jcajce.provider.symmetric; import java.security.AlgorithmParameters; import java.security.InvalidAlgorithmParameterException; import java.security.SecureRandom; import java.security.spec.AlgorithmParameterSpec; import javax.crypto.spec.IvParameterSpec; import org.bouncycastle.crypto.CipherKeyGenerator; import org.bouncycastle.crypto.engines.NoekeonEngine; import org.bouncycastle.crypto.macs.GMac; import org.bouncycastle.crypto.modes.GCMBlockCipher; import org.bouncycastle.jcajce.provider.config.ConfigurableProvider; import org.bouncycastle.jcajce.provider.symmetric.util.BaseAlgorithmParameterGenerator; import org.bouncycastle.jcajce.provider.symmetric.util.BaseBlockCipher; import org.bouncycastle.jcajce.provider.symmetric.util.BaseKeyGenerator; import org.bouncycastle.jcajce.provider.symmetric.util.BaseMac; import org.bouncycastle.jcajce.provider.symmetric.util.IvAlgorithmParameters; import org.bouncycastle.jce.provider.BouncyCastleProvider; public final class Noekeon { private Noekeon() { } public static class ECB extends BaseBlockCipher { public ECB() { super(new NoekeonEngine()); } } public static class KeyGen extends BaseKeyGenerator { public KeyGen() { super("Noekeon", 128, new CipherKeyGenerator()); } } public static class GMAC extends BaseMac { public GMAC() { super(new GMac(new GCMBlockCipher(new NoekeonEngine()))); } } public static class AlgParamGen extends BaseAlgorithmParameterGenerator { protected void engineInit( AlgorithmParameterSpec genParamSpec, SecureRandom random) throws InvalidAlgorithmParameterException { throw new InvalidAlgorithmParameterException("No supported AlgorithmParameterSpec for Noekeon parameter generation."); } protected AlgorithmParameters engineGenerateParameters() { byte[] iv = new byte[16]; if (random == null) { random = new SecureRandom(); } random.nextBytes(iv); AlgorithmParameters params; try { params = AlgorithmParameters.getInstance("Noekeon", BouncyCastleProvider.PROVIDER_NAME); params.init(new IvParameterSpec(iv)); } catch (Exception e) { throw new RuntimeException(e.getMessage()); } return params; } } public static class AlgParams extends IvAlgorithmParameters { protected String engineToString() { return "Noekeon IV"; } } public static class Mappings extends SymmetricAlgorithmProvider { private static final String PREFIX = Noekeon.class.getName(); public Mappings() { } public void configure(ConfigurableProvider provider) { provider.addAlgorithm("AlgorithmParameters.NOEKEON", PREFIX + "$AlgParams"); provider.addAlgorithm("AlgorithmParameterGenerator.NOEKEON", PREFIX + "$AlgParamGen"); provider.addAlgorithm("Cipher.NOEKEON", PREFIX + "$ECB"); provider.addAlgorithm("KeyGenerator.NOEKEON", PREFIX + "$KeyGen"); addGMacAlgorithm(provider, "NOEKEON", PREFIX + "$GMAC", PREFIX + "$KeyGen"); } } } bouncycastle-1.49.orig/src/org/bouncycastle/jcajce/provider/symmetric/DESede.java0000644000175000017500000003654212143615523027537 0ustar ebourgebourgpackage org.bouncycastle.jcajce.provider.symmetric; import java.security.AlgorithmParameters; import java.security.InvalidAlgorithmParameterException; import java.security.SecureRandom; import java.security.spec.AlgorithmParameterSpec; import java.security.spec.InvalidKeySpecException; import java.security.spec.KeySpec; import javax.crypto.SecretKey; import javax.crypto.spec.DESedeKeySpec; import javax.crypto.spec.IvParameterSpec; import javax.crypto.spec.SecretKeySpec; import org.bouncycastle.asn1.pkcs.PKCSObjectIdentifiers; import org.bouncycastle.crypto.KeyGenerationParameters; import org.bouncycastle.crypto.engines.DESedeEngine; import org.bouncycastle.crypto.engines.DESedeWrapEngine; import org.bouncycastle.crypto.engines.RFC3211WrapEngine; import org.bouncycastle.crypto.generators.DESedeKeyGenerator; import org.bouncycastle.crypto.macs.CBCBlockCipherMac; import org.bouncycastle.crypto.macs.CFBBlockCipherMac; import org.bouncycastle.crypto.macs.CMac; import org.bouncycastle.crypto.modes.CBCBlockCipher; import org.bouncycastle.crypto.paddings.ISO7816d4Padding; import org.bouncycastle.jcajce.provider.config.ConfigurableProvider; import org.bouncycastle.jcajce.provider.symmetric.util.BaseAlgorithmParameterGenerator; import org.bouncycastle.jcajce.provider.symmetric.util.BaseBlockCipher; import org.bouncycastle.jcajce.provider.symmetric.util.BaseKeyGenerator; import org.bouncycastle.jcajce.provider.symmetric.util.BaseMac; import org.bouncycastle.jcajce.provider.symmetric.util.BaseSecretKeyFactory; import org.bouncycastle.jcajce.provider.symmetric.util.BaseWrapCipher; import org.bouncycastle.jcajce.provider.util.AlgorithmProvider; import org.bouncycastle.jce.provider.BouncyCastleProvider; public final class DESede { private DESede() { } static public class ECB extends BaseBlockCipher { public ECB() { super(new DESedeEngine()); } } static public class CBC extends BaseBlockCipher { public CBC() { super(new CBCBlockCipher(new DESedeEngine()), 64); } } /** * DESede CFB8 */ public static class DESedeCFB8 extends BaseMac { public DESedeCFB8() { super(new CFBBlockCipherMac(new DESedeEngine())); } } /** * DESede64 */ public static class DESede64 extends BaseMac { public DESede64() { super(new CBCBlockCipherMac(new DESedeEngine(), 64)); } } /** * DESede64with7816-4Padding */ public static class DESede64with7816d4 extends BaseMac { public DESede64with7816d4() { super(new CBCBlockCipherMac(new DESedeEngine(), 64, new ISO7816d4Padding())); } } public static class CBCMAC extends BaseMac { public CBCMAC() { super(new CBCBlockCipherMac(new DESedeEngine())); } } static public class CMAC extends BaseMac { public CMAC() { super(new CMac(new DESedeEngine())); } } public static class Wrap extends BaseWrapCipher { public Wrap() { super(new DESedeWrapEngine()); } } public static class RFC3211 extends BaseWrapCipher { public RFC3211() { super(new RFC3211WrapEngine(new DESedeEngine()), 8); } } /** * DESede - the default for this is to generate a key in * a-b-a format that's 24 bytes long but has 16 bytes of * key material (the first 8 bytes is repeated as the last * 8 bytes). If you give it a size, you'll get just what you * asked for. */ public static class KeyGenerator extends BaseKeyGenerator { private boolean keySizeSet = false; public KeyGenerator() { super("DESede", 192, new DESedeKeyGenerator()); } protected void engineInit( int keySize, SecureRandom random) { super.engineInit(keySize, random); keySizeSet = true; } protected SecretKey engineGenerateKey() { if (uninitialised) { engine.init(new KeyGenerationParameters(new SecureRandom(), defaultKeySize)); uninitialised = false; } // // if no key size has been defined generate a 24 byte key in // the a-b-a format // if (!keySizeSet) { byte[] k = engine.generateKey(); System.arraycopy(k, 0, k, 16, 8); return new SecretKeySpec(k, algName); } else { return new SecretKeySpec(engine.generateKey(), algName); } } } /** * generate a desEDE key in the a-b-c format. */ public static class KeyGenerator3 extends BaseKeyGenerator { public KeyGenerator3() { super("DESede3", 192, new DESedeKeyGenerator()); } } /** * PBEWithSHAAnd3-KeyTripleDES-CBC */ static public class PBEWithSHAAndDES3Key extends BaseBlockCipher { public PBEWithSHAAndDES3Key() { super(new CBCBlockCipher(new DESedeEngine())); } } /** * PBEWithSHAAnd2-KeyTripleDES-CBC */ static public class PBEWithSHAAndDES2Key extends BaseBlockCipher { public PBEWithSHAAndDES2Key() { super(new CBCBlockCipher(new DESedeEngine())); } } /** * PBEWithSHAAnd3-KeyTripleDES-CBC */ static public class PBEWithSHAAndDES3KeyFactory extends DES.DESPBEKeyFactory { public PBEWithSHAAndDES3KeyFactory() { super("PBEwithSHAandDES3Key-CBC", PKCSObjectIdentifiers.pbeWithSHAAnd3_KeyTripleDES_CBC, true, PKCS12, SHA1, 192, 64); } } /** * PBEWithSHAAnd2-KeyTripleDES-CBC */ static public class PBEWithSHAAndDES2KeyFactory extends DES.DESPBEKeyFactory { public PBEWithSHAAndDES2KeyFactory() { super("PBEwithSHAandDES2Key-CBC", PKCSObjectIdentifiers.pbeWithSHAAnd2_KeyTripleDES_CBC, true, PKCS12, SHA1, 128, 64); } } public static class AlgParamGen extends BaseAlgorithmParameterGenerator { protected void engineInit( AlgorithmParameterSpec genParamSpec, SecureRandom random) throws InvalidAlgorithmParameterException { throw new InvalidAlgorithmParameterException("No supported AlgorithmParameterSpec for DES parameter generation."); } protected AlgorithmParameters engineGenerateParameters() { byte[] iv = new byte[8]; if (random == null) { random = new SecureRandom(); } random.nextBytes(iv); AlgorithmParameters params; try { params = AlgorithmParameters.getInstance("DES", BouncyCastleProvider.PROVIDER_NAME); params.init(new IvParameterSpec(iv)); } catch (Exception e) { throw new RuntimeException(e.getMessage()); } return params; } } static public class KeyFactory extends BaseSecretKeyFactory { public KeyFactory() { super("DESede", null); } protected KeySpec engineGetKeySpec( SecretKey key, Class keySpec) throws InvalidKeySpecException { if (keySpec == null) { throw new InvalidKeySpecException("keySpec parameter is null"); } if (key == null) { throw new InvalidKeySpecException("key parameter is null"); } if (SecretKeySpec.class.isAssignableFrom(keySpec)) { return new SecretKeySpec(key.getEncoded(), algName); } else if (DESedeKeySpec.class.isAssignableFrom(keySpec)) { byte[] bytes = key.getEncoded(); try { if (bytes.length == 16) { byte[] longKey = new byte[24]; System.arraycopy(bytes, 0, longKey, 0, 16); System.arraycopy(bytes, 0, longKey, 16, 8); return new DESedeKeySpec(longKey); } else { return new DESedeKeySpec(bytes); } } catch (Exception e) { throw new InvalidKeySpecException(e.toString()); } } throw new InvalidKeySpecException("Invalid KeySpec"); } protected SecretKey engineGenerateSecret( KeySpec keySpec) throws InvalidKeySpecException { if (keySpec instanceof DESedeKeySpec) { DESedeKeySpec desKeySpec = (DESedeKeySpec)keySpec; return new SecretKeySpec(desKeySpec.getKey(), "DESede"); } return super.engineGenerateSecret(keySpec); } } public static class Mappings extends AlgorithmProvider { private static final String PREFIX = DESede.class.getName(); private static final String PACKAGE = "org.bouncycastle.jcajce.provider.symmetric"; // JDK 1.2 public Mappings() { } public void configure(ConfigurableProvider provider) { provider.addAlgorithm("Cipher.DESEDE", PREFIX + "$ECB"); provider.addAlgorithm("Cipher." + PKCSObjectIdentifiers.des_EDE3_CBC, PREFIX + "$CBC"); provider.addAlgorithm("Cipher.DESEDEWRAP", PREFIX + "$Wrap"); provider.addAlgorithm("Cipher." + PKCSObjectIdentifiers.id_alg_CMS3DESwrap, PREFIX + "$Wrap"); provider.addAlgorithm("Cipher.DESEDERFC3211WRAP", PREFIX + "$RFC3211"); provider.addAlgorithm("Alg.Alias.Cipher.TDEA", "DESEDE"); provider.addAlgorithm("Alg.Alias.Cipher.TDEAWRAP", "DESEDEWRAP"); provider.addAlgorithm("Alg.Alias.KeyGenerator.TDEA", "DESEDE"); provider.addAlgorithm("Alg.Alias.AlgorithmParameters.TDEA", "DESEDE"); provider.addAlgorithm("Alg.Alias.AlgorithmParameterGenerator.TDEA", "DESEDE"); provider.addAlgorithm("Alg.Alias.SecretKeyFactory.TDEA", "DESEDE"); if (provider.hasAlgorithm("MessageDigest", "SHA-1")) { provider.addAlgorithm("Cipher.PBEWITHSHAAND3-KEYTRIPLEDES-CBC", PREFIX + "$PBEWithSHAAndDES3Key"); provider.addAlgorithm("Cipher.BROKENPBEWITHSHAAND3-KEYTRIPLEDES-CBC", PREFIX + "$BrokePBEWithSHAAndDES3Key"); provider.addAlgorithm("Cipher.OLDPBEWITHSHAAND3-KEYTRIPLEDES-CBC", PREFIX + "$OldPBEWithSHAAndDES3Key"); provider.addAlgorithm("Cipher.PBEWITHSHAAND2-KEYTRIPLEDES-CBC", PREFIX + "$PBEWithSHAAndDES2Key"); provider.addAlgorithm("Cipher.BROKENPBEWITHSHAAND2-KEYTRIPLEDES-CBC", PREFIX + "$BrokePBEWithSHAAndDES2Key"); provider.addAlgorithm("Alg.Alias.Cipher." + PKCSObjectIdentifiers.pbeWithSHAAnd3_KeyTripleDES_CBC, "PBEWITHSHAAND3-KEYTRIPLEDES-CBC"); provider.addAlgorithm("Alg.Alias.Cipher." + PKCSObjectIdentifiers.pbeWithSHAAnd2_KeyTripleDES_CBC, "PBEWITHSHAAND2-KEYTRIPLEDES-CBC"); provider.addAlgorithm("Alg.Alias.Cipher.PBEWITHSHA1ANDDESEDE", "PBEWITHSHAAND3-KEYTRIPLEDES-CBC"); provider.addAlgorithm("Alg.Alias.Cipher.PBEWITHSHA1AND3-KEYTRIPLEDES-CBC", "PBEWITHSHAAND3-KEYTRIPLEDES-CBC"); provider.addAlgorithm("Alg.Alias.Cipher.PBEWITHSHA1AND2-KEYTRIPLEDES-CBC", "PBEWITHSHAAND2-KEYTRIPLEDES-CBC"); } provider.addAlgorithm("KeyGenerator.DESEDE", PREFIX + "$KeyGenerator"); provider.addAlgorithm("KeyGenerator." + PKCSObjectIdentifiers.des_EDE3_CBC, PREFIX + "$KeyGenerator3"); provider.addAlgorithm("KeyGenerator.DESEDEWRAP", PREFIX + "$KeyGenerator"); provider.addAlgorithm("SecretKeyFactory.DESEDE", PREFIX + "$KeyFactory"); provider.addAlgorithm("Mac.DESEDECMAC", PREFIX + "$CMAC"); provider.addAlgorithm("Mac.DESEDEMAC", PREFIX + "$CBCMAC"); provider.addAlgorithm("Alg.Alias.Mac.DESEDE", "DESEDEMAC"); provider.addAlgorithm("Mac.DESEDEMAC/CFB8", PREFIX + "$DESedeCFB8"); provider.addAlgorithm("Alg.Alias.Mac.DESEDE/CFB8", "DESEDEMAC/CFB8"); provider.addAlgorithm("Mac.DESEDEMAC64", PREFIX + "$DESede64"); provider.addAlgorithm("Alg.Alias.Mac.DESEDE64", "DESEDEMAC64"); provider.addAlgorithm("Mac.DESEDEMAC64WITHISO7816-4PADDING", PREFIX + "$DESede64with7816d4"); provider.addAlgorithm("Alg.Alias.Mac.DESEDE64WITHISO7816-4PADDING", "DESEDEMAC64WITHISO7816-4PADDING"); provider.addAlgorithm("Alg.Alias.Mac.DESEDEISO9797ALG1MACWITHISO7816-4PADDING", "DESEDEMAC64WITHISO7816-4PADDING"); provider.addAlgorithm("Alg.Alias.Mac.DESEDEISO9797ALG1WITHISO7816-4PADDING", "DESEDEMAC64WITHISO7816-4PADDING"); provider.addAlgorithm("AlgorithmParameters.DESEDE", PACKAGE + ".util.IvAlgorithmParameters"); provider.addAlgorithm("Alg.Alias.AlgorithmParameters." + PKCSObjectIdentifiers.des_EDE3_CBC, "DESEDE"); provider.addAlgorithm("AlgorithmParameterGenerator.DESEDE", PREFIX + "$AlgParamGen"); provider.addAlgorithm("Alg.Alias.AlgorithmParameterGenerator." + PKCSObjectIdentifiers.des_EDE3_CBC, "DESEDE"); provider.addAlgorithm("SecretKeyFactory.PBEWITHSHAAND3-KEYTRIPLEDES-CBC", PREFIX + "$PBEWithSHAAndDES3KeyFactory"); provider.addAlgorithm("SecretKeyFactory.PBEWITHSHAAND2-KEYTRIPLEDES-CBC", PREFIX + "$PBEWithSHAAndDES2KeyFactory"); provider.addAlgorithm("Alg.Alias.AlgorithmParameters.PBEWITHSHAAND3-KEYTRIPLEDES", "PKCS12PBE"); provider.addAlgorithm("Alg.Alias.AlgorithmParameters.PBEWITHSHAAND2-KEYTRIPLEDES", "PKCS12PBE"); provider.addAlgorithm("Alg.Alias.AlgorithmParameters.PBEWITHSHAAND3-KEYTRIPLEDES-CBC", "PKCS12PBE"); provider.addAlgorithm("Alg.Alias.AlgorithmParameters.PBEWITHSHAAND2-KEYTRIPLEDES-CBC", "PKCS12PBE"); provider.addAlgorithm("Alg.Alias.AlgorithmParameters.PBEWITHSHAANDDES3KEY-CBC", "PKCS12PBE"); provider.addAlgorithm("Alg.Alias.AlgorithmParameters.PBEWITHSHAANDDES2KEY-CBC", "PKCS12PBE"); provider.addAlgorithm("Alg.Alias.SecretKeyFactory.1.2.840.113549.1.12.1.3", "PBEWITHSHAAND3-KEYTRIPLEDES-CBC"); provider.addAlgorithm("Alg.Alias.SecretKeyFactory.1.2.840.113549.1.12.1.4", "PBEWITHSHAAND2-KEYTRIPLEDES-CBC"); provider.addAlgorithm("Alg.Alias.SecretKeyFactory.PBEWithSHAAnd3KeyTripleDES", "PBEWITHSHAAND3-KEYTRIPLEDES-CBC"); provider.addAlgorithm("Alg.Alias.AlgorithmParameters.1.2.840.113549.1.12.1.3", "PKCS12PBE"); provider.addAlgorithm("Alg.Alias.AlgorithmParameters.1.2.840.113549.1.12.1.4", "PKCS12PBE"); provider.addAlgorithm("Alg.Alias.Cipher.PBEWithSHAAnd3KeyTripleDES", "PBEWITHSHAAND3-KEYTRIPLEDES-CBC"); } } } bouncycastle-1.49.orig/src/org/bouncycastle/jcajce/provider/symmetric/TEA.java0000644000175000017500000000305311701431716027045 0ustar ebourgebourgpackage org.bouncycastle.jcajce.provider.symmetric; import org.bouncycastle.crypto.CipherKeyGenerator; import org.bouncycastle.crypto.engines.TEAEngine; import org.bouncycastle.jcajce.provider.config.ConfigurableProvider; import org.bouncycastle.jcajce.provider.symmetric.util.BaseBlockCipher; import org.bouncycastle.jcajce.provider.symmetric.util.BaseKeyGenerator; import org.bouncycastle.jcajce.provider.symmetric.util.IvAlgorithmParameters; import org.bouncycastle.jcajce.provider.util.AlgorithmProvider; public final class TEA { private TEA() { } public static class ECB extends BaseBlockCipher { public ECB() { super(new TEAEngine()); } } public static class KeyGen extends BaseKeyGenerator { public KeyGen() { super("TEA", 128, new CipherKeyGenerator()); } } public static class AlgParams extends IvAlgorithmParameters { protected String engineToString() { return "TEA IV"; } } public static class Mappings extends AlgorithmProvider { private static final String PREFIX = TEA.class.getName(); public Mappings() { } public void configure(ConfigurableProvider provider) { provider.addAlgorithm("Cipher.TEA", PREFIX + "$ECB"); provider.addAlgorithm("KeyGenerator.TEA", PREFIX + "$KeyGen"); provider.addAlgorithm("AlgorithmParameters.TEA", PREFIX + "$AlgParams"); } } } bouncycastle-1.49.orig/src/org/bouncycastle/jcajce/provider/symmetric/CAST5.java0000644000175000017500000001452111705207421027253 0ustar ebourgebourgpackage org.bouncycastle.jcajce.provider.symmetric; import java.io.IOException; import java.security.AlgorithmParameters; import java.security.InvalidAlgorithmParameterException; import java.security.SecureRandom; import java.security.spec.AlgorithmParameterSpec; import java.security.spec.InvalidParameterSpecException; import javax.crypto.spec.IvParameterSpec; import org.bouncycastle.asn1.ASN1InputStream; import org.bouncycastle.asn1.misc.CAST5CBCParameters; import org.bouncycastle.crypto.CipherKeyGenerator; import org.bouncycastle.crypto.engines.CAST5Engine; import org.bouncycastle.crypto.modes.CBCBlockCipher; import org.bouncycastle.jcajce.provider.config.ConfigurableProvider; import org.bouncycastle.jcajce.provider.symmetric.util.BaseAlgorithmParameterGenerator; import org.bouncycastle.jcajce.provider.symmetric.util.BaseAlgorithmParameters; import org.bouncycastle.jcajce.provider.symmetric.util.BaseBlockCipher; import org.bouncycastle.jcajce.provider.symmetric.util.BaseKeyGenerator; import org.bouncycastle.jcajce.provider.util.AlgorithmProvider; import org.bouncycastle.jce.provider.BouncyCastleProvider; public final class CAST5 { private CAST5() { } public static class ECB extends BaseBlockCipher { public ECB() { super(new CAST5Engine()); } } public static class CBC extends BaseBlockCipher { public CBC() { super(new CBCBlockCipher(new CAST5Engine()), 64); } } public static class KeyGen extends BaseKeyGenerator { public KeyGen() { super("CAST5", 128, new CipherKeyGenerator()); } } public static class AlgParamGen extends BaseAlgorithmParameterGenerator { protected void engineInit( AlgorithmParameterSpec genParamSpec, SecureRandom random) throws InvalidAlgorithmParameterException { throw new InvalidAlgorithmParameterException("No supported AlgorithmParameterSpec for CAST5 parameter generation."); } protected AlgorithmParameters engineGenerateParameters() { byte[] iv = new byte[8]; if (random == null) { random = new SecureRandom(); } random.nextBytes(iv); AlgorithmParameters params; try { params = AlgorithmParameters.getInstance("CAST5", BouncyCastleProvider.PROVIDER_NAME); params.init(new IvParameterSpec(iv)); } catch (Exception e) { throw new RuntimeException(e.getMessage()); } return params; } } public static class AlgParams extends BaseAlgorithmParameters { private byte[] iv; private int keyLength = 128; protected byte[] engineGetEncoded() { byte[] tmp = new byte[iv.length]; System.arraycopy(iv, 0, tmp, 0, iv.length); return tmp; } protected byte[] engineGetEncoded( String format) throws IOException { if (this.isASN1FormatString(format)) { return new CAST5CBCParameters(engineGetEncoded(), keyLength).getEncoded(); } if (format.equals("RAW")) { return engineGetEncoded(); } return null; } protected AlgorithmParameterSpec localEngineGetParameterSpec( Class paramSpec) throws InvalidParameterSpecException { if (paramSpec == IvParameterSpec.class) { return new IvParameterSpec(iv); } throw new InvalidParameterSpecException("unknown parameter spec passed to CAST5 parameters object."); } protected void engineInit( AlgorithmParameterSpec paramSpec) throws InvalidParameterSpecException { if (paramSpec instanceof IvParameterSpec) { this.iv = ((IvParameterSpec)paramSpec).getIV(); } else { throw new InvalidParameterSpecException("IvParameterSpec required to initialise a CAST5 parameters algorithm parameters object"); } } protected void engineInit( byte[] params) throws IOException { this.iv = new byte[params.length]; System.arraycopy(params, 0, iv, 0, iv.length); } protected void engineInit( byte[] params, String format) throws IOException { if (this.isASN1FormatString(format)) { ASN1InputStream aIn = new ASN1InputStream(params); CAST5CBCParameters p = CAST5CBCParameters.getInstance(aIn.readObject()); keyLength = p.getKeyLength(); iv = p.getIV(); return; } if (format.equals("RAW")) { engineInit(params); return; } throw new IOException("Unknown parameters format in IV parameters object"); } protected String engineToString() { return "CAST5 Parameters"; } } public static class Mappings extends AlgorithmProvider { private static final String PREFIX = CAST5.class.getName(); public Mappings() { } public void configure(ConfigurableProvider provider) { provider.addAlgorithm("AlgorithmParameters.CAST5", PREFIX + "$AlgParams"); provider.addAlgorithm("Alg.Alias.AlgorithmParameters.1.2.840.113533.7.66.10", "CAST5"); provider.addAlgorithm("AlgorithmParameterGenerator.CAST5", PREFIX + "$AlgParamGen"); provider.addAlgorithm("Alg.Alias.AlgorithmParameterGenerator.1.2.840.113533.7.66.10", "CAST5"); provider.addAlgorithm("Cipher.CAST5", PREFIX + "$ECB"); provider.addAlgorithm("Cipher.1.2.840.113533.7.66.10", PREFIX + "$CBC"); provider.addAlgorithm("KeyGenerator.CAST5", PREFIX + "$KeyGen"); provider.addAlgorithm("Alg.Alias.KeyGenerator.1.2.840.113533.7.66.10", "CAST5"); } } } bouncycastle-1.49.orig/src/org/bouncycastle/jcajce/NamedJcaJceHelper.java0000644000175000017500000000654211770522423026022 0ustar ebourgebourgpackage org.bouncycastle.jcajce; import java.security.AlgorithmParameterGenerator; import java.security.AlgorithmParameters; import java.security.KeyFactory; import java.security.KeyPairGenerator; import java.security.MessageDigest; import java.security.NoSuchAlgorithmException; import java.security.NoSuchProviderException; import java.security.Signature; import java.security.cert.CertificateException; import java.security.cert.CertificateFactory; import javax.crypto.Cipher; import javax.crypto.KeyAgreement; import javax.crypto.KeyGenerator; import javax.crypto.Mac; import javax.crypto.NoSuchPaddingException; import javax.crypto.SecretKeyFactory; public class NamedJcaJceHelper implements JcaJceHelper { protected final String providerName; public NamedJcaJceHelper(String providerName) { this.providerName = providerName; } public Cipher createCipher( String algorithm) throws NoSuchAlgorithmException, NoSuchPaddingException, NoSuchProviderException { return Cipher.getInstance(algorithm, providerName); } public Mac createMac(String algorithm) throws NoSuchAlgorithmException, NoSuchProviderException { return Mac.getInstance(algorithm, providerName); } public KeyAgreement createKeyAgreement(String algorithm) throws NoSuchAlgorithmException, NoSuchProviderException { return KeyAgreement.getInstance(algorithm, providerName); } public AlgorithmParameterGenerator createAlgorithmParameterGenerator(String algorithm) throws NoSuchAlgorithmException, NoSuchProviderException { return AlgorithmParameterGenerator.getInstance(algorithm, providerName); } public AlgorithmParameters createAlgorithmParameters(String algorithm) throws NoSuchAlgorithmException, NoSuchProviderException { return AlgorithmParameters.getInstance(algorithm, providerName); } public KeyGenerator createKeyGenerator(String algorithm) throws NoSuchAlgorithmException, NoSuchProviderException { return KeyGenerator.getInstance(algorithm, providerName); } public KeyFactory createKeyFactory(String algorithm) throws NoSuchAlgorithmException, NoSuchProviderException { return KeyFactory.getInstance(algorithm, providerName); } public SecretKeyFactory createSecretKeyFactory(String algorithm) throws NoSuchAlgorithmException, NoSuchProviderException { return SecretKeyFactory.getInstance(algorithm, providerName); } public KeyPairGenerator createKeyPairGenerator(String algorithm) throws NoSuchAlgorithmException, NoSuchProviderException { return KeyPairGenerator.getInstance(algorithm, providerName); } public MessageDigest createDigest(String algorithm) throws NoSuchAlgorithmException, NoSuchProviderException { return MessageDigest.getInstance(algorithm, providerName); } public Signature createSignature(String algorithm) throws NoSuchAlgorithmException, NoSuchProviderException { return Signature.getInstance(algorithm, providerName); } public CertificateFactory createCertificateFactory(String algorithm) throws NoSuchAlgorithmException, CertificateException, NoSuchProviderException { return CertificateFactory.getInstance(algorithm, providerName); } } bouncycastle-1.49.orig/src/org/bouncycastle/jcajce/DefaultJcaJceHelper.java0000644000175000017500000000531711776720732026372 0ustar ebourgebourgpackage org.bouncycastle.jcajce; import java.security.AlgorithmParameterGenerator; import java.security.AlgorithmParameters; import java.security.KeyFactory; import java.security.KeyPairGenerator; import java.security.MessageDigest; import java.security.NoSuchAlgorithmException; import java.security.Signature; import java.security.cert.CertificateException; import java.security.cert.CertificateFactory; import javax.crypto.Cipher; import javax.crypto.KeyAgreement; import javax.crypto.KeyGenerator; import javax.crypto.Mac; import javax.crypto.NoSuchPaddingException; import javax.crypto.SecretKeyFactory; public class DefaultJcaJceHelper implements JcaJceHelper { public Cipher createCipher( String algorithm) throws NoSuchAlgorithmException, NoSuchPaddingException { return Cipher.getInstance(algorithm); } public Mac createMac(String algorithm) throws NoSuchAlgorithmException { return Mac.getInstance(algorithm); } public KeyAgreement createKeyAgreement(String algorithm) throws NoSuchAlgorithmException { return KeyAgreement.getInstance(algorithm); } public AlgorithmParameterGenerator createAlgorithmParameterGenerator(String algorithm) throws NoSuchAlgorithmException { return AlgorithmParameterGenerator.getInstance(algorithm); } public AlgorithmParameters createAlgorithmParameters(String algorithm) throws NoSuchAlgorithmException { return AlgorithmParameters.getInstance(algorithm); } public KeyGenerator createKeyGenerator(String algorithm) throws NoSuchAlgorithmException { return KeyGenerator.getInstance(algorithm); } public KeyFactory createKeyFactory(String algorithm) throws NoSuchAlgorithmException { return KeyFactory.getInstance(algorithm); } public SecretKeyFactory createSecretKeyFactory(String algorithm) throws NoSuchAlgorithmException { return SecretKeyFactory.getInstance(algorithm); } public KeyPairGenerator createKeyPairGenerator(String algorithm) throws NoSuchAlgorithmException { return KeyPairGenerator.getInstance(algorithm); } public MessageDigest createDigest(String algorithm) throws NoSuchAlgorithmException { return MessageDigest.getInstance(algorithm); } public Signature createSignature(String algorithm) throws NoSuchAlgorithmException { return Signature.getInstance(algorithm); } public CertificateFactory createCertificateFactory(String algorithm) throws NoSuchAlgorithmException, CertificateException { return CertificateFactory.getInstance(algorithm); } } bouncycastle-1.49.orig/src/org/bouncycastle/jcajce/io/0000755000175000017500000000000012152033551022325 5ustar ebourgebourgbouncycastle-1.49.orig/src/org/bouncycastle/jcajce/io/MacOutputStream.java0000644000175000017500000000114111504531150026260 0ustar ebourgebourgpackage org.bouncycastle.jcajce.io; import java.io.IOException; import java.io.OutputStream; import javax.crypto.Mac; public class MacOutputStream extends OutputStream { protected Mac mac; public MacOutputStream( Mac mac) { this.mac = mac; } public void write(int b) throws IOException { mac.update((byte)b); } public void write( byte[] b, int off, int len) throws IOException { mac.update(b, off, len); } public byte[] getMac() { return mac.doFinal(); } } bouncycastle-1.49.orig/src/org/bouncycastle/jcajce/JcaJceHelper.java0000644000175000017500000000426411770522423025054 0ustar ebourgebourgpackage org.bouncycastle.jcajce; import java.security.AlgorithmParameterGenerator; import java.security.AlgorithmParameters; import java.security.KeyFactory; import java.security.KeyPairGenerator; import java.security.MessageDigest; import java.security.NoSuchAlgorithmException; import java.security.NoSuchProviderException; import java.security.Signature; import java.security.cert.CertificateException; import java.security.cert.CertificateFactory; import javax.crypto.Cipher; import javax.crypto.KeyAgreement; import javax.crypto.KeyGenerator; import javax.crypto.Mac; import javax.crypto.NoSuchPaddingException; import javax.crypto.SecretKeyFactory; public interface JcaJceHelper { Cipher createCipher( String algorithm) throws NoSuchAlgorithmException, NoSuchPaddingException, NoSuchProviderException; Mac createMac(String algorithm) throws NoSuchAlgorithmException, NoSuchProviderException; KeyAgreement createKeyAgreement(String algorithm) throws NoSuchAlgorithmException, NoSuchProviderException; AlgorithmParameterGenerator createAlgorithmParameterGenerator(String algorithm) throws NoSuchAlgorithmException, NoSuchProviderException; AlgorithmParameters createAlgorithmParameters(String algorithm) throws NoSuchAlgorithmException, NoSuchProviderException; KeyGenerator createKeyGenerator(String algorithm) throws NoSuchAlgorithmException, NoSuchProviderException; KeyFactory createKeyFactory(String algorithm) throws NoSuchAlgorithmException, NoSuchProviderException; SecretKeyFactory createSecretKeyFactory(String algorithm) throws NoSuchAlgorithmException, NoSuchProviderException; KeyPairGenerator createKeyPairGenerator(String algorithm) throws NoSuchAlgorithmException, NoSuchProviderException; MessageDigest createDigest(String algorithm) throws NoSuchAlgorithmException, NoSuchProviderException; Signature createSignature(String algorithm) throws NoSuchAlgorithmException, NoSuchProviderException; CertificateFactory createCertificateFactory(String algorithm) throws NoSuchAlgorithmException, NoSuchProviderException, CertificateException; } bouncycastle-1.49.orig/src/org/bouncycastle/jcajce/ProviderJcaJceHelper.java0000644000175000017500000000576111776720732026603 0ustar ebourgebourgpackage org.bouncycastle.jcajce; import java.security.AlgorithmParameterGenerator; import java.security.AlgorithmParameters; import java.security.KeyFactory; import java.security.KeyPairGenerator; import java.security.MessageDigest; import java.security.NoSuchAlgorithmException; import java.security.Provider; import java.security.Signature; import java.security.cert.CertificateException; import java.security.cert.CertificateFactory; import javax.crypto.Cipher; import javax.crypto.KeyAgreement; import javax.crypto.KeyGenerator; import javax.crypto.Mac; import javax.crypto.NoSuchPaddingException; import javax.crypto.SecretKeyFactory; public class ProviderJcaJceHelper implements JcaJceHelper { protected final Provider provider; public ProviderJcaJceHelper(Provider provider) { this.provider = provider; } public Cipher createCipher( String algorithm) throws NoSuchAlgorithmException, NoSuchPaddingException { return Cipher.getInstance(algorithm, provider); } public Mac createMac(String algorithm) throws NoSuchAlgorithmException { return Mac.getInstance(algorithm, provider); } public KeyAgreement createKeyAgreement(String algorithm) throws NoSuchAlgorithmException { return KeyAgreement.getInstance(algorithm, provider); } public AlgorithmParameterGenerator createAlgorithmParameterGenerator(String algorithm) throws NoSuchAlgorithmException { return AlgorithmParameterGenerator.getInstance(algorithm, provider); } public AlgorithmParameters createAlgorithmParameters(String algorithm) throws NoSuchAlgorithmException { return AlgorithmParameters.getInstance(algorithm, provider); } public KeyGenerator createKeyGenerator(String algorithm) throws NoSuchAlgorithmException { return KeyGenerator.getInstance(algorithm, provider); } public KeyFactory createKeyFactory(String algorithm) throws NoSuchAlgorithmException { return KeyFactory.getInstance(algorithm, provider); } public SecretKeyFactory createSecretKeyFactory(String algorithm) throws NoSuchAlgorithmException { return SecretKeyFactory.getInstance(algorithm, provider); } public KeyPairGenerator createKeyPairGenerator(String algorithm) throws NoSuchAlgorithmException { return KeyPairGenerator.getInstance(algorithm, provider); } public MessageDigest createDigest(String algorithm) throws NoSuchAlgorithmException { return MessageDigest.getInstance(algorithm, provider); } public Signature createSignature(String algorithm) throws NoSuchAlgorithmException { return Signature.getInstance(algorithm, provider); } public CertificateFactory createCertificateFactory(String algorithm) throws NoSuchAlgorithmException, CertificateException { return CertificateFactory.getInstance(algorithm, provider); } } bouncycastle-1.49.orig/src/org/bouncycastle/mozilla/0000755000175000017500000000000012152033551022146 5ustar ebourgebourgbouncycastle-1.49.orig/src/org/bouncycastle/mozilla/SignedPublicKeyAndChallenge.java0000644000175000017500000001027711737273736030312 0ustar ebourgebourgpackage org.bouncycastle.mozilla; import java.io.ByteArrayInputStream; import java.security.InvalidKeyException; import java.security.KeyFactory; import java.security.NoSuchAlgorithmException; import java.security.NoSuchProviderException; import java.security.PublicKey; import java.security.Signature; import java.security.SignatureException; import java.security.spec.X509EncodedKeySpec; import org.bouncycastle.asn1.ASN1InputStream; import org.bouncycastle.asn1.ASN1Object; import org.bouncycastle.asn1.ASN1Primitive; import org.bouncycastle.asn1.ASN1Sequence; import org.bouncycastle.asn1.DERBitString; import org.bouncycastle.asn1.mozilla.PublicKeyAndChallenge; import org.bouncycastle.asn1.x509.AlgorithmIdentifier; import org.bouncycastle.asn1.x509.SubjectPublicKeyInfo; /** * This is designed to parse the SignedPublicKeyAndChallenge created by the * KEYGEN tag included by Mozilla based browsers. *
     *  PublicKeyAndChallenge ::= SEQUENCE {
     *    spki SubjectPublicKeyInfo,
     *    challenge IA5STRING
     *  }
     *
     *  SignedPublicKeyAndChallenge ::= SEQUENCE {
     *    publicKeyAndChallenge PublicKeyAndChallenge,
     *    signatureAlgorithm AlgorithmIdentifier,
     *    signature BIT STRING
     *  }
     *  
    */ public class SignedPublicKeyAndChallenge extends ASN1Object { private static ASN1Sequence toDERSequence(byte[] bytes) { try { ByteArrayInputStream bIn = new ByteArrayInputStream(bytes); ASN1InputStream aIn = new ASN1InputStream(bIn); return (ASN1Sequence)aIn.readObject(); } catch (Exception e) { throw new IllegalArgumentException("badly encoded request"); } } private ASN1Sequence spkacSeq; private PublicKeyAndChallenge pkac; private AlgorithmIdentifier signatureAlgorithm; private DERBitString signature; public SignedPublicKeyAndChallenge(byte[] bytes) { spkacSeq = toDERSequence(bytes); pkac = PublicKeyAndChallenge.getInstance(spkacSeq.getObjectAt(0)); signatureAlgorithm = AlgorithmIdentifier.getInstance(spkacSeq.getObjectAt(1)); signature = (DERBitString)spkacSeq.getObjectAt(2); } public ASN1Primitive toASN1Primitive() { return spkacSeq; } public PublicKeyAndChallenge getPublicKeyAndChallenge() { return pkac; } public boolean verify() throws NoSuchAlgorithmException, SignatureException, NoSuchProviderException, InvalidKeyException { return verify(null); } public boolean verify(String provider) throws NoSuchAlgorithmException, SignatureException, NoSuchProviderException, InvalidKeyException { Signature sig = null; if (provider == null) { sig = Signature.getInstance(signatureAlgorithm.getAlgorithm().getId()); } else { sig = Signature.getInstance(signatureAlgorithm.getAlgorithm().getId(), provider); } PublicKey pubKey = this.getPublicKey(provider); sig.initVerify(pubKey); try { DERBitString pkBytes = new DERBitString(pkac); sig.update(pkBytes.getBytes()); return sig.verify(signature.getBytes()); } catch (Exception e) { throw new InvalidKeyException("error encoding public key"); } } public PublicKey getPublicKey(String provider) throws NoSuchAlgorithmException, NoSuchProviderException, InvalidKeyException { SubjectPublicKeyInfo subjectPKInfo = pkac.getSubjectPublicKeyInfo(); try { DERBitString bStr = new DERBitString(subjectPKInfo); X509EncodedKeySpec xspec = new X509EncodedKeySpec(bStr.getBytes()); AlgorithmIdentifier keyAlg = subjectPKInfo.getAlgorithm(); KeyFactory factory = KeyFactory.getInstance(keyAlg.getAlgorithm().getId(),provider); return factory.generatePublic(xspec); } catch (Exception e) { throw new InvalidKeyException("error encoding public key"); } } } bouncycastle-1.49.orig/src/org/bouncycastle/mozilla/package.html0000644000175000017500000000015310262753174024440 0ustar ebourgebourg Support class for mozilla signed public key and challenge. bouncycastle-1.49.orig/src/org/bouncycastle/pkcs/0000755000175000017500000000000012152033551021437 5ustar ebourgebourgbouncycastle-1.49.orig/src/org/bouncycastle/pkcs/PKCS8EncryptedPrivateKeyInfoBuilder.java0000644000175000017500000000275211730247755031163 0ustar ebourgebourgpackage org.bouncycastle.pkcs; import java.io.ByteArrayOutputStream; import java.io.IOException; import java.io.OutputStream; import org.bouncycastle.asn1.pkcs.EncryptedPrivateKeyInfo; import org.bouncycastle.asn1.pkcs.PrivateKeyInfo; import org.bouncycastle.operator.OutputEncryptor; /** * A class for creating EncryptedPrivateKeyInfo structures. *
     * EncryptedPrivateKeyInfo ::= SEQUENCE {
     *      encryptionAlgorithm AlgorithmIdentifier {{KeyEncryptionAlgorithms}},
     *      encryptedData EncryptedData
     * }
     *
     * EncryptedData ::= OCTET STRING
     *
     * KeyEncryptionAlgorithms ALGORITHM-IDENTIFIER ::= {
     *          ... -- For local profiles
     * }
     * 
    */ public class PKCS8EncryptedPrivateKeyInfoBuilder { private PrivateKeyInfo privateKeyInfo; public PKCS8EncryptedPrivateKeyInfoBuilder(PrivateKeyInfo privateKeyInfo) { this.privateKeyInfo = privateKeyInfo; } public PKCS8EncryptedPrivateKeyInfo build( OutputEncryptor encryptor) { try { ByteArrayOutputStream bOut = new ByteArrayOutputStream(); OutputStream cOut = encryptor.getOutputStream(bOut); cOut.write(privateKeyInfo.getEncoded()); cOut.close(); return new PKCS8EncryptedPrivateKeyInfo(new EncryptedPrivateKeyInfo(encryptor.getAlgorithmIdentifier(), bOut.toByteArray())); } catch (IOException e) { throw new IllegalStateException("cannot encode privateKeyInfo"); } } } bouncycastle-1.49.orig/src/org/bouncycastle/pkcs/PKCS10CertificationRequest.java0000644000175000017500000001541611730247706027301 0ustar ebourgebourgpackage org.bouncycastle.pkcs; import java.io.IOException; import java.io.OutputStream; import java.util.ArrayList; import java.util.List; import org.bouncycastle.asn1.ASN1Encoding; import org.bouncycastle.asn1.ASN1ObjectIdentifier; import org.bouncycastle.asn1.ASN1Primitive; import org.bouncycastle.asn1.ASN1Set; import org.bouncycastle.asn1.pkcs.Attribute; import org.bouncycastle.asn1.pkcs.CertificationRequest; import org.bouncycastle.asn1.pkcs.CertificationRequestInfo; import org.bouncycastle.asn1.x500.X500Name; import org.bouncycastle.asn1.x509.AlgorithmIdentifier; import org.bouncycastle.asn1.x509.SubjectPublicKeyInfo; import org.bouncycastle.operator.ContentVerifier; import org.bouncycastle.operator.ContentVerifierProvider; /** * Holding class for a PKCS#10 certification request. */ public class PKCS10CertificationRequest { private static Attribute[] EMPTY_ARRAY = new Attribute[0]; private CertificationRequest certificationRequest; private static CertificationRequest parseBytes(byte[] encoding) throws IOException { try { return CertificationRequest.getInstance(ASN1Primitive.fromByteArray(encoding)); } catch (ClassCastException e) { throw new PKCSIOException("malformed data: " + e.getMessage(), e); } catch (IllegalArgumentException e) { throw new PKCSIOException("malformed data: " + e.getMessage(), e); } } /** * Create a PKCS10CertificationRequestHolder from an underlying ASN.1 structure. * * @param certificationRequest the underlying ASN.1 structure representing a request. */ public PKCS10CertificationRequest(CertificationRequest certificationRequest) { this.certificationRequest = certificationRequest; } /** * Create a PKCS10CertificationRequestHolder from the passed in bytes. * * @param encoded BER/DER encoding of the CertificationRequest structure. * @throws IOException in the event of corrupted data, or an incorrect structure. */ public PKCS10CertificationRequest(byte[] encoded) throws IOException { this(parseBytes(encoded)); } /** * Return the underlying ASN.1 structure for this request. * * @return a CertificateRequest object. */ public CertificationRequest toASN1Structure() { return certificationRequest; } /** * Return the subject on this request. * * @return the X500Name representing the request's subject. */ public X500Name getSubject() { return X500Name.getInstance(certificationRequest.getCertificationRequestInfo().getSubject()); } /** * Return the details of the signature algorithm used to create this request. * * @return the AlgorithmIdentifier describing the signature algorithm used to create this request. */ public AlgorithmIdentifier getSignatureAlgorithm() { return certificationRequest.getSignatureAlgorithm(); } /** * Return the bytes making up the signature associated with this request. * * @return the request signature bytes. */ public byte[] getSignature() { return certificationRequest.getSignature().getBytes(); } /** * Return the SubjectPublicKeyInfo describing the public key this request is carrying. * * @return the public key ASN.1 structure contained in the request. */ public SubjectPublicKeyInfo getSubjectPublicKeyInfo() { return certificationRequest.getCertificationRequestInfo().getSubjectPublicKeyInfo(); } /** * Return the attributes, if any associated with this request. * * @return an array of Attribute, zero length if none present. */ public Attribute[] getAttributes() { ASN1Set attrSet = certificationRequest.getCertificationRequestInfo().getAttributes(); if (attrSet == null) { return EMPTY_ARRAY; } Attribute[] attrs = new Attribute[attrSet.size()]; for (int i = 0; i != attrSet.size(); i++) { attrs[i] = Attribute.getInstance(attrSet.getObjectAt(i)); } return attrs; } /** * Return an array of attributes matching the passed in type OID. * * @param type the type of the attribute being looked for. * @return an array of Attribute of the requested type, zero length if none present. */ public Attribute[] getAttributes(ASN1ObjectIdentifier type) { ASN1Set attrSet = certificationRequest.getCertificationRequestInfo().getAttributes(); if (attrSet == null) { return EMPTY_ARRAY; } List list = new ArrayList(); for (int i = 0; i != attrSet.size(); i++) { Attribute attr = Attribute.getInstance(attrSet.getObjectAt(i)); if (attr.getAttrType().equals(type)) { list.add(attr); } } if (list.size() == 0) { return EMPTY_ARRAY; } return (Attribute[])list.toArray(new Attribute[list.size()]); } public byte[] getEncoded() throws IOException { return certificationRequest.getEncoded(); } /** * Validate the signature on the PKCS10 certification request in this holder. * * @param verifierProvider a ContentVerifierProvider that can generate a verifier for the signature. * @return true if the signature is valid, false otherwise. * @throws PKCSException if the signature cannot be processed or is inappropriate. */ public boolean isSignatureValid(ContentVerifierProvider verifierProvider) throws PKCSException { CertificationRequestInfo requestInfo = certificationRequest.getCertificationRequestInfo(); ContentVerifier verifier; try { verifier = verifierProvider.get(certificationRequest.getSignatureAlgorithm()); OutputStream sOut = verifier.getOutputStream(); sOut.write(requestInfo.getEncoded(ASN1Encoding.DER)); sOut.close(); } catch (Exception e) { throw new PKCSException("unable to process signature: " + e.getMessage(), e); } return verifier.verify(certificationRequest.getSignature().getBytes()); } public boolean equals(Object o) { if (o == this) { return true; } if (!(o instanceof PKCS10CertificationRequest)) { return false; } PKCS10CertificationRequest other = (PKCS10CertificationRequest)o; return this.toASN1Structure().equals(other.toASN1Structure()); } public int hashCode() { return this.toASN1Structure().hashCode(); } } bouncycastle-1.49.orig/src/org/bouncycastle/pkcs/PKCS12MacCalculatorBuilderProvider.java0000644000175000017500000000033511730265417030674 0ustar ebourgebourgpackage org.bouncycastle.pkcs; import org.bouncycastle.asn1.x509.AlgorithmIdentifier; public interface PKCS12MacCalculatorBuilderProvider { PKCS12MacCalculatorBuilder get(AlgorithmIdentifier algorithmIdentifier); } bouncycastle-1.49.orig/src/org/bouncycastle/pkcs/PKCSIOException.java0000644000175000017500000000074411514737427025174 0ustar ebourgebourgpackage org.bouncycastle.pkcs; import java.io.IOException; /** * General IOException thrown in the cert package and its sub-packages. */ public class PKCSIOException extends IOException { private Throwable cause; public PKCSIOException(String msg, Throwable cause) { super(msg); this.cause = cause; } public PKCSIOException(String msg) { super(msg); } public Throwable getCause() { return cause; } } bouncycastle-1.49.orig/src/org/bouncycastle/pkcs/bc/0000755000175000017500000000000012152033551022023 5ustar ebourgebourgbouncycastle-1.49.orig/src/org/bouncycastle/pkcs/bc/BcPKCS12MacCalculatorBuilder.java0000644000175000017500000000320011730273720030000 0ustar ebourgebourgpackage org.bouncycastle.pkcs.bc; import java.security.SecureRandom; import org.bouncycastle.asn1.DERNull; import org.bouncycastle.asn1.oiw.OIWObjectIdentifiers; import org.bouncycastle.asn1.pkcs.PKCS12PBEParams; import org.bouncycastle.asn1.x509.AlgorithmIdentifier; import org.bouncycastle.crypto.ExtendedDigest; import org.bouncycastle.crypto.digests.SHA1Digest; import org.bouncycastle.operator.MacCalculator; import org.bouncycastle.pkcs.PKCS12MacCalculatorBuilder; public class BcPKCS12MacCalculatorBuilder implements PKCS12MacCalculatorBuilder { private ExtendedDigest digest; private AlgorithmIdentifier algorithmIdentifier; private SecureRandom random; private int saltLength; private int iterationCount = 1024; public BcPKCS12MacCalculatorBuilder() { this(new SHA1Digest(), new AlgorithmIdentifier(OIWObjectIdentifiers.idSHA1, DERNull.INSTANCE)); } public BcPKCS12MacCalculatorBuilder(ExtendedDigest digest, AlgorithmIdentifier algorithmIdentifier) { this.digest = digest; this.algorithmIdentifier = algorithmIdentifier; this.saltLength = digest.getDigestSize(); } public AlgorithmIdentifier getDigestAlgorithmIdentifier() { return algorithmIdentifier; } public MacCalculator build(final char[] password) { if (random == null) { random = new SecureRandom(); } byte[] salt = new byte[saltLength]; random.nextBytes(salt); return PKCS12PBEUtils.createMacCalculator(algorithmIdentifier.getAlgorithm(), digest, new PKCS12PBEParams(salt, iterationCount), password); } } bouncycastle-1.49.orig/src/org/bouncycastle/pkcs/bc/BcPKCS10CertificationRequestBuilder.java0000644000175000017500000000207311737210072031425 0ustar ebourgebourgpackage org.bouncycastle.pkcs.bc; import java.io.IOException; import org.bouncycastle.asn1.x500.X500Name; import org.bouncycastle.crypto.params.AsymmetricKeyParameter; import org.bouncycastle.crypto.util.SubjectPublicKeyInfoFactory; import org.bouncycastle.pkcs.PKCS10CertificationRequestBuilder; /** * Extension of the PKCS#10 builder to support AsymmetricKey objects. */ public class BcPKCS10CertificationRequestBuilder extends PKCS10CertificationRequestBuilder { /** * Create a PKCS#10 builder for the passed in subject and JCA public key. * * @param subject an X500Name containing the subject associated with the request we are building. * @param publicKey a JCA public key that is to be associated with the request we are building. * @throws IOException if there is a problem encoding the public key. */ public BcPKCS10CertificationRequestBuilder(X500Name subject, AsymmetricKeyParameter publicKey) throws IOException { super(subject, SubjectPublicKeyInfoFactory.createSubjectPublicKeyInfo(publicKey)); } } bouncycastle-1.49.orig/src/org/bouncycastle/pkcs/bc/BcPKCS12PBEInputDecryptorProviderBuilder.java0000644000175000017500000000441312132370210032317 0ustar ebourgebourgpackage org.bouncycastle.pkcs.bc; import java.io.InputStream; import org.bouncycastle.asn1.pkcs.PKCS12PBEParams; import org.bouncycastle.asn1.x509.AlgorithmIdentifier; import org.bouncycastle.crypto.CipherParameters; import org.bouncycastle.crypto.ExtendedDigest; import org.bouncycastle.crypto.digests.SHA1Digest; import org.bouncycastle.crypto.generators.PKCS12ParametersGenerator; import org.bouncycastle.crypto.io.CipherInputStream; import org.bouncycastle.crypto.paddings.PaddedBufferedBlockCipher; import org.bouncycastle.operator.GenericKey; import org.bouncycastle.operator.InputDecryptor; import org.bouncycastle.operator.InputDecryptorProvider; public class BcPKCS12PBEInputDecryptorProviderBuilder { private ExtendedDigest digest; public BcPKCS12PBEInputDecryptorProviderBuilder() { this(new SHA1Digest()); } public BcPKCS12PBEInputDecryptorProviderBuilder(ExtendedDigest digest) { this.digest = digest; } public InputDecryptorProvider build(final char[] password) { return new InputDecryptorProvider() { public InputDecryptor get(final AlgorithmIdentifier algorithmIdentifier) { final PaddedBufferedBlockCipher engine = PKCS12PBEUtils.getEngine(algorithmIdentifier.getAlgorithm()); PKCS12PBEParams pbeParams = PKCS12PBEParams.getInstance(algorithmIdentifier.getParameters()); CipherParameters params = PKCS12PBEUtils.createCipherParameters(algorithmIdentifier.getAlgorithm(), digest, engine.getBlockSize(), pbeParams, password); engine.init(false, params); return new InputDecryptor() { public AlgorithmIdentifier getAlgorithmIdentifier() { return algorithmIdentifier; } public InputStream getInputStream(InputStream input) { return new CipherInputStream(input, engine); } public GenericKey getKey() { return new GenericKey(PKCS12ParametersGenerator.PKCS12PasswordToBytes(password)); } }; } }; } } bouncycastle-1.49.orig/src/org/bouncycastle/pkcs/bc/PKCS12PBEUtils.java0000644000175000017500000001312012113515771025144 0ustar ebourgebourgpackage org.bouncycastle.pkcs.bc; import java.io.OutputStream; import java.util.HashMap; import java.util.HashSet; import java.util.Map; import java.util.Set; import org.bouncycastle.asn1.ASN1ObjectIdentifier; import org.bouncycastle.asn1.pkcs.PKCS12PBEParams; import org.bouncycastle.asn1.pkcs.PKCSObjectIdentifiers; import org.bouncycastle.asn1.x509.AlgorithmIdentifier; import org.bouncycastle.crypto.BlockCipher; import org.bouncycastle.crypto.CipherParameters; import org.bouncycastle.crypto.ExtendedDigest; import org.bouncycastle.crypto.engines.DESedeEngine; import org.bouncycastle.crypto.engines.RC2Engine; import org.bouncycastle.crypto.generators.PKCS12ParametersGenerator; import org.bouncycastle.crypto.io.MacOutputStream; import org.bouncycastle.crypto.macs.HMac; import org.bouncycastle.crypto.modes.CBCBlockCipher; import org.bouncycastle.crypto.paddings.PKCS7Padding; import org.bouncycastle.crypto.paddings.PaddedBufferedBlockCipher; import org.bouncycastle.crypto.params.DESedeParameters; import org.bouncycastle.crypto.params.KeyParameter; import org.bouncycastle.crypto.params.ParametersWithIV; import org.bouncycastle.operator.GenericKey; import org.bouncycastle.operator.MacCalculator; import org.bouncycastle.util.Integers; class PKCS12PBEUtils { private static Map keySizes = new HashMap(); private static Set noIvAlgs = new HashSet(); private static Set desAlgs = new HashSet(); static { keySizes.put(PKCSObjectIdentifiers.pbeWithSHAAnd128BitRC4, Integers.valueOf(128)); keySizes.put(PKCSObjectIdentifiers.pbeWithSHAAnd40BitRC4, Integers.valueOf(40)); keySizes.put(PKCSObjectIdentifiers.pbeWithSHAAnd3_KeyTripleDES_CBC, Integers.valueOf(192)); keySizes.put(PKCSObjectIdentifiers.pbeWithSHAAnd2_KeyTripleDES_CBC, Integers.valueOf(128)); keySizes.put(PKCSObjectIdentifiers.pbeWithSHAAnd128BitRC2_CBC, Integers.valueOf(128)); keySizes.put(PKCSObjectIdentifiers.pbeWithSHAAnd40BitRC2_CBC, Integers.valueOf(40)); noIvAlgs.add(PKCSObjectIdentifiers.pbeWithSHAAnd128BitRC4); noIvAlgs.add(PKCSObjectIdentifiers.pbeWithSHAAnd40BitRC4); desAlgs.add(PKCSObjectIdentifiers.pbeWithSHAAnd3_KeyTripleDES_CBC); desAlgs.add(PKCSObjectIdentifiers.pbeWithSHAAnd3_KeyTripleDES_CBC); } static int getKeySize(ASN1ObjectIdentifier algorithm) { return ((Integer)keySizes.get(algorithm)).intValue(); } static boolean hasNoIv(ASN1ObjectIdentifier algorithm) { return noIvAlgs.contains(algorithm); } static boolean isDesAlg(ASN1ObjectIdentifier algorithm) { return desAlgs.contains(algorithm); } static PaddedBufferedBlockCipher getEngine(ASN1ObjectIdentifier algorithm) { BlockCipher engine; if (algorithm.equals(PKCSObjectIdentifiers.pbeWithSHAAnd3_KeyTripleDES_CBC) || algorithm.equals(PKCSObjectIdentifiers.pbeWithSHAAnd2_KeyTripleDES_CBC)) { engine = new DESedeEngine(); } else if (algorithm.equals(PKCSObjectIdentifiers.pbeWithSHAAnd128BitRC2_CBC) || algorithm.equals(PKCSObjectIdentifiers.pbeWithSHAAnd40BitRC2_CBC)) { engine = new RC2Engine(); } else { throw new IllegalStateException("unknown algorithm"); } return new PaddedBufferedBlockCipher(new CBCBlockCipher(engine), new PKCS7Padding()); } static MacCalculator createMacCalculator(final ASN1ObjectIdentifier digestAlgorithm, ExtendedDigest digest, final PKCS12PBEParams pbeParams, final char[] password) { PKCS12ParametersGenerator pGen = new PKCS12ParametersGenerator(digest); pGen.init(PKCS12ParametersGenerator.PKCS12PasswordToBytes(password), pbeParams.getIV(), pbeParams.getIterations().intValue()); final KeyParameter keyParam = (KeyParameter)pGen.generateDerivedMacParameters(digest.getDigestSize() * 8); final HMac hMac = new HMac(digest); hMac.init(keyParam); return new MacCalculator() { public AlgorithmIdentifier getAlgorithmIdentifier() { return new AlgorithmIdentifier(digestAlgorithm, pbeParams); } public OutputStream getOutputStream() { return new MacOutputStream(hMac); } public byte[] getMac() { byte[] res = new byte[hMac.getMacSize()]; hMac.doFinal(res, 0); return res; } public GenericKey getKey() { return new GenericKey(getAlgorithmIdentifier(), PKCS12ParametersGenerator.PKCS12PasswordToBytes(password)); } }; } static CipherParameters createCipherParameters(ASN1ObjectIdentifier algorithm, ExtendedDigest digest, int blockSize, PKCS12PBEParams pbeParams, char[] password) { PKCS12ParametersGenerator pGen = new PKCS12ParametersGenerator(digest); pGen.init(PKCS12ParametersGenerator.PKCS12PasswordToBytes(password), pbeParams.getIV(), pbeParams.getIterations().intValue()); CipherParameters params; if (PKCS12PBEUtils.hasNoIv(algorithm)) { params = pGen.generateDerivedParameters(PKCS12PBEUtils.getKeySize(algorithm)); } else { params = pGen.generateDerivedParameters(PKCS12PBEUtils.getKeySize(algorithm), blockSize * 8); if (PKCS12PBEUtils.isDesAlg(algorithm)) { DESedeParameters.setOddParity(((KeyParameter)((ParametersWithIV)params).getParameters()).getKey()); } } return params; } } bouncycastle-1.49.orig/src/org/bouncycastle/pkcs/bc/BcPKCS12PBEOutputEncryptorBuilder.java0000644000175000017500000000507112110537745031036 0ustar ebourgebourgpackage org.bouncycastle.pkcs.bc; import java.io.OutputStream; import java.security.SecureRandom; import org.bouncycastle.asn1.ASN1ObjectIdentifier; import org.bouncycastle.asn1.pkcs.PKCS12PBEParams; import org.bouncycastle.asn1.x509.AlgorithmIdentifier; import org.bouncycastle.crypto.BlockCipher; import org.bouncycastle.crypto.BufferedBlockCipher; import org.bouncycastle.crypto.CipherParameters; import org.bouncycastle.crypto.ExtendedDigest; import org.bouncycastle.crypto.digests.SHA1Digest; import org.bouncycastle.crypto.generators.PKCS12ParametersGenerator; import org.bouncycastle.crypto.io.CipherOutputStream; import org.bouncycastle.crypto.paddings.PKCS7Padding; import org.bouncycastle.crypto.paddings.PaddedBufferedBlockCipher; import org.bouncycastle.operator.GenericKey; import org.bouncycastle.operator.OutputEncryptor; public class BcPKCS12PBEOutputEncryptorBuilder { private ExtendedDigest digest; private BufferedBlockCipher engine; private ASN1ObjectIdentifier algorithm; private SecureRandom random; public BcPKCS12PBEOutputEncryptorBuilder(ASN1ObjectIdentifier algorithm, BlockCipher engine) { this(algorithm, engine, new SHA1Digest()); } public BcPKCS12PBEOutputEncryptorBuilder(ASN1ObjectIdentifier algorithm, BlockCipher engine, ExtendedDigest pbeDigest) { this.algorithm = algorithm; this.engine = new PaddedBufferedBlockCipher(engine, new PKCS7Padding()); this.digest = pbeDigest; } public OutputEncryptor build(final char[] password) { if (random == null) { random = new SecureRandom(); } final byte[] salt = new byte[20]; final int iterationCount = 1024; random.nextBytes(salt); final PKCS12PBEParams pbeParams = new PKCS12PBEParams(salt, iterationCount); CipherParameters params = PKCS12PBEUtils.createCipherParameters(algorithm, digest, engine.getBlockSize(), pbeParams, password); engine.init(true, params); return new OutputEncryptor() { public AlgorithmIdentifier getAlgorithmIdentifier() { return new AlgorithmIdentifier(algorithm, pbeParams); } public OutputStream getOutputStream(OutputStream out) { return new CipherOutputStream(out, engine); } public GenericKey getKey() { return new GenericKey(new AlgorithmIdentifier(algorithm, pbeParams), PKCS12ParametersGenerator.PKCS12PasswordToBytes(password)); } }; } } bouncycastle-1.49.orig/src/org/bouncycastle/pkcs/bc/BcPKCS10CertificationRequest.java0000644000175000017500000000221411737210072030113 0ustar ebourgebourgpackage org.bouncycastle.pkcs.bc; import java.io.IOException; import org.bouncycastle.asn1.pkcs.CertificationRequest; import org.bouncycastle.crypto.params.AsymmetricKeyParameter; import org.bouncycastle.crypto.util.PublicKeyFactory; import org.bouncycastle.pkcs.PKCS10CertificationRequest; import org.bouncycastle.pkcs.PKCSException; public class BcPKCS10CertificationRequest extends PKCS10CertificationRequest { public BcPKCS10CertificationRequest(CertificationRequest certificationRequest) { super(certificationRequest); } public BcPKCS10CertificationRequest(byte[] encoding) throws IOException { super(encoding); } public BcPKCS10CertificationRequest(PKCS10CertificationRequest requestHolder) { super(requestHolder.toASN1Structure()); } public AsymmetricKeyParameter getPublicKey() throws PKCSException { try { return PublicKeyFactory.createKey(this.getSubjectPublicKeyInfo()); } catch (IOException e) { throw new PKCSException("error extracting key encoding: " + e.getMessage(), e); } } } bouncycastle-1.49.orig/src/org/bouncycastle/pkcs/bc/BcPKCS12MacCalculatorBuilderProvider.java0000644000175000017500000000277412151274320031525 0ustar ebourgebourgpackage org.bouncycastle.pkcs.bc; import org.bouncycastle.asn1.DERNull; import org.bouncycastle.asn1.pkcs.PKCS12PBEParams; import org.bouncycastle.asn1.x509.AlgorithmIdentifier; import org.bouncycastle.operator.MacCalculator; import org.bouncycastle.operator.OperatorCreationException; import org.bouncycastle.operator.bc.BcDigestProvider; import org.bouncycastle.pkcs.PKCS12MacCalculatorBuilder; import org.bouncycastle.pkcs.PKCS12MacCalculatorBuilderProvider; public class BcPKCS12MacCalculatorBuilderProvider implements PKCS12MacCalculatorBuilderProvider { private BcDigestProvider digestProvider; public BcPKCS12MacCalculatorBuilderProvider(BcDigestProvider digestProvider) { this.digestProvider = digestProvider; } public PKCS12MacCalculatorBuilder get(final AlgorithmIdentifier algorithmIdentifier) { return new PKCS12MacCalculatorBuilder() { public MacCalculator build(final char[] password) throws OperatorCreationException { PKCS12PBEParams pbeParams = PKCS12PBEParams.getInstance(algorithmIdentifier.getParameters()); return PKCS12PBEUtils.createMacCalculator(algorithmIdentifier.getAlgorithm(), digestProvider.get(algorithmIdentifier), pbeParams, password); } public AlgorithmIdentifier getDigestAlgorithmIdentifier() { return new AlgorithmIdentifier(algorithmIdentifier.getAlgorithm(), DERNull.INSTANCE); } }; } } bouncycastle-1.49.orig/src/org/bouncycastle/pkcs/PKCS12SafeBagFactory.java0000644000175000017500000000365211730470561025763 0ustar ebourgebourgpackage org.bouncycastle.pkcs; import org.bouncycastle.asn1.ASN1OctetString; import org.bouncycastle.asn1.ASN1Sequence; import org.bouncycastle.asn1.pkcs.ContentInfo; import org.bouncycastle.asn1.pkcs.PKCSObjectIdentifiers; import org.bouncycastle.asn1.pkcs.SafeBag; import org.bouncycastle.cms.CMSEncryptedData; import org.bouncycastle.cms.CMSException; import org.bouncycastle.operator.InputDecryptorProvider; public class PKCS12SafeBagFactory { private ASN1Sequence safeBagSeq; public PKCS12SafeBagFactory(ContentInfo info) { if (info.getContentType().equals(PKCSObjectIdentifiers.encryptedData)) { throw new IllegalArgumentException("encryptedData requires constructor with decryptor."); } this.safeBagSeq = ASN1Sequence.getInstance(ASN1OctetString.getInstance(info.getContent()).getOctets()); } public PKCS12SafeBagFactory(ContentInfo info, InputDecryptorProvider inputDecryptorProvider) throws PKCSException { if (info.getContentType().equals(PKCSObjectIdentifiers.encryptedData)) { CMSEncryptedData encData = new CMSEncryptedData(org.bouncycastle.asn1.cms.ContentInfo.getInstance(info)); try { this.safeBagSeq = ASN1Sequence.getInstance(encData.getContent(inputDecryptorProvider)); } catch (CMSException e) { throw new PKCSException("unable to extract data: " + e.getMessage(), e); } return; } throw new IllegalArgumentException("encryptedData requires constructor with decryptor."); } public PKCS12SafeBag[] getSafeBags() { PKCS12SafeBag[] safeBags = new PKCS12SafeBag[safeBagSeq.size()]; for (int i = 0; i != safeBagSeq.size(); i++) { safeBags[i] = new PKCS12SafeBag(SafeBag.getInstance(safeBagSeq.getObjectAt(i))); } return safeBags; } } bouncycastle-1.49.orig/src/org/bouncycastle/pkcs/PKCS8EncryptedPrivateKeyInfo.java0000644000175000017500000000445112110346351027633 0ustar ebourgebourgpackage org.bouncycastle.pkcs; import java.io.ByteArrayInputStream; import java.io.IOException; import org.bouncycastle.asn1.ASN1Primitive; import org.bouncycastle.asn1.pkcs.EncryptedPrivateKeyInfo; import org.bouncycastle.asn1.pkcs.PrivateKeyInfo; import org.bouncycastle.cert.CertIOException; import org.bouncycastle.operator.InputDecryptor; import org.bouncycastle.operator.InputDecryptorProvider; import org.bouncycastle.util.io.Streams; /** * Holding class for a PKCS#8 EncryptedPrivateKeyInfo structure. */ public class PKCS8EncryptedPrivateKeyInfo { private EncryptedPrivateKeyInfo encryptedPrivateKeyInfo; private static EncryptedPrivateKeyInfo parseBytes(byte[] pkcs8Encoding) throws IOException { try { return EncryptedPrivateKeyInfo.getInstance(ASN1Primitive.fromByteArray(pkcs8Encoding)); } catch (ClassCastException e) { throw new CertIOException("malformed data: " + e.getMessage(), e); } catch (IllegalArgumentException e) { throw new CertIOException("malformed data: " + e.getMessage(), e); } } public PKCS8EncryptedPrivateKeyInfo(EncryptedPrivateKeyInfo encryptedPrivateKeyInfo) { this.encryptedPrivateKeyInfo = encryptedPrivateKeyInfo; } public PKCS8EncryptedPrivateKeyInfo(byte[] encryptedPrivateKeyInfo) throws IOException { this(parseBytes(encryptedPrivateKeyInfo)); } public EncryptedPrivateKeyInfo toASN1Structure() { return encryptedPrivateKeyInfo; } public byte[] getEncoded() throws IOException { return encryptedPrivateKeyInfo.getEncoded(); } public PrivateKeyInfo decryptPrivateKeyInfo(InputDecryptorProvider inputDecryptorProvider) throws PKCSException { try { InputDecryptor decrytor = inputDecryptorProvider.get(encryptedPrivateKeyInfo.getEncryptionAlgorithm()); ByteArrayInputStream encIn = new ByteArrayInputStream(encryptedPrivateKeyInfo.getEncryptedData()); return PrivateKeyInfo.getInstance(Streams.readAll(decrytor.getInputStream(encIn))); } catch (Exception e) { throw new PKCSException("unable to read encrypted data: " + e.getMessage(), e); } } } bouncycastle-1.49.orig/src/org/bouncycastle/pkcs/PKCS12SafeBagBuilder.java0000644000175000017500000000500711730473631025737 0ustar ebourgebourgpackage org.bouncycastle.pkcs; import java.io.IOException; import org.bouncycastle.asn1.ASN1Encodable; import org.bouncycastle.asn1.ASN1EncodableVector; import org.bouncycastle.asn1.ASN1ObjectIdentifier; import org.bouncycastle.asn1.DEROctetString; import org.bouncycastle.asn1.DERSet; import org.bouncycastle.asn1.pkcs.Attribute; import org.bouncycastle.asn1.pkcs.CertBag; import org.bouncycastle.asn1.pkcs.PKCSObjectIdentifiers; import org.bouncycastle.asn1.pkcs.PrivateKeyInfo; import org.bouncycastle.asn1.pkcs.SafeBag; import org.bouncycastle.asn1.x509.Certificate; import org.bouncycastle.asn1.x509.CertificateList; import org.bouncycastle.cert.X509CRLHolder; import org.bouncycastle.cert.X509CertificateHolder; import org.bouncycastle.operator.OutputEncryptor; public class PKCS12SafeBagBuilder { private ASN1ObjectIdentifier bagType; private ASN1Encodable bagValue; private ASN1EncodableVector bagAttrs = new ASN1EncodableVector(); public PKCS12SafeBagBuilder(PrivateKeyInfo privateKeyInfo, OutputEncryptor encryptor) { this.bagType = PKCSObjectIdentifiers.pkcs8ShroudedKeyBag; this.bagValue = new PKCS8EncryptedPrivateKeyInfoBuilder(privateKeyInfo).build(encryptor).toASN1Structure(); } public PKCS12SafeBagBuilder(PrivateKeyInfo privateKeyInfo) { this.bagType = PKCSObjectIdentifiers.keyBag; this.bagValue = privateKeyInfo; } public PKCS12SafeBagBuilder(X509CertificateHolder certificate) throws IOException { this(certificate.toASN1Structure()); } public PKCS12SafeBagBuilder(X509CRLHolder crl) throws IOException { this(crl.toASN1Structure()); } public PKCS12SafeBagBuilder(Certificate certificate) throws IOException { this.bagType = PKCSObjectIdentifiers.certBag; this.bagValue = new CertBag(PKCSObjectIdentifiers.x509Certificate, new DEROctetString(certificate.getEncoded())); } public PKCS12SafeBagBuilder(CertificateList crl) throws IOException { this.bagType = PKCSObjectIdentifiers.crlBag; this.bagValue = new CertBag(PKCSObjectIdentifiers.x509Crl, new DEROctetString(crl.getEncoded())); } public PKCS12SafeBagBuilder addBagAttribute(ASN1ObjectIdentifier attrType, ASN1Encodable attrValue) { bagAttrs.add(new Attribute(attrType, new DERSet(attrValue))); return this; } public PKCS12SafeBag build() { return new PKCS12SafeBag(new SafeBag(bagType, bagValue, new DERSet(bagAttrs))); } } bouncycastle-1.49.orig/src/org/bouncycastle/pkcs/MacDataGenerator.java0000644000175000017500000000250312114734767025462 0ustar ebourgebourgpackage org.bouncycastle.pkcs; import java.io.IOException; import java.io.OutputStream; import org.bouncycastle.asn1.pkcs.MacData; import org.bouncycastle.asn1.pkcs.PKCS12PBEParams; import org.bouncycastle.asn1.x509.AlgorithmIdentifier; import org.bouncycastle.asn1.x509.DigestInfo; import org.bouncycastle.operator.MacCalculator; class MacDataGenerator { private PKCS12MacCalculatorBuilder builder; MacDataGenerator(PKCS12MacCalculatorBuilder builder) { this.builder = builder; } public MacData build(char[] password, byte[] data) throws PKCSException { MacCalculator macCalculator; try { macCalculator = builder.build(password); OutputStream out = macCalculator.getOutputStream(); out.write(data); out.close(); } catch (Exception e) { throw new PKCSException("unable to process data: " + e.getMessage(), e); } AlgorithmIdentifier algId = macCalculator.getAlgorithmIdentifier(); DigestInfo dInfo = new DigestInfo(builder.getDigestAlgorithmIdentifier(), macCalculator.getMac()); PKCS12PBEParams params = PKCS12PBEParams.getInstance(algId.getParameters()); return new MacData(dInfo, params.getIV(), params.getIterations().intValue()); } } bouncycastle-1.49.orig/src/org/bouncycastle/pkcs/PKCS12PfxPduBuilder.java0000644000175000017500000001474411730276747025676 0ustar ebourgebourgpackage org.bouncycastle.pkcs; import java.io.IOException; import org.bouncycastle.asn1.ASN1EncodableVector; import org.bouncycastle.asn1.ASN1Sequence; import org.bouncycastle.asn1.DEROctetString; import org.bouncycastle.asn1.DERSequence; import org.bouncycastle.asn1.DLSequence; import org.bouncycastle.asn1.pkcs.AuthenticatedSafe; import org.bouncycastle.asn1.pkcs.ContentInfo; import org.bouncycastle.asn1.pkcs.MacData; import org.bouncycastle.asn1.pkcs.PKCSObjectIdentifiers; import org.bouncycastle.asn1.pkcs.Pfx; import org.bouncycastle.cms.CMSEncryptedDataGenerator; import org.bouncycastle.cms.CMSException; import org.bouncycastle.cms.CMSProcessableByteArray; import org.bouncycastle.operator.OutputEncryptor; /** * A builder for the PKCS#12 Pfx key and certificate store. *

    * For example: you can build a basic key store for the user owning privKey as follows: *

    *
     *      X509Certificate[] chain = ....
     *      PublicKey         pubKey = ....
     *      PrivateKey        privKey = ....
     *      JcaX509ExtensionUtils extUtils = new JcaX509ExtensionUtils();
     *
     *      PKCS12SafeBagBuilder taCertBagBuilder = new JcaPKCS12SafeBagBuilder(chain[2]);
     *
     *      taCertBagBuilder.addBagAttribute(PKCSObjectIdentifiers.pkcs_9_at_friendlyName, new DERBMPString("Bouncy Primary Certificate"));
     *
     *      PKCS12SafeBagBuilder caCertBagBuilder = new JcaPKCS12SafeBagBuilder(chain[1]);
     *
     *      caCertBagBuilder.addBagAttribute(PKCSObjectIdentifiers.pkcs_9_at_friendlyName, new DERBMPString("Bouncy Intermediate Certificate"));
     *
     *      PKCS12SafeBagBuilder eeCertBagBuilder = new JcaPKCS12SafeBagBuilder(chain[0]);
     *
     *      eeCertBagBuilder.addBagAttribute(PKCSObjectIdentifiers.pkcs_9_at_friendlyName, new DERBMPString("Eric's Key"));
     *      eeCertBagBuilder.addBagAttribute(PKCSObjectIdentifiers.pkcs_9_at_localKeyId, extUtils.createSubjectKeyIdentifier(pubKey));
     *
     *      PKCS12SafeBagBuilder keyBagBuilder = new JcaPKCS12SafeBagBuilder(privKey, new BcPKCS12PBEOutputEncryptorBuilder(PKCSObjectIdentifiers.pbeWithSHAAnd3_KeyTripleDES_CBC, new CBCBlockCipher(new DESedeEngine())).build(passwd));
     *
     *      keyBagBuilder.addBagAttribute(PKCSObjectIdentifiers.pkcs_9_at_friendlyName, new DERBMPString("Eric's Key"));
     *      keyBagBuilder.addBagAttribute(PKCSObjectIdentifiers.pkcs_9_at_localKeyId, extUtils.createSubjectKeyIdentifier(pubKey));
     *
     *      //
     *      // construct the actual key store
     *      //
     *      PKCS12PfxPduBuilder pfxPduBuilder = new PKCS12PfxPduBuilder();
     *
     *      PKCS12SafeBag[] certs = new PKCS12SafeBag[3];
     *
     *      certs[0] = eeCertBagBuilder.build();
     *      certs[1] = caCertBagBuilder.build();
     *      certs[2] = taCertBagBuilder.build();
     *
     *      pfxPduBuilder.addEncryptedData(new BcPKCS12PBEOutputEncryptorBuilder(PKCSObjectIdentifiers.pbeWithSHAAnd40BitRC2_CBC, new CBCBlockCipher(new RC2Engine())).build(passwd), certs);
     *
     *      pfxPduBuilder.addData(keyBagBuilder.build());
     *
     *      PKCS12PfxPdu pfx = pfxPduBuilder.build(new BcPKCS12MacCalculatorBuilder(), passwd);
     * 
    * */ public class PKCS12PfxPduBuilder { private ASN1EncodableVector dataVector = new ASN1EncodableVector(); /** * Add a SafeBag that is to be included as is. * * @param data the SafeBag to add. * @return this builder. * @throws IOException */ public PKCS12PfxPduBuilder addData(PKCS12SafeBag data) throws IOException { dataVector.add(new ContentInfo(PKCSObjectIdentifiers.data, new DEROctetString(new DLSequence(data.toASN1Structure()).getEncoded()))); return this; } /** * Add a SafeBag that is to be wrapped in a EncryptedData object. * * @param dataEncryptor the encryptor to use for encoding the data. * @param data the SafeBag to include. * @return this builder. * @throws IOException if a issue occurs processing the data. */ public PKCS12PfxPduBuilder addEncryptedData(OutputEncryptor dataEncryptor, PKCS12SafeBag data) throws IOException { return addEncryptedData(dataEncryptor, new DERSequence(data.toASN1Structure())); } /** * Add a set of SafeBags that are to be wrapped in a EncryptedData object. * * @param dataEncryptor the encryptor to use for encoding the data. * @param data the SafeBags to include. * @return this builder. * @throws IOException if a issue occurs processing the data. */ public PKCS12PfxPduBuilder addEncryptedData(OutputEncryptor dataEncryptor, PKCS12SafeBag[] data) throws IOException { ASN1EncodableVector v = new ASN1EncodableVector(); for (int i = 0; i != data.length; i++) { v.add(data[i].toASN1Structure()); } return addEncryptedData(dataEncryptor, new DLSequence(v)); } private PKCS12PfxPduBuilder addEncryptedData(OutputEncryptor dataEncryptor, ASN1Sequence data) throws IOException { CMSEncryptedDataGenerator envGen = new CMSEncryptedDataGenerator(); try { dataVector.add(envGen.generate(new CMSProcessableByteArray(data.getEncoded()), dataEncryptor).toASN1Structure()); } catch (CMSException e) { throw new PKCSIOException(e.getMessage(), e.getCause()); } return this; } /** * Build the Pfx structure, protecting it with a MAC calculated against the passed in password. * * @param macCalcBuilder a builder for a PKCS12 mac calculator. * @param password the password to use. * @return a Pfx object. * @throws PKCSException on a encoding or processing error. */ public PKCS12PfxPdu build(PKCS12MacCalculatorBuilder macCalcBuilder, char[] password) throws PKCSException { AuthenticatedSafe auth = AuthenticatedSafe.getInstance(new DLSequence(dataVector)); byte[] encAuth; try { encAuth = auth.getEncoded(); } catch (IOException e) { throw new PKCSException("unable to encode AuthenticatedSafe: " + e.getMessage(), e); } ContentInfo mainInfo = new ContentInfo(PKCSObjectIdentifiers.data, new DEROctetString(encAuth)); MacData mData = null; if (macCalcBuilder != null) { MacDataGenerator mdGen = new MacDataGenerator(macCalcBuilder); mData = mdGen.build(password, encAuth); } // // output the Pfx // Pfx pfx = new Pfx(mainInfo, mData); return new PKCS12PfxPdu(pfx); } } bouncycastle-1.49.orig/src/org/bouncycastle/pkcs/PKCS12PfxPdu.java0000644000175000017500000001121512151274320024334 0ustar ebourgebourgpackage org.bouncycastle.pkcs; import java.io.IOException; import org.bouncycastle.asn1.ASN1OctetString; import org.bouncycastle.asn1.ASN1Primitive; import org.bouncycastle.asn1.ASN1Sequence; import org.bouncycastle.asn1.pkcs.ContentInfo; import org.bouncycastle.asn1.pkcs.MacData; import org.bouncycastle.asn1.pkcs.PKCS12PBEParams; import org.bouncycastle.asn1.pkcs.Pfx; import org.bouncycastle.asn1.x509.AlgorithmIdentifier; import org.bouncycastle.cert.CertIOException; import org.bouncycastle.util.Arrays; /** * A holding class for the PKCS12 Pfx structure. */ public class PKCS12PfxPdu { private Pfx pfx; private static Pfx parseBytes(byte[] pfxEncoding) throws IOException { try { return Pfx.getInstance(ASN1Primitive.fromByteArray(pfxEncoding)); } catch (ClassCastException e) { throw new CertIOException("malformed data: " + e.getMessage(), e); } catch (IllegalArgumentException e) { throw new CertIOException("malformed data: " + e.getMessage(), e); } } public PKCS12PfxPdu(Pfx pfx) { this.pfx = pfx; } public PKCS12PfxPdu(byte[] pfx) throws IOException { this(parseBytes(pfx)); } /** * Return the content infos in the AuthenticatedSafe contained in this Pfx. * * @return an array of ContentInfo. */ public ContentInfo[] getContentInfos() { ASN1Sequence seq = ASN1Sequence.getInstance(ASN1OctetString.getInstance(this.pfx.getAuthSafe().getContent()).getOctets()); ContentInfo[] content = new ContentInfo[seq.size()]; for (int i = 0; i != seq.size(); i++) { content[i] = ContentInfo.getInstance(seq.getObjectAt(i)); } return content; } /** * Return whether or not there is MAC attached to this file. * * @return true if there is, false otherwise. */ public boolean hasMac() { return pfx.getMacData() != null; } /** * Return the algorithm identifier describing the MAC algorithm * * @return the AlgorithmIdentifier representing the MAC algorithm, null if none present. */ public AlgorithmIdentifier getMacAlgorithmID() { MacData md = pfx.getMacData(); if (md != null) { return md.getMac().getAlgorithmId(); } return null; } /** * Verify the MacData attached to the PFX is consistent with what is expected. * * @param macCalcProviderBuilder provider builder for the calculator for the MAC * @param password password to use * @return true if mac data is valid, false otherwise. * @throws PKCSException if there is a problem evaluating the MAC. * @throws IllegalStateException if no MAC is actually present */ public boolean isMacValid(PKCS12MacCalculatorBuilderProvider macCalcProviderBuilder, char[] password) throws PKCSException { if (hasMac()) { MacData pfxmData = pfx.getMacData(); MacDataGenerator mdGen = new MacDataGenerator(macCalcProviderBuilder.get(new AlgorithmIdentifier(pfxmData.getMac().getAlgorithmId().getAlgorithm(), new PKCS12PBEParams(pfxmData.getSalt(), pfxmData.getIterationCount().intValue())))); try { MacData mData = mdGen.build( password, ASN1OctetString.getInstance(pfx.getAuthSafe().getContent()).getOctets()); return Arrays.constantTimeAreEqual(mData.getEncoded(), pfx.getMacData().getEncoded()); } catch (IOException e) { throw new PKCSException("unable to process AuthSafe: " + e.getMessage()); } } throw new IllegalStateException("no MAC present on PFX"); } /** * Return the underlying ASN.1 object. * * @return a Pfx object. */ public Pfx toASN1Structure() { return pfx; } public byte[] getEncoded() throws IOException { return toASN1Structure().getEncoded(); } /** * Return a Pfx with the outer wrapper encoded as asked for. For example, Pfx is a usually * a BER encoded object, to get one with DefiniteLength encoding use: *
         * getEncoded(ASN1Encoding.DL)
         * 
    * @param encoding encoding style (ASN1Encoding.DER, ASN1Encoding.DL, ASN1Encoding.BER) * @return a byte array containing the encoded object. * @throws IOException */ public byte[] getEncoded(String encoding) throws IOException { return toASN1Structure().getEncoded(encoding); } } bouncycastle-1.49.orig/src/org/bouncycastle/pkcs/PKCSException.java0000644000175000017500000000070511514737443024737 0ustar ebourgebourgpackage org.bouncycastle.pkcs; /** * General checked Exception thrown in the cert package and its sub-packages. */ public class PKCSException extends Exception { private Throwable cause; public PKCSException(String msg, Throwable cause) { super(msg); this.cause = cause; } public PKCSException(String msg) { super(msg); } public Throwable getCause() { return cause; } } bouncycastle-1.49.orig/src/org/bouncycastle/pkcs/jcajce/0000755000175000017500000000000012152033551022656 5ustar ebourgebourgbouncycastle-1.49.orig/src/org/bouncycastle/pkcs/jcajce/JcaPKCS8EncryptedPrivateKeyInfoBuilder.java0000644000175000017500000000070011730247706033003 0ustar ebourgebourgpackage org.bouncycastle.pkcs.jcajce; import java.security.PrivateKey; import org.bouncycastle.asn1.pkcs.PrivateKeyInfo; import org.bouncycastle.pkcs.PKCS8EncryptedPrivateKeyInfoBuilder; public class JcaPKCS8EncryptedPrivateKeyInfoBuilder extends PKCS8EncryptedPrivateKeyInfoBuilder { public JcaPKCS8EncryptedPrivateKeyInfoBuilder(PrivateKey privateKey) { super(PrivateKeyInfo.getInstance(privateKey.getEncoded())); } } bouncycastle-1.49.orig/src/org/bouncycastle/pkcs/jcajce/JcaPKCS12SafeBagBuilder.java0000644000175000017500000000250611730473631027575 0ustar ebourgebourgpackage org.bouncycastle.pkcs.jcajce; import java.io.IOException; import java.security.PrivateKey; import java.security.cert.CertificateEncodingException; import java.security.cert.X509Certificate; import org.bouncycastle.asn1.pkcs.PrivateKeyInfo; import org.bouncycastle.asn1.x509.Certificate; import org.bouncycastle.operator.OutputEncryptor; import org.bouncycastle.pkcs.PKCS12SafeBagBuilder; import org.bouncycastle.pkcs.PKCSIOException; public class JcaPKCS12SafeBagBuilder extends PKCS12SafeBagBuilder { public JcaPKCS12SafeBagBuilder(X509Certificate certificate) throws IOException { super(convertCert(certificate)); } private static Certificate convertCert(X509Certificate certificate) throws IOException { try { return Certificate.getInstance(certificate.getEncoded()); } catch (CertificateEncodingException e) { throw new PKCSIOException("cannot encode certificate: " + e.getMessage(), e); } } public JcaPKCS12SafeBagBuilder(PrivateKey privateKey, OutputEncryptor encryptor) { super(PrivateKeyInfo.getInstance(privateKey.getEncoded()), encryptor); } public JcaPKCS12SafeBagBuilder(PrivateKey privateKey) { super(PrivateKeyInfo.getInstance(privateKey.getEncoded())); } } bouncycastle-1.49.orig/src/org/bouncycastle/pkcs/jcajce/JcePKCS12MacCalculatorBuilderProvider.java0000644000175000017500000000757212115201201032522 0ustar ebourgebourgpackage org.bouncycastle.pkcs.jcajce; import java.io.OutputStream; import java.security.Provider; import javax.crypto.Mac; import javax.crypto.SecretKey; import javax.crypto.SecretKeyFactory; import javax.crypto.spec.PBEKeySpec; import javax.crypto.spec.PBEParameterSpec; import org.bouncycastle.asn1.ASN1ObjectIdentifier; import org.bouncycastle.asn1.DERNull; import org.bouncycastle.asn1.pkcs.PKCS12PBEParams; import org.bouncycastle.asn1.x509.AlgorithmIdentifier; import org.bouncycastle.crypto.generators.PKCS12ParametersGenerator; import org.bouncycastle.jcajce.DefaultJcaJceHelper; import org.bouncycastle.jcajce.JcaJceHelper; import org.bouncycastle.jcajce.NamedJcaJceHelper; import org.bouncycastle.jcajce.ProviderJcaJceHelper; import org.bouncycastle.jcajce.io.MacOutputStream; import org.bouncycastle.operator.GenericKey; import org.bouncycastle.operator.MacCalculator; import org.bouncycastle.operator.OperatorCreationException; import org.bouncycastle.pkcs.PKCS12MacCalculatorBuilder; import org.bouncycastle.pkcs.PKCS12MacCalculatorBuilderProvider; public class JcePKCS12MacCalculatorBuilderProvider implements PKCS12MacCalculatorBuilderProvider { private JcaJceHelper helper = new DefaultJcaJceHelper(); public JcePKCS12MacCalculatorBuilderProvider() { } public JcePKCS12MacCalculatorBuilderProvider setProvider(Provider provider) { this.helper = new ProviderJcaJceHelper(provider); return this; } public JcePKCS12MacCalculatorBuilderProvider setProvider(String providerName) { this.helper = new NamedJcaJceHelper(providerName); return this; } public PKCS12MacCalculatorBuilder get(final AlgorithmIdentifier algorithmIdentifier) { return new PKCS12MacCalculatorBuilder() { public MacCalculator build(final char[] password) throws OperatorCreationException { final PKCS12PBEParams pbeParams = PKCS12PBEParams.getInstance(algorithmIdentifier.getParameters()); try { final ASN1ObjectIdentifier algorithm = algorithmIdentifier.getAlgorithm(); final Mac mac = helper.createMac(algorithm.getId()); SecretKeyFactory keyFact = helper.createSecretKeyFactory(algorithm.getId()); PBEParameterSpec defParams = new PBEParameterSpec(pbeParams.getIV(), pbeParams.getIterations().intValue()); PBEKeySpec pbeSpec = new PBEKeySpec(password); SecretKey key = keyFact.generateSecret(pbeSpec); mac.init(key, defParams); return new MacCalculator() { public AlgorithmIdentifier getAlgorithmIdentifier() { return new AlgorithmIdentifier(algorithm, pbeParams); } public OutputStream getOutputStream() { return new MacOutputStream(mac); } public byte[] getMac() { return mac.doFinal(); } public GenericKey getKey() { return new GenericKey(getAlgorithmIdentifier(), PKCS12ParametersGenerator.PKCS12PasswordToBytes(password)); } }; } catch (Exception e) { throw new OperatorCreationException("unable to create MAC calculator: " + e.getMessage(), e); } } public AlgorithmIdentifier getDigestAlgorithmIdentifier() { return new AlgorithmIdentifier(algorithmIdentifier.getAlgorithm(), DERNull.INSTANCE); } }; } } bouncycastle-1.49.orig/src/org/bouncycastle/pkcs/jcajce/JcaPKCS10CertificationRequestBuilder.java0000644000175000017500000000272311514737071032441 0ustar ebourgebourgpackage org.bouncycastle.pkcs.jcajce; import java.security.PublicKey; import javax.security.auth.x500.X500Principal; import org.bouncycastle.asn1.x500.X500Name; import org.bouncycastle.asn1.x509.SubjectPublicKeyInfo; import org.bouncycastle.pkcs.PKCS10CertificationRequestBuilder; /** * Extension of the PKCS#10 builder to support PublicKey and X500Principal objects. */ public class JcaPKCS10CertificationRequestBuilder extends PKCS10CertificationRequestBuilder { /** * Create a PKCS#10 builder for the passed in subject and JCA public key. * * @param subject an X500Name containing the subject associated with the request we are building. * @param publicKey a JCA public key that is to be associated with the request we are building. */ public JcaPKCS10CertificationRequestBuilder(X500Name subject, PublicKey publicKey) { super(subject, SubjectPublicKeyInfo.getInstance(publicKey.getEncoded())); } /** * Create a PKCS#10 builder for the passed in subject and JCA public key. * * @param subject an X500Principal containing the subject associated with the request we are building. * @param publicKey a JCA public key that is to be associated with the request we are building. */ public JcaPKCS10CertificationRequestBuilder(X500Principal subject, PublicKey publicKey) { super(X500Name.getInstance(subject.getEncoded()), SubjectPublicKeyInfo.getInstance(publicKey.getEncoded())); } } bouncycastle-1.49.orig/src/org/bouncycastle/pkcs/jcajce/JcaPKCS10CertificationRequest.java0000644000175000017500000000666311737231633031141 0ustar ebourgebourgpackage org.bouncycastle.pkcs.jcajce; import java.io.IOException; import java.security.InvalidKeyException; import java.security.KeyFactory; import java.security.NoSuchAlgorithmException; import java.security.NoSuchProviderException; import java.security.Provider; import java.security.PublicKey; import java.security.spec.InvalidKeySpecException; import java.security.spec.X509EncodedKeySpec; import java.util.Hashtable; import org.bouncycastle.asn1.pkcs.CertificationRequest; import org.bouncycastle.asn1.pkcs.PKCSObjectIdentifiers; import org.bouncycastle.asn1.x509.SubjectPublicKeyInfo; import org.bouncycastle.asn1.x9.X9ObjectIdentifiers; import org.bouncycastle.jcajce.DefaultJcaJceHelper; import org.bouncycastle.jcajce.JcaJceHelper; import org.bouncycastle.jcajce.NamedJcaJceHelper; import org.bouncycastle.jcajce.ProviderJcaJceHelper; import org.bouncycastle.pkcs.PKCS10CertificationRequest; public class JcaPKCS10CertificationRequest extends PKCS10CertificationRequest { private static Hashtable keyAlgorithms = new Hashtable(); static { // // key types // keyAlgorithms.put(PKCSObjectIdentifiers.rsaEncryption, "RSA"); keyAlgorithms.put(X9ObjectIdentifiers.id_dsa, "DSA"); } private JcaJceHelper helper = new DefaultJcaJceHelper(); public JcaPKCS10CertificationRequest(CertificationRequest certificationRequest) { super(certificationRequest); } public JcaPKCS10CertificationRequest(byte[] encoding) throws IOException { super(encoding); } public JcaPKCS10CertificationRequest(PKCS10CertificationRequest requestHolder) { super(requestHolder.toASN1Structure()); } public JcaPKCS10CertificationRequest setProvider(String providerName) { helper = new NamedJcaJceHelper(providerName); return this; } public JcaPKCS10CertificationRequest setProvider(Provider provider) { helper = new ProviderJcaJceHelper(provider); return this; } public PublicKey getPublicKey() throws InvalidKeyException, NoSuchAlgorithmException { try { SubjectPublicKeyInfo keyInfo = this.getSubjectPublicKeyInfo(); X509EncodedKeySpec xspec = new X509EncodedKeySpec(keyInfo.getEncoded()); KeyFactory kFact; try { kFact = helper.createKeyFactory(keyInfo.getAlgorithm().getAlgorithm().getId()); } catch (NoSuchAlgorithmException e) { // // try an alternate // if (keyAlgorithms.get(keyInfo.getAlgorithm().getAlgorithm()) != null) { String keyAlgorithm = (String)keyAlgorithms.get(keyInfo.getAlgorithm().getAlgorithm()); kFact = helper.createKeyFactory(keyAlgorithm); } else { throw e; } } return kFact.generatePublic(xspec); } catch (InvalidKeySpecException e) { throw new InvalidKeyException("error decoding public key"); } catch (IOException e) { throw new InvalidKeyException("error extracting key encoding"); } catch (NoSuchProviderException e) { throw new NoSuchAlgorithmException("cannot find provider: " + e.getMessage()); } } } bouncycastle-1.49.orig/src/org/bouncycastle/pkcs/jcajce/JcePKCSPBEOutputEncryptorBuilder.java0000644000175000017500000001430012115100341031655 0ustar ebourgebourgpackage org.bouncycastle.pkcs.jcajce; import java.io.OutputStream; import java.security.Provider; import java.security.SecureRandom; import javax.crypto.Cipher; import javax.crypto.CipherOutputStream; import javax.crypto.SecretKey; import javax.crypto.SecretKeyFactory; import javax.crypto.spec.PBEKeySpec; import javax.crypto.spec.PBEParameterSpec; import org.bouncycastle.asn1.ASN1ObjectIdentifier; import org.bouncycastle.asn1.ASN1Primitive; import org.bouncycastle.asn1.bc.BCObjectIdentifiers; import org.bouncycastle.asn1.pkcs.EncryptionScheme; import org.bouncycastle.asn1.pkcs.KeyDerivationFunc; import org.bouncycastle.asn1.pkcs.PBES2Parameters; import org.bouncycastle.asn1.pkcs.PBKDF2Params; import org.bouncycastle.asn1.pkcs.PKCS12PBEParams; import org.bouncycastle.asn1.pkcs.PKCSObjectIdentifiers; import org.bouncycastle.asn1.x509.AlgorithmIdentifier; import org.bouncycastle.crypto.PBEParametersGenerator; import org.bouncycastle.jcajce.DefaultJcaJceHelper; import org.bouncycastle.jcajce.JcaJceHelper; import org.bouncycastle.jcajce.NamedJcaJceHelper; import org.bouncycastle.jcajce.ProviderJcaJceHelper; import org.bouncycastle.operator.DefaultSecretKeyProvider; import org.bouncycastle.operator.GenericKey; import org.bouncycastle.operator.OperatorCreationException; import org.bouncycastle.operator.OutputEncryptor; import org.bouncycastle.operator.SecretKeySizeProvider; public class JcePKCSPBEOutputEncryptorBuilder { private JcaJceHelper helper = new DefaultJcaJceHelper(); private ASN1ObjectIdentifier algorithm; private ASN1ObjectIdentifier keyEncAlgorithm; private SecureRandom random; private SecretKeySizeProvider keySizeProvider = DefaultSecretKeyProvider.INSTANCE; public JcePKCSPBEOutputEncryptorBuilder(ASN1ObjectIdentifier algorithm) { if (isPKCS12(algorithm)) { this.algorithm = algorithm; this.keyEncAlgorithm = algorithm; } else { this.algorithm = PKCSObjectIdentifiers.id_PBES2; this.keyEncAlgorithm = algorithm; } } public JcePKCSPBEOutputEncryptorBuilder setProvider(Provider provider) { this.helper = new ProviderJcaJceHelper(provider); return this; } public JcePKCSPBEOutputEncryptorBuilder setProvider(String providerName) { this.helper = new NamedJcaJceHelper(providerName); return this; } /** * Set the lookup provider of AlgorithmIdentifier returning key_size_in_bits used to * handle PKCS5 decryption. * * @param keySizeProvider a provider of integer secret key sizes. * * @return the current builder. */ public JcePKCSPBEOutputEncryptorBuilder setKeySizeProvider(SecretKeySizeProvider keySizeProvider) { this.keySizeProvider = keySizeProvider; return this; } public OutputEncryptor build(final char[] password) throws OperatorCreationException { final Cipher cipher; SecretKey key; if (random == null) { random = new SecureRandom(); } final AlgorithmIdentifier encryptionAlg; final byte[] salt = new byte[20]; final int iterationCount = 1024; random.nextBytes(salt); try { if (algorithm.on(PKCSObjectIdentifiers.pkcs_12PbeIds)) { PBEKeySpec pbeSpec = new PBEKeySpec(password); SecretKeyFactory keyFact = helper.createSecretKeyFactory(algorithm.getId()); PBEParameterSpec defParams = new PBEParameterSpec(salt, iterationCount); key = keyFact.generateSecret(pbeSpec); cipher = helper.createCipher(algorithm.getId()); cipher.init(Cipher.ENCRYPT_MODE, key, defParams); encryptionAlg = new AlgorithmIdentifier(algorithm, new PKCS12PBEParams(salt, iterationCount)); } else if (algorithm.equals(PKCSObjectIdentifiers.id_PBES2)) { SecretKeyFactory keyFact = helper.createSecretKeyFactory(PKCSObjectIdentifiers.id_PBKDF2.getId()); key = keyFact.generateSecret(new PBEKeySpec(password, salt, iterationCount, keySizeProvider.getKeySize(new AlgorithmIdentifier(keyEncAlgorithm)))); cipher = helper.createCipher(keyEncAlgorithm.getId()); cipher.init(Cipher.ENCRYPT_MODE, key, random); PBES2Parameters algParams = new PBES2Parameters( new KeyDerivationFunc(PKCSObjectIdentifiers.id_PBKDF2, new PBKDF2Params(salt, iterationCount)), new EncryptionScheme(keyEncAlgorithm, ASN1Primitive.fromByteArray(cipher.getParameters().getEncoded()))); encryptionAlg = new AlgorithmIdentifier(algorithm, algParams); } else { throw new OperatorCreationException("unrecognised algorithm"); } return new OutputEncryptor() { public AlgorithmIdentifier getAlgorithmIdentifier() { return encryptionAlg; } public OutputStream getOutputStream(OutputStream out) { return new CipherOutputStream(out, cipher); } public GenericKey getKey() { if (isPKCS12(encryptionAlg.getAlgorithm())) { return new GenericKey(encryptionAlg, PBEParametersGenerator.PKCS5PasswordToBytes(password)); } else { return new GenericKey(encryptionAlg, PBEParametersGenerator.PKCS12PasswordToBytes(password)); } } }; } catch (Exception e) { throw new OperatorCreationException("unable to create OutputEncryptor: " + e.getMessage(), e); } } private boolean isPKCS12(ASN1ObjectIdentifier algorithm) { return algorithm.on(PKCSObjectIdentifiers.pkcs_12PbeIds) || algorithm.on(BCObjectIdentifiers.bc_pbe_sha1_pkcs12) || algorithm.on(BCObjectIdentifiers.bc_pbe_sha256_pkcs12); } } bouncycastle-1.49.orig/src/org/bouncycastle/pkcs/jcajce/JcePKCSPBEInputDecryptorProviderBuilder.java0000644000175000017500000001411212151274320033167 0ustar ebourgebourgpackage org.bouncycastle.pkcs.jcajce; import java.io.InputStream; import java.security.Provider; import javax.crypto.Cipher; import javax.crypto.CipherInputStream; import javax.crypto.SecretKey; import javax.crypto.SecretKeyFactory; import javax.crypto.spec.IvParameterSpec; import javax.crypto.spec.PBEKeySpec; import javax.crypto.spec.PBEParameterSpec; import org.bouncycastle.asn1.ASN1ObjectIdentifier; import org.bouncycastle.asn1.ASN1OctetString; import org.bouncycastle.asn1.pkcs.PBES2Parameters; import org.bouncycastle.asn1.pkcs.PBKDF2Params; import org.bouncycastle.asn1.pkcs.PKCS12PBEParams; import org.bouncycastle.asn1.pkcs.PKCSObjectIdentifiers; import org.bouncycastle.asn1.x509.AlgorithmIdentifier; import org.bouncycastle.jcajce.DefaultJcaJceHelper; import org.bouncycastle.jcajce.JcaJceHelper; import org.bouncycastle.jcajce.NamedJcaJceHelper; import org.bouncycastle.jcajce.ProviderJcaJceHelper; import org.bouncycastle.jcajce.provider.symmetric.util.BCPBEKey; import org.bouncycastle.operator.DefaultSecretKeyProvider; import org.bouncycastle.operator.GenericKey; import org.bouncycastle.operator.InputDecryptor; import org.bouncycastle.operator.InputDecryptorProvider; import org.bouncycastle.operator.OperatorCreationException; import org.bouncycastle.operator.SecretKeySizeProvider; import org.bouncycastle.operator.jcajce.JceGenericKey; public class JcePKCSPBEInputDecryptorProviderBuilder { private JcaJceHelper helper = new DefaultJcaJceHelper(); private boolean wrongPKCS12Zero = false; private SecretKeySizeProvider keySizeProvider = DefaultSecretKeyProvider.INSTANCE; public JcePKCSPBEInputDecryptorProviderBuilder() { } public JcePKCSPBEInputDecryptorProviderBuilder setProvider(Provider provider) { this.helper = new ProviderJcaJceHelper(provider); return this; } public JcePKCSPBEInputDecryptorProviderBuilder setProvider(String providerName) { this.helper = new NamedJcaJceHelper(providerName); return this; } public JcePKCSPBEInputDecryptorProviderBuilder setTryWrongPKCS12Zero(boolean tryWrong) { this.wrongPKCS12Zero = tryWrong; return this; } /** * Set the lookup provider of AlgorithmIdentifier returning key_size_in_bits used to * handle PKCS5 decryption. * * @param keySizeProvider a provider of integer secret key sizes. * * @return the current builder. */ public JcePKCSPBEInputDecryptorProviderBuilder setKeySizeProvider(SecretKeySizeProvider keySizeProvider) { this.keySizeProvider = keySizeProvider; return this; } public InputDecryptorProvider build(final char[] password) { return new InputDecryptorProvider() { private Cipher cipher; private SecretKey key; private AlgorithmIdentifier encryptionAlg; public InputDecryptor get(final AlgorithmIdentifier algorithmIdentifier) throws OperatorCreationException { ASN1ObjectIdentifier algorithm = algorithmIdentifier.getAlgorithm(); try { if (algorithm.on(PKCSObjectIdentifiers.pkcs_12PbeIds)) { PKCS12PBEParams pbeParams = PKCS12PBEParams.getInstance(algorithmIdentifier.getParameters()); PBEKeySpec pbeSpec = new PBEKeySpec(password); SecretKeyFactory keyFact = helper.createSecretKeyFactory(algorithm.getId()); PBEParameterSpec defParams = new PBEParameterSpec( pbeParams.getIV(), pbeParams.getIterations().intValue()); key = keyFact.generateSecret(pbeSpec); if (key instanceof BCPBEKey) { ((BCPBEKey)key).setTryWrongPKCS12Zero(wrongPKCS12Zero); } cipher = helper.createCipher(algorithm.getId()); cipher.init(Cipher.DECRYPT_MODE, key, defParams); encryptionAlg = algorithmIdentifier; } else if (algorithm.equals(PKCSObjectIdentifiers.id_PBES2)) { PBES2Parameters alg = PBES2Parameters.getInstance(algorithmIdentifier.getParameters()); PBKDF2Params func = PBKDF2Params.getInstance(alg.getKeyDerivationFunc().getParameters()); AlgorithmIdentifier encScheme = AlgorithmIdentifier.getInstance(alg.getEncryptionScheme()); SecretKeyFactory keyFact = helper.createSecretKeyFactory(alg.getKeyDerivationFunc().getAlgorithm().getId()); key = keyFact.generateSecret(new PBEKeySpec(password, func.getSalt(), func.getIterationCount().intValue(), keySizeProvider.getKeySize(encScheme))); cipher = helper.createCipher(alg.getEncryptionScheme().getAlgorithm().getId()); encryptionAlg = AlgorithmIdentifier.getInstance(alg.getEncryptionScheme()); cipher.init(Cipher.DECRYPT_MODE, key, new IvParameterSpec(ASN1OctetString.getInstance(alg.getEncryptionScheme().getParameters()).getOctets())); } } catch (Exception e) { throw new OperatorCreationException("unable to create InputDecryptor: " + e.getMessage(), e); } return new InputDecryptor() { public AlgorithmIdentifier getAlgorithmIdentifier() { return encryptionAlg; } public InputStream getInputStream(InputStream input) { return new CipherInputStream(input, cipher); } public GenericKey getKey() { return new JceGenericKey(encryptionAlg, key); } }; } }; } } bouncycastle-1.49.orig/src/org/bouncycastle/pkcs/jcajce/JcePKCS12MacCalculatorBuilder.java0000644000175000017500000000740312115012014031002 0ustar ebourgebourgpackage org.bouncycastle.pkcs.jcajce; import java.io.OutputStream; import java.security.Provider; import java.security.SecureRandom; import javax.crypto.Mac; import javax.crypto.SecretKey; import javax.crypto.SecretKeyFactory; import javax.crypto.spec.PBEKeySpec; import javax.crypto.spec.PBEParameterSpec; import org.bouncycastle.asn1.ASN1ObjectIdentifier; import org.bouncycastle.asn1.DERNull; import org.bouncycastle.asn1.oiw.OIWObjectIdentifiers; import org.bouncycastle.asn1.pkcs.PKCS12PBEParams; import org.bouncycastle.asn1.x509.AlgorithmIdentifier; import org.bouncycastle.crypto.ExtendedDigest; import org.bouncycastle.crypto.generators.PKCS12ParametersGenerator; import org.bouncycastle.jcajce.DefaultJcaJceHelper; import org.bouncycastle.jcajce.JcaJceHelper; import org.bouncycastle.jcajce.NamedJcaJceHelper; import org.bouncycastle.jcajce.ProviderJcaJceHelper; import org.bouncycastle.jcajce.io.MacOutputStream; import org.bouncycastle.operator.GenericKey; import org.bouncycastle.operator.MacCalculator; import org.bouncycastle.operator.OperatorCreationException; import org.bouncycastle.pkcs.PKCS12MacCalculatorBuilder; public class JcePKCS12MacCalculatorBuilder implements PKCS12MacCalculatorBuilder { private JcaJceHelper helper = new DefaultJcaJceHelper(); private ExtendedDigest digest; private ASN1ObjectIdentifier algorithm; private SecureRandom random; private int saltLength; private int iterationCount = 1024; public JcePKCS12MacCalculatorBuilder() { this(OIWObjectIdentifiers.idSHA1); } public JcePKCS12MacCalculatorBuilder(ASN1ObjectIdentifier hashAlgorithm) { this.algorithm = hashAlgorithm; } public JcePKCS12MacCalculatorBuilder setProvider(Provider provider) { this.helper = new ProviderJcaJceHelper(provider); return this; } public JcePKCS12MacCalculatorBuilder setProvider(String providerName) { this.helper = new NamedJcaJceHelper(providerName); return this; } public AlgorithmIdentifier getDigestAlgorithmIdentifier() { return new AlgorithmIdentifier(algorithm, DERNull.INSTANCE); } public MacCalculator build(final char[] password) throws OperatorCreationException { if (random == null) { random = new SecureRandom(); } try { final Mac mac = helper.createMac(algorithm.getId()); saltLength = mac.getMacLength(); final byte[] salt = new byte[saltLength]; random.nextBytes(salt); SecretKeyFactory keyFact = helper.createSecretKeyFactory(algorithm.getId()); PBEParameterSpec defParams = new PBEParameterSpec(salt, iterationCount); PBEKeySpec pbeSpec = new PBEKeySpec(password); SecretKey key = keyFact.generateSecret(pbeSpec); mac.init(key, defParams); return new MacCalculator() { public AlgorithmIdentifier getAlgorithmIdentifier() { return new AlgorithmIdentifier(algorithm, new PKCS12PBEParams(salt, iterationCount)); } public OutputStream getOutputStream() { return new MacOutputStream(mac); } public byte[] getMac() { return mac.doFinal(); } public GenericKey getKey() { return new GenericKey(getAlgorithmIdentifier(), PKCS12ParametersGenerator.PKCS12PasswordToBytes(password)); } }; } catch (Exception e) { throw new OperatorCreationException("unable to create MAC calculator: " + e.getMessage(), e); } } } bouncycastle-1.49.orig/src/org/bouncycastle/pkcs/jcajce/package.html0000644000175000017500000000033311501603741025137 0ustar ebourgebourg JCA extensions to the PKCS#10 certification request package. bouncycastle-1.49.orig/src/org/bouncycastle/pkcs/PKCS12MacCalculatorBuilder.java0000644000175000017500000000060012114563406027150 0ustar ebourgebourgpackage org.bouncycastle.pkcs; import org.bouncycastle.asn1.x509.AlgorithmIdentifier; import org.bouncycastle.operator.MacCalculator; import org.bouncycastle.operator.OperatorCreationException; public interface PKCS12MacCalculatorBuilder { MacCalculator build(char[] password) throws OperatorCreationException; AlgorithmIdentifier getDigestAlgorithmIdentifier(); } bouncycastle-1.49.orig/src/org/bouncycastle/pkcs/PKCS10CertificationRequestBuilder.java0000644000175000017500000001224712116547773030615 0ustar ebourgebourgpackage org.bouncycastle.pkcs; import java.io.IOException; import java.io.OutputStream; import java.util.ArrayList; import java.util.Iterator; import java.util.List; import org.bouncycastle.asn1.ASN1Encodable; import org.bouncycastle.asn1.ASN1EncodableVector; import org.bouncycastle.asn1.ASN1Encoding; import org.bouncycastle.asn1.ASN1ObjectIdentifier; import org.bouncycastle.asn1.DERBitString; import org.bouncycastle.asn1.DERSet; import org.bouncycastle.asn1.pkcs.Attribute; import org.bouncycastle.asn1.pkcs.CertificationRequest; import org.bouncycastle.asn1.pkcs.CertificationRequestInfo; import org.bouncycastle.asn1.x500.X500Name; import org.bouncycastle.asn1.x509.SubjectPublicKeyInfo; import org.bouncycastle.operator.ContentSigner; /** * A class for creating PKCS#10 Certification requests. *
     * CertificationRequest ::= SEQUENCE {
     *   certificationRequestInfo  CertificationRequestInfo,
     *   signatureAlgorithm        AlgorithmIdentifier{{ SignatureAlgorithms }},
     *   signature                 BIT STRING
     * }
     *
     * CertificationRequestInfo ::= SEQUENCE {
     *   version             INTEGER { v1(0) } (v1,...),
     *   subject             Name,
     *   subjectPKInfo   SubjectPublicKeyInfo{{ PKInfoAlgorithms }},
     *   attributes          [0] Attributes{{ CRIAttributes }}
     *  }
     *
     *  Attributes { ATTRIBUTE:IOSet } ::= SET OF Attribute{{ IOSet }}
     *
     *  Attribute { ATTRIBUTE:IOSet } ::= SEQUENCE {
     *    type    ATTRIBUTE.&id({IOSet}),
     *    values  SET SIZE(1..MAX) OF ATTRIBUTE.&Type({IOSet}{\@type})
     *  }
     * 
    */ public class PKCS10CertificationRequestBuilder { private SubjectPublicKeyInfo publicKeyInfo; private X500Name subject; private List attributes = new ArrayList(); private boolean leaveOffEmpty = false; /** * Basic constructor. * * @param subject the X.500 Name defining the certificate subject this request is for. * @param publicKeyInfo the info structure for the public key to be associated with this subject. */ public PKCS10CertificationRequestBuilder(X500Name subject, SubjectPublicKeyInfo publicKeyInfo) { this.subject = subject; this.publicKeyInfo = publicKeyInfo; } /** * Add an attribute to the certification request we are building. * * @param attrType the OID giving the type of the attribute. * @param attrValue the ASN.1 structure that forms the value of the attribute. * @return this builder object. */ public PKCS10CertificationRequestBuilder addAttribute(ASN1ObjectIdentifier attrType, ASN1Encodable attrValue) { attributes.add(new Attribute(attrType, new DERSet(attrValue))); return this; } /** * Add an attribute with multiple values to the certification request we are building. * * @param attrType the OID giving the type of the attribute. * @param attrValues an array of ASN.1 structures that form the value of the attribute. * @return this builder object. */ public PKCS10CertificationRequestBuilder addAttribute(ASN1ObjectIdentifier attrType, ASN1Encodable[] attrValues) { attributes.add(new Attribute(attrType, new DERSet(attrValues))); return this; } /** * The attributes field in PKCS10 should encoded to an empty tagged set if there are * no attributes. Some CAs will reject requests with the attribute field present. * * @param leaveOffEmpty true if empty attributes should be left out of the encoding false otherwise. * @return this builder object. */ public PKCS10CertificationRequestBuilder setLeaveOffEmptyAttributes(boolean leaveOffEmpty) { this.leaveOffEmpty = leaveOffEmpty; return this; } /** * Generate an PKCS#10 request based on the past in signer. * * @param signer the content signer to be used to generate the signature validating the certificate. * @return a holder containing the resulting PKCS#10 certification request. */ public PKCS10CertificationRequest build( ContentSigner signer) { CertificationRequestInfo info; if (attributes.isEmpty()) { if (leaveOffEmpty) { info = new CertificationRequestInfo(subject, publicKeyInfo, null); } else { info = new CertificationRequestInfo(subject, publicKeyInfo, new DERSet()); } } else { ASN1EncodableVector v = new ASN1EncodableVector(); for (Iterator it = attributes.iterator(); it.hasNext();) { v.add(Attribute.getInstance(it.next())); } info = new CertificationRequestInfo(subject, publicKeyInfo, new DERSet(v)); } try { OutputStream sOut = signer.getOutputStream(); sOut.write(info.getEncoded(ASN1Encoding.DER)); sOut.close(); return new PKCS10CertificationRequest(new CertificationRequest(info, signer.getAlgorithmIdentifier(), new DERBitString(signer.getSignature()))); } catch (IOException e) { throw new IllegalStateException("cannot produce certification request signature"); } } } bouncycastle-1.49.orig/src/org/bouncycastle/pkcs/PKCS12SafeBag.java0000644000175000017500000000550512114750701024424 0ustar ebourgebourgpackage org.bouncycastle.pkcs; import org.bouncycastle.asn1.ASN1ObjectIdentifier; import org.bouncycastle.asn1.ASN1OctetString; import org.bouncycastle.asn1.ASN1Set; import org.bouncycastle.asn1.pkcs.Attribute; import org.bouncycastle.asn1.pkcs.CRLBag; import org.bouncycastle.asn1.pkcs.CertBag; import org.bouncycastle.asn1.pkcs.EncryptedPrivateKeyInfo; import org.bouncycastle.asn1.pkcs.PKCSObjectIdentifiers; import org.bouncycastle.asn1.pkcs.PrivateKeyInfo; import org.bouncycastle.asn1.pkcs.SafeBag; import org.bouncycastle.asn1.x509.Certificate; import org.bouncycastle.asn1.x509.CertificateList; import org.bouncycastle.cert.X509CRLHolder; import org.bouncycastle.cert.X509CertificateHolder; public class PKCS12SafeBag { public static final ASN1ObjectIdentifier friendlyNameAttribute = PKCSObjectIdentifiers.pkcs_9_at_friendlyName; public static final ASN1ObjectIdentifier localKeyIdAttribute = PKCSObjectIdentifiers.pkcs_9_at_localKeyId; private SafeBag safeBag; public PKCS12SafeBag(SafeBag safeBag) { this.safeBag = safeBag; } /** * Return the underlying ASN.1 structure for this safe bag. * * @return a SafeBag */ public SafeBag toASN1Structure() { return safeBag; } /** * Return the BagId giving the type of content in the bag. * * @return the bagId */ public ASN1ObjectIdentifier getType() { return safeBag.getBagId(); } public Attribute[] getAttributes() { ASN1Set attrs = safeBag.getBagAttributes(); if (attrs == null) { return null; } Attribute[] attributes = new Attribute[attrs.size()]; for (int i = 0; i != attrs.size(); i++) { attributes[i] = Attribute.getInstance(attrs.getObjectAt(i)); } return attributes; } public Object getBagValue() { if (getType().equals(PKCSObjectIdentifiers.pkcs8ShroudedKeyBag)) { return new PKCS8EncryptedPrivateKeyInfo(EncryptedPrivateKeyInfo.getInstance(safeBag.getBagValue())); } if (getType().equals(PKCSObjectIdentifiers.certBag)) { CertBag certBag = CertBag.getInstance(safeBag.getBagValue()); return new X509CertificateHolder(Certificate.getInstance(ASN1OctetString.getInstance(certBag.getCertValue()).getOctets())); } if (getType().equals(PKCSObjectIdentifiers.keyBag)) { return PrivateKeyInfo.getInstance(safeBag.getBagValue()); } if (getType().equals(PKCSObjectIdentifiers.crlBag)) { CRLBag crlBag = CRLBag.getInstance(safeBag.getBagValue()); return new X509CRLHolder(CertificateList.getInstance(ASN1OctetString.getInstance(crlBag.getCRLValue()).getOctets())); } return safeBag.getBagValue(); } } bouncycastle-1.49.orig/src/org/bouncycastle/pkcs/package.html0000644000175000017500000000043511730510110023712 0ustar ebourgebourg Basic support package for handling and creating PKCS#10 certification requests, PKCS#8 encrypted keys and PKCS#12 keys stores. bouncycastle-1.49.orig/src/org/bouncycastle/jce/0000755000175000017500000000000012152033551021240 5ustar ebourgebourgbouncycastle-1.49.orig/src/org/bouncycastle/jce/ECPointUtil.java0000644000175000017500000000314510407440305024245 0ustar ebourgebourgpackage org.bouncycastle.jce; import java.security.spec.ECFieldF2m; import java.security.spec.ECFieldFp; import java.security.spec.ECPoint; import java.security.spec.EllipticCurve; import org.bouncycastle.math.ec.ECCurve; /** * Utility class for handling EC point decoding. */ public class ECPointUtil { /** * Decode a point on this curve which has been encoded using point * compression (X9.62 s 4.2.1 and 4.2.2) or regular encoding. * * @param curve * The elliptic curve. * @param encoded * The encoded point. * @return the decoded point. */ public static ECPoint decodePoint( EllipticCurve curve, byte[] encoded) { ECCurve c = null; if (curve.getField() instanceof ECFieldFp) { c = new ECCurve.Fp( ((ECFieldFp)curve.getField()).getP(), curve.getA(), curve.getB()); } else { int k[] = ((ECFieldF2m)curve.getField()).getMidTermsOfReductionPolynomial(); if (k.length == 3) { c = new ECCurve.F2m( ((ECFieldF2m)curve.getField()).getM(), k[2], k[1], k[0], curve.getA(), curve.getB()); } else { c = new ECCurve.F2m( ((ECFieldF2m)curve.getField()).getM(), k[0], curve.getA(), curve.getB()); } } org.bouncycastle.math.ec.ECPoint p = c.decodePoint(encoded); return new ECPoint(p.getX().toBigInteger(), p.getY().toBigInteger()); } } bouncycastle-1.49.orig/src/org/bouncycastle/jce/provider/0000755000175000017500000000000012152033551023072 5ustar ebourgebourgbouncycastle-1.49.orig/src/org/bouncycastle/jce/provider/JCEElGamalPublicKey.java0000644000175000017500000000756511640213543027410 0ustar ebourgebourgpackage org.bouncycastle.jce.provider; import java.io.IOException; import java.io.ObjectInputStream; import java.io.ObjectOutputStream; import java.math.BigInteger; import javax.crypto.interfaces.DHPublicKey; import javax.crypto.spec.DHParameterSpec; import javax.crypto.spec.DHPublicKeySpec; import org.bouncycastle.asn1.ASN1Sequence; import org.bouncycastle.asn1.DERInteger; import org.bouncycastle.asn1.oiw.ElGamalParameter; import org.bouncycastle.asn1.oiw.OIWObjectIdentifiers; import org.bouncycastle.asn1.x509.AlgorithmIdentifier; import org.bouncycastle.asn1.x509.SubjectPublicKeyInfo; import org.bouncycastle.crypto.params.ElGamalPublicKeyParameters; import org.bouncycastle.jcajce.provider.asymmetric.util.KeyUtil; import org.bouncycastle.jce.interfaces.ElGamalPublicKey; import org.bouncycastle.jce.spec.ElGamalParameterSpec; import org.bouncycastle.jce.spec.ElGamalPublicKeySpec; public class JCEElGamalPublicKey implements ElGamalPublicKey, DHPublicKey { static final long serialVersionUID = 8712728417091216948L; private BigInteger y; private ElGamalParameterSpec elSpec; JCEElGamalPublicKey( ElGamalPublicKeySpec spec) { this.y = spec.getY(); this.elSpec = new ElGamalParameterSpec(spec.getParams().getP(), spec.getParams().getG()); } JCEElGamalPublicKey( DHPublicKeySpec spec) { this.y = spec.getY(); this.elSpec = new ElGamalParameterSpec(spec.getP(), spec.getG()); } JCEElGamalPublicKey( ElGamalPublicKey key) { this.y = key.getY(); this.elSpec = key.getParameters(); } JCEElGamalPublicKey( DHPublicKey key) { this.y = key.getY(); this.elSpec = new ElGamalParameterSpec(key.getParams().getP(), key.getParams().getG()); } JCEElGamalPublicKey( ElGamalPublicKeyParameters params) { this.y = params.getY(); this.elSpec = new ElGamalParameterSpec(params.getParameters().getP(), params.getParameters().getG()); } JCEElGamalPublicKey( BigInteger y, ElGamalParameterSpec elSpec) { this.y = y; this.elSpec = elSpec; } JCEElGamalPublicKey( SubjectPublicKeyInfo info) { ElGamalParameter params = new ElGamalParameter((ASN1Sequence)info.getAlgorithmId().getParameters()); DERInteger derY = null; try { derY = (DERInteger)info.parsePublicKey(); } catch (IOException e) { throw new IllegalArgumentException("invalid info structure in DSA public key"); } this.y = derY.getValue(); this.elSpec = new ElGamalParameterSpec(params.getP(), params.getG()); } public String getAlgorithm() { return "ElGamal"; } public String getFormat() { return "X.509"; } public byte[] getEncoded() { return KeyUtil.getEncodedSubjectPublicKeyInfo(new AlgorithmIdentifier(OIWObjectIdentifiers.elGamalAlgorithm, new ElGamalParameter(elSpec.getP(), elSpec.getG())), new DERInteger(y)); } public ElGamalParameterSpec getParameters() { return elSpec; } public DHParameterSpec getParams() { return new DHParameterSpec(elSpec.getP(), elSpec.getG()); } public BigInteger getY() { return y; } private void readObject( ObjectInputStream in) throws IOException, ClassNotFoundException { this.y = (BigInteger)in.readObject(); this.elSpec = new ElGamalParameterSpec((BigInteger)in.readObject(), (BigInteger)in.readObject()); } private void writeObject( ObjectOutputStream out) throws IOException { out.writeObject(this.getY()); out.writeObject(elSpec.getP()); out.writeObject(elSpec.getG()); } } bouncycastle-1.49.orig/src/org/bouncycastle/jce/provider/JCEDHPrivateKey.java0000644000175000017500000001233511736773417026605 0ustar ebourgebourgpackage org.bouncycastle.jce.provider; import java.io.IOException; import java.io.ObjectInputStream; import java.io.ObjectOutputStream; import java.math.BigInteger; import java.util.Enumeration; import javax.crypto.interfaces.DHPrivateKey; import javax.crypto.spec.DHParameterSpec; import javax.crypto.spec.DHPrivateKeySpec; import org.bouncycastle.asn1.ASN1Encodable; import org.bouncycastle.asn1.ASN1Encoding; import org.bouncycastle.asn1.ASN1ObjectIdentifier; import org.bouncycastle.asn1.ASN1Sequence; import org.bouncycastle.asn1.DERInteger; import org.bouncycastle.asn1.DERObjectIdentifier; import org.bouncycastle.asn1.pkcs.DHParameter; import org.bouncycastle.asn1.pkcs.PKCSObjectIdentifiers; import org.bouncycastle.asn1.pkcs.PrivateKeyInfo; import org.bouncycastle.asn1.x509.AlgorithmIdentifier; import org.bouncycastle.asn1.x9.DHDomainParameters; import org.bouncycastle.asn1.x9.X9ObjectIdentifiers; import org.bouncycastle.crypto.params.DHPrivateKeyParameters; import org.bouncycastle.jcajce.provider.asymmetric.util.PKCS12BagAttributeCarrierImpl; import org.bouncycastle.jce.interfaces.PKCS12BagAttributeCarrier; public class JCEDHPrivateKey implements DHPrivateKey, PKCS12BagAttributeCarrier { static final long serialVersionUID = 311058815616901812L; BigInteger x; private DHParameterSpec dhSpec; private PrivateKeyInfo info; private PKCS12BagAttributeCarrier attrCarrier = new PKCS12BagAttributeCarrierImpl(); protected JCEDHPrivateKey() { } JCEDHPrivateKey( DHPrivateKey key) { this.x = key.getX(); this.dhSpec = key.getParams(); } JCEDHPrivateKey( DHPrivateKeySpec spec) { this.x = spec.getX(); this.dhSpec = new DHParameterSpec(spec.getP(), spec.getG()); } JCEDHPrivateKey( PrivateKeyInfo info) throws IOException { ASN1Sequence seq = ASN1Sequence.getInstance(info.getAlgorithmId().getParameters()); DERInteger derX = DERInteger.getInstance(info.parsePrivateKey()); DERObjectIdentifier id = info.getAlgorithmId().getAlgorithm(); this.info = info; this.x = derX.getValue(); if (id.equals(PKCSObjectIdentifiers.dhKeyAgreement)) { DHParameter params = DHParameter.getInstance(seq); if (params.getL() != null) { this.dhSpec = new DHParameterSpec(params.getP(), params.getG(), params.getL().intValue()); } else { this.dhSpec = new DHParameterSpec(params.getP(), params.getG()); } } else if (id.equals(X9ObjectIdentifiers.dhpublicnumber)) { DHDomainParameters params = DHDomainParameters.getInstance(seq); this.dhSpec = new DHParameterSpec(params.getP().getValue(), params.getG().getValue()); } else { throw new IllegalArgumentException("unknown algorithm type: " + id); } } JCEDHPrivateKey( DHPrivateKeyParameters params) { this.x = params.getX(); this.dhSpec = new DHParameterSpec(params.getParameters().getP(), params.getParameters().getG(), params.getParameters().getL()); } public String getAlgorithm() { return "DH"; } /** * return the encoding format we produce in getEncoded(). * * @return the string "PKCS#8" */ public String getFormat() { return "PKCS#8"; } /** * Return a PKCS8 representation of the key. The sequence returned * represents a full PrivateKeyInfo object. * * @return a PKCS8 representation of the key. */ public byte[] getEncoded() { try { if (info != null) { return info.getEncoded(ASN1Encoding.DER); } PrivateKeyInfo info = new PrivateKeyInfo(new AlgorithmIdentifier(PKCSObjectIdentifiers.dhKeyAgreement, new DHParameter(dhSpec.getP(), dhSpec.getG(), dhSpec.getL())), new DERInteger(getX())); return info.getEncoded(ASN1Encoding.DER); } catch (IOException e) { return null; } } public DHParameterSpec getParams() { return dhSpec; } public BigInteger getX() { return x; } private void readObject( ObjectInputStream in) throws IOException, ClassNotFoundException { x = (BigInteger)in.readObject(); this.dhSpec = new DHParameterSpec((BigInteger)in.readObject(), (BigInteger)in.readObject(), in.readInt()); } private void writeObject( ObjectOutputStream out) throws IOException { out.writeObject(this.getX()); out.writeObject(dhSpec.getP()); out.writeObject(dhSpec.getG()); out.writeInt(dhSpec.getL()); } public void setBagAttribute( ASN1ObjectIdentifier oid, ASN1Encodable attribute) { attrCarrier.setBagAttribute(oid, attribute); } public ASN1Encodable getBagAttribute( ASN1ObjectIdentifier oid) { return attrCarrier.getBagAttribute(oid); } public Enumeration getBagAttributeKeys() { return attrCarrier.getBagAttributeKeys(); } } bouncycastle-1.49.orig/src/org/bouncycastle/jce/provider/JCERSAPrivateCrtKey.java0000644000175000017500000001634612103437526027401 0ustar ebourgebourgpackage org.bouncycastle.jce.provider; import java.io.IOException; import java.math.BigInteger; import java.security.interfaces.RSAPrivateCrtKey; import java.security.spec.RSAPrivateCrtKeySpec; import org.bouncycastle.asn1.DERNull; import org.bouncycastle.asn1.pkcs.PKCSObjectIdentifiers; import org.bouncycastle.asn1.pkcs.PrivateKeyInfo; import org.bouncycastle.asn1.pkcs.RSAPrivateKey; import org.bouncycastle.asn1.x509.AlgorithmIdentifier; import org.bouncycastle.crypto.params.RSAPrivateCrtKeyParameters; import org.bouncycastle.jcajce.provider.asymmetric.util.KeyUtil; /** * A provider representation for a RSA private key, with CRT factors included. */ public class JCERSAPrivateCrtKey extends JCERSAPrivateKey implements RSAPrivateCrtKey { static final long serialVersionUID = 7834723820638524718L; private BigInteger publicExponent; private BigInteger primeP; private BigInteger primeQ; private BigInteger primeExponentP; private BigInteger primeExponentQ; private BigInteger crtCoefficient; /** * construct a private key from it's org.bouncycastle.crypto equivalent. * * @param key the parameters object representing the private key. */ JCERSAPrivateCrtKey( RSAPrivateCrtKeyParameters key) { super(key); this.publicExponent = key.getPublicExponent(); this.primeP = key.getP(); this.primeQ = key.getQ(); this.primeExponentP = key.getDP(); this.primeExponentQ = key.getDQ(); this.crtCoefficient = key.getQInv(); } /** * construct a private key from an RSAPrivateCrtKeySpec * * @param spec the spec to be used in construction. */ JCERSAPrivateCrtKey( RSAPrivateCrtKeySpec spec) { this.modulus = spec.getModulus(); this.publicExponent = spec.getPublicExponent(); this.privateExponent = spec.getPrivateExponent(); this.primeP = spec.getPrimeP(); this.primeQ = spec.getPrimeQ(); this.primeExponentP = spec.getPrimeExponentP(); this.primeExponentQ = spec.getPrimeExponentQ(); this.crtCoefficient = spec.getCrtCoefficient(); } /** * construct a private key from another RSAPrivateCrtKey. * * @param key the object implementing the RSAPrivateCrtKey interface. */ JCERSAPrivateCrtKey( RSAPrivateCrtKey key) { this.modulus = key.getModulus(); this.publicExponent = key.getPublicExponent(); this.privateExponent = key.getPrivateExponent(); this.primeP = key.getPrimeP(); this.primeQ = key.getPrimeQ(); this.primeExponentP = key.getPrimeExponentP(); this.primeExponentQ = key.getPrimeExponentQ(); this.crtCoefficient = key.getCrtCoefficient(); } /** * construct an RSA key from a private key info object. */ JCERSAPrivateCrtKey( PrivateKeyInfo info) throws IOException { this(org.bouncycastle.asn1.pkcs.RSAPrivateKey.getInstance(info.parsePrivateKey())); } /** * construct an RSA key from a ASN.1 RSA private key object. */ JCERSAPrivateCrtKey( RSAPrivateKey key) { this.modulus = key.getModulus(); this.publicExponent = key.getPublicExponent(); this.privateExponent = key.getPrivateExponent(); this.primeP = key.getPrime1(); this.primeQ = key.getPrime2(); this.primeExponentP = key.getExponent1(); this.primeExponentQ = key.getExponent2(); this.crtCoefficient = key.getCoefficient(); } /** * return the encoding format we produce in getEncoded(). * * @return the encoding format we produce in getEncoded(). */ public String getFormat() { return "PKCS#8"; } /** * Return a PKCS8 representation of the key. The sequence returned * represents a full PrivateKeyInfo object. * * @return a PKCS8 representation of the key. */ public byte[] getEncoded() { return KeyUtil.getEncodedPrivateKeyInfo(new AlgorithmIdentifier(PKCSObjectIdentifiers.rsaEncryption, DERNull.INSTANCE), new RSAPrivateKey(getModulus(), getPublicExponent(), getPrivateExponent(), getPrimeP(), getPrimeQ(), getPrimeExponentP(), getPrimeExponentQ(), getCrtCoefficient())); } /** * return the public exponent. * * @return the public exponent. */ public BigInteger getPublicExponent() { return publicExponent; } /** * return the prime P. * * @return the prime P. */ public BigInteger getPrimeP() { return primeP; } /** * return the prime Q. * * @return the prime Q. */ public BigInteger getPrimeQ() { return primeQ; } /** * return the prime exponent for P. * * @return the prime exponent for P. */ public BigInteger getPrimeExponentP() { return primeExponentP; } /** * return the prime exponent for Q. * * @return the prime exponent for Q. */ public BigInteger getPrimeExponentQ() { return primeExponentQ; } /** * return the CRT coefficient. * * @return the CRT coefficient. */ public BigInteger getCrtCoefficient() { return crtCoefficient; } public int hashCode() { return this.getModulus().hashCode() ^ this.getPublicExponent().hashCode() ^ this.getPrivateExponent().hashCode(); } public boolean equals(Object o) { if (o == this) { return true; } if (!(o instanceof RSAPrivateCrtKey)) { return false; } RSAPrivateCrtKey key = (RSAPrivateCrtKey)o; return this.getModulus().equals(key.getModulus()) && this.getPublicExponent().equals(key.getPublicExponent()) && this.getPrivateExponent().equals(key.getPrivateExponent()) && this.getPrimeP().equals(key.getPrimeP()) && this.getPrimeQ().equals(key.getPrimeQ()) && this.getPrimeExponentP().equals(key.getPrimeExponentP()) && this.getPrimeExponentQ().equals(key.getPrimeExponentQ()) && this.getCrtCoefficient().equals(key.getCrtCoefficient()); } public String toString() { StringBuffer buf = new StringBuffer(); String nl = System.getProperty("line.separator"); buf.append("RSA Private CRT Key").append(nl); buf.append(" modulus: ").append(this.getModulus().toString(16)).append(nl); buf.append(" public exponent: ").append(this.getPublicExponent().toString(16)).append(nl); buf.append(" private exponent: ").append(this.getPrivateExponent().toString(16)).append(nl); buf.append(" primeP: ").append(this.getPrimeP().toString(16)).append(nl); buf.append(" primeQ: ").append(this.getPrimeQ().toString(16)).append(nl); buf.append(" primeExponentP: ").append(this.getPrimeExponentP().toString(16)).append(nl); buf.append(" primeExponentQ: ").append(this.getPrimeExponentQ().toString(16)).append(nl); buf.append(" crtCoefficient: ").append(this.getCrtCoefficient().toString(16)).append(nl); return buf.toString(); } } bouncycastle-1.49.orig/src/org/bouncycastle/jce/provider/X509CRLObject.java0000644000175000017500000004231011737275260026107 0ustar ebourgebourgpackage org.bouncycastle.jce.provider; import java.io.IOException; import java.math.BigInteger; import java.security.InvalidKeyException; import java.security.NoSuchAlgorithmException; import java.security.NoSuchProviderException; import java.security.Principal; import java.security.PublicKey; import java.security.Signature; import java.security.SignatureException; import java.security.cert.CRLException; import java.security.cert.Certificate; import java.security.cert.CertificateEncodingException; import java.security.cert.X509CRL; import java.security.cert.X509CRLEntry; import java.security.cert.X509Certificate; import java.util.Collections; import java.util.Date; import java.util.Enumeration; import java.util.HashSet; import java.util.Iterator; import java.util.Set; import javax.security.auth.x500.X500Principal; import org.bouncycastle.asn1.ASN1Encodable; import org.bouncycastle.asn1.ASN1Encoding; import org.bouncycastle.asn1.ASN1InputStream; import org.bouncycastle.asn1.ASN1Integer; import org.bouncycastle.asn1.ASN1ObjectIdentifier; import org.bouncycastle.asn1.ASN1OctetString; import org.bouncycastle.asn1.util.ASN1Dump; import org.bouncycastle.asn1.x500.X500Name; import org.bouncycastle.asn1.x509.CRLDistPoint; import org.bouncycastle.asn1.x509.CRLNumber; import org.bouncycastle.asn1.x509.CertificateList; import org.bouncycastle.asn1.x509.Extension; import org.bouncycastle.asn1.x509.Extensions; import org.bouncycastle.asn1.x509.GeneralNames; import org.bouncycastle.asn1.x509.IssuingDistributionPoint; import org.bouncycastle.asn1.x509.TBSCertList; import org.bouncycastle.jce.X509Principal; import org.bouncycastle.util.encoders.Hex; /** * The following extensions are listed in RFC 2459 as relevant to CRLs * * Authority Key Identifier * Issuer Alternative Name * CRL Number * Delta CRL Indicator (critical) * Issuing Distribution Point (critical) */ public class X509CRLObject extends X509CRL { private CertificateList c; private String sigAlgName; private byte[] sigAlgParams; private boolean isIndirect; static boolean isIndirectCRL(X509CRL crl) throws CRLException { try { byte[] idp = crl.getExtensionValue(Extension.issuingDistributionPoint.getId()); return idp != null && IssuingDistributionPoint.getInstance(ASN1OctetString.getInstance(idp).getOctets()).isIndirectCRL(); } catch (Exception e) { throw new ExtCRLException( "Exception reading IssuingDistributionPoint", e); } } public X509CRLObject( CertificateList c) throws CRLException { this.c = c; try { this.sigAlgName = X509SignatureUtil.getSignatureName(c.getSignatureAlgorithm()); if (c.getSignatureAlgorithm().getParameters() != null) { this.sigAlgParams = ((ASN1Encodable)c.getSignatureAlgorithm().getParameters()).toASN1Primitive().getEncoded(ASN1Encoding.DER); } else { this.sigAlgParams = null; } this.isIndirect = isIndirectCRL(this); } catch (Exception e) { throw new CRLException("CRL contents invalid: " + e); } } /** * Will return true if any extensions are present and marked * as critical as we currently dont handle any extensions! */ public boolean hasUnsupportedCriticalExtension() { Set extns = getCriticalExtensionOIDs(); if (extns == null) { return false; } extns.remove(RFC3280CertPathUtilities.ISSUING_DISTRIBUTION_POINT); extns.remove(RFC3280CertPathUtilities.DELTA_CRL_INDICATOR); return !extns.isEmpty(); } private Set getExtensionOIDs(boolean critical) { if (this.getVersion() == 2) { Extensions extensions = c.getTBSCertList().getExtensions(); if (extensions != null) { Set set = new HashSet(); Enumeration e = extensions.oids(); while (e.hasMoreElements()) { ASN1ObjectIdentifier oid = (ASN1ObjectIdentifier)e.nextElement(); Extension ext = extensions.getExtension(oid); if (critical == ext.isCritical()) { set.add(oid.getId()); } } return set; } } return null; } public Set getCriticalExtensionOIDs() { return getExtensionOIDs(true); } public Set getNonCriticalExtensionOIDs() { return getExtensionOIDs(false); } public byte[] getExtensionValue(String oid) { Extensions exts = c.getTBSCertList().getExtensions(); if (exts != null) { Extension ext = exts.getExtension(new ASN1ObjectIdentifier(oid)); if (ext != null) { try { return ext.getExtnValue().getEncoded(); } catch (Exception e) { throw new IllegalStateException("error parsing " + e.toString()); } } } return null; } public byte[] getEncoded() throws CRLException { try { return c.getEncoded(ASN1Encoding.DER); } catch (IOException e) { throw new CRLException(e.toString()); } } public void verify(PublicKey key) throws CRLException, NoSuchAlgorithmException, InvalidKeyException, NoSuchProviderException, SignatureException { verify(key, BouncyCastleProvider.PROVIDER_NAME); } public void verify(PublicKey key, String sigProvider) throws CRLException, NoSuchAlgorithmException, InvalidKeyException, NoSuchProviderException, SignatureException { if (!c.getSignatureAlgorithm().equals(c.getTBSCertList().getSignature())) { throw new CRLException("Signature algorithm on CertificateList does not match TBSCertList."); } Signature sig; if (sigProvider != null) { sig = Signature.getInstance(getSigAlgName(), sigProvider); } else { sig = Signature.getInstance(getSigAlgName()); } sig.initVerify(key); sig.update(this.getTBSCertList()); if (!sig.verify(this.getSignature())) { throw new SignatureException("CRL does not verify with supplied public key."); } } public int getVersion() { return c.getVersionNumber(); } public Principal getIssuerDN() { return new X509Principal(X500Name.getInstance(c.getIssuer().toASN1Primitive())); } public X500Principal getIssuerX500Principal() { try { return new X500Principal(c.getIssuer().getEncoded()); } catch (IOException e) { throw new IllegalStateException("can't encode issuer DN"); } } public Date getThisUpdate() { return c.getThisUpdate().getDate(); } public Date getNextUpdate() { if (c.getNextUpdate() != null) { return c.getNextUpdate().getDate(); } return null; } private Set loadCRLEntries() { Set entrySet = new HashSet(); Enumeration certs = c.getRevokedCertificateEnumeration(); X500Name previousCertificateIssuer = null; // the issuer while (certs.hasMoreElements()) { TBSCertList.CRLEntry entry = (TBSCertList.CRLEntry)certs.nextElement(); X509CRLEntryObject crlEntry = new X509CRLEntryObject(entry, isIndirect, previousCertificateIssuer); entrySet.add(crlEntry); if (isIndirect && entry.hasExtensions()) { Extension currentCaName = entry.getExtensions().getExtension(Extension.certificateIssuer); if (currentCaName != null) { previousCertificateIssuer = X500Name.getInstance(GeneralNames.getInstance(currentCaName.getParsedValue()).getNames()[0].getName()); } } } return entrySet; } public X509CRLEntry getRevokedCertificate(BigInteger serialNumber) { Enumeration certs = c.getRevokedCertificateEnumeration(); X500Name previousCertificateIssuer = null; // the issuer while (certs.hasMoreElements()) { TBSCertList.CRLEntry entry = (TBSCertList.CRLEntry)certs.nextElement(); if (serialNumber.equals(entry.getUserCertificate().getValue())) { return new X509CRLEntryObject(entry, isIndirect, previousCertificateIssuer); } if (isIndirect && entry.hasExtensions()) { Extension currentCaName = entry.getExtensions().getExtension(Extension.certificateIssuer); if (currentCaName != null) { previousCertificateIssuer = X500Name.getInstance(GeneralNames.getInstance(currentCaName.getParsedValue()).getNames()[0].getName()); } } } return null; } public Set getRevokedCertificates() { Set entrySet = loadCRLEntries(); if (!entrySet.isEmpty()) { return Collections.unmodifiableSet(entrySet); } return null; } public byte[] getTBSCertList() throws CRLException { try { return c.getTBSCertList().getEncoded("DER"); } catch (IOException e) { throw new CRLException(e.toString()); } } public byte[] getSignature() { return c.getSignature().getBytes(); } public String getSigAlgName() { return sigAlgName; } public String getSigAlgOID() { return c.getSignatureAlgorithm().getAlgorithm().getId(); } public byte[] getSigAlgParams() { if (sigAlgParams != null) { byte[] tmp = new byte[sigAlgParams.length]; System.arraycopy(sigAlgParams, 0, tmp, 0, tmp.length); return tmp; } return null; } /** * Returns a string representation of this CRL. * * @return a string representation of this CRL. */ public String toString() { StringBuffer buf = new StringBuffer(); String nl = System.getProperty("line.separator"); buf.append(" Version: ").append(this.getVersion()).append( nl); buf.append(" IssuerDN: ").append(this.getIssuerDN()) .append(nl); buf.append(" This update: ").append(this.getThisUpdate()) .append(nl); buf.append(" Next update: ").append(this.getNextUpdate()) .append(nl); buf.append(" Signature Algorithm: ").append(this.getSigAlgName()) .append(nl); byte[] sig = this.getSignature(); buf.append(" Signature: ").append( new String(Hex.encode(sig, 0, 20))).append(nl); for (int i = 20; i < sig.length; i += 20) { if (i < sig.length - 20) { buf.append(" ").append( new String(Hex.encode(sig, i, 20))).append(nl); } else { buf.append(" ").append( new String(Hex.encode(sig, i, sig.length - i))).append(nl); } } Extensions extensions = c.getTBSCertList().getExtensions(); if (extensions != null) { Enumeration e = extensions.oids(); if (e.hasMoreElements()) { buf.append(" Extensions: ").append(nl); } while (e.hasMoreElements()) { ASN1ObjectIdentifier oid = (ASN1ObjectIdentifier) e.nextElement(); Extension ext = extensions.getExtension(oid); if (ext.getExtnValue() != null) { byte[] octs = ext.getExtnValue().getOctets(); ASN1InputStream dIn = new ASN1InputStream(octs); buf.append(" critical(").append( ext.isCritical()).append(") "); try { if (oid.equals(Extension.cRLNumber)) { buf.append( new CRLNumber(ASN1Integer.getInstance( dIn.readObject()).getPositiveValue())) .append(nl); } else if (oid.equals(Extension.deltaCRLIndicator)) { buf.append( "Base CRL: " + new CRLNumber(ASN1Integer.getInstance( dIn.readObject()).getPositiveValue())) .append(nl); } else if (oid .equals(Extension.issuingDistributionPoint)) { buf.append( IssuingDistributionPoint.getInstance(dIn.readObject())).append(nl); } else if (oid .equals(Extension.cRLDistributionPoints)) { buf.append( CRLDistPoint.getInstance(dIn.readObject())).append(nl); } else if (oid.equals(Extension.freshestCRL)) { buf.append( CRLDistPoint.getInstance(dIn.readObject())).append(nl); } else { buf.append(oid.getId()); buf.append(" value = ").append( ASN1Dump.dumpAsString(dIn.readObject())) .append(nl); } } catch (Exception ex) { buf.append(oid.getId()); buf.append(" value = ").append("*****").append(nl); } } else { buf.append(nl); } } } Set set = getRevokedCertificates(); if (set != null) { Iterator it = set.iterator(); while (it.hasNext()) { buf.append(it.next()); buf.append(nl); } } return buf.toString(); } /** * Checks whether the given certificate is on this CRL. * * @param cert the certificate to check for. * @return true if the given certificate is on this CRL, * false otherwise. */ public boolean isRevoked(Certificate cert) { if (!cert.getType().equals("X.509")) { throw new RuntimeException("X.509 CRL used with non X.509 Cert"); } TBSCertList.CRLEntry[] certs = c.getRevokedCertificates(); X500Name caName = c.getIssuer(); if (certs != null) { BigInteger serial = ((X509Certificate)cert).getSerialNumber(); for (int i = 0; i < certs.length; i++) { if (isIndirect && certs[i].hasExtensions()) { Extension currentCaName = certs[i].getExtensions().getExtension(Extension.certificateIssuer); if (currentCaName != null) { caName = X500Name.getInstance(GeneralNames.getInstance(currentCaName.getParsedValue()).getNames()[0].getName()); } } if (certs[i].getUserCertificate().getValue().equals(serial)) { X500Name issuer; if (cert instanceof X509Certificate) { issuer = X500Name.getInstance(((X509Certificate)cert).getIssuerX500Principal().getEncoded()); } else { try { issuer = org.bouncycastle.asn1.x509.Certificate.getInstance(cert.getEncoded()).getIssuer(); } catch (CertificateEncodingException e) { throw new RuntimeException("Cannot process certificate"); } } if (!caName.equals(issuer)) { return false; } return true; } } } return false; } } bouncycastle-1.49.orig/src/org/bouncycastle/jce/provider/X509StoreLDAPAttrCerts.java0000644000175000017500000000522111624652552027727 0ustar ebourgebourgpackage org.bouncycastle.jce.provider; import java.util.Collection; import java.util.Collections; import java.util.HashSet; import java.util.Set; import org.bouncycastle.jce.X509LDAPCertStoreParameters; import org.bouncycastle.util.Selector; import org.bouncycastle.util.StoreException; import org.bouncycastle.x509.X509AttributeCertStoreSelector; import org.bouncycastle.x509.X509StoreParameters; import org.bouncycastle.x509.X509StoreSpi; import org.bouncycastle.x509.util.LDAPStoreHelper; /** * A SPI implementation of Bouncy Castle X509Store for getting * attribute certificates from an LDAP directory. * * @see org.bouncycastle.x509.X509Store */ public class X509StoreLDAPAttrCerts extends X509StoreSpi { private LDAPStoreHelper helper; public X509StoreLDAPAttrCerts() { } /** * Initializes this LDAP attribute cert store implementation. * * @param parameters X509LDAPCertStoreParameters. * @throws IllegalArgumentException if params is not an instance of * X509LDAPCertStoreParameters. */ public void engineInit(X509StoreParameters parameters) { if (!(parameters instanceof X509LDAPCertStoreParameters)) { throw new IllegalArgumentException( "Initialization parameters must be an instance of " + X509LDAPCertStoreParameters.class.getName() + "."); } helper = new LDAPStoreHelper((X509LDAPCertStoreParameters)parameters); } /** * Returns a collection of matching attribute certificates from the LDAP * location. *

    * The selector must be a of type * X509AttributeCertStoreSelector. If it is not an empty * collection is returned. *

    *

    * The subject and the serial number should be reasonable criterias for a * selector. * * @param selector The selector to use for finding. * @return A collection with the matches. * @throws StoreException if an exception occurs while searching. */ public Collection engineGetMatches(Selector selector) throws StoreException { if (!(selector instanceof X509AttributeCertStoreSelector)) { return Collections.EMPTY_SET; } X509AttributeCertStoreSelector xselector = (X509AttributeCertStoreSelector)selector; Set set = new HashSet(); set.addAll(helper.getAACertificates(xselector)); set.addAll(helper.getAttributeCertificateAttributes(xselector)); set.addAll(helper.getAttributeDescriptorCertificates(xselector)); return set; } } bouncycastle-1.49.orig/src/org/bouncycastle/jce/provider/BrokenPBE.java0000644000175000017500000003235711624640051025520 0ustar ebourgebourgpackage org.bouncycastle.jce.provider; import java.security.spec.AlgorithmParameterSpec; import javax.crypto.spec.PBEParameterSpec; import org.bouncycastle.crypto.CipherParameters; import org.bouncycastle.crypto.Digest; import org.bouncycastle.crypto.PBEParametersGenerator; import org.bouncycastle.crypto.digests.MD5Digest; import org.bouncycastle.crypto.digests.RIPEMD160Digest; import org.bouncycastle.crypto.digests.SHA1Digest; import org.bouncycastle.crypto.generators.PKCS12ParametersGenerator; import org.bouncycastle.crypto.generators.PKCS5S1ParametersGenerator; import org.bouncycastle.crypto.generators.PKCS5S2ParametersGenerator; import org.bouncycastle.crypto.params.KeyParameter; import org.bouncycastle.crypto.params.ParametersWithIV; import org.bouncycastle.jcajce.provider.symmetric.util.BCPBEKey; /** * Generator for PBE derived keys and ivs as defined by PKCS 12 V1.0, * with a bug affecting 180 bit plus keys - this class is only here to * allow smooth migration of the version 0 keystore to version 1. Don't * use it (it won't be staying around). *

    * The document this implementation is based on can be found at * * RSA's PKCS12 Page */ class OldPKCS12ParametersGenerator extends PBEParametersGenerator { public static final int KEY_MATERIAL = 1; public static final int IV_MATERIAL = 2; public static final int MAC_MATERIAL = 3; private Digest digest; private int u; private int v; /** * Construct a PKCS 12 Parameters generator. This constructor will * accept MD5, SHA1, and RIPEMD160. * * @param digest the digest to be used as the source of derived keys. * @exception IllegalArgumentException if an unknown digest is passed in. */ public OldPKCS12ParametersGenerator( Digest digest) { this.digest = digest; if (digest instanceof MD5Digest) { u = 128 / 8; v = 512 / 8; } else if (digest instanceof SHA1Digest) { u = 160 / 8; v = 512 / 8; } else if (digest instanceof RIPEMD160Digest) { u = 160 / 8; v = 512 / 8; } else { throw new IllegalArgumentException("Digest " + digest.getAlgorithmName() + " unsupported"); } } /** * add a + b + 1, returning the result in a. The a value is treated * as a BigInteger of length (b.length * 8) bits. The result is * modulo 2^b.length in case of overflow. */ private void adjust( byte[] a, int aOff, byte[] b) { int x = (b[b.length - 1] & 0xff) + (a[aOff + b.length - 1] & 0xff) + 1; a[aOff + b.length - 1] = (byte)x; x >>>= 8; for (int i = b.length - 2; i >= 0; i--) { x += (b[i] & 0xff) + (a[aOff + i] & 0xff); a[aOff + i] = (byte)x; x >>>= 8; } } /** * generation of a derived key ala PKCS12 V1.0. */ private byte[] generateDerivedKey( int idByte, int n) { byte[] D = new byte[v]; byte[] dKey = new byte[n]; for (int i = 0; i != D.length; i++) { D[i] = (byte)idByte; } byte[] S; if ((salt != null) && (salt.length != 0)) { S = new byte[v * ((salt.length + v - 1) / v)]; for (int i = 0; i != S.length; i++) { S[i] = salt[i % salt.length]; } } else { S = new byte[0]; } byte[] P; if ((password != null) && (password.length != 0)) { P = new byte[v * ((password.length + v - 1) / v)]; for (int i = 0; i != P.length; i++) { P[i] = password[i % password.length]; } } else { P = new byte[0]; } byte[] I = new byte[S.length + P.length]; System.arraycopy(S, 0, I, 0, S.length); System.arraycopy(P, 0, I, S.length, P.length); byte[] B = new byte[v]; int c = (n + u - 1) / u; for (int i = 1; i <= c; i++) { byte[] A = new byte[u]; digest.update(D, 0, D.length); digest.update(I, 0, I.length); digest.doFinal(A, 0); for (int j = 1; j != iterationCount; j++) { digest.update(A, 0, A.length); digest.doFinal(A, 0); } for (int j = 0; j != B.length; j++) { B[i] = A[j % A.length]; } for (int j = 0; j != I.length / v; j++) { adjust(I, j * v, B); } if (i == c) { System.arraycopy(A, 0, dKey, (i - 1) * u, dKey.length - ((i - 1) * u)); } else { System.arraycopy(A, 0, dKey, (i - 1) * u, A.length); } } return dKey; } /** * Generate a key parameter derived from the password, salt, and iteration * count we are currently initialised with. * * @param keySize the size of the key we want (in bits) * @return a KeyParameter object. */ public CipherParameters generateDerivedParameters( int keySize) { keySize = keySize / 8; byte[] dKey = generateDerivedKey(KEY_MATERIAL, keySize); return new KeyParameter(dKey, 0, keySize); } /** * Generate a key with initialisation vector parameter derived from * the password, salt, and iteration count we are currently initialised * with. * * @param keySize the size of the key we want (in bits) * @param ivSize the size of the iv we want (in bits) * @return a ParametersWithIV object. */ public CipherParameters generateDerivedParameters( int keySize, int ivSize) { keySize = keySize / 8; ivSize = ivSize / 8; byte[] dKey = generateDerivedKey(KEY_MATERIAL, keySize); byte[] iv = generateDerivedKey(IV_MATERIAL, ivSize); return new ParametersWithIV(new KeyParameter(dKey, 0, keySize), iv, 0, ivSize); } /** * Generate a key parameter for use with a MAC derived from the password, * salt, and iteration count we are currently initialised with. * * @param keySize the size of the key we want (in bits) * @return a KeyParameter object. */ public CipherParameters generateDerivedMacParameters( int keySize) { keySize = keySize / 8; byte[] dKey = generateDerivedKey(MAC_MATERIAL, keySize); return new KeyParameter(dKey, 0, keySize); } } public interface BrokenPBE { // // PBE Based encryption constants - by default we do PKCS12 with SHA-1 // static final int MD5 = 0; static final int SHA1 = 1; static final int RIPEMD160 = 2; static final int PKCS5S1 = 0; static final int PKCS5S2 = 1; static final int PKCS12 = 2; static final int OLD_PKCS12 = 3; /** * uses the appropriate mixer to generate the key and IV if neccessary. */ static class Util { /** * a faulty parity routine... * * @param bytes the byte array to set the parity on. */ static private void setOddParity( byte[] bytes) { for (int i = 0; i < bytes.length; i++) { int b = bytes[i]; bytes[i] = (byte)((b & 0xfe) | (((b >> 1) ^ (b >> 2) ^ (b >> 3) ^ (b >> 4) ^ (b >> 5) ^ (b >> 6) ^ (b >> 7)) ^ 0x01)); } } static private PBEParametersGenerator makePBEGenerator( int type, int hash) { PBEParametersGenerator generator; if (type == PKCS5S1) { switch (hash) { case MD5: generator = new PKCS5S1ParametersGenerator(new MD5Digest()); break; case SHA1: generator = new PKCS5S1ParametersGenerator(new SHA1Digest()); break; default: throw new IllegalStateException("PKCS5 scheme 1 only supports only MD5 and SHA1."); } } else if (type == PKCS5S2) { generator = new PKCS5S2ParametersGenerator(); } else if (type == OLD_PKCS12) { switch (hash) { case MD5: generator = new OldPKCS12ParametersGenerator(new MD5Digest()); break; case SHA1: generator = new OldPKCS12ParametersGenerator(new SHA1Digest()); break; case RIPEMD160: generator = new OldPKCS12ParametersGenerator(new RIPEMD160Digest()); break; default: throw new IllegalStateException("unknown digest scheme for PBE encryption."); } } else { switch (hash) { case MD5: generator = new PKCS12ParametersGenerator(new MD5Digest()); break; case SHA1: generator = new PKCS12ParametersGenerator(new SHA1Digest()); break; case RIPEMD160: generator = new PKCS12ParametersGenerator(new RIPEMD160Digest()); break; default: throw new IllegalStateException("unknown digest scheme for PBE encryption."); } } return generator; } /** * construct a key and iv (if neccessary) suitable for use with a * Cipher. */ static CipherParameters makePBEParameters( BCPBEKey pbeKey, AlgorithmParameterSpec spec, int type, int hash, String targetAlgorithm, int keySize, int ivSize) { if ((spec == null) || !(spec instanceof PBEParameterSpec)) { throw new IllegalArgumentException("Need a PBEParameter spec with a PBE key."); } PBEParameterSpec pbeParam = (PBEParameterSpec)spec; PBEParametersGenerator generator = makePBEGenerator(type, hash); byte[] key = pbeKey.getEncoded(); CipherParameters param; generator.init(key, pbeParam.getSalt(), pbeParam.getIterationCount()); if (ivSize != 0) { param = generator.generateDerivedParameters(keySize, ivSize); } else { param = generator.generateDerivedParameters(keySize); } if (targetAlgorithm.startsWith("DES")) { if (param instanceof ParametersWithIV) { KeyParameter kParam = (KeyParameter)((ParametersWithIV)param).getParameters(); setOddParity(kParam.getKey()); } else { KeyParameter kParam = (KeyParameter)param; setOddParity(kParam.getKey()); } } for (int i = 0; i != key.length; i++) { key[i] = 0; } return param; } /** * generate a PBE based key suitable for a MAC algorithm, the * key size is chosen according the MAC size, or the hashing algorithm, * whichever is greater. */ static CipherParameters makePBEMacParameters( BCPBEKey pbeKey, AlgorithmParameterSpec spec, int type, int hash, int keySize) { if ((spec == null) || !(spec instanceof PBEParameterSpec)) { throw new IllegalArgumentException("Need a PBEParameter spec with a PBE key."); } PBEParameterSpec pbeParam = (PBEParameterSpec)spec; PBEParametersGenerator generator = makePBEGenerator(type, hash); byte[] key = pbeKey.getEncoded(); CipherParameters param; generator.init(key, pbeParam.getSalt(), pbeParam.getIterationCount()); param = generator.generateDerivedMacParameters(keySize); for (int i = 0; i != key.length; i++) { key[i] = 0; } return param; } } } bouncycastle-1.49.orig/src/org/bouncycastle/jce/provider/BouncyCastleProviderConfiguration.java0000644000175000017500000001247612110037231032576 0ustar ebourgebourgpackage org.bouncycastle.jce.provider; import java.security.Permission; import javax.crypto.spec.DHParameterSpec; import org.bouncycastle.jcajce.provider.asymmetric.util.EC5Util; import org.bouncycastle.jcajce.provider.config.ConfigurableProvider; import org.bouncycastle.jcajce.provider.config.ProviderConfiguration; import org.bouncycastle.jcajce.provider.config.ProviderConfigurationPermission; import org.bouncycastle.jce.spec.ECParameterSpec; class BouncyCastleProviderConfiguration implements ProviderConfiguration { private static Permission BC_EC_LOCAL_PERMISSION = new ProviderConfigurationPermission( BouncyCastleProvider.PROVIDER_NAME, ConfigurableProvider.THREAD_LOCAL_EC_IMPLICITLY_CA); private static Permission BC_EC_PERMISSION = new ProviderConfigurationPermission( BouncyCastleProvider.PROVIDER_NAME, ConfigurableProvider.EC_IMPLICITLY_CA); private static Permission BC_DH_LOCAL_PERMISSION = new ProviderConfigurationPermission( BouncyCastleProvider.PROVIDER_NAME, ConfigurableProvider.THREAD_LOCAL_DH_DEFAULT_PARAMS); private static Permission BC_DH_PERMISSION = new ProviderConfigurationPermission( BouncyCastleProvider.PROVIDER_NAME, ConfigurableProvider.DH_DEFAULT_PARAMS); private ThreadLocal ecThreadSpec = new ThreadLocal(); private ThreadLocal dhThreadSpec = new ThreadLocal(); private volatile ECParameterSpec ecImplicitCaParams; private volatile Object dhDefaultParams; void setParameter(String parameterName, Object parameter) { SecurityManager securityManager = System.getSecurityManager(); if (parameterName.equals(ConfigurableProvider.THREAD_LOCAL_EC_IMPLICITLY_CA)) { ECParameterSpec curveSpec; if (securityManager != null) { securityManager.checkPermission(BC_EC_LOCAL_PERMISSION); } if (parameter instanceof ECParameterSpec || parameter == null) { curveSpec = (ECParameterSpec)parameter; } else // assume java.security.spec { curveSpec = EC5Util.convertSpec((java.security.spec.ECParameterSpec)parameter, false); } if (curveSpec == null) { ecThreadSpec.remove(); } else { ecThreadSpec.set(curveSpec); } } else if (parameterName.equals(ConfigurableProvider.EC_IMPLICITLY_CA)) { if (securityManager != null) { securityManager.checkPermission(BC_EC_PERMISSION); } if (parameter instanceof ECParameterSpec || parameter == null) { ecImplicitCaParams = (ECParameterSpec)parameter; } else // assume java.security.spec { ecImplicitCaParams = EC5Util.convertSpec((java.security.spec.ECParameterSpec)parameter, false); } } else if (parameterName.equals(ConfigurableProvider.THREAD_LOCAL_DH_DEFAULT_PARAMS)) { Object dhSpec; if (securityManager != null) { securityManager.checkPermission(BC_DH_LOCAL_PERMISSION); } if (parameter instanceof DHParameterSpec || parameter instanceof DHParameterSpec[] || parameter == null) { dhSpec = parameter; } else { throw new IllegalArgumentException("not a valid DHParameterSpec"); } if (dhSpec == null) { dhThreadSpec.remove(); } else { dhThreadSpec.set(dhSpec); } } else if (parameterName.equals(ConfigurableProvider.DH_DEFAULT_PARAMS)) { if (securityManager != null) { securityManager.checkPermission(BC_DH_PERMISSION); } if (parameter instanceof DHParameterSpec || parameter instanceof DHParameterSpec[] || parameter == null) { dhDefaultParams = parameter; } else { throw new IllegalArgumentException("not a valid DHParameterSpec or DHParameterSpec[]"); } } } public ECParameterSpec getEcImplicitlyCa() { ECParameterSpec spec = (ECParameterSpec)ecThreadSpec.get(); if (spec != null) { return spec; } return ecImplicitCaParams; } public DHParameterSpec getDHDefaultParameters(int keySize) { Object params = dhThreadSpec.get(); if (params == null) { params = dhDefaultParams; } if (params instanceof DHParameterSpec) { DHParameterSpec spec = (DHParameterSpec)params; if (spec.getP().bitLength() == keySize) { return spec; } } else if (params instanceof DHParameterSpec[]) { DHParameterSpec[] specs = (DHParameterSpec[])params; for (int i = 0; i != specs.length; i++) { if (specs[i].getP().bitLength() == keySize) { return specs[i]; } } } return null; } } bouncycastle-1.49.orig/src/org/bouncycastle/jce/provider/PKIXPolicyNode.java0000644000175000017500000000771411624640052026512 0ustar ebourgebourgpackage org.bouncycastle.jce.provider; import java.security.cert.PolicyNode; import java.util.ArrayList; import java.util.HashSet; import java.util.Iterator; import java.util.List; import java.util.Set; public class PKIXPolicyNode implements PolicyNode { protected List children; protected int depth; protected Set expectedPolicies; protected PolicyNode parent; protected Set policyQualifiers; protected String validPolicy; protected boolean critical; /* * * CONSTRUCTORS * */ public PKIXPolicyNode( List _children, int _depth, Set _expectedPolicies, PolicyNode _parent, Set _policyQualifiers, String _validPolicy, boolean _critical) { children = _children; depth = _depth; expectedPolicies = _expectedPolicies; parent = _parent; policyQualifiers = _policyQualifiers; validPolicy = _validPolicy; critical = _critical; } public void addChild( PKIXPolicyNode _child) { children.add(_child); _child.setParent(this); } public Iterator getChildren() { return children.iterator(); } public int getDepth() { return depth; } public Set getExpectedPolicies() { return expectedPolicies; } public PolicyNode getParent() { return parent; } public Set getPolicyQualifiers() { return policyQualifiers; } public String getValidPolicy() { return validPolicy; } public boolean hasChildren() { return !children.isEmpty(); } public boolean isCritical() { return critical; } public void removeChild(PKIXPolicyNode _child) { children.remove(_child); } public void setCritical(boolean _critical) { critical = _critical; } public void setParent(PKIXPolicyNode _parent) { parent = _parent; } public String toString() { return toString(""); } public String toString(String _indent) { StringBuffer _buf = new StringBuffer(); _buf.append(_indent); _buf.append(validPolicy); _buf.append(" {\n"); for(int i = 0; i < children.size(); i++) { _buf.append(((PKIXPolicyNode)children.get(i)).toString(_indent + " ")); } _buf.append(_indent); _buf.append("}\n"); return _buf.toString(); } public Object clone() { return copy(); } public PKIXPolicyNode copy() { Set _expectedPolicies = new HashSet(); Iterator _iter = expectedPolicies.iterator(); while (_iter.hasNext()) { _expectedPolicies.add(new String((String)_iter.next())); } Set _policyQualifiers = new HashSet(); _iter = policyQualifiers.iterator(); while (_iter.hasNext()) { _policyQualifiers.add(new String((String)_iter.next())); } PKIXPolicyNode _node = new PKIXPolicyNode(new ArrayList(), depth, _expectedPolicies, null, _policyQualifiers, new String(validPolicy), critical); _iter = children.iterator(); while (_iter.hasNext()) { PKIXPolicyNode _child = ((PKIXPolicyNode)_iter.next()).copy(); _child.setParent(_node); _node.addChild(_child); } return _node; } } bouncycastle-1.49.orig/src/org/bouncycastle/jce/provider/MultiCertStoreSpi.java0000644000175000017500000000475111624652552027360 0ustar ebourgebourgpackage org.bouncycastle.jce.provider; import java.security.InvalidAlgorithmParameterException; import java.security.cert.CRLSelector; import java.security.cert.CertSelector; import java.security.cert.CertStore; import java.security.cert.CertStoreException; import java.security.cert.CertStoreParameters; import java.security.cert.CertStoreSpi; import java.util.ArrayList; import java.util.Collection; import java.util.Collections; import java.util.Iterator; import java.util.List; import org.bouncycastle.jce.MultiCertStoreParameters; public class MultiCertStoreSpi extends CertStoreSpi { private MultiCertStoreParameters params; public MultiCertStoreSpi(CertStoreParameters params) throws InvalidAlgorithmParameterException { super(params); if (!(params instanceof MultiCertStoreParameters)) { throw new InvalidAlgorithmParameterException("org.bouncycastle.jce.provider.MultiCertStoreSpi: parameter must be a MultiCertStoreParameters object\n" + params.toString()); } this.params = (MultiCertStoreParameters)params; } public Collection engineGetCertificates(CertSelector certSelector) throws CertStoreException { boolean searchAllStores = params.getSearchAllStores(); Iterator iter = params.getCertStores().iterator(); List allCerts = searchAllStores ? new ArrayList() : Collections.EMPTY_LIST; while (iter.hasNext()) { CertStore store = (CertStore)iter.next(); Collection certs = store.getCertificates(certSelector); if (searchAllStores) { allCerts.addAll(certs); } else if (!certs.isEmpty()) { return certs; } } return allCerts; } public Collection engineGetCRLs(CRLSelector crlSelector) throws CertStoreException { boolean searchAllStores = params.getSearchAllStores(); Iterator iter = params.getCertStores().iterator(); List allCRLs = searchAllStores ? new ArrayList() : Collections.EMPTY_LIST; while (iter.hasNext()) { CertStore store = (CertStore)iter.next(); Collection crls = store.getCRLs(crlSelector); if (searchAllStores) { allCRLs.addAll(crls); } else if (!crls.isEmpty()) { return crls; } } return allCRLs; } } bouncycastle-1.49.orig/src/org/bouncycastle/jce/provider/JCEStreamCipher.java0000644000175000017500000004020412107306021026640 0ustar ebourgebourgpackage org.bouncycastle.jce.provider; import java.security.AlgorithmParameters; import java.security.InvalidAlgorithmParameterException; import java.security.InvalidKeyException; import java.security.Key; import java.security.KeyFactory; import java.security.NoSuchAlgorithmException; import java.security.NoSuchProviderException; import java.security.PrivateKey; import java.security.SecureRandom; import java.security.spec.AlgorithmParameterSpec; import java.security.spec.InvalidKeySpecException; import java.security.spec.PKCS8EncodedKeySpec; import java.security.spec.X509EncodedKeySpec; import javax.crypto.BadPaddingException; import javax.crypto.Cipher; import javax.crypto.CipherSpi; import javax.crypto.IllegalBlockSizeException; import javax.crypto.NoSuchPaddingException; import javax.crypto.SecretKey; import javax.crypto.ShortBufferException; import javax.crypto.spec.IvParameterSpec; import javax.crypto.spec.PBEParameterSpec; import javax.crypto.spec.RC2ParameterSpec; import javax.crypto.spec.RC5ParameterSpec; import javax.crypto.spec.SecretKeySpec; import org.bouncycastle.asn1.pkcs.PrivateKeyInfo; import org.bouncycastle.crypto.BlockCipher; import org.bouncycastle.crypto.CipherParameters; import org.bouncycastle.crypto.DataLengthException; import org.bouncycastle.crypto.StreamBlockCipher; import org.bouncycastle.crypto.StreamCipher; import org.bouncycastle.crypto.engines.BlowfishEngine; import org.bouncycastle.crypto.engines.DESEngine; import org.bouncycastle.crypto.engines.DESedeEngine; import org.bouncycastle.crypto.engines.RC4Engine; import org.bouncycastle.crypto.engines.SkipjackEngine; import org.bouncycastle.crypto.engines.TwofishEngine; import org.bouncycastle.crypto.modes.CFBBlockCipher; import org.bouncycastle.crypto.modes.OFBBlockCipher; import org.bouncycastle.crypto.params.KeyParameter; import org.bouncycastle.crypto.params.ParametersWithIV; import org.bouncycastle.jcajce.provider.symmetric.util.BCPBEKey; import org.bouncycastle.jcajce.provider.symmetric.util.PBE; public class JCEStreamCipher extends CipherSpi implements PBE { // // specs we can handle. // private Class[] availableSpecs = { RC2ParameterSpec.class, RC5ParameterSpec.class, IvParameterSpec.class, PBEParameterSpec.class }; private StreamCipher cipher; private ParametersWithIV ivParam; private int ivLength = 0; private PBEParameterSpec pbeSpec = null; private String pbeAlgorithm = null; private AlgorithmParameters engineParams; protected JCEStreamCipher( StreamCipher engine, int ivLength) { cipher = engine; this.ivLength = ivLength; } protected JCEStreamCipher( BlockCipher engine, int ivLength) { this.ivLength = ivLength; cipher = new StreamBlockCipher(engine); } protected int engineGetBlockSize() { return 0; } protected byte[] engineGetIV() { return (ivParam != null) ? ivParam.getIV() : null; } protected int engineGetKeySize( Key key) { return key.getEncoded().length * 8; } protected int engineGetOutputSize( int inputLen) { return inputLen; } protected AlgorithmParameters engineGetParameters() { if (engineParams == null) { if (pbeSpec != null) { try { AlgorithmParameters engineParams = AlgorithmParameters.getInstance(pbeAlgorithm, BouncyCastleProvider.PROVIDER_NAME); engineParams.init(pbeSpec); return engineParams; } catch (Exception e) { return null; } } } return engineParams; } /** * should never be called. */ protected void engineSetMode( String mode) { if (!mode.equalsIgnoreCase("ECB")) { throw new IllegalArgumentException("can't support mode " + mode); } } /** * should never be called. */ protected void engineSetPadding( String padding) throws NoSuchPaddingException { if (!padding.equalsIgnoreCase("NoPadding")) { throw new NoSuchPaddingException("Padding " + padding + " unknown."); } } protected void engineInit( int opmode, Key key, AlgorithmParameterSpec params, SecureRandom random) throws InvalidKeyException, InvalidAlgorithmParameterException { CipherParameters param; this.pbeSpec = null; this.pbeAlgorithm = null; this.engineParams = null; // // basic key check // if (!(key instanceof SecretKey)) { throw new InvalidKeyException("Key for algorithm " + key.getAlgorithm() + " not suitable for symmetric enryption."); } if (key instanceof BCPBEKey) { BCPBEKey k = (BCPBEKey)key; if (k.getOID() != null) { pbeAlgorithm = k.getOID().getId(); } else { pbeAlgorithm = k.getAlgorithm(); } if (k.getParam() != null) { param = k.getParam(); pbeSpec = new PBEParameterSpec(k.getSalt(), k.getIterationCount()); } else if (params instanceof PBEParameterSpec) { param = PBE.Util.makePBEParameters(k, params, cipher.getAlgorithmName()); pbeSpec = (PBEParameterSpec)params; } else { throw new InvalidAlgorithmParameterException("PBE requires PBE parameters to be set."); } if (k.getIvSize() != 0) { ivParam = (ParametersWithIV)param; } } else if (params == null) { param = new KeyParameter(key.getEncoded()); } else if (params instanceof IvParameterSpec) { param = new ParametersWithIV(new KeyParameter(key.getEncoded()), ((IvParameterSpec)params).getIV()); ivParam = (ParametersWithIV)param; } else { throw new IllegalArgumentException("unknown parameter type."); } if ((ivLength != 0) && !(param instanceof ParametersWithIV)) { SecureRandom ivRandom = random; if (ivRandom == null) { ivRandom = new SecureRandom(); } if ((opmode == Cipher.ENCRYPT_MODE) || (opmode == Cipher.WRAP_MODE)) { byte[] iv = new byte[ivLength]; ivRandom.nextBytes(iv); param = new ParametersWithIV(param, iv); ivParam = (ParametersWithIV)param; } else { throw new InvalidAlgorithmParameterException("no IV set when one expected"); } } switch (opmode) { case Cipher.ENCRYPT_MODE: case Cipher.WRAP_MODE: cipher.init(true, param); break; case Cipher.DECRYPT_MODE: case Cipher.UNWRAP_MODE: cipher.init(false, param); break; default: System.out.println("eeek!"); } } protected void engineInit( int opmode, Key key, AlgorithmParameters params, SecureRandom random) throws InvalidKeyException, InvalidAlgorithmParameterException { AlgorithmParameterSpec paramSpec = null; if (params != null) { for (int i = 0; i != availableSpecs.length; i++) { try { paramSpec = params.getParameterSpec(availableSpecs[i]); break; } catch (Exception e) { continue; } } if (paramSpec == null) { throw new InvalidAlgorithmParameterException("can't handle parameter " + params.toString()); } } engineInit(opmode, key, paramSpec, random); engineParams = params; } protected void engineInit( int opmode, Key key, SecureRandom random) throws InvalidKeyException { try { engineInit(opmode, key, (AlgorithmParameterSpec)null, random); } catch (InvalidAlgorithmParameterException e) { throw new InvalidKeyException(e.getMessage()); } } protected byte[] engineUpdate( byte[] input, int inputOffset, int inputLen) { byte[] out = new byte[inputLen]; cipher.processBytes(input, inputOffset, inputLen, out, 0); return out; } protected int engineUpdate( byte[] input, int inputOffset, int inputLen, byte[] output, int outputOffset) throws ShortBufferException { try { cipher.processBytes(input, inputOffset, inputLen, output, outputOffset); return inputLen; } catch (DataLengthException e) { throw new ShortBufferException(e.getMessage()); } } protected byte[] engineDoFinal( byte[] input, int inputOffset, int inputLen) throws BadPaddingException, IllegalBlockSizeException { if (inputLen != 0) { byte[] out = engineUpdate(input, inputOffset, inputLen); cipher.reset(); return out; } cipher.reset(); return new byte[0]; } protected int engineDoFinal( byte[] input, int inputOffset, int inputLen, byte[] output, int outputOffset) throws BadPaddingException { if (inputLen != 0) { cipher.processBytes(input, inputOffset, inputLen, output, outputOffset); } cipher.reset(); return inputLen; } protected byte[] engineWrap( Key key) throws IllegalBlockSizeException, InvalidKeyException { byte[] encoded = key.getEncoded(); if (encoded == null) { throw new InvalidKeyException("Cannot wrap key, null encoding."); } try { return engineDoFinal(encoded, 0, encoded.length); } catch (BadPaddingException e) { throw new IllegalBlockSizeException(e.getMessage()); } } protected Key engineUnwrap( byte[] wrappedKey, String wrappedKeyAlgorithm, int wrappedKeyType) throws InvalidKeyException { byte[] encoded; try { encoded = engineDoFinal(wrappedKey, 0, wrappedKey.length); } catch (BadPaddingException e) { throw new InvalidKeyException(e.getMessage()); } catch (IllegalBlockSizeException e2) { throw new InvalidKeyException(e2.getMessage()); } if (wrappedKeyType == Cipher.SECRET_KEY) { return new SecretKeySpec(encoded, wrappedKeyAlgorithm); } else if (wrappedKeyAlgorithm.equals("") && wrappedKeyType == Cipher.PRIVATE_KEY) { /* * The caller doesn't know the algorithm as it is part of * the encrypted data. */ try { PrivateKeyInfo in = PrivateKeyInfo.getInstance(encoded); PrivateKey privKey = BouncyCastleProvider.getPrivateKey(in); if (privKey != null) { return privKey; } else { throw new InvalidKeyException("algorithm " + in.getPrivateKeyAlgorithm().getAlgorithm() + " not supported"); } } catch (Exception e) { throw new InvalidKeyException("Invalid key encoding."); } } else { try { KeyFactory kf = KeyFactory.getInstance(wrappedKeyAlgorithm, BouncyCastleProvider.PROVIDER_NAME); if (wrappedKeyType == Cipher.PUBLIC_KEY) { return kf.generatePublic(new X509EncodedKeySpec(encoded)); } else if (wrappedKeyType == Cipher.PRIVATE_KEY) { return kf.generatePrivate(new PKCS8EncodedKeySpec(encoded)); } } catch (NoSuchProviderException e) { throw new InvalidKeyException("Unknown key type " + e.getMessage()); } catch (NoSuchAlgorithmException e) { throw new InvalidKeyException("Unknown key type " + e.getMessage()); } catch (InvalidKeySpecException e2) { throw new InvalidKeyException("Unknown key type " + e2.getMessage()); } throw new InvalidKeyException("Unknown key type " + wrappedKeyType); } } /* * The ciphers that inherit from us. */ /** * DES */ static public class DES_CFB8 extends JCEStreamCipher { public DES_CFB8() { super(new CFBBlockCipher(new DESEngine(), 8), 64); } } /** * DESede */ static public class DESede_CFB8 extends JCEStreamCipher { public DESede_CFB8() { super(new CFBBlockCipher(new DESedeEngine(), 8), 64); } } /** * SKIPJACK */ static public class Skipjack_CFB8 extends JCEStreamCipher { public Skipjack_CFB8() { super(new CFBBlockCipher(new SkipjackEngine(), 8), 64); } } /** * Blowfish */ static public class Blowfish_CFB8 extends JCEStreamCipher { public Blowfish_CFB8() { super(new CFBBlockCipher(new BlowfishEngine(), 8), 64); } } /** * Twofish */ static public class Twofish_CFB8 extends JCEStreamCipher { public Twofish_CFB8() { super(new CFBBlockCipher(new TwofishEngine(), 8), 128); } } /** * DES */ static public class DES_OFB8 extends JCEStreamCipher { public DES_OFB8() { super(new OFBBlockCipher(new DESEngine(), 8), 64); } } /** * DESede */ static public class DESede_OFB8 extends JCEStreamCipher { public DESede_OFB8() { super(new OFBBlockCipher(new DESedeEngine(), 8), 64); } } /** * SKIPJACK */ static public class Skipjack_OFB8 extends JCEStreamCipher { public Skipjack_OFB8() { super(new OFBBlockCipher(new SkipjackEngine(), 8), 64); } } /** * Blowfish */ static public class Blowfish_OFB8 extends JCEStreamCipher { public Blowfish_OFB8() { super(new OFBBlockCipher(new BlowfishEngine(), 8), 64); } } /** * Twofish */ static public class Twofish_OFB8 extends JCEStreamCipher { public Twofish_OFB8() { super(new OFBBlockCipher(new TwofishEngine(), 8), 128); } } } bouncycastle-1.49.orig/src/org/bouncycastle/jce/provider/JCEECPrivateKey.java0000644000175000017500000003442312110037231026551 0ustar ebourgebourgpackage org.bouncycastle.jce.provider; import java.io.IOException; import java.io.ObjectInputStream; import java.io.ObjectOutputStream; import java.math.BigInteger; import java.security.interfaces.ECPrivateKey; import java.security.spec.ECParameterSpec; import java.security.spec.ECPoint; import java.security.spec.ECPrivateKeySpec; import java.security.spec.EllipticCurve; import java.util.Enumeration; import org.bouncycastle.asn1.ASN1Encodable; import org.bouncycastle.asn1.ASN1Encoding; import org.bouncycastle.asn1.ASN1ObjectIdentifier; import org.bouncycastle.asn1.ASN1Primitive; import org.bouncycastle.asn1.ASN1Sequence; import org.bouncycastle.asn1.DERBitString; import org.bouncycastle.asn1.DERInteger; import org.bouncycastle.asn1.DERNull; import org.bouncycastle.asn1.DERObjectIdentifier; import org.bouncycastle.asn1.cryptopro.CryptoProObjectIdentifiers; import org.bouncycastle.asn1.cryptopro.ECGOST3410NamedCurves; import org.bouncycastle.asn1.pkcs.PrivateKeyInfo; import org.bouncycastle.asn1.sec.ECPrivateKeyStructure; import org.bouncycastle.asn1.x509.AlgorithmIdentifier; import org.bouncycastle.asn1.x509.SubjectPublicKeyInfo; import org.bouncycastle.asn1.x9.X962Parameters; import org.bouncycastle.asn1.x9.X9ECParameters; import org.bouncycastle.asn1.x9.X9ObjectIdentifiers; import org.bouncycastle.crypto.params.ECDomainParameters; import org.bouncycastle.crypto.params.ECPrivateKeyParameters; import org.bouncycastle.jcajce.provider.asymmetric.util.EC5Util; import org.bouncycastle.jcajce.provider.asymmetric.util.ECUtil; import org.bouncycastle.jcajce.provider.asymmetric.util.PKCS12BagAttributeCarrierImpl; import org.bouncycastle.jce.interfaces.ECPointEncoder; import org.bouncycastle.jce.interfaces.PKCS12BagAttributeCarrier; import org.bouncycastle.jce.spec.ECNamedCurveSpec; import org.bouncycastle.math.ec.ECCurve; public class JCEECPrivateKey implements ECPrivateKey, org.bouncycastle.jce.interfaces.ECPrivateKey, PKCS12BagAttributeCarrier, ECPointEncoder { private String algorithm = "EC"; private BigInteger d; private ECParameterSpec ecSpec; private boolean withCompression; private DERBitString publicKey; private PKCS12BagAttributeCarrierImpl attrCarrier = new PKCS12BagAttributeCarrierImpl(); protected JCEECPrivateKey() { } public JCEECPrivateKey( ECPrivateKey key) { this.d = key.getS(); this.algorithm = key.getAlgorithm(); this.ecSpec = key.getParams(); } public JCEECPrivateKey( String algorithm, org.bouncycastle.jce.spec.ECPrivateKeySpec spec) { this.algorithm = algorithm; this.d = spec.getD(); if (spec.getParams() != null) // can be null if implicitlyCA { ECCurve curve = spec.getParams().getCurve(); EllipticCurve ellipticCurve; ellipticCurve = EC5Util.convertCurve(curve, spec.getParams().getSeed()); this.ecSpec = EC5Util.convertSpec(ellipticCurve, spec.getParams()); } else { this.ecSpec = null; } } public JCEECPrivateKey( String algorithm, ECPrivateKeySpec spec) { this.algorithm = algorithm; this.d = spec.getS(); this.ecSpec = spec.getParams(); } public JCEECPrivateKey( String algorithm, JCEECPrivateKey key) { this.algorithm = algorithm; this.d = key.d; this.ecSpec = key.ecSpec; this.withCompression = key.withCompression; this.attrCarrier = key.attrCarrier; this.publicKey = key.publicKey; } public JCEECPrivateKey( String algorithm, ECPrivateKeyParameters params, JCEECPublicKey pubKey, ECParameterSpec spec) { ECDomainParameters dp = params.getParameters(); this.algorithm = algorithm; this.d = params.getD(); if (spec == null) { EllipticCurve ellipticCurve = EC5Util.convertCurve(dp.getCurve(), dp.getSeed()); this.ecSpec = new ECParameterSpec( ellipticCurve, new ECPoint( dp.getG().getX().toBigInteger(), dp.getG().getY().toBigInteger()), dp.getN(), dp.getH().intValue()); } else { this.ecSpec = spec; } publicKey = getPublicKeyDetails(pubKey); } public JCEECPrivateKey( String algorithm, ECPrivateKeyParameters params, JCEECPublicKey pubKey, org.bouncycastle.jce.spec.ECParameterSpec spec) { ECDomainParameters dp = params.getParameters(); this.algorithm = algorithm; this.d = params.getD(); if (spec == null) { EllipticCurve ellipticCurve = EC5Util.convertCurve(dp.getCurve(), dp.getSeed()); this.ecSpec = new ECParameterSpec( ellipticCurve, new ECPoint( dp.getG().getX().toBigInteger(), dp.getG().getY().toBigInteger()), dp.getN(), dp.getH().intValue()); } else { EllipticCurve ellipticCurve = EC5Util.convertCurve(spec.getCurve(), spec.getSeed()); this.ecSpec = new ECParameterSpec( ellipticCurve, new ECPoint( spec.getG().getX().toBigInteger(), spec.getG().getY().toBigInteger()), spec.getN(), spec.getH().intValue()); } publicKey = getPublicKeyDetails(pubKey); } public JCEECPrivateKey( String algorithm, ECPrivateKeyParameters params) { this.algorithm = algorithm; this.d = params.getD(); this.ecSpec = null; } JCEECPrivateKey( PrivateKeyInfo info) throws IOException { populateFromPrivKeyInfo(info); } private void populateFromPrivKeyInfo(PrivateKeyInfo info) throws IOException { X962Parameters params = new X962Parameters((ASN1Primitive)info.getPrivateKeyAlgorithm().getParameters()); if (params.isNamedCurve()) { ASN1ObjectIdentifier oid = ASN1ObjectIdentifier.getInstance(params.getParameters()); X9ECParameters ecP = ECUtil.getNamedCurveByOid(oid); if (ecP == null) // GOST Curve { ECDomainParameters gParam = ECGOST3410NamedCurves.getByOID(oid); EllipticCurve ellipticCurve = EC5Util.convertCurve(gParam.getCurve(), gParam.getSeed()); ecSpec = new ECNamedCurveSpec( ECGOST3410NamedCurves.getName(oid), ellipticCurve, new ECPoint( gParam.getG().getX().toBigInteger(), gParam.getG().getY().toBigInteger()), gParam.getN(), gParam.getH()); } else { EllipticCurve ellipticCurve = EC5Util.convertCurve(ecP.getCurve(), ecP.getSeed()); ecSpec = new ECNamedCurveSpec( ECUtil.getCurveName(oid), ellipticCurve, new ECPoint( ecP.getG().getX().toBigInteger(), ecP.getG().getY().toBigInteger()), ecP.getN(), ecP.getH()); } } else if (params.isImplicitlyCA()) { ecSpec = null; } else { X9ECParameters ecP = X9ECParameters.getInstance(params.getParameters()); EllipticCurve ellipticCurve = EC5Util.convertCurve(ecP.getCurve(), ecP.getSeed()); this.ecSpec = new ECParameterSpec( ellipticCurve, new ECPoint( ecP.getG().getX().toBigInteger(), ecP.getG().getY().toBigInteger()), ecP.getN(), ecP.getH().intValue()); } ASN1Encodable privKey = info.parsePrivateKey(); if (privKey instanceof DERInteger) { DERInteger derD = DERInteger.getInstance(privKey); this.d = derD.getValue(); } else { ECPrivateKeyStructure ec = new ECPrivateKeyStructure((ASN1Sequence)privKey); this.d = ec.getKey(); this.publicKey = ec.getPublicKey(); } } public String getAlgorithm() { return algorithm; } /** * return the encoding format we produce in getEncoded(). * * @return the string "PKCS#8" */ public String getFormat() { return "PKCS#8"; } /** * Return a PKCS8 representation of the key. The sequence returned * represents a full PrivateKeyInfo object. * * @return a PKCS8 representation of the key. */ public byte[] getEncoded() { X962Parameters params; if (ecSpec instanceof ECNamedCurveSpec) { DERObjectIdentifier curveOid = ECUtil.getNamedCurveOid(((ECNamedCurveSpec)ecSpec).getName()); if (curveOid == null) // guess it's the OID { curveOid = new DERObjectIdentifier(((ECNamedCurveSpec)ecSpec).getName()); } params = new X962Parameters(curveOid); } else if (ecSpec == null) { params = new X962Parameters(DERNull.INSTANCE); } else { ECCurve curve = EC5Util.convertCurve(ecSpec.getCurve()); X9ECParameters ecP = new X9ECParameters( curve, EC5Util.convertPoint(curve, ecSpec.getGenerator(), withCompression), ecSpec.getOrder(), BigInteger.valueOf(ecSpec.getCofactor()), ecSpec.getCurve().getSeed()); params = new X962Parameters(ecP); } PrivateKeyInfo info; ECPrivateKeyStructure keyStructure; if (publicKey != null) { keyStructure = new ECPrivateKeyStructure(this.getS(), publicKey, params); } else { keyStructure = new ECPrivateKeyStructure(this.getS(), params); } try { if (algorithm.equals("ECGOST3410")) { info = new PrivateKeyInfo(new AlgorithmIdentifier(CryptoProObjectIdentifiers.gostR3410_2001, params.toASN1Primitive()), keyStructure.toASN1Primitive()); } else { info = new PrivateKeyInfo(new AlgorithmIdentifier(X9ObjectIdentifiers.id_ecPublicKey, params.toASN1Primitive()), keyStructure.toASN1Primitive()); } return info.getEncoded(ASN1Encoding.DER); } catch (IOException e) { return null; } } public ECParameterSpec getParams() { return ecSpec; } public org.bouncycastle.jce.spec.ECParameterSpec getParameters() { if (ecSpec == null) { return null; } return EC5Util.convertSpec(ecSpec, withCompression); } org.bouncycastle.jce.spec.ECParameterSpec engineGetSpec() { if (ecSpec != null) { return EC5Util.convertSpec(ecSpec, withCompression); } return BouncyCastleProvider.CONFIGURATION.getEcImplicitlyCa(); } public BigInteger getS() { return d; } public BigInteger getD() { return d; } public void setBagAttribute( ASN1ObjectIdentifier oid, ASN1Encodable attribute) { attrCarrier.setBagAttribute(oid, attribute); } public ASN1Encodable getBagAttribute( ASN1ObjectIdentifier oid) { return attrCarrier.getBagAttribute(oid); } public Enumeration getBagAttributeKeys() { return attrCarrier.getBagAttributeKeys(); } public void setPointFormat(String style) { withCompression = !("UNCOMPRESSED".equalsIgnoreCase(style)); } public boolean equals(Object o) { if (!(o instanceof JCEECPrivateKey)) { return false; } JCEECPrivateKey other = (JCEECPrivateKey)o; return getD().equals(other.getD()) && (engineGetSpec().equals(other.engineGetSpec())); } public int hashCode() { return getD().hashCode() ^ engineGetSpec().hashCode(); } public String toString() { StringBuffer buf = new StringBuffer(); String nl = System.getProperty("line.separator"); buf.append("EC Private Key").append(nl); buf.append(" S: ").append(this.d.toString(16)).append(nl); return buf.toString(); } private DERBitString getPublicKeyDetails(JCEECPublicKey pub) { try { SubjectPublicKeyInfo info = SubjectPublicKeyInfo.getInstance(ASN1Primitive.fromByteArray(pub.getEncoded())); return info.getPublicKeyData(); } catch (IOException e) { // should never happen return null; } } private void readObject( ObjectInputStream in) throws IOException, ClassNotFoundException { byte[] enc = (byte[])in.readObject(); populateFromPrivKeyInfo(PrivateKeyInfo.getInstance(ASN1Primitive.fromByteArray(enc))); this.algorithm = (String)in.readObject(); this.withCompression = in.readBoolean(); this.attrCarrier = new PKCS12BagAttributeCarrierImpl(); attrCarrier.readObject(in); } private void writeObject( ObjectOutputStream out) throws IOException { out.writeObject(this.getEncoded()); out.writeObject(algorithm); out.writeBoolean(withCompression); attrCarrier.writeObject(out); } } bouncycastle-1.49.orig/src/org/bouncycastle/jce/provider/PKIXCRLUtil.java0000644000175000017500000001110711624640052025712 0ustar ebourgebourgpackage org.bouncycastle.jce.provider; import java.security.cert.CertStore; import java.security.cert.CertStoreException; import java.security.cert.PKIXParameters; import java.security.cert.X509CRL; import java.security.cert.X509Certificate; import java.util.Collection; import java.util.Date; import java.util.HashSet; import java.util.Iterator; import java.util.List; import java.util.Set; import org.bouncycastle.util.StoreException; import org.bouncycastle.x509.ExtendedPKIXParameters; import org.bouncycastle.x509.X509CRLStoreSelector; import org.bouncycastle.x509.X509Store; public class PKIXCRLUtil { public Set findCRLs(X509CRLStoreSelector crlselect, ExtendedPKIXParameters paramsPKIX, Date currentDate) throws AnnotatedException { Set initialSet = new HashSet(); // get complete CRL(s) try { initialSet.addAll(findCRLs(crlselect, paramsPKIX.getAdditionalStores())); initialSet.addAll(findCRLs(crlselect, paramsPKIX.getStores())); initialSet.addAll(findCRLs(crlselect, paramsPKIX.getCertStores())); } catch (AnnotatedException e) { throw new AnnotatedException("Exception obtaining complete CRLs.", e); } Set finalSet = new HashSet(); Date validityDate = currentDate; if (paramsPKIX.getDate() != null) { validityDate = paramsPKIX.getDate(); } // based on RFC 5280 6.3.3 for (Iterator it = initialSet.iterator(); it.hasNext();) { X509CRL crl = (X509CRL)it.next(); if (crl.getNextUpdate().after(validityDate)) { X509Certificate cert = crlselect.getCertificateChecking(); if (cert != null) { if (crl.getThisUpdate().before(cert.getNotAfter())) { finalSet.add(crl); } } else { finalSet.add(crl); } } } return finalSet; } public Set findCRLs(X509CRLStoreSelector crlselect, PKIXParameters paramsPKIX) throws AnnotatedException { Set completeSet = new HashSet(); // get complete CRL(s) try { completeSet.addAll(findCRLs(crlselect, paramsPKIX.getCertStores())); } catch (AnnotatedException e) { throw new AnnotatedException("Exception obtaining complete CRLs.", e); } return completeSet; } /** * Return a Collection of all CRLs found in the X509Store's that are * matching the crlSelect criteriums. * * @param crlSelect a {@link X509CRLStoreSelector} object that will be used * to select the CRLs * @param crlStores a List containing only * {@link org.bouncycastle.x509.X509Store X509Store} objects. * These are used to search for CRLs * * @return a Collection of all found {@link java.security.cert.X509CRL X509CRL} objects. May be * empty but never null. */ private final Collection findCRLs(X509CRLStoreSelector crlSelect, List crlStores) throws AnnotatedException { Set crls = new HashSet(); Iterator iter = crlStores.iterator(); AnnotatedException lastException = null; boolean foundValidStore = false; while (iter.hasNext()) { Object obj = iter.next(); if (obj instanceof X509Store) { X509Store store = (X509Store)obj; try { crls.addAll(store.getMatches(crlSelect)); foundValidStore = true; } catch (StoreException e) { lastException = new AnnotatedException( "Exception searching in X.509 CRL store.", e); } } else { CertStore store = (CertStore)obj; try { crls.addAll(store.getCRLs(crlSelect)); foundValidStore = true; } catch (CertStoreException e) { lastException = new AnnotatedException( "Exception searching in X.509 CRL store.", e); } } } if (!foundValidStore && lastException != null) { throw lastException; } return crls; } } bouncycastle-1.49.orig/src/org/bouncycastle/jce/provider/X509StoreCertPairCollection.java0000644000175000017500000000373211624652565031111 0ustar ebourgebourgpackage org.bouncycastle.jce.provider; import java.util.Collection; import org.bouncycastle.util.CollectionStore; import org.bouncycastle.util.Selector; import org.bouncycastle.x509.X509CollectionStoreParameters; import org.bouncycastle.x509.X509StoreParameters; import org.bouncycastle.x509.X509StoreSpi; /** * This class is a collection based Bouncy Castle * {@link org.bouncycastle.x509.X509Store} SPI implementation for certificate * pairs. * * @see org.bouncycastle.x509.X509Store * @see org.bouncycastle.x509.X509CertificatePair */ public class X509StoreCertPairCollection extends X509StoreSpi { private CollectionStore _store; public X509StoreCertPairCollection() { } /** * Initializes this store. * * @param params The {@link X509CollectionStoreParameters}s for this store. * @throws IllegalArgumentException if params is no instance of * X509CollectionStoreParameters. */ public void engineInit(X509StoreParameters params) { if (!(params instanceof X509CollectionStoreParameters)) { throw new IllegalArgumentException( "Initialization parameters must be an instance of " + X509CollectionStoreParameters.class.getName() + "."); } _store = new CollectionStore(((X509CollectionStoreParameters)params) .getCollection()); } /** * Returns a colelction of certificate pairs which match the given * selector. *

    * The returned collection contains * {@link org.bouncycastle.x509.X509CertificatePair}s. The selector must be * a {@link org.bouncycastle.x509.X509CertPairStoreSelector} to select * certificate pairs. * * @return A collection with matching certificate pairs. */ public Collection engineGetMatches(Selector selector) { return _store.getMatches(selector); } } bouncycastle-1.49.orig/src/org/bouncycastle/jce/provider/BrokenKDF2BytesGenerator.java0000644000175000017500000000736011624640051030452 0ustar ebourgebourgpackage org.bouncycastle.jce.provider; import org.bouncycastle.crypto.DataLengthException; import org.bouncycastle.crypto.DerivationFunction; import org.bouncycastle.crypto.DerivationParameters; import org.bouncycastle.crypto.Digest; import org.bouncycastle.crypto.params.KDFParameters; /** * Generator for PBE derived keys and ivs as defined by IEEE P1363a *
    * This implementation is based on draft 9 of IEEE P1363a. Note: * as this is still a draft the output of this generator may change, don't * use it for anything that might be subject to long term storage. */ public class BrokenKDF2BytesGenerator implements DerivationFunction { private Digest digest; private byte[] shared; private byte[] iv; /** * Construct a KDF2 Parameters generator. Generates key material * according to IEEE P1363a - if you want orthodox results you should * use a digest specified in the standard. *

    * Note: IEEE P1363a standard is still a draft standard, if the standard * changes this function, the output of this function will change as well. * Don't use this routine for anything subject to long term storage. * * @param digest the digest to be used as the source of derived keys. */ public BrokenKDF2BytesGenerator( Digest digest) { this.digest = digest; } public void init( DerivationParameters param) { if (!(param instanceof KDFParameters)) { throw new IllegalArgumentException("KDF parameters required for KDF2Generator"); } KDFParameters p = (KDFParameters)param; shared = p.getSharedSecret(); iv = p.getIV(); } /** * return the underlying digest. */ public Digest getDigest() { return digest; } /** * fill len bytes of the output buffer with bytes generated from * the derivation function. * * @throws IllegalArgumentException if the size of the request will cause an overflow. * @throws DataLengthException if the out buffer is too small. */ public int generateBytes( byte[] out, int outOff, int len) throws DataLengthException, IllegalArgumentException { if ((out.length - len) < outOff) { throw new DataLengthException("output buffer too small"); } long oBits = len * 8; // // this is at odds with the standard implementation, the // maximum value should be hBits * (2^23 - 1) where hBits // is the digest output size in bits. We can't have an // array with a long index at the moment... // if (oBits > (digest.getDigestSize() * 8 * (2L^32 - 1))) { new IllegalArgumentException("Output length to large"); } int cThreshold = (int)(oBits / digest.getDigestSize()); byte[] dig = null; dig = new byte[digest.getDigestSize()]; for (int counter = 1; counter <= cThreshold; counter++) { digest.update(shared, 0, shared.length); digest.update((byte)(counter & 0xff)); digest.update((byte)((counter >> 8) & 0xff)); digest.update((byte)((counter >> 16) & 0xff)); digest.update((byte)((counter >> 24) & 0xff)); digest.update(iv, 0, iv.length); digest.doFinal(dig, 0); if ((len - outOff) > dig.length) { System.arraycopy(dig, 0, out, outOff, dig.length); outOff += dig.length; } else { System.arraycopy(dig, 0, out, outOff, len - outOff); } } digest.reset(); return len; } } bouncycastle-1.49.orig/src/org/bouncycastle/jce/provider/CertPathValidatorUtilities.java0000644000175000017500000014133512103440465031222 0ustar ebourgebourgpackage org.bouncycastle.jce.provider; import java.io.ByteArrayOutputStream; import java.io.IOException; import java.math.BigInteger; import java.security.GeneralSecurityException; import java.security.KeyFactory; import java.security.PublicKey; import java.security.cert.CRLException; import java.security.cert.CertPath; import java.security.cert.CertPathValidatorException; import java.security.cert.CertStore; import java.security.cert.CertStoreException; import java.security.cert.Certificate; import java.security.cert.CertificateParsingException; import java.security.cert.PKIXParameters; import java.security.cert.PolicyQualifierInfo; import java.security.cert.TrustAnchor; import java.security.cert.X509CRL; import java.security.cert.X509CRLEntry; import java.security.cert.X509CRLSelector; import java.security.cert.X509CertSelector; import java.security.cert.X509Certificate; import java.security.interfaces.DSAParams; import java.security.interfaces.DSAPublicKey; import java.security.spec.DSAPublicKeySpec; import java.text.ParseException; import java.util.ArrayList; import java.util.Collection; import java.util.Date; import java.util.Enumeration; import java.util.HashSet; import java.util.Iterator; import java.util.List; import java.util.Map; import java.util.Set; import javax.security.auth.x500.X500Principal; import org.bouncycastle.asn1.ASN1Encodable; import org.bouncycastle.asn1.ASN1InputStream; import org.bouncycastle.asn1.ASN1Integer; import org.bouncycastle.asn1.ASN1OctetString; import org.bouncycastle.asn1.ASN1OutputStream; import org.bouncycastle.asn1.ASN1Primitive; import org.bouncycastle.asn1.ASN1Sequence; import org.bouncycastle.asn1.DEREnumerated; import org.bouncycastle.asn1.DERGeneralizedTime; import org.bouncycastle.asn1.DERIA5String; import org.bouncycastle.asn1.DERObjectIdentifier; import org.bouncycastle.asn1.DERSequence; import org.bouncycastle.asn1.isismtt.ISISMTTObjectIdentifiers; import org.bouncycastle.asn1.x509.AlgorithmIdentifier; import org.bouncycastle.asn1.x509.CRLDistPoint; import org.bouncycastle.asn1.x509.CRLReason; import org.bouncycastle.asn1.x509.DistributionPoint; import org.bouncycastle.asn1.x509.DistributionPointName; import org.bouncycastle.asn1.x509.Extension; import org.bouncycastle.asn1.x509.GeneralName; import org.bouncycastle.asn1.x509.GeneralNames; import org.bouncycastle.asn1.x509.PolicyInformation; import org.bouncycastle.asn1.x509.SubjectPublicKeyInfo; import org.bouncycastle.asn1.x509.X509Extension; import org.bouncycastle.jce.X509LDAPCertStoreParameters; import org.bouncycastle.jce.exception.ExtCertPathValidatorException; import org.bouncycastle.util.Integers; import org.bouncycastle.util.Selector; import org.bouncycastle.util.StoreException; import org.bouncycastle.x509.ExtendedPKIXBuilderParameters; import org.bouncycastle.x509.ExtendedPKIXParameters; import org.bouncycastle.x509.X509AttributeCertStoreSelector; import org.bouncycastle.x509.X509AttributeCertificate; import org.bouncycastle.x509.X509CRLStoreSelector; import org.bouncycastle.x509.X509CertStoreSelector; import org.bouncycastle.x509.X509Store; public class CertPathValidatorUtilities { protected static final PKIXCRLUtil CRL_UTIL = new PKIXCRLUtil(); protected static final String CERTIFICATE_POLICIES = Extension.certificatePolicies.getId(); protected static final String BASIC_CONSTRAINTS = Extension.basicConstraints.getId(); protected static final String POLICY_MAPPINGS = Extension.policyMappings.getId(); protected static final String SUBJECT_ALTERNATIVE_NAME = Extension.subjectAlternativeName.getId(); protected static final String NAME_CONSTRAINTS = Extension.nameConstraints.getId(); protected static final String KEY_USAGE = Extension.keyUsage.getId(); protected static final String INHIBIT_ANY_POLICY = Extension.inhibitAnyPolicy.getId(); protected static final String ISSUING_DISTRIBUTION_POINT = Extension.issuingDistributionPoint.getId(); protected static final String DELTA_CRL_INDICATOR = Extension.deltaCRLIndicator.getId(); protected static final String POLICY_CONSTRAINTS = Extension.policyConstraints.getId(); protected static final String FRESHEST_CRL = Extension.freshestCRL.getId(); protected static final String CRL_DISTRIBUTION_POINTS = Extension.cRLDistributionPoints.getId(); protected static final String AUTHORITY_KEY_IDENTIFIER = Extension.authorityKeyIdentifier.getId(); protected static final String ANY_POLICY = "2.5.29.32.0"; protected static final String CRL_NUMBER = Extension.cRLNumber.getId(); /* * key usage bits */ protected static final int KEY_CERT_SIGN = 5; protected static final int CRL_SIGN = 6; protected static final String[] crlReasons = new String[]{ "unspecified", "keyCompromise", "cACompromise", "affiliationChanged", "superseded", "cessationOfOperation", "certificateHold", "unknown", "removeFromCRL", "privilegeWithdrawn", "aACompromise"}; /** * Search the given Set of TrustAnchor's for one that is the * issuer of the given X509 certificate. Uses the default provider * for signature verification. * * @param cert the X509 certificate * @param trustAnchors a Set of TrustAnchor's * @return the TrustAnchor object if found or * null if not. * @throws AnnotatedException if a TrustAnchor was found but the signature verification * on the given certificate has thrown an exception. */ protected static TrustAnchor findTrustAnchor( X509Certificate cert, Set trustAnchors) throws AnnotatedException { return findTrustAnchor(cert, trustAnchors, null); } /** * Search the given Set of TrustAnchor's for one that is the * issuer of the given X509 certificate. Uses the specified * provider for signature verification, or the default provider * if null. * * @param cert the X509 certificate * @param trustAnchors a Set of TrustAnchor's * @param sigProvider the provider to use for signature verification * @return the TrustAnchor object if found or * null if not. * @throws AnnotatedException if a TrustAnchor was found but the signature verification * on the given certificate has thrown an exception. */ protected static TrustAnchor findTrustAnchor( X509Certificate cert, Set trustAnchors, String sigProvider) throws AnnotatedException { TrustAnchor trust = null; PublicKey trustPublicKey = null; Exception invalidKeyEx = null; X509CertSelector certSelectX509 = new X509CertSelector(); X500Principal certIssuer = getEncodedIssuerPrincipal(cert); try { certSelectX509.setSubject(certIssuer.getEncoded()); } catch (IOException ex) { throw new AnnotatedException("Cannot set subject search criteria for trust anchor.", ex); } Iterator iter = trustAnchors.iterator(); while (iter.hasNext() && trust == null) { trust = (TrustAnchor)iter.next(); if (trust.getTrustedCert() != null) { if (certSelectX509.match(trust.getTrustedCert())) { trustPublicKey = trust.getTrustedCert().getPublicKey(); } else { trust = null; } } else if (trust.getCAName() != null && trust.getCAPublicKey() != null) { try { X500Principal caName = new X500Principal(trust.getCAName()); if (certIssuer.equals(caName)) { trustPublicKey = trust.getCAPublicKey(); } else { trust = null; } } catch (IllegalArgumentException ex) { trust = null; } } else { trust = null; } if (trustPublicKey != null) { try { verifyX509Certificate(cert, trustPublicKey, sigProvider); } catch (Exception ex) { invalidKeyEx = ex; trust = null; trustPublicKey = null; } } } if (trust == null && invalidKeyEx != null) { throw new AnnotatedException("TrustAnchor found but certificate validation failed.", invalidKeyEx); } return trust; } protected static void addAdditionalStoresFromAltNames( X509Certificate cert, ExtendedPKIXParameters pkixParams) throws CertificateParsingException { // if in the IssuerAltName extension an URI // is given, add an additinal X.509 store if (cert.getIssuerAlternativeNames() != null) { Iterator it = cert.getIssuerAlternativeNames().iterator(); while (it.hasNext()) { // look for URI List list = (List)it.next(); if (list.get(0).equals(Integers.valueOf(GeneralName.uniformResourceIdentifier))) { // found String temp = (String)list.get(1); CertPathValidatorUtilities.addAdditionalStoreFromLocation(temp, pkixParams); } } } } /** * Returns the issuer of an attribute certificate or certificate. * * @param cert The attribute certificate or certificate. * @return The issuer as X500Principal. */ protected static X500Principal getEncodedIssuerPrincipal( Object cert) { if (cert instanceof X509Certificate) { return ((X509Certificate)cert).getIssuerX500Principal(); } else { return (X500Principal)((X509AttributeCertificate)cert).getIssuer().getPrincipals()[0]; } } protected static Date getValidDate(PKIXParameters paramsPKIX) { Date validDate = paramsPKIX.getDate(); if (validDate == null) { validDate = new Date(); } return validDate; } protected static X500Principal getSubjectPrincipal(X509Certificate cert) { return cert.getSubjectX500Principal(); } protected static boolean isSelfIssued(X509Certificate cert) { return cert.getSubjectDN().equals(cert.getIssuerDN()); } /** * Extract the value of the given extension, if it exists. * * @param ext The extension object. * @param oid The object identifier to obtain. * @throws AnnotatedException if the extension cannot be read. */ protected static ASN1Primitive getExtensionValue( java.security.cert.X509Extension ext, String oid) throws AnnotatedException { byte[] bytes = ext.getExtensionValue(oid); if (bytes == null) { return null; } return getObject(oid, bytes); } private static ASN1Primitive getObject( String oid, byte[] ext) throws AnnotatedException { try { ASN1InputStream aIn = new ASN1InputStream(ext); ASN1OctetString octs = (ASN1OctetString)aIn.readObject(); aIn = new ASN1InputStream(octs.getOctets()); return aIn.readObject(); } catch (Exception e) { throw new AnnotatedException("exception processing extension " + oid, e); } } protected static X500Principal getIssuerPrincipal(X509CRL crl) { return crl.getIssuerX500Principal(); } protected static AlgorithmIdentifier getAlgorithmIdentifier( PublicKey key) throws CertPathValidatorException { try { ASN1InputStream aIn = new ASN1InputStream(key.getEncoded()); SubjectPublicKeyInfo info = SubjectPublicKeyInfo.getInstance(aIn.readObject()); return info.getAlgorithmId(); } catch (Exception e) { throw new ExtCertPathValidatorException("Subject public key cannot be decoded.", e); } } // crl checking // // policy checking // protected static final Set getQualifierSet(ASN1Sequence qualifiers) throws CertPathValidatorException { Set pq = new HashSet(); if (qualifiers == null) { return pq; } ByteArrayOutputStream bOut = new ByteArrayOutputStream(); ASN1OutputStream aOut = new ASN1OutputStream(bOut); Enumeration e = qualifiers.getObjects(); while (e.hasMoreElements()) { try { aOut.writeObject((ASN1Encodable)e.nextElement()); pq.add(new PolicyQualifierInfo(bOut.toByteArray())); } catch (IOException ex) { throw new ExtCertPathValidatorException("Policy qualifier info cannot be decoded.", ex); } bOut.reset(); } return pq; } protected static PKIXPolicyNode removePolicyNode( PKIXPolicyNode validPolicyTree, List[] policyNodes, PKIXPolicyNode _node) { PKIXPolicyNode _parent = (PKIXPolicyNode)_node.getParent(); if (validPolicyTree == null) { return null; } if (_parent == null) { for (int j = 0; j < policyNodes.length; j++) { policyNodes[j] = new ArrayList(); } return null; } else { _parent.removeChild(_node); removePolicyNodeRecurse(policyNodes, _node); return validPolicyTree; } } private static void removePolicyNodeRecurse( List[] policyNodes, PKIXPolicyNode _node) { policyNodes[_node.getDepth()].remove(_node); if (_node.hasChildren()) { Iterator _iter = _node.getChildren(); while (_iter.hasNext()) { PKIXPolicyNode _child = (PKIXPolicyNode)_iter.next(); removePolicyNodeRecurse(policyNodes, _child); } } } protected static boolean processCertD1i( int index, List[] policyNodes, DERObjectIdentifier pOid, Set pq) { List policyNodeVec = policyNodes[index - 1]; for (int j = 0; j < policyNodeVec.size(); j++) { PKIXPolicyNode node = (PKIXPolicyNode)policyNodeVec.get(j); Set expectedPolicies = node.getExpectedPolicies(); if (expectedPolicies.contains(pOid.getId())) { Set childExpectedPolicies = new HashSet(); childExpectedPolicies.add(pOid.getId()); PKIXPolicyNode child = new PKIXPolicyNode(new ArrayList(), index, childExpectedPolicies, node, pq, pOid.getId(), false); node.addChild(child); policyNodes[index].add(child); return true; } } return false; } protected static void processCertD1ii( int index, List[] policyNodes, DERObjectIdentifier _poid, Set _pq) { List policyNodeVec = policyNodes[index - 1]; for (int j = 0; j < policyNodeVec.size(); j++) { PKIXPolicyNode _node = (PKIXPolicyNode)policyNodeVec.get(j); if (ANY_POLICY.equals(_node.getValidPolicy())) { Set _childExpectedPolicies = new HashSet(); _childExpectedPolicies.add(_poid.getId()); PKIXPolicyNode _child = new PKIXPolicyNode(new ArrayList(), index, _childExpectedPolicies, _node, _pq, _poid.getId(), false); _node.addChild(_child); policyNodes[index].add(_child); return; } } } protected static void prepareNextCertB1( int i, List[] policyNodes, String id_p, Map m_idp, X509Certificate cert ) throws AnnotatedException, CertPathValidatorException { boolean idp_found = false; Iterator nodes_i = policyNodes[i].iterator(); while (nodes_i.hasNext()) { PKIXPolicyNode node = (PKIXPolicyNode)nodes_i.next(); if (node.getValidPolicy().equals(id_p)) { idp_found = true; node.expectedPolicies = (Set)m_idp.get(id_p); break; } } if (!idp_found) { nodes_i = policyNodes[i].iterator(); while (nodes_i.hasNext()) { PKIXPolicyNode node = (PKIXPolicyNode)nodes_i.next(); if (ANY_POLICY.equals(node.getValidPolicy())) { Set pq = null; ASN1Sequence policies = null; try { policies = DERSequence.getInstance(getExtensionValue(cert, CERTIFICATE_POLICIES)); } catch (Exception e) { throw new AnnotatedException("Certificate policies cannot be decoded.", e); } Enumeration e = policies.getObjects(); while (e.hasMoreElements()) { PolicyInformation pinfo = null; try { pinfo = PolicyInformation.getInstance(e.nextElement()); } catch (Exception ex) { throw new AnnotatedException("Policy information cannot be decoded.", ex); } if (ANY_POLICY.equals(pinfo.getPolicyIdentifier().getId())) { try { pq = getQualifierSet(pinfo.getPolicyQualifiers()); } catch (CertPathValidatorException ex) { throw new ExtCertPathValidatorException( "Policy qualifier info set could not be built.", ex); } break; } } boolean ci = false; if (cert.getCriticalExtensionOIDs() != null) { ci = cert.getCriticalExtensionOIDs().contains(CERTIFICATE_POLICIES); } PKIXPolicyNode p_node = (PKIXPolicyNode)node.getParent(); if (ANY_POLICY.equals(p_node.getValidPolicy())) { PKIXPolicyNode c_node = new PKIXPolicyNode( new ArrayList(), i, (Set)m_idp.get(id_p), p_node, pq, id_p, ci); p_node.addChild(c_node); policyNodes[i].add(c_node); } break; } } } } protected static PKIXPolicyNode prepareNextCertB2( int i, List[] policyNodes, String id_p, PKIXPolicyNode validPolicyTree) { Iterator nodes_i = policyNodes[i].iterator(); while (nodes_i.hasNext()) { PKIXPolicyNode node = (PKIXPolicyNode)nodes_i.next(); if (node.getValidPolicy().equals(id_p)) { PKIXPolicyNode p_node = (PKIXPolicyNode)node.getParent(); p_node.removeChild(node); nodes_i.remove(); for (int k = (i - 1); k >= 0; k--) { List nodes = policyNodes[k]; for (int l = 0; l < nodes.size(); l++) { PKIXPolicyNode node2 = (PKIXPolicyNode)nodes.get(l); if (!node2.hasChildren()) { validPolicyTree = removePolicyNode(validPolicyTree, policyNodes, node2); if (validPolicyTree == null) { break; } } } } } } return validPolicyTree; } protected static boolean isAnyPolicy( Set policySet) { return policySet == null || policySet.contains(ANY_POLICY) || policySet.isEmpty(); } protected static void addAdditionalStoreFromLocation(String location, ExtendedPKIXParameters pkixParams) { if (pkixParams.isAdditionalLocationsEnabled()) { try { if (location.startsWith("ldap://")) { // ldap://directory.d-trust.net/CN=D-TRUST // Qualified CA 2003 1:PN,O=D-Trust GmbH,C=DE // skip "ldap://" location = location.substring(7); // after first / baseDN starts String base = null; String url = null; if (location.indexOf("/") != -1) { base = location.substring(location.indexOf("/")); // URL url = "ldap://" + location.substring(0, location.indexOf("/")); } else { url = "ldap://" + location; } // use all purpose parameters X509LDAPCertStoreParameters params = new X509LDAPCertStoreParameters.Builder( url, base).build(); pkixParams.addAdditionalStore(X509Store.getInstance( "CERTIFICATE/LDAP", params, BouncyCastleProvider.PROVIDER_NAME)); pkixParams.addAdditionalStore(X509Store.getInstance( "CRL/LDAP", params, BouncyCastleProvider.PROVIDER_NAME)); pkixParams.addAdditionalStore(X509Store.getInstance( "ATTRIBUTECERTIFICATE/LDAP", params, BouncyCastleProvider.PROVIDER_NAME)); pkixParams.addAdditionalStore(X509Store.getInstance( "CERTIFICATEPAIR/LDAP", params, BouncyCastleProvider.PROVIDER_NAME)); } } catch (Exception e) { // cannot happen throw new RuntimeException("Exception adding X.509 stores."); } } } /** * Return a Collection of all certificates or attribute certificates found * in the X509Store's that are matching the certSelect criteriums. * * @param certSelect a {@link Selector} object that will be used to select * the certificates * @param certStores a List containing only {@link X509Store} objects. These * are used to search for certificates. * @return a Collection of all found {@link X509Certificate} or * {@link org.bouncycastle.x509.X509AttributeCertificate} objects. * May be empty but never null. */ protected static Collection findCertificates(X509CertStoreSelector certSelect, List certStores) throws AnnotatedException { Set certs = new HashSet(); Iterator iter = certStores.iterator(); while (iter.hasNext()) { Object obj = iter.next(); if (obj instanceof X509Store) { X509Store certStore = (X509Store)obj; try { certs.addAll(certStore.getMatches(certSelect)); } catch (StoreException e) { throw new AnnotatedException( "Problem while picking certificates from X.509 store.", e); } } else { CertStore certStore = (CertStore)obj; try { certs.addAll(certStore.getCertificates(certSelect)); } catch (CertStoreException e) { throw new AnnotatedException( "Problem while picking certificates from certificate store.", e); } } } return certs; } protected static Collection findCertificates(X509AttributeCertStoreSelector certSelect, List certStores) throws AnnotatedException { Set certs = new HashSet(); Iterator iter = certStores.iterator(); while (iter.hasNext()) { Object obj = iter.next(); if (obj instanceof X509Store) { X509Store certStore = (X509Store)obj; try { certs.addAll(certStore.getMatches(certSelect)); } catch (StoreException e) { throw new AnnotatedException( "Problem while picking certificates from X.509 store.", e); } } } return certs; } protected static void addAdditionalStoresFromCRLDistributionPoint( CRLDistPoint crldp, ExtendedPKIXParameters pkixParams) throws AnnotatedException { if (crldp != null) { DistributionPoint dps[] = null; try { dps = crldp.getDistributionPoints(); } catch (Exception e) { throw new AnnotatedException( "Distribution points could not be read.", e); } for (int i = 0; i < dps.length; i++) { DistributionPointName dpn = dps[i].getDistributionPoint(); // look for URIs in fullName if (dpn != null) { if (dpn.getType() == DistributionPointName.FULL_NAME) { GeneralName[] genNames = GeneralNames.getInstance( dpn.getName()).getNames(); // look for an URI for (int j = 0; j < genNames.length; j++) { if (genNames[j].getTagNo() == GeneralName.uniformResourceIdentifier) { String location = DERIA5String.getInstance( genNames[j].getName()).getString(); CertPathValidatorUtilities .addAdditionalStoreFromLocation(location, pkixParams); } } } } } } } /** * Add the CRL issuers from the cRLIssuer field of the distribution point or * from the certificate if not given to the issuer criterion of the * selector. *

    * The issuerPrincipals are a collection with a single * X500Principal for X509Certificates. For * {@link X509AttributeCertificate}s the issuer may contain more than one * X500Principal. * * @param dp The distribution point. * @param issuerPrincipals The issuers of the certificate or attribute * certificate which contains the distribution point. * @param selector The CRL selector. * @param pkixParams The PKIX parameters containing the cert stores. * @throws AnnotatedException if an exception occurs while processing. * @throws ClassCastException if issuerPrincipals does not * contain only X500Principals. */ protected static void getCRLIssuersFromDistributionPoint( DistributionPoint dp, Collection issuerPrincipals, X509CRLSelector selector, ExtendedPKIXParameters pkixParams) throws AnnotatedException { List issuers = new ArrayList(); // indirect CRL if (dp.getCRLIssuer() != null) { GeneralName genNames[] = dp.getCRLIssuer().getNames(); // look for a DN for (int j = 0; j < genNames.length; j++) { if (genNames[j].getTagNo() == GeneralName.directoryName) { try { issuers.add(new X500Principal(genNames[j].getName() .toASN1Primitive().getEncoded())); } catch (IOException e) { throw new AnnotatedException( "CRL issuer information from distribution point cannot be decoded.", e); } } } } else { /* * certificate issuer is CRL issuer, distributionPoint field MUST be * present. */ if (dp.getDistributionPoint() == null) { throw new AnnotatedException( "CRL issuer is omitted from distribution point but no distributionPoint field present."); } // add and check issuer principals for (Iterator it = issuerPrincipals.iterator(); it.hasNext(); ) { issuers.add((X500Principal)it.next()); } } // TODO: is not found although this should correctly add the rel name. selector of Sun is buggy here or PKI test case is invalid // distributionPoint // if (dp.getDistributionPoint() != null) // { // // look for nameRelativeToCRLIssuer // if (dp.getDistributionPoint().getType() == DistributionPointName.NAME_RELATIVE_TO_CRL_ISSUER) // { // // append fragment to issuer, only one // // issuer can be there, if this is given // if (issuers.size() != 1) // { // throw new AnnotatedException( // "nameRelativeToCRLIssuer field is given but more than one CRL issuer is given."); // } // ASN1Encodable relName = dp.getDistributionPoint().getName(); // Iterator it = issuers.iterator(); // List issuersTemp = new ArrayList(issuers.size()); // while (it.hasNext()) // { // Enumeration e = null; // try // { // e = ASN1Sequence.getInstance( // new ASN1InputStream(((X500Principal) it.next()) // .getEncoded()).readObject()).getObjects(); // } // catch (IOException ex) // { // throw new AnnotatedException( // "Cannot decode CRL issuer information.", ex); // } // ASN1EncodableVector v = new ASN1EncodableVector(); // while (e.hasMoreElements()) // { // v.add((ASN1Encodable) e.nextElement()); // } // v.add(relName); // issuersTemp.add(new X500Principal(new DERSequence(v) // .getDEREncoded())); // } // issuers.clear(); // issuers.addAll(issuersTemp); // } // } Iterator it = issuers.iterator(); while (it.hasNext()) { try { selector.addIssuerName(((X500Principal)it.next()).getEncoded()); } catch (IOException ex) { throw new AnnotatedException( "Cannot decode CRL issuer information.", ex); } } } private static BigInteger getSerialNumber( Object cert) { if (cert instanceof X509Certificate) { return ((X509Certificate)cert).getSerialNumber(); } else { return ((X509AttributeCertificate)cert).getSerialNumber(); } } protected static void getCertStatus( Date validDate, X509CRL crl, Object cert, CertStatus certStatus) throws AnnotatedException { X509CRLEntry crl_entry = null; boolean isIndirect; try { isIndirect = X509CRLObject.isIndirectCRL(crl); } catch (CRLException exception) { throw new AnnotatedException("Failed check for indirect CRL.", exception); } if (isIndirect) { crl_entry = crl.getRevokedCertificate(getSerialNumber(cert)); if (crl_entry == null) { return; } X500Principal certIssuer = crl_entry.getCertificateIssuer(); if (certIssuer == null) { certIssuer = getIssuerPrincipal(crl); } if (!getEncodedIssuerPrincipal(cert).equals(certIssuer)) { return; } } else if (!getEncodedIssuerPrincipal(cert).equals(getIssuerPrincipal(crl))) { return; // not for our issuer, ignore } else { crl_entry = crl.getRevokedCertificate(getSerialNumber(cert)); if (crl_entry == null) { return; } } DEREnumerated reasonCode = null; if (crl_entry.hasExtensions()) { try { reasonCode = DEREnumerated .getInstance(CertPathValidatorUtilities .getExtensionValue(crl_entry, X509Extension.reasonCode.getId())); } catch (Exception e) { throw new AnnotatedException( "Reason code CRL entry extension could not be decoded.", e); } } // for reason keyCompromise, caCompromise, aACompromise or // unspecified if (!(validDate.getTime() < crl_entry.getRevocationDate().getTime()) || reasonCode == null || reasonCode.getValue().intValue() == 0 || reasonCode.getValue().intValue() == 1 || reasonCode.getValue().intValue() == 2 || reasonCode.getValue().intValue() == 8) { // (i) or (j) (1) if (reasonCode != null) { certStatus.setCertStatus(reasonCode.getValue().intValue()); } // (i) or (j) (2) else { certStatus.setCertStatus(CRLReason.unspecified); } certStatus.setRevocationDate(crl_entry.getRevocationDate()); } } /** * Fetches delta CRLs according to RFC 3280 section 5.2.4. * * @param currentDate The date for which the delta CRLs must be valid. * @param paramsPKIX The extended PKIX parameters. * @param completeCRL The complete CRL the delta CRL is for. * @return A Set of X509CRLs with delta CRLs. * @throws AnnotatedException if an exception occurs while picking the delta * CRLs. */ protected static Set getDeltaCRLs(Date currentDate, ExtendedPKIXParameters paramsPKIX, X509CRL completeCRL) throws AnnotatedException { X509CRLStoreSelector deltaSelect = new X509CRLStoreSelector(); // 5.2.4 (a) try { deltaSelect.addIssuerName(CertPathValidatorUtilities .getIssuerPrincipal(completeCRL).getEncoded()); } catch (IOException e) { throw new AnnotatedException("Cannot extract issuer from CRL.", e); } BigInteger completeCRLNumber = null; try { ASN1Primitive derObject = CertPathValidatorUtilities.getExtensionValue(completeCRL, CRL_NUMBER); if (derObject != null) { completeCRLNumber = ASN1Integer.getInstance(derObject).getPositiveValue(); } } catch (Exception e) { throw new AnnotatedException( "CRL number extension could not be extracted from CRL.", e); } // 5.2.4 (b) byte[] idp = null; try { idp = completeCRL.getExtensionValue(ISSUING_DISTRIBUTION_POINT); } catch (Exception e) { throw new AnnotatedException( "Issuing distribution point extension value could not be read.", e); } // 5.2.4 (d) deltaSelect.setMinCRLNumber(completeCRLNumber == null ? null : completeCRLNumber .add(BigInteger.valueOf(1))); deltaSelect.setIssuingDistributionPoint(idp); deltaSelect.setIssuingDistributionPointEnabled(true); // 5.2.4 (c) deltaSelect.setMaxBaseCRLNumber(completeCRLNumber); // find delta CRLs Set temp = CRL_UTIL.findCRLs(deltaSelect, paramsPKIX, currentDate); Set result = new HashSet(); for (Iterator it = temp.iterator(); it.hasNext(); ) { X509CRL crl = (X509CRL)it.next(); if (isDeltaCRL(crl)) { result.add(crl); } } return result; } private static boolean isDeltaCRL(X509CRL crl) { Set critical = crl.getCriticalExtensionOIDs(); if (critical == null) { return false; } return critical.contains(RFC3280CertPathUtilities.DELTA_CRL_INDICATOR); } /** * Fetches complete CRLs according to RFC 3280. * * @param dp The distribution point for which the complete CRL * @param cert The X509Certificate or * {@link org.bouncycastle.x509.X509AttributeCertificate} for * which the CRL should be searched. * @param currentDate The date for which the delta CRLs must be valid. * @param paramsPKIX The extended PKIX parameters. * @return A Set of X509CRLs with complete * CRLs. * @throws AnnotatedException if an exception occurs while picking the CRLs * or no CRLs are found. */ protected static Set getCompleteCRLs(DistributionPoint dp, Object cert, Date currentDate, ExtendedPKIXParameters paramsPKIX) throws AnnotatedException { X509CRLStoreSelector crlselect = new X509CRLStoreSelector(); try { Set issuers = new HashSet(); if (cert instanceof X509AttributeCertificate) { issuers.add(((X509AttributeCertificate)cert) .getIssuer().getPrincipals()[0]); } else { issuers.add(getEncodedIssuerPrincipal(cert)); } CertPathValidatorUtilities.getCRLIssuersFromDistributionPoint(dp, issuers, crlselect, paramsPKIX); } catch (AnnotatedException e) { throw new AnnotatedException( "Could not get issuer information from distribution point.", e); } if (cert instanceof X509Certificate) { crlselect.setCertificateChecking((X509Certificate)cert); } else if (cert instanceof X509AttributeCertificate) { crlselect.setAttrCertificateChecking((X509AttributeCertificate)cert); } crlselect.setCompleteCRLEnabled(true); Set crls = CRL_UTIL.findCRLs(crlselect, paramsPKIX, currentDate); if (crls.isEmpty()) { if (cert instanceof X509AttributeCertificate) { X509AttributeCertificate aCert = (X509AttributeCertificate)cert; throw new AnnotatedException("No CRLs found for issuer \"" + aCert.getIssuer().getPrincipals()[0] + "\""); } else { X509Certificate xCert = (X509Certificate)cert; throw new AnnotatedException("No CRLs found for issuer \"" + xCert.getIssuerX500Principal() + "\""); } } return crls; } protected static Date getValidCertDateFromValidityModel( ExtendedPKIXParameters paramsPKIX, CertPath certPath, int index) throws AnnotatedException { if (paramsPKIX.getValidityModel() == ExtendedPKIXParameters.CHAIN_VALIDITY_MODEL) { // if end cert use given signing/encryption/... time if (index <= 0) { return CertPathValidatorUtilities.getValidDate(paramsPKIX); // else use time when previous cert was created } else { if (index - 1 == 0) { DERGeneralizedTime dateOfCertgen = null; try { byte[] extBytes = ((X509Certificate)certPath.getCertificates().get(index - 1)).getExtensionValue(ISISMTTObjectIdentifiers.id_isismtt_at_dateOfCertGen.getId()); if (extBytes != null) { dateOfCertgen = DERGeneralizedTime.getInstance(ASN1Primitive.fromByteArray(extBytes)); } } catch (IOException e) { throw new AnnotatedException( "Date of cert gen extension could not be read."); } catch (IllegalArgumentException e) { throw new AnnotatedException( "Date of cert gen extension could not be read."); } if (dateOfCertgen != null) { try { return dateOfCertgen.getDate(); } catch (ParseException e) { throw new AnnotatedException( "Date from date of cert gen extension could not be parsed.", e); } } return ((X509Certificate)certPath.getCertificates().get( index - 1)).getNotBefore(); } else { return ((X509Certificate)certPath.getCertificates().get( index - 1)).getNotBefore(); } } } else { return getValidDate(paramsPKIX); } } /** * Return the next working key inheriting DSA parameters if necessary. *

    * This methods inherits DSA parameters from the indexed certificate or * previous certificates in the certificate chain to the returned * PublicKey. The list is searched upwards, meaning the end * certificate is at position 0 and previous certificates are following. *

    *

    * If the indexed certificate does not contain a DSA key this method simply * returns the public key. If the DSA key already contains DSA parameters * the key is also only returned. *

    * * @param certs The certification path. * @param index The index of the certificate which contains the public key * which should be extended with DSA parameters. * @return The public key of the certificate in list position * index extended with DSA parameters if applicable. * @throws AnnotatedException if DSA parameters cannot be inherited. */ protected static PublicKey getNextWorkingKey(List certs, int index) throws CertPathValidatorException { Certificate cert = (Certificate)certs.get(index); PublicKey pubKey = cert.getPublicKey(); if (!(pubKey instanceof DSAPublicKey)) { return pubKey; } DSAPublicKey dsaPubKey = (DSAPublicKey)pubKey; if (dsaPubKey.getParams() != null) { return dsaPubKey; } for (int i = index + 1; i < certs.size(); i++) { X509Certificate parentCert = (X509Certificate)certs.get(i); pubKey = parentCert.getPublicKey(); if (!(pubKey instanceof DSAPublicKey)) { throw new CertPathValidatorException( "DSA parameters cannot be inherited from previous certificate."); } DSAPublicKey prevDSAPubKey = (DSAPublicKey)pubKey; if (prevDSAPubKey.getParams() == null) { continue; } DSAParams dsaParams = prevDSAPubKey.getParams(); DSAPublicKeySpec dsaPubKeySpec = new DSAPublicKeySpec( dsaPubKey.getY(), dsaParams.getP(), dsaParams.getQ(), dsaParams.getG()); try { KeyFactory keyFactory = KeyFactory.getInstance("DSA", BouncyCastleProvider.PROVIDER_NAME); return keyFactory.generatePublic(dsaPubKeySpec); } catch (Exception exception) { throw new RuntimeException(exception.getMessage()); } } throw new CertPathValidatorException("DSA parameters cannot be inherited from previous certificate."); } /** * Find the issuer certificates of a given certificate. * * @param cert The certificate for which an issuer should be found. * @param pkixParams * @return A Collection object containing the issuer * X509Certificates. Never null. * @throws AnnotatedException if an error occurs. */ protected static Collection findIssuerCerts( X509Certificate cert, ExtendedPKIXBuilderParameters pkixParams) throws AnnotatedException { X509CertStoreSelector certSelect = new X509CertStoreSelector(); Set certs = new HashSet(); try { certSelect.setSubject(cert.getIssuerX500Principal().getEncoded()); } catch (IOException ex) { throw new AnnotatedException( "Subject criteria for certificate selector to find issuer certificate could not be set.", ex); } Iterator iter; try { List matches = new ArrayList(); matches.addAll(CertPathValidatorUtilities.findCertificates(certSelect, pkixParams.getCertStores())); matches.addAll(CertPathValidatorUtilities.findCertificates(certSelect, pkixParams.getStores())); matches.addAll(CertPathValidatorUtilities.findCertificates(certSelect, pkixParams.getAdditionalStores())); iter = matches.iterator(); } catch (AnnotatedException e) { throw new AnnotatedException("Issuer certificate cannot be searched.", e); } X509Certificate issuer = null; while (iter.hasNext()) { issuer = (X509Certificate)iter.next(); // issuer cannot be verified because possible DSA inheritance // parameters are missing certs.add(issuer); } return certs; } protected static void verifyX509Certificate(X509Certificate cert, PublicKey publicKey, String sigProvider) throws GeneralSecurityException { if (sigProvider == null) { cert.verify(publicKey); } else { cert.verify(publicKey, sigProvider); } } } bouncycastle-1.49.orig/src/org/bouncycastle/jce/provider/RFC3281CertPathUtilities.java0000644000175000017500000006640311625077510030234 0ustar ebourgebourgpackage org.bouncycastle.jce.provider; import java.io.IOException; import java.security.InvalidAlgorithmParameterException; import java.security.NoSuchAlgorithmException; import java.security.NoSuchProviderException; import java.security.Principal; import java.security.PublicKey; import java.security.cert.CertPath; import java.security.cert.CertPathBuilder; import java.security.cert.CertPathBuilderException; import java.security.cert.CertPathBuilderResult; import java.security.cert.CertPathValidator; import java.security.cert.CertPathValidatorException; import java.security.cert.CertPathValidatorResult; import java.security.cert.CertificateExpiredException; import java.security.cert.CertificateNotYetValidException; import java.security.cert.TrustAnchor; import java.security.cert.X509CRL; import java.security.cert.X509Certificate; import java.util.Date; import java.util.HashSet; import java.util.Iterator; import java.util.List; import java.util.Set; import javax.security.auth.x500.X500Principal; import org.bouncycastle.asn1.ASN1InputStream; import org.bouncycastle.asn1.ASN1Primitive; import org.bouncycastle.asn1.x509.CRLDistPoint; import org.bouncycastle.asn1.x509.CRLReason; import org.bouncycastle.asn1.x509.DistributionPoint; import org.bouncycastle.asn1.x509.DistributionPointName; import org.bouncycastle.asn1.x509.GeneralName; import org.bouncycastle.asn1.x509.GeneralNames; import org.bouncycastle.asn1.x509.TargetInformation; import org.bouncycastle.asn1.x509.X509Extensions; import org.bouncycastle.jce.exception.ExtCertPathValidatorException; import org.bouncycastle.x509.ExtendedPKIXBuilderParameters; import org.bouncycastle.x509.ExtendedPKIXParameters; import org.bouncycastle.x509.PKIXAttrCertChecker; import org.bouncycastle.x509.X509AttributeCertificate; import org.bouncycastle.x509.X509CertStoreSelector; class RFC3281CertPathUtilities { private static final String TARGET_INFORMATION = X509Extensions.TargetInformation .getId(); private static final String NO_REV_AVAIL = X509Extensions.NoRevAvail .getId(); private static final String CRL_DISTRIBUTION_POINTS = X509Extensions.CRLDistributionPoints .getId(); private static final String AUTHORITY_INFO_ACCESS = X509Extensions.AuthorityInfoAccess .getId(); protected static void processAttrCert7(X509AttributeCertificate attrCert, CertPath certPath, CertPath holderCertPath, ExtendedPKIXParameters pkixParams) throws CertPathValidatorException { // TODO: // AA Controls // Attribute encryption // Proxy Set set = attrCert.getCriticalExtensionOIDs(); // 7.1 // process extensions // target information checked in step 6 / X509AttributeCertStoreSelector if (set.contains(TARGET_INFORMATION)) { try { TargetInformation.getInstance(CertPathValidatorUtilities .getExtensionValue(attrCert, TARGET_INFORMATION)); } catch (AnnotatedException e) { throw new ExtCertPathValidatorException( "Target information extension could not be read.", e); } catch (IllegalArgumentException e) { throw new ExtCertPathValidatorException( "Target information extension could not be read.", e); } } set.remove(TARGET_INFORMATION); for (Iterator it = pkixParams.getAttrCertCheckers().iterator(); it .hasNext();) { ((PKIXAttrCertChecker) it.next()).check(attrCert, certPath, holderCertPath, set); } if (!set.isEmpty()) { throw new CertPathValidatorException( "Attribute certificate contains unsupported critical extensions: " + set); } } /** * Checks if an attribute certificate is revoked. * * @param attrCert Attribute certificate to check if it is revoked. * @param paramsPKIX PKIX parameters. * @param issuerCert The issuer certificate of the attribute certificate * attrCert. * @param validDate The date when the certificate revocation status should * be checked. * @param certPathCerts The certificates of the certification path to be * checked. * * @throws CertPathValidatorException if the certificate is revoked or the * status cannot be checked or some error occurs. */ protected static void checkCRLs(X509AttributeCertificate attrCert, ExtendedPKIXParameters paramsPKIX, X509Certificate issuerCert, Date validDate, List certPathCerts) throws CertPathValidatorException { if (paramsPKIX.isRevocationEnabled()) { // check if revocation is available if (attrCert.getExtensionValue(NO_REV_AVAIL) == null) { CRLDistPoint crldp = null; try { crldp = CRLDistPoint.getInstance(CertPathValidatorUtilities .getExtensionValue(attrCert, CRL_DISTRIBUTION_POINTS)); } catch (AnnotatedException e) { throw new CertPathValidatorException( "CRL distribution point extension could not be read.", e); } try { CertPathValidatorUtilities .addAdditionalStoresFromCRLDistributionPoint(crldp, paramsPKIX); } catch (AnnotatedException e) { throw new CertPathValidatorException( "No additional CRL locations could be decoded from CRL distribution point extension.", e); } CertStatus certStatus = new CertStatus(); ReasonsMask reasonsMask = new ReasonsMask(); AnnotatedException lastException = null; boolean validCrlFound = false; // for each distribution point if (crldp != null) { DistributionPoint dps[] = null; try { dps = crldp.getDistributionPoints(); } catch (Exception e) { throw new ExtCertPathValidatorException( "Distribution points could not be read.", e); } try { for (int i = 0; i < dps.length && certStatus.getCertStatus() == CertStatus.UNREVOKED && !reasonsMask.isAllReasons(); i++) { ExtendedPKIXParameters paramsPKIXClone = (ExtendedPKIXParameters) paramsPKIX .clone(); checkCRL(dps[i], attrCert, paramsPKIXClone, validDate, issuerCert, certStatus, reasonsMask, certPathCerts); validCrlFound = true; } } catch (AnnotatedException e) { lastException = new AnnotatedException( "No valid CRL for distribution point found.", e); } } /* * If the revocation status has not been determined, repeat the * process above with any available CRLs not specified in a * distribution point but issued by the certificate issuer. */ if (certStatus.getCertStatus() == CertStatus.UNREVOKED && !reasonsMask.isAllReasons()) { try { /* * assume a DP with both the reasons and the cRLIssuer * fields omitted and a distribution point name of the * certificate issuer. */ ASN1Primitive issuer = null; try { issuer = new ASN1InputStream( ((X500Principal) attrCert.getIssuer() .getPrincipals()[0]).getEncoded()) .readObject(); } catch (Exception e) { throw new AnnotatedException( "Issuer from certificate for CRL could not be reencoded.", e); } DistributionPoint dp = new DistributionPoint( new DistributionPointName(0, new GeneralNames( new GeneralName(GeneralName.directoryName, issuer))), null, null); ExtendedPKIXParameters paramsPKIXClone = (ExtendedPKIXParameters) paramsPKIX .clone(); checkCRL(dp, attrCert, paramsPKIXClone, validDate, issuerCert, certStatus, reasonsMask, certPathCerts); validCrlFound = true; } catch (AnnotatedException e) { lastException = new AnnotatedException( "No valid CRL for distribution point found.", e); } } if (!validCrlFound) { throw new ExtCertPathValidatorException( "No valid CRL found.", lastException); } if (certStatus.getCertStatus() != CertStatus.UNREVOKED) { String message = "Attribute certificate revocation after " + certStatus.getRevocationDate(); message += ", reason: " + RFC3280CertPathUtilities.crlReasons[certStatus .getCertStatus()]; throw new CertPathValidatorException(message); } if (!reasonsMask.isAllReasons() && certStatus.getCertStatus() == CertStatus.UNREVOKED) { certStatus.setCertStatus(CertStatus.UNDETERMINED); } if (certStatus.getCertStatus() == CertStatus.UNDETERMINED) { throw new CertPathValidatorException( "Attribute certificate status could not be determined."); } } else { if (attrCert.getExtensionValue(CRL_DISTRIBUTION_POINTS) != null || attrCert.getExtensionValue(AUTHORITY_INFO_ACCESS) != null) { throw new CertPathValidatorException( "No rev avail extension is set, but also an AC revocation pointer."); } } } } protected static void additionalChecks(X509AttributeCertificate attrCert, ExtendedPKIXParameters pkixParams) throws CertPathValidatorException { // 1 for (Iterator it = pkixParams.getProhibitedACAttributes().iterator(); it .hasNext();) { String oid = (String) it.next(); if (attrCert.getAttributes(oid) != null) { throw new CertPathValidatorException( "Attribute certificate contains prohibited attribute: " + oid + "."); } } for (Iterator it = pkixParams.getNecessaryACAttributes().iterator(); it .hasNext();) { String oid = (String) it.next(); if (attrCert.getAttributes(oid) == null) { throw new CertPathValidatorException( "Attribute certificate does not contain necessary attribute: " + oid + "."); } } } protected static void processAttrCert5(X509AttributeCertificate attrCert, ExtendedPKIXParameters pkixParams) throws CertPathValidatorException { try { attrCert.checkValidity(CertPathValidatorUtilities .getValidDate(pkixParams)); } catch (CertificateExpiredException e) { throw new ExtCertPathValidatorException( "Attribute certificate is not valid.", e); } catch (CertificateNotYetValidException e) { throw new ExtCertPathValidatorException( "Attribute certificate is not valid.", e); } } protected static void processAttrCert4(X509Certificate acIssuerCert, ExtendedPKIXParameters pkixParams) throws CertPathValidatorException { Set set = pkixParams.getTrustedACIssuers(); boolean trusted = false; for (Iterator it = set.iterator(); it.hasNext();) { TrustAnchor anchor = (TrustAnchor) it.next(); if (acIssuerCert.getSubjectX500Principal().getName("RFC2253") .equals(anchor.getCAName()) || acIssuerCert.equals(anchor.getTrustedCert())) { trusted = true; } } if (!trusted) { throw new CertPathValidatorException( "Attribute certificate issuer is not directly trusted."); } } protected static void processAttrCert3(X509Certificate acIssuerCert, ExtendedPKIXParameters pkixParams) throws CertPathValidatorException { if (acIssuerCert.getKeyUsage() != null && (!acIssuerCert.getKeyUsage()[0] && !acIssuerCert.getKeyUsage()[1])) { throw new CertPathValidatorException( "Attribute certificate issuer public key cannot be used to validate digital signatures."); } if (acIssuerCert.getBasicConstraints() != -1) { throw new CertPathValidatorException( "Attribute certificate issuer is also a public key certificate issuer."); } } protected static CertPathValidatorResult processAttrCert2( CertPath certPath, ExtendedPKIXParameters pkixParams) throws CertPathValidatorException { CertPathValidator validator = null; try { validator = CertPathValidator.getInstance("PKIX", BouncyCastleProvider.PROVIDER_NAME); } catch (NoSuchProviderException e) { throw new ExtCertPathValidatorException( "Support class could not be created.", e); } catch (NoSuchAlgorithmException e) { throw new ExtCertPathValidatorException( "Support class could not be created.", e); } try { return validator.validate(certPath, pkixParams); } catch (CertPathValidatorException e) { throw new ExtCertPathValidatorException( "Certification path for issuer certificate of attribute certificate could not be validated.", e); } catch (InvalidAlgorithmParameterException e) { // must be a programming error throw new RuntimeException(e.getMessage()); } } /** * Searches for a holder public key certificate and verifies its * certification path. * * @param attrCert the attribute certificate. * @param pkixParams The PKIX parameters. * @return The certificate path of the holder certificate. * @throws AnnotatedException if *
      *
    • no public key certificate can be found although holder * information is given by an entity name or a base certificate * ID *
    • support classes cannot be created *
    • no certification path for the public key certificate can * be built *
    */ protected static CertPath processAttrCert1( X509AttributeCertificate attrCert, ExtendedPKIXParameters pkixParams) throws CertPathValidatorException { CertPathBuilderResult result = null; // find holder PKCs Set holderPKCs = new HashSet(); if (attrCert.getHolder().getIssuer() != null) { X509CertStoreSelector selector = new X509CertStoreSelector(); selector.setSerialNumber(attrCert.getHolder().getSerialNumber()); Principal[] principals = attrCert.getHolder().getIssuer(); for (int i = 0; i < principals.length; i++) { try { if (principals[i] instanceof X500Principal) { selector.setIssuer(((X500Principal)principals[i]) .getEncoded()); } holderPKCs.addAll(CertPathValidatorUtilities .findCertificates(selector, pkixParams.getStores())); } catch (AnnotatedException e) { throw new ExtCertPathValidatorException( "Public key certificate for attribute certificate cannot be searched.", e); } catch (IOException e) { throw new ExtCertPathValidatorException( "Unable to encode X500 principal.", e); } } if (holderPKCs.isEmpty()) { throw new CertPathValidatorException( "Public key certificate specified in base certificate ID for attribute certificate cannot be found."); } } if (attrCert.getHolder().getEntityNames() != null) { X509CertStoreSelector selector = new X509CertStoreSelector(); Principal[] principals = attrCert.getHolder().getEntityNames(); for (int i = 0; i < principals.length; i++) { try { if (principals[i] instanceof X500Principal) { selector.setIssuer(((X500Principal) principals[i]) .getEncoded()); } holderPKCs.addAll(CertPathValidatorUtilities .findCertificates(selector, pkixParams.getStores())); } catch (AnnotatedException e) { throw new ExtCertPathValidatorException( "Public key certificate for attribute certificate cannot be searched.", e); } catch (IOException e) { throw new ExtCertPathValidatorException( "Unable to encode X500 principal.", e); } } if (holderPKCs.isEmpty()) { throw new CertPathValidatorException( "Public key certificate specified in entity name for attribute certificate cannot be found."); } } // verify cert paths for PKCs ExtendedPKIXBuilderParameters params = (ExtendedPKIXBuilderParameters) ExtendedPKIXBuilderParameters .getInstance(pkixParams); CertPathValidatorException lastException = null; for (Iterator it = holderPKCs.iterator(); it.hasNext();) { X509CertStoreSelector selector = new X509CertStoreSelector(); selector.setCertificate((X509Certificate) it.next()); params.setTargetConstraints(selector); CertPathBuilder builder = null; try { builder = CertPathBuilder.getInstance("PKIX", BouncyCastleProvider.PROVIDER_NAME); } catch (NoSuchProviderException e) { throw new ExtCertPathValidatorException( "Support class could not be created.", e); } catch (NoSuchAlgorithmException e) { throw new ExtCertPathValidatorException( "Support class could not be created.", e); } try { result = builder.build(ExtendedPKIXBuilderParameters .getInstance(params)); } catch (CertPathBuilderException e) { lastException = new ExtCertPathValidatorException( "Certification path for public key certificate of attribute certificate could not be build.", e); } catch (InvalidAlgorithmParameterException e) { // must be a programming error throw new RuntimeException(e.getMessage()); } } if (lastException != null) { throw lastException; } return result.getCertPath(); } /** * * Checks a distribution point for revocation information for the * certificate attrCert. * * @param dp The distribution point to consider. * @param attrCert The attribute certificate which should be checked. * @param paramsPKIX PKIX parameters. * @param validDate The date when the certificate revocation status should * be checked. * @param issuerCert Certificate to check if it is revoked. * @param reasonMask The reasons mask which is already checked. * @param certPathCerts The certificates of the certification path to be * checked. * @throws AnnotatedException if the certificate is revoked or the status * cannot be checked or some error occurs. */ private static void checkCRL(DistributionPoint dp, X509AttributeCertificate attrCert, ExtendedPKIXParameters paramsPKIX, Date validDate, X509Certificate issuerCert, CertStatus certStatus, ReasonsMask reasonMask, List certPathCerts) throws AnnotatedException { /* * 4.3.6 No Revocation Available * * The noRevAvail extension, defined in [X.509-2000], allows an AC * issuer to indicate that no revocation information will be made * available for this AC. */ if (attrCert.getExtensionValue(X509Extensions.NoRevAvail.getId()) != null) { return; } Date currentDate = new Date(System.currentTimeMillis()); if (validDate.getTime() > currentDate.getTime()) { throw new AnnotatedException("Validation time is in future."); } // (a) /* * We always get timely valid CRLs, so there is no step (a) (1). * "locally cached" CRLs are assumed to be in getStore(), additional * CRLs must be enabled in the ExtendedPKIXParameters and are in * getAdditionalStore() */ Set crls = CertPathValidatorUtilities.getCompleteCRLs(dp, attrCert, currentDate, paramsPKIX); boolean validCrlFound = false; AnnotatedException lastException = null; Iterator crl_iter = crls.iterator(); while (crl_iter.hasNext() && certStatus.getCertStatus() == CertStatus.UNREVOKED && !reasonMask.isAllReasons()) { try { X509CRL crl = (X509CRL) crl_iter.next(); // (d) ReasonsMask interimReasonsMask = RFC3280CertPathUtilities .processCRLD(crl, dp); // (e) /* * The reasons mask is updated at the end, so only valid CRLs * can update it. If this CRL does not contain new reasons it * must be ignored. */ if (!interimReasonsMask.hasNewReasons(reasonMask)) { continue; } // (f) Set keys = RFC3280CertPathUtilities.processCRLF(crl, attrCert, null, null, paramsPKIX, certPathCerts); // (g) PublicKey key = RFC3280CertPathUtilities.processCRLG(crl, keys); X509CRL deltaCRL = null; if (paramsPKIX.isUseDeltasEnabled()) { // get delta CRLs Set deltaCRLs = CertPathValidatorUtilities.getDeltaCRLs( currentDate, paramsPKIX, crl); // we only want one valid delta CRL // (h) deltaCRL = RFC3280CertPathUtilities.processCRLH(deltaCRLs, key); } /* * CRL must be be valid at the current time, not the validation * time. If a certificate is revoked with reason keyCompromise, * cACompromise, it can be used for forgery, also for the past. * This reason may not be contained in older CRLs. */ /* * in the chain model signatures stay valid also after the * certificate has been expired, so they do not have to be in * the CRL vality time */ if (paramsPKIX.getValidityModel() != ExtendedPKIXParameters.CHAIN_VALIDITY_MODEL) { /* * if a certificate has expired, but was revoked, it is not * more in the CRL, so it would be regarded as valid if the * first check is not done */ if (attrCert.getNotAfter().getTime() < crl.getThisUpdate() .getTime()) { throw new AnnotatedException( "No valid CRL for current time found."); } } RFC3280CertPathUtilities.processCRLB1(dp, attrCert, crl); // (b) (2) RFC3280CertPathUtilities.processCRLB2(dp, attrCert, crl); // (c) RFC3280CertPathUtilities.processCRLC(deltaCRL, crl, paramsPKIX); // (i) RFC3280CertPathUtilities.processCRLI(validDate, deltaCRL, attrCert, certStatus, paramsPKIX); // (j) RFC3280CertPathUtilities.processCRLJ(validDate, crl, attrCert, certStatus); // (k) if (certStatus.getCertStatus() == CRLReason.removeFromCRL) { certStatus.setCertStatus(CertStatus.UNREVOKED); } // update reasons mask reasonMask.addReasons(interimReasonsMask); validCrlFound = true; } catch (AnnotatedException e) { lastException = e; } } if (!validCrlFound) { throw lastException; } } } bouncycastle-1.49.orig/src/org/bouncycastle/jce/provider/JCERSAPrivateKey.java0000644000175000017500000000731212103437527026722 0ustar ebourgebourgpackage org.bouncycastle.jce.provider; import java.io.IOException; import java.io.ObjectInputStream; import java.io.ObjectOutputStream; import java.math.BigInteger; import java.security.interfaces.RSAPrivateKey; import java.security.spec.RSAPrivateKeySpec; import java.util.Enumeration; import org.bouncycastle.asn1.ASN1Encodable; import org.bouncycastle.asn1.ASN1ObjectIdentifier; import org.bouncycastle.asn1.DERNull; import org.bouncycastle.asn1.pkcs.PKCSObjectIdentifiers; import org.bouncycastle.asn1.x509.AlgorithmIdentifier; import org.bouncycastle.crypto.params.RSAKeyParameters; import org.bouncycastle.jcajce.provider.asymmetric.util.KeyUtil; import org.bouncycastle.jcajce.provider.asymmetric.util.PKCS12BagAttributeCarrierImpl; import org.bouncycastle.jce.interfaces.PKCS12BagAttributeCarrier; public class JCERSAPrivateKey implements RSAPrivateKey, PKCS12BagAttributeCarrier { static final long serialVersionUID = 5110188922551353628L; private static BigInteger ZERO = BigInteger.valueOf(0); protected BigInteger modulus; protected BigInteger privateExponent; private PKCS12BagAttributeCarrierImpl attrCarrier = new PKCS12BagAttributeCarrierImpl(); protected JCERSAPrivateKey() { } JCERSAPrivateKey( RSAKeyParameters key) { this.modulus = key.getModulus(); this.privateExponent = key.getExponent(); } JCERSAPrivateKey( RSAPrivateKeySpec spec) { this.modulus = spec.getModulus(); this.privateExponent = spec.getPrivateExponent(); } JCERSAPrivateKey( RSAPrivateKey key) { this.modulus = key.getModulus(); this.privateExponent = key.getPrivateExponent(); } public BigInteger getModulus() { return modulus; } public BigInteger getPrivateExponent() { return privateExponent; } public String getAlgorithm() { return "RSA"; } public String getFormat() { return "PKCS#8"; } public byte[] getEncoded() { return KeyUtil.getEncodedPrivateKeyInfo(new AlgorithmIdentifier(PKCSObjectIdentifiers.rsaEncryption, DERNull.INSTANCE), new org.bouncycastle.asn1.pkcs.RSAPrivateKey(getModulus(), ZERO, getPrivateExponent(), ZERO, ZERO, ZERO, ZERO, ZERO)); } public boolean equals(Object o) { if (!(o instanceof RSAPrivateKey)) { return false; } if (o == this) { return true; } RSAPrivateKey key = (RSAPrivateKey)o; return getModulus().equals(key.getModulus()) && getPrivateExponent().equals(key.getPrivateExponent()); } public int hashCode() { return getModulus().hashCode() ^ getPrivateExponent().hashCode(); } public void setBagAttribute( ASN1ObjectIdentifier oid, ASN1Encodable attribute) { attrCarrier.setBagAttribute(oid, attribute); } public ASN1Encodable getBagAttribute( ASN1ObjectIdentifier oid) { return attrCarrier.getBagAttribute(oid); } public Enumeration getBagAttributeKeys() { return attrCarrier.getBagAttributeKeys(); } private void readObject( ObjectInputStream in) throws IOException, ClassNotFoundException { this.modulus = (BigInteger)in.readObject(); this.attrCarrier = new PKCS12BagAttributeCarrierImpl(); attrCarrier.readObject(in); this.privateExponent = (BigInteger)in.readObject(); } private void writeObject( ObjectOutputStream out) throws IOException { out.writeObject(modulus); attrCarrier.writeObject(out); out.writeObject(privateExponent); } } bouncycastle-1.49.orig/src/org/bouncycastle/jce/provider/X509CertParser.java0000644000175000017500000001045711737273736026427 0ustar ebourgebourgpackage org.bouncycastle.jce.provider; import java.io.BufferedInputStream; import java.io.IOException; import java.io.InputStream; import java.security.cert.Certificate; import java.security.cert.CertificateParsingException; import java.util.ArrayList; import java.util.Collection; import java.util.List; import org.bouncycastle.asn1.ASN1InputStream; import org.bouncycastle.asn1.ASN1Sequence; import org.bouncycastle.asn1.ASN1Set; import org.bouncycastle.asn1.ASN1TaggedObject; import org.bouncycastle.asn1.DERObjectIdentifier; import org.bouncycastle.asn1.pkcs.PKCSObjectIdentifiers; import org.bouncycastle.asn1.pkcs.SignedData; import org.bouncycastle.x509.X509StreamParserSpi; import org.bouncycastle.x509.util.StreamParsingException; public class X509CertParser extends X509StreamParserSpi { private static final PEMUtil PEM_PARSER = new PEMUtil("CERTIFICATE"); private ASN1Set sData = null; private int sDataObjectCount = 0; private InputStream currentStream = null; private Certificate readDERCertificate( InputStream in) throws IOException, CertificateParsingException { ASN1InputStream dIn = new ASN1InputStream(in); ASN1Sequence seq = (ASN1Sequence)dIn.readObject(); if (seq.size() > 1 && seq.getObjectAt(0) instanceof DERObjectIdentifier) { if (seq.getObjectAt(0).equals(PKCSObjectIdentifiers.signedData)) { sData = new SignedData(ASN1Sequence.getInstance( (ASN1TaggedObject)seq.getObjectAt(1), true)).getCertificates(); return getCertificate(); } } return new X509CertificateObject( org.bouncycastle.asn1.x509.Certificate.getInstance(seq)); } private Certificate getCertificate() throws CertificateParsingException { if (sData != null) { while (sDataObjectCount < sData.size()) { Object obj = sData.getObjectAt(sDataObjectCount++); if (obj instanceof ASN1Sequence) { return new X509CertificateObject( org.bouncycastle.asn1.x509.Certificate.getInstance(obj)); } } } return null; } private Certificate readPEMCertificate( InputStream in) throws IOException, CertificateParsingException { ASN1Sequence seq = PEM_PARSER.readPEMObject(in); if (seq != null) { return new X509CertificateObject( org.bouncycastle.asn1.x509.Certificate.getInstance(seq)); } return null; } public void engineInit(InputStream in) { currentStream = in; sData = null; sDataObjectCount = 0; if (!currentStream.markSupported()) { currentStream = new BufferedInputStream(currentStream); } } public Object engineRead() throws StreamParsingException { try { if (sData != null) { if (sDataObjectCount != sData.size()) { return getCertificate(); } else { sData = null; sDataObjectCount = 0; return null; } } currentStream.mark(10); int tag = currentStream.read(); if (tag == -1) { return null; } if (tag != 0x30) // assume ascii PEM encoded. { currentStream.reset(); return readPEMCertificate(currentStream); } else { currentStream.reset(); return readDERCertificate(currentStream); } } catch (Exception e) { throw new StreamParsingException(e.toString(), e); } } public Collection engineReadAll() throws StreamParsingException { Certificate cert; List certs = new ArrayList(); while ((cert = (Certificate)engineRead()) != null) { certs.add(cert); } return certs; } } bouncycastle-1.49.orig/src/org/bouncycastle/jce/provider/X509CertPairParser.java0000644000175000017500000000400411701453716027217 0ustar ebourgebourgpackage org.bouncycastle.jce.provider; import java.io.BufferedInputStream; import java.io.IOException; import java.io.InputStream; import java.security.cert.CertificateParsingException; import java.util.ArrayList; import java.util.Collection; import java.util.List; import org.bouncycastle.asn1.ASN1InputStream; import org.bouncycastle.asn1.ASN1Sequence; import org.bouncycastle.asn1.x509.CertificatePair; import org.bouncycastle.x509.X509CertificatePair; import org.bouncycastle.x509.X509StreamParserSpi; import org.bouncycastle.x509.util.StreamParsingException; public class X509CertPairParser extends X509StreamParserSpi { private InputStream currentStream = null; private X509CertificatePair readDERCrossCertificatePair( InputStream in) throws IOException, CertificateParsingException { ASN1InputStream dIn = new ASN1InputStream(in); ASN1Sequence seq = (ASN1Sequence)dIn.readObject(); CertificatePair pair = CertificatePair.getInstance(seq); return new X509CertificatePair(pair); } public void engineInit(InputStream in) { currentStream = in; if (!currentStream.markSupported()) { currentStream = new BufferedInputStream(currentStream); } } public Object engineRead() throws StreamParsingException { try { currentStream.mark(10); int tag = currentStream.read(); if (tag == -1) { return null; } currentStream.reset(); return readDERCrossCertificatePair(currentStream); } catch (Exception e) { throw new StreamParsingException(e.toString(), e); } } public Collection engineReadAll() throws StreamParsingException { X509CertificatePair pair; List certs = new ArrayList(); while ((pair = (X509CertificatePair)engineRead()) != null) { certs.add(pair); } return certs; } } bouncycastle-1.49.orig/src/org/bouncycastle/jce/provider/PKIXCertPathValidatorSpi.java0000644000175000017500000003541711625077543030514 0ustar ebourgebourgpackage org.bouncycastle.jce.provider; import java.security.InvalidAlgorithmParameterException; import java.security.PublicKey; import java.security.cert.CertPath; import java.security.cert.CertPathParameters; import java.security.cert.CertPathValidatorException; import java.security.cert.CertPathValidatorResult; import java.security.cert.CertPathValidatorSpi; import java.security.cert.PKIXCertPathChecker; import java.security.cert.PKIXCertPathValidatorResult; import java.security.cert.PKIXParameters; import java.security.cert.TrustAnchor; import java.security.cert.X509Certificate; import java.util.ArrayList; import java.util.HashSet; import java.util.Iterator; import java.util.List; import java.util.Set; import javax.security.auth.x500.X500Principal; import org.bouncycastle.asn1.ASN1Encodable; import org.bouncycastle.asn1.DERObjectIdentifier; import org.bouncycastle.asn1.x509.AlgorithmIdentifier; import org.bouncycastle.jce.exception.ExtCertPathValidatorException; import org.bouncycastle.x509.ExtendedPKIXParameters; /** * CertPathValidatorSpi implementation for X.509 Certificate validation � la RFC * 3280. */ public class PKIXCertPathValidatorSpi extends CertPathValidatorSpi { public CertPathValidatorResult engineValidate( CertPath certPath, CertPathParameters params) throws CertPathValidatorException, InvalidAlgorithmParameterException { if (!(params instanceof PKIXParameters)) { throw new InvalidAlgorithmParameterException("Parameters must be a " + PKIXParameters.class.getName() + " instance."); } ExtendedPKIXParameters paramsPKIX; if (params instanceof ExtendedPKIXParameters) { paramsPKIX = (ExtendedPKIXParameters)params; } else { paramsPKIX = ExtendedPKIXParameters.getInstance((PKIXParameters)params); } if (paramsPKIX.getTrustAnchors() == null) { throw new InvalidAlgorithmParameterException( "trustAnchors is null, this is not allowed for certification path validation."); } // // 6.1.1 - inputs // // // (a) // List certs = certPath.getCertificates(); int n = certs.size(); if (certs.isEmpty()) { throw new CertPathValidatorException("Certification path is empty.", null, certPath, 0); } // // (b) // // Date validDate = CertPathValidatorUtilities.getValidDate(paramsPKIX); // // (c) // Set userInitialPolicySet = paramsPKIX.getInitialPolicies(); // // (d) // TrustAnchor trust; try { trust = CertPathValidatorUtilities.findTrustAnchor((X509Certificate) certs.get(certs.size() - 1), paramsPKIX.getTrustAnchors(), paramsPKIX.getSigProvider()); } catch (AnnotatedException e) { throw new CertPathValidatorException(e.getMessage(), e, certPath, certs.size() - 1); } if (trust == null) { throw new CertPathValidatorException("Trust anchor for certification path not found.", null, certPath, -1); } // // (e), (f), (g) are part of the paramsPKIX object. // Iterator certIter; int index = 0; int i; // Certificate for each interation of the validation loop // Signature information for each iteration of the validation loop // // 6.1.2 - setup // // // (a) // List[] policyNodes = new ArrayList[n + 1]; for (int j = 0; j < policyNodes.length; j++) { policyNodes[j] = new ArrayList(); } Set policySet = new HashSet(); policySet.add(RFC3280CertPathUtilities.ANY_POLICY); PKIXPolicyNode validPolicyTree = new PKIXPolicyNode(new ArrayList(), 0, policySet, null, new HashSet(), RFC3280CertPathUtilities.ANY_POLICY, false); policyNodes[0].add(validPolicyTree); // // (b) and (c) // PKIXNameConstraintValidator nameConstraintValidator = new PKIXNameConstraintValidator(); // (d) // int explicitPolicy; Set acceptablePolicies = new HashSet(); if (paramsPKIX.isExplicitPolicyRequired()) { explicitPolicy = 0; } else { explicitPolicy = n + 1; } // // (e) // int inhibitAnyPolicy; if (paramsPKIX.isAnyPolicyInhibited()) { inhibitAnyPolicy = 0; } else { inhibitAnyPolicy = n + 1; } // // (f) // int policyMapping; if (paramsPKIX.isPolicyMappingInhibited()) { policyMapping = 0; } else { policyMapping = n + 1; } // // (g), (h), (i), (j) // PublicKey workingPublicKey; X500Principal workingIssuerName; X509Certificate sign = trust.getTrustedCert(); try { if (sign != null) { workingIssuerName = CertPathValidatorUtilities.getSubjectPrincipal(sign); workingPublicKey = sign.getPublicKey(); } else { workingIssuerName = new X500Principal(trust.getCAName()); workingPublicKey = trust.getCAPublicKey(); } } catch (IllegalArgumentException ex) { throw new ExtCertPathValidatorException("Subject of trust anchor could not be (re)encoded.", ex, certPath, -1); } AlgorithmIdentifier workingAlgId = null; try { workingAlgId = CertPathValidatorUtilities.getAlgorithmIdentifier(workingPublicKey); } catch (CertPathValidatorException e) { throw new ExtCertPathValidatorException( "Algorithm identifier of public key of trust anchor could not be read.", e, certPath, -1); } DERObjectIdentifier workingPublicKeyAlgorithm = workingAlgId.getObjectId(); ASN1Encodable workingPublicKeyParameters = workingAlgId.getParameters(); // // (k) // int maxPathLength = n; // // 6.1.3 // if (paramsPKIX.getTargetConstraints() != null && !paramsPKIX.getTargetConstraints().match((X509Certificate) certs.get(0))) { throw new ExtCertPathValidatorException( "Target certificate in certification path does not match targetConstraints.", null, certPath, 0); } // // initialize CertPathChecker's // List pathCheckers = paramsPKIX.getCertPathCheckers(); certIter = pathCheckers.iterator(); while (certIter.hasNext()) { ((PKIXCertPathChecker) certIter.next()).init(false); } X509Certificate cert = null; for (index = certs.size() - 1; index >= 0; index--) { // try // { // // i as defined in the algorithm description // i = n - index; // // set certificate to be checked in this round // sign and workingPublicKey and workingIssuerName are set // at the end of the for loop and initialized the // first time from the TrustAnchor // cert = (X509Certificate) certs.get(index); boolean verificationAlreadyPerformed = (index == certs.size() - 1); // // 6.1.3 // RFC3280CertPathUtilities.processCertA(certPath, paramsPKIX, index, workingPublicKey, verificationAlreadyPerformed, workingIssuerName, sign); RFC3280CertPathUtilities.processCertBC(certPath, index, nameConstraintValidator); validPolicyTree = RFC3280CertPathUtilities.processCertD(certPath, index, acceptablePolicies, validPolicyTree, policyNodes, inhibitAnyPolicy); validPolicyTree = RFC3280CertPathUtilities.processCertE(certPath, index, validPolicyTree); RFC3280CertPathUtilities.processCertF(certPath, index, validPolicyTree, explicitPolicy); // // 6.1.4 // if (i != n) { if (cert != null && cert.getVersion() == 1) { throw new CertPathValidatorException("Version 1 certificates can't be used as CA ones.", null, certPath, index); } RFC3280CertPathUtilities.prepareNextCertA(certPath, index); validPolicyTree = RFC3280CertPathUtilities.prepareCertB(certPath, index, policyNodes, validPolicyTree, policyMapping); RFC3280CertPathUtilities.prepareNextCertG(certPath, index, nameConstraintValidator); // (h) explicitPolicy = RFC3280CertPathUtilities.prepareNextCertH1(certPath, index, explicitPolicy); policyMapping = RFC3280CertPathUtilities.prepareNextCertH2(certPath, index, policyMapping); inhibitAnyPolicy = RFC3280CertPathUtilities.prepareNextCertH3(certPath, index, inhibitAnyPolicy); // // (i) // explicitPolicy = RFC3280CertPathUtilities.prepareNextCertI1(certPath, index, explicitPolicy); policyMapping = RFC3280CertPathUtilities.prepareNextCertI2(certPath, index, policyMapping); // (j) inhibitAnyPolicy = RFC3280CertPathUtilities.prepareNextCertJ(certPath, index, inhibitAnyPolicy); // (k) RFC3280CertPathUtilities.prepareNextCertK(certPath, index); // (l) maxPathLength = RFC3280CertPathUtilities.prepareNextCertL(certPath, index, maxPathLength); // (m) maxPathLength = RFC3280CertPathUtilities.prepareNextCertM(certPath, index, maxPathLength); // (n) RFC3280CertPathUtilities.prepareNextCertN(certPath, index); Set criticalExtensions = cert.getCriticalExtensionOIDs(); if (criticalExtensions != null) { criticalExtensions = new HashSet(criticalExtensions); // these extensions are handled by the algorithm criticalExtensions.remove(RFC3280CertPathUtilities.KEY_USAGE); criticalExtensions.remove(RFC3280CertPathUtilities.CERTIFICATE_POLICIES); criticalExtensions.remove(RFC3280CertPathUtilities.POLICY_MAPPINGS); criticalExtensions.remove(RFC3280CertPathUtilities.INHIBIT_ANY_POLICY); criticalExtensions.remove(RFC3280CertPathUtilities.ISSUING_DISTRIBUTION_POINT); criticalExtensions.remove(RFC3280CertPathUtilities.DELTA_CRL_INDICATOR); criticalExtensions.remove(RFC3280CertPathUtilities.POLICY_CONSTRAINTS); criticalExtensions.remove(RFC3280CertPathUtilities.BASIC_CONSTRAINTS); criticalExtensions.remove(RFC3280CertPathUtilities.SUBJECT_ALTERNATIVE_NAME); criticalExtensions.remove(RFC3280CertPathUtilities.NAME_CONSTRAINTS); } else { criticalExtensions = new HashSet(); } // (o) RFC3280CertPathUtilities.prepareNextCertO(certPath, index, criticalExtensions, pathCheckers); // set signing certificate for next round sign = cert; // (c) workingIssuerName = CertPathValidatorUtilities.getSubjectPrincipal(sign); // (d) try { workingPublicKey = CertPathValidatorUtilities.getNextWorkingKey(certPath.getCertificates(), index); } catch (CertPathValidatorException e) { throw new CertPathValidatorException("Next working key could not be retrieved.", e, certPath, index); } workingAlgId = CertPathValidatorUtilities.getAlgorithmIdentifier(workingPublicKey); // (f) workingPublicKeyAlgorithm = workingAlgId.getObjectId(); // (e) workingPublicKeyParameters = workingAlgId.getParameters(); } } // // 6.1.5 Wrap-up procedure // explicitPolicy = RFC3280CertPathUtilities.wrapupCertA(explicitPolicy, cert); explicitPolicy = RFC3280CertPathUtilities.wrapupCertB(certPath, index + 1, explicitPolicy); // // (c) (d) and (e) are already done // // // (f) // Set criticalExtensions = cert.getCriticalExtensionOIDs(); if (criticalExtensions != null) { criticalExtensions = new HashSet(criticalExtensions); // these extensions are handled by the algorithm criticalExtensions.remove(RFC3280CertPathUtilities.KEY_USAGE); criticalExtensions.remove(RFC3280CertPathUtilities.CERTIFICATE_POLICIES); criticalExtensions.remove(RFC3280CertPathUtilities.POLICY_MAPPINGS); criticalExtensions.remove(RFC3280CertPathUtilities.INHIBIT_ANY_POLICY); criticalExtensions.remove(RFC3280CertPathUtilities.ISSUING_DISTRIBUTION_POINT); criticalExtensions.remove(RFC3280CertPathUtilities.DELTA_CRL_INDICATOR); criticalExtensions.remove(RFC3280CertPathUtilities.POLICY_CONSTRAINTS); criticalExtensions.remove(RFC3280CertPathUtilities.BASIC_CONSTRAINTS); criticalExtensions.remove(RFC3280CertPathUtilities.SUBJECT_ALTERNATIVE_NAME); criticalExtensions.remove(RFC3280CertPathUtilities.NAME_CONSTRAINTS); criticalExtensions.remove(RFC3280CertPathUtilities.CRL_DISTRIBUTION_POINTS); } else { criticalExtensions = new HashSet(); } RFC3280CertPathUtilities.wrapupCertF(certPath, index + 1, pathCheckers, criticalExtensions); PKIXPolicyNode intersection = RFC3280CertPathUtilities.wrapupCertG(certPath, paramsPKIX, userInitialPolicySet, index + 1, policyNodes, validPolicyTree, acceptablePolicies); if ((explicitPolicy > 0) || (intersection != null)) { return new PKIXCertPathValidatorResult(trust, intersection, cert.getPublicKey()); } throw new CertPathValidatorException("Path processing failed on policy.", null, certPath, index); } } bouncycastle-1.49.orig/src/org/bouncycastle/jce/provider/X509StoreCertCollection.java0000644000175000017500000000157311624652552030272 0ustar ebourgebourgpackage org.bouncycastle.jce.provider; import java.util.Collection; import org.bouncycastle.util.CollectionStore; import org.bouncycastle.util.Selector; import org.bouncycastle.x509.X509CollectionStoreParameters; import org.bouncycastle.x509.X509StoreParameters; import org.bouncycastle.x509.X509StoreSpi; public class X509StoreCertCollection extends X509StoreSpi { private CollectionStore _store; public X509StoreCertCollection() { } public void engineInit(X509StoreParameters params) { if (!(params instanceof X509CollectionStoreParameters)) { throw new IllegalArgumentException(params.toString()); } _store = new CollectionStore(((X509CollectionStoreParameters)params).getCollection()); } public Collection engineGetMatches(Selector selector) { return _store.getMatches(selector); } } bouncycastle-1.49.orig/src/org/bouncycastle/jce/provider/X509CertificateObject.java0000644000175000017500000006615312102612525027706 0ustar ebourgebourgpackage org.bouncycastle.jce.provider; import java.io.ByteArrayOutputStream; import java.io.IOException; import java.math.BigInteger; import java.net.InetAddress; import java.net.UnknownHostException; import java.security.InvalidKeyException; import java.security.NoSuchAlgorithmException; import java.security.NoSuchProviderException; import java.security.Principal; import java.security.Provider; import java.security.PublicKey; import java.security.Security; import java.security.Signature; import java.security.SignatureException; import java.security.cert.Certificate; import java.security.cert.CertificateEncodingException; import java.security.cert.CertificateException; import java.security.cert.CertificateExpiredException; import java.security.cert.CertificateNotYetValidException; import java.security.cert.CertificateParsingException; import java.security.cert.X509Certificate; import java.util.ArrayList; import java.util.Collection; import java.util.Collections; import java.util.Date; import java.util.Enumeration; import java.util.HashSet; import java.util.List; import java.util.Set; import javax.security.auth.x500.X500Principal; import org.bouncycastle.asn1.ASN1Encodable; import org.bouncycastle.asn1.ASN1Encoding; import org.bouncycastle.asn1.ASN1InputStream; import org.bouncycastle.asn1.ASN1ObjectIdentifier; import org.bouncycastle.asn1.ASN1OutputStream; import org.bouncycastle.asn1.ASN1Primitive; import org.bouncycastle.asn1.ASN1Sequence; import org.bouncycastle.asn1.ASN1String; import org.bouncycastle.asn1.DERBitString; import org.bouncycastle.asn1.DERIA5String; import org.bouncycastle.asn1.DERNull; import org.bouncycastle.asn1.DEROctetString; import org.bouncycastle.asn1.misc.MiscObjectIdentifiers; import org.bouncycastle.asn1.misc.NetscapeCertType; import org.bouncycastle.asn1.misc.NetscapeRevocationURL; import org.bouncycastle.asn1.misc.VerisignCzagExtension; import org.bouncycastle.asn1.util.ASN1Dump; import org.bouncycastle.asn1.x500.X500Name; import org.bouncycastle.asn1.x500.style.RFC4519Style; import org.bouncycastle.asn1.x509.AlgorithmIdentifier; import org.bouncycastle.asn1.x509.BasicConstraints; import org.bouncycastle.asn1.x509.Extension; import org.bouncycastle.asn1.x509.Extensions; import org.bouncycastle.asn1.x509.GeneralName; import org.bouncycastle.asn1.x509.KeyUsage; import org.bouncycastle.jcajce.provider.asymmetric.util.PKCS12BagAttributeCarrierImpl; import org.bouncycastle.jce.X509Principal; import org.bouncycastle.jce.interfaces.PKCS12BagAttributeCarrier; import org.bouncycastle.util.Arrays; import org.bouncycastle.util.Integers; import org.bouncycastle.util.encoders.Hex; public class X509CertificateObject extends X509Certificate implements PKCS12BagAttributeCarrier { private org.bouncycastle.asn1.x509.Certificate c; private BasicConstraints basicConstraints; private boolean[] keyUsage; private boolean hashValueSet; private int hashValue; private PKCS12BagAttributeCarrier attrCarrier = new PKCS12BagAttributeCarrierImpl(); public X509CertificateObject( org.bouncycastle.asn1.x509.Certificate c) throws CertificateParsingException { this.c = c; try { byte[] bytes = this.getExtensionBytes("2.5.29.19"); if (bytes != null) { basicConstraints = BasicConstraints.getInstance(ASN1Primitive.fromByteArray(bytes)); } } catch (Exception e) { throw new CertificateParsingException("cannot construct BasicConstraints: " + e); } try { byte[] bytes = this.getExtensionBytes("2.5.29.15"); if (bytes != null) { DERBitString bits = DERBitString.getInstance(ASN1Primitive.fromByteArray(bytes)); bytes = bits.getBytes(); int length = (bytes.length * 8) - bits.getPadBits(); keyUsage = new boolean[(length < 9) ? 9 : length]; for (int i = 0; i != length; i++) { keyUsage[i] = (bytes[i / 8] & (0x80 >>> (i % 8))) != 0; } } else { keyUsage = null; } } catch (Exception e) { throw new CertificateParsingException("cannot construct KeyUsage: " + e); } } public void checkValidity() throws CertificateExpiredException, CertificateNotYetValidException { this.checkValidity(new Date()); } public void checkValidity( Date date) throws CertificateExpiredException, CertificateNotYetValidException { if (date.getTime() > this.getNotAfter().getTime()) // for other VM compatibility { throw new CertificateExpiredException("certificate expired on " + c.getEndDate().getTime()); } if (date.getTime() < this.getNotBefore().getTime()) { throw new CertificateNotYetValidException("certificate not valid till " + c.getStartDate().getTime()); } } public int getVersion() { return c.getVersionNumber(); } public BigInteger getSerialNumber() { return c.getSerialNumber().getValue(); } public Principal getIssuerDN() { try { return new X509Principal(X500Name.getInstance(c.getIssuer().getEncoded())); } catch (IOException e) { return null; } } public X500Principal getIssuerX500Principal() { try { ByteArrayOutputStream bOut = new ByteArrayOutputStream(); ASN1OutputStream aOut = new ASN1OutputStream(bOut); aOut.writeObject(c.getIssuer()); return new X500Principal(bOut.toByteArray()); } catch (IOException e) { throw new IllegalStateException("can't encode issuer DN"); } } public Principal getSubjectDN() { return new X509Principal(X500Name.getInstance(c.getSubject().toASN1Primitive())); } public X500Principal getSubjectX500Principal() { try { ByteArrayOutputStream bOut = new ByteArrayOutputStream(); ASN1OutputStream aOut = new ASN1OutputStream(bOut); aOut.writeObject(c.getSubject()); return new X500Principal(bOut.toByteArray()); } catch (IOException e) { throw new IllegalStateException("can't encode issuer DN"); } } public Date getNotBefore() { return c.getStartDate().getDate(); } public Date getNotAfter() { return c.getEndDate().getDate(); } public byte[] getTBSCertificate() throws CertificateEncodingException { try { return c.getTBSCertificate().getEncoded(ASN1Encoding.DER); } catch (IOException e) { throw new CertificateEncodingException(e.toString()); } } public byte[] getSignature() { return c.getSignature().getBytes(); } /** * return a more "meaningful" representation for the signature algorithm used in * the certficate. */ public String getSigAlgName() { Provider prov = Security.getProvider(BouncyCastleProvider.PROVIDER_NAME); if (prov != null) { String algName = prov.getProperty("Alg.Alias.Signature." + this.getSigAlgOID()); if (algName != null) { return algName; } } Provider[] provs = Security.getProviders(); // // search every provider looking for a real algorithm // for (int i = 0; i != provs.length; i++) { String algName = provs[i].getProperty("Alg.Alias.Signature." + this.getSigAlgOID()); if (algName != null) { return algName; } } return this.getSigAlgOID(); } /** * return the object identifier for the signature. */ public String getSigAlgOID() { return c.getSignatureAlgorithm().getAlgorithm().getId(); } /** * return the signature parameters, or null if there aren't any. */ public byte[] getSigAlgParams() { if (c.getSignatureAlgorithm().getParameters() != null) { try { return c.getSignatureAlgorithm().getParameters().toASN1Primitive().getEncoded(ASN1Encoding.DER); } catch (IOException e) { return null; } } else { return null; } } public boolean[] getIssuerUniqueID() { DERBitString id = c.getTBSCertificate().getIssuerUniqueId(); if (id != null) { byte[] bytes = id.getBytes(); boolean[] boolId = new boolean[bytes.length * 8 - id.getPadBits()]; for (int i = 0; i != boolId.length; i++) { boolId[i] = (bytes[i / 8] & (0x80 >>> (i % 8))) != 0; } return boolId; } return null; } public boolean[] getSubjectUniqueID() { DERBitString id = c.getTBSCertificate().getSubjectUniqueId(); if (id != null) { byte[] bytes = id.getBytes(); boolean[] boolId = new boolean[bytes.length * 8 - id.getPadBits()]; for (int i = 0; i != boolId.length; i++) { boolId[i] = (bytes[i / 8] & (0x80 >>> (i % 8))) != 0; } return boolId; } return null; } public boolean[] getKeyUsage() { return keyUsage; } public List getExtendedKeyUsage() throws CertificateParsingException { byte[] bytes = this.getExtensionBytes("2.5.29.37"); if (bytes != null) { try { ASN1InputStream dIn = new ASN1InputStream(bytes); ASN1Sequence seq = (ASN1Sequence)dIn.readObject(); List list = new ArrayList(); for (int i = 0; i != seq.size(); i++) { list.add(((ASN1ObjectIdentifier)seq.getObjectAt(i)).getId()); } return Collections.unmodifiableList(list); } catch (Exception e) { throw new CertificateParsingException("error processing extended key usage extension"); } } return null; } public int getBasicConstraints() { if (basicConstraints != null) { if (basicConstraints.isCA()) { if (basicConstraints.getPathLenConstraint() == null) { return Integer.MAX_VALUE; } else { return basicConstraints.getPathLenConstraint().intValue(); } } else { return -1; } } return -1; } public Collection getSubjectAlternativeNames() throws CertificateParsingException { return getAlternativeNames(getExtensionBytes(Extension.subjectAlternativeName.getId())); } public Collection getIssuerAlternativeNames() throws CertificateParsingException { return getAlternativeNames(getExtensionBytes(Extension.issuerAlternativeName.getId())); } public Set getCriticalExtensionOIDs() { if (this.getVersion() == 3) { Set set = new HashSet(); Extensions extensions = c.getTBSCertificate().getExtensions(); if (extensions != null) { Enumeration e = extensions.oids(); while (e.hasMoreElements()) { ASN1ObjectIdentifier oid = (ASN1ObjectIdentifier)e.nextElement(); Extension ext = extensions.getExtension(oid); if (ext.isCritical()) { set.add(oid.getId()); } } return set; } } return null; } private byte[] getExtensionBytes(String oid) { Extensions exts = c.getTBSCertificate().getExtensions(); if (exts != null) { Extension ext = exts.getExtension(new ASN1ObjectIdentifier(oid)); if (ext != null) { return ext.getExtnValue().getOctets(); } } return null; } public byte[] getExtensionValue(String oid) { Extensions exts = c.getTBSCertificate().getExtensions(); if (exts != null) { Extension ext = exts.getExtension(new ASN1ObjectIdentifier(oid)); if (ext != null) { try { return ext.getExtnValue().getEncoded(); } catch (Exception e) { throw new IllegalStateException("error parsing " + e.toString()); } } } return null; } public Set getNonCriticalExtensionOIDs() { if (this.getVersion() == 3) { Set set = new HashSet(); Extensions extensions = c.getTBSCertificate().getExtensions(); if (extensions != null) { Enumeration e = extensions.oids(); while (e.hasMoreElements()) { ASN1ObjectIdentifier oid = (ASN1ObjectIdentifier)e.nextElement(); Extension ext = extensions.getExtension(oid); if (!ext.isCritical()) { set.add(oid.getId()); } } return set; } } return null; } public boolean hasUnsupportedCriticalExtension() { if (this.getVersion() == 3) { Extensions extensions = c.getTBSCertificate().getExtensions(); if (extensions != null) { Enumeration e = extensions.oids(); while (e.hasMoreElements()) { ASN1ObjectIdentifier oid = (ASN1ObjectIdentifier)e.nextElement(); String oidId = oid.getId(); if (oidId.equals(RFC3280CertPathUtilities.KEY_USAGE) || oidId.equals(RFC3280CertPathUtilities.CERTIFICATE_POLICIES) || oidId.equals(RFC3280CertPathUtilities.POLICY_MAPPINGS) || oidId.equals(RFC3280CertPathUtilities.INHIBIT_ANY_POLICY) || oidId.equals(RFC3280CertPathUtilities.CRL_DISTRIBUTION_POINTS) || oidId.equals(RFC3280CertPathUtilities.ISSUING_DISTRIBUTION_POINT) || oidId.equals(RFC3280CertPathUtilities.DELTA_CRL_INDICATOR) || oidId.equals(RFC3280CertPathUtilities.POLICY_CONSTRAINTS) || oidId.equals(RFC3280CertPathUtilities.BASIC_CONSTRAINTS) || oidId.equals(RFC3280CertPathUtilities.SUBJECT_ALTERNATIVE_NAME) || oidId.equals(RFC3280CertPathUtilities.NAME_CONSTRAINTS)) { continue; } Extension ext = extensions.getExtension(oid); if (ext.isCritical()) { return true; } } } } return false; } public PublicKey getPublicKey() { try { return BouncyCastleProvider.getPublicKey(c.getSubjectPublicKeyInfo()); } catch (IOException e) { return null; // should never happen... } } public byte[] getEncoded() throws CertificateEncodingException { try { return c.getEncoded(ASN1Encoding.DER); } catch (IOException e) { throw new CertificateEncodingException(e.toString()); } } public boolean equals( Object o) { if (o == this) { return true; } if (!(o instanceof Certificate)) { return false; } Certificate other = (Certificate)o; try { byte[] b1 = this.getEncoded(); byte[] b2 = other.getEncoded(); return Arrays.areEqual(b1, b2); } catch (CertificateEncodingException e) { return false; } } public synchronized int hashCode() { if (!hashValueSet) { hashValue = calculateHashCode(); hashValueSet = true; } return hashValue; } private int calculateHashCode() { try { int hashCode = 0; byte[] certData = this.getEncoded(); for (int i = 1; i < certData.length; i++) { hashCode += certData[i] * i; } return hashCode; } catch (CertificateEncodingException e) { return 0; } } public void setBagAttribute( ASN1ObjectIdentifier oid, ASN1Encodable attribute) { attrCarrier.setBagAttribute(oid, attribute); } public ASN1Encodable getBagAttribute( ASN1ObjectIdentifier oid) { return attrCarrier.getBagAttribute(oid); } public Enumeration getBagAttributeKeys() { return attrCarrier.getBagAttributeKeys(); } public String toString() { StringBuffer buf = new StringBuffer(); String nl = System.getProperty("line.separator"); buf.append(" [0] Version: ").append(this.getVersion()).append(nl); buf.append(" SerialNumber: ").append(this.getSerialNumber()).append(nl); buf.append(" IssuerDN: ").append(this.getIssuerDN()).append(nl); buf.append(" Start Date: ").append(this.getNotBefore()).append(nl); buf.append(" Final Date: ").append(this.getNotAfter()).append(nl); buf.append(" SubjectDN: ").append(this.getSubjectDN()).append(nl); buf.append(" Public Key: ").append(this.getPublicKey()).append(nl); buf.append(" Signature Algorithm: ").append(this.getSigAlgName()).append(nl); byte[] sig = this.getSignature(); buf.append(" Signature: ").append(new String(Hex.encode(sig, 0, 20))).append(nl); for (int i = 20; i < sig.length; i += 20) { if (i < sig.length - 20) { buf.append(" ").append(new String(Hex.encode(sig, i, 20))).append(nl); } else { buf.append(" ").append(new String(Hex.encode(sig, i, sig.length - i))).append(nl); } } Extensions extensions = c.getTBSCertificate().getExtensions(); if (extensions != null) { Enumeration e = extensions.oids(); if (e.hasMoreElements()) { buf.append(" Extensions: \n"); } while (e.hasMoreElements()) { ASN1ObjectIdentifier oid = (ASN1ObjectIdentifier)e.nextElement(); Extension ext = extensions.getExtension(oid); if (ext.getExtnValue() != null) { byte[] octs = ext.getExtnValue().getOctets(); ASN1InputStream dIn = new ASN1InputStream(octs); buf.append(" critical(").append(ext.isCritical()).append(") "); try { if (oid.equals(Extension.basicConstraints)) { buf.append(BasicConstraints.getInstance(dIn.readObject())).append(nl); } else if (oid.equals(Extension.keyUsage)) { buf.append(KeyUsage.getInstance(dIn.readObject())).append(nl); } else if (oid.equals(MiscObjectIdentifiers.netscapeCertType)) { buf.append(new NetscapeCertType((DERBitString)dIn.readObject())).append(nl); } else if (oid.equals(MiscObjectIdentifiers.netscapeRevocationURL)) { buf.append(new NetscapeRevocationURL((DERIA5String)dIn.readObject())).append(nl); } else if (oid.equals(MiscObjectIdentifiers.verisignCzagExtension)) { buf.append(new VerisignCzagExtension((DERIA5String)dIn.readObject())).append(nl); } else { buf.append(oid.getId()); buf.append(" value = ").append(ASN1Dump.dumpAsString(dIn.readObject())).append(nl); //buf.append(" value = ").append("*****").append(nl); } } catch (Exception ex) { buf.append(oid.getId()); // buf.append(" value = ").append(new String(Hex.encode(ext.getExtnValue().getOctets()))).append(nl); buf.append(" value = ").append("*****").append(nl); } } else { buf.append(nl); } } } return buf.toString(); } public final void verify( PublicKey key) throws CertificateException, NoSuchAlgorithmException, InvalidKeyException, NoSuchProviderException, SignatureException { Signature signature; String sigName = X509SignatureUtil.getSignatureName(c.getSignatureAlgorithm()); try { signature = Signature.getInstance(sigName, BouncyCastleProvider.PROVIDER_NAME); } catch (Exception e) { signature = Signature.getInstance(sigName); } checkSignature(key, signature); } public final void verify( PublicKey key, String sigProvider) throws CertificateException, NoSuchAlgorithmException, InvalidKeyException, NoSuchProviderException, SignatureException { String sigName = X509SignatureUtil.getSignatureName(c.getSignatureAlgorithm()); Signature signature = Signature.getInstance(sigName, sigProvider); checkSignature(key, signature); } private void checkSignature( PublicKey key, Signature signature) throws CertificateException, NoSuchAlgorithmException, SignatureException, InvalidKeyException { if (!isAlgIdEqual(c.getSignatureAlgorithm(), c.getTBSCertificate().getSignature())) { throw new CertificateException("signature algorithm in TBS cert not same as outer cert"); } ASN1Encodable params = c.getSignatureAlgorithm().getParameters(); // TODO This should go after the initVerify? X509SignatureUtil.setSignatureParameters(signature, params); signature.initVerify(key); signature.update(this.getTBSCertificate()); if (!signature.verify(this.getSignature())) { throw new SignatureException("certificate does not verify with supplied key"); } } private boolean isAlgIdEqual(AlgorithmIdentifier id1, AlgorithmIdentifier id2) { if (!id1.getAlgorithm().equals(id2.getAlgorithm())) { return false; } if (id1.getParameters() == null) { if (id2.getParameters() != null && !id2.getParameters().equals(DERNull.INSTANCE)) { return false; } return true; } if (id2.getParameters() == null) { if (id1.getParameters() != null && !id1.getParameters().equals(DERNull.INSTANCE)) { return false; } return true; } return id1.getParameters().equals(id2.getParameters()); } private static Collection getAlternativeNames(byte[] extVal) throws CertificateParsingException { if (extVal == null) { return null; } try { Collection temp = new ArrayList(); Enumeration it = ASN1Sequence.getInstance(extVal).getObjects(); while (it.hasMoreElements()) { GeneralName genName = GeneralName.getInstance(it.nextElement()); List list = new ArrayList(); list.add(Integers.valueOf(genName.getTagNo())); switch (genName.getTagNo()) { case GeneralName.ediPartyName: case GeneralName.x400Address: case GeneralName.otherName: list.add(genName.getEncoded()); break; case GeneralName.directoryName: list.add(X500Name.getInstance(RFC4519Style.INSTANCE, genName.getName()).toString()); break; case GeneralName.dNSName: case GeneralName.rfc822Name: case GeneralName.uniformResourceIdentifier: list.add(((ASN1String)genName.getName()).getString()); break; case GeneralName.registeredID: list.add(ASN1ObjectIdentifier.getInstance(genName.getName()).getId()); break; case GeneralName.iPAddress: byte[] addrBytes = DEROctetString.getInstance(genName.getName()).getOctets(); final String addr; try { addr = InetAddress.getByAddress(addrBytes).getHostAddress(); } catch (UnknownHostException e) { continue; } list.add(addr); break; default: throw new IOException("Bad tag number: " + genName.getTagNo()); } temp.add(Collections.unmodifiableList(list)); } if (temp.size() == 0) { return null; } return Collections.unmodifiableCollection(temp); } catch (Exception e) { throw new CertificateParsingException(e.getMessage()); } } } bouncycastle-1.49.orig/src/org/bouncycastle/jce/provider/X509StoreCRLCollection.java0000644000175000017500000000157111624652555030016 0ustar ebourgebourgpackage org.bouncycastle.jce.provider; import java.util.Collection; import org.bouncycastle.util.CollectionStore; import org.bouncycastle.util.Selector; import org.bouncycastle.x509.X509CollectionStoreParameters; import org.bouncycastle.x509.X509StoreParameters; import org.bouncycastle.x509.X509StoreSpi; public class X509StoreCRLCollection extends X509StoreSpi { private CollectionStore _store; public X509StoreCRLCollection() { } public void engineInit(X509StoreParameters params) { if (!(params instanceof X509CollectionStoreParameters)) { throw new IllegalArgumentException(params.toString()); } _store = new CollectionStore(((X509CollectionStoreParameters)params).getCollection()); } public Collection engineGetMatches(Selector selector) { return _store.getMatches(selector); } } bouncycastle-1.49.orig/src/org/bouncycastle/jce/provider/X509StoreLDAPCRLs.java0000644000175000017500000000572711624652555026635 0ustar ebourgebourgpackage org.bouncycastle.jce.provider; import java.util.Collection; import java.util.Collections; import java.util.HashSet; import java.util.Set; import org.bouncycastle.jce.X509LDAPCertStoreParameters; import org.bouncycastle.util.Selector; import org.bouncycastle.util.StoreException; import org.bouncycastle.x509.X509CRLStoreSelector; import org.bouncycastle.x509.X509StoreParameters; import org.bouncycastle.x509.X509StoreSpi; import org.bouncycastle.x509.util.LDAPStoreHelper; /** * A SPI implementation of Bouncy Castle X509Store for getting * certificate revocation lists from an LDAP directory. * * @see org.bouncycastle.x509.X509Store */ public class X509StoreLDAPCRLs extends X509StoreSpi { private LDAPStoreHelper helper; public X509StoreLDAPCRLs() { } /** * Initializes this LDAP CRL store implementation. * * @param params X509LDAPCertStoreParameters. * @throws IllegalArgumentException if params is not an instance of * X509LDAPCertStoreParameters. */ public void engineInit(X509StoreParameters params) { if (!(params instanceof X509LDAPCertStoreParameters)) { throw new IllegalArgumentException( "Initialization parameters must be an instance of " + X509LDAPCertStoreParameters.class.getName() + "."); } helper = new LDAPStoreHelper((X509LDAPCertStoreParameters)params); } /** * Returns a collection of matching CRLs from the LDAP location. *

    * The selector must be a of type X509CRLStoreSelector. If * it is not an empty collection is returned. *

    * The issuer should be a reasonable criteria for a selector. * * @param selector The selector to use for finding. * @return A collection with the matches. * @throws StoreException if an exception occurs while searching. */ public Collection engineGetMatches(Selector selector) throws StoreException { if (!(selector instanceof X509CRLStoreSelector)) { return Collections.EMPTY_SET; } X509CRLStoreSelector xselector = (X509CRLStoreSelector)selector; Set set = new HashSet(); // test only delta CRLs should be selected if (xselector.isDeltaCRLIndicatorEnabled()) { set.addAll(helper.getDeltaCertificateRevocationLists(xselector)); } // nothing specified else { set.addAll(helper.getDeltaCertificateRevocationLists(xselector)); set.addAll(helper.getAttributeAuthorityRevocationLists(xselector)); set .addAll(helper .getAttributeCertificateRevocationLists(xselector)); set.addAll(helper.getAuthorityRevocationLists(xselector)); set.addAll(helper.getCertificateRevocationLists(xselector)); } return set; } } bouncycastle-1.49.orig/src/org/bouncycastle/jce/provider/X509StoreLDAPCerts.java0000644000175000017500000001060111624652565027076 0ustar ebourgebourgpackage org.bouncycastle.jce.provider; import java.util.Collection; import java.util.Collections; import java.util.HashSet; import java.util.Iterator; import java.util.Set; import org.bouncycastle.jce.X509LDAPCertStoreParameters; import org.bouncycastle.util.Selector; import org.bouncycastle.util.StoreException; import org.bouncycastle.x509.X509CertPairStoreSelector; import org.bouncycastle.x509.X509CertStoreSelector; import org.bouncycastle.x509.X509CertificatePair; import org.bouncycastle.x509.X509StoreParameters; import org.bouncycastle.x509.X509StoreSpi; import org.bouncycastle.x509.util.LDAPStoreHelper; /** * A SPI implementation of Bouncy Castle X509Store for getting * certificates form a LDAP directory. * * @see org.bouncycastle.x509.X509Store */ public class X509StoreLDAPCerts extends X509StoreSpi { private LDAPStoreHelper helper; public X509StoreLDAPCerts() { } /** * Initializes this LDAP cert store implementation. * * @param params X509LDAPCertStoreParameters. * @throws IllegalArgumentException if params is not an instance of * X509LDAPCertStoreParameters. */ public void engineInit(X509StoreParameters params) { if (!(params instanceof X509LDAPCertStoreParameters)) { throw new IllegalArgumentException( "Initialization parameters must be an instance of " + X509LDAPCertStoreParameters.class.getName() + "."); } helper = new LDAPStoreHelper((X509LDAPCertStoreParameters)params); } /** * Returns a collection of matching certificates from the LDAP location. *

    * The selector must be a of type X509CertStoreSelector. If * it is not an empty collection is returned. *

    * The implementation searches only for CA certificates, if the method * {@link java.security.cert.X509CertSelector#getBasicConstraints()} is * greater or equal to 0. If it is -2 only end certificates are searched. *

    * The subject and the serial number for end certificates should be * reasonable criterias for a selector. * * @param selector The selector to use for finding. * @return A collection with the matches. * @throws StoreException if an exception occurs while searching. */ public Collection engineGetMatches(Selector selector) throws StoreException { if (!(selector instanceof X509CertStoreSelector)) { return Collections.EMPTY_SET; } X509CertStoreSelector xselector = (X509CertStoreSelector)selector; Set set = new HashSet(); // test if only CA certificates should be selected if (xselector.getBasicConstraints() > 0) { set.addAll(helper.getCACertificates(xselector)); set.addAll(getCertificatesFromCrossCertificatePairs(xselector)); } // only end certificates should be selected else if (xselector.getBasicConstraints() == -2) { set.addAll(helper.getUserCertificates(xselector)); } // nothing specified else { set.addAll(helper.getUserCertificates(xselector)); set.addAll(helper.getCACertificates(xselector)); set.addAll(getCertificatesFromCrossCertificatePairs(xselector)); } return set; } private Collection getCertificatesFromCrossCertificatePairs( X509CertStoreSelector xselector) throws StoreException { Set set = new HashSet(); X509CertPairStoreSelector ps = new X509CertPairStoreSelector(); ps.setForwardSelector(xselector); ps.setReverseSelector(new X509CertStoreSelector()); Set crossCerts = new HashSet(helper.getCrossCertificatePairs(ps)); Set forward = new HashSet(); Set reverse = new HashSet(); Iterator it = crossCerts.iterator(); while (it.hasNext()) { X509CertificatePair pair = (X509CertificatePair)it.next(); if (pair.getForward() != null) { forward.add(pair.getForward()); } if (pair.getReverse() != null) { reverse.add(pair.getReverse()); } } set.addAll(forward); set.addAll(reverse); return set; } } bouncycastle-1.49.orig/src/org/bouncycastle/jce/provider/JDKPKCS12StoreParameter.java0000644000175000017500000000236312107333336030057 0ustar ebourgebourgpackage org.bouncycastle.jce.provider; import java.io.OutputStream; import java.security.KeyStore; import java.security.KeyStore.LoadStoreParameter; import java.security.KeyStore.ProtectionParameter; /** * @deprecated use org.bouncycastle.jcajce.config.PKCS12StoreParameter */ public class JDKPKCS12StoreParameter implements LoadStoreParameter { private OutputStream outputStream; private ProtectionParameter protectionParameter; private boolean useDEREncoding; public OutputStream getOutputStream() { return outputStream; } public ProtectionParameter getProtectionParameter() { return protectionParameter; } public boolean isUseDEREncoding() { return useDEREncoding; } public void setOutputStream(OutputStream outputStream) { this.outputStream = outputStream; } public void setPassword(char[] password) { this.protectionParameter = new KeyStore.PasswordProtection(password); } public void setProtectionParameter(ProtectionParameter protectionParameter) { this.protectionParameter = protectionParameter; } public void setUseDEREncoding(boolean useDEREncoding) { this.useDEREncoding = useDEREncoding; } } bouncycastle-1.49.orig/src/org/bouncycastle/jce/provider/X509LDAPCertStoreSpi.java0000644000175000017500000003717711624640052027374 0ustar ebourgebourgpackage org.bouncycastle.jce.provider; import java.io.ByteArrayInputStream; import java.io.IOException; import java.security.InvalidAlgorithmParameterException; import java.security.cert.CRL; import java.security.cert.CRLSelector; import java.security.cert.CertSelector; import java.security.cert.CertStoreException; import java.security.cert.CertStoreParameters; import java.security.cert.CertStoreSpi; import java.security.cert.Certificate; import java.security.cert.CertificateFactory; import java.security.cert.X509CRLSelector; import java.security.cert.X509CertSelector; import java.util.ArrayList; import java.util.Collection; import java.util.HashSet; import java.util.Iterator; import java.util.List; import java.util.Properties; import java.util.Set; import javax.naming.Context; import javax.naming.NamingEnumeration; import javax.naming.NamingException; import javax.naming.directory.Attribute; import javax.naming.directory.DirContext; import javax.naming.directory.InitialDirContext; import javax.naming.directory.SearchControls; import javax.naming.directory.SearchResult; import javax.security.auth.x500.X500Principal; import org.bouncycastle.asn1.ASN1InputStream; import org.bouncycastle.asn1.x509.CertificatePair; import org.bouncycastle.jce.X509LDAPCertStoreParameters; /** * * This is a general purpose implementation to get X.509 certificates and CRLs * from a LDAP location. *

    * At first a search is performed in the ldap*AttributeNames of the * {@link org.bouncycastle.jce.X509LDAPCertStoreParameters} with the given * information of the subject (for all kind of certificates) or issuer (for * CRLs), respectively, if a X509CertSelector is given with that details. For * CRLs, CA certificates and cross certificates a coarse search is made only for * entries with that content to get more possibly matchign results. */ public class X509LDAPCertStoreSpi extends CertStoreSpi { private X509LDAPCertStoreParameters params; public X509LDAPCertStoreSpi(CertStoreParameters params) throws InvalidAlgorithmParameterException { super(params); if (!(params instanceof X509LDAPCertStoreParameters)) { throw new InvalidAlgorithmParameterException( X509LDAPCertStoreSpi.class.getName() + ": parameter must be a " + X509LDAPCertStoreParameters.class.getName() + " object\n" + params.toString()); } this.params = (X509LDAPCertStoreParameters)params; } /** * Initial Context Factory. */ private static String LDAP_PROVIDER = "com.sun.jndi.ldap.LdapCtxFactory"; /** * Processing referrals.. */ private static String REFERRALS_IGNORE = "ignore"; /** * Security level to be used for LDAP connections. */ private static final String SEARCH_SECURITY_LEVEL = "none"; /** * Package Prefix for loading URL context factories. */ private static final String URL_CONTEXT_PREFIX = "com.sun.jndi.url"; private DirContext connectLDAP() throws NamingException { Properties props = new Properties(); props.setProperty(Context.INITIAL_CONTEXT_FACTORY, LDAP_PROVIDER); props.setProperty(Context.BATCHSIZE, "0"); props.setProperty(Context.PROVIDER_URL, params.getLdapURL()); props.setProperty(Context.URL_PKG_PREFIXES, URL_CONTEXT_PREFIX); props.setProperty(Context.REFERRAL, REFERRALS_IGNORE); props.setProperty(Context.SECURITY_AUTHENTICATION, SEARCH_SECURITY_LEVEL); DirContext ctx = new InitialDirContext(props); return ctx; } private String parseDN(String subject, String subjectAttributeName) { String temp = subject; int begin = temp.toLowerCase().indexOf( subjectAttributeName.toLowerCase()); temp = temp.substring(begin + subjectAttributeName.length()); int end = temp.indexOf(','); if (end == -1) { end = temp.length(); } while (temp.charAt(end - 1) == '\\') { end = temp.indexOf(',', end + 1); if (end == -1) { end = temp.length(); } } temp = temp.substring(0, end); begin = temp.indexOf('='); temp = temp.substring(begin + 1); if (temp.charAt(0) == ' ') { temp = temp.substring(1); } if (temp.startsWith("\"")) { temp = temp.substring(1); } if (temp.endsWith("\"")) { temp = temp.substring(0, temp.length() - 1); } return temp; } public Collection engineGetCertificates(CertSelector selector) throws CertStoreException { if (!(selector instanceof X509CertSelector)) { throw new CertStoreException("selector is not a X509CertSelector"); } X509CertSelector xselector = (X509CertSelector)selector; Set certSet = new HashSet(); Set set = getEndCertificates(xselector); set.addAll(getCACertificates(xselector)); set.addAll(getCrossCertificates(xselector)); Iterator it = set.iterator(); try { CertificateFactory cf = CertificateFactory.getInstance("X.509", BouncyCastleProvider.PROVIDER_NAME); while (it.hasNext()) { byte[] bytes = (byte[])it.next(); if (bytes == null || bytes.length == 0) { continue; } List bytesList = new ArrayList(); bytesList.add(bytes); try { CertificatePair pair = CertificatePair .getInstance(new ASN1InputStream(bytes) .readObject()); bytesList.clear(); if (pair.getForward() != null) { bytesList.add(pair.getForward().getEncoded()); } if (pair.getReverse() != null) { bytesList.add(pair.getReverse().getEncoded()); } } catch (IOException e) { } catch (IllegalArgumentException e) { } for (Iterator it2 = bytesList.iterator(); it2.hasNext();) { ByteArrayInputStream bIn = new ByteArrayInputStream( (byte[])it2.next()); try { Certificate cert = cf.generateCertificate(bIn); // System.out.println(((X509Certificate) // cert).getSubjectX500Principal()); if (xselector.match(cert)) { certSet.add(cert); } } catch (Exception e) { } } } } catch (Exception e) { throw new CertStoreException( "certificate cannot be constructed from LDAP result: " + e); } return certSet; } private Set certSubjectSerialSearch(X509CertSelector xselector, String[] attrs, String attrName, String subjectAttributeName) throws CertStoreException { Set set = new HashSet(); try { if (xselector.getSubjectAsBytes() != null || xselector.getSubjectAsString() != null || xselector.getCertificate() != null) { String subject = null; String serial = null; if (xselector.getCertificate() != null) { subject = xselector.getCertificate() .getSubjectX500Principal().getName("RFC1779"); serial = xselector.getCertificate().getSerialNumber() .toString(); } else { if (xselector.getSubjectAsBytes() != null) { subject = new X500Principal(xselector .getSubjectAsBytes()).getName("RFC1779"); } else { subject = xselector.getSubjectAsString(); } } String attrValue = parseDN(subject, subjectAttributeName); set.addAll(search(attrName, "*" + attrValue + "*", attrs)); if (serial != null && params.getSearchForSerialNumberIn() != null) { attrValue = serial; attrName = params.getSearchForSerialNumberIn(); set.addAll(search(attrName, "*" + attrValue + "*", attrs)); } } else { set.addAll(search(attrName, "*", attrs)); } } catch (IOException e) { throw new CertStoreException("exception processing selector: " + e); } return set; } private Set getEndCertificates(X509CertSelector xselector) throws CertStoreException { String[] attrs = {params.getUserCertificateAttribute()}; String attrName = params.getLdapUserCertificateAttributeName(); String subjectAttributeName = params.getUserCertificateSubjectAttributeName(); Set set = certSubjectSerialSearch(xselector, attrs, attrName, subjectAttributeName); return set; } private Set getCACertificates(X509CertSelector xselector) throws CertStoreException { String[] attrs = {params.getCACertificateAttribute()}; String attrName = params.getLdapCACertificateAttributeName(); String subjectAttributeName = params .getCACertificateSubjectAttributeName(); Set set = certSubjectSerialSearch(xselector, attrs, attrName, subjectAttributeName); if (set.isEmpty()) { set.addAll(search(null, "*", attrs)); } return set; } private Set getCrossCertificates(X509CertSelector xselector) throws CertStoreException { String[] attrs = {params.getCrossCertificateAttribute()}; String attrName = params.getLdapCrossCertificateAttributeName(); String subjectAttributeName = params .getCrossCertificateSubjectAttributeName(); Set set = certSubjectSerialSearch(xselector, attrs, attrName, subjectAttributeName); if (set.isEmpty()) { set.addAll(search(null, "*", attrs)); } return set; } public Collection engineGetCRLs(CRLSelector selector) throws CertStoreException { String[] attrs = {params.getCertificateRevocationListAttribute()}; if (!(selector instanceof X509CRLSelector)) { throw new CertStoreException("selector is not a X509CRLSelector"); } X509CRLSelector xselector = (X509CRLSelector)selector; Set crlSet = new HashSet(); String attrName = params.getLdapCertificateRevocationListAttributeName(); Set set = new HashSet(); if (xselector.getIssuerNames() != null) { for (Iterator it = xselector.getIssuerNames().iterator(); it .hasNext();) { Object o = it.next(); String attrValue = null; if (o instanceof String) { String issuerAttributeName = params .getCertificateRevocationListIssuerAttributeName(); attrValue = parseDN((String)o, issuerAttributeName); } else { String issuerAttributeName = params .getCertificateRevocationListIssuerAttributeName(); attrValue = parseDN(new X500Principal((byte[])o) .getName("RFC1779"), issuerAttributeName); } set.addAll(search(attrName, "*" + attrValue + "*", attrs)); } } else { set.addAll(search(attrName, "*", attrs)); } set.addAll(search(null, "*", attrs)); Iterator it = set.iterator(); try { CertificateFactory cf = CertificateFactory.getInstance("X.509", BouncyCastleProvider.PROVIDER_NAME); while (it.hasNext()) { CRL crl = cf.generateCRL(new ByteArrayInputStream((byte[])it .next())); if (xselector.match(crl)) { crlSet.add(crl); } } } catch (Exception e) { throw new CertStoreException( "CRL cannot be constructed from LDAP result " + e); } return crlSet; } /** * Returns a Set of byte arrays with the certificate or CRL encodings. * * @param attributeName The attribute name to look for in the LDAP. * @param attributeValue The value the attribute name must have. * @param attrs The attributes in the LDAP which hold the certificate, * certificate pair or CRL in a found entry. * @return Set of byte arrays with the certificate encodings. */ private Set search(String attributeName, String attributeValue, String[] attrs) throws CertStoreException { String filter = attributeName + "=" + attributeValue; if (attributeName == null) { filter = null; } DirContext ctx = null; Set set = new HashSet(); try { ctx = connectLDAP(); SearchControls constraints = new SearchControls(); constraints.setSearchScope(SearchControls.SUBTREE_SCOPE); constraints.setCountLimit(0); for (int i = 0; i < attrs.length; i++) { String temp[] = new String[1]; temp[0] = attrs[i]; constraints.setReturningAttributes(temp); String filter2 = "(&(" + filter + ")(" + temp[0] + "=*))"; if (filter == null) { filter2 = "(" + temp[0] + "=*)"; } NamingEnumeration results = ctx.search(params.getBaseDN(), filter2, constraints); while (results.hasMoreElements()) { SearchResult sr = (SearchResult)results.next(); // should only be one attribute in the attribute set with // one // attribute value as byte array NamingEnumeration enumeration = ((Attribute)(sr .getAttributes().getAll().next())).getAll(); while (enumeration.hasMore()) { Object o = enumeration.next(); set.add(o); } } } } catch (Exception e) { throw new CertStoreException( "Error getting results from LDAP directory " + e); } finally { try { if (null != ctx) { ctx.close(); } } catch (Exception e) { } } return set; } } bouncycastle-1.49.orig/src/org/bouncycastle/jce/provider/DHUtil.java0000644000175000017500000000313111624640052025067 0ustar ebourgebourgpackage org.bouncycastle.jce.provider; import java.security.InvalidKeyException; import java.security.PrivateKey; import java.security.PublicKey; import javax.crypto.interfaces.DHPrivateKey; import javax.crypto.interfaces.DHPublicKey; import org.bouncycastle.crypto.params.AsymmetricKeyParameter; import org.bouncycastle.crypto.params.DHParameters; import org.bouncycastle.crypto.params.DHPrivateKeyParameters; import org.bouncycastle.crypto.params.DHPublicKeyParameters; /** * utility class for converting jce/jca DH objects * objects into their org.bouncycastle.crypto counterparts. */ public class DHUtil { static public AsymmetricKeyParameter generatePublicKeyParameter( PublicKey key) throws InvalidKeyException { if (key instanceof DHPublicKey) { DHPublicKey k = (DHPublicKey)key; return new DHPublicKeyParameters(k.getY(), new DHParameters(k.getParams().getP(), k.getParams().getG(), null, k.getParams().getL())); } throw new InvalidKeyException("can't identify DH public key."); } static public AsymmetricKeyParameter generatePrivateKeyParameter( PrivateKey key) throws InvalidKeyException { if (key instanceof DHPrivateKey) { DHPrivateKey k = (DHPrivateKey)key; return new DHPrivateKeyParameters(k.getX(), new DHParameters(k.getParams().getP(), k.getParams().getG(), null, k.getParams().getL())); } throw new InvalidKeyException("can't identify DH private key."); } } bouncycastle-1.49.orig/src/org/bouncycastle/jce/provider/CertStoreCollectionSpi.java0000644000175000017500000000533111624640051030343 0ustar ebourgebourgpackage org.bouncycastle.jce.provider; import java.security.InvalidAlgorithmParameterException; import java.security.cert.CRL; import java.security.cert.CRLSelector; import java.security.cert.CertSelector; import java.security.cert.CertStoreException; import java.security.cert.CertStoreParameters; import java.security.cert.CertStoreSpi; import java.security.cert.Certificate; import java.security.cert.CollectionCertStoreParameters; import java.util.ArrayList; import java.util.Collection; import java.util.Iterator; import java.util.List; public class CertStoreCollectionSpi extends CertStoreSpi { private CollectionCertStoreParameters params; public CertStoreCollectionSpi(CertStoreParameters params) throws InvalidAlgorithmParameterException { super(params); if (!(params instanceof CollectionCertStoreParameters)) { throw new InvalidAlgorithmParameterException("org.bouncycastle.jce.provider.CertStoreCollectionSpi: parameter must be a CollectionCertStoreParameters object\n" + params.toString()); } this.params = (CollectionCertStoreParameters)params; } public Collection engineGetCertificates( CertSelector selector) throws CertStoreException { List col = new ArrayList(); Iterator iter = params.getCollection().iterator(); if (selector == null) { while (iter.hasNext()) { Object obj = iter.next(); if (obj instanceof Certificate) { col.add(obj); } } } else { while (iter.hasNext()) { Object obj = iter.next(); if ((obj instanceof Certificate) && selector.match((Certificate)obj)) { col.add(obj); } } } return col; } public Collection engineGetCRLs( CRLSelector selector) throws CertStoreException { List col = new ArrayList(); Iterator iter = params.getCollection().iterator(); if (selector == null) { while (iter.hasNext()) { Object obj = iter.next(); if (obj instanceof CRL) { col.add(obj); } } } else { while (iter.hasNext()) { Object obj = iter.next(); if ((obj instanceof CRL) && selector.match((CRL)obj)) { col.add(obj); } } } return col; } } bouncycastle-1.49.orig/src/org/bouncycastle/jce/provider/RFC3280CertPathUtilities.java0000644000175000017500000027013112110036363030215 0ustar ebourgebourgpackage org.bouncycastle.jce.provider; import java.io.IOException; import java.math.BigInteger; import java.security.GeneralSecurityException; import java.security.PublicKey; import java.security.cert.CertPath; import java.security.cert.CertPathBuilder; import java.security.cert.CertPathBuilderException; import java.security.cert.CertPathValidatorException; import java.security.cert.CertificateExpiredException; import java.security.cert.CertificateNotYetValidException; import java.security.cert.PKIXCertPathChecker; import java.security.cert.X509CRL; import java.security.cert.X509Certificate; import java.security.cert.X509Extension; import java.util.ArrayList; import java.util.Collection; import java.util.Date; import java.util.Enumeration; import java.util.HashMap; import java.util.HashSet; import java.util.Iterator; import java.util.List; import java.util.Map; import java.util.Set; import java.util.Vector; import javax.security.auth.x500.X500Principal; import org.bouncycastle.asn1.ASN1Encodable; import org.bouncycastle.asn1.ASN1EncodableVector; import org.bouncycastle.asn1.ASN1InputStream; import org.bouncycastle.asn1.ASN1Primitive; import org.bouncycastle.asn1.ASN1Sequence; import org.bouncycastle.asn1.ASN1TaggedObject; import org.bouncycastle.asn1.DERInteger; import org.bouncycastle.asn1.DERObjectIdentifier; import org.bouncycastle.asn1.DERSequence; import org.bouncycastle.asn1.x509.BasicConstraints; import org.bouncycastle.asn1.x509.CRLDistPoint; import org.bouncycastle.asn1.x509.CRLReason; import org.bouncycastle.asn1.x509.DistributionPoint; import org.bouncycastle.asn1.x509.DistributionPointName; import org.bouncycastle.asn1.x509.GeneralName; import org.bouncycastle.asn1.x509.GeneralNames; import org.bouncycastle.asn1.x509.GeneralSubtree; import org.bouncycastle.asn1.x509.IssuingDistributionPoint; import org.bouncycastle.asn1.x509.NameConstraints; import org.bouncycastle.asn1.x509.PolicyInformation; import org.bouncycastle.asn1.x509.X509Extensions; import org.bouncycastle.asn1.x509.X509Name; import org.bouncycastle.jce.exception.ExtCertPathValidatorException; import org.bouncycastle.util.Arrays; import org.bouncycastle.x509.ExtendedPKIXBuilderParameters; import org.bouncycastle.x509.ExtendedPKIXParameters; import org.bouncycastle.x509.X509CRLStoreSelector; import org.bouncycastle.x509.X509CertStoreSelector; public class RFC3280CertPathUtilities { private static final PKIXCRLUtil CRL_UTIL = new PKIXCRLUtil(); /** * If the complete CRL includes an issuing distribution point (IDP) CRL * extension check the following: *

    * (i) If the distribution point name is present in the IDP CRL extension * and the distribution field is present in the DP, then verify that one of * the names in the IDP matches one of the names in the DP. If the * distribution point name is present in the IDP CRL extension and the * distribution field is omitted from the DP, then verify that one of the * names in the IDP matches one of the names in the cRLIssuer field of the * DP. *

    *

    * (ii) If the onlyContainsUserCerts boolean is asserted in the IDP CRL * extension, verify that the certificate does not include the basic * constraints extension with the cA boolean asserted. *

    *

    * (iii) If the onlyContainsCACerts boolean is asserted in the IDP CRL * extension, verify that the certificate includes the basic constraints * extension with the cA boolean asserted. *

    *

    * (iv) Verify that the onlyContainsAttributeCerts boolean is not asserted. *

    * * @param dp The distribution point. * @param cert The certificate. * @param crl The CRL. * @throws AnnotatedException if one of the conditions is not met or an error occurs. */ protected static void processCRLB2( DistributionPoint dp, Object cert, X509CRL crl) throws AnnotatedException { IssuingDistributionPoint idp = null; try { idp = IssuingDistributionPoint.getInstance(CertPathValidatorUtilities.getExtensionValue(crl, RFC3280CertPathUtilities.ISSUING_DISTRIBUTION_POINT)); } catch (Exception e) { throw new AnnotatedException("Issuing distribution point extension could not be decoded.", e); } // (b) (2) (i) // distribution point name is present if (idp != null) { if (idp.getDistributionPoint() != null) { // make list of names DistributionPointName dpName = IssuingDistributionPoint.getInstance(idp).getDistributionPoint(); List names = new ArrayList(); if (dpName.getType() == DistributionPointName.FULL_NAME) { GeneralName[] genNames = GeneralNames.getInstance(dpName.getName()).getNames(); for (int j = 0; j < genNames.length; j++) { names.add(genNames[j]); } } if (dpName.getType() == DistributionPointName.NAME_RELATIVE_TO_CRL_ISSUER) { ASN1EncodableVector vec = new ASN1EncodableVector(); try { Enumeration e = ASN1Sequence.getInstance( ASN1Sequence.fromByteArray(CertPathValidatorUtilities.getIssuerPrincipal(crl) .getEncoded())).getObjects(); while (e.hasMoreElements()) { vec.add((ASN1Encodable)e.nextElement()); } } catch (IOException e) { throw new AnnotatedException("Could not read CRL issuer.", e); } vec.add(dpName.getName()); names.add(new GeneralName(X509Name.getInstance(new DERSequence(vec)))); } boolean matches = false; // verify that one of the names in the IDP matches one // of the names in the DP. if (dp.getDistributionPoint() != null) { dpName = dp.getDistributionPoint(); GeneralName[] genNames = null; if (dpName.getType() == DistributionPointName.FULL_NAME) { genNames = GeneralNames.getInstance(dpName.getName()).getNames(); } if (dpName.getType() == DistributionPointName.NAME_RELATIVE_TO_CRL_ISSUER) { if (dp.getCRLIssuer() != null) { genNames = dp.getCRLIssuer().getNames(); } else { genNames = new GeneralName[1]; try { genNames[0] = new GeneralName(new X509Name( (ASN1Sequence)ASN1Sequence.fromByteArray(CertPathValidatorUtilities .getEncodedIssuerPrincipal(cert).getEncoded()))); } catch (IOException e) { throw new AnnotatedException("Could not read certificate issuer.", e); } } for (int j = 0; j < genNames.length; j++) { Enumeration e = ASN1Sequence.getInstance(genNames[j].getName().toASN1Primitive()).getObjects(); ASN1EncodableVector vec = new ASN1EncodableVector(); while (e.hasMoreElements()) { vec.add((ASN1Encodable)e.nextElement()); } vec.add(dpName.getName()); genNames[j] = new GeneralName(new X509Name(new DERSequence(vec))); } } if (genNames != null) { for (int j = 0; j < genNames.length; j++) { if (names.contains(genNames[j])) { matches = true; break; } } } if (!matches) { throw new AnnotatedException( "No match for certificate CRL issuing distribution point name to cRLIssuer CRL distribution point."); } } // verify that one of the names in // the IDP matches one of the names in the cRLIssuer field of // the DP else { if (dp.getCRLIssuer() == null) { throw new AnnotatedException("Either the cRLIssuer or the distributionPoint field must " + "be contained in DistributionPoint."); } GeneralName[] genNames = dp.getCRLIssuer().getNames(); for (int j = 0; j < genNames.length; j++) { if (names.contains(genNames[j])) { matches = true; break; } } if (!matches) { throw new AnnotatedException( "No match for certificate CRL issuing distribution point name to cRLIssuer CRL distribution point."); } } } BasicConstraints bc = null; try { bc = BasicConstraints.getInstance(CertPathValidatorUtilities.getExtensionValue((X509Extension)cert, BASIC_CONSTRAINTS)); } catch (Exception e) { throw new AnnotatedException("Basic constraints extension could not be decoded.", e); } if (cert instanceof X509Certificate) { // (b) (2) (ii) if (idp.onlyContainsUserCerts() && (bc != null && bc.isCA())) { throw new AnnotatedException("CA Cert CRL only contains user certificates."); } // (b) (2) (iii) if (idp.onlyContainsCACerts() && (bc == null || !bc.isCA())) { throw new AnnotatedException("End CRL only contains CA certificates."); } } // (b) (2) (iv) if (idp.onlyContainsAttributeCerts()) { throw new AnnotatedException("onlyContainsAttributeCerts boolean is asserted."); } } } /** * If the DP includes cRLIssuer, then verify that the issuer field in the * complete CRL matches cRLIssuer in the DP and that the complete CRL * contains an issuing distribution point extension with the indirectCRL * boolean asserted. Otherwise, verify that the CRL issuer matches the * certificate issuer. * * @param dp The distribution point. * @param cert The certificate ot attribute certificate. * @param crl The CRL for cert. * @throws AnnotatedException if one of the above conditions does not apply or an error * occurs. */ protected static void processCRLB1( DistributionPoint dp, Object cert, X509CRL crl) throws AnnotatedException { ASN1Primitive idp = CertPathValidatorUtilities.getExtensionValue(crl, ISSUING_DISTRIBUTION_POINT); boolean isIndirect = false; if (idp != null) { if (IssuingDistributionPoint.getInstance(idp).isIndirectCRL()) { isIndirect = true; } } byte[] issuerBytes = CertPathValidatorUtilities.getIssuerPrincipal(crl).getEncoded(); boolean matchIssuer = false; if (dp.getCRLIssuer() != null) { GeneralName genNames[] = dp.getCRLIssuer().getNames(); for (int j = 0; j < genNames.length; j++) { if (genNames[j].getTagNo() == GeneralName.directoryName) { try { if (Arrays.areEqual(genNames[j].getName().toASN1Primitive().getEncoded(), issuerBytes)) { matchIssuer = true; } } catch (IOException e) { throw new AnnotatedException( "CRL issuer information from distribution point cannot be decoded.", e); } } } if (matchIssuer && !isIndirect) { throw new AnnotatedException("Distribution point contains cRLIssuer field but CRL is not indirect."); } if (!matchIssuer) { throw new AnnotatedException("CRL issuer of CRL does not match CRL issuer of distribution point."); } } else { if (CertPathValidatorUtilities.getIssuerPrincipal(crl).equals( CertPathValidatorUtilities.getEncodedIssuerPrincipal(cert))) { matchIssuer = true; } } if (!matchIssuer) { throw new AnnotatedException("Cannot find matching CRL issuer for certificate."); } } protected static ReasonsMask processCRLD( X509CRL crl, DistributionPoint dp) throws AnnotatedException { IssuingDistributionPoint idp = null; try { idp = IssuingDistributionPoint.getInstance(CertPathValidatorUtilities.getExtensionValue(crl, RFC3280CertPathUtilities.ISSUING_DISTRIBUTION_POINT)); } catch (Exception e) { throw new AnnotatedException("Issuing distribution point extension could not be decoded.", e); } // (d) (1) if (idp != null && idp.getOnlySomeReasons() != null && dp.getReasons() != null) { return new ReasonsMask(dp.getReasons()).intersect(new ReasonsMask(idp.getOnlySomeReasons())); } // (d) (4) if ((idp == null || idp.getOnlySomeReasons() == null) && dp.getReasons() == null) { return ReasonsMask.allReasons; } // (d) (2) and (d)(3) return (dp.getReasons() == null ? ReasonsMask.allReasons : new ReasonsMask(dp.getReasons())).intersect(idp == null ? ReasonsMask.allReasons : new ReasonsMask(idp.getOnlySomeReasons())); } public static final String CERTIFICATE_POLICIES = X509Extensions.CertificatePolicies.getId(); public static final String POLICY_MAPPINGS = X509Extensions.PolicyMappings.getId(); public static final String INHIBIT_ANY_POLICY = X509Extensions.InhibitAnyPolicy.getId(); public static final String ISSUING_DISTRIBUTION_POINT = X509Extensions.IssuingDistributionPoint.getId(); public static final String FRESHEST_CRL = X509Extensions.FreshestCRL.getId(); public static final String DELTA_CRL_INDICATOR = X509Extensions.DeltaCRLIndicator.getId(); public static final String POLICY_CONSTRAINTS = X509Extensions.PolicyConstraints.getId(); public static final String BASIC_CONSTRAINTS = X509Extensions.BasicConstraints.getId(); public static final String CRL_DISTRIBUTION_POINTS = X509Extensions.CRLDistributionPoints.getId(); public static final String SUBJECT_ALTERNATIVE_NAME = X509Extensions.SubjectAlternativeName.getId(); public static final String NAME_CONSTRAINTS = X509Extensions.NameConstraints.getId(); public static final String AUTHORITY_KEY_IDENTIFIER = X509Extensions.AuthorityKeyIdentifier.getId(); public static final String KEY_USAGE = X509Extensions.KeyUsage.getId(); public static final String CRL_NUMBER = X509Extensions.CRLNumber.getId(); public static final String ANY_POLICY = "2.5.29.32.0"; /* * key usage bits */ protected static final int KEY_CERT_SIGN = 5; protected static final int CRL_SIGN = 6; /** * Obtain and validate the certification path for the complete CRL issuer. * If a key usage extension is present in the CRL issuer's certificate, * verify that the cRLSign bit is set. * * @param crl CRL which contains revocation information for the certificate * cert. * @param cert The attribute certificate or certificate to check if it is * revoked. * @param defaultCRLSignCert The issuer certificate of the certificate cert. * @param defaultCRLSignKey The public key of the issuer certificate * defaultCRLSignCert. * @param paramsPKIX paramsPKIX PKIX parameters. * @param certPathCerts The certificates on the certification path. * @return A Set with all keys of possible CRL issuer * certificates. * @throws AnnotatedException if the CRL is not valid or the status cannot be checked or * some error occurs. */ protected static Set processCRLF( X509CRL crl, Object cert, X509Certificate defaultCRLSignCert, PublicKey defaultCRLSignKey, ExtendedPKIXParameters paramsPKIX, List certPathCerts) throws AnnotatedException { // (f) // get issuer from CRL X509CertStoreSelector selector = new X509CertStoreSelector(); try { byte[] issuerPrincipal = CertPathValidatorUtilities.getIssuerPrincipal(crl).getEncoded(); selector.setSubject(issuerPrincipal); } catch (IOException e) { throw new AnnotatedException( "Subject criteria for certificate selector to find issuer certificate for CRL could not be set.", e); } // get CRL signing certs Collection coll; try { coll = CertPathValidatorUtilities.findCertificates(selector, paramsPKIX.getStores()); coll.addAll(CertPathValidatorUtilities.findCertificates(selector, paramsPKIX.getAdditionalStores())); coll.addAll(CertPathValidatorUtilities.findCertificates(selector, paramsPKIX.getCertStores())); } catch (AnnotatedException e) { throw new AnnotatedException("Issuer certificate for CRL cannot be searched.", e); } coll.add(defaultCRLSignCert); Iterator cert_it = coll.iterator(); List validCerts = new ArrayList(); List validKeys = new ArrayList(); while (cert_it.hasNext()) { X509Certificate signingCert = (X509Certificate)cert_it.next(); /* * CA of the certificate, for which this CRL is checked, has also * signed CRL, so skip the path validation, because is already done */ if (signingCert.equals(defaultCRLSignCert)) { validCerts.add(signingCert); validKeys.add(defaultCRLSignKey); continue; } try { CertPathBuilder builder = CertPathBuilder.getInstance("PKIX", BouncyCastleProvider.PROVIDER_NAME); selector = new X509CertStoreSelector(); selector.setCertificate(signingCert); ExtendedPKIXParameters temp = (ExtendedPKIXParameters)paramsPKIX.clone(); temp.setTargetCertConstraints(selector); ExtendedPKIXBuilderParameters params = (ExtendedPKIXBuilderParameters)ExtendedPKIXBuilderParameters .getInstance(temp); /* * if signingCert is placed not higher on the cert path a * dependency loop results. CRL for cert is checked, but * signingCert is needed for checking the CRL which is dependent * on checking cert because it is higher in the cert path and so * signing signingCert transitively. so, revocation is disabled, * forgery attacks of the CRL are detected in this outer loop * for all other it must be enabled to prevent forgery attacks */ if (certPathCerts.contains(signingCert)) { params.setRevocationEnabled(false); } else { params.setRevocationEnabled(true); } List certs = builder.build(params).getCertPath().getCertificates(); validCerts.add(signingCert); validKeys.add(CertPathValidatorUtilities.getNextWorkingKey(certs, 0)); } catch (CertPathBuilderException e) { throw new AnnotatedException("Internal error.", e); } catch (CertPathValidatorException e) { throw new AnnotatedException("Public key of issuer certificate of CRL could not be retrieved.", e); } catch (Exception e) { throw new RuntimeException(e.getMessage()); } } Set checkKeys = new HashSet(); AnnotatedException lastException = null; for (int i = 0; i < validCerts.size(); i++) { X509Certificate signCert = (X509Certificate)validCerts.get(i); boolean[] keyusage = signCert.getKeyUsage(); if (keyusage != null && (keyusage.length < 7 || !keyusage[CRL_SIGN])) { lastException = new AnnotatedException( "Issuer certificate key usage extension does not permit CRL signing."); } else { checkKeys.add(validKeys.get(i)); } } if (checkKeys.isEmpty() && lastException == null) { throw new AnnotatedException("Cannot find a valid issuer certificate."); } if (checkKeys.isEmpty() && lastException != null) { throw lastException; } return checkKeys; } protected static PublicKey processCRLG( X509CRL crl, Set keys) throws AnnotatedException { Exception lastException = null; for (Iterator it = keys.iterator(); it.hasNext();) { PublicKey key = (PublicKey)it.next(); try { crl.verify(key); return key; } catch (Exception e) { lastException = e; } } throw new AnnotatedException("Cannot verify CRL.", lastException); } protected static X509CRL processCRLH( Set deltacrls, PublicKey key) throws AnnotatedException { Exception lastException = null; for (Iterator it = deltacrls.iterator(); it.hasNext();) { X509CRL crl = (X509CRL)it.next(); try { crl.verify(key); return crl; } catch (Exception e) { lastException = e; } } if (lastException != null) { throw new AnnotatedException("Cannot verify delta CRL.", lastException); } return null; } protected static Set processCRLA1i( Date currentDate, ExtendedPKIXParameters paramsPKIX, X509Certificate cert, X509CRL crl) throws AnnotatedException { Set set = new HashSet(); if (paramsPKIX.isUseDeltasEnabled()) { CRLDistPoint freshestCRL = null; try { freshestCRL = CRLDistPoint .getInstance(CertPathValidatorUtilities.getExtensionValue(cert, FRESHEST_CRL)); } catch (AnnotatedException e) { throw new AnnotatedException("Freshest CRL extension could not be decoded from certificate.", e); } if (freshestCRL == null) { try { freshestCRL = CRLDistPoint.getInstance(CertPathValidatorUtilities.getExtensionValue(crl, FRESHEST_CRL)); } catch (AnnotatedException e) { throw new AnnotatedException("Freshest CRL extension could not be decoded from CRL.", e); } } if (freshestCRL != null) { try { CertPathValidatorUtilities.addAdditionalStoresFromCRLDistributionPoint(freshestCRL, paramsPKIX); } catch (AnnotatedException e) { throw new AnnotatedException( "No new delta CRL locations could be added from Freshest CRL extension.", e); } // get delta CRL(s) try { set.addAll(CertPathValidatorUtilities.getDeltaCRLs(currentDate, paramsPKIX, crl)); } catch (AnnotatedException e) { throw new AnnotatedException("Exception obtaining delta CRLs.", e); } } } return set; } protected static Set[] processCRLA1ii( Date currentDate, ExtendedPKIXParameters paramsPKIX, X509Certificate cert, X509CRL crl) throws AnnotatedException { Set deltaSet = new HashSet(); X509CRLStoreSelector crlselect = new X509CRLStoreSelector(); crlselect.setCertificateChecking(cert); try { crlselect.addIssuerName(crl.getIssuerX500Principal().getEncoded()); } catch (IOException e) { throw new AnnotatedException("Cannot extract issuer from CRL." + e, e); } crlselect.setCompleteCRLEnabled(true); Set completeSet = CRL_UTIL.findCRLs(crlselect, paramsPKIX, currentDate); if (paramsPKIX.isUseDeltasEnabled()) { // get delta CRL(s) try { deltaSet.addAll(CertPathValidatorUtilities.getDeltaCRLs(currentDate, paramsPKIX, crl)); } catch (AnnotatedException e) { throw new AnnotatedException("Exception obtaining delta CRLs.", e); } } return new Set[] { completeSet, deltaSet}; } /** * If use-deltas is set, verify the issuer and scope of the delta CRL. * * @param deltaCRL The delta CRL. * @param completeCRL The complete CRL. * @param pkixParams The PKIX paramaters. * @throws AnnotatedException if an exception occurs. */ protected static void processCRLC( X509CRL deltaCRL, X509CRL completeCRL, ExtendedPKIXParameters pkixParams) throws AnnotatedException { if (deltaCRL == null) { return; } IssuingDistributionPoint completeidp = null; try { completeidp = IssuingDistributionPoint.getInstance(CertPathValidatorUtilities.getExtensionValue( completeCRL, RFC3280CertPathUtilities.ISSUING_DISTRIBUTION_POINT)); } catch (Exception e) { throw new AnnotatedException("Issuing distribution point extension could not be decoded.", e); } if (pkixParams.isUseDeltasEnabled()) { // (c) (1) if (!deltaCRL.getIssuerX500Principal().equals(completeCRL.getIssuerX500Principal())) { throw new AnnotatedException("Complete CRL issuer does not match delta CRL issuer."); } // (c) (2) IssuingDistributionPoint deltaidp = null; try { deltaidp = IssuingDistributionPoint.getInstance(CertPathValidatorUtilities.getExtensionValue( deltaCRL, ISSUING_DISTRIBUTION_POINT)); } catch (Exception e) { throw new AnnotatedException( "Issuing distribution point extension from delta CRL could not be decoded.", e); } boolean match = false; if (completeidp == null) { if (deltaidp == null) { match = true; } } else { if (completeidp.equals(deltaidp)) { match = true; } } if (!match) { throw new AnnotatedException( "Issuing distribution point extension from delta CRL and complete CRL does not match."); } // (c) (3) ASN1Primitive completeKeyIdentifier = null; try { completeKeyIdentifier = CertPathValidatorUtilities.getExtensionValue( completeCRL, AUTHORITY_KEY_IDENTIFIER); } catch (AnnotatedException e) { throw new AnnotatedException( "Authority key identifier extension could not be extracted from complete CRL.", e); } ASN1Primitive deltaKeyIdentifier = null; try { deltaKeyIdentifier = CertPathValidatorUtilities.getExtensionValue( deltaCRL, AUTHORITY_KEY_IDENTIFIER); } catch (AnnotatedException e) { throw new AnnotatedException( "Authority key identifier extension could not be extracted from delta CRL.", e); } if (completeKeyIdentifier == null) { throw new AnnotatedException("CRL authority key identifier is null."); } if (deltaKeyIdentifier == null) { throw new AnnotatedException("Delta CRL authority key identifier is null."); } if (!completeKeyIdentifier.equals(deltaKeyIdentifier)) { throw new AnnotatedException( "Delta CRL authority key identifier does not match complete CRL authority key identifier."); } } } protected static void processCRLI( Date validDate, X509CRL deltacrl, Object cert, CertStatus certStatus, ExtendedPKIXParameters pkixParams) throws AnnotatedException { if (pkixParams.isUseDeltasEnabled() && deltacrl != null) { CertPathValidatorUtilities.getCertStatus(validDate, deltacrl, cert, certStatus); } } protected static void processCRLJ( Date validDate, X509CRL completecrl, Object cert, CertStatus certStatus) throws AnnotatedException { if (certStatus.getCertStatus() == CertStatus.UNREVOKED) { CertPathValidatorUtilities.getCertStatus(validDate, completecrl, cert, certStatus); } } protected static PKIXPolicyNode prepareCertB( CertPath certPath, int index, List[] policyNodes, PKIXPolicyNode validPolicyTree, int policyMapping) throws CertPathValidatorException { List certs = certPath.getCertificates(); X509Certificate cert = (X509Certificate)certs.get(index); int n = certs.size(); // i as defined in the algorithm description int i = n - index; // (b) // ASN1Sequence pm = null; try { pm = DERSequence.getInstance(CertPathValidatorUtilities.getExtensionValue(cert, RFC3280CertPathUtilities.POLICY_MAPPINGS)); } catch (AnnotatedException ex) { throw new ExtCertPathValidatorException("Policy mappings extension could not be decoded.", ex, certPath, index); } PKIXPolicyNode _validPolicyTree = validPolicyTree; if (pm != null) { ASN1Sequence mappings = (ASN1Sequence)pm; Map m_idp = new HashMap(); Set s_idp = new HashSet(); for (int j = 0; j < mappings.size(); j++) { ASN1Sequence mapping = (ASN1Sequence)mappings.getObjectAt(j); String id_p = ((DERObjectIdentifier)mapping.getObjectAt(0)).getId(); String sd_p = ((DERObjectIdentifier)mapping.getObjectAt(1)).getId(); Set tmp; if (!m_idp.containsKey(id_p)) { tmp = new HashSet(); tmp.add(sd_p); m_idp.put(id_p, tmp); s_idp.add(id_p); } else { tmp = (Set)m_idp.get(id_p); tmp.add(sd_p); } } Iterator it_idp = s_idp.iterator(); while (it_idp.hasNext()) { String id_p = (String)it_idp.next(); // // (1) // if (policyMapping > 0) { boolean idp_found = false; Iterator nodes_i = policyNodes[i].iterator(); while (nodes_i.hasNext()) { PKIXPolicyNode node = (PKIXPolicyNode)nodes_i.next(); if (node.getValidPolicy().equals(id_p)) { idp_found = true; node.expectedPolicies = (Set)m_idp.get(id_p); break; } } if (!idp_found) { nodes_i = policyNodes[i].iterator(); while (nodes_i.hasNext()) { PKIXPolicyNode node = (PKIXPolicyNode)nodes_i.next(); if (RFC3280CertPathUtilities.ANY_POLICY.equals(node.getValidPolicy())) { Set pq = null; ASN1Sequence policies = null; try { policies = (ASN1Sequence)CertPathValidatorUtilities.getExtensionValue(cert, RFC3280CertPathUtilities.CERTIFICATE_POLICIES); } catch (AnnotatedException e) { throw new ExtCertPathValidatorException( "Certificate policies extension could not be decoded.", e, certPath, index); } Enumeration e = policies.getObjects(); while (e.hasMoreElements()) { PolicyInformation pinfo = null; try { pinfo = PolicyInformation.getInstance(e.nextElement()); } catch (Exception ex) { throw new CertPathValidatorException( "Policy information could not be decoded.", ex, certPath, index); } if (RFC3280CertPathUtilities.ANY_POLICY.equals(pinfo.getPolicyIdentifier().getId())) { try { pq = CertPathValidatorUtilities .getQualifierSet(pinfo.getPolicyQualifiers()); } catch (CertPathValidatorException ex) { throw new ExtCertPathValidatorException( "Policy qualifier info set could not be decoded.", ex, certPath, index); } break; } } boolean ci = false; if (cert.getCriticalExtensionOIDs() != null) { ci = cert.getCriticalExtensionOIDs().contains( RFC3280CertPathUtilities.CERTIFICATE_POLICIES); } PKIXPolicyNode p_node = (PKIXPolicyNode)node.getParent(); if (RFC3280CertPathUtilities.ANY_POLICY.equals(p_node.getValidPolicy())) { PKIXPolicyNode c_node = new PKIXPolicyNode(new ArrayList(), i, (Set)m_idp .get(id_p), p_node, pq, id_p, ci); p_node.addChild(c_node); policyNodes[i].add(c_node); } break; } } } // // (2) // } else if (policyMapping <= 0) { Iterator nodes_i = policyNodes[i].iterator(); while (nodes_i.hasNext()) { PKIXPolicyNode node = (PKIXPolicyNode)nodes_i.next(); if (node.getValidPolicy().equals(id_p)) { PKIXPolicyNode p_node = (PKIXPolicyNode)node.getParent(); p_node.removeChild(node); nodes_i.remove(); for (int k = (i - 1); k >= 0; k--) { List nodes = policyNodes[k]; for (int l = 0; l < nodes.size(); l++) { PKIXPolicyNode node2 = (PKIXPolicyNode)nodes.get(l); if (!node2.hasChildren()) { _validPolicyTree = CertPathValidatorUtilities.removePolicyNode( _validPolicyTree, policyNodes, node2); if (_validPolicyTree == null) { break; } } } } } } } } } return _validPolicyTree; } protected static void prepareNextCertA( CertPath certPath, int index) throws CertPathValidatorException { List certs = certPath.getCertificates(); X509Certificate cert = (X509Certificate)certs.get(index); // // // (a) check the policy mappings // ASN1Sequence pm = null; try { pm = DERSequence.getInstance(CertPathValidatorUtilities.getExtensionValue(cert, RFC3280CertPathUtilities.POLICY_MAPPINGS)); } catch (AnnotatedException ex) { throw new ExtCertPathValidatorException("Policy mappings extension could not be decoded.", ex, certPath, index); } if (pm != null) { ASN1Sequence mappings = pm; for (int j = 0; j < mappings.size(); j++) { DERObjectIdentifier issuerDomainPolicy = null; DERObjectIdentifier subjectDomainPolicy = null; try { ASN1Sequence mapping = DERSequence.getInstance(mappings.getObjectAt(j)); issuerDomainPolicy = DERObjectIdentifier.getInstance(mapping.getObjectAt(0)); subjectDomainPolicy = DERObjectIdentifier.getInstance(mapping.getObjectAt(1)); } catch (Exception e) { throw new ExtCertPathValidatorException("Policy mappings extension contents could not be decoded.", e, certPath, index); } if (RFC3280CertPathUtilities.ANY_POLICY.equals(issuerDomainPolicy.getId())) { throw new CertPathValidatorException("IssuerDomainPolicy is anyPolicy", null, certPath, index); } if (RFC3280CertPathUtilities.ANY_POLICY.equals(subjectDomainPolicy.getId())) { throw new CertPathValidatorException("SubjectDomainPolicy is anyPolicy,", null, certPath, index); } } } } protected static void processCertF( CertPath certPath, int index, PKIXPolicyNode validPolicyTree, int explicitPolicy) throws CertPathValidatorException { // // (f) // if (explicitPolicy <= 0 && validPolicyTree == null) { throw new ExtCertPathValidatorException("No valid policy tree found when one expected.", null, certPath, index); } } protected static PKIXPolicyNode processCertE( CertPath certPath, int index, PKIXPolicyNode validPolicyTree) throws CertPathValidatorException { List certs = certPath.getCertificates(); X509Certificate cert = (X509Certificate)certs.get(index); // // (e) // ASN1Sequence certPolicies = null; try { certPolicies = DERSequence.getInstance(CertPathValidatorUtilities.getExtensionValue(cert, RFC3280CertPathUtilities.CERTIFICATE_POLICIES)); } catch (AnnotatedException e) { throw new ExtCertPathValidatorException("Could not read certificate policies extension from certificate.", e, certPath, index); } if (certPolicies == null) { validPolicyTree = null; } return validPolicyTree; } protected static void processCertBC( CertPath certPath, int index, PKIXNameConstraintValidator nameConstraintValidator) throws CertPathValidatorException { List certs = certPath.getCertificates(); X509Certificate cert = (X509Certificate)certs.get(index); int n = certs.size(); // i as defined in the algorithm description int i = n - index; // // (b), (c) permitted and excluded subtree checking. // if (!(CertPathValidatorUtilities.isSelfIssued(cert) && (i < n))) { X500Principal principal = CertPathValidatorUtilities.getSubjectPrincipal(cert); ASN1InputStream aIn = new ASN1InputStream(principal.getEncoded()); ASN1Sequence dns; try { dns = DERSequence.getInstance(aIn.readObject()); } catch (Exception e) { throw new CertPathValidatorException("Exception extracting subject name when checking subtrees.", e, certPath, index); } try { nameConstraintValidator.checkPermittedDN(dns); nameConstraintValidator.checkExcludedDN(dns); } catch (PKIXNameConstraintValidatorException e) { throw new CertPathValidatorException("Subtree check for certificate subject failed.", e, certPath, index); } GeneralNames altName = null; try { altName = GeneralNames.getInstance(CertPathValidatorUtilities.getExtensionValue(cert, RFC3280CertPathUtilities.SUBJECT_ALTERNATIVE_NAME)); } catch (Exception e) { throw new CertPathValidatorException("Subject alternative name extension could not be decoded.", e, certPath, index); } Vector emails = new X509Name(dns).getValues(X509Name.EmailAddress); for (Enumeration e = emails.elements(); e.hasMoreElements();) { String email = (String)e.nextElement(); GeneralName emailAsGeneralName = new GeneralName(GeneralName.rfc822Name, email); try { nameConstraintValidator.checkPermitted(emailAsGeneralName); nameConstraintValidator.checkExcluded(emailAsGeneralName); } catch (PKIXNameConstraintValidatorException ex) { throw new CertPathValidatorException( "Subtree check for certificate subject alternative email failed.", ex, certPath, index); } } if (altName != null) { GeneralName[] genNames = null; try { genNames = altName.getNames(); } catch (Exception e) { throw new CertPathValidatorException("Subject alternative name contents could not be decoded.", e, certPath, index); } for (int j = 0; j < genNames.length; j++) { try { nameConstraintValidator.checkPermitted(genNames[j]); nameConstraintValidator.checkExcluded(genNames[j]); } catch (PKIXNameConstraintValidatorException e) { throw new CertPathValidatorException( "Subtree check for certificate subject alternative name failed.", e, certPath, index); } } } } } protected static PKIXPolicyNode processCertD( CertPath certPath, int index, Set acceptablePolicies, PKIXPolicyNode validPolicyTree, List[] policyNodes, int inhibitAnyPolicy) throws CertPathValidatorException { List certs = certPath.getCertificates(); X509Certificate cert = (X509Certificate)certs.get(index); int n = certs.size(); // i as defined in the algorithm description int i = n - index; // // (d) policy Information checking against initial policy and // policy mapping // ASN1Sequence certPolicies = null; try { certPolicies = DERSequence.getInstance(CertPathValidatorUtilities.getExtensionValue(cert, RFC3280CertPathUtilities.CERTIFICATE_POLICIES)); } catch (AnnotatedException e) { throw new ExtCertPathValidatorException("Could not read certificate policies extension from certificate.", e, certPath, index); } if (certPolicies != null && validPolicyTree != null) { // // (d) (1) // Enumeration e = certPolicies.getObjects(); Set pols = new HashSet(); while (e.hasMoreElements()) { PolicyInformation pInfo = PolicyInformation.getInstance(e.nextElement()); DERObjectIdentifier pOid = pInfo.getPolicyIdentifier(); pols.add(pOid.getId()); if (!RFC3280CertPathUtilities.ANY_POLICY.equals(pOid.getId())) { Set pq = null; try { pq = CertPathValidatorUtilities.getQualifierSet(pInfo.getPolicyQualifiers()); } catch (CertPathValidatorException ex) { throw new ExtCertPathValidatorException("Policy qualifier info set could not be build.", ex, certPath, index); } boolean match = CertPathValidatorUtilities.processCertD1i(i, policyNodes, pOid, pq); if (!match) { CertPathValidatorUtilities.processCertD1ii(i, policyNodes, pOid, pq); } } } if (acceptablePolicies.isEmpty() || acceptablePolicies.contains(RFC3280CertPathUtilities.ANY_POLICY)) { acceptablePolicies.clear(); acceptablePolicies.addAll(pols); } else { Iterator it = acceptablePolicies.iterator(); Set t1 = new HashSet(); while (it.hasNext()) { Object o = it.next(); if (pols.contains(o)) { t1.add(o); } } acceptablePolicies.clear(); acceptablePolicies.addAll(t1); } // // (d) (2) // if ((inhibitAnyPolicy > 0) || ((i < n) && CertPathValidatorUtilities.isSelfIssued(cert))) { e = certPolicies.getObjects(); while (e.hasMoreElements()) { PolicyInformation pInfo = PolicyInformation.getInstance(e.nextElement()); if (RFC3280CertPathUtilities.ANY_POLICY.equals(pInfo.getPolicyIdentifier().getId())) { Set _apq = CertPathValidatorUtilities.getQualifierSet(pInfo.getPolicyQualifiers()); List _nodes = policyNodes[i - 1]; for (int k = 0; k < _nodes.size(); k++) { PKIXPolicyNode _node = (PKIXPolicyNode)_nodes.get(k); Iterator _policySetIter = _node.getExpectedPolicies().iterator(); while (_policySetIter.hasNext()) { Object _tmp = _policySetIter.next(); String _policy; if (_tmp instanceof String) { _policy = (String)_tmp; } else if (_tmp instanceof DERObjectIdentifier) { _policy = ((DERObjectIdentifier)_tmp).getId(); } else { continue; } boolean _found = false; Iterator _childrenIter = _node.getChildren(); while (_childrenIter.hasNext()) { PKIXPolicyNode _child = (PKIXPolicyNode)_childrenIter.next(); if (_policy.equals(_child.getValidPolicy())) { _found = true; } } if (!_found) { Set _newChildExpectedPolicies = new HashSet(); _newChildExpectedPolicies.add(_policy); PKIXPolicyNode _newChild = new PKIXPolicyNode(new ArrayList(), i, _newChildExpectedPolicies, _node, _apq, _policy, false); _node.addChild(_newChild); policyNodes[i].add(_newChild); } } } break; } } } PKIXPolicyNode _validPolicyTree = validPolicyTree; // // (d) (3) // for (int j = (i - 1); j >= 0; j--) { List nodes = policyNodes[j]; for (int k = 0; k < nodes.size(); k++) { PKIXPolicyNode node = (PKIXPolicyNode)nodes.get(k); if (!node.hasChildren()) { _validPolicyTree = CertPathValidatorUtilities.removePolicyNode(_validPolicyTree, policyNodes, node); if (_validPolicyTree == null) { break; } } } } // // d (4) // Set criticalExtensionOids = cert.getCriticalExtensionOIDs(); if (criticalExtensionOids != null) { boolean critical = criticalExtensionOids.contains(RFC3280CertPathUtilities.CERTIFICATE_POLICIES); List nodes = policyNodes[i]; for (int j = 0; j < nodes.size(); j++) { PKIXPolicyNode node = (PKIXPolicyNode)nodes.get(j); node.setCritical(critical); } } return _validPolicyTree; } return null; } protected static void processCertA( CertPath certPath, ExtendedPKIXParameters paramsPKIX, int index, PublicKey workingPublicKey, boolean verificationAlreadyPerformed, X500Principal workingIssuerName, X509Certificate sign) throws ExtCertPathValidatorException { List certs = certPath.getCertificates(); X509Certificate cert = (X509Certificate)certs.get(index); // // (a) verify // if (!verificationAlreadyPerformed) { try { // (a) (1) // CertPathValidatorUtilities.verifyX509Certificate(cert, workingPublicKey, paramsPKIX.getSigProvider()); } catch (GeneralSecurityException e) { throw new ExtCertPathValidatorException("Could not validate certificate signature.", e, certPath, index); } } try { // (a) (2) // cert.checkValidity(CertPathValidatorUtilities .getValidCertDateFromValidityModel(paramsPKIX, certPath, index)); } catch (CertificateExpiredException e) { throw new ExtCertPathValidatorException("Could not validate certificate: " + e.getMessage(), e, certPath, index); } catch (CertificateNotYetValidException e) { throw new ExtCertPathValidatorException("Could not validate certificate: " + e.getMessage(), e, certPath, index); } catch (AnnotatedException e) { throw new ExtCertPathValidatorException("Could not validate time of certificate.", e, certPath, index); } // // (a) (3) // if (paramsPKIX.isRevocationEnabled()) { try { checkCRLs(paramsPKIX, cert, CertPathValidatorUtilities.getValidCertDateFromValidityModel(paramsPKIX, certPath, index), sign, workingPublicKey, certs); } catch (AnnotatedException e) { Throwable cause = e; if (null != e.getCause()) { cause = e.getCause(); } throw new ExtCertPathValidatorException(e.getMessage(), cause, certPath, index); } } // // (a) (4) name chaining // if (!CertPathValidatorUtilities.getEncodedIssuerPrincipal(cert).equals(workingIssuerName)) { throw new ExtCertPathValidatorException("IssuerName(" + CertPathValidatorUtilities.getEncodedIssuerPrincipal(cert) + ") does not match SubjectName(" + workingIssuerName + ") of signing certificate.", null, certPath, index); } } protected static int prepareNextCertI1( CertPath certPath, int index, int explicitPolicy) throws CertPathValidatorException { List certs = certPath.getCertificates(); X509Certificate cert = (X509Certificate)certs.get(index); // // (i) // ASN1Sequence pc = null; try { pc = DERSequence.getInstance(CertPathValidatorUtilities.getExtensionValue(cert, RFC3280CertPathUtilities.POLICY_CONSTRAINTS)); } catch (Exception e) { throw new ExtCertPathValidatorException("Policy constraints extension cannot be decoded.", e, certPath, index); } int tmpInt; if (pc != null) { Enumeration policyConstraints = pc.getObjects(); while (policyConstraints.hasMoreElements()) { try { ASN1TaggedObject constraint = ASN1TaggedObject.getInstance(policyConstraints.nextElement()); if (constraint.getTagNo() == 0) { tmpInt = DERInteger.getInstance(constraint, false).getValue().intValue(); if (tmpInt < explicitPolicy) { return tmpInt; } break; } } catch (IllegalArgumentException e) { throw new ExtCertPathValidatorException("Policy constraints extension contents cannot be decoded.", e, certPath, index); } } } return explicitPolicy; } protected static int prepareNextCertI2( CertPath certPath, int index, int policyMapping) throws CertPathValidatorException { List certs = certPath.getCertificates(); X509Certificate cert = (X509Certificate)certs.get(index); // // (i) // ASN1Sequence pc = null; try { pc = DERSequence.getInstance(CertPathValidatorUtilities.getExtensionValue(cert, RFC3280CertPathUtilities.POLICY_CONSTRAINTS)); } catch (Exception e) { throw new ExtCertPathValidatorException("Policy constraints extension cannot be decoded.", e, certPath, index); } int tmpInt; if (pc != null) { Enumeration policyConstraints = pc.getObjects(); while (policyConstraints.hasMoreElements()) { try { ASN1TaggedObject constraint = ASN1TaggedObject.getInstance(policyConstraints.nextElement()); if (constraint.getTagNo() == 1) { tmpInt = DERInteger.getInstance(constraint, false).getValue().intValue(); if (tmpInt < policyMapping) { return tmpInt; } break; } } catch (IllegalArgumentException e) { throw new ExtCertPathValidatorException("Policy constraints extension contents cannot be decoded.", e, certPath, index); } } } return policyMapping; } protected static void prepareNextCertG( CertPath certPath, int index, PKIXNameConstraintValidator nameConstraintValidator) throws CertPathValidatorException { List certs = certPath.getCertificates(); X509Certificate cert = (X509Certificate)certs.get(index); // // (g) handle the name constraints extension // NameConstraints nc = null; try { ASN1Sequence ncSeq = DERSequence.getInstance(CertPathValidatorUtilities.getExtensionValue(cert, RFC3280CertPathUtilities.NAME_CONSTRAINTS)); if (ncSeq != null) { nc = NameConstraints.getInstance(ncSeq); } } catch (Exception e) { throw new ExtCertPathValidatorException("Name constraints extension could not be decoded.", e, certPath, index); } if (nc != null) { // // (g) (1) permitted subtrees // GeneralSubtree[] permitted = nc.getPermittedSubtrees(); if (permitted != null) { try { nameConstraintValidator.intersectPermittedSubtree(permitted); } catch (Exception ex) { throw new ExtCertPathValidatorException( "Permitted subtrees cannot be build from name constraints extension.", ex, certPath, index); } } // // (g) (2) excluded subtrees // GeneralSubtree[] excluded = nc.getExcludedSubtrees(); if (excluded != null) { for (int i = 0; i != excluded.length; i++) try { nameConstraintValidator.addExcludedSubtree(excluded[i]); } catch (Exception ex) { throw new ExtCertPathValidatorException( "Excluded subtrees cannot be build from name constraints extension.", ex, certPath, index); } } } } /** * Checks a distribution point for revocation information for the * certificate cert. * * @param dp The distribution point to consider. * @param paramsPKIX PKIX parameters. * @param cert Certificate to check if it is revoked. * @param validDate The date when the certificate revocation status should be * checked. * @param defaultCRLSignCert The issuer certificate of the certificate cert. * @param defaultCRLSignKey The public key of the issuer certificate * defaultCRLSignCert. * @param certStatus The current certificate revocation status. * @param reasonMask The reasons mask which is already checked. * @param certPathCerts The certificates of the certification path. * @throws AnnotatedException if the certificate is revoked or the status cannot be checked * or some error occurs. */ private static void checkCRL( DistributionPoint dp, ExtendedPKIXParameters paramsPKIX, X509Certificate cert, Date validDate, X509Certificate defaultCRLSignCert, PublicKey defaultCRLSignKey, CertStatus certStatus, ReasonsMask reasonMask, List certPathCerts) throws AnnotatedException { Date currentDate = new Date(System.currentTimeMillis()); if (validDate.getTime() > currentDate.getTime()) { throw new AnnotatedException("Validation time is in future."); } // (a) /* * We always get timely valid CRLs, so there is no step (a) (1). * "locally cached" CRLs are assumed to be in getStore(), additional * CRLs must be enabled in the ExtendedPKIXParameters and are in * getAdditionalStore() */ Set crls = CertPathValidatorUtilities.getCompleteCRLs(dp, cert, currentDate, paramsPKIX); boolean validCrlFound = false; AnnotatedException lastException = null; Iterator crl_iter = crls.iterator(); while (crl_iter.hasNext() && certStatus.getCertStatus() == CertStatus.UNREVOKED && !reasonMask.isAllReasons()) { try { X509CRL crl = (X509CRL)crl_iter.next(); // (d) ReasonsMask interimReasonsMask = RFC3280CertPathUtilities.processCRLD(crl, dp); // (e) /* * The reasons mask is updated at the end, so only valid CRLs * can update it. If this CRL does not contain new reasons it * must be ignored. */ if (!interimReasonsMask.hasNewReasons(reasonMask)) { continue; } // (f) Set keys = RFC3280CertPathUtilities.processCRLF(crl, cert, defaultCRLSignCert, defaultCRLSignKey, paramsPKIX, certPathCerts); // (g) PublicKey key = RFC3280CertPathUtilities.processCRLG(crl, keys); X509CRL deltaCRL = null; if (paramsPKIX.isUseDeltasEnabled()) { // get delta CRLs Set deltaCRLs = CertPathValidatorUtilities.getDeltaCRLs(currentDate, paramsPKIX, crl); // we only want one valid delta CRL // (h) deltaCRL = RFC3280CertPathUtilities.processCRLH(deltaCRLs, key); } /* * CRL must be be valid at the current time, not the validation * time. If a certificate is revoked with reason keyCompromise, * cACompromise, it can be used for forgery, also for the past. * This reason may not be contained in older CRLs. */ /* * in the chain model signatures stay valid also after the * certificate has been expired, so they do not have to be in * the CRL validity time */ if (paramsPKIX.getValidityModel() != ExtendedPKIXParameters.CHAIN_VALIDITY_MODEL) { /* * if a certificate has expired, but was revoked, it is not * more in the CRL, so it would be regarded as valid if the * first check is not done */ if (cert.getNotAfter().getTime() < crl.getThisUpdate().getTime()) { throw new AnnotatedException("No valid CRL for current time found."); } } RFC3280CertPathUtilities.processCRLB1(dp, cert, crl); // (b) (2) RFC3280CertPathUtilities.processCRLB2(dp, cert, crl); // (c) RFC3280CertPathUtilities.processCRLC(deltaCRL, crl, paramsPKIX); // (i) RFC3280CertPathUtilities.processCRLI(validDate, deltaCRL, cert, certStatus, paramsPKIX); // (j) RFC3280CertPathUtilities.processCRLJ(validDate, crl, cert, certStatus); // (k) if (certStatus.getCertStatus() == CRLReason.removeFromCRL) { certStatus.setCertStatus(CertStatus.UNREVOKED); } // update reasons mask reasonMask.addReasons(interimReasonsMask); Set criticalExtensions = crl.getCriticalExtensionOIDs(); if (criticalExtensions != null) { criticalExtensions = new HashSet(criticalExtensions); criticalExtensions.remove(X509Extensions.IssuingDistributionPoint.getId()); criticalExtensions.remove(X509Extensions.DeltaCRLIndicator.getId()); if (!criticalExtensions.isEmpty()) { throw new AnnotatedException("CRL contains unsupported critical extensions."); } } if (deltaCRL != null) { criticalExtensions = deltaCRL.getCriticalExtensionOIDs(); if (criticalExtensions != null) { criticalExtensions = new HashSet(criticalExtensions); criticalExtensions.remove(X509Extensions.IssuingDistributionPoint.getId()); criticalExtensions.remove(X509Extensions.DeltaCRLIndicator.getId()); if (!criticalExtensions.isEmpty()) { throw new AnnotatedException("Delta CRL contains unsupported critical extension."); } } } validCrlFound = true; } catch (AnnotatedException e) { lastException = e; } } if (!validCrlFound) { throw lastException; } } /** * Checks a certificate if it is revoked. * * @param paramsPKIX PKIX parameters. * @param cert Certificate to check if it is revoked. * @param validDate The date when the certificate revocation status should be * checked. * @param sign The issuer certificate of the certificate cert. * @param workingPublicKey The public key of the issuer certificate sign. * @param certPathCerts The certificates of the certification path. * @throws AnnotatedException if the certificate is revoked or the status cannot be checked * or some error occurs. */ protected static void checkCRLs( ExtendedPKIXParameters paramsPKIX, X509Certificate cert, Date validDate, X509Certificate sign, PublicKey workingPublicKey, List certPathCerts) throws AnnotatedException { AnnotatedException lastException = null; CRLDistPoint crldp = null; try { crldp = CRLDistPoint.getInstance(CertPathValidatorUtilities.getExtensionValue(cert, RFC3280CertPathUtilities.CRL_DISTRIBUTION_POINTS)); } catch (Exception e) { throw new AnnotatedException("CRL distribution point extension could not be read.", e); } try { CertPathValidatorUtilities.addAdditionalStoresFromCRLDistributionPoint(crldp, paramsPKIX); } catch (AnnotatedException e) { throw new AnnotatedException( "No additional CRL locations could be decoded from CRL distribution point extension.", e); } CertStatus certStatus = new CertStatus(); ReasonsMask reasonsMask = new ReasonsMask(); boolean validCrlFound = false; // for each distribution point if (crldp != null) { DistributionPoint dps[] = null; try { dps = crldp.getDistributionPoints(); } catch (Exception e) { throw new AnnotatedException("Distribution points could not be read.", e); } if (dps != null) { for (int i = 0; i < dps.length && certStatus.getCertStatus() == CertStatus.UNREVOKED && !reasonsMask.isAllReasons(); i++) { ExtendedPKIXParameters paramsPKIXClone = (ExtendedPKIXParameters)paramsPKIX.clone(); try { checkCRL(dps[i], paramsPKIXClone, cert, validDate, sign, workingPublicKey, certStatus, reasonsMask, certPathCerts); validCrlFound = true; } catch (AnnotatedException e) { lastException = e; } } } } /* * If the revocation status has not been determined, repeat the process * above with any available CRLs not specified in a distribution point * but issued by the certificate issuer. */ if (certStatus.getCertStatus() == CertStatus.UNREVOKED && !reasonsMask.isAllReasons()) { try { /* * assume a DP with both the reasons and the cRLIssuer fields * omitted and a distribution point name of the certificate * issuer. */ ASN1Primitive issuer = null; try { issuer = new ASN1InputStream(CertPathValidatorUtilities.getEncodedIssuerPrincipal(cert).getEncoded()) .readObject(); } catch (Exception e) { throw new AnnotatedException("Issuer from certificate for CRL could not be reencoded.", e); } DistributionPoint dp = new DistributionPoint(new DistributionPointName(0, new GeneralNames( new GeneralName(GeneralName.directoryName, issuer))), null, null); ExtendedPKIXParameters paramsPKIXClone = (ExtendedPKIXParameters)paramsPKIX.clone(); checkCRL(dp, paramsPKIXClone, cert, validDate, sign, workingPublicKey, certStatus, reasonsMask, certPathCerts); validCrlFound = true; } catch (AnnotatedException e) { lastException = e; } } if (!validCrlFound) { if (lastException instanceof AnnotatedException) { throw lastException; } throw new AnnotatedException("No valid CRL found.", lastException); } if (certStatus.getCertStatus() != CertStatus.UNREVOKED) { String message = "Certificate revocation after " + certStatus.getRevocationDate(); message += ", reason: " + crlReasons[certStatus.getCertStatus()]; throw new AnnotatedException(message); } if (!reasonsMask.isAllReasons() && certStatus.getCertStatus() == CertStatus.UNREVOKED) { certStatus.setCertStatus(CertStatus.UNDETERMINED); } if (certStatus.getCertStatus() == CertStatus.UNDETERMINED) { throw new AnnotatedException("Certificate status could not be determined."); } } protected static int prepareNextCertJ( CertPath certPath, int index, int inhibitAnyPolicy) throws CertPathValidatorException { List certs = certPath.getCertificates(); X509Certificate cert = (X509Certificate)certs.get(index); // // (j) // DERInteger iap = null; try { iap = DERInteger.getInstance(CertPathValidatorUtilities.getExtensionValue(cert, RFC3280CertPathUtilities.INHIBIT_ANY_POLICY)); } catch (Exception e) { throw new ExtCertPathValidatorException("Inhibit any-policy extension cannot be decoded.", e, certPath, index); } if (iap != null) { int _inhibitAnyPolicy = iap.getValue().intValue(); if (_inhibitAnyPolicy < inhibitAnyPolicy) { return _inhibitAnyPolicy; } } return inhibitAnyPolicy; } protected static void prepareNextCertK( CertPath certPath, int index) throws CertPathValidatorException { List certs = certPath.getCertificates(); X509Certificate cert = (X509Certificate)certs.get(index); // // (k) // BasicConstraints bc = null; try { bc = BasicConstraints.getInstance(CertPathValidatorUtilities.getExtensionValue(cert, RFC3280CertPathUtilities.BASIC_CONSTRAINTS)); } catch (Exception e) { throw new ExtCertPathValidatorException("Basic constraints extension cannot be decoded.", e, certPath, index); } if (bc != null) { if (!(bc.isCA())) { throw new CertPathValidatorException("Not a CA certificate"); } } else { throw new CertPathValidatorException("Intermediate certificate lacks BasicConstraints"); } } protected static int prepareNextCertL( CertPath certPath, int index, int maxPathLength) throws CertPathValidatorException { List certs = certPath.getCertificates(); X509Certificate cert = (X509Certificate)certs.get(index); // // (l) // if (!CertPathValidatorUtilities.isSelfIssued(cert)) { if (maxPathLength <= 0) { throw new ExtCertPathValidatorException("Max path length not greater than zero", null, certPath, index); } return maxPathLength - 1; } return maxPathLength; } protected static int prepareNextCertM( CertPath certPath, int index, int maxPathLength) throws CertPathValidatorException { List certs = certPath.getCertificates(); X509Certificate cert = (X509Certificate)certs.get(index); // // (m) // BasicConstraints bc = null; try { bc = BasicConstraints.getInstance(CertPathValidatorUtilities.getExtensionValue(cert, RFC3280CertPathUtilities.BASIC_CONSTRAINTS)); } catch (Exception e) { throw new ExtCertPathValidatorException("Basic constraints extension cannot be decoded.", e, certPath, index); } if (bc != null) { BigInteger _pathLengthConstraint = bc.getPathLenConstraint(); if (_pathLengthConstraint != null) { int _plc = _pathLengthConstraint.intValue(); if (_plc < maxPathLength) { return _plc; } } } return maxPathLength; } protected static void prepareNextCertN( CertPath certPath, int index) throws CertPathValidatorException { List certs = certPath.getCertificates(); X509Certificate cert = (X509Certificate)certs.get(index); // // (n) // boolean[] _usage = cert.getKeyUsage(); if ((_usage != null) && !_usage[RFC3280CertPathUtilities.KEY_CERT_SIGN]) { throw new ExtCertPathValidatorException( "Issuer certificate keyusage extension is critical and does not permit key signing.", null, certPath, index); } } protected static void prepareNextCertO( CertPath certPath, int index, Set criticalExtensions, List pathCheckers) throws CertPathValidatorException { List certs = certPath.getCertificates(); X509Certificate cert = (X509Certificate)certs.get(index); // // (o) // Iterator tmpIter; tmpIter = pathCheckers.iterator(); while (tmpIter.hasNext()) { try { ((PKIXCertPathChecker)tmpIter.next()).check(cert, criticalExtensions); } catch (CertPathValidatorException e) { throw new CertPathValidatorException(e.getMessage(), e.getCause(), certPath, index); } } if (!criticalExtensions.isEmpty()) { throw new ExtCertPathValidatorException("Certificate has unsupported critical extension: " + criticalExtensions, null, certPath, index); } } protected static int prepareNextCertH1( CertPath certPath, int index, int explicitPolicy) { List certs = certPath.getCertificates(); X509Certificate cert = (X509Certificate)certs.get(index); // // (h) // if (!CertPathValidatorUtilities.isSelfIssued(cert)) { // // (1) // if (explicitPolicy != 0) { return explicitPolicy - 1; } } return explicitPolicy; } protected static int prepareNextCertH2( CertPath certPath, int index, int policyMapping) { List certs = certPath.getCertificates(); X509Certificate cert = (X509Certificate)certs.get(index); // // (h) // if (!CertPathValidatorUtilities.isSelfIssued(cert)) { // // (2) // if (policyMapping != 0) { return policyMapping - 1; } } return policyMapping; } protected static int prepareNextCertH3( CertPath certPath, int index, int inhibitAnyPolicy) { List certs = certPath.getCertificates(); X509Certificate cert = (X509Certificate)certs.get(index); // // (h) // if (!CertPathValidatorUtilities.isSelfIssued(cert)) { // // (3) // if (inhibitAnyPolicy != 0) { return inhibitAnyPolicy - 1; } } return inhibitAnyPolicy; } protected static final String[] crlReasons = new String[] { "unspecified", "keyCompromise", "cACompromise", "affiliationChanged", "superseded", "cessationOfOperation", "certificateHold", "unknown", "removeFromCRL", "privilegeWithdrawn", "aACompromise"}; protected static int wrapupCertA( int explicitPolicy, X509Certificate cert) { // // (a) // if (!CertPathValidatorUtilities.isSelfIssued(cert) && (explicitPolicy != 0)) { explicitPolicy--; } return explicitPolicy; } protected static int wrapupCertB( CertPath certPath, int index, int explicitPolicy) throws CertPathValidatorException { List certs = certPath.getCertificates(); X509Certificate cert = (X509Certificate)certs.get(index); // // (b) // int tmpInt; ASN1Sequence pc = null; try { pc = DERSequence.getInstance(CertPathValidatorUtilities.getExtensionValue(cert, RFC3280CertPathUtilities.POLICY_CONSTRAINTS)); } catch (AnnotatedException e) { throw new ExtCertPathValidatorException("Policy constraints could not be decoded.", e, certPath, index); } if (pc != null) { Enumeration policyConstraints = pc.getObjects(); while (policyConstraints.hasMoreElements()) { ASN1TaggedObject constraint = (ASN1TaggedObject)policyConstraints.nextElement(); switch (constraint.getTagNo()) { case 0: try { tmpInt = DERInteger.getInstance(constraint, false).getValue().intValue(); } catch (Exception e) { throw new ExtCertPathValidatorException( "Policy constraints requireExplicitPolicy field could not be decoded.", e, certPath, index); } if (tmpInt == 0) { return 0; } break; } } } return explicitPolicy; } protected static void wrapupCertF( CertPath certPath, int index, List pathCheckers, Set criticalExtensions) throws CertPathValidatorException { List certs = certPath.getCertificates(); X509Certificate cert = (X509Certificate)certs.get(index); Iterator tmpIter; tmpIter = pathCheckers.iterator(); while (tmpIter.hasNext()) { try { ((PKIXCertPathChecker)tmpIter.next()).check(cert, criticalExtensions); } catch (CertPathValidatorException e) { throw new ExtCertPathValidatorException("Additional certificate path checker failed.", e, certPath, index); } } if (!criticalExtensions.isEmpty()) { throw new ExtCertPathValidatorException("Certificate has unsupported critical extension: " + criticalExtensions, null, certPath, index); } } protected static PKIXPolicyNode wrapupCertG( CertPath certPath, ExtendedPKIXParameters paramsPKIX, Set userInitialPolicySet, int index, List[] policyNodes, PKIXPolicyNode validPolicyTree, Set acceptablePolicies) throws CertPathValidatorException { int n = certPath.getCertificates().size(); // // (g) // PKIXPolicyNode intersection; // // (g) (i) // if (validPolicyTree == null) { if (paramsPKIX.isExplicitPolicyRequired()) { throw new ExtCertPathValidatorException("Explicit policy requested but none available.", null, certPath, index); } intersection = null; } else if (CertPathValidatorUtilities.isAnyPolicy(userInitialPolicySet)) // (g) // (ii) { if (paramsPKIX.isExplicitPolicyRequired()) { if (acceptablePolicies.isEmpty()) { throw new ExtCertPathValidatorException("Explicit policy requested but none available.", null, certPath, index); } else { Set _validPolicyNodeSet = new HashSet(); for (int j = 0; j < policyNodes.length; j++) { List _nodeDepth = policyNodes[j]; for (int k = 0; k < _nodeDepth.size(); k++) { PKIXPolicyNode _node = (PKIXPolicyNode)_nodeDepth.get(k); if (RFC3280CertPathUtilities.ANY_POLICY.equals(_node.getValidPolicy())) { Iterator _iter = _node.getChildren(); while (_iter.hasNext()) { _validPolicyNodeSet.add(_iter.next()); } } } } Iterator _vpnsIter = _validPolicyNodeSet.iterator(); while (_vpnsIter.hasNext()) { PKIXPolicyNode _node = (PKIXPolicyNode)_vpnsIter.next(); String _validPolicy = _node.getValidPolicy(); if (!acceptablePolicies.contains(_validPolicy)) { // validPolicyTree = // removePolicyNode(validPolicyTree, policyNodes, // _node); } } if (validPolicyTree != null) { for (int j = (n - 1); j >= 0; j--) { List nodes = policyNodes[j]; for (int k = 0; k < nodes.size(); k++) { PKIXPolicyNode node = (PKIXPolicyNode)nodes.get(k); if (!node.hasChildren()) { validPolicyTree = CertPathValidatorUtilities.removePolicyNode(validPolicyTree, policyNodes, node); } } } } } } intersection = validPolicyTree; } else { // // (g) (iii) // // This implementation is not exactly same as the one described in // RFC3280. // However, as far as the validation result is concerned, both // produce // adequate result. The only difference is whether AnyPolicy is // remain // in the policy tree or not. // // (g) (iii) 1 // Set _validPolicyNodeSet = new HashSet(); for (int j = 0; j < policyNodes.length; j++) { List _nodeDepth = policyNodes[j]; for (int k = 0; k < _nodeDepth.size(); k++) { PKIXPolicyNode _node = (PKIXPolicyNode)_nodeDepth.get(k); if (RFC3280CertPathUtilities.ANY_POLICY.equals(_node.getValidPolicy())) { Iterator _iter = _node.getChildren(); while (_iter.hasNext()) { PKIXPolicyNode _c_node = (PKIXPolicyNode)_iter.next(); if (!RFC3280CertPathUtilities.ANY_POLICY.equals(_c_node.getValidPolicy())) { _validPolicyNodeSet.add(_c_node); } } } } } // // (g) (iii) 2 // Iterator _vpnsIter = _validPolicyNodeSet.iterator(); while (_vpnsIter.hasNext()) { PKIXPolicyNode _node = (PKIXPolicyNode)_vpnsIter.next(); String _validPolicy = _node.getValidPolicy(); if (!userInitialPolicySet.contains(_validPolicy)) { validPolicyTree = CertPathValidatorUtilities.removePolicyNode(validPolicyTree, policyNodes, _node); } } // // (g) (iii) 4 // if (validPolicyTree != null) { for (int j = (n - 1); j >= 0; j--) { List nodes = policyNodes[j]; for (int k = 0; k < nodes.size(); k++) { PKIXPolicyNode node = (PKIXPolicyNode)nodes.get(k); if (!node.hasChildren()) { validPolicyTree = CertPathValidatorUtilities.removePolicyNode(validPolicyTree, policyNodes, node); } } } } intersection = validPolicyTree; } return intersection; } } bouncycastle-1.49.orig/src/org/bouncycastle/jce/provider/CertStatus.java0000644000175000017500000000152711624640051026045 0ustar ebourgebourgpackage org.bouncycastle.jce.provider; import java.util.Date; class CertStatus { public static final int UNREVOKED = 11; public static final int UNDETERMINED = 12; int certStatus = UNREVOKED; Date revocationDate = null; /** * @return Returns the revocationDate. */ public Date getRevocationDate() { return revocationDate; } /** * @param revocationDate The revocationDate to set. */ public void setRevocationDate(Date revocationDate) { this.revocationDate = revocationDate; } /** * @return Returns the certStatus. */ public int getCertStatus() { return certStatus; } /** * @param certStatus The certStatus to set. */ public void setCertStatus(int certStatus) { this.certStatus = certStatus; } } bouncycastle-1.49.orig/src/org/bouncycastle/jce/provider/BouncyCastleProvider.java0000644000175000017500000002373012152004717030052 0ustar ebourgebourgpackage org.bouncycastle.jce.provider; import java.io.IOException; import java.security.AccessController; import java.security.PrivateKey; import java.security.PrivilegedAction; import java.security.Provider; import java.security.PublicKey; import java.util.HashMap; import java.util.Map; import org.bouncycastle.asn1.ASN1ObjectIdentifier; import org.bouncycastle.asn1.pkcs.PrivateKeyInfo; import org.bouncycastle.asn1.x509.SubjectPublicKeyInfo; import org.bouncycastle.jcajce.provider.config.ConfigurableProvider; import org.bouncycastle.jcajce.provider.config.ProviderConfiguration; import org.bouncycastle.jcajce.provider.util.AlgorithmProvider; import org.bouncycastle.jcajce.provider.util.AsymmetricKeyInfoConverter; /** * To add the provider at runtime use: *
     * import java.security.Security;
     * import org.bouncycastle.jce.provider.BouncyCastleProvider;
     *
     * Security.addProvider(new BouncyCastleProvider());
     * 
    * The provider can also be configured as part of your environment via * static registration by adding an entry to the java.security properties * file (found in $JAVA_HOME/jre/lib/security/java.security, where * $JAVA_HOME is the location of your JDK/JRE distribution). You'll find * detailed instructions in the file but basically it comes down to adding * a line: *
     * 
     *    security.provider.<n>=org.bouncycastle.jce.provider.BouncyCastleProvider
     * 
     * 
    * Where <n> is the preference you want the provider at (1 being the * most preferred). *

    Note: JCE algorithm names should be upper-case only so the case insensitive * test for getInstance works. */ public final class BouncyCastleProvider extends Provider implements ConfigurableProvider { private static String info = "BouncyCastle Security Provider v1.49"; public static final String PROVIDER_NAME = "BC"; public static final ProviderConfiguration CONFIGURATION = new BouncyCastleProviderConfiguration(); private static final Map keyInfoConverters = new HashMap(); /* * Configurable symmetric ciphers */ private static final String SYMMETRIC_PACKAGE = "org.bouncycastle.jcajce.provider.symmetric."; private static final String[] SYMMETRIC_GENERIC = { "PBEPBKDF2", "PBEPKCS12" }; private static final String[] SYMMETRIC_MACS = { "SipHash" }; private static final String[] SYMMETRIC_CIPHERS = { "AES", "ARC4", "Blowfish", "Camellia", "CAST5", "CAST6", "DES", "DESede", "GOST28147", "Grainv1", "Grain128", "HC128", "HC256", "IDEA", "Noekeon", "RC2", "RC5", "RC6", "Rijndael", "Salsa20", "SEED", "Serpent", "Skipjack", "TEA", "Twofish", "VMPC", "VMPCKSA3", "XTEA" }; /* * Configurable asymmetric ciphers */ private static final String ASYMMETRIC_PACKAGE = "org.bouncycastle.jcajce.provider.asymmetric."; // this one is required for GNU class path - it needs to be loaded first as the // later ones configure it. private static final String[] ASYMMETRIC_GENERIC = { "X509", "IES" }; private static final String[] ASYMMETRIC_CIPHERS = { "DSA", "DH", "EC", "RSA", "GOST", "ECGOST", "ElGamal", "DSTU4145" }; /* * Configurable digests */ private static final String DIGEST_PACKAGE = "org.bouncycastle.jcajce.provider.digest."; private static final String[] DIGESTS = { "GOST3411", "MD2", "MD4", "MD5", "SHA1", "RIPEMD128", "RIPEMD160", "RIPEMD256", "RIPEMD320", "SHA224", "SHA256", "SHA384", "SHA512", "SHA3", "Tiger", "Whirlpool" }; /* * Configurable digests */ private static final String KEYSTORE_PACKAGE = "org.bouncycastle.jcajce.provider.keystore."; private static final String[] KEYSTORES = { "BC", "PKCS12" }; /** * Construct a new provider. This should only be required when * using runtime registration of the provider using the * Security.addProvider() mechanism. */ public BouncyCastleProvider() { super(PROVIDER_NAME, 1.49, info); AccessController.doPrivileged(new PrivilegedAction() { public Object run() { setup(); return null; } }); } private void setup() { loadAlgorithms(DIGEST_PACKAGE, DIGESTS); loadAlgorithms(SYMMETRIC_PACKAGE, SYMMETRIC_GENERIC); loadAlgorithms(SYMMETRIC_PACKAGE, SYMMETRIC_MACS); loadAlgorithms(SYMMETRIC_PACKAGE, SYMMETRIC_CIPHERS); loadAlgorithms(ASYMMETRIC_PACKAGE, ASYMMETRIC_GENERIC); loadAlgorithms(ASYMMETRIC_PACKAGE, ASYMMETRIC_CIPHERS); loadAlgorithms(KEYSTORE_PACKAGE, KEYSTORES); // // X509Store // put("X509Store.CERTIFICATE/COLLECTION", "org.bouncycastle.jce.provider.X509StoreCertCollection"); put("X509Store.ATTRIBUTECERTIFICATE/COLLECTION", "org.bouncycastle.jce.provider.X509StoreAttrCertCollection"); put("X509Store.CRL/COLLECTION", "org.bouncycastle.jce.provider.X509StoreCRLCollection"); put("X509Store.CERTIFICATEPAIR/COLLECTION", "org.bouncycastle.jce.provider.X509StoreCertPairCollection"); put("X509Store.CERTIFICATE/LDAP", "org.bouncycastle.jce.provider.X509StoreLDAPCerts"); put("X509Store.CRL/LDAP", "org.bouncycastle.jce.provider.X509StoreLDAPCRLs"); put("X509Store.ATTRIBUTECERTIFICATE/LDAP", "org.bouncycastle.jce.provider.X509StoreLDAPAttrCerts"); put("X509Store.CERTIFICATEPAIR/LDAP", "org.bouncycastle.jce.provider.X509StoreLDAPCertPairs"); // // X509StreamParser // put("X509StreamParser.CERTIFICATE", "org.bouncycastle.jce.provider.X509CertParser"); put("X509StreamParser.ATTRIBUTECERTIFICATE", "org.bouncycastle.jce.provider.X509AttrCertParser"); put("X509StreamParser.CRL", "org.bouncycastle.jce.provider.X509CRLParser"); put("X509StreamParser.CERTIFICATEPAIR", "org.bouncycastle.jce.provider.X509CertPairParser"); // // cipher engines // put("Cipher.BROKENPBEWITHMD5ANDDES", "org.bouncycastle.jce.provider.BrokenJCEBlockCipher$BrokePBEWithMD5AndDES"); put("Cipher.BROKENPBEWITHSHA1ANDDES", "org.bouncycastle.jce.provider.BrokenJCEBlockCipher$BrokePBEWithSHA1AndDES"); put("Cipher.OLDPBEWITHSHAANDTWOFISH-CBC", "org.bouncycastle.jce.provider.BrokenJCEBlockCipher$OldPBEWithSHAAndTwofish"); // Certification Path API put("CertPathValidator.RFC3281", "org.bouncycastle.jce.provider.PKIXAttrCertPathValidatorSpi"); put("CertPathBuilder.RFC3281", "org.bouncycastle.jce.provider.PKIXAttrCertPathBuilderSpi"); put("CertPathValidator.RFC3280", "org.bouncycastle.jce.provider.PKIXCertPathValidatorSpi"); put("CertPathBuilder.RFC3280", "org.bouncycastle.jce.provider.PKIXCertPathBuilderSpi"); put("CertPathValidator.PKIX", "org.bouncycastle.jce.provider.PKIXCertPathValidatorSpi"); put("CertPathBuilder.PKIX", "org.bouncycastle.jce.provider.PKIXCertPathBuilderSpi"); put("CertStore.Collection", "org.bouncycastle.jce.provider.CertStoreCollectionSpi"); put("CertStore.LDAP", "org.bouncycastle.jce.provider.X509LDAPCertStoreSpi"); put("CertStore.Multi", "org.bouncycastle.jce.provider.MultiCertStoreSpi"); put("Alg.Alias.CertStore.X509LDAP", "LDAP"); } private void loadAlgorithms(String packageName, String[] names) { for (int i = 0; i != names.length; i++) { Class clazz = null; try { ClassLoader loader = this.getClass().getClassLoader(); if (loader != null) { clazz = loader.loadClass(packageName + names[i] + "$Mappings"); } else { clazz = Class.forName(packageName + names[i] + "$Mappings"); } } catch (ClassNotFoundException e) { // ignore } if (clazz != null) { try { ((AlgorithmProvider)clazz.newInstance()).configure(this); } catch (Exception e) { // this should never ever happen!! throw new InternalError("cannot create instance of " + packageName + names[i] + "$Mappings : " + e); } } } } public void setParameter(String parameterName, Object parameter) { synchronized (CONFIGURATION) { ((BouncyCastleProviderConfiguration)CONFIGURATION).setParameter(parameterName, parameter); } } public boolean hasAlgorithm(String type, String name) { return containsKey(type + "." + name) || containsKey("Alg.Alias." + type + "." + name); } public void addAlgorithm(String key, String value) { if (containsKey(key)) { throw new IllegalStateException("duplicate provider key (" + key + ") found"); } put(key, value); } public void addKeyInfoConverter(ASN1ObjectIdentifier oid, AsymmetricKeyInfoConverter keyInfoConverter) { keyInfoConverters.put(oid, keyInfoConverter); } public static PublicKey getPublicKey(SubjectPublicKeyInfo publicKeyInfo) throws IOException { AsymmetricKeyInfoConverter converter = (AsymmetricKeyInfoConverter)keyInfoConverters.get(publicKeyInfo.getAlgorithm().getAlgorithm()); if (converter == null) { return null; } return converter.generatePublic(publicKeyInfo); } public static PrivateKey getPrivateKey(PrivateKeyInfo privateKeyInfo) throws IOException { AsymmetricKeyInfoConverter converter = (AsymmetricKeyInfoConverter)keyInfoConverters.get(privateKeyInfo.getPrivateKeyAlgorithm().getAlgorithm()); if (converter == null) { return null; } return converter.generatePrivate(privateKeyInfo); } } bouncycastle-1.49.orig/src/org/bouncycastle/jce/provider/JCERSAPublicKey.java0000644000175000017500000000650212103437526026525 0ustar ebourgebourgpackage org.bouncycastle.jce.provider; import java.io.IOException; import java.math.BigInteger; import java.security.interfaces.RSAPublicKey; import java.security.spec.RSAPublicKeySpec; import org.bouncycastle.asn1.ASN1Sequence; import org.bouncycastle.asn1.DERNull; import org.bouncycastle.asn1.pkcs.PKCSObjectIdentifiers; import org.bouncycastle.asn1.x509.AlgorithmIdentifier; import org.bouncycastle.asn1.x509.RSAPublicKeyStructure; import org.bouncycastle.asn1.x509.SubjectPublicKeyInfo; import org.bouncycastle.crypto.params.RSAKeyParameters; import org.bouncycastle.jcajce.provider.asymmetric.util.KeyUtil; public class JCERSAPublicKey implements RSAPublicKey { static final long serialVersionUID = 2675817738516720772L; private BigInteger modulus; private BigInteger publicExponent; JCERSAPublicKey( RSAKeyParameters key) { this.modulus = key.getModulus(); this.publicExponent = key.getExponent(); } JCERSAPublicKey( RSAPublicKeySpec spec) { this.modulus = spec.getModulus(); this.publicExponent = spec.getPublicExponent(); } JCERSAPublicKey( RSAPublicKey key) { this.modulus = key.getModulus(); this.publicExponent = key.getPublicExponent(); } JCERSAPublicKey( SubjectPublicKeyInfo info) { try { RSAPublicKeyStructure pubKey = new RSAPublicKeyStructure((ASN1Sequence)info.parsePublicKey()); this.modulus = pubKey.getModulus(); this.publicExponent = pubKey.getPublicExponent(); } catch (IOException e) { throw new IllegalArgumentException("invalid info structure in RSA public key"); } } /** * return the modulus. * * @return the modulus. */ public BigInteger getModulus() { return modulus; } /** * return the public exponent. * * @return the public exponent. */ public BigInteger getPublicExponent() { return publicExponent; } public String getAlgorithm() { return "RSA"; } public String getFormat() { return "X.509"; } public byte[] getEncoded() { return KeyUtil.getEncodedSubjectPublicKeyInfo(new AlgorithmIdentifier(PKCSObjectIdentifiers.rsaEncryption, DERNull.INSTANCE), new RSAPublicKeyStructure(getModulus(), getPublicExponent())); } public int hashCode() { return this.getModulus().hashCode() ^ this.getPublicExponent().hashCode(); } public boolean equals(Object o) { if (o == this) { return true; } if (!(o instanceof RSAPublicKey)) { return false; } RSAPublicKey key = (RSAPublicKey)o; return getModulus().equals(key.getModulus()) && getPublicExponent().equals(key.getPublicExponent()); } public String toString() { StringBuffer buf = new StringBuffer(); String nl = System.getProperty("line.separator"); buf.append("RSA Public Key").append(nl); buf.append(" modulus: ").append(this.getModulus().toString(16)).append(nl); buf.append(" public exponent: ").append(this.getPublicExponent().toString(16)).append(nl); return buf.toString(); } } bouncycastle-1.49.orig/src/org/bouncycastle/jce/provider/X509CRLParser.java0000644000175000017500000000757511701453646026150 0ustar ebourgebourgpackage org.bouncycastle.jce.provider; import java.io.BufferedInputStream; import java.io.IOException; import java.io.InputStream; import java.security.cert.CRL; import java.security.cert.CRLException; import java.util.ArrayList; import java.util.Collection; import java.util.List; import org.bouncycastle.asn1.ASN1InputStream; import org.bouncycastle.asn1.ASN1Sequence; import org.bouncycastle.asn1.ASN1Set; import org.bouncycastle.asn1.ASN1TaggedObject; import org.bouncycastle.asn1.DERObjectIdentifier; import org.bouncycastle.asn1.pkcs.PKCSObjectIdentifiers; import org.bouncycastle.asn1.pkcs.SignedData; import org.bouncycastle.asn1.x509.CertificateList; import org.bouncycastle.x509.X509StreamParserSpi; import org.bouncycastle.x509.util.StreamParsingException; public class X509CRLParser extends X509StreamParserSpi { private static final PEMUtil PEM_PARSER = new PEMUtil("CRL"); private ASN1Set sData = null; private int sDataObjectCount = 0; private InputStream currentStream = null; private CRL readDERCRL( InputStream in) throws IOException, CRLException { ASN1InputStream dIn = new ASN1InputStream(in); ASN1Sequence seq = (ASN1Sequence)dIn.readObject(); if (seq.size() > 1 && seq.getObjectAt(0) instanceof DERObjectIdentifier) { if (seq.getObjectAt(0).equals(PKCSObjectIdentifiers.signedData)) { sData = new SignedData(ASN1Sequence.getInstance( (ASN1TaggedObject)seq.getObjectAt(1), true)).getCRLs(); return getCRL(); } } return new X509CRLObject(CertificateList.getInstance(seq)); } private CRL getCRL() throws CRLException { if (sData == null || sDataObjectCount >= sData.size()) { return null; } return new X509CRLObject( CertificateList.getInstance( sData.getObjectAt(sDataObjectCount++))); } private CRL readPEMCRL( InputStream in) throws IOException, CRLException { ASN1Sequence seq = PEM_PARSER.readPEMObject(in); if (seq != null) { return new X509CRLObject(CertificateList.getInstance(seq)); } return null; } public void engineInit(InputStream in) { currentStream = in; sData = null; sDataObjectCount = 0; if (!currentStream.markSupported()) { currentStream = new BufferedInputStream(currentStream); } } public Object engineRead() throws StreamParsingException { try { if (sData != null) { if (sDataObjectCount != sData.size()) { return getCRL(); } else { sData = null; sDataObjectCount = 0; return null; } } currentStream.mark(10); int tag = currentStream.read(); if (tag == -1) { return null; } if (tag != 0x30) // assume ascii PEM encoded. { currentStream.reset(); return readPEMCRL(currentStream); } else { currentStream.reset(); return readDERCRL(currentStream); } } catch (Exception e) { throw new StreamParsingException(e.toString(), e); } } public Collection engineReadAll() throws StreamParsingException { CRL crl; List certs = new ArrayList(); while ((crl = (CRL)engineRead()) != null) { certs.add(crl); } return certs; } } bouncycastle-1.49.orig/src/org/bouncycastle/jce/provider/BrokenJCEBlockCipher.java0000644000175000017500000004434611624640051027622 0ustar ebourgebourgpackage org.bouncycastle.jce.provider; import java.security.AlgorithmParameters; import java.security.InvalidAlgorithmParameterException; import java.security.InvalidKeyException; import java.security.Key; import java.security.KeyFactory; import java.security.NoSuchAlgorithmException; import java.security.NoSuchProviderException; import java.security.SecureRandom; import java.security.spec.AlgorithmParameterSpec; import java.security.spec.InvalidKeySpecException; import java.security.spec.PKCS8EncodedKeySpec; import java.security.spec.X509EncodedKeySpec; import javax.crypto.BadPaddingException; import javax.crypto.Cipher; import javax.crypto.IllegalBlockSizeException; import javax.crypto.NoSuchPaddingException; import javax.crypto.spec.IvParameterSpec; import javax.crypto.spec.PBEParameterSpec; import javax.crypto.spec.RC2ParameterSpec; import javax.crypto.spec.RC5ParameterSpec; import javax.crypto.spec.SecretKeySpec; import org.bouncycastle.crypto.BlockCipher; import org.bouncycastle.crypto.BufferedBlockCipher; import org.bouncycastle.crypto.CipherParameters; import org.bouncycastle.crypto.DataLengthException; import org.bouncycastle.crypto.InvalidCipherTextException; import org.bouncycastle.crypto.engines.DESEngine; import org.bouncycastle.crypto.engines.DESedeEngine; import org.bouncycastle.crypto.engines.TwofishEngine; import org.bouncycastle.crypto.modes.CBCBlockCipher; import org.bouncycastle.crypto.modes.CFBBlockCipher; import org.bouncycastle.crypto.modes.CTSBlockCipher; import org.bouncycastle.crypto.modes.OFBBlockCipher; import org.bouncycastle.crypto.paddings.PaddedBufferedBlockCipher; import org.bouncycastle.crypto.params.KeyParameter; import org.bouncycastle.crypto.params.ParametersWithIV; import org.bouncycastle.crypto.params.RC2Parameters; import org.bouncycastle.crypto.params.RC5Parameters; import org.bouncycastle.jcajce.provider.symmetric.util.BCPBEKey; import org.bouncycastle.util.Strings; public class BrokenJCEBlockCipher implements BrokenPBE { // // specs we can handle. // private Class[] availableSpecs = { IvParameterSpec.class, PBEParameterSpec.class, RC2ParameterSpec.class, RC5ParameterSpec.class }; private BufferedBlockCipher cipher; private ParametersWithIV ivParam; private int pbeType = PKCS12; private int pbeHash = SHA1; private int pbeKeySize; private int pbeIvSize; private int ivLength = 0; private AlgorithmParameters engineParams = null; protected BrokenJCEBlockCipher( BlockCipher engine) { cipher = new PaddedBufferedBlockCipher(engine); } protected BrokenJCEBlockCipher( BlockCipher engine, int pbeType, int pbeHash, int pbeKeySize, int pbeIvSize) { cipher = new PaddedBufferedBlockCipher(engine); this.pbeType = pbeType; this.pbeHash = pbeHash; this.pbeKeySize = pbeKeySize; this.pbeIvSize = pbeIvSize; } protected int engineGetBlockSize() { return cipher.getBlockSize(); } protected byte[] engineGetIV() { return (ivParam != null) ? ivParam.getIV() : null; } protected int engineGetKeySize( Key key) { return key.getEncoded().length; } protected int engineGetOutputSize( int inputLen) { return cipher.getOutputSize(inputLen); } protected AlgorithmParameters engineGetParameters() { if (engineParams == null) { if (ivParam != null) { String name = cipher.getUnderlyingCipher().getAlgorithmName(); if (name.indexOf('/') >= 0) { name = name.substring(0, name.indexOf('/')); } try { engineParams = AlgorithmParameters.getInstance(name, BouncyCastleProvider.PROVIDER_NAME); engineParams.init(ivParam.getIV()); } catch (Exception e) { throw new RuntimeException(e.toString()); } } } return engineParams; } protected void engineSetMode( String mode) { String modeName = Strings.toUpperCase(mode); if (modeName.equals("ECB")) { ivLength = 0; cipher = new PaddedBufferedBlockCipher(cipher.getUnderlyingCipher()); } else if (modeName.equals("CBC")) { ivLength = cipher.getUnderlyingCipher().getBlockSize(); cipher = new PaddedBufferedBlockCipher( new CBCBlockCipher(cipher.getUnderlyingCipher())); } else if (modeName.startsWith("OFB")) { ivLength = cipher.getUnderlyingCipher().getBlockSize(); if (modeName.length() != 3) { int wordSize = Integer.parseInt(modeName.substring(3)); cipher = new PaddedBufferedBlockCipher( new OFBBlockCipher(cipher.getUnderlyingCipher(), wordSize)); } else { cipher = new PaddedBufferedBlockCipher( new OFBBlockCipher(cipher.getUnderlyingCipher(), 8 * cipher.getBlockSize())); } } else if (modeName.startsWith("CFB")) { ivLength = cipher.getUnderlyingCipher().getBlockSize(); if (modeName.length() != 3) { int wordSize = Integer.parseInt(modeName.substring(3)); cipher = new PaddedBufferedBlockCipher( new CFBBlockCipher(cipher.getUnderlyingCipher(), wordSize)); } else { cipher = new PaddedBufferedBlockCipher( new CFBBlockCipher(cipher.getUnderlyingCipher(), 8 * cipher.getBlockSize())); } } else { throw new IllegalArgumentException("can't support mode " + mode); } } protected void engineSetPadding( String padding) throws NoSuchPaddingException { String paddingName = Strings.toUpperCase(padding); if (paddingName.equals("NOPADDING")) { cipher = new BufferedBlockCipher(cipher.getUnderlyingCipher()); } else if (paddingName.equals("PKCS5PADDING") || paddingName.equals("PKCS7PADDING") || paddingName.equals("ISO10126PADDING")) { cipher = new PaddedBufferedBlockCipher(cipher.getUnderlyingCipher()); } else if (paddingName.equals("WITHCTS")) { cipher = new CTSBlockCipher(cipher.getUnderlyingCipher()); } else { throw new NoSuchPaddingException("Padding " + padding + " unknown."); } } protected void engineInit( int opmode, Key key, AlgorithmParameterSpec params, SecureRandom random) throws InvalidKeyException, InvalidAlgorithmParameterException { CipherParameters param; // // a note on iv's - if ivLength is zero the IV gets ignored (we don't use it). // if (key instanceof BCPBEKey) { param = BrokenPBE.Util.makePBEParameters((BCPBEKey)key, params, pbeType, pbeHash, cipher.getUnderlyingCipher().getAlgorithmName(), pbeKeySize, pbeIvSize); if (pbeIvSize != 0) { ivParam = (ParametersWithIV)param; } } else if (params == null) { param = new KeyParameter(key.getEncoded()); } else if (params instanceof IvParameterSpec) { if (ivLength != 0) { param = new ParametersWithIV(new KeyParameter(key.getEncoded()), ((IvParameterSpec)params).getIV()); ivParam = (ParametersWithIV)param; } else { param = new KeyParameter(key.getEncoded()); } } else if (params instanceof RC2ParameterSpec) { RC2ParameterSpec rc2Param = (RC2ParameterSpec)params; param = new RC2Parameters(key.getEncoded(), ((RC2ParameterSpec)params).getEffectiveKeyBits()); if (rc2Param.getIV() != null && ivLength != 0) { param = new ParametersWithIV(param, rc2Param.getIV()); ivParam = (ParametersWithIV)param; } } else if (params instanceof RC5ParameterSpec) { RC5ParameterSpec rc5Param = (RC5ParameterSpec)params; param = new RC5Parameters(key.getEncoded(), ((RC5ParameterSpec)params).getRounds()); if (rc5Param.getWordSize() != 32) { throw new IllegalArgumentException("can only accept RC5 word size 32 (at the moment...)"); } if ((rc5Param.getIV() != null) && (ivLength != 0)) { param = new ParametersWithIV(param, rc5Param.getIV()); ivParam = (ParametersWithIV)param; } } else { throw new InvalidAlgorithmParameterException("unknown parameter type."); } if ((ivLength != 0) && !(param instanceof ParametersWithIV)) { if (random == null) { random = new SecureRandom(); } if ((opmode == Cipher.ENCRYPT_MODE) || (opmode == Cipher.WRAP_MODE)) { byte[] iv = new byte[ivLength]; random.nextBytes(iv); param = new ParametersWithIV(param, iv); ivParam = (ParametersWithIV)param; } else { throw new InvalidAlgorithmParameterException("no IV set when one expected"); } } switch (opmode) { case Cipher.ENCRYPT_MODE: case Cipher.WRAP_MODE: cipher.init(true, param); break; case Cipher.DECRYPT_MODE: case Cipher.UNWRAP_MODE: cipher.init(false, param); break; default: System.out.println("eeek!"); } } protected void engineInit( int opmode, Key key, AlgorithmParameters params, SecureRandom random) throws InvalidKeyException, InvalidAlgorithmParameterException { AlgorithmParameterSpec paramSpec = null; if (params != null) { for (int i = 0; i != availableSpecs.length; i++) { try { paramSpec = params.getParameterSpec(availableSpecs[i]); break; } catch (Exception e) { continue; } } if (paramSpec == null) { throw new InvalidAlgorithmParameterException("can't handle parameter " + params.toString()); } } engineParams = params; engineInit(opmode, key, paramSpec, random); } protected void engineInit( int opmode, Key key, SecureRandom random) throws InvalidKeyException { try { engineInit(opmode, key, (AlgorithmParameterSpec)null, random); } catch (InvalidAlgorithmParameterException e) { throw new IllegalArgumentException(e.getMessage()); } } protected byte[] engineUpdate( byte[] input, int inputOffset, int inputLen) { int length = cipher.getUpdateOutputSize(inputLen); if (length > 0) { byte[] out = new byte[length]; cipher.processBytes(input, inputOffset, inputLen, out, 0); return out; } cipher.processBytes(input, inputOffset, inputLen, null, 0); return null; } protected int engineUpdate( byte[] input, int inputOffset, int inputLen, byte[] output, int outputOffset) { return cipher.processBytes(input, inputOffset, inputLen, output, outputOffset); } protected byte[] engineDoFinal( byte[] input, int inputOffset, int inputLen) throws IllegalBlockSizeException, BadPaddingException { int len = 0; byte[] tmp = new byte[engineGetOutputSize(inputLen)]; if (inputLen != 0) { len = cipher.processBytes(input, inputOffset, inputLen, tmp, 0); } try { len += cipher.doFinal(tmp, len); } catch (DataLengthException e) { throw new IllegalBlockSizeException(e.getMessage()); } catch (InvalidCipherTextException e) { throw new BadPaddingException(e.getMessage()); } byte[] out = new byte[len]; System.arraycopy(tmp, 0, out, 0, len); return out; } protected int engineDoFinal( byte[] input, int inputOffset, int inputLen, byte[] output, int outputOffset) throws IllegalBlockSizeException, BadPaddingException { int len = 0; if (inputLen != 0) { len = cipher.processBytes(input, inputOffset, inputLen, output, outputOffset); } try { return len + cipher.doFinal(output, outputOffset + len); } catch (DataLengthException e) { throw new IllegalBlockSizeException(e.getMessage()); } catch (InvalidCipherTextException e) { throw new BadPaddingException(e.getMessage()); } } protected byte[] engineWrap( Key key) throws IllegalBlockSizeException, java.security.InvalidKeyException { byte[] encoded = key.getEncoded(); if (encoded == null) { throw new InvalidKeyException("Cannot wrap key, null encoding."); } try { return engineDoFinal(encoded, 0, encoded.length); } catch (BadPaddingException e) { throw new IllegalBlockSizeException(e.getMessage()); } } protected Key engineUnwrap( byte[] wrappedKey, String wrappedKeyAlgorithm, int wrappedKeyType) throws InvalidKeyException { byte[] encoded = null; try { encoded = engineDoFinal(wrappedKey, 0, wrappedKey.length); } catch (BadPaddingException e) { throw new InvalidKeyException(e.getMessage()); } catch (IllegalBlockSizeException e2) { throw new InvalidKeyException(e2.getMessage()); } if (wrappedKeyType == Cipher.SECRET_KEY) { return new SecretKeySpec(encoded, wrappedKeyAlgorithm); } else { try { KeyFactory kf = KeyFactory.getInstance(wrappedKeyAlgorithm, BouncyCastleProvider.PROVIDER_NAME); if (wrappedKeyType == Cipher.PUBLIC_KEY) { return kf.generatePublic(new X509EncodedKeySpec(encoded)); } else if (wrappedKeyType == Cipher.PRIVATE_KEY) { return kf.generatePrivate(new PKCS8EncodedKeySpec(encoded)); } } catch (NoSuchProviderException e) { throw new InvalidKeyException("Unknown key type " + e.getMessage()); } catch (NoSuchAlgorithmException e) { throw new InvalidKeyException("Unknown key type " + e.getMessage()); } catch (InvalidKeySpecException e2) { throw new InvalidKeyException("Unknown key type " + e2.getMessage()); } throw new InvalidKeyException("Unknown key type " + wrappedKeyType); } } /* * The ciphers that inherit from us. */ /** * PBEWithMD5AndDES */ static public class BrokePBEWithMD5AndDES extends BrokenJCEBlockCipher { public BrokePBEWithMD5AndDES() { super(new CBCBlockCipher(new DESEngine()), PKCS5S1, MD5, 64, 64); } } /** * PBEWithSHA1AndDES */ static public class BrokePBEWithSHA1AndDES extends BrokenJCEBlockCipher { public BrokePBEWithSHA1AndDES() { super(new CBCBlockCipher(new DESEngine()), PKCS5S1, SHA1, 64, 64); } } /** * PBEWithSHAAnd3-KeyTripleDES-CBC */ static public class BrokePBEWithSHAAndDES3Key extends BrokenJCEBlockCipher { public BrokePBEWithSHAAndDES3Key() { super(new CBCBlockCipher(new DESedeEngine()), PKCS12, SHA1, 192, 64); } } /** * OldPBEWithSHAAnd3-KeyTripleDES-CBC */ static public class OldPBEWithSHAAndDES3Key extends BrokenJCEBlockCipher { public OldPBEWithSHAAndDES3Key() { super(new CBCBlockCipher(new DESedeEngine()), OLD_PKCS12, SHA1, 192, 64); } } /** * PBEWithSHAAnd2-KeyTripleDES-CBC */ static public class BrokePBEWithSHAAndDES2Key extends BrokenJCEBlockCipher { public BrokePBEWithSHAAndDES2Key() { super(new CBCBlockCipher(new DESedeEngine()), PKCS12, SHA1, 128, 64); } } /** * OldPBEWithSHAAndTwofish-CBC */ static public class OldPBEWithSHAAndTwofish extends BrokenJCEBlockCipher { public OldPBEWithSHAAndTwofish() { super(new CBCBlockCipher(new TwofishEngine()), OLD_PKCS12, SHA1, 256, 128); } } } bouncycastle-1.49.orig/src/org/bouncycastle/jce/provider/X509StoreLDAPCertPairs.java0000644000175000017500000000472411624652552027717 0ustar ebourgebourgpackage org.bouncycastle.jce.provider; import java.util.Collection; import java.util.Collections; import java.util.HashSet; import java.util.Set; import org.bouncycastle.jce.X509LDAPCertStoreParameters; import org.bouncycastle.util.Selector; import org.bouncycastle.util.StoreException; import org.bouncycastle.x509.X509CertPairStoreSelector; import org.bouncycastle.x509.X509StoreParameters; import org.bouncycastle.x509.X509StoreSpi; import org.bouncycastle.x509.util.LDAPStoreHelper; /** * A SPI implementation of Bouncy Castle X509Store for getting * cross certificates pairs from an LDAP directory. * * @see org.bouncycastle.x509.X509Store */ public class X509StoreLDAPCertPairs extends X509StoreSpi { private LDAPStoreHelper helper; public X509StoreLDAPCertPairs() { } /** * Initializes this LDAP cross certificate pair store implementation. * * @param parameters X509LDAPCertStoreParameters. * @throws IllegalArgumentException if params is not an instance of * X509LDAPCertStoreParameters. */ public void engineInit(X509StoreParameters parameters) { if (!(parameters instanceof X509LDAPCertStoreParameters)) { throw new IllegalArgumentException( "Initialization parameters must be an instance of " + X509LDAPCertStoreParameters.class.getName() + "."); } helper = new LDAPStoreHelper((X509LDAPCertStoreParameters)parameters); } /** * Returns a collection of matching cross certificate pairs from the LDAP * location. *

    * The selector must be a of type X509CertPairStoreSelector. * If it is not an empty collection is returned. *

    *

    * The subject should be a reasonable criteria for a selector. * * @param selector The selector to use for finding. * @return A collection with the matches. * @throws StoreException if an exception occurs while searching. */ public Collection engineGetMatches(Selector selector) throws StoreException { if (!(selector instanceof X509CertPairStoreSelector)) { return Collections.EMPTY_SET; } X509CertPairStoreSelector xselector = (X509CertPairStoreSelector)selector; Set set = new HashSet(); set.addAll(helper.getCrossCertificatePairs(xselector)); return set; } } bouncycastle-1.49.orig/src/org/bouncycastle/jce/provider/JDKDSAPrivateKey.java0000644000175000017500000001210512101612542026675 0ustar ebourgebourgpackage org.bouncycastle.jce.provider; import java.io.IOException; import java.io.ObjectInputStream; import java.io.ObjectOutputStream; import java.math.BigInteger; import java.security.interfaces.DSAParams; import java.security.interfaces.DSAPrivateKey; import java.security.spec.DSAParameterSpec; import java.security.spec.DSAPrivateKeySpec; import java.util.Enumeration; import org.bouncycastle.asn1.ASN1Encodable; import org.bouncycastle.asn1.ASN1Encoding; import org.bouncycastle.asn1.ASN1Integer; import org.bouncycastle.asn1.ASN1ObjectIdentifier; import org.bouncycastle.asn1.ASN1Sequence; import org.bouncycastle.asn1.DERInteger; import org.bouncycastle.asn1.pkcs.PrivateKeyInfo; import org.bouncycastle.asn1.x509.AlgorithmIdentifier; import org.bouncycastle.asn1.x509.DSAParameter; import org.bouncycastle.asn1.x9.X9ObjectIdentifiers; import org.bouncycastle.crypto.params.DSAPrivateKeyParameters; import org.bouncycastle.jcajce.provider.asymmetric.util.PKCS12BagAttributeCarrierImpl; import org.bouncycastle.jce.interfaces.PKCS12BagAttributeCarrier; public class JDKDSAPrivateKey implements DSAPrivateKey, PKCS12BagAttributeCarrier { private static final long serialVersionUID = -4677259546958385734L; BigInteger x; DSAParams dsaSpec; private PKCS12BagAttributeCarrierImpl attrCarrier = new PKCS12BagAttributeCarrierImpl(); protected JDKDSAPrivateKey() { } JDKDSAPrivateKey( DSAPrivateKey key) { this.x = key.getX(); this.dsaSpec = key.getParams(); } JDKDSAPrivateKey( DSAPrivateKeySpec spec) { this.x = spec.getX(); this.dsaSpec = new DSAParameterSpec(spec.getP(), spec.getQ(), spec.getG()); } JDKDSAPrivateKey( PrivateKeyInfo info) throws IOException { DSAParameter params = DSAParameter.getInstance(info.getPrivateKeyAlgorithm().getParameters()); DERInteger derX = ASN1Integer.getInstance(info.parsePrivateKey()); this.x = derX.getValue(); this.dsaSpec = new DSAParameterSpec(params.getP(), params.getQ(), params.getG()); } JDKDSAPrivateKey( DSAPrivateKeyParameters params) { this.x = params.getX(); this.dsaSpec = new DSAParameterSpec(params.getParameters().getP(), params.getParameters().getQ(), params.getParameters().getG()); } public String getAlgorithm() { return "DSA"; } /** * return the encoding format we produce in getEncoded(). * * @return the string "PKCS#8" */ public String getFormat() { return "PKCS#8"; } /** * Return a PKCS8 representation of the key. The sequence returned * represents a full PrivateKeyInfo object. * * @return a PKCS8 representation of the key. */ public byte[] getEncoded() { try { PrivateKeyInfo info = new PrivateKeyInfo(new AlgorithmIdentifier(X9ObjectIdentifiers.id_dsa, new DSAParameter(dsaSpec.getP(), dsaSpec.getQ(), dsaSpec.getG())), new DERInteger(getX())); return info.getEncoded(ASN1Encoding.DER); } catch (IOException e) { return null; } } public DSAParams getParams() { return dsaSpec; } public BigInteger getX() { return x; } public boolean equals( Object o) { if (!(o instanceof DSAPrivateKey)) { return false; } DSAPrivateKey other = (DSAPrivateKey)o; return this.getX().equals(other.getX()) && this.getParams().getG().equals(other.getParams().getG()) && this.getParams().getP().equals(other.getParams().getP()) && this.getParams().getQ().equals(other.getParams().getQ()); } public int hashCode() { return this.getX().hashCode() ^ this.getParams().getG().hashCode() ^ this.getParams().getP().hashCode() ^ this.getParams().getQ().hashCode(); } public void setBagAttribute( ASN1ObjectIdentifier oid, ASN1Encodable attribute) { attrCarrier.setBagAttribute(oid, attribute); } public ASN1Encodable getBagAttribute( ASN1ObjectIdentifier oid) { return attrCarrier.getBagAttribute(oid); } public Enumeration getBagAttributeKeys() { return attrCarrier.getBagAttributeKeys(); } private void readObject( ObjectInputStream in) throws IOException, ClassNotFoundException { this.x = (BigInteger)in.readObject(); this.dsaSpec = new DSAParameterSpec((BigInteger)in.readObject(), (BigInteger)in.readObject(), (BigInteger)in.readObject()); this.attrCarrier = new PKCS12BagAttributeCarrierImpl(); attrCarrier.readObject(in); } private void writeObject( ObjectOutputStream out) throws IOException { out.writeObject(x); out.writeObject(dsaSpec.getP()); out.writeObject(dsaSpec.getQ()); out.writeObject(dsaSpec.getG()); attrCarrier.writeObject(out); } } bouncycastle-1.49.orig/src/org/bouncycastle/jce/provider/ExtCRLException.java0000644000175000017500000000052211624640052026717 0ustar ebourgebourgpackage org.bouncycastle.jce.provider; import java.security.cert.CRLException; class ExtCRLException extends CRLException { Throwable cause; ExtCRLException(String message, Throwable cause) { super(message); this.cause = cause; } public Throwable getCause() { return cause; } } bouncycastle-1.49.orig/src/org/bouncycastle/jce/provider/PKIXNameConstraintValidator.java0000644000175000017500000015501112103440465031231 0ustar ebourgebourgpackage org.bouncycastle.jce.provider; import java.util.Collection; import java.util.Collections; import java.util.HashMap; import java.util.HashSet; import java.util.Iterator; import java.util.Map; import java.util.Set; import org.bouncycastle.asn1.ASN1OctetString; import org.bouncycastle.asn1.ASN1Sequence; import org.bouncycastle.asn1.DERIA5String; import org.bouncycastle.asn1.x509.GeneralName; import org.bouncycastle.asn1.x509.GeneralSubtree; import org.bouncycastle.util.Arrays; import org.bouncycastle.util.Integers; import org.bouncycastle.util.Strings; public class PKIXNameConstraintValidator { private Set excludedSubtreesDN = new HashSet(); private Set excludedSubtreesDNS = new HashSet(); private Set excludedSubtreesEmail = new HashSet(); private Set excludedSubtreesURI = new HashSet(); private Set excludedSubtreesIP = new HashSet(); private Set permittedSubtreesDN; private Set permittedSubtreesDNS; private Set permittedSubtreesEmail; private Set permittedSubtreesURI; private Set permittedSubtreesIP; public PKIXNameConstraintValidator() { } private static boolean withinDNSubtree( ASN1Sequence dns, ASN1Sequence subtree) { if (subtree.size() < 1) { return false; } if (subtree.size() > dns.size()) { return false; } for (int j = subtree.size() - 1; j >= 0; j--) { if (!subtree.getObjectAt(j).equals(dns.getObjectAt(j))) { return false; } } return true; } public void checkPermittedDN(ASN1Sequence dns) throws PKIXNameConstraintValidatorException { checkPermittedDN(permittedSubtreesDN, dns); } public void checkExcludedDN(ASN1Sequence dns) throws PKIXNameConstraintValidatorException { checkExcludedDN(excludedSubtreesDN, dns); } private void checkPermittedDN(Set permitted, ASN1Sequence dns) throws PKIXNameConstraintValidatorException { if (permitted == null) { return; } if (permitted.isEmpty() && dns.size() == 0) { return; } Iterator it = permitted.iterator(); while (it.hasNext()) { ASN1Sequence subtree = (ASN1Sequence)it.next(); if (withinDNSubtree(dns, subtree)) { return; } } throw new PKIXNameConstraintValidatorException( "Subject distinguished name is not from a permitted subtree"); } private void checkExcludedDN(Set excluded, ASN1Sequence dns) throws PKIXNameConstraintValidatorException { if (excluded.isEmpty()) { return; } Iterator it = excluded.iterator(); while (it.hasNext()) { ASN1Sequence subtree = (ASN1Sequence)it.next(); if (withinDNSubtree(dns, subtree)) { throw new PKIXNameConstraintValidatorException( "Subject distinguished name is from an excluded subtree"); } } } private Set intersectDN(Set permitted, Set dns) { Set intersect = new HashSet(); for (Iterator it = dns.iterator(); it.hasNext();) { ASN1Sequence dn = ASN1Sequence.getInstance(((GeneralSubtree)it .next()).getBase().getName().toASN1Primitive()); if (permitted == null) { if (dn != null) { intersect.add(dn); } } else { Iterator _iter = permitted.iterator(); while (_iter.hasNext()) { ASN1Sequence subtree = (ASN1Sequence)_iter.next(); if (withinDNSubtree(dn, subtree)) { intersect.add(dn); } else if (withinDNSubtree(subtree, dn)) { intersect.add(subtree); } } } } return intersect; } private Set unionDN(Set excluded, ASN1Sequence dn) { if (excluded.isEmpty()) { if (dn == null) { return excluded; } excluded.add(dn); return excluded; } else { Set intersect = new HashSet(); Iterator it = excluded.iterator(); while (it.hasNext()) { ASN1Sequence subtree = (ASN1Sequence)it.next(); if (withinDNSubtree(dn, subtree)) { intersect.add(subtree); } else if (withinDNSubtree(subtree, dn)) { intersect.add(dn); } else { intersect.add(subtree); intersect.add(dn); } } return intersect; } } private Set intersectEmail(Set permitted, Set emails) { Set intersect = new HashSet(); for (Iterator it = emails.iterator(); it.hasNext();) { String email = extractNameAsString(((GeneralSubtree)it.next()) .getBase()); if (permitted == null) { if (email != null) { intersect.add(email); } } else { Iterator it2 = permitted.iterator(); while (it2.hasNext()) { String _permitted = (String)it2.next(); intersectEmail(email, _permitted, intersect); } } } return intersect; } private Set unionEmail(Set excluded, String email) { if (excluded.isEmpty()) { if (email == null) { return excluded; } excluded.add(email); return excluded; } else { Set union = new HashSet(); Iterator it = excluded.iterator(); while (it.hasNext()) { String _excluded = (String)it.next(); unionEmail(_excluded, email, union); } return union; } } /** * Returns the intersection of the permitted IP ranges in * permitted with ip. * * @param permitted A Set of permitted IP addresses with * their subnet mask as byte arrays. * @param ips The IP address with its subnet mask. * @return The Set of permitted IP ranges intersected with * ip. */ private Set intersectIP(Set permitted, Set ips) { Set intersect = new HashSet(); for (Iterator it = ips.iterator(); it.hasNext();) { byte[] ip = ASN1OctetString.getInstance( ((GeneralSubtree)it.next()).getBase().getName()).getOctets(); if (permitted == null) { if (ip != null) { intersect.add(ip); } } else { Iterator it2 = permitted.iterator(); while (it2.hasNext()) { byte[] _permitted = (byte[])it2.next(); intersect.addAll(intersectIPRange(_permitted, ip)); } } } return intersect; } /** * Returns the union of the excluded IP ranges in excluded * with ip. * * @param excluded A Set of excluded IP addresses with their * subnet mask as byte arrays. * @param ip The IP address with its subnet mask. * @return The Set of excluded IP ranges unified with * ip as byte arrays. */ private Set unionIP(Set excluded, byte[] ip) { if (excluded.isEmpty()) { if (ip == null) { return excluded; } excluded.add(ip); return excluded; } else { Set union = new HashSet(); Iterator it = excluded.iterator(); while (it.hasNext()) { byte[] _excluded = (byte[])it.next(); union.addAll(unionIPRange(_excluded, ip)); } return union; } } /** * Calculates the union if two IP ranges. * * @param ipWithSubmask1 The first IP address with its subnet mask. * @param ipWithSubmask2 The second IP address with its subnet mask. * @return A Set with the union of both addresses. */ private Set unionIPRange(byte[] ipWithSubmask1, byte[] ipWithSubmask2) { Set set = new HashSet(); // difficult, adding always all IPs is not wrong if (Arrays.areEqual(ipWithSubmask1, ipWithSubmask2)) { set.add(ipWithSubmask1); } else { set.add(ipWithSubmask1); set.add(ipWithSubmask2); } return set; } /** * Calculates the interesction if two IP ranges. * * @param ipWithSubmask1 The first IP address with its subnet mask. * @param ipWithSubmask2 The second IP address with its subnet mask. * @return A Set with the single IP address with its subnet * mask as a byte array or an empty Set. */ private Set intersectIPRange(byte[] ipWithSubmask1, byte[] ipWithSubmask2) { if (ipWithSubmask1.length != ipWithSubmask2.length) { return Collections.EMPTY_SET; } byte[][] temp = extractIPsAndSubnetMasks(ipWithSubmask1, ipWithSubmask2); byte ip1[] = temp[0]; byte subnetmask1[] = temp[1]; byte ip2[] = temp[2]; byte subnetmask2[] = temp[3]; byte minMax[][] = minMaxIPs(ip1, subnetmask1, ip2, subnetmask2); byte[] min; byte[] max; max = min(minMax[1], minMax[3]); min = max(minMax[0], minMax[2]); // minimum IP address must be bigger than max if (compareTo(min, max) == 1) { return Collections.EMPTY_SET; } // OR keeps all significant bits byte[] ip = or(minMax[0], minMax[2]); byte[] subnetmask = or(subnetmask1, subnetmask2); return Collections.singleton(ipWithSubnetMask(ip, subnetmask)); } /** * Concatenates the IP address with its subnet mask. * * @param ip The IP address. * @param subnetMask Its subnet mask. * @return The concatenated IP address with its subnet mask. */ private byte[] ipWithSubnetMask(byte[] ip, byte[] subnetMask) { int ipLength = ip.length; byte[] temp = new byte[ipLength * 2]; System.arraycopy(ip, 0, temp, 0, ipLength); System.arraycopy(subnetMask, 0, temp, ipLength, ipLength); return temp; } /** * Splits the IP addresses and their subnet mask. * * @param ipWithSubmask1 The first IP address with the subnet mask. * @param ipWithSubmask2 The second IP address with the subnet mask. * @return An array with two elements. Each element contains the IP address * and the subnet mask in this order. */ private byte[][] extractIPsAndSubnetMasks( byte[] ipWithSubmask1, byte[] ipWithSubmask2) { int ipLength = ipWithSubmask1.length / 2; byte ip1[] = new byte[ipLength]; byte subnetmask1[] = new byte[ipLength]; System.arraycopy(ipWithSubmask1, 0, ip1, 0, ipLength); System.arraycopy(ipWithSubmask1, ipLength, subnetmask1, 0, ipLength); byte ip2[] = new byte[ipLength]; byte subnetmask2[] = new byte[ipLength]; System.arraycopy(ipWithSubmask2, 0, ip2, 0, ipLength); System.arraycopy(ipWithSubmask2, ipLength, subnetmask2, 0, ipLength); return new byte[][] {ip1, subnetmask1, ip2, subnetmask2}; } /** * Based on the two IP addresses and their subnet masks the IP range is * computed for each IP address - subnet mask pair and returned as the * minimum IP address and the maximum address of the range. * * @param ip1 The first IP address. * @param subnetmask1 The subnet mask of the first IP address. * @param ip2 The second IP address. * @param subnetmask2 The subnet mask of the second IP address. * @return A array with two elements. The first/second element contains the * min and max IP address of the first/second IP address and its * subnet mask. */ private byte[][] minMaxIPs( byte[] ip1, byte[] subnetmask1, byte[] ip2, byte[] subnetmask2) { int ipLength = ip1.length; byte[] min1 = new byte[ipLength]; byte[] max1 = new byte[ipLength]; byte[] min2 = new byte[ipLength]; byte[] max2 = new byte[ipLength]; for (int i = 0; i < ipLength; i++) { min1[i] = (byte)(ip1[i] & subnetmask1[i]); max1[i] = (byte)(ip1[i] & subnetmask1[i] | ~subnetmask1[i]); min2[i] = (byte)(ip2[i] & subnetmask2[i]); max2[i] = (byte)(ip2[i] & subnetmask2[i] | ~subnetmask2[i]); } return new byte[][]{min1, max1, min2, max2}; } private void checkPermittedEmail(Set permitted, String email) throws PKIXNameConstraintValidatorException { if (permitted == null) { return; } Iterator it = permitted.iterator(); while (it.hasNext()) { String str = ((String)it.next()); if (emailIsConstrained(email, str)) { return; } } if (email.length() == 0 && permitted.size() == 0) { return; } throw new PKIXNameConstraintValidatorException( "Subject email address is not from a permitted subtree."); } private void checkExcludedEmail(Set excluded, String email) throws PKIXNameConstraintValidatorException { if (excluded.isEmpty()) { return; } Iterator it = excluded.iterator(); while (it.hasNext()) { String str = (String)it.next(); if (emailIsConstrained(email, str)) { throw new PKIXNameConstraintValidatorException( "Email address is from an excluded subtree."); } } } /** * Checks if the IP ip is included in the permitted set * permitted. * * @param permitted A Set of permitted IP addresses with * their subnet mask as byte arrays. * @param ip The IP address. * @throws PKIXNameConstraintValidatorException * if the IP is not permitted. */ private void checkPermittedIP(Set permitted, byte[] ip) throws PKIXNameConstraintValidatorException { if (permitted == null) { return; } Iterator it = permitted.iterator(); while (it.hasNext()) { byte[] ipWithSubnet = (byte[])it.next(); if (isIPConstrained(ip, ipWithSubnet)) { return; } } if (ip.length == 0 && permitted.size() == 0) { return; } throw new PKIXNameConstraintValidatorException( "IP is not from a permitted subtree."); } /** * Checks if the IP ip is included in the excluded set * excluded. * * @param excluded A Set of excluded IP addresses with their * subnet mask as byte arrays. * @param ip The IP address. * @throws PKIXNameConstraintValidatorException * if the IP is excluded. */ private void checkExcludedIP(Set excluded, byte[] ip) throws PKIXNameConstraintValidatorException { if (excluded.isEmpty()) { return; } Iterator it = excluded.iterator(); while (it.hasNext()) { byte[] ipWithSubnet = (byte[])it.next(); if (isIPConstrained(ip, ipWithSubnet)) { throw new PKIXNameConstraintValidatorException( "IP is from an excluded subtree."); } } } /** * Checks if the IP address ip is constrained by * constraint. * * @param ip The IP address. * @param constraint The constraint. This is an IP address concatenated with * its subnetmask. * @return true if constrained, false * otherwise. */ private boolean isIPConstrained(byte ip[], byte[] constraint) { int ipLength = ip.length; if (ipLength != (constraint.length / 2)) { return false; } byte[] subnetMask = new byte[ipLength]; System.arraycopy(constraint, ipLength, subnetMask, 0, ipLength); byte[] permittedSubnetAddress = new byte[ipLength]; byte[] ipSubnetAddress = new byte[ipLength]; // the resulting IP address by applying the subnet mask for (int i = 0; i < ipLength; i++) { permittedSubnetAddress[i] = (byte)(constraint[i] & subnetMask[i]); ipSubnetAddress[i] = (byte)(ip[i] & subnetMask[i]); } return Arrays.areEqual(permittedSubnetAddress, ipSubnetAddress); } private boolean emailIsConstrained(String email, String constraint) { String sub = email.substring(email.indexOf('@') + 1); // a particular mailbox if (constraint.indexOf('@') != -1) { if (email.equalsIgnoreCase(constraint)) { return true; } } // on particular host else if (!(constraint.charAt(0) == '.')) { if (sub.equalsIgnoreCase(constraint)) { return true; } } // address in sub domain else if (withinDomain(sub, constraint)) { return true; } return false; } private boolean withinDomain(String testDomain, String domain) { String tempDomain = domain; if (tempDomain.startsWith(".")) { tempDomain = tempDomain.substring(1); } String[] domainParts = Strings.split(tempDomain, '.'); String[] testDomainParts = Strings.split(testDomain, '.'); // must have at least one subdomain if (testDomainParts.length <= domainParts.length) { return false; } int d = testDomainParts.length - domainParts.length; for (int i = -1; i < domainParts.length; i++) { if (i == -1) { if (testDomainParts[i + d].equals("")) { return false; } } else if (!domainParts[i].equalsIgnoreCase(testDomainParts[i + d])) { return false; } } return true; } private void checkPermittedDNS(Set permitted, String dns) throws PKIXNameConstraintValidatorException { if (permitted == null) { return; } Iterator it = permitted.iterator(); while (it.hasNext()) { String str = ((String)it.next()); // is sub domain if (withinDomain(dns, str) || dns.equalsIgnoreCase(str)) { return; } } if (dns.length() == 0 && permitted.size() == 0) { return; } throw new PKIXNameConstraintValidatorException( "DNS is not from a permitted subtree."); } private void checkExcludedDNS(Set excluded, String dns) throws PKIXNameConstraintValidatorException { if (excluded.isEmpty()) { return; } Iterator it = excluded.iterator(); while (it.hasNext()) { String str = ((String)it.next()); // is sub domain or the same if (withinDomain(dns, str) || dns.equalsIgnoreCase(str)) { throw new PKIXNameConstraintValidatorException( "DNS is from an excluded subtree."); } } } /** * The common part of email1 and email2 is * added to the union union. If email1 and * email2 have nothing in common they are added both. * * @param email1 Email address constraint 1. * @param email2 Email address constraint 2. * @param union The union. */ private void unionEmail(String email1, String email2, Set union) { // email1 is a particular address if (email1.indexOf('@') != -1) { String _sub = email1.substring(email1.indexOf('@') + 1); // both are a particular mailbox if (email2.indexOf('@') != -1) { if (email1.equalsIgnoreCase(email2)) { union.add(email1); } else { union.add(email1); union.add(email2); } } // email2 specifies a domain else if (email2.startsWith(".")) { if (withinDomain(_sub, email2)) { union.add(email2); } else { union.add(email1); union.add(email2); } } // email2 specifies a particular host else { if (_sub.equalsIgnoreCase(email2)) { union.add(email2); } else { union.add(email1); union.add(email2); } } } // email1 specifies a domain else if (email1.startsWith(".")) { if (email2.indexOf('@') != -1) { String _sub = email2.substring(email1.indexOf('@') + 1); if (withinDomain(_sub, email1)) { union.add(email1); } else { union.add(email1); union.add(email2); } } // email2 specifies a domain else if (email2.startsWith(".")) { if (withinDomain(email1, email2) || email1.equalsIgnoreCase(email2)) { union.add(email2); } else if (withinDomain(email2, email1)) { union.add(email1); } else { union.add(email1); union.add(email2); } } else { if (withinDomain(email2, email1)) { union.add(email1); } else { union.add(email1); union.add(email2); } } } // email specifies a host else { if (email2.indexOf('@') != -1) { String _sub = email2.substring(email1.indexOf('@') + 1); if (_sub.equalsIgnoreCase(email1)) { union.add(email1); } else { union.add(email1); union.add(email2); } } // email2 specifies a domain else if (email2.startsWith(".")) { if (withinDomain(email1, email2)) { union.add(email2); } else { union.add(email1); union.add(email2); } } // email2 specifies a particular host else { if (email1.equalsIgnoreCase(email2)) { union.add(email1); } else { union.add(email1); union.add(email2); } } } } private void unionURI(String email1, String email2, Set union) { // email1 is a particular address if (email1.indexOf('@') != -1) { String _sub = email1.substring(email1.indexOf('@') + 1); // both are a particular mailbox if (email2.indexOf('@') != -1) { if (email1.equalsIgnoreCase(email2)) { union.add(email1); } else { union.add(email1); union.add(email2); } } // email2 specifies a domain else if (email2.startsWith(".")) { if (withinDomain(_sub, email2)) { union.add(email2); } else { union.add(email1); union.add(email2); } } // email2 specifies a particular host else { if (_sub.equalsIgnoreCase(email2)) { union.add(email2); } else { union.add(email1); union.add(email2); } } } // email1 specifies a domain else if (email1.startsWith(".")) { if (email2.indexOf('@') != -1) { String _sub = email2.substring(email1.indexOf('@') + 1); if (withinDomain(_sub, email1)) { union.add(email1); } else { union.add(email1); union.add(email2); } } // email2 specifies a domain else if (email2.startsWith(".")) { if (withinDomain(email1, email2) || email1.equalsIgnoreCase(email2)) { union.add(email2); } else if (withinDomain(email2, email1)) { union.add(email1); } else { union.add(email1); union.add(email2); } } else { if (withinDomain(email2, email1)) { union.add(email1); } else { union.add(email1); union.add(email2); } } } // email specifies a host else { if (email2.indexOf('@') != -1) { String _sub = email2.substring(email1.indexOf('@') + 1); if (_sub.equalsIgnoreCase(email1)) { union.add(email1); } else { union.add(email1); union.add(email2); } } // email2 specifies a domain else if (email2.startsWith(".")) { if (withinDomain(email1, email2)) { union.add(email2); } else { union.add(email1); union.add(email2); } } // email2 specifies a particular host else { if (email1.equalsIgnoreCase(email2)) { union.add(email1); } else { union.add(email1); union.add(email2); } } } } private Set intersectDNS(Set permitted, Set dnss) { Set intersect = new HashSet(); for (Iterator it = dnss.iterator(); it.hasNext();) { String dns = extractNameAsString(((GeneralSubtree)it.next()) .getBase()); if (permitted == null) { if (dns != null) { intersect.add(dns); } } else { Iterator _iter = permitted.iterator(); while (_iter.hasNext()) { String _permitted = (String)_iter.next(); if (withinDomain(_permitted, dns)) { intersect.add(_permitted); } else if (withinDomain(dns, _permitted)) { intersect.add(dns); } } } } return intersect; } protected Set unionDNS(Set excluded, String dns) { if (excluded.isEmpty()) { if (dns == null) { return excluded; } excluded.add(dns); return excluded; } else { Set union = new HashSet(); Iterator _iter = excluded.iterator(); while (_iter.hasNext()) { String _permitted = (String)_iter.next(); if (withinDomain(_permitted, dns)) { union.add(dns); } else if (withinDomain(dns, _permitted)) { union.add(_permitted); } else { union.add(_permitted); union.add(dns); } } return union; } } /** * The most restricting part from email1 and * email2 is added to the intersection intersect. * * @param email1 Email address constraint 1. * @param email2 Email address constraint 2. * @param intersect The intersection. */ private void intersectEmail(String email1, String email2, Set intersect) { // email1 is a particular address if (email1.indexOf('@') != -1) { String _sub = email1.substring(email1.indexOf('@') + 1); // both are a particular mailbox if (email2.indexOf('@') != -1) { if (email1.equalsIgnoreCase(email2)) { intersect.add(email1); } } // email2 specifies a domain else if (email2.startsWith(".")) { if (withinDomain(_sub, email2)) { intersect.add(email1); } } // email2 specifies a particular host else { if (_sub.equalsIgnoreCase(email2)) { intersect.add(email1); } } } // email specifies a domain else if (email1.startsWith(".")) { if (email2.indexOf('@') != -1) { String _sub = email2.substring(email1.indexOf('@') + 1); if (withinDomain(_sub, email1)) { intersect.add(email2); } } // email2 specifies a domain else if (email2.startsWith(".")) { if (withinDomain(email1, email2) || email1.equalsIgnoreCase(email2)) { intersect.add(email1); } else if (withinDomain(email2, email1)) { intersect.add(email2); } } else { if (withinDomain(email2, email1)) { intersect.add(email2); } } } // email1 specifies a host else { if (email2.indexOf('@') != -1) { String _sub = email2.substring(email2.indexOf('@') + 1); if (_sub.equalsIgnoreCase(email1)) { intersect.add(email2); } } // email2 specifies a domain else if (email2.startsWith(".")) { if (withinDomain(email1, email2)) { intersect.add(email1); } } // email2 specifies a particular host else { if (email1.equalsIgnoreCase(email2)) { intersect.add(email1); } } } } private void checkExcludedURI(Set excluded, String uri) throws PKIXNameConstraintValidatorException { if (excluded.isEmpty()) { return; } Iterator it = excluded.iterator(); while (it.hasNext()) { String str = ((String)it.next()); if (isUriConstrained(uri, str)) { throw new PKIXNameConstraintValidatorException( "URI is from an excluded subtree."); } } } private Set intersectURI(Set permitted, Set uris) { Set intersect = new HashSet(); for (Iterator it = uris.iterator(); it.hasNext();) { String uri = extractNameAsString(((GeneralSubtree)it.next()) .getBase()); if (permitted == null) { if (uri != null) { intersect.add(uri); } } else { Iterator _iter = permitted.iterator(); while (_iter.hasNext()) { String _permitted = (String)_iter.next(); intersectURI(_permitted, uri, intersect); } } } return intersect; } private Set unionURI(Set excluded, String uri) { if (excluded.isEmpty()) { if (uri == null) { return excluded; } excluded.add(uri); return excluded; } else { Set union = new HashSet(); Iterator _iter = excluded.iterator(); while (_iter.hasNext()) { String _excluded = (String)_iter.next(); unionURI(_excluded, uri, union); } return union; } } private void intersectURI(String email1, String email2, Set intersect) { // email1 is a particular address if (email1.indexOf('@') != -1) { String _sub = email1.substring(email1.indexOf('@') + 1); // both are a particular mailbox if (email2.indexOf('@') != -1) { if (email1.equalsIgnoreCase(email2)) { intersect.add(email1); } } // email2 specifies a domain else if (email2.startsWith(".")) { if (withinDomain(_sub, email2)) { intersect.add(email1); } } // email2 specifies a particular host else { if (_sub.equalsIgnoreCase(email2)) { intersect.add(email1); } } } // email specifies a domain else if (email1.startsWith(".")) { if (email2.indexOf('@') != -1) { String _sub = email2.substring(email1.indexOf('@') + 1); if (withinDomain(_sub, email1)) { intersect.add(email2); } } // email2 specifies a domain else if (email2.startsWith(".")) { if (withinDomain(email1, email2) || email1.equalsIgnoreCase(email2)) { intersect.add(email1); } else if (withinDomain(email2, email1)) { intersect.add(email2); } } else { if (withinDomain(email2, email1)) { intersect.add(email2); } } } // email1 specifies a host else { if (email2.indexOf('@') != -1) { String _sub = email2.substring(email2.indexOf('@') + 1); if (_sub.equalsIgnoreCase(email1)) { intersect.add(email2); } } // email2 specifies a domain else if (email2.startsWith(".")) { if (withinDomain(email1, email2)) { intersect.add(email1); } } // email2 specifies a particular host else { if (email1.equalsIgnoreCase(email2)) { intersect.add(email1); } } } } private void checkPermittedURI(Set permitted, String uri) throws PKIXNameConstraintValidatorException { if (permitted == null) { return; } Iterator it = permitted.iterator(); while (it.hasNext()) { String str = ((String)it.next()); if (isUriConstrained(uri, str)) { return; } } if (uri.length() == 0 && permitted.size() == 0) { return; } throw new PKIXNameConstraintValidatorException( "URI is not from a permitted subtree."); } private boolean isUriConstrained(String uri, String constraint) { String host = extractHostFromURL(uri); // a host if (!constraint.startsWith(".")) { if (host.equalsIgnoreCase(constraint)) { return true; } } // in sub domain or domain else if (withinDomain(host, constraint)) { return true; } return false; } private static String extractHostFromURL(String url) { // see RFC 1738 // remove ':' after protocol, e.g. http: String sub = url.substring(url.indexOf(':') + 1); // extract host from Common Internet Scheme Syntax, e.g. http:// if (sub.indexOf("//") != -1) { sub = sub.substring(sub.indexOf("//") + 2); } // first remove port, e.g. http://test.com:21 if (sub.lastIndexOf(':') != -1) { sub = sub.substring(0, sub.lastIndexOf(':')); } // remove user and password, e.g. http://john:password@test.com sub = sub.substring(sub.indexOf(':') + 1); sub = sub.substring(sub.indexOf('@') + 1); // remove local parts, e.g. http://test.com/bla if (sub.indexOf('/') != -1) { sub = sub.substring(0, sub.indexOf('/')); } return sub; } /** * Checks if the given GeneralName is in the permitted set. * * @param name The GeneralName * @throws PKIXNameConstraintValidatorException * If the name */ public void checkPermitted(GeneralName name) throws PKIXNameConstraintValidatorException { switch (name.getTagNo()) { case 1: checkPermittedEmail(permittedSubtreesEmail, extractNameAsString(name)); break; case 2: checkPermittedDNS(permittedSubtreesDNS, DERIA5String.getInstance( name.getName()).getString()); break; case 4: checkPermittedDN(ASN1Sequence.getInstance(name.getName() .toASN1Primitive())); break; case 6: checkPermittedURI(permittedSubtreesURI, DERIA5String.getInstance( name.getName()).getString()); break; case 7: byte[] ip = ASN1OctetString.getInstance(name.getName()).getOctets(); checkPermittedIP(permittedSubtreesIP, ip); } } /** * Check if the given GeneralName is contained in the excluded set. * * @param name The GeneralName. * @throws PKIXNameConstraintValidatorException * If the name is * excluded. */ public void checkExcluded(GeneralName name) throws PKIXNameConstraintValidatorException { switch (name.getTagNo()) { case 1: checkExcludedEmail(excludedSubtreesEmail, extractNameAsString(name)); break; case 2: checkExcludedDNS(excludedSubtreesDNS, DERIA5String.getInstance( name.getName()).getString()); break; case 4: checkExcludedDN(ASN1Sequence.getInstance(name.getName() .toASN1Primitive())); break; case 6: checkExcludedURI(excludedSubtreesURI, DERIA5String.getInstance( name.getName()).getString()); break; case 7: byte[] ip = ASN1OctetString.getInstance(name.getName()).getOctets(); checkExcludedIP(excludedSubtreesIP, ip); } } public void intersectPermittedSubtree(GeneralSubtree permitted) { intersectPermittedSubtree(new GeneralSubtree[] { permitted }); } /** * Updates the permitted set of these name constraints with the intersection * with the given subtree. * * @param permitted The permitted subtrees */ public void intersectPermittedSubtree(GeneralSubtree[] permitted) { Map subtreesMap = new HashMap(); // group in sets in a map ordered by tag no. for (int i = 0; i != permitted.length; i++) { GeneralSubtree subtree = permitted[i]; Integer tagNo = Integers.valueOf(subtree.getBase().getTagNo()); if (subtreesMap.get(tagNo) == null) { subtreesMap.put(tagNo, new HashSet()); } ((Set)subtreesMap.get(tagNo)).add(subtree); } for (Iterator it = subtreesMap.entrySet().iterator(); it.hasNext();) { Map.Entry entry = (Map.Entry)it.next(); // go through all subtree groups switch (((Integer)entry.getKey()).intValue()) { case 1: permittedSubtreesEmail = intersectEmail(permittedSubtreesEmail, (Set)entry.getValue()); break; case 2: permittedSubtreesDNS = intersectDNS(permittedSubtreesDNS, (Set)entry.getValue()); break; case 4: permittedSubtreesDN = intersectDN(permittedSubtreesDN, (Set)entry.getValue()); break; case 6: permittedSubtreesURI = intersectURI(permittedSubtreesURI, (Set)entry.getValue()); break; case 7: permittedSubtreesIP = intersectIP(permittedSubtreesIP, (Set)entry.getValue()); } } } private String extractNameAsString(GeneralName name) { return DERIA5String.getInstance(name.getName()).getString(); } public void intersectEmptyPermittedSubtree(int nameType) { switch (nameType) { case 1: permittedSubtreesEmail = new HashSet(); break; case 2: permittedSubtreesDNS = new HashSet(); break; case 4: permittedSubtreesDN = new HashSet(); break; case 6: permittedSubtreesURI = new HashSet(); break; case 7: permittedSubtreesIP = new HashSet(); } } /** * Adds a subtree to the excluded set of these name constraints. * * @param subtree A subtree with an excluded GeneralName. */ public void addExcludedSubtree(GeneralSubtree subtree) { GeneralName base = subtree.getBase(); switch (base.getTagNo()) { case 1: excludedSubtreesEmail = unionEmail(excludedSubtreesEmail, extractNameAsString(base)); break; case 2: excludedSubtreesDNS = unionDNS(excludedSubtreesDNS, extractNameAsString(base)); break; case 4: excludedSubtreesDN = unionDN(excludedSubtreesDN, (ASN1Sequence)base.getName().toASN1Primitive()); break; case 6: excludedSubtreesURI = unionURI(excludedSubtreesURI, extractNameAsString(base)); break; case 7: excludedSubtreesIP = unionIP(excludedSubtreesIP, ASN1OctetString .getInstance(base.getName()).getOctets()); break; } } /** * Returns the maximum IP address. * * @param ip1 The first IP address. * @param ip2 The second IP address. * @return The maximum IP address. */ private static byte[] max(byte[] ip1, byte[] ip2) { for (int i = 0; i < ip1.length; i++) { if ((ip1[i] & 0xFFFF) > (ip2[i] & 0xFFFF)) { return ip1; } } return ip2; } /** * Returns the minimum IP address. * * @param ip1 The first IP address. * @param ip2 The second IP address. * @return The minimum IP address. */ private static byte[] min(byte[] ip1, byte[] ip2) { for (int i = 0; i < ip1.length; i++) { if ((ip1[i] & 0xFFFF) < (ip2[i] & 0xFFFF)) { return ip1; } } return ip2; } /** * Compares IP address ip1 with ip2. If ip1 * is equal to ip2 0 is returned. If ip1 is bigger 1 is returned, -1 * otherwise. * * @param ip1 The first IP address. * @param ip2 The second IP address. * @return 0 if ip1 is equal to ip2, 1 if ip1 is bigger, -1 otherwise. */ private static int compareTo(byte[] ip1, byte[] ip2) { if (Arrays.areEqual(ip1, ip2)) { return 0; } if (Arrays.areEqual(max(ip1, ip2), ip1)) { return 1; } return -1; } /** * Returns the logical OR of the IP addresses ip1 and * ip2. * * @param ip1 The first IP address. * @param ip2 The second IP address. * @return The OR of ip1 and ip2. */ private static byte[] or(byte[] ip1, byte[] ip2) { byte[] temp = new byte[ip1.length]; for (int i = 0; i < ip1.length; i++) { temp[i] = (byte)(ip1[i] | ip2[i]); } return temp; } public int hashCode() { return hashCollection(excludedSubtreesDN) + hashCollection(excludedSubtreesDNS) + hashCollection(excludedSubtreesEmail) + hashCollection(excludedSubtreesIP) + hashCollection(excludedSubtreesURI) + hashCollection(permittedSubtreesDN) + hashCollection(permittedSubtreesDNS) + hashCollection(permittedSubtreesEmail) + hashCollection(permittedSubtreesIP) + hashCollection(permittedSubtreesURI); } private int hashCollection(Collection coll) { if (coll == null) { return 0; } int hash = 0; Iterator it1 = coll.iterator(); while (it1.hasNext()) { Object o = it1.next(); if (o instanceof byte[]) { hash += Arrays.hashCode((byte[])o); } else { hash += o.hashCode(); } } return hash; } public boolean equals(Object o) { if (!(o instanceof PKIXNameConstraintValidator)) { return false; } PKIXNameConstraintValidator constraintValidator = (PKIXNameConstraintValidator)o; return collectionsAreEqual(constraintValidator.excludedSubtreesDN, excludedSubtreesDN) && collectionsAreEqual(constraintValidator.excludedSubtreesDNS, excludedSubtreesDNS) && collectionsAreEqual(constraintValidator.excludedSubtreesEmail, excludedSubtreesEmail) && collectionsAreEqual(constraintValidator.excludedSubtreesIP, excludedSubtreesIP) && collectionsAreEqual(constraintValidator.excludedSubtreesURI, excludedSubtreesURI) && collectionsAreEqual(constraintValidator.permittedSubtreesDN, permittedSubtreesDN) && collectionsAreEqual(constraintValidator.permittedSubtreesDNS, permittedSubtreesDNS) && collectionsAreEqual(constraintValidator.permittedSubtreesEmail, permittedSubtreesEmail) && collectionsAreEqual(constraintValidator.permittedSubtreesIP, permittedSubtreesIP) && collectionsAreEqual(constraintValidator.permittedSubtreesURI, permittedSubtreesURI); } private boolean collectionsAreEqual(Collection coll1, Collection coll2) { if (coll1 == coll2) { return true; } if (coll1 == null || coll2 == null) { return false; } if (coll1.size() != coll2.size()) { return false; } Iterator it1 = coll1.iterator(); while (it1.hasNext()) { Object a = it1.next(); Iterator it2 = coll2.iterator(); boolean found = false; while (it2.hasNext()) { Object b = it2.next(); if (equals(a, b)) { found = true; break; } } if (!found) { return false; } } return true; } private boolean equals(Object o1, Object o2) { if (o1 == o2) { return true; } if (o1 == null || o2 == null) { return false; } if (o1 instanceof byte[] && o2 instanceof byte[]) { return Arrays.areEqual((byte[])o1, (byte[])o2); } else { return o1.equals(o2); } } /** * Stringifies an IPv4 or v6 address with subnet mask. * * @param ip The IP with subnet mask. * @return The stringified IP address. */ private String stringifyIP(byte[] ip) { String temp = ""; for (int i = 0; i < ip.length / 2; i++) { temp += Integer.toString(ip[i] & 0x00FF) + "."; } temp = temp.substring(0, temp.length() - 1); temp += "/"; for (int i = ip.length / 2; i < ip.length; i++) { temp += Integer.toString(ip[i] & 0x00FF) + "."; } temp = temp.substring(0, temp.length() - 1); return temp; } private String stringifyIPCollection(Set ips) { String temp = ""; temp += "["; for (Iterator it = ips.iterator(); it.hasNext();) { temp += stringifyIP((byte[])it.next()) + ","; } if (temp.length() > 1) { temp = temp.substring(0, temp.length() - 1); } temp += "]"; return temp; } public String toString() { String temp = ""; temp += "permitted:\n"; if (permittedSubtreesDN != null) { temp += "DN:\n"; temp += permittedSubtreesDN.toString() + "\n"; } if (permittedSubtreesDNS != null) { temp += "DNS:\n"; temp += permittedSubtreesDNS.toString() + "\n"; } if (permittedSubtreesEmail != null) { temp += "Email:\n"; temp += permittedSubtreesEmail.toString() + "\n"; } if (permittedSubtreesURI != null) { temp += "URI:\n"; temp += permittedSubtreesURI.toString() + "\n"; } if (permittedSubtreesIP != null) { temp += "IP:\n"; temp += stringifyIPCollection(permittedSubtreesIP) + "\n"; } temp += "excluded:\n"; if (!excludedSubtreesDN.isEmpty()) { temp += "DN:\n"; temp += excludedSubtreesDN.toString() + "\n"; } if (!excludedSubtreesDNS.isEmpty()) { temp += "DNS:\n"; temp += excludedSubtreesDNS.toString() + "\n"; } if (!excludedSubtreesEmail.isEmpty()) { temp += "Email:\n"; temp += excludedSubtreesEmail.toString() + "\n"; } if (!excludedSubtreesURI.isEmpty()) { temp += "URI:\n"; temp += excludedSubtreesURI.toString() + "\n"; } if (!excludedSubtreesIP.isEmpty()) { temp += "IP:\n"; temp += stringifyIPCollection(excludedSubtreesIP) + "\n"; } return temp; } } bouncycastle-1.49.orig/src/org/bouncycastle/jce/provider/X509SignatureUtil.java0000644000175000017500000001120212103437526027124 0ustar ebourgebourgpackage org.bouncycastle.jce.provider; import java.io.IOException; import java.security.AlgorithmParameters; import java.security.GeneralSecurityException; import java.security.InvalidKeyException; import java.security.NoSuchAlgorithmException; import java.security.Signature; import java.security.SignatureException; import java.security.spec.PSSParameterSpec; import org.bouncycastle.asn1.ASN1Encodable; import org.bouncycastle.asn1.ASN1Null; import org.bouncycastle.asn1.ASN1Sequence; import org.bouncycastle.asn1.DERNull; import org.bouncycastle.asn1.DERObjectIdentifier; import org.bouncycastle.asn1.cryptopro.CryptoProObjectIdentifiers; import org.bouncycastle.asn1.nist.NISTObjectIdentifiers; import org.bouncycastle.asn1.oiw.OIWObjectIdentifiers; import org.bouncycastle.asn1.pkcs.PKCSObjectIdentifiers; import org.bouncycastle.asn1.pkcs.RSASSAPSSparams; import org.bouncycastle.asn1.teletrust.TeleTrusTObjectIdentifiers; import org.bouncycastle.asn1.x509.AlgorithmIdentifier; import org.bouncycastle.asn1.x9.X9ObjectIdentifiers; class X509SignatureUtil { private static final ASN1Null derNull = DERNull.INSTANCE; static void setSignatureParameters( Signature signature, ASN1Encodable params) throws NoSuchAlgorithmException, SignatureException, InvalidKeyException { if (params != null && !derNull.equals(params)) { AlgorithmParameters sigParams = AlgorithmParameters.getInstance(signature.getAlgorithm(), signature.getProvider()); try { sigParams.init(params.toASN1Primitive().getEncoded()); } catch (IOException e) { throw new SignatureException("IOException decoding parameters: " + e.getMessage()); } if (signature.getAlgorithm().endsWith("MGF1")) { try { signature.setParameter(sigParams.getParameterSpec(PSSParameterSpec.class)); } catch (GeneralSecurityException e) { throw new SignatureException("Exception extracting parameters: " + e.getMessage()); } } } } static String getSignatureName( AlgorithmIdentifier sigAlgId) { ASN1Encodable params = sigAlgId.getParameters(); if (params != null && !derNull.equals(params)) { if (sigAlgId.getObjectId().equals(PKCSObjectIdentifiers.id_RSASSA_PSS)) { RSASSAPSSparams rsaParams = RSASSAPSSparams.getInstance(params); return getDigestAlgName(rsaParams.getHashAlgorithm().getObjectId()) + "withRSAandMGF1"; } if (sigAlgId.getObjectId().equals(X9ObjectIdentifiers.ecdsa_with_SHA2)) { ASN1Sequence ecDsaParams = ASN1Sequence.getInstance(params); return getDigestAlgName((DERObjectIdentifier)ecDsaParams.getObjectAt(0)) + "withECDSA"; } } return sigAlgId.getObjectId().getId(); } /** * Return the digest algorithm using one of the standard JCA string * representations rather the the algorithm identifier (if possible). */ private static String getDigestAlgName( DERObjectIdentifier digestAlgOID) { if (PKCSObjectIdentifiers.md5.equals(digestAlgOID)) { return "MD5"; } else if (OIWObjectIdentifiers.idSHA1.equals(digestAlgOID)) { return "SHA1"; } else if (NISTObjectIdentifiers.id_sha224.equals(digestAlgOID)) { return "SHA224"; } else if (NISTObjectIdentifiers.id_sha256.equals(digestAlgOID)) { return "SHA256"; } else if (NISTObjectIdentifiers.id_sha384.equals(digestAlgOID)) { return "SHA384"; } else if (NISTObjectIdentifiers.id_sha512.equals(digestAlgOID)) { return "SHA512"; } else if (TeleTrusTObjectIdentifiers.ripemd128.equals(digestAlgOID)) { return "RIPEMD128"; } else if (TeleTrusTObjectIdentifiers.ripemd160.equals(digestAlgOID)) { return "RIPEMD160"; } else if (TeleTrusTObjectIdentifiers.ripemd256.equals(digestAlgOID)) { return "RIPEMD256"; } else if (CryptoProObjectIdentifiers.gostR3411.equals(digestAlgOID)) { return "GOST3411"; } else { return digestAlgOID.getId(); } } } bouncycastle-1.49.orig/src/org/bouncycastle/jce/provider/PKIXNameConstraintValidatorException.java0000644000175000017500000000032011624640052033101 0ustar ebourgebourgpackage org.bouncycastle.jce.provider; public class PKIXNameConstraintValidatorException extends Exception { public PKIXNameConstraintValidatorException(String msg) { super(msg); } } bouncycastle-1.49.orig/src/org/bouncycastle/jce/provider/X509CRLEntryObject.java0000644000175000017500000002121511737275260027132 0ustar ebourgebourgpackage org.bouncycastle.jce.provider; import java.io.IOException; import java.math.BigInteger; import java.security.cert.CRLException; import java.security.cert.X509CRLEntry; import java.util.Date; import java.util.Enumeration; import java.util.HashSet; import java.util.Set; import javax.security.auth.x500.X500Principal; import org.bouncycastle.asn1.ASN1Encoding; import org.bouncycastle.asn1.ASN1Enumerated; import org.bouncycastle.asn1.ASN1InputStream; import org.bouncycastle.asn1.ASN1ObjectIdentifier; import org.bouncycastle.asn1.util.ASN1Dump; import org.bouncycastle.asn1.x500.X500Name; import org.bouncycastle.asn1.x509.CRLReason; import org.bouncycastle.asn1.x509.Extension; import org.bouncycastle.asn1.x509.Extensions; import org.bouncycastle.asn1.x509.GeneralName; import org.bouncycastle.asn1.x509.GeneralNames; import org.bouncycastle.asn1.x509.TBSCertList; import org.bouncycastle.asn1.x509.X509Extension; /** * The following extensions are listed in RFC 2459 as relevant to CRL Entries * * ReasonCode Hode Instruction Code Invalidity Date Certificate Issuer * (critical) */ public class X509CRLEntryObject extends X509CRLEntry { private TBSCertList.CRLEntry c; private X500Name certificateIssuer; private int hashValue; private boolean isHashValueSet; public X509CRLEntryObject(TBSCertList.CRLEntry c) { this.c = c; this.certificateIssuer = null; } /** * Constructor for CRLEntries of indirect CRLs. If isIndirect * is false {@link #getCertificateIssuer()} will always * return null, previousCertificateIssuer is * ignored. If this isIndirect is specified and this CRLEntry * has no certificate issuer CRL entry extension * previousCertificateIssuer is returned by * {@link #getCertificateIssuer()}. * * @param c * TBSCertList.CRLEntry object. * @param isIndirect * true if the corresponding CRL is a indirect * CRL. * @param previousCertificateIssuer * Certificate issuer of the previous CRLEntry. */ public X509CRLEntryObject( TBSCertList.CRLEntry c, boolean isIndirect, X500Name previousCertificateIssuer) { this.c = c; this.certificateIssuer = loadCertificateIssuer(isIndirect, previousCertificateIssuer); } /** * Will return true if any extensions are present and marked as critical as * we currently don't handle any extensions! */ public boolean hasUnsupportedCriticalExtension() { Set extns = getCriticalExtensionOIDs(); return extns != null && !extns.isEmpty(); } private X500Name loadCertificateIssuer(boolean isIndirect, X500Name previousCertificateIssuer) { if (!isIndirect) { return null; } Extension ext = getExtension(Extension.certificateIssuer); if (ext == null) { return previousCertificateIssuer; } try { GeneralName[] names = GeneralNames.getInstance(ext.getParsedValue()).getNames(); for (int i = 0; i < names.length; i++) { if (names[i].getTagNo() == GeneralName.directoryName) { return X500Name.getInstance(names[i].getName()); } } return null; } catch (Exception e) { return null; } } public X500Principal getCertificateIssuer() { if (certificateIssuer == null) { return null; } try { return new X500Principal(certificateIssuer.getEncoded()); } catch (IOException e) { return null; } } private Set getExtensionOIDs(boolean critical) { Extensions extensions = c.getExtensions(); if (extensions != null) { Set set = new HashSet(); Enumeration e = extensions.oids(); while (e.hasMoreElements()) { ASN1ObjectIdentifier oid = (ASN1ObjectIdentifier) e.nextElement(); Extension ext = extensions.getExtension(oid); if (critical == ext.isCritical()) { set.add(oid.getId()); } } return set; } return null; } public Set getCriticalExtensionOIDs() { return getExtensionOIDs(true); } public Set getNonCriticalExtensionOIDs() { return getExtensionOIDs(false); } private Extension getExtension(ASN1ObjectIdentifier oid) { Extensions exts = c.getExtensions(); if (exts != null) { return exts.getExtension(oid); } return null; } public byte[] getExtensionValue(String oid) { Extension ext = getExtension(new ASN1ObjectIdentifier(oid)); if (ext != null) { try { return ext.getExtnValue().getEncoded(); } catch (Exception e) { throw new RuntimeException("error encoding " + e.toString()); } } return null; } /** * Cache the hashCode value - calculating it with the standard method. * @return calculated hashCode. */ public int hashCode() { if (!isHashValueSet) { hashValue = super.hashCode(); isHashValueSet = true; } return hashValue; } public byte[] getEncoded() throws CRLException { try { return c.getEncoded(ASN1Encoding.DER); } catch (IOException e) { throw new CRLException(e.toString()); } } public BigInteger getSerialNumber() { return c.getUserCertificate().getValue(); } public Date getRevocationDate() { return c.getRevocationDate().getDate(); } public boolean hasExtensions() { return c.getExtensions() != null; } public String toString() { StringBuffer buf = new StringBuffer(); String nl = System.getProperty("line.separator"); buf.append(" userCertificate: ").append(this.getSerialNumber()).append(nl); buf.append(" revocationDate: ").append(this.getRevocationDate()).append(nl); buf.append(" certificateIssuer: ").append(this.getCertificateIssuer()).append(nl); Extensions extensions = c.getExtensions(); if (extensions != null) { Enumeration e = extensions.oids(); if (e.hasMoreElements()) { buf.append(" crlEntryExtensions:").append(nl); while (e.hasMoreElements()) { ASN1ObjectIdentifier oid = (ASN1ObjectIdentifier)e.nextElement(); Extension ext = extensions.getExtension(oid); if (ext.getExtnValue() != null) { byte[] octs = ext.getExtnValue().getOctets(); ASN1InputStream dIn = new ASN1InputStream(octs); buf.append(" critical(").append(ext.isCritical()).append(") "); try { if (oid.equals(X509Extension.reasonCode)) { buf.append(CRLReason.getInstance(ASN1Enumerated.getInstance(dIn.readObject()))).append(nl); } else if (oid.equals(X509Extension.certificateIssuer)) { buf.append("Certificate issuer: ").append(GeneralNames.getInstance(dIn.readObject())).append(nl); } else { buf.append(oid.getId()); buf.append(" value = ").append(ASN1Dump.dumpAsString(dIn.readObject())).append(nl); } } catch (Exception ex) { buf.append(oid.getId()); buf.append(" value = ").append("*****").append(nl); } } else { buf.append(nl); } } } } return buf.toString(); } } bouncycastle-1.49.orig/src/org/bouncycastle/jce/provider/ReasonsMask.java0000644000175000017500000000475611624640052026202 0ustar ebourgebourgpackage org.bouncycastle.jce.provider; import org.bouncycastle.asn1.x509.ReasonFlags; /** * This class helps to handle CRL revocation reasons mask. Each CRL handles a * certain set of revocation reasons. */ class ReasonsMask { private int _reasons; /** * Constructs are reason mask with the reasons. * * @param reasons The reasons. */ ReasonsMask(ReasonFlags reasons) { _reasons = reasons.intValue(); } private ReasonsMask(int reasons) { _reasons = reasons; } /** * A reason mask with no reason. * */ ReasonsMask() { this(0); } /** * A mask with all revocation reasons. */ static final ReasonsMask allReasons = new ReasonsMask(ReasonFlags.aACompromise | ReasonFlags.affiliationChanged | ReasonFlags.cACompromise | ReasonFlags.certificateHold | ReasonFlags.cessationOfOperation | ReasonFlags.keyCompromise | ReasonFlags.privilegeWithdrawn | ReasonFlags.unused | ReasonFlags.superseded); /** * Adds all reasons from the reasons mask to this mask. * * @param mask The reasons mask to add. */ void addReasons(ReasonsMask mask) { _reasons = _reasons | mask.getReasons(); } /** * Returns true if this reasons mask contains all possible * reasons. * * @return true if this reasons mask contains all possible * reasons. */ boolean isAllReasons() { return _reasons == allReasons._reasons ? true : false; } /** * Intersects this mask with the given reasons mask. * * @param mask The mask to intersect with. * @return The intersection of this and teh given mask. */ ReasonsMask intersect(ReasonsMask mask) { ReasonsMask _mask = new ReasonsMask(); _mask.addReasons(new ReasonsMask(_reasons & mask.getReasons())); return _mask; } /** * Returns true if the passed reasons mask has new reasons. * * @param mask The reasons mask which should be tested for new reasons. * @return true if the passed reasons mask has new reasons. */ boolean hasNewReasons(ReasonsMask mask) { return ((_reasons | mask.getReasons() ^ _reasons) != 0); } /** * Returns the reasons in this mask. * * @return Returns the reasons. */ int getReasons() { return _reasons; } } bouncycastle-1.49.orig/src/org/bouncycastle/jce/provider/JCEECPublicKey.java0000644000175000017500000004164612110037231026362 0ustar ebourgebourgpackage org.bouncycastle.jce.provider; import java.io.IOException; import java.io.ObjectInputStream; import java.io.ObjectOutputStream; import java.math.BigInteger; import java.security.interfaces.ECPublicKey; import java.security.spec.ECParameterSpec; import java.security.spec.ECPoint; import java.security.spec.ECPublicKeySpec; import java.security.spec.EllipticCurve; import org.bouncycastle.asn1.ASN1Encodable; import org.bouncycastle.asn1.ASN1ObjectIdentifier; import org.bouncycastle.asn1.ASN1OctetString; import org.bouncycastle.asn1.ASN1Primitive; import org.bouncycastle.asn1.ASN1Sequence; import org.bouncycastle.asn1.DERBitString; import org.bouncycastle.asn1.DERNull; import org.bouncycastle.asn1.DEROctetString; import org.bouncycastle.asn1.cryptopro.CryptoProObjectIdentifiers; import org.bouncycastle.asn1.cryptopro.ECGOST3410NamedCurves; import org.bouncycastle.asn1.cryptopro.GOST3410PublicKeyAlgParameters; import org.bouncycastle.asn1.x509.AlgorithmIdentifier; import org.bouncycastle.asn1.x509.SubjectPublicKeyInfo; import org.bouncycastle.asn1.x9.X962Parameters; import org.bouncycastle.asn1.x9.X9ECParameters; import org.bouncycastle.asn1.x9.X9ECPoint; import org.bouncycastle.asn1.x9.X9IntegerConverter; import org.bouncycastle.asn1.x9.X9ObjectIdentifiers; import org.bouncycastle.crypto.params.ECDomainParameters; import org.bouncycastle.crypto.params.ECPublicKeyParameters; import org.bouncycastle.jcajce.provider.asymmetric.util.EC5Util; import org.bouncycastle.jcajce.provider.asymmetric.util.ECUtil; import org.bouncycastle.jcajce.provider.asymmetric.util.KeyUtil; import org.bouncycastle.jce.ECGOST3410NamedCurveTable; import org.bouncycastle.jce.interfaces.ECPointEncoder; import org.bouncycastle.jce.spec.ECNamedCurveParameterSpec; import org.bouncycastle.jce.spec.ECNamedCurveSpec; import org.bouncycastle.math.ec.ECCurve; public class JCEECPublicKey implements ECPublicKey, org.bouncycastle.jce.interfaces.ECPublicKey, ECPointEncoder { private String algorithm = "EC"; private org.bouncycastle.math.ec.ECPoint q; private ECParameterSpec ecSpec; private boolean withCompression; private GOST3410PublicKeyAlgParameters gostParams; public JCEECPublicKey( String algorithm, JCEECPublicKey key) { this.algorithm = algorithm; this.q = key.q; this.ecSpec = key.ecSpec; this.withCompression = key.withCompression; this.gostParams = key.gostParams; } public JCEECPublicKey( String algorithm, ECPublicKeySpec spec) { this.algorithm = algorithm; this.ecSpec = spec.getParams(); this.q = EC5Util.convertPoint(ecSpec, spec.getW(), false); } public JCEECPublicKey( String algorithm, org.bouncycastle.jce.spec.ECPublicKeySpec spec) { this.algorithm = algorithm; this.q = spec.getQ(); if (spec.getParams() != null) // can be null if implictlyCa { ECCurve curve = spec.getParams().getCurve(); EllipticCurve ellipticCurve = EC5Util.convertCurve(curve, spec.getParams().getSeed()); this.ecSpec = EC5Util.convertSpec(ellipticCurve, spec.getParams()); } else { if (q.getCurve() == null) { org.bouncycastle.jce.spec.ECParameterSpec s = BouncyCastleProvider.CONFIGURATION.getEcImplicitlyCa(); q = s.getCurve().createPoint(q.getX().toBigInteger(), q.getY().toBigInteger(), false); } this.ecSpec = null; } } public JCEECPublicKey( String algorithm, ECPublicKeyParameters params, ECParameterSpec spec) { ECDomainParameters dp = params.getParameters(); this.algorithm = algorithm; this.q = params.getQ(); if (spec == null) { EllipticCurve ellipticCurve = EC5Util.convertCurve(dp.getCurve(), dp.getSeed()); this.ecSpec = createSpec(ellipticCurve, dp); } else { this.ecSpec = spec; } } public JCEECPublicKey( String algorithm, ECPublicKeyParameters params, org.bouncycastle.jce.spec.ECParameterSpec spec) { ECDomainParameters dp = params.getParameters(); this.algorithm = algorithm; this.q = params.getQ(); if (spec == null) { EllipticCurve ellipticCurve = EC5Util.convertCurve(dp.getCurve(), dp.getSeed()); this.ecSpec = createSpec(ellipticCurve, dp); } else { EllipticCurve ellipticCurve = EC5Util.convertCurve(spec.getCurve(), spec.getSeed()); this.ecSpec = EC5Util.convertSpec(ellipticCurve, spec); } } /* * called for implicitCA */ public JCEECPublicKey( String algorithm, ECPublicKeyParameters params) { this.algorithm = algorithm; this.q = params.getQ(); this.ecSpec = null; } private ECParameterSpec createSpec(EllipticCurve ellipticCurve, ECDomainParameters dp) { return new ECParameterSpec( ellipticCurve, new ECPoint( dp.getG().getX().toBigInteger(), dp.getG().getY().toBigInteger()), dp.getN(), dp.getH().intValue()); } public JCEECPublicKey( ECPublicKey key) { this.algorithm = key.getAlgorithm(); this.ecSpec = key.getParams(); this.q = EC5Util.convertPoint(this.ecSpec, key.getW(), false); } JCEECPublicKey( SubjectPublicKeyInfo info) { populateFromPubKeyInfo(info); } private void populateFromPubKeyInfo(SubjectPublicKeyInfo info) { if (info.getAlgorithmId().getObjectId().equals(CryptoProObjectIdentifiers.gostR3410_2001)) { DERBitString bits = info.getPublicKeyData(); ASN1OctetString key; this.algorithm = "ECGOST3410"; try { key = (ASN1OctetString) ASN1Primitive.fromByteArray(bits.getBytes()); } catch (IOException ex) { throw new IllegalArgumentException("error recovering public key"); } byte[] keyEnc = key.getOctets(); byte[] x = new byte[32]; byte[] y = new byte[32]; for (int i = 0; i != x.length; i++) { x[i] = keyEnc[32 - 1 - i]; } for (int i = 0; i != y.length; i++) { y[i] = keyEnc[64 - 1 - i]; } gostParams = new GOST3410PublicKeyAlgParameters((ASN1Sequence)info.getAlgorithmId().getParameters()); ECNamedCurveParameterSpec spec = ECGOST3410NamedCurveTable.getParameterSpec(ECGOST3410NamedCurves.getName(gostParams.getPublicKeyParamSet())); ECCurve curve = spec.getCurve(); EllipticCurve ellipticCurve = EC5Util.convertCurve(curve, spec.getSeed()); this.q = curve.createPoint(new BigInteger(1, x), new BigInteger(1, y), false); ecSpec = new ECNamedCurveSpec( ECGOST3410NamedCurves.getName(gostParams.getPublicKeyParamSet()), ellipticCurve, new ECPoint( spec.getG().getX().toBigInteger(), spec.getG().getY().toBigInteger()), spec.getN(), spec.getH()); } else { X962Parameters params = new X962Parameters((ASN1Primitive)info.getAlgorithmId().getParameters()); ECCurve curve; EllipticCurve ellipticCurve; if (params.isNamedCurve()) { ASN1ObjectIdentifier oid = (ASN1ObjectIdentifier)params.getParameters(); X9ECParameters ecP = ECUtil.getNamedCurveByOid(oid); curve = ecP.getCurve(); ellipticCurve = EC5Util.convertCurve(curve, ecP.getSeed()); ecSpec = new ECNamedCurveSpec( ECUtil.getCurveName(oid), ellipticCurve, new ECPoint( ecP.getG().getX().toBigInteger(), ecP.getG().getY().toBigInteger()), ecP.getN(), ecP.getH()); } else if (params.isImplicitlyCA()) { ecSpec = null; curve = BouncyCastleProvider.CONFIGURATION.getEcImplicitlyCa().getCurve(); } else { X9ECParameters ecP = X9ECParameters.getInstance(params.getParameters()); curve = ecP.getCurve(); ellipticCurve = EC5Util.convertCurve(curve, ecP.getSeed()); this.ecSpec = new ECParameterSpec( ellipticCurve, new ECPoint( ecP.getG().getX().toBigInteger(), ecP.getG().getY().toBigInteger()), ecP.getN(), ecP.getH().intValue()); } DERBitString bits = info.getPublicKeyData(); byte[] data = bits.getBytes(); ASN1OctetString key = new DEROctetString(data); // // extra octet string - one of our old certs... // if (data[0] == 0x04 && data[1] == data.length - 2 && (data[2] == 0x02 || data[2] == 0x03)) { int qLength = new X9IntegerConverter().getByteLength(curve); if (qLength >= data.length - 3) { try { key = (ASN1OctetString) ASN1Primitive.fromByteArray(data); } catch (IOException ex) { throw new IllegalArgumentException("error recovering public key"); } } } X9ECPoint derQ = new X9ECPoint(curve, key); this.q = derQ.getPoint(); } } public String getAlgorithm() { return algorithm; } public String getFormat() { return "X.509"; } public byte[] getEncoded() { ASN1Encodable params; SubjectPublicKeyInfo info; if (algorithm.equals("ECGOST3410")) { if (gostParams != null) { params = gostParams; } else { if (ecSpec instanceof ECNamedCurveSpec) { params = new GOST3410PublicKeyAlgParameters( ECGOST3410NamedCurves.getOID(((ECNamedCurveSpec)ecSpec).getName()), CryptoProObjectIdentifiers.gostR3411_94_CryptoProParamSet); } else { // strictly speaking this may not be applicable... ECCurve curve = EC5Util.convertCurve(ecSpec.getCurve()); X9ECParameters ecP = new X9ECParameters( curve, EC5Util.convertPoint(curve, ecSpec.getGenerator(), withCompression), ecSpec.getOrder(), BigInteger.valueOf(ecSpec.getCofactor()), ecSpec.getCurve().getSeed()); params = new X962Parameters(ecP); } } BigInteger bX = this.q.getX().toBigInteger(); BigInteger bY = this.q.getY().toBigInteger(); byte[] encKey = new byte[64]; extractBytes(encKey, 0, bX); extractBytes(encKey, 32, bY); try { info = new SubjectPublicKeyInfo(new AlgorithmIdentifier(CryptoProObjectIdentifiers.gostR3410_2001, params), new DEROctetString(encKey)); } catch (IOException e) { return null; } } else { if (ecSpec instanceof ECNamedCurveSpec) { ASN1ObjectIdentifier curveOid = ECUtil.getNamedCurveOid(((ECNamedCurveSpec)ecSpec).getName()); if (curveOid == null) { curveOid = new ASN1ObjectIdentifier(((ECNamedCurveSpec)ecSpec).getName()); } params = new X962Parameters(curveOid); } else if (ecSpec == null) { params = new X962Parameters(DERNull.INSTANCE); } else { ECCurve curve = EC5Util.convertCurve(ecSpec.getCurve()); X9ECParameters ecP = new X9ECParameters( curve, EC5Util.convertPoint(curve, ecSpec.getGenerator(), withCompression), ecSpec.getOrder(), BigInteger.valueOf(ecSpec.getCofactor()), ecSpec.getCurve().getSeed()); params = new X962Parameters(ecP); } ECCurve curve = this.engineGetQ().getCurve(); ASN1OctetString p = (ASN1OctetString) new X9ECPoint(curve.createPoint(this.getQ().getX().toBigInteger(), this.getQ().getY().toBigInteger(), withCompression)).toASN1Primitive(); info = new SubjectPublicKeyInfo(new AlgorithmIdentifier(X9ObjectIdentifiers.id_ecPublicKey, params), p.getOctets()); } return KeyUtil.getEncodedSubjectPublicKeyInfo(info); } private void extractBytes(byte[] encKey, int offSet, BigInteger bI) { byte[] val = bI.toByteArray(); if (val.length < 32) { byte[] tmp = new byte[32]; System.arraycopy(val, 0, tmp, tmp.length - val.length, val.length); val = tmp; } for (int i = 0; i != 32; i++) { encKey[offSet + i] = val[val.length - 1 - i]; } } public ECParameterSpec getParams() { return ecSpec; } public org.bouncycastle.jce.spec.ECParameterSpec getParameters() { if (ecSpec == null) // implictlyCA { return null; } return EC5Util.convertSpec(ecSpec, withCompression); } public ECPoint getW() { return new ECPoint(q.getX().toBigInteger(), q.getY().toBigInteger()); } public org.bouncycastle.math.ec.ECPoint getQ() { if (ecSpec == null) { if (q instanceof org.bouncycastle.math.ec.ECPoint.Fp) { return new org.bouncycastle.math.ec.ECPoint.Fp(null, q.getX(), q.getY()); } else { return new org.bouncycastle.math.ec.ECPoint.F2m(null, q.getX(), q.getY()); } } return q; } public org.bouncycastle.math.ec.ECPoint engineGetQ() { return q; } org.bouncycastle.jce.spec.ECParameterSpec engineGetSpec() { if (ecSpec != null) { return EC5Util.convertSpec(ecSpec, withCompression); } return BouncyCastleProvider.CONFIGURATION.getEcImplicitlyCa(); } public String toString() { StringBuffer buf = new StringBuffer(); String nl = System.getProperty("line.separator"); buf.append("EC Public Key").append(nl); buf.append(" X: ").append(this.q.getX().toBigInteger().toString(16)).append(nl); buf.append(" Y: ").append(this.q.getY().toBigInteger().toString(16)).append(nl); return buf.toString(); } public void setPointFormat(String style) { withCompression = !("UNCOMPRESSED".equalsIgnoreCase(style)); } public boolean equals(Object o) { if (!(o instanceof JCEECPublicKey)) { return false; } JCEECPublicKey other = (JCEECPublicKey)o; return engineGetQ().equals(other.engineGetQ()) && (engineGetSpec().equals(other.engineGetSpec())); } public int hashCode() { return engineGetQ().hashCode() ^ engineGetSpec().hashCode(); } private void readObject( ObjectInputStream in) throws IOException, ClassNotFoundException { byte[] enc = (byte[])in.readObject(); populateFromPubKeyInfo(SubjectPublicKeyInfo.getInstance(ASN1Primitive.fromByteArray(enc))); this.algorithm = (String)in.readObject(); this.withCompression = in.readBoolean(); } private void writeObject( ObjectOutputStream out) throws IOException { out.writeObject(this.getEncoded()); out.writeObject(algorithm); out.writeBoolean(withCompression); } } bouncycastle-1.49.orig/src/org/bouncycastle/jce/provider/PKIXCertPathBuilderSpi.java0000644000175000017500000002173211624640052030136 0ustar ebourgebourgpackage org.bouncycastle.jce.provider; import java.security.InvalidAlgorithmParameterException; import java.security.cert.CertPath; import java.security.cert.CertPathBuilderException; import java.security.cert.CertPathBuilderResult; import java.security.cert.CertPathBuilderSpi; import java.security.cert.CertPathParameters; import java.security.cert.CertPathValidator; import java.security.cert.CertificateFactory; import java.security.cert.CertificateParsingException; import java.security.cert.PKIXBuilderParameters; import java.security.cert.PKIXCertPathBuilderResult; import java.security.cert.PKIXCertPathValidatorResult; import java.security.cert.X509Certificate; import java.util.ArrayList; import java.util.Collection; import java.util.HashSet; import java.util.Iterator; import java.util.List; import org.bouncycastle.jce.exception.ExtCertPathBuilderException; import org.bouncycastle.util.Selector; import org.bouncycastle.x509.ExtendedPKIXBuilderParameters; import org.bouncycastle.x509.X509CertStoreSelector; /** * Implements the PKIX CertPathBuilding algorithm for BouncyCastle. * * @see CertPathBuilderSpi */ public class PKIXCertPathBuilderSpi extends CertPathBuilderSpi { /** * Build and validate a CertPath using the given parameter. * * @param params PKIXBuilderParameters object containing all information to * build the CertPath */ public CertPathBuilderResult engineBuild(CertPathParameters params) throws CertPathBuilderException, InvalidAlgorithmParameterException { if (!(params instanceof PKIXBuilderParameters) && !(params instanceof ExtendedPKIXBuilderParameters)) { throw new InvalidAlgorithmParameterException( "Parameters must be an instance of " + PKIXBuilderParameters.class.getName() + " or " + ExtendedPKIXBuilderParameters.class.getName() + "."); } ExtendedPKIXBuilderParameters pkixParams = null; if (params instanceof ExtendedPKIXBuilderParameters) { pkixParams = (ExtendedPKIXBuilderParameters) params; } else { pkixParams = (ExtendedPKIXBuilderParameters) ExtendedPKIXBuilderParameters .getInstance((PKIXBuilderParameters) params); } Collection targets; Iterator targetIter; List certPathList = new ArrayList(); X509Certificate cert; // search target certificates Selector certSelect = pkixParams.getTargetConstraints(); if (!(certSelect instanceof X509CertStoreSelector)) { throw new CertPathBuilderException( "TargetConstraints must be an instance of " + X509CertStoreSelector.class.getName() + " for " + this.getClass().getName() + " class."); } try { targets = CertPathValidatorUtilities.findCertificates((X509CertStoreSelector)certSelect, pkixParams.getStores()); targets.addAll(CertPathValidatorUtilities.findCertificates((X509CertStoreSelector)certSelect, pkixParams.getCertStores())); } catch (AnnotatedException e) { throw new ExtCertPathBuilderException( "Error finding target certificate.", e); } if (targets.isEmpty()) { throw new CertPathBuilderException( "No certificate found matching targetContraints."); } CertPathBuilderResult result = null; // check all potential target certificates targetIter = targets.iterator(); while (targetIter.hasNext() && result == null) { cert = (X509Certificate) targetIter.next(); result = build(cert, pkixParams, certPathList); } if (result == null && certPathException != null) { if (certPathException instanceof AnnotatedException) { throw new CertPathBuilderException(certPathException.getMessage(), certPathException.getCause()); } throw new CertPathBuilderException( "Possible certificate chain could not be validated.", certPathException); } if (result == null && certPathException == null) { throw new CertPathBuilderException( "Unable to find certificate chain."); } return result; } private Exception certPathException; protected CertPathBuilderResult build(X509Certificate tbvCert, ExtendedPKIXBuilderParameters pkixParams, List tbvPath) { // If tbvCert is readily present in tbvPath, it indicates having run // into a cycle in the // PKI graph. if (tbvPath.contains(tbvCert)) { return null; } // step out, the certificate is not allowed to appear in a certification // chain. if (pkixParams.getExcludedCerts().contains(tbvCert)) { return null; } // test if certificate path exceeds maximum length if (pkixParams.getMaxPathLength() != -1) { if (tbvPath.size() - 1 > pkixParams.getMaxPathLength()) { return null; } } tbvPath.add(tbvCert); CertificateFactory cFact; CertPathValidator validator; CertPathBuilderResult builderResult = null; try { cFact = CertificateFactory.getInstance("X.509", BouncyCastleProvider.PROVIDER_NAME); validator = CertPathValidator.getInstance("PKIX", BouncyCastleProvider.PROVIDER_NAME); } catch (Exception e) { // cannot happen throw new RuntimeException("Exception creating support classes."); } try { // check whether the issuer of is a TrustAnchor if (CertPathValidatorUtilities.findTrustAnchor(tbvCert, pkixParams.getTrustAnchors(), pkixParams.getSigProvider()) != null) { // exception message from possibly later tried certification // chains CertPath certPath = null; PKIXCertPathValidatorResult result = null; try { certPath = cFact.generateCertPath(tbvPath); } catch (Exception e) { throw new AnnotatedException( "Certification path could not be constructed from certificate list.", e); } try { result = (PKIXCertPathValidatorResult) validator.validate( certPath, pkixParams); } catch (Exception e) { throw new AnnotatedException( "Certification path could not be validated.", e); } return new PKIXCertPathBuilderResult(certPath, result .getTrustAnchor(), result.getPolicyTree(), result .getPublicKey()); } else { // add additional X.509 stores from locations in certificate try { CertPathValidatorUtilities.addAdditionalStoresFromAltNames( tbvCert, pkixParams); } catch (CertificateParsingException e) { throw new AnnotatedException( "No additiontal X.509 stores can be added from certificate locations.", e); } Collection issuers = new HashSet(); // try to get the issuer certificate from one // of the stores try { issuers.addAll(CertPathValidatorUtilities.findIssuerCerts(tbvCert, pkixParams)); } catch (AnnotatedException e) { throw new AnnotatedException( "Cannot find issuer certificate for certificate in certification path.", e); } if (issuers.isEmpty()) { throw new AnnotatedException( "No issuer certificate for certificate in certification path found."); } Iterator it = issuers.iterator(); while (it.hasNext() && builderResult == null) { X509Certificate issuer = (X509Certificate) it.next(); builderResult = build(issuer, pkixParams, tbvPath); } } } catch (AnnotatedException e) { certPathException = e; } if (builderResult == null) { tbvPath.remove(tbvCert); } return builderResult; } } bouncycastle-1.49.orig/src/org/bouncycastle/jce/provider/JCEElGamalPrivateKey.java0000644000175000017500000001132011736773417027605 0ustar ebourgebourgpackage org.bouncycastle.jce.provider; import java.io.IOException; import java.io.ObjectInputStream; import java.io.ObjectOutputStream; import java.math.BigInteger; import java.util.Enumeration; import javax.crypto.interfaces.DHPrivateKey; import javax.crypto.spec.DHParameterSpec; import javax.crypto.spec.DHPrivateKeySpec; import org.bouncycastle.asn1.ASN1Encodable; import org.bouncycastle.asn1.ASN1Integer; import org.bouncycastle.asn1.ASN1ObjectIdentifier; import org.bouncycastle.asn1.ASN1Sequence; import org.bouncycastle.asn1.DERInteger; import org.bouncycastle.asn1.oiw.ElGamalParameter; import org.bouncycastle.asn1.oiw.OIWObjectIdentifiers; import org.bouncycastle.asn1.pkcs.PrivateKeyInfo; import org.bouncycastle.asn1.x509.AlgorithmIdentifier; import org.bouncycastle.crypto.params.ElGamalPrivateKeyParameters; import org.bouncycastle.jcajce.provider.asymmetric.util.KeyUtil; import org.bouncycastle.jcajce.provider.asymmetric.util.PKCS12BagAttributeCarrierImpl; import org.bouncycastle.jce.interfaces.ElGamalPrivateKey; import org.bouncycastle.jce.interfaces.PKCS12BagAttributeCarrier; import org.bouncycastle.jce.spec.ElGamalParameterSpec; import org.bouncycastle.jce.spec.ElGamalPrivateKeySpec; public class JCEElGamalPrivateKey implements ElGamalPrivateKey, DHPrivateKey, PKCS12BagAttributeCarrier { static final long serialVersionUID = 4819350091141529678L; BigInteger x; ElGamalParameterSpec elSpec; private PKCS12BagAttributeCarrierImpl attrCarrier = new PKCS12BagAttributeCarrierImpl(); protected JCEElGamalPrivateKey() { } JCEElGamalPrivateKey( ElGamalPrivateKey key) { this.x = key.getX(); this.elSpec = key.getParameters(); } JCEElGamalPrivateKey( DHPrivateKey key) { this.x = key.getX(); this.elSpec = new ElGamalParameterSpec(key.getParams().getP(), key.getParams().getG()); } JCEElGamalPrivateKey( ElGamalPrivateKeySpec spec) { this.x = spec.getX(); this.elSpec = new ElGamalParameterSpec(spec.getParams().getP(), spec.getParams().getG()); } JCEElGamalPrivateKey( DHPrivateKeySpec spec) { this.x = spec.getX(); this.elSpec = new ElGamalParameterSpec(spec.getP(), spec.getG()); } JCEElGamalPrivateKey( PrivateKeyInfo info) throws IOException { ElGamalParameter params = new ElGamalParameter((ASN1Sequence)info.getAlgorithmId().getParameters()); DERInteger derX = ASN1Integer.getInstance(info.parsePrivateKey()); this.x = derX.getValue(); this.elSpec = new ElGamalParameterSpec(params.getP(), params.getG()); } JCEElGamalPrivateKey( ElGamalPrivateKeyParameters params) { this.x = params.getX(); this.elSpec = new ElGamalParameterSpec(params.getParameters().getP(), params.getParameters().getG()); } public String getAlgorithm() { return "ElGamal"; } /** * return the encoding format we produce in getEncoded(). * * @return the string "PKCS#8" */ public String getFormat() { return "PKCS#8"; } /** * Return a PKCS8 representation of the key. The sequence returned * represents a full PrivateKeyInfo object. * * @return a PKCS8 representation of the key. */ public byte[] getEncoded() { return KeyUtil.getEncodedPrivateKeyInfo(new AlgorithmIdentifier(OIWObjectIdentifiers.elGamalAlgorithm, new ElGamalParameter(elSpec.getP(), elSpec.getG())), new DERInteger(getX())); } public ElGamalParameterSpec getParameters() { return elSpec; } public DHParameterSpec getParams() { return new DHParameterSpec(elSpec.getP(), elSpec.getG()); } public BigInteger getX() { return x; } private void readObject( ObjectInputStream in) throws IOException, ClassNotFoundException { x = (BigInteger)in.readObject(); this.elSpec = new ElGamalParameterSpec((BigInteger)in.readObject(), (BigInteger)in.readObject()); } private void writeObject( ObjectOutputStream out) throws IOException { out.writeObject(this.getX()); out.writeObject(elSpec.getP()); out.writeObject(elSpec.getG()); } public void setBagAttribute( ASN1ObjectIdentifier oid, ASN1Encodable attribute) { attrCarrier.setBagAttribute(oid, attribute); } public ASN1Encodable getBagAttribute( ASN1ObjectIdentifier oid) { return attrCarrier.getBagAttribute(oid); } public Enumeration getBagAttributeKeys() { return attrCarrier.getBagAttributeKeys(); } } bouncycastle-1.49.orig/src/org/bouncycastle/jce/provider/PEMUtil.java0000644000175000017500000000425611625075651025236 0ustar ebourgebourgpackage org.bouncycastle.jce.provider; import java.io.IOException; import java.io.InputStream; import org.bouncycastle.asn1.ASN1InputStream; import org.bouncycastle.asn1.ASN1Primitive; import org.bouncycastle.asn1.ASN1Sequence; import org.bouncycastle.util.encoders.Base64; public class PEMUtil { private final String _header1; private final String _header2; private final String _footer1; private final String _footer2; PEMUtil( String type) { _header1 = "-----BEGIN " + type + "-----"; _header2 = "-----BEGIN X509 " + type + "-----"; _footer1 = "-----END " + type + "-----"; _footer2 = "-----END X509 " + type + "-----"; } private String readLine( InputStream in) throws IOException { int c; StringBuffer l = new StringBuffer(); do { while (((c = in.read()) != '\r') && c != '\n' && (c >= 0)) { if (c == '\r') { continue; } l.append((char)c); } } while (c >= 0 && l.length() == 0); if (c < 0) { return null; } return l.toString(); } ASN1Sequence readPEMObject( InputStream in) throws IOException { String line; StringBuffer pemBuf = new StringBuffer(); while ((line = readLine(in)) != null) { if (line.startsWith(_header1) || line.startsWith(_header2)) { break; } } while ((line = readLine(in)) != null) { if (line.startsWith(_footer1) || line.startsWith(_footer2)) { break; } pemBuf.append(line); } if (pemBuf.length() != 0) { ASN1Primitive o = new ASN1InputStream(Base64.decode(pemBuf.toString())).readObject(); if (!(o instanceof ASN1Sequence)) { throw new IOException("malformed PEM data encountered"); } return (ASN1Sequence)o; } return null; } } bouncycastle-1.49.orig/src/org/bouncycastle/jce/provider/X509StoreAttrCertCollection.java0000644000175000017500000000160311624652565031123 0ustar ebourgebourgpackage org.bouncycastle.jce.provider; import java.util.Collection; import org.bouncycastle.util.CollectionStore; import org.bouncycastle.util.Selector; import org.bouncycastle.x509.X509CollectionStoreParameters; import org.bouncycastle.x509.X509StoreParameters; import org.bouncycastle.x509.X509StoreSpi; public class X509StoreAttrCertCollection extends X509StoreSpi { private CollectionStore _store; public X509StoreAttrCertCollection() { } public void engineInit(X509StoreParameters params) { if (!(params instanceof X509CollectionStoreParameters)) { throw new IllegalArgumentException(params.toString()); } _store = new CollectionStore(((X509CollectionStoreParameters)params).getCollection()); } public Collection engineGetMatches(Selector selector) { return _store.getMatches(selector); } } bouncycastle-1.49.orig/src/org/bouncycastle/jce/provider/JCEDHPublicKey.java0000644000175000017500000001157111625105237026374 0ustar ebourgebourgpackage org.bouncycastle.jce.provider; import java.io.IOException; import java.io.ObjectInputStream; import java.io.ObjectOutputStream; import java.math.BigInteger; import javax.crypto.interfaces.DHPublicKey; import javax.crypto.spec.DHParameterSpec; import javax.crypto.spec.DHPublicKeySpec; import org.bouncycastle.asn1.ASN1Sequence; import org.bouncycastle.asn1.DERInteger; import org.bouncycastle.asn1.DERObjectIdentifier; import org.bouncycastle.asn1.pkcs.DHParameter; import org.bouncycastle.asn1.pkcs.PKCSObjectIdentifiers; import org.bouncycastle.asn1.x509.AlgorithmIdentifier; import org.bouncycastle.asn1.x509.SubjectPublicKeyInfo; import org.bouncycastle.asn1.x9.DHDomainParameters; import org.bouncycastle.asn1.x9.X9ObjectIdentifiers; import org.bouncycastle.crypto.params.DHPublicKeyParameters; import org.bouncycastle.jcajce.provider.asymmetric.util.KeyUtil; public class JCEDHPublicKey implements DHPublicKey { static final long serialVersionUID = -216691575254424324L; private BigInteger y; private DHParameterSpec dhSpec; private SubjectPublicKeyInfo info; JCEDHPublicKey( DHPublicKeySpec spec) { this.y = spec.getY(); this.dhSpec = new DHParameterSpec(spec.getP(), spec.getG()); } JCEDHPublicKey( DHPublicKey key) { this.y = key.getY(); this.dhSpec = key.getParams(); } JCEDHPublicKey( DHPublicKeyParameters params) { this.y = params.getY(); this.dhSpec = new DHParameterSpec(params.getParameters().getP(), params.getParameters().getG(), params.getParameters().getL()); } JCEDHPublicKey( BigInteger y, DHParameterSpec dhSpec) { this.y = y; this.dhSpec = dhSpec; } JCEDHPublicKey( SubjectPublicKeyInfo info) { this.info = info; DERInteger derY; try { derY = (DERInteger)info.parsePublicKey(); } catch (IOException e) { throw new IllegalArgumentException("invalid info structure in DH public key"); } this.y = derY.getValue(); ASN1Sequence seq = ASN1Sequence.getInstance(info.getAlgorithmId().getParameters()); DERObjectIdentifier id = info.getAlgorithmId().getAlgorithm(); // we need the PKCS check to handle older keys marked with the X9 oid. if (id.equals(PKCSObjectIdentifiers.dhKeyAgreement) || isPKCSParam(seq)) { DHParameter params = DHParameter.getInstance(seq); if (params.getL() != null) { this.dhSpec = new DHParameterSpec(params.getP(), params.getG(), params.getL().intValue()); } else { this.dhSpec = new DHParameterSpec(params.getP(), params.getG()); } } else if (id.equals(X9ObjectIdentifiers.dhpublicnumber)) { DHDomainParameters params = DHDomainParameters.getInstance(seq); this.dhSpec = new DHParameterSpec(params.getP().getValue(), params.getG().getValue()); } else { throw new IllegalArgumentException("unknown algorithm type: " + id); } } public String getAlgorithm() { return "DH"; } public String getFormat() { return "X.509"; } public byte[] getEncoded() { if (info != null) { return KeyUtil.getEncodedSubjectPublicKeyInfo(info); } return KeyUtil.getEncodedSubjectPublicKeyInfo(new AlgorithmIdentifier(PKCSObjectIdentifiers.dhKeyAgreement, new DHParameter(dhSpec.getP(), dhSpec.getG(), dhSpec.getL())), new DERInteger(y)); } public DHParameterSpec getParams() { return dhSpec; } public BigInteger getY() { return y; } private boolean isPKCSParam(ASN1Sequence seq) { if (seq.size() == 2) { return true; } if (seq.size() > 3) { return false; } DERInteger l = DERInteger.getInstance(seq.getObjectAt(2)); DERInteger p = DERInteger.getInstance(seq.getObjectAt(0)); if (l.getValue().compareTo(BigInteger.valueOf(p.getValue().bitLength())) > 0) { return false; } return true; } private void readObject( ObjectInputStream in) throws IOException, ClassNotFoundException { this.y = (BigInteger)in.readObject(); this.dhSpec = new DHParameterSpec((BigInteger)in.readObject(), (BigInteger)in.readObject(), in.readInt()); } private void writeObject( ObjectOutputStream out) throws IOException { out.writeObject(this.getY()); out.writeObject(dhSpec.getP()); out.writeObject(dhSpec.getG()); out.writeInt(dhSpec.getL()); } } bouncycastle-1.49.orig/src/org/bouncycastle/jce/provider/JDKDSAPublicKey.java0000644000175000017500000001151712101612645026513 0ustar ebourgebourgpackage org.bouncycastle.jce.provider; import java.io.IOException; import java.io.ObjectInputStream; import java.io.ObjectOutputStream; import java.math.BigInteger; import java.security.interfaces.DSAParams; import java.security.interfaces.DSAPublicKey; import java.security.spec.DSAParameterSpec; import java.security.spec.DSAPublicKeySpec; import org.bouncycastle.asn1.ASN1Encodable; import org.bouncycastle.asn1.ASN1Encoding; import org.bouncycastle.asn1.ASN1Sequence; import org.bouncycastle.asn1.DERInteger; import org.bouncycastle.asn1.DERNull; import org.bouncycastle.asn1.x509.AlgorithmIdentifier; import org.bouncycastle.asn1.x509.DSAParameter; import org.bouncycastle.asn1.x509.SubjectPublicKeyInfo; import org.bouncycastle.asn1.x9.X9ObjectIdentifiers; import org.bouncycastle.crypto.params.DSAPublicKeyParameters; public class JDKDSAPublicKey implements DSAPublicKey { private static final long serialVersionUID = 1752452449903495175L; private BigInteger y; private DSAParams dsaSpec; JDKDSAPublicKey( DSAPublicKeySpec spec) { this.y = spec.getY(); this.dsaSpec = new DSAParameterSpec(spec.getP(), spec.getQ(), spec.getG()); } JDKDSAPublicKey( DSAPublicKey key) { this.y = key.getY(); this.dsaSpec = key.getParams(); } JDKDSAPublicKey( DSAPublicKeyParameters params) { this.y = params.getY(); this.dsaSpec = new DSAParameterSpec(params.getParameters().getP(), params.getParameters().getQ(), params.getParameters().getG()); } JDKDSAPublicKey( BigInteger y, DSAParameterSpec dsaSpec) { this.y = y; this.dsaSpec = dsaSpec; } JDKDSAPublicKey( SubjectPublicKeyInfo info) { DERInteger derY; try { derY = (DERInteger)info.parsePublicKey(); } catch (IOException e) { throw new IllegalArgumentException("invalid info structure in DSA public key"); } this.y = derY.getValue(); if (isNotNull(info.getAlgorithm().getParameters())) { DSAParameter params = DSAParameter.getInstance(info.getAlgorithm().getParameters()); this.dsaSpec = new DSAParameterSpec(params.getP(), params.getQ(), params.getG()); } } private boolean isNotNull(ASN1Encodable parameters) { return parameters != null && !DERNull.INSTANCE.equals(parameters); } public String getAlgorithm() { return "DSA"; } public String getFormat() { return "X.509"; } public byte[] getEncoded() { try { if (dsaSpec == null) { return new SubjectPublicKeyInfo(new AlgorithmIdentifier(X9ObjectIdentifiers.id_dsa), new DERInteger(y)).getEncoded(ASN1Encoding.DER); } return new SubjectPublicKeyInfo(new AlgorithmIdentifier(X9ObjectIdentifiers.id_dsa, new DSAParameter(dsaSpec.getP(), dsaSpec.getQ(), dsaSpec.getG())), new DERInteger(y)).getEncoded(ASN1Encoding.DER); } catch (IOException e) { return null; } } public DSAParams getParams() { return dsaSpec; } public BigInteger getY() { return y; } public String toString() { StringBuffer buf = new StringBuffer(); String nl = System.getProperty("line.separator"); buf.append("DSA Public Key").append(nl); buf.append(" y: ").append(this.getY().toString(16)).append(nl); return buf.toString(); } public int hashCode() { return this.getY().hashCode() ^ this.getParams().getG().hashCode() ^ this.getParams().getP().hashCode() ^ this.getParams().getQ().hashCode(); } public boolean equals( Object o) { if (!(o instanceof DSAPublicKey)) { return false; } DSAPublicKey other = (DSAPublicKey)o; return this.getY().equals(other.getY()) && this.getParams().getG().equals(other.getParams().getG()) && this.getParams().getP().equals(other.getParams().getP()) && this.getParams().getQ().equals(other.getParams().getQ()); } private void readObject( ObjectInputStream in) throws IOException, ClassNotFoundException { this.y = (BigInteger)in.readObject(); this.dsaSpec = new DSAParameterSpec((BigInteger)in.readObject(), (BigInteger)in.readObject(), (BigInteger)in.readObject()); } private void writeObject( ObjectOutputStream out) throws IOException { out.writeObject(y); out.writeObject(dsaSpec.getP()); out.writeObject(dsaSpec.getQ()); out.writeObject(dsaSpec.getG()); } } bouncycastle-1.49.orig/src/org/bouncycastle/jce/provider/X509AttrCertParser.java0000644000175000017500000001037211701453646027245 0ustar ebourgebourgpackage org.bouncycastle.jce.provider; import java.io.BufferedInputStream; import java.io.IOException; import java.io.InputStream; import java.util.ArrayList; import java.util.Collection; import java.util.List; import org.bouncycastle.asn1.ASN1InputStream; import org.bouncycastle.asn1.ASN1Sequence; import org.bouncycastle.asn1.ASN1Set; import org.bouncycastle.asn1.ASN1TaggedObject; import org.bouncycastle.asn1.DERObjectIdentifier; import org.bouncycastle.asn1.pkcs.PKCSObjectIdentifiers; import org.bouncycastle.asn1.pkcs.SignedData; import org.bouncycastle.x509.X509AttributeCertificate; import org.bouncycastle.x509.X509StreamParserSpi; import org.bouncycastle.x509.X509V2AttributeCertificate; import org.bouncycastle.x509.util.StreamParsingException; public class X509AttrCertParser extends X509StreamParserSpi { private static final PEMUtil PEM_PARSER = new PEMUtil("ATTRIBUTE CERTIFICATE"); private ASN1Set sData = null; private int sDataObjectCount = 0; private InputStream currentStream = null; private X509AttributeCertificate readDERCertificate( InputStream in) throws IOException { ASN1InputStream dIn = new ASN1InputStream(in); ASN1Sequence seq = (ASN1Sequence)dIn.readObject(); if (seq.size() > 1 && seq.getObjectAt(0) instanceof DERObjectIdentifier) { if (seq.getObjectAt(0).equals(PKCSObjectIdentifiers.signedData)) { sData = new SignedData(ASN1Sequence.getInstance( (ASN1TaggedObject)seq.getObjectAt(1), true)).getCertificates(); return getCertificate(); } } return new X509V2AttributeCertificate(seq.getEncoded()); } private X509AttributeCertificate getCertificate() throws IOException { if (sData != null) { while (sDataObjectCount < sData.size()) { Object obj = sData.getObjectAt(sDataObjectCount++); if (obj instanceof ASN1TaggedObject && ((ASN1TaggedObject)obj).getTagNo() == 2) { return new X509V2AttributeCertificate( ASN1Sequence.getInstance((ASN1TaggedObject)obj, false).getEncoded()); } } } return null; } private X509AttributeCertificate readPEMCertificate( InputStream in) throws IOException { ASN1Sequence seq = PEM_PARSER.readPEMObject(in); if (seq != null) { return new X509V2AttributeCertificate(seq.getEncoded()); } return null; } public void engineInit(InputStream in) { currentStream = in; sData = null; sDataObjectCount = 0; if (!currentStream.markSupported()) { currentStream = new BufferedInputStream(currentStream); } } public Object engineRead() throws StreamParsingException { try { if (sData != null) { if (sDataObjectCount != sData.size()) { return getCertificate(); } else { sData = null; sDataObjectCount = 0; return null; } } currentStream.mark(10); int tag = currentStream.read(); if (tag == -1) { return null; } if (tag != 0x30) // assume ascii PEM encoded. { currentStream.reset(); return readPEMCertificate(currentStream); } else { currentStream.reset(); return readDERCertificate(currentStream); } } catch (Exception e) { throw new StreamParsingException(e.toString(), e); } } public Collection engineReadAll() throws StreamParsingException { X509AttributeCertificate cert; List certs = new ArrayList(); while ((cert = (X509AttributeCertificate)engineRead()) != null) { certs.add(cert); } return certs; } } bouncycastle-1.49.orig/src/org/bouncycastle/jce/provider/PKIXAttrCertPathBuilderSpi.java0000644000175000017500000002612711624640052030774 0ustar ebourgebourgpackage org.bouncycastle.jce.provider; import java.io.IOException; import java.security.InvalidAlgorithmParameterException; import java.security.Principal; import java.security.cert.CertPath; import java.security.cert.CertPathBuilderException; import java.security.cert.CertPathBuilderResult; import java.security.cert.CertPathBuilderSpi; import java.security.cert.CertPathParameters; import java.security.cert.CertPathValidator; import java.security.cert.CertificateFactory; import java.security.cert.CertificateParsingException; import java.security.cert.PKIXBuilderParameters; import java.security.cert.PKIXCertPathBuilderResult; import java.security.cert.PKIXCertPathValidatorResult; import java.security.cert.X509Certificate; import java.util.ArrayList; import java.util.Collection; import java.util.HashSet; import java.util.Iterator; import java.util.List; import java.util.Set; import javax.security.auth.x500.X500Principal; import org.bouncycastle.jce.exception.ExtCertPathBuilderException; import org.bouncycastle.util.Selector; import org.bouncycastle.x509.ExtendedPKIXBuilderParameters; import org.bouncycastle.x509.X509AttributeCertStoreSelector; import org.bouncycastle.x509.X509AttributeCertificate; import org.bouncycastle.x509.X509CertStoreSelector; public class PKIXAttrCertPathBuilderSpi extends CertPathBuilderSpi { /** * Build and validate a CertPath using the given parameter. * * @param params PKIXBuilderParameters object containing all information to * build the CertPath */ public CertPathBuilderResult engineBuild(CertPathParameters params) throws CertPathBuilderException, InvalidAlgorithmParameterException { if (!(params instanceof PKIXBuilderParameters) && !(params instanceof ExtendedPKIXBuilderParameters)) { throw new InvalidAlgorithmParameterException( "Parameters must be an instance of " + PKIXBuilderParameters.class.getName() + " or " + ExtendedPKIXBuilderParameters.class.getName() + "."); } ExtendedPKIXBuilderParameters pkixParams; if (params instanceof ExtendedPKIXBuilderParameters) { pkixParams = (ExtendedPKIXBuilderParameters) params; } else { pkixParams = (ExtendedPKIXBuilderParameters) ExtendedPKIXBuilderParameters .getInstance((PKIXBuilderParameters) params); } Collection targets; Iterator targetIter; List certPathList = new ArrayList(); X509AttributeCertificate cert; // search target certificates Selector certSelect = pkixParams.getTargetConstraints(); if (!(certSelect instanceof X509AttributeCertStoreSelector)) { throw new CertPathBuilderException( "TargetConstraints must be an instance of " + X509AttributeCertStoreSelector.class.getName() + " for "+this.getClass().getName()+" class."); } try { targets = CertPathValidatorUtilities.findCertificates((X509AttributeCertStoreSelector)certSelect, pkixParams.getStores()); } catch (AnnotatedException e) { throw new ExtCertPathBuilderException("Error finding target attribute certificate.", e); } if (targets.isEmpty()) { throw new CertPathBuilderException( "No attribute certificate found matching targetContraints."); } CertPathBuilderResult result = null; // check all potential target certificates targetIter = targets.iterator(); while (targetIter.hasNext() && result == null) { cert = (X509AttributeCertificate) targetIter.next(); X509CertStoreSelector selector = new X509CertStoreSelector(); Principal[] principals = cert.getIssuer().getPrincipals(); Set issuers = new HashSet(); for (int i = 0; i < principals.length; i++) { try { if (principals[i] instanceof X500Principal) { selector.setSubject(((X500Principal)principals[i]).getEncoded()); } issuers.addAll(CertPathValidatorUtilities.findCertificates(selector, pkixParams.getStores())); issuers.addAll(CertPathValidatorUtilities.findCertificates(selector, pkixParams.getCertStores())); } catch (AnnotatedException e) { throw new ExtCertPathBuilderException( "Public key certificate for attribute certificate cannot be searched.", e); } catch (IOException e) { throw new ExtCertPathBuilderException( "cannot encode X500Principal.", e); } } if (issuers.isEmpty()) { throw new CertPathBuilderException( "Public key certificate for attribute certificate cannot be found."); } Iterator it = issuers.iterator(); while (it.hasNext() && result == null) { result = build(cert, (X509Certificate)it.next(), pkixParams, certPathList); } } if (result == null && certPathException != null) { throw new ExtCertPathBuilderException( "Possible certificate chain could not be validated.", certPathException); } if (result == null && certPathException == null) { throw new CertPathBuilderException( "Unable to find certificate chain."); } return result; } private Exception certPathException; private CertPathBuilderResult build(X509AttributeCertificate attrCert, X509Certificate tbvCert, ExtendedPKIXBuilderParameters pkixParams, List tbvPath) { // If tbvCert is readily present in tbvPath, it indicates having run // into a cycle in the // PKI graph. if (tbvPath.contains(tbvCert)) { return null; } // step out, the certificate is not allowed to appear in a certification // chain if (pkixParams.getExcludedCerts().contains(tbvCert)) { return null; } // test if certificate path exceeds maximum length if (pkixParams.getMaxPathLength() != -1) { if (tbvPath.size() - 1 > pkixParams.getMaxPathLength()) { return null; } } tbvPath.add(tbvCert); CertificateFactory cFact; CertPathValidator validator; CertPathBuilderResult builderResult = null; try { cFact = CertificateFactory.getInstance("X.509", BouncyCastleProvider.PROVIDER_NAME); validator = CertPathValidator.getInstance("RFC3281", BouncyCastleProvider.PROVIDER_NAME); } catch (Exception e) { // cannot happen throw new RuntimeException( "Exception creating support classes."); } try { // check whether the issuer of is a TrustAnchor if (CertPathValidatorUtilities.findTrustAnchor(tbvCert, pkixParams.getTrustAnchors(), pkixParams.getSigProvider()) != null) { CertPath certPath; PKIXCertPathValidatorResult result; try { certPath = cFact.generateCertPath(tbvPath); } catch (Exception e) { throw new AnnotatedException( "Certification path could not be constructed from certificate list.", e); } try { result = (PKIXCertPathValidatorResult) validator.validate( certPath, pkixParams); } catch (Exception e) { throw new AnnotatedException( "Certification path could not be validated.", e); } return new PKIXCertPathBuilderResult(certPath, result .getTrustAnchor(), result.getPolicyTree(), result .getPublicKey()); } else { // add additional X.509 stores from locations in certificate try { CertPathValidatorUtilities.addAdditionalStoresFromAltNames(tbvCert, pkixParams); } catch (CertificateParsingException e) { throw new AnnotatedException( "No additional X.509 stores can be added from certificate locations.", e); } Collection issuers = new HashSet(); // try to get the issuer certificate from one // of the stores try { issuers.addAll(CertPathValidatorUtilities.findIssuerCerts(tbvCert, pkixParams)); } catch (AnnotatedException e) { throw new AnnotatedException( "Cannot find issuer certificate for certificate in certification path.", e); } if (issuers.isEmpty()) { throw new AnnotatedException( "No issuer certificate for certificate in certification path found."); } Iterator it = issuers.iterator(); while (it.hasNext() && builderResult == null) { X509Certificate issuer = (X509Certificate) it.next(); // TODO Use CertPathValidatorUtilities.isSelfIssued(issuer)? // if untrusted self signed certificate continue if (issuer.getIssuerX500Principal().equals( issuer.getSubjectX500Principal())) { continue; } builderResult = build(attrCert, issuer, pkixParams, tbvPath); } } } catch (AnnotatedException e) { certPathException = new AnnotatedException( "No valid certification path could be build.", e); } if (builderResult == null) { tbvPath.remove(tbvCert); } return builderResult; } } bouncycastle-1.49.orig/src/org/bouncycastle/jce/provider/PKIXAttrCertPathValidatorSpi.java0000644000175000017500000001053011624652565031336 0ustar ebourgebourgpackage org.bouncycastle.jce.provider; import java.security.InvalidAlgorithmParameterException; import java.security.cert.CertPath; import java.security.cert.CertPathParameters; import java.security.cert.CertPathValidatorException; import java.security.cert.CertPathValidatorResult; import java.security.cert.CertPathValidatorSpi; import java.security.cert.X509Certificate; import java.util.Date; import java.util.Set; import org.bouncycastle.jce.exception.ExtCertPathValidatorException; import org.bouncycastle.util.Selector; import org.bouncycastle.x509.ExtendedPKIXParameters; import org.bouncycastle.x509.X509AttributeCertStoreSelector; import org.bouncycastle.x509.X509AttributeCertificate; /** * CertPathValidatorSpi implementation for X.509 Attribute Certificates la RFC 3281. * * @see org.bouncycastle.x509.ExtendedPKIXParameters */ public class PKIXAttrCertPathValidatorSpi extends CertPathValidatorSpi { /** * Validates an attribute certificate with the given certificate path. * *

    * params must be an instance of * ExtendedPKIXParameters. *

    * The target constraints in the params must be an * X509AttributeCertStoreSelector with at least the attribute * certificate criterion set. Obey that also target informations may be * necessary to correctly validate this attribute certificate. *

    * The attribute certificate issuer must be added to the trusted attribute * issuers with {@link ExtendedPKIXParameters#setTrustedACIssuers(Set)}. * * @param certPath The certificate path which belongs to the attribute * certificate issuer public key certificate. * @param params The PKIX parameters. * @return A PKIXCertPathValidatorResult of the result of * validating the certPath. * @throws InvalidAlgorithmParameterException if params is * inappropriate for this validator. * @throws CertPathValidatorException if the verification fails. */ public CertPathValidatorResult engineValidate(CertPath certPath, CertPathParameters params) throws CertPathValidatorException, InvalidAlgorithmParameterException { if (!(params instanceof ExtendedPKIXParameters)) { throw new InvalidAlgorithmParameterException( "Parameters must be a " + ExtendedPKIXParameters.class.getName() + " instance."); } ExtendedPKIXParameters pkixParams = (ExtendedPKIXParameters) params; Selector certSelect = pkixParams.getTargetConstraints(); if (!(certSelect instanceof X509AttributeCertStoreSelector)) { throw new InvalidAlgorithmParameterException( "TargetConstraints must be an instance of " + X509AttributeCertStoreSelector.class.getName() + " for " + this.getClass().getName() + " class."); } X509AttributeCertificate attrCert = ((X509AttributeCertStoreSelector) certSelect) .getAttributeCert(); CertPath holderCertPath = RFC3281CertPathUtilities.processAttrCert1(attrCert, pkixParams); CertPathValidatorResult result = RFC3281CertPathUtilities.processAttrCert2(certPath, pkixParams); X509Certificate issuerCert = (X509Certificate) certPath .getCertificates().get(0); RFC3281CertPathUtilities.processAttrCert3(issuerCert, pkixParams); RFC3281CertPathUtilities.processAttrCert4(issuerCert, pkixParams); RFC3281CertPathUtilities.processAttrCert5(attrCert, pkixParams); // 6 already done in X509AttributeCertStoreSelector RFC3281CertPathUtilities.processAttrCert7(attrCert, certPath, holderCertPath, pkixParams); RFC3281CertPathUtilities.additionalChecks(attrCert, pkixParams); Date date = null; try { date = CertPathValidatorUtilities .getValidCertDateFromValidityModel(pkixParams, null, -1); } catch (AnnotatedException e) { throw new ExtCertPathValidatorException( "Could not get validity date from attribute certificate.", e); } RFC3281CertPathUtilities.checkCRLs(attrCert, pkixParams, issuerCert, date, certPath.getCertificates()); return result; } } bouncycastle-1.49.orig/src/org/bouncycastle/jce/provider/AnnotatedException.java0000644000175000017500000000112311624640051027530 0ustar ebourgebourgpackage org.bouncycastle.jce.provider; import org.bouncycastle.jce.exception.ExtException; public class AnnotatedException extends Exception implements ExtException { private Throwable _underlyingException; AnnotatedException(String string, Throwable e) { super(string); _underlyingException = e; } AnnotatedException(String string) { this(string, null); } Throwable getUnderlyingException() { return _underlyingException; } public Throwable getCause() { return _underlyingException; } } bouncycastle-1.49.orig/src/org/bouncycastle/jce/PKCS10CertificationRequest.java0000644000175000017500000005765112103437526027105 0ustar ebourgebourgpackage org.bouncycastle.jce; import java.io.IOException; import java.security.AlgorithmParameters; import java.security.GeneralSecurityException; import java.security.InvalidKeyException; import java.security.KeyFactory; import java.security.NoSuchAlgorithmException; import java.security.NoSuchProviderException; import java.security.PrivateKey; import java.security.PublicKey; import java.security.Signature; import java.security.SignatureException; import java.security.spec.InvalidKeySpecException; import java.security.spec.PSSParameterSpec; import java.security.spec.X509EncodedKeySpec; import java.util.HashSet; import java.util.Hashtable; import java.util.Set; import javax.security.auth.x500.X500Principal; import org.bouncycastle.asn1.ASN1Encodable; import org.bouncycastle.asn1.ASN1Encoding; import org.bouncycastle.asn1.ASN1InputStream; import org.bouncycastle.asn1.ASN1Integer; import org.bouncycastle.asn1.ASN1Primitive; import org.bouncycastle.asn1.ASN1Sequence; import org.bouncycastle.asn1.ASN1Set; import org.bouncycastle.asn1.DERBitString; import org.bouncycastle.asn1.DERNull; import org.bouncycastle.asn1.DERObjectIdentifier; import org.bouncycastle.asn1.cryptopro.CryptoProObjectIdentifiers; import org.bouncycastle.asn1.nist.NISTObjectIdentifiers; import org.bouncycastle.asn1.oiw.OIWObjectIdentifiers; import org.bouncycastle.asn1.pkcs.CertificationRequest; import org.bouncycastle.asn1.pkcs.CertificationRequestInfo; import org.bouncycastle.asn1.pkcs.PKCSObjectIdentifiers; import org.bouncycastle.asn1.pkcs.RSASSAPSSparams; import org.bouncycastle.asn1.teletrust.TeleTrusTObjectIdentifiers; import org.bouncycastle.asn1.x509.AlgorithmIdentifier; import org.bouncycastle.asn1.x509.SubjectPublicKeyInfo; import org.bouncycastle.asn1.x509.X509Name; import org.bouncycastle.asn1.x9.X9ObjectIdentifiers; import org.bouncycastle.jce.provider.BouncyCastleProvider; import org.bouncycastle.util.Strings; /** * A class for verifying and creating PKCS10 Certification requests. *

     * CertificationRequest ::= SEQUENCE {
     *   certificationRequestInfo  CertificationRequestInfo,
     *   signatureAlgorithm        AlgorithmIdentifier{{ SignatureAlgorithms }},
     *   signature                 BIT STRING
     * }
     *
     * CertificationRequestInfo ::= SEQUENCE {
     *   version             INTEGER { v1(0) } (v1,...),
     *   subject             Name,
     *   subjectPKInfo   SubjectPublicKeyInfo{{ PKInfoAlgorithms }},
     *   attributes          [0] Attributes{{ CRIAttributes }}
     *  }
     *
     *  Attributes { ATTRIBUTE:IOSet } ::= SET OF Attribute{{ IOSet }}
     *
     *  Attribute { ATTRIBUTE:IOSet } ::= SEQUENCE {
     *    type    ATTRIBUTE.&id({IOSet}),
     *    values  SET SIZE(1..MAX) OF ATTRIBUTE.&Type({IOSet}{\@type})
     *  }
     * 
    * @deprecated use classes in org.bouncycastle.pkcs. */ public class PKCS10CertificationRequest extends CertificationRequest { private static Hashtable algorithms = new Hashtable(); private static Hashtable params = new Hashtable(); private static Hashtable keyAlgorithms = new Hashtable(); private static Hashtable oids = new Hashtable(); private static Set noParams = new HashSet(); static { algorithms.put("MD2WITHRSAENCRYPTION", new DERObjectIdentifier("1.2.840.113549.1.1.2")); algorithms.put("MD2WITHRSA", new DERObjectIdentifier("1.2.840.113549.1.1.2")); algorithms.put("MD5WITHRSAENCRYPTION", new DERObjectIdentifier("1.2.840.113549.1.1.4")); algorithms.put("MD5WITHRSA", new DERObjectIdentifier("1.2.840.113549.1.1.4")); algorithms.put("RSAWITHMD5", new DERObjectIdentifier("1.2.840.113549.1.1.4")); algorithms.put("SHA1WITHRSAENCRYPTION", new DERObjectIdentifier("1.2.840.113549.1.1.5")); algorithms.put("SHA1WITHRSA", new DERObjectIdentifier("1.2.840.113549.1.1.5")); algorithms.put("SHA224WITHRSAENCRYPTION", PKCSObjectIdentifiers.sha224WithRSAEncryption); algorithms.put("SHA224WITHRSA", PKCSObjectIdentifiers.sha224WithRSAEncryption); algorithms.put("SHA256WITHRSAENCRYPTION", PKCSObjectIdentifiers.sha256WithRSAEncryption); algorithms.put("SHA256WITHRSA", PKCSObjectIdentifiers.sha256WithRSAEncryption); algorithms.put("SHA384WITHRSAENCRYPTION", PKCSObjectIdentifiers.sha384WithRSAEncryption); algorithms.put("SHA384WITHRSA", PKCSObjectIdentifiers.sha384WithRSAEncryption); algorithms.put("SHA512WITHRSAENCRYPTION", PKCSObjectIdentifiers.sha512WithRSAEncryption); algorithms.put("SHA512WITHRSA", PKCSObjectIdentifiers.sha512WithRSAEncryption); algorithms.put("SHA1WITHRSAANDMGF1", PKCSObjectIdentifiers.id_RSASSA_PSS); algorithms.put("SHA224WITHRSAANDMGF1", PKCSObjectIdentifiers.id_RSASSA_PSS); algorithms.put("SHA256WITHRSAANDMGF1", PKCSObjectIdentifiers.id_RSASSA_PSS); algorithms.put("SHA384WITHRSAANDMGF1", PKCSObjectIdentifiers.id_RSASSA_PSS); algorithms.put("SHA512WITHRSAANDMGF1", PKCSObjectIdentifiers.id_RSASSA_PSS); algorithms.put("RSAWITHSHA1", new DERObjectIdentifier("1.2.840.113549.1.1.5")); algorithms.put("RIPEMD128WITHRSAENCRYPTION", TeleTrusTObjectIdentifiers.rsaSignatureWithripemd128); algorithms.put("RIPEMD128WITHRSA", TeleTrusTObjectIdentifiers.rsaSignatureWithripemd128); algorithms.put("RIPEMD160WITHRSAENCRYPTION", TeleTrusTObjectIdentifiers.rsaSignatureWithripemd160); algorithms.put("RIPEMD160WITHRSA", TeleTrusTObjectIdentifiers.rsaSignatureWithripemd160); algorithms.put("RIPEMD256WITHRSAENCRYPTION", TeleTrusTObjectIdentifiers.rsaSignatureWithripemd256); algorithms.put("RIPEMD256WITHRSA", TeleTrusTObjectIdentifiers.rsaSignatureWithripemd256); algorithms.put("SHA1WITHDSA", new DERObjectIdentifier("1.2.840.10040.4.3")); algorithms.put("DSAWITHSHA1", new DERObjectIdentifier("1.2.840.10040.4.3")); algorithms.put("SHA224WITHDSA", NISTObjectIdentifiers.dsa_with_sha224); algorithms.put("SHA256WITHDSA", NISTObjectIdentifiers.dsa_with_sha256); algorithms.put("SHA384WITHDSA", NISTObjectIdentifiers.dsa_with_sha384); algorithms.put("SHA512WITHDSA", NISTObjectIdentifiers.dsa_with_sha512); algorithms.put("SHA1WITHECDSA", X9ObjectIdentifiers.ecdsa_with_SHA1); algorithms.put("SHA224WITHECDSA", X9ObjectIdentifiers.ecdsa_with_SHA224); algorithms.put("SHA256WITHECDSA", X9ObjectIdentifiers.ecdsa_with_SHA256); algorithms.put("SHA384WITHECDSA", X9ObjectIdentifiers.ecdsa_with_SHA384); algorithms.put("SHA512WITHECDSA", X9ObjectIdentifiers.ecdsa_with_SHA512); algorithms.put("ECDSAWITHSHA1", X9ObjectIdentifiers.ecdsa_with_SHA1); algorithms.put("GOST3411WITHGOST3410", CryptoProObjectIdentifiers.gostR3411_94_with_gostR3410_94); algorithms.put("GOST3410WITHGOST3411", CryptoProObjectIdentifiers.gostR3411_94_with_gostR3410_94); algorithms.put("GOST3411WITHECGOST3410", CryptoProObjectIdentifiers.gostR3411_94_with_gostR3410_2001); algorithms.put("GOST3411WITHECGOST3410-2001", CryptoProObjectIdentifiers.gostR3411_94_with_gostR3410_2001); algorithms.put("GOST3411WITHGOST3410-2001", CryptoProObjectIdentifiers.gostR3411_94_with_gostR3410_2001); // // reverse mappings // oids.put(new DERObjectIdentifier("1.2.840.113549.1.1.5"), "SHA1WITHRSA"); oids.put(PKCSObjectIdentifiers.sha224WithRSAEncryption, "SHA224WITHRSA"); oids.put(PKCSObjectIdentifiers.sha256WithRSAEncryption, "SHA256WITHRSA"); oids.put(PKCSObjectIdentifiers.sha384WithRSAEncryption, "SHA384WITHRSA"); oids.put(PKCSObjectIdentifiers.sha512WithRSAEncryption, "SHA512WITHRSA"); oids.put(CryptoProObjectIdentifiers.gostR3411_94_with_gostR3410_94, "GOST3411WITHGOST3410"); oids.put(CryptoProObjectIdentifiers.gostR3411_94_with_gostR3410_2001, "GOST3411WITHECGOST3410"); oids.put(new DERObjectIdentifier("1.2.840.113549.1.1.4"), "MD5WITHRSA"); oids.put(new DERObjectIdentifier("1.2.840.113549.1.1.2"), "MD2WITHRSA"); oids.put(new DERObjectIdentifier("1.2.840.10040.4.3"), "SHA1WITHDSA"); oids.put(X9ObjectIdentifiers.ecdsa_with_SHA1, "SHA1WITHECDSA"); oids.put(X9ObjectIdentifiers.ecdsa_with_SHA224, "SHA224WITHECDSA"); oids.put(X9ObjectIdentifiers.ecdsa_with_SHA256, "SHA256WITHECDSA"); oids.put(X9ObjectIdentifiers.ecdsa_with_SHA384, "SHA384WITHECDSA"); oids.put(X9ObjectIdentifiers.ecdsa_with_SHA512, "SHA512WITHECDSA"); oids.put(OIWObjectIdentifiers.sha1WithRSA, "SHA1WITHRSA"); oids.put(OIWObjectIdentifiers.dsaWithSHA1, "SHA1WITHDSA"); oids.put(NISTObjectIdentifiers.dsa_with_sha224, "SHA224WITHDSA"); oids.put(NISTObjectIdentifiers.dsa_with_sha256, "SHA256WITHDSA"); // // key types // keyAlgorithms.put(PKCSObjectIdentifiers.rsaEncryption, "RSA"); keyAlgorithms.put(X9ObjectIdentifiers.id_dsa, "DSA"); // // According to RFC 3279, the ASN.1 encoding SHALL (id-dsa-with-sha1) or MUST (ecdsa-with-SHA*) omit the parameters field. // The parameters field SHALL be NULL for RSA based signature algorithms. // noParams.add(X9ObjectIdentifiers.ecdsa_with_SHA1); noParams.add(X9ObjectIdentifiers.ecdsa_with_SHA224); noParams.add(X9ObjectIdentifiers.ecdsa_with_SHA256); noParams.add(X9ObjectIdentifiers.ecdsa_with_SHA384); noParams.add(X9ObjectIdentifiers.ecdsa_with_SHA512); noParams.add(X9ObjectIdentifiers.id_dsa_with_sha1); noParams.add(NISTObjectIdentifiers.dsa_with_sha224); noParams.add(NISTObjectIdentifiers.dsa_with_sha256); // // RFC 4491 // noParams.add(CryptoProObjectIdentifiers.gostR3411_94_with_gostR3410_94); noParams.add(CryptoProObjectIdentifiers.gostR3411_94_with_gostR3410_2001); // // explicit params // AlgorithmIdentifier sha1AlgId = new AlgorithmIdentifier(OIWObjectIdentifiers.idSHA1, DERNull.INSTANCE); params.put("SHA1WITHRSAANDMGF1", creatPSSParams(sha1AlgId, 20)); AlgorithmIdentifier sha224AlgId = new AlgorithmIdentifier(NISTObjectIdentifiers.id_sha224, DERNull.INSTANCE); params.put("SHA224WITHRSAANDMGF1", creatPSSParams(sha224AlgId, 28)); AlgorithmIdentifier sha256AlgId = new AlgorithmIdentifier(NISTObjectIdentifiers.id_sha256, DERNull.INSTANCE); params.put("SHA256WITHRSAANDMGF1", creatPSSParams(sha256AlgId, 32)); AlgorithmIdentifier sha384AlgId = new AlgorithmIdentifier(NISTObjectIdentifiers.id_sha384, DERNull.INSTANCE); params.put("SHA384WITHRSAANDMGF1", creatPSSParams(sha384AlgId, 48)); AlgorithmIdentifier sha512AlgId = new AlgorithmIdentifier(NISTObjectIdentifiers.id_sha512, DERNull.INSTANCE); params.put("SHA512WITHRSAANDMGF1", creatPSSParams(sha512AlgId, 64)); } private static RSASSAPSSparams creatPSSParams(AlgorithmIdentifier hashAlgId, int saltSize) { return new RSASSAPSSparams( hashAlgId, new AlgorithmIdentifier(PKCSObjectIdentifiers.id_mgf1, hashAlgId), new ASN1Integer(saltSize), new ASN1Integer(1)); } private static ASN1Sequence toDERSequence( byte[] bytes) { try { ASN1InputStream dIn = new ASN1InputStream(bytes); return (ASN1Sequence)dIn.readObject(); } catch (Exception e) { throw new IllegalArgumentException("badly encoded request"); } } /** * construct a PKCS10 certification request from a DER encoded * byte stream. */ public PKCS10CertificationRequest( byte[] bytes) { super(toDERSequence(bytes)); } public PKCS10CertificationRequest( ASN1Sequence sequence) { super(sequence); } /** * create a PKCS10 certfication request using the BC provider. */ public PKCS10CertificationRequest( String signatureAlgorithm, X509Name subject, PublicKey key, ASN1Set attributes, PrivateKey signingKey) throws NoSuchAlgorithmException, NoSuchProviderException, InvalidKeyException, SignatureException { this(signatureAlgorithm, subject, key, attributes, signingKey, BouncyCastleProvider.PROVIDER_NAME); } private static X509Name convertName( X500Principal name) { try { return new X509Principal(name.getEncoded()); } catch (IOException e) { throw new IllegalArgumentException("can't convert name"); } } /** * create a PKCS10 certfication request using the BC provider. */ public PKCS10CertificationRequest( String signatureAlgorithm, X500Principal subject, PublicKey key, ASN1Set attributes, PrivateKey signingKey) throws NoSuchAlgorithmException, NoSuchProviderException, InvalidKeyException, SignatureException { this(signatureAlgorithm, convertName(subject), key, attributes, signingKey, BouncyCastleProvider.PROVIDER_NAME); } /** * create a PKCS10 certfication request using the named provider. */ public PKCS10CertificationRequest( String signatureAlgorithm, X500Principal subject, PublicKey key, ASN1Set attributes, PrivateKey signingKey, String provider) throws NoSuchAlgorithmException, NoSuchProviderException, InvalidKeyException, SignatureException { this(signatureAlgorithm, convertName(subject), key, attributes, signingKey, provider); } /** * create a PKCS10 certfication request using the named provider. */ public PKCS10CertificationRequest( String signatureAlgorithm, X509Name subject, PublicKey key, ASN1Set attributes, PrivateKey signingKey, String provider) throws NoSuchAlgorithmException, NoSuchProviderException, InvalidKeyException, SignatureException { String algorithmName = Strings.toUpperCase(signatureAlgorithm); DERObjectIdentifier sigOID = (DERObjectIdentifier)algorithms.get(algorithmName); if (sigOID == null) { try { sigOID = new DERObjectIdentifier(algorithmName); } catch (Exception e) { throw new IllegalArgumentException("Unknown signature type requested"); } } if (subject == null) { throw new IllegalArgumentException("subject must not be null"); } if (key == null) { throw new IllegalArgumentException("public key must not be null"); } if (noParams.contains(sigOID)) { this.sigAlgId = new AlgorithmIdentifier(sigOID); } else if (params.containsKey(algorithmName)) { this.sigAlgId = new AlgorithmIdentifier(sigOID, (ASN1Encodable)params.get(algorithmName)); } else { this.sigAlgId = new AlgorithmIdentifier(sigOID, DERNull.INSTANCE); } try { ASN1Sequence seq = (ASN1Sequence)ASN1Primitive.fromByteArray(key.getEncoded()); this.reqInfo = new CertificationRequestInfo(subject, new SubjectPublicKeyInfo(seq), attributes); } catch (IOException e) { throw new IllegalArgumentException("can't encode public key"); } Signature sig; if (provider == null) { sig = Signature.getInstance(signatureAlgorithm); } else { sig = Signature.getInstance(signatureAlgorithm, provider); } sig.initSign(signingKey); try { sig.update(reqInfo.getEncoded(ASN1Encoding.DER)); } catch (Exception e) { throw new IllegalArgumentException("exception encoding TBS cert request - " + e); } this.sigBits = new DERBitString(sig.sign()); } /** * return the public key associated with the certification request - * the public key is created using the BC provider. */ public PublicKey getPublicKey() throws NoSuchAlgorithmException, NoSuchProviderException, InvalidKeyException { return getPublicKey(BouncyCastleProvider.PROVIDER_NAME); } public PublicKey getPublicKey( String provider) throws NoSuchAlgorithmException, NoSuchProviderException, InvalidKeyException { SubjectPublicKeyInfo subjectPKInfo = reqInfo.getSubjectPublicKeyInfo(); try { X509EncodedKeySpec xspec = new X509EncodedKeySpec(new DERBitString(subjectPKInfo).getBytes()); AlgorithmIdentifier keyAlg = subjectPKInfo.getAlgorithm(); try { if (provider == null) { return KeyFactory.getInstance(keyAlg.getAlgorithm().getId()).generatePublic(xspec); } else { return KeyFactory.getInstance(keyAlg.getAlgorithm().getId(), provider).generatePublic(xspec); } } catch (NoSuchAlgorithmException e) { // // try an alternate // if (keyAlgorithms.get(keyAlg.getObjectId()) != null) { String keyAlgorithm = (String)keyAlgorithms.get(keyAlg.getObjectId()); if (provider == null) { return KeyFactory.getInstance(keyAlgorithm).generatePublic(xspec); } else { return KeyFactory.getInstance(keyAlgorithm, provider).generatePublic(xspec); } } throw e; } } catch (InvalidKeySpecException e) { throw new InvalidKeyException("error decoding public key"); } catch (IOException e) { throw new InvalidKeyException("error decoding public key"); } } /** * verify the request using the BC provider. */ public boolean verify() throws NoSuchAlgorithmException, NoSuchProviderException, InvalidKeyException, SignatureException { return verify(BouncyCastleProvider.PROVIDER_NAME); } /** * verify the request using the passed in provider. */ public boolean verify( String provider) throws NoSuchAlgorithmException, NoSuchProviderException, InvalidKeyException, SignatureException { return verify(this.getPublicKey(provider), provider); } /** * verify the request using the passed in public key and the provider.. */ public boolean verify( PublicKey pubKey, String provider) throws NoSuchAlgorithmException, NoSuchProviderException, InvalidKeyException, SignatureException { Signature sig; try { if (provider == null) { sig = Signature.getInstance(getSignatureName(sigAlgId)); } else { sig = Signature.getInstance(getSignatureName(sigAlgId), provider); } } catch (NoSuchAlgorithmException e) { // // try an alternate // if (oids.get(sigAlgId.getObjectId()) != null) { String signatureAlgorithm = (String)oids.get(sigAlgId.getObjectId()); if (provider == null) { sig = Signature.getInstance(signatureAlgorithm); } else { sig = Signature.getInstance(signatureAlgorithm, provider); } } else { throw e; } } setSignatureParameters(sig, sigAlgId.getParameters()); sig.initVerify(pubKey); try { sig.update(reqInfo.getEncoded(ASN1Encoding.DER)); } catch (Exception e) { throw new SignatureException("exception encoding TBS cert request - " + e); } return sig.verify(sigBits.getBytes()); } /** * return a DER encoded byte array representing this object */ public byte[] getEncoded() { try { return this.getEncoded(ASN1Encoding.DER); } catch (IOException e) { throw new RuntimeException(e.toString()); } } private void setSignatureParameters( Signature signature, ASN1Encodable params) throws NoSuchAlgorithmException, SignatureException, InvalidKeyException { if (params != null && !DERNull.INSTANCE.equals(params)) { AlgorithmParameters sigParams = AlgorithmParameters.getInstance(signature.getAlgorithm(), signature.getProvider()); try { sigParams.init(params.toASN1Primitive().getEncoded(ASN1Encoding.DER)); } catch (IOException e) { throw new SignatureException("IOException decoding parameters: " + e.getMessage()); } if (signature.getAlgorithm().endsWith("MGF1")) { try { signature.setParameter(sigParams.getParameterSpec(PSSParameterSpec.class)); } catch (GeneralSecurityException e) { throw new SignatureException("Exception extracting parameters: " + e.getMessage()); } } } } static String getSignatureName( AlgorithmIdentifier sigAlgId) { ASN1Encodable params = sigAlgId.getParameters(); if (params != null && !DERNull.INSTANCE.equals(params)) { if (sigAlgId.getObjectId().equals(PKCSObjectIdentifiers.id_RSASSA_PSS)) { RSASSAPSSparams rsaParams = RSASSAPSSparams.getInstance(params); return getDigestAlgName(rsaParams.getHashAlgorithm().getObjectId()) + "withRSAandMGF1"; } } return sigAlgId.getObjectId().getId(); } private static String getDigestAlgName( DERObjectIdentifier digestAlgOID) { if (PKCSObjectIdentifiers.md5.equals(digestAlgOID)) { return "MD5"; } else if (OIWObjectIdentifiers.idSHA1.equals(digestAlgOID)) { return "SHA1"; } else if (NISTObjectIdentifiers.id_sha224.equals(digestAlgOID)) { return "SHA224"; } else if (NISTObjectIdentifiers.id_sha256.equals(digestAlgOID)) { return "SHA256"; } else if (NISTObjectIdentifiers.id_sha384.equals(digestAlgOID)) { return "SHA384"; } else if (NISTObjectIdentifiers.id_sha512.equals(digestAlgOID)) { return "SHA512"; } else if (TeleTrusTObjectIdentifiers.ripemd128.equals(digestAlgOID)) { return "RIPEMD128"; } else if (TeleTrusTObjectIdentifiers.ripemd160.equals(digestAlgOID)) { return "RIPEMD160"; } else if (TeleTrusTObjectIdentifiers.ripemd256.equals(digestAlgOID)) { return "RIPEMD256"; } else if (CryptoProObjectIdentifiers.gostR3411.equals(digestAlgOID)) { return "GOST3411"; } else { return digestAlgOID.getId(); } } } bouncycastle-1.49.orig/src/org/bouncycastle/jce/MultiCertStoreParameters.java0000644000175000017500000000267110623745117027073 0ustar ebourgebourgpackage org.bouncycastle.jce; import java.security.cert.CertStoreParameters; import java.util.Collection; public class MultiCertStoreParameters implements CertStoreParameters { private Collection certStores; private boolean searchAllStores; /** * Create a parameters object which specifies searching of all the passed in stores. * * @param certStores CertStores making up the multi CertStore */ public MultiCertStoreParameters(Collection certStores) { this(certStores, true); } /** * Create a parameters object which can be to used to make a multi store made up * of the passed in CertStores. If the searchAllStores parameter is false, any search on * the multi-store will terminate as soon as a search query produces a result. * * @param certStores CertStores making up the multi CertStore * @param searchAllStores true if all CertStores should be searched on request, false if a result * should be returned on the first successful CertStore query. */ public MultiCertStoreParameters(Collection certStores, boolean searchAllStores) { this.certStores = certStores; this.searchAllStores = searchAllStores; } public Collection getCertStores() { return certStores; } public boolean getSearchAllStores() { return searchAllStores; } public Object clone() { return this; } } bouncycastle-1.49.orig/src/org/bouncycastle/jce/exception/0000755000175000017500000000000012152033551023236 5ustar ebourgebourgbouncycastle-1.49.orig/src/org/bouncycastle/jce/exception/ExtException.java0000644000175000017500000000107010557347124026531 0ustar ebourgebourgpackage org.bouncycastle.jce.exception; /** * * This is an extended exception. Java before version 1.4 did not offer the * possibility the attach a cause to an exception. The cause of an exception is * the Throwable object which was thrown and caused the * exception. This interface must be implemented by all exceptions to accomplish * this additional functionality. * */ public interface ExtException { /** * Returns the cause of the exception. * * @return The cause of the exception. */ Throwable getCause(); } bouncycastle-1.49.orig/src/org/bouncycastle/jce/exception/ExtCertPathValidatorException.java0000644000175000017500000000125010557347124032032 0ustar ebourgebourgpackage org.bouncycastle.jce.exception; import java.security.cert.CertPath; import java.security.cert.CertPathValidatorException; public class ExtCertPathValidatorException extends CertPathValidatorException implements ExtException { private Throwable cause; public ExtCertPathValidatorException(String message, Throwable cause) { super(message); this.cause = cause; } public ExtCertPathValidatorException(String msg, Throwable cause, CertPath certPath, int index) { super(msg, cause, certPath, index); this.cause = cause; } public Throwable getCause() { return cause; } } bouncycastle-1.49.orig/src/org/bouncycastle/jce/exception/ExtCertificateEncodingException.java0000644000175000017500000000070510557347124032347 0ustar ebourgebourgpackage org.bouncycastle.jce.exception; import java.security.cert.CertificateEncodingException; public class ExtCertificateEncodingException extends CertificateEncodingException implements ExtException { private Throwable cause; public ExtCertificateEncodingException(String message, Throwable cause) { super(message); this.cause = cause; } public Throwable getCause() { return cause; } } bouncycastle-1.49.orig/src/org/bouncycastle/jce/exception/ExtCertPathBuilderException.java0000644000175000017500000000121410557347124031473 0ustar ebourgebourgpackage org.bouncycastle.jce.exception; import java.security.cert.CertPath; import java.security.cert.CertPathBuilderException; public class ExtCertPathBuilderException extends CertPathBuilderException implements ExtException { private Throwable cause; public ExtCertPathBuilderException(String message, Throwable cause) { super(message); this.cause = cause; } public ExtCertPathBuilderException(String msg, Throwable cause, CertPath certPath, int index) { super(msg, cause); this.cause = cause; } public Throwable getCause() { return cause; } } bouncycastle-1.49.orig/src/org/bouncycastle/jce/exception/ExtIOException.java0000644000175000017500000000056610557347124026772 0ustar ebourgebourgpackage org.bouncycastle.jce.exception; import java.io.IOException; public class ExtIOException extends IOException implements ExtException { private Throwable cause; public ExtIOException(String message, Throwable cause) { super(message); this.cause = cause; } public Throwable getCause() { return cause; } } bouncycastle-1.49.orig/src/org/bouncycastle/jce/X509Principal.java0000644000175000017500000001017011624652555024427 0ustar ebourgebourgpackage org.bouncycastle.jce; import java.io.IOException; import java.security.Principal; import java.util.Hashtable; import java.util.Vector; import org.bouncycastle.asn1.ASN1Encoding; import org.bouncycastle.asn1.ASN1InputStream; import org.bouncycastle.asn1.ASN1Sequence; import org.bouncycastle.asn1.x500.X500Name; import org.bouncycastle.asn1.x509.X509Name; /** * a general extension of X509Name with a couple of extra methods and * constructors. *

    * Objects of this type can be created from certificates and CRLs using the * PrincipalUtil class. *

    * @see org.bouncycastle.jce.PrincipalUtil */ public class X509Principal extends X509Name implements Principal { private static ASN1Sequence readSequence( ASN1InputStream aIn) throws IOException { try { return ASN1Sequence.getInstance(aIn.readObject()); } catch (IllegalArgumentException e) { throw new IOException("not an ASN.1 Sequence: " + e); } } /** * Constructor from an encoded byte array. */ public X509Principal( byte[] bytes) throws IOException { super(readSequence(new ASN1InputStream(bytes))); } /** * Constructor from an X509Name object. */ public X509Principal( X509Name name) { super((ASN1Sequence)name.toASN1Primitive()); } /** * Constructor from an X509Name object. */ public X509Principal( X500Name name) { super((ASN1Sequence)name.toASN1Primitive()); } /** * constructor from a table of attributes. *

    * it's is assumed the table contains OID/String pairs. */ public X509Principal( Hashtable attributes) { super(attributes); } /** * constructor from a table of attributes and a vector giving the * specific ordering required for encoding or conversion to a string. *

    * it's is assumed the table contains OID/String pairs. */ public X509Principal( Vector ordering, Hashtable attributes) { super(ordering, attributes); } /** * constructor from a vector of attribute values and a vector of OIDs. */ public X509Principal( Vector oids, Vector values) { super(oids, values); } /** * takes an X509 dir name as a string of the format "C=AU,ST=Victoria", or * some such, converting it into an ordered set of name attributes. */ public X509Principal( String dirName) { super(dirName); } /** * Takes an X509 dir name as a string of the format "C=AU,ST=Victoria", or * some such, converting it into an ordered set of name attributes. If reverse * is false the dir name will be encoded in the order of the (name, value) pairs * presented, otherwise the encoding will start with the last (name, value) pair * and work back. */ public X509Principal( boolean reverse, String dirName) { super(reverse, dirName); } /** * Takes an X509 dir name as a string of the format "C=AU, ST=Victoria", or * some such, converting it into an ordered set of name attributes. lookUp * should provide a table of lookups, indexed by lowercase only strings and * yielding a DERObjectIdentifier, other than that OID. and numeric oids * will be processed automatically. *

    * If reverse is true, create the encoded version of the sequence starting * from the last element in the string. */ public X509Principal( boolean reverse, Hashtable lookUp, String dirName) { super(reverse, lookUp, dirName); } public String getName() { return this.toString(); } /** * return a DER encoded byte array representing this object */ public byte[] getEncoded() { try { return this.getEncoded(ASN1Encoding.DER); } catch (IOException e) { throw new RuntimeException(e.toString()); } } } bouncycastle-1.49.orig/src/org/bouncycastle/jce/X509KeyUsage.java0000644000175000017500000000335611737273326024233 0ustar ebourgebourgpackage org.bouncycastle.jce; import org.bouncycastle.asn1.ASN1Object; import org.bouncycastle.asn1.ASN1Primitive; import org.bouncycastle.asn1.x509.KeyUsage; /** * A holding class for constructing an X509 Key Usage extension. * *

     *    id-ce-keyUsage OBJECT IDENTIFIER ::=  { id-ce 15 }
     *
     *    KeyUsage ::= BIT STRING {
     *         digitalSignature        (0),
     *         nonRepudiation          (1),
     *         keyEncipherment         (2),
     *         dataEncipherment        (3),
     *         keyAgreement            (4),
     *         keyCertSign             (5),
     *         cRLSign                 (6),
     *         encipherOnly            (7),
     *         decipherOnly            (8) }
     * 
    */ public class X509KeyUsage extends ASN1Object { public static final int digitalSignature = 1 << 7; public static final int nonRepudiation = 1 << 6; public static final int keyEncipherment = 1 << 5; public static final int dataEncipherment = 1 << 4; public static final int keyAgreement = 1 << 3; public static final int keyCertSign = 1 << 2; public static final int cRLSign = 1 << 1; public static final int encipherOnly = 1 << 0; public static final int decipherOnly = 1 << 15; private int usage = 0; /** * Basic constructor. * * @param usage - the bitwise OR of the Key Usage flags giving the * allowed uses for the key. * e.g. (X509KeyUsage.keyEncipherment | X509KeyUsage.dataEncipherment) */ public X509KeyUsage( int usage) { this.usage = usage; } public ASN1Primitive toASN1Primitive() { return new KeyUsage(usage).toASN1Primitive(); } } bouncycastle-1.49.orig/src/org/bouncycastle/jce/spec/0000755000175000017500000000000012152033551022172 5ustar ebourgebourgbouncycastle-1.49.orig/src/org/bouncycastle/jce/spec/GOST3410PrivateKeySpec.java0000644000175000017500000000264210324400070026735 0ustar ebourgebourgpackage org.bouncycastle.jce.spec; import java.math.BigInteger; import java.security.spec.KeySpec; /** * This class specifies a GOST3410-94 private key with its associated parameters. */ public class GOST3410PrivateKeySpec implements KeySpec { private BigInteger x; private BigInteger p; private BigInteger q; private BigInteger a; /** * Creates a new GOST3410PrivateKeySpec with the specified parameter values. * * @param x the private key. * @param p the prime. * @param q the sub-prime. * @param a the base. */ public GOST3410PrivateKeySpec(BigInteger x, BigInteger p, BigInteger q, BigInteger a) { this.x = x; this.p = p; this.q = q; this.a = a; } /** * Returns the private key x. * @return the private key x. */ public BigInteger getX() { return this.x; } /** * Returns the prime p. * @return the prime p. */ public BigInteger getP() { return this.p; } /** * Returns the sub-prime q. * @return the sub-prime q. */ public BigInteger getQ() { return this.q; } /** * Returns the base a. * @return the base a. */ public BigInteger getA() { return this.a; } } bouncycastle-1.49.orig/src/org/bouncycastle/jce/spec/ECNamedCurveParameterSpec.java0000644000175000017500000000236610262753175027774 0ustar ebourgebourgpackage org.bouncycastle.jce.spec; import java.math.BigInteger; import org.bouncycastle.math.ec.ECCurve; import org.bouncycastle.math.ec.ECPoint; /** * specification signifying that the curve parameters can also be * refered to by name. *

    * If you are using JDK 1.5 you should be looking at ECNamedCurveSpec. */ public class ECNamedCurveParameterSpec extends ECParameterSpec { private String name; public ECNamedCurveParameterSpec( String name, ECCurve curve, ECPoint G, BigInteger n) { super(curve, G, n); this.name = name; } public ECNamedCurveParameterSpec( String name, ECCurve curve, ECPoint G, BigInteger n, BigInteger h) { super(curve, G, n, h); this.name = name; } public ECNamedCurveParameterSpec( String name, ECCurve curve, ECPoint G, BigInteger n, BigInteger h, byte[] seed) { super(curve, G, n, h, seed); this.name = name; } /** * return the name of the curve the EC domain parameters belong to. */ public String getName() { return name; } } bouncycastle-1.49.orig/src/org/bouncycastle/jce/spec/ElGamalGenParameterSpec.java0000644000175000017500000000111010262753175027451 0ustar ebourgebourgpackage org.bouncycastle.jce.spec; import java.security.spec.AlgorithmParameterSpec; public class ElGamalGenParameterSpec implements AlgorithmParameterSpec { private int primeSize; /* * @param primeSize the size (in bits) of the prime modulus. */ public ElGamalGenParameterSpec( int primeSize) { this.primeSize = primeSize; } /** * Returns the size in bits of the prime modulus. * * @return the size in bits of the prime modulus */ public int getPrimeSize() { return primeSize; } } bouncycastle-1.49.orig/src/org/bouncycastle/jce/spec/RepeatedSecretKeySpec.java0000644000175000017500000000106611570167534027237 0ustar ebourgebourgpackage org.bouncycastle.jce.spec; import javax.crypto.SecretKey; /** * A simple object to indicate that a symmetric cipher should reuse the * last key provided. */ public class RepeatedSecretKeySpec implements SecretKey { private String algorithm; public RepeatedSecretKeySpec(String algorithm) { this.algorithm = algorithm; } public String getAlgorithm() { return algorithm; } public String getFormat() { return null; } public byte[] getEncoded() { return null; } } bouncycastle-1.49.orig/src/org/bouncycastle/jce/spec/GOST3410ParameterSpec.java0000644000175000017500000001047311625354023026606 0ustar ebourgebourgpackage org.bouncycastle.jce.spec; import java.security.spec.AlgorithmParameterSpec; import org.bouncycastle.asn1.ASN1ObjectIdentifier; import org.bouncycastle.asn1.cryptopro.CryptoProObjectIdentifiers; import org.bouncycastle.asn1.cryptopro.GOST3410NamedParameters; import org.bouncycastle.asn1.cryptopro.GOST3410ParamSetParameters; import org.bouncycastle.asn1.cryptopro.GOST3410PublicKeyAlgParameters; import org.bouncycastle.jce.interfaces.GOST3410Params; /** * ParameterSpec for a GOST 3410-94 key. */ public class GOST3410ParameterSpec implements AlgorithmParameterSpec, GOST3410Params { private GOST3410PublicKeyParameterSetSpec keyParameters; private String keyParamSetOID; private String digestParamSetOID; private String encryptionParamSetOID; public GOST3410ParameterSpec( String keyParamSetID, String digestParamSetOID, String encryptionParamSetOID) { GOST3410ParamSetParameters ecP = null; try { ecP = GOST3410NamedParameters.getByOID(new ASN1ObjectIdentifier(keyParamSetID)); } catch (IllegalArgumentException e) { ASN1ObjectIdentifier oid = GOST3410NamedParameters.getOID(keyParamSetID); if (oid != null) { keyParamSetID = oid.getId(); ecP = GOST3410NamedParameters.getByOID(oid); } } if (ecP == null) { throw new IllegalArgumentException("no key parameter set for passed in name/OID."); } this.keyParameters = new GOST3410PublicKeyParameterSetSpec( ecP.getP(), ecP.getQ(), ecP.getA()); this.keyParamSetOID = keyParamSetID; this.digestParamSetOID = digestParamSetOID; this.encryptionParamSetOID = encryptionParamSetOID; } public GOST3410ParameterSpec( String keyParamSetID, String digestParamSetOID) { this(keyParamSetID, digestParamSetOID, null); } public GOST3410ParameterSpec( String keyParamSetID) { this(keyParamSetID, CryptoProObjectIdentifiers.gostR3411_94_CryptoProParamSet.getId(), null); } public GOST3410ParameterSpec( GOST3410PublicKeyParameterSetSpec spec) { this.keyParameters = spec; this.digestParamSetOID = CryptoProObjectIdentifiers.gostR3411_94_CryptoProParamSet.getId(); this.encryptionParamSetOID = null; } public String getPublicKeyParamSetOID() { return this.keyParamSetOID; } public GOST3410PublicKeyParameterSetSpec getPublicKeyParameters() { return keyParameters; } public String getDigestParamSetOID() { return this.digestParamSetOID; } public String getEncryptionParamSetOID() { return this.encryptionParamSetOID; } public boolean equals(Object o) { if (o instanceof GOST3410ParameterSpec) { GOST3410ParameterSpec other = (GOST3410ParameterSpec)o; return this.keyParameters.equals(other.keyParameters) && this.digestParamSetOID.equals(other.digestParamSetOID) && (this.encryptionParamSetOID == other.encryptionParamSetOID || (this.encryptionParamSetOID != null && this.encryptionParamSetOID.equals(other.encryptionParamSetOID))); } return false; } public int hashCode() { return this.keyParameters.hashCode() ^ this.digestParamSetOID.hashCode() ^ (this.encryptionParamSetOID != null ? this.encryptionParamSetOID.hashCode() : 0); } public static GOST3410ParameterSpec fromPublicKeyAlg( GOST3410PublicKeyAlgParameters params) { if (params.getEncryptionParamSet() != null) { return new GOST3410ParameterSpec(params.getPublicKeyParamSet().getId(), params.getDigestParamSet().getId(), params.getEncryptionParamSet().getId()); } else { return new GOST3410ParameterSpec(params.getPublicKeyParamSet().getId(), params.getDigestParamSet().getId()); } } } bouncycastle-1.49.orig/src/org/bouncycastle/jce/spec/ElGamalParameterSpec.java0000644000175000017500000000171010262753175027025 0ustar ebourgebourgpackage org.bouncycastle.jce.spec; import java.math.BigInteger; import java.security.spec.AlgorithmParameterSpec; public class ElGamalParameterSpec implements AlgorithmParameterSpec { private BigInteger p; private BigInteger g; /** * Constructs a parameter set for Diffie-Hellman, using a prime modulus * p and a base generator g. * * @param p the prime modulus * @param g the base generator */ public ElGamalParameterSpec( BigInteger p, BigInteger g) { this.p = p; this.g = g; } /** * Returns the prime modulus p. * * @return the prime modulus p */ public BigInteger getP() { return p; } /** * Returns the base generator g. * * @return the base generator g */ public BigInteger getG() { return g; } } bouncycastle-1.49.orig/src/org/bouncycastle/jce/spec/ElGamalPublicKeySpec.java0000644000175000017500000000115010262753175026772 0ustar ebourgebourgpackage org.bouncycastle.jce.spec; import java.math.BigInteger; /** * This class specifies an ElGamal public key with its associated parameters. * * @see ElGamalPrivateKeySpec */ public class ElGamalPublicKeySpec extends ElGamalKeySpec { private BigInteger y; public ElGamalPublicKeySpec( BigInteger y, ElGamalParameterSpec spec) { super(spec); this.y = y; } /** * Returns the public value y. * * @return the public value y */ public BigInteger getY() { return y; } } bouncycastle-1.49.orig/src/org/bouncycastle/jce/spec/IESParameterSpec.java0000644000175000017500000000461312033465011026133 0ustar ebourgebourgpackage org.bouncycastle.jce.spec; import java.security.spec.AlgorithmParameterSpec; /** * Parameter spec for an integrated encryptor, as in IEEE P1363a */ public class IESParameterSpec implements AlgorithmParameterSpec { private byte[] derivation; private byte[] encoding; private int macKeySize; private int cipherKeySize; /** * Set the IES engine parameters. * * @param derivation the optional derivation vector for the KDF. * @param encoding the optional encoding vector for the KDF. * @param macKeySize the key size (in bits) for the MAC. */ public IESParameterSpec( byte[] derivation, byte[] encoding, int macKeySize) { this(derivation, encoding, macKeySize, -1); } /** * Set the IES engine parameters. * * @param derivation the optional derivation vector for the KDF. * @param encoding the optional encoding vector for the KDF. * @param macKeySize the key size (in bits) for the MAC. * @param cipherKeySize the key size (in bits) for the block cipher. */ public IESParameterSpec( byte[] derivation, byte[] encoding, int macKeySize, int cipherKeySize) { if (derivation != null) { this.derivation = new byte[derivation.length]; System.arraycopy(derivation, 0, this.derivation, 0, derivation.length); } else { this.derivation = null; } if (encoding != null) { this.encoding = new byte[encoding.length]; System.arraycopy(encoding, 0, this.encoding, 0, encoding.length); } else { this.encoding = null; } this.macKeySize = macKeySize; this.cipherKeySize = cipherKeySize; } /** * return the derivation vector. */ public byte[] getDerivationV() { return derivation; } /** * return the encoding vector. */ public byte[] getEncodingV() { return encoding; } /** * return the key size in bits for the MAC used with the message */ public int getMacKeySize() { return macKeySize; } /** * return the key size in bits for the block cipher used with the message */ public int getCipherKeySize() { return cipherKeySize; } } bouncycastle-1.49.orig/src/org/bouncycastle/jce/spec/ECNamedCurveSpec.java0000644000175000017500000000655110373515661026132 0ustar ebourgebourgpackage org.bouncycastle.jce.spec; import java.math.BigInteger; import java.security.spec.ECFieldF2m; import java.security.spec.ECFieldFp; import java.security.spec.ECPoint; import java.security.spec.EllipticCurve; import org.bouncycastle.math.ec.ECCurve; /** * specification signifying that the curve parameters can also be * referred to by name. */ public class ECNamedCurveSpec extends java.security.spec.ECParameterSpec { private String name; private static EllipticCurve convertCurve( ECCurve curve, byte[] seed) { if (curve instanceof ECCurve.Fp) { return new EllipticCurve(new ECFieldFp(((ECCurve.Fp)curve).getQ()), curve.getA().toBigInteger(), curve.getB().toBigInteger(), seed); } else { ECCurve.F2m curveF2m = (ECCurve.F2m)curve; int ks[]; if (curveF2m.isTrinomial()) { ks = new int[] { curveF2m.getK1() }; return new EllipticCurve(new ECFieldF2m(curveF2m.getM(), ks), curve.getA().toBigInteger(), curve.getB().toBigInteger(), seed); } else { ks = new int[] { curveF2m.getK3(), curveF2m.getK2(), curveF2m.getK1() }; return new EllipticCurve(new ECFieldF2m(curveF2m.getM(), ks), curve.getA().toBigInteger(), curve.getB().toBigInteger(), seed); } } } private static ECPoint convertPoint( org.bouncycastle.math.ec.ECPoint g) { return new ECPoint(g.getX().toBigInteger(), g.getY().toBigInteger()); } public ECNamedCurveSpec( String name, ECCurve curve, org.bouncycastle.math.ec.ECPoint g, BigInteger n) { super(convertCurve(curve, null), convertPoint(g), n, 1); this.name = name; } public ECNamedCurveSpec( String name, EllipticCurve curve, ECPoint g, BigInteger n) { super(curve, g, n, 1); this.name = name; } public ECNamedCurveSpec( String name, ECCurve curve, org.bouncycastle.math.ec.ECPoint g, BigInteger n, BigInteger h) { super(convertCurve(curve, null), convertPoint(g), n, h.intValue()); this.name = name; } public ECNamedCurveSpec( String name, EllipticCurve curve, ECPoint g, BigInteger n, BigInteger h) { super(curve, g, n, h.intValue()); this.name = name; } public ECNamedCurveSpec( String name, ECCurve curve, org.bouncycastle.math.ec.ECPoint g, BigInteger n, BigInteger h, byte[] seed) { super(convertCurve(curve, seed), convertPoint(g), n, h.intValue()); this.name = name; } /** * return the name of the curve the EC domain parameters belong to. */ public String getName() { return name; } } bouncycastle-1.49.orig/src/org/bouncycastle/jce/spec/MQVPrivateKeySpec.java0000644000175000017500000000412711275506021026325 0ustar ebourgebourgpackage org.bouncycastle.jce.spec; import java.security.PrivateKey; import java.security.PublicKey; import java.security.spec.KeySpec; import org.bouncycastle.jce.interfaces.MQVPrivateKey; /** * Static/ephemeral private key (pair) for use with ECMQV key agreement * (Optionally provides the ephemeral public key) */ public class MQVPrivateKeySpec implements KeySpec, MQVPrivateKey { private PrivateKey staticPrivateKey; private PrivateKey ephemeralPrivateKey; private PublicKey ephemeralPublicKey; /** * @param staticPrivateKey the static private key. * @param ephemeralPrivateKey the ephemeral private key. */ public MQVPrivateKeySpec( PrivateKey staticPrivateKey, PrivateKey ephemeralPrivateKey) { this(staticPrivateKey, ephemeralPrivateKey, null); } /** * @param staticPrivateKey the static private key. * @param ephemeralPrivateKey the ephemeral private key. * @param ephemeralPublicKey the ephemeral public key (may be null). */ public MQVPrivateKeySpec( PrivateKey staticPrivateKey, PrivateKey ephemeralPrivateKey, PublicKey ephemeralPublicKey) { this.staticPrivateKey = staticPrivateKey; this.ephemeralPrivateKey = ephemeralPrivateKey; this.ephemeralPublicKey = ephemeralPublicKey; } /** * return the static private key */ public PrivateKey getStaticPrivateKey() { return staticPrivateKey; } /** * return the ephemeral private key */ public PrivateKey getEphemeralPrivateKey() { return ephemeralPrivateKey; } /** * return the ephemeral public key (may be null) */ public PublicKey getEphemeralPublicKey() { return ephemeralPublicKey; } /** * return "ECMQV" */ public String getAlgorithm() { return "ECMQV"; } /** * return null */ public String getFormat() { return null; } /** * returns null */ public byte[] getEncoded() { return null; } } bouncycastle-1.49.orig/src/org/bouncycastle/jce/spec/ECKeySpec.java0000644000175000017500000000067610262753175024634 0ustar ebourgebourgpackage org.bouncycastle.jce.spec; import java.security.spec.KeySpec; /** * base class for an Elliptic Curve Key Spec */ public class ECKeySpec implements KeySpec { private ECParameterSpec spec; protected ECKeySpec( ECParameterSpec spec) { this.spec = spec; } /** * return the domain parameters for the curve */ public ECParameterSpec getParams() { return spec; } } bouncycastle-1.49.orig/src/org/bouncycastle/jce/spec/GOST3410PublicKeyParameterSetSpec.java0000644000175000017500000000314610452142551031067 0ustar ebourgebourgpackage org.bouncycastle.jce.spec; import java.math.BigInteger; /** * ParameterSpec for a GOST 3410-94 key parameters. */ public class GOST3410PublicKeyParameterSetSpec { private BigInteger p; private BigInteger q; private BigInteger a; /** * Creates a new GOST3410ParameterSpec with the specified parameter values. * * @param p the prime. * @param q the sub-prime. * @param a the base. */ public GOST3410PublicKeyParameterSetSpec( BigInteger p, BigInteger q, BigInteger a) { this.p = p; this.q = q; this.a = a; } /** * Returns the prime p. * * @return the prime p. */ public BigInteger getP() { return this.p; } /** * Returns the sub-prime q. * * @return the sub-prime q. */ public BigInteger getQ() { return this.q; } /** * Returns the base a. * * @return the base a. */ public BigInteger getA() { return this.a; } public boolean equals( Object o) { if (o instanceof GOST3410PublicKeyParameterSetSpec) { GOST3410PublicKeyParameterSetSpec other = (GOST3410PublicKeyParameterSetSpec)o; return this.a.equals(other.a) && this.p.equals(other.p) && this.q.equals(other.q); } return false; } public int hashCode() { return a.hashCode() ^ p.hashCode() ^ q.hashCode(); } } bouncycastle-1.49.orig/src/org/bouncycastle/jce/spec/ECNamedCurveGenParameterSpec.java0000644000175000017500000000106711726530737030426 0ustar ebourgebourgpackage org.bouncycastle.jce.spec; import java.security.spec.AlgorithmParameterSpec; /** * Named curve generation spec *

    * If you are using JDK 1.5 you should be looking at ECGenParameterSpec. */ public class ECNamedCurveGenParameterSpec implements AlgorithmParameterSpec { private String name; public ECNamedCurveGenParameterSpec( String name) { this.name = name; } /** * return the name of the curve the EC domain parameters belong to. */ public String getName() { return name; } } bouncycastle-1.49.orig/src/org/bouncycastle/jce/spec/ECPrivateKeySpec.java0000644000175000017500000000115210262753175026155 0ustar ebourgebourgpackage org.bouncycastle.jce.spec; import java.math.BigInteger; /** * Elliptic Curve private key specification. */ public class ECPrivateKeySpec extends ECKeySpec { private BigInteger d; /** * base constructor * * @param d the private number for the key. * @param spec the domain parameters for the curve being used. */ public ECPrivateKeySpec( BigInteger d, ECParameterSpec spec) { super(spec); this.d = d; } /** * return the private number D */ public BigInteger getD() { return d; } } bouncycastle-1.49.orig/src/org/bouncycastle/jce/spec/ElGamalPrivateKeySpec.java0000644000175000017500000000115410262753175027172 0ustar ebourgebourgpackage org.bouncycastle.jce.spec; import java.math.BigInteger; /** * This class specifies an ElGamal private key with its associated parameters. * * @see ElGamalPublicKeySpec */ public class ElGamalPrivateKeySpec extends ElGamalKeySpec { private BigInteger x; public ElGamalPrivateKeySpec( BigInteger x, ElGamalParameterSpec spec) { super(spec); this.x = x; } /** * Returns the private value x. * * @return the private value x */ public BigInteger getX() { return x; } } bouncycastle-1.49.orig/src/org/bouncycastle/jce/spec/ElGamalKeySpec.java0000644000175000017500000000053310262753175025637 0ustar ebourgebourgpackage org.bouncycastle.jce.spec; import java.security.spec.KeySpec; public class ElGamalKeySpec implements KeySpec { private ElGamalParameterSpec spec; public ElGamalKeySpec( ElGamalParameterSpec spec) { this.spec = spec; } public ElGamalParameterSpec getParams() { return spec; } } bouncycastle-1.49.orig/src/org/bouncycastle/jce/spec/GOST28147ParameterSpec.java0000644000175000017500000000302110262753175026702 0ustar ebourgebourgpackage org.bouncycastle.jce.spec; import java.security.spec.AlgorithmParameterSpec; import org.bouncycastle.crypto.engines.GOST28147Engine; /** * A parameter spec for the GOST-28147 cipher. */ public class GOST28147ParameterSpec implements AlgorithmParameterSpec { private byte[] iv = null; private byte[] sBox = null; public GOST28147ParameterSpec( byte[] sBox) { this.sBox = new byte[sBox.length]; System.arraycopy(sBox, 0, this.sBox, 0, sBox.length); } public GOST28147ParameterSpec( byte[] sBox, byte[] iv) { this(sBox); this.iv = new byte[iv.length]; System.arraycopy(iv, 0, this.iv, 0, iv.length); } public GOST28147ParameterSpec( String sBoxName) { this.sBox = GOST28147Engine.getSBox(sBoxName); } public GOST28147ParameterSpec( String sBoxName, byte[] iv) { this(sBoxName); this.iv = new byte[iv.length]; System.arraycopy(iv, 0, this.iv, 0, iv.length); } public byte[] getSbox() { return sBox; } /** * Returns the IV or null if this parameter set does not contain an IV. * * @return the IV or null if this parameter set does not contain an IV. */ public byte[] getIV() { if (iv == null) { return null; } byte[] tmp = new byte[iv.length]; System.arraycopy(iv, 0, tmp, 0, tmp.length); return tmp; } }bouncycastle-1.49.orig/src/org/bouncycastle/jce/spec/ECPublicKeySpec.java0000644000175000017500000000113610262753175025763 0ustar ebourgebourgpackage org.bouncycastle.jce.spec; import org.bouncycastle.math.ec.ECPoint; /** * Elliptic Curve public key specification */ public class ECPublicKeySpec extends ECKeySpec { private ECPoint q; /** * base constructor * * @param q the public point on the curve. * @param spec the domain parameters for the curve. */ public ECPublicKeySpec( ECPoint q, ECParameterSpec spec) { super(spec); this.q = q; } /** * return the public point q */ public ECPoint getQ() { return q; } } bouncycastle-1.49.orig/src/org/bouncycastle/jce/spec/ECParameterSpec.java0000644000175000017500000000463410571211162026006 0ustar ebourgebourgpackage org.bouncycastle.jce.spec; import org.bouncycastle.math.ec.ECCurve; import org.bouncycastle.math.ec.ECPoint; import java.math.BigInteger; import java.security.spec.AlgorithmParameterSpec; /** * basic domain parameters for an Elliptic Curve public or private key. */ public class ECParameterSpec implements AlgorithmParameterSpec { private ECCurve curve; private byte[] seed; private ECPoint G; private BigInteger n; private BigInteger h; public ECParameterSpec( ECCurve curve, ECPoint G, BigInteger n) { this.curve = curve; this.G = G; this.n = n; this.h = BigInteger.valueOf(1); this.seed = null; } public ECParameterSpec( ECCurve curve, ECPoint G, BigInteger n, BigInteger h) { this.curve = curve; this.G = G; this.n = n; this.h = h; this.seed = null; } public ECParameterSpec( ECCurve curve, ECPoint G, BigInteger n, BigInteger h, byte[] seed) { this.curve = curve; this.G = G; this.n = n; this.h = h; this.seed = seed; } /** * return the curve along which the base point lies. * @return the curve */ public ECCurve getCurve() { return curve; } /** * return the base point we are using for these domain parameters. * @return the base point. */ public ECPoint getG() { return G; } /** * return the order N of G * @return the order */ public BigInteger getN() { return n; } /** * return the cofactor H to the order of G. * @return the cofactor */ public BigInteger getH() { return h; } /** * return the seed used to generate this curve (if available). * @return the random seed */ public byte[] getSeed() { return seed; } public boolean equals(Object o) { if (!(o instanceof ECParameterSpec)) { return false; } ECParameterSpec other = (ECParameterSpec)o; return this.getCurve().equals(other.getCurve()) && this.getG().equals(other.getG()); } public int hashCode() { return this.getCurve().hashCode() ^ this.getG().hashCode(); } } bouncycastle-1.49.orig/src/org/bouncycastle/jce/spec/GOST3410PublicKeySpec.java0000644000175000017500000000272010324400070026536 0ustar ebourgebourgpackage org.bouncycastle.jce.spec; import java.math.BigInteger; import java.security.spec.KeySpec; /** * This class specifies a GOST3410-94 public key with its associated parameters. */ public class GOST3410PublicKeySpec implements KeySpec { private BigInteger y; private BigInteger p; private BigInteger q; private BigInteger a; /** * Creates a new GOST3410PublicKeySpec with the specified parameter values. * * @param y the public key. * @param p the prime. * @param q the sub-prime. * @param a the base. */ public GOST3410PublicKeySpec( BigInteger y, BigInteger p, BigInteger q, BigInteger a) { this.y = y; this.p = p; this.q = q; this.a = a; } /** * Returns the public key y. * * @return the public key y. */ public BigInteger getY() { return this.y; } /** * Returns the prime p. * * @return the prime p. */ public BigInteger getP() { return this.p; } /** * Returns the sub-prime q. * * @return the sub-prime q. */ public BigInteger getQ() { return this.q; } /** * Returns the base g. * * @return the base g. */ public BigInteger getA() { return this.a; } } bouncycastle-1.49.orig/src/org/bouncycastle/jce/spec/IEKeySpec.java0000644000175000017500000000237510262753175024640 0ustar ebourgebourgpackage org.bouncycastle.jce.spec; import java.security.PrivateKey; import java.security.PublicKey; import java.security.spec.KeySpec; import org.bouncycastle.jce.interfaces.IESKey; /** * key pair for use with an integrated encryptor - together * they provide what's required to generate the message. */ public class IEKeySpec implements KeySpec, IESKey { private PublicKey pubKey; private PrivateKey privKey; /** * @param privKey our private key. * @param pubKey the public key of the sender/recipient. */ public IEKeySpec( PrivateKey privKey, PublicKey pubKey) { this.privKey = privKey; this.pubKey = pubKey; } /** * return the intended recipient's/sender's public key. */ public PublicKey getPublic() { return pubKey; } /** * return the local private key. */ public PrivateKey getPrivate() { return privKey; } /** * return "IES" */ public String getAlgorithm() { return "IES"; } /** * return null */ public String getFormat() { return null; } /** * returns null */ public byte[] getEncoded() { return null; } } bouncycastle-1.49.orig/src/org/bouncycastle/jce/spec/package.html0000644000175000017500000000016610262753175024471 0ustar ebourgebourg Parameter specifications for supporting El Gamal, and Elliptic Curve. bouncycastle-1.49.orig/src/org/bouncycastle/jce/spec/MQVPublicKeySpec.java0000644000175000017500000000233711275506021026132 0ustar ebourgebourgpackage org.bouncycastle.jce.spec; import java.security.PublicKey; import java.security.spec.KeySpec; import org.bouncycastle.jce.interfaces.MQVPublicKey; /** * Static/ephemeral public key pair for use with ECMQV key agreement */ public class MQVPublicKeySpec implements KeySpec, MQVPublicKey { private PublicKey staticKey; private PublicKey ephemeralKey; /** * @param staticKey the static public key. * @param ephemeralKey the ephemeral public key. */ public MQVPublicKeySpec( PublicKey staticKey, PublicKey ephemeralKey) { this.staticKey = staticKey; this.ephemeralKey = ephemeralKey; } /** * return the static public key */ public PublicKey getStaticKey() { return staticKey; } /** * return the ephemeral public key */ public PublicKey getEphemeralKey() { return ephemeralKey; } /** * return "ECMQV" */ public String getAlgorithm() { return "ECMQV"; } /** * return null */ public String getFormat() { return null; } /** * returns null */ public byte[] getEncoded() { return null; } } bouncycastle-1.49.orig/src/org/bouncycastle/jce/PrincipalUtil.java0000644000175000017500000000473411625075370024703 0ustar ebourgebourgpackage org.bouncycastle.jce; import java.io.IOException; import java.security.cert.CRLException; import java.security.cert.CertificateEncodingException; import java.security.cert.X509CRL; import java.security.cert.X509Certificate; import org.bouncycastle.asn1.ASN1Primitive; import org.bouncycastle.asn1.x509.TBSCertList; import org.bouncycastle.asn1.x509.TBSCertificateStructure; import org.bouncycastle.asn1.x509.X509Name; /** * a utility class that will extract X509Principal objects from X.509 certificates. *

    * Use this in preference to trying to recreate a principal from a String, not all * DNs are what they should be, so it's best to leave them encoded where they * can be. */ public class PrincipalUtil { /** * return the issuer of the given cert as an X509PrincipalObject. */ public static X509Principal getIssuerX509Principal( X509Certificate cert) throws CertificateEncodingException { try { TBSCertificateStructure tbsCert = TBSCertificateStructure.getInstance( ASN1Primitive.fromByteArray(cert.getTBSCertificate())); return new X509Principal(X509Name.getInstance(tbsCert.getIssuer())); } catch (IOException e) { throw new CertificateEncodingException(e.toString()); } } /** * return the subject of the given cert as an X509PrincipalObject. */ public static X509Principal getSubjectX509Principal( X509Certificate cert) throws CertificateEncodingException { try { TBSCertificateStructure tbsCert = TBSCertificateStructure.getInstance( ASN1Primitive.fromByteArray(cert.getTBSCertificate())); return new X509Principal(X509Name.getInstance(tbsCert.getSubject())); } catch (IOException e) { throw new CertificateEncodingException(e.toString()); } } /** * return the issuer of the given CRL as an X509PrincipalObject. */ public static X509Principal getIssuerX509Principal( X509CRL crl) throws CRLException { try { TBSCertList tbsCertList = TBSCertList.getInstance( ASN1Primitive.fromByteArray(crl.getTBSCertList())); return new X509Principal(X509Name.getInstance(tbsCertList.getIssuer())); } catch (IOException e) { throw new CRLException(e.toString()); } } } bouncycastle-1.49.orig/src/org/bouncycastle/jce/ECNamedCurveTable.java0000644000175000017500000000645611625347120025333 0ustar ebourgebourgpackage org.bouncycastle.jce; import java.util.Enumeration; import java.util.Vector; import org.bouncycastle.asn1.ASN1ObjectIdentifier; import org.bouncycastle.asn1.nist.NISTNamedCurves; import org.bouncycastle.asn1.sec.SECNamedCurves; import org.bouncycastle.asn1.teletrust.TeleTrusTNamedCurves; import org.bouncycastle.asn1.x9.X962NamedCurves; import org.bouncycastle.asn1.x9.X9ECParameters; import org.bouncycastle.jce.spec.ECNamedCurveParameterSpec; /** * a table of locally supported named curves. */ public class ECNamedCurveTable { /** * return a parameter spec representing the passed in named * curve. The routine returns null if the curve is not present. * * @param name the name of the curve requested * @return a parameter spec for the curve, null if it is not available. */ public static ECNamedCurveParameterSpec getParameterSpec( String name) { X9ECParameters ecP = X962NamedCurves.getByName(name); if (ecP == null) { try { ecP = X962NamedCurves.getByOID(new ASN1ObjectIdentifier(name)); } catch (IllegalArgumentException e) { // ignore - not an oid } } if (ecP == null) { ecP = SECNamedCurves.getByName(name); if (ecP == null) { try { ecP = SECNamedCurves.getByOID(new ASN1ObjectIdentifier(name)); } catch (IllegalArgumentException e) { // ignore - not an oid } } } if (ecP == null) { ecP = TeleTrusTNamedCurves.getByName(name); if (ecP == null) { try { ecP = TeleTrusTNamedCurves.getByOID(new ASN1ObjectIdentifier(name)); } catch (IllegalArgumentException e) { // ignore - not an oid } } } if (ecP == null) { ecP = NISTNamedCurves.getByName(name); } if (ecP == null) { return null; } return new ECNamedCurveParameterSpec( name, ecP.getCurve(), ecP.getG(), ecP.getN(), ecP.getH(), ecP.getSeed()); } /** * return an enumeration of the names of the available curves. * * @return an enumeration of the names of the available curves. */ public static Enumeration getNames() { Vector v = new Vector(); addEnumeration(v, X962NamedCurves.getNames()); addEnumeration(v, SECNamedCurves.getNames()); addEnumeration(v, NISTNamedCurves.getNames()); addEnumeration(v, TeleTrusTNamedCurves.getNames()); return v.elements(); } private static void addEnumeration( Vector v, Enumeration e) { while (e.hasMoreElements()) { v.addElement(e.nextElement()); } } } bouncycastle-1.49.orig/src/org/bouncycastle/jce/interfaces/0000755000175000017500000000000012152033551023363 5ustar ebourgebourgbouncycastle-1.49.orig/src/org/bouncycastle/jce/interfaces/GOST3410PrivateKey.java0000644000175000017500000000027510324400067027321 0ustar ebourgebourgpackage org.bouncycastle.jce.interfaces; import java.math.BigInteger; public interface GOST3410PrivateKey extends GOST3410Key, java.security.PrivateKey { public BigInteger getX(); } bouncycastle-1.49.orig/src/org/bouncycastle/jce/interfaces/ElGamalPublicKey.java0000644000175000017500000000031610262753175027353 0ustar ebourgebourgpackage org.bouncycastle.jce.interfaces; import java.math.BigInteger; import java.security.PublicKey; public interface ElGamalPublicKey extends ElGamalKey, PublicKey { public BigInteger getY(); } bouncycastle-1.49.orig/src/org/bouncycastle/jce/interfaces/BCKeyStore.java0000644000175000017500000000043410262753175026214 0ustar ebourgebourgpackage org.bouncycastle.jce.interfaces; import java.security.SecureRandom; /** * all BC provider keystores implement this interface. */ public interface BCKeyStore { /** * set the random source for the key store */ public void setRandom(SecureRandom random); } bouncycastle-1.49.orig/src/org/bouncycastle/jce/interfaces/GOST3410PublicKey.java0000644000175000017500000000031510324400067027120 0ustar ebourgebourgpackage org.bouncycastle.jce.interfaces; import java.security.PublicKey; import java.math.BigInteger; public interface GOST3410PublicKey extends GOST3410Key, PublicKey { public BigInteger getY(); } bouncycastle-1.49.orig/src/org/bouncycastle/jce/interfaces/ElGamalPrivateKey.java0000644000175000017500000000032110262753175027543 0ustar ebourgebourgpackage org.bouncycastle.jce.interfaces; import java.math.BigInteger; import java.security.PrivateKey; public interface ElGamalPrivateKey extends ElGamalKey, PrivateKey { public BigInteger getX(); } bouncycastle-1.49.orig/src/org/bouncycastle/jce/interfaces/ECPublicKey.java0000644000175000017500000000046410262753175026344 0ustar ebourgebourgpackage org.bouncycastle.jce.interfaces; import java.security.PublicKey; import org.bouncycastle.math.ec.ECPoint; /** * interface for elliptic curve public keys. */ public interface ECPublicKey extends ECKey, PublicKey { /** * return the public point Q */ public ECPoint getQ(); } bouncycastle-1.49.orig/src/org/bouncycastle/jce/interfaces/GOST3410Params.java0000644000175000017500000000054710324400067026463 0ustar ebourgebourgpackage org.bouncycastle.jce.interfaces; import org.bouncycastle.jce.spec.GOST3410PublicKeyParameterSetSpec; public interface GOST3410Params { public String getPublicKeyParamSetOID(); public String getDigestParamSetOID(); public String getEncryptionParamSetOID(); public GOST3410PublicKeyParameterSetSpec getPublicKeyParameters(); } bouncycastle-1.49.orig/src/org/bouncycastle/jce/interfaces/MQVPrivateKey.java0000644000175000017500000000112511275506021026676 0ustar ebourgebourgpackage org.bouncycastle.jce.interfaces; import java.security.PrivateKey; import java.security.PublicKey; /** * Static/ephemeral private key (pair) for use with ECMQV key agreement * (Optionally provides the ephemeral public key) */ public interface MQVPrivateKey extends PrivateKey { /** * return the static private key. */ PrivateKey getStaticPrivateKey(); /** * return the ephemeral private key. */ PrivateKey getEphemeralPrivateKey(); /** * return the ephemeral public key (may be null). */ PublicKey getEphemeralPublicKey(); } bouncycastle-1.49.orig/src/org/bouncycastle/jce/interfaces/ECPrivateKey.java0000644000175000017500000000046010262753175026534 0ustar ebourgebourgpackage org.bouncycastle.jce.interfaces; import java.math.BigInteger; import java.security.PrivateKey; /** * interface for Elliptic Curve Private keys. */ public interface ECPrivateKey extends ECKey, PrivateKey { /** * return the private value D. */ public BigInteger getD(); } bouncycastle-1.49.orig/src/org/bouncycastle/jce/interfaces/IESKey.java0000644000175000017500000000066310262753175025337 0ustar ebourgebourgpackage org.bouncycastle.jce.interfaces; import java.security.Key; import java.security.PrivateKey; import java.security.PublicKey; /** * key pair for use with an integrated encryptor */ public interface IESKey extends Key { /** * return the intended recipient's/sender's public key. */ public PublicKey getPublic(); /** * return the local private key. */ public PrivateKey getPrivate(); } bouncycastle-1.49.orig/src/org/bouncycastle/jce/interfaces/ElGamalKey.java0000644000175000017500000000026310262753175026215 0ustar ebourgebourgpackage org.bouncycastle.jce.interfaces; import org.bouncycastle.jce.spec.ElGamalParameterSpec; public interface ElGamalKey { public ElGamalParameterSpec getParameters(); } bouncycastle-1.49.orig/src/org/bouncycastle/jce/interfaces/ECKey.java0000644000175000017500000000051610262753175025203 0ustar ebourgebourgpackage org.bouncycastle.jce.interfaces; import org.bouncycastle.jce.spec.ECParameterSpec; /** * generic interface for an Elliptic Curve Key. */ public interface ECKey { /** * return a parameter specification representing the EC domain parameters * for the key. */ public ECParameterSpec getParameters(); } bouncycastle-1.49.orig/src/org/bouncycastle/jce/interfaces/MQVPublicKey.java0000644000175000017500000000057511275506021026512 0ustar ebourgebourgpackage org.bouncycastle.jce.interfaces; import java.security.PublicKey; /** * Static/ephemeral public key pair for use with ECMQV key agreement */ public interface MQVPublicKey extends PublicKey { /** * return the static public key. */ PublicKey getStaticKey(); /** * return the ephemeral public key. */ PublicKey getEphemeralKey(); } bouncycastle-1.49.orig/src/org/bouncycastle/jce/interfaces/ECPointEncoder.java0000644000175000017500000000124310404726070027032 0ustar ebourgebourgpackage org.bouncycastle.jce.interfaces; /** * All BC elliptic curve keys implement this interface. You need to * cast the key to get access to it. *

    * By default BC keys produce encodings without point compression, * to turn this on call setPointFormat() with "COMPRESSED". */ public interface ECPointEncoder { /** * Set the formatting for encoding of points. If the String "UNCOMPRESSED" is passed * in point compression will not be used. If the String "COMPRESSED" is passed point * compression will be used. The default is "UNCOMPRESSED". * * @param style the style to use. */ public void setPointFormat(String style); } bouncycastle-1.49.orig/src/org/bouncycastle/jce/interfaces/package.html0000644000175000017500000000020010262753175025647 0ustar ebourgebourg Interfaces for supporting Elliptic Curve Keys, El Gamal, and PKCS12 attributes. bouncycastle-1.49.orig/src/org/bouncycastle/jce/interfaces/PKCS12BagAttributeCarrier.java0000644000175000017500000000076711737275254030771 0ustar ebourgebourgpackage org.bouncycastle.jce.interfaces; import java.util.Enumeration; import org.bouncycastle.asn1.ASN1Encodable; import org.bouncycastle.asn1.ASN1ObjectIdentifier; /** * allow us to set attributes on objects that can go into a PKCS12 store. */ public interface PKCS12BagAttributeCarrier { void setBagAttribute( ASN1ObjectIdentifier oid, ASN1Encodable attribute); ASN1Encodable getBagAttribute( ASN1ObjectIdentifier oid); Enumeration getBagAttributeKeys(); } bouncycastle-1.49.orig/src/org/bouncycastle/jce/interfaces/GOST3410Key.java0000644000175000017500000000025210324400067025761 0ustar ebourgebourgpackage org.bouncycastle.jce.interfaces; /** * Main interface for a GOST 3410-94 key. */ public interface GOST3410Key { public GOST3410Params getParameters(); } bouncycastle-1.49.orig/src/org/bouncycastle/jce/netscape/0000755000175000017500000000000012152033551023042 5ustar ebourgebourgbouncycastle-1.49.orig/src/org/bouncycastle/jce/netscape/NetscapeCertRequest.java0000644000175000017500000002044311737274620027655 0ustar ebourgebourgpackage org.bouncycastle.jce.netscape; import java.io.ByteArrayInputStream; import java.io.ByteArrayOutputStream; import java.io.IOException; import java.security.InvalidKeyException; import java.security.KeyFactory; import java.security.NoSuchAlgorithmException; import java.security.NoSuchProviderException; import java.security.PrivateKey; import java.security.PublicKey; import java.security.SecureRandom; import java.security.Signature; import java.security.SignatureException; import java.security.spec.InvalidKeySpecException; import java.security.spec.X509EncodedKeySpec; import org.bouncycastle.asn1.ASN1EncodableVector; import org.bouncycastle.asn1.ASN1Encoding; import org.bouncycastle.asn1.ASN1InputStream; import org.bouncycastle.asn1.ASN1Object; import org.bouncycastle.asn1.ASN1Primitive; import org.bouncycastle.asn1.ASN1Sequence; import org.bouncycastle.asn1.DERBitString; import org.bouncycastle.asn1.DERIA5String; import org.bouncycastle.asn1.DERSequence; import org.bouncycastle.asn1.x509.AlgorithmIdentifier; import org.bouncycastle.asn1.x509.SubjectPublicKeyInfo; /** * * * Handles NetScape certificate request (KEYGEN), these are constructed as: *

    
     *   SignedPublicKeyAndChallenge ::= SEQUENCE {
     *     publicKeyAndChallenge    PublicKeyAndChallenge,
     *     signatureAlgorithm       AlgorithmIdentifier,
     *     signature                BIT STRING
     *   }
     * 
    * * PublicKey's encoded-format has to be X.509. * **/ public class NetscapeCertRequest extends ASN1Object { AlgorithmIdentifier sigAlg; AlgorithmIdentifier keyAlg; byte sigBits []; String challenge; DERBitString content; PublicKey pubkey ; private static ASN1Sequence getReq( byte[] r) throws IOException { ASN1InputStream aIn = new ASN1InputStream(new ByteArrayInputStream(r)); return ASN1Sequence.getInstance(aIn.readObject()); } public NetscapeCertRequest( byte[] req) throws IOException { this(getReq(req)); } public NetscapeCertRequest (ASN1Sequence spkac) { try { // // SignedPublicKeyAndChallenge ::= SEQUENCE { // publicKeyAndChallenge PublicKeyAndChallenge, // signatureAlgorithm AlgorithmIdentifier, // signature BIT STRING // } // if (spkac.size() != 3) { throw new IllegalArgumentException("invalid SPKAC (size):" + spkac.size()); } sigAlg = new AlgorithmIdentifier((ASN1Sequence)spkac .getObjectAt(1)); sigBits = ((DERBitString)spkac.getObjectAt(2)).getBytes(); // // PublicKeyAndChallenge ::= SEQUENCE { // spki SubjectPublicKeyInfo, // challenge IA5STRING // } // ASN1Sequence pkac = (ASN1Sequence)spkac.getObjectAt(0); if (pkac.size() != 2) { throw new IllegalArgumentException("invalid PKAC (len): " + pkac.size()); } challenge = ((DERIA5String)pkac.getObjectAt(1)).getString(); //this could be dangerous, as ASN.1 decoding/encoding //could potentially alter the bytes content = new DERBitString(pkac); SubjectPublicKeyInfo pubkeyinfo = new SubjectPublicKeyInfo( (ASN1Sequence)pkac.getObjectAt(0)); X509EncodedKeySpec xspec = new X509EncodedKeySpec(new DERBitString( pubkeyinfo).getBytes()); keyAlg = pubkeyinfo.getAlgorithmId(); pubkey = KeyFactory.getInstance(keyAlg.getObjectId().getId(), "BC") .generatePublic(xspec); } catch (Exception e) { throw new IllegalArgumentException(e.toString()); } } public NetscapeCertRequest( String challenge, AlgorithmIdentifier signing_alg, PublicKey pub_key) throws NoSuchAlgorithmException, InvalidKeySpecException, NoSuchProviderException { this.challenge = challenge; sigAlg = signing_alg; pubkey = pub_key; ASN1EncodableVector content_der = new ASN1EncodableVector(); content_der.add(getKeySpec()); //content_der.add(new SubjectPublicKeyInfo(sigAlg, new RSAPublicKeyStructure(pubkey.getModulus(), pubkey.getPublicExponent()).getDERObject())); content_der.add(new DERIA5String(challenge)); try { content = new DERBitString(new DERSequence(content_der)); } catch (IOException e) { throw new InvalidKeySpecException("exception encoding key: " + e.toString()); } } public String getChallenge() { return challenge; } public void setChallenge(String value) { challenge = value; } public AlgorithmIdentifier getSigningAlgorithm() { return sigAlg; } public void setSigningAlgorithm(AlgorithmIdentifier value) { sigAlg = value; } public AlgorithmIdentifier getKeyAlgorithm() { return keyAlg; } public void setKeyAlgorithm(AlgorithmIdentifier value) { keyAlg = value; } public PublicKey getPublicKey() { return pubkey; } public void setPublicKey(PublicKey value) { pubkey = value; } public boolean verify(String challenge) throws NoSuchAlgorithmException, InvalidKeyException, SignatureException, NoSuchProviderException { if (!challenge.equals(this.challenge)) { return false; } // // Verify the signature .. shows the response was generated // by someone who knew the associated private key // Signature sig = Signature.getInstance(sigAlg.getObjectId().getId(), "BC"); sig.initVerify(pubkey); sig.update(content.getBytes()); return sig.verify(sigBits); } public void sign(PrivateKey priv_key) throws NoSuchAlgorithmException, InvalidKeyException, SignatureException, NoSuchProviderException, InvalidKeySpecException { sign(priv_key, null); } public void sign(PrivateKey priv_key, SecureRandom rand) throws NoSuchAlgorithmException, InvalidKeyException, SignatureException, NoSuchProviderException, InvalidKeySpecException { Signature sig = Signature.getInstance(sigAlg.getAlgorithm().getId(), "BC"); if (rand != null) { sig.initSign(priv_key, rand); } else { sig.initSign(priv_key); } ASN1EncodableVector pkac = new ASN1EncodableVector(); pkac.add(getKeySpec()); pkac.add(new DERIA5String(challenge)); try { sig.update(new DERSequence(pkac).getEncoded(ASN1Encoding.DER)); } catch (IOException ioe) { throw new SignatureException(ioe.getMessage()); } sigBits = sig.sign(); } private ASN1Primitive getKeySpec() throws NoSuchAlgorithmException, InvalidKeySpecException, NoSuchProviderException { ByteArrayOutputStream baos = new ByteArrayOutputStream(); ASN1Primitive obj = null; try { baos.write(pubkey.getEncoded()); baos.close(); ASN1InputStream derin = new ASN1InputStream( new ByteArrayInputStream(baos.toByteArray())); obj = derin.readObject(); } catch (IOException ioe) { throw new InvalidKeySpecException(ioe.getMessage()); } return obj; } public ASN1Primitive toASN1Primitive() { ASN1EncodableVector spkac = new ASN1EncodableVector(); ASN1EncodableVector pkac = new ASN1EncodableVector(); try { pkac.add(getKeySpec()); } catch (Exception e) { //ignore } pkac.add(new DERIA5String(challenge)); spkac.add(new DERSequence(pkac)); spkac.add(sigAlg); spkac.add(new DERBitString(sigBits)); return new DERSequence(spkac); } } bouncycastle-1.49.orig/src/org/bouncycastle/jce/examples/0000755000175000017500000000000012152033551023056 5ustar ebourgebourgbouncycastle-1.49.orig/src/org/bouncycastle/jce/examples/PKCS12Example.java0000644000175000017500000004117711330176735026163 0ustar ebourgebourgpackage org.bouncycastle.jce.examples; import java.io.FileOutputStream; import java.math.BigInteger; import java.security.KeyFactory; import java.security.KeyStore; import java.security.PrivateKey; import java.security.PublicKey; import java.security.Security; import java.security.cert.Certificate; import java.security.cert.X509Certificate; import java.security.spec.RSAPrivateCrtKeySpec; import java.security.spec.RSAPublicKeySpec; import java.util.Date; import java.util.Hashtable; import java.util.Vector; import org.bouncycastle.asn1.DERBMPString; import org.bouncycastle.asn1.pkcs.PKCSObjectIdentifiers; import org.bouncycastle.asn1.x509.BasicConstraints; import org.bouncycastle.asn1.x509.X509Extensions; import org.bouncycastle.jce.PrincipalUtil; import org.bouncycastle.jce.X509Principal; import org.bouncycastle.jce.interfaces.PKCS12BagAttributeCarrier; import org.bouncycastle.jce.provider.BouncyCastleProvider; import org.bouncycastle.x509.X509V1CertificateGenerator; import org.bouncycastle.x509.X509V3CertificateGenerator; import org.bouncycastle.x509.extension.AuthorityKeyIdentifierStructure; import org.bouncycastle.x509.extension.SubjectKeyIdentifierStructure; /** * Example of how to set up a certificiate chain and a PKCS 12 store for * a private individual - obviously you'll need to generate your own keys, * and you may need to add a NetscapeCertType extension or add a key * usage extension depending on your application, but you should get the * idea! As always this is just an example... */ public class PKCS12Example { static char[] passwd = { 'h', 'e', 'l', 'l', 'o', ' ', 'w', 'o', 'r', 'l', 'd' }; static X509V1CertificateGenerator v1CertGen = new X509V1CertificateGenerator(); static X509V3CertificateGenerator v3CertGen = new X509V3CertificateGenerator(); /** * we generate the CA's certificate */ public static Certificate createMasterCert( PublicKey pubKey, PrivateKey privKey) throws Exception { // // signers name // String issuer = "C=AU, O=The Legion of the Bouncy Castle, OU=Bouncy Primary Certificate"; // // subjects name - the same as we are self signed. // String subject = "C=AU, O=The Legion of the Bouncy Castle, OU=Bouncy Primary Certificate"; // // create the certificate - version 1 // v1CertGen.setSerialNumber(BigInteger.valueOf(1)); v1CertGen.setIssuerDN(new X509Principal(issuer)); v1CertGen.setNotBefore(new Date(System.currentTimeMillis() - 1000L * 60 * 60 * 24 * 30)); v1CertGen.setNotAfter(new Date(System.currentTimeMillis() + (1000L * 60 * 60 * 24 * 30))); v1CertGen.setSubjectDN(new X509Principal(subject)); v1CertGen.setPublicKey(pubKey); v1CertGen.setSignatureAlgorithm("SHA1WithRSAEncryption"); X509Certificate cert = v1CertGen.generate(privKey); cert.checkValidity(new Date()); cert.verify(pubKey); PKCS12BagAttributeCarrier bagAttr = (PKCS12BagAttributeCarrier)cert; // // this is actually optional - but if you want to have control // over setting the friendly name this is the way to do it... // bagAttr.setBagAttribute( PKCSObjectIdentifiers.pkcs_9_at_friendlyName, new DERBMPString("Bouncy Primary Certificate")); return cert; } /** * we generate an intermediate certificate signed by our CA */ public static Certificate createIntermediateCert( PublicKey pubKey, PrivateKey caPrivKey, X509Certificate caCert) throws Exception { // // subject name table. // Hashtable attrs = new Hashtable(); Vector order = new Vector(); attrs.put(X509Principal.C, "AU"); attrs.put(X509Principal.O, "The Legion of the Bouncy Castle"); attrs.put(X509Principal.OU, "Bouncy Intermediate Certificate"); attrs.put(X509Principal.EmailAddress, "feedback-crypto@bouncycastle.org"); order.addElement(X509Principal.C); order.addElement(X509Principal.O); order.addElement(X509Principal.OU); order.addElement(X509Principal.EmailAddress); // // create the certificate - version 3 // v3CertGen.reset(); v3CertGen.setSerialNumber(BigInteger.valueOf(2)); v3CertGen.setIssuerDN(PrincipalUtil.getSubjectX509Principal(caCert)); v3CertGen.setNotBefore(new Date(System.currentTimeMillis() - 1000L * 60 * 60 * 24 * 30)); v3CertGen.setNotAfter(new Date(System.currentTimeMillis() + (1000L * 60 * 60 * 24 * 30))); v3CertGen.setSubjectDN(new X509Principal(order, attrs)); v3CertGen.setPublicKey(pubKey); v3CertGen.setSignatureAlgorithm("SHA1WithRSAEncryption"); // // extensions // v3CertGen.addExtension( X509Extensions.SubjectKeyIdentifier, false, new SubjectKeyIdentifierStructure(pubKey)); v3CertGen.addExtension( X509Extensions.AuthorityKeyIdentifier, false, new AuthorityKeyIdentifierStructure(caCert)); v3CertGen.addExtension( X509Extensions.BasicConstraints, true, new BasicConstraints(0)); X509Certificate cert = v3CertGen.generate(caPrivKey); cert.checkValidity(new Date()); cert.verify(caCert.getPublicKey()); PKCS12BagAttributeCarrier bagAttr = (PKCS12BagAttributeCarrier)cert; // // this is actually optional - but if you want to have control // over setting the friendly name this is the way to do it... // bagAttr.setBagAttribute( PKCSObjectIdentifiers.pkcs_9_at_friendlyName, new DERBMPString("Bouncy Intermediate Certificate")); return cert; } /** * we generate a certificate signed by our CA's intermediate certficate */ public static Certificate createCert( PublicKey pubKey, PrivateKey caPrivKey, PublicKey caPubKey) throws Exception { // // signers name table. // Hashtable sAttrs = new Hashtable(); Vector sOrder = new Vector(); sAttrs.put(X509Principal.C, "AU"); sAttrs.put(X509Principal.O, "The Legion of the Bouncy Castle"); sAttrs.put(X509Principal.OU, "Bouncy Intermediate Certificate"); sAttrs.put(X509Principal.EmailAddress, "feedback-crypto@bouncycastle.org"); sOrder.addElement(X509Principal.C); sOrder.addElement(X509Principal.O); sOrder.addElement(X509Principal.OU); sOrder.addElement(X509Principal.EmailAddress); // // subjects name table. // Hashtable attrs = new Hashtable(); Vector order = new Vector(); attrs.put(X509Principal.C, "AU"); attrs.put(X509Principal.O, "The Legion of the Bouncy Castle"); attrs.put(X509Principal.L, "Melbourne"); attrs.put(X509Principal.CN, "Eric H. Echidna"); attrs.put(X509Principal.EmailAddress, "feedback-crypto@bouncycastle.org"); order.addElement(X509Principal.C); order.addElement(X509Principal.O); order.addElement(X509Principal.L); order.addElement(X509Principal.CN); order.addElement(X509Principal.EmailAddress); // // create the certificate - version 3 // v3CertGen.reset(); v3CertGen.setSerialNumber(BigInteger.valueOf(3)); v3CertGen.setIssuerDN(new X509Principal(sOrder, sAttrs)); v3CertGen.setNotBefore(new Date(System.currentTimeMillis() - 1000L * 60 * 60 * 24 * 30)); v3CertGen.setNotAfter(new Date(System.currentTimeMillis() + (1000L * 60 * 60 * 24 * 30))); v3CertGen.setSubjectDN(new X509Principal(order, attrs)); v3CertGen.setPublicKey(pubKey); v3CertGen.setSignatureAlgorithm("SHA1WithRSAEncryption"); // // add the extensions // v3CertGen.addExtension( X509Extensions.SubjectKeyIdentifier, false, new SubjectKeyIdentifierStructure(pubKey)); v3CertGen.addExtension( X509Extensions.AuthorityKeyIdentifier, false, new AuthorityKeyIdentifierStructure(caPubKey)); X509Certificate cert = v3CertGen.generate(caPrivKey); cert.checkValidity(new Date()); cert.verify(caPubKey); PKCS12BagAttributeCarrier bagAttr = (PKCS12BagAttributeCarrier)cert; // // this is also optional - in the sense that if you leave this // out the keystore will add it automatically, note though that // for the browser to recognise the associated private key this // you should at least use the pkcs_9_localKeyId OID and set it // to the same as you do for the private key's localKeyId. // bagAttr.setBagAttribute( PKCSObjectIdentifiers.pkcs_9_at_friendlyName, new DERBMPString("Eric's Key")); bagAttr.setBagAttribute( PKCSObjectIdentifiers.pkcs_9_at_localKeyId, new SubjectKeyIdentifierStructure(pubKey)); return cert; } public static void main( String[] args) throws Exception { Security.addProvider(new BouncyCastleProvider()); // // personal keys // RSAPublicKeySpec pubKeySpec = new RSAPublicKeySpec( new BigInteger("b4a7e46170574f16a97082b22be58b6a2a629798419be12872a4bdba626cfae9900f76abfb12139dce5de56564fab2b6543165a040c606887420e33d91ed7ed7", 16), new BigInteger("11", 16)); RSAPrivateCrtKeySpec privKeySpec = new RSAPrivateCrtKeySpec( new BigInteger("b4a7e46170574f16a97082b22be58b6a2a629798419be12872a4bdba626cfae9900f76abfb12139dce5de56564fab2b6543165a040c606887420e33d91ed7ed7", 16), new BigInteger("11", 16), new BigInteger("9f66f6b05410cd503b2709e88115d55daced94d1a34d4e32bf824d0dde6028ae79c5f07b580f5dce240d7111f7ddb130a7945cd7d957d1920994da389f490c89", 16), new BigInteger("c0a0758cdf14256f78d4708c86becdead1b50ad4ad6c5c703e2168fbf37884cb", 16), new BigInteger("f01734d7960ea60070f1b06f2bb81bfac48ff192ae18451d5e56c734a5aab8a5", 16), new BigInteger("b54bb9edff22051d9ee60f9351a48591b6500a319429c069a3e335a1d6171391", 16), new BigInteger("d3d83daf2a0cecd3367ae6f8ae1aeb82e9ac2f816c6fc483533d8297dd7884cd", 16), new BigInteger("b8f52fc6f38593dabb661d3f50f8897f8106eee68b1bce78a95b132b4e5b5d19", 16)); // // intermediate keys. // RSAPublicKeySpec intPubKeySpec = new RSAPublicKeySpec( new BigInteger("8de0d113c5e736969c8d2b047a243f8fe18edad64cde9e842d3669230ca486f7cfdde1f8eec54d1905fff04acc85e61093e180cadc6cea407f193d44bb0e9449b8dbb49784cd9e36260c39e06a947299978c6ed8300724e887198cfede20f3fbde658fa2bd078be946a392bd349f2b49c486e20c405588e306706c9017308e69", 16), new BigInteger("ffff", 16)); RSAPrivateCrtKeySpec intPrivKeySpec = new RSAPrivateCrtKeySpec( new BigInteger("8de0d113c5e736969c8d2b047a243f8fe18edad64cde9e842d3669230ca486f7cfdde1f8eec54d1905fff04acc85e61093e180cadc6cea407f193d44bb0e9449b8dbb49784cd9e36260c39e06a947299978c6ed8300724e887198cfede20f3fbde658fa2bd078be946a392bd349f2b49c486e20c405588e306706c9017308e69", 16), new BigInteger("ffff", 16), new BigInteger("7deb1b194a85bcfd29cf871411468adbc987650903e3bacc8338c449ca7b32efd39ffc33bc84412fcd7df18d23ce9d7c25ea910b1ae9985373e0273b4dca7f2e0db3b7314056ac67fd277f8f89cf2fd73c34c6ca69f9ba477143d2b0e2445548aa0b4a8473095182631da46844c356f5e5c7522eb54b5a33f11d730ead9c0cff", 16), new BigInteger("ef4cede573cea47f83699b814de4302edb60eefe426c52e17bd7870ec7c6b7a24fe55282ebb73775f369157726fcfb988def2b40350bdca9e5b418340288f649", 16), new BigInteger("97c7737d1b9a0088c3c7b528539247fd2a1593e7e01cef18848755be82f4a45aa093276cb0cbf118cb41117540a78f3fc471ba5d69f0042274defc9161265721", 16), new BigInteger("6c641094e24d172728b8da3c2777e69adfd0839085be7e38c7c4a2dd00b1ae969f2ec9d23e7e37090fcd449a40af0ed463fe1c612d6810d6b4f58b7bfa31eb5f", 16), new BigInteger("70b7123e8e69dfa76feb1236d0a686144b00e9232ed52b73847e74ef3af71fb45ccb24261f40d27f98101e230cf27b977a5d5f1f15f6cf48d5cb1da2a3a3b87f", 16), new BigInteger("e38f5750d97e270996a286df2e653fd26c242106436f5bab0f4c7a9e654ce02665d5a281f2c412456f2d1fa26586ef04a9adac9004ca7f913162cb28e13bf40d", 16)); // // ca keys // RSAPublicKeySpec caPubKeySpec = new RSAPublicKeySpec( new BigInteger("b259d2d6e627a768c94be36164c2d9fc79d97aab9253140e5bf17751197731d6f7540d2509e7b9ffee0a70a6e26d56e92d2edd7f85aba85600b69089f35f6bdbf3c298e05842535d9f064e6b0391cb7d306e0a2d20c4dfb4e7b49a9640bdea26c10ad69c3f05007ce2513cee44cfe01998e62b6c3637d3fc0391079b26ee36d5", 16), new BigInteger("11", 16)); RSAPrivateCrtKeySpec caPrivKeySpec = new RSAPrivateCrtKeySpec( new BigInteger("b259d2d6e627a768c94be36164c2d9fc79d97aab9253140e5bf17751197731d6f7540d2509e7b9ffee0a70a6e26d56e92d2edd7f85aba85600b69089f35f6bdbf3c298e05842535d9f064e6b0391cb7d306e0a2d20c4dfb4e7b49a9640bdea26c10ad69c3f05007ce2513cee44cfe01998e62b6c3637d3fc0391079b26ee36d5", 16), new BigInteger("11", 16), new BigInteger("92e08f83cc9920746989ca5034dcb384a094fb9c5a6288fcc4304424ab8f56388f72652d8fafc65a4b9020896f2cde297080f2a540e7b7ce5af0b3446e1258d1dd7f245cf54124b4c6e17da21b90a0ebd22605e6f45c9f136d7a13eaac1c0f7487de8bd6d924972408ebb58af71e76fd7b012a8d0e165f3ae2e5077a8648e619", 16), new BigInteger("f75e80839b9b9379f1cf1128f321639757dba514642c206bbbd99f9a4846208b3e93fbbe5e0527cc59b1d4b929d9555853004c7c8b30ee6a213c3d1bb7415d03", 16), new BigInteger("b892d9ebdbfc37e397256dd8a5d3123534d1f03726284743ddc6be3a709edb696fc40c7d902ed804c6eee730eee3d5b20bf6bd8d87a296813c87d3b3cc9d7947", 16), new BigInteger("1d1a2d3ca8e52068b3094d501c9a842fec37f54db16e9a67070a8b3f53cc03d4257ad252a1a640eadd603724d7bf3737914b544ae332eedf4f34436cac25ceb5", 16), new BigInteger("6c929e4e81672fef49d9c825163fec97c4b7ba7acb26c0824638ac22605d7201c94625770984f78a56e6e25904fe7db407099cad9b14588841b94f5ab498dded", 16), new BigInteger("dae7651ee69ad1d081ec5e7188ae126f6004ff39556bde90e0b870962fa7b926d070686d8244fe5a9aa709a95686a104614834b0ada4b10f53197a5cb4c97339", 16)); // // set up the keys // KeyFactory fact = KeyFactory.getInstance("RSA", "BC"); PrivateKey caPrivKey = fact.generatePrivate(caPrivKeySpec); PublicKey caPubKey = fact.generatePublic(caPubKeySpec); PrivateKey intPrivKey = fact.generatePrivate(intPrivKeySpec); PublicKey intPubKey = fact.generatePublic(intPubKeySpec); PrivateKey privKey = fact.generatePrivate(privKeySpec); PublicKey pubKey = fact.generatePublic(pubKeySpec); Certificate[] chain = new Certificate[3]; chain[2] = createMasterCert(caPubKey, caPrivKey); chain[1] = createIntermediateCert(intPubKey, caPrivKey, (X509Certificate)chain[2]); chain[0] = createCert(pubKey, intPrivKey, intPubKey); // // add the friendly name for the private key // PKCS12BagAttributeCarrier bagAttr = (PKCS12BagAttributeCarrier)privKey; // // this is also optional - in the sense that if you leave this // out the keystore will add it automatically, note though that // for the browser to recognise which certificate the private key // is associated with you should at least use the pkcs_9_localKeyId // OID and set it to the same as you do for the private key's // corresponding certificate. // bagAttr.setBagAttribute( PKCSObjectIdentifiers.pkcs_9_at_friendlyName, new DERBMPString("Eric's Key")); bagAttr.setBagAttribute( PKCSObjectIdentifiers.pkcs_9_at_localKeyId, new SubjectKeyIdentifierStructure(pubKey)); // // store the key and the certificate chain // KeyStore store = KeyStore.getInstance("PKCS12", "BC"); store.load(null, null); // // if you haven't set the friendly name and local key id above // the name below will be the name of the key // store.setKeyEntry("Eric's Key", privKey, null, chain); FileOutputStream fOut = new FileOutputStream("id.p12"); store.store(fOut, passwd); fOut.close(); } } bouncycastle-1.49.orig/src/org/bouncycastle/jce/examples/package.html0000644000175000017500000000012610262753175025351 0ustar ebourgebourg Example classes for use with the JCE. bouncycastle-1.49.orig/src/org/bouncycastle/jce/PKCS12Util.java0000644000175000017500000001031212103437526023647 0ustar ebourgebourgpackage org.bouncycastle.jce; import java.io.ByteArrayOutputStream; import java.io.IOException; import javax.crypto.Mac; import javax.crypto.SecretKey; import javax.crypto.SecretKeyFactory; import javax.crypto.spec.PBEKeySpec; import javax.crypto.spec.PBEParameterSpec; import org.bouncycastle.asn1.ASN1InputStream; import org.bouncycastle.asn1.ASN1OctetString; import org.bouncycastle.asn1.ASN1Primitive; import org.bouncycastle.asn1.DERNull; import org.bouncycastle.asn1.DERObjectIdentifier; import org.bouncycastle.asn1.DEROctetString; import org.bouncycastle.asn1.DEROutputStream; import org.bouncycastle.asn1.pkcs.ContentInfo; import org.bouncycastle.asn1.pkcs.MacData; import org.bouncycastle.asn1.pkcs.Pfx; import org.bouncycastle.asn1.x509.AlgorithmIdentifier; import org.bouncycastle.asn1.x509.DigestInfo; /** * Utility class for reencoding PKCS#12 files to definite length. */ public class PKCS12Util { /** * Just re-encode the outer layer of the PKCS#12 file to definite length encoding. * * @param berPKCS12File - original PKCS#12 file * @return a byte array representing the DER encoding of the PFX structure * @throws IOException */ public static byte[] convertToDefiniteLength(byte[] berPKCS12File) throws IOException { ByteArrayOutputStream bOut = new ByteArrayOutputStream(); DEROutputStream dOut = new DEROutputStream(bOut); Pfx pfx = Pfx.getInstance(berPKCS12File); bOut.reset(); dOut.writeObject(pfx); return bOut.toByteArray(); } /** * Re-encode the PKCS#12 structure to definite length encoding at the inner layer * as well, recomputing the MAC accordingly. * * @param berPKCS12File - original PKCS12 file. * @param provider - provider to use for MAC calculation. * @return a byte array representing the DER encoding of the PFX structure. * @throws IOException on parsing, encoding errors. */ public static byte[] convertToDefiniteLength(byte[] berPKCS12File, char[] passwd, String provider) throws IOException { Pfx pfx = Pfx.getInstance(berPKCS12File); ContentInfo info = pfx.getAuthSafe(); ASN1OctetString content = ASN1OctetString.getInstance(info.getContent()); ByteArrayOutputStream bOut = new ByteArrayOutputStream(); DEROutputStream dOut = new DEROutputStream(bOut); ASN1InputStream contentIn = new ASN1InputStream(content.getOctets()); ASN1Primitive obj = contentIn.readObject(); dOut.writeObject(obj); info = new ContentInfo(info.getContentType(), new DEROctetString(bOut.toByteArray())); MacData mData = pfx.getMacData(); try { int itCount = mData.getIterationCount().intValue(); byte[] data = ASN1OctetString.getInstance(info.getContent()).getOctets(); byte[] res = calculatePbeMac(mData.getMac().getAlgorithmId().getObjectId(), mData.getSalt(), itCount, passwd, data, provider); AlgorithmIdentifier algId = new AlgorithmIdentifier(mData.getMac().getAlgorithmId().getObjectId(), DERNull.INSTANCE); DigestInfo dInfo = new DigestInfo(algId, res); mData = new MacData(dInfo, mData.getSalt(), itCount); } catch (Exception e) { throw new IOException("error constructing MAC: " + e.toString()); } pfx = new Pfx(info, mData); bOut.reset(); dOut.writeObject(pfx); return bOut.toByteArray(); } private static byte[] calculatePbeMac( DERObjectIdentifier oid, byte[] salt, int itCount, char[] password, byte[] data, String provider) throws Exception { SecretKeyFactory keyFact = SecretKeyFactory.getInstance(oid.getId(), provider); PBEParameterSpec defParams = new PBEParameterSpec(salt, itCount); PBEKeySpec pbeSpec = new PBEKeySpec(password); SecretKey key = keyFact.generateSecret(pbeSpec); Mac mac = Mac.getInstance(oid.getId(), provider); mac.init(key, defParams); mac.update(data); return mac.doFinal(); } } bouncycastle-1.49.orig/src/org/bouncycastle/jce/ECKeyUtil.java0000644000175000017500000002126112110037231023674 0ustar ebourgebourgpackage org.bouncycastle.jce; import java.io.UnsupportedEncodingException; import java.security.KeyFactory; import java.security.NoSuchAlgorithmException; import java.security.NoSuchProviderException; import java.security.PrivateKey; import java.security.Provider; import java.security.PublicKey; import java.security.Security; import java.security.spec.PKCS8EncodedKeySpec; import java.security.spec.X509EncodedKeySpec; import org.bouncycastle.asn1.ASN1ObjectIdentifier; import org.bouncycastle.asn1.ASN1Primitive; import org.bouncycastle.asn1.cryptopro.CryptoProObjectIdentifiers; import org.bouncycastle.asn1.pkcs.PrivateKeyInfo; import org.bouncycastle.asn1.x509.AlgorithmIdentifier; import org.bouncycastle.asn1.x509.SubjectPublicKeyInfo; import org.bouncycastle.asn1.x9.X962Parameters; import org.bouncycastle.asn1.x9.X9ECParameters; import org.bouncycastle.asn1.x9.X9ObjectIdentifiers; import org.bouncycastle.jcajce.provider.asymmetric.util.ECUtil; import org.bouncycastle.jce.provider.BouncyCastleProvider; /** * Utility class to allow conversion of EC key parameters to explicit from named * curves and back (where possible). */ public class ECKeyUtil { /** * Convert a passed in public EC key to have explicit parameters. If the key * is already using explicit parameters it is returned. * * @param key key to be converted * @param providerName provider name to be used. * @return the equivalent key with explicit curve parameters * @throws IllegalArgumentException * @throws NoSuchAlgorithmException * @throws NoSuchProviderException */ public static PublicKey publicToExplicitParameters(PublicKey key, String providerName) throws IllegalArgumentException, NoSuchAlgorithmException, NoSuchProviderException { Provider provider = Security.getProvider(providerName); if (provider == null) { throw new NoSuchProviderException("cannot find provider: " + providerName); } return publicToExplicitParameters(key, provider); } /** * Convert a passed in public EC key to have explicit parameters. If the key * is already using explicit parameters it is returned. * * @param key key to be converted * @param provider provider to be used. * @return the equivalent key with explicit curve parameters * @throws IllegalArgumentException * @throws NoSuchAlgorithmException */ public static PublicKey publicToExplicitParameters(PublicKey key, Provider provider) throws IllegalArgumentException, NoSuchAlgorithmException { try { SubjectPublicKeyInfo info = SubjectPublicKeyInfo.getInstance(ASN1Primitive.fromByteArray(key.getEncoded())); if (info.getAlgorithmId().getObjectId().equals(CryptoProObjectIdentifiers.gostR3410_2001)) { throw new IllegalArgumentException("cannot convert GOST key to explicit parameters."); } else { X962Parameters params = X962Parameters.getInstance(info.getAlgorithmId().getParameters()); X9ECParameters curveParams; if (params.isNamedCurve()) { ASN1ObjectIdentifier oid = ASN1ObjectIdentifier.getInstance(params.getParameters()); curveParams = ECUtil.getNamedCurveByOid(oid); // ignore seed value due to JDK bug curveParams = new X9ECParameters(curveParams.getCurve(), curveParams.getG(), curveParams.getN(), curveParams.getH()); } else if (params.isImplicitlyCA()) { curveParams = new X9ECParameters(BouncyCastleProvider.CONFIGURATION.getEcImplicitlyCa().getCurve(), BouncyCastleProvider.CONFIGURATION.getEcImplicitlyCa().getG(), BouncyCastleProvider.CONFIGURATION.getEcImplicitlyCa().getN(), BouncyCastleProvider.CONFIGURATION.getEcImplicitlyCa().getH()); } else { return key; // already explicit } params = new X962Parameters(curveParams); info = new SubjectPublicKeyInfo(new AlgorithmIdentifier(X9ObjectIdentifiers.id_ecPublicKey, params), info.getPublicKeyData().getBytes()); KeyFactory keyFact = KeyFactory.getInstance(key.getAlgorithm(), provider); return keyFact.generatePublic(new X509EncodedKeySpec(info.getEncoded())); } } catch (IllegalArgumentException e) { throw e; } catch (NoSuchAlgorithmException e) { throw e; } catch (Exception e) { // shouldn't really happen... throw new UnexpectedException(e); } } /** * Convert a passed in private EC key to have explicit parameters. If the key * is already using explicit parameters it is returned. * * @param key key to be converted * @param providerName provider name to be used. * @return the equivalent key with explicit curve parameters * @throws IllegalArgumentException * @throws NoSuchAlgorithmException * @throws NoSuchProviderException */ public static PrivateKey privateToExplicitParameters(PrivateKey key, String providerName) throws IllegalArgumentException, NoSuchAlgorithmException, NoSuchProviderException { Provider provider = Security.getProvider(providerName); if (provider == null) { throw new NoSuchProviderException("cannot find provider: " + providerName); } return privateToExplicitParameters(key, provider); } /** * Convert a passed in private EC key to have explicit parameters. If the key * is already using explicit parameters it is returned. * * @param key key to be converted * @param provider provider to be used. * @return the equivalent key with explicit curve parameters * @throws IllegalArgumentException * @throws NoSuchAlgorithmException */ public static PrivateKey privateToExplicitParameters(PrivateKey key, Provider provider) throws IllegalArgumentException, NoSuchAlgorithmException { try { PrivateKeyInfo info = PrivateKeyInfo.getInstance(ASN1Primitive.fromByteArray(key.getEncoded())); if (info.getAlgorithmId().getObjectId().equals(CryptoProObjectIdentifiers.gostR3410_2001)) { throw new UnsupportedEncodingException("cannot convert GOST key to explicit parameters."); } else { X962Parameters params = X962Parameters.getInstance(info.getAlgorithmId().getParameters()); X9ECParameters curveParams; if (params.isNamedCurve()) { ASN1ObjectIdentifier oid = ASN1ObjectIdentifier.getInstance(params.getParameters()); curveParams = ECUtil.getNamedCurveByOid(oid); // ignore seed value due to JDK bug curveParams = new X9ECParameters(curveParams.getCurve(), curveParams.getG(), curveParams.getN(), curveParams.getH()); } else if (params.isImplicitlyCA()) { curveParams = new X9ECParameters(BouncyCastleProvider.CONFIGURATION.getEcImplicitlyCa().getCurve(), BouncyCastleProvider.CONFIGURATION.getEcImplicitlyCa().getG(), BouncyCastleProvider.CONFIGURATION.getEcImplicitlyCa().getN(), BouncyCastleProvider.CONFIGURATION.getEcImplicitlyCa().getH()); } else { return key; // already explicit } params = new X962Parameters(curveParams); info = new PrivateKeyInfo(new AlgorithmIdentifier(X9ObjectIdentifiers.id_ecPublicKey, params), info.parsePrivateKey()); KeyFactory keyFact = KeyFactory.getInstance(key.getAlgorithm(), provider); return keyFact.generatePrivate(new PKCS8EncodedKeySpec(info.getEncoded())); } } catch (IllegalArgumentException e) { throw e; } catch (NoSuchAlgorithmException e) { throw e; } catch (Exception e) { // shouldn't really happen throw new UnexpectedException(e); } } private static class UnexpectedException extends RuntimeException { private Throwable cause; UnexpectedException(Throwable cause) { super(cause.toString()); this.cause = cause; } public Throwable getCause() { return cause; } } } bouncycastle-1.49.orig/src/org/bouncycastle/jce/X509LDAPCertStoreParameters.java0000644000175000017500000015744410525535570027121 0ustar ebourgebourgpackage org.bouncycastle.jce; import org.bouncycastle.x509.X509StoreParameters; import java.security.cert.CertStoreParameters; import java.security.cert.LDAPCertStoreParameters; /** * An expanded set of parameters for an LDAPCertStore */ public class X509LDAPCertStoreParameters implements X509StoreParameters, CertStoreParameters { private String ldapURL; private String baseDN; // LDAP attributes, where data is stored private String userCertificateAttribute; private String cACertificateAttribute; private String crossCertificateAttribute; private String certificateRevocationListAttribute; private String deltaRevocationListAttribute; private String authorityRevocationListAttribute; private String attributeCertificateAttributeAttribute; private String aACertificateAttribute; private String attributeDescriptorCertificateAttribute; private String attributeCertificateRevocationListAttribute; private String attributeAuthorityRevocationListAttribute; // LDAP attributes with which data can be found private String ldapUserCertificateAttributeName; private String ldapCACertificateAttributeName; private String ldapCrossCertificateAttributeName; private String ldapCertificateRevocationListAttributeName; private String ldapDeltaRevocationListAttributeName; private String ldapAuthorityRevocationListAttributeName; private String ldapAttributeCertificateAttributeAttributeName; private String ldapAACertificateAttributeName; private String ldapAttributeDescriptorCertificateAttributeName; private String ldapAttributeCertificateRevocationListAttributeName; private String ldapAttributeAuthorityRevocationListAttributeName; // certificates and CRLs subject or issuer DN attributes, which must be // matched against ldap attribute names private String userCertificateSubjectAttributeName; private String cACertificateSubjectAttributeName; private String crossCertificateSubjectAttributeName; private String certificateRevocationListIssuerAttributeName; private String deltaRevocationListIssuerAttributeName; private String authorityRevocationListIssuerAttributeName; private String attributeCertificateAttributeSubjectAttributeName; private String aACertificateSubjectAttributeName; private String attributeDescriptorCertificateSubjectAttributeName; private String attributeCertificateRevocationListIssuerAttributeName; private String attributeAuthorityRevocationListIssuerAttributeName; private String searchForSerialNumberIn; public static class Builder { private String ldapURL; private String baseDN; // LDAP attributes, where data is stored private String userCertificateAttribute; private String cACertificateAttribute; private String crossCertificateAttribute; private String certificateRevocationListAttribute; private String deltaRevocationListAttribute; private String authorityRevocationListAttribute; private String attributeCertificateAttributeAttribute; private String aACertificateAttribute; private String attributeDescriptorCertificateAttribute; private String attributeCertificateRevocationListAttribute; private String attributeAuthorityRevocationListAttribute; // LDAP attributes with which data can be found private String ldapUserCertificateAttributeName; private String ldapCACertificateAttributeName; private String ldapCrossCertificateAttributeName; private String ldapCertificateRevocationListAttributeName; private String ldapDeltaRevocationListAttributeName; private String ldapAuthorityRevocationListAttributeName; private String ldapAttributeCertificateAttributeAttributeName; private String ldapAACertificateAttributeName; private String ldapAttributeDescriptorCertificateAttributeName; private String ldapAttributeCertificateRevocationListAttributeName; private String ldapAttributeAuthorityRevocationListAttributeName; // certificates and CRLs subject or issuer DN attributes, which must be // matched against ldap attribute names private String userCertificateSubjectAttributeName; private String cACertificateSubjectAttributeName; private String crossCertificateSubjectAttributeName; private String certificateRevocationListIssuerAttributeName; private String deltaRevocationListIssuerAttributeName; private String authorityRevocationListIssuerAttributeName; private String attributeCertificateAttributeSubjectAttributeName; private String aACertificateSubjectAttributeName; private String attributeDescriptorCertificateSubjectAttributeName; private String attributeCertificateRevocationListIssuerAttributeName; private String attributeAuthorityRevocationListIssuerAttributeName; private String searchForSerialNumberIn; public Builder() { this("ldap://localhost:389", ""); } public Builder(String ldapURL, String baseDN) { this.ldapURL = ldapURL; if (baseDN == null) { this.baseDN = ""; } else { this.baseDN = baseDN; } this.userCertificateAttribute = "userCertificate"; this.cACertificateAttribute = "cACertificate"; this.crossCertificateAttribute = "crossCertificatePair"; this.certificateRevocationListAttribute = "certificateRevocationList"; this.deltaRevocationListAttribute = "deltaRevocationList"; this.authorityRevocationListAttribute = "authorityRevocationList"; this.attributeCertificateAttributeAttribute = "attributeCertificateAttribute"; this.aACertificateAttribute = "aACertificate"; this.attributeDescriptorCertificateAttribute = "attributeDescriptorCertificate"; this.attributeCertificateRevocationListAttribute = "attributeCertificateRevocationList"; this.attributeAuthorityRevocationListAttribute = "attributeAuthorityRevocationList"; this.ldapUserCertificateAttributeName = "cn"; this.ldapCACertificateAttributeName = "cn ou o"; this.ldapCrossCertificateAttributeName = "cn ou o"; this.ldapCertificateRevocationListAttributeName = "cn ou o"; this.ldapDeltaRevocationListAttributeName = "cn ou o"; this.ldapAuthorityRevocationListAttributeName = "cn ou o"; this.ldapAttributeCertificateAttributeAttributeName = "cn"; this.ldapAACertificateAttributeName = "cn o ou"; this.ldapAttributeDescriptorCertificateAttributeName = "cn o ou"; this.ldapAttributeCertificateRevocationListAttributeName = "cn o ou"; this.ldapAttributeAuthorityRevocationListAttributeName = "cn o ou"; this.userCertificateSubjectAttributeName = "cn"; this.cACertificateSubjectAttributeName = "o ou"; this.crossCertificateSubjectAttributeName = "o ou"; this.certificateRevocationListIssuerAttributeName = "o ou"; this.deltaRevocationListIssuerAttributeName = "o ou"; this.authorityRevocationListIssuerAttributeName = "o ou"; this.attributeCertificateAttributeSubjectAttributeName = "cn"; this.aACertificateSubjectAttributeName = "o ou"; this.attributeDescriptorCertificateSubjectAttributeName = "o ou"; this.attributeCertificateRevocationListIssuerAttributeName = "o ou"; this.attributeAuthorityRevocationListIssuerAttributeName = "o ou"; this.searchForSerialNumberIn = "uid serialNumber cn"; } /** * @param userCertificateAttribute Attribute name(s) in the LDAP directory where end certificates * are stored. Separated by space. Defaults to "userCertificate" * if null. * @throws IllegalArgumentException if a necessary parameter is null. * @return the builder */ public Builder setUserCertificateAttribute(String userCertificateAttribute) { this.userCertificateAttribute = userCertificateAttribute; return this; } /** * @param cACertificateAttribute Attribute name(s) in the LDAP directory where CA certificates * are stored. Separated by space. Defaults to "cACertificate" if * null. * @throws IllegalArgumentException if a necessary parameter is null. * @return the builder */ public Builder setCACertificateAttribute(String cACertificateAttribute) { this.cACertificateAttribute = cACertificateAttribute; return this; } /** * @param crossCertificateAttribute Attribute name(s), where the cross certificates are stored. * Separated by space. Defaults to "crossCertificatePair" if * null * @throws IllegalArgumentException if a necessary parameter is null. * @return the builder */ public Builder setCrossCertificateAttribute(String crossCertificateAttribute) { this.crossCertificateAttribute = crossCertificateAttribute; return this; } /** * @param certificateRevocationListAttribute * Attribute name(s) in the LDAP directory where CRLs are stored. * Separated by space. Defaults to "certificateRevocationList" if * null. * @throws IllegalArgumentException if a necessary parameter is null. * @return the builder */ public Builder setCertificateRevocationListAttribute(String certificateRevocationListAttribute) { this.certificateRevocationListAttribute = certificateRevocationListAttribute; return this; } /** * @param deltaRevocationListAttribute Attribute name(s) in the LDAP directory where delta RLs are * stored. Separated by space. Defaults to "deltaRevocationList" * if null. * @throws IllegalArgumentException if a necessary parameter is null. * @return the builder */ public Builder setDeltaRevocationListAttribute(String deltaRevocationListAttribute) { this.deltaRevocationListAttribute = deltaRevocationListAttribute; return this; } /** * @param authorityRevocationListAttribute * Attribute name(s) in the LDAP directory where CRLs for * authorities are stored. Separated by space. Defaults to * "authorityRevocationList" if null. * @throws IllegalArgumentException if a necessary parameter is null. * @return the builder */ public Builder setAuthorityRevocationListAttribute(String authorityRevocationListAttribute) { this.authorityRevocationListAttribute = authorityRevocationListAttribute; return this; } /** * @param attributeCertificateAttributeAttribute * Attribute name(s) in the LDAP directory where end attribute * certificates are stored. Separated by space. Defaults to * "attributeCertificateAttribute" if null. * @throws IllegalArgumentException if a necessary parameter is null. * @return the builder */ public Builder setAttributeCertificateAttributeAttribute(String attributeCertificateAttributeAttribute) { this.attributeCertificateAttributeAttribute = attributeCertificateAttributeAttribute; return this; } /** * @param aACertificateAttribute Attribute name(s) in the LDAP directory where attribute * certificates for attribute authorities are stored. Separated * by space. Defaults to "aACertificate" if null. * @throws IllegalArgumentException if a necessary parameter is null. * @return the builder */ public Builder setAACertificateAttribute(String aACertificateAttribute) { this.aACertificateAttribute = aACertificateAttribute; return this; } /** * @param attributeDescriptorCertificateAttribute * Attribute name(s) in the LDAP directory where self signed * attribute certificates for attribute authorities are stored. * Separated by space. Defaults to * "attributeDescriptorCertificate" if null. * @throws IllegalArgumentException if a necessary parameter is null. * @return the builder */ public Builder setAttributeDescriptorCertificateAttribute(String attributeDescriptorCertificateAttribute) { this.attributeDescriptorCertificateAttribute = attributeDescriptorCertificateAttribute; return this; } /** * @param attributeCertificateRevocationListAttribute * Attribute name(s) in the LDAP directory where CRLs for * attribute certificates are stored. Separated by space. * Defaults to "attributeCertificateRevocationList" if * null. * @throws IllegalArgumentException if a necessary parameter is null. * @return the builder */ public Builder setAttributeCertificateRevocationListAttribute(String attributeCertificateRevocationListAttribute) { this.attributeCertificateRevocationListAttribute = attributeCertificateRevocationListAttribute; return this; } /** * @param attributeAuthorityRevocationListAttribute * Attribute name(s) in the LDAP directory where RLs for * attribute authority attribute certificates are stored. * Separated by space. Defaults to * "attributeAuthorityRevocationList" if null. * @throws IllegalArgumentException if a necessary parameter is null. * @return the builder */ public Builder setAttributeAuthorityRevocationListAttribute(String attributeAuthorityRevocationListAttribute) { this.attributeAuthorityRevocationListAttribute = attributeAuthorityRevocationListAttribute; return this; } /** * @param ldapUserCertificateAttributeName * The attribute name(s) in the LDAP directory where to search * for the attribute value of the specified * userCertificateSubjectAttributeName. E.g. if * "cn" is used to put information about the subject for end * certificates, then specify "cn". * @throws IllegalArgumentException if a necessary parameter is null. * @return the builder */ public Builder setLdapUserCertificateAttributeName(String ldapUserCertificateAttributeName) { this.ldapUserCertificateAttributeName = ldapUserCertificateAttributeName; return this; } /** * @param ldapCACertificateAttributeName The attribute name(s) in the LDAP directory where to search * for the attribute value of the specified * cACertificateSubjectAttributeName. E.g. if * "ou" is used to put information about the subject for CA * certificates, then specify "ou". * @throws IllegalArgumentException if a necessary parameter is null. * @return the builder */ public Builder setLdapCACertificateAttributeName(String ldapCACertificateAttributeName) { this.ldapCACertificateAttributeName = ldapCACertificateAttributeName; return this; } /** * @param ldapCrossCertificateAttributeName * The attribute name(s) in the LDAP directory where to search for * the attribute value of the specified * crossCertificateSubjectAttributeName. E.g. if * "o" is used to put information about the subject for cross * certificates, then specify "o". * @throws IllegalArgumentException if a necessary parameter is null. * @return the builder */ public Builder setLdapCrossCertificateAttributeName(String ldapCrossCertificateAttributeName) { this.ldapCrossCertificateAttributeName = ldapCrossCertificateAttributeName; return this; } /** * @param ldapCertificateRevocationListAttributeName * The attribute name(s) in the LDAP directory where to search for * the attribute value of the specified * certificateRevocationListIssuerAttributeName. * E.g. if "ou" is used to put information about the issuer of * CRLs, specify "ou". * @throws IllegalArgumentException if a necessary parameter is null. * @return the builder */ public Builder setLdapCertificateRevocationListAttributeName(String ldapCertificateRevocationListAttributeName) { this.ldapCertificateRevocationListAttributeName = ldapCertificateRevocationListAttributeName; return this; } /** * @param ldapDeltaRevocationListAttributeName * The attribute name(s) in the LDAP directory where to search for * the attribute value of the specified * deltaRevocationListIssuerAttributeName. E.g. * if "ou" is used to put information about the issuer of CRLs, * specify "ou". * @throws IllegalArgumentException if a necessary parameter is null. * @return the builder */ public Builder setLdapDeltaRevocationListAttributeName(String ldapDeltaRevocationListAttributeName) { this.ldapDeltaRevocationListAttributeName = ldapDeltaRevocationListAttributeName; return this; } /** * @param ldapAuthorityRevocationListAttributeName * The attribute name(s) in the LDAP directory where to search for * the attribute value of the specified * authorityRevocationListIssuerAttributeName. * E.g. if "ou" is used to put information about the issuer of * CRLs, specify "ou". * @throws IllegalArgumentException if a necessary parameter is null. * @return the builder */ public Builder setLdapAuthorityRevocationListAttributeName(String ldapAuthorityRevocationListAttributeName) { this.ldapAuthorityRevocationListAttributeName = ldapAuthorityRevocationListAttributeName; return this; } /** * @param ldapAttributeCertificateAttributeAttributeName * The attribute name(s) in the LDAP directory where to search for * the attribute value of the specified * attributeCertificateAttributeSubjectAttributeName. * E.g. if "cn" is used to put information about the subject of * end attribute certificates, specify "cn". * @throws IllegalArgumentException if a necessary parameter is null. * @return the builder */ public Builder setLdapAttributeCertificateAttributeAttributeName(String ldapAttributeCertificateAttributeAttributeName) { this.ldapAttributeCertificateAttributeAttributeName = ldapAttributeCertificateAttributeAttributeName; return this; } /** * @param ldapAACertificateAttributeName The attribute name(s) in the LDAP directory where to search for * the attribute value of the specified * aACertificateSubjectAttributeName. E.g. if * "ou" is used to put information about the subject of attribute * authority attribute certificates, specify "ou". * @throws IllegalArgumentException if a necessary parameter is null. * @return the builder */ public Builder setLdapAACertificateAttributeName(String ldapAACertificateAttributeName) { this.ldapAACertificateAttributeName = ldapAACertificateAttributeName; return this; } /** * @param ldapAttributeDescriptorCertificateAttributeName * The attribute name(s) in the LDAP directory where to search for * the attribute value of the specified * attributeDescriptorCertificateSubjectAttributeName. * E.g. if "o" is used to put information about the subject of * self signed attribute authority attribute certificates, * specify "o". * @throws IllegalArgumentException if a necessary parameter is null. * @return the builder */ public Builder setLdapAttributeDescriptorCertificateAttributeName(String ldapAttributeDescriptorCertificateAttributeName) { this.ldapAttributeDescriptorCertificateAttributeName = ldapAttributeDescriptorCertificateAttributeName; return this; } /** * @param ldapAttributeCertificateRevocationListAttributeName * The attribute name(s) in the LDAP directory where to search for * the attribute value of the specified * attributeCertificateRevocationListIssuerAttributeName. * E.g. if "ou" is used to put information about the issuer of * CRLs, specify "ou". * @throws IllegalArgumentException if a necessary parameter is null. * @return the builder */ public Builder setLdapAttributeCertificateRevocationListAttributeName(String ldapAttributeCertificateRevocationListAttributeName) { this.ldapAttributeCertificateRevocationListAttributeName = ldapAttributeCertificateRevocationListAttributeName; return this; } /** * @param ldapAttributeAuthorityRevocationListAttributeName * The attribute name(s) in the LDAP directory where to search for * the attribute value of the specified * attributeAuthorityRevocationListIssuerAttributeName. * E.g. if "ou" is used to put information about the issuer of * CRLs, specify "ou". * @throws IllegalArgumentException if a necessary parameter is null. * @return the builder */ public Builder setLdapAttributeAuthorityRevocationListAttributeName(String ldapAttributeAuthorityRevocationListAttributeName) { this.ldapAttributeAuthorityRevocationListAttributeName = ldapAttributeAuthorityRevocationListAttributeName; return this; } /** * @param userCertificateSubjectAttributeName * Attribute(s) in the subject of the certificate which is used * to be searched in the * ldapUserCertificateAttributeName. E.g. the * "cn" attribute of the DN could be used. * @throws IllegalArgumentException if a necessary parameter is null. * @return the builder */ public Builder setUserCertificateSubjectAttributeName(String userCertificateSubjectAttributeName) { this.userCertificateSubjectAttributeName = userCertificateSubjectAttributeName; return this; } /** * @param cACertificateSubjectAttributeName * Attribute(s) in the subject of the certificate which is used * to be searched in the * ldapCACertificateAttributeName. E.g. the "ou" * attribute of the DN could be used. * @throws IllegalArgumentException if a necessary parameter is null. * @return the builder */ public Builder setCACertificateSubjectAttributeName(String cACertificateSubjectAttributeName) { this.cACertificateSubjectAttributeName = cACertificateSubjectAttributeName; return this; } /** * @param crossCertificateSubjectAttributeName * Attribute(s) in the subject of the cross certificate which is * used to be searched in the * ldapCrossCertificateAttributeName. E.g. the * "o" attribute of the DN may be appropriate. * @throws IllegalArgumentException if a necessary parameter is null. * @return the builder */ public Builder setCrossCertificateSubjectAttributeName(String crossCertificateSubjectAttributeName) { this.crossCertificateSubjectAttributeName = crossCertificateSubjectAttributeName; return this; } /** * @param certificateRevocationListIssuerAttributeName * Attribute(s) in the issuer of the CRL which is used to be * searched in the * ldapCertificateRevocationListAttributeName. * E.g. the "o" or "ou" attribute may be used. * @throws IllegalArgumentException if a necessary parameter is null. * @return the builder */ public Builder setCertificateRevocationListIssuerAttributeName(String certificateRevocationListIssuerAttributeName) { this.certificateRevocationListIssuerAttributeName = certificateRevocationListIssuerAttributeName; return this; } /** * @param deltaRevocationListIssuerAttributeName * Attribute(s) in the issuer of the CRL which is used to be * searched in the * ldapDeltaRevocationListAttributeName. E.g. the * "o" or "ou" attribute may be used. * @throws IllegalArgumentException if a necessary parameter is null. * @return the builder */ public Builder setDeltaRevocationListIssuerAttributeName(String deltaRevocationListIssuerAttributeName) { this.deltaRevocationListIssuerAttributeName = deltaRevocationListIssuerAttributeName; return this; } /** * @param authorityRevocationListIssuerAttributeName * Attribute(s) in the issuer of the CRL which is used to be * searched in the * ldapAuthorityRevocationListAttributeName. E.g. * the "o" or "ou" attribute may be used. * @throws IllegalArgumentException if a necessary parameter is null. * @return the builder */ public Builder setAuthorityRevocationListIssuerAttributeName(String authorityRevocationListIssuerAttributeName) { this.authorityRevocationListIssuerAttributeName = authorityRevocationListIssuerAttributeName; return this; } /** * @param attributeCertificateAttributeSubjectAttributeName * Attribute(s) in the subject of the attribute certificate which * is used to be searched in the * ldapAttributeCertificateAttributeAttributeName. * E.g. the "cn" attribute of the DN could be used. * @throws IllegalArgumentException if a necessary parameter is null. * @return the builder */ public Builder setAttributeCertificateAttributeSubjectAttributeName(String attributeCertificateAttributeSubjectAttributeName) { this.attributeCertificateAttributeSubjectAttributeName = attributeCertificateAttributeSubjectAttributeName; return this; } /** * @param aACertificateSubjectAttributeName * Attribute(s) in the subject of the attribute certificate which * is used to be searched in the * ldapAACertificateAttributeName. E.g. the "ou" * attribute of the DN could be used. * @throws IllegalArgumentException if a necessary parameter is null. * @return the builder */ public Builder setAACertificateSubjectAttributeName(String aACertificateSubjectAttributeName) { this.aACertificateSubjectAttributeName = aACertificateSubjectAttributeName; return this; } /** * @param attributeDescriptorCertificateSubjectAttributeName * Attribute(s) in the subject of the attribute certificate which * is used to be searched in the * ldapAttributeDescriptorCertificateAttributeName. * E.g. the "o" attribute of the DN could be used. * @throws IllegalArgumentException if a necessary parameter is null. * @return the builder */ public Builder setAttributeDescriptorCertificateSubjectAttributeName(String attributeDescriptorCertificateSubjectAttributeName) { this.attributeDescriptorCertificateSubjectAttributeName = attributeDescriptorCertificateSubjectAttributeName; return this; } /** * @param attributeCertificateRevocationListIssuerAttributeName * Attribute(s) in the issuer of the CRL which is used to be * searched in the * ldapAttributeCertificateRevocationListAttributeName. * E.g. the "o" or "ou" attribute may be used * certificate is searched in this LDAP attribute. * @throws IllegalArgumentException if a necessary parameter is null. * @return the builder */ public Builder setAttributeCertificateRevocationListIssuerAttributeName(String attributeCertificateRevocationListIssuerAttributeName) { this.attributeCertificateRevocationListIssuerAttributeName = attributeCertificateRevocationListIssuerAttributeName; return this; } /** * @param attributeAuthorityRevocationListIssuerAttributeName * Anttribute(s) in the issuer of the CRL which is used to be * searched in the * ldapAttributeAuthorityRevocationListAttributeName. * E.g. the "o" or "ou" attribute may be used. * @throws IllegalArgumentException if a necessary parameter is null. * @return the builder */ public Builder setAttributeAuthorityRevocationListIssuerAttributeName(String attributeAuthorityRevocationListIssuerAttributeName) { this.attributeAuthorityRevocationListIssuerAttributeName = attributeAuthorityRevocationListIssuerAttributeName; return this; } /** * * @param searchForSerialNumberIn If not null the serial number of the * certificate is searched in this LDAP attribute. * @throws IllegalArgumentException if a necessary parameter is null. * @return the builder */ public Builder setSearchForSerialNumberIn(String searchForSerialNumberIn) { this.searchForSerialNumberIn = searchForSerialNumberIn; return this; } public X509LDAPCertStoreParameters build() { if (ldapUserCertificateAttributeName == null // migrate to setters || ldapCACertificateAttributeName == null || ldapCrossCertificateAttributeName == null || ldapCertificateRevocationListAttributeName == null || ldapDeltaRevocationListAttributeName == null || ldapAuthorityRevocationListAttributeName == null || ldapAttributeCertificateAttributeAttributeName == null || ldapAACertificateAttributeName == null || ldapAttributeDescriptorCertificateAttributeName == null || ldapAttributeCertificateRevocationListAttributeName == null || ldapAttributeAuthorityRevocationListAttributeName == null || userCertificateSubjectAttributeName == null || cACertificateSubjectAttributeName == null || crossCertificateSubjectAttributeName == null || certificateRevocationListIssuerAttributeName == null || deltaRevocationListIssuerAttributeName == null || authorityRevocationListIssuerAttributeName == null || attributeCertificateAttributeSubjectAttributeName == null || aACertificateSubjectAttributeName == null || attributeDescriptorCertificateSubjectAttributeName == null || attributeCertificateRevocationListIssuerAttributeName == null || attributeAuthorityRevocationListIssuerAttributeName == null) { throw new IllegalArgumentException( "Necessary parameters not specified."); } return new X509LDAPCertStoreParameters(this); } } private X509LDAPCertStoreParameters(Builder builder) { this.ldapURL = builder.ldapURL; this.baseDN = builder.baseDN; this.userCertificateAttribute = builder.userCertificateAttribute; this.cACertificateAttribute = builder.cACertificateAttribute; this.crossCertificateAttribute = builder.crossCertificateAttribute; this.certificateRevocationListAttribute = builder.certificateRevocationListAttribute; this.deltaRevocationListAttribute = builder.deltaRevocationListAttribute; this.authorityRevocationListAttribute = builder.authorityRevocationListAttribute; this.attributeCertificateAttributeAttribute = builder.attributeCertificateAttributeAttribute; this.aACertificateAttribute = builder.aACertificateAttribute; this.attributeDescriptorCertificateAttribute = builder.attributeDescriptorCertificateAttribute; this.attributeCertificateRevocationListAttribute = builder.attributeCertificateRevocationListAttribute; this.attributeAuthorityRevocationListAttribute = builder.attributeAuthorityRevocationListAttribute; this.ldapUserCertificateAttributeName = builder.ldapUserCertificateAttributeName; this.ldapCACertificateAttributeName = builder.ldapCACertificateAttributeName; this.ldapCrossCertificateAttributeName = builder.ldapCrossCertificateAttributeName; this.ldapCertificateRevocationListAttributeName = builder.ldapCertificateRevocationListAttributeName; this.ldapDeltaRevocationListAttributeName = builder.ldapDeltaRevocationListAttributeName; this.ldapAuthorityRevocationListAttributeName = builder.ldapAuthorityRevocationListAttributeName; this.ldapAttributeCertificateAttributeAttributeName = builder.ldapAttributeCertificateAttributeAttributeName; this.ldapAACertificateAttributeName = builder.ldapAACertificateAttributeName; this.ldapAttributeDescriptorCertificateAttributeName = builder.ldapAttributeDescriptorCertificateAttributeName; this.ldapAttributeCertificateRevocationListAttributeName = builder.ldapAttributeCertificateRevocationListAttributeName; this.ldapAttributeAuthorityRevocationListAttributeName = builder.ldapAttributeAuthorityRevocationListAttributeName; this.userCertificateSubjectAttributeName = builder.userCertificateSubjectAttributeName; this.cACertificateSubjectAttributeName = builder.cACertificateSubjectAttributeName; this.crossCertificateSubjectAttributeName = builder.crossCertificateSubjectAttributeName; this.certificateRevocationListIssuerAttributeName = builder.certificateRevocationListIssuerAttributeName; this.deltaRevocationListIssuerAttributeName = builder.deltaRevocationListIssuerAttributeName; this.authorityRevocationListIssuerAttributeName = builder.authorityRevocationListIssuerAttributeName; this.attributeCertificateAttributeSubjectAttributeName = builder.attributeCertificateAttributeSubjectAttributeName; this.aACertificateSubjectAttributeName = builder.aACertificateSubjectAttributeName; this.attributeDescriptorCertificateSubjectAttributeName = builder.attributeDescriptorCertificateSubjectAttributeName; this.attributeCertificateRevocationListIssuerAttributeName = builder.attributeCertificateRevocationListIssuerAttributeName; this.attributeAuthorityRevocationListIssuerAttributeName = builder.attributeAuthorityRevocationListIssuerAttributeName; this.searchForSerialNumberIn = builder.searchForSerialNumberIn; } /** * Returns a clone of this object. */ public Object clone() { return this; } public boolean equal(Object o) { if (o == this) { return true; } if (!(o instanceof X509LDAPCertStoreParameters)) { return false; } X509LDAPCertStoreParameters params = (X509LDAPCertStoreParameters)o; return checkField(ldapURL, params.ldapURL) && checkField(baseDN, params.baseDN) && checkField(userCertificateAttribute, params.userCertificateAttribute) && checkField(cACertificateAttribute, params.cACertificateAttribute) && checkField(crossCertificateAttribute, params.crossCertificateAttribute) && checkField(certificateRevocationListAttribute, params.certificateRevocationListAttribute) && checkField(deltaRevocationListAttribute, params.deltaRevocationListAttribute) && checkField(authorityRevocationListAttribute, params.authorityRevocationListAttribute) && checkField(attributeCertificateAttributeAttribute, params.attributeCertificateAttributeAttribute) && checkField(aACertificateAttribute, params.aACertificateAttribute) && checkField(attributeDescriptorCertificateAttribute, params.attributeDescriptorCertificateAttribute) && checkField(attributeCertificateRevocationListAttribute, params.attributeCertificateRevocationListAttribute) && checkField(attributeAuthorityRevocationListAttribute, params.attributeAuthorityRevocationListAttribute) && checkField(ldapUserCertificateAttributeName, params.ldapUserCertificateAttributeName) && checkField(ldapCACertificateAttributeName, params.ldapCACertificateAttributeName) && checkField(ldapCrossCertificateAttributeName, params.ldapCrossCertificateAttributeName) && checkField(ldapCertificateRevocationListAttributeName, params.ldapCertificateRevocationListAttributeName) && checkField(ldapDeltaRevocationListAttributeName, params.ldapDeltaRevocationListAttributeName) && checkField(ldapAuthorityRevocationListAttributeName, params.ldapAuthorityRevocationListAttributeName) && checkField(ldapAttributeCertificateAttributeAttributeName, params.ldapAttributeCertificateAttributeAttributeName) && checkField(ldapAACertificateAttributeName, params.ldapAACertificateAttributeName) && checkField(ldapAttributeDescriptorCertificateAttributeName, params.ldapAttributeDescriptorCertificateAttributeName) && checkField(ldapAttributeCertificateRevocationListAttributeName, params.ldapAttributeCertificateRevocationListAttributeName) && checkField(ldapAttributeAuthorityRevocationListAttributeName, params.ldapAttributeAuthorityRevocationListAttributeName) && checkField(userCertificateSubjectAttributeName, params.userCertificateSubjectAttributeName) && checkField(cACertificateSubjectAttributeName, params.cACertificateSubjectAttributeName) && checkField(crossCertificateSubjectAttributeName, params.crossCertificateSubjectAttributeName) && checkField(certificateRevocationListIssuerAttributeName, params.certificateRevocationListIssuerAttributeName) && checkField(deltaRevocationListIssuerAttributeName, params.deltaRevocationListIssuerAttributeName) && checkField(authorityRevocationListIssuerAttributeName, params.authorityRevocationListIssuerAttributeName) && checkField(attributeCertificateAttributeSubjectAttributeName, params.attributeCertificateAttributeSubjectAttributeName) && checkField(aACertificateSubjectAttributeName, params.aACertificateSubjectAttributeName) && checkField(attributeDescriptorCertificateSubjectAttributeName, params.attributeDescriptorCertificateSubjectAttributeName) && checkField(attributeCertificateRevocationListIssuerAttributeName, params.attributeCertificateRevocationListIssuerAttributeName) && checkField(attributeAuthorityRevocationListIssuerAttributeName, params.attributeAuthorityRevocationListIssuerAttributeName) && checkField(searchForSerialNumberIn, params.searchForSerialNumberIn); } private boolean checkField(Object o1, Object o2) { if (o1 == o2) { return true; } if (o1 == null) { return false; } return o1.equals(o2); } public int hashCode() { int hash = 0; hash = addHashCode(hash, userCertificateAttribute); hash = addHashCode(hash, cACertificateAttribute); hash = addHashCode(hash, crossCertificateAttribute); hash = addHashCode(hash, certificateRevocationListAttribute); hash = addHashCode(hash, deltaRevocationListAttribute); hash = addHashCode(hash, authorityRevocationListAttribute); hash = addHashCode(hash, attributeCertificateAttributeAttribute); hash = addHashCode(hash, aACertificateAttribute); hash = addHashCode(hash, attributeDescriptorCertificateAttribute); hash = addHashCode(hash, attributeCertificateRevocationListAttribute); hash = addHashCode(hash, attributeAuthorityRevocationListAttribute); hash = addHashCode(hash, ldapUserCertificateAttributeName); hash = addHashCode(hash, ldapCACertificateAttributeName); hash = addHashCode(hash, ldapCrossCertificateAttributeName); hash = addHashCode(hash, ldapCertificateRevocationListAttributeName); hash = addHashCode(hash, ldapDeltaRevocationListAttributeName); hash = addHashCode(hash, ldapAuthorityRevocationListAttributeName); hash = addHashCode(hash, ldapAttributeCertificateAttributeAttributeName); hash = addHashCode(hash, ldapAACertificateAttributeName); hash = addHashCode(hash, ldapAttributeDescriptorCertificateAttributeName); hash = addHashCode(hash, ldapAttributeCertificateRevocationListAttributeName); hash = addHashCode(hash, ldapAttributeAuthorityRevocationListAttributeName); hash = addHashCode(hash, userCertificateSubjectAttributeName); hash = addHashCode(hash, cACertificateSubjectAttributeName); hash = addHashCode(hash, crossCertificateSubjectAttributeName); hash = addHashCode(hash, certificateRevocationListIssuerAttributeName); hash = addHashCode(hash, deltaRevocationListIssuerAttributeName); hash = addHashCode(hash, authorityRevocationListIssuerAttributeName); hash = addHashCode(hash, attributeCertificateAttributeSubjectAttributeName); hash = addHashCode(hash, aACertificateSubjectAttributeName); hash = addHashCode(hash, attributeDescriptorCertificateSubjectAttributeName); hash = addHashCode(hash, attributeCertificateRevocationListIssuerAttributeName); hash = addHashCode(hash, attributeAuthorityRevocationListIssuerAttributeName); hash = addHashCode(hash, searchForSerialNumberIn); return hash; } private int addHashCode(int hashCode, Object o) { return (hashCode * 29) + (o == null ? 0 : o.hashCode()); } /** * @return Returns the aACertificateAttribute. */ public String getAACertificateAttribute() { return aACertificateAttribute; } /** * @return Returns the aACertificateSubjectAttributeName. */ public String getAACertificateSubjectAttributeName() { return aACertificateSubjectAttributeName; } /** * @return Returns the attributeAuthorityRevocationListAttribute. */ public String getAttributeAuthorityRevocationListAttribute() { return attributeAuthorityRevocationListAttribute; } /** * @return Returns the attributeAuthorityRevocationListIssuerAttributeName. */ public String getAttributeAuthorityRevocationListIssuerAttributeName() { return attributeAuthorityRevocationListIssuerAttributeName; } /** * @return Returns the attributeCertificateAttributeAttribute. */ public String getAttributeCertificateAttributeAttribute() { return attributeCertificateAttributeAttribute; } /** * @return Returns the attributeCertificateAttributeSubjectAttributeName. */ public String getAttributeCertificateAttributeSubjectAttributeName() { return attributeCertificateAttributeSubjectAttributeName; } /** * @return Returns the attributeCertificateRevocationListAttribute. */ public String getAttributeCertificateRevocationListAttribute() { return attributeCertificateRevocationListAttribute; } /** * @return Returns the * attributeCertificateRevocationListIssuerAttributeName. */ public String getAttributeCertificateRevocationListIssuerAttributeName() { return attributeCertificateRevocationListIssuerAttributeName; } /** * @return Returns the attributeDescriptorCertificateAttribute. */ public String getAttributeDescriptorCertificateAttribute() { return attributeDescriptorCertificateAttribute; } /** * @return Returns the attributeDescriptorCertificateSubjectAttributeName. */ public String getAttributeDescriptorCertificateSubjectAttributeName() { return attributeDescriptorCertificateSubjectAttributeName; } /** * @return Returns the authorityRevocationListAttribute. */ public String getAuthorityRevocationListAttribute() { return authorityRevocationListAttribute; } /** * @return Returns the authorityRevocationListIssuerAttributeName. */ public String getAuthorityRevocationListIssuerAttributeName() { return authorityRevocationListIssuerAttributeName; } /** * @return Returns the baseDN. */ public String getBaseDN() { return baseDN; } /** * @return Returns the cACertificateAttribute. */ public String getCACertificateAttribute() { return cACertificateAttribute; } /** * @return Returns the cACertificateSubjectAttributeName. */ public String getCACertificateSubjectAttributeName() { return cACertificateSubjectAttributeName; } /** * @return Returns the certificateRevocationListAttribute. */ public String getCertificateRevocationListAttribute() { return certificateRevocationListAttribute; } /** * @return Returns the certificateRevocationListIssuerAttributeName. */ public String getCertificateRevocationListIssuerAttributeName() { return certificateRevocationListIssuerAttributeName; } /** * @return Returns the crossCertificateAttribute. */ public String getCrossCertificateAttribute() { return crossCertificateAttribute; } /** * @return Returns the crossCertificateSubjectAttributeName. */ public String getCrossCertificateSubjectAttributeName() { return crossCertificateSubjectAttributeName; } /** * @return Returns the deltaRevocationListAttribute. */ public String getDeltaRevocationListAttribute() { return deltaRevocationListAttribute; } /** * @return Returns the deltaRevocationListIssuerAttributeName. */ public String getDeltaRevocationListIssuerAttributeName() { return deltaRevocationListIssuerAttributeName; } /** * @return Returns the ldapAACertificateAttributeName. */ public String getLdapAACertificateAttributeName() { return ldapAACertificateAttributeName; } /** * @return Returns the ldapAttributeAuthorityRevocationListAttributeName. */ public String getLdapAttributeAuthorityRevocationListAttributeName() { return ldapAttributeAuthorityRevocationListAttributeName; } /** * @return Returns the ldapAttributeCertificateAttributeAttributeName. */ public String getLdapAttributeCertificateAttributeAttributeName() { return ldapAttributeCertificateAttributeAttributeName; } /** * @return Returns the ldapAttributeCertificateRevocationListAttributeName. */ public String getLdapAttributeCertificateRevocationListAttributeName() { return ldapAttributeCertificateRevocationListAttributeName; } /** * @return Returns the ldapAttributeDescriptorCertificateAttributeName. */ public String getLdapAttributeDescriptorCertificateAttributeName() { return ldapAttributeDescriptorCertificateAttributeName; } /** * @return Returns the ldapAuthorityRevocationListAttributeName. */ public String getLdapAuthorityRevocationListAttributeName() { return ldapAuthorityRevocationListAttributeName; } /** * @return Returns the ldapCACertificateAttributeName. */ public String getLdapCACertificateAttributeName() { return ldapCACertificateAttributeName; } /** * @return Returns the ldapCertificateRevocationListAttributeName. */ public String getLdapCertificateRevocationListAttributeName() { return ldapCertificateRevocationListAttributeName; } /** * @return Returns the ldapCrossCertificateAttributeName. */ public String getLdapCrossCertificateAttributeName() { return ldapCrossCertificateAttributeName; } /** * @return Returns the ldapDeltaRevocationListAttributeName. */ public String getLdapDeltaRevocationListAttributeName() { return ldapDeltaRevocationListAttributeName; } /** * @return Returns the ldapURL. */ public String getLdapURL() { return ldapURL; } /** * @return Returns the ldapUserCertificateAttributeName. */ public String getLdapUserCertificateAttributeName() { return ldapUserCertificateAttributeName; } /** * @return Returns the searchForSerialNumberIn. */ public String getSearchForSerialNumberIn() { return searchForSerialNumberIn; } /** * @return Returns the userCertificateAttribute. */ public String getUserCertificateAttribute() { return userCertificateAttribute; } /** * @return Returns the userCertificateSubjectAttributeName. */ public String getUserCertificateSubjectAttributeName() { return userCertificateSubjectAttributeName; } public static X509LDAPCertStoreParameters getInstance(LDAPCertStoreParameters params) { String server = "ldap://" + params.getServerName() + ":" + params.getPort(); X509LDAPCertStoreParameters _params = new Builder(server, "").build(); return _params; } } bouncycastle-1.49.orig/src/org/bouncycastle/jce/ECGOST3410NamedCurveTable.java0000644000175000017500000000345611625353320026334 0ustar ebourgebourgpackage org.bouncycastle.jce; import java.util.Enumeration; import org.bouncycastle.asn1.ASN1ObjectIdentifier; import org.bouncycastle.asn1.cryptopro.ECGOST3410NamedCurves; import org.bouncycastle.crypto.params.ECDomainParameters; import org.bouncycastle.jce.spec.ECNamedCurveParameterSpec; /** * a table of locally supported named curves. */ public class ECGOST3410NamedCurveTable { /** * return a parameter spec representing the passed in named * curve. The routine returns null if the curve is not present. * * @param name the name of the curve requested * @return a parameter spec for the curve, null if it is not available. */ public static ECNamedCurveParameterSpec getParameterSpec( String name) { ECDomainParameters ecP = ECGOST3410NamedCurves.getByName(name); if (ecP == null) { try { ecP = ECGOST3410NamedCurves.getByOID(new ASN1ObjectIdentifier(name)); } catch (IllegalArgumentException e) { return null; // not an oid. } } if (ecP == null) { return null; } return new ECNamedCurveParameterSpec( name, ecP.getCurve(), ecP.getG(), ecP.getN(), ecP.getH(), ecP.getSeed()); } /** * return an enumeration of the names of the available curves. * * @return an enumeration of the names of the available curves. */ public static Enumeration getNames() { return ECGOST3410NamedCurves.getNames(); } } bouncycastle-1.49.orig/src/org/bouncycastle/jce/package.html0000644000175000017500000000046510262753175023541 0ustar ebourgebourg Utility classes for use with the JCE.

    The classes in this package support the generation of certificates and PKCS10 signing requests.

    Note: the PKCS7 class is deprecated, for a fuller version of CMS see the cms package distributed with the BC mail API. bouncycastle-1.49.orig/src/org/bouncycastle/openssl/0000755000175000017500000000000012152033551022162 5ustar ebourgebourgbouncycastle-1.49.orig/src/org/bouncycastle/openssl/MiscPEMGenerator.java0000644000175000017500000001503412147306654026147 0ustar ebourgebourgpackage org.bouncycastle.openssl; import java.io.IOException; import java.math.BigInteger; import java.util.ArrayList; import java.util.List; import org.bouncycastle.asn1.ASN1EncodableVector; import org.bouncycastle.asn1.ASN1Integer; import org.bouncycastle.asn1.ASN1ObjectIdentifier; import org.bouncycastle.asn1.DERInteger; import org.bouncycastle.asn1.DERSequence; import org.bouncycastle.asn1.cms.ContentInfo; import org.bouncycastle.asn1.oiw.OIWObjectIdentifiers; import org.bouncycastle.asn1.pkcs.PKCSObjectIdentifiers; import org.bouncycastle.asn1.pkcs.PrivateKeyInfo; import org.bouncycastle.asn1.x509.DSAParameter; import org.bouncycastle.asn1.x509.SubjectPublicKeyInfo; import org.bouncycastle.asn1.x9.X9ObjectIdentifiers; import org.bouncycastle.cert.X509AttributeCertificateHolder; import org.bouncycastle.cert.X509CRLHolder; import org.bouncycastle.cert.X509CertificateHolder; import org.bouncycastle.pkcs.PKCS10CertificationRequest; import org.bouncycastle.pkcs.PKCS8EncryptedPrivateKeyInfo; import org.bouncycastle.util.Strings; import org.bouncycastle.util.io.pem.PemGenerationException; import org.bouncycastle.util.io.pem.PemHeader; import org.bouncycastle.util.io.pem.PemObject; import org.bouncycastle.util.io.pem.PemObjectGenerator; /** * PEM generator for the original set of PEM objects used in Open SSL. */ public class MiscPEMGenerator implements PemObjectGenerator { private static final ASN1ObjectIdentifier[] dsaOids = { X9ObjectIdentifiers.id_dsa, OIWObjectIdentifiers.dsaWithSHA1 }; private static final byte[] hexEncodingTable = { (byte)'0', (byte)'1', (byte)'2', (byte)'3', (byte)'4', (byte)'5', (byte)'6', (byte)'7', (byte)'8', (byte)'9', (byte)'A', (byte)'B', (byte)'C', (byte)'D', (byte)'E', (byte)'F' }; private final Object obj; private final PEMEncryptor encryptor; public MiscPEMGenerator(Object o) { this.obj = o; // use of this confuses some earlier JDKs. this.encryptor = null; } public MiscPEMGenerator(Object o, PEMEncryptor encryptor) { this.obj = o; this.encryptor = encryptor; } private PemObject createPemObject(Object o) throws IOException { String type; byte[] encoding; if (o instanceof PemObject) { return (PemObject)o; } if (o instanceof PemObjectGenerator) { return ((PemObjectGenerator)o).generate(); } if (o instanceof X509CertificateHolder) { type = "CERTIFICATE"; encoding = ((X509CertificateHolder)o).getEncoded(); } else if (o instanceof X509CRLHolder) { type = "X509 CRL"; encoding = ((X509CRLHolder)o).getEncoded(); } else if (o instanceof PrivateKeyInfo) { PrivateKeyInfo info = (PrivateKeyInfo)o; ASN1ObjectIdentifier algOID = info.getPrivateKeyAlgorithm().getAlgorithm(); if (algOID.equals(PKCSObjectIdentifiers.rsaEncryption)) { type = "RSA PRIVATE KEY"; encoding = info.parsePrivateKey().toASN1Primitive().getEncoded(); } else if (algOID.equals(dsaOids[0]) || algOID.equals(dsaOids[1])) { type = "DSA PRIVATE KEY"; DSAParameter p = DSAParameter.getInstance(info.getPrivateKeyAlgorithm().getParameters()); ASN1EncodableVector v = new ASN1EncodableVector(); v.add(new DERInteger(0)); v.add(new DERInteger(p.getP())); v.add(new DERInteger(p.getQ())); v.add(new DERInteger(p.getG())); BigInteger x = ASN1Integer.getInstance(info.parsePrivateKey()).getValue(); BigInteger y = p.getG().modPow(x, p.getP()); v.add(new DERInteger(y)); v.add(new DERInteger(x)); encoding = new DERSequence(v).getEncoded(); } else if (algOID.equals(X9ObjectIdentifiers.id_ecPublicKey)) { type = "EC PRIVATE KEY"; encoding = info.parsePrivateKey().toASN1Primitive().getEncoded(); } else { throw new IOException("Cannot identify private key"); } } else if (o instanceof SubjectPublicKeyInfo) { type = "PUBLIC KEY"; encoding = ((SubjectPublicKeyInfo)o).getEncoded(); } else if (o instanceof X509AttributeCertificateHolder) { type = "ATTRIBUTE CERTIFICATE"; encoding = ((X509AttributeCertificateHolder)o).getEncoded(); } else if (o instanceof org.bouncycastle.pkcs.PKCS10CertificationRequest) { type = "CERTIFICATE REQUEST"; encoding = ((PKCS10CertificationRequest)o).getEncoded(); } else if (o instanceof ContentInfo) { type = "PKCS7"; encoding = ((ContentInfo)o).getEncoded(); } else { throw new PemGenerationException("unknown object passed - can't encode."); } if (encryptor != null) { String dekAlgName = Strings.toUpperCase(encryptor.getAlgorithm()); // Note: For backward compatibility if (dekAlgName.equals("DESEDE")) { dekAlgName = "DES-EDE3-CBC"; } byte[] iv = encryptor.getIV(); byte[] encData = encryptor.encrypt(encoding); List headers = new ArrayList(2); headers.add(new PemHeader("Proc-Type", "4,ENCRYPTED")); headers.add(new PemHeader("DEK-Info", dekAlgName + "," + getHexEncoded(iv))); return new PemObject(type, headers, encData); } return new PemObject(type, encoding); } private String getHexEncoded(byte[] bytes) throws IOException { char[] chars = new char[bytes.length * 2]; for (int i = 0; i != bytes.length; i++) { int v = bytes[i] & 0xff; chars[2 * i] = (char)(hexEncodingTable[(v >>> 4)]); chars[2 * i + 1] = (char)(hexEncodingTable[v & 0xf]); } return new String(chars); } public PemObject generate() throws PemGenerationException { try { return createPemObject(obj); } catch (IOException e) { throw new PemGenerationException("encoding exception: " + e.getMessage(), e); } } } bouncycastle-1.49.orig/src/org/bouncycastle/openssl/PEMDecryptor.java0000644000175000017500000000022112104051043025326 0ustar ebourgebourgpackage org.bouncycastle.openssl; public interface PEMDecryptor { byte[] decrypt(byte[] keyBytes, byte[] iv) throws PEMException; } bouncycastle-1.49.orig/src/org/bouncycastle/openssl/PEMKeyPair.java0000644000175000017500000000121112101612370024722 0ustar ebourgebourgpackage org.bouncycastle.openssl; import org.bouncycastle.asn1.pkcs.PrivateKeyInfo; import org.bouncycastle.asn1.x509.SubjectPublicKeyInfo; public class PEMKeyPair { private final SubjectPublicKeyInfo publicKeyInfo; private final PrivateKeyInfo privateKeyInfo; public PEMKeyPair(SubjectPublicKeyInfo publicKeyInfo, PrivateKeyInfo privateKeyInfo) { this.publicKeyInfo = publicKeyInfo; this.privateKeyInfo = privateKeyInfo; } public PrivateKeyInfo getPrivateKeyInfo() { return privateKeyInfo; } public SubjectPublicKeyInfo getPublicKeyInfo() { return publicKeyInfo; } } bouncycastle-1.49.orig/src/org/bouncycastle/openssl/PEMException.java0000644000175000017500000000105711442065640025335 0ustar ebourgebourgpackage org.bouncycastle.openssl; import java.io.IOException; public class PEMException extends IOException { Exception underlying; public PEMException( String message) { super(message); } public PEMException( String message, Exception underlying) { super(message); this.underlying = underlying; } public Exception getUnderlyingException() { return underlying; } public Throwable getCause() { return underlying; } } bouncycastle-1.49.orig/src/org/bouncycastle/openssl/PEMDecryptorProvider.java0000644000175000017500000000033412104050241027045 0ustar ebourgebourgpackage org.bouncycastle.openssl; import org.bouncycastle.operator.OperatorCreationException; public interface PEMDecryptorProvider { PEMDecryptor get(String dekAlgName) throws OperatorCreationException; } bouncycastle-1.49.orig/src/org/bouncycastle/openssl/EncryptionException.java0000644000175000017500000000057712101662205027045 0ustar ebourgebourgpackage org.bouncycastle.openssl; public class EncryptionException extends PEMException { private Throwable cause; public EncryptionException(String msg) { super(msg); } public EncryptionException(String msg, Throwable ex) { super(msg); this.cause = ex; } public Throwable getCause() { return cause; } }bouncycastle-1.49.orig/src/org/bouncycastle/openssl/PEMWriter.java0000644000175000017500000000403512104123362024642 0ustar ebourgebourgpackage org.bouncycastle.openssl; import java.io.IOException; import java.io.Writer; import java.security.SecureRandom; import org.bouncycastle.openssl.jcajce.JcaMiscPEMGenerator; import org.bouncycastle.openssl.jcajce.JcePEMEncryptorBuilder; import org.bouncycastle.util.io.pem.PemGenerationException; import org.bouncycastle.util.io.pem.PemObjectGenerator; import org.bouncycastle.util.io.pem.PemWriter; /** * General purpose writer for OpenSSL PEM objects. */ public class PEMWriter extends PemWriter { private String provider; /** * Base constructor. * * @param out output stream to use. */ public PEMWriter(Writer out) { this(out, "BC"); } /** * @deprecated use constructor that just takes out, and writeObject(PEMEncryptor) * @param out * @param provider */ public PEMWriter( Writer out, String provider) { super(out); this.provider = provider; } public void writeObject( Object obj) throws IOException { writeObject(obj, null); } public void writeObject( Object obj, PEMEncryptor encryptor) throws IOException { try { super.writeObject(new JcaMiscPEMGenerator(obj, encryptor)); } catch (PemGenerationException e) { if (e.getCause() instanceof IOException) { throw (IOException)e.getCause(); } throw e; } } public void writeObject( PemObjectGenerator obj) throws IOException { super.writeObject(obj); } /** * @deprecated use writeObject(obj, PEMEncryptor) */ public void writeObject( Object obj, String algorithm, char[] password, SecureRandom random) throws IOException { this.writeObject(obj, new JcePEMEncryptorBuilder(algorithm).setSecureRandom(random).setProvider(provider).build(password)); } } bouncycastle-1.49.orig/src/org/bouncycastle/openssl/PEMParser.java0000644000175000017500000003773712147601537024655 0ustar ebourgebourgpackage org.bouncycastle.openssl; import java.io.IOException; import java.io.Reader; import java.util.HashMap; import java.util.Iterator; import java.util.List; import java.util.Map; import java.util.StringTokenizer; import org.bouncycastle.asn1.ASN1InputStream; import org.bouncycastle.asn1.ASN1Integer; import org.bouncycastle.asn1.ASN1ObjectIdentifier; import org.bouncycastle.asn1.ASN1Primitive; import org.bouncycastle.asn1.ASN1Sequence; import org.bouncycastle.asn1.DERNull; import org.bouncycastle.asn1.cms.ContentInfo; import org.bouncycastle.asn1.pkcs.EncryptedPrivateKeyInfo; import org.bouncycastle.asn1.pkcs.PKCSObjectIdentifiers; import org.bouncycastle.asn1.pkcs.PrivateKeyInfo; import org.bouncycastle.asn1.pkcs.RSAPublicKey; import org.bouncycastle.asn1.x509.AlgorithmIdentifier; import org.bouncycastle.asn1.x509.DSAParameter; import org.bouncycastle.asn1.x509.SubjectPublicKeyInfo; import org.bouncycastle.asn1.x9.X9ECParameters; import org.bouncycastle.asn1.x9.X9ObjectIdentifiers; import org.bouncycastle.cert.X509AttributeCertificateHolder; import org.bouncycastle.cert.X509CRLHolder; import org.bouncycastle.cert.X509CertificateHolder; import org.bouncycastle.pkcs.PKCS10CertificationRequest; import org.bouncycastle.pkcs.PKCS8EncryptedPrivateKeyInfo; import org.bouncycastle.util.encoders.Hex; import org.bouncycastle.util.io.pem.PemHeader; import org.bouncycastle.util.io.pem.PemObject; import org.bouncycastle.util.io.pem.PemObjectParser; import org.bouncycastle.util.io.pem.PemReader; /** * Class for parsing OpenSSL PEM encoded streams containing * X509 certificates, PKCS8 encoded keys and PKCS7 objects. *

    * In the case of PKCS7 objects the reader will return a CMS ContentInfo object. Public keys will be returned as * well formed SubjectPublicKeyInfo objects, private keys will be returned as well formed PrivateKeyInfo objects. In the * case of a private key a PEMKeyPair will normally be returned if the encoding contains both the private and public * key definition. CRLs, Certificates, PKCS#10 requests, and Attribute Certificates will generate the appropriate BC holder class. *

    */ public class PEMParser extends PemReader { private final Map parsers = new HashMap(); /** * Create a new PEMReader * * @param reader the Reader */ public PEMParser( Reader reader) { super(reader); parsers.put("CERTIFICATE REQUEST", new PKCS10CertificationRequestParser()); parsers.put("NEW CERTIFICATE REQUEST", new PKCS10CertificationRequestParser()); parsers.put("CERTIFICATE", new X509CertificateParser()); parsers.put("X509 CERTIFICATE", new X509CertificateParser()); parsers.put("X509 CRL", new X509CRLParser()); parsers.put("PKCS7", new PKCS7Parser()); parsers.put("ATTRIBUTE CERTIFICATE", new X509AttributeCertificateParser()); parsers.put("EC PARAMETERS", new ECCurveParamsParser()); parsers.put("PUBLIC KEY", new PublicKeyParser()); parsers.put("RSA PUBLIC KEY", new RSAPublicKeyParser()); parsers.put("RSA PRIVATE KEY", new KeyPairParser(new RSAKeyPairParser())); parsers.put("DSA PRIVATE KEY", new KeyPairParser(new DSAKeyPairParser())); parsers.put("EC PRIVATE KEY", new KeyPairParser(new ECDSAKeyPairParser())); parsers.put("ENCRYPTED PRIVATE KEY", new EncryptedPrivateKeyParser()); parsers.put("PRIVATE KEY", new PrivateKeyParser()); } public Object readObject() throws IOException { PemObject obj = readPemObject(); if (obj != null) { String type = obj.getType(); if (parsers.containsKey(type)) { return ((PemObjectParser)parsers.get(type)).parseObject(obj); } else { throw new IOException("unrecognised object: " + type); } } return null; } private class KeyPairParser implements PemObjectParser { private final PEMKeyPairParser pemKeyPairParser; public KeyPairParser(PEMKeyPairParser pemKeyPairParser) { this.pemKeyPairParser = pemKeyPairParser; } /** * Read a Key Pair */ public Object parseObject( PemObject obj) throws IOException { boolean isEncrypted = false; String dekInfo = null; List headers = obj.getHeaders(); for (Iterator it = headers.iterator(); it.hasNext();) { PemHeader hdr = (PemHeader)it.next(); if (hdr.getName().equals("Proc-Type") && hdr.getValue().equals("4,ENCRYPTED")) { isEncrypted = true; } else if (hdr.getName().equals("DEK-Info")) { dekInfo = hdr.getValue(); } } // // extract the key // byte[] keyBytes = obj.getContent(); try { if (isEncrypted) { StringTokenizer tknz = new StringTokenizer(dekInfo, ","); String dekAlgName = tknz.nextToken(); byte[] iv = Hex.decode(tknz.nextToken()); return new PEMEncryptedKeyPair(dekAlgName, iv, keyBytes, pemKeyPairParser); } return pemKeyPairParser.parse(keyBytes); } catch (IOException e) { if (isEncrypted) { throw new PEMException("exception decoding - please check password and data.", e); } else { throw new PEMException(e.getMessage(), e); } } catch (IllegalArgumentException e) { if (isEncrypted) { throw new PEMException("exception decoding - please check password and data.", e); } else { throw new PEMException(e.getMessage(), e); } } } } private class DSAKeyPairParser implements PEMKeyPairParser { public PEMKeyPair parse(byte[] encoding) throws IOException { try { ASN1Sequence seq = ASN1Sequence.getInstance(encoding); if (seq.size() != 6) { throw new PEMException("malformed sequence in DSA private key"); } // ASN1Integer v = (ASN1Integer)seq.getObjectAt(0); ASN1Integer p = ASN1Integer.getInstance(seq.getObjectAt(1)); ASN1Integer q = ASN1Integer.getInstance(seq.getObjectAt(2)); ASN1Integer g = ASN1Integer.getInstance(seq.getObjectAt(3)); ASN1Integer y = ASN1Integer.getInstance(seq.getObjectAt(4)); ASN1Integer x = ASN1Integer.getInstance(seq.getObjectAt(5)); return new PEMKeyPair( new SubjectPublicKeyInfo(new AlgorithmIdentifier(X9ObjectIdentifiers.id_dsa, new DSAParameter(p.getValue(), q.getValue(), g.getValue())), y), new PrivateKeyInfo(new AlgorithmIdentifier(X9ObjectIdentifiers.id_dsa, new DSAParameter(p.getValue(), q.getValue(), g.getValue())), x)); } catch (IOException e) { throw e; } catch (Exception e) { throw new PEMException( "problem creating DSA private key: " + e.toString(), e); } } } private class ECDSAKeyPairParser implements PEMKeyPairParser { public PEMKeyPair parse(byte[] encoding) throws IOException { try { ASN1Sequence seq = ASN1Sequence.getInstance(encoding); org.bouncycastle.asn1.sec.ECPrivateKey pKey = org.bouncycastle.asn1.sec.ECPrivateKey.getInstance(seq); AlgorithmIdentifier algId = new AlgorithmIdentifier(X9ObjectIdentifiers.id_ecPublicKey, pKey.getParameters()); PrivateKeyInfo privInfo = new PrivateKeyInfo(algId, pKey); SubjectPublicKeyInfo pubInfo = new SubjectPublicKeyInfo(algId, pKey.getPublicKey().getBytes()); return new PEMKeyPair(pubInfo, privInfo); } catch (IOException e) { throw e; } catch (Exception e) { throw new PEMException( "problem creating EC private key: " + e.toString(), e); } } } private class RSAKeyPairParser implements PEMKeyPairParser { public PEMKeyPair parse(byte[] encoding) throws IOException { try { ASN1Sequence seq = ASN1Sequence.getInstance(encoding); if (seq.size() != 9) { throw new PEMException("malformed sequence in RSA private key"); } org.bouncycastle.asn1.pkcs.RSAPrivateKey keyStruct = org.bouncycastle.asn1.pkcs.RSAPrivateKey.getInstance(seq); RSAPublicKey pubSpec = new RSAPublicKey( keyStruct.getModulus(), keyStruct.getPublicExponent()); AlgorithmIdentifier algId = new AlgorithmIdentifier(PKCSObjectIdentifiers.rsaEncryption, DERNull.INSTANCE); return new PEMKeyPair(new SubjectPublicKeyInfo(algId, pubSpec), new PrivateKeyInfo(algId, keyStruct)); } catch (IOException e) { throw e; } catch (Exception e) { throw new PEMException( "problem creating RSA private key: " + e.toString(), e); } } } private class PublicKeyParser implements PemObjectParser { public PublicKeyParser() { } public Object parseObject(PemObject obj) throws IOException { return SubjectPublicKeyInfo.getInstance(obj.getContent()); } } private class RSAPublicKeyParser implements PemObjectParser { public RSAPublicKeyParser() { } public Object parseObject(PemObject obj) throws IOException { try { RSAPublicKey rsaPubStructure = RSAPublicKey.getInstance(obj.getContent()); return new SubjectPublicKeyInfo(new AlgorithmIdentifier(PKCSObjectIdentifiers.rsaEncryption, DERNull.INSTANCE), rsaPubStructure); } catch (IOException e) { throw e; } catch (Exception e) { throw new PEMException("problem extracting key: " + e.toString(), e); } } } private class X509CertificateParser implements PemObjectParser { /** * Reads in a X509Certificate. * * @return the X509Certificate * @throws java.io.IOException if an I/O error occured */ public Object parseObject(PemObject obj) throws IOException { try { return new X509CertificateHolder(obj.getContent()); } catch (Exception e) { throw new PEMException("problem parsing cert: " + e.toString(), e); } } } private class X509CRLParser implements PemObjectParser { /** * Reads in a X509CRL. * * @return the X509Certificate * @throws java.io.IOException if an I/O error occured */ public Object parseObject(PemObject obj) throws IOException { try { return new X509CRLHolder(obj.getContent()); } catch (Exception e) { throw new PEMException("problem parsing cert: " + e.toString(), e); } } } private class PKCS10CertificationRequestParser implements PemObjectParser { /** * Reads in a PKCS10 certification request. * * @return the certificate request. * @throws java.io.IOException if an I/O error occured */ public Object parseObject(PemObject obj) throws IOException { try { return new PKCS10CertificationRequest(obj.getContent()); } catch (Exception e) { throw new PEMException("problem parsing certrequest: " + e.toString(), e); } } } private class PKCS7Parser implements PemObjectParser { /** * Reads in a PKCS7 object. This returns a ContentInfo object suitable for use with the CMS * API. * * @return the X509Certificate * @throws java.io.IOException if an I/O error occured */ public Object parseObject(PemObject obj) throws IOException { try { ASN1InputStream aIn = new ASN1InputStream(obj.getContent()); return ContentInfo.getInstance(aIn.readObject()); } catch (Exception e) { throw new PEMException("problem parsing PKCS7 object: " + e.toString(), e); } } } private class X509AttributeCertificateParser implements PemObjectParser { public Object parseObject(PemObject obj) throws IOException { return new X509AttributeCertificateHolder(obj.getContent()); } } private class ECCurveParamsParser implements PemObjectParser { public Object parseObject(PemObject obj) throws IOException { try { Object param = ASN1Primitive.fromByteArray(obj.getContent()); if (param instanceof ASN1ObjectIdentifier) { return ASN1Primitive.fromByteArray(obj.getContent()); } else if (param instanceof ASN1Sequence) { return X9ECParameters.getInstance(param); } else { return null; // implicitly CA } } catch (IOException e) { throw e; } catch (Exception e) { throw new PEMException("exception extracting EC named curve: " + e.toString()); } } } private class EncryptedPrivateKeyParser implements PemObjectParser { public EncryptedPrivateKeyParser() { } /** * Reads in an EncryptedPrivateKeyInfo * * @return the X509Certificate * @throws java.io.IOException if an I/O error occured */ public Object parseObject(PemObject obj) throws IOException { try { return new PKCS8EncryptedPrivateKeyInfo(EncryptedPrivateKeyInfo.getInstance(obj.getContent())); } catch (Exception e) { throw new PEMException("problem parsing ENCRYPTED PRIVATE KEY: " + e.toString(), e); } } } private class PrivateKeyParser implements PemObjectParser { public PrivateKeyParser() { } public Object parseObject(PemObject obj) throws IOException { try { return PrivateKeyInfo.getInstance(obj.getContent()); } catch (Exception e) { throw new PEMException("problem parsing PRIVATE KEY: " + e.toString(), e); } } } } bouncycastle-1.49.orig/src/org/bouncycastle/openssl/PEMReader.java0000644000175000017500000010205012110277646024600 0ustar ebourgebourgpackage org.bouncycastle.openssl; import java.io.ByteArrayInputStream; import java.io.IOException; import java.io.Reader; import java.security.AlgorithmParameters; import java.security.Key; import java.security.KeyFactory; import java.security.KeyPair; import java.security.NoSuchAlgorithmException; import java.security.NoSuchProviderException; import java.security.Provider; import java.security.PublicKey; import java.security.Security; import java.security.cert.CertificateFactory; import java.security.spec.AlgorithmParameterSpec; import java.security.spec.DSAPrivateKeySpec; import java.security.spec.DSAPublicKeySpec; import java.security.spec.InvalidKeySpecException; import java.security.spec.KeySpec; import java.security.spec.PKCS8EncodedKeySpec; import java.security.spec.RSAPrivateCrtKeySpec; import java.security.spec.RSAPublicKeySpec; import java.security.spec.X509EncodedKeySpec; import java.util.HashMap; import java.util.Iterator; import java.util.List; import java.util.Map; import java.util.StringTokenizer; import javax.crypto.Cipher; import javax.crypto.SecretKey; import javax.crypto.SecretKeyFactory; import javax.crypto.spec.IvParameterSpec; import javax.crypto.spec.PBEKeySpec; import javax.crypto.spec.PBEParameterSpec; import javax.crypto.spec.RC2ParameterSpec; import javax.crypto.spec.SecretKeySpec; import org.bouncycastle.asn1.ASN1InputStream; import org.bouncycastle.asn1.ASN1Primitive; import org.bouncycastle.asn1.ASN1Sequence; import org.bouncycastle.asn1.DERInteger; import org.bouncycastle.asn1.DERObjectIdentifier; import org.bouncycastle.asn1.cms.ContentInfo; import org.bouncycastle.asn1.pkcs.EncryptedPrivateKeyInfo; import org.bouncycastle.asn1.pkcs.EncryptionScheme; import org.bouncycastle.asn1.pkcs.KeyDerivationFunc; import org.bouncycastle.asn1.pkcs.PBEParameter; import org.bouncycastle.asn1.pkcs.PBES2Parameters; import org.bouncycastle.asn1.pkcs.PBKDF2Params; import org.bouncycastle.asn1.pkcs.PKCS12PBEParams; import org.bouncycastle.asn1.pkcs.PrivateKeyInfo; import org.bouncycastle.asn1.pkcs.RSAPublicKey; import org.bouncycastle.asn1.x509.AlgorithmIdentifier; import org.bouncycastle.asn1.x509.SubjectPublicKeyInfo; import org.bouncycastle.asn1.x9.X9ObjectIdentifiers; import org.bouncycastle.crypto.PBEParametersGenerator; import org.bouncycastle.crypto.generators.OpenSSLPBEParametersGenerator; import org.bouncycastle.crypto.generators.PKCS5S2ParametersGenerator; import org.bouncycastle.crypto.params.KeyParameter; import org.bouncycastle.jce.ECNamedCurveTable; import org.bouncycastle.jce.PKCS10CertificationRequest; import org.bouncycastle.util.encoders.Hex; import org.bouncycastle.util.io.pem.PemHeader; import org.bouncycastle.util.io.pem.PemObject; import org.bouncycastle.util.io.pem.PemObjectParser; import org.bouncycastle.util.io.pem.PemReader; import org.bouncycastle.x509.X509V2AttributeCertificate; /** * Class for reading OpenSSL PEM encoded streams containing * X509 certificates, PKCS8 encoded keys and PKCS7 objects. *

    * In the case of PKCS7 objects the reader will return a CMS ContentInfo object. Keys and * Certificates will be returned using the appropriate java.security type (KeyPair, PublicKey, X509Certificate, * or X509CRL). In the case of a Certificate Request a PKCS10CertificationRequest will be returned. *

    * * @deprecated use PEMParser */ public class PEMReader extends PemReader { private final Map parsers = new HashMap(); private PasswordFinder pFinder; /** * Create a new PEMReader * * @param reader the Reader * @deprecated use PEMParser */ public PEMReader( Reader reader) { this(reader, null, "BC"); } /** * Create a new PEMReader with a password finder * * @param reader the Reader * @param pFinder the password finder * @deprecated use PEMParser */ public PEMReader( Reader reader, PasswordFinder pFinder) { this(reader, pFinder, "BC"); } /** * Create a new PEMReader with a password finder * * @param reader the Reader * @param pFinder the password finder * @param provider the cryptography provider to use * @deprecated use PEMParser */ public PEMReader( Reader reader, PasswordFinder pFinder, String provider) { this(reader, pFinder, provider, provider); } /** * Create a new PEMReader with a password finder and differing providers for secret and public key * operations. * * @param reader the Reader * @param pFinder the password finder * @param symProvider provider to use for symmetric operations * @param asymProvider provider to use for asymmetric (public/private key) operations * @deprecated use PEMParser */ public PEMReader( Reader reader, PasswordFinder pFinder, String symProvider, String asymProvider) { super(reader); this.pFinder = pFinder; parsers.put("CERTIFICATE REQUEST", new PKCS10CertificationRequestParser()); parsers.put("NEW CERTIFICATE REQUEST", new PKCS10CertificationRequestParser()); parsers.put("CERTIFICATE", new X509CertificateParser(asymProvider)); parsers.put("X509 CERTIFICATE", new X509CertificateParser(asymProvider)); parsers.put("X509 CRL", new X509CRLParser(asymProvider)); parsers.put("PKCS7", new PKCS7Parser()); parsers.put("ATTRIBUTE CERTIFICATE", new X509AttributeCertificateParser()); parsers.put("EC PARAMETERS", new ECNamedCurveSpecParser()); parsers.put("PUBLIC KEY", new PublicKeyParser(asymProvider)); parsers.put("RSA PUBLIC KEY", new RSAPublicKeyParser(asymProvider)); parsers.put("RSA PRIVATE KEY", new RSAKeyPairParser(symProvider, asymProvider)); parsers.put("DSA PRIVATE KEY", new DSAKeyPairParser(symProvider, asymProvider)); parsers.put("EC PRIVATE KEY", new ECDSAKeyPairParser(symProvider, asymProvider)); parsers.put("ENCRYPTED PRIVATE KEY", new EncryptedPrivateKeyParser(symProvider, asymProvider)); parsers.put("PRIVATE KEY", new PrivateKeyParser(asymProvider)); } public Object readObject() throws IOException { PemObject obj = readPemObject(); if (obj != null) { String type = obj.getType(); if (parsers.containsKey(type)) { return ((PemObjectParser)parsers.get(type)).parseObject(obj); } else { throw new IOException("unrecognised object: " + type); } } return null; } private abstract class KeyPairParser implements PemObjectParser { protected String symProvider; public KeyPairParser(String symProvider) { this.symProvider = symProvider; } /** * Read a Key Pair */ protected ASN1Sequence readKeyPair( PemObject obj) throws IOException { boolean isEncrypted = false; String dekInfo = null; List headers = obj.getHeaders(); for (Iterator it = headers.iterator(); it.hasNext(); ) { PemHeader hdr = (PemHeader)it.next(); if (hdr.getName().equals("Proc-Type") && hdr.getValue().equals("4,ENCRYPTED")) { isEncrypted = true; } else if (hdr.getName().equals("DEK-Info")) { dekInfo = hdr.getValue(); } } // // extract the key // byte[] keyBytes = obj.getContent(); if (isEncrypted) { if (pFinder == null) { throw new PasswordException("No password finder specified, but a password is required"); } char[] password = pFinder.getPassword(); if (password == null) { throw new PasswordException("Password is null, but a password is required"); } StringTokenizer tknz = new StringTokenizer(dekInfo, ","); String dekAlgName = tknz.nextToken(); byte[] iv = Hex.decode(tknz.nextToken()); keyBytes = crypt(false, symProvider, keyBytes, password, dekAlgName, iv); } try { return ASN1Sequence.getInstance(ASN1Primitive.fromByteArray(keyBytes)); } catch (IOException e) { if (isEncrypted) { throw new PEMException("exception decoding - please check password and data.", e); } else { throw new PEMException(e.getMessage(), e); } } catch (IllegalArgumentException e) { if (isEncrypted) { throw new PEMException("exception decoding - please check password and data.", e); } else { throw new PEMException(e.getMessage(), e); } } } } private class DSAKeyPairParser extends KeyPairParser { private String asymProvider; public DSAKeyPairParser(String symProvider, String asymProvider) { super(symProvider); this.asymProvider = asymProvider; } public Object parseObject(PemObject obj) throws IOException { try { ASN1Sequence seq = readKeyPair(obj); if (seq.size() != 6) { throw new PEMException("malformed sequence in DSA private key"); } // DERInteger v = (DERInteger)seq.getObjectAt(0); DERInteger p = (DERInteger)seq.getObjectAt(1); DERInteger q = (DERInteger)seq.getObjectAt(2); DERInteger g = (DERInteger)seq.getObjectAt(3); DERInteger y = (DERInteger)seq.getObjectAt(4); DERInteger x = (DERInteger)seq.getObjectAt(5); DSAPrivateKeySpec privSpec = new DSAPrivateKeySpec( x.getValue(), p.getValue(), q.getValue(), g.getValue()); DSAPublicKeySpec pubSpec = new DSAPublicKeySpec( y.getValue(), p.getValue(), q.getValue(), g.getValue()); KeyFactory fact = KeyFactory.getInstance("DSA", asymProvider); return new KeyPair( fact.generatePublic(pubSpec), fact.generatePrivate(privSpec)); } catch (IOException e) { throw e; } catch (Exception e) { throw new PEMException( "problem creating DSA private key: " + e.toString(), e); } } } private class ECDSAKeyPairParser extends KeyPairParser { private String asymProvider; public ECDSAKeyPairParser(String symProvider, String asymProvider) { super(symProvider); this.asymProvider = asymProvider; } public Object parseObject(PemObject obj) throws IOException { try { ASN1Sequence seq = readKeyPair(obj); org.bouncycastle.asn1.sec.ECPrivateKey pKey = org.bouncycastle.asn1.sec.ECPrivateKey.getInstance(seq); AlgorithmIdentifier algId = new AlgorithmIdentifier(X9ObjectIdentifiers.id_ecPublicKey, pKey.getParameters()); PrivateKeyInfo privInfo = new PrivateKeyInfo(algId, pKey); SubjectPublicKeyInfo pubInfo = new SubjectPublicKeyInfo(algId, pKey.getPublicKey().getBytes()); PKCS8EncodedKeySpec privSpec = new PKCS8EncodedKeySpec(privInfo.getEncoded()); X509EncodedKeySpec pubSpec = new X509EncodedKeySpec(pubInfo.getEncoded()); KeyFactory fact = KeyFactory.getInstance("ECDSA", asymProvider); return new KeyPair( fact.generatePublic(pubSpec), fact.generatePrivate(privSpec)); } catch (IOException e) { throw e; } catch (Exception e) { throw new PEMException( "problem creating EC private key: " + e.toString(), e); } } } private class RSAKeyPairParser extends KeyPairParser { private String asymProvider; public RSAKeyPairParser(String symProvider, String asymProvider) { super(symProvider); this.asymProvider = asymProvider; } public Object parseObject(PemObject obj) throws IOException { try { ASN1Sequence seq = readKeyPair(obj); if (seq.size() != 9) { throw new PEMException("malformed sequence in RSA private key"); } org.bouncycastle.asn1.pkcs.RSAPrivateKey keyStruct = org.bouncycastle.asn1.pkcs.RSAPrivateKey.getInstance(seq); RSAPublicKeySpec pubSpec = new RSAPublicKeySpec( keyStruct.getModulus(), keyStruct.getPublicExponent()); RSAPrivateCrtKeySpec privSpec = new RSAPrivateCrtKeySpec( keyStruct.getModulus(), keyStruct.getPublicExponent(), keyStruct.getPrivateExponent(), keyStruct.getPrime1(), keyStruct.getPrime2(), keyStruct.getExponent1(), keyStruct.getExponent2(), keyStruct.getCoefficient()); KeyFactory fact = KeyFactory.getInstance("RSA", asymProvider); return new KeyPair( fact.generatePublic(pubSpec), fact.generatePrivate(privSpec)); } catch (IOException e) { throw e; } catch (Exception e) { throw new PEMException( "problem creating RSA private key: " + e.toString(), e); } } } private class PublicKeyParser implements PemObjectParser { private String provider; public PublicKeyParser(String provider) { this.provider = provider; } public Object parseObject(PemObject obj) throws IOException { KeySpec keySpec = new X509EncodedKeySpec(obj.getContent()); String[] algorithms = {"DSA", "RSA"}; for (int i = 0; i < algorithms.length; i++) { try { KeyFactory keyFact = KeyFactory.getInstance(algorithms[i], provider); PublicKey pubKey = keyFact.generatePublic(keySpec); return pubKey; } catch (NoSuchAlgorithmException e) { // ignore } catch (InvalidKeySpecException e) { // ignore } catch (NoSuchProviderException e) { throw new RuntimeException("can't find provider " + provider); } } return null; } } private class RSAPublicKeyParser implements PemObjectParser { private String provider; public RSAPublicKeyParser(String provider) { this.provider = provider; } public Object parseObject(PemObject obj) throws IOException { try { ASN1InputStream ais = new ASN1InputStream(obj.getContent()); Object asnObject = ais.readObject(); ASN1Sequence sequence = (ASN1Sequence)asnObject; RSAPublicKey rsaPubStructure = RSAPublicKey.getInstance(sequence); RSAPublicKeySpec keySpec = new RSAPublicKeySpec( rsaPubStructure.getModulus(), rsaPubStructure.getPublicExponent()); KeyFactory keyFact = KeyFactory.getInstance("RSA", provider); return keyFact.generatePublic(keySpec); } catch (IOException e) { throw e; } catch (NoSuchProviderException e) { throw new IOException("can't find provider " + provider); } catch (Exception e) { throw new PEMException("problem extracting key: " + e.toString(), e); } } } private class X509CertificateParser implements PemObjectParser { private String provider; public X509CertificateParser(String provider) { this.provider = provider; } /** * Reads in a X509Certificate. * * @return the X509Certificate * @throws IOException if an I/O error occured */ public Object parseObject(PemObject obj) throws IOException { ByteArrayInputStream bIn = new ByteArrayInputStream(obj.getContent()); try { CertificateFactory certFact = CertificateFactory.getInstance("X.509", provider); return certFact.generateCertificate(bIn); } catch (Exception e) { throw new PEMException("problem parsing cert: " + e.toString(), e); } } } private class X509CRLParser implements PemObjectParser { private String provider; public X509CRLParser(String provider) { this.provider = provider; } /** * Reads in a X509CRL. * * @return the X509Certificate * @throws IOException if an I/O error occured */ public Object parseObject(PemObject obj) throws IOException { ByteArrayInputStream bIn = new ByteArrayInputStream(obj.getContent()); try { CertificateFactory certFact = CertificateFactory.getInstance("X.509", provider); return certFact.generateCRL(bIn); } catch (Exception e) { throw new PEMException("problem parsing cert: " + e.toString(), e); } } } private class PKCS10CertificationRequestParser implements PemObjectParser { /** * Reads in a PKCS10 certification request. * * @return the certificate request. * @throws IOException if an I/O error occured */ public Object parseObject(PemObject obj) throws IOException { try { return new PKCS10CertificationRequest(obj.getContent()); } catch (Exception e) { throw new PEMException("problem parsing certrequest: " + e.toString(), e); } } } private class PKCS7Parser implements PemObjectParser { /** * Reads in a PKCS7 object. This returns a ContentInfo object suitable for use with the CMS * API. * * @return the X509Certificate * @throws IOException if an I/O error occured */ public Object parseObject(PemObject obj) throws IOException { try { ASN1InputStream aIn = new ASN1InputStream(obj.getContent()); return ContentInfo.getInstance(aIn.readObject()); } catch (Exception e) { throw new PEMException("problem parsing PKCS7 object: " + e.toString(), e); } } } private class X509AttributeCertificateParser implements PemObjectParser { public Object parseObject(PemObject obj) throws IOException { return new X509V2AttributeCertificate(obj.getContent()); } } private class ECNamedCurveSpecParser implements PemObjectParser { public Object parseObject(PemObject obj) throws IOException { try { DERObjectIdentifier oid = (DERObjectIdentifier)ASN1Primitive.fromByteArray(obj.getContent()); Object params = ECNamedCurveTable.getParameterSpec(oid.getId()); if (params == null) { throw new IOException("object ID not found in EC curve table"); } return params; } catch (IOException e) { throw e; } catch (Exception e) { throw new PEMException("exception extracting EC named curve: " + e.toString()); } } } private class EncryptedPrivateKeyParser implements PemObjectParser { private String symProvider; private String asymProvider; public EncryptedPrivateKeyParser(String symProvider, String asymProvider) { this.symProvider = symProvider; this.asymProvider = asymProvider; } /** * Reads in a X509CRL. * * @return the X509Certificate * @throws IOException if an I/O error occured */ public Object parseObject(PemObject obj) throws IOException { try { EncryptedPrivateKeyInfo info = EncryptedPrivateKeyInfo.getInstance(ASN1Primitive.fromByteArray(obj.getContent())); AlgorithmIdentifier algId = info.getEncryptionAlgorithm(); if (pFinder == null) { throw new PEMException("no PasswordFinder specified"); } if (PEMUtilities.isPKCS5Scheme2(algId.getAlgorithm())) { PBES2Parameters params = PBES2Parameters.getInstance(algId.getParameters()); KeyDerivationFunc func = params.getKeyDerivationFunc(); EncryptionScheme scheme = params.getEncryptionScheme(); PBKDF2Params defParams = (PBKDF2Params)func.getParameters(); int iterationCount = defParams.getIterationCount().intValue(); byte[] salt = defParams.getSalt(); String algorithm = scheme.getAlgorithm().getId(); SecretKey key = generateSecretKeyForPKCS5Scheme2(algorithm, pFinder.getPassword(), salt, iterationCount); Cipher cipher = Cipher.getInstance(algorithm, symProvider); AlgorithmParameters algParams = AlgorithmParameters.getInstance(algorithm, symProvider); algParams.init(scheme.getParameters().toASN1Primitive().getEncoded()); cipher.init(Cipher.DECRYPT_MODE, key, algParams); PrivateKeyInfo pInfo = PrivateKeyInfo.getInstance(ASN1Primitive.fromByteArray(cipher.doFinal(info.getEncryptedData()))); PKCS8EncodedKeySpec keySpec = new PKCS8EncodedKeySpec(pInfo.getEncoded()); KeyFactory keyFact = KeyFactory.getInstance(pInfo.getPrivateKeyAlgorithm().getAlgorithm().getId(), asymProvider); return keyFact.generatePrivate(keySpec); } else if (PEMUtilities.isPKCS12(algId.getAlgorithm())) { PKCS12PBEParams params = PKCS12PBEParams.getInstance(algId.getParameters()); String algorithm = algId.getAlgorithm().getId(); PBEKeySpec pbeSpec = new PBEKeySpec(pFinder.getPassword()); SecretKeyFactory secKeyFact = SecretKeyFactory.getInstance(algorithm, symProvider); PBEParameterSpec defParams = new PBEParameterSpec(params.getIV(), params.getIterations().intValue()); Cipher cipher = Cipher.getInstance(algorithm, symProvider); cipher.init(Cipher.DECRYPT_MODE, secKeyFact.generateSecret(pbeSpec), defParams); PrivateKeyInfo pInfo = PrivateKeyInfo.getInstance(ASN1Primitive.fromByteArray(cipher.doFinal(info.getEncryptedData()))); PKCS8EncodedKeySpec keySpec = new PKCS8EncodedKeySpec(pInfo.getEncoded()); KeyFactory keyFact = KeyFactory.getInstance(pInfo.getPrivateKeyAlgorithm().getAlgorithm().getId(), asymProvider); return keyFact.generatePrivate(keySpec); } else if (PEMUtilities.isPKCS5Scheme1(algId.getAlgorithm())) { PBEParameter params = PBEParameter.getInstance(algId.getParameters()); String algorithm = algId.getAlgorithm().getId(); PBEKeySpec pbeSpec = new PBEKeySpec(pFinder.getPassword()); SecretKeyFactory secKeyFact = SecretKeyFactory.getInstance(algorithm, symProvider); PBEParameterSpec defParams = new PBEParameterSpec(params.getSalt(), params.getIterationCount().intValue()); Cipher cipher = Cipher.getInstance(algorithm, symProvider); cipher.init(Cipher.DECRYPT_MODE, secKeyFact.generateSecret(pbeSpec), defParams); PrivateKeyInfo pInfo = PrivateKeyInfo.getInstance(ASN1Primitive.fromByteArray(cipher.doFinal(info.getEncryptedData()))); PKCS8EncodedKeySpec keySpec = new PKCS8EncodedKeySpec(pInfo.getEncoded()); KeyFactory keyFact = KeyFactory.getInstance(pInfo.getPrivateKeyAlgorithm().getAlgorithm().getId(), asymProvider); return keyFact.generatePrivate(keySpec); } else { throw new PEMException("Unknown algorithm: " + algId.getAlgorithm()); } } catch (IOException e) { throw e; } catch (Exception e) { throw new PEMException("problem parsing ENCRYPTED PRIVATE KEY: " + e.toString(), e); } } } private class PrivateKeyParser implements PemObjectParser { private String provider; public PrivateKeyParser(String provider) { this.provider = provider; } public Object parseObject(PemObject obj) throws IOException { try { PrivateKeyInfo info = PrivateKeyInfo.getInstance(ASN1Primitive.fromByteArray(obj.getContent())); PKCS8EncodedKeySpec keySpec = new PKCS8EncodedKeySpec(obj.getContent()); KeyFactory keyFact = KeyFactory.getInstance(info.getPrivateKeyAlgorithm().getAlgorithm().getId(), provider); return keyFact.generatePrivate(keySpec); } catch (Exception e) { throw new PEMException("problem parsing PRIVATE KEY: " + e.toString(), e); } } } static byte[] crypt( boolean encrypt, String provider, byte[] bytes, char[] password, String dekAlgName, byte[] iv) throws IOException { Provider prov = null; if (provider != null) { prov = Security.getProvider(provider); if (prov == null) { throw new EncryptionException("cannot find provider: " + provider); } } return crypt(encrypt, prov, bytes, password, dekAlgName, iv); } static byte[] crypt( boolean encrypt, Provider provider, byte[] bytes, char[] password, String dekAlgName, byte[] iv) throws IOException { AlgorithmParameterSpec paramSpec = new IvParameterSpec(iv); String alg; String blockMode = "CBC"; String padding = "PKCS5Padding"; Key sKey; // Figure out block mode and padding. if (dekAlgName.endsWith("-CFB")) { blockMode = "CFB"; padding = "NoPadding"; } if (dekAlgName.endsWith("-ECB") || "DES-EDE".equals(dekAlgName) || "DES-EDE3".equals(dekAlgName)) { // ECB is actually the default (though seldom used) when OpenSSL // uses DES-EDE (des2) or DES-EDE3 (des3). blockMode = "ECB"; paramSpec = null; } if (dekAlgName.endsWith("-OFB")) { blockMode = "OFB"; padding = "NoPadding"; } // Figure out algorithm and key size. if (dekAlgName.startsWith("DES-EDE")) { alg = "DESede"; // "DES-EDE" is actually des2 in OpenSSL-speak! // "DES-EDE3" is des3. boolean des2 = !dekAlgName.startsWith("DES-EDE3"); sKey = getKey(password, alg, 24, iv, des2); } else if (dekAlgName.startsWith("DES-")) { alg = "DES"; sKey = getKey(password, alg, 8, iv); } else if (dekAlgName.startsWith("BF-")) { alg = "Blowfish"; sKey = getKey(password, alg, 16, iv); } else if (dekAlgName.startsWith("RC2-")) { alg = "RC2"; int keyBits = 128; if (dekAlgName.startsWith("RC2-40-")) { keyBits = 40; } else if (dekAlgName.startsWith("RC2-64-")) { keyBits = 64; } sKey = getKey(password, alg, keyBits / 8, iv); if (paramSpec == null) // ECB block mode { paramSpec = new RC2ParameterSpec(keyBits); } else { paramSpec = new RC2ParameterSpec(keyBits, iv); } } else if (dekAlgName.startsWith("AES-")) { alg = "AES"; byte[] salt = iv; if (salt.length > 8) { salt = new byte[8]; System.arraycopy(iv, 0, salt, 0, 8); } int keyBits; if (dekAlgName.startsWith("AES-128-")) { keyBits = 128; } else if (dekAlgName.startsWith("AES-192-")) { keyBits = 192; } else if (dekAlgName.startsWith("AES-256-")) { keyBits = 256; } else { throw new EncryptionException("unknown AES encryption with private key"); } sKey = getKey(password, "AES", keyBits / 8, salt); } else { throw new EncryptionException("unknown encryption with private key"); } String transformation = alg + "/" + blockMode + "/" + padding; try { Cipher c = Cipher.getInstance(transformation, provider); int mode = encrypt ? Cipher.ENCRYPT_MODE : Cipher.DECRYPT_MODE; if (paramSpec == null) // ECB block mode { c.init(mode, sKey); } else { c.init(mode, sKey, paramSpec); } return c.doFinal(bytes); } catch (Exception e) { throw new EncryptionException("exception using cipher - please check password and data.", e); } } private static SecretKey getKey( char[] password, String algorithm, int keyLength, byte[] salt) { return getKey(password, algorithm, keyLength, salt, false); } private static SecretKey getKey( char[] password, String algorithm, int keyLength, byte[] salt, boolean des2) { OpenSSLPBEParametersGenerator pGen = new OpenSSLPBEParametersGenerator(); pGen.init(PBEParametersGenerator.PKCS5PasswordToBytes(password), salt); KeyParameter keyParam; keyParam = (KeyParameter)pGen.generateDerivedParameters(keyLength * 8); byte[] key = keyParam.getKey(); if (des2 && key.length >= 24) { // For DES2, we must copy first 8 bytes into the last 8 bytes. System.arraycopy(key, 0, key, 16, 8); } return new javax.crypto.spec.SecretKeySpec(key, algorithm); } public static SecretKey generateSecretKeyForPKCS5Scheme2(String algorithm, char[] password, byte[] salt, int iterationCount) { PBEParametersGenerator generator = new PKCS5S2ParametersGenerator(); generator.init( PBEParametersGenerator.PKCS5PasswordToBytes(password), salt, iterationCount); return new SecretKeySpec(((KeyParameter)generator.generateDerivedParameters(PEMUtilities.getKeySize(algorithm))).getKey(), algorithm); } } bouncycastle-1.49.orig/src/org/bouncycastle/openssl/PasswordException.java0000644000175000017500000000025012101670411026477 0ustar ebourgebourgpackage org.bouncycastle.openssl; public class PasswordException extends PEMException { public PasswordException(String msg) { super(msg); } } bouncycastle-1.49.orig/src/org/bouncycastle/openssl/PEMUtilities.java0000644000175000017500000000460512104123547025351 0ustar ebourgebourgpackage org.bouncycastle.openssl; import java.util.HashMap; import java.util.HashSet; import java.util.Map; import java.util.Set; import org.bouncycastle.asn1.ASN1ObjectIdentifier; import org.bouncycastle.asn1.DERObjectIdentifier; import org.bouncycastle.asn1.nist.NISTObjectIdentifiers; import org.bouncycastle.asn1.pkcs.PKCSObjectIdentifiers; import org.bouncycastle.util.Integers; public final class PEMUtilities { private static final Map KEYSIZES = new HashMap(); private static final Set PKCS5_SCHEME_1 = new HashSet(); private static final Set PKCS5_SCHEME_2 = new HashSet(); static { PKCS5_SCHEME_1.add(PKCSObjectIdentifiers.pbeWithMD2AndDES_CBC); PKCS5_SCHEME_1.add(PKCSObjectIdentifiers.pbeWithMD2AndRC2_CBC); PKCS5_SCHEME_1.add(PKCSObjectIdentifiers.pbeWithMD5AndDES_CBC); PKCS5_SCHEME_1.add(PKCSObjectIdentifiers.pbeWithMD5AndRC2_CBC); PKCS5_SCHEME_1.add(PKCSObjectIdentifiers.pbeWithSHA1AndDES_CBC); PKCS5_SCHEME_1.add(PKCSObjectIdentifiers.pbeWithSHA1AndRC2_CBC); PKCS5_SCHEME_2.add(PKCSObjectIdentifiers.id_PBES2); PKCS5_SCHEME_2.add(PKCSObjectIdentifiers.des_EDE3_CBC); PKCS5_SCHEME_2.add(NISTObjectIdentifiers.id_aes128_CBC); PKCS5_SCHEME_2.add(NISTObjectIdentifiers.id_aes192_CBC); PKCS5_SCHEME_2.add(NISTObjectIdentifiers.id_aes256_CBC); KEYSIZES.put(PKCSObjectIdentifiers.des_EDE3_CBC.getId(), Integers.valueOf(192)); KEYSIZES.put(NISTObjectIdentifiers.id_aes128_CBC.getId(), Integers.valueOf(128)); KEYSIZES.put(NISTObjectIdentifiers.id_aes192_CBC.getId(), Integers.valueOf(192)); KEYSIZES.put(NISTObjectIdentifiers.id_aes256_CBC.getId(), Integers.valueOf(256)); } static int getKeySize(String algorithm) { if (!KEYSIZES.containsKey(algorithm)) { throw new IllegalStateException("no key size for algorithm: " + algorithm); } return ((Integer)KEYSIZES.get(algorithm)).intValue(); } static boolean isPKCS5Scheme1(DERObjectIdentifier algOid) { return PKCS5_SCHEME_1.contains(algOid); } public static boolean isPKCS5Scheme2(ASN1ObjectIdentifier algOid) { return PKCS5_SCHEME_2.contains(algOid); } public static boolean isPKCS12(DERObjectIdentifier algOid) { return algOid.getId().startsWith(PKCSObjectIdentifiers.pkcs_12PbeIds.getId()); } } bouncycastle-1.49.orig/src/org/bouncycastle/openssl/PEMKeyPairParser.java0000644000175000017500000000024112101675735026117 0ustar ebourgebourgpackage org.bouncycastle.openssl; import java.io.IOException; interface PEMKeyPairParser { PEMKeyPair parse(byte[] encoding) throws IOException; } bouncycastle-1.49.orig/src/org/bouncycastle/openssl/PEMEncryptor.java0000644000175000017500000000026712104053521025355 0ustar ebourgebourgpackage org.bouncycastle.openssl; public interface PEMEncryptor { String getAlgorithm(); byte[] getIV(); byte[] encrypt(byte[] encoding) throws PEMException; } bouncycastle-1.49.orig/src/org/bouncycastle/openssl/PasswordFinder.java0000644000175000017500000000026610262753174025775 0ustar ebourgebourgpackage org.bouncycastle.openssl; /** * call back to allow a password to be fetched when one is requested. */ public interface PasswordFinder { public char[] getPassword(); } bouncycastle-1.49.orig/src/org/bouncycastle/openssl/jcajce/0000755000175000017500000000000012152033551023401 5ustar ebourgebourgbouncycastle-1.49.orig/src/org/bouncycastle/openssl/jcajce/JcaPKCS8Generator.java0000644000175000017500000000103711777720611027376 0ustar ebourgebourgpackage org.bouncycastle.openssl.jcajce; import java.security.PrivateKey; import org.bouncycastle.asn1.pkcs.PrivateKeyInfo; import org.bouncycastle.openssl.PKCS8Generator; import org.bouncycastle.operator.OutputEncryptor; import org.bouncycastle.util.io.pem.PemGenerationException; public class JcaPKCS8Generator extends PKCS8Generator { public JcaPKCS8Generator(PrivateKey key, OutputEncryptor encryptor) throws PemGenerationException { super(PrivateKeyInfo.getInstance(key.getEncoded()), encryptor); } } ././@LongLink0000000000000000000000000000015000000000000011561 Lustar rootrootbouncycastle-1.49.orig/src/org/bouncycastle/openssl/jcajce/JceOpenSSLPKCS8DecryptorProviderBuilder.javabouncycastle-1.49.orig/src/org/bouncycastle/openssl/jcajce/JceOpenSSLPKCS8DecryptorProviderBuilder.j0000644000175000017500000001336612110310623033151 0ustar ebourgebourgpackage org.bouncycastle.openssl.jcajce; import java.io.IOException; import java.io.InputStream; import java.security.AlgorithmParameters; import java.security.GeneralSecurityException; import java.security.Provider; import javax.crypto.Cipher; import javax.crypto.CipherInputStream; import javax.crypto.SecretKey; import javax.crypto.SecretKeyFactory; import javax.crypto.spec.PBEKeySpec; import javax.crypto.spec.PBEParameterSpec; import org.bouncycastle.asn1.pkcs.EncryptionScheme; import org.bouncycastle.asn1.pkcs.KeyDerivationFunc; import org.bouncycastle.asn1.pkcs.PBEParameter; import org.bouncycastle.asn1.pkcs.PBES2Parameters; import org.bouncycastle.asn1.pkcs.PBKDF2Params; import org.bouncycastle.asn1.pkcs.PKCS12PBEParams; import org.bouncycastle.asn1.x509.AlgorithmIdentifier; import org.bouncycastle.jcajce.DefaultJcaJceHelper; import org.bouncycastle.jcajce.JcaJceHelper; import org.bouncycastle.jcajce.NamedJcaJceHelper; import org.bouncycastle.jcajce.ProviderJcaJceHelper; import org.bouncycastle.openssl.PEMException; import org.bouncycastle.operator.InputDecryptor; import org.bouncycastle.operator.InputDecryptorProvider; import org.bouncycastle.operator.OperatorCreationException; public class JceOpenSSLPKCS8DecryptorProviderBuilder { private JcaJceHelper helper = new DefaultJcaJceHelper(); public JceOpenSSLPKCS8DecryptorProviderBuilder() { helper = new DefaultJcaJceHelper(); } public JceOpenSSLPKCS8DecryptorProviderBuilder setProvider(String providerName) { helper = new NamedJcaJceHelper(providerName); return this; } public JceOpenSSLPKCS8DecryptorProviderBuilder setProvider(Provider provider) { helper = new ProviderJcaJceHelper(provider); return this; } public InputDecryptorProvider build(final char[] password) throws OperatorCreationException { return new InputDecryptorProvider() { public InputDecryptor get(final AlgorithmIdentifier algorithm) throws OperatorCreationException { final Cipher cipher; try { if (PEMUtilities.isPKCS5Scheme2(algorithm.getAlgorithm())) { PBES2Parameters params = PBES2Parameters.getInstance(algorithm.getParameters()); KeyDerivationFunc func = params.getKeyDerivationFunc(); EncryptionScheme scheme = params.getEncryptionScheme(); PBKDF2Params defParams = (PBKDF2Params)func.getParameters(); int iterationCount = defParams.getIterationCount().intValue(); byte[] salt = defParams.getSalt(); String oid = scheme.getAlgorithm().getId(); SecretKey key = PEMUtilities.generateSecretKeyForPKCS5Scheme2(oid, password, salt, iterationCount); cipher = helper.createCipher(oid); AlgorithmParameters algParams = helper.createAlgorithmParameters(oid); algParams.init(scheme.getParameters().toASN1Primitive().getEncoded()); cipher.init(Cipher.DECRYPT_MODE, key, algParams); } else if (PEMUtilities.isPKCS12(algorithm.getAlgorithm())) { PKCS12PBEParams params = PKCS12PBEParams.getInstance(algorithm.getParameters()); PBEKeySpec pbeSpec = new PBEKeySpec(password); SecretKeyFactory secKeyFact = helper.createSecretKeyFactory(algorithm.getAlgorithm().getId()); PBEParameterSpec defParams = new PBEParameterSpec(params.getIV(), params.getIterations().intValue()); cipher = helper.createCipher(algorithm.getAlgorithm().getId()); cipher.init(Cipher.DECRYPT_MODE, secKeyFact.generateSecret(pbeSpec), defParams); } else if (PEMUtilities.isPKCS5Scheme1(algorithm.getAlgorithm())) { PBEParameter params = PBEParameter.getInstance(algorithm.getParameters()); PBEKeySpec pbeSpec = new PBEKeySpec(password); SecretKeyFactory secKeyFact = helper.createSecretKeyFactory(algorithm.getAlgorithm().getId()); PBEParameterSpec defParams = new PBEParameterSpec(params.getSalt(), params.getIterationCount().intValue()); cipher = helper.createCipher(algorithm.getAlgorithm().getId()); cipher.init(Cipher.DECRYPT_MODE, secKeyFact.generateSecret(pbeSpec), defParams); } else { throw new PEMException("Unknown algorithm: " + algorithm.getAlgorithm()); } return new InputDecryptor() { public AlgorithmIdentifier getAlgorithmIdentifier() { return algorithm; } public InputStream getInputStream(InputStream encIn) { return new CipherInputStream(encIn, cipher); } }; } catch (IOException e) { throw new OperatorCreationException(algorithm.getAlgorithm() + " not available: " + e.getMessage(), e); } catch (GeneralSecurityException e) { throw new OperatorCreationException(algorithm.getAlgorithm() + " not available: " + e.getMessage(), e); } }; }; } } bouncycastle-1.49.orig/src/org/bouncycastle/openssl/jcajce/PEMUtilities.java0000644000175000017500000002052112103440465026563 0ustar ebourgebourgpackage org.bouncycastle.openssl.jcajce; import java.security.Key; import java.security.spec.AlgorithmParameterSpec; import java.util.HashMap; import java.util.HashSet; import java.util.Map; import java.util.Set; import javax.crypto.Cipher; import javax.crypto.SecretKey; import javax.crypto.spec.IvParameterSpec; import javax.crypto.spec.RC2ParameterSpec; import javax.crypto.spec.SecretKeySpec; import org.bouncycastle.asn1.ASN1ObjectIdentifier; import org.bouncycastle.asn1.DERObjectIdentifier; import org.bouncycastle.asn1.nist.NISTObjectIdentifiers; import org.bouncycastle.asn1.pkcs.PKCSObjectIdentifiers; import org.bouncycastle.crypto.PBEParametersGenerator; import org.bouncycastle.crypto.generators.OpenSSLPBEParametersGenerator; import org.bouncycastle.crypto.generators.PKCS5S2ParametersGenerator; import org.bouncycastle.crypto.params.KeyParameter; import org.bouncycastle.jcajce.JcaJceHelper; import org.bouncycastle.openssl.EncryptionException; import org.bouncycastle.openssl.PEMException; import org.bouncycastle.util.Integers; class PEMUtilities { private static final Map KEYSIZES = new HashMap(); private static final Set PKCS5_SCHEME_1 = new HashSet(); private static final Set PKCS5_SCHEME_2 = new HashSet(); static { PKCS5_SCHEME_1.add(PKCSObjectIdentifiers.pbeWithMD2AndDES_CBC); PKCS5_SCHEME_1.add(PKCSObjectIdentifiers.pbeWithMD2AndRC2_CBC); PKCS5_SCHEME_1.add(PKCSObjectIdentifiers.pbeWithMD5AndDES_CBC); PKCS5_SCHEME_1.add(PKCSObjectIdentifiers.pbeWithMD5AndRC2_CBC); PKCS5_SCHEME_1.add(PKCSObjectIdentifiers.pbeWithSHA1AndDES_CBC); PKCS5_SCHEME_1.add(PKCSObjectIdentifiers.pbeWithSHA1AndRC2_CBC); PKCS5_SCHEME_2.add(PKCSObjectIdentifiers.id_PBES2); PKCS5_SCHEME_2.add(PKCSObjectIdentifiers.des_EDE3_CBC); PKCS5_SCHEME_2.add(NISTObjectIdentifiers.id_aes128_CBC); PKCS5_SCHEME_2.add(NISTObjectIdentifiers.id_aes192_CBC); PKCS5_SCHEME_2.add(NISTObjectIdentifiers.id_aes256_CBC); KEYSIZES.put(PKCSObjectIdentifiers.des_EDE3_CBC.getId(), Integers.valueOf(192)); KEYSIZES.put(NISTObjectIdentifiers.id_aes128_CBC.getId(), Integers.valueOf(128)); KEYSIZES.put(NISTObjectIdentifiers.id_aes192_CBC.getId(), Integers.valueOf(192)); KEYSIZES.put(NISTObjectIdentifiers.id_aes256_CBC.getId(), Integers.valueOf(256)); } static int getKeySize(String algorithm) { if (!KEYSIZES.containsKey(algorithm)) { throw new IllegalStateException("no key size for algorithm: " + algorithm); } return ((Integer)KEYSIZES.get(algorithm)).intValue(); } static boolean isPKCS5Scheme1(DERObjectIdentifier algOid) { return PKCS5_SCHEME_1.contains(algOid); } static boolean isPKCS5Scheme2(ASN1ObjectIdentifier algOid) { return PKCS5_SCHEME_2.contains(algOid); } public static boolean isPKCS12(DERObjectIdentifier algOid) { return algOid.getId().startsWith(PKCSObjectIdentifiers.pkcs_12PbeIds.getId()); } public static SecretKey generateSecretKeyForPKCS5Scheme2(String algorithm, char[] password, byte[] salt, int iterationCount) { PBEParametersGenerator generator = new PKCS5S2ParametersGenerator(); generator.init( PBEParametersGenerator.PKCS5PasswordToBytes(password), salt, iterationCount); return new SecretKeySpec(((KeyParameter)generator.generateDerivedParameters(PEMUtilities.getKeySize(algorithm))).getKey(), algorithm); } static byte[] crypt( boolean encrypt, JcaJceHelper helper, byte[] bytes, char[] password, String dekAlgName, byte[] iv) throws PEMException { AlgorithmParameterSpec paramSpec = new IvParameterSpec(iv); String alg; String blockMode = "CBC"; String padding = "PKCS5Padding"; Key sKey; // Figure out block mode and padding. if (dekAlgName.endsWith("-CFB")) { blockMode = "CFB"; padding = "NoPadding"; } if (dekAlgName.endsWith("-ECB") || "DES-EDE".equals(dekAlgName) || "DES-EDE3".equals(dekAlgName)) { // ECB is actually the default (though seldom used) when OpenSSL // uses DES-EDE (des2) or DES-EDE3 (des3). blockMode = "ECB"; paramSpec = null; } if (dekAlgName.endsWith("-OFB")) { blockMode = "OFB"; padding = "NoPadding"; } // Figure out algorithm and key size. if (dekAlgName.startsWith("DES-EDE")) { alg = "DESede"; // "DES-EDE" is actually des2 in OpenSSL-speak! // "DES-EDE3" is des3. boolean des2 = !dekAlgName.startsWith("DES-EDE3"); sKey = getKey(password, alg, 24, iv, des2); } else if (dekAlgName.startsWith("DES-")) { alg = "DES"; sKey = getKey(password, alg, 8, iv); } else if (dekAlgName.startsWith("BF-")) { alg = "Blowfish"; sKey = getKey(password, alg, 16, iv); } else if (dekAlgName.startsWith("RC2-")) { alg = "RC2"; int keyBits = 128; if (dekAlgName.startsWith("RC2-40-")) { keyBits = 40; } else if (dekAlgName.startsWith("RC2-64-")) { keyBits = 64; } sKey = getKey(password, alg, keyBits / 8, iv); if (paramSpec == null) // ECB block mode { paramSpec = new RC2ParameterSpec(keyBits); } else { paramSpec = new RC2ParameterSpec(keyBits, iv); } } else if (dekAlgName.startsWith("AES-")) { alg = "AES"; byte[] salt = iv; if (salt.length > 8) { salt = new byte[8]; System.arraycopy(iv, 0, salt, 0, 8); } int keyBits; if (dekAlgName.startsWith("AES-128-")) { keyBits = 128; } else if (dekAlgName.startsWith("AES-192-")) { keyBits = 192; } else if (dekAlgName.startsWith("AES-256-")) { keyBits = 256; } else { throw new EncryptionException("unknown AES encryption with private key"); } sKey = getKey(password, "AES", keyBits / 8, salt); } else { throw new EncryptionException("unknown encryption with private key"); } String transformation = alg + "/" + blockMode + "/" + padding; try { Cipher c = helper.createCipher(transformation); int mode = encrypt ? Cipher.ENCRYPT_MODE : Cipher.DECRYPT_MODE; if (paramSpec == null) // ECB block mode { c.init(mode, sKey); } else { c.init(mode, sKey, paramSpec); } return c.doFinal(bytes); } catch (Exception e) { throw new EncryptionException("exception using cipher - please check password and data.", e); } } private static SecretKey getKey( char[] password, String algorithm, int keyLength, byte[] salt) { return getKey(password, algorithm, keyLength, salt, false); } private static SecretKey getKey( char[] password, String algorithm, int keyLength, byte[] salt, boolean des2) { OpenSSLPBEParametersGenerator pGen = new OpenSSLPBEParametersGenerator(); pGen.init(PBEParametersGenerator.PKCS5PasswordToBytes(password), salt); KeyParameter keyParam; keyParam = (KeyParameter) pGen.generateDerivedParameters(keyLength * 8); byte[] key = keyParam.getKey(); if (des2 && key.length >= 24) { // For DES2, we must copy first 8 bytes into the last 8 bytes. System.arraycopy(key, 0, key, 16, 8); } return new SecretKeySpec(key, algorithm); } } bouncycastle-1.49.orig/src/org/bouncycastle/openssl/jcajce/JcePEMEncryptorBuilder.java0000644000175000017500000000353212104053521030523 0ustar ebourgebourgpackage org.bouncycastle.openssl.jcajce; import java.security.Provider; import java.security.SecureRandom; import org.bouncycastle.jcajce.DefaultJcaJceHelper; import org.bouncycastle.jcajce.JcaJceHelper; import org.bouncycastle.jcajce.NamedJcaJceHelper; import org.bouncycastle.jcajce.ProviderJcaJceHelper; import org.bouncycastle.openssl.PEMEncryptor; import org.bouncycastle.openssl.PEMException; public class JcePEMEncryptorBuilder { private final String algorithm; private JcaJceHelper helper = new DefaultJcaJceHelper(); private SecureRandom random; public JcePEMEncryptorBuilder(String algorithm) { this.algorithm = algorithm; } public JcePEMEncryptorBuilder setProvider(Provider provider) { this.helper = new ProviderJcaJceHelper(provider); return this; } public JcePEMEncryptorBuilder setProvider(String providerName) { this.helper = new NamedJcaJceHelper(providerName); return this; } public JcePEMEncryptorBuilder setSecureRandom(SecureRandom random) { this.random = random; return this; } public PEMEncryptor build(final char[] password) { if (random == null) { random = new SecureRandom(); } int ivLength = algorithm.startsWith("AES-") ? 16 : 8; final byte[] iv = new byte[ivLength]; random.nextBytes(iv); return new PEMEncryptor() { public String getAlgorithm() { return algorithm; } public byte[] getIV() { return iv; } public byte[] encrypt(byte[] encoding) throws PEMException { return PEMUtilities.crypt(true, helper, encoding, password, algorithm, iv); } }; } } bouncycastle-1.49.orig/src/org/bouncycastle/openssl/jcajce/JcaMiscPEMGenerator.java0000644000175000017500000000600612104053521027764 0ustar ebourgebourgpackage org.bouncycastle.openssl.jcajce; import java.io.IOException; import java.security.Key; import java.security.KeyPair; import java.security.PrivateKey; import java.security.Provider; import java.security.PublicKey; import java.security.SecureRandom; import java.security.cert.CRLException; import java.security.cert.CertificateEncodingException; import java.security.cert.X509CRL; import java.security.cert.X509Certificate; import org.bouncycastle.asn1.pkcs.PrivateKeyInfo; import org.bouncycastle.asn1.x509.SubjectPublicKeyInfo; import org.bouncycastle.cert.jcajce.JcaX509AttributeCertificateHolder; import org.bouncycastle.cert.jcajce.JcaX509CRLHolder; import org.bouncycastle.cert.jcajce.JcaX509CertificateHolder; import org.bouncycastle.jce.PKCS10CertificationRequest; import org.bouncycastle.openssl.MiscPEMGenerator; import org.bouncycastle.openssl.PEMEncryptor; import org.bouncycastle.x509.X509AttributeCertificate; import org.bouncycastle.x509.X509V2AttributeCertificate; /** * PEM generator for the original set of PEM objects used in Open SSL. */ public class JcaMiscPEMGenerator extends MiscPEMGenerator { private Object obj; private String algorithm; private char[] password; private SecureRandom random; private Provider provider; public JcaMiscPEMGenerator(Object o) throws IOException { super(convertObject(o)); } public JcaMiscPEMGenerator(Object o, PEMEncryptor encryptor) throws IOException { super(convertObject(o), encryptor); } private static Object convertObject(Object o) throws IOException { if (o instanceof X509Certificate) { try { return new JcaX509CertificateHolder((X509Certificate)o); } catch (CertificateEncodingException e) { throw new IllegalArgumentException("Cannot encode object: " + e.toString()); } } else if (o instanceof X509CRL) { try { return new JcaX509CRLHolder((X509CRL)o); } catch (CRLException e) { throw new IllegalArgumentException("Cannot encode object: " + e.toString()); } } else if (o instanceof KeyPair) { return convertObject(((KeyPair)o).getPrivate()); } else if (o instanceof PrivateKey) { return PrivateKeyInfo.getInstance(((Key)o).getEncoded()); } else if (o instanceof PublicKey) { return SubjectPublicKeyInfo.getInstance(((PublicKey)o).getEncoded()); } else if (o instanceof X509AttributeCertificate) { return new JcaX509AttributeCertificateHolder((X509V2AttributeCertificate)o); } else if (o instanceof PKCS10CertificationRequest) { return new org.bouncycastle.pkcs.PKCS10CertificationRequest(((PKCS10CertificationRequest)o).getEncoded()); } return o; } } bouncycastle-1.49.orig/src/org/bouncycastle/openssl/jcajce/JcePEMDecryptorProviderBuilder.java0000644000175000017500000000322512104051043032220 0ustar ebourgebourgpackage org.bouncycastle.openssl.jcajce; import java.security.Provider; import org.bouncycastle.jcajce.DefaultJcaJceHelper; import org.bouncycastle.jcajce.JcaJceHelper; import org.bouncycastle.jcajce.NamedJcaJceHelper; import org.bouncycastle.jcajce.ProviderJcaJceHelper; import org.bouncycastle.openssl.PEMDecryptor; import org.bouncycastle.openssl.PEMDecryptorProvider; import org.bouncycastle.openssl.PEMException; import org.bouncycastle.openssl.PasswordException; public class JcePEMDecryptorProviderBuilder { private JcaJceHelper helper = new DefaultJcaJceHelper(); public JcePEMDecryptorProviderBuilder setProvider(Provider provider) { this.helper = new ProviderJcaJceHelper(provider); return this; } public JcePEMDecryptorProviderBuilder setProvider(String providerName) { this.helper = new NamedJcaJceHelper(providerName); return this; } public PEMDecryptorProvider build(final char[] password) { return new PEMDecryptorProvider() { public PEMDecryptor get(final String dekAlgName) { return new PEMDecryptor() { public byte[] decrypt(byte[] keyBytes, byte[] iv) throws PEMException { if (password == null) { throw new PasswordException("Password is null, but a password is required"); } return PEMUtilities.crypt(false, helper, keyBytes, password, dekAlgName, iv); } }; } }; } } bouncycastle-1.49.orig/src/org/bouncycastle/openssl/jcajce/JcaPEMKeyConverter.java0000644000175000017500000000644112101664563027660 0ustar ebourgebourgpackage org.bouncycastle.openssl.jcajce; import java.security.KeyFactory; import java.security.KeyPair; import java.security.PrivateKey; import java.security.Provider; import java.security.PublicKey; import java.security.spec.PKCS8EncodedKeySpec; import java.security.spec.X509EncodedKeySpec; import org.bouncycastle.asn1.pkcs.PrivateKeyInfo; import org.bouncycastle.asn1.x509.SubjectPublicKeyInfo; import org.bouncycastle.asn1.x9.X9ObjectIdentifiers; import org.bouncycastle.jcajce.DefaultJcaJceHelper; import org.bouncycastle.jcajce.JcaJceHelper; import org.bouncycastle.jcajce.NamedJcaJceHelper; import org.bouncycastle.jcajce.ProviderJcaJceHelper; import org.bouncycastle.openssl.PEMException; import org.bouncycastle.openssl.PEMKeyPair; public class JcaPEMKeyConverter { private JcaJceHelper helper = new DefaultJcaJceHelper(); public JcaPEMKeyConverter setProvider(Provider provider) { this.helper = new ProviderJcaJceHelper(provider); return this; } public JcaPEMKeyConverter setProvider(String providerName) { this.helper = new NamedJcaJceHelper(providerName); return this; } public KeyPair getKeyPair(PEMKeyPair keyPair) throws PEMException { try { String algorithm = keyPair.getPrivateKeyInfo().getPrivateKeyAlgorithm().getAlgorithm().getId(); if (X9ObjectIdentifiers.id_ecPublicKey.getId().equals(algorithm)) { algorithm = "ECDSA"; } KeyFactory keyFactory = helper.createKeyFactory(algorithm); return new KeyPair(keyFactory.generatePublic(new X509EncodedKeySpec(keyPair.getPublicKeyInfo().getEncoded())), keyFactory.generatePrivate(new PKCS8EncodedKeySpec(keyPair.getPrivateKeyInfo().getEncoded()))); } catch (Exception e) { throw new PEMException("unable to convert key pair: " + e.getMessage(), e); } } public PublicKey getPublicKey(SubjectPublicKeyInfo publicKeyInfo) throws PEMException { try { String algorithm = publicKeyInfo.getAlgorithm().getAlgorithm().getId(); if (X9ObjectIdentifiers.id_ecPublicKey.getId().equals(algorithm)) { algorithm = "ECDSA"; } KeyFactory keyFactory = helper.createKeyFactory(algorithm); return keyFactory.generatePublic(new X509EncodedKeySpec(publicKeyInfo.getEncoded())); } catch (Exception e) { throw new PEMException("unable to convert key pair: " + e.getMessage(), e); } } public PrivateKey getPrivateKey(PrivateKeyInfo privateKeyInfo) throws PEMException { try { String algorithm = privateKeyInfo.getPrivateKeyAlgorithm().getAlgorithm().getId(); if (X9ObjectIdentifiers.id_ecPublicKey.getId().equals(algorithm)) { algorithm = "ECDSA"; } KeyFactory keyFactory = helper.createKeyFactory(algorithm); return keyFactory.generatePrivate(new PKCS8EncodedKeySpec(privateKeyInfo.getEncoded())); } catch (Exception e) { throw new PEMException("unable to convert key pair: " + e.getMessage(), e); } } } bouncycastle-1.49.orig/src/org/bouncycastle/openssl/jcajce/JceOpenSSLPKCS8EncryptorBuilder.java0000644000175000017500000001627612110277315032155 0ustar ebourgebourgpackage org.bouncycastle.openssl.jcajce; import java.io.IOException; import java.io.OutputStream; import java.security.AlgorithmParameterGenerator; import java.security.AlgorithmParameters; import java.security.GeneralSecurityException; import java.security.Provider; import java.security.SecureRandom; import javax.crypto.Cipher; import javax.crypto.CipherOutputStream; import javax.crypto.SecretKey; import javax.crypto.SecretKeyFactory; import javax.crypto.spec.PBEKeySpec; import javax.crypto.spec.PBEParameterSpec; import org.bouncycastle.asn1.ASN1EncodableVector; import org.bouncycastle.asn1.ASN1Integer; import org.bouncycastle.asn1.ASN1ObjectIdentifier; import org.bouncycastle.asn1.ASN1Primitive; import org.bouncycastle.asn1.DEROctetString; import org.bouncycastle.asn1.DERSequence; import org.bouncycastle.asn1.nist.NISTObjectIdentifiers; import org.bouncycastle.asn1.pkcs.KeyDerivationFunc; import org.bouncycastle.asn1.pkcs.PBES2Parameters; import org.bouncycastle.asn1.pkcs.PBKDF2Params; import org.bouncycastle.asn1.pkcs.PKCS12PBEParams; import org.bouncycastle.asn1.pkcs.PKCSObjectIdentifiers; import org.bouncycastle.asn1.x509.AlgorithmIdentifier; import org.bouncycastle.jcajce.DefaultJcaJceHelper; import org.bouncycastle.jcajce.JcaJceHelper; import org.bouncycastle.jcajce.NamedJcaJceHelper; import org.bouncycastle.jcajce.ProviderJcaJceHelper; import org.bouncycastle.operator.GenericKey; import org.bouncycastle.operator.OperatorCreationException; import org.bouncycastle.operator.OutputEncryptor; import org.bouncycastle.operator.jcajce.JceGenericKey; public class JceOpenSSLPKCS8EncryptorBuilder { public static final String AES_128_CBC = NISTObjectIdentifiers.id_aes128_CBC.getId(); public static final String AES_192_CBC = NISTObjectIdentifiers.id_aes192_CBC.getId(); public static final String AES_256_CBC = NISTObjectIdentifiers.id_aes256_CBC.getId(); public static final String DES3_CBC = PKCSObjectIdentifiers.des_EDE3_CBC.getId(); public static final String PBE_SHA1_RC4_128 = PKCSObjectIdentifiers.pbeWithSHAAnd128BitRC4.getId(); public static final String PBE_SHA1_RC4_40 = PKCSObjectIdentifiers.pbeWithSHAAnd40BitRC4.getId(); public static final String PBE_SHA1_3DES = PKCSObjectIdentifiers.pbeWithSHAAnd3_KeyTripleDES_CBC.getId(); public static final String PBE_SHA1_2DES = PKCSObjectIdentifiers.pbeWithSHAAnd2_KeyTripleDES_CBC.getId(); public static final String PBE_SHA1_RC2_128 = PKCSObjectIdentifiers.pbeWithSHAAnd128BitRC2_CBC.getId(); public static final String PBE_SHA1_RC2_40 = PKCSObjectIdentifiers.pbeWithSHAAnd40BitRC2_CBC.getId(); private JcaJceHelper helper = new DefaultJcaJceHelper(); private AlgorithmParameters params; private ASN1ObjectIdentifier algOID; byte[] salt; int iterationCount; private Cipher cipher; private SecureRandom random; private AlgorithmParameterGenerator paramGen; private SecretKeyFactory secKeyFact; private char[] password; private SecretKey key; public JceOpenSSLPKCS8EncryptorBuilder(ASN1ObjectIdentifier algorithm) { algOID = algorithm; this.iterationCount = 2048; } public JceOpenSSLPKCS8EncryptorBuilder setRandom(SecureRandom random) { this.random = random; return this; } public JceOpenSSLPKCS8EncryptorBuilder setPasssword(char[] password) { this.password = password; return this; } public JceOpenSSLPKCS8EncryptorBuilder setIterationCount(int iterationCount) { this.iterationCount = iterationCount; return this; } public JceOpenSSLPKCS8EncryptorBuilder setProvider(String providerName) { helper = new NamedJcaJceHelper(providerName); return this; } public JceOpenSSLPKCS8EncryptorBuilder setProvider(Provider provider) { helper = new ProviderJcaJceHelper(provider); return this; } public OutputEncryptor build() throws OperatorCreationException { final AlgorithmIdentifier algID; salt = new byte[20]; if (random == null) { random = new SecureRandom(); } random.nextBytes(salt); try { this.cipher = helper.createCipher(algOID.getId()); if (PEMUtilities.isPKCS5Scheme2(algOID)) { this.paramGen = helper.createAlgorithmParameterGenerator(algOID.getId()); } else { this.secKeyFact = helper.createSecretKeyFactory(algOID.getId()); } } catch (GeneralSecurityException e) { throw new OperatorCreationException(algOID + " not available: " + e.getMessage(), e); } if (PEMUtilities.isPKCS5Scheme2(algOID)) { params = paramGen.generateParameters(); try { KeyDerivationFunc scheme = new KeyDerivationFunc(algOID, ASN1Primitive.fromByteArray(params.getEncoded())); KeyDerivationFunc func = new KeyDerivationFunc(PKCSObjectIdentifiers.id_PBKDF2, new PBKDF2Params(salt, iterationCount)); ASN1EncodableVector v = new ASN1EncodableVector(); v.add(func); v.add(scheme); algID = new AlgorithmIdentifier(PKCSObjectIdentifiers.id_PBES2, PBES2Parameters.getInstance(new DERSequence(v))); } catch (IOException e) { throw new OperatorCreationException(e.getMessage(), e); } key = PEMUtilities.generateSecretKeyForPKCS5Scheme2(algOID.getId(), password, salt, iterationCount); try { cipher.init(Cipher.ENCRYPT_MODE, key, params); } catch (GeneralSecurityException e) { throw new OperatorCreationException(e.getMessage(), e); } } else if (PEMUtilities.isPKCS12(algOID)) { ASN1EncodableVector v = new ASN1EncodableVector(); v.add(new DEROctetString(salt)); v.add(new ASN1Integer(iterationCount)); algID = new AlgorithmIdentifier(algOID, PKCS12PBEParams.getInstance(new DERSequence(v))); try { PBEKeySpec pbeSpec = new PBEKeySpec(password); PBEParameterSpec defParams = new PBEParameterSpec(salt, iterationCount); key = secKeyFact.generateSecret(pbeSpec); cipher.init(Cipher.ENCRYPT_MODE, key, defParams); } catch (GeneralSecurityException e) { throw new OperatorCreationException(e.getMessage(), e); } } else { throw new OperatorCreationException("unknown algorithm: " + algOID, null); } return new OutputEncryptor() { public AlgorithmIdentifier getAlgorithmIdentifier() { return algID; } public OutputStream getOutputStream(OutputStream encOut) { return new CipherOutputStream(encOut, cipher); } public GenericKey getKey() { return new JceGenericKey(algID, key); } }; } } bouncycastle-1.49.orig/src/org/bouncycastle/openssl/PKCS8Generator.java0000644000175000017500000001460512104123362025527 0ustar ebourgebourgpackage org.bouncycastle.openssl; import java.io.ByteArrayOutputStream; import java.io.IOException; import java.io.OutputStream; import java.security.NoSuchAlgorithmException; import java.security.NoSuchProviderException; import java.security.PrivateKey; import java.security.Provider; import java.security.SecureRandom; import java.security.Security; import org.bouncycastle.asn1.ASN1ObjectIdentifier; import org.bouncycastle.asn1.nist.NISTObjectIdentifiers; import org.bouncycastle.asn1.pkcs.EncryptedPrivateKeyInfo; import org.bouncycastle.asn1.pkcs.PKCSObjectIdentifiers; import org.bouncycastle.asn1.pkcs.PrivateKeyInfo; import org.bouncycastle.openssl.jcajce.JceOpenSSLPKCS8EncryptorBuilder; import org.bouncycastle.operator.OperatorCreationException; import org.bouncycastle.operator.OutputEncryptor; import org.bouncycastle.util.io.pem.PemGenerationException; import org.bouncycastle.util.io.pem.PemObject; import org.bouncycastle.util.io.pem.PemObjectGenerator; public class PKCS8Generator implements PemObjectGenerator { public static final ASN1ObjectIdentifier AES_128_CBC = NISTObjectIdentifiers.id_aes128_CBC; public static final ASN1ObjectIdentifier AES_192_CBC = NISTObjectIdentifiers.id_aes192_CBC; public static final ASN1ObjectIdentifier AES_256_CBC = NISTObjectIdentifiers.id_aes256_CBC; public static final ASN1ObjectIdentifier DES3_CBC = PKCSObjectIdentifiers.des_EDE3_CBC; public static final ASN1ObjectIdentifier PBE_SHA1_RC4_128 = PKCSObjectIdentifiers.pbeWithSHAAnd128BitRC4; public static final ASN1ObjectIdentifier PBE_SHA1_RC4_40 = PKCSObjectIdentifiers.pbeWithSHAAnd40BitRC4; public static final ASN1ObjectIdentifier PBE_SHA1_3DES = PKCSObjectIdentifiers.pbeWithSHAAnd3_KeyTripleDES_CBC; public static final ASN1ObjectIdentifier PBE_SHA1_2DES = PKCSObjectIdentifiers.pbeWithSHAAnd2_KeyTripleDES_CBC; public static final ASN1ObjectIdentifier PBE_SHA1_RC2_128 = PKCSObjectIdentifiers.pbeWithSHAAnd128BitRC2_CBC; public static final ASN1ObjectIdentifier PBE_SHA1_RC2_40 = PKCSObjectIdentifiers.pbeWithSHAAnd40BitRC2_CBC; private PrivateKeyInfo key; private OutputEncryptor outputEncryptor; private JceOpenSSLPKCS8EncryptorBuilder encryptorBuilder; /** * Constructor for an unencrypted private key PEM object. * * @param key private key to be encoded. * @deprecated use JcaPKCS8Generator */ public PKCS8Generator(PrivateKey key) { this.key = PrivateKeyInfo.getInstance(key.getEncoded()); } /** * Constructor for an encrypted private key PEM object. * * @param key private key to be encoded * @param algorithm encryption algorithm to use * @param provider name of provider to use * @throws NoSuchProviderException if provider cannot be found * @throws NoSuchAlgorithmException if algorithm/mode cannot be found * @deprecated use JcaPKCS8Generator */ public PKCS8Generator(PrivateKey key, ASN1ObjectIdentifier algorithm, String provider) throws NoSuchProviderException, NoSuchAlgorithmException { Provider prov = Security.getProvider(provider); if (prov == null) { throw new NoSuchProviderException("cannot find provider: " + provider); } init(key, algorithm, prov); } /** * Constructor for an encrypted private key PEM object. * * @param key private key to be encoded * @param algorithm encryption algorithm to use * @param provider provider to use * @throws NoSuchAlgorithmException if algorithm/mode cannot be found * @deprecated use JcaPKCS8Generator */ public PKCS8Generator(PrivateKey key, ASN1ObjectIdentifier algorithm, Provider provider) throws NoSuchAlgorithmException { init(key, algorithm, provider); } /** * Base constructor. */ public PKCS8Generator(PrivateKeyInfo key, OutputEncryptor outputEncryptor) { this.key = key; this.outputEncryptor = outputEncryptor; } private void init(PrivateKey key, ASN1ObjectIdentifier algorithm, Provider provider) throws NoSuchAlgorithmException { this.key = PrivateKeyInfo.getInstance(key.getEncoded()); this.encryptorBuilder = new JceOpenSSLPKCS8EncryptorBuilder(algorithm); encryptorBuilder.setProvider(provider); } /** * @deprecated ignored in the updated case. */ public PKCS8Generator setSecureRandom(SecureRandom random) { encryptorBuilder.setRandom(random); return this; } /** * @deprecated ignored in the updated case. */ public PKCS8Generator setPassword(char[] password) { encryptorBuilder.setPasssword(password); return this; } /** * @deprecated ignored in the updated case. */ public PKCS8Generator setIterationCount(int iterationCount) { encryptorBuilder.setIterationCount(iterationCount); return this; } public PemObject generate() throws PemGenerationException { try { if (encryptorBuilder != null) { outputEncryptor = encryptorBuilder.build(); } } catch (OperatorCreationException e) { throw new PemGenerationException("unable to create operator: " + e.getMessage(), e); } if (outputEncryptor != null) { return generate(key, outputEncryptor); } else { return generate(key, null); } } private PemObject generate(PrivateKeyInfo key, OutputEncryptor encryptor) throws PemGenerationException { try { byte[] keyData = key.getEncoded(); if (encryptor == null) { return new PemObject("PRIVATE KEY", keyData); } ByteArrayOutputStream bOut = new ByteArrayOutputStream(); OutputStream cOut = encryptor.getOutputStream(bOut); cOut.write(key.getEncoded()); cOut.close(); EncryptedPrivateKeyInfo info = new EncryptedPrivateKeyInfo(encryptor.getAlgorithmIdentifier(), bOut.toByteArray()); return new PemObject("ENCRYPTED PRIVATE KEY", info.getEncoded()); } catch (IOException e) { throw new PemGenerationException("unable to process encoded key data: " + e.getMessage(), e); } } } bouncycastle-1.49.orig/src/org/bouncycastle/openssl/PEMEncryptedKeyPair.java0000644000175000017500000000227012104051043026603 0ustar ebourgebourgpackage org.bouncycastle.openssl; import java.io.IOException; import org.bouncycastle.operator.OperatorCreationException; public class PEMEncryptedKeyPair { private final String dekAlgName; private final byte[] iv; private final byte[] keyBytes; private final PEMKeyPairParser parser; PEMEncryptedKeyPair(String dekAlgName, byte[] iv, byte[] keyBytes, PEMKeyPairParser parser) { this.dekAlgName = dekAlgName; this.iv = iv; this.keyBytes = keyBytes; this.parser = parser; } public PEMKeyPair decryptKeyPair(PEMDecryptorProvider keyDecryptorProvider) throws IOException { try { PEMDecryptor keyDecryptor = keyDecryptorProvider.get(dekAlgName); return parser.parse(keyDecryptor.decrypt(keyBytes, iv)); } catch (IOException e) { throw e; } catch (OperatorCreationException e) { throw new PEMException("cannot create extraction operator: " + e.getMessage(), e); } catch (Exception e) { throw new PEMException("exception processing key pair: " + e.getMessage(), e); } } } bouncycastle-1.49.orig/src/org/bouncycastle/openssl/package.html0000644000175000017500000000013410262753174024453 0ustar ebourgebourg Classes for dealing with OpenSSL PEM files. bouncycastle-1.49.orig/src/org/bouncycastle/voms/0000755000175000017500000000000012152033551021463 5ustar ebourgebourgbouncycastle-1.49.orig/src/org/bouncycastle/voms/VOMSAttribute.java0000644000175000017500000001443411731467175025023 0ustar ebourgebourgpackage org.bouncycastle.voms; import java.util.List; import java.util.ArrayList; import org.bouncycastle.asn1.ASN1OctetString; import org.bouncycastle.asn1.DERIA5String; import org.bouncycastle.asn1.x509.IetfAttrSyntax; import org.bouncycastle.x509.X509Attribute; import org.bouncycastle.x509.X509AttributeCertificate; /** * Representation of the authorization information (VO, server address * and list of Fully Qualified Attribute Names, or FQANs) contained in * a VOMS attribute certificate. */ public class VOMSAttribute { /** * The ASN.1 object identifier for VOMS attributes */ public static final String VOMS_ATTR_OID = "1.3.6.1.4.1.8005.100.100.4"; private X509AttributeCertificate myAC; private String myHostPort; private String myVo; private List myStringList = new ArrayList(); private List myFQANs = new ArrayList(); /** * Parses the contents of an attribute certificate.
    * NOTE: Cryptographic signatures, time stamps etc. will not be checked. * * @param ac the attribute certificate to parse for VOMS attributes */ public VOMSAttribute(X509AttributeCertificate ac) { if (ac == null) { throw new IllegalArgumentException("VOMSAttribute: AttributeCertificate is NULL"); } myAC = ac; X509Attribute[] l = ac.getAttributes(VOMS_ATTR_OID); if (l == null) { return; } try { for (int i = 0; i != l.length; i++) { IetfAttrSyntax attr = IetfAttrSyntax.getInstance(l[i].getValues()[0]); // policyAuthority is on the format /: String url = ((DERIA5String)attr.getPolicyAuthority().getNames()[0].getName()).getString(); int idx = url.indexOf("://"); if ((idx < 0) || (idx == (url.length() - 1))) { throw new IllegalArgumentException("Bad encoding of VOMS policyAuthority : [" + url + "]"); } myVo = url.substring(0, idx); myHostPort = url.substring(idx + 3); if (attr.getValueType() != IetfAttrSyntax.VALUE_OCTETS) { throw new IllegalArgumentException( "VOMS attribute values are not encoded as octet strings, policyAuthority = " + url); } ASN1OctetString[] values = (ASN1OctetString[])attr.getValues(); for (int j = 0; j != values.length; j++) { String fqan = new String(values[j].getOctets()); FQAN f = new FQAN(fqan); if (!myStringList.contains(fqan) && fqan.startsWith("/" + myVo + "/")) { myStringList.add(fqan); myFQANs.add(f); } } } } catch (IllegalArgumentException ie) { throw ie; } catch (Exception e) { throw new IllegalArgumentException("Badly encoded VOMS extension in AC issued by " + ac.getIssuer()); } } /** * @return The AttributeCertificate containing the VOMS information */ public X509AttributeCertificate getAC() { return myAC; } /** * @return List of String of the VOMS fully qualified * attributes names (FQANs):
    * /vo[/group[/group2...]][/Role=[role]][/Capability=capability] */ public List getFullyQualifiedAttributes() { return myStringList; } /** * @return List of FQAN of the VOMS fully qualified * attributes names (FQANs) */ public List getListOfFQAN() { return myFQANs; } /** * Returns the address of the issuing VOMS server, on the form <host>:<port> * @return String */ public String getHostPort() { return myHostPort; } /** * Returns the VO name * @return */ public String getVO() { return myVo; } public String toString() { return "VO :" + myVo + "\n" + "HostPort:" + myHostPort + "\n" + "FQANs :" + myFQANs; } /** * Inner class providing a container of the group,role,capability * information triplet in an FQAN. */ public class FQAN { String fqan; String group; String role; String capability; public FQAN(String fqan) { this.fqan = fqan; } public FQAN(String group, String role, String capability) { this.group = group; this.role = role; this.capability = capability; } public String getFQAN() { if (fqan != null) { return fqan; } fqan = group + "/Role=" + ((role != null) ? role : "") + ((capability != null) ? ("/Capability=" + capability) : ""); return fqan; } protected void split() { int len = fqan.length(); int i = fqan.indexOf("/Role="); if (i < 0) { return; } group = fqan.substring(0, i); int j = fqan.indexOf("/Capability=", i + 6); String s = (j < 0) ? fqan.substring(i + 6) : fqan.substring(i + 6, j); role = (s.length() == 0) ? null : s; s = (j < 0) ? null : fqan.substring(j + 12); capability = ((s == null) || (s.length() == 0)) ? null : s; } public String getGroup() { if ((group == null) && (fqan != null)) { split(); } return group; } public String getRole() { if ((group == null) && (fqan != null)) { split(); } return role; } public String getCapability() { if ((group == null) && (fqan != null)) { split(); } return capability; } public String toString() { return getFQAN(); } } } bouncycastle-1.49.orig/build1-20000644000175000017500000005527712152015376015715 0ustar ebourgebourg#!/bin/sh - # # build script for 1.2 # # If it's given a buildname it creates a subdirectory and places a build in it, # otherwise it just creates the docs and class files. # JDK12PATH=/opt/jdk1.2.2 # JDK 1.2 location base=$1 version=`echo $base | sed -e "s/\([0-9]\)\([0-9a-z]*\)/\1.\2/"` WINDOWTITLE="Bouncy Castle Cryptography $version API Specification" HEADER="Bouncy Castle Cryptography $version" DOCTITLE="Bouncy Castle $version API Specification" if test "$base" != "" -a ! -d lcrypto-jdk12-$base then echo "making lightweight release" mkdir lcrypto-jdk12-$base tar cf - index.html LICENSE.html CONTRIBUTORS.html releasenotes.html specifications.html src/org/bouncycastle/LICENSE.java \ src/org/bouncycastle/math src/org/bouncycastle/crypto src/org/bouncycastle/util src/org/bouncycastle/asn1 src/org/bouncycastle/pqc/math src/org/bouncycastle/pqc/crypto src/org/bouncycastle/pqc/asn1 \ | (cd lcrypto-jdk12-$base && tar xf -) (cd jdk1.4 && tar cf - org/bouncycastle/util) \ | (cd lcrypto-jdk12-$base/src && tar xf -) (cd jdk1.3 && tar cf - org/bouncycastle/asn1) \ | (cd lcrypto-jdk12-$base/src && tar xf -) (cd jdk1.3 && tar cf - org/bouncycastle/crypto) \ | (cd lcrypto-jdk12-$base/src && tar xf -) (cd test && tar cf - src/org/bouncycastle/crypto src/org/bouncycastle/util src/org/bouncycastle/asn1) \ | (cd lcrypto-jdk12-$base && tar xf -) ( cd lcrypto-jdk12-$base; mkdir classes; mkdir docs; rm -rf src/org/bouncycastle/jce rm -rf src/org/bouncycastle/ocsp rm -rf src/org/bouncycastle/openpgp rm -rf src/org/bouncycastle/math/ntru rm -rf src/org/bouncycastle/crypto/test/ntru rm -rf src/org/bouncycastle/crypto/*/NTRU* rm -rf src/org/bouncycastle/crypto/*/test rm -rf src/org/bouncycastle/crypto/*/IndexGenerator* rm -rf src/org/bouncycastle/util/utiltest find src -name AllTests.java -exec rm {} \; rm src/org/bouncycastle/asn1/test/GetInstanceTest.java rm src/org/bouncycastle/asn1/test/ASN1SequenceParserTest.java rm src/org/bouncycastle/asn1/test/OctetStringTest.java rm src/org/bouncycastle/asn1/test/ParseTest.java rm src/org/bouncycastle/crypto/test/GCMReorderTest.java (2>&1 javadoc -windowtitle "$WINDOWTITLE" -doctitle "$DOCTITLE" \ -header "$HEADER" \ -group "Lightweight Crypto Packages" "org.bouncycastle.crypto*" \ -group "ASN.1 Support Packages" "org.bouncycastle.asn1*" \ -group "Math Support Packages" "org.bouncycastle.math*" \ -group "Utility Packages" "org.bouncycastle.util*" \ -classpath classes \ -d docs -sourcepath src \ org.bouncycastle.asn1 \ org.bouncycastle.asn1.cmp \ org.bouncycastle.asn1.cms \ org.bouncycastle.asn1.cryptopro \ org.bouncycastle.asn1.esf \ org.bouncycastle.asn1.ess \ org.bouncycastle.asn1.gnu \ org.bouncycastle.asn1.iana \ org.bouncycastle.asn1.icao \ org.bouncycastle.asn1.misc \ org.bouncycastle.asn1.mozilla \ org.bouncycastle.asn1.nist \ org.bouncycastle.asn1.ocsp \ org.bouncycastle.asn1.oiw \ org.bouncycastle.asn1.pkcs \ org.bouncycastle.asn1.sec \ org.bouncycastle.asn1.smime \ org.bouncycastle.asn1.teletrust \ org.bouncycastle.asn1.test \ org.bouncycastle.asn1.tsp \ org.bouncycastle.asn1.util \ org.bouncycastle.asn1.x509 \ org.bouncycastle.asn1.x9 \ org.bouncycastle.math.ec \ org.bouncycastle.crypto \ org.bouncycastle.crypto.agreement \ org.bouncycastle.crypto.commitments \ org.bouncycastle.crypto.digests \ org.bouncycastle.crypto.encodings \ org.bouncycastle.crypto.ec \ org.bouncycastle.crypto.engines \ org.bouncycastle.crypto.generators \ org.bouncycastle.crypto.io \ org.bouncycastle.crypto.kems \ org.bouncycastle.crypto.macs \ org.bouncycastle.crypto.modes \ org.bouncycastle.crypto.paddings \ org.bouncycastle.crypto.params \ org.bouncycastle.crypto.signers \ org.bouncycastle.crypto.test \ org.bouncycastle.crypto.examples \ org.bouncycastle.crypto.tls \ org.bouncycastle.util.encoders \ org.bouncycastle.util.test) > /dev/null \ PATH=$JDK12PATH/bin:$PATH export PATH echo "compiling" (cd src/org/bouncycastle; javac -d ../../../classes -classpath ../../../classes:../../../src *.java */*.java */*/*.java ) echo "lightweight regression test" java -classpath classes -Dbc.test.data.home=/home/dgh/bc/java/crypto/test/data org.bouncycastle.crypto.test.RegressionTest ) (2>&1 find lcrypto-jdk12-$base -name CVS -exec rm -rf \{\} \; ) > /dev/null fi if test "$base" != "" -a ! -d jce-jdk12-$base then echo "making JCE release" mkdir jce-jdk12-$base tar cf - index.html LICENSE.html CONTRIBUTORS.html releasenotes.html specifications.html src | (cd jce-jdk12-$base; tar xf -) (cd jce && tar cf - src | (cd ../jce-jdk12-$base; tar xf -)) (cd test && tar cf - src | (cd ../jce-jdk12-$base; tar xf -)) (cd jdk1.4 && tar cf - * | (cd ../jce-jdk12-$base/src; tar xf -)) (cd test/jdk1.4 && tar cf - * | (cd ../../jce-jdk12-$base/src; tar xf -)) (cd jdk1.3 && tar cf - * | (cd ../jce-jdk12-$base/src; tar xf -)) (cd test/jdk1.3 && tar cf - * | (cd ../../jce-jdk12-$base/src; tar xf -)) (cd jdk1.2 && tar cf - * | (cd ../jce-jdk12-$base/src; tar xf -)) (cd test/data && tar cf - org/bouncycastle/asn1 | (cd ../../jce-jdk12-$base/src; tar xf -)) ( cd jce-jdk12-$base; mkdir classes; mkdir docs; rm -rf src/org/bouncycastle/crypto/test/ntru rm -rf src/org/bouncycastle/pqc/math/ntru rm -rf src/org/bouncycastle/pqc/crypto/ntru rm -rf src/org/bouncycastle/pqc/crypto/*/NTRU* rm -rf src/org/bouncycastle/pqc/crypto/*/EncryptionKey* rm -rf src/org/bouncycastle/pqc/crypto/*/BitStringT* rm -rf src/org/bouncycastle/crypto/*/test rm -rf src/org/bouncycastle/crypto/*/IndexGenerator* rm -rf src/org/bouncycastle/util/utiltest rm -rf src/org/bouncycastle/mail rm -rf src/org/bouncycastle/bcpg rm -rf src/org/bouncycastle/openpgp rm -rf src/org/bouncycastle/openssl rm -rf src/org/bouncycastle/voms rm -rf src/org/bouncycastle/mozilla rm -rf src/org/bouncycastle/tsp rm -rf src/org/bouncycastle/sasn1/test rm -rf src/org/bouncycastle/i18n/test rm -rf src/org/bouncycastle/i18n/filter/test rm -rf src/org/bouncycastle/math/ec/test rm -rf src/org/bouncycastle/crypto/tls/test rm -rf src/org/bouncycastle/crypto/test/GCMReorderTest.java rm -rf src/org/bouncycastle/jce/ECPointUtil.java rm -rf src/org/bouncycastle/jce/X509LDAP*.java rm -rf src/org/bouncycastle/jce/provider/X509LDAP*.java rm -rf src/org/bouncycastle/jce/provider/JCEEC5*.java rm -rf src/org/bouncycastle/jce/provider/EC5*.java rm -rf src/org/bouncycastle/jce/provider/JCEEC*.java rm -rf src/org/bouncycastle/jcajce/provider/asymmetric/ec/EC5Util.java rm -rf src/org/bouncycastle/jce/provider/asymmetric/ec/EC5*.java #rm -rf src/org/bouncycastle/jce/provider/CertPathValidatorUtilities.java rm -rf src/org/bouncycastle/jce/provider/test/ECDSA5Test.java rm -rf src/org/bouncycastle/jce/provider/test/CRL5Test.java rm -rf src/org/bouncycastle/jce/provider/test/X509LDAP*.java rm -rf src/org/bouncycastle/jce/provider/test/MQVTest*.java rm -rf src/org/bouncycastle/jce/spec/ECNamedCurveSpec.java rm -rf src/org/bouncycastle/util/encoders/test/*.java rm -rf src/org/bouncycastle/x509/PKIXCertPathReviewer.java rm -rf src/org/bouncycastle/x509/CertPathReviewerException.java rm -rf src/org/bouncycastle/x509/util/LDAPStoreHelper.java rm -rf src/org/bouncycastle/jce/provider/X509StoreLDAPAttrCerts.java rm -rf src/org/bouncycastle/jce/provider/X509StoreLDAPCertPairs.java rm -rf src/org/bouncycastle/jce/provider/X509StoreLDAPCerts.java rm -rf src/org/bouncycastle/jce/provider/X509StoreLDAPCRLs.java rm -rf src/org/bouncycastle/jce/provider/PKIXAttrCert*.java rm -rf src/org/bouncycastle/jce/provider/PKIXNameConstraints*.java rm -rf src/org/bouncycastle/jce/provider/test/PKIXNameConstraintsTest.java rm -rf src/org/bouncycastle/jce/provider/test/nist rm -rf src/org/bouncycastle/jce/provider/test/rsa3 rm -rf src/org/bouncycastle/jce/provider/test/DSTU4145Test.java rm -rf src/org/bouncycastle/jce/provider/test/JceTestUtil.java rm -rf src/org/bouncycastle/x509/PKIXAttrCert*.java rm -rf src/org/bouncycastle/jce/provider/RFC3281*.java rm -rf src/org/bouncycastle/jce/provider/JDKPKCS12StoreParameter.java rm -rf src/org/bouncycastle/jcajce/provider/config/PKCS12StoreParameter.java rm -rf src/org/bouncycastle/jcajce/provider/test/PrivateConstructorTest.java find src -name AllTests.java -exec rm {} \; rm src/org/bouncycastle/asn1/test/GetInstanceTest.java rm src/org/bouncycastle/asn1/test/ASN1SequenceParserTest.java rm src/org/bouncycastle/asn1/test/OctetStringTest.java rm src/org/bouncycastle/asn1/test/ParseTest.java rm -rf src/org/bouncycastle/openssl/test rm -rf src/org/bouncycastle/cms rm -rf src/org/bouncycastle/cert rm -rf src/org/bouncycastle/pkcs rm -rf src/org/bouncycastle/operator rm -rf src/org/bouncycastle/eac rm -rf src/org/bouncycastle/tsp rm -rf src/org/bouncycastle/mozilla rm -rf src/org/bouncycastle/jcajce/provider/asymmetric/dstu rm -rf src/org/bouncycastle/jcajce/provider/asymmetric/DSTU*.java rm -rf src/org/bouncycastle/jcajce/provider/asymmetric/util/EC5*.java rm -rf src/org/bouncycastle/pqc/jcajce/provider/test (2>&1 javadoc -windowtitle "$WINDOWTITLE" -doctitle "$DOCTITLE" \ -header "$HEADER" \ -group "Cleanroom JCE" "javax.crypto*" \ -group "JCE Utility and Extension Packages" "org.bouncycastle.jce*" \ -group "OCSP and OpenSSL PEM Support Packages" "org.bouncycastle.ocsp*:org.bouncycastle.openssl*" \ -group "ASN.1 Support Packages" "org.bouncycastle.asn1*" \ -group "Lightweight Crypto Packages" "org.bouncycastle.crypto*" \ -group "Utility Packages" "org.bouncycastle.util*:org.bouncycastle.math*" \ -group "JCE Provider and Test Classes" "org.bouncycastle.jce.provider*" \ -classpath classes \ -d docs -sourcepath src \ java.security.spec \ javax.crypto \ javax.crypto.interfaces \ javax.crypto.spec \ org.bouncycastle.asn1 \ org.bouncycastle.asn1.cmp \ org.bouncycastle.asn1.cms \ org.bouncycastle.asn1.cryptopro \ org.bouncycastle.asn1.esf \ org.bouncycastle.asn1.ess \ org.bouncycastle.asn1.gnu \ org.bouncycastle.asn1.iana \ org.bouncycastle.asn1.icao \ org.bouncycastle.asn1.misc \ org.bouncycastle.asn1.mozilla \ org.bouncycastle.asn1.nist \ org.bouncycastle.asn1.ocsp \ org.bouncycastle.asn1.oiw \ org.bouncycastle.asn1.pkcs \ org.bouncycastle.asn1.sec \ org.bouncycastle.asn1.smime \ org.bouncycastle.asn1.teletrust \ org.bouncycastle.asn1.test \ org.bouncycastle.asn1.tsp \ org.bouncycastle.asn1.util \ org.bouncycastle.asn1.x509 \ org.bouncycastle.asn1.x9 \ org.bouncycastle.math.ec \ org.bouncycastle.crypto \ org.bouncycastle.crypto.agreement \ org.bouncycastle.crypto.commitments \ org.bouncycastle.crypto.digests \ org.bouncycastle.crypto.encodings \ org.bouncycastle.crypto.ec \ org.bouncycastle.crypto.engines \ org.bouncycastle.crypto.generators \ org.bouncycastle.crypto.io \ org.bouncycastle.crypto.kems \ org.bouncycastle.crypto.macs \ org.bouncycastle.crypto.modes \ org.bouncycastle.crypto.paddings \ org.bouncycastle.crypto.params \ org.bouncycastle.crypto.signers \ org.bouncycastle.crypto.test \ org.bouncycastle.crypto.tls \ org.bouncycastle.crypto.examples \ org.bouncycastle.jce \ org.bouncycastle.jce.cert \ org.bouncycastle.jce.interfaces \ org.bouncycastle.jce.spec \ org.bouncycastle.jce.examples \ org.bouncycastle.jce.provider \ org.bouncycastle.jcajce.provider.asymmetric \ org.bouncycastle.jcajce.provider.asymmetric.ec \ org.bouncycastle.jcajce.provider.symmetric \ org.bouncycastle.jce.provider.test \ org.bouncycastle.ocsp \ org.bouncycastle.ocsp.test \ org.bouncycastle.x509 \ org.bouncycastle.x509.examples \ org.bouncycastle.x509.extension \ org.bouncycastle.util.encoders \ org.bouncycastle.util.test) > /dev/null \ PATH=$JDK12PATH/bin:$PATH export PATH echo "compiling" (cd src/java/security/spec; javac -d ../../../../classes -classpath ../../../../classes *.java ) (cd src/org/bouncycastle/jcajce/provider; javac -d ../../../../../classes -classpath ../../../../../classes:../../../../../src [abcis]*/*.java [abcis]*/*/*.java ) (cd src/org/bouncycastle; javac -d ../../../classes -classpath ../../../classes:../../../src *.java [abci]*/*.java [abci]*/*/*.java [abci]*/*/*/*.java ) (cd src/org/bouncycastle; javac -d ../../../classes -classpath ../../../classes:../../../src [jmoptuvx]*/*.java [jmoptuvx]*/*/*.java [jmoptuvx]*/*/*/*.java [jmoptuvx]*/*/*/*/*.java) (cd src/javax/crypto; javac -d ../../../classes -classpath ../../../classes:../../../src *.java */*.java) echo "provider regression test" java -classpath classes org.bouncycastle.jce.provider.test.RegressionTest java -classpath classes org.bouncycastle.asn1.test.RegressionTest (cd classes; jar cf ../../bctest-jdk12-$base.jar org/bouncycastle/asn1/test org/bouncycastle/crypto/test org/bouncycastle/jce/provider/test) rm -rf classes/org/bouncycastle/asn1/test rm -rf classes/org/bouncycastle/crypto/test rm -rf classes/org/bouncycastle/jce/provider/test (cd classes; jar cf ../../bcprov-ext-jdk12-$base.jar java org) (cd classes; jar cf ../../jce-ext-jdk12-$base.jar java javax org) rm -rf classes/org/bouncycastle/jce/provider/symmetric/IDEA.class rm -rf classes/org/bouncycastle/jce/provider/symmetric/IDEAMappings.class rm -rf classes/org/bouncycastle/crypto/engines/IDEAEngine.class (cd classes; jar cf ../../bcprov-jdk12-$base.jar java org) (cd classes; jar cf ../../jce-jdk12-$base.jar java javax org) ) ( 2>&1 find jce-jdk12-$base -name CVS -exec rm -rf \{\} \;) > /dev/null fi if test "$base" != "" -a ! -d bcpkix-jdk12-$base then echo "making PKIX release" mkdir bcpkix-jdk12-$base tar cf - index.html LICENSE.html CONTRIBUTORS.html releasenotes.html specifications.html src/org/bouncycastle/cert src/org/bouncycastle/mozilla src/org/bouncycastle/voms src/org/bouncycastle/openssl src/org/bouncycastle/pkcs src/org/bouncycastle/cms src/org/bouncycastle/eac src/org/bouncycastle/tsp src/org/bouncycastle/operator | (cd bcpkix-jdk12-$base; tar xf -) (cd test/src; tar cf - org/bouncycastle/cert org/bouncycastle/tsp | (cd ../../bcpkix-jdk12-$base/src; tar xf -)) (cd test/jdk1.3; tar cf - org/bouncycastle/cert org/bouncycastle/tsp | (cd ../../bcpkix-jdk12-$base/src; tar xf -)) (cd jdk1.4; tar cf - * | (cd ../bcpkix-jdk12-$base/src; tar xf -)) (cd jdk1.3; tar cf - * | (cd ../bcpkix-jdk12-$base/src; tar xf -)) (cd jdk1.2; tar cf - * | (cd ../bcpkix-jdk12-$base/src; tar xf -)) ( cd bcpkix-jdk12-$base; mkdir classes; mkdir docs; PATH=$JDK12PATH/bin:$PATH export PATH rm -rf src/java rm -rf src/org/bouncycastle/jce rm -rf src/org/bouncycastle/ocsp rm -rf src/org/bouncycastle/bcpg rm -rf src/org/bouncycastle/x509 rm -rf src/org/bouncycastle/mail rm -rf src/org/bouncycastle/openpgp rm -rf src/org/bouncycastle/asn1 rm -rf src/org/bouncycastle/i18n rm -rf src/org/bouncycastle/jcajce rm -rf src/org/bouncycastle/cert/test/ConverterTest* rm -rf src/org/bouncycastle/cert/test/Bc* rm -rf src/org/bouncycastle/tsp/test rm -rf src/org/bouncycastle/tsp/GenTimeAccuracyUnit* rm -rf src/org/bouncycastle/tsp/TimeStampTokenInfoUnit* find src -name AllTests.java -exec rm {} \; javadoc -windowtitle "$WINDOWTITLE" -doctitle "$DOCTITLE" \ -header "$HEADER" \ -group "Basic Signing And Encryption" "org.bouncycastle.operator*" \ -group "Certificate Generation And Handling Support Packages" "org.bouncycastle.cert*" \ -group "CMS Support Packages" "org.bouncycastle.cms*" \ -group "EAC Support Packages" "org.bouncycastle.eac*" \ -group "TSP Support Packages" "org.bouncycastle.tsp*" \ -group "PKCS Support Packages" "org.bouncycastle.pkcs*" \ -group "OpenSSL PEM Support Packages" "org.bouncycastle.openssl*" \ -classpath classes:../jce-ext-jdk12-146.jar \ -d docs -sourcepath src \ org.bouncycastle.openssl \ org.bouncycastle.voms \ org.bouncycastle.mozilla \ org.bouncycastle.pkcs \ org.bouncycastle.pkcs.bc \ org.bouncycastle.pkcs.jcajce \ org.bouncycastle.cert \ org.bouncycastle.cert.cmp \ org.bouncycastle.cert.crmf \ org.bouncycastle.cert.jcajce \ org.bouncycastle.cert.ocsp \ org.bouncycastle.cert.selector \ org.bouncycastle.cms \ org.bouncycastle.cms.bc \ org.bouncycastle.cms.jcajce \ org.bouncycastle.cert.test > /dev/null \ echo "compiling" (cd src/org/bouncycastle; javac -d ../../../classes -classpath ../../../classes:../../../src:../../../../jce-jdk12-$base/classes */*.java */*/*.java */*/*/*.java) cat > classes/pg.mf <<% Manifest-Version: 1.0 Extension-Name: org.bouncycastle.bcpkix Specification-Vendor: BouncyCastle.org Specification-Version: 1.1 Implementation-Vendor-Id: org.bouncycastle Implementation-Vendor: BouncyCastle.org Implementation-Version: $version.0 % (cd classes; jar cmf pg.mf ../../bcpkix-jdk12-$base.jar org) java -classpath ../jce-ext-jdk12-$base.jar:classes org.bouncycastle.cert.test.CertTest java -classpath ../jce-ext-jdk12-$base.jar:classes org.bouncycastle.cert.test.AttrCertTest java -classpath ../jce-ext-jdk12-$base.jar:classes org.bouncycastle.cert.test.PKCS10Test java -classpath ../jce-ext-jdk12-$base.jar:classes org.bouncycastle.cert.test.X509ExtensionUtilsTest ) (2>&1 find bcpkix-jdk12-$base -name CVS -exec rm -rf \{\} \;) > /dev/null fi if test "$base" != "" -a ! -d bcpg-jdk12-$base then echo "making OpenPGP release" mkdir bcpg-jdk12-$base tar cf - index.html LICENSE.html CONTRIBUTORS.html releasenotes.html specifications.html src/org/bouncycastle/bcpg src/org/bouncycastle/openpgp | (cd bcpg-jdk12-$base; tar xf -) (cd test/src; tar cf - org/bouncycastle/openpgp | (cd ../../bcpg-jdk12-$base/src; tar xf -)) (cd bzip2 && tar cf - src | (cd ../bcpg-jdk12-$base; tar xf -)) (cd jdk1.3; tar cf - * | (cd ../bcpg-jdk12-$base/src; tar xf -)) (cd jdk1.2; tar cf - * | (cd ../bcpg-jdk12-$base/src; tar xf -)) ( cd bcpg-jdk12-$base; mkdir classes; mkdir docs; PATH=$JDK12PATH/bin:$PATH export PATH rm -rf src/java rm -rf src/org/bouncycastle/jce rm -rf src/org/bouncycastle/ocsp rm -rf src/org/bouncycastle/mail rm -rf src/org/bouncycastle/pkcs rm -rf src/org/bouncycastle/cms rm -rf src/org/bouncycastle/eac rm -rf src/org/bouncycastle/cert rm -rf src/org/bouncycastle/tsp rm -rf src/org/bouncycastle/x509 rm -rf src/org/bouncycastle/openssl rm -rf src/org/bouncycastle/operator rm -rf src/org/bouncycastle/voms rm -rf src/org/bouncycastle/sasn1 rm -rf src/org/bouncycastle/asn1/test rm -f src/org/bouncycastle/openpgp/test/DSA2Test.java rm -f src/org/bouncycastle/openpgp/test/PGPUnicodeTest.java find src -name AllTests.java -exec rm {} \; javadoc -windowtitle "$WINDOWTITLE" -doctitle "$DOCTITLE" \ -header "$HEADER" \ -group "BCPG Support Packages" "org.bouncycastle.bcpg*" \ -group "OpenPGP Packages" "org.bouncycastle.openpgp*" \ -classpath classes:../jce-ext-jdk12-146.jar \ -d docs -sourcepath src \ org.bouncycastle.bcpg \ org.bouncycastle.bcpg.attr \ org.bouncycastle.bcpg.sig \ org.bouncycastle.openpgp \ org.bouncycastle.openpgp.examples \ org.bouncycastle.openpgp.test > /dev/null \ echo "compiling" ed src/org/bouncycastle/bcpg/ArmoredOutputStream.java <<% /@RELEASE_NAME@/s//$version/ w q % (cd src/org/bouncycastle; javac -d ../../../classes -classpath ../../../classes:../../../src:../../../../jce-jdk12-$base/classes */*.java */*/*.java) cat > classes/pg.mf <<% Manifest-Version: 1.0 Extension-Name: org.bouncycastle.bcpg Specification-Vendor: BouncyCastle.org Specification-Version: 1.1 Implementation-Vendor-Id: org.bouncycastle Implementation-Vendor: BouncyCastle.org Implementation-Version: $version.0 % (cd classes; jar cmf pg.mf ../../bcpg-jdk12-$base.jar org) java -classpath ../jce-ext-jdk12-$base.jar:classes org.bouncycastle.openpgp.test.RegressionTest ) (2>&1 find bcpg-jdk12-$base -name CVS -exec rm -rf \{\} \;) > /dev/null fi if false # test "$base" != "" then echo "making tools release" mkdir bctools-jdk12-$base tar cf - index.html LICENSE.html CONTRIBUTORS.html releasenotes.html specifications.html | (cd bctools-jdk12-$base; tar xf -) (cd tools; tar cf - src) | (cd bctools-jdk12-$base; tar xf -) ( cd bctools-jdk12-$base; mkdir classes; mkdir docs; javadoc -windowtitle "$WINDOWTITLE" -doctitle "$DOCTITLE" \ -header "$HEADER" -group "Core Packages" "org.bouncycastle*" \ -classpath classes \ -d docs -sourcepath src -breakiterator \ org.bouncycastle.tools.openpgp \ org.bouncycastle.tools.openpgp.dump \ org.bouncycastle.tools.openpgp.rampage \ org.bouncycastle.tools.openpgp.util \ > /dev/null \ echo "compiling" (cd src/org/bouncycastle; javac -d ../../../classes -classpath ../../../classes:../../../tools/src */*/*.java */*/*/*.java) cat > classes/tools.mf <<% Manifest-Version: 1.0 Extension-Name: org.bouncycastle.tools Specification-Vendor: BouncyCastle.org Specification-Version: 1.1 Implementation-Vendor-Id: org.bouncycastle Implementation-Vendor: BouncyCastle.org Implementation-Version: $version.0 % (cd classes; jar cmf tools.mf ../../bctools-jdk12-$base.jar org) ) (2>&1 find bctools-jdk12-$base -name CVS -exec rm -rf \{\} \;) > /dev/null fi bouncycastle-1.49.orig/build1-30000644000175000017500000000166511155320444015703 0ustar ebourgebourg#!/bin/sh - # # build script for 1.5 # # If it's given a buildname it creates a subdirectory and places a build in it, # otherwise it just creates the docs and class files. # JDKPATH=/opt/jdk1.3.1 # JDK 1.3 location JAVA_MAIL_HOME=/opt/javamail-1.3.1 JAVA_ACTIVATION_HOME=/opt/jaf-1.0.2 XALAN_HOME=../../apache/xalan-j_2_7_0 W3C_HOME=../../w3c JAVA_HOME=$JDKPATH export JAVA_HOME PATH=$JDKPATH/bin:$PATH export PATH CLASSPATH=$JAVA_MAIL_HOME/mail.jar:$JAVA_ACTIVATION_HOME/activation.jar:$W3C_HOME/w3c.jar:$XALAN_HOME/serializer.jar:$XALAN_HOME/xalan.jar:$XALAN_HOME/xercesImpl.jar:$XALAN_HOME/xml-apis.jar:$XALAN_HOME/xsltc.jar:$CLASSPATH export CLASSPATH if [ "$1" = "test" ] then ant -f jdk13.xml test else if [ "$1" = "provider" ] then ant -f jdk13.xml build-provider ant -f jdk13.xml zip-src-provider else if ant -f jdk13.xml build-jce then ant -f jdk13.xml build ant -f jdk13.xml zip-src fi fi fi bouncycastle-1.49.orig/index.html0000644000175000017500000001257011310313041016416 0ustar ebourgebourg The Bouncy Castle Crypto Package

    The Bouncy Castle Crypto Package

    
    
    The Bouncy Castle Crypto package is a Java implementation of cryptographic algorithms, it was developed by the Legion of the Bouncy Castle - with a little help! The Legion, and the latest goings on with this package, can be found at http://www.bouncycastle.org.

    The Legion also gratefully acknowledges the contributions made to this package by others (see here for the current list).

    The package is organised so that it contains a light-weight API suitable for use in any environment (including the newly released J2ME) with the additional infrastructure to conform the algorithms to the JCE framework.

    Except where otherwise stated, this software is distributed under a license based on the MIT X Consortium license. To view the license, see here. The OpenPGP library also includes a modified BZIP2 library which is licensed under the Apache Software License, Version 2.0.

    The current release notes for this package are here.

    The current specifications for this package are here.

    The current api documentation for this package is here.

    Examples and Tests

    To view some examples, look at the test programs in the packages:

    • org.bouncycastle.crypto.test

    • org.bouncycastle.jce.provider.test

    • org.bouncycastle.cms.test

    • org.bouncycastle.mail.smime.test

    • org.bouncycastle.openpgp.test

    • org.bouncycastle.tsp.test

    There are also some specific example programs for dealing with Attribute Certificates, PKCS12, SMIME and OpenPGP. They can be found in:

    • org.bouncycastle.jce.examples

    • org.bouncycastle.mail.smime.examples

    • org.bouncycastle.openpgp.examples

    • org.bouncycastle.x509.examples

    Finally there are also code examples from Beginning Cryptography with Java which demonstrate both the use of the JCE/JCA and also some of the Bouncy Castle APIs.

    Note 1:The JCE classes are only distributed with the JDK 1.1, JDK 1.2, and JDK 1.3 JCE releases. The JDK 1.0, J2ME, and the JDK 1.1, JDK 1.2, JDK 1.3, JDK 1.4, and JDK 1.5 lightweight releases only include the Bouncy Castle lightweight cryptography API.
    Note 2:The regression test for Diffie-Hellman is quite slow.

    Building From CVS

    The src and test/src directory are for JDK 1.5.

    Compatibility classes for other VMs are as follows:

    • JDK 1.4 - jdk1.4, test/jdk1.4
    • JDK 1.3 - jdk1.3, test/jdk1.3
    • JDK 1.2 - jdk1.2
    • JDK 1.1 - jdk1.1
    • JDK 1.0 - jdk1.0
    • J2ME - j2me

    The clean room JCE, which will compile with everything from JDK 1.1 and up is in the jce/src directory.

    The build scripts that come with the full distribution allow creation of the different releases by using the tree under src and test/src, excluding classes that are not appropriate and copying in the required compatibility classes from the directories containing compatibility classes appropriate for the distribution.

    If you want to try create a build for yourself, using your own environment, the best way to do it is to start with the build for the distribution you are interested in, make sure that builds, and then modify your build scripts to do the required exclusions and file copies for your setup, otherwise you are likely to get class not found exceptions. The final caveat to this is that as the j2me distribution includes some compatibility classes starting in the java package, you need to use an obfuscator to change the package names before attempting to import a midlet using the BC API.

    Mailing Lists

    For those who are interested, there are 2 mailing lists for participation in this project. To subscribe use the links below and include the word subscribe in the message body. (To unsubscribe, replace subscribe with unsubscribe in the message body)

    NOTE:You need to be subscribed to send mail to the above mailing list.

    If you want to provide feedback, offers of jobs (or more importantly beer) directly to the members of The Legion then please use feedback-crypto@bouncycastle.org

    Enjoy! bouncycastle-1.49.orig/jars/0000755000175000017500000000000012152034631015365 5ustar ebourgebourgbouncycastle-1.49.orig/jdk1.1/0000755000175000017500000000000012152033550015415 5ustar ebourgebourgbouncycastle-1.49.orig/jdk1.1/org/0000755000175000017500000000000012152033550016204 5ustar ebourgebourgbouncycastle-1.49.orig/jdk1.1/org/bouncycastle/0000755000175000017500000000000012152033551020700 5ustar ebourgebourgbouncycastle-1.49.orig/jdk1.1/org/bouncycastle/openpgp/0000755000175000017500000000000012152033551022350 5ustar ebourgebourgbouncycastle-1.49.orig/jdk1.1/org/bouncycastle/openpgp/test/0000755000175000017500000000000012152033551023327 5ustar ebourgebourgbouncycastle-1.49.orig/jdk1.1/org/bouncycastle/openpgp/test/PGPKeyRingTest.java0000644000175000017500000012506311705654530026771 0ustar ebourgebourgpackage org.bouncycastle.openpgp.test; import java.math.BigInteger; import java.security.KeyPair; import java.security.KeyPairGenerator; import java.security.SecureRandom; import java.util.Date; import java.util.Iterator; import org.bouncycastle.openpgp.PGPEncryptedData; import org.bouncycastle.openpgp.PGPException; import org.bouncycastle.openpgp.PGPKeyPair; import org.bouncycastle.openpgp.PGPKeyRingGenerator; import org.bouncycastle.openpgp.PGPPublicKey; import org.bouncycastle.openpgp.PGPPublicKeyRing; import org.bouncycastle.openpgp.PGPPublicKeyRingCollection; import org.bouncycastle.openpgp.PGPSecretKey; import org.bouncycastle.openpgp.PGPSecretKeyRing; import org.bouncycastle.openpgp.PGPSecretKeyRingCollection; import org.bouncycastle.openpgp.PGPSignature; import org.bouncycastle.util.encoders.Base64; import org.bouncycastle.util.test.SimpleTestResult; import org.bouncycastle.util.test.Test; import org.bouncycastle.util.test.TestResult; public class PGPKeyRingTest implements Test { byte[] pub1 = Base64.decode( "mQGiBEA83v0RBADzKVLVCnpWQxX0LCsevw/3OLs0H7MOcLBQ4wMO9sYmzGYn" + "xpVj+4e4PiCP7QBayWyy4lugL6Lnw7tESvq3A4v3fefcxaCTkJrryiKn4+Cg" + "y5rIBbrSKNtCEhVi7xjtdnDjP5kFKgHYjVOeIKn4Cz/yzPG3qz75kDknldLf" + "yHxp2wCgwW1vAE5EnZU4/UmY7l8kTNkMltMEAJP4/uY4zcRwLI9Q2raPqAOJ" + "TYLd7h+3k/BxI0gIw96niQ3KmUZDlobbWBI+VHM6H99vcttKU3BgevNf8M9G" + "x/AbtW3SS4De64wNSU3189XDG8vXf0vuyW/K6Pcrb8exJWY0E1zZQ1WXT0gZ" + "W0kH3g5ro//Tusuil9q2lVLF2ovJA/0W+57bPzi318dWeNs0tTq6Njbc/GTG" + "FUAVJ8Ss5v2u6h7gyJ1DB334ExF/UdqZGldp0ugkEXaSwBa2R7d3HBgaYcoP" + "Ck1TrovZzEY8gm7JNVy7GW6mdOZuDOHTxyADEEP2JPxh6eRcZbzhGuJuYIif" + "IIeLOTI5Dc4XKeV32a+bWrQidGVzdCAoVGVzdCBrZXkpIDx0ZXN0QHViaWNh" + "bGwuY29tPohkBBMRAgAkBQJAPN79AhsDBQkB4TOABgsJCAcDAgMVAgMDFgIB" + "Ah4BAheAAAoJEJh8Njfhe8KmGDcAoJWr8xgPr75y/Cp1kKn12oCCOb8zAJ4p" + "xSvk4K6tB2jYbdeSrmoWBZLdMLACAAC5AQ0EQDzfARAEAJeUAPvUzJJbKcc5" + "5Iyb13+Gfb8xBWE3HinQzhGr1v6A1aIZbRj47UPAD/tQxwz8VAwJySx82ggN" + "LxCk4jW9YtTL3uZqfczsJngV25GoIN10f4/j2BVqZAaX3q79a3eMiql1T0oE" + "AGmD7tO1LkTvWfm3VvA0+t8/6ZeRLEiIqAOHAAQNBACD0mVMlAUgd7REYy/1" + "mL99Zlu9XU0uKyUex99sJNrcx1aj8rIiZtWaHz6CN1XptdwpDeSYEOFZ0PSu" + "qH9ByM3OfjU/ya0//xdvhwYXupn6P1Kep85efMBA9jUv/DeBOzRWMFG6sC6y" + "k8NGG7Swea7EHKeQI40G3jgO/+xANtMyTIhPBBgRAgAPBQJAPN8BAhsMBQkB" + "4TOAAAoJEJh8Njfhe8KmG7kAn00mTPGJCWqmskmzgdzeky5fWd7rAKCNCp3u" + "ZJhfg0htdgAfIy8ppm05vLACAAA="); byte[] sec1 = Base64.decode( "lQHhBEA83v0RBADzKVLVCnpWQxX0LCsevw/3OLs0H7MOcLBQ4wMO9sYmzGYn" + "xpVj+4e4PiCP7QBayWyy4lugL6Lnw7tESvq3A4v3fefcxaCTkJrryiKn4+Cg" + "y5rIBbrSKNtCEhVi7xjtdnDjP5kFKgHYjVOeIKn4Cz/yzPG3qz75kDknldLf" + "yHxp2wCgwW1vAE5EnZU4/UmY7l8kTNkMltMEAJP4/uY4zcRwLI9Q2raPqAOJ" + "TYLd7h+3k/BxI0gIw96niQ3KmUZDlobbWBI+VHM6H99vcttKU3BgevNf8M9G" + "x/AbtW3SS4De64wNSU3189XDG8vXf0vuyW/K6Pcrb8exJWY0E1zZQ1WXT0gZ" + "W0kH3g5ro//Tusuil9q2lVLF2ovJA/0W+57bPzi318dWeNs0tTq6Njbc/GTG" + "FUAVJ8Ss5v2u6h7gyJ1DB334ExF/UdqZGldp0ugkEXaSwBa2R7d3HBgaYcoP" + "Ck1TrovZzEY8gm7JNVy7GW6mdOZuDOHTxyADEEP2JPxh6eRcZbzhGuJuYIif" + "IIeLOTI5Dc4XKeV32a+bWv4CAwJ5KgazImo+sGBfMhDiBcBTqyDGhKHNgHic" + "0Pky9FeRvfXTc2AO+jGmFPjcs8BnTWuDD0/jkQnRZpp1TrQidGVzdCAoVGVz" + "dCBrZXkpIDx0ZXN0QHViaWNhbGwuY29tPohkBBMRAgAkBQJAPN79AhsDBQkB" + "4TOABgsJCAcDAgMVAgMDFgIBAh4BAheAAAoJEJh8Njfhe8KmGDcAn3XeXDMg" + "BZgrZzFWU2IKtA/5LG2TAJ0Vf/jjyq0jZNZfGfoqGTvD2MAl0rACAACdAVgE" + "QDzfARAEAJeUAPvUzJJbKcc55Iyb13+Gfb8xBWE3HinQzhGr1v6A1aIZbRj4" + "7UPAD/tQxwz8VAwJySx82ggNLxCk4jW9YtTL3uZqfczsJngV25GoIN10f4/j" + "2BVqZAaX3q79a3eMiql1T0oEAGmD7tO1LkTvWfm3VvA0+t8/6ZeRLEiIqAOH" + "AAQNBACD0mVMlAUgd7REYy/1mL99Zlu9XU0uKyUex99sJNrcx1aj8rIiZtWa" + "Hz6CN1XptdwpDeSYEOFZ0PSuqH9ByM3OfjU/ya0//xdvhwYXupn6P1Kep85e" + "fMBA9jUv/DeBOzRWMFG6sC6yk8NGG7Swea7EHKeQI40G3jgO/+xANtMyTP4C" + "AwJ5KgazImo+sGBl2C7CFuI+5KM4ZhbtVie7l+OiTpr5JW2z5VgnV3EX9p04" + "LcGKfQvD65+ELwli6yh8B2zGcipqTaYk3QoYNIhPBBgRAgAPBQJAPN8BAhsM" + "BQkB4TOAAAoJEJh8Njfhe8KmG7kAniuRkaFFv1pdCBN8JJXpcorHmyouAJ9L" + "xxmusffR6OI7WgD3XZ0AL8zUC7ACAAA="); char[] pass1 = "qwertzuiop".toCharArray(); byte[] pub2 = Base64.decode( "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"); byte[] sec2 = Base64.decode( "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" + "Nifs+ljmsAFn"); char[] sec2pass1 = "sandhya".toCharArray(); char[] sec2pass2 = "psai".toCharArray(); byte[] pub3 = Base64.decode( "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" + "n3FaE6UZE9GMDmCIAjhI+0X9aH6CsAIAAw=="); byte[] sec3 = Base64.decode( "lQHhBEB9BH0RBACtYQtE7tna6hgGyGLpq+ds3r2cLC0ISn5dNw7tm9vwiNVF" + "JA2N37RRrifw4PvgelRSvLaX3M3ZBqC9s1Metg3v4FSlIRtSLWCNpHSvNw7i" + "X8C2Xy9Hdlbh6Y/50o+iscojLRE14upfR1bIkcCZQGSyvGV52V2wBImUUZjV" + "s2ZngwCg7mu852vK7+euz4WaL7ERVYtq9CMEAJ5swrljerDpz/RQ4Lhp6KER" + "KyuI0PUttO57xINGshEINgYlZdGaZHRueHe7uKfI19mb0T4N3NJWaZ0wF+Cn" + "rixsq0VrTUfiwfZeGluNG73aTCeY45fVXMGTTSYXzS8T0LW100Xn/0g9HRyA" + "xUpuWo8IazxkMqHJis2uwriYKpAfA/9anvj5BS9p5pfPjp9dGM7GTMIYl5f2" + "fcP57f+AW1TVR6IZiMJAvAdeWuLtwLnJiFpGlnFz273pfl+sAuqm1yNceImR" + "2SDDP4+vtyycWy8nZhgEuhZx3W3cWMQz5WyNJSY1JJHh9TCQkCoN8E7XpVP4" + "zEPboB2GzD93mfD8JLHP+/4DAwIvYrn+YqRaaGAu19XUj895g/GROyP8WEaU" + "Bd/JNqWc4kE/0guetGnPzq7G3bLVwiKfFd4X7BrgHAo3mrQtVGVzdCBLZXkg" + "KG5vIGNvbW1lbnQpIDx0ZXN0QGJvdW5jeWNhc3RsZS5vcmc+iFkEExECABkF" + "AkB9BH0ECwcDAgMVAgMDFgIBAh4BAheAAAoJEKnMV8vjZQOpSRQAoKZy6YS1" + "irF5/Q3JlWiwbkN6dEuLAJ9lldRLOlXsuQ5JW1+SLEc6K9ho4rACAADRwXPB" + "cQEQAAEBAAAAAAAAAAAAAAAA/9j/4AAQSkZJRgABAQEASABIAAD//gAXQ3Jl" + "YXRlZCB3aXRoIFRoZSBHSU1Q/9sAQwAIBgYHBgUIBwcHCQkICgwUDQwLCwwZ" + "EhMPFB0aHx4dGhwcICQuJyAiLCMcHCg3KSwwMTQ0NB8nOT04MjwuMzQy/9sA" + "QwEJCQkMCwwYDQ0YMiEcITIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIy" + "MjIyMjIyMjIyMjIyMjIyMjIyMjIy/8AAEQgAFAAUAwEiAAIRAQMRAf/EABoA" + "AQACAwEAAAAAAAAAAAAAAAAEBQIDBgf/xAAoEAABAgUDBAEFAAAAAAAAAAAB" + "AgMABBEhMQUSQQYTIiNhFFGBkcH/xAAXAQEAAwAAAAAAAAAAAAAAAAAEAgMF" + "/8QAJBEAAQQAAwkAAAAAAAAAAAAAAQACERIEIfATMTJBUZGx0fH/2gAMAwEA" + "AhEDEQA/APMuotJlJVxstqaPo22NlAUp+YsNO0qSUtBcMu6n6EtOHcfPAHHF" + "I16++oajQtTA3DapK02HFR8UpE9pTbQWtKm2WG2rlxVyQTcfGbn7Qm0OIjL7" + "7Wrs2NNm9lzTmmSxQ0PX4opSprk5tmESF6syggzGwOLG6gXgHFbZhBixk8Xl" + "IDcOQLRKt+rX+3qC5ZLTQblpQlvwvxn9CMpZturVGkJHapQJphRH8hCLXbzr" + "qpYsCx1zC5rtpJNuYQhASc0UAQv/2YhcBBMRAgAcBQJAfQV+AhsDBAsHAwID" + "FQIDAxYCAQIeAQIXgAAKCRCpzFfL42UDqfa2AJ9hjtEeDTbTEAuuSbzhYFxN" + "/qc0FACgsmzysdbBpuN65yK01tbEaeIMtqCwAgAAnQEUBEB9BH4QAwCqRuWO" + "rxm5v/8WWBtPEUZnYuu3WYxefRKn6ON5ka5Ymp4AfKpKqKqn982tjlG13GVE" + "P2ow11L4yQKGNm+VyVEapm7SpMD0SHg9vsJygAWrfMJnBYWSgE19W6o3ckUR" + "sWsAAwYDAKDCSiSxC3Z5/POaCehw5iHs/vmVk5Wn831LSZEEwkSohNDbIEry" + "ia/9tFXSt11AP4stJtZ0MH87/6JBbiIRD4JXcx+zfzchL7Teczr/06QMphSn" + "sAENupbhLupfpR+BbP4DAwIvYrn+YqRaaGBjvFK1fbxCt7ZM4I2W/3BC0lCX" + "m/NypKNspGflec8u96uUlA0fNCnxm6f9nbB0jpvoKi0g4iqAf+P2iEYEGBEC" + "AAYFAkB9BH4ACgkQqcxXy+NlA6mtMgCgvccZA/Sg7BXVpxli47SYhxSHoM4A" + "oNCOMplSnYTuh5ikKeBWtz36gC1psAIAAA=="); char[] sec3pass1 = "123456".toCharArray(); // // GPG comment packets. // byte[] sec4 = Base64.decode( "lQG7BD0PbK8RBAC0cW4Y2MZXmAmqYp5Txyw0kSQsFvwZKHNMFRv996IsN57URVF5" + "BGMVPRBi9dNucWbjiSYpiYN13wE9IuLZsvVaQojV4XWGRDc+Rxz9ElsXnsYQ3mZU" + "7H1bNQEofstChk4z+dlvPBN4GFahrIzn/CeVUn6Ut7dVdYbiTqviANqNXwCglfVA" + "2OEePvqFnGxs1jhJyPSOnTED/RwRvsLH/k43mk6UEvOyN1RIpBXN+Ieqs7h1gFrQ" + "kB+WMgeP5ZUsotTffVDSUS9UMxRQggVUW1Xml0geGwQsNfkr/ztWMs/T4xp1v5j+" + "QyJx6OqNlkGdqOsoqkzJx0SQ1zBxdinFyyC4H95SDAb/RQOu5LQmxFG7quexztMs" + "infEA/9cVc9+qCo92yRAaXRqKNVVQIQuPxeUsGMyVeJQvJBD4An8KTMCdjpF10Cp" + "qA3t+n1S0zKr5WRUtvS6y60MOONO+EJWVWBNkx8HJDaIMNkfoqQoz3Krn7w6FE/v" + "/5uwMd6jY3N3yJZn5nDZT9Yzv9Nx3j+BrY+henRlSU0c6xDc9QAAnjJYg0Z83VJG" + "6HrBcgc4+4K6lHulCqH9JiM6RFNBX2ZhY3RvcjoAAK9hV206agp99GI6x5qE9+pU" + "vs6O+Ich/SYjOkRTQV9mYWN0b3I6AACvYAfGn2FGrpBYbjnpTuFOHJMS/T5xg/0m" + "IzpEU0FfZmFjdG9yOgAAr0dAQz6XxMwxWIn8xIZR/v2iN2L9C6O0EkZvbyBCYXIg" + "PGJhekBxdXV4PohXBBMRAgAXBQI9D2yvBQsHCgMEAxUDAgMWAgECF4AACgkQUGLI" + "YCIktfoGogCfZiXMJUKrScqozv5tMwzTTk2AaT8AniM5iRr0Du/Y08SL/NMhtF6H" + "hJ89nO4EPQ9ssRADAI6Ggxj6ZBfoavuXd/ye99osW8HsNlbqhXObu5mCMNySX2wa" + "HoWyRUEaUkI9eQw+MlHzIwzA32E7y2mU3OQBKdgLcBg4jxtcWVEg8ESKF9MpFXxl" + "pExxWrr4DFBfCRcsTwAFEQL9G3OvwJuEZXgx2JSS41D3pG4/qiHYICVa0u3p/14i" + "cq0kXajIk5ZJ6frCIAHIzuQ3n7jjzr05yR8s/qCrNbBA+nlkVNa/samk+jCzxxxa" + "cR/Dbh2wkvTFuDFFETwQYLuZAADcDck4YGQAmHivVT2NNDCf/aTz0+CJWl+xRc2l" + "Qw7D/SQjOkVMR19mYWN0b3I6AACbBnv9m5/bb/pjYAm2PtDp0CysQ9X9JCM6RUxH" + "X2ZhY3RvcjoAAJsFyHnSmaWguTFf6lJ/j39LtUNtmf0kIzpFTEdfZmFjdG9yOgAA" + "mwfwMD3LxmWtuCWBE9BptWMNH07Z/SQjOkVMR19mYWN0b3I6AACbBdhBrbSiM4UN" + "y7khDW2Sk0e4v9mIRgQYEQIABgUCPQ9ssQAKCRBQYshgIiS1+jCMAJ9txwHnb1Kl" + "6i/fSoDs8SkdM7w48wCdFvPEV0sSxE73073YhBgPZtMWbBo="); // // PGP freeware version 7 // byte[] pub5 = Base64.decode( "mQENBEBrBE4BCACjXVcNIFDQSofaIyZnALb2CRg+WY9uUqgHEEAOlPe03Cs5STM5" + "HDlNmrh4TdFceJ46rxk1mQOjULES1YfHay8lCIzrD7FX4oj0r4DC14Fs1vXaSar2" + "1szIpttOw3obL4A1e0p6N4jjsoG7N/pA0fEL0lSw92SoBrMbAheXRg4qNTZvdjOR" + "grcuOuwgJRvPLtRXlhyLBoyhkd5mmrIDGv8QHJ/UjpeIcRXY9kn9oGXnEYcRbMaU" + "VwXB4pLzWqz3ZejFI3lOxRWjm760puPOnGYlzSVBxlt2LgzUgSj1Mn+lIpWmAzsa" + "xEiU4xUwEomQns72yYRZ6D3euNCibcte4SeXABEBAAG0KXBhbGFzaCBrYXNvZGhh" + "biA8cGthc29kaGFuQHRpYWEtY3JlZi5vcmc+iQEuBBABAgAYBQJAawROCAsBAwkI" + "BwIKAhkBBRsDAAAAAAoJEOfelumuiOrYqPEH+wYrdP5Tq5j+E5yN1pyCg1rwbSOt" + "Dka0y0p7Oq/VIGLk692IWPItLEunnBXQtGBcWqklrvogvlhxtf16FgoyScfLJx1e" + "1cJa+QQnVuH+VOESN6iS9Gp9lUfVOHv74mEMXw0l2Djfy/lnrkAMBatggyGnF9xF" + "VXOLk1J2WVFm9KUE23o6qdB7RGkf31pN2eA7SWmkdJSkUH7o/QSFBI+UTRZ/IY5P" + "ZIJpsdiIOqd9YMG/4RoSZuPqNRR6x7BSs8nQVR9bYs4PPlp4GfdRnOcRonoTeJCZ" + "83RnsraWJnJTg34gRLBcqumhTuFKc8nuCNK98D6zkQESdcHLLTquCOaF5L+5AQ0E" + "QGsETwEIAOVwNCTaDZvW4dowPbET1bI5UeYY8rAGLYsWSUfgaFv2srMiApyBVltf" + "i6OLcPjcUCHDBjCv4pwx/C4qcHWb8av4xQIpqQXOpO9NxYE1eZnel/QB7DtH12ZO" + "nrDNmHtaXlulcKNGe1i1utlFhgzfFx6rWkRL0ENmkTkaQmPY4gTGymJTUhBbsSRq" + "2ivWqQA1TPwBuda73UgslIAHRd/SUaxjXoLpMbGOTeqzcKGjr5XMPTs7/YgBpWPP" + "UxMlEQIiU3ia1bxpEhx05k97ceK6TSH2oCPQA7gumjxOSjKT+jEm+8jACVzymEmc" + "XRy4D5Ztqkw/Z16pvNcu1DI5m6xHwr8AEQEAAYkBIgQYAQIADAUCQGsETwUbDAAA" + "AAAKCRDn3pbprojq2EynB/4/cEOtKbI5UisUd3vkTzvWOcqWUqGqi5wjjioNtIM5" + "pur2nFvhQE7SZ+PbAa87HRJU/4WcWMcoLkHD48JrQwHCHOLHSV5muYowb78X4Yh9" + "epYtSJ0uUahcn4Gp48p4BkhgsPYXkxEImSYzAOWStv21/7WEMqItMYl89BV6Upm8" + "HyTJx5MPTDbMR7X51hRg3OeQs6po3WTCWRzFIMyGm1rd/VK1L5ZDFPqO3S6YUJ0z" + "cxecYruvfK0Wp7q834wE8Zkl/PQ3NhfEPL1ZiLr/L00Ty+77/FZqt8SHRCICzOfP" + "OawcVGI+xHVXW6lijMpB5VaVIH8i2KdBMHXHtduIkPr9"); byte[] sec5 = Base64.decode( "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"); char[] sec5pass1 = "12345678".toCharArray(); private boolean notEqual( byte[] b1, byte[] b2) { if (b1.length != b2.length) { return true; } for (int i = 0; i != b2.length; i++) { if (b1[i] != b2[i]) { return true; } } return false; } public TestResult test1() { try { PGPPublicKeyRingCollection pubRings = new PGPPublicKeyRingCollection(pub1); int count = 0; Iterator rIt = pubRings.getKeyRings(); while (rIt.hasNext()) { PGPPublicKeyRing pgpPub = (PGPPublicKeyRing)rIt.next(); count++; int keyCount = 0; byte[] bytes = pgpPub.getEncoded(); pgpPub = new PGPPublicKeyRing(bytes); Iterator it = pgpPub.getPublicKeys(); while (it.hasNext()) { keyCount++; it.next(); } if (keyCount != 2) { return new SimpleTestResult(false, getName() + ": wrong number of public keys"); } } if (count != 1) { return new SimpleTestResult(false, getName() + ": wrong number of public keyrings"); } PGPSecretKeyRingCollection secretRings = new PGPSecretKeyRingCollection(sec1); rIt = secretRings.getKeyRings(); count = 0; while (rIt.hasNext()) { PGPSecretKeyRing pgpSec = (PGPSecretKeyRing)rIt.next(); count++; int keyCount = 0; byte[] bytes = pgpSec.getEncoded(); pgpSec = new PGPSecretKeyRing(bytes); Iterator it = pgpSec.getSecretKeys(); while (it.hasNext()) { keyCount++; PGPSecretKey k = (PGPSecretKey)it.next(); PGPPublicKey pk = k.getPublicKey(); byte[] pkBytes = pk.getEncoded(); PGPPublicKeyRing pkR = new PGPPublicKeyRing(pkBytes); } if (keyCount != 2) { return new SimpleTestResult(false, getName() + ": wrong number of secret keys"); } } if (count != 1) { return new SimpleTestResult(false, getName() + ": wrong number of secret keyrings"); } return new SimpleTestResult(true, getName() + ": Okay"); } catch (Exception e) { if (e instanceof PGPException) { if (((PGPException)e).getUnderlyingException() != null) { ((PGPException)e).getUnderlyingException().printStackTrace(); } } else { e.printStackTrace(); } return new SimpleTestResult(false, getName() + ": exception - " + e.toString()); } } public TestResult test2() { try { PGPPublicKeyRingCollection pubRings = new PGPPublicKeyRingCollection(pub2); int count = 0; byte[] encRing = pubRings.getEncoded(); pubRings = new PGPPublicKeyRingCollection(encRing); Iterator rIt = pubRings.getKeyRings(); while (rIt.hasNext()) { PGPPublicKeyRing pgpPub = (PGPPublicKeyRing)rIt.next(); count++; int keyCount = 0; byte[] bytes = pgpPub.getEncoded(); pgpPub = new PGPPublicKeyRing(bytes); Iterator it = pgpPub.getPublicKeys(); while (it.hasNext()) { PGPPublicKey pk = (PGPPublicKey)it.next(); byte[] pkBytes = pk.getEncoded(); PGPPublicKeyRing pkR = new PGPPublicKeyRing(pkBytes); keyCount++; } if (keyCount != 2) { return new SimpleTestResult(false, getName() + ": wrong number of public keys"); } } if (count != 2) { return new SimpleTestResult(false, getName() + ": wrong number of public keyrings"); } PGPSecretKeyRingCollection secretRings = new PGPSecretKeyRingCollection(sec2); rIt = secretRings.getKeyRings(); count = 0; encRing = secretRings.getEncoded(); secretRings = new PGPSecretKeyRingCollection(encRing); while (rIt.hasNext()) { PGPSecretKeyRing pgpSec = (PGPSecretKeyRing)rIt.next(); count++; int keyCount = 0; byte[] bytes = pgpSec.getEncoded(); pgpSec = new PGPSecretKeyRing(bytes); Iterator it = pgpSec.getSecretKeys(); while (it.hasNext()) { keyCount++; PGPSecretKey k = (PGPSecretKey)it.next(); PGPPublicKey pk = k.getPublicKey(); byte[] pkBytes = pk.getEncoded(); PGPPublicKeyRing pkR = new PGPPublicKeyRing(pkBytes); if (k.getKeyID() == -4049084404703773049L || k.getKeyID() == -1413891222336124627L) { k.extractPrivateKey(sec2pass1, "BC"); } else if (k.getKeyID() == -6498553574938125416L || k.getKeyID() == 59034765524361024L) { k.extractPrivateKey(sec2pass2, "BC"); } } if (keyCount != 2) { return new SimpleTestResult(false, getName() + ": wrong number of secret keys"); } } if (count != 2) { return new SimpleTestResult(false, getName() + ": wrong number of secret keyrings"); } return new SimpleTestResult(true, getName() + ": Okay"); } catch (Exception e) { if (e instanceof PGPException) { if (((PGPException)e).getUnderlyingException() != null) { ((PGPException)e).getUnderlyingException().printStackTrace(); } } else { e.printStackTrace(); } return new SimpleTestResult(false, getName() + ": exception - "+ e); } } public TestResult test3() { try { PGPPublicKeyRingCollection pubRings = new PGPPublicKeyRingCollection(pub3); int count = 0; byte[] encRing = pubRings.getEncoded(); pubRings = new PGPPublicKeyRingCollection(encRing); Iterator rIt = pubRings.getKeyRings(); while (rIt.hasNext()) { PGPPublicKeyRing pgpPub = (PGPPublicKeyRing)rIt.next(); count++; int keyCount = 0; byte[] bytes = pgpPub.getEncoded(); pgpPub = new PGPPublicKeyRing(bytes); Iterator it = pgpPub.getPublicKeys(); while (it.hasNext()) { keyCount++; it.next(); } if (keyCount != 2) { return new SimpleTestResult(false, getName() + ": wrong number of public keys"); } } if (count != 1) { return new SimpleTestResult(false, getName() + ": wrong number of public keyrings"); } PGPSecretKeyRingCollection secretRings = new PGPSecretKeyRingCollection(sec3); rIt = secretRings.getKeyRings(); count = 0; encRing = secretRings.getEncoded(); secretRings = new PGPSecretKeyRingCollection(encRing); while (rIt.hasNext()) { PGPSecretKeyRing pgpSec = (PGPSecretKeyRing)rIt.next(); count++; int keyCount = 0; byte[] bytes = pgpSec.getEncoded(); pgpSec = new PGPSecretKeyRing(bytes); Iterator it = pgpSec.getSecretKeys(); while (it.hasNext()) { keyCount++; PGPSecretKey k = (PGPSecretKey)it.next(); k.extractPrivateKey(sec3pass1, "BC"); } if (keyCount != 2) { return new SimpleTestResult(false, getName() + ": wrong number of secret keys"); } } if (count != 1) { return new SimpleTestResult(false, getName() + ": wrong number of secret keyrings"); } return new SimpleTestResult(true, getName() + ": Okay"); } catch (Exception e) { if (e instanceof PGPException) { if (((PGPException)e).getUnderlyingException() != null) { ((PGPException)e).getUnderlyingException().printStackTrace(); } } return new SimpleTestResult(false, getName() + ": exception - " + e.toString()); } } public TestResult test4() { try { PGPSecretKeyRingCollection secretRings = new PGPSecretKeyRingCollection(sec4); Iterator rIt = secretRings.getKeyRings(); int count = 0; byte[] encRing = secretRings.getEncoded(); secretRings = new PGPSecretKeyRingCollection(encRing); while (rIt.hasNext()) { PGPSecretKeyRing pgpSec = (PGPSecretKeyRing)rIt.next(); count++; int keyCount = 0; byte[] bytes = pgpSec.getEncoded(); pgpSec = new PGPSecretKeyRing(bytes); Iterator it = pgpSec.getSecretKeys(); while (it.hasNext()) { keyCount++; PGPSecretKey k = (PGPSecretKey)it.next(); k.extractPrivateKey(sec3pass1, "BC"); } if (keyCount != 2) { return new SimpleTestResult(false, getName() + ": wrong number of secret keys"); } } if (count != 1) { return new SimpleTestResult(false, getName() + ": wrong number of secret keyrings"); } return new SimpleTestResult(true, getName() + ": Okay"); } catch (Exception e) { if (e instanceof PGPException) { if (((PGPException)e).getUnderlyingException() != null) { ((PGPException)e).getUnderlyingException().printStackTrace(); } } return new SimpleTestResult(false, getName() + ": exception - " + e.toString()); } } public TestResult test5() { try { PGPPublicKeyRingCollection pubRings = new PGPPublicKeyRingCollection(pub5); int count = 0; byte[] encRing = pubRings.getEncoded(); pubRings = new PGPPublicKeyRingCollection(encRing); Iterator rIt = pubRings.getKeyRings(); while (rIt.hasNext()) { PGPPublicKeyRing pgpPub = (PGPPublicKeyRing)rIt.next(); count++; int keyCount = 0; byte[] bytes = pgpPub.getEncoded(); pgpPub = new PGPPublicKeyRing(bytes); Iterator it = pgpPub.getPublicKeys(); while (it.hasNext()) { keyCount++; it.next(); } if (keyCount != 2) { return new SimpleTestResult(false, getName() + ": wrong number of public keys"); } } if (count != 1) { return new SimpleTestResult(false, getName() + ": wrong number of public keyrings"); } PGPSecretKeyRingCollection secretRings = new PGPSecretKeyRingCollection(sec5); rIt = secretRings.getKeyRings(); count = 0; encRing = secretRings.getEncoded(); secretRings = new PGPSecretKeyRingCollection(encRing); while (rIt.hasNext()) { PGPSecretKeyRing pgpSec = (PGPSecretKeyRing)rIt.next(); count++; int keyCount = 0; byte[] bytes = pgpSec.getEncoded(); pgpSec = new PGPSecretKeyRing(bytes); Iterator it = pgpSec.getSecretKeys(); while (it.hasNext()) { keyCount++; PGPSecretKey k = (PGPSecretKey)it.next(); k.extractPrivateKey(sec5pass1, "BC"); } if (keyCount != 2) { return new SimpleTestResult(false, getName() + ": wrong number of secret keys"); } } if (count != 1) { return new SimpleTestResult(false, getName() + ": wrong number of secret keyrings"); } return new SimpleTestResult(true, getName() + ": Okay"); } catch (Exception e) { if (e instanceof PGPException) { if (((PGPException)e).getUnderlyingException() != null) { ((PGPException)e).getUnderlyingException().printStackTrace(); } } return new SimpleTestResult(false, getName() + ": exception - " + e.toString()); } } public TestResult perform() { TestResult res = test1(); if (!res.isSuccessful()) { return res; } res = test2(); if (!res.isSuccessful()) { return res; } res = test3(); if (!res.isSuccessful()) { return res; } res = test4(); if (!res.isSuccessful()) { return res; } res = test5(); if (!res.isSuccessful()) { return res; } return res; } public String getName() { return "PGPKeyRingTest"; } public static void main( String[] args) { Test test = new PGPKeyRingTest(); TestResult result = test.perform(); System.out.println(result.toString()); } } bouncycastle-1.49.orig/jdk1.1/org/bouncycastle/openpgp/test/BcPGPDSAElGamalTest.java0000644000175000017500000005373311705655644027533 0ustar ebourgebourgpackage org.bouncycastle.openpgp.test; import java.io.ByteArrayInputStream; import java.io.ByteArrayOutputStream; import java.io.InputStream; import java.io.OutputStream; import java.math.BigInteger; import java.security.AlgorithmParameterGenerator; import java.security.AlgorithmParameters; import java.security.KeyPair; import java.security.KeyPairGenerator; import java.security.SecureRandom; import java.security.Security; import java.util.Date; import java.util.Iterator; import javax.crypto.spec.DHParameterSpec; import org.bouncycastle.bcpg.BCPGOutputStream; import org.bouncycastle.bcpg.PublicKeyAlgorithmTags; import org.bouncycastle.bcpg.SymmetricKeyAlgorithmTags; import org.bouncycastle.crypto.AsymmetricBlockCipher; import org.bouncycastle.crypto.encodings.PKCS1Encoding; import org.bouncycastle.crypto.engines.ElGamalEngine; import org.bouncycastle.crypto.params.AsymmetricKeyParameter; import org.bouncycastle.jce.provider.BouncyCastleProvider; import org.bouncycastle.jce.spec.ElGamalParameterSpec; import org.bouncycastle.openpgp.PGPCompressedData; import org.bouncycastle.openpgp.PGPCompressedDataGenerator; import org.bouncycastle.openpgp.PGPEncryptedDataGenerator; import org.bouncycastle.openpgp.PGPEncryptedDataList; import org.bouncycastle.openpgp.PGPException; import org.bouncycastle.openpgp.PGPKeyPair; import org.bouncycastle.openpgp.PGPLiteralData; import org.bouncycastle.openpgp.PGPLiteralDataGenerator; import org.bouncycastle.openpgp.PGPObjectFactory; import org.bouncycastle.openpgp.PGPOnePassSignature; import org.bouncycastle.openpgp.PGPOnePassSignatureList; import org.bouncycastle.openpgp.PGPPrivateKey; import org.bouncycastle.openpgp.PGPPublicKey; import org.bouncycastle.openpgp.PGPPublicKeyEncryptedData; import org.bouncycastle.openpgp.PGPPublicKeyRing; import org.bouncycastle.openpgp.PGPSecretKeyRing; import org.bouncycastle.openpgp.PGPSignature; import org.bouncycastle.openpgp.PGPSignatureGenerator; import org.bouncycastle.openpgp.PGPSignatureList; import org.bouncycastle.openpgp.PGPUtil; import org.bouncycastle.openpgp.operator.bc.BcKeyFingerprintCalculator; import org.bouncycastle.openpgp.operator.bc.BcPBESecretKeyDecryptorBuilder; import org.bouncycastle.openpgp.operator.bc.BcPGPContentSignerBuilder; import org.bouncycastle.openpgp.operator.bc.BcPGPContentVerifierBuilderProvider; import org.bouncycastle.openpgp.operator.bc.BcPGPDataEncryptorBuilder; import org.bouncycastle.openpgp.operator.bc.BcPGPDigestCalculatorProvider; import org.bouncycastle.openpgp.operator.bc.BcPGPKeyConverter; import org.bouncycastle.openpgp.operator.bc.BcPublicKeyDataDecryptorFactory; import org.bouncycastle.openpgp.operator.bc.BcPublicKeyKeyEncryptionMethodGenerator; import org.bouncycastle.util.encoders.Base64; import org.bouncycastle.util.test.SimpleTest; import org.bouncycastle.util.test.UncloseableOutputStream; public class BcPGPDSAElGamalTest extends SimpleTest { byte[] testPubKeyRing = Base64.decode( "mQGiBEAR8jYRBADNifuSopd20JOQ5x30ljIaY0M6927+vo09NeNxS3KqItba" + "nz9o5e2aqdT0W1xgdHYZmdElOHTTsugZxdXTEhghyxoo3KhVcNnTABQyrrvX" + "qouvmP2fEDEw0Vpyk+90BpyY9YlgeX/dEA8OfooRLCJde/iDTl7r9FT+mts8" + "g3azjwCgx+pOLD9LPBF5E4FhUOdXISJ0f4EEAKXSOi9nZzajpdhe8W2ZL9gc" + "BpzZi6AcrRZBHOEMqd69gtUxA4eD8xycUQ42yH89imEcwLz8XdJ98uHUxGJi" + "qp6hq4oakmw8GQfiL7yQIFgaM0dOAI9Afe3m84cEYZsoAFYpB4/s9pVMpPRH" + "NsVspU0qd3NHnSZ0QXs8L8DXGO1uBACjDUj+8GsfDCIP2QF3JC+nPUNa0Y5t" + "wKPKl+T8hX/0FBD7fnNeC6c9j5Ir/Fp/QtdaDAOoBKiyNLh1JaB1NY6US5zc" + "qFks2seZPjXEiE6OIDXYra494mjNKGUobA4hqT2peKWXt/uBcuL1mjKOy8Qf" + "JxgEd0MOcGJO+1PFFZWGzLQ3RXJpYyBILiBFY2hpZG5hICh0ZXN0IGtleSBv" + "bmx5KSA8ZXJpY0Bib3VuY3ljYXN0bGUub3JnPohZBBMRAgAZBQJAEfI2BAsH" + "AwIDFQIDAxYCAQIeAQIXgAAKCRAOtk6iUOgnkDdnAKC/CfLWikSBdbngY6OK" + "5UN3+o7q1ACcDRqjT3yjBU3WmRUNlxBg3tSuljmwAgAAuQENBEAR8jgQBAC2" + "kr57iuOaV7Ga1xcU14MNbKcA0PVembRCjcVjei/3yVfT/fuCVtGHOmYLEBqH" + "bn5aaJ0P/6vMbLCHKuN61NZlts+LEctfwoya43RtcubqMc7eKw4k0JnnoYgB" + "ocLXOtloCb7jfubOsnfORvrUkK0+Ne6anRhFBYfaBmGU75cQgwADBQP/XxR2" + "qGHiwn+0YiMioRDRiIAxp6UiC/JQIri2AKSqAi0zeAMdrRsBN7kyzYVVpWwN" + "5u13gPdQ2HnJ7d4wLWAuizUdKIQxBG8VoCxkbipnwh2RR4xCXFDhJrJFQUm+" + "4nKx9JvAmZTBIlI5Wsi5qxst/9p5MgP3flXsNi1tRbTmRhqIRgQYEQIABgUC" + "QBHyOAAKCRAOtk6iUOgnkBStAJoCZBVM61B1LG2xip294MZecMtCwQCbBbsk" + "JVCXP0/Szm05GB+WN+MOCT2wAgAA"); byte[] testPrivKeyRing = Base64.decode( "lQHhBEAR8jYRBADNifuSopd20JOQ5x30ljIaY0M6927+vo09NeNxS3KqItba" + "nz9o5e2aqdT0W1xgdHYZmdElOHTTsugZxdXTEhghyxoo3KhVcNnTABQyrrvX" + "qouvmP2fEDEw0Vpyk+90BpyY9YlgeX/dEA8OfooRLCJde/iDTl7r9FT+mts8" + "g3azjwCgx+pOLD9LPBF5E4FhUOdXISJ0f4EEAKXSOi9nZzajpdhe8W2ZL9gc" + "BpzZi6AcrRZBHOEMqd69gtUxA4eD8xycUQ42yH89imEcwLz8XdJ98uHUxGJi" + "qp6hq4oakmw8GQfiL7yQIFgaM0dOAI9Afe3m84cEYZsoAFYpB4/s9pVMpPRH" + "NsVspU0qd3NHnSZ0QXs8L8DXGO1uBACjDUj+8GsfDCIP2QF3JC+nPUNa0Y5t" + "wKPKl+T8hX/0FBD7fnNeC6c9j5Ir/Fp/QtdaDAOoBKiyNLh1JaB1NY6US5zc" + "qFks2seZPjXEiE6OIDXYra494mjNKGUobA4hqT2peKWXt/uBcuL1mjKOy8Qf" + "JxgEd0MOcGJO+1PFFZWGzP4DAwLeUcsVxIC2s2Bb9ab2XD860TQ2BI2rMD/r" + "7/psx9WQ+Vz/aFAT3rXkEJ97nFeqEACgKmUCAEk9939EwLQ3RXJpYyBILiBF" + "Y2hpZG5hICh0ZXN0IGtleSBvbmx5KSA8ZXJpY0Bib3VuY3ljYXN0bGUub3Jn" + "PohZBBMRAgAZBQJAEfI2BAsHAwIDFQIDAxYCAQIeAQIXgAAKCRAOtk6iUOgn" + "kDdnAJ9Ala3OcwEV1DbK906CheYWo4zIQwCfUqUOLMp/zj6QAk02bbJAhV1r" + "sAewAgAAnQFYBEAR8jgQBAC2kr57iuOaV7Ga1xcU14MNbKcA0PVembRCjcVj" + "ei/3yVfT/fuCVtGHOmYLEBqHbn5aaJ0P/6vMbLCHKuN61NZlts+LEctfwoya" + "43RtcubqMc7eKw4k0JnnoYgBocLXOtloCb7jfubOsnfORvrUkK0+Ne6anRhF" + "BYfaBmGU75cQgwADBQP/XxR2qGHiwn+0YiMioRDRiIAxp6UiC/JQIri2AKSq" + "Ai0zeAMdrRsBN7kyzYVVpWwN5u13gPdQ2HnJ7d4wLWAuizUdKIQxBG8VoCxk" + "bipnwh2RR4xCXFDhJrJFQUm+4nKx9JvAmZTBIlI5Wsi5qxst/9p5MgP3flXs" + "Ni1tRbTmRhr+AwMC3lHLFcSAtrNg/EiWFLAnKNXH27zjwuhje8u2r+9iMTYs" + "GjbRxaxRY0GKRhttCwqe2BC0lHhzifdlEcc9yjIjuKfepG2fnnSIRgQYEQIA" + "BgUCQBHyOAAKCRAOtk6iUOgnkBStAJ9HFejVtVJ/A9LM/mDPe0ExhEXt/QCg" + "m/KM7hJ/JrfnLQl7IaZsdg1F6vCwAgAA"); byte[] encMessage = Base64.decode( "hQEOAynbo4lhNjcHEAP/dgCkMtPB6mIgjFvNiotjaoh4sAXf4vFNkSeehQ2c" + "r+IMt9CgIYodJI3FoJXxOuTcwesqTp5hRzgUBJS0adLDJwcNubFMy0M2tp5o" + "KTWpXulIiqyO6f5jI/oEDHPzFoYgBmR4x72l/YpMy8UoYGtNxNvR7LVOfqJv" + "uDY/71KMtPQEAIadOWpf1P5Td+61Zqn2VH2UV7H8eI6hGa6Lsy4sb9iZNE7f" + "c+spGJlgkiOt8TrQoq3iOK9UN9nHZLiCSIEGCzsEn3uNuorD++Qs065ij+Oy" + "36TKeuJ+38CfT7u47dEshHCPqWhBKEYrxZWHUJU/izw2Q1Yxd2XRxN+nafTL" + "X1fQ0lABQUASa18s0BkkEERIdcKQXVLEswWcGqWNv1ZghC7xO2VDBX4HrPjp" + "drjL63p2UHzJ7/4gPWGGtnqq1Xita/1mrImn7pzLThDWiT55vjw6Hw=="); byte[] signedAndEncMessage = Base64.decode( "hQEOAynbo4lhNjcHEAP+K20MVhzdX57hf/cU8TH0prP0VePr9mmeBedzqqMn" + "fp2p8Zb68zmcMlI/WiL5XMNLYRmCgEcXyWbKdP/XV9m9LDBe1CMAGrkCeGBy" + "je69IQQ5LS9vDPyEMF4iAAv/EqACjqHkizdY/a/FRx/t2ioXYdEC2jA6kS9C" + "McpsNz16DE8EAIk3uKn4bGo/+15TXkyFYzW5Cf71SfRoHNmU2zAI93zhjN+T" + "B7mGJwWXzsMkIO6FkMU5TCSrwZS3DBWCIaJ6SYoaawE/C/2j9D7bX1Jv8kum" + "4cq+eZM7z6JYs6xend+WAwittpUxbEiyC2AJb3fBSXPAbLqWd6J6xbZZ7GDK" + "r2Ca0pwBxwGhbMDyi2zpHLzw95H7Ah2wMcGU6kMLB+hzBSZ6mSTGFehqFQE3" + "2BnAj7MtnbghiefogacJ891jj8Y2ggJeKDuRz8j2iICaTOy+Y2rXnnJwfYzm" + "BMWcd2h1C5+UeBJ9CrrLniCCI8s5u8z36Rno3sfhBnXdRmWSxExXtocbg1Ht" + "dyiThf6TK3W29Yy/T6x45Ws5zOasaJdsFKM="); char[] pass = { 'h', 'e', 'l', 'l', 'o', ' ', 'w', 'o', 'r', 'l', 'd' }; public void performTest() throws Exception { try { PGPPublicKey pubKey; PGPUtil.setDefaultProvider("BC"); // // Read the public key // PGPObjectFactory pgpFact = new PGPObjectFactory(testPubKeyRing); PGPPublicKeyRing pgpPub = (PGPPublicKeyRing)pgpFact.nextObject(); pubKey = pgpPub.getPublicKey(); if (pubKey.getBitStrength() != 1024) { fail("failed - key strength reported incorrectly."); } // // Read the private key // PGPSecretKeyRing sKey = new PGPSecretKeyRing(testPrivKeyRing, new BcKeyFingerprintCalculator()); PGPPrivateKey pgpPrivKey = sKey.getSecretKey().extractPrivateKey(new BcPBESecretKeyDecryptorBuilder(new BcPGPDigestCalculatorProvider()).build(pass)); // // signature generation // String data = "hello world!"; ByteArrayOutputStream bOut = new ByteArrayOutputStream(); ByteArrayInputStream testIn = new ByteArrayInputStream(data.getBytes()); PGPSignatureGenerator sGen = new PGPSignatureGenerator(new BcPGPContentSignerBuilder(PGPPublicKey.DSA, PGPUtil.SHA1)); sGen.init(PGPSignature.BINARY_DOCUMENT, pgpPrivKey); PGPCompressedDataGenerator cGen = new PGPCompressedDataGenerator( PGPCompressedData.ZIP); BCPGOutputStream bcOut = new BCPGOutputStream( cGen.open(new UncloseableOutputStream(bOut))); sGen.generateOnePassVersion(false).encode(bcOut); PGPLiteralDataGenerator lGen = new PGPLiteralDataGenerator(); Date testDate = new Date((System.currentTimeMillis() / 1000) * 1000); OutputStream lOut = lGen.open( new UncloseableOutputStream(bcOut), PGPLiteralData.BINARY, "_CONSOLE", data.getBytes().length, testDate); int ch; while ((ch = testIn.read()) >= 0) { lOut.write(ch); sGen.update((byte)ch); } lGen.close(); sGen.generate().encode(bcOut); cGen.close(); // // verify generated signature // pgpFact = new PGPObjectFactory(bOut.toByteArray()); PGPCompressedData c1 = (PGPCompressedData)pgpFact.nextObject(); pgpFact = new PGPObjectFactory(c1.getDataStream()); PGPOnePassSignatureList p1 = (PGPOnePassSignatureList)pgpFact.nextObject(); PGPOnePassSignature ops = p1.get(0); PGPLiteralData p2 = (PGPLiteralData)pgpFact.nextObject(); if (!p2.getModificationTime().equals(testDate)) { fail("Modification time not preserved"); } InputStream dIn = p2.getInputStream(); ops.init(new BcPGPContentVerifierBuilderProvider(), pubKey); while ((ch = dIn.read()) >= 0) { ops.update((byte)ch); } PGPSignatureList p3 = (PGPSignatureList)pgpFact.nextObject(); if (!ops.verify(p3.get(0))) { fail("Failed generated signature check"); } // // test encryption // // // find a key suitable for encryption // long pgpKeyID = 0; AsymmetricKeyParameter pKey = null; BcPGPKeyConverter keyConverter = new BcPGPKeyConverter(); Iterator it = pgpPub.getPublicKeys(); while (it.hasNext()) { PGPPublicKey pgpKey = (PGPPublicKey)it.next(); if (pgpKey.getAlgorithm() == PGPPublicKey.ELGAMAL_ENCRYPT || pgpKey.getAlgorithm() == PGPPublicKey.ELGAMAL_GENERAL) { pKey = keyConverter.getPublicKey(pgpKey); pgpKeyID = pgpKey.getKeyID(); if (pgpKey.getBitStrength() != 1024) { fail("failed - key strength reported incorrectly."); } // // verify the key // } } AsymmetricBlockCipher c = new PKCS1Encoding(new ElGamalEngine()); c.init(true, pKey); byte[] in = "hello world".getBytes(); byte[] out = c.processBlock(in, 0, in.length); pgpPrivKey = sKey.getSecretKey(pgpKeyID).extractPrivateKey(new BcPBESecretKeyDecryptorBuilder(new BcPGPDigestCalculatorProvider()).build(pass)); c.init(false, keyConverter.getPrivateKey(pgpPrivKey)); out = c.processBlock(out, 0, out.length); if (!areEqual(in, out)) { fail("decryption failed."); } // // encrypted message // byte[] text = { (byte)'h', (byte)'e', (byte)'l', (byte)'l', (byte)'o', (byte)' ', (byte)'w', (byte)'o', (byte)'r', (byte)'l', (byte)'d', (byte)'!', (byte)'\n' }; PGPObjectFactory pgpF = new PGPObjectFactory(encMessage); PGPEncryptedDataList encList = (PGPEncryptedDataList)pgpF.nextObject(); PGPPublicKeyEncryptedData encP = (PGPPublicKeyEncryptedData)encList.get(0); InputStream clear = encP.getDataStream(new BcPublicKeyDataDecryptorFactory(pgpPrivKey)); pgpFact = new PGPObjectFactory(clear); c1 = (PGPCompressedData)pgpFact.nextObject(); pgpFact = new PGPObjectFactory(c1.getDataStream()); PGPLiteralData ld = (PGPLiteralData)pgpFact.nextObject(); bOut = new ByteArrayOutputStream(); if (!ld.getFileName().equals("test.txt")) { throw new RuntimeException("wrong filename in packet"); } InputStream inLd = ld.getDataStream(); while ((ch = inLd.read()) >= 0) { bOut.write(ch); } if (!areEqual(bOut.toByteArray(), text)) { fail("wrong plain text in decrypted packet"); } // // signed and encrypted message // pgpF = new PGPObjectFactory(signedAndEncMessage); encList = (PGPEncryptedDataList)pgpF.nextObject(); encP = (PGPPublicKeyEncryptedData)encList.get(0); clear = encP.getDataStream(new BcPublicKeyDataDecryptorFactory(pgpPrivKey)); pgpFact = new PGPObjectFactory(clear); c1 = (PGPCompressedData)pgpFact.nextObject(); pgpFact = new PGPObjectFactory(c1.getDataStream()); p1 = (PGPOnePassSignatureList)pgpFact.nextObject(); ops = p1.get(0); ld = (PGPLiteralData)pgpFact.nextObject(); bOut = new ByteArrayOutputStream(); if (!ld.getFileName().equals("test.txt")) { throw new RuntimeException("wrong filename in packet"); } inLd = ld.getDataStream(); // // note: we use the DSA public key here. // ops.init(new BcPGPContentVerifierBuilderProvider(), pgpPub.getPublicKey()); while ((ch = inLd.read()) >= 0) { ops.update((byte)ch); bOut.write(ch); } p3 = (PGPSignatureList)pgpFact.nextObject(); if (!ops.verify(p3.get(0))) { fail("Failed signature check"); } if (!areEqual(bOut.toByteArray(), text)) { fail("wrong plain text in decrypted packet"); } // // encrypt // ByteArrayOutputStream cbOut = new ByteArrayOutputStream(); PGPEncryptedDataGenerator cPk = new PGPEncryptedDataGenerator(new BcPGPDataEncryptorBuilder(SymmetricKeyAlgorithmTags.TRIPLE_DES).setSecureRandom(new SecureRandom())); PGPPublicKey puK = sKey.getSecretKey(pgpKeyID).getPublicKey(); cPk.addMethod(new BcPublicKeyKeyEncryptionMethodGenerator(puK)); OutputStream cOut = cPk.open(new UncloseableOutputStream(cbOut), bOut.toByteArray().length); cOut.write(text); cOut.close(); pgpF = new PGPObjectFactory(cbOut.toByteArray()); encList = (PGPEncryptedDataList)pgpF.nextObject(); encP = (PGPPublicKeyEncryptedData)encList.get(0); pgpPrivKey = sKey.getSecretKey(pgpKeyID).extractPrivateKey(new BcPBESecretKeyDecryptorBuilder(new BcPGPDigestCalculatorProvider()).build(pass)); clear = encP.getDataStream(new BcPublicKeyDataDecryptorFactory(pgpPrivKey)); bOut.reset(); while ((ch = clear.read()) >= 0) { bOut.write(ch); } out = bOut.toByteArray(); if (!areEqual(out, text)) { fail("wrong plain text in generated packet"); } // // use of PGPKeyPair // BigInteger g = new BigInteger("153d5d6172adb43045b68ae8e1de1070b6137005686d29d3d73a7749199681ee5b212c9b96bfdcfa5b20cd5e3fd2044895d609cf9b410b7a0f12ca1cb9a428cc", 16); BigInteger p = new BigInteger("9494fec095f3b85ee286542b3836fc81a5dd0a0349b4c239dd38744d488cf8e31db8bcb7d33b41abb9e5a33cca9144b1cef332c94bf0573bf047a3aca98cdf3b", 16); KeyPairGenerator kpg = KeyPairGenerator.getInstance("ElGamal", "BC"); ElGamalParameterSpec elParams = new ElGamalParameterSpec(p, g); kpg.initialize(512); KeyPair kp = kpg.generateKeyPair(); PGPKeyPair pgpKp = new PGPKeyPair(PGPPublicKey.ELGAMAL_GENERAL , kp.getPublic(), kp.getPrivate(), new Date()); PGPPublicKey k1 = pgpKp.getPublicKey(); PGPPrivateKey k2 = pgpKp.getPrivateKey(); // Test bug with ElGamal P size != 0 mod 8 (don't use these sizes at home!) SecureRandom random = new SecureRandom(); for (int pSize = 257; pSize < 264; ++pSize) { // Generate some parameters of the given size AlgorithmParameterGenerator a = AlgorithmParameterGenerator.getInstance("ElGamal", "BC"); a.init(pSize, new SecureRandom()); AlgorithmParameters params = a.generateParameters(); DHParameterSpec elP = (DHParameterSpec)params.getParameterSpec(DHParameterSpec.class); KeyPairGenerator keyGen = KeyPairGenerator.getInstance("ElGamal", "BC"); keyGen.initialize(512); // Run a short encrypt/decrypt test with random key for the given parameters kp = keyGen.generateKeyPair(); PGPKeyPair elGamalKeyPair = new PGPKeyPair( PublicKeyAlgorithmTags.ELGAMAL_GENERAL, kp, new Date()); cPk = new PGPEncryptedDataGenerator(new BcPGPDataEncryptorBuilder(SymmetricKeyAlgorithmTags.CAST5).setSecureRandom(random)); puK = elGamalKeyPair.getPublicKey(); cPk.addMethod(new BcPublicKeyKeyEncryptionMethodGenerator(puK)); cbOut = new ByteArrayOutputStream(); cOut = cPk.open(cbOut, text.length); cOut.write(text); cOut.close(); pgpF = new PGPObjectFactory(cbOut.toByteArray()); encList = (PGPEncryptedDataList)pgpF.nextObject(); encP = (PGPPublicKeyEncryptedData)encList.get(0); pgpPrivKey = elGamalKeyPair.getPrivateKey(); // Note: This is where an exception would be expected if the P size causes problems clear = encP.getDataStream(new BcPublicKeyDataDecryptorFactory(pgpPrivKey)); ByteArrayOutputStream dec = new ByteArrayOutputStream(); int b; while ((b = clear.read()) >= 0) { dec.write(b); } byte[] decText = dec.toByteArray(); if (!areEqual(text, decText)) { fail("decrypted message incorrect"); } } // check sub key encoding it = pgpPub.getPublicKeys(); while (it.hasNext()) { PGPPublicKey pgpKey = (PGPPublicKey)it.next(); if (!pgpKey.isMasterKey()) { byte[] kEnc = pgpKey.getEncoded(); PGPObjectFactory objF = new PGPObjectFactory(kEnc); PGPPublicKey k = (PGPPublicKey)objF.nextObject(); pKey = keyConverter.getPublicKey(k); pgpKeyID = k.getKeyID(); if (k.getBitStrength() != 1024) { fail("failed - key strength reported incorrectly."); } if (objF.nextObject() != null) { fail("failed - stream not fully parsed."); } } } } catch (PGPException e) { fail("exception: " + e.getMessage(), e.getUnderlyingException()); } } public String getName() { return "PGPDSAElGamalTest"; } public static void main( String[] args) { Security.addProvider(new BouncyCastleProvider()); runTest(new BcPGPDSAElGamalTest()); } } bouncycastle-1.49.orig/jdk1.1/org/bouncycastle/openpgp/test/PGPDSAElGamalTest.java0000644000175000017500000004155611705660263027257 0ustar ebourgebourgpackage org.bouncycastle.openpgp.test; import java.io.ByteArrayInputStream; import java.io.ByteArrayOutputStream; import java.io.InputStream; import java.io.OutputStream; import java.math.BigInteger; import java.security.KeyFactory; import java.security.KeyPair; import java.security.KeyPairGenerator; import java.security.PrivateKey; import java.security.PublicKey; import java.security.SecureRandom; import java.security.Security; import java.util.Date; import java.util.Iterator; import javax.crypto.Cipher; import org.bouncycastle.bcpg.BCPGOutputStream; import org.bouncycastle.bcpg.SymmetricKeyAlgorithmTags; import org.bouncycastle.jce.provider.BouncyCastleProvider; import org.bouncycastle.jce.spec.ElGamalParameterSpec; import org.bouncycastle.openpgp.PGPCompressedData; import org.bouncycastle.openpgp.PGPEncryptedDataGenerator; import org.bouncycastle.openpgp.PGPEncryptedDataList; import org.bouncycastle.openpgp.PGPKeyPair; import org.bouncycastle.openpgp.PGPPublicKeyEncryptedData; import org.bouncycastle.openpgp.PGPSignature; import org.bouncycastle.openpgp.PGPException; import org.bouncycastle.openpgp.PGPCompressedDataGenerator; import org.bouncycastle.openpgp.PGPLiteralData; import org.bouncycastle.openpgp.PGPLiteralDataGenerator; import org.bouncycastle.openpgp.PGPObjectFactory; import org.bouncycastle.openpgp.PGPOnePassSignature; import org.bouncycastle.openpgp.PGPOnePassSignatureList; import org.bouncycastle.openpgp.PGPPrivateKey; import org.bouncycastle.openpgp.PGPPublicKey; import org.bouncycastle.openpgp.PGPPublicKeyRing; import org.bouncycastle.openpgp.PGPSecretKeyRing; import org.bouncycastle.openpgp.PGPSignatureGenerator; import org.bouncycastle.openpgp.PGPSignatureList; import org.bouncycastle.openpgp.PGPUtil; import org.bouncycastle.util.encoders.Base64; import org.bouncycastle.util.test.SimpleTestResult; import org.bouncycastle.util.test.Test; import org.bouncycastle.util.test.TestResult; public class PGPDSAElGamalTest implements Test { byte[] testPubKeyRing = Base64.decode( "mQGiBEAR8jYRBADNifuSopd20JOQ5x30ljIaY0M6927+vo09NeNxS3KqItba" + "nz9o5e2aqdT0W1xgdHYZmdElOHTTsugZxdXTEhghyxoo3KhVcNnTABQyrrvX" + "qouvmP2fEDEw0Vpyk+90BpyY9YlgeX/dEA8OfooRLCJde/iDTl7r9FT+mts8" + "g3azjwCgx+pOLD9LPBF5E4FhUOdXISJ0f4EEAKXSOi9nZzajpdhe8W2ZL9gc" + "BpzZi6AcrRZBHOEMqd69gtUxA4eD8xycUQ42yH89imEcwLz8XdJ98uHUxGJi" + "qp6hq4oakmw8GQfiL7yQIFgaM0dOAI9Afe3m84cEYZsoAFYpB4/s9pVMpPRH" + "NsVspU0qd3NHnSZ0QXs8L8DXGO1uBACjDUj+8GsfDCIP2QF3JC+nPUNa0Y5t" + "wKPKl+T8hX/0FBD7fnNeC6c9j5Ir/Fp/QtdaDAOoBKiyNLh1JaB1NY6US5zc" + "qFks2seZPjXEiE6OIDXYra494mjNKGUobA4hqT2peKWXt/uBcuL1mjKOy8Qf" + "JxgEd0MOcGJO+1PFFZWGzLQ3RXJpYyBILiBFY2hpZG5hICh0ZXN0IGtleSBv" + "bmx5KSA8ZXJpY0Bib3VuY3ljYXN0bGUub3JnPohZBBMRAgAZBQJAEfI2BAsH" + "AwIDFQIDAxYCAQIeAQIXgAAKCRAOtk6iUOgnkDdnAKC/CfLWikSBdbngY6OK" + "5UN3+o7q1ACcDRqjT3yjBU3WmRUNlxBg3tSuljmwAgAAuQENBEAR8jgQBAC2" + "kr57iuOaV7Ga1xcU14MNbKcA0PVembRCjcVjei/3yVfT/fuCVtGHOmYLEBqH" + "bn5aaJ0P/6vMbLCHKuN61NZlts+LEctfwoya43RtcubqMc7eKw4k0JnnoYgB" + "ocLXOtloCb7jfubOsnfORvrUkK0+Ne6anRhFBYfaBmGU75cQgwADBQP/XxR2" + "qGHiwn+0YiMioRDRiIAxp6UiC/JQIri2AKSqAi0zeAMdrRsBN7kyzYVVpWwN" + "5u13gPdQ2HnJ7d4wLWAuizUdKIQxBG8VoCxkbipnwh2RR4xCXFDhJrJFQUm+" + "4nKx9JvAmZTBIlI5Wsi5qxst/9p5MgP3flXsNi1tRbTmRhqIRgQYEQIABgUC" + "QBHyOAAKCRAOtk6iUOgnkBStAJoCZBVM61B1LG2xip294MZecMtCwQCbBbsk" + "JVCXP0/Szm05GB+WN+MOCT2wAgAA"); byte[] testPrivKeyRing = Base64.decode( "lQHhBEAR8jYRBADNifuSopd20JOQ5x30ljIaY0M6927+vo09NeNxS3KqItba" + "nz9o5e2aqdT0W1xgdHYZmdElOHTTsugZxdXTEhghyxoo3KhVcNnTABQyrrvX" + "qouvmP2fEDEw0Vpyk+90BpyY9YlgeX/dEA8OfooRLCJde/iDTl7r9FT+mts8" + "g3azjwCgx+pOLD9LPBF5E4FhUOdXISJ0f4EEAKXSOi9nZzajpdhe8W2ZL9gc" + "BpzZi6AcrRZBHOEMqd69gtUxA4eD8xycUQ42yH89imEcwLz8XdJ98uHUxGJi" + "qp6hq4oakmw8GQfiL7yQIFgaM0dOAI9Afe3m84cEYZsoAFYpB4/s9pVMpPRH" + "NsVspU0qd3NHnSZ0QXs8L8DXGO1uBACjDUj+8GsfDCIP2QF3JC+nPUNa0Y5t" + "wKPKl+T8hX/0FBD7fnNeC6c9j5Ir/Fp/QtdaDAOoBKiyNLh1JaB1NY6US5zc" + "qFks2seZPjXEiE6OIDXYra494mjNKGUobA4hqT2peKWXt/uBcuL1mjKOy8Qf" + "JxgEd0MOcGJO+1PFFZWGzP4DAwLeUcsVxIC2s2Bb9ab2XD860TQ2BI2rMD/r" + "7/psx9WQ+Vz/aFAT3rXkEJ97nFeqEACgKmUCAEk9939EwLQ3RXJpYyBILiBF" + "Y2hpZG5hICh0ZXN0IGtleSBvbmx5KSA8ZXJpY0Bib3VuY3ljYXN0bGUub3Jn" + "PohZBBMRAgAZBQJAEfI2BAsHAwIDFQIDAxYCAQIeAQIXgAAKCRAOtk6iUOgn" + "kDdnAJ9Ala3OcwEV1DbK906CheYWo4zIQwCfUqUOLMp/zj6QAk02bbJAhV1r" + "sAewAgAAnQFYBEAR8jgQBAC2kr57iuOaV7Ga1xcU14MNbKcA0PVembRCjcVj" + "ei/3yVfT/fuCVtGHOmYLEBqHbn5aaJ0P/6vMbLCHKuN61NZlts+LEctfwoya" + "43RtcubqMc7eKw4k0JnnoYgBocLXOtloCb7jfubOsnfORvrUkK0+Ne6anRhF" + "BYfaBmGU75cQgwADBQP/XxR2qGHiwn+0YiMioRDRiIAxp6UiC/JQIri2AKSq" + "Ai0zeAMdrRsBN7kyzYVVpWwN5u13gPdQ2HnJ7d4wLWAuizUdKIQxBG8VoCxk" + "bipnwh2RR4xCXFDhJrJFQUm+4nKx9JvAmZTBIlI5Wsi5qxst/9p5MgP3flXs" + "Ni1tRbTmRhr+AwMC3lHLFcSAtrNg/EiWFLAnKNXH27zjwuhje8u2r+9iMTYs" + "GjbRxaxRY0GKRhttCwqe2BC0lHhzifdlEcc9yjIjuKfepG2fnnSIRgQYEQIA" + "BgUCQBHyOAAKCRAOtk6iUOgnkBStAJ9HFejVtVJ/A9LM/mDPe0ExhEXt/QCg" + "m/KM7hJ/JrfnLQl7IaZsdg1F6vCwAgAA"); byte[] encMessage = Base64.decode( "hQEOAynbo4lhNjcHEAP/dgCkMtPB6mIgjFvNiotjaoh4sAXf4vFNkSeehQ2c" + "r+IMt9CgIYodJI3FoJXxOuTcwesqTp5hRzgUBJS0adLDJwcNubFMy0M2tp5o" + "KTWpXulIiqyO6f5jI/oEDHPzFoYgBmR4x72l/YpMy8UoYGtNxNvR7LVOfqJv" + "uDY/71KMtPQEAIadOWpf1P5Td+61Zqn2VH2UV7H8eI6hGa6Lsy4sb9iZNE7f" + "c+spGJlgkiOt8TrQoq3iOK9UN9nHZLiCSIEGCzsEn3uNuorD++Qs065ij+Oy" + "36TKeuJ+38CfT7u47dEshHCPqWhBKEYrxZWHUJU/izw2Q1Yxd2XRxN+nafTL" + "X1fQ0lABQUASa18s0BkkEERIdcKQXVLEswWcGqWNv1ZghC7xO2VDBX4HrPjp" + "drjL63p2UHzJ7/4gPWGGtnqq1Xita/1mrImn7pzLThDWiT55vjw6Hw=="); byte[] signedAndEncMessage = Base64.decode( "hQEOAynbo4lhNjcHEAP+K20MVhzdX57hf/cU8TH0prP0VePr9mmeBedzqqMn" + "fp2p8Zb68zmcMlI/WiL5XMNLYRmCgEcXyWbKdP/XV9m9LDBe1CMAGrkCeGBy" + "je69IQQ5LS9vDPyEMF4iAAv/EqACjqHkizdY/a/FRx/t2ioXYdEC2jA6kS9C" + "McpsNz16DE8EAIk3uKn4bGo/+15TXkyFYzW5Cf71SfRoHNmU2zAI93zhjN+T" + "B7mGJwWXzsMkIO6FkMU5TCSrwZS3DBWCIaJ6SYoaawE/C/2j9D7bX1Jv8kum" + "4cq+eZM7z6JYs6xend+WAwittpUxbEiyC2AJb3fBSXPAbLqWd6J6xbZZ7GDK" + "r2Ca0pwBxwGhbMDyi2zpHLzw95H7Ah2wMcGU6kMLB+hzBSZ6mSTGFehqFQE3" + "2BnAj7MtnbghiefogacJ891jj8Y2ggJeKDuRz8j2iICaTOy+Y2rXnnJwfYzm" + "BMWcd2h1C5+UeBJ9CrrLniCCI8s5u8z36Rno3sfhBnXdRmWSxExXtocbg1Ht" + "dyiThf6TK3W29Yy/T6x45Ws5zOasaJdsFKM="); char[] pass = { 'h', 'e', 'l', 'l', 'o', ' ', 'w', 'o', 'r', 'l', 'd' }; private boolean notEqual( byte[] b1, byte[] b2) { if (b1.length != b2.length) { return true; } for (int i = 0; i != b2.length; i++) { if (b1[i] != b2[i]) { return true; } } return false; } public TestResult perform() { try { String file = null; KeyFactory fact = KeyFactory.getInstance("DSA", "BC"); PGPPublicKey pubKey = null; PrivateKey privKey = null; PGPUtil.setDefaultProvider("BC"); // // Read the public key // PGPObjectFactory pgpFact = new PGPObjectFactory(testPubKeyRing); PGPPublicKeyRing pgpPub = (PGPPublicKeyRing)pgpFact.nextObject(); pubKey = pgpPub.getPublicKey(); // // Read the private key // PGPSecretKeyRing sKey = new PGPSecretKeyRing(testPrivKeyRing); PGPPrivateKey pgpPrivKey = sKey.getSecretKey().extractPrivateKey(pass, "BC"); // // signature generation // String data = "hello world!"; ByteArrayOutputStream bOut = new ByteArrayOutputStream(); ByteArrayInputStream testIn = new ByteArrayInputStream(data.getBytes()); PGPSignatureGenerator sGen = new PGPSignatureGenerator(PGPPublicKey.DSA, PGPUtil.SHA1, "BC"); sGen.initSign(PGPSignature.BINARY_DOCUMENT, pgpPrivKey); PGPCompressedDataGenerator cGen = new PGPCompressedDataGenerator( PGPCompressedData.ZIP); BCPGOutputStream bcOut = new BCPGOutputStream(cGen.open(bOut)); sGen.generateOnePassVersion(false).encode(bcOut); PGPLiteralDataGenerator lGen = new PGPLiteralDataGenerator(); OutputStream lOut = lGen.open(bcOut, PGPLiteralData.BINARY, "_CONSOLE", data.getBytes().length, new Date()); int ch; while ((ch = testIn.read()) >= 0) { lOut.write(ch); sGen.update((byte)ch); } sGen.generate().encode(bcOut); lGen.close(); cGen.close(); // // verify generated signature // pgpFact = new PGPObjectFactory(bOut.toByteArray()); PGPCompressedData c1 = (PGPCompressedData)pgpFact.nextObject(); pgpFact = new PGPObjectFactory(c1.getDataStream()); PGPOnePassSignatureList p1 = (PGPOnePassSignatureList)pgpFact.nextObject(); PGPOnePassSignature ops = p1.get(0); PGPLiteralData p2 = (PGPLiteralData)pgpFact.nextObject(); InputStream dIn = p2.getInputStream(); ops.initVerify(pubKey, "BC"); while ((ch = dIn.read()) >= 0) { ops.update((byte)ch); } PGPSignatureList p3 = (PGPSignatureList)pgpFact.nextObject(); if (!ops.verify(p3.get(0))) { return new SimpleTestResult(false, getName() + ": Failed generated signature check"); } // // test encryption // // // find a key sutiable for encryption // long pgpKeyID = 0; PublicKey pKey = null; Iterator it = pgpPub.getPublicKeys(); while (it.hasNext()) { PGPPublicKey pgpKey = (PGPPublicKey)it.next(); if (pgpKey.getAlgorithm() == PGPPublicKey.ELGAMAL_ENCRYPT || pgpKey.getAlgorithm() == PGPPublicKey.ELGAMAL_GENERAL) { pKey = pgpKey.getKey("BC"); pgpKeyID = pgpKey.getKeyID(); // // verify the key // } } Cipher c = Cipher.getInstance("ElGamal/None/PKCS1Padding", "BC"); c.init(Cipher.ENCRYPT_MODE, pKey); byte[] in = "hello world".getBytes(); byte[] out = c.doFinal(in); pgpPrivKey = sKey.getSecretKey(pgpKeyID).extractPrivateKey(pass, "BC"); c.init(Cipher.DECRYPT_MODE, pgpPrivKey.getKey()); out = c.doFinal(out); if (notEqual(in, out)) { return new SimpleTestResult(false, getName() + ": decryption failed."); } // // encrypted message // byte[] text = { (byte)'h', (byte)'e', (byte)'l', (byte)'l', (byte)'o', (byte)' ', (byte)'w', (byte)'o', (byte)'r', (byte)'l', (byte)'d', (byte)'!', (byte)'\n' }; PGPObjectFactory pgpF = new PGPObjectFactory(encMessage); PGPEncryptedDataList encList = (PGPEncryptedDataList)pgpF.nextObject(); PGPPublicKeyEncryptedData encP = (PGPPublicKeyEncryptedData)encList.get(0); InputStream clear = encP.getDataStream(pgpPrivKey, "BC"); pgpFact = new PGPObjectFactory(clear); c1 = (PGPCompressedData)pgpFact.nextObject(); pgpFact = new PGPObjectFactory(c1.getDataStream()); PGPLiteralData ld = (PGPLiteralData)pgpFact.nextObject(); bOut = new ByteArrayOutputStream(); if (!ld.getFileName().equals("test.txt")) { throw new RuntimeException("wrong filename in packet"); } InputStream inLd = ld.getDataStream(); while ((ch = inLd.read()) >= 0) { bOut.write(ch); } if (notEqual(bOut.toByteArray(), text)) { return new SimpleTestResult(false, getName() + ": wrong plain text in decrypted packet"); } // // signed and encrypted message // pgpF = new PGPObjectFactory(signedAndEncMessage); encList = (PGPEncryptedDataList)pgpF.nextObject(); encP = (PGPPublicKeyEncryptedData)encList.get(0); clear = encP.getDataStream(pgpPrivKey, "BC"); pgpFact = new PGPObjectFactory(clear); c1 = (PGPCompressedData)pgpFact.nextObject(); pgpFact = new PGPObjectFactory(c1.getDataStream()); p1 = (PGPOnePassSignatureList)pgpFact.nextObject(); ops = p1.get(0); ld = (PGPLiteralData)pgpFact.nextObject(); bOut = new ByteArrayOutputStream(); if (!ld.getFileName().equals("test.txt")) { throw new RuntimeException("wrong filename in packet"); } inLd = ld.getDataStream(); // // note: we use the DSA public key here. // ops.initVerify(pgpPub.getPublicKey(), "BC"); while ((ch = inLd.read()) >= 0) { ops.update((byte)ch); bOut.write(ch); } p3 = (PGPSignatureList)pgpFact.nextObject(); if (!ops.verify(p3.get(0))) { return new SimpleTestResult(false, getName() + ": Failed signature check"); } if (notEqual(bOut.toByteArray(), text)) { return new SimpleTestResult(false, getName() + ": wrong plain text in decrypted packet"); } // // encrypt // ByteArrayOutputStream cbOut = new ByteArrayOutputStream(); PGPEncryptedDataGenerator cPk = new PGPEncryptedDataGenerator(SymmetricKeyAlgorithmTags.TRIPLE_DES, new SecureRandom(), "BC"); PGPPublicKey puK = sKey.getSecretKey(pgpKeyID).getPublicKey(); cPk.addMethod(puK); OutputStream cOut = cPk.open(cbOut, bOut.toByteArray().length); cOut.write(text); cOut.close(); pgpF = new PGPObjectFactory(cbOut.toByteArray()); encList = (PGPEncryptedDataList)pgpF.nextObject(); encP = (PGPPublicKeyEncryptedData)encList.get(0); pgpPrivKey = sKey.getSecretKey(pgpKeyID).extractPrivateKey(pass, "BC"); clear = encP.getDataStream(pgpPrivKey, "BC"); bOut.reset(); while ((ch = clear.read()) >= 0) { bOut.write(ch); } out = bOut.toByteArray(); if (notEqual(out, text)) { return new SimpleTestResult(false, getName() + ": wrong plain text in generated packet"); } return new SimpleTestResult(true, getName() + ": Okay"); } catch (Exception e) { e.printStackTrace(); if (e instanceof PGPException) { ((PGPException)e).getUnderlyingException().printStackTrace(); } return new SimpleTestResult(false, getName() + ": exception - " + e.toString()); } } public String getName() { return "PGPDSAElGamalTest"; } public static void main(String[] args) { Security.addProvider(new BouncyCastleProvider()); Test test = new PGPDSAElGamalTest(); TestResult result = test.perform(); System.out.println(result.toString()); if (result.getException() != null) { result.getException().printStackTrace(); } } } bouncycastle-1.49.orig/jdk1.1/org/bouncycastle/openpgp/test/BcPGPKeyRingTest.java0000644000175000017500000034130712105031243027220 0ustar ebourgebourgpackage org.bouncycastle.openpgp.test; import java.io.ByteArrayInputStream; import java.math.BigInteger; import java.security.KeyPair; import java.security.KeyPairGenerator; import java.security.SecureRandom; import java.security.Security; import java.util.Date; import java.util.Iterator; import org.bouncycastle.jce.provider.BouncyCastleProvider; import org.bouncycastle.jce.spec.ElGamalParameterSpec; import org.bouncycastle.openpgp.PGPEncryptedData; import org.bouncycastle.openpgp.PGPException; import org.bouncycastle.openpgp.PGPKeyPair; import org.bouncycastle.openpgp.PGPKeyRingGenerator; import org.bouncycastle.openpgp.PGPPrivateKey; import org.bouncycastle.openpgp.PGPPublicKey; import org.bouncycastle.openpgp.PGPPublicKeyRing; import org.bouncycastle.openpgp.PGPPublicKeyRingCollection; import org.bouncycastle.openpgp.PGPSecretKey; import org.bouncycastle.openpgp.PGPSecretKeyRing; import org.bouncycastle.openpgp.PGPSecretKeyRingCollection; import org.bouncycastle.openpgp.PGPSignature; import org.bouncycastle.openpgp.operator.bc.BcKeyFingerprintCalculator; import org.bouncycastle.openpgp.operator.bc.BcPBESecretKeyDecryptorBuilder; import org.bouncycastle.openpgp.operator.bc.BcPGPContentVerifierBuilderProvider; import org.bouncycastle.openpgp.operator.bc.BcPGPDigestCalculatorProvider; import org.bouncycastle.util.encoders.Base64; import org.bouncycastle.util.encoders.Hex; import org.bouncycastle.util.test.SimpleTest; public class BcPGPKeyRingTest extends SimpleTest { byte[] pub1 = Base64.decode( "mQGiBEA83v0RBADzKVLVCnpWQxX0LCsevw/3OLs0H7MOcLBQ4wMO9sYmzGYn" + "xpVj+4e4PiCP7QBayWyy4lugL6Lnw7tESvq3A4v3fefcxaCTkJrryiKn4+Cg" + "y5rIBbrSKNtCEhVi7xjtdnDjP5kFKgHYjVOeIKn4Cz/yzPG3qz75kDknldLf" + "yHxp2wCgwW1vAE5EnZU4/UmY7l8kTNkMltMEAJP4/uY4zcRwLI9Q2raPqAOJ" + "TYLd7h+3k/BxI0gIw96niQ3KmUZDlobbWBI+VHM6H99vcttKU3BgevNf8M9G" + "x/AbtW3SS4De64wNSU3189XDG8vXf0vuyW/K6Pcrb8exJWY0E1zZQ1WXT0gZ" + "W0kH3g5ro//Tusuil9q2lVLF2ovJA/0W+57bPzi318dWeNs0tTq6Njbc/GTG" + "FUAVJ8Ss5v2u6h7gyJ1DB334ExF/UdqZGldp0ugkEXaSwBa2R7d3HBgaYcoP" + "Ck1TrovZzEY8gm7JNVy7GW6mdOZuDOHTxyADEEP2JPxh6eRcZbzhGuJuYIif" + "IIeLOTI5Dc4XKeV32a+bWrQidGVzdCAoVGVzdCBrZXkpIDx0ZXN0QHViaWNh" + "bGwuY29tPohkBBMRAgAkBQJAPN79AhsDBQkB4TOABgsJCAcDAgMVAgMDFgIB" + "Ah4BAheAAAoJEJh8Njfhe8KmGDcAoJWr8xgPr75y/Cp1kKn12oCCOb8zAJ4p" + "xSvk4K6tB2jYbdeSrmoWBZLdMLACAAC5AQ0EQDzfARAEAJeUAPvUzJJbKcc5" + "5Iyb13+Gfb8xBWE3HinQzhGr1v6A1aIZbRj47UPAD/tQxwz8VAwJySx82ggN" + "LxCk4jW9YtTL3uZqfczsJngV25GoIN10f4/j2BVqZAaX3q79a3eMiql1T0oE" + "AGmD7tO1LkTvWfm3VvA0+t8/6ZeRLEiIqAOHAAQNBACD0mVMlAUgd7REYy/1" + "mL99Zlu9XU0uKyUex99sJNrcx1aj8rIiZtWaHz6CN1XptdwpDeSYEOFZ0PSu" + "qH9ByM3OfjU/ya0//xdvhwYXupn6P1Kep85efMBA9jUv/DeBOzRWMFG6sC6y" + "k8NGG7Swea7EHKeQI40G3jgO/+xANtMyTIhPBBgRAgAPBQJAPN8BAhsMBQkB" + "4TOAAAoJEJh8Njfhe8KmG7kAn00mTPGJCWqmskmzgdzeky5fWd7rAKCNCp3u" + "ZJhfg0htdgAfIy8ppm05vLACAAA="); byte[] sec1 = Base64.decode( "lQHhBEA83v0RBADzKVLVCnpWQxX0LCsevw/3OLs0H7MOcLBQ4wMO9sYmzGYn" + "xpVj+4e4PiCP7QBayWyy4lugL6Lnw7tESvq3A4v3fefcxaCTkJrryiKn4+Cg" + "y5rIBbrSKNtCEhVi7xjtdnDjP5kFKgHYjVOeIKn4Cz/yzPG3qz75kDknldLf" + "yHxp2wCgwW1vAE5EnZU4/UmY7l8kTNkMltMEAJP4/uY4zcRwLI9Q2raPqAOJ" + "TYLd7h+3k/BxI0gIw96niQ3KmUZDlobbWBI+VHM6H99vcttKU3BgevNf8M9G" + "x/AbtW3SS4De64wNSU3189XDG8vXf0vuyW/K6Pcrb8exJWY0E1zZQ1WXT0gZ" + "W0kH3g5ro//Tusuil9q2lVLF2ovJA/0W+57bPzi318dWeNs0tTq6Njbc/GTG" + "FUAVJ8Ss5v2u6h7gyJ1DB334ExF/UdqZGldp0ugkEXaSwBa2R7d3HBgaYcoP" + "Ck1TrovZzEY8gm7JNVy7GW6mdOZuDOHTxyADEEP2JPxh6eRcZbzhGuJuYIif" + "IIeLOTI5Dc4XKeV32a+bWv4CAwJ5KgazImo+sGBfMhDiBcBTqyDGhKHNgHic" + "0Pky9FeRvfXTc2AO+jGmFPjcs8BnTWuDD0/jkQnRZpp1TrQidGVzdCAoVGVz" + "dCBrZXkpIDx0ZXN0QHViaWNhbGwuY29tPohkBBMRAgAkBQJAPN79AhsDBQkB" + "4TOABgsJCAcDAgMVAgMDFgIBAh4BAheAAAoJEJh8Njfhe8KmGDcAn3XeXDMg" + "BZgrZzFWU2IKtA/5LG2TAJ0Vf/jjyq0jZNZfGfoqGTvD2MAl0rACAACdAVgE" + "QDzfARAEAJeUAPvUzJJbKcc55Iyb13+Gfb8xBWE3HinQzhGr1v6A1aIZbRj4" + "7UPAD/tQxwz8VAwJySx82ggNLxCk4jW9YtTL3uZqfczsJngV25GoIN10f4/j" + "2BVqZAaX3q79a3eMiql1T0oEAGmD7tO1LkTvWfm3VvA0+t8/6ZeRLEiIqAOH" + "AAQNBACD0mVMlAUgd7REYy/1mL99Zlu9XU0uKyUex99sJNrcx1aj8rIiZtWa" + "Hz6CN1XptdwpDeSYEOFZ0PSuqH9ByM3OfjU/ya0//xdvhwYXupn6P1Kep85e" + "fMBA9jUv/DeBOzRWMFG6sC6yk8NGG7Swea7EHKeQI40G3jgO/+xANtMyTP4C" + "AwJ5KgazImo+sGBl2C7CFuI+5KM4ZhbtVie7l+OiTpr5JW2z5VgnV3EX9p04" + "LcGKfQvD65+ELwli6yh8B2zGcipqTaYk3QoYNIhPBBgRAgAPBQJAPN8BAhsM" + "BQkB4TOAAAoJEJh8Njfhe8KmG7kAniuRkaFFv1pdCBN8JJXpcorHmyouAJ9L" + "xxmusffR6OI7WgD3XZ0AL8zUC7ACAAA="); char[] pass1 = "qwertzuiop".toCharArray(); byte[] pub2 = Base64.decode( "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"); byte[] sec2 = Base64.decode( "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" + "Nifs+ljmsAFn"); char[] sec2pass1 = "sandhya".toCharArray(); char[] sec2pass2 = "psai".toCharArray(); byte[] pub3 = Base64.decode( "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" + "n3FaE6UZE9GMDmCIAjhI+0X9aH6CsAIAAw=="); byte[] sec3 = Base64.decode( "lQHhBEB9BH0RBACtYQtE7tna6hgGyGLpq+ds3r2cLC0ISn5dNw7tm9vwiNVF" + "JA2N37RRrifw4PvgelRSvLaX3M3ZBqC9s1Metg3v4FSlIRtSLWCNpHSvNw7i" + "X8C2Xy9Hdlbh6Y/50o+iscojLRE14upfR1bIkcCZQGSyvGV52V2wBImUUZjV" + "s2ZngwCg7mu852vK7+euz4WaL7ERVYtq9CMEAJ5swrljerDpz/RQ4Lhp6KER" + "KyuI0PUttO57xINGshEINgYlZdGaZHRueHe7uKfI19mb0T4N3NJWaZ0wF+Cn" + "rixsq0VrTUfiwfZeGluNG73aTCeY45fVXMGTTSYXzS8T0LW100Xn/0g9HRyA" + "xUpuWo8IazxkMqHJis2uwriYKpAfA/9anvj5BS9p5pfPjp9dGM7GTMIYl5f2" + "fcP57f+AW1TVR6IZiMJAvAdeWuLtwLnJiFpGlnFz273pfl+sAuqm1yNceImR" + "2SDDP4+vtyycWy8nZhgEuhZx3W3cWMQz5WyNJSY1JJHh9TCQkCoN8E7XpVP4" + "zEPboB2GzD93mfD8JLHP+/4DAwIvYrn+YqRaaGAu19XUj895g/GROyP8WEaU" + "Bd/JNqWc4kE/0guetGnPzq7G3bLVwiKfFd4X7BrgHAo3mrQtVGVzdCBLZXkg" + "KG5vIGNvbW1lbnQpIDx0ZXN0QGJvdW5jeWNhc3RsZS5vcmc+iFkEExECABkF" + "AkB9BH0ECwcDAgMVAgMDFgIBAh4BAheAAAoJEKnMV8vjZQOpSRQAoKZy6YS1" + "irF5/Q3JlWiwbkN6dEuLAJ9lldRLOlXsuQ5JW1+SLEc6K9ho4rACAADRwXPB" + "cQEQAAEBAAAAAAAAAAAAAAAA/9j/4AAQSkZJRgABAQEASABIAAD//gAXQ3Jl" + "YXRlZCB3aXRoIFRoZSBHSU1Q/9sAQwAIBgYHBgUIBwcHCQkICgwUDQwLCwwZ" + "EhMPFB0aHx4dGhwcICQuJyAiLCMcHCg3KSwwMTQ0NB8nOT04MjwuMzQy/9sA" + "QwEJCQkMCwwYDQ0YMiEcITIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIy" + "MjIyMjIyMjIyMjIyMjIyMjIyMjIy/8AAEQgAFAAUAwEiAAIRAQMRAf/EABoA" + "AQACAwEAAAAAAAAAAAAAAAAEBQIDBgf/xAAoEAABAgUDBAEFAAAAAAAAAAAB" + "AgMABBEhMQUSQQYTIiNhFFGBkcH/xAAXAQEAAwAAAAAAAAAAAAAAAAAEAgMF" + "/8QAJBEAAQQAAwkAAAAAAAAAAAAAAQACERIEIfATMTJBUZGx0fH/2gAMAwEA" + "AhEDEQA/APMuotJlJVxstqaPo22NlAUp+YsNO0qSUtBcMu6n6EtOHcfPAHHF" + "I16++oajQtTA3DapK02HFR8UpE9pTbQWtKm2WG2rlxVyQTcfGbn7Qm0OIjL7" + "7Wrs2NNm9lzTmmSxQ0PX4opSprk5tmESF6syggzGwOLG6gXgHFbZhBixk8Xl" + "IDcOQLRKt+rX+3qC5ZLTQblpQlvwvxn9CMpZturVGkJHapQJphRH8hCLXbzr" + "qpYsCx1zC5rtpJNuYQhASc0UAQv/2YhcBBMRAgAcBQJAfQV+AhsDBAsHAwID" + "FQIDAxYCAQIeAQIXgAAKCRCpzFfL42UDqfa2AJ9hjtEeDTbTEAuuSbzhYFxN" + "/qc0FACgsmzysdbBpuN65yK01tbEaeIMtqCwAgAAnQEUBEB9BH4QAwCqRuWO" + "rxm5v/8WWBtPEUZnYuu3WYxefRKn6ON5ka5Ymp4AfKpKqKqn982tjlG13GVE" + "P2ow11L4yQKGNm+VyVEapm7SpMD0SHg9vsJygAWrfMJnBYWSgE19W6o3ckUR" + "sWsAAwYDAKDCSiSxC3Z5/POaCehw5iHs/vmVk5Wn831LSZEEwkSohNDbIEry" + "ia/9tFXSt11AP4stJtZ0MH87/6JBbiIRD4JXcx+zfzchL7Teczr/06QMphSn" + "sAENupbhLupfpR+BbP4DAwIvYrn+YqRaaGBjvFK1fbxCt7ZM4I2W/3BC0lCX" + "m/NypKNspGflec8u96uUlA0fNCnxm6f9nbB0jpvoKi0g4iqAf+P2iEYEGBEC" + "AAYFAkB9BH4ACgkQqcxXy+NlA6mtMgCgvccZA/Sg7BXVpxli47SYhxSHoM4A" + "oNCOMplSnYTuh5ikKeBWtz36gC1psAIAAA=="); char[] sec3pass1 = "123456".toCharArray(); // // GPG comment packets. // byte[] sec4 = Base64.decode( "lQG7BD0PbK8RBAC0cW4Y2MZXmAmqYp5Txyw0kSQsFvwZKHNMFRv996IsN57URVF5" + "BGMVPRBi9dNucWbjiSYpiYN13wE9IuLZsvVaQojV4XWGRDc+Rxz9ElsXnsYQ3mZU" + "7H1bNQEofstChk4z+dlvPBN4GFahrIzn/CeVUn6Ut7dVdYbiTqviANqNXwCglfVA" + "2OEePvqFnGxs1jhJyPSOnTED/RwRvsLH/k43mk6UEvOyN1RIpBXN+Ieqs7h1gFrQ" + "kB+WMgeP5ZUsotTffVDSUS9UMxRQggVUW1Xml0geGwQsNfkr/ztWMs/T4xp1v5j+" + "QyJx6OqNlkGdqOsoqkzJx0SQ1zBxdinFyyC4H95SDAb/RQOu5LQmxFG7quexztMs" + "infEA/9cVc9+qCo92yRAaXRqKNVVQIQuPxeUsGMyVeJQvJBD4An8KTMCdjpF10Cp" + "qA3t+n1S0zKr5WRUtvS6y60MOONO+EJWVWBNkx8HJDaIMNkfoqQoz3Krn7w6FE/v" + "/5uwMd6jY3N3yJZn5nDZT9Yzv9Nx3j+BrY+henRlSU0c6xDc9QAAnjJYg0Z83VJG" + "6HrBcgc4+4K6lHulCqH9JiM6RFNBX2ZhY3RvcjoAAK9hV206agp99GI6x5qE9+pU" + "vs6O+Ich/SYjOkRTQV9mYWN0b3I6AACvYAfGn2FGrpBYbjnpTuFOHJMS/T5xg/0m" + "IzpEU0FfZmFjdG9yOgAAr0dAQz6XxMwxWIn8xIZR/v2iN2L9C6O0EkZvbyBCYXIg" + "PGJhekBxdXV4PohXBBMRAgAXBQI9D2yvBQsHCgMEAxUDAgMWAgECF4AACgkQUGLI" + "YCIktfoGogCfZiXMJUKrScqozv5tMwzTTk2AaT8AniM5iRr0Du/Y08SL/NMhtF6H" + "hJ89nO4EPQ9ssRADAI6Ggxj6ZBfoavuXd/ye99osW8HsNlbqhXObu5mCMNySX2wa" + "HoWyRUEaUkI9eQw+MlHzIwzA32E7y2mU3OQBKdgLcBg4jxtcWVEg8ESKF9MpFXxl" + "pExxWrr4DFBfCRcsTwAFEQL9G3OvwJuEZXgx2JSS41D3pG4/qiHYICVa0u3p/14i" + "cq0kXajIk5ZJ6frCIAHIzuQ3n7jjzr05yR8s/qCrNbBA+nlkVNa/samk+jCzxxxa" + "cR/Dbh2wkvTFuDFFETwQYLuZAADcDck4YGQAmHivVT2NNDCf/aTz0+CJWl+xRc2l" + "Qw7D/SQjOkVMR19mYWN0b3I6AACbBnv9m5/bb/pjYAm2PtDp0CysQ9X9JCM6RUxH" + "X2ZhY3RvcjoAAJsFyHnSmaWguTFf6lJ/j39LtUNtmf0kIzpFTEdfZmFjdG9yOgAA" + "mwfwMD3LxmWtuCWBE9BptWMNH07Z/SQjOkVMR19mYWN0b3I6AACbBdhBrbSiM4UN" + "y7khDW2Sk0e4v9mIRgQYEQIABgUCPQ9ssQAKCRBQYshgIiS1+jCMAJ9txwHnb1Kl" + "6i/fSoDs8SkdM7w48wCdFvPEV0sSxE73073YhBgPZtMWbBo="); // // PGP freeware version 7 // byte[] pub5 = Base64.decode( "mQENBEBrBE4BCACjXVcNIFDQSofaIyZnALb2CRg+WY9uUqgHEEAOlPe03Cs5STM5" + "HDlNmrh4TdFceJ46rxk1mQOjULES1YfHay8lCIzrD7FX4oj0r4DC14Fs1vXaSar2" + "1szIpttOw3obL4A1e0p6N4jjsoG7N/pA0fEL0lSw92SoBrMbAheXRg4qNTZvdjOR" + "grcuOuwgJRvPLtRXlhyLBoyhkd5mmrIDGv8QHJ/UjpeIcRXY9kn9oGXnEYcRbMaU" + "VwXB4pLzWqz3ZejFI3lOxRWjm760puPOnGYlzSVBxlt2LgzUgSj1Mn+lIpWmAzsa" + "xEiU4xUwEomQns72yYRZ6D3euNCibcte4SeXABEBAAG0KXBhbGFzaCBrYXNvZGhh" + "biA8cGthc29kaGFuQHRpYWEtY3JlZi5vcmc+iQEuBBABAgAYBQJAawROCAsBAwkI" + "BwIKAhkBBRsDAAAAAAoJEOfelumuiOrYqPEH+wYrdP5Tq5j+E5yN1pyCg1rwbSOt" + "Dka0y0p7Oq/VIGLk692IWPItLEunnBXQtGBcWqklrvogvlhxtf16FgoyScfLJx1e" + "1cJa+QQnVuH+VOESN6iS9Gp9lUfVOHv74mEMXw0l2Djfy/lnrkAMBatggyGnF9xF" + "VXOLk1J2WVFm9KUE23o6qdB7RGkf31pN2eA7SWmkdJSkUH7o/QSFBI+UTRZ/IY5P" + "ZIJpsdiIOqd9YMG/4RoSZuPqNRR6x7BSs8nQVR9bYs4PPlp4GfdRnOcRonoTeJCZ" + "83RnsraWJnJTg34gRLBcqumhTuFKc8nuCNK98D6zkQESdcHLLTquCOaF5L+5AQ0E" + "QGsETwEIAOVwNCTaDZvW4dowPbET1bI5UeYY8rAGLYsWSUfgaFv2srMiApyBVltf" + "i6OLcPjcUCHDBjCv4pwx/C4qcHWb8av4xQIpqQXOpO9NxYE1eZnel/QB7DtH12ZO" + "nrDNmHtaXlulcKNGe1i1utlFhgzfFx6rWkRL0ENmkTkaQmPY4gTGymJTUhBbsSRq" + "2ivWqQA1TPwBuda73UgslIAHRd/SUaxjXoLpMbGOTeqzcKGjr5XMPTs7/YgBpWPP" + "UxMlEQIiU3ia1bxpEhx05k97ceK6TSH2oCPQA7gumjxOSjKT+jEm+8jACVzymEmc" + "XRy4D5Ztqkw/Z16pvNcu1DI5m6xHwr8AEQEAAYkBIgQYAQIADAUCQGsETwUbDAAA" + "AAAKCRDn3pbprojq2EynB/4/cEOtKbI5UisUd3vkTzvWOcqWUqGqi5wjjioNtIM5" + "pur2nFvhQE7SZ+PbAa87HRJU/4WcWMcoLkHD48JrQwHCHOLHSV5muYowb78X4Yh9" + "epYtSJ0uUahcn4Gp48p4BkhgsPYXkxEImSYzAOWStv21/7WEMqItMYl89BV6Upm8" + "HyTJx5MPTDbMR7X51hRg3OeQs6po3WTCWRzFIMyGm1rd/VK1L5ZDFPqO3S6YUJ0z" + "cxecYruvfK0Wp7q834wE8Zkl/PQ3NhfEPL1ZiLr/L00Ty+77/FZqt8SHRCICzOfP" + "OawcVGI+xHVXW6lijMpB5VaVIH8i2KdBMHXHtduIkPr9"); byte[] sec5 = Base64.decode( "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"); char[] sec5pass1 = "12345678".toCharArray(); // // Werner Koch "odd keys" // byte[] pub6 = Base64.decode( "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" + "L4Kb7TWkd/OHQScVBO8sTUz0+2g="); byte[] pub6check = Base64.decode("62O9"); // // revoked sub key // byte[] pub7 = Base64.decode( "mQGiBEFOsIwRBADcjRx7nAs4RaWsQU6p8/ECLZD9sSeYc6CN6UDI96RKj0/hCzMs" + "qlA0+9fzGZ7ZEJ34nuvDKlhKGC7co5eOiE0a9EijxgcrZU/LClZWa4YfyNg/ri6I" + "yTyfOfrPQ33GNQt2iImDf3FKp7XKuY9nIxicGQEaW0kkuAmbV3oh0+9q8QCg/+fS" + "epDEqEE/+nKONULGizKUjMED/RtL6RThRftZ9DOSdBytGYd48z35pca/qZ6HA36K" + "PVQwi7V77VKQyKFLTOXPLnVyO85hyYB/Nv4DFHN+vcC7/49lfoyYMZlN+LarckHi" + "NL154wmmzygB/KKysvWBLgkErEBCD0xBDd89iTQNlDtVQAWGORVffl6WWjOAkliG" + "3dL6A/9A288HfFRnywqi3xddriV6wCPmStC3dkCS4vHk2ofS8uw4ZNoRlp1iEPna" + "ai2Xa9DX1tkhaGk2k96MqqbBdGpbW8sMA9otJ9xdMjWEm/CgJUFUFQf3zaVy3mkM" + "S2Lvb6P4Wc2l/diEEIyK8+PqJItSh0OVU3K9oM7ngHwVcalKILQVUkV2b2tlZCA8" + "UmV2b2tlZEB0ZWQ+iQBOBBARAgAOBQJBTrCMBAsDAgECGQEACgkQvglkcFA/c63+" + "QgCguh8rsJbPTtbhZcrqBi5Mo1bntLEAoPZQ0Kjmu2knRUpHBeUemHDB6zQeuQIN" + "BEFOsIwQCAD2Qle3CH8IF3KiutapQvMF6PlTETlPtvFuuUs4INoBp1ajFOmPQFXz" + "0AfGy0OplK33TGSGSfgMg71l6RfUodNQ+PVZX9x2Uk89PY3bzpnhV5JZzf24rnRP" + "xfx2vIPFRzBhznzJZv8V+bv9kV7HAarTW56NoKVyOtQa8L9GAFgr5fSI/VhOSdvN" + "ILSd5JEHNmszbDgNRR0PfIizHHxbLY7288kjwEPwpVsYjY67VYy4XTjTNP18F1dD" + "ox0YbN4zISy1Kv884bEpQBgRjXyEpwpy1obEAxnIByl6ypUM2Zafq9AKUJsCRtMI" + "PWakXUGfnHy9iUsiGSa6q6Jew1XpMgs7AAICB/93zriSvSHqsi1FeEmUBo431Jkh" + "VerIzb6Plb1j6FIq+s3vyvx9K+dMvjotZqylWZj4GXpH+2xLJTjWkrGSfUZVI2Nk" + "nyOFxUCKLLqaqVBFAQIjULfvQfGEWiGQKk9aRLkdG+D+8Y2N9zYoBXoQ9arvvS/t" + "4mlOsiuaTe+BZ4x+BXTpF4b9sKZl7V8QP/TkoJWUdydkvxciHdWp7ssqyiKOFRhG" + "818knDfFQ3cn2w/RnOb+7AF9wDncXDPYLfpPv9b2qZoLrXcyvlLffGDUdWs553ut" + "1F5AprMURs8BGmY9BnjggfVubHdhTUoA4gVvrdaf+D9NwZAl0xK/5Y/oPuMZiQBG" + "BBgRAgAGBQJBTrCMAAoJEL4JZHBQP3Ot09gAoMmLKloVDP+WhDXnsM5VikxysZ4+" + "AKCrJAUO+lYAyPYwEwgK+bKmUGeKrIkARgQoEQIABgUCQU6wpQAKCRC+CWRwUD9z" + "rQK4AJ98kKFxGU6yhHPr6jYBJPWemTNOXgCfeGB3ox4PXeS4DJDuLy9yllytOjo="); byte[] pub7check = Base64.decode("f/YQ"); byte[] pub8 = Base64.decode( "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" + "9Uqz3fUvGoewAWA="); byte[] sec8 = Base64.decode( "lQHpBEEcraYRBADFYj+uFOhHz5SdECvJ3Z03P47gzmWLQ5HH8fPYC9rrv7AgqFFX" + "aWlJJVMLua9e6xoCiDWJs/n4BbZ/weL/11ELg6XqUnzFhYyz0H2KFsPgQ/b9lWLY" + "MtcPMFy5jE33hv/ixHgYLFqoNaAIbg0lzYEW/otQ9IhRl16fO1Q/CQZZrQCg/9M2" + "V2BTmm9RYog86CXJtjawRBcD/RIqU0zulxZ2Zt4javKVxrGIwW3iBU935ebmJEIK" + "Y5EVkGKBOCvsApZ+RGzpYeR2uMsTnQi8RJgiAnjaoVPCdsVJE7uQ0h8XuJ5n5mJ2" + "kLCFlF2hj5ViicZzse+crC12CGtgRe8z23ubLRcd6IUGhVutK8/b5knZ22vE14JD" + "ykKdA/96ObzJQdiuuPsEWN799nUUCaYWPAoLAmiXuICSP4GEnxLbYHWo8zhMrVMT" + "9Q5x3h8cszUz7Acu2BXjP1m96msUNoxPOZtt88NlaFz1Q/JSbQTsVOMd9b/IRN6S" + "A/uU0BiKEMHXuT8HUHVPK49oCKhZrGFP3RT8HZxDKLmR/qrgZ/4JAwLXyWhb4pf4" + "nmCmD0lDwoYvatLiR7UQVM2MamxClIiT0lCPN9C2AYIFgRWAJNS215Tjx7P/dh7e" + "8sYfh5XEHErT3dMbsAGHtCFKaWEgWWl5dSA8eXlqaWFAbm93bWVkaWF0ZWNoLmNv" + "bT6wAwP//4kAXQQQEQIAHQUCQRytpgcLCQgHAwIKAhkBBRsDAAAABR4BAAAAAAoJ" + "EPT+Vvgr/2IUmWEAoJEyJ9B7CJfmjwVTT30UbdCctVRmAJ9akw6we6UYd82vF0FK" + "QTlSuqHXKbABZ50CawRBHK2mEAgA9kJXtwh/CBdyorrWqULzBej5UxE5T7bxbrlL" + "OCDaAadWoxTpj0BV89AHxstDqZSt90xkhkn4DIO9ZekX1KHTUPj1WV/cdlJPPT2N" + "286Z4VeSWc39uK50T8X8dryDxUcwYc58yWb/Ffm7/ZFexwGq01uejaClcjrUGvC/" + "RgBYK+X0iP1YTknbzSC0neSRBzZrM2w4DUUdD3yIsxx8Wy2O9vPJI8BD8KVbGI2O" + "u1WMuF040zT9fBdXQ6MdGGzeMyEstSr/POGxKUAYEY18hKcKctaGxAMZyAcpesqV" + "DNmWn6vQClCbAkbTCD1mpF1Bn5x8vYlLIhkmuquiXsNV6TILOwACAgf/crbApFLO" + "QikN9lHbn62dDxuu/dNigNmjf/A3cX+vo8aPHTXnRDyDwQALRuqbitdbM6p1LFjG" + "8g84Aabk/jL7zzjJLqPe8pxeK1Pu+P44NzalXAYMsOOsxGuixIrz3Jw8IrpH/mkP" + "tG/iX0NaLZ+Au9eokdLb+6NR/a51r2qL3E0ycFciJ61HzZKKHi6d0VQ7CHozCz+j" + "d5530Mh1qq/ZjYDDjfP+snpyNIZXcLtGR/3HzkBqNgDcvClLx3322AWKDa7pX8DX" + "qiLr8znWhPRpH9kCTnSpRzhYGT25FRcvdj4/q/oUIET/Tp+BWW3BxAc7WgpgqEfn" + "fa0Mv72Zbn91gf4JAwITijME9IlFBGAwH6YmBtWIlnDiRbsq/Pxozuhbnes831il" + "KmdpUKXkiIfHY0MqrEWl3Dfn6PMJGTnhgqXMrDxx3uHrq0Jl2swRnAWIIO8gID7j" + "uPetUqEviPiwAYeJAEwEGBECAAwFAkEcraYFGwwAAAAACgkQ9P5W+Cv/YhShrgCg" + "+JW8m5nF3R/oZGuG87bXQBszkjMAoLhGPncuGKowJXMRVc70/8qwXQJLsAFn"); char[] sec8pass = "qwertyui".toCharArray(); byte[] sec9 = Base64.decode( "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" + "6neEEX/i1Q=="); public char[] sec9pass = "foo".toCharArray(); // version 4 keys with expiry dates byte[] pub10 = Base64.decode( "mQGiBEKqia0RBACc3hkufmscRSC4UvPZqMDsHm4+d/GXIr+3iNMSSEySJu8yk+k0" + "Xs11C/K+n+v1rnn2jGGknv+1lDY6w75TIcTE6o6HGKeIDxsAm8P3MhoGU1GNPamA" + "eTDeNybtrN/g6C65fCY9uI11hsUboYgQZ8ND22PB0VtvdOgq9D85qNUzxwCg1BbJ" + "ycAKd4VqEvQ2Zglp3dCSrFMD/Ambq1kZqYa69sp3b9BPKuAgUgUPoytOArEej3Bk" + "easAgAxNhWJy4GxigES3vk50rVi7w8XBuqbD1mQCzldF0HX0/A7PxLBv6od5uqqF" + "HFxIyxg/KBZLd9ZOrsSaoUWH58jZq98X/sFtJtRi5VuJagMxCIJD4mLgtMv7Unlb" + "/GrsA/9DEnObA/fNTgK70T+ZmPIS5tSt+bio30Aw4YGpPCGqpnm1u73b5kqX3U3B" + "P+vGDvFuqZYpqQA8byAueH0MbaDHI4CFugvShXvgysJxN7ov7/8qsZZUMfK1t2Nr" + "SAsPuKRbcY4gNKXIElKeXbyaET7vX7uAEKuxEwdYGFp/lNTkHLQgdGVzdCBrZXkg" + "KHRlc3QpIDx0ZXN0QHRlc3QudGVzdD6IZAQTEQIAJAUCQqqJrQIbAwUJACTqAAYL" + "CQgHAwIDFQIDAxYCAQIeAQIXgAAKCRDjDROQZRqIzDzLAJ42AeCRIBBjv8r8qw9y" + "laNj2GZ1sACgiWYHVXMA6B1H9I1kS3YsCd3Oq7qwAgAAuM0EQqqJrhADAKWkix8l" + "pJN7MMTXob4xFF1TvGll0UD1bDGOMMbes6aeXSbT9QXee/fH3GnijLY7wB+qTPv9" + "ohubrSpnv3yen3CEBW6Q2YK+NlCskma42Py8YMV2idmYjtJi1ckvHFWt5wADBQL/" + "fkB5Q5xSGgspMaTZmtmX3zG7ZDeZ0avP8e8mRL8UszCTpqs6vMZrXwyQLZPbtMYv" + "PQpuRGEeKj0ysimwYRA5rrLQjnRER3nyuuEUUgc4j+aeRxPf9WVsJ/a1FCHtaAP1" + "iE8EGBECAA8FAkKqia4CGwwFCQAk6gAACgkQ4w0TkGUaiMzdqgCfd66H7DL7kFGd" + "IoS+NIp8JO+noxAAn25si4QAF7og8+4T5YQUuhIhx/NesAIAAA=="); byte[] sec10 = Base64.decode( "lQHhBEKqia0RBACc3hkufmscRSC4UvPZqMDsHm4+d/GXIr+3iNMSSEySJu8yk+k0" + "Xs11C/K+n+v1rnn2jGGknv+1lDY6w75TIcTE6o6HGKeIDxsAm8P3MhoGU1GNPamA" + "eTDeNybtrN/g6C65fCY9uI11hsUboYgQZ8ND22PB0VtvdOgq9D85qNUzxwCg1BbJ" + "ycAKd4VqEvQ2Zglp3dCSrFMD/Ambq1kZqYa69sp3b9BPKuAgUgUPoytOArEej3Bk" + "easAgAxNhWJy4GxigES3vk50rVi7w8XBuqbD1mQCzldF0HX0/A7PxLBv6od5uqqF" + "HFxIyxg/KBZLd9ZOrsSaoUWH58jZq98X/sFtJtRi5VuJagMxCIJD4mLgtMv7Unlb" + "/GrsA/9DEnObA/fNTgK70T+ZmPIS5tSt+bio30Aw4YGpPCGqpnm1u73b5kqX3U3B" + "P+vGDvFuqZYpqQA8byAueH0MbaDHI4CFugvShXvgysJxN7ov7/8qsZZUMfK1t2Nr" + "SAsPuKRbcY4gNKXIElKeXbyaET7vX7uAEKuxEwdYGFp/lNTkHP4DAwLssmOjVC+d" + "mWB783Lpzjb9evKzsxisTdx8/jHpUSS+r//6/Guyx3aA/zUw5bbftItW57mhuNNb" + "JTu7WrQgdGVzdCBrZXkgKHRlc3QpIDx0ZXN0QHRlc3QudGVzdD6IZAQTEQIAJAUC" + "QqqJrQIbAwUJACTqAAYLCQgHAwIDFQIDAxYCAQIeAQIXgAAKCRDjDROQZRqIzDzL" + "AJ0cYPwKeoSReY14LqJtAjnkX7URHACgsRZWfpbalrSyDnq3TtZeGPUqGX+wAgAA" + "nQEUBEKqia4QAwClpIsfJaSTezDE16G+MRRdU7xpZdFA9WwxjjDG3rOmnl0m0/UF" + "3nv3x9xp4oy2O8Afqkz7/aIbm60qZ798np9whAVukNmCvjZQrJJmuNj8vGDFdonZ" + "mI7SYtXJLxxVrecAAwUC/35AeUOcUhoLKTGk2ZrZl98xu2Q3mdGrz/HvJkS/FLMw" + "k6arOrzGa18MkC2T27TGLz0KbkRhHio9MrIpsGEQOa6y0I50REd58rrhFFIHOI/m" + "nkcT3/VlbCf2tRQh7WgD9f4DAwLssmOjVC+dmWDXVLRopzxbBGOvodp/LZoSDb56" + "gNJjDMJ1aXqWW9qTAg1CFjBq73J3oFpVzInXZ8+Q8inxv7bnWiHbiE8EGBECAA8F" + "AkKqia4CGwwFCQAk6gAACgkQ4w0TkGUaiMzdqgCgl2jw5hfk/JsyjulQqe1Nps1q" + "Lx0AoMdnFMZmTMLHn8scUW2j9XO312tmsAIAAA=="); public char[] sec10pass = "test".toCharArray(); public byte[] subKeyBindingKey = Base64.decode( "mQGiBDWagYwRBAD7UcH4TAIp7tmUoHBNxVxCVz2ZrNo79M6fV63riOiH2uDxfIpr" + "IrL0cM4ehEKoqlhngjDhX60eJrOw1nC5BpYZRnDnyDYT4wTWRguxObzGq9pqA1dM" + "oPTJhkFZVIBgFY99/ULRqaUYIhFGgBtnwS70J8/L/PGVc3DmWRLMkTDjSQCg/5Nh" + "MCjMK++MdYMcMl/ziaKRT6EEAOtw6PnU9afdohbpx9CK4UvCCEagfbnUtkSCQKSk" + "6cUp6VsqyzY0pai/BwJ3h4apFMMMpVrtBAtchVgqo4xTr0Sve2j0k+ase6FSImiB" + "g+AR7hvTUTcBjwtIExBc8TuCTqmn4GG8F7UMdl5Z0AZYj/FfAQYaRVZYP/pRVFNx" + "Lw65BAC/Fi3qgiGCJFvXnHIckTfcAmZnKSEXWY9NJ4YQb4+/nH7Vsw0wR/ZObUHR" + "bWgTc9Vw1uZIMe0XVj6Yk1dhGRehUnrm3mE7UJxu7pgkBCbFECFSlSSqP4MEJwZV" + "09YP/msu50kjoxyoTpt+16uX/8B4at24GF1aTHBxwDLd8X0QWrQsTWVycmlsbCBM" + "eW5jaCBDTEVBUiBzeXN0ZW0gREggPGNsZWFyQG1sLmNvbT6JAEsEEBECAAsFAjWa" + "gYwECwMBAgAKCRDyAGjiP47/XanfAKCs6BPURWVQlGh635VgL+pdkUVNUwCdFcNa" + "1isw+eAcopXPMj6ACOapepu5Ag0ENZqBlBAIAPZCV7cIfwgXcqK61qlC8wXo+VMR" + "OU+28W65Szgg2gGnVqMU6Y9AVfPQB8bLQ6mUrfdMZIZJ+AyDvWXpF9Sh01D49Vlf" + "3HZSTz09jdvOmeFXklnN/biudE/F/Ha8g8VHMGHOfMlm/xX5u/2RXscBqtNbno2g" + "pXI61Brwv0YAWCvl9Ij9WE5J280gtJ3kkQc2azNsOA1FHQ98iLMcfFstjvbzySPA" + "Q/ClWxiNjrtVjLhdONM0/XwXV0OjHRhs3jMhLLUq/zzhsSlAGBGNfISnCnLWhsQD" + "GcgHKXrKlQzZlp+r0ApQmwJG0wg9ZqRdQZ+cfL2JSyIZJrqrol7DVekyCzsAAgIH" + "/RYtVo+HROZ6jrNjrATEwQm1fUQrk6n5+2dniN881lF0CNkB4NkHw1Xxz4Ejnu/0" + "iLg8fkOAsmanOsKpOkRtqUnVpsVL5mLJpFEyCY5jbcfj+KY9/25bs0ga7kLHNZia" + "zbCxJdF+W179z3nudQxRaXG/0XISIH7ziZbSVni69sKc1osk1+OoOMbSuZ86z535" + "Pln4fXclkFE927HxfbWoO+60hkOLKh7x+8fC82b3x9vCETujEaxrscO2xS7/MYXP" + "8t1ffriTDmhuIuQS2q4fLgeWdqrODrMhrD8Dq7e558gzp30ZCqpiS7EmKGczL7B8" + "gXxbBCVSTxYMJheXt2xMXsuJAD8DBRg1moGU8gBo4j+O/10RAgWdAKCPhaFIXuC8" + "/cdiNMxTDw9ug3De5QCfYXmDzRSFUu/nrCi8yz/l09wsnxo="); public byte[] subKeyBindingCheckSum = Base64.decode("3HU+"); // // PGP8 with SHA1 checksum. // public byte[] rewrapKey = Base64.decode( "lQOWBEUPOQgBCADdjPTtl8oOwqJFA5WU8p7oDK5KRWfmXeXUZr+ZJipemY5RSvAM" + "rxqsM47LKYbmXOJznXCQ8+PPa+VxXAsI1CXFHIFqrXSwvB/DUmb4Ec9EuvNd18Zl" + "hJAybzmV2KMkaUp9oG/DUvxZJqkpUddNfwqZu0KKKZWF5gwW5Oy05VCpaJxQVXFS" + "whdbRfwEENJiNx4RB3OlWhIjY2p+TgZfgQjiGB9i15R+37sV7TqzBUZF4WWcnIRQ" + "DnpUfxHgxQ0wO/h/aooyRHSpIx5i4oNpMYq9FNIyakEx/Bomdbs5hW9dFxhrE8Es" + "UViAYITgTsyROxmgGatGG09dcmVDJVYF4i7JAAYpAAf/VnVyUDs8HrxYTOIt4rYY" + "jIHToBsV0IiLpA8fEA7k078L1MwSwERVVe6oHVTjeR4A9OxE52Vroh2eOLnF3ftf" + "6QThVVZr+gr5qeG3yvQ36N7PXNEVOlkyBzGmFQNe4oCA+NR2iqnAIspnekVmwJV6" + "xVvPCjWw/A7ZArDARpfthspwNcJAp4SWfoa2eKzvUTznTyqFu2PSS5fwQZUgOB0P" + "Y2FNaKeqV8vEZu4SUWwLOqXBQIZXiaLvdKNgwFvUe3kSHdCNsrVzW7SYxFwaEog2" + "o6YLKPVPqjlGX1cMOponGp+7n9nDYkQjtEsGSSMQkQRDAcBdSVJmLO07kFOQSOhL" + "WQQA49BcgTZyhyH6TnDBMBHsGCYj43FnBigypGT9FrQHoWybfX47yZaZFROAaaMa" + "U6man50YcYZPwzDzXHrK2MoGALY+DzB3mGeXVB45D/KYtlMHPLgntV9T5b14Scbc" + "w1ES2OUtsSIUs0zelkoXqjLuKnSIYK3mMb67Au7AEp6LXM8EAPj2NypvC86VEnn+" + "FH0QHvUwBpmDw0EZe25xQs0brvAG00uIbiZnTH66qsIfRhXV/gbKK9J5DTGIqQ15" + "DuPpz7lcxg/n2+SmjQLNfXCnG8hmtBjhTe+udXAUrmIcfafXyu68SAtebgm1ga56" + "zUfqsgN3FFuMUffLl3myjyGsg5DnA/oCFWL4WCNClOgL6A5VkNIUait8QtSdCACT" + "Y7jdSOguSNXfln0QT5lTv+q1AjU7zjRl/LsFNmIJ5g2qdDyK937FOXM44FEEjZty" + "/4P2dzYpThUI4QUohIj8Qi9f2pZQueC5ztH6rpqANv9geZKcciAeAbZ8Md0K2TEU" + "RD3Lh+RSBzILtBtUZXN0IEtleSA8dGVzdEBleGFtcGxlLmNvbT6JATYEEwECACAF" + "AkUPOQgCGwMGCwkIBwMCBBUCCAMEFgIDAQIeAQIXgAAKCRDYpknHeQaskD9NB/9W" + "EbFuLaqZAl3yjLU5+vb75BdvcfL1lUs44LZVwobNp3/0XbZdY76xVPNZURtU4u3L" + "sJfGlaF+EqZDE0Mqc+vs5SIb0OnCzNJ00KaUFraUtkByRV32T5ECHK0gMBjCs5RT" + "I0vVv+Qmzl4+X1Y2bJ2mlpBejHIrOzrBD5NTJimTAzyfnNfipmbqL8p/cxXKKzS+" + "OM++ZFNACj6lRM1W9GioXnivBRC88gFSQ4/GXc8yjcrMlKA27JxV+SZ9kRWwKH2f" + "6o6mojUQxnHr+ZFKUpo6ocvTgBDlC57d8IpwJeZ2TvqD6EdA8rZ0YriVjxGMDrX1" + "8esfw+iLchfEwXtBIRwS"); char[] rewrapPass = "voltage123".toCharArray(); byte[] pubWithX509 = Base64.decode( "mQENBERabjABCACtmfyo6Nph9MQjv4nmCWjZrRYnhXbivomAdIwYkLZUj1bjqE+j"+ "uaLzjZV8xSI59odZvrmOiqlzOc4txitQ1OX7nRgbOJ7qku0dvwjtIn46+HQ+cAFn"+ "2mTi81RyXEpO2uiZXfsNTxUtMi+ZuFLufiMc2kdk27GZYWEuasdAPOaPJnA+wW6i"+ "ZHlt0NfXIGNz864gRwhD07fmBIr1dMFfATWxCbgMd/rH7Z/j4rvceHD2n9yrhPze"+ "YN7W4Nuhsr2w/Ft5Cm9xO7vXT/cpto45uxn8f7jERep6bnUwNOhH8G+6xLQgTLD0"+ "qFBGVSIneK3lobs6+xn6VaGN8W0tH3UOaxA1ABEBAAG0D0NOPXFhLWRlZXBzaWdo"+ "dIkFDgQQZAIFAQUCRFpuMAUDCWdU0gMF/3gCGwPELGQBAQQwggTkMIIDzKADAgEC"+ "AhBVUMV/M6rIiE+IzmnPheQWMA0GCSqGSIb3DQEBBQUAMG4xEzARBgoJkiaJk/Is"+ "ZAEZFgNjb20xEjAQBgoJkiaJk/IsZAEZFgJxYTEVMBMGCgmSJomT8ixkARkWBXRt"+ "czAxMRUwEwYKCZImiZPyLGQBGRYFV2ViZmUxFTATBgNVBAMTDHFhLWRlZXBzaWdo"+ "dDAeFw0wNjA1MDQyMTEyMTZaFw0xMTA1MDQyMTIwMDJaMG4xEzARBgoJkiaJk/Is"+ "ZAEZFgNjb20xEjAQBgoJkiaJk/IsZAEZFgJxYTEVMBMGCgmSJomT8ixkARkWBXRt"+ "czAxMRUwEwYKCZImiZPyLGQBGRYFV2ViZmUxFTATBgNVBAMTDHFhLWRlZXBzaWdo"+ "dDCCASIwDQYJKoZIhvcNAQEBBQADggEPADCCAQoCggEBAK2Z/Kjo2mH0xCO/ieYJ"+ "aNmtFieFduK+iYB0jBiQtlSPVuOoT6O5ovONlXzFIjn2h1m+uY6KqXM5zi3GK1DU"+ "5fudGBs4nuqS7R2/CO0ifjr4dD5wAWfaZOLzVHJcSk7a6Jld+w1PFS0yL5m4Uu5+"+ "IxzaR2TbsZlhYS5qx0A85o8mcD7BbqJkeW3Q19cgY3PzriBHCEPTt+YEivV0wV8B"+ "NbEJuAx3+sftn+Piu9x4cPaf3KuE/N5g3tbg26GyvbD8W3kKb3E7u9dP9ym2jjm7"+ "Gfx/uMRF6npudTA06Efwb7rEtCBMsPSoUEZVIid4reWhuzr7GfpVoY3xbS0fdQ5r"+ "EDUCAwEAAaOCAXwwggF4MAsGA1UdDwQEAwIBhjAPBgNVHRMBAf8EBTADAQH/MB0G"+ "A1UdDgQWBBSmFTRv5y65DHtTYae48zl0ExNWZzCCASUGA1UdHwSCARwwggEYMIIB"+ "FKCCARCgggEMhoHFbGRhcDovLy9DTj1xYS1kZWVwc2lnaHQsQ049cWEtd3VtYW4x"+ "LWRjLENOPUNEUCxDTj1QdWJsaWMlMjBLZXklMjBTZXJ2aWNlcyxDTj1TZXJ2aWNl"+ "cyxDTj1Db25maWd1cmF0aW9uLERDPVdlYmZlLERDPXRtczAxLERDPXFhLERDPWNv"+ "bT9jZXJ0aWZpY2F0ZVJldm9jYXRpb25MaXN0P2Jhc2U/b2JqZWN0Q2xhc3M9Y1JM"+ "RGlzdHJpYnV0aW9uUG9pbnSGQmh0dHA6Ly9xYS13dW1hbjEtZGMud2ViZmUudG1z"+ "MDEucWEuY29tL0NlcnRFbnJvbGwvcWEtZGVlcHNpZ2h0LmNybDAQBgkrBgEEAYI3"+ "FQEEAwIBADANBgkqhkiG9w0BAQUFAAOCAQEAfuZCW3XlB7Eok35zQbvYt9rhAndT"+ "DNw3wPNI4ZzD1nXoYWnwhNNvWRpsOt4ExOSNdaHErfgDXAMyyg66Sro0TkAx8eAj"+ "fPQsyRAh0nm0glzFmJN6TdOZbj7hqGZjc4opQ6nZo8h/ULnaEwMIUW4gcSkZt0ww"+ "CuErl5NUrN3DpkREeCG/fVvQZ8ays3ibQ5ZCZnYBkLYq/i0r3NLW34WfYhjDY48J"+ "oQWtvFSAxvRfz2NGmqnrCHPQZxqlfdta97kDa4VQ0zSeBaC70gZkLmD1GJMxWoXW"+ "6tmEcgPY5SghInUf+L2u52V55MjyAFzVp7kTK2KY+p7qw35vzckrWkwu8AAAAAAA"+ "AQE="); private static byte[] secWithPersonalCertificate = Base64.decode( "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" + "cGdwbWltZQULBwgJAgIZAQUbAQAAAAUeAQAAAAIVAgAKCRDlTa3BE84gWVKW" + "BACcoCFKvph9r9QiHT1Z3N4wZH36Uxqu/059EFALnBkEdVudX/p6S9mynGRk" + "EfhmWFC1O6dMpnt+ZBEed/4XyFWVSLPwirML+6dxfXogdUsdFF1NCRHc3QGc" + "txnNUT/zcZ9IRIQjUhp6RkIvJPHcyfTXKSbLviI+PxzHU2Padq8pV7ABZ7kA" + "jQRIfg8tAQQAutJR/aRnfZYwlVv+KlUDYjG8YQUfHpTxpnmVu7W6N0tNg/Xr" + "5dg50wq3I4HOamRxUwHpdPkXyNF1szpDSRZmlM+VmiIvJDBnyH5YVlxT6+zO" + "8LUJ2VTbfPxoLFp539SQ0oJOm7IGMAGO7c0n/QV0N3hKUfWgCyJ+sENDa0Ft" + "JycAEQEAAbABj4kEzQQYAQIENwUCSMYtnAUJAeEzgMLFFAAAAAAAFwNleDUw" + "OWNlcnRpZmljYXRlQHBncC5jb20wggNhMIICyqADAgECAgkA1AoCoRKJCgsw" + "DQYJKoZIhvcNAQEFBQAwgakxCzAJBgNVBAYTAkNaMRcwFQYDVQQIEw5DemVj" + "aCBSZXB1YmxpYzESMBAGA1UEChQJQSYmTCBzb2Z0MSAwHgYDVQQLExdJbnRl" + "cm5hbCBEZXZlbG9wbWVudCBDQTEqMCgGA1UEAxQhQSYmTCBzb2Z0IEludGVy" + "bmFsIERldmVsb3BtZW50IENBMR8wHQYJKoZIhvcNAQkBFhBrYWRsZWNAYWxz" + "b2Z0LmN6MB4XDTA4MDcxNjE1MDkzM1oXDTA5MDcxNjE1MDkzM1owaTELMAkG" + "A1UEBhMCQ1oxFzAVBgNVBAgTDkN6ZWNoIFJlcHVibGljMRIwEAYDVQQKFAlB" + "JiZMIHNvZnQxFDASBgNVBAsTC0RldmVsb3BtZW50MRcwFQYDVQQDEw5IeW5l" + "ay1JbnRyYW5ldDCBnzANBgkqhkiG9w0BAQEFAAOBjQAwgYkCgYEAutJR/aRn" + "fZYwlVv+KlUDYjG8YQUfHpTxpnmVu7W6N0tNg/Xr5dg50wq3I4HOamRxUwHp" + "dPkXyNF1szpDSRZmlM+VmiIvJDBnyH5YVlxT6+zO8LUJ2VTbfPxoLFp539SQ" + "0oJOm7IGMAGO7c0n/QV0N3hKUfWgCyJ+sENDa0FtJycCAwEAAaOBzzCBzDAJ" + "BgNVHRMEAjAAMCwGCWCGSAGG+EIBDQQfFh1PcGVuU1NMIEdlbmVyYXRlZCBD" + "ZXJ0aWZpY2F0ZTAdBgNVHQ4EFgQUNaw7A6r10PtYZzAvr9CrSKeRYJgwHwYD" + "VR0jBBgwFoAUmqSRM8rN3+T1+tkGiqef8S5suYgwGgYDVR0RBBMwEYEPaHlu" + "ZWtAYWxzb2Z0LmN6MCgGA1UdHwQhMB8wHaAboBmGF2h0dHA6Ly9wZXRyazIv" + "Y2EvY2EuY3JsMAsGA1UdDwQEAwIF4DANBgkqhkiG9w0BAQUFAAOBgQCUdOWd" + "7mBLWj1/GSiYgfwgdTrgk/VZOJvMKBiiFyy1iFEzldz6Xx+mAexnFJKfZXZb" + "EMEGWHfWPmgJzAtuTT0Jz6tUwDmeLH3MP4m8uOZtmyUJ2aq41kciV3rGxF0G" + "BVlZ/bWTaOzHdm6cjylt6xxLt6MJzpPBA/9ZfybSBh1DaAUbDgAAAJ0gBBkB" + "AgAGBQJIxi2bAAoJEAdYkEWLb2R2fJED/RK+JErZ98uGo3Z81cHkdP3rk8is" + "DUL/PR3odBPFH2SIA5wrzklteLK/ZXmBUzcvxqHEgI1F7goXbsBgeTuGgZdx" + "pINErxkNpcMl9FTldWKGiapKrhkZ+G8knDizF/Y7Lg6uGd2nKVxzutLXdHJZ" + "pU89Q5nzq6aJFAZo5TBIcchQAAoJEOVNrcETziBZXvQD/1mvFqBfWqwXxoj3" + "8fHUuFrE2pcp32y3ciO2i+uNVEkNDoaVVNw5eHQaXXWpllI/Pe6LnBl4vkyc" + "n3pjONa4PKrePkEsCUhRbIySqXIHuNwZumDOlKzZHDpCUw72LaC6S6zwuoEf" + "ucOcxTeGIUViANWXyTIKkHfo7HfigixJIL8nsAFn"); private static final byte[] umlautKeySig = Base64.decode( "mI0ETdvOgQEEALoI2a39TRk1HReEB6DP9Bu3ShZUce+/Oeg9RIL9aUFuCsNdhu02" + "REEHjO29Jz8daPgrnJDfFepNLD6iKKru2m9P30qnhsHMIAshO2Ozfh6wKwuHRqR3" + "L4gBDu7cCB6SLwPoD8AYG0yQSM+Do10Td87RlStxCgxpMK6R3TsRkxcFABEBAAG0" + "OlVNTEFVVFNUQVJUOsOEw6TDlsO2w5zDvMOfOlVNTEFURU5ERSA8YXNkbGFrc2Rs" + "QGFrc2RqLmNvbT6IuAQTAQIAIgUCTdvOgQIbAwYLCQgHAwIGFQgCCQoLBBYCAwEC" + "HgECF4AACgkQP8kDwm8AOFiArAP/ZXrlZJB1jFEjyBb04ckpE6F/aJuSYIXf0Yx5" + "T2eS+lA69vYuqKRC1qNROBrAn/WGNOQBFNEgGoy3F3gV5NgpIphnyIEZdZWGY2rv" + "yjunKWlioZjWc/xbSbvpvJ3Q8RyfDXBOkDEB6uF1ksimw2eJSOUTkF9AQfS5f4rT" + "5gs013G4jQRN286BAQQApVbjd8UhsQLB4TpeKn9+dDXAfikGgxDOb19XisjRiWxA" + "+bKFxu5tRt6fxXl6BGSGT7DhoVbNkcJGVQFYcbR31UGKCVYcWSL3yfz+PiVuf1UB" + "Rp44cXxxqxrLqKp1rk3dGvV4Ayy8lkk3ncDGPez6lIKvj3832yVtAzUOX1QOg9EA" + "EQEAAYifBBgBAgAJBQJN286BAhsMAAoJED/JA8JvADhYQ80D/R3TX0FBMHs/xqEh" + "tiS86XP/8pW6eMm2eaAYINxoDY3jmDMv2HFQ+YgrYXgqGr6eVGqDMNPj4W8VBoOt" + "iYW7+SWY76AAl+gmWIMm2jbN8bZXFk4jmIxpycHCrtoXX8rUk/0+se8NvbmAdMGK" + "POOoD7oxdRmJSU5hSspOCHrCwCa3"); public void test1() throws Exception { PGPPublicKeyRingCollection pubRings = new PGPPublicKeyRingCollection(pub1); int count = 0; Iterator rIt = pubRings.getKeyRings(); while (rIt.hasNext()) { PGPPublicKeyRing pgpPub = (PGPPublicKeyRing)rIt.next(); count++; int keyCount = 0; byte[] bytes = pgpPub.getEncoded(); pgpPub = new PGPPublicKeyRing(bytes, new BcKeyFingerprintCalculator()); Iterator it = pgpPub.getPublicKeys(); while (it.hasNext()) { keyCount++; PGPPublicKey pubKey = (PGPPublicKey)it.next(); Iterator sIt = pubKey.getSignatures(); while (sIt.hasNext()) { ((PGPSignature)sIt.next()).getSignatureType(); } } if (keyCount != 2) { fail("wrong number of public keys"); } } if (count != 1) { fail("wrong number of public keyrings"); } // // exact match // rIt = pubRings.getKeyRings("test (Test key) "); count = 0; while (rIt.hasNext()) { count++; rIt.next(); } if (count != 1) { fail("wrong number of public keyrings on exact match"); } // // partial match 1 expected // rIt = pubRings.getKeyRings("test", true); count = 0; while (rIt.hasNext()) { count++; rIt.next(); } if (count != 1) { fail("wrong number of public keyrings on partial match 1"); } // // partial match 0 expected // rIt = pubRings.getKeyRings("XXX", true); count = 0; while (rIt.hasNext()) { count++; rIt.next(); } if (count != 0) { fail("wrong number of public keyrings on partial match 0"); } // // case-insensitive partial match // rIt = pubRings.getKeyRings("TEST@ubicall.com", true, true); count = 0; while (rIt.hasNext()) { count++; rIt.next(); } if (count != 1) { fail("wrong number of public keyrings on case-insensitive partial match"); } PGPSecretKeyRingCollection secretRings = new PGPSecretKeyRingCollection(sec1); rIt = secretRings.getKeyRings(); count = 0; while (rIt.hasNext()) { PGPSecretKeyRing pgpSec = (PGPSecretKeyRing)rIt.next(); count++; int keyCount = 0; byte[] bytes = pgpSec.getEncoded(); pgpSec = new PGPSecretKeyRing(bytes); Iterator it = pgpSec.getSecretKeys(); while (it.hasNext()) { keyCount++; PGPSecretKey k = (PGPSecretKey)it.next(); PGPPublicKey pk = k.getPublicKey(); pk.getSignatures(); byte[] pkBytes = pk.getEncoded(); PGPPublicKeyRing pkR = new PGPPublicKeyRing(pkBytes, new BcKeyFingerprintCalculator()); } if (keyCount != 2) { fail("wrong number of secret keys"); } } if (count != 1) { fail("wrong number of secret keyrings"); } // // exact match // rIt = secretRings.getKeyRings("test (Test key) "); count = 0; while (rIt.hasNext()) { count++; rIt.next(); } if (count != 1) { fail("wrong number of secret keyrings on exact match"); } // // partial match 1 expected // rIt = secretRings.getKeyRings("test", true); count = 0; while (rIt.hasNext()) { count++; rIt.next(); } if (count != 1) { fail("wrong number of secret keyrings on partial match 1"); } // // exact match 0 expected // rIt = secretRings.getKeyRings("test", false); count = 0; while (rIt.hasNext()) { count++; rIt.next(); } if (count != 0) { fail("wrong number of secret keyrings on partial match 0"); } // // case-insensitive partial match // rIt = secretRings.getKeyRings("TEST@ubicall.com", true, true); count = 0; while (rIt.hasNext()) { count++; rIt.next(); } if (count != 1) { fail("wrong number of secret keyrings on case-insensitive partial match"); } } public void test2() throws Exception { PGPPublicKeyRingCollection pubRings = new PGPPublicKeyRingCollection(pub2); int count = 0; byte[] encRing = pubRings.getEncoded(); pubRings = new PGPPublicKeyRingCollection(encRing); Iterator rIt = pubRings.getKeyRings(); while (rIt.hasNext()) { PGPPublicKeyRing pgpPub = (PGPPublicKeyRing)rIt.next(); count++; int keyCount = 0; byte[] bytes = pgpPub.getEncoded(); pgpPub = new PGPPublicKeyRing(bytes); Iterator it = pgpPub.getPublicKeys(); while (it.hasNext()) { PGPPublicKey pk = (PGPPublicKey)it.next(); byte[] pkBytes = pk.getEncoded(); PGPPublicKeyRing pkR = new PGPPublicKeyRing(pkBytes, new BcKeyFingerprintCalculator()); keyCount++; } if (keyCount != 2) { fail("wrong number of public keys"); } } if (count != 2) { fail("wrong number of public keyrings"); } PGPSecretKeyRingCollection secretRings = new PGPSecretKeyRingCollection(sec2); rIt = secretRings.getKeyRings(); count = 0; encRing = secretRings.getEncoded(); secretRings = new PGPSecretKeyRingCollection(encRing); while (rIt.hasNext()) { PGPSecretKeyRing pgpSec = (PGPSecretKeyRing)rIt.next(); count++; int keyCount = 0; byte[] bytes = pgpSec.getEncoded(); pgpSec = new PGPSecretKeyRing(bytes, new BcKeyFingerprintCalculator()); Iterator it = pgpSec.getSecretKeys(); while (it.hasNext()) { keyCount++; PGPSecretKey k = (PGPSecretKey)it.next(); PGPPublicKey pk = k.getPublicKey(); if (pk.getKeyID() == -1413891222336124627L) { int sCount = 0; Iterator sIt = pk.getSignaturesOfType(PGPSignature.SUBKEY_BINDING); while (sIt.hasNext()) { int type = ((PGPSignature)sIt.next()).getSignatureType(); if (type != PGPSignature.SUBKEY_BINDING) { fail("failed to return correct signature type"); } sCount++; } if (sCount != 1) { fail("failed to find binding signature"); } } pk.getSignatures(); if (k.getKeyID() == -4049084404703773049L || k.getKeyID() == -1413891222336124627L) { k.extractPrivateKey(new BcPBESecretKeyDecryptorBuilder(new BcPGPDigestCalculatorProvider()).build(sec2pass1)); } else if (k.getKeyID() == -6498553574938125416L || k.getKeyID() == 59034765524361024L) { k.extractPrivateKey(new BcPBESecretKeyDecryptorBuilder(new BcPGPDigestCalculatorProvider()).build(sec2pass2)); } } if (keyCount != 2) { fail("wrong number of secret keys"); } } if (count != 2) { fail("wrong number of secret keyrings"); } } public void test3() throws Exception { PGPPublicKeyRingCollection pubRings = new PGPPublicKeyRingCollection(pub3); int count = 0; byte[] encRing = pubRings.getEncoded(); pubRings = new PGPPublicKeyRingCollection(encRing); Iterator rIt = pubRings.getKeyRings(); while (rIt.hasNext()) { PGPPublicKeyRing pgpPub = (PGPPublicKeyRing)rIt.next(); count++; int keyCount = 0; byte[] bytes = pgpPub.getEncoded(); pgpPub = new PGPPublicKeyRing(bytes, new BcKeyFingerprintCalculator()); Iterator it = pgpPub.getPublicKeys(); while (it.hasNext()) { keyCount++; PGPPublicKey pubK = (PGPPublicKey)it.next(); pubK.getSignatures(); } if (keyCount != 2) { fail("wrong number of public keys"); } } if (count != 1) { fail("wrong number of public keyrings"); } PGPSecretKeyRingCollection secretRings = new PGPSecretKeyRingCollection(sec3); rIt = secretRings.getKeyRings(); count = 0; encRing = secretRings.getEncoded(); secretRings = new PGPSecretKeyRingCollection(encRing); while (rIt.hasNext()) { PGPSecretKeyRing pgpSec = (PGPSecretKeyRing)rIt.next(); count++; int keyCount = 0; byte[] bytes = pgpSec.getEncoded(); pgpSec = new PGPSecretKeyRing(bytes); Iterator it = pgpSec.getSecretKeys(); while (it.hasNext()) { keyCount++; PGPSecretKey k = (PGPSecretKey)it.next(); k.extractPrivateKey(new BcPBESecretKeyDecryptorBuilder(new BcPGPDigestCalculatorProvider()).build(sec3pass1)); } if (keyCount != 2) { fail("wrong number of secret keys"); } } if (count != 1) { fail("wrong number of secret keyrings"); } } public void test4() throws Exception { PGPSecretKeyRingCollection secretRings = new PGPSecretKeyRingCollection(sec4); Iterator rIt = secretRings.getKeyRings(); int count = 0; byte[] encRing = secretRings.getEncoded(); secretRings = new PGPSecretKeyRingCollection(encRing); while (rIt.hasNext()) { PGPSecretKeyRing pgpSec = (PGPSecretKeyRing)rIt.next(); count++; int keyCount = 0; byte[] bytes = pgpSec.getEncoded(); pgpSec = new PGPSecretKeyRing(bytes, new BcKeyFingerprintCalculator()); Iterator it = pgpSec.getSecretKeys(); while (it.hasNext()) { keyCount++; PGPSecretKey k = (PGPSecretKey)it.next(); k.extractPrivateKey(new BcPBESecretKeyDecryptorBuilder(new BcPGPDigestCalculatorProvider()).build(sec3pass1)); } if (keyCount != 2) { fail("wrong number of secret keys"); } } if (count != 1) { fail("wrong number of secret keyrings"); } } public void test5() throws Exception { PGPPublicKeyRingCollection pubRings = new PGPPublicKeyRingCollection(pub5); int count = 0; byte[] encRing = pubRings.getEncoded(); pubRings = new PGPPublicKeyRingCollection(encRing); Iterator rIt = pubRings.getKeyRings(); while (rIt.hasNext()) { PGPPublicKeyRing pgpPub = (PGPPublicKeyRing)rIt.next(); count++; int keyCount = 0; byte[] bytes = pgpPub.getEncoded(); pgpPub = new PGPPublicKeyRing(bytes, new BcKeyFingerprintCalculator()); Iterator it = pgpPub.getPublicKeys(); while (it.hasNext()) { keyCount++; it.next(); } if (keyCount != 2) { fail("wrong number of public keys"); } } if (count != 1) { fail("wrong number of public keyrings"); } if (noIDEA()) { return; } PGPSecretKeyRingCollection secretRings = new PGPSecretKeyRingCollection(sec5); rIt = secretRings.getKeyRings(); count = 0; encRing = secretRings.getEncoded(); secretRings = new PGPSecretKeyRingCollection(encRing); while (rIt.hasNext()) { PGPSecretKeyRing pgpSec = (PGPSecretKeyRing)rIt.next(); count++; int keyCount = 0; byte[] bytes = pgpSec.getEncoded(); pgpSec = new PGPSecretKeyRing(bytes, new BcKeyFingerprintCalculator()); Iterator it = pgpSec.getSecretKeys(); while (it.hasNext()) { keyCount++; PGPSecretKey k = (PGPSecretKey)it.next(); k.extractPrivateKey(new BcPBESecretKeyDecryptorBuilder(new BcPGPDigestCalculatorProvider()).build(sec5pass1)); } if (keyCount != 2) { fail("wrong number of secret keys"); } } if (count != 1) { fail("wrong number of secret keyrings"); } } private boolean noIDEA() { return true; } public void test6() throws Exception { PGPPublicKeyRingCollection pubRings = new PGPPublicKeyRingCollection(pub6); Iterator rIt = pubRings.getKeyRings(); while (rIt.hasNext()) { PGPPublicKeyRing pgpPub = (PGPPublicKeyRing)rIt.next(); Iterator it = pgpPub.getPublicKeys(); while (it.hasNext()) { PGPPublicKey k = (PGPPublicKey)it.next(); if (k.getKeyID() == 0x5ce086b5b5a18ff4L) { int count = 0; Iterator sIt = k.getSignaturesOfType(PGPSignature.SUBKEY_REVOCATION); while (sIt.hasNext()) { PGPSignature sig = (PGPSignature)sIt.next(); count++; } if (count != 1) { fail("wrong number of revocations in test6."); } } } } byte[] encRing = pubRings.getEncoded(); } public void test7() throws Exception { PGPPublicKeyRing pgpPub = new PGPPublicKeyRing(pub7, new BcKeyFingerprintCalculator()); Iterator it = pgpPub.getPublicKeys(); PGPPublicKey masterKey = null; while (it.hasNext()) { PGPPublicKey k = (PGPPublicKey)it.next(); if (k.isMasterKey()) { masterKey = k; continue; } int count = 0; PGPSignature sig = null; Iterator sIt = k.getSignaturesOfType(PGPSignature.SUBKEY_REVOCATION); while (sIt.hasNext()) { sig = (PGPSignature)sIt.next(); count++; } if (count != 1) { fail("wrong number of revocations in test7."); } sig.init(new BcPGPContentVerifierBuilderProvider(), masterKey); if (!sig.verifyCertification(k)) { fail("failed to verify revocation certification"); } } } public void test8() throws Exception { PGPPublicKeyRingCollection pubRings = new PGPPublicKeyRingCollection(pub8); int count = 0; byte[] encRing = pubRings.getEncoded(); pubRings = new PGPPublicKeyRingCollection(encRing); Iterator rIt = pubRings.getKeyRings(); while (rIt.hasNext()) { PGPPublicKeyRing pgpPub = (PGPPublicKeyRing)rIt.next(); count++; int keyCount = 0; byte[] bytes = pgpPub.getEncoded(); pgpPub = new PGPPublicKeyRing(bytes, new BcKeyFingerprintCalculator()); Iterator it = pgpPub.getPublicKeys(); while (it.hasNext()) { keyCount++; it.next(); } if (keyCount != 2) { fail("wrong number of public keys"); } } if (count != 2) { fail("wrong number of public keyrings"); } PGPSecretKeyRingCollection secretRings = new PGPSecretKeyRingCollection(sec8); rIt = secretRings.getKeyRings(); count = 0; encRing = secretRings.getEncoded(); secretRings = new PGPSecretKeyRingCollection(encRing); while (rIt.hasNext()) { PGPSecretKeyRing pgpSec = (PGPSecretKeyRing)rIt.next(); count++; int keyCount = 0; byte[] bytes = pgpSec.getEncoded(); pgpSec = new PGPSecretKeyRing(bytes, new BcKeyFingerprintCalculator()); Iterator it = pgpSec.getSecretKeys(); while (it.hasNext()) { keyCount++; PGPSecretKey k = (PGPSecretKey)it.next(); k.extractPrivateKey(new BcPBESecretKeyDecryptorBuilder(new BcPGPDigestCalculatorProvider()).build(sec8pass)); } if (keyCount != 2) { fail("wrong number of secret keys"); } } if (count != 1) { fail("wrong number of secret keyrings"); } } public void test9() throws Exception { PGPSecretKeyRingCollection secretRings = new PGPSecretKeyRingCollection(sec9); Iterator rIt = secretRings.getKeyRings(); int count = 0; byte[] encRing = secretRings.getEncoded(); secretRings = new PGPSecretKeyRingCollection(encRing); while (rIt.hasNext()) { PGPSecretKeyRing pgpSec = (PGPSecretKeyRing)rIt.next(); count++; int keyCount = 0; byte[] bytes = pgpSec.getEncoded(); pgpSec = new PGPSecretKeyRing(bytes, new BcKeyFingerprintCalculator()); Iterator it = pgpSec.getSecretKeys(); while (it.hasNext()) { keyCount++; PGPSecretKey k = (PGPSecretKey)it.next(); PGPPrivateKey pKey = k.extractPrivateKey(new BcPBESecretKeyDecryptorBuilder(new BcPGPDigestCalculatorProvider()).build(sec9pass)); if (keyCount == 1 && pKey != null) { fail("primary secret key found, null expected"); } } if (keyCount != 3) { fail("wrong number of secret keys"); } } if (count != 1) { fail("wrong number of secret keyrings"); } } public void test10() throws Exception { PGPSecretKeyRing secretRing = new PGPSecretKeyRing(sec10, new BcKeyFingerprintCalculator()); Iterator secretKeys = secretRing.getSecretKeys(); while (secretKeys.hasNext()) { PGPPublicKey pubKey = ((PGPSecretKey)secretKeys.next()).getPublicKey(); if (pubKey.getValidDays() != 28) { fail("days wrong on secret key ring"); } if (pubKey.getValidSeconds() != 28 * 24 * 60 * 60) { fail("seconds wrong on secret key ring"); } } PGPPublicKeyRing publicRing = new PGPPublicKeyRing(pub10, new BcKeyFingerprintCalculator()); Iterator publicKeys = publicRing.getPublicKeys(); while (publicKeys.hasNext()) { PGPPublicKey pubKey = (PGPPublicKey)publicKeys.next(); if (pubKey.getValidDays() != 28) { fail("days wrong on public key ring"); } if (pubKey.getValidSeconds() != 28 * 24 * 60 * 60) { fail("seconds wrong on public key ring"); } } } public void generateTest() throws Exception { char[] passPhrase = "hello".toCharArray(); KeyPairGenerator dsaKpg = KeyPairGenerator.getInstance("DSA", "BC"); dsaKpg.initialize(512); // // this takes a while as the key generator has to generate some DSA params // before it generates the key. // KeyPair dsaKp = dsaKpg.generateKeyPair(); KeyPairGenerator elgKpg = KeyPairGenerator.getInstance("ELGAMAL", "BC"); BigInteger g = new BigInteger("153d5d6172adb43045b68ae8e1de1070b6137005686d29d3d73a7749199681ee5b212c9b96bfdcfa5b20cd5e3fd2044895d609cf9b410b7a0f12ca1cb9a428cc", 16); BigInteger p = new BigInteger("9494fec095f3b85ee286542b3836fc81a5dd0a0349b4c239dd38744d488cf8e31db8bcb7d33b41abb9e5a33cca9144b1cef332c94bf0573bf047a3aca98cdf3b", 16); ElGamalParameterSpec elParams = new ElGamalParameterSpec(p, g); elgKpg.initialize(512); // // this is quicker because we are using pregenerated parameters. // KeyPair elgKp = elgKpg.generateKeyPair(); PGPKeyPair dsaKeyPair = new PGPKeyPair(PGPPublicKey.DSA, dsaKp, new Date()); PGPKeyPair elgKeyPair = new PGPKeyPair(PGPPublicKey.ELGAMAL_ENCRYPT, elgKp, new Date()); PGPKeyRingGenerator keyRingGen = new PGPKeyRingGenerator(PGPSignature.POSITIVE_CERTIFICATION, dsaKeyPair, "test", PGPEncryptedData.AES_256, passPhrase, null, null, new SecureRandom(), "BC"); keyRingGen.addSubKey(elgKeyPair); PGPSecretKeyRing keyRing = keyRingGen.generateSecretKeyRing(); keyRing.getSecretKey().extractPrivateKey(new BcPBESecretKeyDecryptorBuilder(new BcPGPDigestCalculatorProvider()).build(passPhrase)); PGPPublicKeyRing pubRing = keyRingGen.generatePublicKeyRing(); PGPPublicKey vKey = null; PGPPublicKey sKey = null; Iterator it = pubRing.getPublicKeys(); while (it.hasNext()) { PGPPublicKey pk = (PGPPublicKey)it.next(); if (pk.isMasterKey()) { vKey = pk; } else { sKey = pk; } } Iterator sIt = sKey.getSignatures(); while (sIt.hasNext()) { PGPSignature sig = (PGPSignature)sIt.next(); if (sig.getKeyID() == vKey.getKeyID() && sig.getSignatureType() == PGPSignature.SUBKEY_BINDING) { sig.init(new BcPGPContentVerifierBuilderProvider(), vKey); if (!sig.verifyCertification(vKey, sKey)) { fail("failed to verify sub-key signature."); } } } } private void insertMasterTest() throws Exception { char[] passPhrase = "hello".toCharArray(); KeyPairGenerator rsaKpg = KeyPairGenerator.getInstance("RSA", "BC"); rsaKpg.initialize(512); // // this is quicker because we are using pregenerated parameters. // KeyPair rsaKp = rsaKpg.generateKeyPair(); PGPKeyPair rsaKeyPair1 = new PGPKeyPair(PGPPublicKey.RSA_GENERAL, rsaKp, new Date()); rsaKp = rsaKpg.generateKeyPair(); PGPKeyPair rsaKeyPair2 = new PGPKeyPair(PGPPublicKey.RSA_GENERAL, rsaKp, new Date()); PGPKeyRingGenerator keyRingGen = new PGPKeyRingGenerator(PGPSignature.POSITIVE_CERTIFICATION, rsaKeyPair1, "test", PGPEncryptedData.AES_256, passPhrase, null, null, new SecureRandom(), "BC"); PGPSecretKeyRing secRing1 = keyRingGen.generateSecretKeyRing(); PGPPublicKeyRing pubRing1 = keyRingGen.generatePublicKeyRing(); keyRingGen = new PGPKeyRingGenerator(PGPSignature.POSITIVE_CERTIFICATION, rsaKeyPair2, "test", PGPEncryptedData.AES_256, passPhrase, null, null, new SecureRandom(), "BC"); PGPSecretKeyRing secRing2 = keyRingGen.generateSecretKeyRing(); PGPPublicKeyRing pubRing2 = keyRingGen.generatePublicKeyRing(); try { PGPPublicKeyRing.insertPublicKey(pubRing1, pubRing2.getPublicKey()); fail("adding second master key (public) should throw an IllegalArgumentException"); } catch (IllegalArgumentException e) { if (!e.getMessage().equals("cannot add a master key to a ring that already has one")) { fail("wrong message in public test"); } } try { PGPSecretKeyRing.insertSecretKey(secRing1, secRing2.getSecretKey()); fail("adding second master key (secret) should throw an IllegalArgumentException"); } catch (IllegalArgumentException e) { if (!e.getMessage().equals("cannot add a master key to a ring that already has one")) { fail("wrong message in secret test"); } } } public void generateSha1Test() throws Exception { char[] passPhrase = "hello".toCharArray(); KeyPairGenerator dsaKpg = KeyPairGenerator.getInstance("DSA", "BC"); dsaKpg.initialize(512); // // this takes a while as the key generator has to generate some DSA params // before it generates the key. // KeyPair dsaKp = dsaKpg.generateKeyPair(); KeyPairGenerator elgKpg = KeyPairGenerator.getInstance("ELGAMAL", "BC"); BigInteger g = new BigInteger("153d5d6172adb43045b68ae8e1de1070b6137005686d29d3d73a7749199681ee5b212c9b96bfdcfa5b20cd5e3fd2044895d609cf9b410b7a0f12ca1cb9a428cc", 16); BigInteger p = new BigInteger("9494fec095f3b85ee286542b3836fc81a5dd0a0349b4c239dd38744d488cf8e31db8bcb7d33b41abb9e5a33cca9144b1cef332c94bf0573bf047a3aca98cdf3b", 16); ElGamalParameterSpec elParams = new ElGamalParameterSpec(p, g); elgKpg.initialize(512); // // this is quicker because we are using pregenerated parameters. // KeyPair elgKp = elgKpg.generateKeyPair(); PGPKeyPair dsaKeyPair = new PGPKeyPair(PGPPublicKey.DSA, dsaKp, new Date()); PGPKeyPair elgKeyPair = new PGPKeyPair(PGPPublicKey.ELGAMAL_ENCRYPT, elgKp, new Date()); PGPKeyRingGenerator keyRingGen = new PGPKeyRingGenerator(PGPSignature.POSITIVE_CERTIFICATION, dsaKeyPair, "test", PGPEncryptedData.AES_256, passPhrase, true, null, null, new SecureRandom(), "BC"); keyRingGen.addSubKey(elgKeyPair); PGPSecretKeyRing keyRing = keyRingGen.generateSecretKeyRing(); keyRing.getSecretKey().extractPrivateKey(new BcPBESecretKeyDecryptorBuilder(new BcPGPDigestCalculatorProvider()).build(passPhrase)); PGPPublicKeyRing pubRing = keyRingGen.generatePublicKeyRing(); PGPPublicKey vKey = null; PGPPublicKey sKey = null; Iterator it = pubRing.getPublicKeys(); while (it.hasNext()) { PGPPublicKey pk = (PGPPublicKey)it.next(); if (pk.isMasterKey()) { vKey = pk; } else { sKey = pk; } } Iterator sIt = sKey.getSignatures(); while (sIt.hasNext()) { PGPSignature sig = (PGPSignature)sIt.next(); if (sig.getKeyID() == vKey.getKeyID() && sig.getSignatureType() == PGPSignature.SUBKEY_BINDING) { sig.init(new BcPGPContentVerifierBuilderProvider(), vKey); if (!sig.verifyCertification(vKey, sKey)) { fail("failed to verify sub-key signature."); } } } } private void test11() throws Exception { PGPPublicKeyRing pubRing = new PGPPublicKeyRing(subKeyBindingKey, new BcKeyFingerprintCalculator()); Iterator it = pubRing.getPublicKeys(); while (it.hasNext()) { PGPPublicKey key = (PGPPublicKey)it.next(); if (key.getValidSeconds() != 0) { fail("expiration time non-zero"); } } } private void rewrapTest() throws Exception { SecureRandom rand = new SecureRandom(); // Read the secret key rings PGPSecretKeyRingCollection privRings = new PGPSecretKeyRingCollection( new ByteArrayInputStream(rewrapKey)); Iterator rIt = privRings.getKeyRings(); if (rIt.hasNext()) { PGPSecretKeyRing pgpPriv = (PGPSecretKeyRing)rIt.next(); Iterator it = pgpPriv.getSecretKeys(); while (it.hasNext()) { PGPSecretKey pgpKey = (PGPSecretKey)it.next(); // re-encrypt the key with an empty password pgpPriv = PGPSecretKeyRing.removeSecretKey(pgpPriv, pgpKey); pgpKey = PGPSecretKey.copyWithNewPassword( pgpKey, new BcPBESecretKeyDecryptorBuilder(new BcPGPDigestCalculatorProvider()).build(rewrapPass), null); pgpPriv = PGPSecretKeyRing.insertSecretKey(pgpPriv, pgpKey); // this should succeed PGPPrivateKey privTmp = pgpKey.extractPrivateKey(null); } } } private void testPublicKeyRingWithX509() throws Exception { checkPublicKeyRingWithX509(pubWithX509); PGPPublicKeyRing pubRing = new PGPPublicKeyRing(pubWithX509, new BcKeyFingerprintCalculator()); checkPublicKeyRingWithX509(pubRing.getEncoded()); } private void testSecretKeyRingWithPersonalCertificate() throws Exception { checkSecretKeyRingWithPersonalCertificate(secWithPersonalCertificate); PGPSecretKeyRingCollection secRing = new PGPSecretKeyRingCollection(secWithPersonalCertificate); checkSecretKeyRingWithPersonalCertificate(secRing.getEncoded()); } private void testUmlaut() throws Exception { PGPPublicKeyRing pubRing = new PGPPublicKeyRing(umlautKeySig, new BcKeyFingerprintCalculator()); PGPPublicKey pub = pubRing.getPublicKey(); String userID = (String)pub.getUserIDs().next(); for (Iterator it = pub.getSignatures(); it.hasNext();) { PGPSignature sig = (PGPSignature)it.next(); if (sig.getSignatureType() == PGPSignature.POSITIVE_CERTIFICATION) { sig.init(new BcPGPContentVerifierBuilderProvider(), pub); if (!sig.verifyCertification(userID, pub)) { fail("failed UTF8 userID test"); } } } // // this is quicker because we are using pregenerated parameters. // KeyPairGenerator rsaKpg = KeyPairGenerator.getInstance("RSA", "BC"); KeyPair rsaKp = rsaKpg.generateKeyPair(); PGPKeyPair rsaKeyPair1 = new PGPKeyPair(PGPPublicKey.RSA_GENERAL, rsaKp, new Date()); rsaKp = rsaKpg.generateKeyPair(); PGPKeyPair rsaKeyPair2 = new PGPKeyPair(PGPPublicKey.RSA_GENERAL, rsaKp, new Date()); char[] passPhrase = "passwd".toCharArray(); PGPKeyRingGenerator keyRingGen = new PGPKeyRingGenerator(PGPSignature.POSITIVE_CERTIFICATION, rsaKeyPair1, userID, PGPEncryptedData.AES_256, passPhrase, null, null, new SecureRandom(), "BC"); PGPPublicKeyRing pubRing1 = keyRingGen.generatePublicKeyRing(); pub = pubRing1.getPublicKey(); for (Iterator it = pub.getSignatures(); it.hasNext();) { PGPSignature sig = (PGPSignature)it.next(); if (sig.getSignatureType() == PGPSignature.POSITIVE_CERTIFICATION) { sig.init(new BcPGPContentVerifierBuilderProvider(), pub); if (!sig.verifyCertification(userID, pub)) { fail("failed UTF8 userID creation test"); } } } } private void checkSecretKeyRingWithPersonalCertificate(byte[] keyRing) throws Exception { PGPSecretKeyRingCollection secCol = new PGPSecretKeyRingCollection(keyRing); int count = 0; for (Iterator rIt = secCol.getKeyRings(); rIt.hasNext();) { PGPSecretKeyRing ring = (PGPSecretKeyRing)rIt.next(); for (Iterator it = ring.getExtraPublicKeys(); it.hasNext();) { it.next(); count++; } } if (count != 1) { fail("personal certificate data subkey not found - count = " + count); } } private void checkPublicKeyRingWithX509(byte[] keyRing) throws Exception { PGPPublicKeyRing pubRing = new PGPPublicKeyRing(keyRing, new BcKeyFingerprintCalculator()); Iterator it = pubRing.getPublicKeys(); if (it.hasNext()) { PGPPublicKey key = (PGPPublicKey)it.next(); Iterator sIt = key.getSignatures(); if (sIt.hasNext()) { PGPSignature sig = (PGPSignature)sIt.next(); if (sig.getKeyAlgorithm() != 100) { fail("experimental signature not found"); } if (!areEqual(sig.getSignature(), Hex.decode("000101"))) { fail("experimental encoding check failed"); } } else { fail("no signature found"); } } else { fail("no key found"); } } public void performTest() throws Exception { try { test1(); test2(); test3(); test4(); test5(); test6(); // test7(); test8(); test9(); test10(); test11(); generateTest(); generateSha1Test(); rewrapTest(); testPublicKeyRingWithX509(); testSecretKeyRingWithPersonalCertificate(); insertMasterTest(); testUmlaut(); } catch (PGPException e) { if (e.getUnderlyingException() != null) { Exception ex = e.getUnderlyingException(); fail("exception: " + ex, ex); } else { fail("exception: " + e, e); } } } public String getName() { return "BcPGPKeyRingTest"; } public static void main( String[] args) { Security.addProvider(new BouncyCastleProvider()); runTest(new BcPGPKeyRingTest()); } } bouncycastle-1.49.orig/jdk1.1/org/bouncycastle/openpgp/examples/0000755000175000017500000000000012152033551024166 5ustar ebourgebourgbouncycastle-1.49.orig/jdk1.1/org/bouncycastle/openpgp/examples/DetachedSignatureProcessor.java0000644000175000017500000001470311705655644032341 0ustar ebourgebourgpackage org.bouncycastle.openpgp.examples; import java.io.BufferedInputStream; import java.io.BufferedOutputStream; import java.io.FileInputStream; import java.io.FileOutputStream; import java.io.IOException; import java.io.InputStream; import java.io.OutputStream; import java.security.GeneralSecurityException; import java.security.SignatureException; import java.security.Security; import org.bouncycastle.bcpg.ArmoredOutputStream; import org.bouncycastle.bcpg.BCPGOutputStream; import org.bouncycastle.jce.provider.BouncyCastleProvider; import org.bouncycastle.openpgp.PGPCompressedData; import org.bouncycastle.openpgp.PGPException; import org.bouncycastle.openpgp.PGPObjectFactory; import org.bouncycastle.openpgp.PGPPrivateKey; import org.bouncycastle.openpgp.PGPPublicKey; import org.bouncycastle.openpgp.PGPPublicKeyRingCollection; import org.bouncycastle.openpgp.PGPSecretKey; import org.bouncycastle.openpgp.PGPSignature; import org.bouncycastle.openpgp.PGPSignatureGenerator; import org.bouncycastle.openpgp.PGPSignatureList; import org.bouncycastle.openpgp.PGPUtil; import org.bouncycastle.openpgp.operator.jcajce.JcaPGPContentSignerBuilder; import org.bouncycastle.openpgp.operator.jcajce.JcaPGPContentVerifierBuilderProvider; import org.bouncycastle.openpgp.operator.jcajce.JcePBESecretKeyDecryptorBuilder; /** * A simple utility class that creates seperate signatures for files and verifies them. *

    * To sign a file: DetachedSignatureProcessor -s [-a] fileName secretKey passPhrase.
    * If -a is specified the output file will be "ascii-armored". *

    * To decrypt: DetachedSignatureProcessor -v fileName signatureFile publicKeyFile. *

    * Note: this example will silently overwrite files. * It also expects that a single pass phrase * will have been used. */ public class DetachedSignatureProcessor { private static void verifySignature( String fileName, String inputFileName, String keyFileName) throws GeneralSecurityException, IOException, PGPException, SignatureException { InputStream in = new BufferedInputStream(new FileInputStream(inputFileName)); InputStream keyIn = new BufferedInputStream(new FileInputStream(keyFileName)); verifySignature(fileName, in, keyIn); keyIn.close(); in.close(); } /* * verify the signature in in against the file fileName. */ private static void verifySignature( String fileName, InputStream in, InputStream keyIn) throws GeneralSecurityException, IOException, PGPException, SignatureException { in = PGPUtil.getDecoderStream(in); PGPObjectFactory pgpFact = new PGPObjectFactory(in); PGPSignatureList p3; Object o = pgpFact.nextObject(); if (o instanceof PGPCompressedData) { PGPCompressedData c1 = (PGPCompressedData)o; pgpFact = new PGPObjectFactory(c1.getDataStream()); p3 = (PGPSignatureList)pgpFact.nextObject(); } else { p3 = (PGPSignatureList)o; } PGPPublicKeyRingCollection pgpPubRingCollection = new PGPPublicKeyRingCollection(PGPUtil.getDecoderStream(keyIn)); InputStream dIn = new BufferedInputStream(new FileInputStream(fileName)); PGPSignature sig = p3.get(0); PGPPublicKey key = pgpPubRingCollection.getPublicKey(sig.getKeyID()); sig.init(new JcaPGPContentVerifierBuilderProvider().setProvider("BC"), key); int ch; while ((ch = dIn.read()) >= 0) { sig.update((byte)ch); } dIn.close(); if (sig.verify()) { System.out.println("signature verified."); } else { System.out.println("signature verification failed."); } } private static void createSignature( String inputFileName, String keyFileName, String outputFileName, char[] pass, boolean armor) throws GeneralSecurityException, IOException, PGPException, SignatureException { InputStream keyIn = new BufferedInputStream(new FileInputStream(keyFileName)); OutputStream out = new BufferedOutputStream(new FileOutputStream(outputFileName)); createSignature(inputFileName, keyIn, out, pass, armor); out.close(); keyIn.close(); } private static void createSignature( String fileName, InputStream keyIn, OutputStream out, char[] pass, boolean armor) throws GeneralSecurityException, IOException, PGPException, SignatureException { if (armor) { out = new ArmoredOutputStream(out); } PGPSecretKey pgpSec = PGPExampleUtil.readSecretKey(keyIn); PGPPrivateKey pgpPrivKey = pgpSec.extractPrivateKey(new JcePBESecretKeyDecryptorBuilder().setProvider("BC").build(pass)); PGPSignatureGenerator sGen = new PGPSignatureGenerator(new JcaPGPContentSignerBuilder(pgpSec.getPublicKey().getAlgorithm(), PGPUtil.SHA1).setProvider("BC")); sGen.init(PGPSignature.BINARY_DOCUMENT, pgpPrivKey); BCPGOutputStream bOut = new BCPGOutputStream(out); InputStream fIn = new BufferedInputStream(new FileInputStream(fileName)); int ch; while ((ch = fIn.read()) >= 0) { sGen.update((byte)ch); } fIn.close(); sGen.generate().encode(bOut); if (armor) { out.close(); } } public static void main( String[] args) throws Exception { Security.addProvider(new BouncyCastleProvider()); if (args[0].equals("-s")) { if (args[1].equals("-a")) { createSignature(args[2], args[3], args[2] + ".asc", args[4].toCharArray(), true); } else { createSignature(args[1], args[2], args[1] + ".bpg", args[3].toCharArray(), false); } } else if (args[0].equals("-v")) { verifySignature(args[1], args[2], args[3]); } else { System.err.println("usage: DetachedSignatureProcessor [-s [-a] file keyfile passPhrase]|[-v file sigFile keyFile]"); } } } bouncycastle-1.49.orig/jdk1.1/org/bouncycastle/openpgp/operator/0000755000175000017500000000000012152033551024203 5ustar ebourgebourgbouncycastle-1.49.orig/jdk1.1/org/bouncycastle/openpgp/operator/jcajce/0000755000175000017500000000000012152033551025422 5ustar ebourgebourg././@LongLink0000000000000000000000000000014700000000000011567 Lustar rootrootbouncycastle-1.49.orig/jdk1.1/org/bouncycastle/openpgp/operator/jcajce/JcaPGPContentSignerBuilder.javabouncycastle-1.49.orig/jdk1.1/org/bouncycastle/openpgp/operator/jcajce/JcaPGPContentSignerBuilder.ja0000644000175000017500000001057011724032240033015 0ustar ebourgebourgpackage org.bouncycastle.openpgp.operator.jcajce; import java.io.OutputStream; import java.security.InvalidKeyException; import java.security.Provider; import java.security.SecureRandom; import java.security.Signature; import java.security.SignatureException; import org.bouncycastle.jcajce.DefaultJcaJceHelper; import org.bouncycastle.jcajce.NamedJcaJceHelper; import org.bouncycastle.jcajce.ProviderJcaJceHelper; import org.bouncycastle.openpgp.PGPException; import org.bouncycastle.openpgp.PGPPrivateKey; import org.bouncycastle.openpgp.operator.PGPContentSigner; import org.bouncycastle.openpgp.operator.PGPContentSignerBuilder; import org.bouncycastle.openpgp.operator.PGPDigestCalculator; import org.bouncycastle.util.io.TeeOutputStream; public class JcaPGPContentSignerBuilder implements PGPContentSignerBuilder { private OperatorHelper helper = new OperatorHelper(new DefaultJcaJceHelper()); private JcaPGPDigestCalculatorProviderBuilder digestCalculatorProviderBuilder = new JcaPGPDigestCalculatorProviderBuilder(); private JcaPGPKeyConverter keyConverter = new JcaPGPKeyConverter(); private int hashAlgorithm; private SecureRandom random; private int keyAlgorithm; public JcaPGPContentSignerBuilder(int keyAlgorithm, int hashAlgorithm) { this.keyAlgorithm = keyAlgorithm; this.hashAlgorithm = hashAlgorithm; } public JcaPGPContentSignerBuilder setSecureRandom(SecureRandom random) { this.random = random; return this; } public JcaPGPContentSignerBuilder setProvider(Provider provider) { this.helper = new OperatorHelper(new ProviderJcaJceHelper(provider)); keyConverter.setProvider(provider); digestCalculatorProviderBuilder.setProvider(provider); return this; } public JcaPGPContentSignerBuilder setProvider(String providerName) { this.helper = new OperatorHelper(new NamedJcaJceHelper(providerName)); keyConverter.setProvider(providerName); digestCalculatorProviderBuilder.setProvider(providerName); return this; } public JcaPGPContentSignerBuilder setDigestProvider(Provider provider) { digestCalculatorProviderBuilder.setProvider(provider); return this; } public JcaPGPContentSignerBuilder setDigestProvider(String providerName) { digestCalculatorProviderBuilder.setProvider(providerName); return this; } public PGPContentSigner build(final int signatureType, final PGPPrivateKey privateKey) throws PGPException { final PGPDigestCalculator digestCalculator = digestCalculatorProviderBuilder.build().get(hashAlgorithm); final Signature signature = helper.createSignature(keyAlgorithm, hashAlgorithm); try { if (random != null) { signature.initSign(keyConverter.getPrivateKey(privateKey)); } else { signature.initSign(keyConverter.getPrivateKey(privateKey)); } } catch (InvalidKeyException e) { throw new PGPException("invalid key.", e); } return new PGPContentSigner() { public int getType() { return signatureType; } public int getHashAlgorithm() { return hashAlgorithm; } public int getKeyAlgorithm() { return keyAlgorithm; } public long getKeyID() { return privateKey.getKeyID(); } public OutputStream getOutputStream() { return new TeeOutputStream(new SignatureOutputStream(signature), digestCalculator.getOutputStream()); } public byte[] getSignature() { try { return signature.sign(); } catch (SignatureException e) { // TODO: need a specific runtime exception for PGP operators. throw new IllegalStateException("unable to create signature"); } } public byte[] getDigest() { return digestCalculator.getDigest(); } }; } } bouncycastle-1.49.orig/jdk1.1/org/bouncycastle/openpgp/operator/jcajce/OperatorHelper.java0000644000175000017500000001370211724024772031234 0ustar ebourgebourgpackage org.bouncycastle.openpgp.operator.jcajce; import java.io.InputStream; import java.security.GeneralSecurityException; import java.security.KeyFactory; import java.security.MessageDigest; import java.security.NoSuchAlgorithmException; import java.security.NoSuchProviderException; import java.security.Signature; import javax.crypto.Cipher; import javax.crypto.CipherInputStream; import javax.crypto.SecretKey; import javax.crypto.spec.IvParameterSpec; import javax.crypto.spec.SecretKeySpec; import org.bouncycastle.bcpg.PublicKeyAlgorithmTags; import org.bouncycastle.jcajce.JcaJceHelper; import org.bouncycastle.openpgp.PGPException; import org.bouncycastle.openpgp.PGPPublicKey; import org.bouncycastle.openpgp.operator.PGPDataDecryptor; import org.bouncycastle.openpgp.operator.PGPDigestCalculator; class OperatorHelper { private JcaJceHelper helper; OperatorHelper(JcaJceHelper helper) { this.helper = helper; } MessageDigest createDigest(int algorithm) throws GeneralSecurityException, PGPException { try { MessageDigest dig; dig = helper.createDigest(PGPUtil.getDigestName(algorithm)); return dig; } catch (NoSuchProviderException e) { throw new GeneralSecurityException(e.toString()); } catch (NoSuchAlgorithmException e) { throw new GeneralSecurityException(e.toString()); } } KeyFactory createKeyFactory(String algorithm) throws GeneralSecurityException, PGPException { try { return helper.createKeyFactory(algorithm); } catch (NoSuchProviderException e) { throw new GeneralSecurityException(e.toString()); } catch (NoSuchAlgorithmException e) { throw new GeneralSecurityException(e.toString()); } } PGPDataDecryptor createDataDecryptor(boolean withIntegrityPacket, int encAlgorithm, byte[] key) throws PGPException { try { SecretKey secretKey = new SecretKeySpec(key, PGPUtil.getSymmetricCipherName(encAlgorithm)); final Cipher c = createStreamCipher(encAlgorithm, withIntegrityPacket); byte[] iv = new byte[c.getBlockSize()]; c.init(Cipher.DECRYPT_MODE, secretKey, new IvParameterSpec(iv)); return new PGPDataDecryptor() { public InputStream getInputStream(InputStream in) { return new CipherInputStream(in, c); } public int getBlockSize() { return c.getBlockSize(); } public PGPDigestCalculator getIntegrityCalculator() { return new SHA1PGPDigestCalculator(); } }; } catch (PGPException e) { throw e; } catch (Exception e) { throw new PGPException("Exception creating cipher", e); } } Cipher createStreamCipher(int encAlgorithm, boolean withIntegrityPacket) throws PGPException { String mode = (withIntegrityPacket) ? "CFB" : "OpenPGPCFB"; String cName = PGPUtil.getSymmetricCipherName(encAlgorithm) + "/" + mode + "/NoPadding"; return createCipher(cName); } Cipher createCipher(String cipherName) throws PGPException { try { return helper.createCipher(cipherName); } catch (NoSuchProviderException e) { throw new PGPException("cannot create cipher: " + e.getMessage(), e); } catch (NoSuchAlgorithmException e) { throw new PGPException("cannot create cipher: " + e.getMessage(), e); } catch (GeneralSecurityException e) { throw new PGPException("cannot create cipher: " + e.getMessage(), e); } } Cipher createPublicKeyCipher(int encAlgorithm) throws PGPException { switch (encAlgorithm) { case PGPPublicKey.RSA_ENCRYPT: case PGPPublicKey.RSA_GENERAL: return createCipher("RSA/ECB/PKCS1Padding"); case PGPPublicKey.ELGAMAL_ENCRYPT: case PGPPublicKey.ELGAMAL_GENERAL: return createCipher("ElGamal/ECB/PKCS1Padding"); case PGPPublicKey.DSA: throw new PGPException("Can't use DSA for encryption."); case PGPPublicKey.ECDSA: throw new PGPException("Can't use ECDSA for encryption."); default: throw new PGPException("unknown asymmetric algorithm: " + encAlgorithm); } } private Signature createSignature(String cipherName) throws PGPException { try { return helper.createSignature(cipherName); } catch (NoSuchProviderException e) { throw new PGPException("cannot create cipher: " + e.getMessage(), e); } catch (NoSuchAlgorithmException e) { throw new PGPException("cannot create cipher: " + e.getMessage(), e); } } public Signature createSignature(int keyAlgorithm, int hashAlgorithm) throws PGPException { String encAlg; switch (keyAlgorithm) { case PublicKeyAlgorithmTags.RSA_GENERAL: case PublicKeyAlgorithmTags.RSA_SIGN: encAlg = "RSA"; break; case PublicKeyAlgorithmTags.DSA: encAlg = "DSA"; break; case PublicKeyAlgorithmTags.ELGAMAL_ENCRYPT: // in some malformed cases. case PublicKeyAlgorithmTags.ELGAMAL_GENERAL: encAlg = "ElGamal"; break; default: throw new PGPException("unknown algorithm tag in signature:" + keyAlgorithm); } return createSignature(PGPUtil.getDigestName(hashAlgorithm) + "with" + encAlg); } } bouncycastle-1.49.orig/jdk1.1/org/bouncycastle/crypto/0000755000175000017500000000000012152033551022220 5ustar ebourgebourgbouncycastle-1.49.orig/jdk1.1/org/bouncycastle/crypto/tls/0000755000175000017500000000000012152033551023022 5ustar ebourgebourgbouncycastle-1.49.orig/jdk1.1/org/bouncycastle/crypto/tls/DTLSReliableHandshake.java0000644000175000017500000003340312147306502027710 0ustar ebourgebourgpackage org.bouncycastle.crypto.tls; import java.io.ByteArrayOutputStream; import java.io.IOException; import java.util.Enumeration; import java.util.Hashtable; import java.util.Vector; import org.bouncycastle.util.Integers; class DTLSReliableHandshake { private final static int MAX_RECEIVE_AHEAD = 10; private DTLSRecordLayer recordLayer; private TlsHandshakeHash hash = new DeferredHash(); private Hashtable currentInboundFlight = new Hashtable(); private Hashtable previousInboundFlight = null; private Vector outboundFlight = new Vector(); private boolean sending = true; private int message_seq = 0, next_receive_seq = 0; DTLSReliableHandshake(TlsContext context, DTLSRecordLayer transport) { this.recordLayer = transport; this.hash.init(context); } void notifyHelloComplete() { this.hash = this.hash.commit(); } byte[] getCurrentHash() { TlsHandshakeHash copyOfHash = hash.fork(); byte[] result = new byte[copyOfHash.getDigestSize()]; copyOfHash.doFinal(result, 0); return result; } void sendMessage(short msg_type, byte[] body) throws IOException { if (!sending) { checkInboundFlight(); sending = true; outboundFlight.removeAllElements(); } Message message = new Message(message_seq++, msg_type, body); outboundFlight.addElement(message); writeMessage(message); updateHandshakeMessagesDigest(message); } Message receiveMessage() throws IOException { if (sending) { sending = false; prepareInboundFlight(); } // Check if we already have the next message waiting { DTLSReassembler next = (DTLSReassembler)currentInboundFlight.get(Integers.valueOf(next_receive_seq)); if (next != null) { byte[] body = next.getBodyIfComplete(); if (body != null) { previousInboundFlight = null; return updateHandshakeMessagesDigest(new Message(next_receive_seq++, next.getType(), body)); } } } byte[] buf = null; // TODO Check the conditions under which we should reset this int readTimeoutMillis = 1000; for (; ; ) { int receiveLimit = recordLayer.getReceiveLimit(); if (buf == null || buf.length < receiveLimit) { buf = new byte[receiveLimit]; } // TODO Handle records containing multiple handshake messages try { for (; ; ) { int received = recordLayer.receive(buf, 0, receiveLimit, readTimeoutMillis); if (received < 0) { break; } if (received < 12) { continue; } int fragment_length = TlsUtils.readUint24(buf, 9); if (received != (fragment_length + 12)) { continue; } int seq = TlsUtils.readUint16(buf, 4); if (seq > (next_receive_seq + MAX_RECEIVE_AHEAD)) { continue; } short msg_type = TlsUtils.readUint8(buf, 0); int length = TlsUtils.readUint24(buf, 1); int fragment_offset = TlsUtils.readUint24(buf, 6); if (fragment_offset + fragment_length > length) { continue; } if (seq < next_receive_seq) { /* * NOTE: If we receive the previous flight of incoming messages in full * again, retransmit our last flight */ if (previousInboundFlight != null) { DTLSReassembler reassembler = (DTLSReassembler)previousInboundFlight.get(Integers .valueOf(seq)); if (reassembler != null) { reassembler.contributeFragment(msg_type, length, buf, 12, fragment_offset, fragment_length); if (checkAll(previousInboundFlight)) { resendOutboundFlight(); /* * TODO[DTLS] implementations SHOULD back off handshake packet * size during the retransmit backoff. */ readTimeoutMillis = Math.min(readTimeoutMillis * 2, 60000); resetAll(previousInboundFlight); } } } } else { DTLSReassembler reassembler = (DTLSReassembler)currentInboundFlight.get(Integers.valueOf(seq)); if (reassembler == null) { reassembler = new DTLSReassembler(msg_type, length); currentInboundFlight.put(Integers.valueOf(seq), reassembler); } reassembler.contributeFragment(msg_type, length, buf, 12, fragment_offset, fragment_length); if (seq == next_receive_seq) { byte[] body = reassembler.getBodyIfComplete(); if (body != null) { previousInboundFlight = null; return updateHandshakeMessagesDigest(new Message(next_receive_seq++, reassembler.getType(), body)); } } } } } catch (IOException e) { // NOTE: Assume this is a timeout for the moment } resendOutboundFlight(); /* * TODO[DTLS] implementations SHOULD back off handshake packet size during the * retransmit backoff. */ readTimeoutMillis = Math.min(readTimeoutMillis * 2, 60000); } } void finish() { DTLSHandshakeRetransmit retransmit = null; if (!sending) { checkInboundFlight(); } else if (currentInboundFlight != null) { /* * RFC 6347 4.2.4. In addition, for at least twice the default MSL defined for [TCP], * when in the FINISHED state, the node that transmits the last flight (the server in an * ordinary handshake or the client in a resumed handshake) MUST respond to a retransmit * of the peer's last flight with a retransmit of the last flight. */ retransmit = new DTLSHandshakeRetransmit() { public void receivedHandshakeRecord(int epoch, byte[] buf, int off, int len) throws IOException { /* * TODO Need to handle the case where the previous inbound flight contains * messages from two epochs. */ if (len < 12) { return; } int fragment_length = TlsUtils.readUint24(buf, off + 9); if (len != (fragment_length + 12)) { return; } int seq = TlsUtils.readUint16(buf, off + 4); if (seq >= next_receive_seq) { return; } short msg_type = TlsUtils.readUint8(buf, off); // TODO This is a hack that only works until we try to support renegotiation int expectedEpoch = msg_type == HandshakeType.finished ? 1 : 0; if (epoch != expectedEpoch) { return; } int length = TlsUtils.readUint24(buf, off + 1); int fragment_offset = TlsUtils.readUint24(buf, off + 6); if (fragment_offset + fragment_length > length) { return; } DTLSReassembler reassembler = (DTLSReassembler)currentInboundFlight.get(Integers.valueOf(seq)); if (reassembler != null) { reassembler.contributeFragment(msg_type, length, buf, off + 12, fragment_offset, fragment_length); if (checkAll(currentInboundFlight)) { resendOutboundFlight(); resetAll(currentInboundFlight); } } } }; } recordLayer.handshakeSuccessful(retransmit); } void resetHandshakeMessagesDigest() { hash.reset(); } /** * Check that there are no "extra" messages left in the current inbound flight */ private void checkInboundFlight() { Enumeration e = currentInboundFlight.keys(); while (e.hasMoreElements()) { Integer key = (Integer)e.nextElement(); if (key.intValue() >= next_receive_seq) { // TODO Should this be considered an error? } } } private void prepareInboundFlight() { resetAll(currentInboundFlight); previousInboundFlight = currentInboundFlight; currentInboundFlight = new Hashtable(); } private void resendOutboundFlight() throws IOException { recordLayer.resetWriteEpoch(); for (int i = 0; i < outboundFlight.size(); ++i) { writeMessage((Message)outboundFlight.elementAt(i)); } } private Message updateHandshakeMessagesDigest(Message message) throws IOException { if (message.getType() != HandshakeType.hello_request) { byte[] body = message.getBody(); byte[] buf = new byte[12]; TlsUtils.writeUint8(message.getType(), buf, 0); TlsUtils.writeUint24(body.length, buf, 1); TlsUtils.writeUint16(message.getSeq(), buf, 4); TlsUtils.writeUint24(0, buf, 6); TlsUtils.writeUint24(body.length, buf, 9); hash.update(buf, 0, buf.length); hash.update(body, 0, body.length); } return message; } private void writeMessage(Message message) throws IOException { int sendLimit = recordLayer.getSendLimit(); int fragmentLimit = sendLimit - 12; // TODO Support a higher minimum fragment size? if (fragmentLimit < 1) { // TODO Should we be throwing an exception here? throw new TlsFatalAlert(AlertDescription.internal_error); } int length = message.getBody().length; // NOTE: Must still send a fragment if body is empty int fragment_offset = 0; do { int fragment_length = Math.min(length - fragment_offset, fragmentLimit); writeHandshakeFragment(message, fragment_offset, fragment_length); fragment_offset += fragment_length; } while (fragment_offset < length); } private void writeHandshakeFragment(Message message, int fragment_offset, int fragment_length) throws IOException { ByteArrayOutputStream buf = new ByteArrayOutputStream(); TlsUtils.writeUint8(message.getType(), buf); TlsUtils.writeUint24(message.getBody().length, buf); TlsUtils.writeUint16(message.getSeq(), buf); TlsUtils.writeUint24(fragment_offset, buf); TlsUtils.writeUint24(fragment_length, buf); buf.write(message.getBody(), fragment_offset, fragment_length); byte[] fragment = buf.toByteArray(); recordLayer.send(fragment, 0, fragment.length); } private static boolean checkAll(Hashtable inboundFlight) { Enumeration e = inboundFlight.elements(); while (e.hasMoreElements()) { if (((DTLSReassembler)e.nextElement()).getBodyIfComplete() == null) { return false; } } return true; } private static void resetAll(Hashtable inboundFlight) { Enumeration e = inboundFlight.elements(); while (e.hasMoreElements()) { ((DTLSReassembler)e.nextElement()).reset(); } } static class Message { private final int message_seq; private final short msg_type; private final byte[] body; private Message(int message_seq, short msg_type, byte[] body) { this.message_seq = message_seq; this.msg_type = msg_type; this.body = body; } public int getSeq() { return message_seq; } public short getType() { return msg_type; } public byte[] getBody() { return body; } } } bouncycastle-1.49.orig/jdk1.1/org/bouncycastle/crypto/tls/UDPTransport.java0000644000175000017500000000531112147306502026235 0ustar ebourgebourgpackage org.bouncycastle.crypto.tls; import java.io.IOException; import java.net.DatagramPacket; import java.net.DatagramSocket; public class UDPTransport implements DatagramTransport { private final static int MIN_IP_OVERHEAD = 20; private final static int MAX_IP_OVERHEAD = MIN_IP_OVERHEAD + 64; private final static int UDP_OVERHEAD = 8; private final DatagramSocket socket; private final int receiveLimit, sendLimit; public UDPTransport(DatagramSocket socket, int mtu) throws IOException { // // In 1.3 and earlier sockets were bound and connected during creation // //if (!socket.isBound() || !socket.isConnected()) //{ // throw new IllegalArgumentException("'socket' must be bound and connected"); //} this.socket = socket; // NOTE: As of JDK 1.6, can use NetworkInterface.getMTU this.receiveLimit = mtu - MIN_IP_OVERHEAD - UDP_OVERHEAD; this.sendLimit = mtu - MAX_IP_OVERHEAD - UDP_OVERHEAD; } public int getReceiveLimit() { return receiveLimit; } public int getSendLimit() { // TODO[DTLS] Implement Path-MTU discovery? return sendLimit; } public int receive(byte[] buf, int off, int len, int waitMillis) throws IOException { socket.setSoTimeout(waitMillis); if (off == 0) { DatagramPacket packet = new DatagramPacket(buf, len); socket.receive(packet); return packet.getLength(); } else { byte[] rv = new byte[len]; DatagramPacket packet = new DatagramPacket(rv, len); socket.receive(packet); System.arraycopy(rv, 0, buf, off, packet.getLength()); return packet.getLength(); } } public void send(byte[] buf, int off, int len) throws IOException { if (len > getSendLimit()) { /* * RFC 4347 4.1.1. "If the application attempts to send a record larger than the MTU, * the DTLS implementation SHOULD generate an error, thus avoiding sending a packet * which will be fragmented." */ // TODO Exception } if (off == 0) { DatagramPacket packet = new DatagramPacket(buf, len); socket.send(packet); } else { byte[] data = new byte[len]; System.arraycopy(buf, off, data, 0, len); DatagramPacket packet = new DatagramPacket(data, len); socket.send(packet); } } public void close() throws IOException { socket.close(); } } bouncycastle-1.49.orig/jdk1.1/org/bouncycastle/crypto/tls/DTLSReassembler.java0000644000175000017500000000645412147306502026634 0ustar ebourgebourgpackage org.bouncycastle.crypto.tls; import java.util.Vector; class DTLSReassembler { private short msg_type; private byte[] body; private Vector missing = new Vector(); DTLSReassembler(short msg_type, int length) { this.msg_type = msg_type; this.body = new byte[length]; this.missing.addElement(new Range(0, length)); } short getType() { return msg_type; } byte[] getBodyIfComplete() { return missing.isEmpty() ? body : null; } void contributeFragment(short msg_type, int length, byte[] buf, int off, int fragment_offset, int fragment_length) { int fragment_end = fragment_offset + fragment_length; if (this.msg_type != msg_type || this.body.length != length || fragment_end > length) { return; } if (fragment_length == 0) { // NOTE: Empty messages still require an empty fragment to complete it if (fragment_offset == 0 && !missing.isEmpty()) { Range firstRange = (Range)missing.firstElement(); if (firstRange.getEnd() == 0) { missing.removeElementAt(0); } } return; } for (int i = 0; i < missing.size(); ++i) { Range range = (Range)missing.elementAt(i); if (range.getStart() >= fragment_end) { break; } if (range.getEnd() > fragment_offset) { int copyStart = Math.max(range.getStart(), fragment_offset); int copyEnd = Math.min(range.getEnd(), fragment_end); int copyLength = copyEnd - copyStart; System.arraycopy(buf, off + copyStart - fragment_offset, body, copyStart, copyLength); if (copyStart == range.getStart()) { if (copyEnd == range.getEnd()) { missing.removeElementAt(i--); } else { range.setStart(copyEnd); } } else { if (copyEnd == range.getEnd()) { range.setEnd(copyStart); } else { missing.insertElementAt(new Range(copyEnd, range.getEnd()), ++i); range.setEnd(copyStart); } } } } } void reset() { this.missing.removeAllElements(); this.missing.addElement(new Range(0, body.length)); } private static class Range { private int start, end; Range(int start, int end) { this.start = start; this.end = end; } public int getStart() { return start; } public void setStart(int start) { this.start = start; } public int getEnd() { return end; } public void setEnd(int end) { this.end = end; } } } bouncycastle-1.49.orig/jdk1.1/org/bouncycastle/crypto/encodings/0000755000175000017500000000000012152033551024171 5ustar ebourgebourgbouncycastle-1.49.orig/jdk1.1/org/bouncycastle/crypto/encodings/PKCS1Encoding.java0000644000175000017500000001442511705654527027351 0ustar ebourgebourgpackage org.bouncycastle.crypto.encodings; import org.bouncycastle.crypto.AsymmetricBlockCipher; import org.bouncycastle.crypto.CipherParameters; import org.bouncycastle.crypto.InvalidCipherTextException; import org.bouncycastle.crypto.params.AsymmetricKeyParameter; import org.bouncycastle.crypto.params.ParametersWithRandom; import java.security.SecureRandom; /** * this does your basic PKCS 1 v1.5 padding - whether or not you should be using this * depends on your application - see PKCS1 Version 2 for details. */ public class PKCS1Encoding implements AsymmetricBlockCipher { /** * some providers fail to include the leading zero in PKCS1 encoded blocks. If you need to * work with one of these set the system property org.bouncycastle.pkcs1.strict to false. *

    * The system property is checked during construction of the encoding object, it is set to * true by default. *

    */ public static final String STRICT_LENGTH_ENABLED_PROPERTY = "org.bouncycastle.pkcs1.strict"; private static final int HEADER_LENGTH = 10; private SecureRandom random; private AsymmetricBlockCipher engine; private boolean forEncryption; private boolean forPrivateKey; private boolean useStrictLength; /** * Basic constructor. * @param cipher */ public PKCS1Encoding( AsymmetricBlockCipher cipher) { this.engine = cipher; this.useStrictLength = useStrict(); } // // for J2ME compatibility // private boolean useStrict() { String strict = System.getProperty(STRICT_LENGTH_ENABLED_PROPERTY); return strict == null || strict.equals("true"); } public AsymmetricBlockCipher getUnderlyingCipher() { return engine; } public void init( boolean forEncryption, CipherParameters param) { AsymmetricKeyParameter kParam; if (param instanceof ParametersWithRandom) { ParametersWithRandom rParam = (ParametersWithRandom)param; this.random = rParam.getRandom(); kParam = (AsymmetricKeyParameter)rParam.getParameters(); } else { this.random = new SecureRandom(); kParam = (AsymmetricKeyParameter)param; } engine.init(forEncryption, param); this.forPrivateKey = kParam.isPrivate(); this.forEncryption = forEncryption; } public int getInputBlockSize() { int baseBlockSize = engine.getInputBlockSize(); if (forEncryption) { return baseBlockSize - HEADER_LENGTH; } else { return baseBlockSize; } } public int getOutputBlockSize() { int baseBlockSize = engine.getOutputBlockSize(); if (forEncryption) { return baseBlockSize; } else { return baseBlockSize - HEADER_LENGTH; } } public byte[] processBlock( byte[] in, int inOff, int inLen) throws InvalidCipherTextException { if (forEncryption) { return encodeBlock(in, inOff, inLen); } else { return decodeBlock(in, inOff, inLen); } } private byte[] encodeBlock( byte[] in, int inOff, int inLen) throws InvalidCipherTextException { if (inLen > getInputBlockSize()) { throw new IllegalArgumentException("input data too large"); } byte[] block = new byte[engine.getInputBlockSize()]; if (forPrivateKey) { block[0] = 0x01; // type code 1 for (int i = 1; i != block.length - inLen - 1; i++) { block[i] = (byte)0xFF; } } else { random.nextBytes(block); // random fill block[0] = 0x02; // type code 2 // // a zero byte marks the end of the padding, so all // the pad bytes must be non-zero. // for (int i = 1; i != block.length - inLen - 1; i++) { while (block[i] == 0) { block[i] = (byte)random.nextInt(); } } } block[block.length - inLen - 1] = 0x00; // mark the end of the padding System.arraycopy(in, inOff, block, block.length - inLen, inLen); return engine.processBlock(block, 0, block.length); } /** * @exception InvalidCipherTextException if the decrypted block is not in PKCS1 format. */ private byte[] decodeBlock( byte[] in, int inOff, int inLen) throws InvalidCipherTextException { byte[] block = engine.processBlock(in, inOff, inLen); if (block.length < getOutputBlockSize()) { throw new InvalidCipherTextException("block truncated"); } byte type = block[0]; if (type != 1 && type != 2) { throw new InvalidCipherTextException("unknown block type"); } if (useStrictLength && block.length != engine.getOutputBlockSize()) { throw new InvalidCipherTextException("block incorrect size"); } // // find and extract the message block. // int start; for (start = 1; start != block.length; start++) { byte pad = block[start]; if (pad == 0) { break; } if (type == 1 && pad != (byte)0xff) { throw new InvalidCipherTextException("block padding incorrect"); } } start++; // data should start at the next byte if (start > block.length || start < HEADER_LENGTH) { throw new InvalidCipherTextException("no data in block"); } byte[] result = new byte[block.length - start]; System.arraycopy(block, start, result, 0, result.length); return result; } } bouncycastle-1.49.orig/jdk1.1/org/bouncycastle/crypto/prng/0000755000175000017500000000000012152033551023166 5ustar ebourgebourgbouncycastle-1.49.orig/jdk1.1/org/bouncycastle/crypto/prng/SP800SecureRandomBuilder.java0000644000175000017500000002345312147306502030434 0ustar ebourgebourgpackage org.bouncycastle.crypto.prng; import java.security.SecureRandom; import org.bouncycastle.crypto.BlockCipher; import org.bouncycastle.crypto.Digest; import org.bouncycastle.crypto.Mac; import org.bouncycastle.crypto.prng.drbg.CTRSP800DRBG; import org.bouncycastle.crypto.prng.drbg.DualECSP800DRBG; import org.bouncycastle.crypto.prng.drbg.HMacSP800DRBG; import org.bouncycastle.crypto.prng.drbg.HashSP800DRBG; import org.bouncycastle.crypto.prng.drbg.SP80090DRBG; /** * Builder class for making SecureRandom objects based on SP 800-90A Deterministic Random Bit Generators (DRBG). */ public class SP800SecureRandomBuilder { private SecureRandom random; private EntropySourceProvider entropySourceProvider; private byte[] personalizationString; private int securityStrength = 256; private int entropyBitsRequired = 256; /** * Basic constructor, creates a builder using an EntropySourceProvider based on the default SecureRandom with * predictionResistant set to false. *

    * Any SecureRandom created from a builder constructed like this will make use of input passed to SecureRandom.setSeed() if * the default SecureRandom does for its generateSeed() call. *

    */ public SP800SecureRandomBuilder() { this(new SecureRandom(), false); } /** * Construct a builder with an EntropySourceProvider based on the passed in SecureRandom and the passed in value * for prediction resistance. *

    * Any SecureRandom created from a builder constructed like this will make use of input passed to SecureRandom.setSeed() if * the passed in SecureRandom does for its generateSeed() call. *

    * @param entropySource * @param predictionResistant */ public SP800SecureRandomBuilder(SecureRandom entropySource, boolean predictionResistant) { this.random = entropySource; this.entropySourceProvider = new BasicEntropySourceProvider(random, predictionResistant); } /** * Create a builder which makes creates the SecureRandom objects from a specified entropy source provider. *

    * Note: If this constructor is used any calls to setSeed() in the resulting SecureRandom will be ignored. *

    * @param entropySourceProvider a provider of EntropySource objects. */ public SP800SecureRandomBuilder(EntropySourceProvider entropySourceProvider) { this.random = null; this.entropySourceProvider = entropySourceProvider; } /** * Set the personalization string for DRBG SecureRandoms created by this builder * @param personalizationString the personalisation string for the underlying DRBG. * @return the current builder. */ public SP800SecureRandomBuilder setPersonalizationString(byte[] personalizationString) { this.personalizationString = personalizationString; return this; } /** * Set the security strength required for DRBGs used in building SecureRandom objects. * * @param securityStrength the security strength (in bits) * @return the current builder. */ public SP800SecureRandomBuilder setSecurityStrength(int securityStrength) { this.securityStrength = securityStrength; return this; } /** * Set the amount of entropy bits required for seeding and reseeding DRBGs used in building SecureRandom objects. * * @param entropyBitsRequired the number of bits of entropy to be requested from the entropy source on each seed/reseed. * @return the current builder. */ public SP800SecureRandomBuilder setEntropyBitsRequired(int entropyBitsRequired) { this.entropyBitsRequired = entropyBitsRequired; return this; } /** * Build a SecureRandom based on a SP 800-90A Hash DRBG. * * @param digest digest algorithm to use in the DRBG underneath the SecureRandom. * @param nonce nonce value to use in DRBG construction. * @param predictionResistant specify whether the underlying DRBG in the resulting SecureRandom should reseed on each request for bytes. * @return a SecureRandom supported by a Hash DRBG. */ public SP800SecureRandom buildHash(Digest digest, byte[] nonce, boolean predictionResistant) { return new SP800SecureRandom(random, entropySourceProvider.get(entropyBitsRequired), new HashDRBGProvider(digest, nonce, personalizationString, securityStrength), predictionResistant); } /** * Build a SecureRandom based on a SP 800-90A CTR DRBG. * * @param cipher the block cipher to base the DRBG on. * @param keySizeInBits key size in bits to be used with the block cipher. * @param nonce nonce value to use in DRBG construction. * @param predictionResistant specify whether the underlying DRBG in the resulting SecureRandom should reseed on each request for bytes. * @return a SecureRandom supported by a CTR DRBG. */ public SP800SecureRandom buildCTR(BlockCipher cipher, int keySizeInBits, byte[] nonce, boolean predictionResistant) { return new SP800SecureRandom(random, entropySourceProvider.get(entropyBitsRequired), new CTRDRBGProvider(cipher, keySizeInBits, nonce, personalizationString, securityStrength), predictionResistant); } /** * Build a SecureRandom based on a SP 800-90A HMAC DRBG. * * @param hMac HMAC algorithm to use in the DRBG underneath the SecureRandom. * @param nonce nonce value to use in DRBG construction. * @param predictionResistant specify whether the underlying DRBG in the resulting SecureRandom should reseed on each request for bytes. * @return a SecureRandom supported by a HMAC DRBG. */ public SP800SecureRandom buildHMAC(Mac hMac, byte[] nonce, boolean predictionResistant) { return new SP800SecureRandom(random, entropySourceProvider.get(entropyBitsRequired), new HMacDRBGProvider(hMac, nonce, personalizationString, securityStrength), predictionResistant); } /** * Build a SecureRandom based on a SP 800-90A Dual EC DRBG. * * @param digest digest algorithm to use in the DRBG underneath the SecureRandom. * @param nonce nonce value to use in DRBG construction. * @param predictionResistant specify whether the underlying DRBG in the resulting SecureRandom should reseed on each request for bytes. * @return a SecureRandom supported by a Dual EC DRBG. */ public SP800SecureRandom buildDualEC(Digest digest, byte[] nonce, boolean predictionResistant) { return new SP800SecureRandom(random, entropySourceProvider.get(entropyBitsRequired), new DualECDRBGProvider(digest, nonce, personalizationString, securityStrength), predictionResistant); } private static class HashDRBGProvider implements DRBGProvider { private final Digest digest; private final byte[] nonce; private final byte[] personalizationString; private final int securityStrength; public HashDRBGProvider(Digest digest, byte[] nonce, byte[] personalizationString, int securityStrength) { this.digest = digest; this.nonce = nonce; this.personalizationString = personalizationString; this.securityStrength = securityStrength; } public SP80090DRBG get(EntropySource entropySource) { return new HashSP800DRBG(digest, securityStrength, entropySource, personalizationString, nonce); } } private static class DualECDRBGProvider implements DRBGProvider { private final Digest digest; private final byte[] nonce; private final byte[] personalizationString; private final int securityStrength; public DualECDRBGProvider(Digest digest, byte[] nonce, byte[] personalizationString, int securityStrength) { this.digest = digest; this.nonce = nonce; this.personalizationString = personalizationString; this.securityStrength = securityStrength; } public SP80090DRBG get(EntropySource entropySource) { return new DualECSP800DRBG(digest, securityStrength, entropySource, personalizationString, nonce); } } private static class HMacDRBGProvider implements DRBGProvider { private final Mac hMac; private final byte[] nonce; private final byte[] personalizationString; private final int securityStrength; public HMacDRBGProvider(Mac hMac, byte[] nonce, byte[] personalizationString, int securityStrength) { this.hMac = hMac; this.nonce = nonce; this.personalizationString = personalizationString; this.securityStrength = securityStrength; } public SP80090DRBG get(EntropySource entropySource) { return new HMacSP800DRBG(hMac, securityStrength, entropySource, personalizationString, nonce); } } private static class CTRDRBGProvider implements DRBGProvider { private final BlockCipher blockCipher; private final int keySizeInBits; private final byte[] nonce; private final byte[] personalizationString; private final int securityStrength; public CTRDRBGProvider(BlockCipher blockCipher, int keySizeInBits, byte[] nonce, byte[] personalizationString, int securityStrength) { this.blockCipher = blockCipher; this.keySizeInBits = keySizeInBits; this.nonce = nonce; this.personalizationString = personalizationString; this.securityStrength = securityStrength; } public SP80090DRBG get(EntropySource entropySource) { return new CTRSP800DRBG(blockCipher, keySizeInBits, securityStrength, entropySource, personalizationString, nonce); } } } bouncycastle-1.49.orig/jdk1.1/org/bouncycastle/crypto/prng/BasicEntropySourceProvider.java0000644000175000017500000000331412147306502031333 0ustar ebourgebourgpackage org.bouncycastle.crypto.prng; import java.security.SecureRandom; /** * An EntropySourceProvider where entropy generation is based on a SecureRandom output using SecureRandom.generateSeed(). */ public class BasicEntropySourceProvider implements EntropySourceProvider { private SecureRandom _sr; private boolean _predictionResistant; /** * Create a entropy source provider based on the passed in SecureRandom. * * @param random the SecureRandom to base EntropySource construction on. * @param isPredictionResistant boolean indicating if the SecureRandom is based on prediction resistant entropy or not (true if it is). */ public BasicEntropySourceProvider(SecureRandom random, boolean isPredictionResistant) { _sr = random; _predictionResistant = isPredictionResistant; } /** * Return an entropy source that will create bitsRequired bits of entropy on * each invocation of getEntropy(). * * @param bitsRequired size (in bits) of entropy to be created by the provided source. * @return an EntropySource that generates bitsRequired bits of entropy on each call to its getEntropy() method. */ public EntropySource get(final int bitsRequired) { return new EntropySource() { public boolean isPredictionResistant() { return _predictionResistant; } public byte[] getEntropy() { byte[] rv = new byte[(bitsRequired + 7) / 8]; _sr.nextBytes(rv); return rv; } public int entropySize() { return bitsRequired; } }; } } bouncycastle-1.49.orig/jdk1.1/org/bouncycastle/crypto/agreement/0000755000175000017500000000000012152033551024167 5ustar ebourgebourgbouncycastle-1.49.orig/jdk1.1/org/bouncycastle/crypto/agreement/jpake/0000755000175000017500000000000012152033551025261 5ustar ebourgebourgbouncycastle-1.49.orig/jdk1.1/org/bouncycastle/crypto/agreement/jpake/JPAKEParticipant.java0000644000175000017500000005466512104616412031175 0ustar ebourgebourgpackage org.bouncycastle.crypto.agreement.jpake; import java.math.BigInteger; import java.security.SecureRandom; import org.bouncycastle.crypto.CryptoException; import org.bouncycastle.crypto.Digest; import org.bouncycastle.crypto.digests.SHA256Digest; import org.bouncycastle.util.Arrays; /** * A participant in a Password Authenticated Key Exchange by Juggling (J-PAKE) exchange. *

    *

    * The J-PAKE exchange is defined by Feng Hao and Peter Ryan in the paper * * "Password Authenticated Key Exchange by Juggling, 2008." *

    *

    * The J-PAKE protocol is symmetric. * There is no notion of a client or server, but rather just two participants. * An instance of {@link JPAKEParticipant} represents one participant, and * is the primary interface for executing the exchange. *

    *

    * To execute an exchange, construct a {@link JPAKEParticipant} on each end, * and call the following 7 methods * (once and only once, in the given order, for each participant, sending messages between them as described): *

      *
    1. {@link #createRound1PayloadToSend()} - and send the payload to the other participant
    2. *
    3. {@link #validateRound1PayloadReceived(JPAKERound1Payload)} - use the payload received from the other participant
    4. *
    5. {@link #createRound2PayloadToSend()} - and send the payload to the other participant
    6. *
    7. {@link #validateRound2PayloadReceived(JPAKERound2Payload)} - use the payload received from the other participant
    8. *
    9. {@link #calculateKeyingMaterial()}
    10. *
    11. {@link #createRound3PayloadToSend(BigInteger)} - and send the payload to the other participant
    12. *
    13. {@link #validateRound3PayloadReceived(JPAKERound3Payload, BigInteger)} - use the payload received from the other participant
    14. *
    *

    *

    * Each side should derive a session key from the keying material returned by {@link #calculateKeyingMaterial()}. * The caller is responsible for deriving the session key using a secure key derivation function (KDF). *

    *

    * Round 3 is an optional key confirmation process. * If you do not execute round 3, then there is no assurance that both participants are using the same key. * (i.e. if the participants used different passwords, then their session keys will differ.) *

    *

    * If the round 3 validation succeeds, then the keys are guaranteed to be the same on both sides. *

    *

    * The symmetric design can easily support the asymmetric cases when one party initiates the communication. * e.g. Sometimes the round1 payload and round2 payload may be sent in one pass. * Also, in some cases, the key confirmation payload can be sent together with the round2 payload. * These are the trivial techniques to optimize the communication. *

    *

    * The key confirmation process is implemented as specified in * NIST SP 800-56A Revision 1, * Section 8.2 Unilateral Key Confirmation for Key Agreement Schemes. *

    *

    * This class is stateful and NOT threadsafe. * Each instance should only be used for ONE complete J-PAKE exchange * (i.e. a new {@link JPAKEParticipant} should be constructed for each new J-PAKE exchange). *

    *

    * See {@link JPAKEExample} for example usage. */ public class JPAKEParticipant { /* * Possible internal states. Used for state checking. */ public static final int STATE_INITIALIZED = 0; public static final int STATE_ROUND_1_CREATED = 10; public static final int STATE_ROUND_1_VALIDATED = 20; public static final int STATE_ROUND_2_CREATED = 30; public static final int STATE_ROUND_2_VALIDATED = 40; public static final int STATE_KEY_CALCULATED = 50; public static final int STATE_ROUND_3_CREATED = 60; public static final int STATE_ROUND_3_VALIDATED = 70; /** * Unique identifier of this participant. * The two participants in the exchange must NOT share the same id. */ private String participantId; /** * Shared secret. This only contains the secret between construction * and the call to {@link #calculateKeyingMaterial()}. *

    * i.e. When {@link #calculateKeyingMaterial()} is called, this buffer overwritten with 0's, * and the field is set to null. */ private char[] password; /** * Digest to use during calculations. */ private Digest digest; /** * Source of secure random data. */ private SecureRandom random; private BigInteger p; private BigInteger q; private BigInteger g; /** * The participantId of the other participant in this exchange. */ private String partnerParticipantId; /** * Alice's x1 or Bob's x3. */ private BigInteger x1; /** * Alice's x2 or Bob's x4. */ private BigInteger x2; /** * Alice's g^x1 or Bob's g^x3. */ private BigInteger gx1; /** * Alice's g^x2 or Bob's g^x4. */ private BigInteger gx2; /** * Alice's g^x3 or Bob's g^x1. */ private BigInteger gx3; /** * Alice's g^x4 or Bob's g^x2. */ private BigInteger gx4; /** * Alice's B or Bob's A. */ private BigInteger b; /** * The current state. * See the STATE_* constants for possible values. */ private int state; /** * Convenience constructor for a new {@link JPAKEParticipant} that uses * the {@link JPAKEPrimeOrderGroups#NIST_3072} prime order group, * a SHA-256 digest, and a default {@link SecureRandom} implementation. *

    * After construction, the {@link #getState() state} will be {@link #STATE_INITIALIZED}. * * @param participantId unique identifier of this participant. * The two participants in the exchange must NOT share the same id. * @param password shared secret. * A defensive copy of this array is made (and cleared once {@link #calculateKeyingMaterial()} is called). * Caller should clear the input password as soon as possible. * @throws NullPointerException if any argument is null * @throws IllegalArgumentException if password is empty */ public JPAKEParticipant( String participantId, char[] password) { this( participantId, password, JPAKEPrimeOrderGroups.NIST_3072); } /** * Convenience constructor for a new {@link JPAKEParticipant} that uses * a SHA-256 digest and a default {@link SecureRandom} implementation. *

    * After construction, the {@link #getState() state} will be {@link #STATE_INITIALIZED}. * * @param participantId unique identifier of this participant. * The two participants in the exchange must NOT share the same id. * @param password shared secret. * A defensive copy of this array is made (and cleared once {@link #calculateKeyingMaterial()} is called). * Caller should clear the input password as soon as possible. * @param group prime order group. * See {@link JPAKEPrimeOrderGroups} for standard groups * @throws NullPointerException if any argument is null * @throws IllegalArgumentException if password is empty */ public JPAKEParticipant( String participantId, char[] password, JPAKEPrimeOrderGroup group) { this( participantId, password, group, new SHA256Digest(), new SecureRandom()); } /** * Construct a new {@link JPAKEParticipant}. *

    * After construction, the {@link #getState() state} will be {@link #STATE_INITIALIZED}. * * @param participantId unique identifier of this participant. * The two participants in the exchange must NOT share the same id. * @param password shared secret. * A defensive copy of this array is made (and cleared once {@link #calculateKeyingMaterial()} is called). * Caller should clear the input password as soon as possible. * @param group prime order group. * See {@link JPAKEPrimeOrderGroups} for standard groups * @param digest digest to use during zero knowledge proofs and key confirmation (SHA-256 or stronger preferred) * @param random source of secure random data for x1 and x2, and for the zero knowledge proofs * @throws NullPointerException if any argument is null * @throws IllegalArgumentException if password is empty */ public JPAKEParticipant( String participantId, char[] password, JPAKEPrimeOrderGroup group, Digest digest, SecureRandom random) { JPAKEUtil.validateNotNull(participantId, "participantId"); JPAKEUtil.validateNotNull(password, "password"); JPAKEUtil.validateNotNull(group, "p"); JPAKEUtil.validateNotNull(digest, "digest"); JPAKEUtil.validateNotNull(random, "random"); if (password.length == 0) { throw new IllegalArgumentException("Password must not be empty."); } this.participantId = participantId; /* * Create a defensive copy so as to fully encapsulate the password. * * This array will contain the password for the lifetime of this * participant BEFORE {@link #calculateKeyingMaterial()} is called. * * i.e. When {@link #calculateKeyingMaterial()} is called, the array will be cleared * in order to remove the password from memory. * * The caller is responsible for clearing the original password array * given as input to this constructor. */ this.password = Arrays.copyOf(password, password.length); this.p = group.getP(); this.q = group.getQ(); this.g = group.getG(); this.digest = digest; this.random = random; this.state = STATE_INITIALIZED; } /** * Gets the current state of this participant. * See the STATE_* constants for possible values. */ public int getState() { return this.state; } /** * Creates and returns the payload to send to the other participant during round 1. *

    *

    * After execution, the {@link #getState() state} will be {@link #STATE_ROUND_1_CREATED}. */ public JPAKERound1Payload createRound1PayloadToSend() { if (this.state >= STATE_ROUND_1_CREATED) { throw new IllegalStateException("Round1 payload already created for " + participantId); } this.x1 = JPAKEUtil.generateX1(q, random); this.x2 = JPAKEUtil.generateX2(q, random); this.gx1 = JPAKEUtil.calculateGx(p, g, x1); this.gx2 = JPAKEUtil.calculateGx(p, g, x2); BigInteger[] knowledgeProofForX1 = JPAKEUtil.calculateZeroKnowledgeProof(p, q, g, gx1, x1, participantId, digest, random); BigInteger[] knowledgeProofForX2 = JPAKEUtil.calculateZeroKnowledgeProof(p, q, g, gx2, x2, participantId, digest, random); this.state = STATE_ROUND_1_CREATED; return new JPAKERound1Payload(participantId, gx1, gx2, knowledgeProofForX1, knowledgeProofForX2); } /** * Validates the payload received from the other participant during round 1. *

    *

    * Must be called prior to {@link #createRound2PayloadToSend()}. *

    *

    * After execution, the {@link #getState() state} will be {@link #STATE_ROUND_1_VALIDATED}. * * @throws CryptoException if validation fails. * @throws IllegalStateException if called multiple times. */ public void validateRound1PayloadReceived(JPAKERound1Payload round1PayloadReceived) throws CryptoException { if (this.state >= STATE_ROUND_1_VALIDATED) { throw new IllegalStateException("Validation already attempted for round1 payload for" + participantId); } this.partnerParticipantId = round1PayloadReceived.getParticipantId(); this.gx3 = round1PayloadReceived.getGx1(); this.gx4 = round1PayloadReceived.getGx2(); BigInteger[] knowledgeProofForX3 = round1PayloadReceived.getKnowledgeProofForX1(); BigInteger[] knowledgeProofForX4 = round1PayloadReceived.getKnowledgeProofForX2(); JPAKEUtil.validateParticipantIdsDiffer(participantId, round1PayloadReceived.getParticipantId()); JPAKEUtil.validateGx4(gx4); JPAKEUtil.validateZeroKnowledgeProof(p, q, g, gx3, knowledgeProofForX3, round1PayloadReceived.getParticipantId(), digest); JPAKEUtil.validateZeroKnowledgeProof(p, q, g, gx4, knowledgeProofForX4, round1PayloadReceived.getParticipantId(), digest); this.state = STATE_ROUND_1_VALIDATED; } /** * Creates and returns the payload to send to the other participant during round 2. *

    *

    * {@link #validateRound1PayloadReceived(JPAKERound1Payload)} must be called prior to this method. *

    *

    * After execution, the {@link #getState() state} will be {@link #STATE_ROUND_2_CREATED}. * * @throws IllegalStateException if called prior to {@link #validateRound1PayloadReceived(JPAKERound1Payload)}, or multiple times */ public JPAKERound2Payload createRound2PayloadToSend() { if (this.state >= STATE_ROUND_2_CREATED) { throw new IllegalStateException("Round2 payload already created for " + this.participantId); } if (this.state < STATE_ROUND_1_VALIDATED) { throw new IllegalStateException("Round1 payload must be validated prior to creating Round2 payload for " + this.participantId); } BigInteger gA = JPAKEUtil.calculateGA(p, gx1, gx3, gx4); BigInteger s = JPAKEUtil.calculateS(password); BigInteger x2s = JPAKEUtil.calculateX2s(q, x2, s); BigInteger A = JPAKEUtil.calculateA(p, q, gA, x2s); BigInteger[] knowledgeProofForX2s = JPAKEUtil.calculateZeroKnowledgeProof(p, q, gA, A, x2s, participantId, digest, random); this.state = STATE_ROUND_2_CREATED; return new JPAKERound2Payload(participantId, A, knowledgeProofForX2s); } /** * Validates the payload received from the other participant during round 2. *

    *

    * Note that this DOES NOT detect a non-common password. * The only indication of a non-common password is through derivation * of different keys (which can be detected explicitly by executing round 3 and round 4) *

    *

    * Must be called prior to {@link #calculateKeyingMaterial()}. *

    *

    * After execution, the {@link #getState() state} will be {@link #STATE_ROUND_2_VALIDATED}. * * @throws CryptoException if validation fails. * @throws IllegalStateException if called prior to {@link #validateRound1PayloadReceived(JPAKERound1Payload)}, or multiple times */ public void validateRound2PayloadReceived(JPAKERound2Payload round2PayloadReceived) throws CryptoException { if (this.state >= STATE_ROUND_2_VALIDATED) { throw new IllegalStateException("Validation already attempted for round2 payload for" + participantId); } if (this.state < STATE_ROUND_1_VALIDATED) { throw new IllegalStateException("Round1 payload must be validated prior to validating Round2 payload for " + this.participantId); } BigInteger gB = JPAKEUtil.calculateGA(p, gx3, gx1, gx2); this.b = round2PayloadReceived.getA(); BigInteger[] knowledgeProofForX4s = round2PayloadReceived.getKnowledgeProofForX2s(); JPAKEUtil.validateParticipantIdsDiffer(participantId, round2PayloadReceived.getParticipantId()); JPAKEUtil.validateParticipantIdsEqual(this.partnerParticipantId, round2PayloadReceived.getParticipantId()); JPAKEUtil.validateGa(gB); JPAKEUtil.validateZeroKnowledgeProof(p, q, gB, b, knowledgeProofForX4s, round2PayloadReceived.getParticipantId(), digest); this.state = STATE_ROUND_2_VALIDATED; } /** * Calculates and returns the key material. * A session key must be derived from this key material using a secure key derivation function (KDF). * The KDF used to derive the key is handled externally (i.e. not by {@link JPAKEParticipant}). *

    *

    * The keying material will be identical for each participant if and only if * each participant's password is the same. i.e. If the participants do not * share the same password, then each participant will derive a different key. * Therefore, if you immediately start using a key derived from * the keying material, then you must handle detection of incorrect keys. * If you want to handle this detection explicitly, you can optionally perform * rounds 3 and 4. See {@link JPAKEParticipant} for details on how to execute * rounds 3 and 4. *

    *

    * The keying material will be in the range [0, p-1]. *

    *

    * {@link #validateRound2PayloadReceived(JPAKERound2Payload)} must be called prior to this method. *

    *

    * As a side effect, the internal {@link #password} array is cleared, since it is no longer needed. *

    *

    * After execution, the {@link #getState() state} will be {@link #STATE_KEY_CALCULATED}. * * @throws IllegalStateException if called prior to {@link #validateRound2PayloadReceived(JPAKERound2Payload)}, * or if called multiple times. */ public BigInteger calculateKeyingMaterial() { if (this.state >= STATE_KEY_CALCULATED) { throw new IllegalStateException("Key already calculated for " + participantId); } if (this.state < STATE_ROUND_2_VALIDATED) { throw new IllegalStateException("Round2 payload must be validated prior to creating key for " + participantId); } BigInteger s = JPAKEUtil.calculateS(password); /* * Clear the password array from memory, since we don't need it anymore. * * Also set the field to null as a flag to indicate that the key has already been calculated. */ Arrays.fill(password, (char)0); this.password = null; BigInteger keyingMaterial = JPAKEUtil.calculateKeyingMaterial(p, q, gx4, x2, s, b); /* * Clear the ephemeral private key fields as well. * Note that we're relying on the garbage collector to do its job to clean these up. * The old objects will hang around in memory until the garbage collector destroys them. * * If the ephemeral private keys x1 and x2 are leaked, * the attacker might be able to brute-force the password. */ this.x1 = null; this.x2 = null; this.b = null; /* * Do not clear gx* yet, since those are needed by round 3. */ this.state = STATE_KEY_CALCULATED; return keyingMaterial; } /** * Creates and returns the payload to send to the other participant during round 3. *

    *

    * See {@link JPAKEParticipant} for more details on round 3. *

    *

    * After execution, the {@link #getState() state} will be {@link #STATE_ROUND_3_CREATED}. * * @param keyingMaterial The keying material as returned from {@link #calculateKeyingMaterial()}. * @throws IllegalStateException if called prior to {@link #calculateKeyingMaterial()}, or multiple times */ public JPAKERound3Payload createRound3PayloadToSend(BigInteger keyingMaterial) { if (this.state >= STATE_ROUND_3_CREATED) { throw new IllegalStateException("Round3 payload already created for " + this.participantId); } if (this.state < STATE_KEY_CALCULATED) { throw new IllegalStateException("Keying material must be calculated prior to creating Round3 payload for " + this.participantId); } BigInteger macTag = JPAKEUtil.calculateMacTag( this.participantId, this.partnerParticipantId, this.gx1, this.gx2, this.gx3, this.gx4, keyingMaterial, this.digest); this.state = STATE_ROUND_3_CREATED; return new JPAKERound3Payload(participantId, macTag); } /** * Validates the payload received from the other participant during round 3. *

    *

    * See {@link JPAKEParticipant} for more details on round 3. *

    *

    * After execution, the {@link #getState() state} will be {@link #STATE_ROUND_3_VALIDATED}. * * @param keyingMaterial The keying material as returned from {@link #calculateKeyingMaterial()}. * @throws CryptoException if validation fails. * @throws IllegalStateException if called prior to {@link #calculateKeyingMaterial()}, or multiple times */ public void validateRound3PayloadReceived(JPAKERound3Payload round3PayloadReceived, BigInteger keyingMaterial) throws CryptoException { if (this.state >= STATE_ROUND_3_VALIDATED) { throw new IllegalStateException("Validation already attempted for round3 payload for" + participantId); } if (this.state < STATE_KEY_CALCULATED) { throw new IllegalStateException("Keying material must be calculated validated prior to validating Round3 payload for " + this.participantId); } JPAKEUtil.validateParticipantIdsDiffer(participantId, round3PayloadReceived.getParticipantId()); JPAKEUtil.validateParticipantIdsEqual(this.partnerParticipantId, round3PayloadReceived.getParticipantId()); JPAKEUtil.validateMacTag( this.participantId, this.partnerParticipantId, this.gx1, this.gx2, this.gx3, this.gx4, keyingMaterial, this.digest, round3PayloadReceived.getMacTag()); /* * Clear the rest of the fields. */ this.gx1 = null; this.gx2 = null; this.gx3 = null; this.gx4 = null; this.state = STATE_ROUND_3_VALIDATED; } } bouncycastle-1.49.orig/jdk1.1/org/bouncycastle/crypto/agreement/jpake/JPAKEPrimeOrderGroup.java0000644000175000017500000000733112104616413031771 0ustar ebourgebourgpackage org.bouncycastle.crypto.agreement.jpake; import java.math.BigInteger; /** * A pre-computed prime order group for use during a J-PAKE exchange. *

    *

    * Typically a Schnorr group is used. In general, J-PAKE can use any prime order group * that is suitable for public key cryptography, including elliptic curve cryptography. *

    *

    * See {@link JPAKEPrimeOrderGroups} for convenient standard groups. *

    *

    * NIST publishes * many groups that can be used for the desired level of security. */ public class JPAKEPrimeOrderGroup { private BigInteger p; private BigInteger q; private BigInteger g; /** * Constructs a new {@link JPAKEPrimeOrderGroup}. *

    *

    * In general, you should use one of the pre-approved groups from * {@link JPAKEPrimeOrderGroups}, rather than manually constructing one. *

    *

    * The following basic checks are performed: *

      *
    • p-1 must be evenly divisible by q
    • *
    • g must be in [2, p-1]
    • *
    • g^q mod p must equal 1
    • *
    • p must be prime (within reasonably certainty)
    • *
    • q must be prime (within reasonably certainty)
    • *
    *

    *

    * The prime checks are performed using {@link BigInteger#isProbablePrime(int)}, * and are therefore subject to the same probability guarantees. *

    *

    * These checks prevent trivial mistakes. * However, due to the small uncertainties if p and q are not prime, * advanced attacks are not prevented. * Use it at your own risk. * * @throws NullPointerException if any argument is null * @throws IllegalArgumentException if any of the above validations fail */ public JPAKEPrimeOrderGroup(BigInteger p, BigInteger q, BigInteger g) { /* * Don't skip the checks on user-specified groups. */ this(p, q, g, false); } /** * Internal package-private constructor used by the pre-approved * groups in {@link JPAKEPrimeOrderGroups}. * These pre-approved groups can avoid the expensive checks. */ JPAKEPrimeOrderGroup(BigInteger p, BigInteger q, BigInteger g, boolean skipChecks) { JPAKEUtil.validateNotNull(p, "p"); JPAKEUtil.validateNotNull(q, "q"); JPAKEUtil.validateNotNull(g, "g"); if (!skipChecks) { if (!p.subtract(JPAKEUtil.ONE).mod(q).equals(JPAKEUtil.ZERO)) { throw new IllegalArgumentException("p-1 must be evenly divisible by q"); } if (g.compareTo(BigInteger.valueOf(2)) == -1 || g.compareTo(p.subtract(JPAKEUtil.ONE)) == 1) { throw new IllegalArgumentException("g must be in [2, p-1]"); } if (!g.modPow(q, p).equals(JPAKEUtil.ONE)) { throw new IllegalArgumentException("g^q mod p must equal 1"); } /* * Note that these checks do not guarantee that p and q are prime. * We just have reasonable certainty that they are prime. */ if (!p.isProbablePrime(20)) { throw new IllegalArgumentException("p must be prime"); } if (!q.isProbablePrime(20)) { throw new IllegalArgumentException("q must be prime"); } } this.p = p; this.q = q; this.g = g; } public BigInteger getP() { return p; } public BigInteger getQ() { return q; } public BigInteger getG() { return g; } } bouncycastle-1.49.orig/jdk1.1/org/bouncycastle/crypto/params/0000755000175000017500000000000012152033551023503 5ustar ebourgebourgbouncycastle-1.49.orig/jdk1.1/org/bouncycastle/crypto/params/HKDFParameters.java0000644000175000017500000000615512104616413027116 0ustar ebourgebourgpackage org.bouncycastle.crypto.params; import org.bouncycastle.crypto.DerivationParameters; import org.bouncycastle.util.Arrays; /** * Parameter class for the HKDFBytesGenerator class. */ public class HKDFParameters implements DerivationParameters { private byte[] ikm; private boolean skipExpand; private byte[] salt; private byte[] info; private HKDFParameters(final byte[] ikm, final boolean skip, final byte[] salt, final byte[] info) { if (ikm == null) { throw new IllegalArgumentException( "IKM (input keying material) should not be null"); } this.ikm = Arrays.clone(ikm); this.skipExpand = skip; if (salt == null || salt.length == 0) { this.salt = null; } else { this.salt = Arrays.clone(salt); } if (info == null) { this.info = new byte[0]; } else { this.info = Arrays.clone(info); } } /** * Generates parameters for HKDF, specifying both the optional salt and * optional info. Step 1: Extract won't be skipped. * * @param ikm the input keying material or seed * @param salt the salt to use, may be null for a salt for hashLen zeros * @param info the info to use, may be null for an info field of zero bytes */ public HKDFParameters(final byte[] ikm, final byte[] salt, final byte[] info) { this(ikm, false, salt, info); } /** * Factory method that makes the HKDF skip the extract part of the key * derivation function. * * @param ikm the input keying material or seed, directly used for step 2: * Expand * @param info the info to use, may be null for an info field of zero bytes * @return HKDFParameters that makes the implementation skip step 1 */ public static HKDFParameters skipExtractParameters(final byte[] ikm, final byte[] info) { return new HKDFParameters(ikm, true, null, info); } public static HKDFParameters defaultParameters(final byte[] ikm) { return new HKDFParameters(ikm, false, null, null); } /** * Returns the input keying material or seed. * * @return the keying material */ public byte[] getIKM() { return Arrays.clone(ikm); } /** * Returns if step 1: extract has to be skipped or not * * @return true for skipping, false for no skipping of step 1 */ public boolean skipExtract() { return skipExpand; } /** * Returns the salt, or null if the salt should be generated as a byte array * of HashLen zeros. * * @return the salt, or null */ public byte[] getSalt() { return Arrays.clone(salt); } /** * Returns the info field, which may be empty (null is converted to empty). * * @return the info field, never null */ public byte[] getInfo() { return Arrays.clone(info); } } bouncycastle-1.49.orig/jdk1.1/org/bouncycastle/crypto/params/DSAParameterGenerationParameters.java0000644000175000017500000000365312147306502032670 0ustar ebourgebourgpackage org.bouncycastle.crypto.params; import java.security.SecureRandom; public class DSAParameterGenerationParameters { public static final int DIGITAL_SIGNATURE_USAGE = 1; public static final int KEY_ESTABLISHMENT_USAGE = 2; private int l; private int n; private int usageIndex; private int certainty; private SecureRandom random; /** * Construct without a usage index, this will do a random construction of G. * * @param L desired length of prime P in bits (the effective key size). * @param N desired length of prime Q in bits. * @param certainty certainty level for prime number generation. * @param random the source of randomness to use. */ public DSAParameterGenerationParameters( int L, int N, int certainty, SecureRandom random) { this(L, N, certainty, random, -1); } /** * Construct for a specific usage index - this has the effect of using verifiable canonical generation of G. * * @param L desired length of prime P in bits (the effective key size). * @param N desired length of prime Q in bits. * @param certainty certainty level for prime number generation. * @param random the source of randomness to use. * @param usageIndex a valid usage index. */ public DSAParameterGenerationParameters( int L, int N, int certainty, SecureRandom random, int usageIndex) { this.l = L; this.n = N; this.certainty = certainty; this.usageIndex = usageIndex; this.random = random; } public int getL() { return l; } public int getN() { return n; } public int getCertainty() { return certainty; } public SecureRandom getRandom() { return random; } public int getUsageIndex() { return usageIndex; } } bouncycastle-1.49.orig/jdk1.1/org/bouncycastle/asn1/0000755000175000017500000000000012152033551021542 5ustar ebourgebourgbouncycastle-1.49.orig/jdk1.1/org/bouncycastle/asn1/test/0000755000175000017500000000000012152033551022521 5ustar ebourgebourgbouncycastle-1.49.orig/jdk1.1/org/bouncycastle/asn1/test/RegressionTest.java0000644000175000017500000000537011705654527026370 0ustar ebourgebourgpackage org.bouncycastle.asn1.test; import org.bouncycastle.util.test.Test; import org.bouncycastle.util.test.TestResult; public class RegressionTest { public static Test[] tests = { new InputStreamTest(), new EqualsAndHashCodeTest(), new TagTest(), new SetTest(), new DERUTF8StringTest(), new CertificateTest(), new GenerationTest(), new CMSTest(), new OCSPTest(), new OIDTest(), new PKCS10Test(), new PKCS12Test(), new X509NameTest(), new X500NameTest(), new X509ExtensionsTest(), new GeneralizedTimeTest(), new BitStringTest(), new MiscTest(), new SMIMETest(), new X9Test(), new MonetaryValueUnitTest(), new BiometricDataUnitTest(), new Iso4217CurrencyCodeUnitTest(), new SemanticsInformationUnitTest(), new QCStatementUnitTest(), new TypeOfBiometricDataUnitTest(), new SignerLocationUnitTest(), new CommitmentTypeQualifierUnitTest(), new CommitmentTypeIndicationUnitTest(), new EncryptedPrivateKeyInfoTest(), new DataGroupHashUnitTest(), new LDSSecurityObjectUnitTest(), // new CscaMasterListTest(), new AttributeTableUnitTest(), new ReasonFlagsTest(), new NetscapeCertTypeTest(), new PKIFailureInfoTest(), new KeyUsageTest(), new StringTest(), new UTCTimeTest(), new RequestedCertificateUnitTest(), new OtherCertIDUnitTest(), new OtherSigningCertificateUnitTest(), new ContentHintsUnitTest(), new CertHashUnitTest(), new AdditionalInformationSyntaxUnitTest(), new AdmissionSyntaxUnitTest(), new AdmissionsUnitTest(), new DeclarationOfMajorityUnitTest(), new ProcurationSyntaxUnitTest(), new ProfessionInfoUnitTest(), new RestrictionUnitTest(), new NamingAuthorityUnitTest(), new MonetaryLimitUnitTest(), new NameOrPseudonymUnitTest(), new PersonalDataUnitTest(), new DERApplicationSpecificTest(), new IssuingDistributionPointUnitTest(), new TargetInformationTest(), new SubjectKeyIdentifierTest(), new ESSCertIDv2UnitTest(), new ParsingTest(), new GeneralNameTest(), new RFC4519Test() }; public static void main( String[] args) { for (int i = 0; i != tests.length; i++) { TestResult result = tests[i].perform(); if (result.getException() != null) { result.getException().printStackTrace(); } System.out.println(result); } } } bouncycastle-1.49.orig/jdk1.1/org/bouncycastle/asn1/ASN1StreamParser.java0000644000175000017500000001652311705654527025466 0ustar ebourgebourgpackage org.bouncycastle.asn1; import java.io.ByteArrayInputStream; import java.io.IOException; import java.io.InputStream; public class ASN1StreamParser { private InputStream _in; private int _limit; private byte[][] tmpBuffers; public ASN1StreamParser( InputStream in) { this(in, StreamUtil.findLimit(in)); } public ASN1StreamParser( InputStream in, int limit) { this._in = in; this._limit = limit; this.tmpBuffers = new byte[11][]; } public ASN1StreamParser( byte[] encoding) { this(new ByteArrayInputStream(encoding), encoding.length); } ASN1Encodable readIndef(int tagValue) throws IOException { // Note: INDEF => CONSTRUCTED // TODO There are other tags that may be constructed (e.g. BIT_STRING) switch (tagValue) { case BERTags.EXTERNAL: return new DERExternalParser(this); case BERTags.OCTET_STRING: return new BEROctetStringParser(this); case BERTags.SEQUENCE: return new BERSequenceParser(this); case BERTags.SET: return new BERSetParser(this); default: throw new ASN1Exception("unknown BER object encountered: 0x" + Integer.toHexString(tagValue)); } } ASN1Encodable readImplicit(boolean constructed, int tag) throws IOException { if (_in instanceof IndefiniteLengthInputStream) { if (!constructed) { throw new IOException("indefinite length primitive encoding encountered"); } return readIndef(tag); } if (constructed) { switch (tag) { case BERTags.SET: return new DERSetParser(this); case BERTags.SEQUENCE: return new DERSequenceParser(this); case BERTags.OCTET_STRING: return new BEROctetStringParser(this); } } else { switch (tag) { case BERTags.SET: throw new ASN1Exception("sequences must use constructed encoding (see X.690 8.9.1/8.10.1)"); case BERTags.SEQUENCE: throw new ASN1Exception("sets must use constructed encoding (see X.690 8.11.1/8.12.1)"); case BERTags.OCTET_STRING: return new DEROctetStringParser((DefiniteLengthInputStream)_in); } } // TODO ASN1Exception throw new RuntimeException("implicit tagging not implemented"); } ASN1Primitive readTaggedObject(boolean constructed, int tag) throws IOException { if (!constructed) { // Note: !CONSTRUCTED => IMPLICIT DefiniteLengthInputStream defIn = (DefiniteLengthInputStream)_in; return new DERTaggedObject(false, tag, new DEROctetString(defIn.toByteArray())); } ASN1EncodableVector v = readVector(); if (_in instanceof IndefiniteLengthInputStream) { return v.size() == 1 ? new BERTaggedObject(true, tag, v.get(0)) : new BERTaggedObject(false, tag, BERFactory.createSequence(v)); } return v.size() == 1 ? new DERTaggedObject(true, tag, v.get(0)) : new DERTaggedObject(false, tag, DERFactory.createSequence(v)); } public ASN1Encodable readObject() throws IOException { int tag = _in.read(); if (tag == -1) { return null; } // // turn of looking for "00" while we resolve the tag // set00Check(false); // // calculate tag number // int tagNo = ASN1InputStream.readTagNumber(_in, tag); boolean isConstructed = (tag & BERTags.CONSTRUCTED) != 0; // // calculate length // int length = ASN1InputStream.readLength(_in, _limit); if (length < 0) // indefinite length method { if (!isConstructed) { throw new IOException("indefinite length primitive encoding encountered"); } IndefiniteLengthInputStream indIn = new IndefiniteLengthInputStream(_in, _limit); ASN1StreamParser sp = new ASN1StreamParser(indIn, _limit); if ((tag & BERTags.APPLICATION) != 0) { return new BERApplicationSpecificParser(tagNo, sp); } if ((tag & BERTags.TAGGED) != 0) { return new BERTaggedObjectParser(true, tagNo, sp); } return sp.readIndef(tagNo); } else { DefiniteLengthInputStream defIn = new DefiniteLengthInputStream(_in, length); if ((tag & BERTags.APPLICATION) != 0) { return new DERApplicationSpecific(isConstructed, tagNo, defIn.toByteArray()); } if ((tag & BERTags.TAGGED) != 0) { return new BERTaggedObjectParser(isConstructed, tagNo, new ASN1StreamParser(defIn)); } if (isConstructed) { // TODO There are other tags that may be constructed (e.g. BIT_STRING) switch (tagNo) { case BERTags.OCTET_STRING: // // yes, people actually do this... // return new BEROctetStringParser(new ASN1StreamParser(defIn)); case BERTags.SEQUENCE: return new DERSequenceParser(new ASN1StreamParser(defIn)); case BERTags.SET: return new DERSetParser(new ASN1StreamParser(defIn)); case BERTags.EXTERNAL: return new DERExternalParser(new ASN1StreamParser(defIn)); default: throw new IOException("unknown tag " + tagNo + " encountered"); } } // Some primitive encodings can be handled by parsers too... switch (tagNo) { case BERTags.OCTET_STRING: return new DEROctetStringParser(defIn); } try { return ASN1InputStream.createPrimitiveDERObject(tagNo, defIn, tmpBuffers); } catch (IllegalArgumentException e) { throw new ASN1Exception("corrupted stream detected", e); } } } private void set00Check(boolean enabled) { if (_in instanceof IndefiniteLengthInputStream) { ((IndefiniteLengthInputStream)_in).setEofOn00(enabled); } } ASN1EncodableVector readVector() throws IOException { ASN1EncodableVector v = new ASN1EncodableVector(); ASN1Encodable obj; while ((obj = readObject()) != null) { if (obj instanceof InMemoryRepresentable) { v.add(((InMemoryRepresentable)obj).getLoadedObject()); } else { v.add(obj.toASN1Primitive()); } } return v; } } bouncycastle-1.49.orig/jdk1.1/org/bouncycastle/asn1/DERApplicationSpecific.java0000644000175000017500000001600711705654527026674 0ustar ebourgebourgpackage org.bouncycastle.asn1; import java.io.ByteArrayOutputStream; import java.io.IOException; import org.bouncycastle.util.Arrays; /** * Base class for an application specific object */ public class DERApplicationSpecific extends ASN1Primitive { private boolean isConstructed; private int tag; private byte[] octets; DERApplicationSpecific( boolean isConstructed, int tag, byte[] octets) { this.isConstructed = isConstructed; this.tag = tag; this.octets = octets; } public DERApplicationSpecific( int tag, byte[] octets) { this(false, tag, octets); } public DERApplicationSpecific( int tag, ASN1Encodable object) throws IOException { this(true, tag, object); } public DERApplicationSpecific( boolean explicit, int tag, ASN1Encodable object) throws IOException { ASN1Primitive primitive = object.toASN1Primitive(); byte[] data = primitive.getEncoded(ASN1Encoding.DER); this.isConstructed = explicit || (primitive instanceof ASN1Set || primitive instanceof ASN1Sequence); this.tag = tag; if (explicit) { this.octets = data; } else { int lenBytes = getLengthOfHeader(data); byte[] tmp = new byte[data.length - lenBytes]; System.arraycopy(data, lenBytes, tmp, 0, tmp.length); this.octets = tmp; } } public DERApplicationSpecific(int tagNo, ASN1EncodableVector vec) { this.tag = tagNo; this.isConstructed = true; ByteArrayOutputStream bOut = new ByteArrayOutputStream(); for (int i = 0; i != vec.size(); i++) { try { bOut.write(((ASN1Object)vec.get(i)).getEncoded(ASN1Encoding.DER)); } catch (IOException e) { throw new ASN1ParsingException("malformed object: " + e, e); } } this.octets = bOut.toByteArray(); } public static DERApplicationSpecific getInstance(Object obj) { if (obj == null || obj instanceof DERApplicationSpecific) { return (DERApplicationSpecific)obj; } else if (obj instanceof byte[]) { try { return DERApplicationSpecific.getInstance(ASN1Primitive.fromByteArray((byte[])obj)); } catch (IOException e) { throw new IllegalArgumentException("failed to construct object from byte[]: " + e.getMessage()); } } else if (obj instanceof ASN1Encodable) { ASN1Primitive primitive = ((ASN1Encodable)obj).toASN1Primitive(); if (primitive instanceof ASN1Sequence) { return (DERApplicationSpecific)primitive; } } throw new IllegalArgumentException("unknown object in getInstance: " + obj.getClass().getName()); } private int getLengthOfHeader(byte[] data) { int length = data[1] & 0xff; // TODO: assumes 1 byte tag if (length == 0x80) { return 2; // indefinite-length encoding } if (length > 127) { int size = length & 0x7f; // Note: The invalid long form "0xff" (see X.690 8.1.3.5c) will be caught here if (size > 4) { throw new IllegalStateException("DER length more than 4 bytes: " + size); } return size + 2; } return 2; } public boolean isConstructed() { return isConstructed; } public byte[] getContents() { return octets; } public int getApplicationTag() { return tag; } /** * Return the enclosed object assuming explicit tagging. * * @return the resulting object * @throws IOException if reconstruction fails. */ public ASN1Primitive getObject() throws IOException { return new ASN1InputStream(getContents()).readObject(); } /** * Return the enclosed object assuming implicit tagging. * * @param derTagNo the type tag that should be applied to the object's contents. * @return the resulting object * @throws IOException if reconstruction fails. */ public ASN1Primitive getObject(int derTagNo) throws IOException { if (derTagNo >= 0x1f) { throw new IOException("unsupported tag number"); } byte[] orig = this.getEncoded(); byte[] tmp = replaceTagNumber(derTagNo, orig); if ((orig[0] & BERTags.CONSTRUCTED) != 0) { tmp[0] |= BERTags.CONSTRUCTED; } return new ASN1InputStream(tmp).readObject(); } int encodedLength() throws IOException { return StreamUtil.calculateTagLength(tag) + StreamUtil.calculateBodyLength(octets.length) + octets.length; } /* (non-Javadoc) * @see org.bouncycastle.asn1.ASN1Primitive#encode(org.bouncycastle.asn1.DEROutputStream) */ void encode(ASN1OutputStream out) throws IOException { int classBits = BERTags.APPLICATION; if (isConstructed) { classBits |= BERTags.CONSTRUCTED; } out.writeEncoded(classBits, tag, octets); } boolean asn1Equals( ASN1Primitive o) { if (!(o instanceof DERApplicationSpecific)) { return false; } DERApplicationSpecific other = (DERApplicationSpecific)o; return isConstructed == other.isConstructed && tag == other.tag && Arrays.areEqual(octets, other.octets); } public int hashCode() { return (isConstructed ? 1 : 0) ^ tag ^ Arrays.hashCode(octets); } private byte[] replaceTagNumber(int newTag, byte[] input) throws IOException { int tagNo = input[0] & 0x1f; int index = 1; // // with tagged object tag number is bottom 5 bits, or stored at the start of the content // if (tagNo == 0x1f) { tagNo = 0; int b = input[index++] & 0xff; // X.690-0207 8.1.2.4.2 // "c) bits 7 to 1 of the first subsequent octet shall not all be zero." if ((b & 0x7f) == 0) // Note: -1 will pass { throw new ASN1ParsingException("corrupted stream - invalid high tag number found"); } while ((b >= 0) && ((b & 0x80) != 0)) { tagNo |= (b & 0x7f); tagNo <<= 7; b = input[index++] & 0xff; } tagNo |= (b & 0x7f); } byte[] tmp = new byte[input.length - index + 1]; System.arraycopy(input, index, tmp, 1, tmp.length - 1); tmp[0] = (byte)newTag; return tmp; } } bouncycastle-1.49.orig/jdk1.1/org/bouncycastle/asn1/ASN1InputStream.java0000644000175000017500000003317211705654527025330 0ustar ebourgebourgpackage org.bouncycastle.asn1; import java.io.ByteArrayInputStream; import java.io.EOFException; import java.io.FilterInputStream; import java.io.IOException; import java.io.InputStream; import org.bouncycastle.util.io.Streams; /** * a general purpose ASN.1 decoder - note: this class differs from the * others in that it returns null after it has read the last object in * the stream. If an ASN.1 NULL is encountered a DER/BER Null object is * returned. */ public class ASN1InputStream extends FilterInputStream implements BERTags { private int limit; private boolean lazyEvaluate; private byte[][] tmpBuffers; public ASN1InputStream( InputStream is) { this(is, StreamUtil.findLimit(is)); } /** * Create an ASN1InputStream based on the input byte array. The length of DER objects in * the stream is automatically limited to the length of the input array. * * @param input array containing ASN.1 encoded data. */ public ASN1InputStream( byte[] input) { this(new ByteArrayInputStream(input), input.length); } /** * Create an ASN1InputStream based on the input byte array. The length of DER objects in * the stream is automatically limited to the length of the input array. * * @param input array containing ASN.1 encoded data. * @param lazyEvaluate true if parsing inside constructed objects can be delayed. */ public ASN1InputStream( byte[] input, boolean lazyEvaluate) { this(new ByteArrayInputStream(input), input.length, lazyEvaluate); } /** * Create an ASN1InputStream where no DER object will be longer than limit. * * @param input stream containing ASN.1 encoded data. * @param limit maximum size of a DER encoded object. */ public ASN1InputStream( InputStream input, int limit) { this(input, limit, false); } /** * Create an ASN1InputStream where no DER object will be longer than limit, and constructed * objects such as sequences will be parsed lazily. * * @param input stream containing ASN.1 encoded data. * @param lazyEvaluate true if parsing inside constructed objects can be delayed. */ public ASN1InputStream( InputStream input, boolean lazyEvaluate) { this(input, StreamUtil.findLimit(input), lazyEvaluate); } /** * Create an ASN1InputStream where no DER object will be longer than limit, and constructed * objects such as sequences will be parsed lazily. * * @param input stream containing ASN.1 encoded data. * @param limit maximum size of a DER encoded object. * @param lazyEvaluate true if parsing inside constructed objects can be delayed. */ public ASN1InputStream( InputStream input, int limit, boolean lazyEvaluate) { super(input); this.limit = limit; this.lazyEvaluate = lazyEvaluate; this.tmpBuffers = new byte[11][]; } int getLimit() { return limit; } protected int readLength() throws IOException { return readLength(this, limit); } protected void readFully( byte[] bytes) throws IOException { if (Streams.readFully(this, bytes) != bytes.length) { throw new EOFException("EOF encountered in middle of object"); } } /** * build an object given its tag and the number of bytes to construct it from. */ protected ASN1Primitive buildObject( int tag, int tagNo, int length) throws IOException { boolean isConstructed = (tag & CONSTRUCTED) != 0; DefiniteLengthInputStream defIn = new DefiniteLengthInputStream(this, length); if ((tag & APPLICATION) != 0) { return new DERApplicationSpecific(isConstructed, tagNo, defIn.toByteArray()); } if ((tag & TAGGED) != 0) { return new ASN1StreamParser(defIn).readTaggedObject(isConstructed, tagNo); } if (isConstructed) { // TODO There are other tags that may be constructed (e.g. BIT_STRING) switch (tagNo) { case OCTET_STRING: // // yes, people actually do this... // ASN1EncodableVector v = buildDEREncodableVector(defIn); ASN1OctetString[] strings = new ASN1OctetString[v.size()]; for (int i = 0; i != strings.length; i++) { strings[i] = (ASN1OctetString)v.get(i); } return new BEROctetString(strings); case SEQUENCE: if (lazyEvaluate) { return new LazyEncodedSequence(defIn.toByteArray()); } else { return DERFactory.createSequence(buildDEREncodableVector(defIn)); } case SET: return DERFactory.createSet(buildDEREncodableVector(defIn)); case EXTERNAL: return new DERExternal(buildDEREncodableVector(defIn)); default: throw new IOException("unknown tag " + tagNo + " encountered"); } } return createPrimitiveDERObject(tagNo, defIn, tmpBuffers); } ASN1EncodableVector buildEncodableVector() throws IOException { ASN1EncodableVector v = new ASN1EncodableVector(); ASN1Primitive o; while ((o = readObject()) != null) { v.add(o); } return v; } ASN1EncodableVector buildDEREncodableVector( DefiniteLengthInputStream dIn) throws IOException { return new ASN1InputStream(dIn).buildEncodableVector(); } public ASN1Primitive readObject() throws IOException { int tag = read(); if (tag <= 0) { if (tag == 0) { throw new IOException("unexpected end-of-contents marker"); } return null; } // // calculate tag number // int tagNo = readTagNumber(this, tag); boolean isConstructed = (tag & CONSTRUCTED) != 0; // // calculate length // int length = readLength(); if (length < 0) // indefinite length method { if (!isConstructed) { throw new IOException("indefinite length primitive encoding encountered"); } IndefiniteLengthInputStream indIn = new IndefiniteLengthInputStream(this, limit); ASN1StreamParser sp = new ASN1StreamParser(indIn, limit); if ((tag & APPLICATION) != 0) { return new BERApplicationSpecificParser(tagNo, sp).getLoadedObject(); } if ((tag & TAGGED) != 0) { return new BERTaggedObjectParser(true, tagNo, sp).getLoadedObject(); } // TODO There are other tags that may be constructed (e.g. BIT_STRING) switch (tagNo) { case OCTET_STRING: return new BEROctetStringParser(sp).getLoadedObject(); case SEQUENCE: return new BERSequenceParser(sp).getLoadedObject(); case SET: return new BERSetParser(sp).getLoadedObject(); case EXTERNAL: return new DERExternalParser(sp).getLoadedObject(); default: throw new IOException("unknown BER object encountered"); } } else { try { return buildObject(tag, tagNo, length); } catch (IllegalArgumentException e) { throw new ASN1Exception("corrupted stream detected", e); } } } static int readTagNumber(InputStream s, int tag) throws IOException { int tagNo = tag & 0x1f; // // with tagged object tag number is bottom 5 bits, or stored at the start of the content // if (tagNo == 0x1f) { tagNo = 0; int b = s.read(); // X.690-0207 8.1.2.4.2 // "c) bits 7 to 1 of the first subsequent octet shall not all be zero." if ((b & 0x7f) == 0) // Note: -1 will pass { throw new IOException("corrupted stream - invalid high tag number found"); } while ((b >= 0) && ((b & 0x80) != 0)) { tagNo |= (b & 0x7f); tagNo <<= 7; b = s.read(); } if (b < 0) { throw new EOFException("EOF found inside tag value."); } tagNo |= (b & 0x7f); } return tagNo; } static int readLength(InputStream s, int limit) throws IOException { int length = s.read(); if (length < 0) { throw new EOFException("EOF found when length expected"); } if (length == 0x80) { return -1; // indefinite-length encoding } if (length > 127) { int size = length & 0x7f; // Note: The invalid long form "0xff" (see X.690 8.1.3.5c) will be caught here if (size > 4) { throw new IOException("DER length more than 4 bytes: " + size); } length = 0; for (int i = 0; i < size; i++) { int next = s.read(); if (next < 0) { throw new EOFException("EOF found reading length"); } length = (length << 8) + next; } if (length < 0) { throw new IOException("corrupted stream - negative length found"); } if (length >= limit) // after all we must have read at least 1 byte { throw new IOException("corrupted stream - out of bounds length found"); } } return length; } private static byte[] getBuffer(DefiniteLengthInputStream defIn, byte[][] tmpBuffers) throws IOException { int len = defIn.getRemaining(); if (defIn.getRemaining() < tmpBuffers.length) { byte[] buf = tmpBuffers[len]; if (buf == null) { buf = tmpBuffers[len] = new byte[len]; } Streams.readFully(defIn, buf); return buf; } else { return defIn.toByteArray(); } } private static char[] getBMPCharBuffer(DefiniteLengthInputStream defIn) throws IOException { int len = defIn.getRemaining() / 2; char[] buf = new char[len]; int totalRead = 0; while (totalRead < len) { int ch1 = defIn.read(); if (ch1 < 0) { break; } int ch2 = defIn.read(); if (ch2 < 0) { break; } buf[totalRead++] = (char)((ch1 << 8) | (ch2 & 0xff)); } return buf; } static ASN1Primitive createPrimitiveDERObject( int tagNo, DefiniteLengthInputStream defIn, byte[][] tmpBuffers) throws IOException { switch (tagNo) { case BIT_STRING: return DERBitString.fromInputStream(defIn.getRemaining(), defIn); case BMP_STRING: return new DERBMPString(getBMPCharBuffer(defIn)); case BOOLEAN: return ASN1Boolean.fromOctetString(getBuffer(defIn, tmpBuffers)); case ENUMERATED: return ASN1Enumerated.fromOctetString(getBuffer(defIn, tmpBuffers)); case GENERALIZED_TIME: return new ASN1GeneralizedTime(defIn.toByteArray()); case GENERAL_STRING: return new DERGeneralString(defIn.toByteArray()); case IA5_STRING: return new DERIA5String(defIn.toByteArray()); case INTEGER: return new ASN1Integer(defIn.toByteArray()); case NULL: return DERNull.INSTANCE; // actual content is ignored (enforce 0 length?) case NUMERIC_STRING: return new DERNumericString(defIn.toByteArray()); case OBJECT_IDENTIFIER: return ASN1ObjectIdentifier.fromOctetString(getBuffer(defIn, tmpBuffers)); case OCTET_STRING: return new DEROctetString(defIn.toByteArray()); case PRINTABLE_STRING: return new DERPrintableString(defIn.toByteArray()); case T61_STRING: return new DERT61String(defIn.toByteArray()); case UNIVERSAL_STRING: return new DERUniversalString(defIn.toByteArray()); case UTC_TIME: return new ASN1UTCTime(defIn.toByteArray()); case UTF8_STRING: return new DERUTF8String(defIn.toByteArray()); case VISIBLE_STRING: return new DERVisibleString(defIn.toByteArray()); default: throw new IOException("unknown tag " + tagNo + " encountered"); } } } bouncycastle-1.49.orig/jdk1.1/org/bouncycastle/cert/0000755000175000017500000000000012152033551021635 5ustar ebourgebourgbouncycastle-1.49.orig/jdk1.1/org/bouncycastle/cert/crmf/0000755000175000017500000000000012152033551022564 5ustar ebourgebourgbouncycastle-1.49.orig/jdk1.1/org/bouncycastle/cert/crmf/FixedLengthMGF1Padder.java0000644000175000017500000000620411731466725027404 0ustar ebourgebourgpackage org.bouncycastle.cert.crmf; import java.security.SecureRandom; import org.bouncycastle.crypto.Digest; import org.bouncycastle.crypto.digests.SHA1Digest; import org.bouncycastle.crypto.generators.MGF1BytesGenerator; import org.bouncycastle.crypto.params.MGFParameters; /** * An encrypted value padder that uses MGF1 as the basis of the padding. */ public class FixedLengthMGF1Padder implements EncryptedValuePadder { private int length; private SecureRandom random; private Digest dig = new SHA1Digest(); /** * Create a padder to so that padded output will always be at least * length bytes long. * * @param length fixed length for padded output. */ public FixedLengthMGF1Padder(int length) { this(length, null); } /** * Create a padder to so that padded output will always be at least * length bytes long, using the passed in source of randomness to * provide the random material for the padder. * * @param length fixed length for padded output. * @param random a source of randomness. */ public FixedLengthMGF1Padder(int length, SecureRandom random) { this.length = length; this.random = random; } public byte[] getPaddedData(byte[] data) { byte[] bytes = new byte[length]; byte[] seed = new byte[dig.getDigestSize()]; byte[] mask = new byte[length - dig.getDigestSize()]; if (random == null) { random = new SecureRandom(); } random.nextBytes(seed); MGF1BytesGenerator maskGen = new MGF1BytesGenerator(dig); maskGen.init(new MGFParameters(seed)); maskGen.generateBytes(mask, 0, mask.length); System.arraycopy(seed, 0, bytes, 0, seed.length); System.arraycopy(data, 0, bytes, seed.length, data.length); for (int i = seed.length + data.length + 1; i != bytes.length; i++) { bytes[i] = (byte)(1 + Math.abs(random.nextInt()) % 254); } for (int i = 0; i != mask.length; i++) { bytes[i + seed.length] ^= mask[i]; } return bytes; } public byte[] getUnpaddedData(byte[] paddedData) { byte[] seed = new byte[dig.getDigestSize()]; byte[] mask = new byte[length - dig.getDigestSize()]; System.arraycopy(paddedData, 0, seed, 0, seed.length); MGF1BytesGenerator maskGen = new MGF1BytesGenerator(dig); maskGen.init(new MGFParameters(seed)); maskGen.generateBytes(mask, 0, mask.length); for (int i = 0; i != mask.length; i++) { paddedData[i + seed.length] ^= mask[i]; } int end = 0; for (int i = paddedData.length - 1; i != seed.length; i--) { if (paddedData[i] == 0) { end = i; break; } } if (end == 0) { throw new IllegalStateException("bad padding in encoding"); } byte[] data = new byte[end - seed.length]; System.arraycopy(paddedData, seed.length, data, 0, data.length); return data; } } bouncycastle-1.49.orig/jdk1.1/org/bouncycastle/cert/crmf/CertificateRequestMessage.java0000644000175000017500000002413411731466725030552 0ustar ebourgebourgpackage org.bouncycastle.cert.crmf; import java.io.IOException; import org.bouncycastle.asn1.ASN1ObjectIdentifier; import org.bouncycastle.asn1.ASN1Primitive; import org.bouncycastle.asn1.DERUTF8String; import org.bouncycastle.asn1.crmf.AttributeTypeAndValue; import org.bouncycastle.asn1.crmf.CRMFObjectIdentifiers; import org.bouncycastle.asn1.crmf.CertReqMsg; import org.bouncycastle.asn1.crmf.CertTemplate; import org.bouncycastle.asn1.crmf.Controls; import org.bouncycastle.asn1.crmf.PKIArchiveOptions; import org.bouncycastle.asn1.crmf.PKMACValue; import org.bouncycastle.asn1.crmf.POPOSigningKey; import org.bouncycastle.asn1.crmf.ProofOfPossession; import org.bouncycastle.cert.CertIOException; import org.bouncycastle.operator.ContentVerifier; import org.bouncycastle.operator.ContentVerifierProvider; import org.bouncycastle.operator.OperatorCreationException; /** * Carrier for a CRMF CertReqMsg. */ public class CertificateRequestMessage { public static final int popRaVerified = ProofOfPossession.TYPE_RA_VERIFIED; public static final int popSigningKey = ProofOfPossession.TYPE_SIGNING_KEY; public static final int popKeyEncipherment = ProofOfPossession.TYPE_KEY_ENCIPHERMENT; public static final int popKeyAgreement = ProofOfPossession.TYPE_KEY_AGREEMENT; private CertReqMsg certReqMsg; private Controls controls; private static CertReqMsg parseBytes(byte[] encoding) throws IOException { try { return CertReqMsg.getInstance(ASN1Primitive.fromByteArray(encoding)); } catch (ClassCastException e) { throw new CertIOException("malformed data: " + e.getMessage(), e); } catch (IllegalArgumentException e) { throw new CertIOException("malformed data: " + e.getMessage(), e); } } /** * Create a CertificateRequestMessage from the passed in bytes. * * @param certReqMsg BER/DER encoding of the CertReqMsg structure. * @throws IOException in the event of corrupted data, or an incorrect structure. */ public CertificateRequestMessage(byte[] certReqMsg) throws IOException { this(parseBytes(certReqMsg)); } public CertificateRequestMessage(CertReqMsg certReqMsg) { this.certReqMsg = certReqMsg; this.controls = certReqMsg.getCertReq().getControls(); } /** * Return the underlying ASN.1 object defining this CertificateRequestMessage object. * * @return a CertReqMsg. */ public CertReqMsg toASN1Structure() { return certReqMsg; } /** * Return the certificate template contained in this message. * * @return a CertTemplate structure. */ public CertTemplate getCertTemplate() { return this.certReqMsg.getCertReq().getCertTemplate(); } /** * Return whether or not this request has control values associated with it. * * @return true if there are control values present, false otherwise. */ public boolean hasControls() { return controls != null; } /** * Return whether or not this request has a specific type of control value. * * @param type the type OID for the control value we are checking for. * @return true if a control value of type is present, false otherwise. */ public boolean hasControl(ASN1ObjectIdentifier type) { return findControl(type) != null; } /** * Return a control value of the specified type. * * @param type the type OID for the control value we are checking for. * @return the control value if present, null otherwise. */ public Control getControl(ASN1ObjectIdentifier type) { AttributeTypeAndValue found = findControl(type); if (found != null) { if (found.getType().equals(CRMFObjectIdentifiers.id_regCtrl_pkiArchiveOptions)) { return new PKIArchiveControl(PKIArchiveOptions.getInstance(found.getValue())); } if (found.getType().equals(CRMFObjectIdentifiers.id_regCtrl_regToken)) { return new RegTokenControl(DERUTF8String.getInstance(found.getValue())); } if (found.getType().equals(CRMFObjectIdentifiers.id_regCtrl_authenticator)) { return new AuthenticatorControl(DERUTF8String.getInstance(found.getValue())); } } return null; } private AttributeTypeAndValue findControl(ASN1ObjectIdentifier type) { if (controls == null) { return null; } AttributeTypeAndValue[] tAndVs = controls.toAttributeTypeAndValueArray(); AttributeTypeAndValue found = null; for (int i = 0; i != tAndVs.length; i++) { if (tAndVs[i].getType().equals(type)) { found = tAndVs[i]; break; } } return found; } /** * Return whether or not this request message has a proof-of-possession field in it. * * @return true if proof-of-possession is present, false otherwise. */ public boolean hasProofOfPossession() { return this.certReqMsg.getPopo() != null; } /** * Return the type of the proof-of-possession this request message provides. * * @return one of: popRaVerified, popSigningKey, popKeyEncipherment, popKeyAgreement */ public int getProofOfPossessionType() { return this.certReqMsg.getPopo().getType(); } /** * Return whether or not the proof-of-possession (POP) is of the type popSigningKey and * it has a public key MAC associated with it. * * @return true if POP is popSigningKey and a PKMAC is present, false otherwise. */ public boolean hasSigningKeyProofOfPossessionWithPKMAC() { ProofOfPossession pop = certReqMsg.getPopo(); if (pop.getType() == popSigningKey) { POPOSigningKey popoSign = POPOSigningKey.getInstance(pop.getObject()); return popoSign.getPoposkInput().getPublicKeyMAC() != null; } return false; } /** * Return whether or not a signing key proof-of-possession (POP) is valid. * * @param verifierProvider a provider that can produce content verifiers for the signature contained in this POP. * @return true if the POP is valid, false otherwise. * @throws CRMFException if there is a problem in verification or content verifier creation. * @throws IllegalStateException if POP not appropriate. */ public boolean isValidSigningKeyPOP(ContentVerifierProvider verifierProvider) throws CRMFException, IllegalStateException { ProofOfPossession pop = certReqMsg.getPopo(); if (pop.getType() == popSigningKey) { POPOSigningKey popoSign = POPOSigningKey.getInstance(pop.getObject()); if (popoSign.getPoposkInput() != null && popoSign.getPoposkInput().getPublicKeyMAC() != null) { throw new IllegalStateException("verification requires password check"); } return verifySignature(verifierProvider, popoSign); } else { throw new IllegalStateException("not Signing Key type of proof of possession"); } } /** * Return whether or not a signing key proof-of-possession (POP), with an associated PKMAC, is valid. * * @param verifierProvider a provider that can produce content verifiers for the signature contained in this POP. * @param macBuilder a suitable PKMACBuilder to create the MAC verifier. * @param password the password used to key the MAC calculation. * @return true if the POP is valid, false otherwise. * @throws CRMFException if there is a problem in verification or content verifier creation. * @throws IllegalStateException if POP not appropriate. */ public boolean isValidSigningKeyPOP(ContentVerifierProvider verifierProvider, PKMACBuilder macBuilder, char[] password) throws CRMFException, IllegalStateException { ProofOfPossession pop = certReqMsg.getPopo(); if (pop.getType() == popSigningKey) { POPOSigningKey popoSign = POPOSigningKey.getInstance(pop.getObject()); if (popoSign.getPoposkInput() == null || popoSign.getPoposkInput().getSender() != null) { throw new IllegalStateException("no PKMAC present in proof of possession"); } PKMACValue pkMAC = popoSign.getPoposkInput().getPublicKeyMAC(); PKMACValueVerifier macVerifier = new PKMACValueVerifier(macBuilder); if (macVerifier.isValid(pkMAC, password, this.getCertTemplate().getPublicKey())) { return verifySignature(verifierProvider, popoSign); } return false; } else { throw new IllegalStateException("not Signing Key type of proof of possession"); } } private boolean verifySignature(ContentVerifierProvider verifierProvider, POPOSigningKey popoSign) throws CRMFException { ContentVerifier verifier; try { verifier = verifierProvider.get(popoSign.getAlgorithmIdentifier()); } catch (OperatorCreationException e) { throw new CRMFException("unable to create verifier: " + e.getMessage(), e); } if (popoSign.getPoposkInput() != null) { CRMFUtil.derEncodeToStream(popoSign.getPoposkInput(), verifier.getOutputStream()); } else { CRMFUtil.derEncodeToStream(certReqMsg.getCertReq(), verifier.getOutputStream()); } return verifier.verify(popoSign.getSignature().getBytes()); } /** * Return the ASN.1 encoding of the certReqMsg we wrap. * * @return a byte array containing the binary encoding of the certReqMsg. * @throws IOException if there is an exception creating the encoding. */ public byte[] getEncoded() throws IOException { return certReqMsg.getEncoded(); } } bouncycastle-1.49.orig/jdk1.1/org/bouncycastle/cert/crmf/jcajce/0000755000175000017500000000000012152033551024003 5ustar ebourgebourg././@LongLink0000000000000000000000000000015200000000000011563 Lustar rootrootbouncycastle-1.49.orig/jdk1.1/org/bouncycastle/cert/crmf/jcajce/JceAsymmetricValueDecryptorGenerator.javabouncycastle-1.49.orig/jdk1.1/org/bouncycastle/cert/crmf/jcajce/JceAsymmetricValueDecryptorGenerator0000644000175000017500000001002611731466725033243 0ustar ebourgebourgpackage org.bouncycastle.cert.crmf.jcajce; import java.io.InputStream; import java.security.GeneralSecurityException; import java.security.InvalidKeyException; import java.security.Key; import java.security.PrivateKey; import java.security.Provider; import java.security.ProviderException; import java.security.NoSuchAlgorithmException; import javax.crypto.BadPaddingException; import javax.crypto.Cipher; import javax.crypto.CipherInputStream; import javax.crypto.IllegalBlockSizeException; import javax.crypto.spec.SecretKeySpec; import org.bouncycastle.asn1.x509.AlgorithmIdentifier; import org.bouncycastle.cert.crmf.CRMFException; import org.bouncycastle.cert.crmf.ValueDecryptorGenerator; import org.bouncycastle.jcajce.DefaultJcaJceHelper; import org.bouncycastle.jcajce.NamedJcaJceHelper; import org.bouncycastle.jcajce.ProviderJcaJceHelper; import org.bouncycastle.operator.InputDecryptor; public class JceAsymmetricValueDecryptorGenerator implements ValueDecryptorGenerator { private PrivateKey recipientKey; private CRMFHelper helper = new CRMFHelper(new DefaultJcaJceHelper()); public JceAsymmetricValueDecryptorGenerator(PrivateKey recipientKey) { this.recipientKey = recipientKey; } public JceAsymmetricValueDecryptorGenerator setProvider(Provider provider) { this.helper = new CRMFHelper(new ProviderJcaJceHelper(provider)); return this; } public JceAsymmetricValueDecryptorGenerator setProvider(String providerName) { this.helper = new CRMFHelper(new NamedJcaJceHelper(providerName)); return this; } private Key extractSecretKey(AlgorithmIdentifier keyEncryptionAlgorithm, AlgorithmIdentifier contentEncryptionAlgorithm, byte[] encryptedContentEncryptionKey) throws CRMFException { try { Key sKey = null; Cipher keyCipher = helper.createCipher(keyEncryptionAlgorithm.getAlgorithm()); try { keyCipher.init(Cipher.UNWRAP_MODE, recipientKey); sKey = keyCipher.unwrap(encryptedContentEncryptionKey, contentEncryptionAlgorithm.getAlgorithm().getId(), Cipher.SECRET_KEY); } catch (NoSuchAlgorithmException e) { } catch (IllegalStateException e) { } catch (UnsupportedOperationException e) { } catch (ProviderException e) { } // some providers do not support UNWRAP (this appears to be only for asymmetric algorithms) if (sKey == null) { keyCipher.init(Cipher.DECRYPT_MODE, recipientKey); sKey = new SecretKeySpec(keyCipher.doFinal(encryptedContentEncryptionKey), contentEncryptionAlgorithm.getAlgorithm().getId()); } return sKey; } catch (InvalidKeyException e) { throw new CRMFException("key invalid in message.", e); } catch (IllegalBlockSizeException e) { throw new CRMFException("illegal blocksize in message.", e); } catch (BadPaddingException e) { throw new CRMFException("bad padding in message.", e); } } public InputDecryptor getValueDecryptor(AlgorithmIdentifier keyEncryptionAlgorithm, final AlgorithmIdentifier contentEncryptionAlgorithm, byte[] encryptedContentEncryptionKey) throws CRMFException { Key secretKey = extractSecretKey(keyEncryptionAlgorithm, contentEncryptionAlgorithm, encryptedContentEncryptionKey); final Cipher dataCipher = helper.createContentCipher(secretKey, contentEncryptionAlgorithm); return new InputDecryptor() { public AlgorithmIdentifier getAlgorithmIdentifier() { return contentEncryptionAlgorithm; } public InputStream getInputStream(InputStream dataIn) { return new CipherInputStream(dataIn, dataCipher); } }; } } bouncycastle-1.49.orig/jdk1.1/org/bouncycastle/cert/crmf/jcajce/JceCRMFEncryptorBuilder.java0000644000175000017500000001006211731466725031252 0ustar ebourgebourgpackage org.bouncycastle.cert.crmf.jcajce; import java.io.OutputStream; import java.security.AlgorithmParameters; import java.security.GeneralSecurityException; import java.security.Provider; import java.security.SecureRandom; import java.security.InvalidKeyException; import javax.crypto.Cipher; import javax.crypto.CipherOutputStream; import javax.crypto.KeyGenerator; import javax.crypto.SecretKey; import org.bouncycastle.asn1.ASN1ObjectIdentifier; import org.bouncycastle.asn1.x509.AlgorithmIdentifier; import org.bouncycastle.cert.crmf.CRMFException; import org.bouncycastle.jcajce.DefaultJcaJceHelper; import org.bouncycastle.jcajce.NamedJcaJceHelper; import org.bouncycastle.jcajce.ProviderJcaJceHelper; import org.bouncycastle.operator.GenericKey; import org.bouncycastle.operator.OutputEncryptor; public class JceCRMFEncryptorBuilder { private ASN1ObjectIdentifier encryptionOID; private int keySize; private CRMFHelper helper = new CRMFHelper(new DefaultJcaJceHelper()); private SecureRandom random; public JceCRMFEncryptorBuilder(ASN1ObjectIdentifier encryptionOID) { this(encryptionOID, -1); } public JceCRMFEncryptorBuilder(ASN1ObjectIdentifier encryptionOID, int keySize) { this.encryptionOID = encryptionOID; this.keySize = keySize; } public JceCRMFEncryptorBuilder setProvider(Provider provider) { this.helper = new CRMFHelper(new ProviderJcaJceHelper(provider)); return this; } public JceCRMFEncryptorBuilder setProvider(String providerName) { this.helper = new CRMFHelper(new NamedJcaJceHelper(providerName)); return this; } public JceCRMFEncryptorBuilder setSecureRandom(SecureRandom random) { this.random = random; return this; } public OutputEncryptor build() throws CRMFException { return new CRMFOutputEncryptor(encryptionOID, keySize, random); } private class CRMFOutputEncryptor implements OutputEncryptor { private SecretKey encKey; private AlgorithmIdentifier algorithmIdentifier; private Cipher cipher; CRMFOutputEncryptor(ASN1ObjectIdentifier encryptionOID, int keySize, SecureRandom random) throws CRMFException { KeyGenerator keyGen = helper.createKeyGenerator(encryptionOID); if (random == null) { random = new SecureRandom(); } if (keySize < 0) { keyGen.init(random); } else { keyGen.init(keySize, random); } cipher = helper.createCipher(encryptionOID); encKey = keyGen.generateKey(); AlgorithmParameters params = helper.generateParameters(encryptionOID, encKey, random); try { cipher.init(Cipher.ENCRYPT_MODE, encKey, params, random); } catch (InvalidKeyException e) { throw new CRMFException("unable to initialize cipher: " + e.getMessage(), e); } catch (GeneralSecurityException e) { throw new CRMFException("unable to initialize cipher: " + e.getMessage(), e); } // // If params are null we try and second guess on them as some providers don't provide // algorithm parameter generation explicity but instead generate them under the hood. // if (params == null) { params = cipher.getParameters(); } algorithmIdentifier = helper.getAlgorithmIdentifier(encryptionOID, params); } public AlgorithmIdentifier getAlgorithmIdentifier() { return algorithmIdentifier; } public OutputStream getOutputStream(OutputStream dOut) { return new CipherOutputStream(dOut, cipher); } public GenericKey getKey() { return new GenericKey(encKey); } } } bouncycastle-1.49.orig/jdk1.1/org/bouncycastle/cert/crmf/jcajce/CRMFHelper.java0000644000175000017500000004145012105031243026533 0ustar ebourgebourgpackage org.bouncycastle.cert.crmf.jcajce; import java.io.IOException; import java.security.AlgorithmParameterGenerator; import java.security.AlgorithmParameters; import java.security.GeneralSecurityException; import java.security.InvalidAlgorithmParameterException; import java.security.InvalidKeyException; import java.security.Key; import java.security.KeyFactory; import java.security.MessageDigest; import java.security.NoSuchAlgorithmException; import java.security.NoSuchProviderException; import java.security.PublicKey; import java.security.SecureRandom; import java.security.spec.InvalidKeySpecException; import java.security.spec.InvalidParameterSpecException; import java.security.spec.X509EncodedKeySpec; import java.util.HashMap; import java.util.Map; import javax.crypto.Cipher; import javax.crypto.KeyGenerator; import javax.crypto.Mac; import javax.crypto.NoSuchPaddingException; import javax.crypto.SecretKey; import javax.crypto.spec.IvParameterSpec; import javax.crypto.spec.RC2ParameterSpec; import org.bouncycastle.asn1.ASN1Encodable; import org.bouncycastle.asn1.ASN1Null; import org.bouncycastle.asn1.ASN1ObjectIdentifier; import org.bouncycastle.asn1.ASN1OctetString; import org.bouncycastle.asn1.ASN1Primitive; import org.bouncycastle.asn1.DERBitString; import org.bouncycastle.asn1.DERNull; import org.bouncycastle.asn1.iana.IANAObjectIdentifiers; import org.bouncycastle.asn1.nist.NISTObjectIdentifiers; import org.bouncycastle.asn1.oiw.OIWObjectIdentifiers; import org.bouncycastle.asn1.pkcs.PKCSObjectIdentifiers; import org.bouncycastle.asn1.x509.AlgorithmIdentifier; import org.bouncycastle.asn1.x509.SubjectPublicKeyInfo; import org.bouncycastle.asn1.x9.X9ObjectIdentifiers; import org.bouncycastle.cert.crmf.CRMFException; import org.bouncycastle.cms.CMSAlgorithm; import org.bouncycastle.cms.CMSEnvelopedDataGenerator; import org.bouncycastle.jcajce.JcaJceHelper; class CRMFHelper { protected static final Map BASE_CIPHER_NAMES = new HashMap(); protected static final Map CIPHER_ALG_NAMES = new HashMap(); protected static final Map DIGEST_ALG_NAMES = new HashMap(); protected static final Map KEY_ALG_NAMES = new HashMap(); protected static final Map MAC_ALG_NAMES = new HashMap(); static { BASE_CIPHER_NAMES.put(PKCSObjectIdentifiers.des_EDE3_CBC, "DESEDE"); BASE_CIPHER_NAMES.put(NISTObjectIdentifiers.id_aes128_CBC, "AES"); BASE_CIPHER_NAMES.put(NISTObjectIdentifiers.id_aes192_CBC, "AES"); BASE_CIPHER_NAMES.put(NISTObjectIdentifiers.id_aes256_CBC, "AES"); CIPHER_ALG_NAMES.put(CMSAlgorithm.DES_EDE3_CBC, "DESEDE/CBC/PKCS5Padding"); CIPHER_ALG_NAMES.put(CMSAlgorithm.AES128_CBC, "AES/CBC/PKCS5Padding"); CIPHER_ALG_NAMES.put(CMSAlgorithm.AES192_CBC, "AES/CBC/PKCS5Padding"); CIPHER_ALG_NAMES.put(CMSAlgorithm.AES256_CBC, "AES/CBC/PKCS5Padding"); CIPHER_ALG_NAMES.put(new ASN1ObjectIdentifier(PKCSObjectIdentifiers.rsaEncryption.getId()), "RSA/ECB/PKCS1Padding"); DIGEST_ALG_NAMES.put(OIWObjectIdentifiers.idSHA1, "SHA1"); DIGEST_ALG_NAMES.put(NISTObjectIdentifiers.id_sha224, "SHA224"); DIGEST_ALG_NAMES.put(NISTObjectIdentifiers.id_sha256, "SHA256"); DIGEST_ALG_NAMES.put(NISTObjectIdentifiers.id_sha384, "SHA384"); DIGEST_ALG_NAMES.put(NISTObjectIdentifiers.id_sha512, "SHA512"); MAC_ALG_NAMES.put(IANAObjectIdentifiers.hmacSHA1, "HMACSHA1"); MAC_ALG_NAMES.put(PKCSObjectIdentifiers.id_hmacWithSHA1, "HMACSHA1"); MAC_ALG_NAMES.put(PKCSObjectIdentifiers.id_hmacWithSHA224, "HMACSHA224"); MAC_ALG_NAMES.put(PKCSObjectIdentifiers.id_hmacWithSHA256, "HMACSHA256"); MAC_ALG_NAMES.put(PKCSObjectIdentifiers.id_hmacWithSHA384, "HMACSHA384"); MAC_ALG_NAMES.put(PKCSObjectIdentifiers.id_hmacWithSHA512, "HMACSHA512"); KEY_ALG_NAMES.put(PKCSObjectIdentifiers.rsaEncryption, "RSA"); KEY_ALG_NAMES.put(X9ObjectIdentifiers.id_dsa, "DSA"); } private JcaJceHelper helper; CRMFHelper(JcaJceHelper helper) { this.helper = helper; } PublicKey toPublicKey(SubjectPublicKeyInfo subjectPublicKeyInfo) throws CRMFException { try { X509EncodedKeySpec xspec = new X509EncodedKeySpec(new DERBitString(subjectPublicKeyInfo).getBytes()); AlgorithmIdentifier keyAlg = subjectPublicKeyInfo.getAlgorithmId(); return createKeyFactory(keyAlg.getAlgorithm()).generatePublic(xspec); } catch (IOException e) { throw new CRMFException("invalid key: " + e.getMessage(), e); } catch (InvalidKeySpecException e) { throw new CRMFException("invalid key: " + e.getMessage(), e); } } Cipher createCipher(ASN1ObjectIdentifier algorithm) throws CRMFException { try { String cipherName = (String)CIPHER_ALG_NAMES.get(algorithm); if (cipherName != null) { try { // this is reversed as the Sun policy files now allow unlimited strength RSA return helper.createCipher(cipherName); } catch (NoSuchAlgorithmException e) { // Ignore } } return helper.createCipher(algorithm.getId()); } catch (NoSuchPaddingException e) { throw new CRMFException("cannot create cipher: " + e.getMessage(), e); } catch (NoSuchAlgorithmException e) { throw new CRMFException("cannot create cipher: " + e.getMessage(), e); } catch (NoSuchProviderException e) { throw new CRMFException("cannot create cipher: " + e.getMessage(), e); } } public KeyGenerator createKeyGenerator(ASN1ObjectIdentifier algorithm) throws CRMFException { try { String cipherName = (String)BASE_CIPHER_NAMES.get(algorithm); if (cipherName != null) { try { // this is reversed as the Sun policy files now allow unlimited strength RSA return helper.createKeyGenerator(cipherName); } catch (NoSuchAlgorithmException e) { // Ignore } } return helper.createKeyGenerator(algorithm.getId()); } catch (NoSuchAlgorithmException e) { throw new CRMFException("cannot create key generator: " + e.getMessage(), e); } catch (NoSuchProviderException e) { throw new CRMFException("cannot create key generator: " + e.getMessage(), e); } } Cipher createContentCipher(final Key sKey, final AlgorithmIdentifier encryptionAlgID) throws CRMFException { return (Cipher)execute(new JCECallback() { public Object doInJCE() throws CRMFException, InvalidAlgorithmParameterException, InvalidKeyException, InvalidParameterSpecException, NoSuchAlgorithmException, NoSuchPaddingException, NoSuchProviderException { Cipher cipher = createCipher(encryptionAlgID.getAlgorithm()); ASN1Primitive sParams = (ASN1Primitive)encryptionAlgID.getParameters(); String encAlg = encryptionAlgID.getAlgorithm().getId(); if (sParams != null && !(sParams instanceof ASN1Null)) { try { AlgorithmParameters params = createAlgorithmParameters(encryptionAlgID.getAlgorithm()); try { params.init(sParams.getEncoded(), "ASN.1"); } catch (IOException e) { throw new CRMFException("error decoding algorithm parameters.", e); } cipher.init(Cipher.DECRYPT_MODE, sKey, params); } catch (NoSuchAlgorithmException e) { if (encAlg.equals(CMSEnvelopedDataGenerator.DES_EDE3_CBC) || encAlg.equals(CMSEnvelopedDataGenerator.IDEA_CBC) || encAlg.equals(CMSEnvelopedDataGenerator.AES128_CBC) || encAlg.equals(CMSEnvelopedDataGenerator.AES192_CBC) || encAlg.equals(CMSEnvelopedDataGenerator.AES256_CBC)) { cipher.init(Cipher.DECRYPT_MODE, sKey, new IvParameterSpec( ASN1OctetString.getInstance(sParams).getOctets())); } else { throw e; } } } else { if (encAlg.equals(CMSEnvelopedDataGenerator.DES_EDE3_CBC) || encAlg.equals(CMSEnvelopedDataGenerator.IDEA_CBC) || encAlg.equals(CMSEnvelopedDataGenerator.CAST5_CBC)) { cipher.init(Cipher.DECRYPT_MODE, sKey, new IvParameterSpec(new byte[8])); } else { cipher.init(Cipher.DECRYPT_MODE, sKey); } } return cipher; } }); } AlgorithmParameters createAlgorithmParameters(ASN1ObjectIdentifier algorithm) throws NoSuchAlgorithmException, NoSuchProviderException { String algorithmName = (String)BASE_CIPHER_NAMES.get(algorithm); if (algorithmName != null) { try { // this is reversed as the Sun policy files now allow unlimited strength RSA return helper.createAlgorithmParameters(algorithmName); } catch (NoSuchAlgorithmException e) { // Ignore } } return helper.createAlgorithmParameters(algorithm.getId()); } KeyFactory createKeyFactory(ASN1ObjectIdentifier algorithm) throws CRMFException { try { String algName = (String)KEY_ALG_NAMES.get(algorithm); if (algName != null) { try { // this is reversed as the Sun policy files now allow unlimited strength RSA return helper.createKeyFactory(algName); } catch (NoSuchAlgorithmException e) { // Ignore } } return helper.createKeyFactory(algorithm.getId()); } catch (NoSuchProviderException e) { throw new CRMFException("cannot create cipher: " + e.getMessage(), e); } catch (NoSuchAlgorithmException e) { throw new CRMFException("cannot create cipher: " + e.getMessage(), e); } } MessageDigest createDigest(ASN1ObjectIdentifier algorithm) throws CRMFException { try { String digestName = (String)DIGEST_ALG_NAMES.get(algorithm); if (digestName != null) { try { // this is reversed as the Sun policy files now allow unlimited strength RSA return helper.createDigest(digestName); } catch (NoSuchAlgorithmException e) { // Ignore } } return helper.createDigest(algorithm.getId()); } catch (NoSuchAlgorithmException e) { throw new CRMFException("cannot create cipher: " + e.getMessage(), e); } catch (NoSuchProviderException e) { throw new CRMFException("cannot create cipher: " + e.getMessage(), e); } } Mac createMac(ASN1ObjectIdentifier algorithm) throws CRMFException { try { String macName = (String)MAC_ALG_NAMES.get(algorithm); if (macName != null) { try { // this is reversed as the Sun policy files now allow unlimited strength RSA return helper.createMac(macName); } catch (NoSuchAlgorithmException e) { // Ignore } } return helper.createMac(algorithm.getId()); } catch (NoSuchProviderException e) { throw new CRMFException("cannot create mac: " + e.getMessage(), e); } catch (NoSuchAlgorithmException e) { throw new CRMFException("cannot create mac: " + e.getMessage(), e); } } AlgorithmParameterGenerator createAlgorithmParameterGenerator(ASN1ObjectIdentifier algorithm) throws GeneralSecurityException { String algorithmName = (String)BASE_CIPHER_NAMES.get(algorithm); try { if (algorithmName != null) { try { // this is reversed as the Sun policy files now allow unlimited strength RSA return helper.createAlgorithmParameterGenerator(algorithmName); } catch (NoSuchAlgorithmException e) { // Ignore } } return helper.createAlgorithmParameterGenerator(algorithm.getId()); } catch (NoSuchAlgorithmException e) { throw new GeneralSecurityException(e.toString()); } catch (NoSuchProviderException e) { throw new GeneralSecurityException(e.toString()); } } AlgorithmParameters generateParameters(ASN1ObjectIdentifier encryptionOID, SecretKey encKey, SecureRandom rand) throws CRMFException { try { AlgorithmParameterGenerator pGen = createAlgorithmParameterGenerator(encryptionOID); if (encryptionOID.equals(CMSEnvelopedDataGenerator.RC2_CBC)) { byte[] iv = new byte[8]; rand.nextBytes(iv); try { pGen.init(new RC2ParameterSpec(encKey.getEncoded().length * 8, iv), rand); } catch (InvalidAlgorithmParameterException e) { throw new CRMFException("parameters generation error: " + e, e); } } return pGen.generateParameters(); } catch (GeneralSecurityException e) { throw new CRMFException("exception creating algorithm parameter generator: " + e, e); } } AlgorithmIdentifier getAlgorithmIdentifier(ASN1ObjectIdentifier encryptionOID, AlgorithmParameters params) throws CRMFException { ASN1Encodable asn1Params; if (params != null) { try { asn1Params = ASN1Primitive.fromByteArray(params.getEncoded("ASN.1")); } catch (IOException e) { throw new CRMFException("cannot encode parameters: " + e.getMessage(), e); } } else { asn1Params = DERNull.INSTANCE; } return new AlgorithmIdentifier( encryptionOID, asn1Params); } static Object execute(JCECallback callback) throws CRMFException { try { return callback.doInJCE(); } catch (NoSuchAlgorithmException e) { throw new CRMFException("can't find algorithm.", e); } catch (InvalidKeyException e) { throw new CRMFException("key invalid in message.", e); } catch (NoSuchProviderException e) { throw new CRMFException("can't find provider.", e); } catch (NoSuchPaddingException e) { throw new CRMFException("required padding not supported.", e); } catch (InvalidAlgorithmParameterException e) { throw new CRMFException("algorithm parameters invalid.", e); } catch (InvalidParameterSpecException e) { throw new CRMFException("MAC algorithm parameter spec invalid.", e); } } static interface JCECallback { Object doInJCE() throws CRMFException, InvalidAlgorithmParameterException, InvalidKeyException, InvalidParameterSpecException, NoSuchAlgorithmException, NoSuchPaddingException, NoSuchProviderException; } } bouncycastle-1.49.orig/jdk1.1/org/bouncycastle/cert/crmf/jcajce/JcePKMACValuesCalculator.java0000644000175000017500000000362111731466725031336 0ustar ebourgebourgpackage org.bouncycastle.cert.crmf.jcajce; import java.security.GeneralSecurityException; import java.security.MessageDigest; import java.security.Provider; import java.security.InvalidKeyException; import javax.crypto.Mac; import javax.crypto.spec.SecretKeySpec; import org.bouncycastle.asn1.x509.AlgorithmIdentifier; import org.bouncycastle.cert.crmf.CRMFException; import org.bouncycastle.cert.crmf.PKMACValuesCalculator; import org.bouncycastle.jcajce.DefaultJcaJceHelper; import org.bouncycastle.jcajce.NamedJcaJceHelper; import org.bouncycastle.jcajce.ProviderJcaJceHelper; public class JcePKMACValuesCalculator implements PKMACValuesCalculator { private MessageDigest digest; private Mac mac; private CRMFHelper helper; public JcePKMACValuesCalculator() { this.helper = new CRMFHelper(new DefaultJcaJceHelper()); } public JcePKMACValuesCalculator setProvider(Provider provider) { this.helper = new CRMFHelper(new ProviderJcaJceHelper(provider)); return this; } public JcePKMACValuesCalculator setProvider(String providerName) { this.helper = new CRMFHelper(new NamedJcaJceHelper(providerName)); return this; } public void setup(AlgorithmIdentifier digAlg, AlgorithmIdentifier macAlg) throws CRMFException { digest = helper.createDigest(digAlg.getAlgorithm()); mac = helper.createMac(macAlg.getAlgorithm()); } public byte[] calculateDigest(byte[] data) { return digest.digest(data); } public byte[] calculateMac(byte[] pwd, byte[] data) throws CRMFException { try { mac.init(new SecretKeySpec(pwd, mac.getAlgorithm())); return mac.doFinal(data); } catch (InvalidKeyException e) { throw new CRMFException("failure in setup: " + e.getMessage(), e); } } } bouncycastle-1.49.orig/jdk1.1/org/bouncycastle/cert/selector/0000755000175000017500000000000012152033551023455 5ustar ebourgebourgbouncycastle-1.49.orig/jdk1.1/org/bouncycastle/cert/selector/jcajce/0000755000175000017500000000000012152033551024674 5ustar ebourgebourg././@LongLink0000000000000000000000000000014600000000000011566 Lustar rootrootbouncycastle-1.49.orig/jdk1.1/org/bouncycastle/cert/selector/jcajce/JcaX509CertSelectorConverter.javabouncycastle-1.49.orig/jdk1.1/org/bouncycastle/cert/selector/jcajce/JcaX509CertSelectorConverter.jav0000644000175000017500000000316211730751564032706 0ustar ebourgebourgpackage org.bouncycastle.cert.selector.jcajce; import java.io.IOException; import java.math.BigInteger; import java.security.cert.X509CertSelector; import org.bouncycastle.asn1.DEROctetString; import org.bouncycastle.asn1.x500.X500Name; import org.bouncycastle.cert.selector.X509CertificateHolderSelector; public class JcaX509CertSelectorConverter { public JcaX509CertSelectorConverter() { } protected X509CertSelector doConversion(X500Name issuer, BigInteger serialNumber, byte[] subjectKeyIdentifier) { X509CertSelector selector = new X509CertSelector(); if (issuer != null) { try { selector.setIssuer(issuer.getEncoded()); } catch (IOException e) { throw new IllegalArgumentException("unable to convert issuer: " + e.getMessage()); } } if (serialNumber != null) { selector.setSerialNumber(serialNumber); } if (subjectKeyIdentifier != null) { try { selector.setSubjectKeyIdentifier(new DEROctetString(subjectKeyIdentifier).getEncoded()); } catch (IOException e) { throw new IllegalArgumentException("unable to convert issuer: " + e.getMessage()); } } return selector; } public X509CertSelector getCertSelector(X509CertificateHolderSelector holderSelector) { return doConversion(holderSelector.getIssuer(), holderSelector.getSerialNumber(), holderSelector.getSubjectKeyIdentifier()); } } bouncycastle-1.49.orig/jdk1.1/org/bouncycastle/cert/selector/jcajce/JcaSelectorConverter.java0000644000175000017500000000201211730751564031634 0ustar ebourgebourgpackage org.bouncycastle.cert.selector.jcajce; import java.security.cert.X509CertSelector; import org.bouncycastle.asn1.ASN1OctetString; import org.bouncycastle.asn1.x500.X500Name; import org.bouncycastle.cert.selector.X509CertificateHolderSelector; public class JcaSelectorConverter { public JcaSelectorConverter() { } public X509CertificateHolderSelector getCertificateHolderSelector(X509CertSelector certSelector) { try { if (certSelector.getSubjectKeyIdentifier() != null) { return new X509CertificateHolderSelector(X500Name.getInstance(certSelector.getIssuerAsBytes()), certSelector.getSerialNumber(), ASN1OctetString.getInstance(certSelector.getSubjectKeyIdentifier()).getOctets()); } else { return new X509CertificateHolderSelector(X500Name.getInstance(certSelector.getIssuerAsBytes()), certSelector.getSerialNumber()); } } catch (Exception e) { throw new IllegalArgumentException("conversion failed: " + e.toString()); } } } bouncycastle-1.49.orig/jdk1.1/org/bouncycastle/cert/cmp/0000755000175000017500000000000012152033551022414 5ustar ebourgebourgbouncycastle-1.49.orig/jdk1.1/org/bouncycastle/cert/cmp/GeneralPKIMessage.java0000644000175000017500000000401311731466725026522 0ustar ebourgebourgpackage org.bouncycastle.cert.cmp; import java.io.IOException; import org.bouncycastle.asn1.ASN1Primitive; import org.bouncycastle.asn1.cmp.PKIBody; import org.bouncycastle.asn1.cmp.PKIHeader; import org.bouncycastle.asn1.cmp.PKIMessage; import org.bouncycastle.cert.CertIOException; /** * General wrapper for a generic PKIMessage */ public class GeneralPKIMessage { private PKIMessage pkiMessage; private static PKIMessage parseBytes(byte[] encoding) throws IOException { try { return PKIMessage.getInstance(ASN1Primitive.fromByteArray(encoding)); } catch (ClassCastException e) { throw new CertIOException("malformed data: " + e.getMessage(), e); } catch (IllegalArgumentException e) { throw new CertIOException("malformed data: " + e.getMessage(), e); } } /** * Create a PKIMessage from the passed in bytes. * * @param encoding BER/DER encoding of the PKIMessage * @throws IOException in the event of corrupted data, or an incorrect structure. */ public GeneralPKIMessage(byte[] encoding) throws IOException { this(parseBytes(encoding)); } /** * Wrap a PKIMessage ASN.1 structure. * * @param pkiMessage base PKI message. */ public GeneralPKIMessage(PKIMessage pkiMessage) { this.pkiMessage = pkiMessage; } public PKIHeader getHeader() { return pkiMessage.getHeader(); } public PKIBody getBody() { return pkiMessage.getBody(); } /** * Return true if this message has protection bits on it. A return value of true * indicates the message can be used to construct a ProtectedPKIMessage. * * @return true if message has protection, false otherwise. */ public boolean hasProtection() { return pkiMessage.getHeader().getProtectionAlg() != null; } public PKIMessage toASN1Structure() { return pkiMessage; } } bouncycastle-1.49.orig/jdk1.1/org/bouncycastle/cert/test/0000755000175000017500000000000012152033551022614 5ustar ebourgebourgbouncycastle-1.49.orig/jdk1.1/org/bouncycastle/cert/test/PKCS10Test.java0000644000175000017500000004650012147310320025221 0ustar ebourgebourgpackage org.bouncycastle.cert.test; import java.math.BigInteger; import java.security.KeyFactory; import java.security.KeyPair; import java.security.KeyPairGenerator; import java.security.PrivateKey; import java.security.PublicKey; import java.security.SecureRandom; import java.security.Security; import java.security.Signature; import java.security.spec.RSAPrivateCrtKeySpec; import java.security.spec.RSAPublicKeySpec; import java.util.Vector; import org.bouncycastle.asn1.DERObjectIdentifier; import org.bouncycastle.asn1.DEROctetString; import org.bouncycastle.asn1.cryptopro.CryptoProObjectIdentifiers; import org.bouncycastle.asn1.pkcs.Attribute; import org.bouncycastle.asn1.pkcs.PKCSObjectIdentifiers; import org.bouncycastle.asn1.x500.X500Name; import org.bouncycastle.asn1.x500.X500NameBuilder; import org.bouncycastle.asn1.x500.style.BCStyle; import org.bouncycastle.asn1.x509.BasicConstraints; import org.bouncycastle.asn1.x509.KeyUsage; import org.bouncycastle.asn1.x509.SubjectKeyIdentifier; import org.bouncycastle.asn1.x509.X509Extension; import org.bouncycastle.asn1.x509.X509Extensions; import org.bouncycastle.asn1.x9.X9ObjectIdentifiers; import org.bouncycastle.jce.ECGOST3410NamedCurveTable; import org.bouncycastle.jce.ECNamedCurveTable; import org.bouncycastle.jce.interfaces.ECPointEncoder; import org.bouncycastle.jce.provider.BouncyCastleProvider; import org.bouncycastle.jce.spec.ECNamedCurveParameterSpec; import org.bouncycastle.jce.spec.ECParameterSpec; import org.bouncycastle.jce.spec.ECPrivateKeySpec; import org.bouncycastle.jce.spec.ECPublicKeySpec; import org.bouncycastle.math.ec.ECCurve; import org.bouncycastle.operator.ContentSigner; import org.bouncycastle.operator.ContentVerifierProvider; import org.bouncycastle.operator.jcajce.JcaContentSignerBuilder; import org.bouncycastle.operator.jcajce.JcaContentVerifierProviderBuilder; import org.bouncycastle.pkcs.PKCS10CertificationRequest; import org.bouncycastle.pkcs.PKCS10CertificationRequestBuilder; import org.bouncycastle.pkcs.jcajce.JcaPKCS10CertificationRequest; import org.bouncycastle.pkcs.jcajce.JcaPKCS10CertificationRequestBuilder; import org.bouncycastle.util.Arrays; import org.bouncycastle.util.encoders.Base64; import org.bouncycastle.util.encoders.Hex; import org.bouncycastle.util.test.SimpleTest; import org.bouncycastle.x509.extension.SubjectKeyIdentifierStructure; /** **/ public class PKCS10Test extends SimpleTest { private static final String BC = BouncyCastleProvider.PROVIDER_NAME; private byte[] gost3410EC_A = Base64.decode( "MIIBOzCB6wIBADB/MQ0wCwYDVQQDEwR0ZXN0MRUwEwYDVQQKEwxEZW1vcyBDbyBMdGQxHjAcBgNV" +"BAsTFUNyeXB0b2dyYXBoeSBkaXZpc2lvbjEPMA0GA1UEBxMGTW9zY293MQswCQYDVQQGEwJydTEZ" +"MBcGCSqGSIb3DQEJARYKc2RiQGRvbC5ydTBjMBwGBiqFAwICEzASBgcqhQMCAiMBBgcqhQMCAh4B" +"A0MABEBYx0P2D7YuuZo5HgdIAUKAXcLBDZ+4LYFgbKjrfStVfH59lc40BQ2FZ7M703hLpXK8GiBQ" +"GEYpKaAuQZnMIpByoAAwCAYGKoUDAgIDA0EAgXMcTrhdOY2Er2tHOSAgnMezqrYxocZTWhxmW5Rl" +"JY6lbXH5rndCn4swFzXU+YhgAsJv1wQBaoZEWRl5WV4/nA=="); private byte[] gost3410EC_B = Base64.decode( "MIIBPTCB7QIBADCBgDENMAsGA1UEAxMEdGVzdDEWMBQGA1UEChMNRGVtb3MgQ28gTHRkLjEeMBwG" +"A1UECxMVQ3J5cHRvZ3JhcGh5IGRpdmlzaW9uMQ8wDQYDVQQHEwZNb3Njb3cxCzAJBgNVBAYTAnJ1" +"MRkwFwYJKoZIhvcNAQkBFgpzZGJAZG9sLnJ1MGMwHAYGKoUDAgITMBIGByqFAwICIwIGByqFAwIC" +"HgEDQwAEQI5SLoWT7dZVilbV9j5B/fyIDuDs6x4pjqNC2TtFYbpRHrk/Wc5g/mcHvD80tsm5o1C7" +"7cizNzkvAVUM4VT4Dz6gADAIBgYqhQMCAgMDQQAoT5TwJ8o+bSrxckymyo3diwG7ZbSytX4sRiKy" +"wXPWRS9LlBvPO2NqwpS2HUnxSU8rzfL9fJcybATf7Yt1OEVq"); private byte[] gost3410EC_C = Base64.decode( "MIIBRDCB9AIBADCBhzEVMBMGA1UEAxMMdGVzdCByZXF1ZXN0MRUwEwYDVQQKEwxEZW1vcyBDbyBM" +"dGQxHjAcBgNVBAsTFUNyeXB0b2dyYXBoeSBkaXZpc2lvbjEPMA0GA1UEBxMGTW9zY293MQswCQYD" +"VQQGEwJydTEZMBcGCSqGSIb3DQEJARYKc2RiQGRvbC5ydTBjMBwGBiqFAwICEzASBgcqhQMCAiMD" +"BgcqhQMCAh4BA0MABEBcmGh7OmR4iqqj+ycYo1S1fS7r5PhisSQU2Ezuz8wmmmR2zeTZkdMYCOBa" +"UTMNms0msW3wuYDho7nTDNscHTB5oAAwCAYGKoUDAgIDA0EAVoOMbfyo1Un4Ss7WQrUjHJoiaYW8" +"Ime5LeGGU2iW3ieAv6es/FdMrwTKkqn5dhd3aL/itFg5oQbhyfXw5yw/QQ=="); private byte[] gost3410EC_ExA = Base64.decode( "MIIBOzCB6wIBADB/MQ0wCwYDVQQDEwR0ZXN0MRUwEwYDVQQKEwxEZW1vcyBDbyBMdGQxHjAcBgNV" + "BAsTFUNyeXB0b2dyYXBoeSBkaXZpc2lvbjEPMA0GA1UEBxMGTW9zY293MQswCQYDVQQGEwJydTEZ" + "MBcGCSqGSIb3DQEJARYKc2RiQGRvbC5ydTBjMBwGBiqFAwICEzASBgcqhQMCAiQABgcqhQMCAh4B" + "A0MABEDkqNT/3f8NHj6EUiWnK4JbVZBh31bEpkwq9z3jf0u8ZndG56Vt+K1ZB6EpFxLT7hSIos0w" + "weZ2YuTZ4w43OgodoAAwCAYGKoUDAgIDA0EASk/IUXWxoi6NtcUGVF23VRV1L3undB4sRZLp4Vho" + "gQ7m3CMbZFfJ2cPu6QyarseXGYHmazoirH5lGjEo535c1g=="); private byte[] gost3410EC_ExB = Base64.decode( "MIIBPTCB7QIBADCBgDENMAsGA1UEAxMEdGVzdDEWMBQGA1UEChMNRGVtb3MgQ28gTHRkLjEeMBwG" + "A1UECxMVQ3J5cHRvZ3JhcGh5IGRpdmlzaW9uMQ8wDQYDVQQHEwZNb3Njb3cxCzAJBgNVBAYTAnJ1" + "MRkwFwYJKoZIhvcNAQkBFgpzZGJAZG9sLnJ1MGMwHAYGKoUDAgITMBIGByqFAwICJAEGByqFAwIC" + "HgEDQwAEQMBWYUKPy/1Kxad9ChAmgoSWSYOQxRnXo7KEGLU5RNSXA4qMUvArWzvhav+EYUfTbWLh" + "09nELDyHt2XQcvgQHnSgADAIBgYqhQMCAgMDQQAdaNhgH/ElHp64mbMaEo1tPCg9Q22McxpH8rCz" + "E0QBpF4H5mSSQVGI5OAXHToetnNuh7gHHSynyCupYDEHTbkZ"); public String getName() { return "PKCS10CertRequest"; } private void generationTest(int keySize, String keyName, String sigName, String provider) throws Exception { KeyPairGenerator kpg = KeyPairGenerator.getInstance(keyName, "BC"); kpg.initialize(keySize); KeyPair kp = kpg.generateKeyPair(); X500NameBuilder x500NameBld = new X500NameBuilder(BCStyle.INSTANCE); x500NameBld.addRDN(BCStyle.C, "AU"); x500NameBld.addRDN(BCStyle.O, "The Legion of the Bouncy Castle"); x500NameBld.addRDN(BCStyle.L, "Melbourne"); x500NameBld.addRDN(BCStyle.ST, "Victoria"); x500NameBld.addRDN(BCStyle.EmailAddress, "feedback-crypto@bouncycastle.org"); X500Name subject = x500NameBld.build(); PKCS10CertificationRequestBuilder requestBuilder = new JcaPKCS10CertificationRequestBuilder(subject, kp.getPublic()); PKCS10CertificationRequest req1 = requestBuilder.build(new JcaContentSignerBuilder(sigName).setProvider(provider).build(kp.getPrivate())); JcaPKCS10CertificationRequest req2 = new JcaPKCS10CertificationRequest(req1.getEncoded()).setProvider(provider); if (!req2.isSignatureValid(new JcaContentVerifierProviderBuilder().setProvider(provider).build(kp.getPublic()))) { fail(sigName + ": Failed verify check."); } if (!Arrays.areEqual(req2.getPublicKey().getEncoded(), req1.getSubjectPublicKeyInfo().getEncoded())) { fail(keyName + ": Failed public key check."); } } private void createECRequest(String algorithm, DERObjectIdentifier algOid) throws Exception { ECCurve.Fp curve = new ECCurve.Fp( new BigInteger("6864797660130609714981900799081393217269435300143305409394463459185543183397656052122559640661454554977296311391480858037121987999716643812574028291115057151"), // q (or p) new BigInteger("01FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFC", 16), // a new BigInteger("0051953EB9618E1C9A1F929A21A0B68540EEA2DA725B99B315F3B8B489918EF109E156193951EC7E937B1652C0BD3BB1BF073573DF883D2C34F1EF451FD46B503F00", 16)); // b ECParameterSpec spec = new ECParameterSpec( curve, curve.decodePoint(Hex.decode("0200C6858E06B70404E9CD9E3ECB662395B4429C648139053FB521F828AF606B4D3DBAA14B5E77EFE75928FE1DC127A2FFA8DE3348B3C1856A429BF97E7E31C2E5BD66")), // G new BigInteger("01FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFA51868783BF2F966B7FCC0148F709A5D03BB5C9B8899C47AEBB6FB71E91386409", 16)); // n ECPrivateKeySpec privKeySpec = new ECPrivateKeySpec( new BigInteger("5769183828869504557786041598510887460263120754767955773309066354712783118202294874205844512909370791582896372147797293913785865682804434049019366394746072023"), // d spec); ECPublicKeySpec pubKeySpec = new ECPublicKeySpec( curve.decodePoint(Hex.decode("02006BFDD2C9278B63C92D6624F151C9D7A822CC75BD983B17D25D74C26740380022D3D8FAF304781E416175EADF4ED6E2B47142D2454A7AC7801DD803CF44A4D1F0AC")), // Q spec); // // set up the keys // PrivateKey privKey; PublicKey pubKey; KeyFactory fact = KeyFactory.getInstance("ECDSA", "BC"); privKey = fact.generatePrivate(privKeySpec); pubKey = fact.generatePublic(pubKeySpec); PKCS10CertificationRequest req = new JcaPKCS10CertificationRequestBuilder( new X500Name("CN=XXX"), pubKey).build(new JcaContentSignerBuilder(algorithm).setProvider(BC).build(privKey)); if (!req.isSignatureValid(new JcaContentVerifierProviderBuilder().setProvider(BC).build(pubKey))) { fail("Failed verify check EC."); } req = new PKCS10CertificationRequest(req.getEncoded()); if (!req.isSignatureValid(new JcaContentVerifierProviderBuilder().setProvider(BC).build(pubKey))) { fail("Failed verify check EC encoded."); } // // try with point compression turned off // ((ECPointEncoder)pubKey).setPointFormat("UNCOMPRESSED"); req = new JcaPKCS10CertificationRequestBuilder( new X500Name("CN=XXX"), pubKey).build(new JcaContentSignerBuilder(algorithm).setProvider(BC).build(privKey)); if (!req.isSignatureValid(new JcaContentVerifierProviderBuilder().setProvider(BC).build(pubKey))) { fail("Failed verify check EC uncompressed."); } JcaPKCS10CertificationRequest jcaReq = new JcaPKCS10CertificationRequest(new PKCS10CertificationRequest(req.getEncoded())); if (!jcaReq.isSignatureValid(new JcaContentVerifierProviderBuilder().setProvider(BC).build(jcaReq.getPublicKey()))) { fail("Failed verify check EC uncompressed encoded."); } if (!jcaReq.getSignatureAlgorithm().getAlgorithm().equals(algOid)) { fail("ECDSA oid incorrect."); } if (jcaReq.getSignatureAlgorithm().getParameters() != null) { fail("ECDSA parameters incorrect."); } Signature sig = Signature.getInstance(algorithm, BC); sig.initVerify(pubKey); sig.update(req.toASN1Structure().getCertificationRequestInfo().getEncoded()); if (!sig.verify(req.getSignature())) { fail("signature not mapped correctly."); } } private void createPSSTest(String algorithm) throws Exception { RSAPublicKeySpec pubKeySpec = new RSAPublicKeySpec( new BigInteger("a56e4a0e701017589a5187dc7ea841d156f2ec0e36ad52a44dfeb1e61f7ad991d8c51056ffedb162b4c0f283a12a88a394dff526ab7291cbb307ceabfce0b1dfd5cd9508096d5b2b8b6df5d671ef6377c0921cb23c270a70e2598e6ff89d19f105acc2d3f0cb35f29280e1386b6f64c4ef22e1e1f20d0ce8cffb2249bd9a2137",16), new BigInteger("010001",16)); RSAPrivateCrtKeySpec privKeySpec = new RSAPrivateCrtKeySpec( new BigInteger("a56e4a0e701017589a5187dc7ea841d156f2ec0e36ad52a44dfeb1e61f7ad991d8c51056ffedb162b4c0f283a12a88a394dff526ab7291cbb307ceabfce0b1dfd5cd9508096d5b2b8b6df5d671ef6377c0921cb23c270a70e2598e6ff89d19f105acc2d3f0cb35f29280e1386b6f64c4ef22e1e1f20d0ce8cffb2249bd9a2137",16), new BigInteger("010001",16), new BigInteger("33a5042a90b27d4f5451ca9bbbd0b44771a101af884340aef9885f2a4bbe92e894a724ac3c568c8f97853ad07c0266c8c6a3ca0929f1e8f11231884429fc4d9ae55fee896a10ce707c3ed7e734e44727a39574501a532683109c2abacaba283c31b4bd2f53c3ee37e352cee34f9e503bd80c0622ad79c6dcee883547c6a3b325",16), new BigInteger("e7e8942720a877517273a356053ea2a1bc0c94aa72d55c6e86296b2dfc967948c0a72cbccca7eacb35706e09a1df55a1535bd9b3cc34160b3b6dcd3eda8e6443",16), new BigInteger("b69dca1cf7d4d7ec81e75b90fcca874abcde123fd2700180aa90479b6e48de8d67ed24f9f19d85ba275874f542cd20dc723e6963364a1f9425452b269a6799fd",16), new BigInteger("28fa13938655be1f8a159cbaca5a72ea190c30089e19cd274a556f36c4f6e19f554b34c077790427bbdd8dd3ede2448328f385d81b30e8e43b2fffa027861979",16), new BigInteger("1a8b38f398fa712049898d7fb79ee0a77668791299cdfa09efc0e507acb21ed74301ef5bfd48be455eaeb6e1678255827580a8e4e8e14151d1510a82a3f2e729",16), new BigInteger("27156aba4126d24a81f3a528cbfb27f56886f840a9f6e86e17a44b94fe9319584b8e22fdde1e5a2e3bd8aa5ba8d8584194eb2190acf832b847f13a3d24a79f4d",16)); KeyFactory fact = KeyFactory.getInstance("RSA", "BC"); PrivateKey privKey = fact.generatePrivate(privKeySpec); PublicKey pubKey = fact.generatePublic(pubKeySpec); PKCS10CertificationRequest req = new JcaPKCS10CertificationRequestBuilder( new X500Name("CN=XXX"), pubKey).build(new JcaContentSignerBuilder(algorithm).setProvider(BC).build(privKey)); if (!req.isSignatureValid(new JcaContentVerifierProviderBuilder().setProvider(BC).build(pubKey))) { fail("Failed verify check PSS."); } JcaPKCS10CertificationRequest jcaReq = new JcaPKCS10CertificationRequest(req.getEncoded()).setProvider(BC); if (!jcaReq.isSignatureValid(new JcaContentVerifierProviderBuilder().setProvider(BC).build(jcaReq.getPublicKey()))) { fail("Failed verify check PSS encoded."); } if (!jcaReq.getSignatureAlgorithm().getAlgorithm().equals(PKCSObjectIdentifiers.id_RSASSA_PSS)) { fail("PSS oid incorrect."); } if (jcaReq.getSignatureAlgorithm().getParameters() == null) { fail("PSS parameters incorrect."); } Signature sig = Signature.getInstance(algorithm, "BC"); sig.initVerify(pubKey); sig.update(jcaReq.toASN1Structure().getCertificationRequestInfo().getEncoded()); if (!sig.verify(req.getSignature())) { fail("signature not mapped correctly."); } } // previous code found to cause a NullPointerException private void nullPointerTest() throws Exception { KeyPairGenerator keyGen = KeyPairGenerator.getInstance("RSA", "BC"); keyGen.initialize(1024, new SecureRandom()); KeyPair pair = keyGen.generateKeyPair(); Vector oids = new Vector(); Vector values = new Vector(); oids.addElement(X509Extension.basicConstraints); values.addElement(new X509Extension(true, new DEROctetString(new BasicConstraints(true)))); oids.addElement(X509Extension.keyUsage); values.addElement(new X509Extension(true, new DEROctetString( new KeyUsage(KeyUsage.keyCertSign | KeyUsage.cRLSign)))); SubjectKeyIdentifier subjectKeyIdentifier = new SubjectKeyIdentifierStructure(pair.getPublic()); X509Extension ski = new X509Extension(false, new DEROctetString(subjectKeyIdentifier)); oids.addElement(X509Extension.subjectKeyIdentifier); values.addElement(ski); PKCS10CertificationRequest p1 = new JcaPKCS10CertificationRequestBuilder( new X500Name("cn=csr"), pair.getPublic()) .addAttribute(PKCSObjectIdentifiers.pkcs_9_at_extensionRequest, new X509Extensions(oids, values)) .build(new JcaContentSignerBuilder("SHA1withRSA").setProvider(BC).build(pair.getPrivate())); PKCS10CertificationRequest p2 = new JcaPKCS10CertificationRequestBuilder( new X500Name("cn=csr"), pair.getPublic()) .addAttribute(PKCSObjectIdentifiers.pkcs_9_at_extensionRequest, new X509Extensions(oids, values)) .build(new JcaContentSignerBuilder("SHA1withRSA").setProvider(BC).build(pair.getPrivate())); if (!p1.equals(p2)) { fail("cert request comparison failed"); } Attribute[] attr1 = p1.getAttributes(); Attribute[] attr2 = p1.getAttributes(); checkAttrs(1, attr1, attr2); attr1 = p1.getAttributes(PKCSObjectIdentifiers.pkcs_9_at_extensionRequest); attr2 = p1.getAttributes(PKCSObjectIdentifiers.pkcs_9_at_extensionRequest); checkAttrs(1, attr1, attr2); } private void checkAttrs(int expectedLength, Attribute[] attr1, Attribute[] attr2) { if (expectedLength != attr1.length) { fail("expected length mismatch"); } if (attr1.length != attr2.length) { fail("atrribute length mismatch"); } for (int i = 0; i != attr1.length; i++) { if (!attr1[i].equals(attr2[i])) { fail("atrribute mismatch"); } } } public void performTest() throws Exception { generationTest(512, "RSA", "SHA1withRSA", "BC"); generationTest(512, "GOST3410", "GOST3411withGOST3410", "BC"); if (Security.getProvider("SunRsaSign") != null) { generationTest(512, "RSA", "SHA1withRSA", "SunRsaSign"); } // elliptic curve GOST A parameter set JcaPKCS10CertificationRequest req = new JcaPKCS10CertificationRequest(gost3410EC_A).setProvider(BC); if (!req.isSignatureValid(new JcaContentVerifierProviderBuilder().setProvider(BC).build(req.getPublicKey()))) { fail("Failed verify check gost3410EC_A."); } // elliptic curve GOST B parameter set req = new JcaPKCS10CertificationRequest(gost3410EC_B).setProvider(BC); if (!req.isSignatureValid(new JcaContentVerifierProviderBuilder().setProvider(BC).build(req.getPublicKey()))) { fail("Failed verify check gost3410EC_B."); } // elliptic curve GOST C parameter set req = new JcaPKCS10CertificationRequest(gost3410EC_C).setProvider(BC); if (!req.isSignatureValid(new JcaContentVerifierProviderBuilder().setProvider(BC).build(req.getPublicKey()))) { fail("Failed verify check gost3410EC_C."); } // elliptic curve GOST ExA parameter set req = new JcaPKCS10CertificationRequest(gost3410EC_ExA).setProvider(BC); if (!req.isSignatureValid(new JcaContentVerifierProviderBuilder().setProvider(BC).build(req.getPublicKey()))) { fail("Failed verify check gost3410EC_ExA."); } // elliptic curve GOST ExB parameter set req = new JcaPKCS10CertificationRequest(gost3410EC_ExB).setProvider(BC); if (!req.isSignatureValid(new JcaContentVerifierProviderBuilder().setProvider(BC).build(req.getPublicKey()))) { fail("Failed verify check gost3410EC_ExA."); } createECRequest("SHA1withECDSA", X9ObjectIdentifiers.ecdsa_with_SHA1); createECRequest("SHA224withECDSA", X9ObjectIdentifiers.ecdsa_with_SHA224); createECRequest("SHA256withECDSA", X9ObjectIdentifiers.ecdsa_with_SHA256); createECRequest("SHA384withECDSA", X9ObjectIdentifiers.ecdsa_with_SHA384); createECRequest("SHA512withECDSA", X9ObjectIdentifiers.ecdsa_with_SHA512); createPSSTest("SHA1withRSAandMGF1"); createPSSTest("SHA224withRSAandMGF1"); createPSSTest("SHA256withRSAandMGF1"); createPSSTest("SHA384withRSAandMGF1"); nullPointerTest(); } public static void main( String[] args) { Security.addProvider(new BouncyCastleProvider()); runTest(new PKCS10Test()); } } bouncycastle-1.49.orig/jdk1.1/org/bouncycastle/cert/test/CertTest.java0000644000175000017500000042717512147310320025230 0ustar ebourgebourgpackage org.bouncycastle.cert.test; import java.io.ByteArrayInputStream; import java.io.IOException; import java.io.UnsupportedEncodingException; import java.math.BigInteger; import java.security.KeyFactory; import java.security.KeyPair; import java.security.KeyPairGenerator; import java.security.KeyStore; import java.security.NoSuchAlgorithmException; import java.security.NoSuchProviderException; import java.security.PrivateKey; import java.security.PublicKey; import java.security.SecureRandom; import java.security.Security; import java.security.Signature; import java.security.cert.CRL; import java.security.cert.Certificate; import java.security.cert.CertificateException; import java.security.cert.CertificateFactory; import java.security.cert.X509CRL; import java.security.cert.X509CRLEntry; import java.security.cert.X509Certificate; import java.security.spec.InvalidKeySpecException; import java.security.spec.RSAPrivateCrtKeySpec; import java.security.spec.RSAPublicKeySpec; import java.util.Collection; import java.util.Date; import java.util.Iterator; import java.util.Set; import java.util.Vector; import org.bouncycastle.asn1.ASN1Encodable; import org.bouncycastle.asn1.ASN1EncodableVector; import org.bouncycastle.asn1.ASN1Enumerated; import org.bouncycastle.asn1.ASN1ObjectIdentifier; import org.bouncycastle.asn1.ASN1Primitive; import org.bouncycastle.asn1.DEREnumerated; import org.bouncycastle.asn1.DERNull; import org.bouncycastle.asn1.DERObjectIdentifier; import org.bouncycastle.asn1.DEROctetString; import org.bouncycastle.asn1.DERSequence; import org.bouncycastle.asn1.pkcs.PKCSObjectIdentifiers; import org.bouncycastle.asn1.pkcs.RSAPublicKey; import org.bouncycastle.asn1.x500.X500Name; import org.bouncycastle.asn1.x500.X500NameBuilder; import org.bouncycastle.asn1.x500.style.BCStyle; import org.bouncycastle.asn1.x509.AlgorithmIdentifier; import org.bouncycastle.asn1.x509.AuthorityKeyIdentifier; import org.bouncycastle.asn1.x509.CRLReason; import org.bouncycastle.asn1.x509.Extension; import org.bouncycastle.asn1.x509.ExtensionsGenerator; import org.bouncycastle.asn1.x509.GeneralName; import org.bouncycastle.asn1.x509.GeneralNames; import org.bouncycastle.asn1.x509.IssuingDistributionPoint; import org.bouncycastle.asn1.x509.KeyPurposeId; import org.bouncycastle.asn1.x509.SubjectPublicKeyInfo; import org.bouncycastle.asn1.x509.X509CertificateStructure; import org.bouncycastle.asn1.x509.X509Extension; import org.bouncycastle.asn1.x509.X509Extensions; import org.bouncycastle.asn1.x9.X9ObjectIdentifiers; import org.bouncycastle.cert.X509CRLEntryHolder; import org.bouncycastle.cert.X509CRLHolder; import org.bouncycastle.cert.X509CertificateHolder; import org.bouncycastle.cert.X509v1CertificateBuilder; import org.bouncycastle.cert.X509v2CRLBuilder; import org.bouncycastle.cert.X509v3CertificateBuilder; import org.bouncycastle.cert.jcajce.JcaX509CRLConverter; import org.bouncycastle.cert.jcajce.JcaX509CRLHolder; import org.bouncycastle.cert.jcajce.JcaX509CertificateConverter; import org.bouncycastle.cert.jcajce.JcaX509CertificateHolder; import org.bouncycastle.cert.jcajce.JcaX509v1CertificateBuilder; import org.bouncycastle.cert.jcajce.JcaX509v2CRLBuilder; import org.bouncycastle.cert.jcajce.JcaX509v3CertificateBuilder; import org.bouncycastle.crypto.params.RSAKeyParameters; import org.bouncycastle.crypto.params.RSAPrivateCrtKeyParameters; import org.bouncycastle.jce.PrincipalUtil; import org.bouncycastle.jce.X509KeyUsage; import org.bouncycastle.jce.X509Principal; import org.bouncycastle.jce.interfaces.ECPointEncoder; import org.bouncycastle.jce.provider.BouncyCastleProvider; import org.bouncycastle.jce.spec.ECParameterSpec; import org.bouncycastle.jce.spec.ECPrivateKeySpec; import org.bouncycastle.jce.spec.ECPublicKeySpec; import org.bouncycastle.jce.spec.GOST3410ParameterSpec; import org.bouncycastle.math.ec.ECCurve; import org.bouncycastle.operator.ContentSigner; import org.bouncycastle.operator.ContentVerifierProvider; import org.bouncycastle.operator.DefaultDigestAlgorithmIdentifierFinder; import org.bouncycastle.operator.DefaultSignatureAlgorithmIdentifierFinder; import org.bouncycastle.operator.bc.BcRSAContentSignerBuilder; import org.bouncycastle.operator.bc.BcRSAContentVerifierProviderBuilder; import org.bouncycastle.operator.jcajce.JcaContentSignerBuilder; import org.bouncycastle.operator.jcajce.JcaContentVerifierProviderBuilder; import org.bouncycastle.util.encoders.Base64; import org.bouncycastle.util.encoders.Hex; import org.bouncycastle.util.test.SimpleTest; import org.bouncycastle.x509.extension.AuthorityKeyIdentifierStructure; import org.bouncycastle.x509.extension.X509ExtensionUtil; public class CertTest extends SimpleTest { private static final String BC = org.bouncycastle.jce.provider.BouncyCastleProvider.PROVIDER_NAME; // test CA byte[] testCAp12 = Base64.decode( "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" + "HLhcYQcQ1R+RucctAgIEAAAA"); // // server.crt // byte[] cert1 = Base64.decode( "MIIDXjCCAsegAwIBAgIBBzANBgkqhkiG9w0BAQQFADCBtzELMAkGA1UEBhMCQVUx" + "ETAPBgNVBAgTCFZpY3RvcmlhMRgwFgYDVQQHEw9Tb3V0aCBNZWxib3VybmUxGjAY" + "BgNVBAoTEUNvbm5lY3QgNCBQdHkgTHRkMR4wHAYDVQQLExVDZXJ0aWZpY2F0ZSBB" + "dXRob3JpdHkxFTATBgNVBAMTDENvbm5lY3QgNCBDQTEoMCYGCSqGSIb3DQEJARYZ" + "d2VibWFzdGVyQGNvbm5lY3Q0LmNvbS5hdTAeFw0wMDA2MDIwNzU2MjFaFw0wMTA2" + "MDIwNzU2MjFaMIG4MQswCQYDVQQGEwJBVTERMA8GA1UECBMIVmljdG9yaWExGDAW" + "BgNVBAcTD1NvdXRoIE1lbGJvdXJuZTEaMBgGA1UEChMRQ29ubmVjdCA0IFB0eSBM" + "dGQxFzAVBgNVBAsTDldlYnNlcnZlciBUZWFtMR0wGwYDVQQDExR3d3cyLmNvbm5l" + "Y3Q0LmNvbS5hdTEoMCYGCSqGSIb3DQEJARYZd2VibWFzdGVyQGNvbm5lY3Q0LmNv" + "bS5hdTCBnzANBgkqhkiG9w0BAQEFAAOBjQAwgYkCgYEArvDxclKAhyv7Q/Wmr2re" + "Gw4XL9Cnh9e+6VgWy2AWNy/MVeXdlxzd7QAuc1eOWQkGQEiLPy5XQtTY+sBUJ3AO" + "Rvd2fEVJIcjf29ey7bYua9J/vz5MG2KYo9/WCHIwqD9mmG9g0xLcfwq/s8ZJBswE" + "7sb85VU+h94PTvsWOsWuKaECAwEAAaN3MHUwJAYDVR0RBB0wG4EZd2VibWFzdGVy" + "QGNvbm5lY3Q0LmNvbS5hdTA6BglghkgBhvhCAQ0ELRYrbW9kX3NzbCBnZW5lcmF0" + "ZWQgY3VzdG9tIHNlcnZlciBjZXJ0aWZpY2F0ZTARBglghkgBhvhCAQEEBAMCBkAw" + "DQYJKoZIhvcNAQEEBQADgYEAotccfKpwSsIxM1Hae8DR7M/Rw8dg/RqOWx45HNVL" + "iBS4/3N/TO195yeQKbfmzbAA2jbPVvIvGgTxPgO1MP4ZgvgRhasaa0qCJCkWvpM4" + "yQf33vOiYQbpv4rTwzU8AmRlBG45WdjyNIigGV+oRc61aKCTnLq7zB8N3z1TF/bF" + "5/8="); // // ca.crt // byte[] cert2 = Base64.decode( "MIIDbDCCAtWgAwIBAgIBADANBgkqhkiG9w0BAQQFADCBtzELMAkGA1UEBhMCQVUx" + "ETAPBgNVBAgTCFZpY3RvcmlhMRgwFgYDVQQHEw9Tb3V0aCBNZWxib3VybmUxGjAY" + "BgNVBAoTEUNvbm5lY3QgNCBQdHkgTHRkMR4wHAYDVQQLExVDZXJ0aWZpY2F0ZSBB" + "dXRob3JpdHkxFTATBgNVBAMTDENvbm5lY3QgNCBDQTEoMCYGCSqGSIb3DQEJARYZ" + "d2VibWFzdGVyQGNvbm5lY3Q0LmNvbS5hdTAeFw0wMDA2MDIwNzU1MzNaFw0wMTA2" + "MDIwNzU1MzNaMIG3MQswCQYDVQQGEwJBVTERMA8GA1UECBMIVmljdG9yaWExGDAW" + "BgNVBAcTD1NvdXRoIE1lbGJvdXJuZTEaMBgGA1UEChMRQ29ubmVjdCA0IFB0eSBM" + "dGQxHjAcBgNVBAsTFUNlcnRpZmljYXRlIEF1dGhvcml0eTEVMBMGA1UEAxMMQ29u" + "bmVjdCA0IENBMSgwJgYJKoZIhvcNAQkBFhl3ZWJtYXN0ZXJAY29ubmVjdDQuY29t" + "LmF1MIGfMA0GCSqGSIb3DQEBAQUAA4GNADCBiQKBgQDgs5ptNG6Qv1ZpCDuUNGmv" + "rhjqMDPd3ri8JzZNRiiFlBA4e6/ReaO1U8ASewDeQMH6i9R6degFdQRLngbuJP0s" + "xcEE+SksEWNvygfzLwV9J/q+TQDyJYK52utb++lS0b48A1KPLwEsyL6kOAgelbur" + "ukwxowprKUIV7Knf1ajetQIDAQABo4GFMIGCMCQGA1UdEQQdMBuBGXdlYm1hc3Rl" + "ckBjb25uZWN0NC5jb20uYXUwDwYDVR0TBAgwBgEB/wIBADA2BglghkgBhvhCAQ0E" + "KRYnbW9kX3NzbCBnZW5lcmF0ZWQgY3VzdG9tIENBIGNlcnRpZmljYXRlMBEGCWCG" + "SAGG+EIBAQQEAwICBDANBgkqhkiG9w0BAQQFAAOBgQCsGvfdghH8pPhlwm1r3pQk" + "msnLAVIBb01EhbXm2861iXZfWqGQjrGAaA0ZpXNk9oo110yxoqEoSJSzniZa7Xtz" + "soTwNUpE0SLHvWf/SlKdFWlzXA+vOZbzEv4UmjeelekTm7lc01EEa5QRVzOxHFtQ" + "DhkaJ8VqOMajkQFma2r9iA=="); // // testx509.pem // byte[] cert3 = Base64.decode( "MIIBWzCCAQYCARgwDQYJKoZIhvcNAQEEBQAwODELMAkGA1UEBhMCQVUxDDAKBgNV" + "BAgTA1FMRDEbMBkGA1UEAxMSU1NMZWF5L3JzYSB0ZXN0IENBMB4XDTk1MDYxOTIz" + "MzMxMloXDTk1MDcxNzIzMzMxMlowOjELMAkGA1UEBhMCQVUxDDAKBgNVBAgTA1FM" + "RDEdMBsGA1UEAxMUU1NMZWF5L3JzYSB0ZXN0IGNlcnQwXDANBgkqhkiG9w0BAQEF" + "AANLADBIAkEAqtt6qS5GTxVxGZYWa0/4u+IwHf7p2LNZbcPBp9/OfIcYAXBQn8hO" + "/Re1uwLKXdCjIoaGs4DLdG88rkzfyK5dPQIDAQABMAwGCCqGSIb3DQIFBQADQQAE" + "Wc7EcF8po2/ZO6kNCwK/ICH6DobgLekA5lSLr5EvuioZniZp5lFzAw4+YzPQ7XKJ" + "zl9HYIMxATFyqSiD9jsx"); // // v3-cert1.pem // byte[] cert4 = Base64.decode( "MIICjTCCAfigAwIBAgIEMaYgRzALBgkqhkiG9w0BAQQwRTELMAkGA1UEBhMCVVMx" + "NjA0BgNVBAoTLU5hdGlvbmFsIEFlcm9uYXV0aWNzIGFuZCBTcGFjZSBBZG1pbmlz" + "dHJhdGlvbjAmFxE5NjA1MjgxMzQ5MDUrMDgwMBcROTgwNTI4MTM0OTA1KzA4MDAw" + "ZzELMAkGA1UEBhMCVVMxNjA0BgNVBAoTLU5hdGlvbmFsIEFlcm9uYXV0aWNzIGFu" + "ZCBTcGFjZSBBZG1pbmlzdHJhdGlvbjEgMAkGA1UEBRMCMTYwEwYDVQQDEwxTdGV2" + "ZSBTY2hvY2gwWDALBgkqhkiG9w0BAQEDSQAwRgJBALrAwyYdgxmzNP/ts0Uyf6Bp" + "miJYktU/w4NG67ULaN4B5CnEz7k57s9o3YY3LecETgQ5iQHmkwlYDTL2fTgVfw0C" + "AQOjgaswgagwZAYDVR0ZAQH/BFowWDBWMFQxCzAJBgNVBAYTAlVTMTYwNAYDVQQK" + "Ey1OYXRpb25hbCBBZXJvbmF1dGljcyBhbmQgU3BhY2UgQWRtaW5pc3RyYXRpb24x" + "DTALBgNVBAMTBENSTDEwFwYDVR0BAQH/BA0wC4AJODMyOTcwODEwMBgGA1UdAgQR" + "MA8ECTgzMjk3MDgyM4ACBSAwDQYDVR0KBAYwBAMCBkAwCwYJKoZIhvcNAQEEA4GB" + "AH2y1VCEw/A4zaXzSYZJTTUi3uawbbFiS2yxHvgf28+8Js0OHXk1H1w2d6qOHH21" + "X82tZXd/0JtG0g1T9usFFBDvYK8O0ebgz/P5ELJnBL2+atObEuJy1ZZ0pBDWINR3" + "WkDNLCGiTkCKp0F5EWIrVDwh54NNevkCQRZita+z4IBO"); // // v3-cert2.pem // byte[] cert5 = Base64.decode( "MIICiTCCAfKgAwIBAgIEMeZfHzANBgkqhkiG9w0BAQQFADB9MQswCQYDVQQGEwJD" + "YTEPMA0GA1UEBxMGTmVwZWFuMR4wHAYDVQQLExVObyBMaWFiaWxpdHkgQWNjZXB0" + "ZWQxHzAdBgNVBAoTFkZvciBEZW1vIFB1cnBvc2VzIE9ubHkxHDAaBgNVBAMTE0Vu" + "dHJ1c3QgRGVtbyBXZWIgQ0EwHhcNOTYwNzEyMTQyMDE1WhcNOTYxMDEyMTQyMDE1" + "WjB0MSQwIgYJKoZIhvcNAQkBExVjb29rZUBpc3NsLmF0bC5ocC5jb20xCzAJBgNV" + "BAYTAlVTMScwJQYDVQQLEx5IZXdsZXR0IFBhY2thcmQgQ29tcGFueSAoSVNTTCkx" + "FjAUBgNVBAMTDVBhdWwgQS4gQ29va2UwXDANBgkqhkiG9w0BAQEFAANLADBIAkEA" + "6ceSq9a9AU6g+zBwaL/yVmW1/9EE8s5you1mgjHnj0wAILuoB3L6rm6jmFRy7QZT" + "G43IhVZdDua4e+5/n1ZslwIDAQABo2MwYTARBglghkgBhvhCAQEEBAMCB4AwTAYJ" + "YIZIAYb4QgENBD8WPVRoaXMgY2VydGlmaWNhdGUgaXMgb25seSBpbnRlbmRlZCBm" + "b3IgZGVtb25zdHJhdGlvbiBwdXJwb3Nlcy4wDQYJKoZIhvcNAQEEBQADgYEAi8qc" + "F3zfFqy1sV8NhjwLVwOKuSfhR/Z8mbIEUeSTlnH3QbYt3HWZQ+vXI8mvtZoBc2Fz" + "lexKeIkAZXCesqGbs6z6nCt16P6tmdfbZF3I3AWzLquPcOXjPf4HgstkyvVBn0Ap" + "jAFN418KF/Cx4qyHB4cjdvLrRjjQLnb2+ibo7QU="); // // pem encoded pkcs7 // byte[] cert6 = Base64.decode( "MIAGCSqGSIb3DQEHAqCAMIACAQExCzAJBgUrDgMCGgUAMIAGCSqGSIb3DQEHAQAAoIIJbzCCAj0w" + "ggGmAhEAzbp/VvDf5LxU/iKss3KqVTANBgkqhkiG9w0BAQIFADBfMQswCQYDVQQGEwJVUzEXMBUG" + "A1UEChMOVmVyaVNpZ24sIEluYy4xNzA1BgNVBAsTLkNsYXNzIDEgUHVibGljIFByaW1hcnkgQ2Vy" + "dGlmaWNhdGlvbiBBdXRob3JpdHkwHhcNOTYwMTI5MDAwMDAwWhcNMjgwODAxMjM1OTU5WjBfMQsw" + "CQYDVQQGEwJVUzEXMBUGA1UEChMOVmVyaVNpZ24sIEluYy4xNzA1BgNVBAsTLkNsYXNzIDEgUHVi" + "bGljIFByaW1hcnkgQ2VydGlmaWNhdGlvbiBBdXRob3JpdHkwgZ8wDQYJKoZIhvcNAQEBBQADgY0A" + "MIGJAoGBAOUZv22jVmEtmUhx9mfeuY3rt56GgAqRDvo4Ja9GiILlc6igmyRdDR/MZW4MsNBWhBiH" + "mgabEKFz37RYOWtuwfYV1aioP6oSBo0xrH+wNNePNGeICc0UEeJORVZpH3gCgNrcR5EpuzbJY1zF" + "4Ncth3uhtzKwezC6Ki8xqu6jZ9rbAgMBAAEwDQYJKoZIhvcNAQECBQADgYEATD+4i8Zo3+5DMw5d" + "6abLB4RNejP/khv0Nq3YlSI2aBFsfELM85wuxAc/FLAPT/+Qknb54rxK6Y/NoIAK98Up8YIiXbix" + "3YEjo3slFUYweRb46gVLlH8dwhzI47f0EEA8E8NfH1PoSOSGtHuhNbB7Jbq4046rPzidADQAmPPR" + "cZQwggMuMIICl6ADAgECAhEA0nYujRQMPX2yqCVdr+4NdTANBgkqhkiG9w0BAQIFADBfMQswCQYD" + "VQQGEwJVUzEXMBUGA1UEChMOVmVyaVNpZ24sIEluYy4xNzA1BgNVBAsTLkNsYXNzIDEgUHVibGlj" + "IFByaW1hcnkgQ2VydGlmaWNhdGlvbiBBdXRob3JpdHkwHhcNOTgwNTEyMDAwMDAwWhcNMDgwNTEy" + "MjM1OTU5WjCBzDEXMBUGA1UEChMOVmVyaVNpZ24sIEluYy4xHzAdBgNVBAsTFlZlcmlTaWduIFRy" + "dXN0IE5ldHdvcmsxRjBEBgNVBAsTPXd3dy52ZXJpc2lnbi5jb20vcmVwb3NpdG9yeS9SUEEgSW5j" + "b3JwLiBCeSBSZWYuLExJQUIuTFREKGMpOTgxSDBGBgNVBAMTP1ZlcmlTaWduIENsYXNzIDEgQ0Eg" + "SW5kaXZpZHVhbCBTdWJzY3JpYmVyLVBlcnNvbmEgTm90IFZhbGlkYXRlZDCBnzANBgkqhkiG9w0B" + "AQEFAAOBjQAwgYkCgYEAu1pEigQWu1X9A3qKLZRPFXg2uA1Ksm+cVL+86HcqnbnwaLuV2TFBcHqB" + "S7lIE1YtxwjhhEKrwKKSq0RcqkLwgg4C6S/7wju7vsknCl22sDZCM7VuVIhPh0q/Gdr5FegPh7Yc" + "48zGmo5/aiSS4/zgZbqnsX7vyds3ashKyAkG5JkCAwEAAaN8MHowEQYJYIZIAYb4QgEBBAQDAgEG" + "MEcGA1UdIARAMD4wPAYLYIZIAYb4RQEHAQEwLTArBggrBgEFBQcCARYfd3d3LnZlcmlzaWduLmNv" + "bS9yZXBvc2l0b3J5L1JQQTAPBgNVHRMECDAGAQH/AgEAMAsGA1UdDwQEAwIBBjANBgkqhkiG9w0B" + "AQIFAAOBgQCIuDc73dqUNwCtqp/hgQFxHpJqbS/28Z3TymQ43BuYDAeGW4UVag+5SYWklfEXfWe0" + "fy0s3ZpCnsM+tI6q5QsG3vJWKvozx74Z11NMw73I4xe1pElCY+zCphcPXVgaSTyQXFWjZSAA/Rgg" + "5V+CprGoksVYasGNAzzrw80FopCubjCCA/gwggNhoAMCAQICEBbbn/1G1zppD6KsP01bwywwDQYJ" + "KoZIhvcNAQEEBQAwgcwxFzAVBgNVBAoTDlZlcmlTaWduLCBJbmMuMR8wHQYDVQQLExZWZXJpU2ln" + "biBUcnVzdCBOZXR3b3JrMUYwRAYDVQQLEz13d3cudmVyaXNpZ24uY29tL3JlcG9zaXRvcnkvUlBB" + "IEluY29ycC4gQnkgUmVmLixMSUFCLkxURChjKTk4MUgwRgYDVQQDEz9WZXJpU2lnbiBDbGFzcyAx" + "IENBIEluZGl2aWR1YWwgU3Vic2NyaWJlci1QZXJzb25hIE5vdCBWYWxpZGF0ZWQwHhcNMDAxMDAy" + "MDAwMDAwWhcNMDAxMjAxMjM1OTU5WjCCAQcxFzAVBgNVBAoTDlZlcmlTaWduLCBJbmMuMR8wHQYD" + "VQQLExZWZXJpU2lnbiBUcnVzdCBOZXR3b3JrMUYwRAYDVQQLEz13d3cudmVyaXNpZ24uY29tL3Jl" + "cG9zaXRvcnkvUlBBIEluY29ycC4gYnkgUmVmLixMSUFCLkxURChjKTk4MR4wHAYDVQQLExVQZXJz" + "b25hIE5vdCBWYWxpZGF0ZWQxJzAlBgNVBAsTHkRpZ2l0YWwgSUQgQ2xhc3MgMSAtIE1pY3Jvc29m" + "dDETMBEGA1UEAxQKRGF2aWQgUnlhbjElMCMGCSqGSIb3DQEJARYWZGF2aWRAbGl2ZW1lZGlhLmNv" + "bS5hdTCBnzANBgkqhkiG9w0BAQEFAAOBjQAwgYkCgYEAqxBsdeNmSvFqhMNwhQgNzM8mdjX9eSXb" + "DawpHtQHjmh0AKJSa3IwUY0VIsyZHuXWktO/CgaMBVPt6OVf/n0R2sQigMP6Y+PhEiS0vCJBL9aK" + "0+pOo2qXrjVBmq+XuCyPTnc+BOSrU26tJsX0P9BYorwySiEGxGanBNATdVL4NdUCAwEAAaOBnDCB" + "mTAJBgNVHRMEAjAAMEQGA1UdIAQ9MDswOQYLYIZIAYb4RQEHAQgwKjAoBggrBgEFBQcCARYcaHR0" + "cHM6Ly93d3cudmVyaXNpZ24uY29tL3JwYTARBglghkgBhvhCAQEEBAMCB4AwMwYDVR0fBCwwKjAo" + "oCagJIYiaHR0cDovL2NybC52ZXJpc2lnbi5jb20vY2xhc3MxLmNybDANBgkqhkiG9w0BAQQFAAOB" + "gQBC8yIIdVGpFTf8/YiL14cMzcmL0nIRm4kGR3U59z7UtcXlfNXXJ8MyaeI/BnXwG/gD5OKYqW6R" + "yca9vZOxf1uoTBl82gInk865ED3Tej6msCqFzZffnSUQvOIeqLxxDlqYRQ6PmW2nAnZeyjcnbI5Y" + "syQSM2fmo7n6qJFP+GbFezGCAkUwggJBAgEBMIHhMIHMMRcwFQYDVQQKEw5WZXJpU2lnbiwgSW5j" + "LjEfMB0GA1UECxMWVmVyaVNpZ24gVHJ1c3QgTmV0d29yazFGMEQGA1UECxM9d3d3LnZlcmlzaWdu" + "LmNvbS9yZXBvc2l0b3J5L1JQQSBJbmNvcnAuIEJ5IFJlZi4sTElBQi5MVEQoYyk5ODFIMEYGA1UE" + "AxM/VmVyaVNpZ24gQ2xhc3MgMSBDQSBJbmRpdmlkdWFsIFN1YnNjcmliZXItUGVyc29uYSBOb3Qg" + "VmFsaWRhdGVkAhAW25/9Rtc6aQ+irD9NW8MsMAkGBSsOAwIaBQCggbowGAYJKoZIhvcNAQkDMQsG" + "CSqGSIb3DQEHATAcBgkqhkiG9w0BCQUxDxcNMDAxMDAyMTczNTE4WjAjBgkqhkiG9w0BCQQxFgQU" + "gZjSaBEY2oxGvlQUIMnxSXhivK8wWwYJKoZIhvcNAQkPMU4wTDAKBggqhkiG9w0DBzAOBggqhkiG" + "9w0DAgICAIAwDQYIKoZIhvcNAwICAUAwBwYFKw4DAgcwDQYIKoZIhvcNAwICASgwBwYFKw4DAh0w" + "DQYJKoZIhvcNAQEBBQAEgYAzk+PU91/ZFfoiuKOECjxEh9fDYE2jfDCheBIgh5gdcCo+sS1WQs8O" + "HreQ9Nop/JdJv1DQMBK6weNBBDoP0EEkRm1XCC144XhXZC82jBZohYmi2WvDbbC//YN58kRMYMyy" + "srrfn4Z9I+6kTriGXkrpGk9Q0LSGjmG2BIsqiF0dvwAAAAAAAA=="); // // dsaWithSHA1 cert // byte[] cert7 = Base64.decode( "MIIEXAYJKoZIhvcNAQcCoIIETTCCBEkCAQExCzAJBgUrDgMCGgUAMAsGCSqG" + "SIb3DQEHAaCCAsMwggK/MIIB4AIBADCBpwYFKw4DAhswgZ0CQQEkJRHP+mN7" + "d8miwTMN55CUSmo3TO8WGCxgY61TX5k+7NU4XPf1TULjw3GobwaJX13kquPh" + "fVXk+gVy46n4Iw3hAhUBSe/QF4BUj+pJOF9ROBM4u+FEWA8CQQD4mSJbrABj" + "TUWrlnAte8pS22Tq4/FPO7jHSqjijUHfXKTrHL1OEqV3SVWcFy5j/cqBgX/z" + "m8Q12PFp/PjOhh+nMA4xDDAKBgNVBAMTA0lEMzAeFw05NzEwMDEwMDAwMDBa" + "Fw0zODAxMDEwMDAwMDBaMA4xDDAKBgNVBAMTA0lEMzCB8DCBpwYFKw4DAhsw" + "gZ0CQQEkJRHP+mN7d8miwTMN55CUSmo3TO8WGCxgY61TX5k+7NU4XPf1TULj" + "w3GobwaJX13kquPhfVXk+gVy46n4Iw3hAhUBSe/QF4BUj+pJOF9ROBM4u+FE" + "WA8CQQD4mSJbrABjTUWrlnAte8pS22Tq4/FPO7jHSqjijUHfXKTrHL1OEqV3" + "SVWcFy5j/cqBgX/zm8Q12PFp/PjOhh+nA0QAAkEAkYkXLYMtGVGWj9OnzjPn" + "sB9sefSRPrVegZJCZbpW+Iv0/1RP1u04pHG9vtRpIQLjzUiWvLMU9EKQTThc" + "eNMmWDCBpwYFKw4DAhswgZ0CQQEkJRHP+mN7d8miwTMN55CUSmo3TO8WGCxg" + "Y61TX5k+7NU4XPf1TULjw3GobwaJX13kquPhfVXk+gVy46n4Iw3hAhUBSe/Q" + "F4BUj+pJOF9ROBM4u+FEWA8CQQD4mSJbrABjTUWrlnAte8pS22Tq4/FPO7jH" + "SqjijUHfXKTrHL1OEqV3SVWcFy5j/cqBgX/zm8Q12PFp/PjOhh+nAy8AMCwC" + "FBY3dBSdeprGcqpr6wr3xbG+6WW+AhRMm/facKJNxkT3iKgJbp7R8Xd3QTGC" + "AWEwggFdAgEBMBMwDjEMMAoGA1UEAxMDSUQzAgEAMAkGBSsOAwIaBQCgXTAY" + "BgkqhkiG9w0BCQMxCwYJKoZIhvcNAQcBMBwGCSqGSIb3DQEJBTEPFw0wMjA1" + "MjQyMzEzMDdaMCMGCSqGSIb3DQEJBDEWBBS4WMsoJhf7CVbZYCFcjoTRzPkJ" + "xjCBpwYFKw4DAhswgZ0CQQEkJRHP+mN7d8miwTMN55CUSmo3TO8WGCxgY61T" + "X5k+7NU4XPf1TULjw3GobwaJX13kquPhfVXk+gVy46n4Iw3hAhUBSe/QF4BU" + "j+pJOF9ROBM4u+FEWA8CQQD4mSJbrABjTUWrlnAte8pS22Tq4/FPO7jHSqji" + "jUHfXKTrHL1OEqV3SVWcFy5j/cqBgX/zm8Q12PFp/PjOhh+nBC8wLQIVALID" + "dt+MHwawrDrwsO1Z6sXBaaJsAhRaKssrpevmLkbygKPV07XiAKBG02Zvb2Jh" + "cg=="); // // testcrl.pem // byte[] crl1 = Base64.decode( "MIICjTCCAfowDQYJKoZIhvcNAQECBQAwXzELMAkGA1UEBhMCVVMxIDAeBgNVBAoT" + "F1JTQSBEYXRhIFNlY3VyaXR5LCBJbmMuMS4wLAYDVQQLEyVTZWN1cmUgU2VydmVy" + "IENlcnRpZmljYXRpb24gQXV0aG9yaXR5Fw05NTA1MDIwMjEyMjZaFw05NTA2MDEw" + "MDAxNDlaMIIBaDAWAgUCQQAABBcNOTUwMjAxMTcyNDI2WjAWAgUCQQAACRcNOTUw" + "MjEwMDIxNjM5WjAWAgUCQQAADxcNOTUwMjI0MDAxMjQ5WjAWAgUCQQAADBcNOTUw" + "MjI1MDA0NjQ0WjAWAgUCQQAAGxcNOTUwMzEzMTg0MDQ5WjAWAgUCQQAAFhcNOTUw" + "MzE1MTkxNjU0WjAWAgUCQQAAGhcNOTUwMzE1MTk0MDQxWjAWAgUCQQAAHxcNOTUw" + "MzI0MTk0NDMzWjAWAgUCcgAABRcNOTUwMzI5MjAwNzExWjAWAgUCcgAAERcNOTUw" + "MzMwMDIzNDI2WjAWAgUCQQAAIBcNOTUwNDA3MDExMzIxWjAWAgUCcgAAHhcNOTUw" + "NDA4MDAwMjU5WjAWAgUCcgAAQRcNOTUwNDI4MTcxNzI0WjAWAgUCcgAAOBcNOTUw" + "NDI4MTcyNzIxWjAWAgUCcgAATBcNOTUwNTAyMDIxMjI2WjANBgkqhkiG9w0BAQIF" + "AAN+AHqOEJXSDejYy0UwxxrH/9+N2z5xu/if0J6qQmK92W0hW158wpJg+ovV3+wQ" + "wvIEPRL2rocL0tKfAsVq1IawSJzSNgxG0lrcla3MrJBnZ4GaZDu4FutZh72MR3Gt" + "JaAL3iTJHJD55kK2D/VoyY1djlsPuNh6AEgdVwFAyp0v"); // // ecdsa cert with extra octet string. // byte[] oldEcdsa = Base64.decode( "MIICljCCAkCgAwIBAgIBATALBgcqhkjOPQQBBQAwgY8xCzAJBgNVBAYTAkFVMSgwJ" + "gYDVQQKEx9UaGUgTGVnaW9uIG9mIHRoZSBCb3VuY3kgQ2FzdGxlMRIwEAYDVQQHEw" + "lNZWxib3VybmUxETAPBgNVBAgTCFZpY3RvcmlhMS8wLQYJKoZIhvcNAQkBFiBmZWV" + "kYmFjay1jcnlwdG9AYm91bmN5Y2FzdGxlLm9yZzAeFw0wMTEyMDcwMTAwMDRaFw0w" + "MTEyMDcwMTAxNDRaMIGPMQswCQYDVQQGEwJBVTEoMCYGA1UEChMfVGhlIExlZ2lvb" + "iBvZiB0aGUgQm91bmN5IENhc3RsZTESMBAGA1UEBxMJTWVsYm91cm5lMREwDwYDVQ" + "QIEwhWaWN0b3JpYTEvMC0GCSqGSIb3DQEJARYgZmVlZGJhY2stY3J5cHRvQGJvdW5" + "jeWNhc3RsZS5vcmcwgeQwgb0GByqGSM49AgEwgbECAQEwKQYHKoZIzj0BAQIef///" + "////////////f///////gAAAAAAAf///////MEAEHn///////////////3///////" + "4AAAAAAAH///////AQeawFsO9zxiUHQ1lSSFHXKcanbL7J9HTd5YYXClCwKBB8CD/" + "qWPNyogWzMM7hkK+35BcPTWFc9Pyf7vTs8uaqvAh5///////////////9///+eXpq" + "fXZBx+9FSJoiQnQsDIgAEHwJbbcU7xholSP+w9nFHLebJUhqdLSU05lq/y9X+DHAw" + "CwYHKoZIzj0EAQUAA0MAMEACHnz6t4UNoVROp74ma4XNDjjGcjaqiIWPZLK8Bdw3G" + "QIeLZ4j3a6ividZl344UH+UPUE7xJxlYGuy7ejTsqRR"); byte[] uncompressedPtEC = Base64.decode( "MIIDKzCCAsGgAwIBAgICA+kwCwYHKoZIzj0EAQUAMGYxCzAJBgNVBAYTAkpQ" + "MRUwEwYDVQQKEwxuaXRlY2guYWMuanAxDjAMBgNVBAsTBWFpbGFiMQ8wDQYD" + "VQQDEwZ0ZXN0Y2ExHzAdBgkqhkiG9w0BCQEWEHRlc3RjYUBsb2NhbGhvc3Qw" + "HhcNMDExMDEzMTE1MzE3WhcNMjAxMjEyMTE1MzE3WjBmMQswCQYDVQQGEwJK" + "UDEVMBMGA1UEChMMbml0ZWNoLmFjLmpwMQ4wDAYDVQQLEwVhaWxhYjEPMA0G" + "A1UEAxMGdGVzdGNhMR8wHQYJKoZIhvcNAQkBFhB0ZXN0Y2FAbG9jYWxob3N0" + "MIIBczCCARsGByqGSM49AgEwggEOAgEBMDMGByqGSM49AQECKEdYWnajFmnZ" + "tzrukK2XWdle2v+GsD9l1ZiR6g7ozQDbhFH/bBiMDQcwVAQoJ5EQKrI54/CT" + "xOQ2pMsd/fsXD+EX8YREd8bKHWiLz8lIVdD5cBNeVwQoMKSc6HfI7vKZp8Q2" + "zWgIFOarx1GQoWJbMcSt188xsl30ncJuJT2OoARRBAqJ4fD+q6hbqgNSjTQ7" + "htle1KO3eiaZgcJ8rrnyN8P+5A8+5K+H9aQ/NbBR4Gs7yto5PXIUZEUgodHA" + "TZMSAcSq5ZYt4KbnSYaLY0TtH9CqAigEwZ+hglbT21B7ZTzYX2xj0x+qooJD" + "hVTLtIPaYJK2HrMPxTw6/zfrAgEPA1IABAnvfFcFDgD/JicwBGn6vR3N8MIn" + "mptZf/mnJ1y649uCF60zOgdwIyI7pVSxBFsJ7ohqXEHW0x7LrGVkdSEiipiH" + "LYslqh3xrqbAgPbl93GUo0IwQDAPBgNVHRMBAf8EBTADAQH/MA4GA1UdDwEB" + "/wQEAwIBxjAdBgNVHQ4EFgQUAEo62Xm9H6DcsE0zUDTza4BRG90wCwYHKoZI" + "zj0EAQUAA1cAMFQCKAQsCHHSNOqfJXLgt3bg5+k49hIBGVr/bfG0B9JU3rNt" + "Ycl9Y2zfRPUCKAK2ccOQXByAWfsasDu8zKHxkZv7LVDTFjAIffz3HaCQeVhD" + "z+fauEg="); byte[] keyUsage = Base64.decode( "MIIE7TCCBFagAwIBAgIEOAOR7jANBgkqhkiG9w0BAQQFADCByTELMAkGA1UE" + "BhMCVVMxFDASBgNVBAoTC0VudHJ1c3QubmV0MUgwRgYDVQQLFD93d3cuZW50" + "cnVzdC5uZXQvQ2xpZW50X0NBX0luZm8vQ1BTIGluY29ycC4gYnkgcmVmLiBs" + "aW1pdHMgbGlhYi4xJTAjBgNVBAsTHChjKSAxOTk5IEVudHJ1c3QubmV0IExp" + "bWl0ZWQxMzAxBgNVBAMTKkVudHJ1c3QubmV0IENsaWVudCBDZXJ0aWZpY2F0" + "aW9uIEF1dGhvcml0eTAeFw05OTEwMTIxOTI0MzBaFw0xOTEwMTIxOTU0MzBa" + "MIHJMQswCQYDVQQGEwJVUzEUMBIGA1UEChMLRW50cnVzdC5uZXQxSDBGBgNV" + "BAsUP3d3dy5lbnRydXN0Lm5ldC9DbGllbnRfQ0FfSW5mby9DUFMgaW5jb3Jw" + "LiBieSByZWYuIGxpbWl0cyBsaWFiLjElMCMGA1UECxMcKGMpIDE5OTkgRW50" + "cnVzdC5uZXQgTGltaXRlZDEzMDEGA1UEAxMqRW50cnVzdC5uZXQgQ2xpZW50" + "IENlcnRpZmljYXRpb24gQXV0aG9yaXR5MIGdMA0GCSqGSIb3DQEBAQUAA4GL" + "ADCBhwKBgQDIOpleMRffrCdvkHvkGf9FozTC28GoT/Bo6oT9n3V5z8GKUZSv" + "x1cDR2SerYIbWtp/N3hHuzeYEpbOxhN979IMMFGpOZ5V+Pux5zDeg7K6PvHV" + "iTs7hbqqdCz+PzFur5GVbgbUB01LLFZHGARS2g4Qk79jkJvh34zmAqTmT173" + "iwIBA6OCAeAwggHcMBEGCWCGSAGG+EIBAQQEAwIABzCCASIGA1UdHwSCARkw" + "ggEVMIHkoIHhoIHepIHbMIHYMQswCQYDVQQGEwJVUzEUMBIGA1UEChMLRW50" + "cnVzdC5uZXQxSDBGBgNVBAsUP3d3dy5lbnRydXN0Lm5ldC9DbGllbnRfQ0Ff" + "SW5mby9DUFMgaW5jb3JwLiBieSByZWYuIGxpbWl0cyBsaWFiLjElMCMGA1UE" + "CxMcKGMpIDE5OTkgRW50cnVzdC5uZXQgTGltaXRlZDEzMDEGA1UEAxMqRW50" + "cnVzdC5uZXQgQ2xpZW50IENlcnRpZmljYXRpb24gQXV0aG9yaXR5MQ0wCwYD" + "VQQDEwRDUkwxMCygKqAohiZodHRwOi8vd3d3LmVudHJ1c3QubmV0L0NSTC9D" + "bGllbnQxLmNybDArBgNVHRAEJDAigA8xOTk5MTAxMjE5MjQzMFqBDzIwMTkx" + "MDEyMTkyNDMwWjALBgNVHQ8EBAMCAQYwHwYDVR0jBBgwFoAUxPucKXuXzUyW" + "/O5bs8qZdIuV6kwwHQYDVR0OBBYEFMT7nCl7l81MlvzuW7PKmXSLlepMMAwG" + "A1UdEwQFMAMBAf8wGQYJKoZIhvZ9B0EABAwwChsEVjQuMAMCBJAwDQYJKoZI" + "hvcNAQEEBQADgYEAP66K8ddmAwWePvrqHEa7pFuPeJoSSJn59DXeDDYHAmsQ" + "OokUgZwxpnyyQbJq5wcBoUv5nyU7lsqZwz6hURzzwy5E97BnRqqS5TvaHBkU" + "ODDV4qIxJS7x7EU47fgGWANzYrAQMY9Av2TgXD7FTx/aEkP/TOYGJqibGapE" + "PHayXOw="); byte[] nameCert = Base64.decode( "MIIEFjCCA3+gAwIBAgIEdS8BozANBgkqhkiG9w0BAQUFADBKMQswCQYDVQQGEwJE"+ "RTERMA8GA1UEChQIREFURVYgZUcxKDAMBgcCggYBCgcUEwExMBgGA1UEAxQRQ0Eg"+ "REFURVYgRDAzIDE6UE4wIhgPMjAwMTA1MTAxMDIyNDhaGA8yMDA0MDUwOTEwMjI0"+ "OFowgYQxCzAJBgNVBAYTAkRFMQ8wDQYDVQQIFAZCYXllcm4xEjAQBgNVBAcUCU7I"+ "dXJuYmVyZzERMA8GA1UEChQIREFURVYgZUcxHTAbBgNVBAUTFDAwMDAwMDAwMDA4"+ "OTU3NDM2MDAxMR4wHAYDVQQDFBVEaWV0bWFyIFNlbmdlbmxlaXRuZXIwgaEwDQYJ"+ "KoZIhvcNAQEBBQADgY8AMIGLAoGBAJLI/LJLKaHoMk8fBECW/od8u5erZi6jI8Ug"+ "C0a/LZyQUO/R20vWJs6GrClQtXB+AtfiBSnyZOSYzOdfDI8yEKPEv8qSuUPpOHps"+ "uNCFdLZF1vavVYGEEWs2+y+uuPmg8q1oPRyRmUZ+x9HrDvCXJraaDfTEd9olmB/Z"+ "AuC/PqpjAgUAwAAAAaOCAcYwggHCMAwGA1UdEwEB/wQCMAAwDwYDVR0PAQH/BAUD"+ "AwdAADAxBgNVHSAEKjAoMCYGBSskCAEBMB0wGwYIKwYBBQUHAgEWD3d3dy56cy5k"+ "YXRldi5kZTApBgNVHREEIjAggR5kaWV0bWFyLnNlbmdlbmxlaXRuZXJAZGF0ZXYu"+ "ZGUwgYQGA1UdIwR9MHuhc6RxMG8xCzAJBgNVBAYTAkRFMT0wOwYDVQQKFDRSZWd1"+ "bGllcnVuZ3NiZWjIb3JkZSBmyHVyIFRlbGVrb21tdW5pa2F0aW9uIHVuZCBQb3N0"+ "MSEwDAYHAoIGAQoHFBMBMTARBgNVBAMUCjVSLUNBIDE6UE6CBACm8LkwDgYHAoIG"+ "AQoMAAQDAQEAMEcGA1UdHwRAMD4wPKAUoBKGEHd3dy5jcmwuZGF0ZXYuZGWiJKQi"+ "MCAxCzAJBgNVBAYTAkRFMREwDwYDVQQKFAhEQVRFViBlRzAWBgUrJAgDBAQNMAsT"+ "A0VVUgIBBQIBATAdBgNVHQ4EFgQUfv6xFP0xk7027folhy+ziZvBJiwwLAYIKwYB"+ "BQUHAQEEIDAeMBwGCCsGAQUFBzABhhB3d3cuZGlyLmRhdGV2LmRlMA0GCSqGSIb3"+ "DQEBBQUAA4GBAEOVX6uQxbgtKzdgbTi6YLffMftFr2mmNwch7qzpM5gxcynzgVkg"+ "pnQcDNlm5AIbS6pO8jTCLfCd5TZ5biQksBErqmesIl3QD+VqtB+RNghxectZ3VEs"+ "nCUtcE7tJ8O14qwCb3TxS9dvIUFiVi4DjbxX46TdcTbTaK8/qr6AIf+l"); byte[] probSelfSignedCert = Base64.decode( "MIICxTCCAi6gAwIBAgIQAQAAAAAAAAAAAAAAAAAAATANBgkqhkiG9w0BAQUFADBF" + "MScwJQYDVQQKEx4gRElSRUNUSU9OIEdFTkVSQUxFIERFUyBJTVBPVFMxGjAYBgNV" + "BAMTESBBQyBNSU5FRkkgQiBURVNUMB4XDTA0MDUwNzEyMDAwMFoXDTE0MDUwNzEy" + "MDAwMFowRTEnMCUGA1UEChMeIERJUkVDVElPTiBHRU5FUkFMRSBERVMgSU1QT1RT" + "MRowGAYDVQQDExEgQUMgTUlORUZJIEIgVEVTVDCBnzANBgkqhkiG9w0BAQEFAAOB" + "jQAwgYkCgYEAveoCUOAukZdcFCs2qJk76vSqEX0ZFzHqQ6faBPZWjwkgUNwZ6m6m" + "qWvvyq1cuxhoDvpfC6NXILETawYc6MNwwxsOtVVIjuXlcF17NMejljJafbPximEt" + "DQ4LcQeSp4K7FyFlIAMLyt3BQ77emGzU5fjFTvHSUNb3jblx0sV28c0CAwEAAaOB" + "tTCBsjAfBgNVHSMEGDAWgBSEJ4bLbvEQY8cYMAFKPFD1/fFXlzAdBgNVHQ4EFgQU" + "hCeGy27xEGPHGDABSjxQ9f3xV5cwDgYDVR0PAQH/BAQDAgEGMBEGCWCGSAGG+EIB" + "AQQEAwIBBjA8BgNVHR8ENTAzMDGgL6AthitodHRwOi8vYWRvbmlzLnBrNy5jZXJ0" + "cGx1cy5uZXQvZGdpLXRlc3QuY3JsMA8GA1UdEwEB/wQFMAMBAf8wDQYJKoZIhvcN" + "AQEFBQADgYEAmToHJWjd3+4zknfsP09H6uMbolHNGG0zTS2lrLKpzcmkQfjhQpT9" + "LUTBvfs1jdjo9fGmQLvOG+Sm51Rbjglb8bcikVI5gLbclOlvqLkm77otjl4U4Z2/" + "Y0vP14Aov3Sn3k+17EfReYUZI4liuB95ncobC4e8ZM++LjQcIM0s+Vs="); byte[] gost34102001base = Base64.decode( "MIIB1DCCAYECEEjpVKXP6Wn1yVz3VeeDQa8wCgYGKoUDAgIDBQAwbTEfMB0G" + "A1UEAwwWR29zdFIzNDEwLTIwMDEgZXhhbXBsZTESMBAGA1UECgwJQ3J5cHRv" + "UHJvMQswCQYDVQQGEwJSVTEpMCcGCSqGSIb3DQEJARYaR29zdFIzNDEwLTIw" + "MDFAZXhhbXBsZS5jb20wHhcNMDUwMjAzMTUxNjQ2WhcNMTUwMjAzMTUxNjQ2" + "WjBtMR8wHQYDVQQDDBZHb3N0UjM0MTAtMjAwMSBleGFtcGxlMRIwEAYDVQQK" + "DAlDcnlwdG9Qcm8xCzAJBgNVBAYTAlJVMSkwJwYJKoZIhvcNAQkBFhpHb3N0" + "UjM0MTAtMjAwMUBleGFtcGxlLmNvbTBjMBwGBiqFAwICEzASBgcqhQMCAiQA" + "BgcqhQMCAh4BA0MABECElWh1YAIaQHUIzROMMYks/eUFA3pDXPRtKw/nTzJ+" + "V4/rzBa5lYgD0Jp8ha4P5I3qprt+VsfLsN8PZrzK6hpgMAoGBiqFAwICAwUA" + "A0EAHw5dw/aw/OiNvHyOE65kvyo4Hp0sfz3csM6UUkp10VO247ofNJK3tsLb" + "HOLjUaqzefrlGb11WpHYrvWFg+FcLA=="); byte[] gost341094base = Base64.decode( "MIICDzCCAbwCEBcxKsIb0ghYvAQeUjfQdFAwCgYGKoUDAgIEBQAwaTEdMBsG" + "A1UEAwwUR29zdFIzNDEwLTk0IGV4YW1wbGUxEjAQBgNVBAoMCUNyeXB0b1By" + "bzELMAkGA1UEBhMCUlUxJzAlBgkqhkiG9w0BCQEWGEdvc3RSMzQxMC05NEBl" + "eGFtcGxlLmNvbTAeFw0wNTAyMDMxNTE2NTFaFw0xNTAyMDMxNTE2NTFaMGkx" + "HTAbBgNVBAMMFEdvc3RSMzQxMC05NCBleGFtcGxlMRIwEAYDVQQKDAlDcnlw" + "dG9Qcm8xCzAJBgNVBAYTAlJVMScwJQYJKoZIhvcNAQkBFhhHb3N0UjM0MTAt" + "OTRAZXhhbXBsZS5jb20wgaUwHAYGKoUDAgIUMBIGByqFAwICIAIGByqFAwIC" + "HgEDgYQABIGAu4Rm4XmeWzTYLIB/E6gZZnFX/oxUJSFHbzALJ3dGmMb7R1W+" + "t7Lzk2w5tUI3JoTiDRCKJA4fDEJNKzsRK6i/ZjkyXJSLwaj+G2MS9gklh8x1" + "G/TliYoJgmjTXHemD7aQEBON4z58nJHWrA0ILD54wbXCtrcaqCqLRYGTMjJ2" + "+nswCgYGKoUDAgIEBQADQQBxKNhOmjgz/i5CEgLOyKyz9pFGkDcaymsWYQWV" + "v7CZ0pTM8IzMzkUBW3GHsUjCFpanFZDfg2zuN+3kT+694n9B"); byte[] gost341094A = Base64.decode( "MIICSDCCAfWgAwIBAgIBATAKBgYqhQMCAgQFADCBgTEXMBUGA1UEAxMOZGVmYXVsdDM0MTAtOTQx" + "DTALBgNVBAoTBERpZ3QxDzANBgNVBAsTBkNyeXB0bzEOMAwGA1UEBxMFWS1vbGExDDAKBgNVBAgT" + "A01FTDELMAkGA1UEBhMCcnUxGzAZBgkqhkiG9w0BCQEWDHRlc3RAdGVzdC5ydTAeFw0wNTAzMjkx" + "MzExNTdaFw0wNjAzMjkxMzExNTdaMIGBMRcwFQYDVQQDEw5kZWZhdWx0MzQxMC05NDENMAsGA1UE" + "ChMERGlndDEPMA0GA1UECxMGQ3J5cHRvMQ4wDAYDVQQHEwVZLW9sYTEMMAoGA1UECBMDTUVMMQsw" + "CQYDVQQGEwJydTEbMBkGCSqGSIb3DQEJARYMdGVzdEB0ZXN0LnJ1MIGlMBwGBiqFAwICFDASBgcq" + "hQMCAiACBgcqhQMCAh4BA4GEAASBgIQACDLEuxSdRDGgdZxHmy30g/DUYkRxO9Mi/uSHX5NjvZ31" + "b7JMEMFqBtyhql1HC5xZfUwZ0aT3UnEFDfFjLP+Bf54gA+LPkQXw4SNNGOj+klnqgKlPvoqMGlwa" + "+hLPKbS561WpvB2XSTgbV+pqqXR3j6j30STmybelEV3RdS2Now8wDTALBgNVHQ8EBAMCB4AwCgYG" + "KoUDAgIEBQADQQBCFy7xWRXtNVXflKvDs0pBdBuPzjCMeZAXVxK8vUxsxxKu76d9CsvhgIFknFRi" + "wWTPiZenvNoJ4R1uzeX+vREm"); byte[] gost341094B = Base64.decode( "MIICSDCCAfWgAwIBAgIBATAKBgYqhQMCAgQFADCBgTEXMBUGA1UEAxMOcGFyYW0xLTM0MTAtOTQx" + "DTALBgNVBAoTBERpZ3QxDzANBgNVBAsTBkNyeXB0bzEOMAwGA1UEBxMFWS1PbGExDDAKBgNVBAgT" + "A01lbDELMAkGA1UEBhMCcnUxGzAZBgkqhkiG9w0BCQEWDHRlc3RAdGVzdC5ydTAeFw0wNTAzMjkx" + "MzEzNTZaFw0wNjAzMjkxMzEzNTZaMIGBMRcwFQYDVQQDEw5wYXJhbTEtMzQxMC05NDENMAsGA1UE" + "ChMERGlndDEPMA0GA1UECxMGQ3J5cHRvMQ4wDAYDVQQHEwVZLU9sYTEMMAoGA1UECBMDTWVsMQsw" + "CQYDVQQGEwJydTEbMBkGCSqGSIb3DQEJARYMdGVzdEB0ZXN0LnJ1MIGlMBwGBiqFAwICFDASBgcq" + "hQMCAiADBgcqhQMCAh4BA4GEAASBgEa+AAcZmijWs1M9x5Pn9efE8D9ztG1NMoIt0/hNZNqln3+j" + "lMZjyqPt+kTLIjtmvz9BRDmIDk6FZz+4LhG2OTL7yGpWfrMxMRr56nxomTN9aLWRqbyWmn3brz9Y" + "AUD3ifnwjjIuW7UM84JNlDTOdxx0XRUfLQIPMCXe9cO02Xskow8wDTALBgNVHQ8EBAMCB4AwCgYG" + "KoUDAgIEBQADQQBzFcnuYc/639OTW+L5Ecjw9KxGr+dwex7lsS9S1BUgKa3m1d5c+cqI0B2XUFi5" + "4iaHHJG0dCyjtQYLJr0OZjRw"); byte[] gost34102001A = Base64.decode( "MIICCzCCAbigAwIBAgIBATAKBgYqhQMCAgMFADCBhDEaMBgGA1UEAxMRZGVmYXVsdC0zNDEwLTIw" + "MDExDTALBgNVBAoTBERpZ3QxDzANBgNVBAsTBkNyeXB0bzEOMAwGA1UEBxMFWS1PbGExDDAKBgNV" + "BAgTA01lbDELMAkGA1UEBhMCcnUxGzAZBgkqhkiG9w0BCQEWDHRlc3RAdGVzdC5ydTAeFw0wNTAz" + "MjkxMzE4MzFaFw0wNjAzMjkxMzE4MzFaMIGEMRowGAYDVQQDExFkZWZhdWx0LTM0MTAtMjAwMTEN" + "MAsGA1UEChMERGlndDEPMA0GA1UECxMGQ3J5cHRvMQ4wDAYDVQQHEwVZLU9sYTEMMAoGA1UECBMD" + "TWVsMQswCQYDVQQGEwJydTEbMBkGCSqGSIb3DQEJARYMdGVzdEB0ZXN0LnJ1MGMwHAYGKoUDAgIT" + "MBIGByqFAwICIwEGByqFAwICHgEDQwAEQG/4c+ZWb10IpeHfmR+vKcbpmSOClJioYmCVgnojw0Xn" + "ned0KTg7TJreRUc+VX7vca4hLQaZ1o/TxVtfEApK/O6jDzANMAsGA1UdDwQEAwIHgDAKBgYqhQMC" + "AgMFAANBAN8y2b6HuIdkD3aWujpfQbS1VIA/7hro4vLgDhjgVmev/PLzFB8oTh3gKhExpDo82IEs" + "ZftGNsbbyp1NFg7zda0="); byte[] gostCA1 = Base64.decode( "MIIDNDCCAuGgAwIBAgIQZLcKDcWcQopF+jp4p9jylDAKBgYqhQMCAgQFADBm" + "MQswCQYDVQQGEwJSVTEPMA0GA1UEBxMGTW9zY293MRcwFQYDVQQKEw5PT08g" + "Q3J5cHRvLVBybzEUMBIGA1UECxMLRGV2ZWxvcG1lbnQxFzAVBgNVBAMTDkNQ" + "IENTUCBUZXN0IENBMB4XDTAyMDYwOTE1NTIyM1oXDTA5MDYwOTE1NTkyOVow" + "ZjELMAkGA1UEBhMCUlUxDzANBgNVBAcTBk1vc2NvdzEXMBUGA1UEChMOT09P" + "IENyeXB0by1Qcm8xFDASBgNVBAsTC0RldmVsb3BtZW50MRcwFQYDVQQDEw5D" + "UCBDU1AgVGVzdCBDQTCBpTAcBgYqhQMCAhQwEgYHKoUDAgIgAgYHKoUDAgIe" + "AQOBhAAEgYAYglywKuz1nMc9UiBYOaulKy53jXnrqxZKbCCBSVaJ+aCKbsQm" + "glhRFrw6Mwu8Cdeabo/ojmea7UDMZd0U2xhZFRti5EQ7OP6YpqD0alllo7za" + "4dZNXdX+/ag6fOORSLFdMpVx5ganU0wHMPk67j+audnCPUj/plbeyccgcdcd" + "WaOCASIwggEeMAsGA1UdDwQEAwIBxjAPBgNVHRMBAf8EBTADAQH/MB0GA1Ud" + "DgQWBBTe840gTo4zt2twHilw3PD9wJaX0TCBygYDVR0fBIHCMIG/MDygOqA4" + "hjYtaHR0cDovL2ZpZXdhbGwvQ2VydEVucm9sbC9DUCUyMENTUCUyMFRlc3Ql" + "MjBDQSgzKS5jcmwwRKBCoECGPmh0dHA6Ly93d3cuY3J5cHRvcHJvLnJ1L0Nl" + "cnRFbnJvbGwvQ1AlMjBDU1AlMjBUZXN0JTIwQ0EoMykuY3JsMDmgN6A1hjMt" + "ZmlsZTovL1xcZmlld2FsbFxDZXJ0RW5yb2xsXENQIENTUCBUZXN0IENBKDMp" + "LmNybC8wEgYJKwYBBAGCNxUBBAUCAwMAAzAKBgYqhQMCAgQFAANBAIJi7ni7" + "9rwMR5rRGTFftt2k70GbqyUEfkZYOzrgdOoKiB4IIsIstyBX0/ne6GsL9Xan" + "G2IN96RB7KrowEHeW+k="); byte[] gostCA2 = Base64.decode( "MIIC2DCCAoWgAwIBAgIQe9ZCugm42pRKNcHD8466zTAKBgYqhQMCAgMFADB+" + "MRowGAYJKoZIhvcNAQkBFgtzYmFAZGlndC5ydTELMAkGA1UEBhMCUlUxDDAK" + "BgNVBAgTA01FTDEUMBIGA1UEBxMLWW9zaGthci1PbGExDTALBgNVBAoTBERp" + "Z3QxDzANBgNVBAsTBkNyeXB0bzEPMA0GA1UEAxMGc2JhLUNBMB4XDTA0MDgw" + "MzEzMzE1OVoXDTE0MDgwMzEzNDAxMVowfjEaMBgGCSqGSIb3DQEJARYLc2Jh" + "QGRpZ3QucnUxCzAJBgNVBAYTAlJVMQwwCgYDVQQIEwNNRUwxFDASBgNVBAcT" + "C1lvc2hrYXItT2xhMQ0wCwYDVQQKEwREaWd0MQ8wDQYDVQQLEwZDcnlwdG8x" + "DzANBgNVBAMTBnNiYS1DQTBjMBwGBiqFAwICEzASBgcqhQMCAiMBBgcqhQMC" + "Ah4BA0MABEDMSy10CuOH+i8QKG2UWA4XmCt6+BFrNTZQtS6bOalyDY8Lz+G7" + "HybyipE3PqdTB4OIKAAPsEEeZOCZd2UXGQm5o4HaMIHXMBMGCSsGAQQBgjcU" + "AgQGHgQAQwBBMAsGA1UdDwQEAwIBhjAPBgNVHRMBAf8EBTADAQH/MB0GA1Ud" + "DgQWBBRJJl3LcNMxkZI818STfoi3ng1xoDBxBgNVHR8EajBoMDGgL6Athito" + "dHRwOi8vc2JhLmRpZ3QubG9jYWwvQ2VydEVucm9sbC9zYmEtQ0EuY3JsMDOg" + "MaAvhi1maWxlOi8vXFxzYmEuZGlndC5sb2NhbFxDZXJ0RW5yb2xsXHNiYS1D" + "QS5jcmwwEAYJKwYBBAGCNxUBBAMCAQAwCgYGKoUDAgIDBQADQQA+BRJHbc/p" + "q8EYl6iJqXCuR+ozRmH7hPAP3c4KqYSC38TClCgBloLapx/3/WdatctFJW/L" + "mcTovpq088927shE"); byte[] inDirectCrl = Base64.decode( "MIIdXjCCHMcCAQEwDQYJKoZIhvcNAQEFBQAwdDELMAkGA1UEBhMCREUxHDAaBgNV" +"BAoUE0RldXRzY2hlIFRlbGVrb20gQUcxFzAVBgNVBAsUDlQtVGVsZVNlYyBUZXN0" +"MS4wDAYHAoIGAQoHFBMBMTAeBgNVBAMUF1QtVGVsZVNlYyBUZXN0IERJUiA4OlBO" +"Fw0wNjA4MDQwODQ1MTRaFw0wNjA4MDQxNDQ1MTRaMIIbfzB+AgQvrj/pFw0wMzA3" +"MjIwNTQxMjhaMGcwZQYDVR0dAQH/BFswWaRXMFUxCzAJBgNVBAYTAkRFMRwwGgYD" +"VQQKFBNEZXV0c2NoZSBUZWxla29tIEFHMSgwDAYHAoIGAQoHFBMBMTAYBgNVBAMU" +"EVNpZ0cgVGVzdCBDQSA0OlBOMH4CBC+uP+oXDTAzMDcyMjA1NDEyOFowZzBlBgNV" +"HR0BAf8EWzBZpFcwVTELMAkGA1UEBhMCREUxHDAaBgNVBAoUE0RldXRzY2hlIFRl" +"bGVrb20gQUcxKDAMBgcCggYBCgcUEwExMBgGA1UEAxQRU2lnRyBUZXN0IENBIDQ6" +"UE4wfgIEL64/5xcNMDQwNDA1MTMxODE3WjBnMGUGA1UdHQEB/wRbMFmkVzBVMQsw" +"CQYDVQQGEwJERTEcMBoGA1UEChQTRGV1dHNjaGUgVGVsZWtvbSBBRzEoMAwGBwKC" +"BgEKBxQTATEwGAYDVQQDFBFTaWdHIFRlc3QgQ0EgNDpQTjB+AgQvrj/oFw0wNDA0" +"MDUxMzE4MTdaMGcwZQYDVR0dAQH/BFswWaRXMFUxCzAJBgNVBAYTAkRFMRwwGgYD" +"VQQKFBNEZXV0c2NoZSBUZWxla29tIEFHMSgwDAYHAoIGAQoHFBMBMTAYBgNVBAMU" +"EVNpZ0cgVGVzdCBDQSA0OlBOMH4CBC+uP+UXDTAzMDExMzExMTgxMVowZzBlBgNV" +"HR0BAf8EWzBZpFcwVTELMAkGA1UEBhMCREUxHDAaBgNVBAoUE0RldXRzY2hlIFRl" +"bGVrb20gQUcxKDAMBgcCggYBCgcUEwExMBgGA1UEAxQRU2lnRyBUZXN0IENBIDQ6" +"UE4wfgIEL64/5hcNMDMwMTEzMTExODExWjBnMGUGA1UdHQEB/wRbMFmkVzBVMQsw" +"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"); byte[] directCRL = Base64.decode( "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" +"MQ=="); private final byte[] pkcs7CrlProblem = Base64.decode( "MIIwSAYJKoZIhvcNAQcCoIIwOTCCMDUCAQExCzAJBgUrDgMCGgUAMAsGCSqG" + "SIb3DQEHAaCCEsAwggP4MIIC4KADAgECAgF1MA0GCSqGSIb3DQEBBQUAMEUx" + "CzAJBgNVBAYTAlVTMRYwFAYDVQQKEw1HZW9UcnVzdCBJbmMuMR4wHAYDVQQD" + "ExVHZW9UcnVzdCBDQSBmb3IgQWRvYmUwHhcNMDQxMjAyMjEyNTM5WhcNMDYx" + "MjMwMjEyNTM5WjBMMQswCQYDVQQGEwJVUzEVMBMGA1UEChMMR2VvVHJ1c3Qg" + "SW5jMSYwJAYDVQQDEx1HZW9UcnVzdCBBZG9iZSBPQ1NQIFJlc3BvbmRlcjCB" + "nzANBgkqhkiG9w0BAQEFAAOBjQAwgYkCgYEA4gnNYhtw7U6QeVXZODnGhHMj" + "+OgZ0DB393rEk6a2q9kq129IA2e03yKBTfJfQR9aWKc2Qj90dsSqPjvTDHFG" + "Qsagm2FQuhnA3fb1UWhPzeEIdm6bxDsnQ8nWqKqxnWZzELZbdp3I9bBLizIq" + "obZovzt60LNMghn/unvvuhpeVSsCAwEAAaOCAW4wggFqMA4GA1UdDwEB/wQE" + "AwIE8DCB5QYDVR0gAQH/BIHaMIHXMIHUBgkqhkiG9y8BAgEwgcYwgZAGCCsG" + "AQUFBwICMIGDGoGAVGhpcyBjZXJ0aWZpY2F0ZSBoYXMgYmVlbiBpc3N1ZWQg" + "aW4gYWNjb3JkYW5jZSB3aXRoIHRoZSBBY3JvYmF0IENyZWRlbnRpYWxzIENQ" + "UyBsb2NhdGVkIGF0IGh0dHA6Ly93d3cuZ2VvdHJ1c3QuY29tL3Jlc291cmNl" + "cy9jcHMwMQYIKwYBBQUHAgEWJWh0dHA6Ly93d3cuZ2VvdHJ1c3QuY29tL3Jl" + "c291cmNlcy9jcHMwEwYDVR0lBAwwCgYIKwYBBQUHAwkwOgYDVR0fBDMwMTAv" + "oC2gK4YpaHR0cDovL2NybC5nZW90cnVzdC5jb20vY3Jscy9hZG9iZWNhMS5j" + "cmwwHwYDVR0jBBgwFoAUq4BZw2WDbR19E70Zw+wajw1HaqMwDQYJKoZIhvcN" + "AQEFBQADggEBAENJf1BD7PX5ivuaawt90q1OGzXpIQL/ClzEeFVmOIxqPc1E" + "TFRq92YuxG5b6+R+k+tGkmCwPLcY8ipg6ZcbJ/AirQhohzjlFuT6YAXsTfEj" + "CqEZfWM2sS7crK2EYxCMmKE3xDfPclYtrAoz7qZvxfQj0TuxHSstHZv39wu2" + "ZiG1BWiEcyDQyTgqTOXBoZmfJtshuAcXmTpgkrYSrS37zNlPTGh+pMYQ0yWD" + "c8OQRJR4OY5ZXfdna01mjtJTOmj6/6XPoLPYTq2gQrc2BCeNJ4bEhLb7sFVB" + "PbwPrpzTE/HRbQHDrzj0YimDxeOUV/UXctgvYwHNtEkcBLsOm/uytMYwggSh" + "MIIDiaADAgECAgQ+HL0oMA0GCSqGSIb3DQEBBQUAMGkxCzAJBgNVBAYTAlVT" + "MSMwIQYDVQQKExpBZG9iZSBTeXN0ZW1zIEluY29ycG9yYXRlZDEdMBsGA1UE" + "CxMUQWRvYmUgVHJ1c3QgU2VydmljZXMxFjAUBgNVBAMTDUFkb2JlIFJvb3Qg" + "Q0EwHhcNMDMwMTA4MjMzNzIzWhcNMjMwMTA5MDAwNzIzWjBpMQswCQYDVQQG" + "EwJVUzEjMCEGA1UEChMaQWRvYmUgU3lzdGVtcyBJbmNvcnBvcmF0ZWQxHTAb" + "BgNVBAsTFEFkb2JlIFRydXN0IFNlcnZpY2VzMRYwFAYDVQQDEw1BZG9iZSBS" + "b290IENBMIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEAzE9UhPen" + "ouczU38/nBKIayyZR2d+Dx65rRSI+cMQ2B3w8NWfaQovWTWwzGypTJwVoJ/O" + "IL+gz1Ti4CBmRT85hjh+nMSOByLGJPYBErA131XqaZCw24U3HuJOB7JCoWoT" + "aaBm6oCREVkqmwh5WiBELcm9cziLPC/gQxtdswvwrzUaKf7vppLdgUydPVmO" + "rTE8QH6bkTYG/OJcjdGNJtVcRc+vZT+xqtJilvSoOOq6YEL09BxKNRXO+E4i" + "Vg+VGMX4lp+f+7C3eCXpgGu91grwxnSUnfMPUNuad85LcIMjjaDKeCBEXDxU" + "ZPHqojAZn+pMBk0GeEtekt8i0slns3rSAQIDAQABo4IBTzCCAUswEQYJYIZI" + "AYb4QgEBBAQDAgAHMIGOBgNVHR8EgYYwgYMwgYCgfqB8pHoweDELMAkGA1UE" + "BhMCVVMxIzAhBgNVBAoTGkFkb2JlIFN5c3RlbXMgSW5jb3Jwb3JhdGVkMR0w" + "GwYDVQQLExRBZG9iZSBUcnVzdCBTZXJ2aWNlczEWMBQGA1UEAxMNQWRvYmUg" + "Um9vdCBDQTENMAsGA1UEAxMEQ1JMMTArBgNVHRAEJDAigA8yMDAzMDEwODIz" + "MzcyM1qBDzIwMjMwMTA5MDAwNzIzWjALBgNVHQ8EBAMCAQYwHwYDVR0jBBgw" + "FoAUgrc4SpOqmxDvgLvZVOLxD/uAnN4wHQYDVR0OBBYEFIK3OEqTqpsQ74C7" + "2VTi8Q/7gJzeMAwGA1UdEwQFMAMBAf8wHQYJKoZIhvZ9B0EABBAwDhsIVjYu" + "MDo0LjADAgSQMA0GCSqGSIb3DQEBBQUAA4IBAQAy2p9DdcH6b8lv26sdNjc+" + "vGEZNrcCPB0jWZhsnu5NhedUyCAfp9S74r8Ad30ka3AvXME6dkm10+AjhCpx" + "aiLzwScpmBX2NZDkBEzDjbyfYRzn/SSM0URDjBa6m02l1DUvvBHOvfdRN42f" + "kOQU8Rg/vulZEjX5M5LznuDVa5pxm5lLyHHD4bFhCcTl+pHwQjo3fTT5cujN" + "qmIcIenV9IIQ43sFti1oVgt+fpIsb01yggztVnSynbmrLSsdEF/bJ3Vwj/0d" + "1+ICoHnlHOX/r2RAUS2em0fbQqV8H8KmSLDXvpJpTaT2KVfFeBEY3IdRyhOy" + "Yp1PKzK9MaXB+lKrBYjIMIIEyzCCA7OgAwIBAgIEPhy9tTANBgkqhkiG9w0B" + "AQUFADBpMQswCQYDVQQGEwJVUzEjMCEGA1UEChMaQWRvYmUgU3lzdGVtcyBJ" + "bmNvcnBvcmF0ZWQxHTAbBgNVBAsTFEFkb2JlIFRydXN0IFNlcnZpY2VzMRYw" + "FAYDVQQDEw1BZG9iZSBSb290IENBMB4XDTA0MDExNzAwMDMzOVoXDTE1MDEx" + "NTA4MDAwMFowRTELMAkGA1UEBhMCVVMxFjAUBgNVBAoTDUdlb1RydXN0IElu" + "Yy4xHjAcBgNVBAMTFUdlb1RydXN0IENBIGZvciBBZG9iZTCCASIwDQYJKoZI" + "hvcNAQEBBQADggEPADCCAQoCggEBAKfld+BkeFrnOYW8r9L1WygTDlTdSfrO" + "YvWS/Z6Ye5/l+HrBbOHqQCXBcSeCpz7kB2WdKMh1FOE4e9JlmICsHerBLdWk" + "emU+/PDb69zh8E0cLoDfxukF6oVPXj6WSThdSG7H9aXFzRr6S3XGCuvgl+Qw" + "DTLiLYW+ONF6DXwt3TQQtKReJjOJZk46ZZ0BvMStKyBaeB6DKZsmiIo89qso" + "13VDZINH2w1KvXg0ygDizoNtbvgAPFymwnsINS1klfQlcvn0x0RJm9bYQXK3" + "5GNZAgL3M7Lqrld0jMfIUaWvuHCLyivytRuzq1dJ7E8rmidjDEk/G+27pf13" + "fNZ7vR7M+IkCAwEAAaOCAZ0wggGZMBIGA1UdEwEB/wQIMAYBAf8CAQEwUAYD" + "VR0gBEkwRzBFBgkqhkiG9y8BAgEwODA2BggrBgEFBQcCARYqaHR0cHM6Ly93" + "d3cuYWRvYmUuY29tL21pc2MvcGtpL2Nkc19jcC5odG1sMBQGA1UdJQQNMAsG" + "CSqGSIb3LwEBBTCBsgYDVR0fBIGqMIGnMCKgIKAehhxodHRwOi8vY3JsLmFk" + "b2JlLmNvbS9jZHMuY3JsMIGAoH6gfKR6MHgxCzAJBgNVBAYTAlVTMSMwIQYD" + "VQQKExpBZG9iZSBTeXN0ZW1zIEluY29ycG9yYXRlZDEdMBsGA1UECxMUQWRv" + "YmUgVHJ1c3QgU2VydmljZXMxFjAUBgNVBAMTDUFkb2JlIFJvb3QgQ0ExDTAL" + "BgNVBAMTBENSTDEwCwYDVR0PBAQDAgEGMB8GA1UdIwQYMBaAFIK3OEqTqpsQ" + "74C72VTi8Q/7gJzeMB0GA1UdDgQWBBSrgFnDZYNtHX0TvRnD7BqPDUdqozAZ" + "BgkqhkiG9n0HQQAEDDAKGwRWNi4wAwIEkDANBgkqhkiG9w0BAQUFAAOCAQEA" + "PzlZLqIAjrFeEWEs0uC29YyJhkXOE9mf3YSaFGsITF+Gl1j0pajTjyH4R35Q" + "r3floW2q3HfNzTeZ90Jnr1DhVERD6zEMgJpCtJqVuk0sixuXJHghS/KicKf4" + "YXJJPx9epuIRF1siBRnznnF90svmOJMXApc0jGnYn3nQfk4kaShSnDaYaeYR" + "DJKcsiWhl6S5zfwS7Gg8hDeyckhMQKKWnlG1CQrwlSFisKCduoodwRtWgft8" + "kx13iyKK3sbalm6vnVc+5nufS4vI+TwMXoV63NqYaSroafBWk0nL53zGXPEy" + "+A69QhzEViJKn2Wgqt5gt++jMMNImbRObIqgfgF1VjCCBUwwggQ0oAMCAQIC" + "AgGDMA0GCSqGSIb3DQEBBQUAMEUxCzAJBgNVBAYTAlVTMRYwFAYDVQQKEw1H" + "ZW9UcnVzdCBJbmMuMR4wHAYDVQQDExVHZW9UcnVzdCBDQSBmb3IgQWRvYmUw" + "HhcNMDYwMzI0MTU0MjI5WhcNMDkwNDA2MTQ0MjI5WjBzMQswCQYDVQQGEwJV" + "UzELMAkGA1UECBMCTUExETAPBgNVBAoTCEdlb1RydXN0MR0wGwYDVQQDExRN" + "YXJrZXRpbmcgRGVwYXJ0bWVudDElMCMGCSqGSIb3DQEJARYWbWFya2V0aW5n" + "QGdlb3RydXN0LmNvbTCCASIwDQYJKoZIhvcNAQEBBQADggEPADCCAQoCggEB" + "ANmvajTO4XJvAU2nVcLmXeCnAQX7RZt+7+ML3InmqQ3LCGo1weop09zV069/" + "1x/Nmieol7laEzeXxd2ghjGzwfXafqQEqHn6+vBCvqdNPoSi63fSWhnuDVWp" + "KVDOYgxOonrXl+Cc43lu4zRSq+Pi5phhrjDWcH74a3/rdljUt4c4GFezFXfa" + "w2oTzWkxj2cTSn0Szhpr17+p66UNt8uknlhmu4q44Speqql2HwmCEnpLYJrK" + "W3fOq5D4qdsvsLR2EABLhrBezamLI3iGV8cRHOUTsbTMhWhv/lKfHAyf4XjA" + "z9orzvPN5jthhIfICOFq/nStTgakyL4Ln+nFAB/SMPkCAwEAAaOCAhYwggIS" + "MA4GA1UdDwEB/wQEAwIF4DCB5QYDVR0gAQH/BIHaMIHXMIHUBgkqhkiG9y8B" + "AgEwgcYwgZAGCCsGAQUFBwICMIGDGoGAVGhpcyBjZXJ0aWZpY2F0ZSBoYXMg" + "YmVlbiBpc3N1ZWQgaW4gYWNjb3JkYW5jZSB3aXRoIHRoZSBBY3JvYmF0IENy" + "ZWRlbnRpYWxzIENQUyBsb2NhdGVkIGF0IGh0dHA6Ly93d3cuZ2VvdHJ1c3Qu" + "Y29tL3Jlc291cmNlcy9jcHMwMQYIKwYBBQUHAgEWJWh0dHA6Ly93d3cuZ2Vv" + "dHJ1c3QuY29tL3Jlc291cmNlcy9jcHMwOgYDVR0fBDMwMTAvoC2gK4YpaHR0" + "cDovL2NybC5nZW90cnVzdC5jb20vY3Jscy9hZG9iZWNhMS5jcmwwHwYDVR0j" + "BBgwFoAUq4BZw2WDbR19E70Zw+wajw1HaqMwRAYIKwYBBQUHAQEEODA2MDQG" + "CCsGAQUFBzABhihodHRwOi8vYWRvYmUtb2NzcC5nZW90cnVzdC5jb20vcmVz" + "cG9uZGVyMBQGA1UdJQQNMAsGCSqGSIb3LwEBBTA8BgoqhkiG9y8BAQkBBC4w" + "LAIBAYYnaHR0cDovL2Fkb2JlLXRpbWVzdGFtcC5nZW90cnVzdC5jb20vdHNh" + "MBMGCiqGSIb3LwEBCQIEBTADAgEBMAwGA1UdEwQFMAMCAQAwDQYJKoZIhvcN" + "AQEFBQADggEBAAOhy6QxOo+i3h877fvDvTa0plGD2bIqK7wMdNqbMDoSWied" + "FIcgcBOIm2wLxOjZBAVj/3lDq59q2rnVeNnfXM0/N0MHI9TumHRjU7WNk9e4" + "+JfJ4M+c3anrWOG3NE5cICDVgles+UHjXetHWql/LlP04+K2ZOLb6LE2xGnI" + "YyLW9REzCYNAVF+/WkYdmyceHtaBZdbyVAJq0NAJPsfgY1pWcBo31Mr1fpX9" + "WrXNTYDCqMyxMImJTmN3iI68tkXlNrhweQoArKFqBysiBkXzG/sGKYY6tWKU" + "pzjLc3vIp/LrXC5zilROes8BSvwu1w9qQrJNcGwo7O4uijoNtyYil1Exgh1Q" + "MIIdTAIBATBLMEUxCzAJBgNVBAYTAlVTMRYwFAYDVQQKEw1HZW9UcnVzdCBJ" + "bmMuMR4wHAYDVQQDExVHZW9UcnVzdCBDQSBmb3IgQWRvYmUCAgGDMAkGBSsO" + "AwIaBQCgggxMMBgGCSqGSIb3DQEJAzELBgkqhkiG9w0BBwEwIwYJKoZIhvcN" + "AQkEMRYEFP4R6qIdpQJzWyzrqO8X1ZfJOgChMIIMCQYJKoZIhvcvAQEIMYIL" + "+jCCC/agggZ5MIIGdTCCA6gwggKQMA0GCSqGSIb3DQEBBQUAMEUxCzAJBgNV" + "BAYTAlVTMRYwFAYDVQQKEw1HZW9UcnVzdCBJbmMuMR4wHAYDVQQDExVHZW9U" + "cnVzdCBDQSBmb3IgQWRvYmUXDTA2MDQwNDE3NDAxMFoXDTA2MDQwNTE3NDAx" + "MFowggIYMBMCAgC5Fw0wNTEwMTEyMDM2MzJaMBICAVsXDTA0MTEwNDE1MDk0" + "MVowEwICALgXDTA1MTIxMjIyMzgzOFowEgIBWhcNMDQxMTA0MTUwOTMzWjAT" + "AgIA5hcNMDUwODI3MDQwOTM4WjATAgIAtxcNMDYwMTE2MTc1NTEzWjATAgIA" + "hhcNMDUxMjEyMjIzODU1WjATAgIAtRcNMDUwNzA2MTgzODQwWjATAgIA4BcN" + "MDYwMzIwMDc0ODM0WjATAgIAgRcNMDUwODAyMjIzMTE1WjATAgIA3xcNMDUx" + "MjEyMjIzNjUwWjASAgFKFw0wNDExMDQxNTA5MTZaMBICAUQXDTA0MTEwNDE1" + "MDg1M1owEgIBQxcNMDQxMDAzMDEwMDQwWjASAgFsFw0wNDEyMDYxOTQ0MzFa" + "MBMCAgEoFw0wNjAzMDkxMjA3MTJaMBMCAgEkFw0wNjAxMTYxNzU1MzRaMBIC" + "AWcXDTA1MDMxODE3NTYxNFowEwICAVEXDTA2MDEzMTExMjcxMVowEgIBZBcN" + "MDQxMTExMjI0ODQxWjATAgIA8RcNMDUwOTE2MTg0ODAxWjATAgIBThcNMDYw" + "MjIxMjAxMDM2WjATAgIAwRcNMDUxMjEyMjIzODE2WjASAgFiFw0wNTAxMTAx" + "NjE5MzRaMBICAWAXDTA1MDExMDE5MDAwNFowEwICAL4XDTA1MDUxNzE0NTYx" + "MFowDQYJKoZIhvcNAQEFBQADggEBAEKhRMS3wVho1U3EvEQJZC8+JlUngmZQ" + "A78KQbHPWNZWFlNvPuf/b0s7Lu16GfNHXh1QAW6Y5Hi1YtYZ3YOPyMd4Xugt" + "gCdumbB6xtKsDyN5RvTht6ByXj+CYlYqsL7RX0izJZ6mJn4fjMkqzPKNOjb8" + "kSn5T6rn93BjlATtCE8tPVOM8dnqGccRE0OV59+nDBXc90UMt5LdEbwaUOap" + "snVB0oLcNm8d/HnlVH6RY5LnDjrT4vwfe/FApZtTecEWsllVUXDjSpwfcfD/" + "476/lpGySB2otALqzImlA9R8Ok3hJ8dnF6hhQ5Oe6OJMnGYgdhkKbxsKkdib" + "tTVl3qmH5QAwggLFMIIBrQIBATANBgkqhkiG9w0BAQUFADBpMQswCQYDVQQG" + "EwJVUzEjMCEGA1UEChMaQWRvYmUgU3lzdGVtcyBJbmNvcnBvcmF0ZWQxHTAb" + "BgNVBAsTFEFkb2JlIFRydXN0IFNlcnZpY2VzMRYwFAYDVQQDEw1BZG9iZSBS" + "b290IENBFw0wNjAxMjcxODMzMzFaFw0wNzAxMjcwMDAwMDBaMIHeMCMCBD4c" + "vUAXDTAzMDEyMTIzNDY1NlowDDAKBgNVHRUEAwoBBDAjAgQ+HL1BFw0wMzAx" + "MjEyMzQ3MjJaMAwwCgYDVR0VBAMKAQQwIwIEPhy9YhcNMDMwMTIxMjM0NzQy" + "WjAMMAoGA1UdFQQDCgEEMCMCBD4cvWEXDTA0MDExNzAxMDg0OFowDDAKBgNV" + "HRUEAwoBBDAjAgQ+HL2qFw0wNDAxMTcwMTA5MDVaMAwwCgYDVR0VBAMKAQQw" + "IwIEPhy9qBcNMDQwMTE3MDEzOTI5WjAMMAoGA1UdFQQDCgEEoC8wLTAKBgNV" + "HRQEAwIBDzAfBgNVHSMEGDAWgBSCtzhKk6qbEO+Au9lU4vEP+4Cc3jANBgkq" + "hkiG9w0BAQUFAAOCAQEAwtXF9042wG39icUlsotn5tpE3oCusLb/hBpEONhx" + "OdfEQOq0w5hf/vqaxkcf71etA+KpbEUeSVaHMHRPhx/CmPrO9odE139dJdbt" + "9iqbrC9iZokFK3h/es5kg73xujLKd7C/u5ngJ4mwBtvhMLjFjF2vJhPKHL4C" + "IgMwdaUAhrcNzy16v+mw/VGJy3Fvc6oCESW1K9tvFW58qZSNXrMlsuidgunM" + "hPKG+z0SXVyCqL7pnqKiaGddcgujYGOSY4S938oVcfZeZQEODtSYGlzldojX" + "C1U1hCK5+tHAH0Ox/WqRBIol5VCZQwJftf44oG8oviYq52aaqSejXwmfT6zb" + "76GCBXUwggVxMIIFbQoBAKCCBWYwggViBgkrBgEFBQcwAQEEggVTMIIFTzCB" + "taIWBBS+8EpykfXdl4h3z7m/NZfdkAQQERgPMjAwNjA0MDQyMDIwMTVaMGUw" + "YzA7MAkGBSsOAwIaBQAEFEb4BuZYkbjBjOjT6VeA/00fBvQaBBT3fTSQniOp" + "BbHBSkz4xridlX0bsAICAYOAABgPMjAwNjA0MDQyMDIwMTVaoBEYDzIwMDYw" + "NDA1MDgyMDE1WqEjMCEwHwYJKwYBBQUHMAECBBIEEFqooq/R2WltD7TposkT" + "BhMwDQYJKoZIhvcNAQEFBQADgYEAMig6lty4b0JDsT/oanfQG5x6jVKPACpp" + "1UA9SJ0apJJa7LeIdDFmu5C2S/CYiKZm4A4P9cAu0YzgLHxE4r6Op+HfVlAG" + "6bzUe1P/hi1KCJ8r8wxOZAktQFPSzs85RAZwkHMfB0lP2e/h666Oye+Zf8VH" + "RaE+/xZ7aswE89HXoumgggQAMIID/DCCA/gwggLgoAMCAQICAXUwDQYJKoZI" + "hvcNAQEFBQAwRTELMAkGA1UEBhMCVVMxFjAUBgNVBAoTDUdlb1RydXN0IElu" + "Yy4xHjAcBgNVBAMTFUdlb1RydXN0IENBIGZvciBBZG9iZTAeFw0wNDEyMDIy" + "MTI1MzlaFw0wNjEyMzAyMTI1MzlaMEwxCzAJBgNVBAYTAlVTMRUwEwYDVQQK" + "EwxHZW9UcnVzdCBJbmMxJjAkBgNVBAMTHUdlb1RydXN0IEFkb2JlIE9DU1Ag" + "UmVzcG9uZGVyMIGfMA0GCSqGSIb3DQEBAQUAA4GNADCBiQKBgQDiCc1iG3Dt" + "TpB5Vdk4OcaEcyP46BnQMHf3esSTprar2SrXb0gDZ7TfIoFN8l9BH1pYpzZC" + "P3R2xKo+O9MMcUZCxqCbYVC6GcDd9vVRaE/N4Qh2bpvEOydDydaoqrGdZnMQ" + "tlt2ncj1sEuLMiqhtmi/O3rQs0yCGf+6e++6Gl5VKwIDAQABo4IBbjCCAWow" + "DgYDVR0PAQH/BAQDAgTwMIHlBgNVHSABAf8EgdowgdcwgdQGCSqGSIb3LwEC" + "ATCBxjCBkAYIKwYBBQUHAgIwgYMagYBUaGlzIGNlcnRpZmljYXRlIGhhcyBi" + "ZWVuIGlzc3VlZCBpbiBhY2NvcmRhbmNlIHdpdGggdGhlIEFjcm9iYXQgQ3Jl" + "ZGVudGlhbHMgQ1BTIGxvY2F0ZWQgYXQgaHR0cDovL3d3dy5nZW90cnVzdC5j" + "b20vcmVzb3VyY2VzL2NwczAxBggrBgEFBQcCARYlaHR0cDovL3d3dy5nZW90" + "cnVzdC5jb20vcmVzb3VyY2VzL2NwczATBgNVHSUEDDAKBggrBgEFBQcDCTA6" + "BgNVHR8EMzAxMC+gLaArhilodHRwOi8vY3JsLmdlb3RydXN0LmNvbS9jcmxz" + "L2Fkb2JlY2ExLmNybDAfBgNVHSMEGDAWgBSrgFnDZYNtHX0TvRnD7BqPDUdq" + "ozANBgkqhkiG9w0BAQUFAAOCAQEAQ0l/UEPs9fmK+5prC33SrU4bNekhAv8K" + "XMR4VWY4jGo9zURMVGr3Zi7Eblvr5H6T60aSYLA8txjyKmDplxsn8CKtCGiH" + "OOUW5PpgBexN8SMKoRl9YzaxLtysrYRjEIyYoTfEN89yVi2sCjPupm/F9CPR" + "O7EdKy0dm/f3C7ZmIbUFaIRzINDJOCpM5cGhmZ8m2yG4BxeZOmCSthKtLfvM" + "2U9MaH6kxhDTJYNzw5BElHg5jlld92drTWaO0lM6aPr/pc+gs9hOraBCtzYE" + "J40nhsSEtvuwVUE9vA+unNMT8dFtAcOvOPRiKYPF45RX9Rdy2C9jAc20SRwE" + "uw6b+7K0xjANBgkqhkiG9w0BAQEFAASCAQC7a4yICFGCEMPlJbydK5qLG3rV" + "sip7Ojjz9TB4nLhC2DgsIHds8jjdq2zguInluH2nLaBCVS+qxDVlTjgbI2cB" + "TaWS8nglC7nNjzkKAsa8vThA8FZUVXTW0pb74jNJJU2AA27bb4g+4WgunCrj" + "fpYp+QjDyMmdrJVqRmt5eQN+dpVxMS9oq+NrhOSEhyIb4/rejgNg9wnVK1ms" + "l5PxQ4x7kpm7+Ua41//owkJVWykRo4T1jo4eHEz1DolPykAaKie2VKH/sMqR" + "Spjh4E5biKJLOV9fKivZWKAXByXfwUbbMsJvz4v/2yVHFy9xP+tqB5ZbRoDK" + "k8PzUyCprozn+/22oYIPijCCD4YGCyqGSIb3DQEJEAIOMYIPdTCCD3EGCSqG" + "SIb3DQEHAqCCD2Iwgg9eAgEDMQswCQYFKw4DAhoFADCB+gYLKoZIhvcNAQkQ" + "AQSggeoEgecwgeQCAQEGAikCMCEwCQYFKw4DAhoFAAQUoT97qeCv3FXYaEcS" + "gY8patCaCA8CAiMHGA8yMDA2MDQwNDIwMjA1N1owAwIBPAEB/wIIO0yRre3L" + "8/6ggZCkgY0wgYoxCzAJBgNVBAYTAlVTMRYwFAYDVQQIEw1NYXNzYWNodXNl" + "dHRzMRAwDgYDVQQHEwdOZWVkaGFtMRUwEwYDVQQKEwxHZW9UcnVzdCBJbmMx" + "EzARBgNVBAsTClByb2R1Y3Rpb24xJTAjBgNVBAMTHGFkb2JlLXRpbWVzdGFt" + "cC5nZW90cnVzdC5jb22gggzJMIIDUTCCAjmgAwIBAgICAI8wDQYJKoZIhvcN" + "AQEFBQAwRTELMAkGA1UEBhMCVVMxFjAUBgNVBAoTDUdlb1RydXN0IEluYy4x" + "HjAcBgNVBAMTFUdlb1RydXN0IENBIGZvciBBZG9iZTAeFw0wNTAxMTAwMTI5" + "MTBaFw0xNTAxMTUwODAwMDBaMIGKMQswCQYDVQQGEwJVUzEWMBQGA1UECBMN" + "TWFzc2FjaHVzZXR0czEQMA4GA1UEBxMHTmVlZGhhbTEVMBMGA1UEChMMR2Vv" + "VHJ1c3QgSW5jMRMwEQYDVQQLEwpQcm9kdWN0aW9uMSUwIwYDVQQDExxhZG9i" + "ZS10aW1lc3RhbXAuZ2VvdHJ1c3QuY29tMIGfMA0GCSqGSIb3DQEBAQUAA4GN" + "ADCBiQKBgQDRbxJotLFPWQuuEDhKtOMaBUJepGxIvWxeahMbq1DVmqnk88+j" + "w/5lfPICPzQZ1oHrcTLSAFM7Mrz3pyyQKQKMqUyiemzuG/77ESUNfBNSUfAF" + "PdtHuDMU8Is8ABVnFk63L+wdlvvDIlKkE08+VTKCRdjmuBVltMpQ6QcLFQzm" + "AQIDAQABo4GIMIGFMDoGA1UdHwQzMDEwL6AtoCuGKWh0dHA6Ly9jcmwuZ2Vv" + "dHJ1c3QuY29tL2NybHMvYWRvYmVjYTEuY3JsMB8GA1UdIwQYMBaAFKuAWcNl" + "g20dfRO9GcPsGo8NR2qjMA4GA1UdDwEB/wQEAwIGwDAWBgNVHSUBAf8EDDAK" + "BggrBgEFBQcDCDANBgkqhkiG9w0BAQUFAAOCAQEAmnyXjdtX+F79Nf0KggTd" + "6YC2MQD9s09IeXTd8TP3rBmizfM+7f3icggeCGakNfPRmIUMLoa0VM5Kt37T" + "2X0TqzBWusfbKx7HnX4v1t/G8NJJlT4SShSHv+8bjjU4lUoCmW2oEcC5vXwP" + "R5JfjCyois16npgcO05ZBT+LLDXyeBijE6qWmwLDfEpLyILzVRmyU4IE7jvm" + "rgb3GXwDUvd3yQXGRRHbPCh3nj9hBGbuzyt7GnlqnEie3wzIyMG2ET/wvTX5" + "4BFXKNe7lDLvZj/MXvd3V7gMTSVW0kAszKao56LfrVTgp1VX3UBQYwmQqaoA" + "UwFezih+jEvjW6cYJo/ErDCCBKEwggOJoAMCAQICBD4cvSgwDQYJKoZIhvcN" + "AQEFBQAwaTELMAkGA1UEBhMCVVMxIzAhBgNVBAoTGkFkb2JlIFN5c3RlbXMg" + "SW5jb3Jwb3JhdGVkMR0wGwYDVQQLExRBZG9iZSBUcnVzdCBTZXJ2aWNlczEW" + "MBQGA1UEAxMNQWRvYmUgUm9vdCBDQTAeFw0wMzAxMDgyMzM3MjNaFw0yMzAx" + "MDkwMDA3MjNaMGkxCzAJBgNVBAYTAlVTMSMwIQYDVQQKExpBZG9iZSBTeXN0" + "ZW1zIEluY29ycG9yYXRlZDEdMBsGA1UECxMUQWRvYmUgVHJ1c3QgU2Vydmlj" + "ZXMxFjAUBgNVBAMTDUFkb2JlIFJvb3QgQ0EwggEiMA0GCSqGSIb3DQEBAQUA" + "A4IBDwAwggEKAoIBAQDMT1SE96ei5zNTfz+cEohrLJlHZ34PHrmtFIj5wxDY" + "HfDw1Z9pCi9ZNbDMbKlMnBWgn84gv6DPVOLgIGZFPzmGOH6cxI4HIsYk9gES" + "sDXfVeppkLDbhTce4k4HskKhahNpoGbqgJERWSqbCHlaIEQtyb1zOIs8L+BD" + "G12zC/CvNRop/u+mkt2BTJ09WY6tMTxAfpuRNgb84lyN0Y0m1VxFz69lP7Gq" + "0mKW9Kg46rpgQvT0HEo1Fc74TiJWD5UYxfiWn5/7sLd4JemAa73WCvDGdJSd" + "8w9Q25p3zktwgyONoMp4IERcPFRk8eqiMBmf6kwGTQZ4S16S3yLSyWezetIB" + "AgMBAAGjggFPMIIBSzARBglghkgBhvhCAQEEBAMCAAcwgY4GA1UdHwSBhjCB" + "gzCBgKB+oHykejB4MQswCQYDVQQGEwJVUzEjMCEGA1UEChMaQWRvYmUgU3lz" + "dGVtcyBJbmNvcnBvcmF0ZWQxHTAbBgNVBAsTFEFkb2JlIFRydXN0IFNlcnZp" + "Y2VzMRYwFAYDVQQDEw1BZG9iZSBSb290IENBMQ0wCwYDVQQDEwRDUkwxMCsG" + "A1UdEAQkMCKADzIwMDMwMTA4MjMzNzIzWoEPMjAyMzAxMDkwMDA3MjNaMAsG" + "A1UdDwQEAwIBBjAfBgNVHSMEGDAWgBSCtzhKk6qbEO+Au9lU4vEP+4Cc3jAd" + "BgNVHQ4EFgQUgrc4SpOqmxDvgLvZVOLxD/uAnN4wDAYDVR0TBAUwAwEB/zAd" + "BgkqhkiG9n0HQQAEEDAOGwhWNi4wOjQuMAMCBJAwDQYJKoZIhvcNAQEFBQAD" + "ggEBADLan0N1wfpvyW/bqx02Nz68YRk2twI8HSNZmGye7k2F51TIIB+n1Lvi" + "vwB3fSRrcC9cwTp2SbXT4COEKnFqIvPBJymYFfY1kOQETMONvJ9hHOf9JIzR" + "REOMFrqbTaXUNS+8Ec6991E3jZ+Q5BTxGD++6VkSNfkzkvOe4NVrmnGbmUvI" + "ccPhsWEJxOX6kfBCOjd9NPly6M2qYhwh6dX0ghDjewW2LWhWC35+kixvTXKC" + "DO1WdLKduastKx0QX9sndXCP/R3X4gKgeeUc5f+vZEBRLZ6bR9tCpXwfwqZI" + "sNe+kmlNpPYpV8V4ERjch1HKE7JinU8rMr0xpcH6UqsFiMgwggTLMIIDs6AD" + "AgECAgQ+HL21MA0GCSqGSIb3DQEBBQUAMGkxCzAJBgNVBAYTAlVTMSMwIQYD" + "VQQKExpBZG9iZSBTeXN0ZW1zIEluY29ycG9yYXRlZDEdMBsGA1UECxMUQWRv" + "YmUgVHJ1c3QgU2VydmljZXMxFjAUBgNVBAMTDUFkb2JlIFJvb3QgQ0EwHhcN" + "MDQwMTE3MDAwMzM5WhcNMTUwMTE1MDgwMDAwWjBFMQswCQYDVQQGEwJVUzEW" + "MBQGA1UEChMNR2VvVHJ1c3QgSW5jLjEeMBwGA1UEAxMVR2VvVHJ1c3QgQ0Eg" + "Zm9yIEFkb2JlMIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEAp+V3" + "4GR4Wuc5hbyv0vVbKBMOVN1J+s5i9ZL9nph7n+X4esFs4epAJcFxJ4KnPuQH" + "ZZ0oyHUU4Th70mWYgKwd6sEt1aR6ZT788Nvr3OHwTRwugN/G6QXqhU9ePpZJ" + "OF1Ibsf1pcXNGvpLdcYK6+CX5DANMuIthb440XoNfC3dNBC0pF4mM4lmTjpl" + "nQG8xK0rIFp4HoMpmyaIijz2qyjXdUNkg0fbDUq9eDTKAOLOg21u+AA8XKbC" + "ewg1LWSV9CVy+fTHREmb1thBcrfkY1kCAvczsuquV3SMx8hRpa+4cIvKK/K1" + "G7OrV0nsTyuaJ2MMST8b7bul/Xd81nu9Hsz4iQIDAQABo4IBnTCCAZkwEgYD" + "VR0TAQH/BAgwBgEB/wIBATBQBgNVHSAESTBHMEUGCSqGSIb3LwECATA4MDYG" + "CCsGAQUFBwIBFipodHRwczovL3d3dy5hZG9iZS5jb20vbWlzYy9wa2kvY2Rz" + "X2NwLmh0bWwwFAYDVR0lBA0wCwYJKoZIhvcvAQEFMIGyBgNVHR8Egaowgacw" + "IqAgoB6GHGh0dHA6Ly9jcmwuYWRvYmUuY29tL2Nkcy5jcmwwgYCgfqB8pHow" + "eDELMAkGA1UEBhMCVVMxIzAhBgNVBAoTGkFkb2JlIFN5c3RlbXMgSW5jb3Jw" + "b3JhdGVkMR0wGwYDVQQLExRBZG9iZSBUcnVzdCBTZXJ2aWNlczEWMBQGA1UE" + "AxMNQWRvYmUgUm9vdCBDQTENMAsGA1UEAxMEQ1JMMTALBgNVHQ8EBAMCAQYw" + "HwYDVR0jBBgwFoAUgrc4SpOqmxDvgLvZVOLxD/uAnN4wHQYDVR0OBBYEFKuA" + "WcNlg20dfRO9GcPsGo8NR2qjMBkGCSqGSIb2fQdBAAQMMAobBFY2LjADAgSQ" + "MA0GCSqGSIb3DQEBBQUAA4IBAQA/OVkuogCOsV4RYSzS4Lb1jImGRc4T2Z/d" + "hJoUawhMX4aXWPSlqNOPIfhHflCvd+Whbarcd83NN5n3QmevUOFUREPrMQyA" + "mkK0mpW6TSyLG5ckeCFL8qJwp/hhckk/H16m4hEXWyIFGfOecX3Sy+Y4kxcC" + "lzSMadifedB+TiRpKFKcNphp5hEMkpyyJaGXpLnN/BLsaDyEN7JySExAopae" + "UbUJCvCVIWKwoJ26ih3BG1aB+3yTHXeLIorextqWbq+dVz7me59Li8j5PAxe" + "hXrc2phpKuhp8FaTScvnfMZc8TL4Dr1CHMRWIkqfZaCq3mC376Mww0iZtE5s" + "iqB+AXVWMYIBgDCCAXwCAQEwSzBFMQswCQYDVQQGEwJVUzEWMBQGA1UEChMN" + "R2VvVHJ1c3QgSW5jLjEeMBwGA1UEAxMVR2VvVHJ1c3QgQ0EgZm9yIEFkb2Jl" + "AgIAjzAJBgUrDgMCGgUAoIGMMBoGCSqGSIb3DQEJAzENBgsqhkiG9w0BCRAB" + "BDAcBgkqhkiG9w0BCQUxDxcNMDYwNDA0MjAyMDU3WjAjBgkqhkiG9w0BCQQx" + "FgQUp7AnXBqoNcarvO7fMJut1og2U5AwKwYLKoZIhvcNAQkQAgwxHDAaMBgw" + "FgQU1dH4eZTNhgxdiSABrat6zsPdth0wDQYJKoZIhvcNAQEBBQAEgYCinr/F" + "rMiQz/MRm9ZD5YGcC0Qo2dRTPd0Aop8mZ4g1xAhKFLnp7lLsjCbkSDpVLDBh" + "cnCk7CV+3FT5hlvt8OqZlR0CnkSnCswLFhrppiWle6cpxlwGqyAteC8uKtQu" + "wjE5GtBKLcCOAzQYyyuNZZeB6oCZ+3mPhZ62FxrvvEGJCgAAAAAAAAAAAAAA" + "AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA" + "AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA" + "AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA" + "AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA" + "AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA" + "AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA" + "AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA" + "AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA" + "AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA=="); private final byte[] emptyDNCert = Base64.decode( "MIICfTCCAeagAwIBAgIBajANBgkqhkiG9w0BAQQFADB8MQswCQYDVQQGEwJVUzEMMAoGA1UEChMD" + "Q0RXMQkwBwYDVQQLEwAxCTAHBgNVBAcTADEJMAcGA1UECBMAMRowGAYDVQQDExFUZW1wbGFyIFRl" + "c3QgMTAyNDEiMCAGCSqGSIb3DQEJARYTdGVtcGxhcnRlc3RAY2R3LmNvbTAeFw0wNjA1MjIwNTAw" + "MDBaFw0xMDA1MjIwNTAwMDBaMHwxCzAJBgNVBAYTAlVTMQwwCgYDVQQKEwNDRFcxCTAHBgNVBAsT" + "ADEJMAcGA1UEBxMAMQkwBwYDVQQIEwAxGjAYBgNVBAMTEVRlbXBsYXIgVGVzdCAxMDI0MSIwIAYJ" + "KoZIhvcNAQkBFhN0ZW1wbGFydGVzdEBjZHcuY29tMIGfMA0GCSqGSIb3DQEBAQUAA4GNADCBiQKB" + "gQDH3aJpJBfM+A3d84j5YcU6zEQaQ76u5xO9NSBmHjZykKS2kCcUqPpvVOPDA5WgV22dtKPh+lYV" + "iUp7wyCVwAKibq8HIbihHceFqMKzjwC639rMoDJ7bi/yzQWz1Zg+075a4FGPlUKn7Yfu89wKkjdW" + "wDpRPXc/agqBnrx5pJTXzQIDAQABow8wDTALBgNVHQ8EBAMCALEwDQYJKoZIhvcNAQEEBQADgYEA" + "RRsRsjse3i2/KClFVd6YLZ+7K1BE0WxFyY2bbytkwQJSxvv3vLSuweFUbhNxutb68wl/yW4GLy4b" + "1QdyswNxrNDXTuu5ILKhRDDuWeocz83aG2KGtr3JlFyr3biWGEyn5WUOE6tbONoQDJ0oPYgI6CAc" + "EHdUp0lioOCt6UOw7Cs="); private final byte[] gostRFC4491_94 = Base64.decode( "MIICCzCCAboCECMO42BGlSTOxwvklBgufuswCAYGKoUDAgIEMGkxHTAbBgNVBAMM" + "FEdvc3RSMzQxMC05NCBleGFtcGxlMRIwEAYDVQQKDAlDcnlwdG9Qcm8xCzAJBgNV" + "BAYTAlJVMScwJQYJKoZIhvcNAQkBFhhHb3N0UjM0MTAtOTRAZXhhbXBsZS5jb20w" + "HhcNMDUwODE2MTIzMjUwWhcNMTUwODE2MTIzMjUwWjBpMR0wGwYDVQQDDBRHb3N0" + "UjM0MTAtOTQgZXhhbXBsZTESMBAGA1UECgwJQ3J5cHRvUHJvMQswCQYDVQQGEwJS" + "VTEnMCUGCSqGSIb3DQEJARYYR29zdFIzNDEwLTk0QGV4YW1wbGUuY29tMIGlMBwG" + "BiqFAwICFDASBgcqhQMCAiACBgcqhQMCAh4BA4GEAASBgLuEZuF5nls02CyAfxOo" + "GWZxV/6MVCUhR28wCyd3RpjG+0dVvrey85NsObVCNyaE4g0QiiQOHwxCTSs7ESuo" + "v2Y5MlyUi8Go/htjEvYJJYfMdRv05YmKCYJo01x3pg+2kBATjeM+fJyR1qwNCCw+" + "eMG1wra3Gqgqi0WBkzIydvp7MAgGBiqFAwICBANBABHHCH4S3ALxAiMpR3aPRyqB" + "g1DjB8zy5DEjiULIc+HeIveF81W9lOxGkZxnrFjXBSqnjLeFKgF1hffXOAP7zUM="); private final byte[] gostRFC4491_2001 = Base64.decode( "MIIB0DCCAX8CECv1xh7CEb0Xx9zUYma0LiEwCAYGKoUDAgIDMG0xHzAdBgNVBAMM" + "Fkdvc3RSMzQxMC0yMDAxIGV4YW1wbGUxEjAQBgNVBAoMCUNyeXB0b1BybzELMAkG" + "A1UEBhMCUlUxKTAnBgkqhkiG9w0BCQEWGkdvc3RSMzQxMC0yMDAxQGV4YW1wbGUu" + "Y29tMB4XDTA1MDgxNjE0MTgyMFoXDTE1MDgxNjE0MTgyMFowbTEfMB0GA1UEAwwW" + "R29zdFIzNDEwLTIwMDEgZXhhbXBsZTESMBAGA1UECgwJQ3J5cHRvUHJvMQswCQYD" + "VQQGEwJSVTEpMCcGCSqGSIb3DQEJARYaR29zdFIzNDEwLTIwMDFAZXhhbXBsZS5j" + "b20wYzAcBgYqhQMCAhMwEgYHKoUDAgIkAAYHKoUDAgIeAQNDAARAhJVodWACGkB1" + "CM0TjDGJLP3lBQN6Q1z0bSsP508yfleP68wWuZWIA9CafIWuD+SN6qa7flbHy7Df" + "D2a8yuoaYDAIBgYqhQMCAgMDQQA8L8kJRLcnqeyn1en7U23Sw6pkfEQu3u0xFkVP" + "vFQ/3cHeF26NG+xxtZPz3TaTVXdoiYkXYiD02rEx1bUcM97i"); private PublicKey dudPublicKey = new PublicKey() { public String getAlgorithm() { return null; } public String getFormat() { return null; } public byte[] getEncoded() { return null; } }; public String getName() { return "CertTest"; } public void checkCertificate( int id, byte[] bytes) { ByteArrayInputStream bIn; String dump = ""; try { bIn = new ByteArrayInputStream(bytes); CertificateFactory fact = CertificateFactory.getInstance("X.509", "BC"); Certificate cert = fact.generateCertificate(bIn); PublicKey k = cert.getPublicKey(); // System.out.println(cert); } catch (Exception e) { fail(dump + System.getProperty("line.separator") + getName() + ": "+ id + " failed - exception " + e.toString(), e); } } public void checkNameCertificate( int id, byte[] bytes) { ByteArrayInputStream bIn; String dump = ""; try { bIn = new ByteArrayInputStream(bytes); CertificateFactory fact = CertificateFactory.getInstance("X.509", "BC"); X509Certificate cert = (X509Certificate)fact.generateCertificate(bIn); PublicKey k = cert.getPublicKey(); if (!cert.getIssuerDN().toString().equals("C=DE,O=DATEV eG,0.2.262.1.10.7.20=1+CN=CA DATEV D03 1:PN")) { fail(id + " failed - name test."); } // System.out.println(cert); } catch (Exception e) { fail(dump + System.getProperty("line.separator") + getName() + ": "+ id + " failed - exception " + e.toString(), e); } } public void checkKeyUsage( int id, byte[] bytes) { ByteArrayInputStream bIn; String dump = ""; try { bIn = new ByteArrayInputStream(bytes); CertificateFactory fact = CertificateFactory.getInstance("X.509", "BC"); X509Certificate cert = (X509Certificate)fact.generateCertificate(bIn); PublicKey k = cert.getPublicKey(); if (cert.getKeyUsage()[7]) { fail("error generating cert - key usage wrong."); } // System.out.println(cert); } catch (Exception e) { fail(dump + System.getProperty("line.separator") + getName() + ": "+ id + " failed - exception " + e.toString(), e); } } public void checkSelfSignedCertificate( int id, byte[] bytes) { ByteArrayInputStream bIn; String dump = ""; try { bIn = new ByteArrayInputStream(bytes); CertificateFactory fact = CertificateFactory.getInstance("X.509", "BC"); Certificate cert = fact.generateCertificate(bIn); PublicKey k = cert.getPublicKey(); cert.verify(k); // System.out.println(cert); } catch (Exception e) { fail(dump + System.getProperty("line.separator") + getName() + ": "+ id + " failed - exception " + e.toString(), e); } } /** * Test a generated certificate with the sun provider */ private void sunProviderCheck(byte[] encoding) throws CertificateException { CertificateFactory certFact = CertificateFactory.getInstance("X.509"); certFact.generateCertificate(new ByteArrayInputStream(encoding)); } /** * we generate a self signed certificate for the sake of testing - RSA */ public void checkCreation1() throws Exception { // // a sample key pair. // RSAPublicKeySpec pubKeySpec = new RSAPublicKeySpec( new BigInteger("b4a7e46170574f16a97082b22be58b6a2a629798419be12872a4bdba626cfae9900f76abfb12139dce5de56564fab2b6543165a040c606887420e33d91ed7ed7", 16), new BigInteger("11", 16)); RSAPrivateCrtKeySpec privKeySpec = new RSAPrivateCrtKeySpec( new BigInteger("b4a7e46170574f16a97082b22be58b6a2a629798419be12872a4bdba626cfae9900f76abfb12139dce5de56564fab2b6543165a040c606887420e33d91ed7ed7", 16), new BigInteger("11", 16), new BigInteger("9f66f6b05410cd503b2709e88115d55daced94d1a34d4e32bf824d0dde6028ae79c5f07b580f5dce240d7111f7ddb130a7945cd7d957d1920994da389f490c89", 16), new BigInteger("c0a0758cdf14256f78d4708c86becdead1b50ad4ad6c5c703e2168fbf37884cb", 16), new BigInteger("f01734d7960ea60070f1b06f2bb81bfac48ff192ae18451d5e56c734a5aab8a5", 16), new BigInteger("b54bb9edff22051d9ee60f9351a48591b6500a319429c069a3e335a1d6171391", 16), new BigInteger("d3d83daf2a0cecd3367ae6f8ae1aeb82e9ac2f816c6fc483533d8297dd7884cd", 16), new BigInteger("b8f52fc6f38593dabb661d3f50f8897f8106eee68b1bce78a95b132b4e5b5d19", 16)); // // set up the keys // PrivateKey privKey; PublicKey pubKey; KeyFactory fact = KeyFactory.getInstance("RSA", "BC"); privKey = fact.generatePrivate(privKeySpec); pubKey = fact.generatePublic(pubKeySpec); // // distinguished name table. // X500NameBuilder builder = new X500NameBuilder(BCStyle.INSTANCE); builder.addRDN(BCStyle.C, "AU"); builder.addRDN(BCStyle.O, "The Legion of the Bouncy Castle"); builder.addRDN(BCStyle.L, "Melbourne"); builder.addRDN(BCStyle.ST, "Victoria"); builder.addRDN(BCStyle.E, "feedback-crypto@bouncycastle.org"); // // extensions // // // create the certificate - version 3 - without extensions // ContentSigner sigGen = new JcaContentSignerBuilder("SHA256WithRSAEncryption").setProvider(BC).build(privKey); X509v3CertificateBuilder certGen = new JcaX509v3CertificateBuilder(builder.build(), BigInteger.valueOf(1), new Date(System.currentTimeMillis() - 50000), new Date(System.currentTimeMillis() + 50000),builder.build(), pubKey); X509Certificate cert = new JcaX509CertificateConverter().setProvider(BC).getCertificate(certGen.build(sigGen)); cert.checkValidity(new Date()); cert.verify(pubKey); cert.verify(cert.getPublicKey()); Set dummySet = cert.getNonCriticalExtensionOIDs(); if (dummySet != null) { fail("non-critical oid set should be null"); } dummySet = cert.getCriticalExtensionOIDs(); if (dummySet != null) { fail("critical oid set should be null"); } // // create the certificate - version 3 - with extensions // sigGen = new JcaContentSignerBuilder("MD5WithRSAEncryption").setProvider(BC).build(privKey); certGen = new JcaX509v3CertificateBuilder(builder.build(), BigInteger.valueOf(1) , new Date(System.currentTimeMillis() - 50000) , new Date(System.currentTimeMillis() + 50000) , builder.build() , pubKey) .addExtension(new ASN1ObjectIdentifier("2.5.29.15"), true, new X509KeyUsage(X509KeyUsage.encipherOnly)) .addExtension(new ASN1ObjectIdentifier("2.5.29.37"), true, new DERSequence(KeyPurposeId.anyExtendedKeyUsage)) .addExtension(new ASN1ObjectIdentifier("2.5.29.17"), true, new GeneralNames(new GeneralName[] { new GeneralName(GeneralName.rfc822Name, "test@test.test"), new GeneralName(GeneralName.dNSName, "dom.test.test") })); X509CertificateHolder certHolder = certGen.build(sigGen); cert = new JcaX509CertificateConverter().setProvider(BC).getCertificate(certHolder); cert.checkValidity(new Date()); cert.verify(pubKey); cert.verify(cert.getPublicKey()); ContentVerifierProvider contentVerifierProvider = new JcaContentVerifierProviderBuilder().setProvider(BC).build(pubKey); if (!certHolder.isSignatureValid(contentVerifierProvider)) { fail("signature test failed"); } ByteArrayInputStream bIn = new ByteArrayInputStream(cert.getEncoded()); CertificateFactory certFact = CertificateFactory.getInstance("X.509", "BC"); cert = (X509Certificate)certFact.generateCertificate(bIn); if (!cert.getKeyUsage()[7]) { fail("error generating cert - key usage wrong."); } /* List l = cert.getExtendedKeyUsage(); if (!l.get(0).equals(KeyPurposeId.anyExtendedKeyUsage.getId())) { fail("failed extended key usage test"); } Collection c = cert.getSubjectAlternativeNames(); Iterator it = c.iterator(); while (it.hasNext()) { List gn = (List)it.next(); if (!gn.get(1).equals("test@test.test") && !gn.get(1).equals("dom.test.test")) { fail("failed subject alternative names test"); } } */ sunProviderCheck(certHolder.getEncoded()); sunProviderCheck(cert.getEncoded()); // System.out.println(cert); // // create the certificate - version 1 // sigGen = new JcaContentSignerBuilder("MD5WithRSAEncryption").setProvider(BC).build(privKey); X509v1CertificateBuilder certGen1 = new JcaX509v1CertificateBuilder(builder.build(), BigInteger.valueOf(1), new Date(System.currentTimeMillis() - 50000),new Date(System.currentTimeMillis() + 50000),builder.build(),pubKey); cert = new JcaX509CertificateConverter().setProvider(BC).getCertificate(certGen1.build(sigGen)); cert.checkValidity(new Date()); cert.verify(pubKey); cert.verify(cert.getPublicKey()); bIn = new ByteArrayInputStream(cert.getEncoded()); certFact = CertificateFactory.getInstance("X.509", "BC"); cert = (X509Certificate)certFact.generateCertificate(bIn); // System.out.println(cert); if (!cert.getIssuerDN().equals(cert.getSubjectDN())) { fail("name comparison fails"); } sunProviderCheck(certHolder.getEncoded()); sunProviderCheck(cert.getEncoded()); // // a lightweight key pair. // RSAKeyParameters lwPubKey = new RSAKeyParameters( false, new BigInteger("b4a7e46170574f16a97082b22be58b6a2a629798419be12872a4bdba626cfae9900f76abfb12139dce5de56564fab2b6543165a040c606887420e33d91ed7ed7", 16), new BigInteger("11", 16)); RSAPrivateCrtKeyParameters lwPrivKey = new RSAPrivateCrtKeyParameters( new BigInteger("b4a7e46170574f16a97082b22be58b6a2a629798419be12872a4bdba626cfae9900f76abfb12139dce5de56564fab2b6543165a040c606887420e33d91ed7ed7", 16), new BigInteger("11", 16), new BigInteger("9f66f6b05410cd503b2709e88115d55daced94d1a34d4e32bf824d0dde6028ae79c5f07b580f5dce240d7111f7ddb130a7945cd7d957d1920994da389f490c89", 16), new BigInteger("c0a0758cdf14256f78d4708c86becdead1b50ad4ad6c5c703e2168fbf37884cb", 16), new BigInteger("f01734d7960ea60070f1b06f2bb81bfac48ff192ae18451d5e56c734a5aab8a5", 16), new BigInteger("b54bb9edff22051d9ee60f9351a48591b6500a319429c069a3e335a1d6171391", 16), new BigInteger("d3d83daf2a0cecd3367ae6f8ae1aeb82e9ac2f816c6fc483533d8297dd7884cd", 16), new BigInteger("b8f52fc6f38593dabb661d3f50f8897f8106eee68b1bce78a95b132b4e5b5d19", 16)); // // distinguished name table. // builder = new X500NameBuilder(BCStyle.INSTANCE); builder.addRDN(BCStyle.C, "AU"); builder.addRDN(BCStyle.O, "The Legion of the Bouncy Castle"); builder.addRDN(BCStyle.L, "Melbourne"); builder.addRDN(BCStyle.ST, "Victoria"); builder.addRDN(BCStyle.E, "feedback-crypto@bouncycastle.org"); // // extensions // // // create the certificate - version 3 - without extensions // AlgorithmIdentifier sigAlgId = new DefaultSignatureAlgorithmIdentifierFinder().find("SHA256WithRSAEncryption"); AlgorithmIdentifier digAlgId = new DefaultDigestAlgorithmIdentifierFinder().find(sigAlgId); sigGen = new BcRSAContentSignerBuilder(sigAlgId, digAlgId).build(lwPrivKey); SubjectPublicKeyInfo pubInfo = new SubjectPublicKeyInfo(new AlgorithmIdentifier(PKCSObjectIdentifiers.rsaEncryption, DERNull.INSTANCE), new RSAPublicKey(lwPubKey.getModulus(), lwPubKey.getExponent())); certGen = new X509v3CertificateBuilder(builder.build(), BigInteger.valueOf(1), new Date(System.currentTimeMillis() - 50000), new Date(System.currentTimeMillis() + 50000), builder.build(), pubInfo); certHolder = certGen.build(sigGen); cert = new JcaX509CertificateConverter().setProvider(BC).getCertificate(certHolder); cert.checkValidity(new Date()); cert.verify(pubKey); contentVerifierProvider = new BcRSAContentVerifierProviderBuilder(new DefaultDigestAlgorithmIdentifierFinder()).build(lwPubKey); if (!certHolder.isSignatureValid(contentVerifierProvider)) { fail("lw sig verification failed"); } } /** * we generate a self signed certificate for the sake of testing - DSA */ public void checkCreation2() throws Exception { // // set up the keys // PrivateKey privKey; PublicKey pubKey; try { KeyPairGenerator g = KeyPairGenerator.getInstance("DSA", "SUN"); g.initialize(512, new SecureRandom()); KeyPair p = g.generateKeyPair(); privKey = p.getPrivate(); pubKey = p.getPublic(); } catch (Exception e) { fail("error setting up keys - " + e.toString()); return; } // // distinguished name table. // X500NameBuilder builder = createStdBuilder(); // // extensions // // // create the certificate - version 3 // ContentSigner sigGen = new JcaContentSignerBuilder("SHA1withDSA").setProvider(BC).build(privKey); JcaX509v3CertificateBuilder certGen = new JcaX509v3CertificateBuilder(builder.build(),BigInteger.valueOf(1),new Date(System.currentTimeMillis() - 50000),new Date(System.currentTimeMillis() + 50000),builder.build(),pubKey); X509Certificate cert = new JcaX509CertificateConverter().setProvider(BC).getCertificate(certGen.build(sigGen)); cert.checkValidity(new Date()); cert.verify(pubKey); ByteArrayInputStream bIn = new ByteArrayInputStream(cert.getEncoded()); CertificateFactory fact = CertificateFactory.getInstance("X.509", BC); cert = (X509Certificate)fact.generateCertificate(bIn); // System.out.println(cert); // // create the certificate - version 1 // sigGen = new JcaContentSignerBuilder("SHA1withDSA").setProvider(BC).build(privKey); JcaX509v1CertificateBuilder certGen1 = new JcaX509v1CertificateBuilder(builder.build(),BigInteger.valueOf(1),new Date(System.currentTimeMillis() - 50000),new Date(System.currentTimeMillis() + 50000),builder.build(),pubKey); cert = new JcaX509CertificateConverter().setProvider(BC).getCertificate(certGen1.build(sigGen)); cert.checkValidity(new Date()); cert.verify(pubKey); bIn = new ByteArrayInputStream(cert.getEncoded()); fact = CertificateFactory.getInstance("X.509", BC); cert = (X509Certificate)fact.generateCertificate(bIn); //System.out.println(cert); // // exception test // try { certGen1 = new JcaX509v1CertificateBuilder(builder.build(),BigInteger.valueOf(1),new Date(System.currentTimeMillis() - 50000),new Date(System.currentTimeMillis() + 50000),builder.build(),dudPublicKey); fail("key without encoding not detected in v1"); } catch (IllegalArgumentException e) { // expected } } private X500NameBuilder createStdBuilder() { X500NameBuilder builder = new X500NameBuilder(BCStyle.INSTANCE); builder.addRDN(BCStyle.C, "AU"); builder.addRDN(BCStyle.O, "The Legion of the Bouncy Castle"); builder.addRDN(BCStyle.L, "Melbourne"); builder.addRDN(BCStyle.ST, "Victoria"); builder.addRDN(BCStyle.E, "feedback-crypto@bouncycastle.org"); return builder; } /** * we generate a self signed certificate for the sake of testing - ECDSA */ public void checkCreation3() { ECCurve curve = new ECCurve.Fp( new BigInteger("883423532389192164791648750360308885314476597252960362792450860609699839"), // q new BigInteger("7fffffffffffffffffffffff7fffffffffff8000000000007ffffffffffc", 16), // a new BigInteger("6b016c3bdcf18941d0d654921475ca71a9db2fb27d1d37796185c2942c0a", 16)); // b ECParameterSpec spec = new ECParameterSpec( curve, curve.decodePoint(Hex.decode("020ffa963cdca8816ccc33b8642bedf905c3d358573d3f27fbbd3b3cb9aaaf")), // G new BigInteger("883423532389192164791648750360308884807550341691627752275345424702807307")); // n ECPrivateKeySpec privKeySpec = new ECPrivateKeySpec( new BigInteger("876300101507107567501066130761671078357010671067781776716671676178726717"), // d spec); ECPublicKeySpec pubKeySpec = new ECPublicKeySpec( curve.decodePoint(Hex.decode("025b6dc53bc61a2548ffb0f671472de6c9521a9d2d2534e65abfcbd5fe0c70")), // Q spec); // // set up the keys // PrivateKey privKey; PublicKey pubKey; try { KeyFactory fact = KeyFactory.getInstance("ECDSA", BC); privKey = fact.generatePrivate(privKeySpec); pubKey = fact.generatePublic(pubKeySpec); } catch (Exception e) { fail("error setting up keys - " + e.toString()); return; } // // distinguished name table. // X500NameBuilder builder = createStdBuilder(); // // toString test // X500Name p = builder.build(); String s = p.toString(); if (!s.equals("C=AU,O=The Legion of the Bouncy Castle,L=Melbourne,ST=Victoria,E=feedback-crypto@bouncycastle.org")) { fail("ordered X509Principal test failed - s = " + s + "."); } // p = new X509Principal(attrs); // s = p.toString(); // // // // // we need two of these as the hash code for strings changed... // // // if (!s.equals("O=The Legion of the Bouncy Castle,E=feedback-crypto@bouncycastle.org,ST=Victoria,L=Melbourne,C=AU") && !s.equals("ST=Victoria,L=Melbourne,C=AU,E=feedback-crypto@bouncycastle.org,O=The Legion of the Bouncy Castle")) // { // fail("unordered X509Principal test failed."); // } // // create the certificate - version 3 // try { ContentSigner sigGen = new JcaContentSignerBuilder("SHA1withECDSA").setProvider(BC).build(privKey); JcaX509v3CertificateBuilder certGen = new JcaX509v3CertificateBuilder(builder.build(),BigInteger.valueOf(1),new Date(System.currentTimeMillis() - 50000),new Date(System.currentTimeMillis() + 50000),builder.build(),pubKey); X509Certificate cert = new JcaX509CertificateConverter().setProvider(BC).getCertificate(certGen.build(sigGen)); cert.checkValidity(new Date()); cert.verify(pubKey); ByteArrayInputStream bIn = new ByteArrayInputStream(cert.getEncoded()); CertificateFactory fact = CertificateFactory.getInstance("X.509", BC); cert = (X509Certificate)fact.generateCertificate(bIn); // // try with point compression turned off // ((ECPointEncoder)pubKey).setPointFormat("UNCOMPRESSED"); certGen = new JcaX509v3CertificateBuilder(builder.build(),BigInteger.valueOf(1),new Date(System.currentTimeMillis() - 50000),new Date(System.currentTimeMillis() + 50000),builder.build(),pubKey); cert = new JcaX509CertificateConverter().setProvider(BC).getCertificate(certGen.build(sigGen)); cert.checkValidity(new Date()); cert.verify(pubKey); bIn = new ByteArrayInputStream(cert.getEncoded()); fact = CertificateFactory.getInstance("X.509", BC); cert = (X509Certificate)fact.generateCertificate(bIn); // System.out.println(cert); } catch (Exception e) { fail("error setting generating cert - " + e.toString()); } X509Principal pr = new X509Principal("O=\"The Bouncy Castle, The Legion of\",E=feedback-crypto@bouncycastle.org,ST=Victoria,L=Melbourne,C=AU"); if (!pr.toString().equals("O=The Bouncy Castle\\, The Legion of,E=feedback-crypto@bouncycastle.org,ST=Victoria,L=Melbourne,C=AU")) { fail("string based X509Principal test failed."); } pr = new X509Principal("O=The Bouncy Castle\\, The Legion of,E=feedback-crypto@bouncycastle.org,ST=Victoria,L=Melbourne,C=AU"); if (!pr.toString().equals("O=The Bouncy Castle\\, The Legion of,E=feedback-crypto@bouncycastle.org,ST=Victoria,L=Melbourne,C=AU")) { fail("string based X509Principal test failed."); } } /** * we generate a self signed certificate for the sake of testing - SHA224withECDSA */ private void createECCert(String algorithm, DERObjectIdentifier algOid) throws Exception { ECCurve.Fp curve = new ECCurve.Fp( new BigInteger("6864797660130609714981900799081393217269435300143305409394463459185543183397656052122559640661454554977296311391480858037121987999716643812574028291115057151"), // q (or p) new BigInteger("01FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFC", 16), // a new BigInteger("0051953EB9618E1C9A1F929A21A0B68540EEA2DA725B99B315F3B8B489918EF109E156193951EC7E937B1652C0BD3BB1BF073573DF883D2C34F1EF451FD46B503F00", 16)); // b ECParameterSpec spec = new ECParameterSpec( curve, curve.decodePoint(Hex.decode("0200C6858E06B70404E9CD9E3ECB662395B4429C648139053FB521F828AF606B4D3DBAA14B5E77EFE75928FE1DC127A2FFA8DE3348B3C1856A429BF97E7E31C2E5BD66")), // G new BigInteger("01FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFA51868783BF2F966B7FCC0148F709A5D03BB5C9B8899C47AEBB6FB71E91386409", 16)); // n ECPrivateKeySpec privKeySpec = new ECPrivateKeySpec( new BigInteger("5769183828869504557786041598510887460263120754767955773309066354712783118202294874205844512909370791582896372147797293913785865682804434049019366394746072023"), // d spec); ECPublicKeySpec pubKeySpec = new ECPublicKeySpec( curve.decodePoint(Hex.decode("02006BFDD2C9278B63C92D6624F151C9D7A822CC75BD983B17D25D74C26740380022D3D8FAF304781E416175EADF4ED6E2B47142D2454A7AC7801DD803CF44A4D1F0AC")), // Q spec); // // set up the keys // PrivateKey privKey; PublicKey pubKey; KeyFactory fact = KeyFactory.getInstance("ECDSA", BC); privKey = fact.generatePrivate(privKeySpec); pubKey = fact.generatePublic(pubKeySpec); // // distinguished name table. // X500NameBuilder builder = createStdBuilder(); // // create the certificate - version 3 // ContentSigner sigGen = new JcaContentSignerBuilder(algorithm).setProvider(BC).build(privKey); X509v3CertificateBuilder certGen = new JcaX509v3CertificateBuilder(builder.build(),BigInteger.valueOf(1),new Date(System.currentTimeMillis() - 50000),new Date(System.currentTimeMillis() + 50000),builder.build(),pubKey); X509Certificate cert = new JcaX509CertificateConverter().setProvider(BC).getCertificate(certGen.build(sigGen)); cert.checkValidity(new Date()); cert.verify(pubKey); ByteArrayInputStream bIn = new ByteArrayInputStream(cert.getEncoded()); CertificateFactory certFact = CertificateFactory.getInstance("X.509", BC); cert = (X509Certificate)certFact.generateCertificate(bIn); // // try with point compression turned off // ((ECPointEncoder)pubKey).setPointFormat("UNCOMPRESSED"); certGen = new JcaX509v3CertificateBuilder(builder.build(),BigInteger.valueOf(1),new Date(System.currentTimeMillis() - 50000),new Date(System.currentTimeMillis() + 50000),builder.build(),pubKey); cert = new JcaX509CertificateConverter().setProvider(BC).getCertificate(certGen.build(sigGen)); cert.checkValidity(new Date()); cert.verify(pubKey); bIn = new ByteArrayInputStream(cert.getEncoded()); certFact = CertificateFactory.getInstance("X.509", BC); cert = (X509Certificate)certFact.generateCertificate(bIn); if (!cert.getSigAlgOID().equals(algOid.toString())) { fail("ECDSA oid incorrect."); } if (cert.getSigAlgParams() != null) { fail("sig parameters present"); } Signature sig = Signature.getInstance(algorithm, BC); sig.initVerify(pubKey); sig.update(cert.getTBSCertificate()); if (!sig.verify(cert.getSignature())) { fail("EC certificate signature not mapped correctly."); } // System.out.println(cert); } private void checkCRL( int id, byte[] bytes) { ByteArrayInputStream bIn; String dump = ""; try { bIn = new ByteArrayInputStream(bytes); CertificateFactory fact = CertificateFactory.getInstance("X.509", BC); CRL cert = fact.generateCRL(bIn); // System.out.println(cert); } catch (Exception e) { fail(dump + System.getProperty("line.separator") + getName() + ": "+ id + " failed - exception " + e.toString(), e); } } public void checkCRLCreation1() throws Exception { KeyPairGenerator kpGen = KeyPairGenerator.getInstance("RSA", BC); Date now = new Date(); KeyPair pair = kpGen.generateKeyPair(); X509v2CRLBuilder crlGen = new X509v2CRLBuilder(new X500Name("CN=Test CA"), now); crlGen.setNextUpdate(new Date(now.getTime() + 100000)); crlGen.addCRLEntry(BigInteger.valueOf(1), now, CRLReason.privilegeWithdrawn); crlGen.addExtension(X509Extensions.AuthorityKeyIdentifier, false, new AuthorityKeyIdentifierStructure(pair.getPublic())); X509CRLHolder crl = crlGen.build(new JcaContentSignerBuilder("SHA256withRSAEncryption").setProvider(BC).build(pair.getPrivate())); if (!crl.getIssuer().equals(new X500Name("CN=Test CA"))) { fail("failed CRL issuer test"); } Extension authExt = crl.getExtension(Extension.authorityKeyIdentifier); if (authExt == null) { fail("failed to find CRL extension"); } AuthorityKeyIdentifier authId = new AuthorityKeyIdentifierStructure(authExt); X509CRLEntryHolder entry = crl.getRevokedCertificate(BigInteger.valueOf(1)); if (entry == null) { fail("failed to find CRL entry"); } if (!entry.getSerialNumber().equals(BigInteger.valueOf(1))) { fail("CRL cert serial number does not match"); } if (!entry.hasExtensions()) { fail("CRL entry extension not found"); } Extension ext = entry.getExtension(X509Extension.reasonCode); if (ext != null) { ASN1Enumerated reasonCode = (ASN1Enumerated)ASN1Enumerated.getInstance(ext.getParsedValue()); if (reasonCode.getValue().intValue() != CRLReason.privilegeWithdrawn) { fail("CRL entry reasonCode wrong"); } } else { fail("CRL entry reasonCode not found"); } } public void checkCRLCreation2() throws Exception { KeyPairGenerator kpGen = KeyPairGenerator.getInstance("RSA", BC); Date now = new Date(); KeyPair pair = kpGen.generateKeyPair(); X509v2CRLBuilder crlGen = new X509v2CRLBuilder(new X500Name("CN=Test CA"), now); crlGen.setNextUpdate(new Date(now.getTime() + 100000)); Vector extOids = new Vector(); Vector extValues = new Vector(); CRLReason crlReason = CRLReason.lookup(CRLReason.privilegeWithdrawn); try { extOids.addElement(X509Extensions.ReasonCode); extValues.addElement(new X509Extension(false, new DEROctetString(crlReason.getEncoded()))); } catch (IOException e) { throw new IllegalArgumentException("error encoding reason: " + e); } X509Extensions entryExtensions = new X509Extensions(extOids, extValues); crlGen.addCRLEntry(BigInteger.valueOf(1), now, entryExtensions); crlGen.addExtension(X509Extensions.AuthorityKeyIdentifier, false, new AuthorityKeyIdentifierStructure(pair.getPublic())); X509CRLHolder crlHolder = crlGen.build(new JcaContentSignerBuilder("SHA256withRSAEncryption").setProvider(BC).build(pair.getPrivate())); X509CRL crl = new JcaX509CRLConverter().setProvider(BC).getCRL(crlHolder); if (!PrincipalUtil.getIssuerX509Principal(crl).equals(new X509Principal("CN=Test CA"))) { fail("failed CRL issuer test"); } byte[] authExt = crl.getExtensionValue(X509Extensions.AuthorityKeyIdentifier.getId()); if (authExt == null) { fail("failed to find CRL extension"); } AuthorityKeyIdentifier authId = new AuthorityKeyIdentifierStructure(authExt); X509CRLEntry entry = crl.getRevokedCertificate(BigInteger.valueOf(1)); if (entry == null) { fail("failed to find CRL entry"); } if (!entry.getSerialNumber().equals(BigInteger.valueOf(1))) { fail("CRL cert serial number does not match"); } if (!entry.hasExtensions()) { fail("CRL entry extension not found"); } byte[] ext = entry.getExtensionValue(X509Extensions.ReasonCode.getId()); if (ext != null) { DEREnumerated reasonCode = (DEREnumerated)X509ExtensionUtil.fromExtensionValue(ext); if (reasonCode.getValue().intValue() != CRLReason.privilegeWithdrawn) { fail("CRL entry reasonCode wrong"); } } else { fail("CRL entry reasonCode not found"); } } public void checkCRLCreation3() throws Exception { KeyPairGenerator kpGen = KeyPairGenerator.getInstance("RSA", BC); Date now = new Date(); KeyPair pair = kpGen.generateKeyPair(); X509v2CRLBuilder crlGen = new JcaX509v2CRLBuilder(new X500Name("CN=Test CA"), now); crlGen.setNextUpdate(new Date(now.getTime() + 100000)); Vector extOids = new Vector(); Vector extValues = new Vector(); CRLReason crlReason = CRLReason.lookup(CRLReason.privilegeWithdrawn); try { extOids.addElement(X509Extensions.ReasonCode); extValues.addElement(new X509Extension(false, new DEROctetString(crlReason.getEncoded()))); } catch (IOException e) { throw new IllegalArgumentException("error encoding reason: " + e); } X509Extensions entryExtensions = new X509Extensions(extOids, extValues); crlGen.addCRLEntry(BigInteger.valueOf(1), now, entryExtensions); crlGen.addExtension(X509Extensions.AuthorityKeyIdentifier, false, new AuthorityKeyIdentifierStructure(pair.getPublic())); X509CRLHolder crlHolder = crlGen.build(new JcaContentSignerBuilder("SHA256withRSAEncryption").setProvider(BC).build(pair.getPrivate())); X509CRL crl = new JcaX509CRLConverter().setProvider(BC).getCRL(crlHolder); if (!PrincipalUtil.getIssuerX509Principal(crl).equals(new X509Principal("CN=Test CA"))) { fail("failed CRL issuer test"); } byte[] authExt = crl.getExtensionValue(X509Extensions.AuthorityKeyIdentifier.getId()); if (authExt == null) { fail("failed to find CRL extension"); } AuthorityKeyIdentifier authId = new AuthorityKeyIdentifierStructure(authExt); X509CRLEntry entry = crl.getRevokedCertificate(BigInteger.valueOf(1)); if (entry == null) { fail("failed to find CRL entry"); } if (!entry.getSerialNumber().equals(BigInteger.valueOf(1))) { fail("CRL cert serial number does not match"); } if (!entry.hasExtensions()) { fail("CRL entry extension not found"); } byte[] ext = entry.getExtensionValue(X509Extensions.ReasonCode.getId()); if (ext != null) { DEREnumerated reasonCode = (DEREnumerated)X509ExtensionUtil.fromExtensionValue(ext); if (reasonCode.getValue().intValue() != CRLReason.privilegeWithdrawn) { fail("CRL entry reasonCode wrong"); } } else { fail("CRL entry reasonCode not found"); } // // check loading of existing CRL // now = new Date(); crlGen = new X509v2CRLBuilder(new X500Name("CN=Test CA"), now); crlGen.setNextUpdate(new Date(now.getTime() + 100000)); crlGen.addCRL(new JcaX509CRLHolder(crl)); crlGen.addCRLEntry(BigInteger.valueOf(2), now, entryExtensions); crlGen.addExtension(X509Extension.authorityKeyIdentifier, false, new AuthorityKeyIdentifierStructure(pair.getPublic())); crlHolder = crlGen.build(new JcaContentSignerBuilder("SHA256withRSAEncryption").setProvider(BC).build(pair.getPrivate())); int count = 0; boolean oneFound = false; boolean twoFound = false; Iterator it = crlHolder.getRevokedCertificates().iterator(); while (it.hasNext()) { X509CRLEntryHolder crlEnt = (X509CRLEntryHolder)it.next(); if (crlEnt.getSerialNumber().intValue() == 1) { oneFound = true; Extension extn = crlEnt.getExtension(X509Extension.reasonCode); if (extn != null) { ASN1Enumerated reasonCode = (ASN1Enumerated)ASN1Enumerated.getInstance(extn.getParsedValue()); if (reasonCode.getValue().intValue() != CRLReason.privilegeWithdrawn) { fail("CRL entry reasonCode wrong"); } } else { fail("CRL entry reasonCode not found"); } } else if (crlEnt.getSerialNumber().intValue() == 2) { twoFound = true; } count++; } if (count != 2) { fail("wrong number of CRLs found"); } if (!oneFound || !twoFound) { fail("wrong CRLs found in copied list"); } // // check factory read back // CertificateFactory cFact = CertificateFactory.getInstance("X.509", BC); X509CRL readCrl = (X509CRL)cFact.generateCRL(new ByteArrayInputStream(crlHolder.getEncoded())); if (readCrl == null) { fail("crl not returned!"); } Collection col = cFact.generateCRLs(new ByteArrayInputStream(crlHolder.getEncoded())); if (col.size() != 1) { fail("wrong number of CRLs found in collection"); } } public void checkCreation5() throws Exception { // // a sample key pair. // RSAPublicKeySpec pubKeySpec = new RSAPublicKeySpec( new BigInteger("b4a7e46170574f16a97082b22be58b6a2a629798419be12872a4bdba626cfae9900f76abfb12139dce5de56564fab2b6543165a040c606887420e33d91ed7ed7", 16), new BigInteger("11", 16)); RSAPrivateCrtKeySpec privKeySpec = new RSAPrivateCrtKeySpec( new BigInteger("b4a7e46170574f16a97082b22be58b6a2a629798419be12872a4bdba626cfae9900f76abfb12139dce5de56564fab2b6543165a040c606887420e33d91ed7ed7", 16), new BigInteger("11", 16), new BigInteger("9f66f6b05410cd503b2709e88115d55daced94d1a34d4e32bf824d0dde6028ae79c5f07b580f5dce240d7111f7ddb130a7945cd7d957d1920994da389f490c89", 16), new BigInteger("c0a0758cdf14256f78d4708c86becdead1b50ad4ad6c5c703e2168fbf37884cb", 16), new BigInteger("f01734d7960ea60070f1b06f2bb81bfac48ff192ae18451d5e56c734a5aab8a5", 16), new BigInteger("b54bb9edff22051d9ee60f9351a48591b6500a319429c069a3e335a1d6171391", 16), new BigInteger("d3d83daf2a0cecd3367ae6f8ae1aeb82e9ac2f816c6fc483533d8297dd7884cd", 16), new BigInteger("b8f52fc6f38593dabb661d3f50f8897f8106eee68b1bce78a95b132b4e5b5d19", 16)); // // set up the keys // SecureRandom rand = new SecureRandom(); PrivateKey privKey; PublicKey pubKey; KeyFactory fact = KeyFactory.getInstance("RSA", BC); privKey = fact.generatePrivate(privKeySpec); pubKey = fact.generatePublic(pubKeySpec); // // distinguished name table. // Vector ord = new Vector(); Vector values = new Vector(); X500NameBuilder builder = createStdBuilder(); // // create base certificate - version 3 // ContentSigner sigGen = new JcaContentSignerBuilder("MD5WithRSAEncryption").setProvider(BC).build(privKey); X509v3CertificateBuilder certGen = new JcaX509v3CertificateBuilder(builder.build(),BigInteger.valueOf(1),new Date(System.currentTimeMillis() - 50000),new Date(System.currentTimeMillis() + 50000),builder.build(),pubKey) .addExtension(new ASN1ObjectIdentifier("2.5.29.15"), true, new X509KeyUsage(X509KeyUsage.encipherOnly)) .addExtension(new ASN1ObjectIdentifier("2.5.29.37"), true, new DERSequence(KeyPurposeId.anyExtendedKeyUsage)) .addExtension(new ASN1ObjectIdentifier("2.5.29.17"), true, new GeneralNames(new GeneralName(GeneralName.rfc822Name, "test@test.test"))); X509Certificate baseCert = new JcaX509CertificateConverter().setProvider(BC).getCertificate(certGen.build(sigGen)); // // copy certificate // certGen = new JcaX509v3CertificateBuilder(builder.build(),BigInteger.valueOf(1),new Date(System.currentTimeMillis() - 50000),new Date(System.currentTimeMillis() + 50000),builder.build(),pubKey) .copyAndAddExtension(new ASN1ObjectIdentifier("2.5.29.15"), true, baseCert) .copyAndAddExtension(new ASN1ObjectIdentifier("2.5.29.37"), false, baseCert); X509Certificate cert = new JcaX509CertificateConverter().setProvider(BC).getCertificate(certGen.build(sigGen)); cert.checkValidity(new Date()); cert.verify(pubKey); if (!areEqual(baseCert.getExtensionValue("2.5.29.15"), cert.getExtensionValue("2.5.29.15"))) { fail("2.5.29.15 differs"); } if (!areEqual(baseCert.getExtensionValue("2.5.29.37"), cert.getExtensionValue("2.5.29.37"))) { fail("2.5.29.37 differs"); } // // exception test // try { certGen.copyAndAddExtension(new ASN1ObjectIdentifier("2.5.99.99"), true, new JcaX509CertificateHolder(baseCert)); fail("exception not thrown on dud extension copy"); } catch (NullPointerException e) { // expected } // try // { // certGen.setPublicKey(dudPublicKey); // // certGen.generate(privKey, BC); // // fail("key without encoding not detected in v3"); // } // catch (IllegalArgumentException e) // { // // expected // } } private void testForgedSignature() throws Exception { String cert = "MIIBsDCCAVoCAQYwDQYJKoZIhvcNAQEFBQAwYzELMAkGA1UEBhMCQVUxEzARBgNV" + "BAgTClF1ZWVuc2xhbmQxGjAYBgNVBAoTEUNyeXB0U29mdCBQdHkgTHRkMSMwIQYD" + "VQQDExpTZXJ2ZXIgdGVzdCBjZXJ0ICg1MTIgYml0KTAeFw0wNjA5MTEyMzU4NTVa" + "Fw0wNjEwMTEyMzU4NTVaMGMxCzAJBgNVBAYTAkFVMRMwEQYDVQQIEwpRdWVlbnNs" + "YW5kMRowGAYDVQQKExFDcnlwdFNvZnQgUHR5IEx0ZDEjMCEGA1UEAxMaU2VydmVy" + "IHRlc3QgY2VydCAoNTEyIGJpdCkwXDANBgkqhkiG9w0BAQEFAANLADBIAkEAn7PD" + "hCeV/xIxUg8V70YRxK2A5jZbD92A12GN4PxyRQk0/lVmRUNMaJdq/qigpd9feP/u" + "12S4PwTLb/8q/v657QIDAQABMA0GCSqGSIb3DQEBBQUAA0EAbynCRIlUQgaqyNgU" + "DF6P14yRKUtX8akOP2TwStaSiVf/akYqfLFm3UGka5XbPj4rifrZ0/sOoZEEBvHQ" + "e20sRA=="; CertificateFactory certFact = CertificateFactory.getInstance("X.509", BC); X509Certificate x509 = (X509Certificate)certFact.generateCertificate(new ByteArrayInputStream(Base64.decode(cert))); try { x509.verify(x509.getPublicKey()); fail("forged RSA signature passed"); } catch (Exception e) { // expected } } private void pemTest() throws Exception { CertificateFactory cf = CertificateFactory.getInstance("X.509", BC); Certificate cert = readPEMCert(cf, PEMData.CERTIFICATE_1); if (cert == null) { fail("PEM cert not read"); } cert = readPEMCert(cf, "-----BEGIN CERTIFICATE-----" + PEMData.CERTIFICATE_2); if (cert == null) { fail("PEM cert with extraneous header not read"); } CRL crl = cf.generateCRL(new ByteArrayInputStream(PEMData.CRL_1.getBytes("US-ASCII"))); if (crl == null) { fail("PEM crl not read"); } Collection col = cf.generateCertificates(new ByteArrayInputStream(PEMData.CERTIFICATE_2.getBytes("US-ASCII"))); if (col.size() != 1 || !col.contains(cert)) { fail("PEM cert collection not right"); } col = cf.generateCRLs(new ByteArrayInputStream(PEMData.CRL_2.getBytes("US-ASCII"))); if (col.size() != 1 || !col.contains(crl)) { fail("PEM crl collection not right"); } } private static Certificate readPEMCert(CertificateFactory cf, String pemData) throws CertificateException, UnsupportedEncodingException { return cf.generateCertificate(new ByteArrayInputStream(pemData.getBytes("US-ASCII"))); } private void pkcs7Test() throws Exception { /* ASN1EncodableVector certs = new ASN1EncodableVector(); certs.add(new ASN1InputStream(CertPathTest.rootCertBin).readObject()); certs.add(new DERTaggedObject(false, 2, new ASN1InputStream(AttrCertTest.attrCert).readObject())); ASN1EncodableVector crls = new ASN1EncodableVector(); crls.add(new ASN1InputStream(CertPathTest.rootCrlBin).readObject()); SignedData sigData = new SignedData(new DERSet(), new ContentInfo(CMSObjectIdentifiers.data, null), new DERSet(certs), new DERSet(crls), new DERSet()); ContentInfo info = new ContentInfo(CMSObjectIdentifiers.signedData, sigData); CertificateFactory cf = CertificateFactory.getInstance("X.509", BC); X509Certificate cert = (X509Certificate)cf.generateCertificate(new ByteArrayInputStream(info.getEncoded())); if (cert == null || !areEqual(cert.getEncoded(), certs.get(0).getDERObject().getEncoded())) { fail("PKCS7 cert not read"); } X509CRL crl = (X509CRL)cf.generateCRL(new ByteArrayInputStream(info.getEncoded())); if (crl == null || !areEqual(crl.getEncoded(), crls.get(0).getDERObject().getEncoded())) { fail("PKCS7 crl not read"); } Collection col = cf.generateCertificates(new ByteArrayInputStream(info.getEncoded())); if (col.size() != 1 || !col.contains(cert)) { fail("PKCS7 cert collection not right"); } col = cf.generateCRLs(new ByteArrayInputStream(info.getEncoded())); if (col.size() != 1 || !col.contains(crl)) { fail("PKCS7 crl collection not right"); } // data with no certificates or CRLs sigData = new SignedData(new DERSet(), new ContentInfo(CMSObjectIdentifiers.data, null), new DERSet(), new DERSet(), new DERSet()); info = new ContentInfo(CMSObjectIdentifiers.signedData, sigData); cert = (X509Certificate)cf.generateCertificate(new ByteArrayInputStream(info.getEncoded())); if (cert != null) { fail("PKCS7 cert present"); } crl = (X509CRL)cf.generateCRL(new ByteArrayInputStream(info.getEncoded())); if (crl != null) { fail("PKCS7 crl present"); } // data with absent certificates and CRLS sigData = new SignedData(new DERSet(), new ContentInfo(CMSObjectIdentifiers.data, null), null, null, new DERSet()); info = new ContentInfo(CMSObjectIdentifiers.signedData, sigData); cert = (X509Certificate)cf.generateCertificate(new ByteArrayInputStream(info.getEncoded())); if (cert != null) { fail("PKCS7 cert present"); } crl = (X509CRL)cf.generateCRL(new ByteArrayInputStream(info.getEncoded())); if (crl != null) { fail("PKCS7 crl present"); } // // sample message // InputStream in = new ByteArrayInputStream(pkcs7CrlProblem); Collection certCol = cf.generateCertificates(in); Collection crlCol = cf.generateCRLs(in); if (crlCol.size() != 0) { fail("wrong number of CRLs: " + crlCol.size()); } if (certCol.size() != 4) { fail("wrong number of Certs: " + certCol.size()); } */ } private void createPSSCert(String algorithm) throws Exception { KeyPair pair = generateLongFixedKeys(); PrivateKey privKey = pair.getPrivate(); PublicKey pubKey = pair.getPublic(); // // distinguished name table. // X500NameBuilder builder = createStdBuilder(); // // create base certificate - version 3 // ContentSigner sigGen = new JcaContentSignerBuilder(algorithm).setProvider(BC).build(privKey); JcaX509v3CertificateBuilder certGen = new JcaX509v3CertificateBuilder(builder.build(),BigInteger.valueOf(1), new Date(System.currentTimeMillis() - 50000),new Date(System.currentTimeMillis() + 50000),builder.build(),pubKey); certGen.addExtension(new ASN1ObjectIdentifier("2.5.29.15"), true, new X509KeyUsage(X509KeyUsage.encipherOnly)); certGen.addExtension(new ASN1ObjectIdentifier("2.5.29.37"), true, new DERSequence(KeyPurposeId.anyExtendedKeyUsage)); certGen.addExtension(new ASN1ObjectIdentifier("2.5.29.17"), true, new GeneralNames(new GeneralName(GeneralName.rfc822Name, "test@test.test"))); X509Certificate baseCert = new JcaX509CertificateConverter().setProvider(BC).getCertificate(certGen.build(sigGen)); baseCert.verify(pubKey); } private KeyPair generateLongFixedKeys() throws NoSuchAlgorithmException, NoSuchProviderException, InvalidKeySpecException { RSAPublicKeySpec pubKeySpec = new RSAPublicKeySpec( new BigInteger("a56e4a0e701017589a5187dc7ea841d156f2ec0e36ad52a44dfeb1e61f7ad991d8c51056ffedb162b4c0f283a12a88a394dff526ab7291cbb307ceabfce0b1dfd5cd9508096d5b2b8b6df5d671ef6377c0921cb23c270a70e2598e6ff89d19f105acc2d3f0cb35f29280e1386b6f64c4ef22e1e1f20d0ce8cffb2249bd9a2137",16), new BigInteger("010001",16)); RSAPrivateCrtKeySpec privKeySpec = new RSAPrivateCrtKeySpec( new BigInteger("a56e4a0e701017589a5187dc7ea841d156f2ec0e36ad52a44dfeb1e61f7ad991d8c51056ffedb162b4c0f283a12a88a394dff526ab7291cbb307ceabfce0b1dfd5cd9508096d5b2b8b6df5d671ef6377c0921cb23c270a70e2598e6ff89d19f105acc2d3f0cb35f29280e1386b6f64c4ef22e1e1f20d0ce8cffb2249bd9a2137",16), new BigInteger("010001",16), new BigInteger("33a5042a90b27d4f5451ca9bbbd0b44771a101af884340aef9885f2a4bbe92e894a724ac3c568c8f97853ad07c0266c8c6a3ca0929f1e8f11231884429fc4d9ae55fee896a10ce707c3ed7e734e44727a39574501a532683109c2abacaba283c31b4bd2f53c3ee37e352cee34f9e503bd80c0622ad79c6dcee883547c6a3b325",16), new BigInteger("e7e8942720a877517273a356053ea2a1bc0c94aa72d55c6e86296b2dfc967948c0a72cbccca7eacb35706e09a1df55a1535bd9b3cc34160b3b6dcd3eda8e6443",16), new BigInteger("b69dca1cf7d4d7ec81e75b90fcca874abcde123fd2700180aa90479b6e48de8d67ed24f9f19d85ba275874f542cd20dc723e6963364a1f9425452b269a6799fd",16), new BigInteger("28fa13938655be1f8a159cbaca5a72ea190c30089e19cd274a556f36c4f6e19f554b34c077790427bbdd8dd3ede2448328f385d81b30e8e43b2fffa027861979",16), new BigInteger("1a8b38f398fa712049898d7fb79ee0a77668791299cdfa09efc0e507acb21ed74301ef5bfd48be455eaeb6e1678255827580a8e4e8e14151d1510a82a3f2e729",16), new BigInteger("27156aba4126d24a81f3a528cbfb27f56886f840a9f6e86e17a44b94fe9319584b8e22fdde1e5a2e3bd8aa5ba8d8584194eb2190acf832b847f13a3d24a79f4d",16)); KeyFactory fact = KeyFactory.getInstance("RSA", BC); return new KeyPair(fact.generatePublic(pubKeySpec), fact.generatePrivate(privKeySpec)); } private void rfc4491Test() throws Exception { CertificateFactory certFact = CertificateFactory.getInstance("X.509", BC); X509Certificate x509 = (X509Certificate)certFact.generateCertificate(new ByteArrayInputStream(gostRFC4491_94)); x509.verify(x509.getPublicKey(), BC); x509 = (X509Certificate)certFact.generateCertificate(new ByteArrayInputStream(gostRFC4491_2001)); x509.verify(x509.getPublicKey(), BC); } private void testNullDerNullCert() throws Exception { KeyPair pair = generateLongFixedKeys(); PublicKey pubKey = pair.getPublic(); PrivateKey privKey = pair.getPrivate(); ContentSigner sigGen = new JcaContentSignerBuilder("MD5WithRSAEncryption").setProvider(BC).build(privKey); JcaX509v3CertificateBuilder certGen = new JcaX509v3CertificateBuilder(new X500Name("CN=Test"),BigInteger.valueOf(1),new Date(System.currentTimeMillis() - 50000),new Date(System.currentTimeMillis() + 50000),new X500Name("CN=Test"),pubKey); X509Certificate cert = new JcaX509CertificateConverter().setProvider(BC).getCertificate(certGen.build(sigGen)); X509CertificateStructure struct = X509CertificateStructure.getInstance(ASN1Primitive.fromByteArray(cert.getEncoded())); ASN1Encodable tbsCertificate = struct.getTBSCertificate(); AlgorithmIdentifier sig = struct.getSignatureAlgorithm(); ASN1EncodableVector v = new ASN1EncodableVector(); v.add(tbsCertificate); v.add(new AlgorithmIdentifier(sig.getAlgorithm())); v.add(struct.getSignature()); // verify ByteArrayInputStream bIn; String dump = ""; try { bIn = new ByteArrayInputStream(new DERSequence(v).getEncoded()); CertificateFactory fact = CertificateFactory.getInstance("X.509", BC); cert = (X509Certificate)fact.generateCertificate(bIn); cert.verify(cert.getPublicKey()); } catch (Exception e) { fail(dump + System.getProperty("line.separator") + getName() + ": testNullDerNull failed - exception " + e.toString(), e); } } private void testDirect() throws Exception { KeyStore keyStore = KeyStore.getInstance("PKCS12", "BC"); ByteArrayInputStream input = new ByteArrayInputStream(testCAp12); keyStore.load(input, "test".toCharArray()); X509Certificate certificate = (X509Certificate) keyStore.getCertificate("ca"); PrivateKey privateKey = (PrivateKey) keyStore.getKey("ca", null); X500Name issuer = X500Name.getInstance(PrincipalUtil.getIssuerX509Principal(certificate).getEncoded()); X509v2CRLBuilder builder = new X509v2CRLBuilder(issuer, new Date()); builder.addCRLEntry(certificate.getSerialNumber(), new Date(), CRLReason.cACompromise); JcaContentSignerBuilder contentSignerBuilder = new JcaContentSignerBuilder("SHA256WithRSAEncryption"); contentSignerBuilder.setProvider("BC"); X509CRLHolder cRLHolder = builder.build(contentSignerBuilder.build(privateKey)); JcaX509CRLConverter converter = new JcaX509CRLConverter(); converter.setProvider("BC"); X509CRL crl = converter.getCRL(cRLHolder); crl.verify(certificate.getPublicKey()); if (!crl.isRevoked(certificate)) { fail("Certificate should be revoked"); } // now encode the CRL and load the CRL with the JCE provider CertificateFactory fac = CertificateFactory.getInstance("X.509"); X509CRL jceCRL = (X509CRL) fac.generateCRL(new ByteArrayInputStream(crl.getEncoded())); jceCRL.verify(certificate.getPublicKey()); if (!jceCRL.isRevoked(certificate)) { fail("This certificate should also be revoked"); } } private void testIndirect() throws Exception { KeyStore keyStore = KeyStore.getInstance("PKCS12", "BC"); ByteArrayInputStream input = new ByteArrayInputStream(testCAp12); keyStore.load(input, "test".toCharArray()); X509Certificate certificate = (X509Certificate) keyStore.getCertificate("ca"); PrivateKey privateKey = (PrivateKey) keyStore.getKey("ca", null); X500Name crlIssuer = X500Name.getInstance(PrincipalUtil.getSubjectX509Principal(certificate).getEncoded()); X500Name caName = X500Name.getInstance(PrincipalUtil.getIssuerX509Principal(certificate).getEncoded()); X509v2CRLBuilder builder = new X509v2CRLBuilder(crlIssuer, new Date()); builder.addExtension(Extension.issuingDistributionPoint, true, new IssuingDistributionPoint(null, true, false)); ExtensionsGenerator extGen = new ExtensionsGenerator(); extGen.addExtension(Extension.reasonCode, false, CRLReason.lookup(CRLReason.cACompromise)); extGen.addExtension(Extension.certificateIssuer, true, new GeneralNames(new GeneralName(caName))); builder.addCRLEntry(certificate.getSerialNumber(), new Date(), extGen.generate()); JcaContentSignerBuilder contentSignerBuilder = new JcaContentSignerBuilder("SHA256WithRSAEncryption"); contentSignerBuilder.setProvider("BC"); X509CRLHolder cRLHolder = builder.build(contentSignerBuilder.build(privateKey)); JcaX509CRLConverter converter = new JcaX509CRLConverter(); converter.setProvider("BC"); X509CRL crl = converter.getCRL(cRLHolder); crl.verify(certificate.getPublicKey()); if (!crl.isRevoked(certificate)) { fail("Certificate should be revoked"); } // now encode the CRL and load the CRL with the JCE provider CertificateFactory fac = CertificateFactory.getInstance("X.509"); X509CRL jceCRL = (X509CRL) fac.generateCRL(new ByteArrayInputStream(crl.getEncoded())); jceCRL.verify(certificate.getPublicKey()); if (!jceCRL.isRevoked(certificate)) { fail("This certificate should also be revoked"); } } // issuing distribution point must be set for an indirect CRL to be recognised private void testMalformedIndirect() throws Exception { KeyStore keyStore = KeyStore.getInstance("PKCS12", "BC"); ByteArrayInputStream input = new ByteArrayInputStream(testCAp12); keyStore.load(input, "test".toCharArray()); X509Certificate certificate = (X509Certificate) keyStore.getCertificate("ca"); PrivateKey privateKey = (PrivateKey) keyStore.getKey("ca", null); X500Name crlIssuer = X500Name.getInstance(PrincipalUtil.getSubjectX509Principal(certificate).getEncoded()); X500Name caName = X500Name.getInstance(PrincipalUtil.getIssuerX509Principal(certificate).getEncoded()); X509v2CRLBuilder builder = new X509v2CRLBuilder(crlIssuer, new Date()); ExtensionsGenerator extGen = new ExtensionsGenerator(); extGen.addExtension(Extension.reasonCode, false, CRLReason.lookup(CRLReason.cACompromise)); extGen.addExtension(Extension.certificateIssuer, true, new GeneralNames(new GeneralName(caName))); builder.addCRLEntry(certificate.getSerialNumber(), new Date(), extGen.generate()); JcaContentSignerBuilder contentSignerBuilder = new JcaContentSignerBuilder("SHA256WithRSAEncryption"); contentSignerBuilder.setProvider("BC"); X509CRLHolder cRLHolder = builder.build(contentSignerBuilder.build(privateKey)); JcaX509CRLConverter converter = new JcaX509CRLConverter(); converter.setProvider("BC"); X509CRL crl = converter.getCRL(cRLHolder); crl.verify(certificate.getPublicKey()); if (crl.isRevoked(certificate)) { throw new Exception("Certificate should not be revoked"); } } public void performTest() throws Exception { testDirect(); testIndirect(); testMalformedIndirect(); checkCertificate(1, cert1); checkCertificate(2, cert2); checkCertificate(3, cert3); checkCertificate(4, cert4); checkCertificate(5, cert5); checkCertificate(6, oldEcdsa); checkCertificate(7, cert7); checkKeyUsage(8, keyUsage); checkSelfSignedCertificate(9, uncompressedPtEC); checkNameCertificate(10, nameCert); checkSelfSignedCertificate(11, probSelfSignedCert); checkSelfSignedCertificate(12, gostCA1); checkSelfSignedCertificate(13, gostCA2); checkSelfSignedCertificate(14, gost341094base); checkSelfSignedCertificate(15, gost34102001base); checkSelfSignedCertificate(16, gost341094A); checkSelfSignedCertificate(17, gost341094B); checkSelfSignedCertificate(17, gost34102001A); checkCRL(1, crl1); checkCreation1(); checkCreation2(); checkCreation3(); checkCreation5(); createECCert("SHA1withECDSA", X9ObjectIdentifiers.ecdsa_with_SHA1); createECCert("SHA224withECDSA", X9ObjectIdentifiers.ecdsa_with_SHA224); createECCert("SHA256withECDSA", X9ObjectIdentifiers.ecdsa_with_SHA256); createECCert("SHA384withECDSA", X9ObjectIdentifiers.ecdsa_with_SHA384); createECCert("SHA512withECDSA", X9ObjectIdentifiers.ecdsa_with_SHA512); createPSSCert("SHA1withRSAandMGF1"); createPSSCert("SHA224withRSAandMGF1"); createPSSCert("SHA256withRSAandMGF1"); createPSSCert("SHA384withRSAandMGF1"); checkCRLCreation1(); checkCRLCreation2(); checkCRLCreation3(); pemTest(); pkcs7Test(); rfc4491Test(); testForgedSignature(); testNullDerNullCert(); checkCertificate(18, emptyDNCert); } public static void main( String[] args) { Security.addProvider(new BouncyCastleProvider()); runTest(new CertTest()); } } bouncycastle-1.49.orig/jdk1.1/org/bouncycastle/cert/jcajce/0000755000175000017500000000000012152033551023054 5ustar ebourgebourgbouncycastle-1.49.orig/jdk1.1/org/bouncycastle/cert/jcajce/JcaCertStoreBuilder.java0000644000175000017500000001004211731466725027572 0ustar ebourgebourgpackage org.bouncycastle.cert.jcajce; import java.security.GeneralSecurityException; import java.security.Provider; import java.security.NoSuchProviderException; import java.security.NoSuchAlgorithmException; import java.security.cert.CRLException; import java.security.cert.CertStore; import java.security.cert.CertificateException; import java.security.cert.CollectionCertStoreParameters; import java.util.ArrayList; import java.util.Iterator; import java.util.List; import org.bouncycastle.cert.X509CRLHolder; import org.bouncycastle.cert.X509CertificateHolder; import org.bouncycastle.util.Store; /** * Builder to create a CertStore from certificate and CRL stores. */ public class JcaCertStoreBuilder { private List certs = new ArrayList(); private List crls = new ArrayList(); private Object provider; private JcaX509CertificateConverter certificateConverter = new JcaX509CertificateConverter(); private JcaX509CRLConverter crlConverter = new JcaX509CRLConverter(); /** * Add a store full of X509CertificateHolder objects. * * @param certStore a store of X509CertificateHolder objects. */ public JcaCertStoreBuilder addCertificates(Store certStore) { certs.addAll(certStore.getMatches(null)); return this; } /** * Add a single certificate. * * @param cert the X509 certificate holder containing the certificate. */ public JcaCertStoreBuilder addCertificate(X509CertificateHolder cert) { certs.add(cert); return this; } /** * Add a store full of X509CRLHolder objects. * @param crlStore a store of X509CRLHolder objects. */ public JcaCertStoreBuilder addCRLs(Store crlStore) { crls.addAll(crlStore.getMatches(null)); return this; } /** * Add a single CRL. * * @param crl the X509 CRL holder containing the CRL. */ public JcaCertStoreBuilder addCRL(X509CRLHolder crl) { crls.add(crl); return this; } public JcaCertStoreBuilder setProvider(String providerName) throws GeneralSecurityException { certificateConverter.setProvider(providerName); crlConverter.setProvider(providerName); this.provider = providerName; return this; } public JcaCertStoreBuilder setProvider(Provider provider) throws GeneralSecurityException { certificateConverter.setProvider(provider); crlConverter.setProvider(provider); this.provider = provider; return this; } /** * Build the CertStore from the current inputs. * * @return a CertStore. * @throws GeneralSecurityException */ public CertStore build() throws GeneralSecurityException { CollectionCertStoreParameters params = convertHolders(certificateConverter, crlConverter); try { if (provider instanceof String) { return CertStore.getInstance("Collection", params, (String)provider); } if (provider instanceof Provider) { return CertStore.getInstance("Collection", params, (Provider)provider); } return CertStore.getInstance("Collection", params); } catch (NoSuchAlgorithmException e) { throw new GeneralSecurityException(e.toString()); } catch (NoSuchProviderException e) { throw new GeneralSecurityException(e.toString()); } } private CollectionCertStoreParameters convertHolders(JcaX509CertificateConverter certificateConverter, JcaX509CRLConverter crlConverter) throws CertificateException, CRLException { List jcaObjs = new ArrayList(certs.size() + crls.size()); for (Iterator it = certs.iterator(); it.hasNext();) { jcaObjs.add(certificateConverter.getCertificate((X509CertificateHolder)it.next())); } for (Iterator it = crls.iterator(); it.hasNext();) { jcaObjs.add(crlConverter.getCRL((X509CRLHolder)it.next())); } return new CollectionCertStoreParameters(jcaObjs); } } bouncycastle-1.49.orig/jdk1.1/org/bouncycastle/i18n/0000755000175000017500000000000012152033551021457 5ustar ebourgebourgbouncycastle-1.49.orig/jdk1.1/org/bouncycastle/i18n/LocalizedMessage.java0000644000175000017500000003507211705654527025563 0ustar ebourgebourgpackage org.bouncycastle.i18n; import org.bouncycastle.i18n.filter.Filter; import org.bouncycastle.i18n.filter.TrustedInput; import org.bouncycastle.i18n.filter.UntrustedInput; import org.bouncycastle.i18n.filter.UntrustedUrlInput; import java.io.UnsupportedEncodingException; import java.text.DateFormat; import java.text.Format; import java.text.MessageFormat; import java.util.Locale; import java.util.MissingResourceException; import java.util.ResourceBundle; import java.util.TimeZone; public class LocalizedMessage { protected static final int NO_FILTER = 0; protected static final int FILTER = 1; protected static final int FILTER_URL = 2; protected String id; protected String resource; // ISO-8859-1 is the default encoding public static final String DEFAULT_ENCODING = "ISO-8859-1"; protected String encoding = DEFAULT_ENCODING; protected FilteredArguments arguments; protected FilteredArguments extraArgs = null; protected Filter filter = null; protected ClassLoader loader = null; /** * Constructs a new LocalizedMessage using resource as the base name for the * RessourceBundle and id as the message bundle id the resource file. * @param resource base name of the resource file * @param id the id of the corresponding bundle in the resource file * @throws NullPointerException if resource or id is null */ public LocalizedMessage(String resource,String id) throws NullPointerException { if (resource == null || id == null) { throw new NullPointerException(); } this.id = id; this.resource = resource; arguments = new FilteredArguments(); } /** * Constructs a new LocalizedMessage using resource as the base name for the * RessourceBundle and id as the message bundle id the resource file. * @param resource base name of the resource file * @param id the id of the corresponding bundle in the resource file * @param encoding the encoding of the resource file * @throws NullPointerException if resource or id is null * @throws UnsupportedEncodingException if the encoding is not supported */ public LocalizedMessage(String resource,String id, String encoding) throws NullPointerException, UnsupportedEncodingException { if (resource == null || id == null) { throw new NullPointerException(); } this.id = id; this.resource = resource; arguments = new FilteredArguments(); this.encoding = encoding; } /** * Constructs a new LocalizedMessage using resource as the base name for the * RessourceBundle and id as the message bundle id the resource file. * @param resource base name of the resource file * @param id the id of the corresponding bundle in the resource file * @param arguments an array containing the arguments for the message * @throws NullPointerException if resource or id is null */ public LocalizedMessage(String resource, String id, Object[] arguments) throws NullPointerException { if (resource == null || id == null || arguments == null) { throw new NullPointerException(); } this.id = id; this.resource = resource; this.arguments = new FilteredArguments(arguments); } /** * Constructs a new LocalizedMessage using resource as the base name for the * RessourceBundle and id as the message bundle id the resource file. * @param resource base name of the resource file * @param id the id of the corresponding bundle in the resource file * @param encoding the encoding of the resource file * @param arguments an array containing the arguments for the message * @throws NullPointerException if resource or id is null * @throws UnsupportedEncodingException if the encoding is not supported */ public LocalizedMessage(String resource, String id, String encoding, Object[] arguments) throws NullPointerException, UnsupportedEncodingException { if (resource == null || id == null || arguments == null) { throw new NullPointerException(); } this.id = id; this.resource = resource; this.arguments = new FilteredArguments(arguments); this.encoding = encoding; } /** * Reads the entry id + "." + key from the resource file and returns a * formated message for the given Locale and TimeZone. * @param key second part of the entry id * @param loc the used {@link Locale} * @param timezone the used {@link TimeZone} * @return a Strng containing the localized message * @throws MissingEntryException if the resource file is not available or the entry does not exist. */ public String getEntry(String key,Locale loc, TimeZone timezone) throws MissingEntryException { String entry = id; if (key != null) { entry += "." + key; } try { ResourceBundle bundle; if (loader == null) { bundle = ResourceBundle.getBundle(resource,loc); } else { bundle = ResourceBundle.getBundle(resource, loc); } String result = bundle.getString(entry); if (!encoding.equals(DEFAULT_ENCODING)) { result = new String(result.getBytes(DEFAULT_ENCODING), encoding); } if (!arguments.isEmpty()) { result = formatWithTimeZone(result,arguments.getFilteredArgs(loc),loc,timezone); } result = addExtraArgs(result, loc); return result; } catch (MissingResourceException mre) { throw new MissingEntryException("Can't find entry " + entry + " in resource file " + resource + ".", resource, entry, loc, loader != null ? loader : this.getClassLoader()); } catch (UnsupportedEncodingException use) { // should never occur - cause we already test this in the constructor throw new RuntimeException(use.toString()); } } protected String formatWithTimeZone( String template, Object[] arguments, Locale locale, TimeZone timezone) { MessageFormat mf = new MessageFormat(" "); mf.setLocale(locale); mf.applyPattern(template); if (!timezone.equals(TimeZone.getDefault())) { Format[] formats = mf.getFormats(); for (int i = 0; i < formats.length; i++) { if (formats[i] instanceof DateFormat) { DateFormat temp = (DateFormat) formats[i]; temp.setTimeZone(timezone); mf.setFormat(i,temp); } } } return mf.format(arguments); } protected String addExtraArgs(String msg, Locale locale) { if (extraArgs != null) { StringBuffer sb = new StringBuffer(msg); Object[] filteredArgs = extraArgs.getFilteredArgs(locale); for (int i = 0; i < filteredArgs.length; i++) { sb.append(filteredArgs[i]); } msg = sb.toString(); } return msg; } /** * Sets the {@link Filter} that is used to filter the arguments of this message * @param filter the {@link Filter} to use. null to disable filtering. */ public void setFilter(Filter filter) { arguments.setFilter(filter); if (extraArgs != null) { extraArgs.setFilter(filter); } this.filter = filter; } /** * Returns the current filter. * @return the current filter */ public Filter getFilter() { return filter; } /** * Set the {@link ClassLoader} which loads the resource files. If it is set to null * then the default {@link ClassLoader} is used. * @param loader the {@link ClassLoader} which loads the resource files */ public void setClassLoader(ClassLoader loader) { this.loader = loader; } /** * Returns the {@link ClassLoader} which loads the resource files or null * if the default ClassLoader is used. * @return the {@link ClassLoader} which loads the resource files */ public ClassLoader getClassLoader() { return loader; } /** * Returns the id of the message in the resource bundle. * @return the id of the message */ public String getId() { return id; } /** * Returns the name of the resource bundle for this message * @return name of the resource file */ public String getResource() { return resource; } /** * Returns an Object[] containing the message arguments. * @return the message arguments */ public Object[] getArguments() { return arguments.getArguments(); } /** * * @param extraArg */ public void setExtraArgument(Object extraArg) { setExtraArguments(new Object[] {extraArg}); } /** * * @param extraArgs */ public void setExtraArguments(Object[] extraArgs) { if (extraArgs != null) { this.extraArgs = new FilteredArguments(extraArgs); this.extraArgs.setFilter(filter); } else { this.extraArgs = null; } } /** * * @return */ public Object[] getExtraArgs() { return (extraArgs == null) ? null : extraArgs.getArguments(); } protected class FilteredArguments { protected Filter filter = null; protected boolean[] isLocaleSpecific; protected int[] argFilterType; protected Object[] arguments; protected Object[] unpackedArgs; protected Object[] filteredArgs; FilteredArguments() { this(new Object[0]); } FilteredArguments(Object[] args) { this.arguments = args; this.unpackedArgs = new Object[args.length]; this.filteredArgs = new Object[args.length]; this.isLocaleSpecific = new boolean[args.length]; this.argFilterType = new int[args.length]; for (int i = 0; i < args.length; i++) { if (args[i] instanceof TrustedInput) { this.unpackedArgs[i] = ((TrustedInput) args[i]).getInput(); argFilterType[i] = NO_FILTER; } else if (args[i] instanceof UntrustedInput) { this.unpackedArgs[i] = ((UntrustedInput) args[i]).getInput(); if (args[i] instanceof UntrustedUrlInput) { argFilterType[i] = FILTER_URL; } else { argFilterType[i] = FILTER; } } else { this.unpackedArgs[i] = args[i]; argFilterType[i] = FILTER; } // locale specific this.isLocaleSpecific[i] = (this.unpackedArgs[i] instanceof LocaleString); } } public boolean isEmpty() { return unpackedArgs.length == 0; } public Object[] getArguments() { return arguments; } public Object[] getFilteredArgs(Locale locale) { Object[] result = new Object[unpackedArgs.length]; for (int i = 0; i < unpackedArgs.length; i++) { Object arg; if (filteredArgs[i] != null) { arg = filteredArgs[i]; } else { arg = unpackedArgs[i]; if (isLocaleSpecific[i]) { // get locale arg = ((LocaleString) arg).getLocaleString(locale); arg = filter(argFilterType[i], arg); } else { arg = filter(argFilterType[i], arg); filteredArgs[i] = arg; } } result[i] = arg; } return result; } private Object filter(int type, Object obj) { if (filter != null) { Object o = (null == obj) ? "null" : obj; switch (type) { case NO_FILTER: return o; case FILTER: return filter.doFilter(o.toString()); case FILTER_URL: return filter.doFilterUrl(o.toString()); default: return null; } } else { return obj; } } public Filter getFilter() { return filter; } public void setFilter(Filter filter) { if (filter != this.filter) { for (int i = 0; i < unpackedArgs.length; i++) { filteredArgs[i] = null; } } this.filter = filter; } } public String toString() { StringBuffer sb = new StringBuffer(); sb.append("Resource: \"").append(resource); sb.append("\" Id: \"").append(id).append("\""); sb.append(" Arguments: ").append(arguments.getArguments().length).append(" normal, ") .append(extraArgs.getArguments().length).append(" extra"); sb.append(" Encoding: ").append(encoding); sb.append(" ClassLoader: ").append(loader); return sb.toString(); } } bouncycastle-1.49.orig/jdk1.1/org/bouncycastle/i18n/MissingEntryException.java0000644000175000017500000000261411705654527026656 0ustar ebourgebourgpackage org.bouncycastle.i18n; import java.net.URL; import java.util.Locale; public class MissingEntryException extends RuntimeException { protected final String resource; protected final String key; protected final ClassLoader loader; protected final Locale locale; private String debugMsg; public MissingEntryException(String message, String resource, String key, Locale locale, ClassLoader loader) { super(message); this.resource = resource; this.key = key; this.locale = locale; this.loader = loader; } public MissingEntryException(String message, Throwable cause, String resource, String key, Locale locale, ClassLoader loader) { super(message + ": " + cause); this.resource = resource; this.key = key; this.locale = locale; this.loader = loader; } public String getKey() { return key; } public String getResource() { return resource; } public ClassLoader getClassLoader() { return loader; } public Locale getLocale() { return locale; } public String getDebugMsg() { if (debugMsg == null) { debugMsg = "Can not find entry " + key + " in resource file " + resource + " for the locale " + locale + "."; } return debugMsg; } } bouncycastle-1.49.orig/jdk1.1/org/bouncycastle/ocsp/0000755000175000017500000000000012152033551021644 5ustar ebourgebourgbouncycastle-1.49.orig/jdk1.1/org/bouncycastle/ocsp/OCSPUtil.java0000644000175000017500000002144711705654530024132 0ustar ebourgebourgpackage org.bouncycastle.ocsp; import org.bouncycastle.asn1.DERNull; import org.bouncycastle.asn1.DERObjectIdentifier; import org.bouncycastle.asn1.cryptopro.CryptoProObjectIdentifiers; import org.bouncycastle.asn1.nist.NISTObjectIdentifiers; import org.bouncycastle.asn1.pkcs.PKCSObjectIdentifiers; import org.bouncycastle.asn1.teletrust.TeleTrusTObjectIdentifiers; import org.bouncycastle.asn1.x509.AlgorithmIdentifier; import org.bouncycastle.asn1.x9.X9ObjectIdentifiers; import org.bouncycastle.util.Strings; import java.security.InvalidAlgorithmParameterException; import java.security.MessageDigest; import java.security.NoSuchAlgorithmException; import java.security.NoSuchProviderException; import java.security.Signature; import java.security.cert.CertStore; import java.security.cert.CertStoreParameters; import java.security.cert.CertificateException; import java.security.cert.CertificateFactory; import java.util.ArrayList; import java.util.Enumeration; import java.util.HashSet; import java.util.Hashtable; import java.util.Iterator; import java.util.List; import java.util.Set; class OCSPUtil { private static Hashtable algorithms = new Hashtable(); private static Hashtable oids = new Hashtable(); private static Set noParams = new HashSet(); static { algorithms.put("MD2WITHRSAENCRYPTION", PKCSObjectIdentifiers.md2WithRSAEncryption); algorithms.put("MD2WITHRSA", PKCSObjectIdentifiers.md2WithRSAEncryption); algorithms.put("MD5WITHRSAENCRYPTION", PKCSObjectIdentifiers.md5WithRSAEncryption); algorithms.put("MD5WITHRSA", PKCSObjectIdentifiers.md5WithRSAEncryption); algorithms.put("SHA1WITHRSAENCRYPTION", PKCSObjectIdentifiers.sha1WithRSAEncryption); algorithms.put("SHA1WITHRSA", PKCSObjectIdentifiers.sha1WithRSAEncryption); algorithms.put("SHA224WITHRSAENCRYPTION", PKCSObjectIdentifiers.sha224WithRSAEncryption); algorithms.put("SHA224WITHRSA", PKCSObjectIdentifiers.sha224WithRSAEncryption); algorithms.put("SHA256WITHRSAENCRYPTION", PKCSObjectIdentifiers.sha256WithRSAEncryption); algorithms.put("SHA256WITHRSA", PKCSObjectIdentifiers.sha256WithRSAEncryption); algorithms.put("SHA384WITHRSAENCRYPTION", PKCSObjectIdentifiers.sha384WithRSAEncryption); algorithms.put("SHA384WITHRSA", PKCSObjectIdentifiers.sha384WithRSAEncryption); algorithms.put("SHA512WITHRSAENCRYPTION", PKCSObjectIdentifiers.sha512WithRSAEncryption); algorithms.put("SHA512WITHRSA", PKCSObjectIdentifiers.sha512WithRSAEncryption); algorithms.put("RIPEMD160WITHRSAENCRYPTION", TeleTrusTObjectIdentifiers.rsaSignatureWithripemd160); algorithms.put("RIPEMD160WITHRSA", TeleTrusTObjectIdentifiers.rsaSignatureWithripemd160); algorithms.put("RIPEMD128WITHRSAENCRYPTION", TeleTrusTObjectIdentifiers.rsaSignatureWithripemd128); algorithms.put("RIPEMD128WITHRSA", TeleTrusTObjectIdentifiers.rsaSignatureWithripemd128); algorithms.put("RIPEMD256WITHRSAENCRYPTION", TeleTrusTObjectIdentifiers.rsaSignatureWithripemd256); algorithms.put("RIPEMD256WITHRSA", TeleTrusTObjectIdentifiers.rsaSignatureWithripemd256); algorithms.put("SHA1WITHDSA", X9ObjectIdentifiers.id_dsa_with_sha1); algorithms.put("DSAWITHSHA1", X9ObjectIdentifiers.id_dsa_with_sha1); algorithms.put("SHA224WITHDSA", NISTObjectIdentifiers.dsa_with_sha224); algorithms.put("SHA256WITHDSA", NISTObjectIdentifiers.dsa_with_sha256); algorithms.put("SHA1WITHECDSA", X9ObjectIdentifiers.ecdsa_with_SHA1); algorithms.put("ECDSAWITHSHA1", X9ObjectIdentifiers.ecdsa_with_SHA1); algorithms.put("SHA224WITHECDSA", X9ObjectIdentifiers.ecdsa_with_SHA224); algorithms.put("SHA256WITHECDSA", X9ObjectIdentifiers.ecdsa_with_SHA256); algorithms.put("SHA384WITHECDSA", X9ObjectIdentifiers.ecdsa_with_SHA384); algorithms.put("SHA512WITHECDSA", X9ObjectIdentifiers.ecdsa_with_SHA512); algorithms.put("GOST3411WITHGOST3410", CryptoProObjectIdentifiers.gostR3411_94_with_gostR3410_94); algorithms.put("GOST3411WITHGOST3410-94", CryptoProObjectIdentifiers.gostR3411_94_with_gostR3410_94); oids.put(PKCSObjectIdentifiers.md2WithRSAEncryption, "MD2WITHRSA"); oids.put(PKCSObjectIdentifiers.md5WithRSAEncryption, "MD5WITHRSA"); oids.put(PKCSObjectIdentifiers.sha1WithRSAEncryption, "SHA1WITHRSA"); oids.put(PKCSObjectIdentifiers.sha224WithRSAEncryption, "SHA224WITHRSA"); oids.put(PKCSObjectIdentifiers.sha256WithRSAEncryption, "SHA256WITHRSA"); oids.put(PKCSObjectIdentifiers.sha384WithRSAEncryption, "SHA384WITHRSA"); oids.put(PKCSObjectIdentifiers.sha512WithRSAEncryption, "SHA512WITHRSA"); oids.put(TeleTrusTObjectIdentifiers.rsaSignatureWithripemd160, "RIPEMD160WITHRSA"); oids.put(TeleTrusTObjectIdentifiers.rsaSignatureWithripemd128, "RIPEMD128WITHRSA"); oids.put(TeleTrusTObjectIdentifiers.rsaSignatureWithripemd256, "RIPEMD256WITHRSA"); oids.put(X9ObjectIdentifiers.id_dsa_with_sha1, "SHA1WITHDSA"); oids.put(NISTObjectIdentifiers.dsa_with_sha224, "SHA224WITHDSA"); oids.put(NISTObjectIdentifiers.dsa_with_sha256, "SHA256WITHDSA"); oids.put(X9ObjectIdentifiers.ecdsa_with_SHA1, "SHA1WITHECDSA"); oids.put(X9ObjectIdentifiers.ecdsa_with_SHA224, "SHA224WITHECDSA"); oids.put(X9ObjectIdentifiers.ecdsa_with_SHA256, "SHA256WITHECDSA"); oids.put(X9ObjectIdentifiers.ecdsa_with_SHA384, "SHA384WITHECDSA"); oids.put(X9ObjectIdentifiers.ecdsa_with_SHA512, "SHA512WITHECDSA"); oids.put(CryptoProObjectIdentifiers.gostR3411_94_with_gostR3410_94, "GOST3411WITHGOST3410"); // // According to RFC 3279, the ASN.1 encoding SHALL (id-dsa-with-sha1) or MUST (ecdsa-with-SHA*) omit the parameters field. // The parameters field SHALL be NULL for RSA based signature algorithms. // noParams.add(X9ObjectIdentifiers.ecdsa_with_SHA1); noParams.add(X9ObjectIdentifiers.ecdsa_with_SHA224); noParams.add(X9ObjectIdentifiers.ecdsa_with_SHA256); noParams.add(X9ObjectIdentifiers.ecdsa_with_SHA384); noParams.add(X9ObjectIdentifiers.ecdsa_with_SHA512); noParams.add(X9ObjectIdentifiers.id_dsa_with_sha1); noParams.add(NISTObjectIdentifiers.dsa_with_sha224); noParams.add(NISTObjectIdentifiers.dsa_with_sha256); } static DERObjectIdentifier getAlgorithmOID( String algorithmName) { algorithmName = Strings.toUpperCase(algorithmName); if (algorithms.containsKey(algorithmName)) { return (DERObjectIdentifier)algorithms.get(algorithmName); } return new DERObjectIdentifier(algorithmName); } static String getAlgorithmName( DERObjectIdentifier oid) { if (oids.containsKey(oid)) { return (String)oids.get(oid); } return oid.getId(); } static AlgorithmIdentifier getSigAlgID( DERObjectIdentifier sigOid) { if (noParams.contains(sigOid)) { return new AlgorithmIdentifier(sigOid); } else { return new AlgorithmIdentifier(sigOid, new DERNull()); } } static Iterator getAlgNames() { Enumeration e = algorithms.keys(); List l = new ArrayList(); while (e.hasMoreElements()) { l.add(e.nextElement()); } return l.iterator(); } static CertStore createCertStoreInstance(String type, CertStoreParameters params, String provider) throws InvalidAlgorithmParameterException, NoSuchAlgorithmException, NoSuchProviderException { if (provider == null) { return CertStore.getInstance(type, params); } return CertStore.getInstance(type, params, provider); } static MessageDigest createDigestInstance(String digestName, String provider) throws NoSuchAlgorithmException, NoSuchProviderException { if (provider == null) { return MessageDigest.getInstance(digestName); } return MessageDigest.getInstance(digestName, provider); } static Signature createSignatureInstance(String sigName, String provider) throws NoSuchAlgorithmException, NoSuchProviderException { if (provider == null) { return Signature.getInstance(sigName); } return Signature.getInstance(sigName, provider); } static CertificateFactory createX509CertificateFactory(String provider) throws CertificateException, NoSuchProviderException { if (provider == null) { return CertificateFactory.getInstance("X.509"); } return CertificateFactory.getInstance("X.509", provider); } } bouncycastle-1.49.orig/jdk1.1/org/bouncycastle/cms/0000755000175000017500000000000012152033551021462 5ustar ebourgebourgbouncycastle-1.49.orig/jdk1.1/org/bouncycastle/cms/CMSAuthenticatedDataStreamGenerator.java0000644000175000017500000003142711731466725031315 0ustar ebourgebourgpackage org.bouncycastle.cms; import java.io.IOException; import java.io.OutputStream; import java.security.NoSuchAlgorithmException; import java.security.NoSuchProviderException; import java.security.Provider; import java.security.SecureRandom; import java.util.Collections; import java.util.HashMap; import java.util.Iterator; import java.util.Map; import org.bouncycastle.asn1.ASN1EncodableVector; import org.bouncycastle.asn1.ASN1Encoding; import org.bouncycastle.asn1.ASN1ObjectIdentifier; import org.bouncycastle.asn1.ASN1Set; import org.bouncycastle.asn1.BERSequenceGenerator; import org.bouncycastle.asn1.BERSet; import org.bouncycastle.asn1.DERInteger; import org.bouncycastle.asn1.DEROctetString; import org.bouncycastle.asn1.DERSet; import org.bouncycastle.asn1.DERTaggedObject; import org.bouncycastle.asn1.cms.AuthenticatedData; import org.bouncycastle.asn1.cms.CMSObjectIdentifiers; import org.bouncycastle.asn1.x509.AlgorithmIdentifier; import org.bouncycastle.cms.jcajce.JceCMSMacCalculatorBuilder; import org.bouncycastle.operator.DigestCalculator; import org.bouncycastle.operator.MacCalculator; import org.bouncycastle.util.io.TeeOutputStream; /** * General class for generating a CMS authenticated-data message stream. *

    * A simple example of usage. *

     *      CMSAuthenticatedDataStreamGenerator edGen = new CMSAuthenticatedDataStreamGenerator();
     *
     *      edGen.addRecipientInfoGenerator(new JceKeyTransRecipientInfoGenerator(cert).setProvider("BC"));
     *
     *      ByteArrayOutputStream  bOut = new ByteArrayOutputStream();
     *
     *      OutputStream out = edGen.open(
     *                              bOut, new JceCMSMacCalculatorBuilder(CMSAlgorithm.DES_EDE3_CBC).setProvider("BC").build());*
     *      out.write(data);
     *
     *      out.close();
     * 
    */ public class CMSAuthenticatedDataStreamGenerator extends CMSAuthenticatedGenerator { // Currently not handled // private Object _originatorInfo = null; // private Object _unprotectedAttributes = null; private int bufferSize; private boolean berEncodeRecipientSet; private MacCalculator macCalculator; /** * base constructor */ public CMSAuthenticatedDataStreamGenerator() { } /** * Set the underlying string size for encapsulated data * * @param bufferSize length of octet strings to buffer the data. */ public void setBufferSize( int bufferSize) { this.bufferSize = bufferSize; } /** * Use a BER Set to store the recipient information. By default recipients are * stored in a DER encoding. * * @param useBerEncodingForRecipients true if a BER set should be used, false if DER. */ public void setBEREncodeRecipients( boolean useBerEncodingForRecipients) { berEncodeRecipientSet = useBerEncodingForRecipients; } /** * generate an authenticated data structure with the encapsulated bytes marked as DATA. * * @param out the stream to store the authenticated structure in. * @param macCalculator calculator for the MAC to be attached to the data. */ public OutputStream open( OutputStream out, MacCalculator macCalculator) throws CMSException { return open(CMSObjectIdentifiers.data, out, macCalculator); } public OutputStream open( OutputStream out, MacCalculator macCalculator, DigestCalculator digestCalculator) throws CMSException { return open(CMSObjectIdentifiers.data, out, macCalculator, digestCalculator); } /** * generate an authenticated data structure with the encapsulated bytes marked as type dataType. * * @param dataType the type of the data been written to the object. * @param out the stream to store the authenticated structure in. * @param macCalculator calculator for the MAC to be attached to the data. */ public OutputStream open( ASN1ObjectIdentifier dataType, OutputStream out, MacCalculator macCalculator) throws CMSException { return open(dataType, out, macCalculator, null); } /** * generate an authenticated data structure with the encapsulated bytes marked as type dataType. * * @param dataType the type of the data been written to the object. * @param out the stream to store the authenticated structure in. * @param macCalculator calculator for the MAC to be attached to the data. * @param digestCalculator calculator for computing digest of the encapsulated data. */ public OutputStream open( ASN1ObjectIdentifier dataType, OutputStream out, MacCalculator macCalculator, DigestCalculator digestCalculator) throws CMSException { this.macCalculator = macCalculator; try { ASN1EncodableVector recipientInfos = new ASN1EncodableVector(); for (Iterator it = recipientInfoGenerators.iterator(); it.hasNext();) { RecipientInfoGenerator recipient = (RecipientInfoGenerator)it.next(); recipientInfos.add(recipient.generate(macCalculator.getKey())); } // // ContentInfo // BERSequenceGenerator cGen = new BERSequenceGenerator(out); cGen.addObject(CMSObjectIdentifiers.authenticatedData); // // Authenticated Data // BERSequenceGenerator authGen = new BERSequenceGenerator(cGen.getRawOutputStream(), 0, true); authGen.addObject(new DERInteger(AuthenticatedData.calculateVersion(originatorInfo))); if (originatorInfo != null) { authGen.addObject(new DERTaggedObject(false, 0, originatorInfo)); } if (berEncodeRecipientSet) { authGen.getRawOutputStream().write(new BERSet(recipientInfos).getEncoded()); } else { authGen.getRawOutputStream().write(new DERSet(recipientInfos).getEncoded()); } AlgorithmIdentifier macAlgId = macCalculator.getAlgorithmIdentifier(); authGen.getRawOutputStream().write(macAlgId.getEncoded()); if (digestCalculator != null) { authGen.addObject(new DERTaggedObject(false, 1, digestCalculator.getAlgorithmIdentifier())); } BERSequenceGenerator eiGen = new BERSequenceGenerator(authGen.getRawOutputStream()); eiGen.addObject(dataType); OutputStream octetStream = CMSUtils.createBEROctetOutputStream( eiGen.getRawOutputStream(), 0, false, bufferSize); OutputStream mOut; if (digestCalculator != null) { mOut = new TeeOutputStream(octetStream, digestCalculator.getOutputStream()); } else { mOut = new TeeOutputStream(octetStream, macCalculator.getOutputStream()); } return new CmsAuthenticatedDataOutputStream(macCalculator, digestCalculator, dataType, mOut, cGen, authGen, eiGen); } catch (IOException e) { throw new CMSException("exception decoding algorithm parameters.", e); } } private class CmsAuthenticatedDataOutputStream extends OutputStream { private OutputStream dataStream; private BERSequenceGenerator cGen; private BERSequenceGenerator envGen; private BERSequenceGenerator eiGen; private MacCalculator macCalculator; private DigestCalculator digestCalculator; private ASN1ObjectIdentifier contentType; public CmsAuthenticatedDataOutputStream( MacCalculator macCalculator, DigestCalculator digestCalculator, ASN1ObjectIdentifier contentType, OutputStream dataStream, BERSequenceGenerator cGen, BERSequenceGenerator envGen, BERSequenceGenerator eiGen) { this.macCalculator = macCalculator; this.digestCalculator = digestCalculator; this.contentType = contentType; this.dataStream = dataStream; this.cGen = cGen; this.envGen = envGen; this.eiGen = eiGen; } public void write( int b) throws IOException { dataStream.write(b); } public void write( byte[] bytes, int off, int len) throws IOException { dataStream.write(bytes, off, len); } public void write( byte[] bytes) throws IOException { dataStream.write(bytes); } public void close() throws IOException { dataStream.close(); eiGen.close(); Map parameters; if (digestCalculator != null) { parameters = getBaseParameters(contentType, digestCalculator.getAlgorithmIdentifier(), digestCalculator.getDigest()); if (authGen == null) { authGen = new DefaultAuthenticatedAttributeTableGenerator(); } ASN1Set authed = new DERSet(authGen.getAttributes(parameters).toASN1EncodableVector()); OutputStream mOut = macCalculator.getOutputStream(); mOut.write(authed.getEncoded(ASN1Encoding.DER)); mOut.close(); envGen.addObject(new DERTaggedObject(false, 2, authed)); } else { parameters = new HashMap(); } envGen.addObject(new DEROctetString(macCalculator.getMac())); if (unauthGen != null) { envGen.addObject(new DERTaggedObject(false, 3, new BERSet(unauthGen.getAttributes(parameters).toASN1EncodableVector()))); } envGen.close(); cGen.close(); } } /** * constructor allowing specific source of randomness * @param rand instance of SecureRandom to use * @deprecated no longer of any use, use basic constructor. */ public CMSAuthenticatedDataStreamGenerator( SecureRandom rand) { super(rand); } /** * generate an authenticated object that contains an CMS Authenticated Data * object using the given provider. * @throws java.io.IOException * @deprecated use open(out, MacCalculator) */ public OutputStream open( OutputStream out, String encryptionOID, String provider) throws NoSuchAlgorithmException, NoSuchProviderException, CMSException, IOException { convertOldRecipients(rand, CMSUtils.getProvider(provider)); return open(out, new JceCMSMacCalculatorBuilder(new ASN1ObjectIdentifier(encryptionOID)).setSecureRandom(rand).setProvider(provider).build()); } /** * @deprecated use open(out, MacCalculator) */ public OutputStream open( OutputStream out, String encryptionOID, Provider provider) throws NoSuchAlgorithmException, CMSException, IOException { convertOldRecipients(rand, provider); return open(out, new JceCMSMacCalculatorBuilder(new ASN1ObjectIdentifier(encryptionOID)).setSecureRandom(rand).setProvider(provider).build()); } /** * generate an enveloped object that contains an CMS Enveloped Data * object using the given provider. * @deprecated use open(out, MacCalculator) */ public OutputStream open( OutputStream out, String encryptionOID, int keySize, String provider) throws NoSuchAlgorithmException, NoSuchProviderException, CMSException, IOException { convertOldRecipients(rand, CMSUtils.getProvider(provider)); return open(out, new JceCMSMacCalculatorBuilder(new ASN1ObjectIdentifier(encryptionOID), keySize).setSecureRandom(rand).setProvider(provider).build()); } /** * generate an enveloped object that contains an CMS Enveloped Data * object using the given provider. * @deprecated use open(out, MacCalculator) */ public OutputStream open( OutputStream out, String encryptionOID, int keySize, Provider provider) throws NoSuchAlgorithmException, CMSException, IOException { convertOldRecipients(rand, provider); return open(out, new JceCMSMacCalculatorBuilder(new ASN1ObjectIdentifier(encryptionOID), keySize).setSecureRandom(rand).setProvider(provider).build()); } } bouncycastle-1.49.orig/jdk1.1/org/bouncycastle/cms/CMSAuthenticatedDataGenerator.java0000644000175000017500000002266711731466725030147 0ustar ebourgebourgpackage org.bouncycastle.cms; import java.io.ByteArrayOutputStream; import java.io.IOException; import java.io.OutputStream; import java.security.NoSuchAlgorithmException; import java.security.NoSuchProviderException; import java.security.Provider; import java.security.SecureRandom; import java.util.Collections; import java.util.HashMap; import java.util.Iterator; import java.util.Map; import javax.crypto.KeyGenerator; import org.bouncycastle.asn1.ASN1EncodableVector; import org.bouncycastle.asn1.ASN1Encoding; import org.bouncycastle.asn1.ASN1ObjectIdentifier; import org.bouncycastle.asn1.ASN1OctetString; import org.bouncycastle.asn1.ASN1Set; import org.bouncycastle.asn1.BEROctetString; import org.bouncycastle.asn1.BERSet; import org.bouncycastle.asn1.DEROctetString; import org.bouncycastle.asn1.DERSet; import org.bouncycastle.asn1.cms.AuthenticatedData; import org.bouncycastle.asn1.cms.CMSObjectIdentifiers; import org.bouncycastle.asn1.cms.ContentInfo; import org.bouncycastle.asn1.x509.AlgorithmIdentifier; import org.bouncycastle.cms.jcajce.JceCMSMacCalculatorBuilder; import org.bouncycastle.operator.DigestCalculator; import org.bouncycastle.operator.DigestCalculatorProvider; import org.bouncycastle.operator.MacCalculator; import org.bouncycastle.operator.OperatorCreationException; import org.bouncycastle.util.io.TeeOutputStream; /** * General class for generating a CMS authenticated-data message. * * A simple example of usage. * *
     *      CMSAuthenticatedDataGenerator  fact = new CMSAuthenticatedDataGenerator();
     *
     *      adGen.addRecipientInfoGenerator(new JceKeyTransRecipientInfoGenerator(recipientCert).setProvider("BC"));
     *
     *      CMSAuthenticatedData         data = fact.generate(new CMSProcessableByteArray(data),
     *                              new JceCMSMacCalculatorBuilder(CMSAlgorithm.DES_EDE3_CBC).setProvider(BC).build()));
     * 
    */ public class CMSAuthenticatedDataGenerator extends CMSAuthenticatedGenerator { /** * base constructor */ public CMSAuthenticatedDataGenerator() { } /** * Generate an authenticated data object from the passed in typedData and MacCalculator. * * @param typedData the data to have a MAC attached. * @param macCalculator the calculator of the MAC to be attached. * @return the resulting CMSAuthenticatedData object. * @throws CMSException on failure in encoding data or processing recipients. */ public CMSAuthenticatedData generate(CMSTypedData typedData, MacCalculator macCalculator) throws CMSException { return generate(typedData, macCalculator, null); } /** * Generate an authenticated data object from the passed in typedData and MacCalculator. * * @param typedData the data to have a MAC attached. * @param macCalculator the calculator of the MAC to be attached. * @param digestCalculator calculator for computing digest of the encapsulated data. * @return the resulting CMSAuthenticatedData object. * @throws CMSException on failure in encoding data or processing recipients. */ public CMSAuthenticatedData generate(CMSTypedData typedData, MacCalculator macCalculator, final DigestCalculator digestCalculator) throws CMSException { ASN1EncodableVector recipientInfos = new ASN1EncodableVector(); ASN1OctetString encContent; ASN1OctetString macResult; for (Iterator it = recipientInfoGenerators.iterator(); it.hasNext();) { RecipientInfoGenerator recipient = (RecipientInfoGenerator)it.next(); recipientInfos.add(recipient.generate(macCalculator.getKey())); } AuthenticatedData authData; if (digestCalculator != null) { try { ByteArrayOutputStream bOut = new ByteArrayOutputStream(); OutputStream out = new TeeOutputStream(digestCalculator.getOutputStream(), bOut); typedData.write(out); out.close(); encContent = new BEROctetString(bOut.toByteArray()); } catch (IOException e) { throw new CMSException("unable to perform digest calculation: " + e.getMessage(), e); } Map parameters = getBaseParameters(typedData.getContentType(), digestCalculator.getAlgorithmIdentifier(), digestCalculator.getDigest()); if (authGen == null) { authGen = new DefaultAuthenticatedAttributeTableGenerator(); } ASN1Set authed = new DERSet(authGen.getAttributes(parameters).toASN1EncodableVector()); try { OutputStream mOut = macCalculator.getOutputStream(); mOut.write(authed.getEncoded(ASN1Encoding.DER)); mOut.close(); macResult = new DEROctetString(macCalculator.getMac()); } catch (IOException e) { throw new CMSException("exception decoding algorithm parameters.", e); } ASN1Set unauthed = (unauthGen != null) ? new BERSet(unauthGen.getAttributes(parameters).toASN1EncodableVector()) : null; ContentInfo eci = new ContentInfo( CMSObjectIdentifiers.data, encContent); authData = new AuthenticatedData(originatorInfo, new DERSet(recipientInfos), macCalculator.getAlgorithmIdentifier(), digestCalculator.getAlgorithmIdentifier(), eci, authed, macResult, unauthed); } else { try { ByteArrayOutputStream bOut = new ByteArrayOutputStream(); OutputStream mOut = new TeeOutputStream(bOut, macCalculator.getOutputStream()); typedData.write(mOut); mOut.close(); encContent = new BEROctetString(bOut.toByteArray()); macResult = new DEROctetString(macCalculator.getMac()); } catch (IOException e) { throw new CMSException("exception decoding algorithm parameters.", e); } ASN1Set unauthed = (unauthGen != null) ? new BERSet(unauthGen.getAttributes(new HashMap()).toASN1EncodableVector()) : null; ContentInfo eci = new ContentInfo( CMSObjectIdentifiers.data, encContent); authData = new AuthenticatedData(originatorInfo, new DERSet(recipientInfos), macCalculator.getAlgorithmIdentifier(), null, eci, null, macResult, unauthed); } ContentInfo contentInfo = new ContentInfo( CMSObjectIdentifiers.authenticatedData, authData); return new CMSAuthenticatedData(contentInfo, new DigestCalculatorProvider() { public DigestCalculator get(AlgorithmIdentifier digestAlgorithmIdentifier) throws OperatorCreationException { return digestCalculator; } }); } /** * constructor allowing specific source of randomness * @param rand instance of SecureRandom to use * @deprecated no longer required, use simple constructor. */ public CMSAuthenticatedDataGenerator( SecureRandom rand) { super(rand); } /** * generate an authenticated object that contains an CMS Authenticated Data * object using the given provider and the passed in key generator. * @deprecated */ private CMSAuthenticatedData generate( final CMSProcessable content, String macOID, KeyGenerator keyGen, Provider provider) throws NoSuchAlgorithmException, CMSException { Provider encProvider = keyGen.getProvider(); convertOldRecipients(rand, provider); return generate(new CMSTypedData() { public ASN1ObjectIdentifier getContentType() { return CMSObjectIdentifiers.data; } public void write(OutputStream out) throws IOException, CMSException { content.write(out); } public Object getContent() { return content; } }, new JceCMSMacCalculatorBuilder(new ASN1ObjectIdentifier(macOID)).setProvider(encProvider).setSecureRandom(rand).build()); } /** * generate an authenticated object that contains an CMS Authenticated Data * object using the given provider. * @deprecated use addRecipientInfoGenerator method. */ public CMSAuthenticatedData generate( CMSProcessable content, String macOID, String provider) throws NoSuchAlgorithmException, NoSuchProviderException, CMSException { return generate(content, macOID, CMSUtils.getProvider(provider)); } /** * generate an authenticated object that contains an CMS Authenticated Data * object using the given provider * @deprecated use addRecipientInfoGenerator method.. */ public CMSAuthenticatedData generate( CMSProcessable content, String encryptionOID, Provider provider) throws NoSuchAlgorithmException, CMSException { KeyGenerator keyGen = CMSEnvelopedHelper.INSTANCE.createSymmetricKeyGenerator(encryptionOID, provider); return generate(content, encryptionOID, keyGen, provider); } } bouncycastle-1.49.orig/jdk1.1/org/bouncycastle/cms/RecipientId.java0000644000175000017500000000115411731466726024545 0ustar ebourgebourgpackage org.bouncycastle.cms; import org.bouncycastle.util.Selector; public abstract class RecipientId implements Selector { public static final int keyTrans = 0; public static final int kek = 1; public static final int keyAgree = 2; public static final int password = 3; private int type; protected RecipientId(int type) { this.type = type; } /** * Return the type code for this recipient ID. * * @return one of keyTrans, kek, keyAgree, password */ public int getType() { return type; } public abstract Object clone(); } bouncycastle-1.49.orig/jdk1.1/org/bouncycastle/cms/CMSSignedData.java0000644000175000017500000006022512105031243024672 0ustar ebourgebourgpackage org.bouncycastle.cms; import java.io.IOException; import java.io.InputStream; import java.io.OutputStream; import java.security.NoSuchAlgorithmException; import java.security.NoSuchProviderException; import java.security.Provider; import java.security.cert.CertStore; import java.security.cert.CertStoreException; import java.util.ArrayList; import java.util.Enumeration; import java.util.Iterator; import java.util.List; import java.util.Map; import org.bouncycastle.asn1.ASN1Encodable; import org.bouncycastle.asn1.ASN1EncodableVector; import org.bouncycastle.asn1.ASN1InputStream; import org.bouncycastle.asn1.ASN1ObjectIdentifier; import org.bouncycastle.asn1.ASN1OctetString; import org.bouncycastle.asn1.ASN1Primitive; import org.bouncycastle.asn1.ASN1Sequence; import org.bouncycastle.asn1.ASN1Set; import org.bouncycastle.asn1.ASN1TaggedObject; import org.bouncycastle.asn1.BERSequence; import org.bouncycastle.asn1.DERSet; import org.bouncycastle.asn1.cms.ContentInfo; import org.bouncycastle.asn1.cms.SignedData; import org.bouncycastle.asn1.cms.SignerInfo; import org.bouncycastle.asn1.x509.AttributeCertificate; import org.bouncycastle.asn1.x509.Certificate; import org.bouncycastle.asn1.x509.CertificateList; import org.bouncycastle.cert.X509AttributeCertificateHolder; import org.bouncycastle.cert.X509CRLHolder; import org.bouncycastle.cert.X509CertificateHolder; import org.bouncycastle.operator.DefaultSignatureAlgorithmIdentifierFinder; import org.bouncycastle.operator.SignatureAlgorithmIdentifierFinder; import org.bouncycastle.util.CollectionStore; import org.bouncycastle.util.Store; import org.bouncycastle.x509.NoSuchStoreException; import org.bouncycastle.x509.X509Store; /** * general class for handling a pkcs7-signature message. * * A simple example of usage - note, in the example below the validity of * the certificate isn't verified, just the fact that one of the certs * matches the given signer... * *
     *  Store                   certStore = s.getCertificates();
     *  SignerInformationStore  signers = s.getSignerInfos();
     *  Collection              c = signers.getSigners();
     *  Iterator                it = c.iterator();
     *  
     *  while (it.hasNext())
     *  {
     *      SignerInformation   signer = (SignerInformation)it.next();
     *      Collection          certCollection = certStore.getMatches(signer.getSID());
     *
     *      Iterator              certIt = certCollection.iterator();
     *      X509CertificateHolder cert = (X509CertificateHolder)certIt.next();
     *  
     *      if (signer.verify(new JcaSimpleSignerInfoVerifierBuilder().setProvider("BC").build(cert)))
     *      {
     *          verified++;
     *      }   
     *  }
     * 
    */ public class CMSSignedData { private static final CMSSignedHelper HELPER = CMSSignedHelper.INSTANCE; SignedData signedData; ContentInfo contentInfo; CMSTypedData signedContent; SignerInformationStore signerInfoStore; X509Store attributeStore; X509Store certificateStore; X509Store crlStore; private Map hashes; private CMSSignedData( CMSSignedData c) { this.signedData = c.signedData; this.contentInfo = c.contentInfo; this.signedContent = c.signedContent; this.signerInfoStore = c.signerInfoStore; } public CMSSignedData( byte[] sigBlock) throws CMSException { this(CMSUtils.readContentInfo(sigBlock)); } public CMSSignedData( CMSProcessable signedContent, byte[] sigBlock) throws CMSException { this(signedContent, CMSUtils.readContentInfo(sigBlock)); } /** * Content with detached signature, digests precomputed * * @param hashes a map of precomputed digests for content indexed by name of hash. * @param sigBlock the signature object. */ public CMSSignedData( Map hashes, byte[] sigBlock) throws CMSException { this(hashes, CMSUtils.readContentInfo(sigBlock)); } /** * base constructor - content with detached signature. * * @param signedContent the content that was signed. * @param sigData the signature object. */ public CMSSignedData( CMSProcessable signedContent, InputStream sigData) throws CMSException { this(signedContent, CMSUtils.readContentInfo(new ASN1InputStream(sigData))); } /** * base constructor - with encapsulated content */ public CMSSignedData( InputStream sigData) throws CMSException { this(CMSUtils.readContentInfo(sigData)); } public CMSSignedData( final CMSProcessable signedContent, ContentInfo sigData) throws CMSException { if (signedContent instanceof CMSTypedData) { this.signedContent = (CMSTypedData)signedContent; } else { this.signedContent = new CMSTypedData() { public ASN1ObjectIdentifier getContentType() { return signedData.getEncapContentInfo().getContentType(); } public void write(OutputStream out) throws IOException, CMSException { signedContent.write(out); } public Object getContent() { return signedContent.getContent(); } }; } this.contentInfo = sigData; this.signedData = getSignedData(); } public CMSSignedData( Map hashes, ContentInfo sigData) throws CMSException { this.hashes = hashes; this.contentInfo = sigData; this.signedData = getSignedData(); } public CMSSignedData( ContentInfo sigData) throws CMSException { this.contentInfo = sigData; this.signedData = getSignedData(); // // this can happen if the signed message is sent simply to send a // certificate chain. // if (signedData.getEncapContentInfo().getContent() != null) { this.signedContent = new CMSProcessableByteArray(signedData.getEncapContentInfo().getContentType(), ((ASN1OctetString)(signedData.getEncapContentInfo() .getContent())).getOctets()); } else { this.signedContent = null; } } private SignedData getSignedData() throws CMSException { try { return SignedData.getInstance(contentInfo.getContent()); } catch (ClassCastException e) { throw new CMSException("Malformed content.", e); } catch (IllegalArgumentException e) { throw new CMSException("Malformed content.", e); } } /** * Return the version number for this object */ public int getVersion() { return signedData.getVersion().getValue().intValue(); } /** * return the collection of signers that are associated with the * signatures for the message. */ public SignerInformationStore getSignerInfos() { if (signerInfoStore == null) { ASN1Set s = signedData.getSignerInfos(); List signerInfos = new ArrayList(); SignatureAlgorithmIdentifierFinder sigAlgFinder = new DefaultSignatureAlgorithmIdentifierFinder(); for (int i = 0; i != s.size(); i++) { SignerInfo info = SignerInfo.getInstance(s.getObjectAt(i)); ASN1ObjectIdentifier contentType = signedData.getEncapContentInfo().getContentType(); if (hashes == null) { signerInfos.add(new SignerInformation(info, contentType, signedContent, null)); } else { Object obj = hashes.keySet().iterator().next(); byte[] hash = (obj instanceof String) ? (byte[])hashes.get(info.getDigestAlgorithm().getAlgorithm().getId()) : (byte[])hashes.get(info.getDigestAlgorithm().getAlgorithm()); signerInfos.add(new SignerInformation(info, contentType, null, hash)); } } signerInfoStore = new SignerInformationStore(signerInfos); } return signerInfoStore; } /** * return a X509Store containing the attribute certificates, if any, contained * in this message. * * @param type type of store to create * @param provider name of provider to use * @return a store of attribute certificates * @exception NoSuchProviderException if the provider requested isn't available. * @exception NoSuchStoreException if the store type isn't available. * @exception CMSException if a general exception prevents creation of the X509Store * @deprecated use base Store returning method */ public X509Store getAttributeCertificates( String type, String provider) throws NoSuchStoreException, NoSuchProviderException, CMSException { return getAttributeCertificates(type, CMSUtils.getProvider(provider)); } /** * return a X509Store containing the attribute certificates, if any, contained * in this message. * * @param type type of store to create * @param provider provider to use * @return a store of attribute certificates * @exception NoSuchStoreException if the store type isn't available. * @exception CMSException if a general exception prevents creation of the X509Store * @deprecated use base Store returning method */ public X509Store getAttributeCertificates( String type, Provider provider) throws NoSuchStoreException, CMSException { if (attributeStore == null) { attributeStore = HELPER.createAttributeStore(type, provider, signedData.getCertificates()); } return attributeStore; } /** * return a X509Store containing the public key certificates, if any, contained * in this message. * * @param type type of store to create * @param provider name of provider to use * @return a store of public key certificates * @exception NoSuchProviderException if the provider requested isn't available. * @exception NoSuchStoreException if the store type isn't available. * @exception CMSException if a general exception prevents creation of the X509Store * @deprecated use base Store returning method */ public X509Store getCertificates( String type, String provider) throws NoSuchStoreException, NoSuchProviderException, CMSException { return getCertificates(type, CMSUtils.getProvider(provider)); } /** * return a X509Store containing the public key certificates, if any, contained * in this message. * * @param type type of store to create * @param provider provider to use * @return a store of public key certificates * @exception NoSuchStoreException if the store type isn't available. * @exception CMSException if a general exception prevents creation of the X509Store * @deprecated use base Store returning method */ public X509Store getCertificates( String type, Provider provider) throws NoSuchStoreException, CMSException { if (certificateStore == null) { certificateStore = HELPER.createCertificateStore(type, provider, signedData.getCertificates()); } return certificateStore; } /** * return a X509Store containing CRLs, if any, contained * in this message. * * @param type type of store to create * @param provider name of provider to use * @return a store of CRLs * @exception NoSuchProviderException if the provider requested isn't available. * @exception NoSuchStoreException if the store type isn't available. * @exception CMSException if a general exception prevents creation of the X509Store * @deprecated use base Store returning method */ public X509Store getCRLs( String type, String provider) throws NoSuchStoreException, NoSuchProviderException, CMSException { return getCRLs(type, CMSUtils.getProvider(provider)); } /** * return a X509Store containing CRLs, if any, contained * in this message. * * @param type type of store to create * @param provider provider to use * @return a store of CRLs * @exception NoSuchStoreException if the store type isn't available. * @exception CMSException if a general exception prevents creation of the X509Store * @deprecated use base Store returning method */ public X509Store getCRLs( String type, Provider provider) throws NoSuchStoreException, CMSException { if (crlStore == null) { crlStore = HELPER.createCRLsStore(type, provider, signedData.getCRLs()); } return crlStore; } /** * return a CertStore containing the certificates and CRLs associated with * this message. * * @exception NoSuchProviderException if the provider requested isn't available. * @exception NoSuchAlgorithmException if the cert store isn't available. * @exception CMSException if a general exception prevents creation of the CertStore * @deprecated use base Store returning method */ public CertStore getCertificatesAndCRLs( String type, String provider) throws NoSuchAlgorithmException, NoSuchProviderException, CMSException { return getCertificatesAndCRLs(type, CMSUtils.getProvider(provider)); } /** * return a CertStore containing the certificates and CRLs associated with * this message. * * @exception NoSuchAlgorithmException if the cert store isn't available. * @exception CMSException if a general exception prevents creation of the CertStore * @deprecated use base Store returning method */ public CertStore getCertificatesAndCRLs( String type, Provider provider) throws NoSuchAlgorithmException, CMSException { ASN1Set certSet = signedData.getCertificates(); ASN1Set crlSet = signedData.getCRLs(); return HELPER.createCertStore(type, provider, certSet, crlSet); } public Store getCertificates() { ASN1Set certSet = signedData.getCertificates(); if (certSet != null) { List certList = new ArrayList(certSet.size()); for (Enumeration en = certSet.getObjects(); en.hasMoreElements();) { ASN1Primitive obj = ((ASN1Encodable)en.nextElement()).toASN1Primitive(); if (obj instanceof ASN1Sequence) { certList.add(new X509CertificateHolder(Certificate.getInstance(obj))); } } return new CollectionStore(certList); } return new CollectionStore(new ArrayList()); } public Store getCRLs() { ASN1Set crlSet = signedData.getCRLs(); if (crlSet != null) { List crlList = new ArrayList(crlSet.size()); for (Enumeration en = crlSet.getObjects(); en.hasMoreElements();) { ASN1Primitive obj = ((ASN1Encodable)en.nextElement()).toASN1Primitive(); if (obj instanceof ASN1Sequence) { crlList.add(new X509CRLHolder(CertificateList.getInstance(obj))); } } return new CollectionStore(crlList); } return new CollectionStore(new ArrayList()); } public Store getAttributeCertificates() { ASN1Set certSet = signedData.getCertificates(); if (certSet != null) { List certList = new ArrayList(certSet.size()); for (Enumeration en = certSet.getObjects(); en.hasMoreElements();) { ASN1Primitive obj = ((ASN1Encodable)en.nextElement()).toASN1Primitive(); if (obj instanceof ASN1TaggedObject) { certList.add(new X509AttributeCertificateHolder(AttributeCertificate.getInstance(((ASN1TaggedObject)obj).getObject()))); } } return new CollectionStore(certList); } return new CollectionStore(new ArrayList()); } /** * Return the a string representation of the OID associated with the * encapsulated content info structure carried in the signed data. * * @return the OID for the content type. */ public String getSignedContentTypeOID() { return signedData.getEncapContentInfo().getContentType().getId(); } public CMSTypedData getSignedContent() { return signedContent; } /** * return the ContentInfo * @deprecated use toASN1Structure() */ public ContentInfo getContentInfo() { return contentInfo; } /** * return the ContentInfo */ public ContentInfo toASN1Structure() { return contentInfo; } /** * return the ASN.1 encoded representation of this object. */ public byte[] getEncoded() throws IOException { return contentInfo.getEncoded(); } /** * Replace the signerinformation store associated with this * CMSSignedData object with the new one passed in. You would * probably only want to do this if you wanted to change the unsigned * attributes associated with a signer, or perhaps delete one. * * @param signedData the signed data object to be used as a base. * @param signerInformationStore the new signer information store to use. * @return a new signed data object. */ public static CMSSignedData replaceSigners( CMSSignedData signedData, SignerInformationStore signerInformationStore) { // // copy // CMSSignedData cms = new CMSSignedData(signedData); // // replace the store // cms.signerInfoStore = signerInformationStore; // // replace the signers in the SignedData object // ASN1EncodableVector digestAlgs = new ASN1EncodableVector(); ASN1EncodableVector vec = new ASN1EncodableVector(); Iterator it = signerInformationStore.getSigners().iterator(); while (it.hasNext()) { SignerInformation signer = (SignerInformation)it.next(); digestAlgs.add(CMSSignedHelper.INSTANCE.fixAlgID(signer.getDigestAlgorithmID())); vec.add(signer.toASN1Structure()); } ASN1Set digests = new DERSet(digestAlgs); ASN1Set signers = new DERSet(vec); ASN1Sequence sD = (ASN1Sequence)signedData.signedData.toASN1Primitive(); vec = new ASN1EncodableVector(); // // signers are the last item in the sequence. // vec.add(sD.getObjectAt(0)); // version vec.add(digests); for (int i = 2; i != sD.size() - 1; i++) { vec.add(sD.getObjectAt(i)); } vec.add(signers); cms.signedData = SignedData.getInstance(new BERSequence(vec)); // // replace the contentInfo with the new one // cms.contentInfo = new ContentInfo(cms.contentInfo.getContentType(), cms.signedData); return cms; } /** * Replace the certificate and CRL information associated with this * CMSSignedData object with the new one passed in. * * @param signedData the signed data object to be used as a base. * @param certsAndCrls the new certificates and CRLs to be used. * @return a new signed data object. * @exception CMSException if there is an error processing the CertStore * @deprecated use method taking Store arguments. */ public static CMSSignedData replaceCertificatesAndCRLs( CMSSignedData signedData, CertStore certsAndCrls) throws CMSException { // // copy // CMSSignedData cms = new CMSSignedData(signedData); // // replace the certs and crls in the SignedData object // ASN1Set certs = null; ASN1Set crls = null; try { ASN1Set set = CMSUtils.createBerSetFromList(CMSUtils.getCertificatesFromStore(certsAndCrls)); if (set.size() != 0) { certs = set; } } catch (CertStoreException e) { throw new CMSException("error getting certs from certStore", e); } try { ASN1Set set = CMSUtils.createBerSetFromList(CMSUtils.getCRLsFromStore(certsAndCrls)); if (set.size() != 0) { crls = set; } } catch (CertStoreException e) { throw new CMSException("error getting crls from certStore", e); } // // replace the CMS structure. // cms.signedData = new SignedData(signedData.signedData.getDigestAlgorithms(), signedData.signedData.getEncapContentInfo(), certs, crls, signedData.signedData.getSignerInfos()); // // replace the contentInfo with the new one // cms.contentInfo = new ContentInfo(cms.contentInfo.getContentType(), cms.signedData); return cms; } /** * Replace the certificate and CRL information associated with this * CMSSignedData object with the new one passed in. * * @param signedData the signed data object to be used as a base. * @param certificates the new certificates to be used. * @param attrCerts the new attribute certificates to be used. * @param crls the new CRLs to be used. * @return a new signed data object. * @exception CMSException if there is an error processing the CertStore */ public static CMSSignedData replaceCertificatesAndCRLs( CMSSignedData signedData, Store certificates, Store attrCerts, Store crls) throws CMSException { // // copy // CMSSignedData cms = new CMSSignedData(signedData); // // replace the certs and crls in the SignedData object // ASN1Set certSet = null; ASN1Set crlSet = null; if (certificates != null || attrCerts != null) { List certs = new ArrayList(); if (certificates != null) { certs.addAll(CMSUtils.getCertificatesFromStore(certificates)); } if (attrCerts != null) { certs.addAll(CMSUtils.getAttributeCertificatesFromStore(attrCerts)); } ASN1Set set = CMSUtils.createBerSetFromList(certs); if (set.size() != 0) { certSet = set; } } if (crls != null) { ASN1Set set = CMSUtils.createBerSetFromList(CMSUtils.getCRLsFromStore(crls)); if (set.size() != 0) { crlSet = set; } } // // replace the CMS structure. // cms.signedData = new SignedData(signedData.signedData.getDigestAlgorithms(), signedData.signedData.getEncapContentInfo(), certSet, crlSet, signedData.signedData.getSignerInfos()); // // replace the contentInfo with the new one // cms.contentInfo = new ContentInfo(cms.contentInfo.getContentType(), cms.signedData); return cms; } } bouncycastle-1.49.orig/jdk1.1/org/bouncycastle/cms/CMSUtils.java0000644000175000017500000002311211731466726024007 0ustar ebourgebourgpackage org.bouncycastle.cms; import java.io.IOException; import java.io.InputStream; import java.io.OutputStream; import java.security.NoSuchProviderException; import java.security.Provider; import java.security.Security; import java.security.cert.CRLException; import java.security.cert.CertStore; import java.security.cert.CertStoreException; import java.security.cert.CertificateEncodingException; import java.security.cert.X509CRL; import java.security.cert.X509Certificate; import java.util.ArrayList; import java.util.Collection; import java.util.Iterator; import java.util.List; import org.bouncycastle.asn1.ASN1Encodable; import org.bouncycastle.asn1.ASN1EncodableVector; import org.bouncycastle.asn1.ASN1InputStream; import org.bouncycastle.asn1.ASN1Primitive; import org.bouncycastle.asn1.ASN1Set; import org.bouncycastle.asn1.BEROctetStringGenerator; import org.bouncycastle.asn1.BERSet; import org.bouncycastle.asn1.DERSet; import org.bouncycastle.asn1.DERTaggedObject; import org.bouncycastle.asn1.cms.ContentInfo; import org.bouncycastle.asn1.cms.IssuerAndSerialNumber; import org.bouncycastle.asn1.x509.CertificateList; import org.bouncycastle.asn1.x509.TBSCertificateStructure; import org.bouncycastle.asn1.x509.X509CertificateStructure; import org.bouncycastle.cert.X509AttributeCertificateHolder; import org.bouncycastle.cert.X509CRLHolder; import org.bouncycastle.cert.X509CertificateHolder; import org.bouncycastle.operator.DigestCalculator; import org.bouncycastle.util.Store; import org.bouncycastle.util.io.Streams; import org.bouncycastle.util.io.TeeInputStream; import org.bouncycastle.util.io.TeeOutputStream; class CMSUtils { static ContentInfo readContentInfo( byte[] input) throws CMSException { // enforce limit checking as from a byte array return readContentInfo(new ASN1InputStream(input)); } static ContentInfo readContentInfo( InputStream input) throws CMSException { // enforce some limit checking return readContentInfo(new ASN1InputStream(input)); } static List getCertificatesFromStore(CertStore certStore) throws CertStoreException, CMSException { List certs = new ArrayList(); try { for (Iterator it = certStore.getCertificates(null).iterator(); it.hasNext();) { X509Certificate c = (X509Certificate)it.next(); certs.add(X509CertificateStructure.getInstance( ASN1Primitive.fromByteArray(c.getEncoded()))); } return certs; } catch (IllegalArgumentException e) { throw new CMSException("error processing certs", e); } catch (IOException e) { throw new CMSException("error processing certs", e); } catch (CertificateEncodingException e) { throw new CMSException("error encoding certs", e); } } static List getCertificatesFromStore(Store certStore) throws CMSException { List certs = new ArrayList(); try { for (Iterator it = certStore.getMatches(null).iterator(); it.hasNext();) { X509CertificateHolder c = (X509CertificateHolder)it.next(); certs.add(c.toASN1Structure()); } return certs; } catch (ClassCastException e) { throw new CMSException("error processing certs", e); } } static List getAttributeCertificatesFromStore(Store attrStore) throws CMSException { List certs = new ArrayList(); try { for (Iterator it = attrStore.getMatches(null).iterator(); it.hasNext();) { X509AttributeCertificateHolder attrCert = (X509AttributeCertificateHolder)it.next(); certs.add(new DERTaggedObject(false, 2, attrCert.toASN1Structure())); } return certs; } catch (ClassCastException e) { throw new CMSException("error processing certs", e); } } static List getCRLsFromStore(CertStore certStore) throws CertStoreException, CMSException { List crls = new ArrayList(); try { for (Iterator it = certStore.getCRLs(null).iterator(); it.hasNext();) { X509CRL c = (X509CRL)it.next(); crls.add(CertificateList.getInstance(ASN1Primitive.fromByteArray(c.getEncoded()))); } return crls; } catch (IllegalArgumentException e) { throw new CMSException("error processing crls", e); } catch (IOException e) { throw new CMSException("error processing crls", e); } catch (CRLException e) { throw new CMSException("error encoding crls", e); } } static List getCRLsFromStore(Store crlStore) throws CMSException { List certs = new ArrayList(); try { for (Iterator it = crlStore.getMatches(null).iterator(); it.hasNext();) { X509CRLHolder c = (X509CRLHolder)it.next(); certs.add(c.toASN1Structure()); } return certs; } catch (ClassCastException e) { throw new CMSException("error processing certs", e); } } static ASN1Set createBerSetFromList(List derObjects) { ASN1EncodableVector v = new ASN1EncodableVector(); for (Iterator it = derObjects.iterator(); it.hasNext();) { v.add((ASN1Encodable)it.next()); } return new BERSet(v); } static ASN1Set createDerSetFromList(List derObjects) { ASN1EncodableVector v = new ASN1EncodableVector(); for (Iterator it = derObjects.iterator(); it.hasNext();) { v.add((ASN1Encodable)it.next()); } return new DERSet(v); } static OutputStream createBEROctetOutputStream(OutputStream s, int tagNo, boolean isExplicit, int bufferSize) throws IOException { BEROctetStringGenerator octGen = new BEROctetStringGenerator(s, tagNo, isExplicit); if (bufferSize != 0) { return octGen.getOctetOutputStream(new byte[bufferSize]); } return octGen.getOctetOutputStream(); } static TBSCertificateStructure getTBSCertificateStructure( X509Certificate cert) { try { return TBSCertificateStructure.getInstance( ASN1Primitive.fromByteArray(cert.getTBSCertificate())); } catch (Exception e) { throw new IllegalArgumentException( "can't extract TBS structure from this cert"); } } static IssuerAndSerialNumber getIssuerAndSerialNumber(X509Certificate cert) { TBSCertificateStructure tbsCert = getTBSCertificateStructure(cert); return new IssuerAndSerialNumber(tbsCert.getIssuer(), tbsCert.getSerialNumber().getValue()); } private static ContentInfo readContentInfo( ASN1InputStream in) throws CMSException { try { return ContentInfo.getInstance(in.readObject()); } catch (IOException e) { throw new CMSException("IOException reading content.", e); } catch (ClassCastException e) { throw new CMSException("Malformed content.", e); } catch (IllegalArgumentException e) { throw new CMSException("Malformed content.", e); } } public static byte[] streamToByteArray( InputStream in) throws IOException { return Streams.readAll(in); } public static byte[] streamToByteArray( InputStream in, int limit) throws IOException { return Streams.readAllLimited(in, limit); } public static Provider getProvider(String providerName) throws NoSuchProviderException { if (providerName != null) { Provider prov = Security.getProvider(providerName); if (prov != null) { return prov; } throw new NoSuchProviderException("provider " + providerName + " not found."); } return null; } static InputStream attachDigestsToInputStream(Collection digests, InputStream s) { InputStream result = s; Iterator it = digests.iterator(); while (it.hasNext()) { DigestCalculator digest = (DigestCalculator)it.next(); result = new TeeInputStream(result, digest.getOutputStream()); } return result; } static OutputStream attachSignersToOutputStream(Collection signers, OutputStream s) { OutputStream result = s; Iterator it = signers.iterator(); while (it.hasNext()) { SignerInfoGenerator signerGen = (SignerInfoGenerator)it.next(); result = getSafeTeeOutputStream(result, signerGen.getCalculatingOutputStream()); } return result; } static OutputStream getSafeOutputStream(OutputStream s) { return s == null ? new NullOutputStream() : s; } static OutputStream getSafeTeeOutputStream(OutputStream s1, OutputStream s2) { return s1 == null ? getSafeOutputStream(s2) : s2 == null ? getSafeOutputStream(s1) : new TeeOutputStream( s1, s2); } } bouncycastle-1.49.orig/jdk1.1/org/bouncycastle/cms/CMSTypedStream.java0000644000175000017500000000362311731466726025155 0ustar ebourgebourgpackage org.bouncycastle.cms; import java.io.BufferedInputStream; import java.io.FilterInputStream; import java.io.IOException; import java.io.InputStream; import org.bouncycastle.asn1.ASN1ObjectIdentifier; import org.bouncycastle.asn1.pkcs.PKCSObjectIdentifiers; import org.bouncycastle.util.io.Streams; public class CMSTypedStream { private static final int BUF_SIZ = 32 * 1024; private ASN1ObjectIdentifier _oid; private InputStream _in; public CMSTypedStream( InputStream in) { this(PKCSObjectIdentifiers.data.getId(), in, BUF_SIZ); } public CMSTypedStream( String oid, InputStream in) { this(new ASN1ObjectIdentifier(oid), in, BUF_SIZ); } public CMSTypedStream( String oid, InputStream in, int bufSize) { this(new ASN1ObjectIdentifier(oid), in, bufSize); } public CMSTypedStream( ASN1ObjectIdentifier oid, InputStream in) { this(oid, in, BUF_SIZ); } public CMSTypedStream( ASN1ObjectIdentifier oid, InputStream in, int bufSize) { _oid = oid; _in = new FullReaderStream(new BufferedInputStream(in, bufSize)); } public ASN1ObjectIdentifier getContentType() { return _oid; } public InputStream getContentStream() { return _in; } public void drain() throws IOException { Streams.drain(_in); _in.close(); } private static class FullReaderStream extends FilterInputStream { FullReaderStream(InputStream in) { super(in); } public int read(byte[] buf, int off, int len) throws IOException { int totalRead = Streams.readFully(super.in, buf, off, len); return totalRead > 0 ? totalRead : -1; } } } bouncycastle-1.49.orig/jdk1.1/org/bouncycastle/cms/OriginatorInfoGenerator.java0000644000175000017500000000260311731466726027146 0ustar ebourgebourgpackage org.bouncycastle.cms; import java.util.ArrayList; import java.util.List; import org.bouncycastle.asn1.cms.OriginatorInfo; import org.bouncycastle.cert.X509CertificateHolder; import org.bouncycastle.util.Store; public class OriginatorInfoGenerator { private List origCerts; private List origCRLs; public OriginatorInfoGenerator(X509CertificateHolder origCert) { this.origCerts = new ArrayList(1); this.origCRLs = null; origCerts.add(origCert.toASN1Structure()); } public OriginatorInfoGenerator(Store origCerts) throws CMSException { this(origCerts, null); } public OriginatorInfoGenerator(Store origCerts, Store origCRLs) throws CMSException { this.origCerts = CMSUtils.getCertificatesFromStore(origCerts); if (origCRLs != null) { this.origCRLs = CMSUtils.getCRLsFromStore(origCRLs); } else { this.origCRLs = null; } } public OriginatorInformation generate() { if (origCRLs != null) { return new OriginatorInformation(new OriginatorInfo(CMSUtils.createDerSetFromList(origCerts), CMSUtils.createDerSetFromList(origCRLs))); } else { return new OriginatorInformation(new OriginatorInfo(CMSUtils.createDerSetFromList(origCerts), null)); } } } bouncycastle-1.49.orig/jdk1.1/org/bouncycastle/cms/CMSEnvelopedHelper.java0000644000175000017500000002103012103632343025745 0ustar ebourgebourgpackage org.bouncycastle.cms; import java.io.FilterInputStream; import java.io.IOException; import java.io.InputStream; import java.security.NoSuchAlgorithmException; import java.security.NoSuchProviderException; import java.security.Provider; import java.util.ArrayList; import java.util.HashMap; import java.util.List; import java.util.Map; import javax.crypto.KeyGenerator; import org.bouncycastle.asn1.ASN1Encodable; import org.bouncycastle.asn1.ASN1Set; import org.bouncycastle.asn1.cms.KEKRecipientInfo; import org.bouncycastle.asn1.cms.KeyAgreeRecipientInfo; import org.bouncycastle.asn1.cms.KeyTransRecipientInfo; import org.bouncycastle.asn1.cms.PasswordRecipientInfo; import org.bouncycastle.asn1.cms.RecipientInfo; import org.bouncycastle.asn1.x509.AlgorithmIdentifier; import org.bouncycastle.operator.DigestCalculator; import org.bouncycastle.util.Integers; class CMSEnvelopedHelper { static final CMSEnvelopedHelper INSTANCE = new CMSEnvelopedHelper(); private static final Map KEYSIZES = new HashMap(); private static final Map BASE_CIPHER_NAMES = new HashMap(); private static final Map CIPHER_ALG_NAMES = new HashMap(); private static final Map MAC_ALG_NAMES = new HashMap(); static { KEYSIZES.put(CMSEnvelopedGenerator.DES_EDE3_CBC, Integers.valueOf(192)); KEYSIZES.put(CMSEnvelopedGenerator.AES128_CBC, Integers.valueOf(128)); KEYSIZES.put(CMSEnvelopedGenerator.AES192_CBC, Integers.valueOf(192)); KEYSIZES.put(CMSEnvelopedGenerator.AES256_CBC, Integers.valueOf(256)); BASE_CIPHER_NAMES.put(CMSEnvelopedGenerator.DES_EDE3_CBC, "DESEDE"); BASE_CIPHER_NAMES.put(CMSEnvelopedGenerator.AES128_CBC, "AES"); BASE_CIPHER_NAMES.put(CMSEnvelopedGenerator.AES192_CBC, "AES"); BASE_CIPHER_NAMES.put(CMSEnvelopedGenerator.AES256_CBC, "AES"); CIPHER_ALG_NAMES.put(CMSEnvelopedGenerator.DES_EDE3_CBC, "DESEDE/CBC/PKCS5Padding"); CIPHER_ALG_NAMES.put(CMSEnvelopedGenerator.AES128_CBC, "AES/CBC/PKCS5Padding"); CIPHER_ALG_NAMES.put(CMSEnvelopedGenerator.AES192_CBC, "AES/CBC/PKCS5Padding"); CIPHER_ALG_NAMES.put(CMSEnvelopedGenerator.AES256_CBC, "AES/CBC/PKCS5Padding"); MAC_ALG_NAMES.put(CMSEnvelopedGenerator.DES_EDE3_CBC, "DESEDEMac"); MAC_ALG_NAMES.put(CMSEnvelopedGenerator.AES128_CBC, "AESMac"); MAC_ALG_NAMES.put(CMSEnvelopedGenerator.AES192_CBC, "AESMac"); MAC_ALG_NAMES.put(CMSEnvelopedGenerator.AES256_CBC, "AESMac"); } KeyGenerator createSymmetricKeyGenerator( String encryptionOID, Provider provider) throws NoSuchAlgorithmException { try { return createKeyGenerator(encryptionOID, provider); } catch (NoSuchAlgorithmException e) { try { String algName = (String)BASE_CIPHER_NAMES.get(encryptionOID); if (algName != null) { return createKeyGenerator(algName, provider); } } catch (NoSuchAlgorithmException ex) { // ignore } if (provider != null) { return createSymmetricKeyGenerator(encryptionOID, null); } throw e; } } int getKeySize(String oid) { Integer keySize = (Integer)KEYSIZES.get(oid); if (keySize == null) { throw new IllegalArgumentException("no keysize for " + oid); } return keySize.intValue(); } private KeyGenerator createKeyGenerator( String algName, Provider provider) throws NoSuchAlgorithmException { if (provider != null) { try { return KeyGenerator.getInstance(algName, provider.getName()); } catch (NoSuchProviderException e) { throw new NoSuchAlgorithmException(e.toString()); } } else { return KeyGenerator.getInstance(algName); } } static RecipientInformationStore buildRecipientInformationStore( ASN1Set recipientInfos, AlgorithmIdentifier messageAlgorithm, CMSSecureReadable secureReadable) { return buildRecipientInformationStore(recipientInfos, messageAlgorithm, secureReadable, null); } static RecipientInformationStore buildRecipientInformationStore( ASN1Set recipientInfos, AlgorithmIdentifier messageAlgorithm, CMSSecureReadable secureReadable, AuthAttributesProvider additionalData) { List infos = new ArrayList(); for (int i = 0; i != recipientInfos.size(); i++) { RecipientInfo info = RecipientInfo.getInstance(recipientInfos.getObjectAt(i)); readRecipientInfo(infos, info, messageAlgorithm, secureReadable, additionalData); } return new RecipientInformationStore(infos); } private static void readRecipientInfo( List infos, RecipientInfo info, AlgorithmIdentifier messageAlgorithm, CMSSecureReadable secureReadable, AuthAttributesProvider additionalData) { ASN1Encodable recipInfo = info.getInfo(); if (recipInfo instanceof KeyTransRecipientInfo) { infos.add(new KeyTransRecipientInformation( (KeyTransRecipientInfo)recipInfo, messageAlgorithm, secureReadable, additionalData)); } else if (recipInfo instanceof KEKRecipientInfo) { infos.add(new KEKRecipientInformation( (KEKRecipientInfo)recipInfo, messageAlgorithm, secureReadable, additionalData)); } else if (recipInfo instanceof KeyAgreeRecipientInfo) { KeyAgreeRecipientInformation.readRecipientInfo(infos, (KeyAgreeRecipientInfo)recipInfo, messageAlgorithm, secureReadable, additionalData); } else if (recipInfo instanceof PasswordRecipientInfo) { infos.add(new PasswordRecipientInformation( (PasswordRecipientInfo)recipInfo, messageAlgorithm, secureReadable, additionalData)); } } static class CMSDigestAuthenticatedSecureReadable implements CMSSecureReadable { private DigestCalculator digestCalculator; private CMSReadable readable; public CMSDigestAuthenticatedSecureReadable(DigestCalculator digestCalculator, CMSReadable readable) { this.digestCalculator = digestCalculator; this.readable = readable; } public InputStream getInputStream() throws IOException, CMSException { return new FilterInputStream(readable.getInputStream()) { public int read() throws IOException { int b = in.read(); if (b >= 0) { digestCalculator.getOutputStream().write(b); } return b; } public int read(byte[] inBuf, int inOff, int inLen) throws IOException { int n = in.read(inBuf, inOff, inLen); if (n >= 0) { digestCalculator.getOutputStream().write(inBuf, inOff, n); } return n; } }; } public byte[] getDigest() { return digestCalculator.getDigest(); } } static class CMSAuthenticatedSecureReadable implements CMSSecureReadable { private AlgorithmIdentifier algorithm; private CMSReadable readable; CMSAuthenticatedSecureReadable(AlgorithmIdentifier algorithm, CMSReadable readable) { this.algorithm = algorithm; this.readable = readable; } public InputStream getInputStream() throws IOException, CMSException { return readable.getInputStream(); } } static class CMSEnvelopedSecureReadable implements CMSSecureReadable { private AlgorithmIdentifier algorithm; private CMSReadable readable; CMSEnvelopedSecureReadable(AlgorithmIdentifier algorithm, CMSReadable readable) { this.algorithm = algorithm; this.readable = readable; } public InputStream getInputStream() throws IOException, CMSException { return readable.getInputStream(); } } } bouncycastle-1.49.orig/jdk1.1/org/bouncycastle/cms/CMSSignedGenerator.java0000644000175000017500000002430011731466726025767 0ustar ebourgebourgpackage org.bouncycastle.cms; import java.io.IOException; import java.security.AlgorithmParameters; import java.security.PrivateKey; import java.security.SecureRandom; import java.security.Signature; import java.security.cert.CertStore; import java.security.cert.CertStoreException; import java.security.interfaces.DSAPrivateKey; import java.security.interfaces.RSAPrivateKey; import java.util.ArrayList; import java.util.HashMap; import java.util.HashSet; import java.util.Iterator; import java.util.List; import java.util.Map; import java.util.Set; import org.bouncycastle.asn1.ASN1ObjectIdentifier; import org.bouncycastle.asn1.ASN1Primitive; import org.bouncycastle.asn1.ASN1Set; import org.bouncycastle.asn1.DERNull; import org.bouncycastle.asn1.DERObjectIdentifier; import org.bouncycastle.asn1.DERSet; import org.bouncycastle.asn1.DERTaggedObject; import org.bouncycastle.asn1.cms.AttributeTable; import org.bouncycastle.asn1.cms.CMSObjectIdentifiers; import org.bouncycastle.asn1.cryptopro.CryptoProObjectIdentifiers; import org.bouncycastle.asn1.nist.NISTObjectIdentifiers; import org.bouncycastle.asn1.oiw.OIWObjectIdentifiers; import org.bouncycastle.asn1.pkcs.PKCSObjectIdentifiers; import org.bouncycastle.asn1.teletrust.TeleTrusTObjectIdentifiers; import org.bouncycastle.asn1.x509.AlgorithmIdentifier; import org.bouncycastle.asn1.x509.AttributeCertificate; import org.bouncycastle.asn1.x9.X9ObjectIdentifiers; import org.bouncycastle.jce.interfaces.GOST3410PrivateKey; import org.bouncycastle.util.Store; import org.bouncycastle.x509.X509AttributeCertificate; import org.bouncycastle.x509.X509Store; public class CMSSignedGenerator { /** * Default type for the signed data. */ public static final String DATA = CMSObjectIdentifiers.data.getId(); public static final String DIGEST_SHA1 = OIWObjectIdentifiers.idSHA1.getId(); public static final String DIGEST_SHA224 = NISTObjectIdentifiers.id_sha224.getId(); public static final String DIGEST_SHA256 = NISTObjectIdentifiers.id_sha256.getId(); public static final String DIGEST_SHA384 = NISTObjectIdentifiers.id_sha384.getId(); public static final String DIGEST_SHA512 = NISTObjectIdentifiers.id_sha512.getId(); public static final String DIGEST_MD5 = PKCSObjectIdentifiers.md5.getId(); public static final String DIGEST_GOST3411 = CryptoProObjectIdentifiers.gostR3411.getId(); public static final String DIGEST_RIPEMD128 = TeleTrusTObjectIdentifiers.ripemd128.getId(); public static final String DIGEST_RIPEMD160 = TeleTrusTObjectIdentifiers.ripemd160.getId(); public static final String DIGEST_RIPEMD256 = TeleTrusTObjectIdentifiers.ripemd256.getId(); public static final String ENCRYPTION_RSA = PKCSObjectIdentifiers.rsaEncryption.getId(); public static final String ENCRYPTION_DSA = X9ObjectIdentifiers.id_dsa_with_sha1.getId(); public static final String ENCRYPTION_ECDSA = X9ObjectIdentifiers.ecdsa_with_SHA1.getId(); public static final String ENCRYPTION_RSA_PSS = PKCSObjectIdentifiers.id_RSASSA_PSS.getId(); public static final String ENCRYPTION_GOST3410 = CryptoProObjectIdentifiers.gostR3410_94.getId(); public static final String ENCRYPTION_ECGOST3410 = CryptoProObjectIdentifiers.gostR3410_2001.getId(); private static final String ENCRYPTION_ECDSA_WITH_SHA1 = X9ObjectIdentifiers.ecdsa_with_SHA1.getId(); private static final String ENCRYPTION_ECDSA_WITH_SHA224 = X9ObjectIdentifiers.ecdsa_with_SHA224.getId(); private static final String ENCRYPTION_ECDSA_WITH_SHA256 = X9ObjectIdentifiers.ecdsa_with_SHA256.getId(); private static final String ENCRYPTION_ECDSA_WITH_SHA384 = X9ObjectIdentifiers.ecdsa_with_SHA384.getId(); private static final String ENCRYPTION_ECDSA_WITH_SHA512 = X9ObjectIdentifiers.ecdsa_with_SHA512.getId(); private static final Set NO_PARAMS = new HashSet(); private static final Map EC_ALGORITHMS = new HashMap(); static { NO_PARAMS.add(ENCRYPTION_DSA); NO_PARAMS.add(ENCRYPTION_ECDSA); NO_PARAMS.add(ENCRYPTION_ECDSA_WITH_SHA1); NO_PARAMS.add(ENCRYPTION_ECDSA_WITH_SHA224); NO_PARAMS.add(ENCRYPTION_ECDSA_WITH_SHA256); NO_PARAMS.add(ENCRYPTION_ECDSA_WITH_SHA384); NO_PARAMS.add(ENCRYPTION_ECDSA_WITH_SHA512); EC_ALGORITHMS.put(DIGEST_SHA1, ENCRYPTION_ECDSA_WITH_SHA1); EC_ALGORITHMS.put(DIGEST_SHA224, ENCRYPTION_ECDSA_WITH_SHA224); EC_ALGORITHMS.put(DIGEST_SHA256, ENCRYPTION_ECDSA_WITH_SHA256); EC_ALGORITHMS.put(DIGEST_SHA384, ENCRYPTION_ECDSA_WITH_SHA384); EC_ALGORITHMS.put(DIGEST_SHA512, ENCRYPTION_ECDSA_WITH_SHA512); } protected List certs = new ArrayList(); protected List crls = new ArrayList(); protected List _signers = new ArrayList(); protected List signerGens = new ArrayList(); protected Map digests = new HashMap(); protected SecureRandom rand; /** * base constructor */ protected CMSSignedGenerator() { this(new SecureRandom()); } /** * constructor allowing specific source of randomness * @param rand instance of SecureRandom to use */ protected CMSSignedGenerator( SecureRandom rand) { this.rand = rand; } protected String getEncOID( PrivateKey key, String digestOID) { String encOID = null; if (key instanceof RSAPrivateKey || "RSA".equalsIgnoreCase(key.getAlgorithm())) { encOID = ENCRYPTION_RSA; } else if (key instanceof DSAPrivateKey || "DSA".equalsIgnoreCase(key.getAlgorithm())) { encOID = ENCRYPTION_DSA; if (!digestOID.equals(DIGEST_SHA1)) { throw new IllegalArgumentException("can't mix DSA with anything but SHA1"); } } else if ("ECDSA".equalsIgnoreCase(key.getAlgorithm()) || "EC".equalsIgnoreCase(key.getAlgorithm())) { encOID = (String)EC_ALGORITHMS.get(digestOID); if (encOID == null) { throw new IllegalArgumentException("can't mix ECDSA with anything but SHA family digests"); } } else if (key instanceof GOST3410PrivateKey || "GOST3410".equalsIgnoreCase(key.getAlgorithm())) { encOID = ENCRYPTION_GOST3410; } else if ("ECGOST3410".equalsIgnoreCase(key.getAlgorithm())) { encOID = ENCRYPTION_ECGOST3410; } return encOID; } protected Map getBaseParameters(DERObjectIdentifier contentType, AlgorithmIdentifier digAlgId, byte[] hash) { Map param = new HashMap(); param.put(CMSAttributeTableGenerator.CONTENT_TYPE, contentType); param.put(CMSAttributeTableGenerator.DIGEST_ALGORITHM_IDENTIFIER, digAlgId); param.put(CMSAttributeTableGenerator.DIGEST, hash.clone()); return param; } protected ASN1Set getAttributeSet( AttributeTable attr) { if (attr != null) { return new DERSet(attr.toASN1EncodableVector()); } return null; } /** * add the certificates and CRLs contained in the given CertStore * to the pool that will be included in the encoded signature block. *

    * Note: this assumes the CertStore will support null in the get * methods. * @param certStore CertStore containing the public key certificates and CRLs * @throws org.bouncycastle.jce.cert.CertStoreException if an issue occurs processing the CertStore * @throws CMSException if an issue occurse transforming data from the CertStore into the message * @deprecated use addCertificates and addCRLs */ public void addCertificatesAndCRLs( CertStore certStore) throws CertStoreException, CMSException { certs.addAll(CMSUtils.getCertificatesFromStore(certStore)); crls.addAll(CMSUtils.getCRLsFromStore(certStore)); } public void addCertificates( Store certStore) throws CMSException { certs.addAll(CMSUtils.getCertificatesFromStore(certStore)); } public void addCRLs( Store crlStore) throws CMSException { crls.addAll(CMSUtils.getCRLsFromStore(crlStore)); } public void addAttributeCertificates( Store attrStore) throws CMSException { certs.addAll(CMSUtils.getAttributeCertificatesFromStore(attrStore)); } /** * Add the attribute certificates contained in the passed in store to the * generator. * * @param store a store of Version 2 attribute certificates * @throws CMSException if an error occurse processing the store. * @deprecated use basic Store method */ public void addAttributeCertificates( X509Store store) throws CMSException { try { for (Iterator it = store.getMatches(null).iterator(); it.hasNext();) { X509AttributeCertificate attrCert = (X509AttributeCertificate)it.next(); certs.add(new DERTaggedObject(false, 2, AttributeCertificate.getInstance(ASN1Primitive.fromByteArray(attrCert.getEncoded())))); } } catch (IllegalArgumentException e) { throw new CMSException("error processing attribute certs", e); } catch (IOException e) { throw new CMSException("error processing attribute certs", e); } } /** * Add a store of precalculated signers to the generator. * * @param signerStore store of signers */ public void addSigners( SignerInformationStore signerStore) { Iterator it = signerStore.getSigners().iterator(); while (it.hasNext()) { _signers.add(it.next()); } } public void addSignerInfoGenerator(SignerInfoGenerator infoGen) { signerGens.add(infoGen); } /** * Return a map of oids and byte arrays representing the digests calculated on the content during * the last generate. * * @return a map of oids (as String objects) and byte[] representing digests. */ public Map getGeneratedDigests() { return new HashMap(digests); } } bouncycastle-1.49.orig/jdk1.1/org/bouncycastle/cms/CMSAbsentContent.java0000644000175000017500000000167211731466725025464 0ustar ebourgebourgpackage org.bouncycastle.cms; import java.io.IOException; import java.io.InputStream; import java.io.OutputStream; import org.bouncycastle.asn1.ASN1ObjectIdentifier; import org.bouncycastle.asn1.cms.CMSObjectIdentifiers; /** * a class representing null or absent content. */ public class CMSAbsentContent implements CMSTypedData, CMSReadable { private ASN1ObjectIdentifier type; public CMSAbsentContent() { this(new ASN1ObjectIdentifier(CMSObjectIdentifiers.data.getId())); } public CMSAbsentContent( ASN1ObjectIdentifier type) { this.type = type; } public InputStream getInputStream() { return null; } public void write(OutputStream zOut) throws IOException, CMSException { // do nothing } public Object getContent() { return null; } public ASN1ObjectIdentifier getContentType() { return type; } } bouncycastle-1.49.orig/jdk1.1/org/bouncycastle/cms/SignerInfoGenerator.java0000644000175000017500000002162312105031243026235 0ustar ebourgebourgpackage org.bouncycastle.cms; import java.io.IOException; import java.io.OutputStream; import java.util.Collections; import java.util.HashMap; import java.util.Map; import org.bouncycastle.asn1.ASN1Encoding; import org.bouncycastle.asn1.ASN1Integer; import org.bouncycastle.asn1.ASN1ObjectIdentifier; import org.bouncycastle.asn1.ASN1Set; import org.bouncycastle.asn1.DEROctetString; import org.bouncycastle.asn1.DERSet; import org.bouncycastle.asn1.cms.AttributeTable; import org.bouncycastle.asn1.cms.SignerIdentifier; import org.bouncycastle.asn1.cms.SignerInfo; import org.bouncycastle.asn1.x509.AlgorithmIdentifier; import org.bouncycastle.cert.X509CertificateHolder; import org.bouncycastle.operator.ContentSigner; import org.bouncycastle.operator.DefaultDigestAlgorithmIdentifierFinder; import org.bouncycastle.operator.DigestAlgorithmIdentifierFinder; import org.bouncycastle.operator.DigestCalculator; import org.bouncycastle.operator.DigestCalculatorProvider; import org.bouncycastle.operator.OperatorCreationException; import org.bouncycastle.util.io.TeeOutputStream; public class SignerInfoGenerator { private SignerIdentifier signerIdentifier; private CMSAttributeTableGenerator sAttrGen; private CMSAttributeTableGenerator unsAttrGen; private ContentSigner signer; private DigestCalculator digester; private DigestAlgorithmIdentifierFinder digAlgFinder = new DefaultDigestAlgorithmIdentifierFinder(); private CMSSignatureEncryptionAlgorithmFinder sigEncAlgFinder; private byte[] calculatedDigest = null; private X509CertificateHolder certHolder; SignerInfoGenerator( SignerIdentifier signerIdentifier, ContentSigner signer, DigestCalculatorProvider digesterProvider, CMSSignatureEncryptionAlgorithmFinder sigEncAlgFinder) throws OperatorCreationException { this(signerIdentifier, signer, digesterProvider, sigEncAlgFinder, false); } SignerInfoGenerator( SignerIdentifier signerIdentifier, ContentSigner signer, DigestCalculatorProvider digesterProvider, CMSSignatureEncryptionAlgorithmFinder sigEncAlgFinder, boolean isDirectSignature) throws OperatorCreationException { this.signerIdentifier = signerIdentifier; this.signer = signer; if (digesterProvider != null) { this.digester = digesterProvider.get(digAlgFinder.find(signer.getAlgorithmIdentifier())); } else { this.digester = null; } if (isDirectSignature) { this.sAttrGen = null; this.unsAttrGen = null; } else { this.sAttrGen = new DefaultSignedAttributeTableGenerator(); this.unsAttrGen = null; } this.sigEncAlgFinder = sigEncAlgFinder; } public SignerInfoGenerator( SignerInfoGenerator original, CMSAttributeTableGenerator sAttrGen, CMSAttributeTableGenerator unsAttrGen) { this.signerIdentifier = original.signerIdentifier; this.signer = original.signer; this.digester = original.digester; this.sigEncAlgFinder = original.sigEncAlgFinder; this.sAttrGen = sAttrGen; this.unsAttrGen = unsAttrGen; } SignerInfoGenerator( SignerIdentifier signerIdentifier, ContentSigner signer, DigestCalculatorProvider digesterProvider, CMSSignatureEncryptionAlgorithmFinder sigEncAlgFinder, CMSAttributeTableGenerator sAttrGen, CMSAttributeTableGenerator unsAttrGen) throws OperatorCreationException { this.signerIdentifier = signerIdentifier; this.signer = signer; if (digesterProvider != null) { this.digester = digesterProvider.get(digAlgFinder.find(signer.getAlgorithmIdentifier())); } else { this.digester = null; } this.sAttrGen = sAttrGen; this.unsAttrGen = unsAttrGen; this.sigEncAlgFinder = sigEncAlgFinder; } public SignerIdentifier getSID() { return signerIdentifier; } public ASN1Integer getGeneratedVersion() { return new ASN1Integer(signerIdentifier.isTagged() ? 3 : 1); } public boolean hasAssociatedCertificate() { return certHolder != null; } public X509CertificateHolder getAssociatedCertificate() { return certHolder; } public AlgorithmIdentifier getDigestAlgorithm() { if (digester != null) { return digester.getAlgorithmIdentifier(); } return digAlgFinder.find(signer.getAlgorithmIdentifier()); } public OutputStream getCalculatingOutputStream() { if (digester != null) { if (sAttrGen == null) { return new TeeOutputStream(digester.getOutputStream(), signer.getOutputStream()); } return digester.getOutputStream(); } else { return signer.getOutputStream(); } } public SignerInfo generate(ASN1ObjectIdentifier contentType) throws CMSException { try { /* RFC 3852 5.4 * The result of the message digest calculation process depends on * whether the signedAttrs field is present. When the field is absent, * the result is just the message digest of the content as described * * above. When the field is present, however, the result is the message * digest of the complete DER encoding of the SignedAttrs value * contained in the signedAttrs field. */ ASN1Set signedAttr = null; AlgorithmIdentifier digestAlg = null; if (sAttrGen != null) { digestAlg = digester.getAlgorithmIdentifier(); calculatedDigest = digester.getDigest(); Map parameters = getBaseParameters(contentType, digester.getAlgorithmIdentifier(), calculatedDigest); AttributeTable signed = sAttrGen.getAttributes(new HashMap(parameters)); signedAttr = getAttributeSet(signed); // sig must be composed from the DER encoding. OutputStream sOut = signer.getOutputStream(); sOut.write(signedAttr.getEncoded(ASN1Encoding.DER)); sOut.close(); } else { if (digester != null) { digestAlg = digester.getAlgorithmIdentifier(); calculatedDigest = digester.getDigest(); } else { digestAlg = digAlgFinder.find(signer.getAlgorithmIdentifier()); calculatedDigest = null; } } byte[] sigBytes = signer.getSignature(); ASN1Set unsignedAttr = null; if (unsAttrGen != null) { Map parameters = getBaseParameters(contentType, digestAlg, calculatedDigest); parameters.put(CMSAttributeTableGenerator.SIGNATURE, sigBytes.clone()); AttributeTable unsigned = unsAttrGen.getAttributes(new HashMap(parameters)); unsignedAttr = getAttributeSet(unsigned); } AlgorithmIdentifier digestEncryptionAlgorithm = sigEncAlgFinder.findEncryptionAlgorithm(signer.getAlgorithmIdentifier()); return new SignerInfo(signerIdentifier, digestAlg, signedAttr, digestEncryptionAlgorithm, new DEROctetString(sigBytes), unsignedAttr); } catch (IOException e) { throw new CMSException("encoding error.", e); } } void setAssociatedCertificate(X509CertificateHolder certHolder) { this.certHolder = certHolder; } private ASN1Set getAttributeSet( AttributeTable attr) { if (attr != null) { return new DERSet(attr.toASN1EncodableVector()); } return null; } private Map getBaseParameters(ASN1ObjectIdentifier contentType, AlgorithmIdentifier digAlgId, byte[] hash) { Map param = new HashMap(); if (contentType != null) { param.put(CMSAttributeTableGenerator.CONTENT_TYPE, contentType); } param.put(CMSAttributeTableGenerator.DIGEST_ALGORITHM_IDENTIFIER, digAlgId); param.put(CMSAttributeTableGenerator.DIGEST, hash.clone()); return param; } public byte[] getCalculatedDigest() { if (calculatedDigest != null) { return (byte[])calculatedDigest.clone(); } return null; } public CMSAttributeTableGenerator getSignedAttributeTableGenerator() { return sAttrGen; } public CMSAttributeTableGenerator getUnsignedAttributeTableGenerator() { return unsAttrGen; } } bouncycastle-1.49.orig/jdk1.1/org/bouncycastle/cms/CMSEnvelopedGenerator.java0000644000175000017500000003752611731466725026514 0ustar ebourgebourgpackage org.bouncycastle.cms; import java.io.IOException; import java.security.AlgorithmParameters; import java.security.InvalidKeyException; import java.security.NoSuchAlgorithmException; import java.security.NoSuchProviderException; import java.security.PrivateKey; import java.security.Provider; import java.security.PublicKey; import java.security.SecureRandom; import java.security.cert.CertificateEncodingException; import java.security.cert.X509Certificate; import java.util.ArrayList; import java.util.Collection; import java.util.Iterator; import java.util.List; import javax.crypto.SecretKey; import org.bouncycastle.asn1.ASN1Encodable; import org.bouncycastle.asn1.ASN1ObjectIdentifier; import org.bouncycastle.asn1.ASN1Primitive; import org.bouncycastle.asn1.DERNull; import org.bouncycastle.asn1.cms.KEKIdentifier; import org.bouncycastle.asn1.cms.OriginatorInfo; import org.bouncycastle.asn1.kisa.KISAObjectIdentifiers; import org.bouncycastle.asn1.nist.NISTObjectIdentifiers; import org.bouncycastle.asn1.ntt.NTTObjectIdentifiers; import org.bouncycastle.asn1.pkcs.PKCSObjectIdentifiers; import org.bouncycastle.asn1.x509.AlgorithmIdentifier; import org.bouncycastle.asn1.x9.X9ObjectIdentifiers; import org.bouncycastle.cms.jcajce.JceKEKRecipientInfoGenerator; import org.bouncycastle.cms.jcajce.JceKeyAgreeRecipientInfoGenerator; import org.bouncycastle.cms.jcajce.JceKeyTransRecipientInfoGenerator; import org.bouncycastle.cms.jcajce.JcePasswordRecipientInfoGenerator; /** * General class for generating a CMS enveloped-data message. */ public class CMSEnvelopedGenerator { public static final String DES_EDE3_CBC = PKCSObjectIdentifiers.des_EDE3_CBC.getId(); public static final String RC2_CBC = PKCSObjectIdentifiers.RC2_CBC.getId(); public static final String IDEA_CBC = "1.3.6.1.4.1.188.7.1.1.2"; public static final String CAST5_CBC = "1.2.840.113533.7.66.10"; public static final String AES128_CBC = NISTObjectIdentifiers.id_aes128_CBC.getId(); public static final String AES192_CBC = NISTObjectIdentifiers.id_aes192_CBC.getId(); public static final String AES256_CBC = NISTObjectIdentifiers.id_aes256_CBC.getId(); public static final String CAMELLIA128_CBC = NTTObjectIdentifiers.id_camellia128_cbc.getId(); public static final String CAMELLIA192_CBC = NTTObjectIdentifiers.id_camellia192_cbc.getId(); public static final String CAMELLIA256_CBC = NTTObjectIdentifiers.id_camellia256_cbc.getId(); public static final String SEED_CBC = KISAObjectIdentifiers.id_seedCBC.getId(); public static final String DES_EDE3_WRAP = PKCSObjectIdentifiers.id_alg_CMS3DESwrap.getId(); public static final String AES128_WRAP = NISTObjectIdentifiers.id_aes128_wrap.getId(); public static final String AES192_WRAP = NISTObjectIdentifiers.id_aes192_wrap.getId(); public static final String AES256_WRAP = NISTObjectIdentifiers.id_aes256_wrap.getId(); public static final String CAMELLIA128_WRAP = NTTObjectIdentifiers.id_camellia128_wrap.getId(); public static final String CAMELLIA192_WRAP = NTTObjectIdentifiers.id_camellia192_wrap.getId(); public static final String CAMELLIA256_WRAP = NTTObjectIdentifiers.id_camellia256_wrap.getId(); public static final String SEED_WRAP = KISAObjectIdentifiers.id_npki_app_cmsSeed_wrap.getId(); public static final String ECDH_SHA1KDF = X9ObjectIdentifiers.dhSinglePass_stdDH_sha1kdf_scheme.getId(); public static final String ECMQV_SHA1KDF = X9ObjectIdentifiers.mqvSinglePass_sha1kdf_scheme.getId(); List oldRecipientInfoGenerators = new ArrayList(); List recipientInfoGenerators = new ArrayList(); protected CMSAttributeTableGenerator unprotectedAttributeGenerator = null; SecureRandom rand; protected OriginatorInfo originatorInfo; /** * base constructor */ public CMSEnvelopedGenerator() { this(new SecureRandom()); } /** * constructor allowing specific source of randomness * @param rand instance of SecureRandom to use */ public CMSEnvelopedGenerator( SecureRandom rand) { this.rand = rand; } public void setUnprotectedAttributeGenerator(CMSAttributeTableGenerator unprotectedAttributeGenerator) { this.unprotectedAttributeGenerator = unprotectedAttributeGenerator; } public void setOriginatorInfo(OriginatorInformation originatorInfo) { this.originatorInfo = originatorInfo.toASN1Structure(); } /** * add a recipient. * * @deprecated use the addRecipientGenerator and JceKeyTransRecipientInfoGenerator * @param cert recipient's public key certificate * @exception IllegalArgumentException if there is a problem with the certificate */ public void addKeyTransRecipient( X509Certificate cert) throws IllegalArgumentException { try { oldRecipientInfoGenerators.add(new JceKeyTransRecipientInfoGenerator(cert)); } catch (CertificateEncodingException e) { throw new IllegalArgumentException("unable to encode certificate: " + e.getMessage()); } } /** * add a recipient * * @deprecated use the addRecipientGenerator and JceKeyTransRecipientInfoGenerator * @param key the public key used by the recipient * @param subKeyId the identifier for the recipient's public key * @exception IllegalArgumentException if there is a problem with the key */ public void addKeyTransRecipient( PublicKey key, byte[] subKeyId) throws IllegalArgumentException { oldRecipientInfoGenerators.add(new JceKeyTransRecipientInfoGenerator(subKeyId, key)); } /** * add a KEK recipient. * * @deprecated use the addRecipientGenerator and JceKEKRecipientInfoGenerator * @param key the secret key to use for wrapping * @param keyIdentifier the byte string that identifies the key */ public void addKEKRecipient( SecretKey key, byte[] keyIdentifier) { addKEKRecipient(key, new KEKIdentifier(keyIdentifier, null, null)); } /** * add a KEK recipient. * * @deprecated use the addRecipientGenerator and JceKEKRecipientInfoGenerator * @param key the secret key to use for wrapping * @param kekIdentifier a KEKIdentifier structure (identifies the key) */ public void addKEKRecipient( SecretKey key, KEKIdentifier kekIdentifier) { oldRecipientInfoGenerators.add(new JceKEKRecipientInfoGenerator(kekIdentifier, key)); } /** * @deprecated use addRecipientGenerator and JcePasswordRecipientInfoGenerator * @param pbeKey PBE key * @param kekAlgorithmOid key encryption algorithm to use. */ public void addPasswordRecipient( CMSPBEKey pbeKey, String kekAlgorithmOid) { oldRecipientInfoGenerators.add(new JcePasswordRecipientInfoGenerator(new ASN1ObjectIdentifier(kekAlgorithmOid), pbeKey.getPassword()) .setSaltAndIterationCount(pbeKey.getSalt(), pbeKey.getIterationCount()) .setPasswordConversionScheme((pbeKey instanceof PKCS5Scheme2UTF8PBEKey) ? PasswordRecipient.PKCS5_SCHEME2_UTF8 : PasswordRecipient.PKCS5_SCHEME2)); } /** * Add a key agreement based recipient. * * @deprecated use the addRecipientGenerator and JceKeyAgreeRecipientInfoGenerator * @param agreementAlgorithm key agreement algorithm to use. * @param senderPrivateKey private key to initialise sender side of agreement with. * @param senderPublicKey sender public key to include with message. * @param recipientCert recipient's public key certificate. * @param cekWrapAlgorithm OID for key wrapping algorithm to use. * @param provider provider to use for the agreement calculation. * @exception NoSuchProviderException if the specified provider cannot be found * @exception NoSuchAlgorithmException if the algorithm requested cannot be found * @exception InvalidKeyException if the keys are inappropriate for the algorithm specified */ public void addKeyAgreementRecipient( String agreementAlgorithm, PrivateKey senderPrivateKey, PublicKey senderPublicKey, X509Certificate recipientCert, String cekWrapAlgorithm, String provider) throws NoSuchProviderException, NoSuchAlgorithmException, InvalidKeyException { addKeyAgreementRecipient(agreementAlgorithm, senderPrivateKey, senderPublicKey, recipientCert, cekWrapAlgorithm, CMSUtils.getProvider(provider)); } /** * Add a key agreement based recipient. * * @deprecated use the addRecipientGenerator and JceKeyAgreeRecipientInfoGenerator * @param agreementAlgorithm key agreement algorithm to use. * @param senderPrivateKey private key to initialise sender side of agreement with. * @param senderPublicKey sender public key to include with message. * @param recipientCert recipient's public key certificate. * @param cekWrapAlgorithm OID for key wrapping algorithm to use. * @param provider provider to use for the agreement calculation. * @exception NoSuchAlgorithmException if the algorithm requested cannot be found * @exception InvalidKeyException if the keys are inappropriate for the algorithm specified */ public void addKeyAgreementRecipient( String agreementAlgorithm, PrivateKey senderPrivateKey, PublicKey senderPublicKey, X509Certificate recipientCert, String cekWrapAlgorithm, Provider provider) throws NoSuchAlgorithmException, InvalidKeyException { List recipients = new ArrayList(); recipients.add(recipientCert); addKeyAgreementRecipients(agreementAlgorithm, senderPrivateKey, senderPublicKey, recipients, cekWrapAlgorithm, provider); } /** * Add multiple key agreement based recipients (sharing a single KeyAgreeRecipientInfo structure). * * @deprecated use the addRecipientGenerator and JceKeyAgreeRecipientInfoGenerator * @param agreementAlgorithm key agreement algorithm to use. * @param senderPrivateKey private key to initialise sender side of agreement with. * @param senderPublicKey sender public key to include with message. * @param recipientCerts recipients' public key certificates. * @param cekWrapAlgorithm OID for key wrapping algorithm to use. * @param provider provider to use for the agreement calculation. * @exception NoSuchAlgorithmException if the algorithm requested cannot be found * @exception InvalidKeyException if the keys are inappropriate for the algorithm specified */ public void addKeyAgreementRecipients( String agreementAlgorithm, PrivateKey senderPrivateKey, PublicKey senderPublicKey, Collection recipientCerts, String cekWrapAlgorithm, String provider) throws NoSuchProviderException, NoSuchAlgorithmException, InvalidKeyException { addKeyAgreementRecipients(agreementAlgorithm, senderPrivateKey, senderPublicKey, recipientCerts, cekWrapAlgorithm, CMSUtils.getProvider(provider)); } /** * Add multiple key agreement based recipients (sharing a single KeyAgreeRecipientInfo structure). * * @deprecated use the addRecipientGenerator and JceKeyAgreeRecipientInfoGenerator * @param agreementAlgorithm key agreement algorithm to use. * @param senderPrivateKey private key to initialise sender side of agreement with. * @param senderPublicKey sender public key to include with message. * @param recipientCerts recipients' public key certificates. * @param cekWrapAlgorithm OID for key wrapping algorithm to use. * @param provider provider to use for the agreement calculation. * @exception NoSuchAlgorithmException if the algorithm requested cannot be found * @exception InvalidKeyException if the keys are inappropriate for the algorithm specified */ public void addKeyAgreementRecipients( String agreementAlgorithm, PrivateKey senderPrivateKey, PublicKey senderPublicKey, Collection recipientCerts, String cekWrapAlgorithm, Provider provider) throws NoSuchAlgorithmException, InvalidKeyException { JceKeyAgreeRecipientInfoGenerator recipientInfoGenerator = new JceKeyAgreeRecipientInfoGenerator(new ASN1ObjectIdentifier(agreementAlgorithm), senderPrivateKey, senderPublicKey, new ASN1ObjectIdentifier(cekWrapAlgorithm)).setProvider(provider); for (Iterator it = recipientCerts.iterator(); it.hasNext();) { try { recipientInfoGenerator.addRecipient((X509Certificate)it.next()); } catch (CertificateEncodingException e) { throw new IllegalArgumentException("unable to encode certificate: " + e.getMessage()); } } oldRecipientInfoGenerators.add(recipientInfoGenerator); } /** * Add a generator to produce the recipient info required. * * @param recipientGenerator a generator of a recipient info object. */ public void addRecipientInfoGenerator(RecipientInfoGenerator recipientGenerator) { recipientInfoGenerators.add(recipientGenerator); } protected AlgorithmIdentifier getAlgorithmIdentifier(String encryptionOID, AlgorithmParameters params) throws IOException { ASN1Encodable asn1Params; if (params != null) { asn1Params = ASN1Primitive.fromByteArray(params.getEncoded("ASN.1")); } else { asn1Params = DERNull.INSTANCE; } return new AlgorithmIdentifier( new ASN1ObjectIdentifier(encryptionOID), asn1Params); } protected void convertOldRecipients(SecureRandom rand, Provider provider) { for (Iterator it = oldRecipientInfoGenerators.iterator(); it.hasNext();) { Object recipient = it.next(); if (recipient instanceof JceKeyTransRecipientInfoGenerator) { JceKeyTransRecipientInfoGenerator recip = (JceKeyTransRecipientInfoGenerator)recipient; if (provider != null) { recip.setProvider(provider); } recipientInfoGenerators.add(recip); } else if (recipient instanceof KEKRecipientInfoGenerator) { JceKEKRecipientInfoGenerator recip = (JceKEKRecipientInfoGenerator)recipient; if (provider != null) { recip.setProvider(provider); } recip.setSecureRandom(rand); recipientInfoGenerators.add(recip); } else if (recipient instanceof JcePasswordRecipientInfoGenerator) { JcePasswordRecipientInfoGenerator recip = (JcePasswordRecipientInfoGenerator)recipient; if (provider != null) { recip.setProvider(provider); } recip.setSecureRandom(rand); recipientInfoGenerators.add(recip); } else if (recipient instanceof JceKeyAgreeRecipientInfoGenerator) { JceKeyAgreeRecipientInfoGenerator recip = (JceKeyAgreeRecipientInfoGenerator)recipient; if (provider != null) { recip.setProvider(provider); } recip.setSecureRandom(rand); recipientInfoGenerators.add(recip); } } oldRecipientInfoGenerators.clear(); } } bouncycastle-1.49.orig/jdk1.1/org/bouncycastle/cms/CMSSignedDataParser.java0000644000175000017500000010175011731466725026073 0ustar ebourgebourgpackage org.bouncycastle.cms; import java.io.ByteArrayInputStream; import java.io.IOException; import java.io.InputStream; import java.io.OutputStream; import java.security.NoSuchAlgorithmException; import java.security.NoSuchProviderException; import java.security.Provider; import java.security.cert.CertStore; import java.security.cert.CertStoreException; import java.util.ArrayList; import java.util.Enumeration; import java.util.HashMap; import java.util.Iterator; import java.util.List; import java.util.Map; import org.bouncycastle.asn1.ASN1Encodable; import org.bouncycastle.asn1.ASN1EncodableVector; import org.bouncycastle.asn1.ASN1Generator; import org.bouncycastle.asn1.ASN1ObjectIdentifier; import org.bouncycastle.asn1.ASN1OctetStringParser; import org.bouncycastle.asn1.ASN1Primitive; import org.bouncycastle.asn1.ASN1Sequence; import org.bouncycastle.asn1.ASN1SequenceParser; import org.bouncycastle.asn1.ASN1Set; import org.bouncycastle.asn1.ASN1SetParser; import org.bouncycastle.asn1.ASN1StreamParser; import org.bouncycastle.asn1.ASN1TaggedObject; import org.bouncycastle.asn1.BERSequenceGenerator; import org.bouncycastle.asn1.BERSetParser; import org.bouncycastle.asn1.BERTaggedObject; import org.bouncycastle.asn1.BERTags; import org.bouncycastle.asn1.DERSet; import org.bouncycastle.asn1.DERTaggedObject; import org.bouncycastle.asn1.cms.CMSObjectIdentifiers; import org.bouncycastle.asn1.cms.ContentInfoParser; import org.bouncycastle.asn1.cms.SignedDataParser; import org.bouncycastle.asn1.cms.SignerInfo; import org.bouncycastle.asn1.x509.AlgorithmIdentifier; import org.bouncycastle.asn1.x509.AttributeCertificate; import org.bouncycastle.asn1.x509.CertificateList; import org.bouncycastle.asn1.x509.Certificate; import org.bouncycastle.cert.X509AttributeCertificateHolder; import org.bouncycastle.cert.X509CRLHolder; import org.bouncycastle.cert.X509CertificateHolder; import org.bouncycastle.operator.DigestCalculator; import org.bouncycastle.operator.DigestCalculatorProvider; import org.bouncycastle.operator.OperatorCreationException; import org.bouncycastle.operator.bc.BcDigestCalculatorProvider; import org.bouncycastle.util.CollectionStore; import org.bouncycastle.util.Store; import org.bouncycastle.util.io.Streams; import org.bouncycastle.x509.NoSuchStoreException; import org.bouncycastle.x509.X509Store; /** * Parsing class for an CMS Signed Data object from an input stream. *

    * Note: that because we are in a streaming mode only one signer can be tried and it is important * that the methods on the parser are called in the appropriate order. *

    *

    * A simple example of usage for an encapsulated signature. *

    *

    * Two notes: first, in the example below the validity of * the certificate isn't verified, just the fact that one of the certs * matches the given signer, and, second, because we are in a streaming * mode the order of the operations is important. *

    *
     *      CMSSignedDataParser     sp = new CMSSignedDataParser(new JcaDigestCalculatorProviderBuilder().setProvider("BC").build(), encapSigData);
     *
     *      sp.getSignedContent().drain();
     *
     *      Store                   certStore = sp.getCertificates();
     *      SignerInformationStore  signers = sp.getSignerInfos();
     *      
     *      Collection              c = signers.getSigners();
     *      Iterator                it = c.iterator();
     *
     *      while (it.hasNext())
     *      {
     *          SignerInformation   signer = (SignerInformation)it.next();
     *          Collection          certCollection = certStore.getMatches(signer.getSID());
     *
     *          Iterator        certIt = certCollection.iterator();
     *          X509CertificateHolder cert = (X509CertificateHolder)certIt.next();
     *
     *          System.out.println("verify returns: " + signer.verify(new JcaSimpleSignerInfoVerifierBuilder().setProvider("BC").build(cert)));
     *      }
     * 
    * Note also: this class does not introduce buffering - if you are processing large files you should create * the parser with: *
     *          CMSSignedDataParser     ep = new CMSSignedDataParser(new BufferedInputStream(encapSigData, bufSize));
     *  
    * where bufSize is a suitably large buffer size. */ public class CMSSignedDataParser extends CMSContentInfoParser { private static final CMSSignedHelper HELPER = CMSSignedHelper.INSTANCE; private SignedDataParser _signedData; private ASN1ObjectIdentifier _signedContentType; private CMSTypedStream _signedContent; private Map digests; private SignerInformationStore _signerInfoStore; private X509Store _attributeStore; private ASN1Set _certSet, _crlSet; private boolean _isCertCrlParsed; private X509Store _certificateStore; private X509Store _crlStore; /** * @deprecated use method taking a DigestCalculatorProvider */ public CMSSignedDataParser( byte[] sigBlock) throws CMSException { this(createDefaultDigestProvider(), new ByteArrayInputStream(sigBlock)); } public CMSSignedDataParser( DigestCalculatorProvider digestCalculatorProvider, byte[] sigBlock) throws CMSException { this(digestCalculatorProvider, new ByteArrayInputStream(sigBlock)); } /** * @deprecated use method taking digest calculator provider. * @param signedContent * @param sigBlock * @throws CMSException */ public CMSSignedDataParser( CMSTypedStream signedContent, byte[] sigBlock) throws CMSException { this(createDefaultDigestProvider(), signedContent, new ByteArrayInputStream(sigBlock)); } public CMSSignedDataParser( DigestCalculatorProvider digestCalculatorProvider, CMSTypedStream signedContent, byte[] sigBlock) throws CMSException { this(digestCalculatorProvider, signedContent, new ByteArrayInputStream(sigBlock)); } private static DigestCalculatorProvider createDefaultDigestProvider() throws CMSException { return new BcDigestCalculatorProvider(); } /** * base constructor - with encapsulated content * * @deprecated use method taking a DigestCalculatorProvider */ public CMSSignedDataParser( InputStream sigData) throws CMSException { this(createDefaultDigestProvider(), null, sigData); } /** * base constructor - with encapsulated content */ public CMSSignedDataParser( DigestCalculatorProvider digestCalculatorProvider, InputStream sigData) throws CMSException { this(digestCalculatorProvider, null, sigData); } /** * base constructor * * @param signedContent the content that was signed. * @param sigData the signature object stream. * * * @deprecated use method taking a DigestCalculatorProvider */ public CMSSignedDataParser( CMSTypedStream signedContent, InputStream sigData) throws CMSException { this(createDefaultDigestProvider(), signedContent, sigData); } /** * base constructor * * @param digestCalculatorProvider for generating accumulating digests * @param signedContent the content that was signed. * @param sigData the signature object stream. */ public CMSSignedDataParser( DigestCalculatorProvider digestCalculatorProvider, CMSTypedStream signedContent, InputStream sigData) throws CMSException { super(sigData); try { _signedContent = signedContent; _signedData = SignedDataParser.getInstance(_contentInfo.getContent(BERTags.SEQUENCE)); digests = new HashMap(); ASN1SetParser digAlgs = _signedData.getDigestAlgorithms(); ASN1Encodable o; while ((o = digAlgs.readObject()) != null) { AlgorithmIdentifier algId = AlgorithmIdentifier.getInstance(o); try { DigestCalculator calculator = digestCalculatorProvider.get(algId); if (calculator != null) { this.digests.put(algId.getAlgorithm(), calculator); } } catch (OperatorCreationException e) { // ignore } } // // If the message is simply a certificate chain message getContent() may return null. // ContentInfoParser cont = _signedData.getEncapContentInfo(); ASN1OctetStringParser octs = (ASN1OctetStringParser) cont.getContent(BERTags.OCTET_STRING); if (octs != null) { CMSTypedStream ctStr = new CMSTypedStream( cont.getContentType().getId(), octs.getOctetStream()); if (_signedContent == null) { _signedContent = ctStr; } else { // // content passed in, need to read past empty encapsulated content info object if present // ctStr.drain(); } } if (signedContent == null) { _signedContentType = cont.getContentType(); } else { _signedContentType = _signedContent.getContentType(); } } catch (IOException e) { throw new CMSException("io exception: " + e.getMessage(), e); } if (digests.isEmpty()) { throw new CMSException("no digests could be created for message."); } } /** * Return the version number for the SignedData object * * @return the version number */ public int getVersion() { return _signedData.getVersion().getValue().intValue(); } /** * return the collection of signers that are associated with the * signatures for the message. * @throws CMSException */ public SignerInformationStore getSignerInfos() throws CMSException { if (_signerInfoStore == null) { populateCertCrlSets(); List signerInfos = new ArrayList(); Map hashes = new HashMap(); Iterator it = digests.keySet().iterator(); while (it.hasNext()) { Object digestKey = it.next(); hashes.put(digestKey, ((DigestCalculator)digests.get(digestKey)).getDigest()); } try { ASN1SetParser s = _signedData.getSignerInfos(); ASN1Encodable o; while ((o = s.readObject()) != null) { SignerInfo info = SignerInfo.getInstance(o.toASN1Primitive()); byte[] hash = (byte[])hashes.get(info.getDigestAlgorithm().getAlgorithm()); signerInfos.add(new SignerInformation(info, _signedContentType, null, hash)); } } catch (IOException e) { throw new CMSException("io exception: " + e.getMessage(), e); } _signerInfoStore = new SignerInformationStore(signerInfos); } return _signerInfoStore; } /** * return a X509Store containing the attribute certificates, if any, contained * in this message. * * @param type type of store to create * @param provider name of provider to use * @return a store of attribute certificates * @exception NoSuchProviderException if the provider requested isn't available. * @exception org.bouncycastle.x509.NoSuchStoreException if the store type isn't available. * @exception CMSException if a general exception prevents creation of the X509Store */ public X509Store getAttributeCertificates( String type, String provider) throws NoSuchStoreException, NoSuchProviderException, CMSException { return getAttributeCertificates(type, CMSUtils.getProvider(provider)); } /** * return a X509Store containing the attribute certificates, if any, contained * in this message. * * @param type type of store to create * @param provider provider to use * @return a store of attribute certificates * @exception org.bouncycastle.x509.NoSuchStoreException if the store type isn't available. * @exception CMSException if a general exception prevents creation of the X509Store */ public X509Store getAttributeCertificates( String type, Provider provider) throws NoSuchStoreException, CMSException { if (_attributeStore == null) { populateCertCrlSets(); _attributeStore = HELPER.createAttributeStore(type, provider, _certSet); } return _attributeStore; } /** * return a X509Store containing the public key certificates, if any, contained * in this message. * * @param type type of store to create * @param provider provider to use * @return a store of public key certificates * @exception NoSuchProviderException if the provider requested isn't available. * @exception NoSuchStoreException if the store type isn't available. * @exception CMSException if a general exception prevents creation of the X509Store * @deprecated use getCertificates() */ public X509Store getCertificates( String type, String provider) throws NoSuchStoreException, NoSuchProviderException, CMSException { return getCertificates(type, CMSUtils.getProvider(provider)); } /** * return a X509Store containing the public key certificates, if any, contained * in this message. * * @param type type of store to create * @param provider provider to use * @return a store of public key certificates * @exception NoSuchStoreException if the store type isn't available. * @exception CMSException if a general exception prevents creation of the X509Store * @deprecated use getCertificates() */ public X509Store getCertificates( String type, Provider provider) throws NoSuchStoreException, CMSException { if (_certificateStore == null) { populateCertCrlSets(); _certificateStore = HELPER.createCertificateStore(type, provider, _certSet); } return _certificateStore; } /** * return a X509Store containing CRLs, if any, contained * in this message. * * @param type type of store to create * @param provider name of provider to use * @return a store of CRLs * @exception NoSuchProviderException if the provider requested isn't available. * @exception NoSuchStoreException if the store type isn't available. * @exception CMSException if a general exception prevents creation of the X509Store * @deprecated use getCRLs() */ public X509Store getCRLs( String type, String provider) throws NoSuchStoreException, NoSuchProviderException, CMSException { return getCRLs(type, CMSUtils.getProvider(provider)); } /** * return a X509Store containing CRLs, if any, contained * in this message. * * @param type type of store to create * @param provider provider to use * @return a store of CRLs * @exception NoSuchStoreException if the store type isn't available. * @exception CMSException if a general exception prevents creation of the X509Store * @deprecated use getCRLs() */ public X509Store getCRLs( String type, Provider provider) throws NoSuchStoreException, CMSException { if (_crlStore == null) { populateCertCrlSets(); _crlStore = HELPER.createCRLsStore(type, provider, _crlSet); } return _crlStore; } /** * return a CertStore containing the certificates and CRLs associated with * this message. * * @exception NoSuchProviderException if the provider requested isn't available. * @exception NoSuchAlgorithmException if the cert store isn't available. * @exception CMSException if a general exception prevents creation of the CertStore * @deprecated use getCertificates() */ public CertStore getCertificatesAndCRLs( String type, String provider) throws NoSuchAlgorithmException, NoSuchProviderException, CMSException { return getCertificatesAndCRLs(type, CMSUtils.getProvider(provider)); } /** * return a CertStore containing the certificates and CRLs associated with * this message. * * @exception NoSuchProviderException if the provider requested isn't available. * @exception NoSuchAlgorithmException if the cert store isn't available. * @exception CMSException if a general exception prevents creation of the CertStore * @deprecated use getCertificates() */ public CertStore getCertificatesAndCRLs( String type, Provider provider) throws NoSuchAlgorithmException, NoSuchProviderException, CMSException { populateCertCrlSets(); return HELPER.createCertStore(type, provider, _certSet, _crlSet); } public Store getCertificates() throws CMSException { populateCertCrlSets(); ASN1Set certSet = _certSet; if (certSet != null) { List certList = new ArrayList(certSet.size()); for (Enumeration en = certSet.getObjects(); en.hasMoreElements();) { ASN1Primitive obj = ((ASN1Encodable)en.nextElement()).toASN1Primitive(); if (obj instanceof ASN1Sequence) { certList.add(new X509CertificateHolder(Certificate.getInstance(obj))); } } return new CollectionStore(certList); } return new CollectionStore(new ArrayList()); } public Store getCRLs() throws CMSException { populateCertCrlSets(); ASN1Set crlSet = _crlSet; if (crlSet != null) { List crlList = new ArrayList(crlSet.size()); for (Enumeration en = crlSet.getObjects(); en.hasMoreElements();) { ASN1Primitive obj = ((ASN1Encodable)en.nextElement()).toASN1Primitive(); if (obj instanceof ASN1Sequence) { crlList.add(new X509CRLHolder(CertificateList.getInstance(obj))); } } return new CollectionStore(crlList); } return new CollectionStore(new ArrayList()); } public Store getAttributeCertificates() throws CMSException { populateCertCrlSets(); ASN1Set certSet = _certSet; if (certSet != null) { List certList = new ArrayList(certSet.size()); for (Enumeration en = certSet.getObjects(); en.hasMoreElements();) { ASN1Primitive obj = ((ASN1Encodable)en.nextElement()).toASN1Primitive(); if (obj instanceof ASN1TaggedObject) { ASN1TaggedObject tagged = (ASN1TaggedObject)obj; if (tagged.getTagNo() == 2) { certList.add(new X509AttributeCertificateHolder(AttributeCertificate.getInstance(ASN1Sequence.getInstance(tagged, false)))); } } } return new CollectionStore(certList); } return new CollectionStore(new ArrayList()); } private void populateCertCrlSets() throws CMSException { if (_isCertCrlParsed) { return; } _isCertCrlParsed = true; try { // care! Streaming - these must be done in exactly this order. _certSet = getASN1Set(_signedData.getCertificates()); _crlSet = getASN1Set(_signedData.getCrls()); } catch (IOException e) { throw new CMSException("problem parsing cert/crl sets", e); } } /** * Return the a string representation of the OID associated with the * encapsulated content info structure carried in the signed data. * * @return the OID for the content type. */ public String getSignedContentTypeOID() { return _signedContentType.getId(); } public CMSTypedStream getSignedContent() { if (_signedContent == null) { return null; } InputStream digStream = CMSUtils.attachDigestsToInputStream( digests.values(), _signedContent.getContentStream()); return new CMSTypedStream(_signedContent.getContentType(), digStream); } /** * Replace the signerinformation store associated with the passed * in message contained in the stream original with the new one passed in. * You would probably only want to do this if you wanted to change the unsigned * attributes associated with a signer, or perhaps delete one. *

    * The output stream is returned unclosed. *

    * @param original the signed data stream to be used as a base. * @param signerInformationStore the new signer information store to use. * @param out the stream to write the new signed data object to. * @return out. */ public static OutputStream replaceSigners( InputStream original, SignerInformationStore signerInformationStore, OutputStream out) throws CMSException, IOException { ASN1StreamParser in = new ASN1StreamParser(original); ContentInfoParser contentInfo = new ContentInfoParser((ASN1SequenceParser)in.readObject()); SignedDataParser signedData = SignedDataParser.getInstance(contentInfo.getContent(BERTags.SEQUENCE)); BERSequenceGenerator sGen = new BERSequenceGenerator(out); sGen.addObject(CMSObjectIdentifiers.signedData); BERSequenceGenerator sigGen = new BERSequenceGenerator(sGen.getRawOutputStream(), 0, true); // version number sigGen.addObject(signedData.getVersion()); // digests signedData.getDigestAlgorithms().toASN1Primitive(); // skip old ones ASN1EncodableVector digestAlgs = new ASN1EncodableVector(); for (Iterator it = signerInformationStore.getSigners().iterator(); it.hasNext();) { SignerInformation signer = (SignerInformation)it.next(); digestAlgs.add(CMSSignedHelper.INSTANCE.fixAlgID(signer.getDigestAlgorithmID())); } sigGen.getRawOutputStream().write(new DERSet(digestAlgs).getEncoded()); // encap content info ContentInfoParser encapContentInfo = signedData.getEncapContentInfo(); BERSequenceGenerator eiGen = new BERSequenceGenerator(sigGen.getRawOutputStream()); eiGen.addObject(encapContentInfo.getContentType()); pipeEncapsulatedOctetString(encapContentInfo, eiGen.getRawOutputStream()); eiGen.close(); writeSetToGeneratorTagged(sigGen, signedData.getCertificates(), 0); writeSetToGeneratorTagged(sigGen, signedData.getCrls(), 1); ASN1EncodableVector signerInfos = new ASN1EncodableVector(); for (Iterator it = signerInformationStore.getSigners().iterator(); it.hasNext();) { SignerInformation signer = (SignerInformation)it.next(); signerInfos.add(signer.toASN1Structure()); } sigGen.getRawOutputStream().write(new DERSet(signerInfos).getEncoded()); sigGen.close(); sGen.close(); return out; } /** * Replace the certificate and CRL information associated with this * CMSSignedData object with the new one passed in. *

    * The output stream is returned unclosed. *

    * @param original the signed data stream to be used as a base. * @param certsAndCrls the new certificates and CRLs to be used. * @param out the stream to write the new signed data object to. * @return out. * @exception CMSException if there is an error processing the CertStore * @deprecated use method that takes Store objects. */ public static OutputStream replaceCertificatesAndCRLs( InputStream original, CertStore certsAndCrls, OutputStream out) throws CMSException, IOException { ASN1StreamParser in = new ASN1StreamParser(original); ContentInfoParser contentInfo = new ContentInfoParser((ASN1SequenceParser)in.readObject()); SignedDataParser signedData = SignedDataParser.getInstance(contentInfo.getContent(BERTags.SEQUENCE)); BERSequenceGenerator sGen = new BERSequenceGenerator(out); sGen.addObject(CMSObjectIdentifiers.signedData); BERSequenceGenerator sigGen = new BERSequenceGenerator(sGen.getRawOutputStream(), 0, true); // version number sigGen.addObject(signedData.getVersion()); // digests sigGen.getRawOutputStream().write(signedData.getDigestAlgorithms().toASN1Primitive().getEncoded()); // encap content info ContentInfoParser encapContentInfo = signedData.getEncapContentInfo(); BERSequenceGenerator eiGen = new BERSequenceGenerator(sigGen.getRawOutputStream()); eiGen.addObject(encapContentInfo.getContentType()); pipeEncapsulatedOctetString(encapContentInfo, eiGen.getRawOutputStream()); eiGen.close(); // // skip existing certs and CRLs // getASN1Set(signedData.getCertificates()); getASN1Set(signedData.getCrls()); // // replace the certs and crls in the SignedData object // ASN1Set certs; try { certs = CMSUtils.createBerSetFromList(CMSUtils.getCertificatesFromStore(certsAndCrls)); } catch (CertStoreException e) { throw new CMSException("error getting certs from certStore", e); } if (certs.size() > 0) { sigGen.getRawOutputStream().write(new DERTaggedObject(false, 0, certs).getEncoded()); } ASN1Set crls; try { crls = CMSUtils.createBerSetFromList(CMSUtils.getCRLsFromStore(certsAndCrls)); } catch (CertStoreException e) { throw new CMSException("error getting crls from certStore", e); } if (crls.size() > 0) { sigGen.getRawOutputStream().write(new DERTaggedObject(false, 1, crls).getEncoded()); } sigGen.getRawOutputStream().write(signedData.getSignerInfos().toASN1Primitive().getEncoded()); sigGen.close(); sGen.close(); return out; } /** * Replace the certificate and CRL information associated with this * CMSSignedData object with the new one passed in. *

    * The output stream is returned unclosed. *

    * @param original the signed data stream to be used as a base. * @param certs new certificates to be used, if any. * @param crls new CRLs to be used, if any. * @param attrCerts new attribute certificates to be used, if any. * @param out the stream to write the new signed data object to. * @return out. * @exception CMSException if there is an error processing the CertStore */ public static OutputStream replaceCertificatesAndCRLs( InputStream original, Store certs, Store crls, Store attrCerts, OutputStream out) throws CMSException, IOException { ASN1StreamParser in = new ASN1StreamParser(original); ContentInfoParser contentInfo = new ContentInfoParser((ASN1SequenceParser)in.readObject()); SignedDataParser signedData = SignedDataParser.getInstance(contentInfo.getContent(BERTags.SEQUENCE)); BERSequenceGenerator sGen = new BERSequenceGenerator(out); sGen.addObject(CMSObjectIdentifiers.signedData); BERSequenceGenerator sigGen = new BERSequenceGenerator(sGen.getRawOutputStream(), 0, true); // version number sigGen.addObject(signedData.getVersion()); // digests sigGen.getRawOutputStream().write(signedData.getDigestAlgorithms().toASN1Primitive().getEncoded()); // encap content info ContentInfoParser encapContentInfo = signedData.getEncapContentInfo(); BERSequenceGenerator eiGen = new BERSequenceGenerator(sigGen.getRawOutputStream()); eiGen.addObject(encapContentInfo.getContentType()); pipeEncapsulatedOctetString(encapContentInfo, eiGen.getRawOutputStream()); eiGen.close(); // // skip existing certs and CRLs // getASN1Set(signedData.getCertificates()); getASN1Set(signedData.getCrls()); // // replace the certs and crls in the SignedData object // if (certs != null || attrCerts != null) { List certificates = new ArrayList(); if (certs != null) { certificates.addAll(CMSUtils.getCertificatesFromStore(certs)); } if (attrCerts != null) { certificates.addAll(CMSUtils.getAttributeCertificatesFromStore(attrCerts)); } ASN1Set asn1Certs = CMSUtils.createBerSetFromList(certificates); if (asn1Certs.size() > 0) { sigGen.getRawOutputStream().write(new DERTaggedObject(false, 0, asn1Certs).getEncoded()); } } if (crls != null) { ASN1Set asn1Crls = CMSUtils.createBerSetFromList(CMSUtils.getCRLsFromStore(crls)); if (asn1Crls.size() > 0) { sigGen.getRawOutputStream().write(new DERTaggedObject(false, 1, asn1Crls).getEncoded()); } } sigGen.getRawOutputStream().write(signedData.getSignerInfos().toASN1Primitive().getEncoded()); sigGen.close(); sGen.close(); return out; } private static void writeSetToGeneratorTagged( ASN1Generator asn1Gen, ASN1SetParser asn1SetParser, int tagNo) throws IOException { ASN1Set asn1Set = getASN1Set(asn1SetParser); if (asn1Set != null) { if (asn1SetParser instanceof BERSetParser) { asn1Gen.getRawOutputStream().write(new BERTaggedObject(false, tagNo, asn1Set).getEncoded()); } else { asn1Gen.getRawOutputStream().write(new DERTaggedObject(false, tagNo, asn1Set).getEncoded()); } } } private static ASN1Set getASN1Set( ASN1SetParser asn1SetParser) { return asn1SetParser == null ? null : ASN1Set.getInstance(asn1SetParser.toASN1Primitive()); } private static void pipeEncapsulatedOctetString(ContentInfoParser encapContentInfo, OutputStream rawOutputStream) throws IOException { ASN1OctetStringParser octs = (ASN1OctetStringParser) encapContentInfo.getContent(BERTags.OCTET_STRING); if (octs != null) { pipeOctetString(octs, rawOutputStream); } // BERTaggedObjectParser contentObject = (BERTaggedObjectParser)encapContentInfo.getContentObject(); // if (contentObject != null) // { // // Handle IndefiniteLengthInputStream safely // InputStream input = ASN1StreamParser.getSafeRawInputStream(contentObject.getContentStream(true)); // // // TODO BerTaggedObjectGenerator? // BEROutputStream berOut = new BEROutputStream(rawOutputStream); // berOut.write(DERTags.CONSTRUCTED | DERTags.TAGGED | 0); // berOut.write(0x80); // // pipeRawOctetString(input, rawOutputStream); // // berOut.write(0x00); // berOut.write(0x00); // // input.close(); // } } private static void pipeOctetString( ASN1OctetStringParser octs, OutputStream output) throws IOException { // TODO Allow specification of a specific fragment size? OutputStream outOctets = CMSUtils.createBEROctetOutputStream( output, 0, true, 0); Streams.pipeAll(octs.getOctetStream(), outOctets); outOctets.close(); } // private static void pipeRawOctetString( // InputStream rawInput, // OutputStream rawOutput) // throws IOException // { // InputStream tee = new TeeInputStream(rawInput, rawOutput); // ASN1StreamParser sp = new ASN1StreamParser(tee); // ASN1OctetStringParser octs = (ASN1OctetStringParser)sp.readObject(); // Streams.drain(octs.getOctetStream()); // } } bouncycastle-1.49.orig/jdk1.1/org/bouncycastle/cms/jcajce/0000755000175000017500000000000012152033551022701 5ustar ebourgebourgbouncycastle-1.49.orig/jdk1.1/org/bouncycastle/cms/jcajce/JcaX509CertSelectorConverter.java0000644000175000017500000000136311731466726031061 0ustar ebourgebourgpackage org.bouncycastle.cms.jcajce; import java.security.cert.X509CertSelector; import org.bouncycastle.cms.KeyTransRecipientId; import org.bouncycastle.cms.SignerId; public class JcaX509CertSelectorConverter extends org.bouncycastle.cert.selector.jcajce.JcaX509CertSelectorConverter { public JcaX509CertSelectorConverter() { } public X509CertSelector getCertSelector(KeyTransRecipientId recipientId) { return doConversion(recipientId.getIssuer(), recipientId.getSerialNumber(), recipientId.getSubjectKeyIdentifier()); } public X509CertSelector getCertSelector(SignerId signerId) { return doConversion(signerId.getIssuer(), signerId.getSerialNumber(), signerId.getSubjectKeyIdentifier()); } } bouncycastle-1.49.orig/jdk1.1/org/bouncycastle/cms/jcajce/JceKeyAgreeRecipientInfoGenerator.java0000644000175000017500000001777611731466726032252 0ustar ebourgebourgpackage org.bouncycastle.cms.jcajce; import java.security.GeneralSecurityException; import java.security.InvalidAlgorithmParameterException; import java.security.KeyPair; import java.security.KeyPairGenerator; import java.security.PrivateKey; import java.security.Provider; import java.security.PublicKey; import java.security.SecureRandom; import java.security.InvalidKeyException; import java.security.NoSuchAlgorithmException; import java.security.cert.CertificateEncodingException; import java.security.cert.X509Certificate; import java.util.ArrayList; import java.util.List; import javax.crypto.Cipher; import javax.crypto.KeyAgreement; import javax.crypto.SecretKey; import org.bouncycastle.asn1.ASN1Encodable; import org.bouncycastle.asn1.ASN1EncodableVector; import org.bouncycastle.asn1.ASN1ObjectIdentifier; import org.bouncycastle.asn1.ASN1OctetString; import org.bouncycastle.asn1.ASN1Sequence; import org.bouncycastle.asn1.DEROctetString; import org.bouncycastle.asn1.DERSequence; import org.bouncycastle.asn1.cms.KeyAgreeRecipientIdentifier; import org.bouncycastle.asn1.cms.RecipientEncryptedKey; import org.bouncycastle.asn1.cms.RecipientKeyIdentifier; import org.bouncycastle.asn1.cms.ecc.MQVuserKeyingMaterial; import org.bouncycastle.asn1.x509.AlgorithmIdentifier; import org.bouncycastle.asn1.x509.SubjectPublicKeyInfo; import org.bouncycastle.cms.CMSAlgorithm; import org.bouncycastle.cms.CMSEnvelopedGenerator; import org.bouncycastle.cms.CMSException; import org.bouncycastle.cms.KeyAgreeRecipientInfoGenerator; import org.bouncycastle.jce.interfaces.ECPublicKey; import org.bouncycastle.jce.spec.ECParameterSpec; import org.bouncycastle.jce.spec.MQVPrivateKeySpec; import org.bouncycastle.jce.spec.MQVPublicKeySpec; import org.bouncycastle.operator.GenericKey; public class JceKeyAgreeRecipientInfoGenerator extends KeyAgreeRecipientInfoGenerator { private List recipientIDs = new ArrayList(); private List recipientKeys = new ArrayList(); private PublicKey senderPublicKey; private PrivateKey senderPrivateKey; private EnvelopedDataHelper helper = new EnvelopedDataHelper(new DefaultJcaJceExtHelper()); private SecureRandom random; private KeyPair ephemeralKP; public JceKeyAgreeRecipientInfoGenerator(ASN1ObjectIdentifier keyAgreementOID, PrivateKey senderPrivateKey, PublicKey senderPublicKey, ASN1ObjectIdentifier keyEncryptionOID) { super(keyAgreementOID, SubjectPublicKeyInfo.getInstance(senderPublicKey.getEncoded()), keyEncryptionOID); this.senderPublicKey = senderPublicKey; this.senderPrivateKey = senderPrivateKey; } public JceKeyAgreeRecipientInfoGenerator setProvider(Provider provider) { this.helper = new EnvelopedDataHelper(new ProviderJcaJceExtHelper(provider)); return this; } public JceKeyAgreeRecipientInfoGenerator setProvider(String providerName) { this.helper = new EnvelopedDataHelper(new NamedJcaJceExtHelper(providerName)); return this; } public JceKeyAgreeRecipientInfoGenerator setSecureRandom(SecureRandom random) { this.random = random; return this; } /** * Add a recipient based on the passed in certificate's public key and its issuer and serial number. * * @param recipientCert recipient's certificate * @return the current instance. * @throws CertificateEncodingException if the necessary data cannot be extracted from the certificate. */ public JceKeyAgreeRecipientInfoGenerator addRecipient(X509Certificate recipientCert) throws CertificateEncodingException { recipientIDs.add(new KeyAgreeRecipientIdentifier(CMSUtils.getIssuerAndSerialNumber(recipientCert))); recipientKeys.add(recipientCert.getPublicKey()); return this; } /** * Add a recipient identified by the passed in subjectKeyID and the for the passed in public key. * * @param subjectKeyID identifier actual recipient will use to match the private key. * @param publicKey the public key for encrypting the secret key. * @return the current instance. * @throws CertificateEncodingException */ public JceKeyAgreeRecipientInfoGenerator addRecipient(byte[] subjectKeyID, PublicKey publicKey) throws CertificateEncodingException { recipientIDs.add(new KeyAgreeRecipientIdentifier(new RecipientKeyIdentifier(subjectKeyID))); recipientKeys.add(publicKey); return this; } public ASN1Sequence generateRecipientEncryptedKeys(AlgorithmIdentifier keyAgreeAlgorithm, AlgorithmIdentifier keyEncryptionAlgorithm, GenericKey contentEncryptionKey) throws CMSException { init(keyAgreeAlgorithm.getAlgorithm()); PrivateKey senderPrivateKey = this.senderPrivateKey; ASN1ObjectIdentifier keyAgreementOID = keyAgreeAlgorithm.getAlgorithm(); if (keyAgreementOID.getId().equals(CMSEnvelopedGenerator.ECMQV_SHA1KDF)) { senderPrivateKey = new MQVPrivateKeySpec( senderPrivateKey, ephemeralKP.getPrivate(), ephemeralKP.getPublic()); } ASN1EncodableVector recipientEncryptedKeys = new ASN1EncodableVector(); for (int i = 0; i != recipientIDs.size(); i++) { PublicKey recipientPublicKey = (PublicKey)recipientKeys.get(i); KeyAgreeRecipientIdentifier karId = (KeyAgreeRecipientIdentifier)recipientIDs.get(i); if (keyAgreementOID.getId().equals(CMSEnvelopedGenerator.ECMQV_SHA1KDF)) { recipientPublicKey = new MQVPublicKeySpec(recipientPublicKey, recipientPublicKey); } try { // Use key agreement to choose a wrap key for this recipient KeyAgreement keyAgreement = helper.createKeyAgreement(keyAgreementOID); keyAgreement.init(senderPrivateKey, random); keyAgreement.doPhase(recipientPublicKey, true); SecretKey keyEncryptionKey = keyAgreement.generateSecret(keyEncryptionAlgorithm.getAlgorithm().getId()); // Wrap the content encryption key with the agreement key Cipher keyEncryptionCipher = helper.createCipher(keyEncryptionAlgorithm.getAlgorithm()); keyEncryptionCipher.init(Cipher.WRAP_MODE, keyEncryptionKey, random); byte[] encryptedKeyBytes = keyEncryptionCipher.wrap(helper.getJceKey(contentEncryptionKey)); ASN1OctetString encryptedKey = new DEROctetString(encryptedKeyBytes); recipientEncryptedKeys.add(new RecipientEncryptedKey(karId, encryptedKey)); } catch (NoSuchAlgorithmException e) { throw new CMSException("cannot perform agreement step: " + e.getMessage(), e); } catch (InvalidKeyException e) { throw new CMSException("cannot perform agreement step: " + e.getMessage(), e); } catch (GeneralSecurityException e) { throw new CMSException("cannot perform agreement step: " + e.getMessage(), e); } } return new DERSequence(recipientEncryptedKeys); } protected ASN1Encodable getUserKeyingMaterial(AlgorithmIdentifier keyAgreeAlg) throws CMSException { init(keyAgreeAlg.getAlgorithm()); if (ephemeralKP != null) { return new MQVuserKeyingMaterial( createOriginatorPublicKey(SubjectPublicKeyInfo.getInstance(ephemeralKP.getPublic().getEncoded())), null); } return null; } private void init(ASN1ObjectIdentifier keyAgreementOID) throws CMSException { if (random == null) { random = new SecureRandom(); } if (keyAgreementOID.equals(CMSAlgorithm.ECMQV_SHA1KDF)) { if (ephemeralKP == null) { throw new CMSException( "cannot determine MQV ephemeral key pair parameters from public key"); } } } } bouncycastle-1.49.orig/jdk1.1/org/bouncycastle/cms/jcajce/JceCMSContentEncryptorBuilder.java0000644000175000017500000001153212103632343031362 0ustar ebourgebourgpackage org.bouncycastle.cms.jcajce; import java.io.OutputStream; import java.security.AlgorithmParameters; import java.security.GeneralSecurityException; import java.security.InvalidKeyException; import java.security.Provider; import java.security.SecureRandom; import java.util.HashMap; import java.util.Map; import javax.crypto.Cipher; import javax.crypto.CipherOutputStream; import javax.crypto.KeyGenerator; import javax.crypto.SecretKey; import org.bouncycastle.asn1.ASN1ObjectIdentifier; import org.bouncycastle.asn1.x509.AlgorithmIdentifier; import org.bouncycastle.cms.CMSAlgorithm; import org.bouncycastle.cms.CMSException; import org.bouncycastle.operator.GenericKey; import org.bouncycastle.operator.OutputEncryptor; import org.bouncycastle.util.Integers; public class JceCMSContentEncryptorBuilder { private static Map keySizes = new HashMap(); static { keySizes.put(CMSAlgorithm.AES128_CBC, Integers.valueOf(128)); keySizes.put(CMSAlgorithm.AES192_CBC, Integers.valueOf(192)); keySizes.put(CMSAlgorithm.AES256_CBC, Integers.valueOf(256)); keySizes.put(CMSAlgorithm.CAMELLIA128_CBC, Integers.valueOf(128)); keySizes.put(CMSAlgorithm.CAMELLIA192_CBC, Integers.valueOf(192)); keySizes.put(CMSAlgorithm.CAMELLIA256_CBC, Integers.valueOf(256)); } private static int getKeySize(ASN1ObjectIdentifier oid) { Integer size = (Integer)keySizes.get(oid); if (size != null) { return size.intValue(); } return -1; } private ASN1ObjectIdentifier encryptionOID; private int keySize; private EnvelopedDataHelper helper = new EnvelopedDataHelper(new DefaultJcaJceExtHelper()); private SecureRandom random; public JceCMSContentEncryptorBuilder(ASN1ObjectIdentifier encryptionOID) { this(encryptionOID, getKeySize(encryptionOID)); } public JceCMSContentEncryptorBuilder(ASN1ObjectIdentifier encryptionOID, int keySize) { this.encryptionOID = encryptionOID; this.keySize = keySize; } public JceCMSContentEncryptorBuilder setProvider(Provider provider) { this.helper = new EnvelopedDataHelper(new ProviderJcaJceExtHelper(provider)); return this; } public JceCMSContentEncryptorBuilder setProvider(String providerName) { this.helper = new EnvelopedDataHelper(new NamedJcaJceExtHelper(providerName)); return this; } public JceCMSContentEncryptorBuilder setSecureRandom(SecureRandom random) { this.random = random; return this; } public OutputEncryptor build() throws CMSException { return new CMSOutputEncryptor(encryptionOID, keySize, random); } private class CMSOutputEncryptor implements OutputEncryptor { private SecretKey encKey; private AlgorithmIdentifier algorithmIdentifier; private Cipher cipher; CMSOutputEncryptor(ASN1ObjectIdentifier encryptionOID, int keySize, SecureRandom random) throws CMSException { KeyGenerator keyGen = helper.createKeyGenerator(encryptionOID); if (random == null) { random = new SecureRandom(); } if (keySize < 0) { keyGen.init(random); } else { keyGen.init(keySize, random); } cipher = helper.createCipher(encryptionOID); encKey = keyGen.generateKey(); AlgorithmParameters params = helper.generateParameters(encryptionOID, encKey, random); try { cipher.init(Cipher.ENCRYPT_MODE, encKey, params, random); } catch (InvalidKeyException e) { throw new CMSException("unable to initialize cipher: " + e.getMessage(), e); } catch (GeneralSecurityException e) { throw new CMSException("unable to initialize cipher: " + e.getMessage(), e); } // // If params are null we try and second guess on them as some providers don't provide // algorithm parameter generation explicity but instead generate them under the hood. // if (params == null) { params = cipher.getParameters(); } algorithmIdentifier = helper.getAlgorithmIdentifier(encryptionOID, params); } public AlgorithmIdentifier getAlgorithmIdentifier() { return algorithmIdentifier; } public OutputStream getOutputStream(OutputStream dOut) { return new CipherOutputStream(dOut, cipher); } public GenericKey getKey() { return new GenericKey(encKey); } } } bouncycastle-1.49.orig/jdk1.1/org/bouncycastle/cms/jcajce/EnvelopedDataHelper.java0000644000175000017500000006324011731466726027444 0ustar ebourgebourgpackage org.bouncycastle.cms.jcajce; import java.io.IOException; import java.security.AlgorithmParameterGenerator; import java.security.AlgorithmParameters; import java.security.GeneralSecurityException; import java.security.InvalidAlgorithmParameterException; import java.security.InvalidKeyException; import java.security.Key; import java.security.KeyFactory; import java.security.KeyPairGenerator; import java.security.NoSuchAlgorithmException; import java.security.NoSuchProviderException; import java.security.PrivateKey; import java.security.SecureRandom; import java.security.spec.AlgorithmParameterSpec; import java.security.spec.InvalidParameterSpecException; import java.util.HashMap; import java.util.Map; import javax.crypto.Cipher; import javax.crypto.KeyAgreement; import javax.crypto.KeyGenerator; import javax.crypto.Mac; import javax.crypto.NoSuchPaddingException; import javax.crypto.SecretKey; import javax.crypto.spec.IvParameterSpec; import javax.crypto.spec.RC2ParameterSpec; import javax.crypto.spec.SecretKeySpec; import org.bouncycastle.asn1.ASN1Encodable; import org.bouncycastle.asn1.ASN1Null; import org.bouncycastle.asn1.ASN1ObjectIdentifier; import org.bouncycastle.asn1.ASN1OctetString; import org.bouncycastle.asn1.ASN1Primitive; import org.bouncycastle.asn1.DERNull; import org.bouncycastle.asn1.DERObjectIdentifier; import org.bouncycastle.asn1.DEROctetString; import org.bouncycastle.asn1.pkcs.PKCSObjectIdentifiers; import org.bouncycastle.asn1.pkcs.RC2CBCParameter; import org.bouncycastle.asn1.x509.AlgorithmIdentifier; import org.bouncycastle.cms.CMSAlgorithm; import org.bouncycastle.cms.CMSEnvelopedDataGenerator; import org.bouncycastle.cms.CMSException; import org.bouncycastle.operator.GenericKey; import org.bouncycastle.operator.SymmetricKeyUnwrapper; import org.bouncycastle.operator.jcajce.JceAsymmetricKeyUnwrapper; class EnvelopedDataHelper { protected static final Map BASE_CIPHER_NAMES = new HashMap(); protected static final Map CIPHER_ALG_NAMES = new HashMap(); protected static final Map MAC_ALG_NAMES = new HashMap(); static { BASE_CIPHER_NAMES.put(CMSAlgorithm.DES_EDE3_CBC, "DESEDE"); BASE_CIPHER_NAMES.put(CMSAlgorithm.AES128_CBC, "AES"); BASE_CIPHER_NAMES.put(CMSAlgorithm.AES192_CBC, "AES"); BASE_CIPHER_NAMES.put(CMSAlgorithm.AES256_CBC, "AES"); BASE_CIPHER_NAMES.put(CMSAlgorithm.RC2_CBC, "RC2"); BASE_CIPHER_NAMES.put(CMSAlgorithm.CAST5_CBC, "CAST5"); BASE_CIPHER_NAMES.put(CMSAlgorithm.CAMELLIA128_CBC, "Camellia"); BASE_CIPHER_NAMES.put(CMSAlgorithm.CAMELLIA192_CBC, "Camellia"); BASE_CIPHER_NAMES.put(CMSAlgorithm.CAMELLIA256_CBC, "Camellia"); BASE_CIPHER_NAMES.put(CMSAlgorithm.SEED_CBC, "SEED"); CIPHER_ALG_NAMES.put(CMSAlgorithm.DES_EDE3_CBC, "DESEDE/CBC/PKCS5Padding"); CIPHER_ALG_NAMES.put(CMSAlgorithm.AES128_CBC, "AES/CBC/PKCS5Padding"); CIPHER_ALG_NAMES.put(CMSAlgorithm.AES192_CBC, "AES/CBC/PKCS5Padding"); CIPHER_ALG_NAMES.put(CMSAlgorithm.AES256_CBC, "AES/CBC/PKCS5Padding"); CIPHER_ALG_NAMES.put(PKCSObjectIdentifiers.rsaEncryption, "RSA/ECB/PKCS1Padding"); CIPHER_ALG_NAMES.put(CMSAlgorithm.CAST5_CBC, "CAST5/CBC/PKCS5Padding"); CIPHER_ALG_NAMES.put(CMSAlgorithm.CAMELLIA128_CBC, "Camellia/CBC/PKCS5Padding"); CIPHER_ALG_NAMES.put(CMSAlgorithm.CAMELLIA192_CBC, "Camellia/CBC/PKCS5Padding"); CIPHER_ALG_NAMES.put(CMSAlgorithm.CAMELLIA256_CBC, "Camellia/CBC/PKCS5Padding"); CIPHER_ALG_NAMES.put(CMSAlgorithm.SEED_CBC, "SEED/CBC/PKCS5Padding"); MAC_ALG_NAMES.put(CMSAlgorithm.DES_EDE3_CBC, "DESEDEMac"); MAC_ALG_NAMES.put(CMSAlgorithm.AES128_CBC, "AESMac"); MAC_ALG_NAMES.put(CMSAlgorithm.AES192_CBC, "AESMac"); MAC_ALG_NAMES.put(CMSAlgorithm.AES256_CBC, "AESMac"); MAC_ALG_NAMES.put(CMSAlgorithm.RC2_CBC, "RC2Mac"); } private static final short[] rc2Table = { 0xbd, 0x56, 0xea, 0xf2, 0xa2, 0xf1, 0xac, 0x2a, 0xb0, 0x93, 0xd1, 0x9c, 0x1b, 0x33, 0xfd, 0xd0, 0x30, 0x04, 0xb6, 0xdc, 0x7d, 0xdf, 0x32, 0x4b, 0xf7, 0xcb, 0x45, 0x9b, 0x31, 0xbb, 0x21, 0x5a, 0x41, 0x9f, 0xe1, 0xd9, 0x4a, 0x4d, 0x9e, 0xda, 0xa0, 0x68, 0x2c, 0xc3, 0x27, 0x5f, 0x80, 0x36, 0x3e, 0xee, 0xfb, 0x95, 0x1a, 0xfe, 0xce, 0xa8, 0x34, 0xa9, 0x13, 0xf0, 0xa6, 0x3f, 0xd8, 0x0c, 0x78, 0x24, 0xaf, 0x23, 0x52, 0xc1, 0x67, 0x17, 0xf5, 0x66, 0x90, 0xe7, 0xe8, 0x07, 0xb8, 0x60, 0x48, 0xe6, 0x1e, 0x53, 0xf3, 0x92, 0xa4, 0x72, 0x8c, 0x08, 0x15, 0x6e, 0x86, 0x00, 0x84, 0xfa, 0xf4, 0x7f, 0x8a, 0x42, 0x19, 0xf6, 0xdb, 0xcd, 0x14, 0x8d, 0x50, 0x12, 0xba, 0x3c, 0x06, 0x4e, 0xec, 0xb3, 0x35, 0x11, 0xa1, 0x88, 0x8e, 0x2b, 0x94, 0x99, 0xb7, 0x71, 0x74, 0xd3, 0xe4, 0xbf, 0x3a, 0xde, 0x96, 0x0e, 0xbc, 0x0a, 0xed, 0x77, 0xfc, 0x37, 0x6b, 0x03, 0x79, 0x89, 0x62, 0xc6, 0xd7, 0xc0, 0xd2, 0x7c, 0x6a, 0x8b, 0x22, 0xa3, 0x5b, 0x05, 0x5d, 0x02, 0x75, 0xd5, 0x61, 0xe3, 0x18, 0x8f, 0x55, 0x51, 0xad, 0x1f, 0x0b, 0x5e, 0x85, 0xe5, 0xc2, 0x57, 0x63, 0xca, 0x3d, 0x6c, 0xb4, 0xc5, 0xcc, 0x70, 0xb2, 0x91, 0x59, 0x0d, 0x47, 0x20, 0xc8, 0x4f, 0x58, 0xe0, 0x01, 0xe2, 0x16, 0x38, 0xc4, 0x6f, 0x3b, 0x0f, 0x65, 0x46, 0xbe, 0x7e, 0x2d, 0x7b, 0x82, 0xf9, 0x40, 0xb5, 0x1d, 0x73, 0xf8, 0xeb, 0x26, 0xc7, 0x87, 0x97, 0x25, 0x54, 0xb1, 0x28, 0xaa, 0x98, 0x9d, 0xa5, 0x64, 0x6d, 0x7a, 0xd4, 0x10, 0x81, 0x44, 0xef, 0x49, 0xd6, 0xae, 0x2e, 0xdd, 0x76, 0x5c, 0x2f, 0xa7, 0x1c, 0xc9, 0x09, 0x69, 0x9a, 0x83, 0xcf, 0x29, 0x39, 0xb9, 0xe9, 0x4c, 0xff, 0x43, 0xab }; private static final short[] rc2Ekb = { 0x5d, 0xbe, 0x9b, 0x8b, 0x11, 0x99, 0x6e, 0x4d, 0x59, 0xf3, 0x85, 0xa6, 0x3f, 0xb7, 0x83, 0xc5, 0xe4, 0x73, 0x6b, 0x3a, 0x68, 0x5a, 0xc0, 0x47, 0xa0, 0x64, 0x34, 0x0c, 0xf1, 0xd0, 0x52, 0xa5, 0xb9, 0x1e, 0x96, 0x43, 0x41, 0xd8, 0xd4, 0x2c, 0xdb, 0xf8, 0x07, 0x77, 0x2a, 0xca, 0xeb, 0xef, 0x10, 0x1c, 0x16, 0x0d, 0x38, 0x72, 0x2f, 0x89, 0xc1, 0xf9, 0x80, 0xc4, 0x6d, 0xae, 0x30, 0x3d, 0xce, 0x20, 0x63, 0xfe, 0xe6, 0x1a, 0xc7, 0xb8, 0x50, 0xe8, 0x24, 0x17, 0xfc, 0x25, 0x6f, 0xbb, 0x6a, 0xa3, 0x44, 0x53, 0xd9, 0xa2, 0x01, 0xab, 0xbc, 0xb6, 0x1f, 0x98, 0xee, 0x9a, 0xa7, 0x2d, 0x4f, 0x9e, 0x8e, 0xac, 0xe0, 0xc6, 0x49, 0x46, 0x29, 0xf4, 0x94, 0x8a, 0xaf, 0xe1, 0x5b, 0xc3, 0xb3, 0x7b, 0x57, 0xd1, 0x7c, 0x9c, 0xed, 0x87, 0x40, 0x8c, 0xe2, 0xcb, 0x93, 0x14, 0xc9, 0x61, 0x2e, 0xe5, 0xcc, 0xf6, 0x5e, 0xa8, 0x5c, 0xd6, 0x75, 0x8d, 0x62, 0x95, 0x58, 0x69, 0x76, 0xa1, 0x4a, 0xb5, 0x55, 0x09, 0x78, 0x33, 0x82, 0xd7, 0xdd, 0x79, 0xf5, 0x1b, 0x0b, 0xde, 0x26, 0x21, 0x28, 0x74, 0x04, 0x97, 0x56, 0xdf, 0x3c, 0xf0, 0x37, 0x39, 0xdc, 0xff, 0x06, 0xa4, 0xea, 0x42, 0x08, 0xda, 0xb4, 0x71, 0xb0, 0xcf, 0x12, 0x7a, 0x4e, 0xfa, 0x6c, 0x1d, 0x84, 0x00, 0xc8, 0x7f, 0x91, 0x45, 0xaa, 0x2b, 0xc2, 0xb1, 0x8f, 0xd5, 0xba, 0xf2, 0xad, 0x19, 0xb2, 0x67, 0x36, 0xf7, 0x0f, 0x0a, 0x92, 0x7d, 0xe3, 0x9d, 0xe9, 0x90, 0x3e, 0x23, 0x27, 0x66, 0x13, 0xec, 0x81, 0x15, 0xbd, 0x22, 0xbf, 0x9f, 0x7e, 0xa9, 0x51, 0x4b, 0x4c, 0xfb, 0x02, 0xd3, 0x70, 0x86, 0x31, 0xe7, 0x3b, 0x05, 0x03, 0x54, 0x60, 0x48, 0x65, 0x18, 0xd2, 0xcd, 0x5f, 0x32, 0x88, 0x0e, 0x35, 0xfd }; private JcaJceExtHelper helper; EnvelopedDataHelper(JcaJceExtHelper helper) { this.helper = helper; } String getBaseCipherName(ASN1ObjectIdentifier algorithm) { String name = (String)BASE_CIPHER_NAMES.get(algorithm); if (name == null) { return algorithm.getId(); } return name; } Key getJceKey(GenericKey key) { if (key.getRepresentation() instanceof Key) { return (Key)key.getRepresentation(); } if (key.getRepresentation() instanceof byte[]) { return new SecretKeySpec((byte[])key.getRepresentation(), "ENC"); } throw new IllegalArgumentException("unknown generic key type"); } Key getJceKey(ASN1ObjectIdentifier algorithm, GenericKey key) { if (key.getRepresentation() instanceof Key) { return (Key)key.getRepresentation(); } if (key.getRepresentation() instanceof byte[]) { return new SecretKeySpec((byte[])key.getRepresentation(), getBaseCipherName(algorithm)); } throw new IllegalArgumentException("unknown generic key type"); } Cipher createCipher(ASN1ObjectIdentifier algorithm) throws CMSException { try { String cipherName = (String)CIPHER_ALG_NAMES.get(algorithm); if (cipherName != null) { try { // this is reversed as the Sun policy files now allow unlimited strength RSA return helper.createCipher(cipherName); } catch (NoSuchAlgorithmException e) { // Ignore } } return helper.createCipher(algorithm.getId()); } catch (NoSuchPaddingException e) { throw new CMSException("cannot create cipher: " + e.getMessage(), e); } catch (NoSuchAlgorithmException e) { throw new CMSException("cannot create cipher: " + e.getMessage(), e); } catch (NoSuchProviderException e) { throw new CMSException("cannot create cipher: " + e.getMessage(), e); } } Mac createMac(ASN1ObjectIdentifier algorithm) throws CMSException { try { String macName = (String)MAC_ALG_NAMES.get(algorithm); if (macName != null) { try { // this is reversed as the Sun policy files now allow unlimited strength RSA return helper.createMac(macName); } catch (NoSuchAlgorithmException e) { // Ignore } } return helper.createMac(algorithm.getId()); } catch (NoSuchProviderException e) { throw new CMSException("cannot create mac: " + e.getMessage(), e); } catch (NoSuchAlgorithmException e) { throw new CMSException("cannot create mac: " + e.getMessage(), e); } } Cipher createRFC3211Wrapper(ASN1ObjectIdentifier algorithm) throws CMSException { String cipherName = (String)BASE_CIPHER_NAMES.get(algorithm); if (cipherName == null) { throw new CMSException("no name for " + algorithm); } cipherName += "RFC3211Wrap"; try { return helper.createCipher(cipherName); } catch (NoSuchPaddingException e) { throw new CMSException("cannot create cipher: " + e.getMessage(), e); } catch (NoSuchAlgorithmException e) { throw new CMSException("cannot create cipher: " + e.getMessage(), e); } catch (NoSuchProviderException e) { throw new CMSException("cannot create cipher: " + e.getMessage(), e); } } KeyAgreement createKeyAgreement(ASN1ObjectIdentifier algorithm) throws CMSException { try { String agreementName = (String)BASE_CIPHER_NAMES.get(algorithm); if (agreementName != null) { try { // this is reversed as the Sun policy files now allow unlimited strength RSA return helper.createKeyAgreement(agreementName); } catch (NoSuchAlgorithmException e) { // Ignore } } return helper.createKeyAgreement(algorithm.getId()); } catch (NoSuchAlgorithmException e) { throw new CMSException("cannot create key pair generator: " + e.getMessage(), e); } catch (NoSuchProviderException e) { throw new CMSException("cannot create key pair generator: " + e.getMessage(), e); } } AlgorithmParameterGenerator createAlgorithmParameterGenerator(ASN1ObjectIdentifier algorithm) throws GeneralSecurityException { String algorithmName = (String)BASE_CIPHER_NAMES.get(algorithm); try { if (algorithmName != null) { try { // this is reversed as the Sun policy files now allow unlimited strength RSA return helper.createAlgorithmParameterGenerator(algorithmName); } catch (NoSuchAlgorithmException e) { // Ignore } } return helper.createAlgorithmParameterGenerator(algorithm.getId()); } catch (NoSuchAlgorithmException e) { throw new GeneralSecurityException("cannot create key generator: " + e.getMessage()); } catch (NoSuchProviderException e) { throw new GeneralSecurityException("cannot create key generator: " + e.getMessage()); } } Cipher createContentCipher(final Key sKey, final AlgorithmIdentifier encryptionAlgID) throws CMSException { return (Cipher)execute(new JCECallback() { public Object doInJCE() throws CMSException, InvalidAlgorithmParameterException, InvalidKeyException, InvalidParameterSpecException, NoSuchAlgorithmException, NoSuchPaddingException, NoSuchProviderException { Cipher cipher = createCipher(encryptionAlgID.getAlgorithm()); ASN1Encodable sParams = encryptionAlgID.getParameters(); String encAlg = encryptionAlgID.getAlgorithm().getId(); if (sParams != null && !(sParams instanceof ASN1Null)) { try { AlgorithmParameters params = createAlgorithmParameters(encryptionAlgID.getAlgorithm()); try { params.init(sParams.toASN1Primitive().getEncoded(), "ASN.1"); } catch (IOException e) { throw new CMSException("error decoding algorithm parameters.", e); } cipher.init(Cipher.DECRYPT_MODE, sKey, params); } catch (NoSuchAlgorithmException e) { if (encAlg.equals(CMSEnvelopedDataGenerator.DES_EDE3_CBC) || encAlg.equals(CMSEnvelopedDataGenerator.IDEA_CBC) || encAlg.equals(CMSEnvelopedDataGenerator.AES128_CBC) || encAlg.equals(CMSEnvelopedDataGenerator.AES192_CBC) || encAlg.equals(CMSEnvelopedDataGenerator.AES256_CBC)) { cipher.init(Cipher.DECRYPT_MODE, sKey, new IvParameterSpec( ASN1OctetString.getInstance(sParams).getOctets())); } else { throw e; } } } else { if (encAlg.equals(CMSEnvelopedDataGenerator.DES_EDE3_CBC) || encAlg.equals(CMSEnvelopedDataGenerator.IDEA_CBC) || encAlg.equals(CMSEnvelopedDataGenerator.CAST5_CBC)) { cipher.init(Cipher.DECRYPT_MODE, sKey, new IvParameterSpec(new byte[8])); } else { cipher.init(Cipher.DECRYPT_MODE, sKey); } } return cipher; } }); } Mac createContentMac(final Key sKey, final AlgorithmIdentifier macAlgId) throws CMSException { return (Mac)execute(new JCECallback() { public Object doInJCE() throws CMSException, InvalidAlgorithmParameterException, InvalidKeyException, InvalidParameterSpecException, NoSuchAlgorithmException, NoSuchPaddingException, NoSuchProviderException { Mac mac = createMac(macAlgId.getAlgorithm()); ASN1Encodable sParams = macAlgId.getParameters(); String macAlg = macAlgId.getAlgorithm().getId(); if (sParams != null && !(sParams instanceof ASN1Null)) { try { AlgorithmParameters params = createAlgorithmParameters(macAlgId.getAlgorithm()); try { params.init(sParams.toASN1Primitive().getEncoded(), "ASN.1"); } catch (IOException e) { throw new CMSException("error decoding algorithm parameters.", e); } mac.init(sKey, params.getParameterSpec(IvParameterSpec.class)); } catch (NoSuchAlgorithmException e) { throw e; } } else { mac.init(sKey); } return mac; } }); } AlgorithmParameters createAlgorithmParameters(ASN1ObjectIdentifier algorithm) throws NoSuchAlgorithmException, NoSuchProviderException { String algorithmName = (String)BASE_CIPHER_NAMES.get(algorithm); if (algorithmName != null) { try { // this is reversed as the Sun policy files now allow unlimited strength RSA return helper.createAlgorithmParameters(algorithmName); } catch (NoSuchAlgorithmException e) { // Ignore } } return helper.createAlgorithmParameters(algorithm.getId()); } KeyPairGenerator createKeyPairGenerator(DERObjectIdentifier algorithm) throws CMSException { try { String cipherName = (String)BASE_CIPHER_NAMES.get(algorithm); if (cipherName != null) { try { // this is reversed as the Sun policy files now allow unlimited strength RSA return helper.createKeyPairGenerator(cipherName); } catch (NoSuchAlgorithmException e) { // Ignore } } return helper.createKeyPairGenerator(algorithm.getId()); } catch (NoSuchAlgorithmException e) { throw new CMSException("cannot create key pair generator: " + e.getMessage(), e); } catch (NoSuchProviderException e) { throw new CMSException("cannot create key pair generator: " + e.getMessage(), e); } } public KeyGenerator createKeyGenerator(ASN1ObjectIdentifier algorithm) throws CMSException { try { String cipherName = (String)BASE_CIPHER_NAMES.get(algorithm); if (cipherName != null) { try { // this is reversed as the Sun policy files now allow unlimited strength RSA return helper.createKeyGenerator(cipherName); } catch (NoSuchAlgorithmException e) { // Ignore } } return helper.createKeyGenerator(algorithm.getId()); } catch (NoSuchAlgorithmException e) { throw new CMSException("cannot create key generator: " + e.getMessage(), e); } catch (NoSuchProviderException e) { throw new CMSException("cannot create key generator: " + e.getMessage(), e); } } AlgorithmParameters generateParameters(ASN1ObjectIdentifier encryptionOID, SecretKey encKey, SecureRandom rand) throws CMSException { try { AlgorithmParameterGenerator pGen = createAlgorithmParameterGenerator(encryptionOID); if (encryptionOID.equals(CMSEnvelopedDataGenerator.RC2_CBC)) { byte[] iv = new byte[8]; rand.nextBytes(iv); try { pGen.init(new RC2ParameterSpec(encKey.getEncoded().length * 8, iv), rand); } catch (InvalidAlgorithmParameterException e) { throw new CMSException("parameters generation error: " + e, e); } } return pGen.generateParameters(); } catch (GeneralSecurityException e) { throw new CMSException("exception creating algorithm parameter generator: " + e, e); } } AlgorithmIdentifier getAlgorithmIdentifier(ASN1ObjectIdentifier encryptionOID, AlgorithmParameters params) throws CMSException { ASN1Encodable asn1Params; if (params != null) { try { asn1Params = ASN1Primitive.fromByteArray(params.getEncoded("ASN.1")); } catch (IOException e) { throw new CMSException("cannot encode parameters: " + e.getMessage(), e); } } else { asn1Params = DERNull.INSTANCE; } return new AlgorithmIdentifier( encryptionOID, asn1Params); } static Object execute(JCECallback callback) throws CMSException { try { return callback.doInJCE(); } catch (NoSuchAlgorithmException e) { throw new CMSException("can't find algorithm.", e); } catch (InvalidKeyException e) { throw new CMSException("key invalid in message.", e); } catch (NoSuchProviderException e) { throw new CMSException("can't find provider.", e); } catch (NoSuchPaddingException e) { throw new CMSException("required padding not supported.", e); } catch (InvalidAlgorithmParameterException e) { throw new CMSException("algorithm parameters invalid.", e); } catch (InvalidParameterSpecException e) { throw new CMSException("MAC algorithm parameter spec invalid.", e); } } public KeyFactory createKeyFactory(ASN1ObjectIdentifier algorithm) throws CMSException { try { String cipherName = (String)BASE_CIPHER_NAMES.get(algorithm); if (cipherName != null) { try { // this is reversed as the Sun policy files now allow unlimited strength RSA return helper.createKeyFactory(cipherName); } catch (NoSuchAlgorithmException e) { // Ignore } } return helper.createKeyFactory(algorithm.getId()); } catch (NoSuchAlgorithmException e) { throw new CMSException("cannot create key factory: " + e.getMessage(), e); } catch (NoSuchProviderException e) { throw new CMSException("cannot create key factory: " + e.getMessage(), e); } } public JceAsymmetricKeyUnwrapper createAsymmetricUnwrapper(AlgorithmIdentifier keyEncryptionAlgorithm, PrivateKey keyEncryptionKey) { return helper.createAsymmetricUnwrapper(keyEncryptionAlgorithm, keyEncryptionKey); } public SymmetricKeyUnwrapper createSymmetricUnwrapper(AlgorithmIdentifier keyEncryptionAlgorithm, SecretKey keyEncryptionKey) { return helper.createSymmetricUnwrapper(keyEncryptionAlgorithm, keyEncryptionKey); } public AlgorithmIdentifier getAlgorithmIdentifier(ASN1ObjectIdentifier macOID, AlgorithmParameterSpec paramSpec) { if (paramSpec instanceof IvParameterSpec) { return new AlgorithmIdentifier(macOID, new DEROctetString(((IvParameterSpec)paramSpec).getIV())); } if (paramSpec instanceof RC2ParameterSpec) { RC2ParameterSpec rc2Spec = (RC2ParameterSpec)paramSpec; int effKeyBits = ((RC2ParameterSpec)paramSpec).getEffectiveKeyBits(); if (effKeyBits != -1) { int parameterVersion; if (effKeyBits < 256) { parameterVersion = rc2Table[effKeyBits]; } else { parameterVersion = effKeyBits; } return new AlgorithmIdentifier(macOID, new RC2CBCParameter(parameterVersion, rc2Spec.getIV())); } return new AlgorithmIdentifier(macOID, new RC2CBCParameter(rc2Spec.getIV())); } throw new IllegalStateException("unknown parameter spec: " + paramSpec); } static interface JCECallback { Object doInJCE() throws CMSException, InvalidAlgorithmParameterException, InvalidKeyException, InvalidParameterSpecException, NoSuchAlgorithmException, NoSuchPaddingException, NoSuchProviderException; } } bouncycastle-1.49.orig/jdk1.1/org/bouncycastle/cms/jcajce/ZlibExpanderProvider.java0000644000175000017500000000607711731466726027700 0ustar ebourgebourgpackage org.bouncycastle.cms.jcajce; import java.io.FilterInputStream; import java.io.IOException; import java.io.InputStream; import java.util.zip.InflaterInputStream; import org.bouncycastle.asn1.x509.AlgorithmIdentifier; import org.bouncycastle.operator.InputExpander; import org.bouncycastle.operator.InputExpanderProvider; import org.bouncycastle.util.io.StreamOverflowException; public class ZlibExpanderProvider implements InputExpanderProvider { private long limit; public ZlibExpanderProvider() { this.limit = -1; } /** * Create a provider which caps the number of expanded bytes that can be produced when the * compressed stream is parsed. * * @param limit max number of bytes allowed in an expanded stream. */ public ZlibExpanderProvider(long limit) { this.limit = limit; } public InputExpander get(final AlgorithmIdentifier algorithm) { return new InputExpander() { public AlgorithmIdentifier getAlgorithmIdentifier() { return algorithm; } public InputStream getInputStream(InputStream comIn) { InputStream s = new InflaterInputStream(comIn); if (limit >= 0) { s = new LimitedInputStream(s, limit); } return s; } }; } private static class LimitedInputStream extends FilterInputStream { private long remaining; public LimitedInputStream(InputStream input, long limit) { super(input); this.remaining = limit; } public int read() throws IOException { // Only a single 'extra' byte will ever be read if (remaining >= 0) { int b = super.in.read(); if (b < 0 || --remaining >= 0) { return b; } } throw new StreamOverflowException("expanded byte limit exceeded"); } public int read(byte[] buf, int off, int len) throws IOException { if (len < 1) { // This will give correct exceptions/returns for strange lengths return super.read(buf, off, len); } if (remaining < 1) { // Will either return EOF or throw exception read(); return -1; } /* * Limit the underlying request to 'remaining' bytes. This ensures the * caller will see the full 'limit' bytes before getting an exception. * Also, only one extra byte will ever be read. */ int actualLen = (remaining > len ? len : (int)remaining); int numRead = super.in.read(buf, off, actualLen); if (numRead > 0) { remaining -= numRead; } return numRead; } } } bouncycastle-1.49.orig/jdk1.1/org/bouncycastle/cms/jcajce/JcePasswordRecipient.java0000644000175000017500000000560311731466726027657 0ustar ebourgebourgpackage org.bouncycastle.cms.jcajce; import java.security.GeneralSecurityException; import java.security.Key; import java.security.Provider; import java.security.InvalidKeyException; import java.security.NoSuchAlgorithmException; import javax.crypto.Cipher; import javax.crypto.spec.IvParameterSpec; import javax.crypto.spec.SecretKeySpec; import org.bouncycastle.asn1.ASN1OctetString; import org.bouncycastle.asn1.x509.AlgorithmIdentifier; import org.bouncycastle.cms.CMSException; import org.bouncycastle.cms.PasswordRecipient; /** * the RecipientInfo class for a recipient who has been sent a message * encrypted using a password. */ public abstract class JcePasswordRecipient implements PasswordRecipient { private int schemeID = PasswordRecipient.PKCS5_SCHEME2_UTF8; protected EnvelopedDataHelper helper = new EnvelopedDataHelper(new DefaultJcaJceExtHelper()); private char[] password; JcePasswordRecipient( char[] password) { this.password = password; } public JcePasswordRecipient setPasswordConversionScheme(int schemeID) { this.schemeID = schemeID; return this; } public JcePasswordRecipient setProvider(Provider provider) { this.helper = new EnvelopedDataHelper(new ProviderJcaJceExtHelper(provider)); return this; } public JcePasswordRecipient setProvider(String providerName) { this.helper = new EnvelopedDataHelper(new NamedJcaJceExtHelper(providerName)); return this; } protected Key extractSecretKey(AlgorithmIdentifier keyEncryptionAlgorithm, AlgorithmIdentifier contentEncryptionAlgorithm, byte[] derivedKey, byte[] encryptedContentEncryptionKey) throws CMSException { Cipher keyEncryptionCipher = helper.createRFC3211Wrapper(keyEncryptionAlgorithm.getAlgorithm()); try { IvParameterSpec ivSpec = new IvParameterSpec(ASN1OctetString.getInstance(keyEncryptionAlgorithm.getParameters()).getOctets()); keyEncryptionCipher.init(Cipher.UNWRAP_MODE, new SecretKeySpec(derivedKey, keyEncryptionCipher.getAlgorithm()), ivSpec); return keyEncryptionCipher.unwrap(encryptedContentEncryptionKey, contentEncryptionAlgorithm.getAlgorithm().getId(), Cipher.SECRET_KEY); } catch (NoSuchAlgorithmException e) { throw new CMSException("cannot process content encryption key: " + e.getMessage(), e); } catch (InvalidKeyException e) { throw new CMSException("cannot process content encryption key: " + e.getMessage(), e); } catch (GeneralSecurityException e) { throw new CMSException("cannot process content encryption key: " + e.getMessage(), e); } } public int getPasswordConversionScheme() { return schemeID; } public char[] getPassword() { return password; } } bouncycastle-1.49.orig/jdk1.1/org/bouncycastle/cms/jcajce/JceKeyAgreeRecipient.java0000644000175000017500000001577211731466726027561 0ustar ebourgebourgpackage org.bouncycastle.cms.jcajce; import java.io.IOException; import java.security.GeneralSecurityException; import java.security.InvalidKeyException; import java.security.Key; import java.security.KeyFactory; import java.security.NoSuchAlgorithmException; import java.security.PrivateKey; import java.security.Provider; import java.security.PublicKey; import java.security.spec.InvalidKeySpecException; import java.security.spec.X509EncodedKeySpec; import javax.crypto.Cipher; import javax.crypto.KeyAgreement; import javax.crypto.NoSuchPaddingException; import javax.crypto.SecretKey; import org.bouncycastle.asn1.ASN1ObjectIdentifier; import org.bouncycastle.asn1.ASN1OctetString; import org.bouncycastle.asn1.ASN1Primitive; import org.bouncycastle.asn1.cms.ecc.MQVuserKeyingMaterial; import org.bouncycastle.asn1.pkcs.PrivateKeyInfo; import org.bouncycastle.asn1.x509.AlgorithmIdentifier; import org.bouncycastle.asn1.x509.SubjectPublicKeyInfo; import org.bouncycastle.cms.CMSEnvelopedGenerator; import org.bouncycastle.cms.CMSException; import org.bouncycastle.cms.KeyAgreeRecipient; import org.bouncycastle.jce.spec.MQVPrivateKeySpec; import org.bouncycastle.jce.spec.MQVPublicKeySpec; public abstract class JceKeyAgreeRecipient implements KeyAgreeRecipient { private PrivateKey recipientKey; protected EnvelopedDataHelper helper = new EnvelopedDataHelper(new DefaultJcaJceExtHelper()); protected EnvelopedDataHelper contentHelper = helper; public JceKeyAgreeRecipient(PrivateKey recipientKey) { this.recipientKey = recipientKey; } /** * Set the provider to use for key recovery and content processing. * * @param provider provider to use. * @return this recipient. */ public JceKeyAgreeRecipient setProvider(Provider provider) { this.helper = new EnvelopedDataHelper(new ProviderJcaJceExtHelper(provider)); this.contentHelper = helper; return this; } /** * Set the provider to use for key recovery and content processing. * * @param providerName the name of the provider to use. * @return this recipient. */ public JceKeyAgreeRecipient setProvider(String providerName) { this.helper = new EnvelopedDataHelper(new NamedJcaJceExtHelper(providerName)); this.contentHelper = helper; return this; } /** * Set the provider to use for content processing. If providerName is null a "no provider" search will be * used to satisfy getInstance calls. * * @param provider the provider to use. * @return this recipient. */ public JceKeyAgreeRecipient setContentProvider(Provider provider) { this.contentHelper = CMSUtils.createContentHelper(provider); return this; } /** * Set the provider to use for content processing. If providerName is null a "no provider" search will be * used to satisfy getInstance calls. * * @param providerName the name of the provider to use. * @return this recipient. */ public JceKeyAgreeRecipient setContentProvider(String providerName) { this.contentHelper = CMSUtils.createContentHelper(providerName); return this; } private SecretKey calculateAgreedWrapKey(AlgorithmIdentifier keyEncAlg, ASN1ObjectIdentifier wrapAlg, PublicKey senderPublicKey, ASN1OctetString userKeyingMaterial, PrivateKey receiverPrivateKey) throws CMSException, GeneralSecurityException, IOException, InvalidKeyException, NoSuchAlgorithmException { String agreeAlg = keyEncAlg.getAlgorithm().getId(); if (agreeAlg.equals(CMSEnvelopedGenerator.ECMQV_SHA1KDF)) { byte[] ukmEncoding = userKeyingMaterial.getOctets(); MQVuserKeyingMaterial ukm = MQVuserKeyingMaterial.getInstance( ASN1Primitive.fromByteArray(ukmEncoding)); SubjectPublicKeyInfo pubInfo = new SubjectPublicKeyInfo( getPrivateKeyAlgorithmIdentifier(), ukm.getEphemeralPublicKey().getPublicKey().getBytes()); X509EncodedKeySpec pubSpec = new X509EncodedKeySpec(pubInfo.getEncoded()); KeyFactory fact = helper.createKeyFactory(keyEncAlg.getAlgorithm()); PublicKey ephemeralKey = fact.generatePublic(pubSpec); senderPublicKey = new MQVPublicKeySpec(senderPublicKey, ephemeralKey); receiverPrivateKey = new MQVPrivateKeySpec(receiverPrivateKey, receiverPrivateKey); } KeyAgreement agreement = helper.createKeyAgreement(keyEncAlg.getAlgorithm()); agreement.init(receiverPrivateKey); agreement.doPhase(senderPublicKey, true); return agreement.generateSecret(wrapAlg.getId()); } private Key unwrapSessionKey(ASN1ObjectIdentifier wrapAlg, SecretKey agreedKey, ASN1ObjectIdentifier contentEncryptionAlgorithm, byte[] encryptedContentEncryptionKey) throws CMSException, InvalidKeyException, NoSuchAlgorithmException { Cipher keyCipher = helper.createCipher(wrapAlg); keyCipher.init(Cipher.UNWRAP_MODE, agreedKey); return keyCipher.unwrap(encryptedContentEncryptionKey, helper.getBaseCipherName(contentEncryptionAlgorithm), Cipher.SECRET_KEY); } protected Key extractSecretKey(AlgorithmIdentifier keyEncryptionAlgorithm, AlgorithmIdentifier contentEncryptionAlgorithm, SubjectPublicKeyInfo senderKey, ASN1OctetString userKeyingMaterial, byte[] encryptedContentEncryptionKey) throws CMSException { try { ASN1ObjectIdentifier wrapAlg = AlgorithmIdentifier.getInstance(keyEncryptionAlgorithm.getParameters()).getAlgorithm(); X509EncodedKeySpec pubSpec = new X509EncodedKeySpec(senderKey.getEncoded()); KeyFactory fact = helper.createKeyFactory(keyEncryptionAlgorithm.getAlgorithm()); PublicKey senderPublicKey = fact.generatePublic(pubSpec); SecretKey agreedWrapKey = calculateAgreedWrapKey(keyEncryptionAlgorithm, wrapAlg, senderPublicKey, userKeyingMaterial, recipientKey); return unwrapSessionKey(wrapAlg, agreedWrapKey, contentEncryptionAlgorithm.getAlgorithm(), encryptedContentEncryptionKey); } catch (NoSuchAlgorithmException e) { throw new CMSException("can't find algorithm.", e); } catch (InvalidKeyException e) { throw new CMSException("key invalid in message.", e); } catch (InvalidKeySpecException e) { throw new CMSException("originator key spec invalid.", e); } catch (NoSuchPaddingException e) { throw new CMSException("required padding not supported.", e); } catch (Exception e) { throw new CMSException("originator key invalid.", e); } } public AlgorithmIdentifier getPrivateKeyAlgorithmIdentifier() { return PrivateKeyInfo.getInstance(recipientKey.getEncoded()).getAlgorithmId(); } } bouncycastle-1.49.orig/jdk1.1/org/bouncycastle/cms/jcajce/JcePasswordRecipientInfoGenerator.java0000644000175000017500000000452511731466726032344 0ustar ebourgebourgpackage org.bouncycastle.cms.jcajce; import java.security.GeneralSecurityException; import java.security.Key; import java.security.Provider; import java.security.InvalidKeyException; import javax.crypto.Cipher; import javax.crypto.spec.IvParameterSpec; import javax.crypto.spec.SecretKeySpec; import org.bouncycastle.asn1.ASN1ObjectIdentifier; import org.bouncycastle.asn1.ASN1OctetString; import org.bouncycastle.asn1.x509.AlgorithmIdentifier; import org.bouncycastle.cms.CMSException; import org.bouncycastle.cms.PasswordRecipientInfoGenerator; import org.bouncycastle.operator.GenericKey; public class JcePasswordRecipientInfoGenerator extends PasswordRecipientInfoGenerator { private EnvelopedDataHelper helper = new EnvelopedDataHelper(new DefaultJcaJceExtHelper()); public JcePasswordRecipientInfoGenerator(ASN1ObjectIdentifier kekAlgorithm, char[] password) { super(kekAlgorithm, password); } public JcePasswordRecipientInfoGenerator setProvider(Provider provider) { this.helper = new EnvelopedDataHelper(new ProviderJcaJceExtHelper(provider)); return this; } public JcePasswordRecipientInfoGenerator setProvider(String providerName) { this.helper = new EnvelopedDataHelper(new NamedJcaJceExtHelper(providerName)); return this; } public byte[] generateEncryptedBytes(AlgorithmIdentifier keyEncryptionAlgorithm, byte[] derivedKey, GenericKey contentEncryptionKey) throws CMSException { Key contentEncryptionKeySpec = helper.getJceKey(contentEncryptionKey); Cipher keyEncryptionCipher = helper.createRFC3211Wrapper(keyEncryptionAlgorithm.getAlgorithm()); try { IvParameterSpec ivSpec = new IvParameterSpec(ASN1OctetString.getInstance(keyEncryptionAlgorithm.getParameters()).getOctets()); keyEncryptionCipher.init(Cipher.WRAP_MODE, new SecretKeySpec(derivedKey, keyEncryptionCipher.getAlgorithm()), ivSpec); return keyEncryptionCipher.wrap(contentEncryptionKeySpec); } catch (InvalidKeyException e) { throw new CMSException("cannot process content encryption key: " + e.getMessage(), e); } catch (GeneralSecurityException e) { throw new CMSException("cannot process content encryption key: " + e.getMessage(), e); } } } bouncycastle-1.49.orig/jdk1.1/org/bouncycastle/cms/jcajce/JcaSelectorConverter.java0000644000175000017500000000313611731466726027655 0ustar ebourgebourgpackage org.bouncycastle.cms.jcajce; import java.security.cert.X509CertSelector; import org.bouncycastle.asn1.ASN1OctetString; import org.bouncycastle.asn1.x500.X500Name; import org.bouncycastle.cms.KeyTransRecipientId; import org.bouncycastle.cms.SignerId; public class JcaSelectorConverter { public JcaSelectorConverter() { } public SignerId getSignerId(X509CertSelector certSelector) { try { if (certSelector.getSubjectKeyIdentifier() != null) { return new SignerId(X500Name.getInstance(certSelector.getIssuerAsBytes()), certSelector.getSerialNumber(), ASN1OctetString.getInstance(certSelector.getSubjectKeyIdentifier()).getOctets()); } else { return new SignerId(X500Name.getInstance(certSelector.getIssuerAsBytes()), certSelector.getSerialNumber()); } } catch (Exception e) { throw new IllegalArgumentException("conversion failed: " + e.toString()); } } public KeyTransRecipientId getKeyTransRecipientId(X509CertSelector certSelector) { try { if (certSelector.getSubjectKeyIdentifier() != null) { return new KeyTransRecipientId(X500Name.getInstance(certSelector.getIssuerAsBytes()), certSelector.getSerialNumber(), ASN1OctetString.getInstance(certSelector.getSubjectKeyIdentifier()).getOctets()); } else { return new KeyTransRecipientId(X500Name.getInstance(certSelector.getIssuerAsBytes()), certSelector.getSerialNumber()); } } catch (Exception e) { throw new IllegalArgumentException("conversion failed: " + e.toString()); } } } bouncycastle-1.49.orig/jdk1.1/org/bouncycastle/cms/CMSProcessableByteArray.java0000644000175000017500000000222511731466725026775 0ustar ebourgebourgpackage org.bouncycastle.cms; import java.io.ByteArrayInputStream; import java.io.IOException; import java.io.InputStream; import java.io.OutputStream; import org.bouncycastle.asn1.ASN1ObjectIdentifier; import org.bouncycastle.asn1.cms.CMSObjectIdentifiers; /** * a holding class for a byte array of data to be processed. */ public class CMSProcessableByteArray implements CMSTypedData, CMSReadable { private ASN1ObjectIdentifier type; private byte[] bytes; public CMSProcessableByteArray( byte[] bytes) { this(new ASN1ObjectIdentifier(CMSObjectIdentifiers.data.getId()), bytes); } public CMSProcessableByteArray( ASN1ObjectIdentifier type, byte[] bytes) { this.type = type; this.bytes = bytes; } public InputStream getInputStream() { return new ByteArrayInputStream(bytes); } public void write(OutputStream zOut) throws IOException, CMSException { zOut.write(bytes); } public Object getContent() { return bytes.clone(); } public ASN1ObjectIdentifier getContentType() { return type; } } bouncycastle-1.49.orig/jdk1.1/org/bouncycastle/cms/CMSSignedHelper.java0000644000175000017500000003517611731466726025275 0ustar ebourgebourgpackage org.bouncycastle.cms; import java.io.ByteArrayInputStream; import java.io.IOException; import java.security.InvalidAlgorithmParameterException; import java.security.NoSuchAlgorithmException; import java.security.NoSuchProviderException; import java.security.Provider; import java.security.cert.CRLException; import java.security.cert.CertStore; import java.security.cert.CertificateException; import java.security.cert.CertificateFactory; import java.security.cert.CollectionCertStoreParameters; import java.util.ArrayList; import java.util.Enumeration; import java.util.HashMap; import java.util.List; import java.util.Map; import org.bouncycastle.asn1.ASN1Encodable; import org.bouncycastle.asn1.ASN1Primitive; import org.bouncycastle.asn1.ASN1Sequence; import org.bouncycastle.asn1.ASN1Set; import org.bouncycastle.asn1.ASN1TaggedObject; import org.bouncycastle.asn1.DERNull; import org.bouncycastle.asn1.DERObjectIdentifier; import org.bouncycastle.asn1.cryptopro.CryptoProObjectIdentifiers; import org.bouncycastle.asn1.eac.EACObjectIdentifiers; import org.bouncycastle.asn1.nist.NISTObjectIdentifiers; import org.bouncycastle.asn1.oiw.OIWObjectIdentifiers; import org.bouncycastle.asn1.pkcs.PKCSObjectIdentifiers; import org.bouncycastle.asn1.teletrust.TeleTrusTObjectIdentifiers; import org.bouncycastle.asn1.x509.AlgorithmIdentifier; import org.bouncycastle.asn1.x509.X509ObjectIdentifiers; import org.bouncycastle.asn1.x9.X9ObjectIdentifiers; import org.bouncycastle.x509.NoSuchStoreException; import org.bouncycastle.x509.X509CollectionStoreParameters; import org.bouncycastle.x509.X509Store; import org.bouncycastle.x509.X509V2AttributeCertificate; class CMSSignedHelper { static final CMSSignedHelper INSTANCE = new CMSSignedHelper(); private static final Map encryptionAlgs = new HashMap(); private static final Map digestAlgs = new HashMap(); private static final Map digestAliases = new HashMap(); private static void addEntries(DERObjectIdentifier alias, String digest, String encryption) { digestAlgs.put(alias.getId(), digest); encryptionAlgs.put(alias.getId(), encryption); } static { addEntries(NISTObjectIdentifiers.dsa_with_sha224, "SHA224", "DSA"); addEntries(NISTObjectIdentifiers.dsa_with_sha256, "SHA256", "DSA"); addEntries(NISTObjectIdentifiers.dsa_with_sha384, "SHA384", "DSA"); addEntries(NISTObjectIdentifiers.dsa_with_sha512, "SHA512", "DSA"); addEntries(OIWObjectIdentifiers.dsaWithSHA1, "SHA1", "DSA"); addEntries(OIWObjectIdentifiers.md4WithRSA, "MD4", "RSA"); addEntries(OIWObjectIdentifiers.md4WithRSAEncryption, "MD4", "RSA"); addEntries(OIWObjectIdentifiers.md5WithRSA, "MD5", "RSA"); addEntries(OIWObjectIdentifiers.sha1WithRSA, "SHA1", "RSA"); addEntries(PKCSObjectIdentifiers.md2WithRSAEncryption, "MD2", "RSA"); addEntries(PKCSObjectIdentifiers.md4WithRSAEncryption, "MD4", "RSA"); addEntries(PKCSObjectIdentifiers.md5WithRSAEncryption, "MD5", "RSA"); addEntries(PKCSObjectIdentifiers.sha1WithRSAEncryption, "SHA1", "RSA"); addEntries(PKCSObjectIdentifiers.sha224WithRSAEncryption, "SHA224", "RSA"); addEntries(PKCSObjectIdentifiers.sha256WithRSAEncryption, "SHA256", "RSA"); addEntries(PKCSObjectIdentifiers.sha384WithRSAEncryption, "SHA384", "RSA"); addEntries(PKCSObjectIdentifiers.sha512WithRSAEncryption, "SHA512", "RSA"); addEntries(X9ObjectIdentifiers.ecdsa_with_SHA1, "SHA1", "ECDSA"); addEntries(X9ObjectIdentifiers.ecdsa_with_SHA224, "SHA224", "ECDSA"); addEntries(X9ObjectIdentifiers.ecdsa_with_SHA256, "SHA256", "ECDSA"); addEntries(X9ObjectIdentifiers.ecdsa_with_SHA384, "SHA384", "ECDSA"); addEntries(X9ObjectIdentifiers.ecdsa_with_SHA512, "SHA512", "ECDSA"); addEntries(X9ObjectIdentifiers.id_dsa_with_sha1, "SHA1", "DSA"); addEntries(EACObjectIdentifiers.id_TA_ECDSA_SHA_1, "SHA1", "ECDSA"); addEntries(EACObjectIdentifiers.id_TA_ECDSA_SHA_224, "SHA224", "ECDSA"); addEntries(EACObjectIdentifiers.id_TA_ECDSA_SHA_256, "SHA256", "ECDSA"); addEntries(EACObjectIdentifiers.id_TA_ECDSA_SHA_384, "SHA384", "ECDSA"); addEntries(EACObjectIdentifiers.id_TA_ECDSA_SHA_512, "SHA512", "ECDSA"); addEntries(EACObjectIdentifiers.id_TA_RSA_v1_5_SHA_1, "SHA1", "RSA"); addEntries(EACObjectIdentifiers.id_TA_RSA_v1_5_SHA_256, "SHA256", "RSA"); addEntries(EACObjectIdentifiers.id_TA_RSA_PSS_SHA_1, "SHA1", "RSAandMGF1"); addEntries(EACObjectIdentifiers.id_TA_RSA_PSS_SHA_256, "SHA256", "RSAandMGF1"); encryptionAlgs.put(X9ObjectIdentifiers.id_dsa.getId(), "DSA"); encryptionAlgs.put(PKCSObjectIdentifiers.rsaEncryption.getId(), "RSA"); encryptionAlgs.put(TeleTrusTObjectIdentifiers.teleTrusTRSAsignatureAlgorithm, "RSA"); encryptionAlgs.put(X509ObjectIdentifiers.id_ea_rsa.getId(), "RSA"); encryptionAlgs.put(CMSSignedDataGenerator.ENCRYPTION_RSA_PSS, "RSAandMGF1"); encryptionAlgs.put(CryptoProObjectIdentifiers.gostR3410_94.getId(), "GOST3410"); encryptionAlgs.put(CryptoProObjectIdentifiers.gostR3410_2001.getId(), "ECGOST3410"); encryptionAlgs.put("1.3.6.1.4.1.5849.1.6.2", "ECGOST3410"); encryptionAlgs.put("1.3.6.1.4.1.5849.1.1.5", "GOST3410"); encryptionAlgs.put(CryptoProObjectIdentifiers.gostR3411_94_with_gostR3410_2001.getId(), "ECGOST3410"); encryptionAlgs.put(CryptoProObjectIdentifiers.gostR3411_94_with_gostR3410_94.getId(), "GOST3410"); digestAlgs.put(PKCSObjectIdentifiers.md2.getId(), "MD2"); digestAlgs.put(PKCSObjectIdentifiers.md4.getId(), "MD4"); digestAlgs.put(PKCSObjectIdentifiers.md5.getId(), "MD5"); digestAlgs.put(OIWObjectIdentifiers.idSHA1.getId(), "SHA1"); digestAlgs.put(NISTObjectIdentifiers.id_sha224.getId(), "SHA224"); digestAlgs.put(NISTObjectIdentifiers.id_sha256.getId(), "SHA256"); digestAlgs.put(NISTObjectIdentifiers.id_sha384.getId(), "SHA384"); digestAlgs.put(NISTObjectIdentifiers.id_sha512.getId(), "SHA512"); digestAlgs.put(TeleTrusTObjectIdentifiers.ripemd128.getId(), "RIPEMD128"); digestAlgs.put(TeleTrusTObjectIdentifiers.ripemd160.getId(), "RIPEMD160"); digestAlgs.put(TeleTrusTObjectIdentifiers.ripemd256.getId(), "RIPEMD256"); digestAlgs.put(CryptoProObjectIdentifiers.gostR3411.getId(), "GOST3411"); digestAlgs.put("1.3.6.1.4.1.5849.1.2.1", "GOST3411"); digestAliases.put("SHA1", new String[] { "SHA-1" }); digestAliases.put("SHA224", new String[] { "SHA-224" }); digestAliases.put("SHA256", new String[] { "SHA-256" }); digestAliases.put("SHA384", new String[] { "SHA-384" }); digestAliases.put("SHA512", new String[] { "SHA-512" }); } /** * Return the digest algorithm using one of the standard JCA string * representations rather than the algorithm identifier (if possible). */ String getDigestAlgName( String digestAlgOID) { String algName = (String)digestAlgs.get(digestAlgOID); if (algName != null) { return algName; } return digestAlgOID; } /** * Return the digest encryption algorithm using one of the standard * JCA string representations rather the the algorithm identifier (if * possible). */ String getEncryptionAlgName( String encryptionAlgOID) { String algName = (String)encryptionAlgs.get(encryptionAlgOID); if (algName != null) { return algName; } return encryptionAlgOID; } X509Store createAttributeStore( String type, Provider provider, ASN1Set certSet) throws NoSuchStoreException, CMSException { List certs = new ArrayList(); if (certSet != null) { Enumeration e = certSet.getObjects(); while (e.hasMoreElements()) { try { ASN1Primitive obj = ((ASN1Encodable)e.nextElement()).toASN1Primitive(); if (obj instanceof ASN1TaggedObject) { ASN1TaggedObject tagged = (ASN1TaggedObject)obj; if (tagged.getTagNo() == 2) { certs.add(new X509V2AttributeCertificate(ASN1Sequence.getInstance(tagged, false).getEncoded())); } } } catch (IOException ex) { throw new CMSException( "can't re-encode attribute certificate!", ex); } } } try { return X509Store.getInstance( "AttributeCertificate/" +type, new X509CollectionStoreParameters(certs), provider); } catch (IllegalArgumentException e) { throw new CMSException("can't setup the X509Store", e); } } X509Store createCertificateStore( String type, Provider provider, ASN1Set certSet) throws NoSuchStoreException, CMSException { List certs = new ArrayList(); if (certSet != null) { addCertsFromSet(certs, certSet, provider); } try { return X509Store.getInstance( "Certificate/" +type, new X509CollectionStoreParameters(certs), provider); } catch (IllegalArgumentException e) { throw new CMSException("can't setup the X509Store", e); } } X509Store createCRLsStore( String type, Provider provider, ASN1Set crlSet) throws NoSuchStoreException, CMSException { List crls = new ArrayList(); if (crlSet != null) { addCRLsFromSet(crls, crlSet, provider); } try { return X509Store.getInstance( "CRL/" +type, new X509CollectionStoreParameters(crls), provider); } catch (IllegalArgumentException e) { throw new CMSException("can't setup the X509Store", e); } } CertStore createCertStore( String type, Provider provider, ASN1Set certSet, ASN1Set crlSet) throws CMSException, NoSuchAlgorithmException { List certsAndcrls = new ArrayList(); // // load the certificates and revocation lists if we have any // if (certSet != null) { addCertsFromSet(certsAndcrls, certSet, provider); } if (crlSet != null) { addCRLsFromSet(certsAndcrls, crlSet, provider); } try { if (provider != null) { return CertStore.getInstance(type, new CollectionCertStoreParameters(certsAndcrls), provider.getName()); } else { return CertStore.getInstance(type, new CollectionCertStoreParameters(certsAndcrls)); } } catch (InvalidAlgorithmParameterException e) { throw new CMSException("can't setup the CertStore", e); } catch (NoSuchProviderException e) { throw new CMSException("can't setup the CertStore", e); } } private void addCertsFromSet(List certs, ASN1Set certSet, Provider provider) throws CMSException { CertificateFactory cf; try { if (provider != null) { cf = CertificateFactory.getInstance("X.509", provider.getName()); } else { cf = CertificateFactory.getInstance("X.509"); } } catch (CertificateException ex) { throw new CMSException("can't get certificate factory.", ex); } catch (NoSuchProviderException ex) { throw new CMSException("can't get certificate factory.", ex); } Enumeration e = certSet.getObjects(); while (e.hasMoreElements()) { try { ASN1Primitive obj = ((ASN1Encodable)e.nextElement()).toASN1Primitive(); if (obj instanceof ASN1Sequence) { certs.add(cf.generateCertificate( new ByteArrayInputStream(obj.getEncoded()))); } } catch (IOException ex) { throw new CMSException( "can't re-encode certificate!", ex); } catch (CertificateException ex) { throw new CMSException( "can't re-encode certificate!", ex); } } } private void addCRLsFromSet(List crls, ASN1Set certSet, Provider provider) throws CMSException { CertificateFactory cf; try { if (provider != null) { cf = CertificateFactory.getInstance("X.509", provider.getName()); } else { cf = CertificateFactory.getInstance("X.509"); } } catch (CertificateException ex) { throw new CMSException("can't get certificate factory.", ex); } catch (NoSuchProviderException ex) { throw new CMSException("can't get certificate factory.", ex); } Enumeration e = certSet.getObjects(); while (e.hasMoreElements()) { try { ASN1Primitive obj = ((ASN1Encodable)e.nextElement()).toASN1Primitive(); crls.add(cf.generateCRL( new ByteArrayInputStream(obj.getEncoded()))); } catch (IOException ex) { throw new CMSException("can't re-encode CRL!", ex); } catch (CRLException ex) { throw new CMSException("can't re-encode CRL!", ex); } } } AlgorithmIdentifier fixAlgID(AlgorithmIdentifier algId) { if (algId.getParameters() == null) { return new AlgorithmIdentifier(algId.getObjectId(), DERNull.INSTANCE); } return algId; } void setSigningEncryptionAlgorithmMapping(DERObjectIdentifier oid, String algorithmName) { encryptionAlgs.put(oid.getId(), algorithmName); } void setSigningDigestAlgorithmMapping(DERObjectIdentifier oid, String algorithmName) { digestAlgs.put(oid.getId(), algorithmName); } } bouncycastle-1.49.orig/jdk1.1/org/bouncycastle/cms/CMSProcessableFile.java0000644000175000017500000000341011731466725025747 0ustar ebourgebourgpackage org.bouncycastle.cms; import java.io.BufferedInputStream; import java.io.File; import java.io.FileInputStream; import java.io.IOException; import java.io.InputStream; import java.io.OutputStream; import org.bouncycastle.asn1.ASN1ObjectIdentifier; import org.bouncycastle.asn1.cms.CMSObjectIdentifiers; /** * a holding class for a file of data to be processed. */ public class CMSProcessableFile implements CMSTypedData, CMSReadable { private static final int DEFAULT_BUF_SIZE = 32 * 1024; private ASN1ObjectIdentifier type; private File file; private byte[] buf; public CMSProcessableFile( File file) { this(file, DEFAULT_BUF_SIZE); } public CMSProcessableFile( File file, int bufSize) { this(new ASN1ObjectIdentifier(CMSObjectIdentifiers.data.getId()), file, bufSize); } public CMSProcessableFile( ASN1ObjectIdentifier type, File file, int bufSize) { this.type = type; this.file = file; buf = new byte[bufSize]; } public InputStream getInputStream() throws IOException, CMSException { return new BufferedInputStream(new FileInputStream(file), DEFAULT_BUF_SIZE); } public void write(OutputStream zOut) throws IOException, CMSException { FileInputStream fIn = new FileInputStream(file); int len; while ((len = fIn.read(buf, 0, buf.length)) > 0) { zOut.write(buf, 0, len); } fIn.close(); } /** * Return the file handle. */ public Object getContent() { return file; } public ASN1ObjectIdentifier getContentType() { return type; } } bouncycastle-1.49.orig/jdk1.1/org/bouncycastle/tsp/0000755000175000017500000000000012152033551021506 5ustar ebourgebourgbouncycastle-1.49.orig/jdk1.1/org/bouncycastle/tsp/TimeStampTokenGenerator.java0000644000175000017500000003606711731466727027161 0ustar ebourgebourgpackage org.bouncycastle.tsp; import java.io.IOException; import java.math.BigInteger; import java.security.MessageDigest; import java.security.NoSuchAlgorithmException; import java.security.NoSuchProviderException; import java.security.PrivateKey; import java.security.cert.CRLException; import java.security.cert.CertStore; import java.security.cert.CertStoreException; import java.security.cert.CertificateEncodingException; import java.security.cert.X509CRL; import java.security.cert.X509Certificate; import java.security.interfaces.DSAPrivateKey; import java.security.interfaces.RSAPrivateKey; import java.util.ArrayList; import java.util.Collection; import java.util.Date; import java.util.Hashtable; import java.util.Iterator; import java.util.List; import java.util.Map; import org.bouncycastle.asn1.ASN1Boolean; import org.bouncycastle.asn1.ASN1Encoding; import org.bouncycastle.asn1.ASN1GeneralizedTime; import org.bouncycastle.asn1.ASN1Integer; import org.bouncycastle.asn1.ASN1ObjectIdentifier; import org.bouncycastle.asn1.DERNull; import org.bouncycastle.asn1.DERSet; import org.bouncycastle.asn1.cms.Attribute; import org.bouncycastle.asn1.cms.AttributeTable; import org.bouncycastle.asn1.ess.ESSCertID; import org.bouncycastle.asn1.ess.SigningCertificate; import org.bouncycastle.asn1.pkcs.PKCSObjectIdentifiers; import org.bouncycastle.asn1.tsp.Accuracy; import org.bouncycastle.asn1.tsp.MessageImprint; import org.bouncycastle.asn1.tsp.TSTInfo; import org.bouncycastle.asn1.x509.AlgorithmIdentifier; import org.bouncycastle.asn1.x509.GeneralName; import org.bouncycastle.cert.jcajce.JcaX509CRLHolder; import org.bouncycastle.cert.jcajce.JcaX509CertificateHolder; import org.bouncycastle.cms.CMSAttributeTableGenerationException; import org.bouncycastle.cms.CMSAttributeTableGenerator; import org.bouncycastle.cms.CMSException; import org.bouncycastle.cms.CMSProcessableByteArray; import org.bouncycastle.cms.CMSSignedData; import org.bouncycastle.cms.CMSSignedDataGenerator; import org.bouncycastle.cms.CMSSignedGenerator; import org.bouncycastle.cms.DefaultSignedAttributeTableGenerator; import org.bouncycastle.cms.SignerInfoGenerator; import org.bouncycastle.cms.SimpleAttributeTableGenerator; import org.bouncycastle.cms.jcajce.JcaSignerInfoGeneratorBuilder; import org.bouncycastle.jce.interfaces.GOST3410PrivateKey; import org.bouncycastle.operator.OperatorCreationException; import org.bouncycastle.operator.jcajce.JcaContentSignerBuilder; import org.bouncycastle.operator.jcajce.JcaDigestCalculatorProviderBuilder; import org.bouncycastle.util.CollectionStore; import org.bouncycastle.util.Store; public class TimeStampTokenGenerator { int accuracySeconds = -1; int accuracyMillis = -1; int accuracyMicros = -1; boolean ordering = false; GeneralName tsa = null; private ASN1ObjectIdentifier tsaPolicyOID; PrivateKey key; X509Certificate cert; String digestOID; AttributeTable signedAttr; AttributeTable unsignedAttr; private List certs = new ArrayList(); private List crls = new ArrayList(); private List attrCerts = new ArrayList(); private SignerInfoGenerator signerInfoGen; /** * */ public TimeStampTokenGenerator( final SignerInfoGenerator signerInfoGen, ASN1ObjectIdentifier tsaPolicy) throws IllegalArgumentException, TSPException { this.signerInfoGen = signerInfoGen; this.tsaPolicyOID = tsaPolicy; if (!signerInfoGen.hasAssociatedCertificate()) { throw new IllegalArgumentException("SignerInfoGenerator must have an associated certificate"); } TSPUtil.validateCertificate(signerInfoGen.getAssociatedCertificate()); try { final ESSCertID essCertid = new ESSCertID(MessageDigest.getInstance("SHA-1").digest(signerInfoGen.getAssociatedCertificate().getEncoded())); this.signerInfoGen = new SignerInfoGenerator(signerInfoGen, new CMSAttributeTableGenerator() { public AttributeTable getAttributes(Map parameters) throws CMSAttributeTableGenerationException { AttributeTable table = signerInfoGen.getSignedAttributeTableGenerator().getAttributes(parameters); return table.add(PKCSObjectIdentifiers.id_aa_signingCertificate, new SigningCertificate(essCertid)); } }, signerInfoGen.getUnsignedAttributeTableGenerator()); } catch (NoSuchAlgorithmException e) { throw new TSPException("Can't find a SHA-1 implementation.", e); } catch (IOException e) { throw new TSPException("Exception processing certificate.", e); } } /** * basic creation - only the default attributes will be included here. * @deprecated use SignerInfoGenerator constructor */ public TimeStampTokenGenerator( PrivateKey key, X509Certificate cert, String digestOID, String tsaPolicyOID) throws IllegalArgumentException, TSPException { this(key, cert, digestOID, tsaPolicyOID, null, null); } /** * basic creation - only the default attributes will be included here. * @deprecated use SignerInfoGenerator constructor */ public TimeStampTokenGenerator( PrivateKey key, X509Certificate cert, ASN1ObjectIdentifier digestOID, String tsaPolicyOID) throws IllegalArgumentException, TSPException { this(key, cert, digestOID.getId(), tsaPolicyOID, null, null); } /** * create with a signer with extra signed/unsigned attributes. * @deprecated use SignerInfoGenerator constructor */ public TimeStampTokenGenerator( PrivateKey key, X509Certificate cert, String digestOID, String tsaPolicyOID, AttributeTable signedAttr, AttributeTable unsignedAttr) throws IllegalArgumentException, TSPException { this.key = key; this.cert = cert; this.digestOID = digestOID; this.tsaPolicyOID = new ASN1ObjectIdentifier(tsaPolicyOID); this.unsignedAttr = unsignedAttr; // // add the essCertid // Hashtable signedAttrs = null; if (signedAttr != null) { signedAttrs = signedAttr.toHashtable(); } else { signedAttrs = new Hashtable(); } TSPUtil.validateCertificate(cert); try { ESSCertID essCertid = new ESSCertID(MessageDigest.getInstance("SHA-1").digest(cert.getEncoded())); signedAttrs.put(PKCSObjectIdentifiers.id_aa_signingCertificate, new Attribute( PKCSObjectIdentifiers.id_aa_signingCertificate, new DERSet(new SigningCertificate(essCertid)))); } catch (NoSuchAlgorithmException e) { throw new TSPException("Can't find a SHA-1 implementation.", e); } catch (CertificateEncodingException e) { throw new TSPException("Exception processing certificate.", e); } this.signedAttr = new AttributeTable(signedAttrs); } /** * @deprecated use addCertificates and addCRLs * @param certificates * @throws CertStoreException * @throws TSPException */ public void setCertificatesAndCRLs(CertStore certificates) throws CertStoreException, TSPException { Collection c1 = certificates.getCertificates(null); for (Iterator it = c1.iterator(); it.hasNext();) { try { certs.add(new JcaX509CertificateHolder((X509Certificate)it.next())); } catch (CertificateEncodingException e) { throw new TSPException("cannot encode certificate: " + e.getMessage(), e); } } c1 = certificates.getCRLs(null); for (Iterator it = c1.iterator(); it.hasNext();) { try { crls.add(new JcaX509CRLHolder((X509CRL)it.next())); } catch (CRLException e) { throw new TSPException("cannot encode CRL: " + e.getMessage(), e); } } } /** * Add the store of X509 Certificates to the generator. * * @param certStore a Store containing X509CertificateHolder objects */ public void addCertificates( Store certStore) { certs.addAll(certStore.getMatches(null)); } /** * * @param crlStore a Store containing X509CRLHolder objects. */ public void addCRLs( Store crlStore) { crls.addAll(crlStore.getMatches(null)); } /** * * @param attrStore a Store containing X509AttributeCertificate objects. */ public void addAttributeCertificates( Store attrStore) { attrCerts.addAll(attrStore.getMatches(null)); } public void setAccuracySeconds(int accuracySeconds) { this.accuracySeconds = accuracySeconds; } public void setAccuracyMillis(int accuracyMillis) { this.accuracyMillis = accuracyMillis; } public void setAccuracyMicros(int accuracyMicros) { this.accuracyMicros = accuracyMicros; } public void setOrdering(boolean ordering) { this.ordering = ordering; } public void setTSA(GeneralName tsa) { this.tsa = tsa; } //------------------------------------------------------------------------------ public TimeStampToken generate( TimeStampRequest request, BigInteger serialNumber, Date genTime, String provider) throws NoSuchAlgorithmException, NoSuchProviderException, TSPException { if (signerInfoGen == null) { try { JcaSignerInfoGeneratorBuilder sigBuilder = new JcaSignerInfoGeneratorBuilder(new JcaDigestCalculatorProviderBuilder().setProvider(provider).build()); sigBuilder.setSignedAttributeGenerator(new DefaultSignedAttributeTableGenerator(signedAttr)); if (unsignedAttr != null) { sigBuilder.setUnsignedAttributeGenerator(new SimpleAttributeTableGenerator(unsignedAttr)); } signerInfoGen = sigBuilder.build(new JcaContentSignerBuilder(getSigAlgorithm(key, digestOID)).setProvider(provider).build(key), cert); } catch (OperatorCreationException e) { throw new TSPException("Error generating signing operator", e); } catch (CertificateEncodingException e) { throw new TSPException("Error encoding certificate", e); } } return generate(request, serialNumber, genTime); } public TimeStampToken generate( TimeStampRequest request, BigInteger serialNumber, Date genTime) throws TSPException { if (signerInfoGen == null) { throw new IllegalStateException("can only use this method with SignerInfoGenerator constructor"); } ASN1ObjectIdentifier digestAlgOID = request.getMessageImprintAlgOID(); AlgorithmIdentifier algID = new AlgorithmIdentifier(digestAlgOID, new DERNull()); MessageImprint messageImprint = new MessageImprint(algID, request.getMessageImprintDigest()); Accuracy accuracy = null; if (accuracySeconds > 0 || accuracyMillis > 0 || accuracyMicros > 0) { ASN1Integer seconds = null; if (accuracySeconds > 0) { seconds = new ASN1Integer(accuracySeconds); } ASN1Integer millis = null; if (accuracyMillis > 0) { millis = new ASN1Integer(accuracyMillis); } ASN1Integer micros = null; if (accuracyMicros > 0) { micros = new ASN1Integer(accuracyMicros); } accuracy = new Accuracy(seconds, millis, micros); } ASN1Boolean derOrdering = null; if (ordering) { derOrdering = new ASN1Boolean(ordering); } ASN1Integer nonce = null; if (request.getNonce() != null) { nonce = new ASN1Integer(request.getNonce()); } ASN1ObjectIdentifier tsaPolicy = tsaPolicyOID; if (request.getReqPolicy() != null) { tsaPolicy = request.getReqPolicy(); } TSTInfo tstInfo = new TSTInfo(tsaPolicy, messageImprint, new ASN1Integer(serialNumber), new ASN1GeneralizedTime(genTime), accuracy, derOrdering, nonce, tsa, request.getExtensions()); try { CMSSignedDataGenerator signedDataGenerator = new CMSSignedDataGenerator(); if (request.getCertReq()) { // TODO: do we need to check certs non-empty? signedDataGenerator.addCertificates(new CollectionStore(certs)); signedDataGenerator.addCRLs(new CollectionStore(crls)); signedDataGenerator.addAttributeCertificates(new CollectionStore(attrCerts)); } else { signedDataGenerator.addCRLs(new CollectionStore(crls)); } signedDataGenerator.addSignerInfoGenerator(signerInfoGen); byte[] derEncodedTSTInfo = tstInfo.getEncoded(ASN1Encoding.DER); CMSSignedData signedData = signedDataGenerator.generate(new CMSProcessableByteArray(PKCSObjectIdentifiers.id_ct_TSTInfo, derEncodedTSTInfo), true); return new TimeStampToken(signedData); } catch (CMSException cmsEx) { throw new TSPException("Error generating time-stamp token", cmsEx); } catch (IOException e) { throw new TSPException("Exception encoding info", e); } } private String getSigAlgorithm( PrivateKey key, String digestOID) { String enc = null; if (key instanceof RSAPrivateKey || "RSA".equalsIgnoreCase(key.getAlgorithm())) { enc = "RSA"; } else if (key instanceof DSAPrivateKey || "DSA".equalsIgnoreCase(key.getAlgorithm())) { enc = "DSA"; } else if ("ECDSA".equalsIgnoreCase(key.getAlgorithm()) || "EC".equalsIgnoreCase(key.getAlgorithm())) { enc = "ECDSA"; } else if (key instanceof GOST3410PrivateKey || "GOST3410".equalsIgnoreCase(key.getAlgorithm())) { enc = "GOST3410"; } else if ("ECGOST3410".equalsIgnoreCase(key.getAlgorithm())) { enc = CMSSignedGenerator.ENCRYPTION_ECGOST3410; } return TSPUtil.getDigestAlgName(digestOID) + "with" + enc; } } bouncycastle-1.49.orig/jdk1.1/org/bouncycastle/tsp/TimeStampToken.java0000644000175000017500000003766712105031243025272 0ustar ebourgebourgpackage org.bouncycastle.tsp; import java.io.ByteArrayInputStream; import java.io.ByteArrayOutputStream; import java.io.IOException; import java.io.OutputStream; import java.security.MessageDigest; import java.security.NoSuchAlgorithmException; import java.security.NoSuchProviderException; import java.security.cert.CertStore; import java.security.cert.CertificateEncodingException; import java.security.cert.CertificateExpiredException; import java.security.cert.CertificateNotYetValidException; import java.security.cert.X509Certificate; import java.util.Collection; import java.util.Date; import org.bouncycastle.asn1.ASN1InputStream; import org.bouncycastle.asn1.cms.Attribute; import org.bouncycastle.asn1.cms.AttributeTable; import org.bouncycastle.asn1.cms.ContentInfo; import org.bouncycastle.asn1.cms.IssuerAndSerialNumber; import org.bouncycastle.asn1.ess.ESSCertID; import org.bouncycastle.asn1.ess.ESSCertIDv2; import org.bouncycastle.asn1.ess.SigningCertificate; import org.bouncycastle.asn1.ess.SigningCertificateV2; import org.bouncycastle.asn1.nist.NISTObjectIdentifiers; import org.bouncycastle.asn1.oiw.OIWObjectIdentifiers; import org.bouncycastle.asn1.pkcs.PKCSObjectIdentifiers; import org.bouncycastle.asn1.tsp.TSTInfo; import org.bouncycastle.asn1.x500.X500Name; import org.bouncycastle.asn1.x509.AlgorithmIdentifier; import org.bouncycastle.asn1.x509.GeneralName; import org.bouncycastle.asn1.x509.IssuerSerial; import org.bouncycastle.asn1.x509.X509Name; import org.bouncycastle.cert.X509CertificateHolder; import org.bouncycastle.cms.CMSException; import org.bouncycastle.cms.CMSProcessable; import org.bouncycastle.cms.CMSSignedData; import org.bouncycastle.cms.SignerId; import org.bouncycastle.cms.SignerInformation; import org.bouncycastle.cms.SignerInformationVerifier; import org.bouncycastle.jce.PrincipalUtil; import org.bouncycastle.jce.X509Principal; import org.bouncycastle.operator.DigestCalculator; import org.bouncycastle.operator.OperatorCreationException; import org.bouncycastle.util.Arrays; import org.bouncycastle.util.Store; public class TimeStampToken { CMSSignedData tsToken; SignerInformation tsaSignerInfo; Date genTime; TimeStampTokenInfo tstInfo; CertID certID; public TimeStampToken(ContentInfo contentInfo) throws TSPException, IOException { this(getSignedData(contentInfo)); } private static CMSSignedData getSignedData(ContentInfo contentInfo) throws TSPException { try { return new CMSSignedData(contentInfo); } catch (CMSException e) { throw new TSPException("TSP parsing error: " + e.getMessage(), e.getCause()); } } public TimeStampToken(CMSSignedData signedData) throws TSPException, IOException { this.tsToken = signedData; if (!this.tsToken.getSignedContentTypeOID().equals(PKCSObjectIdentifiers.id_ct_TSTInfo.getId())) { throw new TSPValidationException("ContentInfo object not for a time stamp."); } Collection signers = tsToken.getSignerInfos().getSigners(); if (signers.size() != 1) { throw new IllegalArgumentException("Time-stamp token signed by " + signers.size() + " signers, but it must contain just the TSA signature."); } tsaSignerInfo = (SignerInformation)signers.iterator().next(); try { CMSProcessable content = tsToken.getSignedContent(); ByteArrayOutputStream bOut = new ByteArrayOutputStream(); content.write(bOut); ASN1InputStream aIn = new ASN1InputStream(new ByteArrayInputStream(bOut.toByteArray())); this.tstInfo = new TimeStampTokenInfo(TSTInfo.getInstance(aIn.readObject())); Attribute attr = tsaSignerInfo.getSignedAttributes().get(PKCSObjectIdentifiers.id_aa_signingCertificate); if (attr != null) { SigningCertificate signCert = SigningCertificate.getInstance(attr.getAttrValues().getObjectAt(0)); this.certID = new CertID(ESSCertID.getInstance(signCert.getCerts()[0])); } else { attr = tsaSignerInfo.getSignedAttributes().get(PKCSObjectIdentifiers.id_aa_signingCertificateV2); if (attr == null) { throw new TSPValidationException("no signing certificate attribute found, time stamp invalid."); } SigningCertificateV2 signCertV2 = SigningCertificateV2.getInstance(attr.getAttrValues().getObjectAt(0)); this.certID = new CertID(ESSCertIDv2.getInstance(signCertV2.getCerts()[0])); } } catch (CMSException e) { throw new TSPException(e.getMessage(), e.getUnderlyingException()); } } public TimeStampTokenInfo getTimeStampInfo() { return tstInfo; } public SignerId getSID() { return tsaSignerInfo.getSID(); } public AttributeTable getSignedAttributes() { return tsaSignerInfo.getSignedAttributes(); } public AttributeTable getUnsignedAttributes() { return tsaSignerInfo.getUnsignedAttributes(); } /** * @deprecated use getCertificates() or getCRLs() */ public CertStore getCertificatesAndCRLs( String type, String provider) throws NoSuchAlgorithmException, NoSuchProviderException, CMSException { return tsToken.getCertificatesAndCRLs(type, provider); } public Store getCertificates() { return tsToken.getCertificates(); } public Store getCRLs() { return tsToken.getCRLs(); } public Store getAttributeCertificates() { return tsToken.getAttributeCertificates(); } /** * Validate the time stamp token. *

    * To be valid the token must be signed by the passed in certificate and * the certificate must be the one referred to by the SigningCertificate * attribute included in the hashed attributes of the token. The * certificate must also have the ExtendedKeyUsageExtension with only * KeyPurposeId.id_kp_timeStamping and have been valid at the time the * timestamp was created. *

    *

    * A successful call to validate means all the above are true. *

    * @deprecated */ public void validate( X509Certificate cert, String provider) throws TSPException, TSPValidationException, CertificateExpiredException, CertificateNotYetValidException, NoSuchProviderException { try { if (!Arrays.constantTimeAreEqual(certID.getCertHash(), MessageDigest.getInstance(certID.getHashAlgorithmName()).digest(cert.getEncoded()))) { throw new TSPValidationException("certificate hash does not match certID hash."); } if (certID.getIssuerSerial() != null) { if (!certID.getIssuerSerial().getSerial().getValue().equals(cert.getSerialNumber())) { throw new TSPValidationException("certificate serial number does not match certID for signature."); } GeneralName[] names = certID.getIssuerSerial().getIssuer().getNames(); X509Principal principal = PrincipalUtil.getIssuerX509Principal(cert); boolean found = false; for (int i = 0; i != names.length; i++) { if (names[i].getTagNo() == 4 && new X509Principal(X509Name.getInstance(names[i].getName())).equals(principal)) { found = true; break; } } if (!found) { throw new TSPValidationException("certificate name does not match certID for signature. "); } } TSPUtil.validateCertificate(cert); cert.checkValidity(tstInfo.getGenTime()); if (!tsaSignerInfo.verify(cert, provider)) { throw new TSPValidationException("signature not created by certificate."); } } catch (CMSException e) { if (e.getUnderlyingException() != null) { throw new TSPException(e.getMessage(), e.getUnderlyingException()); } else { throw new TSPException("CMS exception: " + e, e); } } catch (NoSuchAlgorithmException e) { throw new TSPException("cannot find algorithm: " + e, e); } catch (CertificateEncodingException e) { throw new TSPException("problem processing certificate: " + e, e); } } /** * Validate the time stamp token. *

    * To be valid the token must be signed by the passed in certificate and * the certificate must be the one referred to by the SigningCertificate * attribute included in the hashed attributes of the token. The * certificate must also have the ExtendedKeyUsageExtension with only * KeyPurposeId.id_kp_timeStamping and have been valid at the time the * timestamp was created. *

    *

    * A successful call to validate means all the above are true. *

    * * @param sigVerifier the content verifier create the objects required to verify the CMS object in the timestamp. * @throws TSPException if an exception occurs in processing the token. * @throws TSPValidationException if the certificate or signature fail to be valid. * @throws IllegalArgumentException if the sigVerifierProvider has no associated certificate. */ public void validate( SignerInformationVerifier sigVerifier) throws TSPException, TSPValidationException { if (!sigVerifier.hasAssociatedCertificate()) { throw new IllegalArgumentException("verifier provider needs an associated certificate"); } try { X509CertificateHolder certHolder = sigVerifier.getAssociatedCertificate(); DigestCalculator calc = sigVerifier.getDigestCalculator(certID.getHashAlgorithm()); OutputStream cOut = calc.getOutputStream(); cOut.write(certHolder.getEncoded()); cOut.close(); if (!Arrays.constantTimeAreEqual(certID.getCertHash(), calc.getDigest())) { throw new TSPValidationException("certificate hash does not match certID hash."); } if (certID.getIssuerSerial() != null) { IssuerAndSerialNumber issuerSerial = new IssuerAndSerialNumber(certHolder.toASN1Structure()); if (!certID.getIssuerSerial().getSerial().equals(issuerSerial.getSerialNumber())) { throw new TSPValidationException("certificate serial number does not match certID for signature."); } GeneralName[] names = certID.getIssuerSerial().getIssuer().getNames(); boolean found = false; for (int i = 0; i != names.length; i++) { if (names[i].getTagNo() == 4 && X500Name.getInstance(names[i].getName()).equals(X500Name.getInstance(issuerSerial.getName()))) { found = true; break; } } if (!found) { throw new TSPValidationException("certificate name does not match certID for signature. "); } } TSPUtil.validateCertificate(certHolder); if (!certHolder.isValidOn(tstInfo.getGenTime())) { throw new TSPValidationException("certificate not valid when time stamp created."); } if (!tsaSignerInfo.verify(sigVerifier)) { throw new TSPValidationException("signature not created by certificate."); } } catch (CMSException e) { if (e.getUnderlyingException() != null) { throw new TSPException(e.getMessage(), e.getUnderlyingException()); } else { throw new TSPException("CMS exception: " + e, e); } } catch (IOException e) { throw new TSPException("problem processing certificate: " + e, e); } catch (OperatorCreationException e) { throw new TSPException("unable to create digest: " + e.getMessage(), e); } } /** * Return true if the signature on time stamp token is valid. *

    * Note: this is a much weaker proof of correctness than calling validate(). *

    * * @param sigVerifier the content verifier create the objects required to verify the CMS object in the timestamp. * @return true if the signature matches, false otherwise. * @throws TSPException if the signature cannot be processed or the provider cannot match the algorithm. */ public boolean isSignatureValid( SignerInformationVerifier sigVerifier) throws TSPException { try { return tsaSignerInfo.verify(sigVerifier); } catch (CMSException e) { if (e.getUnderlyingException() != null) { throw new TSPException(e.getMessage(), e.getUnderlyingException()); } else { throw new TSPException("CMS exception: " + e, e); } } } /** * Return the underlying CMSSignedData object. * * @return the underlying CMS structure. */ public CMSSignedData toCMSSignedData() { return tsToken; } /** * Return a ASN.1 encoded byte stream representing the encoded object. * * @throws IOException if encoding fails. */ public byte[] getEncoded() throws IOException { return tsToken.getEncoded(); } // perhaps this should be done using an interface on the ASN.1 classes... private class CertID { private ESSCertID certID; private ESSCertIDv2 certIDv2; CertID(ESSCertID certID) { this.certID = certID; this.certIDv2 = null; } CertID(ESSCertIDv2 certID) { this.certIDv2 = certID; this.certID = null; } public String getHashAlgorithmName() { if (certID != null) { return "SHA-1"; } else { if (NISTObjectIdentifiers.id_sha256.equals(certIDv2.getHashAlgorithm().getAlgorithm())) { return "SHA-256"; } return certIDv2.getHashAlgorithm().getAlgorithm().getId(); } } public AlgorithmIdentifier getHashAlgorithm() { if (certID != null) { return new AlgorithmIdentifier(OIWObjectIdentifiers.idSHA1); } else { return certIDv2.getHashAlgorithm(); } } public byte[] getCertHash() { if (certID != null) { return certID.getCertHash(); } else { return certIDv2.getCertHash(); } } public IssuerSerial getIssuerSerial() { if (certID != null) { return certID.getIssuerSerial(); } else { return certIDv2.getIssuerSerial(); } } } } bouncycastle-1.49.orig/jdk1.1/org/bouncycastle/x509/0000755000175000017500000000000012152033551021405 5ustar ebourgebourgbouncycastle-1.49.orig/jdk1.1/org/bouncycastle/x509/AttributeCertificateIssuer.java0000644000175000017500000001301111731467175027564 0ustar ebourgebourgpackage org.bouncycastle.x509; import org.bouncycastle.asn1.ASN1Encodable; import org.bouncycastle.asn1.DERSequence; import org.bouncycastle.asn1.x509.AttCertIssuer; import org.bouncycastle.asn1.x509.GeneralName; import org.bouncycastle.asn1.x509.GeneralNames; import org.bouncycastle.asn1.x509.V2Form; import org.bouncycastle.jce.PrincipalUtil; import org.bouncycastle.jce.X509Principal; import org.bouncycastle.util.Selector; import java.io.IOException; import java.security.Principal; import java.security.cert.CertSelector; import java.security.cert.Certificate; import java.security.cert.CertificateEncodingException; import java.security.cert.X509Certificate; import java.util.ArrayList; import java.util.List; /** * Carrying class for an attribute certificate issuer. */ public class AttributeCertificateIssuer implements CertSelector, Selector { final ASN1Encodable form; /** * @param issuer */ AttributeCertificateIssuer( AttCertIssuer issuer) { form = issuer.getIssuer(); } public AttributeCertificateIssuer( X509Principal principal) { form = new V2Form(new GeneralNames(new GeneralName(principal))); } private Object[] getNames() { GeneralNames name; if (form instanceof V2Form) { name = ((V2Form)form).getIssuerName(); } else { name = (GeneralNames)form; } GeneralName[] names = name.getNames(); List l = new ArrayList(names.length); for (int i = 0; i != names.length; i++) { if (names[i].getTagNo() == GeneralName.directoryName) { try { l.add(new X509Principal(((ASN1Encodable)names[i].getName()).toASN1Primitive().getEncoded())); } catch (IOException e) { throw new RuntimeException("badly formed Name object"); } } } return l.toArray(new Object[l.size()]); } /** * Return any principal objects inside the attribute certificate issuer object. * * @return an array of Principal objects (usually X509Principal) */ public Principal[] getPrincipals() { Object[] p = this.getNames(); List l = new ArrayList(); for (int i = 0; i != p.length; i++) { if (p[i] instanceof Principal) { l.add(p[i]); } } return (Principal[])l.toArray(new Principal[l.size()]); } private boolean matchesDN(X509Principal subject, GeneralNames targets) { GeneralName[] names = targets.getNames(); for (int i = 0; i != names.length; i++) { GeneralName gn = names[i]; if (gn.getTagNo() == GeneralName.directoryName) { try { if (new X509Principal(((ASN1Encodable)gn.getName()).toASN1Primitive().getEncoded()).equals(subject)) { return true; } } catch (IOException e) { } } } return false; } /* (non-Javadoc) * @see java.security.cert.CertSelector#clone() */ public Object clone() { return new AttributeCertificateIssuer(AttCertIssuer.getInstance(form)); } /* (non-Javadoc) * @see java.security.cert.CertSelector#match(java.security.cert.Certificate) */ public boolean match(Certificate cert) { if (!(cert instanceof X509Certificate)) { return false; } X509Certificate x509Cert = (X509Certificate)cert; try { if (form instanceof V2Form) { V2Form issuer = (V2Form)form; if (issuer.getBaseCertificateID() != null) { return issuer.getBaseCertificateID().getSerial().getValue().equals(x509Cert.getSerialNumber()) && matchesDN(PrincipalUtil.getIssuerX509Principal(x509Cert), issuer.getBaseCertificateID().getIssuer()); } GeneralNames name = issuer.getIssuerName(); if (matchesDN(PrincipalUtil.getSubjectX509Principal(x509Cert), name)) { return true; } } else { GeneralNames name = (GeneralNames)form; if (matchesDN(PrincipalUtil.getSubjectX509Principal(x509Cert), name)) { return true; } } } catch (CertificateEncodingException e) { return false; } return false; } public boolean equals(Object obj) { if (obj == this) { return true; } if (!(obj instanceof AttributeCertificateIssuer)) { return false; } AttributeCertificateIssuer other = (AttributeCertificateIssuer)obj; return this.form.equals(other.form); } public int hashCode() { return this.form.hashCode(); } public boolean match(Object obj) { if (!(obj instanceof X509Certificate)) { return false; } return match((Certificate)obj); } } bouncycastle-1.49.orig/jdk1.1/org/bouncycastle/x509/AttributeCertificateHolder.java0000644000175000017500000002745711731467175027552 0ustar ebourgebourgpackage org.bouncycastle.x509; import java.io.IOException; import java.math.BigInteger; import java.security.MessageDigest; import java.security.Principal; import java.security.cert.Certificate; import java.security.cert.CertificateEncodingException; import java.security.cert.CertificateParsingException; import java.security.cert.X509Certificate; import java.util.ArrayList; import java.util.List; import org.bouncycastle.asn1.ASN1Encodable; import org.bouncycastle.asn1.ASN1Integer; import org.bouncycastle.asn1.ASN1Sequence; import org.bouncycastle.asn1.ASN1ObjectIdentifier; import org.bouncycastle.asn1.x509.AlgorithmIdentifier; import org.bouncycastle.asn1.x509.GeneralName; import org.bouncycastle.asn1.x509.GeneralNames; import org.bouncycastle.asn1.x509.Holder; import org.bouncycastle.asn1.x509.IssuerSerial; import org.bouncycastle.asn1.x509.ObjectDigestInfo; import org.bouncycastle.jce.PrincipalUtil; import org.bouncycastle.jce.X509Principal; import java.security.cert.CertSelector; import org.bouncycastle.util.Arrays; import org.bouncycastle.util.Selector; /** * The Holder object. * *
     *          Holder ::= SEQUENCE {
     *                baseCertificateID   [0] IssuerSerial OPTIONAL,
     *                         -- the issuer and serial number of
     *                         -- the holder's Public Key Certificate
     *                entityName          [1] GeneralNames OPTIONAL,
     *                         -- the name of the claimant or role
     *                objectDigestInfo    [2] ObjectDigestInfo OPTIONAL
     *                         -- used to directly authenticate the holder,
     *                         -- for example, an executable
     *          }
     * 
    * @deprecated use org.bouncycastle.cert.AttributeCertificateHolder */ public class AttributeCertificateHolder implements CertSelector, Selector { final Holder holder; AttributeCertificateHolder(ASN1Sequence seq) { holder = Holder.getInstance(seq); } public AttributeCertificateHolder(X509Principal issuerName, BigInteger serialNumber) { holder = new org.bouncycastle.asn1.x509.Holder(new IssuerSerial( new GeneralNames(new GeneralName(issuerName)), new ASN1Integer(serialNumber))); } public AttributeCertificateHolder(X509Certificate cert) throws CertificateParsingException { X509Principal name; try { name = PrincipalUtil.getIssuerX509Principal(cert); } catch (Exception e) { throw new CertificateParsingException(e.getMessage()); } holder = new Holder(new IssuerSerial(generateGeneralNames(name), new ASN1Integer(cert.getSerialNumber()))); } public AttributeCertificateHolder(X509Principal principal) { holder = new Holder(generateGeneralNames(principal)); } /** * Constructs a holder for v2 attribute certificates with a hash value for * some type of object. *

    * digestedObjectType can be one of the following: *

      *
    • 0 - publicKey - A hash of the public key of the holder must be * passed. *
    • 1 - publicKeyCert - A hash of the public key certificate of the * holder must be passed. *
    • 2 - otherObjectDigest - A hash of some other object type must be * passed. otherObjectTypeID must not be empty. *
    *

    * This cannot be used if a v1 attribute certificate is used. * * @param digestedObjectType The digest object type. * @param digestAlgorithm The algorithm identifier for the hash. * @param otherObjectTypeID The object type ID if * digestedObjectType is * otherObjectDigest. * @param objectDigest The hash value. */ public AttributeCertificateHolder(int digestedObjectType, String digestAlgorithm, String otherObjectTypeID, byte[] objectDigest) { holder = new Holder(new ObjectDigestInfo(digestedObjectType, new ASN1ObjectIdentifier(otherObjectTypeID), new AlgorithmIdentifier(digestAlgorithm), Arrays .clone(objectDigest))); } /** * Returns the digest object type if an object digest info is used. *

    *

      *
    • 0 - publicKey - A hash of the public key of the holder must be * passed. *
    • 1 - publicKeyCert - A hash of the public key certificate of the * holder must be passed. *
    • 2 - otherObjectDigest - A hash of some other object type must be * passed. otherObjectTypeID must not be empty. *
    * * @return The digest object type or -1 if no object digest info is set. */ public int getDigestedObjectType() { if (holder.getObjectDigestInfo() != null) { return holder.getObjectDigestInfo().getDigestedObjectType() .getValue().intValue(); } return -1; } /** * Returns the other object type ID if an object digest info is used. * * @return The other object type ID or null if no object * digest info is set. */ public String getDigestAlgorithm() { if (holder.getObjectDigestInfo() != null) { return holder.getObjectDigestInfo().getDigestAlgorithm().getObjectId() .getId(); } return null; } /** * Returns the hash if an object digest info is used. * * @return The hash or null if no object digest info is set. */ public byte[] getObjectDigest() { if (holder.getObjectDigestInfo() != null) { return holder.getObjectDigestInfo().getObjectDigest().getBytes(); } return null; } /** * Returns the digest algorithm ID if an object digest info is used. * * @return The digest algorithm ID or null if no object * digest info is set. */ public String getOtherObjectTypeID() { if (holder.getObjectDigestInfo() != null) { holder.getObjectDigestInfo().getOtherObjectTypeID().getId(); } return null; } private GeneralNames generateGeneralNames(X509Principal principal) { return new GeneralNames(new GeneralName(principal)); } private boolean matchesDN(X509Principal subject, GeneralNames targets) { GeneralName[] names = targets.getNames(); for (int i = 0; i != names.length; i++) { GeneralName gn = names[i]; if (gn.getTagNo() == GeneralName.directoryName) { try { if (new X509Principal(((ASN1Encodable)gn.getName()).toASN1Primitive() .getEncoded()).equals(subject)) { return true; } } catch (IOException e) { } } } return false; } private Object[] getNames(GeneralName[] names) { List l = new ArrayList(names.length); for (int i = 0; i != names.length; i++) { if (names[i].getTagNo() == GeneralName.directoryName) { try { l.add(new X509Principal( ((ASN1Encodable)names[i].getName()).toASN1Primitive().getEncoded())); } catch (IOException e) { throw new RuntimeException("badly formed Name object"); } } } return l.toArray(new Object[l.size()]); } private Principal[] getPrincipals(GeneralNames names) { Object[] p = this.getNames(names.getNames()); List l = new ArrayList(); for (int i = 0; i != p.length; i++) { if (p[i] instanceof Principal) { l.add(p[i]); } } return (Principal[])l.toArray(new Principal[l.size()]); } /** * Return any principal objects inside the attribute certificate holder * entity names field. * * @return an array of Principal objects (usually X509Principal), null if no * entity names field is set. */ public Principal[] getEntityNames() { if (holder.getEntityName() != null) { return getPrincipals(holder.getEntityName()); } return null; } /** * Return the principals associated with the issuer attached to this holder * * @return an array of principals, null if no BaseCertificateID is set. */ public Principal[] getIssuer() { if (holder.getBaseCertificateID() != null) { return getPrincipals(holder.getBaseCertificateID().getIssuer()); } return null; } /** * Return the serial number associated with the issuer attached to this * holder. * * @return the certificate serial number, null if no BaseCertificateID is * set. */ public BigInteger getSerialNumber() { if (holder.getBaseCertificateID() != null) { return holder.getBaseCertificateID().getSerial().getValue(); } return null; } public Object clone() { return new AttributeCertificateHolder((ASN1Sequence)holder .toASN1Object()); } public boolean match(Certificate cert) { if (!(cert instanceof X509Certificate)) { return false; } X509Certificate x509Cert = (X509Certificate)cert; try { if (holder.getBaseCertificateID() != null) { return holder.getBaseCertificateID().getSerial().getValue().equals(x509Cert.getSerialNumber()) && matchesDN(PrincipalUtil.getIssuerX509Principal(x509Cert), holder.getBaseCertificateID().getIssuer()); } if (holder.getEntityName() != null) { if (matchesDN(PrincipalUtil.getSubjectX509Principal(x509Cert), holder.getEntityName())) { return true; } } if (holder.getObjectDigestInfo() != null) { MessageDigest md = null; try { md = MessageDigest.getInstance(getDigestAlgorithm(), "BC"); } catch (Exception e) { return false; } switch (getDigestedObjectType()) { case ObjectDigestInfo.publicKey: // TODO: DSA Dss-parms md.update(cert.getPublicKey().getEncoded()); break; case ObjectDigestInfo.publicKeyCert: md.update(cert.getEncoded()); break; } if (!Arrays.areEqual(md.digest(), getObjectDigest())) { return false; } } } catch (CertificateEncodingException e) { return false; } return false; } public boolean equals(Object obj) { if (obj == this) { return true; } if (!(obj instanceof AttributeCertificateHolder)) { return false; } AttributeCertificateHolder other = (AttributeCertificateHolder)obj; return this.holder.equals(other.holder); } public int hashCode() { return this.holder.hashCode(); } public boolean match(Object obj) { if (!(obj instanceof X509Certificate)) { return false; } return match((Certificate)obj); } } bouncycastle-1.49.orig/jdk1.1/org/bouncycastle/x509/X509CRLStoreSelector.java0000644000175000017500000000075511705654530026014 0ustar ebourgebourgpackage org.bouncycastle.x509; import org.bouncycastle.util.Selector; import java.security.cert.X509CRLSelector; import java.security.cert.CRL; public class X509CRLStoreSelector extends X509CRLSelector implements Selector { public boolean match(Object obj) { if (!(obj instanceof CRL)) { return false; } return super.match((CRL)obj); } public boolean match(CRL obj) { return this.match((Object)obj); } } bouncycastle-1.49.orig/jdk1.1/org/bouncycastle/x509/X509CertStoreSelector.java0000644000175000017500000000102011705654530026253 0ustar ebourgebourgpackage org.bouncycastle.x509; import org.bouncycastle.util.Selector; import java.security.cert.X509CertSelector; import java.security.cert.Certificate; public class X509CertStoreSelector extends X509CertSelector implements Selector { public boolean match(Object obj) { if (!(obj instanceof Certificate)) { return false; } return super.match((Certificate)obj); } public boolean match(Certificate obj) { return this.match((Object)obj); } } bouncycastle-1.49.orig/jdk1.1/org/bouncycastle/x509/X509Util.java0000644000175000017500000003467211731467175023606 0ustar ebourgebourgpackage org.bouncycastle.x509; import java.io.IOException; import java.security.InvalidKeyException; import java.security.NoSuchAlgorithmException; import java.security.NoSuchProviderException; import java.security.PrivateKey; import java.security.Provider; import java.security.SecureRandom; import java.security.Security; import java.security.Signature; import java.security.SignatureException; import java.util.ArrayList; import java.util.Enumeration; import java.util.HashSet; import java.util.Hashtable; import java.util.Iterator; import java.util.List; import java.util.Set; import org.bouncycastle.asn1.ASN1Encodable; import org.bouncycastle.asn1.ASN1Encoding; import org.bouncycastle.asn1.ASN1Integer; import org.bouncycastle.asn1.DERNull; import org.bouncycastle.asn1.DERObjectIdentifier; import org.bouncycastle.asn1.cryptopro.CryptoProObjectIdentifiers; import org.bouncycastle.asn1.nist.NISTObjectIdentifiers; import org.bouncycastle.asn1.oiw.OIWObjectIdentifiers; import org.bouncycastle.asn1.pkcs.PKCSObjectIdentifiers; import org.bouncycastle.asn1.pkcs.RSASSAPSSparams; import org.bouncycastle.asn1.teletrust.TeleTrusTObjectIdentifiers; import org.bouncycastle.asn1.x509.AlgorithmIdentifier; import org.bouncycastle.asn1.x9.X9ObjectIdentifiers; import org.bouncycastle.jce.X509Principal; import org.bouncycastle.util.Strings; class X509Util { private static Hashtable algorithms = new Hashtable(); private static Hashtable params = new Hashtable(); private static Set noParams = new HashSet(); static { algorithms.put("MD2WITHRSAENCRYPTION", PKCSObjectIdentifiers.md2WithRSAEncryption); algorithms.put("MD2WITHRSA", PKCSObjectIdentifiers.md2WithRSAEncryption); algorithms.put("MD5WITHRSAENCRYPTION", PKCSObjectIdentifiers.md5WithRSAEncryption); algorithms.put("MD5WITHRSA", PKCSObjectIdentifiers.md5WithRSAEncryption); algorithms.put("SHA1WITHRSAENCRYPTION", PKCSObjectIdentifiers.sha1WithRSAEncryption); algorithms.put("SHA1WITHRSA", PKCSObjectIdentifiers.sha1WithRSAEncryption); algorithms.put("SHA224WITHRSAENCRYPTION", PKCSObjectIdentifiers.sha224WithRSAEncryption); algorithms.put("SHA224WITHRSA", PKCSObjectIdentifiers.sha224WithRSAEncryption); algorithms.put("SHA256WITHRSAENCRYPTION", PKCSObjectIdentifiers.sha256WithRSAEncryption); algorithms.put("SHA256WITHRSA", PKCSObjectIdentifiers.sha256WithRSAEncryption); algorithms.put("SHA384WITHRSAENCRYPTION", PKCSObjectIdentifiers.sha384WithRSAEncryption); algorithms.put("SHA384WITHRSA", PKCSObjectIdentifiers.sha384WithRSAEncryption); algorithms.put("SHA512WITHRSAENCRYPTION", PKCSObjectIdentifiers.sha512WithRSAEncryption); algorithms.put("SHA512WITHRSA", PKCSObjectIdentifiers.sha512WithRSAEncryption); algorithms.put("SHA1WITHRSAANDMGF1", PKCSObjectIdentifiers.id_RSASSA_PSS); algorithms.put("SHA224WITHRSAANDMGF1", PKCSObjectIdentifiers.id_RSASSA_PSS); algorithms.put("SHA256WITHRSAANDMGF1", PKCSObjectIdentifiers.id_RSASSA_PSS); algorithms.put("SHA384WITHRSAANDMGF1", PKCSObjectIdentifiers.id_RSASSA_PSS); algorithms.put("SHA512WITHRSAANDMGF1", PKCSObjectIdentifiers.id_RSASSA_PSS); algorithms.put("RIPEMD160WITHRSAENCRYPTION", TeleTrusTObjectIdentifiers.rsaSignatureWithripemd160); algorithms.put("RIPEMD160WITHRSA", TeleTrusTObjectIdentifiers.rsaSignatureWithripemd160); algorithms.put("RIPEMD128WITHRSAENCRYPTION", TeleTrusTObjectIdentifiers.rsaSignatureWithripemd128); algorithms.put("RIPEMD128WITHRSA", TeleTrusTObjectIdentifiers.rsaSignatureWithripemd128); algorithms.put("RIPEMD256WITHRSAENCRYPTION", TeleTrusTObjectIdentifiers.rsaSignatureWithripemd256); algorithms.put("RIPEMD256WITHRSA", TeleTrusTObjectIdentifiers.rsaSignatureWithripemd256); algorithms.put("SHA1WITHDSA", X9ObjectIdentifiers.id_dsa_with_sha1); algorithms.put("DSAWITHSHA1", X9ObjectIdentifiers.id_dsa_with_sha1); algorithms.put("SHA224WITHDSA", NISTObjectIdentifiers.dsa_with_sha224); algorithms.put("SHA256WITHDSA", NISTObjectIdentifiers.dsa_with_sha256); algorithms.put("SHA384WITHDSA", NISTObjectIdentifiers.dsa_with_sha384); algorithms.put("SHA512WITHDSA", NISTObjectIdentifiers.dsa_with_sha512); algorithms.put("SHA1WITHECDSA", X9ObjectIdentifiers.ecdsa_with_SHA1); algorithms.put("ECDSAWITHSHA1", X9ObjectIdentifiers.ecdsa_with_SHA1); algorithms.put("SHA224WITHECDSA", X9ObjectIdentifiers.ecdsa_with_SHA224); algorithms.put("SHA256WITHECDSA", X9ObjectIdentifiers.ecdsa_with_SHA256); algorithms.put("SHA384WITHECDSA", X9ObjectIdentifiers.ecdsa_with_SHA384); algorithms.put("SHA512WITHECDSA", X9ObjectIdentifiers.ecdsa_with_SHA512); algorithms.put("GOST3411WITHGOST3410", CryptoProObjectIdentifiers.gostR3411_94_with_gostR3410_94); algorithms.put("GOST3411WITHGOST3410-94", CryptoProObjectIdentifiers.gostR3411_94_with_gostR3410_94); algorithms.put("GOST3411WITHECGOST3410", CryptoProObjectIdentifiers.gostR3411_94_with_gostR3410_2001); algorithms.put("GOST3411WITHECGOST3410-2001", CryptoProObjectIdentifiers.gostR3411_94_with_gostR3410_2001); algorithms.put("GOST3411WITHGOST3410-2001", CryptoProObjectIdentifiers.gostR3411_94_with_gostR3410_2001); // // According to RFC 3279, the ASN.1 encoding SHALL (id-dsa-with-sha1) or MUST (ecdsa-with-SHA*) omit the parameters field. // The parameters field SHALL be NULL for RSA based signature algorithms. // noParams.add(X9ObjectIdentifiers.ecdsa_with_SHA1); noParams.add(X9ObjectIdentifiers.ecdsa_with_SHA224); noParams.add(X9ObjectIdentifiers.ecdsa_with_SHA256); noParams.add(X9ObjectIdentifiers.ecdsa_with_SHA384); noParams.add(X9ObjectIdentifiers.ecdsa_with_SHA512); noParams.add(X9ObjectIdentifiers.id_dsa_with_sha1); noParams.add(NISTObjectIdentifiers.dsa_with_sha224); noParams.add(NISTObjectIdentifiers.dsa_with_sha256); noParams.add(NISTObjectIdentifiers.dsa_with_sha384); noParams.add(NISTObjectIdentifiers.dsa_with_sha512); // // RFC 4491 // noParams.add(CryptoProObjectIdentifiers.gostR3411_94_with_gostR3410_94); noParams.add(CryptoProObjectIdentifiers.gostR3411_94_with_gostR3410_2001); // // explicit params // AlgorithmIdentifier sha1AlgId = new AlgorithmIdentifier(OIWObjectIdentifiers.idSHA1, new DERNull()); params.put("SHA1WITHRSAANDMGF1", creatPSSParams(sha1AlgId, 20)); AlgorithmIdentifier sha224AlgId = new AlgorithmIdentifier(NISTObjectIdentifiers.id_sha224, new DERNull()); params.put("SHA224WITHRSAANDMGF1", creatPSSParams(sha224AlgId, 28)); AlgorithmIdentifier sha256AlgId = new AlgorithmIdentifier(NISTObjectIdentifiers.id_sha256, new DERNull()); params.put("SHA256WITHRSAANDMGF1", creatPSSParams(sha256AlgId, 32)); AlgorithmIdentifier sha384AlgId = new AlgorithmIdentifier(NISTObjectIdentifiers.id_sha384, new DERNull()); params.put("SHA384WITHRSAANDMGF1", creatPSSParams(sha384AlgId, 48)); AlgorithmIdentifier sha512AlgId = new AlgorithmIdentifier(NISTObjectIdentifiers.id_sha512, new DERNull()); params.put("SHA512WITHRSAANDMGF1", creatPSSParams(sha512AlgId, 64)); } private static RSASSAPSSparams creatPSSParams(AlgorithmIdentifier hashAlgId, int saltSize) { return new RSASSAPSSparams( hashAlgId, new AlgorithmIdentifier(PKCSObjectIdentifiers.id_mgf1, hashAlgId), new ASN1Integer(saltSize), new ASN1Integer(1)); } static DERObjectIdentifier getAlgorithmOID( String algorithmName) { algorithmName = Strings.toUpperCase(algorithmName); if (algorithms.containsKey(algorithmName)) { return (DERObjectIdentifier)algorithms.get(algorithmName); } return new DERObjectIdentifier(algorithmName); } static AlgorithmIdentifier getSigAlgID( DERObjectIdentifier sigOid, String algorithmName) { if (noParams.contains(sigOid)) { return new AlgorithmIdentifier(sigOid); } algorithmName = Strings.toUpperCase(algorithmName); if (params.containsKey(algorithmName)) { return new AlgorithmIdentifier(sigOid, (ASN1Encodable)params.get(algorithmName)); } else { return new AlgorithmIdentifier(sigOid, new DERNull()); } } static Iterator getAlgNames() { Enumeration e = algorithms.keys(); List l = new ArrayList(); while (e.hasMoreElements()) { l.add(e.nextElement()); } return l.iterator(); } static Signature getSignatureInstance( String algorithm) throws NoSuchAlgorithmException { return Signature.getInstance(algorithm); } static Signature getSignatureInstance( String algorithm, String provider) throws NoSuchProviderException, NoSuchAlgorithmException { if (provider != null) { return Signature.getInstance(algorithm, provider); } else { return Signature.getInstance(algorithm); } } static byte[] calculateSignature( DERObjectIdentifier sigOid, String sigName, PrivateKey key, SecureRandom random, ASN1Encodable object) throws IOException, NoSuchAlgorithmException, InvalidKeyException, SignatureException { Signature sig; if (sigOid == null) { throw new IllegalStateException("no signature algorithm specified"); } sig = X509Util.getSignatureInstance(sigName); if (random != null) { sig.initSign(key); } else { sig.initSign(key); } sig.update(object.toASN1Primitive().getEncoded(ASN1Encoding.DER)); return sig.sign(); } static byte[] calculateSignature( DERObjectIdentifier sigOid, String sigName, String provider, PrivateKey key, SecureRandom random, ASN1Encodable object) throws IOException, NoSuchProviderException, NoSuchAlgorithmException, InvalidKeyException, SignatureException { Signature sig; if (sigOid == null) { throw new IllegalStateException("no signature algorithm specified"); } sig = X509Util.getSignatureInstance(sigName, provider); if (random != null) { sig.initSign(key); } else { sig.initSign(key); } sig.update(object.toASN1Primitive().getEncoded(ASN1Encoding.DER)); return sig.sign(); } static class Implementation { Object engine; Provider provider; Implementation( Object engine, Provider provider) { this.engine = engine; this.provider = provider; } Object getEngine() { return engine; } Provider getProvider() { return provider; } } /** * see if we can find an algorithm (or its alias and what it represents) in * the property table for the given provider. */ static Implementation getImplementation( String baseName, String algorithm, Provider prov) throws NoSuchAlgorithmException { algorithm = Strings.toUpperCase(algorithm); String alias; while ((alias = prov.getProperty("Alg.Alias." + baseName + "." + algorithm)) != null) { algorithm = alias; } String className = prov.getProperty(baseName + "." + algorithm); if (className != null) { try { Class cls; ClassLoader clsLoader = prov.getClass().getClassLoader(); if (clsLoader != null) { cls = clsLoader.loadClass(className); } else { cls = Class.forName(className); } return new Implementation(cls.newInstance(), prov); } catch (ClassNotFoundException e) { throw new IllegalStateException( "algorithm " + algorithm + " in provider " + prov.getName() + " but no class \"" + className + "\" found!"); } catch (Exception e) { throw new IllegalStateException( "algorithm " + algorithm + " in provider " + prov.getName() + " but class \"" + className + "\" inaccessible!"); } } throw new NoSuchAlgorithmException("cannot find implementation " + algorithm + " for provider " + prov.getName()); } /** * return an implementation for a given algorithm/provider. * If the provider is null, we grab the first avalaible who has the required algorithm. */ static Implementation getImplementation( String baseName, String algorithm) throws NoSuchAlgorithmException { Provider[] prov = Security.getProviders(); // // search every provider looking for the algorithm we want. // for (int i = 0; i != prov.length; i++) { // // try case insensitive // Implementation imp = getImplementation(baseName, Strings.toUpperCase(algorithm), prov[i]); if (imp != null) { return imp; } try { imp = getImplementation(baseName, algorithm, prov[i]); } catch (NoSuchAlgorithmException e) { // continue } } throw new NoSuchAlgorithmException("cannot find implementation " + algorithm); } static Provider getProvider(String provider) throws NoSuchProviderException { Provider prov = Security.getProvider(provider); if (prov == null) { throw new NoSuchProviderException("Provider " + provider + " not found"); } return prov; } } bouncycastle-1.49.orig/jdk1.1/org/bouncycastle/x509/X509V2AttributeCertificateGenerator.java0000644000175000017500000002125612105031243031023 0ustar ebourgebourgpackage org.bouncycastle.x509; import java.io.ByteArrayOutputStream; import java.io.IOException; import java.math.BigInteger; import java.security.InvalidKeyException; import java.security.NoSuchAlgorithmException; import java.security.NoSuchProviderException; import java.security.PrivateKey; import java.security.SecureRandom; import java.security.Signature; import java.security.SignatureException; import java.util.Date; import java.util.Hashtable; import java.util.Vector; import org.bouncycastle.asn1.ASN1Encodable; import org.bouncycastle.asn1.ASN1EncodableVector; import org.bouncycastle.asn1.DERBitString; import org.bouncycastle.asn1.ASN1GeneralizedTime; import org.bouncycastle.asn1.ASN1Integer; import org.bouncycastle.asn1.DERNull; import org.bouncycastle.asn1.DERObjectIdentifier; import org.bouncycastle.asn1.DEROctetString; import org.bouncycastle.asn1.DEROutputStream; import org.bouncycastle.asn1.DERSequence; import org.bouncycastle.asn1.x509.AlgorithmIdentifier; import org.bouncycastle.asn1.x509.AttCertIssuer; import org.bouncycastle.asn1.x509.Attribute; import org.bouncycastle.asn1.x509.AttributeCertificate; import org.bouncycastle.asn1.x509.V2AttributeCertificateInfoGenerator; import org.bouncycastle.asn1.x509.AttributeCertificateInfo; import org.bouncycastle.asn1.x509.X509Extension; import org.bouncycastle.asn1.x509.X509Extensions; import org.bouncycastle.util.Strings; /** * class to produce an X.509 Version 2 AttributeCertificate. */ public class X509V2AttributeCertificateGenerator { private V2AttributeCertificateInfoGenerator acInfoGen; private DERObjectIdentifier sigOID; private AlgorithmIdentifier sigAlgId; private String signatureAlgorithm; private Hashtable extensions = null; private Vector extOrdering = null; private static Hashtable algorithms = new Hashtable(); static { algorithms.put("MD2WITHRSAENCRYPTION", new DERObjectIdentifier("1.2.840.113549.1.1.2")); algorithms.put("MD2WITHRSA", new DERObjectIdentifier("1.2.840.113549.1.1.2")); algorithms.put("MD5WITHRSAENCRYPTION", new DERObjectIdentifier("1.2.840.113549.1.1.4")); algorithms.put("MD5WITHRSA", new DERObjectIdentifier("1.2.840.113549.1.1.4")); algorithms.put("SHA1WITHRSAENCRYPTION", new DERObjectIdentifier("1.2.840.113549.1.1.5")); algorithms.put("SHA1WITHRSA", new DERObjectIdentifier("1.2.840.113549.1.1.5")); algorithms.put("RIPEMD160WITHRSAENCRYPTION", new DERObjectIdentifier("1.3.36.3.3.1.2")); algorithms.put("RIPEMD160WITHRSA", new DERObjectIdentifier("1.3.36.3.3.1.2")); algorithms.put("SHA1WITHDSA", new DERObjectIdentifier("1.2.840.10040.4.3")); algorithms.put("DSAWITHSHA1", new DERObjectIdentifier("1.2.840.10040.4.3")); algorithms.put("SHA1WITHECDSA", new DERObjectIdentifier("1.2.840.10045.4.1")); algorithms.put("ECDSAWITHSHA1", new DERObjectIdentifier("1.2.840.10045.4.1")); } public X509V2AttributeCertificateGenerator() { acInfoGen = new V2AttributeCertificateInfoGenerator(); } /** * reset the generator */ public void reset() { acInfoGen = new V2AttributeCertificateInfoGenerator(); extensions = null; extOrdering = null; } /** * Set the Holder of this Attribute Certificate */ public void setHolder( AttributeCertificateHolder holder) { acInfoGen.setHolder(holder.holder); } /** * Set the issuer */ public void setIssuer( AttributeCertificateIssuer issuer) { acInfoGen.setIssuer(AttCertIssuer.getInstance(issuer.form)); } /** * Set the Signature inside the AttributeCertificateInfo */ public void setSignature( AlgorithmIdentifier sig) { acInfoGen.setSignature(sig); } /** * set the serial number for the certificate. */ public void setSerialNumber( BigInteger serialNumber) { acInfoGen.setSerialNumber(new ASN1Integer(serialNumber)); } public void setNotBefore( Date date) { acInfoGen.setStartDate(new ASN1GeneralizedTime(date)); } public void setNotAfter( Date date) { acInfoGen.setEndDate(new ASN1GeneralizedTime(date)); } public void setSignatureAlgorithm( String signatureAlgorithm) { this.signatureAlgorithm = signatureAlgorithm; sigOID = (DERObjectIdentifier)algorithms.get(Strings.toUpperCase(signatureAlgorithm)); if (sigOID == null) { throw new IllegalArgumentException("Unknown signature type requested"); } sigAlgId = new AlgorithmIdentifier(this.sigOID, new DERNull()); acInfoGen.setSignature(sigAlgId); } /** * add an attribute */ public void addAttribute( X509Attribute attribute) { acInfoGen.addAttribute(Attribute.getInstance(attribute.toASN1Object())); } public void setIssuerUniqueId( boolean[] iui) { // [TODO] convert boolean array to bit string //acInfoGen.setIssuerUniqueID(iui); } /** * add a given extension field for the standard extensions tag (tag 3) * @throws IOException */ public void addExtension( String OID, boolean critical, ASN1Encodable value) throws IOException { this.addExtension(OID, critical, value.toASN1Primitive().getEncoded()); } /** * add a given extension field for the standard extensions tag (tag 3) * The value parameter becomes the contents of the octet string associated * with the extension. */ public void addExtension( String OID, boolean critical, byte[] value) { if (extensions == null) { extensions = new Hashtable(); extOrdering = new Vector(); } DERObjectIdentifier oid = new DERObjectIdentifier(OID); extensions.put(oid, new X509Extension(critical, new DEROctetString(value))); extOrdering.addElement(oid); } /** * generate an X509 certificate, based on the current issuer and subject, * using the passed in provider for the signing. */ public X509AttributeCertificate generateCertificate( PrivateKey key, String provider) throws NoSuchProviderException, SecurityException, SignatureException, InvalidKeyException { return generateCertificate(key, provider, null); } /** * generate an X509 certificate, based on the current issuer and subject, * using the passed in provider for the signing and the supplied source * of randomness, if required. */ public X509AttributeCertificate generateCertificate( PrivateKey key, String provider, SecureRandom random) throws NoSuchProviderException, SecurityException, SignatureException, InvalidKeyException { Signature sig = null; if (sigOID == null) { throw new IllegalStateException("no signature algorithm specified"); } try { sig = Signature.getInstance(sigOID.getId(), provider); } catch (NoSuchAlgorithmException ex) { try { sig = Signature.getInstance(signatureAlgorithm, provider); } catch (NoSuchAlgorithmException e) { throw new SecurityException("exception creating signature: " + e.toString()); } } sig.initSign(key); if (extensions != null) { acInfoGen.setExtensions(new X509Extensions(extOrdering, extensions)); } AttributeCertificateInfo acInfo = acInfoGen.generateAttributeCertificateInfo(); try { ByteArrayOutputStream bOut = new ByteArrayOutputStream(); DEROutputStream dOut = new DEROutputStream(bOut); dOut.writeObject(acInfo); sig.update(bOut.toByteArray()); } catch (Exception e) { throw new SecurityException("exception encoding Attribute cert - " + e); } ASN1EncodableVector v = new ASN1EncodableVector(); v.add(acInfo); v.add(sigAlgId); v.add(new DERBitString(sig.sign())); try { return new X509V2AttributeCertificate(new AttributeCertificate(new DERSequence(v))); } catch (IOException e) { throw new RuntimeException("constructed invalid certificate!"); } } } bouncycastle-1.49.orig/jdk1.1/org/bouncycastle/x509/X509V2CRLGenerator.java0000644000175000017500000003157512132656275025364 0ustar ebourgebourgpackage org.bouncycastle.x509; import java.io.IOException; import java.math.BigInteger; import java.security.GeneralSecurityException; import java.security.InvalidKeyException; import java.security.NoSuchAlgorithmException; import java.security.NoSuchProviderException; import java.security.PrivateKey; import java.security.SecureRandom; import java.security.SignatureException; import java.security.cert.CRLException; import java.security.cert.X509CRL; import java.security.cert.X509CRLEntry; import java.util.Date; import java.util.Iterator; import java.util.Set; import org.bouncycastle.asn1.ASN1Encodable; import org.bouncycastle.asn1.ASN1EncodableVector; import org.bouncycastle.asn1.ASN1InputStream; import org.bouncycastle.asn1.ASN1ObjectIdentifier; import org.bouncycastle.asn1.ASN1Sequence; import org.bouncycastle.asn1.DERBitString; import org.bouncycastle.asn1.ASN1GeneralizedTime; import org.bouncycastle.asn1.ASN1Integer; import org.bouncycastle.asn1.DERObjectIdentifier; import org.bouncycastle.asn1.DERSequence; import org.bouncycastle.asn1.x509.AlgorithmIdentifier; import org.bouncycastle.asn1.x509.CertificateList; import org.bouncycastle.asn1.x509.TBSCertList; import org.bouncycastle.asn1.x509.Time; import org.bouncycastle.asn1.x509.V2TBSCertListGenerator; import org.bouncycastle.asn1.x509.X509Extensions; import org.bouncycastle.asn1.x509.Extensions; import org.bouncycastle.asn1.x509.X509ExtensionsGenerator; import org.bouncycastle.asn1.x509.X509Name; import org.bouncycastle.jce.provider.X509CRLObject; /** * class to produce an X.509 Version 2 CRL. * @deprecated use org.bouncycastle.cert.X509v2CRLBuilder. */ public class X509V2CRLGenerator { private V2TBSCertListGenerator tbsGen; private DERObjectIdentifier sigOID; private AlgorithmIdentifier sigAlgId; private String signatureAlgorithm; private X509ExtensionsGenerator extGenerator; public X509V2CRLGenerator() { tbsGen = new V2TBSCertListGenerator(); extGenerator = new X509ExtensionsGenerator(); } /** * reset the generator */ public void reset() { tbsGen = new V2TBSCertListGenerator(); extGenerator.reset(); } /** * Set the issuer distinguished name - the issuer is the entity whose private key is used to sign the * certificate. */ public void setIssuerDN( X509Name issuer) { tbsGen.setIssuer(issuer); } public void setThisUpdate( Date date) { tbsGen.setThisUpdate(new Time(date)); } public void setNextUpdate( Date date) { tbsGen.setNextUpdate(new Time(date)); } /** * Reason being as indicated by CRLReason, i.e. CRLReason.keyCompromise * or 0 if CRLReason is not to be used **/ public void addCRLEntry(BigInteger userCertificate, Date revocationDate, int reason) { tbsGen.addCRLEntry(new ASN1Integer(userCertificate), new Time(revocationDate), reason); } /** * Add a CRL entry with an Invalidity Date extension as well as a CRLReason extension. * Reason being as indicated by CRLReason, i.e. CRLReason.keyCompromise * or 0 if CRLReason is not to be used **/ public void addCRLEntry(BigInteger userCertificate, Date revocationDate, int reason, Date invalidityDate) { tbsGen.addCRLEntry(new ASN1Integer(userCertificate), new Time(revocationDate), reason, new ASN1GeneralizedTime(invalidityDate)); } /** * Add a CRL entry with extensions. **/ public void addCRLEntry(BigInteger userCertificate, Date revocationDate, X509Extensions extensions) { tbsGen.addCRLEntry(new ASN1Integer(userCertificate), new Time(revocationDate), Extensions.getInstance(extensions)); } /** * Add the CRLEntry objects contained in a previous CRL. * * @param other the X509CRL to source the other entries from. */ public void addCRL(X509CRL other) throws CRLException { Set revocations = other.getRevokedCertificates(); if (revocations != null) { Iterator it = revocations.iterator(); while (it.hasNext()) { X509CRLEntry entry = (X509CRLEntry)it.next(); ASN1InputStream aIn = new ASN1InputStream(entry.getEncoded()); try { tbsGen.addCRLEntry(ASN1Sequence.getInstance(aIn.readObject())); } catch (IOException e) { throw new CRLException("exception processing encoding of CRL: " + e.toString()); } } } } /** * Set the signature algorithm. This can be either a name or an OID, names * are treated as case insensitive. * * @param signatureAlgorithm string representation of the algorithm name. */ public void setSignatureAlgorithm( String signatureAlgorithm) { this.signatureAlgorithm = signatureAlgorithm; try { sigOID = X509Util.getAlgorithmOID(signatureAlgorithm); } catch (Exception e) { throw new IllegalArgumentException("Unknown signature type requested"); } sigAlgId = X509Util.getSigAlgID(sigOID, signatureAlgorithm); tbsGen.setSignature(sigAlgId); } /** * add a given extension field for the standard extensions tag (tag 0) */ public void addExtension( String oid, boolean critical, ASN1Encodable value) { this.addExtension(new DERObjectIdentifier(oid), critical, value); } /** * add a given extension field for the standard extensions tag (tag 0) */ public void addExtension( DERObjectIdentifier oid, boolean critical, ASN1Encodable value) { extGenerator.addExtension(new ASN1ObjectIdentifier(oid.getId()), critical, value); } /** * add a given extension field for the standard extensions tag (tag 0) */ public void addExtension( String oid, boolean critical, byte[] value) { this.addExtension(new DERObjectIdentifier(oid), critical, value); } /** * add a given extension field for the standard extensions tag (tag 0) */ public void addExtension( DERObjectIdentifier oid, boolean critical, byte[] value) { extGenerator.addExtension(new ASN1ObjectIdentifier(oid.getId()), critical, value); } /** * generate an X509 CRL, based on the current issuer and subject * using the default provider "BC". * @deprecated use generate(key, "BC") */ public X509CRL generateX509CRL( PrivateKey key) throws SecurityException, SignatureException, InvalidKeyException { try { return generateX509CRL(key, "BC", null); } catch (NoSuchProviderException e) { throw new SecurityException("BC provider not installed!"); } } /** * generate an X509 CRL, based on the current issuer and subject * using the default provider "BC" and an user defined SecureRandom object as * source of randomness. * @deprecated use generate(key, random, "BC") */ public X509CRL generateX509CRL( PrivateKey key, SecureRandom random) throws SecurityException, SignatureException, InvalidKeyException { try { return generateX509CRL(key, "BC", random); } catch (NoSuchProviderException e) { throw new SecurityException("BC provider not installed!"); } } /** * generate an X509 certificate, based on the current issuer and subject * using the passed in provider for the signing. * @deprecated use generate() */ public X509CRL generateX509CRL( PrivateKey key, String provider) throws NoSuchProviderException, SecurityException, SignatureException, InvalidKeyException { return generateX509CRL(key, provider, null); } /** * generate an X509 CRL, based on the current issuer and subject, * using the passed in provider for the signing. * @deprecated use generate() */ public X509CRL generateX509CRL( PrivateKey key, String provider, SecureRandom random) throws NoSuchProviderException, SecurityException, SignatureException, InvalidKeyException { try { return generate(key, provider, random); } catch (NoSuchProviderException e) { throw e; } catch (SignatureException e) { throw e; } catch (InvalidKeyException e) { throw e; } catch (NoSuchAlgorithmException e) { throw new SecurityException("exception: " + e); } catch (GeneralSecurityException e) { throw new SecurityException("exception: " + e); } } /** * generate an X509 CRL, based on the current issuer and subject * using the default provider. *

    * Note: this differs from the deprecated method in that the default provider is * used - not "BC". *

    */ public X509CRL generate( PrivateKey key) throws CRLException, IllegalStateException, NoSuchAlgorithmException, SignatureException, InvalidKeyException { return generate(key, (SecureRandom)null); } /** * generate an X509 CRL, based on the current issuer and subject * using the default provider and an user defined SecureRandom object as * source of randomness. *

    * Note: this differs from the deprecated method in that the default provider is * used - not "BC". *

    */ public X509CRL generate( PrivateKey key, SecureRandom random) throws CRLException, IllegalStateException, NoSuchAlgorithmException, SignatureException, InvalidKeyException { TBSCertList tbsCrl = generateCertList(); byte[] signature; try { signature = X509Util.calculateSignature(sigOID, signatureAlgorithm, key, random, tbsCrl); } catch (IOException e) { throw new ExtCRLException("cannot generate CRL encoding", e); } return generateJcaObject(tbsCrl, signature); } /** * generate an X509 certificate, based on the current issuer and subject * using the passed in provider for the signing. */ public X509CRL generate( PrivateKey key, String provider) throws CRLException, IllegalStateException, NoSuchProviderException, NoSuchAlgorithmException, SignatureException, InvalidKeyException { return generate(key, provider, null); } /** * generate an X509 CRL, based on the current issuer and subject, * using the passed in provider for the signing. */ public X509CRL generate( PrivateKey key, String provider, SecureRandom random) throws CRLException, IllegalStateException, NoSuchProviderException, NoSuchAlgorithmException, SignatureException, InvalidKeyException { TBSCertList tbsCrl = generateCertList(); byte[] signature; try { signature = X509Util.calculateSignature(sigOID, signatureAlgorithm, provider, key, random, tbsCrl); } catch (IOException e) { throw new ExtCRLException("cannot generate CRL encoding", e); } return generateJcaObject(tbsCrl, signature); } private TBSCertList generateCertList() { if (!extGenerator.isEmpty()) { tbsGen.setExtensions(extGenerator.generate()); } return tbsGen.generateTBSCertList(); } private X509CRL generateJcaObject(TBSCertList tbsCrl, byte[] signature) throws CRLException { ASN1EncodableVector v = new ASN1EncodableVector(); v.add(tbsCrl); v.add(sigAlgId); v.add(new DERBitString(signature)); return new X509CRLObject(new CertificateList(new DERSequence(v))); } /** * Return an iterator of the signature names supported by the generator. * * @return an iterator containing recognised names. */ public Iterator getSignatureAlgNames() { return X509Util.getAlgNames(); } private static class ExtCRLException extends CRLException { Throwable cause; ExtCRLException(String message, Throwable cause) { super(message); this.cause = cause; } public Throwable getCause() { return cause; } } } bouncycastle-1.49.orig/jdk1.1/org/bouncycastle/x509/X509V1CertificateGenerator.java0000644000175000017500000002516312132656275027161 0ustar ebourgebourgpackage org.bouncycastle.x509; import java.io.ByteArrayInputStream; import java.io.IOException; import java.math.BigInteger; import java.security.GeneralSecurityException; import java.security.InvalidKeyException; import java.security.NoSuchAlgorithmException; import java.security.NoSuchProviderException; import java.security.PrivateKey; import java.security.PublicKey; import java.security.SecureRandom; import java.security.SignatureException; import java.security.cert.CertificateEncodingException; import java.security.cert.CertificateParsingException; import java.security.cert.X509Certificate; import java.util.Date; import java.util.Iterator; import org.bouncycastle.asn1.ASN1EncodableVector; import org.bouncycastle.asn1.ASN1InputStream; import org.bouncycastle.asn1.ASN1Integer; import org.bouncycastle.asn1.ASN1Sequence; import org.bouncycastle.asn1.DERBitString; import org.bouncycastle.asn1.DERObjectIdentifier; import org.bouncycastle.asn1.DERSequence; import org.bouncycastle.asn1.x509.AlgorithmIdentifier; import org.bouncycastle.asn1.x509.SubjectPublicKeyInfo; import org.bouncycastle.asn1.x509.TBSCertificate; import org.bouncycastle.asn1.x509.Time; import org.bouncycastle.asn1.x509.V1TBSCertificateGenerator; import org.bouncycastle.asn1.x509.Certificate; import org.bouncycastle.asn1.x509.X509Name; import org.bouncycastle.jce.provider.X509CertificateObject; /** * class to produce an X.509 Version 1 certificate. * @deprecated use org.bouncycastle.cert.X509v1CertificateBuilder. */ public class X509V1CertificateGenerator { private V1TBSCertificateGenerator tbsGen; private DERObjectIdentifier sigOID; private AlgorithmIdentifier sigAlgId; private String signatureAlgorithm; public X509V1CertificateGenerator() { tbsGen = new V1TBSCertificateGenerator(); } /** * reset the generator */ public void reset() { tbsGen = new V1TBSCertificateGenerator(); } /** * set the serial number for the certificate. */ public void setSerialNumber( BigInteger serialNumber) { if (serialNumber.compareTo(BigInteger.valueOf(0)) <= 0) { throw new IllegalArgumentException("serial number must be a positive integer"); } tbsGen.setSerialNumber(new ASN1Integer(serialNumber)); } /** * Set the issuer distinguished name - the issuer is the entity whose private key is used to sign the * certificate. */ public void setIssuerDN( X509Name issuer) { tbsGen.setIssuer(issuer); } public void setNotBefore( Date date) { tbsGen.setStartDate(new Time(date)); } public void setNotAfter( Date date) { tbsGen.setEndDate(new Time(date)); } /** * Set the subject distinguished name. The subject describes the entity associated with the public key. */ public void setSubjectDN( X509Name subject) { tbsGen.setSubject(subject); } public void setPublicKey( PublicKey key) { try { tbsGen.setSubjectPublicKeyInfo(new SubjectPublicKeyInfo((ASN1Sequence)new ASN1InputStream( new ByteArrayInputStream(key.getEncoded())).readObject())); } catch (Exception e) { throw new IllegalArgumentException("unable to process key - " + e.toString()); } } /** * Set the signature algorithm. This can be either a name or an OID, names * are treated as case insensitive. * * @param signatureAlgorithm string representation of the algorithm name. */ public void setSignatureAlgorithm( String signatureAlgorithm) { this.signatureAlgorithm = signatureAlgorithm; try { sigOID = X509Util.getAlgorithmOID(signatureAlgorithm); } catch (Exception e) { throw new IllegalArgumentException("Unknown signature type requested"); } sigAlgId = X509Util.getSigAlgID(sigOID, signatureAlgorithm); tbsGen.setSignature(sigAlgId); } /** * generate an X509 certificate, based on the current issuer and subject * using the default provider "BC". * @deprecated use generate(key, "BC") */ public X509Certificate generateX509Certificate( PrivateKey key) throws SecurityException, SignatureException, InvalidKeyException { try { return generateX509Certificate(key, "BC", null); } catch (NoSuchProviderException e) { throw new SecurityException("BC provider not installed!"); } } /** * generate an X509 certificate, based on the current issuer and subject * using the default provider "BC" and the passed in source of randomness * @deprecated use generate(key, random, "BC") */ public X509Certificate generateX509Certificate( PrivateKey key, SecureRandom random) throws SecurityException, SignatureException, InvalidKeyException { try { return generateX509Certificate(key, "BC", random); } catch (NoSuchProviderException e) { throw new SecurityException("BC provider not installed!"); } } /** * generate an X509 certificate, based on the current issuer and subject, * using the passed in provider for the signing, and the passed in source * of randomness (if required). * @deprecated use generate() */ public X509Certificate generateX509Certificate( PrivateKey key, String provider) throws NoSuchProviderException, SecurityException, SignatureException, InvalidKeyException { return generateX509Certificate(key, provider, null); } /** * generate an X509 certificate, based on the current issuer and subject, * using the passed in provider for the signing, and the passed in source * of randomness (if required). * @deprecated use generate() */ public X509Certificate generateX509Certificate( PrivateKey key, String provider, SecureRandom random) throws NoSuchProviderException, SecurityException, SignatureException, InvalidKeyException { try { return generate(key, provider, random); } catch (NoSuchProviderException e) { throw e; } catch (SignatureException e) { throw e; } catch (InvalidKeyException e) { throw e; } catch (NoSuchAlgorithmException e) { throw new SecurityException("exception: " + e); } catch (GeneralSecurityException e) { throw new SecurityException("exception: " + e); } } /** * generate an X509 certificate, based on the current issuer and subject * using the default provider. *

    * Note: this differs from the deprecated method in that the default provider is * used - not "BC". *

    */ public X509Certificate generate( PrivateKey key) throws CertificateEncodingException, IllegalStateException, NoSuchAlgorithmException, SignatureException, InvalidKeyException { return generate(key, (SecureRandom)null); } /** * generate an X509 certificate, based on the current issuer and subject * using the default provider and the passed in source of randomness *

    * Note: this differs from the deprecated method in that the default provider is * used - not "BC". *

    */ public X509Certificate generate( PrivateKey key, SecureRandom random) throws CertificateEncodingException, IllegalStateException, NoSuchAlgorithmException, SignatureException, InvalidKeyException { TBSCertificate tbsCert = tbsGen.generateTBSCertificate(); byte[] signature; try { signature = X509Util.calculateSignature(sigOID, signatureAlgorithm, key, random, tbsCert); } catch (IOException e) { throw new ExtCertificateEncodingException("exception encoding TBS cert", e); } return generateJcaObject(tbsCert, signature); } /** * generate an X509 certificate, based on the current issuer and subject, * using the passed in provider for the signing, and the passed in source * of randomness (if required). */ public X509Certificate generate( PrivateKey key, String provider) throws CertificateEncodingException, IllegalStateException, NoSuchProviderException, NoSuchAlgorithmException, SignatureException, InvalidKeyException { return generate(key, provider, null); } /** * generate an X509 certificate, based on the current issuer and subject, * using the passed in provider for the signing, and the passed in source * of randomness (if required). */ public X509Certificate generate( PrivateKey key, String provider, SecureRandom random) throws CertificateEncodingException, IllegalStateException, NoSuchProviderException, NoSuchAlgorithmException, SignatureException, InvalidKeyException { TBSCertificate tbsCert = tbsGen.generateTBSCertificate(); byte[] signature; try { signature = X509Util.calculateSignature(sigOID, signatureAlgorithm, provider, key, random, tbsCert); } catch (IOException e) { throw new ExtCertificateEncodingException("exception encoding TBS cert", e); } return generateJcaObject(tbsCert, signature); } private X509Certificate generateJcaObject(TBSCertificate tbsCert, byte[] signature) throws CertificateEncodingException { ASN1EncodableVector v = new ASN1EncodableVector(); v.add(tbsCert); v.add(sigAlgId); v.add(new DERBitString(signature)); try { return new X509CertificateObject(Certificate.getInstance((new DERSequence(v)))); } catch (CertificateParsingException e) { throw new ExtCertificateEncodingException("exception producing certificate object", e); } } /** * Return an iterator of the signature names supported by the generator. * * @return an iterator containing recognised names. */ public Iterator getSignatureAlgNames() { return X509Util.getAlgNames(); } } bouncycastle-1.49.orig/jdk1.1/org/bouncycastle/x509/X509AttributeCertStoreSelector.java0000644000175000017500000003544211731467175030164 0ustar ebourgebourgpackage org.bouncycastle.x509; import org.bouncycastle.asn1.ASN1InputStream; import org.bouncycastle.asn1.ASN1Object; import org.bouncycastle.asn1.ASN1Primitive; import org.bouncycastle.asn1.DEROctetString; import org.bouncycastle.asn1.x509.GeneralName; import org.bouncycastle.asn1.x509.Target; import org.bouncycastle.asn1.x509.TargetInformation; import org.bouncycastle.asn1.x509.Targets; import org.bouncycastle.asn1.x509.X509Extensions; import org.bouncycastle.util.Selector; import java.io.IOException; import java.math.BigInteger; import java.security.cert.CertificateExpiredException; import java.security.cert.CertificateNotYetValidException; import java.security.cert.X509CertSelector; import java.util.Collection; import java.util.Collections; import java.util.Date; import java.util.HashSet; import java.util.Iterator; import java.util.Set; /** * This class is an Selector like implementation to select * attribute certificates from a given set of criteria. * * @see org.bouncycastle.x509.X509AttributeCertificate * @see org.bouncycastle.x509.X509Store */ public class X509AttributeCertStoreSelector implements Selector { // TODO: name constraints??? private AttributeCertificateHolder holder; private AttributeCertificateIssuer issuer; private BigInteger serialNumber; private Date attributeCertificateValid; private X509AttributeCertificate attributeCert; private Collection targetNames = new HashSet(); private Collection targetGroups = new HashSet(); public X509AttributeCertStoreSelector() { super(); } /** * Decides if the given attribute certificate should be selected. * * @param obj The attribute certificate which should be checked. * @return true if the attribute certificate can be selected, * false otherwise. */ public boolean match(Object obj) { if (!(obj instanceof X509AttributeCertificate)) { return false; } X509AttributeCertificate attrCert = (X509AttributeCertificate) obj; if (this.attributeCert != null) { if (!this.attributeCert.equals(attrCert)) { return false; } } if (serialNumber != null) { if (!attrCert.getSerialNumber().equals(serialNumber)) { return false; } } if (holder != null) { if (!attrCert.getHolder().equals(holder)) { return false; } } if (issuer != null) { if (!attrCert.getIssuer().equals(issuer)) { return false; } } if (attributeCertificateValid != null) { try { attrCert.checkValidity(attributeCertificateValid); } catch (CertificateExpiredException e) { return false; } catch (CertificateNotYetValidException e) { return false; } } if (!targetNames.isEmpty() || !targetGroups.isEmpty()) { byte[] targetInfoExt = attrCert .getExtensionValue(X509Extensions.TargetInformation.getId()); if (targetInfoExt != null) { TargetInformation targetinfo; try { targetinfo = TargetInformation .getInstance(new ASN1InputStream( ((DEROctetString) DEROctetString .fromByteArray(targetInfoExt)).getOctets()) .readObject()); } catch (IOException e) { return false; } catch (IllegalArgumentException e) { return false; } Targets[] targetss = targetinfo.getTargetsObjects(); if (!targetNames.isEmpty()) { boolean found = false; for (int i=0; inull
    is * given any will do. * * @param attributeCert The attribute certificate to set. */ public void setAttributeCert(X509AttributeCertificate attributeCert) { this.attributeCert = attributeCert; } /** * Get the criteria for the validity. * * @return Returns the attributeCertificateValid. */ public Date getAttributeCertificateValid() { if (attributeCertificateValid != null) { return new Date(attributeCertificateValid.getTime()); } return null; } /** * Set the time, when the certificate must be valid. If null * is given any will do. * * @param attributeCertificateValid The attribute certificate validation * time to set. */ public void setAttributeCertificateValid(Date attributeCertificateValid) { if (attributeCertificateValid != null) { this.attributeCertificateValid = new Date(attributeCertificateValid .getTime()); } else { this.attributeCertificateValid = null; } } /** * Gets the holder. * * @return Returns the holder. */ public AttributeCertificateHolder getHolder() { return holder; } /** * Sets the holder. If null is given any will do. * * @param holder The holder to set. */ public void setHolder(AttributeCertificateHolder holder) { this.holder = holder; } /** * Returns the issuer criterion. * * @return Returns the issuer. */ public AttributeCertificateIssuer getIssuer() { return issuer; } /** * Sets the issuer the attribute certificate must have. If null * is given any will do. * * @param issuer The issuer to set. */ public void setIssuer(AttributeCertificateIssuer issuer) { this.issuer = issuer; } /** * Gets the serial number the attribute certificate must have. * * @return Returns the serialNumber. */ public BigInteger getSerialNumber() { return serialNumber; } /** * Sets the serial number the attribute certificate must have. If * null is given any will do. * * @param serialNumber The serialNumber to set. */ public void setSerialNumber(BigInteger serialNumber) { this.serialNumber = serialNumber; } /** * Adds a target name criterion for the attribute certificate to the target * information extension criteria. The X509AttributeCertificate * must contain at least one of the specified target names. *

    * Each attribute certificate may contain a target information extension * limiting the servers where this attribute certificate can be used. If * this extension is not present, the attribute certificate is not targeted * and may be accepted by any server. * * @param name The name as a GeneralName (not null) */ public void addTargetName(GeneralName name) { targetNames.add(name); } /** * Adds a target name criterion for the attribute certificate to the target * information extension criteria. The X509AttributeCertificate * must contain at least one of the specified target names. *

    * Each attribute certificate may contain a target information extension * limiting the servers where this attribute certificate can be used. If * this extension is not present, the attribute certificate is not targeted * and may be accepted by any server. * * @param name a byte array containing the name in ASN.1 DER encoded form of a GeneralName * @throws IOException if a parsing error occurs. */ public void addTargetName(byte[] name) throws IOException { addTargetName(GeneralName.getInstance(ASN1Primitive.fromByteArray(name))); } /** * Adds a collection with target names criteria. If null is * given any will do. *

    * The collection consists of either GeneralName objects or byte[] arrays representing * DER encoded GeneralName structures. * * @param names A collection of target names. * @throws IOException if a parsing error occurs. * @see #addTargetName(byte[]) * @see #addTargetName(GeneralName) */ public void setTargetNames(Collection names) throws IOException { targetNames = extractGeneralNames(names); } /** * Gets the target names. The collection consists of Lists * made up of an Integer in the first entry and a DER encoded * byte array or a String in the second entry. *

    * The returned collection is immutable. * * @return The collection of target names * @see #setTargetNames(Collection) */ public Collection getTargetNames() { return Collections.unmodifiableCollection(targetNames); } /** * Adds a target group criterion for the attribute certificate to the target * information extension criteria. The X509AttributeCertificate * must contain at least one of the specified target groups. *

    * Each attribute certificate may contain a target information extension * limiting the servers where this attribute certificate can be used. If * this extension is not present, the attribute certificate is not targeted * and may be accepted by any server. * * @param group The group as GeneralName form (not null) */ public void addTargetGroup(GeneralName group) { targetGroups.add(group); } /** * Adds a target group criterion for the attribute certificate to the target * information extension criteria. The X509AttributeCertificate * must contain at least one of the specified target groups. *

    * Each attribute certificate may contain a target information extension * limiting the servers where this attribute certificate can be used. If * this extension is not present, the attribute certificate is not targeted * and may be accepted by any server. * * @param name a byte array containing the group in ASN.1 DER encoded form of a GeneralName * @throws IOException if a parsing error occurs. */ public void addTargetGroup(byte[] name) throws IOException { addTargetGroup(GeneralName.getInstance(ASN1Primitive.fromByteArray(name))); } /** * Adds a collection with target groups criteria. If null is * given any will do. *

    * The collection consists of GeneralName objects or byte[]Lists * made up of an Integer in the first entry and a DER encoded * byte array or a String in the second entry. *

    * The returned collection is immutable. * * @return The collection of target groups. * @see #setTargetGroups(Collection) */ public Collection getTargetGroups() { return Collections.unmodifiableCollection(targetGroups); } private Set extractGeneralNames(Collection names) throws IOException { if (names == null || names.isEmpty()) { return new HashSet(); } Set temp = new HashSet(); for (Iterator it = names.iterator(); it.hasNext();) { Object o = it.next(); if (o instanceof GeneralName) { temp.add(o); } else { temp.add(GeneralName.getInstance(ASN1Primitive.fromByteArray((byte[])o))); } } return temp; } } bouncycastle-1.49.orig/jdk1.1/org/bouncycastle/x509/X509V3CertificateGenerator.java0000644000175000017500000003553612132656275027170 0ustar ebourgebourgpackage org.bouncycastle.x509; import java.io.IOException; import java.math.BigInteger; import java.security.GeneralSecurityException; import java.security.InvalidKeyException; import java.security.NoSuchAlgorithmException; import java.security.NoSuchProviderException; import java.security.PrivateKey; import java.security.PublicKey; import java.security.SecureRandom; import java.security.SignatureException; import java.security.cert.CertificateEncodingException; import java.security.cert.CertificateParsingException; import java.security.cert.X509Certificate; import java.util.Date; import java.util.Iterator; import org.bouncycastle.asn1.ASN1Encodable; import org.bouncycastle.asn1.ASN1EncodableVector; import org.bouncycastle.asn1.ASN1InputStream; import org.bouncycastle.asn1.ASN1Integer; import org.bouncycastle.asn1.ASN1ObjectIdentifier; import org.bouncycastle.asn1.DERBitString; import org.bouncycastle.asn1.DERObjectIdentifier; import org.bouncycastle.asn1.DERSequence; import org.bouncycastle.asn1.x509.AlgorithmIdentifier; import org.bouncycastle.asn1.x509.SubjectPublicKeyInfo; import org.bouncycastle.asn1.x509.TBSCertificate; import org.bouncycastle.asn1.x509.Time; import org.bouncycastle.asn1.x509.V3TBSCertificateGenerator; import org.bouncycastle.asn1.x509.Certificate; import org.bouncycastle.asn1.x509.X509ExtensionsGenerator; import org.bouncycastle.asn1.x509.X509Name; import org.bouncycastle.jce.provider.X509CertificateObject; import org.bouncycastle.x509.extension.X509ExtensionUtil; /** * class to produce an X.509 Version 3 certificate. * @deprecated use org.bouncycastle.cert.X509v3CertificateBuilder. */ public class X509V3CertificateGenerator { private V3TBSCertificateGenerator tbsGen; private DERObjectIdentifier sigOID; private AlgorithmIdentifier sigAlgId; private String signatureAlgorithm; private X509ExtensionsGenerator extGenerator; public X509V3CertificateGenerator() { tbsGen = new V3TBSCertificateGenerator(); extGenerator = new X509ExtensionsGenerator(); } /** * reset the generator */ public void reset() { tbsGen = new V3TBSCertificateGenerator(); extGenerator.reset(); } /** * set the serial number for the certificate. */ public void setSerialNumber( BigInteger serialNumber) { if (serialNumber.compareTo(BigInteger.valueOf(0)) <= 0) { throw new IllegalArgumentException("serial number must be a positive integer"); } tbsGen.setSerialNumber(new ASN1Integer(serialNumber)); } /** * Set the issuer distinguished name - the issuer is the entity whose private key is used to sign the * certificate. */ public void setIssuerDN( X509Name issuer) { tbsGen.setIssuer(issuer); } public void setNotBefore( Date date) { tbsGen.setStartDate(new Time(date)); } public void setNotAfter( Date date) { tbsGen.setEndDate(new Time(date)); } /** * Set the subject distinguished name. The subject describes the entity associated with the public key. */ public void setSubjectDN( X509Name subject) { tbsGen.setSubject(subject); } public void setPublicKey( PublicKey key) throws IllegalArgumentException { try { tbsGen.setSubjectPublicKeyInfo( SubjectPublicKeyInfo.getInstance(new ASN1InputStream(key.getEncoded()).readObject())); } catch (Exception e) { throw new IllegalArgumentException("unable to process key - " + e.toString()); } } /** * Set the signature algorithm. This can be either a name or an OID, names * are treated as case insensitive. * * @param signatureAlgorithm string representation of the algorithm name. */ public void setSignatureAlgorithm( String signatureAlgorithm) { this.signatureAlgorithm = signatureAlgorithm; try { sigOID = X509Util.getAlgorithmOID(signatureAlgorithm); } catch (Exception e) { throw new IllegalArgumentException("Unknown signature type requested: " + signatureAlgorithm); } sigAlgId = X509Util.getSigAlgID(sigOID, signatureAlgorithm); tbsGen.setSignature(sigAlgId); } /** * Set the subject unique ID - note: it is very rare that it is correct to do this. */ public void setSubjectUniqueID(boolean[] uniqueID) { tbsGen.setSubjectUniqueID(booleanToBitString(uniqueID)); } /** * Set the issuer unique ID - note: it is very rare that it is correct to do this. */ public void setIssuerUniqueID(boolean[] uniqueID) { tbsGen.setIssuerUniqueID(booleanToBitString(uniqueID)); } private DERBitString booleanToBitString(boolean[] id) { byte[] bytes = new byte[(id.length + 7) / 8]; for (int i = 0; i != id.length; i++) { bytes[i / 8] |= (id[i]) ? (1 << ((7 - (i % 8)))) : 0; } int pad = id.length % 8; if (pad == 0) { return new DERBitString(bytes); } else { return new DERBitString(bytes, 8 - pad); } } /** * add a given extension field for the standard extensions tag (tag 3) */ public void addExtension( String oid, boolean critical, ASN1Encodable value) { this.addExtension(new DERObjectIdentifier(oid), critical, value); } /** * add a given extension field for the standard extensions tag (tag 3) */ public void addExtension( DERObjectIdentifier oid, boolean critical, ASN1Encodable value) { extGenerator.addExtension(new ASN1ObjectIdentifier(oid.getId()), critical, value); } /** * add a given extension field for the standard extensions tag (tag 3) * The value parameter becomes the contents of the octet string associated * with the extension. */ public void addExtension( String oid, boolean critical, byte[] value) { this.addExtension(new DERObjectIdentifier(oid), critical, value); } /** * add a given extension field for the standard extensions tag (tag 3) */ public void addExtension( DERObjectIdentifier oid, boolean critical, byte[] value) { extGenerator.addExtension(new ASN1ObjectIdentifier(oid.getId()), critical, value); } /** * add a given extension field for the standard extensions tag (tag 3) * copying the extension value from another certificate. * @throws CertificateParsingException if the extension cannot be extracted. */ public void copyAndAddExtension( String oid, boolean critical, X509Certificate cert) throws CertificateParsingException { byte[] extValue = cert.getExtensionValue(oid); if (extValue == null) { throw new CertificateParsingException("extension " + oid + " not present"); } try { ASN1Encodable value = X509ExtensionUtil.fromExtensionValue(extValue); this.addExtension(oid, critical, value); } catch (IOException e) { throw new CertificateParsingException(e.toString()); } } /** * add a given extension field for the standard extensions tag (tag 3) * copying the extension value from another certificate. * @throws CertificateParsingException if the extension cannot be extracted. */ public void copyAndAddExtension( DERObjectIdentifier oid, boolean critical, X509Certificate cert) throws CertificateParsingException { this.copyAndAddExtension(oid.getId(), critical, cert); } /** * generate an X509 certificate, based on the current issuer and subject * using the default provider "BC". * @deprecated use generate(key, "BC") */ public X509Certificate generateX509Certificate( PrivateKey key) throws SecurityException, SignatureException, InvalidKeyException { try { return generateX509Certificate(key, "BC", null); } catch (NoSuchProviderException e) { throw new SecurityException("BC provider not installed!"); } } /** * generate an X509 certificate, based on the current issuer and subject * using the default provider "BC", and the passed in source of randomness * (if required). * @deprecated use generate(key, random, "BC") */ public X509Certificate generateX509Certificate( PrivateKey key, SecureRandom random) throws SecurityException, SignatureException, InvalidKeyException { try { return generateX509Certificate(key, "BC", random); } catch (NoSuchProviderException e) { throw new SecurityException("BC provider not installed!"); } } /** * generate an X509 certificate, based on the current issuer and subject, * using the passed in provider for the signing. * @deprecated use generate() */ public X509Certificate generateX509Certificate( PrivateKey key, String provider) throws NoSuchProviderException, SecurityException, SignatureException, InvalidKeyException { return generateX509Certificate(key, provider, null); } /** * generate an X509 certificate, based on the current issuer and subject, * using the passed in provider for the signing and the supplied source * of randomness, if required. * @deprecated use generate() */ public X509Certificate generateX509Certificate( PrivateKey key, String provider, SecureRandom random) throws NoSuchProviderException, SecurityException, SignatureException, InvalidKeyException { try { return generate(key, provider, random); } catch (NoSuchProviderException e) { throw e; } catch (SignatureException e) { throw e; } catch (InvalidKeyException e) { throw e; } catch (NoSuchAlgorithmException e) { throw new SecurityException("exception: " + e); } catch (GeneralSecurityException e) { throw new SecurityException("exception: " + e); } } /** * generate an X509 certificate, based on the current issuer and subject * using the default provider. *

    * Note: this differs from the deprecated method in that the default provider is * used - not "BC". *

    */ public X509Certificate generate( PrivateKey key) throws CertificateEncodingException, IllegalStateException, NoSuchAlgorithmException, SignatureException, InvalidKeyException { return generate(key, (SecureRandom)null); } /** * generate an X509 certificate, based on the current issuer and subject * using the default provider, and the passed in source of randomness * (if required). *

    * Note: this differs from the deprecated method in that the default provider is * used - not "BC". *

    */ public X509Certificate generate( PrivateKey key, SecureRandom random) throws CertificateEncodingException, IllegalStateException, NoSuchAlgorithmException, SignatureException, InvalidKeyException { TBSCertificate tbsCert = generateTbsCert(); byte[] signature; try { signature = X509Util.calculateSignature(sigOID, signatureAlgorithm, key, random, tbsCert); } catch (IOException e) { throw new ExtCertificateEncodingException("exception encoding TBS cert", e); } try { return generateJcaObject(tbsCert, signature); } catch (CertificateParsingException e) { throw new ExtCertificateEncodingException("exception producing certificate object", e); } } /** * generate an X509 certificate, based on the current issuer and subject, * using the passed in provider for the signing. */ public X509Certificate generate( PrivateKey key, String provider) throws CertificateEncodingException, IllegalStateException, NoSuchProviderException, NoSuchAlgorithmException, SignatureException, InvalidKeyException { return generate(key, provider, null); } /** * generate an X509 certificate, based on the current issuer and subject, * using the passed in provider for the signing and the supplied source * of randomness, if required. */ public X509Certificate generate( PrivateKey key, String provider, SecureRandom random) throws CertificateEncodingException, IllegalStateException, NoSuchProviderException, NoSuchAlgorithmException, SignatureException, InvalidKeyException { TBSCertificate tbsCert = generateTbsCert(); byte[] signature; try { signature = X509Util.calculateSignature(sigOID, signatureAlgorithm, provider, key, random, tbsCert); } catch (IOException e) { throw new ExtCertificateEncodingException("exception encoding TBS cert", e); } try { return generateJcaObject(tbsCert, signature); } catch (CertificateParsingException e) { throw new ExtCertificateEncodingException("exception producing certificate object", e); } } private TBSCertificate generateTbsCert() { if (!extGenerator.isEmpty()) { tbsGen.setExtensions(extGenerator.generate()); } return tbsGen.generateTBSCertificate(); } private X509Certificate generateJcaObject(TBSCertificate tbsCert, byte[] signature) throws CertificateParsingException { ASN1EncodableVector v = new ASN1EncodableVector(); v.add(tbsCert); v.add(sigAlgId); v.add(new DERBitString(signature)); return new X509CertificateObject(Certificate.getInstance(new DERSequence(v))); } /** * Return an iterator of the signature names supported by the generator. * * @return an iterator containing recognised names. */ public Iterator getSignatureAlgNames() { return X509Util.getAlgNames(); } } bouncycastle-1.49.orig/jdk1.1/org/bouncycastle/operator/0000755000175000017500000000000012152033551022533 5ustar ebourgebourgbouncycastle-1.49.orig/jdk1.1/org/bouncycastle/operator/jcajce/0000755000175000017500000000000012152033551023752 5ustar ebourgebourg././@LongLink0000000000000000000000000000014600000000000011566 Lustar rootrootbouncycastle-1.49.orig/jdk1.1/org/bouncycastle/operator/jcajce/JcaContentVerifierProviderBuilder.javabouncycastle-1.49.orig/jdk1.1/org/bouncycastle/operator/jcajce/JcaContentVerifierProviderBuilder.jav0000644000175000017500000002160311731466726033244 0ustar ebourgebourgpackage org.bouncycastle.operator.jcajce; import java.io.IOException; import java.io.OutputStream; import java.security.GeneralSecurityException; import java.security.Provider; import java.security.PublicKey; import java.security.Signature; import java.security.SignatureException; import java.security.InvalidKeyException; import java.security.cert.CertificateEncodingException; import java.security.cert.CertificateException; import java.security.cert.X509Certificate; import org.bouncycastle.asn1.x509.AlgorithmIdentifier; import org.bouncycastle.cert.X509CertificateHolder; import org.bouncycastle.cert.jcajce.JcaX509CertificateHolder; import org.bouncycastle.jcajce.DefaultJcaJceHelper; import org.bouncycastle.jcajce.NamedJcaJceHelper; import org.bouncycastle.jcajce.ProviderJcaJceHelper; import org.bouncycastle.operator.ContentVerifier; import org.bouncycastle.operator.ContentVerifierProvider; import org.bouncycastle.operator.OperatorCreationException; import org.bouncycastle.operator.OperatorStreamException; import org.bouncycastle.operator.RawContentVerifier; import org.bouncycastle.operator.RuntimeOperatorException; public class JcaContentVerifierProviderBuilder { private OperatorHelper helper = new OperatorHelper(new DefaultJcaJceHelper()); public JcaContentVerifierProviderBuilder() { } public JcaContentVerifierProviderBuilder setProvider(Provider provider) { this.helper = new OperatorHelper(new ProviderJcaJceHelper(provider)); return this; } public JcaContentVerifierProviderBuilder setProvider(String providerName) { this.helper = new OperatorHelper(new NamedJcaJceHelper(providerName)); return this; } public ContentVerifierProvider build(X509CertificateHolder certHolder) throws OperatorCreationException, CertificateException { return build(helper.convertCertificate(certHolder)); } public ContentVerifierProvider build(final X509Certificate certificate) throws OperatorCreationException { final X509CertificateHolder certHolder; try { certHolder = new JcaX509CertificateHolder(certificate); } catch (CertificateEncodingException e) { throw new OperatorCreationException("cannot process certificate: " + e.getMessage(), e); } return new ContentVerifierProvider() { private SignatureOutputStream stream; public boolean hasAssociatedCertificate() { return true; } public X509CertificateHolder getAssociatedCertificate() { return certHolder; } public ContentVerifier get(AlgorithmIdentifier algorithm) throws OperatorCreationException { try { Signature sig = helper.createSignature(algorithm); sig.initVerify(certificate.getPublicKey()); stream = new SignatureOutputStream(sig); } catch (InvalidKeyException e) { throw new OperatorCreationException("exception on setup: " + e, e); } catch (GeneralSecurityException e) { throw new OperatorCreationException("exception on setup: " + e, e); } Signature rawSig = createRawSig(algorithm, certificate.getPublicKey()); if (rawSig != null) { return new RawSigVerifier(algorithm, stream, rawSig); } else { return new SigVerifier(algorithm, stream); } } }; } public ContentVerifierProvider build(final PublicKey publicKey) throws OperatorCreationException { return new ContentVerifierProvider() { public boolean hasAssociatedCertificate() { return false; } public X509CertificateHolder getAssociatedCertificate() { return null; } public ContentVerifier get(AlgorithmIdentifier algorithm) throws OperatorCreationException { SignatureOutputStream stream = createSignatureStream(algorithm, publicKey); Signature rawSig = createRawSig(algorithm, publicKey); if (rawSig != null) { return new RawSigVerifier(algorithm, stream, rawSig); } else { return new SigVerifier(algorithm, stream); } } }; } private SignatureOutputStream createSignatureStream(AlgorithmIdentifier algorithm, PublicKey publicKey) throws OperatorCreationException { try { Signature sig = helper.createSignature(algorithm); sig.initVerify(publicKey); return new SignatureOutputStream(sig); } catch (InvalidKeyException e) { throw new OperatorCreationException("exception on setup: " + e, e); } catch (GeneralSecurityException e) { throw new OperatorCreationException("exception on setup: " + e, e); } } private Signature createRawSig(AlgorithmIdentifier algorithm, PublicKey publicKey) { Signature rawSig; try { rawSig = helper.createRawSignature(algorithm); if (rawSig != null) { rawSig.initVerify(publicKey); } } catch (Exception e) { rawSig = null; } return rawSig; } private class SigVerifier implements ContentVerifier { private SignatureOutputStream stream; private AlgorithmIdentifier algorithm; SigVerifier(AlgorithmIdentifier algorithm, SignatureOutputStream stream) { this.algorithm = algorithm; this.stream = stream; } public AlgorithmIdentifier getAlgorithmIdentifier() { return algorithm; } public OutputStream getOutputStream() { if (stream == null) { throw new IllegalStateException("verifier not initialised"); } return stream; } public boolean verify(byte[] expected) { try { return stream.verify(expected); } catch (SignatureException e) { throw new RuntimeOperatorException("exception obtaining signature: " + e.getMessage(), e); } } } private class RawSigVerifier extends SigVerifier implements RawContentVerifier { private Signature rawSignature; RawSigVerifier(AlgorithmIdentifier algorithm, SignatureOutputStream stream, Signature rawSignature) { super(algorithm, stream); this.rawSignature = rawSignature; } public boolean verify(byte[] digest, byte[] expected) { try { rawSignature.update(digest); return rawSignature.verify(expected); } catch (SignatureException e) { throw new RuntimeOperatorException("exception obtaining raw signature: " + e.getMessage(), e); } } } private class SignatureOutputStream extends OutputStream { private Signature sig; SignatureOutputStream(Signature sig) { this.sig = sig; } public void write(byte[] bytes, int off, int len) throws IOException { try { sig.update(bytes, off, len); } catch (SignatureException e) { throw new OperatorStreamException("exception in content signer: " + e.getMessage(), e); } } public void write(byte[] bytes) throws IOException { try { sig.update(bytes); } catch (SignatureException e) { throw new OperatorStreamException("exception in content signer: " + e.getMessage(), e); } } public void write(int b) throws IOException { try { sig.update((byte)b); } catch (SignatureException e) { throw new OperatorStreamException("exception in content signer: " + e.getMessage(), e); } } boolean verify(byte[] expected) throws SignatureException { return sig.verify(expected); } } } bouncycastle-1.49.orig/jdk1.1/org/bouncycastle/operator/jcajce/JceAsymmetricKeyWrapper.java0000644000175000017500000001014611731466727031411 0ustar ebourgebourgpackage org.bouncycastle.operator.jcajce; import java.security.GeneralSecurityException; import java.security.InvalidKeyException; import java.security.Provider; import java.security.ProviderException; import java.security.PublicKey; import java.security.SecureRandom; import java.security.cert.X509Certificate; import java.util.HashMap; import java.util.Map; import javax.crypto.Cipher; import org.bouncycastle.asn1.ASN1ObjectIdentifier; import org.bouncycastle.asn1.x509.SubjectPublicKeyInfo; import org.bouncycastle.jcajce.DefaultJcaJceHelper; import org.bouncycastle.jcajce.NamedJcaJceHelper; import org.bouncycastle.jcajce.ProviderJcaJceHelper; import org.bouncycastle.operator.AsymmetricKeyWrapper; import org.bouncycastle.operator.GenericKey; import org.bouncycastle.operator.OperatorException; public class JceAsymmetricKeyWrapper extends AsymmetricKeyWrapper { private OperatorHelper helper = new OperatorHelper(new DefaultJcaJceHelper()); private Map extraMappings = new HashMap(); private PublicKey publicKey; private SecureRandom random; public JceAsymmetricKeyWrapper(PublicKey publicKey) { super(SubjectPublicKeyInfo.getInstance(publicKey.getEncoded()).getAlgorithm()); this.publicKey = publicKey; } public JceAsymmetricKeyWrapper(X509Certificate certificate) { this(certificate.getPublicKey()); } public JceAsymmetricKeyWrapper setProvider(Provider provider) { this.helper = new OperatorHelper(new ProviderJcaJceHelper(provider)); return this; } public JceAsymmetricKeyWrapper setProvider(String providerName) { this.helper = new OperatorHelper(new NamedJcaJceHelper(providerName)); return this; } public JceAsymmetricKeyWrapper setSecureRandom(SecureRandom random) { this.random = random; return this; } /** * Internally algorithm ids are converted into cipher names using a lookup table. For some providers * the standard lookup table won't work. Use this method to establish a specific mapping from an * algorithm identifier to a specific algorithm. *

    * For example: *

         *     unwrapper.setAlgorithmMapping(PKCSObjectIdentifiers.rsaEncryption, "RSA");
         * 
    *

    * @param algorithm OID of algorithm in recipient. * @param algorithmName JCE algorithm name to use. * @return the current Wrapper. */ public JceAsymmetricKeyWrapper setAlgorithmMapping(ASN1ObjectIdentifier algorithm, String algorithmName) { extraMappings.put(algorithm, algorithmName); return this; } public byte[] generateWrappedKey(GenericKey encryptionKey) throws OperatorException { Cipher keyEncryptionCipher = helper.createAsymmetricWrapper(getAlgorithmIdentifier().getAlgorithm(), extraMappings); byte[] encryptedKeyBytes = null; try { keyEncryptionCipher.init(Cipher.WRAP_MODE, publicKey, random); encryptedKeyBytes = keyEncryptionCipher.wrap(OperatorUtils.getJceKey(encryptionKey)); } catch (InvalidKeyException e) { } catch (GeneralSecurityException e) { } catch (IllegalStateException e) { } catch (UnsupportedOperationException e) { } catch (ProviderException e) { } // some providers do not support WRAP (this appears to be only for asymmetric algorithms) if (encryptedKeyBytes == null) { try { keyEncryptionCipher.init(Cipher.ENCRYPT_MODE, publicKey, random); encryptedKeyBytes = keyEncryptionCipher.doFinal(OperatorUtils.getJceKey(encryptionKey).getEncoded()); } catch (InvalidKeyException e) { throw new OperatorException("unable to encrypt contents key", e); } catch (GeneralSecurityException e) { throw new OperatorException("unable to encrypt contents key", e); } } return encryptedKeyBytes; } } bouncycastle-1.49.orig/jdk1.1/org/bouncycastle/operator/jcajce/JceSymmetricKeyWrapper.java0000644000175000017500000001164611731466727031256 0ustar ebourgebourgpackage org.bouncycastle.operator.jcajce; import java.security.GeneralSecurityException; import java.security.Key; import java.security.Provider; import java.security.SecureRandom; import java.security.InvalidKeyException; import javax.crypto.Cipher; import javax.crypto.SecretKey; import org.bouncycastle.asn1.DERInteger; import org.bouncycastle.asn1.DERNull; import org.bouncycastle.asn1.DERObjectIdentifier; import org.bouncycastle.asn1.kisa.KISAObjectIdentifiers; import org.bouncycastle.asn1.nist.NISTObjectIdentifiers; import org.bouncycastle.asn1.ntt.NTTObjectIdentifiers; import org.bouncycastle.asn1.x509.AlgorithmIdentifier; import org.bouncycastle.jcajce.DefaultJcaJceHelper; import org.bouncycastle.jcajce.NamedJcaJceHelper; import org.bouncycastle.jcajce.ProviderJcaJceHelper; import org.bouncycastle.operator.GenericKey; import org.bouncycastle.operator.OperatorException; import org.bouncycastle.operator.SymmetricKeyWrapper; public class JceSymmetricKeyWrapper extends SymmetricKeyWrapper { private OperatorHelper helper = new OperatorHelper(new DefaultJcaJceHelper()); private SecureRandom random; private SecretKey wrappingKey; public JceSymmetricKeyWrapper(SecretKey wrappingKey) { super(determineKeyEncAlg(wrappingKey)); this.wrappingKey = wrappingKey; } public JceSymmetricKeyWrapper setProvider(Provider provider) { this.helper = new OperatorHelper(new ProviderJcaJceHelper(provider)); return this; } public JceSymmetricKeyWrapper setProvider(String providerName) { this.helper = new OperatorHelper(new NamedJcaJceHelper(providerName)); return this; } public JceSymmetricKeyWrapper setSecureRandom(SecureRandom random) { this.random = random; return this; } public byte[] generateWrappedKey(GenericKey encryptionKey) throws OperatorException { Key contentEncryptionKeySpec = OperatorUtils.getJceKey(encryptionKey); Cipher keyEncryptionCipher = helper.createSymmetricWrapper(this.getAlgorithmIdentifier().getAlgorithm()); try { keyEncryptionCipher.init(Cipher.WRAP_MODE, wrappingKey, random); return keyEncryptionCipher.wrap(contentEncryptionKeySpec); } catch (InvalidKeyException e) { throw new OperatorException("cannot wrap key: " + e.getMessage(), e); } catch (GeneralSecurityException e) { throw new OperatorException("cannot wrap key: " + e.getMessage(), e); } } private static AlgorithmIdentifier determineKeyEncAlg(SecretKey key) { String algorithm = key.getAlgorithm(); if (algorithm.startsWith("DES")) { return new AlgorithmIdentifier(new DERObjectIdentifier( "1.2.840.113549.1.9.16.3.6"), new DERNull()); } else if (algorithm.startsWith("RC2")) { return new AlgorithmIdentifier(new DERObjectIdentifier( "1.2.840.113549.1.9.16.3.7"), new DERInteger(58)); } else if (algorithm.startsWith("AES")) { int length = key.getEncoded().length * 8; DERObjectIdentifier wrapOid; if (length == 128) { wrapOid = NISTObjectIdentifiers.id_aes128_wrap; } else if (length == 192) { wrapOid = NISTObjectIdentifiers.id_aes192_wrap; } else if (length == 256) { wrapOid = NISTObjectIdentifiers.id_aes256_wrap; } else { throw new IllegalArgumentException("illegal keysize in AES"); } return new AlgorithmIdentifier(wrapOid); // parameters absent } else if (algorithm.startsWith("SEED")) { // parameters absent return new AlgorithmIdentifier( KISAObjectIdentifiers.id_npki_app_cmsSeed_wrap); } else if (algorithm.startsWith("Camellia")) { int length = key.getEncoded().length * 8; DERObjectIdentifier wrapOid; if (length == 128) { wrapOid = NTTObjectIdentifiers.id_camellia128_wrap; } else if (length == 192) { wrapOid = NTTObjectIdentifiers.id_camellia192_wrap; } else if (length == 256) { wrapOid = NTTObjectIdentifiers.id_camellia256_wrap; } else { throw new IllegalArgumentException( "illegal keysize in Camellia"); } return new AlgorithmIdentifier(wrapOid); // parameters must be // absent } else { throw new IllegalArgumentException("unknown algorithm"); } } } bouncycastle-1.49.orig/jdk1.1/org/bouncycastle/operator/jcajce/JceAsymmetricKeyUnwrapper.java0000644000175000017500000001024211731467175031747 0ustar ebourgebourgpackage org.bouncycastle.operator.jcajce; import java.security.GeneralSecurityException; import java.security.InvalidKeyException; import java.security.NoSuchAlgorithmException; import java.security.Key; import java.security.PrivateKey; import java.security.Provider; import java.security.ProviderException; import java.util.HashMap; import java.util.Map; import javax.crypto.BadPaddingException; import javax.crypto.Cipher; import javax.crypto.IllegalBlockSizeException; import javax.crypto.spec.SecretKeySpec; import org.bouncycastle.asn1.ASN1ObjectIdentifier; import org.bouncycastle.asn1.x509.AlgorithmIdentifier; import org.bouncycastle.jcajce.DefaultJcaJceHelper; import org.bouncycastle.jcajce.NamedJcaJceHelper; import org.bouncycastle.jcajce.ProviderJcaJceHelper; import org.bouncycastle.operator.AsymmetricKeyUnwrapper; import org.bouncycastle.operator.GenericKey; import org.bouncycastle.operator.OperatorException; public class JceAsymmetricKeyUnwrapper extends AsymmetricKeyUnwrapper { private OperatorHelper helper = new OperatorHelper(new DefaultJcaJceHelper()); private Map extraMappings = new HashMap(); private PrivateKey privKey; public JceAsymmetricKeyUnwrapper(AlgorithmIdentifier algorithmIdentifier, PrivateKey privKey) { super(algorithmIdentifier); this.privKey = privKey; } public JceAsymmetricKeyUnwrapper setProvider(Provider provider) { this.helper = new OperatorHelper(new ProviderJcaJceHelper(provider)); return this; } public JceAsymmetricKeyUnwrapper setProvider(String providerName) { this.helper = new OperatorHelper(new NamedJcaJceHelper(providerName)); return this; } /** * Internally algorithm ids are converted into cipher names using a lookup table. For some providers * the standard lookup table won't work. Use this method to establish a specific mapping from an * algorithm identifier to a specific algorithm. *

    * For example: *

         *     unwrapper.setAlgorithmMapping(PKCSObjectIdentifiers.rsaEncryption, "RSA");
         * 
    *

    * @param algorithm OID of algorithm in recipient. * @param algorithmName JCE algorithm name to use. * @return the current Unwrapper. */ public JceAsymmetricKeyUnwrapper setAlgorithmMapping(ASN1ObjectIdentifier algorithm, String algorithmName) { extraMappings.put(algorithm, algorithmName); return this; } public GenericKey generateUnwrappedKey(AlgorithmIdentifier encryptedKeyAlgorithm, byte[] encryptedKey) throws OperatorException { try { Key sKey = null; Cipher keyCipher = helper.createAsymmetricWrapper(this.getAlgorithmIdentifier().getAlgorithm(), extraMappings); try { keyCipher.init(Cipher.UNWRAP_MODE, privKey); sKey = keyCipher.unwrap(encryptedKey, helper.getKeyAlgorithmName(encryptedKeyAlgorithm.getAlgorithm()), Cipher.SECRET_KEY); } catch (NoSuchAlgorithmException e) { } catch (InvalidKeyException e) { } catch (IllegalStateException e) { } catch (UnsupportedOperationException e) { } catch (ProviderException e) { } // some providers do not support UNWRAP (this appears to be only for asymmetric algorithms) if (sKey == null) { keyCipher.init(Cipher.DECRYPT_MODE, privKey); sKey = new SecretKeySpec(keyCipher.doFinal(encryptedKey), encryptedKeyAlgorithm.getAlgorithm().getId()); } return new GenericKey(sKey); } catch (InvalidKeyException e) { throw new OperatorException("key invalid: " + e.getMessage(), e); } catch (IllegalBlockSizeException e) { throw new OperatorException("illegal blocksize: " + e.getMessage(), e); } catch (BadPaddingException e) { throw new OperatorException("bad padding: " + e.getMessage(), e); } } } bouncycastle-1.49.orig/jdk1.1/org/bouncycastle/operator/jcajce/OperatorHelper.java0000644000175000017500000003416111731467175027574 0ustar ebourgebourgpackage org.bouncycastle.operator.jcajce; import java.io.ByteArrayInputStream; import java.io.IOException; import java.security.GeneralSecurityException; import java.security.MessageDigest; import java.security.NoSuchAlgorithmException; import java.security.NoSuchProviderException; import java.security.Signature; import java.security.cert.CertificateException; import java.security.cert.CertificateFactory; import java.security.cert.X509Certificate; import java.util.HashMap; import java.util.Map; import javax.crypto.Cipher; import org.bouncycastle.asn1.ASN1Encodable; import org.bouncycastle.asn1.ASN1ObjectIdentifier; import org.bouncycastle.asn1.DERNull; import org.bouncycastle.asn1.cryptopro.CryptoProObjectIdentifiers; import org.bouncycastle.asn1.kisa.KISAObjectIdentifiers; import org.bouncycastle.asn1.nist.NISTObjectIdentifiers; import org.bouncycastle.asn1.ntt.NTTObjectIdentifiers; import org.bouncycastle.asn1.oiw.OIWObjectIdentifiers; import org.bouncycastle.asn1.pkcs.PKCSObjectIdentifiers; import org.bouncycastle.asn1.pkcs.RSASSAPSSparams; import org.bouncycastle.asn1.teletrust.TeleTrusTObjectIdentifiers; import org.bouncycastle.asn1.x509.AlgorithmIdentifier; import org.bouncycastle.asn1.x9.X9ObjectIdentifiers; import org.bouncycastle.cert.X509CertificateHolder; import org.bouncycastle.jcajce.JcaJceHelper; import org.bouncycastle.operator.OperatorCreationException; //import java.security.spec.PSSParameterSpec; class OperatorHelper { private static final Map oids = new HashMap(); private static final Map asymmetricWrapperAlgNames = new HashMap(); private static final Map symmetricWrapperAlgNames = new HashMap(); private static final Map symmetricKeyAlgNames = new HashMap(); static { // // reverse mappings // oids.put(new ASN1ObjectIdentifier("1.2.840.113549.1.1.5"), "SHA1WITHRSA"); oids.put(PKCSObjectIdentifiers.sha224WithRSAEncryption, "SHA224WITHRSA"); oids.put(PKCSObjectIdentifiers.sha256WithRSAEncryption, "SHA256WITHRSA"); oids.put(PKCSObjectIdentifiers.sha384WithRSAEncryption, "SHA384WITHRSA"); oids.put(PKCSObjectIdentifiers.sha512WithRSAEncryption, "SHA512WITHRSA"); oids.put(CryptoProObjectIdentifiers.gostR3411_94_with_gostR3410_94, "GOST3411WITHGOST3410"); oids.put(CryptoProObjectIdentifiers.gostR3411_94_with_gostR3410_2001, "GOST3411WITHECGOST3410"); oids.put(new ASN1ObjectIdentifier("1.2.840.113549.1.1.4"), "MD5WITHRSA"); oids.put(new ASN1ObjectIdentifier("1.2.840.113549.1.1.2"), "MD2WITHRSA"); oids.put(new ASN1ObjectIdentifier("1.2.840.10040.4.3"), "SHA1WITHDSA"); oids.put(X9ObjectIdentifiers.ecdsa_with_SHA1, "SHA1WITHECDSA"); oids.put(X9ObjectIdentifiers.ecdsa_with_SHA224, "SHA224WITHECDSA"); oids.put(X9ObjectIdentifiers.ecdsa_with_SHA256, "SHA256WITHECDSA"); oids.put(X9ObjectIdentifiers.ecdsa_with_SHA384, "SHA384WITHECDSA"); oids.put(X9ObjectIdentifiers.ecdsa_with_SHA512, "SHA512WITHECDSA"); oids.put(OIWObjectIdentifiers.sha1WithRSA, "SHA1WITHRSA"); oids.put(OIWObjectIdentifiers.dsaWithSHA1, "SHA1WITHDSA"); oids.put(NISTObjectIdentifiers.dsa_with_sha224, "SHA224WITHDSA"); oids.put(NISTObjectIdentifiers.dsa_with_sha256, "SHA256WITHDSA"); asymmetricWrapperAlgNames.put(new ASN1ObjectIdentifier(PKCSObjectIdentifiers.rsaEncryption.getId()), "RSA/ECB/PKCS1Padding"); symmetricWrapperAlgNames.put(PKCSObjectIdentifiers.id_alg_CMS3DESwrap, "DESEDEWrap"); symmetricWrapperAlgNames.put(PKCSObjectIdentifiers.id_alg_CMSRC2wrap, "RC2Wrap"); symmetricWrapperAlgNames.put(NISTObjectIdentifiers.id_aes128_wrap, "AESWrap"); symmetricWrapperAlgNames.put(NISTObjectIdentifiers.id_aes192_wrap, "AESWrap"); symmetricWrapperAlgNames.put(NISTObjectIdentifiers.id_aes256_wrap, "AESWrap"); symmetricWrapperAlgNames.put(NTTObjectIdentifiers.id_camellia128_wrap, "CamelliaWrap"); symmetricWrapperAlgNames.put(NTTObjectIdentifiers.id_camellia192_wrap, "CamelliaWrap"); symmetricWrapperAlgNames.put(NTTObjectIdentifiers.id_camellia256_wrap, "CamelliaWrap"); symmetricWrapperAlgNames.put(KISAObjectIdentifiers.id_npki_app_cmsSeed_wrap, "SEEDWrap"); symmetricWrapperAlgNames.put(PKCSObjectIdentifiers.des_EDE3_CBC, "DESede"); symmetricKeyAlgNames.put(NISTObjectIdentifiers.aes, "AES"); symmetricKeyAlgNames.put(NISTObjectIdentifiers.id_aes128_CBC, "AES"); symmetricKeyAlgNames.put(NISTObjectIdentifiers.id_aes192_CBC, "AES"); symmetricKeyAlgNames.put(NISTObjectIdentifiers.id_aes256_CBC, "AES"); symmetricKeyAlgNames.put(PKCSObjectIdentifiers.des_EDE3_CBC, "DESede"); symmetricKeyAlgNames.put(PKCSObjectIdentifiers.RC2_CBC, "RC2"); } private JcaJceHelper helper; OperatorHelper(JcaJceHelper helper) { this.helper = helper; } Cipher createAsymmetricWrapper(ASN1ObjectIdentifier algorithm, Map extraAlgNames) throws OperatorCreationException { try { try { String cipherName = null; if (!extraAlgNames.isEmpty()) { cipherName = (String)extraAlgNames.get(algorithm); } if (cipherName == null) { cipherName = (String)asymmetricWrapperAlgNames.get(algorithm); } if (cipherName != null) { try { // this is reversed as the Sun policy files now allow unlimited strength RSA return helper.createCipher(cipherName); } catch (NoSuchAlgorithmException e) { // try alternate for RSA if (cipherName.equals("RSA/ECB/PKCS1Padding")) { try { return helper.createCipher("RSA/NONE/PKCS1Padding"); } catch (NoSuchAlgorithmException ex) { // Ignore } } // Ignore } } return helper.createCipher(algorithm.getId()); } catch (NoSuchAlgorithmException e) { throw new OperatorCreationException("cannot create cipher: " + e.getMessage(), e); } catch (NoSuchProviderException e) { throw new OperatorCreationException("cannot create cipher: " + e.getMessage(), e); } } catch (GeneralSecurityException e) { throw new OperatorCreationException("cannot create cipher: " + e.getMessage(), e); } } Cipher createSymmetricWrapper(ASN1ObjectIdentifier algorithm) throws OperatorCreationException { try { String cipherName = (String)symmetricWrapperAlgNames.get(algorithm); if (cipherName != null) { try { // this is reversed as the Sun policy files now allow unlimited strength RSA return helper.createCipher(cipherName); } catch (NoSuchAlgorithmException e) { // Ignore } } return helper.createCipher(algorithm.getId()); } catch (NoSuchAlgorithmException e) { throw new OperatorCreationException("cannot create cipher: " + e.getMessage(), e); } catch (NoSuchProviderException e) { throw new OperatorCreationException("cannot create cipher: " + e.getMessage(), e); } catch (GeneralSecurityException e) { throw new OperatorCreationException("cannot create cipher: " + e.getMessage(), e); } } MessageDigest createDigest(AlgorithmIdentifier digAlgId) throws GeneralSecurityException { try { MessageDigest dig; try { dig = helper.createDigest(getDigestAlgName(digAlgId.getAlgorithm())); } catch (NoSuchAlgorithmException e) { // // try an alternate // if (oids.get(digAlgId.getAlgorithm()) != null) { String digestAlgorithm = (String)oids.get(digAlgId.getAlgorithm()); dig = helper.createDigest(digestAlgorithm); } else { throw e; } } return dig; } catch (NoSuchProviderException e) { throw new GeneralSecurityException(e.toString()); } catch (NoSuchAlgorithmException e) { throw new GeneralSecurityException(e.toString()); } } Signature createSignature(AlgorithmIdentifier sigAlgId) throws GeneralSecurityException { try { Signature sig; try { sig = helper.createSignature(getSignatureName(sigAlgId)); } catch (NoSuchAlgorithmException e) { // // try an alternate // if (oids.get(sigAlgId.getAlgorithm()) != null) { String signatureAlgorithm = (String)oids.get(sigAlgId.getAlgorithm()); sig = helper.createSignature(signatureAlgorithm); } else { throw e; } } return sig; } catch (NoSuchProviderException e) { throw new GeneralSecurityException(e.toString()); } catch (NoSuchAlgorithmException e) { throw new GeneralSecurityException(e.toString()); } } public Signature createRawSignature(AlgorithmIdentifier algorithm) { Signature sig; try { String algName = getSignatureName(algorithm); algName = "NONE" + algName.substring(algName.indexOf("WITH")); sig = helper.createSignature(algName); // RFC 4056 // When the id-RSASSA-PSS algorithm identifier is used for a signature, // the AlgorithmIdentifier parameters field MUST contain RSASSA-PSS-params. /* Can;t do this pre-jdk1.4 if (algorithm.getAlgorithm().equals(PKCSObjectIdentifiers.id_RSASSA_PSS)) { AlgorithmParameters params = helper.createAlgorithmParameters(algName); params.init(algorithm.getParameters().toASN1Primitive().getEncoded(), "ASN.1"); PSSParameterSpec spec = (PSSParameterSpec)params.getParameterSpec(PSSParameterSpec.class); sig.setParameter(spec); } */ } catch (Exception e) { return null; } return sig; } private static String getSignatureName( AlgorithmIdentifier sigAlgId) { ASN1Encodable params = sigAlgId.getParameters(); if (params != null && !DERNull.INSTANCE.equals(params)) { if (sigAlgId.getAlgorithm().equals(PKCSObjectIdentifiers.id_RSASSA_PSS)) { RSASSAPSSparams rsaParams = RSASSAPSSparams.getInstance(params); return getDigestAlgName(rsaParams.getHashAlgorithm().getAlgorithm()) + "WITHRSAANDMGF1"; } } if (oids.containsKey(sigAlgId.getAlgorithm())) { return (String)oids.get(sigAlgId.getAlgorithm()); } return sigAlgId.getAlgorithm().getId(); } private static String getDigestAlgName( ASN1ObjectIdentifier digestAlgOID) { if (PKCSObjectIdentifiers.md5.equals(digestAlgOID)) { return "MD5"; } else if (OIWObjectIdentifiers.idSHA1.equals(digestAlgOID)) { return "SHA1"; } else if (NISTObjectIdentifiers.id_sha224.equals(digestAlgOID)) { return "SHA224"; } else if (NISTObjectIdentifiers.id_sha256.equals(digestAlgOID)) { return "SHA256"; } else if (NISTObjectIdentifiers.id_sha384.equals(digestAlgOID)) { return "SHA384"; } else if (NISTObjectIdentifiers.id_sha512.equals(digestAlgOID)) { return "SHA512"; } else if (TeleTrusTObjectIdentifiers.ripemd128.equals(digestAlgOID)) { return "RIPEMD128"; } else if (TeleTrusTObjectIdentifiers.ripemd160.equals(digestAlgOID)) { return "RIPEMD160"; } else if (TeleTrusTObjectIdentifiers.ripemd256.equals(digestAlgOID)) { return "RIPEMD256"; } else if (CryptoProObjectIdentifiers.gostR3411.equals(digestAlgOID)) { return "GOST3411"; } else { return digestAlgOID.getId(); } } public X509Certificate convertCertificate(X509CertificateHolder certHolder) throws CertificateException { try { CertificateFactory certFact = helper.createCertificateFactory("X.509"); return (X509Certificate)certFact.generateCertificate(new ByteArrayInputStream(certHolder.getEncoded())); } catch (IOException e) { throw new OpCertificateException("cannot get encoded form of certificate: " + e.getMessage(), e); } catch (NoSuchAlgorithmException e) { throw new OpCertificateException("cannot create certificate factory: " + e.getMessage(), e); } catch (NoSuchProviderException e) { throw new OpCertificateException("cannot find factory provider: " + e.getMessage(), e); } } // TODO: put somewhere public so cause easily accessed private static class OpCertificateException extends CertificateException { private Throwable cause; public OpCertificateException(String msg, Throwable cause) { super(msg); this.cause = cause; } public Throwable getCause() { return cause; } } String getKeyAlgorithmName(ASN1ObjectIdentifier oid) { String name = (String)symmetricKeyAlgNames.get(oid); if (name != null) { return name; } return oid.getId(); } } bouncycastle-1.49.orig/jdk1.1/org/bouncycastle/operator/jcajce/JcaContentSignerBuilder.java0000644000175000017500000001131111731467174031337 0ustar ebourgebourgpackage org.bouncycastle.operator.jcajce; import java.io.IOException; import java.io.OutputStream; import java.security.GeneralSecurityException; import java.security.InvalidKeyException; import java.security.PrivateKey; import java.security.Provider; import java.security.SecureRandom; import java.security.Signature; import java.security.SignatureException; import org.bouncycastle.asn1.x509.AlgorithmIdentifier; import org.bouncycastle.jcajce.JcaJceHelper; import org.bouncycastle.jcajce.DefaultJcaJceHelper; import org.bouncycastle.jcajce.NamedJcaJceHelper; import org.bouncycastle.jcajce.ProviderJcaJceHelper; import org.bouncycastle.operator.ContentSigner; import org.bouncycastle.operator.DefaultSignatureAlgorithmIdentifierFinder; import org.bouncycastle.operator.OperatorCreationException; import org.bouncycastle.operator.OperatorStreamException; import org.bouncycastle.operator.RuntimeOperatorException; public class JcaContentSignerBuilder { private OperatorHelper helper = new OperatorHelper(new DefaultJcaJceHelper()); private SecureRandom random; private String signatureAlgorithm; private AlgorithmIdentifier sigAlgId; public JcaContentSignerBuilder(String signatureAlgorithm) { this.signatureAlgorithm = signatureAlgorithm; this.sigAlgId = new DefaultSignatureAlgorithmIdentifierFinder().find(signatureAlgorithm); } public JcaContentSignerBuilder setProvider(Provider provider) { this.helper = new OperatorHelper(new ProviderJcaJceHelper(provider)); return this; } public JcaContentSignerBuilder setProvider(String providerName) { this.helper = new OperatorHelper(new NamedJcaJceHelper(providerName)); return this; } public JcaContentSignerBuilder setSecureRandom(SecureRandom random) { this.random = random; return this; } public ContentSigner build(PrivateKey privateKey) throws OperatorCreationException { try { final Signature sig = helper.createSignature(sigAlgId); if (random != null) { sig.initSign(privateKey); } else { sig.initSign(privateKey); } return new ContentSigner() { private SignatureOutputStream stream = new SignatureOutputStream(sig); public AlgorithmIdentifier getAlgorithmIdentifier() { return sigAlgId; } public OutputStream getOutputStream() { return stream; } public byte[] getSignature() { try { return stream.getSignature(); } catch (SignatureException e) { throw new RuntimeOperatorException("exception obtaining signature: " + e.getMessage(), e); } } }; } catch (InvalidKeyException e) { throw new OperatorCreationException("cannot create signer: " + e.getMessage(), e); } catch (GeneralSecurityException e) { throw new OperatorCreationException("cannot create signer: " + e.getMessage(), e); } } private class SignatureOutputStream extends OutputStream { private Signature sig; SignatureOutputStream(Signature sig) { this.sig = sig; } public void write(byte[] bytes, int off, int len) throws IOException { try { sig.update(bytes, off, len); } catch (SignatureException e) { throw new OperatorStreamException("exception in content signer: " + e.getMessage(), e); } } public void write(byte[] bytes) throws IOException { try { sig.update(bytes); } catch (SignatureException e) { throw new OperatorStreamException("exception in content signer: " + e.getMessage(), e); } } public void write(int b) throws IOException { try { sig.update((byte)b); } catch (SignatureException e) { throw new OperatorStreamException("exception in content signer: " + e.getMessage(), e); } } byte[] getSignature() throws SignatureException { return sig.sign(); } } } bouncycastle-1.49.orig/jdk1.1/org/bouncycastle/jcajce/0000755000175000017500000000000012152033551022117 5ustar ebourgebourgbouncycastle-1.49.orig/jdk1.1/org/bouncycastle/jcajce/provider/0000755000175000017500000000000012152033551023751 5ustar ebourgebourgbouncycastle-1.49.orig/jdk1.1/org/bouncycastle/jcajce/provider/asymmetric/0000755000175000017500000000000012152033551026126 5ustar ebourgebourgbouncycastle-1.49.orig/jdk1.1/org/bouncycastle/jcajce/provider/asymmetric/util/0000755000175000017500000000000012152033551027103 5ustar ebourgebourgbouncycastle-1.49.orig/jdk1.1/org/bouncycastle/jcajce/provider/asymmetric/util/DSABase.java0000644000175000017500000000637211705627153031172 0ustar ebourgebourgpackage org.bouncycastle.jcajce.provider.asymmetric.util; import java.math.BigInteger; import java.security.InvalidKeyException; import java.security.PrivateKey; import java.security.SecureRandom; import java.security.Signature; import java.security.SignatureException; import java.security.spec.AlgorithmParameterSpec; import org.bouncycastle.asn1.pkcs.PKCSObjectIdentifiers; import org.bouncycastle.asn1.x509.X509ObjectIdentifiers; import org.bouncycastle.crypto.DSA; import org.bouncycastle.crypto.Digest; public abstract class DSABase extends Signature implements PKCSObjectIdentifiers, X509ObjectIdentifiers { protected Digest digest; protected DSA signer; protected DSAEncoder encoder; private SecureRandom appRandom; protected DSABase( String name, Digest digest, DSA signer, DSAEncoder encoder) { super(name); this.digest = digest; this.signer = signer; this.encoder = encoder; } protected void engineInitSign( PrivateKey privateKey) throws InvalidKeyException { doEngineInitSign(privateKey, appRandom); } protected void engineUpdate( byte b) throws SignatureException { digest.update(b); } protected void engineUpdate( byte[] b, int off, int len) throws SignatureException { digest.update(b, off, len); } protected byte[] engineSign() throws SignatureException { byte[] hash = new byte[digest.getDigestSize()]; digest.doFinal(hash, 0); try { BigInteger[] sig = signer.generateSignature(hash); return encoder.encode(sig[0], sig[1]); } catch (Exception e) { throw new SignatureException(e.toString()); } } protected boolean engineVerify( byte[] sigBytes) throws SignatureException { byte[] hash = new byte[digest.getDigestSize()]; digest.doFinal(hash, 0); BigInteger[] sig; try { sig = encoder.decode(sigBytes); } catch (Exception e) { throw new SignatureException("error decoding signature bytes."); } return signer.verifySignature(hash, sig[0], sig[1]); } protected void engineSetParameter( AlgorithmParameterSpec params) { throw new UnsupportedOperationException("engineSetParameter unsupported"); } /** * @deprecated replaced with */ protected void engineSetParameter( String param, Object value) { throw new UnsupportedOperationException("engineSetParameter unsupported"); } /** * @deprecated */ protected Object engineGetParameter( String param) { throw new UnsupportedOperationException("engineSetParameter unsupported"); } protected abstract void doEngineInitSign(PrivateKey privateKey, SecureRandom random) throws InvalidKeyException; } bouncycastle-1.49.orig/jdk1.1/org/bouncycastle/jcajce/provider/asymmetric/ecgost/0000755000175000017500000000000012152033551027412 5ustar ebourgebourgbouncycastle-1.49.orig/jdk1.1/org/bouncycastle/jcajce/provider/asymmetric/ecgost/SignatureSpi.java0000644000175000017500000001411512110037231032665 0ustar ebourgebourgpackage org.bouncycastle.jcajce.provider.asymmetric.ecgost; import java.math.BigInteger; import java.security.InvalidKeyException; import java.security.PrivateKey; import java.security.PublicKey; import java.security.SecureRandom; import java.security.SignatureException; import java.security.spec.AlgorithmParameterSpec; import org.bouncycastle.asn1.pkcs.PKCSObjectIdentifiers; import org.bouncycastle.asn1.x509.SubjectPublicKeyInfo; import org.bouncycastle.asn1.x509.X509ObjectIdentifiers; import org.bouncycastle.crypto.CipherParameters; import org.bouncycastle.crypto.DSA; import org.bouncycastle.crypto.Digest; import org.bouncycastle.crypto.digests.GOST3411Digest; import org.bouncycastle.crypto.params.ParametersWithRandom; import org.bouncycastle.crypto.signers.ECGOST3410Signer; import org.bouncycastle.jcajce.provider.asymmetric.util.ECUtil; import org.bouncycastle.jce.interfaces.ECKey; import org.bouncycastle.jce.interfaces.ECPublicKey; import org.bouncycastle.jce.interfaces.GOST3410Key; import org.bouncycastle.jce.provider.BouncyCastleProvider; import org.bouncycastle.jcajce.provider.asymmetric.util.GOST3410Util; public class SignatureSpi extends java.security.Signature implements PKCSObjectIdentifiers, X509ObjectIdentifiers { private Digest digest; private DSA signer; private SecureRandom appRandom; public SignatureSpi() { super("ECGOST3410"); this.digest = new GOST3411Digest(); this.signer = new ECGOST3410Signer(); } protected void engineInitVerify( PublicKey publicKey) throws InvalidKeyException { CipherParameters param; if (publicKey instanceof ECPublicKey) { param = ECUtil.generatePublicKeyParameter(publicKey); } else if (publicKey instanceof GOST3410Key) { param = GOST3410Util.generatePublicKeyParameter(publicKey); } else { try { byte[] bytes = publicKey.getEncoded(); publicKey = BouncyCastleProvider.getPublicKey(SubjectPublicKeyInfo.getInstance(bytes)); if (publicKey instanceof ECPublicKey) { param = ECUtil.generatePublicKeyParameter(publicKey); } else { throw new InvalidKeyException("can't recognise key type in DSA based signer"); } } catch (Exception e) { throw new InvalidKeyException("can't recognise key type in DSA based signer"); } } digest.reset(); signer.init(false, param); } protected void engineInitSign( PrivateKey privateKey) throws InvalidKeyException { CipherParameters param; if (privateKey instanceof ECKey) { param = ECUtil.generatePrivateKeyParameter(privateKey); } else { param = GOST3410Util.generatePrivateKeyParameter(privateKey); } digest.reset(); if (appRandom != null) { signer.init(true, new ParametersWithRandom(param, appRandom)); } else { signer.init(true, param); } } protected void engineUpdate( byte b) throws SignatureException { digest.update(b); } protected void engineUpdate( byte[] b, int off, int len) throws SignatureException { digest.update(b, off, len); } protected byte[] engineSign() throws SignatureException { byte[] hash = new byte[digest.getDigestSize()]; digest.doFinal(hash, 0); try { byte[] sigBytes = new byte[64]; BigInteger[] sig = signer.generateSignature(hash); byte[] r = sig[0].toByteArray(); byte[] s = sig[1].toByteArray(); if (s[0] != 0) { System.arraycopy(s, 0, sigBytes, 32 - s.length, s.length); } else { System.arraycopy(s, 1, sigBytes, 32 - (s.length - 1), s.length - 1); } if (r[0] != 0) { System.arraycopy(r, 0, sigBytes, 64 - r.length, r.length); } else { System.arraycopy(r, 1, sigBytes, 64 - (r.length - 1), r.length - 1); } return sigBytes; } catch (Exception e) { throw new SignatureException(e.toString()); } } protected boolean engineVerify( byte[] sigBytes) throws SignatureException { byte[] hash = new byte[digest.getDigestSize()]; digest.doFinal(hash, 0); BigInteger[] sig; try { byte[] r = new byte[32]; byte[] s = new byte[32]; System.arraycopy(sigBytes, 0, s, 0, 32); System.arraycopy(sigBytes, 32, r, 0, 32); sig = new BigInteger[2]; sig[0] = new BigInteger(1, r); sig[1] = new BigInteger(1, s); } catch (Exception e) { throw new SignatureException("error decoding signature bytes."); } return signer.verifySignature(hash, sig[0], sig[1]); } protected void engineSetParameter( AlgorithmParameterSpec params) { throw new UnsupportedOperationException("engineSetParameter unsupported"); } /** * @deprecated replaced with */ protected void engineSetParameter( String param, Object value) { throw new UnsupportedOperationException("engineSetParameter unsupported"); } /** * @deprecated */ protected Object engineGetParameter( String param) { throw new UnsupportedOperationException("engineSetParameter unsupported"); } } bouncycastle-1.49.orig/jdk1.1/org/bouncycastle/jcajce/provider/asymmetric/rsa/0000755000175000017500000000000012152033551026713 5ustar ebourgebourg././@LongLink0000000000000000000000000000014600000000000011566 Lustar rootrootbouncycastle-1.49.orig/jdk1.1/org/bouncycastle/jcajce/provider/asymmetric/rsa/DigestSignatureSpi.javabouncycastle-1.49.orig/jdk1.1/org/bouncycastle/jcajce/provider/asymmetric/rsa/DigestSignatureSpi.jav0000644000175000017500000002354611705627153033216 0ustar ebourgebourgpackage org.bouncycastle.jcajce.provider.asymmetric.rsa; import java.io.IOException; import java.security.AlgorithmParameters; import java.security.InvalidKeyException; import java.security.PrivateKey; import java.security.PublicKey; import java.security.SignatureException; import java.security.Signature; import java.security.interfaces.RSAPrivateKey; import java.security.interfaces.RSAPublicKey; import java.security.spec.AlgorithmParameterSpec; import org.bouncycastle.asn1.ASN1Encoding; import org.bouncycastle.asn1.ASN1ObjectIdentifier; import org.bouncycastle.asn1.DERNull; import org.bouncycastle.asn1.nist.NISTObjectIdentifiers; import org.bouncycastle.asn1.oiw.OIWObjectIdentifiers; import org.bouncycastle.asn1.pkcs.PKCSObjectIdentifiers; import org.bouncycastle.asn1.teletrust.TeleTrusTObjectIdentifiers; import org.bouncycastle.asn1.x509.AlgorithmIdentifier; import org.bouncycastle.asn1.x509.DigestInfo; import org.bouncycastle.crypto.AsymmetricBlockCipher; import org.bouncycastle.crypto.CipherParameters; import org.bouncycastle.crypto.Digest; import org.bouncycastle.crypto.digests.MD2Digest; import org.bouncycastle.crypto.digests.MD4Digest; import org.bouncycastle.crypto.digests.MD5Digest; import org.bouncycastle.crypto.digests.NullDigest; import org.bouncycastle.crypto.digests.RIPEMD128Digest; import org.bouncycastle.crypto.digests.RIPEMD160Digest; import org.bouncycastle.crypto.digests.RIPEMD256Digest; import org.bouncycastle.crypto.digests.SHA1Digest; import org.bouncycastle.crypto.digests.SHA224Digest; import org.bouncycastle.crypto.digests.SHA256Digest; import org.bouncycastle.crypto.digests.SHA384Digest; import org.bouncycastle.crypto.digests.SHA512Digest; import org.bouncycastle.crypto.encodings.PKCS1Encoding; import org.bouncycastle.crypto.engines.RSABlindedEngine; public class DigestSignatureSpi extends Signature { private Digest digest; private AsymmetricBlockCipher cipher; private AlgorithmIdentifier algId; // care - this constructor is actually used by outside organisations protected DigestSignatureSpi( Digest digest, AsymmetricBlockCipher cipher) { super(digest.getAlgorithmName() + "withRSA"); this.digest = digest; this.cipher = cipher; this.algId = null; } // care - this constructor is actually used by outside organisations protected DigestSignatureSpi( ASN1ObjectIdentifier objId, Digest digest, AsymmetricBlockCipher cipher) { super(digest.getAlgorithmName() + "withRSA"); this.digest = digest; this.cipher = cipher; this.algId = new AlgorithmIdentifier(objId, DERNull.INSTANCE); } protected void engineInitVerify( PublicKey publicKey) throws InvalidKeyException { if (!(publicKey instanceof RSAPublicKey)) { throw new InvalidKeyException("Supplied key (" + getType(publicKey) + ") is not a RSAPublicKey instance"); } CipherParameters param = RSAUtil.generatePublicKeyParameter((RSAPublicKey)publicKey); digest.reset(); cipher.init(false, param); } protected void engineInitSign( PrivateKey privateKey) throws InvalidKeyException { if (!(privateKey instanceof RSAPrivateKey)) { throw new InvalidKeyException("Supplied key (" + getType(privateKey) + ") is not a RSAPrivateKey instance"); } CipherParameters param = RSAUtil.generatePrivateKeyParameter((RSAPrivateKey)privateKey); digest.reset(); cipher.init(true, param); } private String getType( Object o) { if (o == null) { return null; } return o.getClass().getName(); } protected void engineUpdate( byte b) throws SignatureException { digest.update(b); } protected void engineUpdate( byte[] b, int off, int len) throws SignatureException { digest.update(b, off, len); } protected byte[] engineSign() throws SignatureException { byte[] hash = new byte[digest.getDigestSize()]; digest.doFinal(hash, 0); try { byte[] bytes = derEncode(hash); return cipher.processBlock(bytes, 0, bytes.length); } catch (ArrayIndexOutOfBoundsException e) { throw new SignatureException("key too small for signature type"); } catch (Exception e) { throw new SignatureException(e.toString()); } } protected boolean engineVerify( byte[] sigBytes) throws SignatureException { byte[] hash = new byte[digest.getDigestSize()]; digest.doFinal(hash, 0); byte[] sig; byte[] expected; try { sig = cipher.processBlock(sigBytes, 0, sigBytes.length); expected = derEncode(hash); } catch (Exception e) { return false; } if (sig.length == expected.length) { for (int i = 0; i < sig.length; i++) { if (sig[i] != expected[i]) { return false; } } } else if (sig.length == expected.length - 2) // NULL left out { int sigOffset = sig.length - hash.length - 2; int expectedOffset = expected.length - hash.length - 2; expected[1] -= 2; // adjust lengths expected[3] -= 2; for (int i = 0; i < hash.length; i++) { if (sig[sigOffset + i] != expected[expectedOffset + i]) // check hash { return false; } } for (int i = 0; i < sigOffset; i++) { if (sig[i] != expected[i]) // check header less NULL { return false; } } } else { return false; } return true; } protected void engineSetParameter( AlgorithmParameterSpec params) { throw new UnsupportedOperationException("engineSetParameter unsupported"); } /** * @deprecated replaced with */ protected void engineSetParameter( String param, Object value) { throw new UnsupportedOperationException("engineSetParameter unsupported"); } /** * @deprecated */ protected Object engineGetParameter( String param) { return null; } protected AlgorithmParameters engineGetParameters() { return null; } private byte[] derEncode( byte[] hash) throws IOException { if (algId == null) { // For raw RSA, the DigestInfo must be prepared externally return hash; } DigestInfo dInfo = new DigestInfo(algId, hash); return dInfo.getEncoded(ASN1Encoding.DER); } static public class SHA1 extends DigestSignatureSpi { public SHA1() { super(OIWObjectIdentifiers.idSHA1, new SHA1Digest(), new PKCS1Encoding(new RSABlindedEngine())); } } static public class SHA224 extends DigestSignatureSpi { public SHA224() { super(NISTObjectIdentifiers.id_sha224, new SHA224Digest(), new PKCS1Encoding(new RSABlindedEngine())); } } static public class SHA256 extends DigestSignatureSpi { public SHA256() { super(NISTObjectIdentifiers.id_sha256, new SHA256Digest(), new PKCS1Encoding(new RSABlindedEngine())); } } static public class SHA384 extends DigestSignatureSpi { public SHA384() { super(NISTObjectIdentifiers.id_sha384, new SHA384Digest(), new PKCS1Encoding(new RSABlindedEngine())); } } static public class SHA512 extends DigestSignatureSpi { public SHA512() { super(NISTObjectIdentifiers.id_sha512, new SHA512Digest(), new PKCS1Encoding(new RSABlindedEngine())); } } static public class MD2 extends DigestSignatureSpi { public MD2() { super(PKCSObjectIdentifiers.md2, new MD2Digest(), new PKCS1Encoding(new RSABlindedEngine())); } } static public class MD4 extends DigestSignatureSpi { public MD4() { super(PKCSObjectIdentifiers.md4, new MD4Digest(), new PKCS1Encoding(new RSABlindedEngine())); } } static public class MD5 extends DigestSignatureSpi { public MD5() { super(PKCSObjectIdentifiers.md5, new MD5Digest(), new PKCS1Encoding(new RSABlindedEngine())); } } static public class RIPEMD160 extends DigestSignatureSpi { public RIPEMD160() { super(TeleTrusTObjectIdentifiers.ripemd160, new RIPEMD160Digest(), new PKCS1Encoding(new RSABlindedEngine())); } } static public class RIPEMD128 extends DigestSignatureSpi { public RIPEMD128() { super(TeleTrusTObjectIdentifiers.ripemd128, new RIPEMD128Digest(), new PKCS1Encoding(new RSABlindedEngine())); } } static public class RIPEMD256 extends DigestSignatureSpi { public RIPEMD256() { super(TeleTrusTObjectIdentifiers.ripemd256, new RIPEMD256Digest(), new PKCS1Encoding(new RSABlindedEngine())); } } static public class noneRSA extends DigestSignatureSpi { public noneRSA() { super(new NullDigest(), new PKCS1Encoding(new RSABlindedEngine())); } } } bouncycastle-1.49.orig/jdk1.1/org/bouncycastle/jcajce/provider/asymmetric/rsa/ISOSignatureSpi.java0000644000175000017500000000717411705627153032571 0ustar ebourgebourgpackage org.bouncycastle.jcajce.provider.asymmetric.rsa; import java.security.InvalidKeyException; import java.security.PrivateKey; import java.security.PublicKey; import java.security.SignatureException; import java.security.Signature; import java.security.interfaces.RSAPrivateKey; import java.security.interfaces.RSAPublicKey; import java.security.spec.AlgorithmParameterSpec; import org.bouncycastle.crypto.AsymmetricBlockCipher; import org.bouncycastle.crypto.CipherParameters; import org.bouncycastle.crypto.Digest; import org.bouncycastle.crypto.digests.MD5Digest; import org.bouncycastle.crypto.digests.RIPEMD160Digest; import org.bouncycastle.crypto.digests.SHA1Digest; import org.bouncycastle.crypto.engines.RSABlindedEngine; import org.bouncycastle.crypto.signers.ISO9796d2Signer; public class ISOSignatureSpi extends Signature { private ISO9796d2Signer signer; protected ISOSignatureSpi( Digest digest, AsymmetricBlockCipher cipher) { super(digest.getAlgorithmName() + "withRSA/ISO9796-2"); signer = new ISO9796d2Signer(cipher, digest, true); } protected void engineInitVerify( PublicKey publicKey) throws InvalidKeyException { CipherParameters param = RSAUtil.generatePublicKeyParameter((RSAPublicKey)publicKey); signer.init(false, param); } protected void engineInitSign( PrivateKey privateKey) throws InvalidKeyException { CipherParameters param = RSAUtil.generatePrivateKeyParameter((RSAPrivateKey)privateKey); signer.init(true, param); } protected void engineUpdate( byte b) throws SignatureException { signer.update(b); } protected void engineUpdate( byte[] b, int off, int len) throws SignatureException { signer.update(b, off, len); } protected byte[] engineSign() throws SignatureException { try { byte[] sig = signer.generateSignature(); return sig; } catch (Exception e) { throw new SignatureException(e.toString()); } } protected boolean engineVerify( byte[] sigBytes) throws SignatureException { boolean yes = signer.verifySignature(sigBytes); return yes; } protected void engineSetParameter( AlgorithmParameterSpec params) { throw new UnsupportedOperationException("engineSetParameter unsupported"); } /** * @deprecated replaced with */ protected void engineSetParameter( String param, Object value) { throw new UnsupportedOperationException("engineSetParameter unsupported"); } /** * @deprecated */ protected Object engineGetParameter( String param) { throw new UnsupportedOperationException("engineSetParameter unsupported"); } static public class SHA1WithRSAEncryption extends ISOSignatureSpi { public SHA1WithRSAEncryption() { super(new SHA1Digest(), new RSABlindedEngine()); } } static public class MD5WithRSAEncryption extends ISOSignatureSpi { public MD5WithRSAEncryption() { super(new MD5Digest(), new RSABlindedEngine()); } } static public class RIPEMD160WithRSAEncryption extends ISOSignatureSpi { public RIPEMD160WithRSAEncryption() { super(new RIPEMD160Digest(), new RSABlindedEngine()); } } } bouncycastle-1.49.orig/jdk1.1/org/bouncycastle/jcajce/provider/asymmetric/gost/0000755000175000017500000000000012152033551027102 5ustar ebourgebourgbouncycastle-1.49.orig/jdk1.1/org/bouncycastle/jcajce/provider/asymmetric/gost/SignatureSpi.java0000644000175000017500000001442512110037231032361 0ustar ebourgebourgpackage org.bouncycastle.jcajce.provider.asymmetric.gost; import java.math.BigInteger; import java.security.InvalidKeyException; import java.security.PrivateKey; import java.security.PublicKey; import java.security.SecureRandom; import java.security.SignatureException; import java.security.spec.AlgorithmParameterSpec; import org.bouncycastle.asn1.pkcs.PKCSObjectIdentifiers; import org.bouncycastle.asn1.x509.SubjectPublicKeyInfo; import org.bouncycastle.asn1.x509.X509ObjectIdentifiers; import org.bouncycastle.crypto.CipherParameters; import org.bouncycastle.crypto.DSA; import org.bouncycastle.crypto.Digest; import org.bouncycastle.crypto.digests.GOST3411Digest; import org.bouncycastle.crypto.params.ParametersWithRandom; import org.bouncycastle.crypto.signers.GOST3410Signer; import org.bouncycastle.jcajce.provider.asymmetric.util.ECUtil; import org.bouncycastle.jce.interfaces.ECKey; import org.bouncycastle.jce.interfaces.ECPublicKey; import org.bouncycastle.jce.interfaces.GOST3410Key; import org.bouncycastle.jce.provider.BouncyCastleProvider; import org.bouncycastle.jcajce.provider.asymmetric.util.GOST3410Util; public class SignatureSpi extends java.security.Signature implements PKCSObjectIdentifiers, X509ObjectIdentifiers { private Digest digest; private DSA signer; private SecureRandom random; public SignatureSpi() { super("GOST3410"); this.digest = new GOST3411Digest(); this.signer = new GOST3410Signer(); } protected void engineInitVerify( PublicKey publicKey) throws InvalidKeyException { CipherParameters param; if (publicKey instanceof ECPublicKey) { param = ECUtil.generatePublicKeyParameter(publicKey); } else if (publicKey instanceof GOST3410Key) { param = GOST3410Util.generatePublicKeyParameter(publicKey); } else { try { byte[] bytes = publicKey.getEncoded(); publicKey = BouncyCastleProvider.getPublicKey(SubjectPublicKeyInfo.getInstance(bytes)); if (publicKey instanceof ECPublicKey) { param = ECUtil.generatePublicKeyParameter(publicKey); } else { throw new InvalidKeyException("can't recognise key type in DSA based signer"); } } catch (Exception e) { throw new InvalidKeyException("can't recognise key type in DSA based signer"); } } digest.reset(); signer.init(false, param); } protected void engineInitSign( PrivateKey privateKey, SecureRandom random) throws InvalidKeyException { this.random = random; engineInitSign(privateKey); } protected void engineInitSign( PrivateKey privateKey) throws InvalidKeyException { CipherParameters param; if (privateKey instanceof ECKey) { param = ECUtil.generatePrivateKeyParameter(privateKey); } else { param = GOST3410Util.generatePrivateKeyParameter(privateKey); } digest.reset(); if (random != null) { signer.init(true, new ParametersWithRandom(param, random)); } else { signer.init(true, param); } } protected void engineUpdate( byte b) throws SignatureException { digest.update(b); } protected void engineUpdate( byte[] b, int off, int len) throws SignatureException { digest.update(b, off, len); } protected byte[] engineSign() throws SignatureException { byte[] hash = new byte[digest.getDigestSize()]; digest.doFinal(hash, 0); try { byte[] sigBytes = new byte[64]; BigInteger[] sig = signer.generateSignature(hash); byte[] r = sig[0].toByteArray(); byte[] s = sig[1].toByteArray(); if (s[0] != 0) { System.arraycopy(s, 0, sigBytes, 32 - s.length, s.length); } else { System.arraycopy(s, 1, sigBytes, 32 - (s.length - 1), s.length - 1); } if (r[0] != 0) { System.arraycopy(r, 0, sigBytes, 64 - r.length, r.length); } else { System.arraycopy(r, 1, sigBytes, 64 - (r.length - 1), r.length - 1); } return sigBytes; } catch (Exception e) { throw new SignatureException(e.toString()); } } protected boolean engineVerify( byte[] sigBytes) throws SignatureException { byte[] hash = new byte[digest.getDigestSize()]; digest.doFinal(hash, 0); BigInteger[] sig; try { byte[] r = new byte[32]; byte[] s = new byte[32]; System.arraycopy(sigBytes, 0, s, 0, 32); System.arraycopy(sigBytes, 32, r, 0, 32); sig = new BigInteger[2]; sig[0] = new BigInteger(1, r); sig[1] = new BigInteger(1, s); } catch (Exception e) { throw new SignatureException("error decoding signature bytes."); } return signer.verifySignature(hash, sig[0], sig[1]); } protected void engineSetParameter( AlgorithmParameterSpec params) { throw new UnsupportedOperationException("engineSetParameter unsupported"); } /** * @deprecated replaced with */ protected void engineSetParameter( String param, Object value) { throw new UnsupportedOperationException("engineSetParameter unsupported"); } /** * @deprecated */ protected Object engineGetParameter( String param) { throw new UnsupportedOperationException("engineSetParameter unsupported"); } } bouncycastle-1.49.orig/jdk1.1/org/bouncycastle/jcajce/provider/asymmetric/x509/0000755000175000017500000000000012152033551026633 5ustar ebourgebourg././@LongLink0000000000000000000000000000014700000000000011567 Lustar rootrootbouncycastle-1.49.orig/jdk1.1/org/bouncycastle/jcajce/provider/asymmetric/x509/CertificateFactory.javabouncycastle-1.49.orig/jdk1.1/org/bouncycastle/jcajce/provider/asymmetric/x509/CertificateFactory.ja0000644000175000017500000002545212105031243032723 0ustar ebourgebourgpackage org.bouncycastle.jcajce.provider.asymmetric.x509; import java.io.IOException; import java.io.InputStream; import java.io.PushbackInputStream; import java.security.cert.CRL; import java.security.cert.CRLException; import java.security.cert.CertPath; import java.security.cert.CertificateException; import java.security.cert.CertificateFactorySpi; import java.security.cert.CertificateParsingException; import java.security.cert.X509Certificate; import java.util.ArrayList; import java.util.Collection; import java.util.Iterator; import java.util.List; import org.bouncycastle.asn1.ASN1InputStream; import org.bouncycastle.asn1.ASN1ObjectIdentifier; import org.bouncycastle.asn1.ASN1Sequence; import org.bouncycastle.asn1.ASN1Set; import org.bouncycastle.asn1.ASN1TaggedObject; import org.bouncycastle.asn1.pkcs.PKCSObjectIdentifiers; import org.bouncycastle.asn1.pkcs.SignedData; import org.bouncycastle.asn1.x509.Certificate; import org.bouncycastle.asn1.x509.CertificateList; import org.bouncycastle.jce.provider.X509CRLObject; import org.bouncycastle.jce.provider.X509CertificateObject; /** * class for dealing with X509 certificates. *

    * At the moment this will deal with "-----BEGIN CERTIFICATE-----" to "-----END CERTIFICATE-----" * base 64 encoded certs, as well as the BER binaries of certificates and some classes of PKCS#7 * objects. */ public class CertificateFactory extends CertificateFactorySpi { private static final PEMUtil PEM_CERT_PARSER = new PEMUtil("CERTIFICATE"); private static final PEMUtil PEM_CRL_PARSER = new PEMUtil("CRL"); private ASN1Set sData = null; private int sDataObjectCount = 0; private InputStream currentStream = null; private ASN1Set sCrlData = null; private int sCrlDataObjectCount = 0; private InputStream currentCrlStream = null; private java.security.cert.Certificate readDERCertificate( ASN1InputStream dIn) throws IOException, CertificateParsingException { ASN1Sequence seq = (ASN1Sequence)dIn.readObject(); if (seq.size() > 1 && seq.getObjectAt(0) instanceof ASN1ObjectIdentifier) { if (seq.getObjectAt(0).equals(PKCSObjectIdentifiers.signedData)) { sData = SignedData.getInstance(ASN1Sequence.getInstance( (ASN1TaggedObject)seq.getObjectAt(1), true)).getCertificates(); return getCertificate(); } } return new X509CertificateObject( Certificate.getInstance(seq)); } private java.security.cert.Certificate getCertificate() throws CertificateParsingException { if (sData != null) { while (sDataObjectCount < sData.size()) { Object obj = sData.getObjectAt(sDataObjectCount++); if (obj instanceof ASN1Sequence) { return new X509CertificateObject( Certificate.getInstance(obj)); } } } return null; } private java.security.cert.Certificate readPEMCertificate( InputStream in) throws IOException, CertificateParsingException { ASN1Sequence seq = PEM_CERT_PARSER.readPEMObject(in); if (seq != null) { return new X509CertificateObject( Certificate.getInstance(seq)); } return null; } protected CRL createCRL(CertificateList c) throws CRLException { return new X509CRLObject(c); } private CRL readPEMCRL( InputStream in) throws IOException, CRLException { ASN1Sequence seq = PEM_CRL_PARSER.readPEMObject(in); if (seq != null) { return createCRL( CertificateList.getInstance(seq)); } return null; } private CRL readDERCRL( ASN1InputStream aIn) throws IOException, CRLException { ASN1Sequence seq = (ASN1Sequence)aIn.readObject(); if (seq.size() > 1 && seq.getObjectAt(0) instanceof ASN1ObjectIdentifier) { if (seq.getObjectAt(0).equals(PKCSObjectIdentifiers.signedData)) { sCrlData = SignedData.getInstance(ASN1Sequence.getInstance( (ASN1TaggedObject)seq.getObjectAt(1), true)).getCRLs(); return getCRL(); } } return createCRL( CertificateList.getInstance(seq)); } private CRL getCRL() throws CRLException { if (sCrlData == null || sCrlDataObjectCount >= sCrlData.size()) { return null; } return createCRL( CertificateList.getInstance( sCrlData.getObjectAt(sCrlDataObjectCount++))); } /** * Generates a certificate object and initializes it with the data * read from the input stream inStream. */ public java.security.cert.Certificate engineGenerateCertificate( InputStream in) throws CertificateException { if (currentStream == null) { currentStream = in; sData = null; sDataObjectCount = 0; } else if (currentStream != in) // reset if input stream has changed { currentStream = in; sData = null; sDataObjectCount = 0; } try { if (sData != null) { if (sDataObjectCount != sData.size()) { return getCertificate(); } else { sData = null; sDataObjectCount = 0; return null; } } PushbackInputStream pis = new PushbackInputStream(in); int tag = pis.read(); if (tag == -1) { return null; } pis.unread(tag); if (tag != 0x30) // assume ascii PEM encoded. { return readPEMCertificate(pis); } else { return readDERCertificate(new ASN1InputStream(pis)); } } catch (Exception e) { throw new ExCertificateException(e); } } /** * Returns a (possibly empty) collection view of the certificates * read from the given input stream inStream. */ public Collection engineGenerateCertificates( InputStream inStream) throws CertificateException { java.security.cert.Certificate cert; List certs = new ArrayList(); while ((cert = engineGenerateCertificate(inStream)) != null) { certs.add(cert); } return certs; } /** * Generates a certificate revocation list (CRL) object and initializes * it with the data read from the input stream inStream. */ public CRL engineGenerateCRL( InputStream inStream) throws CRLException { if (currentCrlStream == null) { currentCrlStream = inStream; sCrlData = null; sCrlDataObjectCount = 0; } else if (currentCrlStream != inStream) // reset if input stream has changed { currentCrlStream = inStream; sCrlData = null; sCrlDataObjectCount = 0; } try { if (sCrlData != null) { if (sCrlDataObjectCount != sCrlData.size()) { return getCRL(); } else { sCrlData = null; sCrlDataObjectCount = 0; return null; } } PushbackInputStream pis = new PushbackInputStream(inStream); int tag = pis.read(); if (tag == -1) { return null; } pis.unread(tag); if (tag != 0x30) // assume ascii PEM encoded. { return readPEMCRL(pis); } else { // lazy evaluate to help processing of large CRLs return readDERCRL(new ASN1InputStream(pis, true)); } } catch (CRLException e) { throw e; } catch (Exception e) { throw new CRLException(e.toString()); } } /** * Returns a (possibly empty) collection view of the CRLs read from * the given input stream inStream. * * The inStream may contain a sequence of DER-encoded CRLs, or * a PKCS#7 CRL set. This is a PKCS#7 SignedData object, with the * only signficant field being crls. In particular the signature * and the contents are ignored. */ public Collection engineGenerateCRLs( InputStream inStream) throws CRLException { CRL crl; List crls = new ArrayList(); while ((crl = engineGenerateCRL(inStream)) != null) { crls.add(crl); } return crls; } public Iterator engineGetCertPathEncodings() { return null; // TODO: PKIXCertPath.certPathEncodings.iterator(); } public CertPath engineGenerateCertPath( InputStream inStream) throws CertificateException { return engineGenerateCertPath(inStream, "PkiPath"); } public CertPath engineGenerateCertPath( InputStream inStream, String encoding) throws CertificateException { return new PKIXCertPath(inStream, encoding); } public CertPath engineGenerateCertPath( List certificates) throws CertificateException { Iterator iter = certificates.iterator(); Object obj; while (iter.hasNext()) { obj = iter.next(); if (obj != null) { if (!(obj instanceof X509Certificate)) { throw new CertificateException("list contains non X509Certificate object while creating CertPath\n" + obj.toString()); } } } return new PKIXCertPath(certificates); } private class ExCertificateException extends CertificateException { private Throwable cause; public ExCertificateException(Throwable cause) { this.cause = cause; } public ExCertificateException(String msg, Throwable cause) { super(msg); this.cause = cause; } public Throwable getCause() { return cause; } } } bouncycastle-1.49.orig/jdk1.1/org/bouncycastle/jcajce/provider/asymmetric/x509/SignatureUtil.java0000644000175000017500000000711511705627153032313 0ustar ebourgebourgpackage org.bouncycastle.jcajce.provider.asymmetric.x509; import java.io.IOException; import java.security.AlgorithmParameters; import java.security.GeneralSecurityException; import java.security.InvalidKeyException; import java.security.NoSuchAlgorithmException; import java.security.NoSuchProviderException; import java.security.Signature; import java.security.SignatureException; import org.bouncycastle.asn1.ASN1Encodable; import org.bouncycastle.asn1.ASN1Encoding; import org.bouncycastle.asn1.ASN1Null; import org.bouncycastle.asn1.ASN1ObjectIdentifier; import org.bouncycastle.asn1.ASN1Sequence; import org.bouncycastle.asn1.DERNull; import org.bouncycastle.asn1.cryptopro.CryptoProObjectIdentifiers; import org.bouncycastle.asn1.nist.NISTObjectIdentifiers; import org.bouncycastle.asn1.oiw.OIWObjectIdentifiers; import org.bouncycastle.asn1.pkcs.PKCSObjectIdentifiers; import org.bouncycastle.asn1.pkcs.RSASSAPSSparams; import org.bouncycastle.asn1.teletrust.TeleTrusTObjectIdentifiers; import org.bouncycastle.asn1.x509.AlgorithmIdentifier; import org.bouncycastle.asn1.x9.X9ObjectIdentifiers; class SignatureUtil { private static final ASN1Null derNull = new DERNull(); static String getSignatureName( AlgorithmIdentifier sigAlgId) { ASN1Encodable params = sigAlgId.getParameters(); if (params != null && !derNull.equals(params)) { if (sigAlgId.getAlgorithm().equals(PKCSObjectIdentifiers.id_RSASSA_PSS)) { RSASSAPSSparams rsaParams = RSASSAPSSparams.getInstance(params); return getDigestAlgName(rsaParams.getHashAlgorithm().getAlgorithm()) + "withRSAandMGF1"; } if (sigAlgId.getAlgorithm().equals(X9ObjectIdentifiers.ecdsa_with_SHA2)) { ASN1Sequence ecDsaParams = ASN1Sequence.getInstance(params); return getDigestAlgName((ASN1ObjectIdentifier)ecDsaParams.getObjectAt(0)) + "withECDSA"; } } return sigAlgId.getAlgorithm().getId(); } /** * Return the digest algorithm using one of the standard JCA string * representations rather the the algorithm identifier (if possible). */ private static String getDigestAlgName( ASN1ObjectIdentifier digestAlgOID) { if (PKCSObjectIdentifiers.md5.equals(digestAlgOID)) { return "MD5"; } else if (OIWObjectIdentifiers.idSHA1.equals(digestAlgOID)) { return "SHA1"; } else if (NISTObjectIdentifiers.id_sha224.equals(digestAlgOID)) { return "SHA224"; } else if (NISTObjectIdentifiers.id_sha256.equals(digestAlgOID)) { return "SHA256"; } else if (NISTObjectIdentifiers.id_sha384.equals(digestAlgOID)) { return "SHA384"; } else if (NISTObjectIdentifiers.id_sha512.equals(digestAlgOID)) { return "SHA512"; } else if (TeleTrusTObjectIdentifiers.ripemd128.equals(digestAlgOID)) { return "RIPEMD128"; } else if (TeleTrusTObjectIdentifiers.ripemd160.equals(digestAlgOID)) { return "RIPEMD160"; } else if (TeleTrusTObjectIdentifiers.ripemd256.equals(digestAlgOID)) { return "RIPEMD256"; } else if (CryptoProObjectIdentifiers.gostR3411.equals(digestAlgOID)) { return "GOST3411"; } else { return digestAlgOID.getId(); } } } bouncycastle-1.49.orig/jdk1.1/org/bouncycastle/jcajce/provider/asymmetric/x509/PKIXCertPath.java0000644000175000017500000002771111731467174031732 0ustar ebourgebourgpackage org.bouncycastle.jcajce.provider.asymmetric.x509; import java.io.BufferedInputStream; import java.io.ByteArrayInputStream; import java.io.ByteArrayOutputStream; import java.io.IOException; import java.io.InputStream; import java.io.OutputStreamWriter; import java.security.NoSuchProviderException; import java.security.cert.CertPath; import java.security.cert.Certificate; import java.security.cert.CertificateEncodingException; import java.security.cert.CertificateException; import java.security.cert.CertificateFactory; import java.security.cert.X509Certificate; import java.util.ArrayList; import java.util.Collections; import java.util.Enumeration; import java.util.Iterator; import java.util.List; import java.util.ListIterator; import org.bouncycastle.jce.X509Principal; import org.bouncycastle.jce.PrincipalUtil; import org.bouncycastle.asn1.ASN1Encodable; import org.bouncycastle.asn1.ASN1EncodableVector; import org.bouncycastle.asn1.ASN1Encoding; import org.bouncycastle.asn1.ASN1InputStream; import org.bouncycastle.asn1.ASN1Integer; import org.bouncycastle.asn1.ASN1Primitive; import org.bouncycastle.asn1.ASN1Sequence; import org.bouncycastle.asn1.DERSequence; import org.bouncycastle.asn1.DERSet; import org.bouncycastle.asn1.pkcs.ContentInfo; import org.bouncycastle.asn1.pkcs.PKCSObjectIdentifiers; import org.bouncycastle.asn1.pkcs.SignedData; import org.bouncycastle.jce.provider.BouncyCastleProvider; import org.bouncycastle.util.io.pem.PemObject; import org.bouncycastle.util.io.pem.PemWriter; /** * CertPath implementation for X.509 certificates. *
    **/ public class PKIXCertPath extends CertPath { static final List certPathEncodings; static { List encodings = new ArrayList(); encodings.add("PkiPath"); encodings.add("PEM"); encodings.add("PKCS7"); certPathEncodings = Collections.unmodifiableList(encodings); } private List certificates; /** * @param certs */ private List sortCerts( List certs) { try { if (certs.size() < 2) { return certs; } X509Principal issuer = PrincipalUtil.getIssuerX509Principal(((X509Certificate)certs.get(0))); boolean okay = true; for (int i = 1; i != certs.size(); i++) { X509Certificate cert = (X509Certificate)certs.get(i); if (issuer.equals(PrincipalUtil.getSubjectX509Principal(cert))) { issuer = PrincipalUtil.getIssuerX509Principal(((X509Certificate)certs.get(i))); } else { okay = false; break; } } if (okay) { return certs; } // find end-entity cert List retList = new ArrayList(certs.size()); List orig = new ArrayList(certs); for (int i = 0; i < certs.size(); i++) { X509Certificate cert = (X509Certificate)certs.get(i); boolean found = false; X509Principal subject = PrincipalUtil.getSubjectX509Principal(cert); for (int j = 0; j != certs.size(); j++) { X509Certificate c = (X509Certificate)certs.get(j); if (PrincipalUtil.getIssuerX509Principal(c).equals(subject)) { found = true; break; } } if (!found) { retList.add(cert); certs.remove(i); } } // can only have one end entity cert - something's wrong, give up. if (retList.size() > 1) { return orig; } for (int i = 0; i != retList.size(); i++) { issuer = PrincipalUtil.getIssuerX509Principal(((X509Certificate)retList.get(i))); for (int j = 0; j < certs.size(); j++) { X509Certificate c = (X509Certificate)certs.get(j); if (issuer.equals(PrincipalUtil.getSubjectX509Principal(c))) { retList.add(c); certs.remove(j); break; } } } // make sure all certificates are accounted for. if (certs.size() > 0) { return orig; } return retList; } catch (Exception e) { return certs; } } PKIXCertPath(List certificates) { super("X.509"); this.certificates = sortCerts(new ArrayList(certificates)); } /** * Creates a CertPath of the specified type. * This constructor is protected because most users should use * a CertificateFactory to create CertPaths. **/ PKIXCertPath( InputStream inStream, String encoding) throws CertificateException { super("X.509"); try { if (encoding.equalsIgnoreCase("PkiPath")) { ASN1InputStream derInStream = new ASN1InputStream(inStream); ASN1Primitive derObject = derInStream.readObject(); if (!(derObject instanceof ASN1Sequence)) { throw new CertificateException("input stream does not contain a ASN1 SEQUENCE while reading PkiPath encoded data to load CertPath"); } Enumeration e = ((ASN1Sequence)derObject).getObjects(); certificates = new ArrayList(); CertificateFactory certFactory = CertificateFactory.getInstance("X.509", BouncyCastleProvider.PROVIDER_NAME); while (e.hasMoreElements()) { ASN1Encodable element = (ASN1Encodable)e.nextElement(); byte[] encoded = element.toASN1Primitive().getEncoded(ASN1Encoding.DER); certificates.add(0, certFactory.generateCertificate( new ByteArrayInputStream(encoded))); } } else if (encoding.equalsIgnoreCase("PKCS7") || encoding.equalsIgnoreCase("PEM")) { inStream = new BufferedInputStream(inStream); certificates = new ArrayList(); CertificateFactory certFactory= CertificateFactory.getInstance("X.509", BouncyCastleProvider.PROVIDER_NAME); Certificate cert; while ((cert = certFactory.generateCertificate(inStream)) != null) { certificates.add(cert); } } else { throw new CertificateException("unsupported encoding: " + encoding); } } catch (IOException ex) { throw new CertificateException("IOException throw while decoding CertPath:\n" + ex.toString()); } catch (NoSuchProviderException ex) { throw new CertificateException("BouncyCastle provider not found while trying to get a CertificateFactory:\n" + ex.toString()); } this.certificates = sortCerts(certificates); } /** * Returns an iteration of the encodings supported by this * certification path, with the default encoding * first. Attempts to modify the returned Iterator via its * remove method result in an UnsupportedOperationException. * * @return an Iterator over the names of the supported encodings (as Strings) **/ public Iterator getEncodings() { return certPathEncodings.iterator(); } /** * Returns the encoded form of this certification path, using * the default encoding. * * @return the encoded bytes * @exception java.security.cert.CertificateEncodingException if an encoding error occurs **/ public byte[] getEncoded() throws CertificateEncodingException { Iterator iter = getEncodings(); if (iter.hasNext()) { Object enc = iter.next(); if (enc instanceof String) { return getEncoded((String)enc); } } return null; } /** * Returns the encoded form of this certification path, using * the specified encoding. * * @param encoding the name of the encoding to use * @return the encoded bytes * @exception java.security.cert.CertificateEncodingException if an encoding error * occurs or the encoding requested is not supported * **/ public byte[] getEncoded(String encoding) throws CertificateEncodingException { if (encoding.equalsIgnoreCase("PkiPath")) { ASN1EncodableVector v = new ASN1EncodableVector(); ListIterator iter = certificates.listIterator(certificates.size()); while (iter.hasPrevious()) { v.add(toASN1Object((X509Certificate)iter.previous())); } return toDEREncoded(new DERSequence(v)); } else if (encoding.equalsIgnoreCase("PKCS7")) { ContentInfo encInfo = new ContentInfo(PKCSObjectIdentifiers.data, null); ASN1EncodableVector v = new ASN1EncodableVector(); for (int i = 0; i != certificates.size(); i++) { v.add(toASN1Object((X509Certificate)certificates.get(i))); } SignedData sd = new SignedData( new ASN1Integer(1), new DERSet(), encInfo, new DERSet(v), null, new DERSet()); return toDEREncoded(new ContentInfo( PKCSObjectIdentifiers.signedData, sd)); } else if (encoding.equalsIgnoreCase("PEM")) { ByteArrayOutputStream bOut = new ByteArrayOutputStream(); PemWriter pWrt = new PemWriter(new OutputStreamWriter(bOut)); try { for (int i = 0; i != certificates.size(); i++) { pWrt.writeObject(new PemObject("CERTIFICATE", ((X509Certificate)certificates.get(i)).getEncoded())); } pWrt.close(); } catch (Exception e) { throw new CertificateEncodingException("can't encode certificate for PEM encoded path"); } return bOut.toByteArray(); } else { throw new CertificateEncodingException("unsupported encoding: " + encoding); } } /** * Returns the list of certificates in this certification * path. The List returned must be immutable and thread-safe. * * @return an immutable List of Certificates (may be empty, but not null) **/ public List getCertificates() { return Collections.unmodifiableList(new ArrayList(certificates)); } /** * Return a DERObject containing the encoded certificate. * * @param cert the X509Certificate object to be encoded * * @return the DERObject **/ private ASN1Primitive toASN1Object( X509Certificate cert) throws CertificateEncodingException { try { return new ASN1InputStream(cert.getEncoded()).readObject(); } catch (Exception e) { throw new CertificateEncodingException("Exception while encoding certificate: " + e.toString()); } } private byte[] toDEREncoded(ASN1Encodable obj) throws CertificateEncodingException { try { return obj.toASN1Primitive().getEncoded(ASN1Encoding.DER); } catch (IOException e) { throw new CertificateEncodingException("Exception thrown: " + e); } } } bouncycastle-1.49.orig/jdk1.1/org/bouncycastle/jcajce/provider/asymmetric/dsa/0000755000175000017500000000000012152033551026675 5ustar ebourgebourgbouncycastle-1.49.orig/jdk1.1/org/bouncycastle/jcajce/provider/asymmetric/dsa/DSASigner.java0000644000175000017500000001643311705627153031340 0ustar ebourgebourgpackage org.bouncycastle.jcajce.provider.asymmetric.dsa; import java.io.IOException; import java.math.BigInteger; import java.security.InvalidKeyException; import java.security.PrivateKey; import java.security.PublicKey; import java.security.SecureRandom; import java.security.SignatureException; import java.security.Signature; import java.security.interfaces.DSAKey; import java.security.spec.AlgorithmParameterSpec; import org.bouncycastle.asn1.ASN1Encoding; import org.bouncycastle.asn1.ASN1Integer; import org.bouncycastle.asn1.ASN1Primitive; import org.bouncycastle.asn1.ASN1Sequence; import org.bouncycastle.asn1.DERSequence; import org.bouncycastle.asn1.pkcs.PKCSObjectIdentifiers; import org.bouncycastle.asn1.x509.SubjectPublicKeyInfo; import org.bouncycastle.asn1.x509.X509ObjectIdentifiers; import org.bouncycastle.crypto.CipherParameters; import org.bouncycastle.crypto.DSA; import org.bouncycastle.crypto.Digest; import org.bouncycastle.crypto.digests.NullDigest; import org.bouncycastle.crypto.digests.SHA1Digest; import org.bouncycastle.crypto.digests.SHA224Digest; import org.bouncycastle.crypto.digests.SHA256Digest; import org.bouncycastle.crypto.digests.SHA384Digest; import org.bouncycastle.crypto.digests.SHA512Digest; import org.bouncycastle.crypto.params.ParametersWithRandom; public class DSASigner extends Signature implements PKCSObjectIdentifiers, X509ObjectIdentifiers { private Digest digest; private DSA signer; private SecureRandom random; protected DSASigner( Digest digest, DSA signer) { super("DSA"); this.digest = digest; this.signer = signer; } protected void engineInitVerify( PublicKey publicKey) throws InvalidKeyException { CipherParameters param; // if (publicKey instanceof GOST3410Key) // { // param = GOST3410Util.generatePublicKeyParameter(publicKey); // } // else if (publicKey instanceof DSAKey) if (publicKey instanceof DSAKey) { param = DSAUtil.generatePublicKeyParameter(publicKey); } else { try { byte[] bytes = publicKey.getEncoded(); publicKey = new BCDSAPublicKey(SubjectPublicKeyInfo.getInstance(bytes)); if (publicKey instanceof DSAKey) { param = DSAUtil.generatePublicKeyParameter(publicKey); } else { throw new InvalidKeyException("can't recognise key type in DSA based signer"); } } catch (Exception e) { throw new InvalidKeyException("can't recognise key type in DSA based signer"); } } digest.reset(); signer.init(false, param); } protected void engineInitSign( PrivateKey privateKey, SecureRandom random) throws InvalidKeyException { this.random = random; engineInitSign(privateKey); } protected void engineInitSign( PrivateKey privateKey) throws InvalidKeyException { CipherParameters param; // if (privateKey instanceof GOST3410Key) // { // param = GOST3410Util.generatePrivateKeyParameter(privateKey); // } // else // { param = DSAUtil.generatePrivateKeyParameter(privateKey); // } if (random != null) { param = new ParametersWithRandom(param, random); } digest.reset(); signer.init(true, param); } protected void engineUpdate( byte b) throws SignatureException { digest.update(b); } protected void engineUpdate( byte[] b, int off, int len) throws SignatureException { digest.update(b, off, len); } protected byte[] engineSign() throws SignatureException { byte[] hash = new byte[digest.getDigestSize()]; digest.doFinal(hash, 0); try { BigInteger[] sig = signer.generateSignature(hash); return derEncode(sig[0], sig[1]); } catch (Exception e) { throw new SignatureException(e.toString()); } } protected boolean engineVerify( byte[] sigBytes) throws SignatureException { byte[] hash = new byte[digest.getDigestSize()]; digest.doFinal(hash, 0); BigInteger[] sig; try { sig = derDecode(sigBytes); } catch (Exception e) { throw new SignatureException("error decoding signature bytes."); } return signer.verifySignature(hash, sig[0], sig[1]); } protected void engineSetParameter( AlgorithmParameterSpec params) { throw new UnsupportedOperationException("engineSetParameter unsupported"); } /** * @deprecated replaced with
    */ protected void engineSetParameter( String param, Object value) { throw new UnsupportedOperationException("engineSetParameter unsupported"); } /** * @deprecated */ protected Object engineGetParameter( String param) { throw new UnsupportedOperationException("engineSetParameter unsupported"); } private byte[] derEncode( BigInteger r, BigInteger s) throws IOException { ASN1Integer[] rs = new ASN1Integer[]{ new ASN1Integer(r), new ASN1Integer(s) }; return new DERSequence(rs).getEncoded(ASN1Encoding.DER); } private BigInteger[] derDecode( byte[] encoding) throws IOException { ASN1Sequence s = (ASN1Sequence)ASN1Primitive.fromByteArray(encoding); return new BigInteger[]{ ((ASN1Integer)s.getObjectAt(0)).getValue(), ((ASN1Integer)s.getObjectAt(1)).getValue() }; } static public class stdDSA extends DSASigner { public stdDSA() { super(new SHA1Digest(), new org.bouncycastle.crypto.signers.DSASigner()); } } static public class dsa224 extends DSASigner { public dsa224() { super(new SHA224Digest(), new org.bouncycastle.crypto.signers.DSASigner()); } } static public class dsa256 extends DSASigner { public dsa256() { super(new SHA256Digest(), new org.bouncycastle.crypto.signers.DSASigner()); } } static public class dsa384 extends DSASigner { public dsa384() { super(new SHA384Digest(), new org.bouncycastle.crypto.signers.DSASigner()); } } static public class dsa512 extends DSASigner { public dsa512() { super(new SHA512Digest(), new org.bouncycastle.crypto.signers.DSASigner()); } } static public class noneDSA extends DSASigner { public noneDSA() { super(new NullDigest(), new org.bouncycastle.crypto.signers.DSASigner()); } } } bouncycastle-1.49.orig/jdk1.1/org/bouncycastle/jce/0000755000175000017500000000000012152033551021441 5ustar ebourgebourgbouncycastle-1.49.orig/jdk1.1/org/bouncycastle/jce/provider/0000755000175000017500000000000012152033551023273 5ustar ebourgebourgbouncycastle-1.49.orig/jdk1.1/org/bouncycastle/jce/provider/X509CRLObject.java0000644000175000017500000004113011731467174026310 0ustar ebourgebourgpackage org.bouncycastle.jce.provider; import java.io.IOException; import java.math.BigInteger; import java.security.InvalidKeyException; import java.security.NoSuchAlgorithmException; import java.security.NoSuchProviderException; import java.security.Principal; import java.security.PublicKey; import java.security.Signature; import java.security.SignatureException; import java.security.cert.CRLException; import java.security.cert.Certificate; import java.security.cert.CertificateEncodingException; import java.security.cert.X509CRL; import java.security.cert.X509CRLEntry; import java.security.cert.X509Certificate; import java.util.Collections; import java.util.Date; import java.util.Enumeration; import java.util.HashSet; import java.util.Iterator; import java.util.Set; import org.bouncycastle.asn1.ASN1Encodable; import org.bouncycastle.asn1.ASN1Encoding; import org.bouncycastle.asn1.ASN1InputStream; import org.bouncycastle.asn1.ASN1ObjectIdentifier; import org.bouncycastle.asn1.DERInteger; import org.bouncycastle.asn1.util.ASN1Dump; import org.bouncycastle.asn1.x500.X500Name; import org.bouncycastle.asn1.x509.CRLDistPoint; import org.bouncycastle.asn1.x509.CRLNumber; import org.bouncycastle.asn1.x509.CertificateList; import org.bouncycastle.asn1.x509.Extension; import org.bouncycastle.asn1.x509.Extensions; import org.bouncycastle.asn1.x509.GeneralNames; import org.bouncycastle.asn1.x509.IssuingDistributionPoint; import org.bouncycastle.asn1.x509.TBSCertList; import org.bouncycastle.jce.X509Principal; import org.bouncycastle.util.encoders.Hex; import org.bouncycastle.x509.extension.X509ExtensionUtil; /** * The following extensions are listed in RFC 2459 as relevant to CRLs * * Authority Key Identifier * Issuer Alternative Name * CRL Number * Delta CRL Indicator (critical) * Issuing Distribution Point (critical) */ public class X509CRLObject extends X509CRL { private CertificateList c; private String sigAlgName; private byte[] sigAlgParams; private boolean isIndirect; static boolean isIndirectCRL(X509CRL crl) throws CRLException { try { byte[] idp = crl.getExtensionValue(Extension.issuingDistributionPoint.getId()); return idp != null && IssuingDistributionPoint.getInstance(X509ExtensionUtil.fromExtensionValue(idp)).isIndirectCRL(); } catch (Exception e) { throw new ExtCRLException( "Exception reading IssuingDistributionPoint", e); } } public X509CRLObject( CertificateList c) throws CRLException { this.c = c; try { this.sigAlgName = X509SignatureUtil.getSignatureName(c.getSignatureAlgorithm()); if (c.getSignatureAlgorithm().getParameters() != null) { this.sigAlgParams = ((ASN1Encodable)c.getSignatureAlgorithm().getParameters()).toASN1Primitive().getEncoded(ASN1Encoding.DER); } else { this.sigAlgParams = null; } this.isIndirect = isIndirectCRL(this); } catch (Exception e) { throw new CRLException("CRL contents invalid: " + e); } } /** * Will return true if any extensions are present and marked * as critical as we currently dont handle any extensions! */ public boolean hasUnsupportedCriticalExtension() { Set extns = getCriticalExtensionOIDs(); if (extns == null) { return false; } extns.remove(RFC3280CertPathUtilities.ISSUING_DISTRIBUTION_POINT); extns.remove(RFC3280CertPathUtilities.DELTA_CRL_INDICATOR); return !extns.isEmpty(); } private Set getExtensionOIDs(boolean critical) { if (this.getVersion() == 2) { Extensions extensions = c.getTBSCertList().getExtensions(); if (extensions != null) { Set set = new HashSet(); Enumeration e = extensions.oids(); while (e.hasMoreElements()) { ASN1ObjectIdentifier oid = (ASN1ObjectIdentifier)e.nextElement(); Extension ext = extensions.getExtension(oid); if (critical == ext.isCritical()) { set.add(oid.getId()); } } return set; } } return null; } public Set getCriticalExtensionOIDs() { return getExtensionOIDs(true); } public Set getNonCriticalExtensionOIDs() { return getExtensionOIDs(false); } public byte[] getExtensionValue(String oid) { Extensions exts = c.getTBSCertList().getExtensions(); if (exts != null) { Extension ext = exts.getExtension(new ASN1ObjectIdentifier(oid)); if (ext != null) { try { return ext.getExtnValue().getEncoded(); } catch (Exception e) { throw new IllegalStateException("error parsing " + e.toString()); } } } return null; } public byte[] getEncoded() throws CRLException { try { return c.getEncoded(ASN1Encoding.DER); } catch (IOException e) { throw new CRLException(e.toString()); } } public void verify(PublicKey key) throws CRLException, NoSuchAlgorithmException, InvalidKeyException, NoSuchProviderException, SignatureException { verify(key, BouncyCastleProvider.PROVIDER_NAME); } public void verify(PublicKey key, String sigProvider) throws CRLException, NoSuchAlgorithmException, InvalidKeyException, NoSuchProviderException, SignatureException { if (!c.getSignatureAlgorithm().equals(c.getTBSCertList().getSignature())) { throw new CRLException("Signature algorithm on CertificateList does not match TBSCertList."); } Signature sig; if (sigProvider != null) { sig = Signature.getInstance(getSigAlgName(), sigProvider); } else { sig = Signature.getInstance(getSigAlgName()); } sig.initVerify(key); sig.update(this.getTBSCertList()); if (!sig.verify(this.getSignature())) { throw new SignatureException("CRL does not verify with supplied public key."); } } public int getVersion() { return c.getVersionNumber(); } public Principal getIssuerDN() { return new X509Principal(X500Name.getInstance(c.getIssuer().toASN1Primitive())); } public Date getThisUpdate() { return c.getThisUpdate().getDate(); } public Date getNextUpdate() { if (c.getNextUpdate() != null) { return c.getNextUpdate().getDate(); } return null; } private Set loadCRLEntries() { Set entrySet = new HashSet(); Enumeration certs = c.getRevokedCertificateEnumeration(); X500Name previousCertificateIssuer = c.getIssuer(); while (certs.hasMoreElements()) { TBSCertList.CRLEntry entry = (TBSCertList.CRLEntry)certs.nextElement(); X509CRLEntryObject crlEntry = new X509CRLEntryObject(entry, isIndirect, previousCertificateIssuer); entrySet.add(crlEntry); if (isIndirect && entry.hasExtensions()) { Extension currentCaName = entry.getExtensions().getExtension(Extension.certificateIssuer); if (currentCaName != null) { previousCertificateIssuer = X500Name.getInstance(GeneralNames.getInstance(currentCaName.getParsedValue()).getNames()[0].getName()); } } } return entrySet; } public X509CRLEntry getRevokedCertificate(BigInteger serialNumber) { Enumeration certs = c.getRevokedCertificateEnumeration(); X500Name previousCertificateIssuer = c.getIssuer(); while (certs.hasMoreElements()) { TBSCertList.CRLEntry entry = (TBSCertList.CRLEntry)certs.nextElement(); if (serialNumber.equals(entry.getUserCertificate().getValue())) { return new X509CRLEntryObject(entry, isIndirect, previousCertificateIssuer); } if (isIndirect && entry.hasExtensions()) { Extension currentCaName = entry.getExtensions().getExtension(Extension.certificateIssuer); if (currentCaName != null) { previousCertificateIssuer = X500Name.getInstance(GeneralNames.getInstance(currentCaName.getParsedValue()).getNames()[0].getName()); } } } return null; } public Set getRevokedCertificates() { Set entrySet = loadCRLEntries(); if (!entrySet.isEmpty()) { return Collections.unmodifiableSet(entrySet); } return null; } public byte[] getTBSCertList() throws CRLException { try { return c.getTBSCertList().getEncoded("DER"); } catch (IOException e) { throw new CRLException(e.toString()); } } public byte[] getSignature() { return c.getSignature().getBytes(); } public String getSigAlgName() { return sigAlgName; } public String getSigAlgOID() { return c.getSignatureAlgorithm().getAlgorithm().getId(); } public byte[] getSigAlgParams() { if (sigAlgParams != null) { byte[] tmp = new byte[sigAlgParams.length]; System.arraycopy(sigAlgParams, 0, tmp, 0, tmp.length); return tmp; } return null; } /** * Returns a string representation of this CRL. * * @return a string representation of this CRL. */ public String toString() { StringBuffer buf = new StringBuffer(); String nl = System.getProperty("line.separator"); buf.append(" Version: ").append(this.getVersion()).append( nl); buf.append(" IssuerDN: ").append(this.getIssuerDN()) .append(nl); buf.append(" This update: ").append(this.getThisUpdate()) .append(nl); buf.append(" Next update: ").append(this.getNextUpdate()) .append(nl); buf.append(" Signature Algorithm: ").append(this.getSigAlgName()) .append(nl); byte[] sig = this.getSignature(); buf.append(" Signature: ").append( new String(Hex.encode(sig, 0, 20))).append(nl); for (int i = 20; i < sig.length; i += 20) { if (i < sig.length - 20) { buf.append(" ").append( new String(Hex.encode(sig, i, 20))).append(nl); } else { buf.append(" ").append( new String(Hex.encode(sig, i, sig.length - i))).append(nl); } } Extensions extensions = c.getTBSCertList().getExtensions(); if (extensions != null) { Enumeration e = extensions.oids(); if (e.hasMoreElements()) { buf.append(" Extensions: ").append(nl); } while (e.hasMoreElements()) { ASN1ObjectIdentifier oid = (ASN1ObjectIdentifier) e.nextElement(); Extension ext = extensions.getExtension(oid); if (ext.getExtnValue() != null) { byte[] octs = ext.getExtnValue().getOctets(); ASN1InputStream dIn = new ASN1InputStream(octs); buf.append(" critical(").append( ext.isCritical()).append(") "); try { if (oid.equals(Extension.cRLNumber)) { buf.append( new CRLNumber(DERInteger.getInstance( dIn.readObject()).getPositiveValue())) .append(nl); } else if (oid.equals(Extension.deltaCRLIndicator)) { buf.append( "Base CRL: " + new CRLNumber(DERInteger.getInstance( dIn.readObject()).getPositiveValue())) .append(nl); } else if (oid .equals(Extension.issuingDistributionPoint)) { buf.append( IssuingDistributionPoint.getInstance(dIn.readObject())).append(nl); } else if (oid .equals(Extension.cRLDistributionPoints)) { buf.append( CRLDistPoint.getInstance(dIn.readObject())).append(nl); } else if (oid.equals(Extension.freshestCRL)) { buf.append( CRLDistPoint.getInstance(dIn.readObject())).append(nl); } else { buf.append(oid.getId()); buf.append(" value = ").append( ASN1Dump.dumpAsString(dIn.readObject())) .append(nl); } } catch (Exception ex) { buf.append(oid.getId()); buf.append(" value = ").append("*****").append(nl); } } else { buf.append(nl); } } } Set set = getRevokedCertificates(); if (set != null) { Iterator it = set.iterator(); while (it.hasNext()) { buf.append(it.next()); buf.append(nl); } } return buf.toString(); } /** * Checks whether the given certificate is on this CRL. * * @param cert the certificate to check for. * @return true if the given certificate is on this CRL, * false otherwise. */ public boolean isRevoked(Certificate cert) { if (!cert.getType().equals("X.509")) { throw new RuntimeException("X.509 CRL used with non X.509 Cert"); } TBSCertList.CRLEntry[] certs = c.getRevokedCertificates(); X500Name caName = c.getIssuer(); if (certs != null) { BigInteger serial = ((X509Certificate)cert).getSerialNumber(); for (int i = 0; i < certs.length; i++) { if (isIndirect && certs[i].hasExtensions()) { Extension currentCaName = certs[i].getExtensions().getExtension(Extension.certificateIssuer); if (currentCaName != null) { caName = X500Name.getInstance(GeneralNames.getInstance(currentCaName.getParsedValue()).getNames()[0].getName()); } } if (certs[i].getUserCertificate().getValue().equals(serial)) { X500Name issuer; try { issuer = org.bouncycastle.asn1.x509.Certificate.getInstance(cert.getEncoded()).getIssuer(); } catch (CertificateEncodingException e) { throw new RuntimeException("Cannot process certificate"); } if (!caName.equals(issuer)) { return false; } return true; } } } return false; } } bouncycastle-1.49.orig/jdk1.1/org/bouncycastle/jce/provider/BouncyCastleProviderConfiguration.java0000644000175000017500000000631612105031243032774 0ustar ebourgebourgpackage org.bouncycastle.jce.provider; import javax.crypto.spec.DHParameterSpec; import org.bouncycastle.jcajce.provider.config.ConfigurableProvider; import org.bouncycastle.jcajce.provider.config.ProviderConfiguration; import org.bouncycastle.jce.spec.ECParameterSpec; class BouncyCastleProviderConfiguration implements ProviderConfiguration { private volatile ECParameterSpec ecImplicitCaParams; private volatile Object dhDefaultParams; void setParameter(String parameterName, Object parameter) { SecurityManager securityManager = System.getSecurityManager(); if (parameterName.equals(ConfigurableProvider.THREAD_LOCAL_EC_IMPLICITLY_CA)) { ECParameterSpec curveSpec; if (parameter instanceof ECParameterSpec || parameter == null) { curveSpec = (ECParameterSpec)parameter; } else { throw new IllegalArgumentException("not a valid ECParameterSpec"); } ecImplicitCaParams = (ECParameterSpec)curveSpec; } else if (parameterName.equals(ConfigurableProvider.EC_IMPLICITLY_CA)) { if (parameter instanceof ECParameterSpec || parameter == null) { ecImplicitCaParams = (ECParameterSpec)parameter; } else // assume java.security.spec { throw new IllegalArgumentException("not a valid ECParameterSpec"); } } else if (parameterName.equals(ConfigurableProvider.THREAD_LOCAL_DH_DEFAULT_PARAMS)) { Object dhSpec; if (parameter instanceof DHParameterSpec || parameter instanceof DHParameterSpec[] || parameter == null) { dhSpec = parameter; } else { throw new IllegalArgumentException("not a valid DHParameterSpec"); } dhDefaultParams = dhSpec; } else if (parameterName.equals(ConfigurableProvider.DH_DEFAULT_PARAMS)) { if (parameter instanceof DHParameterSpec || parameter instanceof DHParameterSpec[] || parameter == null) { dhDefaultParams = parameter; } else { throw new IllegalArgumentException("not a valid DHParameterSpec or DHParameterSpec[]"); } } } public ECParameterSpec getEcImplicitlyCa() { return ecImplicitCaParams; } public DHParameterSpec getDHDefaultParameters(int keySize) { Object params = dhDefaultParams; if (params instanceof DHParameterSpec) { DHParameterSpec spec = (DHParameterSpec)params; if (spec.getP().bitLength() == keySize) { return spec; } } else if (params instanceof DHParameterSpec[]) { DHParameterSpec[] specs = (DHParameterSpec[])params; for (int i = 0; i != specs.length; i++) { if (specs[i].getP().bitLength() == keySize) { return specs[i]; } } } return null; } } bouncycastle-1.49.orig/jdk1.1/org/bouncycastle/jce/provider/PKIXPolicyNode.java0000644000175000017500000000770411705654527026726 0ustar ebourgebourgpackage org.bouncycastle.jce.provider; import java.security.cert.PolicyNode; import java.util.ArrayList; import java.util.HashSet; import java.util.Iterator; import java.util.List; import java.util.Set; public class PKIXPolicyNode implements PolicyNode { protected List children; protected int depth; protected Set expectedPolicies; protected PolicyNode parent; protected Set policyQualifiers; protected String validPolicy; protected boolean critical; /* * * CONSTRUCTORS * */ public PKIXPolicyNode( List _children, int _depth, Set _expectedPolicies, PolicyNode _parent, Set _policyQualifiers, String _validPolicy, boolean _critical) { children = _children; depth = _depth; expectedPolicies = _expectedPolicies; parent = _parent; policyQualifiers = _policyQualifiers; validPolicy = _validPolicy; critical = _critical; } public void addChild( PKIXPolicyNode _child) { children.add(_child); _child.setParent(this); } public Iterator getChildren() { return children.iterator(); } public int getDepth() { return depth; } public Set getExpectedPolicies() { return expectedPolicies; } public PolicyNode getParent() { return parent; } public Set getPolicyQualifiers() { return policyQualifiers; } public String getValidPolicy() { return validPolicy; } public boolean hasChildren() { return !children.isEmpty(); } public boolean isCritical() { return critical; } public void removeChild(PKIXPolicyNode _child) { children.remove(_child); } public void setCritical(boolean _critical) { critical = _critical; } public void setParent(PKIXPolicyNode _parent) { parent = _parent; } public String toString() { return toString(""); } public String toString(String _indent) { StringBuffer _buf = new StringBuffer(); _buf.append(_indent); _buf.append(validPolicy); _buf.append(" {\n"); for(int i = 0; i < children.size(); i++) { _buf.append(((PKIXPolicyNode)children.get(i)).toString(_indent + " ")); } _buf.append(_indent); _buf.append("}\n"); return _buf.toString(); } public Object clone() { return copy(); } public PKIXPolicyNode copy() { HashSet _expectedPolicies = new HashSet(); Iterator _iter = expectedPolicies.iterator(); while (_iter.hasNext()) { _expectedPolicies.add(new String((String)_iter.next())); } HashSet _policyQualifiers = new HashSet(); _iter = policyQualifiers.iterator(); while (_iter.hasNext()) { _policyQualifiers.add(new String((String)_iter.next())); } PKIXPolicyNode _node = new PKIXPolicyNode(new ArrayList(), depth, _expectedPolicies, null, _policyQualifiers, new String(validPolicy), critical); _iter = children.iterator(); while (_iter.hasNext()) { PKIXPolicyNode _child = ((PKIXPolicyNode)_iter.next()).copy(); _child.setParent(_node); _node.addChild(_child); } return _node; } } bouncycastle-1.49.orig/jdk1.1/org/bouncycastle/jce/provider/MultiCertStoreSpi.java0000644000175000017500000000475111705654527027565 0ustar ebourgebourgpackage org.bouncycastle.jce.provider; import org.bouncycastle.jce.MultiCertStoreParameters; import java.security.InvalidAlgorithmParameterException; import java.security.cert.CRLSelector; import java.security.cert.CertSelector; import java.security.cert.CertStore; import java.security.cert.CertStoreException; import java.security.cert.CertStoreParameters; import java.security.cert.CertStoreSpi; import java.util.ArrayList; import java.util.Collection; import java.util.Collections; import java.util.Iterator; import java.util.List; public class MultiCertStoreSpi extends CertStoreSpi { private MultiCertStoreParameters params; public MultiCertStoreSpi(CertStoreParameters params) throws InvalidAlgorithmParameterException { super(params); if (!(params instanceof MultiCertStoreParameters)) { throw new InvalidAlgorithmParameterException("org.bouncycastle.jce.provider.MultiCertStoreSpi: parameter must be a MultiCertStoreParameters object\n" + params.toString()); } this.params = (MultiCertStoreParameters)params; } public Collection engineGetCertificates(CertSelector certSelector) throws CertStoreException { boolean searchAllStores = params.getSearchAllStores(); Iterator iter = params.getCertStores().iterator(); List allCerts = searchAllStores ? new ArrayList() : Collections.EMPTY_LIST; while (iter.hasNext()) { CertStore store = (CertStore)iter.next(); Collection certs = store.getCertificates(certSelector); if (searchAllStores) { allCerts.addAll(certs); } else if (!certs.isEmpty()) { return certs; } } return allCerts; } public Collection engineGetCRLs(CRLSelector crlSelector) throws CertStoreException { boolean searchAllStores = params.getSearchAllStores(); Iterator iter = params.getCertStores().iterator(); List allCRLs = searchAllStores ? new ArrayList() : Collections.EMPTY_LIST; while (iter.hasNext()) { CertStore store = (CertStore)iter.next(); Collection crls = store.getCRLs(crlSelector); if (searchAllStores) { allCRLs.addAll(crls); } else if (!crls.isEmpty()) { return crls; } } return allCRLs; } } bouncycastle-1.49.orig/jdk1.1/org/bouncycastle/jce/provider/PKIXCertPathValidatorSpi.java0000644000175000017500000023116012105031243030663 0ustar ebourgebourgpackage org.bouncycastle.jce.provider; import java.io.ByteArrayInputStream; import java.io.ByteArrayOutputStream; import java.io.IOException; import java.math.BigInteger; import java.security.InvalidAlgorithmParameterException; import java.security.PublicKey; import java.security.cert.CRLException; import java.security.cert.CertificateNotYetValidException; import java.security.cert.CertificateExpiredException; import java.security.cert.CertificateEncodingException; import java.security.cert.CertPath; import java.security.cert.CertPathParameters; import java.security.cert.CertPathValidatorSpi; import java.security.cert.CertPathValidatorException; import java.security.cert.CertPathValidatorResult; import java.security.cert.PolicyQualifierInfo; import java.security.cert.X509Certificate; import java.security.cert.X509CRL; import java.security.cert.X509CRLEntry; import java.security.cert.X509CRLSelector; import java.security.cert.X509CertSelector; import java.security.cert.PKIXParameters; import java.security.cert.PKIXCertPathChecker; import java.security.cert.PKIXCertPathValidatorResult; import java.security.cert.TrustAnchor; import java.security.cert.PKIXParameters; import java.security.cert.CertStore; import java.security.cert.CertStoreException; import java.util.ArrayList; import java.util.Collection; import java.util.Date; import java.util.Enumeration; import java.util.HashMap; import java.util.HashSet; import java.util.Iterator; import java.util.List; import java.util.Map; import java.util.Set; import org.bouncycastle.jce.X509Principal; import org.bouncycastle.jce.PrincipalUtil; import org.bouncycastle.asn1.ASN1InputStream; import org.bouncycastle.asn1.ASN1OctetString; import org.bouncycastle.asn1.ASN1OutputStream; import org.bouncycastle.asn1.ASN1Sequence; import org.bouncycastle.asn1.ASN1TaggedObject; import org.bouncycastle.asn1.BERConstructedOctetString; import org.bouncycastle.asn1.ASN1Encodable; import org.bouncycastle.asn1.DEREnumerated; import org.bouncycastle.asn1.DERIA5String; import org.bouncycastle.asn1.DERInteger; import org.bouncycastle.asn1.ASN1Primitive; import org.bouncycastle.asn1.DERObjectIdentifier; import org.bouncycastle.asn1.x509.AlgorithmIdentifier; import org.bouncycastle.asn1.x509.BasicConstraints; import org.bouncycastle.asn1.x509.GeneralName; import org.bouncycastle.asn1.x509.GeneralSubtree; import org.bouncycastle.asn1.x509.IssuingDistributionPoint; import org.bouncycastle.asn1.x509.NameConstraints; import org.bouncycastle.asn1.x509.PolicyInformation; import org.bouncycastle.asn1.x509.SubjectPublicKeyInfo; import org.bouncycastle.asn1.x509.X509Extensions; /** * CertPathValidatorSpi implemenation for X.509 Certificate validation ala rfc 3280
    **/ public class PKIXCertPathValidatorSpi extends CertPathValidatorSpi { private static final String CERTIFICATE_POLICIES = X509Extensions.CertificatePolicies.getId(); private static final String POLICY_MAPPINGS = X509Extensions.PolicyMappings.getId(); private static final String INHIBIT_ANY_POLICY = X509Extensions.InhibitAnyPolicy.getId(); private static final String ISSUING_DISTRIBUTION_POINT = X509Extensions.IssuingDistributionPoint.getId(); private static final String DELTA_CRL_INDICATOR = X509Extensions.DeltaCRLIndicator.getId(); private static final String POLICY_CONSTRAINTS = X509Extensions.PolicyConstraints.getId(); private static final String BASIC_CONSTRAINTS = X509Extensions.BasicConstraints.getId(); private static final String SUBJECT_ALTERNATIVE_NAME = X509Extensions.SubjectAlternativeName.getId(); private static final String NAME_CONSTRAINTS = X509Extensions.NameConstraints.getId(); private static final String KEY_USAGE = X509Extensions.KeyUsage.getId(); private static final String CRL_NUMBER = X509Extensions.CRLNumber.getId(); private static final String ANY_POLICY = "2.5.29.32.0"; /* * key usage bits */ private static final int KEY_CERT_SIGN = 5; private static final int CRL_SIGN = 6; private static final String[] crlReasons = new String[] { "unspecified", "keyCompromise", "cACompromise", "affiliationChanged", "superseded", "cessationOfOperation", "certificateHold", "unknown", "removeFromCRL", "privilegeWithdrawn", "aACompromise" }; /** * extract the value of the given extension, if it exists. */ private ASN1Primitive getExtensionValue( java.security.cert.X509Extension ext, String oid) throws AnnotatedException { byte[] bytes = ext.getExtensionValue(oid); if (bytes == null) { return null; } return getObject(oid, bytes); } private ASN1Primitive getObject( String oid, byte[] ext) throws AnnotatedException { try { ASN1InputStream aIn = new ASN1InputStream(ext); ASN1OctetString octs = (ASN1OctetString)aIn.readObject(); aIn = new ASN1InputStream(octs.getOctets()); return aIn.readObject(); } catch (IOException e) { throw new AnnotatedException("exception processing extension " + oid, e); } } private boolean withinDNSubtree( ASN1Sequence dns, ASN1Sequence subtree) { if (subtree.size() < 1) { return false; } if (subtree.size() > dns.size()) { return false; } for (int j = subtree.size() - 1; j >= 0; j--) { if (!subtree.getObjectAt(j).equals(dns.getObjectAt(j))) { return false; } } return true; } private void checkPermittedDN( Set permitted, ASN1Sequence dns) throws CertPathValidatorException { if (permitted.isEmpty()) { return; } Iterator it = permitted.iterator(); while (it.hasNext()) { ASN1Sequence subtree = (ASN1Sequence)it.next(); if (withinDNSubtree(dns, subtree)) { return; } } throw new CertPathValidatorException("Subject distinguished name is not from a permitted subtree"); } private void checkExcludedDN( Set excluded, ASN1Sequence dns) throws CertPathValidatorException { if (excluded.isEmpty()) { return; } Iterator it = excluded.iterator(); while (it.hasNext()) { ASN1Sequence subtree = (ASN1Sequence)it.next(); if (withinDNSubtree(dns, subtree)) { throw new CertPathValidatorException("Subject distinguished name is from an excluded subtree"); } } } private Set intersectDN( Set permitted, ASN1Sequence dn) { if (permitted.isEmpty()) { permitted.add(dn); return permitted; } else { Set intersect = new HashSet(); Iterator _iter = permitted.iterator(); while (_iter.hasNext()) { ASN1Sequence subtree = (ASN1Sequence)_iter.next(); if (withinDNSubtree(dn, subtree)) { intersect.add(dn); } else if (withinDNSubtree(subtree, dn)) { intersect.add(subtree); } } return intersect; } } private Set unionDN( Set excluded, ASN1Sequence dn) { if (excluded.isEmpty()) { excluded.add(dn); return excluded; } else { Set intersect = new HashSet(); Iterator _iter = excluded.iterator(); while (_iter.hasNext()) { ASN1Sequence subtree = (ASN1Sequence)_iter.next(); if (withinDNSubtree(dn, subtree)) { intersect.add(subtree); } else if (withinDNSubtree(subtree, dn)) { intersect.add(dn); } else { intersect.add(subtree); intersect.add(dn); } } return intersect; } } private Set intersectEmail( Set permitted, String email) { String _sub = email.substring(email.indexOf('@') + 1); if (permitted.isEmpty()) { permitted.add(_sub); return permitted; } else { Set intersect = new HashSet(); Iterator _iter = permitted.iterator(); while (_iter.hasNext()) { String _permitted = (String)_iter.next(); if (_sub.endsWith(_permitted)) { intersect.add(_sub); } else if (_permitted.endsWith(_sub)) { intersect.add(_permitted); } } return intersect; } } private Set unionEmail( Set excluded, String email) { String _sub = email.substring(email.indexOf('@') + 1); if (excluded.isEmpty()) { excluded.add(_sub); return excluded; } else { Set intersect = new HashSet(); Iterator _iter = excluded.iterator(); while (_iter.hasNext()) { String _excluded = (String)_iter.next(); if (_sub.endsWith(_excluded)) { intersect.add(_excluded); } else if (_excluded.endsWith(_sub)) { intersect.add(_sub); } else { intersect.add(_excluded); intersect.add(_sub); } } return intersect; } } private Set intersectIP( Set permitted, byte[] ip) { // TBD return permitted; } private Set unionIP( Set excluded, byte[] ip) { // TBD return excluded; } private void checkPermittedEmail( Set permitted, String email) throws CertPathValidatorException { if (permitted.isEmpty()) { return; } String sub = email.substring(email.indexOf('@') + 1); Iterator it = permitted.iterator(); while (it.hasNext()) { String str = (String)it.next(); if (sub.endsWith(str)) { return; } } throw new CertPathValidatorException("Subject email address is not from a permitted subtree"); } private void checkExcludedEmail( Set excluded, String email) throws CertPathValidatorException { if (excluded.isEmpty()) { return; } String sub = email.substring(email.indexOf('@') + 1); Iterator it = excluded.iterator(); while (it.hasNext()) { String str = (String)it.next(); if (sub.endsWith(str)) { throw new CertPathValidatorException("Subject email address is from an excluded subtree"); } } } private void checkPermittedIP( Set permitted, byte[] ip) throws CertPathValidatorException { if (permitted.isEmpty()) { return; } // TODO: ??? Something here } private void checkExcludedIP( Set excluded, byte[] ip) throws CertPathValidatorException { if (excluded.isEmpty()) { return; } // TODO, check RFC791 and RFC1883 for IP bytes definition. } private PKIXPolicyNode removePolicyNode( PKIXPolicyNode validPolicyTree, List [] policyNodes, PKIXPolicyNode _node) { PKIXPolicyNode _parent = (PKIXPolicyNode)_node.getParent(); if (validPolicyTree == null) { return null; } if (_parent == null) { for (int j = 0; j < policyNodes.length; j++) { policyNodes[j] = new ArrayList(); } return null; } else { _parent.removeChild(_node); removePolicyNodeRecurse(policyNodes, _node); return validPolicyTree; } } private void removePolicyNodeRecurse( List [] policyNodes, PKIXPolicyNode _node) { policyNodes[_node.getDepth()].remove(_node); if (_node.hasChildren()) { Iterator _iter = _node.getChildren(); while (_iter.hasNext()) { PKIXPolicyNode _child = (PKIXPolicyNode)_iter.next(); removePolicyNodeRecurse(policyNodes, _child); } } } private boolean isSelfIssued( X509Certificate cert) { return cert.getSubjectDN().equals(cert.getIssuerDN()); } private boolean isAnyPolicy( Set policySet) { return policySet == null || policySet.contains(ANY_POLICY) || policySet.isEmpty(); } private AlgorithmIdentifier getAlgorithmIdentifier( PublicKey key) throws CertPathValidatorException { try { ASN1InputStream aIn = new ASN1InputStream( new ByteArrayInputStream(key.getEncoded())); SubjectPublicKeyInfo info = SubjectPublicKeyInfo.getInstance(aIn.readObject()); return info.getAlgorithmId(); } catch (IOException e) { throw new CertPathValidatorException("exception processing public key"); } } private Set getQualifierSet(ASN1Sequence qualifiers) throws CertPathValidatorException { Set pq = new HashSet(); if (qualifiers == null) { return pq; } ByteArrayOutputStream bOut = new ByteArrayOutputStream(); ASN1OutputStream aOut = new ASN1OutputStream(bOut); Enumeration e = qualifiers.getObjects(); while (e.hasMoreElements()) { try { aOut.writeObject((ASN1Encodable)e.nextElement()); pq.add(new PolicyQualifierInfo(bOut.toByteArray())); } catch (IOException ex) { throw new CertPathValidatorException("exception building qualifier set: " + ex); } bOut.reset(); } return pq; } private boolean processCertD1i( int index, List [] policyNodes, DERObjectIdentifier pOid, Set pq) { List policyNodeVec = policyNodes[index - 1]; for (int j = 0; j < policyNodeVec.size(); j++) { PKIXPolicyNode node = (PKIXPolicyNode)policyNodeVec.get(j); Set expectedPolicies = node.getExpectedPolicies(); if (expectedPolicies.contains(pOid.getId())) { Set childExpectedPolicies = new HashSet(); childExpectedPolicies.add(pOid.getId()); PKIXPolicyNode child = new PKIXPolicyNode(new ArrayList(), index, childExpectedPolicies, node, pq, pOid.getId(), false); node.addChild(child); policyNodes[index].add(child); return true; } } return false; } private void processCertD1ii( int index, List [] policyNodes, DERObjectIdentifier _poid, Set _pq) { List policyNodeVec = policyNodes[index - 1]; for (int j = 0; j < policyNodeVec.size(); j++) { PKIXPolicyNode _node = (PKIXPolicyNode)policyNodeVec.get(j); Set _expectedPolicies = _node.getExpectedPolicies(); if (ANY_POLICY.equals(_node.getValidPolicy())) { Set _childExpectedPolicies = new HashSet(); _childExpectedPolicies.add(_poid.getId()); PKIXPolicyNode _child = new PKIXPolicyNode(new ArrayList(), index, _childExpectedPolicies, _node, _pq, _poid.getId(), false); _node.addChild(_child); policyNodes[index].add(_child); return; } } } public CertPathValidatorResult engineValidate( CertPath certPath, CertPathParameters params) throws CertPathValidatorException, InvalidAlgorithmParameterException { if (!(params instanceof PKIXParameters)) { throw new InvalidAlgorithmParameterException("params must be a PKIXParameters instance"); } PKIXParameters paramsPKIX = (PKIXParameters)params; if (paramsPKIX.getTrustAnchors() == null) { throw new InvalidAlgorithmParameterException("trustAnchors is null, this is not allowed for path validation"); } // // 6.1.1 - inputs // // // (a) // List certs = certPath.getCertificates(); int n = certs.size(); if (certs.isEmpty()) { throw new CertPathValidatorException("CertPath is empty", null, certPath, 0); } // // (b) // Date validDate = getValidDate(paramsPKIX); // // (c) // Set userInitialPolicySet = paramsPKIX.getInitialPolicies(); // // (d) // TrustAnchor trust = findTrustAnchor((X509Certificate)certs.get(certs.size() - 1), certPath, certs.size() - 1, paramsPKIX.getTrustAnchors()); if (trust == null) { throw new CertPathValidatorException("TrustAnchor for CertPath not found.", null, certPath, -1); } // // (e), (f), (g) are part of the paramsPKIX object. // Iterator certIter; int index = 0; int i; //Certificate for each interation of the validation loop //Signature information for each iteration of the validation loop Set subTreeContraints = new HashSet(); Set subTreeExcludes = new HashSet(); // // 6.1.2 - setup // // // (a) // List [] policyNodes = new ArrayList[n + 1]; for (int j = 0; j < policyNodes.length; j++) { policyNodes[j] = new ArrayList(); } Set policySet = new HashSet(); policySet.add(ANY_POLICY); PKIXPolicyNode validPolicyTree = new PKIXPolicyNode(new ArrayList(), 0, policySet, null, new HashSet(), ANY_POLICY, false); policyNodes[0].add(validPolicyTree); // // (b) // Set permittedSubtreesDN = new HashSet(); Set permittedSubtreesEmail = new HashSet(); Set permittedSubtreesIP = new HashSet(); // // (c) // Set excludedSubtreesDN = new HashSet(); Set excludedSubtreesEmail = new HashSet(); Set excludedSubtreesIP = new HashSet(); // // (d) // int explicitPolicy; Set acceptablePolicies = null; if (paramsPKIX.isExplicitPolicyRequired()) { explicitPolicy = 0; } else { explicitPolicy = n + 1; } // // (e) // int inhibitAnyPolicy; if (paramsPKIX.isAnyPolicyInhibited()) { inhibitAnyPolicy = 0; } else { inhibitAnyPolicy = n + 1; } // // (f) // int policyMapping; if (paramsPKIX.isPolicyMappingInhibited()) { policyMapping = 0; } else { policyMapping = n + 1; } // // (g), (h), (i), (j) // PublicKey workingPublicKey; X509Principal workingIssuerName; X509Certificate sign = trust.getTrustedCert(); try { if (sign != null) { workingIssuerName = getSubjectPrincipal(sign); workingPublicKey = sign.getPublicKey(); } else { workingIssuerName = new X509Principal(trust.getCAName()); workingPublicKey = trust.getCAPublicKey(); } } catch (IllegalArgumentException ex) { throw new CertPathValidatorException("TrustAnchor subjectDN: " + ex.toString()); } catch (AnnotatedException ex) { throw new CertPathValidatorException(ex.getMessage(), ex.getUnderlyingException(), certPath, index); } AlgorithmIdentifier workingAlgId = getAlgorithmIdentifier(workingPublicKey); DERObjectIdentifier workingPublicKeyAlgorithm = workingAlgId.getObjectId(); ASN1Encodable workingPublicKeyParameters = workingAlgId.getParameters(); // // (k) // int maxPathLength = n; // // 6.1.3 // Iterator tmpIter; int tmpInt; if (paramsPKIX.getTargetCertConstraints() != null && !paramsPKIX.getTargetCertConstraints().match((X509Certificate)certs.get(0))) { throw new CertPathValidatorException("target certificate in certpath does not match targetcertconstraints", null, certPath, 0); } // // initialise CertPathChecker's // List pathCheckers = paramsPKIX.getCertPathCheckers(); certIter = pathCheckers.iterator(); while (certIter.hasNext()) { ((PKIXCertPathChecker)certIter.next()).init(false); } X509Certificate cert = null; for (index = certs.size() - 1; index >= 0 ; index--) { try { // // i as defined in the algorithm description // i = n - index; // // set certificate to be checked in this round // sign and workingPublicKey and workingIssuerName are set // at the end of the for loop and initialied the // first time from the TrustAnchor // cert = (X509Certificate)certs.get(index); // // 6.1.3 // // // (a) verify // try { // (a) (1) // cert.verify(workingPublicKey, "BC"); } catch (Exception e) { throw new CertPathValidatorException("Could not validate certificate signature.", e, certPath, index); } try { // (a) (2) // cert.checkValidity(validDate); } catch (CertificateExpiredException e) { throw new CertPathValidatorException("Could not validate certificate: " + e.getMessage(), e, certPath, index); } catch (CertificateNotYetValidException e) { throw new CertPathValidatorException("Could not validate certificate: " + e.getMessage(), e, certPath, index); } // // (a) (3) // if (paramsPKIX.isRevocationEnabled()) { checkCRLs(paramsPKIX, cert, validDate, sign, workingPublicKey); } // // (a) (4) name chaining // if (!getEncodedIssuerPrincipal(cert).equals(workingIssuerName)) { throw new CertPathValidatorException( "IssuerName(" + getEncodedIssuerPrincipal(cert) + ") does not match SubjectName(" + workingIssuerName + ") of signing certificate", null, certPath, index); } // // (b), (c) permitted and excluded subtree checking. // if (!(isSelfIssued(cert) && (i < n))) { X509Principal principal = getSubjectPrincipal(cert); ASN1InputStream aIn = new ASN1InputStream(new ByteArrayInputStream(principal.getEncoded())); ASN1Sequence dns; try { dns = (ASN1Sequence)aIn.readObject(); } catch (IOException e) { throw new CertPathValidatorException("exception extracting subject name when checking subtrees"); } checkPermittedDN(permittedSubtreesDN, dns); checkExcludedDN(excludedSubtreesDN, dns); ASN1Sequence altName = (ASN1Sequence)getExtensionValue(cert, SUBJECT_ALTERNATIVE_NAME); if (altName != null) { for (int j = 0; j < altName.size(); j++) { ASN1TaggedObject o = (ASN1TaggedObject)altName.getObjectAt(j); switch(o.getTagNo()) { case 1: String email = DERIA5String.getInstance(o, true).getString(); checkPermittedEmail(permittedSubtreesEmail, email); checkExcludedEmail(excludedSubtreesEmail, email); break; case 4: ASN1Sequence altDN = ASN1Sequence.getInstance(o, true); checkPermittedDN(permittedSubtreesDN, altDN); checkExcludedDN(excludedSubtreesDN, altDN); break; case 7: byte[] ip = ASN1OctetString.getInstance(o, true).getOctets(); checkPermittedIP(permittedSubtreesIP, ip); checkExcludedIP(excludedSubtreesIP, ip); } } } } // // (d) policy Information checking against initial policy and // policy mapping // ASN1Sequence certPolicies = (ASN1Sequence)getExtensionValue(cert, CERTIFICATE_POLICIES); if (certPolicies != null && validPolicyTree != null) { // // (d) (1) // Enumeration e = certPolicies.getObjects(); Set pols = new HashSet(); while (e.hasMoreElements()) { PolicyInformation pInfo = PolicyInformation.getInstance(e.nextElement()); DERObjectIdentifier pOid = pInfo.getPolicyIdentifier(); pols.add(pOid.getId()); if (!ANY_POLICY.equals(pOid.getId())) { Set pq = getQualifierSet(pInfo.getPolicyQualifiers()); boolean match = processCertD1i(i, policyNodes, pOid, pq); if (!match) { processCertD1ii(i, policyNodes, pOid, pq); } } } if (acceptablePolicies == null || acceptablePolicies.contains(ANY_POLICY)) { acceptablePolicies = pols; } else { Iterator it = acceptablePolicies.iterator(); Set t1 = new HashSet(); while (it.hasNext()) { Object o = it.next(); if (pols.contains(o)) { t1.add(o); } } acceptablePolicies = t1; } // // (d) (2) // if ((inhibitAnyPolicy > 0) || ((i < n) && isSelfIssued(cert))) { e = certPolicies.getObjects(); while (e.hasMoreElements()) { PolicyInformation pInfo = PolicyInformation.getInstance(e.nextElement()); if (ANY_POLICY.equals(pInfo.getPolicyIdentifier().getId())) { Set _apq = getQualifierSet(pInfo.getPolicyQualifiers()); List _nodes = policyNodes[i - 1]; for (int k = 0; k < _nodes.size(); k++) { PKIXPolicyNode _node = (PKIXPolicyNode)_nodes.get(k); Iterator _policySetIter = _node.getExpectedPolicies().iterator(); while (_policySetIter.hasNext()) { Object _tmp = _policySetIter.next(); String _policy; if (_tmp instanceof String) { _policy = (String)_tmp; } else if (_tmp instanceof DERObjectIdentifier) { _policy = ((DERObjectIdentifier)_tmp).getId(); } else { continue; } boolean _found = false; Iterator _childrenIter = _node.getChildren(); while (_childrenIter.hasNext()) { PKIXPolicyNode _child = (PKIXPolicyNode)_childrenIter.next(); if (_policy.equals(_child.getValidPolicy())) { _found = true; } } if (!_found) { Set _newChildExpectedPolicies = new HashSet(); _newChildExpectedPolicies.add(_policy); PKIXPolicyNode _newChild = new PKIXPolicyNode(new ArrayList(), i, _newChildExpectedPolicies, _node, _apq, _policy, false); _node.addChild(_newChild); policyNodes[i].add(_newChild); } } } break; } } } // // (d) (3) // for (int j = (i - 1); j >= 0; j--) { List nodes = policyNodes[j]; for (int k = 0; k < nodes.size(); k++) { PKIXPolicyNode node = (PKIXPolicyNode)nodes.get(k); if (!node.hasChildren()) { validPolicyTree = removePolicyNode(validPolicyTree, policyNodes, node); if (validPolicyTree == null) { break; } } } } // // d (4) // Set criticalExtensionOids = cert.getCriticalExtensionOIDs(); if (criticalExtensionOids != null) { boolean critical = criticalExtensionOids.contains(CERTIFICATE_POLICIES); List nodes = policyNodes[i]; for (int j = 0; j < nodes.size(); j++) { PKIXPolicyNode node = (PKIXPolicyNode)nodes.get(j); node.setCritical(critical); } } } // // (e) // if (certPolicies == null) { validPolicyTree = null; } // // (f) // if (explicitPolicy <= 0 && validPolicyTree == null) { throw new CertPathValidatorException("No valid policy tree found when one expected."); } // // 6.1.4 // if (i != n) { if (cert != null && cert.getVersion() == 1) { throw new CertPathValidatorException( "Version 1 certs can't be used as CA ones"); } // // // (a) check the policy mappings // ASN1Primitive pm = getExtensionValue(cert, POLICY_MAPPINGS); if (pm != null) { ASN1Sequence mappings = (ASN1Sequence)pm; for (int j = 0; j < mappings.size(); j++) { ASN1Sequence mapping = (ASN1Sequence)mappings.getObjectAt(j); DERObjectIdentifier issuerDomainPolicy = (DERObjectIdentifier)mapping.getObjectAt(0); DERObjectIdentifier subjectDomainPolicy = (DERObjectIdentifier)mapping.getObjectAt(1); if (ANY_POLICY.equals(issuerDomainPolicy.getId())) { throw new CertPathValidatorException("IssuerDomainPolicy is anyPolicy"); } if (ANY_POLICY.equals(subjectDomainPolicy.getId())) { throw new CertPathValidatorException("SubjectDomainPolicy is anyPolicy"); } } } // (b) // if (pm != null) { ASN1Sequence mappings = (ASN1Sequence)pm; Map m_idp = new HashMap(); Set s_idp = new HashSet(); for (int j = 0; j < mappings.size(); j++) { ASN1Sequence mapping = (ASN1Sequence)mappings.getObjectAt(j); String id_p = ((DERObjectIdentifier)mapping.getObjectAt(0)).getId(); String sd_p = ((DERObjectIdentifier)mapping.getObjectAt(1)).getId(); Set tmp; if (!m_idp.containsKey(id_p)) { tmp = new HashSet(); tmp.add(sd_p); m_idp.put(id_p, tmp); s_idp.add(id_p); } else { tmp = (Set)m_idp.get(id_p); tmp.add(sd_p); } } Iterator it_idp = s_idp.iterator(); while (it_idp.hasNext()) { String id_p = (String)it_idp.next(); // // (1) // if (policyMapping > 0) { boolean idp_found = false; Iterator nodes_i = policyNodes[i].iterator(); while (nodes_i.hasNext()) { PKIXPolicyNode node = (PKIXPolicyNode)nodes_i.next(); if (node.getValidPolicy().equals(id_p)) { idp_found = true; node.expectedPolicies = (Set)m_idp.get(id_p); break; } } if (!idp_found) { nodes_i = policyNodes[i].iterator(); while (nodes_i.hasNext()) { PKIXPolicyNode node = (PKIXPolicyNode)nodes_i.next(); if (ANY_POLICY.equals(node.getValidPolicy())) { Set pq = null; ASN1Sequence policies = (ASN1Sequence)getExtensionValue( cert, CERTIFICATE_POLICIES); Enumeration e = policies.getObjects(); while (e.hasMoreElements()) { PolicyInformation pinfo = PolicyInformation.getInstance(e.nextElement()); if (ANY_POLICY.equals(pinfo.getPolicyIdentifier().getId())) { pq = getQualifierSet(pinfo.getPolicyQualifiers()); break; } } boolean ci = false; if (cert.getCriticalExtensionOIDs() != null) { ci = cert.getCriticalExtensionOIDs().contains(CERTIFICATE_POLICIES); } PKIXPolicyNode p_node = (PKIXPolicyNode)node.getParent(); if (ANY_POLICY.equals(p_node.getValidPolicy())) { PKIXPolicyNode c_node = new PKIXPolicyNode( new ArrayList(), i, (Set)m_idp.get(id_p), p_node, pq, id_p, ci); p_node.addChild(c_node); policyNodes[i].add(c_node); } break; } } } // // (2) // } else if (policyMapping <= 0) { Iterator nodes_i = policyNodes[i].iterator(); while (nodes_i.hasNext()) { PKIXPolicyNode node = (PKIXPolicyNode)nodes_i.next(); if (node.getValidPolicy().equals(id_p)) { PKIXPolicyNode p_node = (PKIXPolicyNode)node.getParent(); p_node.removeChild(node); nodes_i.remove(); for (int k = (i - 1); k >= 0; k--) { List nodes = policyNodes[k]; for (int l = 0; l < nodes.size(); l++) { PKIXPolicyNode node2 = (PKIXPolicyNode)nodes.get(l); if (!node2.hasChildren()) { validPolicyTree = removePolicyNode(validPolicyTree, policyNodes, node2); if (validPolicyTree == null) { break; } } } } } } } } } // // (g) handle the name constraints extension // ASN1Sequence ncSeq = (ASN1Sequence)getExtensionValue(cert, NAME_CONSTRAINTS); if (ncSeq != null) { NameConstraints nc = NameConstraints.getInstance(ncSeq); // // (g) (1) permitted subtrees // GeneralSubtree[] permitted = nc.getPermittedSubtrees(); if (permitted != null) { for (int indx = 0; indx != permitted.length; indx++) { GeneralSubtree subtree = permitted[indx]; GeneralName base = subtree.getBase(); switch(base.getTagNo()) { case 1: permittedSubtreesEmail = intersectEmail(permittedSubtreesEmail, DERIA5String.getInstance(base.getName()).getString()); break; case 4: permittedSubtreesDN = intersectDN(permittedSubtreesDN, (ASN1Sequence)base.getName()); break; case 7: permittedSubtreesIP = intersectIP(permittedSubtreesIP, BERConstructedOctetString.fromSequence((ASN1Sequence)base.getName()).getOctets()); break; } } } // // (g) (2) excluded subtrees // GeneralSubtree[] excluded = nc.getExcludedSubtrees(); if (excluded != null) { for (int indx = 0; indx != excluded.length; indx++) { GeneralSubtree subtree = excluded[indx]; GeneralName base = subtree.getBase(); switch(base.getTagNo()) { case 1: excludedSubtreesEmail = unionEmail(excludedSubtreesEmail, DERIA5String.getInstance(base.getName()).getString()); break; case 4: excludedSubtreesDN = unionDN(excludedSubtreesDN, (ASN1Sequence)base.getName()); break; case 7: excludedSubtreesIP = unionIP(excludedSubtreesIP, BERConstructedOctetString.fromSequence((ASN1Sequence)base.getName()).getOctets()); break; } } } } // // (h) // if (!isSelfIssued(cert)) { // // (1) // if (explicitPolicy != 0) { explicitPolicy--; } // // (2) // if (policyMapping != 0) { policyMapping--; } // // (3) // if (inhibitAnyPolicy != 0) { inhibitAnyPolicy--; } } // // (i) // ASN1Sequence pc = (ASN1Sequence)getExtensionValue(cert, POLICY_CONSTRAINTS); if (pc != null) { Enumeration policyConstraints = pc.getObjects(); while (policyConstraints.hasMoreElements()) { ASN1TaggedObject constraint = (ASN1TaggedObject)policyConstraints.nextElement(); switch (constraint.getTagNo()) { case 0: tmpInt = DERInteger.getInstance(constraint).getValue().intValue(); if (tmpInt < explicitPolicy) { explicitPolicy = tmpInt; } break; case 1: tmpInt = DERInteger.getInstance(constraint).getValue().intValue(); if (tmpInt < policyMapping) { policyMapping = tmpInt; } break; } } } // // (j) // DERInteger iap = (DERInteger)getExtensionValue(cert, INHIBIT_ANY_POLICY); if (iap != null) { int _inhibitAnyPolicy = iap.getValue().intValue(); if (_inhibitAnyPolicy < inhibitAnyPolicy) { inhibitAnyPolicy = _inhibitAnyPolicy; } } // // (k) // BasicConstraints bc = BasicConstraints.getInstance( getExtensionValue(cert, BASIC_CONSTRAINTS)); if (bc != null) { if (!(bc.isCA())) { throw new CertPathValidatorException("Not a CA certificate"); } } else { throw new CertPathValidatorException("Intermediate certificate lacks BasicConstraints"); } // // (l) // if (!isSelfIssued(cert)) { if (maxPathLength <= 0) { throw new CertPathValidatorException("Max path length not greater than zero"); } maxPathLength--; } // // (m) // if (bc != null) { BigInteger _pathLengthConstraint = bc.getPathLenConstraint(); if (_pathLengthConstraint != null) { int _plc = _pathLengthConstraint.intValue(); if (_plc < maxPathLength) { maxPathLength = _plc; } } } // // (n) // boolean[] _usage = cert.getKeyUsage(); if ((_usage != null) && !_usage[5]) { throw new CertPathValidatorException( "Issuer certificate keyusage extension is critical an does not permit key signing.\n", null, certPath, index); } // // (o) // Set criticalExtensions = new HashSet(cert.getCriticalExtensionOIDs()); // these extensions are handle by the algorithem criticalExtensions.remove(KEY_USAGE); criticalExtensions.remove(CERTIFICATE_POLICIES); criticalExtensions.remove(POLICY_MAPPINGS); criticalExtensions.remove(INHIBIT_ANY_POLICY); criticalExtensions.remove(ISSUING_DISTRIBUTION_POINT); criticalExtensions.remove(DELTA_CRL_INDICATOR); criticalExtensions.remove(POLICY_CONSTRAINTS); criticalExtensions.remove(BASIC_CONSTRAINTS); criticalExtensions.remove(SUBJECT_ALTERNATIVE_NAME); criticalExtensions.remove(NAME_CONSTRAINTS); tmpIter = pathCheckers.iterator(); while (tmpIter.hasNext()) { try { ((PKIXCertPathChecker)tmpIter.next()).check(cert, criticalExtensions); } catch (CertPathValidatorException e) { throw new CertPathValidatorException(e.getMessage(), e.getCause(), certPath, index); } } if (!criticalExtensions.isEmpty()) { throw new CertPathValidatorException( "Certificate has unsupported critical extension", null, certPath, index); } } // set signing certificate for next round sign = cert; workingPublicKey = sign.getPublicKey(); try { workingIssuerName = getSubjectPrincipal(sign); } catch (IllegalArgumentException ex) { throw new CertPathValidatorException(sign.getSubjectDN().getName() + " :" + ex.toString()); } workingAlgId = getAlgorithmIdentifier(workingPublicKey); workingPublicKeyAlgorithm = workingAlgId.getObjectId(); workingPublicKeyParameters = workingAlgId.getParameters(); } catch (AnnotatedException e) { throw new CertPathValidatorException(e.getMessage(), e.getUnderlyingException(), certPath, index); } } // // 6.1.5 Wrap-up procedure // // // (a) // if (!isSelfIssued(cert) && (explicitPolicy != 0)) { explicitPolicy--; } // // (b) // try { ASN1Sequence pc = (ASN1Sequence)getExtensionValue(cert, POLICY_CONSTRAINTS); if (pc != null) { Enumeration policyConstraints = pc.getObjects(); while (policyConstraints.hasMoreElements()) { ASN1TaggedObject constraint = (ASN1TaggedObject)policyConstraints.nextElement(); switch (constraint.getTagNo()) { case 0: tmpInt = DERInteger.getInstance(constraint).getValue().intValue(); if (tmpInt == 0) { explicitPolicy = 0; } break; } } } } catch (AnnotatedException e) { throw new CertPathValidatorException(e.getMessage(), e.getUnderlyingException(), certPath, index); } // // (c) (d) and (e) are already done // // // (f) // Set criticalExtensions = cert.getCriticalExtensionOIDs(); if (criticalExtensions != null) { criticalExtensions = new HashSet(criticalExtensions); // these extensions are handle by the algorithm criticalExtensions.remove(KEY_USAGE); criticalExtensions.remove(CERTIFICATE_POLICIES); criticalExtensions.remove(POLICY_MAPPINGS); criticalExtensions.remove(INHIBIT_ANY_POLICY); criticalExtensions.remove(ISSUING_DISTRIBUTION_POINT); criticalExtensions.remove(DELTA_CRL_INDICATOR); criticalExtensions.remove(POLICY_CONSTRAINTS); criticalExtensions.remove(BASIC_CONSTRAINTS); criticalExtensions.remove(SUBJECT_ALTERNATIVE_NAME); criticalExtensions.remove(NAME_CONSTRAINTS); } else { criticalExtensions = new HashSet(); } tmpIter = pathCheckers.iterator(); while (tmpIter.hasNext()) { try { ((PKIXCertPathChecker)tmpIter.next()).check(cert, criticalExtensions); } catch (CertPathValidatorException e) { throw new CertPathValidatorException(e.getMessage(), e.getCause(), certPath, index); } } if (!criticalExtensions.isEmpty()) { throw new CertPathValidatorException( "Certificate has unsupported critical extension", null, certPath, index); } // // (g) // PKIXPolicyNode intersection; // // (g) (i) // if (validPolicyTree == null) { if (paramsPKIX.isExplicitPolicyRequired()) { throw new CertPathValidatorException("Explicit policy requested but none available."); } intersection = null; } else if (isAnyPolicy(userInitialPolicySet)) // (g) (ii) { if (paramsPKIX.isExplicitPolicyRequired()) { if (acceptablePolicies.isEmpty()) { throw new CertPathValidatorException("Explicit policy requested but none available."); } else { Set _validPolicyNodeSet = new HashSet(); for (int j = 0; j < policyNodes.length; j++) { List _nodeDepth = policyNodes[j]; for (int k = 0; k < _nodeDepth.size(); k++) { PKIXPolicyNode _node = (PKIXPolicyNode)_nodeDepth.get(k); if (ANY_POLICY.equals(_node.getValidPolicy())) { Iterator _iter = _node.getChildren(); while (_iter.hasNext()) { _validPolicyNodeSet.add(_iter.next()); } } } } Iterator _vpnsIter = _validPolicyNodeSet.iterator(); while (_vpnsIter.hasNext()) { PKIXPolicyNode _node = (PKIXPolicyNode)_vpnsIter.next(); String _validPolicy = _node.getValidPolicy(); if (!acceptablePolicies.contains(_validPolicy)) { //validPolicyTree = removePolicyNode(validPolicyTree, policyNodes, _node); } } if (validPolicyTree != null) { for (int j = (n - 1); j >= 0; j--) { List nodes = policyNodes[j]; for (int k = 0; k < nodes.size(); k++) { PKIXPolicyNode node = (PKIXPolicyNode)nodes.get(k); if (!node.hasChildren()) { validPolicyTree = removePolicyNode(validPolicyTree, policyNodes, node); } } } } } } intersection = validPolicyTree; } else { // // (g) (iii) // // This implementation is not exactly same as the one described in RFC3280. // However, as far as the validation result is concerned, both produce // adequate result. The only difference is whether AnyPolicy is remain // in the policy tree or not. // // (g) (iii) 1 // Set _validPolicyNodeSet = new HashSet(); for (int j = 0; j < policyNodes.length; j++) { List _nodeDepth = policyNodes[j]; for (int k = 0; k < _nodeDepth.size(); k++) { PKIXPolicyNode _node = (PKIXPolicyNode)_nodeDepth.get(k); if (ANY_POLICY.equals(_node.getValidPolicy())) { Iterator _iter = _node.getChildren(); while (_iter.hasNext()) { PKIXPolicyNode _c_node = (PKIXPolicyNode)_iter.next(); if (!ANY_POLICY.equals(_c_node.getValidPolicy())) { _validPolicyNodeSet.add(_c_node); } } } } } // // (g) (iii) 2 // Iterator _vpnsIter = _validPolicyNodeSet.iterator(); while (_vpnsIter.hasNext()) { PKIXPolicyNode _node = (PKIXPolicyNode)_vpnsIter.next(); String _validPolicy = _node.getValidPolicy(); if (!userInitialPolicySet.contains(_validPolicy)) { validPolicyTree = removePolicyNode(validPolicyTree, policyNodes, _node); } } // // (g) (iii) 4 // if (validPolicyTree != null) { for (int j = (n - 1); j >= 0; j--) { List nodes = policyNodes[j]; for (int k = 0; k < nodes.size(); k++) { PKIXPolicyNode node = (PKIXPolicyNode)nodes.get(k); if (!node.hasChildren()) { validPolicyTree = removePolicyNode(validPolicyTree, policyNodes, node); } } } } intersection = validPolicyTree; } if ((explicitPolicy > 0) || (intersection != null)) { return new PKIXCertPathValidatorResult(trust, intersection, workingPublicKey); } throw new CertPathValidatorException("Path processing failed on policy.", null, certPath, index); } private Date getValidDate( PKIXParameters paramsPKIX) { Date validDate = paramsPKIX.getDate(); if (validDate == null) { validDate = new Date(); } return validDate; } private void checkCRLs(PKIXParameters paramsPKIX, X509Certificate cert, Date validDate, X509Certificate sign, PublicKey workingPublicKey) throws AnnotatedException { X509CRLSelector crlselect; crlselect = new X509CRLSelector(); try { crlselect.addIssuerName(getEncodedIssuerPrincipal(cert).getEncoded()); } catch (IOException e) { throw new AnnotatedException("Cannot extract issuer from certificate: " + e, e); } crlselect.setCertificateChecking(cert); Iterator crl_iter = findCRLs(crlselect, paramsPKIX.getCertStores()).iterator(); boolean validCrlFound = false; X509CRLEntry crl_entry; while (crl_iter.hasNext()) { X509CRL crl = (X509CRL)crl_iter.next(); if (cert.getNotAfter().after(crl.getThisUpdate())) { if (crl.getNextUpdate() == null || validDate.before(crl.getNextUpdate())) { validCrlFound = true; } if (sign != null) { boolean[] keyusage = sign.getKeyUsage(); if (keyusage != null && (keyusage.length < 7 || !keyusage[CRL_SIGN])) { throw new AnnotatedException( "Issuer certificate keyusage extension does not permit crl signing.\n" + sign); } } try { crl.verify(workingPublicKey, "BC"); } catch (Exception e) { throw new AnnotatedException("can't verify CRL: " + e, e); } crl_entry = crl.getRevokedCertificate(cert.getSerialNumber()); if (crl_entry != null && !validDate.before(crl_entry.getRevocationDate())) { String reason = null; if (crl_entry.hasExtensions()) { DEREnumerated reasonCode = DEREnumerated.getInstance(getExtensionValue(crl_entry, X509Extensions.ReasonCode.getId())); if (reasonCode != null) { reason = crlReasons[reasonCode.getValue().intValue()]; } } String message = "Certificate revocation after " + crl_entry.getRevocationDate(); if (reason != null) { message += ", reason: " + reason; } throw new AnnotatedException(message); } // // check the DeltaCRL indicator, base point and the issuing distribution point // ASN1Primitive idp = getExtensionValue(crl, ISSUING_DISTRIBUTION_POINT); ASN1Primitive dci = getExtensionValue(crl, DELTA_CRL_INDICATOR); if (dci != null) { X509CRLSelector baseSelect = new X509CRLSelector(); try { baseSelect.addIssuerName(getIssuerPrincipal(crl).getEncoded()); } catch (IOException e) { throw new AnnotatedException("can't extract issuer from certificate: " + e, e); } baseSelect.setMinCRLNumber(((DERInteger)dci).getPositiveValue()); baseSelect.setMaxCRLNumber(((DERInteger)getExtensionValue(crl, CRL_NUMBER)).getPositiveValue().subtract(BigInteger.valueOf(1))); boolean foundBase = false; Iterator it = findCRLs(baseSelect, paramsPKIX.getCertStores()).iterator(); while (it.hasNext()) { X509CRL base = (X509CRL)it.next(); ASN1Primitive baseIdp = getExtensionValue(base, ISSUING_DISTRIBUTION_POINT); if (idp == null) { if (baseIdp == null) { foundBase = true; break; } } else { if (idp.equals(baseIdp)) { foundBase = true; break; } } } if (!foundBase) { throw new AnnotatedException("No base CRL for delta CRL"); } } if (idp != null) { IssuingDistributionPoint p = IssuingDistributionPoint.getInstance(idp); BasicConstraints bc = BasicConstraints.getInstance(getExtensionValue(cert, BASIC_CONSTRAINTS)); if (p.onlyContainsUserCerts() && (bc != null && bc.isCA())) { throw new AnnotatedException("CA Cert CRL only contains user certificates"); } if (p.onlyContainsCACerts() && (bc == null || !bc.isCA())) { throw new AnnotatedException("End CRL only contains CA certificates"); } if (p.onlyContainsAttributeCerts()) { throw new AnnotatedException("onlyContainsAttributeCerts boolean is asserted"); } } } } if (!validCrlFound) { throw new AnnotatedException("no valid CRL found"); } } /** * Return a Collection of all CRLs found in the * CertStore's that are matching the crlSelect criteriums. * * @param certSelector a {@link CertSelector CertSelector} * object that will be used to select the certificates * @param certStores a List containing only {@link CertStore * CertStore} objects. These are used to search for * CRLs * * @return a Collection of all found {@link CRL CRL} * objects. May be empty but never null. */ private Collection findCRLs( X509CRLSelector crlSelect, List crlStores) throws AnnotatedException { Set crls = new HashSet(); Iterator iter = crlStores.iterator(); while (iter.hasNext()) { CertStore certStore = (CertStore)iter.next(); try { crls.addAll(certStore.getCRLs(crlSelect)); } catch (CertStoreException e) { throw new AnnotatedException("cannot extract crl: " + e, e); } } return crls; } /** * Search the given Set of TrustAnchor's for one that is the * issuer of the fiven X509 certificate. * * @param cert the X509 certificate * @param trustAnchors a Set of TrustAnchor's * * @return the TrustAnchor object if found or * null if not. * * @exception CertPathValidatorException if a TrustAnchor was * found but the signature verification on the given certificate * has thrown an exception. This Exception can be obtainted with * getCause() method. **/ final TrustAnchor findTrustAnchor( X509Certificate cert, CertPath certPath, int index, Set trustAnchors) throws CertPathValidatorException { Iterator iter = trustAnchors.iterator(); TrustAnchor trust = null; PublicKey trustPublicKey = null; Exception invalidKeyEx = null; X509CertSelector certSelectX509 = new X509CertSelector(); try { certSelectX509.setSubject(getEncodedIssuerPrincipal(cert).getEncoded()); } catch (IOException ex) { throw new CertPathValidatorException(ex); } catch (AnnotatedException ex) { throw new CertPathValidatorException(ex.getUnderlyingException()); } while (iter.hasNext() && trust == null) { trust = (TrustAnchor)iter.next(); if (trust.getTrustedCert() != null) { if (certSelectX509.match(trust.getTrustedCert())) { trustPublicKey = trust.getTrustedCert().getPublicKey(); } else { trust = null; } } else if (trust.getCAName() != null && trust.getCAPublicKey() != null) { try { X509Principal certIssuer = getEncodedIssuerPrincipal(cert); X509Principal caName = new X509Principal(trust.getCAName()); if (certIssuer.equals(caName)) { trustPublicKey = trust.getCAPublicKey(); } else { trust = null; } } catch (AnnotatedException ex) { throw new CertPathValidatorException(ex.getMessage(), ex.getUnderlyingException(), certPath, index); } catch (IllegalArgumentException ex) { trust = null; } } else { trust = null; } if (trustPublicKey != null) { try { cert.verify(trustPublicKey); } catch (Exception ex) { invalidKeyEx = ex; trust = null; } } } if (trust == null && invalidKeyEx != null) { throw new CertPathValidatorException("TrustAnchor found but certificate validation failed.", invalidKeyEx, certPath, index); } return trust; } private X509Principal getIssuerPrincipal(X509CRL crl) throws AnnotatedException { try { return PrincipalUtil.getIssuerX509Principal(crl); } catch (CRLException e) { throw new AnnotatedException("can't get CRL issuer principal", e); } } private X509Principal getEncodedIssuerPrincipal(X509Certificate cert) throws AnnotatedException { try { return PrincipalUtil.getIssuerX509Principal(cert); } catch (CertificateEncodingException e) { throw new AnnotatedException("can't get issuer principal.", e); } } private X509Principal getSubjectPrincipal(X509Certificate cert) throws AnnotatedException { try { return PrincipalUtil.getSubjectX509Principal(cert); } catch (CertificateEncodingException e) { throw new AnnotatedException("can't get subject principal.", e); } } } bouncycastle-1.49.orig/jdk1.1/org/bouncycastle/jce/provider/X509CertificateObject.java0000644000175000017500000006347712105031243030110 0ustar ebourgebourgpackage org.bouncycastle.jce.provider; import java.io.ByteArrayOutputStream; import java.io.IOException; import java.math.BigInteger; import java.net.InetAddress; import java.net.UnknownHostException; import java.security.InvalidKeyException; import java.security.NoSuchAlgorithmException; import java.security.NoSuchProviderException; import java.security.Principal; import java.security.Provider; import java.security.PublicKey; import java.security.Security; import java.security.Signature; import java.security.SignatureException; import java.security.cert.Certificate; import java.security.cert.CertificateEncodingException; import java.security.cert.CertificateException; import java.security.cert.CertificateExpiredException; import java.security.cert.CertificateNotYetValidException; import java.security.cert.CertificateParsingException; import java.security.cert.X509Certificate; import java.util.ArrayList; import java.util.Collection; import java.util.Collections; import java.util.Date; import java.util.Enumeration; import java.util.HashSet; import java.util.List; import java.util.Set; import org.bouncycastle.asn1.ASN1Encodable; import org.bouncycastle.asn1.ASN1Encoding; import org.bouncycastle.asn1.ASN1InputStream; import org.bouncycastle.asn1.ASN1ObjectIdentifier; import org.bouncycastle.asn1.ASN1OutputStream; import org.bouncycastle.asn1.ASN1Primitive; import org.bouncycastle.asn1.ASN1Sequence; import org.bouncycastle.asn1.ASN1String; import org.bouncycastle.asn1.DERBitString; import org.bouncycastle.asn1.DERIA5String; import org.bouncycastle.asn1.DERNull; import org.bouncycastle.asn1.DEROctetString; import org.bouncycastle.asn1.misc.MiscObjectIdentifiers; import org.bouncycastle.asn1.misc.NetscapeCertType; import org.bouncycastle.asn1.misc.NetscapeRevocationURL; import org.bouncycastle.asn1.misc.VerisignCzagExtension; import org.bouncycastle.asn1.util.ASN1Dump; import org.bouncycastle.asn1.x500.X500Name; import org.bouncycastle.asn1.x500.style.RFC4519Style; import org.bouncycastle.asn1.x509.AlgorithmIdentifier; import org.bouncycastle.asn1.x509.BasicConstraints; import org.bouncycastle.asn1.x509.Extension; import org.bouncycastle.asn1.x509.Extensions; import org.bouncycastle.asn1.x509.GeneralName; import org.bouncycastle.asn1.x509.KeyUsage; import org.bouncycastle.jcajce.provider.asymmetric.util.PKCS12BagAttributeCarrierImpl; import org.bouncycastle.jce.X509Principal; import org.bouncycastle.jce.interfaces.PKCS12BagAttributeCarrier; import org.bouncycastle.util.Arrays; import org.bouncycastle.util.Integers; import org.bouncycastle.util.encoders.Hex; public class X509CertificateObject extends X509Certificate implements PKCS12BagAttributeCarrier { private org.bouncycastle.asn1.x509.Certificate c; private BasicConstraints basicConstraints; private boolean[] keyUsage; private boolean hashValueSet; private int hashValue; private PKCS12BagAttributeCarrier attrCarrier = new PKCS12BagAttributeCarrierImpl(); public X509CertificateObject( org.bouncycastle.asn1.x509.Certificate c) throws CertificateParsingException { this.c = c; try { byte[] bytes = this.getExtensionBytes("2.5.29.19"); if (bytes != null) { basicConstraints = BasicConstraints.getInstance(ASN1Primitive.fromByteArray(bytes)); } } catch (Exception e) { throw new CertificateParsingException("cannot construct BasicConstraints: " + e); } try { byte[] bytes = this.getExtensionBytes("2.5.29.15"); if (bytes != null) { DERBitString bits = DERBitString.getInstance(ASN1Primitive.fromByteArray(bytes)); bytes = bits.getBytes(); int length = (bytes.length * 8) - bits.getPadBits(); keyUsage = new boolean[(length < 9) ? 9 : length]; for (int i = 0; i != length; i++) { keyUsage[i] = (bytes[i / 8] & (0x80 >>> (i % 8))) != 0; } } else { keyUsage = null; } } catch (Exception e) { throw new CertificateParsingException("cannot construct KeyUsage: " + e); } } public void checkValidity() throws CertificateExpiredException, CertificateNotYetValidException { this.checkValidity(new Date()); } public void checkValidity( Date date) throws CertificateExpiredException, CertificateNotYetValidException { if (date.getTime() > this.getNotAfter().getTime()) // for other VM compatibility { throw new CertificateExpiredException("certificate expired on " + c.getEndDate().getTime()); } if (date.getTime() < this.getNotBefore().getTime()) { throw new CertificateNotYetValidException("certificate not valid till " + c.getStartDate().getTime()); } } public int getVersion() { return c.getVersionNumber(); } public BigInteger getSerialNumber() { return c.getSerialNumber().getValue(); } public Principal getIssuerDN() { try { return new X509Principal(X500Name.getInstance(c.getIssuer().getEncoded())); } catch (IOException e) { return null; } } public Principal getSubjectDN() { return new X509Principal(X500Name.getInstance(c.getSubject().toASN1Primitive())); } public Date getNotBefore() { return c.getStartDate().getDate(); } public Date getNotAfter() { return c.getEndDate().getDate(); } public byte[] getTBSCertificate() throws CertificateEncodingException { try { return c.getTBSCertificate().getEncoded(ASN1Encoding.DER); } catch (IOException e) { throw new CertificateEncodingException(e.toString()); } } public byte[] getSignature() { return c.getSignature().getBytes(); } /** * return a more "meaningful" representation for the signature algorithm used in * the certficate. */ public String getSigAlgName() { Provider prov = Security.getProvider(BouncyCastleProvider.PROVIDER_NAME); if (prov != null) { String algName = prov.getProperty("Alg.Alias.Signature." + this.getSigAlgOID()); if (algName != null) { return algName; } } Provider[] provs = Security.getProviders(); // // search every provider looking for a real algorithm // for (int i = 0; i != provs.length; i++) { String algName = provs[i].getProperty("Alg.Alias.Signature." + this.getSigAlgOID()); if (algName != null) { return algName; } } return this.getSigAlgOID(); } /** * return the object identifier for the signature. */ public String getSigAlgOID() { return c.getSignatureAlgorithm().getAlgorithm().getId(); } /** * return the signature parameters, or null if there aren't any. */ public byte[] getSigAlgParams() { if (c.getSignatureAlgorithm().getParameters() != null) { try { return c.getSignatureAlgorithm().getParameters().toASN1Primitive().getEncoded(ASN1Encoding.DER); } catch (IOException e) { return null; } } else { return null; } } public boolean[] getIssuerUniqueID() { DERBitString id = c.getTBSCertificate().getIssuerUniqueId(); if (id != null) { byte[] bytes = id.getBytes(); boolean[] boolId = new boolean[bytes.length * 8 - id.getPadBits()]; for (int i = 0; i != boolId.length; i++) { boolId[i] = (bytes[i / 8] & (0x80 >>> (i % 8))) != 0; } return boolId; } return null; } public boolean[] getSubjectUniqueID() { DERBitString id = c.getTBSCertificate().getSubjectUniqueId(); if (id != null) { byte[] bytes = id.getBytes(); boolean[] boolId = new boolean[bytes.length * 8 - id.getPadBits()]; for (int i = 0; i != boolId.length; i++) { boolId[i] = (bytes[i / 8] & (0x80 >>> (i % 8))) != 0; } return boolId; } return null; } public boolean[] getKeyUsage() { return keyUsage; } public List getExtendedKeyUsage() throws CertificateParsingException { byte[] bytes = this.getExtensionBytes("2.5.29.37"); if (bytes != null) { try { ASN1InputStream dIn = new ASN1InputStream(bytes); ASN1Sequence seq = (ASN1Sequence)dIn.readObject(); List list = new ArrayList(); for (int i = 0; i != seq.size(); i++) { list.add(((ASN1ObjectIdentifier)seq.getObjectAt(i)).getId()); } return Collections.unmodifiableList(list); } catch (Exception e) { throw new CertificateParsingException("error processing extended key usage extension"); } } return null; } public int getBasicConstraints() { if (basicConstraints != null) { if (basicConstraints.isCA()) { if (basicConstraints.getPathLenConstraint() == null) { return Integer.MAX_VALUE; } else { return basicConstraints.getPathLenConstraint().intValue(); } } else { return -1; } } return -1; } public Collection getSubjectAlternativeNames() throws CertificateParsingException { return getAlternativeNames(getExtensionBytes(Extension.subjectAlternativeName.getId())); } public Collection getIssuerAlternativeNames() throws CertificateParsingException { return getAlternativeNames(getExtensionBytes(Extension.issuerAlternativeName.getId())); } public Set getCriticalExtensionOIDs() { if (this.getVersion() == 3) { Set set = new HashSet(); Extensions extensions = c.getTBSCertificate().getExtensions(); if (extensions != null) { Enumeration e = extensions.oids(); while (e.hasMoreElements()) { ASN1ObjectIdentifier oid = (ASN1ObjectIdentifier)e.nextElement(); Extension ext = extensions.getExtension(oid); if (ext.isCritical()) { set.add(oid.getId()); } } return set; } } return null; } private byte[] getExtensionBytes(String oid) { Extensions exts = c.getTBSCertificate().getExtensions(); if (exts != null) { Extension ext = exts.getExtension(new ASN1ObjectIdentifier(oid)); if (ext != null) { return ext.getExtnValue().getOctets(); } } return null; } public byte[] getExtensionValue(String oid) { Extensions exts = c.getTBSCertificate().getExtensions(); if (exts != null) { Extension ext = exts.getExtension(new ASN1ObjectIdentifier(oid)); if (ext != null) { try { return ext.getExtnValue().getEncoded(); } catch (Exception e) { throw new IllegalStateException("error parsing " + e.toString()); } } } return null; } public Set getNonCriticalExtensionOIDs() { if (this.getVersion() == 3) { Set set = new HashSet(); Extensions extensions = c.getTBSCertificate().getExtensions(); if (extensions != null) { Enumeration e = extensions.oids(); while (e.hasMoreElements()) { ASN1ObjectIdentifier oid = (ASN1ObjectIdentifier)e.nextElement(); Extension ext = extensions.getExtension(oid); if (!ext.isCritical()) { set.add(oid.getId()); } } return set; } } return null; } public boolean hasUnsupportedCriticalExtension() { if (this.getVersion() == 3) { Extensions extensions = c.getTBSCertificate().getExtensions(); if (extensions != null) { Enumeration e = extensions.oids(); while (e.hasMoreElements()) { ASN1ObjectIdentifier oid = (ASN1ObjectIdentifier)e.nextElement(); String oidId = oid.getId(); if (oidId.equals(RFC3280CertPathUtilities.KEY_USAGE) || oidId.equals(RFC3280CertPathUtilities.CERTIFICATE_POLICIES) || oidId.equals(RFC3280CertPathUtilities.POLICY_MAPPINGS) || oidId.equals(RFC3280CertPathUtilities.INHIBIT_ANY_POLICY) || oidId.equals(RFC3280CertPathUtilities.CRL_DISTRIBUTION_POINTS) || oidId.equals(RFC3280CertPathUtilities.ISSUING_DISTRIBUTION_POINT) || oidId.equals(RFC3280CertPathUtilities.DELTA_CRL_INDICATOR) || oidId.equals(RFC3280CertPathUtilities.POLICY_CONSTRAINTS) || oidId.equals(RFC3280CertPathUtilities.BASIC_CONSTRAINTS) || oidId.equals(RFC3280CertPathUtilities.SUBJECT_ALTERNATIVE_NAME) || oidId.equals(RFC3280CertPathUtilities.NAME_CONSTRAINTS)) { continue; } Extension ext = extensions.getExtension(oid); if (ext.isCritical()) { return true; } } } } return false; } public PublicKey getPublicKey() { try { return BouncyCastleProvider.getPublicKey(c.getSubjectPublicKeyInfo()); } catch (IOException e) { return null; // should never happen... } } public byte[] getEncoded() throws CertificateEncodingException { try { return c.getEncoded(ASN1Encoding.DER); } catch (IOException e) { throw new CertificateEncodingException(e.toString()); } } public boolean equals( Object o) { if (o == this) { return true; } if (!(o instanceof Certificate)) { return false; } Certificate other = (Certificate)o; try { byte[] b1 = this.getEncoded(); byte[] b2 = other.getEncoded(); return Arrays.areEqual(b1, b2); } catch (CertificateEncodingException e) { return false; } } public synchronized int hashCode() { if (!hashValueSet) { hashValue = calculateHashCode(); hashValueSet = true; } return hashValue; } private int calculateHashCode() { try { int hashCode = 0; byte[] certData = this.getEncoded(); for (int i = 1; i < certData.length; i++) { hashCode += certData[i] * i; } return hashCode; } catch (CertificateEncodingException e) { return 0; } } public void setBagAttribute( ASN1ObjectIdentifier oid, ASN1Encodable attribute) { attrCarrier.setBagAttribute(oid, attribute); } public ASN1Encodable getBagAttribute( ASN1ObjectIdentifier oid) { return attrCarrier.getBagAttribute(oid); } public Enumeration getBagAttributeKeys() { return attrCarrier.getBagAttributeKeys(); } public String toString() { StringBuffer buf = new StringBuffer(); String nl = System.getProperty("line.separator"); buf.append(" [0] Version: ").append(this.getVersion()).append(nl); buf.append(" SerialNumber: ").append(this.getSerialNumber()).append(nl); buf.append(" IssuerDN: ").append(this.getIssuerDN()).append(nl); buf.append(" Start Date: ").append(this.getNotBefore()).append(nl); buf.append(" Final Date: ").append(this.getNotAfter()).append(nl); buf.append(" SubjectDN: ").append(this.getSubjectDN()).append(nl); buf.append(" Public Key: ").append(this.getPublicKey()).append(nl); buf.append(" Signature Algorithm: ").append(this.getSigAlgName()).append(nl); byte[] sig = this.getSignature(); buf.append(" Signature: ").append(new String(Hex.encode(sig, 0, 20))).append(nl); for (int i = 20; i < sig.length; i += 20) { if (i < sig.length - 20) { buf.append(" ").append(new String(Hex.encode(sig, i, 20))).append(nl); } else { buf.append(" ").append(new String(Hex.encode(sig, i, sig.length - i))).append(nl); } } Extensions extensions = c.getTBSCertificate().getExtensions(); if (extensions != null) { Enumeration e = extensions.oids(); if (e.hasMoreElements()) { buf.append(" Extensions: \n"); } while (e.hasMoreElements()) { ASN1ObjectIdentifier oid = (ASN1ObjectIdentifier)e.nextElement(); Extension ext = extensions.getExtension(oid); if (ext.getExtnValue() != null) { byte[] octs = ext.getExtnValue().getOctets(); ASN1InputStream dIn = new ASN1InputStream(octs); buf.append(" critical(").append(ext.isCritical()).append(") "); try { if (oid.equals(Extension.basicConstraints)) { buf.append(BasicConstraints.getInstance(dIn.readObject())).append(nl); } else if (oid.equals(Extension.keyUsage)) { buf.append(KeyUsage.getInstance(dIn.readObject())).append(nl); } else if (oid.equals(MiscObjectIdentifiers.netscapeCertType)) { buf.append(new NetscapeCertType((DERBitString)dIn.readObject())).append(nl); } else if (oid.equals(MiscObjectIdentifiers.netscapeRevocationURL)) { buf.append(new NetscapeRevocationURL((DERIA5String)dIn.readObject())).append(nl); } else if (oid.equals(MiscObjectIdentifiers.verisignCzagExtension)) { buf.append(new VerisignCzagExtension((DERIA5String)dIn.readObject())).append(nl); } else { buf.append(oid.getId()); buf.append(" value = ").append(ASN1Dump.dumpAsString(dIn.readObject())).append(nl); //buf.append(" value = ").append("*****").append(nl); } } catch (Exception ex) { buf.append(oid.getId()); // buf.append(" value = ").append(new String(Hex.encode(ext.getExtnValue().getOctets()))).append(nl); buf.append(" value = ").append("*****").append(nl); } } else { buf.append(nl); } } } return buf.toString(); } public final void verify( PublicKey key) throws CertificateException, NoSuchAlgorithmException, InvalidKeyException, NoSuchProviderException, SignatureException { Signature signature; String sigName = X509SignatureUtil.getSignatureName(c.getSignatureAlgorithm()); try { signature = Signature.getInstance(sigName, BouncyCastleProvider.PROVIDER_NAME); } catch (Exception e) { signature = Signature.getInstance(sigName); } checkSignature(key, signature); } public final void verify( PublicKey key, String sigProvider) throws CertificateException, NoSuchAlgorithmException, InvalidKeyException, NoSuchProviderException, SignatureException { String sigName = X509SignatureUtil.getSignatureName(c.getSignatureAlgorithm()); Signature signature = Signature.getInstance(sigName, sigProvider); checkSignature(key, signature); } private void checkSignature( PublicKey key, Signature signature) throws CertificateException, NoSuchAlgorithmException, SignatureException, InvalidKeyException { if (!isAlgIdEqual(c.getSignatureAlgorithm(), c.getTBSCertificate().getSignature())) { throw new CertificateException("signature algorithm in TBS cert not same as outer cert"); } ASN1Encodable params = c.getSignatureAlgorithm().getParameters(); // TODO This should go after the initVerify? X509SignatureUtil.setSignatureParameters(signature, params); signature.initVerify(key); signature.update(this.getTBSCertificate()); if (!signature.verify(this.getSignature())) { throw new SignatureException("certificate does not verify with supplied key"); } } private boolean isAlgIdEqual(AlgorithmIdentifier id1, AlgorithmIdentifier id2) { if (!id1.getAlgorithm().equals(id2.getAlgorithm())) { return false; } if (id1.getParameters() == null) { if (id2.getParameters() != null && !id2.getParameters().equals(DERNull.INSTANCE)) { return false; } return true; } if (id2.getParameters() == null) { if (id1.getParameters() != null && !id1.getParameters().equals(DERNull.INSTANCE)) { return false; } return true; } return id1.getParameters().equals(id2.getParameters()); } private static Collection getAlternativeNames(byte[] extVal) throws CertificateParsingException { if (extVal == null) { return null; } try { Collection temp = new ArrayList(); Enumeration it = ASN1Sequence.getInstance(extVal).getObjects(); while (it.hasMoreElements()) { GeneralName genName = GeneralName.getInstance(it.nextElement()); List list = new ArrayList(); list.add(Integers.valueOf(genName.getTagNo())); switch (genName.getTagNo()) { case GeneralName.ediPartyName: case GeneralName.x400Address: case GeneralName.otherName: list.add(genName.getEncoded()); break; case GeneralName.directoryName: list.add(X500Name.getInstance(RFC4519Style.INSTANCE, genName.getName()).toString()); break; case GeneralName.dNSName: case GeneralName.rfc822Name: case GeneralName.uniformResourceIdentifier: list.add(((ASN1String)genName.getName()).getString()); break; case GeneralName.registeredID: list.add(ASN1ObjectIdentifier.getInstance(genName.getName()).getId()); break; case GeneralName.iPAddress: byte[] addrBytes = DEROctetString.getInstance(genName.getName()).getOctets(); list.add(addrBytes); break; default: throw new IOException("Bad tag number: " + genName.getTagNo()); } temp.add(list); } if (temp.size() == 0) { return null; } return Collections.unmodifiableCollection(temp); } catch (Exception e) { throw new CertificateParsingException(e.getMessage()); } } } bouncycastle-1.49.orig/jdk1.1/org/bouncycastle/jce/provider/test/0000755000175000017500000000000012152033551024252 5ustar ebourgebourgbouncycastle-1.49.orig/jdk1.1/org/bouncycastle/jce/provider/test/KeyStoreTest.java0000644000175000017500000001341011705654530027532 0ustar ebourgebourgpackage org.bouncycastle.jce.provider.test; import java.io.ByteArrayInputStream; import java.io.ByteArrayOutputStream; import java.math.BigInteger; import java.security.KeyPair; import java.security.KeyPairGenerator; import java.security.KeyStore; import java.security.SecureRandom; import java.security.Security; import java.security.cert.Certificate; import java.security.cert.CertificateFactory; import java.security.cert.X509Certificate; import java.security.interfaces.RSAPrivateKey; import java.security.interfaces.RSAPublicKey; import java.util.Date; import java.util.Hashtable; import org.bouncycastle.jce.X509Principal; import org.bouncycastle.jce.provider.BouncyCastleProvider; import org.bouncycastle.util.test.SimpleTestResult; import org.bouncycastle.util.test.Test; import org.bouncycastle.util.test.TestResult; import org.bouncycastle.x509.X509V3CertificateGenerator; /** * Exercise the various key stores, making sure we at least get back what we put in! *

    * This tests both the BKS, and the UBER key store. */ public class KeyStoreTest implements Test { static char[] passwd = { 'h', 'e', 'l', 'l', 'o', ' ', 'w', 'o', 'r', 'l', 'd' }; public TestResult keyStoreTest( String storeName) { try { KeyStore store = KeyStore.getInstance(storeName, "BC"); store.load(null, null); KeyPairGenerator gen = KeyPairGenerator.getInstance("RSA", "BC"); gen.initialize(1024, new SecureRandom()); KeyPair pair = gen.generateKeyPair(); RSAPrivateKey privKey = (RSAPrivateKey)pair.getPrivate(); RSAPublicKey pubKey = (RSAPublicKey)pair.getPublic(); BigInteger modulus = privKey.getModulus(); BigInteger privateExponent = privKey.getPrivateExponent(); // // distinguished name table. // Hashtable attrs = new Hashtable(); attrs.put(X509Principal.C, "AU"); attrs.put(X509Principal.O, "The Legion of the Bouncy Castle"); attrs.put(X509Principal.L, "Melbourne"); attrs.put(X509Principal.ST, "Victoria"); attrs.put(X509Principal.EmailAddress, "feedback-crypto@bouncycastle.org"); // // extensions // // // create the certificate. // X509V3CertificateGenerator certGen = new X509V3CertificateGenerator(); certGen.setSerialNumber(BigInteger.valueOf(1)); certGen.setIssuerDN(new X509Principal(attrs)); certGen.setNotBefore(new Date(System.currentTimeMillis() - 50000)); certGen.setNotAfter(new Date(System.currentTimeMillis() + 50000)); certGen.setSubjectDN(new X509Principal(attrs)); certGen.setPublicKey(pubKey); certGen.setSignatureAlgorithm("MD5WithRSAEncryption"); Certificate[] chain = new Certificate[1]; try { X509Certificate cert = certGen.generateX509Certificate(privKey); cert.checkValidity(new Date()); cert.verify(pubKey); ByteArrayInputStream bIn = new ByteArrayInputStream(cert.getEncoded()); CertificateFactory fact = CertificateFactory.getInstance("X.509", "BC"); cert = (X509Certificate)fact.generateCertificate(bIn); chain[0] = cert; } catch (Exception e) { return new SimpleTestResult(false, getName() + ": error generating cert - " + e.toString()); } store.setKeyEntry("private", privKey, passwd, chain); // // write out and read back store // ByteArrayOutputStream bOut = new ByteArrayOutputStream(); store.store(bOut, passwd); ByteArrayInputStream bIn = new ByteArrayInputStream(bOut.toByteArray()); // // start with a new key store // store = KeyStore.getInstance(storeName, "BC"); store.load(bIn, passwd); // // verify public key // privKey = (RSAPrivateKey)store.getKey("private", passwd); if (!privKey.getModulus().equals(modulus)) { return new SimpleTestResult(false, getName() + ": private key modulus wrong"); } else if (!privKey.getPrivateExponent().equals(privateExponent)) { return new SimpleTestResult(false, getName() + ": private key exponent wrong"); } // // verify certificate // Certificate cert = store.getCertificateChain("private")[0]; cert.verify(pubKey); return new SimpleTestResult(true, getName() + ": Okay"); } catch (Exception e) { return new SimpleTestResult(false, getName() + ": exception - " + e.toString()); } } public String getName() { return "KeyStore"; } public TestResult perform() { TestResult result = keyStoreTest("BKS"); if (!result.isSuccessful()) { return result; } result = keyStoreTest("UBER"); if (!result.isSuccessful()) { return result; } return new SimpleTestResult(true, getName() + ": Okay"); } public static void main( String[] args) { Security.addProvider(new BouncyCastleProvider()); Test test = new KeyStoreTest(); TestResult result = test.perform(); System.out.println(result.toString()); } } bouncycastle-1.49.orig/jdk1.1/org/bouncycastle/jce/provider/test/MultiCertStoreTest.java0000644000175000017500000000645111705654530030721 0ustar ebourgebourgpackage org.bouncycastle.jce.provider.test; import org.bouncycastle.jce.PrincipalUtil; import org.bouncycastle.jce.MultiCertStoreParameters; import org.bouncycastle.jce.provider.BouncyCastleProvider; import org.bouncycastle.util.test.SimpleTest; import java.io.ByteArrayInputStream; import java.security.Security; import java.security.cert.CertStore; import java.security.cert.CertificateFactory; import java.security.cert.CollectionCertStoreParameters; import java.security.cert.X509CRL; import java.security.cert.X509CertSelector; import java.security.cert.X509Certificate; import java.util.ArrayList; import java.util.Collection; import java.util.List; public class MultiCertStoreTest extends SimpleTest { public void performTest() throws Exception { basicTest(); } private void basicTest() throws Exception { CertificateFactory cf = CertificateFactory.getInstance("X.509", "BC"); X509Certificate rootCert = (X509Certificate)cf .generateCertificate(new ByteArrayInputStream( CertPathTest.rootCertBin)); X509Certificate interCert = (X509Certificate)cf .generateCertificate(new ByteArrayInputStream( CertPathTest.interCertBin)); X509Certificate finalCert = (X509Certificate)cf .generateCertificate(new ByteArrayInputStream( CertPathTest.finalCertBin)); X509CRL rootCrl = (X509CRL)cf.generateCRL(new ByteArrayInputStream( CertPathTest.rootCrlBin)); X509CRL interCrl = (X509CRL)cf .generateCRL(new ByteArrayInputStream( CertPathTest.interCrlBin)); // Testing CollectionCertStore generation from List List list = new ArrayList(); list.add(rootCert); list.add(interCert); list.add(finalCert); list.add(rootCrl); list.add(interCrl); CollectionCertStoreParameters ccsp = new CollectionCertStoreParameters(list); CertStore store1 = CertStore.getInstance("Collection", ccsp, "BC"); CertStore store2 = CertStore.getInstance("Collection", ccsp, "BC"); List storeList = new ArrayList(); storeList.add(store1); storeList.add(store2); CertStore store = CertStore.getInstance("Multi", new MultiCertStoreParameters(storeList)); // Searching for rootCert by subjectDN X509CertSelector targetConstraints = new X509CertSelector(); targetConstraints.setSubject(PrincipalUtil.getSubjectX509Principal(rootCert).getEncoded()); Collection certs = store.getCertificates(targetConstraints); if (certs.size() != 2 || !certs.contains(rootCert)) { fail("2 rootCerts not found by subjectDN"); } store = CertStore.getInstance("Multi", new MultiCertStoreParameters(storeList, false)); certs = store.getCertificates(targetConstraints); if (certs.size() != 1 || !certs.contains(rootCert)) { fail("1 rootCert not found by subjectDN"); } } public String getName() { return "MultiCertStore"; } public static void main(String[] args) { Security.addProvider(new BouncyCastleProvider()); runTest(new MultiCertStoreTest()); } } bouncycastle-1.49.orig/jdk1.1/org/bouncycastle/jce/provider/test/CertPathTest.java0000644000175000017500000001723011705654530027503 0ustar ebourgebourgpackage org.bouncycastle.jce.provider.test; import java.io.ByteArrayInputStream; import java.security.Security; import java.security.cert.CertPath; import java.security.cert.CertificateFactory; import java.security.cert.X509Certificate; import java.util.ArrayList; import java.util.List; import org.bouncycastle.jce.provider.BouncyCastleProvider; import org.bouncycastle.util.encoders.Hex; import org.bouncycastle.util.test.SimpleTestResult; import org.bouncycastle.util.test.Test; import org.bouncycastle.util.test.TestResult; public class CertPathTest implements Test { static byte[] rootCertBin = Hex.decode( "3082023c308201a5a003020102020101300d06092a864886f70d0101040500305c310b300906035504061302415531283026060355040a131f546865204c6567696f6e206f662074686520426f756e637920436173746c6531233021060355040b131a426f756e6379205072696d617279204365727469666963617465301e170d3032303132323133353230385a170d3032303332333133353230385a305c310b300906035504061302415531283026060355040a131f546865204c6567696f6e206f662074686520426f756e637920436173746c6531233021060355040b131a426f756e6379205072696d61727920436572746966696361746530819d300d06092a864886f70d010101050003818b0030818702818100b259d2d6e627a768c94be36164c2d9fc79d97aab9253140e5bf17751197731d6f7540d2509e7b9ffee0a70a6e26d56e92d2edd7f85aba85600b69089f35f6bdbf3c298e05842535d9f064e6b0391cb7d306e0a2d20c4dfb4e7b49a9640bdea26c10ad69c3f05007ce2513cee44cfe01998e62b6c3637d3fc0391079b26ee36d5020111a310300e300c0603551d13040530030101ff300d06092a864886f70d0101040500038181002584a067f9d3e9a02efcf33d9fb870176311ad7741551397a3717cfa71f8724907bdfe9846d25205c9241631df9c0dabd5a980ccdb69fdfcad3694fbe6939f7dffd730d67242400b6fcc9aa718e87f1d7ea58832e4f47d253c7843cc6f4c0a206fb141b959ff639b986cc3470bd576f176cf4d4f402b549ec14e90349b8fb8f5" ); static byte[] interCertBin = Hex.decode( "308202fe30820267a003020102020102300d06092a864886f70d0101040500305c310b300906035504061302415531283026060355040a131f546865204c6567696f6e206f662074686520426f756e637920436173746c6531233021060355040b131a426f756e6379205072696d617279204365727469666963617465301e170d3032303132323133353230395a170d3032303332333133353230395a3061310b300906035504061302415531283026060355040a131f546865204c6567696f6e206f662074686520426f756e637920436173746c6531283026060355040b131f426f756e637920496e7465726d65646961746520436572746966696361746530819f300d06092a864886f70d010101050003818d00308189028181008de0d113c5e736969c8d2b047a243f8fe18edad64cde9e842d3669230ca486f7cfdde1f8eec54d1905fff04acc85e61093e180cadc6cea407f193d44bb0e9449b8dbb49784cd9e36260c39e06a947299978c6ed8300724e887198cfede20f3fbde658fa2bd078be946a392bd349f2b49c486e20c405588e306706c9017308e69020300ffffa381ca3081c7301d0603551d0e041604149408336f3240f78737dad120aaed2ea76ec9c91e3081840603551d23047d307b8014c0361907adc48897a85e726f6b09ebe5e6f1295ca160a45e305c310b300906035504061302415531283026060355040a131f546865204c6567696f6e206f662074686520426f756e637920436173746c6531233021060355040b131a426f756e6379205072696d617279204365727469666963617465820101300c0603551d13040530030101ff301106096086480186f8420101040403020060300d06092a864886f70d010104050003818100a06b166b48c82ba1f81c8f142c14974050266f7b9d003e39e24e53d6f82ce43f4099937aa69b818a5193c5a842521cdb59a44b8837c2caddea70d8e013d6c9fd5e572010ee5cc6894c91783af13909eb53bd79d3c9bf6e268b0c13c41c6b16365287975683ece8a4dad9c8394faf707a00348ed01ac59287734411af4e878486"); static byte[] finalCertBin = Hex.decode( "30820259308201c2a003020102020103300d06092a864886f70d01010405003061310b300906035504061302415531283026060355040a131f546865204c6567696f6e206f662074686520426f756e637920436173746c6531283026060355040b131f426f756e637920496e7465726d656469617465204365727469666963617465301e170d3032303132323133353230395a170d3032303332333133353230395a3065310b300906035504061302415531283026060355040a131f546865204c6567696f6e206f662074686520426f756e637920436173746c6531123010060355040713094d656c626f75726e65311830160603550403130f4572696320482e2045636869646e61305a300d06092a864886f70d01010105000349003046024100b4a7e46170574f16a97082b22be58b6a2a629798419be12872a4bdba626cfae9900f76abfb12139dce5de56564fab2b6543165a040c606887420e33d91ed7ed7020111a3633061301d0603551d0e04160414d06cec6d3583bc55121b0ccb3efed726a6166468301f0603551d230418301680149408336f3240f78737dad120aaed2ea76ec9c91e300c0603551d1304053003010100301106096086480186f8420101040403020001300d06092a864886f70d010104050003818100135db1857d0bb8bf108ce4df2cba4d1cf9e4a4578c0197b4da4e6ddd4c62d25debc5ed0916341aa577caa8eebf21409f065bb94369e3f006536a0a715c429c5888504b84030a181c88cb72fc99c11571d3171f869865cee722af474b5279df9ccd6ec3b04bf0fae272ca15266b74a5ce2d14548a0c76a07b4f97dbc25ed7d0ef"); static byte[] rootCrlBin = Hex.decode( "3082012430818e020101300d06092a864886f70d0101050500305c310b300906035504061302415531283026060355040a131f546865204c6567696f6e206f662074686520426f756e637920436173746c6531233021060355040b131a426f756e6379205072696d617279204365727469666963617465170d3032303132323133353230395a170d3032303332333133353230395a300d06092a864886f70d0101050500038181001255a218c620add68a7a8a561f331d2d510b42515c53f3701f2f49946ff2513a0c6e8e606e3488679f8354dc06a79a84c5233c9c9c9f746bbf4d19e49e730850b3bb7e672d59200d3da12512a91f7bc6f56036250789860ade5b0859a2a8fd24904b271624a544c8e894f293bb0f7018679e3499bf06548618ba473b7852a577"); static byte[] interCrlBin = Hex.decode( "30820129308193020101300d06092a864886f70d01010505003061310b300906035504061302415531283026060355040a131f546865204c6567696f6e206f662074686520426f756e637920436173746c6531283026060355040b131f426f756e637920496e7465726d656469617465204365727469666963617465170d3032303132323133353230395a170d3032303332333133353230395a300d06092a864886f70d01010505000381810046e2743d2faa0a3ed3555fc860a6fed78da96ce967c0db6ec8f40de95ec8cab9c720698d705f1cd8a75a400c0b15f23751cdfd5491abb9d416f0585f425e6802a3612a30cecd593abdcd15c632e0a4e2a7a3049649138ae0367431dd626d079c13c1449058547d796f53660acd5b432e7dacf31315ed3c21eb8948a7c043f418"); public TestResult perform() { try { CertificateFactory cf = CertificateFactory.getInstance("X.509", "BC"); X509Certificate rootCert = (X509Certificate)cf.generateCertificate(new ByteArrayInputStream(rootCertBin)); X509Certificate interCert = (X509Certificate)cf.generateCertificate(new ByteArrayInputStream(interCertBin)); X509Certificate finalCert = (X509Certificate)cf.generateCertificate(new ByteArrayInputStream(finalCertBin)); //Testing CertPath generation from List List list = new ArrayList(); list.add( interCert ); CertPath certPath1 = cf.generateCertPath( list ); //Testing CertPath encoding as PkiPath byte[] encoded = certPath1.getEncoded( "PkiPath" ); //Testing CertPath generation from InputStream ByteArrayInputStream inStream = new ByteArrayInputStream( encoded ); CertPath certPath2 = cf.generateCertPath( inStream, "PkiPath" ); //Comparing both CertPathes if ( ! certPath2.equals( certPath2 ) ) { return new SimpleTestResult( false, this.getName() + ": CertPath differ after encoding and decoding." ); } } catch (Exception e) { return new SimpleTestResult(false, this.getName() + ": exception - " + e.toString()); } return new SimpleTestResult(true, this.getName() + ": Okay"); } public String getName() { return "CertPath"; } public static void main( String[] args) { Security.addProvider(new BouncyCastleProvider()); Test test = new CertPathTest(); TestResult result = test.perform(); System.out.println(result.toString()); } } bouncycastle-1.49.orig/jdk1.1/org/bouncycastle/jce/provider/test/RSATest.java0000644000175000017500000001622611705654530026422 0ustar ebourgebourgpackage org.bouncycastle.jce.provider.test; import java.math.BigInteger; import java.security.KeyFactory; import java.security.PrivateKey; import java.security.PublicKey; import java.security.SecureRandom; import java.security.Security; import java.security.spec.RSAPrivateCrtKeySpec; import java.security.spec.RSAPublicKeySpec; import javax.crypto.Cipher; import org.bouncycastle.jce.provider.BouncyCastleProvider; import org.bouncycastle.util.encoders.Hex; import org.bouncycastle.util.test.SimpleTestResult; import org.bouncycastle.util.test.Test; import org.bouncycastle.util.test.TestResult; public class RSATest implements Test { /** * a fake random number generator - we just want to make sure the random numbers * aren't random so that we get the same output, while still getting to test the * key generation facilities. */ private class FixedSecureRandom extends SecureRandom { byte[] seed = { (byte)0xaa, (byte)0xfd, (byte)0x12, (byte)0xf6, (byte)0x59, (byte)0xca, (byte)0xe6, (byte)0x34, (byte)0x89, (byte)0xb4, (byte)0x79, (byte)0xe5, (byte)0x07, (byte)0x6d, (byte)0xde, (byte)0xc2, (byte)0xf0, (byte)0x6c, (byte)0xb5, (byte)0x8f }; public void nextBytes( byte[] bytes) { int offset = 0; while ((offset + seed.length) < bytes.length) { System.arraycopy(seed, 0, bytes, offset, seed.length); offset += seed.length; } System.arraycopy(seed, 0, bytes, offset, bytes.length - offset); } } private boolean arrayEquals( byte[] a, byte[] b) { if (a.length != b.length) { return false; } for (int i = 0; i != a.length; i++) { if (a[i] != b[i]) { return false; } } return true; } private RSAPublicKeySpec pubKeySpec = new RSAPublicKeySpec( new BigInteger("b4a7e46170574f16a97082b22be58b6a2a629798419be12872a4bdba626cfae9900f76abfb12139dce5de56564fab2b6543165a040c606887420e33d91ed7ed7", 16), new BigInteger("11", 16)); private RSAPrivateCrtKeySpec privKeySpec = new RSAPrivateCrtKeySpec( new BigInteger("b4a7e46170574f16a97082b22be58b6a2a629798419be12872a4bdba626cfae9900f76abfb12139dce5de56564fab2b6543165a040c606887420e33d91ed7ed7", 16), new BigInteger("11", 16), new BigInteger("9f66f6b05410cd503b2709e88115d55daced94d1a34d4e32bf824d0dde6028ae79c5f07b580f5dce240d7111f7ddb130a7945cd7d957d1920994da389f490c89", 16), new BigInteger("c0a0758cdf14256f78d4708c86becdead1b50ad4ad6c5c703e2168fbf37884cb", 16), new BigInteger("f01734d7960ea60070f1b06f2bb81bfac48ff192ae18451d5e56c734a5aab8a5", 16), new BigInteger("b54bb9edff22051d9ee60f9351a48591b6500a319429c069a3e335a1d6171391", 16), new BigInteger("d3d83daf2a0cecd3367ae6f8ae1aeb82e9ac2f816c6fc483533d8297dd7884cd", 16), new BigInteger("b8f52fc6f38593dabb661d3f50f8897f8106eee68b1bce78a95b132b4e5b5d19", 16)); public TestResult perform() { try { KeyFactory fact; byte[] input = new byte[] { (byte)0x54, (byte)0x85, (byte)0x9b, (byte)0x34, (byte)0x2c, (byte)0x49, (byte)0xea, (byte)0x2a }; byte[][] output = new byte[][] { Hex.decode("8b427f781a2e59dd9def386f1956b996ee07f48c96880e65a368055ed8c0a8831669ef7250b40918b2b1d488547e72c84540e42bd07b03f14e226f04fbc2d929"), Hex.decode("2ec6e1a1711b6c7b8cd3f6a25db21ab8bb0a5f1d6df2ef375fa708a43997730ffc7c98856dbbe36edddcdd1b2d2a53867d8355af94fea3aeec128da908e08f4c"), Hex.decode("0850ac4e5a8118323200c8ed1e5aaa3d5e635172553ccac66a8e4153d35c79305c4440f11034ab147fccce21f18a50cf1c0099c08a577eb68237a91042278965") }; SecureRandom rand = new FixedSecureRandom(); fact = KeyFactory.getInstance("RSA", "BC"); PrivateKey privKey = fact.generatePrivate(privKeySpec); PublicKey pubKey = fact.generatePublic(pubKeySpec); // // No Padding // Cipher c = Cipher.getInstance("RSA//NoPadding", "BC"); c.init(Cipher.ENCRYPT_MODE, pubKey, rand); byte[] out = c.doFinal(input); if (!arrayEquals(out, output[0])) { return new SimpleTestResult(false, "NoPadding test failed on encrypt expected " + new String(Hex.encode(output[0])) + " got " + new String(Hex.encode(out))); } c.init(Cipher.DECRYPT_MODE, privKey); out = c.doFinal(out); if (!arrayEquals(out, input)) { return new SimpleTestResult(false, "NoPadding test failed on decrypt expected " + new String(Hex.encode(input)) + " got " + new String(Hex.encode(out))); } // // PKCS1 V 1.5 // c = Cipher.getInstance("RSA//PKCS1Padding", "BC"); c.init(Cipher.ENCRYPT_MODE, pubKey, rand); out = c.doFinal(input); if (!arrayEquals(out, output[1])) { return new SimpleTestResult(false, "PKCS1 test failed on encrypt expected " + new String(Hex.encode(output[1])) + " got " + new String(Hex.encode(out))); } c.init(Cipher.DECRYPT_MODE, privKey); out = c.doFinal(out); if (!arrayEquals(out, input)) { return new SimpleTestResult(false, "PKCS1 test failed on decrypt expected " + new String(Hex.encode(input)) + " got " + new String(Hex.encode(out))); } // // OAEP // c = Cipher.getInstance("RSA//OAEPPadding", "BC"); c.init(Cipher.ENCRYPT_MODE, pubKey, rand); out = c.doFinal(input); if (!arrayEquals(out, output[2])) { return new SimpleTestResult(false, "OAEP test failed on encrypt expected " + new String(Hex.encode(output[2])) + " got " + new String(Hex.encode(out))); } c.init(Cipher.DECRYPT_MODE, privKey); out = c.doFinal(out); if (!arrayEquals(out, input)) { return new SimpleTestResult(false, "OAEP test failed on decrypt expected " + new String(Hex.encode(input)) + " got " + new String(Hex.encode(out))); } return new SimpleTestResult(true, getName() + ": Okay"); } catch (Exception e) { return new SimpleTestResult(false, getName() + ": exception - " + e.toString()); } } public String getName() { return "RSATest"; } public static void main( String[] args) { Security.addProvider(new BouncyCastleProvider()); Test test = new RSATest(); TestResult result = test.perform(); System.out.println(result.toString()); } } bouncycastle-1.49.orig/jdk1.1/org/bouncycastle/jce/provider/test/NetscapeCertRequestTest.java0000644000175000017500000001050411705654530031717 0ustar ebourgebourgpackage org.bouncycastle.jce.provider.test; import java.io.ByteArrayInputStream; import java.io.ByteArrayOutputStream; import java.security.KeyPair; import java.security.KeyPairGenerator; import java.security.Security; import org.bouncycastle.asn1.ASN1InputStream; import org.bouncycastle.asn1.ASN1Sequence; import org.bouncycastle.asn1.DEROutputStream; import org.bouncycastle.asn1.pkcs.PKCSObjectIdentifiers; import org.bouncycastle.asn1.x509.AlgorithmIdentifier; import org.bouncycastle.jce.netscape.NetscapeCertRequest; import org.bouncycastle.jce.provider.BouncyCastleProvider; import org.bouncycastle.util.encoders.Base64; import org.bouncycastle.util.test.SimpleTestResult; import org.bouncycastle.util.test.Test; import org.bouncycastle.util.test.TestResult; /** **/ public class NetscapeCertRequestTest implements Test { /* from NS 4.75 */ static final String test1 = "MIIBRzCBsTCBnzANBgkqhkiG9w0BAQEFAAOBjQAwgYkCgYEAmwdh+LJXQ8AtXczo"+ "4EIGfXjpmDwsoIRpPaXEx1CBHhpon/Dpo/o5Vw2WoWNICXj5lmqhftIpCPO9qKxx"+ "85x6k/fuyTPH8P02hkmscAYsgqOgb/1yRCNXFryuFOATqxw1tsuye5Q3lTU9JCLU"+ "UilQ6BV8n3fm2egtPPUaJEuCvcsCAwEAARYNZml4ZWQtZm9yLW5vdzANBgkqhkiG"+ "9w0BAQQFAAOBgQAImbJD6xHbJtXl6kOTbCFoMnDk7U0o6pHy9l56DYVsiluXegiY"+ "6twB4o7OWsrqTb+gVvzK65FfP+NBVVzxY8UzcjbqC51yvO/9wnpUsIBqD/Gvi1gE"+ "qvw7RHwVEhdzsvLwlL22G8CfDxHnWLww39j8uRJsmoNiKJly3BcsZkLd9g=="; public String getName() { return "NetscapeCertRequest"; } public TestResult perform() { try { String challenge = "fixed-for-now"; byte data [] = Base64.decode (test1); ASN1InputStream in = new ASN1InputStream (new ByteArrayInputStream(data)); ASN1Sequence spkac = (ASN1Sequence)in.readObject (); // System.out.println("SPKAC: \n"+DERDump.dumpAsString (spkac)); NetscapeCertRequest nscr = new NetscapeCertRequest (spkac); if (!nscr.verify (challenge)) { return new SimpleTestResult(false, getName() + ": 1 - not verified"); } //now try to generate one KeyPairGenerator kpg = KeyPairGenerator.getInstance (nscr.getKeyAlgorithm().getObjectId ().getId(), "BC"); kpg.initialize (1024); KeyPair kp = kpg.generateKeyPair(); nscr.setPublicKey (kp.getPublic()); nscr.sign (kp.getPrivate()); ByteArrayOutputStream baos = new ByteArrayOutputStream(); DEROutputStream deros = new DEROutputStream (baos); deros.writeObject (nscr); deros.close(); ASN1InputStream in2 = new ASN1InputStream (new ByteArrayInputStream(baos.toByteArray())); ASN1Sequence spkac2 = (ASN1Sequence)in2.readObject (); // System.out.println("SPKAC2: \n"+DERDump.dumpAsString (spkac2)); NetscapeCertRequest nscr2 = new NetscapeCertRequest (spkac2); if (!nscr2.verify (challenge)) { return new SimpleTestResult(false, getName() + ": 2 - not verified"); } //lets build it from scratch challenge = "try it"; NetscapeCertRequest nscr3 = new NetscapeCertRequest (challenge, new AlgorithmIdentifier(PKCSObjectIdentifiers.sha1WithRSAEncryption, null), kp.getPublic()); nscr3.sign (kp.getPrivate()); // System.out.println("SPKAC3: \n"+DERDump.dumpAsString (nscr3)); if (nscr3.verify (challenge)) { return new SimpleTestResult(true, getName() + ": Okay"); } else { return new SimpleTestResult(false, getName() + ": 3 - not verified"); } } catch (Exception e) { return new SimpleTestResult(false, getName() + ": exception - " + e.toString()); } } public static void main( String[] args) { Security.addProvider(new BouncyCastleProvider()); Test test = new NetscapeCertRequestTest(); TestResult result = test.perform(); System.out.println(result.toString()); } } bouncycastle-1.49.orig/jdk1.1/org/bouncycastle/jce/provider/test/BlockCipherTest.java0000644000175000017500000007665011705654530030171 0ustar ebourgebourgpackage org.bouncycastle.jce.provider.test; import org.bouncycastle.jce.provider.BouncyCastleProvider; import org.bouncycastle.util.encoders.Hex; import org.bouncycastle.util.test.SimpleTest; import javax.crypto.Cipher; import javax.crypto.CipherInputStream; import javax.crypto.CipherOutputStream; import javax.crypto.IllegalBlockSizeException; import javax.crypto.KeyGenerator; import javax.crypto.SecretKey; import javax.crypto.SecretKeyFactory; import javax.crypto.ShortBufferException; import javax.crypto.spec.DESedeKeySpec; import javax.crypto.spec.IvParameterSpec; import javax.crypto.spec.RC2ParameterSpec; import javax.crypto.spec.RC5ParameterSpec; import javax.crypto.spec.SecretKeySpec; import java.io.ByteArrayInputStream; import java.io.ByteArrayOutputStream; import java.io.DataInputStream; import java.io.IOException; import java.security.AlgorithmParameters; import java.security.InvalidAlgorithmParameterException; import java.security.InvalidKeyException; import java.security.InvalidParameterException; import java.security.Key; import java.security.PrivateKey; import java.security.PublicKey; import java.security.SecureRandom; import java.security.Security; import java.security.spec.InvalidKeySpecException; import java.security.spec.KeySpec; /** * basic test class for a block cipher, basically this just exercises the provider, and makes sure we * are behaving sensibly, correctness of the implementation is shown in the lightweight test classes. */ public class BlockCipherTest extends SimpleTest { static String[] cipherTests1 = { "DES", "466da00648ef0e1f9617b1f002e225251a3248d09172f46b9617b1f002e225250112ecb3da61bc99", "DESede", "2f4bc6b30c893fa549d82c560d61cf3eb088aed020603de249d82c560d61cf3e529e95ecd8e05394", "SKIPJACK", "d4de46d52274dbb029f33b076043f8c40089f906751623de29f33b076043f8c4ac99b90f9396cb04", "Blowfish", "7870ebe7f6a52803eb9396ba6c5198216ce81d76d8d4c74beb9396ba6c5198211212473b05214e9f", "Twofish", "70336d9c9718a8a2ced1b19deed973a3c58af7ea71a69e7efc4df082dca581c0839e31468661bcfc57a14899ceeb0253", "RC2", "eb5b889bbcced12eb6b1a3da6a3d965bba66a5edfdd4c8a6b6b1a3da6a3d965b994a5b859e765797", "RC5", "220053543e3eca3bc9503a091ca67b08372560d8a4fdbee8c9503a091ca67b08a796d53bb8a4b7e0", "RC5-64", "e0b4a526ba3bc5f09199c3b1fe3737fe6d248cde70e565b0feea59ebfda375ae1946c386a48d8d8a74d7b1947ff6a788", "RC6", "44c97b67ca8486067f8b6c5b97632f3049e5e52c1d61fdd527dc3da39616540f19a3db39aac1ffd713795cd886cce0c0", "IDEA", "8c9fd56823ffdc523f6ccf7f614aa6173553e594fc7a21b53f6ccf7f614aa61740c54f7a66e95108", "TEA", "fcf45062104fda7c35712368b56dd4216a6ca998dc297b5435712368b56dd421208027ed2923cd0c", "XTEA", "4b427893d3d6aaded2afafabe25f7b233fb5589faa2b6389d2afafabe25f7b239d12979ac67e1c07", "Camellia", "3a68b4ad145bc2c76010669d68f2826359887afce763a78d9994143266adfaec8ba7ee562a1688ef9dfd7f897e5c44dc", "SEED", "d53d4ce1f48b9879420949467bfcbfbe2c6a7d4a8770bee0c71211def898d7c5024ce2007dd85accb3f69d906ae2164d", "Noekeon", "7e68ceb33aad9db04af6b878a16dd6c6b4f880d6c89027ba581884c10690bb6b3dbfd6ed5513e2c4f5670c3528023121", "DES/CBC/NoPadding", "60fa2f8fae5aa2a38e9ac77d0246726beb7511e4515feb12cf99f75cc6e0122a", "DESede/CBC/NoPadding", "4d3d7931875cf25593dc402298add8b914761e4936c9585ae22b2c1441169231", "SKIPJACK/CBC/NoPadding", "ceebcc2e5e2b847f9ed797b4930b95f115b9e6cf49c457fc2ea0df79ad5c8334", "Blowfish/CBC/NoPadding", "80823abbabc109733e7ebf3ce3344d67fc387c306b782086b452f7fbe8e844ce", "Twofish/CBC/NoPadding", "f819694251a00bdd403928745cd1d8a094de61f49ddf8e7692e9d81a83812943", "RC2/CBC/NoPadding", "a51facdb3933c9676795cd38cc3146fd4694722b468b1a979a399c77606abf99", "RC5/CBC/NoPadding", "9ee7517eab0280445f3a7c60c90c0f75029d65bca8b1af83ace5399d388c83c3", "RC6/CBC/NoPadding", "c44695633c07010f3a0d8f7ea046a642d4a96bf4e44f89fd91b46830bc95b130", "IDEA/CBC/NoPadding", "30cd990ebdae80fe12b6c6e4fcd1c064a27d985c276b3d7097351c8684e4c4d9", "DES/CBC/PKCS5Padding", "60fa2f8fae5aa2a38e9ac77d0246726beb7511e4515feb12cf99f75cc6e0122afdc70484fb9c0232", "DES/CBC/ISO10126Padding", "60fa2f8fae5aa2a38e9ac77d0246726beb7511e4515feb12cf99f75cc6e0122a980639850a2cc3e8", "DES/CBC/ISO7816-4Padding", "60fa2f8fae5aa2a38e9ac77d0246726beb7511e4515feb12cf99f75cc6e0122a1f80b9b0f1be49ac", "DES/CBC/X9.23Padding", "60fa2f8fae5aa2a38e9ac77d0246726beb7511e4515feb12cf99f75cc6e0122a980639850a2cc3e8", "DESede/CBC/PKCS7Padding", "4d3d7931875cf25593dc402298add8b914761e4936c9585ae22b2c1441169231a41e40695f1cff84", "SKIPJACK/CBC/PKCS7Padding", "ceebcc2e5e2b847f9ed797b4930b95f115b9e6cf49c457fc2ea0df79ad5c8334df7042de5db89c96", "Blowfish/CBC/PKCS7Padding", "80823abbabc109733e7ebf3ce3344d67fc387c306b782086b452f7fbe8e844cef986562ab1a675e8", "Twofish/CBC/PKCS7Padding", "f819694251a00bdd403928745cd1d8a094de61f49ddf8e7692e9d81a838129433e5f1343d6cdb0b41838619da1541f04", "RC2/CBC/PKCS7Padding", "a51facdb3933c9676795cd38cc3146fd4694722b468b1a979a399c77606abf9958435525f770f137", "RC5/CBC/PKCS7Padding", "9ee7517eab0280445f3a7c60c90c0f75029d65bca8b1af83ace5399d388c83c3edd95ff49be76651", "RC5-64/CBC/PKCS7Padding", "e479fd11f89dab22d2f3dd062b1d2abd5b5962553421a5c562dc7214c3b23b8e21949fda87f2f820e5f032c552c6ec78", "RC6/CBC/PKCS7Padding", "c44695633c07010f3a0d8f7ea046a642d4a96bf4e44f89fd91b46830bc95b130824b972c9019a69d2dd05ef2d36b37ac", "IDEA/CBC/PKCS7Padding", "30cd990ebdae80fe12b6c6e4fcd1c064a27d985c276b3d7097351c8684e4c4d9e584751325ef7c32", "IDEA/CBC/ISO10126Padding", "30cd990ebdae80fe12b6c6e4fcd1c064a27d985c276b3d7097351c8684e4c4d978b3fd73135f033b", "IDEA/CBC/X9.23Padding", "30cd990ebdae80fe12b6c6e4fcd1c064a27d985c276b3d7097351c8684e4c4d978b3fd73135f033b", "AES/CBC/PKCS7Padding", "cf87f4d8bb9d1abb36cdd9f44ead7d046db2f802d99e1ef0a5940f306079e08389a44c4a8cc1a47cbaee1128da55bbb7", "AES/CBC/ISO7816-4Padding", "cf87f4d8bb9d1abb36cdd9f44ead7d046db2f802d99e1ef0a5940f306079e08306d84876508a33efec701118d8eeaf6d", "Rijndael/CBC/PKCS7Padding", "cf87f4d8bb9d1abb36cdd9f44ead7d046db2f802d99e1ef0a5940f306079e08389a44c4a8cc1a47cbaee1128da55bbb7", "Serpent/CBC/PKCS7Padding", "f8940ca31aba8ce1e0693b1ae0b1e08daef6de03c80f019774280052f824ac44540bb8dd74dfad47f83f9c7ec268ca68", "CAST5/CBC/PKCS7Padding", "87b6dc0c5a1d23d42fa740b0548be0b298112000544610d889d6361994cf8e670a19d6af72d7289f", "CAST6/CBC/PKCS7Padding", "943445569cfdda174118e433828f84e137faee38cac5c827d87a3c9a5a46a07dd64e7ad8accd921f248eea627cd6826f", "DES/CBC/WithCTS", "60fa2f8fae5aa2a38e9ac77d0246726bcf99f75cc6e0122aeb7511e4515feb12", "IDEA/CBC/PKCS7Padding", "30cd990ebdae80fe12b6c6e4fcd1c064a27d985c276b3d7097351c8684e4c4d9e584751325ef7c32", "DES/CBC/ZeroBytePadding", "60fa2f8fae5aa2a38e9ac77d0246726beb7511e4515feb12cf99f75cc6e0122ad3b3f002c927f1fd", "DES/CTS/NoPadding", // official style "60fa2f8fae5aa2a38e9ac77d0246726bcf99f75cc6e0122aeb7511e4515feb12", "DESede/CTS/NoPadding", "4d3d7931875cf25593dc402298add8b9e22b2c144116923114761e4936c9585a", "SKIPJACK/CTS/NoPadding", "ceebcc2e5e2b847f9ed797b4930b95f12ea0df79ad5c833415b9e6cf49c457fc", "Blowfish/CTS/NoPadding", "80823abbabc109733e7ebf3ce3344d67b452f7fbe8e844cefc387c306b782086", "Twofish/CTS/NoPadding", "94de61f49ddf8e7692e9d81a83812943f819694251a00bdd403928745cd1d8a0", "AES/CTS/NoPadding", "6db2f802d99e1ef0a5940f306079e083cf87f4d8bb9d1abb36cdd9f44ead7d04", "Rijndael/CTS/NoPadding", "6db2f802d99e1ef0a5940f306079e083cf87f4d8bb9d1abb36cdd9f44ead7d04", "Serpent/CTS/NoPadding", "aef6de03c80f019774280052f824ac44f8940ca31aba8ce1e0693b1ae0b1e08d", "CAST5/CTS/NoPadding", "87b6dc0c5a1d23d42fa740b0548be0b289d6361994cf8e6798112000544610d8", "CAST6/CTS/NoPadding", "37faee38cac5c827d87a3c9a5a46a07d943445569cfdda174118e433828f84e1", "RC2/CTS/NoPadding", "a51facdb3933c9676795cd38cc3146fd9a399c77606abf994694722b468b1a97", "RC5/CTS/NoPadding", "9ee7517eab0280445f3a7c60c90c0f75ace5399d388c83c3029d65bca8b1af83", "RC6/CTS/NoPadding", "d4a96bf4e44f89fd91b46830bc95b130c44695633c07010f3a0d8f7ea046a642", "IDEA/CTS/NoPadding", "30cd990ebdae80fe12b6c6e4fcd1c06497351c8684e4c4d9a27d985c276b3d70", "DES/CBC/WithCTS", // older style "60fa2f8fae5aa2a38e9ac77d0246726bcf99f75cc6e0122aeb7511e4515feb12", "DESede/CBC/WithCTS", "4d3d7931875cf25593dc402298add8b9e22b2c144116923114761e4936c9585a", "SKIPJACK/CBC/WithCTS", "ceebcc2e5e2b847f9ed797b4930b95f12ea0df79ad5c833415b9e6cf49c457fc", "Blowfish/CBC/WithCTS", "80823abbabc109733e7ebf3ce3344d67b452f7fbe8e844cefc387c306b782086", "Twofish/CBC/WithCTS", "94de61f49ddf8e7692e9d81a83812943f819694251a00bdd403928745cd1d8a0", "AES/CBC/WithCTS", "6db2f802d99e1ef0a5940f306079e083cf87f4d8bb9d1abb36cdd9f44ead7d04", "Rijndael/CBC/WithCTS", "6db2f802d99e1ef0a5940f306079e083cf87f4d8bb9d1abb36cdd9f44ead7d04", "Serpent/CBC/WithCTS", "aef6de03c80f019774280052f824ac44f8940ca31aba8ce1e0693b1ae0b1e08d", "CAST5/CBC/WithCTS", "87b6dc0c5a1d23d42fa740b0548be0b289d6361994cf8e6798112000544610d8", "CAST6/CBC/WithCTS", "37faee38cac5c827d87a3c9a5a46a07d943445569cfdda174118e433828f84e1", "RC2/CBC/WithCTS", "a51facdb3933c9676795cd38cc3146fd9a399c77606abf994694722b468b1a97", "RC5/CBC/WithCTS", "9ee7517eab0280445f3a7c60c90c0f75ace5399d388c83c3029d65bca8b1af83", "RC6/CBC/WithCTS", "d4a96bf4e44f89fd91b46830bc95b130c44695633c07010f3a0d8f7ea046a642", "IDEA/CBC/WithCTS", "30cd990ebdae80fe12b6c6e4fcd1c06497351c8684e4c4d9a27d985c276b3d70", "DES/OFB/NoPadding", "537572e480c1714f5c9a4f3b874df824dc6681b1fd6c11982debcad91e3f78b7", "DESede/OFB/NoPadding", "481e9872acea7fcf8e29a453242da774e5f6a28f15f7723659a73e4ff4939f80", "SKIPJACK/OFB/NoPadding", "71143a124e3a0cde753b60fe9b200e559018b6a0fe0682659f7c13feb9df995c", "Blowfish/OFB/NoPadding", "6cd6f7c5d2c655556d7a9e98a1696d1875e9f1b2fc991e28a2d55b56861e80bd", "Twofish/OFB/NoPadding", "821c54b1b54ae113cf74595eefe10c83b61c9682fc81f92c52f39a3a693f88b8", "RC2/OFB/NoPadding", "0a07cb78537cb04c0c74e28a7b86b80f80acadf87d6ef32792f1a8cf74b39f74", "RC5/OFB/NoPadding", "c62b233df296283b918a2b4cc53a54fbf061850e781b97332ed1bd78b88d9670", "IDEA/OFB/NoPadding", "dd447da3cbdcf81f4053fb446596261cb00a3c49a66085485af5f7c10ba20dad", "DES/OFB8/NoPadding", "53cb5010d189f94cf584e5ff1c4a9d86443c45ddb6fa3c2d1a5dadfcdf01db8a", "DESede/OFB8/NoPadding", "482c0c1ccd0e6d218e1cffb0a295352c2357ffaa673f2257ef5c77b6c04f03b5", "SKIPJACK/OFB8/NoPadding", "719ea1b432b3d2c8011e5aa873f95978420022b5e2c9c1a1c1082cd1f4999da2", "Blowfish/OFB8/NoPadding", "6ca6078755b263f09787d830b6fda7b7748494634bdc73ab68540cf9f6b7eccf", "Twofish/OFB8/NoPadding", "825dcec234ad52253d6e064b0d769bc04b1142435933f4a510ffc20d70095a88", "RC2/OFB8/NoPadding", "0aa26c6f6a820fe7d38da97085995ad62e2e293323a76300fcd4eb572810f7c6", "RC5/OFB8/NoPadding", "c601a9074dbd874f4d3293f6a32d93d9f0a4f5685d8597f0102fcc96d444f976", "IDEA/OFB8/NoPadding", "dd7897b6ced43d060a518bb38d570308b83b4de577eb208130daabf619e9b1fb", "DES/CFB/NoPadding", "537572e480c1714fec3c7424f88d4202219244c5ca8f5e4361d64f08fe747bb2", "DESede/CFB/NoPadding", "481e9872acea7fcfb75bb58670fe64c59123265139e357d161cd4ddb5eba042a", "SKIPJACK/CFB/NoPadding", "71143a124e3a0cde70a69ede4ceb14376b1e6a80bafde0a6330508dfa86a7c41", "Blowfish/CFB/NoPadding", "6cd6f7c5d2c6555561167fe9b10665102206869339122f1ed89efa4a985397f6", "Twofish/CFB/NoPadding", "821c54b1b54ae113cf74595eefe10c8308b7a438277de4f40948ac2d172d53d2", "RC2/CFB/NoPadding", "0a07cb78537cb04ca1401450d5cd411c7da7fa5b6baaa17bb2137bd95c9f26a5", "RC5/CFB/NoPadding", "c62b233df296283b989352bbebf616a19e11503ac737f9e0eaf19049cde05d34", "IDEA/CFB/NoPadding", "dd447da3cbdcf81fcbe4661dcbed88aed899f87585118384bd0565067fa6c13a", "DES/CFB8/NoPadding", "53cb0cdff712a825eb283b23c31e7323aa12495e7e751428b5c4eb89b28a25d4", "DESede/CFB8/NoPadding", "482cd5bf87ca4cee0b573d66a077231bfea93843ce2d1f948550a1d208e18279", "SKIPJACK/CFB8/NoPadding", "719eef3906bef23f7b63599285437d8e34183b165acf3e855b4e160d4f036508", "Blowfish/CFB8/NoPadding", "6ca63aaada9188d2410c07513cc0736b9888770768c25a5befc776beea5bdc4c", "Twofish/CFB8/NoPadding", "825d12af040721cf5ed4a4798647837ac5eb14d752aace28728aeb37b2010abd", "RC2/CFB8/NoPadding", "0aa227f94be3a32ff927c5d25647ea41d7c2a1e94012fc7f2ad6767b9664bce5", "RC5/CFB8/NoPadding", "c601cf88725411f119965b9cd38d6c313b91128ed7c98c7604cc62d9b210be79", "IDEA/CFB8/NoPadding", "dd7839d2525420d10f95eec23dbaf3463302c445972a28c563c2635191bc19af", "IDEA/PGPCFB/NoPadding", "dd447da3cbdcf81fcbe4661dcbed88aed899f87585118384bd0565067fa6c13a", "IDEA/PGPCFBwithIv/NoPadding", "ed5adbac0e730cc0f00df7e4f6fef672ab042673106435faf3ecf3996a72a0e127b440ba9e5313501de3", "Twofish/ECB/TBCPadding", "70336d9c9718a8a2ced1b19deed973a3c58af7ea71a69e7efc4df082dca581c019d7daa58d02b89aab6e8c0d17202439", "RC2/ECB/TBCPadding", "eb5b889bbcced12eb6b1a3da6a3d965bba66a5edfdd4c8a6b6b1a3da6a3d965b6b5359ba5e69b179" }; static String[] cipherTests2 = { "DES/OFB64/NoPadding", "537572e480c1714f5c9a4f3b874df824dc6681b1fd6c11982debcad91e", "DES/CFB64/NoPadding", "537572e480c1714fec3c7424f88d4202219244c5ca8f5e4361d64f08fe", "DES/CTR/NoPadding", "537572e480c1714fb47081d35eb18eaca9e0a5aee982f105438a0db6ce", "DES/CTS/NoPadding", "60fa2f8fae5aa2a38e9ac77d0246726b32df660db51a710ceb7511e451" }; static byte[] input1 = Hex.decode("000102030405060708090a0b0c0d0e0fff0102030405060708090a0b0c0d0e0f"); static byte[] input2 = Hex.decode("000102030405060708090a0b0c0d0e0fff0102030405060708090a0b0c"); static RC2ParameterSpec rc2Spec = new RC2ParameterSpec(128, Hex.decode("0123456789abcdef")); static RC5ParameterSpec rc5Spec = new RC5ParameterSpec(16, 16, 32, Hex.decode("0123456789abcdef")); static RC5ParameterSpec rc564Spec = new RC5ParameterSpec(16, 16, 64, Hex.decode("0123456789abcdef0123456789abcdef")); /** * a fake random number generator - we just want to make sure the random numbers * aren't random so that we get the same output, while still getting to test the * key generation facilities. */ private class FixedSecureRandom extends SecureRandom { byte[] seed = { (byte)0xaa, (byte)0xfd, (byte)0x12, (byte)0xf6, (byte)0x59, (byte)0xca, (byte)0xe6, (byte)0x34, (byte)0x89, (byte)0xb4, (byte)0x79, (byte)0xe5, (byte)0x07, (byte)0x6d, (byte)0xde, (byte)0xc2, (byte)0xf0, (byte)0x6c, (byte)0xb5, (byte)0x8f }; public void nextBytes( byte[] bytes) { int offset = 0; while ((offset + seed.length) < bytes.length) { System.arraycopy(seed, 0, bytes, offset, seed.length); offset += seed.length; } System.arraycopy(seed, 0, bytes, offset, bytes.length - offset); } } public String getName() { return "BlockCipher"; } public void test( String algorithm, byte[] input, byte[] output) { Key key = null; KeyGenerator keyGen; SecureRandom rand; Cipher in = null; Cipher out = null; CipherInputStream cIn; CipherOutputStream cOut; ByteArrayInputStream bIn; ByteArrayOutputStream bOut; rand = new FixedSecureRandom(); try { String baseAlgorithm; int index = algorithm.indexOf('/'); if (index > 0) { baseAlgorithm = algorithm.substring(0, index); } else { baseAlgorithm = algorithm; } if (baseAlgorithm.equals("IDEA") & noIDEA()) { return; } keyGen = KeyGenerator.getInstance(baseAlgorithm, "BC"); if (!keyGen.getAlgorithm().equals(baseAlgorithm)) { fail("wrong key generator returned!"); } keyGen.init(rand); key = keyGen.generateKey(); in = Cipher.getInstance(algorithm, "BC"); out = Cipher.getInstance(algorithm, "BC"); if (!in.getAlgorithm().startsWith(baseAlgorithm)) { fail("wrong cipher returned!"); } if (algorithm.startsWith("RC2")) { out.init(Cipher.ENCRYPT_MODE, key, rc2Spec, rand); } else if (algorithm.startsWith("RC5")) { if (algorithm.startsWith("RC5-64")) { out.init(Cipher.ENCRYPT_MODE, key, rc564Spec, rand); } else { out.init(Cipher.ENCRYPT_MODE, key, rc5Spec, rand); } } else { out.init(Cipher.ENCRYPT_MODE, key, rand); } } catch (Exception e) { fail("" + algorithm + " failed initialisation - " + e.toString(), e); } // // grab the iv if there is one // try { if (algorithm.startsWith("RC2")) { in.init(Cipher.DECRYPT_MODE, key, rc2Spec); } else if (algorithm.startsWith("RC5")) { if (algorithm.startsWith("RC5-64")) { in.init(Cipher.DECRYPT_MODE, key, rc564Spec, rand); } else { in.init(Cipher.DECRYPT_MODE, key, rc5Spec, rand); } } else { byte[] iv; iv = out.getIV(); if (iv != null) { try { byte[] nIv = new byte[iv.length - 1]; in.init(Cipher.DECRYPT_MODE, key, new IvParameterSpec(nIv)); fail("failed to pick up short IV"); } catch (InvalidAlgorithmParameterException e) { // ignore - this is what we want... } IvParameterSpec spec; spec = new IvParameterSpec(iv); in.init(Cipher.DECRYPT_MODE, key, spec); } else { in.init(Cipher.DECRYPT_MODE, key); } } } catch (Exception e) { fail("" + algorithm + " failed initialisation - " + e.toString()); } // // encryption pass // bOut = new ByteArrayOutputStream(); cOut = new CipherOutputStream(bOut, out); try { for (int i = 0; i != input.length / 2; i++) { cOut.write(input[i]); } cOut.write(input, input.length / 2, input.length - input.length / 2); cOut.close(); } catch (IOException e) { fail("" + algorithm + " failed encryption - " + e.toString()); } byte[] bytes; bytes = bOut.toByteArray(); if (!areEqual(bytes, output)) { fail("" + algorithm + " failed encryption - expected " + new String(Hex.encode(output)) + " got " + new String(Hex.encode(bytes))); } // // decryption pass // bIn = new ByteArrayInputStream(bytes); cIn = new CipherInputStream(bIn, in); try { DataInputStream dIn = new DataInputStream(cIn); bytes = new byte[input.length]; for (int i = 0; i != input.length / 2; i++) { bytes[i] = (byte)dIn.read(); } dIn.readFully(bytes, input.length / 2, bytes.length - input.length / 2); } catch (Exception e) { fail("" + algorithm + " failed decryption - " + e.toString()); } if (!areEqual(bytes, input)) { fail("" + algorithm + " failed decryption - expected " + new String(Hex.encode(input)) + " got " + new String(Hex.encode(bytes))); } } private boolean noIDEA() { try { Cipher.getInstance("IDEA", "BC"); return false; } catch (Exception e) { return true; } } private void testExceptions() { SecretKeyFactory skF = null; try { skF = SecretKeyFactory.getInstance("DESede", "BC"); } catch (Exception e) { fail("unexpected exception.", e); } KeySpec ks = null; SecretKey secKey = null; byte[] bb = new byte[24]; try { skF.getKeySpec(null, null); fail("failed exception test - no exception thrown"); } catch (InvalidKeySpecException e) { // ignore okay } catch (Exception e) { fail("failed exception test.", e); } try { ks = (KeySpec)new DESedeKeySpec(bb); skF.getKeySpec(null, ks.getClass()); fail("failed exception test - no exception thrown"); } catch (InvalidKeySpecException e) { // ignore okay; } catch (Exception e) { fail("failed exception test.", e); } try { skF.getKeySpec(secKey, null); } catch (InvalidKeySpecException e) { // ignore okay } catch (Exception e) { fail("failed exception test.", e); } try { KeyGenerator kg = KeyGenerator.getInstance("DESede", "BC"); try { kg.init(Integer.MIN_VALUE, new SecureRandom()); fail("failed exception test - no exception thrown"); } catch (InvalidParameterException e) { // ignore okay } catch (Exception e) { fail("failed exception test.", e); } } catch (Exception e) { fail("unexpected exception.", e); } try { skF = SecretKeyFactory.getInstance("DESede", "BC"); try { skF.translateKey(null); fail("failed exception test - no exception thrown"); } catch (InvalidKeyException e) { // ignore okay } catch (Exception e) { fail("failed exception test.", e); } } catch (Exception e) { fail("unexpected exception.", e); } try { byte[] rawDESKey = { (byte)128, (byte)131, (byte)133, (byte)134, (byte)137, (byte)138, (byte)140, (byte)143 }; SecretKeySpec cipherKey = new SecretKeySpec(rawDESKey, "DES"); Cipher cipher = Cipher.getInstance("DES/CBC/NoPadding", "BC"); try { // According specification engineInit(int opmode, Key key, // SecureRandom random) throws InvalidKeyException if this // cipher is being // initialized for decryption and requires algorithm parameters // that cannot be determined from the given key cipher.init(Cipher.DECRYPT_MODE, cipherKey, (SecureRandom)null); fail("failed exception test - no InvalidKeyException thrown"); } catch (InvalidKeyException e) { // ignore } } catch (Exception e) { fail("unexpected exception.", e); } try { byte[] rawDESKey = { -128, -125, -123, -122, -119, -118 }; SecretKeySpec cipherKey = new SecretKeySpec(rawDESKey, "DES"); Cipher cipher = Cipher.getInstance("DES/ECB/NoPadding", "BC"); try { // According specification engineInit(int opmode, Key key, // SecureRandom random) throws InvalidKeyException if the given // key is inappropriate for initializing this cipher cipher.init(Cipher.ENCRYPT_MODE, cipherKey); fail("failed exception test - no InvalidKeyException thrown"); } catch (InvalidKeyException e) { // ignore } } catch (Exception e) { fail("unexpected exception.", e); } try { byte[] rawDESKey = { -128, -125, -123, -122, -119, -118, -117, -115, -114 }; SecretKeySpec cipherKey = new SecretKeySpec(rawDESKey, "DES"); Cipher cipher = Cipher.getInstance("DES/ECB/NoPadding", "BC"); try { // According specification engineInit(int opmode, Key key, // SecureRandom random) throws InvalidKeyException if the given // key is inappropriate for initializing this cipher cipher.init(Cipher.ENCRYPT_MODE, cipherKey); fail("failed exception test - no InvalidKeyException thrown"); } catch (InvalidKeyException e) { // ignore } } catch (Exception e) { fail("unexpected exception.", e); } try { byte[] rawDESKey = { (byte)128, (byte)131, (byte)133, (byte)134, (byte)137, (byte)138, (byte)140, (byte)143 }; SecretKeySpec cipherKey = new SecretKeySpec(rawDESKey, "DES"); Cipher ecipher = Cipher.getInstance("DES/ECB/PKCS5Padding", "BC"); ecipher.init(Cipher.ENCRYPT_MODE, cipherKey); byte[] cipherText = new byte[0]; try { // According specification Method engineUpdate(byte[] input, // int inputOffset, int inputLen, byte[] output, int // outputOffset) // throws ShortBufferException - if the given output buffer is // too // small to hold the result ecipher.update(new byte[20], 0, 20, cipherText); fail("failed exception test - no ShortBufferException thrown"); } catch (ShortBufferException e) { // ignore } } catch (Exception e) { fail("unexpected exception.", e); } try { KeyGenerator keyGen = KeyGenerator.getInstance("DES", "BC"); keyGen.init((SecureRandom)null); // According specification engineGenerateKey() doesn't throw any exceptions. SecretKey key = keyGen.generateKey(); if (key == null) { fail("key is null!"); } } catch (Exception e) { fail("unexpected exception.", e); } try { try { Cipher c = Cipher.getInstance("DES", "BC"); Key k = new PublicKey() { public String getAlgorithm() { return "STUB"; } public String getFormat() { return null; } public byte[] getEncoded() { return null; } }; c.init(Cipher.ENCRYPT_MODE, k); fail("failed exception test - no InvalidKeyException thrown for public key"); } catch (InvalidKeyException e) { // okay } try { Cipher c = Cipher.getInstance("DES", "BC"); Key k = new PrivateKey() { public String getAlgorithm() { return "STUB"; } public String getFormat() { return null; } public byte[] getEncoded() { return null; } }; c.init(Cipher.DECRYPT_MODE, k); fail("failed exception test - no InvalidKeyException thrown for private key"); } catch (InvalidKeyException e) { // okay } } catch (Exception e) { fail("unexpected exception.", e); } } public void performTest() { for (int i = 0; i != cipherTests1.length; i += 2) { test(cipherTests1[i], input1, Hex.decode(cipherTests1[i + 1])); } for (int i = 0; i != cipherTests2.length; i += 2) { test(cipherTests2[i], input2, Hex.decode(cipherTests2[i + 1])); } // // check for less than a block // try { Cipher c = Cipher.getInstance("AES/CTS/NoPadding", "BC"); c.init(Cipher.ENCRYPT_MODE, new SecretKeySpec(new byte[16], "AES")); c.doFinal(new byte[4]); fail("CTS failed to throw exception"); } catch (Exception e) { if (!(e instanceof IllegalBlockSizeException)) { fail("CTS exception test - " + e, e); } } testExceptions(); } public static void main( String[] args) { Security.addProvider(new BouncyCastleProvider()); runTest(new BlockCipherTest()); } } bouncycastle-1.49.orig/jdk1.1/org/bouncycastle/jce/provider/test/CertStoreTest.java0000644000175000017500000001203511705654530027701 0ustar ebourgebourgpackage org.bouncycastle.jce.provider.test; import java.io.ByteArrayInputStream; import java.security.Security; import java.security.cert.CertStore; import java.security.cert.CertificateFactory; import java.security.cert.CollectionCertStoreParameters; import java.security.cert.X509CRL; import java.security.cert.X509CRLSelector; import java.security.cert.X509CertSelector; import java.security.cert.X509Certificate; import java.util.ArrayList; import java.util.Collection; import java.util.List; import org.bouncycastle.jce.X509Principal; import org.bouncycastle.jce.provider.BouncyCastleProvider; import org.bouncycastle.util.test.SimpleTestResult; import org.bouncycastle.util.test.Test; import org.bouncycastle.util.test.TestResult; public class CertStoreTest implements Test { public TestResult perform() { try { CertificateFactory cf = CertificateFactory.getInstance("X.509", "BC"); X509Certificate rootCert = (X509Certificate)cf.generateCertificate(new ByteArrayInputStream(CertPathTest.rootCertBin)); X509Certificate interCert = (X509Certificate)cf.generateCertificate(new ByteArrayInputStream(CertPathTest.interCertBin)); X509Certificate finalCert = (X509Certificate)cf.generateCertificate(new ByteArrayInputStream(CertPathTest.finalCertBin)); X509CRL rootCrl = (X509CRL)cf.generateCRL(new ByteArrayInputStream(CertPathTest.rootCrlBin)); X509CRL interCrl = (X509CRL)cf.generateCRL(new ByteArrayInputStream(CertPathTest.interCrlBin)); //Testing CollectionCertStore generation from List List list = new ArrayList(); list.add( rootCert ); list.add( interCert ); list.add( finalCert ); list.add( rootCrl ); list.add( interCrl ); CollectionCertStoreParameters ccsp = new CollectionCertStoreParameters( list ); CertStore store = CertStore.getInstance("Collection", ccsp ); //Searching for rootCert by subjectDN X509CertSelector targetConstraints = new X509CertSelector(); targetConstraints.setSubject(rootCert.getSubjectDN().getName()); Collection certs = store.getCertificates( targetConstraints ); if ( certs.size() != 1 || ! certs.contains( rootCert ) ) { return new SimpleTestResult( false, this.getName() + ": rootCert not found by subjectDN" ); } //Searching for rootCert by subjectDN encoded as byte targetConstraints = new X509CertSelector(); targetConstraints.setSubject(((X509Principal)rootCert.getSubjectDN()).getEncoded()); certs = store.getCertificates( targetConstraints ); if ( certs.size() != 1 || ! certs.contains( rootCert ) ) { return new SimpleTestResult( false, this.getName() + ": rootCert not found by encoded subjectDN" ); } //Searching for rootCert by public key encoded as byte targetConstraints = new X509CertSelector(); targetConstraints.setSubjectPublicKey(rootCert.getPublicKey().getEncoded()); certs = store.getCertificates( targetConstraints ); if ( certs.size() != 1 || ! certs.contains( rootCert ) ) { return new SimpleTestResult( false, this.getName() + ": rootCert not found by encoded public key" ); } //Searching for interCert by issuerDN targetConstraints = new X509CertSelector(); targetConstraints.setIssuer( ((X509Principal)rootCert.getSubjectDN()).getEncoded() ); certs = store.getCertificates( targetConstraints ); if ( certs.size() != 2 ) { return new SimpleTestResult( false, this.getName() + ": did not found 2 certs" ); } if ( ! certs.contains( rootCert ) ) { return new SimpleTestResult( false, this.getName() + ": rootCert not found" ); } if ( ! certs.contains( interCert ) ) { return new SimpleTestResult( false, this.getName() + ": interCert not found" ); } //Searching for rootCrl by issuerDN X509CRLSelector targetConstraintsCRL = new X509CRLSelector(); targetConstraintsCRL.addIssuerName( ((X509Principal)rootCrl.getIssuerDN()).getEncoded() ); Collection crls = store.getCRLs( targetConstraintsCRL ); if ( crls.size() != 1 || ! crls.contains( rootCrl ) ) { return new SimpleTestResult( false, this.getName() + ": rootCrl not found" ); } } catch (Exception e) { e.printStackTrace(); return new SimpleTestResult(false, this.getName() + ": exception - " + e.toString()); } return new SimpleTestResult(true, this.getName() + ": Okay"); } public String getName() { return "CertStore"; } public static void main(String[] args) { Security.addProvider(new BouncyCastleProvider()); Test test = new CertStoreTest(); TestResult result = test.perform(); System.out.println(result.toString()); } } bouncycastle-1.49.orig/jdk1.1/org/bouncycastle/jce/provider/test/CertPathBuilderTest.java0000644000175000017500000000614211705654530031012 0ustar ebourgebourgpackage org.bouncycastle.jce.provider.test; import java.io.ByteArrayInputStream; import java.security.Security; import java.security.cert.*; import java.util.ArrayList; import java.util.Calendar; import java.util.HashSet; import java.util.List; import java.util.Set; import org.bouncycastle.jce.X509Principal; import org.bouncycastle.jce.provider.BouncyCastleProvider; import org.bouncycastle.util.test.SimpleTestResult; import org.bouncycastle.util.test.Test; import org.bouncycastle.util.test.TestResult; public class CertPathBuilderTest implements Test { public TestResult perform() { try { CertificateFactory cf = CertificateFactory.getInstance("X.509", "BC"); // initialise CertStore X509Certificate rootCert = (X509Certificate)cf.generateCertificate(new ByteArrayInputStream(CertPathTest.rootCertBin)); X509Certificate interCert = (X509Certificate)cf.generateCertificate(new ByteArrayInputStream(CertPathTest.interCertBin)); X509Certificate finalCert = (X509Certificate)cf.generateCertificate(new ByteArrayInputStream(CertPathTest.finalCertBin)); X509CRL rootCrl = (X509CRL)cf.generateCRL(new ByteArrayInputStream(CertPathTest.rootCrlBin)); X509CRL interCrl = (X509CRL)cf.generateCRL(new ByteArrayInputStream(CertPathTest.interCrlBin)); List list = new ArrayList(); list.add( rootCert ); list.add( interCert ); list.add( finalCert ); list.add( rootCrl ); list.add( interCrl ); CollectionCertStoreParameters ccsp = new CollectionCertStoreParameters( list ); CertStore store = CertStore.getInstance("Collection", ccsp ); Calendar validDate = Calendar.getInstance(); validDate.set(2002,2,21,2,21,10); //Searching for rootCert by subjectDN without CRL Set trust = new HashSet(); trust.add( new TrustAnchor( rootCert, null ) ); CertPathBuilder cpb = CertPathBuilder.getInstance("PKIX","BC"); X509CertSelector targetConstraints = new X509CertSelector(); targetConstraints.setSubject(((X509Principal)rootCert.getSubjectDN()).getEncoded()); PKIXBuilderParameters params = new PKIXBuilderParameters( trust, targetConstraints ); params.addCertStore( store ); params.setDate( validDate.getTime() ); PKIXCertPathBuilderResult result = (PKIXCertPathBuilderResult) cpb.build(params); } catch (Exception e) { e.printStackTrace(); return new SimpleTestResult(false, this.getName() + ": exception - " + e.toString()); } return new SimpleTestResult(true, this.getName() + ": Okay"); } public String getName() { return "CertPathBuilder"; } public static void main( String[] args) { Security.addProvider(new BouncyCastleProvider()); Test test = new CertPathBuilderTest(); TestResult result = test.perform(); System.out.println(result.toString()); } } bouncycastle-1.49.orig/jdk1.1/org/bouncycastle/jce/provider/test/CertPathValidatorTest.java0000644000175000017500000000635211705654530031354 0ustar ebourgebourgpackage org.bouncycastle.jce.provider.test; import java.io.ByteArrayInputStream; import java.security.PublicKey; import java.security.Security; import java.security.cert.*; import java.util.ArrayList; import java.util.Calendar; import java.util.HashSet; import java.util.List; import java.util.Set; import org.bouncycastle.jce.provider.BouncyCastleProvider; import org.bouncycastle.util.test.SimpleTestResult; import org.bouncycastle.util.test.Test; import org.bouncycastle.util.test.TestResult; public class CertPathValidatorTest implements Test { public TestResult perform() { try { CertificateFactory cf = CertificateFactory.getInstance("X.509", "BC"); // initialise CertStore X509Certificate rootCert = (X509Certificate)cf.generateCertificate(new ByteArrayInputStream(CertPathTest.rootCertBin)); X509Certificate interCert = (X509Certificate)cf.generateCertificate(new ByteArrayInputStream(CertPathTest.interCertBin)); X509Certificate finalCert = (X509Certificate)cf.generateCertificate(new ByteArrayInputStream(CertPathTest.finalCertBin)); X509CRL rootCrl = (X509CRL)cf.generateCRL(new ByteArrayInputStream(CertPathTest.rootCrlBin)); X509CRL interCrl = (X509CRL)cf.generateCRL(new ByteArrayInputStream(CertPathTest.interCrlBin)); List list = new ArrayList(); list.add( rootCert ); list.add( interCert ); list.add( finalCert ); list.add( rootCrl ); list.add( interCrl ); CollectionCertStoreParameters ccsp = new CollectionCertStoreParameters( list ); CertStore store = CertStore.getInstance("Collection", ccsp ); Calendar validDate = Calendar.getInstance(); validDate.set(2002,2,21,2,21,10); //validating path List certchain = new ArrayList(); certchain.add( finalCert ); certchain.add( interCert ); CertPath cp = CertificateFactory.getInstance("X.509","BC").generateCertPath( certchain ); Set trust = new HashSet(); trust.add( new TrustAnchor( rootCert, null ) ); CertPathValidator cpv = CertPathValidator.getInstance("PKIX","BC"); PKIXParameters param = new PKIXParameters( trust ); param.addCertStore(store); param.setDate( validDate.getTime() ); PKIXCertPathValidatorResult result = (PKIXCertPathValidatorResult) cpv.validate(cp, param); PolicyNode policyTree = result.getPolicyTree(); PublicKey subjectPublicKey = result.getPublicKey(); } catch (Exception e) { e.printStackTrace(); return new SimpleTestResult(false, this.getName() + ": exception - " + e.toString()); } return new SimpleTestResult(true, this.getName() + ": Okay"); } public String getName() { return "CertPathValidator"; } public static void main( String[] args) { Security.addProvider(new BouncyCastleProvider()); Test test = new CertPathValidatorTest(); TestResult result = test.perform(); System.out.println(result.toString()); } } bouncycastle-1.49.orig/jdk1.1/org/bouncycastle/jce/provider/test/RegressionTest.java0000644000175000017500000000227111705654530030110 0ustar ebourgebourgpackage org.bouncycastle.jce.provider.test; import java.security.Security; import org.bouncycastle.jce.provider.BouncyCastleProvider; import org.bouncycastle.util.test.SimpleTestResult; import org.bouncycastle.util.test.Test; import org.bouncycastle.util.test.TestResult; public class RegressionTest { public static Test[] tests = { new FIPSDESTest(), new BlockCipherTest(), new MacTest(), new SealedTest(), new RSATest(), new SigTest(), new CertTest(), new KeyStoreTest(), new DigestTest(), new WrapTest(), new CertPathTest(), new CertStoreTest(), new CertPathValidatorTest(), new CertPathBuilderTest() }; public static void main( String[] args) { Security.addProvider(new BouncyCastleProvider()); for (int i = 0; i != tests.length; i++) { TestResult result = tests[i].perform(); if (((SimpleTestResult)result).getException() != null) { ((SimpleTestResult)result).getException().printStackTrace(); } System.out.println(result); } } } bouncycastle-1.49.orig/jdk1.1/org/bouncycastle/jce/provider/test/CertTest.java0000644000175000017500000016275311705654530026701 0ustar ebourgebourgpackage org.bouncycastle.jce.provider.test; import java.io.ByteArrayInputStream; import java.math.BigInteger; import java.security.KeyFactory; import java.security.KeyPair; import java.security.KeyPairGenerator; import java.security.PrivateKey; import java.security.PublicKey; import java.security.SecureRandom; import java.security.Security; import java.security.cert.CRL; import java.security.cert.Certificate; import java.security.cert.CertificateFactory; import java.security.cert.X509Certificate; import java.security.spec.RSAPrivateCrtKeySpec; import java.security.spec.RSAPublicKeySpec; import java.util.Date; import java.util.Hashtable; import java.util.Set; import java.util.Vector; import org.bouncycastle.asn1.ASN1InputStream; import org.bouncycastle.asn1.DERSequence; import org.bouncycastle.asn1.x509.GeneralName; import org.bouncycastle.asn1.x509.GeneralNames; import org.bouncycastle.asn1.x509.KeyPurposeId; import org.bouncycastle.jce.X509KeyUsage; import org.bouncycastle.jce.X509Principal; import org.bouncycastle.jce.interfaces.ECPointEncoder; import org.bouncycastle.jce.provider.BouncyCastleProvider; import org.bouncycastle.jce.spec.ECParameterSpec; import org.bouncycastle.jce.spec.ECPrivateKeySpec; import org.bouncycastle.jce.spec.ECPublicKeySpec; import org.bouncycastle.math.ec.ECCurve; import org.bouncycastle.util.encoders.Base64; import org.bouncycastle.util.encoders.Hex; import org.bouncycastle.util.test.SimpleTestResult; import org.bouncycastle.util.test.Test; import org.bouncycastle.util.test.TestResult; import org.bouncycastle.x509.X509V1CertificateGenerator; import org.bouncycastle.x509.X509V3CertificateGenerator; public class CertTest implements Test { // // server.crt // byte[] cert1 = Base64.decode( "MIIDXjCCAsegAwIBAgIBBzANBgkqhkiG9w0BAQQFADCBtzELMAkGA1UEBhMCQVUx" + "ETAPBgNVBAgTCFZpY3RvcmlhMRgwFgYDVQQHEw9Tb3V0aCBNZWxib3VybmUxGjAY" + "BgNVBAoTEUNvbm5lY3QgNCBQdHkgTHRkMR4wHAYDVQQLExVDZXJ0aWZpY2F0ZSBB" + "dXRob3JpdHkxFTATBgNVBAMTDENvbm5lY3QgNCBDQTEoMCYGCSqGSIb3DQEJARYZ" + "d2VibWFzdGVyQGNvbm5lY3Q0LmNvbS5hdTAeFw0wMDA2MDIwNzU2MjFaFw0wMTA2" + "MDIwNzU2MjFaMIG4MQswCQYDVQQGEwJBVTERMA8GA1UECBMIVmljdG9yaWExGDAW" + "BgNVBAcTD1NvdXRoIE1lbGJvdXJuZTEaMBgGA1UEChMRQ29ubmVjdCA0IFB0eSBM" + "dGQxFzAVBgNVBAsTDldlYnNlcnZlciBUZWFtMR0wGwYDVQQDExR3d3cyLmNvbm5l" + "Y3Q0LmNvbS5hdTEoMCYGCSqGSIb3DQEJARYZd2VibWFzdGVyQGNvbm5lY3Q0LmNv" + "bS5hdTCBnzANBgkqhkiG9w0BAQEFAAOBjQAwgYkCgYEArvDxclKAhyv7Q/Wmr2re" + "Gw4XL9Cnh9e+6VgWy2AWNy/MVeXdlxzd7QAuc1eOWQkGQEiLPy5XQtTY+sBUJ3AO" + "Rvd2fEVJIcjf29ey7bYua9J/vz5MG2KYo9/WCHIwqD9mmG9g0xLcfwq/s8ZJBswE" + "7sb85VU+h94PTvsWOsWuKaECAwEAAaN3MHUwJAYDVR0RBB0wG4EZd2VibWFzdGVy" + "QGNvbm5lY3Q0LmNvbS5hdTA6BglghkgBhvhCAQ0ELRYrbW9kX3NzbCBnZW5lcmF0" + "ZWQgY3VzdG9tIHNlcnZlciBjZXJ0aWZpY2F0ZTARBglghkgBhvhCAQEEBAMCBkAw" + "DQYJKoZIhvcNAQEEBQADgYEAotccfKpwSsIxM1Hae8DR7M/Rw8dg/RqOWx45HNVL" + "iBS4/3N/TO195yeQKbfmzbAA2jbPVvIvGgTxPgO1MP4ZgvgRhasaa0qCJCkWvpM4" + "yQf33vOiYQbpv4rTwzU8AmRlBG45WdjyNIigGV+oRc61aKCTnLq7zB8N3z1TF/bF" + "5/8="); // // ca.crt // byte[] cert2 = Base64.decode( "MIIDbDCCAtWgAwIBAgIBADANBgkqhkiG9w0BAQQFADCBtzELMAkGA1UEBhMCQVUx" + "ETAPBgNVBAgTCFZpY3RvcmlhMRgwFgYDVQQHEw9Tb3V0aCBNZWxib3VybmUxGjAY" + "BgNVBAoTEUNvbm5lY3QgNCBQdHkgTHRkMR4wHAYDVQQLExVDZXJ0aWZpY2F0ZSBB" + "dXRob3JpdHkxFTATBgNVBAMTDENvbm5lY3QgNCBDQTEoMCYGCSqGSIb3DQEJARYZ" + "d2VibWFzdGVyQGNvbm5lY3Q0LmNvbS5hdTAeFw0wMDA2MDIwNzU1MzNaFw0wMTA2" + "MDIwNzU1MzNaMIG3MQswCQYDVQQGEwJBVTERMA8GA1UECBMIVmljdG9yaWExGDAW" + "BgNVBAcTD1NvdXRoIE1lbGJvdXJuZTEaMBgGA1UEChMRQ29ubmVjdCA0IFB0eSBM" + "dGQxHjAcBgNVBAsTFUNlcnRpZmljYXRlIEF1dGhvcml0eTEVMBMGA1UEAxMMQ29u" + "bmVjdCA0IENBMSgwJgYJKoZIhvcNAQkBFhl3ZWJtYXN0ZXJAY29ubmVjdDQuY29t" + "LmF1MIGfMA0GCSqGSIb3DQEBAQUAA4GNADCBiQKBgQDgs5ptNG6Qv1ZpCDuUNGmv" + "rhjqMDPd3ri8JzZNRiiFlBA4e6/ReaO1U8ASewDeQMH6i9R6degFdQRLngbuJP0s" + "xcEE+SksEWNvygfzLwV9J/q+TQDyJYK52utb++lS0b48A1KPLwEsyL6kOAgelbur" + "ukwxowprKUIV7Knf1ajetQIDAQABo4GFMIGCMCQGA1UdEQQdMBuBGXdlYm1hc3Rl" + "ckBjb25uZWN0NC5jb20uYXUwDwYDVR0TBAgwBgEB/wIBADA2BglghkgBhvhCAQ0E" + "KRYnbW9kX3NzbCBnZW5lcmF0ZWQgY3VzdG9tIENBIGNlcnRpZmljYXRlMBEGCWCG" + "SAGG+EIBAQQEAwICBDANBgkqhkiG9w0BAQQFAAOBgQCsGvfdghH8pPhlwm1r3pQk" + "msnLAVIBb01EhbXm2861iXZfWqGQjrGAaA0ZpXNk9oo110yxoqEoSJSzniZa7Xtz" + "soTwNUpE0SLHvWf/SlKdFWlzXA+vOZbzEv4UmjeelekTm7lc01EEa5QRVzOxHFtQ" + "DhkaJ8VqOMajkQFma2r9iA=="); // // testx509.pem // byte[] cert3 = Base64.decode( "MIIBWzCCAQYCARgwDQYJKoZIhvcNAQEEBQAwODELMAkGA1UEBhMCQVUxDDAKBgNV" + "BAgTA1FMRDEbMBkGA1UEAxMSU1NMZWF5L3JzYSB0ZXN0IENBMB4XDTk1MDYxOTIz" + "MzMxMloXDTk1MDcxNzIzMzMxMlowOjELMAkGA1UEBhMCQVUxDDAKBgNVBAgTA1FM" + "RDEdMBsGA1UEAxMUU1NMZWF5L3JzYSB0ZXN0IGNlcnQwXDANBgkqhkiG9w0BAQEF" + "AANLADBIAkEAqtt6qS5GTxVxGZYWa0/4u+IwHf7p2LNZbcPBp9/OfIcYAXBQn8hO" + "/Re1uwLKXdCjIoaGs4DLdG88rkzfyK5dPQIDAQABMAwGCCqGSIb3DQIFBQADQQAE" + "Wc7EcF8po2/ZO6kNCwK/ICH6DobgLekA5lSLr5EvuioZniZp5lFzAw4+YzPQ7XKJ" + "zl9HYIMxATFyqSiD9jsx"); // // v3-cert1.pem // byte[] cert4 = Base64.decode( "MIICjTCCAfigAwIBAgIEMaYgRzALBgkqhkiG9w0BAQQwRTELMAkGA1UEBhMCVVMx" + "NjA0BgNVBAoTLU5hdGlvbmFsIEFlcm9uYXV0aWNzIGFuZCBTcGFjZSBBZG1pbmlz" + "dHJhdGlvbjAmFxE5NjA1MjgxMzQ5MDUrMDgwMBcROTgwNTI4MTM0OTA1KzA4MDAw" + "ZzELMAkGA1UEBhMCVVMxNjA0BgNVBAoTLU5hdGlvbmFsIEFlcm9uYXV0aWNzIGFu" + "ZCBTcGFjZSBBZG1pbmlzdHJhdGlvbjEgMAkGA1UEBRMCMTYwEwYDVQQDEwxTdGV2" + "ZSBTY2hvY2gwWDALBgkqhkiG9w0BAQEDSQAwRgJBALrAwyYdgxmzNP/ts0Uyf6Bp" + "miJYktU/w4NG67ULaN4B5CnEz7k57s9o3YY3LecETgQ5iQHmkwlYDTL2fTgVfw0C" + "AQOjgaswgagwZAYDVR0ZAQH/BFowWDBWMFQxCzAJBgNVBAYTAlVTMTYwNAYDVQQK" + "Ey1OYXRpb25hbCBBZXJvbmF1dGljcyBhbmQgU3BhY2UgQWRtaW5pc3RyYXRpb24x" + "DTALBgNVBAMTBENSTDEwFwYDVR0BAQH/BA0wC4AJODMyOTcwODEwMBgGA1UdAgQR" + "MA8ECTgzMjk3MDgyM4ACBSAwDQYDVR0KBAYwBAMCBkAwCwYJKoZIhvcNAQEEA4GB" + "AH2y1VCEw/A4zaXzSYZJTTUi3uawbbFiS2yxHvgf28+8Js0OHXk1H1w2d6qOHH21" + "X82tZXd/0JtG0g1T9usFFBDvYK8O0ebgz/P5ELJnBL2+atObEuJy1ZZ0pBDWINR3" + "WkDNLCGiTkCKp0F5EWIrVDwh54NNevkCQRZita+z4IBO"); // // v3-cert2.pem // byte[] cert5 = Base64.decode( "MIICiTCCAfKgAwIBAgIEMeZfHzANBgkqhkiG9w0BAQQFADB9MQswCQYDVQQGEwJD" + "YTEPMA0GA1UEBxMGTmVwZWFuMR4wHAYDVQQLExVObyBMaWFiaWxpdHkgQWNjZXB0" + "ZWQxHzAdBgNVBAoTFkZvciBEZW1vIFB1cnBvc2VzIE9ubHkxHDAaBgNVBAMTE0Vu" + "dHJ1c3QgRGVtbyBXZWIgQ0EwHhcNOTYwNzEyMTQyMDE1WhcNOTYxMDEyMTQyMDE1" + "WjB0MSQwIgYJKoZIhvcNAQkBExVjb29rZUBpc3NsLmF0bC5ocC5jb20xCzAJBgNV" + "BAYTAlVTMScwJQYDVQQLEx5IZXdsZXR0IFBhY2thcmQgQ29tcGFueSAoSVNTTCkx" + "FjAUBgNVBAMTDVBhdWwgQS4gQ29va2UwXDANBgkqhkiG9w0BAQEFAANLADBIAkEA" + "6ceSq9a9AU6g+zBwaL/yVmW1/9EE8s5you1mgjHnj0wAILuoB3L6rm6jmFRy7QZT" + "G43IhVZdDua4e+5/n1ZslwIDAQABo2MwYTARBglghkgBhvhCAQEEBAMCB4AwTAYJ" + "YIZIAYb4QgENBD8WPVRoaXMgY2VydGlmaWNhdGUgaXMgb25seSBpbnRlbmRlZCBm" + "b3IgZGVtb25zdHJhdGlvbiBwdXJwb3Nlcy4wDQYJKoZIhvcNAQEEBQADgYEAi8qc" + "F3zfFqy1sV8NhjwLVwOKuSfhR/Z8mbIEUeSTlnH3QbYt3HWZQ+vXI8mvtZoBc2Fz" + "lexKeIkAZXCesqGbs6z6nCt16P6tmdfbZF3I3AWzLquPcOXjPf4HgstkyvVBn0Ap" + "jAFN418KF/Cx4qyHB4cjdvLrRjjQLnb2+ibo7QU="); // // pem encoded pkcs7 // byte[] cert6 = Base64.decode( "MIAGCSqGSIb3DQEHAqCAMIACAQExCzAJBgUrDgMCGgUAMIAGCSqGSIb3DQEHAQAAoIIJbzCCAj0w" + "ggGmAhEAzbp/VvDf5LxU/iKss3KqVTANBgkqhkiG9w0BAQIFADBfMQswCQYDVQQGEwJVUzEXMBUG" + "A1UEChMOVmVyaVNpZ24sIEluYy4xNzA1BgNVBAsTLkNsYXNzIDEgUHVibGljIFByaW1hcnkgQ2Vy" + "dGlmaWNhdGlvbiBBdXRob3JpdHkwHhcNOTYwMTI5MDAwMDAwWhcNMjgwODAxMjM1OTU5WjBfMQsw" + "CQYDVQQGEwJVUzEXMBUGA1UEChMOVmVyaVNpZ24sIEluYy4xNzA1BgNVBAsTLkNsYXNzIDEgUHVi" + "bGljIFByaW1hcnkgQ2VydGlmaWNhdGlvbiBBdXRob3JpdHkwgZ8wDQYJKoZIhvcNAQEBBQADgY0A" + "MIGJAoGBAOUZv22jVmEtmUhx9mfeuY3rt56GgAqRDvo4Ja9GiILlc6igmyRdDR/MZW4MsNBWhBiH" + "mgabEKFz37RYOWtuwfYV1aioP6oSBo0xrH+wNNePNGeICc0UEeJORVZpH3gCgNrcR5EpuzbJY1zF" + "4Ncth3uhtzKwezC6Ki8xqu6jZ9rbAgMBAAEwDQYJKoZIhvcNAQECBQADgYEATD+4i8Zo3+5DMw5d" + "6abLB4RNejP/khv0Nq3YlSI2aBFsfELM85wuxAc/FLAPT/+Qknb54rxK6Y/NoIAK98Up8YIiXbix" + "3YEjo3slFUYweRb46gVLlH8dwhzI47f0EEA8E8NfH1PoSOSGtHuhNbB7Jbq4046rPzidADQAmPPR" + "cZQwggMuMIICl6ADAgECAhEA0nYujRQMPX2yqCVdr+4NdTANBgkqhkiG9w0BAQIFADBfMQswCQYD" + "VQQGEwJVUzEXMBUGA1UEChMOVmVyaVNpZ24sIEluYy4xNzA1BgNVBAsTLkNsYXNzIDEgUHVibGlj" + "IFByaW1hcnkgQ2VydGlmaWNhdGlvbiBBdXRob3JpdHkwHhcNOTgwNTEyMDAwMDAwWhcNMDgwNTEy" + "MjM1OTU5WjCBzDEXMBUGA1UEChMOVmVyaVNpZ24sIEluYy4xHzAdBgNVBAsTFlZlcmlTaWduIFRy" + "dXN0IE5ldHdvcmsxRjBEBgNVBAsTPXd3dy52ZXJpc2lnbi5jb20vcmVwb3NpdG9yeS9SUEEgSW5j" + "b3JwLiBCeSBSZWYuLExJQUIuTFREKGMpOTgxSDBGBgNVBAMTP1ZlcmlTaWduIENsYXNzIDEgQ0Eg" + "SW5kaXZpZHVhbCBTdWJzY3JpYmVyLVBlcnNvbmEgTm90IFZhbGlkYXRlZDCBnzANBgkqhkiG9w0B" + "AQEFAAOBjQAwgYkCgYEAu1pEigQWu1X9A3qKLZRPFXg2uA1Ksm+cVL+86HcqnbnwaLuV2TFBcHqB" + "S7lIE1YtxwjhhEKrwKKSq0RcqkLwgg4C6S/7wju7vsknCl22sDZCM7VuVIhPh0q/Gdr5FegPh7Yc" + "48zGmo5/aiSS4/zgZbqnsX7vyds3ashKyAkG5JkCAwEAAaN8MHowEQYJYIZIAYb4QgEBBAQDAgEG" + "MEcGA1UdIARAMD4wPAYLYIZIAYb4RQEHAQEwLTArBggrBgEFBQcCARYfd3d3LnZlcmlzaWduLmNv" + "bS9yZXBvc2l0b3J5L1JQQTAPBgNVHRMECDAGAQH/AgEAMAsGA1UdDwQEAwIBBjANBgkqhkiG9w0B" + "AQIFAAOBgQCIuDc73dqUNwCtqp/hgQFxHpJqbS/28Z3TymQ43BuYDAeGW4UVag+5SYWklfEXfWe0" + "fy0s3ZpCnsM+tI6q5QsG3vJWKvozx74Z11NMw73I4xe1pElCY+zCphcPXVgaSTyQXFWjZSAA/Rgg" + "5V+CprGoksVYasGNAzzrw80FopCubjCCA/gwggNhoAMCAQICEBbbn/1G1zppD6KsP01bwywwDQYJ" + "KoZIhvcNAQEEBQAwgcwxFzAVBgNVBAoTDlZlcmlTaWduLCBJbmMuMR8wHQYDVQQLExZWZXJpU2ln" + "biBUcnVzdCBOZXR3b3JrMUYwRAYDVQQLEz13d3cudmVyaXNpZ24uY29tL3JlcG9zaXRvcnkvUlBB" + "IEluY29ycC4gQnkgUmVmLixMSUFCLkxURChjKTk4MUgwRgYDVQQDEz9WZXJpU2lnbiBDbGFzcyAx" + "IENBIEluZGl2aWR1YWwgU3Vic2NyaWJlci1QZXJzb25hIE5vdCBWYWxpZGF0ZWQwHhcNMDAxMDAy" + "MDAwMDAwWhcNMDAxMjAxMjM1OTU5WjCCAQcxFzAVBgNVBAoTDlZlcmlTaWduLCBJbmMuMR8wHQYD" + "VQQLExZWZXJpU2lnbiBUcnVzdCBOZXR3b3JrMUYwRAYDVQQLEz13d3cudmVyaXNpZ24uY29tL3Jl" + "cG9zaXRvcnkvUlBBIEluY29ycC4gYnkgUmVmLixMSUFCLkxURChjKTk4MR4wHAYDVQQLExVQZXJz" + "b25hIE5vdCBWYWxpZGF0ZWQxJzAlBgNVBAsTHkRpZ2l0YWwgSUQgQ2xhc3MgMSAtIE1pY3Jvc29m" + "dDETMBEGA1UEAxQKRGF2aWQgUnlhbjElMCMGCSqGSIb3DQEJARYWZGF2aWRAbGl2ZW1lZGlhLmNv" + "bS5hdTCBnzANBgkqhkiG9w0BAQEFAAOBjQAwgYkCgYEAqxBsdeNmSvFqhMNwhQgNzM8mdjX9eSXb" + "DawpHtQHjmh0AKJSa3IwUY0VIsyZHuXWktO/CgaMBVPt6OVf/n0R2sQigMP6Y+PhEiS0vCJBL9aK" + "0+pOo2qXrjVBmq+XuCyPTnc+BOSrU26tJsX0P9BYorwySiEGxGanBNATdVL4NdUCAwEAAaOBnDCB" + "mTAJBgNVHRMEAjAAMEQGA1UdIAQ9MDswOQYLYIZIAYb4RQEHAQgwKjAoBggrBgEFBQcCARYcaHR0" + "cHM6Ly93d3cudmVyaXNpZ24uY29tL3JwYTARBglghkgBhvhCAQEEBAMCB4AwMwYDVR0fBCwwKjAo" + "oCagJIYiaHR0cDovL2NybC52ZXJpc2lnbi5jb20vY2xhc3MxLmNybDANBgkqhkiG9w0BAQQFAAOB" + "gQBC8yIIdVGpFTf8/YiL14cMzcmL0nIRm4kGR3U59z7UtcXlfNXXJ8MyaeI/BnXwG/gD5OKYqW6R" + "yca9vZOxf1uoTBl82gInk865ED3Tej6msCqFzZffnSUQvOIeqLxxDlqYRQ6PmW2nAnZeyjcnbI5Y" + "syQSM2fmo7n6qJFP+GbFezGCAkUwggJBAgEBMIHhMIHMMRcwFQYDVQQKEw5WZXJpU2lnbiwgSW5j" + "LjEfMB0GA1UECxMWVmVyaVNpZ24gVHJ1c3QgTmV0d29yazFGMEQGA1UECxM9d3d3LnZlcmlzaWdu" + "LmNvbS9yZXBvc2l0b3J5L1JQQSBJbmNvcnAuIEJ5IFJlZi4sTElBQi5MVEQoYyk5ODFIMEYGA1UE" + "AxM/VmVyaVNpZ24gQ2xhc3MgMSBDQSBJbmRpdmlkdWFsIFN1YnNjcmliZXItUGVyc29uYSBOb3Qg" + "VmFsaWRhdGVkAhAW25/9Rtc6aQ+irD9NW8MsMAkGBSsOAwIaBQCggbowGAYJKoZIhvcNAQkDMQsG" + "CSqGSIb3DQEHATAcBgkqhkiG9w0BCQUxDxcNMDAxMDAyMTczNTE4WjAjBgkqhkiG9w0BCQQxFgQU" + "gZjSaBEY2oxGvlQUIMnxSXhivK8wWwYJKoZIhvcNAQkPMU4wTDAKBggqhkiG9w0DBzAOBggqhkiG" + "9w0DAgICAIAwDQYIKoZIhvcNAwICAUAwBwYFKw4DAgcwDQYIKoZIhvcNAwICASgwBwYFKw4DAh0w" + "DQYJKoZIhvcNAQEBBQAEgYAzk+PU91/ZFfoiuKOECjxEh9fDYE2jfDCheBIgh5gdcCo+sS1WQs8O" + "HreQ9Nop/JdJv1DQMBK6weNBBDoP0EEkRm1XCC144XhXZC82jBZohYmi2WvDbbC//YN58kRMYMyy" + "srrfn4Z9I+6kTriGXkrpGk9Q0LSGjmG2BIsqiF0dvwAAAAAAAA=="); // // dsaWithSHA1 cert // byte[] cert7 = Base64.decode( "MIIEXAYJKoZIhvcNAQcCoIIETTCCBEkCAQExCzAJBgUrDgMCGgUAMAsGCSqG" + "SIb3DQEHAaCCAsMwggK/MIIB4AIBADCBpwYFKw4DAhswgZ0CQQEkJRHP+mN7" + "d8miwTMN55CUSmo3TO8WGCxgY61TX5k+7NU4XPf1TULjw3GobwaJX13kquPh" + "fVXk+gVy46n4Iw3hAhUBSe/QF4BUj+pJOF9ROBM4u+FEWA8CQQD4mSJbrABj" + "TUWrlnAte8pS22Tq4/FPO7jHSqjijUHfXKTrHL1OEqV3SVWcFy5j/cqBgX/z" + "m8Q12PFp/PjOhh+nMA4xDDAKBgNVBAMTA0lEMzAeFw05NzEwMDEwMDAwMDBa" + "Fw0zODAxMDEwMDAwMDBaMA4xDDAKBgNVBAMTA0lEMzCB8DCBpwYFKw4DAhsw" + "gZ0CQQEkJRHP+mN7d8miwTMN55CUSmo3TO8WGCxgY61TX5k+7NU4XPf1TULj" + "w3GobwaJX13kquPhfVXk+gVy46n4Iw3hAhUBSe/QF4BUj+pJOF9ROBM4u+FE" + "WA8CQQD4mSJbrABjTUWrlnAte8pS22Tq4/FPO7jHSqjijUHfXKTrHL1OEqV3" + "SVWcFy5j/cqBgX/zm8Q12PFp/PjOhh+nA0QAAkEAkYkXLYMtGVGWj9OnzjPn" + "sB9sefSRPrVegZJCZbpW+Iv0/1RP1u04pHG9vtRpIQLjzUiWvLMU9EKQTThc" + "eNMmWDCBpwYFKw4DAhswgZ0CQQEkJRHP+mN7d8miwTMN55CUSmo3TO8WGCxg" + "Y61TX5k+7NU4XPf1TULjw3GobwaJX13kquPhfVXk+gVy46n4Iw3hAhUBSe/Q" + "F4BUj+pJOF9ROBM4u+FEWA8CQQD4mSJbrABjTUWrlnAte8pS22Tq4/FPO7jH" + "SqjijUHfXKTrHL1OEqV3SVWcFy5j/cqBgX/zm8Q12PFp/PjOhh+nAy8AMCwC" + "FBY3dBSdeprGcqpr6wr3xbG+6WW+AhRMm/facKJNxkT3iKgJbp7R8Xd3QTGC" + "AWEwggFdAgEBMBMwDjEMMAoGA1UEAxMDSUQzAgEAMAkGBSsOAwIaBQCgXTAY" + "BgkqhkiG9w0BCQMxCwYJKoZIhvcNAQcBMBwGCSqGSIb3DQEJBTEPFw0wMjA1" + "MjQyMzEzMDdaMCMGCSqGSIb3DQEJBDEWBBS4WMsoJhf7CVbZYCFcjoTRzPkJ" + "xjCBpwYFKw4DAhswgZ0CQQEkJRHP+mN7d8miwTMN55CUSmo3TO8WGCxgY61T" + "X5k+7NU4XPf1TULjw3GobwaJX13kquPhfVXk+gVy46n4Iw3hAhUBSe/QF4BU" + "j+pJOF9ROBM4u+FEWA8CQQD4mSJbrABjTUWrlnAte8pS22Tq4/FPO7jHSqji" + "jUHfXKTrHL1OEqV3SVWcFy5j/cqBgX/zm8Q12PFp/PjOhh+nBC8wLQIVALID" + "dt+MHwawrDrwsO1Z6sXBaaJsAhRaKssrpevmLkbygKPV07XiAKBG02Zvb2Jh" + "cg=="); // // testcrl.pem // byte[] crl1 = Base64.decode( "MIICjTCCAfowDQYJKoZIhvcNAQECBQAwXzELMAkGA1UEBhMCVVMxIDAeBgNVBAoT" + "F1JTQSBEYXRhIFNlY3VyaXR5LCBJbmMuMS4wLAYDVQQLEyVTZWN1cmUgU2VydmVy" + "IENlcnRpZmljYXRpb24gQXV0aG9yaXR5Fw05NTA1MDIwMjEyMjZaFw05NTA2MDEw" + "MDAxNDlaMIIBaDAWAgUCQQAABBcNOTUwMjAxMTcyNDI2WjAWAgUCQQAACRcNOTUw" + "MjEwMDIxNjM5WjAWAgUCQQAADxcNOTUwMjI0MDAxMjQ5WjAWAgUCQQAADBcNOTUw" + "MjI1MDA0NjQ0WjAWAgUCQQAAGxcNOTUwMzEzMTg0MDQ5WjAWAgUCQQAAFhcNOTUw" + "MzE1MTkxNjU0WjAWAgUCQQAAGhcNOTUwMzE1MTk0MDQxWjAWAgUCQQAAHxcNOTUw" + "MzI0MTk0NDMzWjAWAgUCcgAABRcNOTUwMzI5MjAwNzExWjAWAgUCcgAAERcNOTUw" + "MzMwMDIzNDI2WjAWAgUCQQAAIBcNOTUwNDA3MDExMzIxWjAWAgUCcgAAHhcNOTUw" + "NDA4MDAwMjU5WjAWAgUCcgAAQRcNOTUwNDI4MTcxNzI0WjAWAgUCcgAAOBcNOTUw" + "NDI4MTcyNzIxWjAWAgUCcgAATBcNOTUwNTAyMDIxMjI2WjANBgkqhkiG9w0BAQIF" + "AAN+AHqOEJXSDejYy0UwxxrH/9+N2z5xu/if0J6qQmK92W0hW158wpJg+ovV3+wQ" + "wvIEPRL2rocL0tKfAsVq1IawSJzSNgxG0lrcla3MrJBnZ4GaZDu4FutZh72MR3Gt" + "JaAL3iTJHJD55kK2D/VoyY1djlsPuNh6AEgdVwFAyp0v"); // // ecdsa cert with extra octet string. // byte[] oldEcdsa = Base64.decode( "MIICljCCAkCgAwIBAgIBATALBgcqhkjOPQQBBQAwgY8xCzAJBgNVBAYTAkFVMSgwJ" + "gYDVQQKEx9UaGUgTGVnaW9uIG9mIHRoZSBCb3VuY3kgQ2FzdGxlMRIwEAYDVQQHEw" + "lNZWxib3VybmUxETAPBgNVBAgTCFZpY3RvcmlhMS8wLQYJKoZIhvcNAQkBFiBmZWV" + "kYmFjay1jcnlwdG9AYm91bmN5Y2FzdGxlLm9yZzAeFw0wMTEyMDcwMTAwMDRaFw0w" + "MTEyMDcwMTAxNDRaMIGPMQswCQYDVQQGEwJBVTEoMCYGA1UEChMfVGhlIExlZ2lvb" + "iBvZiB0aGUgQm91bmN5IENhc3RsZTESMBAGA1UEBxMJTWVsYm91cm5lMREwDwYDVQ" + "QIEwhWaWN0b3JpYTEvMC0GCSqGSIb3DQEJARYgZmVlZGJhY2stY3J5cHRvQGJvdW5" + "jeWNhc3RsZS5vcmcwgeQwgb0GByqGSM49AgEwgbECAQEwKQYHKoZIzj0BAQIef///" + "////////////f///////gAAAAAAAf///////MEAEHn///////////////3///////" + "4AAAAAAAH///////AQeawFsO9zxiUHQ1lSSFHXKcanbL7J9HTd5YYXClCwKBB8CD/" + "qWPNyogWzMM7hkK+35BcPTWFc9Pyf7vTs8uaqvAh5///////////////9///+eXpq" + "fXZBx+9FSJoiQnQsDIgAEHwJbbcU7xholSP+w9nFHLebJUhqdLSU05lq/y9X+DHAw" + "CwYHKoZIzj0EAQUAA0MAMEACHnz6t4UNoVROp74ma4XNDjjGcjaqiIWPZLK8Bdw3G" + "QIeLZ4j3a6ividZl344UH+UPUE7xJxlYGuy7ejTsqRR"); byte[] uncompressedPtEC = Base64.decode( "MIIDKzCCAsGgAwIBAgICA+kwCwYHKoZIzj0EAQUAMGYxCzAJBgNVBAYTAkpQ" + "MRUwEwYDVQQKEwxuaXRlY2guYWMuanAxDjAMBgNVBAsTBWFpbGFiMQ8wDQYD" + "VQQDEwZ0ZXN0Y2ExHzAdBgkqhkiG9w0BCQEWEHRlc3RjYUBsb2NhbGhvc3Qw" + "HhcNMDExMDEzMTE1MzE3WhcNMjAxMjEyMTE1MzE3WjBmMQswCQYDVQQGEwJK" + "UDEVMBMGA1UEChMMbml0ZWNoLmFjLmpwMQ4wDAYDVQQLEwVhaWxhYjEPMA0G" + "A1UEAxMGdGVzdGNhMR8wHQYJKoZIhvcNAQkBFhB0ZXN0Y2FAbG9jYWxob3N0" + "MIIBczCCARsGByqGSM49AgEwggEOAgEBMDMGByqGSM49AQECKEdYWnajFmnZ" + "tzrukK2XWdle2v+GsD9l1ZiR6g7ozQDbhFH/bBiMDQcwVAQoJ5EQKrI54/CT" + "xOQ2pMsd/fsXD+EX8YREd8bKHWiLz8lIVdD5cBNeVwQoMKSc6HfI7vKZp8Q2" + "zWgIFOarx1GQoWJbMcSt188xsl30ncJuJT2OoARRBAqJ4fD+q6hbqgNSjTQ7" + "htle1KO3eiaZgcJ8rrnyN8P+5A8+5K+H9aQ/NbBR4Gs7yto5PXIUZEUgodHA" + "TZMSAcSq5ZYt4KbnSYaLY0TtH9CqAigEwZ+hglbT21B7ZTzYX2xj0x+qooJD" + "hVTLtIPaYJK2HrMPxTw6/zfrAgEPA1IABAnvfFcFDgD/JicwBGn6vR3N8MIn" + "mptZf/mnJ1y649uCF60zOgdwIyI7pVSxBFsJ7ohqXEHW0x7LrGVkdSEiipiH" + "LYslqh3xrqbAgPbl93GUo0IwQDAPBgNVHRMBAf8EBTADAQH/MA4GA1UdDwEB" + "/wQEAwIBxjAdBgNVHQ4EFgQUAEo62Xm9H6DcsE0zUDTza4BRG90wCwYHKoZI" + "zj0EAQUAA1cAMFQCKAQsCHHSNOqfJXLgt3bg5+k49hIBGVr/bfG0B9JU3rNt" + "Ycl9Y2zfRPUCKAK2ccOQXByAWfsasDu8zKHxkZv7LVDTFjAIffz3HaCQeVhD" + "z+fauEg="); byte[] keyUsage = Base64.decode( "MIIE7TCCBFagAwIBAgIEOAOR7jANBgkqhkiG9w0BAQQFADCByTELMAkGA1UE" + "BhMCVVMxFDASBgNVBAoTC0VudHJ1c3QubmV0MUgwRgYDVQQLFD93d3cuZW50" + "cnVzdC5uZXQvQ2xpZW50X0NBX0luZm8vQ1BTIGluY29ycC4gYnkgcmVmLiBs" + "aW1pdHMgbGlhYi4xJTAjBgNVBAsTHChjKSAxOTk5IEVudHJ1c3QubmV0IExp" + "bWl0ZWQxMzAxBgNVBAMTKkVudHJ1c3QubmV0IENsaWVudCBDZXJ0aWZpY2F0" + "aW9uIEF1dGhvcml0eTAeFw05OTEwMTIxOTI0MzBaFw0xOTEwMTIxOTU0MzBa" + "MIHJMQswCQYDVQQGEwJVUzEUMBIGA1UEChMLRW50cnVzdC5uZXQxSDBGBgNV" + "BAsUP3d3dy5lbnRydXN0Lm5ldC9DbGllbnRfQ0FfSW5mby9DUFMgaW5jb3Jw" + "LiBieSByZWYuIGxpbWl0cyBsaWFiLjElMCMGA1UECxMcKGMpIDE5OTkgRW50" + "cnVzdC5uZXQgTGltaXRlZDEzMDEGA1UEAxMqRW50cnVzdC5uZXQgQ2xpZW50" + "IENlcnRpZmljYXRpb24gQXV0aG9yaXR5MIGdMA0GCSqGSIb3DQEBAQUAA4GL" + "ADCBhwKBgQDIOpleMRffrCdvkHvkGf9FozTC28GoT/Bo6oT9n3V5z8GKUZSv" + "x1cDR2SerYIbWtp/N3hHuzeYEpbOxhN979IMMFGpOZ5V+Pux5zDeg7K6PvHV" + "iTs7hbqqdCz+PzFur5GVbgbUB01LLFZHGARS2g4Qk79jkJvh34zmAqTmT173" + "iwIBA6OCAeAwggHcMBEGCWCGSAGG+EIBAQQEAwIABzCCASIGA1UdHwSCARkw" + "ggEVMIHkoIHhoIHepIHbMIHYMQswCQYDVQQGEwJVUzEUMBIGA1UEChMLRW50" + "cnVzdC5uZXQxSDBGBgNVBAsUP3d3dy5lbnRydXN0Lm5ldC9DbGllbnRfQ0Ff" + "SW5mby9DUFMgaW5jb3JwLiBieSByZWYuIGxpbWl0cyBsaWFiLjElMCMGA1UE" + "CxMcKGMpIDE5OTkgRW50cnVzdC5uZXQgTGltaXRlZDEzMDEGA1UEAxMqRW50" + "cnVzdC5uZXQgQ2xpZW50IENlcnRpZmljYXRpb24gQXV0aG9yaXR5MQ0wCwYD" + "VQQDEwRDUkwxMCygKqAohiZodHRwOi8vd3d3LmVudHJ1c3QubmV0L0NSTC9D" + "bGllbnQxLmNybDArBgNVHRAEJDAigA8xOTk5MTAxMjE5MjQzMFqBDzIwMTkx" + "MDEyMTkyNDMwWjALBgNVHQ8EBAMCAQYwHwYDVR0jBBgwFoAUxPucKXuXzUyW" + "/O5bs8qZdIuV6kwwHQYDVR0OBBYEFMT7nCl7l81MlvzuW7PKmXSLlepMMAwG" + "A1UdEwQFMAMBAf8wGQYJKoZIhvZ9B0EABAwwChsEVjQuMAMCBJAwDQYJKoZI" + "hvcNAQEEBQADgYEAP66K8ddmAwWePvrqHEa7pFuPeJoSSJn59DXeDDYHAmsQ" + "OokUgZwxpnyyQbJq5wcBoUv5nyU7lsqZwz6hURzzwy5E97BnRqqS5TvaHBkU" + "ODDV4qIxJS7x7EU47fgGWANzYrAQMY9Av2TgXD7FTx/aEkP/TOYGJqibGapE" + "PHayXOw="); byte[] nameCert = Base64.decode( "MIIEFjCCA3+gAwIBAgIEdS8BozANBgkqhkiG9w0BAQUFADBKMQswCQYDVQQGEwJE" + "RTERMA8GA1UEChQIREFURVYgZUcxKDAMBgcCggYBCgcUEwExMBgGA1UEAxQRQ0Eg" + "REFURVYgRDAzIDE6UE4wIhgPMjAwMTA1MTAxMDIyNDhaGA8yMDA0MDUwOTEwMjI0" + "OFowgYQxCzAJBgNVBAYTAkRFMQ8wDQYDVQQIFAZCYXllcm4xEjAQBgNVBAcUCU7I" + "dXJuYmVyZzERMA8GA1UEChQIREFURVYgZUcxHTAbBgNVBAUTFDAwMDAwMDAwMDA4" + "OTU3NDM2MDAxMR4wHAYDVQQDFBVEaWV0bWFyIFNlbmdlbmxlaXRuZXIwgaEwDQYJ" + "KoZIhvcNAQEBBQADgY8AMIGLAoGBAJLI/LJLKaHoMk8fBECW/od8u5erZi6jI8Ug" + "C0a/LZyQUO/R20vWJs6GrClQtXB+AtfiBSnyZOSYzOdfDI8yEKPEv8qSuUPpOHps" + "uNCFdLZF1vavVYGEEWs2+y+uuPmg8q1oPRyRmUZ+x9HrDvCXJraaDfTEd9olmB/Z" + "AuC/PqpjAgUAwAAAAaOCAcYwggHCMAwGA1UdEwEB/wQCMAAwDwYDVR0PAQH/BAUD" + "AwdAADAxBgNVHSAEKjAoMCYGBSskCAEBMB0wGwYIKwYBBQUHAgEWD3d3dy56cy5k" + "YXRldi5kZTApBgNVHREEIjAggR5kaWV0bWFyLnNlbmdlbmxlaXRuZXJAZGF0ZXYu" + "ZGUwgYQGA1UdIwR9MHuhc6RxMG8xCzAJBgNVBAYTAkRFMT0wOwYDVQQKFDRSZWd1" + "bGllcnVuZ3NiZWjIb3JkZSBmyHVyIFRlbGVrb21tdW5pa2F0aW9uIHVuZCBQb3N0" + "MSEwDAYHAoIGAQoHFBMBMTARBgNVBAMUCjVSLUNBIDE6UE6CBACm8LkwDgYHAoIG" + "AQoMAAQDAQEAMEcGA1UdHwRAMD4wPKAUoBKGEHd3dy5jcmwuZGF0ZXYuZGWiJKQi" + "MCAxCzAJBgNVBAYTAkRFMREwDwYDVQQKFAhEQVRFViBlRzAWBgUrJAgDBAQNMAsT" + "A0VVUgIBBQIBATAdBgNVHQ4EFgQUfv6xFP0xk7027folhy+ziZvBJiwwLAYIKwYB" + "BQUHAQEEIDAeMBwGCCsGAQUFBzABhhB3d3cuZGlyLmRhdGV2LmRlMA0GCSqGSIb3" + "DQEBBQUAA4GBAEOVX6uQxbgtKzdgbTi6YLffMftFr2mmNwch7qzpM5gxcynzgVkg" + "pnQcDNlm5AIbS6pO8jTCLfCd5TZ5biQksBErqmesIl3QD+VqtB+RNghxectZ3VEs" + "nCUtcE7tJ8O14qwCb3TxS9dvIUFiVi4DjbxX46TdcTbTaK8/qr6AIf+l"); byte[] probSelfSignedCert = Base64.decode( "MIICxTCCAi6gAwIBAgIQAQAAAAAAAAAAAAAAAAAAATANBgkqhkiG9w0BAQUFADBF" + "MScwJQYDVQQKEx4gRElSRUNUSU9OIEdFTkVSQUxFIERFUyBJTVBPVFMxGjAYBgNV" + "BAMTESBBQyBNSU5FRkkgQiBURVNUMB4XDTA0MDUwNzEyMDAwMFoXDTE0MDUwNzEy" + "MDAwMFowRTEnMCUGA1UEChMeIERJUkVDVElPTiBHRU5FUkFMRSBERVMgSU1QT1RT" + "MRowGAYDVQQDExEgQUMgTUlORUZJIEIgVEVTVDCBnzANBgkqhkiG9w0BAQEFAAOB" + "jQAwgYkCgYEAveoCUOAukZdcFCs2qJk76vSqEX0ZFzHqQ6faBPZWjwkgUNwZ6m6m" + "qWvvyq1cuxhoDvpfC6NXILETawYc6MNwwxsOtVVIjuXlcF17NMejljJafbPximEt" + "DQ4LcQeSp4K7FyFlIAMLyt3BQ77emGzU5fjFTvHSUNb3jblx0sV28c0CAwEAAaOB" + "tTCBsjAfBgNVHSMEGDAWgBSEJ4bLbvEQY8cYMAFKPFD1/fFXlzAdBgNVHQ4EFgQU" + "hCeGy27xEGPHGDABSjxQ9f3xV5cwDgYDVR0PAQH/BAQDAgEGMBEGCWCGSAGG+EIB" + "AQQEAwIBBjA8BgNVHR8ENTAzMDGgL6AthitodHRwOi8vYWRvbmlzLnBrNy5jZXJ0" + "cGx1cy5uZXQvZGdpLXRlc3QuY3JsMA8GA1UdEwEB/wQFMAMBAf8wDQYJKoZIhvcN" + "AQEFBQADgYEAmToHJWjd3+4zknfsP09H6uMbolHNGG0zTS2lrLKpzcmkQfjhQpT9" + "LUTBvfs1jdjo9fGmQLvOG+Sm51Rbjglb8bcikVI5gLbclOlvqLkm77otjl4U4Z2/" + "Y0vP14Aov3Sn3k+17EfReYUZI4liuB95ncobC4e8ZM++LjQcIM0s+Vs="); byte[] gost34102001base = Base64.decode( "MIIB1DCCAYECEEjpVKXP6Wn1yVz3VeeDQa8wCgYGKoUDAgIDBQAwbTEfMB0G" + "A1UEAwwWR29zdFIzNDEwLTIwMDEgZXhhbXBsZTESMBAGA1UECgwJQ3J5cHRv" + "UHJvMQswCQYDVQQGEwJSVTEpMCcGCSqGSIb3DQEJARYaR29zdFIzNDEwLTIw" + "MDFAZXhhbXBsZS5jb20wHhcNMDUwMjAzMTUxNjQ2WhcNMTUwMjAzMTUxNjQ2" + "WjBtMR8wHQYDVQQDDBZHb3N0UjM0MTAtMjAwMSBleGFtcGxlMRIwEAYDVQQK" + "DAlDcnlwdG9Qcm8xCzAJBgNVBAYTAlJVMSkwJwYJKoZIhvcNAQkBFhpHb3N0" + "UjM0MTAtMjAwMUBleGFtcGxlLmNvbTBjMBwGBiqFAwICEzASBgcqhQMCAiQA" + "BgcqhQMCAh4BA0MABECElWh1YAIaQHUIzROMMYks/eUFA3pDXPRtKw/nTzJ+" + "V4/rzBa5lYgD0Jp8ha4P5I3qprt+VsfLsN8PZrzK6hpgMAoGBiqFAwICAwUA" + "A0EAHw5dw/aw/OiNvHyOE65kvyo4Hp0sfz3csM6UUkp10VO247ofNJK3tsLb" + "HOLjUaqzefrlGb11WpHYrvWFg+FcLA=="); byte[] gost341094base = Base64.decode( "MIICDzCCAbwCEBcxKsIb0ghYvAQeUjfQdFAwCgYGKoUDAgIEBQAwaTEdMBsG" + "A1UEAwwUR29zdFIzNDEwLTk0IGV4YW1wbGUxEjAQBgNVBAoMCUNyeXB0b1By" + "bzELMAkGA1UEBhMCUlUxJzAlBgkqhkiG9w0BCQEWGEdvc3RSMzQxMC05NEBl" + "eGFtcGxlLmNvbTAeFw0wNTAyMDMxNTE2NTFaFw0xNTAyMDMxNTE2NTFaMGkx" + "HTAbBgNVBAMMFEdvc3RSMzQxMC05NCBleGFtcGxlMRIwEAYDVQQKDAlDcnlw" + "dG9Qcm8xCzAJBgNVBAYTAlJVMScwJQYJKoZIhvcNAQkBFhhHb3N0UjM0MTAt" + "OTRAZXhhbXBsZS5jb20wgaUwHAYGKoUDAgIUMBIGByqFAwICIAIGByqFAwIC" + "HgEDgYQABIGAu4Rm4XmeWzTYLIB/E6gZZnFX/oxUJSFHbzALJ3dGmMb7R1W+" + "t7Lzk2w5tUI3JoTiDRCKJA4fDEJNKzsRK6i/ZjkyXJSLwaj+G2MS9gklh8x1" + "G/TliYoJgmjTXHemD7aQEBON4z58nJHWrA0ILD54wbXCtrcaqCqLRYGTMjJ2" + "+nswCgYGKoUDAgIEBQADQQBxKNhOmjgz/i5CEgLOyKyz9pFGkDcaymsWYQWV" + "v7CZ0pTM8IzMzkUBW3GHsUjCFpanFZDfg2zuN+3kT+694n9B"); byte[] gost341094A = Base64.decode( "MIICSDCCAfWgAwIBAgIBATAKBgYqhQMCAgQFADCBgTEXMBUGA1UEAxMOZGVmYXVsdDM0MTAtOTQx" + "DTALBgNVBAoTBERpZ3QxDzANBgNVBAsTBkNyeXB0bzEOMAwGA1UEBxMFWS1vbGExDDAKBgNVBAgT" + "A01FTDELMAkGA1UEBhMCcnUxGzAZBgkqhkiG9w0BCQEWDHRlc3RAdGVzdC5ydTAeFw0wNTAzMjkx" + "MzExNTdaFw0wNjAzMjkxMzExNTdaMIGBMRcwFQYDVQQDEw5kZWZhdWx0MzQxMC05NDENMAsGA1UE" + "ChMERGlndDEPMA0GA1UECxMGQ3J5cHRvMQ4wDAYDVQQHEwVZLW9sYTEMMAoGA1UECBMDTUVMMQsw" + "CQYDVQQGEwJydTEbMBkGCSqGSIb3DQEJARYMdGVzdEB0ZXN0LnJ1MIGlMBwGBiqFAwICFDASBgcq" + "hQMCAiACBgcqhQMCAh4BA4GEAASBgIQACDLEuxSdRDGgdZxHmy30g/DUYkRxO9Mi/uSHX5NjvZ31" + "b7JMEMFqBtyhql1HC5xZfUwZ0aT3UnEFDfFjLP+Bf54gA+LPkQXw4SNNGOj+klnqgKlPvoqMGlwa" + "+hLPKbS561WpvB2XSTgbV+pqqXR3j6j30STmybelEV3RdS2Now8wDTALBgNVHQ8EBAMCB4AwCgYG" + "KoUDAgIEBQADQQBCFy7xWRXtNVXflKvDs0pBdBuPzjCMeZAXVxK8vUxsxxKu76d9CsvhgIFknFRi" + "wWTPiZenvNoJ4R1uzeX+vREm"); byte[] gost341094B = Base64.decode( "MIICSDCCAfWgAwIBAgIBATAKBgYqhQMCAgQFADCBgTEXMBUGA1UEAxMOcGFyYW0xLTM0MTAtOTQx" + "DTALBgNVBAoTBERpZ3QxDzANBgNVBAsTBkNyeXB0bzEOMAwGA1UEBxMFWS1PbGExDDAKBgNVBAgT" + "A01lbDELMAkGA1UEBhMCcnUxGzAZBgkqhkiG9w0BCQEWDHRlc3RAdGVzdC5ydTAeFw0wNTAzMjkx" + "MzEzNTZaFw0wNjAzMjkxMzEzNTZaMIGBMRcwFQYDVQQDEw5wYXJhbTEtMzQxMC05NDENMAsGA1UE" + "ChMERGlndDEPMA0GA1UECxMGQ3J5cHRvMQ4wDAYDVQQHEwVZLU9sYTEMMAoGA1UECBMDTWVsMQsw" + "CQYDVQQGEwJydTEbMBkGCSqGSIb3DQEJARYMdGVzdEB0ZXN0LnJ1MIGlMBwGBiqFAwICFDASBgcq" + "hQMCAiADBgcqhQMCAh4BA4GEAASBgEa+AAcZmijWs1M9x5Pn9efE8D9ztG1NMoIt0/hNZNqln3+j" + "lMZjyqPt+kTLIjtmvz9BRDmIDk6FZz+4LhG2OTL7yGpWfrMxMRr56nxomTN9aLWRqbyWmn3brz9Y" + "AUD3ifnwjjIuW7UM84JNlDTOdxx0XRUfLQIPMCXe9cO02Xskow8wDTALBgNVHQ8EBAMCB4AwCgYG" + "KoUDAgIEBQADQQBzFcnuYc/639OTW+L5Ecjw9KxGr+dwex7lsS9S1BUgKa3m1d5c+cqI0B2XUFi5" + "4iaHHJG0dCyjtQYLJr0OZjRw"); byte[] gost34102001A = Base64.decode( "MIICCzCCAbigAwIBAgIBATAKBgYqhQMCAgMFADCBhDEaMBgGA1UEAxMRZGVmYXVsdC0zNDEwLTIw" + "MDExDTALBgNVBAoTBERpZ3QxDzANBgNVBAsTBkNyeXB0bzEOMAwGA1UEBxMFWS1PbGExDDAKBgNV" + "BAgTA01lbDELMAkGA1UEBhMCcnUxGzAZBgkqhkiG9w0BCQEWDHRlc3RAdGVzdC5ydTAeFw0wNTAz" + "MjkxMzE4MzFaFw0wNjAzMjkxMzE4MzFaMIGEMRowGAYDVQQDExFkZWZhdWx0LTM0MTAtMjAwMTEN" + "MAsGA1UEChMERGlndDEPMA0GA1UECxMGQ3J5cHRvMQ4wDAYDVQQHEwVZLU9sYTEMMAoGA1UECBMD" + "TWVsMQswCQYDVQQGEwJydTEbMBkGCSqGSIb3DQEJARYMdGVzdEB0ZXN0LnJ1MGMwHAYGKoUDAgIT" + "MBIGByqFAwICIwEGByqFAwICHgEDQwAEQG/4c+ZWb10IpeHfmR+vKcbpmSOClJioYmCVgnojw0Xn" + "ned0KTg7TJreRUc+VX7vca4hLQaZ1o/TxVtfEApK/O6jDzANMAsGA1UdDwQEAwIHgDAKBgYqhQMC" + "AgMFAANBAN8y2b6HuIdkD3aWujpfQbS1VIA/7hro4vLgDhjgVmev/PLzFB8oTh3gKhExpDo82IEs" + "ZftGNsbbyp1NFg7zda0="); byte[] gostCA1 = Base64.decode( "MIIDNDCCAuGgAwIBAgIQZLcKDcWcQopF+jp4p9jylDAKBgYqhQMCAgQFADBm" + "MQswCQYDVQQGEwJSVTEPMA0GA1UEBxMGTW9zY293MRcwFQYDVQQKEw5PT08g" + "Q3J5cHRvLVBybzEUMBIGA1UECxMLRGV2ZWxvcG1lbnQxFzAVBgNVBAMTDkNQ" + "IENTUCBUZXN0IENBMB4XDTAyMDYwOTE1NTIyM1oXDTA5MDYwOTE1NTkyOVow" + "ZjELMAkGA1UEBhMCUlUxDzANBgNVBAcTBk1vc2NvdzEXMBUGA1UEChMOT09P" + "IENyeXB0by1Qcm8xFDASBgNVBAsTC0RldmVsb3BtZW50MRcwFQYDVQQDEw5D" + "UCBDU1AgVGVzdCBDQTCBpTAcBgYqhQMCAhQwEgYHKoUDAgIgAgYHKoUDAgIe" + "AQOBhAAEgYAYglywKuz1nMc9UiBYOaulKy53jXnrqxZKbCCBSVaJ+aCKbsQm" + "glhRFrw6Mwu8Cdeabo/ojmea7UDMZd0U2xhZFRti5EQ7OP6YpqD0alllo7za" + "4dZNXdX+/ag6fOORSLFdMpVx5ganU0wHMPk67j+audnCPUj/plbeyccgcdcd" + "WaOCASIwggEeMAsGA1UdDwQEAwIBxjAPBgNVHRMBAf8EBTADAQH/MB0GA1Ud" + "DgQWBBTe840gTo4zt2twHilw3PD9wJaX0TCBygYDVR0fBIHCMIG/MDygOqA4" + "hjYtaHR0cDovL2ZpZXdhbGwvQ2VydEVucm9sbC9DUCUyMENTUCUyMFRlc3Ql" + "MjBDQSgzKS5jcmwwRKBCoECGPmh0dHA6Ly93d3cuY3J5cHRvcHJvLnJ1L0Nl" + "cnRFbnJvbGwvQ1AlMjBDU1AlMjBUZXN0JTIwQ0EoMykuY3JsMDmgN6A1hjMt" + "ZmlsZTovL1xcZmlld2FsbFxDZXJ0RW5yb2xsXENQIENTUCBUZXN0IENBKDMp" + "LmNybC8wEgYJKwYBBAGCNxUBBAUCAwMAAzAKBgYqhQMCAgQFAANBAIJi7ni7" + "9rwMR5rRGTFftt2k70GbqyUEfkZYOzrgdOoKiB4IIsIstyBX0/ne6GsL9Xan" + "G2IN96RB7KrowEHeW+k="); byte[] gostCA2 = Base64.decode( "MIIC2DCCAoWgAwIBAgIQe9ZCugm42pRKNcHD8466zTAKBgYqhQMCAgMFADB+" + "MRowGAYJKoZIhvcNAQkBFgtzYmFAZGlndC5ydTELMAkGA1UEBhMCUlUxDDAK" + "BgNVBAgTA01FTDEUMBIGA1UEBxMLWW9zaGthci1PbGExDTALBgNVBAoTBERp" + "Z3QxDzANBgNVBAsTBkNyeXB0bzEPMA0GA1UEAxMGc2JhLUNBMB4XDTA0MDgw" + "MzEzMzE1OVoXDTE0MDgwMzEzNDAxMVowfjEaMBgGCSqGSIb3DQEJARYLc2Jh" + "QGRpZ3QucnUxCzAJBgNVBAYTAlJVMQwwCgYDVQQIEwNNRUwxFDASBgNVBAcT" + "C1lvc2hrYXItT2xhMQ0wCwYDVQQKEwREaWd0MQ8wDQYDVQQLEwZDcnlwdG8x" + "DzANBgNVBAMTBnNiYS1DQTBjMBwGBiqFAwICEzASBgcqhQMCAiMBBgcqhQMC" + "Ah4BA0MABEDMSy10CuOH+i8QKG2UWA4XmCt6+BFrNTZQtS6bOalyDY8Lz+G7" + "HybyipE3PqdTB4OIKAAPsEEeZOCZd2UXGQm5o4HaMIHXMBMGCSsGAQQBgjcU" + "AgQGHgQAQwBBMAsGA1UdDwQEAwIBhjAPBgNVHRMBAf8EBTADAQH/MB0GA1Ud" + "DgQWBBRJJl3LcNMxkZI818STfoi3ng1xoDBxBgNVHR8EajBoMDGgL6Athito" + "dHRwOi8vc2JhLmRpZ3QubG9jYWwvQ2VydEVucm9sbC9zYmEtQ0EuY3JsMDOg" + "MaAvhi1maWxlOi8vXFxzYmEuZGlndC5sb2NhbFxDZXJ0RW5yb2xsXHNiYS1D" + "QS5jcmwwEAYJKwYBBAGCNxUBBAMCAQAwCgYGKoUDAgIDBQADQQA+BRJHbc/p" + "q8EYl6iJqXCuR+ozRmH7hPAP3c4KqYSC38TClCgBloLapx/3/WdatctFJW/L" + "mcTovpq088927shE"); public String getName() { return "CertTest"; } public TestResult checkCertificate( int id, byte[] bytes) { ByteArrayInputStream bIn; String dump = ""; try { bIn = new ByteArrayInputStream(bytes); CertificateFactory fact = CertificateFactory.getInstance("X.509", "BC"); Certificate cert = fact.generateCertificate(bIn); PublicKey k = cert.getPublicKey(); // System.out.println(cert); } catch (Exception e) { return new SimpleTestResult(false, dump + System.getProperty("line.separator") + getName() + ": " + id + " failed - exception " + e.toString(), e); } return new SimpleTestResult(true, getName() + ": " + id + " Okay"); } public TestResult checkNameCertificate( int id, byte[] bytes) { ByteArrayInputStream bIn; String dump = ""; try { bIn = new ByteArrayInputStream(bytes); CertificateFactory fact = CertificateFactory.getInstance("X.509", "BC"); X509Certificate cert = (X509Certificate)fact.generateCertificate(bIn); PublicKey k = cert.getPublicKey(); if (!cert.getIssuerDN().toString().equals("C=DE,O=DATEV eG,0.2.262.1.10.7.20=1+CN=CA DATEV D03 1:PN")) { return new SimpleTestResult(false, getName() + ": " + id + " failed - name test."); } // System.out.println(cert); } catch (Exception e) { return new SimpleTestResult(false, dump + System.getProperty("line.separator") + getName() + ": " + id + " failed - exception " + e.toString(), e); } return new SimpleTestResult(true, getName() + ": " + id + " Okay"); } public TestResult checkKeyUsage( int id, byte[] bytes) { ByteArrayInputStream bIn; String dump = ""; try { bIn = new ByteArrayInputStream(bytes); CertificateFactory fact = CertificateFactory.getInstance("X.509", "BC"); X509Certificate cert = (X509Certificate)fact.generateCertificate(bIn); PublicKey k = cert.getPublicKey(); if (cert.getKeyUsage()[7]) { return new SimpleTestResult(false, getName() + ": error generating cert - key usage wrong."); } // System.out.println(cert); } catch (Exception e) { return new SimpleTestResult(false, dump + System.getProperty("line.separator") + getName() + ": " + id + " failed - exception " + e.toString(), e); } return new SimpleTestResult(true, getName() + ": " + id + " Okay"); } public TestResult checkSelfSignedCertificate( int id, byte[] bytes) { ByteArrayInputStream bIn; String dump = ""; try { bIn = new ByteArrayInputStream(bytes); CertificateFactory fact = CertificateFactory.getInstance("X.509", "BC"); Certificate cert = fact.generateCertificate(bIn); PublicKey k = cert.getPublicKey(); cert.verify(k); // System.out.println(cert); } catch (Exception e) { return new SimpleTestResult(false, dump + System.getProperty("line.separator") + getName() + ": " + id + " failed - exception " + e.toString(), e); } return new SimpleTestResult(true, getName() + ": " + id + " Okay"); } /** * we generate a self signed certificate for the sake of testing - RSA */ public TestResult checkCreation1() { // // a sample key pair. // RSAPublicKeySpec pubKeySpec = new RSAPublicKeySpec( new BigInteger("b4a7e46170574f16a97082b22be58b6a2a629798419be12872a4bdba626cfae9900f76abfb12139dce5de56564fab2b6543165a040c606887420e33d91ed7ed7", 16), new BigInteger("11", 16)); RSAPrivateCrtKeySpec privKeySpec = new RSAPrivateCrtKeySpec( new BigInteger("b4a7e46170574f16a97082b22be58b6a2a629798419be12872a4bdba626cfae9900f76abfb12139dce5de56564fab2b6543165a040c606887420e33d91ed7ed7", 16), new BigInteger("11", 16), new BigInteger("9f66f6b05410cd503b2709e88115d55daced94d1a34d4e32bf824d0dde6028ae79c5f07b580f5dce240d7111f7ddb130a7945cd7d957d1920994da389f490c89", 16), new BigInteger("c0a0758cdf14256f78d4708c86becdead1b50ad4ad6c5c703e2168fbf37884cb", 16), new BigInteger("f01734d7960ea60070f1b06f2bb81bfac48ff192ae18451d5e56c734a5aab8a5", 16), new BigInteger("b54bb9edff22051d9ee60f9351a48591b6500a319429c069a3e335a1d6171391", 16), new BigInteger("d3d83daf2a0cecd3367ae6f8ae1aeb82e9ac2f816c6fc483533d8297dd7884cd", 16), new BigInteger("b8f52fc6f38593dabb661d3f50f8897f8106eee68b1bce78a95b132b4e5b5d19", 16)); // // set up the keys // SecureRandom rand = new SecureRandom(); PrivateKey privKey; PublicKey pubKey; try { KeyFactory fact = KeyFactory.getInstance("RSA", "BC"); privKey = fact.generatePrivate(privKeySpec); pubKey = fact.generatePublic(pubKeySpec); } catch (Exception e) { return new SimpleTestResult(false, getName() + ": error setting up keys - " + e.toString()); } // // distinguished name table. // Hashtable attrs = new Hashtable(); attrs.put(X509Principal.C, "AU"); attrs.put(X509Principal.O, "The Legion of the Bouncy Castle"); attrs.put(X509Principal.L, "Melbourne"); attrs.put(X509Principal.ST, "Victoria"); attrs.put(X509Principal.E, "feedback-crypto@bouncycastle.org"); Vector ord = new Vector(); Vector values = new Vector(); ord.addElement(X509Principal.C); ord.addElement(X509Principal.O); ord.addElement(X509Principal.L); ord.addElement(X509Principal.ST); ord.addElement(X509Principal.E); values.addElement("AU"); values.addElement("The Legion of the Bouncy Castle"); values.addElement("Melbourne"); values.addElement("Victoria"); values.addElement("feedback-crypto@bouncycastle.org"); // // extensions // // // create the certificate - version 3 - without extensions // X509V3CertificateGenerator certGen = new X509V3CertificateGenerator(); certGen.setSerialNumber(BigInteger.valueOf(1)); certGen.setIssuerDN(new X509Principal(attrs)); certGen.setNotBefore(new Date(System.currentTimeMillis() - 50000)); certGen.setNotAfter(new Date(System.currentTimeMillis() + 50000)); certGen.setSubjectDN(new X509Principal(attrs)); certGen.setPublicKey(pubKey); certGen.setSignatureAlgorithm("SHA256WithRSAEncryption"); try { X509Certificate cert = certGen.generateX509Certificate(privKey); cert.checkValidity(new Date()); cert.verify(pubKey); Set dummySet = cert.getNonCriticalExtensionOIDs(); dummySet = cert.getNonCriticalExtensionOIDs(); } catch (Exception e) { return new SimpleTestResult(false, getName() + ": error setting generating cert - " + e.toString()); } // // create the certificate - version 3 - with extensions // certGen = new X509V3CertificateGenerator(); certGen.setSerialNumber(BigInteger.valueOf(1)); certGen.setIssuerDN(new X509Principal(attrs)); certGen.setNotBefore(new Date(System.currentTimeMillis() - 50000)); certGen.setNotAfter(new Date(System.currentTimeMillis() + 50000)); certGen.setSubjectDN(new X509Principal(attrs)); certGen.setPublicKey(pubKey); certGen.setSignatureAlgorithm("MD5WithRSAEncryption"); certGen.addExtension("2.5.29.15", true, new X509KeyUsage(X509KeyUsage.encipherOnly)); certGen.addExtension("2.5.29.37", true, new DERSequence(KeyPurposeId.anyExtendedKeyUsage)); certGen.addExtension("2.5.29.17", true, new GeneralNames(new GeneralName(GeneralName.rfc822Name, "test@test.test"))); try { X509Certificate cert = certGen.generateX509Certificate(privKey); cert.checkValidity(new Date()); cert.verify(pubKey); ByteArrayInputStream sbIn = new ByteArrayInputStream(cert.getEncoded()); ASN1InputStream sdIn = new ASN1InputStream(sbIn); ByteArrayInputStream bIn = new ByteArrayInputStream(cert.getEncoded()); CertificateFactory fact = CertificateFactory.getInstance("X.509", "BC"); cert = (X509Certificate)fact.generateCertificate(bIn); if (!cert.getKeyUsage()[7]) { return new SimpleTestResult(false, getName() + ": error generating cert - key usage wrong."); } // System.out.println(cert); } catch (Exception e) { return new SimpleTestResult(false, getName() + ": error setting generating cert - " + e.toString(), e); } // // create the certificate - version 1 // X509V1CertificateGenerator certGen1 = new X509V1CertificateGenerator(); certGen1.setSerialNumber(BigInteger.valueOf(1)); certGen1.setIssuerDN(new X509Principal(ord, attrs)); certGen1.setNotBefore(new Date(System.currentTimeMillis() - 50000)); certGen1.setNotAfter(new Date(System.currentTimeMillis() + 50000)); certGen1.setSubjectDN(new X509Principal(ord, values)); certGen1.setPublicKey(pubKey); certGen1.setSignatureAlgorithm("MD5WithRSAEncryption"); try { X509Certificate cert = certGen1.generateX509Certificate(privKey); cert.checkValidity(new Date()); cert.verify(pubKey); ByteArrayInputStream bIn = new ByteArrayInputStream(cert.getEncoded()); CertificateFactory fact = CertificateFactory.getInstance("X.509", "BC"); cert = (X509Certificate)fact.generateCertificate(bIn); // System.out.println(cert); if (!cert.getIssuerDN().equals(cert.getSubjectDN())) { return new SimpleTestResult(false, getName() + ": name comparison fails"); } } catch (Exception e) { return new SimpleTestResult(false, getName() + ": error setting generating cert - " + e.toString()); } return new SimpleTestResult(true, getName() + ": Okay"); } /** * we generate a self signed certificate for the sake of testing - DSA */ public TestResult checkCreation2() { // // set up the keys // PrivateKey privKey; PublicKey pubKey; try { KeyPairGenerator g = KeyPairGenerator.getInstance("DSA", "SUN"); g.initialize(512, new SecureRandom()); KeyPair p = g.generateKeyPair(); privKey = p.getPrivate(); pubKey = p.getPublic(); } catch (Exception e) { return new SimpleTestResult(false, getName() + ": error setting up keys - " + e.toString()); } // // distinguished name table. // Hashtable attrs = new Hashtable(); attrs.put(X509Principal.C, "AU"); attrs.put(X509Principal.O, "The Legion of the Bouncy Castle"); attrs.put(X509Principal.L, "Melbourne"); attrs.put(X509Principal.ST, "Victoria"); attrs.put(X509Principal.E, "feedback-crypto@bouncycastle.org"); // // extensions // // // create the certificate - version 3 // X509V3CertificateGenerator certGen = new X509V3CertificateGenerator(); certGen.setSerialNumber(BigInteger.valueOf(1)); certGen.setIssuerDN(new X509Principal(attrs)); certGen.setNotBefore(new Date(System.currentTimeMillis() - 50000)); certGen.setNotAfter(new Date(System.currentTimeMillis() + 50000)); certGen.setSubjectDN(new X509Principal(attrs)); certGen.setPublicKey(pubKey); certGen.setSignatureAlgorithm("SHA1withDSA"); try { X509Certificate cert = certGen.generateX509Certificate(privKey); cert.checkValidity(new Date()); cert.verify(pubKey); ByteArrayInputStream bIn = new ByteArrayInputStream(cert.getEncoded()); CertificateFactory fact = CertificateFactory.getInstance("X.509", "BC"); cert = (X509Certificate)fact.generateCertificate(bIn); // System.out.println(cert); } catch (Exception e) { return new SimpleTestResult(false, getName() + ": error setting generating cert - " + e.toString()); } // // create the certificate - version 1 // X509V1CertificateGenerator certGen1 = new X509V1CertificateGenerator(); certGen1.setSerialNumber(BigInteger.valueOf(1)); certGen1.setIssuerDN(new X509Principal(attrs)); certGen1.setNotBefore(new Date(System.currentTimeMillis() - 50000)); certGen1.setNotAfter(new Date(System.currentTimeMillis() + 50000)); certGen1.setSubjectDN(new X509Principal(attrs)); certGen1.setPublicKey(pubKey); certGen1.setSignatureAlgorithm("SHA1withDSA"); try { X509Certificate cert = certGen1.generateX509Certificate(privKey); cert.checkValidity(new Date()); cert.verify(pubKey); ByteArrayInputStream bIn = new ByteArrayInputStream(cert.getEncoded()); CertificateFactory fact = CertificateFactory.getInstance("X.509", "BC"); cert = (X509Certificate)fact.generateCertificate(bIn); //System.out.println(cert); } catch (Exception e) { return new SimpleTestResult(false, getName() + ": error setting generating cert - " + e.toString()); } return new SimpleTestResult(true, getName() + ": Okay"); } /** * we generate a self signed certificate for the sake of testing - ECDSA */ public TestResult checkCreation3() { ECCurve curve = new ECCurve.Fp( new BigInteger("883423532389192164791648750360308885314476597252960362792450860609699839"), // q new BigInteger("7fffffffffffffffffffffff7fffffffffff8000000000007ffffffffffc", 16), // a new BigInteger("6b016c3bdcf18941d0d654921475ca71a9db2fb27d1d37796185c2942c0a", 16)); // b ECParameterSpec spec = new ECParameterSpec( curve, curve.decodePoint(Hex.decode("020ffa963cdca8816ccc33b8642bedf905c3d358573d3f27fbbd3b3cb9aaaf")), // G new BigInteger("883423532389192164791648750360308884807550341691627752275345424702807307")); // n ECPrivateKeySpec privKeySpec = new ECPrivateKeySpec( new BigInteger("876300101507107567501066130761671078357010671067781776716671676178726717"), // d spec); ECPublicKeySpec pubKeySpec = new ECPublicKeySpec( curve.decodePoint(Hex.decode("025b6dc53bc61a2548ffb0f671472de6c9521a9d2d2534e65abfcbd5fe0c70")), // Q spec); // // set up the keys // PrivateKey privKey; PublicKey pubKey; try { KeyFactory fact = KeyFactory.getInstance("ECDSA", "BC"); privKey = fact.generatePrivate(privKeySpec); pubKey = fact.generatePublic(pubKeySpec); } catch (Exception e) { return new SimpleTestResult(false, getName() + ": error setting up keys - " + e.toString()); } // // distinguished name table. // Hashtable attrs = new Hashtable(); Vector order = new Vector(); attrs.put(X509Principal.C, "AU"); attrs.put(X509Principal.O, "The Legion of the Bouncy Castle"); attrs.put(X509Principal.L, "Melbourne"); attrs.put(X509Principal.ST, "Victoria"); attrs.put(X509Principal.E, "feedback-crypto@bouncycastle.org"); order.addElement(X509Principal.C); order.addElement(X509Principal.O); order.addElement(X509Principal.L); order.addElement(X509Principal.ST); order.addElement(X509Principal.E); // // toString test // X509Principal p = new X509Principal(order, attrs); String s = p.toString(); if (!s.equals("C=AU,O=The Legion of the Bouncy Castle,L=Melbourne,ST=Victoria,E=feedback-crypto@bouncycastle.org")) { return new SimpleTestResult(false, getName() + ": ordered X509Principal test failed - s = " + s + "."); } p = new X509Principal(attrs); s = p.toString(); // // we need two of these as the hash code for strings changed... // if (!s.equals("O=The Legion of the Bouncy Castle,E=feedback-crypto@bouncycastle.org,ST=Victoria,L=Melbourne,C=AU") && !s.equals("ST=Victoria,L=Melbourne,C=AU,E=feedback-crypto@bouncycastle.org,O=The Legion of the Bouncy Castle")) { return new SimpleTestResult(false, getName() + ": unordered X509Principal test failed."); } // // create the certificate - version 3 // X509V3CertificateGenerator certGen = new X509V3CertificateGenerator(); certGen.setSerialNumber(BigInteger.valueOf(1)); certGen.setIssuerDN(new X509Principal(order, attrs)); certGen.setNotBefore(new Date(System.currentTimeMillis() - 50000)); certGen.setNotAfter(new Date(System.currentTimeMillis() + 50000)); certGen.setSubjectDN(new X509Principal(order, attrs)); certGen.setPublicKey(pubKey); certGen.setSignatureAlgorithm("ECDSAwithSHA1"); try { X509Certificate cert = certGen.generateX509Certificate(privKey); cert.checkValidity(new Date()); cert.verify(pubKey); ByteArrayInputStream bIn = new ByteArrayInputStream(cert.getEncoded()); CertificateFactory fact = CertificateFactory.getInstance("X.509", "BC"); cert = (X509Certificate)fact.generateCertificate(bIn); // // try with point compression turned off // ((ECPointEncoder)pubKey).setPointFormat("UNCOMPRESSED"); certGen.setPublicKey(pubKey); cert = certGen.generateX509Certificate(privKey); cert.checkValidity(new Date()); cert.verify(pubKey); bIn = new ByteArrayInputStream(cert.getEncoded()); fact = CertificateFactory.getInstance("X.509", "BC"); cert = (X509Certificate)fact.generateCertificate(bIn); // System.out.println(cert); } catch (Exception e) { return new SimpleTestResult(false, getName() + ": error setting generating cert - " + e.toString()); } X509Principal pr = new X509Principal("O=\"The Bouncy Castle, The Legion of\",E=feedback-crypto@bouncycastle.org,ST=Victoria,L=Melbourne,C=AU"); if (!pr.toString().equals("O=The Bouncy Castle\\, The Legion of,E=feedback-crypto@bouncycastle.org,ST=Victoria,L=Melbourne,C=AU")) { return new SimpleTestResult(false, getName() + ": string based X509Principal test failed."); } pr = new X509Principal("O=The Bouncy Castle\\, The Legion of,E=feedback-crypto@bouncycastle.org,ST=Victoria,L=Melbourne,C=AU"); if (!pr.toString().equals("O=The Bouncy Castle\\, The Legion of,E=feedback-crypto@bouncycastle.org,ST=Victoria,L=Melbourne,C=AU")) { return new SimpleTestResult(false, getName() + ": string based X509Principal test failed."); } return new SimpleTestResult(true, getName() + ": Okay"); } public TestResult checkCRL( int id, byte[] bytes) { ByteArrayInputStream bIn; String dump = ""; try { bIn = new ByteArrayInputStream(bytes); CertificateFactory fact = CertificateFactory.getInstance("X.509", "BC"); CRL cert = fact.generateCRL(bIn); // System.out.println(cert); } catch (Exception e) { return new SimpleTestResult(false, dump + System.getProperty("line.separator") + getName() + ": " + id + " failed - exception " + e.toString(), e); } return new SimpleTestResult(true, getName() + ": " + id + " Okay"); } // /** // * we generate a self signed certificate for the sake of testing - GOST3410 // */ // public TestResult checkCreation4() // { // // // // set up the keys // // // PrivateKey privKey; // PublicKey pubKey; // // try // { // KeyPairGenerator g = KeyPairGenerator.getInstance("GOST3410", "BC"); // GOST3410ParameterSpec gost3410P = new GOST3410ParameterSpec("GostR3410-94-CryptoPro-A"); // // g.initialize(gost3410P, new SecureRandom()); // // KeyPair p = g.generateKeyPair(); // // privKey = p.getPrivate(); // pubKey = p.getPublic(); // } // catch (Exception e) // { // return new SimpleTestResult(false, getName() + ": error setting up keys - " + e.toString()); // } // // // // // distinguished name table. // // // Hashtable attrs = new Hashtable(); // // attrs.put(X509Principal.C, "AU"); // attrs.put(X509Principal.O, "The Legion of the Bouncy Castle"); // attrs.put(X509Principal.L, "Melbourne"); // attrs.put(X509Principal.ST, "Victoria"); // attrs.put(X509Principal.E, "feedback-crypto@bouncycastle.org"); // // // // // extensions // // // // // // // create the certificate - version 3 // // // X509V3CertificateGenerator certGen = new X509V3CertificateGenerator(); // // certGen.setSerialNumber(BigInteger.valueOf(1)); // certGen.setIssuerDN(new X509Principal(attrs)); // certGen.setNotBefore(new Date(System.currentTimeMillis() - 50000)); // certGen.setNotAfter(new Date(System.currentTimeMillis() + 50000)); // certGen.setSubjectDN(new X509Principal(attrs)); // certGen.setPublicKey(pubKey); // certGen.setSignatureAlgorithm("GOST3411withGOST3410"); // // try // { // X509Certificate cert = certGen.generateX509Certificate(privKey); // // cert.checkValidity(new Date()); // // // // // check verifies in general // // // cert.verify(pubKey); // // // // // check verifies with contained key // // // cert.verify(cert.getPublicKey()); // // ByteArrayInputStream bIn = new ByteArrayInputStream(cert.getEncoded()); // CertificateFactory fact = CertificateFactory.getInstance("X.509", "BC"); // // cert = (X509Certificate)fact.generateCertificate(bIn); // // //System.out.println(cert); // // //check getEncoded() // byte[] bytesch = cert.getEncoded(); // } // catch (Exception e) // { // return new SimpleTestResult(false, getName() + ": error setting generating cert - " + e.toString(), e); // } // // return new SimpleTestResult(true, getName() + ": Okay"); // } public TestResult perform() { TestResult res; res = checkCertificate(1, cert1); if (!res.isSuccessful()) { return res; } res = checkCertificate(2, cert2); if (!res.isSuccessful()) { return res; } res = checkCertificate(4, cert4); if (!res.isSuccessful()) { return res; } res = checkCertificate(5, cert5); if (!res.isSuccessful()) { return res; } res = checkCertificate(6, oldEcdsa); if (!res.isSuccessful()) { return res; } res = checkCertificate(7, cert7); if (!res.isSuccessful()) { return res; } res = checkKeyUsage(8, keyUsage); if (!res.isSuccessful()) { return res; } res = checkSelfSignedCertificate(9, uncompressedPtEC); if (!res.isSuccessful()) { return res; } res = checkNameCertificate(10, nameCert); if (!res.isSuccessful()) { return res; } res = checkSelfSignedCertificate(11, probSelfSignedCert); if (!res.isSuccessful()) { return res; } res = checkSelfSignedCertificate(12, gostCA1); if (!res.isSuccessful()) { return res; } res = checkSelfSignedCertificate(13, gostCA2); if (!res.isSuccessful()) { return res; } res = checkSelfSignedCertificate(14, gost341094base); if (!res.isSuccessful()) { return res; } res = checkSelfSignedCertificate(15, gost34102001base); if (!res.isSuccessful()) { return res; } res = checkSelfSignedCertificate(16, gost341094A); if (!res.isSuccessful()) { return res; } res = checkSelfSignedCertificate(17, gost341094B); if (!res.isSuccessful()) { return res; } res = checkSelfSignedCertificate(17, gost34102001A); if (!res.isSuccessful()) { return res; } res = checkCRL(1, crl1); if (!res.isSuccessful()) { return res; } res = checkCreation1(); if (!res.isSuccessful()) { return res; } res = checkCreation2(); if (!res.isSuccessful()) { return res; } res = checkCreation3(); if (!res.isSuccessful()) { return res; } // res = checkCreation4(); // if (!res.isSuccessful()) // { // return res; // } return new SimpleTestResult(true, getName() + ": Okay"); } public static void main( String[] args) { Security.addProvider(new BouncyCastleProvider()); Test test = new CertTest(); TestResult result = test.perform(); System.out.println(result); } } bouncycastle-1.49.orig/jdk1.1/org/bouncycastle/jce/provider/test/PKCS10CertRequestTest.java0000644000175000017500000000645511705654530031070 0ustar ebourgebourgpackage org.bouncycastle.jce.provider.test; import java.io.ByteArrayInputStream; import java.io.ByteArrayOutputStream; import java.security.KeyPair; import java.security.KeyPairGenerator; import java.security.Security; import java.util.Hashtable; import org.bouncycastle.asn1.ASN1InputStream; import org.bouncycastle.asn1.ASN1Sequence; import org.bouncycastle.asn1.DEROutputStream; import org.bouncycastle.asn1.x509.X509Name; import org.bouncycastle.jce.PKCS10CertificationRequest; import org.bouncycastle.jce.X509Principal; import org.bouncycastle.jce.provider.BouncyCastleProvider; import org.bouncycastle.util.test.SimpleTestResult; import org.bouncycastle.util.test.Test; import org.bouncycastle.util.test.TestResult; /** **/ public class PKCS10CertRequestTest implements Test { public String getName() { return "PKCS10CertRequest"; } public TestResult perform() { try { KeyPairGenerator kpg = KeyPairGenerator.getInstance("RSA", "BC"); kpg.initialize(512); KeyPair kp = kpg.generateKeyPair(); Hashtable attrs = new Hashtable(); attrs.put(X509Principal.C, "AU"); attrs.put(X509Principal.O, "The Legion of the Bouncy Castle"); attrs.put(X509Principal.L, "Melbourne"); attrs.put(X509Principal.ST, "Victoria"); attrs.put(X509Principal.EmailAddress, "feedback-crypto@bouncycastle.org"); X509Name subject = new X509Name(attrs); PKCS10CertificationRequest req1 = new PKCS10CertificationRequest( "SHA1withRSA", subject, kp.getPublic(), null, kp.getPrivate()); ByteArrayOutputStream bOut = new ByteArrayOutputStream(); DEROutputStream dOut = new DEROutputStream(bOut); dOut.writeObject(req1); dOut.close(); ByteArrayInputStream bIn = new ByteArrayInputStream(bOut.toByteArray()); ASN1InputStream dIn = new ASN1InputStream(bIn); PKCS10CertificationRequest req2 = new PKCS10CertificationRequest( (ASN1Sequence)dIn.readObject()); if (!req2.verify()) { return new SimpleTestResult(false, getName() + ": Failed verify check."); } if (!req2.getPublicKey().equals(req1.getPublicKey())) { return new SimpleTestResult(false, getName() + ": Failed public key check."); } return new SimpleTestResult(true, getName() + ": Okay"); } catch (Exception e) { e.printStackTrace(); return new SimpleTestResult(false, getName() + ": exception - " + e.toString()); } } public static void main( String[] args) { Security.addProvider(new BouncyCastleProvider()); Test test = new PKCS10CertRequestTest(); TestResult result = test.perform(); System.out.println(result.toString()); } } bouncycastle-1.49.orig/jdk1.1/org/bouncycastle/jce/provider/CertStoreCollectionSpi.java0000644000175000017500000000532411705654527030563 0ustar ebourgebourgpackage org.bouncycastle.jce.provider; import java.security.InvalidAlgorithmParameterException; import java.security.cert.CRL; import java.security.cert.CRLSelector; import java.security.cert.CertSelector; import java.security.cert.CertStoreException; import java.security.cert.CertStoreParameters; import java.security.cert.CertStoreSpi; import java.security.cert.Certificate; import java.security.cert.CollectionCertStoreParameters; import java.util.Collection; import java.util.HashSet; import java.util.Iterator; import java.util.Set; public class CertStoreCollectionSpi extends CertStoreSpi { private CollectionCertStoreParameters params; public CertStoreCollectionSpi(CertStoreParameters params) throws InvalidAlgorithmParameterException { super(params); if (!(params instanceof CollectionCertStoreParameters)) { throw new InvalidAlgorithmParameterException( "org.bouncycastle.jce.provider.CertStoreCollectionSpi: parameter must be a CollectionCertStoreParameters object\n" + params.toString() ); } this.params = (CollectionCertStoreParameters)params; } public Collection engineGetCertificates( CertSelector selector) throws CertStoreException { Set col = new HashSet(); Iterator iter = params.getCollection().iterator(); if (selector == null) { while (iter.hasNext()) { Object obj = iter.next(); if (obj instanceof Certificate) { col.add(obj); } } } else { while (iter.hasNext()) { Object obj = iter.next(); if ((obj instanceof Certificate) && selector.match((Certificate)obj)) { col.add(obj); } } } return col; } public Collection engineGetCRLs( CRLSelector selector) throws CertStoreException { Set col = new HashSet(); Iterator iter = params.getCollection().iterator(); if (selector == null) { while (iter.hasNext()) { Object obj = iter.next(); if (obj instanceof CRL) { col.add(obj); } } } else { while (iter.hasNext()) { Object obj = iter.next(); if ((obj instanceof CRL) && selector.match((CRL)obj)) { col.add(obj); } } } return col; } } bouncycastle-1.49.orig/jdk1.1/org/bouncycastle/jce/provider/RFC3280CertPathUtilities.java0000644000175000017500000000643512147310320030420 0ustar ebourgebourgpackage org.bouncycastle.jce.provider; import java.io.IOException; import java.math.BigInteger; import java.security.GeneralSecurityException; import java.security.PublicKey; import java.security.cert.CertPath; import java.security.cert.CertPathBuilder; import java.security.cert.CertPathBuilderException; import java.security.cert.CertPathValidatorException; import java.security.cert.CertificateExpiredException; import java.security.cert.CertificateNotYetValidException; import java.security.cert.PKIXCertPathChecker; import java.security.cert.X509CRL; import java.security.cert.X509Certificate; import java.security.cert.X509Extension; import java.util.ArrayList; import java.util.Collection; import java.util.Date; import java.util.Enumeration; import java.util.HashMap; import java.util.HashSet; import java.util.Iterator; import java.util.List; import java.util.Map; import java.util.Set; import java.util.Vector; import org.bouncycastle.asn1.ASN1EncodableVector; import org.bouncycastle.asn1.ASN1InputStream; import org.bouncycastle.asn1.ASN1Sequence; import org.bouncycastle.asn1.ASN1TaggedObject; import org.bouncycastle.asn1.x509.BasicConstraints; import org.bouncycastle.asn1.x509.CRLDistPoint; import org.bouncycastle.asn1.x509.CRLReason; import org.bouncycastle.asn1.x509.DistributionPoint; import org.bouncycastle.asn1.x509.DistributionPointName; import org.bouncycastle.asn1.x509.GeneralName; import org.bouncycastle.asn1.x509.GeneralNames; import org.bouncycastle.asn1.x509.GeneralSubtree; import org.bouncycastle.asn1.x509.IssuingDistributionPoint; import org.bouncycastle.asn1.x509.NameConstraints; import org.bouncycastle.asn1.x509.PolicyInformation; import org.bouncycastle.asn1.x509.X509Extensions; import org.bouncycastle.asn1.x509.X509Name; import org.bouncycastle.util.Arrays; public class RFC3280CertPathUtilities { public static final String CERTIFICATE_POLICIES = X509Extensions.CertificatePolicies.getId(); public static final String POLICY_MAPPINGS = X509Extensions.PolicyMappings.getId(); public static final String INHIBIT_ANY_POLICY = X509Extensions.InhibitAnyPolicy.getId(); public static final String ISSUING_DISTRIBUTION_POINT = X509Extensions.IssuingDistributionPoint.getId(); public static final String FRESHEST_CRL = X509Extensions.FreshestCRL.getId(); public static final String DELTA_CRL_INDICATOR = X509Extensions.DeltaCRLIndicator.getId(); public static final String POLICY_CONSTRAINTS = X509Extensions.PolicyConstraints.getId(); public static final String BASIC_CONSTRAINTS = X509Extensions.BasicConstraints.getId(); public static final String CRL_DISTRIBUTION_POINTS = X509Extensions.CRLDistributionPoints.getId(); public static final String SUBJECT_ALTERNATIVE_NAME = X509Extensions.SubjectAlternativeName.getId(); public static final String NAME_CONSTRAINTS = X509Extensions.NameConstraints.getId(); public static final String AUTHORITY_KEY_IDENTIFIER = X509Extensions.AuthorityKeyIdentifier.getId(); public static final String KEY_USAGE = X509Extensions.KeyUsage.getId(); public static final String CRL_NUMBER = X509Extensions.CRLNumber.getId(); public static final String ANY_POLICY = "2.5.29.32.0"; /* * key usage bits */ public static final int KEY_CERT_SIGN = 5; public static final int CRL_SIGN = 6; } bouncycastle-1.49.orig/jdk1.1/org/bouncycastle/jce/provider/BouncyCastleProvider.java0000644000175000017500000002332612147276205030263 0ustar ebourgebourgpackage org.bouncycastle.jce.provider; import java.io.IOException; import java.security.PrivateKey; import java.security.Provider; import java.security.PublicKey; import java.util.HashMap; import java.util.Map; import org.bouncycastle.asn1.ASN1ObjectIdentifier; import org.bouncycastle.asn1.pkcs.PrivateKeyInfo; import org.bouncycastle.asn1.x509.SubjectPublicKeyInfo; import org.bouncycastle.jcajce.provider.config.ConfigurableProvider; import org.bouncycastle.jcajce.provider.config.ProviderConfiguration; import org.bouncycastle.jcajce.provider.util.AlgorithmProvider; import org.bouncycastle.jcajce.provider.util.AsymmetricKeyInfoConverter; /** * To add the provider at runtime use: *

     * import java.security.Security;
     * import org.bouncycastle.jce.provider.BouncyCastleProvider;
     *
     * Security.addProvider(new BouncyCastleProvider());
     * 
    * The provider can also be configured as part of your environment via * static registration by adding an entry to the java.security properties * file (found in $JAVA_HOME/jre/lib/security/java.security, where * $JAVA_HOME is the location of your JDK/JRE distribution). You'll find * detailed instructions in the file but basically it comes down to adding * a line: *
     * 
     *    security.provider.<n>=org.bouncycastle.jce.provider.BouncyCastleProvider
     * 
     * 
    * Where <n> is the preference you want the provider at (1 being the * most preferred). *

    Note: JCE algorithm names should be upper-case only so the case insensitive * test for getInstance works. */ public final class BouncyCastleProvider extends Provider implements ConfigurableProvider { private static String info = "BouncyCastle Security Provider v1.49"; public static final String PROVIDER_NAME = "BC"; public static final ProviderConfiguration CONFIGURATION = new BouncyCastleProviderConfiguration(); private static final Map keyInfoConverters = new HashMap(); /* * Configurable symmetric ciphers */ private static final String SYMMETRIC_PACKAGE = "org.bouncycastle.jcajce.provider.symmetric."; private static final String[] SYMMETRIC_GENERIC = { "PBEPBKDF2", "PBEPKCS12" }; private static final String[] SYMMETRIC_MACS = { "SipHash" }; private static final String[] SYMMETRIC_CIPHERS = { "AES", "ARC4", "Blowfish", "Camellia", "CAST5", "CAST6", "DES", "DESede", "GOST28147", "Grainv1", "Grain128", "HC128", "HC256", "IDEA", "Noekeon", "RC2", "RC5", "RC6", "Rijndael", "Salsa20", "SEED", "Serpent", "Skipjack", "TEA", "Twofish", "VMPC", "VMPCKSA3", "XTEA" }; /* * Configurable asymmetric ciphers */ private static final String ASYMMETRIC_PACKAGE = "org.bouncycastle.jcajce.provider.asymmetric."; // this one is required for GNU class path - it needs to be loaded first as the // later ones configure it. private static final String[] ASYMMETRIC_GENERIC = { "X509", "IES" }; private static final String[] ASYMMETRIC_CIPHERS = { "DSA", "DH", "EC", "RSA", "GOST", "ECGOST", "ElGamal", "DSTU4145" }; /* * Configurable digests */ private static final String DIGEST_PACKAGE = "org.bouncycastle.jcajce.provider.digest."; private static final String[] DIGESTS = { "GOST3411", "MD2", "MD4", "MD5", "SHA1", "RIPEMD128", "RIPEMD160", "RIPEMD256", "RIPEMD320", "SHA224", "SHA256", "SHA384", "SHA512", "SHA3", "Tiger", "Whirlpool" }; /* * Configurable digests */ private static final String KEYSTORE_PACKAGE = "org.bouncycastle.jcajce.provider.keystore."; private static final String[] KEYSTORES = { "BC", "PKCS12" }; /** * Construct a new provider. This should only be required when * using runtime registration of the provider using the * Security.addProvider() mechanism. */ public BouncyCastleProvider() { super(PROVIDER_NAME, 1.49, info); setup(); } private void setup() { loadAlgorithms(DIGEST_PACKAGE, DIGESTS); loadAlgorithms(SYMMETRIC_PACKAGE, SYMMETRIC_GENERIC); loadAlgorithms(SYMMETRIC_PACKAGE, SYMMETRIC_MACS); loadAlgorithms(SYMMETRIC_PACKAGE, SYMMETRIC_CIPHERS); loadAlgorithms(ASYMMETRIC_PACKAGE, ASYMMETRIC_GENERIC); loadAlgorithms(ASYMMETRIC_PACKAGE, ASYMMETRIC_CIPHERS); loadAlgorithms(KEYSTORE_PACKAGE, KEYSTORES); // // X509Store // put("X509Store.CERTIFICATE/COLLECTION", "org.bouncycastle.jce.provider.X509StoreCertCollection"); put("X509Store.ATTRIBUTECERTIFICATE/COLLECTION", "org.bouncycastle.jce.provider.X509StoreAttrCertCollection"); put("X509Store.CRL/COLLECTION", "org.bouncycastle.jce.provider.X509StoreCRLCollection"); put("X509Store.CERTIFICATEPAIR/COLLECTION", "org.bouncycastle.jce.provider.X509StoreCertPairCollection"); put("X509Store.CERTIFICATE/LDAP", "org.bouncycastle.jce.provider.X509StoreLDAPCerts"); put("X509Store.CRL/LDAP", "org.bouncycastle.jce.provider.X509StoreLDAPCRLs"); put("X509Store.ATTRIBUTECERTIFICATE/LDAP", "org.bouncycastle.jce.provider.X509StoreLDAPAttrCerts"); put("X509Store.CERTIFICATEPAIR/LDAP", "org.bouncycastle.jce.provider.X509StoreLDAPCertPairs"); // // X509StreamParser // put("X509StreamParser.CERTIFICATE", "org.bouncycastle.jce.provider.X509CertParser"); put("X509StreamParser.ATTRIBUTECERTIFICATE", "org.bouncycastle.jce.provider.X509AttrCertParser"); put("X509StreamParser.CRL", "org.bouncycastle.jce.provider.X509CRLParser"); put("X509StreamParser.CERTIFICATEPAIR", "org.bouncycastle.jce.provider.X509CertPairParser"); // // cipher engines // put("Cipher.BROKENPBEWITHMD5ANDDES", "org.bouncycastle.jce.provider.BrokenJCEBlockCipher$BrokePBEWithMD5AndDES"); put("Cipher.BROKENPBEWITHSHA1ANDDES", "org.bouncycastle.jce.provider.BrokenJCEBlockCipher$BrokePBEWithSHA1AndDES"); put("Cipher.OLDPBEWITHSHAANDTWOFISH-CBC", "org.bouncycastle.jce.provider.BrokenJCEBlockCipher$OldPBEWithSHAAndTwofish"); // Certification Path API put("CertPathValidator.RFC3281", "org.bouncycastle.jce.provider.PKIXAttrCertPathValidatorSpi"); put("CertPathBuilder.RFC3281", "org.bouncycastle.jce.provider.PKIXAttrCertPathBuilderSpi"); put("CertPathValidator.RFC3280", "org.bouncycastle.jce.provider.PKIXCertPathValidatorSpi"); put("CertPathBuilder.RFC3280", "org.bouncycastle.jce.provider.PKIXCertPathBuilderSpi"); put("CertPathValidator.PKIX", "org.bouncycastle.jce.provider.PKIXCertPathValidatorSpi"); put("CertPathBuilder.PKIX", "org.bouncycastle.jce.provider.PKIXCertPathBuilderSpi"); put("CertStore.Collection", "org.bouncycastle.jce.provider.CertStoreCollectionSpi"); put("CertStore.LDAP", "org.bouncycastle.jce.provider.X509LDAPCertStoreSpi"); put("CertStore.Multi", "org.bouncycastle.jce.provider.MultiCertStoreSpi"); put("Alg.Alias.CertStore.X509LDAP", "LDAP"); } private void loadAlgorithms(String packageName, String[] names) { for (int i = 0; i != names.length; i++) { Class clazz = null; try { ClassLoader loader = this.getClass().getClassLoader(); if (loader != null) { clazz = loader.loadClass(packageName + names[i] + "$Mappings"); } else { clazz = Class.forName(packageName + names[i] + "$Mappings"); } } catch (ClassNotFoundException e) { // ignore } if (clazz != null) { try { ((AlgorithmProvider)clazz.newInstance()).configure(this); } catch (Exception e) { // this should never ever happen!! throw new InternalError("cannot create instance of " + packageName + names[i] + "$Mappings : " + e); } } } } public void setParameter(String parameterName, Object parameter) { synchronized (CONFIGURATION) { ((BouncyCastleProviderConfiguration)CONFIGURATION).setParameter(parameterName, parameter); } } public boolean hasAlgorithm(String type, String name) { return containsKey(type + "." + name) || containsKey("Alg.Alias." + type + "." + name); } public void addAlgorithm(String key, String value) { if (containsKey(key)) { throw new IllegalStateException("duplicate provider key (" + key + ") found"); } put(key, value); } public void addKeyInfoConverter(ASN1ObjectIdentifier oid, AsymmetricKeyInfoConverter keyInfoConverter) { keyInfoConverters.put(oid, keyInfoConverter); } public static PublicKey getPublicKey(SubjectPublicKeyInfo publicKeyInfo) throws IOException { AsymmetricKeyInfoConverter converter = (AsymmetricKeyInfoConverter)keyInfoConverters.get(publicKeyInfo.getAlgorithm().getAlgorithm()); if (converter == null) { return null; } return converter.generatePublic(publicKeyInfo); } public static PrivateKey getPrivateKey(PrivateKeyInfo privateKeyInfo) throws IOException { AsymmetricKeyInfoConverter converter = (AsymmetricKeyInfoConverter)keyInfoConverters.get(privateKeyInfo.getPrivateKeyAlgorithm().getAlgorithm()); if (converter == null) { return null; } return converter.generatePrivate(privateKeyInfo); } } bouncycastle-1.49.orig/jdk1.1/org/bouncycastle/jce/provider/ProviderUtil.java0000644000175000017500000000223411705654527026606 0ustar ebourgebourgpackage org.bouncycastle.jce.provider; import org.bouncycastle.jcajce.provider.config.ConfigurableProvider; import org.bouncycastle.jce.spec.ECParameterSpec; import java.io.ByteArrayInputStream; import java.io.IOException; import java.io.InputStream; public class ProviderUtil { private static final long MAX_MEMORY = Integer.MAX_VALUE; private static volatile ECParameterSpec ecImplicitCaParams; static void setParameter(String parameterName, Object parameter) { if (parameterName.equals(ConfigurableProvider.EC_IMPLICITLY_CA)) { if (parameter instanceof ECParameterSpec || parameter == null) { ecImplicitCaParams = (ECParameterSpec)parameter; } } } public static ECParameterSpec getEcImplicitlyCa() { return ecImplicitCaParams; } static int getReadLimit(InputStream in) throws IOException { if (in instanceof ByteArrayInputStream) { return in.available(); } if (MAX_MEMORY > Integer.MAX_VALUE) { return Integer.MAX_VALUE; } return (int)MAX_MEMORY; } } bouncycastle-1.49.orig/jdk1.1/org/bouncycastle/jce/provider/PKIXCertPathBuilderSpi.java0000644000175000017500000002700711705654527030354 0ustar ebourgebourgpackage org.bouncycastle.jce.provider; import java.io.IOException; import java.security.InvalidAlgorithmParameterException; import java.security.PublicKey; import java.security.cert.*; import org.bouncycastle.jce.*; import java.util.ArrayList; import java.util.Collection; import java.util.HashSet; import java.util.Iterator; import java.util.List; import java.util.Set; /** * Implements the PKIX CertPathBuilding algorithem for BouncyCastle. *
    * MAYBE: implement more CertPath validation whil build path to omit invalid pathes * * @see CertPathBuilderSpi **/ public class PKIXCertPathBuilderSpi extends CertPathBuilderSpi { /** * Build and validate a CertPath using the given parameter. * * @param params PKIXBuilderParameters object containing all * information to build the CertPath **/ public CertPathBuilderResult engineBuild( CertPathParameters params) throws CertPathBuilderException, InvalidAlgorithmParameterException { if (!(params instanceof PKIXBuilderParameters)) { throw new InvalidAlgorithmParameterException("params must be a PKIXBuilderParameters instance"); } PKIXBuilderParameters pkixParams = (PKIXBuilderParameters)params; Collection targets; Iterator targetIter; List certPathList = new ArrayList(); X509Certificate cert; Collection certs; CertPath certPath = null; Exception certPathException = null; // search target certificates CertSelector certSelect = pkixParams.getTargetCertConstraints(); if (certSelect == null) { throw new CertPathBuilderException("targetCertConstraints must be non-null for CertPath building"); } try { targets = findCertificates(certSelect, pkixParams.getCertStores()); } catch (CertStoreException e) { throw new CertPathBuilderException(e); } if (targets.isEmpty()) { throw new CertPathBuilderException("no certificate found matching targetCertContraints"); } CertificateFactory cFact; CertPathValidator validator; try { cFact = CertificateFactory.getInstance("X.509", "BC"); validator = CertPathValidator.getInstance("PKIX", "BC"); } catch (Exception e) { throw new CertPathBuilderException("exception creating support classes: " + e); } // // check all potential target certificates targetIter = targets.iterator(); while (targetIter.hasNext()) { cert = (X509Certificate)targetIter.next(); certPathList.clear(); while (cert != null) { // add cert to the certpath certPathList.add(cert); // check wether the issuer of is a TrustAnchor if (findTrustAnchor(cert, pkixParams.getTrustAnchors()) != null) { try { certPath = cFact.generateCertPath(certPathList); PKIXCertPathValidatorResult result = (PKIXCertPathValidatorResult)validator.validate(certPath, pkixParams); return new PKIXCertPathBuilderResult(certPath, result.getTrustAnchor(), result.getPolicyTree(), result.getPublicKey()); } catch (CertificateException ex) { certPathException = ex; } catch (CertPathValidatorException ex) { certPathException = ex; } // if validation failed go to next certificate cert = null; } else { // try to get the issuer certificate from one // of the CertStores try { X509Certificate issuer = findIssuer(cert, pkixParams.getCertStores()); if (issuer.equals(cert)) { cert = null; } else { cert = issuer; } } catch (CertPathValidatorException ex) { certPathException = ex; cert = null; } } } } if (certPath != null) { throw new CertPathBuilderException("found certificate chain, but could not be validated", certPathException); } throw new CertPathBuilderException("unable to find certificate chain"); } /** * Search the given Set of TrustAnchor's for one that is the * issuer of the fiven X509 certificate. * * @param cert the X509 certificate * @param trustAnchors a Set of TrustAnchor's * * @return the TrustAnchor object if found or * null if not. * * @exception CertPathValidatorException if a TrustAnchor was * found but the signature verificytion on the given certificate * has thrown an exception. This Exception can be obtainted with * getCause() method. **/ final TrustAnchor findTrustAnchor( X509Certificate cert, Set trustAnchors) throws CertPathBuilderException { Iterator iter = trustAnchors.iterator(); TrustAnchor trust = null; PublicKey trustPublicKey = null; Exception invalidKeyEx = null; X509CertSelector certSelectX509 = new X509CertSelector(); try { certSelectX509.setSubject(PrincipalUtil.getIssuerX509Principal(cert).getEncoded()); } catch (CertificateEncodingException ex) { throw new CertPathBuilderException("can't get trust anchor principal",null); } catch (IOException ex) { throw new CertPathBuilderException("can't get trust anchor principal",null); } while (iter.hasNext() && trust == null) { trust = (TrustAnchor)iter.next(); if (trust.getTrustedCert() != null) { if (certSelectX509.match(trust.getTrustedCert())) { trustPublicKey = trust.getTrustedCert().getPublicKey(); } else { trust = null; } } else if (trust.getCAName() != null && trust.getCAPublicKey() != null) { try { X509Principal certIssuer = PrincipalUtil.getIssuerX509Principal(cert); X509Principal caName = new X509Principal(trust.getCAName()); if (certIssuer.equals(caName)) { trustPublicKey = trust.getCAPublicKey(); } else { trust = null; } } catch (CertificateEncodingException ex) { trust = null; } catch (IllegalArgumentException ex) { trust = null; } } else { trust = null; } if (trustPublicKey != null) { try { cert.verify(trustPublicKey); } catch (Exception ex) { invalidKeyEx = ex; trust = null; } } } if (trust == null && invalidKeyEx != null) { throw new CertPathBuilderException("TrustAnchor found put certificate validation failed",invalidKeyEx); } return trust; } /** * Return a Collection of all certificates found in the * CertStore's that are matching the certSelect criteriums. * * @param certSelector a {@link CertSelector CertSelector} * object that will be used to select the certificates * @param certStores a List containing only {@link CertStore * CertStore} objects. These are used to search for * certificates * * @return a Collection of all found {@link Certificate Certificate} * objects. May be empty but never null. **/ private Collection findCertificates( CertSelector certSelect, List certStores) throws CertStoreException { Set certs = new HashSet(); Iterator iter = certStores.iterator(); while (iter.hasNext()) { CertStore certStore = (CertStore)iter.next(); certs.addAll(certStore.getCertificates(certSelect)); } return certs; } /** * Find the issuer certificate of the given certificate. * * @param cert the certificate hows issuer certificate should * be found. * @param certStores a list of CertStore object * that will be searched * * @return then X509Certificate object containing * the issuer certificate or null if not found * * @exception CertPathValidatorException if a TrustAnchor was * found but the signature verificytion on the given certificate * has thrown an exception. This Exception can be obtainted with * getCause() method. **/ private X509Certificate findIssuer( X509Certificate cert, List certStores) throws CertPathValidatorException { Exception invalidKeyEx = null; X509CertSelector certSelect = new X509CertSelector(); try { certSelect.setSubject(PrincipalUtil.getIssuerX509Principal(cert).getEncoded()); } catch (CertificateEncodingException ex) { throw new CertPathValidatorException("Issuer not found", null, null, -1); } catch (IOException ex) { throw new CertPathValidatorException("Issuer not found", null, null, -1); } Iterator iter; try { iter = findCertificates(certSelect, certStores).iterator(); } catch (CertStoreException e) { throw new CertPathValidatorException(e); } X509Certificate issuer = null; while (iter.hasNext() && issuer == null) { issuer = (X509Certificate)iter.next(); try { cert.verify(issuer.getPublicKey()); } catch (Exception ex) { invalidKeyEx = ex; issuer = null; } } if (issuer == null && invalidKeyEx == null) { throw new CertPathValidatorException("Issuer not found", null, null, -1); } if (issuer == null && invalidKeyEx != null) { throw new CertPathValidatorException("issuer found but certificate validation failed",invalidKeyEx,null,-1); } return issuer; } } bouncycastle-1.49.orig/jdk1.1/org/bouncycastle/jce/provider/AnnotatedException.java0000644000175000017500000000100211705654527027742 0ustar ebourgebourgpackage org.bouncycastle.jce.provider; public class AnnotatedException extends Exception { private Throwable _underlyingException; AnnotatedException(String string, Throwable e) { super(string); _underlyingException = e; } AnnotatedException(String string) { this(string, null); } Throwable getUnderlyingException() { return _underlyingException; } public Throwable getCause() { return _underlyingException; } } bouncycastle-1.49.orig/jdk1.1/org/bouncycastle/jce/MultiCertStoreParameters.java0000644000175000017500000000267111705654527027302 0ustar ebourgebourgpackage org.bouncycastle.jce; import java.security.cert.CertStoreParameters; import java.util.Collection; public class MultiCertStoreParameters implements CertStoreParameters { private Collection certStores; private boolean searchAllStores; /** * Create a parameters object which specifies searching of all the passed in stores. * * @param certStores CertStores making up the multi CertStore */ public MultiCertStoreParameters(Collection certStores) { this(certStores, true); } /** * Create a parameters object which can be to used to make a multi store made up * of the passed in CertStores. If the searchAllStores parameter is false, any search on * the multi-store will terminate as soon as a search query produces a result. * * @param certStores CertStores making up the multi CertStore * @param searchAllStores true if all CertStores should be searched on request, false if a result * should be returned on the first successful CertStore query. */ public MultiCertStoreParameters(Collection certStores, boolean searchAllStores) { this.certStores = certStores; this.searchAllStores = searchAllStores; } public Collection getCertStores() { return certStores; } public boolean getSearchAllStores() { return searchAllStores; } public Object clone() { return this; } } bouncycastle-1.49.orig/jdk1.1/org/bouncycastle/jce/netscape/0000755000175000017500000000000012152033551023243 5ustar ebourgebourgbouncycastle-1.49.orig/jdk1.1/org/bouncycastle/jce/netscape/NetscapeCertRequest.java0000644000175000017500000002017212105031243030033 0ustar ebourgebourgpackage org.bouncycastle.jce.netscape; import java.io.ByteArrayInputStream; import java.io.ByteArrayOutputStream; import java.io.IOException; import java.security.InvalidKeyException; import java.security.KeyFactory; import java.security.NoSuchAlgorithmException; import java.security.NoSuchProviderException; import java.security.PrivateKey; import java.security.PublicKey; import java.security.SecureRandom; import java.security.Signature; import java.security.SignatureException; import java.security.spec.InvalidKeySpecException; import java.security.spec.X509EncodedKeySpec; import org.bouncycastle.asn1.ASN1EncodableVector; import org.bouncycastle.asn1.ASN1Encoding; import org.bouncycastle.asn1.ASN1InputStream; import org.bouncycastle.asn1.ASN1Object; import org.bouncycastle.asn1.ASN1Primitive; import org.bouncycastle.asn1.ASN1Sequence; import org.bouncycastle.asn1.DERBitString; import org.bouncycastle.asn1.DERIA5String; import org.bouncycastle.asn1.DERSequence; import org.bouncycastle.asn1.x509.AlgorithmIdentifier; import org.bouncycastle.asn1.x509.SubjectPublicKeyInfo; /** * * * Handles NetScape certificate request (KEYGEN), these are constructed as: *

    
     *   SignedPublicKeyAndChallenge ::= SEQUENCE {
     *     publicKeyAndChallenge    PublicKeyAndChallenge,
     *     signatureAlgorithm       AlgorithmIdentifier,
     *     signature                BIT STRING
     *   }
     * 
    * * PublicKey's encoded-format has to be X.509. * **/ public class NetscapeCertRequest extends ASN1Object { AlgorithmIdentifier sigAlg; AlgorithmIdentifier keyAlg; byte sigBits []; String challenge; DERBitString content; PublicKey pubkey ; private static ASN1Sequence getReq( byte[] r) throws IOException { ASN1InputStream aIn = new ASN1InputStream(new ByteArrayInputStream(r)); return ASN1Sequence.getInstance(aIn.readObject()); } public NetscapeCertRequest( byte[] req) throws IOException { this(getReq(req)); } public NetscapeCertRequest (ASN1Sequence spkac) { try { // // SignedPublicKeyAndChallenge ::= SEQUENCE { // publicKeyAndChallenge PublicKeyAndChallenge, // signatureAlgorithm AlgorithmIdentifier, // signature BIT STRING // } // if (spkac.size() != 3) { throw new IllegalArgumentException("invalid SPKAC (size):" + spkac.size()); } sigAlg = new AlgorithmIdentifier((ASN1Sequence)spkac .getObjectAt(1)); sigBits = ((DERBitString)spkac.getObjectAt(2)).getBytes(); // // PublicKeyAndChallenge ::= SEQUENCE { // spki SubjectPublicKeyInfo, // challenge IA5STRING // } // ASN1Sequence pkac = (ASN1Sequence)spkac.getObjectAt(0); if (pkac.size() != 2) { throw new IllegalArgumentException("invalid PKAC (len): " + pkac.size()); } challenge = ((DERIA5String)pkac.getObjectAt(1)).getString(); //this could be dangerous, as ASN.1 decoding/encoding //could potentially alter the bytes content = new DERBitString(pkac); SubjectPublicKeyInfo pubkeyinfo = new SubjectPublicKeyInfo( (ASN1Sequence)pkac.getObjectAt(0)); X509EncodedKeySpec xspec = new X509EncodedKeySpec(new DERBitString( pubkeyinfo).getBytes()); keyAlg = pubkeyinfo.getAlgorithmId(); pubkey = KeyFactory.getInstance(keyAlg.getObjectId().getId(), "BC") .generatePublic(xspec); } catch (Exception e) { throw new IllegalArgumentException(e.toString()); } } public NetscapeCertRequest( String challenge, AlgorithmIdentifier signing_alg, PublicKey pub_key) throws NoSuchAlgorithmException, InvalidKeySpecException, NoSuchProviderException, IOException { this.challenge = challenge; sigAlg = signing_alg; pubkey = pub_key; ASN1EncodableVector content_der = new ASN1EncodableVector(); content_der.add(getKeySpec()); //content_der.add(new SubjectPublicKeyInfo(sigAlg, new RSAPublicKeyStructure(pubkey.getModulus(), pubkey.getPublicExponent()).getDERObject())); content_der.add(new DERIA5String(challenge)); content = new DERBitString(new DERSequence(content_der)); } public String getChallenge() { return challenge; } public void setChallenge(String value) { challenge = value; } public AlgorithmIdentifier getSigningAlgorithm() { return sigAlg; } public void setSigningAlgorithm(AlgorithmIdentifier value) { sigAlg = value; } public AlgorithmIdentifier getKeyAlgorithm() { return keyAlg; } public void setKeyAlgorithm(AlgorithmIdentifier value) { keyAlg = value; } public PublicKey getPublicKey() { return pubkey; } public void setPublicKey(PublicKey value) { pubkey = value; } public boolean verify(String challenge) throws NoSuchAlgorithmException, InvalidKeyException, SignatureException, NoSuchProviderException { if (!challenge.equals(this.challenge)) { return false; } // // Verify the signature .. shows the response was generated // by someone who knew the associated private key // Signature sig = Signature.getInstance(sigAlg.getObjectId().getId(), "BC"); sig.initVerify(pubkey); sig.update(content.getBytes()); return sig.verify(sigBits); } public void sign(PrivateKey priv_key) throws NoSuchAlgorithmException, InvalidKeyException, SignatureException, NoSuchProviderException, InvalidKeySpecException { sign(priv_key, null); } public void sign(PrivateKey priv_key, SecureRandom rand) throws NoSuchAlgorithmException, InvalidKeyException, SignatureException, NoSuchProviderException, InvalidKeySpecException { Signature sig = Signature.getInstance(sigAlg.getAlgorithm().getId(), "BC"); if (rand != null) { sig.initSign(priv_key); } else { sig.initSign(priv_key); } ASN1EncodableVector pkac = new ASN1EncodableVector(); pkac.add(getKeySpec()); pkac.add(new DERIA5String(challenge)); try { sig.update(new DERSequence(pkac).getEncoded(ASN1Encoding.DER)); } catch (IOException ioe) { throw new SignatureException(ioe.getMessage()); } sigBits = sig.sign(); } private ASN1Primitive getKeySpec() throws NoSuchAlgorithmException, InvalidKeySpecException, NoSuchProviderException { ByteArrayOutputStream baos = new ByteArrayOutputStream(); ASN1Primitive obj = null; try { baos.write(pubkey.getEncoded()); baos.close(); ASN1InputStream derin = new ASN1InputStream( new ByteArrayInputStream(baos.toByteArray())); obj = derin.readObject(); } catch (IOException ioe) { throw new InvalidKeySpecException(ioe.getMessage()); } return obj; } public ASN1Primitive toASN1Primitive() { ASN1EncodableVector spkac = new ASN1EncodableVector(); ASN1EncodableVector pkac = new ASN1EncodableVector(); try { pkac.add(getKeySpec()); } catch (Exception e) { //ignore } pkac.add(new DERIA5String(challenge)); spkac.add(new DERSequence(pkac)); spkac.add(sigAlg); spkac.add(new DERBitString(sigBits)); return new DERSequence(spkac); } } bouncycastle-1.49.orig/jdk1.1/org/bouncycastle/openssl/0000755000175000017500000000000012152033551022363 5ustar ebourgebourgbouncycastle-1.49.orig/jdk1.1/org/bouncycastle/openssl/jcajce/0000755000175000017500000000000012152033551023602 5ustar ebourgebourg././@LongLink0000000000000000000000000000015300000000000011564 Lustar rootrootbouncycastle-1.49.orig/jdk1.1/org/bouncycastle/openssl/jcajce/JceOpenSSLPKCS8DecryptorProviderBuilder.javabouncycastle-1.49.orig/jdk1.1/org/bouncycastle/openssl/jcajce/JceOpenSSLPKCS8DecryptorProviderBuilde0000644000175000017500000001476012147310320032743 0ustar ebourgebourgpackage org.bouncycastle.openssl.jcajce; import java.io.IOException; import java.io.InputStream; import java.security.AlgorithmParameters; import java.security.GeneralSecurityException; import java.security.NoSuchAlgorithmException; import java.security.NoSuchProviderException; import java.security.InvalidKeyException; import java.security.Provider; import javax.crypto.Cipher; import javax.crypto.CipherInputStream; import javax.crypto.SecretKey; import javax.crypto.SecretKeyFactory; import javax.crypto.spec.PBEKeySpec; import javax.crypto.spec.PBEParameterSpec; import org.bouncycastle.asn1.pkcs.KeyDerivationFunc; import org.bouncycastle.asn1.pkcs.EncryptionScheme; import org.bouncycastle.asn1.pkcs.PBEParameter; import org.bouncycastle.asn1.pkcs.PBES2Parameters; import org.bouncycastle.asn1.pkcs.PBKDF2Params; import org.bouncycastle.asn1.pkcs.PKCS12PBEParams; import org.bouncycastle.asn1.x509.AlgorithmIdentifier; import org.bouncycastle.jcajce.DefaultJcaJceHelper; import org.bouncycastle.jcajce.JcaJceHelper; import org.bouncycastle.jcajce.NamedJcaJceHelper; import org.bouncycastle.jcajce.ProviderJcaJceHelper; import org.bouncycastle.openssl.PEMException; import org.bouncycastle.operator.InputDecryptor; import org.bouncycastle.operator.InputDecryptorProvider; import org.bouncycastle.operator.OperatorCreationException; public class JceOpenSSLPKCS8DecryptorProviderBuilder { private JcaJceHelper helper = new DefaultJcaJceHelper(); public JceOpenSSLPKCS8DecryptorProviderBuilder() { helper = new DefaultJcaJceHelper(); } public JceOpenSSLPKCS8DecryptorProviderBuilder setProvider(String providerName) { helper = new NamedJcaJceHelper(providerName); return this; } public JceOpenSSLPKCS8DecryptorProviderBuilder setProvider(Provider provider) { helper = new ProviderJcaJceHelper(provider); return this; } public InputDecryptorProvider build(final char[] password) throws OperatorCreationException { return new InputDecryptorProvider() { public InputDecryptor get(final AlgorithmIdentifier algorithm) throws OperatorCreationException { final Cipher cipher; try { if (PEMUtilities.isPKCS5Scheme2(algorithm.getAlgorithm())) { PBES2Parameters params = PBES2Parameters.getInstance(algorithm.getParameters()); KeyDerivationFunc func = params.getKeyDerivationFunc(); EncryptionScheme scheme = params.getEncryptionScheme(); PBKDF2Params defParams = (PBKDF2Params)func.getParameters(); int iterationCount = defParams.getIterationCount().intValue(); byte[] salt = defParams.getSalt(); String oid = scheme.getAlgorithm().getId(); SecretKey key = PEMUtilities.generateSecretKeyForPKCS5Scheme2(oid, password, salt, iterationCount); cipher = helper.createCipher(oid); AlgorithmParameters algParams = helper.createAlgorithmParameters(oid); algParams.init(scheme.getParameters().toASN1Primitive().getEncoded()); cipher.init(Cipher.DECRYPT_MODE, key, algParams); } else if (PEMUtilities.isPKCS12(algorithm.getAlgorithm())) { PKCS12PBEParams params = PKCS12PBEParams.getInstance(algorithm.getParameters()); PBEKeySpec pbeSpec = new PBEKeySpec(password); SecretKeyFactory secKeyFact = helper.createSecretKeyFactory(algorithm.getAlgorithm().getId()); PBEParameterSpec defParams = new PBEParameterSpec(params.getIV(), params.getIterations().intValue()); cipher = helper.createCipher(algorithm.getAlgorithm().getId()); cipher.init(Cipher.DECRYPT_MODE, secKeyFact.generateSecret(pbeSpec), defParams); } else if (PEMUtilities.isPKCS5Scheme1(algorithm.getAlgorithm())) { PBEParameter params = PBEParameter.getInstance(algorithm.getParameters()); PBEKeySpec pbeSpec = new PBEKeySpec(password); SecretKeyFactory secKeyFact = helper.createSecretKeyFactory(algorithm.getAlgorithm().getId()); PBEParameterSpec defParams = new PBEParameterSpec(params.getSalt(), params.getIterationCount().intValue()); cipher = helper.createCipher(algorithm.getAlgorithm().getId()); cipher.init(Cipher.DECRYPT_MODE, secKeyFact.generateSecret(pbeSpec), defParams); } else { throw new PEMException("Unknown algorithm: " + algorithm.getAlgorithm()); } return new InputDecryptor() { public AlgorithmIdentifier getAlgorithmIdentifier() { return algorithm; } public InputStream getInputStream(InputStream encIn) { return new CipherInputStream(encIn, cipher); } }; } catch (IOException e) { throw new OperatorCreationException(algorithm.getAlgorithm() + " not available: " + e.getMessage(), e); } catch (InvalidKeyException e) { throw new OperatorCreationException(algorithm.getAlgorithm() + " not available: " + e.getMessage(), e); } catch (NoSuchProviderException e) { throw new OperatorCreationException(algorithm.getAlgorithm() + " not available: " + e.getMessage(), e); } catch (NoSuchAlgorithmException e) { throw new OperatorCreationException(algorithm.getAlgorithm() + " not available: " + e.getMessage(), e); } catch (GeneralSecurityException e) { throw new OperatorCreationException(algorithm.getAlgorithm() + " not available: " + e.getMessage(), e); } }; }; } } bouncycastle-1.49.orig/jdk1.1/org/bouncycastle/openssl/jcajce/JceOpenSSLPKCS8EncryptorBuilder.java0000644000175000017500000001764212110277315032354 0ustar ebourgebourgpackage org.bouncycastle.openssl.jcajce; import java.io.IOException; import java.io.OutputStream; import java.security.AlgorithmParameterGenerator; import java.security.AlgorithmParameters; import java.security.GeneralSecurityException; import java.security.NoSuchAlgorithmException; import java.security.NoSuchProviderException; import java.security.InvalidKeyException; import java.security.Provider; import java.security.SecureRandom; import javax.crypto.Cipher; import javax.crypto.CipherOutputStream; import javax.crypto.SecretKey; import javax.crypto.SecretKeyFactory; import javax.crypto.spec.PBEKeySpec; import javax.crypto.spec.PBEParameterSpec; import org.bouncycastle.asn1.ASN1EncodableVector; import org.bouncycastle.asn1.ASN1Integer; import org.bouncycastle.asn1.ASN1ObjectIdentifier; import org.bouncycastle.asn1.ASN1Primitive; import org.bouncycastle.asn1.DEROctetString; import org.bouncycastle.asn1.DERSequence; import org.bouncycastle.asn1.nist.NISTObjectIdentifiers; import org.bouncycastle.asn1.pkcs.KeyDerivationFunc; import org.bouncycastle.asn1.pkcs.PBES2Parameters; import org.bouncycastle.asn1.pkcs.PBKDF2Params; import org.bouncycastle.asn1.pkcs.PKCS12PBEParams; import org.bouncycastle.asn1.pkcs.PKCSObjectIdentifiers; import org.bouncycastle.asn1.x509.AlgorithmIdentifier; import org.bouncycastle.jcajce.DefaultJcaJceHelper; import org.bouncycastle.jcajce.JcaJceHelper; import org.bouncycastle.jcajce.NamedJcaJceHelper; import org.bouncycastle.jcajce.ProviderJcaJceHelper; import org.bouncycastle.operator.GenericKey; import org.bouncycastle.operator.OperatorCreationException; import org.bouncycastle.operator.OutputEncryptor; import org.bouncycastle.operator.jcajce.JceGenericKey; public class JceOpenSSLPKCS8EncryptorBuilder { public static final String AES_128_CBC = NISTObjectIdentifiers.id_aes128_CBC.getId(); public static final String AES_192_CBC = NISTObjectIdentifiers.id_aes192_CBC.getId(); public static final String AES_256_CBC = NISTObjectIdentifiers.id_aes256_CBC.getId(); public static final String DES3_CBC = PKCSObjectIdentifiers.des_EDE3_CBC.getId(); public static final String PBE_SHA1_RC4_128 = PKCSObjectIdentifiers.pbeWithSHAAnd128BitRC4.getId(); public static final String PBE_SHA1_RC4_40 = PKCSObjectIdentifiers.pbeWithSHAAnd40BitRC4.getId(); public static final String PBE_SHA1_3DES = PKCSObjectIdentifiers.pbeWithSHAAnd3_KeyTripleDES_CBC.getId(); public static final String PBE_SHA1_2DES = PKCSObjectIdentifiers.pbeWithSHAAnd2_KeyTripleDES_CBC.getId(); public static final String PBE_SHA1_RC2_128 = PKCSObjectIdentifiers.pbeWithSHAAnd128BitRC2_CBC.getId(); public static final String PBE_SHA1_RC2_40 = PKCSObjectIdentifiers.pbeWithSHAAnd40BitRC2_CBC.getId(); private JcaJceHelper helper = new DefaultJcaJceHelper(); private AlgorithmParameters params; private ASN1ObjectIdentifier algOID; byte[] salt; int iterationCount; private Cipher cipher; private SecureRandom random; private AlgorithmParameterGenerator paramGen; private SecretKeyFactory secKeyFact; private char[] password; private SecretKey key; public JceOpenSSLPKCS8EncryptorBuilder(ASN1ObjectIdentifier algorithm) { algOID = algorithm; this.iterationCount = 2048; } public JceOpenSSLPKCS8EncryptorBuilder setRandom(SecureRandom random) { this.random = random; return this; } public JceOpenSSLPKCS8EncryptorBuilder setPasssword(char[] password) { this.password = password; return this; } public JceOpenSSLPKCS8EncryptorBuilder setIterationCount(int iterationCount) { this.iterationCount = iterationCount; return this; } public JceOpenSSLPKCS8EncryptorBuilder setProvider(String providerName) { helper = new NamedJcaJceHelper(providerName); return this; } public JceOpenSSLPKCS8EncryptorBuilder setProvider(Provider provider) { helper = new ProviderJcaJceHelper(provider); return this; } public OutputEncryptor build() throws OperatorCreationException { final AlgorithmIdentifier algID; salt = new byte[20]; if (random == null) { random = new SecureRandom(); } random.nextBytes(salt); try { this.cipher = helper.createCipher(algOID.getId()); if (PEMUtilities.isPKCS5Scheme2(algOID)) { this.paramGen = helper.createAlgorithmParameterGenerator(algOID.getId()); } else { this.secKeyFact = helper.createSecretKeyFactory(algOID.getId()); } } catch (NoSuchAlgorithmException e) { throw new OperatorCreationException(algOID + " not available: " + e.getMessage(), e); } catch (NoSuchProviderException e) { throw new OperatorCreationException(algOID + " not available: " + e.getMessage(), e); } catch (GeneralSecurityException e) { throw new OperatorCreationException(algOID + " not available: " + e.getMessage(), e); } if (PEMUtilities.isPKCS5Scheme2(algOID)) { params = paramGen.generateParameters(); try { KeyDerivationFunc scheme = new KeyDerivationFunc(algOID, ASN1Primitive.fromByteArray(params.getEncoded())); KeyDerivationFunc func = new KeyDerivationFunc(PKCSObjectIdentifiers.id_PBKDF2, new PBKDF2Params(salt, iterationCount)); ASN1EncodableVector v = new ASN1EncodableVector(); v.add(func); v.add(scheme); algID = new AlgorithmIdentifier(PKCSObjectIdentifiers.id_PBES2, PBES2Parameters.getInstance(new DERSequence(v))); } catch (IOException e) { throw new OperatorCreationException(e.getMessage(), e); } key = PEMUtilities.generateSecretKeyForPKCS5Scheme2(algOID.getId(), password, salt, iterationCount); try { cipher.init(Cipher.ENCRYPT_MODE, key, params); } catch (InvalidKeyException e) { throw new OperatorCreationException(e.getMessage(), e); } catch (GeneralSecurityException e) { throw new OperatorCreationException(e.getMessage(), e); } } else if (PEMUtilities.isPKCS12(algOID)) { ASN1EncodableVector v = new ASN1EncodableVector(); v.add(new DEROctetString(salt)); v.add(new ASN1Integer(iterationCount)); algID = new AlgorithmIdentifier(algOID, PKCS12PBEParams.getInstance(new DERSequence(v))); try { PBEKeySpec pbeSpec = new PBEKeySpec(password); PBEParameterSpec defParams = new PBEParameterSpec(salt, iterationCount); key = secKeyFact.generateSecret(pbeSpec); cipher.init(Cipher.ENCRYPT_MODE, key, defParams); } catch (InvalidKeyException e) { throw new OperatorCreationException(e.getMessage(), e); } catch (GeneralSecurityException e) { throw new OperatorCreationException(e.getMessage(), e); } } else { throw new OperatorCreationException("unknown algorithm: " + algOID, null); } return new OutputEncryptor() { public AlgorithmIdentifier getAlgorithmIdentifier() { return algID; } public OutputStream getOutputStream(OutputStream encOut) { return new CipherOutputStream(encOut, cipher); } public GenericKey getKey() { return new JceGenericKey(algID, key); } }; } } bouncycastle-1.49.orig/jdk1.1/java/0000755000175000017500000000000012152033550016336 5ustar ebourgebourgbouncycastle-1.49.orig/jdk1.1/java/util/0000755000175000017500000000000012152033550017313 5ustar ebourgebourgbouncycastle-1.49.orig/jdk1.1/java/util/AbstractCollection.java0000644000175000017500000001735011705654527023763 0ustar ebourgebourgpackage java.util; import java.lang.reflect.Array; /** * Title: * Description: * Copyright: Copyright (c) 2001 * Company: * @version 1.0 */ public abstract class AbstractCollection implements Collection { protected AbstractCollection() { } public abstract Iterator iterator(); public abstract int size(); public boolean isEmpty() { return size()==0; } public boolean contains(Object o) { Iterator it=iterator(); while(it.hasNext()) { Object e=it.next(); if(o==null) { if(e==null) return true; } else { if(o.equals(e)) return true; } } return false; } public Object[] toArray() { Object[] arObjects=new Object[size()]; Iterator it=iterator(); int i=0; while(it.hasNext()) { arObjects[i++]=it.next(); } return arObjects; } public Object[] toArray(Object[] a) throws NullPointerException,ArrayStoreException //TODO: Check if this is realy compatible to SUN!!! { if(a==null) throw new NullPointerException(); if (isEmpty()) return a; Object[] arObjects=null; int size=size(); if(a.lengthsize) arObjects[size]=null; } Iterator it=iterator(); int i=0; while(it.hasNext()) { Object o=it.next(); arObjects[i++]=o; } return arObjects; } public boolean add(Object o) throws UnsupportedOperationException,NullPointerException,ClassCastException,IllegalArgumentException { throw new UnsupportedOperationException(); } public boolean remove(Object o) throws UnsupportedOperationException { Iterator it=iterator(); while(it.hasNext()) { Object e=it.next(); if(o==null) { if(e==null) { try { it.remove(); } catch(UnsupportedOperationException ue) { throw ue; } return true; } } else { if(o.equals(e)) { try { it.remove(); } catch(UnsupportedOperationException ue) { throw ue; } return true; } } } return false; } public boolean containsAll(Collection c) { Iterator it=c.iterator(); while(it.hasNext()) { if(!contains(it.next())) return false; } return true; } public boolean addAll(Collection c) throws UnsupportedOperationException { Iterator it=c.iterator(); boolean ret=false; while(it.hasNext()) { try { ret|=add(it.next()); } catch(UnsupportedOperationException ue) { throw ue; } } return ret; } public boolean removeAll(Collection c) throws UnsupportedOperationException { Iterator it=iterator(); boolean ret=false; while(it.hasNext()) { if(c.contains(it.next())) try { it.remove(); ret=true; } catch(UnsupportedOperationException ue) { throw ue; } } return ret; } public boolean retainAll(Collection c) throws UnsupportedOperationException { Iterator it=iterator(); boolean ret=false; while(it.hasNext()) { if(!c.contains(it.next())) try { it.remove(); ret=true; } catch(UnsupportedOperationException ue) { throw ue; } } return ret; } public void clear() throws UnsupportedOperationException { Iterator it=iterator(); while(it.hasNext()) { try { it.next(); it.remove(); } catch(UnsupportedOperationException ue) { throw ue; } } } public String toString() { String ret="["; Iterator it=iterator(); if(it.hasNext()) ret+=String.valueOf(it.next()); while(it.hasNext()) { ret+=", "; ret+=String.valueOf(it.next()); } ret+="]"; return ret; } } bouncycastle-1.49.orig/jdk1.1/java/util/ArrayList.java0000644000175000017500000000462511705654527022117 0ustar ebourgebourgpackage java.util; public class ArrayList extends AbstractList implements List { Vector m_Vector=null; public ArrayList() { m_Vector=new Vector(); } public ArrayList(Collection c) { m_Vector=new Vector((int)(c.size()*1.1)); addAll(c); } public ArrayList(int initialCapacity) { m_Vector=new Vector(initialCapacity); } public void trimToSize() { m_Vector.trimToSize(); } public void ensureCapacity(int minCapacity) { m_Vector.ensureCapacity(minCapacity); } public int size() { return m_Vector.size(); } public boolean contains(Object elem) { return m_Vector.contains(elem); } public int indexOf(Object elem) { return m_Vector.indexOf(elem); } public int lastIndexOf(Object elem) { return m_Vector.lastIndexOf(elem); } public Object clone() { ArrayList al=new ArrayList(); al.m_Vector=(Vector)m_Vector.clone(); return al; } public Object[] toArray() { Object[] o=new Object[m_Vector.size()]; m_Vector.copyInto(o); return o; } public Object get(int index) { return m_Vector.elementAt(index); } public Object set(int index,Object elem) { Object o=m_Vector.elementAt(index); m_Vector.setElementAt(elem,index); return o; } public boolean add(Object o) { m_Vector.addElement(o); return true; } public void add(int index,Object elem) { m_Vector.insertElementAt(elem,index); } public Object remove(int index) { Object o=m_Vector.elementAt(index); m_Vector.removeElementAt(index); return o; } public void clear() { m_Vector.removeAllElements(); } } bouncycastle-1.49.orig/jdk1.1/java/util/AbstractMap.java0000644000175000017500000001103511705654527022377 0ustar ebourgebourgpackage java.util; /************* * Title: * Description: * Copyright: Copyright (c) 2001 * Company: * @version 1.0 */ public abstract class AbstractMap implements Map{ protected AbstractMap() { } public int size() { return entrySet().size(); } public boolean isEmpty() { return size()==0; } public boolean containsValue(Object value) { Iterator it=entrySet().iterator(); while(it.hasNext()) { Map.Entry v=(Map.Entry)it.next(); if(value==null) { if(v.getValue()==null) return true; } else { if(value.equals(v.getValue())) return true; } } return false; } public boolean containsKey(Object key) throws ClassCastException,NullPointerException { Iterator it=entrySet().iterator(); while(it.hasNext()) { Map.Entry v=(Map.Entry)it.next(); if(key==null) { if(v.getKey()==null) return true; } else { if(key.equals(v.getKey())) return true; } } return false; } public Object get(Object key)throws ClassCastException,NullPointerException { Iterator it=entrySet().iterator(); while(it.hasNext()) { Map.Entry v=(Map.Entry)it.next(); if(key==null) { if(v.getKey()==null) return v.getValue(); } else { if(key.equals(v.getKey())) return v.getValue(); } } return null; } public Object put(Object key,Object value) throws UnsupportedOperationException { throw new UnsupportedOperationException(); } public Object remove(Object key) { Iterator it=entrySet().iterator(); Object o=null; while(it.hasNext()) { Map.Entry v=(Map.Entry)it.next(); if(key==null) { if(v.getKey()==null) { o=v.getValue(); it.remove(); return o; } } else { if(key.equals(v.getKey())) { o=v.getValue(); it.remove(); return o; } } } return null; } public void putAll(Map t) { Iterator it=t.entrySet().iterator(); while(it.hasNext()) { Map.Entry v=(Map.Entry)it.next(); put(v.getKey(),v.getValue()); } } public void clear() { entrySet().clear(); } public Set keySet() { throw new UnsupportedOperationException("no keySet in AbstractMap()"); } public Collection values() { throw new UnsupportedOperationException("no values in AbstractMap()"); } public abstract Set entrySet(); public boolean equals(Object o) { throw new UnsupportedOperationException("no equals in AbstractMap()"); } public int hashCode() { throw new UnsupportedOperationException("no hashCode in AbstractMap()"); } public String toString() { throw new UnsupportedOperationException("no toString in AbstractMap()"); } } bouncycastle-1.49.orig/jdk1.1/java/util/List.java0000644000175000017500000000165011705654527021113 0ustar ebourgebourgpackage java.util; public interface List extends Collection { void add(int index, Object element)throws UnsupportedOperationException,ClassCastException,IllegalArgumentException,IndexOutOfBoundsException; boolean addAll(int index, Collection c) throws UnsupportedOperationException,ClassCastException,IllegalArgumentException,IndexOutOfBoundsException; Object get(int index) throws IndexOutOfBoundsException; int indexOf(Object o); int lastIndexOf(Object o); ListIterator listIterator(); ListIterator listIterator(int index)throws IndexOutOfBoundsException; Object remove(int index)throws UnsupportedOperationException,IndexOutOfBoundsException; Object set(int index, Object element) throws UnsupportedOperationException,ClassCastException,IllegalArgumentException,IndexOutOfBoundsException; List subList(int fromIndex, int toIndex) throws IndexOutOfBoundsException; } bouncycastle-1.49.orig/jdk1.1/java/util/Set.java0000644000175000017500000000113711705654527020733 0ustar ebourgebourg package java.util; public interface Set extends Collection { public int size(); public boolean isEmpty(); public boolean contains(Object o); public Iterator iterator(); public Object[] toArray(); public Object[] toArray(Object[] a); public boolean add(Object o); public boolean remove(Object o); public boolean containsAll(Collection c); public boolean addAll(Collection c); public boolean retainAll(Collection c); public boolean removeAll(Collection c); public void clear(); public boolean equals(Object o); public int hashCode(); } bouncycastle-1.49.orig/jdk1.1/java/util/ListIterator.java0000644000175000017500000000113611705654527022624 0ustar ebourgebourgpackage java.util; /** * Title: * Description: * Copyright: Copyright (c) 2001 * Company: * @version 1.0 */ public interface ListIterator extends Iterator { public boolean hasPrevious(); public Object previous() throws NoSuchElementException; public int nextIndex(); public int previousIndex(); public void set(Object o) throws UnsupportedOperationException, ClassCastException, IllegalArgumentException,IllegalStateException; public void add(Object o) throws UnsupportedOperationException, ClassCastException, IllegalArgumentException; } bouncycastle-1.49.orig/jdk1.1/java/util/AbstractList.java0000644000175000017500000001771211705654527022605 0ustar ebourgebourgpackage java.util; /** * Title: * Description: * Copyright: Copyright (c) 2001 * Company: * @version 1.0 */ public abstract class AbstractList extends AbstractCollection implements List { protected AbstractList al = this; protected AbstractList() { } public boolean add(Object o) throws UnsupportedOperationException, ClassCastException, IllegalArgumentException { try { add(size(),o); return true; } catch(UnsupportedOperationException ue) { throw ue; } } public abstract Object get(int index) throws IndexOutOfBoundsException; public Object set(int index,Object element) throws UnsupportedOperationException, ClassCastException, IllegalArgumentException, IndexOutOfBoundsException { throw new UnsupportedOperationException(); } public void add(int index,Object element) throws UnsupportedOperationException, ClassCastException, IllegalArgumentException, IndexOutOfBoundsException { throw new UnsupportedOperationException(); } public Object remove(int index) throws UnsupportedOperationException, IndexOutOfBoundsException { Object o = get(index); removeRange(index,index+1); return o; } public int indexOf(Object o) { ListIterator li = listIterator(); Object e; while(li.hasNext()) { int index=li.nextIndex(); e=li.next(); System.out.println(e); if(o==null) { if(e==null) return index; } else { if(o.equals(e)) return index; } } return -1; } public int lastIndexOf(Object o) { ListIterator li=listIterator(size()); while(li.hasPrevious()) { int index=li.previousIndex(); Object e=li.previous(); if(o==null) { if(e==null) return index; } else { if(o.equals(e)) return index; } } return -1; } public void clear() throws UnsupportedOperationException { try { removeRange(0,size()); } catch(UnsupportedOperationException ue) { throw ue; } } public boolean addAll(int index,Collection c) throws UnsupportedOperationException, ClassCastException, IllegalArgumentException, IndexOutOfBoundsException { Iterator it=c.iterator(); boolean ret=false; while(it.hasNext()) { try { add(index++,it.next()); ret=true; } catch(UnsupportedOperationException ue) { throw ue; } } return ret; } public Iterator iterator() { return new AbstractListIterator(this,0); } public ListIterator listIterator() { return listIterator(0); } public ListIterator listIterator(int index) throws IndexOutOfBoundsException { if(index<0||index>size()) throw new IndexOutOfBoundsException(); return new AbstractListListIterator(this,index); } public List subList(int fromIndex,int toIndex) throws IndexOutOfBoundsException,IllegalArgumentException { if(fromIndex < 0 || toIndex > size()) throw new IndexOutOfBoundsException(); if(fromIndex>toIndex) throw new IllegalArgumentException(); return (List) new Sublist(this,fromIndex,toIndex); } public boolean equals(Object o) { if(o==this) return true; if(!(o instanceof List)) return false; Iterator it1=iterator(); Iterator it2=((List)o).iterator(); while(it1.hasNext()) { if(!it2.hasNext()) return false; Object e1=it1.next(); Object e2=it2.next(); if(e1==null) { if(e2!=null) return false; } if(!e1.equals(e2)) return false; } return true; } public int hashCode() { int hashCode = 1; Iterator it = iterator(); while (it.hasNext()) { Object o = it.next(); hashCode = 31*hashCode + (o==null ? 0 : o.hashCode()); } return hashCode; } protected void removeRange(int fromIndex,int toIndex) { System.out.println("breakpoint 1"); if(fromIndex==toIndex) return; System.out.println("breakpoint 2"); ListIterator li=listIterator(fromIndex); System.out.println("breakpoint 3"); int i=fromIndex; do { li.next(); li.remove(); i++; }while(li.hasNext()&&i0; } public Object previous()// throws NoSuchElementException; { return m_al.get(--m_nextIndex); } public int nextIndex() { return m_nextIndex; } public int previousIndex() { return m_nextIndex-1; } public void set(Object o) //throws UnsupportedOperationException, ClassCastException, IllegalArgumentException,IllegalStateException; { m_al.set(m_nextIndex-1,o); } public void add(Object o)// throws UnsupportedOperationException, ClassCastException, IllegalArgumentException; { m_al.add(m_nextIndex-1,o); } } } bouncycastle-1.49.orig/jdk1.1/java/util/HashSet.java0000644000175000017500000000315611705654527021542 0ustar ebourgebourgpackage java.util; import java.io.*; ///*sk13*/import java.util.Hashtable; public class HashSet extends /*sk13*/AbstractSet /*sk13*/ /*extends Hashmap*/ { private HashMap m_HashMap=null; public HashSet() { m_HashMap=new HashMap(); } public HashSet(Collection c) { m_HashMap=new HashMap(Math.max(11,c.size()*2)); addAll(c); } public HashSet(int initialCapacity, float loadFactor) { m_HashMap=new HashMap(initialCapacity,loadFactor); } public HashSet(int initialCapacity) { m_HashMap=new HashMap(initialCapacity); } public Iterator iterator() { return (m_HashMap.keySet()).iterator(); } public int size() { return m_HashMap.size(); } public boolean contains(Object o) { return m_HashMap.containsKey(o); } public boolean add(Object o) { if (!m_HashMap.containsValue(o)) { m_HashMap.put(o, o); return true; } return false; } public boolean remove(Object o) { return (m_HashMap.remove(o)!=null); } public void clear() { m_HashMap.clear(); } public Object clone() { HashSet hs=new HashSet(); hs.m_HashMap=(HashMap)m_HashMap.clone(); return hs; } } bouncycastle-1.49.orig/jdk1.1/java/util/Collections.java0000644000175000017500000001741012147303644022447 0ustar ebourgebourgpackage java.util; import java.io.Serializable; public class Collections { public static List EMPTY_LIST = new ArrayList(); private Collections() { } public static Collection unmodifiableCollection(Collection c) { return new UnmodifiableCollection(c); } static class UnmodifiableCollection implements Collection, Serializable { Collection c; UnmodifiableCollection(Collection c) { this.c = c; } public int size() { return c.size(); } public boolean isEmpty() { return c.isEmpty(); } public boolean contains(Object o) { return c.contains(o); } public Object[] toArray() { return c.toArray(); } public Object[] toArray(Object[] a) { return c.toArray(a); } public Iterator iterator() { return new Iterator() { Iterator i = c.iterator(); public boolean hasNext() { return i.hasNext(); } public Object next() { return i.next(); } public void remove() { throw new UnsupportedOperationException(); } }; } public boolean add(Object o) { throw new UnsupportedOperationException(); } public boolean remove(Object o) { throw new UnsupportedOperationException(); } public boolean containsAll(Collection coll) { return c.containsAll(coll); } public boolean addAll(Collection coll) { throw new UnsupportedOperationException(); } public boolean removeAll(Collection coll) { throw new UnsupportedOperationException(); } public boolean retainAll(Collection coll) { throw new UnsupportedOperationException(); } public void clear() { throw new UnsupportedOperationException(); } public String toString() { return c.toString(); } } public static Set unmodifiableSet(Set s) { return new UnmodifiableSet(s); } static class UnmodifiableSet extends UnmodifiableCollection implements Set, Serializable { UnmodifiableSet(Set s) { super(s); } public boolean equals(Object o) { return c.equals(o); } public int hashCode() { return c.hashCode(); } } public static List unmodifiableList(List list) { return new UnmodifiableList(list); } static class UnmodifiableList extends UnmodifiableCollection implements List { private List list; UnmodifiableList(List list) { super(list); this.list = list; } public boolean equals(Object o) { return list.equals(o); } public int hashCode() { return list.hashCode(); } public Object get(int index) { return list.get(index); } public Object set(int index, Object element) { throw new UnsupportedOperationException(); } public void add(int index, Object element) { throw new UnsupportedOperationException(); } public Object remove(int index) { throw new UnsupportedOperationException(); } public int indexOf(Object o) { return list.indexOf(o); } public int lastIndexOf(Object o) { return list.lastIndexOf(o); } public boolean addAll(int index, Collection c) { throw new UnsupportedOperationException(); } public ListIterator listIterator() { return listIterator(0); } public ListIterator listIterator(final int index) { return new ListIterator() { ListIterator i = list.listIterator(index); public boolean hasNext() { return i.hasNext(); } public Object next() { return i.next(); } public boolean hasPrevious() { return i.hasPrevious(); } public Object previous() { return i.previous(); } public int nextIndex() { return i.nextIndex(); } public int previousIndex() { return i.previousIndex(); } public void remove() { throw new UnsupportedOperationException(); } public void set(Object o) { throw new UnsupportedOperationException(); } public void add(Object o) { throw new UnsupportedOperationException(); } }; } public List subList(int fromIndex, int toIndex) { return new UnmodifiableList(list.subList(fromIndex, toIndex)); } } public static Enumeration enumeration(final Collection c) { return new Enumeration() { Iterator i = c.iterator(); public boolean hasMoreElements() { return i.hasNext(); } public Object nextElement() { return i.next(); } }; } public static Map unmodifiableMap(Map s) { return new UnmodifiableMap(s); } static class UnmodifiableMap implements Map { private Map c; UnmodifiableMap(Map map) { this.c = map; } public int size() { return c.size(); } public boolean isEmpty() { return c.isEmpty(); } public boolean containsKey(Object o) { return c.containsKey(o); } public boolean containsValue(Object o) { return c.containsValue(o); } public Object get(Object o) { return c.get(o); } public Object put(Object o, Object o2) { throw new UnsupportedOperationException(); } public Object remove(Object o) { throw new UnsupportedOperationException(); } public void putAll(Map map) { throw new UnsupportedOperationException(); } public void clear() { throw new UnsupportedOperationException(); } public Set keySet() { return Collections.unmodifiableSet(c.keySet()); } public Collection values() { return new UnmodifiableCollection(c.values()); } public Set entrySet() { return Collections.unmodifiableSet(c.entrySet()); } public boolean equals(Object o) { return c.equals(o); } public int hashCode() { return c.hashCode(); } public String toString() { return c.toString(); } } } bouncycastle-1.49.orig/jdk1.1/java/util/Sublist.java0000644000175000017500000000541611705654527021631 0ustar ebourgebourgpackage java.util; /** * Title: * Description: * Copyright: Copyright (c) 2001 * Company: * @version 1.0 */ public class Sublist extends AbstractList { AbstractList m_al=null; int m_fromIndex=0; int m_toIndex=0; int size=0; public Sublist(AbstractList ali,int fromIndex,int toIndex) { m_al=ali; m_toIndex=toIndex; m_fromIndex=fromIndex; size = size(); } public Object set(int index,Object o) { if (index < size) { o = m_al.set(index+m_fromIndex,o); if (o != null) { size++; m_toIndex++; } return o; } else throw new IndexOutOfBoundsException(); } public Object get(int index) throws IndexOutOfBoundsException { if (index < size) return m_al.get(index+m_fromIndex); else throw new IndexOutOfBoundsException(); } public void add (int index,Object o) { if (index <= size) { m_al.add(index + m_fromIndex,o); m_toIndex++; size++; } else throw new IndexOutOfBoundsException(); } public Object remove(int index,Object o) { if (index < size) { Object ob = m_al.remove(index + m_fromIndex); if (ob !=null) { m_toIndex--; size--; } return ob; } else throw new IndexOutOfBoundsException(); } public boolean addAll(int index, Collection c) { if (index < size) { boolean bool = m_al.addAll(index + m_fromIndex,c); if (bool) { int lange = c.size(); m_toIndex = m_toIndex + lange; size = size + lange; } return bool; } else throw new IndexOutOfBoundsException(); } public boolean addAll(Collection c) { boolean bool = m_al.addAll(m_toIndex,c); if (bool) { int lange = c.size(); m_toIndex = m_toIndex + lange; size = size + lange; } return bool; } public void removeRange (int from,int to) { if ((from <= to) && (from <= size) && (to <= size)) { m_al.removeRange(from,to); int lange = to - from; m_toIndex = m_toIndex - lange; size = size - lange; } else { if (from > to) throw new IllegalArgumentException(); else throw new IndexOutOfBoundsException(); } } public int size() { return (m_toIndex - m_fromIndex); } } bouncycastle-1.49.orig/jdk1.1/java/util/Collection.java0000644000175000017500000000204411705654527022271 0ustar ebourgebourg package java.util; public interface Collection { public boolean add(Object o) throws UnsupportedOperationException,ClassCastException,IllegalArgumentException; public boolean addAll(Collection c) throws UnsupportedOperationException,ClassCastException,IllegalArgumentException; public void clear() throws UnsupportedOperationException; public boolean contains(Object o); public boolean containsAll(Collection c); public boolean equals(Object o); public int hashCode(); public boolean isEmpty(); public Iterator iterator(); public /*SK13*/boolean remove(Object o) throws UnsupportedOperationException; public boolean removeAll(Collection c) throws UnsupportedOperationException; public boolean retainAll(Collection c) throws UnsupportedOperationException; public int size(); public Object[] toArray(); public Object[] toArray(Object[] a) throws ArrayStoreException; } bouncycastle-1.49.orig/jdk1.1/java/util/AbstractSet.java0000644000175000017500000000201411705654527022412 0ustar ebourgebourgpackage java.util; /** * Title: * Description: * Copyright: Copyright (c) 2001 * Company: * @version 1.0 */ public abstract class AbstractSet extends AbstractCollection implements Set { protected AbstractSet() { } public boolean equals(Object o) { if(this==o) return true; if(o==null) return false; if(!(o instanceof Set)) return false; if(((Set)o).size()!=size()) return false; return containsAll((Collection)o); } public int hashCode() { int hashCode=0; Iterator it=iterator(); while(it.hasNext()) { Object o=it.next(); if(o!=null) hashCode+=o.hashCode(); } return hashCode; } } bouncycastle-1.49.orig/jdk1.1/java/util/HashMap.java0000644000175000017500000001421211705654527021517 0ustar ebourgebourgpackage java.util; public class HashMap extends AbstractMap{ ////////////////////////////////////////////////////////////// ///// innere Klasse Null //////////////////////////////////// ////////////////////////////////////////////////////////////// public class Null extends Object { public Null() { } public String toString() { return "Nullobject"; } } ////////////////////////////////////////////////////////////// ///// innere Klasse innerSet //////////////////////////////////// ////////////////////////////////////////////////////////////// class ISet extends AbstractSet implements java.util.Set { Vector vec = null; public ISet() { vec = new Vector(); } public boolean add(Object o) { vec.addElement(o); return true; } public int size() { return vec.size(); } public Iterator iterator() { return new IIterator(vec); } } ////////////////////////////////////////////////////////////// ///// innere Klasse Iterator //////////////////////////////////// ////////////////////////////////////////////////////////////// class IIterator implements java.util.Iterator { int index = 0; Vector vec = null; public IIterator(Vector ve) { vec = ve; } public boolean hasNext() { if (vec.size() > index) return true; return false; } public Object next() { Object o = vec.elementAt(index); if (o==Nullobject) o=null; index++; return o; } public void remove() { index--; vec.removeElementAt(index); } } ////////////////////////////////////////////////////////////// ///// innere Klasse Entry //////////////////////////////////// ////////////////////////////////////////////////////////////// class Entry implements Map.Entry { public Object key=null; public Object value=null; public Entry(Object ke,Object valu) { key = ke; value = valu; } public boolean equals(Object o) { if (value == ((Entry)o).value && key == ((Entry)o).key ) return true; else return false; } public Object getValue() { return value; } public Object getKey() { return (Object)key; } public int hashCode() { return value.hashCode() + key.hashCode(); } public Object setValue(Object valu) { value = (String)valu; return this; } } //////////////////////////////////////////////////////////////////// private Hashtable m_HashTable=null; private Null Nullobject = null; public HashMap() { Nullobject = new Null(); m_HashTable=new Hashtable(); } public HashMap(int initialCapacity) { Nullobject = new Null(); m_HashTable=new Hashtable(initialCapacity); } public HashMap(int initialCapacity, float loadFactor) { Nullobject = new Null(); m_HashTable=new Hashtable(initialCapacity, loadFactor); } public HashMap(Map t) { Nullobject = new Null(); m_HashTable=new Hashtable(); this.putAll(t); } public void clear() { m_HashTable.clear(); } public Object clone() { HashMap hm=new HashMap(); hm.m_HashTable=(Hashtable)m_HashTable.clone(); return hm; } public boolean containsKey(Object key) { if (key == null) key = Nullobject; boolean b = m_HashTable.containsKey(key); return b; } public boolean containsValue(Object value) { if (value == null ) value = Nullobject; boolean b = m_HashTable.contains(value); return b; } public Set entrySet() { Object Key = null; ISet s = new ISet(); Enumeration enum = m_HashTable.keys(); while (enum.hasMoreElements()) { Key = enum.nextElement(); s.add(new Entry(Key,m_HashTable.get(Key))); } return s; } public Object get(Object key) { if (key==null) key= Nullobject; Object o = m_HashTable.get(key); if (o == Nullobject) o=null; return o; } public boolean isEmpty() { return m_HashTable.isEmpty(); } public Set keySet() { ISet s=new ISet(); Enumeration enum = m_HashTable.keys(); while (enum.hasMoreElements()) { s.add(enum.nextElement()); } return s; } public Object put(Object key, Object value) { if (key==null) key=Nullobject; if (value==null) value = Nullobject; return m_HashTable.put(key,value); } public void putAll(Map m) { Iterator it = m.entrySet().iterator(); Object key=null; Object value=null; while (it.hasNext()) { Map.Entry me = (Map.Entry)it.next(); if (me.getKey() == null) key = Nullobject; else key= me.getKey(); if (me.getValue()==null) value = Nullobject; else value = me.getValue(); m_HashTable.put(key,value); } } public Object remove(Object key) { return m_HashTable.remove(key); } public int size() { return m_HashTable.size(); } public Collection values() { ISet s=new ISet(); Enumeration enum = m_HashTable.keys(); while (enum.hasMoreElements()) { Object Key = enum.nextElement(); //s.add(((Map.Entry)m_HashTable.get(Key)).getValue()); s.add(m_HashTable.get(Key)); } return s; } } bouncycastle-1.49.orig/jdk1.1/java/util/Iterator.java0000644000175000017500000000037111705654527021770 0ustar ebourgebourg package java.util; public interface Iterator { public abstract boolean hasNext(); public abstract Object next() throws NoSuchElementException; public abstract void remove() throws UnsupportedOperationException,IllegalStateException; } bouncycastle-1.49.orig/jdk1.1/java/util/Arrays.java0000644000175000017500000000327411705654527021445 0ustar ebourgebourgpackage java.util; public class Arrays { private Arrays() {} public static void fill(byte[] ret, byte v) { for (int i = 0; i != ret.length; i++) { ret[i] = v; } } public static boolean equals(byte[] a, byte[] a2) { if (a==a2) return true; if (a==null || a2==null) return false; int length = a.length; if (a2.length != length) return false; for (int i=0; i *
    * The ASN.1 definition is as follows:
    *
    * *
     *    PolicyQualifierInfo ::= SEQUENCE {
     *         policyQualifierId       PolicyQualifierId,
     *         qualifier               ANY DEFINED BY policyQualifierId }
     * 
    * *
    *
    * A certificate policies extension, if present in an X.509 version 3 * certificate, contains a sequence of one or more policy information terms, * each of which consists of an object identifier (OID) and optional qualifiers. * In an end-entity certificate, these policy information terms indicate the * policy under which the certificate has been issued and the purposes for which * the certificate may be used. In a CA certificate, these policy information * terms limit the set of policies for certification paths which include this * certificate.
    *
    * A Set of PolicyQualifierInfo objects are * returned by the * {@link PolicyNode#getPolicyQualifiers PolicyNode.getPolicyQualifiers} method. * This allows applications with specific policy requirements to process and * validate each policy qualifier. Applications that need to process policy * qualifiers should explicitly set the policyQualifiersRejected * flag to false (by calling the * {@link PKIXParameters#setPolicyQualifiersRejected * PKIXParameters.setPolicyQualifiersRejected} method) before validating a * certification path.
    *
    * Note that the PKIX certification path validation algorithm specifies that any * policy qualifier in a certificate policies extension that is marked critical * must be processed and validated. Otherwise the certification path must be * rejected. If the policyQualifiersRejected flag is set to * false, it is up to the application to validate all policy qualifiers in this * manner in order to be PKIX compliant.
    *
    * Concurrent Access
    *
    * All PolicyQualifierInfo objects must be immutable and * thread-safe. That is, multiple threads may concurrently invoke the methods * defined in this class on a single PolicyQualifierInfo object * (or more than one) with no ill effects. Requiring * PolicyQualifierInfo objects to be immutable and thread-safe * allows them to be passed around to various pieces of code without worrying * about coordinating access.
    *
    * Uses {@link org.bouncycastle.asn1.ASN1InputStream ASN1InputStream}, * {@link org.bouncycastle.asn1.ASN1Sequence ASN1Sequence}, * {@link org.bouncycastle.asn1.ASN1ObjectIdentifier ASN1ObjectIdentifier}, * {@link org.bouncycastle.asn1.DEROutputStream DEROutputStream}, * {@link org.bouncycastle.asn1.ASN1Object ASN1Object} */ public final class PolicyQualifierInfo { private String id; private byte[] encoded; private byte[] qualifier; /** * Creates an instance of PolicyQualifierInfo from the * encoded bytes. The encoded byte array is copied on construction.
    *
    * Uses {@link org.bouncycastle.asn1.ASN1InputStream ASN1InputStream}, * {@link org.bouncycastle.asn1.ASN1Sequence ASN1Sequence}, * {@link org.bouncycastle.asn1.ASN1ObjectIdentifier ASN1ObjectIdentifier} and * {@link org.bouncycastle.asn1.DEROutputStream DEROutputStream} * * @param encoded * a byte array containing the qualifier in DER encoding * * @exception IOException * thrown if the byte array does not represent a valid and * parsable policy qualifier */ public PolicyQualifierInfo(byte[] encoded) throws IOException { this.encoded = (byte[])encoded.clone(); try { ByteArrayInputStream inStream = new ByteArrayInputStream( this.encoded); ASN1InputStream derInStream = new ASN1InputStream(inStream); ASN1Sequence obj = (ASN1Sequence)derInStream.readObject(); id = ((ASN1ObjectIdentifier)obj.getObjectAt(0)).getId(); ByteArrayOutputStream outStream = new ByteArrayOutputStream(); DEROutputStream derOutStream = new DEROutputStream(outStream); derOutStream.writeObject(obj.getObjectAt(1)); derOutStream.close(); qualifier = outStream.toByteArray(); } catch (Exception ex) { throw new IOException("parsing exception : " + ex.toString()); } } /** * Returns the policyQualifierId field of this * PolicyQualifierInfo. The policyQualifierId * is an Object Identifier (OID) represented by a set of nonnegative * integers separated by periods. * * @return the OID (never null) */ public String getPolicyQualifierId() { return id; } /** * Returns the ASN.1 DER encoded form of this * PolicyQualifierInfo. * * @return the ASN.1 DER encoded bytes (never null). Note * that a copy is returned, so the data is cloned each time this * method is called. */ public byte[] getEncoded() { return (byte[])encoded.clone(); } /** * Returns the ASN.1 DER encoded form of the qualifier field * of this PolicyQualifierInfo. * * @return the ASN.1 DER encoded bytes of the qualifier * field. Note that a copy is returned, so the data is cloned each * time this method is called. */ public byte[] getPolicyQualifier() { if (qualifier == null) { return null; } return (byte[])qualifier.clone(); } /** * Return a printable representation of this * PolicyQualifierInfo.
    *
    * Uses {@link org.bouncycastle.asn1.ASN1InputStream ASN1InputStream}, * {@link org.bouncycastle.asn1.ASN1Object ASN1Object} * * @return a String describing the contents of this * PolicyQualifierInfo */ public String toString() { StringBuffer s = new StringBuffer(); s.append("PolicyQualifierInfo: [\n"); s.append("qualifierID: ").append(id).append('\n'); try { ByteArrayInputStream inStream = new ByteArrayInputStream(qualifier); ASN1InputStream derInStream = new ASN1InputStream(inStream); ASN1Object derObject = derInStream.readObject(); s .append(" qualifier:\n").append(ASN1Dump.dumpAsString(derObject)) .append('\n'); } catch (IOException ex) { s.append(ex.getMessage()); } s.append("qualifier: ").append(id).append('\n'); s.append(']'); return s.toString(); } } bouncycastle-1.49.orig/jdk1.1/java/security/cert/X509Extension.java0000644000175000017500000000047511705654527024375 0ustar ebourgebourg package java.security.cert; import java.util.Set; public interface X509Extension { public abstract Set getCriticalExtensionOIDs(); public abstract byte[] getExtensionValue(String oid); public abstract Set getNonCriticalExtensionOIDs(); public abstract boolean hasUnsupportedCriticalExtension(); } bouncycastle-1.49.orig/jdk1.1/java/security/cert/CertPathValidator.java0000644000175000017500000002333011705654526025405 0ustar ebourgebourgpackage java.security.cert; import java.security.InvalidAlgorithmParameterException; import java.security.NoSuchAlgorithmException; import java.security.NoSuchProviderException; import java.security.Provider; import java.security.Security; /** * A class for validating certification paths (also known as certificate * chains).
    *
    * This class uses a provider-based architecture, as described in the Java * Cryptography Architecture. To create a CertPathValidator, * call one of the static getInstance methods, passing in the * algorithm name of the CertPathValidator desired and * optionally the name of the provider desired.
    *
    * Once a CertPathValidator object has been created, it can * be used to validate certification paths by calling the {@link #validate * validate} method and passing it the CertPath to be validated * and an algorithm-specific set of parameters. If successful, the result is * returned in an object that implements the * CertPathValidatorResult interface.
    *
    * Concurrent Access
    *
    * The static methods of this class are guaranteed to be thread-safe. * Multiple threads may concurrently invoke the static methods defined in * this class with no ill effects.
    *
    * However, this is not true for the non-static methods defined by this class. * Unless otherwise documented by a specific provider, threads that need to * access a single CertPathValidator instance concurrently should * synchronize amongst themselves and provide the necessary locking. Multiple * threads each manipulating a different CertPathValidator * instance need not synchronize.
    *
    * Uses {@link CertUtil CertUtil} to actualiy load the SPI classes. * * @see CertPath * @see CertUtil **/ public class CertPathValidator extends Object { private CertPathValidatorSpi validatorSpi; private Provider provider; private String algorithm; /** * Creates a CertPathValidator object of the given algorithm, * and encapsulates the given provider implementation (SPI object) in it. * * @param validatorSpi the provider implementation * @param provider the provider * @param algorithm the algorithm name */ protected CertPathValidator( CertPathValidatorSpi validatorSpi, Provider provider, String algorithm) { this.validatorSpi = validatorSpi; this.provider = provider; this.algorithm = algorithm; } /** * Returns a CertPathValidator object that implements the * specified algorithm.
    *
    * If the default provider package provides an implementation of the * specified CertPathValidator algorithm, an instance of * CertPathValidator containing that implementation is * returned. If the requested algorithm is not available in the default * package, other packages are searched. * * @param algorithm the name of the requested CertPathValidator * algorithm * * @return a CertPathValidator object that implements the * specified algorithm * * @exception NoSuchAlgorithmException if the requested algorithm * is not available in the default provider package or any of the other * provider packages that were searched */ public static CertPathValidator getInstance(String algorithm) throws NoSuchAlgorithmException { try { CertUtil.Implementation imp = CertUtil.getImplementation("CertPathValidator", algorithm, (String)null ); if (imp != null) { return new CertPathValidator((CertPathValidatorSpi)imp.getEngine(), imp.getProvider(), algorithm); } } catch (NoSuchProviderException ex ) {} throw new NoSuchAlgorithmException("can't find algorithm " + algorithm); } /** * Returns a CertPathValidator object that implements the * specified algorithm, as supplied by the specified provider. * * @param algorithm the name of the requested CertPathValidator * algorithm * @param provider the name of the provider * * @return a CertPathValidator object that implements the * specified algorithm, as supplied by the specified provider * * @exception NoSuchAlgorithmException if the requested algorithm * is not available from the specified provider * @exception NoSuchProviderException if the provider has not been * configured * @exception IllegalArgumentException if the provider is * null */ public static CertPathValidator getInstance(String algorithm, String provider) throws NoSuchAlgorithmException, NoSuchProviderException { if ( provider == null ) throw new IllegalArgumentException("provider must be non-null"); CertUtil.Implementation imp = CertUtil.getImplementation("CertPathValidator", algorithm, provider ); if (imp != null) { return new CertPathValidator((CertPathValidatorSpi)imp.getEngine(), imp.getProvider(), algorithm); } throw new NoSuchAlgorithmException("can't find algorithm " + algorithm); } /** * Returns a CertPathValidator object that implements the * specified algorithm, as supplied by the specified provider. * Note: the provider doesn't have to be registered. * * @param algorithm the name of the requested * CertPathValidator algorithm * @param provider the provider * * @return a CertPathValidator object that implements the * specified algorithm, as supplied by the specified provider * * @exception NoSuchAlgorithmException if the requested algorithm * is not available from the specified provider * @exception IllegalArgumentException if the provider is * null */ public static CertPathValidator getInstance(String algorithm, Provider provider) throws NoSuchAlgorithmException { if ( provider == null ) throw new IllegalArgumentException("provider must be non-null"); CertUtil.Implementation imp = CertUtil.getImplementation("CertPathValidator", algorithm, provider ); if (imp != null) { return new CertPathValidator((CertPathValidatorSpi)imp.getEngine(), provider, algorithm); } throw new NoSuchAlgorithmException("can't find algorithm " + algorithm); } /** * Returns the Provider of this * CertPathValidator. * * @return the Provider of this CertPathValidator */ public final Provider getProvider() { return provider; } /** * Returns the algorithm name of this CertPathValidator. * * @return the algorithm name of this CertPathValidator */ public final String getAlgorithm() { return algorithm; } /** * Validates the specified certification path using the specified * algorithm parameter set.
    *
    * The CertPath specified must be of a type that is * supported by the validation algorithm, otherwise an * InvalidAlgorithmParameterException will be thrown. For * example, a CertPathValidator that implements the PKIX * algorithm validates CertPath objects of type X.509. * * @param certPath the CertPath to be validated * @param params the algorithm parameters * * @return the result of the validation algorithm * * @exception CertPathValidatorException if the CertPath * does not validate * @exception InvalidAlgorithmParameterException if the specified * parameters or the type of the specified CertPath are * inappropriate for this CertPathValidator */ public final CertPathValidatorResult validate( CertPath certPath, CertPathParameters params) throws CertPathValidatorException, InvalidAlgorithmParameterException { return validatorSpi.engineValidate( certPath, params ); } /** * Returns the default CertPathValidator type as specified in * the Java security properties file, or the string "PKIX" * if no such property exists. The Java security properties file is * located in the file named <JAVA_HOME>/lib/security/java.security, * where <JAVA_HOME> refers to the directory where the SDK was * installed.
    *
    * The default CertPathValidator type can be used by * applications that do not want to use a hard-coded type when calling one * of the getInstance methods, and want to provide a default * type in case a user does not specify its own.
    *
    * The default CertPathValidator type can be changed by * setting the value of the "certpathvalidator.type" security property * (in the Java security properties file) to the desired type. * * @return the default CertPathValidator type as specified * in the Java security properties file, or the string "PKIX" * if no such property exists. */ public static final String getDefaultType() { String defaulttype = null; defaulttype = Security.getProperty("certpathvalidator.type"); if ( defaulttype == null || defaulttype.length() <= 0 ) return "PKIX"; else return defaulttype; } } bouncycastle-1.49.orig/jdk1.1/java/security/cert/CRLException.java0000644000175000017500000000037011705654526024323 0ustar ebourgebourg package java.security.cert; import java.security.GeneralSecurityException; public class CRLException extends GeneralSecurityException { public CRLException() { } public CRLException(String msg) { super(msg); } } bouncycastle-1.49.orig/jdk1.1/java/security/cert/CertificateFactory.java0000644000175000017500000001364211705654526025604 0ustar ebourgebourg package java.security.cert; import java.io.InputStream; import java.security.NoSuchProviderException; import java.security.Provider; import java.util.Collection; import java.util.Iterator; import java.util.List; /** * Uses {@link CertUtil CertUtil} to actualiy load the SPI classes. * * @see CertUtil **/ public class CertificateFactory { private CertificateFactorySpi certFacSpi; private Provider provider; private String type; protected CertificateFactory( CertificateFactorySpi certFacSpi, Provider provider, String type) { this.certFacSpi = certFacSpi; this.provider = provider; this.type = type; } public final CRL generateCRL(InputStream inStream) throws CRLException { return certFacSpi.engineGenerateCRL(inStream); } public final Collection generateCRLs(InputStream inStream) throws CRLException { return certFacSpi.engineGenerateCRLs(inStream); } public final Certificate generateCertificate(InputStream inStream) throws CertificateException { return certFacSpi.engineGenerateCertificate(inStream); } public final /*Sk13 Vector*/ Collection generateCertificates(InputStream inStream) throws CertificateException { return certFacSpi.engineGenerateCertificates(inStream); } /** * Returns an iteration of the CertPath encodings supported * by this certificate factory, with the default encoding first. See * Appendix A in the * Java Certification Path API Programmer's Guide for information about * standard encoding names and their formats.
    *
    * Attempts to modify the returned Iterator via its * remove method result in an * UnsupportedOperationException. * * @return an Iterator over the names of the supported * CertPath encodings (as Strings) */ public final Iterator getCertPathEncodings() { return certFacSpi.engineGetCertPathEncodings(); } /** * Generates a CertPath object and initializes it with * the data read from the InputStream inStream. The data * is assumed to be in the default encoding. The name of the default * encoding is the first element of the Iterator returned by * the {@link #getCertPathEncodings getCertPathEncodings} method. * * @param inStream an InputStream containing the data * * @return a CertPath initialized with the data from the * InputStream * * @exception CertificateException if an exception occurs while decoding */ public final CertPath generateCertPath(InputStream inStream) throws CertificateException { return certFacSpi.engineGenerateCertPath(inStream); } /** * Generates a CertPath object and initializes it with * the data read from the InputStream inStream. The data * is assumed to be in the specified encoding. See Appendix A in the *
    * Java Certification Path API Programmer's Guide * for information about standard encoding names and their formats. * * @param inStream an InputStream containing the data * @param encoding the encoding used for the data * * @return a CertPath initialized with the data from the * InputStream * * @exception CertificateException if an exception occurs while decoding or * the encoding requested is not supported */ public final CertPath generateCertPath(InputStream inStream, String encoding) throws CertificateException { return certFacSpi.engineGenerateCertPath(inStream, encoding); } /** * Generates a CertPath object and initializes it with * a List of Certificates.
    *
    * The certificates supplied must be of a type supported by the * CertificateFactory. They will be copied out of the supplied * List object. * * @param certificates a List of Certificates * * @return a CertPath initialized with the supplied list of * certificates * * @exception CertificateException if an exception occurs */ public final CertPath generateCertPath(List certificates) throws CertificateException { return certFacSpi.engineGenerateCertPath( certificates ); } public static final CertificateFactory getInstance(String type) throws CertificateException { try { CertUtil.Implementation imp = CertUtil.getImplementation("CertificateFactory", type, (String)null); if (imp != null) { return new CertificateFactory((CertificateFactorySpi)imp.getEngine(), imp.getProvider(), type); } throw new CertificateException("can't find type " + type); } catch (NoSuchProviderException e) { throw new CertificateException(type + " not found"); } } public static final CertificateFactory getInstance( String type, String provider) throws CertificateException, NoSuchProviderException { CertUtil.Implementation imp = CertUtil.getImplementation("CertificateFactory", type, provider); if (imp != null) { return new CertificateFactory((CertificateFactorySpi)imp.getEngine(), imp.getProvider(), type); } throw new CertificateException("can't find type " + type); } public final Provider getProvider() { return provider; } public final String getType() { return type; } } bouncycastle-1.49.orig/jdk1.1/java/security/cert/CertStore.java0000644000175000017500000003535411705654526023750 0ustar ebourgebourgpackage java.security.cert; import java.security.InvalidAlgorithmParameterException; import java.security.NoSuchAlgorithmException; import java.security.NoSuchProviderException; import java.security.Provider; import java.security.Security; import java.util.Collection; /** * A class for retrieving Certificates and CRLs * from a repository.
    *
    * This class uses a provider-based architecture, as described in the * Java Cryptography Architecture. * To create a CertStore, call one of the static * getInstance methods, passing in the type of * CertStore desired, any applicable initialization parameters * and optionally the name of the provider desired.
    *
    * Once the CertStore has been created, it can be used to * retrieve Certificates and CRLs by calling its * {@link #getCertificates(CertSelector selector) getCertificates} and * {@link #getCRLs(CRLSelector selector) getCRLs} methods.
    *
    * Unlike a {@link java.security.KeyStore KeyStore}, which provides access * to a cache of private keys and trusted certificates, a * CertStore is designed to provide access to a potentially * vast repository of untrusted certificates and CRLs. For example, an LDAP * implementation of CertStore provides access to certificates * and CRLs stored in one or more directories using the LDAP protocol and the * schema as defined in the RFC service attribute. See Appendix A in the * Java Certification Path API Programmer's Guide for more information about * standard CertStore types.
    *
    * Concurrent Access
    *
    * All public methods of CertStore objects must be thread-safe. * That is, multiple threads may concurrently invoke these methods on a * single CertStore object (or more than one) with no * ill effects. This allows a CertPathBuilder to search for a * CRL while simultaneously searching for further certificates, for instance.
    *
    * The static methods of this class are also guaranteed to be thread-safe. * Multiple threads may concurrently invoke the static methods defined in * this class with no ill effects.
    *
    * Uses {@link CertUtil CertUtil} to actualiy load the SPI classes. * * @see CertUtil **/ public class CertStore extends Object { private CertStoreSpi storeSpi; private Provider provider; private String type; private CertStoreParameters params; /** * Creates a CertStore object of the given type, and * encapsulates the given provider implementation (SPI object) in it. * * @param storeSpi the provider implementation * @param provider the provider * @param type the type * @param params the initialization parameters (may be null) */ protected CertStore( CertStoreSpi storeSpi, Provider provider, String type, CertStoreParameters params ) { this.storeSpi = storeSpi; this.provider = provider; this.type = type; this.params = params; } /** * Returns a Collection of Certificates that * match the specified selector. If no Certificates * match the selector, an empty Collection will be returned.
    *
    * For some CertStore types, the resulting * Collection may not contain all of the * Certificates that match the selector. For instance, * an LDAP CertStore may not search all entries in the * directory. Instead, it may just search entries that are likely to * contain the Certificates it is looking for.
    *
    * Some CertStore implementations (especially LDAP * CertStores) may throw a CertStoreException * unless a non-null CertSelector is provided that * includes specific criteria that can be used to find the certificates. * Issuer and/or subject names are especially useful criteria. * * @param selector A CertSelector used to select which * Certificates should be returned. Specify null * to return all Certificates (if supported). * * @return A Collection of Certificates that * match the specified selector (never null) * @exception CertStoreException if an exception occurs */ public final Collection getCertificates( CertSelector selector ) throws CertStoreException { return storeSpi.engineGetCertificates( selector ); } /** * Returns a Collection of CRLs that * match the specified selector. If no CRLs * match the selector, an empty Collection will be returned.
    *
    * For some CertStore types, the resulting * Collection may not contain all of the * CRLs that match the selector. For instance, * an LDAP CertStore may not search all entries in the * directory. Instead, it may just search entries that are likely to * contain the CRLs it is looking for.
    *
    * Some CertStore implementations (especially LDAP * CertStores) may throw a CertStoreException * unless a non-null CRLSelector is provided that * includes specific criteria that can be used to find the CRLs. * Issuer names and/or the certificate to be checked are especially useful. * * @param selector A CRLSelector used to select which * CRLs should be returned. Specify null * to return all CRLs (if supported). * * @return A Collection of CRLs that * match the specified selector (never null) * * @exception CertStoreException if an exception occurs */ public final Collection getCRLs( CRLSelector selector ) throws CertStoreException { return storeSpi.engineGetCRLs( selector ); } /** * Returns a CertStore object that implements the specified * CertStore type and is initialized with the specified * parameters.
    *
    * If the default provider package provides an implementation * of the specified CertStore type, an instance of * CertStore containing that implementation is returned. * If the requested type is not available in the default package, other * packages are searched.
    *
    * The CertStore that is returned is initialized with the * specified CertStoreParameters. The type of parameters * needed may vary between different types of CertStores. * Note that the specified CertStoreParameters object is * cloned. * * @param type the name of the requested CertStore type * @param params the initialization parameters (may be null) * * @return a CertStore object that implements the specified * CertStore type * * @exception NoSuchAlgorithmException if the requested type is not * available in the default provider package or any of the other provider * packages that were searched * @exception InvalidAlgorithmParameterException if the specified * initialization parameters are inappropriate for this * CertStore */ public static CertStore getInstance( String type, CertStoreParameters params) throws InvalidAlgorithmParameterException, NoSuchAlgorithmException { try { CertUtil.Implementation imp = CertUtil.getImplementation( "CertStore", type, (String)null, new Class[] { CertStoreParameters.class }, new Object[] { params } ); if (imp != null) { return new CertStore((CertStoreSpi)imp.getEngine(), imp.getProvider(), type, params ); } } catch ( NoSuchProviderException ex ) {} throw new NoSuchAlgorithmException("can't find type " + type); } /** * Returns a CertStore object that implements the specified * CertStore type, as supplied by the specified provider * and initialized with the specified parameters.
    *
    * The CertStore that is returned is initialized with the * specified CertStoreParameters. The type of parameters * needed may vary between different types of CertStores. * Note that the specified CertStoreParameters object is * cloned. * * @param type the requested CertStore type * @param params the initialization parameters (may be null) * @param provider the name of the provider * * @return a CertStore object that implements the * specified type, as supplied by the specified provider * * @exception NoSuchAlgorithmException if the requested type is not * available from the specified provider * @exception InvalidAlgorithmParameterException if the specified * initialization parameters are inappropriate for this * CertStore * @exception NoSuchProviderException if the provider has not been configured * @exception IllegalArgumentException if the provider is * null */ public static CertStore getInstance( String type, CertStoreParameters params, String provider) throws InvalidAlgorithmParameterException, NoSuchAlgorithmException, NoSuchProviderException, IllegalArgumentException { if ( provider == null ) throw new IllegalArgumentException( "provider must be non-null" ); CertUtil.Implementation imp = CertUtil.getImplementation( "CertStore", type, provider, new Class[] { CertStoreParameters.class }, new Object[] { params } ); if (imp != null) { return new CertStore((CertStoreSpi)imp.getEngine(), imp.getProvider(), type, params ); } throw new NoSuchAlgorithmException("can't find type " + type); } /** * Returns a CertStore object that implements the specified * CertStore type, as supplied by the specified provider and * initialized with the specified parameters. * Note: the provider doesn't have to be registered.
    *
    * The CertStore that is returned is initialized with the * specified CertStoreParameters. The type of parameters * needed may vary between different types of CertStores. * Note that the specified CertStoreParameters object is * cloned. * * @param type the requested CertStore type * @param params the initialization parameters (may be null) * @param provider the provider * * @return a CertStore object that implements the * specified type, as supplied by the specified provider * * @exception NoSuchAlgorithmException if the requested type is not * available from the specified provider * @exception InvalidAlgorithmParameterException if the specified * initialization parameters are inappropriate for this * CertStore * @exception IllegalArgumentException if the provider is * null */ public static CertStore getInstance( String type, CertStoreParameters params, Provider provider ) throws NoSuchAlgorithmException, InvalidAlgorithmParameterException, IllegalArgumentException { if ( provider == null ) throw new IllegalArgumentException( "provider must be non-null" ); CertUtil.Implementation imp = CertUtil.getImplementation( "CertStore", type, provider, new Class[] { CertStoreParameters.class }, new Object[] { params } ); if (imp != null) { return new CertStore((CertStoreSpi)imp.getEngine(), provider, type, params ); } throw new NoSuchAlgorithmException("can't find type " + type); } /** * Returns the parameters used to initialize this CertStore. * Note that the CertStoreParameters object is cloned before * it is returned. * * @return the parameters used to initialize this CertStore * (may be null) */ public final CertStoreParameters getCertStoreParameters() { return params; } /** * Returns the type of this CertStore. * * @return the type of this CertStore */ public final String getType() { return type; } /** * Returns the provider of this CertStore. * * @return the provider of this CertStore */ public final Provider getProvider() { return provider; } /** * Returns the default CertStore type as specified in the * Java security properties file, or the string "LDAP" if no * such property exists. The Java security properties file is located in * the file named <JAVA_HOME>/lib/security/java.security, where * <JAVA_HOME> refers to the directory where the SDK was installed.
    *
    * The default CertStore type can be used by applications * that do not want to use a hard-coded type when calling one of the * getInstance methods, and want to provide a default * CertStore type in case a user does not specify its own.
    *
    * The default CertStore type can be changed by setting * the value of the "certstore.type" security property (in the Java * security properties file) to the desired type. * * @return the default CertStore type as specified in the * Java security properties file, or the string "LDAP" * if no such property exists. */ public static final String getDefaultType() { String defaulttype = null; defaulttype = Security.getProperty("certstore.type"); if ( defaulttype == null || defaulttype.length() <= 0 ) return "LDAP"; else return defaulttype; } } bouncycastle-1.49.orig/jdk1.1/java/security/cert/CertPathBuilderSpi.java0000644000175000017500000000354611705654526025531 0ustar ebourgebourgpackage java.security.cert; import java.security.InvalidAlgorithmParameterException; /** * The Service Provider Interface (SPI) for the CertPathBuilder * class. All CertPathBuilder implementations must include a class * (the SPI class) that extends this class (CertPathBuilderSpi) and * implements all of its methods. In general, instances of this class * should only be accessed through the CertPathBuilder class. For * details, see the Java Cryptography Architecture.
    *
    * Concurrent Access
    *
    * Instances of this class need not be protected against concurrent * access from multiple threads. Threads that need to access a single * CertPathBuilderSpi instance concurrently should synchronize amongst * themselves and provide the necessary locking before calling the * wrapping CertPathBuilder object.
    *
    * However, implementations of CertPathBuilderSpi may still encounter * concurrency issues, since multiple threads each manipulating a * different CertPathBuilderSpi instance need not synchronize. **/ public abstract class CertPathBuilderSpi extends Object { /** * The default constructor. */ public CertPathBuilderSpi() {} /** * Attempts to build a certification path using the specified * algorithm parameter set. * * @param params the algorithm parameters * * @return the result of the build algorithm * * @exception CertPathBuilderException if the builder is unable * to construct a certification path that satisfies the * specified * @exception parametersInvalidAlgorithmParameterException if the * specified parameters are inappropriate for this CertPathBuilder */ public abstract CertPathBuilderResult engineBuild( CertPathParameters params ) throws CertPathBuilderException, InvalidAlgorithmParameterException; } bouncycastle-1.49.orig/jdk1.1/java/security/cert/CertificateParsingException.java0000644000175000017500000000036111705654526027451 0ustar ebourgebourg package java.security.cert; public class CertificateParsingException extends CertificateException { public CertificateParsingException() { } public CertificateParsingException(String msg) { super(msg); } } bouncycastle-1.49.orig/jdk1.1/java/security/cert/PKIXBuilderParameters.java0000644000175000017500000001700311705654526026133 0ustar ebourgebourgpackage java.security.cert; import java.security.InvalidAlgorithmParameterException; import java.security.InvalidParameterException; import java.security.KeyStore; import java.security.KeyStoreException; import java.util.Set; /** * Parameters used as input for the PKIX CertPathBuilder * algorithm.
    *
    * A PKIX CertPathBuilder uses these parameters to {@link * CertPathBuilder#build build} a CertPath which has been * validated according to the PKIX certification path validation algorithm.
    *
    * To instantiate a PKIXBuilderParameters object, an * application must specify one or more most-trusted CAs as defined by * the PKIX certification path validation algorithm. The most-trusted CA * can be specified using one of two constructors. An application * can call {@link #PKIXBuilderParameters(Set, CertSelector) * PKIXBuilderParameters(Set, CertSelector)}, specifying a * Set of TrustAnchor objects, each of which * identifies a most-trusted CA. Alternatively, an application can call * {@link #PKIXBuilderParameters(KeyStore, CertSelector) * PKIXBuilderParameters(KeyStore, CertSelector)}, specifying a * KeyStore instance containing trusted certificate entries, each * of which will be considered as a most-trusted CA.
    *
    * In addition, an application must specify constraints on the target * certificate that the CertPathBuilder will attempt * to build a path to. The constraints are specified as a * CertSelector object. These constraints should provide the * CertPathBuilder with enough search criteria to find the target * certificate. Minimal criteria for an X509Certificate usually * include the subject name and/or one or more subject alternative names. * If enough criteria is not specified, the CertPathBuilder * may throw a CertPathBuilderException.
    *
    * Concurrent Access
    *
    * Unless otherwise specified, the methods defined in this class are not * thread-safe. Multiple threads that need to access a single * object concurrently should synchronize amongst themselves and * provide the necessary locking. Multiple threads each manipulating * separate objects need not synchronize. * * @see CertPathBuilder **/ public class PKIXBuilderParameters extends PKIXParameters { private int maxPathLength = 5; /** * Creates an instance of PKIXBuilderParameters with * the specified Set of most-trusted CAs. * Each element of the set is a {@link TrustAnchor TrustAnchor}.
    *
    * Note that the Set is copied to protect against * subsequent modifications. * * @param trustAnchors a Set of TrustAnchors * @param targetConstraints a CertSelector specifying the * constraints on the target certificate * * @exception InvalidAlgorithmParameterException if trustAnchors * is empty (trustAnchors.isEmpty() == true) * @exception NullPointerException if trustAnchors is * null * @exception ClassCastException if any of the elements of * trustAnchors are not of type * java.security.cert.TrustAnchor */ public PKIXBuilderParameters( Set trustAnchors, CertSelector targetConstraints) throws InvalidAlgorithmParameterException { super( trustAnchors ); setTargetCertConstraints( targetConstraints ); } /** * Creates an instance of PKIXBuilderParameters that * populates the set of most-trusted CAs from the trusted * certificate entries contained in the specified KeyStore. * Only keystore entries that contain trusted X509Certificates * are considered; all other certificate types are ignored. * * @param keystore a KeyStore from which the set of * most-trusted CAs will be populated * @param targetConstraints a CertSelector specifying the * constraints on the target certificate * * @exception KeyStoreException if keystore has not been * initialized * @exception InvalidAlgorithmParameterException if keystore does * not contain at least one trusted certificate entry * @exception NullPointerException if keystore is * null */ public PKIXBuilderParameters(KeyStore keystore, CertSelector targetConstraints) throws KeyStoreException, InvalidAlgorithmParameterException { super( keystore ); setTargetCertConstraints( targetConstraints ); } /** * Sets the value of the maximum number of non-self-issued intermediate * certificates that may exist in a certification path. A certificate * is self-issued if the DNs that appear in the subject and issuer * fields are identical and are not empty. Note that the last certificate * in a certification path is not an intermediate certificate, and is not * included in this limit. Usually the last certificate is an end entity * certificate, but it can be a CA certificate. A PKIX * CertPathBuilder instance must not build * paths longer than the length specified.
    *
    * A value of 0 implies that the path can only contain * a single certificate. A value of -1 implies that the * path length is unconstrained (i.e. there is no maximum). * The default maximum path length, if not specified, is 5. * Setting a value less than -1 will cause an exception to be thrown.
    *
    * If any of the CA certificates contain the * BasicConstraintsExtension, the value of the * pathLenConstraint field of the extension overrides * the maximum path length parameter whenever the result is a * certification path of smaller length. * * @param maxPathLength the maximum number of non-self-issued intermediate * certificates that may exist in a certification path * * @exception InvalidParameterException if maxPathLength is set * to a value less than -1 * * @see #getMaxPathLength */ public void setMaxPathLength(int maxPathLength) { if ( maxPathLength < -1 ) throw new InvalidParameterException("the maximum path length parameter can not be less than -1"); this.maxPathLength = maxPathLength; } /** * Returns the value of the maximum number of intermediate non-self-issued * certificates that may exist in a certification path. See * the {@link #setMaxPathLength} method for more details. * * @return the maximum number of non-self-issued intermediate certificates * that may exist in a certification path, or -1 if there is no limit * * @see #setMaxPathLength */ public int getMaxPathLength() { return maxPathLength; } /** * Returns a formatted string describing the parameters. * * @return a formatted string describing the parameters */ public String toString() { StringBuffer s = new StringBuffer(); s.append( "PKIXBuilderParameters [\n" ); s.append( super.toString() ); s.append( " Maximum Path Length: " ); s.append( getMaxPathLength() ); s.append( "\n]\n" ); return s.toString(); } } bouncycastle-1.49.orig/jdk1.1/java/security/cert/CertPath.java0000644000175000017500000002417211705654526023544 0ustar ebourgebourgpackage java.security.cert; import java.io.ByteArrayInputStream; import java.io.NotSerializableException; import java.io.ObjectStreamException; import java.io.Serializable; import java.util.Iterator; import java.util.List; import java.util.ListIterator; /** * An immutable sequence of certificates (a certification path).
    *
    * This is an abstract class that defines the methods common to all * CertPaths. Subclasses can handle different kinds of certificates * (X.509, PGP, etc.).
    *
    * All CertPath objects have a type, a list of Certificates, and one * or more supported encodings. Because the CertPath class is * immutable, a CertPath cannot change in any externally visible way * after being constructed. This stipulation applies to all public * fields and methods of this class and any added or overridden by * subclasses.
    *
    * The type is a String that identifies the type of Certificates in * the certification path. For each certificate cert in a * certification path certPath, * cert.getType().equals(certPath.getType()) must be true.
    *
    * The list of Certificates is an ordered List of zero or more * Certificates. This List and all of the Certificates contained in it * must be immutable.
    *
    * Each CertPath object must support one or more encodings so that the * object can be translated into a byte array for storage or * transmission to other parties. Preferably, these encodings should * be well-documented standards (such as PKCS#7). One of the encodings * supported by a CertPath is considered the default encoding. This * encoding is used if no encoding is explicitly requested (for the * {@link #getEncoded()} method, for instance).
    *
    * All CertPath objects are also Serializable. CertPath objects are * resolved into an alternate {@link CertPathRep} object during * serialization. This allows a CertPath object to be serialized into * an equivalent representation regardless of its underlying * implementation.
    *
    * CertPath objects can be created with a CertificateFactory or they * can be returned by other classes, such as a CertPathBuilder.
    *
    * By convention, X.509 CertPaths (consisting of X509Certificates), * are ordered starting with the target certificate and ending with a * certificate issued by the trust anchor. That is, the issuer of one * certificate is the subject of the following one. The certificate * representing the {@link TrustAnchor TrustAnchor} should not be included in the * certification path. Unvalidated X.509 CertPaths may not follow * these conventions. PKIX CertPathValidators will detect any * departure from these conventions that cause the certification path * to be invalid and throw a CertPathValidatorException.
    *
    * Concurrent Access
    *
    * All CertPath objects must be thread-safe. That is, multiple threads * may concurrently invoke the methods defined in this class on a * single CertPath object (or more than one) with no ill effects. This * is also true for the List returned by CertPath.getCertificates.
    *
    * Requiring CertPath objects to be immutable and thread-safe allows * them to be passed around to various pieces of code without worrying * about coordinating access. Providing this thread-safety is * generally not difficult, since the CertPath and List objects in * question are immutable. * * @see CertificateFactory * @see CertPathBuilder */ public abstract class CertPath extends Object implements Serializable { private String type; /** * Alternate CertPath class for serialization. **/ protected static class CertPathRep implements Serializable { private String type; private byte[] data; /** * Creates a CertPathRep with the specified * type and encoded form of a certification path. * * @param type the standard name of a CertPath * @param typedata the encoded form of the certification * path **/ protected CertPathRep(String type, byte[] data) { this.type = type; this.data = data; } /** * Returns a CertPath constructed from the type and data. * * @return the resolved CertPath object * @exception ObjectStreamException if a CertPath could not be constructed **/ protected Object readResolve() throws ObjectStreamException { try { ByteArrayInputStream inStream = new ByteArrayInputStream(data); CertificateFactory cf = CertificateFactory.getInstance(type); return cf.generateCertPath(inStream); } catch ( CertificateException ce ) { throw new NotSerializableException(" java.security.cert.CertPath: " + type); } } } /** * Creates a CertPath of the specified type. * This constructor is protected because most users should use * a CertificateFactory to create CertPaths. * @param type the standard name of the type of Certificatesin this path **/ protected CertPath(String type) { this.type = type; } /** * Returns the type of Certificates in this certification * path. This is the same string that would be returned by * {@link Certificate#getType() cert.getType()} for all * Certificates in the certification path. * * @return the type of Certificates in this certification path (never null) **/ public String getType() { return type; } /** * Returns an iteration of the encodings supported by this * certification path, with the default encoding * first. Attempts to modify the returned Iterator via its * remove method result in an UnsupportedOperationException. * * @return an Iterator over the names of the supported encodings (as Strings) **/ public abstract Iterator getEncodings(); /** * Compares this certification path for equality with the * specified object. Two CertPaths are equal if and only if * their types are equal and their certificate Lists (and by * implication the Certificates in those Lists) are equal. A * CertPath is never equal to an object that is not a * CertPath.
    *
    * This algorithm is implemented by this method. If it is * overridden, the behavior specified here must be maintained. * * @param other the object to test for equality with this * certification path * * @return true if the specified object is equal to this * certification path, false otherwise * * @see Object#hashCode() Object.hashCode() **/ public boolean equals(Object other) { if (!( other instanceof CertPath ) ) return false; CertPath otherCertPath = (CertPath)other; if ( ! getType().equals(otherCertPath.getType()) ) return false; return getCertificates().equals(otherCertPath.getCertificates()); } /** * Returns the hashcode for this certification path. The hash * code of a certification path is defined to be the result of * the following calculation: *
         *   hashCode = path.getType().hashCode();
         *   hashCode = 31 * hashCode + path.getCertificates().hashCode();
         * 
    * This ensures that path1.equals(path2) implies that * path1.hashCode()==path2.hashCode() for any two * certification paths, path1 and path2, as required by the * general contract of Object.hashCode. * * @return The hashcode value for this certification path * * @see #equals(Object) **/ public int hashCode() { return getType().hashCode() * 31 + getCertificates().hashCode(); } /** * Returns a string representation of this certification * path. This calls the toString method on each of the * Certificates in the path. * * @return a string representation of this certification path **/ public String toString() { StringBuffer s = new StringBuffer(); List certs = getCertificates(); ListIterator iter = certs.listIterator(); s.append('\n').append(getType()).append(" Cert Path: length = ").append(certs.size()).append("\n[\n"); while ( iter.hasNext() ) { s.append("=========================================================Certificate ").append(iter.nextIndex()).append('\n'); s.append(iter.next()).append('\n'); s.append("========================================================Certificate end\n\n\n"); } s.append("\n]"); return s.toString(); } /** * Returns the encoded form of this certification path, using * the default encoding. * * @return the encoded bytes * * @exception CertificateEncodingException if an encoding error occurs **/ public abstract byte[] getEncoded() throws CertificateEncodingException; /** * Returns the encoded form of this certification path, using * the specified encoding. * * @param encoding the name of the encoding to use * * @return the encoded bytes * * @exception CertificateEncodingException if an encoding error * occurs or the encoding requested is not supported **/ public abstract byte[] getEncoded(String encoding) throws CertificateEncodingException; /** * Returns the list of certificates in this certification * path. The List returned must be immutable and thread-safe. * * @return an immutable List of Certificates (may be empty, but not null) **/ public abstract List getCertificates(); /** * Replaces the CertPath to be serialized with a CertPathRep * object. * * @return the CertPathRep to be serialized * * @exception ObjectStreamException if a CertPathRep object * representing this certification path could not be created **/ protected Object writeReplace() throws ObjectStreamException { try { return new CertPathRep( getType(), getEncoded() ); } catch ( CertificateException ce ) { throw new NotSerializableException( " java.security.cert.CertPath: " + getType() ); } } } bouncycastle-1.49.orig/jdk1.1/java/security/cert/LDAPCertStoreParameters.java0000644000175000017500000000722111705654526026425 0ustar ebourgebourgpackage java.security.cert; /** * Parameters used as input for the LDAP CertStore algorithm.
    *
    * This class is used to provide necessary configuration parameters (server * name and port number) to implementations of the LDAP CertStore * algorithm.
    *
    * Concurrent Access
    *
    * Unless otherwise specified, the methods defined in this class are not * thread-safe. Multiple threads that need to access a single * object concurrently should synchronize amongst themselves and * provide the necessary locking. Multiple threads each manipulating * separate objects need not synchronize. * * @see CertStore **/ public class LDAPCertStoreParameters implements CertStoreParameters { private static final int LDAP_DEFAULT_PORT = 389; /** * the port number of the LDAP server */ private String serverName; /** * the DNS name of the LDAP server */ private int port; /** * Creates an instance of LDAPCertStoreParameters with the * default parameter values (server name "localhost", port 389). */ public LDAPCertStoreParameters() { this("localhost", LDAP_DEFAULT_PORT); } /** * Creates an instance of LDAPCertStoreParameters with the * specified server name and a default port of 389. * * @param serverName the DNS name of the LDAP server * * @exception NullPointerException if serverName is * null */ public LDAPCertStoreParameters(String serverName) { this(serverName, LDAP_DEFAULT_PORT); } /** * Creates an instance of LDAPCertStoreParameters with the * specified parameter values. * * @param serverName the DNS name of the LDAP server * @param port the port number of the LDAP server * * @exception NullPointerException if serverName is * null */ public LDAPCertStoreParameters(String serverName, int port) { if (serverName == null) throw new NullPointerException("serverName must be non-null"); this.serverName = serverName; this.port = port; } /** * Returns the DNS name of the LDAP server. * * @return the name (not null) */ public String getServerName() { return serverName; } /** * Returns the port number of the LDAP server. * * @return the port number */ public int getPort() { return port; } /** * Returns a copy of this object. Changes to the copy will not affect * the original and vice versa.
    *
    * Note: this method currently performs a shallow copy of the object * (simply calls Object.clone()). This may be changed in a * future revision to perform a deep copy if new parameters are added * that should not be shared. * * @return the copy */ public Object clone() { try { return super.clone(); } catch (CloneNotSupportedException e) { /* Cannot happen */ throw new InternalError(e.toString()); } } /** * Returns a formatted string describing the parameters. * * @return a formatted string describing the parameters */ public String toString() { StringBuffer sb = new StringBuffer(); sb.append("LDAPCertStoreParameters: [\n"); sb.append(" serverName: ").append(serverName).append('\n'); sb.append(" port: ").append(port).append('\n'); sb.append(']'); return sb.toString(); } } bouncycastle-1.49.orig/jdk1.1/java/security/cert/CertPathValidatorException.java0000644000175000017500000001751211705654526027271 0ustar ebourgebourgpackage java.security.cert; import java.io.PrintStream; import java.io.PrintWriter; import java.security.GeneralSecurityException; /** * An exception indicating one of a variety of problems encountered when * validating a certification path.
    *
    * A CertPathValidatorException provides support for wrapping * exceptions. The {@link #getCause getCause} method returns the throwable, * if any, that caused this exception to be thrown.
    *
    * A CertPathValidatorException may also include the * certification path that was being validated when the exception was thrown * and the index of the certificate in the certification path that caused the * exception to be thrown. Use the {@link #getCertPath getCertPath} and * {@link #getIndex getIndex} methods to retrieve this information.
    *
    * Concurrent Access
    *
    * Unless otherwise specified, the methods defined in this class are not * thread-safe. Multiple threads that need to access a single * object concurrently should synchronize amongst themselves and * provide the necessary locking. Multiple threads each manipulating * separate objects need not synchronize. * * @see CertPathValidator **/ public class CertPathValidatorException extends GeneralSecurityException { private Throwable cause; private CertPath certPath; private int index = -1; /** * Creates a CertPathValidatorException with * no detail message. */ public CertPathValidatorException() { super(); } /** * Creates a CertPathValidatorException with the given * detail message. A detail message is a String that * describes this particular exception. * * @param messag the detail message */ public CertPathValidatorException(String message) { super(message); } /** * Creates a CertPathValidatorException with the specified * detail message and cause. * * @param msg the detail message * @param cause the cause (which is saved for later retrieval by the * {@link #getCause getCause()} method). (A null value is * permitted, and indicates that the cause is nonexistent or unknown.) */ public CertPathValidatorException(String message, Throwable cause) { super(message); this.cause = cause; } /** * Creates a CertPathValidatorException with the specified * detail message, cause, certification path, and index. * * @param msg the detail message (or null if none) * @param cause the cause (or null if none) * @param certPath the certification path that was in the process of * being validated when the error was encountered * @param index the index of the certificate in the certification path * that caused the error (or -1 if not applicable). Note that * the list of certificates in a CertPath is zero based. * * @exception IndexOutOfBoundsException if the index is out of range * (index < -1 || (certPath != null && index >= * certPath.getCertificates().size()) * @exception IllegalArgumentException if certPath is * null and index is not -1 */ public CertPathValidatorException(String message, Throwable cause, CertPath certPath, int index) { super( message ); if ( certPath == null && index != -1 ) throw new IllegalArgumentException( "certPath = null and index != -1" ); if ( index < -1 || ( certPath != null && index >= certPath.getCertificates().size() ) ) throw new IndexOutOfBoundsException( " index < -1 or out of bound of certPath.getCertificates()" ); this.cause = cause; this.certPath = certPath; this.index = index; } /** * Creates a CertPathValidatorException that wraps the * specified throwable. This allows any exception to be converted into a * CertPathValidatorException, while retaining information * about the wrapped exception, which may be useful for debugging. The * detail message is set to (cause==null ? null : cause.toString() * ) (which typically contains the class and detail message of * cause). * * @param cause the cause (which is saved for later retrieval by the * {@link #getCause getCause()} method). (A null value is * permitted, and indicates that the cause is nonexistent or unknown.) */ public CertPathValidatorException(Throwable cause) { this.cause = cause; } /** * Returns the detail message for this * CertPathValidatorException. * * @return the detail message, or null if neither the message * nor cause were specified */ public String getMessage() { String message = super.getMessage(); if ( message == null && cause == null ) return null; StringBuffer s = new StringBuffer(); if ( message != null ) { s.append(message).append('\n'); } if ( cause != null ) { s.append("Cause:\n").append(cause.getMessage()).append('\n'); } return s.toString(); } /** * Returns the certification path that was being validated when * the exception was thrown. * * @return the CertPath that was being validated when * the exception was thrown (or null if not specified) */ public CertPath getCertPath() { return certPath; } /** * Returns the index of the certificate in the certification path * that caused the exception to be thrown. Note that the list of * certificates in a CertPath is zero based. If no * index has been set, -1 is returned. * * @return the index that has been set, or -1 if none has been set */ public int getIndex() { return index; } /** * Returns the cause of this CertPathValidatorException or * null if the cause is nonexistent or unknown. * * @return the cause of this throwable or null if the cause * is nonexistent or unknown. */ public Throwable getCause() { return cause; } /** * Returns a string describing this exception, including a description * of the internal (wrapped) cause if there is one. * * @return a string representation of this * CertPathValidatorException */ public String toString() { StringBuffer sb = new StringBuffer(); String s = getMessage(); if ( s != null ) { sb.append( s ); } if ( getIndex() >= 0 ) { sb.append("index in certpath: ").append(getIndex()).append('\n'); sb.append(getCertPath()); } return sb.toString(); } /** * Prints a stack trace to System.err, including the backtrace * of the cause, if any. */ public void printStackTrace() { printStackTrace(System.err); } /** * Prints a stack trace to a PrintStream, including the * backtrace of the cause, if any. * * @param ps the PrintStream to use for output */ public void printStackTrace(PrintStream ps) { super.printStackTrace(ps); if ( getCause() != null ) { getCause().printStackTrace(ps); } } /** * Prints a stack trace to a PrintWriter, including the * backtrace of the cause, if any. * * @param pw the PrintWriter to use for output */ public void printStackTrace(PrintWriter pw) { super.printStackTrace(pw); if ( getCause() != null ) { getCause().printStackTrace(pw); } } } bouncycastle-1.49.orig/jdk1.1/java/security/cert/X509CRL.java0000644000175000017500000000433311705654526023035 0ustar ebourgebourg package java.security.cert; import java.math.BigInteger; import java.security.InvalidKeyException; import java.security.MessageDigest; import java.security.NoSuchAlgorithmException; import java.security.NoSuchProviderException; import java.security.Principal; import java.security.PublicKey; import java.security.SignatureException; import java.util.Date; import java.util.Set; public abstract class X509CRL extends CRL implements X509Extension { protected X509CRL() { super("X.509"); } public boolean equals(Object other) { if ( this == other ) return true; if ( !(other instanceof X509CRL) ) return false; try { byte[] enc1 = getEncoded(); byte[] enc2 = ((X509CRL)other).getEncoded(); return MessageDigest.isEqual(enc1, enc2); } catch (CRLException e) { return false; } } public int hashCode() { int hashcode = 0; try { byte[] encoded = getEncoded(); for (int i = 1; i < encoded.length; i++) { hashcode += encoded[i] * i; } } catch (CRLException ce) { return(hashcode); } return(hashcode); } public abstract byte[] getEncoded() throws CRLException; public abstract Principal getIssuerDN(); public abstract Date getNextUpdate(); public abstract X509CRLEntry getRevokedCertificate(BigInteger serialNumber); public abstract Set getRevokedCertificates(); public abstract String getSigAlgName(); public abstract String getSigAlgOID(); public abstract byte[] getSigAlgParams(); public abstract byte[] getSignature(); public abstract byte[] getTBSCertList() throws CRLException; public abstract Date getThisUpdate(); public abstract int getVersion(); public abstract void verify(PublicKey key) throws CRLException, NoSuchAlgorithmException, InvalidKeyException, NoSuchProviderException, SignatureException; public abstract void verify(PublicKey key, String sigProvider) throws CRLException, NoSuchAlgorithmException, InvalidKeyException, NoSuchProviderException, SignatureException; } bouncycastle-1.49.orig/jdk1.1/java/security/cert/CertificateNotYetValidException.java0000644000175000017500000000037511705654526030255 0ustar ebourgebourg package java.security.cert; public class CertificateNotYetValidException extends CertificateException { public CertificateNotYetValidException() { } public CertificateNotYetValidException(String msg) { super(msg); } } bouncycastle-1.49.orig/jdk1.1/java/security/cert/CertPathBuilder.java0000644000175000017500000002163511705654526025054 0ustar ebourgebourgpackage java.security.cert; import java.security.InvalidAlgorithmParameterException; import java.security.NoSuchAlgorithmException; import java.security.NoSuchProviderException; import java.security.Provider; import java.security.Security; /** * A class for building certification paths (also known as certificate * chains).
    *
    * This class uses a provider-based architecture, as described in the * Java Cryptography Architecture. To create a * CertPathBuilder, call one of the static * getInstance methods, passing in the algorithm name of * the CertPathBuilder desired and optionally the name of the provider * desired.
    *
    * Once a CertPathBuilder object has been created, * certification paths can be constructed by calling the * {@link #build build} method and passing it an algorithm-specific set * of parameters. If successful, the result (including the CertPath * that was built) is returned in an object that implements the * CertPathBuilderResult interface.
    *
    * Concurrent Access
    *
    * The static methods of this class are guaranteed to be * thread-safe. Multiple threads may concurrently invoke the static * methods defined in this class with no ill effects.
    *
    * However, this is not true for the non-static methods defined by * this class. Unless otherwise documented by a specific provider, * threads that need to access a single CertPathBuilder * instance concurrently should synchronize amongst themselves and * provide the necessary locking. Multiple threads each manipulating a * different CertPathBuilder instance need not * synchronize.
    *
    * Uses {@link CertUtil CertUtil} to actualiy load the SPI classes. * * @see CertUtil **/ public class CertPathBuilder extends Object { private CertPathBuilderSpi builderSpi; private Provider provider; private String algorithm; /** * Creates a CertPathBuilder object of the given algorithm, and * encapsulates the given provider implementation (SPI object) * in it. * * @param builderSpi the provider implementation * @param provider the provider * @param algorithm the algorithm name **/ protected CertPathBuilder(CertPathBuilderSpi builderSpi, Provider provider, String algorithm) { this.builderSpi = builderSpi; this.provider = provider; this.algorithm = algorithm; } /** * Returns a CertPathBuilder object that implements the * specified algorithm.
    *
    * If the default provider package provides an implementation * of the specified CertPathBuilder algorithm, an instance of * CertPathBuilder containing that implementation is * returned. If the requested algorithm is not available in * the default package, other packages are searched.
    *
    * @param algorithm the name of the requested CertPathBuilder algorithm * * @return a CertPathBuilder object that implements the * specified algorithm * * @exception NoSuchAlgorithmException if the requested * algorithm is not available in the default provider package * or any of the other provider packages that were searched **/ public static CertPathBuilder getInstance(String algorithm) throws NoSuchAlgorithmException { try { CertUtil.Implementation imp = CertUtil.getImplementation("CertPathBuilder", algorithm, (String)null); if (imp != null) { return new CertPathBuilder((CertPathBuilderSpi)imp.getEngine(), imp.getProvider(), algorithm); } } catch ( NoSuchProviderException ex ) {} throw new NoSuchAlgorithmException("can't find type " + algorithm); } /** * Returns a CertPathBuilder object that implements the * specified algorithm, as supplied by the specified provider. * * @param algorithm the name of the requested CertPathBuilder * algorithm * @param provider the name of the provider * * @return a CertPathBuilder object that implements the * specified algorithm, as supplied by the specified provider * * @exception NoSuchAlgorithmException if the requested algorithm * is not available from the specified provider * @exception NoSuchProviderException if the provider has not * been configured * @exception IllegalArgumentException if the provider is null **/ public static CertPathBuilder getInstance(String algorithm, String provider) throws NoSuchAlgorithmException, NoSuchProviderException { if ( provider == null ) throw new IllegalArgumentException("provider must be non-null"); CertUtil.Implementation imp = CertUtil.getImplementation("CertPathBuilder", algorithm, provider); if (imp != null) { return new CertPathBuilder((CertPathBuilderSpi)imp.getEngine(), imp.getProvider(), algorithm); } throw new NoSuchAlgorithmException("can't find type " + algorithm); } /** * Returns a CertPathBuilder object that implements the * specified algorithm, as supplied by the specified * provider. Note: the provider doesn't have to be registered. * * @param algorithm the name of the requested CertPathBuilder * algorithm * @param provider the provider * @return a CertPathBuilder object that implements the * specified algorithm, as supplied by the specified provider * * @exception NoSuchAlgorithmException if the requested algorithm * is not available from the specified provider * @exception IllegalArgumentException if the provider is null. **/ public static CertPathBuilder getInstance(String algorithm, Provider provider) throws NoSuchAlgorithmException { if ( provider == null ) throw new IllegalArgumentException("provider must be non-null"); CertUtil.Implementation imp = CertUtil.getImplementation("CertPathBuilder", algorithm, provider); if (imp != null) { return new CertPathBuilder((CertPathBuilderSpi)imp.getEngine(), provider, algorithm); } throw new NoSuchAlgorithmException("can't find type " + algorithm); } /** * Returns the provider of this CertPathBuilder. * * @return the provider of this CertPathBuilder **/ public final Provider getProvider() { return provider; } /** * Returns the name of the algorithm of this * CertPathBuilder. * * @return the name of the algorithm of this CertPathBuilder **/ public final String getAlgorithm() { return algorithm; } /** * Attempts to build a certification path using the specified algorithm * parameter set. * * @param params the algorithm parameters * * @return the result of the build algorithm * * @exception CertPathBuilderException if the builder is unable to construct * a certification path that satisfies the specified parameters * @exception InvalidAlgorithmParameterException if the specified parameters * are inappropriate for this CertPathBuilder */ public final CertPathBuilderResult build(CertPathParameters params) throws CertPathBuilderException, InvalidAlgorithmParameterException { return builderSpi.engineBuild(params); } /** * Returns the default CertPathBuilder type as specified in * the Java security properties file, or the string "PKIX" * if no such property exists. The Java security properties file is * located in the file named <JAVA_HOME>/lib/security/java.security, * where <JAVA_HOME> refers to the directory where the SDK was * installed.
    *
    * The default CertPathBuilder type can be used by * applications that do not want to use a hard-coded type when calling one * of the getInstance methods, and want to provide a default * type in case a user does not specify its own.
    *
    * The default CertPathBuilder type can be changed by * setting the value of the "certpathbuilder.type" security property * (in the Java security properties file) to the desired type. * * @return the default CertPathBuilder type as specified * in the Java security properties file, or the string "PKIX" * if no such property exists. */ public static final String getDefaultType() { String defaulttype = null; defaulttype = Security.getProperty("certpathbuilder.type"); if ( defaulttype == null || defaulttype.length() <= 0 ) return "PKIX"; else return defaulttype; } } bouncycastle-1.49.orig/jdk1.1/java/security/cert/PKIXParameters.java0000644000175000017500000006372411705654526024637 0ustar ebourgebourgpackage java.security.cert; import java.security.InvalidAlgorithmParameterException; import java.security.KeyStore; import java.security.KeyStoreException; import java.util.ArrayList; import java.util.Collections; import java.util.Date; import java.util.Enumeration; import java.util.HashSet; import java.util.Iterator; import java.util.List; import java.util.Set; /** * Parameters used as input for the PKIX CertPathValidator algorithm.
    *
    * A PKIX CertPathValidator uses these parameters to validate a * CertPath according to the PKIX certification path validation * algorithm.
    *
    * To instantiate a PKIXParameters object, an application must specify * one or more most-trusted CAs as defined by the PKIX certification * path validation algorithm. The most-trusted CAs can be specified * using one of two constructors. An application can call * {@link #PKIXParameters(Set)}, specifying a Set of TrustAnchor objects, each * of which identify a most-trusted CA. Alternatively, an application * can call {@link #PKIXParameters(KeyStore)}, specifying a KeyStore instance * containing trusted certificate entries, each of which will be * considered as a most-trusted CA.
    *
    * Once a PKIXParameters object has been created, other parameters can * be specified (by calling {@link #setInitialPolicies} or {@link #setDate}, for * instance) and then the PKIXParameters is passed along with the * CertPath to be validated to {@link CertPathValidator#validate}.
    *
    * Any parameter that is not set (or is set to null) will be set to the * default value for that parameter. The default value for the date * parameter is null, which indicates the current time when the path is * validated. The default for the remaining parameters is the least * constrained.
    *
    * Concurrent Access
    *
    * Unless otherwise specified, the methods defined in this class are * not thread-safe. Multiple threads that need to access a single * object concurrently should synchronize amongst themselves and * provide the necessary locking. Multiple threads each manipulating * separate objects need not synchronize. * * @see CertPathValidator **/ public class PKIXParameters implements CertPathParameters { private Set trustAnchors; private Set initialPolicies = new HashSet(); private List certStores = new ArrayList(); private CertSelector certSelector; private List certPathCheckers = new ArrayList(); private boolean revocationEnabled = true; private boolean explicitPolicyRequired = false; private boolean policyMappingInhibited = false; private boolean anyPolicyInhibited = false; private boolean policyQualifiersRejected = true; private Date date; private String sigProvider; /** * Creates an instance of PKIXParameters with the specified * Set of most-trusted CAs. Each element of the set is a * TrustAnchor.
    *
    * Note that the Set is copied to protect against subsequent * modifications. * * @param trustAnchors a Set of TrustAnchors * * @exception InvalidAlgorithmParameterException if the * specified Set is empty (trustAnchors.isEmpty() == true) * @exception NullPointerException if the specified Set is null * @exception ClassCastException if any of the elements in the * Set are not of type * java.security.cert.TrustAnchor **/ public PKIXParameters(Set trustAnchors) throws InvalidAlgorithmParameterException { setTrustAnchors( trustAnchors ); } /** * Creates an instance of PKIXParameters that populates the * set of most-trusted CAs from the trusted certificate * entries contained in the specified KeyStore. Only keystore * entries that contain trusted X509Certificates are * considered; all other certificate types are ignored. * * @param keystore a KeyStore from which the set of * most-trusted CAs will be populated * * @exception KeyStoreException if the keystore has not been * initialized * @exception InvalidAlgorithmParameterException if the keystore * does not contain at least one trusted certificate entry * @exception NullPointerException if the keystore is null **/ public PKIXParameters(KeyStore keystore) throws KeyStoreException, InvalidAlgorithmParameterException { if ( keystore == null ) throw new NullPointerException( "the keystore parameter must be non-null" ); Set trustAnchors = new HashSet(); String alias; Certificate cert; Enumeration enum = keystore.aliases(); while ( enum.hasMoreElements() ) { alias = (String)enum.nextElement(); if ( keystore.isCertificateEntry( alias ) ) { cert = keystore.getCertificate( alias ); if ( cert instanceof X509Certificate ) trustAnchors.add( new TrustAnchor( (X509Certificate)cert, null ) ); } } setTrustAnchors( trustAnchors ); } /** * Returns an immutable Set of the most-trusted CAs. * * @return an immutable Set of * TrustAnchors (never null) * * @see #setTrustAnchors **/ public Set getTrustAnchors() { return Collections.unmodifiableSet(trustAnchors); } /** * Sets the Set of most-trusted CAs.
    *
    * Note that the Set is copied to protect against subsequent * modifications.
    *
    * @param trustAnchors a Set of TrustAnchors * * @exception InvalidAlgorithmParameterException if the specified Set is empty (trustAnchors.isEmpty() == true) * @exception NullPointerException if the specified Set is null * @exception ClassCastException if any of the elements in * the set are not of type java.security.cert.TrustAnchor * * @see #getTrustAnchors **/ public void setTrustAnchors(Set trustAnchors) throws InvalidAlgorithmParameterException { if ( trustAnchors == null ) throw new NullPointerException("the trustAnchors parameter must be non-null"); if ( trustAnchors.isEmpty() ) throw new InvalidAlgorithmParameterException("the trustAnchors parameter must be non-empty"); Iterator iter = trustAnchors.iterator(); TrustAnchor obj; this.trustAnchors = new HashSet(); while( iter.hasNext() ) { obj = (TrustAnchor)iter.next(); if ( obj != null ) { this .trustAnchors.add( obj ); } } } /** * Returns an immutable Set of initial policy identifiers (OID * strings), indicating that any one of these policies would * be acceptable to the certificate user for the purposes of * certification path processing. The default return value is * an empty Set, which is interpreted as meaning that any * policy would be acceptable. * * @return an immutable Set of initial policy * OIDs in String format, or an empty Set (implying any policy * is acceptable). Never returns null. * * @see #setInitialPolicies(java.util.Set) **/ public Set getInitialPolicies() { Set returnSet = initialPolicies; if ( initialPolicies == null ) returnSet = new HashSet(); return Collections.unmodifiableSet( returnSet ); } /** * Sets the Set of initial policy identifiers (OID strings), * indicating that any one of these policies would be * acceptable to the certificate user for the purposes of * certification path processing. By default, any policy is * acceptable (i.e. all policies), so a user that wants to * allow any policy as acceptable does not need to call this * method, or can call it with an empty Set (or null).
    *
    * Note that the Set is copied to protect against subsequent * modifications.
    *
    * @param initialPolicies a Set of initial policy OIDs in String format (or null) * * @exception ClassCastException if any of the elements in the * set are not of type String * * @see #getInitialPolicies() **/ public void setInitialPolicies(Set initialPolicies) { if ( initialPolicies == null || initialPolicies.isEmpty() ) { this.initialPolicies = null; } else { Iterator iter = initialPolicies.iterator(); this.initialPolicies = new HashSet(); String obj; while ( iter.hasNext() ) { obj = (String)iter.next(); if ( obj != null ) { this.initialPolicies.add( obj ); } } } } /** * Sets the list of CertStores to be used in finding * certificates and CRLs. May be null, in which case no * CertStores will be used. The first CertStores in the list * may be preferred to those that appear later.
    *
    * Note that the List is copied to protect against subsequent * modifications.
    *
    * @param stores a List of CertStores (or null) * * @exception ClassCastException if any of the elements in the * list are not of type java.security.cert.CertStore * * @see #getCertStores() **/ public void setCertStores(List stores) { certStores = new ArrayList(); if ( stores != null && ! stores.isEmpty() ) { Iterator iter = stores.iterator(); CertStore obj; while ( iter.hasNext() ) { obj = (CertStore)iter.next(); if ( obj != null ) { certStores.add( obj ); } } } } /** * Adds a CertStore to the end of the list of CertStores used * in finding certificates and CRLs. * * @param store the CertStore to add. If * nullnull) * * @see #setCertStores(java.util.List) **/ public List getCertStores() { return Collections.unmodifiableList(certStores); } /** * Sets the RevocationEnabled flag. If this flag is true, the default * revocation checking mechanism of the underlying PKIX service provider * will be used. If this flag is false, the default revocation checking * mechanism will be disabled (not used).
    *
    * When a PKIXParameters object is created, this flag is set * to true. This setting reflects the most common strategy for checking * revocation, since each service provider must support revocation * checking to be PKIX compliant. Sophisticated applications should set * this flag to false when it is not practical to use a PKIX service * provider's default revocation checking mechanism or when an alternative * revocation checking mechanism is to be substituted (by also calling the * {@link #addCertPathChecker addCertPathChecker} or {@link * #setCertPathCheckers setCertPathCheckers} methods). * * @param val the new value of the RevocationEnabled flag **/ public void setRevocationEnabled(boolean val) { revocationEnabled = val; } /** * Checks the RevocationEnabled flag. If this flag is true, * the default revocation checking mechanism of the underlying * PKIX service provider will be used. If this flag is false, * the default revocation checking mechanism will be disabled * (not used). See the setRevocationEnabled method for more * details on setting the value of this flag. * * @return the current value of the RevocationEnabled flag **/ public boolean isRevocationEnabled() { return revocationEnabled; } /** * Sets the ExplicitPolicyRequired flag. If this flag is true, * an acceptable policy needs to be explicitly identified in * every certificate. By default, the ExplicitPolicyRequired * flag is false. * * @param val true if explicit policy is to be required, false * otherwise **/ public void setExplicitPolicyRequired(boolean val) { explicitPolicyRequired = val; } /** * Checks if explicit policy is required. If this flag is * true, an acceptable policy needs to be explicitly * identified in every certificate. By default, the * ExplicitPolicyRequired flag is false. * * @return true if explicit policy is required, false otherwise **/ public boolean isExplicitPolicyRequired() { return explicitPolicyRequired; } /** * Sets the PolicyMappingInhibited flag. If this flag is true, * policy mapping is inhibited. By default, policy mapping is * not inhibited (the flag is false). * * @param val true if policy mapping is to be inhibited, false otherwise **/ public void setPolicyMappingInhibited(boolean val) { policyMappingInhibited = val; } /** * Checks if policy mapping is inhibited. If this flag is * true, policy mapping is inhibited. By default, policy * mapping is not inhibited (the flag is false). * * @return true if policy mapping is inhibited, false otherwise **/ public boolean isPolicyMappingInhibited() { return policyMappingInhibited; } /** * Sets state to determine if the any policy OID should be * processed if it is included in a certificate. By default, * the any policy OID is not inhibited ({@link #isAnyPolicyInhibited()} * returns false). * * @return val - true if the any policy OID is to be inhibited, false otherwise **/ public void setAnyPolicyInhibited(boolean val) { anyPolicyInhibited = val; } /** * Checks whether the any policy OID should be processed if it * is included in a certificate. * * @return true if the any policy OID is inhibited, false otherwise **/ public boolean isAnyPolicyInhibited() { return anyPolicyInhibited; } /** * Sets the PolicyQualifiersRejected flag. If this flag is * true, certificates that include policy qualifiers in a * certificate policies extension that is marked critical are * rejected. If the flag is false, certificates are not * rejected on this basis.
    *
    * When a PKIXParameters object is created, this flag is set * to true. This setting reflects the most common (and * simplest) strategy for processing policy * qualifiers. Applications that want to use a more * sophisticated policy must set this flag to false.
    *
    * Note that the PKIX certification path validation algorithm * specifies that any policy qualifier in a certificate * policies extension that is marked critical must be * processed and validated. Otherwise the certification path * must be rejected. If the policyQualifiersRejected flag is * set to false, it is up to the application to validate all * policy qualifiers in this manner in order to be PKIX * compliant. * * @param qualifiersRejected the new value of the PolicyQualifiersRejected flag * * @see #getPolicyQualifiersRejected() * @see PolicyQualifierInfo **/ public void setPolicyQualifiersRejected(boolean qualifiersRejected) { policyQualifiersRejected = qualifiersRejected; } /** * Gets the PolicyQualifiersRejected flag. If this flag is * true, certificates that include policy qualifiers in a * certificate policies extension that is marked critical are * rejected. If the flag is false, certificates are not * rejected on this basis.
    *
    * When a PKIXParameters object is created, this flag is set to * true. This setting reflects the most common (and simplest) * strategy for processing policy qualifiers. Applications that * want to use a more sophisticated policy must set this flag * to false. * * @return the current value of the PolicyQualifiersRejected flag * * @see #setPolicyQualifiersRejected(boolean) **/ public boolean getPolicyQualifiersRejected() { return policyQualifiersRejected; } /** * Returns the time for which the validity of the * certification path should be determined. If null, the * current time is used.
    *
    * Note that the Date returned is copied to protect against * subsequent modifications. * * @return the Date, or null if not set * * @see #setDate(java.util.Date) **/ public Date getDate() { if ( date == null ) return null; return new Date( date.getTime() ); } /** * Sets the time for which the validity of the certification * path should be determined. If null, the current time is * used.
    *
    * Note that the Date supplied here is copied to protect * against subsequent modifications. * * @param date the Date, or null for the current time * * @see #getDate() **/ public void setDate(Date date) { if ( date == null ) this.date = null; else this.date = new Date( date.getTime() ); } /** * Sets a List of additional certification path checkers. If * the specified List contains an object that is not a * PKIXCertPathChecker, it is ignored.
    *
    * Each PKIXCertPathChecker specified implements additional * checks on a certificate. Typically, these are checks to * process and verify private extensions contained in * certificates. Each PKIXCertPathChecker should be * instantiated with any initialization parameters needed to * execute the check.
    *
    * This method allows sophisticated applications to extend a * PKIX CertPathValidator or CertPathBuilder. Each of the * specified PKIXCertPathCheckers will be called, in turn, by * a PKIX CertPathValidator or CertPathBuilder for each * certificate processed or validated.
    *
    * Regardless of whether these additional PKIXCertPathCheckers * are set, a PKIX CertPathValidator or CertPathBuilder must * perform all of the required PKIX checks on each * certificate. The one exception to this rule is if the * RevocationEnabled flag is set to false (see the * {@link #setRevocationEnabled(boolean) setRevocationEnabled} method).
    *
    * Note that the List supplied here is copied and each * PKIXCertPathChecker in the list is cloned to protect against * subsequent modifications. * * @param checkers a List of PKIXCertPathCheckers. May be * null, in which case no additional checkers will be used. * @exception ClassCastException if any of the elements in the * list are not of type * java.security.cert.PKIXCertPathChecker * @see #getCertPathCheckers() **/ public void setCertPathCheckers(List checkers) { certPathCheckers = new ArrayList(); if ( checkers == null ) return; Iterator iter = checkers.iterator(); while ( iter.hasNext() ) certPathCheckers.add( (PKIXCertPathChecker)((PKIXCertPathChecker)iter.next()).clone() ); } /** * Returns the List of certification path checkers. The * returned List is immutable, and each PKIXCertPathChecker in * the List is cloned to protect against subsequent * modifications. * * @return an immutable List of PKIXCertPathCheckers (may be empty, but not null) * * @see #setCertPathCheckers(java.util.List) **/ public List getCertPathCheckers() { List checkers = new ArrayList(); Iterator iter = certPathCheckers.iterator(); while ( iter.hasNext() ) { checkers.add( (PKIXCertPathChecker)((PKIXCertPathChecker)iter.next()).clone() ); } return Collections.unmodifiableList(checkers); } /** * Adds a PKIXCertPathChecker to the list of certification * path checkers. See the {@link #setCertPathCheckers} method for more * details.
    *
    * Note that the PKIXCertPathChecker is cloned to protect * against subsequent modifications. * * @param checker a PKIXCertPathChecker to add * to the list of checks. If null, the checker is * ignored (not added to list). **/ public void addCertPathChecker( PKIXCertPathChecker checker ) { if ( checker != null ) { certPathCheckers.add( checker.clone() ); } } /** * Returns the signature provider's name, or null if not set. * * @return the signature provider's name (or null) * * @see #setSigProvider(java.lang.String) **/ public String getSigProvider() { return sigProvider; } /** * Sets the signature provider's name. The specified provider * will be preferred when creating Signature objects. If null * or not set, the first provider found supporting the * algorithm will be used. * * @param sigProvider the signature provider's name (or null) * * @see #getSigProvider() **/ public void setSigProvider(String sigProvider) { this.sigProvider = sigProvider; } /** * Returns the required constraints on the target * certificate. The constraints are returned as an instance of * CertSelector. If null, no constraints are defined.
    *
    * Note that the CertSelector returned is cloned to protect * against subsequent modifications. * * @return a CertSelector specifying the constraints on the target certificate (or null) * * @see #setTargetCertConstraints(java.security.cert.CertSelector) **/ public CertSelector getTargetCertConstraints() { if ( certSelector == null ) return null; return (CertSelector)certSelector.clone(); } /** * Sets the required constraints on the target * certificate. The constraints are specified as an instance * of CertSelector. If null, no constraints are defined.
    *
    * Note that the CertSelector specified is cloned to protect * against subsequent modifications. * * @param selector a CertSelector specifying the constraints * on the target certificate (or null) * * @see #getTargetCertConstraints() **/ public void setTargetCertConstraints(CertSelector selector) { if ( selector == null ) certSelector = null; else certSelector = (CertSelector)selector.clone(); } /** * Makes a copy of this PKIXParameters object. Changes to the * copy will not affect the original and vice versa. * * @return a copy of this PKIXParameters object **/ public Object clone() { try { PKIXParameters obj = (PKIXParameters)super.clone(); obj.certStores = new ArrayList( certStores ); Iterator iter = certPathCheckers.iterator(); obj.certPathCheckers = new ArrayList(); while ( iter.hasNext() ) { obj.certPathCheckers.add( ((PKIXCertPathChecker)iter.next()).clone() ); } if ( initialPolicies != null ) { obj.initialPolicies = new HashSet( initialPolicies ); } if ( trustAnchors != null ) { obj.trustAnchors = new HashSet( trustAnchors ); } if ( certSelector != null ) { obj.certSelector = (CertSelector)certSelector.clone(); } return obj; } catch ( CloneNotSupportedException ex ) { throw new InternalError(); } } /** * Returns a formatted string describing the parameters. * * @return a formatted string describing the parameters. **/ public String toString() { StringBuffer s = new StringBuffer(); s.append("[\n"); if ( trustAnchors != null ) { s.append(" Trust Anchors: ").append(trustAnchors).append('\n'); } if ( initialPolicies != null ) { if ( initialPolicies.isEmpty() ) { s.append(" Initial Policy OIDs: any\n" ); } else { s.append(" Initial Policy OIDs: [").append(initialPolicies).append("]\n"); } } s.append(" Validity Date: "); if ( date != null ) s.append(date); else s.append("null"); s.append('\n'); s.append(" Signature Provider: "); if ( sigProvider != null ) s.append(sigProvider); else s.append("null"); s.append('\n'); s.append(" Default Revocation Enabled: "); s.append(revocationEnabled); s.append('\n' ); s.append(" Explicit Policy Required: "); s.append(explicitPolicyRequired); s.append('\n'); s.append(" Policy Mapping Inhibited: "); s.append(policyMappingInhibited); s.append('\n'); s.append(" Any Policy Inhibited: "); s.append(anyPolicyInhibited); s.append('\n'); s.append(" Policy Qualifiers Rejected: "); s.append(policyQualifiersRejected); s.append('\n'); s.append(" Target Cert Constraints: "); s.append(certSelector); s.append('\n'); s.append(" Certification Path Checkers: ["); s.append(certPathCheckers); s.append( "}\n"); s.append(" CertStores: ["); s.append(certStores); s.append("}\n"); s.append("]\n"); return s.toString(); } } bouncycastle-1.49.orig/jdk1.1/java/security/cert/CertPathBuilderResult.java0000644000175000017500000000257711705654526026257 0ustar ebourgebourgpackage java.security.cert; /** * A specification of the result of a certification path builder algorithm. * All results returned by the {@link CertPathBuilder#build CertPathBuilder.build} method * must implement this interface.
    *
    * At a minimum, a CertPathBuilderResult contains the CertPath built by the * CertPathBuilder instance. Implementations of this interface may add methods * to return implementation or algorithm specific information, such as * debugging information or certification path validation results.
    *
    * Concurrent Access
    *
    * Unless otherwise specified, the methods defined in this interface are not * thread-safe. Multiple threads that need to access a single object * concurrently should synchronize amongst themselves and provide the * necessary locking. Multiple threads each manipulating separate objects * need not synchronize. **/ public interface CertPathBuilderResult extends Cloneable { /** * Returns the built certification path. * * @return the certification path (never null) */ public CertPath getCertPath(); /** * Makes a copy of this CertPathBuilderResult. * Changes to the copy will not affect the original and vice * versa. * * @return a copy of this CertPathBuilderResult */ public Object clone(); } bouncycastle-1.49.orig/jdk1.1/java/security/cert/CertUtil.java0000644000175000017500000004072611705654526023570 0ustar ebourgebourgpackage java.security.cert; import java.io.ByteArrayOutputStream; import java.io.IOException; import java.security.InvalidAlgorithmParameterException; import java.security.NoSuchProviderException; import java.security.Provider; import java.security.Security; import org.bouncycastle.asn1.ASN1Object; import org.bouncycastle.asn1.ASN1ObjectIdentifier; import org.bouncycastle.asn1.DERIA5String; import org.bouncycastle.asn1.DEROutputStream; import org.bouncycastle.asn1.OIDTokenizer; import org.bouncycastle.asn1.x509.X509Name; import org.bouncycastle.util.Strings; class CertUtil { static class Implementation { Object engine; Provider provider; Implementation( Object engine, Provider provider) { this.engine = engine; this.provider = provider; } Object getEngine() { return engine; } Provider getProvider() { return provider; } } /** * see if we can find an algorithm (or its alias and what it represents) in * the property table for the given provider. * * @return null if no algorithm found, an Implementation if it is. */ static Implementation getImplementation( String baseName, String algorithm, Provider prov) { if (prov == null) { Provider[] provider = Security.getProviders(); // // search every provider looking for the algorithm we want. // for (int i = 0; i != provider.length; i++) { Implementation imp = getImplementation(baseName, algorithm, provider[i]); if (imp != null) { return imp; } } return null; } String alias; while ((alias = prov.getProperty("Alg.Alias." + baseName + "." + algorithm)) != null) { algorithm = alias; } String className = prov.getProperty(baseName + "." + algorithm); if (className != null) { try { return new Implementation(Class.forName(className).newInstance(), prov); } catch (ClassNotFoundException e) { throw new IllegalStateException( "algorithm " + algorithm + " in provider " + prov.getName() + " but no class found!"); } catch (Exception e) { throw new IllegalStateException( "algorithm " + algorithm + " in provider " + prov.getName() + " but class inaccessible: " + e.toString()); } } return null; } /** * return an implementation for a given algorithm/provider. * If the provider is null, we grab the first avalaible who has the required algorithm. * * @return null if no algorithm found, an Implementation if it is. * @exception NoSuchProviderException if a provider is specified and not found. */ static Implementation getImplementation( String baseName, String algorithm, String provider) throws NoSuchProviderException { if (provider == null) { Provider[] prov = Security.getProviders(); // // search every provider looking for the algorithm we want. // for (int i = 0; i != prov.length; i++) { Implementation imp = getImplementation(baseName, algorithm, prov[i]); if (imp != null) { return imp; } } } else { Provider prov = Security.getProvider(provider); if (prov == null) { throw new NoSuchProviderException("Provider " + provider + " not found"); } return getImplementation(baseName, algorithm, prov); } return null; } /** * see if we can find an algorithm (or its alias and what it represents) in * the property table for the given provider. * * @return null if no algorithm found, an Implementation if it is. */ static Implementation getImplementation(String baseName, String algorithm, Provider prov, Class[] ctorparamtype, Object[] ctorparam) throws InvalidAlgorithmParameterException { String alias; while ((alias = prov.getProperty("Alg.Alias." + baseName + "." + algorithm)) != null) { algorithm = alias; } String className = prov.getProperty(baseName + "." + algorithm); if (className != null) { try { return new Implementation(Class.forName(className) .getConstructor(ctorparamtype).newInstance(ctorparam), prov); } catch (ClassNotFoundException e) { throw new IllegalStateException("algorithm " + algorithm + " in provider " + prov.getName() + " but no class found!"); } catch (Exception e) { if (e instanceof InvalidAlgorithmParameterException) { throw (InvalidAlgorithmParameterException)e; } throw new IllegalStateException("algorithm " + algorithm + " in provider " + prov.getName() + " but class inaccessible!"); } } return null; } /** * return an implementation for a given algorithm/provider. If the provider * is null, we grab the first avalaible who has the required algorithm. * * @return null if no algorithm found, an Implementation if it is. * * @exception NoSuchProviderException * if a provider is specified and not found. */ static Implementation getImplementation(String baseName, String algorithm, String provider, Class[] ctorparamtype, Object[] ctorparam) throws NoSuchProviderException, InvalidAlgorithmParameterException { if (provider == null) { Provider[] prov = Security.getProviders(); // // search every provider looking for the algorithm we want. // for (int i = 0; i != prov.length; i++) { Implementation imp = getImplementation(baseName, algorithm, prov[i], ctorparamtype, ctorparam); if (imp != null) { return imp; } } } else { Provider prov = Security.getProvider(provider); if (prov == null) { throw new NoSuchProviderException("Provider " + provider + " not found"); } return getImplementation(baseName, algorithm, prov, ctorparamtype, ctorparam); } return null; } static byte[] parseGeneralName(int type, String data) throws IOException { byte[] encoded = null; switch (type) { case 0: throw new IOException( "unable to parse OtherName String representation"); case 1: encoded = parseRfc822(data.trim()); break; case 2: encoded = parseDNSName(data.trim()); break; case 3: throw new IOException( "unable to parse ORAddress String representation"); case 4: encoded = parseX509Name(data.trim()); break; case 5: throw new IOException( "unable to parse EDIPartyName String representation"); case 6: encoded = parseURI(data.trim()); break; case 7: encoded = parseIP(data.trim()); break; case 8: encoded = parseOID(data.trim()); break; default: throw new IOException( "unable to parse unkown type String representation"); } return encoded; } /** * Check the format of an OID.
    * Throw an IOException if the first component is not 0, 1 or 2 or the * second component is greater than 39.
    *
    * User {@link org.bouncycastle.asn1.OIDTokenizer OIDTokenizer} * * @param the * OID to be checked. * * @exception IOException * if the first component is not 0, 1 or 2 or the second * component is greater than 39. */ static byte[] parseOID(String oid) throws IOException { OIDTokenizer tokenizer = new OIDTokenizer(oid); String token; if (!tokenizer.hasMoreTokens()) { throw new IOException("OID contains no tokens"); } token = tokenizer.nextToken(); if (token == null) { throw new IOException("OID contains no tokens"); } try { int test = (Integer.valueOf(token)).intValue(); if (test < 0 || test > 2) { throw new IOException("first token is not >= 0 and <=2"); } if (!tokenizer.hasMoreTokens()) { throw new IOException("OID contains only one token"); } token = tokenizer.nextToken(); if (token == null) { throw new IOException("OID contains only one token"); } test = (Integer.valueOf(token)).intValue(); if (test < 0 || test > 39) { throw new IOException("secon token is not >= 0 and <=39"); } } catch (NumberFormatException ex) { throw new IOException("token: " + token + ": " + ex.toString()); } ASN1Object derData = new ASN1ObjectIdentifier(oid); ByteArrayOutputStream outStream = new ByteArrayOutputStream(); DEROutputStream derOutStream = new DEROutputStream(outStream); derOutStream.writeObject(derData); derOutStream.close(); return outStream.toByteArray(); } /** * Parse the given IPv4 or IPv6 into DER encoded byte array representation. * * @param the * IP in well known String format * * @return the IP as byte array * * @exception IOException * if the String could not be parsed */ private static byte[] parseIP(String data) throws IOException { byte[] encoded = parseIPv4(data); if (encoded == null) { encoded = parseIPv6(data); } if (encoded == null) { throw new IOException( "unable to parse IP to DER encoded byte array"); } return encoded; } /** * Parse the given IPv4 into DER encoded byte array representation. * * @param the * IP in well known String format * * @return the IP as byte array or null if not parseable */ private static byte[] parseIPv4(String data) { if (data.length() == 0) { return null; } int octet; int octets = 0; byte[] dst = new byte[4]; int pos = 0; int start = 0; while (start < data.length() && (pos = data.indexOf('.', start)) > start && pos - start > 3) { try { octet = (Integer.valueOf(data.substring(start, pos - start))) .intValue(); } catch (NumberFormatException ex) { return null; } if (octet < 0 || octet > 255) { return null; } dst[octets++] = (byte)(octet & 0xff); start = pos + 1; } if (octets < 4) { return null; } return dst; } /** * Parse the given IPv6 into DER encoded byte array representation.
    *
    * TODO: implement this * * @param the * IP in well known String format * * @return the IP as byte array or null if not parseable */ private static byte[] parseIPv6(String data) { return null; } /** * Parse the given URI into DER encoded byte array representation. * * @param the * URI in well known String format * * @return the URI as byte array * * @exception IOException * if the String could not be parsed */ private static byte[] parseURI(String data) throws IOException { // TODO do parsing test ASN1Object derData = new DERIA5String(data); ByteArrayOutputStream outStream = new ByteArrayOutputStream(); DEROutputStream derOutStream = new DEROutputStream(outStream); derOutStream.writeObject(derData); derOutStream.close(); return outStream.toByteArray(); } /** * Parse the given rfc822 addr-spec into DER encoded byte array * representation. * * @param the * rfc822 addr-spec in well known String format * * @return the rfc822 addr-spec as byte array * * @exception IOException * if the String could not be parsed */ private static byte[] parseRfc822(String data) throws IOException { int tmpInt = data.indexOf('@'); if (tmpInt < 0 || tmpInt >= data.length() - 1) { throw new IOException("wrong format of rfc822Name:" + data); } // TODO more test for illegal charateers ASN1Object derData = new DERIA5String(data); ByteArrayOutputStream outStream = new ByteArrayOutputStream(); DEROutputStream derOutStream = new DEROutputStream(outStream); derOutStream.writeObject(derData); derOutStream.close(); return outStream.toByteArray(); } /** * Parse the given DNS name into DER encoded byte array representation. The * String must be in den preffered name syntax as defined in RFC 1034. * * @param the * DNS name in well known String format * * @return the DNS name as byte array * * @exception IOException * if the String could not be parsed */ private static byte[] parseDNSName(String data) throws IOException { // TODO more test for illegal charateers ASN1Object derData = new DERIA5String(data); ByteArrayOutputStream outStream = new ByteArrayOutputStream(); DEROutputStream derOutStream = new DEROutputStream(outStream); derOutStream.writeObject(derData); derOutStream.close(); return outStream.toByteArray(); } /** * Parse the given X.509 name into DER encoded byte array representation. * * @param the * X.509 name in well known String format * * @return the X.509 name as byte array * * @exception IOException * if the String could not be parsed */ private static byte[] parseX509Name(String data) throws IOException { // TODO more test for illegal charateers ByteArrayOutputStream outStream = new ByteArrayOutputStream(); DEROutputStream derOutStream = new DEROutputStream(outStream); derOutStream.writeObject(new X509Name(trimX509Name(data))); derOutStream.close(); return outStream.toByteArray(); } /** * Returns the given name converted to upper case and all multi spaces squezed * to one space. **/ static String trimX509Name(String name) { String data = Strings.toUpperCase(name.trim()); int pos; while ((pos = data.indexOf(" ")) >= 0) { data = data.substring(0, pos) + data.substring(pos + 1); } while ((pos = data.indexOf(" =")) >= 0) { data = data.substring(0, pos) + data.substring(pos + 1); } while ((pos = data.indexOf("= ")) >= 0) { data = data.substring(0, pos + 1) + data.substring(pos + 2); } return data; } } bouncycastle-1.49.orig/jdk1.1/java/security/cert/CertPathValidatorSpi.java0000644000175000017500000000476311705654526026072 0ustar ebourgebourgpackage java.security.cert; import java.security.InvalidAlgorithmParameterException; /** * * The Service Provider Interface (SPI) * for the {@link CertPathValidator CertPathValidator} class. All * CertPathValidator implementations must include a class (the * SPI class) that extends this class (CertPathValidatorSpi) * and implements all of its methods. In general, instances of this class * should only be accessed through the CertPathValidator class. * For details, see the Java Cryptography Architecture.
    *
    * Concurrent Access
    *
    * Instances of this class need not be protected against concurrent * access from multiple threads. Threads that need to access a single * CertPathValidatorSpi instance concurrently should synchronize * amongst themselves and provide the necessary locking before calling the * wrapping CertPathValidator object.
    *
    * However, implementations of CertPathValidatorSpi may still * encounter concurrency issues, since multiple threads each * manipulating a different CertPathValidatorSpi instance need not * synchronize. **/ public abstract class CertPathValidatorSpi extends Object { /** * The default constructor. */ public CertPathValidatorSpi() {} /** * Validates the specified certification path using the specified * algorithm parameter set.
    *
    * The CertPath specified must be of a type that is * supported by the validation algorithm, otherwise an * InvalidAlgorithmParameterException will be thrown. For * example, a CertPathValidator that implements the PKIX * algorithm validates CertPath objects of type X.509. * * @param certPath the CertPath to be validated * @param params the algorithm parameters * * @return the result of the validation algorithm * * @exception CertPathValidatorException if the CertPath * does not validate * @exception InvalidAlgorithmParameterException if the specified * parameters or the type of the specified CertPath are * inappropriate for this CertPathValidator */ public abstract CertPathValidatorResult engineValidate(CertPath certPath, CertPathParameters params) throws CertPathValidatorException, InvalidAlgorithmParameterException; } bouncycastle-1.49.orig/jdk1.1/java/security/cert/CertificateExpiredException.java0000644000175000017500000000036111705654526027446 0ustar ebourgebourg package java.security.cert; public class CertificateExpiredException extends CertificateException { public CertificateExpiredException() { } public CertificateExpiredException(String msg) { super(msg); } } bouncycastle-1.49.orig/jdk1.1/java/security/cert/CertPathParameters.java0000644000175000017500000000114011705654526025556 0ustar ebourgebourgpackage java.security.cert; /** * A specification of certification path algorithm parameters. The purpose * of this interface is to group (and provide type safety for) all CertPath * parameter specifications. All CertPath parameter specifications must * implement this interface. **/ public interface CertPathParameters extends Cloneable { /** * Makes a copy of this CertPathParameters. Changes to the * copy will not affect the original and vice versa. * * @return a copy of this CertPathParameters **/ public Object clone(); } bouncycastle-1.49.orig/jdk1.1/java/security/cert/X509CRLSelector.java0000644000175000017500000005611011705654526024536 0ustar ebourgebourgpackage java.security.cert; import java.io.ByteArrayInputStream; import java.io.IOException; import java.math.BigInteger; import java.security.cert.CRL; import java.security.cert.X509CRL; import java.security.cert.X509Certificate; import java.util.Collection; import java.util.Date; import java.util.HashSet; import java.util.Iterator; import java.util.Set; import org.bouncycastle.asn1.ASN1InputStream; import org.bouncycastle.asn1.ASN1Object; import org.bouncycastle.asn1.ASN1OctetString; import org.bouncycastle.asn1.ASN1Sequence; import org.bouncycastle.asn1.DERInteger; import org.bouncycastle.asn1.x509.X509Extensions; import org.bouncycastle.asn1.x509.X509Name; import org.bouncycastle.jce.PrincipalUtil; /** * A CRLSelector that selects X509CRLs that match * all specified criteria. This class is particularly useful when selecting CRLs * from a CertStore to check revocation status of a particular * certificate.
    *
    * When first constructed, an X509CRLSelector has no criteria * enabled and each of the get methods return a default value (null). * Therefore, the {@link #match match} method would return true * for any X509CRL. Typically, several criteria are enabled (by * calling {@link #setIssuerNames setIssuerNames} or * {@link #setDateAndTime setDateAndTime}, for instance) and then the * X509CRLSelector is passed to * {@link CertStore#getCRLs CertStore.getCRLs} or some similar method.
    *
    * Please refer to RFC 2459 for definitions of the X.509 CRL fields and * extensions mentioned below.
    *
    * Concurrent Access
    *
    * Unless otherwise specified, the methods defined in this class are not * thread-safe. Multiple threads that need to access a single object * concurrently should synchronize amongst themselves and provide the necessary * locking. Multiple threads each manipulating separate objects need not * synchronize.
    *
    * Uses {@link org.bouncycastle.asn1.ASN1InputStream ASN1InputStream}, * {@link org.bouncycastle.asn1.ASN1Sequence ASN1Sequence}, * {@link org.bouncycastle.asn1.ASN1ObjectIdentifier ASN1ObjectIdentifier}, * {@link org.bouncycastle.asn1.DEROutputStream DEROutputStream}, * {@link org.bouncycastle.asn1.ASN1Object ASN1Object}, * {@link org.bouncycastle.asn1.x509.X509Name X509Name} * * @see CRLSelector * @see X509CRL */ public class X509CRLSelector implements CRLSelector { private Set issuerNames = null; private Set issuerNamesX509 = null; private BigInteger minCRL = null; private BigInteger maxCRL = null; private Date dateAndTime = null; private X509Certificate certChecking = null; /** * Creates an X509CRLSelector. Initially, no criteria are * set so any X509CRL will match. */ public X509CRLSelector() { } /** * Sets the issuerNames criterion. The issuer distinguished name in the * X509CRL must match at least one of the specified * distinguished names. If null, any issuer distinguished * name will do.
    *
    * This method allows the caller to specify, with a single method call, the * complete set of issuer names which X509CRLs may contain. * The specified value replaces the previous value for the issuerNames * criterion.
    *
    * The names parameter (if not null) is a * Collection of names. Each name is a String * or a byte array representing a distinguished name (in RFC 2253 or ASN.1 * DER encoded form, respectively). If null is supplied as * the value for this argument, no issuerNames check will be performed.
    *
    * Note that the names parameter can contain duplicate * distinguished names, but they may be removed from the * Collection of names returned by the * {@link #getIssuerNames getIssuerNames} method.
    *
    * If a name is specified as a byte array, it should contain a single DER * encoded distinguished name, as defined in X.501. The ASN.1 notation for * this structure is as follows. * *
    
         *  Name ::= CHOICE {
         *    RDNSequence }
         * 
         *  RDNSequence ::= SEQUENCE OF RDN
         * 
         *  RDN ::=
         *    SET SIZE (1 .. MAX) OF AttributeTypeAndValue
         * 
         *  AttributeTypeAndValue ::= SEQUENCE {
         *    type     AttributeType,
         *    value    AttributeValue }
         * 
         *  AttributeType ::= OBJECT IDENTIFIER
         * 
         *  AttributeValue ::= ANY DEFINED BY AttributeType
         *  ....
         *  DirectoryString ::= CHOICE {
         *        teletexString           TeletexString (SIZE (1..MAX)),
         *        printableString         PrintableString (SIZE (1..MAX)),
         *        universalString         UniversalString (SIZE (1..MAX)),
         *        utf8String              UTF8String (SIZE (1.. MAX)),
         *        bmpString               BMPString (SIZE (1..MAX)) }
         * 
    * *
    *
    * Note that a deep copy is performed on the Collection to * protect against subsequent modifications. * * @param names * a Collection of names (or null) * * @exception IOException * if a parsing error occurs * * @see #getIssuerNames */ public void setIssuerNames(Collection names) throws IOException { if (names == null || names.isEmpty()) { issuerNames = null; issuerNamesX509 = null; } else { Object item; Iterator iter = names.iterator(); while (iter.hasNext()) { item = iter.next(); if (item instanceof String) { addIssuerName((String)item); } else if (item instanceof byte[]) { addIssuerName((byte[])item); } else { throw new IOException("name not byte[]or String: " + item.toString()); } } } } /** * Adds a name to the issuerNames criterion. The issuer distinguished name * in the X509CRL must match at least one of the specified * distinguished names.
    *
    * This method allows the caller to add a name to the set of issuer names * which X509CRLs may contain. The specified name is added to * any previous value for the issuerNames criterion. If the specified name * is a duplicate, it may be ignored.
    *
    * Uses {@link org.bouncycastle.asn1.x509.X509Name X509Name} for parsing the * name * * @param name * the name in RFC 2253 form * * @exception IOException * if a parsing error occurs */ public void addIssuerName(String name) throws IOException { if (issuerNames == null) { issuerNames = new HashSet(); issuerNamesX509 = new HashSet(); } X509Name nameX509; try { nameX509 = new X509Name(name); } catch (IllegalArgumentException ex) { throw new IOException(ex.getMessage()); } issuerNamesX509.add(nameX509); issuerNames.add(name); } /** * Adds a name to the issuerNames criterion. The issuer distinguished name * in the X509CRL must match at least one of the specified * distinguished names.
    *
    * This method allows the caller to add a name to the set of issuer names * which X509CRLs may contain. The specified name is added to * any previous value for the issuerNames criterion. If the specified name * is a duplicate, it may be ignored. If a name is specified as a byte * array, it should contain a single DER encoded distinguished name, as * defined in X.501. The ASN.1 notation for this structure is as follows.
    *
    * The name is provided as a byte array. This byte array should contain a * single DER encoded distinguished name, as defined in X.501. The ASN.1 * notation for this structure appears in the documentation for * {@link #setIssuerNames setIssuerNames(Collection names)}.
    *
    * Note that the byte array supplied here is cloned to protect against * subsequent modifications.
    *
    * Uses {@link org.bouncycastle.asn1.x509.X509Name X509Name} for parsing the * name, {@link org.bouncycastle.asn1.ASN1InputStream ASN1InputStream}, * {@link org.bouncycastle.asn1.ASN1Object ASN1Object} and * {@link org.bouncycastle.asn1.ASN1Sequence ASN1Sequence} * * @param name * a byte array containing the name in ASN.1 DER encoded form * * @exception IOException * if a parsing error occurs */ public void addIssuerName(byte[] name) throws IOException { if (issuerNames == null) { issuerNames = new HashSet(); issuerNamesX509 = new HashSet(); } ByteArrayInputStream inStream = new ByteArrayInputStream(name); ASN1InputStream derInStream = new ASN1InputStream(inStream); ASN1Object obj = derInStream.readObject(); if (obj instanceof ASN1Sequence) { issuerNamesX509.add(new X509Name((ASN1Sequence)obj)); } else { throw new IOException("parsing error"); } issuerNames.add(name.clone()); } /** * Sets the minCRLNumber criterion. The X509CRL must have a * CRL number extension whose value is greater than or equal to the * specified value. If null, no minCRLNumber check will be * done. * * @param minCRL * the minimum CRL number accepted (or null) */ public void setMinCRLNumber(BigInteger minCRL) { this.minCRL = minCRL; } /** * Sets the maxCRLNumber criterion. The X509CRL must have a * CRL number extension whose value is less than or equal to the specified * value. If null, no maxCRLNumber check will be done. * * @param maxCRL * the maximum CRL number accepted (or null) */ public void setMaxCRLNumber(BigInteger maxCRL) { this.maxCRL = maxCRL; } /** * Sets the dateAndTime criterion. The specified date must be equal to or * later than the value of the thisUpdate component of the * X509CRL and earlier than the value of the nextUpdate * component. There is no match if the X509CRL does not * contain a nextUpdate component. If null, no dateAndTime * check will be done.
    *
    * Note that the Date supplied here is cloned to protect * against subsequent modifications. * * @param dateAndTime * the Date to match against (or null) * * @see #getDateAndTime */ public void setDateAndTime(Date dateAndTime) { if (dateAndTime == null) { this.dateAndTime = null; } else { this.dateAndTime = new Date(dateAndTime.getTime()); } } /** * Sets the certificate being checked. This is not a criterion. Rather, it * is optional information that may help a CertStore find * CRLs that would be relevant when checking revocation for the specified * certificate. If null is specified, then no such optional * information is provided. * * @param cert * the X509Certificate being checked (or * null) * * @see #getCertificateChecking */ public void setCertificateChecking(X509Certificate cert) { certChecking = cert; } /** * Returns a copy of the issuerNames criterion. The issuer distinguished * name in the X509CRL must match at least one of the * specified distinguished names. If the value returned is null, * any issuer distinguished name will do.
    *
    * If the value returned is not null, it is a * Collection of names. Each name is a String * or a byte array representing a distinguished name (in RFC 2253 or ASN.1 * DER encoded form, respectively). Note that the Collection * returned may contain duplicate names.
    *
    * If a name is specified as a byte array, it should contain a single DER * encoded distinguished name, as defined in X.501. The ASN.1 notation for * this structure is given in the documentation for * {@link #setIssuerNames setIssuerNames(Collection names)}.
    *
    * Note that a deep copy is performed on the Collection to * protect against subsequent modifications. * * @return a Collection of names (or null) * @see #setIssuerNames */ public Collection getIssuerNames() { if (issuerNames == null) { return null; } Collection set = new HashSet(); Iterator iter = issuerNames.iterator(); Object item; while (iter.hasNext()) { item = iter.next(); if (item instanceof String) { set.add(new String((String)item)); } else if (item instanceof byte[]) { set.add(((byte[])item).clone()); } } return set; } /** * Returns the minCRLNumber criterion. The X509CRL must have * a CRL number extension whose value is greater than or equal to the * specified value. If null, no minCRLNumber check will be * done. * * @return the minimum CRL number accepted (or null) */ public BigInteger getMinCRL() { return minCRL; } /** * Returns the maxCRLNumber criterion. The X509CRL must have * a CRL number extension whose value is less than or equal to the specified * value. If null, no maxCRLNumber check will be done. * * @return the maximum CRL number accepted (or null) */ public BigInteger getMaxCRL() { return maxCRL; } /** * Returns the dateAndTime criterion. The specified date must be equal to or * later than the value of the thisUpdate component of the * X509CRL and earlier than the value of the nextUpdate * component. There is no match if the X509CRL does not * contain a nextUpdate component. If null, no dateAndTime * check will be done.
    *
    * Note that the Date returned is cloned to protect against * subsequent modifications. * * @return the Date to match against (or null) * * @see #setDateAndTime */ public Date getDateAndTime() { if (dateAndTime == null) { return null; } return new Date(dateAndTime.getTime()); } /** * Returns the certificate being checked. This is not a criterion. Rather, * it is optional information that may help a CertStore find * CRLs that would be relevant when checking revocation for the specified * certificate. If the value returned is null, then no such * optional information is provided. * * @return the certificate being checked (or null) * * @see #setCertificateChecking */ public X509Certificate getCertificateChecking() { return certChecking; } /** * Returns a printable representation of the X509CRLSelector.
    *
    * Uses * {@link org.bouncycastle.asn1.x509.X509Name#toString X509Name.toString} to * format the output * * @return a String describing the contents of the * X509CRLSelector. */ public String toString() { StringBuffer s = new StringBuffer(); s.append("X509CRLSelector: [\n"); if (issuerNamesX509 != null) { s.append(" IssuerNames:\n"); Iterator iter = issuerNamesX509.iterator(); while (iter.hasNext()) { s.append(" ").append(iter.next()).append('\n'); } } if (minCRL != null) { s.append(" minCRLNumber: ").append(minCRL).append('\n'); } if (maxCRL != null) { s.append(" maxCRLNumber: ").append(maxCRL).append('\n'); } if (dateAndTime != null) { s.append(" dateAndTime: ").append(dateAndTime).append('\n'); } if (certChecking != null) { s.append(" Certificate being checked: ").append(certChecking).append('\n'); } s.append(']'); return s.toString(); } /** * Decides whether a CRL should be selected.
    *
    * Uses * {@link org.bouncycastle.asn1.x509.X509Name#toString X509Name.toString} to * parse and to compare the crl parameter issuer and * {@link org.bouncycastle.asn1.x509.X509Extensions#CRLNumber CRLNumber} to * access the CRL number extension. * * @param crl * the CRL to be checked * * @return true if the CRL should be selected, * false otherwise */ public boolean match(CRL crl) { if (!(crl instanceof X509CRL)) { return false; } X509CRL crlX509 = (X509CRL)crl; boolean test; if (issuerNamesX509 != null) { Iterator iter = issuerNamesX509.iterator(); test = false; X509Name crlIssuer = null; try { crlIssuer = PrincipalUtil.getIssuerX509Principal(crlX509); } catch (Exception ex) { return false; } while (iter.hasNext()) { if (crlIssuer.equals(iter.next(), true)) { test = true; break; } } if (!test) { return false; } } byte[] data = crlX509.getExtensionValue(X509Extensions.CRLNumber .getId()); if (data != null) { try { ByteArrayInputStream inStream = new ByteArrayInputStream(data); ASN1InputStream derInputStream = new ASN1InputStream(inStream); inStream = new ByteArrayInputStream( ((ASN1OctetString)derInputStream.readObject()) .getOctets()); derInputStream = new ASN1InputStream(inStream); BigInteger crlNumber = ((DERInteger)derInputStream.readObject()) .getPositiveValue(); if (minCRL != null && minCRL.compareTo(crlNumber) > 0) { return false; } if (maxCRL != null && maxCRL.compareTo(crlNumber) < 0) { return false; } } catch (IOException ex) { return false; } } else if (minCRL != null || maxCRL != null) { return false; } if (dateAndTime != null) { Date check = crlX509.getThisUpdate(); if (check == null) { return false; } else if (dateAndTime.before(check)) { return false; } check = crlX509.getNextUpdate(); if (check == null) { return false; } else if (!dateAndTime.before(check)) { return false; } } return true; } /** * Returns a copy of this object. * * @return the copy */ public Object clone() { try { X509CRLSelector copy = (X509CRLSelector)super.clone(); if (issuerNames != null) { copy.issuerNames = new HashSet(); Iterator iter = issuerNames.iterator(); Object obj; while (iter.hasNext()) { obj = iter.next(); if (obj instanceof byte[]) { copy.issuerNames.add(((byte[])obj).clone()); } else { copy.issuerNames.add(obj); } } copy.issuerNamesX509 = new HashSet(issuerNamesX509); } return copy; } catch (CloneNotSupportedException e) { /* Cannot happen */ throw new InternalError(e.toString()); } } /** * Decides whether a CRL should be selected. * * @param crl * the CRL to be checked * * @return true if the CRL should be selected, * false otherwise */ public boolean equals(Object obj) { if (!(obj instanceof X509CRLSelector)) { return false; } X509CRLSelector equalsCRL = (X509CRLSelector)obj; if (!equals(dateAndTime, equalsCRL.dateAndTime)) { return false; } if (!equals(minCRL, equalsCRL.minCRL)) { return false; } if (!equals(maxCRL, equalsCRL.maxCRL)) { return false; } if (!equals(issuerNamesX509, equalsCRL.issuerNamesX509)) { return false; } if (!equals(certChecking, equalsCRL.certChecking)) { return false; } return true; } /** * Return true if two Objects are unequal. * This means that one is null and the other is * not or obj1.equals(obj2) returns * false. **/ private boolean equals(Object obj1, Object obj2) { if (obj1 == null) { if (obj2 != null) { return true; } } else if (!obj1.equals(obj2)) { return true; } return false; } } bouncycastle-1.49.orig/jdk1.1/java/security/cert/X509Certificate.java0000644000175000017500000000227711705654527024645 0ustar ebourgebourg package java.security.cert; import java.math.BigInteger; import java.security.Principal; import java.util.Date; public abstract class X509Certificate extends Certificate implements X509Extension { protected X509Certificate() { super("X.509"); } public abstract void checkValidity() throws CertificateExpiredException, CertificateNotYetValidException; public abstract void checkValidity(Date date) throws CertificateExpiredException, CertificateNotYetValidException; public abstract int getBasicConstraints(); public abstract Principal getIssuerDN(); public abstract boolean[] getIssuerUniqueID(); public abstract boolean[] getKeyUsage(); public abstract Date getNotAfter(); public abstract Date getNotBefore(); public abstract BigInteger getSerialNumber(); public abstract String getSigAlgName(); public abstract String getSigAlgOID(); public abstract byte[] getSigAlgParams(); public abstract byte[] getSignature(); public abstract Principal getSubjectDN(); public abstract boolean[] getSubjectUniqueID(); public abstract byte[] getTBSCertificate() throws CertificateEncodingException; public abstract int getVersion(); } bouncycastle-1.49.orig/jdk1.1/java/security/cert/X509CertSelector.java0000644000175000017500000026471012105031243024776 0ustar ebourgebourgpackage java.security.cert; import java.io.ByteArrayInputStream; import java.io.ByteArrayOutputStream; import java.io.IOException; import java.math.BigInteger; import java.security.PublicKey; import java.security.cert.Certificate; import java.security.cert.X509Certificate; import java.text.SimpleDateFormat; import java.util.ArrayList; import java.util.Arrays; import java.util.Collection; import java.util.Collections; import java.util.Date; import java.util.Enumeration; import java.util.HashSet; import java.util.Hashtable; import java.util.Iterator; import java.util.List; import java.util.Set; import org.bouncycastle.asn1.ASN1InputStream; import org.bouncycastle.asn1.ASN1Object; import org.bouncycastle.asn1.ASN1ObjectIdentifier; import org.bouncycastle.asn1.ASN1OctetString; import org.bouncycastle.asn1.ASN1Sequence; import org.bouncycastle.asn1.ASN1TaggedObject; import org.bouncycastle.asn1.DERGeneralizedTime; import org.bouncycastle.asn1.DEROutputStream; import org.bouncycastle.asn1.util.ASN1Dump; import org.bouncycastle.asn1.x509.AlgorithmIdentifier; import org.bouncycastle.asn1.x509.ExtendedKeyUsage; import org.bouncycastle.asn1.x509.KeyPurposeId; import org.bouncycastle.asn1.x509.SubjectPublicKeyInfo; import org.bouncycastle.asn1.x509.X509Extensions; import org.bouncycastle.asn1.x509.X509Name; import org.bouncycastle.jce.PrincipalUtil; import org.bouncycastle.util.Integers; /** * A CertSelector that selects * X509Certificates that match all * specified criteria. This class is particularly useful when * selecting certificates from a CertStore to build a PKIX-compliant * certification path.
    *
    * When first constructed, an X509CertSelector has no criteria enabled * and each of the get methods return a default value (null, or -1 for * the {@link #getBasicConstraints} method). Therefore, the {@link #match} method would * return true for any X509Certificate. Typically, several criteria * are enabled (by calling {@link #setIssuer} or {@link #setKeyUsage}, for instance) and * then the X509CertSelector is passed to {@link CertStore#getCertificates} or * some similar method.
    *
    * Several criteria can be enabled (by calling {@link #setIssuer} and * {@link #setSerialNumber}, for example) such that the match method usually * uniquely matches a single X509Certificate. We say usually, since it * is possible for two issuing CAs to have the same distinguished name * and each issue a certificate with the same serial number. Other * unique combinations include the issuer, subject, * subjectKeyIdentifier and/or the subjectPublicKey criteria.
    *
    * Please refer to RFC 2459 for definitions of the X.509 certificate * extensions mentioned below.
    *
    * Concurrent Access
    *
    * Unless otherwise specified, the methods defined in this class are * not thread-safe. Multiple threads that need to access a single * object concurrently should synchronize amongst themselves and * provide the necessary locking. Multiple threads each manipulating * separate objects need not synchronize.
    *
    * TODO: implement name constraints * TODO: implement match check for path to names
    *
    * Uses {@link org.bouncycastle.asn1.ASN1InputStream ASN1InputStream}, * {@link org.bouncycastle.asn1.ASN1Sequence ASN1Sequence}, * {@link org.bouncycastle.asn1.ASN1ObjectIdentifier ASN1ObjectIdentifier}, * {@link org.bouncycastle.asn1.DEROutputStream DEROutputStream}, * {@link org.bouncycastle.asn1.ASN1Object ASN1Object}, * {@link org.bouncycastle.asn1.OIDTokenizer OIDTokenizer}, * {@link org.bouncycastle.asn1.x509.X509Name X509Name}, * {@link org.bouncycastle.asn1.x509.X509Extensions X509Extensions}, * {@link org.bouncycastle.asn1.x509.ExtendedKeyUsage ExtendedKeyUsage}, * {@link org.bouncycastle.asn1.x509.KeyPurposeId KeyPurposeId}, * {@link org.bouncycastle.asn1.x509.SubjectPublicKeyInfo SubjectPublicKeyInfo}, * {@link org.bouncycastle.asn1.x509.AlgorithmIdentifier AlgorithmIdentifier} */ public class X509CertSelector implements CertSelector { private static final Hashtable keyPurposeIdMap = new Hashtable(); static { keyPurposeIdMap.put(KeyPurposeId.id_kp_serverAuth.getId(), KeyPurposeId.id_kp_serverAuth); keyPurposeIdMap.put(KeyPurposeId.id_kp_clientAuth.getId(), KeyPurposeId.id_kp_clientAuth); keyPurposeIdMap.put(KeyPurposeId.id_kp_codeSigning.getId(), KeyPurposeId.id_kp_codeSigning); keyPurposeIdMap.put(KeyPurposeId.id_kp_emailProtection.getId(), KeyPurposeId.id_kp_emailProtection); keyPurposeIdMap.put(KeyPurposeId.id_kp_ipsecEndSystem.getId(), KeyPurposeId.id_kp_ipsecEndSystem); keyPurposeIdMap.put(KeyPurposeId.id_kp_ipsecTunnel.getId(), KeyPurposeId.id_kp_ipsecTunnel); keyPurposeIdMap.put(KeyPurposeId.id_kp_ipsecUser.getId(), KeyPurposeId.id_kp_ipsecUser); keyPurposeIdMap.put(KeyPurposeId.id_kp_timeStamping.getId(), KeyPurposeId.id_kp_timeStamping); } private X509Certificate x509Cert = null; private BigInteger serialNumber = null; private Object issuerDN = null; private X509Name issuerDNX509 = null; private Object subjectDN = null; private X509Name subjectDNX509 = null; private byte[] subjectKeyID = null; private byte[] authorityKeyID = null; private Date certValid = null; private Date privateKeyValid = null; private ASN1ObjectIdentifier subjectKeyAlgID = null; private PublicKey subjectPublicKey = null; private byte[] subjectPublicKeyByte = null; private boolean[] keyUsage = null; private Set keyPurposeSet = null; private boolean matchAllSubjectAltNames = true; private Set subjectAltNames = null; private Set subjectAltNamesByte = null; private int minMaxPathLen = -1; private Set policy = null; private Set policyOID = null; private Set pathToNames = null; private Set pathToNamesByte = null; /** * Creates an X509CertSelector. Initially, no criteria are * set so any X509Certificate will match. */ public X509CertSelector() { } /** * Sets the certificateEquals criterion. The specified * X509Certificate must be equal to the * X509Certificate passed to the match method. If * null, then this check is not applied.
    *
    * This method is particularly useful when it is necessary to match a single * certificate. Although other criteria can be specified in conjunction with * the certificateEquals criterion, it is usually not practical or * necessary. * * @param cert * the X509Certificate to match (or null) * * @see #getCertificate() */ public void setCertificate(X509Certificate cert) { x509Cert = cert; } /** * Sets the serialNumber criterion. The specified serial number must match * the certificate serial number in the X509Certificate. If * null, any certificate serial number will do. * * @param serial * the certificate serial number to match (or null) * * @see #getSerialNumber() */ public void setSerialNumber(BigInteger serial) { serialNumber = serial; } /** * Sets the issuer criterion. The specified distinguished name must match * the issuer distinguished name in the X509Certificate. If * null, any issuer distinguished name will do.
    *
    * If issuerDN is not null, it should contain * a distinguished name, in RFC 2253 format.
    *
    * Uses {@link org.bouncycastle.asn1.x509.X509Name X509Name} for parsing the * issuerDN. * * @param issuerDN * a distinguished name in RFC 2253 format (or null) * * @exception IOException * if a parsing error occurs (incorrect form for DN) */ public void setIssuer(String issuerDN) throws IOException { if (issuerDN == null) { this.issuerDN = null; this.issuerDNX509 = null; } else { X509Name nameX509; try { nameX509 = new X509Name(issuerDN); } catch (IllegalArgumentException ex) { throw new IOException(ex.getMessage()); } this.issuerDNX509 = nameX509; this.issuerDN = issuerDN; } } /** * Sets the issuer criterion. The specified distinguished name must match * the issuer distinguished name in the X509Certificate. If * null is specified, the issuer criterion is disabled and any issuer * distinguished name will do.
    *
    * If issuerDN is not null, it should contain * a single DER encoded distinguished name, as defined in X.501. The ASN.1 * notation for this structure is as follows.
    *
    * *
         *    Name ::= CHOICE {
         *      RDNSequence }
         * 
         *    RDNSequence ::= SEQUENCE OF RDN
         * 
         *    RDN ::=
         *      SET SIZE (1 .. MAX) OF AttributeTypeAndValue
         * 
         *    AttributeTypeAndValue ::= SEQUENCE {
         *      type     AttributeType,
         *      value    AttributeValue }
         * 
         *    AttributeType ::= OBJECT IDENTIFIER
         * 
         *    AttributeValue ::= ANY DEFINED BY AttributeType
         *    ....
         *    DirectoryString ::= CHOICE {
         *      teletexString           TeletexString (SIZE (1..MAX)),
         *      printableString         PrintableString (SIZE (1..MAX)),
         *      universalString         UniversalString (SIZE (1..MAX)),
         *      utf8String              UTF8String (SIZE (1.. MAX)),
         *      bmpString               BMPString (SIZE (1..MAX)) }
         * 
    * *
    *
    * Note that the byte array specified here is cloned to protect against * subsequent modifications.
    *
    * Uses {@link org.bouncycastle.asn1.ASN1InputStream ASN1InputStream}, * {@link org.bouncycastle.asn1.ASN1Object ASN1Object}, * {@link org.bouncycastle.asn1.ASN1Sequence ASN1Sequence}, * {@link org.bouncycastle.asn1.x509.X509Name X509Name} * * @param issuerDN - * a byte array containing the distinguished name in ASN.1 DER * encoded form (or null) * * @exception IOException * if an encoding error occurs (incorrect form for DN) */ public void setIssuer(byte[] issuerDN) throws IOException { if (issuerDN == null) { this.issuerDN = null; this.issuerDNX509 = null; } else { ByteArrayInputStream inStream = new ByteArrayInputStream(issuerDN); ASN1InputStream derInStream = new ASN1InputStream(inStream); ASN1Object obj = derInStream.readObject(); if (obj instanceof ASN1Sequence) { this.issuerDNX509 = new X509Name((ASN1Sequence)obj); } else { throw new IOException("parsing error"); } this.issuerDN = (byte[])issuerDN.clone(); } } /** * Sets the subject criterion. The specified distinguished name must match * the subject distinguished name in the X509Certificate. If * null, any subject distinguished name will do.
    *
    * If subjectDN is not null, it should * contain a distinguished name, in RFC 2253 format.
    *
    * Uses {@link org.bouncycastle.asn1.x509.X509Name X509Name} for parsing the * subjectDN. * * @param subjectDN * a distinguished name in RFC 2253 format (or null) * * @exception IOException * if a parsing error occurs (incorrect form for DN) */ public void setSubject(String subjectDN) throws IOException { if (subjectDN == null) { this.subjectDN = null; this.subjectDNX509 = null; } else { X509Name nameX509; try { nameX509 = new X509Name(subjectDN); } catch (IllegalArgumentException ex) { throw new IOException(ex.getMessage()); } this.subjectDNX509 = nameX509; this.subjectDN = subjectDN; } } /** * Sets the subject criterion. The specified distinguished name must match * the subject distinguished name in the X509Certificate. If * null, any subject distinguished name will do.
    *
    * If subjectDN is not null, it should * contain a single DER encoded distinguished name, as defined in X.501. For * the ASN.1 notation for this structure, see * {@link #setIssuer(byte []) setIssuer(byte [] issuerDN)}.
    *
    * Uses {@link org.bouncycastle.asn1.ASN1InputStream ASN1InputStream}, * {@link org.bouncycastle.asn1.ASN1Object ASN1Object}, * {@link org.bouncycastle.asn1.ASN1Sequence ASN1Sequence}, * {@link org.bouncycastle.asn1.x509.X509Name X509Name} * * @param subjectDN * a byte array containing the distinguished name in ASN.1 DER * format (or null) * * @exception IOException * if an encoding error occurs (incorrect form for DN) */ public void setSubject(byte[] subjectDN) throws IOException { if (subjectDN == null) { this.subjectDN = null; this.subjectDNX509 = null; } else { ByteArrayInputStream inStream = new ByteArrayInputStream(subjectDN); ASN1InputStream derInStream = new ASN1InputStream(inStream); ASN1Object obj = derInStream.readObject(); if (obj instanceof ASN1Sequence) { this.subjectDNX509 = new X509Name((ASN1Sequence)obj); } else { throw new IOException("parsing error"); } this.subjectDN = (byte[])subjectDN.clone(); } } /** * Sets the subjectKeyIdentifier criterion. The X509Certificate * must contain a SubjectKeyIdentifier extension for which the contents of * the extension matches the specified criterion value. If the criterion * value is null, no subjectKeyIdentifier check will be done.
    *
    * If subjectKeyID is not null, it should * contain a single DER encoded value corresponding to the contents of the * extension value (not including the object identifier, criticality * setting, and encapsulating OCTET STRING) for a SubjectKeyIdentifier * extension. The ASN.1 notation for this structure follows.
    *
    * *
         *    SubjectKeyIdentifier ::= KeyIdentifier
         * 
         *    KeyIdentifier ::= OCTET STRING
         * 
    * *
    *
    * Since the format of subject key identifiers is not mandated by any * standard, subject key identifiers are not parsed by the * X509CertSelector. Instead, the values are compared using * a byte-by-byte comparison.
    *
    * Note that the byte array supplied here is cloned to protect against * subsequent modifications. * * @param subjectKeyID - * the subject key identifier (or null) * * @see #getSubjectKeyIdentifier() */ public void setSubjectKeyIdentifier(byte[] subjectKeyID) { if (subjectKeyID == null) { this.subjectKeyID = null; } else { this.subjectKeyID = (byte[])subjectKeyID.clone(); } } /** * Sets the authorityKeyIdentifier criterion. The * X509Certificate must contain an AuthorityKeyIdentifier * extension for which the contents of the extension value matches the * specified criterion value. If the criterion value is null, * no authorityKeyIdentifier check will be done.
    *
    * If authorityKeyID is not null, it should * contain a single DER encoded value corresponding to the contents of the * extension value (not including the object identifier, criticality * setting, and encapsulating OCTET STRING) for an AuthorityKeyIdentifier * extension. The ASN.1 notation for this structure follows.
    *
    * *
         *    AuthorityKeyIdentifier ::= SEQUENCE {
         *      keyIdentifier             [0] KeyIdentifier           OPTIONAL,
         *      authorityCertIssuer       [1] GeneralNames            OPTIONAL,
         *      authorityCertSerialNumber [2] CertificateSerialNumber OPTIONAL  }
         * 
         *    KeyIdentifier ::= OCTET STRING
         * 
    * *
    *
    * Authority key identifiers are not parsed by the * X509CertSelector. Instead, the values are compared using * a byte-by-byte comparison.
    *
    * When the keyIdentifier field of * AuthorityKeyIdentifier is populated, the value is usually * taken from the SubjectKeyIdentifier extension in the issuer's * certificate. Note, however, that the result of * X509Certificate.getExtensionValue() on the issuer's certificate may NOT be used directly as the * input to setAuthorityKeyIdentifier. This is because the * SubjectKeyIdentifier contains only a KeyIdentifier OCTET STRING, and not * a SEQUENCE of KeyIdentifier, GeneralNames, and CertificateSerialNumber. * In order to use the extension value of the issuer certificate's * SubjectKeyIdentifier extension, it will be necessary to extract the value * of the embedded KeyIdentifier OCTET STRING, then DER encode this OCTET * STRING inside a SEQUENCE. For more details on SubjectKeyIdentifier, see * {@link #setSubjectKeyIdentifier(byte[]) setSubjectKeyIdentifier(byte[] subjectKeyID }).
    *
    * Note also that the byte array supplied here is cloned to protect against * subsequent modifications. * * @param authorityKeyID * the authority key identifier (or null) * * @see #getAuthorityKeyIdentifier() */ public void setAuthorityKeyIdentifier(byte[] authorityKeyID) { if (authorityKeyID == null) { this.authorityKeyID = null; } else { this.authorityKeyID = (byte[])authorityKeyID.clone(); } } /** * Sets the certificateValid criterion. The specified date must fall within * the certificate validity period for the X509Certificate. If * null, no certificateValid check will be done.
    *
    * Note that the Date supplied here is cloned to protect against subsequent * modifications. * * @param certValid * the Date to check (or null) * * @see #getCertificateValid() */ public void setCertificateValid(Date certValid) { if (certValid == null) { this.certValid = null; } else { this.certValid = new Date(certValid.getTime()); } } /** * Sets the privateKeyValid criterion. The specified date must fall within * the private key validity period for the X509Certificate. If * null, no privateKeyValid check will be done.
    *
    * Note that the Date supplied here is cloned to protect against subsequent * modifications. * * @param privateKeyValid * the Date to check (or null) * * @see #getPrivateKeyValid() */ public void setPrivateKeyValid(Date privateKeyValid) { if (privateKeyValid == null) { this.privateKeyValid = null; } else { this.privateKeyValid = new Date(privateKeyValid.getTime()); } } /** * Sets the subjectPublicKeyAlgID criterion. The X509Certificate must * contain a subject public key with the specified algorithm. If * null, no subjectPublicKeyAlgID check will be done. * * @param oid * The object identifier (OID) of the algorithm to check for (or * null). An OID is represented by a set of * nonnegative integers separated by periods. * * @exception IOException * if the OID is invalid, such as the first component being * not 0, 1 or 2 or the second component being greater than * 39. * * @see #getSubjectPublicKeyAlgID() */ public void setSubjectPublicKeyAlgID(String oid) throws IOException { CertUtil.parseOID(oid); subjectKeyAlgID = new ASN1ObjectIdentifier(oid); } /** * Sets the subjectPublicKey criterion. The X509Certificate must contain the * specified subject public key. If null, no subjectPublicKey check will be * done. * * @param key * the subject public key to check for (or null) * * @see #getSubjectPublicKey() */ public void setSubjectPublicKey(PublicKey key) { if (key == null) { subjectPublicKey = null; subjectPublicKeyByte = null; } else { subjectPublicKey = key; subjectPublicKeyByte = key.getEncoded(); } } /** * Sets the subjectPublicKey criterion. The X509Certificate * must contain the specified subject public key. If null, * no subjectPublicKey check will be done.
    *
    * Because this method allows the public key to be specified as a byte * array, it may be used for unknown key types.
    *
    * If key is not null, it should contain a single DER * encoded SubjectPublicKeyInfo structure, as defined in X.509. The ASN.1 * notation for this structure is as follows.
    *
    * *
         *    SubjectPublicKeyInfo  ::=  SEQUENCE  {
         *      algorithm            AlgorithmIdentifier,
         *      subjectPublicKey     BIT STRING  }
         * 
         *    AlgorithmIdentifier  ::=  SEQUENCE  {
         *      algorithm               OBJECT IDENTIFIER,
         *      parameters              ANY DEFINED BY algorithm OPTIONAL  }
         *                                -- contains a value of the type
         *                                -- registered for use with the
         *                                -- algorithm object identifier value
         * 
    * *
    *
    * Note that the byte array supplied here is cloned to protect against * subsequent modifications. * * @param key * a byte array containing the subject public key in ASN.1 DER * form (or null) * * @exception IOException * if an encoding error occurs (incorrect form for subject * public key) * * @see #getSubjectPublicKey() */ public void setSubjectPublicKey(byte[] key) throws IOException { if (key == null) { subjectPublicKey = null; subjectPublicKeyByte = null; } else { subjectPublicKey = null; subjectPublicKeyByte = (byte[])key.clone(); // TODO // try to generyte PublicKey Object from subjectPublicKeyByte } } /** * Sets the keyUsage criterion. The X509Certificate must allow the specified * keyUsage values. If null, no keyUsage check will be done. Note that an * X509Certificate that has no keyUsage extension implicitly allows all * keyUsage values.
    *
    * Note that the boolean array supplied here is cloned to protect against * subsequent modifications. * * @param keyUsage * a boolean array in the same format as the boolean array * returned by X509Certificate.getKeyUsage(). Or * null. * * @see #getKeyUsage() */ public void setKeyUsage(boolean[] keyUsage) { if (keyUsage == null) { this.keyUsage = null; } else { this.keyUsage = (boolean[])keyUsage.clone(); } } /** * Sets the extendedKeyUsage criterion. The X509Certificate * must allow the specified key purposes in its extended key usage * extension. If keyPurposeSet is empty or null, * no extendedKeyUsage check will be done. Note that an * X509Certificate that has no extendedKeyUsage extension * implicitly allows all key purposes.
    *
    * Note that the Set is cloned to protect against subsequent modifications.
    *
    * Uses {@link org.bouncycastle.asn1.x509.KeyPurposeId KeyPurposeId} * * @param keyPurposeSet * a Set of key purpose OIDs in string format (or * null). Each OID is represented by a set of * nonnegative integers separated by periods. * * @exception IOException * if the OID is invalid, such as the first component being * not 0, 1 or 2 or the second component being greater than * 39. * * @see #getExtendedKeyUsage() */ public void setExtendedKeyUsage(Set keyPurposeSet) throws IOException { if (keyPurposeSet == null || keyPurposeSet.isEmpty()) { this.keyPurposeSet = keyPurposeSet; } else { this.keyPurposeSet = new HashSet(); Iterator iter = keyPurposeSet.iterator(); Object obj; KeyPurposeId purposeID; while (iter.hasNext()) { obj = iter.next(); if (obj instanceof String) { purposeID = (KeyPurposeId)keyPurposeIdMap.get((String)obj); if (purposeID == null) { throw new IOException("unknown purposeID " + (String)obj); } this.keyPurposeSet.add(purposeID); } } } } /** * Enables/disables matching all of the subjectAlternativeNames specified in * the {@link #setSubjectAlternativeNames setSubjectAlternativeNames} or * {@link #addSubjectAlternativeName addSubjectAlternativeName} methods. If * enabled, the X509Certificate must contain all of the * specified subject alternative names. If disabled, the X509Certificate * must contain at least one of the specified subject alternative names.
    *
    * The matchAllNames flag is true by default. * * @param matchAllNames * if true, the flag is enabled; if * false, the flag is disabled. * * @see #getMatchAllSubjectAltNames() */ public void setMatchAllSubjectAltNames(boolean matchAllNames) { matchAllSubjectAltNames = matchAllNames; } /** * Sets the subjectAlternativeNames criterion. The * X509Certificate must contain all or at least one of the * specified subjectAlternativeNames, depending on the value of the * matchAllNames flag (see {@link #setMatchAllSubjectAltNames}).
    *
    * This method allows the caller to specify, with a single method call, the * complete set of subject alternative names for the subjectAlternativeNames * criterion. The specified value replaces the previous value for the * subjectAlternativeNames criterion.
    *
    * The names parameter (if not null) is a * Collection with one entry for each name to be included in * the subject alternative name criterion. Each entry is a List * whose first entry is an Integer (the name type, 0-8) and * whose second entry is a String or a byte array (the name, * in string or ASN.1 DER encoded form, respectively). There can be multiple * names of the same type. If null is supplied as the value * for this argument, no subjectAlternativeNames check will be performed.
    *
    * Each subject alternative name in the Collection may be * specified either as a String or as an ASN.1 encoded byte * array. For more details about the formats used, see * {@link #addSubjectAlternativeName(int, String) addSubjectAlternativeName(int type, String name)} * and * {@link #addSubjectAlternativeName(int, byte[]) addSubjectAlternativeName(int type, byte [] name}).
    *
    * Note that the names parameter can contain duplicate names * (same name and name type), but they may be removed from the * Collection of names returned by the * {@link #getSubjectAlternativeNames} method.
    *
    * Note that a deep copy is performed on the Collection to protect against * subsequent modifications. * * @param names - * a Collection of names (or null) * * @exception IOException * if a parsing error occurs * * @see #getSubjectAlternativeNames() */ public void setSubjectAlternativeNames(Collection names) throws IOException { try { if (names == null || names.isEmpty()) { subjectAltNames = null; subjectAltNamesByte = null; } else { subjectAltNames = new HashSet(); subjectAltNamesByte = new HashSet(); Iterator iter = names.iterator(); List item; int type; Object data; while (iter.hasNext()) { item = (List)iter.next(); type = ((Integer)item.get(0)).intValue(); data = item.get(1); if (data instanceof String) { addSubjectAlternativeName(type, (String)data); } else if (data instanceof byte[]) { addSubjectAlternativeName(type, (byte[])data); } else { throw new IOException( "parsing error: unknown data type"); } } } } catch (Exception ex) { throw new IOException("parsing exception:\n" + ex.toString()); } } /** * Adds a name to the subjectAlternativeNames criterion. The * X509Certificate must contain all or at least one of the * specified subjectAlternativeNames, depending on the value of the * matchAllNames flag (see {@link #setMatchAllSubjectAltNames}).
    *
    * This method allows the caller to add a name to the set of subject * alternative names. The specified name is added to any previous value for * the subjectAlternativeNames criterion. If the specified name is a * duplicate, it may be ignored.
    *
    * The name is provided in string format. RFC 822, DNS, and URI names use * the well-established string formats for those types (subject to the * restrictions included in RFC 2459). IPv4 address names are supplied using * dotted quad notation. OID address names are represented as a series of * nonnegative integers separated by periods. And directory names * (distinguished names) are supplied in RFC 2253 format. No standard string * format is defined for otherNames, X.400 names, EDI party names, IPv6 * address names, or any other type of names. They should be specified using * the * {@link #addSubjectAlternativeName(int, byte[]) addSubjectAlternativeName(int type, byte [] name)} * method. * * @param type * the name type (0-8, as specified in RFC 2459, section 4.2.1.7) * @param name - * the name in string form (not null) * * @exception IOException * if a parsing error occurs */ public void addSubjectAlternativeName(int type, String name) throws IOException { // TODO full implementation of CertUtil.parseGeneralName byte[] encoded = CertUtil.parseGeneralName(type, name); List tmpList = new ArrayList(); tmpList.add(Integers.valueOf(type)); tmpList.add(name); subjectAltNames.add(tmpList); tmpList.set(1, encoded); subjectAltNamesByte.add(tmpList); } /** * Adds a name to the subjectAlternativeNames criterion. The * X509Certificate must contain all or at least one of the * specified subjectAlternativeNames, depending on the value of the * matchAllNames flag (see {@link #setMatchAllSubjectAltNames}).
    *
    * This method allows the caller to add a name to the set of subject * alternative names. The specified name is added to any previous value for * the subjectAlternativeNames criterion. If the specified name is a * duplicate, it may be ignored.
    *
    * The name is provided as a byte array. This byte array should contain the * DER encoded name, as it would appear in the GeneralName structure defined * in RFC 2459 and X.509. The encoded byte array should only contain the * encoded value of the name, and should not include the tag associated with * the name in the GeneralName structure. The ASN.1 definition of this * structure appears below.
    *
    * *
         *    GeneralName ::= CHOICE {
         *        otherName                       [0]     OtherName,
         *        rfc822Name                      [1]     IA5String,
         *        dNSName                         [2]     IA5String,
         *        x400Address                     [3]     ORAddress,
         *        directoryName                   [4]     Name,
         *        ediPartyName                    [5]     EDIPartyName,
         *        uniformResourceIdentifier       [6]     IA5String,
         *        iPAddress                       [7]     OCTET STRING,
         *        registeredID                    [8]     OBJECT IDENTIFIER}
         * 
    * *
    *
    * Note that the byte array supplied here is cloned to protect against * subsequent modifications.
    *
    * TODO: check encoded format * * @param type * the name type (0-8, as listed above) * @param name * a byte array containing the name in ASN.1 DER encoded form * * @exception IOException * if a parsing error occurs */ public void addSubjectAlternativeName(int type, byte[] name) throws IOException { // TODO check encoded format List tmpList = new ArrayList(); tmpList.add(Integers.valueOf(type)); tmpList.add(name.clone()); subjectAltNames.add(tmpList); subjectAltNamesByte.add(tmpList); } /** * Sets the name constraints criterion. The X509Certificate * must have subject and subject alternative names that meet the specified * name constraints.
    *
    * The name constraints are specified as a byte array. This byte array * should contain the DER encoded form of the name constraints, as they * would appear in the NameConstraints structure defined in RFC 2459 and * X.509. The ASN.1 definition of this structure appears below.
    *
    * *
         *   NameConstraints ::= SEQUENCE {
         *        permittedSubtrees       [0]     GeneralSubtrees OPTIONAL,
         *        excludedSubtrees        [1]     GeneralSubtrees OPTIONAL }
         * 
         *   GeneralSubtrees ::= SEQUENCE SIZE (1..MAX) OF GeneralSubtree
         * 
         *   GeneralSubtree ::= SEQUENCE {
         *        base                    GeneralName,
         *        minimum         [0]     BaseDistance DEFAULT 0,
         *        maximum         [1]     BaseDistance OPTIONAL }
         * 
         *   BaseDistance ::= INTEGER (0..MAX)
         * 
         *   GeneralName ::= CHOICE {
         *        otherName                       [0]     OtherName,
         *        rfc822Name                      [1]     IA5String,
         *        dNSName                         [2]     IA5String,
         *        x400Address                     [3]     ORAddress,
         *        directoryName                   [4]     Name,
         *        ediPartyName                    [5]     EDIPartyName,
         *        uniformResourceIdentifier       [6]     IA5String,
         *        iPAddress                       [7]     OCTET STRING,
         *        registeredID                    [8]     OBJECT IDENTIFIER}
         * 
    * *
    *
    * Note that the byte array supplied here is cloned to protect against * subsequent modifications.
    *
    * TODO: implement this * * @param bytes * a byte array containing the ASN.1 DER encoding of a * NameConstraints extension to be used for checking name * constraints. Only the value of the extension is included, not * the OID or criticality flag. Can be null, in * which case no name constraints check will be performed * * @exception IOException * if a parsing error occurs * @exception UnsupportedOperationException * because this method is not supported * @see #getNameConstraints() */ public void setNameConstraints(byte[] bytes) throws IOException { throw new UnsupportedOperationException(); } /** * Sets the basic constraints constraint. If the value is greater than or * equal to zero, X509Certificates must include a * basicConstraints extension with a pathLen of at least this value. If the * value is -2, only end-entity certificates are accepted. If the value is * -1, no check is done.
    *
    * This constraint is useful when building a certification path forward * (from the target toward the trust anchor. If a partial path has been * built, any candidate certificate must have a maxPathLen value greater * than or equal to the number of certificates in the partial path. * * @param minMaxPathLen * the value for the basic constraints constraint * * @exception IllegalArgumentException * if the value is less than -2 * * @see #getBasicConstraints() */ public void setBasicConstraints(int minMaxPathLen) { if (minMaxPathLen < -2) { throw new IllegalArgumentException("minMaxPathLen must be >= -2"); } this.minMaxPathLen = minMaxPathLen; } /** * Sets the policy constraint. The X509Certificate must include at least one * of the specified policies in its certificate policies extension. If * certPolicySet is empty, then the X509Certificate must include at least * some specified policy in its certificate policies extension. If * certPolicySet is null, no policy check will be performed.
    *
    * Note that the Set is cloned to protect against subsequent modifications.
    *
    * TODO: implement match check for this * * @param certPolicySet * a Set of certificate policy OIDs in string format (or null). * Each OID is represented by a set of nonnegative integers * separated by periods. * * @exception IOException * if a parsing error occurs on the OID such as the first * component is not 0, 1 or 2 or the second component is * greater than 39. * * @see #getPolicy() */ public void setPolicy(Set certPolicySet) throws IOException { if (certPolicySet == null) { policy = null; policyOID = null; } else { policyOID = new HashSet(); Iterator iter = certPolicySet.iterator(); Object item; while (iter.hasNext()) { item = iter.next(); if (item instanceof String) { CertUtil.parseOID((String)item); policyOID.add(new ASN1ObjectIdentifier((String)item)); } else { throw new IOException( "certPolicySet contains null values or non String objects"); } } policy = new HashSet(certPolicySet); } } /** * Sets the pathToNames criterion. The X509Certificate must * not include name constraints that would prohibit building a path to the * specified names.
    *
    * This method allows the caller to specify, with a single method call, the * complete set of names which the X509Certificates's name * constraints must permit. The specified value replaces the previous value * for the pathToNames criterion.
    *
    * This constraint is useful when building a certification path forward * (from the target toward the trust anchor. If a partial path has been * built, any candidate certificate must not include name constraints that * would prohibit building a path to any of the names in the partial path.
    *
    * The names parameter (if not null) is a * Collection with one entry for each name to be included in * the pathToNames criterion. Each entry is a List whose * first entry is an Integer (the name type, 0-8) and whose second entry is * a String or a byte array (the name, in string or ASN.1 DER * encoded form, respectively). There can be multiple names of the same * type. If null is supplied as the value for this argument, * no pathToNames check will be performed.
    *
    * Each name in the Collection may be specified either as a String or as an * ASN.1 encoded byte array. For more details about the formats used, see * {@link #addPathToName(int, String) addPathToName(int type, String name)} * and * {@link #addPathToName(int, byte[]) addPathToName(int type, byte [] name)}.
    *
    * Note that the names parameter can contain duplicate names (same name and * name type), but they may be removed from the Collection of names returned * by the {@link #getPathToNames} method.
    *
    * Note that a deep copy is performed on the Collection to protect against * subsequent modifications.
    *
    * TODO: implement this match check for this * * @param names * a Collection with one entry per name (or null) * * @exception IOException * if a parsing error occurs * @exception UnsupportedOperationException * because this method is not supported * * @see #getPathToNames() */ public void setPathToNames(Collection names) throws IOException { try { if (names == null || names.isEmpty()) { pathToNames = null; pathToNamesByte = null; } else { pathToNames = new HashSet(); pathToNamesByte = new HashSet(); Iterator iter = names.iterator(); List item; int type; Object data; while (iter.hasNext()) { item = (List)iter.next(); type = ((Integer)item.get(0)).intValue(); data = item.get(1); if (data instanceof String) { addPathToName(type, (String)data); } else if (data instanceof byte[]) { addPathToName(type, (byte[])data); } else { throw new IOException( "parsing error: unknown data type"); } } } } catch (Exception ex) { throw new IOException("parsing exception:\n" + ex.toString()); } } /** * Adds a name to the pathToNames criterion. The * X509Certificate must not include name constraints that * would prohibit building a path to the specified name.
    *
    * This method allows the caller to add a name to the set of names which the * X509Certificates's name constraints must permit. The * specified name is added to any previous value for the pathToNames * criterion. If the name is a duplicate, it may be ignored.
    *
    * The name is provided in string format. RFC 822, DNS, and URI names use * the well-established string formats for those types (subject to the * restrictions included in RFC 2459). IPv4 address names are supplied using * dotted quad notation. OID address names are represented as a series of * nonnegative integers separated by periods. And directory names * (distinguished names) are supplied in RFC 2253 format. No standard string * format is defined for otherNames, X.400 names, EDI party names, IPv6 * address names, or any other type of names. They should be specified using * the * {@link #addPathToName(int, byte[]) addPathToName(int type, byte [] name)} * method.
    *
    * TODO: implement this match check for this * * @param type * the name type (0-8, as specified in RFC 2459, section 4.2.1.7) * @param name * the name in string form * * @exceptrion IOException if a parsing error occurs */ public void addPathToName(int type, String name) throws IOException { // TODO full implementation of CertUtil.parseGeneralName byte[] encoded = CertUtil.parseGeneralName(type, name); List tmpList = new ArrayList(); tmpList.add(Integers.valueOf(type)); tmpList.add(name); pathToNames.add(tmpList); tmpList.set(1, encoded); pathToNamesByte.add(tmpList); throw new UnsupportedOperationException(); } /** * Adds a name to the pathToNames criterion. The * X509Certificate must not include name constraints that * would prohibit building a path to the specified name.
    *
    * This method allows the caller to add a name to the set of names which the * X509Certificates's name constraints must permit. The * specified name is added to any previous value for the pathToNames * criterion. If the name is a duplicate, it may be ignored.
    *
    * The name is provided as a byte array. This byte array should contain the * DER encoded name, as it would appear in the GeneralName structure defined * in RFC 2459 and X.509. The ASN.1 definition of this structure appears in * the documentation for * {@link #addSubjectAlternativeName(int,byte[]) addSubjectAlternativeName(int type, byte[] name)}.
    *
    * Note that the byte array supplied here is cloned to protect against * subsequent modifications.
    *
    * TODO: implement this match check for this * * @param type * the name type (0-8, as specified in RFC 2459, section 4.2.1.7) * @param name * a byte array containing the name in ASN.1 DER encoded form * * @exception IOException * if a parsing error occurs */ public void addPathToName(int type, byte[] name) throws IOException { // TODO check encoded format List tmpList = new ArrayList(); tmpList.add(Integers.valueOf(type)); tmpList.add(name.clone()); pathToNames.add(tmpList); pathToNamesByte.add(tmpList); } /** * Returns the certificateEquals criterion. The specified * X509Certificate must be equal to the * X509Certificate passed to the match method. If * null, this check is not applied. * * @retrun the X509Certificate to match (or null) * * @see #setCertificate(java.security.cert.X509Certificate) */ public X509Certificate getCertificate() { return x509Cert; } /** * Returns the serialNumber criterion. The specified serial number must * match the certificate serial number in the X509Certificate. * If null, any certificate serial number will do. * * @return the certificate serial number to match (or null) * * @see #setSerialNumber(java.math.BigInteger) */ public BigInteger getSerialNumber() { return serialNumber; } /** * Returns the issuer criterion as a String. This distinguished name must * match the issuer distinguished name in the X509Certificate. * If null, the issuer criterion is disabled and any issuer * distinguished name will do.
    *
    * If the value returned is not null, it is a distinguished * name, in RFC 2253 format.
    *
    * Uses {@link org.bouncycastle.asn1.x509.X509Name X509Name} for formatiing * byte[] issuerDN to String. * * @return the required issuer distinguished name in RFC 2253 format (or * null) */ public String getIssuerAsString() { if (issuerDN instanceof String) { return new String((String)issuerDN); } else if (issuerDNX509 != null) { return issuerDNX509.toString(); } return null; } /** * Returns the issuer criterion as a byte array. This distinguished name * must match the issuer distinguished name in the * X509Certificate. If null, the issuer * criterion is disabled and any issuer distinguished name will do.
    *
    * If the value returned is not null, it is a byte array * containing a single DER encoded distinguished name, as defined in X.501. * The ASN.1 notation for this structure is supplied in the documentation * for {@link #setIssuer(byte[]) setIssuer(byte [] issuerDN)}.
    *
    * Note that the byte array returned is cloned to protect against subsequent * modifications.
    *
    * Uses {@link org.bouncycastle.asn1.DEROutputStream DEROutputStream}, * {@link org.bouncycastle.asn1.x509.X509Name X509Name} to gnerate byte[] * output for String issuerDN. * * @return a byte array containing the required issuer distinguished name in * ASN.1 DER format (or null) * * @exception IOException * if an encoding error occurs */ public byte[] getIssuerAsBytes() throws IOException { if (issuerDN instanceof byte[]) { return (byte[])((byte[])issuerDN).clone(); } else if (issuerDNX509 != null) { ByteArrayOutputStream outStream = new ByteArrayOutputStream(); DEROutputStream derOutStream = new DEROutputStream(outStream); derOutStream.writeObject(issuerDNX509.toASN1Primitive()); derOutStream.close(); return outStream.toByteArray(); } return null; } /** * Returns the subject criterion as a String. This distinguished name must * match the subject distinguished name in the X509Certificate. * If null, the subject criterion is disabled and any * subject distinguished name will do.
    *
    * If the value returned is not null, it is a distinguished * name, in RFC 2253 format.
    *
    * Uses {@link org.bouncycastle.asn1.x509.X509Name X509Name} for formatiing * byte[] subjectDN to String. * * @return the required subject distinguished name in RFC 2253 format (or * null) */ public String getSubjectAsString() { if (subjectDN instanceof String) { return new String((String)subjectDN); } else if (subjectDNX509 != null) { return subjectDNX509.toString(); } return null; } /** * Returns the subject criterion as a byte array. This distinguished name * must match the subject distinguished name in the * X509Certificate. If null, the subject * criterion is disabled and any subject distinguished name will do.
    *
    * If the value returned is not null, it is a byte array * containing a single DER encoded distinguished name, as defined in X.501. * The ASN.1 notation for this structure is supplied in the documentation * for {@link #setSubject(byte [] subjectDN) setSubject(byte [] subjectDN)}.
    *
    * Note that the byte array returned is cloned to protect against subsequent * modifications.
    *
    * Uses {@link org.bouncycastle.asn1.DEROutputStream DEROutputStream}, * {@link org.bouncycastle.asn1.x509.X509Name X509Name} to gnerate byte[] * output for String subjectDN. * * @return a byte array containing the required subject distinguished name * in ASN.1 DER format (or null) * * @exception IOException * if an encoding error occurs */ public byte[] getSubjectAsBytes() throws IOException { if (subjectDN instanceof byte[]) { return (byte[])((byte[])subjectDN).clone(); } else if (subjectDNX509 != null) { ByteArrayOutputStream outStream = new ByteArrayOutputStream(); DEROutputStream derOutStream = new DEROutputStream(outStream); derOutStream.writeObject(subjectDNX509.toASN1Primitive()); derOutStream.close(); return outStream.toByteArray(); } return null; } /** * Returns the subjectKeyIdentifier criterion. The * X509Certificate must contain a SubjectKeyIdentifier * extension with the specified value. If null, no * subjectKeyIdentifier check will be done.
    *
    * Note that the byte array returned is cloned to protect against subsequent * modifications. * * @return the key identifier (or null) * * @see #setSubjectKeyIdentifier */ public byte[] getSubjectKeyIdentifier() { if (subjectKeyID != null) { return (byte[])subjectKeyID.clone(); } return null; } /** * Returns the authorityKeyIdentifier criterion. The * X509Certificate must contain a AuthorityKeyIdentifier * extension with the specified value. If null, no * authorityKeyIdentifier check will be done.
    *
    * Note that the byte array returned is cloned to protect against subsequent * modifications. * * @return the key identifier (or null) * * @see #setAuthorityKeyIdentifier */ public byte[] getAuthorityKeyIdentifier() { if (authorityKeyID != null) { return (byte[])authorityKeyID.clone(); } return null; } /** * Returns the certificateValid criterion. The specified date must fall * within the certificate validity period for the * X509Certificate. If null, no * certificateValid check will be done.
    *
    * Note that the Date returned is cloned to protect against * subsequent modifications. * * @return the Date to check (or null) * * @see #setCertificateValid */ public Date getCertificateValid() { if (certValid != null) { return new Date(certValid.getTime()); } return null; } /** * Returns the privateKeyValid criterion. The specified date must fall * within the private key validity period for the * X509Certificate. If null, no * privateKeyValid check will be done.
    *
    * Note that the Date returned is cloned to protect against * subsequent modifications. * * @return the Date to check (or null) * * @see #setPrivateKeyValid */ public Date getPrivateKeyValid() { if (privateKeyValid != null) { return new Date(privateKeyValid.getTime()); } return null; } /** * Returns the subjectPublicKeyAlgID criterion. The * X509Certificate must contain a subject public key with the * specified algorithm. If null, no subjectPublicKeyAlgID * check will be done. * * @return the object identifier (OID) of the signature algorithm to check * for (or null). An OID is represented by a set of * nonnegative integers separated by periods. * * @see #setSubjectPublicKeyAlgID */ public String getSubjectPublicKeyAlgID() { if (subjectKeyAlgID != null) { return subjectKeyAlgID.toString(); } return null; } /** * Returns the subjectPublicKey criterion. The X509Certificate * must contain the specified subject public key. If null, * no subjectPublicKey check will be done. * * @return the subject public key to check for (or null) * * @see #setSubjectPublicKey */ public PublicKey getSubjectPublicKey() { return subjectPublicKey; } /** * Returns the keyUsage criterion. The X509Certificate must * allow the specified keyUsage values. If null, no keyUsage check will be * done.
    *
    * Note that the boolean array returned is cloned to protect against * subsequent modifications. * * @return a boolean array in the same format as the boolean array returned * by * {@link X509Certificate#getKeyUsage() X509Certificate.getKeyUsage()}. * Or null. * * @see #setKeyUsage */ public boolean[] getKeyUsage() { if (keyUsage != null) { return (boolean[])keyUsage.clone(); } return null; } /** * Returns the extendedKeyUsage criterion. The X509Certificate * must allow the specified key purposes in its extended key usage * extension. If the keyPurposeSet returned is empty or * null, no extendedKeyUsage check will be done. Note that * an X509Certificate that has no extendedKeyUsage extension * implicitly allows all key purposes. * * @return an immutable Set of key purpose OIDs in string * format (or null) * @see #setExtendedKeyUsage */ public Set getExtendedKeyUsage() { if (keyPurposeSet == null || keyPurposeSet.isEmpty()) { return keyPurposeSet; } Set returnSet = new HashSet(); Iterator iter = keyPurposeSet.iterator(); while (iter.hasNext()) { returnSet.add(iter.next().toString()); } return Collections.unmodifiableSet(returnSet); } /** * Indicates if the X509Certificate must contain all or at * least one of the subjectAlternativeNames specified in the * {@link #setSubjectAlternativeNames setSubjectAlternativeNames} or * {@link #addSubjectAlternativeName addSubjectAlternativeName} methods. If * true, the X509Certificate must contain all * of the specified subject alternative names. If false, the * X509Certificate must contain at least one of the specified * subject alternative names. * * @return true if the flag is enabled; false * if the flag is disabled. The flag is true by * default. * * @see #setMatchAllSubjectAltNames */ public boolean getMatchAllSubjectAltNames() { return matchAllSubjectAltNames; } /** * Returns a copy of the subjectAlternativeNames criterion. The * X509Certificate must contain all or at least one of the * specified subjectAlternativeNames, depending on the value of the * matchAllNames flag (see {@link #getMatchAllSubjectAltNames * getMatchAllSubjectAltNames}). If the value returned is null, * no subjectAlternativeNames check will be performed.
    *
    * If the value returned is not null, it is a * Collection with one entry for each name to be included in * the subject alternative name criterion. Each entry is a List * whose first entry is an Integer (the name type, 0-8) and * whose second entry is a String or a byte array (the name, * in string or ASN.1 DER encoded form, respectively). There can be multiple * names of the same type. Note that the Collection returned * may contain duplicate names (same name and name type).
    *
    * Each subject alternative name in the Collection may be * specified either as a String or as an ASN.1 encoded byte * array. For more details about the formats used, see * {@link #addSubjectAlternativeName(int type, String name) * addSubjectAlternativeName(int type, String name)} and * {@link #addSubjectAlternativeName(int type, byte [] name) * addSubjectAlternativeName(int type, byte [] name)}.
    *
    * Note that a deep copy is performed on the Collection to * protect against subsequent modifications. * * @return a Collection of names (or null) * * @see #setSubjectAlternativeNames */ public Collection getSubjectAlternativeNames() { if (subjectAltNames != null) { return null; } Set returnAltNames = new HashSet(); List returnList; Iterator iter = subjectAltNames.iterator(); List obj; while (iter.hasNext()) { obj = (List)iter.next(); returnList = new ArrayList(); returnList.add(obj.get(0)); if (obj.get(1) instanceof byte[]) { returnList.add(((byte[])obj.get(1)).clone()); } else { returnList.add(obj.get(1)); } returnAltNames.add(returnList); } return returnAltNames; } /** * Returns the name constraints criterion. The X509Certificate * must have subject and subject alternative names that meet the specified * name constraints.
    *
    * The name constraints are returned as a byte array. This byte array * contains the DER encoded form of the name constraints, as they would * appear in the NameConstraints structure defined in RFC 2459 and X.509. * The ASN.1 notation for this structure is supplied in the documentation * for * {@link #setNameConstraints(byte [] bytes) setNameConstraints(byte [] bytes)}.
    *
    * Note that the byte array returned is cloned to protect against subsequent * modifications.
    *
    * TODO: implement this * * @return a byte array containing the ASN.1 DER encoding of a * NameConstraints extension used for checking name constraints. * null if no name constraints check will be * performed. * * @exception UnsupportedOperationException * because this method is not supported * * @see #setNameConstraints */ public byte[] getNameConstraints() { throw new UnsupportedOperationException(); } /** * Returns the basic constraints constraint. If the value is greater than or * equal to zero, the X509Certificates must include a * basicConstraints extension with a pathLen of at least this value. If the * value is -2, only end-entity certificates are accepted. If the value is * -1, no basicConstraints check is done. * * @return the value for the basic constraints constraint * * @see #setBasicConstraints */ public int getBasicConstraints() { return minMaxPathLen; } /** * Returns the policy criterion. The X509Certificate must * include at least one of the specified policies in its certificate * policies extension. If the Set returned is empty, then the * X509Certificate must include at least some specified * policy in its certificate policies extension. If the Set * returned is null, no policy check will be performed. * * @return an immutable Set of certificate policy OIDs in * string format (or null) * * @see #setPolicy */ public Set getPolicy() { if (policy == null) { return null; } return Collections.unmodifiableSet(policy); } /** * Returns a copy of the pathToNames criterion. The * X509Certificate must not include name constraints that * would prohibit building a path to the specified names. If the value * returned is null, no pathToNames check will be performed.
    *
    * If the value returned is not null, it is a * Collection with one entry for each name to be included in * the pathToNames criterion. Each entry is a List whose * first entry is an Integer (the name type, 0-8) and whose * second entry is a String or a byte array (the name, in * string or ASN.1 DER encoded form, respectively). There can be multiple * names of the same type. Note that the Collection returned * may contain duplicate names (same name and name type).
    *
    * Each name in the Collection may be specified either as a * String or as an ASN.1 encoded byte array. For more details * about the formats used, see {@link #addPathToName(int type, String name) * addPathToName(int type, String name)} and * {@link #addPathToName(int type, byte [] name) addPathToName(int type, * byte [] name)}.
    *
    * Note that a deep copy is performed on the Collection to * protect against subsequent modifications. * * @return a Collection of names (or null) * * @see #setPathToNames */ public Collection getPathToNames() { if (pathToNames == null) { return null; } Set returnPathToNames = new HashSet(); List returnList; Iterator iter = pathToNames.iterator(); List obj; while (iter.hasNext()) { obj = (List)iter.next(); returnList = new ArrayList(); returnList.add(obj.get(0)); if (obj.get(1) instanceof byte[]) { returnList.add(((byte[])obj.get(1)).clone()); } else { returnList.add(obj.get(1)); } returnPathToNames.add(returnList); } return returnPathToNames; } /** * Return a printable representation of the CertSelector.
    *
    * TODO: implement output for currently unsupported options(name * constraints)
    *
    * Uses {@link org.bouncycastle.asn1.ASN1InputStream ASN1InputStream}, * {@link org.bouncycastle.asn1.ASN1Object ASN1Object}, * {@link org.bouncycastle.asn1.x509.KeyPurposeId KeyPurposeId} * * @return a String describing the contents of the * CertSelector */ public String toString() { StringBuffer sb = new StringBuffer(); sb.append("X509CertSelector: [\n"); if (x509Cert != null) { sb.append(" Certificate: ").append(x509Cert).append('\n'); } if (serialNumber != null) { sb.append(" Serial Number: ").append(serialNumber).append('\n'); } if (issuerDN != null) { sb.append(" Issuer: ").append(getIssuerAsString()).append('\n'); } if (subjectDN != null) { sb.append(" Subject: ").append(getSubjectAsString()).append('\n'); } try { if (subjectKeyID != null) { ByteArrayInputStream inStream = new ByteArrayInputStream( subjectKeyID); ASN1InputStream derInStream = new ASN1InputStream(inStream); ASN1Object derObject = derInStream.readObject(); sb.append(" Subject Key Identifier: ") .append(ASN1Dump.dumpAsString(derObject)).append('\n'); } if (authorityKeyID != null) { ByteArrayInputStream inStream = new ByteArrayInputStream( authorityKeyID); ASN1InputStream derInStream = new ASN1InputStream(inStream); ASN1Object derObject = derInStream.readObject(); sb.append(" Authority Key Identifier: ") .append(ASN1Dump.dumpAsString(derObject)).append('\n'); } } catch (IOException ex) { sb.append(ex.getMessage()).append('\n'); } if (certValid != null) { sb.append(" Certificate Valid: ").append(certValid).append('\n'); } if (privateKeyValid != null) { sb.append(" Private Key Valid: ").append(privateKeyValid) .append('\n'); } if (subjectKeyAlgID != null) { sb.append(" Subject Public Key AlgID: ") .append(subjectKeyAlgID).append('\n'); } if (subjectPublicKey != null) { sb.append(" Subject Public Key: ").append(subjectPublicKey) .append('\n'); } if (keyUsage != null) { sb.append(" Key Usage: ").append(keyUsage).append('\n'); } if (keyPurposeSet != null) { sb.append(" Extended Key Usage: ").append(keyPurposeSet) .append('\n'); } if (policy != null) { sb.append(" Policy: ").append(policy).append('\n'); } sb.append(" matchAllSubjectAltNames flag: ") .append(matchAllSubjectAltNames).append('\n'); if (subjectAltNamesByte != null) { sb.append(" SubjectAlternativNames: \n["); Iterator iter = subjectAltNamesByte.iterator(); List obj; try { while (iter.hasNext()) { obj = (List)iter.next(); ByteArrayInputStream inStream = new ByteArrayInputStream( (byte[])obj.get(1)); ASN1InputStream derInStream = new ASN1InputStream(inStream); ASN1Object derObject = derInStream.readObject(); sb.append(" Type: ").append(obj.get(0)).append(" Data: ") .append(ASN1Dump.dumpAsString(derObject)).append('\n'); } } catch (IOException ex) { sb.append(ex.getMessage()).append('\n'); } sb.append("]\n"); } if (pathToNamesByte != null) { sb.append(" PathToNamesNames: \n["); Iterator iter = pathToNamesByte.iterator(); List obj; try { while (iter.hasNext()) { obj = (List)iter.next(); ByteArrayInputStream inStream = new ByteArrayInputStream( (byte[])obj.get(1)); ASN1InputStream derInStream = new ASN1InputStream(inStream); ASN1Object derObject = derInStream.readObject(); sb.append(" Type: ").append(obj.get(0)).append(" Data: ") .append(ASN1Dump.dumpAsString(derObject)).append('\n'); } } catch (IOException ex) { sb.append(ex.getMessage()).append('\n'); } sb.append("]\n"); } sb.append(']'); return sb.toString(); } /** * Decides whether a Certificate should be selected.
    *
    * TODO: implement missing tests (name constraints and path to names)
    *
    * Uses {@link org.bouncycastle.asn1.ASN1InputStream ASN1InputStream}, * {@link org.bouncycastle.asn1.ASN1Sequence ASN1Sequence}, * {@link org.bouncycastle.asn1.ASN1ObjectIdentifier ASN1ObjectIdentifier}, * {@link org.bouncycastle.asn1.ASN1Object ASN1Object}, * {@link org.bouncycastle.asn1.DERGeneralizedTime DERGeneralizedTime}, * {@link org.bouncycastle.asn1.x509.X509Name X509Name}, * {@link org.bouncycastle.asn1.x509.X509Extensions X509Extensions}, * {@link org.bouncycastle.asn1.x509.ExtendedKeyUsage ExtendedKeyUsage}, * {@link org.bouncycastle.asn1.x509.KeyPurposeId KeyPurposeId}, * {@link org.bouncycastle.asn1.x509.SubjectPublicKeyInfo SubjectPublicKeyInfo}, * {@link org.bouncycastle.asn1.x509.AlgorithmIdentifier AlgorithmIdentifier} * to access X509 extensions * * @param cert * the Certificate to be checked * * @return true if the Certificate should be * selected, false otherwise */ public boolean match(Certificate cert) { boolean[] booleanArray; List tempList; Iterator tempIter; if (!(cert instanceof X509Certificate)) { return false; } X509Certificate certX509 = (X509Certificate)cert; if (x509Cert != null && !x509Cert.equals(certX509)) { return false; } if (serialNumber != null && !serialNumber.equals(certX509.getSerialNumber())) { return false; } try { if (issuerDNX509 != null) { if (!issuerDNX509.equals(PrincipalUtil .getIssuerX509Principal(certX509), true)) { return false; } } if (subjectDNX509 != null) { if (!subjectDNX509.equals(PrincipalUtil .getSubjectX509Principal(certX509), true)) { return false; } } } catch (Exception ex) { return false; } if (subjectKeyID != null) { byte[] data = certX509 .getExtensionValue(X509Extensions.SubjectKeyIdentifier .getId()); if (data == null) { return false; } try { ByteArrayInputStream inStream = new ByteArrayInputStream(data); ASN1InputStream derInputStream = new ASN1InputStream(inStream); byte[] testData = ((ASN1OctetString)derInputStream.readObject()) .getOctets(); if (!Arrays.equals(subjectKeyID, testData)) { return false; } } catch (IOException ex) { return false; } } if (authorityKeyID != null) { byte[] data = certX509 .getExtensionValue(X509Extensions.AuthorityKeyIdentifier .getId()); if (data == null) { return false; } try { ByteArrayInputStream inStream = new ByteArrayInputStream(data); ASN1InputStream derInputStream = new ASN1InputStream(inStream); byte[] testData = ((ASN1OctetString)derInputStream.readObject()) .getOctets(); if (!Arrays.equals(authorityKeyID, testData)) { return false; } } catch (IOException ex) { return false; } } if (certValid != null) { if (certX509.getNotAfter() != null && certValid.after(certX509.getNotAfter())) { return false; } if (certX509.getNotBefore() != null && certValid.before(certX509.getNotBefore())) { return false; } } if (privateKeyValid != null) { try { byte[] data = certX509 .getExtensionValue(X509Extensions.PrivateKeyUsagePeriod .getId()); if (data != null) { ByteArrayInputStream inStream = new ByteArrayInputStream( data); ASN1InputStream derInputStream = new ASN1InputStream(inStream); inStream = new ByteArrayInputStream( ((ASN1OctetString)derInputStream.readObject()) .getOctets()); derInputStream = new ASN1InputStream(inStream); // TODO fix this, Sequence contains tagged objects ASN1Sequence derObject = (ASN1Sequence)derInputStream .readObject(); DERGeneralizedTime derDate = DERGeneralizedTime .getInstance(derObject.getObjectAt(0)); SimpleDateFormat dateF = new SimpleDateFormat( "yyyyMMddHHmmssZ"); if (privateKeyValid.before(dateF.parse(derDate.getTime()))) { return false; } derDate = DERGeneralizedTime.getInstance(derObject .getObjectAt(1)); if (privateKeyValid.after(dateF.parse(derDate.getTime()))) { return false; } } } catch (Exception ex) { return false; } } if (subjectKeyAlgID != null) { try { ByteArrayInputStream inStream = new ByteArrayInputStream( certX509.getPublicKey().getEncoded()); ASN1InputStream derInputStream = new ASN1InputStream(inStream); SubjectPublicKeyInfo publicKeyInfo = new SubjectPublicKeyInfo( (ASN1Sequence)derInputStream.readObject()); AlgorithmIdentifier algInfo = publicKeyInfo.getAlgorithmId(); if (!algInfo.getObjectId().equals(subjectKeyAlgID)) { return false; } } catch (Exception ex) { return false; } } if (subjectPublicKeyByte != null) { if (!Arrays.equals(subjectPublicKeyByte, certX509.getPublicKey() .getEncoded())) { return false; } } if (subjectPublicKey != null) { if (!subjectPublicKey.equals(certX509.getPublicKey())) { return false; } } if (keyUsage != null) { booleanArray = certX509.getKeyUsage(); if (booleanArray != null) { for (int i = 0; i < keyUsage.length; i++) { if (keyUsage[i] && (booleanArray.length <= i || !booleanArray[i])) { return false; } } } } if (keyPurposeSet != null && !keyPurposeSet.isEmpty()) { try { byte[] data = certX509 .getExtensionValue(X509Extensions.ExtendedKeyUsage .getId()); if (data != null) { ByteArrayInputStream inStream = new ByteArrayInputStream( data); ASN1InputStream derInputStream = new ASN1InputStream(inStream); ExtendedKeyUsage extendedKeyUsage = ExtendedKeyUsage.getInstance( (ASN1Sequence)derInputStream.readObject()); tempIter = keyPurposeSet.iterator(); while (tempIter.hasNext()) { if (!extendedKeyUsage .hasKeyPurposeId((KeyPurposeId)tempIter.next())) { return false; } } } } catch (Exception ex) { return false; } } if (minMaxPathLen != -1) { if (minMaxPathLen == -2 && certX509.getBasicConstraints() != -1) { return false; } if (minMaxPathLen >= 0 && certX509.getBasicConstraints() < minMaxPathLen) { return false; } } if (policyOID != null) { try { byte[] data = certX509 .getExtensionValue(X509Extensions.CertificatePolicies .getId()); if (data == null) { return false; } if (!policyOID.isEmpty()) { ByteArrayInputStream inStream = new ByteArrayInputStream( data); ASN1InputStream derInputStream = new ASN1InputStream(inStream); inStream = new ByteArrayInputStream( ((ASN1OctetString)derInputStream.readObject()) .getOctets()); derInputStream = new ASN1InputStream(inStream); Enumeration policySequence = ((ASN1Sequence)derInputStream .readObject()).getObjects(); ASN1Sequence policyObject; boolean test = false; while (policySequence.hasMoreElements() && !test) { policyObject = (ASN1Sequence)policySequence .nextElement(); if (policyOID.contains(policyObject.getObjectAt(0))) { test = true; } } if (!test) { return false; } } } catch (Exception ex) { ex.printStackTrace(); return false; } } if (subjectAltNamesByte != null) { try { byte[] data = certX509 .getExtensionValue(X509Extensions.SubjectAlternativeName .getId()); if (data == null) { return false; } ByteArrayInputStream inStream = new ByteArrayInputStream(data); ASN1InputStream derInputStream = new ASN1InputStream(inStream); inStream = new ByteArrayInputStream( ((ASN1OctetString)derInputStream.readObject()) .getOctets()); derInputStream = new ASN1InputStream(inStream); Enumeration altNamesSequence = ((ASN1Sequence)derInputStream .readObject()).getObjects(); ASN1TaggedObject altNameObject; boolean test = false; Set testSet = new HashSet(subjectAltNamesByte); List testList; ASN1Object derData; ByteArrayOutputStream outStream; DEROutputStream derOutStream; while (altNamesSequence.hasMoreElements() && !test) { altNameObject = (ASN1TaggedObject)altNamesSequence .nextElement(); testList = new ArrayList(2); testList.add(Integers.valueOf(altNameObject.getTagNo())); derData = altNameObject.getObject(); outStream = new ByteArrayOutputStream(); derOutStream = new DEROutputStream(outStream); derOutStream.writeObject(derData); derOutStream.close(); testList.add(outStream.toByteArray()); if (testSet.remove(testList)) { test = true; } if (matchAllSubjectAltNames && !testSet.isEmpty()) { test = false; } } if (!test) { return false; } } catch (Exception ex) { ex.printStackTrace(); return false; } } return true; } /** * Returns a copy of this object. * * @return the copy */ public Object clone() { try { X509CertSelector copy = (X509CertSelector)super.clone(); if (issuerDN instanceof byte[]) { copy.issuerDN = ((byte[])issuerDN).clone(); } if (subjectDN instanceof byte[]) { copy.subjectDN = ((byte[])subjectDN).clone(); } if (subjectKeyID != null) { copy.subjectKeyID = (byte[])subjectKeyID.clone(); } if (authorityKeyID != null) { copy.authorityKeyID = (byte[])authorityKeyID.clone(); } if (subjectPublicKeyByte != null) { copy.subjectPublicKeyByte = (byte[])subjectPublicKeyByte .clone(); } if (keyUsage != null) { copy.keyUsage = (boolean[])keyUsage.clone(); } if (keyPurposeSet != null) { copy.keyPurposeSet = new HashSet(keyPurposeSet); } if (policy != null) { copy.policy = new HashSet(policy); copy.policyOID = new HashSet(); Iterator iter = policyOID.iterator(); while (iter.hasNext()) { copy.policyOID.add(new ASN1ObjectIdentifier( ((ASN1ObjectIdentifier)iter.next()).getId())); } } if (subjectAltNames != null) { copy.subjectAltNames = new HashSet(getSubjectAlternativeNames()); Iterator iter = subjectAltNamesByte.iterator(); List obj; List cloneObj; while (iter.hasNext()) { obj = (List)iter.next(); cloneObj = new ArrayList(); cloneObj.add(obj.get(0)); cloneObj.add(((byte[])obj.get(1)).clone()); copy.subjectAltNamesByte.add(cloneObj); } } if (pathToNames != null) { copy.pathToNames = new HashSet(getPathToNames()); Iterator iter = pathToNamesByte.iterator(); List obj; List cloneObj; while (iter.hasNext()) { obj = (List)iter.next(); cloneObj = new ArrayList(); cloneObj.add(obj.get(0)); cloneObj.add(((byte[])obj.get(1)).clone()); copy.pathToNamesByte.add(cloneObj); } } return copy; } catch (CloneNotSupportedException e) { /* Cannot happen */ throw new InternalError(e.toString()); } } } bouncycastle-1.49.orig/jdk1.1/java/security/cert/PolicyNode.java0000644000175000017500000000776511705654526024110 0ustar ebourgebourgpackage java.security.cert; import java.util.Iterator; import java.util.Set; /** * An immutable valid policy tree node as defined by the PKIX certification * path validation algorithm.
    *
    * One of the outputs of the PKIX certification path validation * algorithm is a valid policy tree, which includes the policies that * were determined to be valid, how this determination was reached, * and any policy qualifiers encountered. This tree is of depth * n, where n is the length of the certification * path that has been validated.
    *
    * Most applications will not need to examine the valid policy tree. * They can achieve their policy processing goals by setting the * policy-related parameters in PKIXParameters. However, * the valid policy tree is available for more sophisticated applications, * especially those that process policy qualifiers.
    *
    * {@link PKIXCertPathValidatorResult#getPolicyTree() * PKIXCertPathValidatorResult.getPolicyTree} returns the root node of the * valid policy tree. The tree can be traversed using the * {@link #getChildren getChildren} and {@link #getParent getParent} methods. * Data about a particular node can be retrieved using other methods of * PolicyNode.
    *
    * Concurrent Access
    *
    * All PolicyNode objects must be immutable and * thread-safe. Multiple threads may concurrently invoke the methods defined * in this class on a single PolicyNode object (or more than one) * with no ill effects. This stipulation applies to all public fields and * methods of this class and any added or overridden by subclasses. **/ public interface PolicyNode { /** * Returns the parent of this node, or null if this is the * root node. * * @return the parent of this node, or null if this is the * root node */ public PolicyNode getParent(); /** * Returns an iterator over the children of this node. Any attempts to * modify the children of this node through the * Iterator's remove method must throw an * UnsupportedOperationException. * * @return an iterator over the children of this node */ public Iterator getChildren(); /** * Returns the depth of this node in the valid policy tree. * * @return the depth of this node (0 for the root node, 1 for its * children, and so on) */ public int getDepth(); /** * Returns the valid policy represented by this node. * * @return the String OID of the valid policy * represented by this node, or the special value "any-policy". For * the root node, this method always returns the special value "any-policy". */ public String getValidPolicy(); /** * Returns the set of policy qualifiers associated with the * valid policy represented by this node. * * @return an immutable Set of * PolicyQualifierInfos. For the root node, this * is always an empty Set. */ public Set getPolicyQualifiers(); /** * Returns the set of expected policies that would satisfy this * node's valid policy in the next certificate to be processed. * * @return an immutable Set of expected policy * String OIDs, or an immutable Set with * the single special value "any-policy". For the root node, this method * always returns a Set with the single value "any-policy". */ public Set getExpectedPolicies(); /** * Returns the criticality indicator of the certificate policy extension * in the most recently processed certificate. * * @return true if extension marked critical, * false otherwise. For the root node, false * is always returned. */ public boolean isCritical(); } bouncycastle-1.49.orig/jdk1.1/java/security/cert/CertPathBuilderException.java0000644000175000017500000001216211705654526026726 0ustar ebourgebourgpackage java.security.cert; import java.io.PrintStream; import java.io.PrintWriter; import java.security.GeneralSecurityException; /** * An exception indicating one of a variety of problems encountered * when building a certification path with a * CertPathBuilder.
    *
    * A CertPathBuilderException provides support for * wrapping exceptions. The {@link #getCause() getCause} method * returns the throwable, if any, that caused this exception to be * thrown.
    *
    * Concurrent Access
    *
    * Unless otherwise specified, the methods defined in this class are * not thread-safe. Multiple threads that need to access a single * object concurrently should synchronize amongst themselves and * provide the necessary locking. Multiple threads each manipulating * separate objects need not synchronize. * * @see CertPathBuilder **/ public class CertPathBuilderException extends GeneralSecurityException { private Throwable cause; /** * Creates a CertPathBuilderException with null * as its detail message. */ public CertPathBuilderException() { } /** * Creates a CertPathBuilderException with the given detail * message. The detail message is a String that describes * this particular exception in more detail. * * @param msg * the detail message */ public CertPathBuilderException(String message) { super(message); } /** * Creates a CertPathBuilderException that wraps the * specified throwable. This allows any exception to be converted into a * CertPathBuilderException, while retaining information * about the wrapped exception, which may be useful for debugging. The * detail message is set to * (cause==null ? null : cause.toString()) (which typically * contains the class and detail message of cause). * * @param cause * the cause (which is saved for later retrieval by the * {@link #getCause()} method). (A null value is permitted, and * indicates that the cause is nonexistent or unknown.) */ public CertPathBuilderException(String message, Throwable cause) { super(message); this.cause = cause; } /** * Creates a CertPathBuilderException with the specified * detail message and cause. * * @param msg * the detail message * @param cause * the cause (which is saved for later retrieval by the * {@link #getCause()} method). (A null value is permitted, and * indicates that the cause is nonexistent or unknown.) */ public CertPathBuilderException(Throwable cause) { this.cause = cause; } /** * Returns the internal (wrapped) cause, or null if the cause is nonexistent * or unknown. * * @return the cause of this throwable or null if the cause * is nonexistent or unknown. */ public Throwable getCause() { return cause; } /** * Returns the detail message for this CertPathBuilderException. * * @return the detail message, or null if neither the message * nor internal cause were specified */ public String getMessage() { String message = super.getMessage(); if (message == null && cause == null) { return null; } if (cause != null) { return cause.getMessage(); } return message; } /** * Returns a string describing this exception, including a description of * the internal (wrapped) cause if there is one. * * @return a string representation of this * CertPathBuilderException */ public String toString() { String message = getMessage(); if (message == null) { return ""; } return message; } /** * Prints a stack trace to System.err, including the * backtrace of the cause, if any. */ public void printStackTrace() { printStackTrace(System.err); } /** * Prints a stack trace to a PrintStream, including the * backtrace of the cause, if any. * * @param ps * the PrintStream to use for output */ public void printStackTrace(PrintStream ps) { super.printStackTrace(ps); if (getCause() != null) { getCause().printStackTrace(ps); } } /** * Prints a stack trace to a PrintWriter, including the * backtrace of the cause, if any. * * @param ps * the PrintWriter to use for output */ public void printStackTrace(PrintWriter pw) { super.printStackTrace(pw); if (getCause() != null) { getCause().printStackTrace(pw); } } } bouncycastle-1.49.orig/jdk1.1/java/security/cert/Certificate.java0000644000175000017500000000354511705654526024255 0ustar ebourgebourg package java.security.cert; import java.security.InvalidKeyException; import java.security.MessageDigest; import java.security.NoSuchAlgorithmException; import java.security.NoSuchProviderException; import java.security.PublicKey; import java.security.SignatureException; public abstract class Certificate extends Object { private String type; protected Certificate(String type) { this.type = type; } public boolean equals(Object other) { if ( !(other instanceof Certificate) ) return false; if ( other == this ) return true; try { byte[] enc1 = getEncoded(); byte[] enc2 = ((Certificate)other).getEncoded(); return MessageDigest.isEqual(enc1, enc2); } catch (CertificateEncodingException e) { return false; } } public final String getType() { return type; } // XXX public int hashCode() { try { byte[] enc1 = getEncoded(); int hc = 0; for (int i = 0; i < enc1.length; i++) { hc += enc1[i]; } return hc; } catch (CertificateEncodingException e) { return 0; } } public abstract byte[] getEncoded() throws CertificateEncodingException; public abstract PublicKey getPublicKey(); public abstract String toString(); public abstract void verify(PublicKey key) throws CertificateException, NoSuchAlgorithmException, InvalidKeyException, NoSuchProviderException, SignatureException; public abstract void verify(PublicKey key, String sigProvider) throws CertificateException, NoSuchAlgorithmException, InvalidKeyException, NoSuchProviderException, SignatureException; } bouncycastle-1.49.orig/jdk1.1/java/security/cert/X509CRLEntry.java0000644000175000017500000000234011705654526024053 0ustar ebourgebourg package java.security.cert; import java.math.BigInteger; import java.security.MessageDigest; import java.util.Date; public abstract class X509CRLEntry implements X509Extension { public boolean equals(Object other) { if ( this == other ) return true; if ( !(other instanceof X509CRLEntry) ) return false; try { byte[] enc1 = getEncoded(); byte[] enc2 = ((X509CRLEntry)other).getEncoded(); return MessageDigest.isEqual(enc1, enc2); } catch (CRLException e) { return false; } } public int hashCode() { int hashcode = 0; try { byte[] encoded = getEncoded(); for (int i = 1; i < encoded.length; i++) { hashcode += encoded[i] * i; } } catch (CRLException ce) { return(hashcode); } return(hashcode); } public abstract byte[] getEncoded() throws CRLException; public abstract Date getRevocationDate(); public abstract BigInteger getSerialNumber(); public abstract boolean hasExtensions(); public abstract String toString(); } bouncycastle-1.49.orig/jdk1.1/java/security/cert/PKIXCertPathChecker.java0000644000175000017500000001570411705654526025526 0ustar ebourgebourgpackage java.security.cert; import java.util.Collection; import java.util.Set; /** * An abstract class that performs one or more checks on an * X509Certificate.
    *
    * A concrete implementation of the PKIXCertPathChecker class * can be created to extend the PKIX certification path validation algorithm. * For example, an implementation may check for and process a critical private * extension of each certificate in a certification path.
    *
    * Instances of PKIXCertPathChecker are passed as parameters * using the {@link PKIXParameters#setCertPathCheckers setCertPathCheckers} * or {@link PKIXParameters#addCertPathChecker addCertPathChecker} methods * of the PKIXParameters and PKIXBuilderParameters * class. Each of the PKIXCertPathCheckers {@link #check check} * methods will be called, in turn, for each certificate processed by a PKIX * CertPathValidator or CertPathBuilder * implementation.
    *
    * A PKIXCertPathChecker may be called multiple times on * successive certificates in a certification path. Concrete subclasses * are expected to maintain any internal state that may be necessary to * check successive certificates. The {@link #init init} method is used * to initialize the internal state of the checker so that the certificates * of a new certification path may be checked. A stateful implementation * must override the {@link #clone clone} method if necessary in * order to allow a PKIX CertPathBuilder to efficiently * backtrack and try other paths. In these situations, the * CertPathBuilder is able to restore prior path validation * states by restoring the cloned PKIXCertPathCheckers.
    *
    * The order in which the certificates are presented to the * PKIXCertPathChecker may be either in the forward direction * (from target to most-trusted CA) or in the reverse direction (from * most-trusted CA to target). A PKIXCertPathChecker implementation * must support reverse checking (the ability to perform its checks when * it is presented with certificates in the reverse direction) and may * support forward checking (the ability to perform its checks when it is * presented with certificates in the forward direction). The * {@link #isForwardCheckingSupported isForwardCheckingSupported} method * indicates whether forward checking is supported.
    *
    * Additional input parameters required for executing the check may be * specified through constructors of concrete implementations of this class.
    *
    * Concurrent Access
    *
    * Unless otherwise specified, the methods defined in this class are not * thread-safe. Multiple threads that need to access a single * object concurrently should synchronize amongst themselves and * provide the necessary locking. Multiple threads each manipulating * separate objects need not synchronize. * * @see PKIXParameters * @see PKIXBuilderParameters **/ public abstract class PKIXCertPathChecker implements Cloneable { /** * Default constructor. */ protected PKIXCertPathChecker() {} /** * Initializes the internal state of this PKIXCertPathChecker. *

    * The forward flag specifies the order that * certificates will be passed to the {@link #check check} method * (forward or reverse). A PKIXCertPathChecker must * support reverse checking and may support forward checking. * * @param forward the order that certificates are presented to * the check method. If true, certificates * are presented from target to most-trusted CA (forward); if * false, from most-trusted CA to target (reverse). * @exception CertPathValidatorException if this * PKIXCertPathChecker is unable to check certificates in * the specified order; it should never be thrown if the forward flag * is false since reverse checking must be supported */ public abstract void init(boolean forward) throws CertPathValidatorException; /** * Indicates if forward checking is supported. Forward checking refers * to the ability of the PKIXCertPathChecker to perform * its checks when certificates are presented to the check * method in the forward direction (from target to most-trusted CA). * * @return true if forward checking is supported, * false otherwise */ public abstract boolean isForwardCheckingSupported(); /** * Returns an immutable Set of X.509 certificate extensions * that this PKIXCertPathChecker supports (i.e. recognizes, is * able to process), or null if no extensions are supported. *

    * Each element of the set is a String representing the * Object Identifier (OID) of the X.509 extension that is supported. * The OID is represented by a set of nonnegative integers separated by * periods. *

    * All X.509 certificate extensions that a PKIXCertPathChecker * might possibly be able to process should be included in the set. * * @return an immutable Set of X.509 extension OIDs (in * String format) supported by this * PKIXCertPathChecker, or null if no * extensions are supported */ public abstract Set getSupportedExtensions(); /** * Performs the check(s) on the specified certificate using its internal * state and removes any critical extensions that it processes from the * specified collection of OID strings that represent the unresolved * critical extensions. The certificates are presented in the order * specified by the init method. * * @param cert the Certificate to be checked * @param unresolvedCritExts a Collection of OID strings * representing the current set of unresolved critical extensions * @exception CertPathValidatorException if the specified certificate does * not pass the check */ public abstract void check( Certificate cert, Collection unresolvedCritExts) throws CertPathValidatorException; /** * Returns a clone of this object. Calls the Object.clone() * method. * All subclasses which maintain state must support and * override this method, if necessary. * * @return a copy of this PKIXCertPathChecker */ public Object clone() { try { return super.clone(); } catch ( CloneNotSupportedException ex ) { /* Cannot happen */ throw new InternalError( ex.toString() ); } } } bouncycastle-1.49.orig/jdk1.1/java/security/cert/CRL.java0000644000175000017500000000050011705654526022437 0ustar ebourgebourg package java.security.cert; public abstract class CRL { private String type; protected CRL(String type) { this.type = type; } public final String getType() { return type; } public abstract boolean isRevoked(Certificate cert); public abstract String toString(); } bouncycastle-1.49.orig/jdk1.1/java/security/cert/CertStoreParameters.java0000644000175000017500000000506611705654526025771 0ustar ebourgebourgpackage java.security.cert; /** * A specification of CertStore parameters.
    *
    * The purpose of this interface is to group (and provide type safety for) * all CertStore parameter specifications. All * CertStore parameter specifications must implement this * interface.
    *
    * Typically, a CertStoreParameters object is passed as a parameter * to one of the {@link CertStore#getInstance CertStore.getInstance} methods. * The getInstance method returns a CertStore that * is used for retrieving Certificates and CRLs. The * CertStore that is returned is initialized with the specified * parameters. The type of parameters needed may vary between different types * of CertStores. * * @see CertStore#getInstance **/ public interface CertStoreParameters extends Cloneable { /** * Makes a copy of this CertStoreParameters.
    *
    * The precise meaning of "copy" may depend on the class of * the CertStoreParameters object. A typical implementation * performs a "deep copy" of this object, but this is not an absolute * requirement. Some implementations may perform a "shallow copy" of some * or all of the fields of this object.
    *
    * Note that the CertStore.getInstance methods make a copy * of the specified CertStoreParameters. A deep copy * implementation of clone is safer and more robust, as it * prevents the caller from corrupting a shared CertStore by * subsequently modifying the contents of its initialization parameters. * However, a shallow copy implementation of clone is more * appropriate for applications that need to hold a reference to a * parameter contained in the CertStoreParameters. For example, * a shallow copy clone allows an application to release the resources of * a particular CertStore initialization parameter immediately, * rather than waiting for the garbage collection mechanism. This should * be done with the utmost care, since the CertStore may still * be in use by other threads.
    *
    * Each subclass should state the precise behavior of this method so * that users and developers know what to expect. * * @return a copy of this CertStoreParameters */ public Object clone(); } bouncycastle-1.49.orig/jdk1.1/java/security/cert/CollectionCertStoreParameters.java0000644000175000017500000001017611705654526030003 0ustar ebourgebourgpackage java.security.cert; import java.util.ArrayList; import java.util.Collection; /** * Parameters used as input for the Collection CertStore * algorithm.
    *
    * This class is used to provide necessary configuration parameters * to implementations of the Collection CertStore * algorithm. The only parameter included in this class is the * Collection from which the CertStore will * retrieve certificates and CRLs.
    *
    * Concurrent Access
    *
    * Unless otherwise specified, the methods defined in this class are not * thread-safe. Multiple threads that need to access a single * object concurrently should synchronize amongst themselves and * provide the necessary locking. Multiple threads each manipulating * separate objects need not synchronize. * * @see java.util.Collection * @see CertStore **/ public class CollectionCertStoreParameters implements CertStoreParameters { private Collection collection; /** * Creates an instance of CollectionCertStoreParameters * which will allow certificates and CRLs to be retrieved from the * specified Collection. If the specified * Collection contains an object that is not a * Certificate or CRL, that object will be * ignored by the Collection CertStore.
    *
    * The Collection is not copied. Instead, a * reference is used. This allows the caller to subsequently add or * remove Certificates or CRLs from the * Collection, thus changing the set of * Certificates or CRLs available to the * Collection CertStore. The Collection CertStore * will not modify the contents of the Collection.
    *
    * If the Collection will be modified by one thread while * another thread is calling a method of a Collection CertStore * that has been initialized with this Collection, the * Collection must have fail-fast iterators. * * @param collection a Collection of * Certificates and CRLs * * @exception NullPointerException if collection is * null */ public CollectionCertStoreParameters(Collection collection) { if ( collection == null ) throw new NullPointerException("collection must be non-null"); this.collection = collection; } /** * Creates an instance of CollectionCertStoreParameters with * the an empty Collection. */ public CollectionCertStoreParameters() { collection = new ArrayList(); } /** * Returns the Collection from which Certificates * and CRLs are retrieved. This is not a copy of the * Collection, it is a reference. This allows the caller to * subsequently add or remove Certificates or * CRLs from the Collection. * * @return the Collection (never null) */ public Collection getCollection() { return collection; } /** * Returns a copy of this object. Note that only a reference to the * Collection is copied, and not the contents. * * @return the copy */ public Object clone() { try { return super.clone(); } catch (CloneNotSupportedException e) { /* Cannot happen */ throw new InternalError(e.toString()); } } /** * Returns a formatted string describing the parameters. * * @return a formatted string describing the parameters */ public String toString() { StringBuffer s = new StringBuffer(); s.append("CollectionCertStoreParameters: [\n collections:\n"); s.append( getCollection()); s.append("\n]" ); return s.toString(); } } bouncycastle-1.49.orig/jdk1.1/java/security/cert/TrustAnchor.java0000644000175000017500000002620411705654526024304 0ustar ebourgebourgpackage java.security.cert; import java.io.ByteArrayInputStream; import java.io.IOException; import java.security.PublicKey; import java.security.cert.X509Certificate; import org.bouncycastle.asn1.ASN1InputStream; import org.bouncycastle.asn1.ASN1Object; import org.bouncycastle.asn1.ASN1Sequence; /** * A trust anchor or most-trusted Certification Authority (CA).
    *
    * This class represents a "most-trusted CA", which is used as a trust anchor * for validating X.509 certification paths. A most-trusted CA includes the * public key of the CA, the CA's name, and any constraints upon the set of * paths which may be validated using this key. These parameters can be * specified in the form of a trusted X509Certificate or as individual * parameters.
    *
    * Concurrent Access
    *
    * All TrustAnchor objects must be immutable and thread-safe. That is, multiple * threads may concurrently invoke the methods defined in this class on a * single TrustAnchor object (or more than one) with no ill effects. Requiring * TrustAnchor objects to be immutable and thread-safe allows them to be passed * around to various pieces of code without worrying about coordinating access. * This stipulation applies to all public fields and methods of this class and * any added or overridden by subclasses.
    *
    * TODO: implement better nameConstraints testing. **/ public class TrustAnchor { private X509Certificate trustCert = null; private PublicKey trustPublicKey = null; private String trustName = null; private byte[] nameConstraints = null; /** * Creates an instance of TrustAnchor with the specified X509Certificate and * optional name constraints, which are intended to be used as additional * constraints when validating an X.509 certification path.
    *
    * The name constraints are specified as a byte array. This byte array * should contain the DER encoded form of the name constraints, as they * would appear in the NameConstraints structure defined in RFC 2459 and * X.509. The ASN.1 definition of this structure appears below.
    *
    * *

         *   NameConstraints ::= SEQUENCE {
         *        permittedSubtrees       [0]     GeneralSubtrees OPTIONAL,
         *        excludedSubtrees        [1]     GeneralSubtrees OPTIONAL }
         * 
         *   GeneralSubtrees ::= SEQUENCE SIZE (1..MAX) OF GeneralSubtree
         * 
         *   GeneralSubtree ::= SEQUENCE {
         *        base                    GeneralName,
         *        minimum         [0]     BaseDistance DEFAULT 0,
         *        maximum         [1]     BaseDistance OPTIONAL }
         * 
         *   BaseDistance ::= INTEGER (0..MAX)
         * 
         *   GeneralName ::= CHOICE {
         *        otherName                       [0]     OtherName,
         *        rfc822Name                      [1]     IA5String,
         *        dNSName                         [2]     IA5String,
         *        x400Address                     [3]     ORAddress,
         *        directoryName                   [4]     Name,
         *        ediPartyName                    [5]     EDIPartyName,
         *        uniformResourceIdentifier       [6]     IA5String,
         *        iPAddress                       [7]     OCTET STRING,
         *        registeredID                    [8]     OBJECT IDENTIFIER}
         * 
    * *
    *
    * Note that the name constraints byte array supplied is cloned to protect * against subsequent modifications. * * @param trustedCert * a trusted X509Certificate * @param nameConstraints * a byte array containing the ASN.1 DER encoding of a * NameConstraints extension to be used for checking name * constraints. Only the value of the extension is included, not * the OID or criticality flag. Specify null to omit the * parameter. * * @exception IllegalArgumentException * if the name constraints cannot be decoded * @exception NullPointerException * if the specified X509Certificate is null */ public TrustAnchor(X509Certificate trustedCert, byte[] nameConstraints) { if (trustedCert == null) { throw new NullPointerException("trustedCert must be non-null"); } this.trustCert = trustedCert; if (nameConstraints != null) { this.nameConstraints = (byte[])nameConstraints.clone(); checkNameConstraints(this.nameConstraints); } } /** * Creates an instance of TrustAnchor where the most-trusted * CA is specified as a distinguished name and public key. Name constraints * are an optional parameter, and are intended to be used as additional * constraints when validating an X.509 certification path. * * The name constraints are specified as a byte array. This byte array * contains the DER encoded form of the name constraints, as they would * appear in the NameConstraints structure defined in RFC 2459 and X.509. * The ASN.1 notation for this structure is supplied in the documentation * for {@link #TrustAnchor(X509Certificate trustedCert, byte[] * nameConstraints) TrustAnchor(X509Certificate trustedCert, byte[] * nameConstraints) }. * * Note that the name constraints byte array supplied here is cloned to * protect against subsequent modifications. * * @param caName * the X.500 distinguished name of the most-trusted CA in RFC * 2253 String format * @param pubKey * the public key of the most-trusted CA * @param nameConstraints * a byte array containing the ASN.1 DER encoding of a * NameConstraints extension to be used for checking name * constraints. Only the value of the extension is included, not * the OID or criticality flag. Specify null to omit the * parameter. * * @exception IllegalArgumentException * if the specified caName parameter is empty (caName.length() == 0) * or incorrectly formatted or the name constraints cannot be * decoded * @exception NullPointerException * if the specified caName or pubKey parameter is null */ public TrustAnchor(String caName, PublicKey pubKey, byte[] nameConstraints) { if (caName == null) { throw new NullPointerException("caName must be non-null"); } if (pubKey == null) { throw new NullPointerException("pubKey must be non-null"); } if (caName.length() == 0) { throw new IllegalArgumentException( "caName can not be an empty string"); } this.trustName = caName; this.trustPublicKey = pubKey; if (nameConstraints != null) { this.nameConstraints = (byte[])nameConstraints.clone(); checkNameConstraints(this.nameConstraints); } } /** * Returns the most-trusted CA certificate. * * @return a trusted X509Certificate or null * if the trust anchor was not specified as a trusted certificate */ public final X509Certificate getTrustedCert() { return trustCert; } /** * Returns the name of the most-trusted CA in RFC 2253 String format. * * @return the X.500 distinguished name of the most-trusted CA, or * null if the trust anchor was not specified as a * trusted public key and name pair */ public final String getCAName() { return trustName; } /** * Returns the public key of the most-trusted CA. * * @return the public key of the most-trusted CA, or null if the trust * anchor was not specified as a trusted public key and name pair */ public final PublicKey getCAPublicKey() { return trustPublicKey; } /** * Returns the name constraints parameter. The specified name constraints * are associated with this trust anchor and are intended to be used as * additional constraints when validating an X.509 certification path.
    *
    * The name constraints are returned as a byte array. This byte array * contains the DER encoded form of the name constraints, as they would * appear in the NameConstraints structure defined in RFC 2459 and X.509. * The ASN.1 notation for this structure is supplied in the documentation * for TrustAnchor(X509Certificate trustedCert, byte[] * nameConstraints).
    *
    * Note that the byte array returned is cloned to protect against subsequent * modifications. * * @return a byte array containing the ASN.1 DER encoding of a * NameConstraints extension used for checking name constraints, or * null if not set. */ public final byte[] getNameConstraints() { return (byte[])nameConstraints.clone(); } /** * Returns a formatted string describing the TrustAnchor. * * @return a formatted string describing the TrustAnchor */ public String toString() { StringBuffer sb = new StringBuffer(); sb.append("[\n"); if (getCAPublicKey() != null) { sb.append(" Trusted CA Public Key: ").append(getCAPublicKey()).append('\n'); sb.append(" Trusted CA Issuer Name: ").append(getCAName()).append('\n'); } else { sb.append(" Trusted CA cert: ").append(getTrustedCert()).append('\n'); } if (nameConstraints != null) { sb.append(" Name Constraints: ").append(nameConstraints).append('\n'); } return sb.toString(); } /** * Check given DER encoded nameConstraints for correct decoding. Currently * only basic DER decoding test.
    *
    * TODO: implement more testing. * * @param data * the DER encoded nameConstrains to be checked or * null * @exception IllegalArgumentException * if the check failed. */ private void checkNameConstraints(byte[] data) { if (data != null) { try { ByteArrayInputStream inStream = new ByteArrayInputStream(data); ASN1InputStream derInStream = new ASN1InputStream(inStream); ASN1Object derObject = derInStream.readObject(); if (!(derObject instanceof ASN1Sequence)) { throw new IllegalArgumentException( "nameConstraints parameter decoding error"); } } catch (IOException ex) { throw new IllegalArgumentException( "nameConstraints parameter decoding error: " + ex); } } } } bouncycastle-1.49.orig/jdk1.1/java/security/cert/CertSelector.java0000644000175000017500000000247511705654526024432 0ustar ebourgebourgpackage java.security.cert; /** * A selector that defines a set of criteria for selecting * Certificates. Classes that implement this interface * are often used to specify which Certificates should * be retrieved from a CertStore.
    *
    * Concurrent Access
    *
    * Unless otherwise specified, the methods defined in this interface are not * thread-safe. Multiple threads that need to access a single * object concurrently should synchronize amongst themselves and * provide the necessary locking. Multiple threads each manipulating * separate objects need not synchronize. * * @see Certificate * @see CertStore * @see CertStore#getCertificates */ public interface CertSelector extends Cloneable { /** * Decides whether a Certificate should be selected. * * @param cert the Certificate to be checked * @return true if the Certificate * should be selected, false otherwise */ public boolean match(Certificate cert); /** * Makes a copy of this CertSelector. Changes to the * copy will not affect the original and vice versa. * * @return a copy of this CertSelector */ public Object clone(); } bouncycastle-1.49.orig/jdk1.1/java/security/cert/PKIXCertPathValidatorResult.java0000644000175000017500000001153211705654526027301 0ustar ebourgebourgpackage java.security.cert; import java.security.PublicKey; /** * This class represents the successful result of the PKIX certification * path validation algorithm.
    *
    * Instances of PKIXCertPathValidatorResult are returned by the * {@link CertPathValidator#validate validate} method of * CertPathValidator objects implementing the PKIX algorithm.
    *
    * All PKIXCertPathValidatorResult objects contain the * valid policy tree and subject public key resulting from the * validation algorithm, as well as a TrustAnchor describing * the certification authority (CA) that served as a trust anchor for the * certification path.
    *
    * Concurrent Access
    *
    * Unless otherwise specified, the methods defined in this class are not * thread-safe. Multiple threads that need to access a single * object concurrently should synchronize amongst themselves and * provide the necessary locking. Multiple threads each manipulating * separate objects need not synchronize. * * @see CertPathValidatorResult **/ public class PKIXCertPathValidatorResult implements CertPathValidatorResult { private TrustAnchor trustAnchor; private PolicyNode policyTree; private PublicKey subjectPublicKey; /** * Creates an instance of PKIXCertPathValidatorResult * containing the specified parameters. * * @param trustAnchor a TrustAnchor describing the CA that * served as a trust anchor for the certification path * @param policyTree the immutable valid policy tree, or null * if there are no valid policies * @param subjectPublicKey the public key of the subject * * @exception NullPointerException if the subjectPublicKey or * trustAnchor parameters are null */ public PKIXCertPathValidatorResult(TrustAnchor trustAnchor, PolicyNode policyTree, PublicKey subjectPublicKey) { if ( subjectPublicKey == null ) throw new NullPointerException( "subjectPublicKey must be non-null" ); if ( trustAnchor == null ) throw new NullPointerException( "trustAnchor must be non-null" ); this.trustAnchor = trustAnchor; this.policyTree = policyTree; this.subjectPublicKey = subjectPublicKey; } /** * Returns the TrustAnchor describing the CA that served * as a trust anchor for the certification path. * * @return the TrustAnchor (never null) */ public TrustAnchor getTrustAnchor() { return trustAnchor; } /** * Returns the root node of the valid policy tree resulting from the * PKIX certification path validation algorithm. The * PolicyNode object that is returned and any objects that * it returns through public methods are immutable.
    *
    * Most applications will not need to examine the valid policy tree. * They can achieve their policy processing goals by setting the * policy-related parameters in PKIXParameters. However, more * sophisticated applications, especially those that process policy * qualifiers, may need to traverse the valid policy tree using the * {@link PolicyNode#getParent PolicyNode.getParent} and * {@link PolicyNode#getChildren PolicyNode.getChildren} methods. * * @return the root node of the valid policy tree, or null * if there are no valid policies */ public PolicyNode getPolicyTree() { return policyTree; } /** * Returns the public key of the subject (target) of the certification * path, including any inherited public key parameters if applicable. * * @return the public key of the subject (never null) */ public PublicKey getPublicKey() { return subjectPublicKey; } /** * Returns a copy of this object. * * @return the copy */ public Object clone() { try { return super.clone(); } catch ( CloneNotSupportedException ex ) { throw new InternalError( ex.toString() ); } } /** * Return a printable representation of this * PKIXCertPathValidatorResult. * * @return a String describing the contents of this * PKIXCertPathValidatorResult */ public String toString() { StringBuffer s = new StringBuffer(); s.append( "PKIXCertPathValidatorResult: [ \n" ); s.append( " Trust Anchor: ").append(getTrustAnchor()).append('\n' ); s.append( " Policy Tree: ").append(getPolicyTree()).append('\n' ); s.append( " Subject Public Key: ").append(getPublicKey()).append("\n]" ); return s.toString(); } } bouncycastle-1.49.orig/jdk1.1/java/security/cert/CRLSelector.java0000644000175000017500000000237111705654526024150 0ustar ebourgebourgpackage java.security.cert; /** * A selector that defines a set of criteria for selecting CRLs. * Classes that implement this interface are often used to specify * which CRLs should be retrieved from a CertStore.
    *
    * Concurrent Access
    *
    * Unless otherwise specified, the methods defined in this interface are not * thread-safe. Multiple threads that need to access a single * object concurrently should synchronize amongst themselves and * provide the necessary locking. Multiple threads each manipulating * separate objects need not synchronize. * * @see CRL * @see CertStore * @see CertStore#getCRLs **/ public interface CRLSelector extends Cloneable { /** * Decides whether a CRL should be selected. * * @param crl the CRL to be checked * * @return true if the CRL should be selected, * false otherwise */ public boolean match(CRL crl); /** * Makes a copy of this CRLSelector. Changes to the * copy will not affect the original and vice versa. * * @return a copy of this CRLSelector */ public Object clone(); } bouncycastle-1.49.orig/jdk1.1/java/security/cert/CertStoreException.java0000644000175000017500000001165411705654526025624 0ustar ebourgebourgpackage java.security.cert; import java.io.PrintStream; import java.io.PrintWriter; import java.security.GeneralSecurityException; /** * An exception indicating one of a variety of problems retrieving * certificates and CRLs from a CertStore.
    *
    * A CertStoreException provides support for wrapping * exceptions. The {@link #getCause getCause} method returns the throwable, * if any, that caused this exception to be thrown.
    *
    * Concurrent Access
    *
    * Unless otherwise specified, the methods defined in this class are not * thread-safe. Multiple threads that need to access a single * object concurrently should synchronize amongst themselves and * provide the necessary locking. Multiple threads each manipulating * separate objects need not synchronize. * * @see CertStore **/ public class CertStoreException extends GeneralSecurityException { private Throwable cause; /** * Creates a CertStoreException with null as * its detail message. */ public CertStoreException() { super(); } /** * Creates a CertStoreException with the given detail * message. A detail message is a String that describes this * particular exception. * * @param messag the detail message */ public CertStoreException(String message) { super(message); } /** * Creates a CertStoreException with the specified detail * message and cause. * * @param messag the detail message * @param cause the cause (which is saved for later retrieval by the * {@link #getCause getCause()} method). (A null value is * permitted, and indicates that the cause is nonexistent or unknown.) */ public CertStoreException(String message, Throwable cause) { super(message); this.cause = cause; } /** * Creates a CertStoreException that wraps the specified * throwable. This allows any exception to be converted into a * CertStoreException, while retaining information about the * cause, which may be useful for debugging. The detail message is * set to (cause==null ? null : cause.toString()) (which * typically contains the class and detail message of cause). * * @param cause the cause (which is saved for later retrieval by the * {@link #getCause getCause()} method). (A null value is * permitted, and indicates that the cause is nonexistent or unknown.) */ public CertStoreException(Throwable cause) { this.cause = cause; } /** * Returns the detail message for this CertStoreException. * * @return the detail message, or null if neither the message * nor cause were specified */ public String getMessage() { String message = super.getMessage(); if ( message == null && cause == null ) return null; StringBuffer s = new StringBuffer(); if ( message != null ) { s.append(message).append('\n'); } if ( cause != null ) { s.append("Cause:\n").append(cause.getMessage()); } return s.toString(); } /** * Returns the cause of this CertStoreException or * null if the cause is nonexistent or unknown. * * @return the cause of this throwable or null if the cause * is nonexistent or unknown. */ public Throwable getCause() { return cause; } /** * Returns a string describing this exception, including a description * of the internal (wrapped) cause if there is one. * * @return a string representation of this * CertStoreException */ public String toString() { String message = getMessage(); if ( message == null ) return ""; return message; } /** * Prints a stack trace to System.err, including the backtrace * of the cause, if any. */ public void printStackTrace() { printStackTrace(System.err); } /** * Prints a stack trace to a PrintStream, including the * backtrace of the cause, if any. * * @param ps the PrintStream to use for output */ public void printStackTrace(PrintStream ps) { super.printStackTrace(ps); if ( cause != null ) { cause.printStackTrace(ps); } } /** * Prints a stack trace to a PrintWriter, including the * backtrace of the cause, if any. * * @param pw the PrintWriter to use for output */ public void printStackTrace(PrintWriter pw) { if ( cause != null ) { cause.printStackTrace(pw); } super.printStackTrace(pw); if ( cause != null ) { cause.printStackTrace(pw); } } } bouncycastle-1.49.orig/jdk1.1/java/security/cert/CertStoreSpi.java0000644000175000017500000001155411705654526024420 0ustar ebourgebourgpackage java.security.cert; import java.security.InvalidAlgorithmParameterException; import java.util.Collection; /** * The Service Provider Interface (SPI) * for the {@link CertStore CertStore} class. All CertStore * implementations must include a class (the SPI class) that extends * this class (CertStoreSpi), provides a constructor with * a single argument of type CertStoreParameters, and implements * all of its methods. In general, instances of this class should only be * accessed through the CertStore class. * For details, see the Java Cryptography Architecture.
    *
    * Concurrent Access
    *
    * The public methods of all CertStoreSpi objects must be * thread-safe. That is, multiple threads may concurrently invoke these * methods on a single CertStoreSpi object (or more than one) * with no ill effects. This allows a CertPathBuilder to search * for a CRL while simultaneously searching for further certificates, for * instance.
    *
    * Simple CertStoreSpi implementations will probably ensure * thread safety by adding a synchronized keyword to their * engineGetCertificates and engineGetCRLs methods. * More sophisticated ones may allow truly concurrent access. **/ public abstract class CertStoreSpi extends Object { /** * The sole constructor. * * @param params the initialization parameters (may be null) * @exception InvalidAlgorithmParameterException if the initialization * parameters are inappropriate for this CertStoreSpi */ public CertStoreSpi( CertStoreParameters params ) throws InvalidAlgorithmParameterException {} /** * Returns a Collection of Certificates that * match the specified selector. If no Certificates * match the selector, an empty Collection will be returned.
    *
    * For some CertStore types, the resulting * Collection may not contain all of the * Certificates that match the selector. For instance, * an LDAP CertStore may not search all entries in the * directory. Instead, it may just search entries that are likely to * contain the Certificates it is looking for.
    *
    * Some CertStore implementations (especially LDAP * CertStores) may throw a CertStoreException * unless a non-null CertSelector is provided that includes * specific criteria that can be used to find the certificates. Issuer * and/or subject names are especially useful criteria. * * @param selector A CertSelector used to select which * Certificates should be returned. Specify null * to return all Certificates (if supported). * * @return A Collection of Certificates that * match the specified selector (never null) * * @exception CertStoreException if an exception occurs */ public abstract Collection engineGetCertificates( CertSelector selector ) throws CertStoreException; /** * Returns a Collection of CRLs that * match the specified selector. If no CRLs * match the selector, an empty Collection will be returned.
    *
    * For some CertStore types, the resulting * Collection may not contain all of the * CRLs that match the selector. For instance, * an LDAP CertStore may not search all entries in the * directory. Instead, it may just search entries that are likely to * contain the CRLs it is looking for.
    *
    * Some CertStore implementations (especially LDAP * CertStores) may throw a CertStoreException * unless a non-null CRLSelector is provided that includes * specific criteria that can be used to find the CRLs. Issuer names * and/or the certificate to be checked are especially useful. * * @param selector A CRLSelector used to select which * CRLs should be returned. Specify null * to return all CRLs (if supported). * * @return A Collection of CRLs that * match the specified selector (never null) * * @exception CertStoreException if an exception occurs */ public abstract Collection engineGetCRLs( CRLSelector selector ) throws CertStoreException; } bouncycastle-1.49.orig/jdk1.1/java/security/cert/CertificateEncodingException.java0000644000175000017500000000036411705654526027577 0ustar ebourgebourg package java.security.cert; public class CertificateEncodingException extends CertificateException { public CertificateEncodingException() { } public CertificateEncodingException(String msg) { super(msg); } } bouncycastle-1.49.orig/jdk1.1/java/security/cert/PKIXCertPathBuilderResult.java0000644000175000017500000000716511705654526026751 0ustar ebourgebourgpackage java.security.cert; import java.security.PublicKey; /** * This class represents the successful result of the PKIX certification * path builder algorithm. All certification paths that are built and * returned using this algorithm are also validated according to the PKIX * certification path validation algorithm.
    *
    * Instances of PKIXCertPathBuilderResult are returned by * the build method of CertPathBuilder * objects implementing the PKIX algorithm.
    *
    * All PKIXCertPathBuilderResult objects contain the * certification path constructed by the build algorithm, the * valid policy tree and subject public key resulting from the build * algorithm, and a TrustAnchor describing the certification * authority (CA) that served as a trust anchor for the certification path.
    *
    * Concurrent Access
    *
    * Unless otherwise specified, the methods defined in this class are not * thread-safe. Multiple threads that need to access a single * object concurrently should synchronize amongst themselves and * provide the necessary locking. Multiple threads each manipulating * separate objects need not synchronize. * * @see CertPathBuilderResult * **/ public class PKIXCertPathBuilderResult extends PKIXCertPathValidatorResult implements CertPathBuilderResult { private CertPath certPath; /** * Creates an instance of PKIXCertPathBuilderResult * containing the specified parameters. * * @param certPath the validated CertPath * @param trustAnchor a TrustAnchor describing the CA that * served as a trust anchor for the certification path * @param policyTree the immutable valid policy tree, or null * if there are no valid policies * @param subjectPublicKey the public key of the subject * * @exception NullPointerException if the certPath, * trustAnchor or subjectPublicKey parameters * are null */ public PKIXCertPathBuilderResult(CertPath certPath, TrustAnchor trustAnchor, PolicyNode policyTree, PublicKey subjectPublicKey) { super(trustAnchor, policyTree, subjectPublicKey); if ( certPath == null ) throw new NullPointerException( "certPath must be non-null" ); this.certPath = certPath; } /** * Returns the built and validated certification path. The * CertPath object does not include the trust anchor. * Instead, use the {@link #getTrustAnchor() getTrustAnchor()} method to * obtain the TrustAnchor that served as the trust anchor * for the certification path. * * @return the built and validated CertPath (never * null) */ public CertPath getCertPath() { return certPath; } /** * Return a printable representation of this * PKIXCertPathBuilderResult. * * @return a String describing the contents of this * PKIXCertPathBuilderResult */ public String toString() { StringBuffer s = new StringBuffer(); s.append( "PKIXCertPathBuilderResult: [\n" ); s.append( " Certification Path: ").append(getCertPath()).append('\n' ); s.append( " Trust Anchor: ").append(getTrustAnchor()).append('\n' ); s.append( " Policy Tree: ").append(getPolicyTree()).append('\n' ); s.append( " Subject Public Key: ").append(getPublicKey()).append("\n]"); return s.toString(); } } bouncycastle-1.49.orig/jdk1.1/java/security/cert/CertPathValidatorResult.java0000644000175000017500000000134111705654526026602 0ustar ebourgebourgpackage java.security.cert; /** * A specification of the result of a certification path validator algorithm.
    *
    * The purpose of this interface is to group (and provide type safety * for) all certification path validator results. All results returned * by the {@link CertPathValidator#validate CertPathValidator.validate} * method must implement this interface. * * @see CertPathValidator **/ public interface CertPathValidatorResult extends Cloneable { /** * Makes a copy of this CertPathValidatorResult. Changes to the * copy will not affect the original and vice versa. * * @return a copy of this CertPathValidatorResult */ public Object clone(); } bouncycastle-1.49.orig/jdk1.1/java/security/cert/CertificateException.java0000644000175000017500000000042011705654526026121 0ustar ebourgebourg package java.security.cert; import java.security.GeneralSecurityException; public class CertificateException extends GeneralSecurityException { public CertificateException() { } public CertificateException(String msg) { super(msg); } } bouncycastle-1.49.orig/jdk1.1/java/security/cert/CertificateFactorySpi.java0000644000175000017500000001100711705654526026251 0ustar ebourgebourg package java.security.cert; import java.io.InputStream; import java.util.Collection; import java.util.Iterator; import java.util.List; public abstract class CertificateFactorySpi { public CertificateFactorySpi() { } public abstract CRL engineGenerateCRL(InputStream inStream) throws CRLException; public abstract Collection engineGenerateCRLs(InputStream inStream) throws CRLException; public abstract Certificate engineGenerateCertificate(InputStream inStream) throws CertificateException; public abstract /*SK13 Vector*/ Collection engineGenerateCertificates(InputStream inStream) throws CertificateException; /** * Returns an iteration of the CertPath encodings supported * by this certificate factory, with the default encoding first. See * Appendix A in the * Java Certification Path API Programmer's Guide * for information about standard encoding names.
    *
    * Attempts to modify the returned Iterator via its * remove method result in an * UnsupportedOperationException.
    *
    * This method was added to version 1.4 of the Java 2 Platform * Standard Edition. In order to maintain backwards compatibility with * existing service providers, this method cannot be abstract * and by default throws an UnsupportedOperationException. * * @return an Iterator over the names of the supported * CertPath encodings (as Strings) * * @exception UnsupportedOperationException if the method is not supported */ public abstract Iterator engineGetCertPathEncodings(); /** * Generates a CertPath object and initializes it with * the data read from the InputStream inStream. The data * is assumed to be in the default encoding. * * @param inStream an InputStream containing the data * * @return a CertPath initialized with the data from the * InputStream * * @exception CertificateException if an exception occurs while decoding */ public abstract CertPath engineGenerateCertPath(InputStream inStream) throws CertificateException; /** * Generates a CertPath object and initializes it with * the data read from the InputStream inStream. The data * is assumed to be in the specified encoding.
    *
    * This method was added to version 1.4 of the Java 2 Platform * Standard Edition. In order to maintain backwards compatibility with * existing service providers, this method cannot be abstract * and by default throws an UnsupportedOperationException. * * @param inStream an InputStream containing the data * @param encoding the encoding used for the data * * @return a CertPath initialized with the data from the * InputStream * * @exception CertificateException if an exception occurs while decoding or * the encoding requested is not supported * @exception UnsupportedOperationException if the method is not supported */ public abstract CertPath engineGenerateCertPath(InputStream inStream, String encoding) throws CertificateException; /** * Generates a CertPath object and initializes it with * a List of Certificates.
    *
    * The certificates supplied must be of a type supported by the * CertificateFactory. They will be copied out of the supplied * List object.
    *
    * This method was added to version 1.4 of the Java 2 Platform * Standard Edition. In order to maintain backwards compatibility with * existing service providers, this method cannot be abstract * and by default throws an UnsupportedOperationException. * * @param certificates a List of Certificates * * @return a CertPath initialized with the supplied list of * certificates * * @exception CertificateException if an exception occurs * @exception UnsupportedOperationException if the method is not supported */ public abstract CertPath engineGenerateCertPath(List certificates) throws CertificateException; } bouncycastle-1.49.orig/jdk1.1/java/security/UnrecoverableKeyException.java0000644000175000017500000000035211705654526026213 0ustar ebourgebourg package java.security; public class UnrecoverableKeyException extends GeneralSecurityException { public UnrecoverableKeyException() { } public UnrecoverableKeyException(String msg) { super(msg); } } bouncycastle-1.49.orig/jdk1.1/java/security/AlgorithmParameterGeneratorSpi.java0000644000175000017500000000073411705654526027205 0ustar ebourgebourgpackage java.security; import java.security.spec.AlgorithmParameterSpec; public abstract class AlgorithmParameterGeneratorSpi { public AlgorithmParameterGeneratorSpi() { } protected abstract AlgorithmParameters engineGenerateParameters(); protected abstract void engineInit(AlgorithmParameterSpec genParamSpec, SecureRandom random) throws InvalidAlgorithmParameterException; protected abstract void engineInit(int size, SecureRandom random); } bouncycastle-1.49.orig/jdk1.1/java/security/KeyStoreException.java0000644000175000017500000000032211705654526024510 0ustar ebourgebourg package java.security; public class KeyStoreException extends GeneralSecurityException { public KeyStoreException() { } public KeyStoreException(String msg) { super(msg); } } bouncycastle-1.49.orig/jdk1.1/java/security/AlgorithmParametersSpi.java0000644000175000017500000000162711705654526025523 0ustar ebourgebourg package java.security; import java.io.IOException; import java.security.spec.AlgorithmParameterSpec; import java.security.spec.InvalidParameterSpecException; public abstract class AlgorithmParametersSpi extends Object { public AlgorithmParametersSpi() { } protected abstract byte[] engineGetEncoded() throws IOException; protected abstract byte[] engineGetEncoded(String format) throws IOException; protected abstract AlgorithmParameterSpec engineGetParameterSpec(Class paramSpec) throws InvalidParameterSpecException; protected abstract void engineInit(AlgorithmParameterSpec paramSpec) throws InvalidParameterSpecException; protected abstract void engineInit(byte[] params) throws IOException; protected abstract void engineInit(byte[] params, String format) throws IOException; protected abstract String engineToString(); } bouncycastle-1.49.orig/jdk1.1/java/security/KeyStoreSpi.java0000644000175000017500000000343111705654526023311 0ustar ebourgebourg package java.security; import java.io.IOException; import java.io.InputStream; import java.io.OutputStream; import java.security.cert.Certificate; import java.security.cert.CertificateException; import java.util.Date; import java.util.Enumeration; public abstract class KeyStoreSpi extends Object { public KeyStoreSpi() { } public abstract Enumeration engineAliases(); public abstract boolean engineContainsAlias(String alias); public abstract void engineDeleteEntry(String alias) throws KeyStoreException; public abstract Certificate engineGetCertificate(String alias); public abstract String engineGetCertificateAlias(Certificate cert); public abstract Certificate[] engineGetCertificateChain(String alias); public abstract Date engineGetCreationDate(String alias); public abstract Key engineGetKey(String alias, char[] password) throws NoSuchAlgorithmException, UnrecoverableKeyException; public abstract boolean engineIsCertificateEntry(String alias); public abstract boolean engineIsKeyEntry(String alias); public abstract void engineLoad(InputStream stream, char[] password) throws IOException, NoSuchAlgorithmException, CertificateException; public abstract void engineSetCertificateEntry( String alias, Certificate cert) throws KeyStoreException; public abstract void engineSetKeyEntry( String alias, Key key, char[] password, Certificate[] chain) throws KeyStoreException; public abstract void engineSetKeyEntry( String alias, byte[] key, Certificate[] chain) throws KeyStoreException; public abstract int engineSize(); public abstract void engineStore(OutputStream stream, char[] password) throws IOException, NoSuchAlgorithmException, CertificateException; } bouncycastle-1.49.orig/jdk1.1/java/security/KeyFactorySpi.java0000644000175000017500000000115511705654526023625 0ustar ebourgebourg package java.security; import java.security.spec.InvalidKeySpecException; import java.security.spec.KeySpec; public abstract class KeyFactorySpi extends Object { public KeyFactorySpi() { } protected abstract PrivateKey engineGeneratePrivate(KeySpec keySpec) throws InvalidKeySpecException; protected abstract PublicKey engineGeneratePublic(KeySpec keySpec) throws InvalidKeySpecException; protected abstract KeySpec engineGetKeySpec(Key key, Class keySpec) throws InvalidKeySpecException; protected abstract Key engineTranslateKey(Key key) throws InvalidKeyException; } bouncycastle-1.49.orig/jdk1.1/java/security/InvalidAlgorithmParameterException.java0000644000175000017500000000040511705654526030043 0ustar ebourgebourg package java.security; public class InvalidAlgorithmParameterException extends GeneralSecurityException { public InvalidAlgorithmParameterException() { } public InvalidAlgorithmParameterException(String msg) { super(msg); } } bouncycastle-1.49.orig/jdk1.1/java/security/KeyStore.java0000644000175000017500000001401711705654526022637 0ustar ebourgebourg package java.security; import java.io.IOException; import java.io.InputStream; import java.io.OutputStream; import java.security.cert.Certificate; import java.security.cert.CertificateException; import java.util.Date; import java.util.Enumeration; public class KeyStore extends Object { private KeyStoreSpi keyStoreSpi; private Provider provider; private String type; private boolean initialised; protected KeyStore( KeyStoreSpi keyStoreSpi, Provider provider, String type) { this.keyStoreSpi = keyStoreSpi; this.provider = provider; this.type = type; this.initialised = false; } public final Enumeration aliases() throws KeyStoreException { if ( !initialised ) throw new KeyStoreException("KeyStore not initialised."); return keyStoreSpi.engineAliases(); } public final boolean containsAlias(String alias) throws KeyStoreException { if ( !initialised ) throw new KeyStoreException("KeyStore not initialised."); return keyStoreSpi.engineContainsAlias(alias); } public final void deleteEntry(String alias) throws KeyStoreException { if ( !initialised ) throw new KeyStoreException("KeyStore not initialised."); keyStoreSpi.engineDeleteEntry(alias); } public final Certificate getCertificate(String alias) throws KeyStoreException { if ( !initialised ) throw new KeyStoreException("KeyStore not initialised."); return keyStoreSpi.engineGetCertificate(alias); } public final String getCertificateAlias(Certificate cert) throws KeyStoreException { if ( !initialised ) throw new KeyStoreException("KeyStore not initialised."); return keyStoreSpi.engineGetCertificateAlias(cert); } public final Certificate[] getCertificateChain(String alias) throws KeyStoreException { if ( !initialised ) throw new KeyStoreException("KeyStore not initialised."); return keyStoreSpi.engineGetCertificateChain(alias); } public final Date getCreationDate(String alias) throws KeyStoreException { if ( !initialised ) throw new KeyStoreException("KeyStore not initialised."); return keyStoreSpi.engineGetCreationDate(alias); } public static final String getDefaultType() { return "JKS"; } public static KeyStore getInstance(String type) throws KeyStoreException { try { SecurityUtil.Implementation imp = SecurityUtil.getImplementation("KeyStore", type, null); if (imp != null) { return new KeyStore((KeyStoreSpi)imp.getEngine(), imp.getProvider(), type); } throw new KeyStoreException("can't find type " + type); } catch (NoSuchProviderException e) { throw new KeyStoreException(type + " not found"); } } public static KeyStore getInstance(String type, String provider) throws KeyStoreException, NoSuchProviderException { SecurityUtil.Implementation imp = SecurityUtil.getImplementation("KeyStore", type, provider); if (imp != null) { return new KeyStore((KeyStoreSpi)imp.getEngine(), imp.getProvider(), type); } throw new KeyStoreException("can't find type " + type); } public final Key getKey(String alias, char[] password) throws KeyStoreException, NoSuchAlgorithmException, UnrecoverableKeyException { if ( !initialised ) throw new KeyStoreException("KeyStore not initialised."); return keyStoreSpi.engineGetKey(alias, password); } public final Provider getProvider() { return provider; } public final String getType() { return type; } public final boolean isCertificateEntry(String alias) throws KeyStoreException { if ( !initialised ) throw new KeyStoreException("KeyStore not initialised."); return keyStoreSpi.engineIsCertificateEntry(alias); } public final boolean isKeyEntry(String alias) throws KeyStoreException { if ( !initialised ) throw new KeyStoreException("KeyStore not initialised."); return keyStoreSpi.engineIsKeyEntry(alias); } public final void load( InputStream stream, char[] password) throws IOException, NoSuchAlgorithmException, CertificateException { keyStoreSpi.engineLoad(stream, password); initialised = true; } public final void setCertificateEntry(String alias, Certificate cert) throws KeyStoreException { if ( !initialised ) throw new KeyStoreException("KeyStore not initialised."); keyStoreSpi.engineSetCertificateEntry(alias, cert); } public final void setKeyEntry( String alias, Key key, char[] password, Certificate[] chain) throws KeyStoreException { if ( !initialised ) throw new KeyStoreException("KeyStore not initialised."); keyStoreSpi.engineSetKeyEntry(alias, key, password, chain); } public final void setKeyEntry( String alias, byte[] key, Certificate[] chain) throws KeyStoreException { if ( !initialised ) throw new KeyStoreException("KeyStore not initialised."); keyStoreSpi.engineSetKeyEntry(alias, key, chain); } public final int size() throws KeyStoreException { if ( !initialised ) throw new KeyStoreException("KeyStore not initialised."); return keyStoreSpi.engineSize(); } public final void store( OutputStream stream, char[] password) throws KeyStoreException, IOException, NoSuchAlgorithmException, CertificateException { if ( !initialised ) throw new KeyStoreException("KeyStore not initialised."); keyStoreSpi.engineStore(stream, password); } } bouncycastle-1.49.orig/jdk1.1/java/security/spec/0000755000175000017500000000000012152033550021137 5ustar ebourgebourgbouncycastle-1.49.orig/jdk1.1/java/security/spec/RSAPrivateCrtKeySpec.java0000644000175000017500000000261011705654527025736 0ustar ebourgebourg package java.security.spec; import java.math.BigInteger; public class RSAPrivateCrtKeySpec extends RSAPrivateKeySpec { private BigInteger publicExponent; private BigInteger primeP; private BigInteger primeQ; private BigInteger primeExponentP; private BigInteger primeExponentQ; private BigInteger crtCoefficient; public RSAPrivateCrtKeySpec( BigInteger modulus, BigInteger publicExponent, BigInteger privateExponent, BigInteger primeP, BigInteger primeQ, BigInteger primeExponentP, BigInteger primeExponentQ, BigInteger crtCoefficient) { super(modulus, privateExponent); this.publicExponent = publicExponent; this.primeP = primeP; this.primeQ = primeQ; this.primeExponentP = primeExponentP; this.primeExponentQ = primeExponentQ; this.crtCoefficient = crtCoefficient; } public BigInteger getCrtCoefficient() { return crtCoefficient; } public BigInteger getPrimeExponentP() { return primeExponentP; } public BigInteger getPrimeExponentQ() { return primeExponentQ; } public BigInteger getPrimeP() { return primeP; } public BigInteger getPrimeQ() { return primeQ; } public BigInteger getPublicExponent() { return publicExponent; } } bouncycastle-1.49.orig/jdk1.1/java/security/spec/DSAParameterSpec.java0000644000175000017500000000110711705654527025104 0ustar ebourgebourg package java.security.spec; import java.math.BigInteger; import java.security.interfaces.DSAParams; public class DSAParameterSpec implements AlgorithmParameterSpec, DSAParams { private BigInteger p; private BigInteger q; private BigInteger g; public DSAParameterSpec(BigInteger p, BigInteger q, BigInteger g) { this.p = p; this.q = q; this.g = g; } public BigInteger getG() { return g; } public BigInteger getP() { return p; } public BigInteger getQ() { return q; } } bouncycastle-1.49.orig/jdk1.1/java/security/spec/PKCS8EncodedKeySpec.java0000644000175000017500000000051411705654527025420 0ustar ebourgebourg package java.security.spec; public class PKCS8EncodedKeySpec extends EncodedKeySpec { public PKCS8EncodedKeySpec(byte[] encodedKey) { super(encodedKey); } public byte[] getEncoded() { return super.getEncoded(); } public final String getFormat() { return "PKCS#8"; } } bouncycastle-1.49.orig/jdk1.1/java/security/spec/InvalidKeySpecException.java0000644000175000017500000000043111705654527026551 0ustar ebourgebourg package java.security.spec; import java.security.GeneralSecurityException; public class InvalidKeySpecException extends GeneralSecurityException { public InvalidKeySpecException() { } public InvalidKeySpecException(String msg) { super(msg); } } bouncycastle-1.49.orig/jdk1.1/java/security/spec/PSSParameterSpec.java0000644000175000017500000000171511705654527025147 0ustar ebourgebourg package java.security.spec; /** * This class specifies a parameter spec for RSA PSS encoding scheme, * as defined in the PKCS#1 v2.1. * * @since 1.4 * @see AlgorithmParameterSpec, Signature */ public class PSSParameterSpec extends Object implements AlgorithmParameterSpec { private int saltLen; /** * Creates a new PSSParameterSpec given the salt length as defined * in PKCS#1. * * @param saltLen - the length of salt in bits to be used in PKCS#1 * PSS encoding. * @throws IllegalArgumentException - if saltLen is less than 0. */ public PSSParameterSpec(int saltLen) { if ( saltLen < 0 ) { throw new IllegalArgumentException("Salt length must be >= 0"); } this.saltLen = saltLen; } /** * Returns the salt length in bits. * * @returns the salt length. */ public int getSaltLength() { return saltLen; } } bouncycastle-1.49.orig/jdk1.1/java/security/spec/InvalidParameterSpecException.java0000644000175000017500000000045311705654527027745 0ustar ebourgebourg package java.security.spec; import java.security.GeneralSecurityException; public class InvalidParameterSpecException extends GeneralSecurityException { public InvalidParameterSpecException() { } public InvalidParameterSpecException(String msg) { super(msg); } } bouncycastle-1.49.orig/jdk1.1/java/security/spec/X509EncodedKeySpec.java0000644000175000017500000000051111705654527025232 0ustar ebourgebourg package java.security.spec; public class X509EncodedKeySpec extends EncodedKeySpec { public X509EncodedKeySpec(byte[] encodedKey) { super(encodedKey); } public byte[] getEncoded() { return super.getEncoded(); } public final String getFormat() { return "X.509"; } } bouncycastle-1.49.orig/jdk1.1/java/security/spec/KeySpec.java0000644000175000017500000000007411705654527023366 0ustar ebourgebourg package java.security.spec; public interface KeySpec { } bouncycastle-1.49.orig/jdk1.1/java/security/spec/EncodedKeySpec.java0000644000175000017500000000055111705654527024650 0ustar ebourgebourg package java.security.spec; public abstract class EncodedKeySpec implements KeySpec { private byte[] encodedKey; public EncodedKeySpec(byte[] encodedKey) { this.encodedKey = (byte[])encodedKey.clone(); } public byte[] getEncoded() { return (byte[])encodedKey.clone(); } public abstract String getFormat(); } bouncycastle-1.49.orig/jdk1.1/java/security/spec/DSAPrivateKeySpec.java0000644000175000017500000000117411705654527025253 0ustar ebourgebourg package java.security.spec; import java.math.BigInteger; public class DSAPrivateKeySpec implements KeySpec { private BigInteger x; private BigInteger p; private BigInteger q; private BigInteger g; public DSAPrivateKeySpec(BigInteger x, BigInteger p, BigInteger q, BigInteger g) { this.x = x; this.p = p; this.q = q; this.g = g; } public BigInteger getG() { return g; } public BigInteger getP() { return p; } public BigInteger getQ() { return q; } public BigInteger getX() { return x; } } bouncycastle-1.49.orig/jdk1.1/java/security/spec/RSAMultiPrimePrivateCrtKeySpec.java0000644000175000017500000001042311705654527027747 0ustar ebourgebourg package java.security.spec; import java.math.BigInteger; /** * This class specifies an RSA multi-prime private key, as defined in * the PKCS#1 v2.1, using the Chinese Remainder Theorem (CRT) information * values for efficiency. * * @since 1.4 * @see Key, KeyFactory, KeySpec, PKCS8EncodedKeySpec, RSAPrivateKeySpec, * RSAPublicKeySpec, RSAOtherPrimeInfo */ public class RSAMultiPrimePrivateCrtKeySpec extends RSAPrivateKeySpec { private BigInteger publicExponent; private BigInteger privateExponent; private BigInteger primeP; private BigInteger primeQ; private BigInteger primeExponentP; private BigInteger primeExponentQ; private BigInteger crtCoefficient; private RSAOtherPrimeInfo[] otherPrimeInfo; /** * Creates a new RSAMultiPrimePrivateCrtKeySpec given the modulus, * publicExponent, privateExponent, primeP, primeQ, primeExponentP, * primeExponentQ, crtCoefficient, and otherPrimeInfo as defined in * PKCS#1 v2.1. * * Note that otherPrimeInfo is cloned when constructing this object. * * @param modulus - the modulus n. * @param publicExponent - the public exponent e. * @param privateExponent - the private exponent d. * @param primeP - the prime factor p of n. * @param primeQ - the prime factor q of n. * @param primeExponentP - this is d mod (p-1). * @param primeExponentQ - this is d mod (q-1). * @param crtCoefficient - the Chinese Remainder Theorem coefficient q-1 * mod p. * @param otherPrimeInfo - triplets of the rest of primes, null can be * specified if there are only two prime factors (p and q). * @throws NullPointerException - if any of the parameters, i.e. modulus, * publicExponent, privateExponent, primeP, primeQ, primeExponentP, * primeExponentQ, crtCoefficient, is null. * @throws IllegalArgumentException - if an empty, i.e. 0-length, * otherPrimeInfo is specified. */ public RSAMultiPrimePrivateCrtKeySpec( BigInteger modulus, BigInteger publicExponent, BigInteger privateExponent, BigInteger primeP, BigInteger primeQ, BigInteger primeExponentP, BigInteger primeExponentQ, BigInteger crtCoefficient, RSAOtherPrimeInfo[] otherPrimeInfo) { super(modulus, privateExponent); if ( publicExponent == null || primeP == null || primeQ == null || primeExponentP == null || primeExponentQ == null || crtCoefficient == null ) { throw new NullPointerException("Invalid null argument"); } if ( otherPrimeInfo != null ) { if ( otherPrimeInfo.length == 0 ) { throw new IllegalArgumentException("Invalid length for otherPrimeInfo"); } this.otherPrimeInfo = (RSAOtherPrimeInfo[])otherPrimeInfo.clone(); } } /** * Returns the public exponent. * * @returns the public exponent. */ public BigInteger getPublicExponent() { return publicExponent; } /** * Returns the primeP. * * @returns the primeP. */ public BigInteger getPrimeP() { return primeP; } /** * Returns the primeQ. * * @returns the primeQ. */ public BigInteger getPrimeQ() { return primeQ; } /** * Returns the primeExponentP. * * @returns the primeExponentP. */ public BigInteger getPrimeExponentP() { return primeExponentP; } /** * Returns the primeExponentQ. * * @returns the primeExponentQ. */ public BigInteger getPrimeExponentQ() { return primeExponentQ; } /** * Returns the crtCofficient. * * @returns the crtCofficient. */ public BigInteger getCrtCoefficient() { return crtCoefficient; } /** * Returns a copy of the otherPrimeInfo or null if there are only * two prime factors (p and q). * * @returns the otherPrimeInfo. */ public RSAOtherPrimeInfo[] getOtherPrimeInfo() { if ( otherPrimeInfo != null ) { return (RSAOtherPrimeInfo[])otherPrimeInfo.clone(); } return null; } } bouncycastle-1.49.orig/jdk1.1/java/security/spec/RSAPublicKeySpec.java0000644000175000017500000000103411705654527025070 0ustar ebourgebourg package java.security.spec; import java.math.BigInteger; public class RSAPublicKeySpec extends Object implements KeySpec { private BigInteger modulus; private BigInteger publicExponent; public RSAPublicKeySpec( BigInteger modulus, BigInteger publicExponent) { this.modulus = modulus; this.publicExponent = publicExponent; } public BigInteger getModulus() { return modulus; } public BigInteger getPublicExponent() { return publicExponent; } } bouncycastle-1.49.orig/jdk1.1/java/security/spec/RSAKeyGenParameterSpec.java0000644000175000017500000000135111705654527026226 0ustar ebourgebourgpackage java.security.spec; import java.math.BigInteger; /** * specifies parameters to be used for the generation of * a RSA key pair. */ public class RSAKeyGenParameterSpec implements AlgorithmParameterSpec { static BigInteger F0 = BigInteger.valueOf(3); static BigInteger F4 = BigInteger.valueOf(65537); private int keysize; private BigInteger publicExponent; public RSAKeyGenParameterSpec( int keysize, BigInteger publicExponent) { this.keysize = keysize; this.publicExponent = publicExponent; } public int getKeysize() { return keysize; } public BigInteger getPublicExponent() { return publicExponent; } } bouncycastle-1.49.orig/jdk1.1/java/security/spec/DSAPublicKeySpec.java0000644000175000017500000000117211705654527025055 0ustar ebourgebourg package java.security.spec; import java.math.BigInteger; public class DSAPublicKeySpec implements KeySpec { private BigInteger y; private BigInteger p; private BigInteger q; private BigInteger g; public DSAPublicKeySpec(BigInteger y, BigInteger p, BigInteger q, BigInteger g) { this.y = y; this.p = p; this.q = q; this.g = g; } public BigInteger getG() { return g; } public BigInteger getP() { return p; } public BigInteger getQ() { return q; } public BigInteger getY() { return y; } } bouncycastle-1.49.orig/jdk1.1/java/security/spec/RSAPrivateKeySpec.java0000644000175000017500000000104411705654527025265 0ustar ebourgebourg package java.security.spec; import java.math.BigInteger; public class RSAPrivateKeySpec extends Object implements KeySpec { private BigInteger modulus; private BigInteger privateExponent; public RSAPrivateKeySpec( BigInteger modulus, BigInteger privateExponent) { this.modulus = modulus; this.privateExponent = privateExponent; } public BigInteger getModulus() { return modulus; } public BigInteger getPrivateExponent() { return privateExponent; } } bouncycastle-1.49.orig/jdk1.1/java/security/spec/RSAOtherPrimeInfo.java0000644000175000017500000000363011705654527025264 0ustar ebourgebourg package java.security.spec; import java.math.BigInteger; /** * This class represents the triplet (prime, exponent, and coefficient) * inside RSA's OtherPrimeInfo structure, as defined in the PKCS#1 v2.1. * The ASN.1 syntax of RSA's OtherPrimeInfo is as follows: * *
     * OtherPrimeInfo ::= SEQUENCE {
     *    prime INTEGER,
     *    exponent INTEGER,
     *    coefficient INTEGER
     * }
     * 
    */ public class RSAOtherPrimeInfo extends Object { private BigInteger prime; private BigInteger primeExponent; private BigInteger crtCoefficient; /** * Creates a new RSAOtherPrimeInfo given the prime, primeExponent, * and crtCoefficient as defined in PKCS#1. * * @param prime - the prime factor of n. * @param primeExponent - the exponent. * @param crtCoefficient - the Chinese Remainder Theorem coefficient. * @throws NullPointerException - if any of the parameters, i.e. prime, * primeExponent, crtCoefficient, is null. */ public RSAOtherPrimeInfo( BigInteger prime, BigInteger primeExponent, BigInteger crtCoefficient) { if ( prime == null || primeExponent == null || crtCoefficient == null ) { throw new NullPointerException("Null parameter"); } this.prime = prime; this.primeExponent = primeExponent; this.crtCoefficient = crtCoefficient; } /** * Returns the prime. * * @returns the prime. */ public final BigInteger getPrime() { return prime; } /** * Returns the prime's exponent. * * @returns the primeExponent. */ public final BigInteger getExponent() { return primeExponent; } /** * Returns the prime's crtCoefficient. * * @returns the crtCoefficient. */ public final BigInteger getCrtCoefficient() { return crtCoefficient; } } bouncycastle-1.49.orig/jdk1.1/java/security/spec/AlgorithmParameterSpec.java0000644000175000017500000000011311705654527026417 0ustar ebourgebourg package java.security.spec; public interface AlgorithmParameterSpec { } bouncycastle-1.49.orig/jdk1.1/java/security/interfaces/0000755000175000017500000000000012152033550022330 5ustar ebourgebourgbouncycastle-1.49.orig/jdk1.1/java/security/interfaces/RSAMultiPrimePrivateCrtKey.java0000644000175000017500000000265311705654527030333 0ustar ebourgebourg package java.security.interfaces; import java.math.BigInteger; import java.security.spec.RSAOtherPrimeInfo; /** * The interface to an RSA multi-prime private key, as defined in the * PKCS#1 v2.1, using the Chinese Remainder Theorem (CRT) information values. * * @since 1.4 * @see RSAPrivateKeySpec, RSAMultiPrimePrivateCrtKeySpec, RSAPrivateKey, * RSAPrivateCrtKey */ public interface RSAMultiPrimePrivateCrtKey extends RSAPrivateKey { /** * Returns the public exponent. * * @returns the public exponent. */ public BigInteger getPublicExponent(); /** * Returns the primeP. * * @returns the primeP. */ public BigInteger getPrimeP(); /** * Returns the primeQ. * * @returns the primeQ. */ public BigInteger getPrimeQ(); /** * Returns the primeExponentP. * * @returns the primeExponentP. */ public BigInteger getPrimeExponentP(); /** * Returns the primeExponentQ. * * @returns the primeExponentQ. */ public BigInteger getPrimeExponentQ(); /** * Returns the crtCoefficient. * * @returns the crtCoefficient. */ public BigInteger getCrtCoefficient(); /** * Returns the otherPrimeInfo or null if there are only two prime * factors (p and q). * * @returns the otherPrimeInfo. */ public RSAOtherPrimeInfo[] getOtherPrimeInfo(); } bouncycastle-1.49.orig/jdk1.1/java/security/interfaces/RSAPrivateKey.java0000644000175000017500000000050311705654527025642 0ustar ebourgebourg package java.security.interfaces; import java.math.BigInteger; import java.security.PrivateKey; public interface RSAPrivateKey extends PrivateKey { public static final long serialVersionUID = 6034044314589513430L; public abstract BigInteger getModulus(); public abstract BigInteger getPrivateExponent(); } bouncycastle-1.49.orig/jdk1.1/java/security/interfaces/RSAPublicKey.java0000644000175000017500000000047711705654527025460 0ustar ebourgebourg package java.security.interfaces; import java.math.BigInteger; import java.security.PublicKey; public interface RSAPublicKey extends PublicKey { public static final long serialVersionUID = 7187392471159151072L; public abstract BigInteger getModulus(); public abstract BigInteger getPublicExponent(); } bouncycastle-1.49.orig/jdk1.1/java/security/interfaces/RSAPrivateCrtKey.java0000644000175000017500000000075611705654527026325 0ustar ebourgebourg package java.security.interfaces; import java.math.BigInteger; public interface RSAPrivateCrtKey extends RSAPrivateKey { public static final long serialVersionUID = 6034044314589513430L; public abstract BigInteger getCrtCoefficient(); public abstract BigInteger getPrimeExponentP(); public abstract BigInteger getPrimeExponentQ(); public abstract BigInteger getPrimeP(); public abstract BigInteger getPrimeQ(); public abstract BigInteger getPublicExponent(); } bouncycastle-1.49.orig/jdk1.1/java/security/KeyFactory.java0000644000175000017500000000451711705654526023156 0ustar ebourgebourg package java.security; import java.security.spec.InvalidKeySpecException; import java.security.spec.KeySpec; public class KeyFactory extends Object { private KeyFactorySpi keyFacSpi; private Provider provider; private String algorithm; protected KeyFactory( KeyFactorySpi keyFacSpi, Provider provider, String algorithm) { this.keyFacSpi = keyFacSpi; this.provider = provider; this.algorithm = algorithm; } public final PrivateKey generatePrivate(KeySpec keySpec) throws InvalidKeySpecException { return keyFacSpi.engineGeneratePrivate(keySpec); } public final PublicKey generatePublic(KeySpec keySpec) throws InvalidKeySpecException { return keyFacSpi.engineGeneratePublic(keySpec); } public final String getAlgorithm() { return algorithm; } public static KeyFactory getInstance(String algorithm) throws NoSuchAlgorithmException { try { SecurityUtil.Implementation imp = SecurityUtil.getImplementation("KeyFactory", algorithm, null); if (imp != null) { return new KeyFactory((KeyFactorySpi)imp.getEngine(), imp.getProvider(), algorithm); } throw new NoSuchAlgorithmException("can't find algorithm " + algorithm); } catch (NoSuchProviderException e) { throw new NoSuchAlgorithmException(algorithm + " not found"); } } public static KeyFactory getInstance(String algorithm, String provider) throws NoSuchAlgorithmException, NoSuchProviderException { SecurityUtil.Implementation imp = SecurityUtil.getImplementation("KeyFactory", algorithm, null); if (imp != null) { return new KeyFactory((KeyFactorySpi)imp.getEngine(), imp.getProvider(), algorithm); } throw new NoSuchAlgorithmException("can't find algorithm " + algorithm); } public final KeySpec getKeySpec(Key key, Class keySpec) throws InvalidKeySpecException { return keyFacSpi.engineGetKeySpec(key, keySpec); } public final Provider getProvider() { return provider; } public final Key translateKey(Key key) throws InvalidKeyException { return keyFacSpi.engineTranslateKey(key); } } bouncycastle-1.49.orig/tools/0000755000175000017500000000000012152033551015566 5ustar ebourgebourgbouncycastle-1.49.orig/tools/test/0000755000175000017500000000000012152033551016545 5ustar ebourgebourgbouncycastle-1.49.orig/tools/test/org/0000755000175000017500000000000012152033551017334 5ustar ebourgebourgbouncycastle-1.49.orig/tools/test/org/bouncycastle/0000755000175000017500000000000012152033551022027 5ustar ebourgebourgbouncycastle-1.49.orig/tools/test/org/bouncycastle/tools/0000755000175000017500000000000012152033551023167 5ustar ebourgebourgbouncycastle-1.49.orig/tools/test/org/bouncycastle/tools/openpgp/0000755000175000017500000000000012152033551024637 5ustar ebourgebourgbouncycastle-1.49.orig/tools/test/org/bouncycastle/tools/openpgp/dump/0000755000175000017500000000000012152033551025604 5ustar ebourgebourgbouncycastle-1.49.orig/tools/test/org/bouncycastle/tools/openpgp/dump/PGPDumpTest.java0000644000175000017500000000474210262753174030604 0ustar ebourgebourgpackage org.bouncycastle.tools.openpgp.dump; import junit.framework.TestCase; import org.bouncycastle.tools.openpgp.PGPDump; import org.bouncycastle.tools.openpgp.util.PGPParams; /* * NOTE: This test class _will not work_ in your environment unless you have * the same files in the same places that I do. This is purely for my purposes * to avoid having to run lots of command line programs to make it all work. * * Please don't complain about this code at this stage, I'm going to ignore it anyway. * In the future, I'll update this test case so it will create all the necessary * files so this all works, but don't hold your breath, it's not a priority. * * Jon Eaves */ public class PGPDumpTest extends TestCase { public void testSingleFileParameter() { String file = "e:/usr/home/pgptesting/forboo.gpg"; PGPDump dump = new PGPDump(); PGPParams params = dump.processArguments(new String[]{file}); assertTrue("No errors in processing arguments", !params.isError()); assertNotNull("File exists", params.getInputFile()); } public void testProcessSignedAndEncryptedFile() { String file = "e:/usr/home/pgptesting/formaddy.gpg"; String keyDir = "c:/gnupg"; String passPhrase = "bouncy"; runEncryptedFileTest(file, keyDir, passPhrase); } public void testProcessEncryptedFile() { String file = "e:/usr/home/pgptesting/forboo.gpg"; String keyDir = "c:/gnupg"; String passPhrase = "bouncy"; runEncryptedFileTest(file, keyDir, passPhrase); } public void testProcessEncryptedArmoredFile() { String file = "e:/usr/home/pgptesting/index.html.asc"; String keyDir = "c:/gnupg"; String passPhrase = "bouncy"; runEncryptedFileTest(file, keyDir, passPhrase); } private void runEncryptedFileTest(String file, String keyDir, String passPhrase) { PGPDump dump = new PGPDump(); PGPParams params = dump.processArguments(new String[]{ "-K", keyDir, "-P", passPhrase, file }); if (params.isError()) { System.out.println(params.getErrors()); } assertTrue("Found errors processing arguments", !params.isError()); System.out.println("Dumping the file < "+file+" >"); PGPDumpEngine engine = new PGPDumpEngine(params); engine.process(); System.out.println(); } } bouncycastle-1.49.orig/tools/test/org/bouncycastle/tools/openpgp/rampage/0000755000175000017500000000000012152033551026253 5ustar ebourgebourgbouncycastle-1.49.orig/tools/test/org/bouncycastle/tools/openpgp/rampage/BCRampageTest.java0000644000175000017500000000673210262753174031561 0ustar ebourgebourgpackage org.bouncycastle.tools.openpgp.rampage; import org.bouncycastle.tools.openpgp.BCRampage; import org.bouncycastle.tools.openpgp.util.PGPParams; import junit.framework.TestCase; /* * NOTE: This test class _will not work_ in your environment unless you have * the same files in the same places that I do. This is purely for my purposes * to avoid having to run lots of command line programs to make it all work. * * Please don't complain about this code at this stage, I'm going to ignore it anyway. * In the future, I'll update this test case so it will create all the necessary * files so this all works, but don't hold your breath, it's not a priority. * * Jon Eaves */ public class BCRampageTest extends TestCase { public void testNotProvidingPKR() { String file = "e:/usr/home/pgptesting/tomcat.log"; String recipient = "maddy@eaves.org"; String[] args = new String[]{ "-e", "-R", recipient, file}; PGPParams params = processArgs(args); assertTrue("Found errors processing arguments", !params.isError()); assertNull("Missing the public key", params.getPublicKeyRingFile()); } public void testNotProvidingRecipient() { String file = "e:/usr/home/pgptesting/tomcat.log"; String keyDir = "c:/gnupg"; String[] args = new String[]{ "-e", "-K", keyDir, file}; PGPParams params = processArgs(args); assertTrue("Found errors processing arguments", !params.isError()); assertNull("Missing the recipient", params.getRecipient()); } public void testNotProvidingFile() { String keyDir = "c:/gnupg"; String recipient = "maddy@eaves.org"; String[] args = new String[]{ "-e", "-K", keyDir, "-R", recipient }; PGPParams params = processArgs(args); assertTrue("Found no errors processing arguments", params.isError()); // not an argument error assertNull("Missing the input file", params.getInputFile()); } public void testEncryptFile() { String file = "e:/usr/home/pgptesting/tomcat.log"; String keyDir = "c:/gnupg"; String recipient = "boo@eaves.org"; runEncrypt(file, keyDir, recipient, false); assertTrue("Processing completed successfully", true); } public void testAsciiArmorEncryptFile() { String file = "e:/usr/home/pgptesting/index.html"; String keyDir = "c:/gnupg"; String recipient = "jon@eaves.org"; runEncrypt(file, keyDir, recipient, true); assertTrue("Processing completed successfully", true); } private void runEncrypt(String file, String keyDir, String recipient, boolean armor) { String[] args = new String[]{ "-e", "-K", keyDir, "-R", recipient, file }; if (armor) { args[0] = "-ea"; } PGPParams params = processArgs(args); assertTrue("Found errors processing arguments", !params.isError()); runEngine(params); } private void runEngine(PGPParams params) { PGPRampageEngine engine = new PGPRampageEngine(params); engine.process(); } private PGPParams processArgs(String[] args) { BCRampage rampage = new BCRampage(); PGPParams params = rampage.processArguments(args); if (params.isError()) { System.out.println(params.getErrors()); } return params; } } bouncycastle-1.49.orig/tools/src/0000755000175000017500000000000012152033551016355 5ustar ebourgebourgbouncycastle-1.49.orig/tools/src/org/0000755000175000017500000000000012152033551017144 5ustar ebourgebourgbouncycastle-1.49.orig/tools/src/org/bouncycastle/0000755000175000017500000000000012152033551021637 5ustar ebourgebourgbouncycastle-1.49.orig/tools/src/org/bouncycastle/tools/0000755000175000017500000000000012152033551022777 5ustar ebourgebourgbouncycastle-1.49.orig/tools/src/org/bouncycastle/tools/openpgp/0000755000175000017500000000000012152033551024447 5ustar ebourgebourgbouncycastle-1.49.orig/tools/src/org/bouncycastle/tools/openpgp/util/0000755000175000017500000000000012152033551025424 5ustar ebourgebourgbouncycastle-1.49.orig/tools/src/org/bouncycastle/tools/openpgp/util/PGPParams.java0000644000175000017500000001052410263207707030072 0ustar ebourgebourgpackage org.bouncycastle.tools.openpgp.util; import java.io.File; import java.util.ArrayList; import java.util.Collection; public class PGPParams { public static final String BINARY_SUFFIX = ".gpg"; public static final String ASCII_SUFFIX = ".asc"; private boolean _encrypting = false; private boolean _decrypting = false; private boolean _signing = false; private boolean _verify = false; private File _secretKeyRingFile = null; private File _publicKeyRingFile = null; private File _inputFile = null; private String _outputFilename = null; private String _passPhrase = null; private String _keyPassPhrase = null; private boolean _mdcRequired = false; private boolean _pgp2Compatible = false; private String _recipient = null; private String _signor = null; private boolean _armor = false; private boolean _error = false; private Collection _errorMgs = null; public boolean isError() { return _error; } public void addError(String string) { if (_errorMgs == null) { _errorMgs = new ArrayList(); _error = true; } _errorMgs.add(string); } public Collection getErrors() { return _errorMgs; } public boolean isEncrypting() { return _encrypting; } public void setEncrypting(boolean encrypting) { _encrypting = encrypting; } public File getInputFile() { return _inputFile; } public void setInputFile(File inputFile) { _inputFile = inputFile; } public String getOutputFilename() { return _outputFilename; } public void setOutputFilename(String outputFilename) { _outputFilename = outputFilename; } public String getKeyPassPhrase() { return _keyPassPhrase; } public void setKeyPassPhrase(String keyPassPhrase) { _keyPassPhrase = keyPassPhrase; } public void setPassPhrase(String passPhrase) { _passPhrase = passPhrase; } public String getPassPhrase() { return _passPhrase; } public File getPublicKeyRingFile() { return _publicKeyRingFile; } public void setPublicKeyRingFile(File publicKeyRingFile) { _publicKeyRingFile = publicKeyRingFile; } public File getSecretKeyRingFile() { return _secretKeyRingFile; } public void setSecretKeyRingFile(File secretKeyRingFile) { _secretKeyRingFile = secretKeyRingFile; } public String getRecipient() { return _recipient; } public void setRecipient(String recipient) { _recipient = recipient; } public String getSignor() { return _signor; } public void setSignor(String signor) { _signor = signor; } public boolean isSigning() { return _signing; } public void setSigning(boolean signing) { _signing = signing; } public void setMDCRequired(boolean mdc) { _mdcRequired = mdc; if (mdc) { // Cannot be PGP 2 compatible if MDC required _pgp2Compatible = false; } } public boolean isMDCRequired() { return _mdcRequired; } public void setPGP2Compatible(boolean pgp2) { _pgp2Compatible = pgp2; if (pgp2) { // Cannot have MDC if PGP 2 compatible _mdcRequired = false; } } public boolean isPGP2Compatible() { return _pgp2Compatible; } public void setVerify(boolean verify) { _verify = verify; } public boolean isVerify() { return _verify; } public void setDecrypting(boolean decrypting) { _decrypting = decrypting; } public boolean isDecrypting() { return _decrypting; } public void setAsciiArmor(boolean armor) { _armor = armor; } public boolean isAsciiArmor() { return _armor; } } bouncycastle-1.49.orig/tools/src/org/bouncycastle/tools/openpgp/util/ProcessingEngine.java0000644000175000017500000000034710262753174031547 0ustar ebourgebourgpackage org.bouncycastle.tools.openpgp.util; import java.util.Collection; /** * */ public interface ProcessingEngine { public void process(); public boolean isError(); public Collection errorMessages(); }bouncycastle-1.49.orig/tools/src/org/bouncycastle/tools/openpgp/util/PGPCmdLineArgProcessor.java0000644000175000017500000001137210263207707032516 0ustar ebourgebourgpackage org.bouncycastle.tools.openpgp.util; import java.io.File; /** * */ public class PGPCmdLineArgProcessor { private static final String PGP_DEFAULT_PUBLIC_RING = "pubring.gpg"; private static final String PGP_DEFAULT_SECRET_RING = "secring.gpg"; public PGPParams processArguments(String[] args) { PGPParams rv = new PGPParams(); int count = 0; while (count != args.length) { String arg = args[count++]; if (arg.equals("-e")) { rv.setEncrypting(true); rv.setAsciiArmor(false); } else if (arg.equals("-ea")) { rv.setEncrypting(true); rv.setAsciiArmor(true); } else if (arg.equals("-s")) { rv.setSigning(true); rv.setAsciiArmor(false); } else if (arg.equals("-sa")) { rv.setSigning(true); rv.setAsciiArmor(true); } else if (arg.equals("-se")) { rv.setSigning(true); rv.setEncrypting(true); rv.setAsciiArmor(false); } else if (arg.equals("-sea")) { rv.setSigning(true); rv.setEncrypting(true); rv.setAsciiArmor(true); } else if (arg.equals("-v")) { rv.setVerify(true); } else if (arg.equals("-d")) { rv.setDecrypting(true); } else if (arg.equals("-K")) { String keyRingDir = args[count++]; if (!checkDirectory(keyRingDir)) { rv.addError("Cannot find key ring directory [" + keyRingDir + "]"); } String pubRing = keyRingDir + File.separator + PGP_DEFAULT_PUBLIC_RING; String secRing = keyRingDir + File.separator + PGP_DEFAULT_SECRET_RING; processPubRing(pubRing, rv); processSecRing(secRing, rv); } else if (arg.equals("-skr")) { String fileName = args[count++]; processSecRing(fileName, rv); } else if (arg.equals("-pkr")) { String fileName = args[count++]; processPubRing(fileName, rv); } else if (arg.equals("-P")) { rv.setKeyPassPhrase(args[count++]); } else if (arg.equals("-R")) { rv.setRecipient(args[count++]); } else if (arg.equals("-u")) { rv.setSignor(args[count++]); } else if (arg.equals("-o")) { rv.setOutputFilename(args[count++]); } else if (arg.equals("-pbe")) { rv.setPassPhrase(args[count++]); } else if (arg.equals("-mdc")) // if specified, set to true { rv.setMDCRequired(true); } else if (arg.equals("-pgp2")) // if specified, set to true { rv.setPGP2Compatible(true); } else if (arg.startsWith("-")) { rv.addError("Unknown option [" + arg + "]"); } else { String fileName = arg; File file = new File(fileName); if (!file.exists()) { rv.addError("Input file does not exist [" + fileName + "]"); } else { rv.setInputFile(file); } } } return rv; } private void processPubRing(String fileName, PGPParams rv) { File file = new File(fileName); if (!file.exists()) { rv.addError("Public Key Ring file does not exist [" + fileName + "]"); } else { rv.setPublicKeyRingFile(file); } } private void processSecRing(String fileName, PGPParams rv) { File file = new File(fileName); if (!file.exists()) { rv.addError("Secret Key Ring file does not exist [" + fileName + "]"); } else { rv.setSecretKeyRingFile(new File(fileName)); } } private boolean checkDirectory(String keyRingDir) { File dir = new File(keyRingDir); if (dir.exists() && dir.isDirectory()) { return true; } return false; } } bouncycastle-1.49.orig/tools/src/org/bouncycastle/tools/openpgp/util/package.html0000644000175000017500000000016310262753174027717 0ustar ebourgebourg Utility classes used by all the tools and their support libraries. bouncycastle-1.49.orig/tools/src/org/bouncycastle/tools/openpgp/PGPPubringDump.java0000644000175000017500000000705710262753174030140 0ustar ebourgebourgpackage org.bouncycastle.tools.openpgp; import java.io.*; import java.security.PrivateKey; import java.security.PublicKey; import java.security.Security; import java.util.Iterator; import org.bouncycastle.bcpg.PublicKeyAlgorithmTags; import org.bouncycastle.jce.provider.BouncyCastleProvider; import org.bouncycastle.openpgp.PGPPublicKey; import org.bouncycastle.openpgp.PGPPublicKeyRing; import org.bouncycastle.openpgp.PGPPublicKeyRingCollection; import org.bouncycastle.openpgp.PGPUtil; import org.bouncycastle.util.encoders.Hex; /** * Basic class which just lists the contents of the public key file passed * as an argument. If the file contains more than one "key ring" they are * listed in the order found. */ public class PGPPubringDump { public static String getAlgorithm( int algId) { switch (algId) { case PublicKeyAlgorithmTags.RSA_GENERAL: return "RSA_GENERAL"; case PublicKeyAlgorithmTags.RSA_ENCRYPT: return "RSA_ENCRYPT"; case PublicKeyAlgorithmTags.RSA_SIGN: return "RSA_SIGN"; case PublicKeyAlgorithmTags.ELGAMAL_ENCRYPT: return "ELGAMAL_ENCRYPT"; case PublicKeyAlgorithmTags.DSA: return "DSA"; case PublicKeyAlgorithmTags.EC: return "EC"; case PublicKeyAlgorithmTags.ECDSA: return "ECDSA"; case PublicKeyAlgorithmTags.ELGAMAL_GENERAL: return "ELGAMAL_GENERAL"; case PublicKeyAlgorithmTags.DIFFIE_HELLMAN: return "DIFFIE_HELLMAN"; } return "unknown"; } public static void main(String[] args) throws Exception { Security.addProvider(new BouncyCastleProvider()); PGPPublicKey pubKey = null; PrivateKey privKey = null; PGPUtil.setDefaultProvider("BC"); // // Read the public key rings // PGPPublicKeyRingCollection pubRings = new PGPPublicKeyRingCollection( PGPUtil.getDecoderStream(new FileInputStream(args[0]))); Iterator rIt = pubRings.getKeyRings(); while (rIt.hasNext()) { PGPPublicKeyRing pgpPub = (PGPPublicKeyRing)rIt.next(); try { pubKey = pgpPub.getPublicKey(); } catch (Exception e) { e.printStackTrace(); continue; } long pgpKeyID = 0; PublicKey pKey = null; Iterator it = pgpPub.getPublicKeys(); boolean first = true; while (it.hasNext()) { PGPPublicKey pgpKey = (PGPPublicKey)it.next(); if (first) { System.out.println("Key ID: " + Long.toHexString(pgpKey.getKeyID())); first = false; } else { System.out.println("Key ID: " + Long.toHexString(pgpKey.getKeyID()) + " (subkey)"); } Iterator iid = pgpKey.getUserIDs(); while (iid.hasNext()) { System.out.println(" Id: " + (String) iid.next()); } System.out.println(" Algorithm: " + getAlgorithm(pgpKey.getAlgorithm())); System.out.println(" Fingerprint: " + new String(Hex.encode(pgpKey.getFingerprint()))); } } } } bouncycastle-1.49.orig/tools/src/org/bouncycastle/tools/openpgp/BCRampage.java0000644000175000017500000000307710262753174027114 0ustar ebourgebourgpackage org.bouncycastle.tools.openpgp; import java.security.Security; import org.bouncycastle.jce.provider.BouncyCastleProvider; import org.bouncycastle.tools.openpgp.rampage.PGPRampageEngine; import org.bouncycastle.tools.openpgp.util.PGPCmdLineArgProcessor; import org.bouncycastle.tools.openpgp.util.PGPParams; /** * A general tool for manipulating PGP messages. */ public class BCRampage { private boolean _verbose = true; public PGPParams processArguments(String[] args) { PGPCmdLineArgProcessor cmdLine = new PGPCmdLineArgProcessor(); PGPParams rv = cmdLine.processArguments(args); if (rv.getInputFile() == null) { rv.addError("Input file must be specified"); } return rv; } public static void main(String[] args) { String usage = "usage: BCRampage [ -e[a] | -d | -s | -v ] " + "[ -skr ] [ -pkr ] [ -K ] [ -P ]" + "[ -R ] [ -pbe ] [ -mdc ] fileName"; Security.addProvider(new BouncyCastleProvider()); BCRampage cmdLineProcessor = new BCRampage(); PGPParams params = cmdLineProcessor.processArguments(args); if (params.isError()) { System.out.println(usage); System.out.println("Error details - "); System.out.println(params.getErrors()); System.exit(1); } PGPRampageEngine engine = new PGPRampageEngine(params); engine.process(); } } bouncycastle-1.49.orig/tools/src/org/bouncycastle/tools/openpgp/dump/0000755000175000017500000000000012152033551025414 5ustar ebourgebourgbouncycastle-1.49.orig/tools/src/org/bouncycastle/tools/openpgp/dump/PGPDumpEngine.java0000644000175000017500000003514510505106273030673 0ustar ebourgebourgpackage org.bouncycastle.tools.openpgp.dump; import java.io.FileInputStream; import java.io.IOException; import java.io.InputStream; import java.util.Collection; import java.util.Iterator; import org.bouncycastle.openpgp.PGPCompressedData; import org.bouncycastle.openpgp.PGPEncryptedDataList; import org.bouncycastle.openpgp.PGPException; import org.bouncycastle.openpgp.PGPLiteralData; import org.bouncycastle.openpgp.PGPObjectFactory; import org.bouncycastle.openpgp.PGPOnePassSignature; import org.bouncycastle.openpgp.PGPOnePassSignatureList; import org.bouncycastle.openpgp.PGPPublicKey; import org.bouncycastle.openpgp.PGPPublicKeyEncryptedData; import org.bouncycastle.openpgp.PGPPublicKeyRingCollection; import org.bouncycastle.openpgp.PGPSecretKey; import org.bouncycastle.openpgp.PGPSecretKeyRingCollection; import org.bouncycastle.openpgp.PGPSignature; import org.bouncycastle.openpgp.PGPSignatureList; import org.bouncycastle.openpgp.PGPUtil; import org.bouncycastle.tools.openpgp.util.PGPParams; import org.bouncycastle.tools.openpgp.util.ProcessingEngine; /** * */ public class PGPDumpEngine implements ProcessingEngine { private PGPParams _params = null; private PGPSecretKeyRingCollection _pgpSecRingCache; private PGPPublicKeyRingCollection _pgpPubRingCache; public PGPDumpEngine(PGPParams params) { _params = params; } public void process() { InputStream rawFile; try { rawFile = new FileInputStream(_params.getInputFile()); InputStream openPGPMessage = PGPUtil.getDecoderStream(rawFile); PGPObjectFactory pgpFact = new PGPObjectFactory(openPGPMessage); Object nextObject = pgpFact.nextObject(); while (nextObject != null) { if (nextObject instanceof PGPEncryptedDataList) { System.out.println("Found an encrypted OpenPGP message...\n"); processEncryptedDataList((PGPEncryptedDataList) nextObject); } else if (nextObject instanceof PGPCompressedData) { System.out.println("Found unencrypted compressed data...\n"); processUnencryptedData((PGPCompressedData) nextObject); } else { System.out.println("Found an object called: " + nextObject.getClass() + "\n"); } nextObject = pgpFact.nextObject(); } } catch (Exception unexpected) { unexpected.printStackTrace(); } } private void processEncryptedDataList(PGPEncryptedDataList edl) throws Exception { PGPPublicKeyEncryptedData pked = findValidPublicKeyEncryptedData(edl); if (pked == null) { System.out.println("Corresponding secret key not found, cannot process remainder"); return; } PGPSecretKey pgpSecKey = _pgpSecRingCache.getSecretKey(pked.getKeyID()); char[] passPhrase = _params.getKeyPassPhrase().toCharArray(); InputStream decryptedDataList = null; PGPObjectFactory plainFact = null; PGPCompressedData cData = null; PGPObjectFactory plainObjectFactory = null; Object message = null; decryptedDataList = pked.getDataStream(pgpSecKey.extractPrivateKey(passPhrase, "BC"), "BC"); plainFact = new PGPObjectFactory(decryptedDataList); message = plainFact.nextObject(); if (message instanceof PGPCompressedData) { cData = (PGPCompressedData) message; } else { System.out.println("Can only process compressed data. " + " Please report this message to feedback-crypto@bouncycastle.org"); return; } plainObjectFactory = new PGPObjectFactory(cData.getDataStream()); message = plainObjectFactory.nextObject(); while (message != null) { if (message instanceof PGPLiteralData) { PGPLiteralData ld = (PGPLiteralData) message; // ld should be a PGPInputStreamPacket when the marker interface is implemented readAndDiscardInputStreamPacket(ld); System.out.println("Found the data for the file: " + ld.getFileName() + "\n"); } else if (message instanceof PGPOnePassSignatureList) { PGPOnePassSignatureList onePassSigList = (PGPOnePassSignatureList) message; processOnePassSignatureList(onePassSigList); } else if (message instanceof PGPSignatureList) { PGPSignatureList sigList = (PGPSignatureList) message; processSignatureList(sigList); } else { System.out.println("Found an *unexpected* object called: " + message.getClass()); } message = plainObjectFactory.nextObject(); } } private void processUnencryptedData(PGPCompressedData cData) throws Exception { PGPObjectFactory plainObjectFactory = null; Object message = null; plainObjectFactory = new PGPObjectFactory(cData.getDataStream()); message = plainObjectFactory.nextObject(); while (message != null) { if (message instanceof PGPLiteralData) { PGPLiteralData ld = (PGPLiteralData) message; // ld should be a PGPInputStreamPacket when the marker interface is implemented readAndDiscardInputStreamPacket(ld); System.out.println("Found the data for the file: " + ld.getFileName() + "\n"); } else if (message instanceof PGPOnePassSignatureList) { PGPOnePassSignatureList onePassSigList = (PGPOnePassSignatureList) message; processOnePassSignatureList(onePassSigList); } else if (message instanceof PGPSignatureList) { PGPSignatureList sigList = (PGPSignatureList) message; processSignatureList(sigList); } else { System.out.println("Found an *unexpected* object called: " + message.getClass()); } message = plainObjectFactory.nextObject(); } } private void processSignatureList(PGPSignatureList sigList) { for (int i = 0; i < sigList.size(); i++) { Object obj = sigList.get(i); if (obj instanceof PGPSignature) { PGPSignature sig = (PGPSignature) obj; System.out.println(pgpSigDump(sig)); } else { System.out.println("Found an *unexpected* object called: " + obj.getClass()); } } } private String pgpSigDump(PGPSignature sig) { if (sig == null) { return "Found null Signature"; } StringBuffer sb = new StringBuffer("Found Signature: "); sb.append(asHex(sig.getKeyID())); sb.append('\n'); sb.append("Creation: ").append(sig.getCreationTime()).append('\n'); PGPPublicKey pubKey = findPublicKey(sig.getKeyID()); if (pubKey != null) { userDataDump(sb, pubKey); } else { sb.append("Cannot find associated public key\n"); } return sb.toString(); } // TODO: ld should be a PGPInputStreamPacket private void readAndDiscardInputStreamPacket(PGPLiteralData ld) { InputStream is = ld.getInputStream(); try { int ch; while ((ch = is.read()) >= 0) { // do nothing; } } catch (IOException unexpected) { unexpected.printStackTrace(); } } private void processOnePassSignatureList(PGPOnePassSignatureList sigList) { if (sigList == null) { return; } System.out.println("-- start 1PS list"); for (int i = 0; i < sigList.size(); i++) { PGPOnePassSignature sig = (PGPOnePassSignature) sigList.get(i); if (i > 0) { System.out.print("\n"); } System.out.print(pgpOnePassSigDump(sig)); } System.out.println("-- end 1PS list\n"); } private String pgpOnePassSigDump(PGPOnePassSignature sig) { if (sig == null) { return "Found null One-Pass Signature\n"; } StringBuffer sb = new StringBuffer("Found One-Pass Signature: "); sb.append(asHex(sig.getKeyID())); sb.append('\n'); // sb.append("Creation: ").append(sig.getCreationTime()).append("\n"); PGPPublicKey pubKey = findPublicKey(sig.getKeyID()); if (pubKey != null) { userDataDump(sb, pubKey); } else { sb.append("Cannot find associated public key\n"); } return sb.toString(); } private PGPPublicKeyEncryptedData findValidPublicKeyEncryptedData(PGPEncryptedDataList edl) { PGPSecretKey pgpSecKey = null; int count = 0; PGPPublicKeyEncryptedData pked = null; while (count != edl.size()) { Object obj = edl.get(count); if (obj instanceof PGPPublicKeyEncryptedData) { System.out.print("Found some PGPPublicKeyEncryptedData, "); pked = (PGPPublicKeyEncryptedData) obj; long keyId = pked.getKeyID(); System.out.println("Encrypted by " + asHex(keyId)); pgpSecKey = findSecretKey(keyId); if (pgpSecKey != null) { // TODO: Produce more information here about the key, such as user id System.out.println("Found matching key " + asHex(pgpSecKey.getKeyID()) + ": "); System.out.println(secKeyDump(pgpSecKey)); break; } else { System.out.println(""); } } else { System.out.println("Found an object in the PGPEncryptedDataList of: " + obj.getClass()); } count++; } return pked; } private String secKeyDump(PGPSecretKey pgpSecKey) { if (pgpSecKey == null) { return "Key is null"; } StringBuffer sb = new StringBuffer("SecretKey: "); sb.append(asHex(pgpSecKey.getKeyID())); sb.append('\n'); PGPPublicKey pubKey = findPublicKey(pgpSecKey.getKeyID()); // need to grab the public key information or something // for data about the "master key" if (pubKey != null) { userDataDump(sb, pubKey); } else { sb.append("Cannot find associated public key\n"); } return sb.toString(); } private String pubKeyDump(PGPPublicKey pubKey) { if (pubKey == null) { return "Key is null"; } StringBuffer sb = new StringBuffer("PublicKey: "); sb.append(asHex(pubKey.getKeyID())); sb.append('\n'); userDataDump(sb, pubKey); return sb.toString(); } private void userDataDump(StringBuffer sb, PGPPublicKey pubKey) { Iterator i = pubKey.getUserIDs(); sb.append("Id list: "); if ((i != null) && i.hasNext()) { while (i.hasNext()) { String id = (String) i.next(); sb.append('\"').append(id).append("\" "); } } else { sb.append(""); } sb.append('\n'); /* i = pubKey.getUserAttributes(); sb.append("Attribute list: "); if ((i != null) && i.hasNext()) { while (i.hasNext()) { String id = (String) i.next(); sb.append("\"").append(id).append("\" "); } } else { sb.append(""); } */ } private PGPPublicKey findPublicKey(long keyID) { if (_pgpPubRingCache == null && _params.getPublicKeyRingFile() != null) { try { _pgpPubRingCache = new PGPPublicKeyRingCollection( PGPUtil.getDecoderStream(new FileInputStream( _params.getPublicKeyRingFile()))); } catch (Exception unexpected) { System.out.println("Error occurred processing the public key ring:"); unexpected.printStackTrace(); } } PGPPublicKey key = null; if (_pgpPubRingCache != null) { try { key = _pgpPubRingCache.getPublicKey(keyID); } catch (PGPException unexpected) { unexpected.printStackTrace(); } } return key; } private PGPSecretKey findSecretKey(long keyID) { PGPSecretKeyRingCollection keyRing = null; if (_pgpSecRingCache == null && _params.getSecretKeyRingFile() != null) { try { _pgpSecRingCache = new PGPSecretKeyRingCollection( PGPUtil.getDecoderStream(new FileInputStream( _params.getSecretKeyRingFile()))); } catch (Exception unexpected) { System.out.println("Error occurred processing the secret key ring:"); unexpected.printStackTrace(); } } PGPSecretKey key = null; if (_pgpSecRingCache != null) { try { key = _pgpSecRingCache.getSecretKey(keyID); } catch (PGPException unexpected) { unexpected.printStackTrace(); } } return key; } private String asHex(long l) { return Long.toHexString(l).substring(8); } // TODO: Implement these methods so that can be used by the CmdLineProcessors // and the test cases. public boolean isError() { return false; } public Collection errorMessages() { return null; } } bouncycastle-1.49.orig/tools/src/org/bouncycastle/tools/openpgp/dump/package.html0000644000175000017500000000011510262753174027704 0ustar ebourgebourg Support classes for PGPDump. bouncycastle-1.49.orig/tools/src/org/bouncycastle/tools/openpgp/rampage/0000755000175000017500000000000012152033551026063 5ustar ebourgebourgbouncycastle-1.49.orig/tools/src/org/bouncycastle/tools/openpgp/rampage/PGPRampageEngine.java0000644000175000017500000014104010263207707032006 0ustar ebourgebourgpackage org.bouncycastle.tools.openpgp.rampage; import java.io.ByteArrayOutputStream; import java.io.File; import java.io.FileInputStream; import java.io.FileOutputStream; import java.io.IOException; import java.io.InputStream; import java.io.OutputStream; import java.security.NoSuchProviderException; import java.security.SecureRandom; import java.util.Collection; import java.util.Date; import java.util.Iterator; import org.bouncycastle.bcpg.ArmoredInputStream; import org.bouncycastle.bcpg.ArmoredOutputStream; import org.bouncycastle.bcpg.BCPGOutputStream; import org.bouncycastle.openpgp.PGPCompressedData; import org.bouncycastle.openpgp.PGPCompressedDataGenerator; import org.bouncycastle.openpgp.PGPEncryptedData; import org.bouncycastle.openpgp.PGPEncryptedDataGenerator; import org.bouncycastle.openpgp.PGPEncryptedDataList; import org.bouncycastle.openpgp.PGPException; import org.bouncycastle.openpgp.PGPKeyValidationException; import org.bouncycastle.openpgp.PGPLiteralData; import org.bouncycastle.openpgp.PGPLiteralDataGenerator; import org.bouncycastle.openpgp.PGPObjectFactory; import org.bouncycastle.openpgp.PGPOnePassSignature; import org.bouncycastle.openpgp.PGPOnePassSignatureList; import org.bouncycastle.openpgp.PGPPBEEncryptedData; import org.bouncycastle.openpgp.PGPPrivateKey; import org.bouncycastle.openpgp.PGPPublicKey; import org.bouncycastle.openpgp.PGPPublicKeyEncryptedData; import org.bouncycastle.openpgp.PGPPublicKeyRing; import org.bouncycastle.openpgp.PGPPublicKeyRingCollection; import org.bouncycastle.openpgp.PGPSecretKey; import org.bouncycastle.openpgp.PGPSecretKeyRing; import org.bouncycastle.openpgp.PGPSecretKeyRingCollection; import org.bouncycastle.openpgp.PGPSignature; import org.bouncycastle.openpgp.PGPSignatureGenerator; import org.bouncycastle.openpgp.PGPV3SignatureGenerator; import org.bouncycastle.openpgp.PGPSignatureList; import org.bouncycastle.openpgp.PGPSignatureSubpacketGenerator; import org.bouncycastle.openpgp.PGPUtil; import org.bouncycastle.tools.openpgp.util.PGPParams; import org.bouncycastle.tools.openpgp.util.ProcessingEngine; /** * A general tool for manipulating PGP objects. */ public class PGPRampageEngine implements ProcessingEngine { private boolean _verbose = true; private PGPParams _params = null; public PGPRampageEngine(PGPParams params) { _params = params; } // Do the job! public void process() { boolean error = false; if (_params == null) { System.out.println("null parameters, much bad"); return; } try { if (_params.isEncrypting() && _params.isSigning()) { if ((_params.getPublicKeyRingFile() != null) && (_params.getSecretKeyRingFile() != null) && (_params.getRecipient() != null) && (_params.getKeyPassPhrase() != null)) { File inFile = _params.getInputFile(); String inputFileName = inFile.getAbsolutePath(); String fileSuffix = _params.isAsciiArmor()? PGPParams.ASCII_SUFFIX: PGPParams.BINARY_SUFFIX; String outputFileName = _params.getOutputFilename(); if (outputFileName == null) { outputFileName = inputFileName + fileSuffix; } FileInputStream publicRing = new FileInputStream(_params.getPublicKeyRingFile()); FileInputStream secretRing = new FileInputStream(_params.getSecretKeyRingFile()); char[] pass = _params.getKeyPassPhrase().toCharArray(); encryptAndSignFile(outputFileName, inFile, publicRing, secretRing, _params.getRecipient(), _params.getSignor(), pass, _params.isAsciiArmor(), _params.isMDCRequired(), _params.isPGP2Compatible()); // Blank out passphrase in memory - no longer needed blank(pass); // Close the files publicRing.close(); secretRing.close(); } else { System.out.println("Encrypt and sign could not be completed due to lack of information"); error = true; } } else if (_params.isEncrypting()) { if ((_params.getPublicKeyRingFile() != null) && (_params.getRecipient() != null)) { File inFile = _params.getInputFile(); String inputFileName = inFile.getAbsolutePath(); String fileSuffix = _params.isAsciiArmor()? PGPParams.ASCII_SUFFIX: PGPParams.BINARY_SUFFIX; String outputFileName = _params.getOutputFilename(); if (outputFileName == null) { outputFileName = inputFileName + fileSuffix; } FileInputStream publicRing = new FileInputStream(_params.getPublicKeyRingFile()); encryptFile(outputFileName, inFile, publicRing, _params.getRecipient(), _params.isAsciiArmor(), _params.isMDCRequired(), _params.isPGP2Compatible()); // Close the files publicRing.close(); } else { System.out.println("Encryption could not be completed due to lack of information"); error = true; } } else if (_params.isSigning()) { if ((_params.getPublicKeyRingFile() != null) && (_params.getSecretKeyRingFile() != null) && (_params.getKeyPassPhrase() != null)) { File inFile = _params.getInputFile(); String inputFileName = inFile.getAbsolutePath(); String fileSuffix = _params.isAsciiArmor()? PGPParams.ASCII_SUFFIX: PGPParams.BINARY_SUFFIX; String outputFileName = _params.getOutputFilename(); if (outputFileName == null) { outputFileName = inputFileName + fileSuffix; } FileInputStream publicRing = new FileInputStream(_params.getPublicKeyRingFile()); FileInputStream secretRing = new FileInputStream(_params.getSecretKeyRingFile()); char[] pass = _params.getKeyPassPhrase().toCharArray(); signFile(outputFileName, inFile, publicRing, secretRing, _params.getSignor(), pass, _params.isAsciiArmor(), _params.isPGP2Compatible()); // Blank out passphrase in memory - no longer needed blank(pass); // Close the files publicRing.close(); secretRing.close(); } else { System.out.println("Both keyrings and passphrase are required for signing"); error = true; } } else if (_params.isDecrypting()) { if (((_params.getSecretKeyRingFile() != null) || (_params.getPassPhrase() != null)) && (_params.getPublicKeyRingFile() != null)) { String outputFileName = _params.getOutputFilename(); FileInputStream inFile = new FileInputStream(_params.getInputFile()); char[] pass; if (_params.getSecretKeyRingFile() != null) { FileInputStream publicRing = new FileInputStream(_params.getPublicKeyRingFile()); FileInputStream secretRing = new FileInputStream(_params.getSecretKeyRingFile()); pass = _params.getKeyPassPhrase().toCharArray(); decryptKeyBasedFile(outputFileName, inFile, publicRing, secretRing, pass, _params.isMDCRequired()); // Close the files publicRing.close(); secretRing.close(); } else { pass = _params.getPassPhrase().toCharArray(); decryptPBEBasedFile(outputFileName, inFile, pass, _params.isMDCRequired()); } // Blank out passphrase in memory - no longer needed blank(pass); // Close the files inFile.close(); } else { System.out.println("Decryption could not be completed due to lack of information"); error = true; } } else if (_params.isVerify()) { if (_params.getPublicKeyRingFile() != null) { String outputFileName = _params.getOutputFilename(); FileInputStream inFile = new FileInputStream(_params.getInputFile()); FileInputStream publicRing = new FileInputStream(_params.getPublicKeyRingFile()); verifyFile(outputFileName, inFile, publicRing); // Close the files publicRing.close(); inFile.close(); } else { System.out.println("Public keyring is required for signature verification"); error = true; } } else { System.out.println("Operation not implemented - please wait"); error = true; } } catch (PGPException e) { Exception ue = e.getUnderlyingException(); if (ue != null) { System.err.println("Error: " + e.getMessage() + " - " + ue.toString()); } else { System.err.println("Error: " + e.getMessage()); } error = true; } catch (Exception e) { System.err.println(e.toString()); error = true; } if (error) { // System.out.println("error!"); System.exit(1); } } /** * Encrypt and sign the specified input file */ public void encryptAndSignFile(String outputFilename, File inFile, InputStream publicRing, InputStream secretRing, String recipient, String signor, char[] passwd, boolean armor, boolean withIntegrityCheck, boolean oldFormat) throws PGPException { try { // Get the public keyring PGPPublicKeyRingCollection pubRing = new PGPPublicKeyRingCollection( PGPUtil.getDecoderStream(publicRing)); // Get the secret keyring PGPSecretKeyRingCollection secRing = new PGPSecretKeyRingCollection( PGPUtil.getDecoderStream(secretRing)); // Find the recipient's key PGPPublicKey encKey = readPublicKey(pubRing, recipient, true); if (encKey.isRevoked()) { String keyId = Long.toHexString(encKey.getKeyID()).substring(8); throw new PGPException("Encryption key (0x"+keyId+") has been revoked"); } // Find the signing key PGPPublicKey publicKey; PGPSecretKey secretKey; if (signor != null) { publicKey = readPublicKey(pubRing, signor, false); secretKey = findSecretKey(secRing, publicKey.getKeyID(), true); } else { // Just look for the first signing key on the secret keyring (if any) secretKey = findSigningKey(secRing); publicKey = findPublicKey(pubRing, secretKey.getKeyID(), false); } if (publicKey.isRevoked()) { String keyId = Long.toHexString(publicKey.getKeyID()).substring(8); throw new PGPException("Signing key (0x"+keyId+") has been revoked"); } PGPPrivateKey privateKey = secretKey.extractPrivateKey(passwd, "BC"); // Sign the data into an in-memory stream ByteArrayOutputStream bOut = new ByteArrayOutputStream(); if (oldFormat) { signDataV3(inFile, bOut, publicKey, privateKey); } else { signData(inFile, bOut, publicKey, privateKey); } // Now encrypt the result PGPEncryptedDataGenerator cPk = oldFormat? new PGPEncryptedDataGenerator(PGPEncryptedData.CAST5, new SecureRandom(), oldFormat, "BC"): new PGPEncryptedDataGenerator(PGPEncryptedData.CAST5, withIntegrityCheck, new SecureRandom(), "BC"); cPk.addMethod(encKey); byte[] bytes = bOut.toByteArray(); OutputStream out = new FileOutputStream(outputFilename); OutputStream aOut = armor? new ArmoredOutputStream(out): out; OutputStream cOut = cPk.open(aOut, bytes.length); cOut.write(bytes); cPk.close(); if (armor) { aOut.close(); } out.close(); } catch (PGPException e) { throw e; } catch (Exception e) { throw new PGPException("Error in encryption", e); } } /** * Encrypt the specified input file */ public void encryptFile(String outputFilename, File inFile, InputStream publicRing, String recipient, boolean armor, boolean withIntegrityCheck, boolean oldFormat) throws PGPException { try { // Get the public keyring PGPPublicKeyRingCollection pubRing = new PGPPublicKeyRingCollection( PGPUtil.getDecoderStream(publicRing)); // Find the recipient's key PGPPublicKey encKey = readPublicKey(pubRing, recipient, true); if (encKey.isRevoked()) { String keyId = Long.toHexString(encKey.getKeyID()).substring(8); throw new PGPException("Encryption key (0x"+keyId+") has been revoked"); } // Compress the data into an in-memory stream ByteArrayOutputStream bOut = new ByteArrayOutputStream(); compressData(inFile, bOut, oldFormat); // Now encrypt the result PGPEncryptedDataGenerator cPk = oldFormat? new PGPEncryptedDataGenerator(PGPEncryptedData.CAST5, new SecureRandom(), oldFormat, "BC"): new PGPEncryptedDataGenerator(PGPEncryptedData.CAST5, withIntegrityCheck, new SecureRandom(), "BC"); cPk.addMethod(encKey); byte[] bytes = bOut.toByteArray(); OutputStream out = new FileOutputStream(outputFilename); OutputStream aOut = armor? new ArmoredOutputStream(out): out; OutputStream cOut = cPk.open(aOut, bytes.length); cOut.write(bytes); cPk.close(); if (armor) { aOut.close(); } out.close(); } catch (PGPException e) { throw e; } catch (Exception e) { throw new PGPException("Error in encryption", e); } } /** * Sign the specified file */ public void signFile(String outputFilename, File inFile, InputStream publicRing, InputStream secretRing, String signor, char[] passwd, boolean armor, boolean oldFormat) throws PGPException { try { PGPPublicKey publicKey; PGPSecretKey secretKey; // Get the public keyring PGPPublicKeyRingCollection pubRing = new PGPPublicKeyRingCollection( PGPUtil.getDecoderStream(publicRing)); // Get the secret keyring PGPSecretKeyRingCollection secRing = new PGPSecretKeyRingCollection( PGPUtil.getDecoderStream(secretRing)); // Find the signing key if (signor != null) { publicKey = readPublicKey(pubRing, signor, false); secretKey = findSecretKey(secRing, publicKey.getKeyID(), true); } else { // Just look for the first signing key on the secret keyring (if any) secretKey = findSigningKey(secRing); publicKey = findPublicKey(pubRing, secretKey.getKeyID(), false); } if (publicKey.isRevoked()) { String keyId = Long.toHexString(publicKey.getKeyID()).substring(8); throw new PGPException("Signing key (0x"+keyId+") has been revoked"); } PGPPrivateKey privateKey = secretKey.extractPrivateKey(passwd, "BC"); OutputStream out = new FileOutputStream(outputFilename); OutputStream aOut = armor? new ArmoredOutputStream(out): out; // Sign the data if (oldFormat) { signDataV3(inFile, aOut, publicKey, privateKey); } else { signData(inFile, aOut, publicKey, privateKey); } if (armor) { // close() just finishes and flushes the stream but does not close it aOut.close(); } out.close(); } catch (PGPException e) { throw e; } catch (Exception e) { throw new PGPException("Error in signing", e); } } /** * Sign the passed in message stream (version 3 signature) */ private void signDataV3(File inFile, OutputStream aOut, PGPPublicKey publicKey, PGPPrivateKey privateKey) throws PGPException { try { PGPCompressedDataGenerator cGen = new PGPCompressedDataGenerator(PGPCompressedData.ZIP); BCPGOutputStream bOut = new BCPGOutputStream(cGen.open(aOut)); PGPLiteralDataGenerator lGen = new PGPLiteralDataGenerator(true); PGPV3SignatureGenerator s3Gen = new PGPV3SignatureGenerator(publicKey.getAlgorithm(), PGPUtil.SHA1, "BC"); s3Gen.initSign(PGPSignature.BINARY_DOCUMENT, privateKey); s3Gen.generateOnePassVersion(false).encode(bOut); OutputStream lOut = lGen.open(bOut, PGPLiteralData.BINARY, inFile); FileInputStream fIn = new FileInputStream(inFile); int ch; while ((ch = fIn.read()) >= 0) { lOut.write(ch); s3Gen.update((byte)ch); } fIn.close(); // close() finishes the writing of the literal data and flushes the stream // It does not close bOut so this is ok here lGen.close(); // Generate the signature s3Gen.generate().encode(bOut); // Must not close bOut here bOut.finish(); bOut.flush(); cGen.close(); } catch (PGPException e) { throw e; } catch (Exception e) { throw new PGPException("Error in signing", e); } } /** * Sign the passed in message stream */ private void signData(File inFile, OutputStream aOut, PGPPublicKey publicKey, PGPPrivateKey privateKey) throws PGPException { try { PGPCompressedDataGenerator cGen = new PGPCompressedDataGenerator(PGPCompressedData.ZIP); BCPGOutputStream bOut = new BCPGOutputStream(cGen.open(aOut)); PGPLiteralDataGenerator lGen = new PGPLiteralDataGenerator(); PGPSignatureGenerator sGen = new PGPSignatureGenerator(publicKey.getAlgorithm(), PGPUtil.SHA1, "BC"); sGen.initSign(PGPSignature.BINARY_DOCUMENT, privateKey); Iterator users = publicKey.getUserIDs(); if (users.hasNext()) { PGPSignatureSubpacketGenerator spGen = new PGPSignatureSubpacketGenerator(); spGen.setSignerUserID(false, (String) users.next()); sGen.setHashedSubpackets(spGen.generate()); } sGen.generateOnePassVersion(false).encode(bOut); OutputStream lOut = lGen.open(bOut, PGPLiteralData.BINARY, inFile); FileInputStream fIn = new FileInputStream(inFile); int ch; while ((ch = fIn.read()) >= 0) { lOut.write(ch); sGen.update((byte)ch); } fIn.close(); // close() finishes the writing of the literal data and flushes the stream // It does not close bOut so this is ok here lGen.close(); // Generate the signature sGen.generate().encode(bOut); // Must not close bOut here bOut.finish(); bOut.flush(); cGen.close(); } catch (PGPException e) { throw e; } catch (Exception e) { throw new PGPException("Error in signing", e); } } /** * Compress the data in the input stream */ private void compressData(File inFile, OutputStream bOut, boolean oldFormat) throws PGPException { try { PGPCompressedDataGenerator comData = new PGPCompressedDataGenerator(PGPCompressedData.ZIP); PGPLiteralDataGenerator lData = new PGPLiteralDataGenerator(oldFormat); OutputStream pOut = lData.open(comData.open(bOut), PGPLiteralData.BINARY, inFile.getName(), inFile.length(), new Date(inFile.lastModified())); FileInputStream fIn = new FileInputStream(inFile); byte[] bytes = new byte[4096]; int len; while ((len = fIn.read(bytes)) > 0) { pOut.write(bytes, 0, len); } fIn.close(); lData.close(); comData.close(); } catch (Exception e) { throw new PGPException("Error in encryption", e); } } /** * Decrypt the specified (PKE) input file */ public void decryptKeyBasedFile(String outputFilename, InputStream inFile, InputStream publicRing, InputStream secretRing, char[] passwd, boolean mdcRequired) throws PGPException { try { // Get the public keyring PGPPublicKeyRingCollection pubRing = new PGPPublicKeyRingCollection( PGPUtil.getDecoderStream(publicRing)); InputStream fileToDecrypt = PGPUtil.getDecoderStream(inFile); PGPObjectFactory pgpFact = new PGPObjectFactory(fileToDecrypt); Object message = pgpFact.nextObject(); PGPPublicKeyEncryptedData pked = null; PGPCompressedData cData; // Check for signed only if (!(message instanceof PGPCompressedData)) { // // Encrypted - the first object might be a PGP marker packet. // if (!(message instanceof PGPEncryptedDataList)) { message = pgpFact.nextObject(); if (!(message instanceof PGPEncryptedDataList)) { if (_verbose) { System.out.println("Unrecognised PGP message type"); } throw new PGPException("Unrecognised PGP message type"); } } PGPEncryptedDataList enc = (PGPEncryptedDataList) message; PGPSecretKeyRingCollection pgpSec = new PGPSecretKeyRingCollection( PGPUtil.getDecoderStream(secretRing)); PGPSecretKey pgpSecKey = null; int count = 0; // find the secret key that is needed while (count != enc.size()) { if (enc.get(count) instanceof PGPPublicKeyEncryptedData) { pked = (PGPPublicKeyEncryptedData) enc.get(count); pgpSecKey = pgpSec.getSecretKey(pked.getKeyID()); if (pgpSecKey != null) { break; } } count++; } if (pgpSecKey == null) { throw new PGPException("Corresponding secret key not found"); } // Check for revoked key PGPPublicKey encKey = findPublicKey(pubRing, pgpSecKey.getKeyID(), true); if (encKey.isRevoked()) { String keyId = Long.toHexString(encKey.getKeyID()).substring(8); System.out.println("Warning: Encryption key (0x"+keyId+") has been revoked"); // throw new PGPException("Encryption key (0x"+keyId+") has been revoked"); } InputStream clear = pked.getDataStream(pgpSecKey.extractPrivateKey(passwd, "BC"), "BC"); pgpFact = new PGPObjectFactory(clear); cData = (PGPCompressedData) pgpFact.nextObject(); } else { cData = (PGPCompressedData) message; } // Blank out password in memory - no longer needed blank(passwd); pgpFact = new PGPObjectFactory(cData.getDataStream()); message = pgpFact.nextObject(); // Plain file if (message instanceof PGPLiteralData) { PGPLiteralData ld = (PGPLiteralData) message; if (outputFilename == null) { outputFilename = ld.getFileName(); } FileOutputStream out = new FileOutputStream(outputFilename); InputStream dataIn = ld.getInputStream(); int ch; while ((ch = dataIn.read()) >= 0) { out.write(ch); } out.close(); } else if (message instanceof PGPOnePassSignatureList) // One-pass signature { if (!checkOnePassSignature(outputFilename, (PGPOnePassSignatureList) message, pgpFact, pubRing)) { if (_verbose) { System.out.println("Signature verification failed"); } throw new PGPException("Signature verification failed"); } System.out.println("Signature verified"); } else if (message instanceof PGPSignatureList) // Signature list { if (!checkSignature(outputFilename, (PGPSignatureList) message, pgpFact, pubRing)) { if (_verbose) { System.out.println("Signature verification failed"); } throw new PGPException("Signature verification failed"); } System.out.println("Signature verified"); } else // what? { // System.out.println("Unrecognised message type"); throw new PGPException("Unrecognised PGP message type"); } if (pked != null) { if (pked.isIntegrityProtected()) { if (!pked.verify()) { if (_verbose) { System.out.println("message failed integrity check"); } throw new PGPException("Message failed integrity check"); } if (_verbose) { System.out.println("Message integrity check passed"); } } else { if (_verbose) { System.out.println("No message integrity check"); } if (mdcRequired) { throw new PGPException("Missing required message integrity check"); } } } } catch (PGPException e) { throw e; } catch (Exception e) { throw new PGPException("Error in decryption", e); } } /** * Decrypt the specified (PBE) input file */ public void decryptPBEBasedFile(String outputFilename, InputStream in, char[] passPhrase, boolean mdcRequired) throws PGPException { try { // // we need to be able to reset the stream if we try a // wrong password, we'll assume that all the mechanisms // appear in the first 10k for the moment... // int READ_LIMIT = 10 * 1024; in.mark(READ_LIMIT); PGPPBEEncryptedData pbe; InputStream clear; int count = 0; for (;;) { InputStream dIn = PGPUtil.getDecoderStream(in); PGPObjectFactory pgpF = new PGPObjectFactory(dIn); PGPEncryptedDataList enc; Object o = pgpF.nextObject(); // // the first object might be a PGP marker packet. // if (o instanceof PGPEncryptedDataList) { enc = (PGPEncryptedDataList) o; } else { enc = (PGPEncryptedDataList) pgpF.nextObject(); } while (count < enc.size()) { if (enc.get(count) instanceof PGPPBEEncryptedData) { break; } count++; } if (count >= enc.size()) { throw new PGPException("Password invalid"); } pbe = (PGPPBEEncryptedData) enc.get(count); try { clear = pbe.getDataStream(passPhrase, "BC"); } catch (PGPKeyValidationException e) { in.reset(); continue; } break; } PGPObjectFactory pgpFact = new PGPObjectFactory(clear); PGPCompressedData cData = (PGPCompressedData) pgpFact.nextObject(); pgpFact = new PGPObjectFactory(cData.getDataStream()); PGPLiteralData ld = (PGPLiteralData) pgpFact.nextObject(); if (outputFilename == null) { outputFilename = ld.getFileName(); } FileOutputStream fOut = new FileOutputStream(outputFilename); InputStream unc = ld.getInputStream(); int ch; while ((ch = unc.read()) >= 0) { fOut.write(ch); } if (pbe.isIntegrityProtected()) { if (!pbe.verify()) { if (_verbose) { System.out.println("Message failed integrity check"); } throw new PGPException("Message failed integrity check"); } if (_verbose) { System.out.println("Message integrity check passed"); } } else { if (_verbose) { System.out.println("No message integrity check"); } if (mdcRequired) { throw new PGPException("Missing required message integrity check"); } } } catch (PGPException e) { throw e; } catch (Exception e) { throw new PGPException("Error in decryption", e); } } /** * Verify the passed in file as being correctly signed. */ public void verifyFile(String outputFilename, InputStream inFile, InputStream publicRing) throws PGPException { try { // Get the public keyring PGPPublicKeyRingCollection pubRing = new PGPPublicKeyRingCollection( PGPUtil.getDecoderStream(publicRing)); InputStream in = PGPUtil.getDecoderStream(inFile); // // a clear signed file // if (in instanceof ArmoredInputStream && ((ArmoredInputStream) in).isClearText()) { if (!checkClearsign(in, pubRing)) { if (_verbose) { System.out.println("Signature verification failed."); } throw new PGPException("Signature verification failed."); } if (_verbose) { System.out.println("Signature verified."); } } else { PGPObjectFactory pgpFact = new PGPObjectFactory(in); PGPCompressedData c1 = (PGPCompressedData) pgpFact.nextObject(); pgpFact = new PGPObjectFactory(c1.getDataStream()); Object message = pgpFact.nextObject(); if (message instanceof PGPOnePassSignatureList) // One-pass signature list { if (!checkOnePassSignature(outputFilename, (PGPOnePassSignatureList) message, pgpFact, pubRing)) { if (_verbose) { System.out.println("Signature verification failed."); } throw new PGPException("Signature verification failed."); } } else if (message instanceof PGPSignatureList) // Signature list { if (!checkSignature(outputFilename, (PGPSignatureList) message, pgpFact, pubRing)) { if (_verbose) { System.out.println("Signature verification failed."); } throw new PGPException("Signature verification failed."); } } else // what? { if (_verbose) { System.out.println("Unrecognised PGP message type"); } throw new PGPException("Unrecognised PGP message type"); } } if (_verbose) { System.out.println("Signature verified."); } } catch (PGPException e) { throw e; } catch (Exception e) { throw new PGPException("Error in verification", e); } } /** * Check the signature in clear-signed data */ private boolean checkClearsign(InputStream in, PGPPublicKeyRingCollection pgpRings) throws PGPException { try { // // read the input, making sure we ingore the last newline. // ArmoredInputStream aIn = (ArmoredInputStream) in; boolean newLine = false; ByteArrayOutputStream bOut = new ByteArrayOutputStream(); int ch; while ((ch = aIn.read()) >= 0 && aIn.isClearText()) { if (newLine) { bOut.write((byte) '\n'); newLine = false; } if (ch == '\n') { newLine = true; continue; } bOut.write((byte) ch); } PGPObjectFactory pgpFact = new PGPObjectFactory(aIn); PGPSignatureList p3 = (PGPSignatureList) pgpFact.nextObject(); PGPSignature sig = null; PGPPublicKey key = null; int count = 0; while (count < p3.size()) { sig = (PGPSignature) p3.get(count); key = pgpRings.getPublicKey(sig.getKeyID()); if (key != null) { break; } count++; } if (key == null) { throw new PGPException("Corresponding public key not found"); } if (key.isRevoked()) { String keyId = Long.toHexString(key.getKeyID()).substring(8); System.out.println("Warning: Signing key (0x"+keyId+") has been revoked"); // throw new PGPException("Signing key (0x"+keyId+") has been revoked"); } sig.initVerify(key, "BC"); sig.update(bOut.toByteArray()); return sig.verify(); } catch (PGPException e) { throw e; } catch (Exception e) { throw new PGPException("Error in verification", e); } } /** * Check a one-pass signature */ private boolean checkOnePassSignature(String outputFilename, PGPOnePassSignatureList p1, PGPObjectFactory pgpFact, PGPPublicKeyRingCollection pgpRing) throws PGPException { try { PGPOnePassSignature ops = null; PGPPublicKey key = null; int count = 0; while (count < p1.size()) { ops = p1.get(count); key = pgpRing.getPublicKey(ops.getKeyID()); if (key != null) { break; } count++; } if (key == null) { throw new PGPException("Corresponding public key not found"); } if (key.isRevoked()) { String keyId = Long.toHexString(key.getKeyID()).substring(8); System.out.println("Warning: Signing key (0x"+keyId+") has been revoked"); // throw new PGPException("Signing key (0x"+keyId+") has been revoked"); } PGPLiteralData ld = (PGPLiteralData) pgpFact.nextObject(); if (outputFilename == null) { outputFilename = ld.getFileName(); } FileOutputStream out = new FileOutputStream(outputFilename); InputStream dataIn = ld.getInputStream(); ops.initVerify(key, "BC"); int ch; while ((ch = dataIn.read()) >= 0) { ops.update((byte) ch); out.write(ch); } out.close(); PGPSignatureList p3 = (PGPSignatureList) pgpFact.nextObject(); return ops.verify(p3.get(0)); } catch (PGPException e) { throw e; } catch (Exception e) { throw new PGPException("Error in verification", e); } } /** * Check a signature */ private boolean checkSignature(String outputFilename, PGPSignatureList sigList, PGPObjectFactory pgpFact, PGPPublicKeyRingCollection pgpRing) throws PGPException { try { PGPSignature sig = null; PGPPublicKey key = null; int count = 0; while (count < sigList.size()) { sig = sigList.get(count); key = pgpRing.getPublicKey(sig.getKeyID()); if (key != null) { break; } count++; } if (key == null) { throw new PGPException("Corresponding public key not found"); } if (key.isRevoked()) { String keyId = Long.toHexString(key.getKeyID()).substring(8); System.out.println("Warning: Signing key (0x"+keyId+") has been revoked"); // throw new PGPException("Signing key (0x"+keyId+") has been revoked"); } PGPLiteralData ld = (PGPLiteralData) pgpFact.nextObject(); if (outputFilename == null) { outputFilename = ld.getFileName(); } FileOutputStream out = new FileOutputStream(outputFilename); InputStream dataIn = ld.getInputStream(); sig.initVerify(key, "BC"); int ch; while ((ch = dataIn.read()) >= 0) { sig.update((byte) ch); out.write(ch); } out.close(); return sig.verify(); } catch (PGPException e) { throw e; } catch (Exception e) { throw new PGPException("Error in verification", e); } } /** * Find the public key for the recipient */ private PGPPublicKey readPublicKey(PGPPublicKeyRingCollection pubRing, String recipient, boolean encrypting) throws IOException, PGPException { // // we just loop through the collection till we find a key suitable for encryption, in the real // world you would probably want to be a bit smarter about this. // PGPPublicKey key = null; // // iterate through the key rings. // Iterator rIt = pubRing.getKeyRings(); //System.out.println("processing public key ring, looking for : "+recipient); while (key == null && rIt.hasNext()) { PGPPublicKeyRing kRing = (PGPPublicKeyRing) rIt.next(); //System.out.println("Found a ring with keys "); Iterator kIt = kRing.getPublicKeys(); while (key == null && kIt.hasNext()) { PGPPublicKey k = (PGPPublicKey) kIt.next(); Iterator userIDs = k.getUserIDs(); String name = ""; if (userIDs.hasNext()) { name = (String) userIDs.next(); } //System.out.println("found a key with name "+name); if (name.indexOf(recipient) >= 0) { if (!encrypting || k.isEncryptionKey()) { //System.out.println("Found the key I'm looking for"); key = k; } } } } if (key == null) { if (encrypting) { throw new PGPException("Can't find encryption key in key ring"); } else { throw new PGPException("Can't find signing key in key ring"); } } return key; } /** * Load a public key ring collection from keyIn and find the key corresponding to * keyID if it exists. * * @param keyIn input stream representing a key ring collection. * @param keyID keyID we want. * @param encrypting whether we are encrypting or not * @return * @throws IOException * @throws PGPException * @throws NoSuchProviderException */ private static PGPPublicKey findPublicKey(PGPPublicKeyRingCollection pubRing, long keyID, boolean encrypting) throws IOException, PGPException, NoSuchProviderException { PGPPublicKey pubKey = pubRing.getPublicKey(keyID); if (pubKey != null) { if (encrypting && !pubKey.isEncryptionKey()) { throw new PGPException("Key is not an encryption key"); } } else { throw new PGPException("Can't find public key in key ring"); } return pubKey; } /** * Load a secret key ring collection from keyIn and find the secret key corresponding to * keyID if it exists. * * @param keyIn input stream representing a key ring collection. * @param keyID keyID we want. * @param signing indicates whether looking for a signing key. * @return * @throws IOException * @throws PGPException * @throws NoSuchProviderException */ private static PGPSecretKey findSecretKey(PGPSecretKeyRingCollection secRing, long keyID, boolean signing) throws IOException, PGPException, NoSuchProviderException { PGPSecretKey pgpSecKey = secRing.getSecretKey(keyID); if (pgpSecKey != null) { if (signing && !pgpSecKey.isSigningKey()) { throw new PGPException("Key is not a signing key"); } } else { throw new PGPException("Can't find secret key in key ring"); } return pgpSecKey; } /** * A simple routine that opens a key ring file and finds the first available * key suitable for signature generation. * * @param in * @return * @throws IOException * @throws PGPException */ private static PGPSecretKey findSigningKey(PGPSecretKeyRingCollection secRing) throws IOException, PGPException { // // We just loop through the collection till we find a key suitable for encryption. // PGPSecretKey key = null; Iterator rIt = secRing.getKeyRings(); while (key == null && rIt.hasNext()) { PGPSecretKeyRing kRing = (PGPSecretKeyRing) rIt.next(); Iterator kIt = kRing.getSecretKeys(); while (key == null && kIt.hasNext()) { PGPSecretKey k = (PGPSecretKey) kIt.next(); if (k.isSigningKey()) { key = k; } } } if (key == null) { throw new PGPException("Can't find a signing key in the key ring"); } return key; } /** * Zero out the passed in character array */ private static void blank(char[] bytes) { for (int t = 0; t < bytes.length; t++) { bytes[t]=0; } } // TODO: Implement these methods so that can be used by the CmdLineProcessors // and the test cases. public boolean isError() { return false; } public Collection errorMessages() { return null; } } bouncycastle-1.49.orig/tools/src/org/bouncycastle/tools/openpgp/rampage/package.html0000644000175000017500000000011710262753174030355 0ustar ebourgebourg Support classes for BCRampage. bouncycastle-1.49.orig/tools/src/org/bouncycastle/tools/openpgp/PGPDump.java0000644000175000017500000000542010262753174026601 0ustar ebourgebourgpackage org.bouncycastle.tools.openpgp; import java.io.File; import java.security.Security; import org.bouncycastle.jce.provider.BouncyCastleProvider; import org.bouncycastle.tools.openpgp.dump.PGPDumpEngine; import org.bouncycastle.tools.openpgp.util.PGPCmdLineArgProcessor; import org.bouncycastle.tools.openpgp.util.PGPParams; /** * A simple packet walker that will dump the contents of the OpenPGP Message. * It will process the Message to the best of its ability, depending on the * parameters provided to the program. * * For example, if the SecretKeyRing and passphrase are not provided, then * any contents of an Encrypted Message will be opaque and not processed. * */ public class PGPDump { private static final String PGP_DEFAULT_PUBLIC_RING = "pubring.gpg"; private static final String PGP_DEFAULT_SECRET_RING = "secring.gpg"; public static void main(String[] argv) { String usage = "usage: PGPDump " + "[ -skr ] [ -pkr ] [ -K ] [ -P ]" + "[ -pbe ] fileName"; Security.addProvider(new BouncyCastleProvider()); PGPDump cmdLineProcessor = new PGPDump(); PGPParams params = cmdLineProcessor.processArguments(argv); if (params.isError()) { System.out.println(usage); System.out.println("Error details - "); System.out.println(params.getErrors()); System.exit(1); } PGPDumpEngine engine = new PGPDumpEngine(params); engine.process(); } public PGPParams processArguments(String[] argv) { PGPCmdLineArgProcessor cmdLine = new PGPCmdLineArgProcessor(); PGPParams rv = cmdLine.processArguments(argv); if (rv.getInputFile() == null) { rv.addError("Input file must be specified"); } return rv; } private void processPubRing(String fileName, PGPParams rv) { File file = new File(fileName); if (!file.exists()) { rv.addError("Public Key Ring file does not exist [" + fileName + "]"); } else { rv.setPublicKeyRingFile(file); } } private void processSecRing(String fileName, PGPParams rv) { File file = new File(fileName); if (!file.exists()) { rv.addError("Secret Key Ring file does not exist [" + fileName + "]"); } else { rv.setSecretKeyRingFile(new File(fileName)); } } private boolean checkDirectory(String keyRingDir) { File dir = new File(keyRingDir); if (dir.exists() && dir.isDirectory()) { return true; } return false; } } bouncycastle-1.49.orig/tools/src/org/bouncycastle/tools/openpgp/package.html0000644000175000017500000001203110262753174026737 0ustar ebourgebourg

    OpenPGP Tools Package

    NOTE:These tools are definitely in beta stage, they work for very specific instances and may not work correctly for you. If there are issues, then report them on the dev-crypto@bouncycastle.org mailing list. Please read the options below, and please pay attention when options are not currently implemented. For the short term expect these tools to change rapidly, and to be updated frequently in the betas directory (http://www.bouncycastle.org/betas)

    Thanks.

    PGPDump

    This tool is similar to the gpg --list-packets command.

    java org.bouncycastle.tools.openpgp.PGPDump [-K dir] [-skr file] [-pkr file] 
                                                [-P passphrase] [-pbe passphrase] filename
    

    OptionDescription
    -K <keyring dir>Specifies the directory containing the gpg keyring files. These must be called pubring.gpg and secring.gpg. This should be sufficient for general use with gpg compatibility. Use the -pkr and -skr options to specify particular files. Using this option will generally require the -P option when processing encrypted files.
    -skr <secretkeyring file>Specifies the file containing the gpg secret keyring file. This must be the full path to the file. Using this option will generally require the -P option.
    -pkr <publickeyring file>Specifies the file containing the gpg public keyring file. This must be the full path to the file.
    -P <passphrase>Specifies the passphrase to unlock the secret keyring file.
    -pbe <passphrase>Specifies the passphrase to decrypt the file using the PGP PBE method. (NOT TESTED)
    filenameThe filename is the file to process. This is required

    NOTE: Combining options such as -K and -pkr will provide results that are unlikely to be useful.

    BCRampage

    This tool is similar to the gpg command. This tool provides the capability to encrypt, decrypt, sign and verify PGP messages.

    java org.bouncycastle.tools.openpgp.BCRampage [ -e[a] | -d | -s | -v  ]
                                                  [-K dir] [-skr file] [-pkr file] 
                                                  [-R recipient]
                                                  [-P passphrase] [-pbe passphrase]
                                                  [-mdc] filename
    

    OptionDescription
    -e[a]Encrypt [with ascii armour]
    -dDecrypt
    -sSign (NOT IMPLEMENTED)
    -vVerify (REQUIRES MORE TESTING)
    -K <keyring dir>Specifies the directory containing the gpg keyring files. These must be called pubring.gpg and secring.gpg. This should be sufficient for general use with gpg compatibility. Use the -pkr and -skr options to specify particular files. Using this option will generally require the -P option when processing encrypted files.
    -skr <secretkeyring file>Specifies the file containing the gpg secret keyring file. This must be the full path to the file. Using this option will generally require the -P option.
    -pkr <publickeyring file>Specifies the file containing the gpg public keyring file. This must be the full path to the file.
    -P <passphrase>Specifies the passphrase to unlock the secret keyring file.
    -pbe <passphrase>Specifies the passphrase to decrypt the file using the PGP PBE method. (NOT TESTED)
    -R <recipient>Specifies the recipient of the encrypted message. This is normally the email address of the recipient, however the matching is done using String.indexOf(), so any fragment that is part of the user id attribute string for the key should work.
    -mdcIf this option is specified, a PGP MDC (modification detection code) packet is added to the encrypted file. (So, use this with the -e option).The MDC packet contains a SHA-1 digest of the plaintext for comparison with the decrypted plaintext.
    filenameThe filename is the file to process. This is required

    NOTE: Combining options such as -K and -pkr will provide results that are unlikely to be useful. Mixing options or not providing options that might be needed (such as -e with -d, or -e and no -R) may result in NullPointerExceptions or other strange errors. bouncycastle-1.49.orig/tools/package.html0000644000175000017500000000101510262753174020056 0ustar ebourgebourg Tools Package

    These are tools that generally serve two purposes. The first is to provide a set of tools that perform cryptographic operations. The second is to provide a comprehensive set of worked examples (and usable code) on how to use the Bouncy Castle API's. The test code in the tools directory contains a parallel directory structure containing the tests for the respective tool. Additional documentation can be found on each tool in their respective package. bouncycastle-1.49.orig/checkstyle/0000755000175000017500000000000012152033551016564 5ustar ebourgebourgbouncycastle-1.49.orig/checkstyle/bc-checks.xml0000644000175000017500000001151012151123463021127 0ustar ebourgebourg bouncycastle-1.49.orig/checkstyle/bc-suppressions.xml0000644000175000017500000000160110350737027022452 0ustar ebourgebourg bouncycastle-1.49.orig/build/0000755000175000017500000000000012152033363015526 5ustar ebourgebourgbouncycastle-1.49.orig/j2me/0000755000175000017500000000000012152033550015262 5ustar ebourgebourgbouncycastle-1.49.orig/j2me/org/0000755000175000017500000000000012152033550016051 5ustar ebourgebourgbouncycastle-1.49.orig/j2me/org/bouncycastle/0000755000175000017500000000000012152033550020544 5ustar ebourgebourgbouncycastle-1.49.orig/j2me/org/bouncycastle/openpgp/0000755000175000017500000000000012152033550022214 5ustar ebourgebourgbouncycastle-1.49.orig/j2me/org/bouncycastle/openpgp/PGPSecretKey.java0000644000175000017500000005430312150050436025331 0ustar ebourgebourgpackage org.bouncycastle.openpgp; import java.io.ByteArrayInputStream; import java.io.ByteArrayOutputStream; import java.io.IOException; import java.io.OutputStream; import java.security.SecureRandom; import java.util.ArrayList; import java.util.Iterator; import java.util.List; import org.bouncycastle.bcpg.BCPGInputStream; import org.bouncycastle.bcpg.BCPGObject; import org.bouncycastle.bcpg.BCPGOutputStream; import org.bouncycastle.bcpg.ContainedPacket; import org.bouncycastle.bcpg.DSASecretBCPGKey; import org.bouncycastle.bcpg.ElGamalSecretBCPGKey; import org.bouncycastle.bcpg.HashAlgorithmTags; import org.bouncycastle.bcpg.PublicKeyPacket; import org.bouncycastle.bcpg.RSASecretBCPGKey; import org.bouncycastle.bcpg.S2K; import org.bouncycastle.bcpg.SecretKeyPacket; import org.bouncycastle.bcpg.SecretSubkeyPacket; import org.bouncycastle.bcpg.SymmetricKeyAlgorithmTags; import org.bouncycastle.bcpg.UserAttributePacket; import org.bouncycastle.bcpg.UserIDPacket; import org.bouncycastle.openpgp.operator.PBESecretKeyDecryptor; import org.bouncycastle.openpgp.operator.PBESecretKeyEncryptor; import org.bouncycastle.openpgp.operator.PGPContentSignerBuilder; import org.bouncycastle.openpgp.operator.PGPDigestCalculator; /** * general class to handle a PGP secret key object. */ public class PGPSecretKey { SecretKeyPacket secret; PGPPublicKey pub; PGPSecretKey( SecretKeyPacket secret, PGPPublicKey pub) { this.secret = secret; this.pub = pub; } PGPSecretKey( PGPPrivateKey privKey, PGPPublicKey pubKey, PGPDigestCalculator checksumCalculator, PBESecretKeyEncryptor keyEncryptor) throws PGPException { this(privKey, pubKey, checksumCalculator, false, keyEncryptor); } PGPSecretKey( PGPPrivateKey privKey, PGPPublicKey pubKey, PGPDigestCalculator checksumCalculator, boolean isMasterKey, PBESecretKeyEncryptor keyEncryptor) throws PGPException { this.pub = pubKey; BCPGObject secKey = (BCPGObject)privKey.getPrivateKeyDataPacket(); try { ByteArrayOutputStream bOut = new ByteArrayOutputStream(); BCPGOutputStream pOut = new BCPGOutputStream(bOut); pOut.writeObject(secKey); byte[] keyData = bOut.toByteArray(); pOut.write(checksum(checksumCalculator, keyData, keyData.length)); int encAlgorithm = keyEncryptor.getAlgorithm(); if (encAlgorithm != SymmetricKeyAlgorithmTags.NULL) { keyData = bOut.toByteArray(); // include checksum byte[] encData = keyEncryptor.encryptKeyData(keyData, 0, keyData.length); byte[] iv = keyEncryptor.getCipherIV(); S2K s2k = keyEncryptor.getS2K(); int s2kUsage; if (checksumCalculator != null) { if (checksumCalculator.getAlgorithm() != HashAlgorithmTags.SHA1) { throw new PGPException("only SHA1 supported for key checksum calculations."); } s2kUsage = SecretKeyPacket.USAGE_SHA1; } else { s2kUsage = SecretKeyPacket.USAGE_CHECKSUM; } if (isMasterKey) { this.secret = new SecretKeyPacket(pub.publicPk, encAlgorithm, s2kUsage, s2k, iv, encData); } else { this.secret = new SecretSubkeyPacket(pub.publicPk, encAlgorithm, s2kUsage, s2k, iv, encData); } } else { if (isMasterKey) { this.secret = new SecretKeyPacket(pub.publicPk, encAlgorithm, null, null, bOut.toByteArray()); } else { this.secret = new SecretSubkeyPacket(pub.publicPk, encAlgorithm, null, null, bOut.toByteArray()); } } } catch (PGPException e) { throw e; } catch (Exception e) { throw new PGPException("Exception encrypting key", e); } } public PGPSecretKey( int certificationLevel, PGPKeyPair keyPair, String id, PGPSignatureSubpacketVector hashedPcks, PGPSignatureSubpacketVector unhashedPcks, PGPContentSignerBuilder certificationSignerBuilder, PBESecretKeyEncryptor keyEncryptor) throws PGPException { this(certificationLevel, keyPair, id, null, hashedPcks, unhashedPcks, certificationSignerBuilder, keyEncryptor); } public PGPSecretKey( int certificationLevel, PGPKeyPair keyPair, String id, PGPDigestCalculator checksumCalculator, PGPSignatureSubpacketVector hashedPcks, PGPSignatureSubpacketVector unhashedPcks, PGPContentSignerBuilder certificationSignerBuilder, PBESecretKeyEncryptor keyEncryptor) throws PGPException { this(keyPair.getPrivateKey(), certifiedPublicKey(certificationLevel, keyPair, id, hashedPcks, unhashedPcks, certificationSignerBuilder), checksumCalculator, true, keyEncryptor); } private static PGPPublicKey certifiedPublicKey( int certificationLevel, PGPKeyPair keyPair, String id, PGPSignatureSubpacketVector hashedPcks, PGPSignatureSubpacketVector unhashedPcks, PGPContentSignerBuilder certificationSignerBuilder) throws PGPException { PGPSignatureGenerator sGen; try { sGen = new PGPSignatureGenerator(certificationSignerBuilder); } catch (Exception e) { throw new PGPException("creating signature generator: " + e, e); } // // generate the certification // sGen.init(certificationLevel, keyPair.getPrivateKey()); sGen.setHashedSubpackets(hashedPcks); sGen.setUnhashedSubpackets(unhashedPcks); try { PGPSignature certification = sGen.generateCertification(id, keyPair.getPublicKey()); return PGPPublicKey.addCertification(keyPair.getPublicKey(), id, certification); } catch (Exception e) { throw new PGPException("exception doing certification: " + e, e); } } /** * Return true if this key has an algorithm type that makes it suitable to use for signing. *

    * Note: with version 4 keys KeyFlags subpackets should also be considered when present for * determining the preferred use of the key. * * @return true if this key algorithm is suitable for use with signing. */ public boolean isSigningKey() { int algorithm = pub.getAlgorithm(); return ((algorithm == PGPPublicKey.RSA_GENERAL) || (algorithm == PGPPublicKey.RSA_SIGN) || (algorithm == PGPPublicKey.DSA) || (algorithm == PGPPublicKey.ECDSA) || (algorithm == PGPPublicKey.ELGAMAL_GENERAL)); } /** * Return true if this is a master key. * @return true if a master key. */ public boolean isMasterKey() { return pub.isMasterKey(); } /** * Detect if the Secret Key's Private Key is empty or not * * @return boolean whether or not the private key is empty */ public boolean isPrivateKeyEmpty() { byte[] secKeyData = secret.getSecretKeyData(); return (secKeyData == null || secKeyData.length < 1); } /** * return the algorithm the key is encrypted with. * * @return the algorithm used to encrypt the secret key. */ public int getKeyEncryptionAlgorithm() { return secret.getEncAlgorithm(); } /** * Return the keyID of the public key associated with this key. * * @return the keyID associated with this key. */ public long getKeyID() { return pub.getKeyID(); } /** * Return the public key associated with this key. * * @return the public key for this key. */ public PGPPublicKey getPublicKey() { return pub; } /** * Return any userIDs associated with the key. * * @return an iterator of Strings. */ public Iterator getUserIDs() { return pub.getUserIDs(); } /** * Return any user attribute vectors associated with the key. * * @return an iterator of Strings. */ public Iterator getUserAttributes() { return pub.getUserAttributes(); } private byte[] extractKeyData( PBESecretKeyDecryptor decryptorFactory) throws PGPException { byte[] encData = secret.getSecretKeyData(); byte[] data = null; if (secret.getEncAlgorithm() != SymmetricKeyAlgorithmTags.NULL) { try { if (secret.getPublicKeyPacket().getVersion() == 4) { byte[] key = decryptorFactory.makeKeyFromPassPhrase(secret.getEncAlgorithm(), secret.getS2K()); data = decryptorFactory.recoverKeyData(secret.getEncAlgorithm(), key, secret.getIV(), encData, 0, encData.length); boolean useSHA1 = secret.getS2KUsage() == SecretKeyPacket.USAGE_SHA1; byte[] check = checksum(useSHA1 ? decryptorFactory.getChecksumCalculator(HashAlgorithmTags.SHA1) : null, data, (useSHA1) ? data.length - 20 : data.length - 2); for (int i = 0; i != check.length; i++) { if (check[i] != data[data.length - check.length + i]) { throw new PGPException("checksum mismatch at " + i + " of " + check.length); } } } else // version 2 or 3, RSA only. { byte[] key = decryptorFactory.makeKeyFromPassPhrase(secret.getEncAlgorithm(), secret.getS2K()); data = new byte[encData.length]; byte[] iv = new byte[secret.getIV().length]; System.arraycopy(secret.getIV(), 0, iv, 0, iv.length); // // read in the four numbers // int pos = 0; for (int i = 0; i != 4; i++) { int encLen = (((encData[pos] << 8) | (encData[pos + 1] & 0xff)) + 7) / 8; data[pos] = encData[pos]; data[pos + 1] = encData[pos + 1]; byte[] tmp = decryptorFactory.recoverKeyData(secret.getEncAlgorithm(), key, iv, encData, pos + 2, encLen); System.arraycopy(tmp, 0, data, pos + 2, tmp.length); pos += 2 + encLen; if (i != 3) { System.arraycopy(encData, pos - iv.length, iv, 0, iv.length); } } // // verify and copy checksum // data[pos] = encData[pos]; data[pos + 1] = encData[pos + 1]; int cs = ((encData[pos] << 8) & 0xff00) | (encData[pos + 1] & 0xff); int calcCs = 0; for (int j = 0; j < data.length - 2; j++) { calcCs += data[j] & 0xff; } calcCs &= 0xffff; if (calcCs != cs) { throw new PGPException("checksum mismatch: passphrase wrong, expected " + Integer.toHexString(cs) + " found " + Integer.toHexString(calcCs)); } } } catch (PGPException e) { throw e; } catch (Exception e) { throw new PGPException("Exception decrypting key", e); } } else { data = encData; } return data; } /** * Extract a PGPPrivate key from the SecretKey's encrypted contents. * * @param decryptorFactory factory to use to generate a decryptor for the passed in secretKey. * @return PGPPrivateKey the unencrypted private key. * @throws PGPException on failure. */ public PGPPrivateKey extractPrivateKey( PBESecretKeyDecryptor decryptorFactory) throws PGPException { if (isPrivateKeyEmpty()) { return null; } PublicKeyPacket pubPk = secret.getPublicKeyPacket(); try { byte[] data = extractKeyData(decryptorFactory); BCPGInputStream in = new BCPGInputStream(new ByteArrayInputStream(data)); switch (pubPk.getAlgorithm()) { case PGPPublicKey.RSA_ENCRYPT: case PGPPublicKey.RSA_GENERAL: case PGPPublicKey.RSA_SIGN: RSASecretBCPGKey rsaPriv = new RSASecretBCPGKey(in); return new PGPPrivateKey(this.getKeyID(), pubPk, rsaPriv); case PGPPublicKey.DSA: DSASecretBCPGKey dsaPriv = new DSASecretBCPGKey(in); return new PGPPrivateKey(this.getKeyID(), pubPk, dsaPriv); case PGPPublicKey.ELGAMAL_ENCRYPT: case PGPPublicKey.ELGAMAL_GENERAL: ElGamalSecretBCPGKey elPriv = new ElGamalSecretBCPGKey(in); return new PGPPrivateKey(this.getKeyID(), pubPk, elPriv); default: throw new PGPException("unknown public key algorithm encountered"); } } catch (PGPException e) { throw e; } catch (Exception e) { throw new PGPException("Exception constructing key", e); } } private static byte[] checksum(PGPDigestCalculator digCalc, byte[] bytes, int length) throws PGPException { if (digCalc != null) { OutputStream dOut = digCalc.getOutputStream(); try { dOut.write(bytes, 0, length); dOut.close(); } catch (Exception e) { throw new PGPException("checksum digest calculation failed: " + e.getMessage(), e); } return digCalc.getDigest(); } else { int checksum = 0; for (int i = 0; i != length; i++) { checksum += bytes[i] & 0xff; } byte[] check = new byte[2]; check[0] = (byte)(checksum >> 8); check[1] = (byte)checksum; return check; } } public byte[] getEncoded() throws IOException { ByteArrayOutputStream bOut = new ByteArrayOutputStream(); this.encode(bOut); return bOut.toByteArray(); } public void encode( OutputStream outStream) throws IOException { BCPGOutputStream out; if (outStream instanceof BCPGOutputStream) { out = (BCPGOutputStream)outStream; } else { out = new BCPGOutputStream(outStream); } out.writePacket(secret); if (pub.trustPk != null) { out.writePacket(pub.trustPk); } if (pub.subSigs == null) // is not a sub key { for (int i = 0; i != pub.keySigs.size(); i++) { ((PGPSignature)pub.keySigs.get(i)).encode(out); } for (int i = 0; i != pub.ids.size(); i++) { if (pub.ids.get(i) instanceof String) { String id = (String)pub.ids.get(i); out.writePacket(new UserIDPacket(id)); } else { PGPUserAttributeSubpacketVector v = (PGPUserAttributeSubpacketVector)pub.ids.get(i); out.writePacket(new UserAttributePacket(v.toSubpacketArray())); } if (pub.idTrusts.get(i) != null) { out.writePacket((ContainedPacket)pub.idTrusts.get(i)); } List sigs = (ArrayList)pub.idSigs.get(i); for (int j = 0; j != sigs.size(); j++) { ((PGPSignature)sigs.get(j)).encode(out); } } } else { for (int j = 0; j != pub.subSigs.size(); j++) { ((PGPSignature)pub.subSigs.get(j)).encode(out); } } } /** * Return a copy of the passed in secret key, encrypted using a new * password and the passed in algorithm. * * @param key the PGPSecretKey to be copied. * @param oldKeyDecryptor the current decryptor based on the current password for key. * @param newKeyEncryptor a new encryptor based on a new password for encrypting the secret key material. */ public static PGPSecretKey copyWithNewPassword( PGPSecretKey key, PBESecretKeyDecryptor oldKeyDecryptor, PBESecretKeyEncryptor newKeyEncryptor) throws PGPException { if (key.isPrivateKeyEmpty()) { throw new PGPException("no private key in this SecretKey - public key present only."); } byte[] rawKeyData = key.extractKeyData(oldKeyDecryptor); int s2kUsage = key.secret.getS2KUsage(); byte[] iv = null; S2K s2k = null; byte[] keyData; int newEncAlgorithm = SymmetricKeyAlgorithmTags.NULL; if (newKeyEncryptor == null || newKeyEncryptor.getAlgorithm() == SymmetricKeyAlgorithmTags.NULL) { s2kUsage = SecretKeyPacket.USAGE_NONE; if (key.secret.getS2KUsage() == SecretKeyPacket.USAGE_SHA1) // SHA-1 hash, need to rewrite checksum { keyData = new byte[rawKeyData.length - 18]; System.arraycopy(rawKeyData, 0, keyData, 0, keyData.length - 2); byte[] check = checksum(null, keyData, keyData.length - 2); keyData[keyData.length - 2] = check[0]; keyData[keyData.length - 1] = check[1]; } else { keyData = rawKeyData; } } else { if (key.secret.getPublicKeyPacket().getVersion() < 4) { // Version 2 or 3 - RSA Keys only byte[] encKey = newKeyEncryptor.getKey(); keyData = new byte[rawKeyData.length]; if (newKeyEncryptor.getS2K() != null) { throw new PGPException("MD5 Digest Calculator required for version 3 key encryptor."); } // // process 4 numbers // int pos = 0; for (int i = 0; i != 4; i++) { int encLen = (((rawKeyData[pos] << 8) | (rawKeyData[pos + 1] & 0xff)) + 7) / 8; keyData[pos] = rawKeyData[pos]; keyData[pos + 1] = rawKeyData[pos + 1]; byte[] tmp; if (i == 0) { tmp = newKeyEncryptor.encryptKeyData(encKey, rawKeyData, pos + 2, encLen); iv = newKeyEncryptor.getCipherIV(); } else { byte[] tmpIv = new byte[iv.length]; System.arraycopy(keyData, pos - iv.length, tmpIv, 0, tmpIv.length); tmp = newKeyEncryptor.encryptKeyData(encKey, tmpIv, rawKeyData, pos + 2, encLen); } System.arraycopy(tmp, 0, keyData, pos + 2, tmp.length); pos += 2 + encLen; } // // copy in checksum. // keyData[pos] = rawKeyData[pos]; keyData[pos + 1] = rawKeyData[pos + 1]; s2k = newKeyEncryptor.getS2K(); newEncAlgorithm = newKeyEncryptor.getAlgorithm(); } else { keyData = newKeyEncryptor.encryptKeyData(rawKeyData, 0, rawKeyData.length); iv = newKeyEncryptor.getCipherIV(); s2k = newKeyEncryptor.getS2K(); newEncAlgorithm = newKeyEncryptor.getAlgorithm(); } } SecretKeyPacket secret; if (key.secret instanceof SecretSubkeyPacket) { secret = new SecretSubkeyPacket(key.secret.getPublicKeyPacket(), newEncAlgorithm, s2kUsage, s2k, iv, keyData); } else { secret = new SecretKeyPacket(key.secret.getPublicKeyPacket(), newEncAlgorithm, s2kUsage, s2k, iv, keyData); } return new PGPSecretKey(secret, key.pub); } /** * Replace the passed the public key on the passed in secret key. * * @param secretKey secret key to change * @param publicKey new public key. * @return a new secret key. * @throws IllegalArgumentException if keyIDs do not match. */ public static PGPSecretKey replacePublicKey(PGPSecretKey secretKey, PGPPublicKey publicKey) { if (publicKey.getKeyID() != secretKey.getKeyID()) { throw new IllegalArgumentException("keyIDs do not match"); } return new PGPSecretKey(secretKey.secret, publicKey); } } bouncycastle-1.49.orig/j2me/org/bouncycastle/openpgp/PGPUtil.java0000644000175000017500000001027111731766635024367 0ustar ebourgebourgpackage org.bouncycastle.openpgp; import java.io.IOException; import java.security.SecureRandom; import org.bouncycastle.asn1.ASN1InputStream; import org.bouncycastle.asn1.ASN1Sequence; import org.bouncycastle.asn1.DERInteger; import org.bouncycastle.bcpg.HashAlgorithmTags; import org.bouncycastle.bcpg.MPInteger; import org.bouncycastle.bcpg.PublicKeyAlgorithmTags; import org.bouncycastle.bcpg.SymmetricKeyAlgorithmTags; /** * Basic utility class */ public class PGPUtil implements HashAlgorithmTags { static MPInteger[] dsaSigToMpi( byte[] encoding) throws PGPException { ASN1InputStream aIn = new ASN1InputStream(encoding); DERInteger i1; DERInteger i2; try { ASN1Sequence s = (ASN1Sequence)aIn.readObject(); i1 = (DERInteger)s.getObjectAt(0); i2 = (DERInteger)s.getObjectAt(1); } catch (IOException e) { throw new PGPException("exception encoding signature", e); } MPInteger[] values = new MPInteger[2]; values[0] = new MPInteger(i1.getValue()); values[1] = new MPInteger(i2.getValue()); return values; } static String getDigestName( int hashAlgorithm) throws PGPException { switch (hashAlgorithm) { case HashAlgorithmTags.SHA1: return "SHA1"; case HashAlgorithmTags.MD2: return "MD2"; case HashAlgorithmTags.MD5: return "MD5"; case HashAlgorithmTags.RIPEMD160: return "RIPEMD160"; case HashAlgorithmTags.SHA256: return "SHA256"; case HashAlgorithmTags.SHA384: return "SHA384"; case HashAlgorithmTags.SHA512: return "SHA512"; case HashAlgorithmTags.SHA224: return "SHA224"; default: throw new PGPException("unknown hash algorithm tag in getDigestName: " + hashAlgorithm); } } static String getSignatureName( int keyAlgorithm, int hashAlgorithm) throws PGPException { String encAlg; switch (keyAlgorithm) { case PublicKeyAlgorithmTags.RSA_GENERAL: case PublicKeyAlgorithmTags.RSA_SIGN: encAlg = "RSA"; break; case PublicKeyAlgorithmTags.DSA: encAlg = "DSA"; break; case PublicKeyAlgorithmTags.ELGAMAL_ENCRYPT: // in some malformed cases. case PublicKeyAlgorithmTags.ELGAMAL_GENERAL: encAlg = "ElGamal"; break; default: throw new PGPException("unknown algorithm tag in signature:" + keyAlgorithm); } return getDigestName(hashAlgorithm) + "with" + encAlg; } public static byte[] makeRandomKey( int algorithm, SecureRandom random) throws PGPException { int keySize = 0; switch (algorithm) { case SymmetricKeyAlgorithmTags.TRIPLE_DES: keySize = 192; break; case SymmetricKeyAlgorithmTags.IDEA: keySize = 128; break; case SymmetricKeyAlgorithmTags.CAST5: keySize = 128; break; case SymmetricKeyAlgorithmTags.BLOWFISH: keySize = 128; break; case SymmetricKeyAlgorithmTags.SAFER: keySize = 128; break; case SymmetricKeyAlgorithmTags.DES: keySize = 64; break; case SymmetricKeyAlgorithmTags.AES_128: keySize = 128; break; case SymmetricKeyAlgorithmTags.AES_192: keySize = 192; break; case SymmetricKeyAlgorithmTags.AES_256: keySize = 256; break; case SymmetricKeyAlgorithmTags.TWOFISH: keySize = 256; break; default: throw new PGPException("unknown symmetric algorithm: " + algorithm); } byte[] keyBytes = new byte[(keySize + 7) / 8]; random.nextBytes(keyBytes); return keyBytes; } } bouncycastle-1.49.orig/j2me/org/bouncycastle/openpgp/PGPPBEEncryptedData.java0000644000175000017500000001142411731766113026520 0ustar ebourgebourgpackage org.bouncycastle.openpgp; import java.io.EOFException; import java.io.InputStream; import org.bouncycastle.bcpg.BCPGInputStream; import org.bouncycastle.bcpg.InputStreamPacket; import org.bouncycastle.bcpg.SymmetricEncIntegrityPacket; import org.bouncycastle.bcpg.SymmetricKeyEncSessionPacket; import org.bouncycastle.openpgp.operator.PBEDataDecryptorFactory; import org.bouncycastle.openpgp.operator.PGPDataDecryptor; import org.bouncycastle.util.io.TeeInputStream; /** * A password based encryption object. */ public class PGPPBEEncryptedData extends PGPEncryptedData { SymmetricKeyEncSessionPacket keyData; PGPPBEEncryptedData( SymmetricKeyEncSessionPacket keyData, InputStreamPacket encData) { super(encData); this.keyData = keyData; } /** * Return the raw input stream for the data stream. * * @return InputStream */ public InputStream getInputStream() { return encData.getInputStream(); } /** * Return the symmetric key algorithm required to decrypt the data protected by this object. * * @param dataDecryptorFactory decryptor factory to use to recover the session data. * @return the integer encryption algorithm code. * @throws PGPException if the session data cannot be recovered. */ public int getSymmetricAlgorithm( PBEDataDecryptorFactory dataDecryptorFactory) throws PGPException { byte[] key = dataDecryptorFactory.makeKeyFromPassPhrase(keyData.getEncAlgorithm(), keyData.getS2K()); byte[] sessionData = dataDecryptorFactory.recoverSessionData(keyData.getEncAlgorithm(), key, keyData.getSecKeyData()); return sessionData[0]; } /** * Open an input stream which will provide the decrypted data protected by this object. * * @param dataDecryptorFactory decryptor factory to use to recover the session data and provide the stream. * @return the resulting input stream * @throws PGPException if the session data cannot be recovered or the stream cannot be created. */ public InputStream getDataStream( PBEDataDecryptorFactory dataDecryptorFactory) throws PGPException { try { int keyAlgorithm = keyData.getEncAlgorithm(); byte[] key = dataDecryptorFactory.makeKeyFromPassPhrase(keyAlgorithm, keyData.getS2K()); boolean withIntegrityPacket = encData instanceof SymmetricEncIntegrityPacket; byte[] sessionData = dataDecryptorFactory.recoverSessionData(keyData.getEncAlgorithm(), key, keyData.getSecKeyData()); byte[] sessionKey = new byte[sessionData.length - 1]; System.arraycopy(sessionData, 1, sessionKey, 0, sessionKey.length); PGPDataDecryptor dataDecryptor = dataDecryptorFactory.createDataDecryptor(withIntegrityPacket, sessionData[0] & 0xff, sessionKey); encStream = new BCPGInputStream(dataDecryptor.getInputStream(encData.getInputStream())); if (withIntegrityPacket) { truncStream = new TruncatedStream(encStream); integrityCalculator = dataDecryptor.getIntegrityCalculator(); encStream = new TeeInputStream(truncStream, integrityCalculator.getOutputStream()); } byte[] iv = new byte[dataDecryptor.getBlockSize()]; for (int i = 0; i != iv.length; i++) { int ch = encStream.read(); if (ch < 0) { throw new EOFException("unexpected end of stream."); } iv[i] = (byte)ch; } int v1 = encStream.read(); int v2 = encStream.read(); if (v1 < 0 || v2 < 0) { throw new EOFException("unexpected end of stream."); } // Note: the oracle attack on "quick check" bytes is not deemed // a security risk for PBE (see PGPPublicKeyEncryptedData) boolean repeatCheckPassed = iv[iv.length - 2] == (byte) v1 && iv[iv.length - 1] == (byte) v2; // Note: some versions of PGP appear to produce 0 for the extra // bytes rather than repeating the two previous bytes boolean zeroesCheckPassed = v1 == 0 && v2 == 0; if (!repeatCheckPassed && !zeroesCheckPassed) { throw new PGPDataValidationException("data check failed."); } return encStream; } catch (PGPException e) { throw e; } catch (Exception e) { throw new PGPException("Exception creating cipher", e); } } } bouncycastle-1.49.orig/j2me/org/bouncycastle/openpgp/PGPLiteralDataGenerator.java0000644000175000017500000001204611732001352027464 0ustar ebourgebourgpackage org.bouncycastle.openpgp; import java.io.IOException; import java.io.OutputStream; import java.util.Date; import org.bouncycastle.bcpg.BCPGOutputStream; import org.bouncycastle.bcpg.PacketTags; import org.bouncycastle.util.Strings; /** * Class for producing literal data packets. */ public class PGPLiteralDataGenerator implements StreamGenerator { public static final char BINARY = PGPLiteralData.BINARY; public static final char TEXT = PGPLiteralData.TEXT; public static final char UTF8 = PGPLiteralData.UTF8; /** * The special name indicating a "for your eyes only" packet. */ public static final String CONSOLE = PGPLiteralData.CONSOLE; /** * The special time for a modification time of "now" or * the present time. */ public static final Date NOW = PGPLiteralData.NOW; private BCPGOutputStream pkOut; private boolean oldFormat = false; public PGPLiteralDataGenerator() { } /** * Generates literal data objects in the old format, this is * important if you need compatability with PGP 2.6.x. * * @param oldFormat */ public PGPLiteralDataGenerator( boolean oldFormat) { this.oldFormat = oldFormat; } private void writeHeader( OutputStream out, char format, byte[] encName, long modificationTime) throws IOException { out.write(format); out.write((byte)encName.length); for (int i = 0; i != encName.length; i++) { out.write(encName[i]); } long modDate = modificationTime / 1000; out.write((byte)(modDate >> 24)); out.write((byte)(modDate >> 16)); out.write((byte)(modDate >> 8)); out.write((byte)(modDate)); } /** * Open a literal data packet, returning a stream to store the data inside * the packet. *

    * The stream created can be closed off by either calling close() * on the stream or close() on the generator. Closing the returned * stream does not close off the OutputStream parameter out. * * @param out the stream we want the packet in * @param format the format we are using * @param name the name of the "file" * @param length the length of the data we will write * @param modificationTime the time of last modification we want stored. */ public OutputStream open( OutputStream out, char format, String name, long length, Date modificationTime) throws IOException { if (pkOut != null) { throw new IllegalStateException("generator already in open state"); } byte[] encName = Strings.toUTF8ByteArray(name); pkOut = new BCPGOutputStream(out, PacketTags.LITERAL_DATA, length + 2 + encName.length + 4, oldFormat); writeHeader(pkOut, format, encName, modificationTime.getTime()); return new WrappedGeneratorStream(pkOut, this); } /** * Open a literal data packet, returning a stream to store the data inside * the packet as an indefinite length stream. The stream is written out as a * series of partial packets with a chunk size determined by the size of the * passed in buffer. *

    * The stream created can be closed off by either calling close() * on the stream or close() on the generator. Closing the returned * stream does not close off the OutputStream parameter out. *

    * Note: if the buffer is not a power of 2 in length only the largest power of 2 * bytes worth of the buffer will be used. * * @param out the stream we want the packet in * @param format the format we are using * @param name the name of the "file" * @param modificationTime the time of last modification we want stored. * @param buffer the buffer to use for collecting data to put into chunks. */ public OutputStream open( OutputStream out, char format, String name, Date modificationTime, byte[] buffer) throws IOException { if (pkOut != null) { throw new IllegalStateException("generator already in open state"); } pkOut = new BCPGOutputStream(out, PacketTags.LITERAL_DATA, buffer); byte[] encName = Strings.toUTF8ByteArray(name); writeHeader(pkOut, format, encName, modificationTime.getTime()); return new WrappedGeneratorStream(pkOut, this); } /** * Close the literal data packet - this is equivalent to calling close on the stream * returned by the open() method. * * @throws IOException */ public void close() throws IOException { if (pkOut != null) { pkOut.finish(); pkOut.flush(); pkOut = null; } } } bouncycastle-1.49.orig/j2me/org/bouncycastle/openpgp/PGPSignatureException.java0000644000175000017500000000044611731770075027266 0ustar ebourgebourgpackage org.bouncycastle.openpgp; public class PGPSignatureException extends PGPException { public PGPSignatureException(String message) { super(message); } public PGPSignatureException(String message, Exception cause) { super(message, cause); } } bouncycastle-1.49.orig/j2me/org/bouncycastle/openpgp/PGPOnePassSignature.java0000644000175000017500000001262611731771575026711 0ustar ebourgebourgpackage org.bouncycastle.openpgp; import java.io.ByteArrayOutputStream; import java.io.IOException; import java.io.OutputStream; import org.bouncycastle.bcpg.BCPGInputStream; import org.bouncycastle.bcpg.BCPGOutputStream; import org.bouncycastle.bcpg.OnePassSignaturePacket; import org.bouncycastle.openpgp.operator.PGPContentVerifier; import org.bouncycastle.openpgp.operator.PGPContentVerifierBuilder; import org.bouncycastle.openpgp.operator.PGPContentVerifierBuilderProvider; /** * A one pass signature object. */ public class PGPOnePassSignature { private OnePassSignaturePacket sigPack; private int signatureType; private PGPContentVerifier verifier; private byte lastb; private OutputStream sigOut; PGPOnePassSignature( BCPGInputStream pIn) throws IOException, PGPException { this((OnePassSignaturePacket)pIn.readPacket()); } PGPOnePassSignature( OnePassSignaturePacket sigPack) throws PGPException { this.sigPack = sigPack; this.signatureType = sigPack.getSignatureType(); } /** * Initialise the signature object for verification. * * @param verifierBuilderProvider provider for a content verifier builder for the signature type of interest. * @param pubKey the public key to use for verification * @throws PGPException if there's an issue with creating the verifier. */ public void init(PGPContentVerifierBuilderProvider verifierBuilderProvider, PGPPublicKey pubKey) throws PGPException { PGPContentVerifierBuilder verifierBuilder = verifierBuilderProvider.get(sigPack.getKeyAlgorithm(), sigPack.getHashAlgorithm()); verifier = verifierBuilder.build(pubKey); lastb = 0; sigOut = verifier.getOutputStream(); } public void update( byte b) throws PGPSignatureException { if (signatureType == PGPSignature.CANONICAL_TEXT_DOCUMENT) { if (b == '\r') { byteUpdate((byte)'\r'); byteUpdate((byte)'\n'); } else if (b == '\n') { if (lastb != '\r') { byteUpdate((byte)'\r'); byteUpdate((byte)'\n'); } } else { byteUpdate(b); } lastb = b; } else { byteUpdate(b); } } public void update( byte[] bytes) throws PGPSignatureException { if (signatureType == PGPSignature.CANONICAL_TEXT_DOCUMENT) { for (int i = 0; i != bytes.length; i++) { this.update(bytes[i]); } } else { blockUpdate(bytes, 0, bytes.length); } } public void update( byte[] bytes, int off, int length) throws PGPSignatureException { if (signatureType == PGPSignature.CANONICAL_TEXT_DOCUMENT) { int finish = off + length; for (int i = off; i != finish; i++) { this.update(bytes[i]); } } else { blockUpdate(bytes, off, length); } } private void byteUpdate(byte b) throws PGPSignatureException { try { sigOut.write(b); } catch (IOException e) { throw new PGPSignatureException(e.getMessage(), e); } } private void blockUpdate(byte[] block, int off, int len) throws PGPSignatureException { try { sigOut.write(block, off, len); } catch (IOException e) { throw new PGPSignatureException(e.getMessage(), e); } } /** * Verify the calculated signature against the passed in PGPSignature. * * @param pgpSig * @return boolean * @throws PGPException */ public boolean verify( PGPSignature pgpSig) throws PGPException { try { sigOut.write(pgpSig.getSignatureTrailer()); sigOut.close(); } catch (IOException e) { throw new PGPException("unable to add trailer: " + e.getMessage(), e); } return verifier.verify(pgpSig.getSignature()); } public long getKeyID() { return sigPack.getKeyID(); } public int getSignatureType() { return sigPack.getSignatureType(); } public int getHashAlgorithm() { return sigPack.getHashAlgorithm(); } public int getKeyAlgorithm() { return sigPack.getKeyAlgorithm(); } public byte[] getEncoded() throws IOException { ByteArrayOutputStream bOut = new ByteArrayOutputStream(); this.encode(bOut); return bOut.toByteArray(); } public void encode( OutputStream outStream) throws IOException { BCPGOutputStream out; if (outStream instanceof BCPGOutputStream) { out = (BCPGOutputStream)outStream; } else { out = new BCPGOutputStream(outStream); } out.writePacket(sigPack); } } bouncycastle-1.49.orig/j2me/org/bouncycastle/openpgp/test/0000755000175000017500000000000012152033550023173 5ustar ebourgebourgbouncycastle-1.49.orig/j2me/org/bouncycastle/openpgp/test/BcPGPDSAElGamalTest.java0000644000175000017500000004544511732237604027371 0ustar ebourgebourgpackage org.bouncycastle.openpgp.test; import java.io.ByteArrayInputStream; import java.io.ByteArrayOutputStream; import java.io.IOException; import java.io.InputStream; import java.io.OutputStream; import java.math.BigInteger; import java.security.SecureRandom; import java.util.Date; import java.util.Iterator; import org.bouncycastle.bcpg.SymmetricKeyAlgorithmTags; import org.bouncycastle.crypto.AsymmetricBlockCipher; import org.bouncycastle.crypto.AsymmetricCipherKeyPair; import org.bouncycastle.crypto.encodings.PKCS1Encoding; import org.bouncycastle.crypto.engines.ElGamalEngine; import org.bouncycastle.crypto.generators.ElGamalKeyPairGenerator; import org.bouncycastle.crypto.params.AsymmetricKeyParameter; import org.bouncycastle.crypto.params.ElGamalKeyGenerationParameters; import org.bouncycastle.crypto.params.ElGamalParameters; import org.bouncycastle.openpgp.PGPEncryptedDataGenerator; import org.bouncycastle.openpgp.PGPEncryptedDataList; import org.bouncycastle.openpgp.PGPException; import org.bouncycastle.openpgp.PGPKeyPair; import org.bouncycastle.openpgp.PGPLiteralData; import org.bouncycastle.openpgp.PGPLiteralDataGenerator; import org.bouncycastle.openpgp.PGPObjectFactory; import org.bouncycastle.openpgp.PGPOnePassSignature; import org.bouncycastle.openpgp.PGPOnePassSignatureList; import org.bouncycastle.openpgp.PGPPrivateKey; import org.bouncycastle.openpgp.PGPPublicKey; import org.bouncycastle.openpgp.PGPPublicKeyEncryptedData; import org.bouncycastle.openpgp.PGPPublicKeyRing; import org.bouncycastle.openpgp.PGPSecretKeyRing; import org.bouncycastle.openpgp.PGPSignature; import org.bouncycastle.openpgp.PGPSignatureGenerator; import org.bouncycastle.openpgp.PGPSignatureList; import org.bouncycastle.openpgp.PGPUtil; import org.bouncycastle.openpgp.operator.bc.BcKeyFingerprintCalculator; import org.bouncycastle.openpgp.operator.bc.BcPBESecretKeyDecryptorBuilder; import org.bouncycastle.openpgp.operator.bc.BcPGPContentSignerBuilder; import org.bouncycastle.openpgp.operator.bc.BcPGPContentVerifierBuilderProvider; import org.bouncycastle.openpgp.operator.bc.BcPGPDataEncryptorBuilder; import org.bouncycastle.openpgp.operator.bc.BcPGPDigestCalculatorProvider; import org.bouncycastle.openpgp.operator.bc.BcPGPKeyConverter; import org.bouncycastle.openpgp.operator.bc.BcPGPKeyPair; import org.bouncycastle.openpgp.operator.bc.BcPublicKeyDataDecryptorFactory; import org.bouncycastle.openpgp.operator.bc.BcPublicKeyKeyEncryptionMethodGenerator; import org.bouncycastle.util.encoders.Base64; import org.bouncycastle.util.test.SimpleTest; import org.bouncycastle.util.test.UncloseableOutputStream; public class BcPGPDSAElGamalTest extends SimpleTest { byte[] testPubKeyRing = Base64.decode( "mQGiBEAR8jYRBADNifuSopd20JOQ5x30ljIaY0M6927+vo09NeNxS3KqItba" + "nz9o5e2aqdT0W1xgdHYZmdElOHTTsugZxdXTEhghyxoo3KhVcNnTABQyrrvX" + "qouvmP2fEDEw0Vpyk+90BpyY9YlgeX/dEA8OfooRLCJde/iDTl7r9FT+mts8" + "g3azjwCgx+pOLD9LPBF5E4FhUOdXISJ0f4EEAKXSOi9nZzajpdhe8W2ZL9gc" + "BpzZi6AcrRZBHOEMqd69gtUxA4eD8xycUQ42yH89imEcwLz8XdJ98uHUxGJi" + "qp6hq4oakmw8GQfiL7yQIFgaM0dOAI9Afe3m84cEYZsoAFYpB4/s9pVMpPRH" + "NsVspU0qd3NHnSZ0QXs8L8DXGO1uBACjDUj+8GsfDCIP2QF3JC+nPUNa0Y5t" + "wKPKl+T8hX/0FBD7fnNeC6c9j5Ir/Fp/QtdaDAOoBKiyNLh1JaB1NY6US5zc" + "qFks2seZPjXEiE6OIDXYra494mjNKGUobA4hqT2peKWXt/uBcuL1mjKOy8Qf" + "JxgEd0MOcGJO+1PFFZWGzLQ3RXJpYyBILiBFY2hpZG5hICh0ZXN0IGtleSBv" + "bmx5KSA8ZXJpY0Bib3VuY3ljYXN0bGUub3JnPohZBBMRAgAZBQJAEfI2BAsH" + "AwIDFQIDAxYCAQIeAQIXgAAKCRAOtk6iUOgnkDdnAKC/CfLWikSBdbngY6OK" + "5UN3+o7q1ACcDRqjT3yjBU3WmRUNlxBg3tSuljmwAgAAuQENBEAR8jgQBAC2" + "kr57iuOaV7Ga1xcU14MNbKcA0PVembRCjcVjei/3yVfT/fuCVtGHOmYLEBqH" + "bn5aaJ0P/6vMbLCHKuN61NZlts+LEctfwoya43RtcubqMc7eKw4k0JnnoYgB" + "ocLXOtloCb7jfubOsnfORvrUkK0+Ne6anRhFBYfaBmGU75cQgwADBQP/XxR2" + "qGHiwn+0YiMioRDRiIAxp6UiC/JQIri2AKSqAi0zeAMdrRsBN7kyzYVVpWwN" + "5u13gPdQ2HnJ7d4wLWAuizUdKIQxBG8VoCxkbipnwh2RR4xCXFDhJrJFQUm+" + "4nKx9JvAmZTBIlI5Wsi5qxst/9p5MgP3flXsNi1tRbTmRhqIRgQYEQIABgUC" + "QBHyOAAKCRAOtk6iUOgnkBStAJoCZBVM61B1LG2xip294MZecMtCwQCbBbsk" + "JVCXP0/Szm05GB+WN+MOCT2wAgAA"); byte[] testPrivKeyRing = Base64.decode( "lQHhBEAR8jYRBADNifuSopd20JOQ5x30ljIaY0M6927+vo09NeNxS3KqItba" + "nz9o5e2aqdT0W1xgdHYZmdElOHTTsugZxdXTEhghyxoo3KhVcNnTABQyrrvX" + "qouvmP2fEDEw0Vpyk+90BpyY9YlgeX/dEA8OfooRLCJde/iDTl7r9FT+mts8" + "g3azjwCgx+pOLD9LPBF5E4FhUOdXISJ0f4EEAKXSOi9nZzajpdhe8W2ZL9gc" + "BpzZi6AcrRZBHOEMqd69gtUxA4eD8xycUQ42yH89imEcwLz8XdJ98uHUxGJi" + "qp6hq4oakmw8GQfiL7yQIFgaM0dOAI9Afe3m84cEYZsoAFYpB4/s9pVMpPRH" + "NsVspU0qd3NHnSZ0QXs8L8DXGO1uBACjDUj+8GsfDCIP2QF3JC+nPUNa0Y5t" + "wKPKl+T8hX/0FBD7fnNeC6c9j5Ir/Fp/QtdaDAOoBKiyNLh1JaB1NY6US5zc" + "qFks2seZPjXEiE6OIDXYra494mjNKGUobA4hqT2peKWXt/uBcuL1mjKOy8Qf" + "JxgEd0MOcGJO+1PFFZWGzP4DAwLeUcsVxIC2s2Bb9ab2XD860TQ2BI2rMD/r" + "7/psx9WQ+Vz/aFAT3rXkEJ97nFeqEACgKmUCAEk9939EwLQ3RXJpYyBILiBF" + "Y2hpZG5hICh0ZXN0IGtleSBvbmx5KSA8ZXJpY0Bib3VuY3ljYXN0bGUub3Jn" + "PohZBBMRAgAZBQJAEfI2BAsHAwIDFQIDAxYCAQIeAQIXgAAKCRAOtk6iUOgn" + "kDdnAJ9Ala3OcwEV1DbK906CheYWo4zIQwCfUqUOLMp/zj6QAk02bbJAhV1r" + "sAewAgAAnQFYBEAR8jgQBAC2kr57iuOaV7Ga1xcU14MNbKcA0PVembRCjcVj" + "ei/3yVfT/fuCVtGHOmYLEBqHbn5aaJ0P/6vMbLCHKuN61NZlts+LEctfwoya" + "43RtcubqMc7eKw4k0JnnoYgBocLXOtloCb7jfubOsnfORvrUkK0+Ne6anRhF" + "BYfaBmGU75cQgwADBQP/XxR2qGHiwn+0YiMioRDRiIAxp6UiC/JQIri2AKSq" + "Ai0zeAMdrRsBN7kyzYVVpWwN5u13gPdQ2HnJ7d4wLWAuizUdKIQxBG8VoCxk" + "bipnwh2RR4xCXFDhJrJFQUm+4nKx9JvAmZTBIlI5Wsi5qxst/9p5MgP3flXs" + "Ni1tRbTmRhr+AwMC3lHLFcSAtrNg/EiWFLAnKNXH27zjwuhje8u2r+9iMTYs" + "GjbRxaxRY0GKRhttCwqe2BC0lHhzifdlEcc9yjIjuKfepG2fnnSIRgQYEQIA" + "BgUCQBHyOAAKCRAOtk6iUOgnkBStAJ9HFejVtVJ/A9LM/mDPe0ExhEXt/QCg" + "m/KM7hJ/JrfnLQl7IaZsdg1F6vCwAgAA"); byte[] encMessage = Base64.decode( "hQEOAynbo4lhNjcHEAP/dgCkMtPB6mIgjFvNiotjaoh4sAXf4vFNkSeehQ2c" + "r+IMt9CgIYodJI3FoJXxOuTcwesqTp5hRzgUBJS0adLDJwcNubFMy0M2tp5o" + "KTWpXulIiqyO6f5jI/oEDHPzFoYgBmR4x72l/YpMy8UoYGtNxNvR7LVOfqJv" + "uDY/71KMtPQEAIadOWpf1P5Td+61Zqn2VH2UV7H8eI6hGa6Lsy4sb9iZNE7f" + "c+spGJlgkiOt8TrQoq3iOK9UN9nHZLiCSIEGCzsEn3uNuorD++Qs065ij+Oy" + "36TKeuJ+38CfT7u47dEshHCPqWhBKEYrxZWHUJU/izw2Q1Yxd2XRxN+nafTL" + "X1fQ0lABQUASa18s0BkkEERIdcKQXVLEswWcGqWNv1ZghC7xO2VDBX4HrPjp" + "drjL63p2UHzJ7/4gPWGGtnqq1Xita/1mrImn7pzLThDWiT55vjw6Hw=="); byte[] signedAndEncMessage = Base64.decode( "hQEOAynbo4lhNjcHEAP+K20MVhzdX57hf/cU8TH0prP0VePr9mmeBedzqqMn" + "fp2p8Zb68zmcMlI/WiL5XMNLYRmCgEcXyWbKdP/XV9m9LDBe1CMAGrkCeGBy" + "je69IQQ5LS9vDPyEMF4iAAv/EqACjqHkizdY/a/FRx/t2ioXYdEC2jA6kS9C" + "McpsNz16DE8EAIk3uKn4bGo/+15TXkyFYzW5Cf71SfRoHNmU2zAI93zhjN+T" + "B7mGJwWXzsMkIO6FkMU5TCSrwZS3DBWCIaJ6SYoaawE/C/2j9D7bX1Jv8kum" + "4cq+eZM7z6JYs6xend+WAwittpUxbEiyC2AJb3fBSXPAbLqWd6J6xbZZ7GDK" + "r2Ca0pwBxwGhbMDyi2zpHLzw95H7Ah2wMcGU6kMLB+hzBSZ6mSTGFehqFQE3" + "2BnAj7MtnbghiefogacJ891jj8Y2ggJeKDuRz8j2iICaTOy+Y2rXnnJwfYzm" + "BMWcd2h1C5+UeBJ9CrrLniCCI8s5u8z36Rno3sfhBnXdRmWSxExXtocbg1Ht" + "dyiThf6TK3W29Yy/T6x45Ws5zOasaJdsFKM="); char[] pass = { 'h', 'e', 'l', 'l', 'o', ' ', 'w', 'o', 'r', 'l', 'd' }; public void performTest() throws Exception { try { PGPPublicKey pubKey; // // Read the public key // PGPObjectFactory pgpFact = new PGPObjectFactory(testPubKeyRing); PGPPublicKeyRing pgpPub = (PGPPublicKeyRing)pgpFact.nextObject(); pubKey = pgpPub.getPublicKey(); if (pubKey.getBitStrength() != 1024) { fail("failed - key strength reported incorrectly."); } // // Read the private key // PGPSecretKeyRing sKey = new PGPSecretKeyRing(testPrivKeyRing, new BcKeyFingerprintCalculator()); PGPPrivateKey pgpPrivKey = sKey.getSecretKey().extractPrivateKey(new BcPBESecretKeyDecryptorBuilder(new BcPGPDigestCalculatorProvider()).build(pass)); // // signature generation // String data = "hello world!"; ByteArrayOutputStream bOut = new ByteArrayOutputStream(); ByteArrayInputStream testIn = new ByteArrayInputStream(data.getBytes()); PGPSignatureGenerator sGen = new PGPSignatureGenerator(new BcPGPContentSignerBuilder(PGPPublicKey.DSA, PGPUtil.SHA1)); sGen.init(PGPSignature.BINARY_DOCUMENT, pgpPrivKey); sGen.generateOnePassVersion(false).encode(bOut); PGPLiteralDataGenerator lGen = new PGPLiteralDataGenerator(); Date testDate = new Date((System.currentTimeMillis() / 1000) * 1000); OutputStream lOut = lGen.open( new UncloseableOutputStream(bOut), PGPLiteralData.BINARY, "_CONSOLE", data.getBytes().length, testDate); int ch; while ((ch = testIn.read()) >= 0) { lOut.write(ch); sGen.update((byte)ch); } lGen.close(); sGen.generate().encode(bOut); // // verify generated signature // pgpFact = new PGPObjectFactory(bOut.toByteArray()); PGPOnePassSignatureList p1 = (PGPOnePassSignatureList)pgpFact.nextObject(); PGPOnePassSignature ops = p1.get(0); PGPLiteralData p2 = (PGPLiteralData)pgpFact.nextObject(); if (!p2.getModificationTime().equals(testDate)) { fail("Modification time not preserved"); } InputStream dIn = p2.getInputStream(); ops.init(new BcPGPContentVerifierBuilderProvider(), pubKey); while ((ch = dIn.read()) >= 0) { ops.update((byte)ch); } PGPSignatureList p3 = (PGPSignatureList)pgpFact.nextObject(); if (!ops.verify(p3.get(0))) { fail("Failed generated signature check"); } // // test encryption // // // find a key suitable for encryption // long pgpKeyID = 0; AsymmetricKeyParameter pKey = null; BcPGPKeyConverter keyConverter = new BcPGPKeyConverter(); Iterator it = pgpPub.getPublicKeys(); while (it.hasNext()) { PGPPublicKey pgpKey = (PGPPublicKey)it.next(); if (pgpKey.getAlgorithm() == PGPPublicKey.ELGAMAL_ENCRYPT || pgpKey.getAlgorithm() == PGPPublicKey.ELGAMAL_GENERAL) { pKey = keyConverter.getPublicKey(pgpKey); pgpKeyID = pgpKey.getKeyID(); if (pgpKey.getBitStrength() != 1024) { fail("failed - key strength reported incorrectly."); } // // verify the key // } } AsymmetricBlockCipher c = new PKCS1Encoding(new ElGamalEngine()); c.init(true, pKey); byte[] in = "hello world".getBytes(); byte[] out = c.processBlock(in, 0, in.length); pgpPrivKey = sKey.getSecretKey(pgpKeyID).extractPrivateKey(new BcPBESecretKeyDecryptorBuilder(new BcPGPDigestCalculatorProvider()).build(pass)); c.init(false, keyConverter.getPrivateKey(pgpPrivKey)); out = c.processBlock(out, 0, out.length); if (!areEqual(in, out)) { fail("decryption failed."); } // // encrypted message // byte[] text = { (byte)'h', (byte)'e', (byte)'l', (byte)'l', (byte)'o', (byte)' ', (byte)'w', (byte)'o', (byte)'r', (byte)'l', (byte)'d', (byte)'!', (byte)'\n' }; PGPObjectFactory pgpF = new PGPObjectFactory(encMessage); PGPEncryptedDataList encList = (PGPEncryptedDataList)pgpF.nextObject(); PGPPublicKeyEncryptedData encP = (PGPPublicKeyEncryptedData)encList.get(0); InputStream clear = encP.getDataStream(new BcPublicKeyDataDecryptorFactory(pgpPrivKey)); pgpFact = new PGPObjectFactory(clear); /* No compressed data support PGPLiteralData ld = (PGPLiteralData)pgpFact.nextObject(); bOut = new ByteArrayOutputStream(); if (!ld.getFileName().equals("test.txt")) { throw new RuntimeException("wrong filename in packet"); } InputStream inLd = ld.getDataStream(); while ((ch = inLd.read()) >= 0) { bOut.write(ch); } if (!areEqual(bOut.toByteArray(), text)) { fail("wrong plain text in decrypted packet"); } // // signed and encrypted message // pgpF = new PGPObjectFactory(signedAndEncMessage); encList = (PGPEncryptedDataList)pgpF.nextObject(); encP = (PGPPublicKeyEncryptedData)encList.get(0); clear = encP.getDataStream(new BcPublicKeyDataDecryptorFactory(pgpPrivKey)); pgpFact = new PGPObjectFactory(clear); p1 = (PGPOnePassSignatureList)pgpFact.nextObject(); ops = p1.get(0); ld = (PGPLiteralData)pgpFact.nextObject(); bOut = new ByteArrayOutputStream(); if (!ld.getFileName().equals("test.txt")) { throw new RuntimeException("wrong filename in packet"); } inLd = ld.getDataStream(); // // note: we use the DSA public key here. // ops.init(new BcPGPContentVerifierBuilderProvider(), pgpPub.getPublicKey()); while ((ch = inLd.read()) >= 0) { ops.update((byte)ch); bOut.write(ch); } p3 = (PGPSignatureList)pgpFact.nextObject(); if (!ops.verify(p3.get(0))) { fail("Failed signature check"); } if (!areEqual(bOut.toByteArray(), text)) { fail("wrong plain text in decrypted packet"); } */ // // encrypt // ByteArrayOutputStream cbOut = new ByteArrayOutputStream(); PGPEncryptedDataGenerator cPk = new PGPEncryptedDataGenerator(new BcPGPDataEncryptorBuilder(SymmetricKeyAlgorithmTags.TRIPLE_DES).setSecureRandom(new SecureRandom())); PGPPublicKey puK = sKey.getSecretKey(pgpKeyID).getPublicKey(); cPk.addMethod(new BcPublicKeyKeyEncryptionMethodGenerator(puK)); OutputStream cOut = cPk.open(new UncloseableOutputStream(cbOut), bOut.toByteArray().length); cOut.write(text); cOut.close(); pgpF = new PGPObjectFactory(cbOut.toByteArray()); encList = (PGPEncryptedDataList)pgpF.nextObject(); encP = (PGPPublicKeyEncryptedData)encList.get(0); pgpPrivKey = sKey.getSecretKey(pgpKeyID).extractPrivateKey(new BcPBESecretKeyDecryptorBuilder(new BcPGPDigestCalculatorProvider()).build(pass)); clear = encP.getDataStream(new BcPublicKeyDataDecryptorFactory(pgpPrivKey)); bOut.reset(); // compressed data not supported // while ((ch = clear.read()) >= 0) // { // bOut.write(ch); // } // // out = bOut.toByteArray(); // // if (!areEqual(out, text)) // { // fail("wrong plain text in generated packet"); // } // // use of PGPKeyPair // BigInteger g = new BigInteger("153d5d6172adb43045b68ae8e1de1070b6137005686d29d3d73a7749199681ee5b212c9b96bfdcfa5b20cd5e3fd2044895d609cf9b410b7a0f12ca1cb9a428cc", 16); BigInteger p = new BigInteger("9494fec095f3b85ee286542b3836fc81a5dd0a0349b4c239dd38744d488cf8e31db8bcb7d33b41abb9e5a33cca9144b1cef332c94bf0573bf047a3aca98cdf3b", 16); ElGamalKeyPairGenerator kpg = new ElGamalKeyPairGenerator(); ElGamalParameters elParams = new ElGamalParameters(p, g); kpg.init(new ElGamalKeyGenerationParameters(new SecureRandom(), elParams)); AsymmetricCipherKeyPair kp = kpg.generateKeyPair(); PGPKeyPair pgpKp = new BcPGPKeyPair(PGPPublicKey.ELGAMAL_GENERAL , kp, new Date()); PGPPublicKey k1 = pgpKp.getPublicKey(); PGPPrivateKey k2 = pgpKp.getPrivateKey(); // check sub key encoding it = pgpPub.getPublicKeys(); while (it.hasNext()) { PGPPublicKey pgpKey = (PGPPublicKey)it.next(); if (!pgpKey.isMasterKey()) { byte[] kEnc = pgpKey.getEncoded(); PGPObjectFactory objF = new PGPObjectFactory(kEnc); PGPPublicKey k = (PGPPublicKey)objF.nextObject(); pKey = keyConverter.getPublicKey(k); pgpKeyID = k.getKeyID(); if (k.getBitStrength() != 1024) { fail("failed - key strength reported incorrectly."); } if (objF.nextObject() != null) { fail("failed - stream not fully parsed."); } } } } catch (PGPException e) { fail("exception: " + e.getMessage(), e.getUnderlyingException()); } } public String getName() { return "PGPDSAElGamalTest"; } public static void main( String[] args) { runTest(new BcPGPDSAElGamalTest()); } } bouncycastle-1.49.orig/j2me/org/bouncycastle/openpgp/test/BcPGPRSATest.java0000644000175000017500000016323411732237503026157 0ustar ebourgebourgpackage org.bouncycastle.openpgp.test; import java.io.ByteArrayInputStream; import java.io.ByteArrayOutputStream; import java.io.IOException; import java.io.InputStream; import java.io.OutputStream; import java.math.BigInteger; import java.security.SecureRandom; import java.util.Date; import java.util.Iterator; import org.bouncycastle.bcpg.BCPGOutputStream; import org.bouncycastle.bcpg.CompressionAlgorithmTags; import org.bouncycastle.bcpg.HashAlgorithmTags; import org.bouncycastle.bcpg.PublicKeyAlgorithmTags; import org.bouncycastle.bcpg.SymmetricKeyAlgorithmTags; import org.bouncycastle.bcpg.attr.ImageAttribute; import org.bouncycastle.bcpg.sig.Features; import org.bouncycastle.bcpg.sig.KeyFlags; import org.bouncycastle.crypto.AsymmetricCipherKeyPair; import org.bouncycastle.crypto.BufferedAsymmetricBlockCipher; import org.bouncycastle.crypto.KeyGenerationParameters; import org.bouncycastle.crypto.engines.RSAEngine; import org.bouncycastle.crypto.generators.RSAKeyPairGenerator; import org.bouncycastle.crypto.params.AsymmetricKeyParameter; import org.bouncycastle.crypto.params.RSAKeyGenerationParameters; import org.bouncycastle.openpgp.PGPEncryptedData; import org.bouncycastle.openpgp.PGPEncryptedDataGenerator; import org.bouncycastle.openpgp.PGPEncryptedDataList; import org.bouncycastle.openpgp.PGPKeyPair; import org.bouncycastle.openpgp.PGPKeyRingGenerator; import org.bouncycastle.openpgp.PGPLiteralData; import org.bouncycastle.openpgp.PGPLiteralDataGenerator; import org.bouncycastle.openpgp.PGPObjectFactory; import org.bouncycastle.openpgp.PGPOnePassSignature; import org.bouncycastle.openpgp.PGPOnePassSignatureList; import org.bouncycastle.openpgp.PGPPBEEncryptedData; import org.bouncycastle.openpgp.PGPPrivateKey; import org.bouncycastle.openpgp.PGPPublicKey; import org.bouncycastle.openpgp.PGPPublicKeyEncryptedData; import org.bouncycastle.openpgp.PGPPublicKeyRing; import org.bouncycastle.openpgp.PGPSecretKey; import org.bouncycastle.openpgp.PGPSecretKeyRing; import org.bouncycastle.openpgp.PGPSignature; import org.bouncycastle.openpgp.PGPSignatureGenerator; import org.bouncycastle.openpgp.PGPSignatureList; import org.bouncycastle.openpgp.PGPSignatureSubpacketGenerator; import org.bouncycastle.openpgp.PGPSignatureSubpacketVector; import org.bouncycastle.openpgp.PGPUserAttributeSubpacketVector; import org.bouncycastle.openpgp.PGPUserAttributeSubpacketVectorGenerator; import org.bouncycastle.openpgp.PGPUtil; import org.bouncycastle.openpgp.PGPV3SignatureGenerator; import org.bouncycastle.openpgp.operator.bc.BcPGPKeyPair; import org.bouncycastle.openpgp.operator.PublicKeyDataDecryptorFactory; import org.bouncycastle.openpgp.operator.bc.BcKeyFingerprintCalculator; import org.bouncycastle.openpgp.operator.bc.BcPBEDataDecryptorFactory; import org.bouncycastle.openpgp.operator.bc.BcPBEKeyEncryptionMethodGenerator; import org.bouncycastle.openpgp.operator.bc.BcPBESecretKeyDecryptorBuilder; import org.bouncycastle.openpgp.operator.bc.BcPBESecretKeyEncryptorBuilder; import org.bouncycastle.openpgp.operator.bc.BcPGPContentSignerBuilder; import org.bouncycastle.openpgp.operator.bc.BcPGPContentVerifierBuilderProvider; import org.bouncycastle.openpgp.operator.bc.BcPGPDataEncryptorBuilder; import org.bouncycastle.openpgp.operator.bc.BcPGPDigestCalculatorProvider; import org.bouncycastle.openpgp.operator.bc.BcPGPKeyConverter; import org.bouncycastle.openpgp.operator.bc.BcPublicKeyDataDecryptorFactory; import org.bouncycastle.openpgp.operator.bc.BcPublicKeyKeyEncryptionMethodGenerator; import org.bouncycastle.util.Arrays; import org.bouncycastle.util.encoders.Base64; import org.bouncycastle.util.encoders.Hex; import org.bouncycastle.util.test.SimpleTest; import org.bouncycastle.util.test.UncloseableOutputStream; public class BcPGPRSATest extends SimpleTest { byte[] testPubKey = Base64.decode( "mIsEPz2nJAEEAOTVqWMvqYE693qTgzKv/TJpIj3hI8LlYPC6m1dk0z3bDLwVVk9F" + "FAB+CWS8RdFOWt/FG3tEv2nzcoNdRvjv9WALyIGNawtae4Ml6oAT06/511yUzXHO" + "k+9xK3wkXN5jdzUhf4cA2oGpLSV/pZlocsIDL+jCUQtumUPwFodmSHhzAAYptC9F" + "cmljIEVjaGlkbmEgKHRlc3Qga2V5KSA8ZXJpY0Bib3VuY3ljYXN0bGUub3JnPoi4" + "BBMBAgAiBQI/PackAhsDBQkAg9YABAsHAwIDFQIDAxYCAQIeAQIXgAAKCRA1WGFG" + "/fPzc8WMA/9BbjuB8E48QAlxoiVf9U8SfNelrz/ONJA/bMvWr/JnOGA9PPmFD5Uc" + "+kV/q+i94dEMjsC5CQ1moUHWSP2xlQhbOzBP2+oPXw3z2fBs9XJgnTH6QWMAAvLs" + "3ug9po0loNHLobT/D/XdXvcrb3wvwvPT2FptZqrtonH/OdzT9JdfrA=="); byte[] testPrivKey = Base64.decode( "lQH8BD89pyQBBADk1aljL6mBOvd6k4Myr/0yaSI94SPC5WDwuptXZNM92wy8FVZP" + "RRQAfglkvEXRTlrfxRt7RL9p83KDXUb47/VgC8iBjWsLWnuDJeqAE9Ov+ddclM1x" + "zpPvcSt8JFzeY3c1IX+HANqBqS0lf6WZaHLCAy/owlELbplD8BaHZkh4cwAGKf4D" + "AwKbLeIOVYTEdWD5v/YgW8ERs0pDsSIfBTvsJp2qA798KeFuED6jGsHUzdi1M990" + "6PRtplQgnoYmYQrzEc6DXAiAtBR4Kuxi4XHx0ZR2wpVlVxm2Ypgz7pbBNWcWqzvw" + "33inl7tR4IDsRdJOY8cFlN+1tSCf16sDidtKXUVjRjZNYJytH18VfSPlGXMeYgtw" + "3cSGNTERwKaq5E/SozT2MKTiORO0g0Mtyz+9MEB6XVXFavMun/mXURqbZN/k9BFb" + "z+TadpkihrLD1xw3Hp+tpe4CwPQ2GdWKI9KNo5gEnbkJgLrSMGgWalPhknlNHRyY" + "bSq6lbIMJEE3LoOwvYWwweR1+GrV9farJESdunl1mDr5/d6rKru+FFDwZM3na1IF" + "4Ei4FpqhivZ4zG6pN5XqLy+AK85EiW4XH0yAKX1O4YlbmDU4BjxhiwTdwuVMCjLO" + "5++jkz5BBQWdFX8CCMA4FJl36G70IbGzuFfOj07ly7QvRXJpYyBFY2hpZG5hICh0" + "ZXN0IGtleSkgPGVyaWNAYm91bmN5Y2FzdGxlLm9yZz6IuAQTAQIAIgUCPz2nJAIb" + "AwUJAIPWAAQLBwMCAxUCAwMWAgECHgECF4AACgkQNVhhRv3z83PFjAP/QW47gfBO" + "PEAJcaIlX/VPEnzXpa8/zjSQP2zL1q/yZzhgPTz5hQ+VHPpFf6voveHRDI7AuQkN" + "ZqFB1kj9sZUIWzswT9vqD18N89nwbPVyYJ0x+kFjAALy7N7oPaaNJaDRy6G0/w/1" + "3V73K298L8Lz09habWaq7aJx/znc0/SXX6w="); byte[] testPubKeyV3 = Base64.decode( "mQCNAz+zvlEAAAEEAMS22jgXbOZ/D3xWgM2kauSdzrwlU7Ms5hDW05ObqQyO" + "FfQoKKMhfupyoa7J3x04VVBKu6Eomvr1es+VImH0esoeWFFahNOYq/I+jRRB" + "woOhAGZ5UB2/hRd7rFmxqp6sCXi8wmLO2tAorlTzAiNNvl7xF4cQZpc0z56F" + "wdi2fBUJAAURtApGSVhDSVRZX1FBiQCVAwUQP7O+UZ6Fwdi2fBUJAQFMwwQA" + "qRnFsdg4xQnB8Y5d4cOpXkIn9AZgYS3cxtuSJB84vG2CgC39nfv4c+nlLkWP" + "4puG+mZuJNgVoE84cuAF4I//1anKjlU7q1M6rFQnt5S4uxPyG3dFXmgyU1b4" + "PBOnA0tIxjPzlIhJAMsPCGGA5+5M2JP0ad6RnzqzE3EENMX+GqY="); byte[] testPrivKeyV3 = Base64.decode( "lQHfAz+zvlEAAAEEAMS22jgXbOZ/D3xWgM2kauSdzrwlU7Ms5hDW05ObqQyO" + "FfQoKKMhfupyoa7J3x04VVBKu6Eomvr1es+VImH0esoeWFFahNOYq/I+jRRB" + "woOhAGZ5UB2/hRd7rFmxqp6sCXi8wmLO2tAorlTzAiNNvl7xF4cQZpc0z56F" + "wdi2fBUJAAURAXWwRBZQHNikA/f0ScLLjrXi4s0hgQecg+dkpDow94eu5+AR" + "0DzZnfurpgfUJCNiDi5W/5c3Zj/xyrfMAgkbCgJ1m6FZqAQh7Mq73l7Kfu4/" + "XIkyDF3tDgRuZNezB+JuElX10tV03xumHepp6M6CfhXqNJ15F33F99TA5hXY" + "CPYD7SiSOpIhQkCOAgDAA63imxbpuKE2W7Y4I1BUHB7WQi8ZdkZd04njNTv+" + "rFUuOPapQVfbWG0Vq8ld3YmJB4QWsa2mmqn+qToXbwufAgBpXkjvqK5yPiHF" + "Px2QbFc1VqoCJB6PO5JRIqEiUZBFGdDlLxt3VSyqz7IZ/zEnxZq+tPCGGGSm" + "/sAGiMvENcHVAfy0kTXU42TxEAYJyyNyqjXOobDJpEV1mKhFskRXt7tbMfOS" + "Yf91oX8f6xw6O2Nal+hU8dS0Bmfmk5/enHmvRLHQocO0CkZJWENJVFlfUUE="); byte[] sig1 = Base64.decode( "owGbwMvMwMRoGpHo9vfz52LGNTJJnBmpOTn5eiUVJfb23JvAHIXy/KKcFEWuToap" + "zKwMIGG4Bqav0SwMy3yParsEKi2LMGI9xhh65sBxb05n5++ZLcWNJ/eLFKdWbm95" + "tHbDV7GMwj/tUctUpFUXWPYFCLdNsDiVNuXbQvZtdXV/5xzY+9w1nCnijH9JoNiJ" + "22n2jo0zo30/TZLo+jDl2vTzIvPeLEsPM3ZUE/1Ytqs4SG2TxIQbH7xf3uzcYXq2" + "5Fw9AA=="); byte[] sig1crc = Base64.decode("+3i0"); byte[] subKey = Base64.decode( "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" + "CphiUYWnsC0mQ+J15B4="); byte[] enc1 = Base64.decode( "hIwDKwfQexPJboABA/4/7prhYYMORTiQ5avQKx0XYpCLujzGefYjnyuWZnx3Iev8" + "Pmsguumm+OLLvtXhhkXQmkJRXbIg6Otj2ubPYWflRPgpJSgOrNOreOl5jeABOrtw" + "bV6TJb9OTtZuB7cTQSCq2gmYiSZkluIiDjNs3R3mEanILbYzOQ3zKSggKpzlv9JQ" + "AZUqTyDyJ6/OUbJF5fI5uiv76DCsw1zyMWotUIu5/X01q+AVP5Ly3STzI7xkWg/J" + "APz4zUHism7kSYz2viAQaJx9/bNnH3AM6qm1Fuyikl4="); byte[] enc1crc = Base64.decode("lv4o"); byte[] enc2 = Base64.decode( "hIwDKwfQexPJboABBAC62jcJH8xKnKb1neDVmiovYON04+7VQ2v4BmeHwJrdag1g" + "Ya++6PeBlQ2Q9lSGBwLobVuJmQ7cOnPUJP727JeSGWlMyFtMbBSHekOaTenT5lj7" + "Zk7oRHxMp/hByzlMacIDzOn8LPSh515RHM57eDLCOwqnAxGQwk67GRl8f5dFH9JQ" + "Aa7xx8rjCqPbiIQW6t5LqCNvPZOiSCmftll6+se1XJhFEuq8WS4nXtPfTiJ3vib4" + "3soJdHzGB6AOs+BQ6aKmmNTVAxa5owhtSt1Z/6dfSSk="); byte[] subPubKey = Base64.decode( "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"); byte[] subPubCrc = Base64.decode("rikt"); byte[] pgp8Key = Base64.decode( "lQIEBEBXUNMBBADScQczBibewnbCzCswc/9ut8R0fwlltBRxMW0NMdKJY2LF" + "7k2COeLOCIU95loJGV6ulbpDCXEO2Jyq8/qGw1qD3SCZNXxKs3GS8Iyh9Uwd" + "VL07nMMYl5NiQRsFB7wOb86+94tYWgvikVA5BRP5y3+O3GItnXnpWSJyREUy" + "6WI2QQAGKf4JAwIVmnRs4jtTX2DD05zy2mepEQ8bsqVAKIx7lEwvMVNcvg4Y" + "8vFLh9Mf/uNciwL4Se/ehfKQ/AT0JmBZduYMqRU2zhiBmxj4cXUQ0s36ysj7" + "fyDngGocDnM3cwPxaTF1ZRBQHSLewP7dqE7M73usFSz8vwD/0xNOHFRLKbsO" + "RqDlLA1Cg2Yd0wWPS0o7+qqk9ndqrjjSwMM8ftnzFGjShAdg4Ca7fFkcNePP" + "/rrwIH472FuRb7RbWzwXA4+4ZBdl8D4An0dwtfvAO+jCZSrLjmSpxEOveJxY" + "GduyR4IA4lemvAG51YHTHd4NXheuEqsIkn1yarwaaj47lFPnxNOElOREMdZb" + "nkWQb1jfgqO24imEZgrLMkK9bJfoDnlF4k6r6hZOp5FSFvc5kJB4cVo1QJl4" + "pwCSdoU6luwCggrlZhDnkGCSuQUUW45NE7Br22NGqn4/gHs0KCsWbAezApGj" + "qYUCfX1bcpPzUMzUlBaD5rz2vPeO58CDtBJ0ZXN0ZXIgPHRlc3RAdGVzdD6I" + "sgQTAQIAHAUCQFdQ0wIbAwQLBwMCAxUCAwMWAgECHgECF4AACgkQs8JyyQfH" + "97I1QgP8Cd+35maM2cbWV9iVRO+c5456KDi3oIUSNdPf1NQrCAtJqEUhmMSt" + "QbdiaFEkPrORISI/2htXruYn0aIpkCfbUheHOu0sef7s6pHmI2kOQPzR+C/j" + "8D9QvWsPOOso81KU2axUY8zIer64Uzqc4szMIlLw06c8vea27RfgjBpSCryw" + "AgAA"); char[] pgp8Pass = "2002 Buffalo Sabres".toCharArray(); char[] pass = { 'h', 'e', 'l', 'l', 'o', ' ', 'w', 'o', 'r', 'l', 'd' }; byte[] fingerprintKey = Base64.decode( "mQEPA0CiJdUAAAEIAMI+znDlPd2kQoEcnxqxLcRz56Z7ttFKHpnYp0UkljZdquVc" + "By1jMfXGVV64xN1IvMcyenLXUE0IUeUBCQs6tHunFRAPSeCxJ3FdFe1B5MpqQG8A" + "BnEpAds/hAUfRDZD5y/lolk1hjvFMrRh6WXckaA/QQ2t00NmTrJ1pYUpkw9tnVQb" + "LUjWJhfZDBBcN0ADtATzgkugxMtcDxR6I5x8Ndn+IilqIm23kxGIcmMd/BHOec4c" + "jRwJXXDb7u8tl+2knAf9cwhPHp3+Zy4uGSQPdzQnXOhBlA+4WDa0RROOevWgq8uq" + "8/9Xp/OlTVL+OoIzjsI6mJP1Joa4qmqAnaHAmXcAEQEAAbQoQk9BM1JTS1kgPEJP" + "QSBNb25pdG9yaW5nIEAgODg4LTI2OS01MjY2PokBFQMFEECiJdWqaoCdocCZdwEB" + "0RsH/3HPxoUZ3G3K7T3jgOnJUckTSHWU3XspHzMVgqOxjTrcexi5IsAM5M+BulfW" + "T2aO+Kqf5w8cKTKgW02DNpHUiPjHx0nzDE+Do95zbIErGeK+Twkc4O/aVsvU9GGO" + "81VFI6WMvDQ4CUAUnAdk03MRrzI2nAuhn4NJ5LQS+uJrnqUJ4HmFAz6CQZQKd/kS" + "Xgq+A6i7aI1LG80YxWa9ooQgaCrb9dwY/kPQ+yC22zQ3FExtv+Fv3VtAKTilO3vn" + "BA4Y9uTHuObHfI+1yxUS2PrlRUX0m48ZjpIX+cEN3QblGBJudI/A1QSd6P0LZeBr" + "7F1Z1aF7ZDo0KzgiAIBvgXkeTpw="); byte[] fingerprintCheck = Base64.decode("CTv2"); byte[] expiry60and30daysSig13Key = Base64.decode( "mQGiBENZt/URBAC5JccXiwe4g6MuviEC8NI/x0NaVkGFAOY04d5E4jeIycBP" + "SrpOPrjETuigqhrj8oqed2+2yUqfnK4nhTsTAjyeJ3PpWC1pGAKzJgYmJk+K" + "9aTLq0BQWiXDdv5RG6fDmeq1umvOfcXBqGFAguLPZC+U872bSLnfe3lqGNA8" + "jvmY7wCgjhzVQVm10NN5ST8nemPEcSjnBrED/R494gHL6+r5OgUgXnNCDejA" + "4InoDImQCF+g7epp5E1MB6CMYSg2WSY2jHFuHpwnUb7AiOO0ZZ3UBqM9rYnK" + "kDvxkFCxba7Ms+aFj9blRNmy3vG4FewDcTdxzCtjUk6dRfu6UoARpqlTE/q7" + "Xo6EQP1ncwJ+UTlcHkTBvg/usI/yBACGjBqX8glb5VfNaZgNHMeS/UIiUiuV" + "SVFojiSDOHcnCe/6y4M2gVm38zz1W9qhoLfLpiAOFeL0yj6wzXvsjjXQiKQ8" + "nBE4Mf+oeH2qiQ/LfzQrGpI5eNcMXrzK9nigmz2htYO2GjQfupEnu1RHBTH8" + "NjofD2AShL9IO73plRuExrQgVGVzdCBLZXkgPHRlc3RAYm91bmN5Y2FzdGxl" + "Lm9yZz6IZAQTEQIAJAIbAwYLCQgHAwIDFQIDAxYCAQIeAQIXgAUCQ1m4DgUJ" + "AE8aGQAKCRD8QP1QuU7Kqw+eAJ0dZ3ZAqr73X61VmCkbyPoszLQMAQCfdFs2" + "YMDeUvX34Q/8Ba0KgO5f3RSwAgADuM0EQ1m39hADAIHpVGcLqS9UkmQaWBvH" + "WP6TnN7Y1Ha0TJOuxpbFjBW+CmVh/FjcsnavFXDXpo2zc742WT+vrHBSa/0D" + "1QEBsnCaX5SRRVp7Mqs8q+aDhjcHMIP8Sdxf7GozXDORkrRaJwADBQL9HLYm" + "7Rr5iYWDcvs+Pi6O1zUyb1tjkxEGaV/rcozl2MMmr2mzJ6x/Bz8SuhZEJS0m" + "bB2CvAA39aQi9jHlV7q0SV73NOkd2L/Vt2UZhzlUdvrJ37PgYDv+Wd9Ufz6g" + "MzLSiE8EGBECAA8FAkNZt/YCGwwFCQAnjQAACgkQ/ED9ULlOyqsTqQCcDnAZ" + "7YymCfhm1yJiuFQg3qiX6Z4An19OSEgeSKugVcH49g1sxUB0zNdIsAIAAw=="); byte[] jpegImage = Base64.decode( "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"); byte[] embeddedJPEGKey = Base64.decode( "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" + "Qvmtc8X7lqK/zLRVkSSBItik2IIhsAIAAw=="); private void fingerPrintTest() throws Exception { // // version 3 // PGPPublicKeyRing pgpPub = new PGPPublicKeyRing(fingerprintKey, new BcKeyFingerprintCalculator()); PGPPublicKey pubKey = pgpPub.getPublicKey(); if (!areEqual(pubKey.getFingerprint(), Hex.decode("4FFB9F0884266C715D1CEAC804A3BBFA"))) { fail("version 3 fingerprint test failed"); } // // version 4 // pgpPub = new PGPPublicKeyRing(testPubKey, new BcKeyFingerprintCalculator()); pubKey = pgpPub.getPublicKey(); if (!areEqual(pubKey.getFingerprint(), Hex.decode("3062363c1046a01a751946bb35586146fdf3f373"))) { fail("version 4 fingerprint test failed"); } } private void mixedTest(PGPPrivateKey pgpPrivKey, PGPPublicKey pgpPubKey) throws Exception { byte[] text = { (byte)'h', (byte)'e', (byte)'l', (byte)'l', (byte)'o', (byte)' ', (byte)'w', (byte)'o', (byte)'r', (byte)'l', (byte)'d', (byte)'!', (byte)'\n' }; // // literal data // ByteArrayOutputStream bOut = new ByteArrayOutputStream(); PGPLiteralDataGenerator lGen = new PGPLiteralDataGenerator(); OutputStream lOut = lGen.open(bOut, PGPLiteralData.BINARY, PGPLiteralData.CONSOLE, text.length, new Date()); lOut.write(text); lGen.close(); byte[] bytes = bOut.toByteArray(); PGPObjectFactory f = new PGPObjectFactory(bytes); checkLiteralData((PGPLiteralData)f.nextObject(), text); ByteArrayOutputStream bcOut = new ByteArrayOutputStream(); PGPEncryptedDataGenerator encGen = new PGPEncryptedDataGenerator(new BcPGPDataEncryptorBuilder(SymmetricKeyAlgorithmTags.AES_128).setWithIntegrityPacket(true).setSecureRandom(new SecureRandom())); encGen.addMethod(new BcPublicKeyKeyEncryptionMethodGenerator(pgpPubKey)); encGen.addMethod(new BcPBEKeyEncryptionMethodGenerator("password".toCharArray())); OutputStream cOut = encGen.open(bcOut, bytes.length); cOut.write(bytes); cOut.close(); byte[] encData = bcOut.toByteArray(); // // asymmetric // PGPObjectFactory pgpF = new PGPObjectFactory(encData); PGPEncryptedDataList encList = (PGPEncryptedDataList)pgpF.nextObject(); PGPPublicKeyEncryptedData encP = (PGPPublicKeyEncryptedData)encList.get(0); InputStream clear = encP.getDataStream(new BcPublicKeyDataDecryptorFactory(pgpPrivKey)); PGPObjectFactory pgpFact = new PGPObjectFactory(clear); checkLiteralData((PGPLiteralData)pgpFact.nextObject(), text); // // PBE // pgpF = new PGPObjectFactory(encData); encList = (PGPEncryptedDataList)pgpF.nextObject(); PGPPBEEncryptedData encPbe = (PGPPBEEncryptedData)encList.get(1); clear = encPbe.getDataStream(new BcPBEDataDecryptorFactory("password".toCharArray(), new BcPGPDigestCalculatorProvider())); pgpF = new PGPObjectFactory(clear); checkLiteralData((PGPLiteralData)pgpF.nextObject(), text); } private void checkLiteralData(PGPLiteralData ld, byte[] data) throws IOException { ByteArrayOutputStream bOut = new ByteArrayOutputStream(); if (!ld.getFileName().equals(PGPLiteralData.CONSOLE)) { throw new RuntimeException("wrong filename in packet"); } InputStream inLd = ld.getDataStream(); int ch; while ((ch = inLd.read()) >= 0) { bOut.write(ch); } if (!areEqual(bOut.toByteArray(), data)) { fail("wrong plain text in decrypted packet"); } } private void existingEmbeddedJpegTest() throws Exception { PGPPublicKeyRing pgpPub = new PGPPublicKeyRing(embeddedJPEGKey, new BcKeyFingerprintCalculator()); PGPPublicKey pubKey = pgpPub.getPublicKey(); Iterator it = pubKey.getUserAttributes(); int count = 0; while (it.hasNext()) { PGPUserAttributeSubpacketVector attributes = (PGPUserAttributeSubpacketVector)it.next(); Iterator sigs = pubKey.getSignaturesForUserAttribute(attributes); int sigCount = 0; while (sigs.hasNext()) { PGPSignature sig = (PGPSignature)sigs.next(); sig.init(new BcPGPContentVerifierBuilderProvider(), pubKey); if (!sig.verifyCertification(attributes, pubKey)) { fail("signature failed verification"); } sigCount++; } if (sigCount != 1) { fail("Failed user attributes signature check"); } count++; } if (count != 1) { fail("didn't find user attributes"); } } private void embeddedJpegTest() throws Exception { PGPPublicKeyRing pgpPub = new PGPPublicKeyRing(testPubKey, new BcKeyFingerprintCalculator()); PGPSecretKeyRing pgpSec = new PGPSecretKeyRing(testPrivKey, new BcKeyFingerprintCalculator()); PGPPublicKey pubKey = pgpPub.getPublicKey(); PGPUserAttributeSubpacketVectorGenerator vGen = new PGPUserAttributeSubpacketVectorGenerator(); vGen.setImageAttribute(ImageAttribute.JPEG, jpegImage); PGPUserAttributeSubpacketVector uVec = vGen.generate(); PGPSignatureGenerator sGen = new PGPSignatureGenerator(new BcPGPContentSignerBuilder(PublicKeyAlgorithmTags.RSA_GENERAL, HashAlgorithmTags.SHA1)); sGen.init(PGPSignature.POSITIVE_CERTIFICATION, pgpSec.getSecretKey().extractPrivateKey(new BcPBESecretKeyDecryptorBuilder(new BcPGPDigestCalculatorProvider()).build(pass))); PGPSignature sig = sGen.generateCertification(uVec, pubKey); PGPPublicKey nKey = PGPPublicKey.addCertification(pubKey, uVec, sig); Iterator it = nKey.getUserAttributes(); int count = 0; while (it.hasNext()) { PGPUserAttributeSubpacketVector attributes = (PGPUserAttributeSubpacketVector)it.next(); Iterator sigs = nKey.getSignaturesForUserAttribute(attributes); int sigCount = 0; while (sigs.hasNext()) { PGPSignature s = (PGPSignature)sigs.next(); s.init(new BcPGPContentVerifierBuilderProvider(), pubKey); if (!s.verifyCertification(attributes, pubKey)) { fail("added signature failed verification"); } sigCount++; } if (sigCount != 1) { fail("Failed added user attributes signature check"); } count++; } if (count != 1) { fail("didn't find added user attributes"); } nKey = PGPPublicKey.removeCertification(nKey, uVec); count = 0; for (it = nKey.getUserAttributes(); it.hasNext();) { count++; } if (count != 0) { fail("found attributes where none expected"); } } private void sigsubpacketTest() throws Exception { char[] passPhrase = "test".toCharArray(); String identity = "TEST "; Date date = new Date(); RSAKeyPairGenerator kpg = new RSAKeyPairGenerator(); kpg.init(new RSAKeyGenerationParameters(BigInteger.valueOf(0x11), new SecureRandom(), 2048, 25)); AsymmetricCipherKeyPair kpSgn = kpg.generateKeyPair(); AsymmetricCipherKeyPair kpEnc = kpg.generateKeyPair(); PGPKeyPair sgnKeyPair = new BcPGPKeyPair(PGPPublicKey.RSA_SIGN, kpSgn, date); PGPKeyPair encKeyPair = new BcPGPKeyPair(PGPPublicKey.RSA_GENERAL, kpEnc, date); PGPSignatureSubpacketVector unhashedPcks = null; PGPSignatureSubpacketGenerator svg = new PGPSignatureSubpacketGenerator(); svg.setKeyExpirationTime(true, 86400L * 366 * 2); svg.setPrimaryUserID(true, true); int[] encAlgs = {SymmetricKeyAlgorithmTags.AES_256, SymmetricKeyAlgorithmTags.AES_192, SymmetricKeyAlgorithmTags.TRIPLE_DES}; svg.setPreferredSymmetricAlgorithms(true, encAlgs); int[] hashAlgs = {HashAlgorithmTags.SHA1, HashAlgorithmTags.SHA512, HashAlgorithmTags.SHA384, HashAlgorithmTags.SHA256, HashAlgorithmTags.RIPEMD160}; svg.setPreferredHashAlgorithms(true, hashAlgs); int[] comprAlgs = {CompressionAlgorithmTags.ZLIB, CompressionAlgorithmTags.BZIP2, CompressionAlgorithmTags.ZIP}; svg.setPreferredCompressionAlgorithms(true, comprAlgs); svg.setFeature(true, Features.FEATURE_MODIFICATION_DETECTION); svg.setKeyFlags(true, KeyFlags.CERTIFY_OTHER + KeyFlags.SIGN_DATA); PGPSignatureSubpacketVector hashedPcks = svg.generate(); PGPKeyRingGenerator keyRingGen = new PGPKeyRingGenerator(PGPSignature.POSITIVE_CERTIFICATION, sgnKeyPair, identity, new BcPGPDigestCalculatorProvider().get(HashAlgorithmTags.SHA1), hashedPcks, unhashedPcks, new BcPGPContentSignerBuilder(PGPPublicKey.RSA_GENERAL, HashAlgorithmTags.SHA1), new BcPBESecretKeyEncryptorBuilder(PGPEncryptedData.AES_256).build(passPhrase)); svg = new PGPSignatureSubpacketGenerator(); svg.setKeyExpirationTime(true, 86400L * 366 * 2); svg.setKeyFlags(true, KeyFlags.ENCRYPT_COMMS + KeyFlags.ENCRYPT_STORAGE); svg.setPrimaryUserID(true, false); svg.setFeature(true, Features.FEATURE_MODIFICATION_DETECTION); hashedPcks = svg.generate(); keyRingGen.addSubKey(encKeyPair, hashedPcks, unhashedPcks); byte[] encodedKeyRing = keyRingGen.generatePublicKeyRing().getEncoded(); PGPPublicKeyRing keyRing = new PGPPublicKeyRing(encodedKeyRing, new BcKeyFingerprintCalculator()); for (Iterator it = keyRing.getPublicKeys(); it.hasNext();) { PGPPublicKey pKey = (PGPPublicKey)it.next(); if (pKey.isEncryptionKey()) { for (Iterator sit = pKey.getSignatures(); sit.hasNext();) { PGPSignature sig = (PGPSignature)sit.next(); PGPSignatureSubpacketVector v = sig.getHashedSubPackets(); if (v.getKeyExpirationTime() != 86400L * 366 * 2) { fail("key expiration time wrong"); } if (!v.getFeatures().supportsFeature(Features.FEATURE_MODIFICATION_DETECTION)) { fail("features wrong"); } if (v.isPrimaryUserID()) { fail("primary userID flag wrong"); } if (v.getKeyFlags() != KeyFlags.ENCRYPT_COMMS + KeyFlags.ENCRYPT_STORAGE) { fail("keyFlags wrong"); } } } else { for (Iterator sit = pKey.getSignatures(); sit.hasNext();) { PGPSignature sig = (PGPSignature)sit.next(); PGPSignatureSubpacketVector v = sig.getHashedSubPackets(); if (!Arrays.areEqual(v.getPreferredSymmetricAlgorithms(), encAlgs)) { fail("preferred encryption algs don't match"); } if (!Arrays.areEqual(v.getPreferredHashAlgorithms(), hashAlgs)) { fail("preferred hash algs don't match"); } if (!Arrays.areEqual(v.getPreferredCompressionAlgorithms(), comprAlgs)) { fail("preferred compression algs don't match"); } if (!v.getFeatures().supportsFeature(Features.FEATURE_MODIFICATION_DETECTION)) { fail("features wrong"); } if (v.getKeyFlags() != KeyFlags.CERTIFY_OTHER + KeyFlags.SIGN_DATA) { fail("keyFlags wrong"); } } } } } public void performTest() throws Exception { // // Read the public key // PGPPublicKeyRing pgpPub = new PGPPublicKeyRing(testPubKey, new BcKeyFingerprintCalculator()); AsymmetricKeyParameter pubKey = new BcPGPKeyConverter().getPublicKey(pgpPub.getPublicKey()); Iterator it = pgpPub.getPublicKey().getUserIDs(); String uid = (String)it.next(); it = pgpPub.getPublicKey().getSignaturesForID(uid); PGPSignature sig = (PGPSignature)it.next(); sig.init(new BcPGPContentVerifierBuilderProvider(), pgpPub.getPublicKey()); if (!sig.verifyCertification(uid, pgpPub.getPublicKey())) { fail("failed to verify certification"); } // // write a public key // ByteArrayOutputStream bOut = new ByteArrayOutputStream(); BCPGOutputStream pOut = new BCPGOutputStream(bOut); pgpPub.encode(pOut); if (!areEqual(bOut.toByteArray(), testPubKey)) { fail("public key rewrite failed"); } // // Read the public key // PGPPublicKeyRing pgpPubV3 = new PGPPublicKeyRing(testPubKeyV3, new BcKeyFingerprintCalculator()); AsymmetricKeyParameter pubKeyV3 = new BcPGPKeyConverter().getPublicKey(pgpPub.getPublicKey()); // // write a V3 public key // bOut = new ByteArrayOutputStream(); pOut = new BCPGOutputStream(bOut); pgpPubV3.encode(pOut); // // Read a v3 private key // char[] passP = "FIXCITY_QA".toCharArray(); if (!noIDEA()) { PGPSecretKeyRing pgpPriv = new PGPSecretKeyRing(testPrivKeyV3, new BcKeyFingerprintCalculator()); PGPPrivateKey pgpPrivKey = pgpPriv.getSecretKey().extractPrivateKey(new BcPBESecretKeyDecryptorBuilder(new BcPGPDigestCalculatorProvider()).build(passP)); // // write a v3 private key // bOut = new ByteArrayOutputStream(); pOut = new BCPGOutputStream(bOut); pgpPriv.encode(pOut); if (!areEqual(bOut.toByteArray(), testPrivKeyV3)) { fail("private key V3 rewrite failed"); } } // // Read the private key // PGPSecretKeyRing pgpPriv = new PGPSecretKeyRing(testPrivKey, new BcKeyFingerprintCalculator()); PGPPrivateKey pgpPrivKey = pgpPriv.getSecretKey().extractPrivateKey(new BcPBESecretKeyDecryptorBuilder(new BcPGPDigestCalculatorProvider()).build(pass)); // // write a private key // bOut = new ByteArrayOutputStream(); pOut = new BCPGOutputStream(bOut); pgpPriv.encode(pOut); if (!areEqual(bOut.toByteArray(), testPrivKey)) { fail("private key rewrite failed"); } // // test encryption // BufferedAsymmetricBlockCipher c = new BufferedAsymmetricBlockCipher(new RSAEngine()); c.init(true, pubKey); byte[] in = "hello world".getBytes(); c.processBytes(in, 0, in.length); byte[] out = c.doFinal(); c.init(false, new BcPGPKeyConverter().getPrivateKey(pgpPrivKey)); c.processBytes(out, 0, out.length); out = c.doFinal(); if (!areEqual(in, out)) { fail("decryption failed."); } // // test signature message // PGPObjectFactory pgpFact = new PGPObjectFactory(sig1, new BcKeyFingerprintCalculator()); // PGPOnePassSignatureList p1 = (PGPOnePassSignatureList)pgpFact.nextObject(); // PGPOnePassSignature ops = p1.get(0); // compression not supported // PGPLiteralData p2 = (PGPLiteralData)pgpFact.nextObject(); // // InputStream dIn = p2.getInputStream(); // int ch; // // ops.init(new BcPGPContentVerifierBuilderProvider(), pgpPub.getPublicKey(ops.getKeyID())); // // while ((ch = dIn.read()) >= 0) // { // ops.update((byte)ch); // } // // PGPSignatureList p3 = (PGPSignatureList)pgpFact.nextObject(); // // if (!ops.verify(p3.get(0))) // { // fail("Failed signature check"); // } // // // encrypted message - read subkey // pgpPriv = new PGPSecretKeyRing(subKey, new BcKeyFingerprintCalculator()); // // encrypted message // byte[] text = { (byte)'h', (byte)'e', (byte)'l', (byte)'l', (byte)'o', (byte)' ', (byte)'w', (byte)'o', (byte)'r', (byte)'l', (byte)'d', (byte)'!', (byte)'\n' }; PGPObjectFactory pgpF = new PGPObjectFactory(enc1, new BcKeyFingerprintCalculator()); PGPEncryptedDataList encList = (PGPEncryptedDataList)pgpF.nextObject(); PGPPublicKeyEncryptedData encP = (PGPPublicKeyEncryptedData)encList.get(0); pgpPrivKey = pgpPriv.getSecretKey(encP.getKeyID()).extractPrivateKey(new BcPBESecretKeyDecryptorBuilder(new BcPGPDigestCalculatorProvider()).build(pass)); InputStream clear = encP.getDataStream(new BcPublicKeyDataDecryptorFactory(pgpPrivKey)); pgpFact = new PGPObjectFactory(clear, new BcKeyFingerprintCalculator()); // compressed data not supported // PGPLiteralData ld = (PGPLiteralData)pgpFact.nextObject(); // // bOut = new ByteArrayOutputStream(); // // if (!ld.getFileName().equals("test.txt")) // { // throw new RuntimeException("wrong filename in packet"); // } // // InputStream inLd = ld.getDataStream(); // int ch; // // while ((ch = inLd.read()) >= 0) // { // bOut.write(ch); // } // // if (!areEqual(bOut.toByteArray(), text)) // { // fail("wrong plain text in decrypted packet"); // } // // encrypt - short message // byte[] shortText = { (byte)'h', (byte)'e', (byte)'l', (byte)'l', (byte)'o' }; ByteArrayOutputStream cbOut = new ByteArrayOutputStream(); PGPEncryptedDataGenerator cPk = new PGPEncryptedDataGenerator(new BcPGPDataEncryptorBuilder(SymmetricKeyAlgorithmTags.CAST5).setSecureRandom(new SecureRandom())); PGPPublicKey puK = pgpPriv.getSecretKey(encP.getKeyID()).getPublicKey(); cPk.addMethod(new BcPublicKeyKeyEncryptionMethodGenerator(puK)); OutputStream cOut = cPk.open(new UncloseableOutputStream(cbOut), shortText.length); cOut.write(shortText); cOut.close(); pgpF = new PGPObjectFactory(cbOut.toByteArray(), new BcKeyFingerprintCalculator()); encList = (PGPEncryptedDataList)pgpF.nextObject(); encP = (PGPPublicKeyEncryptedData)encList.get(0); pgpPrivKey = pgpPriv.getSecretKey(encP.getKeyID()).extractPrivateKey(new BcPBESecretKeyDecryptorBuilder(new BcPGPDigestCalculatorProvider()).build(pass)); PublicKeyDataDecryptorFactory dataDecryptorFactory = new BcPublicKeyDataDecryptorFactory(pgpPrivKey); if (encP.getSymmetricAlgorithm(dataDecryptorFactory) != SymmetricKeyAlgorithmTags.CAST5) { fail("symmetric algorithm mismatch"); } clear = encP.getDataStream(dataDecryptorFactory); bOut.reset(); int ch; while ((ch = clear.read()) >= 0) { bOut.write(ch); } out = bOut.toByteArray(); if (!areEqual(out, shortText)) { fail("wrong plain text in generated short text packet"); } // // encrypt // cbOut = new ByteArrayOutputStream(); cPk = new PGPEncryptedDataGenerator(new BcPGPDataEncryptorBuilder(SymmetricKeyAlgorithmTags.CAST5).setSecureRandom(new SecureRandom())); puK = pgpPriv.getSecretKey(encP.getKeyID()).getPublicKey(); cPk.addMethod(new BcPublicKeyKeyEncryptionMethodGenerator(puK)); cOut = cPk.open(new UncloseableOutputStream(cbOut), text.length); cOut.write(text); cOut.close(); pgpF = new PGPObjectFactory(cbOut.toByteArray()); encList = (PGPEncryptedDataList)pgpF.nextObject(); encP = (PGPPublicKeyEncryptedData)encList.get(0); pgpPrivKey = pgpPriv.getSecretKey(encP.getKeyID()).extractPrivateKey(new BcPBESecretKeyDecryptorBuilder(new BcPGPDigestCalculatorProvider()).build(pass)); clear = encP.getDataStream(new BcPublicKeyDataDecryptorFactory(pgpPrivKey)); bOut.reset(); while ((ch = clear.read()) >= 0) { bOut.write(ch); } out = bOut.toByteArray(); if (!areEqual(out, text)) { fail("wrong plain text in generated packet"); } // // read public key with sub key. // pgpF = new PGPObjectFactory(subPubKey, new BcKeyFingerprintCalculator()); Object o; // while ((o = pgpFact.nextObject()) != null) // { // // System.out.println(o); // } // // key pair generation - CAST5 encryption // char[] passPhrase = "hello".toCharArray(); RSAKeyPairGenerator kpg = new RSAKeyPairGenerator(); kpg.init(new RSAKeyGenerationParameters(BigInteger.valueOf(0x11), new SecureRandom(), 1024, 25)); AsymmetricCipherKeyPair kp = kpg.generateKeyPair(); PGPSecretKey secretKey = new PGPSecretKey(PGPSignature.DEFAULT_CERTIFICATION, new BcPGPKeyPair(PublicKeyAlgorithmTags.RSA_GENERAL, kp, new Date()), "fred", null, null, new BcPGPContentSignerBuilder(PublicKeyAlgorithmTags.RSA_GENERAL, HashAlgorithmTags.SHA1), new BcPBESecretKeyEncryptorBuilder(SymmetricKeyAlgorithmTags.CAST5).build(passPhrase)); PGPPublicKey key = secretKey.getPublicKey(); it = key.getUserIDs(); uid = (String)it.next(); it = key.getSignaturesForID(uid); sig = (PGPSignature)it.next(); sig.init(new BcPGPContentVerifierBuilderProvider(), key); if (!sig.verifyCertification(uid, key)) { fail("failed to verify certification"); } pgpPrivKey = secretKey.extractPrivateKey(new BcPBESecretKeyDecryptorBuilder(new BcPGPDigestCalculatorProvider()).build(passPhrase)); key = PGPPublicKey.removeCertification(key, uid, sig); if (key == null) { fail("failed certification removal"); } byte[] keyEnc = key.getEncoded(); key = PGPPublicKey.addCertification(key, uid, sig); keyEnc = key.getEncoded(); PGPSignatureGenerator sGen = new PGPSignatureGenerator(new BcPGPContentSignerBuilder(PublicKeyAlgorithmTags.RSA_GENERAL, HashAlgorithmTags.SHA1)); sGen.init(PGPSignature.KEY_REVOCATION, secretKey.extractPrivateKey(new BcPBESecretKeyDecryptorBuilder(new BcPGPDigestCalculatorProvider()).build(passPhrase))); sig = sGen.generateCertification(key); key = PGPPublicKey.addCertification(key, sig); keyEnc = key.getEncoded(); PGPPublicKeyRing tmpRing = new PGPPublicKeyRing(keyEnc, new BcKeyFingerprintCalculator()); key = tmpRing.getPublicKey(); Iterator sgIt = key.getSignaturesOfType(PGPSignature.KEY_REVOCATION); sig = (PGPSignature)sgIt.next(); sig.init(new BcPGPContentVerifierBuilderProvider(), key); if (!sig.verifyCertification(key)) { fail("failed to verify revocation certification"); } // // use of PGPKeyPair // PGPKeyPair pgpKp = new BcPGPKeyPair(PGPPublicKey.RSA_GENERAL , kp, new Date()); PGPPublicKey k1 = pgpKp.getPublicKey(); PGPPrivateKey k2 = pgpKp.getPrivateKey(); k1.getEncoded(); mixedTest(k2, k1); // // key pair generation - AES_256 encryption. // kp = kpg.generateKeyPair(); secretKey = new PGPSecretKey(PGPSignature.DEFAULT_CERTIFICATION, pgpKp, "fred", null, null, new BcPGPContentSignerBuilder(PublicKeyAlgorithmTags.RSA_GENERAL, HashAlgorithmTags.SHA1), new BcPBESecretKeyEncryptorBuilder(SymmetricKeyAlgorithmTags.AES_256).build(passPhrase)); secretKey.extractPrivateKey(new BcPBESecretKeyDecryptorBuilder(new BcPGPDigestCalculatorProvider()).build(passPhrase)); secretKey.encode(new ByteArrayOutputStream()); // // secret key password changing. // String newPass = "newPass"; secretKey = PGPSecretKey.copyWithNewPassword(secretKey, new BcPBESecretKeyDecryptorBuilder(new BcPGPDigestCalculatorProvider()).build(passPhrase), new BcPBESecretKeyEncryptorBuilder(secretKey.getKeyEncryptionAlgorithm()).build(newPass.toCharArray())); secretKey.extractPrivateKey(new BcPBESecretKeyDecryptorBuilder(new BcPGPDigestCalculatorProvider()).build(newPass.toCharArray())); secretKey.encode(new ByteArrayOutputStream()); key = secretKey.getPublicKey(); key.encode(new ByteArrayOutputStream()); it = key.getUserIDs(); uid = (String)it.next(); it = key.getSignaturesForID(uid); sig = (PGPSignature)it.next(); sig.init(new BcPGPContentVerifierBuilderProvider(), key); if (!sig.verifyCertification(uid, key)) { fail("failed to verify certification"); } pgpPrivKey = secretKey.extractPrivateKey(new BcPBESecretKeyDecryptorBuilder(new BcPGPDigestCalculatorProvider()).build(newPass.toCharArray())); // // signature generation // String data = "hello world!"; bOut = new ByteArrayOutputStream(); ByteArrayInputStream testIn = new ByteArrayInputStream(data.getBytes()); sGen = new PGPSignatureGenerator(new BcPGPContentSignerBuilder(PublicKeyAlgorithmTags.RSA_GENERAL, HashAlgorithmTags.SHA1)); sGen.init(PGPSignature.BINARY_DOCUMENT, pgpPrivKey); sGen.generateOnePassVersion(false).encode(bOut); PGPLiteralDataGenerator lGen = new PGPLiteralDataGenerator(); Date testDate = new Date((System.currentTimeMillis() / 1000) * 1000); OutputStream lOut = lGen.open( new UncloseableOutputStream(bOut), PGPLiteralData.BINARY, "_CONSOLE", data.getBytes().length, testDate); while ((ch = testIn.read()) >= 0) { lOut.write(ch); sGen.update((byte)ch); } lOut.close(); sGen.generate().encode(bOut); bOut.close(); // // verify generated signature // pgpFact = new PGPObjectFactory(bOut.toByteArray()); PGPOnePassSignatureList p1 = (PGPOnePassSignatureList)pgpFact.nextObject(); PGPOnePassSignature ops = p1.get(0); PGPLiteralData p2 = (PGPLiteralData)pgpFact.nextObject(); if (!p2.getModificationTime().equals(testDate)) { fail("Modification time not preserved: " + p2.getModificationTime() + " " + testDate); } InputStream dIn = p2.getInputStream(); ops.init(new BcPGPContentVerifierBuilderProvider(), secretKey.getPublicKey()); while ((ch = dIn.read()) >= 0) { ops.update((byte)ch); } PGPSignatureList p3 = (PGPSignatureList)pgpFact.nextObject(); if (!ops.verify(p3.get(0))) { fail("Failed generated signature check"); } // // signature generation - version 3 // bOut = new ByteArrayOutputStream(); testIn = new ByteArrayInputStream(data.getBytes()); PGPV3SignatureGenerator sGenV3 = new PGPV3SignatureGenerator(new BcPGPContentSignerBuilder(PGPPublicKey.RSA_GENERAL, PGPUtil.SHA1)); sGen.init(PGPSignature.BINARY_DOCUMENT, pgpPrivKey); sGen.generateOnePassVersion(false).encode(bOut); lGen = new PGPLiteralDataGenerator(); lOut = lGen.open( new UncloseableOutputStream(bOut), PGPLiteralData.BINARY, "_CONSOLE", data.getBytes().length, testDate); while ((ch = testIn.read()) >= 0) { lOut.write(ch); sGen.update((byte)ch); } lOut.close(); sGen.generate().encode(bOut); bOut.close(); // // verify generated signature // pgpFact = new PGPObjectFactory(bOut.toByteArray()); p1 = (PGPOnePassSignatureList)pgpFact.nextObject(); ops = p1.get(0); p2 = (PGPLiteralData)pgpFact.nextObject(); if (!p2.getModificationTime().equals(testDate)) { fail("Modification time not preserved"); } dIn = p2.getInputStream(); ops.init(new BcPGPContentVerifierBuilderProvider(), secretKey.getPublicKey()); while ((ch = dIn.read()) >= 0) { ops.update((byte)ch); } p3 = (PGPSignatureList)pgpFact.nextObject(); if (!ops.verify(p3.get(0))) { fail("Failed v3 generated signature check"); } // // extract PGP 8 private key // pgpPriv = new PGPSecretKeyRing(pgp8Key, new BcKeyFingerprintCalculator()); secretKey = pgpPriv.getSecretKey(); pgpPrivKey = secretKey.extractPrivateKey(new BcPBESecretKeyDecryptorBuilder(new BcPGPDigestCalculatorProvider()).build(pgp8Pass)); // // expiry // testExpiry(expiry60and30daysSig13Key, 60, 30); fingerPrintTest(); existingEmbeddedJpegTest(); embeddedJpegTest(); sigsubpacketTest(); } private void testExpiry( byte[] encodedRing, int masterDays, int subKeyDays) throws Exception { PGPPublicKeyRing pubRing = new PGPPublicKeyRing(encodedRing, new BcKeyFingerprintCalculator()); PGPPublicKey k = pubRing.getPublicKey(); if (k.getValidDays() != masterDays) { fail("mismatch on master valid days."); } Iterator it = pubRing.getPublicKeys(); it.next(); k = (PGPPublicKey)it.next(); if (k.getValidDays() != subKeyDays) { fail("mismatch on subkey valid days."); } } private boolean noIDEA() { return true; } public String getName() { return "BcPGPRSATest"; } public static void main( String[] args) { runTest(new BcPGPRSATest()); } } bouncycastle-1.49.orig/j2me/org/bouncycastle/openpgp/test/BcPGPDSATest.java0000644000175000017500000007166611732242753026153 0ustar ebourgebourgpackage org.bouncycastle.openpgp.test; import java.io.ByteArrayInputStream; import java.io.ByteArrayOutputStream; import java.io.InputStream; import java.io.OutputStream; import java.math.BigInteger; import java.security.SecureRandom; import java.util.Date; import java.util.Iterator; import org.bouncycastle.bcpg.HashAlgorithmTags; import org.bouncycastle.bcpg.PublicKeyAlgorithmTags; import org.bouncycastle.crypto.AsymmetricCipherKeyPair; import org.bouncycastle.crypto.generators.RSAKeyPairGenerator; import org.bouncycastle.crypto.params.AsymmetricKeyParameter; import org.bouncycastle.crypto.params.RSAKeyGenerationParameters; import org.bouncycastle.openpgp.PGPKeyPair; import org.bouncycastle.openpgp.PGPLiteralData; import org.bouncycastle.openpgp.PGPLiteralDataGenerator; import org.bouncycastle.openpgp.PGPObjectFactory; import org.bouncycastle.openpgp.PGPOnePassSignature; import org.bouncycastle.openpgp.PGPOnePassSignatureList; import org.bouncycastle.openpgp.PGPPrivateKey; import org.bouncycastle.openpgp.PGPPublicKey; import org.bouncycastle.openpgp.PGPPublicKeyRing; import org.bouncycastle.openpgp.PGPSecretKeyRing; import org.bouncycastle.openpgp.PGPSignature; import org.bouncycastle.openpgp.PGPSignatureGenerator; import org.bouncycastle.openpgp.PGPSignatureList; import org.bouncycastle.openpgp.PGPSignatureSubpacketGenerator; import org.bouncycastle.openpgp.PGPUserAttributeSubpacketVector; import org.bouncycastle.openpgp.PGPUtil; import org.bouncycastle.openpgp.operator.bc.BcKeyFingerprintCalculator; import org.bouncycastle.openpgp.operator.bc.BcPBESecretKeyDecryptorBuilder; import org.bouncycastle.openpgp.operator.bc.BcPGPContentSignerBuilder; import org.bouncycastle.openpgp.operator.bc.BcPGPContentVerifierBuilderProvider; import org.bouncycastle.openpgp.operator.bc.BcPGPDigestCalculatorProvider; import org.bouncycastle.openpgp.operator.bc.BcPGPKeyConverter; import org.bouncycastle.openpgp.operator.bc.BcPGPKeyPair; import org.bouncycastle.util.encoders.Base64; import org.bouncycastle.util.test.SimpleTest; import org.bouncycastle.util.test.UncloseableOutputStream; public class BcPGPDSATest extends SimpleTest { byte[] testPubKey = Base64.decode( "mQGiBD9HBzURBACzkxRCVGJg5+Ld9DU4Xpnd4LCKgMq7YOY7Gi0EgK92gbaa6+zQ" + "oQFqz1tt3QUmpz3YVkm/zLESBBtC1ACIXGggUdFMUr5I87+1Cb6vzefAtGt8N5VV" + "1F/MXv1gJz4Bu6HyxL/ncfe71jsNhav0i4yAjf2etWFj53zK6R+Ojg5H6wCgpL9/" + "tXVfGP8SqFvyrN/437MlFSUEAIN3V6j/MUllyrZglrtr2+RWIwRrG/ACmrF6hTug" + "Ol4cQxaDYNcntXbhlTlJs9MxjTH3xxzylyirCyq7HzGJxZzSt6FTeh1DFYzhJ7Qu" + "YR1xrSdA6Y0mUv0ixD5A4nPHjupQ5QCqHGeRfFD/oHzD4zqBnJp/BJ3LvQ66bERJ" + "mKl5A/4uj3HoVxpb0vvyENfRqKMmGBISycY4MoH5uWfb23FffsT9r9KL6nJ4syLz" + "aRR0gvcbcjkc9Z3epI7gr3jTrb4d8WPxsDbT/W1tv9bG/EHawomLcihtuUU68Uej" + "6/wZot1XJqu2nQlku57+M/V2X1y26VKsipolPfja4uyBOOyvbLQzRXJpYyBFY2hp" + "ZG5hIChEU0EgVGVzdCBLZXkpIDxlcmljQGJvdW5jeWNhc3RsZS5vcmc+iFkEExEC" + "ABkFAj9HBzUECwcDAgMVAgMDFgIBAh4BAheAAAoJEM0j9enEyjRDAlwAn2rrom0s" + "MhufWK5vIRwg7gj5qsLEAJ4vnT5dPBVblofsG+pDoCVeJXGGng=="); byte[] testPrivKey = Base64.decode( "lQHhBD9HBzURBACzkxRCVGJg5+Ld9DU4Xpnd4LCKgMq7YOY7Gi0EgK92gbaa6+zQ" + "oQFqz1tt3QUmpz3YVkm/zLESBBtC1ACIXGggUdFMUr5I87+1Cb6vzefAtGt8N5VV" + "1F/MXv1gJz4Bu6HyxL/ncfe71jsNhav0i4yAjf2etWFj53zK6R+Ojg5H6wCgpL9/" + "tXVfGP8SqFvyrN/437MlFSUEAIN3V6j/MUllyrZglrtr2+RWIwRrG/ACmrF6hTug" + "Ol4cQxaDYNcntXbhlTlJs9MxjTH3xxzylyirCyq7HzGJxZzSt6FTeh1DFYzhJ7Qu" + "YR1xrSdA6Y0mUv0ixD5A4nPHjupQ5QCqHGeRfFD/oHzD4zqBnJp/BJ3LvQ66bERJ" + "mKl5A/4uj3HoVxpb0vvyENfRqKMmGBISycY4MoH5uWfb23FffsT9r9KL6nJ4syLz" + "aRR0gvcbcjkc9Z3epI7gr3jTrb4d8WPxsDbT/W1tv9bG/EHawomLcihtuUU68Uej" + "6/wZot1XJqu2nQlku57+M/V2X1y26VKsipolPfja4uyBOOyvbP4DAwIDIBTxWjkC" + "GGAWQO2jy9CTvLHJEoTO7moHrp1FxOVpQ8iJHyRqZzLllO26OzgohbiPYz8u9qCu" + "lZ9Xn7QzRXJpYyBFY2hpZG5hIChEU0EgVGVzdCBLZXkpIDxlcmljQGJvdW5jeWNh" + "c3RsZS5vcmc+iFkEExECABkFAj9HBzUECwcDAgMVAgMDFgIBAh4BAheAAAoJEM0j" + "9enEyjRDAlwAnjTjjt57NKIgyym7OTCwzIU3xgFpAJ0VO5m5PfQKmGJRhaewLSZD" + "4nXkHg=="); byte[] testPrivKey2 = Base64.decode( "lQHhBEAnoewRBADRvKgDhbV6pMzqYfUgBsLxSHzmycpuxGbjMrpyKHDOEemj" + "iQb6TyyBKUoR28/pfshFP9R5urtKIT7wjVrDuOkxYkgRhNm+xmPXW2Lw3D++" + "MQrC5VWe8ywBltz6T9msmChsaKo2hDhIiRI/mg9Q6rH9pJKtVGi4R7CgGxM2" + "STQ5fwCgub38qGS1W2O4hUsa+3gva5gaNZUEAItegda4/H4t88XdWxW3D8pv" + "RnFz26/ADdImVaQlBoumD15VmcgYoT1Djizey7X8vfV+pntudESzLbn3GHlI" + "6C09seH4e8eYP63t7KU/qbUCDomlSswd1OgQ/RxfN86q765K2t3K1i3wDSxe" + "EgSRyGKee0VNvOBFOFhuWt+patXaBADE1riNkUxg2P4lBNWwu8tEZRmsl/Ys" + "DBIzXBshoMzZCvS5PnNXMW4G3SAaC9OC9jvKSx9IEWhKjfjs3QcWzXR28mcm" + "5na0bTxeOMlaPPhBdkTCmFl0IITWlH/pFlR2ah9WYoWYhZEL2tqB82wByzxH" + "SkSeD9V5oeSCdCcqiqkEmv4DAwLeNsQ2XGJVRmA4lld+CR5vRxpT/+/2xklp" + "lxVf/nx0+thrHDpro3u/nINIIObk0gh59+zaEEe3APlHqbQVYWFhIGJiYiA8" + "Y2NjQGRkZC5lZWU+iFoEExECABoFAkAnoewFCwcDAgEDFQIDAxYCAQIeAQIX" + "gAAKCRA5nBpCS63az85BAKCbPfU8ATrFvkXhzGNGlc1BJo6DWQCgnK125xVK" + "lWLpt6ZJJ7TXcx3nkm6wAgAAnQFXBEAnoe0QBACsQxPvaeBcv2TkbgU/5Wc/" + "tO222dPE1mxFbXjGTKfb+6ge96iyD8kTRLrKCkEEeVBa8AZqMSoXUVN6tV8j" + "/zD8Bc76o5iJ6wgpg3Mmy2GxInVfsfZN6/G3Y2ukmouz+CDNvQdUw8cTguIb" + "QoV3XhQ03MLbfVmNcHsku9F4CuKNWwADBQP0DSSe8v5PXF9CSCXOIxBDcQ5x" + "RKjyYOveqoH/4lbOV0YNUbIDZq4RaUdotpADuPREFmWf0zTB6KV/WIiag8XU" + "WU9zdDvLKR483Bo6Do5pDBcN+NqfQ+ntGY9WJ7BSFnhQ3+07i1K+NsfFTRfv" + "hf9X3MP75rCf7MxAIWHTabEmUf4DAwLeNsQ2XGJVRmA8DssBUCghogG9n8T3" + "qfBeKsplGyCcF+JjPeQXkKQaoYGJ0aJz36qFP9d8DuWtT9soQcqIxVf6mTa8" + "kN1594hGBBgRAgAGBQJAJ6HtAAoJEDmcGkJLrdrPpMkAnRyjQSKugz0YJqOB" + "yGasMLQLxd2OAKCEIlhtCarlufVQNGZsuWxHVbU8crACAAA="); byte[] sig1 = Base64.decode( "owGbwMvMwCR4VvnryyOnTJwZ10gncZSkFpfolVSU2Ltz78hIzcnJVyjPL8pJUeTq" + "sGdmZQCJwpQLMq3ayTA/0Fj3xf4jbwPfK/H3zj55Z9L1n2k/GOapKJrvMZ4tLiCW" + "GtP/XeDqX4fORDUA"); byte[] sig1crc = Base64.decode("OZa/"); byte[] testPubWithUserAttr = Base64.decode( "mQGiBD2Rqv0RBADqKCkhVEtB/lEEr/9CubuHEy2oN/yU5j+2GXSdcNdVnRI/rwFy" + "fHEQIk3uU7zHSUKFrC59yDm0sODYyjEdE3BVb0xvEJ5LE/OdndcIMXT1DungZ1vB" + "zIK/3lr33W/PHixYxv9jduH3WrTehBpiKkgMZp8XloSFj2Cnw9LDyfqB7QCg/8K1" + "o2k75NkOd9ZjnA9ye7Ri3bEEAKyr61Mo7viPWBK1joWAEsxG0OBWM+iSlG7kwh31" + "8efgC/7Os6x4Y0jzs8mpcbBjeZtZjS9lRbfp7RinhF269xL0TZ3JxIdtaAV/6yDQ" + "9NXfZY9dskN++HIR/5GCEEgq/qTJZt6ti5k7aV19ZFfO6wiK3NUy08wOrVsdOkVE" + "w9IcBADaplhpcel3201uU3OCboogJtw81R5MJMZ4Y9cKL/ca2jGISn0nA7KrAw9v" + "ShheSixGO4BV9JECkLEbtg7i+W/j/De6S+x2GLNcphuTP3UmgtKbhs0ItRqzW561" + "s6gLkqi6aWmgaFLd8E1pMJcd9DSY95P13EYB9VJIUxFNUopzo7QcUmFsZiBIYXVz" + "ZXIgPGhhdXNlckBhY20ub3JnPokAWAQQEQIAGAUCPZGq/QgLAwkIBwIBCgIZAQUb" + "AwAAAAAKCRAqIBiOh4JvOKg4AJ9j14yygOqqzqiLKeaasIzqT8LCIgCggx14WuLO" + "wOUTUswTaVKMFnU7tseJAJwEEAECAAYFAj2Rqx8ACgkQ9aWTKMpUDFV+9QP/RiWT" + "5FAF5Rgb7beaApsgXsME+Pw7HEYFtqGa6VcXEpbcUXO6rjaXsgMgY90klWlWCF1T" + "HOyKITvj2FdhE+0j8NQn4vaGpiTwORW/zMf/BZ0abdSWQybp10Yjs8gXw30UheO+" + "F1E524MC+s2AeUi2hwHMiS+AVYd4WhxWHmWuBpTRypP/AAALTgEQAAEBAAAAAQAA" + "AAABAAAA/9j/4AAQSkZJRgABAQAAAQABAAD/2wBDAAoHBwgHBgoICAgLCgoLDhgQ" + "Dg0NDh0VFhEYIx8lJCIfIiEmKzcvJik0KSEiMEExNDk7Pj4+JS5ESUM8SDc9Pjv/" + "2wBDAQoLCw4NDhwQEBw7KCIoOzs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7" + "Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozv/wAARCABqAF0DASIAAhEBAxEB/8QAHwAAAQUB" + "AQEBAQEAAAAAAAAAAAECAwQFBgcICQoL/8QAtRAAAgEDAwIEAwUFBAQAAAF9AQID" + "AAQRBRIhMUEGE1FhByJxFDKBkaEII0KxwRVS0fAkM2JyggkKFhcYGRolJicoKSo0" + "NTY3ODk6Q0RFRkdISUpTVFVWV1hZWmNkZWZnaGlqc3R1dnd4eXqDhIWGh4iJipKT" + "lJWWl5iZmqKjpKWmp6ipqrKztLW2t7i5usLDxMXGx8jJytLT1NXW19jZ2uHi4+Tl" + "5ufo6erx8vP09fb3+Pn6/8QAHwEAAwEBAQEBAQEBAQAAAAAAAAECAwQFBgcICQoL" + "/8QAtREAAgECBAQDBAcFBAQAAQJ3AAECAxEEBSExBhJBUQdhcRMiMoEIFEKRobHB" + "CSMzUvAVYnLRChYkNOEl8RcYGRomJygpKjU2Nzg5OkNERUZHSElKU1RVVldYWVpj" + "ZGVmZ2hpanN0dXZ3eHl6goOEhYaHiImKkpOUlZaXmJmaoqOkpaanqKmqsrO0tba3" + "uLm6wsPExcbHyMnK0tPU1dbX2Nna4uPk5ebn6Onq8vP09fb3+Pn6/9oADAMBAAIR" + "AxEAPwD2aiiq9xcxWsRllcKqjOT06E/0oAsVm6jrmm6VGXvLuOPGflz8x+grzXxV" + "8U51u5LXRgBGowZHXknnkc9OQcV51caneXdw9xPOXlckl2AJHY4J6cD1oA9J1z4p" + "TRkrYQhRyQ0hIY5/2QRx7k9ulczN8SvEEshdZkX0UorDrznI759a5Mksckkknqec" + "mkoA7WD4oavEoEttbTepYEZ+mCMVv6H8SLTULhbe/gFozAYkD5Unp3Ax/kV5XRQB" + "9EAhgCDkHkEcgilryTwd4zn0m4WzvpTJZSMBuY5MfbueletKyugZWDKwyCOc/j3o" + "AduyWLDeWB5Ynj8jSUUUAdFXn/xU15dO0RbGGYC5uWwUB6L1Jx+n413F1cJa2stz" + "J92JC5+gGa+bdfvp9S1q4urmRneQg5Yk4HGAPYZoAzySxySSSep5yaSvQvAPhOHU" + "rB7u5iLGUlIwQRx7HPr/AJ9LGsfC+dJGngc+X12gc8nvx1/rQB5rRXS3Xg28t9ye" + "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" + "qkEsPXn6/pXo/ilVzbttG7DDOOeornqAONbRpI4v3pKOQcAqQD+Y/P6j052NK0p5" + "HWHy3IBPyqrfN6gZz+P4/hpXoGzOOiP/ACNdH4XRftsp2jIBxx70AX9E0pdMtvMm" + "VRNt5xyEGOgPf3NeDeLdVOs+J768zlGkKx+yjgfy/WvoPXeNEvMcfujXzJQAUUUU" + "Af/ZiQBGBBARAgAGBQI9katEAAoJECogGI6Hgm84xz8AoNGz1fJrVPxqkBrUDmWA" + "GsP6qVGYAJ0ZOftw/GfQHzdGR8pOK85DLUPEErQkUmFsZiBIYXVzZXIgPGhhdXNl" + "ckBwcml2YXNwaGVyZS5jb20+iQBGBBARAgAGBQI9katmAAoJECogGI6Hgm84m0oA" + "oJS3CTrgpqRZfhgPtHGtUVjRCJbbAJ9stJgPcbqA2xXEg9yl2TQToWdWxbQkUmFs" + "ZiBIYXVzZXIgPGhhdXNlckBwcml2YXNwaGVyZS5vcmc+iQBGBBARAgAGBQI9kauJ" + "AAoJECogGI6Hgm84GfAAnRswktLMzDfIjv6ni76Qp5B850byAJ90I0LEHOLhda7r" + "kqTwZ8rguNssUrQkUmFsZiBIYXVzZXIgPGhhdXNlckBwcml2YXNwaGVyZS5uZXQ+" + "iQBGBBARAgAGBQI9kaubAAoJECogGI6Hgm84zi0An16C4s/B9Z0/AtfoN4ealMh3" + "i3/7AJ9Jg4GOUqGCGRRKUA9Gs5pk8yM8GbQmUmFsZiBDLiBIYXVzZXIgPHJhbGZo" + "YXVzZXJAYmx1ZXdpbi5jaD6JAEYEEBECAAYFAj2Rq8oACgkQKiAYjoeCbzhPOACg" + "iiTohKuIa66FNiI24mQ+XR9nTisAoLmh3lJf16/06qLPsRd9shTkLfmHtB9SYWxm" + "IEhhdXNlciA8cmFsZmhhdXNlckBnbXguY2g+iQBGBBARAgAGBQI9kavvAAoJECog" + "GI6Hgm84ZE8An0RlgL8mPBa/P08S5e/lD35MlDdgAJ99pjCeY46S9+nVyx7ACyKO" + "SZ4OcLQmUmFsZiBIYXVzZXIgPGhhdXNlci5yYWxmQG15c3VucmlzZS5jaD6JAEYE" + "EBECAAYFAj2RrEEACgkQKiAYjoeCbzjz0wCg+q801XrXk+Rf+koSI50MW5OaaKYA" + "oKOVA8SLxE29qSR/bJeuW0ryzRLqtCVSYWxmIEhhdXNlciA8aGF1c2VyLnJhbGZA" + "ZnJlZXN1cmYuY2g+iQBGBBARAgAGBQI9kaxXAAoJECogGI6Hgm848zoAnRBtWH6e" + "fTb3is63s8J2zTfpsyS0AKDxTjl+ZZV0COHLrSCaNLZVcpImFrkEDQQ9kar+EBAA" + "+RigfloGYXpDkJXcBWyHhuxh7M1FHw7Y4KN5xsncegus5D/jRpS2MEpT13wCFkiA" + "tRXlKZmpnwd00//jocWWIE6YZbjYDe4QXau2FxxR2FDKIldDKb6V6FYrOHhcC9v4" + "TE3V46pGzPvOF+gqnRRh44SpT9GDhKh5tu+Pp0NGCMbMHXdXJDhK4sTw6I4TZ5dO" + "khNh9tvrJQ4X/faY98h8ebByHTh1+/bBc8SDESYrQ2DD4+jWCv2hKCYLrqmus2UP" + "ogBTAaB81qujEh76DyrOH3SET8rzF/OkQOnX0ne2Qi0CNsEmy2henXyYCQqNfi3t" + "5F159dSST5sYjvwqp0t8MvZCV7cIfwgXcqK61qlC8wXo+VMROU+28W65Szgg2gGn" + "VqMU6Y9AVfPQB8bLQ6mUrfdMZIZJ+AyDvWXpF9Sh01D49Vlf3HZSTz09jdvOmeFX" + "klnN/biudE/F/Ha8g8VHMGHOfMlm/xX5u/2RXscBqtNbno2gpXI61Brwv0YAWCvl" + "9Ij9WE5J280gtJ3kkQc2azNsOA1FHQ98iLMcfFstjvbzySPAQ/ClWxiNjrtVjLhd" + "ONM0/XwXV0OjHRhs3jMhLLUq/zzhsSlAGBGNfISnCnLWhsQDGcgHKXrKlQzZlp+r" + "0ApQmwJG0wg9ZqRdQZ+cfL2JSyIZJrqrol7DVes91hcAAgIQAKD9MGkS8SUD2irI" + "AiwVHU0WXLBnk2CvvueSmT9YtC34UKkIkDPZ7VoeuXDfqTOlbiE6T16zPvArZfbl" + "JGdrU7HhsTdu+ADxRt1dPur0G0ICJ3pBD3ydGWpdLI/94x1BvTY4rsR5mS4YWmpf" + "e2kWc7ZqezhP7Xt9q7m4EK456ddeUZWtkwGU+PKyRAZ+CK82Uhouw+4aW0NjiqmX" + "hfH9/BUhI1P/8R9VkTfAFGPmZzqoHr4AuO5tLRLD2RFSmQCP8nZTiP9nP+wBBvn7" + "vuqKRQsj9PwwPD4V5SM+kpW+rUIWr9TZYl3UqSnlXlpEZFd2Bfl6NloeH0cfU69E" + "gtjcWGvGxYKPS0cg5yhVb4okka6RqIPQiYl6eJgv4tRTKoPRX29o0aUVdqVvDr5u" + "tnFzcINq7jTo8GiO8Ia3cIFWfo0LyQBd1cf1U+eEOz+DleEFqyljaz9VCbDPE4GP" + "o+ALESBlOwn5daUSaah9iU8aVPaSjn45hoQqxOKPwJxnCKKQ01iy0Gir+CDU8JJB" + "7bmbvQN4bke30EGAeED3oi+3VaBHrhjYLv7SHIxP5jtCJKWMJuLRV709HsWJi3kn" + "fGHwH+yCDF8+PDeROAzpXBaD2EFhKgeUTjP5Rgn6ltRf8TQnfbW4qlwyiXMhPOfC" + "x6qNmwaFPKQJpIkVq5VGfRXAERfkiQBMBBgRAgAMBQI9kar+BRsMAAAAAAoJECog" + "GI6Hgm84CDMAoNrNeP4c8XqFJnsLLPcjk5YGLaVIAKCrL5KFuLQVIp7d0Fkscx3/" + "7DGrzw=="); byte[] aesSecretKey = Base64.decode( "lQHpBEBSdIYRBADpd7MeIxRk4RsvyMnJNIYe4FiVv6i7I7+LPRvnIjDct0bN" + "1gCV48QFej7g/PsvXRjYSowV3VIvchWX8OERd/5i10cLbcs7X52EP1vwYaLj" + "uRfNUBg8Q51RQsKR+/rBmnVsi68rjU4yTH6wpo6FOO4pz4wFV+tWwGOwOitA" + "K31L4wCgqh59eFFBrOlRFAbDvaL7emoCIR8EAOLxDKiLQJYQrKZfXdZnifeo" + "dhEP0uuV4O5TG6nrqkhWffzC9cSoFD0BhMl979d8IB2Uft4FNvQc2u8hbJL5" + "7OCGDCUAidlB9jSdu0/J+kfRaTGhYDjBgw7AA42576BBSMNouJg/aOOQENEN" + "Nn4n7NxR3viBzIsL/OIeU8HSkBgaA/41PsvcgZ3kwpdltJ/FVRWhmMmv/q/X" + "qp1YOnF8xPU9bv2ofELrxJfRsbS4GW1etzD+nXs/woW4Vfixs01x+cutR4iF" + "3hw+eU+yLToMPmmo8D2LUvX1SRODJpx5yBBeRIYv6nz9H3sQRDx3kaLASxDV" + "jTxKmrLYnZz5w5qyVpvRyv4JAwKyWlhdblPudWBFXNkW5ydKn0AV2f51wEtj" + "Zy0aLIeutVMSJf1ytLqjFqrnFe6pdJrHO3G00TE8OuFhftWosLGLbEGytDtF" + "cmljIEguIEVjaGlkbmEgKHRlc3Qga2V5IC0gQUVTMjU2KSA8ZXJpY0Bib3Vu" + "Y3ljYXN0bGUub3JnPohZBBMRAgAZBQJAUnSGBAsHAwIDFQIDAxYCAQIeAQIX" + "gAAKCRBYt1NnUiCgeFKaAKCiqtOO+NQES1gJW6XuOGmSkXt8bQCfcuW7SXZH" + "zxK1FfdcG2HEDs3YEVawAgAA"); byte[] aesPublicKey = Base64.decode( "mQGiBEBSdIYRBADpd7MeIxRk4RsvyMnJNIYe4FiVv6i7I7+LPRvnIjDct0bN" + "1gCV48QFej7g/PsvXRjYSowV3VIvchWX8OERd/5i10cLbcs7X52EP1vwYaLj" + "uRfNUBg8Q51RQsKR+/rBmnVsi68rjU4yTH6wpo6FOO4pz4wFV+tWwGOwOitA" + "K31L4wCgqh59eFFBrOlRFAbDvaL7emoCIR8EAOLxDKiLQJYQrKZfXdZnifeo" + "dhEP0uuV4O5TG6nrqkhWffzC9cSoFD0BhMl979d8IB2Uft4FNvQc2u8hbJL5" + "7OCGDCUAidlB9jSdu0/J+kfRaTGhYDjBgw7AA42576BBSMNouJg/aOOQENEN" + "Nn4n7NxR3viBzIsL/OIeU8HSkBgaA/41PsvcgZ3kwpdltJ/FVRWhmMmv/q/X" + "qp1YOnF8xPU9bv2ofELrxJfRsbS4GW1etzD+nXs/woW4Vfixs01x+cutR4iF" + "3hw+eU+yLToMPmmo8D2LUvX1SRODJpx5yBBeRIYv6nz9H3sQRDx3kaLASxDV" + "jTxKmrLYnZz5w5qyVpvRyrQ7RXJpYyBILiBFY2hpZG5hICh0ZXN0IGtleSAt" + "IEFFUzI1NikgPGVyaWNAYm91bmN5Y2FzdGxlLm9yZz6IWQQTEQIAGQUCQFJ0" + "hgQLBwMCAxUCAwMWAgECHgECF4AACgkQWLdTZ1IgoHhSmgCfU83BLBF2nCua" + "zk2dXB9zO1l6XS8AnA07U4cq5W0GrKM6/kP9HWtPhgOFsAIAAA=="); byte[] twofishSecretKey = Base64.decode( "lQHpBEBSdtIRBACf7WfrqTl8F051+EbaljPf/8/ajFpAfMq/7p3Hri8OCsuc" + "fJJIufEEOV1/Lt/wkN67MmSyrU0fUCsRbEckRiB4EJ0zGHVFfAnku2lzdgc8" + "AVounqcHOmqA/gliFDEnhYOx3bOIAOav+yiOqfKVBhWRCpFdOTE+w/XoDM+p" + "p8bH5wCgmP2FuWpzfSut7GVKp51xNEBRNuED/3t2Q+Mq834FVynmLKEmeXB/" + "qtIz5reHEQR8eMogsOoJS3bXs6v3Oblj4in1gLyTVfcID5tku6kLP20xMRM2" + "zx2oRbz7TyOCrs15IpRXyqqJxUWD8ipgJPkPXE7hK8dh4YSTUi4i5a1ug8xG" + "314twlPzrchpWZiutDvZ+ks1rzOtBACHrEFG2frUu+qVkL43tySE0cV2bnuK" + "LVhXbpzF3Qdkfxou2nuzsCbl6m87OWocJX8uYcQGlHLKv8Q2cfxZyieLFg6v" + "06LSFdE9drGBWz7mbrT4OJjxPyvnkffPfLOOqae3PMYIIuscvswuhm4X5aoj" + "KJs01YT3L6f0iIj03hCeV/4KAwLcGrxT3X0qR2CZyZYSVBdjXeNYKXuGBtOf" + "ood26WOtwLw4+l9sHVoiXNv0LomkO58ndJRPGCeZWZEDMVrfkS7rcOlktDxF" + "cmljIEguIEVjaGlkbmEgKHRlc3Qga2V5IC0gdHdvZmlzaCkgPGVyaWNAYm91" + "bmN5Y2FzdGxlLm9yZz6IWQQTEQIAGQUCQFJ20gQLBwMCAxUCAwMWAgECHgEC" + "F4AACgkQaCCMaHh9zR2+RQCghcQwlt4B4YmNxp2b3v6rP3E8M0kAn2Gspi4u" + "A/ynoqnC1O8HNlbjPdlVsAIAAA=="); byte[] twofishPublicKey = Base64.decode( "mQGiBEBSdtIRBACf7WfrqTl8F051+EbaljPf/8/ajFpAfMq/7p3Hri8OCsuc" + "fJJIufEEOV1/Lt/wkN67MmSyrU0fUCsRbEckRiB4EJ0zGHVFfAnku2lzdgc8" + "AVounqcHOmqA/gliFDEnhYOx3bOIAOav+yiOqfKVBhWRCpFdOTE+w/XoDM+p" + "p8bH5wCgmP2FuWpzfSut7GVKp51xNEBRNuED/3t2Q+Mq834FVynmLKEmeXB/" + "qtIz5reHEQR8eMogsOoJS3bXs6v3Oblj4in1gLyTVfcID5tku6kLP20xMRM2" + "zx2oRbz7TyOCrs15IpRXyqqJxUWD8ipgJPkPXE7hK8dh4YSTUi4i5a1ug8xG" + "314twlPzrchpWZiutDvZ+ks1rzOtBACHrEFG2frUu+qVkL43tySE0cV2bnuK" + "LVhXbpzF3Qdkfxou2nuzsCbl6m87OWocJX8uYcQGlHLKv8Q2cfxZyieLFg6v" + "06LSFdE9drGBWz7mbrT4OJjxPyvnkffPfLOOqae3PMYIIuscvswuhm4X5aoj" + "KJs01YT3L6f0iIj03hCeV7Q8RXJpYyBILiBFY2hpZG5hICh0ZXN0IGtleSAt" + "IHR3b2Zpc2gpIDxlcmljQGJvdW5jeWNhc3RsZS5vcmc+iFkEExECABkFAkBS" + "dtIECwcDAgMVAgMDFgIBAh4BAheAAAoJEGggjGh4fc0dvkUAn2QGdNk8Wrrd" + "+DvKECrO5+yoPRx3AJ91DhCMme6uMrQorKSDYxHlgc7iT7ACAAA="); char[] pass = { 'h', 'e', 'l', 'l', 'o', ' ', 'w', 'o', 'r', 'l', 'd' }; /** * Generated signature test * * @param sKey * @param pgpPrivKey */ public void generateTest( PGPSecretKeyRing sKey, PGPPublicKey pgpPubKey, PGPPrivateKey pgpPrivKey) throws Exception { String data = "hello world!"; ByteArrayOutputStream bOut = new ByteArrayOutputStream(); ByteArrayInputStream testIn = new ByteArrayInputStream(data.getBytes()); PGPSignatureGenerator sGen = new PGPSignatureGenerator(new BcPGPContentSignerBuilder(PublicKeyAlgorithmTags.DSA, HashAlgorithmTags.SHA1)); sGen.init(PGPSignature.BINARY_DOCUMENT, pgpPrivKey); PGPSignatureSubpacketGenerator spGen = new PGPSignatureSubpacketGenerator(); Iterator it = sKey.getSecretKey().getPublicKey().getUserIDs(); String primaryUserID = (String)it.next(); spGen.setSignerUserID(true, primaryUserID); sGen.setHashedSubpackets(spGen.generate()); sGen.generateOnePassVersion(false).encode(bOut); PGPLiteralDataGenerator lGen = new PGPLiteralDataGenerator(); Date testDate = new Date((System.currentTimeMillis() / 1000) * 1000); OutputStream lOut = lGen.open( new UncloseableOutputStream(bOut), PGPLiteralData.BINARY, "_CONSOLE", data.getBytes().length, testDate); int ch; while ((ch = testIn.read()) >= 0) { lOut.write(ch); sGen.update((byte)ch); } lGen.close(); sGen.generate().encode(bOut); PGPObjectFactory pgpFact = new PGPObjectFactory(bOut.toByteArray()); PGPOnePassSignatureList p1 = (PGPOnePassSignatureList)pgpFact.nextObject(); PGPOnePassSignature ops = p1.get(0); PGPLiteralData p2 = (PGPLiteralData)pgpFact.nextObject(); if (!p2.getModificationTime().equals(testDate)) { fail("Modification time not preserved"); } InputStream dIn = p2.getInputStream(); ops.init(new BcPGPContentVerifierBuilderProvider(), pgpPubKey); while ((ch = dIn.read()) >= 0) { ops.update((byte)ch); } PGPSignatureList p3 = (PGPSignatureList)pgpFact.nextObject(); if (!ops.verify(p3.get(0))) { fail("Failed generated signature check"); } } public void performTest() throws Exception { String file = null; PGPPublicKey pubKey = null; // // Read the public key // PGPPublicKeyRing pgpPub = new PGPPublicKeyRing(testPubKey, new BcKeyFingerprintCalculator()); pubKey = pgpPub.getPublicKey(); // // Read the private key // PGPSecretKeyRing sKey = new PGPSecretKeyRing(testPrivKey, new BcKeyFingerprintCalculator()); PGPPrivateKey pgpPrivKey = sKey.getSecretKey().extractPrivateKey(new BcPBESecretKeyDecryptorBuilder(new BcPGPDigestCalculatorProvider()).build(pass)); // // test signature message // PGPOnePassSignatureList p1; PGPOnePassSignature ops; PGPLiteralData p2; InputStream dIn; int ch; PGPObjectFactory pgpFact = new PGPObjectFactory(sig1); // compressed data not supported // PGPOnePassSignatureList p1 = (PGPOnePassSignatureList)pgpFact.nextObject(); // // PGPOnePassSignature ops = p1.get(0); // // PGPLiteralData p2 = (PGPLiteralData)pgpFact.nextObject(); // // InputStream dIn = p2.getInputStream(); // int ch; // // ops.init(new BcPGPContentVerifierBuilderProvider(), pubKey); // // while ((ch = dIn.read()) >= 0) // { // ops.update((byte)ch); // } // // PGPSignatureList p3 = (PGPSignatureList)pgpFact.nextObject(); // // if (!ops.verify(p3.get(0))) // { // fail("Failed signature check"); // } // // signature generation // generateTest(sKey, pubKey, pgpPrivKey); // // signature generation - canonical text // String data = "hello world!"; ByteArrayOutputStream bOut = new ByteArrayOutputStream(); ByteArrayInputStream testIn = new ByteArrayInputStream(data.getBytes()); PGPSignatureGenerator sGen = new PGPSignatureGenerator(new BcPGPContentSignerBuilder(PGPPublicKey.DSA, PGPUtil.SHA1)); sGen.init(PGPSignature.CANONICAL_TEXT_DOCUMENT, pgpPrivKey); sGen.generateOnePassVersion(false).encode(bOut); PGPLiteralDataGenerator lGen = new PGPLiteralDataGenerator(); Date testDate = new Date((System.currentTimeMillis() / 1000) * 1000); OutputStream lOut = lGen.open( new UncloseableOutputStream(bOut), PGPLiteralData.TEXT, "_CONSOLE", data.getBytes().length, testDate); while ((ch = testIn.read()) >= 0) { lOut.write(ch); sGen.update((byte)ch); } lGen.close(); sGen.generate().encode(bOut); // // verify generated signature - canconical text // pgpFact = new PGPObjectFactory(bOut.toByteArray()); p1 = (PGPOnePassSignatureList)pgpFact.nextObject(); ops = p1.get(0); p2 = (PGPLiteralData)pgpFact.nextObject(); if (!p2.getModificationTime().equals(testDate)) { fail("Modification time not preserved"); } dIn = p2.getInputStream(); ops.init(new BcPGPContentVerifierBuilderProvider(), pubKey); while ((ch = dIn.read()) >= 0) { ops.update((byte)ch); } PGPSignatureList p3 = (PGPSignatureList)pgpFact.nextObject(); if (!ops.verify(p3.get(0))) { fail("Failed generated signature check"); } // // Read the public key with user attributes // pgpPub = new PGPPublicKeyRing(testPubWithUserAttr, new BcKeyFingerprintCalculator()); pubKey = pgpPub.getPublicKey(); Iterator it = pubKey.getUserAttributes(); int count = 0; while (it.hasNext()) { PGPUserAttributeSubpacketVector attributes = (PGPUserAttributeSubpacketVector)it.next(); Iterator sigs = pubKey.getSignaturesForUserAttribute(attributes); int sigCount = 0; while (sigs.hasNext()) { sigs.next(); sigCount++; } if (sigCount != 1) { fail("Failed user attributes signature check"); } count++; } if (count != 1) { fail("Failed user attributes check"); } byte[] pgpPubBytes = pgpPub.getEncoded(); pgpPub = new PGPPublicKeyRing(pgpPubBytes, new BcKeyFingerprintCalculator()); pubKey = pgpPub.getPublicKey(); it = pubKey.getUserAttributes(); count = 0; while (it.hasNext()) { it.next(); count++; } if (count != 1) { fail("Failed user attributes reread"); } // // reading test extra data - key with edge condition for DSA key password. // char [] passPhrase = { '0', '1', '2', '3', '4', '5', '6', '7', '8', '9' }; sKey = new PGPSecretKeyRing(testPrivKey2, new BcKeyFingerprintCalculator()); pgpPrivKey = sKey.getSecretKey().extractPrivateKey(new BcPBESecretKeyDecryptorBuilder(new BcPGPDigestCalculatorProvider()).build(passPhrase)); AsymmetricKeyParameter bytes = new BcPGPKeyConverter().getPrivateKey(pgpPrivKey); // // reading test - aes256 encrypted passphrase. // sKey = new PGPSecretKeyRing(aesSecretKey, new BcKeyFingerprintCalculator()); pgpPrivKey = sKey.getSecretKey().extractPrivateKey(new BcPBESecretKeyDecryptorBuilder(new BcPGPDigestCalculatorProvider()).build(pass)); bytes = new BcPGPKeyConverter().getPrivateKey(pgpPrivKey); // // reading test - twofish encrypted passphrase. // sKey = new PGPSecretKeyRing(twofishSecretKey, new BcKeyFingerprintCalculator()); pgpPrivKey = sKey.getSecretKey().extractPrivateKey(new BcPBESecretKeyDecryptorBuilder(new BcPGPDigestCalculatorProvider()).build(pass)); bytes = new BcPGPKeyConverter().getPrivateKey(pgpPrivKey); // // use of PGPKeyPair // RSAKeyPairGenerator kpg = new RSAKeyPairGenerator(); kpg.init(new RSAKeyGenerationParameters(BigInteger.valueOf(0x11), new SecureRandom(), 512, 25)); AsymmetricCipherKeyPair kp = kpg.generateKeyPair(); PGPKeyPair pgpKp = new BcPGPKeyPair(PGPPublicKey.RSA_GENERAL , kp, new Date()); PGPPublicKey k1 = pgpKp.getPublicKey(); PGPPrivateKey k2 = pgpKp.getPrivateKey(); } public String getName() { return "BcPGPDSATest"; } public static void main( String[] args) { runTest(new BcPGPDSATest()); } } bouncycastle-1.49.orig/j2me/org/bouncycastle/openpgp/test/BcPGPPBETest.java0000644000175000017500000003057611732236747026153 0ustar ebourgebourgpackage org.bouncycastle.openpgp.test; import java.io.ByteArrayOutputStream; import java.io.InputStream; import java.io.OutputStream; import java.security.SecureRandom; import java.util.Date; import org.bouncycastle.openpgp.PGPEncryptedData; import org.bouncycastle.openpgp.PGPEncryptedDataGenerator; import org.bouncycastle.openpgp.PGPEncryptedDataList; import org.bouncycastle.openpgp.PGPLiteralData; import org.bouncycastle.openpgp.PGPLiteralDataGenerator; import org.bouncycastle.openpgp.PGPObjectFactory; import org.bouncycastle.openpgp.PGPPBEEncryptedData; import org.bouncycastle.openpgp.operator.bc.BcPBEDataDecryptorFactory; import org.bouncycastle.openpgp.operator.bc.BcPBEKeyEncryptionMethodGenerator; import org.bouncycastle.openpgp.operator.bc.BcPGPDataEncryptorBuilder; import org.bouncycastle.openpgp.operator.bc.BcPGPDigestCalculatorProvider; import org.bouncycastle.util.encoders.Base64; import org.bouncycastle.util.encoders.Hex; import org.bouncycastle.util.test.SimpleTest; import org.bouncycastle.util.test.UncloseableOutputStream; public class BcPGPPBETest extends SimpleTest { private static final Date TEST_DATE = new Date(1062200111000L); byte[] enc1 = Base64.decode( "jA0EAwMC5M5wWBP2HBZgySvUwWFAmMRLn7dWiZN6AkQMvpE3b6qwN3SSun7zInw2" + "hxxdgFzVGfbjuB8w"); byte[] enc1crc = Base64.decode("H66L"); char[] pass = { 'h', 'e', 'l', 'l', 'o', ' ', 'w', 'o', 'r', 'l', 'd' }; /** * Message with both PBE and symmetric */ byte[] testPBEAsym = Base64.decode( "hQIOA/ZlQEFWB5vuEAf/covEUaBve7NlWWdiO5NZubdtTHGElEXzG9hyBycp9At8" + "nZGi27xOZtEGFQo7pfz4JySRc3O0s6w7PpjJSonFJyNSxuze2LuqRwFWBYYcbS8/" + "7YcjB6PqutrT939OWsozfNqivI9/QyZCjBvFU89pp7dtUngiZ6MVv81ds2I+vcvk" + "GlIFcxcE1XoCIB3EvbqWNaoOotgEPT60unnB2BeDV1KD3lDRouMIYHfZ3SzBwOOI" + "6aK39sWnY5sAK7JjFvnDAMBdueOiI0Fy+gxbFD/zFDt4cWAVSAGTC4w371iqppmT" + "25TM7zAtCgpiq5IsELPlUZZnXKmnYQ7OCeysF0eeVwf+OFB9fyvCEv/zVQocJCg8" + "fWxfCBlIVFNeNQpeGygn/ZmRaILvB7IXDWP0oOw7/F2Ym66IdYYIp2HeEZv+jFwa" + "l41w5W4BH/gtbwGjFQ6CvF/m+lfUv6ZZdzsMIeEOwhP5g7rXBxrbcnGBaU+PXbho" + "gjDqaYzAWGlrmAd6aPSj51AGeYXkb2T1T/yoJ++M3GvhH4C4hvitamDkksh/qRnM" + "M/s8Nku6z1+RXO3M6p5QC1nlAVqieU8esT43945eSoC77K8WyujDNbysDyUCUTzt" + "p/aoQwe/HgkeOTJNelKR9y2W3xinZLFzep0SqpNI/e468yB/2/LGsykIyQa7JX6r" + "BYwuBAIDAkOKfv5rK8v0YDfnN+eFqwhTcrfBj5rDH7hER6nW3lNWcMataUiHEaMg" + "o6Q0OO1vptIGxW8jClTD4N1sCNwNu9vKny8dKYDDHbCjE06DNTv7XYVW3+JqTL5E" + "BnidvGgOmA=="); /** * decrypt the passed in message stream */ private byte[] decryptMessage( byte[] message, Date date) throws Exception { PGPObjectFactory pgpF = new PGPObjectFactory(message); PGPEncryptedDataList enc = (PGPEncryptedDataList)pgpF.nextObject(); PGPPBEEncryptedData pbe = (PGPPBEEncryptedData)enc.get(0); InputStream clear = pbe.getDataStream(new BcPBEDataDecryptorFactory(pass, new BcPGPDigestCalculatorProvider())); PGPObjectFactory pgpFact = new PGPObjectFactory(clear); PGPLiteralData ld = (PGPLiteralData)pgpFact.nextObject(); ByteArrayOutputStream bOut = new ByteArrayOutputStream(); if (!ld.getFileName().equals("test.txt") && !ld.getFileName().equals("_CONSOLE")) { fail("wrong filename in packet"); } if (!ld.getModificationTime().equals(date)) { fail("wrong modification time in packet: " + ld.getModificationTime().getTime() + " " + date.getTime()); } InputStream unc = ld.getInputStream(); int ch; while ((ch = unc.read()) >= 0) { bOut.write(ch); } if (pbe.isIntegrityProtected() && !pbe.verify()) { fail("integrity check failed"); } return bOut.toByteArray(); } private byte[] decryptMessageBuffered( byte[] message, Date date) throws Exception { PGPObjectFactory pgpF = new PGPObjectFactory(message); PGPEncryptedDataList enc = (PGPEncryptedDataList)pgpF.nextObject(); PGPPBEEncryptedData pbe = (PGPPBEEncryptedData)enc.get(0); InputStream clear = pbe.getDataStream(new BcPBEDataDecryptorFactory(pass, new BcPGPDigestCalculatorProvider())); PGPObjectFactory pgpFact = new PGPObjectFactory(clear);; PGPLiteralData ld = (PGPLiteralData)pgpFact.nextObject(); ByteArrayOutputStream bOut = new ByteArrayOutputStream(); if (!ld.getFileName().equals("test.txt") && !ld.getFileName().equals("_CONSOLE")) { fail("wrong filename in packet"); } if (!ld.getModificationTime().equals(date)) { fail("wrong modification time in packet: " + ld.getModificationTime().getTime() + " " + date.getTime()); } InputStream unc = ld.getInputStream(); byte[] buf = new byte[1024]; int len; while ((len = unc.read(buf)) >= 0) { bOut.write(buf, 0, len); } if (pbe.isIntegrityProtected() && !pbe.verify()) { fail("integrity check failed"); } return bOut.toByteArray(); } public void performTest() throws Exception { // compressed data not supported // byte[] out = decryptMessage(enc1, TEST_DATE); // // if (out[0] != 'h' || out[1] != 'e' || out[2] != 'l') // { // fail("wrong plain text in packet"); // } // // // create a PBE encrypted message and read it back. // byte[] text = { (byte)'h', (byte)'e', (byte)'l', (byte)'l', (byte)'o', (byte)' ', (byte)'w', (byte)'o', (byte)'r', (byte)'l', (byte)'d', (byte)'!', (byte)'\n' }; // // encryption step - convert to literal data, compress, encode. // ByteArrayOutputStream bOut = new ByteArrayOutputStream(); Date cDate = new Date((System.currentTimeMillis() / 1000) * 1000); PGPLiteralDataGenerator lData = new PGPLiteralDataGenerator(); OutputStream comOut = bOut; OutputStream ldOut = lData.open( new UncloseableOutputStream(comOut), PGPLiteralData.BINARY, PGPLiteralData.CONSOLE, text.length, cDate); ldOut.write(text); ldOut.close(); comOut.close(); // // encrypt - with stream close // ByteArrayOutputStream cbOut = new ByteArrayOutputStream(); PGPEncryptedDataGenerator cPk = new PGPEncryptedDataGenerator(new BcPGPDataEncryptorBuilder(PGPEncryptedData.CAST5).setSecureRandom(new SecureRandom())); cPk.addMethod(new BcPBEKeyEncryptionMethodGenerator(pass)); OutputStream cOut = cPk.open(new UncloseableOutputStream(cbOut), bOut.toByteArray().length); cOut.write(bOut.toByteArray()); cOut.close(); byte[] out = decryptMessage(cbOut.toByteArray(), cDate); if (!areEqual(out, text)) { fail("wrong plain text in generated packet"); } // // encrypt - with generator close // cbOut = new ByteArrayOutputStream(); cPk = new PGPEncryptedDataGenerator(new BcPGPDataEncryptorBuilder(PGPEncryptedData.CAST5).setSecureRandom(new SecureRandom())); cPk.addMethod(new BcPBEKeyEncryptionMethodGenerator(pass)); cOut = cPk.open(new UncloseableOutputStream(cbOut), bOut.toByteArray().length); cOut.write(bOut.toByteArray()); cPk.close(); out = decryptMessage(cbOut.toByteArray(), cDate); if (!areEqual(out, text)) { fail("wrong plain text in generated packet"); } // // encrypt - partial packet style. // SecureRandom rand = new SecureRandom(); byte[] test = new byte[1233]; rand.nextBytes(test); bOut = new ByteArrayOutputStream(); comOut = bOut; lData = new PGPLiteralDataGenerator(); ldOut = lData.open(new UncloseableOutputStream(comOut), PGPLiteralData.BINARY, PGPLiteralData.CONSOLE, TEST_DATE, new byte[16]); ldOut.write(test); ldOut.close(); comOut.close(); cbOut = new ByteArrayOutputStream(); cPk = new PGPEncryptedDataGenerator(new BcPGPDataEncryptorBuilder(PGPEncryptedData.CAST5).setSecureRandom(rand)); cPk.addMethod(new BcPBEKeyEncryptionMethodGenerator(pass)); cOut = cPk.open(new UncloseableOutputStream(cbOut), new byte[16]); cOut.write(bOut.toByteArray()); cOut.close(); out = decryptMessage(cbOut.toByteArray(), TEST_DATE); if (!areEqual(out, test)) { fail("wrong plain text in generated packet"); } // // with integrity packet // cbOut = new ByteArrayOutputStream(); cPk = new PGPEncryptedDataGenerator(new BcPGPDataEncryptorBuilder(PGPEncryptedData.CAST5).setWithIntegrityPacket(true).setSecureRandom(rand)); cPk.addMethod(new BcPBEKeyEncryptionMethodGenerator(pass)); cOut = cPk.open(new UncloseableOutputStream(cbOut), new byte[16]); cOut.write(bOut.toByteArray()); cOut.close(); out = decryptMessage(cbOut.toByteArray(), TEST_DATE); if (!areEqual(out, test)) { fail("wrong plain text in generated packet"); } // // decrypt with buffering // out = decryptMessageBuffered(cbOut.toByteArray(), TEST_DATE); if (!areEqual(out, test)) { fail("wrong plain text in buffer generated packet"); } // // sample message // PGPObjectFactory pgpFact = new PGPObjectFactory(testPBEAsym); PGPEncryptedDataList enc = (PGPEncryptedDataList)pgpFact.nextObject(); PGPPBEEncryptedData pbe = (PGPPBEEncryptedData)enc.get(1); InputStream clear = pbe.getDataStream(new BcPBEDataDecryptorFactory("password".toCharArray(), new BcPGPDigestCalculatorProvider())); pgpFact = new PGPObjectFactory(clear); // Compressed data not supported // PGPLiteralData ld = (PGPLiteralData)pgpFact.nextObject(); // // bOut = new ByteArrayOutputStream(); // InputStream unc = ld.getInputStream(); // int ch; // // while ((ch = unc.read()) >= 0) // { // bOut.write(ch); // } // // if (!areEqual(bOut.toByteArray(), Hex.decode("5361742031302e30322e30370d0a"))) // { // fail("data mismatch on combined PBE"); // } // // with integrity packet - one byte message // byte[] msg = new byte[1]; bOut = new ByteArrayOutputStream(); lData = new PGPLiteralDataGenerator(); comOut = bOut; ldOut = lData.open( new UncloseableOutputStream(comOut), PGPLiteralData.BINARY, PGPLiteralData.CONSOLE, msg.length, cDate); ldOut.write(msg); ldOut.close(); comOut.close(); cbOut = new ByteArrayOutputStream(); cPk = new PGPEncryptedDataGenerator(new BcPGPDataEncryptorBuilder(PGPEncryptedData.CAST5).setWithIntegrityPacket(true).setSecureRandom(rand)); cPk.addMethod(new BcPBEKeyEncryptionMethodGenerator(pass)); cOut = cPk.open(new UncloseableOutputStream(cbOut), new byte[16]); cOut.write(bOut.toByteArray()); cOut.close(); out = decryptMessage(cbOut.toByteArray(), cDate); if (!areEqual(out, msg)) { fail("wrong plain text in generated packet"); } // // decrypt with buffering // out = decryptMessageBuffered(cbOut.toByteArray(), cDate); if (!areEqual(out, msg)) { fail("wrong plain text in buffer generated packet"); } } public String getName() { return "BcPGPPBETest"; } public static void main( String[] args) { runTest(new BcPGPPBETest()); } } bouncycastle-1.49.orig/j2me/org/bouncycastle/openpgp/test/BcPGPKeyRingTest.java0000644000175000017500000034520211732241021027065 0ustar ebourgebourgpackage org.bouncycastle.openpgp.test; import java.io.ByteArrayInputStream; import java.math.BigInteger; import java.security.SecureRandom; import java.util.Date; import java.util.Iterator; import org.bouncycastle.bcpg.HashAlgorithmTags; import org.bouncycastle.crypto.AsymmetricCipherKeyPair; import org.bouncycastle.crypto.generators.DSAKeyPairGenerator; import org.bouncycastle.crypto.generators.DSAParametersGenerator; import org.bouncycastle.crypto.generators.ElGamalKeyPairGenerator; import org.bouncycastle.crypto.generators.RSAKeyPairGenerator; import org.bouncycastle.crypto.params.DSAKeyGenerationParameters; import org.bouncycastle.crypto.params.ElGamalKeyGenerationParameters; import org.bouncycastle.crypto.params.ElGamalParameters; import org.bouncycastle.crypto.params.RSAKeyGenerationParameters; import org.bouncycastle.openpgp.PGPEncryptedData; import org.bouncycastle.openpgp.PGPException; import org.bouncycastle.openpgp.PGPKeyPair; import org.bouncycastle.openpgp.PGPKeyRingGenerator; import org.bouncycastle.openpgp.PGPPrivateKey; import org.bouncycastle.openpgp.PGPPublicKey; import org.bouncycastle.openpgp.PGPPublicKeyRing; import org.bouncycastle.openpgp.PGPPublicKeyRingCollection; import org.bouncycastle.openpgp.PGPSecretKey; import org.bouncycastle.openpgp.PGPSecretKeyRing; import org.bouncycastle.openpgp.PGPSecretKeyRingCollection; import org.bouncycastle.openpgp.PGPSignature; import org.bouncycastle.openpgp.operator.PGPDigestCalculator; import org.bouncycastle.openpgp.operator.bc.BcKeyFingerprintCalculator; import org.bouncycastle.openpgp.operator.bc.BcPBESecretKeyDecryptorBuilder; import org.bouncycastle.openpgp.operator.bc.BcPBESecretKeyEncryptorBuilder; import org.bouncycastle.openpgp.operator.bc.BcPGPContentSignerBuilder; import org.bouncycastle.openpgp.operator.bc.BcPGPContentVerifierBuilderProvider; import org.bouncycastle.openpgp.operator.bc.BcPGPDigestCalculatorProvider; import org.bouncycastle.openpgp.operator.bc.BcPGPKeyPair; import org.bouncycastle.util.encoders.Base64; import org.bouncycastle.util.encoders.Hex; import org.bouncycastle.util.test.SimpleTest; public class BcPGPKeyRingTest extends SimpleTest { byte[] pub1 = Base64.decode( "mQGiBEA83v0RBADzKVLVCnpWQxX0LCsevw/3OLs0H7MOcLBQ4wMO9sYmzGYn" + "xpVj+4e4PiCP7QBayWyy4lugL6Lnw7tESvq3A4v3fefcxaCTkJrryiKn4+Cg" + "y5rIBbrSKNtCEhVi7xjtdnDjP5kFKgHYjVOeIKn4Cz/yzPG3qz75kDknldLf" + "yHxp2wCgwW1vAE5EnZU4/UmY7l8kTNkMltMEAJP4/uY4zcRwLI9Q2raPqAOJ" + "TYLd7h+3k/BxI0gIw96niQ3KmUZDlobbWBI+VHM6H99vcttKU3BgevNf8M9G" + "x/AbtW3SS4De64wNSU3189XDG8vXf0vuyW/K6Pcrb8exJWY0E1zZQ1WXT0gZ" + "W0kH3g5ro//Tusuil9q2lVLF2ovJA/0W+57bPzi318dWeNs0tTq6Njbc/GTG" + "FUAVJ8Ss5v2u6h7gyJ1DB334ExF/UdqZGldp0ugkEXaSwBa2R7d3HBgaYcoP" + "Ck1TrovZzEY8gm7JNVy7GW6mdOZuDOHTxyADEEP2JPxh6eRcZbzhGuJuYIif" + "IIeLOTI5Dc4XKeV32a+bWrQidGVzdCAoVGVzdCBrZXkpIDx0ZXN0QHViaWNh" + "bGwuY29tPohkBBMRAgAkBQJAPN79AhsDBQkB4TOABgsJCAcDAgMVAgMDFgIB" + "Ah4BAheAAAoJEJh8Njfhe8KmGDcAoJWr8xgPr75y/Cp1kKn12oCCOb8zAJ4p" + "xSvk4K6tB2jYbdeSrmoWBZLdMLACAAC5AQ0EQDzfARAEAJeUAPvUzJJbKcc5" + "5Iyb13+Gfb8xBWE3HinQzhGr1v6A1aIZbRj47UPAD/tQxwz8VAwJySx82ggN" + "LxCk4jW9YtTL3uZqfczsJngV25GoIN10f4/j2BVqZAaX3q79a3eMiql1T0oE" + "AGmD7tO1LkTvWfm3VvA0+t8/6ZeRLEiIqAOHAAQNBACD0mVMlAUgd7REYy/1" + "mL99Zlu9XU0uKyUex99sJNrcx1aj8rIiZtWaHz6CN1XptdwpDeSYEOFZ0PSu" + "qH9ByM3OfjU/ya0//xdvhwYXupn6P1Kep85efMBA9jUv/DeBOzRWMFG6sC6y" + "k8NGG7Swea7EHKeQI40G3jgO/+xANtMyTIhPBBgRAgAPBQJAPN8BAhsMBQkB" + "4TOAAAoJEJh8Njfhe8KmG7kAn00mTPGJCWqmskmzgdzeky5fWd7rAKCNCp3u" + "ZJhfg0htdgAfIy8ppm05vLACAAA="); byte[] sec1 = Base64.decode( "lQHhBEA83v0RBADzKVLVCnpWQxX0LCsevw/3OLs0H7MOcLBQ4wMO9sYmzGYn" + "xpVj+4e4PiCP7QBayWyy4lugL6Lnw7tESvq3A4v3fefcxaCTkJrryiKn4+Cg" + "y5rIBbrSKNtCEhVi7xjtdnDjP5kFKgHYjVOeIKn4Cz/yzPG3qz75kDknldLf" + "yHxp2wCgwW1vAE5EnZU4/UmY7l8kTNkMltMEAJP4/uY4zcRwLI9Q2raPqAOJ" + "TYLd7h+3k/BxI0gIw96niQ3KmUZDlobbWBI+VHM6H99vcttKU3BgevNf8M9G" + "x/AbtW3SS4De64wNSU3189XDG8vXf0vuyW/K6Pcrb8exJWY0E1zZQ1WXT0gZ" + "W0kH3g5ro//Tusuil9q2lVLF2ovJA/0W+57bPzi318dWeNs0tTq6Njbc/GTG" + "FUAVJ8Ss5v2u6h7gyJ1DB334ExF/UdqZGldp0ugkEXaSwBa2R7d3HBgaYcoP" + "Ck1TrovZzEY8gm7JNVy7GW6mdOZuDOHTxyADEEP2JPxh6eRcZbzhGuJuYIif" + "IIeLOTI5Dc4XKeV32a+bWv4CAwJ5KgazImo+sGBfMhDiBcBTqyDGhKHNgHic" + "0Pky9FeRvfXTc2AO+jGmFPjcs8BnTWuDD0/jkQnRZpp1TrQidGVzdCAoVGVz" + "dCBrZXkpIDx0ZXN0QHViaWNhbGwuY29tPohkBBMRAgAkBQJAPN79AhsDBQkB" + "4TOABgsJCAcDAgMVAgMDFgIBAh4BAheAAAoJEJh8Njfhe8KmGDcAn3XeXDMg" + "BZgrZzFWU2IKtA/5LG2TAJ0Vf/jjyq0jZNZfGfoqGTvD2MAl0rACAACdAVgE" + "QDzfARAEAJeUAPvUzJJbKcc55Iyb13+Gfb8xBWE3HinQzhGr1v6A1aIZbRj4" + "7UPAD/tQxwz8VAwJySx82ggNLxCk4jW9YtTL3uZqfczsJngV25GoIN10f4/j" + "2BVqZAaX3q79a3eMiql1T0oEAGmD7tO1LkTvWfm3VvA0+t8/6ZeRLEiIqAOH" + "AAQNBACD0mVMlAUgd7REYy/1mL99Zlu9XU0uKyUex99sJNrcx1aj8rIiZtWa" + "Hz6CN1XptdwpDeSYEOFZ0PSuqH9ByM3OfjU/ya0//xdvhwYXupn6P1Kep85e" + "fMBA9jUv/DeBOzRWMFG6sC6yk8NGG7Swea7EHKeQI40G3jgO/+xANtMyTP4C" + "AwJ5KgazImo+sGBl2C7CFuI+5KM4ZhbtVie7l+OiTpr5JW2z5VgnV3EX9p04" + "LcGKfQvD65+ELwli6yh8B2zGcipqTaYk3QoYNIhPBBgRAgAPBQJAPN8BAhsM" + "BQkB4TOAAAoJEJh8Njfhe8KmG7kAniuRkaFFv1pdCBN8JJXpcorHmyouAJ9L" + "xxmusffR6OI7WgD3XZ0AL8zUC7ACAAA="); char[] pass1 = "qwertzuiop".toCharArray(); byte[] pub2 = Base64.decode( "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"); byte[] sec2 = Base64.decode( "lQHpBEBtfW8RBADfWjTxFedIbGBNVgh064D/OCf6ul7x4PGsCl+BkAyheYkr" + "mVUsChmBKoeXaY+Fb85wwusXzyM/6JFK58Rg+vEb3Z19pue8Ixxq7cRtCtOA" + "tOP1eKXLNtTRWJutvLkQmeOa19UZ6ziIq23aWuWKSq+KKMWek2GUnGycnx5M" + "W0pn1QCg/39r9RKhY9cdKYqRcqsr9b2B/AsD/Ru24Q15Jmrsl9zZ6EC47J49" + "iNW5sLQx1qf/mgfVWQTmU2j6gq4ND1OuK7+0OP/1yMOUpkjjcqxFgTnDAAoM" + "hHDTzCv/aZzIzmMvgLsYU3aIMfbz+ojpuASMCMh+te01cEMjiPWwDtdWWOdS" + "OSyX9ylzhO3PiNDks8R83onsacYpA/9WhTcg4bvkjaj66I7wGZkm3BmTxNSb" + "pE4b5HZDh31rRYhY9tmrryCfFnU4BS2Enjj5KQe9zFv7pUBCBW2oFo8i8Osn" + "O6fa1wVN4fBHC6wqWmmpnkFerNPkiC9V75KUFIfeWHmT3r2DVSO3dfdHDERA" + "jFIAioMLjhaX6DnODF5KQv4JAwIJH6A/rzqmMGAG4e+b8Whdvp8jaTGVT4CG" + "M1b65rbiDyAuf5KTFymQBOIi9towgFzG9NXAZC07nEYSukN56tUTUDNVsAGH" + "tCZTYWkgUHVsbGFiaG90bGEgPHBzYWlAbXlqYXZhd29ybGQuY29tPrADA///" + "iQBXBBARAgAXBQJAbX1vBwsJCAcDAgoCGQEFGwMAAAAACgkQpdB/9FP325iZ" + "8ACgwrFXmDajAh+bLbDu9Iu85BSm+84AnieMHrEmi3nbes8BBb2K0+gYZ6SK" + "sAFnnQJqBEBtfW8QCAD2Qle3CH8IF3KiutapQvMF6PlTETlPtvFuuUs4INoB" + "p1ajFOmPQFXz0AfGy0OplK33TGSGSfgMg71l6RfUodNQ+PVZX9x2Uk89PY3b" + "zpnhV5JZzf24rnRPxfx2vIPFRzBhznzJZv8V+bv9kV7HAarTW56NoKVyOtQa" + "8L9GAFgr5fSI/VhOSdvNILSd5JEHNmszbDgNRR0PfIizHHxbLY7288kjwEPw" + "pVsYjY67VYy4XTjTNP18F1dDox0YbN4zISy1Kv884bEpQBgRjXyEpwpy1obE" + "AxnIByl6ypUM2Zafq9AKUJsCRtMIPWakXUGfnHy9iUsiGSa6q6Jew1XpMgs7" + "AAICB/0Xv+ckcNrInekFVNNVKraDlYpRcyDHEYpO85qGJVFxs7TfDSkoCQfz" + "kI5qRV97nqwxilZGXfpp2M2go7FpyKjDvgPVHmydj+G/+QFc8GTOjhQyRsA0" + "hVpnQhycun6uSRdwNVtEKJtl/wV8JjXNdup3rzRS0SBFu/UPzAUGp8y3uQuy" + "5/0WcjDq8rgNTTrPlkODblEcaazBoPJjozA0YKsoZsd/0j9Pswy6EYX+KfxR" + "TyG/y5EQ6Ox46qSUbf+ewjWEP8x1QLt/NeIxE7hG9qEuh5c65oOQxgAt0mTm" + "eY24IvVg+lsUa20jdewrtSs/8WF3w0Po2ujAKqs3qR524r64/gkDAmmp39NN" + "U2pqYHokufIOab2VpD7iQo8UjHZNwR6dpjyky9dVfIe4MA0H+t0ju8UDdWoe" + "IkRu8guWsI83mjGPbIq8lmsZOXPCA8hPuBmL0iaj8TnuotmsBjIBsAGHiQBM" + "BBgRAgAMBQJAbX1vBRsMAAAAAAoJEKXQf/RT99uYL/QAnivXK/K7ip85eUOC" + "ZW4Ky8cVajreAJ9EisIHYm/83VyCmarQvwsYczsb8rABZ5UDqARAbX2jAQgA" + "ydq8tipHt99oM9tur6VBm8sIr/e4DRCXKeA3JNqwNbRYLX+vLLZ3HvKk44KJ" + "yOc9h+Dcs/lORgAagyPEfn7HMzrF85H7z8TArXM3cDn5f89IEOViND10RUqu" + "+9zuIw6n7UrVUx/hSDxhqHbY63h4sY/QdEJeK/m+B0E2wCX+5ecEm4NhCYus" + "SeKqr/pTEkcofFmhL/mnXcKrs18oHUIkK4ldoIRNbZ2j5wOk3qvSW2QX+v4R" + "L7YvuPHKgdy9DhiismgMyUA3rGkhlDx01pNg/+czH+kNLeyFTNtT5Rg9Cut4" + "kswXWkP5hY/kxMpplOj5T+o+MMUZxp0ieE/G+HfWywARAQABCWEWL2cKQKcm" + "XFTNsWgRoOcOkKyJ/osERh2PzNWvOF6/ir1BMRsg0qhd+hEcoWHaT+7Vt12i" + "5Y2Ogm2HFrVrS5/DlV/rw0mkALp/3cR6jLOPyhmq7QGwhG27Iy++pLIksXQa" + "RTboa7ZasEWw8zTqa4w17M5Ebm8dtB9Mwl/kqU9cnIYnFXj38BWeia3iFBNG" + "PD00hqwhPUCTUAcH9qQPSqKqnFJVPe0KQWpq78zhCh1zPUIa27CE86xRBf45" + "XbJwN+LmjCuQEnSNlloXJSPTRjEpla+gWAZz90fb0uVIR1dMMRFxsuaO6aCF" + "QMN2Mu1wR/xzTzNCiQf8cVzq7YkkJD8ChJvu/4BtWp3BlU9dehAz43mbMhaw" + "Qx3NmhKR/2dv1cJy/5VmRuljuzC+MRtuIjJ+ChoTa9ubNjsT6BF5McRAnVzf" + "raZK+KVWCGA8VEZwe/K6ouYLsBr6+ekCKIkGZdM29927m9HjdFwEFjnzQlWO" + "NZCeYgDcK22v7CzobKjdo2wdC7XIOUVCzMWMl+ch1guO/Y4KVuslfeQG5X1i" + "PJqV+bwJriCx5/j3eE/aezK/vtZU6cchifmvefKvaNL34tY0Myz2bOx44tl8" + "qNcGZbkYF7xrNCutzI63xa2ruN1p3hNxicZV1FJSOje6+ITXkU5Jmufto7IJ" + "t/4Q2dQefBQ1x/d0EdX31yK6+1z9dF/k3HpcSMb5cAWa2u2g4duAmREHc3Jz" + "lHCsNgyzt5mkb6kS43B6og8Mm2SOx78dBIOA8ANzi5B6Sqk3/uN5eQFLY+sQ" + "qGxXzimyfbMjyq9DdqXThx4vlp3h/GC39KxL5MPeB0oe6P3fSP3C2ZGjsn3+" + "XcYk0Ti1cBwBOFOZ59WYuc61B0wlkiU/WGeaebABh7QuU2FuZGh5YSBQdWxs" + "YWJob3RsYSA8cHNhbmRoeWFAbXlqYXZhd29ybGQuY29tPrADA///iQEtBBAB" + "AgAXBQJAbX2jBwsJCAcDAgoCGQEFGwMAAAAACgkQx87DL9gOvoeVUwgAkQXY" + "iF0CxhKbDnuabAssnOEwJrutgCROCJRQvIwTe3fe6hQaWn2Yowt8OQtNFiR8" + "GfAY6EYxyFLKzZbAI/qtq5fHmN3eRSyNWe6d6e17hqZZL7kf2sVkyGTChHj7" + "Jiuo7vWkdqT2MJN6BW5tS9CRH7MeD839STv+4mAAO9auGvSvicP6UEQikAyC" + "y/ihoJxLQlspfbSNpi0vrUjCPT7NtWwfP0qF64i9LYkjzLqihnu+UareqOPh" + "XcWnyFKrjmg4ezQkweNU2pdvCLbcW24FhT92ivHgpLyWTswXcqjhFjVlRr0+" + "2sIz7v1k0budCsJ7PjzOoH0hJxCvsJQMlZR/e7ABZ50DqARAbX2kAQgAm5j+" + "/LO2M4pKm/VUPkYuj3eefHkzjM6nKbvRZX1Oqyf+6CJTxQskUWKAtkzzKafP" + "dS5Wg0CMqeXov+EFod4bPEYccszncKd1U8NRwacbEpCvvvB84Yl2YwdWpDpk" + "ryyyLI4PbCHkeuwx9Dc2z7t4XDB6FyAJTMAkia7nzYa/kbeUO3c2snDb/dU7" + "uyCsyKtTZyTyhTgtl/f9L03Bgh95y3mOUz0PimJ0Sg4ANczF4d04BpWkjLNV" + "Ji489ifWodPlHm1hag5drYekYpWJ+3g0uxs5AwayV9BcOkPKb1uU3EoYQw+n" + "n0Kn314Nvx2M1tKYunuVNLEm0PhA/+B8PTq8BQARAQABCXo6bD6qi3s4U8Pp" + "Uf9l3DyGuwiVPGuyb2P+sEmRFysi2AvxMe9CkF+CLCVYfZ32H3Fcr6XQ8+K8" + "ZGH6bJwijtV4QRnWDZIuhUQDS7dsbGqTh4Aw81Fm0Bz9fpufViM9RPVEysxs" + "CZRID+9jDrACthVsbq/xKomkKdBfNTK7XzGeZ/CBr9F4EPlnBWClURi9txc0" + "pz9YP5ZRy4XTFgx+jCbHgKWUIz4yNaWQqpSgkHEDrGZwstXeRaaPftcfQN+s" + "EO7OGl/Hd9XepGLez4vKSbT35CnqTwMzCK1IwUDUzyB4BYEFZ+p9TI18HQDW" + "hA0Wmf6E8pjS16m/SDXoiRY43u1jUVZFNFzz25uLFWitfRNHCLl+VfgnetZQ" + "jMFr36HGVQ65fogs3avkgvpgPwDc0z+VMj6ujTyXXgnCP/FdhzgkRFJqgmdJ" + "yOlC+wFmZJEs0MX7L/VXEXdpR27XIGYm24CC7BTFKSdlmR1qqenXHmCCg4Wp" + "00fV8+aAsnesgwPvxhCbZQVp4v4jqhVuB/rvsQu9t0rZnKdDnWeom/F3StYo" + "A025l1rrt0wRP8YS4XlslwzZBqgdhN4urnzLH0/F3X/MfjP79Efj7Zk07vOH" + "o/TPjz8lXroPTscOyXWHwtQqcMhnVsj9jvrzhZZSdUuvnT30DR7b8xcHyvAo" + "WG2cnF/pNSQX11RlyyAOlw9TOEiDJ4aLbFdkUt+qZdRKeC8mEC2xsQ87HqFR" + "pWKWABWaoUO0nxBEmvNOy97PkIeGVFNHDLlIeL++Ry03+JvuNNg4qAnwacbJ" + "TwQzWP4vJqre7Gl/9D0tVlD4Yy6Xz3qyosxdoFpeMSKHhgKVt1bk0SQP7eXA" + "C1c+eDc4gN/ZWpl+QLqdk2T9vr4wRAaK5LABh4kBIgQYAQIADAUCQG19pAUb" + "DAAAAAAKCRDHzsMv2A6+h5C6B/0QWPJb1L9a/CHU7Of3zfHvzJxnk4S5fia5" + "WBf+Ld7Y12CH+cVI/3PTXY63imIB3zLa21TNPC5cVFUJZI7hdwyJOW1R/QZa" + "vGl5sosIjORqwq8vs1oqpKWc3tRue+wt/JjCWxw8G6jQiwCzM6PltqtOAL5e" + "bJ4jZwzRmxs/RI4UYKO6EteipJA+i7OEZx0xGdL8mTl6HQx7vrJP9pM4/CtO" + "5CmjPK70e2gyoiOxx9RsSc+9H59YJCrldogCCIlNuW7cvkt8K/uYdN9GAbFG" + "RdanignRjpqSu3vTn8r/VO63+meZfKvmpI6i2b3o/UZ8Xh9lJu1vrRoNpnuP" + "Nifs+ljmsAFn"); char[] sec2pass1 = "sandhya".toCharArray(); char[] sec2pass2 = "psai".toCharArray(); byte[] pub3 = Base64.decode( "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" + "n3FaE6UZE9GMDmCIAjhI+0X9aH6CsAIAAw=="); byte[] sec3 = Base64.decode( "lQHhBEB9BH0RBACtYQtE7tna6hgGyGLpq+ds3r2cLC0ISn5dNw7tm9vwiNVF" + "JA2N37RRrifw4PvgelRSvLaX3M3ZBqC9s1Metg3v4FSlIRtSLWCNpHSvNw7i" + "X8C2Xy9Hdlbh6Y/50o+iscojLRE14upfR1bIkcCZQGSyvGV52V2wBImUUZjV" + "s2ZngwCg7mu852vK7+euz4WaL7ERVYtq9CMEAJ5swrljerDpz/RQ4Lhp6KER" + "KyuI0PUttO57xINGshEINgYlZdGaZHRueHe7uKfI19mb0T4N3NJWaZ0wF+Cn" + "rixsq0VrTUfiwfZeGluNG73aTCeY45fVXMGTTSYXzS8T0LW100Xn/0g9HRyA" + "xUpuWo8IazxkMqHJis2uwriYKpAfA/9anvj5BS9p5pfPjp9dGM7GTMIYl5f2" + "fcP57f+AW1TVR6IZiMJAvAdeWuLtwLnJiFpGlnFz273pfl+sAuqm1yNceImR" + "2SDDP4+vtyycWy8nZhgEuhZx3W3cWMQz5WyNJSY1JJHh9TCQkCoN8E7XpVP4" + "zEPboB2GzD93mfD8JLHP+/4DAwIvYrn+YqRaaGAu19XUj895g/GROyP8WEaU" + "Bd/JNqWc4kE/0guetGnPzq7G3bLVwiKfFd4X7BrgHAo3mrQtVGVzdCBLZXkg" + "KG5vIGNvbW1lbnQpIDx0ZXN0QGJvdW5jeWNhc3RsZS5vcmc+iFkEExECABkF" + "AkB9BH0ECwcDAgMVAgMDFgIBAh4BAheAAAoJEKnMV8vjZQOpSRQAoKZy6YS1" + "irF5/Q3JlWiwbkN6dEuLAJ9lldRLOlXsuQ5JW1+SLEc6K9ho4rACAADRwXPB" + "cQEQAAEBAAAAAAAAAAAAAAAA/9j/4AAQSkZJRgABAQEASABIAAD//gAXQ3Jl" + "YXRlZCB3aXRoIFRoZSBHSU1Q/9sAQwAIBgYHBgUIBwcHCQkICgwUDQwLCwwZ" + "EhMPFB0aHx4dGhwcICQuJyAiLCMcHCg3KSwwMTQ0NB8nOT04MjwuMzQy/9sA" + "QwEJCQkMCwwYDQ0YMiEcITIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIy" + "MjIyMjIyMjIyMjIyMjIyMjIyMjIy/8AAEQgAFAAUAwEiAAIRAQMRAf/EABoA" + "AQACAwEAAAAAAAAAAAAAAAAEBQIDBgf/xAAoEAABAgUDBAEFAAAAAAAAAAAB" + "AgMABBEhMQUSQQYTIiNhFFGBkcH/xAAXAQEAAwAAAAAAAAAAAAAAAAAEAgMF" + "/8QAJBEAAQQAAwkAAAAAAAAAAAAAAQACERIEIfATMTJBUZGx0fH/2gAMAwEA" + "AhEDEQA/APMuotJlJVxstqaPo22NlAUp+YsNO0qSUtBcMu6n6EtOHcfPAHHF" + "I16++oajQtTA3DapK02HFR8UpE9pTbQWtKm2WG2rlxVyQTcfGbn7Qm0OIjL7" + "7Wrs2NNm9lzTmmSxQ0PX4opSprk5tmESF6syggzGwOLG6gXgHFbZhBixk8Xl" + "IDcOQLRKt+rX+3qC5ZLTQblpQlvwvxn9CMpZturVGkJHapQJphRH8hCLXbzr" + "qpYsCx1zC5rtpJNuYQhASc0UAQv/2YhcBBMRAgAcBQJAfQV+AhsDBAsHAwID" + "FQIDAxYCAQIeAQIXgAAKCRCpzFfL42UDqfa2AJ9hjtEeDTbTEAuuSbzhYFxN" + "/qc0FACgsmzysdbBpuN65yK01tbEaeIMtqCwAgAAnQEUBEB9BH4QAwCqRuWO" + "rxm5v/8WWBtPEUZnYuu3WYxefRKn6ON5ka5Ymp4AfKpKqKqn982tjlG13GVE" + "P2ow11L4yQKGNm+VyVEapm7SpMD0SHg9vsJygAWrfMJnBYWSgE19W6o3ckUR" + "sWsAAwYDAKDCSiSxC3Z5/POaCehw5iHs/vmVk5Wn831LSZEEwkSohNDbIEry" + "ia/9tFXSt11AP4stJtZ0MH87/6JBbiIRD4JXcx+zfzchL7Teczr/06QMphSn" + "sAENupbhLupfpR+BbP4DAwIvYrn+YqRaaGBjvFK1fbxCt7ZM4I2W/3BC0lCX" + "m/NypKNspGflec8u96uUlA0fNCnxm6f9nbB0jpvoKi0g4iqAf+P2iEYEGBEC" + "AAYFAkB9BH4ACgkQqcxXy+NlA6mtMgCgvccZA/Sg7BXVpxli47SYhxSHoM4A" + "oNCOMplSnYTuh5ikKeBWtz36gC1psAIAAA=="); char[] sec3pass1 = "123456".toCharArray(); // // GPG comment packets. // byte[] sec4 = Base64.decode( "lQG7BD0PbK8RBAC0cW4Y2MZXmAmqYp5Txyw0kSQsFvwZKHNMFRv996IsN57URVF5" + "BGMVPRBi9dNucWbjiSYpiYN13wE9IuLZsvVaQojV4XWGRDc+Rxz9ElsXnsYQ3mZU" + "7H1bNQEofstChk4z+dlvPBN4GFahrIzn/CeVUn6Ut7dVdYbiTqviANqNXwCglfVA" + "2OEePvqFnGxs1jhJyPSOnTED/RwRvsLH/k43mk6UEvOyN1RIpBXN+Ieqs7h1gFrQ" + "kB+WMgeP5ZUsotTffVDSUS9UMxRQggVUW1Xml0geGwQsNfkr/ztWMs/T4xp1v5j+" + "QyJx6OqNlkGdqOsoqkzJx0SQ1zBxdinFyyC4H95SDAb/RQOu5LQmxFG7quexztMs" + "infEA/9cVc9+qCo92yRAaXRqKNVVQIQuPxeUsGMyVeJQvJBD4An8KTMCdjpF10Cp" + "qA3t+n1S0zKr5WRUtvS6y60MOONO+EJWVWBNkx8HJDaIMNkfoqQoz3Krn7w6FE/v" + "/5uwMd6jY3N3yJZn5nDZT9Yzv9Nx3j+BrY+henRlSU0c6xDc9QAAnjJYg0Z83VJG" + "6HrBcgc4+4K6lHulCqH9JiM6RFNBX2ZhY3RvcjoAAK9hV206agp99GI6x5qE9+pU" + "vs6O+Ich/SYjOkRTQV9mYWN0b3I6AACvYAfGn2FGrpBYbjnpTuFOHJMS/T5xg/0m" + "IzpEU0FfZmFjdG9yOgAAr0dAQz6XxMwxWIn8xIZR/v2iN2L9C6O0EkZvbyBCYXIg" + "PGJhekBxdXV4PohXBBMRAgAXBQI9D2yvBQsHCgMEAxUDAgMWAgECF4AACgkQUGLI" + "YCIktfoGogCfZiXMJUKrScqozv5tMwzTTk2AaT8AniM5iRr0Du/Y08SL/NMhtF6H" + "hJ89nO4EPQ9ssRADAI6Ggxj6ZBfoavuXd/ye99osW8HsNlbqhXObu5mCMNySX2wa" + "HoWyRUEaUkI9eQw+MlHzIwzA32E7y2mU3OQBKdgLcBg4jxtcWVEg8ESKF9MpFXxl" + "pExxWrr4DFBfCRcsTwAFEQL9G3OvwJuEZXgx2JSS41D3pG4/qiHYICVa0u3p/14i" + "cq0kXajIk5ZJ6frCIAHIzuQ3n7jjzr05yR8s/qCrNbBA+nlkVNa/samk+jCzxxxa" + "cR/Dbh2wkvTFuDFFETwQYLuZAADcDck4YGQAmHivVT2NNDCf/aTz0+CJWl+xRc2l" + "Qw7D/SQjOkVMR19mYWN0b3I6AACbBnv9m5/bb/pjYAm2PtDp0CysQ9X9JCM6RUxH" + "X2ZhY3RvcjoAAJsFyHnSmaWguTFf6lJ/j39LtUNtmf0kIzpFTEdfZmFjdG9yOgAA" + "mwfwMD3LxmWtuCWBE9BptWMNH07Z/SQjOkVMR19mYWN0b3I6AACbBdhBrbSiM4UN" + "y7khDW2Sk0e4v9mIRgQYEQIABgUCPQ9ssQAKCRBQYshgIiS1+jCMAJ9txwHnb1Kl" + "6i/fSoDs8SkdM7w48wCdFvPEV0sSxE73073YhBgPZtMWbBo="); // // PGP freeware version 7 // byte[] pub5 = Base64.decode( "mQENBEBrBE4BCACjXVcNIFDQSofaIyZnALb2CRg+WY9uUqgHEEAOlPe03Cs5STM5" + "HDlNmrh4TdFceJ46rxk1mQOjULES1YfHay8lCIzrD7FX4oj0r4DC14Fs1vXaSar2" + "1szIpttOw3obL4A1e0p6N4jjsoG7N/pA0fEL0lSw92SoBrMbAheXRg4qNTZvdjOR" + "grcuOuwgJRvPLtRXlhyLBoyhkd5mmrIDGv8QHJ/UjpeIcRXY9kn9oGXnEYcRbMaU" + "VwXB4pLzWqz3ZejFI3lOxRWjm760puPOnGYlzSVBxlt2LgzUgSj1Mn+lIpWmAzsa" + "xEiU4xUwEomQns72yYRZ6D3euNCibcte4SeXABEBAAG0KXBhbGFzaCBrYXNvZGhh" + "biA8cGthc29kaGFuQHRpYWEtY3JlZi5vcmc+iQEuBBABAgAYBQJAawROCAsBAwkI" + "BwIKAhkBBRsDAAAAAAoJEOfelumuiOrYqPEH+wYrdP5Tq5j+E5yN1pyCg1rwbSOt" + "Dka0y0p7Oq/VIGLk692IWPItLEunnBXQtGBcWqklrvogvlhxtf16FgoyScfLJx1e" + "1cJa+QQnVuH+VOESN6iS9Gp9lUfVOHv74mEMXw0l2Djfy/lnrkAMBatggyGnF9xF" + "VXOLk1J2WVFm9KUE23o6qdB7RGkf31pN2eA7SWmkdJSkUH7o/QSFBI+UTRZ/IY5P" + "ZIJpsdiIOqd9YMG/4RoSZuPqNRR6x7BSs8nQVR9bYs4PPlp4GfdRnOcRonoTeJCZ" + "83RnsraWJnJTg34gRLBcqumhTuFKc8nuCNK98D6zkQESdcHLLTquCOaF5L+5AQ0E" + "QGsETwEIAOVwNCTaDZvW4dowPbET1bI5UeYY8rAGLYsWSUfgaFv2srMiApyBVltf" + "i6OLcPjcUCHDBjCv4pwx/C4qcHWb8av4xQIpqQXOpO9NxYE1eZnel/QB7DtH12ZO" + "nrDNmHtaXlulcKNGe1i1utlFhgzfFx6rWkRL0ENmkTkaQmPY4gTGymJTUhBbsSRq" + "2ivWqQA1TPwBuda73UgslIAHRd/SUaxjXoLpMbGOTeqzcKGjr5XMPTs7/YgBpWPP" + "UxMlEQIiU3ia1bxpEhx05k97ceK6TSH2oCPQA7gumjxOSjKT+jEm+8jACVzymEmc" + "XRy4D5Ztqkw/Z16pvNcu1DI5m6xHwr8AEQEAAYkBIgQYAQIADAUCQGsETwUbDAAA" + "AAAKCRDn3pbprojq2EynB/4/cEOtKbI5UisUd3vkTzvWOcqWUqGqi5wjjioNtIM5" + "pur2nFvhQE7SZ+PbAa87HRJU/4WcWMcoLkHD48JrQwHCHOLHSV5muYowb78X4Yh9" + "epYtSJ0uUahcn4Gp48p4BkhgsPYXkxEImSYzAOWStv21/7WEMqItMYl89BV6Upm8" + "HyTJx5MPTDbMR7X51hRg3OeQs6po3WTCWRzFIMyGm1rd/VK1L5ZDFPqO3S6YUJ0z" + "cxecYruvfK0Wp7q834wE8Zkl/PQ3NhfEPL1ZiLr/L00Ty+77/FZqt8SHRCICzOfP" + "OawcVGI+xHVXW6lijMpB5VaVIH8i2KdBMHXHtduIkPr9"); byte[] sec5 = Base64.decode( "lQOgBEBrBE4BCACjXVcNIFDQSofaIyZnALb2CRg+WY9uUqgHEEAOlPe03Cs5STM5" + "HDlNmrh4TdFceJ46rxk1mQOjULES1YfHay8lCIzrD7FX4oj0r4DC14Fs1vXaSar2" + "1szIpttOw3obL4A1e0p6N4jjsoG7N/pA0fEL0lSw92SoBrMbAheXRg4qNTZvdjOR" + "grcuOuwgJRvPLtRXlhyLBoyhkd5mmrIDGv8QHJ/UjpeIcRXY9kn9oGXnEYcRbMaU" + "VwXB4pLzWqz3ZejFI3lOxRWjm760puPOnGYlzSVBxlt2LgzUgSj1Mn+lIpWmAzsa" + "xEiU4xUwEomQns72yYRZ6D3euNCibcte4SeXABEBAAEB8wqP7JkKN6oMNi1xJNqU" + "vvt0OV4CCnrIFiOPCjebjH/NC4T/9pJ6BYSjYdo3VEPNhPhRS9U3071Kqbdt35J5" + "kmzMq1yNStC1jkxHRCNTMsb1yIEY1v+fv8/Cy+tBpvAYiJKaox8jW3ppi9vTHZjW" + "tYYq0kwAVojMovz1O3wW/pEF69UPBmPYsze+AHA1UucYYqdWO8U2tsdFJET/hYpe" + "o7ppHJJCdqWzeiE1vDUrih9pP3MPpzcRS/gU7HRDb5HbfP7ghSLzByEa+2mvg5eK" + "eLwNAx2OUtrVg9rJswXX7DOLa1nKPhdGrSV/qwuK4rBdaqJ/OvszVJ0Vln0T/aus" + "it1PAuVROLUPqTVVN8/zkMenFbf5vtryC3GQYXvvZq+l3a4EXwrR/1pqrTfnfOuD" + "GwlFhRJAqPfthxZS68/xC8qAmTtkl7j4nscNM9kSoZ3BFwSyD9B/vYHPWGlqnpGF" + "k/hBXuIgl07KIeNIyEC3f1eRyaiMFqEz5yXbbTfEKirSVpHM/mpeKxG8w96aK3Je" + "AV0X6ZkC4oLTp6HCG2TITUIeNxCh2rX3fhr9HvBDXBbMHgYlIcLwzNkwDX74cz/7" + "nIclcubaWjEkDHP20XFicuChFc9zx6kBYuYy170snltTBgTWSuRH15W4NQqrLo37" + "zyzZQubX7CObgQJu4ahquiOg4SWl6uEI7+36U0SED7sZzw8ns1LxrwOWbXuHie1i" + "xCvsJ4RpJJ03iEdNdUIb77qf6AriqE92tXzcVXToBv5S2K5LdFYNJ1rWdwaKJRkt" + "kmjCL67KM9WT/IagsUyU+57ao3COtqw9VWZi6ev+ubM6fIV0ZK46NEggOLph1hi2" + "gZ9ew9uVuruYg7lG2Ku82N0fjrQpcGFsYXNoIGthc29kaGFuIDxwa2Fzb2RoYW5A" + "dGlhYS1jcmVmLm9yZz6dA6AEQGsETwEIAOVwNCTaDZvW4dowPbET1bI5UeYY8rAG" + "LYsWSUfgaFv2srMiApyBVltfi6OLcPjcUCHDBjCv4pwx/C4qcHWb8av4xQIpqQXO" + "pO9NxYE1eZnel/QB7DtH12ZOnrDNmHtaXlulcKNGe1i1utlFhgzfFx6rWkRL0ENm" + "kTkaQmPY4gTGymJTUhBbsSRq2ivWqQA1TPwBuda73UgslIAHRd/SUaxjXoLpMbGO" + "TeqzcKGjr5XMPTs7/YgBpWPPUxMlEQIiU3ia1bxpEhx05k97ceK6TSH2oCPQA7gu" + "mjxOSjKT+jEm+8jACVzymEmcXRy4D5Ztqkw/Z16pvNcu1DI5m6xHwr8AEQEAAQF7" + "osMrvQieBAJFYY+x9jKPVclm+pVaMaIcHKwCTv6yUZMqbHNRTfwdCVKTdAzdlh5d" + "zJNXXRu8eNwOcfnG3WrWAy59cYE389hA0pQPOh7iL2V1nITf1qdLru1HJqqLC+dy" + "E5GtkNcgvQYbv7ACjQacscvnyBioYC6TATtPnHipMO0S1sXEnmUugNlW88pDln4y" + "VxCtQXMBjuqMt0bURqmb+RoYhHhoCibo6sexxSnbEAPHBaW1b1Rm7l4UBSW6S5U0" + "MXURE60IHfP1TBe1l/xOIxOi8qdBQCyaFW2up00EhRBy/WOO6KAYXQrRRpOs9TBq" + "ic2wquwZePmErTbIttnnBcAKmpodrM/JBkn/we5fVg+FDTP8sM/Ubv0ZuM70aWmF" + "v0/ZKbkCkh2YORLWl5+HR/RKShdkmmFgZZ5uzbOGxxEGKhw+Q3+QFUF7PmYOnOtv" + "s9PZE3dV7ovRDoXIjfniD1+8sLUWwW5d+3NHAQnCHJrLnPx4sTHx6C0yWMcyZk6V" + "fNHpLK4xDTbgoTmxJa/4l+wa0iD69h9K/Nxw/6+X/GEM5w3d/vjlK1Da6urN9myc" + "GMsfiIll5DNIWdLLxCBPFmhJy653CICQLY5xkycWB7JOZUBTOEVrYr0AbBZSTkuB" + "fq5p9MfH4N51M5TWnwlJnqEiGnpaK+VDeP8GniwCidTYyiocNPvghvWIzG8QGWMY" + "PFncRpjFxmcY4XScYYpyRme4qyPbJhbZcgGpfeLvFKBPmNxVKJ2nXTdx6O6EbHDj" + "XctWqNd1EQas7rUN728u7bk8G7m37MGqQuKCpNvOScH4TnPROBY8get0G3bC4mWz" + "6emPeENnuyElfWQiHEtCZr1InjnNbb/C97O+vWu9PfsE"); char[] sec5pass1 = "12345678".toCharArray(); // // Werner Koch "odd keys" // byte[] pub6 = Base64.decode( "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" + "L4Kb7TWkd/OHQScVBO8sTUz0+2g="); byte[] pub6check = Base64.decode("62O9"); // // revoked sub key // byte[] pub7 = Base64.decode( "mQGiBEFOsIwRBADcjRx7nAs4RaWsQU6p8/ECLZD9sSeYc6CN6UDI96RKj0/hCzMs" + "qlA0+9fzGZ7ZEJ34nuvDKlhKGC7co5eOiE0a9EijxgcrZU/LClZWa4YfyNg/ri6I" + "yTyfOfrPQ33GNQt2iImDf3FKp7XKuY9nIxicGQEaW0kkuAmbV3oh0+9q8QCg/+fS" + "epDEqEE/+nKONULGizKUjMED/RtL6RThRftZ9DOSdBytGYd48z35pca/qZ6HA36K" + "PVQwi7V77VKQyKFLTOXPLnVyO85hyYB/Nv4DFHN+vcC7/49lfoyYMZlN+LarckHi" + "NL154wmmzygB/KKysvWBLgkErEBCD0xBDd89iTQNlDtVQAWGORVffl6WWjOAkliG" + "3dL6A/9A288HfFRnywqi3xddriV6wCPmStC3dkCS4vHk2ofS8uw4ZNoRlp1iEPna" + "ai2Xa9DX1tkhaGk2k96MqqbBdGpbW8sMA9otJ9xdMjWEm/CgJUFUFQf3zaVy3mkM" + "S2Lvb6P4Wc2l/diEEIyK8+PqJItSh0OVU3K9oM7ngHwVcalKILQVUkV2b2tlZCA8" + "UmV2b2tlZEB0ZWQ+iQBOBBARAgAOBQJBTrCMBAsDAgECGQEACgkQvglkcFA/c63+" + "QgCguh8rsJbPTtbhZcrqBi5Mo1bntLEAoPZQ0Kjmu2knRUpHBeUemHDB6zQeuQIN" + "BEFOsIwQCAD2Qle3CH8IF3KiutapQvMF6PlTETlPtvFuuUs4INoBp1ajFOmPQFXz" + "0AfGy0OplK33TGSGSfgMg71l6RfUodNQ+PVZX9x2Uk89PY3bzpnhV5JZzf24rnRP" + "xfx2vIPFRzBhznzJZv8V+bv9kV7HAarTW56NoKVyOtQa8L9GAFgr5fSI/VhOSdvN" + "ILSd5JEHNmszbDgNRR0PfIizHHxbLY7288kjwEPwpVsYjY67VYy4XTjTNP18F1dD" + "ox0YbN4zISy1Kv884bEpQBgRjXyEpwpy1obEAxnIByl6ypUM2Zafq9AKUJsCRtMI" + "PWakXUGfnHy9iUsiGSa6q6Jew1XpMgs7AAICB/93zriSvSHqsi1FeEmUBo431Jkh" + "VerIzb6Plb1j6FIq+s3vyvx9K+dMvjotZqylWZj4GXpH+2xLJTjWkrGSfUZVI2Nk" + "nyOFxUCKLLqaqVBFAQIjULfvQfGEWiGQKk9aRLkdG+D+8Y2N9zYoBXoQ9arvvS/t" + "4mlOsiuaTe+BZ4x+BXTpF4b9sKZl7V8QP/TkoJWUdydkvxciHdWp7ssqyiKOFRhG" + "818knDfFQ3cn2w/RnOb+7AF9wDncXDPYLfpPv9b2qZoLrXcyvlLffGDUdWs553ut" + "1F5AprMURs8BGmY9BnjggfVubHdhTUoA4gVvrdaf+D9NwZAl0xK/5Y/oPuMZiQBG" + "BBgRAgAGBQJBTrCMAAoJEL4JZHBQP3Ot09gAoMmLKloVDP+WhDXnsM5VikxysZ4+" + "AKCrJAUO+lYAyPYwEwgK+bKmUGeKrIkARgQoEQIABgUCQU6wpQAKCRC+CWRwUD9z" + "rQK4AJ98kKFxGU6yhHPr6jYBJPWemTNOXgCfeGB3ox4PXeS4DJDuLy9yllytOjo="); byte[] pub7check = Base64.decode("f/YQ"); byte[] pub8 = Base64.decode( "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" + "9Uqz3fUvGoewAWA="); byte[] sec8 = Base64.decode( "lQHpBEEcraYRBADFYj+uFOhHz5SdECvJ3Z03P47gzmWLQ5HH8fPYC9rrv7AgqFFX" + "aWlJJVMLua9e6xoCiDWJs/n4BbZ/weL/11ELg6XqUnzFhYyz0H2KFsPgQ/b9lWLY" + "MtcPMFy5jE33hv/ixHgYLFqoNaAIbg0lzYEW/otQ9IhRl16fO1Q/CQZZrQCg/9M2" + "V2BTmm9RYog86CXJtjawRBcD/RIqU0zulxZ2Zt4javKVxrGIwW3iBU935ebmJEIK" + "Y5EVkGKBOCvsApZ+RGzpYeR2uMsTnQi8RJgiAnjaoVPCdsVJE7uQ0h8XuJ5n5mJ2" + "kLCFlF2hj5ViicZzse+crC12CGtgRe8z23ubLRcd6IUGhVutK8/b5knZ22vE14JD" + "ykKdA/96ObzJQdiuuPsEWN799nUUCaYWPAoLAmiXuICSP4GEnxLbYHWo8zhMrVMT" + "9Q5x3h8cszUz7Acu2BXjP1m96msUNoxPOZtt88NlaFz1Q/JSbQTsVOMd9b/IRN6S" + "A/uU0BiKEMHXuT8HUHVPK49oCKhZrGFP3RT8HZxDKLmR/qrgZ/4JAwLXyWhb4pf4" + "nmCmD0lDwoYvatLiR7UQVM2MamxClIiT0lCPN9C2AYIFgRWAJNS215Tjx7P/dh7e" + "8sYfh5XEHErT3dMbsAGHtCFKaWEgWWl5dSA8eXlqaWFAbm93bWVkaWF0ZWNoLmNv" + "bT6wAwP//4kAXQQQEQIAHQUCQRytpgcLCQgHAwIKAhkBBRsDAAAABR4BAAAAAAoJ" + "EPT+Vvgr/2IUmWEAoJEyJ9B7CJfmjwVTT30UbdCctVRmAJ9akw6we6UYd82vF0FK" + "QTlSuqHXKbABZ50CawRBHK2mEAgA9kJXtwh/CBdyorrWqULzBej5UxE5T7bxbrlL" + "OCDaAadWoxTpj0BV89AHxstDqZSt90xkhkn4DIO9ZekX1KHTUPj1WV/cdlJPPT2N" + "286Z4VeSWc39uK50T8X8dryDxUcwYc58yWb/Ffm7/ZFexwGq01uejaClcjrUGvC/" + "RgBYK+X0iP1YTknbzSC0neSRBzZrM2w4DUUdD3yIsxx8Wy2O9vPJI8BD8KVbGI2O" + "u1WMuF040zT9fBdXQ6MdGGzeMyEstSr/POGxKUAYEY18hKcKctaGxAMZyAcpesqV" + "DNmWn6vQClCbAkbTCD1mpF1Bn5x8vYlLIhkmuquiXsNV6TILOwACAgf/crbApFLO" + "QikN9lHbn62dDxuu/dNigNmjf/A3cX+vo8aPHTXnRDyDwQALRuqbitdbM6p1LFjG" + "8g84Aabk/jL7zzjJLqPe8pxeK1Pu+P44NzalXAYMsOOsxGuixIrz3Jw8IrpH/mkP" + "tG/iX0NaLZ+Au9eokdLb+6NR/a51r2qL3E0ycFciJ61HzZKKHi6d0VQ7CHozCz+j" + "d5530Mh1qq/ZjYDDjfP+snpyNIZXcLtGR/3HzkBqNgDcvClLx3322AWKDa7pX8DX" + "qiLr8znWhPRpH9kCTnSpRzhYGT25FRcvdj4/q/oUIET/Tp+BWW3BxAc7WgpgqEfn" + "fa0Mv72Zbn91gf4JAwITijME9IlFBGAwH6YmBtWIlnDiRbsq/Pxozuhbnes831il" + "KmdpUKXkiIfHY0MqrEWl3Dfn6PMJGTnhgqXMrDxx3uHrq0Jl2swRnAWIIO8gID7j" + "uPetUqEviPiwAYeJAEwEGBECAAwFAkEcraYFGwwAAAAACgkQ9P5W+Cv/YhShrgCg" + "+JW8m5nF3R/oZGuG87bXQBszkjMAoLhGPncuGKowJXMRVc70/8qwXQJLsAFn"); char[] sec8pass = "qwertyui".toCharArray(); byte[] sec9 = Base64.decode( "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" + "6neEEX/i1Q=="); public char[] sec9pass = "foo".toCharArray(); // version 4 keys with expiry dates byte[] pub10 = Base64.decode( "mQGiBEKqia0RBACc3hkufmscRSC4UvPZqMDsHm4+d/GXIr+3iNMSSEySJu8yk+k0" + "Xs11C/K+n+v1rnn2jGGknv+1lDY6w75TIcTE6o6HGKeIDxsAm8P3MhoGU1GNPamA" + "eTDeNybtrN/g6C65fCY9uI11hsUboYgQZ8ND22PB0VtvdOgq9D85qNUzxwCg1BbJ" + "ycAKd4VqEvQ2Zglp3dCSrFMD/Ambq1kZqYa69sp3b9BPKuAgUgUPoytOArEej3Bk" + "easAgAxNhWJy4GxigES3vk50rVi7w8XBuqbD1mQCzldF0HX0/A7PxLBv6od5uqqF" + "HFxIyxg/KBZLd9ZOrsSaoUWH58jZq98X/sFtJtRi5VuJagMxCIJD4mLgtMv7Unlb" + "/GrsA/9DEnObA/fNTgK70T+ZmPIS5tSt+bio30Aw4YGpPCGqpnm1u73b5kqX3U3B" + "P+vGDvFuqZYpqQA8byAueH0MbaDHI4CFugvShXvgysJxN7ov7/8qsZZUMfK1t2Nr" + "SAsPuKRbcY4gNKXIElKeXbyaET7vX7uAEKuxEwdYGFp/lNTkHLQgdGVzdCBrZXkg" + "KHRlc3QpIDx0ZXN0QHRlc3QudGVzdD6IZAQTEQIAJAUCQqqJrQIbAwUJACTqAAYL" + "CQgHAwIDFQIDAxYCAQIeAQIXgAAKCRDjDROQZRqIzDzLAJ42AeCRIBBjv8r8qw9y" + "laNj2GZ1sACgiWYHVXMA6B1H9I1kS3YsCd3Oq7qwAgAAuM0EQqqJrhADAKWkix8l" + "pJN7MMTXob4xFF1TvGll0UD1bDGOMMbes6aeXSbT9QXee/fH3GnijLY7wB+qTPv9" + "ohubrSpnv3yen3CEBW6Q2YK+NlCskma42Py8YMV2idmYjtJi1ckvHFWt5wADBQL/" + "fkB5Q5xSGgspMaTZmtmX3zG7ZDeZ0avP8e8mRL8UszCTpqs6vMZrXwyQLZPbtMYv" + "PQpuRGEeKj0ysimwYRA5rrLQjnRER3nyuuEUUgc4j+aeRxPf9WVsJ/a1FCHtaAP1" + "iE8EGBECAA8FAkKqia4CGwwFCQAk6gAACgkQ4w0TkGUaiMzdqgCfd66H7DL7kFGd" + "IoS+NIp8JO+noxAAn25si4QAF7og8+4T5YQUuhIhx/NesAIAAA=="); byte[] sec10 = Base64.decode( "lQHhBEKqia0RBACc3hkufmscRSC4UvPZqMDsHm4+d/GXIr+3iNMSSEySJu8yk+k0" + "Xs11C/K+n+v1rnn2jGGknv+1lDY6w75TIcTE6o6HGKeIDxsAm8P3MhoGU1GNPamA" + "eTDeNybtrN/g6C65fCY9uI11hsUboYgQZ8ND22PB0VtvdOgq9D85qNUzxwCg1BbJ" + "ycAKd4VqEvQ2Zglp3dCSrFMD/Ambq1kZqYa69sp3b9BPKuAgUgUPoytOArEej3Bk" + "easAgAxNhWJy4GxigES3vk50rVi7w8XBuqbD1mQCzldF0HX0/A7PxLBv6od5uqqF" + "HFxIyxg/KBZLd9ZOrsSaoUWH58jZq98X/sFtJtRi5VuJagMxCIJD4mLgtMv7Unlb" + "/GrsA/9DEnObA/fNTgK70T+ZmPIS5tSt+bio30Aw4YGpPCGqpnm1u73b5kqX3U3B" + "P+vGDvFuqZYpqQA8byAueH0MbaDHI4CFugvShXvgysJxN7ov7/8qsZZUMfK1t2Nr" + "SAsPuKRbcY4gNKXIElKeXbyaET7vX7uAEKuxEwdYGFp/lNTkHP4DAwLssmOjVC+d" + "mWB783Lpzjb9evKzsxisTdx8/jHpUSS+r//6/Guyx3aA/zUw5bbftItW57mhuNNb" + "JTu7WrQgdGVzdCBrZXkgKHRlc3QpIDx0ZXN0QHRlc3QudGVzdD6IZAQTEQIAJAUC" + "QqqJrQIbAwUJACTqAAYLCQgHAwIDFQIDAxYCAQIeAQIXgAAKCRDjDROQZRqIzDzL" + "AJ0cYPwKeoSReY14LqJtAjnkX7URHACgsRZWfpbalrSyDnq3TtZeGPUqGX+wAgAA" + "nQEUBEKqia4QAwClpIsfJaSTezDE16G+MRRdU7xpZdFA9WwxjjDG3rOmnl0m0/UF" + "3nv3x9xp4oy2O8Afqkz7/aIbm60qZ798np9whAVukNmCvjZQrJJmuNj8vGDFdonZ" + "mI7SYtXJLxxVrecAAwUC/35AeUOcUhoLKTGk2ZrZl98xu2Q3mdGrz/HvJkS/FLMw" + "k6arOrzGa18MkC2T27TGLz0KbkRhHio9MrIpsGEQOa6y0I50REd58rrhFFIHOI/m" + "nkcT3/VlbCf2tRQh7WgD9f4DAwLssmOjVC+dmWDXVLRopzxbBGOvodp/LZoSDb56" + "gNJjDMJ1aXqWW9qTAg1CFjBq73J3oFpVzInXZ8+Q8inxv7bnWiHbiE8EGBECAA8F" + "AkKqia4CGwwFCQAk6gAACgkQ4w0TkGUaiMzdqgCgl2jw5hfk/JsyjulQqe1Nps1q" + "Lx0AoMdnFMZmTMLHn8scUW2j9XO312tmsAIAAA=="); public char[] sec10pass = "test".toCharArray(); public byte[] subKeyBindingKey = Base64.decode( "mQGiBDWagYwRBAD7UcH4TAIp7tmUoHBNxVxCVz2ZrNo79M6fV63riOiH2uDxfIpr" + "IrL0cM4ehEKoqlhngjDhX60eJrOw1nC5BpYZRnDnyDYT4wTWRguxObzGq9pqA1dM" + "oPTJhkFZVIBgFY99/ULRqaUYIhFGgBtnwS70J8/L/PGVc3DmWRLMkTDjSQCg/5Nh" + "MCjMK++MdYMcMl/ziaKRT6EEAOtw6PnU9afdohbpx9CK4UvCCEagfbnUtkSCQKSk" + "6cUp6VsqyzY0pai/BwJ3h4apFMMMpVrtBAtchVgqo4xTr0Sve2j0k+ase6FSImiB" + "g+AR7hvTUTcBjwtIExBc8TuCTqmn4GG8F7UMdl5Z0AZYj/FfAQYaRVZYP/pRVFNx" + "Lw65BAC/Fi3qgiGCJFvXnHIckTfcAmZnKSEXWY9NJ4YQb4+/nH7Vsw0wR/ZObUHR" + "bWgTc9Vw1uZIMe0XVj6Yk1dhGRehUnrm3mE7UJxu7pgkBCbFECFSlSSqP4MEJwZV" + "09YP/msu50kjoxyoTpt+16uX/8B4at24GF1aTHBxwDLd8X0QWrQsTWVycmlsbCBM" + "eW5jaCBDTEVBUiBzeXN0ZW0gREggPGNsZWFyQG1sLmNvbT6JAEsEEBECAAsFAjWa" + "gYwECwMBAgAKCRDyAGjiP47/XanfAKCs6BPURWVQlGh635VgL+pdkUVNUwCdFcNa" + "1isw+eAcopXPMj6ACOapepu5Ag0ENZqBlBAIAPZCV7cIfwgXcqK61qlC8wXo+VMR" + "OU+28W65Szgg2gGnVqMU6Y9AVfPQB8bLQ6mUrfdMZIZJ+AyDvWXpF9Sh01D49Vlf" + "3HZSTz09jdvOmeFXklnN/biudE/F/Ha8g8VHMGHOfMlm/xX5u/2RXscBqtNbno2g" + "pXI61Brwv0YAWCvl9Ij9WE5J280gtJ3kkQc2azNsOA1FHQ98iLMcfFstjvbzySPA" + "Q/ClWxiNjrtVjLhdONM0/XwXV0OjHRhs3jMhLLUq/zzhsSlAGBGNfISnCnLWhsQD" + "GcgHKXrKlQzZlp+r0ApQmwJG0wg9ZqRdQZ+cfL2JSyIZJrqrol7DVekyCzsAAgIH" + "/RYtVo+HROZ6jrNjrATEwQm1fUQrk6n5+2dniN881lF0CNkB4NkHw1Xxz4Ejnu/0" + "iLg8fkOAsmanOsKpOkRtqUnVpsVL5mLJpFEyCY5jbcfj+KY9/25bs0ga7kLHNZia" + "zbCxJdF+W179z3nudQxRaXG/0XISIH7ziZbSVni69sKc1osk1+OoOMbSuZ86z535" + "Pln4fXclkFE927HxfbWoO+60hkOLKh7x+8fC82b3x9vCETujEaxrscO2xS7/MYXP" + "8t1ffriTDmhuIuQS2q4fLgeWdqrODrMhrD8Dq7e558gzp30ZCqpiS7EmKGczL7B8" + "gXxbBCVSTxYMJheXt2xMXsuJAD8DBRg1moGU8gBo4j+O/10RAgWdAKCPhaFIXuC8" + "/cdiNMxTDw9ug3De5QCfYXmDzRSFUu/nrCi8yz/l09wsnxo="); public byte[] subKeyBindingCheckSum = Base64.decode("3HU+"); // // PGP8 with SHA1 checksum. // public byte[] rewrapKey = Base64.decode( "lQOWBEUPOQgBCADdjPTtl8oOwqJFA5WU8p7oDK5KRWfmXeXUZr+ZJipemY5RSvAM" + "rxqsM47LKYbmXOJznXCQ8+PPa+VxXAsI1CXFHIFqrXSwvB/DUmb4Ec9EuvNd18Zl" + "hJAybzmV2KMkaUp9oG/DUvxZJqkpUddNfwqZu0KKKZWF5gwW5Oy05VCpaJxQVXFS" + "whdbRfwEENJiNx4RB3OlWhIjY2p+TgZfgQjiGB9i15R+37sV7TqzBUZF4WWcnIRQ" + "DnpUfxHgxQ0wO/h/aooyRHSpIx5i4oNpMYq9FNIyakEx/Bomdbs5hW9dFxhrE8Es" + "UViAYITgTsyROxmgGatGG09dcmVDJVYF4i7JAAYpAAf/VnVyUDs8HrxYTOIt4rYY" + "jIHToBsV0IiLpA8fEA7k078L1MwSwERVVe6oHVTjeR4A9OxE52Vroh2eOLnF3ftf" + "6QThVVZr+gr5qeG3yvQ36N7PXNEVOlkyBzGmFQNe4oCA+NR2iqnAIspnekVmwJV6" + "xVvPCjWw/A7ZArDARpfthspwNcJAp4SWfoa2eKzvUTznTyqFu2PSS5fwQZUgOB0P" + "Y2FNaKeqV8vEZu4SUWwLOqXBQIZXiaLvdKNgwFvUe3kSHdCNsrVzW7SYxFwaEog2" + "o6YLKPVPqjlGX1cMOponGp+7n9nDYkQjtEsGSSMQkQRDAcBdSVJmLO07kFOQSOhL" + "WQQA49BcgTZyhyH6TnDBMBHsGCYj43FnBigypGT9FrQHoWybfX47yZaZFROAaaMa" + "U6man50YcYZPwzDzXHrK2MoGALY+DzB3mGeXVB45D/KYtlMHPLgntV9T5b14Scbc" + "w1ES2OUtsSIUs0zelkoXqjLuKnSIYK3mMb67Au7AEp6LXM8EAPj2NypvC86VEnn+" + "FH0QHvUwBpmDw0EZe25xQs0brvAG00uIbiZnTH66qsIfRhXV/gbKK9J5DTGIqQ15" + "DuPpz7lcxg/n2+SmjQLNfXCnG8hmtBjhTe+udXAUrmIcfafXyu68SAtebgm1ga56" + "zUfqsgN3FFuMUffLl3myjyGsg5DnA/oCFWL4WCNClOgL6A5VkNIUait8QtSdCACT" + "Y7jdSOguSNXfln0QT5lTv+q1AjU7zjRl/LsFNmIJ5g2qdDyK937FOXM44FEEjZty" + "/4P2dzYpThUI4QUohIj8Qi9f2pZQueC5ztH6rpqANv9geZKcciAeAbZ8Md0K2TEU" + "RD3Lh+RSBzILtBtUZXN0IEtleSA8dGVzdEBleGFtcGxlLmNvbT6JATYEEwECACAF" + "AkUPOQgCGwMGCwkIBwMCBBUCCAMEFgIDAQIeAQIXgAAKCRDYpknHeQaskD9NB/9W" + "EbFuLaqZAl3yjLU5+vb75BdvcfL1lUs44LZVwobNp3/0XbZdY76xVPNZURtU4u3L" + "sJfGlaF+EqZDE0Mqc+vs5SIb0OnCzNJ00KaUFraUtkByRV32T5ECHK0gMBjCs5RT" + "I0vVv+Qmzl4+X1Y2bJ2mlpBejHIrOzrBD5NTJimTAzyfnNfipmbqL8p/cxXKKzS+" + "OM++ZFNACj6lRM1W9GioXnivBRC88gFSQ4/GXc8yjcrMlKA27JxV+SZ9kRWwKH2f" + "6o6mojUQxnHr+ZFKUpo6ocvTgBDlC57d8IpwJeZ2TvqD6EdA8rZ0YriVjxGMDrX1" + "8esfw+iLchfEwXtBIRwS"); char[] rewrapPass = "voltage123".toCharArray(); byte[] pubWithX509 = Base64.decode( "mQENBERabjABCACtmfyo6Nph9MQjv4nmCWjZrRYnhXbivomAdIwYkLZUj1bjqE+j"+ "uaLzjZV8xSI59odZvrmOiqlzOc4txitQ1OX7nRgbOJ7qku0dvwjtIn46+HQ+cAFn"+ "2mTi81RyXEpO2uiZXfsNTxUtMi+ZuFLufiMc2kdk27GZYWEuasdAPOaPJnA+wW6i"+ "ZHlt0NfXIGNz864gRwhD07fmBIr1dMFfATWxCbgMd/rH7Z/j4rvceHD2n9yrhPze"+ "YN7W4Nuhsr2w/Ft5Cm9xO7vXT/cpto45uxn8f7jERep6bnUwNOhH8G+6xLQgTLD0"+ "qFBGVSIneK3lobs6+xn6VaGN8W0tH3UOaxA1ABEBAAG0D0NOPXFhLWRlZXBzaWdo"+ "dIkFDgQQZAIFAQUCRFpuMAUDCWdU0gMF/3gCGwPELGQBAQQwggTkMIIDzKADAgEC"+ "AhBVUMV/M6rIiE+IzmnPheQWMA0GCSqGSIb3DQEBBQUAMG4xEzARBgoJkiaJk/Is"+ "ZAEZFgNjb20xEjAQBgoJkiaJk/IsZAEZFgJxYTEVMBMGCgmSJomT8ixkARkWBXRt"+ "czAxMRUwEwYKCZImiZPyLGQBGRYFV2ViZmUxFTATBgNVBAMTDHFhLWRlZXBzaWdo"+ "dDAeFw0wNjA1MDQyMTEyMTZaFw0xMTA1MDQyMTIwMDJaMG4xEzARBgoJkiaJk/Is"+ "ZAEZFgNjb20xEjAQBgoJkiaJk/IsZAEZFgJxYTEVMBMGCgmSJomT8ixkARkWBXRt"+ "czAxMRUwEwYKCZImiZPyLGQBGRYFV2ViZmUxFTATBgNVBAMTDHFhLWRlZXBzaWdo"+ "dDCCASIwDQYJKoZIhvcNAQEBBQADggEPADCCAQoCggEBAK2Z/Kjo2mH0xCO/ieYJ"+ "aNmtFieFduK+iYB0jBiQtlSPVuOoT6O5ovONlXzFIjn2h1m+uY6KqXM5zi3GK1DU"+ "5fudGBs4nuqS7R2/CO0ifjr4dD5wAWfaZOLzVHJcSk7a6Jld+w1PFS0yL5m4Uu5+"+ "IxzaR2TbsZlhYS5qx0A85o8mcD7BbqJkeW3Q19cgY3PzriBHCEPTt+YEivV0wV8B"+ "NbEJuAx3+sftn+Piu9x4cPaf3KuE/N5g3tbg26GyvbD8W3kKb3E7u9dP9ym2jjm7"+ "Gfx/uMRF6npudTA06Efwb7rEtCBMsPSoUEZVIid4reWhuzr7GfpVoY3xbS0fdQ5r"+ "EDUCAwEAAaOCAXwwggF4MAsGA1UdDwQEAwIBhjAPBgNVHRMBAf8EBTADAQH/MB0G"+ "A1UdDgQWBBSmFTRv5y65DHtTYae48zl0ExNWZzCCASUGA1UdHwSCARwwggEYMIIB"+ "FKCCARCgggEMhoHFbGRhcDovLy9DTj1xYS1kZWVwc2lnaHQsQ049cWEtd3VtYW4x"+ "LWRjLENOPUNEUCxDTj1QdWJsaWMlMjBLZXklMjBTZXJ2aWNlcyxDTj1TZXJ2aWNl"+ "cyxDTj1Db25maWd1cmF0aW9uLERDPVdlYmZlLERDPXRtczAxLERDPXFhLERDPWNv"+ "bT9jZXJ0aWZpY2F0ZVJldm9jYXRpb25MaXN0P2Jhc2U/b2JqZWN0Q2xhc3M9Y1JM"+ "RGlzdHJpYnV0aW9uUG9pbnSGQmh0dHA6Ly9xYS13dW1hbjEtZGMud2ViZmUudG1z"+ "MDEucWEuY29tL0NlcnRFbnJvbGwvcWEtZGVlcHNpZ2h0LmNybDAQBgkrBgEEAYI3"+ "FQEEAwIBADANBgkqhkiG9w0BAQUFAAOCAQEAfuZCW3XlB7Eok35zQbvYt9rhAndT"+ "DNw3wPNI4ZzD1nXoYWnwhNNvWRpsOt4ExOSNdaHErfgDXAMyyg66Sro0TkAx8eAj"+ "fPQsyRAh0nm0glzFmJN6TdOZbj7hqGZjc4opQ6nZo8h/ULnaEwMIUW4gcSkZt0ww"+ "CuErl5NUrN3DpkREeCG/fVvQZ8ays3ibQ5ZCZnYBkLYq/i0r3NLW34WfYhjDY48J"+ "oQWtvFSAxvRfz2NGmqnrCHPQZxqlfdta97kDa4VQ0zSeBaC70gZkLmD1GJMxWoXW"+ "6tmEcgPY5SghInUf+L2u52V55MjyAFzVp7kTK2KY+p7qw35vzckrWkwu8AAAAAAA"+ "AQE="); private static byte[] secWithPersonalCertificate = Base64.decode( "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" + "cGdwbWltZQULBwgJAgIZAQUbAQAAAAUeAQAAAAIVAgAKCRDlTa3BE84gWVKW" + "BACcoCFKvph9r9QiHT1Z3N4wZH36Uxqu/059EFALnBkEdVudX/p6S9mynGRk" + "EfhmWFC1O6dMpnt+ZBEed/4XyFWVSLPwirML+6dxfXogdUsdFF1NCRHc3QGc" + "txnNUT/zcZ9IRIQjUhp6RkIvJPHcyfTXKSbLviI+PxzHU2Padq8pV7ABZ7kA" + "jQRIfg8tAQQAutJR/aRnfZYwlVv+KlUDYjG8YQUfHpTxpnmVu7W6N0tNg/Xr" + "5dg50wq3I4HOamRxUwHpdPkXyNF1szpDSRZmlM+VmiIvJDBnyH5YVlxT6+zO" + "8LUJ2VTbfPxoLFp539SQ0oJOm7IGMAGO7c0n/QV0N3hKUfWgCyJ+sENDa0Ft" + "JycAEQEAAbABj4kEzQQYAQIENwUCSMYtnAUJAeEzgMLFFAAAAAAAFwNleDUw" + "OWNlcnRpZmljYXRlQHBncC5jb20wggNhMIICyqADAgECAgkA1AoCoRKJCgsw" + "DQYJKoZIhvcNAQEFBQAwgakxCzAJBgNVBAYTAkNaMRcwFQYDVQQIEw5DemVj" + "aCBSZXB1YmxpYzESMBAGA1UEChQJQSYmTCBzb2Z0MSAwHgYDVQQLExdJbnRl" + "cm5hbCBEZXZlbG9wbWVudCBDQTEqMCgGA1UEAxQhQSYmTCBzb2Z0IEludGVy" + "bmFsIERldmVsb3BtZW50IENBMR8wHQYJKoZIhvcNAQkBFhBrYWRsZWNAYWxz" + "b2Z0LmN6MB4XDTA4MDcxNjE1MDkzM1oXDTA5MDcxNjE1MDkzM1owaTELMAkG" + "A1UEBhMCQ1oxFzAVBgNVBAgTDkN6ZWNoIFJlcHVibGljMRIwEAYDVQQKFAlB" + "JiZMIHNvZnQxFDASBgNVBAsTC0RldmVsb3BtZW50MRcwFQYDVQQDEw5IeW5l" + "ay1JbnRyYW5ldDCBnzANBgkqhkiG9w0BAQEFAAOBjQAwgYkCgYEAutJR/aRn" + "fZYwlVv+KlUDYjG8YQUfHpTxpnmVu7W6N0tNg/Xr5dg50wq3I4HOamRxUwHp" + "dPkXyNF1szpDSRZmlM+VmiIvJDBnyH5YVlxT6+zO8LUJ2VTbfPxoLFp539SQ" + "0oJOm7IGMAGO7c0n/QV0N3hKUfWgCyJ+sENDa0FtJycCAwEAAaOBzzCBzDAJ" + "BgNVHRMEAjAAMCwGCWCGSAGG+EIBDQQfFh1PcGVuU1NMIEdlbmVyYXRlZCBD" + "ZXJ0aWZpY2F0ZTAdBgNVHQ4EFgQUNaw7A6r10PtYZzAvr9CrSKeRYJgwHwYD" + "VR0jBBgwFoAUmqSRM8rN3+T1+tkGiqef8S5suYgwGgYDVR0RBBMwEYEPaHlu" + "ZWtAYWxzb2Z0LmN6MCgGA1UdHwQhMB8wHaAboBmGF2h0dHA6Ly9wZXRyazIv" + "Y2EvY2EuY3JsMAsGA1UdDwQEAwIF4DANBgkqhkiG9w0BAQUFAAOBgQCUdOWd" + "7mBLWj1/GSiYgfwgdTrgk/VZOJvMKBiiFyy1iFEzldz6Xx+mAexnFJKfZXZb" + "EMEGWHfWPmgJzAtuTT0Jz6tUwDmeLH3MP4m8uOZtmyUJ2aq41kciV3rGxF0G" + "BVlZ/bWTaOzHdm6cjylt6xxLt6MJzpPBA/9ZfybSBh1DaAUbDgAAAJ0gBBkB" + "AgAGBQJIxi2bAAoJEAdYkEWLb2R2fJED/RK+JErZ98uGo3Z81cHkdP3rk8is" + "DUL/PR3odBPFH2SIA5wrzklteLK/ZXmBUzcvxqHEgI1F7goXbsBgeTuGgZdx" + "pINErxkNpcMl9FTldWKGiapKrhkZ+G8knDizF/Y7Lg6uGd2nKVxzutLXdHJZ" + "pU89Q5nzq6aJFAZo5TBIcchQAAoJEOVNrcETziBZXvQD/1mvFqBfWqwXxoj3" + "8fHUuFrE2pcp32y3ciO2i+uNVEkNDoaVVNw5eHQaXXWpllI/Pe6LnBl4vkyc" + "n3pjONa4PKrePkEsCUhRbIySqXIHuNwZumDOlKzZHDpCUw72LaC6S6zwuoEf" + "ucOcxTeGIUViANWXyTIKkHfo7HfigixJIL8nsAFn"); private static final byte[] umlautKeySig = Base64.decode( "mI0ETdvOgQEEALoI2a39TRk1HReEB6DP9Bu3ShZUce+/Oeg9RIL9aUFuCsNdhu02" + "REEHjO29Jz8daPgrnJDfFepNLD6iKKru2m9P30qnhsHMIAshO2Ozfh6wKwuHRqR3" + "L4gBDu7cCB6SLwPoD8AYG0yQSM+Do10Td87RlStxCgxpMK6R3TsRkxcFABEBAAG0" + "OlVNTEFVVFNUQVJUOsOEw6TDlsO2w5zDvMOfOlVNTEFURU5ERSA8YXNkbGFrc2Rs" + "QGFrc2RqLmNvbT6IuAQTAQIAIgUCTdvOgQIbAwYLCQgHAwIGFQgCCQoLBBYCAwEC" + "HgECF4AACgkQP8kDwm8AOFiArAP/ZXrlZJB1jFEjyBb04ckpE6F/aJuSYIXf0Yx5" + "T2eS+lA69vYuqKRC1qNROBrAn/WGNOQBFNEgGoy3F3gV5NgpIphnyIEZdZWGY2rv" + "yjunKWlioZjWc/xbSbvpvJ3Q8RyfDXBOkDEB6uF1ksimw2eJSOUTkF9AQfS5f4rT" + "5gs013G4jQRN286BAQQApVbjd8UhsQLB4TpeKn9+dDXAfikGgxDOb19XisjRiWxA" + "+bKFxu5tRt6fxXl6BGSGT7DhoVbNkcJGVQFYcbR31UGKCVYcWSL3yfz+PiVuf1UB" + "Rp44cXxxqxrLqKp1rk3dGvV4Ayy8lkk3ncDGPez6lIKvj3832yVtAzUOX1QOg9EA" + "EQEAAYifBBgBAgAJBQJN286BAhsMAAoJED/JA8JvADhYQ80D/R3TX0FBMHs/xqEh" + "tiS86XP/8pW6eMm2eaAYINxoDY3jmDMv2HFQ+YgrYXgqGr6eVGqDMNPj4W8VBoOt" + "iYW7+SWY76AAl+gmWIMm2jbN8bZXFk4jmIxpycHCrtoXX8rUk/0+se8NvbmAdMGK" + "POOoD7oxdRmJSU5hSspOCHrCwCa3"); public void test1() throws Exception { PGPPublicKeyRingCollection pubRings = new PGPPublicKeyRingCollection(pub1); int count = 0; Iterator rIt = pubRings.getKeyRings(); while (rIt.hasNext()) { PGPPublicKeyRing pgpPub = (PGPPublicKeyRing)rIt.next(); count++; int keyCount = 0; byte[] bytes = pgpPub.getEncoded(); pgpPub = new PGPPublicKeyRing(bytes, new BcKeyFingerprintCalculator()); Iterator it = pgpPub.getPublicKeys(); while (it.hasNext()) { keyCount++; PGPPublicKey pubKey = (PGPPublicKey)it.next(); Iterator sIt = pubKey.getSignatures(); while (sIt.hasNext()) { ((PGPSignature)sIt.next()).getSignatureType(); } } if (keyCount != 2) { fail("wrong number of public keys"); } } if (count != 1) { fail("wrong number of public keyrings"); } // // exact match // rIt = pubRings.getKeyRings("test (Test key) "); count = 0; while (rIt.hasNext()) { count++; rIt.next(); } if (count != 1) { fail("wrong number of public keyrings on exact match"); } // // partial match 1 expected // rIt = pubRings.getKeyRings("test", true); count = 0; while (rIt.hasNext()) { count++; rIt.next(); } if (count != 1) { fail("wrong number of public keyrings on partial match 1"); } // // partial match 0 expected // rIt = pubRings.getKeyRings("XXX", true); count = 0; while (rIt.hasNext()) { count++; rIt.next(); } if (count != 0) { fail("wrong number of public keyrings on partial match 0"); } // // case-insensitive partial match // rIt = pubRings.getKeyRings("TEST@ubicall.com", true, true); count = 0; while (rIt.hasNext()) { count++; rIt.next(); } if (count != 1) { fail("wrong number of public keyrings on case-insensitive partial match"); } PGPSecretKeyRingCollection secretRings = new PGPSecretKeyRingCollection(sec1); rIt = secretRings.getKeyRings(); count = 0; while (rIt.hasNext()) { PGPSecretKeyRing pgpSec = (PGPSecretKeyRing)rIt.next(); count++; int keyCount = 0; byte[] bytes = pgpSec.getEncoded(); pgpSec = new PGPSecretKeyRing(bytes, new BcKeyFingerprintCalculator()); Iterator it = pgpSec.getSecretKeys(); while (it.hasNext()) { keyCount++; PGPSecretKey k = (PGPSecretKey)it.next(); PGPPublicKey pk = k.getPublicKey(); pk.getSignatures(); byte[] pkBytes = pk.getEncoded(); PGPPublicKeyRing pkR = new PGPPublicKeyRing(pkBytes, new BcKeyFingerprintCalculator()); } if (keyCount != 2) { fail("wrong number of secret keys"); } } if (count != 1) { fail("wrong number of secret keyrings"); } // // exact match // rIt = secretRings.getKeyRings("test (Test key) "); count = 0; while (rIt.hasNext()) { count++; rIt.next(); } if (count != 1) { fail("wrong number of secret keyrings on exact match"); } // // partial match 1 expected // rIt = secretRings.getKeyRings("test", true); count = 0; while (rIt.hasNext()) { count++; rIt.next(); } if (count != 1) { fail("wrong number of secret keyrings on partial match 1"); } // // exact match 0 expected // rIt = secretRings.getKeyRings("test", false); count = 0; while (rIt.hasNext()) { count++; rIt.next(); } if (count != 0) { fail("wrong number of secret keyrings on partial match 0"); } // // case-insensitive partial match // rIt = secretRings.getKeyRings("TEST@ubicall.com", true, true); count = 0; while (rIt.hasNext()) { count++; rIt.next(); } if (count != 1) { fail("wrong number of secret keyrings on case-insensitive partial match"); } } public void test2() throws Exception { PGPPublicKeyRingCollection pubRings = new PGPPublicKeyRingCollection(pub2); int count = 0; byte[] encRing = pubRings.getEncoded(); pubRings = new PGPPublicKeyRingCollection(encRing); Iterator rIt = pubRings.getKeyRings(); while (rIt.hasNext()) { PGPPublicKeyRing pgpPub = (PGPPublicKeyRing)rIt.next(); count++; int keyCount = 0; byte[] bytes = pgpPub.getEncoded(); pgpPub = new PGPPublicKeyRing(bytes, new BcKeyFingerprintCalculator()); Iterator it = pgpPub.getPublicKeys(); while (it.hasNext()) { PGPPublicKey pk = (PGPPublicKey)it.next(); byte[] pkBytes = pk.getEncoded(); PGPPublicKeyRing pkR = new PGPPublicKeyRing(pkBytes, new BcKeyFingerprintCalculator()); keyCount++; } if (keyCount != 2) { fail("wrong number of public keys"); } } if (count != 2) { fail("wrong number of public keyrings"); } PGPSecretKeyRingCollection secretRings = new PGPSecretKeyRingCollection(sec2); rIt = secretRings.getKeyRings(); count = 0; encRing = secretRings.getEncoded(); secretRings = new PGPSecretKeyRingCollection(encRing); while (rIt.hasNext()) { PGPSecretKeyRing pgpSec = (PGPSecretKeyRing)rIt.next(); count++; int keyCount = 0; byte[] bytes = pgpSec.getEncoded(); pgpSec = new PGPSecretKeyRing(bytes, new BcKeyFingerprintCalculator()); Iterator it = pgpSec.getSecretKeys(); while (it.hasNext()) { keyCount++; PGPSecretKey k = (PGPSecretKey)it.next(); PGPPublicKey pk = k.getPublicKey(); if (pk.getKeyID() == -1413891222336124627L) { int sCount = 0; Iterator sIt = pk.getSignaturesOfType(PGPSignature.SUBKEY_BINDING); while (sIt.hasNext()) { int type = ((PGPSignature)sIt.next()).getSignatureType(); if (type != PGPSignature.SUBKEY_BINDING) { fail("failed to return correct signature type"); } sCount++; } if (sCount != 1) { fail("failed to find binding signature"); } } pk.getSignatures(); if (k.getKeyID() == -4049084404703773049L || k.getKeyID() == -1413891222336124627L) { k.extractPrivateKey(new BcPBESecretKeyDecryptorBuilder(new BcPGPDigestCalculatorProvider()).build(sec2pass1)); } else if (k.getKeyID() == -6498553574938125416L || k.getKeyID() == 59034765524361024L) { k.extractPrivateKey(new BcPBESecretKeyDecryptorBuilder(new BcPGPDigestCalculatorProvider()).build(sec2pass2)); } } if (keyCount != 2) { fail("wrong number of secret keys"); } } if (count != 2) { fail("wrong number of secret keyrings"); } } public void test3() throws Exception { PGPPublicKeyRingCollection pubRings = new PGPPublicKeyRingCollection(pub3); int count = 0; byte[] encRing = pubRings.getEncoded(); pubRings = new PGPPublicKeyRingCollection(encRing); Iterator rIt = pubRings.getKeyRings(); while (rIt.hasNext()) { PGPPublicKeyRing pgpPub = (PGPPublicKeyRing)rIt.next(); count++; int keyCount = 0; byte[] bytes = pgpPub.getEncoded(); pgpPub = new PGPPublicKeyRing(bytes, new BcKeyFingerprintCalculator()); Iterator it = pgpPub.getPublicKeys(); while (it.hasNext()) { keyCount++; PGPPublicKey pubK = (PGPPublicKey)it.next(); pubK.getSignatures(); } if (keyCount != 2) { fail("wrong number of public keys"); } } if (count != 1) { fail("wrong number of public keyrings"); } PGPSecretKeyRingCollection secretRings = new PGPSecretKeyRingCollection(sec3); rIt = secretRings.getKeyRings(); count = 0; encRing = secretRings.getEncoded(); secretRings = new PGPSecretKeyRingCollection(encRing); while (rIt.hasNext()) { PGPSecretKeyRing pgpSec = (PGPSecretKeyRing)rIt.next(); count++; int keyCount = 0; byte[] bytes = pgpSec.getEncoded(); pgpSec = new PGPSecretKeyRing(bytes, new BcKeyFingerprintCalculator()); Iterator it = pgpSec.getSecretKeys(); while (it.hasNext()) { keyCount++; PGPSecretKey k = (PGPSecretKey)it.next(); k.extractPrivateKey(new BcPBESecretKeyDecryptorBuilder(new BcPGPDigestCalculatorProvider()).build(sec3pass1)); } if (keyCount != 2) { fail("wrong number of secret keys"); } } if (count != 1) { fail("wrong number of secret keyrings"); } } public void test4() throws Exception { PGPSecretKeyRingCollection secretRings = new PGPSecretKeyRingCollection(sec4); Iterator rIt = secretRings.getKeyRings(); int count = 0; byte[] encRing = secretRings.getEncoded(); secretRings = new PGPSecretKeyRingCollection(encRing); while (rIt.hasNext()) { PGPSecretKeyRing pgpSec = (PGPSecretKeyRing)rIt.next(); count++; int keyCount = 0; byte[] bytes = pgpSec.getEncoded(); pgpSec = new PGPSecretKeyRing(bytes, new BcKeyFingerprintCalculator()); Iterator it = pgpSec.getSecretKeys(); while (it.hasNext()) { keyCount++; PGPSecretKey k = (PGPSecretKey)it.next(); k.extractPrivateKey(new BcPBESecretKeyDecryptorBuilder(new BcPGPDigestCalculatorProvider()).build(sec3pass1)); } if (keyCount != 2) { fail("wrong number of secret keys"); } } if (count != 1) { fail("wrong number of secret keyrings"); } } public void test5() throws Exception { PGPPublicKeyRingCollection pubRings = new PGPPublicKeyRingCollection(pub5); int count = 0; byte[] encRing = pubRings.getEncoded(); pubRings = new PGPPublicKeyRingCollection(encRing); Iterator rIt = pubRings.getKeyRings(); while (rIt.hasNext()) { PGPPublicKeyRing pgpPub = (PGPPublicKeyRing)rIt.next(); count++; int keyCount = 0; byte[] bytes = pgpPub.getEncoded(); pgpPub = new PGPPublicKeyRing(bytes, new BcKeyFingerprintCalculator()); Iterator it = pgpPub.getPublicKeys(); while (it.hasNext()) { keyCount++; it.next(); } if (keyCount != 2) { fail("wrong number of public keys"); } } if (count != 1) { fail("wrong number of public keyrings"); } if (noIDEA()) { return; } PGPSecretKeyRingCollection secretRings = new PGPSecretKeyRingCollection(sec5); rIt = secretRings.getKeyRings(); count = 0; encRing = secretRings.getEncoded(); secretRings = new PGPSecretKeyRingCollection(encRing); while (rIt.hasNext()) { PGPSecretKeyRing pgpSec = (PGPSecretKeyRing)rIt.next(); count++; int keyCount = 0; byte[] bytes = pgpSec.getEncoded(); pgpSec = new PGPSecretKeyRing(bytes, new BcKeyFingerprintCalculator()); Iterator it = pgpSec.getSecretKeys(); while (it.hasNext()) { keyCount++; PGPSecretKey k = (PGPSecretKey)it.next(); k.extractPrivateKey(new BcPBESecretKeyDecryptorBuilder(new BcPGPDigestCalculatorProvider()).build(sec5pass1)); } if (keyCount != 2) { fail("wrong number of secret keys"); } } if (count != 1) { fail("wrong number of secret keyrings"); } } private boolean noIDEA() { return true; } public void test6() throws Exception { PGPPublicKeyRingCollection pubRings = new PGPPublicKeyRingCollection(pub6); Iterator rIt = pubRings.getKeyRings(); while (rIt.hasNext()) { PGPPublicKeyRing pgpPub = (PGPPublicKeyRing)rIt.next(); Iterator it = pgpPub.getPublicKeys(); while (it.hasNext()) { PGPPublicKey k = (PGPPublicKey)it.next(); if (k.getKeyID() == 0x5ce086b5b5a18ff4L) { int count = 0; Iterator sIt = k.getSignaturesOfType(PGPSignature.SUBKEY_REVOCATION); while (sIt.hasNext()) { PGPSignature sig = (PGPSignature)sIt.next(); count++; } if (count != 1) { fail("wrong number of revocations in test6."); } } } } byte[] encRing = pubRings.getEncoded(); } public void test7() throws Exception { PGPPublicKeyRing pgpPub = new PGPPublicKeyRing(pub7, new BcKeyFingerprintCalculator()); Iterator it = pgpPub.getPublicKeys(); PGPPublicKey masterKey = null; while (it.hasNext()) { PGPPublicKey k = (PGPPublicKey)it.next(); if (k.isMasterKey()) { masterKey = k; continue; } int count = 0; PGPSignature sig = null; Iterator sIt = k.getSignaturesOfType(PGPSignature.SUBKEY_REVOCATION); while (sIt.hasNext()) { sig = (PGPSignature)sIt.next(); count++; } if (count != 1) { fail("wrong number of revocations in test7."); } sig.init(new BcPGPContentVerifierBuilderProvider(), masterKey); if (!sig.verifyCertification(k)) { fail("failed to verify revocation certification"); } } } public void test8() throws Exception { PGPPublicKeyRingCollection pubRings = new PGPPublicKeyRingCollection(pub8); int count = 0; byte[] encRing = pubRings.getEncoded(); pubRings = new PGPPublicKeyRingCollection(encRing); Iterator rIt = pubRings.getKeyRings(); while (rIt.hasNext()) { PGPPublicKeyRing pgpPub = (PGPPublicKeyRing)rIt.next(); count++; int keyCount = 0; byte[] bytes = pgpPub.getEncoded(); pgpPub = new PGPPublicKeyRing(bytes, new BcKeyFingerprintCalculator()); Iterator it = pgpPub.getPublicKeys(); while (it.hasNext()) { keyCount++; it.next(); } if (keyCount != 2) { fail("wrong number of public keys"); } } if (count != 2) { fail("wrong number of public keyrings"); } PGPSecretKeyRingCollection secretRings = new PGPSecretKeyRingCollection(sec8); rIt = secretRings.getKeyRings(); count = 0; encRing = secretRings.getEncoded(); secretRings = new PGPSecretKeyRingCollection(encRing); while (rIt.hasNext()) { PGPSecretKeyRing pgpSec = (PGPSecretKeyRing)rIt.next(); count++; int keyCount = 0; byte[] bytes = pgpSec.getEncoded(); pgpSec = new PGPSecretKeyRing(bytes, new BcKeyFingerprintCalculator()); Iterator it = pgpSec.getSecretKeys(); while (it.hasNext()) { keyCount++; PGPSecretKey k = (PGPSecretKey)it.next(); k.extractPrivateKey(new BcPBESecretKeyDecryptorBuilder(new BcPGPDigestCalculatorProvider()).build(sec8pass)); } if (keyCount != 2) { fail("wrong number of secret keys"); } } if (count != 1) { fail("wrong number of secret keyrings"); } } public void test9() throws Exception { PGPSecretKeyRingCollection secretRings = new PGPSecretKeyRingCollection(sec9); Iterator rIt = secretRings.getKeyRings(); int count = 0; byte[] encRing = secretRings.getEncoded(); secretRings = new PGPSecretKeyRingCollection(encRing); while (rIt.hasNext()) { PGPSecretKeyRing pgpSec = (PGPSecretKeyRing)rIt.next(); count++; int keyCount = 0; byte[] bytes = pgpSec.getEncoded(); pgpSec = new PGPSecretKeyRing(bytes, new BcKeyFingerprintCalculator()); Iterator it = pgpSec.getSecretKeys(); while (it.hasNext()) { keyCount++; PGPSecretKey k = (PGPSecretKey)it.next(); PGPPrivateKey pKey = k.extractPrivateKey(new BcPBESecretKeyDecryptorBuilder(new BcPGPDigestCalculatorProvider()).build(sec9pass)); if (keyCount == 1 && pKey != null) { fail("primary secret key found, null expected"); } } if (keyCount != 3) { fail("wrong number of secret keys"); } } if (count != 1) { fail("wrong number of secret keyrings"); } } public void test10() throws Exception { PGPSecretKeyRing secretRing = new PGPSecretKeyRing(sec10, new BcKeyFingerprintCalculator()); Iterator secretKeys = secretRing.getSecretKeys(); while (secretKeys.hasNext()) { PGPPublicKey pubKey = ((PGPSecretKey)secretKeys.next()).getPublicKey(); if (pubKey.getValidDays() != 28) { fail("days wrong on secret key ring"); } if (pubKey.getValidSeconds() != 28 * 24 * 60 * 60) { fail("seconds wrong on secret key ring"); } } PGPPublicKeyRing publicRing = new PGPPublicKeyRing(pub10, new BcKeyFingerprintCalculator()); Iterator publicKeys = publicRing.getPublicKeys(); while (publicKeys.hasNext()) { PGPPublicKey pubKey = (PGPPublicKey)publicKeys.next(); if (pubKey.getValidDays() != 28) { fail("days wrong on public key ring"); } if (pubKey.getValidSeconds() != 28 * 24 * 60 * 60) { fail("seconds wrong on public key ring"); } } } public void generateTest() throws Exception { char[] passPhrase = "hello".toCharArray(); DSAParametersGenerator dsaPGen = new DSAParametersGenerator(); dsaPGen.init(512, 10, new SecureRandom()); DSAKeyPairGenerator dsaKpg = new DSAKeyPairGenerator(); dsaKpg.init(new DSAKeyGenerationParameters(new SecureRandom(), dsaPGen.generateParameters())); // // this takes a while as the key generator has to generate some DSA params // before it generates the key. // AsymmetricCipherKeyPair dsaKp = dsaKpg.generateKeyPair(); ElGamalKeyPairGenerator elgKpg = new ElGamalKeyPairGenerator(); BigInteger g = new BigInteger("153d5d6172adb43045b68ae8e1de1070b6137005686d29d3d73a7749199681ee5b212c9b96bfdcfa5b20cd5e3fd2044895d609cf9b410b7a0f12ca1cb9a428cc", 16); BigInteger p = new BigInteger("9494fec095f3b85ee286542b3836fc81a5dd0a0349b4c239dd38744d488cf8e31db8bcb7d33b41abb9e5a33cca9144b1cef332c94bf0573bf047a3aca98cdf3b", 16); ElGamalParameters elParams = new ElGamalParameters(p, g); elgKpg.init(new ElGamalKeyGenerationParameters(new SecureRandom(), elParams)); // // this is quicker because we are using pregenerated parameters. // AsymmetricCipherKeyPair elgKp = elgKpg.generateKeyPair(); PGPKeyPair dsaKeyPair = new BcPGPKeyPair(PGPPublicKey.DSA, dsaKp, new Date()); PGPKeyPair elgKeyPair = new BcPGPKeyPair(PGPPublicKey.ELGAMAL_ENCRYPT, elgKp, new Date()); PGPKeyRingGenerator keyRingGen = new PGPKeyRingGenerator(PGPSignature.POSITIVE_CERTIFICATION, dsaKeyPair, "test", null, null, null, new BcPGPContentSignerBuilder(PGPPublicKey.DSA, HashAlgorithmTags.SHA1), new BcPBESecretKeyEncryptorBuilder(PGPEncryptedData.AES_256).build(passPhrase)); keyRingGen.addSubKey(elgKeyPair); PGPSecretKeyRing keyRing = keyRingGen.generateSecretKeyRing(); keyRing.getSecretKey().extractPrivateKey(new BcPBESecretKeyDecryptorBuilder(new BcPGPDigestCalculatorProvider()).build(passPhrase)); PGPPublicKeyRing pubRing = keyRingGen.generatePublicKeyRing(); PGPPublicKey vKey = null; PGPPublicKey sKey = null; Iterator it = pubRing.getPublicKeys(); while (it.hasNext()) { PGPPublicKey pk = (PGPPublicKey)it.next(); if (pk.isMasterKey()) { vKey = pk; } else { sKey = pk; } } Iterator sIt = sKey.getSignatures(); while (sIt.hasNext()) { PGPSignature sig = (PGPSignature)sIt.next(); if (sig.getKeyID() == vKey.getKeyID() && sig.getSignatureType() == PGPSignature.SUBKEY_BINDING) { sig.init(new BcPGPContentVerifierBuilderProvider(), vKey); if (!sig.verifyCertification(vKey, sKey)) { fail("failed to verify sub-key signature."); } } } } private void insertMasterTest() throws Exception { char[] passPhrase = "hello".toCharArray(); RSAKeyPairGenerator rsaKpg = new RSAKeyPairGenerator(); rsaKpg.init(new RSAKeyGenerationParameters(BigInteger.valueOf(0x11), new SecureRandom(), 512, 25)); // // this is quicker because we are using pregenerated parameters. // AsymmetricCipherKeyPair rsaKp = rsaKpg.generateKeyPair(); PGPKeyPair rsaKeyPair1 = new BcPGPKeyPair(PGPPublicKey.RSA_GENERAL, rsaKp, new Date()); rsaKp = rsaKpg.generateKeyPair(); PGPKeyPair rsaKeyPair2 = new BcPGPKeyPair(PGPPublicKey.RSA_GENERAL, rsaKp, new Date()); PGPDigestCalculator chkSumCalc = new BcPGPDigestCalculatorProvider().get(HashAlgorithmTags.SHA1); PGPKeyRingGenerator keyRingGen = new PGPKeyRingGenerator(PGPSignature.POSITIVE_CERTIFICATION, rsaKeyPair1, "test", chkSumCalc, null, null, new BcPGPContentSignerBuilder(PGPPublicKey.RSA_GENERAL, HashAlgorithmTags.SHA1), new BcPBESecretKeyEncryptorBuilder(PGPEncryptedData.AES_256).build(passPhrase)); PGPSecretKeyRing secRing1 = keyRingGen.generateSecretKeyRing(); PGPPublicKeyRing pubRing1 = keyRingGen.generatePublicKeyRing(); keyRingGen = new PGPKeyRingGenerator(PGPSignature.POSITIVE_CERTIFICATION, rsaKeyPair2, "test", chkSumCalc, null, null, new BcPGPContentSignerBuilder(PGPPublicKey.RSA_GENERAL, HashAlgorithmTags.SHA1), new BcPBESecretKeyEncryptorBuilder(PGPEncryptedData.AES_256).build(passPhrase)); PGPSecretKeyRing secRing2 = keyRingGen.generateSecretKeyRing(); PGPPublicKeyRing pubRing2 = keyRingGen.generatePublicKeyRing(); try { PGPPublicKeyRing.insertPublicKey(pubRing1, pubRing2.getPublicKey()); fail("adding second master key (public) should throw an IllegalArgumentException"); } catch (IllegalArgumentException e) { if (!e.getMessage().equals("cannot add a master key to a ring that already has one")) { fail("wrong message in public test"); } } try { PGPSecretKeyRing.insertSecretKey(secRing1, secRing2.getSecretKey()); fail("adding second master key (secret) should throw an IllegalArgumentException"); } catch (IllegalArgumentException e) { if (!e.getMessage().equals("cannot add a master key to a ring that already has one")) { fail("wrong message in secret test"); } } } public void generateSha1Test() throws Exception { char[] passPhrase = "hello".toCharArray(); DSAParametersGenerator dsaPGen = new DSAParametersGenerator(); dsaPGen.init(512, 10, new SecureRandom()); DSAKeyPairGenerator dsaKpg = new DSAKeyPairGenerator(); dsaKpg.init(new DSAKeyGenerationParameters(new SecureRandom(), dsaPGen.generateParameters())); // // this takes a while as the key generator has to generate some DSA params // before it generates the key. // AsymmetricCipherKeyPair dsaKp = dsaKpg.generateKeyPair(); ElGamalKeyPairGenerator elgKpg = new ElGamalKeyPairGenerator(); BigInteger g = new BigInteger("153d5d6172adb43045b68ae8e1de1070b6137005686d29d3d73a7749199681ee5b212c9b96bfdcfa5b20cd5e3fd2044895d609cf9b410b7a0f12ca1cb9a428cc", 16); BigInteger p = new BigInteger("9494fec095f3b85ee286542b3836fc81a5dd0a0349b4c239dd38744d488cf8e31db8bcb7d33b41abb9e5a33cca9144b1cef332c94bf0573bf047a3aca98cdf3b", 16); ElGamalParameters elParams = new ElGamalParameters(p, g); elgKpg.init(new ElGamalKeyGenerationParameters(new SecureRandom(), elParams)); // // this is quicker because we are using pregenerated parameters. // AsymmetricCipherKeyPair elgKp = elgKpg.generateKeyPair(); PGPKeyPair dsaKeyPair = new BcPGPKeyPair(PGPPublicKey.DSA, dsaKp, new Date()); PGPKeyPair elgKeyPair = new BcPGPKeyPair(PGPPublicKey.ELGAMAL_ENCRYPT, elgKp, new Date()); PGPDigestCalculator chkSumCalc = new BcPGPDigestCalculatorProvider().get(HashAlgorithmTags.SHA1); PGPKeyRingGenerator keyRingGen = new PGPKeyRingGenerator(PGPSignature.POSITIVE_CERTIFICATION, dsaKeyPair, "test", chkSumCalc, null, null, new BcPGPContentSignerBuilder(PGPPublicKey.DSA, HashAlgorithmTags.SHA1), new BcPBESecretKeyEncryptorBuilder(PGPEncryptedData.AES_256).build(passPhrase)); keyRingGen.addSubKey(elgKeyPair); PGPSecretKeyRing keyRing = keyRingGen.generateSecretKeyRing(); keyRing.getSecretKey().extractPrivateKey(new BcPBESecretKeyDecryptorBuilder(new BcPGPDigestCalculatorProvider()).build(passPhrase)); PGPPublicKeyRing pubRing = keyRingGen.generatePublicKeyRing(); PGPPublicKey vKey = null; PGPPublicKey sKey = null; Iterator it = pubRing.getPublicKeys(); while (it.hasNext()) { PGPPublicKey pk = (PGPPublicKey)it.next(); if (pk.isMasterKey()) { vKey = pk; } else { sKey = pk; } } Iterator sIt = sKey.getSignatures(); while (sIt.hasNext()) { PGPSignature sig = (PGPSignature)sIt.next(); if (sig.getKeyID() == vKey.getKeyID() && sig.getSignatureType() == PGPSignature.SUBKEY_BINDING) { sig.init(new BcPGPContentVerifierBuilderProvider(), vKey); if (!sig.verifyCertification(vKey, sKey)) { fail("failed to verify sub-key signature."); } } } } private void test11() throws Exception { PGPPublicKeyRing pubRing = new PGPPublicKeyRing(subKeyBindingKey, new BcKeyFingerprintCalculator()); Iterator it = pubRing.getPublicKeys(); while (it.hasNext()) { PGPPublicKey key = (PGPPublicKey)it.next(); if (key.getValidSeconds() != 0) { fail("expiration time non-zero"); } } } private void rewrapTest() throws Exception { SecureRandom rand = new SecureRandom(); // Read the secret key rings PGPSecretKeyRingCollection privRings = new PGPSecretKeyRingCollection( new ByteArrayInputStream(rewrapKey)); Iterator rIt = privRings.getKeyRings(); if (rIt.hasNext()) { PGPSecretKeyRing pgpPriv = (PGPSecretKeyRing)rIt.next(); Iterator it = pgpPriv.getSecretKeys(); while (it.hasNext()) { PGPSecretKey pgpKey = (PGPSecretKey)it.next(); // re-encrypt the key with an empty password pgpPriv = PGPSecretKeyRing.removeSecretKey(pgpPriv, pgpKey); pgpKey = PGPSecretKey.copyWithNewPassword( pgpKey, new BcPBESecretKeyDecryptorBuilder(new BcPGPDigestCalculatorProvider()).build(rewrapPass), null); pgpPriv = PGPSecretKeyRing.insertSecretKey(pgpPriv, pgpKey); // this should succeed PGPPrivateKey privTmp = pgpKey.extractPrivateKey(null); } } } private void testPublicKeyRingWithX509() throws Exception { checkPublicKeyRingWithX509(pubWithX509); PGPPublicKeyRing pubRing = new PGPPublicKeyRing(pubWithX509, new BcKeyFingerprintCalculator()); checkPublicKeyRingWithX509(pubRing.getEncoded()); } private void testSecretKeyRingWithPersonalCertificate() throws Exception { checkSecretKeyRingWithPersonalCertificate(secWithPersonalCertificate); PGPSecretKeyRingCollection secRing = new PGPSecretKeyRingCollection(secWithPersonalCertificate); checkSecretKeyRingWithPersonalCertificate(secRing.getEncoded()); } private void testUmlaut() throws Exception { PGPPublicKeyRing pubRing = new PGPPublicKeyRing(umlautKeySig, new BcKeyFingerprintCalculator()); PGPPublicKey pub = pubRing.getPublicKey(); String userID = (String)pub.getUserIDs().next(); for (Iterator it = pub.getSignatures(); it.hasNext();) { PGPSignature sig = (PGPSignature)it.next(); if (sig.getSignatureType() == PGPSignature.POSITIVE_CERTIFICATION) { sig.init(new BcPGPContentVerifierBuilderProvider(), pub); if (!sig.verifyCertification(userID, pub)) { fail("failed UTF8 userID test"); } } } // // this is quicker because we are using pregenerated parameters. // RSAKeyPairGenerator rsaKpg = new RSAKeyPairGenerator(); rsaKpg.init(new RSAKeyGenerationParameters(BigInteger.valueOf(0x11), new SecureRandom(), 512, 25)); AsymmetricCipherKeyPair rsaKp = rsaKpg.generateKeyPair(); PGPKeyPair rsaKeyPair1 = new BcPGPKeyPair(PGPPublicKey.RSA_GENERAL, rsaKp, new Date()); rsaKp = rsaKpg.generateKeyPair(); char[] passPhrase = "passwd".toCharArray(); PGPKeyRingGenerator keyRingGen = new PGPKeyRingGenerator(PGPSignature.POSITIVE_CERTIFICATION, rsaKeyPair1, userID, null, null, null, new BcPGPContentSignerBuilder(PGPPublicKey.RSA_GENERAL, HashAlgorithmTags.SHA1), new BcPBESecretKeyEncryptorBuilder(PGPEncryptedData.AES_256).build(passPhrase)); PGPPublicKeyRing pubRing1 = keyRingGen.generatePublicKeyRing(); pub = pubRing1.getPublicKey(); for (Iterator it = pub.getSignatures(); it.hasNext();) { PGPSignature sig = (PGPSignature)it.next(); if (sig.getSignatureType() == PGPSignature.POSITIVE_CERTIFICATION) { sig.init(new BcPGPContentVerifierBuilderProvider(), pub); if (!sig.verifyCertification(userID, pub)) { fail("failed UTF8 userID creation test"); } } } } private void checkSecretKeyRingWithPersonalCertificate(byte[] keyRing) throws Exception { PGPSecretKeyRingCollection secCol = new PGPSecretKeyRingCollection(keyRing); int count = 0; for (Iterator rIt = secCol.getKeyRings(); rIt.hasNext();) { PGPSecretKeyRing ring = (PGPSecretKeyRing)rIt.next(); for (Iterator it = ring.getExtraPublicKeys(); it.hasNext();) { it.next(); count++; } } if (count != 1) { fail("personal certificate data subkey not found - count = " + count); } } private void checkPublicKeyRingWithX509(byte[] keyRing) throws Exception { PGPPublicKeyRing pubRing = new PGPPublicKeyRing(keyRing, new BcKeyFingerprintCalculator()); Iterator it = pubRing.getPublicKeys(); if (it.hasNext()) { PGPPublicKey key = (PGPPublicKey)it.next(); Iterator sIt = key.getSignatures(); if (sIt.hasNext()) { PGPSignature sig = (PGPSignature)sIt.next(); if (sig.getKeyAlgorithm() != 100) { fail("experimental signature not found"); } if (!areEqual(sig.getSignature(), Hex.decode("000101"))) { fail("experimental encoding check failed"); } } else { fail("no signature found"); } } else { fail("no key found"); } } public void performTest() throws Exception { try { test1(); test2(); test3(); test4(); test5(); test6(); // test7(); test8(); test9(); test10(); test11(); generateTest(); generateSha1Test(); rewrapTest(); testPublicKeyRingWithX509(); testSecretKeyRingWithPersonalCertificate(); insertMasterTest(); testUmlaut(); } catch (PGPException e) { if (e.getUnderlyingException() != null) { Exception ex = e.getUnderlyingException(); fail("exception: " + ex, ex); } else { fail("exception: " + e, e); } } } public String getName() { return "PGPKeyRingTest"; } public static void main( String[] args) { runTest(new BcPGPKeyRingTest()); } } bouncycastle-1.49.orig/j2me/org/bouncycastle/openpgp/test/RegressionTest.java0000644000175000017500000000134611732234343027030 0ustar ebourgebourgpackage org.bouncycastle.openpgp.test; import org.bouncycastle.util.test.Test; import org.bouncycastle.util.test.TestResult; public class RegressionTest { public static Test[] tests = { new BcPGPDSAElGamalTest(), new BcPGPDSATest(), new BcPGPKeyRingTest(), new BcPGPPBETest(), new BcPGPRSATest() }; public static void main( String[] args) { for (int i = 0; i != tests.length; i++) { TestResult result = tests[i].perform(); if (result.getException() != null) { result.getException().printStackTrace(); } System.out.println(result); } } } bouncycastle-1.49.orig/j2me/org/bouncycastle/openpgp/PGPSignatureGenerator.java0000644000175000017500000003277511731771171027266 0ustar ebourgebourgpackage org.bouncycastle.openpgp; import java.io.ByteArrayOutputStream; import java.io.IOException; import java.io.OutputStream; import java.math.BigInteger; import java.security.SecureRandom; import java.util.Date; import org.bouncycastle.bcpg.MPInteger; import org.bouncycastle.bcpg.OnePassSignaturePacket; import org.bouncycastle.bcpg.PublicKeyAlgorithmTags; import org.bouncycastle.bcpg.SignaturePacket; import org.bouncycastle.bcpg.SignatureSubpacket; import org.bouncycastle.bcpg.SignatureSubpacketTags; import org.bouncycastle.bcpg.UserAttributeSubpacket; import org.bouncycastle.bcpg.sig.IssuerKeyID; import org.bouncycastle.bcpg.sig.SignatureCreationTime; import org.bouncycastle.openpgp.operator.PGPContentSigner; import org.bouncycastle.openpgp.operator.PGPContentSignerBuilder; import org.bouncycastle.util.Strings; /** * Generator for PGP Signatures. */ public class PGPSignatureGenerator { private SignatureSubpacket[] unhashed = new SignatureSubpacket[0]; private SignatureSubpacket[] hashed = new SignatureSubpacket[0]; private OutputStream sigOut; private PGPContentSignerBuilder contentSignerBuilder; private PGPContentSigner contentSigner; private int sigType; private byte lastb; private int providedKeyAlgorithm = -1; /** * Create a signature generator built on the passed in contentSignerBuilder. * * @param contentSignerBuilder builder to produce PGPContentSigner objects for generating signatures. */ public PGPSignatureGenerator( PGPContentSignerBuilder contentSignerBuilder) { this.contentSignerBuilder = contentSignerBuilder; } /** * Initialise the generator for signing. * * @param signatureType * @param key * @throws PGPException * @deprecated use init() method */ public void initSign( int signatureType, PGPPrivateKey key) throws PGPException { contentSigner = contentSignerBuilder.build(signatureType, key); sigOut = contentSigner.getOutputStream(); sigType = contentSigner.getType(); lastb = 0; if (providedKeyAlgorithm >= 0 && providedKeyAlgorithm != contentSigner.getKeyAlgorithm()) { throw new PGPException("key algorithm mismatch"); } } /** * Initialise the generator for signing. * * @param signatureType * @param key * @throws PGPException */ public void init( int signatureType, PGPPrivateKey key) throws PGPException { contentSigner = contentSignerBuilder.build(signatureType, key); sigOut = contentSigner.getOutputStream(); sigType = contentSigner.getType(); lastb = 0; if (providedKeyAlgorithm >= 0 && providedKeyAlgorithm != contentSigner.getKeyAlgorithm()) { throw new PGPException("key algorithm mismatch"); } } /** * Initialise the generator for signing. * * @param signatureType * @param key * @param random * @throws PGPException * @deprecated random parameter now ignored. */ public void initSign( int signatureType, PGPPrivateKey key, SecureRandom random) throws PGPException { initSign(signatureType, key); } public void update( byte b) throws PGPSignatureException { if (sigType == PGPSignature.CANONICAL_TEXT_DOCUMENT) { if (b == '\r') { byteUpdate((byte)'\r'); byteUpdate((byte)'\n'); } else if (b == '\n') { if (lastb != '\r') { byteUpdate((byte)'\r'); byteUpdate((byte)'\n'); } } else { byteUpdate(b); } lastb = b; } else { byteUpdate(b); } } public void update( byte[] b) throws PGPSignatureException { this.update(b, 0, b.length); } public void update( byte[] b, int off, int len) throws PGPSignatureException { if (sigType == PGPSignature.CANONICAL_TEXT_DOCUMENT) { int finish = off + len; for (int i = off; i != finish; i++) { this.update(b[i]); } } else { blockUpdate(b, off, len); } } private void byteUpdate(byte b) throws PGPSignatureException { try { sigOut.write(b); } catch (IOException e) { throw new PGPSignatureException(e.getMessage(), e); } } private void blockUpdate(byte[] block, int off, int len) throws PGPSignatureException { try { sigOut.write(block, off, len); } catch (IOException e) { throw new PGPSignatureException(e.getMessage(), e); } } public void setHashedSubpackets( PGPSignatureSubpacketVector hashedPcks) { if (hashedPcks == null) { hashed = new SignatureSubpacket[0]; return; } hashed = hashedPcks.toSubpacketArray(); } public void setUnhashedSubpackets( PGPSignatureSubpacketVector unhashedPcks) { if (unhashedPcks == null) { unhashed = new SignatureSubpacket[0]; return; } unhashed = unhashedPcks.toSubpacketArray(); } /** * Return the one pass header associated with the current signature. * * @param isNested * @return PGPOnePassSignature * @throws PGPException */ public PGPOnePassSignature generateOnePassVersion( boolean isNested) throws PGPException { return new PGPOnePassSignature(new OnePassSignaturePacket(sigType, contentSigner.getHashAlgorithm(), contentSigner.getKeyAlgorithm(), contentSigner.getKeyID(), isNested)); } /** * Return a signature object containing the current signature state. * * @return PGPSignature * @throws PGPException */ public PGPSignature generate() throws PGPException { MPInteger[] sigValues; int version = 4; ByteArrayOutputStream sOut = new ByteArrayOutputStream(); SignatureSubpacket[] hPkts, unhPkts; if (!packetPresent(hashed, SignatureSubpacketTags.CREATION_TIME)) { hPkts = insertSubpacket(hashed, new SignatureCreationTime(false, new Date())); } else { hPkts = hashed; } if (!packetPresent(hashed, SignatureSubpacketTags.ISSUER_KEY_ID) && !packetPresent(unhashed, SignatureSubpacketTags.ISSUER_KEY_ID)) { unhPkts = insertSubpacket(unhashed, new IssuerKeyID(false, contentSigner.getKeyID())); } else { unhPkts = unhashed; } try { sOut.write((byte)version); sOut.write((byte)sigType); sOut.write((byte)contentSigner.getKeyAlgorithm()); sOut.write((byte)contentSigner.getHashAlgorithm()); ByteArrayOutputStream hOut = new ByteArrayOutputStream(); for (int i = 0; i != hPkts.length; i++) { hPkts[i].encode(hOut); } byte[] data = hOut.toByteArray(); sOut.write((byte)(data.length >> 8)); sOut.write((byte)data.length); sOut.write(data); } catch (IOException e) { throw new PGPException("exception encoding hashed data.", e); } byte[] hData = sOut.toByteArray(); sOut.write((byte)version); sOut.write((byte)0xff); sOut.write((byte)(hData.length >> 24)); sOut.write((byte)(hData.length >> 16)); sOut.write((byte)(hData.length >> 8)); sOut.write((byte)(hData.length)); byte[] trailer = sOut.toByteArray(); blockUpdate(trailer, 0, trailer.length); if (contentSigner.getKeyAlgorithm() == PublicKeyAlgorithmTags.RSA_SIGN || contentSigner.getKeyAlgorithm() == PublicKeyAlgorithmTags.RSA_GENERAL) // an RSA signature { sigValues = new MPInteger[1]; sigValues[0] = new MPInteger(new BigInteger(1, contentSigner.getSignature())); } else { sigValues = PGPUtil.dsaSigToMpi(contentSigner.getSignature()); } byte[] digest = contentSigner.getDigest(); byte[] fingerPrint = new byte[2]; fingerPrint[0] = digest[0]; fingerPrint[1] = digest[1]; return new PGPSignature(new SignaturePacket(sigType, contentSigner.getKeyID(), contentSigner.getKeyAlgorithm(), contentSigner.getHashAlgorithm(), hPkts, unhPkts, fingerPrint, sigValues)); } /** * Generate a certification for the passed in id and key. * * @param id the id we are certifying against the public key. * @param pubKey the key we are certifying against the id. * @return the certification. * @throws PGPException */ public PGPSignature generateCertification( String id, PGPPublicKey pubKey) throws PGPException { updateWithPublicKey(pubKey); // // hash in the id // updateWithIdData(0xb4, Strings.toUTF8ByteArray(id)); return this.generate(); } /** * Generate a certification for the passed in userAttributes * @param userAttributes the id we are certifying against the public key. * @param pubKey the key we are certifying against the id. * @return the certification. * @throws PGPException */ public PGPSignature generateCertification( PGPUserAttributeSubpacketVector userAttributes, PGPPublicKey pubKey) throws PGPException { updateWithPublicKey(pubKey); // // hash in the attributes // try { ByteArrayOutputStream bOut = new ByteArrayOutputStream(); UserAttributeSubpacket[] packets = userAttributes.toSubpacketArray(); for (int i = 0; i != packets.length; i++) { packets[i].encode(bOut); } updateWithIdData(0xd1, bOut.toByteArray()); } catch (IOException e) { throw new PGPException("cannot encode subpacket array", e); } return this.generate(); } /** * Generate a certification for the passed in key against the passed in * master key. * * @param masterKey the key we are certifying against. * @param pubKey the key we are certifying. * @return the certification. * @throws PGPException */ public PGPSignature generateCertification( PGPPublicKey masterKey, PGPPublicKey pubKey) throws PGPException { updateWithPublicKey(masterKey); updateWithPublicKey(pubKey); return this.generate(); } /** * Generate a certification, such as a revocation, for the passed in key. * * @param pubKey the key we are certifying. * @return the certification. * @throws PGPException */ public PGPSignature generateCertification( PGPPublicKey pubKey) throws PGPException { updateWithPublicKey(pubKey); return this.generate(); } private byte[] getEncodedPublicKey( PGPPublicKey pubKey) throws PGPException { byte[] keyBytes; try { keyBytes = pubKey.publicPk.getEncodedContents(); } catch (IOException e) { throw new PGPException("exception preparing key.", e); } return keyBytes; } private boolean packetPresent( SignatureSubpacket[] packets, int type) { for (int i = 0; i != packets.length; i++) { if (packets[i].getType() == type) { return true; } } return false; } private SignatureSubpacket[] insertSubpacket( SignatureSubpacket[] packets, SignatureSubpacket subpacket) { SignatureSubpacket[] tmp = new SignatureSubpacket[packets.length + 1]; tmp[0] = subpacket; System.arraycopy(packets, 0, tmp, 1, packets.length); return tmp; } private void updateWithIdData(int header, byte[] idBytes) throws PGPSignatureException { this.update((byte)header); this.update((byte)(idBytes.length >> 24)); this.update((byte)(idBytes.length >> 16)); this.update((byte)(idBytes.length >> 8)); this.update((byte)(idBytes.length)); this.update(idBytes); } private void updateWithPublicKey(PGPPublicKey key) throws PGPException { byte[] keyBytes = getEncodedPublicKey(key); this.update((byte)0x99); this.update((byte)(keyBytes.length >> 8)); this.update((byte)(keyBytes.length)); this.update(keyBytes); } } bouncycastle-1.49.orig/j2me/org/bouncycastle/openpgp/PGPSecretKeyRing.java0000644000175000017500000002667412150050436026163 0ustar ebourgebourgpackage org.bouncycastle.openpgp; import java.io.ByteArrayInputStream; import java.io.ByteArrayOutputStream; import java.io.IOException; import java.io.InputStream; import java.io.OutputStream; import java.security.SecureRandom; import java.util.ArrayList; import java.util.Collections; import java.util.Iterator; import java.util.List; import org.bouncycastle.bcpg.BCPGInputStream; import org.bouncycastle.bcpg.PacketTags; import org.bouncycastle.bcpg.PublicSubkeyPacket; import org.bouncycastle.bcpg.SecretKeyPacket; import org.bouncycastle.bcpg.SecretSubkeyPacket; import org.bouncycastle.bcpg.TrustPacket; import org.bouncycastle.openpgp.operator.KeyFingerPrintCalculator; import org.bouncycastle.openpgp.operator.PBESecretKeyDecryptor; import org.bouncycastle.openpgp.operator.PBESecretKeyEncryptor; /** * Class to hold a single master secret key and its subkeys. *

    * Often PGP keyring files consist of multiple master keys, if you are trying to process * or construct one of these you should use the PGPSecretKeyRingCollection class. */ public class PGPSecretKeyRing extends PGPKeyRing { List keys; List extraPubKeys; PGPSecretKeyRing(List keys) { this(keys, new ArrayList()); } private PGPSecretKeyRing(List keys, List extraPubKeys) { this.keys = keys; this.extraPubKeys = extraPubKeys; } public PGPSecretKeyRing( byte[] encoding, KeyFingerPrintCalculator fingerPrintCalculator) throws IOException, PGPException { this(new ByteArrayInputStream(encoding), fingerPrintCalculator); } public PGPSecretKeyRing( InputStream in, KeyFingerPrintCalculator fingerPrintCalculator) throws IOException, PGPException { this.keys = new ArrayList(); this.extraPubKeys = new ArrayList(); BCPGInputStream pIn = wrap(in); int initialTag = pIn.nextPacketTag(); if (initialTag != PacketTags.SECRET_KEY && initialTag != PacketTags.SECRET_SUBKEY) { throw new IOException( "secret key ring doesn't start with secret key tag: " + "tag 0x" + Integer.toHexString(initialTag)); } SecretKeyPacket secret = (SecretKeyPacket)pIn.readPacket(); // // ignore GPG comment packets if found. // while (pIn.nextPacketTag() == PacketTags.EXPERIMENTAL_2) { pIn.readPacket(); } TrustPacket trust = readOptionalTrustPacket(pIn); // revocation and direct signatures List keySigs = readSignaturesAndTrust(pIn); List ids = new ArrayList(); List idTrusts = new ArrayList(); List idSigs = new ArrayList(); readUserIDs(pIn, ids, idTrusts, idSigs); keys.add(new PGPSecretKey(secret, new PGPPublicKey(secret.getPublicKeyPacket(), trust, keySigs, ids, idTrusts, idSigs, fingerPrintCalculator))); // Read subkeys while (pIn.nextPacketTag() == PacketTags.SECRET_SUBKEY || pIn.nextPacketTag() == PacketTags.PUBLIC_SUBKEY) { if (pIn.nextPacketTag() == PacketTags.SECRET_SUBKEY) { SecretSubkeyPacket sub = (SecretSubkeyPacket)pIn.readPacket(); // // ignore GPG comment packets if found. // while (pIn.nextPacketTag() == PacketTags.EXPERIMENTAL_2) { pIn.readPacket(); } TrustPacket subTrust = readOptionalTrustPacket(pIn); List sigList = readSignaturesAndTrust(pIn); keys.add(new PGPSecretKey(sub, new PGPPublicKey(sub.getPublicKeyPacket(), subTrust, sigList, fingerPrintCalculator))); } else { PublicSubkeyPacket sub = (PublicSubkeyPacket)pIn.readPacket(); TrustPacket subTrust = readOptionalTrustPacket(pIn); List sigList = readSignaturesAndTrust(pIn); extraPubKeys.add(new PGPPublicKey(sub, subTrust, sigList, fingerPrintCalculator)); } } } /** * Return the public key for the master key. * * @return PGPPublicKey */ public PGPPublicKey getPublicKey() { return ((PGPSecretKey)keys.get(0)).getPublicKey(); } /** * Return the public key referred to by the passed in keyID if it * is present. * * @param keyID * @return PGPPublicKey */ public PGPPublicKey getPublicKey( long keyID) { PGPSecretKey key = getSecretKey(keyID); if (key != null) { return key.getPublicKey(); } for (int i = 0; i != extraPubKeys.size(); i++) { PGPPublicKey k = (PGPPublicKey)keys.get(i); if (keyID == k.getKeyID()) { return k; } } return null; } /** * Return an iterator containing all the public keys. * * @return Iterator */ public Iterator getPublicKeys() { List pubKeys = new ArrayList(); for (Iterator it = getSecretKeys(); it.hasNext();) { pubKeys.add(((PGPSecretKey)it.next()).getPublicKey()); } pubKeys.addAll(extraPubKeys); return Collections.unmodifiableList(pubKeys).iterator(); } /** * Return the master private key. * * @return PGPSecretKey */ public PGPSecretKey getSecretKey() { return ((PGPSecretKey)keys.get(0)); } /** * Return an iterator containing all the secret keys. * * @return Iterator */ public Iterator getSecretKeys() { return Collections.unmodifiableList(keys).iterator(); } public PGPSecretKey getSecretKey( long keyId) { for (int i = 0; i != keys.size(); i++) { PGPSecretKey k = (PGPSecretKey)keys.get(i); if (keyId == k.getKeyID()) { return k; } } return null; } /** * Return an iterator of the public keys in the secret key ring that * have no matching private key. At the moment only personal certificate data * appears in this fashion. * * @return iterator of unattached, or extra, public keys. */ public Iterator getExtraPublicKeys() { return extraPubKeys.iterator(); } public byte[] getEncoded() throws IOException { ByteArrayOutputStream bOut = new ByteArrayOutputStream(); this.encode(bOut); return bOut.toByteArray(); } public void encode( OutputStream outStream) throws IOException { for (int i = 0; i != keys.size(); i++) { PGPSecretKey k = (PGPSecretKey)keys.get(i); k.encode(outStream); } for (int i = 0; i != extraPubKeys.size(); i++) { PGPPublicKey k = (PGPPublicKey)extraPubKeys.get(i); k.encode(outStream); } } /** * Replace the public key set on the secret ring with the corresponding key off the public ring. * * @param secretRing secret ring to be changed. * @param publicRing public ring containing the new public key set. */ public static PGPSecretKeyRing replacePublicKeys(PGPSecretKeyRing secretRing, PGPPublicKeyRing publicRing) { List newList = new ArrayList(secretRing.keys.size()); for (Iterator it = secretRing.keys.iterator(); it.hasNext();) { PGPSecretKey sk = (PGPSecretKey)it.next(); PGPPublicKey pk = publicRing.getPublicKey(sk.getKeyID()); newList.add(PGPSecretKey.replacePublicKey(sk, pk)); } return new PGPSecretKeyRing(newList); } /** * Return a copy of the passed in secret key ring, with the private keys (where present) associated with the master key and sub keys * are encrypted using a new password and the passed in algorithm. * * @param ring the PGPSecretKeyRing to be copied. * @param oldKeyDecryptor the current decryptor based on the current password for key. * @param newKeyEncryptor a new encryptor based on a new password for encrypting the secret key material. * @return the updated key ring. */ public static PGPSecretKeyRing copyWithNewPassword( PGPSecretKeyRing ring, PBESecretKeyDecryptor oldKeyDecryptor, PBESecretKeyEncryptor newKeyEncryptor) throws PGPException { List newKeys = new ArrayList(ring.keys.size()); for (Iterator keys = ring.getSecretKeys(); keys.hasNext();) { PGPSecretKey key = (PGPSecretKey)keys.next(); if (key.isPrivateKeyEmpty()) { newKeys.add(key); } else { newKeys.add(PGPSecretKey.copyWithNewPassword(key, oldKeyDecryptor, newKeyEncryptor)); } } return new PGPSecretKeyRing(newKeys, ring.extraPubKeys); } /** * Returns a new key ring with the secret key passed in either added or * replacing an existing one with the same key ID. * * @param secRing the secret key ring to be modified. * @param secKey the secret key to be added. * @return a new secret key ring. */ public static PGPSecretKeyRing insertSecretKey( PGPSecretKeyRing secRing, PGPSecretKey secKey) { List keys = new ArrayList(secRing.keys); boolean found = false; boolean masterFound = false; for (int i = 0; i != keys.size();i++) { PGPSecretKey key = (PGPSecretKey)keys.get(i); if (key.getKeyID() == secKey.getKeyID()) { found = true; keys.set(i, secKey); } if (key.isMasterKey()) { masterFound = true; } } if (!found) { if (secKey.isMasterKey()) { if (masterFound) { throw new IllegalArgumentException("cannot add a master key to a ring that already has one"); } keys.add(0, secKey); } else { keys.add(secKey); } } return new PGPSecretKeyRing(keys, secRing.extraPubKeys); } /** * Returns a new key ring with the secret key passed in removed from the * key ring. * * @param secRing the secret key ring to be modified. * @param secKey the secret key to be removed. * @return a new secret key ring, or null if secKey is not found. */ public static PGPSecretKeyRing removeSecretKey( PGPSecretKeyRing secRing, PGPSecretKey secKey) { List keys = new ArrayList(secRing.keys); boolean found = false; for (int i = 0; i < keys.size();i++) { PGPSecretKey key = (PGPSecretKey)keys.get(i); if (key.getKeyID() == secKey.getKeyID()) { found = true; keys.remove(i); } } if (!found) { return null; } return new PGPSecretKeyRing(keys, secRing.extraPubKeys); } } bouncycastle-1.49.orig/j2me/org/bouncycastle/openpgp/PGPSignature.java0000644000175000017500000003352211731770075025410 0ustar ebourgebourgpackage org.bouncycastle.openpgp; import java.io.ByteArrayOutputStream; import java.io.IOException; import java.io.OutputStream; import java.util.Date; import org.bouncycastle.asn1.ASN1EncodableVector; import org.bouncycastle.asn1.DERInteger; import org.bouncycastle.asn1.DERSequence; import org.bouncycastle.bcpg.BCPGInputStream; import org.bouncycastle.bcpg.BCPGOutputStream; import org.bouncycastle.bcpg.MPInteger; import org.bouncycastle.bcpg.SignaturePacket; import org.bouncycastle.bcpg.SignatureSubpacket; import org.bouncycastle.bcpg.TrustPacket; import org.bouncycastle.bcpg.UserAttributeSubpacket; import org.bouncycastle.openpgp.operator.PGPContentVerifier; import org.bouncycastle.openpgp.operator.PGPContentVerifierBuilder; import org.bouncycastle.openpgp.operator.PGPContentVerifierBuilderProvider; import org.bouncycastle.util.BigIntegers; import org.bouncycastle.util.Strings; /** *A PGP signature object. */ public class PGPSignature { public static final int BINARY_DOCUMENT = 0x00; public static final int CANONICAL_TEXT_DOCUMENT = 0x01; public static final int STAND_ALONE = 0x02; public static final int DEFAULT_CERTIFICATION = 0x10; public static final int NO_CERTIFICATION = 0x11; public static final int CASUAL_CERTIFICATION = 0x12; public static final int POSITIVE_CERTIFICATION = 0x13; public static final int SUBKEY_BINDING = 0x18; public static final int PRIMARYKEY_BINDING = 0x19; public static final int DIRECT_KEY = 0x1f; public static final int KEY_REVOCATION = 0x20; public static final int SUBKEY_REVOCATION = 0x28; public static final int CERTIFICATION_REVOCATION = 0x30; public static final int TIMESTAMP = 0x40; private SignaturePacket sigPck; private int signatureType; private TrustPacket trustPck; private PGPContentVerifier verifier; private byte lastb; private OutputStream sigOut; PGPSignature( BCPGInputStream pIn) throws IOException, PGPException { this((SignaturePacket)pIn.readPacket()); } PGPSignature( SignaturePacket sigPacket) throws PGPException { sigPck = sigPacket; signatureType = sigPck.getSignatureType(); trustPck = null; } PGPSignature( SignaturePacket sigPacket, TrustPacket trustPacket) throws PGPException { this(sigPacket); this.trustPck = trustPacket; } /** * Return the OpenPGP version number for this signature. * * @return signature version number. */ public int getVersion() { return sigPck.getVersion(); } /** * Return the key algorithm associated with this signature. * @return signature key algorithm. */ public int getKeyAlgorithm() { return sigPck.getKeyAlgorithm(); } /** * Return the hash algorithm associated with this signature. * @return signature hash algorithm. */ public int getHashAlgorithm() { return sigPck.getHashAlgorithm(); } public void init(PGPContentVerifierBuilderProvider verifierBuilderProvider, PGPPublicKey pubKey) throws PGPException { PGPContentVerifierBuilder verifierBuilder = verifierBuilderProvider.get(sigPck.getKeyAlgorithm(), sigPck.getHashAlgorithm()); verifier = verifierBuilder.build(pubKey); lastb = 0; sigOut = verifier.getOutputStream(); } public void update( byte b) throws PGPSignatureException { if (signatureType == PGPSignature.CANONICAL_TEXT_DOCUMENT) { if (b == '\r') { byteUpdate((byte)'\r'); byteUpdate((byte)'\n'); } else if (b == '\n') { if (lastb != '\r') { byteUpdate((byte)'\r'); byteUpdate((byte)'\n'); } } else { byteUpdate(b); } lastb = b; } else { byteUpdate(b); } } public void update( byte[] bytes) throws PGPSignatureException { this.update(bytes, 0, bytes.length); } public void update( byte[] bytes, int off, int length) throws PGPSignatureException { if (signatureType == PGPSignature.CANONICAL_TEXT_DOCUMENT) { int finish = off + length; for (int i = off; i != finish; i++) { this.update(bytes[i]); } } else { blockUpdate(bytes, off, length); } } private void byteUpdate(byte b) throws PGPSignatureException { try { sigOut.write(b); } catch (IOException e) { throw new PGPSignatureException(e.getMessage(), e); } } private void blockUpdate(byte[] block, int off, int len) throws PGPSignatureException { try { sigOut.write(block, off, len); } catch (IOException e) { throw new PGPSignatureException(e.getMessage(), e); } } public boolean verify() throws PGPException { try { sigOut.write(this.getSignatureTrailer()); sigOut.close(); } catch (IOException e) { throw new PGPSignatureException(e.getMessage(), e); } return verifier.verify(this.getSignature()); } private void updateWithIdData(int header, byte[] idBytes) throws PGPException { this.update((byte)header); this.update((byte)(idBytes.length >> 24)); this.update((byte)(idBytes.length >> 16)); this.update((byte)(idBytes.length >> 8)); this.update((byte)(idBytes.length)); this.update(idBytes); } private void updateWithPublicKey(PGPPublicKey key) throws PGPException { byte[] keyBytes = getEncodedPublicKey(key); this.update((byte)0x99); this.update((byte)(keyBytes.length >> 8)); this.update((byte)(keyBytes.length)); this.update(keyBytes); } /** * Verify the signature as certifying the passed in public key as associated * with the passed in user attributes. * * @param userAttributes user attributes the key was stored under * @param key the key to be verified. * @return true if the signature matches, false otherwise. * @throws PGPException */ public boolean verifyCertification( PGPUserAttributeSubpacketVector userAttributes, PGPPublicKey key) throws PGPException { if (verifier == null) { throw new PGPException("PGPSignature not initialised - call init()."); } updateWithPublicKey(key); // // hash in the userAttributes // try { ByteArrayOutputStream bOut = new ByteArrayOutputStream(); UserAttributeSubpacket[] packets = userAttributes.toSubpacketArray(); for (int i = 0; i != packets.length; i++) { packets[i].encode(bOut); } updateWithIdData(0xd1, bOut.toByteArray()); } catch (IOException e) { throw new PGPException("cannot encode subpacket array", e); } addTrailer(); return verifier.verify(this.getSignature()); } /** * Verify the signature as certifying the passed in public key as associated * with the passed in id. * * @param id id the key was stored under * @param key the key to be verified. * @return true if the signature matches, false otherwise. * @throws PGPException */ public boolean verifyCertification( String id, PGPPublicKey key) throws PGPException { if (verifier == null) { throw new PGPException("PGPSignature not initialised - call init()."); } updateWithPublicKey(key); // // hash in the id // updateWithIdData(0xb4, Strings.toUTF8ByteArray(id)); addTrailer(); return verifier.verify(this.getSignature()); } /** * Verify a certification for the passed in key against the passed in * master key. * * @param masterKey the key we are verifying against. * @param pubKey the key we are verifying. * @return true if the certification is valid, false otherwise. * @throws PGPException */ public boolean verifyCertification( PGPPublicKey masterKey, PGPPublicKey pubKey) throws PGPException { if (verifier == null) { throw new PGPException("PGPSignature not initialised - call init()."); } updateWithPublicKey(masterKey); updateWithPublicKey(pubKey); addTrailer(); return verifier.verify(this.getSignature()); } private void addTrailer() throws PGPSignatureException { try { sigOut.write(sigPck.getSignatureTrailer()); sigOut.close(); } catch (IOException e) { throw new PGPSignatureException(e.getMessage(), e); } } /** * Verify a key certification, such as a revocation, for the passed in key. * * @param pubKey the key we are checking. * @return true if the certification is valid, false otherwise. * @throws PGPException */ public boolean verifyCertification( PGPPublicKey pubKey) throws PGPException { if (verifier == null) { throw new PGPException("PGPSignature not initialised - call init()."); } if (this.getSignatureType() != KEY_REVOCATION && this.getSignatureType() != SUBKEY_REVOCATION) { throw new PGPException("signature is not a key signature"); } updateWithPublicKey(pubKey); addTrailer(); return verifier.verify(this.getSignature()); } public int getSignatureType() { return sigPck.getSignatureType(); } /** * Return the id of the key that created the signature. * @return keyID of the signatures corresponding key. */ public long getKeyID() { return sigPck.getKeyID(); } /** * Return the creation time of the signature. * * @return the signature creation time. */ public Date getCreationTime() { return new Date(sigPck.getCreationTime()); } public byte[] getSignatureTrailer() { return sigPck.getSignatureTrailer(); } /** * Return true if the signature has either hashed or unhashed subpackets. * * @return true if either hashed or unhashed subpackets are present, false otherwise. */ public boolean hasSubpackets() { return sigPck.getHashedSubPackets() != null || sigPck.getUnhashedSubPackets() != null; } public PGPSignatureSubpacketVector getHashedSubPackets() { return createSubpacketVector(sigPck.getHashedSubPackets()); } public PGPSignatureSubpacketVector getUnhashedSubPackets() { return createSubpacketVector(sigPck.getUnhashedSubPackets()); } private PGPSignatureSubpacketVector createSubpacketVector(SignatureSubpacket[] pcks) { if (pcks != null) { return new PGPSignatureSubpacketVector(pcks); } return null; } public byte[] getSignature() throws PGPException { MPInteger[] sigValues = sigPck.getSignature(); byte[] signature; if (sigValues != null) { if (sigValues.length == 1) // an RSA signature { signature = BigIntegers.asUnsignedByteArray(sigValues[0].getValue()); } else { try { ASN1EncodableVector v = new ASN1EncodableVector(); v.add(new DERInteger(sigValues[0].getValue())); v.add(new DERInteger(sigValues[1].getValue())); signature = new DERSequence(v).getEncoded(); } catch (IOException e) { throw new PGPException("exception encoding DSA sig.", e); } } } else { signature = sigPck.getSignatureBytes(); } return signature; } public byte[] getEncoded() throws IOException { ByteArrayOutputStream bOut = new ByteArrayOutputStream(); this.encode(bOut); return bOut.toByteArray(); } public void encode( OutputStream outStream) throws IOException { BCPGOutputStream out; if (outStream instanceof BCPGOutputStream) { out = (BCPGOutputStream)outStream; } else { out = new BCPGOutputStream(outStream); } out.writePacket(sigPck); if (trustPck != null) { out.writePacket(trustPck); } } private byte[] getEncodedPublicKey( PGPPublicKey pubKey) throws PGPException { byte[] keyBytes; try { keyBytes = pubKey.publicPk.getEncodedContents(); } catch (IOException e) { throw new PGPException("exception preparing key.", e); } return keyBytes; } } bouncycastle-1.49.orig/j2me/org/bouncycastle/openpgp/PGPPublicKeyEncryptedData.java0000644000175000017500000001274211731766220030004 0ustar ebourgebourgpackage org.bouncycastle.openpgp; import java.io.EOFException; import java.io.InputStream; import org.bouncycastle.bcpg.BCPGInputStream; import org.bouncycastle.bcpg.InputStreamPacket; import org.bouncycastle.bcpg.PublicKeyEncSessionPacket; import org.bouncycastle.bcpg.SymmetricEncIntegrityPacket; import org.bouncycastle.bcpg.SymmetricKeyAlgorithmTags; import org.bouncycastle.openpgp.operator.PGPDataDecryptor; import org.bouncycastle.openpgp.operator.PublicKeyDataDecryptorFactory; import org.bouncycastle.util.io.TeeInputStream; /** * A public key encrypted data object. */ public class PGPPublicKeyEncryptedData extends PGPEncryptedData { PublicKeyEncSessionPacket keyData; PGPPublicKeyEncryptedData( PublicKeyEncSessionPacket keyData, InputStreamPacket encData) { super(encData); this.keyData = keyData; } private boolean confirmCheckSum( byte[] sessionInfo) { int check = 0; for (int i = 1; i != sessionInfo.length - 2; i++) { check += sessionInfo[i] & 0xff; } return (sessionInfo[sessionInfo.length - 2] == (byte)(check >> 8)) && (sessionInfo[sessionInfo.length - 1] == (byte)(check)); } /** * Return the keyID for the key used to encrypt the data. * * @return long */ public long getKeyID() { return keyData.getKeyID(); } /** * Return the symmetric key algorithm required to decrypt the data protected by this object. * * @param dataDecryptorFactory decryptor factory to use to recover the session data. * @return the integer encryption algorithm code. * @throws PGPException if the session data cannot be recovered. */ public int getSymmetricAlgorithm( PublicKeyDataDecryptorFactory dataDecryptorFactory) throws PGPException { byte[] plain = dataDecryptorFactory.recoverSessionData(keyData.getAlgorithm(), keyData.getEncSessionKey()); return plain[0]; } /** * Open an input stream which will provide the decrypted data protected by this object. * * @param dataDecryptorFactory decryptor factory to use to recover the session data and provide the stream. * @return the resulting input stream * @throws PGPException if the session data cannot be recovered or the stream cannot be created. */ public InputStream getDataStream( PublicKeyDataDecryptorFactory dataDecryptorFactory) throws PGPException { byte[] sessionData = dataDecryptorFactory.recoverSessionData(keyData.getAlgorithm(), keyData.getEncSessionKey()); if (!confirmCheckSum(sessionData)) { throw new PGPKeyValidationException("key checksum failed"); } if (sessionData[0] != SymmetricKeyAlgorithmTags.NULL) { try { boolean withIntegrityPacket = encData instanceof SymmetricEncIntegrityPacket; byte[] sessionKey = new byte[sessionData.length - 3]; System.arraycopy(sessionData, 1, sessionKey, 0, sessionKey.length); PGPDataDecryptor dataDecryptor = dataDecryptorFactory.createDataDecryptor(withIntegrityPacket, sessionData[0] & 0xff, sessionKey); encStream = new BCPGInputStream(dataDecryptor.getInputStream(encData.getInputStream())); if (withIntegrityPacket) { truncStream = new TruncatedStream(encStream); integrityCalculator = dataDecryptor.getIntegrityCalculator(); encStream = new TeeInputStream(truncStream, integrityCalculator.getOutputStream()); } byte[] iv = new byte[dataDecryptor.getBlockSize()]; for (int i = 0; i != iv.length; i++) { int ch = encStream.read(); if (ch < 0) { throw new EOFException("unexpected end of stream."); } iv[i] = (byte)ch; } int v1 = encStream.read(); int v2 = encStream.read(); if (v1 < 0 || v2 < 0) { throw new EOFException("unexpected end of stream."); } // // some versions of PGP appear to produce 0 for the extra // bytes rather than repeating the two previous bytes // /* * Commented out in the light of the oracle attack. if (iv[iv.length - 2] != (byte)v1 && v1 != 0) { throw new PGPDataValidationException("data check failed."); } if (iv[iv.length - 1] != (byte)v2 && v2 != 0) { throw new PGPDataValidationException("data check failed."); } */ return encStream; } catch (PGPException e) { throw e; } catch (Exception e) { throw new PGPException("Exception starting decryption", e); } } else { return encData.getInputStream(); } } } bouncycastle-1.49.orig/j2me/org/bouncycastle/openpgp/PGPPrivateKey.java0000644000175000017500000000221711732232207025516 0ustar ebourgebourgpackage org.bouncycastle.openpgp; import org.bouncycastle.bcpg.BCPGKey; import org.bouncycastle.bcpg.DSASecretBCPGKey; import org.bouncycastle.bcpg.ElGamalSecretBCPGKey; import org.bouncycastle.bcpg.PublicKeyPacket; import org.bouncycastle.bcpg.RSASecretBCPGKey; /** * general class to contain a private key for use with other openPGP * objects. */ public class PGPPrivateKey { private long keyID; private PublicKeyPacket publicKeyPacket; private BCPGKey privateKeyDataPacket; public PGPPrivateKey( long keyID, PublicKeyPacket publicKeyPacket, BCPGKey privateKeyDataPacket) { this.keyID = keyID; this.publicKeyPacket = publicKeyPacket; this.privateKeyDataPacket = privateKeyDataPacket; } /** * Return the keyID associated with the contained private key. * * @return long */ public long getKeyID() { return keyID; } public PublicKeyPacket getPublicKeyPacket() { return publicKeyPacket; } public BCPGKey getPrivateKeyDataPacket() { return privateKeyDataPacket; } } bouncycastle-1.49.orig/j2me/org/bouncycastle/openpgp/PGPV3SignatureGenerator.java0000644000175000017500000001466611731771362027500 0ustar ebourgebourgpackage org.bouncycastle.openpgp; import java.io.ByteArrayOutputStream; import java.io.IOException; import java.io.OutputStream; import java.math.BigInteger; import java.security.SecureRandom; import java.util.Date; import org.bouncycastle.bcpg.MPInteger; import org.bouncycastle.bcpg.OnePassSignaturePacket; import org.bouncycastle.bcpg.PublicKeyAlgorithmTags; import org.bouncycastle.bcpg.SignaturePacket; import org.bouncycastle.openpgp.operator.PGPContentSigner; import org.bouncycastle.openpgp.operator.PGPContentSignerBuilder; /** * Generator for old style PGP V3 Signatures. */ public class PGPV3SignatureGenerator { private byte lastb; private OutputStream sigOut; private PGPContentSignerBuilder contentSignerBuilder; private PGPContentSigner contentSigner; private int sigType; private int providedKeyAlgorithm = -1; /** * Create a signature generator built on the passed in contentSignerBuilder. * * @param contentSignerBuilder builder to produce PGPContentSigner objects for generating signatures. */ public PGPV3SignatureGenerator( PGPContentSignerBuilder contentSignerBuilder) { this.contentSignerBuilder = contentSignerBuilder; } /** * Initialise the generator for signing. * * @param signatureType * @param key * @throws PGPException */ public void init( int signatureType, PGPPrivateKey key) throws PGPException { contentSigner = contentSignerBuilder.build(signatureType, key); sigOut = contentSigner.getOutputStream(); sigType = contentSigner.getType(); lastb = 0; if (providedKeyAlgorithm >= 0 && providedKeyAlgorithm != contentSigner.getKeyAlgorithm()) { throw new PGPException("key algorithm mismatch"); } } /** * Initialise the generator for signing. * * @param signatureType * @param key * @param random * @throws PGPException * @deprecated random now ignored - set random in PGPContentSignerBuilder */ public void initSign( int signatureType, PGPPrivateKey key, SecureRandom random) throws PGPException { init(signatureType, key); } /** * Initialise the generator for signing. * * @param signatureType * @param key * @throws PGPException * @deprecated use init() */ public void initSign( int signatureType, PGPPrivateKey key) throws PGPException { init(signatureType, key); } public void update( byte b) throws PGPSignatureException { if (sigType == PGPSignature.CANONICAL_TEXT_DOCUMENT) { if (b == '\r') { byteUpdate((byte)'\r'); byteUpdate((byte)'\n'); } else if (b == '\n') { if (lastb != '\r') { byteUpdate((byte)'\r'); byteUpdate((byte)'\n'); } } else { byteUpdate(b); } lastb = b; } else { byteUpdate(b); } } public void update( byte[] b) throws PGPSignatureException { this.update(b, 0, b.length); } public void update( byte[] b, int off, int len) throws PGPSignatureException { if (sigType == PGPSignature.CANONICAL_TEXT_DOCUMENT) { int finish = off + len; for (int i = off; i != finish; i++) { this.update(b[i]); } } else { blockUpdate(b, off, len); } } private void byteUpdate(byte b) throws PGPSignatureException { try { sigOut.write(b); } catch (IOException e) { throw new PGPSignatureException("unable to update signature", e); } } private void blockUpdate(byte[] block, int off, int len) throws PGPSignatureException { try { sigOut.write(block, off, len); } catch (IOException e) { throw new PGPSignatureException("unable to update signature", e); } } /** * Return the one pass header associated with the current signature. * * @param isNested * @return PGPOnePassSignature * @throws PGPException */ public PGPOnePassSignature generateOnePassVersion( boolean isNested) throws PGPException { return new PGPOnePassSignature(new OnePassSignaturePacket(sigType, contentSigner.getHashAlgorithm(), contentSigner.getKeyAlgorithm(), contentSigner.getKeyID(), isNested)); } /** * Return a V3 signature object containing the current signature state. * * @return PGPSignature * @throws PGPException */ public PGPSignature generate() throws PGPException { long creationTime = new Date().getTime() / 1000; ByteArrayOutputStream sOut = new ByteArrayOutputStream(); sOut.write(sigType); sOut.write((byte)(creationTime >> 24)); sOut.write((byte)(creationTime >> 16)); sOut.write((byte)(creationTime >> 8)); sOut.write((byte)creationTime); byte[] hData = sOut.toByteArray(); blockUpdate(hData, 0, hData.length); MPInteger[] sigValues; if (contentSigner.getKeyAlgorithm() == PublicKeyAlgorithmTags.RSA_SIGN || contentSigner.getKeyAlgorithm() == PublicKeyAlgorithmTags.RSA_GENERAL) // an RSA signature { sigValues = new MPInteger[1]; sigValues[0] = new MPInteger(new BigInteger(1, contentSigner.getSignature())); } else { sigValues = PGPUtil.dsaSigToMpi(contentSigner.getSignature()); } byte[] digest = contentSigner.getDigest(); byte[] fingerPrint = new byte[2]; fingerPrint[0] = digest[0]; fingerPrint[1] = digest[1]; return new PGPSignature(new SignaturePacket(3, contentSigner.getType(), contentSigner.getKeyID(), contentSigner.getKeyAlgorithm(), contentSigner.getHashAlgorithm(), creationTime * 1000, fingerPrint, sigValues)); } } bouncycastle-1.49.orig/j2me/org/bouncycastle/openpgp/PGPKeyPair.java0000644000175000017500000000266211732232207025003 0ustar ebourgebourgpackage org.bouncycastle.openpgp; import java.util.Date; import org.bouncycastle.bcpg.BCPGKey; import org.bouncycastle.bcpg.DSASecretBCPGKey; import org.bouncycastle.bcpg.ElGamalSecretBCPGKey; import org.bouncycastle.bcpg.RSASecretBCPGKey; /** * General class to handle JCA key pairs and convert them into OpenPGP ones. *

    * A word for the unwary, the KeyID for a OpenPGP public key is calculated from * a hash that includes the time of creation, if you pass a different date to the * constructor below with the same public private key pair the KeyID will not be the * same as for previous generations of the key, so ideally you only want to do * this once. */ public class PGPKeyPair { protected PGPPublicKey pub; protected PGPPrivateKey priv; protected PGPKeyPair() { } /** * Create a key pair from a PGPPrivateKey and a PGPPublicKey. * * @param pub the public key * @param priv the private key */ public PGPKeyPair( PGPPublicKey pub, PGPPrivateKey priv) { this.pub = pub; this.priv = priv; } /** * Return the keyID associated with this key pair. * * @return keyID */ public long getKeyID() { return pub.getKeyID(); } public PGPPublicKey getPublicKey() { return pub; } public PGPPrivateKey getPrivateKey() { return priv; } } bouncycastle-1.49.orig/j2me/org/bouncycastle/openpgp/PGPObjectFactory.java0000644000175000017500000001147511732222124026174 0ustar ebourgebourgpackage org.bouncycastle.openpgp; import java.io.ByteArrayInputStream; import java.io.IOException; import java.io.InputStream; import java.util.ArrayList; import java.util.List; import org.bouncycastle.bcpg.BCPGInputStream; import org.bouncycastle.bcpg.PacketTags; import org.bouncycastle.openpgp.operator.KeyFingerPrintCalculator; import org.bouncycastle.openpgp.operator.bc.BcKeyFingerprintCalculator; /** * General class for reading a PGP object stream. *

    * Note: if this class finds a PGPPublicKey or a PGPSecretKey it * will create a PGPPublicKeyRing, or a PGPSecretKeyRing for each * key found. If all you are trying to do is read a key ring file use * either PGPPublicKeyRingCollection or PGPSecretKeyRingCollection. */ public class PGPObjectFactory { private BCPGInputStream in; private KeyFingerPrintCalculator fingerPrintCalculator; public PGPObjectFactory( InputStream in) { this(in, new BcKeyFingerprintCalculator()); } /** * Create an object factor suitable for reading keys, key rings and key ring collections. * * @param in stream to read from * @param fingerPrintCalculator calculator to use in key finger print calculations. */ public PGPObjectFactory( InputStream in, KeyFingerPrintCalculator fingerPrintCalculator) { this.in = new BCPGInputStream(in); this.fingerPrintCalculator = fingerPrintCalculator; } public PGPObjectFactory( byte[] bytes) { this(new ByteArrayInputStream(bytes)); } /** * Create an object factor suitable for reading keys, key rings and key ring collections. * * @param bytes stream to read from * @param fingerPrintCalculator calculator to use in key finger print calculations. */ public PGPObjectFactory( byte[] bytes, KeyFingerPrintCalculator fingerPrintCalculator) { this(new ByteArrayInputStream(bytes), fingerPrintCalculator); } /** * Return the next object in the stream, or null if the end is reached. * * @return Object * @throws IOException on a parse error */ public Object nextObject() throws IOException { List l; switch (in.nextPacketTag()) { case -1: return null; case PacketTags.SIGNATURE: l = new ArrayList(); while (in.nextPacketTag() == PacketTags.SIGNATURE) { try { l.add(new PGPSignature(in)); } catch (PGPException e) { throw new IOException("can't create signature object: " + e); } } return new PGPSignatureList((PGPSignature[])l.toArray(new PGPSignature[l.size()])); case PacketTags.SECRET_KEY: try { return new PGPSecretKeyRing(in, fingerPrintCalculator); } catch (PGPException e) { throw new IOException("can't create secret key object: " + e); } case PacketTags.PUBLIC_KEY: return new PGPPublicKeyRing(in, fingerPrintCalculator); case PacketTags.PUBLIC_SUBKEY: try { return PGPPublicKeyRing.readSubkey(in, fingerPrintCalculator); } catch (PGPException e) { throw new IOException("processing error: " + e.getMessage()); } case PacketTags.COMPRESSED_DATA: throw new IOException("processing error: " + "compressed data not supported"); case PacketTags.LITERAL_DATA: return new PGPLiteralData(in); case PacketTags.PUBLIC_KEY_ENC_SESSION: case PacketTags.SYMMETRIC_KEY_ENC_SESSION: return new PGPEncryptedDataList(in); case PacketTags.ONE_PASS_SIGNATURE: l = new ArrayList(); while (in.nextPacketTag() == PacketTags.ONE_PASS_SIGNATURE) { try { l.add(new PGPOnePassSignature(in)); } catch (PGPException e) { throw new IOException("can't create one pass signature object: " + e); } } return new PGPOnePassSignatureList((PGPOnePassSignature[])l.toArray(new PGPOnePassSignature[l.size()])); case PacketTags.MARKER: return new PGPMarker(in); case PacketTags.EXPERIMENTAL_1: case PacketTags.EXPERIMENTAL_2: case PacketTags.EXPERIMENTAL_3: case PacketTags.EXPERIMENTAL_4: return in.readPacket(); } throw new IOException("unknown object in stream: " + in.nextPacketTag()); } } bouncycastle-1.49.orig/j2me/org/bouncycastle/openpgp/PGPKeyRingGenerator.java0000644000175000017500000001146711732224221026656 0ustar ebourgebourgpackage org.bouncycastle.openpgp; import java.util.ArrayList; import java.util.Iterator; import java.util.List; import org.bouncycastle.bcpg.PublicSubkeyPacket; import org.bouncycastle.openpgp.operator.PBESecretKeyEncryptor; import org.bouncycastle.openpgp.operator.PGPContentSignerBuilder; import org.bouncycastle.openpgp.operator.PGPDigestCalculator; /** * Generator for a PGP master and subkey ring. This class will generate * both the secret and public key rings */ public class PGPKeyRingGenerator { List keys = new ArrayList(); private PBESecretKeyEncryptor keyEncryptor; private PGPDigestCalculator checksumCalculator; private PGPKeyPair masterKey; private PGPSignatureSubpacketVector hashedPcks; private PGPSignatureSubpacketVector unhashedPcks; private PGPContentSignerBuilder keySignerBuilder; /** * Create a new key ring generator. * * @param certificationLevel * @param masterKey * @param id * @param checksumCalculator * @param hashedPcks * @param unhashedPcks * @param keySignerBuilder * @param keyEncryptor * @throws PGPException */ public PGPKeyRingGenerator( int certificationLevel, PGPKeyPair masterKey, String id, PGPDigestCalculator checksumCalculator, PGPSignatureSubpacketVector hashedPcks, PGPSignatureSubpacketVector unhashedPcks, PGPContentSignerBuilder keySignerBuilder, PBESecretKeyEncryptor keyEncryptor) throws PGPException { this.masterKey = masterKey; this.keyEncryptor = keyEncryptor; this.checksumCalculator = checksumCalculator; this.keySignerBuilder = keySignerBuilder; this.hashedPcks = hashedPcks; this.unhashedPcks = unhashedPcks; keys.add(new PGPSecretKey(certificationLevel, masterKey, id, checksumCalculator, hashedPcks, unhashedPcks, keySignerBuilder, keyEncryptor)); } /** * Add a sub key to the key ring to be generated with default certification and inheriting * the hashed/unhashed packets of the master key. * * @param keyPair * @throws PGPException */ public void addSubKey( PGPKeyPair keyPair) throws PGPException { addSubKey(keyPair, hashedPcks, unhashedPcks); } /** * Add a subkey with specific hashed and unhashed packets associated with it and default * certification. * * @param keyPair public/private key pair. * @param hashedPcks hashed packet values to be included in certification. * @param unhashedPcks unhashed packets values to be included in certification. * @throws PGPException */ public void addSubKey( PGPKeyPair keyPair, PGPSignatureSubpacketVector hashedPcks, PGPSignatureSubpacketVector unhashedPcks) throws PGPException { try { // // generate the certification // PGPSignatureGenerator sGen = new PGPSignatureGenerator(keySignerBuilder); sGen.init(PGPSignature.SUBKEY_BINDING, masterKey.getPrivateKey()); sGen.setHashedSubpackets(hashedPcks); sGen.setUnhashedSubpackets(unhashedPcks); List subSigs = new ArrayList(); subSigs.add(sGen.generateCertification(masterKey.getPublicKey(), keyPair.getPublicKey())); keys.add(new PGPSecretKey(keyPair.getPrivateKey(), new PGPPublicKey(keyPair.getPublicKey(), null, subSigs), checksumCalculator, keyEncryptor)); } catch (PGPException e) { throw e; } catch (Exception e) { throw new PGPException("exception adding subkey: ", e); } } /** * Return the secret key ring. * * @return a secret key ring. */ public PGPSecretKeyRing generateSecretKeyRing() { return new PGPSecretKeyRing(keys); } /** * Return the public key ring that corresponds to the secret key ring. * * @return a public key ring. */ public PGPPublicKeyRing generatePublicKeyRing() { Iterator it = keys.iterator(); List pubKeys = new ArrayList(); pubKeys.add(((PGPSecretKey)it.next()).getPublicKey()); while (it.hasNext()) { PGPPublicKey k = new PGPPublicKey(((PGPSecretKey)it.next()).getPublicKey()); k.publicPk = new PublicSubkeyPacket(k.getAlgorithm(), k.getCreationTime(), k.publicPk.getKey()); pubKeys.add(k); } return new PGPPublicKeyRing(pubKeys); } } bouncycastle-1.49.orig/j2me/org/bouncycastle/openpgp/PGPEncryptedDataGenerator.java0000644000175000017500000002643411731766674030063 0ustar ebourgebourgpackage org.bouncycastle.openpgp; import java.io.IOException; import java.io.OutputStream; import java.security.SecureRandom; import java.util.ArrayList; import java.util.List; import org.bouncycastle.bcpg.BCPGOutputStream; import org.bouncycastle.bcpg.HashAlgorithmTags; import org.bouncycastle.bcpg.PacketTags; import org.bouncycastle.bcpg.SymmetricKeyAlgorithmTags; import org.bouncycastle.openpgp.operator.PBEKeyEncryptionMethodGenerator; import org.bouncycastle.openpgp.operator.PGPDataEncryptor; import org.bouncycastle.openpgp.operator.PGPDataEncryptorBuilder; import org.bouncycastle.openpgp.operator.PGPDigestCalculator; import org.bouncycastle.openpgp.operator.PGPKeyEncryptionMethodGenerator; import org.bouncycastle.util.io.TeeOutputStream; /** * Generator for encrypted objects. */ public class PGPEncryptedDataGenerator implements SymmetricKeyAlgorithmTags, StreamGenerator { /** * Specifier for SHA-1 S2K PBE generator. */ public static final int S2K_SHA1 = HashAlgorithmTags.SHA1; /** * Specifier for SHA-224 S2K PBE generator. */ public static final int S2K_SHA224 = HashAlgorithmTags.SHA224; /** * Specifier for SHA-256 S2K PBE generator. */ public static final int S2K_SHA256 = HashAlgorithmTags.SHA256; /** * Specifier for SHA-384 S2K PBE generator. */ public static final int S2K_SHA384 = HashAlgorithmTags.SHA384; /** * Specifier for SHA-512 S2K PBE generator. */ public static final int S2K_SHA512 = HashAlgorithmTags.SHA512; private BCPGOutputStream pOut; private OutputStream cOut; private boolean oldFormat = false; private PGPDigestCalculator digestCalc; private OutputStream genOut; private PGPDataEncryptorBuilder dataEncryptorBuilder; private List methods = new ArrayList(); private int defAlgorithm; private SecureRandom rand; /** * Base constructor. * * @param encryptorBuilder builder to create actual data encryptor. */ public PGPEncryptedDataGenerator(PGPDataEncryptorBuilder encryptorBuilder) { this(encryptorBuilder, false); } /** * Base constructor with the option to turn on formatting for PGP 2.6.x compatibility. * * @param encryptorBuilder builder to create actual data encryptor. * @param oldFormat PGP 2.6.x compatibility required. */ public PGPEncryptedDataGenerator(PGPDataEncryptorBuilder encryptorBuilder, boolean oldFormat) { this.dataEncryptorBuilder = encryptorBuilder; this.oldFormat = oldFormat; this.defAlgorithm = dataEncryptorBuilder.getAlgorithm(); this.rand = dataEncryptorBuilder.getSecureRandom(); } /** * Added a key encryption method to be used to encrypt the session data associated * with this encrypted data. * * @param method key encryption method to use. */ public void addMethod(PGPKeyEncryptionMethodGenerator method) { methods.add(method); } private void addCheckSum( byte[] sessionInfo) { int check = 0; for (int i = 1; i != sessionInfo.length - 2; i++) { check += sessionInfo[i] & 0xff; } sessionInfo[sessionInfo.length - 2] = (byte)(check >> 8); sessionInfo[sessionInfo.length - 1] = (byte)(check); } private byte[] createSessionInfo( int algorithm, byte[] keyBytes) { byte[] sessionInfo = new byte[keyBytes.length + 3]; sessionInfo[0] = (byte) algorithm; System.arraycopy(keyBytes, 0, sessionInfo, 1, keyBytes.length); addCheckSum(sessionInfo); return sessionInfo; } /** * If buffer is non null stream assumed to be partial, otherwise the * length will be used to output a fixed length packet. *

    * The stream created can be closed off by either calling close() * on the stream or close() on the generator. Closing the returned * stream does not close off the OutputStream parameter out. * * @param out * @param length * @param buffer * @return * @throws java.io.IOException * @throws PGPException * @throws IllegalStateException */ private OutputStream open( OutputStream out, long length, byte[] buffer) throws IOException, PGPException, IllegalStateException { if (cOut != null) { throw new IllegalStateException("generator already in open state"); } if (methods.size() == 0) { throw new IllegalStateException("no encryption methods specified"); } byte[] key = null; pOut = new BCPGOutputStream(out); defAlgorithm = dataEncryptorBuilder.getAlgorithm(); rand = dataEncryptorBuilder.getSecureRandom(); if (methods.size() == 1) { if (methods.get(0) instanceof PBEKeyEncryptionMethodGenerator) { PBEKeyEncryptionMethodGenerator m = (PBEKeyEncryptionMethodGenerator)methods.get(0); key = m.getKey(dataEncryptorBuilder.getAlgorithm()); pOut.writePacket(((PGPKeyEncryptionMethodGenerator)methods.get(0)).generate(defAlgorithm, null)); } else { key = PGPUtil.makeRandomKey(defAlgorithm, rand); byte[] sessionInfo = createSessionInfo(defAlgorithm, key); PGPKeyEncryptionMethodGenerator m = (PGPKeyEncryptionMethodGenerator)methods.get(0); pOut.writePacket(m.generate(defAlgorithm, sessionInfo)); } } else // multiple methods { key = PGPUtil.makeRandomKey(defAlgorithm, rand); byte[] sessionInfo = createSessionInfo(defAlgorithm, key); for (int i = 0; i != methods.size(); i++) { PGPKeyEncryptionMethodGenerator m = (PGPKeyEncryptionMethodGenerator)methods.get(i); pOut.writePacket(m.generate(defAlgorithm, sessionInfo)); } } try { PGPDataEncryptor dataEncryptor = dataEncryptorBuilder.build(key); digestCalc = dataEncryptor.getIntegrityCalculator(); if (buffer == null) { // // we have to add block size + 2 for the generated IV and + 1 + 22 if integrity protected // if (digestCalc != null) { pOut = new ClosableBCPGOutputStream(out, PacketTags.SYM_ENC_INTEGRITY_PRO, length + dataEncryptor.getBlockSize() + 2 + 1 + 22); pOut.write(1); // version number } else { pOut = new ClosableBCPGOutputStream(out, PacketTags.SYMMETRIC_KEY_ENC, length + dataEncryptor.getBlockSize() + 2, oldFormat); } } else { if (digestCalc != null) { pOut = new ClosableBCPGOutputStream(out, PacketTags.SYM_ENC_INTEGRITY_PRO, buffer); pOut.write(1); // version number } else { pOut = new ClosableBCPGOutputStream(out, PacketTags.SYMMETRIC_KEY_ENC, buffer); } } genOut = cOut = dataEncryptor.getOutputStream(pOut); if (digestCalc != null) { genOut = new TeeOutputStream(digestCalc.getOutputStream(), cOut); } byte[] inLineIv = new byte[dataEncryptor.getBlockSize() + 2]; rand.nextBytes(inLineIv); inLineIv[inLineIv.length - 1] = inLineIv[inLineIv.length - 3]; inLineIv[inLineIv.length - 2] = inLineIv[inLineIv.length - 4]; genOut.write(inLineIv); return new WrappedGeneratorStream(genOut, this); } catch (Exception e) { throw new PGPException("Exception creating cipher", e); } } /** * Return an outputstream which will encrypt the data as it is written * to it. *

    * The stream created can be closed off by either calling close() * on the stream or close() on the generator. Closing the returned * stream does not close off the OutputStream parameter out. * * @param out * @param length * @return OutputStream * @throws IOException * @throws PGPException */ public OutputStream open( OutputStream out, long length) throws IOException, PGPException { return this.open(out, length, null); } /** * Return an outputstream which will encrypt the data as it is written * to it. The stream will be written out in chunks according to the size of the * passed in buffer. *

    * The stream created can be closed off by either calling close() * on the stream or close() on the generator. Closing the returned * stream does not close off the OutputStream parameter out. *

    * Note: if the buffer is not a power of 2 in length only the largest power of 2 * bytes worth of the buffer will be used. * * @param out * @param buffer the buffer to use. * @return OutputStream * @throws IOException * @throws PGPException */ public OutputStream open( OutputStream out, byte[] buffer) throws IOException, PGPException { return this.open(out, 0, buffer); } /** * Close off the encrypted object - this is equivalent to calling close on the stream * returned by the open() method. *

    * Note: This does not close the underlying output stream, only the stream on top of it created by the open() method. * @throws java.io.IOException */ public void close() throws IOException { if (cOut != null) { if (digestCalc != null) { // // hand code a mod detection packet // BCPGOutputStream bOut = new BCPGOutputStream(genOut, PacketTags.MOD_DETECTION_CODE, 20); bOut.flush(); byte[] dig = digestCalc.getDigest(); cOut.write(dig); } cOut.close(); cOut = null; pOut = null; } } private class ClosableBCPGOutputStream extends BCPGOutputStream { public ClosableBCPGOutputStream(OutputStream out, int symmetricKeyEnc, byte[] buffer) throws IOException { super(out, symmetricKeyEnc, buffer); } public ClosableBCPGOutputStream(OutputStream out, int symmetricKeyEnc, long length, boolean oldFormat) throws IOException { super(out, symmetricKeyEnc, length, oldFormat); } public ClosableBCPGOutputStream(OutputStream out, int symEncIntegrityPro, long length) throws IOException { super(out, symEncIntegrityPro, length); } public void close() throws IOException { this.finish(); } } } bouncycastle-1.49.orig/j2me/org/bouncycastle/openpgp/PGPPublicKey.java0000644000175000017500000006241611731753004025333 0ustar ebourgebourgpackage org.bouncycastle.openpgp; import java.io.ByteArrayOutputStream; import java.io.IOException; import java.io.OutputStream; import java.util.ArrayList; import java.util.Collection; import java.util.Date; import java.util.Iterator; import java.util.List; import org.bouncycastle.bcpg.BCPGKey; import org.bouncycastle.bcpg.BCPGOutputStream; import org.bouncycastle.bcpg.ContainedPacket; import org.bouncycastle.bcpg.DSAPublicBCPGKey; import org.bouncycastle.bcpg.ElGamalPublicBCPGKey; import org.bouncycastle.bcpg.PublicKeyAlgorithmTags; import org.bouncycastle.bcpg.PublicKeyPacket; import org.bouncycastle.bcpg.RSAPublicBCPGKey; import org.bouncycastle.bcpg.TrustPacket; import org.bouncycastle.bcpg.UserAttributePacket; import org.bouncycastle.bcpg.UserIDPacket; import org.bouncycastle.openpgp.operator.KeyFingerPrintCalculator; import org.bouncycastle.util.Arrays; /** * general class to handle a PGP public key object. */ public class PGPPublicKey implements PublicKeyAlgorithmTags { private static final int[] MASTER_KEY_CERTIFICATION_TYPES = new int[] { PGPSignature.POSITIVE_CERTIFICATION, PGPSignature.CASUAL_CERTIFICATION, PGPSignature.NO_CERTIFICATION, PGPSignature.DEFAULT_CERTIFICATION }; PublicKeyPacket publicPk; TrustPacket trustPk; List keySigs = new ArrayList(); List ids = new ArrayList(); List idTrusts = new ArrayList(); List idSigs = new ArrayList(); List subSigs = null; private long keyID; private byte[] fingerprint; private int keyStrength; private void init(KeyFingerPrintCalculator fingerPrintCalculator) throws PGPException { BCPGKey key = publicPk.getKey(); this.fingerprint = fingerPrintCalculator.calculateFingerprint(publicPk); if (publicPk.getVersion() <= 3) { RSAPublicBCPGKey rK = (RSAPublicBCPGKey)key; this.keyID = rK.getModulus().longValue(); this.keyStrength = rK.getModulus().bitLength(); } else { this.keyID = ((long)(fingerprint[fingerprint.length - 8] & 0xff) << 56) | ((long)(fingerprint[fingerprint.length - 7] & 0xff) << 48) | ((long)(fingerprint[fingerprint.length - 6] & 0xff) << 40) | ((long)(fingerprint[fingerprint.length - 5] & 0xff) << 32) | ((long)(fingerprint[fingerprint.length - 4] & 0xff) << 24) | ((long)(fingerprint[fingerprint.length - 3] & 0xff) << 16) | ((long)(fingerprint[fingerprint.length - 2] & 0xff) << 8) | ((fingerprint[fingerprint.length - 1] & 0xff)); if (key instanceof RSAPublicBCPGKey) { this.keyStrength = ((RSAPublicBCPGKey)key).getModulus().bitLength(); } else if (key instanceof DSAPublicBCPGKey) { this.keyStrength = ((DSAPublicBCPGKey)key).getP().bitLength(); } else if (key instanceof ElGamalPublicBCPGKey) { this.keyStrength = ((ElGamalPublicBCPGKey)key).getP().bitLength(); } } } /** * Create a PGP public key from a packet descriptor using the passed in fingerPrintCalculator to do calculate * the fingerprint and keyID. * * @param publicKeyPacket packet describing the public key. * @param fingerPrintCalculator calculator providing the digest support ot create the key fingerprint. * @throws PGPException if the packet is faulty, or the required calculations fail. */ public PGPPublicKey(PublicKeyPacket publicKeyPacket, KeyFingerPrintCalculator fingerPrintCalculator) throws PGPException { this.publicPk = publicKeyPacket; this.ids = new ArrayList(); this.idSigs = new ArrayList(); init(fingerPrintCalculator); } /* * Constructor for a sub-key. */ PGPPublicKey( PublicKeyPacket publicPk, TrustPacket trustPk, List sigs, KeyFingerPrintCalculator fingerPrintCalculator) throws PGPException { this.publicPk = publicPk; this.trustPk = trustPk; this.subSigs = sigs; init(fingerPrintCalculator); } PGPPublicKey( PGPPublicKey key, TrustPacket trust, List subSigs) { this.publicPk = key.publicPk; this.trustPk = trust; this.subSigs = subSigs; this.fingerprint = key.fingerprint; this.keyID = key.keyID; this.keyStrength = key.keyStrength; } /** * Copy constructor. * @param pubKey the public key to copy. */ PGPPublicKey( PGPPublicKey pubKey) { this.publicPk = pubKey.publicPk; this.keySigs = new ArrayList(pubKey.keySigs); this.ids = new ArrayList(pubKey.ids); this.idTrusts = new ArrayList(pubKey.idTrusts); this.idSigs = new ArrayList(pubKey.idSigs.size()); for (int i = 0; i != pubKey.idSigs.size(); i++) { this.idSigs.add(new ArrayList((ArrayList)pubKey.idSigs.get(i))); } if (pubKey.subSigs != null) { this.subSigs = new ArrayList(pubKey.subSigs.size()); for (int i = 0; i != pubKey.subSigs.size(); i++) { this.subSigs.add(pubKey.subSigs.get(i)); } } this.fingerprint = pubKey.fingerprint; this.keyID = pubKey.keyID; this.keyStrength = pubKey.keyStrength; } PGPPublicKey( PublicKeyPacket publicPk, TrustPacket trustPk, List keySigs, List ids, List idTrusts, List idSigs, KeyFingerPrintCalculator fingerPrintCalculator) throws PGPException { this.publicPk = publicPk; this.trustPk = trustPk; this.keySigs = keySigs; this.ids = ids; this.idTrusts = idTrusts; this.idSigs = idSigs; init(fingerPrintCalculator); } /** * @return the version of this key. */ public int getVersion() { return publicPk.getVersion(); } /** * @return creation time of key. */ public Date getCreationTime() { return publicPk.getTime(); } /** * @return number of valid days from creation time - zero means no * expiry. */ public int getValidDays() { if (publicPk.getVersion() > 3) { return (int)(this.getValidSeconds() / (24 * 60 * 60)); } else { return publicPk.getValidDays(); } } /** * Return the trust data associated with the public key, if present. * @return a byte array with trust data, null otherwise. */ public byte[] getTrustData() { if (trustPk == null) { return null; } return Arrays.clone(trustPk.getLevelAndTrustAmount()); } /** * @return number of valid seconds from creation time - zero means no * expiry. */ public long getValidSeconds() { if (publicPk.getVersion() > 3) { if (this.isMasterKey()) { for (int i = 0; i != MASTER_KEY_CERTIFICATION_TYPES.length; i++) { long seconds = getExpirationTimeFromSig(true, MASTER_KEY_CERTIFICATION_TYPES[i]); if (seconds >= 0) { return seconds; } } } else { long seconds = getExpirationTimeFromSig(false, PGPSignature.SUBKEY_BINDING); if (seconds >= 0) { return seconds; } } return 0; } else { return (long)publicPk.getValidDays() * 24 * 60 * 60; } } private long getExpirationTimeFromSig( boolean selfSigned, int signatureType) { Iterator signatures = this.getSignaturesOfType(signatureType); long expiryTime = -1; while (signatures.hasNext()) { PGPSignature sig = (PGPSignature)signatures.next(); if (!selfSigned || sig.getKeyID() == this.getKeyID()) { PGPSignatureSubpacketVector hashed = sig.getHashedSubPackets(); if (hashed != null) { long current = hashed.getKeyExpirationTime(); if (current == 0 || current > expiryTime) { expiryTime = current; } } else { return 0; } } } return expiryTime; } /** * Return the keyID associated with the public key. * * @return long */ public long getKeyID() { return keyID; } /** * Return the fingerprint of the key. * * @return key fingerprint. */ public byte[] getFingerprint() { byte[] tmp = new byte[fingerprint.length]; System.arraycopy(fingerprint, 0, tmp, 0, tmp.length); return tmp; } /** * Return true if this key has an algorithm type that makes it suitable to use for encryption. *

    * Note: with version 4 keys KeyFlags subpackets should also be considered when present for * determining the preferred use of the key. * * @return true if the key algorithm is suitable for encryption. */ public boolean isEncryptionKey() { int algorithm = publicPk.getAlgorithm(); return ((algorithm == RSA_GENERAL) || (algorithm == RSA_ENCRYPT) || (algorithm == ELGAMAL_ENCRYPT) || (algorithm == ELGAMAL_GENERAL)); } /** * Return true if this is a master key. * @return true if a master key. */ public boolean isMasterKey() { return (subSigs == null); } /** * Return the algorithm code associated with the public key. * * @return int */ public int getAlgorithm() { return publicPk.getAlgorithm(); } /** * Return the strength of the key in bits. * * @return bit strenght of key. */ public int getBitStrength() { return keyStrength; } /** * Return any userIDs associated with the key. * * @return an iterator of Strings. */ public Iterator getUserIDs() { List temp = new ArrayList(); for (int i = 0; i != ids.size(); i++) { if (ids.get(i) instanceof String) { temp.add(ids.get(i)); } } return temp.iterator(); } /** * Return any user attribute vectors associated with the key. * * @return an iterator of PGPUserAttributeSubpacketVector objects. */ public Iterator getUserAttributes() { List temp = new ArrayList(); for (int i = 0; i != ids.size(); i++) { if (ids.get(i) instanceof PGPUserAttributeSubpacketVector) { temp.add(ids.get(i)); } } return temp.iterator(); } /** * Return any signatures associated with the passed in id. * * @param id the id to be matched. * @return an iterator of PGPSignature objects. */ public Iterator getSignaturesForID( String id) { for (int i = 0; i != ids.size(); i++) { if (id.equals(ids.get(i))) { return ((ArrayList)idSigs.get(i)).iterator(); } } return null; } /** * Return an iterator of signatures associated with the passed in user attributes. * * @param userAttributes the vector of user attributes to be matched. * @return an iterator of PGPSignature objects. */ public Iterator getSignaturesForUserAttribute( PGPUserAttributeSubpacketVector userAttributes) { for (int i = 0; i != ids.size(); i++) { if (userAttributes.equals(ids.get(i))) { return ((ArrayList)idSigs.get(i)).iterator(); } } return null; } /** * Return signatures of the passed in type that are on this key. * * @param signatureType the type of the signature to be returned. * @return an iterator (possibly empty) of signatures of the given type. */ public Iterator getSignaturesOfType( int signatureType) { List l = new ArrayList(); Iterator it = this.getSignatures(); while (it.hasNext()) { PGPSignature sig = (PGPSignature)it.next(); if (sig.getSignatureType() == signatureType) { l.add(sig); } } return l.iterator(); } /** * Return all signatures/certifications associated with this key. * * @return an iterator (possibly empty) with all signatures/certifications. */ public Iterator getSignatures() { if (subSigs == null) { List sigs = new ArrayList(); sigs.addAll(keySigs); for (int i = 0; i != idSigs.size(); i++) { sigs.addAll((Collection)idSigs.get(i)); } return sigs.iterator(); } else { return subSigs.iterator(); } } public PublicKeyPacket getPublicKeyPacket() { return publicPk; } public byte[] getEncoded() throws IOException { ByteArrayOutputStream bOut = new ByteArrayOutputStream(); this.encode(bOut); return bOut.toByteArray(); } public void encode( OutputStream outStream) throws IOException { BCPGOutputStream out; if (outStream instanceof BCPGOutputStream) { out = (BCPGOutputStream)outStream; } else { out = new BCPGOutputStream(outStream); } out.writePacket(publicPk); if (trustPk != null) { out.writePacket(trustPk); } if (subSigs == null) // not a sub-key { for (int i = 0; i != keySigs.size(); i++) { ((PGPSignature)keySigs.get(i)).encode(out); } for (int i = 0; i != ids.size(); i++) { if (ids.get(i) instanceof String) { String id = (String)ids.get(i); out.writePacket(new UserIDPacket(id)); } else { PGPUserAttributeSubpacketVector v = (PGPUserAttributeSubpacketVector)ids.get(i); out.writePacket(new UserAttributePacket(v.toSubpacketArray())); } if (idTrusts.get(i) != null) { out.writePacket((ContainedPacket)idTrusts.get(i)); } List sigs = (List)idSigs.get(i); for (int j = 0; j != sigs.size(); j++) { ((PGPSignature)sigs.get(j)).encode(out); } } } else { for (int j = 0; j != subSigs.size(); j++) { ((PGPSignature)subSigs.get(j)).encode(out); } } } /** * Check whether this (sub)key has a revocation signature on it. * * @return boolean indicating whether this (sub)key has been revoked. */ public boolean isRevoked() { int ns = 0; boolean revoked = false; if (this.isMasterKey()) // Master key { while (!revoked && (ns < keySigs.size())) { if (((PGPSignature)keySigs.get(ns++)).getSignatureType() == PGPSignature.KEY_REVOCATION) { revoked = true; } } } else // Sub-key { while (!revoked && (ns < subSigs.size())) { if (((PGPSignature)subSigs.get(ns++)).getSignatureType() == PGPSignature.SUBKEY_REVOCATION) { revoked = true; } } } return revoked; } /** * Add a certification for an id to the given public key. * * @param key the key the certification is to be added to. * @param id the id the certification is associated with. * @param certification the new certification. * @return the re-certified key. */ public static PGPPublicKey addCertification( PGPPublicKey key, String id, PGPSignature certification) { return addCert(key, id, certification); } /** * Add a certification for the given UserAttributeSubpackets to the given public key. * * @param key the key the certification is to be added to. * @param userAttributes the attributes the certification is associated with. * @param certification the new certification. * @return the re-certified key. */ public static PGPPublicKey addCertification( PGPPublicKey key, PGPUserAttributeSubpacketVector userAttributes, PGPSignature certification) { return addCert(key, userAttributes, certification); } private static PGPPublicKey addCert( PGPPublicKey key, Object id, PGPSignature certification) { PGPPublicKey returnKey = new PGPPublicKey(key); List sigList = null; for (int i = 0; i != returnKey.ids.size(); i++) { if (id.equals(returnKey.ids.get(i))) { sigList = (List)returnKey.idSigs.get(i); } } if (sigList != null) { sigList.add(certification); } else { sigList = new ArrayList(); sigList.add(certification); returnKey.ids.add(id); returnKey.idTrusts.add(null); returnKey.idSigs.add(sigList); } return returnKey; } /** * Remove any certifications associated with a given user attribute subpacket * on a key. * * @param key the key the certifications are to be removed from. * @param userAttributes the attributes to be removed. * @return the re-certified key, null if the user attribute subpacket was not found on the key. */ public static PGPPublicKey removeCertification( PGPPublicKey key, PGPUserAttributeSubpacketVector userAttributes) { return removeCert(key, userAttributes); } /** * Remove any certifications associated with a given id on a key. * * @param key the key the certifications are to be removed from. * @param id the id that is to be removed. * @return the re-certified key, null if the id was not found on the key. */ public static PGPPublicKey removeCertification( PGPPublicKey key, String id) { return removeCert(key, id); } private static PGPPublicKey removeCert( PGPPublicKey key, Object id) { PGPPublicKey returnKey = new PGPPublicKey(key); boolean found = false; for (int i = 0; i < returnKey.ids.size(); i++) { if (id.equals(returnKey.ids.get(i))) { found = true; returnKey.ids.remove(i); returnKey.idTrusts.remove(i); returnKey.idSigs.remove(i); } } if (!found) { return null; } return returnKey; } /** * Remove a certification associated with a given id on a key. * * @param key the key the certifications are to be removed from. * @param id the id that the certification is to be removed from. * @param certification the certification to be removed. * @return the re-certified key, null if the certification was not found. */ public static PGPPublicKey removeCertification( PGPPublicKey key, String id, PGPSignature certification) { return removeCert(key, id, certification); } /** * Remove a certification associated with a given user attributes on a key. * * @param key the key the certifications are to be removed from. * @param userAttributes the user attributes that the certification is to be removed from. * @param certification the certification to be removed. * @return the re-certified key, null if the certification was not found. */ public static PGPPublicKey removeCertification( PGPPublicKey key, PGPUserAttributeSubpacketVector userAttributes, PGPSignature certification) { return removeCert(key, userAttributes, certification); } private static PGPPublicKey removeCert( PGPPublicKey key, Object id, PGPSignature certification) { PGPPublicKey returnKey = new PGPPublicKey(key); boolean found = false; for (int i = 0; i < returnKey.ids.size(); i++) { if (id.equals(returnKey.ids.get(i))) { found = ((List)returnKey.idSigs.get(i)).remove(certification); } } if (!found) { return null; } return returnKey; } /** * Add a revocation or some other key certification to a key. * * @param key the key the revocation is to be added to. * @param certification the key signature to be added. * @return the new changed public key object. */ public static PGPPublicKey addCertification( PGPPublicKey key, PGPSignature certification) { if (key.isMasterKey()) { if (certification.getSignatureType() == PGPSignature.SUBKEY_REVOCATION) { throw new IllegalArgumentException("signature type incorrect for master key revocation."); } } else { if (certification.getSignatureType() == PGPSignature.KEY_REVOCATION) { throw new IllegalArgumentException("signature type incorrect for sub-key revocation."); } } PGPPublicKey returnKey = new PGPPublicKey(key); if (returnKey.subSigs != null) { returnKey.subSigs.add(certification); } else { returnKey.keySigs.add(certification); } return returnKey; } /** * Remove a certification from the key. * * @param key the key the certifications are to be removed from. * @param certification the certification to be removed. * @return the modified key, null if the certification was not found. */ public static PGPPublicKey removeCertification( PGPPublicKey key, PGPSignature certification) { PGPPublicKey returnKey = new PGPPublicKey(key); boolean found; if (returnKey.subSigs != null) { found = returnKey.subSigs.remove(certification); } else { found = returnKey.keySigs.remove(certification); } if (!found) { for (Iterator it = key.getUserIDs(); it.hasNext();) { String id = (String)it.next(); for (Iterator sIt = key.getSignaturesForID(id); sIt.hasNext();) { if (certification == sIt.next()) { found = true; returnKey = PGPPublicKey.removeCertification(returnKey, id, certification); } } } if (!found) { for (Iterator it = key.getUserAttributes(); it.hasNext();) { PGPUserAttributeSubpacketVector id = (PGPUserAttributeSubpacketVector)it.next(); for (Iterator sIt = key.getSignaturesForUserAttribute(id); sIt.hasNext();) { if (certification == sIt.next()) { found = true; returnKey = PGPPublicKey.removeCertification(returnKey, id, certification); } } } } } return returnKey; } } bouncycastle-1.49.orig/j2me/org/bouncycastle/openpgp/PGPPublicKeyRing.java0000644000175000017500000001525411732235302026146 0ustar ebourgebourgpackage org.bouncycastle.openpgp; import java.io.ByteArrayInputStream; import java.io.ByteArrayOutputStream; import java.io.IOException; import java.io.InputStream; import java.io.OutputStream; import java.util.ArrayList; import java.util.Collections; import java.util.Iterator; import java.util.List; import org.bouncycastle.bcpg.BCPGInputStream; import org.bouncycastle.bcpg.PacketTags; import org.bouncycastle.bcpg.PublicKeyPacket; import org.bouncycastle.bcpg.TrustPacket; import org.bouncycastle.openpgp.operator.KeyFingerPrintCalculator; /** * Class to hold a single master public key and its subkeys. *

    * Often PGP keyring files consist of multiple master keys, if you are trying to process * or construct one of these you should use the PGPPublicKeyRingCollection class. */ public class PGPPublicKeyRing extends PGPKeyRing { List keys; public PGPPublicKeyRing( byte[] encoding, KeyFingerPrintCalculator fingerPrintCalculator) throws IOException { this(new ByteArrayInputStream(encoding), fingerPrintCalculator); } /** * @param pubKeys */ PGPPublicKeyRing( List pubKeys) { this.keys = pubKeys; } public PGPPublicKeyRing( InputStream in, KeyFingerPrintCalculator fingerPrintCalculator) throws IOException { this.keys = new ArrayList(); BCPGInputStream pIn = wrap(in); int initialTag = pIn.nextPacketTag(); if (initialTag != PacketTags.PUBLIC_KEY && initialTag != PacketTags.PUBLIC_SUBKEY) { throw new IOException( "public key ring doesn't start with public key tag: " + "tag 0x" + Integer.toHexString(initialTag)); } PublicKeyPacket pubPk = (PublicKeyPacket)pIn.readPacket(); TrustPacket trustPk = readOptionalTrustPacket(pIn); // direct signatures and revocations List keySigs = readSignaturesAndTrust(pIn); List ids = new ArrayList(); List idTrusts = new ArrayList(); List idSigs = new ArrayList(); readUserIDs(pIn, ids, idTrusts, idSigs); try { keys.add(new PGPPublicKey(pubPk, trustPk, keySigs, ids, idTrusts, idSigs, fingerPrintCalculator)); // Read subkeys while (pIn.nextPacketTag() == PacketTags.PUBLIC_SUBKEY) { keys.add(readSubkey(pIn, fingerPrintCalculator)); } } catch (PGPException e) { throw new IOException("processing exception: " + e.toString()); } } /** * Return the first public key in the ring. * * @return PGPPublicKey */ public PGPPublicKey getPublicKey() { return (PGPPublicKey)keys.get(0); } /** * Return the public key referred to by the passed in keyID if it * is present. * * @param keyID * @return PGPPublicKey */ public PGPPublicKey getPublicKey( long keyID) { for (int i = 0; i != keys.size(); i++) { PGPPublicKey k = (PGPPublicKey)keys.get(i); if (keyID == k.getKeyID()) { return k; } } return null; } /** * Return an iterator containing all the public keys. * * @return Iterator */ public Iterator getPublicKeys() { return Collections.unmodifiableList(keys).iterator(); } public byte[] getEncoded() throws IOException { ByteArrayOutputStream bOut = new ByteArrayOutputStream(); this.encode(bOut); return bOut.toByteArray(); } public void encode( OutputStream outStream) throws IOException { for (int i = 0; i != keys.size(); i++) { PGPPublicKey k = (PGPPublicKey)keys.get(i); k.encode(outStream); } } /** * Returns a new key ring with the public key passed in * either added or replacing an existing one. * * @param pubRing the public key ring to be modified * @param pubKey the public key to be inserted. * @return a new keyRing */ public static PGPPublicKeyRing insertPublicKey( PGPPublicKeyRing pubRing, PGPPublicKey pubKey) { List keys = new ArrayList(pubRing.keys); boolean found = false; boolean masterFound = false; for (int i = 0; i != keys.size();i++) { PGPPublicKey key = (PGPPublicKey)keys.get(i); if (key.getKeyID() == pubKey.getKeyID()) { found = true; keys.set(i, pubKey); } if (key.isMasterKey()) { masterFound = true; } } if (!found) { if (pubKey.isMasterKey()) { if (masterFound) { throw new IllegalArgumentException("cannot add a master key to a ring that already has one"); } keys.add(0, pubKey); } else { keys.add(pubKey); } } return new PGPPublicKeyRing(keys); } /** * Returns a new key ring with the public key passed in * removed from the key ring. * * @param pubRing the public key ring to be modified * @param pubKey the public key to be removed. * @return a new keyRing, null if pubKey is not found. */ public static PGPPublicKeyRing removePublicKey( PGPPublicKeyRing pubRing, PGPPublicKey pubKey) { List keys = new ArrayList(pubRing.keys); boolean found = false; for (int i = 0; i < keys.size();i++) { PGPPublicKey key = (PGPPublicKey)keys.get(i); if (key.getKeyID() == pubKey.getKeyID()) { found = true; keys.remove(i); } } if (!found) { return null; } return new PGPPublicKeyRing(keys); } static PGPPublicKey readSubkey(BCPGInputStream in, KeyFingerPrintCalculator fingerPrintCalculator) throws IOException, PGPException { PublicKeyPacket pk = (PublicKeyPacket)in.readPacket(); TrustPacket kTrust = readOptionalTrustPacket(in); // PGP 8 actually leaves out the signature. List sigList = readSignaturesAndTrust(in); return new PGPPublicKey(pk, kTrust, sigList, fingerPrintCalculator); } } bouncycastle-1.49.orig/j2me/org/bouncycastle/crypto/0000755000175000017500000000000012152033550022064 5ustar ebourgebourgbouncycastle-1.49.orig/j2me/org/bouncycastle/crypto/tls/0000755000175000017500000000000012152033550022666 5ustar ebourgebourgbouncycastle-1.49.orig/j2me/org/bouncycastle/crypto/tls/UDPTransport.java0000644000175000017500000000534512150044070026102 0ustar ebourgebourgpackage org.bouncycastle.crypto.tls; import java.io.IOException; import javax.microedition.io.DatagramConnection; import javax.microedition.io.Datagram; public class UDPTransport implements DatagramTransport { private final static int MIN_IP_OVERHEAD = 20; private final static int MAX_IP_OVERHEAD = MIN_IP_OVERHEAD + 64; private final static int UDP_OVERHEAD = 8; private final DatagramConnection socket; private final int receiveLimit, sendLimit; public UDPTransport(DatagramConnection socket, int mtu) throws IOException { // // In 1.3 and earlier sockets were bound and connected during creation // //if (!socket.isBound() || !socket.isConnected()) //{ // throw new IllegalArgumentException("'socket' must be bound and connected"); //} this.socket = socket; // NOTE: As of JDK 1.6, can use NetworkInterface.getMTU this.receiveLimit = mtu - MIN_IP_OVERHEAD - UDP_OVERHEAD; this.sendLimit = mtu - MAX_IP_OVERHEAD - UDP_OVERHEAD; } public int getReceiveLimit() { return receiveLimit; } public int getSendLimit() { // TODO[DTLS] Implement Path-MTU discovery? return sendLimit; } public int receive(byte[] buf, int off, int len, int waitMillis) throws IOException { //socket.setSoTimeout(waitMillis); -- not applicable if (off == 0) { Datagram packet = socket.newDatagram(buf, len); socket.receive(packet); return packet.getLength(); } else { byte[] rv = new byte[len]; Datagram packet = socket.newDatagram(rv, len); socket.receive(packet); System.arraycopy(rv, 0, buf, off, packet.getLength()); return packet.getLength(); } } public void send(byte[] buf, int off, int len) throws IOException { if (len > getSendLimit()) { /* * RFC 4347 4.1.1. "If the application attempts to send a record larger than the MTU, * the DTLS implementation SHOULD generate an error, thus avoiding sending a packet * which will be fragmented." */ // TODO Exception } if (off == 0) { Datagram packet = socket.newDatagram(buf, len); socket.send(packet); } else { byte[] data = new byte[len]; System.arraycopy(buf, off, data, 0, len); Datagram packet = socket.newDatagram(data, len); socket.send(packet); } } public void close() throws IOException { socket.close(); } } bouncycastle-1.49.orig/j2me/org/bouncycastle/crypto/encodings/0000755000175000017500000000000012152033550024035 5ustar ebourgebourgbouncycastle-1.49.orig/j2me/org/bouncycastle/crypto/encodings/PKCS1Encoding.java0000644000175000017500000001442511527114057027205 0ustar ebourgebourgpackage org.bouncycastle.crypto.encodings; import org.bouncycastle.crypto.AsymmetricBlockCipher; import org.bouncycastle.crypto.CipherParameters; import org.bouncycastle.crypto.InvalidCipherTextException; import org.bouncycastle.crypto.params.AsymmetricKeyParameter; import org.bouncycastle.crypto.params.ParametersWithRandom; import java.security.SecureRandom; /** * this does your basic PKCS 1 v1.5 padding - whether or not you should be using this * depends on your application - see PKCS1 Version 2 for details. */ public class PKCS1Encoding implements AsymmetricBlockCipher { /** * some providers fail to include the leading zero in PKCS1 encoded blocks. If you need to * work with one of these set the system property org.bouncycastle.pkcs1.strict to false. *

    * The system property is checked during construction of the encoding object, it is set to * true by default. *

    */ public static final String STRICT_LENGTH_ENABLED_PROPERTY = "org.bouncycastle.pkcs1.strict"; private static final int HEADER_LENGTH = 10; private SecureRandom random; private AsymmetricBlockCipher engine; private boolean forEncryption; private boolean forPrivateKey; private boolean useStrictLength; /** * Basic constructor. * @param cipher */ public PKCS1Encoding( AsymmetricBlockCipher cipher) { this.engine = cipher; this.useStrictLength = useStrict(); } // // for J2ME compatibility // private boolean useStrict() { String strict = System.getProperty(STRICT_LENGTH_ENABLED_PROPERTY); return strict == null || strict.equals("true"); } public AsymmetricBlockCipher getUnderlyingCipher() { return engine; } public void init( boolean forEncryption, CipherParameters param) { AsymmetricKeyParameter kParam; if (param instanceof ParametersWithRandom) { ParametersWithRandom rParam = (ParametersWithRandom)param; this.random = rParam.getRandom(); kParam = (AsymmetricKeyParameter)rParam.getParameters(); } else { this.random = new SecureRandom(); kParam = (AsymmetricKeyParameter)param; } engine.init(forEncryption, param); this.forPrivateKey = kParam.isPrivate(); this.forEncryption = forEncryption; } public int getInputBlockSize() { int baseBlockSize = engine.getInputBlockSize(); if (forEncryption) { return baseBlockSize - HEADER_LENGTH; } else { return baseBlockSize; } } public int getOutputBlockSize() { int baseBlockSize = engine.getOutputBlockSize(); if (forEncryption) { return baseBlockSize; } else { return baseBlockSize - HEADER_LENGTH; } } public byte[] processBlock( byte[] in, int inOff, int inLen) throws InvalidCipherTextException { if (forEncryption) { return encodeBlock(in, inOff, inLen); } else { return decodeBlock(in, inOff, inLen); } } private byte[] encodeBlock( byte[] in, int inOff, int inLen) throws InvalidCipherTextException { if (inLen > getInputBlockSize()) { throw new IllegalArgumentException("input data too large"); } byte[] block = new byte[engine.getInputBlockSize()]; if (forPrivateKey) { block[0] = 0x01; // type code 1 for (int i = 1; i != block.length - inLen - 1; i++) { block[i] = (byte)0xFF; } } else { random.nextBytes(block); // random fill block[0] = 0x02; // type code 2 // // a zero byte marks the end of the padding, so all // the pad bytes must be non-zero. // for (int i = 1; i != block.length - inLen - 1; i++) { while (block[i] == 0) { block[i] = (byte)random.nextInt(); } } } block[block.length - inLen - 1] = 0x00; // mark the end of the padding System.arraycopy(in, inOff, block, block.length - inLen, inLen); return engine.processBlock(block, 0, block.length); } /** * @exception InvalidCipherTextException if the decrypted block is not in PKCS1 format. */ private byte[] decodeBlock( byte[] in, int inOff, int inLen) throws InvalidCipherTextException { byte[] block = engine.processBlock(in, inOff, inLen); if (block.length < getOutputBlockSize()) { throw new InvalidCipherTextException("block truncated"); } byte type = block[0]; if (type != 1 && type != 2) { throw new InvalidCipherTextException("unknown block type"); } if (useStrictLength && block.length != engine.getOutputBlockSize()) { throw new InvalidCipherTextException("block incorrect size"); } // // find and extract the message block. // int start; for (start = 1; start != block.length; start++) { byte pad = block[start]; if (pad == 0) { break; } if (type == 1 && pad != (byte)0xff) { throw new InvalidCipherTextException("block padding incorrect"); } } start++; // data should start at the next byte if (start > block.length || start < HEADER_LENGTH) { throw new InvalidCipherTextException("no data in block"); } byte[] result = new byte[block.length - start]; System.arraycopy(block, start, result, 0, result.length); return result; } } bouncycastle-1.49.orig/j2me/org/bouncycastle/crypto/test/0000755000175000017500000000000012152033550023043 5ustar ebourgebourgbouncycastle-1.49.orig/j2me/org/bouncycastle/crypto/test/BigIntegerTest.java0000644000175000017500000000123610262753174026602 0ustar ebourgebourgpackage org.bouncycastle.crypto.test; import org.bouncycastle.util.test.*; public class BigIntegerTest { public static Test[] tests = { new DHTest(), new ElGamalTest(), new DSATest(), new ECTest(), new ECIESTest(), new RSATest(), new ISO9796Test(), new OAEPTest(), new PSSTest(), new CTSTest(), new PKCS5Test(), new PKCS12Test() }; public static void main( String[] args) { for (int i = 0; i != tests.length; i++) { TestResult result = tests[i].perform(); System.out.println(result); } } } bouncycastle-1.49.orig/j2me/org/bouncycastle/crypto/test/CryptoRegressionTest.java0000644000175000017500000000304710355130470030075 0ustar ebourgebourgpackage org.bouncycastle.crypto.test; import org.bouncycastle.util.test.*; public class CryptoRegressionTest { public static Test[] tests = { new AESTest(), new DESTest(), new DESedeTest(), new ModeTest(), new DHTest(), new ElGamalTest(), new DSATest(), new ECTest(), new ECIESTest(), new MacTest(), new RC2Test(), new RC4Test(), new RC5Test(), new RC6Test(), new RijndaelTest(), new SerpentTest(), new SkipjackTest(), new BlowfishTest(), new TwofishTest(), new CAST5Test(), new CAST6Test(), new IDEATest(), new CamelliaTest(), new RSATest(), new ISO9796Test(), new MD2DigestTest(), new MD4DigestTest(), new MD5DigestTest(), new SHA1DigestTest(), new SHA256DigestTest(), new SHA384DigestTest(), new SHA512DigestTest(), new RIPEMD128DigestTest(), new RIPEMD160DigestTest(), new TigerDigestTest(), new MD5HMacTest(), new SHA1HMacTest(), new RIPEMD128HMacTest(), new RIPEMD160HMacTest(), /* new OAEPTest() */ new PSSTest(), new CTSTest(), /* new PKCS5Test() */ new PKCS12Test() }; public static void main( String[] args) { for (int i = 0; i != tests.length; i++) { TestResult result = tests[i].perform(); System.out.println(result); } } } bouncycastle-1.49.orig/j2me/org/bouncycastle/crypto/test/RSATest.java0000644000175000017500000003716512147561641025222 0ustar ebourgebourgpackage org.bouncycastle.crypto.test; import java.math.BigInteger; import java.security.SecureRandom; import org.bouncycastle.crypto.AsymmetricBlockCipher; import org.bouncycastle.crypto.AsymmetricCipherKeyPair; import org.bouncycastle.crypto.CipherParameters; import org.bouncycastle.crypto.InvalidCipherTextException; import org.bouncycastle.crypto.encodings.OAEPEncoding; import org.bouncycastle.crypto.encodings.PKCS1Encoding; import org.bouncycastle.crypto.engines.RSAEngine; import org.bouncycastle.crypto.generators.RSAKeyPairGenerator; import org.bouncycastle.crypto.params.RSAKeyGenerationParameters; import org.bouncycastle.crypto.params.RSAKeyParameters; import org.bouncycastle.crypto.params.RSAPrivateCrtKeyParameters; import org.bouncycastle.util.Arrays; import org.bouncycastle.util.encoders.Hex; import org.bouncycastle.util.test.SimpleTest; public class RSATest extends SimpleTest { static BigInteger mod = new BigInteger("b259d2d6e627a768c94be36164c2d9fc79d97aab9253140e5bf17751197731d6f7540d2509e7b9ffee0a70a6e26d56e92d2edd7f85aba85600b69089f35f6bdbf3c298e05842535d9f064e6b0391cb7d306e0a2d20c4dfb4e7b49a9640bdea26c10ad69c3f05007ce2513cee44cfe01998e62b6c3637d3fc0391079b26ee36d5", 16); static BigInteger pubExp = new BigInteger("11", 16); static BigInteger privExp = new BigInteger("92e08f83cc9920746989ca5034dcb384a094fb9c5a6288fcc4304424ab8f56388f72652d8fafc65a4b9020896f2cde297080f2a540e7b7ce5af0b3446e1258d1dd7f245cf54124b4c6e17da21b90a0ebd22605e6f45c9f136d7a13eaac1c0f7487de8bd6d924972408ebb58af71e76fd7b012a8d0e165f3ae2e5077a8648e619", 16); static BigInteger p = new BigInteger("f75e80839b9b9379f1cf1128f321639757dba514642c206bbbd99f9a4846208b3e93fbbe5e0527cc59b1d4b929d9555853004c7c8b30ee6a213c3d1bb7415d03", 16); static BigInteger q = new BigInteger("b892d9ebdbfc37e397256dd8a5d3123534d1f03726284743ddc6be3a709edb696fc40c7d902ed804c6eee730eee3d5b20bf6bd8d87a296813c87d3b3cc9d7947", 16); static BigInteger pExp = new BigInteger("1d1a2d3ca8e52068b3094d501c9a842fec37f54db16e9a67070a8b3f53cc03d4257ad252a1a640eadd603724d7bf3737914b544ae332eedf4f34436cac25ceb5", 16); static BigInteger qExp = new BigInteger("6c929e4e81672fef49d9c825163fec97c4b7ba7acb26c0824638ac22605d7201c94625770984f78a56e6e25904fe7db407099cad9b14588841b94f5ab498dded", 16); static BigInteger crtCoef = new BigInteger("dae7651ee69ad1d081ec5e7188ae126f6004ff39556bde90e0b870962fa7b926d070686d8244fe5a9aa709a95686a104614834b0ada4b10f53197a5cb4c97339", 16); static String input = "4e6f77206973207468652074696d6520666f7220616c6c20676f6f64206d656e"; // // to check that we handling byte extension by big number correctly. // static String edgeInput = "ff6f77206973207468652074696d6520666f7220616c6c20676f6f64206d656e"; static byte[] oversizedSig = Hex.decode("01ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff004e6f77206973207468652074696d6520666f7220616c6c20676f6f64206d656e"); static byte[] dudBlock = Hex.decode("000fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff004e6f77206973207468652074696d6520666f7220616c6c20676f6f64206d656e"); static byte[] truncatedDataBlock = Hex.decode("0001ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff004e6f77206973207468652074696d6520666f7220616c6c20676f6f64206d656e"); static byte[] incorrectPadding = Hex.decode("0001ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff4e6f77206973207468652074696d6520666f7220616c6c20676f6f64206d656e"); static byte[] missingDataBlock = Hex.decode("0001ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff"); public String getName() { return "RSA"; } private void testStrictPKCS1Length(RSAKeyParameters pubParameters, RSAKeyParameters privParameters) { AsymmetricBlockCipher eng = new RSAEngine(); eng.init(true, privParameters); byte[] data = null; try { data = eng.processBlock(oversizedSig, 0, oversizedSig.length); } catch (Exception e) { fail("RSA: failed - exception " + e.toString(), e); } eng = new PKCS1Encoding(eng); eng.init(false, pubParameters); try { data = eng.processBlock(data, 0, data.length); fail("oversized signature block not recognised"); } catch (InvalidCipherTextException e) { if (!e.getMessage().equals("block incorrect size")) { fail("RSA: failed - exception " + e.toString(), e); } } } private void testTruncatedPKCS1Block(RSAKeyParameters pubParameters, RSAKeyParameters privParameters) { checkForPKCS1Exception(pubParameters, privParameters, truncatedDataBlock, "block truncated"); } private void testDudPKCS1Block(RSAKeyParameters pubParameters, RSAKeyParameters privParameters) { checkForPKCS1Exception(pubParameters, privParameters, dudBlock, "unknown block type"); } private void testWrongPaddingPKCS1Block(RSAKeyParameters pubParameters, RSAKeyParameters privParameters) { checkForPKCS1Exception(pubParameters, privParameters, incorrectPadding, "block padding incorrect"); } private void testMissingDataPKCS1Block(RSAKeyParameters pubParameters, RSAKeyParameters privParameters) { checkForPKCS1Exception(pubParameters, privParameters, missingDataBlock, "no data in block"); } private void checkForPKCS1Exception(RSAKeyParameters pubParameters, RSAKeyParameters privParameters, byte[] inputData, String expectedMessage) { AsymmetricBlockCipher eng = new RSAEngine(); eng.init(true, privParameters); byte[] data = null; try { data = eng.processBlock(inputData, 0, inputData.length); } catch (Exception e) { fail("RSA: failed - exception " + e.toString(), e); } eng = new PKCS1Encoding(eng); eng.init(false, pubParameters); try { data = eng.processBlock(data, 0, data.length); fail("missing data block not recognised"); } catch (InvalidCipherTextException e) { if (!e.getMessage().equals(expectedMessage)) { fail("RSA: failed - exception " + e.toString(), e); } } } private void testOAEP(RSAKeyParameters pubParameters, RSAKeyParameters privParameters) { // // OAEP - public encrypt, private decrypt // AsymmetricBlockCipher eng = new OAEPEncoding(new RSAEngine()); byte[] data = Hex.decode(input); eng.init(true, pubParameters); try { data = eng.processBlock(data, 0, data.length); } catch (Exception e) { fail("failed - exception " + e.toString(), e); } eng.init(false, privParameters); try { data = eng.processBlock(data, 0, data.length); } catch (Exception e) { fail("failed - exception " + e.toString(), e); } if (!input.equals(new String(Hex.encode(data)))) { fail("failed OAEP Test"); } } private void zeroBlockTest(CipherParameters encParameters, CipherParameters decParameters) { AsymmetricBlockCipher eng = new PKCS1Encoding(new RSAEngine()); eng.init(true, encParameters); if (eng.getOutputBlockSize() != ((PKCS1Encoding)eng).getUnderlyingCipher().getOutputBlockSize()) { fail("PKCS1 output block size incorrect"); } byte[] zero = new byte[0]; byte[] data = null; try { data = eng.processBlock(zero, 0, zero.length); } catch (Exception e) { fail("failed - exception " + e.toString(), e); } eng.init(false, decParameters); try { data = eng.processBlock(data, 0, data.length); } catch (Exception e) { fail("failed - exception " + e.toString(), e); } if (!Arrays.areEqual(zero, data)) { fail("failed PKCS1 zero Test"); } } public void performTest() { RSAKeyParameters pubParameters = new RSAKeyParameters(false, mod, pubExp); RSAKeyParameters privParameters = new RSAPrivateCrtKeyParameters(mod, pubExp, privExp, p, q, pExp, qExp, crtCoef); byte[] data = Hex.decode(edgeInput); // // RAW // AsymmetricBlockCipher eng = new RSAEngine(); eng.init(true, pubParameters); try { data = eng.processBlock(data, 0, data.length); } catch (Exception e) { fail("RSA: failed - exception " + e.toString(), e); } eng.init(false, privParameters); try { data = eng.processBlock(data, 0, data.length); } catch (Exception e) { fail("failed - exception " + e.toString(), e); } if (!edgeInput.equals(new String(Hex.encode(data)))) { fail("failed RAW edge Test"); } data = Hex.decode(input); eng.init(true, pubParameters); try { data = eng.processBlock(data, 0, data.length); } catch (Exception e) { fail("failed - exception " + e.toString(), e); } eng.init(false, privParameters); try { data = eng.processBlock(data, 0, data.length); } catch (Exception e) { fail("failed - exception " + e.toString(), e); } if (!input.equals(new String(Hex.encode(data)))) { fail("failed RAW Test"); } // // PKCS1 - public encrypt, private decrypt // eng = new PKCS1Encoding(eng); eng.init(true, pubParameters); if (eng.getOutputBlockSize() != ((PKCS1Encoding)eng).getUnderlyingCipher().getOutputBlockSize()) { fail("PKCS1 output block size incorrect"); } try { data = eng.processBlock(data, 0, data.length); } catch (Exception e) { fail("failed - exception " + e.toString(), e); } eng.init(false, privParameters); try { data = eng.processBlock(data, 0, data.length); } catch (Exception e) { fail("failed - exception " + e.toString(), e); } if (!input.equals(new String(Hex.encode(data)))) { fail("failed PKCS1 public/private Test"); } // // PKCS1 - private encrypt, public decrypt // eng = new PKCS1Encoding(((PKCS1Encoding)eng).getUnderlyingCipher()); eng.init(true, privParameters); try { data = eng.processBlock(data, 0, data.length); } catch (Exception e) { fail("failed - exception " + e.toString(), e); } eng.init(false, pubParameters); try { data = eng.processBlock(data, 0, data.length); } catch (Exception e) { fail("failed - exception " + e.toString(), e); } if (!input.equals(new String(Hex.encode(data)))) { fail("failed PKCS1 private/public Test"); } zeroBlockTest(pubParameters, privParameters); zeroBlockTest(privParameters, pubParameters); // // key generation test // RSAKeyPairGenerator pGen = new RSAKeyPairGenerator(); RSAKeyGenerationParameters genParam = new RSAKeyGenerationParameters( BigInteger.valueOf(0x11), new SecureRandom(), 768, 25); pGen.init(genParam); AsymmetricCipherKeyPair pair = pGen.generateKeyPair(); eng = new RSAEngine(); if (((RSAKeyParameters)pair.getPublic()).getModulus().bitLength() < 768) { fail("failed key generation (768) length test"); } eng.init(true, pair.getPublic()); try { data = eng.processBlock(data, 0, data.length); } catch (Exception e) { fail("failed - exception " + e.toString(), e); } eng.init(false, pair.getPrivate()); try { data = eng.processBlock(data, 0, data.length); } catch (Exception e) { fail("failed - exception " + e.toString(), e); } if (!input.equals(new String(Hex.encode(data)))) { fail("failed key generation (768) Test"); } genParam = new RSAKeyGenerationParameters(BigInteger.valueOf(0x11), new SecureRandom(), 1024, 25); pGen.init(genParam); pair = pGen.generateKeyPair(); eng.init(true, pair.getPublic()); if (((RSAKeyParameters)pair.getPublic()).getModulus().bitLength() < 1024) { fail("failed key generation (1024) length test"); } try { data = eng.processBlock(data, 0, data.length); } catch (Exception e) { fail("failed - exception " + e.toString(), e); } eng.init(false, pair.getPrivate()); try { data = eng.processBlock(data, 0, data.length); } catch (Exception e) { fail("failed - exception " + e.toString(), e); } if (!input.equals(new String(Hex.encode(data)))) { fail("failed key generation (1024) test"); } genParam = new RSAKeyGenerationParameters( BigInteger.valueOf(0x11), new SecureRandom(), 16, 25); pGen.init(genParam); for (int i = 0; i < 100; ++i) { pair = pGen.generateKeyPair(); RSAPrivateCrtKeyParameters privKey = (RSAPrivateCrtKeyParameters) pair.getPrivate(); BigInteger pqDiff = privKey.getP().subtract(privKey.getQ()).abs(); if (pqDiff.bitLength() < 5) { fail("P and Q too close in RSA key pair"); } } testOAEP(pubParameters, privParameters); testStrictPKCS1Length(pubParameters, privParameters); testDudPKCS1Block(pubParameters, privParameters); testMissingDataPKCS1Block(pubParameters, privParameters); testTruncatedPKCS1Block(pubParameters, privParameters); testWrongPaddingPKCS1Block(pubParameters, privParameters); try { new RSAEngine().processBlock(new byte[]{ 1 }, 0, 1); fail("failed initialisation check"); } catch (IllegalStateException e) { // expected } } public static void main( String[] args) { runTest(new RSATest()); } } bouncycastle-1.49.orig/j2me/org/bouncycastle/crypto/test/RegressionTest.java0000644000175000017500000000325611732470741026706 0ustar ebourgebourgpackage org.bouncycastle.crypto.test; import org.bouncycastle.util.test.Test; import org.bouncycastle.util.test.TestResult; public final class RegressionTest { public static Test[] tests = { new AESTest(), new DESTest(), new DESedeTest(), new ModeTest(), new DHTest(), new ElGamalTest(), new DSATest(), new ECTest(), new ECIESTest(), new MacTest(), new RC2Test(), new RC4Test(), new RC5Test(), new RC6Test(), new RijndaelTest(), new SerpentTest(), new SkipjackTest(), new BlowfishTest(), new TwofishTest(), new CAST5Test(), new CAST6Test(), new IDEATest(), new CamelliaTest(), new RSATest(), new ISO9796Test(), new MD2DigestTest(), new MD4DigestTest(), new MD5DigestTest(), new SHA1DigestTest(), new SHA256DigestTest(), new SHA384DigestTest(), new SHA512DigestTest(), new RIPEMD128DigestTest(), new RIPEMD160DigestTest(), new TigerDigestTest(), new MD5HMacTest(), new SHA1HMacTest(), new RIPEMD128HMacTest(), new RIPEMD160HMacTest(), new OAEPTest(), new PSSTest(), new CTSTest(), new PKCS5Test(), new PKCS12Test(), new GOST28147Test(), new GOST3410Test(), new WhirlpoolDigestTest() }; public static void main( String[] args) { for (int i = 0; i != tests.length; i++) { TestResult result = tests[i].perform(); System.out.println(result); } } } bouncycastle-1.49.orig/j2me/org/bouncycastle/crypto/examples/0000755000175000017500000000000012152033550023702 5ustar ebourgebourgbouncycastle-1.49.orig/j2me/org/bouncycastle/crypto/examples/MIDPTest.java0000644000175000017500000001116511251102140026131 0ustar ebourgebourgpackage org.bouncycastle.crypto.examples; import java.io.*; import java.lang.*; import javax.microedition.midlet.MIDlet; import javax.microedition.lcdui.*; import org.bouncycastle.util.test.*; import org.bouncycastle.util.encoders.*; import org.bouncycastle.crypto.*; import org.bouncycastle.crypto.paddings.*; import org.bouncycastle.crypto.engines.*; import org.bouncycastle.crypto.modes.*; import org.bouncycastle.crypto.params.*; /** * MIDP is a simple graphics application for the J2ME CLDC/MIDP. * * It has hardcoded values for the key and plain text. It also performs the * standard testing for the chosen cipher, and displays the results. * * This example shows how to use the light-weight API and a symmetric cipher. * */ public class MIDPTest extends MIDlet { private Display d = null; private boolean doneEncrypt = false; private String key = "0123456789abcdef0123456789abcdef"; private String plainText = "www.bouncycastle.org"; private byte[] keyBytes = null; private byte[] cipherText = null; private BufferedBlockCipher cipher = null; private String[] cipherNames = {"DES", "DESede", "IDEA", "Rijndael", "Twofish"}; private Form output = null; public void startApp() { Display.getDisplay(this).setCurrent(output); } public void pauseApp() { } public void destroyApp(boolean unconditional) { } public MIDPTest() { output = new Form("BouncyCastle"); output.append("Key: " + key.substring(0, 7) + "...\n"); output.append("In : " + plainText.substring(0, 7) + "...\n"); cipherText = performEncrypt(Hex.decode(key.getBytes()), plainText); String ctS = new String(Hex.encode(cipherText)); output.append("\nCT : " + ctS.substring(0, 7) + "...\n"); String decryptText = performDecrypt(Hex.decode(key.getBytes()), cipherText); output.append("PT : " + decryptText.substring(0, 7) + "...\n"); if (decryptText.compareTo(plainText) == 0) { output.append("Success"); } else { output.append("Failure"); message("[" + plainText + "]"); message("[" + decryptText + "]"); } } private byte[] performEncrypt(byte[] key, String plainText) { byte[] ptBytes = plainText.getBytes(); cipher = new PaddedBufferedBlockCipher(new CBCBlockCipher(getEngineInstance())); String name = cipher.getUnderlyingCipher().getAlgorithmName(); message("Using " + name); cipher.init(true, new KeyParameter(key)); byte[] rv = new byte[cipher.getOutputSize(ptBytes.length)]; int oLen = cipher.processBytes(ptBytes, 0, ptBytes.length, rv, 0); try { cipher.doFinal(rv, oLen); } catch (CryptoException ce) { message("Ooops, encrypt exception"); status(ce.toString()); } return rv; } private String performDecrypt(byte[] key, byte[] cipherText) { cipher.init(false, new KeyParameter(key)); byte[] rv = new byte[cipher.getOutputSize(cipherText.length)]; int oLen = cipher.processBytes(cipherText, 0, cipherText.length, rv, 0); try { cipher.doFinal(rv, oLen); } catch (CryptoException ce) { message("Ooops, decrypt exception"); status(ce.toString()); } return new String(rv).trim(); } private int whichCipher() { return 4; // DES } private BlockCipher getEngineInstance() { // returns a block cipher according to the current // state of the radio button lists. This is only // done prior to encryption. BlockCipher rv = null; switch (whichCipher()) { case 0 : rv = new DESEngine(); break; case 1 : rv = new DESedeEngine(); break; case 2 : rv = new IDEAEngine(); break; case 3 : rv = new RijndaelEngine(); break; case 4 : rv = new TwofishEngine(); break; default : rv = new DESEngine(); break; } return rv; } public void message(String s) { System.out.println("M:" + s); } public void status(String s) { System.out.println("S:" + s); } } bouncycastle-1.49.orig/j2me/org/bouncycastle/crypto/examples/midp_test.jad0000644000175000017500000000032110262753174026361 0ustar ebourgebourgMIDlet-1: MIDPTest, , org.bouncycastle.crypto.examples.MIDPTest MIDlet-Name: MIDPTest MIDlet-Jar-Size: 300000 MIDlet-Jar-URL: midp_test.jar MIDlet-Vendor: The Legion of the Bouncy Castle MIDlet-Version: 1.0.0 bouncycastle-1.49.orig/j2me/org/bouncycastle/crypto/examples/midp_test.mf0000644000175000017500000000036410262753174026234 0ustar ebourgebourgMIDlet-1: MIDPTTest, , org.bouncycastle.crypto.examples.MIDPTest MIDlet-Name: MIDPTest MIDlet-Version: 1.0.0 MIDlet-Vendor: Jon Eaves Created-By: 1.3.1 (Sun Microsystems Inc.) MicroEdition-Configuration: CLDC-1.0 MicroEdition-Profile: MIDP-1.0 bouncycastle-1.49.orig/j2me/org/bouncycastle/asn1/0000755000175000017500000000000012152033550021406 5ustar ebourgebourgbouncycastle-1.49.orig/j2me/org/bouncycastle/asn1/DERUTCTime.java0000644000175000017500000001442411732207626024075 0ustar ebourgebourgpackage org.bouncycastle.asn1; import java.io.IOException; import java.util.Date; import org.bouncycastle.util.Arrays; import org.bouncycastle.util.Strings; /** * UTC time object. */ public class DERUTCTime extends ASN1Primitive { private byte[] time; /** * return an UTC Time from the passed in object. * * @exception IllegalArgumentException if the object cannot be converted. */ public static ASN1UTCTime getInstance( Object obj) { if (obj == null || obj instanceof ASN1UTCTime) { return (ASN1UTCTime)obj; } if (obj instanceof DERUTCTime) { return new ASN1UTCTime(((DERUTCTime)obj).time); } throw new IllegalArgumentException("illegal object in getInstance: " + obj.getClass().getName()); } /** * return an UTC Time from a tagged object. * * @param obj the tagged object holding the object we want * @param explicit true if the object is meant to be explicitly * tagged false otherwise. * @exception IllegalArgumentException if the tagged object cannot * be converted. */ public static ASN1UTCTime getInstance( ASN1TaggedObject obj, boolean explicit) { ASN1Object o = obj.getObject(); if (explicit || o instanceof ASN1UTCTime) { return getInstance(o); } else { return new ASN1UTCTime(((ASN1OctetString)o).getOctets()); } } /** * The correct format for this is YYMMDDHHMMSSZ (it used to be that seconds were * never encoded. When you're creating one of these objects from scratch, that's * what you want to use, otherwise we'll try to deal with whatever gets read from * the input stream... (this is why the input format is different from the getTime() * method output). *

    * * @param time the time string. */ public DERUTCTime( String time) { if (time.charAt(time.length() - 1) != 'Z') { // we accept this as a variation if (time.indexOf('-') < 0 && time.indexOf('+') < 0) { throw new IllegalArgumentException("time needs to be in format YYMMDDHHMMSSZ"); } } this.time = Strings.toByteArray(time); } /** * base constructor from a java.util.date object */ public DERUTCTime( Date time) { this.time = Strings.toByteArray(DateFormatter.toUTCDateString(time)); } DERUTCTime( byte[] time) { this.time = time; } /** * return the time as a date based on whatever a 2 digit year will return. For * standardised processing use getAdjustedDate(). * * @return the resulting date */ public Date getDate() { return DateFormatter.adjustedFromUTCDateString(time); } /** * return the time as an adjusted date * in the range of 1950 - 2049. * * @return a date in the range of 1950 to 2049. */ public Date getAdjustedDate() { return DateFormatter.adjustedFromUTCDateString(time); } /** * return the time - always in the form of * YYMMDDhhmmssGMT(+hh:mm|-hh:mm). *

    * Normally in a certificate we would expect "Z" rather than "GMT", * however adding the "GMT" means we can just use: *

         *     dateF = new SimpleDateFormat("yyMMddHHmmssz");
         * 
    * To read in the time and get a date which is compatible with our local * time zone. *

    * Note: In some cases, due to the local date processing, this * may lead to unexpected results. If you want to stick the normal * convention of 1950 to 2049 use the getAdjustedTime() method. */ public String getTime() { String stime = Strings.fromByteArray(time); // // standardise the format. // if (stime.indexOf('-') < 0 && stime.indexOf('+') < 0) { if (stime.length() == 11) { return stime.substring(0, 10) + "00GMT+00:00"; } else { return stime.substring(0, 12) + "GMT+00:00"; } } else { int index = stime.indexOf('-'); if (index < 0) { index = stime.indexOf('+'); } String d = stime; if (index == stime.length() - 3) { d += "00"; } if (index == 10) { return d.substring(0, 10) + "00GMT" + d.substring(10, 13) + ":" + d.substring(13, 15); } else { return d.substring(0, 12) + "GMT" + d.substring(12, 15) + ":" + d.substring(15, 17); } } } /** * return a time string as an adjusted date with a 4 digit year. This goes * in the range of 1950 - 2049. */ public String getAdjustedTime() { String d = this.getTime(); if (d.charAt(0) < '5') { return "20" + d; } else { return "19" + d; } } /** * Return the time. * @return The time string as it appeared in the encoded object. */ public String getTimeString() { return Strings.fromByteArray(time); } boolean isConstructed() { return false; } int encodedLength() { int length = time.length; return 1 + StreamUtil.calculateBodyLength(length) + length; } void encode( ASN1OutputStream out) throws IOException { out.write(BERTags.UTC_TIME); int length = time.length; out.writeLength(length); for (int i = 0; i != length; i++) { out.write((byte)time[i]); } } boolean asn1Equals( ASN1Primitive o) { if (!(o instanceof DERUTCTime)) { return false; } return Arrays.areEqual(time, ((DERUTCTime)o).time); } public int hashCode() { return Arrays.hashCode(time); } public String toString() { return Strings.fromByteArray(time); } } bouncycastle-1.49.orig/j2me/org/bouncycastle/asn1/DERGeneralizedTime.java0000644000175000017500000001540711732211460025664 0ustar ebourgebourgpackage org.bouncycastle.asn1; import java.io.IOException; import java.util.Date; import java.util.TimeZone; import org.bouncycastle.util.Arrays; import org.bouncycastle.util.Strings; /** * Generalized time object. */ public class DERGeneralizedTime extends ASN1Primitive { private byte[] time; /** * return a generalized time from the passed in object * * @exception IllegalArgumentException if the object cannot be converted. */ public static ASN1GeneralizedTime getInstance( Object obj) { if (obj == null || obj instanceof ASN1GeneralizedTime) { return (ASN1GeneralizedTime)obj; } if (obj instanceof DERGeneralizedTime) { return new ASN1GeneralizedTime(((DERGeneralizedTime)obj).time); } throw new IllegalArgumentException("illegal object in getInstance: " + obj.getClass().getName()); } /** * return a Generalized Time object from a tagged object. * * @param obj the tagged object holding the object we want * @param explicit true if the object is meant to be explicitly * tagged false otherwise. * @exception IllegalArgumentException if the tagged object cannot * be converted. */ public static ASN1GeneralizedTime getInstance( ASN1TaggedObject obj, boolean explicit) { ASN1Primitive o = obj.getObject(); if (explicit || o instanceof DERGeneralizedTime) { return getInstance(o); } else { return new ASN1GeneralizedTime(((ASN1OctetString)o).getOctets()); } } /** * The correct format for this is YYYYMMDDHHMMSS[.f]Z, or without the Z * for local time, or Z|[+|-]HHMM on the end, for difference between local * time and UTC time. The fractional second amount f must consist of at * least one number with trailing zeroes removed. * * @param time the time string. * @exception IllegalArgumentException if String is an illegal format. */ public DERGeneralizedTime( String time) { char last = time.charAt(time.length() - 1); if (last != 'Z' && !(last >= 0 && last <= '9')) { if (time.indexOf('-') < 0 && time.indexOf('+') < 0) { throw new IllegalArgumentException("time needs to be in format YYYYMMDDHHMMSS[.f]Z or YYYYMMDDHHMMSS[.f][+-]HHMM"); } } this.time = Strings.toByteArray(time); } /** * base constructer from a java.util.date object */ public DERGeneralizedTime( Date time) { this.time = Strings.toByteArray(DateFormatter.getGeneralizedTimeDateString(time, false)); } protected DERGeneralizedTime(Date date, boolean includeMillis) { this.time = Strings.toByteArray(DateFormatter.getGeneralizedTimeDateString(date, true)); } DERGeneralizedTime( byte[] bytes) { this.time = bytes; } /** * Return the time. * @return The time string as it appeared in the encoded object. */ public String getTimeString() { return Strings.fromByteArray(time); } /** * return the time - always in the form of * YYYYMMDDhhmmssGMT(+hh:mm|-hh:mm). *

    * Normally in a certificate we would expect "Z" rather than "GMT", * however adding the "GMT" means we can just use: *

         *     dateF = new SimpleDateFormat("yyyyMMddHHmmssz");
         * 
    * To read in the time and get a date which is compatible with our local * time zone. */ public String getTime() { String stime = Strings.fromByteArray(time); // // standardise the format. // if (stime.charAt(stime.length() - 1) == 'Z') { return stime.substring(0, stime.length() - 1) + "GMT+00:00"; } else { int signPos = stime.length() - 5; char sign = stime.charAt(signPos); if (sign == '-' || sign == '+') { return stime.substring(0, signPos) + "GMT" + stime.substring(signPos, signPos + 3) + ":" + stime.substring(signPos + 3); } else { signPos = stime.length() - 3; sign = stime.charAt(signPos); if (sign == '-' || sign == '+') { return stime.substring(0, signPos) + "GMT" + stime.substring(signPos) + ":00"; } } } return stime + calculateGMTOffset(); } private String calculateGMTOffset() { String sign = "+"; TimeZone timeZone = TimeZone.getDefault(); int offset = timeZone.getRawOffset(); if (offset < 0) { sign = "-"; offset = -offset; } int hours = offset / (60 * 60 * 1000); int minutes = (offset - (hours * 60 * 60 * 1000)) / (60 * 1000); // try // { // if (timeZone.useDaylightTime() && timeZone.inDaylightTime(this.getDate())) // { // hours += sign.equals("+") ? 1 : -1; // } // } // catch (ParseException e) // { // // we'll do our best and ignore daylight savings // } return "GMT" + sign + convert(hours) + ":" + convert(minutes); } private String convert(int time) { if (time < 10) { return "0" + time; } return Integer.toString(time); } public Date getDate() { return DateFormatter.fromGeneralizedTimeString(time); } private boolean hasFractionalSeconds() { for (int i = 0; i != time.length; i++) { if (time[i] == '.') { if (i == 14) { return true; } } } return false; } boolean isConstructed() { return false; } int encodedLength() { int length = time.length; return 1 + StreamUtil.calculateBodyLength(length) + length; } void encode( ASN1OutputStream out) throws IOException { out.writeEncoded(BERTags.GENERALIZED_TIME, time); } boolean asn1Equals( ASN1Primitive o) { if (!(o instanceof DERGeneralizedTime)) { return false; } return Arrays.areEqual(time, ((DERGeneralizedTime)o).time); } public int hashCode() { return Arrays.hashCode(time); } } bouncycastle-1.49.orig/j2me/org/bouncycastle/asn1/StreamUtil.java0000644000175000017500000000352011731536451024354 0ustar ebourgebourgpackage org.bouncycastle.asn1; import java.io.ByteArrayInputStream; import java.io.IOException; import java.io.InputStream; class StreamUtil { /** * Find out possible longest length... * * @param in input stream of interest * @return length calculation or MAX_VALUE. */ static int findLimit(InputStream in) { if (in instanceof LimitedInputStream) { return ((LimitedInputStream)in).getRemaining(); } else if (in instanceof ASN1InputStream) { return ((ASN1InputStream)in).getLimit(); } else if (in instanceof ByteArrayInputStream) { return ((ByteArrayInputStream)in).available(); } return Integer.MAX_VALUE; } static int calculateBodyLength( int length) { int count = 1; if (length > 127) { int size = 1; int val = length; while ((val >>>= 8) != 0) { size++; } for (int i = (size - 1) * 8; i >= 0; i -= 8) { count++; } } return count; } static int calculateTagLength(int tagNo) throws IOException { int length = 1; if (tagNo >= 31) { if (tagNo < 128) { length++; } else { byte[] stack = new byte[5]; int pos = stack.length; stack[--pos] = (byte)(tagNo & 0x7F); do { tagNo >>= 7; stack[--pos] = (byte)(tagNo & 0x7F | 0x80); } while (tagNo > 127); length += stack.length - pos; } } return length; } } bouncycastle-1.49.orig/j2me/org/bouncycastle/asn1/DateFormatter.java0000644000175000017500000001532111732211675025025 0ustar ebourgebourgpackage org.bouncycastle.asn1; import java.util.Calendar; import java.util.Date; import java.util.TimeZone; class DateFormatter { // YYMMDDHHMMSSZ static String toUTCDateString(Date date) { Calendar calendar = Calendar.getInstance(TimeZone.getTimeZone("GMT")); calendar.setTime(date); return format2Year(calendar.get(Calendar.YEAR)) + format2(calendar.get(Calendar.MONTH) + 1) + format2(calendar.get(Calendar.DAY_OF_MONTH)) + format2(calendar.get(Calendar.HOUR_OF_DAY)) + format2(calendar.get(Calendar.MINUTE)) + format2(calendar.get(Calendar.SECOND)) + "Z"; } static Date adjustedFromUTCDateString(byte[] date) { Calendar calendar = Calendar.getInstance(TimeZone.getTimeZone("GMT")); int year = toInt2(date, 0); if (year < 50) { year += 2000; } else { year += 1900; } calendar.setTimeZone(TimeZone.getTimeZone("GMT")); calendar.set(Calendar.YEAR, year); calendar.set(Calendar.MONTH, toInt2(date, 2) - 1); calendar.set(Calendar.DAY_OF_MONTH, toInt2(date, 4)); calendar.set(Calendar.HOUR_OF_DAY, toInt2(date, 6)); calendar.set(Calendar.MINUTE, toInt2(date, 8)); int tzChar = 10; if (isNumber(date, tzChar)) { calendar.set(Calendar.SECOND, toInt2(date, 10)); tzChar = 12; } else { calendar.set(Calendar.SECOND, 0); } calendar.set(Calendar.MILLISECOND, 0); if (date[tzChar] != 'Z') { int hoursOff = 0; int minutesOff = 0; hoursOff = toInt2(date, tzChar + 1) * 60 * 60 * 1000; if (date.length > tzChar + 3) { minutesOff = toInt2(date, tzChar + 3) * 60 * 1000; } if (date[tzChar] == '-') { return new Date(calendar.getTime().getTime() + hoursOff + minutesOff); } else { return new Date(calendar.getTime().getTime() - (hoursOff + minutesOff)); } } return calendar.getTime(); } static String getGeneralizedTimeDateString(Date date, boolean includeMillis) { Calendar calendar = Calendar.getInstance(TimeZone.getTimeZone("GMT")); calendar.setTime(date); String time = format4Year(calendar.get(Calendar.YEAR)) + format2(calendar.get(Calendar.MONTH) + 1) + format2(calendar.get(Calendar.DAY_OF_MONTH)) + format2(calendar.get(Calendar.HOUR_OF_DAY)) + format2(calendar.get(Calendar.MINUTE)) + format2(calendar.get(Calendar.SECOND)); if (includeMillis) { time += "." + format3(calendar.get(Calendar.MILLISECOND)); } return time + "Z"; } static Date fromGeneralizedTimeString(byte[] date) { Calendar calendar = Calendar.getInstance(TimeZone.getTimeZone("GMT")); int year = toInt4(date, 0); if (isLocalTime(date)) { calendar.setTimeZone(TimeZone.getTimeZone("GMT")); } calendar.set(Calendar.YEAR, year); calendar.set(Calendar.MONTH, toInt2(date, 4) - 1); calendar.set(Calendar.DAY_OF_MONTH, toInt2(date, 6)); calendar.set(Calendar.HOUR_OF_DAY, toInt2(date, 8)); calendar.set(Calendar.MINUTE, toInt2(date, 10)); int tzChar = 12; if (isNumber(date, tzChar)) { calendar.set(Calendar.SECOND, toInt2(date, 12)); tzChar = 14; } else { calendar.set(Calendar.SECOND, 0); } if (tzChar != date.length && date[tzChar] == '.') { int millis = 0; tzChar++; if (isNumber(date, tzChar)) { millis = (date[tzChar] - '0') * 100; tzChar++; } if (tzChar != date.length && isNumber(date, tzChar)) { millis += (date[tzChar] - '0') * 10; tzChar++; } if (tzChar != date.length && isNumber(date, tzChar)) { millis += (date[tzChar] - '0'); tzChar++; } calendar.set(Calendar.MILLISECOND, millis); } else { calendar.set(Calendar.MILLISECOND, 0); } // skip nano-seconds while (tzChar != date.length && isNumber(date, tzChar)) { tzChar++; } if (tzChar != date.length && date[tzChar] != 'Z') { int hoursOff = 0; int minutesOff = 0; hoursOff = toInt2(date, tzChar + 1) * 60 * 60 * 1000; if (date.length > tzChar + 3) { minutesOff = toInt2(date, tzChar + 3) * 60 * 1000; } if (date[tzChar] == '-') { return new Date(calendar.getTime().getTime() + hoursOff + minutesOff); } else { return new Date(calendar.getTime().getTime() - (hoursOff + minutesOff)); } } return calendar.getTime(); } private static String format2(int v) { if (v < 10) { return "0" + v; } return Integer.toString(v); } private static String format2Year(int v) { if (v > 2000) { v = v - 2000; } else { v = v - 1900; } return format2(v); } private static String format3(int v) { if (v < 10) { return "00" + v; } if (v < 100) { return "0" + v; } return Integer.toString(v); } private static String format4Year(int v) { if (v < 10) { return "000" + v; } if (v < 100) { return "00" + v; } if (v < 1000) { return "0" + v; } return Integer.toString(v); } private static boolean isNumber(byte[] input, int off) { byte b = input[off]; return (b >= '0') && (b <= '9'); } private static boolean isLocalTime(byte[] date) { for (int i = date.length - 1; i > date.length - 6; i--) { if (date[i] == 'Z' || date[i] == '-' || date[i] == '+') { return false; } } return true; } private static int toInt2(byte[] input, int off) { return (input[off] - '0') * 10 + (input[off + 1] - '0'); } private static int toInt4(byte[] input, int off) { return toInt2(input, off) * 100 + toInt2(input, off + 2) ; } } bouncycastle-1.49.orig/j2me/org/bouncycastle/asn1/ASN1UTCTime.java0000644000175000017500000000046611732003253024154 0ustar ebourgebourgpackage org.bouncycastle.asn1; import java.util.Date; public class ASN1UTCTime extends DERUTCTime { ASN1UTCTime(byte[] bytes) { super(bytes); } public ASN1UTCTime(Date date) { super(date); } public ASN1UTCTime(String time) { super(time); } } bouncycastle-1.49.orig/j2me/org/bouncycastle/asn1/cms/0000755000175000017500000000000012152033550022170 5ustar ebourgebourgbouncycastle-1.49.orig/j2me/org/bouncycastle/asn1/cms/Time.java0000644000175000017500000000543511731760106023746 0ustar ebourgebourgpackage org.bouncycastle.asn1.cms; import java.util.Calendar; import java.util.Date; import org.bouncycastle.asn1.ASN1Choice; import org.bouncycastle.asn1.ASN1Object; import org.bouncycastle.asn1.ASN1Primitive; import org.bouncycastle.asn1.ASN1TaggedObject; import org.bouncycastle.asn1.DERGeneralizedTime; import org.bouncycastle.asn1.DERUTCTime; public class Time extends ASN1Object implements ASN1Choice { ASN1Primitive time; public static Time getInstance( ASN1TaggedObject obj, boolean explicit) { return getInstance(obj.getObject()); // must be explicitly tagged } public Time( ASN1Primitive time) { if (!(time instanceof DERUTCTime) && !(time instanceof DERGeneralizedTime)) { throw new IllegalArgumentException("unknown object passed to Time"); } this.time = time; } /** * creates a time object from a given date - if the date is between 1950 * and 2049 a UTCTime object is generated, otherwise a GeneralizedTime * is used. */ public Time( Date date) { Calendar calendar = Calendar.getInstance(); calendar.setTime(date); int year = calendar.get(Calendar.YEAR); if (year < 1950 || year > 2049) { time = new DERGeneralizedTime(date); } else { time = new DERUTCTime(date); } } public static Time getInstance( Object obj) { if (obj == null || obj instanceof Time) { return (Time)obj; } else if (obj instanceof DERUTCTime) { return new Time((DERUTCTime)obj); } else if (obj instanceof DERGeneralizedTime) { return new Time((DERGeneralizedTime)obj); } throw new IllegalArgumentException("unknown object in factory: " + obj.getClass().getName()); } public String getTime() { if (time instanceof DERUTCTime) { return ((DERUTCTime)time).getAdjustedTime(); } else { return ((DERGeneralizedTime)time).getTime(); } } public Date getDate() { if (time instanceof DERUTCTime) { return ((DERUTCTime)time).getAdjustedDate(); } else { return ((DERGeneralizedTime)time).getDate(); } } /** * Produce an object suitable for an ASN1OutputStream. *
         * Time ::= CHOICE {
         *             utcTime        UTCTime,
         *             generalTime    GeneralizedTime }
         * 
    */ public ASN1Primitive toASN1Primitive() { return time; } public String toString() { return getTime(); } } bouncycastle-1.49.orig/j2me/org/bouncycastle/asn1/eac/0000755000175000017500000000000012152033550022136 5ustar ebourgebourgbouncycastle-1.49.orig/j2me/org/bouncycastle/asn1/eac/PackedDate.java0000644000175000017500000000230011731536015024767 0ustar ebourgebourgpackage org.bouncycastle.asn1.eac; import org.bouncycastle.util.Arrays; /** * EAC encoding date object */ public class PackedDate { private byte[] time; public PackedDate( String time) { this.time = convert(time); } private byte[] convert(String sTime) { char[] digs = sTime.toCharArray(); byte[] date = new byte[6]; for (int i = 0; i != 6; i++) { date[i] = (byte)(digs[i] - '0'); } return date; } PackedDate( byte[] bytes) { this.time = bytes; } public int hashCode() { return Arrays.hashCode(time); } public boolean equals(Object o) { if (!(o instanceof PackedDate)) { return false; } PackedDate other = (PackedDate)o; return Arrays.areEqual(time, other.time); } public String toString() { char[] dateC = new char[time.length]; for (int i = 0; i != dateC.length; i++) { dateC[i] = (char)((time[i] & 0xff) + '0'); } return new String(dateC); } public byte[] getEncoding() { return time; } } bouncycastle-1.49.orig/j2me/org/bouncycastle/asn1/x509/0000755000175000017500000000000012152033550022113 5ustar ebourgebourgbouncycastle-1.49.orig/j2me/org/bouncycastle/asn1/x509/Time.java0000644000175000017500000000543611731760043023672 0ustar ebourgebourgpackage org.bouncycastle.asn1.x509; import java.util.Calendar; import java.util.Date; import org.bouncycastle.asn1.ASN1Choice; import org.bouncycastle.asn1.ASN1Object; import org.bouncycastle.asn1.ASN1Primitive; import org.bouncycastle.asn1.ASN1TaggedObject; import org.bouncycastle.asn1.DERGeneralizedTime; import org.bouncycastle.asn1.DERUTCTime; public class Time extends ASN1Object implements ASN1Choice { ASN1Primitive time; public static Time getInstance( ASN1TaggedObject obj, boolean explicit) { return getInstance(obj.getObject()); // must be explicitly tagged } public Time( ASN1Primitive time) { if (!(time instanceof DERUTCTime) && !(time instanceof DERGeneralizedTime)) { throw new IllegalArgumentException("unknown object passed to Time"); } this.time = time; } /** * creates a time object from a given date - if the date is between 1950 * and 2049 a UTCTime object is generated, otherwise a GeneralizedTime * is used. */ public Time( Date date) { Calendar calendar = Calendar.getInstance(); calendar.setTime(date); int year = calendar.get(Calendar.YEAR); if (year < 1950 || year > 2049) { time = new DERGeneralizedTime(date); } else { time = new DERUTCTime(date); } } public static Time getInstance( Object obj) { if (obj == null || obj instanceof Time) { return (Time)obj; } else if (obj instanceof DERUTCTime) { return new Time((DERUTCTime)obj); } else if (obj instanceof DERGeneralizedTime) { return new Time((DERGeneralizedTime)obj); } throw new IllegalArgumentException("unknown object in factory: " + obj.getClass().getName()); } public String getTime() { if (time instanceof DERUTCTime) { return ((DERUTCTime)time).getAdjustedTime(); } else { return ((DERGeneralizedTime)time).getTime(); } } public Date getDate() { if (time instanceof DERUTCTime) { return ((DERUTCTime)time).getAdjustedDate(); } else { return ((DERGeneralizedTime)time).getDate(); } } /** * Produce an object suitable for an ASN1OutputStream. *
         * Time ::= CHOICE {
         *             utcTime        UTCTime,
         *             generalTime    GeneralizedTime }
         * 
    */ public ASN1Primitive toASN1Primitive() { return time; } public String toString() { return getTime(); } } bouncycastle-1.49.orig/j2me/org/bouncycastle/asn1/test/0000755000175000017500000000000012152033550022365 5ustar ebourgebourgbouncycastle-1.49.orig/j2me/org/bouncycastle/asn1/test/UTCTimeTest.java0000644000175000017500000000461111732212223025343 0ustar ebourgebourgpackage org.bouncycastle.asn1.test; import org.bouncycastle.asn1.ASN1UTCTime; import org.bouncycastle.asn1.DERUTCTime; import org.bouncycastle.util.test.SimpleTest; /** * X.690 test example */ public class UTCTimeTest extends SimpleTest { String[] input = { "020122122220Z", "020122122220-1000", "020122122220+1000", "020122122220+00", "0201221222Z", "0201221222-1000", "0201221222+1000", "0201221222+00", "550122122220Z", "5501221222Z" }; String[] output = { "20020122122220GMT+00:00", "20020122122220GMT-10:00", "20020122122220GMT+10:00", "20020122122220GMT+00:00", "20020122122200GMT+00:00", "20020122122200GMT-10:00", "20020122122200GMT+10:00", "20020122122200GMT+00:00", "19550122122220GMT+00:00", "19550122122200GMT+00:00" }; String[] zOutput1 = { "20020122122220Z", "20020122222220Z", "20020122022220Z", "20020122122220Z", "20020122122200Z", "20020122222200Z", "20020122022200Z", "20020122122200Z", "19550122122220Z", "19550122122200Z" }; String[] zOutput2 = { "20020122122220Z", "20020122222220Z", "20020122022220Z", "20020122122220Z", "20020122122200Z", "20020122222200Z", "20020122022200Z", "20020122122200Z", "19550122122220Z", "19550122122200Z" }; public String getName() { return "UTCTime"; } public void performTest() throws Exception { for (int i = 0; i != input.length; i++) { DERUTCTime t = new DERUTCTime(input[i]); if (!t.getAdjustedTime().equals(output[i])) { fail("failed conversion test " + i); } t = new ASN1UTCTime(zOutput1[i].substring(2)); if (!new ASN1UTCTime(t.getAdjustedDate()).getAdjustedTime().equals(t.getAdjustedTime())) { fail("failed equality test"); } } } public static void main( String[] args) { runTest(new UTCTimeTest()); } } bouncycastle-1.49.orig/j2me/org/bouncycastle/asn1/test/GeneralizedTimeTest.java0000644000175000017500000001234311732212171027144 0ustar ebourgebourgpackage org.bouncycastle.asn1.test; import java.util.Date; import java.util.TimeZone; import org.bouncycastle.asn1.ASN1GeneralizedTime; import org.bouncycastle.asn1.DERGeneralizedTime; import org.bouncycastle.util.test.SimpleTest; /** * X.690 test example */ public class GeneralizedTimeTest extends SimpleTest { String[] input = { "20020122122220", "20020122122220Z", "20020122122220-1000", "20020122122220+00", "20020122122220.1", "20020122122220.1Z", "20020122122220.1-1000", "20020122122220.1+00", "20020122122220.01", "20020122122220.01Z", "20020122122220.01-1000", "20020122122220.01+00", "20020122122220.001", "20020122122220.001Z", "20020122122220.001-1000", "20020122122220.001+00", "20020122122220.0001", "20020122122220.0001Z", "20020122122220.0001-1000", "20020122122220.0001+00", "20020122122220.0001+1000" }; String[] output = { "20020122122220", "20020122122220GMT+00:00", "20020122122220GMT-10:00", "20020122122220GMT+00:00", "20020122122220.1", "20020122122220.1GMT+00:00", "20020122122220.1GMT-10:00", "20020122122220.1GMT+00:00", "20020122122220.01", "20020122122220.01GMT+00:00", "20020122122220.01GMT-10:00", "20020122122220.01GMT+00:00", "20020122122220.001", "20020122122220.001GMT+00:00", "20020122122220.001GMT-10:00", "20020122122220.001GMT+00:00", "20020122122220.0001", "20020122122220.0001GMT+00:00", "20020122122220.0001GMT-10:00", "20020122122220.0001GMT+00:00", "20020122122220.0001GMT+10:00" }; String[] zOutput = { "20020122122220Z", "20020122122220Z", "20020122222220Z", "20020122122220Z", "20020122122220Z", "20020122122220Z", "20020122222220Z", "20020122122220Z", "20020122122220Z", "20020122122220Z", "20020122222220Z", "20020122122220Z", "20020122122220Z", "20020122122220Z", "20020122222220Z", "20020122122220Z", "20020122122220Z", "20020122122220Z", "20020122222220Z", "20020122122220Z", "20020122022220Z" }; String[] mzOutput = { "20020122122220.000Z", "20020122122220.000Z", "20020122222220.000Z", "20020122122220.000Z", "20020122122220.100Z", "20020122122220.100Z", "20020122222220.100Z", "20020122122220.100Z", "20020122122220.010Z", "20020122122220.010Z", "20020122222220.010Z", "20020122122220.010Z", "20020122122220.001Z", "20020122122220.001Z", "20020122222220.001Z", "20020122122220.001Z", "20020122122220.000Z", "20020122122220.000Z", "20020122222220.000Z", "20020122122220.000Z", "20020122022220.000Z" }; public String getName() { return "GeneralizedTime"; } public void performTest() throws Exception { for (int i = 0; i != input.length; i++) { DERGeneralizedTime t = new DERGeneralizedTime(input[i]); if (output[i].indexOf('G') > 0) // don't check local time the same way { if (!t.getTime().equals(output[i])) { fail("failed conversion test"); } } else { String offset = calculateGMTOffset(t.getDate()); if (!t.getTime().equals(output[i] + offset)) { fail("failed conversion test"); } } } for (int i = 0; i != input.length; i++) { ASN1GeneralizedTime t = new ASN1GeneralizedTime(mzOutput[i]); if (!new ASN1GeneralizedTime(t.getDate(), true).getDate().equals(t.getDate())) { fail("failed equality test"); } } } private String calculateGMTOffset(Date date) { String sign = "+"; TimeZone timeZone = TimeZone.getDefault(); int offset = timeZone.getRawOffset(); if (offset < 0) { sign = "-"; offset = -offset; } int hours = offset / (60 * 60 * 1000); int minutes = (offset - (hours * 60 * 60 * 1000)) / (60 * 1000); // if (timeZone.useDaylightTime() && timeZone.inDaylightTime(date)) // { // hours += sign.equals("+") ? 1 : -1; // } return "GMT" + sign + convert(hours) + ":" + convert(minutes); } private String convert(int time) { if (time < 10) { return "0" + time; } return Integer.toString(time); } public static void main( String[] args) { runTest(new GeneralizedTimeTest()); } } bouncycastle-1.49.orig/j2me/org/bouncycastle/asn1/test/RegressionTest.java0000644000175000017500000000342712105426345026224 0ustar ebourgebourgpackage org.bouncycastle.asn1.test; import org.bouncycastle.util.test.Test; import org.bouncycastle.util.test.TestResult; public class RegressionTest { public static Test[] tests = { new CertificateTest(), new CMSTest(), new OCSPTest(), new OIDTest(), new PKCS10Test(), new PKCS12Test(), new X509NameTest(), new X500NameTest(), new X509ExtensionsTest(), new BitStringTest(), new MiscTest(), new X9Test(), new EncryptedPrivateKeyInfoTest(), new StringTest(), new RequestedCertificateUnitTest(), new OtherCertIDUnitTest(), new OtherSigningCertificateUnitTest(), new ContentHintsUnitTest(), new CertHashUnitTest(), new AdditionalInformationSyntaxUnitTest(), new AdmissionSyntaxUnitTest(), new AdmissionsUnitTest(), new DeclarationOfMajorityUnitTest(), new ProcurationSyntaxUnitTest(), new ProfessionInfoUnitTest(), new RestrictionUnitTest(), new NamingAuthorityUnitTest(), new MonetaryLimitUnitTest(), new DERApplicationSpecificTest(), new IssuingDistributionPointUnitTest(), new TargetInformationTest(), new SubjectKeyIdentifierTest(), new ESSCertIDv2UnitTest(), new ParsingTest(), new GeneralNameTest(), new RFC4519Test() }; public static void main( String[] args) { for (int i = 0; i != tests.length; i++) { TestResult result = tests[i].perform(); if (result.getException() != null) { result.getException().printStackTrace(); } System.out.println(result); } } } bouncycastle-1.49.orig/j2me/org/bouncycastle/asn1/DERFactory.java0000644000175000017500000000113411731517453024225 0ustar ebourgebourgpackage org.bouncycastle.asn1; class DERFactory { static final ASN1Sequence EMPTY_SEQUENCE = new DERSequence(); static final ASN1Set EMPTY_SET = new DERSet(); static ASN1Sequence createSequence(ASN1EncodableVector v) { if (v.size() < 1) { return EMPTY_SEQUENCE; } else { return new DLSequence(v); } } static ASN1Set createSet(ASN1EncodableVector v) { if (v.size() < 1) { return EMPTY_SET; } else { return new DLSet(v); } } } bouncycastle-1.49.orig/j2me/org/bouncycastle/asn1/ASN1GeneralizedTime.java0000644000175000017500000000072011732211460025744 0ustar ebourgebourgpackage org.bouncycastle.asn1; import java.util.Date; public class ASN1GeneralizedTime extends DERGeneralizedTime { ASN1GeneralizedTime(byte[] bytes) { super(bytes); } public ASN1GeneralizedTime(Date date) { super(date); } public ASN1GeneralizedTime(Date date, boolean includeMillis) { super(date, includeMillis); } public ASN1GeneralizedTime(String time) { super(time); } } bouncycastle-1.49.orig/j2me/org/bouncycastle/util/0000755000175000017500000000000012152033550021521 5ustar ebourgebourgbouncycastle-1.49.orig/j2me/org/bouncycastle/util/Selector.java0000644000175000017500000000016211731760737024163 0ustar ebourgebourgpackage org.bouncycastle.util; public interface Selector { boolean match(Object obj); Object clone(); } bouncycastle-1.49.orig/j2me/org/bouncycastle/util/test/0000755000175000017500000000000012152033550022500 5ustar ebourgebourgbouncycastle-1.49.orig/j2me/org/bouncycastle/util/test/SimpleTest.java0000644000175000017500000000344010355150016025435 0ustar ebourgebourgpackage org.bouncycastle.util.test; import java.io.PrintStream; import org.bouncycastle.util.Arrays; public abstract class SimpleTest implements Test { public abstract String getName(); private TestResult success() { return SimpleTestResult.successful(this, "Okay"); } protected void fail( String message) { throw new TestFailedException(SimpleTestResult.failed(this, message)); } protected void fail( String message, Throwable throwable) { throw new TestFailedException(SimpleTestResult.failed(this, message, throwable)); } protected void fail( String message, Object expected, Object found) { throw new TestFailedException(SimpleTestResult.failed(this, message, expected, found)); } protected boolean areEqual( byte[] a, byte[] b) { return Arrays.areEqual(a, b); } public TestResult perform() { try { performTest(); return success(); } catch (TestFailedException e) { return e.getResult(); } catch (Exception e) { return SimpleTestResult.failed(this, "Exception: " + e, e); } } protected static void runTest( Test test) { runTest(test, System.out); } protected static void runTest( Test test, PrintStream out) { TestResult result = test.perform(); out.println(result.toString()); if (result.getException() != null) { result.getException().printStackTrace(); } } public abstract void performTest() throws Exception; } bouncycastle-1.49.orig/j2me/org/bouncycastle/util/Integers.java0000644000175000017500000000022612105426036024147 0ustar ebourgebourgpackage org.bouncycastle.util; public class Integers { public static Integer valueOf(int value) { return new Integer(value); } } bouncycastle-1.49.orig/j2me/org/bouncycastle/cert/0000755000175000017500000000000012152033550021501 5ustar ebourgebourgbouncycastle-1.49.orig/j2me/org/bouncycastle/cert/crmf/0000755000175000017500000000000012152033550022430 5ustar ebourgebourgbouncycastle-1.49.orig/j2me/org/bouncycastle/cert/crmf/FixedLengthMGF1Padder.java0000644000175000017500000000617511732500421027237 0ustar ebourgebourgpackage org.bouncycastle.cert.crmf; import java.security.SecureRandom; import org.bouncycastle.crypto.Digest; import org.bouncycastle.crypto.digests.SHA1Digest; import org.bouncycastle.crypto.generators.MGF1BytesGenerator; import org.bouncycastle.crypto.params.MGFParameters; /** * An encrypted value padder that uses MGF1 as the basis of the padding. */ public class FixedLengthMGF1Padder implements EncryptedValuePadder { private int length; private SecureRandom random; private Digest dig = new SHA1Digest(); /** * Create a padder to so that padded output will always be at least * length bytes long. * * @param length fixed length for padded output. */ public FixedLengthMGF1Padder(int length) { this(length, null); } /** * Create a padder to so that padded output will always be at least * length bytes long, using the passed in source of randomness to * provide the random material for the padder. * * @param length fixed length for padded output. * @param random a source of randomness. */ public FixedLengthMGF1Padder(int length, SecureRandom random) { this.length = length; this.random = random; } public byte[] getPaddedData(byte[] data) { byte[] bytes = new byte[length]; byte[] seed = new byte[dig.getDigestSize()]; byte[] mask = new byte[length - dig.getDigestSize()]; if (random == null) { random = new SecureRandom(); } random.nextBytes(seed); MGF1BytesGenerator maskGen = new MGF1BytesGenerator(dig); maskGen.init(new MGFParameters(seed)); maskGen.generateBytes(mask, 0, mask.length); System.arraycopy(seed, 0, bytes, 0, seed.length); System.arraycopy(data, 0, bytes, seed.length, data.length); for (int i = seed.length + data.length + 1; i != bytes.length; i++) { bytes[i] = (byte)(1 | (random.nextInt() & 0xff)); } for (int i = 0; i != mask.length; i++) { bytes[i + seed.length] ^= mask[i]; } return bytes; } public byte[] getUnpaddedData(byte[] paddedData) { byte[] seed = new byte[dig.getDigestSize()]; byte[] mask = new byte[length - dig.getDigestSize()]; System.arraycopy(paddedData, 0, seed, 0, seed.length); MGF1BytesGenerator maskGen = new MGF1BytesGenerator(dig); maskGen.init(new MGFParameters(seed)); maskGen.generateBytes(mask, 0, mask.length); for (int i = 0; i != mask.length; i++) { paddedData[i + seed.length] ^= mask[i]; } int end = 0; for (int i = paddedData.length - 1; i != seed.length; i--) { if (paddedData[i] == 0) { end = i; break; } } if (end == 0) { throw new IllegalStateException("bad padding in encoding"); } byte[] data = new byte[end - seed.length]; System.arraycopy(paddedData, seed.length, data, 0, data.length); return data; } } bouncycastle-1.49.orig/j2me/org/bouncycastle/cert/crmf/EncryptedValueParser.java0000644000175000017500000000631111731757424027422 0ustar ebourgebourgpackage org.bouncycastle.cert.crmf; import java.io.ByteArrayInputStream; import java.io.IOException; import java.io.InputStream; import org.bouncycastle.asn1.crmf.EncryptedValue; import org.bouncycastle.asn1.x509.Certificate; import org.bouncycastle.cert.X509CertificateHolder; import org.bouncycastle.operator.InputDecryptor; import org.bouncycastle.util.Strings; import org.bouncycastle.util.io.Streams; /** * Parser for EncryptedValue structures. */ public class EncryptedValueParser { private EncryptedValue value; private EncryptedValuePadder padder; /** * Basic constructor - create a parser to read the passed in value. * * @param value the value to be parsed. */ public EncryptedValueParser(EncryptedValue value) { this.value = value; } /** * Create a parser to read the passed in value, assuming the padder was * applied to the data prior to encryption. * * @param value the value to be parsed. * @param padder the padder to be used to remove padding from the decrypted value.. */ public EncryptedValueParser(EncryptedValue value, EncryptedValuePadder padder) { this.value = value; this.padder = padder; } private byte[] decryptValue(ValueDecryptorGenerator decGen) throws CRMFException { if (value.getIntendedAlg() != null) { throw new IllegalStateException("unsupported operation"); } if (value.getValueHint() != null) { throw new IllegalStateException("unsupported operation"); } InputDecryptor decryptor = decGen.getValueDecryptor(value.getKeyAlg(), value.getSymmAlg(), value.getEncSymmKey().getBytes()); InputStream dataIn = decryptor.getInputStream(new ByteArrayInputStream( value.getEncValue().getBytes())); try { byte[] data = Streams.readAll(dataIn); if (padder != null) { return padder.getUnpaddedData(data); } return data; } catch (IOException e) { throw new CRMFException("Cannot parse decrypted data: " + e.getMessage(), e); } } /** * Read a X.509 certificate. * * @param decGen the decryptor generator to decrypt the encrypted value. * @return an X509CertificateHolder containing the certificate read. * @throws CRMFException if the decrypted data cannot be parsed, or a decryptor cannot be generated. */ public X509CertificateHolder readCertificateHolder(ValueDecryptorGenerator decGen) throws CRMFException { return new X509CertificateHolder(Certificate.getInstance(decryptValue(decGen))); } /** * Read a pass phrase. * * @param decGen the decryptor generator to decrypt the encrypted value. * @return a pass phrase as recovered from the encrypted value. * @throws CRMFException if the decrypted data cannot be parsed, or a decryptor cannot be generated. */ public char[] readPassphrase(ValueDecryptorGenerator decGen) throws CRMFException { return Strings.fromUTF8ByteArray(decryptValue(decGen)).toCharArray(); } } bouncycastle-1.49.orig/j2me/org/bouncycastle/cert/X509AttributeCertificateHolder.java0000644000175000017500000002524712105426345030216 0ustar ebourgebourgpackage org.bouncycastle.cert; import java.io.IOException; import java.io.OutputStream; import java.math.BigInteger; import java.util.ArrayList; import java.util.Date; import java.util.List; import java.util.Set; import org.bouncycastle.asn1.ASN1ObjectIdentifier; import org.bouncycastle.asn1.ASN1Primitive; import org.bouncycastle.asn1.ASN1Sequence; import org.bouncycastle.asn1.DEROutputStream; import org.bouncycastle.asn1.x509.AlgorithmIdentifier; import org.bouncycastle.asn1.x509.AttCertValidityPeriod; import org.bouncycastle.asn1.x509.Attribute; import org.bouncycastle.asn1.x509.AttributeCertificate; import org.bouncycastle.asn1.x509.AttributeCertificateInfo; import org.bouncycastle.asn1.x509.Extension; import org.bouncycastle.asn1.x509.Extensions; import org.bouncycastle.operator.ContentVerifier; import org.bouncycastle.operator.ContentVerifierProvider; /** * Holding class for an X.509 AttributeCertificate structure. */ public class X509AttributeCertificateHolder { private static Attribute[] EMPTY_ARRAY = new Attribute[0]; private AttributeCertificate attrCert; private Extensions extensions; private static AttributeCertificate parseBytes(byte[] certEncoding) throws IOException { try { return AttributeCertificate.getInstance(ASN1Primitive.fromByteArray(certEncoding)); } catch (ClassCastException e) { throw new CertIOException("malformed data: " + e.getMessage(), e); } catch (IllegalArgumentException e) { throw new CertIOException("malformed data: " + e.getMessage(), e); } } /** * Create a X509AttributeCertificateHolder from the passed in bytes. * * @param certEncoding BER/DER encoding of the certificate. * @throws IOException in the event of corrupted data, or an incorrect structure. */ public X509AttributeCertificateHolder(byte[] certEncoding) throws IOException { this(parseBytes(certEncoding)); } /** * Create a X509AttributeCertificateHolder from the passed in ASN.1 structure. * * @param attrCert an ASN.1 AttributeCertificate structure. */ public X509AttributeCertificateHolder(AttributeCertificate attrCert) { this.attrCert = attrCert; this.extensions = attrCert.getAcinfo().getExtensions(); } /** * Return the ASN.1 encoding of this holder's attribute certificate. * * @return a DER encoded byte array. * @throws IOException if an encoding cannot be generated. */ public byte[] getEncoded() throws IOException { return attrCert.getEncoded(); } public int getVersion() { return attrCert.getAcinfo().getVersion().getValue().intValue() + 1; } /** * Return the serial number of this attribute certificate. * * @return the serial number. */ public BigInteger getSerialNumber() { return attrCert.getAcinfo().getSerialNumber().getValue(); } /** * Return the holder details for this attribute certificate. * * @return this attribute certificate's holder structure. */ public AttributeCertificateHolder getHolder() { return new AttributeCertificateHolder((ASN1Sequence)attrCert.getAcinfo().getHolder().toASN1Primitive()); } /** * Return the issuer details for this attribute certificate. * * @return this attribute certificate's issuer structure, */ public AttributeCertificateIssuer getIssuer() { return new AttributeCertificateIssuer(attrCert.getAcinfo().getIssuer()); } /** * Return the date before which this attribute certificate is not valid. * * @return the start date for the attribute certificate's validity period. */ public Date getNotBefore() { return CertUtils.recoverDate(attrCert.getAcinfo().getAttrCertValidityPeriod().getNotBeforeTime()); } /** * Return the date after which this attribute certificate is not valid. * * @return the final date for the attribute certificate's validity period. */ public Date getNotAfter() { return CertUtils.recoverDate(attrCert.getAcinfo().getAttrCertValidityPeriod().getNotAfterTime()); } /** * Return the attributes, if any associated with this request. * * @return an array of Attribute, zero length if none present. */ public Attribute[] getAttributes() { ASN1Sequence seq = attrCert.getAcinfo().getAttributes(); Attribute[] attrs = new Attribute[seq.size()]; for (int i = 0; i != seq.size(); i++) { attrs[i] = Attribute.getInstance(seq.getObjectAt(i)); } return attrs; } /** * Return an array of attributes matching the passed in type OID. * * @param type the type of the attribute being looked for. * @return an array of Attribute of the requested type, zero length if none present. */ public Attribute[] getAttributes(ASN1ObjectIdentifier type) { ASN1Sequence seq = attrCert.getAcinfo().getAttributes(); List list = new ArrayList(); for (int i = 0; i != seq.size(); i++) { Attribute attr = Attribute.getInstance(seq.getObjectAt(i)); if (attr.getAttrType().equals(type)) { list.add(attr); } } if (list.size() == 0) { return EMPTY_ARRAY; } return (Attribute[])list.toArray(new Attribute[list.size()]); } /** * Return whether or not the holder's attribute certificate contains extensions. * * @return true if extension are present, false otherwise. */ public boolean hasExtensions() { return extensions != null; } /** * Look up the extension associated with the passed in OID. * * @param oid the OID of the extension of interest. * * @return the extension if present, null otherwise. */ public Extension getExtension(ASN1ObjectIdentifier oid) { if (extensions != null) { return extensions.getExtension(oid); } return null; } /** * Return the extensions block associated with this certificate if there is one. * * @return the extensions block, null otherwise. */ public Extensions getExtensions() { return extensions; } /** * Returns a list of ASN1ObjectIdentifier objects representing the OIDs of the * extensions contained in this holder's attribute certificate. * * @return a list of extension OIDs. */ public List getExtensionOIDs() { return CertUtils.getExtensionOIDs(extensions); } /** * Returns a set of ASN1ObjectIdentifier objects representing the OIDs of the * critical extensions contained in this holder's attribute certificate. * * @return a set of critical extension OIDs. */ public Set getCriticalExtensionOIDs() { return CertUtils.getCriticalExtensionOIDs(extensions); } /** * Returns a set of ASN1ObjectIdentifier objects representing the OIDs of the * non-critical extensions contained in this holder's attribute certificate. * * @return a set of non-critical extension OIDs. */ public Set getNonCriticalExtensionOIDs() { return CertUtils.getNonCriticalExtensionOIDs(extensions); } public boolean[] getIssuerUniqueID() { return CertUtils.bitStringToBoolean(attrCert.getAcinfo().getIssuerUniqueID()); } /** * Return the details of the signature algorithm used to create this attribute certificate. * * @return the AlgorithmIdentifier describing the signature algorithm used to create this attribute certificate. */ public AlgorithmIdentifier getSignatureAlgorithm() { return attrCert.getSignatureAlgorithm(); } /** * Return the bytes making up the signature associated with this attribute certificate. * * @return the attribute certificate signature bytes. */ public byte[] getSignature() { return attrCert.getSignatureValue().getBytes(); } /** * Return the underlying ASN.1 structure for the attribute certificate in this holder. * * @return a AttributeCertificate object. */ public AttributeCertificate toASN1Structure() { return attrCert; } /** * Return whether or not this attribute certificate is valid on a particular date. * * @param date the date of interest. * @return true if the attribute certificate is valid, false otherwise. */ public boolean isValidOn(Date date) { AttCertValidityPeriod certValidityPeriod = attrCert.getAcinfo().getAttrCertValidityPeriod(); return !CertUtils.dateBefore(date, CertUtils.recoverDate(certValidityPeriod.getNotBeforeTime())) && !CertUtils.dateAfter(date, CertUtils.recoverDate(certValidityPeriod.getNotAfterTime())); } /** * Validate the signature on the attribute certificate in this holder. * * @param verifierProvider a ContentVerifierProvider that can generate a verifier for the signature. * @return true if the signature is valid, false otherwise. * @throws CertException if the signature cannot be processed or is inappropriate. */ public boolean isSignatureValid(ContentVerifierProvider verifierProvider) throws CertException { AttributeCertificateInfo acinfo = attrCert.getAcinfo(); if (!CertUtils.isAlgIdEqual(acinfo.getSignature(), attrCert.getSignatureAlgorithm())) { throw new CertException("signature invalid - algorithm identifier mismatch"); } ContentVerifier verifier; try { verifier = verifierProvider.get((acinfo.getSignature())); OutputStream sOut = verifier.getOutputStream(); DEROutputStream dOut = new DEROutputStream(sOut); dOut.writeObject(acinfo); sOut.close(); } catch (Exception e) { throw new CertException("unable to process signature: " + e.getMessage(), e); } return verifier.verify(attrCert.getSignatureValue().getBytes()); } public boolean equals( Object o) { if (o == this) { return true; } if (!(o instanceof X509AttributeCertificateHolder)) { return false; } X509AttributeCertificateHolder other = (X509AttributeCertificateHolder)o; return this.attrCert.equals(other.attrCert); } public int hashCode() { return this.attrCert.hashCode(); } } bouncycastle-1.49.orig/j2me/org/bouncycastle/cert/test/0000755000175000017500000000000012152033550022460 5ustar ebourgebourgbouncycastle-1.49.orig/j2me/org/bouncycastle/cert/test/AttrCertTest.java0000644000175000017500000006337311732220502025725 0ustar ebourgebourgpackage org.bouncycastle.cert.test; import java.io.IOException; import java.math.BigInteger; import java.util.ArrayList; import java.util.Collection; import java.util.Date; import java.util.List; import java.util.Set; import org.bouncycastle.asn1.ASN1Encodable; import org.bouncycastle.asn1.ASN1EncodableVector; import org.bouncycastle.asn1.ASN1ObjectIdentifier; import org.bouncycastle.asn1.ASN1String; import org.bouncycastle.asn1.DEROctetString; import org.bouncycastle.asn1.DERSequence; import org.bouncycastle.asn1.x500.X500Name; import org.bouncycastle.asn1.x500.style.BCStrictStyle; import org.bouncycastle.asn1.x500.style.RFC4519Style; import org.bouncycastle.asn1.x509.AlgorithmIdentifier; import org.bouncycastle.asn1.x509.Attribute; import org.bouncycastle.asn1.x509.Extension; import org.bouncycastle.asn1.x509.GeneralName; import org.bouncycastle.asn1.x509.GeneralNames; import org.bouncycastle.cert.AttributeCertificateHolder; import org.bouncycastle.cert.AttributeCertificateIssuer; import org.bouncycastle.cert.X509AttributeCertificateHolder; import org.bouncycastle.cert.X509CertificateHolder; import org.bouncycastle.cert.X509v2AttributeCertificateBuilder; import org.bouncycastle.crypto.params.RSAKeyParameters; import org.bouncycastle.crypto.params.RSAPrivateCrtKeyParameters; import org.bouncycastle.operator.ContentSigner; import org.bouncycastle.operator.DefaultDigestAlgorithmIdentifierFinder; import org.bouncycastle.operator.DefaultSignatureAlgorithmIdentifierFinder; import org.bouncycastle.operator.bc.BcRSAContentSignerBuilder; import org.bouncycastle.operator.bc.BcRSAContentVerifierProviderBuilder; import org.bouncycastle.util.CollectionStore; import org.bouncycastle.util.Store; import org.bouncycastle.util.encoders.Base64; import org.bouncycastle.util.test.SimpleTest; public class AttrCertTest extends SimpleTest { private static final RSAPrivateCrtKeyParameters RSA_PRIVATE_KEY = new RSAPrivateCrtKeyParameters( new BigInteger("b4a7e46170574f16a97082b22be58b6a2a629798419be12872a4bdba626cfae9900f76abfb12139dce5de56564fab2b6543165a040c606887420e33d91ed7ed7", 16), new BigInteger("11", 16), new BigInteger("9f66f6b05410cd503b2709e88115d55daced94d1a34d4e32bf824d0dde6028ae79c5f07b580f5dce240d7111f7ddb130a7945cd7d957d1920994da389f490c89", 16), new BigInteger("c0a0758cdf14256f78d4708c86becdead1b50ad4ad6c5c703e2168fbf37884cb", 16), new BigInteger("f01734d7960ea60070f1b06f2bb81bfac48ff192ae18451d5e56c734a5aab8a5", 16), new BigInteger("b54bb9edff22051d9ee60f9351a48591b6500a319429c069a3e335a1d6171391", 16), new BigInteger("d3d83daf2a0cecd3367ae6f8ae1aeb82e9ac2f816c6fc483533d8297dd7884cd", 16), new BigInteger("b8f52fc6f38593dabb661d3f50f8897f8106eee68b1bce78a95b132b4e5b5d19", 16)); public static byte[] attrCert = Base64.decode( "MIIHQDCCBqkCAQEwgZChgY2kgYowgYcxHDAaBgkqhkiG9w0BCQEWDW1sb3JjaEB2" + "dC5lZHUxHjAcBgNVBAMTFU1hcmt1cyBMb3JjaCAobWxvcmNoKTEbMBkGA1UECxMS" + "VmlyZ2luaWEgVGVjaCBVc2VyMRAwDgYDVQQLEwdDbGFzcyAyMQswCQYDVQQKEwJ2" + "dDELMAkGA1UEBhMCVVMwgYmkgYYwgYMxGzAZBgkqhkiG9w0BCQEWDHNzaGFoQHZ0" + "LmVkdTEbMBkGA1UEAxMSU3VtaXQgU2hhaCAoc3NoYWgpMRswGQYDVQQLExJWaXJn" + "aW5pYSBUZWNoIFVzZXIxEDAOBgNVBAsTB0NsYXNzIDExCzAJBgNVBAoTAnZ0MQsw" + "CQYDVQQGEwJVUzANBgkqhkiG9w0BAQQFAAIBBTAiGA8yMDAzMDcxODE2MDgwMloY" + "DzIwMDMwNzI1MTYwODAyWjCCBU0wggVJBgorBgEEAbRoCAEBMYIFORaCBTU8UnVs" + "ZSBSdWxlSWQ9IkZpbGUtUHJpdmlsZWdlLVJ1bGUiIEVmZmVjdD0iUGVybWl0Ij4K" + "IDxUYXJnZXQ+CiAgPFN1YmplY3RzPgogICA8U3ViamVjdD4KICAgIDxTdWJqZWN0" + "TWF0Y2ggTWF0Y2hJZD0idXJuOm9hc2lzOm5hbWVzOnRjOnhhY21sOjEuMDpmdW5j" + "dGlvbjpzdHJpbmctZXF1YWwiPgogICAgIDxBdHRyaWJ1dGVWYWx1ZSBEYXRhVHlw" + "ZT0iaHR0cDovL3d3dy53My5vcmcvMjAwMS9YTUxTY2hlbWEjc3RyaW5nIj4KICAg" + "ICAgIENOPU1hcmt1cyBMb3JjaDwvQXR0cmlidXRlVmFsdWU+CiAgICAgPFN1Ympl" + "Y3RBdHRyaWJ1dGVEZXNpZ25hdG9yIEF0dHJpYnV0ZUlkPSJ1cm46b2FzaXM6bmFt" + "ZXM6dGM6eGFjbWw6MS4wOnN1YmplY3Q6c3ViamVjdC1pZCIgRGF0YVR5cGU9Imh0" + "dHA6Ly93d3cudzMub3JnLzIwMDEvWE1MU2NoZW1hI3N0cmluZyIgLz4gCiAgICA8" + "L1N1YmplY3RNYXRjaD4KICAgPC9TdWJqZWN0PgogIDwvU3ViamVjdHM+CiAgPFJl" + "c291cmNlcz4KICAgPFJlc291cmNlPgogICAgPFJlc291cmNlTWF0Y2ggTWF0Y2hJ" + "ZD0idXJuOm9hc2lzOm5hbWVzOnRjOnhhY21sOjEuMDpmdW5jdGlvbjpzdHJpbmct" + "ZXF1YWwiPgogICAgIDxBdHRyaWJ1dGVWYWx1ZSBEYXRhVHlwZT0iaHR0cDovL3d3" + "dy53My5vcmcvMjAwMS9YTUxTY2hlbWEjYW55VVJJIj4KICAgICAgaHR0cDovL3p1" + "bmkuY3MudnQuZWR1PC9BdHRyaWJ1dGVWYWx1ZT4KICAgICA8UmVzb3VyY2VBdHRy" + "aWJ1dGVEZXNpZ25hdG9yIEF0dHJpYnV0ZUlkPSJ1cm46b2FzaXM6bmFtZXM6dGM6" + "eGFjbWw6MS4wOnJlc291cmNlOnJlc291cmNlLWlkIiBEYXRhVHlwZT0iaHR0cDov" + "L3d3dy53My5vcmcvMjAwMS9YTUxTY2hlbWEjYW55VVJJIiAvPiAKICAgIDwvUmVz" + "b3VyY2VNYXRjaD4KICAgPC9SZXNvdXJjZT4KICA8L1Jlc291cmNlcz4KICA8QWN0" + "aW9ucz4KICAgPEFjdGlvbj4KICAgIDxBY3Rpb25NYXRjaCBNYXRjaElkPSJ1cm46" + "b2FzaXM6bmFtZXM6dGM6eGFjbWw6MS4wOmZ1bmN0aW9uOnN0cmluZy1lcXVhbCI+" + "CiAgICAgPEF0dHJpYnV0ZVZhbHVlIERhdGFUeXBlPSJodHRwOi8vd3d3LnczLm9y" + "Zy8yMDAxL1hNTFNjaGVtYSNzdHJpbmciPgpEZWxlZ2F0ZSBBY2Nlc3MgICAgIDwv" + "QXR0cmlidXRlVmFsdWU+CgkgIDxBY3Rpb25BdHRyaWJ1dGVEZXNpZ25hdG9yIEF0" + "dHJpYnV0ZUlkPSJ1cm46b2FzaXM6bmFtZXM6dGM6eGFjbWw6MS4wOmFjdGlvbjph" + "Y3Rpb24taWQiIERhdGFUeXBlPSJodHRwOi8vd3d3LnczLm9yZy8yMDAxL1hNTFNj" + "aGVtYSNzdHJpbmciIC8+IAogICAgPC9BY3Rpb25NYXRjaD4KICAgPC9BY3Rpb24+" + "CiAgPC9BY3Rpb25zPgogPC9UYXJnZXQ+CjwvUnVsZT4KMA0GCSqGSIb3DQEBBAUA" + "A4GBAGiJSM48XsY90HlYxGmGVSmNR6ZW2As+bot3KAfiCIkUIOAqhcphBS23egTr" + "6asYwy151HshbPNYz+Cgeqs45KkVzh7bL/0e1r8sDVIaaGIkjHK3CqBABnfSayr3" + "Rd1yBoDdEv8Qb+3eEPH6ab9021AsLEnJ6LWTmybbOpMNZ3tv"); byte[] signCert = Base64.decode( "MIIGjTCCBXWgAwIBAgICAPswDQYJKoZIhvcNAQEEBQAwaTEdMBsGCSqGSIb3DQEJ" + "ARYOaXJtaGVscEB2dC5lZHUxLjAsBgNVBAMTJVZpcmdpbmlhIFRlY2ggQ2VydGlm" + "aWNhdGlvbiBBdXRob3JpdHkxCzAJBgNVBAoTAnZ0MQswCQYDVQQGEwJVUzAeFw0w" + "MzAxMzExMzUyMTRaFw0wNDAxMzExMzUyMTRaMIGDMRswGQYJKoZIhvcNAQkBFgxz" + "c2hhaEB2dC5lZHUxGzAZBgNVBAMTElN1bWl0IFNoYWggKHNzaGFoKTEbMBkGA1UE" + "CxMSVmlyZ2luaWEgVGVjaCBVc2VyMRAwDgYDVQQLEwdDbGFzcyAxMQswCQYDVQQK" + "EwJ2dDELMAkGA1UEBhMCVVMwgZ8wDQYJKoZIhvcNAQEBBQADgY0AMIGJAoGBAPDc" + "scgSKmsEp0VegFkuitD5j5PUkDuzLjlfaYONt2SN8WeqU4j2qtlCnsipa128cyKS" + "JzYe9duUdNxquh5BPIkMkHBw4jHoQA33tk0J/sydWdN74/AHPpPieK5GHwhU7GTG" + "rCCS1PJRxjXqse79ExAlul+gjQwHeldAC+d4A6oZAgMBAAGjggOmMIIDojAMBgNV" + "HRMBAf8EAjAAMBEGCWCGSAGG+EIBAQQEAwIFoDAOBgNVHQ8BAf8EBAMCA/gwHQYD" + "VR0lBBYwFAYIKwYBBQUHAwIGCCsGAQUFBwMEMB0GA1UdDgQWBBRUIoWAzlXbzBYE" + "yVTjQFWyMMKo1jCBkwYDVR0jBIGLMIGIgBTgc3Fm+TGqKDhen+oKfbl+xVbj2KFt" + "pGswaTEdMBsGCSqGSIb3DQEJARYOaXJtaGVscEB2dC5lZHUxLjAsBgNVBAMTJVZp" + "cmdpbmlhIFRlY2ggQ2VydGlmaWNhdGlvbiBBdXRob3JpdHkxCzAJBgNVBAoTAnZ0" + "MQswCQYDVQQGEwJVU4IBADCBiwYJYIZIAYb4QgENBH4WfFZpcmdpbmlhIFRlY2gg" + "Q2VydGlmaWNhdGlvbiBBdXRob3JpdHkgZGlnaXRhbCBjZXJ0aWZpY2F0ZXMgYXJl" + "IHN1YmplY3QgdG8gcG9saWNpZXMgbG9jYXRlZCBhdCBodHRwOi8vd3d3LnBraS52" + "dC5lZHUvY2EvY3BzLy4wFwYDVR0RBBAwDoEMc3NoYWhAdnQuZWR1MBkGA1UdEgQS" + "MBCBDmlybWhlbHBAdnQuZWR1MEMGCCsGAQUFBwEBBDcwNTAzBggrBgEFBQcwAoYn" + "aHR0cDovL2JveDE3Ny5jYy52dC5lZHUvY2EvaXNzdWVycy5odG1sMEQGA1UdHwQ9" + "MDswOaA3oDWGM2h0dHA6Ly9ib3gxNzcuY2MudnQuZWR1L2h0ZG9jcy1wdWJsaWMv" + "Y3JsL2NhY3JsLmNybDBUBgNVHSAETTBLMA0GCysGAQQBtGgFAQEBMDoGCysGAQQB" + "tGgFAQEBMCswKQYIKwYBBQUHAgEWHWh0dHA6Ly93d3cucGtpLnZ0LmVkdS9jYS9j" + "cHMvMD8GCWCGSAGG+EIBBAQyFjBodHRwOi8vYm94MTc3LmNjLnZ0LmVkdS9jZ2kt" + "cHVibGljL2NoZWNrX3Jldl9jYT8wPAYJYIZIAYb4QgEDBC8WLWh0dHA6Ly9ib3gx" + "NzcuY2MudnQuZWR1L2NnaS1wdWJsaWMvY2hlY2tfcmV2PzBLBglghkgBhvhCAQcE" + "PhY8aHR0cHM6Ly9ib3gxNzcuY2MudnQuZWR1L35PcGVuQ0E4LjAxMDYzMC9jZ2kt" + "cHVibGljL3JlbmV3YWw/MCwGCWCGSAGG+EIBCAQfFh1odHRwOi8vd3d3LnBraS52" + "dC5lZHUvY2EvY3BzLzANBgkqhkiG9w0BAQQFAAOCAQEAHJ2ls9yjpZVcu5DqiE67" + "r7BfkdMnm7IOj2v8cd4EAlPp6OPBmjwDMwvKRBb/P733kLBqFNWXWKTpT008R0KB" + "8kehbx4h0UPz9vp31zhGv169+5iReQUUQSIwTGNWGLzrT8kPdvxiSAvdAJxcbRBm" + "KzDic5I8PoGe48kSCkPpT1oNmnivmcu5j1SMvlx0IS2BkFMksr0OHiAW1elSnE/N" + "RuX2k73b3FucwVxB3NRo3vgoHPCTnh9r4qItAHdxFlF+pPtbw2oHESKRfMRfOIHz" + "CLQWSIa6Tvg4NIV3RRJ0sbCObesyg08lymalQMdkXwtRn5eGE00SHWwEUjSXP2gR" + "3g=="); static byte[] certWithBaseCertificateID = Base64.decode( "MIIBqzCCARQCAQEwSKBGMD6kPDA6MQswCQYDVQQGEwJJVDEOMAwGA1UEChMFVU5JVE4xDDAKBgNV" + "BAsTA0RJVDENMAsGA1UEAxMEcm9vdAIEAVMVjqB6MHikdjB0MQswCQYDVQQGEwJBVTEoMCYGA1UE" + "ChMfVGhlIExlZ2lvbiBvZiB0aGUgQm91bmN5IENhc3RsZTEjMCEGA1UECxMaQm91bmN5IFByaW1h" + "cnkgQ2VydGlmaWNhdGUxFjAUBgNVBAMTDUJvdW5jeSBDYXN0bGUwDQYJKoZIhvcNAQEFBQACBQKW" + "RhnHMCIYDzIwMDUxMjEyMTIwMDQyWhgPMjAwNTEyMTkxMjAxMzJaMA8wDQYDVRhIMQaBBGVWSVAw" + "DQYJKoZIhvcNAQEFBQADgYEAUAVin9StDaA+InxtXq/av6rUQLI9p1X6louBcj4kYJnxRvTrHpsr" + "N3+i9Uq/uk5lRdAqmPFvcmSbuE3TRAsjrXON5uFiBBKZ1AouLqcr8nHbwcdwjJ9TyUNO9I4hfpSH" + "UHHXMtBKgp4MOkhhX8xTGyWg3hp23d3GaUeg/IYlXBI="); byte[] holderCertWithBaseCertificateID = Base64.decode( "MIIBwDCCASmgAwIBAgIEAVMVjjANBgkqhkiG9w0BAQUFADA6MQswCQYDVQQGEwJJVDEOMAwGA1UE" + "ChMFVU5JVE4xDDAKBgNVBAsTA0RJVDENMAsGA1UEAxMEcm9vdDAeFw0wNTExMTExMjAxMzJaFw0w" + "NjA2MTYxMjAxMzJaMD4xCzAJBgNVBAYTAklUMQ4wDAYDVQQKEwVVTklUTjEMMAoGA1UECxMDRElU" + "MREwDwYDVQQDEwhMdWNhQm9yejBaMA0GCSqGSIb3DQEBAQUAA0kAMEYCQQC0p+RhcFdPFqlwgrIr" + "5YtqKmKXmEGb4ShypL26Ymz66ZAPdqv7EhOdzl3lZWT6srZUMWWgQMYGiHQg4z2R7X7XAgERoxUw" + "EzARBglghkgBhvhCAQEEBAMCBDAwDQYJKoZIhvcNAQEFBQADgYEAsX50VPQQCWmHvPq9y9DeCpmS" + "4szcpFAhpZyn6gYRwY9CRZVtmZKH8713XhkGDWcIEMcG0u3oTz3tdKgPU5uyIPrDEWr6w8ClUj4x" + "5aVz5c2223+dVY7KES//JSB2bE/KCIchN3kAioQ4K8O3e0OL6oDVjsqKGw5bfahgKuSIk/Q="); public String getName() { return "AttrCertTest"; } private void testCertWithBaseCertificateID() throws Exception { X509AttributeCertificateHolder attrCert = new X509AttributeCertificateHolder(certWithBaseCertificateID); X509CertificateHolder cert = new X509CertificateHolder(holderCertWithBaseCertificateID); AttributeCertificateHolder holder = attrCert.getHolder(); if (holder.getEntityNames() != null) { fail("entity names set when none expected"); } if (!holder.getSerialNumber().equals(cert.getSerialNumber())) { fail("holder serial number doesn't match"); } if (!holder.getIssuer()[0].equals(cert.getIssuer())) { fail("holder issuer doesn't match"); } if (!holder.match(cert)) { fail("holder not matching holder certificate"); } if (!holder.equals(holder.clone())) { fail("holder clone test failed"); } if (!attrCert.getIssuer().equals(attrCert.getIssuer().clone())) { fail("issuer clone test failed"); } //equalityAndHashCodeTest(attrCert, certWithBaseCertificateID); } private void equalityAndHashCodeTest(X509AttributeCertificateHolder attrCert, byte[] encoding) throws IOException { if (!attrCert.equals(attrCert)) { fail("same certificate not equal"); } if (!attrCert.getHolder().equals(attrCert.getHolder())) { fail("same holder not equal"); } if (!attrCert.getIssuer().equals(attrCert.getIssuer())) { fail("same issuer not equal"); } if (attrCert.getHolder().equals(attrCert.getIssuer())) { fail("wrong holder equal"); } if (attrCert.getIssuer().equals(attrCert.getHolder())) { fail("wrong issuer equal"); } X509AttributeCertificateHolder attrCert2 = new X509AttributeCertificateHolder(encoding); if (attrCert2.getHolder().hashCode() != attrCert.getHolder().hashCode()) { fail("holder hashCode test failed"); } if (!attrCert2.getHolder().equals(attrCert.getHolder())) { fail("holder equals test failed"); } if (attrCert2.getIssuer().hashCode() != attrCert.getIssuer().hashCode()) { fail("issuer hashCode test failed"); } if (!attrCert2.getIssuer().equals(attrCert.getIssuer())) { fail("issuer equals test failed"); } } private void testGenerateWithCert() throws Exception { X509CertificateHolder iCert = new X509CertificateHolder(signCert); // // a sample key pair. // RSAKeyParameters pubKey = new RSAKeyParameters(false, new BigInteger("b4a7e46170574f16a97082b22be58b6a2a629798419be12872a4bdba626cfae9900f76abfb12139dce5de56564fab2b6543165a040c606887420e33d91ed7ed7", 16), new BigInteger("11", 16)); // // set up the keys X509v2AttributeCertificateBuilder gen = new X509v2AttributeCertificateBuilder( new AttributeCertificateHolder(iCert), new AttributeCertificateIssuer(new X500Name("cn=test")), BigInteger.ONE, new Date(System.currentTimeMillis() - 50000), new Date(System.currentTimeMillis() + 50000)); // the actual attributes GeneralName roleName = new GeneralName(GeneralName.rfc822Name, "DAU123456789"); ASN1EncodableVector roleSyntax = new ASN1EncodableVector(); roleSyntax.add(roleName); // roleSyntax OID: 2.5.24.72; gen.addAttribute(new ASN1ObjectIdentifier("2.5.24.72"), new DERSequence(roleSyntax)); AlgorithmIdentifier sigAlgId = new DefaultSignatureAlgorithmIdentifierFinder().find("SHA1WithRSAEncryption"); AlgorithmIdentifier digAlgId = new DefaultDigestAlgorithmIdentifierFinder().find(sigAlgId); ContentSigner sigGen = new BcRSAContentSignerBuilder(sigAlgId, digAlgId).build(RSA_PRIVATE_KEY); X509AttributeCertificateHolder aCert = gen.build(sigGen); if (!aCert.isValidOn(new Date())) { fail("certificate invalid"); } if (!aCert.isSignatureValid(new BcRSAContentVerifierProviderBuilder(new DefaultDigestAlgorithmIdentifierFinder()).build(pubKey))) { fail("certificate signature not valid"); } AttributeCertificateHolder holder = aCert.getHolder(); if (holder.getEntityNames() != null) { fail("entity names set when none expected"); } if (!holder.getSerialNumber().equals(iCert.getSerialNumber())) { fail("holder serial number doesn't match"); } if (!holder.getIssuer()[0].equals(iCert.getIssuer())) { fail("holder issuer doesn't match"); } if (!holder.match(iCert)) { fail("generated holder not matching holder certificate"); } Attribute[] attrs = aCert.getAttributes(new ASN1ObjectIdentifier("2.5.24.72")); if (attrs == null) { fail("attributes related to 2.5.24.72 not found"); } Attribute attr = attrs[0]; if (!attr.getAttrType().getId().equals("2.5.24.72")) { fail("attribute oid mismatch"); } ASN1Encodable[] values = attr.getAttrValues().toArray(); GeneralName role = GeneralNames.getInstance(values[0]).getNames()[0]; if (role.getTagNo() != GeneralName.rfc822Name) { fail("wrong general name type found in role"); } if (!((ASN1String)role.getName()).getString().equals("DAU123456789")) { fail("wrong general name value found in role"); } X509CertificateHolder sCert = new X509CertificateHolder(holderCertWithBaseCertificateID); if (holder.match(sCert)) { fail("generated holder matching wrong certificate"); } equalityAndHashCodeTest(aCert, aCert.getEncoded()); } private void testGenerateWithPrincipal() throws Exception { X509CertificateHolder iCert = new X509CertificateHolder(signCert); // // a sample key pair. // RSAKeyParameters pubKey = new RSAKeyParameters(false, new BigInteger("b4a7e46170574f16a97082b22be58b6a2a629798419be12872a4bdba626cfae9900f76abfb12139dce5de56564fab2b6543165a040c606887420e33d91ed7ed7", 16), new BigInteger("11", 16)); // // set up the keys // X509v2AttributeCertificateBuilder gen = new X509v2AttributeCertificateBuilder( new AttributeCertificateHolder(iCert.getSubject()), new AttributeCertificateIssuer(new X500Name("cn=test")), BigInteger.ONE, new Date(System.currentTimeMillis() - 50000), new Date(System.currentTimeMillis() + 50000)); // the actual attributes GeneralName roleName = new GeneralName(GeneralName.rfc822Name, "DAU123456789"); ASN1EncodableVector roleSyntax = new ASN1EncodableVector(); roleSyntax.add(roleName); // roleSyntax OID: 2.5.24.72 gen.addAttribute(new ASN1ObjectIdentifier("2.5.24.72"), new DERSequence(roleSyntax)); AlgorithmIdentifier sigAlgId = new DefaultSignatureAlgorithmIdentifierFinder().find("SHA1WithRSAEncryption"); AlgorithmIdentifier digAlgId = new DefaultDigestAlgorithmIdentifierFinder().find(sigAlgId); ContentSigner sigGen = new BcRSAContentSignerBuilder(sigAlgId, digAlgId).build(RSA_PRIVATE_KEY); X509AttributeCertificateHolder aCert = gen.build(sigGen); if (!aCert.isValidOn(new Date())) { fail("certificate invalid"); } if (!aCert.isSignatureValid(new BcRSAContentVerifierProviderBuilder(new DefaultDigestAlgorithmIdentifierFinder()).build(pubKey))) { fail("certificate signature not valid"); } AttributeCertificateHolder holder = aCert.getHolder(); if (holder.getEntityNames() == null) { fail("entity names not set when expected"); } if (holder.getSerialNumber() != null) { fail("holder serial number found when none expected"); } if (holder.getIssuer() != null) { fail("holder issuer found when none expected"); } if (!holder.match(iCert)) { fail("generated holder not matching holder certificate"); } X509CertificateHolder sCert = new X509CertificateHolder(holderCertWithBaseCertificateID); if (holder.match(sCert)) { fail("principal generated holder matching wrong certificate"); } equalityAndHashCodeTest(aCert, aCert.getEncoded()); } public void performTest() throws Exception { X509AttributeCertificateHolder aCert = new X509AttributeCertificateHolder(attrCert); X509CertificateHolder sCert = new X509CertificateHolder(signCert); if (!aCert.isSignatureValid(new BcRSAContentVerifierProviderBuilder(new DefaultDigestAlgorithmIdentifierFinder()).build(sCert))) { fail("certificate signature not valid"); } // // search test // List list = new ArrayList(); list.add(sCert); Store store = new CollectionStore(list); Collection certs = store.getMatches(aCert.getIssuer()); if (certs.size() != 1 || !certs.contains(sCert)) { fail("sCert not found by issuer"); } Attribute[] attrs = aCert.getAttributes(new ASN1ObjectIdentifier("1.3.6.1.4.1.6760.8.1.1")); if (attrs == null || attrs.length != 1) { fail("attribute not found"); } // // reencode test // aCert = new X509AttributeCertificateHolder(aCert.getEncoded()); if (!aCert.isSignatureValid(new BcRSAContentVerifierProviderBuilder(new DefaultDigestAlgorithmIdentifierFinder()).build(sCert))) { fail("certificate signature not valid"); } X509AttributeCertificateHolder saCert = new X509AttributeCertificateHolder(aCert.getEncoded()); if (!aCert.getNotAfter().equals(saCert.getNotAfter())) { fail("failed date comparison"); } // base generator test // // a sample key pair. // RSAKeyParameters pubKey = new RSAKeyParameters(false, new BigInteger("b4a7e46170574f16a97082b22be58b6a2a629798419be12872a4bdba626cfae9900f76abfb12139dce5de56564fab2b6543165a040c606887420e33d91ed7ed7", 16), new BigInteger("11", 16)); // // set up the keys // X509v2AttributeCertificateBuilder gen = new X509v2AttributeCertificateBuilder( aCert.getHolder(), aCert.getIssuer(), aCert.getSerialNumber(), new Date(System.currentTimeMillis() - 50000), new Date(System.currentTimeMillis() + 50000)); gen.addAttribute(attrs[0].getAttrType(), attrs[0].getAttributeValues()); AlgorithmIdentifier sigAlgId = new DefaultSignatureAlgorithmIdentifierFinder().find("SHA1WithRSAEncryption"); AlgorithmIdentifier digAlgId = new DefaultDigestAlgorithmIdentifierFinder().find(sigAlgId); ContentSigner sigGen = new BcRSAContentSignerBuilder(sigAlgId, digAlgId).build(RSA_PRIVATE_KEY); aCert = gen.build(sigGen); if (!aCert.isValidOn(new Date())) { fail("certificate not valid"); } if (!aCert.isSignatureValid(new BcRSAContentVerifierProviderBuilder(new DefaultDigestAlgorithmIdentifierFinder()).build(pubKey))) { fail("signature not valid"); } // as the issuer is the same this should still work (even though it is not // technically correct certs = store.getMatches(aCert.getIssuer()); if (certs.size() != 1 || !certs.contains(sCert)) { fail("sCert not found by issuer"); } attrs = aCert.getAttributes(new ASN1ObjectIdentifier("1.3.6.1.4.1.6760.8.1.1")); if (attrs == null || attrs.length != 1) { fail("attribute not found"); } // // reencode test // aCert = new X509AttributeCertificateHolder(aCert.getEncoded()); if (!aCert.isSignatureValid(new BcRSAContentVerifierProviderBuilder(new DefaultDigestAlgorithmIdentifierFinder()).build(pubKey))) { fail("signature not valid"); } AttributeCertificateIssuer issuer = aCert.getIssuer(); X500Name[] principals = issuer.getNames(); // // test holder // AttributeCertificateHolder holder = aCert.getHolder(); if (holder.getEntityNames() == null) { fail("entity names not set"); } if (holder.getSerialNumber() != null) { fail("holder serial number set when none expected"); } if (holder.getIssuer() != null) { fail("holder issuer set when none expected"); } principals = holder.getEntityNames(); X500Name principal0 = X500Name.getInstance(RFC4519Style.INSTANCE, principals[0].getEncoded()); if (!principal0.toString().equals("c=US,o=vt,ou=Class 2,ou=Virginia Tech User,cn=Markus Lorch (mlorch),1.2.840.113549.1.9.1=mlorch@vt.edu")) { fail("principal[0] for entity names don't match"); } // // extension test // if (aCert.hasExtensions()) { fail("hasExtensions true with no extensions"); } gen.addExtension(new ASN1ObjectIdentifier("1.1"), true, new DEROctetString(new byte[10])); gen.addExtension(new ASN1ObjectIdentifier("2.2"), false, new DEROctetString(new byte[20])); aCert = gen.build(sigGen); Set exts = aCert.getCriticalExtensionOIDs(); if (exts.size() != 1 || !exts.contains(new ASN1ObjectIdentifier("1.1"))) { System.err.println(exts); fail("critical extension test failed"); } exts = aCert.getNonCriticalExtensionOIDs(); if (exts.size() != 1 || !exts.contains(new ASN1ObjectIdentifier("2.2"))) { fail("non-critical extension test failed"); } if (aCert.getCriticalExtensionOIDs().isEmpty()) { fail("critical extensions not found"); } Extension ext = aCert.getExtension(new ASN1ObjectIdentifier("1.1")); ASN1Encodable extValue = ext.getParsedValue(); if (!extValue.equals(new DEROctetString(new byte[10]))) { fail("wrong extension value found for 1.1"); } testCertWithBaseCertificateID(); testGenerateWithCert(); testGenerateWithPrincipal(); } public static void main( String[] args) { runTest(new AttrCertTest()); } } bouncycastle-1.49.orig/j2me/org/bouncycastle/cert/test/PKCS10Test.java0000644000175000017500000001701411732217612025075 0ustar ebourgebourgpackage org.bouncycastle.cert.test; import java.math.BigInteger; import org.bouncycastle.asn1.DERNull; import org.bouncycastle.asn1.pkcs.PKCSObjectIdentifiers; import org.bouncycastle.asn1.pkcs.RSAPublicKey; import org.bouncycastle.asn1.x500.X500Name; import org.bouncycastle.asn1.x500.X500NameBuilder; import org.bouncycastle.asn1.x500.style.BCStyle; import org.bouncycastle.asn1.x509.AlgorithmIdentifier; import org.bouncycastle.asn1.x509.SubjectPublicKeyInfo; import org.bouncycastle.crypto.params.RSAKeyParameters; import org.bouncycastle.crypto.params.RSAPrivateCrtKeyParameters; import org.bouncycastle.operator.ContentSigner; import org.bouncycastle.operator.DefaultDigestAlgorithmIdentifierFinder; import org.bouncycastle.operator.DefaultSignatureAlgorithmIdentifierFinder; import org.bouncycastle.operator.bc.BcRSAContentSignerBuilder; import org.bouncycastle.operator.bc.BcRSAContentVerifierProviderBuilder; import org.bouncycastle.pkcs.PKCS10CertificationRequest; import org.bouncycastle.pkcs.PKCS10CertificationRequestBuilder; import org.bouncycastle.util.Arrays; import org.bouncycastle.util.encoders.Base64; import org.bouncycastle.util.test.SimpleTest; /** **/ public class PKCS10Test extends SimpleTest { private byte[] gost3410EC_A = Base64.decode( "MIIBOzCB6wIBADB/MQ0wCwYDVQQDEwR0ZXN0MRUwEwYDVQQKEwxEZW1vcyBDbyBMdGQxHjAcBgNV" +"BAsTFUNyeXB0b2dyYXBoeSBkaXZpc2lvbjEPMA0GA1UEBxMGTW9zY293MQswCQYDVQQGEwJydTEZ" +"MBcGCSqGSIb3DQEJARYKc2RiQGRvbC5ydTBjMBwGBiqFAwICEzASBgcqhQMCAiMBBgcqhQMCAh4B" +"A0MABEBYx0P2D7YuuZo5HgdIAUKAXcLBDZ+4LYFgbKjrfStVfH59lc40BQ2FZ7M703hLpXK8GiBQ" +"GEYpKaAuQZnMIpByoAAwCAYGKoUDAgIDA0EAgXMcTrhdOY2Er2tHOSAgnMezqrYxocZTWhxmW5Rl" +"JY6lbXH5rndCn4swFzXU+YhgAsJv1wQBaoZEWRl5WV4/nA=="); private byte[] gost3410EC_B = Base64.decode( "MIIBPTCB7QIBADCBgDENMAsGA1UEAxMEdGVzdDEWMBQGA1UEChMNRGVtb3MgQ28gTHRkLjEeMBwG" +"A1UECxMVQ3J5cHRvZ3JhcGh5IGRpdmlzaW9uMQ8wDQYDVQQHEwZNb3Njb3cxCzAJBgNVBAYTAnJ1" +"MRkwFwYJKoZIhvcNAQkBFgpzZGJAZG9sLnJ1MGMwHAYGKoUDAgITMBIGByqFAwICIwIGByqFAwIC" +"HgEDQwAEQI5SLoWT7dZVilbV9j5B/fyIDuDs6x4pjqNC2TtFYbpRHrk/Wc5g/mcHvD80tsm5o1C7" +"7cizNzkvAVUM4VT4Dz6gADAIBgYqhQMCAgMDQQAoT5TwJ8o+bSrxckymyo3diwG7ZbSytX4sRiKy" +"wXPWRS9LlBvPO2NqwpS2HUnxSU8rzfL9fJcybATf7Yt1OEVq"); private byte[] gost3410EC_C = Base64.decode( "MIIBRDCB9AIBADCBhzEVMBMGA1UEAxMMdGVzdCByZXF1ZXN0MRUwEwYDVQQKEwxEZW1vcyBDbyBM" +"dGQxHjAcBgNVBAsTFUNyeXB0b2dyYXBoeSBkaXZpc2lvbjEPMA0GA1UEBxMGTW9zY293MQswCQYD" +"VQQGEwJydTEZMBcGCSqGSIb3DQEJARYKc2RiQGRvbC5ydTBjMBwGBiqFAwICEzASBgcqhQMCAiMD" +"BgcqhQMCAh4BA0MABEBcmGh7OmR4iqqj+ycYo1S1fS7r5PhisSQU2Ezuz8wmmmR2zeTZkdMYCOBa" +"UTMNms0msW3wuYDho7nTDNscHTB5oAAwCAYGKoUDAgIDA0EAVoOMbfyo1Un4Ss7WQrUjHJoiaYW8" +"Ime5LeGGU2iW3ieAv6es/FdMrwTKkqn5dhd3aL/itFg5oQbhyfXw5yw/QQ=="); private byte[] gost3410EC_ExA = Base64.decode( "MIIBOzCB6wIBADB/MQ0wCwYDVQQDEwR0ZXN0MRUwEwYDVQQKEwxEZW1vcyBDbyBMdGQxHjAcBgNV" + "BAsTFUNyeXB0b2dyYXBoeSBkaXZpc2lvbjEPMA0GA1UEBxMGTW9zY293MQswCQYDVQQGEwJydTEZ" + "MBcGCSqGSIb3DQEJARYKc2RiQGRvbC5ydTBjMBwGBiqFAwICEzASBgcqhQMCAiQABgcqhQMCAh4B" + "A0MABEDkqNT/3f8NHj6EUiWnK4JbVZBh31bEpkwq9z3jf0u8ZndG56Vt+K1ZB6EpFxLT7hSIos0w" + "weZ2YuTZ4w43OgodoAAwCAYGKoUDAgIDA0EASk/IUXWxoi6NtcUGVF23VRV1L3undB4sRZLp4Vho" + "gQ7m3CMbZFfJ2cPu6QyarseXGYHmazoirH5lGjEo535c1g=="); private byte[] gost3410EC_ExB = Base64.decode( "MIIBPTCB7QIBADCBgDENMAsGA1UEAxMEdGVzdDEWMBQGA1UEChMNRGVtb3MgQ28gTHRkLjEeMBwG" + "A1UECxMVQ3J5cHRvZ3JhcGh5IGRpdmlzaW9uMQ8wDQYDVQQHEwZNb3Njb3cxCzAJBgNVBAYTAnJ1" + "MRkwFwYJKoZIhvcNAQkBFgpzZGJAZG9sLnJ1MGMwHAYGKoUDAgITMBIGByqFAwICJAEGByqFAwIC" + "HgEDQwAEQMBWYUKPy/1Kxad9ChAmgoSWSYOQxRnXo7KEGLU5RNSXA4qMUvArWzvhav+EYUfTbWLh" + "09nELDyHt2XQcvgQHnSgADAIBgYqhQMCAgMDQQAdaNhgH/ElHp64mbMaEo1tPCg9Q22McxpH8rCz" + "E0QBpF4H5mSSQVGI5OAXHToetnNuh7gHHSynyCupYDEHTbkZ"); public String getName() { return "PKCS10CertRequest"; } private void rsaCreationTest() throws Exception { // // a lightweight key pair. // RSAKeyParameters lwPubKey = new RSAKeyParameters( false, new BigInteger("b4a7e46170574f16a97082b22be58b6a2a629798419be12872a4bdba626cfae9900f76abfb12139dce5de56564fab2b6543165a040c606887420e33d91ed7ed7", 16), new BigInteger("11", 16)); RSAPrivateCrtKeyParameters lwPrivKey = new RSAPrivateCrtKeyParameters( new BigInteger("b4a7e46170574f16a97082b22be58b6a2a629798419be12872a4bdba626cfae9900f76abfb12139dce5de56564fab2b6543165a040c606887420e33d91ed7ed7", 16), new BigInteger("11", 16), new BigInteger("9f66f6b05410cd503b2709e88115d55daced94d1a34d4e32bf824d0dde6028ae79c5f07b580f5dce240d7111f7ddb130a7945cd7d957d1920994da389f490c89", 16), new BigInteger("c0a0758cdf14256f78d4708c86becdead1b50ad4ad6c5c703e2168fbf37884cb", 16), new BigInteger("f01734d7960ea60070f1b06f2bb81bfac48ff192ae18451d5e56c734a5aab8a5", 16), new BigInteger("b54bb9edff22051d9ee60f9351a48591b6500a319429c069a3e335a1d6171391", 16), new BigInteger("d3d83daf2a0cecd3367ae6f8ae1aeb82e9ac2f816c6fc483533d8297dd7884cd", 16), new BigInteger("b8f52fc6f38593dabb661d3f50f8897f8106eee68b1bce78a95b132b4e5b5d19", 16)); // // distinguished name table. // X500NameBuilder builder = new X500NameBuilder(BCStyle.INSTANCE); builder.addRDN(BCStyle.C, "AU"); builder.addRDN(BCStyle.O, "The Legion of the Bouncy Castle"); builder.addRDN(BCStyle.L, "Melbourne"); builder.addRDN(BCStyle.ST, "Victoria"); builder.addRDN(BCStyle.E, "feedback-crypto@bouncycastle.org"); // // extensions // // // create the certificate - version 3 - without extensions // AlgorithmIdentifier sigAlgId = new DefaultSignatureAlgorithmIdentifierFinder().find("SHA256WithRSAEncryption"); AlgorithmIdentifier digAlgId = new DefaultDigestAlgorithmIdentifierFinder().find(sigAlgId); ContentSigner sigGen = new BcRSAContentSignerBuilder(sigAlgId, digAlgId).build(lwPrivKey); SubjectPublicKeyInfo pubInfo = new SubjectPublicKeyInfo(new AlgorithmIdentifier(PKCSObjectIdentifiers.rsaEncryption, DERNull.INSTANCE), new RSAPublicKey(lwPubKey.getModulus(), lwPubKey.getExponent())); X500NameBuilder x500NameBld = new X500NameBuilder(BCStyle.INSTANCE); x500NameBld.addRDN(BCStyle.C, "AU"); x500NameBld.addRDN(BCStyle.O, "The Legion of the Bouncy Castle"); x500NameBld.addRDN(BCStyle.L, "Melbourne"); x500NameBld.addRDN(BCStyle.ST, "Victoria"); x500NameBld.addRDN(BCStyle.EmailAddress, "feedback-crypto@bouncycastle.org"); X500Name subject = x500NameBld.build(); PKCS10CertificationRequestBuilder requestBuilder = new PKCS10CertificationRequestBuilder(subject, pubInfo); PKCS10CertificationRequest req1 = requestBuilder.build(sigGen); PKCS10CertificationRequest req2 = new PKCS10CertificationRequest(req1.getEncoded()); if (!req2.isSignatureValid(new BcRSAContentVerifierProviderBuilder(new DefaultDigestAlgorithmIdentifierFinder()).build(lwPubKey))) { fail("Failed verify check."); } if (!Arrays.areEqual(req2.getSubjectPublicKeyInfo().getEncoded(), req1.getSubjectPublicKeyInfo().getEncoded())) { fail("Failed public key check."); } } public void performTest() throws Exception { rsaCreationTest(); } public static void main( String[] args) { runTest(new PKCS10Test()); } } bouncycastle-1.49.orig/j2me/org/bouncycastle/cert/test/RegressionTest.java0000644000175000017500000000127611732217612026317 0ustar ebourgebourgpackage org.bouncycastle.cert.test; import org.bouncycastle.util.test.Test; import org.bouncycastle.util.test.TestResult; public class RegressionTest { public static Test[] tests = { new AttrCertTest(), new AttrCertSelectorTest(), new CertTest(), new PKCS10Test() }; public static void main( String[] args) { for (int i = 0; i != tests.length; i++) { TestResult result = tests[i].perform(); if (result.getException() != null) { result.getException().printStackTrace(); } System.out.println(result); } } } bouncycastle-1.49.orig/j2me/org/bouncycastle/cert/test/CertTest.java0000644000175000017500000023647611732214467025115 0ustar ebourgebourgpackage org.bouncycastle.cert.test; import java.math.BigInteger; import java.util.Date; import org.bouncycastle.asn1.DERNull; import org.bouncycastle.asn1.pkcs.PKCSObjectIdentifiers; import org.bouncycastle.asn1.pkcs.RSAPublicKey; import org.bouncycastle.asn1.x500.X500NameBuilder; import org.bouncycastle.asn1.x500.style.BCStyle; import org.bouncycastle.asn1.x509.AlgorithmIdentifier; import org.bouncycastle.asn1.x509.SubjectPublicKeyInfo; import org.bouncycastle.cert.X509CertificateHolder; import org.bouncycastle.cert.X509v3CertificateBuilder; import org.bouncycastle.crypto.params.RSAKeyParameters; import org.bouncycastle.crypto.params.RSAPrivateCrtKeyParameters; import org.bouncycastle.operator.ContentSigner; import org.bouncycastle.operator.ContentVerifierProvider; import org.bouncycastle.operator.DefaultDigestAlgorithmIdentifierFinder; import org.bouncycastle.operator.DefaultSignatureAlgorithmIdentifierFinder; import org.bouncycastle.operator.bc.BcRSAContentSignerBuilder; import org.bouncycastle.operator.bc.BcRSAContentVerifierProviderBuilder; import org.bouncycastle.util.encoders.Base64; import org.bouncycastle.util.test.SimpleTest; public class CertTest extends SimpleTest { // test CA byte[] testCAp12 = Base64.decode( "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" + "HLhcYQcQ1R+RucctAgIEAAAA"); // // server.crt // byte[] cert1 = Base64.decode( "MIIDXjCCAsegAwIBAgIBBzANBgkqhkiG9w0BAQQFADCBtzELMAkGA1UEBhMCQVUx" + "ETAPBgNVBAgTCFZpY3RvcmlhMRgwFgYDVQQHEw9Tb3V0aCBNZWxib3VybmUxGjAY" + "BgNVBAoTEUNvbm5lY3QgNCBQdHkgTHRkMR4wHAYDVQQLExVDZXJ0aWZpY2F0ZSBB" + "dXRob3JpdHkxFTATBgNVBAMTDENvbm5lY3QgNCBDQTEoMCYGCSqGSIb3DQEJARYZ" + "d2VibWFzdGVyQGNvbm5lY3Q0LmNvbS5hdTAeFw0wMDA2MDIwNzU2MjFaFw0wMTA2" + "MDIwNzU2MjFaMIG4MQswCQYDVQQGEwJBVTERMA8GA1UECBMIVmljdG9yaWExGDAW" + "BgNVBAcTD1NvdXRoIE1lbGJvdXJuZTEaMBgGA1UEChMRQ29ubmVjdCA0IFB0eSBM" + "dGQxFzAVBgNVBAsTDldlYnNlcnZlciBUZWFtMR0wGwYDVQQDExR3d3cyLmNvbm5l" + "Y3Q0LmNvbS5hdTEoMCYGCSqGSIb3DQEJARYZd2VibWFzdGVyQGNvbm5lY3Q0LmNv" + "bS5hdTCBnzANBgkqhkiG9w0BAQEFAAOBjQAwgYkCgYEArvDxclKAhyv7Q/Wmr2re" + "Gw4XL9Cnh9e+6VgWy2AWNy/MVeXdlxzd7QAuc1eOWQkGQEiLPy5XQtTY+sBUJ3AO" + "Rvd2fEVJIcjf29ey7bYua9J/vz5MG2KYo9/WCHIwqD9mmG9g0xLcfwq/s8ZJBswE" + "7sb85VU+h94PTvsWOsWuKaECAwEAAaN3MHUwJAYDVR0RBB0wG4EZd2VibWFzdGVy" + "QGNvbm5lY3Q0LmNvbS5hdTA6BglghkgBhvhCAQ0ELRYrbW9kX3NzbCBnZW5lcmF0" + "ZWQgY3VzdG9tIHNlcnZlciBjZXJ0aWZpY2F0ZTARBglghkgBhvhCAQEEBAMCBkAw" + "DQYJKoZIhvcNAQEEBQADgYEAotccfKpwSsIxM1Hae8DR7M/Rw8dg/RqOWx45HNVL" + "iBS4/3N/TO195yeQKbfmzbAA2jbPVvIvGgTxPgO1MP4ZgvgRhasaa0qCJCkWvpM4" + "yQf33vOiYQbpv4rTwzU8AmRlBG45WdjyNIigGV+oRc61aKCTnLq7zB8N3z1TF/bF" + "5/8="); // // ca.crt // byte[] cert2 = Base64.decode( "MIIDbDCCAtWgAwIBAgIBADANBgkqhkiG9w0BAQQFADCBtzELMAkGA1UEBhMCQVUx" + "ETAPBgNVBAgTCFZpY3RvcmlhMRgwFgYDVQQHEw9Tb3V0aCBNZWxib3VybmUxGjAY" + "BgNVBAoTEUNvbm5lY3QgNCBQdHkgTHRkMR4wHAYDVQQLExVDZXJ0aWZpY2F0ZSBB" + "dXRob3JpdHkxFTATBgNVBAMTDENvbm5lY3QgNCBDQTEoMCYGCSqGSIb3DQEJARYZ" + "d2VibWFzdGVyQGNvbm5lY3Q0LmNvbS5hdTAeFw0wMDA2MDIwNzU1MzNaFw0wMTA2" + "MDIwNzU1MzNaMIG3MQswCQYDVQQGEwJBVTERMA8GA1UECBMIVmljdG9yaWExGDAW" + "BgNVBAcTD1NvdXRoIE1lbGJvdXJuZTEaMBgGA1UEChMRQ29ubmVjdCA0IFB0eSBM" + "dGQxHjAcBgNVBAsTFUNlcnRpZmljYXRlIEF1dGhvcml0eTEVMBMGA1UEAxMMQ29u" + "bmVjdCA0IENBMSgwJgYJKoZIhvcNAQkBFhl3ZWJtYXN0ZXJAY29ubmVjdDQuY29t" + "LmF1MIGfMA0GCSqGSIb3DQEBAQUAA4GNADCBiQKBgQDgs5ptNG6Qv1ZpCDuUNGmv" + "rhjqMDPd3ri8JzZNRiiFlBA4e6/ReaO1U8ASewDeQMH6i9R6degFdQRLngbuJP0s" + "xcEE+SksEWNvygfzLwV9J/q+TQDyJYK52utb++lS0b48A1KPLwEsyL6kOAgelbur" + "ukwxowprKUIV7Knf1ajetQIDAQABo4GFMIGCMCQGA1UdEQQdMBuBGXdlYm1hc3Rl" + "ckBjb25uZWN0NC5jb20uYXUwDwYDVR0TBAgwBgEB/wIBADA2BglghkgBhvhCAQ0E" + "KRYnbW9kX3NzbCBnZW5lcmF0ZWQgY3VzdG9tIENBIGNlcnRpZmljYXRlMBEGCWCG" + "SAGG+EIBAQQEAwICBDANBgkqhkiG9w0BAQQFAAOBgQCsGvfdghH8pPhlwm1r3pQk" + "msnLAVIBb01EhbXm2861iXZfWqGQjrGAaA0ZpXNk9oo110yxoqEoSJSzniZa7Xtz" + "soTwNUpE0SLHvWf/SlKdFWlzXA+vOZbzEv4UmjeelekTm7lc01EEa5QRVzOxHFtQ" + "DhkaJ8VqOMajkQFma2r9iA=="); // // testx509.pem // byte[] cert3 = Base64.decode( "MIIBWzCCAQYCARgwDQYJKoZIhvcNAQEEBQAwODELMAkGA1UEBhMCQVUxDDAKBgNV" + "BAgTA1FMRDEbMBkGA1UEAxMSU1NMZWF5L3JzYSB0ZXN0IENBMB4XDTk1MDYxOTIz" + "MzMxMloXDTk1MDcxNzIzMzMxMlowOjELMAkGA1UEBhMCQVUxDDAKBgNVBAgTA1FM" + "RDEdMBsGA1UEAxMUU1NMZWF5L3JzYSB0ZXN0IGNlcnQwXDANBgkqhkiG9w0BAQEF" + "AANLADBIAkEAqtt6qS5GTxVxGZYWa0/4u+IwHf7p2LNZbcPBp9/OfIcYAXBQn8hO" + "/Re1uwLKXdCjIoaGs4DLdG88rkzfyK5dPQIDAQABMAwGCCqGSIb3DQIFBQADQQAE" + "Wc7EcF8po2/ZO6kNCwK/ICH6DobgLekA5lSLr5EvuioZniZp5lFzAw4+YzPQ7XKJ" + "zl9HYIMxATFyqSiD9jsx"); // // v3-cert1.pem // byte[] cert4 = Base64.decode( "MIICjTCCAfigAwIBAgIEMaYgRzALBgkqhkiG9w0BAQQwRTELMAkGA1UEBhMCVVMx" + "NjA0BgNVBAoTLU5hdGlvbmFsIEFlcm9uYXV0aWNzIGFuZCBTcGFjZSBBZG1pbmlz" + "dHJhdGlvbjAmFxE5NjA1MjgxMzQ5MDUrMDgwMBcROTgwNTI4MTM0OTA1KzA4MDAw" + "ZzELMAkGA1UEBhMCVVMxNjA0BgNVBAoTLU5hdGlvbmFsIEFlcm9uYXV0aWNzIGFu" + "ZCBTcGFjZSBBZG1pbmlzdHJhdGlvbjEgMAkGA1UEBRMCMTYwEwYDVQQDEwxTdGV2" + "ZSBTY2hvY2gwWDALBgkqhkiG9w0BAQEDSQAwRgJBALrAwyYdgxmzNP/ts0Uyf6Bp" + "miJYktU/w4NG67ULaN4B5CnEz7k57s9o3YY3LecETgQ5iQHmkwlYDTL2fTgVfw0C" + "AQOjgaswgagwZAYDVR0ZAQH/BFowWDBWMFQxCzAJBgNVBAYTAlVTMTYwNAYDVQQK" + "Ey1OYXRpb25hbCBBZXJvbmF1dGljcyBhbmQgU3BhY2UgQWRtaW5pc3RyYXRpb24x" + "DTALBgNVBAMTBENSTDEwFwYDVR0BAQH/BA0wC4AJODMyOTcwODEwMBgGA1UdAgQR" + "MA8ECTgzMjk3MDgyM4ACBSAwDQYDVR0KBAYwBAMCBkAwCwYJKoZIhvcNAQEEA4GB" + "AH2y1VCEw/A4zaXzSYZJTTUi3uawbbFiS2yxHvgf28+8Js0OHXk1H1w2d6qOHH21" + "X82tZXd/0JtG0g1T9usFFBDvYK8O0ebgz/P5ELJnBL2+atObEuJy1ZZ0pBDWINR3" + "WkDNLCGiTkCKp0F5EWIrVDwh54NNevkCQRZita+z4IBO"); // // v3-cert2.pem // byte[] cert5 = Base64.decode( "MIICiTCCAfKgAwIBAgIEMeZfHzANBgkqhkiG9w0BAQQFADB9MQswCQYDVQQGEwJD" + "YTEPMA0GA1UEBxMGTmVwZWFuMR4wHAYDVQQLExVObyBMaWFiaWxpdHkgQWNjZXB0" + "ZWQxHzAdBgNVBAoTFkZvciBEZW1vIFB1cnBvc2VzIE9ubHkxHDAaBgNVBAMTE0Vu" + "dHJ1c3QgRGVtbyBXZWIgQ0EwHhcNOTYwNzEyMTQyMDE1WhcNOTYxMDEyMTQyMDE1" + "WjB0MSQwIgYJKoZIhvcNAQkBExVjb29rZUBpc3NsLmF0bC5ocC5jb20xCzAJBgNV" + "BAYTAlVTMScwJQYDVQQLEx5IZXdsZXR0IFBhY2thcmQgQ29tcGFueSAoSVNTTCkx" + "FjAUBgNVBAMTDVBhdWwgQS4gQ29va2UwXDANBgkqhkiG9w0BAQEFAANLADBIAkEA" + "6ceSq9a9AU6g+zBwaL/yVmW1/9EE8s5you1mgjHnj0wAILuoB3L6rm6jmFRy7QZT" + "G43IhVZdDua4e+5/n1ZslwIDAQABo2MwYTARBglghkgBhvhCAQEEBAMCB4AwTAYJ" + "YIZIAYb4QgENBD8WPVRoaXMgY2VydGlmaWNhdGUgaXMgb25seSBpbnRlbmRlZCBm" + "b3IgZGVtb25zdHJhdGlvbiBwdXJwb3Nlcy4wDQYJKoZIhvcNAQEEBQADgYEAi8qc" + "F3zfFqy1sV8NhjwLVwOKuSfhR/Z8mbIEUeSTlnH3QbYt3HWZQ+vXI8mvtZoBc2Fz" + "lexKeIkAZXCesqGbs6z6nCt16P6tmdfbZF3I3AWzLquPcOXjPf4HgstkyvVBn0Ap" + "jAFN418KF/Cx4qyHB4cjdvLrRjjQLnb2+ibo7QU="); // // pem encoded pkcs7 // byte[] cert6 = Base64.decode( "MIAGCSqGSIb3DQEHAqCAMIACAQExCzAJBgUrDgMCGgUAMIAGCSqGSIb3DQEHAQAAoIIJbzCCAj0w" + "ggGmAhEAzbp/VvDf5LxU/iKss3KqVTANBgkqhkiG9w0BAQIFADBfMQswCQYDVQQGEwJVUzEXMBUG" + "A1UEChMOVmVyaVNpZ24sIEluYy4xNzA1BgNVBAsTLkNsYXNzIDEgUHVibGljIFByaW1hcnkgQ2Vy" + "dGlmaWNhdGlvbiBBdXRob3JpdHkwHhcNOTYwMTI5MDAwMDAwWhcNMjgwODAxMjM1OTU5WjBfMQsw" + "CQYDVQQGEwJVUzEXMBUGA1UEChMOVmVyaVNpZ24sIEluYy4xNzA1BgNVBAsTLkNsYXNzIDEgUHVi" + "bGljIFByaW1hcnkgQ2VydGlmaWNhdGlvbiBBdXRob3JpdHkwgZ8wDQYJKoZIhvcNAQEBBQADgY0A" + "MIGJAoGBAOUZv22jVmEtmUhx9mfeuY3rt56GgAqRDvo4Ja9GiILlc6igmyRdDR/MZW4MsNBWhBiH" + "mgabEKFz37RYOWtuwfYV1aioP6oSBo0xrH+wNNePNGeICc0UEeJORVZpH3gCgNrcR5EpuzbJY1zF" + "4Ncth3uhtzKwezC6Ki8xqu6jZ9rbAgMBAAEwDQYJKoZIhvcNAQECBQADgYEATD+4i8Zo3+5DMw5d" + "6abLB4RNejP/khv0Nq3YlSI2aBFsfELM85wuxAc/FLAPT/+Qknb54rxK6Y/NoIAK98Up8YIiXbix" + "3YEjo3slFUYweRb46gVLlH8dwhzI47f0EEA8E8NfH1PoSOSGtHuhNbB7Jbq4046rPzidADQAmPPR" + "cZQwggMuMIICl6ADAgECAhEA0nYujRQMPX2yqCVdr+4NdTANBgkqhkiG9w0BAQIFADBfMQswCQYD" + "VQQGEwJVUzEXMBUGA1UEChMOVmVyaVNpZ24sIEluYy4xNzA1BgNVBAsTLkNsYXNzIDEgUHVibGlj" + "IFByaW1hcnkgQ2VydGlmaWNhdGlvbiBBdXRob3JpdHkwHhcNOTgwNTEyMDAwMDAwWhcNMDgwNTEy" + "MjM1OTU5WjCBzDEXMBUGA1UEChMOVmVyaVNpZ24sIEluYy4xHzAdBgNVBAsTFlZlcmlTaWduIFRy" + "dXN0IE5ldHdvcmsxRjBEBgNVBAsTPXd3dy52ZXJpc2lnbi5jb20vcmVwb3NpdG9yeS9SUEEgSW5j" + "b3JwLiBCeSBSZWYuLExJQUIuTFREKGMpOTgxSDBGBgNVBAMTP1ZlcmlTaWduIENsYXNzIDEgQ0Eg" + "SW5kaXZpZHVhbCBTdWJzY3JpYmVyLVBlcnNvbmEgTm90IFZhbGlkYXRlZDCBnzANBgkqhkiG9w0B" + "AQEFAAOBjQAwgYkCgYEAu1pEigQWu1X9A3qKLZRPFXg2uA1Ksm+cVL+86HcqnbnwaLuV2TFBcHqB" + "S7lIE1YtxwjhhEKrwKKSq0RcqkLwgg4C6S/7wju7vsknCl22sDZCM7VuVIhPh0q/Gdr5FegPh7Yc" + "48zGmo5/aiSS4/zgZbqnsX7vyds3ashKyAkG5JkCAwEAAaN8MHowEQYJYIZIAYb4QgEBBAQDAgEG" + "MEcGA1UdIARAMD4wPAYLYIZIAYb4RQEHAQEwLTArBggrBgEFBQcCARYfd3d3LnZlcmlzaWduLmNv" + "bS9yZXBvc2l0b3J5L1JQQTAPBgNVHRMECDAGAQH/AgEAMAsGA1UdDwQEAwIBBjANBgkqhkiG9w0B" + "AQIFAAOBgQCIuDc73dqUNwCtqp/hgQFxHpJqbS/28Z3TymQ43BuYDAeGW4UVag+5SYWklfEXfWe0" + "fy0s3ZpCnsM+tI6q5QsG3vJWKvozx74Z11NMw73I4xe1pElCY+zCphcPXVgaSTyQXFWjZSAA/Rgg" + "5V+CprGoksVYasGNAzzrw80FopCubjCCA/gwggNhoAMCAQICEBbbn/1G1zppD6KsP01bwywwDQYJ" + "KoZIhvcNAQEEBQAwgcwxFzAVBgNVBAoTDlZlcmlTaWduLCBJbmMuMR8wHQYDVQQLExZWZXJpU2ln" + "biBUcnVzdCBOZXR3b3JrMUYwRAYDVQQLEz13d3cudmVyaXNpZ24uY29tL3JlcG9zaXRvcnkvUlBB" + "IEluY29ycC4gQnkgUmVmLixMSUFCLkxURChjKTk4MUgwRgYDVQQDEz9WZXJpU2lnbiBDbGFzcyAx" + "IENBIEluZGl2aWR1YWwgU3Vic2NyaWJlci1QZXJzb25hIE5vdCBWYWxpZGF0ZWQwHhcNMDAxMDAy" + "MDAwMDAwWhcNMDAxMjAxMjM1OTU5WjCCAQcxFzAVBgNVBAoTDlZlcmlTaWduLCBJbmMuMR8wHQYD" + "VQQLExZWZXJpU2lnbiBUcnVzdCBOZXR3b3JrMUYwRAYDVQQLEz13d3cudmVyaXNpZ24uY29tL3Jl" + "cG9zaXRvcnkvUlBBIEluY29ycC4gYnkgUmVmLixMSUFCLkxURChjKTk4MR4wHAYDVQQLExVQZXJz" + "b25hIE5vdCBWYWxpZGF0ZWQxJzAlBgNVBAsTHkRpZ2l0YWwgSUQgQ2xhc3MgMSAtIE1pY3Jvc29m" + "dDETMBEGA1UEAxQKRGF2aWQgUnlhbjElMCMGCSqGSIb3DQEJARYWZGF2aWRAbGl2ZW1lZGlhLmNv" + "bS5hdTCBnzANBgkqhkiG9w0BAQEFAAOBjQAwgYkCgYEAqxBsdeNmSvFqhMNwhQgNzM8mdjX9eSXb" + "DawpHtQHjmh0AKJSa3IwUY0VIsyZHuXWktO/CgaMBVPt6OVf/n0R2sQigMP6Y+PhEiS0vCJBL9aK" + "0+pOo2qXrjVBmq+XuCyPTnc+BOSrU26tJsX0P9BYorwySiEGxGanBNATdVL4NdUCAwEAAaOBnDCB" + "mTAJBgNVHRMEAjAAMEQGA1UdIAQ9MDswOQYLYIZIAYb4RQEHAQgwKjAoBggrBgEFBQcCARYcaHR0" + "cHM6Ly93d3cudmVyaXNpZ24uY29tL3JwYTARBglghkgBhvhCAQEEBAMCB4AwMwYDVR0fBCwwKjAo" + "oCagJIYiaHR0cDovL2NybC52ZXJpc2lnbi5jb20vY2xhc3MxLmNybDANBgkqhkiG9w0BAQQFAAOB" + "gQBC8yIIdVGpFTf8/YiL14cMzcmL0nIRm4kGR3U59z7UtcXlfNXXJ8MyaeI/BnXwG/gD5OKYqW6R" + "yca9vZOxf1uoTBl82gInk865ED3Tej6msCqFzZffnSUQvOIeqLxxDlqYRQ6PmW2nAnZeyjcnbI5Y" + "syQSM2fmo7n6qJFP+GbFezGCAkUwggJBAgEBMIHhMIHMMRcwFQYDVQQKEw5WZXJpU2lnbiwgSW5j" + "LjEfMB0GA1UECxMWVmVyaVNpZ24gVHJ1c3QgTmV0d29yazFGMEQGA1UECxM9d3d3LnZlcmlzaWdu" + "LmNvbS9yZXBvc2l0b3J5L1JQQSBJbmNvcnAuIEJ5IFJlZi4sTElBQi5MVEQoYyk5ODFIMEYGA1UE" + "AxM/VmVyaVNpZ24gQ2xhc3MgMSBDQSBJbmRpdmlkdWFsIFN1YnNjcmliZXItUGVyc29uYSBOb3Qg" + "VmFsaWRhdGVkAhAW25/9Rtc6aQ+irD9NW8MsMAkGBSsOAwIaBQCggbowGAYJKoZIhvcNAQkDMQsG" + "CSqGSIb3DQEHATAcBgkqhkiG9w0BCQUxDxcNMDAxMDAyMTczNTE4WjAjBgkqhkiG9w0BCQQxFgQU" + "gZjSaBEY2oxGvlQUIMnxSXhivK8wWwYJKoZIhvcNAQkPMU4wTDAKBggqhkiG9w0DBzAOBggqhkiG" + "9w0DAgICAIAwDQYIKoZIhvcNAwICAUAwBwYFKw4DAgcwDQYIKoZIhvcNAwICASgwBwYFKw4DAh0w" + "DQYJKoZIhvcNAQEBBQAEgYAzk+PU91/ZFfoiuKOECjxEh9fDYE2jfDCheBIgh5gdcCo+sS1WQs8O" + "HreQ9Nop/JdJv1DQMBK6weNBBDoP0EEkRm1XCC144XhXZC82jBZohYmi2WvDbbC//YN58kRMYMyy" + "srrfn4Z9I+6kTriGXkrpGk9Q0LSGjmG2BIsqiF0dvwAAAAAAAA=="); // // dsaWithSHA1 cert // byte[] cert7 = Base64.decode( "MIIEXAYJKoZIhvcNAQcCoIIETTCCBEkCAQExCzAJBgUrDgMCGgUAMAsGCSqG" + "SIb3DQEHAaCCAsMwggK/MIIB4AIBADCBpwYFKw4DAhswgZ0CQQEkJRHP+mN7" + "d8miwTMN55CUSmo3TO8WGCxgY61TX5k+7NU4XPf1TULjw3GobwaJX13kquPh" + "fVXk+gVy46n4Iw3hAhUBSe/QF4BUj+pJOF9ROBM4u+FEWA8CQQD4mSJbrABj" + "TUWrlnAte8pS22Tq4/FPO7jHSqjijUHfXKTrHL1OEqV3SVWcFy5j/cqBgX/z" + "m8Q12PFp/PjOhh+nMA4xDDAKBgNVBAMTA0lEMzAeFw05NzEwMDEwMDAwMDBa" + "Fw0zODAxMDEwMDAwMDBaMA4xDDAKBgNVBAMTA0lEMzCB8DCBpwYFKw4DAhsw" + "gZ0CQQEkJRHP+mN7d8miwTMN55CUSmo3TO8WGCxgY61TX5k+7NU4XPf1TULj" + "w3GobwaJX13kquPhfVXk+gVy46n4Iw3hAhUBSe/QF4BUj+pJOF9ROBM4u+FE" + "WA8CQQD4mSJbrABjTUWrlnAte8pS22Tq4/FPO7jHSqjijUHfXKTrHL1OEqV3" + "SVWcFy5j/cqBgX/zm8Q12PFp/PjOhh+nA0QAAkEAkYkXLYMtGVGWj9OnzjPn" + "sB9sefSRPrVegZJCZbpW+Iv0/1RP1u04pHG9vtRpIQLjzUiWvLMU9EKQTThc" + "eNMmWDCBpwYFKw4DAhswgZ0CQQEkJRHP+mN7d8miwTMN55CUSmo3TO8WGCxg" + "Y61TX5k+7NU4XPf1TULjw3GobwaJX13kquPhfVXk+gVy46n4Iw3hAhUBSe/Q" + "F4BUj+pJOF9ROBM4u+FEWA8CQQD4mSJbrABjTUWrlnAte8pS22Tq4/FPO7jH" + "SqjijUHfXKTrHL1OEqV3SVWcFy5j/cqBgX/zm8Q12PFp/PjOhh+nAy8AMCwC" + "FBY3dBSdeprGcqpr6wr3xbG+6WW+AhRMm/facKJNxkT3iKgJbp7R8Xd3QTGC" + "AWEwggFdAgEBMBMwDjEMMAoGA1UEAxMDSUQzAgEAMAkGBSsOAwIaBQCgXTAY" + "BgkqhkiG9w0BCQMxCwYJKoZIhvcNAQcBMBwGCSqGSIb3DQEJBTEPFw0wMjA1" + "MjQyMzEzMDdaMCMGCSqGSIb3DQEJBDEWBBS4WMsoJhf7CVbZYCFcjoTRzPkJ" + "xjCBpwYFKw4DAhswgZ0CQQEkJRHP+mN7d8miwTMN55CUSmo3TO8WGCxgY61T" + "X5k+7NU4XPf1TULjw3GobwaJX13kquPhfVXk+gVy46n4Iw3hAhUBSe/QF4BU" + "j+pJOF9ROBM4u+FEWA8CQQD4mSJbrABjTUWrlnAte8pS22Tq4/FPO7jHSqji" + "jUHfXKTrHL1OEqV3SVWcFy5j/cqBgX/zm8Q12PFp/PjOhh+nBC8wLQIVALID" + "dt+MHwawrDrwsO1Z6sXBaaJsAhRaKssrpevmLkbygKPV07XiAKBG02Zvb2Jh" + "cg=="); // // testcrl.pem // byte[] crl1 = Base64.decode( "MIICjTCCAfowDQYJKoZIhvcNAQECBQAwXzELMAkGA1UEBhMCVVMxIDAeBgNVBAoT" + "F1JTQSBEYXRhIFNlY3VyaXR5LCBJbmMuMS4wLAYDVQQLEyVTZWN1cmUgU2VydmVy" + "IENlcnRpZmljYXRpb24gQXV0aG9yaXR5Fw05NTA1MDIwMjEyMjZaFw05NTA2MDEw" + "MDAxNDlaMIIBaDAWAgUCQQAABBcNOTUwMjAxMTcyNDI2WjAWAgUCQQAACRcNOTUw" + "MjEwMDIxNjM5WjAWAgUCQQAADxcNOTUwMjI0MDAxMjQ5WjAWAgUCQQAADBcNOTUw" + "MjI1MDA0NjQ0WjAWAgUCQQAAGxcNOTUwMzEzMTg0MDQ5WjAWAgUCQQAAFhcNOTUw" + "MzE1MTkxNjU0WjAWAgUCQQAAGhcNOTUwMzE1MTk0MDQxWjAWAgUCQQAAHxcNOTUw" + "MzI0MTk0NDMzWjAWAgUCcgAABRcNOTUwMzI5MjAwNzExWjAWAgUCcgAAERcNOTUw" + "MzMwMDIzNDI2WjAWAgUCQQAAIBcNOTUwNDA3MDExMzIxWjAWAgUCcgAAHhcNOTUw" + "NDA4MDAwMjU5WjAWAgUCcgAAQRcNOTUwNDI4MTcxNzI0WjAWAgUCcgAAOBcNOTUw" + "NDI4MTcyNzIxWjAWAgUCcgAATBcNOTUwNTAyMDIxMjI2WjANBgkqhkiG9w0BAQIF" + "AAN+AHqOEJXSDejYy0UwxxrH/9+N2z5xu/if0J6qQmK92W0hW158wpJg+ovV3+wQ" + "wvIEPRL2rocL0tKfAsVq1IawSJzSNgxG0lrcla3MrJBnZ4GaZDu4FutZh72MR3Gt" + "JaAL3iTJHJD55kK2D/VoyY1djlsPuNh6AEgdVwFAyp0v"); // // ecdsa cert with extra octet string. // byte[] oldEcdsa = Base64.decode( "MIICljCCAkCgAwIBAgIBATALBgcqhkjOPQQBBQAwgY8xCzAJBgNVBAYTAkFVMSgwJ" + "gYDVQQKEx9UaGUgTGVnaW9uIG9mIHRoZSBCb3VuY3kgQ2FzdGxlMRIwEAYDVQQHEw" + "lNZWxib3VybmUxETAPBgNVBAgTCFZpY3RvcmlhMS8wLQYJKoZIhvcNAQkBFiBmZWV" + "kYmFjay1jcnlwdG9AYm91bmN5Y2FzdGxlLm9yZzAeFw0wMTEyMDcwMTAwMDRaFw0w" + "MTEyMDcwMTAxNDRaMIGPMQswCQYDVQQGEwJBVTEoMCYGA1UEChMfVGhlIExlZ2lvb" + "iBvZiB0aGUgQm91bmN5IENhc3RsZTESMBAGA1UEBxMJTWVsYm91cm5lMREwDwYDVQ" + "QIEwhWaWN0b3JpYTEvMC0GCSqGSIb3DQEJARYgZmVlZGJhY2stY3J5cHRvQGJvdW5" + "jeWNhc3RsZS5vcmcwgeQwgb0GByqGSM49AgEwgbECAQEwKQYHKoZIzj0BAQIef///" + "////////////f///////gAAAAAAAf///////MEAEHn///////////////3///////" + "4AAAAAAAH///////AQeawFsO9zxiUHQ1lSSFHXKcanbL7J9HTd5YYXClCwKBB8CD/" + "qWPNyogWzMM7hkK+35BcPTWFc9Pyf7vTs8uaqvAh5///////////////9///+eXpq" + "fXZBx+9FSJoiQnQsDIgAEHwJbbcU7xholSP+w9nFHLebJUhqdLSU05lq/y9X+DHAw" + "CwYHKoZIzj0EAQUAA0MAMEACHnz6t4UNoVROp74ma4XNDjjGcjaqiIWPZLK8Bdw3G" + "QIeLZ4j3a6ividZl344UH+UPUE7xJxlYGuy7ejTsqRR"); byte[] uncompressedPtEC = Base64.decode( "MIIDKzCCAsGgAwIBAgICA+kwCwYHKoZIzj0EAQUAMGYxCzAJBgNVBAYTAkpQ" + "MRUwEwYDVQQKEwxuaXRlY2guYWMuanAxDjAMBgNVBAsTBWFpbGFiMQ8wDQYD" + "VQQDEwZ0ZXN0Y2ExHzAdBgkqhkiG9w0BCQEWEHRlc3RjYUBsb2NhbGhvc3Qw" + "HhcNMDExMDEzMTE1MzE3WhcNMjAxMjEyMTE1MzE3WjBmMQswCQYDVQQGEwJK" + "UDEVMBMGA1UEChMMbml0ZWNoLmFjLmpwMQ4wDAYDVQQLEwVhaWxhYjEPMA0G" + "A1UEAxMGdGVzdGNhMR8wHQYJKoZIhvcNAQkBFhB0ZXN0Y2FAbG9jYWxob3N0" + "MIIBczCCARsGByqGSM49AgEwggEOAgEBMDMGByqGSM49AQECKEdYWnajFmnZ" + "tzrukK2XWdle2v+GsD9l1ZiR6g7ozQDbhFH/bBiMDQcwVAQoJ5EQKrI54/CT" + "xOQ2pMsd/fsXD+EX8YREd8bKHWiLz8lIVdD5cBNeVwQoMKSc6HfI7vKZp8Q2" + "zWgIFOarx1GQoWJbMcSt188xsl30ncJuJT2OoARRBAqJ4fD+q6hbqgNSjTQ7" + "htle1KO3eiaZgcJ8rrnyN8P+5A8+5K+H9aQ/NbBR4Gs7yto5PXIUZEUgodHA" + "TZMSAcSq5ZYt4KbnSYaLY0TtH9CqAigEwZ+hglbT21B7ZTzYX2xj0x+qooJD" + "hVTLtIPaYJK2HrMPxTw6/zfrAgEPA1IABAnvfFcFDgD/JicwBGn6vR3N8MIn" + "mptZf/mnJ1y649uCF60zOgdwIyI7pVSxBFsJ7ohqXEHW0x7LrGVkdSEiipiH" + "LYslqh3xrqbAgPbl93GUo0IwQDAPBgNVHRMBAf8EBTADAQH/MA4GA1UdDwEB" + "/wQEAwIBxjAdBgNVHQ4EFgQUAEo62Xm9H6DcsE0zUDTza4BRG90wCwYHKoZI" + "zj0EAQUAA1cAMFQCKAQsCHHSNOqfJXLgt3bg5+k49hIBGVr/bfG0B9JU3rNt" + "Ycl9Y2zfRPUCKAK2ccOQXByAWfsasDu8zKHxkZv7LVDTFjAIffz3HaCQeVhD" + "z+fauEg="); byte[] keyUsage = Base64.decode( "MIIE7TCCBFagAwIBAgIEOAOR7jANBgkqhkiG9w0BAQQFADCByTELMAkGA1UE" + "BhMCVVMxFDASBgNVBAoTC0VudHJ1c3QubmV0MUgwRgYDVQQLFD93d3cuZW50" + "cnVzdC5uZXQvQ2xpZW50X0NBX0luZm8vQ1BTIGluY29ycC4gYnkgcmVmLiBs" + "aW1pdHMgbGlhYi4xJTAjBgNVBAsTHChjKSAxOTk5IEVudHJ1c3QubmV0IExp" + "bWl0ZWQxMzAxBgNVBAMTKkVudHJ1c3QubmV0IENsaWVudCBDZXJ0aWZpY2F0" + "aW9uIEF1dGhvcml0eTAeFw05OTEwMTIxOTI0MzBaFw0xOTEwMTIxOTU0MzBa" + "MIHJMQswCQYDVQQGEwJVUzEUMBIGA1UEChMLRW50cnVzdC5uZXQxSDBGBgNV" + "BAsUP3d3dy5lbnRydXN0Lm5ldC9DbGllbnRfQ0FfSW5mby9DUFMgaW5jb3Jw" + "LiBieSByZWYuIGxpbWl0cyBsaWFiLjElMCMGA1UECxMcKGMpIDE5OTkgRW50" + "cnVzdC5uZXQgTGltaXRlZDEzMDEGA1UEAxMqRW50cnVzdC5uZXQgQ2xpZW50" + "IENlcnRpZmljYXRpb24gQXV0aG9yaXR5MIGdMA0GCSqGSIb3DQEBAQUAA4GL" + "ADCBhwKBgQDIOpleMRffrCdvkHvkGf9FozTC28GoT/Bo6oT9n3V5z8GKUZSv" + "x1cDR2SerYIbWtp/N3hHuzeYEpbOxhN979IMMFGpOZ5V+Pux5zDeg7K6PvHV" + "iTs7hbqqdCz+PzFur5GVbgbUB01LLFZHGARS2g4Qk79jkJvh34zmAqTmT173" + "iwIBA6OCAeAwggHcMBEGCWCGSAGG+EIBAQQEAwIABzCCASIGA1UdHwSCARkw" + "ggEVMIHkoIHhoIHepIHbMIHYMQswCQYDVQQGEwJVUzEUMBIGA1UEChMLRW50" + "cnVzdC5uZXQxSDBGBgNVBAsUP3d3dy5lbnRydXN0Lm5ldC9DbGllbnRfQ0Ff" + "SW5mby9DUFMgaW5jb3JwLiBieSByZWYuIGxpbWl0cyBsaWFiLjElMCMGA1UE" + "CxMcKGMpIDE5OTkgRW50cnVzdC5uZXQgTGltaXRlZDEzMDEGA1UEAxMqRW50" + "cnVzdC5uZXQgQ2xpZW50IENlcnRpZmljYXRpb24gQXV0aG9yaXR5MQ0wCwYD" + "VQQDEwRDUkwxMCygKqAohiZodHRwOi8vd3d3LmVudHJ1c3QubmV0L0NSTC9D" + "bGllbnQxLmNybDArBgNVHRAEJDAigA8xOTk5MTAxMjE5MjQzMFqBDzIwMTkx" + "MDEyMTkyNDMwWjALBgNVHQ8EBAMCAQYwHwYDVR0jBBgwFoAUxPucKXuXzUyW" + "/O5bs8qZdIuV6kwwHQYDVR0OBBYEFMT7nCl7l81MlvzuW7PKmXSLlepMMAwG" + "A1UdEwQFMAMBAf8wGQYJKoZIhvZ9B0EABAwwChsEVjQuMAMCBJAwDQYJKoZI" + "hvcNAQEEBQADgYEAP66K8ddmAwWePvrqHEa7pFuPeJoSSJn59DXeDDYHAmsQ" + "OokUgZwxpnyyQbJq5wcBoUv5nyU7lsqZwz6hURzzwy5E97BnRqqS5TvaHBkU" + "ODDV4qIxJS7x7EU47fgGWANzYrAQMY9Av2TgXD7FTx/aEkP/TOYGJqibGapE" + "PHayXOw="); byte[] nameCert = Base64.decode( "MIIEFjCCA3+gAwIBAgIEdS8BozANBgkqhkiG9w0BAQUFADBKMQswCQYDVQQGEwJE"+ "RTERMA8GA1UEChQIREFURVYgZUcxKDAMBgcCggYBCgcUEwExMBgGA1UEAxQRQ0Eg"+ "REFURVYgRDAzIDE6UE4wIhgPMjAwMTA1MTAxMDIyNDhaGA8yMDA0MDUwOTEwMjI0"+ "OFowgYQxCzAJBgNVBAYTAkRFMQ8wDQYDVQQIFAZCYXllcm4xEjAQBgNVBAcUCU7I"+ "dXJuYmVyZzERMA8GA1UEChQIREFURVYgZUcxHTAbBgNVBAUTFDAwMDAwMDAwMDA4"+ "OTU3NDM2MDAxMR4wHAYDVQQDFBVEaWV0bWFyIFNlbmdlbmxlaXRuZXIwgaEwDQYJ"+ "KoZIhvcNAQEBBQADgY8AMIGLAoGBAJLI/LJLKaHoMk8fBECW/od8u5erZi6jI8Ug"+ "C0a/LZyQUO/R20vWJs6GrClQtXB+AtfiBSnyZOSYzOdfDI8yEKPEv8qSuUPpOHps"+ "uNCFdLZF1vavVYGEEWs2+y+uuPmg8q1oPRyRmUZ+x9HrDvCXJraaDfTEd9olmB/Z"+ "AuC/PqpjAgUAwAAAAaOCAcYwggHCMAwGA1UdEwEB/wQCMAAwDwYDVR0PAQH/BAUD"+ "AwdAADAxBgNVHSAEKjAoMCYGBSskCAEBMB0wGwYIKwYBBQUHAgEWD3d3dy56cy5k"+ "YXRldi5kZTApBgNVHREEIjAggR5kaWV0bWFyLnNlbmdlbmxlaXRuZXJAZGF0ZXYu"+ "ZGUwgYQGA1UdIwR9MHuhc6RxMG8xCzAJBgNVBAYTAkRFMT0wOwYDVQQKFDRSZWd1"+ "bGllcnVuZ3NiZWjIb3JkZSBmyHVyIFRlbGVrb21tdW5pa2F0aW9uIHVuZCBQb3N0"+ "MSEwDAYHAoIGAQoHFBMBMTARBgNVBAMUCjVSLUNBIDE6UE6CBACm8LkwDgYHAoIG"+ "AQoMAAQDAQEAMEcGA1UdHwRAMD4wPKAUoBKGEHd3dy5jcmwuZGF0ZXYuZGWiJKQi"+ "MCAxCzAJBgNVBAYTAkRFMREwDwYDVQQKFAhEQVRFViBlRzAWBgUrJAgDBAQNMAsT"+ "A0VVUgIBBQIBATAdBgNVHQ4EFgQUfv6xFP0xk7027folhy+ziZvBJiwwLAYIKwYB"+ "BQUHAQEEIDAeMBwGCCsGAQUFBzABhhB3d3cuZGlyLmRhdGV2LmRlMA0GCSqGSIb3"+ "DQEBBQUAA4GBAEOVX6uQxbgtKzdgbTi6YLffMftFr2mmNwch7qzpM5gxcynzgVkg"+ "pnQcDNlm5AIbS6pO8jTCLfCd5TZ5biQksBErqmesIl3QD+VqtB+RNghxectZ3VEs"+ "nCUtcE7tJ8O14qwCb3TxS9dvIUFiVi4DjbxX46TdcTbTaK8/qr6AIf+l"); byte[] probSelfSignedCert = Base64.decode( "MIICxTCCAi6gAwIBAgIQAQAAAAAAAAAAAAAAAAAAATANBgkqhkiG9w0BAQUFADBF" + "MScwJQYDVQQKEx4gRElSRUNUSU9OIEdFTkVSQUxFIERFUyBJTVBPVFMxGjAYBgNV" + "BAMTESBBQyBNSU5FRkkgQiBURVNUMB4XDTA0MDUwNzEyMDAwMFoXDTE0MDUwNzEy" + "MDAwMFowRTEnMCUGA1UEChMeIERJUkVDVElPTiBHRU5FUkFMRSBERVMgSU1QT1RT" + "MRowGAYDVQQDExEgQUMgTUlORUZJIEIgVEVTVDCBnzANBgkqhkiG9w0BAQEFAAOB" + "jQAwgYkCgYEAveoCUOAukZdcFCs2qJk76vSqEX0ZFzHqQ6faBPZWjwkgUNwZ6m6m" + "qWvvyq1cuxhoDvpfC6NXILETawYc6MNwwxsOtVVIjuXlcF17NMejljJafbPximEt" + "DQ4LcQeSp4K7FyFlIAMLyt3BQ77emGzU5fjFTvHSUNb3jblx0sV28c0CAwEAAaOB" + "tTCBsjAfBgNVHSMEGDAWgBSEJ4bLbvEQY8cYMAFKPFD1/fFXlzAdBgNVHQ4EFgQU" + "hCeGy27xEGPHGDABSjxQ9f3xV5cwDgYDVR0PAQH/BAQDAgEGMBEGCWCGSAGG+EIB" + "AQQEAwIBBjA8BgNVHR8ENTAzMDGgL6AthitodHRwOi8vYWRvbmlzLnBrNy5jZXJ0" + "cGx1cy5uZXQvZGdpLXRlc3QuY3JsMA8GA1UdEwEB/wQFMAMBAf8wDQYJKoZIhvcN" + "AQEFBQADgYEAmToHJWjd3+4zknfsP09H6uMbolHNGG0zTS2lrLKpzcmkQfjhQpT9" + "LUTBvfs1jdjo9fGmQLvOG+Sm51Rbjglb8bcikVI5gLbclOlvqLkm77otjl4U4Z2/" + "Y0vP14Aov3Sn3k+17EfReYUZI4liuB95ncobC4e8ZM++LjQcIM0s+Vs="); byte[] gost34102001base = Base64.decode( "MIIB1DCCAYECEEjpVKXP6Wn1yVz3VeeDQa8wCgYGKoUDAgIDBQAwbTEfMB0G" + "A1UEAwwWR29zdFIzNDEwLTIwMDEgZXhhbXBsZTESMBAGA1UECgwJQ3J5cHRv" + "UHJvMQswCQYDVQQGEwJSVTEpMCcGCSqGSIb3DQEJARYaR29zdFIzNDEwLTIw" + "MDFAZXhhbXBsZS5jb20wHhcNMDUwMjAzMTUxNjQ2WhcNMTUwMjAzMTUxNjQ2" + "WjBtMR8wHQYDVQQDDBZHb3N0UjM0MTAtMjAwMSBleGFtcGxlMRIwEAYDVQQK" + "DAlDcnlwdG9Qcm8xCzAJBgNVBAYTAlJVMSkwJwYJKoZIhvcNAQkBFhpHb3N0" + "UjM0MTAtMjAwMUBleGFtcGxlLmNvbTBjMBwGBiqFAwICEzASBgcqhQMCAiQA" + "BgcqhQMCAh4BA0MABECElWh1YAIaQHUIzROMMYks/eUFA3pDXPRtKw/nTzJ+" + "V4/rzBa5lYgD0Jp8ha4P5I3qprt+VsfLsN8PZrzK6hpgMAoGBiqFAwICAwUA" + "A0EAHw5dw/aw/OiNvHyOE65kvyo4Hp0sfz3csM6UUkp10VO247ofNJK3tsLb" + "HOLjUaqzefrlGb11WpHYrvWFg+FcLA=="); byte[] gost341094base = Base64.decode( "MIICDzCCAbwCEBcxKsIb0ghYvAQeUjfQdFAwCgYGKoUDAgIEBQAwaTEdMBsG" + "A1UEAwwUR29zdFIzNDEwLTk0IGV4YW1wbGUxEjAQBgNVBAoMCUNyeXB0b1By" + "bzELMAkGA1UEBhMCUlUxJzAlBgkqhkiG9w0BCQEWGEdvc3RSMzQxMC05NEBl" + "eGFtcGxlLmNvbTAeFw0wNTAyMDMxNTE2NTFaFw0xNTAyMDMxNTE2NTFaMGkx" + "HTAbBgNVBAMMFEdvc3RSMzQxMC05NCBleGFtcGxlMRIwEAYDVQQKDAlDcnlw" + "dG9Qcm8xCzAJBgNVBAYTAlJVMScwJQYJKoZIhvcNAQkBFhhHb3N0UjM0MTAt" + "OTRAZXhhbXBsZS5jb20wgaUwHAYGKoUDAgIUMBIGByqFAwICIAIGByqFAwIC" + "HgEDgYQABIGAu4Rm4XmeWzTYLIB/E6gZZnFX/oxUJSFHbzALJ3dGmMb7R1W+" + "t7Lzk2w5tUI3JoTiDRCKJA4fDEJNKzsRK6i/ZjkyXJSLwaj+G2MS9gklh8x1" + "G/TliYoJgmjTXHemD7aQEBON4z58nJHWrA0ILD54wbXCtrcaqCqLRYGTMjJ2" + "+nswCgYGKoUDAgIEBQADQQBxKNhOmjgz/i5CEgLOyKyz9pFGkDcaymsWYQWV" + "v7CZ0pTM8IzMzkUBW3GHsUjCFpanFZDfg2zuN+3kT+694n9B"); byte[] gost341094A = Base64.decode( "MIICSDCCAfWgAwIBAgIBATAKBgYqhQMCAgQFADCBgTEXMBUGA1UEAxMOZGVmYXVsdDM0MTAtOTQx" + "DTALBgNVBAoTBERpZ3QxDzANBgNVBAsTBkNyeXB0bzEOMAwGA1UEBxMFWS1vbGExDDAKBgNVBAgT" + "A01FTDELMAkGA1UEBhMCcnUxGzAZBgkqhkiG9w0BCQEWDHRlc3RAdGVzdC5ydTAeFw0wNTAzMjkx" + "MzExNTdaFw0wNjAzMjkxMzExNTdaMIGBMRcwFQYDVQQDEw5kZWZhdWx0MzQxMC05NDENMAsGA1UE" + "ChMERGlndDEPMA0GA1UECxMGQ3J5cHRvMQ4wDAYDVQQHEwVZLW9sYTEMMAoGA1UECBMDTUVMMQsw" + "CQYDVQQGEwJydTEbMBkGCSqGSIb3DQEJARYMdGVzdEB0ZXN0LnJ1MIGlMBwGBiqFAwICFDASBgcq" + "hQMCAiACBgcqhQMCAh4BA4GEAASBgIQACDLEuxSdRDGgdZxHmy30g/DUYkRxO9Mi/uSHX5NjvZ31" + "b7JMEMFqBtyhql1HC5xZfUwZ0aT3UnEFDfFjLP+Bf54gA+LPkQXw4SNNGOj+klnqgKlPvoqMGlwa" + "+hLPKbS561WpvB2XSTgbV+pqqXR3j6j30STmybelEV3RdS2Now8wDTALBgNVHQ8EBAMCB4AwCgYG" + "KoUDAgIEBQADQQBCFy7xWRXtNVXflKvDs0pBdBuPzjCMeZAXVxK8vUxsxxKu76d9CsvhgIFknFRi" + "wWTPiZenvNoJ4R1uzeX+vREm"); byte[] gost341094B = Base64.decode( "MIICSDCCAfWgAwIBAgIBATAKBgYqhQMCAgQFADCBgTEXMBUGA1UEAxMOcGFyYW0xLTM0MTAtOTQx" + "DTALBgNVBAoTBERpZ3QxDzANBgNVBAsTBkNyeXB0bzEOMAwGA1UEBxMFWS1PbGExDDAKBgNVBAgT" + "A01lbDELMAkGA1UEBhMCcnUxGzAZBgkqhkiG9w0BCQEWDHRlc3RAdGVzdC5ydTAeFw0wNTAzMjkx" + "MzEzNTZaFw0wNjAzMjkxMzEzNTZaMIGBMRcwFQYDVQQDEw5wYXJhbTEtMzQxMC05NDENMAsGA1UE" + "ChMERGlndDEPMA0GA1UECxMGQ3J5cHRvMQ4wDAYDVQQHEwVZLU9sYTEMMAoGA1UECBMDTWVsMQsw" + "CQYDVQQGEwJydTEbMBkGCSqGSIb3DQEJARYMdGVzdEB0ZXN0LnJ1MIGlMBwGBiqFAwICFDASBgcq" + "hQMCAiADBgcqhQMCAh4BA4GEAASBgEa+AAcZmijWs1M9x5Pn9efE8D9ztG1NMoIt0/hNZNqln3+j" + "lMZjyqPt+kTLIjtmvz9BRDmIDk6FZz+4LhG2OTL7yGpWfrMxMRr56nxomTN9aLWRqbyWmn3brz9Y" + "AUD3ifnwjjIuW7UM84JNlDTOdxx0XRUfLQIPMCXe9cO02Xskow8wDTALBgNVHQ8EBAMCB4AwCgYG" + "KoUDAgIEBQADQQBzFcnuYc/639OTW+L5Ecjw9KxGr+dwex7lsS9S1BUgKa3m1d5c+cqI0B2XUFi5" + "4iaHHJG0dCyjtQYLJr0OZjRw"); byte[] gost34102001A = Base64.decode( "MIICCzCCAbigAwIBAgIBATAKBgYqhQMCAgMFADCBhDEaMBgGA1UEAxMRZGVmYXVsdC0zNDEwLTIw" + "MDExDTALBgNVBAoTBERpZ3QxDzANBgNVBAsTBkNyeXB0bzEOMAwGA1UEBxMFWS1PbGExDDAKBgNV" + "BAgTA01lbDELMAkGA1UEBhMCcnUxGzAZBgkqhkiG9w0BCQEWDHRlc3RAdGVzdC5ydTAeFw0wNTAz" + "MjkxMzE4MzFaFw0wNjAzMjkxMzE4MzFaMIGEMRowGAYDVQQDExFkZWZhdWx0LTM0MTAtMjAwMTEN" + "MAsGA1UEChMERGlndDEPMA0GA1UECxMGQ3J5cHRvMQ4wDAYDVQQHEwVZLU9sYTEMMAoGA1UECBMD" + "TWVsMQswCQYDVQQGEwJydTEbMBkGCSqGSIb3DQEJARYMdGVzdEB0ZXN0LnJ1MGMwHAYGKoUDAgIT" + "MBIGByqFAwICIwEGByqFAwICHgEDQwAEQG/4c+ZWb10IpeHfmR+vKcbpmSOClJioYmCVgnojw0Xn" + "ned0KTg7TJreRUc+VX7vca4hLQaZ1o/TxVtfEApK/O6jDzANMAsGA1UdDwQEAwIHgDAKBgYqhQMC" + "AgMFAANBAN8y2b6HuIdkD3aWujpfQbS1VIA/7hro4vLgDhjgVmev/PLzFB8oTh3gKhExpDo82IEs" + "ZftGNsbbyp1NFg7zda0="); byte[] gostCA1 = Base64.decode( "MIIDNDCCAuGgAwIBAgIQZLcKDcWcQopF+jp4p9jylDAKBgYqhQMCAgQFADBm" + "MQswCQYDVQQGEwJSVTEPMA0GA1UEBxMGTW9zY293MRcwFQYDVQQKEw5PT08g" + "Q3J5cHRvLVBybzEUMBIGA1UECxMLRGV2ZWxvcG1lbnQxFzAVBgNVBAMTDkNQ" + "IENTUCBUZXN0IENBMB4XDTAyMDYwOTE1NTIyM1oXDTA5MDYwOTE1NTkyOVow" + "ZjELMAkGA1UEBhMCUlUxDzANBgNVBAcTBk1vc2NvdzEXMBUGA1UEChMOT09P" + "IENyeXB0by1Qcm8xFDASBgNVBAsTC0RldmVsb3BtZW50MRcwFQYDVQQDEw5D" + "UCBDU1AgVGVzdCBDQTCBpTAcBgYqhQMCAhQwEgYHKoUDAgIgAgYHKoUDAgIe" + "AQOBhAAEgYAYglywKuz1nMc9UiBYOaulKy53jXnrqxZKbCCBSVaJ+aCKbsQm" + "glhRFrw6Mwu8Cdeabo/ojmea7UDMZd0U2xhZFRti5EQ7OP6YpqD0alllo7za" + "4dZNXdX+/ag6fOORSLFdMpVx5ganU0wHMPk67j+audnCPUj/plbeyccgcdcd" + "WaOCASIwggEeMAsGA1UdDwQEAwIBxjAPBgNVHRMBAf8EBTADAQH/MB0GA1Ud" + "DgQWBBTe840gTo4zt2twHilw3PD9wJaX0TCBygYDVR0fBIHCMIG/MDygOqA4" + "hjYtaHR0cDovL2ZpZXdhbGwvQ2VydEVucm9sbC9DUCUyMENTUCUyMFRlc3Ql" + "MjBDQSgzKS5jcmwwRKBCoECGPmh0dHA6Ly93d3cuY3J5cHRvcHJvLnJ1L0Nl" + "cnRFbnJvbGwvQ1AlMjBDU1AlMjBUZXN0JTIwQ0EoMykuY3JsMDmgN6A1hjMt" + "ZmlsZTovL1xcZmlld2FsbFxDZXJ0RW5yb2xsXENQIENTUCBUZXN0IENBKDMp" + "LmNybC8wEgYJKwYBBAGCNxUBBAUCAwMAAzAKBgYqhQMCAgQFAANBAIJi7ni7" + "9rwMR5rRGTFftt2k70GbqyUEfkZYOzrgdOoKiB4IIsIstyBX0/ne6GsL9Xan" + "G2IN96RB7KrowEHeW+k="); byte[] gostCA2 = Base64.decode( "MIIC2DCCAoWgAwIBAgIQe9ZCugm42pRKNcHD8466zTAKBgYqhQMCAgMFADB+" + "MRowGAYJKoZIhvcNAQkBFgtzYmFAZGlndC5ydTELMAkGA1UEBhMCUlUxDDAK" + "BgNVBAgTA01FTDEUMBIGA1UEBxMLWW9zaGthci1PbGExDTALBgNVBAoTBERp" + "Z3QxDzANBgNVBAsTBkNyeXB0bzEPMA0GA1UEAxMGc2JhLUNBMB4XDTA0MDgw" + "MzEzMzE1OVoXDTE0MDgwMzEzNDAxMVowfjEaMBgGCSqGSIb3DQEJARYLc2Jh" + "QGRpZ3QucnUxCzAJBgNVBAYTAlJVMQwwCgYDVQQIEwNNRUwxFDASBgNVBAcT" + "C1lvc2hrYXItT2xhMQ0wCwYDVQQKEwREaWd0MQ8wDQYDVQQLEwZDcnlwdG8x" + "DzANBgNVBAMTBnNiYS1DQTBjMBwGBiqFAwICEzASBgcqhQMCAiMBBgcqhQMC" + "Ah4BA0MABEDMSy10CuOH+i8QKG2UWA4XmCt6+BFrNTZQtS6bOalyDY8Lz+G7" + "HybyipE3PqdTB4OIKAAPsEEeZOCZd2UXGQm5o4HaMIHXMBMGCSsGAQQBgjcU" + "AgQGHgQAQwBBMAsGA1UdDwQEAwIBhjAPBgNVHRMBAf8EBTADAQH/MB0GA1Ud" + "DgQWBBRJJl3LcNMxkZI818STfoi3ng1xoDBxBgNVHR8EajBoMDGgL6Athito" + "dHRwOi8vc2JhLmRpZ3QubG9jYWwvQ2VydEVucm9sbC9zYmEtQ0EuY3JsMDOg" + "MaAvhi1maWxlOi8vXFxzYmEuZGlndC5sb2NhbFxDZXJ0RW5yb2xsXHNiYS1D" + "QS5jcmwwEAYJKwYBBAGCNxUBBAMCAQAwCgYGKoUDAgIDBQADQQA+BRJHbc/p" + "q8EYl6iJqXCuR+ozRmH7hPAP3c4KqYSC38TClCgBloLapx/3/WdatctFJW/L" + "mcTovpq088927shE"); byte[] inDirectCrl = Base64.decode( "MIIdXjCCHMcCAQEwDQYJKoZIhvcNAQEFBQAwdDELMAkGA1UEBhMCREUxHDAaBgNV" +"BAoUE0RldXRzY2hlIFRlbGVrb20gQUcxFzAVBgNVBAsUDlQtVGVsZVNlYyBUZXN0" +"MS4wDAYHAoIGAQoHFBMBMTAeBgNVBAMUF1QtVGVsZVNlYyBUZXN0IERJUiA4OlBO" +"Fw0wNjA4MDQwODQ1MTRaFw0wNjA4MDQxNDQ1MTRaMIIbfzB+AgQvrj/pFw0wMzA3" +"MjIwNTQxMjhaMGcwZQYDVR0dAQH/BFswWaRXMFUxCzAJBgNVBAYTAkRFMRwwGgYD" +"VQQKFBNEZXV0c2NoZSBUZWxla29tIEFHMSgwDAYHAoIGAQoHFBMBMTAYBgNVBAMU" +"EVNpZ0cgVGVzdCBDQSA0OlBOMH4CBC+uP+oXDTAzMDcyMjA1NDEyOFowZzBlBgNV" +"HR0BAf8EWzBZpFcwVTELMAkGA1UEBhMCREUxHDAaBgNVBAoUE0RldXRzY2hlIFRl" +"bGVrb20gQUcxKDAMBgcCggYBCgcUEwExMBgGA1UEAxQRU2lnRyBUZXN0IENBIDQ6" +"UE4wfgIEL64/5xcNMDQwNDA1MTMxODE3WjBnMGUGA1UdHQEB/wRbMFmkVzBVMQsw" +"CQYDVQQGEwJERTEcMBoGA1UEChQTRGV1dHNjaGUgVGVsZWtvbSBBRzEoMAwGBwKC" +"BgEKBxQTATEwGAYDVQQDFBFTaWdHIFRlc3QgQ0EgNDpQTjB+AgQvrj/oFw0wNDA0" +"MDUxMzE4MTdaMGcwZQYDVR0dAQH/BFswWaRXMFUxCzAJBgNVBAYTAkRFMRwwGgYD" +"VQQKFBNEZXV0c2NoZSBUZWxla29tIEFHMSgwDAYHAoIGAQoHFBMBMTAYBgNVBAMU" +"EVNpZ0cgVGVzdCBDQSA0OlBOMH4CBC+uP+UXDTAzMDExMzExMTgxMVowZzBlBgNV" +"HR0BAf8EWzBZpFcwVTELMAkGA1UEBhMCREUxHDAaBgNVBAoUE0RldXRzY2hlIFRl" +"bGVrb20gQUcxKDAMBgcCggYBCgcUEwExMBgGA1UEAxQRU2lnRyBUZXN0IENBIDQ6" +"UE4wfgIEL64/5hcNMDMwMTEzMTExODExWjBnMGUGA1UdHQEB/wRbMFmkVzBVMQsw" +"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"); byte[] directCRL = Base64.decode( "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" +"MQ=="); private final byte[] pkcs7CrlProblem = Base64.decode( "MIIwSAYJKoZIhvcNAQcCoIIwOTCCMDUCAQExCzAJBgUrDgMCGgUAMAsGCSqG" + "SIb3DQEHAaCCEsAwggP4MIIC4KADAgECAgF1MA0GCSqGSIb3DQEBBQUAMEUx" + "CzAJBgNVBAYTAlVTMRYwFAYDVQQKEw1HZW9UcnVzdCBJbmMuMR4wHAYDVQQD" + "ExVHZW9UcnVzdCBDQSBmb3IgQWRvYmUwHhcNMDQxMjAyMjEyNTM5WhcNMDYx" + "MjMwMjEyNTM5WjBMMQswCQYDVQQGEwJVUzEVMBMGA1UEChMMR2VvVHJ1c3Qg" + "SW5jMSYwJAYDVQQDEx1HZW9UcnVzdCBBZG9iZSBPQ1NQIFJlc3BvbmRlcjCB" + "nzANBgkqhkiG9w0BAQEFAAOBjQAwgYkCgYEA4gnNYhtw7U6QeVXZODnGhHMj" + "+OgZ0DB393rEk6a2q9kq129IA2e03yKBTfJfQR9aWKc2Qj90dsSqPjvTDHFG" + "Qsagm2FQuhnA3fb1UWhPzeEIdm6bxDsnQ8nWqKqxnWZzELZbdp3I9bBLizIq" + "obZovzt60LNMghn/unvvuhpeVSsCAwEAAaOCAW4wggFqMA4GA1UdDwEB/wQE" + "AwIE8DCB5QYDVR0gAQH/BIHaMIHXMIHUBgkqhkiG9y8BAgEwgcYwgZAGCCsG" + "AQUFBwICMIGDGoGAVGhpcyBjZXJ0aWZpY2F0ZSBoYXMgYmVlbiBpc3N1ZWQg" + "aW4gYWNjb3JkYW5jZSB3aXRoIHRoZSBBY3JvYmF0IENyZWRlbnRpYWxzIENQ" + "UyBsb2NhdGVkIGF0IGh0dHA6Ly93d3cuZ2VvdHJ1c3QuY29tL3Jlc291cmNl" + "cy9jcHMwMQYIKwYBBQUHAgEWJWh0dHA6Ly93d3cuZ2VvdHJ1c3QuY29tL3Jl" + "c291cmNlcy9jcHMwEwYDVR0lBAwwCgYIKwYBBQUHAwkwOgYDVR0fBDMwMTAv" + "oC2gK4YpaHR0cDovL2NybC5nZW90cnVzdC5jb20vY3Jscy9hZG9iZWNhMS5j" + "cmwwHwYDVR0jBBgwFoAUq4BZw2WDbR19E70Zw+wajw1HaqMwDQYJKoZIhvcN" + "AQEFBQADggEBAENJf1BD7PX5ivuaawt90q1OGzXpIQL/ClzEeFVmOIxqPc1E" + "TFRq92YuxG5b6+R+k+tGkmCwPLcY8ipg6ZcbJ/AirQhohzjlFuT6YAXsTfEj" + "CqEZfWM2sS7crK2EYxCMmKE3xDfPclYtrAoz7qZvxfQj0TuxHSstHZv39wu2" + "ZiG1BWiEcyDQyTgqTOXBoZmfJtshuAcXmTpgkrYSrS37zNlPTGh+pMYQ0yWD" + "c8OQRJR4OY5ZXfdna01mjtJTOmj6/6XPoLPYTq2gQrc2BCeNJ4bEhLb7sFVB" + "PbwPrpzTE/HRbQHDrzj0YimDxeOUV/UXctgvYwHNtEkcBLsOm/uytMYwggSh" + "MIIDiaADAgECAgQ+HL0oMA0GCSqGSIb3DQEBBQUAMGkxCzAJBgNVBAYTAlVT" + "MSMwIQYDVQQKExpBZG9iZSBTeXN0ZW1zIEluY29ycG9yYXRlZDEdMBsGA1UE" + "CxMUQWRvYmUgVHJ1c3QgU2VydmljZXMxFjAUBgNVBAMTDUFkb2JlIFJvb3Qg" + "Q0EwHhcNMDMwMTA4MjMzNzIzWhcNMjMwMTA5MDAwNzIzWjBpMQswCQYDVQQG" + "EwJVUzEjMCEGA1UEChMaQWRvYmUgU3lzdGVtcyBJbmNvcnBvcmF0ZWQxHTAb" + "BgNVBAsTFEFkb2JlIFRydXN0IFNlcnZpY2VzMRYwFAYDVQQDEw1BZG9iZSBS" + "b290IENBMIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEAzE9UhPen" + "ouczU38/nBKIayyZR2d+Dx65rRSI+cMQ2B3w8NWfaQovWTWwzGypTJwVoJ/O" + "IL+gz1Ti4CBmRT85hjh+nMSOByLGJPYBErA131XqaZCw24U3HuJOB7JCoWoT" + "aaBm6oCREVkqmwh5WiBELcm9cziLPC/gQxtdswvwrzUaKf7vppLdgUydPVmO" + "rTE8QH6bkTYG/OJcjdGNJtVcRc+vZT+xqtJilvSoOOq6YEL09BxKNRXO+E4i" + "Vg+VGMX4lp+f+7C3eCXpgGu91grwxnSUnfMPUNuad85LcIMjjaDKeCBEXDxU" + "ZPHqojAZn+pMBk0GeEtekt8i0slns3rSAQIDAQABo4IBTzCCAUswEQYJYIZI" + "AYb4QgEBBAQDAgAHMIGOBgNVHR8EgYYwgYMwgYCgfqB8pHoweDELMAkGA1UE" + "BhMCVVMxIzAhBgNVBAoTGkFkb2JlIFN5c3RlbXMgSW5jb3Jwb3JhdGVkMR0w" + "GwYDVQQLExRBZG9iZSBUcnVzdCBTZXJ2aWNlczEWMBQGA1UEAxMNQWRvYmUg" + "Um9vdCBDQTENMAsGA1UEAxMEQ1JMMTArBgNVHRAEJDAigA8yMDAzMDEwODIz" + "MzcyM1qBDzIwMjMwMTA5MDAwNzIzWjALBgNVHQ8EBAMCAQYwHwYDVR0jBBgw" + "FoAUgrc4SpOqmxDvgLvZVOLxD/uAnN4wHQYDVR0OBBYEFIK3OEqTqpsQ74C7" + "2VTi8Q/7gJzeMAwGA1UdEwQFMAMBAf8wHQYJKoZIhvZ9B0EABBAwDhsIVjYu" + "MDo0LjADAgSQMA0GCSqGSIb3DQEBBQUAA4IBAQAy2p9DdcH6b8lv26sdNjc+" + "vGEZNrcCPB0jWZhsnu5NhedUyCAfp9S74r8Ad30ka3AvXME6dkm10+AjhCpx" + "aiLzwScpmBX2NZDkBEzDjbyfYRzn/SSM0URDjBa6m02l1DUvvBHOvfdRN42f" + "kOQU8Rg/vulZEjX5M5LznuDVa5pxm5lLyHHD4bFhCcTl+pHwQjo3fTT5cujN" + "qmIcIenV9IIQ43sFti1oVgt+fpIsb01yggztVnSynbmrLSsdEF/bJ3Vwj/0d" + "1+ICoHnlHOX/r2RAUS2em0fbQqV8H8KmSLDXvpJpTaT2KVfFeBEY3IdRyhOy" + "Yp1PKzK9MaXB+lKrBYjIMIIEyzCCA7OgAwIBAgIEPhy9tTANBgkqhkiG9w0B" + "AQUFADBpMQswCQYDVQQGEwJVUzEjMCEGA1UEChMaQWRvYmUgU3lzdGVtcyBJ" + "bmNvcnBvcmF0ZWQxHTAbBgNVBAsTFEFkb2JlIFRydXN0IFNlcnZpY2VzMRYw" + "FAYDVQQDEw1BZG9iZSBSb290IENBMB4XDTA0MDExNzAwMDMzOVoXDTE1MDEx" + "NTA4MDAwMFowRTELMAkGA1UEBhMCVVMxFjAUBgNVBAoTDUdlb1RydXN0IElu" + "Yy4xHjAcBgNVBAMTFUdlb1RydXN0IENBIGZvciBBZG9iZTCCASIwDQYJKoZI" + "hvcNAQEBBQADggEPADCCAQoCggEBAKfld+BkeFrnOYW8r9L1WygTDlTdSfrO" + "YvWS/Z6Ye5/l+HrBbOHqQCXBcSeCpz7kB2WdKMh1FOE4e9JlmICsHerBLdWk" + "emU+/PDb69zh8E0cLoDfxukF6oVPXj6WSThdSG7H9aXFzRr6S3XGCuvgl+Qw" + "DTLiLYW+ONF6DXwt3TQQtKReJjOJZk46ZZ0BvMStKyBaeB6DKZsmiIo89qso" + "13VDZINH2w1KvXg0ygDizoNtbvgAPFymwnsINS1klfQlcvn0x0RJm9bYQXK3" + "5GNZAgL3M7Lqrld0jMfIUaWvuHCLyivytRuzq1dJ7E8rmidjDEk/G+27pf13" + "fNZ7vR7M+IkCAwEAAaOCAZ0wggGZMBIGA1UdEwEB/wQIMAYBAf8CAQEwUAYD" + "VR0gBEkwRzBFBgkqhkiG9y8BAgEwODA2BggrBgEFBQcCARYqaHR0cHM6Ly93" + "d3cuYWRvYmUuY29tL21pc2MvcGtpL2Nkc19jcC5odG1sMBQGA1UdJQQNMAsG" + "CSqGSIb3LwEBBTCBsgYDVR0fBIGqMIGnMCKgIKAehhxodHRwOi8vY3JsLmFk" + "b2JlLmNvbS9jZHMuY3JsMIGAoH6gfKR6MHgxCzAJBgNVBAYTAlVTMSMwIQYD" + "VQQKExpBZG9iZSBTeXN0ZW1zIEluY29ycG9yYXRlZDEdMBsGA1UECxMUQWRv" + "YmUgVHJ1c3QgU2VydmljZXMxFjAUBgNVBAMTDUFkb2JlIFJvb3QgQ0ExDTAL" + "BgNVBAMTBENSTDEwCwYDVR0PBAQDAgEGMB8GA1UdIwQYMBaAFIK3OEqTqpsQ" + "74C72VTi8Q/7gJzeMB0GA1UdDgQWBBSrgFnDZYNtHX0TvRnD7BqPDUdqozAZ" + "BgkqhkiG9n0HQQAEDDAKGwRWNi4wAwIEkDANBgkqhkiG9w0BAQUFAAOCAQEA" + "PzlZLqIAjrFeEWEs0uC29YyJhkXOE9mf3YSaFGsITF+Gl1j0pajTjyH4R35Q" + "r3floW2q3HfNzTeZ90Jnr1DhVERD6zEMgJpCtJqVuk0sixuXJHghS/KicKf4" + "YXJJPx9epuIRF1siBRnznnF90svmOJMXApc0jGnYn3nQfk4kaShSnDaYaeYR" + "DJKcsiWhl6S5zfwS7Gg8hDeyckhMQKKWnlG1CQrwlSFisKCduoodwRtWgft8" + "kx13iyKK3sbalm6vnVc+5nufS4vI+TwMXoV63NqYaSroafBWk0nL53zGXPEy" + "+A69QhzEViJKn2Wgqt5gt++jMMNImbRObIqgfgF1VjCCBUwwggQ0oAMCAQIC" + "AgGDMA0GCSqGSIb3DQEBBQUAMEUxCzAJBgNVBAYTAlVTMRYwFAYDVQQKEw1H" + "ZW9UcnVzdCBJbmMuMR4wHAYDVQQDExVHZW9UcnVzdCBDQSBmb3IgQWRvYmUw" + "HhcNMDYwMzI0MTU0MjI5WhcNMDkwNDA2MTQ0MjI5WjBzMQswCQYDVQQGEwJV" + "UzELMAkGA1UECBMCTUExETAPBgNVBAoTCEdlb1RydXN0MR0wGwYDVQQDExRN" + "YXJrZXRpbmcgRGVwYXJ0bWVudDElMCMGCSqGSIb3DQEJARYWbWFya2V0aW5n" + "QGdlb3RydXN0LmNvbTCCASIwDQYJKoZIhvcNAQEBBQADggEPADCCAQoCggEB" + "ANmvajTO4XJvAU2nVcLmXeCnAQX7RZt+7+ML3InmqQ3LCGo1weop09zV069/" + "1x/Nmieol7laEzeXxd2ghjGzwfXafqQEqHn6+vBCvqdNPoSi63fSWhnuDVWp" + "KVDOYgxOonrXl+Cc43lu4zRSq+Pi5phhrjDWcH74a3/rdljUt4c4GFezFXfa" + "w2oTzWkxj2cTSn0Szhpr17+p66UNt8uknlhmu4q44Speqql2HwmCEnpLYJrK" + "W3fOq5D4qdsvsLR2EABLhrBezamLI3iGV8cRHOUTsbTMhWhv/lKfHAyf4XjA" + "z9orzvPN5jthhIfICOFq/nStTgakyL4Ln+nFAB/SMPkCAwEAAaOCAhYwggIS" + "MA4GA1UdDwEB/wQEAwIF4DCB5QYDVR0gAQH/BIHaMIHXMIHUBgkqhkiG9y8B" + "AgEwgcYwgZAGCCsGAQUFBwICMIGDGoGAVGhpcyBjZXJ0aWZpY2F0ZSBoYXMg" + "YmVlbiBpc3N1ZWQgaW4gYWNjb3JkYW5jZSB3aXRoIHRoZSBBY3JvYmF0IENy" + "ZWRlbnRpYWxzIENQUyBsb2NhdGVkIGF0IGh0dHA6Ly93d3cuZ2VvdHJ1c3Qu" + "Y29tL3Jlc291cmNlcy9jcHMwMQYIKwYBBQUHAgEWJWh0dHA6Ly93d3cuZ2Vv" + "dHJ1c3QuY29tL3Jlc291cmNlcy9jcHMwOgYDVR0fBDMwMTAvoC2gK4YpaHR0" + "cDovL2NybC5nZW90cnVzdC5jb20vY3Jscy9hZG9iZWNhMS5jcmwwHwYDVR0j" + "BBgwFoAUq4BZw2WDbR19E70Zw+wajw1HaqMwRAYIKwYBBQUHAQEEODA2MDQG" + "CCsGAQUFBzABhihodHRwOi8vYWRvYmUtb2NzcC5nZW90cnVzdC5jb20vcmVz" + "cG9uZGVyMBQGA1UdJQQNMAsGCSqGSIb3LwEBBTA8BgoqhkiG9y8BAQkBBC4w" + "LAIBAYYnaHR0cDovL2Fkb2JlLXRpbWVzdGFtcC5nZW90cnVzdC5jb20vdHNh" + "MBMGCiqGSIb3LwEBCQIEBTADAgEBMAwGA1UdEwQFMAMCAQAwDQYJKoZIhvcN" + "AQEFBQADggEBAAOhy6QxOo+i3h877fvDvTa0plGD2bIqK7wMdNqbMDoSWied" + "FIcgcBOIm2wLxOjZBAVj/3lDq59q2rnVeNnfXM0/N0MHI9TumHRjU7WNk9e4" + "+JfJ4M+c3anrWOG3NE5cICDVgles+UHjXetHWql/LlP04+K2ZOLb6LE2xGnI" + "YyLW9REzCYNAVF+/WkYdmyceHtaBZdbyVAJq0NAJPsfgY1pWcBo31Mr1fpX9" + "WrXNTYDCqMyxMImJTmN3iI68tkXlNrhweQoArKFqBysiBkXzG/sGKYY6tWKU" + "pzjLc3vIp/LrXC5zilROes8BSvwu1w9qQrJNcGwo7O4uijoNtyYil1Exgh1Q" + "MIIdTAIBATBLMEUxCzAJBgNVBAYTAlVTMRYwFAYDVQQKEw1HZW9UcnVzdCBJ" + "bmMuMR4wHAYDVQQDExVHZW9UcnVzdCBDQSBmb3IgQWRvYmUCAgGDMAkGBSsO" + "AwIaBQCgggxMMBgGCSqGSIb3DQEJAzELBgkqhkiG9w0BBwEwIwYJKoZIhvcN" + "AQkEMRYEFP4R6qIdpQJzWyzrqO8X1ZfJOgChMIIMCQYJKoZIhvcvAQEIMYIL" + "+jCCC/agggZ5MIIGdTCCA6gwggKQMA0GCSqGSIb3DQEBBQUAMEUxCzAJBgNV" + "BAYTAlVTMRYwFAYDVQQKEw1HZW9UcnVzdCBJbmMuMR4wHAYDVQQDExVHZW9U" + "cnVzdCBDQSBmb3IgQWRvYmUXDTA2MDQwNDE3NDAxMFoXDTA2MDQwNTE3NDAx" + "MFowggIYMBMCAgC5Fw0wNTEwMTEyMDM2MzJaMBICAVsXDTA0MTEwNDE1MDk0" + "MVowEwICALgXDTA1MTIxMjIyMzgzOFowEgIBWhcNMDQxMTA0MTUwOTMzWjAT" + "AgIA5hcNMDUwODI3MDQwOTM4WjATAgIAtxcNMDYwMTE2MTc1NTEzWjATAgIA" + "hhcNMDUxMjEyMjIzODU1WjATAgIAtRcNMDUwNzA2MTgzODQwWjATAgIA4BcN" + "MDYwMzIwMDc0ODM0WjATAgIAgRcNMDUwODAyMjIzMTE1WjATAgIA3xcNMDUx" + "MjEyMjIzNjUwWjASAgFKFw0wNDExMDQxNTA5MTZaMBICAUQXDTA0MTEwNDE1" + "MDg1M1owEgIBQxcNMDQxMDAzMDEwMDQwWjASAgFsFw0wNDEyMDYxOTQ0MzFa" + "MBMCAgEoFw0wNjAzMDkxMjA3MTJaMBMCAgEkFw0wNjAxMTYxNzU1MzRaMBIC" + "AWcXDTA1MDMxODE3NTYxNFowEwICAVEXDTA2MDEzMTExMjcxMVowEgIBZBcN" + "MDQxMTExMjI0ODQxWjATAgIA8RcNMDUwOTE2MTg0ODAxWjATAgIBThcNMDYw" + "MjIxMjAxMDM2WjATAgIAwRcNMDUxMjEyMjIzODE2WjASAgFiFw0wNTAxMTAx" + "NjE5MzRaMBICAWAXDTA1MDExMDE5MDAwNFowEwICAL4XDTA1MDUxNzE0NTYx" + "MFowDQYJKoZIhvcNAQEFBQADggEBAEKhRMS3wVho1U3EvEQJZC8+JlUngmZQ" + "A78KQbHPWNZWFlNvPuf/b0s7Lu16GfNHXh1QAW6Y5Hi1YtYZ3YOPyMd4Xugt" + "gCdumbB6xtKsDyN5RvTht6ByXj+CYlYqsL7RX0izJZ6mJn4fjMkqzPKNOjb8" + "kSn5T6rn93BjlATtCE8tPVOM8dnqGccRE0OV59+nDBXc90UMt5LdEbwaUOap" + "snVB0oLcNm8d/HnlVH6RY5LnDjrT4vwfe/FApZtTecEWsllVUXDjSpwfcfD/" + "476/lpGySB2otALqzImlA9R8Ok3hJ8dnF6hhQ5Oe6OJMnGYgdhkKbxsKkdib" + "tTVl3qmH5QAwggLFMIIBrQIBATANBgkqhkiG9w0BAQUFADBpMQswCQYDVQQG" + "EwJVUzEjMCEGA1UEChMaQWRvYmUgU3lzdGVtcyBJbmNvcnBvcmF0ZWQxHTAb" + "BgNVBAsTFEFkb2JlIFRydXN0IFNlcnZpY2VzMRYwFAYDVQQDEw1BZG9iZSBS" + "b290IENBFw0wNjAxMjcxODMzMzFaFw0wNzAxMjcwMDAwMDBaMIHeMCMCBD4c" + "vUAXDTAzMDEyMTIzNDY1NlowDDAKBgNVHRUEAwoBBDAjAgQ+HL1BFw0wMzAx" + "MjEyMzQ3MjJaMAwwCgYDVR0VBAMKAQQwIwIEPhy9YhcNMDMwMTIxMjM0NzQy" + "WjAMMAoGA1UdFQQDCgEEMCMCBD4cvWEXDTA0MDExNzAxMDg0OFowDDAKBgNV" + "HRUEAwoBBDAjAgQ+HL2qFw0wNDAxMTcwMTA5MDVaMAwwCgYDVR0VBAMKAQQw" + "IwIEPhy9qBcNMDQwMTE3MDEzOTI5WjAMMAoGA1UdFQQDCgEEoC8wLTAKBgNV" + "HRQEAwIBDzAfBgNVHSMEGDAWgBSCtzhKk6qbEO+Au9lU4vEP+4Cc3jANBgkq" + "hkiG9w0BAQUFAAOCAQEAwtXF9042wG39icUlsotn5tpE3oCusLb/hBpEONhx" + "OdfEQOq0w5hf/vqaxkcf71etA+KpbEUeSVaHMHRPhx/CmPrO9odE139dJdbt" + "9iqbrC9iZokFK3h/es5kg73xujLKd7C/u5ngJ4mwBtvhMLjFjF2vJhPKHL4C" + "IgMwdaUAhrcNzy16v+mw/VGJy3Fvc6oCESW1K9tvFW58qZSNXrMlsuidgunM" + "hPKG+z0SXVyCqL7pnqKiaGddcgujYGOSY4S938oVcfZeZQEODtSYGlzldojX" + "C1U1hCK5+tHAH0Ox/WqRBIol5VCZQwJftf44oG8oviYq52aaqSejXwmfT6zb" + "76GCBXUwggVxMIIFbQoBAKCCBWYwggViBgkrBgEFBQcwAQEEggVTMIIFTzCB" + "taIWBBS+8EpykfXdl4h3z7m/NZfdkAQQERgPMjAwNjA0MDQyMDIwMTVaMGUw" + "YzA7MAkGBSsOAwIaBQAEFEb4BuZYkbjBjOjT6VeA/00fBvQaBBT3fTSQniOp" + "BbHBSkz4xridlX0bsAICAYOAABgPMjAwNjA0MDQyMDIwMTVaoBEYDzIwMDYw" + "NDA1MDgyMDE1WqEjMCEwHwYJKwYBBQUHMAECBBIEEFqooq/R2WltD7TposkT" + "BhMwDQYJKoZIhvcNAQEFBQADgYEAMig6lty4b0JDsT/oanfQG5x6jVKPACpp" + "1UA9SJ0apJJa7LeIdDFmu5C2S/CYiKZm4A4P9cAu0YzgLHxE4r6Op+HfVlAG" + "6bzUe1P/hi1KCJ8r8wxOZAktQFPSzs85RAZwkHMfB0lP2e/h666Oye+Zf8VH" + "RaE+/xZ7aswE89HXoumgggQAMIID/DCCA/gwggLgoAMCAQICAXUwDQYJKoZI" + "hvcNAQEFBQAwRTELMAkGA1UEBhMCVVMxFjAUBgNVBAoTDUdlb1RydXN0IElu" + "Yy4xHjAcBgNVBAMTFUdlb1RydXN0IENBIGZvciBBZG9iZTAeFw0wNDEyMDIy" + "MTI1MzlaFw0wNjEyMzAyMTI1MzlaMEwxCzAJBgNVBAYTAlVTMRUwEwYDVQQK" + "EwxHZW9UcnVzdCBJbmMxJjAkBgNVBAMTHUdlb1RydXN0IEFkb2JlIE9DU1Ag" + "UmVzcG9uZGVyMIGfMA0GCSqGSIb3DQEBAQUAA4GNADCBiQKBgQDiCc1iG3Dt" + "TpB5Vdk4OcaEcyP46BnQMHf3esSTprar2SrXb0gDZ7TfIoFN8l9BH1pYpzZC" + "P3R2xKo+O9MMcUZCxqCbYVC6GcDd9vVRaE/N4Qh2bpvEOydDydaoqrGdZnMQ" + "tlt2ncj1sEuLMiqhtmi/O3rQs0yCGf+6e++6Gl5VKwIDAQABo4IBbjCCAWow" + "DgYDVR0PAQH/BAQDAgTwMIHlBgNVHSABAf8EgdowgdcwgdQGCSqGSIb3LwEC" + "ATCBxjCBkAYIKwYBBQUHAgIwgYMagYBUaGlzIGNlcnRpZmljYXRlIGhhcyBi" + "ZWVuIGlzc3VlZCBpbiBhY2NvcmRhbmNlIHdpdGggdGhlIEFjcm9iYXQgQ3Jl" + "ZGVudGlhbHMgQ1BTIGxvY2F0ZWQgYXQgaHR0cDovL3d3dy5nZW90cnVzdC5j" + "b20vcmVzb3VyY2VzL2NwczAxBggrBgEFBQcCARYlaHR0cDovL3d3dy5nZW90" + "cnVzdC5jb20vcmVzb3VyY2VzL2NwczATBgNVHSUEDDAKBggrBgEFBQcDCTA6" + "BgNVHR8EMzAxMC+gLaArhilodHRwOi8vY3JsLmdlb3RydXN0LmNvbS9jcmxz" + "L2Fkb2JlY2ExLmNybDAfBgNVHSMEGDAWgBSrgFnDZYNtHX0TvRnD7BqPDUdq" + "ozANBgkqhkiG9w0BAQUFAAOCAQEAQ0l/UEPs9fmK+5prC33SrU4bNekhAv8K" + "XMR4VWY4jGo9zURMVGr3Zi7Eblvr5H6T60aSYLA8txjyKmDplxsn8CKtCGiH" + "OOUW5PpgBexN8SMKoRl9YzaxLtysrYRjEIyYoTfEN89yVi2sCjPupm/F9CPR" + "O7EdKy0dm/f3C7ZmIbUFaIRzINDJOCpM5cGhmZ8m2yG4BxeZOmCSthKtLfvM" + "2U9MaH6kxhDTJYNzw5BElHg5jlld92drTWaO0lM6aPr/pc+gs9hOraBCtzYE" + "J40nhsSEtvuwVUE9vA+unNMT8dFtAcOvOPRiKYPF45RX9Rdy2C9jAc20SRwE" + "uw6b+7K0xjANBgkqhkiG9w0BAQEFAASCAQC7a4yICFGCEMPlJbydK5qLG3rV" + "sip7Ojjz9TB4nLhC2DgsIHds8jjdq2zguInluH2nLaBCVS+qxDVlTjgbI2cB" + "TaWS8nglC7nNjzkKAsa8vThA8FZUVXTW0pb74jNJJU2AA27bb4g+4WgunCrj" + "fpYp+QjDyMmdrJVqRmt5eQN+dpVxMS9oq+NrhOSEhyIb4/rejgNg9wnVK1ms" + "l5PxQ4x7kpm7+Ua41//owkJVWykRo4T1jo4eHEz1DolPykAaKie2VKH/sMqR" + "Spjh4E5biKJLOV9fKivZWKAXByXfwUbbMsJvz4v/2yVHFy9xP+tqB5ZbRoDK" + "k8PzUyCprozn+/22oYIPijCCD4YGCyqGSIb3DQEJEAIOMYIPdTCCD3EGCSqG" + "SIb3DQEHAqCCD2Iwgg9eAgEDMQswCQYFKw4DAhoFADCB+gYLKoZIhvcNAQkQ" + "AQSggeoEgecwgeQCAQEGAikCMCEwCQYFKw4DAhoFAAQUoT97qeCv3FXYaEcS" + "gY8patCaCA8CAiMHGA8yMDA2MDQwNDIwMjA1N1owAwIBPAEB/wIIO0yRre3L" + "8/6ggZCkgY0wgYoxCzAJBgNVBAYTAlVTMRYwFAYDVQQIEw1NYXNzYWNodXNl" + "dHRzMRAwDgYDVQQHEwdOZWVkaGFtMRUwEwYDVQQKEwxHZW9UcnVzdCBJbmMx" + "EzARBgNVBAsTClByb2R1Y3Rpb24xJTAjBgNVBAMTHGFkb2JlLXRpbWVzdGFt" + "cC5nZW90cnVzdC5jb22gggzJMIIDUTCCAjmgAwIBAgICAI8wDQYJKoZIhvcN" + "AQEFBQAwRTELMAkGA1UEBhMCVVMxFjAUBgNVBAoTDUdlb1RydXN0IEluYy4x" + "HjAcBgNVBAMTFUdlb1RydXN0IENBIGZvciBBZG9iZTAeFw0wNTAxMTAwMTI5" + "MTBaFw0xNTAxMTUwODAwMDBaMIGKMQswCQYDVQQGEwJVUzEWMBQGA1UECBMN" + "TWFzc2FjaHVzZXR0czEQMA4GA1UEBxMHTmVlZGhhbTEVMBMGA1UEChMMR2Vv" + "VHJ1c3QgSW5jMRMwEQYDVQQLEwpQcm9kdWN0aW9uMSUwIwYDVQQDExxhZG9i" + "ZS10aW1lc3RhbXAuZ2VvdHJ1c3QuY29tMIGfMA0GCSqGSIb3DQEBAQUAA4GN" + "ADCBiQKBgQDRbxJotLFPWQuuEDhKtOMaBUJepGxIvWxeahMbq1DVmqnk88+j" + "w/5lfPICPzQZ1oHrcTLSAFM7Mrz3pyyQKQKMqUyiemzuG/77ESUNfBNSUfAF" + "PdtHuDMU8Is8ABVnFk63L+wdlvvDIlKkE08+VTKCRdjmuBVltMpQ6QcLFQzm" + "AQIDAQABo4GIMIGFMDoGA1UdHwQzMDEwL6AtoCuGKWh0dHA6Ly9jcmwuZ2Vv" + "dHJ1c3QuY29tL2NybHMvYWRvYmVjYTEuY3JsMB8GA1UdIwQYMBaAFKuAWcNl" + "g20dfRO9GcPsGo8NR2qjMA4GA1UdDwEB/wQEAwIGwDAWBgNVHSUBAf8EDDAK" + "BggrBgEFBQcDCDANBgkqhkiG9w0BAQUFAAOCAQEAmnyXjdtX+F79Nf0KggTd" + "6YC2MQD9s09IeXTd8TP3rBmizfM+7f3icggeCGakNfPRmIUMLoa0VM5Kt37T" + "2X0TqzBWusfbKx7HnX4v1t/G8NJJlT4SShSHv+8bjjU4lUoCmW2oEcC5vXwP" + "R5JfjCyois16npgcO05ZBT+LLDXyeBijE6qWmwLDfEpLyILzVRmyU4IE7jvm" + "rgb3GXwDUvd3yQXGRRHbPCh3nj9hBGbuzyt7GnlqnEie3wzIyMG2ET/wvTX5" + "4BFXKNe7lDLvZj/MXvd3V7gMTSVW0kAszKao56LfrVTgp1VX3UBQYwmQqaoA" + "UwFezih+jEvjW6cYJo/ErDCCBKEwggOJoAMCAQICBD4cvSgwDQYJKoZIhvcN" + "AQEFBQAwaTELMAkGA1UEBhMCVVMxIzAhBgNVBAoTGkFkb2JlIFN5c3RlbXMg" + "SW5jb3Jwb3JhdGVkMR0wGwYDVQQLExRBZG9iZSBUcnVzdCBTZXJ2aWNlczEW" + "MBQGA1UEAxMNQWRvYmUgUm9vdCBDQTAeFw0wMzAxMDgyMzM3MjNaFw0yMzAx" + "MDkwMDA3MjNaMGkxCzAJBgNVBAYTAlVTMSMwIQYDVQQKExpBZG9iZSBTeXN0" + "ZW1zIEluY29ycG9yYXRlZDEdMBsGA1UECxMUQWRvYmUgVHJ1c3QgU2Vydmlj" + "ZXMxFjAUBgNVBAMTDUFkb2JlIFJvb3QgQ0EwggEiMA0GCSqGSIb3DQEBAQUA" + "A4IBDwAwggEKAoIBAQDMT1SE96ei5zNTfz+cEohrLJlHZ34PHrmtFIj5wxDY" + "HfDw1Z9pCi9ZNbDMbKlMnBWgn84gv6DPVOLgIGZFPzmGOH6cxI4HIsYk9gES" + "sDXfVeppkLDbhTce4k4HskKhahNpoGbqgJERWSqbCHlaIEQtyb1zOIs8L+BD" + "G12zC/CvNRop/u+mkt2BTJ09WY6tMTxAfpuRNgb84lyN0Y0m1VxFz69lP7Gq" + "0mKW9Kg46rpgQvT0HEo1Fc74TiJWD5UYxfiWn5/7sLd4JemAa73WCvDGdJSd" + "8w9Q25p3zktwgyONoMp4IERcPFRk8eqiMBmf6kwGTQZ4S16S3yLSyWezetIB" + "AgMBAAGjggFPMIIBSzARBglghkgBhvhCAQEEBAMCAAcwgY4GA1UdHwSBhjCB" + "gzCBgKB+oHykejB4MQswCQYDVQQGEwJVUzEjMCEGA1UEChMaQWRvYmUgU3lz" + "dGVtcyBJbmNvcnBvcmF0ZWQxHTAbBgNVBAsTFEFkb2JlIFRydXN0IFNlcnZp" + "Y2VzMRYwFAYDVQQDEw1BZG9iZSBSb290IENBMQ0wCwYDVQQDEwRDUkwxMCsG" + "A1UdEAQkMCKADzIwMDMwMTA4MjMzNzIzWoEPMjAyMzAxMDkwMDA3MjNaMAsG" + "A1UdDwQEAwIBBjAfBgNVHSMEGDAWgBSCtzhKk6qbEO+Au9lU4vEP+4Cc3jAd" + "BgNVHQ4EFgQUgrc4SpOqmxDvgLvZVOLxD/uAnN4wDAYDVR0TBAUwAwEB/zAd" + "BgkqhkiG9n0HQQAEEDAOGwhWNi4wOjQuMAMCBJAwDQYJKoZIhvcNAQEFBQAD" + "ggEBADLan0N1wfpvyW/bqx02Nz68YRk2twI8HSNZmGye7k2F51TIIB+n1Lvi" + "vwB3fSRrcC9cwTp2SbXT4COEKnFqIvPBJymYFfY1kOQETMONvJ9hHOf9JIzR" + "REOMFrqbTaXUNS+8Ec6991E3jZ+Q5BTxGD++6VkSNfkzkvOe4NVrmnGbmUvI" + "ccPhsWEJxOX6kfBCOjd9NPly6M2qYhwh6dX0ghDjewW2LWhWC35+kixvTXKC" + "DO1WdLKduastKx0QX9sndXCP/R3X4gKgeeUc5f+vZEBRLZ6bR9tCpXwfwqZI" + "sNe+kmlNpPYpV8V4ERjch1HKE7JinU8rMr0xpcH6UqsFiMgwggTLMIIDs6AD" + "AgECAgQ+HL21MA0GCSqGSIb3DQEBBQUAMGkxCzAJBgNVBAYTAlVTMSMwIQYD" + "VQQKExpBZG9iZSBTeXN0ZW1zIEluY29ycG9yYXRlZDEdMBsGA1UECxMUQWRv" + "YmUgVHJ1c3QgU2VydmljZXMxFjAUBgNVBAMTDUFkb2JlIFJvb3QgQ0EwHhcN" + "MDQwMTE3MDAwMzM5WhcNMTUwMTE1MDgwMDAwWjBFMQswCQYDVQQGEwJVUzEW" + "MBQGA1UEChMNR2VvVHJ1c3QgSW5jLjEeMBwGA1UEAxMVR2VvVHJ1c3QgQ0Eg" + "Zm9yIEFkb2JlMIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEAp+V3" + "4GR4Wuc5hbyv0vVbKBMOVN1J+s5i9ZL9nph7n+X4esFs4epAJcFxJ4KnPuQH" + "ZZ0oyHUU4Th70mWYgKwd6sEt1aR6ZT788Nvr3OHwTRwugN/G6QXqhU9ePpZJ" + "OF1Ibsf1pcXNGvpLdcYK6+CX5DANMuIthb440XoNfC3dNBC0pF4mM4lmTjpl" + "nQG8xK0rIFp4HoMpmyaIijz2qyjXdUNkg0fbDUq9eDTKAOLOg21u+AA8XKbC" + "ewg1LWSV9CVy+fTHREmb1thBcrfkY1kCAvczsuquV3SMx8hRpa+4cIvKK/K1" + "G7OrV0nsTyuaJ2MMST8b7bul/Xd81nu9Hsz4iQIDAQABo4IBnTCCAZkwEgYD" + "VR0TAQH/BAgwBgEB/wIBATBQBgNVHSAESTBHMEUGCSqGSIb3LwECATA4MDYG" + "CCsGAQUFBwIBFipodHRwczovL3d3dy5hZG9iZS5jb20vbWlzYy9wa2kvY2Rz" + "X2NwLmh0bWwwFAYDVR0lBA0wCwYJKoZIhvcvAQEFMIGyBgNVHR8Egaowgacw" + "IqAgoB6GHGh0dHA6Ly9jcmwuYWRvYmUuY29tL2Nkcy5jcmwwgYCgfqB8pHow" + "eDELMAkGA1UEBhMCVVMxIzAhBgNVBAoTGkFkb2JlIFN5c3RlbXMgSW5jb3Jw" + "b3JhdGVkMR0wGwYDVQQLExRBZG9iZSBUcnVzdCBTZXJ2aWNlczEWMBQGA1UE" + "AxMNQWRvYmUgUm9vdCBDQTENMAsGA1UEAxMEQ1JMMTALBgNVHQ8EBAMCAQYw" + "HwYDVR0jBBgwFoAUgrc4SpOqmxDvgLvZVOLxD/uAnN4wHQYDVR0OBBYEFKuA" + "WcNlg20dfRO9GcPsGo8NR2qjMBkGCSqGSIb2fQdBAAQMMAobBFY2LjADAgSQ" + "MA0GCSqGSIb3DQEBBQUAA4IBAQA/OVkuogCOsV4RYSzS4Lb1jImGRc4T2Z/d" + "hJoUawhMX4aXWPSlqNOPIfhHflCvd+Whbarcd83NN5n3QmevUOFUREPrMQyA" + "mkK0mpW6TSyLG5ckeCFL8qJwp/hhckk/H16m4hEXWyIFGfOecX3Sy+Y4kxcC" + "lzSMadifedB+TiRpKFKcNphp5hEMkpyyJaGXpLnN/BLsaDyEN7JySExAopae" + "UbUJCvCVIWKwoJ26ih3BG1aB+3yTHXeLIorextqWbq+dVz7me59Li8j5PAxe" + "hXrc2phpKuhp8FaTScvnfMZc8TL4Dr1CHMRWIkqfZaCq3mC376Mww0iZtE5s" + "iqB+AXVWMYIBgDCCAXwCAQEwSzBFMQswCQYDVQQGEwJVUzEWMBQGA1UEChMN" + "R2VvVHJ1c3QgSW5jLjEeMBwGA1UEAxMVR2VvVHJ1c3QgQ0EgZm9yIEFkb2Jl" + "AgIAjzAJBgUrDgMCGgUAoIGMMBoGCSqGSIb3DQEJAzENBgsqhkiG9w0BCRAB" + "BDAcBgkqhkiG9w0BCQUxDxcNMDYwNDA0MjAyMDU3WjAjBgkqhkiG9w0BCQQx" + "FgQUp7AnXBqoNcarvO7fMJut1og2U5AwKwYLKoZIhvcNAQkQAgwxHDAaMBgw" + "FgQU1dH4eZTNhgxdiSABrat6zsPdth0wDQYJKoZIhvcNAQEBBQAEgYCinr/F" + "rMiQz/MRm9ZD5YGcC0Qo2dRTPd0Aop8mZ4g1xAhKFLnp7lLsjCbkSDpVLDBh" + "cnCk7CV+3FT5hlvt8OqZlR0CnkSnCswLFhrppiWle6cpxlwGqyAteC8uKtQu" + "wjE5GtBKLcCOAzQYyyuNZZeB6oCZ+3mPhZ62FxrvvEGJCgAAAAAAAAAAAAAA" + "AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA" + "AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA" + "AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA" + "AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA" + "AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA" + "AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA" + "AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA" + "AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA" + "AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA=="); private final byte[] emptyDNCert = Base64.decode( "MIICfTCCAeagAwIBAgIBajANBgkqhkiG9w0BAQQFADB8MQswCQYDVQQGEwJVUzEMMAoGA1UEChMD" + "Q0RXMQkwBwYDVQQLEwAxCTAHBgNVBAcTADEJMAcGA1UECBMAMRowGAYDVQQDExFUZW1wbGFyIFRl" + "c3QgMTAyNDEiMCAGCSqGSIb3DQEJARYTdGVtcGxhcnRlc3RAY2R3LmNvbTAeFw0wNjA1MjIwNTAw" + "MDBaFw0xMDA1MjIwNTAwMDBaMHwxCzAJBgNVBAYTAlVTMQwwCgYDVQQKEwNDRFcxCTAHBgNVBAsT" + "ADEJMAcGA1UEBxMAMQkwBwYDVQQIEwAxGjAYBgNVBAMTEVRlbXBsYXIgVGVzdCAxMDI0MSIwIAYJ" + "KoZIhvcNAQkBFhN0ZW1wbGFydGVzdEBjZHcuY29tMIGfMA0GCSqGSIb3DQEBAQUAA4GNADCBiQKB" + "gQDH3aJpJBfM+A3d84j5YcU6zEQaQ76u5xO9NSBmHjZykKS2kCcUqPpvVOPDA5WgV22dtKPh+lYV" + "iUp7wyCVwAKibq8HIbihHceFqMKzjwC639rMoDJ7bi/yzQWz1Zg+075a4FGPlUKn7Yfu89wKkjdW" + "wDpRPXc/agqBnrx5pJTXzQIDAQABow8wDTALBgNVHQ8EBAMCALEwDQYJKoZIhvcNAQEEBQADgYEA" + "RRsRsjse3i2/KClFVd6YLZ+7K1BE0WxFyY2bbytkwQJSxvv3vLSuweFUbhNxutb68wl/yW4GLy4b" + "1QdyswNxrNDXTuu5ILKhRDDuWeocz83aG2KGtr3JlFyr3biWGEyn5WUOE6tbONoQDJ0oPYgI6CAc" + "EHdUp0lioOCt6UOw7Cs="); private final byte[] gostRFC4491_94 = Base64.decode( "MIICCzCCAboCECMO42BGlSTOxwvklBgufuswCAYGKoUDAgIEMGkxHTAbBgNVBAMM" + "FEdvc3RSMzQxMC05NCBleGFtcGxlMRIwEAYDVQQKDAlDcnlwdG9Qcm8xCzAJBgNV" + "BAYTAlJVMScwJQYJKoZIhvcNAQkBFhhHb3N0UjM0MTAtOTRAZXhhbXBsZS5jb20w" + "HhcNMDUwODE2MTIzMjUwWhcNMTUwODE2MTIzMjUwWjBpMR0wGwYDVQQDDBRHb3N0" + "UjM0MTAtOTQgZXhhbXBsZTESMBAGA1UECgwJQ3J5cHRvUHJvMQswCQYDVQQGEwJS" + "VTEnMCUGCSqGSIb3DQEJARYYR29zdFIzNDEwLTk0QGV4YW1wbGUuY29tMIGlMBwG" + "BiqFAwICFDASBgcqhQMCAiACBgcqhQMCAh4BA4GEAASBgLuEZuF5nls02CyAfxOo" + "GWZxV/6MVCUhR28wCyd3RpjG+0dVvrey85NsObVCNyaE4g0QiiQOHwxCTSs7ESuo" + "v2Y5MlyUi8Go/htjEvYJJYfMdRv05YmKCYJo01x3pg+2kBATjeM+fJyR1qwNCCw+" + "eMG1wra3Gqgqi0WBkzIydvp7MAgGBiqFAwICBANBABHHCH4S3ALxAiMpR3aPRyqB" + "g1DjB8zy5DEjiULIc+HeIveF81W9lOxGkZxnrFjXBSqnjLeFKgF1hffXOAP7zUM="); private final byte[] gostRFC4491_2001 = Base64.decode( "MIIB0DCCAX8CECv1xh7CEb0Xx9zUYma0LiEwCAYGKoUDAgIDMG0xHzAdBgNVBAMM" + "Fkdvc3RSMzQxMC0yMDAxIGV4YW1wbGUxEjAQBgNVBAoMCUNyeXB0b1BybzELMAkG" + "A1UEBhMCUlUxKTAnBgkqhkiG9w0BCQEWGkdvc3RSMzQxMC0yMDAxQGV4YW1wbGUu" + "Y29tMB4XDTA1MDgxNjE0MTgyMFoXDTE1MDgxNjE0MTgyMFowbTEfMB0GA1UEAwwW" + "R29zdFIzNDEwLTIwMDEgZXhhbXBsZTESMBAGA1UECgwJQ3J5cHRvUHJvMQswCQYD" + "VQQGEwJSVTEpMCcGCSqGSIb3DQEJARYaR29zdFIzNDEwLTIwMDFAZXhhbXBsZS5j" + "b20wYzAcBgYqhQMCAhMwEgYHKoUDAgIkAAYHKoUDAgIeAQNDAARAhJVodWACGkB1" + "CM0TjDGJLP3lBQN6Q1z0bSsP508yfleP68wWuZWIA9CafIWuD+SN6qa7flbHy7Df" + "D2a8yuoaYDAIBgYqhQMCAgMDQQA8L8kJRLcnqeyn1en7U23Sw6pkfEQu3u0xFkVP" + "vFQ/3cHeF26NG+xxtZPz3TaTVXdoiYkXYiD02rEx1bUcM97i"); public String getName() { return "CertTest"; } /** * we generate a self signed certificate for the sake of testing - RSA */ public void checkCreation1() throws Exception { // // a lightweight key pair. // RSAKeyParameters lwPubKey = new RSAKeyParameters( false, new BigInteger("b4a7e46170574f16a97082b22be58b6a2a629798419be12872a4bdba626cfae9900f76abfb12139dce5de56564fab2b6543165a040c606887420e33d91ed7ed7", 16), new BigInteger("11", 16)); RSAPrivateCrtKeyParameters lwPrivKey = new RSAPrivateCrtKeyParameters( new BigInteger("b4a7e46170574f16a97082b22be58b6a2a629798419be12872a4bdba626cfae9900f76abfb12139dce5de56564fab2b6543165a040c606887420e33d91ed7ed7", 16), new BigInteger("11", 16), new BigInteger("9f66f6b05410cd503b2709e88115d55daced94d1a34d4e32bf824d0dde6028ae79c5f07b580f5dce240d7111f7ddb130a7945cd7d957d1920994da389f490c89", 16), new BigInteger("c0a0758cdf14256f78d4708c86becdead1b50ad4ad6c5c703e2168fbf37884cb", 16), new BigInteger("f01734d7960ea60070f1b06f2bb81bfac48ff192ae18451d5e56c734a5aab8a5", 16), new BigInteger("b54bb9edff22051d9ee60f9351a48591b6500a319429c069a3e335a1d6171391", 16), new BigInteger("d3d83daf2a0cecd3367ae6f8ae1aeb82e9ac2f816c6fc483533d8297dd7884cd", 16), new BigInteger("b8f52fc6f38593dabb661d3f50f8897f8106eee68b1bce78a95b132b4e5b5d19", 16)); // // distinguished name table. // X500NameBuilder builder = new X500NameBuilder(BCStyle.INSTANCE); builder.addRDN(BCStyle.C, "AU"); builder.addRDN(BCStyle.O, "The Legion of the Bouncy Castle"); builder.addRDN(BCStyle.L, "Melbourne"); builder.addRDN(BCStyle.ST, "Victoria"); builder.addRDN(BCStyle.E, "feedback-crypto@bouncycastle.org"); // // extensions // // // create the certificate - version 3 - without extensions // AlgorithmIdentifier sigAlgId = new DefaultSignatureAlgorithmIdentifierFinder().find("SHA256WithRSAEncryption"); AlgorithmIdentifier digAlgId = new DefaultDigestAlgorithmIdentifierFinder().find(sigAlgId); ContentSigner sigGen = new BcRSAContentSignerBuilder(sigAlgId, digAlgId).build(lwPrivKey); SubjectPublicKeyInfo pubInfo = new SubjectPublicKeyInfo(new AlgorithmIdentifier(PKCSObjectIdentifiers.rsaEncryption, DERNull.INSTANCE), new RSAPublicKey(lwPubKey.getModulus(), lwPubKey.getExponent())); X509v3CertificateBuilder certGen = new X509v3CertificateBuilder(builder.build(), BigInteger.valueOf(1), new Date(System.currentTimeMillis() - 50000), new Date(System.currentTimeMillis() + 50000), builder.build(), pubInfo); X509CertificateHolder certHolder = certGen.build(sigGen); ContentVerifierProvider contentVerifierProvider = new BcRSAContentVerifierProviderBuilder(new DefaultDigestAlgorithmIdentifierFinder()).build(lwPubKey); if (!certHolder.isSignatureValid(contentVerifierProvider)) { fail("lw sig verification failed"); } } public void performTest() throws Exception { checkCreation1(); } public static void main( String[] args) { runTest(new CertTest()); } }bouncycastle-1.49.orig/j2me/org/bouncycastle/cert/test/AttrCertSelectorTest.java0000644000175000017500000002376611732220055027433 0ustar ebourgebourgpackage org.bouncycastle.cert.test; import java.math.BigInteger; import java.util.Date; import org.bouncycastle.asn1.ASN1EncodableVector; import org.bouncycastle.asn1.ASN1ObjectIdentifier; import org.bouncycastle.asn1.DERSequence; import org.bouncycastle.asn1.x500.X500Name; import org.bouncycastle.asn1.x509.AlgorithmIdentifier; import org.bouncycastle.asn1.x509.GeneralName; import org.bouncycastle.asn1.x509.Target; import org.bouncycastle.asn1.x509.TargetInformation; import org.bouncycastle.asn1.x509.X509Extension; import org.bouncycastle.cert.AttributeCertificateHolder; import org.bouncycastle.cert.AttributeCertificateIssuer; import org.bouncycastle.cert.X509AttributeCertificateHolder; import org.bouncycastle.cert.X509CertificateHolder; import org.bouncycastle.cert.X509v2AttributeCertificateBuilder; import org.bouncycastle.cert.selector.X509AttributeCertificateHolderSelectorBuilder; import org.bouncycastle.crypto.params.RSAPrivateCrtKeyParameters; import org.bouncycastle.operator.ContentSigner; import org.bouncycastle.operator.DefaultDigestAlgorithmIdentifierFinder; import org.bouncycastle.operator.DefaultSignatureAlgorithmIdentifierFinder; import org.bouncycastle.operator.bc.BcRSAContentSignerBuilder; import org.bouncycastle.util.encoders.Base64; import org.bouncycastle.util.test.SimpleTest; import org.bouncycastle.util.test.Test; import org.bouncycastle.util.test.TestResult; public class AttrCertSelectorTest extends SimpleTest { private static final RSAPrivateCrtKeyParameters RSA_PRIVATE_KEY = new RSAPrivateCrtKeyParameters( new BigInteger("b4a7e46170574f16a97082b22be58b6a2a629798419be12872a4bdba626cfae9900f76abfb12139dce5de56564fab2b6543165a040c606887420e33d91ed7ed7", 16), new BigInteger("11", 16), new BigInteger("9f66f6b05410cd503b2709e88115d55daced94d1a34d4e32bf824d0dde6028ae79c5f07b580f5dce240d7111f7ddb130a7945cd7d957d1920994da389f490c89", 16), new BigInteger("c0a0758cdf14256f78d4708c86becdead1b50ad4ad6c5c703e2168fbf37884cb", 16), new BigInteger("f01734d7960ea60070f1b06f2bb81bfac48ff192ae18451d5e56c734a5aab8a5", 16), new BigInteger("b54bb9edff22051d9ee60f9351a48591b6500a319429c069a3e335a1d6171391", 16), new BigInteger("d3d83daf2a0cecd3367ae6f8ae1aeb82e9ac2f816c6fc483533d8297dd7884cd", 16), new BigInteger("b8f52fc6f38593dabb661d3f50f8897f8106eee68b1bce78a95b132b4e5b5d19", 16)); static final byte[] holderCert = Base64 .decode("MIIGjTCCBXWgAwIBAgICAPswDQYJKoZIhvcNAQEEBQAwaTEdMBsGCSqGSIb3DQEJ" + "ARYOaXJtaGVscEB2dC5lZHUxLjAsBgNVBAMTJVZpcmdpbmlhIFRlY2ggQ2VydGlm" + "aWNhdGlvbiBBdXRob3JpdHkxCzAJBgNVBAoTAnZ0MQswCQYDVQQGEwJVUzAeFw0w" + "MzAxMzExMzUyMTRaFw0wNDAxMzExMzUyMTRaMIGDMRswGQYJKoZIhvcNAQkBFgxz" + "c2hhaEB2dC5lZHUxGzAZBgNVBAMTElN1bWl0IFNoYWggKHNzaGFoKTEbMBkGA1UE" + "CxMSVmlyZ2luaWEgVGVjaCBVc2VyMRAwDgYDVQQLEwdDbGFzcyAxMQswCQYDVQQK" + "EwJ2dDELMAkGA1UEBhMCVVMwgZ8wDQYJKoZIhvcNAQEBBQADgY0AMIGJAoGBAPDc" + "scgSKmsEp0VegFkuitD5j5PUkDuzLjlfaYONt2SN8WeqU4j2qtlCnsipa128cyKS" + "JzYe9duUdNxquh5BPIkMkHBw4jHoQA33tk0J/sydWdN74/AHPpPieK5GHwhU7GTG" + "rCCS1PJRxjXqse79ExAlul+gjQwHeldAC+d4A6oZAgMBAAGjggOmMIIDojAMBgNV" + "HRMBAf8EAjAAMBEGCWCGSAGG+EIBAQQEAwIFoDAOBgNVHQ8BAf8EBAMCA/gwHQYD" + "VR0lBBYwFAYIKwYBBQUHAwIGCCsGAQUFBwMEMB0GA1UdDgQWBBRUIoWAzlXbzBYE" + "yVTjQFWyMMKo1jCBkwYDVR0jBIGLMIGIgBTgc3Fm+TGqKDhen+oKfbl+xVbj2KFt" + "pGswaTEdMBsGCSqGSIb3DQEJARYOaXJtaGVscEB2dC5lZHUxLjAsBgNVBAMTJVZp" + "cmdpbmlhIFRlY2ggQ2VydGlmaWNhdGlvbiBBdXRob3JpdHkxCzAJBgNVBAoTAnZ0" + "MQswCQYDVQQGEwJVU4IBADCBiwYJYIZIAYb4QgENBH4WfFZpcmdpbmlhIFRlY2gg" + "Q2VydGlmaWNhdGlvbiBBdXRob3JpdHkgZGlnaXRhbCBjZXJ0aWZpY2F0ZXMgYXJl" + "IHN1YmplY3QgdG8gcG9saWNpZXMgbG9jYXRlZCBhdCBodHRwOi8vd3d3LnBraS52" + "dC5lZHUvY2EvY3BzLy4wFwYDVR0RBBAwDoEMc3NoYWhAdnQuZWR1MBkGA1UdEgQS" + "MBCBDmlybWhlbHBAdnQuZWR1MEMGCCsGAQUFBwEBBDcwNTAzBggrBgEFBQcwAoYn" + "aHR0cDovL2JveDE3Ny5jYy52dC5lZHUvY2EvaXNzdWVycy5odG1sMEQGA1UdHwQ9" + "MDswOaA3oDWGM2h0dHA6Ly9ib3gxNzcuY2MudnQuZWR1L2h0ZG9jcy1wdWJsaWMv" + "Y3JsL2NhY3JsLmNybDBUBgNVHSAETTBLMA0GCysGAQQBtGgFAQEBMDoGCysGAQQB" + "tGgFAQEBMCswKQYIKwYBBQUHAgEWHWh0dHA6Ly93d3cucGtpLnZ0LmVkdS9jYS9j" + "cHMvMD8GCWCGSAGG+EIBBAQyFjBodHRwOi8vYm94MTc3LmNjLnZ0LmVkdS9jZ2kt" + "cHVibGljL2NoZWNrX3Jldl9jYT8wPAYJYIZIAYb4QgEDBC8WLWh0dHA6Ly9ib3gx" + "NzcuY2MudnQuZWR1L2NnaS1wdWJsaWMvY2hlY2tfcmV2PzBLBglghkgBhvhCAQcE" + "PhY8aHR0cHM6Ly9ib3gxNzcuY2MudnQuZWR1L35PcGVuQ0E4LjAxMDYzMC9jZ2kt" + "cHVibGljL3JlbmV3YWw/MCwGCWCGSAGG+EIBCAQfFh1odHRwOi8vd3d3LnBraS52" + "dC5lZHUvY2EvY3BzLzANBgkqhkiG9w0BAQQFAAOCAQEAHJ2ls9yjpZVcu5DqiE67" + "r7BfkdMnm7IOj2v8cd4EAlPp6OPBmjwDMwvKRBb/P733kLBqFNWXWKTpT008R0KB" + "8kehbx4h0UPz9vp31zhGv169+5iReQUUQSIwTGNWGLzrT8kPdvxiSAvdAJxcbRBm" + "KzDic5I8PoGe48kSCkPpT1oNmnivmcu5j1SMvlx0IS2BkFMksr0OHiAW1elSnE/N" + "RuX2k73b3FucwVxB3NRo3vgoHPCTnh9r4qItAHdxFlF+pPtbw2oHESKRfMRfOIHz" + "CLQWSIa6Tvg4NIV3RRJ0sbCObesyg08lymalQMdkXwtRn5eGE00SHWwEUjSXP2gR" + "3g=="); public String getName() { return "AttrCertSelector"; } private X509AttributeCertificateHolder createAttrCert() throws Exception { X509CertificateHolder iCertHolder = new X509CertificateHolder(holderCert); // // a sample key pair. // // RSAPublicKeySpec pubKeySpec = new RSAPublicKeySpec( // new BigInteger( // "b4a7e46170574f16a97082b22be58b6a2a629798419be12872a4bdba626cfae9900f76abfb12139dce5de56564fab2b6543165a040c606887420e33d91ed7ed7", // 16), new BigInteger("11", 16)); // // set up the keys // X509v2AttributeCertificateBuilder gen = new X509v2AttributeCertificateBuilder( new AttributeCertificateHolder(iCertHolder.getSubject()), new AttributeCertificateIssuer(new X500Name("cn=test")), BigInteger.valueOf(1), new Date(System.currentTimeMillis() - 50000), new Date(System.currentTimeMillis() + 50000)); // the actual attributes GeneralName roleName = new GeneralName(GeneralName.rfc822Name, "DAU123456789@test.com"); ASN1EncodableVector roleSyntax = new ASN1EncodableVector(); roleSyntax.add(roleName); // roleSyntax OID: 2.5.24.72 gen.addAttribute(new ASN1ObjectIdentifier("2.5.24.72"), new DERSequence(roleSyntax)); AlgorithmIdentifier sigAlgId = new DefaultSignatureAlgorithmIdentifierFinder().find("SHA1WithRSAEncryption"); AlgorithmIdentifier digAlgId = new DefaultDigestAlgorithmIdentifierFinder().find(sigAlgId); ContentSigner sigGen = new BcRSAContentSignerBuilder(sigAlgId, digAlgId).build(RSA_PRIVATE_KEY); Target targetName = new Target(Target.targetName, new GeneralName(GeneralName.dNSName, "www.test.com")); Target targetGroup = new Target(Target.targetGroup, new GeneralName( GeneralName.directoryName, "o=Test, ou=Test")); Target[] targets = new Target[2]; targets[0] = targetName; targets[1] = targetGroup; TargetInformation targetInformation = new TargetInformation(targets); gen.addExtension(X509Extension.targetInformation, true, targetInformation); return gen.build(sigGen); } public void testSelector() throws Exception { X509AttributeCertificateHolder aCert = createAttrCert(); X509AttributeCertificateHolderSelectorBuilder sel = new X509AttributeCertificateHolderSelectorBuilder(); sel.setAttributeCert(aCert); boolean match = sel.build().match(aCert); if (!match) { fail("Selector does not match attribute certificate."); } sel.setAttributeCert(null); match = sel.build().match(aCert); if (!match) { fail("Selector does not match attribute certificate."); } sel.setHolder(aCert.getHolder()); match = sel.build().match(aCert); if (!match) { fail("Selector does not match attribute certificate holder."); } sel.setHolder(null); sel.setIssuer(aCert.getIssuer()); match = sel.build().match(aCert); if (!match) { fail("Selector does not match attribute certificate issuer."); } sel.setIssuer(null); X509CertificateHolder iCert = new X509CertificateHolder(holderCert); match = aCert.getHolder().match(iCert); if (!match) { fail("Issuer holder does not match signing certificate of attribute certificate."); } sel.setSerialNumber(aCert.getSerialNumber()); match = sel.build().match(aCert); if (!match) { fail("Selector does not match attribute certificate serial number."); } sel.setAttributeCertificateValid(new Date()); match = sel.build().match(aCert); if (!match) { fail("Selector does not match attribute certificate time."); } sel.addTargetName(new GeneralName(2, "www.test.com")); match = sel.build().match(aCert); if (!match) { fail("Selector does not match attribute certificate target name."); } sel.setTargetNames(null); sel.addTargetGroup(new GeneralName(4, "o=Test, ou=Test")); match = sel.build().match(aCert); if (!match) { fail("Selector does not match attribute certificate target group."); } sel.setTargetGroups(null); } public void performTest() throws Exception { testSelector(); } public static void main(String[] args) { Test test = new AttrCertSelectorTest(); TestResult result = test.perform(); System.out.println(result); } } bouncycastle-1.49.orig/j2me/org/bouncycastle/cert/CertUtils.java0000644000175000017500000001621312105426345024273 0ustar ebourgebourgpackage org.bouncycastle.cert; import java.io.IOException; import java.io.OutputStream; import java.util.ArrayList; import java.util.Arrays; import java.util.Collections; import java.util.Date; import java.util.HashSet; import java.util.List; import java.util.Set; import org.bouncycastle.asn1.ASN1Encodable; import org.bouncycastle.asn1.ASN1EncodableVector; import org.bouncycastle.asn1.ASN1ObjectIdentifier; import org.bouncycastle.asn1.DERBitString; import org.bouncycastle.asn1.DERGeneralizedTime; import org.bouncycastle.asn1.DERNull; import org.bouncycastle.asn1.DEROutputStream; import org.bouncycastle.asn1.DERSequence; import org.bouncycastle.asn1.x509.AlgorithmIdentifier; import org.bouncycastle.asn1.x509.AttributeCertificate; import org.bouncycastle.asn1.x509.AttributeCertificateInfo; import org.bouncycastle.asn1.x509.Certificate; import org.bouncycastle.asn1.x509.CertificateList; import org.bouncycastle.asn1.x509.Extensions; import org.bouncycastle.asn1.x509.ExtensionsGenerator; import org.bouncycastle.asn1.x509.TBSCertList; import org.bouncycastle.asn1.x509.TBSCertificate; import org.bouncycastle.operator.ContentSigner; class CertUtils { private static Set EMPTY_SET = Collections.unmodifiableSet(new HashSet()); private static List EMPTY_LIST = Collections.unmodifiableList(new ArrayList()); static X509CertificateHolder generateFullCert(ContentSigner signer, TBSCertificate tbsCert) { try { return new X509CertificateHolder(generateStructure(tbsCert, signer.getAlgorithmIdentifier(), generateSig(signer, tbsCert))); } catch (IOException e) { throw new IllegalStateException("cannot produce certificate signature"); } } static X509AttributeCertificateHolder generateFullAttrCert(ContentSigner signer, AttributeCertificateInfo attrInfo) { try { return new X509AttributeCertificateHolder(generateAttrStructure(attrInfo, signer.getAlgorithmIdentifier(), generateSig(signer, attrInfo))); } catch (IOException e) { throw new IllegalStateException("cannot produce attribute certificate signature"); } } static X509CRLHolder generateFullCRL(ContentSigner signer, TBSCertList tbsCertList) { try { return new X509CRLHolder(generateCRLStructure(tbsCertList, signer.getAlgorithmIdentifier(), generateSig(signer, tbsCertList))); } catch (IOException e) { throw new IllegalStateException("cannot produce certificate signature"); } } private static byte[] generateSig(ContentSigner signer, ASN1Encodable tbsObj) throws IOException { OutputStream sOut = signer.getOutputStream(); DEROutputStream dOut = new DEROutputStream(sOut); dOut.writeObject(tbsObj); sOut.close(); return signer.getSignature(); } private static Certificate generateStructure(TBSCertificate tbsCert, AlgorithmIdentifier sigAlgId, byte[] signature) { ASN1EncodableVector v = new ASN1EncodableVector(); v.add(tbsCert); v.add(sigAlgId); v.add(new DERBitString(signature)); return Certificate.getInstance(new DERSequence(v)); } private static AttributeCertificate generateAttrStructure(AttributeCertificateInfo attrInfo, AlgorithmIdentifier sigAlgId, byte[] signature) { ASN1EncodableVector v = new ASN1EncodableVector(); v.add(attrInfo); v.add(sigAlgId); v.add(new DERBitString(signature)); return AttributeCertificate.getInstance(new DERSequence(v)); } private static CertificateList generateCRLStructure(TBSCertList tbsCertList, AlgorithmIdentifier sigAlgId, byte[] signature) { ASN1EncodableVector v = new ASN1EncodableVector(); v.add(tbsCertList); v.add(sigAlgId); v.add(new DERBitString(signature)); return CertificateList.getInstance(new DERSequence(v)); } static Set getCriticalExtensionOIDs(Extensions extensions) { if (extensions == null) { return EMPTY_SET; } return Collections.unmodifiableSet(new HashSet(Arrays.asList(extensions.getCriticalExtensionOIDs()))); } static Set getNonCriticalExtensionOIDs(Extensions extensions) { if (extensions == null) { return EMPTY_SET; } // TODO: should probably produce a set that imposes correct ordering return Collections.unmodifiableSet(new HashSet(Arrays.asList(extensions.getNonCriticalExtensionOIDs()))); } static List getExtensionOIDs(Extensions extensions) { if (extensions == null) { return EMPTY_LIST; } return Collections.unmodifiableList(Arrays.asList(extensions.getExtensionOIDs())); } static void addExtension(ExtensionsGenerator extGenerator, ASN1ObjectIdentifier oid, boolean isCritical, ASN1Encodable value) throws CertIOException { try { extGenerator.addExtension(oid, isCritical, value); } catch (IOException e) { throw new CertIOException("cannot encode extension: " + e.getMessage(), e); } } static DERBitString booleanToBitString(boolean[] id) { byte[] bytes = new byte[(id.length + 7) / 8]; for (int i = 0; i != id.length; i++) { bytes[i / 8] |= (id[i]) ? (1 << ((7 - (i % 8)))) : 0; } int pad = id.length % 8; if (pad == 0) { return new DERBitString(bytes); } else { return new DERBitString(bytes, 8 - pad); } } static boolean[] bitStringToBoolean(DERBitString bitString) { if (bitString != null) { byte[] bytes = bitString.getBytes(); boolean[] boolId = new boolean[bytes.length * 8 - bitString.getPadBits()]; for (int i = 0; i != boolId.length; i++) { boolId[i] = (bytes[i / 8] & (0x80 >>> (i % 8))) != 0; } return boolId; } return null; } static Date recoverDate(DERGeneralizedTime time) { return time.getDate(); } static boolean dateBefore(Date d1, Date d2) { return d1.getTime() < d2.getTime(); } static boolean dateAfter(Date d1, Date d2) { return d1.getTime() > d2.getTime(); } static boolean isAlgIdEqual(AlgorithmIdentifier id1, AlgorithmIdentifier id2) { if (!id1.getAlgorithm().equals(id2.getAlgorithm())) { return false; } if (id1.getParameters() == null) { if (id2.getParameters() != null && !id2.getParameters().equals(DERNull.INSTANCE)) { return false; } return true; } if (id2.getParameters() == null) { if (id1.getParameters() != null && !id1.getParameters().equals(DERNull.INSTANCE)) { return false; } return true; } return id1.getParameters().equals(id2.getParameters()); } } bouncycastle-1.49.orig/j2me/org/bouncycastle/cert/X509CertificateHolder.java0000644000175000017500000002173512105426345026330 0ustar ebourgebourgpackage org.bouncycastle.cert; import java.io.IOException; import java.io.OutputStream; import java.math.BigInteger; import java.util.Date; import java.util.List; import java.util.Set; import org.bouncycastle.asn1.ASN1ObjectIdentifier; import org.bouncycastle.asn1.ASN1Primitive; import org.bouncycastle.asn1.DEROutputStream; import org.bouncycastle.asn1.x500.X500Name; import org.bouncycastle.asn1.x509.AlgorithmIdentifier; import org.bouncycastle.asn1.x509.Certificate; import org.bouncycastle.asn1.x509.Extension; import org.bouncycastle.asn1.x509.Extensions; import org.bouncycastle.asn1.x509.SubjectPublicKeyInfo; import org.bouncycastle.asn1.x509.TBSCertificate; import org.bouncycastle.operator.ContentVerifier; import org.bouncycastle.operator.ContentVerifierProvider; /** * Holding class for an X.509 Certificate structure. */ public class X509CertificateHolder { private Certificate x509Certificate; private Extensions extensions; private static Certificate parseBytes(byte[] certEncoding) throws IOException { try { return Certificate.getInstance(ASN1Primitive.fromByteArray(certEncoding)); } catch (ClassCastException e) { throw new CertIOException("malformed data: " + e.getMessage(), e); } catch (IllegalArgumentException e) { throw new CertIOException("malformed data: " + e.getMessage(), e); } } /** * Create a X509CertificateHolder from the passed in bytes. * * @param certEncoding BER/DER encoding of the certificate. * @throws IOException in the event of corrupted data, or an incorrect structure. */ public X509CertificateHolder(byte[] certEncoding) throws IOException { this(parseBytes(certEncoding)); } /** * Create a X509CertificateHolder from the passed in ASN.1 structure. * * @param x509Certificate an ASN.1 Certificate structure. */ public X509CertificateHolder(Certificate x509Certificate) { this.x509Certificate = x509Certificate; this.extensions = x509Certificate.getTBSCertificate().getExtensions(); } public int getVersionNumber() { return x509Certificate.getVersionNumber(); } /** * @deprecated use getVersionNumber */ public int getVersion() { return x509Certificate.getVersionNumber(); } /** * Return whether or not the holder's certificate contains extensions. * * @return true if extension are present, false otherwise. */ public boolean hasExtensions() { return extensions != null; } /** * Look up the extension associated with the passed in OID. * * @param oid the OID of the extension of interest. * * @return the extension if present, null otherwise. */ public Extension getExtension(ASN1ObjectIdentifier oid) { if (extensions != null) { return extensions.getExtension(oid); } return null; } /** * Return the extensions block associated with this certificate if there is one. * * @return the extensions block, null otherwise. */ public Extensions getExtensions() { return extensions; } /** * Returns a list of ASN1ObjectIdentifier objects representing the OIDs of the * extensions contained in this holder's certificate. * * @return a list of extension OIDs. */ public List getExtensionOIDs() { return CertUtils.getExtensionOIDs(extensions); } /** * Returns a set of ASN1ObjectIdentifier objects representing the OIDs of the * critical extensions contained in this holder's certificate. * * @return a set of critical extension OIDs. */ public Set getCriticalExtensionOIDs() { return CertUtils.getCriticalExtensionOIDs(extensions); } /** * Returns a set of ASN1ObjectIdentifier objects representing the OIDs of the * non-critical extensions contained in this holder's certificate. * * @return a set of non-critical extension OIDs. */ public Set getNonCriticalExtensionOIDs() { return CertUtils.getNonCriticalExtensionOIDs(extensions); } /** * Return the serial number of this attribute certificate. * * @return the serial number. */ public BigInteger getSerialNumber() { return x509Certificate.getSerialNumber().getValue(); } /** * Return the issuer of this certificate. * * @return the certificate issuer. */ public X500Name getIssuer() { return X500Name.getInstance(x509Certificate.getIssuer()); } /** * Return the subject this certificate is for. * * @return the subject for the certificate. */ public X500Name getSubject() { return X500Name.getInstance(x509Certificate.getSubject()); } /** * Return the date before which this certificate is not valid. * * @return the start time for the certificate's validity period. */ public Date getNotBefore() { return x509Certificate.getStartDate().getDate(); } /** * Return the date after which this certificate is not valid. * * @return the final time for the certificate's validity period. */ public Date getNotAfter() { return x509Certificate.getEndDate().getDate(); } /** * Return the SubjectPublicKeyInfo describing the public key this certificate is carrying. * * @return the public key ASN.1 structure contained in the certificate. */ public SubjectPublicKeyInfo getSubjectPublicKeyInfo() { return x509Certificate.getSubjectPublicKeyInfo(); } /** * Return the underlying ASN.1 structure for the certificate in this holder. * * @return a X509CertificateStructure object. */ public Certificate toASN1Structure() { return x509Certificate; } /** * Return the details of the signature algorithm used to create this attribute certificate. * * @return the AlgorithmIdentifier describing the signature algorithm used to create this attribute certificate. */ public AlgorithmIdentifier getSignatureAlgorithm() { return x509Certificate.getSignatureAlgorithm(); } /** * Return the bytes making up the signature associated with this attribute certificate. * * @return the attribute certificate signature bytes. */ public byte[] getSignature() { return x509Certificate.getSignature().getBytes(); } /** * Return whether or not this certificate is valid on a particular date. * * @param date the date of interest. * @return true if the certificate is valid, false otherwise. */ public boolean isValidOn(Date date) { return !CertUtils.dateBefore(date, x509Certificate.getStartDate().getDate()) && !CertUtils.dateAfter(date, x509Certificate.getEndDate().getDate()); } /** * Validate the signature on the certificate in this holder. * * @param verifierProvider a ContentVerifierProvider that can generate a verifier for the signature. * @return true if the signature is valid, false otherwise. * @throws CertException if the signature cannot be processed or is inappropriate. */ public boolean isSignatureValid(ContentVerifierProvider verifierProvider) throws CertException { TBSCertificate tbsCert = x509Certificate.getTBSCertificate(); if (!CertUtils.isAlgIdEqual(tbsCert.getSignature(), x509Certificate.getSignatureAlgorithm())) { throw new CertException("signature invalid - algorithm identifier mismatch"); } ContentVerifier verifier; try { verifier = verifierProvider.get((tbsCert.getSignature())); OutputStream sOut = verifier.getOutputStream(); DEROutputStream dOut = new DEROutputStream(sOut); dOut.writeObject(tbsCert); sOut.close(); } catch (Exception e) { throw new CertException("unable to process signature: " + e.getMessage(), e); } return verifier.verify(x509Certificate.getSignature().getBytes()); } public boolean equals( Object o) { if (o == this) { return true; } if (!(o instanceof X509CertificateHolder)) { return false; } X509CertificateHolder other = (X509CertificateHolder)o; return this.x509Certificate.equals(other.x509Certificate); } public int hashCode() { return this.x509Certificate.hashCode(); } /** * Return the ASN.1 encoding of this holder's certificate. * * @return a DER encoded byte array. * @throws IOException if an encoding cannot be generated. */ public byte[] getEncoded() throws IOException { return x509Certificate.getEncoded(); } } bouncycastle-1.49.orig/j2me/org/bouncycastle/cms/0000755000175000017500000000000012152033550021326 5ustar ebourgebourgbouncycastle-1.49.orig/j2me/org/bouncycastle/cms/KeyTransRecipientInformation.java0000644000175000017500000000321211731764575030024 0ustar ebourgebourgpackage org.bouncycastle.cms; import org.bouncycastle.asn1.ASN1OctetString; import org.bouncycastle.asn1.cms.IssuerAndSerialNumber; import org.bouncycastle.asn1.cms.KeyTransRecipientInfo; import org.bouncycastle.asn1.cms.RecipientIdentifier; import org.bouncycastle.asn1.x509.AlgorithmIdentifier; /** * the KeyTransRecipientInformation class for a recipient who has been sent a secret * key encrypted using their public key that needs to be used to * extract the message. */ public class KeyTransRecipientInformation extends RecipientInformation { private KeyTransRecipientInfo info; KeyTransRecipientInformation( KeyTransRecipientInfo info, AlgorithmIdentifier messageAlgorithm, CMSSecureReadable secureReadable, AuthAttributesProvider additionalData) { super(info.getKeyEncryptionAlgorithm(), messageAlgorithm, secureReadable, additionalData); this.info = info; RecipientIdentifier r = info.getRecipientIdentifier(); if (r.isTagged()) { ASN1OctetString octs = ASN1OctetString.getInstance(r.getId()); rid = new KeyTransRecipientId(octs.getOctets()); } else { IssuerAndSerialNumber iAnds = IssuerAndSerialNumber.getInstance(r.getId()); rid = new KeyTransRecipientId(iAnds.getName(), iAnds.getSerialNumber().getValue()); } } protected RecipientOperator getRecipientOperator(Recipient recipient) throws CMSException { return ((KeyTransRecipient)recipient).getRecipientOperator(keyEncAlg, messageAlgorithm, info.getEncryptedKey().getOctets()); } } bouncycastle-1.49.orig/j2me/org/bouncycastle/cms/SignerInformation.java0000644000175000017500000005452511732461007025646 0ustar ebourgebourgpackage org.bouncycastle.cms; import java.io.IOException; import java.io.OutputStream; import java.util.ArrayList; import java.util.Enumeration; import java.util.Iterator; import java.util.List; import org.bouncycastle.asn1.ASN1Encodable; import org.bouncycastle.asn1.ASN1EncodableVector; import org.bouncycastle.asn1.ASN1Encoding; import org.bouncycastle.asn1.ASN1ObjectIdentifier; import org.bouncycastle.asn1.ASN1OctetString; import org.bouncycastle.asn1.ASN1Primitive; import org.bouncycastle.asn1.ASN1Set; import org.bouncycastle.asn1.DERObjectIdentifier; import org.bouncycastle.asn1.DERSet; import org.bouncycastle.asn1.cms.Attribute; import org.bouncycastle.asn1.cms.AttributeTable; import org.bouncycastle.asn1.cms.CMSAttributes; import org.bouncycastle.asn1.cms.IssuerAndSerialNumber; import org.bouncycastle.asn1.cms.SignerIdentifier; import org.bouncycastle.asn1.cms.SignerInfo; import org.bouncycastle.asn1.cms.Time; import org.bouncycastle.asn1.x509.AlgorithmIdentifier; import org.bouncycastle.asn1.x509.DigestInfo; import org.bouncycastle.cert.X509CertificateHolder; import org.bouncycastle.operator.ContentVerifier; import org.bouncycastle.operator.DigestCalculator; import org.bouncycastle.operator.OperatorCreationException; import org.bouncycastle.operator.RawContentVerifier; import org.bouncycastle.util.Arrays; /** * an expanded SignerInfo block from a CMS Signed message */ public class SignerInformation { private SignerId sid; private SignerInfo info; private AlgorithmIdentifier digestAlgorithm; private AlgorithmIdentifier encryptionAlgorithm; private final ASN1Set signedAttributeSet; private final ASN1Set unsignedAttributeSet; private CMSProcessable content; private byte[] signature; private ASN1ObjectIdentifier contentType; private byte[] resultDigest; // Derived private AttributeTable signedAttributeValues; private AttributeTable unsignedAttributeValues; private boolean isCounterSignature; SignerInformation( SignerInfo info, ASN1ObjectIdentifier contentType, CMSProcessable content, byte[] resultDigest) { this.info = info; this.contentType = contentType; this.isCounterSignature = contentType == null; SignerIdentifier s = info.getSID(); if (s.isTagged()) { ASN1OctetString octs = ASN1OctetString.getInstance(s.getId()); sid = new SignerId(octs.getOctets()); } else { IssuerAndSerialNumber iAnds = IssuerAndSerialNumber.getInstance(s.getId()); sid = new SignerId(iAnds.getName(), iAnds.getSerialNumber().getValue()); } this.digestAlgorithm = info.getDigestAlgorithm(); this.signedAttributeSet = info.getAuthenticatedAttributes(); this.unsignedAttributeSet = info.getUnauthenticatedAttributes(); this.encryptionAlgorithm = info.getDigestEncryptionAlgorithm(); this.signature = info.getEncryptedDigest().getOctets(); this.content = content; this.resultDigest = resultDigest; } public boolean isCounterSignature() { return isCounterSignature; } public ASN1ObjectIdentifier getContentType() { return this.contentType; } private byte[] encodeObj( ASN1Encodable obj) throws IOException { if (obj != null) { return obj.toASN1Primitive().getEncoded(); } return null; } public SignerId getSID() { return sid; } /** * return the version number for this objects underlying SignerInfo structure. */ public int getVersion() { return info.getVersion().getValue().intValue(); } public AlgorithmIdentifier getDigestAlgorithmID() { return digestAlgorithm; } /** * return the object identifier for the signature. */ public String getDigestAlgOID() { return digestAlgorithm.getObjectId().getId(); } /** * return the signature parameters, or null if there aren't any. */ public byte[] getDigestAlgParams() { try { return encodeObj(digestAlgorithm.getParameters()); } catch (Exception e) { throw new RuntimeException("exception getting digest parameters " + e); } } /** * return the content digest that was calculated during verification. */ public byte[] getContentDigest() { if (resultDigest == null) { throw new IllegalStateException("method can only be called after verify."); } return Arrays.clone(resultDigest); } /** * return the object identifier for the signature. */ public String getEncryptionAlgOID() { return encryptionAlgorithm.getObjectId().getId(); } /** * return the signature/encryption algorithm parameters, or null if * there aren't any. */ public byte[] getEncryptionAlgParams() { try { return encodeObj(encryptionAlgorithm.getParameters()); } catch (Exception e) { throw new RuntimeException("exception getting encryption parameters " + e); } } /** * return a table of the signed attributes - indexed by * the OID of the attribute. */ public AttributeTable getSignedAttributes() { if (signedAttributeSet != null && signedAttributeValues == null) { signedAttributeValues = new AttributeTable(signedAttributeSet); } return signedAttributeValues; } /** * return a table of the unsigned attributes indexed by * the OID of the attribute. */ public AttributeTable getUnsignedAttributes() { if (unsignedAttributeSet != null && unsignedAttributeValues == null) { unsignedAttributeValues = new AttributeTable(unsignedAttributeSet); } return unsignedAttributeValues; } /** * return the encoded signature */ public byte[] getSignature() { return Arrays.clone(signature); } /** * Return a SignerInformationStore containing the counter signatures attached to this * signer. If no counter signatures are present an empty store is returned. */ public SignerInformationStore getCounterSignatures() { // TODO There are several checks implied by the RFC3852 comments that are missing /* The countersignature attribute MUST be an unsigned attribute; it MUST NOT be a signed attribute, an authenticated attribute, an unauthenticated attribute, or an unprotected attribute. */ AttributeTable unsignedAttributeTable = getUnsignedAttributes(); if (unsignedAttributeTable == null) { return new SignerInformationStore(new ArrayList(0)); } List counterSignatures = new ArrayList(); /* The UnsignedAttributes syntax is defined as a SET OF Attributes. The UnsignedAttributes in a signerInfo may include multiple instances of the countersignature attribute. */ ASN1EncodableVector allCSAttrs = unsignedAttributeTable.getAll(CMSAttributes.counterSignature); for (int i = 0; i < allCSAttrs.size(); ++i) { Attribute counterSignatureAttribute = (Attribute)allCSAttrs.get(i); /* A countersignature attribute can have multiple attribute values. The syntax is defined as a SET OF AttributeValue, and there MUST be one or more instances of AttributeValue present. */ ASN1Set values = counterSignatureAttribute.getAttrValues(); if (values.size() < 1) { // TODO Throw an appropriate exception? } for (Enumeration en = values.getObjects(); en.hasMoreElements();) { /* Countersignature values have the same meaning as SignerInfo values for ordinary signatures, except that: 1. The signedAttributes field MUST NOT contain a content-type attribute; there is no content type for countersignatures. 2. The signedAttributes field MUST contain a message-digest attribute if it contains any other attributes. 3. The input to the message-digesting process is the contents octets of the DER encoding of the signatureValue field of the SignerInfo value with which the attribute is associated. */ SignerInfo si = SignerInfo.getInstance(en.nextElement()); counterSignatures.add(new SignerInformation(si, null, new CMSProcessableByteArray(getSignature()), null)); } } return new SignerInformationStore(counterSignatures); } /** * return the DER encoding of the signed attributes. * @throws IOException if an encoding error occurs. */ public byte[] getEncodedSignedAttributes() throws IOException { if (signedAttributeSet != null) { return signedAttributeSet.getEncoded(); } return null; } private boolean doVerify( SignerInformationVerifier verifier) throws CMSException { String encName = CMSSignedHelper.INSTANCE.getEncryptionAlgName(this.getEncryptionAlgOID()); try { if (resultDigest == null) { DigestCalculator calc = verifier.getDigestCalculator(this.getDigestAlgorithmID()); if (content != null) { OutputStream digOut = calc.getOutputStream(); content.write(digOut); digOut.close(); } else if (signedAttributeSet == null) { // TODO Get rid of this exception and just treat content==null as empty not missing? throw new CMSException("data not encapsulated in signature - use detached constructor."); } resultDigest = calc.getDigest(); } } catch (IOException e) { throw new CMSException("can't process mime object to create signature.", e); } catch (OperatorCreationException e) { throw new CMSException("can't create digest calculator: " + e.getMessage(), e); } // RFC 3852 11.1 Check the content-type attribute is correct { ASN1Primitive validContentType = getSingleValuedSignedAttribute( CMSAttributes.contentType, "content-type"); if (validContentType == null) { if (!isCounterSignature && signedAttributeSet != null) { throw new CMSException("The content-type attribute type MUST be present whenever signed attributes are present in signed-data"); } } else { if (isCounterSignature) { throw new CMSException("[For counter signatures,] the signedAttributes field MUST NOT contain a content-type attribute"); } if (!(validContentType instanceof DERObjectIdentifier)) { throw new CMSException("content-type attribute value not of ASN.1 type 'OBJECT IDENTIFIER'"); } DERObjectIdentifier signedContentType = (DERObjectIdentifier)validContentType; if (!signedContentType.equals(contentType)) { throw new CMSException("content-type attribute value does not match eContentType"); } } } // RFC 3852 11.2 Check the message-digest attribute is correct { ASN1Primitive validMessageDigest = getSingleValuedSignedAttribute( CMSAttributes.messageDigest, "message-digest"); if (validMessageDigest == null) { if (signedAttributeSet != null) { throw new CMSException("the message-digest signed attribute type MUST be present when there are any signed attributes present"); } } else { if (!(validMessageDigest instanceof ASN1OctetString)) { throw new CMSException("message-digest attribute value not of ASN.1 type 'OCTET STRING'"); } ASN1OctetString signedMessageDigest = (ASN1OctetString)validMessageDigest; if (!Arrays.constantTimeAreEqual(resultDigest, signedMessageDigest.getOctets())) { throw new CMSSignerDigestMismatchException("message-digest attribute value does not match calculated value"); } } } // RFC 3852 11.4 Validate countersignature attribute(s) { AttributeTable signedAttrTable = this.getSignedAttributes(); if (signedAttrTable != null && signedAttrTable.getAll(CMSAttributes.counterSignature).size() > 0) { throw new CMSException("A countersignature attribute MUST NOT be a signed attribute"); } AttributeTable unsignedAttrTable = this.getUnsignedAttributes(); if (unsignedAttrTable != null) { ASN1EncodableVector csAttrs = unsignedAttrTable.getAll(CMSAttributes.counterSignature); for (int i = 0; i < csAttrs.size(); ++i) { Attribute csAttr = (Attribute)csAttrs.get(i); if (csAttr.getAttrValues().size() < 1) { throw new CMSException("A countersignature attribute MUST contain at least one AttributeValue"); } // Note: We don't recursively validate the countersignature value } } } try { ContentVerifier contentVerifier = verifier.getContentVerifier(encryptionAlgorithm, info.getDigestAlgorithm()); OutputStream sigOut = contentVerifier.getOutputStream(); if (signedAttributeSet == null) { if (resultDigest != null) { if (contentVerifier instanceof RawContentVerifier) { RawContentVerifier rawVerifier = (RawContentVerifier)contentVerifier; if (encName.equals("RSA")) { DigestInfo digInfo = new DigestInfo(digestAlgorithm, resultDigest); return rawVerifier.verify(digInfo.getEncoded(ASN1Encoding.DER), this.getSignature()); } return rawVerifier.verify(resultDigest, this.getSignature()); } throw new CMSException("verifier unable to process raw signature"); } else if (content != null) { // TODO Use raw signature of the hash value instead content.write(sigOut); } } else { sigOut.write(this.getEncodedSignedAttributes()); } sigOut.close(); return contentVerifier.verify(this.getSignature()); } catch (IOException e) { throw new CMSException("can't process mime object to create signature.", e); } catch (OperatorCreationException e) { throw new CMSException("can't create content verifier: " + e.getMessage(), e); } } /** * Verify that the given verifier can successfully verify the signature on * this SignerInformation object. * * @param verifier a suitably configured SignerInformationVerifier. * @return true if the signer information is verified, false otherwise. * @throws org.bouncycastle.cms.CMSVerifierCertificateNotValidException if the provider has an associated certificate and the certificate is not valid at the time given as the SignerInfo's signing time. * @throws org.bouncycastle.cms.CMSException if the verifier is unable to create a ContentVerifiers or DigestCalculators. */ public boolean verify(SignerInformationVerifier verifier) throws CMSException { Time signingTime = getSigningTime(); // has to be validated if present. if (verifier.hasAssociatedCertificate()) { if (signingTime != null) { X509CertificateHolder dcv = verifier.getAssociatedCertificate(); if (!dcv.isValidOn(signingTime.getDate())) { throw new CMSVerifierCertificateNotValidException("verifier not valid at signingTime"); } } } return doVerify(verifier); } /** * Return the base ASN.1 CMS structure that this object contains. * * @return an object containing a CMS SignerInfo structure. * @deprecated use toASN1Structure() */ public SignerInfo toSignerInfo() { return info; } /** * Return the underlying ASN.1 object defining this SignerInformation object. * * @return a SignerInfo. */ public SignerInfo toASN1Structure() { return info; } private ASN1Primitive getSingleValuedSignedAttribute( ASN1ObjectIdentifier attrOID, String printableName) throws CMSException { AttributeTable unsignedAttrTable = this.getUnsignedAttributes(); if (unsignedAttrTable != null && unsignedAttrTable.getAll(attrOID).size() > 0) { throw new CMSException("The " + printableName + " attribute MUST NOT be an unsigned attribute"); } AttributeTable signedAttrTable = this.getSignedAttributes(); if (signedAttrTable == null) { return null; } ASN1EncodableVector v = signedAttrTable.getAll(attrOID); switch (v.size()) { case 0: return null; case 1: { Attribute t = (Attribute)v.get(0); ASN1Set attrValues = t.getAttrValues(); if (attrValues.size() != 1) { throw new CMSException("A " + printableName + " attribute MUST have a single attribute value"); } return attrValues.getObjectAt(0).toASN1Primitive(); } default: throw new CMSException("The SignedAttributes in a signerInfo MUST NOT include multiple instances of the " + printableName + " attribute"); } } private Time getSigningTime() throws CMSException { ASN1Primitive validSigningTime = getSingleValuedSignedAttribute( CMSAttributes.signingTime, "signing-time"); if (validSigningTime == null) { return null; } try { return Time.getInstance(validSigningTime); } catch (IllegalArgumentException e) { throw new CMSException("signing-time attribute value not a valid 'Time' structure"); } } /** * Return a signer information object with the passed in unsigned * attributes replacing the ones that are current associated with * the object passed in. * * @param signerInformation the signerInfo to be used as the basis. * @param unsignedAttributes the unsigned attributes to add. * @return a copy of the original SignerInformationObject with the changed attributes. */ public static SignerInformation replaceUnsignedAttributes( SignerInformation signerInformation, AttributeTable unsignedAttributes) { SignerInfo sInfo = signerInformation.info; ASN1Set unsignedAttr = null; if (unsignedAttributes != null) { unsignedAttr = new DERSet(unsignedAttributes.toASN1EncodableVector()); } return new SignerInformation( new SignerInfo(sInfo.getSID(), sInfo.getDigestAlgorithm(), sInfo.getAuthenticatedAttributes(), sInfo.getDigestEncryptionAlgorithm(), sInfo.getEncryptedDigest(), unsignedAttr), signerInformation.contentType, signerInformation.content, null); } /** * Return a signer information object with passed in SignerInformationStore representing counter * signatures attached as an unsigned attribute. * * @param signerInformation the signerInfo to be used as the basis. * @param counterSigners signer info objects carrying counter signature. * @return a copy of the original SignerInformationObject with the changed attributes. */ public static SignerInformation addCounterSigners( SignerInformation signerInformation, SignerInformationStore counterSigners) { // TODO Perform checks from RFC 3852 11.4 SignerInfo sInfo = signerInformation.info; AttributeTable unsignedAttr = signerInformation.getUnsignedAttributes(); ASN1EncodableVector v; if (unsignedAttr != null) { v = unsignedAttr.toASN1EncodableVector(); } else { v = new ASN1EncodableVector(); } ASN1EncodableVector sigs = new ASN1EncodableVector(); for (Iterator it = counterSigners.getSigners().iterator(); it.hasNext();) { sigs.add(((SignerInformation)it.next()).toSignerInfo()); } v.add(new Attribute(CMSAttributes.counterSignature, new DERSet(sigs))); return new SignerInformation( new SignerInfo(sInfo.getSID(), sInfo.getDigestAlgorithm(), sInfo.getAuthenticatedAttributes(), sInfo.getDigestEncryptionAlgorithm(), sInfo.getEncryptedDigest(), new DERSet(v)), signerInformation.contentType, signerInformation.content, null); } } bouncycastle-1.49.orig/j2me/org/bouncycastle/cms/CMSSignedData.java0000644000175000017500000004154712150050436024552 0ustar ebourgebourgpackage org.bouncycastle.cms; import java.io.IOException; import java.io.InputStream; import java.io.OutputStream; import java.util.ArrayList; import java.util.Collection; import java.util.Iterator; import java.util.List; import java.util.Map; import org.bouncycastle.asn1.ASN1EncodableVector; import org.bouncycastle.asn1.ASN1InputStream; import org.bouncycastle.asn1.ASN1ObjectIdentifier; import org.bouncycastle.asn1.ASN1OctetString; import org.bouncycastle.asn1.ASN1Sequence; import org.bouncycastle.asn1.ASN1Set; import org.bouncycastle.asn1.BERSequence; import org.bouncycastle.asn1.DERSet; import org.bouncycastle.asn1.cms.ContentInfo; import org.bouncycastle.asn1.cms.SignedData; import org.bouncycastle.asn1.cms.SignerInfo; import org.bouncycastle.operator.DefaultSignatureAlgorithmIdentifierFinder; import org.bouncycastle.operator.OperatorCreationException; import org.bouncycastle.operator.SignatureAlgorithmIdentifierFinder; import org.bouncycastle.util.Store; /** * general class for handling a pkcs7-signature message. * * A simple example of usage - note, in the example below the validity of * the certificate isn't verified, just the fact that one of the certs * matches the given signer... * *
     *  Store                   certStore = s.getCertificates();
     *  SignerInformationStore  signers = s.getSignerInfos();
     *  Collection              c = signers.getSigners();
     *  Iterator                it = c.iterator();
     *  
     *  while (it.hasNext())
     *  {
     *      SignerInformation   signer = (SignerInformation)it.next();
     *      Collection          certCollection = certStore.getMatches(signer.getSID());
     *
     *      Iterator              certIt = certCollection.iterator();
     *      X509CertificateHolder cert = (X509CertificateHolder)certIt.next();
     *  
     *      if (signer.verify(new JcaSimpleSignerInfoVerifierBuilder().setProvider("BC").build(cert)))
     *      {
     *          verified++;
     *      }   
     *  }
     * 
    */ public class CMSSignedData { private static final CMSSignedHelper HELPER = CMSSignedHelper.INSTANCE; SignedData signedData; ContentInfo contentInfo; CMSTypedData signedContent; SignerInformationStore signerInfoStore; private Map hashes; private CMSSignedData( CMSSignedData c) { this.signedData = c.signedData; this.contentInfo = c.contentInfo; this.signedContent = c.signedContent; this.signerInfoStore = c.signerInfoStore; } public CMSSignedData( byte[] sigBlock) throws CMSException { this(CMSUtils.readContentInfo(sigBlock)); } public CMSSignedData( CMSProcessable signedContent, byte[] sigBlock) throws CMSException { this(signedContent, CMSUtils.readContentInfo(sigBlock)); } /** * Content with detached signature, digests precomputed * * @param hashes a map of precomputed digests for content indexed by name of hash. * @param sigBlock the signature object. */ public CMSSignedData( Map hashes, byte[] sigBlock) throws CMSException { this(hashes, CMSUtils.readContentInfo(sigBlock)); } /** * base constructor - content with detached signature. * * @param signedContent the content that was signed. * @param sigData the signature object. */ public CMSSignedData( CMSProcessable signedContent, InputStream sigData) throws CMSException { this(signedContent, CMSUtils.readContentInfo(new ASN1InputStream(sigData))); } /** * base constructor - with encapsulated content */ public CMSSignedData( InputStream sigData) throws CMSException { this(CMSUtils.readContentInfo(sigData)); } public CMSSignedData( final CMSProcessable signedContent, ContentInfo sigData) throws CMSException { if (signedContent instanceof CMSTypedData) { this.signedContent = (CMSTypedData)signedContent; } else { this.signedContent = new CMSTypedData() { public ASN1ObjectIdentifier getContentType() { return signedData.getEncapContentInfo().getContentType(); } public void write(OutputStream out) throws IOException, CMSException { signedContent.write(out); } public Object getContent() { return signedContent.getContent(); } }; } this.contentInfo = sigData; this.signedData = getSignedData(); } public CMSSignedData( Map hashes, ContentInfo sigData) throws CMSException { this.hashes = hashes; this.contentInfo = sigData; this.signedData = getSignedData(); } public CMSSignedData( ContentInfo sigData) throws CMSException { this.contentInfo = sigData; this.signedData = getSignedData(); // // this can happen if the signed message is sent simply to send a // certificate chain. // if (signedData.getEncapContentInfo().getContent() != null) { this.signedContent = new CMSProcessableByteArray(signedData.getEncapContentInfo().getContentType(), ((ASN1OctetString)(signedData.getEncapContentInfo() .getContent())).getOctets()); } else { this.signedContent = null; } } private SignedData getSignedData() throws CMSException { try { return SignedData.getInstance(contentInfo.getContent()); } catch (ClassCastException e) { throw new CMSException("Malformed content.", e); } catch (IllegalArgumentException e) { throw new CMSException("Malformed content.", e); } } /** * Return the version number for this object */ public int getVersion() { return signedData.getVersion().getValue().intValue(); } /** * return the collection of signers that are associated with the * signatures for the message. */ public SignerInformationStore getSignerInfos() { if (signerInfoStore == null) { ASN1Set s = signedData.getSignerInfos(); List signerInfos = new ArrayList(); SignatureAlgorithmIdentifierFinder sigAlgFinder = new DefaultSignatureAlgorithmIdentifierFinder(); for (int i = 0; i != s.size(); i++) { SignerInfo info = SignerInfo.getInstance(s.getObjectAt(i)); ASN1ObjectIdentifier contentType = signedData.getEncapContentInfo().getContentType(); if (hashes == null) { signerInfos.add(new SignerInformation(info, contentType, signedContent, null)); } else { Object obj = hashes.keySet().iterator().next(); byte[] hash = (obj instanceof String) ? (byte[])hashes.get(info.getDigestAlgorithm().getAlgorithm().getId()) : (byte[])hashes.get(info.getDigestAlgorithm().getAlgorithm()); signerInfos.add(new SignerInformation(info, contentType, null, hash)); } } signerInfoStore = new SignerInformationStore(signerInfos); } return signerInfoStore; } /** * Return any X.509 certificate objects in this SignedData structure as a Store of X509CertificateHolder objects. * * @return a Store of X509CertificateHolder objects. */ public Store getCertificates() { return HELPER.getCertificates(signedData.getCertificates()); } /** * Return any X.509 CRL objects in this SignedData structure as a Store of X509CRLHolder objects. * * @return a Store of X509CRLHolder objects. */ public Store getCRLs() { return HELPER.getCRLs(signedData.getCRLs()); } /** * Return any X.509 attribute certificate objects in this SignedData structure as a Store of X509AttributeCertificateHolder objects. * * @return a Store of X509AttributeCertificateHolder objects. */ public Store getAttributeCertificates() { return HELPER.getAttributeCertificates(signedData.getCertificates()); } /** * Return any OtherRevocationInfo OtherRevInfo objects of the type indicated by otherRevocationInfoFormat in * this SignedData structure. * * @param otherRevocationInfoFormat OID of the format type been looked for. * * @return a Store of ASN1Encodable objects representing any objects of otherRevocationInfoFormat found. */ public Store getOtherRevocationInfo(ASN1ObjectIdentifier otherRevocationInfoFormat) { return HELPER.getOtherRevocationInfo(otherRevocationInfoFormat, signedData.getCRLs()); } /** * Return the a string representation of the OID associated with the * encapsulated content info structure carried in the signed data. * * @return the OID for the content type. */ public String getSignedContentTypeOID() { return signedData.getEncapContentInfo().getContentType().getId(); } public CMSTypedData getSignedContent() { return signedContent; } /** * return the ContentInfo */ public ContentInfo toASN1Structure() { return contentInfo; } /** * return the ASN.1 encoded representation of this object. */ public byte[] getEncoded() throws IOException { return contentInfo.getEncoded(); } /** * Verify all the SignerInformation objects and their associated counter signatures attached * to this CMS SignedData object. * * @param verifierProvider a provider of SignerInformationVerifier objects. * @return true if all verify, false otherwise. * @throws CMSException if an exception occurs during the verification process. */ public boolean verifySignatures(SignerInformationVerifierProvider verifierProvider) throws CMSException { return verifySignatures(verifierProvider, false); } /** * Verify all the SignerInformation objects and optionally their associated counter signatures attached * to this CMS SignedData object. * * @param verifierProvider a provider of SignerInformationVerifier objects. * @param ignoreCounterSignatures if true don't check counter signatures. If false check counter signatures as well. * @return true if all verify, false otherwise. * @throws CMSException if an exception occurs during the verification process. */ public boolean verifySignatures(SignerInformationVerifierProvider verifierProvider, boolean ignoreCounterSignatures) throws CMSException { Collection signers = this.getSignerInfos().getSigners(); for (Iterator it = signers.iterator(); it.hasNext();) { SignerInformation signer = (SignerInformation)it.next(); try { SignerInformationVerifier verifier = verifierProvider.get(signer.getSID()); if (!signer.verify(verifier)) { return false; } if (!ignoreCounterSignatures) { Collection counterSigners = signer.getCounterSignatures().getSigners(); for (Iterator cIt = counterSigners.iterator(); cIt.hasNext();) { SignerInformation counterSigner = (SignerInformation)cIt.next(); SignerInformationVerifier counterVerifier = verifierProvider.get(signer.getSID()); if (!counterSigner.verify(counterVerifier)) { return false; } } } } catch (OperatorCreationException e) { throw new CMSException("failure in verifier provider: " + e.getMessage(), e); } } return true; } /** * Replace the SignerInformation store associated with this * CMSSignedData object with the new one passed in. You would * probably only want to do this if you wanted to change the unsigned * attributes associated with a signer, or perhaps delete one. * * @param signedData the signed data object to be used as a base. * @param signerInformationStore the new signer information store to use. * @return a new signed data object. */ public static CMSSignedData replaceSigners( CMSSignedData signedData, SignerInformationStore signerInformationStore) { // // copy // CMSSignedData cms = new CMSSignedData(signedData); // // replace the store // cms.signerInfoStore = signerInformationStore; // // replace the signers in the SignedData object // ASN1EncodableVector digestAlgs = new ASN1EncodableVector(); ASN1EncodableVector vec = new ASN1EncodableVector(); Iterator it = signerInformationStore.getSigners().iterator(); while (it.hasNext()) { SignerInformation signer = (SignerInformation)it.next(); digestAlgs.add(CMSSignedHelper.INSTANCE.fixAlgID(signer.getDigestAlgorithmID())); vec.add(signer.toASN1Structure()); } ASN1Set digests = new DERSet(digestAlgs); ASN1Set signers = new DERSet(vec); ASN1Sequence sD = (ASN1Sequence)signedData.signedData.toASN1Primitive(); vec = new ASN1EncodableVector(); // // signers are the last item in the sequence. // vec.add(sD.getObjectAt(0)); // version vec.add(digests); for (int i = 2; i != sD.size() - 1; i++) { vec.add(sD.getObjectAt(i)); } vec.add(signers); cms.signedData = SignedData.getInstance(new BERSequence(vec)); // // replace the contentInfo with the new one // cms.contentInfo = new ContentInfo(cms.contentInfo.getContentType(), cms.signedData); return cms; } /** * Replace the certificate and CRL information associated with this * CMSSignedData object with the new one passed in. * * @param signedData the signed data object to be used as a base. * @param certificates the new certificates to be used. * @param attrCerts the new attribute certificates to be used. * @param crls the new CRLs to be used. * @return a new signed data object. * @exception CMSException if there is an error processing the CertStore */ public static CMSSignedData replaceCertificatesAndCRLs( CMSSignedData signedData, Store certificates, Store attrCerts, Store crls) throws CMSException { // // copy // CMSSignedData cms = new CMSSignedData(signedData); // // replace the certs and crls in the SignedData object // ASN1Set certSet = null; ASN1Set crlSet = null; if (certificates != null || attrCerts != null) { List certs = new ArrayList(); if (certificates != null) { certs.addAll(CMSUtils.getCertificatesFromStore(certificates)); } if (attrCerts != null) { certs.addAll(CMSUtils.getAttributeCertificatesFromStore(attrCerts)); } ASN1Set set = CMSUtils.createBerSetFromList(certs); if (set.size() != 0) { certSet = set; } } if (crls != null) { ASN1Set set = CMSUtils.createBerSetFromList(CMSUtils.getCRLsFromStore(crls)); if (set.size() != 0) { crlSet = set; } } // // replace the CMS structure. // cms.signedData = new SignedData(signedData.signedData.getDigestAlgorithms(), signedData.signedData.getEncapContentInfo(), certSet, crlSet, signedData.signedData.getSignerInfos()); // // replace the contentInfo with the new one // cms.contentInfo = new ContentInfo(cms.contentInfo.getContentType(), cms.signedData); return cms; } } bouncycastle-1.49.orig/j2me/org/bouncycastle/cms/CMSUtils.java0000644000175000017500000001713012150050436023636 0ustar ebourgebourgpackage org.bouncycastle.cms; import java.io.IOException; import java.io.InputStream; import java.io.OutputStream; import java.util.ArrayList; import java.util.Collection; import java.util.Iterator; import java.util.List; import org.bouncycastle.asn1.ASN1Encodable; import org.bouncycastle.asn1.ASN1EncodableVector; import org.bouncycastle.asn1.ASN1InputStream; import org.bouncycastle.asn1.ASN1ObjectIdentifier; import org.bouncycastle.asn1.ASN1Primitive; import org.bouncycastle.asn1.ASN1Set; import org.bouncycastle.asn1.BEROctetStringGenerator; import org.bouncycastle.asn1.BERSet; import org.bouncycastle.asn1.DERSet; import org.bouncycastle.asn1.DERTaggedObject; import org.bouncycastle.asn1.cms.CMSObjectIdentifiers; import org.bouncycastle.asn1.cms.ContentInfo; import org.bouncycastle.asn1.cms.IssuerAndSerialNumber; import org.bouncycastle.asn1.cms.OtherRecipientInfo; import org.bouncycastle.asn1.cms.OtherRevocationInfoFormat; import org.bouncycastle.asn1.ocsp.OCSPResponse; import org.bouncycastle.asn1.ocsp.OCSPResponseStatus; import org.bouncycastle.asn1.x509.Certificate; import org.bouncycastle.asn1.x509.CertificateList; import org.bouncycastle.asn1.x509.TBSCertificate; import org.bouncycastle.cert.X509AttributeCertificateHolder; import org.bouncycastle.cert.X509CRLHolder; import org.bouncycastle.cert.X509CertificateHolder; import org.bouncycastle.operator.DigestCalculator; import org.bouncycastle.util.Store; import org.bouncycastle.util.io.Streams; import org.bouncycastle.util.io.TeeInputStream; import org.bouncycastle.util.io.TeeOutputStream; class CMSUtils { static ContentInfo readContentInfo( byte[] input) throws CMSException { // enforce limit checking as from a byte array return readContentInfo(new ASN1InputStream(input)); } static ContentInfo readContentInfo( InputStream input) throws CMSException { // enforce some limit checking return readContentInfo(new ASN1InputStream(input)); } static List getCertificatesFromStore(Store certStore) throws CMSException { List certs = new ArrayList(); try { for (Iterator it = certStore.getMatches(null).iterator(); it.hasNext();) { X509CertificateHolder c = (X509CertificateHolder)it.next(); certs.add(c.toASN1Structure()); } return certs; } catch (ClassCastException e) { throw new CMSException("error processing certs", e); } } static List getAttributeCertificatesFromStore(Store attrStore) throws CMSException { List certs = new ArrayList(); try { for (Iterator it = attrStore.getMatches(null).iterator(); it.hasNext();) { X509AttributeCertificateHolder attrCert = (X509AttributeCertificateHolder)it.next(); certs.add(new DERTaggedObject(false, 2, attrCert.toASN1Structure())); } return certs; } catch (ClassCastException e) { throw new CMSException("error processing certs", e); } } static List getCRLsFromStore(Store crlStore) throws CMSException { List certs = new ArrayList(); try { for (Iterator it = crlStore.getMatches(null).iterator(); it.hasNext();) { X509CRLHolder c = (X509CRLHolder)it.next(); certs.add(c.toASN1Structure()); } return certs; } catch (ClassCastException e) { throw new CMSException("error processing certs", e); } } static Collection getOthersFromStore(ASN1ObjectIdentifier otherRevocationInfoFormat, Store otherRevocationInfos) { List others = new ArrayList(); for (Iterator it = otherRevocationInfos.getMatches(null).iterator(); it.hasNext();) { ASN1Encodable info = (ASN1Encodable)it.next(); if (CMSObjectIdentifiers.id_ri_ocsp_response.equals(otherRevocationInfoFormat)) { OCSPResponse resp = OCSPResponse.getInstance(info); if (resp.getResponseStatus().getValue().intValue() != OCSPResponseStatus.SUCCESSFUL) { throw new IllegalArgumentException("cannot add unsuccessful OCSP response to CMS SignedData"); } } others.add(new DERTaggedObject(false, 1, new OtherRevocationInfoFormat(otherRevocationInfoFormat, info))); } return others; } static ASN1Set createBerSetFromList(List derObjects) { ASN1EncodableVector v = new ASN1EncodableVector(); for (Iterator it = derObjects.iterator(); it.hasNext();) { v.add((ASN1Encodable)it.next()); } return new BERSet(v); } static ASN1Set createDerSetFromList(List derObjects) { ASN1EncodableVector v = new ASN1EncodableVector(); for (Iterator it = derObjects.iterator(); it.hasNext();) { v.add((ASN1Encodable)it.next()); } return new DERSet(v); } static OutputStream createBEROctetOutputStream(OutputStream s, int tagNo, boolean isExplicit, int bufferSize) throws IOException { BEROctetStringGenerator octGen = new BEROctetStringGenerator(s, tagNo, isExplicit); if (bufferSize != 0) { return octGen.getOctetOutputStream(new byte[bufferSize]); } return octGen.getOctetOutputStream(); } private static ContentInfo readContentInfo( ASN1InputStream in) throws CMSException { try { return ContentInfo.getInstance(in.readObject()); } catch (IOException e) { throw new CMSException("IOException reading content.", e); } catch (ClassCastException e) { throw new CMSException("Malformed content.", e); } catch (IllegalArgumentException e) { throw new CMSException("Malformed content.", e); } } public static byte[] streamToByteArray( InputStream in) throws IOException { return Streams.readAll(in); } public static byte[] streamToByteArray( InputStream in, int limit) throws IOException { return Streams.readAllLimited(in, limit); } static InputStream attachDigestsToInputStream(Collection digests, InputStream s) { InputStream result = s; Iterator it = digests.iterator(); while (it.hasNext()) { DigestCalculator digest = (DigestCalculator)it.next(); result = new TeeInputStream(result, digest.getOutputStream()); } return result; } static OutputStream attachSignersToOutputStream(Collection signers, OutputStream s) { OutputStream result = s; Iterator it = signers.iterator(); while (it.hasNext()) { SignerInfoGenerator signerGen = (SignerInfoGenerator)it.next(); result = getSafeTeeOutputStream(result, signerGen.getCalculatingOutputStream()); } return result; } static OutputStream getSafeOutputStream(OutputStream s) { return s == null ? new NullOutputStream() : s; } static OutputStream getSafeTeeOutputStream(OutputStream s1, OutputStream s2) { return s1 == null ? getSafeOutputStream(s2) : s2 == null ? getSafeOutputStream(s1) : new TeeOutputStream( s1, s2); } } bouncycastle-1.49.orig/j2me/org/bouncycastle/cms/CMSTypedStream.java0000644000175000017500000000353111731762107025010 0ustar ebourgebourgpackage org.bouncycastle.cms; import java.io.FilterInputStream; import java.io.IOException; import java.io.InputStream; import org.bouncycastle.asn1.ASN1ObjectIdentifier; import org.bouncycastle.asn1.pkcs.PKCSObjectIdentifiers; import org.bouncycastle.util.io.Streams; public class CMSTypedStream { private static final int BUF_SIZ = 32 * 1024; private final ASN1ObjectIdentifier _oid; private final InputStream _in; public CMSTypedStream( InputStream in) { this(PKCSObjectIdentifiers.data.getId(), in, BUF_SIZ); } public CMSTypedStream( String oid, InputStream in) { this(new ASN1ObjectIdentifier(oid), in, BUF_SIZ); } public CMSTypedStream( String oid, InputStream in, int bufSize) { this(new ASN1ObjectIdentifier(oid), in, bufSize); } public CMSTypedStream( ASN1ObjectIdentifier oid, InputStream in) { this(oid, in, BUF_SIZ); } public CMSTypedStream( ASN1ObjectIdentifier oid, InputStream in, int bufSize) { _oid = oid; _in = new FullReaderStream(in); } public ASN1ObjectIdentifier getContentType() { return _oid; } public InputStream getContentStream() { return _in; } public void drain() throws IOException { Streams.drain(_in); _in.close(); } private static class FullReaderStream extends FilterInputStream { FullReaderStream(InputStream in) { super(in); } public int read(byte[] buf, int off, int len) throws IOException { int totalRead = Streams.readFully(super.in, buf, off, len); return totalRead > 0 ? totalRead : -1; } } } bouncycastle-1.49.orig/j2me/org/bouncycastle/cms/CMSSignedDataStreamGenerator.java0000644000175000017500000003775112150050436027577 0ustar ebourgebourgpackage org.bouncycastle.cms; import java.io.IOException; import java.io.OutputStream; import java.security.SecureRandom; import java.util.Iterator; import java.util.List; import org.bouncycastle.asn1.ASN1EncodableVector; import org.bouncycastle.asn1.ASN1Integer; import org.bouncycastle.asn1.ASN1ObjectIdentifier; import org.bouncycastle.asn1.ASN1Set; import org.bouncycastle.asn1.ASN1TaggedObject; import org.bouncycastle.asn1.BERSequenceGenerator; import org.bouncycastle.asn1.BERTaggedObject; import org.bouncycastle.asn1.DERSet; import org.bouncycastle.asn1.cms.AttributeTable; import org.bouncycastle.asn1.cms.CMSObjectIdentifiers; import org.bouncycastle.asn1.cms.SignerInfo; import org.bouncycastle.operator.ContentSigner; import org.bouncycastle.operator.OperatorCreationException; /** * General class for generating a pkcs7-signature message stream. *

    * A simple example of usage. *

    *
     *      X509Certificate signCert = ...
     *      certList.add(signCert);
     *
     *      Store           certs = new JcaCertStore(certList);
     *      ContentSigner sha1Signer = new JcaContentSignerBuilder("SHA1withRSA").setProvider("BC").build(signKP.getPrivate());
     *
     *      CMSSignedDataStreamGenerator gen = new CMSSignedDataStreamGenerator();
     *  
     *      gen.addSignerInfoGenerator(
     *                new JcaSignerInfoGeneratorBuilder(
     *                     new JcaDigestCalculatorProviderBuilder().setProvider("BC").build())
     *                     .build(sha1Signer, signCert));
     *
     *      gen.addCertificates(certs);
     *  
     *      OutputStream sigOut = gen.open(bOut);
     *  
     *      sigOut.write("Hello World!".getBytes());
     *      
     *      sigOut.close();
     * 
    */ public class CMSSignedDataStreamGenerator extends CMSSignedGenerator { private int _bufferSize; /** * base constructor */ public CMSSignedDataStreamGenerator() { } /** * Set the underlying string size for encapsulated data * * @param bufferSize length of octet strings to buffer the data. */ public void setBufferSize( int bufferSize) { _bufferSize = bufferSize; } /** * generate a signed object that for a CMS Signed Data * object using the given provider. */ public OutputStream open( OutputStream out) throws IOException { return open(out, false); } /** * generate a signed object that for a CMS Signed Data * object using the given provider - if encapsulate is true a copy * of the message will be included in the signature with the * default content type "data". */ public OutputStream open( OutputStream out, boolean encapsulate) throws IOException { return open(CMSObjectIdentifiers.data, out, encapsulate); } /** * generate a signed object that for a CMS Signed Data * object using the given provider - if encapsulate is true a copy * of the message will be included in the signature with the * default content type "data". If dataOutputStream is non null the data * being signed will be written to the stream as it is processed. * @param out stream the CMS object is to be written to. * @param encapsulate true if data should be encapsulated. * @param dataOutputStream output stream to copy the data being signed to. */ public OutputStream open( OutputStream out, boolean encapsulate, OutputStream dataOutputStream) throws IOException { return open(CMSObjectIdentifiers.data, out, encapsulate, dataOutputStream); } /** * generate a signed object that for a CMS Signed Data * object using the given provider - if encapsulate is true a copy * of the message will be included in the signature. The content type * is set according to the OID represented by the string signedContentType. */ public OutputStream open( ASN1ObjectIdentifier eContentType, OutputStream out, boolean encapsulate) throws IOException { return open(eContentType, out, encapsulate, null); } /** * generate a signed object that for a CMS Signed Data * object using the given provider - if encapsulate is true a copy * of the message will be included in the signature. The content type * is set according to the OID represented by the string signedContentType. * @param eContentType OID for data to be signed. * @param out stream the CMS object is to be written to. * @param encapsulate true if data should be encapsulated. * @param dataOutputStream output stream to copy the data being signed to. */ public OutputStream open( ASN1ObjectIdentifier eContentType, OutputStream out, boolean encapsulate, OutputStream dataOutputStream) throws IOException { // TODO // if (_signerInfs.isEmpty()) // { // /* RFC 3852 5.2 // * "In the degenerate case where there are no signers, the // * EncapsulatedContentInfo value being "signed" is irrelevant. In this // * case, the content type within the EncapsulatedContentInfo value being // * "signed" MUST be id-data (as defined in section 4), and the content // * field of the EncapsulatedContentInfo value MUST be omitted." // */ // if (encapsulate) // { // throw new IllegalArgumentException("no signers, encapsulate must be false"); // } // if (!DATA.equals(eContentType)) // { // throw new IllegalArgumentException("no signers, eContentType must be id-data"); // } // } // // if (!DATA.equals(eContentType)) // { // /* RFC 3852 5.3 // * [The 'signedAttrs']... // * field is optional, but it MUST be present if the content type of // * the EncapsulatedContentInfo value being signed is not id-data. // */ // // TODO signedAttrs must be present for all signers // } // // ContentInfo // BERSequenceGenerator sGen = new BERSequenceGenerator(out); sGen.addObject(CMSObjectIdentifiers.signedData); // // Signed Data // BERSequenceGenerator sigGen = new BERSequenceGenerator(sGen.getRawOutputStream(), 0, true); sigGen.addObject(calculateVersion(eContentType)); ASN1EncodableVector digestAlgs = new ASN1EncodableVector(); // // add the precalculated SignerInfo digest algorithms. // for (Iterator it = _signers.iterator(); it.hasNext();) { SignerInformation signer = (SignerInformation)it.next(); digestAlgs.add(CMSSignedHelper.INSTANCE.fixAlgID(signer.getDigestAlgorithmID())); } // // add the new digests // for (Iterator it = signerGens.iterator(); it.hasNext();) { SignerInfoGenerator signerGen = (SignerInfoGenerator)it.next(); digestAlgs.add(signerGen.getDigestAlgorithm()); } sigGen.getRawOutputStream().write(new DERSet(digestAlgs).getEncoded()); BERSequenceGenerator eiGen = new BERSequenceGenerator(sigGen.getRawOutputStream()); eiGen.addObject(eContentType); // If encapsulating, add the data as an octet string in the sequence OutputStream encapStream = encapsulate ? CMSUtils.createBEROctetOutputStream(eiGen.getRawOutputStream(), 0, true, _bufferSize) : null; // Also send the data to 'dataOutputStream' if necessary OutputStream contentStream = CMSUtils.getSafeTeeOutputStream(dataOutputStream, encapStream); // Let all the signers see the data as it is written OutputStream sigStream = CMSUtils.attachSignersToOutputStream(signerGens, contentStream); return new CmsSignedDataOutputStream(sigStream, eContentType, sGen, sigGen, eiGen); } // TODO Make public? void generate( OutputStream out, String eContentType, boolean encapsulate, OutputStream dataOutputStream, CMSProcessable content) throws CMSException, IOException { OutputStream signedOut = open(out, eContentType, encapsulate, dataOutputStream); if (content != null) { content.write(signedOut); } signedOut.close(); } // RFC3852, section 5.1: // IF ((certificates is present) AND // (any certificates with a type of other are present)) OR // ((crls is present) AND // (any crls with a type of other are present)) // THEN version MUST be 5 // ELSE // IF (certificates is present) AND // (any version 2 attribute certificates are present) // THEN version MUST be 4 // ELSE // IF ((certificates is present) AND // (any version 1 attribute certificates are present)) OR // (any SignerInfo structures are version 3) OR // (encapContentInfo eContentType is other than id-data) // THEN version MUST be 3 // ELSE version MUST be 1 // private ASN1Integer calculateVersion( ASN1ObjectIdentifier contentOid) { boolean otherCert = false; boolean otherCrl = false; boolean attrCertV1Found = false; boolean attrCertV2Found = false; if (certs != null) { for (Iterator it = certs.iterator(); it.hasNext();) { Object obj = it.next(); if (obj instanceof ASN1TaggedObject) { ASN1TaggedObject tagged = (ASN1TaggedObject)obj; if (tagged.getTagNo() == 1) { attrCertV1Found = true; } else if (tagged.getTagNo() == 2) { attrCertV2Found = true; } else if (tagged.getTagNo() == 3) { otherCert = true; } } } } if (otherCert) { return new ASN1Integer(5); } if (crls != null) // no need to check if otherCert is true { for (Iterator it = crls.iterator(); it.hasNext();) { Object obj = it.next(); if (obj instanceof ASN1TaggedObject) { otherCrl = true; } } } if (otherCrl) { return new ASN1Integer(5); } if (attrCertV2Found) { return new ASN1Integer(4); } if (attrCertV1Found) { return new ASN1Integer(3); } if (checkForVersion3(_signers, signerGens)) { return new ASN1Integer(3); } if (!CMSObjectIdentifiers.data.equals(contentOid)) { return new ASN1Integer(3); } return new ASN1Integer(1); } private boolean checkForVersion3(List signerInfos, List signerInfoGens) { for (Iterator it = signerInfos.iterator(); it.hasNext();) { SignerInfo s = SignerInfo.getInstance(((SignerInformation)it.next()).toASN1Structure()); if (s.getVersion().getValue().intValue() == 3) { return true; } } for (Iterator it = signerInfoGens.iterator(); it.hasNext();) { SignerInfoGenerator s = (SignerInfoGenerator)it.next(); if (s.getGeneratedVersion().getValue().intValue() == 3) { return true; } } return false; } private class CmsSignedDataOutputStream extends OutputStream { private OutputStream _out; private ASN1ObjectIdentifier _contentOID; private BERSequenceGenerator _sGen; private BERSequenceGenerator _sigGen; private BERSequenceGenerator _eiGen; public CmsSignedDataOutputStream( OutputStream out, ASN1ObjectIdentifier contentOID, BERSequenceGenerator sGen, BERSequenceGenerator sigGen, BERSequenceGenerator eiGen) { _out = out; _contentOID = contentOID; _sGen = sGen; _sigGen = sigGen; _eiGen = eiGen; } public void write( int b) throws IOException { _out.write(b); } public void write( byte[] bytes, int off, int len) throws IOException { _out.write(bytes, off, len); } public void write( byte[] bytes) throws IOException { _out.write(bytes); } public void close() throws IOException { _out.close(); _eiGen.close(); digests.clear(); // clear the current preserved digest state if (certs.size() != 0) { ASN1Set certSet = CMSUtils.createBerSetFromList(certs); _sigGen.getRawOutputStream().write(new BERTaggedObject(false, 0, certSet).getEncoded()); } if (crls.size() != 0) { ASN1Set crlSet = CMSUtils.createBerSetFromList(crls); _sigGen.getRawOutputStream().write(new BERTaggedObject(false, 1, crlSet).getEncoded()); } // // collect all the SignerInfo objects // ASN1EncodableVector signerInfos = new ASN1EncodableVector(); // // add the generated SignerInfo objects // for (Iterator it = signerGens.iterator(); it.hasNext();) { SignerInfoGenerator sigGen = (SignerInfoGenerator)it.next(); try { signerInfos.add(sigGen.generate(_contentOID)); byte[] calculatedDigest = sigGen.getCalculatedDigest(); digests.put(sigGen.getDigestAlgorithm().getAlgorithm().getId(), calculatedDigest); } catch (CMSException e) { throw new CMSStreamException("exception generating signers: " + e.getMessage(), e); } } // // add the precalculated SignerInfo objects // { Iterator it = _signers.iterator(); while (it.hasNext()) { SignerInformation signer = (SignerInformation)it.next(); // TODO Verify the content type and calculated digest match the precalculated SignerInfo // if (!signer.getContentType().equals(_contentOID)) // { // // TODO The precalculated content type did not match - error? // } // // byte[] calculatedDigest = (byte[])_digests.get(signer.getDigestAlgOID()); // if (calculatedDigest == null) // { // // TODO We can't confirm this digest because we didn't calculate it - error? // } // else // { // if (!Arrays.areEqual(signer.getContentDigest(), calculatedDigest)) // { // // TODO The precalculated digest did not match - error? // } // } signerInfos.add(signer.toASN1Structure()); } } _sigGen.getRawOutputStream().write(new DERSet(signerInfos).getEncoded()); _sigGen.close(); _sGen.close(); } } } bouncycastle-1.49.orig/j2me/org/bouncycastle/cms/PasswordRecipientInformation.java0000644000175000017500000001121712103632343030047 0ustar ebourgebourgpackage org.bouncycastle.cms; import java.io.IOException; import java.util.HashMap; import java.util.Map; import org.bouncycastle.asn1.ASN1Encodable; import org.bouncycastle.asn1.cms.PasswordRecipientInfo; import org.bouncycastle.asn1.pkcs.PBKDF2Params; import org.bouncycastle.asn1.x509.AlgorithmIdentifier; import org.bouncycastle.crypto.PBEParametersGenerator; import org.bouncycastle.crypto.generators.PKCS5S2ParametersGenerator; import org.bouncycastle.crypto.params.KeyParameter; import org.bouncycastle.util.Integers; /** * the RecipientInfo class for a recipient who has been sent a message * encrypted using a password. */ public class PasswordRecipientInformation extends RecipientInformation { static Map KEYSIZES = new HashMap(); static Map BLOCKSIZES = new HashMap(); static { BLOCKSIZES.put(CMSAlgorithm.DES_EDE3_CBC, Integers.valueOf(8)); BLOCKSIZES.put(CMSAlgorithm.AES128_CBC, Integers.valueOf(16)); BLOCKSIZES.put(CMSAlgorithm.AES192_CBC, Integers.valueOf(16)); BLOCKSIZES.put(CMSAlgorithm.AES256_CBC, Integers.valueOf(16)); KEYSIZES.put(CMSAlgorithm.DES_EDE3_CBC, Integers.valueOf(192)); KEYSIZES.put(CMSAlgorithm.AES128_CBC, Integers.valueOf(128)); KEYSIZES.put(CMSAlgorithm.AES192_CBC, Integers.valueOf(192)); KEYSIZES.put(CMSAlgorithm.AES256_CBC, Integers.valueOf(256)); } private PasswordRecipientInfo info; PasswordRecipientInformation( PasswordRecipientInfo info, AlgorithmIdentifier messageAlgorithm, CMSSecureReadable secureReadable, AuthAttributesProvider additionalData) { super(info.getKeyEncryptionAlgorithm(), messageAlgorithm, secureReadable, additionalData); this.info = info; this.rid = new PasswordRecipientId(); } /** * return the object identifier for the key derivation algorithm, or null * if there is none present. * * @return OID for key derivation algorithm, if present. */ public String getKeyDerivationAlgOID() { if (info.getKeyDerivationAlgorithm() != null) { return info.getKeyDerivationAlgorithm().getAlgorithm().getId(); } return null; } /** * return the ASN.1 encoded key derivation algorithm parameters, or null if * there aren't any. * @return ASN.1 encoding of key derivation algorithm parameters. */ public byte[] getKeyDerivationAlgParams() { try { if (info.getKeyDerivationAlgorithm() != null) { ASN1Encodable params = info.getKeyDerivationAlgorithm().getParameters(); if (params != null) { return params.toASN1Primitive().getEncoded(); } } return null; } catch (Exception e) { throw new RuntimeException("exception getting encryption parameters " + e); } } /** * Return the key derivation algorithm details for the key in this recipient. * * @return AlgorithmIdentifier representing the key derivation algorithm. */ public AlgorithmIdentifier getKeyDerivationAlgorithm() { return info.getKeyDerivationAlgorithm(); } protected RecipientOperator getRecipientOperator(Recipient recipient) throws CMSException, IOException { PasswordRecipient pbeRecipient = (PasswordRecipient)recipient; AlgorithmIdentifier kekAlg = AlgorithmIdentifier.getInstance(info.getKeyEncryptionAlgorithm()); AlgorithmIdentifier kekAlgParams = AlgorithmIdentifier.getInstance(kekAlg.getParameters()); byte[] passwordBytes = getPasswordBytes(pbeRecipient.getPasswordConversionScheme(), pbeRecipient.getPassword()); PBKDF2Params params = PBKDF2Params.getInstance(info.getKeyDerivationAlgorithm().getParameters()); PKCS5S2ParametersGenerator gen = new PKCS5S2ParametersGenerator(); gen.init(passwordBytes, params.getSalt(), params.getIterationCount().intValue()); int keySize = ((Integer)KEYSIZES.get(kekAlgParams.getAlgorithm())).intValue(); byte[] derivedKey = ((KeyParameter)gen.generateDerivedParameters(keySize)).getKey(); return pbeRecipient.getRecipientOperator(kekAlgParams, messageAlgorithm, derivedKey, info.getEncryptedKey().getOctets()); } protected byte[] getPasswordBytes(int scheme, char[] password) { if (scheme == PasswordRecipient.PKCS5_SCHEME2) { return PBEParametersGenerator.PKCS5PasswordToBytes(password); } return PBEParametersGenerator.PKCS5PasswordToUTF8Bytes(password); } } bouncycastle-1.49.orig/j2me/org/bouncycastle/cms/test/0000755000175000017500000000000012152033550022305 5ustar ebourgebourgbouncycastle-1.49.orig/j2me/org/bouncycastle/cms/test/BcEnvelopedDataTest.java0000644000175000017500000000751012105426345027001 0ustar ebourgebourgpackage org.bouncycastle.cms.test; import java.util.Collection; import java.util.Iterator; import org.bouncycastle.asn1.nist.NISTObjectIdentifiers; import org.bouncycastle.cert.X509CertificateHolder; import org.bouncycastle.cms.CMSEnvelopedData; import org.bouncycastle.cms.CMSEnvelopedDataGenerator; import org.bouncycastle.cms.CMSProcessableByteArray; import org.bouncycastle.cms.RecipientInformation; import org.bouncycastle.cms.RecipientInformationStore; import org.bouncycastle.cms.bc.BcCMSContentEncryptorBuilder; import org.bouncycastle.cms.bc.BcRSAKeyTransEnvelopedRecipient; import org.bouncycastle.cms.bc.BcRSAKeyTransRecipientInfoGenerator; import org.bouncycastle.crypto.AsymmetricCipherKeyPair; import org.bouncycastle.crypto.params.AsymmetricKeyParameter; import org.bouncycastle.util.Arrays; import org.bouncycastle.util.test.SimpleTest; public class BcEnvelopedDataTest extends SimpleTest { private static String _origDN; private static AsymmetricCipherKeyPair _origKP; private static X509CertificateHolder _origCert; private static String _signDN; private static AsymmetricCipherKeyPair _signKP; private static X509CertificateHolder _signCert; private static String _reciDN; private static String _reciDN2; private static AsymmetricCipherKeyPair _reciKP; private static X509CertificateHolder _reciCert; private static boolean _initialised = false; public String getName() { return "BcEnvelopedData"; } private void init() throws Exception { if (!_initialised) { _initialised = true; _origDN = "O=Bouncy Castle, C=AU"; _origKP = CMSTestUtil.makeKeyPair(); _origCert = CMSTestUtil.makeCertificate(_origKP, _origDN, _origKP, _origDN); _signDN = "CN=Bob, OU=Sales, O=Bouncy Castle, C=AU"; _signKP = CMSTestUtil.makeKeyPair(); _signCert = CMSTestUtil.makeCertificate(_signKP, _signDN, _origKP, _origDN); _reciDN = "CN=Doug, OU=Sales, O=Bouncy Castle, C=AU"; _reciDN2 = "CN=Fred, OU=Sales, O=Bouncy Castle, C=AU"; _reciKP = CMSTestUtil.makeKeyPair(); _reciCert = CMSTestUtil.makeCertificate(_reciKP, _reciDN, _signKP, _signDN); } } private void testKeyTransLight128RC4() throws Exception { byte[] data = "WallaWallaBouncyCastle".getBytes(); CMSEnvelopedDataGenerator edGen = new CMSEnvelopedDataGenerator(); edGen.addRecipientInfoGenerator(new BcRSAKeyTransRecipientInfoGenerator(_reciCert)); CMSEnvelopedData ed = edGen.generate( new CMSProcessableByteArray(data), new BcCMSContentEncryptorBuilder(NISTObjectIdentifiers.id_aes128_CBC).build()); RecipientInformationStore recipients = ed.getRecipientInfos(); if (!ed.getEncryptionAlgOID().equals(NISTObjectIdentifiers.id_aes128_CBC.getId())) { fail("enc oid mismatch"); } Collection c = recipients.getRecipients(); Iterator it = c.iterator(); if (it.hasNext()) { RecipientInformation recipient = (RecipientInformation)it.next(); byte[] recData = recipient.getContent(new BcRSAKeyTransEnvelopedRecipient((AsymmetricKeyParameter)_reciKP.getPrivate())); if (!Arrays.areEqual(data, recData)) { fail("decryption failed"); } } else { fail("no recipient found"); } } public void performTest() throws Exception { init(); testKeyTransLight128RC4(); } public static void main( String[] args) { runTest(new BcEnvelopedDataTest()); } } bouncycastle-1.49.orig/j2me/org/bouncycastle/cms/test/CMSTestUtil.java0000644000175000017500000002235311732266435025312 0ustar ebourgebourgpackage org.bouncycastle.cms.test; import java.io.IOException; import java.math.BigInteger; import java.security.SecureRandom; import java.util.Date; import org.bouncycastle.asn1.DERNull; import org.bouncycastle.asn1.pkcs.PKCSObjectIdentifiers; import org.bouncycastle.asn1.pkcs.RSAPublicKey; import org.bouncycastle.asn1.x500.X500Name; import org.bouncycastle.asn1.x509.AlgorithmIdentifier; import org.bouncycastle.asn1.x509.BasicConstraints; import org.bouncycastle.asn1.x509.SubjectPublicKeyInfo; import org.bouncycastle.asn1.x509.X509Extension; import org.bouncycastle.cert.X509AttributeCertificateHolder; import org.bouncycastle.cert.X509CertificateHolder; import org.bouncycastle.cert.X509v1CertificateBuilder; import org.bouncycastle.cert.X509v3CertificateBuilder; import org.bouncycastle.crypto.AsymmetricCipherKeyPair; import org.bouncycastle.crypto.generators.RSAKeyPairGenerator; import org.bouncycastle.crypto.params.AsymmetricKeyParameter; import org.bouncycastle.crypto.params.RSAKeyGenerationParameters; import org.bouncycastle.crypto.params.RSAKeyParameters; import org.bouncycastle.operator.ContentSigner; import org.bouncycastle.operator.DefaultDigestAlgorithmIdentifierFinder; import org.bouncycastle.operator.DefaultSignatureAlgorithmIdentifierFinder; import org.bouncycastle.operator.OperatorCreationException; import org.bouncycastle.operator.bc.BcRSAContentSignerBuilder; import org.bouncycastle.util.encoders.Base64; public class CMSTestUtil { public static SecureRandom rand; public static RSAKeyPairGenerator kpg; public static BigInteger serialNumber; public static final boolean DEBUG = true; private static byte[] attrCert = Base64.decode( "MIIHQDCCBqkCAQEwgZChgY2kgYowgYcxHDAaBgkqhkiG9w0BCQEWDW1sb3JjaEB2" + "dC5lZHUxHjAcBgNVBAMTFU1hcmt1cyBMb3JjaCAobWxvcmNoKTEbMBkGA1UECxMS" + "VmlyZ2luaWEgVGVjaCBVc2VyMRAwDgYDVQQLEwdDbGFzcyAyMQswCQYDVQQKEwJ2" + "dDELMAkGA1UEBhMCVVMwgYmkgYYwgYMxGzAZBgkqhkiG9w0BCQEWDHNzaGFoQHZ0" + "LmVkdTEbMBkGA1UEAxMSU3VtaXQgU2hhaCAoc3NoYWgpMRswGQYDVQQLExJWaXJn" + "aW5pYSBUZWNoIFVzZXIxEDAOBgNVBAsTB0NsYXNzIDExCzAJBgNVBAoTAnZ0MQsw" + "CQYDVQQGEwJVUzANBgkqhkiG9w0BAQQFAAIBBTAiGA8yMDAzMDcxODE2MDgwMloY" + "DzIwMDMwNzI1MTYwODAyWjCCBU0wggVJBgorBgEEAbRoCAEBMYIFORaCBTU8UnVs" + "ZSBSdWxlSWQ9IkZpbGUtUHJpdmlsZWdlLVJ1bGUiIEVmZmVjdD0iUGVybWl0Ij4K" + "IDxUYXJnZXQ+CiAgPFN1YmplY3RzPgogICA8U3ViamVjdD4KICAgIDxTdWJqZWN0" + "TWF0Y2ggTWF0Y2hJZD0idXJuOm9hc2lzOm5hbWVzOnRjOnhhY21sOjEuMDpmdW5j" + "dGlvbjpzdHJpbmctZXF1YWwiPgogICAgIDxBdHRyaWJ1dGVWYWx1ZSBEYXRhVHlw" + "ZT0iaHR0cDovL3d3dy53My5vcmcvMjAwMS9YTUxTY2hlbWEjc3RyaW5nIj4KICAg" + "ICAgIENOPU1hcmt1cyBMb3JjaDwvQXR0cmlidXRlVmFsdWU+CiAgICAgPFN1Ympl" + "Y3RBdHRyaWJ1dGVEZXNpZ25hdG9yIEF0dHJpYnV0ZUlkPSJ1cm46b2FzaXM6bmFt" + "ZXM6dGM6eGFjbWw6MS4wOnN1YmplY3Q6c3ViamVjdC1pZCIgRGF0YVR5cGU9Imh0" + "dHA6Ly93d3cudzMub3JnLzIwMDEvWE1MU2NoZW1hI3N0cmluZyIgLz4gCiAgICA8" + "L1N1YmplY3RNYXRjaD4KICAgPC9TdWJqZWN0PgogIDwvU3ViamVjdHM+CiAgPFJl" + "c291cmNlcz4KICAgPFJlc291cmNlPgogICAgPFJlc291cmNlTWF0Y2ggTWF0Y2hJ" + "ZD0idXJuOm9hc2lzOm5hbWVzOnRjOnhhY21sOjEuMDpmdW5jdGlvbjpzdHJpbmct" + "ZXF1YWwiPgogICAgIDxBdHRyaWJ1dGVWYWx1ZSBEYXRhVHlwZT0iaHR0cDovL3d3" + "dy53My5vcmcvMjAwMS9YTUxTY2hlbWEjYW55VVJJIj4KICAgICAgaHR0cDovL3p1" + "bmkuY3MudnQuZWR1PC9BdHRyaWJ1dGVWYWx1ZT4KICAgICA8UmVzb3VyY2VBdHRy" + "aWJ1dGVEZXNpZ25hdG9yIEF0dHJpYnV0ZUlkPSJ1cm46b2FzaXM6bmFtZXM6dGM6" + "eGFjbWw6MS4wOnJlc291cmNlOnJlc291cmNlLWlkIiBEYXRhVHlwZT0iaHR0cDov" + "L3d3dy53My5vcmcvMjAwMS9YTUxTY2hlbWEjYW55VVJJIiAvPiAKICAgIDwvUmVz" + "b3VyY2VNYXRjaD4KICAgPC9SZXNvdXJjZT4KICA8L1Jlc291cmNlcz4KICA8QWN0" + "aW9ucz4KICAgPEFjdGlvbj4KICAgIDxBY3Rpb25NYXRjaCBNYXRjaElkPSJ1cm46" + "b2FzaXM6bmFtZXM6dGM6eGFjbWw6MS4wOmZ1bmN0aW9uOnN0cmluZy1lcXVhbCI+" + "CiAgICAgPEF0dHJpYnV0ZVZhbHVlIERhdGFUeXBlPSJodHRwOi8vd3d3LnczLm9y" + "Zy8yMDAxL1hNTFNjaGVtYSNzdHJpbmciPgpEZWxlZ2F0ZSBBY2Nlc3MgICAgIDwv" + "QXR0cmlidXRlVmFsdWU+CgkgIDxBY3Rpb25BdHRyaWJ1dGVEZXNpZ25hdG9yIEF0" + "dHJpYnV0ZUlkPSJ1cm46b2FzaXM6bmFtZXM6dGM6eGFjbWw6MS4wOmFjdGlvbjph" + "Y3Rpb24taWQiIERhdGFUeXBlPSJodHRwOi8vd3d3LnczLm9yZy8yMDAxL1hNTFNj" + "aGVtYSNzdHJpbmciIC8+IAogICAgPC9BY3Rpb25NYXRjaD4KICAgPC9BY3Rpb24+" + "CiAgPC9BY3Rpb25zPgogPC9UYXJnZXQ+CjwvUnVsZT4KMA0GCSqGSIb3DQEBBAUA" + "A4GBAGiJSM48XsY90HlYxGmGVSmNR6ZW2As+bot3KAfiCIkUIOAqhcphBS23egTr" + "6asYwy151HshbPNYz+Cgeqs45KkVzh7bL/0e1r8sDVIaaGIkjHK3CqBABnfSayr3" + "Rd1yBoDdEv8Qb+3eEPH6ab9021AsLEnJ6LWTmybbOpMNZ3tv"); static { try { rand = new SecureRandom(); kpg = new RSAKeyPairGenerator(); kpg.init(new RSAKeyGenerationParameters(BigInteger.valueOf(0x11), new SecureRandom(), 1024, 25)); serialNumber = new BigInteger("1"); } catch (Exception ex) { throw new RuntimeException(ex.toString()); } } public static String dumpBase64( byte[] data) { StringBuffer buf = new StringBuffer(); data = Base64.encode(data); for (int i = 0; i < data.length; i += 64) { if (i + 64 < data.length) { buf.append(new String(data, i, 64)); } else { buf.append(new String(data, i, data.length - i)); } buf.append('\n'); } return buf.toString(); } public static X509AttributeCertificateHolder getAttributeCertificate() throws Exception { return new X509AttributeCertificateHolder(CMSTestUtil.attrCert); } public static AsymmetricCipherKeyPair makeKeyPair() { return kpg.generateKeyPair(); } public static X509CertificateHolder makeCertificate(AsymmetricCipherKeyPair _subKP, String _subDN, AsymmetricCipherKeyPair _issKP, String _issDN) throws IOException, OperatorCreationException { return makeCertificate(_subKP, _subDN, _issKP, _issDN, false); } public static X509CertificateHolder makeCACertificate(AsymmetricCipherKeyPair _subKP, String _subDN, AsymmetricCipherKeyPair _issKP, String _issDN) throws IOException, OperatorCreationException { return makeCertificate(_subKP, _subDN, _issKP, _issDN, true); } public static X509CertificateHolder makeV1Certificate(AsymmetricCipherKeyPair subKP, String _subDN, AsymmetricCipherKeyPair issKP, String _issDN) throws IOException, OperatorCreationException { RSAKeyParameters lwPubKey = (RSAKeyParameters)subKP.getPublic(); X509v1CertificateBuilder v1CertGen = new X509v1CertificateBuilder( new X500Name(_issDN), allocateSerialNumber(), new Date(System.currentTimeMillis()), new Date(System.currentTimeMillis() + (1000L * 60 * 60 * 24 * 100)), new X500Name(_subDN), new SubjectPublicKeyInfo(new AlgorithmIdentifier(PKCSObjectIdentifiers.rsaEncryption, DERNull.INSTANCE), new RSAPublicKey(lwPubKey.getModulus(), lwPubKey.getExponent())) ); AlgorithmIdentifier sigAlgId = new DefaultSignatureAlgorithmIdentifierFinder().find("SHA1WithRSAEncryption"); AlgorithmIdentifier digAlgId = new DefaultDigestAlgorithmIdentifierFinder().find(sigAlgId); ContentSigner sigGen = new BcRSAContentSignerBuilder(sigAlgId, digAlgId).build((AsymmetricKeyParameter)issKP.getPrivate()); return v1CertGen.build(sigGen); } public static X509CertificateHolder makeCertificate(AsymmetricCipherKeyPair subKP, String _subDN, AsymmetricCipherKeyPair issKP, String _issDN, boolean _ca) throws IOException, OperatorCreationException { RSAKeyParameters lwPubKey = (RSAKeyParameters)subKP.getPublic(); X509v3CertificateBuilder v3CertGen = new X509v3CertificateBuilder( new X500Name(_issDN), allocateSerialNumber(), new Date(System.currentTimeMillis()), new Date(System.currentTimeMillis() + (1000L * 60 * 60 * 24 * 100)), new X500Name(_subDN), new SubjectPublicKeyInfo(new AlgorithmIdentifier(PKCSObjectIdentifiers.rsaEncryption, DERNull.INSTANCE), new RSAPublicKey(lwPubKey.getModulus(), lwPubKey.getExponent())) ); AlgorithmIdentifier sigAlgId = new DefaultSignatureAlgorithmIdentifierFinder().find("SHA1WithRSAEncryption"); AlgorithmIdentifier digAlgId = new DefaultDigestAlgorithmIdentifierFinder().find(sigAlgId); ContentSigner sigGen = new BcRSAContentSignerBuilder(sigAlgId, digAlgId).build((AsymmetricKeyParameter)issKP.getPrivate()); v3CertGen.addExtension( X509Extension.basicConstraints, false, new BasicConstraints(_ca)); return v3CertGen.build(sigGen); } private static BigInteger allocateSerialNumber() { BigInteger _tmp = serialNumber; serialNumber = serialNumber.add(BigInteger.ONE); return _tmp; } } bouncycastle-1.49.orig/j2me/org/bouncycastle/cms/test/BcSignedDataTest.java0000644000175000017500000007421711732267205026304 0ustar ebourgebourgpackage org.bouncycastle.cms.test; import java.util.ArrayList; import java.util.Collection; import java.util.Iterator; import java.util.List; import org.bouncycastle.asn1.ASN1EncodableVector; import org.bouncycastle.asn1.DEROctetString; import org.bouncycastle.asn1.DERSet; import org.bouncycastle.asn1.cms.Attribute; import org.bouncycastle.asn1.cms.AttributeTable; import org.bouncycastle.asn1.cms.CMSAttributes; import org.bouncycastle.asn1.x509.AlgorithmIdentifier; import org.bouncycastle.cert.X509CertificateHolder; import org.bouncycastle.cms.CMSAbsentContent; import org.bouncycastle.cms.CMSProcessableByteArray; import org.bouncycastle.cms.CMSSignedData; import org.bouncycastle.cms.CMSSignedDataGenerator; import org.bouncycastle.cms.CMSTypedData; import org.bouncycastle.cms.DefaultCMSSignatureAlgorithmNameGenerator; import org.bouncycastle.cms.DefaultSignedAttributeTableGenerator; import org.bouncycastle.cms.SignerInfoGeneratorBuilder; import org.bouncycastle.cms.SignerInformation; import org.bouncycastle.cms.SignerInformationStore; import org.bouncycastle.cms.bc.BcRSASignerInfoVerifierBuilder; import org.bouncycastle.crypto.AsymmetricCipherKeyPair; import org.bouncycastle.crypto.Digest; import org.bouncycastle.crypto.digests.SHA1Digest; import org.bouncycastle.crypto.params.AsymmetricKeyParameter; import org.bouncycastle.operator.DefaultDigestAlgorithmIdentifierFinder; import org.bouncycastle.operator.DefaultSignatureAlgorithmIdentifierFinder; import org.bouncycastle.operator.bc.BcContentSignerBuilder; import org.bouncycastle.operator.bc.BcDigestCalculatorProvider; import org.bouncycastle.operator.bc.BcRSAContentSignerBuilder; import org.bouncycastle.util.Arrays; import org.bouncycastle.util.CollectionStore; import org.bouncycastle.util.Store; import org.bouncycastle.util.encoders.Base64; import org.bouncycastle.util.test.SimpleTest; public class BcSignedDataTest extends SimpleTest { private static String _origDN; private static AsymmetricCipherKeyPair _origKP; private static X509CertificateHolder _origCert; private static String _signDN; private static AsymmetricCipherKeyPair _signKP; private static X509CertificateHolder _signCert; private static boolean _initialised = false; private byte[] disorderedMessage = Base64.decode( "SU9fc3RkaW5fdXNlZABfX2xpYmNfc3RhcnRfbWFpbgBnZXRob3N0aWQAX19n" + "bW9uX3M="); private byte[] disorderedSet = Base64.decode( "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" + "gQBpSRdnDb6AcNVaXSmGo6+kVPIBhot1LzJOGaPyDNpGXxd7LV4tMBF1U7gr" + "4k1g9BO6YiMWvw9uiTZmn0CfV8+k4fWEuG/nmafRoGIuay2f+ILuT+C0rnp1" + "4FgMsEhuVNJJAmb12QV0PZII+UneyhAneZuQQzVUkTcVgYxogxdSOzCCAlUw" + "ggHBoAMCAQICBACdekowCgYGKyQDAwECBQAwbzELMAkGA1UEBhMCREUxPTA7" + "BgNVBAoUNFJlZ3VsaWVydW5nc2JlaMhvcmRlIGbIdXIgVGVsZWtvbW11bmlr" + "YXRpb24gdW5kIFBvc3QxITAMBgcCggYBCgcUEwExMBEGA1UEAxQKNlItQ2Eg" + "MTpQTjAiGA8yMDAxMDIwMTEzNDcwN1oYDzIwMDUwMzIyMDg1NTUxWjBvMQsw" + "CQYDVQQGEwJERTE9MDsGA1UEChQ0UmVndWxpZXJ1bmdzYmVoyG9yZGUgZsh1" + "ciBUZWxla29tbXVuaWthdGlvbiB1bmQgUG9zdDEhMAwGBwKCBgEKBxQTATEw" + "EQYDVQQDFAo1Ui1DQSAxOlBOMIGhMA0GCSqGSIb3DQEBAQUAA4GPADCBiwKB" + "gQCKHkFTJx8GmoqFTxEOxpK9XkC3NZ5dBEKiUv0Ife3QMqeGMoCUnyJxwW0k" + "2/53duHxtv2yHSZpFKjrjvE/uGwdOMqBMTjMzkFg19e9JPv061wyADOucOIa" + "NAgha/zFt9XUyrHF21knKCvDNExv2MYIAagkTKajLMAw0bu1J0FadQIFAMAA" + "AAEwCgYGKyQDAwECBQADgYEAV1yTi+2gyB7sUhn4PXmi/tmBxAfe5oBjDW8m" + "gxtfudxKGZ6l/FUPNcrSc5oqBYxKWtLmf3XX87LcblYsch617jtNTkMzhx9e" + "qxiD02ufcrxz2EVt0Akdqiz8mdVeqp3oLcNU/IttpSrcA91CAnoUXtDZYwb/" + "gdQ4FI9l3+qo/0UwggJVMIIBwaADAgECAgQAxIymMAoGBiskAwMBAgUAMG8x" + "CzAJBgNVBAYTAkRFMT0wOwYDVQQKFDRSZWd1bGllcnVuZ3NiZWjIb3JkZSBm" + "yHVyIFRlbGVrb21tdW5pa2F0aW9uIHVuZCBQb3N0MSEwDAYHAoIGAQoHFBMB" + "MTARBgNVBAMUCjZSLUNhIDE6UE4wIhgPMjAwMTEwMTUxMzMxNThaGA8yMDA1" + "MDYwMTA5NTIxN1owbzELMAkGA1UEBhMCREUxPTA7BgNVBAoUNFJlZ3VsaWVy" + "dW5nc2JlaMhvcmRlIGbIdXIgVGVsZWtvbW11bmlrYXRpb24gdW5kIFBvc3Qx" + "ITAMBgcCggYBCgcUEwExMBEGA1UEAxQKN1ItQ0EgMTpQTjCBoTANBgkqhkiG" + "9w0BAQEFAAOBjwAwgYsCgYEAiokD/j6lEP4FexF356OpU5teUpGGfUKjIrFX" + "BHc79G0TUzgVxqMoN1PWnWktQvKo8ETaugxLkP9/zfX3aAQzDW4Zki6x6GDq" + "fy09Agk+RJvhfbbIzRkV4sBBco0n73x7TfG/9NTgVr/96U+I+z/1j30aboM6" + "9OkLEhjxAr0/GbsCBQDAAAABMAoGBiskAwMBAgUAA4GBAHWRqRixt+EuqHhR" + "K1kIxKGZL2vZuakYV0R24Gv/0ZR52FE4ECr+I49o8FP1qiGSwnXB0SwjuH2S" + "iGiSJi+iH/MeY85IHwW1P5e+bOMvEOFhZhQXQixOD7totIoFtdyaj1XGYRef" + "0f2cPOjNJorXHGV8wuBk+/j++sxbd/Net3FtMIICVTCCAcGgAwIBAgIEAMSM" + "pzAKBgYrJAMDAQIFADBvMQswCQYDVQQGEwJERTE9MDsGA1UEChQ0UmVndWxp" + "ZXJ1bmdzYmVoyG9yZGUgZsh1ciBUZWxla29tbXVuaWthdGlvbiB1bmQgUG9z" + "dDEhMAwGBwKCBgEKBxQTATEwEQYDVQQDFAo3Ui1DQSAxOlBOMCIYDzIwMDEx" + "MDE1MTMzNDE0WhgPMjAwNTA2MDEwOTUyMTdaMG8xCzAJBgNVBAYTAkRFMT0w" + "OwYDVQQKFDRSZWd1bGllcnVuZ3NiZWjIb3JkZSBmyHVyIFRlbGVrb21tdW5p" + "a2F0aW9uIHVuZCBQb3N0MSEwDAYHAoIGAQoHFBMBMTARBgNVBAMUCjZSLUNh" + "IDE6UE4wgaEwDQYJKoZIhvcNAQEBBQADgY8AMIGLAoGBAIOiqxUkzVyqnvth" + "ihnltsE5m1Xn5TZKeR/2MQPStc5hJ+V4yptEtIx+Fn5rOoqT5VEVWhcE35wd" + "bPvgJyQFn5msmhPQT/6XSGOlrWRoFummXN9lQzAjCj1sgTcmoLCVQ5s5WpCA" + "OXFwVWu16qndz3sPItn3jJ0F3Kh3w79NglvPAgUAwAAAATAKBgYrJAMDAQIF" + "AAOBgQBi5W96UVDoNIRkCncqr1LLG9vF9SGBIkvFpLDIIbcvp+CXhlvsdCJl" + "0pt2QEPSDl4cmpOet+CxJTdTuMeBNXxhb7Dvualog69w/+K2JbPhZYxuVFZs" + "Zh5BkPn2FnbNu3YbJhE60aIkikr72J4XZsI5DxpZCGh6xyV/YPRdKSljFjCC" + "AlQwggHAoAMCAQICAwyDqzAKBgYrJAMDAQIFADBvMQswCQYDVQQGEwJERTE9" + "MDsGA1UEChQ0UmVndWxpZXJ1bmdzYmVoyG9yZGUgZsh1ciBUZWxla29tbXVu" + "aWthdGlvbiB1bmQgUG9zdDEhMAwGBwKCBgEKBxQTATEwEQYDVQQDFAo1Ui1D" + "QSAxOlBOMCIYDzIwMDAwMzIyMDk0MTI3WhgPMjAwNDAxMjExNjA0NTNaMG8x" + "CzAJBgNVBAYTAkRFMT0wOwYDVQQKFDRSZWd1bGllcnVuZ3NiZWjIb3JkZSBm" + "yHVyIFRlbGVrb21tdW5pa2F0aW9uIHVuZCBQb3N0MSEwDAYHAoIGAQoHFBMB" + "MTARBgNVBAMUCjRSLUNBIDE6UE4wgaEwDQYJKoZIhvcNAQEBBQADgY8AMIGL" + "AoGBAI8x26tmrFJanlm100B7KGlRemCD1R93PwdnG7svRyf5ZxOsdGrDszNg" + "xg6ouO8ZHQMT3NC2dH8TvO65Js+8bIyTm51azF6clEg0qeWNMKiiXbBXa+ph" + "hTkGbXiLYvACZ6/MTJMJ1lcrjpRF7BXtYeYMcEF6znD4pxOqrtbf9z5hAgUA" + "wAAAATAKBgYrJAMDAQIFAAOBgQB99BjSKlGPbMLQAgXlvA9jUsDNhpnVm3a1" + "YkfxSqS/dbQlYkbOKvCxkPGA9NBxisBM8l1zFynVjJoy++aysRmcnLY/sHaz" + "23BF2iU7WERy18H3lMBfYB6sXkfYiZtvQZcWaO48m73ZBySuiV3iXpb2wgs/" + "Cs20iqroAWxwq/W/9jCCAlMwggG/oAMCAQICBDsFZ9UwCgYGKyQDAwECBQAw" + "bzELMAkGA1UEBhMCREUxITAMBgcCggYBCgcUEwExMBEGA1UEAxQKNFItQ0Eg" + "MTpQTjE9MDsGA1UEChQ0UmVndWxpZXJ1bmdzYmVoyG9yZGUgZsh1ciBUZWxl" + "a29tbXVuaWthdGlvbiB1bmQgUG9zdDAiGA8xOTk5MDEyMTE3MzUzNFoYDzIw" + "MDQwMTIxMTYwMDAyWjBvMQswCQYDVQQGEwJERTE9MDsGA1UEChQ0UmVndWxp" + "ZXJ1bmdzYmVoyG9yZGUgZsh1ciBUZWxla29tbXVuaWthdGlvbiB1bmQgUG9z" + "dDEhMAwGBwKCBgEKBxQTATEwEQYDVQQDFAozUi1DQSAxOlBOMIGfMA0GCSqG" + "SIb3DQEBAQUAA4GNADCBiQKBgI4B557mbKQg/AqWBXNJhaT/6lwV93HUl4U8" + "u35udLq2+u9phns1WZkdM3gDfEpL002PeLfHr1ID/96dDYf04lAXQfombils" + "of1C1k32xOvxjlcrDOuPEMxz9/HDAQZA5MjmmYHAIulGI8Qg4Tc7ERRtg/hd" + "0QX0/zoOeXoDSEOBAgTAAAABMAoGBiskAwMBAgUAA4GBAIyzwfT3keHI/n2P" + "LrarRJv96mCohmDZNpUQdZTVjGu5VQjVJwk3hpagU0o/t/FkdzAjOdfEw8Ql" + "3WXhfIbNLv1YafMm2eWSdeYbLcbB5yJ1od+SYyf9+tm7cwfDAcr22jNRBqx8" + "wkWKtKDjWKkevaSdy99sAI8jebHtWz7jzydKMIID9TCCA16gAwIBAgICbMcw" + "DQYJKoZIhvcNAQEFBQAwSzELMAkGA1UEBhMCREUxEjAQBgNVBAoUCVNpZ250" + "cnVzdDEoMAwGBwKCBgEKBxQTATEwGAYDVQQDFBFDQSBTSUdOVFJVU1QgMTpQ" + "TjAeFw0wNDA3MzAxMzAyNDZaFw0wNzA3MzAxMzAyNDZaMDwxETAPBgNVBAMM" + "CFlhY29tOlBOMQ4wDAYDVQRBDAVZYWNvbTELMAkGA1UEBhMCREUxCjAIBgNV" + "BAUTATEwgZ8wDQYJKoZIhvcNAQEBBQADgY0AMIGJAoGBAIWzLlYLQApocXIp" + "pgCCpkkOUVLgcLYKeOd6/bXAnI2dTHQqT2bv7qzfUnYvOqiNgYdF13pOYtKg" + "XwXMTNFL4ZOI6GoBdNs9TQiZ7KEWnqnr2945HYx7UpgTBclbOK/wGHuCdcwO" + "x7juZs1ZQPFG0Lv8RoiV9s6HP7POqh1sO0P/AgMBAAGjggH1MIIB8TCBnAYD" + "VR0jBIGUMIGRgBQcZzNghfnXoXRm8h1+VITC5caNRqFzpHEwbzELMAkGA1UE" + "BhMCREUxPTA7BgNVBAoUNFJlZ3VsaWVydW5nc2JlaMhvcmRlIGbIdXIgVGVs" + "ZWtvbW11bmlrYXRpb24gdW5kIFBvc3QxITAMBgcCggYBCgcUEwExMBEGA1UE" + "AxQKNVItQ0EgMTpQToIEALs8rjAdBgNVHQ4EFgQU2e5KAzkVuKaM9I5heXkz" + "bcAIuR8wDgYDVR0PAQH/BAQDAgZAMBIGA1UdIAQLMAkwBwYFKyQIAQEwfwYD" + "VR0fBHgwdjB0oCygKoYobGRhcDovL2Rpci5zaWdudHJ1c3QuZGUvbz1TaWdu" + "dHJ1c3QsYz1kZaJEpEIwQDEdMBsGA1UEAxMUQ1JMU2lnblNpZ250cnVzdDE6" + "UE4xEjAQBgNVBAoTCVNpZ250cnVzdDELMAkGA1UEBhMCREUwYgYIKwYBBQUH" + "AQEEVjBUMFIGCCsGAQUFBzABhkZodHRwOi8vZGlyLnNpZ250cnVzdC5kZS9T" + "aWdudHJ1c3QvT0NTUC9zZXJ2bGV0L2h0dHBHYXRld2F5LlBvc3RIYW5kbGVy" + "MBgGCCsGAQUFBwEDBAwwCjAIBgYEAI5GAQEwDgYHAoIGAQoMAAQDAQH/MA0G" + "CSqGSIb3DQEBBQUAA4GBAHn1m3GcoyD5GBkKUY/OdtD6Sj38LYqYCF+qDbJR" + "6pqUBjY2wsvXepUppEler+stH8mwpDDSJXrJyuzf7xroDs4dkLl+Rs2x+2tg" + "BjU+ABkBDMsym2WpwgA8LCdymmXmjdv9tULxY+ec2pjSEzql6nEZNEfrU8nt" + "ZCSCavgqW4TtMYIBejCCAXYCAQEwUTBLMQswCQYDVQQGEwJERTESMBAGA1UE" + "ChQJU2lnbnRydXN0MSgwDAYHAoIGAQoHFBMBMTAYBgNVBAMUEUNBIFNJR05U" + "UlVTVCAxOlBOAgJsxzAJBgUrDgMCGgUAoIGAMBgGCSqGSIb3DQEJAzELBgkq" + "hkiG9w0BBwEwIwYJKoZIhvcNAQkEMRYEFIYfhPoyfGzkLWWSSLjaHb4HQmaK" + "MBwGCSqGSIb3DQEJBTEPFw0wNTAzMjQwNzM4MzVaMCEGBSskCAYFMRgWFi92" + "YXIvZmlsZXMvdG1wXzEvdGVzdDEwDQYJKoZIhvcNAQEFBQAEgYA2IvA8lhVz" + "VD5e/itUxbFboKxeKnqJ5n/KuO/uBCl1N14+7Z2vtw1sfkIG+bJdp3OY2Cmn" + "mrQcwsN99Vjal4cXVj8t+DJzFG9tK9dSLvD3q9zT/GQ0kJXfimLVwCa4NaSf" + "Qsu4xtG0Rav6bCcnzabAkKuNNvKtH8amSRzk870DBg=="); public static byte[] xtraCounterSig = Base64.decode( "MIIR/AYJKoZIhvcNAQcCoIIR7TCCEekCAQExCzAJBgUrDgMCGgUAMBoGCSqG" + "SIb3DQEHAaANBAtIZWxsbyB3b3JsZKCCDnkwggTPMIIDt6ADAgECAgRDnYD3" + "MA0GCSqGSIb3DQEBBQUAMFgxCzAJBgNVBAYTAklUMRowGAYDVQQKExFJbi5U" + "ZS5TLkEuIFMucC5BLjEtMCsGA1UEAxMkSW4uVGUuUy5BLiAtIENlcnRpZmlj" + "YXRpb24gQXV0aG9yaXR5MB4XDTA4MDkxMjExNDMxMloXDTEwMDkxMjExNDMx" + "MlowgdgxCzAJBgNVBAYTAklUMSIwIAYDVQQKDBlJbnRlc2EgUy5wLkEuLzA1" + "MjYyODkwMDE0MSowKAYDVQQLDCFCdXNpbmVzcyBDb2xsYWJvcmF0aW9uICYg" + "U2VjdXJpdHkxHjAcBgNVBAMMFU1BU1NJTUlMSUFOTyBaSUNDQVJESTERMA8G" + "A1UEBAwIWklDQ0FSREkxFTATBgNVBCoMDE1BU1NJTUlMSUFOTzEcMBoGA1UE" + "BRMTSVQ6WkNDTVNNNzZIMTRMMjE5WTERMA8GA1UELhMIMDAwMDI1ODUwgaAw" + "DQYJKoZIhvcNAQEBBQADgY4AMIGKAoGBALeJTjmyFgx1SIP6c2AuB/kuyHo5" + "j/prKELTALsFDimre/Hxr3wOSet1TdQfFzU8Lu+EJqgfV9cV+cI1yeH1rZs7" + "lei7L3tX/VR565IywnguX5xwvteASgWZr537Fkws50bvTEMyYOj1Tf3FZvZU" + "z4n4OD39KI4mfR9i1eEVIxR3AgQAizpNo4IBoTCCAZ0wHQYDVR0RBBYwFIES" + "emljY2FyZGlAaW50ZXNhLml0MC8GCCsGAQUFBwEDBCMwITAIBgYEAI5GAQEw" + "CwYGBACORgEDAgEUMAgGBgQAjkYBBDBZBgNVHSAEUjBQME4GBgQAizABATBE" + "MEIGCCsGAQUFBwIBFjZodHRwOi8vZS10cnVzdGNvbS5pbnRlc2EuaXQvY2Ff" + "cHViYmxpY2EvQ1BTX0lOVEVTQS5odG0wDgYDVR0PAQH/BAQDAgZAMIGDBgNV" + "HSMEfDB6gBQZCQOW0bjFWBt+EORuxPagEgkQqKFcpFowWDELMAkGA1UEBhMC" + "SVQxGjAYBgNVBAoTEUluLlRlLlMuQS4gUy5wLkEuMS0wKwYDVQQDEyRJbi5U" + "ZS5TLkEuIC0gQ2VydGlmaWNhdGlvbiBBdXRob3JpdHmCBDzRARMwOwYDVR0f" + "BDQwMjAwoC6gLIYqaHR0cDovL2UtdHJ1c3Rjb20uaW50ZXNhLml0L0NSTC9J" + "TlRFU0EuY3JsMB0GA1UdDgQWBBTf5ItL8KmQh541Dxt7YxcWI1254TANBgkq" + "hkiG9w0BAQUFAAOCAQEAgW+uL1CVWQepbC/wfCmR6PN37Sueb4xiKQj2mTD5" + "UZ5KQjpivy/Hbuf0NrfKNiDEhAvoHSPC31ebGiKuTMFNyZPHfPEUnyYGSxea" + "2w837aXJFr6utPNQGBRi89kH90sZDlXtOSrZI+AzJJn5QK3F9gjcayU2NZXQ" + "MJgRwYmFyn2w4jtox+CwXPQ9E5XgxiMZ4WDL03cWVXDLX00EOJwnDDMUNTRI" + "m9Zv+4SKTNlfFbi9UTBqWBySkDzAelsfB2U61oqc2h1xKmCtkGMmN9iZT+Qz" + "ZC/vaaT+hLEBFGAH2gwFrYc4/jTBKyBYeU1vsAxsibIoTs1Apgl6MH75qPDL" + "BzCCBM8wggO3oAMCAQICBEOdgPcwDQYJKoZIhvcNAQEFBQAwWDELMAkGA1UE" + "BhMCSVQxGjAYBgNVBAoTEUluLlRlLlMuQS4gUy5wLkEuMS0wKwYDVQQDEyRJ" + "bi5UZS5TLkEuIC0gQ2VydGlmaWNhdGlvbiBBdXRob3JpdHkwHhcNMDgwOTEy" + "MTE0MzEyWhcNMTAwOTEyMTE0MzEyWjCB2DELMAkGA1UEBhMCSVQxIjAgBgNV" + "BAoMGUludGVzYSBTLnAuQS4vMDUyNjI4OTAwMTQxKjAoBgNVBAsMIUJ1c2lu" + "ZXNzIENvbGxhYm9yYXRpb24gJiBTZWN1cml0eTEeMBwGA1UEAwwVTUFTU0lN" + "SUxJQU5PIFpJQ0NBUkRJMREwDwYDVQQEDAhaSUNDQVJESTEVMBMGA1UEKgwM" + "TUFTU0lNSUxJQU5PMRwwGgYDVQQFExNJVDpaQ0NNU003NkgxNEwyMTlZMREw" + "DwYDVQQuEwgwMDAwMjU4NTCBoDANBgkqhkiG9w0BAQEFAAOBjgAwgYoCgYEA" + "t4lOObIWDHVIg/pzYC4H+S7IejmP+msoQtMAuwUOKat78fGvfA5J63VN1B8X" + "NTwu74QmqB9X1xX5wjXJ4fWtmzuV6Lsve1f9VHnrkjLCeC5fnHC+14BKBZmv" + "nfsWTCznRu9MQzJg6PVN/cVm9lTPifg4Pf0ojiZ9H2LV4RUjFHcCBACLOk2j" + "ggGhMIIBnTAdBgNVHREEFjAUgRJ6aWNjYXJkaUBpbnRlc2EuaXQwLwYIKwYB" + "BQUHAQMEIzAhMAgGBgQAjkYBATALBgYEAI5GAQMCARQwCAYGBACORgEEMFkG" + "A1UdIARSMFAwTgYGBACLMAEBMEQwQgYIKwYBBQUHAgEWNmh0dHA6Ly9lLXRy" + "dXN0Y29tLmludGVzYS5pdC9jYV9wdWJibGljYS9DUFNfSU5URVNBLmh0bTAO" + "BgNVHQ8BAf8EBAMCBkAwgYMGA1UdIwR8MHqAFBkJA5bRuMVYG34Q5G7E9qAS" + "CRCooVykWjBYMQswCQYDVQQGEwJJVDEaMBgGA1UEChMRSW4uVGUuUy5BLiBT" + "LnAuQS4xLTArBgNVBAMTJEluLlRlLlMuQS4gLSBDZXJ0aWZpY2F0aW9uIEF1" + "dGhvcml0eYIEPNEBEzA7BgNVHR8ENDAyMDCgLqAshipodHRwOi8vZS10cnVz" + "dGNvbS5pbnRlc2EuaXQvQ1JML0lOVEVTQS5jcmwwHQYDVR0OBBYEFN/ki0vw" + "qZCHnjUPG3tjFxYjXbnhMA0GCSqGSIb3DQEBBQUAA4IBAQCBb64vUJVZB6ls" + "L/B8KZHo83ftK55vjGIpCPaZMPlRnkpCOmK/L8du5/Q2t8o2IMSEC+gdI8Lf" + "V5saIq5MwU3Jk8d88RSfJgZLF5rbDzftpckWvq6081AYFGLz2Qf3SxkOVe05" + "Ktkj4DMkmflArcX2CNxrJTY1ldAwmBHBiYXKfbDiO2jH4LBc9D0TleDGIxnh" + "YMvTdxZVcMtfTQQ4nCcMMxQ1NEib1m/7hIpM2V8VuL1RMGpYHJKQPMB6Wx8H" + "ZTrWipzaHXEqYK2QYyY32JlP5DNkL+9ppP6EsQEUYAfaDAWthzj+NMErIFh5" + "TW+wDGyJsihOzUCmCXowfvmo8MsHMIIEzzCCA7egAwIBAgIEQ52A9zANBgkq" + "hkiG9w0BAQUFADBYMQswCQYDVQQGEwJJVDEaMBgGA1UEChMRSW4uVGUuUy5B" + "LiBTLnAuQS4xLTArBgNVBAMTJEluLlRlLlMuQS4gLSBDZXJ0aWZpY2F0aW9u" + "IEF1dGhvcml0eTAeFw0wODA5MTIxMTQzMTJaFw0xMDA5MTIxMTQzMTJaMIHY" + "MQswCQYDVQQGEwJJVDEiMCAGA1UECgwZSW50ZXNhIFMucC5BLi8wNTI2Mjg5" + "MDAxNDEqMCgGA1UECwwhQnVzaW5lc3MgQ29sbGFib3JhdGlvbiAmIFNlY3Vy" + "aXR5MR4wHAYDVQQDDBVNQVNTSU1JTElBTk8gWklDQ0FSREkxETAPBgNVBAQM" + "CFpJQ0NBUkRJMRUwEwYDVQQqDAxNQVNTSU1JTElBTk8xHDAaBgNVBAUTE0lU" + "OlpDQ01TTTc2SDE0TDIxOVkxETAPBgNVBC4TCDAwMDAyNTg1MIGgMA0GCSqG" + "SIb3DQEBAQUAA4GOADCBigKBgQC3iU45shYMdUiD+nNgLgf5Lsh6OY/6ayhC" + "0wC7BQ4pq3vx8a98DknrdU3UHxc1PC7vhCaoH1fXFfnCNcnh9a2bO5Xouy97" + "V/1UeeuSMsJ4Ll+ccL7XgEoFma+d+xZMLOdG70xDMmDo9U39xWb2VM+J+Dg9" + "/SiOJn0fYtXhFSMUdwIEAIs6TaOCAaEwggGdMB0GA1UdEQQWMBSBEnppY2Nh" + "cmRpQGludGVzYS5pdDAvBggrBgEFBQcBAwQjMCEwCAYGBACORgEBMAsGBgQA" + "jkYBAwIBFDAIBgYEAI5GAQQwWQYDVR0gBFIwUDBOBgYEAIswAQEwRDBCBggr" + "BgEFBQcCARY2aHR0cDovL2UtdHJ1c3Rjb20uaW50ZXNhLml0L2NhX3B1YmJs" + "aWNhL0NQU19JTlRFU0EuaHRtMA4GA1UdDwEB/wQEAwIGQDCBgwYDVR0jBHww" + "eoAUGQkDltG4xVgbfhDkbsT2oBIJEKihXKRaMFgxCzAJBgNVBAYTAklUMRow" + "GAYDVQQKExFJbi5UZS5TLkEuIFMucC5BLjEtMCsGA1UEAxMkSW4uVGUuUy5B" + "LiAtIENlcnRpZmljYXRpb24gQXV0aG9yaXR5ggQ80QETMDsGA1UdHwQ0MDIw" + "MKAuoCyGKmh0dHA6Ly9lLXRydXN0Y29tLmludGVzYS5pdC9DUkwvSU5URVNB" + "LmNybDAdBgNVHQ4EFgQU3+SLS/CpkIeeNQ8be2MXFiNdueEwDQYJKoZIhvcN" + "AQEFBQADggEBAIFvri9QlVkHqWwv8Hwpkejzd+0rnm+MYikI9pkw+VGeSkI6" + "Yr8vx27n9Da3yjYgxIQL6B0jwt9XmxoirkzBTcmTx3zxFJ8mBksXmtsPN+2l" + "yRa+rrTzUBgUYvPZB/dLGQ5V7Tkq2SPgMySZ+UCtxfYI3GslNjWV0DCYEcGJ" + "hcp9sOI7aMfgsFz0PROV4MYjGeFgy9N3FlVwy19NBDicJwwzFDU0SJvWb/uE" + "ikzZXxW4vVEwalgckpA8wHpbHwdlOtaKnNodcSpgrZBjJjfYmU/kM2Qv72mk" + "/oSxARRgB9oMBa2HOP40wSsgWHlNb7AMbImyKE7NQKYJejB++ajwywcxggM8" + "MIIDOAIBATBgMFgxCzAJBgNVBAYTAklUMRowGAYDVQQKExFJbi5UZS5TLkEu" + "IFMucC5BLjEtMCsGA1UEAxMkSW4uVGUuUy5BLiAtIENlcnRpZmljYXRpb24g" + "QXV0aG9yaXR5AgRDnYD3MAkGBSsOAwIaBQAwDQYJKoZIhvcNAQEBBQAEgYB+" + "lH2cwLqc91mP8prvgSV+RRzk13dJdZvdoVjgQoFrPhBiZCNIEoHvIhMMA/sM" + "X6euSRZk7EjD24FasCEGYyd0mJVLEy6TSPmuW+wWz/28w3a6IWXBGrbb/ild" + "/CJMkPgLPGgOVD1WDwiNKwfasiQSFtySf5DPn3jFevdLeMmEY6GCAjIwggEV" + "BgkqhkiG9w0BCQYxggEGMIIBAgIBATBgMFgxCzAJBgNVBAYTAklUMRowGAYD" + "VQQKExFJbi5UZS5TLkEuIFMucC5BLjEtMCsGA1UEAxMkSW4uVGUuUy5BLiAt" + "IENlcnRpZmljYXRpb24gQXV0aG9yaXR5AgRDnYD3MAkGBSsOAwIaBQAwDQYJ" + "KoZIhvcNAQEBBQAEgYBHlOULfT5GDigIvxP0qZOy8VbpntmzaPF55VV4buKV" + "35J+uHp98gXKp0LrHM69V5IRKuyuQzHHFBqsXxsRI9o6KoOfgliD9Xc+BeMg" + "dKzQhBhBYoFREq8hQM0nSbqDNHYAQyNHMzUA/ZQUO5dlFuH8Dw3iDYAhNtfd" + "PrlchKJthDCCARUGCSqGSIb3DQEJBjGCAQYwggECAgEBMGAwWDELMAkGA1UE" + "BhMCSVQxGjAYBgNVBAoTEUluLlRlLlMuQS4gUy5wLkEuMS0wKwYDVQQDEyRJ" + "bi5UZS5TLkEuIC0gQ2VydGlmaWNhdGlvbiBBdXRob3JpdHkCBEOdgPcwCQYF" + "Kw4DAhoFADANBgkqhkiG9w0BAQEFAASBgEeU5Qt9PkYOKAi/E/Spk7LxVume" + "2bNo8XnlVXhu4pXfkn64en3yBcqnQusczr1XkhEq7K5DMccUGqxfGxEj2joq" + "g5+CWIP1dz4F4yB0rNCEGEFigVESryFAzSdJuoM0dgBDI0czNQD9lBQ7l2UW" + "4fwPDeINgCE2190+uVyEom2E"); byte[] noSignedAttrSample2 = Base64.decode( "MIIIlAYJKoZIhvcNAQcCoIIIhTCCCIECAQExCzAJBgUrDgMCGgUAMAsGCSqG" + "SIb3DQEHAaCCB3UwggOtMIIDa6ADAgECAgEzMAsGByqGSM44BAMFADCBkDEL" + "MAkGA1UEBhMCVVMxCzAJBgNVBAgTAkNBMRIwEAYDVQQHEwlQYWxvIEFsdG8x" + "HTAbBgNVBAoTFFN1biBNaWNyb3N5c3RlbXMgSW5jMSMwIQYDVQQLExpKYXZh" + "IFNvZnR3YXJlIENvZGUgU2lnbmluZzEcMBoGA1UEAxMTSkNFIENvZGUgU2ln" + "bmluZyBDQTAeFw0wMTA1MjkxNjQ3MTFaFw0wNjA1MjgxNjQ3MTFaMG4xHTAb" + "BgNVBAoTFFN1biBNaWNyb3N5c3RlbXMgSW5jMSMwIQYDVQQLExpKYXZhIFNv" + "ZnR3YXJlIENvZGUgU2lnbmluZzEoMCYGA1UEAxMfVGhlIExlZ2lvbiBvZiB0" + "aGUgQm91bmN5IENhc3RsZTCCAbcwggEsBgcqhkjOOAQBMIIBHwKBgQD9f1OB" + "HXUSKVLfSpwu7OTn9hG3UjzvRADDHj+AtlEmaUVdQCJR+1k9jVj6v8X1ujD2" + "y5tVbNeBO4AdNG/yZmC3a5lQpaSfn+gEexAiwk+7qdf+t8Yb+DtX58aophUP" + "BPuD9tPFHsMCNVQTWhaRMvZ1864rYdcq7/IiAxmd0UgBxwIVAJdgUI8VIwvM" + "spK5gqLrhAvwWBz1AoGBAPfhoIXWmz3ey7yrXDa4V7l5lK+7+jrqgvlXTAs9" + "B4JnUVlXjrrUWU/mcQcQgYC0SRZxI+hMKBYTt88JMozIpuE8FnqLVHyNKOCj" + "rh4rs6Z1kW6jfwv6ITVi8ftiegEkO8yk8b6oUZCJqIPf4VrlnwaSi2ZegHtV" + "JWQBTDv+z0kqA4GEAAKBgBWry/FCAZ6miyy39+ftsa+h9lxoL+JtV0MJcUyQ" + "E4VAhpAwWb8vyjba9AwOylYQTktHX5sAkFvjBiU0LOYDbFSTVZSHMRJgfjxB" + "SHtICjOEvr1BJrrOrdzqdxcOUge5n7El124BCrv91x5Ol8UTwtiO9LrRXF/d" + "SyK+RT5n1klRo3YwdDARBglghkgBhvhCAQEEBAMCAIcwDgYDVR0PAQH/BAQD" + "AgHGMB0GA1UdDgQWBBQwMY4NRcco1AO3w1YsokfDLVseEjAPBgNVHRMBAf8E" + "BTADAQH/MB8GA1UdIwQYMBaAFGXi9IbJ007wkU5Yomr12HhamsGmMAsGByqG" + "SM44BAMFAAMvADAsAhRmigTu6QV0sTfEkVljgij/hhdVfAIUQZvMxAnIHc30" + "y/u0C1T5UEG9glUwggPAMIIDfqADAgECAgEQMAsGByqGSM44BAMFADCBkDEL" + "MAkGA1UEBhMCVVMxCzAJBgNVBAgTAkNBMRIwEAYDVQQHEwlQYWxvIEFsdG8x" + "HTAbBgNVBAoTFFN1biBNaWNyb3N5c3RlbXMgSW5jMSMwIQYDVQQLExpKYXZh" + "IFNvZnR3YXJlIENvZGUgU2lnbmluZzEcMBoGA1UEAxMTSkNFIENvZGUgU2ln" + "bmluZyBDQTAeFw0wMTA0MjUwNzAwMDBaFw0yMDA0MjUwNzAwMDBaMIGQMQsw" + "CQYDVQQGEwJVUzELMAkGA1UECBMCQ0ExEjAQBgNVBAcTCVBhbG8gQWx0bzEd" + "MBsGA1UEChMUU3VuIE1pY3Jvc3lzdGVtcyBJbmMxIzAhBgNVBAsTGkphdmEg" + "U29mdHdhcmUgQ29kZSBTaWduaW5nMRwwGgYDVQQDExNKQ0UgQ29kZSBTaWdu" + "aW5nIENBMIIBtzCCASwGByqGSM44BAEwggEfAoGBAOuvNwQeylEeaV2w8o/2" + "tUkfxqSZBdcpv3S3avUZ2B7kG/gKAZqY/3Cr4kpWhmxTs/zhyIGMMfDE87CL" + "5nAG7PdpaNuDTHIpiSk2F1w7SgegIAIqRpdRHXDICBgLzgxum3b3BePn+9Nh" + "eeFgmiSNBpWDPFEg4TDPOFeCphpyDc7TAhUAhCVF4bq5qWKreehbMLiJaxv/" + "e3UCgYEAq8l0e3Tv7kK1alNNO92QBnJokQ8LpCl2LlU71a5NZVx+KjoEpmem" + "0HGqpde34sFyDaTRqh6SVEwgAAmisAlBGTMAssNcrkL4sYvKfJbYEH83RFuq" + "zHjI13J2N2tAmahVZvqoAx6LShECactMuCUGHKB30sms0j3pChD6dnC3+9wD" + "gYQAAoGALQmYXKy4nMeZfu4gGSo0kPnXq6uu3WtylQ1m+O8nj0Sy7ShEx/6v" + "sKYnbwBnRYJbB6hWVjvSKVFhXmk51y50dxLPGUr1LcjLcmHETm/6R0M/FLv6" + "vBhmKMLZZot6LS/CYJJLFP5YPiF/aGK+bEhJ+aBLXoWdGRD5FUVRG3HU9wuj" + "ZjBkMBEGCWCGSAGG+EIBAQQEAwIABzAPBgNVHRMBAf8EBTADAQH/MB8GA1Ud" + "IwQYMBaAFGXi9IbJ007wkU5Yomr12HhamsGmMB0GA1UdDgQWBBRl4vSGydNO" + "8JFOWKJq9dh4WprBpjALBgcqhkjOOAQDBQADLwAwLAIUKvfPPJdd+Xi2CNdB" + "tNkNRUzktJwCFEXNdWkOIfod1rMpsun3Mx0z/fxJMYHoMIHlAgEBMIGWMIGQ" + "MQswCQYDVQQGEwJVUzELMAkGA1UECBMCQ0ExEjAQBgNVBAcTCVBhbG8gQWx0" + "bzEdMBsGA1UEChMUU3VuIE1pY3Jvc3lzdGVtcyBJbmMxIzAhBgNVBAsTGkph" + "dmEgU29mdHdhcmUgQ29kZSBTaWduaW5nMRwwGgYDVQQDExNKQ0UgQ29kZSBT" + "aWduaW5nIENBAgEzMAkGBSsOAwIaBQAwCwYHKoZIzjgEAQUABC8wLQIVAIGV" + "khm+kbV4a/+EP45PHcq0hIViAhR4M9os6IrJnoEDS3Y3l7O6zrSosA=="); public String getName() { return "BcSignedData"; } private void init() throws Exception { if (!_initialised) { _initialised = true; _origDN = "O=Bouncy Castle, C=AU"; _origKP = CMSTestUtil.makeKeyPair(); _origCert = CMSTestUtil.makeCertificate(_origKP, _origDN, _origKP, _origDN); _signDN = "CN=Bob, OU=Sales, O=Bouncy Castle, C=AU"; _signKP = CMSTestUtil.makeKeyPair(); _signCert = CMSTestUtil.makeCertificate(_signKP, _signDN, _origKP, _origDN); } } private void verifyRSASignatures(CMSSignedData s, byte[] contentDigest) throws Exception { Store certStore = s.getCertificates(); SignerInformationStore signers = s.getSignerInfos(); Collection c = signers.getSigners(); Iterator it = c.iterator(); while (it.hasNext()) { SignerInformation signer = (SignerInformation)it.next(); Collection certCollection = certStore.getMatches(signer.getSID()); Iterator certIt = certCollection.iterator(); X509CertificateHolder cert = (X509CertificateHolder)certIt.next(); if (!signer.verify(new BcRSASignerInfoVerifierBuilder(new DefaultCMSSignatureAlgorithmNameGenerator(), new DefaultSignatureAlgorithmIdentifierFinder(), new DefaultDigestAlgorithmIdentifierFinder(), new BcDigestCalculatorProvider()).build(cert))) { fail("signature verification failed"); } if (contentDigest != null) { if (!Arrays.areEqual(contentDigest, signer.getContentDigest())) { fail("digest verification failed"); } } } } public void performTest() throws Exception { init(); testDetachedRSA(); testEncapsulatedRSA(); } private void testDetachedRSA() throws Exception { Digest md = new SHA1Digest(); List certList = new ArrayList(); CMSTypedData msg = new CMSProcessableByteArray("Hello world!".getBytes()); certList.add(_origCert); certList.add(_signCert); Store certs = new CollectionStore(certList); CMSSignedDataGenerator gen = new CMSSignedDataGenerator(); byte[] digValue = new byte[md.getDigestSize()]; byte[] data = "Hello world!".getBytes(); md.update(data, 0, data.length); md.doFinal(digValue, 0); Attribute attr = new Attribute(CMSAttributes.messageDigest, new DERSet( new DEROctetString( digValue))); ASN1EncodableVector v = new ASN1EncodableVector(); v.add(attr); AsymmetricKeyParameter privKey = (AsymmetricKeyParameter)_origKP.getPrivate(); AlgorithmIdentifier sigAlgId = new DefaultSignatureAlgorithmIdentifierFinder().find("SHA1withRSA"); AlgorithmIdentifier digAlgId = new DefaultDigestAlgorithmIdentifierFinder().find(sigAlgId); BcContentSignerBuilder contentSignerBuilder = new BcRSAContentSignerBuilder(sigAlgId, digAlgId); gen.addSignerInfoGenerator( new SignerInfoGeneratorBuilder(new BcDigestCalculatorProvider()) .setSignedAttributeGenerator(new DefaultSignedAttributeTableGenerator(new AttributeTable(v))) .build(contentSignerBuilder.build(privKey), _origCert)); gen.addCertificates(certs); CMSSignedData s = gen.generate(new CMSAbsentContent(), false); // // the signature is detached, so need to add msg before passing on // s = new CMSSignedData(msg, s.getEncoded()); // // compute expected content digest // verifyRSASignatures(s, digValue); } private void testEncapsulatedRSA() throws Exception { Digest md = new SHA1Digest(); List certList = new ArrayList(); CMSTypedData msg = new CMSProcessableByteArray("Hello world!".getBytes()); certList.add(_origCert); certList.add(_signCert); Store certs = new CollectionStore(certList); CMSSignedDataGenerator gen = new CMSSignedDataGenerator(); byte[] digValue = new byte[md.getDigestSize()]; byte[] data = "Hello world!".getBytes(); md.update(data, 0, data.length); md.doFinal(digValue, 0); Attribute attr = new Attribute(CMSAttributes.messageDigest, new DERSet( new DEROctetString( digValue))); ASN1EncodableVector v = new ASN1EncodableVector(); v.add(attr); AsymmetricKeyParameter privKey = (AsymmetricKeyParameter)_origKP.getPrivate(); AlgorithmIdentifier sigAlgId = new DefaultSignatureAlgorithmIdentifierFinder().find("SHA1withRSA"); AlgorithmIdentifier digAlgId = new DefaultDigestAlgorithmIdentifierFinder().find(sigAlgId); BcContentSignerBuilder contentSignerBuilder = new BcRSAContentSignerBuilder(sigAlgId, digAlgId); gen.addSignerInfoGenerator( new SignerInfoGeneratorBuilder(new BcDigestCalculatorProvider()) .build(contentSignerBuilder.build(privKey), _origCert)); gen.addCertificates(certs); CMSSignedData s = gen.generate(new CMSProcessableByteArray(data), true); // // the signature is encapsulated, so no need to add msg before passing on // s = new CMSSignedData(s.getEncoded()); // // compute expected content digest // verifyRSASignatures(s, digValue); } public static void main( String[] args) { runTest(new BcSignedDataTest()); } } bouncycastle-1.49.orig/j2me/org/bouncycastle/cms/test/RegressionTest.java0000644000175000017500000000121611732275232026140 0ustar ebourgebourgpackage org.bouncycastle.cms.test; import org.bouncycastle.util.test.Test; import org.bouncycastle.util.test.TestResult; public class RegressionTest { public static Test[] tests = { new BcEnvelopedDataTest(), new BcSignedDataTest() }; public static void main( String[] args) { for (int i = 0; i != tests.length; i++) { TestResult result = tests[i].perform(); if (result.getException() != null) { result.getException().printStackTrace(); } System.out.println(result); } } } bouncycastle-1.49.orig/j2me/org/bouncycastle/cms/CMSEnvelopedHelper.java0000644000175000017500000001602212103632343025617 0ustar ebourgebourgpackage org.bouncycastle.cms; import java.io.FilterInputStream; import java.io.IOException; import java.io.InputStream; import java.util.ArrayList; import java.util.HashMap; import java.util.List; import java.util.Map; import org.bouncycastle.asn1.ASN1Encodable; import org.bouncycastle.asn1.ASN1Set; import org.bouncycastle.asn1.cms.KEKRecipientInfo; import org.bouncycastle.asn1.cms.KeyAgreeRecipientInfo; import org.bouncycastle.asn1.cms.KeyTransRecipientInfo; import org.bouncycastle.asn1.cms.PasswordRecipientInfo; import org.bouncycastle.asn1.cms.RecipientInfo; import org.bouncycastle.asn1.x509.AlgorithmIdentifier; import org.bouncycastle.operator.DigestCalculator; import org.bouncycastle.util.Integers; class CMSEnvelopedHelper { static final CMSEnvelopedHelper INSTANCE = new CMSEnvelopedHelper(); private static final Map KEYSIZES = new HashMap(); private static final Map BASE_CIPHER_NAMES = new HashMap(); private static final Map CIPHER_ALG_NAMES = new HashMap(); private static final Map MAC_ALG_NAMES = new HashMap(); static { KEYSIZES.put(CMSEnvelopedGenerator.DES_EDE3_CBC, Integers.valueOf(192)); KEYSIZES.put(CMSEnvelopedGenerator.AES128_CBC, Integers.valueOf(128)); KEYSIZES.put(CMSEnvelopedGenerator.AES192_CBC, Integers.valueOf(192)); KEYSIZES.put(CMSEnvelopedGenerator.AES256_CBC, Integers.valueOf(256)); BASE_CIPHER_NAMES.put(CMSEnvelopedGenerator.DES_EDE3_CBC, "DESEDE"); BASE_CIPHER_NAMES.put(CMSEnvelopedGenerator.AES128_CBC, "AES"); BASE_CIPHER_NAMES.put(CMSEnvelopedGenerator.AES192_CBC, "AES"); BASE_CIPHER_NAMES.put(CMSEnvelopedGenerator.AES256_CBC, "AES"); CIPHER_ALG_NAMES.put(CMSEnvelopedGenerator.DES_EDE3_CBC, "DESEDE/CBC/PKCS5Padding"); CIPHER_ALG_NAMES.put(CMSEnvelopedGenerator.AES128_CBC, "AES/CBC/PKCS5Padding"); CIPHER_ALG_NAMES.put(CMSEnvelopedGenerator.AES192_CBC, "AES/CBC/PKCS5Padding"); CIPHER_ALG_NAMES.put(CMSEnvelopedGenerator.AES256_CBC, "AES/CBC/PKCS5Padding"); MAC_ALG_NAMES.put(CMSEnvelopedGenerator.DES_EDE3_CBC, "DESEDEMac"); MAC_ALG_NAMES.put(CMSEnvelopedGenerator.AES128_CBC, "AESMac"); MAC_ALG_NAMES.put(CMSEnvelopedGenerator.AES192_CBC, "AESMac"); MAC_ALG_NAMES.put(CMSEnvelopedGenerator.AES256_CBC, "AESMac"); } int getKeySize(String oid) { Integer keySize = (Integer)KEYSIZES.get(oid); if (keySize == null) { throw new IllegalArgumentException("no keysize for " + oid); } return keySize.intValue(); } static RecipientInformationStore buildRecipientInformationStore( ASN1Set recipientInfos, AlgorithmIdentifier messageAlgorithm, CMSSecureReadable secureReadable) { return buildRecipientInformationStore(recipientInfos, messageAlgorithm, secureReadable, null); } static RecipientInformationStore buildRecipientInformationStore( ASN1Set recipientInfos, AlgorithmIdentifier messageAlgorithm, CMSSecureReadable secureReadable, AuthAttributesProvider additionalData) { List infos = new ArrayList(); for (int i = 0; i != recipientInfos.size(); i++) { RecipientInfo info = RecipientInfo.getInstance(recipientInfos.getObjectAt(i)); readRecipientInfo(infos, info, messageAlgorithm, secureReadable, additionalData); } return new RecipientInformationStore(infos); } private static void readRecipientInfo( List infos, RecipientInfo info, AlgorithmIdentifier messageAlgorithm, CMSSecureReadable secureReadable, AuthAttributesProvider additionalData) { ASN1Encodable recipInfo = info.getInfo(); if (recipInfo instanceof KeyTransRecipientInfo) { infos.add(new KeyTransRecipientInformation( (KeyTransRecipientInfo)recipInfo, messageAlgorithm, secureReadable, additionalData)); } else if (recipInfo instanceof KEKRecipientInfo) { infos.add(new KEKRecipientInformation( (KEKRecipientInfo)recipInfo, messageAlgorithm, secureReadable, additionalData)); } else if (recipInfo instanceof KeyAgreeRecipientInfo) { KeyAgreeRecipientInformation.readRecipientInfo(infos, (KeyAgreeRecipientInfo)recipInfo, messageAlgorithm, secureReadable, additionalData); } else if (recipInfo instanceof PasswordRecipientInfo) { infos.add(new PasswordRecipientInformation( (PasswordRecipientInfo)recipInfo, messageAlgorithm, secureReadable, additionalData)); } } static class CMSDigestAuthenticatedSecureReadable implements CMSSecureReadable { private DigestCalculator digestCalculator; private CMSReadable readable; public CMSDigestAuthenticatedSecureReadable(DigestCalculator digestCalculator, CMSReadable readable) { this.digestCalculator = digestCalculator; this.readable = readable; } public InputStream getInputStream() throws IOException, CMSException { return new FilterInputStream(readable.getInputStream()) { public int read() throws IOException { int b = in.read(); if (b >= 0) { digestCalculator.getOutputStream().write(b); } return b; } public int read(byte[] inBuf, int inOff, int inLen) throws IOException { int n = in.read(inBuf, inOff, inLen); if (n >= 0) { digestCalculator.getOutputStream().write(inBuf, inOff, n); } return n; } }; } public byte[] getDigest() { return digestCalculator.getDigest(); } } static class CMSAuthenticatedSecureReadable implements CMSSecureReadable { private AlgorithmIdentifier algorithm; private CMSReadable readable; CMSAuthenticatedSecureReadable(AlgorithmIdentifier algorithm, CMSReadable readable) { this.algorithm = algorithm; this.readable = readable; } public InputStream getInputStream() throws IOException, CMSException { return readable.getInputStream(); } } static class CMSEnvelopedSecureReadable implements CMSSecureReadable { private AlgorithmIdentifier algorithm; private CMSReadable readable; CMSEnvelopedSecureReadable(AlgorithmIdentifier algorithm, CMSReadable readable) { this.algorithm = algorithm; this.readable = readable; } public InputStream getInputStream() throws IOException, CMSException { return readable.getInputStream(); } } } bouncycastle-1.49.orig/j2me/org/bouncycastle/cms/CMSSignedGenerator.java0000644000175000017500000002404112152021663025617 0ustar ebourgebourgpackage org.bouncycastle.cms; import java.io.IOException; import java.security.SecureRandom; import java.util.ArrayList; import java.util.HashMap; import java.util.HashSet; import java.util.Iterator; import java.util.List; import java.util.Map; import java.util.Set; import org.bouncycastle.asn1.ASN1Encodable; import org.bouncycastle.asn1.ASN1ObjectIdentifier; import org.bouncycastle.asn1.ASN1Primitive; import org.bouncycastle.asn1.ASN1Set; import org.bouncycastle.asn1.DERSet; import org.bouncycastle.asn1.DERTaggedObject; import org.bouncycastle.asn1.cms.AttributeTable; import org.bouncycastle.asn1.cms.CMSObjectIdentifiers; import org.bouncycastle.asn1.cms.OtherRevocationInfoFormat; import org.bouncycastle.asn1.cryptopro.CryptoProObjectIdentifiers; import org.bouncycastle.asn1.nist.NISTObjectIdentifiers; import org.bouncycastle.asn1.oiw.OIWObjectIdentifiers; import org.bouncycastle.asn1.pkcs.PKCSObjectIdentifiers; import org.bouncycastle.asn1.teletrust.TeleTrusTObjectIdentifiers; import org.bouncycastle.asn1.x509.AlgorithmIdentifier; import org.bouncycastle.asn1.x509.AttributeCertificate; import org.bouncycastle.asn1.x9.X9ObjectIdentifiers; import org.bouncycastle.cert.X509AttributeCertificateHolder; import org.bouncycastle.cert.X509CRLHolder; import org.bouncycastle.cert.X509CertificateHolder; import org.bouncycastle.util.Store; import org.bouncycastle.util.Arrays; public class CMSSignedGenerator { /** * Default type for the signed data. */ public static final String DATA = CMSObjectIdentifiers.data.getId(); public static final String DIGEST_SHA1 = OIWObjectIdentifiers.idSHA1.getId(); public static final String DIGEST_SHA224 = NISTObjectIdentifiers.id_sha224.getId(); public static final String DIGEST_SHA256 = NISTObjectIdentifiers.id_sha256.getId(); public static final String DIGEST_SHA384 = NISTObjectIdentifiers.id_sha384.getId(); public static final String DIGEST_SHA512 = NISTObjectIdentifiers.id_sha512.getId(); public static final String DIGEST_MD5 = PKCSObjectIdentifiers.md5.getId(); public static final String DIGEST_GOST3411 = CryptoProObjectIdentifiers.gostR3411.getId(); public static final String DIGEST_RIPEMD128 = TeleTrusTObjectIdentifiers.ripemd128.getId(); public static final String DIGEST_RIPEMD160 = TeleTrusTObjectIdentifiers.ripemd160.getId(); public static final String DIGEST_RIPEMD256 = TeleTrusTObjectIdentifiers.ripemd256.getId(); public static final String ENCRYPTION_RSA = PKCSObjectIdentifiers.rsaEncryption.getId(); public static final String ENCRYPTION_DSA = X9ObjectIdentifiers.id_dsa_with_sha1.getId(); public static final String ENCRYPTION_ECDSA = X9ObjectIdentifiers.ecdsa_with_SHA1.getId(); public static final String ENCRYPTION_RSA_PSS = PKCSObjectIdentifiers.id_RSASSA_PSS.getId(); public static final String ENCRYPTION_GOST3410 = CryptoProObjectIdentifiers.gostR3410_94.getId(); public static final String ENCRYPTION_ECGOST3410 = CryptoProObjectIdentifiers.gostR3410_2001.getId(); private static final String ENCRYPTION_ECDSA_WITH_SHA1 = X9ObjectIdentifiers.ecdsa_with_SHA1.getId(); private static final String ENCRYPTION_ECDSA_WITH_SHA224 = X9ObjectIdentifiers.ecdsa_with_SHA224.getId(); private static final String ENCRYPTION_ECDSA_WITH_SHA256 = X9ObjectIdentifiers.ecdsa_with_SHA256.getId(); private static final String ENCRYPTION_ECDSA_WITH_SHA384 = X9ObjectIdentifiers.ecdsa_with_SHA384.getId(); private static final String ENCRYPTION_ECDSA_WITH_SHA512 = X9ObjectIdentifiers.ecdsa_with_SHA512.getId(); private static final Set NO_PARAMS = new HashSet(); private static final Map EC_ALGORITHMS = new HashMap(); static { NO_PARAMS.add(ENCRYPTION_DSA); NO_PARAMS.add(ENCRYPTION_ECDSA); NO_PARAMS.add(ENCRYPTION_ECDSA_WITH_SHA1); NO_PARAMS.add(ENCRYPTION_ECDSA_WITH_SHA224); NO_PARAMS.add(ENCRYPTION_ECDSA_WITH_SHA256); NO_PARAMS.add(ENCRYPTION_ECDSA_WITH_SHA384); NO_PARAMS.add(ENCRYPTION_ECDSA_WITH_SHA512); EC_ALGORITHMS.put(DIGEST_SHA1, ENCRYPTION_ECDSA_WITH_SHA1); EC_ALGORITHMS.put(DIGEST_SHA224, ENCRYPTION_ECDSA_WITH_SHA224); EC_ALGORITHMS.put(DIGEST_SHA256, ENCRYPTION_ECDSA_WITH_SHA256); EC_ALGORITHMS.put(DIGEST_SHA384, ENCRYPTION_ECDSA_WITH_SHA384); EC_ALGORITHMS.put(DIGEST_SHA512, ENCRYPTION_ECDSA_WITH_SHA512); } protected List certs = new ArrayList(); protected List crls = new ArrayList(); protected List _signers = new ArrayList(); protected List signerGens = new ArrayList(); protected Map digests = new HashMap(); protected final SecureRandom rand; /** * base constructor */ protected CMSSignedGenerator() { this(new SecureRandom()); } /** * constructor allowing specific source of randomness * @param rand instance of SecureRandom to use */ protected CMSSignedGenerator( SecureRandom rand) { this.rand = rand; } protected Map getBaseParameters(ASN1ObjectIdentifier contentType, AlgorithmIdentifier digAlgId, byte[] hash) { Map param = new HashMap(); param.put(CMSAttributeTableGenerator.CONTENT_TYPE, contentType); param.put(CMSAttributeTableGenerator.DIGEST_ALGORITHM_IDENTIFIER, digAlgId); param.put(CMSAttributeTableGenerator.DIGEST, Arrays.clone(hash)); return param; } protected ASN1Set getAttributeSet( AttributeTable attr) { if (attr != null) { return new DERSet(attr.toASN1EncodableVector()); } return null; } /** * Add a certificate to the certificate set to be included with the generated SignedData message. * * @param certificate the certificate to be included. * @throws CMSException if the certificate cannot be encoded for adding. */ public void addCertificate( X509CertificateHolder certificate) throws CMSException { certs.add(certificate.toASN1Structure()); } /** * Add the certificates in certStore to the certificate set to be included with the generated SignedData message. * * @param certStore the store containing the certificates to be included. * @throws CMSException if the certificates cannot be encoded for adding. */ public void addCertificates( Store certStore) throws CMSException { certs.addAll(CMSUtils.getCertificatesFromStore(certStore)); } /** * Add a CRL to the CRL set to be included with the generated SignedData message. * * @param crl the CRL to be included. */ public void addCRL(X509CRLHolder crl) { crls.add(crl.toASN1Structure()); } /** * Add the CRLs in crlStore to the CRL set to be included with the generated SignedData message. * * @param crlStore the store containing the CRLs to be included. * @throws CMSException if the CRLs cannot be encoded for adding. */ public void addCRLs( Store crlStore) throws CMSException { crls.addAll(CMSUtils.getCRLsFromStore(crlStore)); } /** * Add the attribute certificates in attrStore to the certificate set to be included with the generated SignedData message. * * @param attrCert the store containing the certificates to be included. * @throws CMSException if the attribute certificate cannot be encoded for adding. */ public void addAttributeCertificate( X509AttributeCertificateHolder attrCert) throws CMSException { certs.add(new DERTaggedObject(false, 2, attrCert.toASN1Structure())); } /** * Add the attribute certificates in attrStore to the certificate set to be included with the generated SignedData message. * * @param attrStore the store containing the certificates to be included. * @throws CMSException if the attribute certificate cannot be encoded for adding. */ public void addAttributeCertificates( Store attrStore) throws CMSException { certs.addAll(CMSUtils.getAttributeCertificatesFromStore(attrStore)); } /** * Add a single instance of otherRevocationData to the CRL set to be included with the generated SignedData message. * * @param otherRevocationInfoFormat the OID specifying the format of the otherRevocationInfo data. * @param otherRevocationInfo the otherRevocationInfo ASN.1 structure. */ public void addOtherRevocationInfo( ASN1ObjectIdentifier otherRevocationInfoFormat, ASN1Encodable otherRevocationInfo) { crls.add(new DERTaggedObject(false, 1, new OtherRevocationInfoFormat(otherRevocationInfoFormat, otherRevocationInfo))); } /** * Add a Store of otherRevocationData to the CRL set to be included with the generated SignedData message. * * @param otherRevocationInfoFormat the OID specifying the format of the otherRevocationInfo data. * @param otherRevocationInfos a Store of otherRevocationInfo data to add. */ public void addOtherRevocationInfo( ASN1ObjectIdentifier otherRevocationInfoFormat, Store otherRevocationInfos) { crls.addAll(CMSUtils.getOthersFromStore(otherRevocationInfoFormat, otherRevocationInfos)); } /** * Add a store of precalculated signers to the generator. * * @param signerStore store of signers */ public void addSigners( SignerInformationStore signerStore) { Iterator it = signerStore.getSigners().iterator(); while (it.hasNext()) { _signers.add(it.next()); } } public void addSignerInfoGenerator(SignerInfoGenerator infoGen) { signerGens.add(infoGen); } /** * Return a map of oids and byte arrays representing the digests calculated on the content during * the last generate. * * @return a map of oids (as String objects) and byte[] representing digests. */ public Map getGeneratedDigests() { return new HashMap(digests); } } bouncycastle-1.49.orig/j2me/org/bouncycastle/cms/CMSSignedDataGenerator.java0000644000175000017500000001631012150050436026407 0ustar ebourgebourgpackage org.bouncycastle.cms; import java.io.ByteArrayOutputStream; import java.io.IOException; import java.io.OutputStream; import java.security.SecureRandom; import java.util.ArrayList; import java.util.Iterator; import java.util.List; import org.bouncycastle.asn1.ASN1EncodableVector; import org.bouncycastle.asn1.ASN1ObjectIdentifier; import org.bouncycastle.asn1.ASN1OctetString; import org.bouncycastle.asn1.ASN1Set; import org.bouncycastle.asn1.BEROctetString; import org.bouncycastle.asn1.DERSet; import org.bouncycastle.asn1.cms.AttributeTable; import org.bouncycastle.asn1.cms.CMSObjectIdentifiers; import org.bouncycastle.asn1.cms.ContentInfo; import org.bouncycastle.asn1.cms.SignedData; import org.bouncycastle.asn1.cms.SignerInfo; import org.bouncycastle.operator.ContentSigner; import org.bouncycastle.operator.OperatorCreationException; import org.bouncycastle.operator.bc.BcDigestCalculatorProvider; /** * general class for generating a pkcs7-signature message. *

    * A simple example of usage, generating a detached signature. * *

     *      List             certList = new ArrayList();
     *      CMSTypedData     msg = new CMSProcessableByteArray("Hello world!".getBytes());
     *
     *      certList.add(signCert);
     *
     *      Store           certs = new JcaCertStore(certList);
     *
     *      CMSSignedDataGenerator gen = new CMSSignedDataGenerator();
     *      ContentSigner sha1Signer = new JcaContentSignerBuilder("SHA1withRSA").setProvider("BC").build(signKP.getPrivate());
     *
     *      gen.addSignerInfoGenerator(
     *                new JcaSignerInfoGeneratorBuilder(
     *                     new JcaDigestCalculatorProviderBuilder().setProvider("BC").build())
     *                     .build(sha1Signer, signCert));
     *
     *      gen.addCertificates(certs);
     *
     *      CMSSignedData sigData = gen.generate(msg, false);
     * 
    */ public class CMSSignedDataGenerator extends CMSSignedGenerator { private List signerInfs = new ArrayList(); /** * base constructor */ public CMSSignedDataGenerator() { } public CMSSignedData generate( CMSTypedData content) throws CMSException { return generate(content, false); } public CMSSignedData generate( // FIXME Avoid accessing more than once to support CMSProcessableInputStream CMSTypedData content, boolean encapsulate) throws CMSException { if (!signerInfs.isEmpty()) { throw new IllegalStateException("this method can only be used with SignerInfoGenerator"); } // TODO // if (signerInfs.isEmpty()) // { // /* RFC 3852 5.2 // * "In the degenerate case where there are no signers, the // * EncapsulatedContentInfo value being "signed" is irrelevant. In this // * case, the content type within the EncapsulatedContentInfo value being // * "signed" MUST be id-data (as defined in section 4), and the content // * field of the EncapsulatedContentInfo value MUST be omitted." // */ // if (encapsulate) // { // throw new IllegalArgumentException("no signers, encapsulate must be false"); // } // if (!DATA.equals(eContentType)) // { // throw new IllegalArgumentException("no signers, eContentType must be id-data"); // } // } // // if (!DATA.equals(eContentType)) // { // /* RFC 3852 5.3 // * [The 'signedAttrs']... // * field is optional, but it MUST be present if the content type of // * the EncapsulatedContentInfo value being signed is not id-data. // */ // // TODO signedAttrs must be present for all signers // } ASN1EncodableVector digestAlgs = new ASN1EncodableVector(); ASN1EncodableVector signerInfos = new ASN1EncodableVector(); digests.clear(); // clear the current preserved digest state // // add the precalculated SignerInfo objects. // for (Iterator it = _signers.iterator(); it.hasNext();) { SignerInformation signer = (SignerInformation)it.next(); digestAlgs.add(CMSSignedHelper.INSTANCE.fixAlgID(signer.getDigestAlgorithmID())); // TODO Verify the content type and calculated digest match the precalculated SignerInfo signerInfos.add(signer.toASN1Structure()); } // // add the SignerInfo objects // ASN1ObjectIdentifier contentTypeOID = content.getContentType(); ASN1OctetString octs = null; if (content != null) { ByteArrayOutputStream bOut = null; if (encapsulate) { bOut = new ByteArrayOutputStream(); } OutputStream cOut = CMSUtils.attachSignersToOutputStream(signerGens, bOut); // Just in case it's unencapsulated and there are no signers! cOut = CMSUtils.getSafeOutputStream(cOut); try { content.write(cOut); cOut.close(); } catch (IOException e) { throw new CMSException("data processing exception: " + e.getMessage(), e); } if (encapsulate) { octs = new BEROctetString(bOut.toByteArray()); } } for (Iterator it = signerGens.iterator(); it.hasNext();) { SignerInfoGenerator sGen = (SignerInfoGenerator)it.next(); SignerInfo inf = sGen.generate(contentTypeOID); digestAlgs.add(inf.getDigestAlgorithm()); signerInfos.add(inf); byte[] calcDigest = sGen.getCalculatedDigest(); if (calcDigest != null) { digests.put(inf.getDigestAlgorithm().getAlgorithm().getId(), calcDigest); } } ASN1Set certificates = null; if (certs.size() != 0) { certificates = CMSUtils.createBerSetFromList(certs); } ASN1Set certrevlist = null; if (crls.size() != 0) { certrevlist = CMSUtils.createBerSetFromList(crls); } ContentInfo encInfo = new ContentInfo(contentTypeOID, octs); SignedData sd = new SignedData( new DERSet(digestAlgs), encInfo, certificates, certrevlist, new DERSet(signerInfos)); ContentInfo contentInfo = new ContentInfo( CMSObjectIdentifiers.signedData, sd); return new CMSSignedData(content, contentInfo); } /** * generate a set of one or more SignerInformation objects representing counter signatures on * the passed in SignerInformation object. * * @param signer the signer to be countersigned * @return a store containing the signers. */ public SignerInformationStore generateCounterSigners(SignerInformation signer) throws CMSException { return this.generate(new CMSProcessableByteArray(null, signer.getSignature()), false).getSignerInfos(); } } bouncycastle-1.49.orig/j2me/org/bouncycastle/cms/DefaultSignedAttributeTableGenerator.java0000644000175000017500000000661211732000343031414 0ustar ebourgebourgpackage org.bouncycastle.cms; import java.util.Date; import java.util.Enumeration; import java.util.Hashtable; import java.util.Iterator; import java.util.Map; import org.bouncycastle.asn1.DERObjectIdentifier; import org.bouncycastle.asn1.DEROctetString; import org.bouncycastle.asn1.DERSet; import org.bouncycastle.asn1.cms.Attribute; import org.bouncycastle.asn1.cms.AttributeTable; import org.bouncycastle.asn1.cms.CMSAttributes; import org.bouncycastle.asn1.cms.Time; /** * Default signed attributes generator. */ public class DefaultSignedAttributeTableGenerator implements CMSAttributeTableGenerator { private final Hashtable table; /** * Initialise to use all defaults */ public DefaultSignedAttributeTableGenerator() { table = new Hashtable(); } /** * Initialise with some extra attributes or overrides. * * @param attributeTable initial attribute table to use. */ public DefaultSignedAttributeTableGenerator( AttributeTable attributeTable) { if (attributeTable != null) { table = attributeTable.toHashtable(); } else { table = new Hashtable(); } } /** * Create a standard attribute table from the passed in parameters - this will * normally include contentType, signingTime, and messageDigest. If the constructor * using an AttributeTable was used, entries in it for contentType, signingTime, and * messageDigest will override the generated ones. * * @param parameters source parameters for table generation. * * @return a filled in Hashtable of attributes. */ protected Hashtable createStandardAttributeTable( Map parameters) { Hashtable std = new Hashtable(); for (Enumeration it = table.keys(); it.hasMoreElements();) { Object k = it.nextElement(); std.put(k, table.get(k)); } if (!std.containsKey(CMSAttributes.contentType)) { DERObjectIdentifier contentType = (DERObjectIdentifier) parameters.get(CMSAttributeTableGenerator.CONTENT_TYPE); // contentType will be null if we're trying to generate a counter signature. if (contentType != null) { Attribute attr = new Attribute(CMSAttributes.contentType, new DERSet(contentType)); std.put(attr.getAttrType(), attr); } } if (!std.containsKey(CMSAttributes.signingTime)) { Date signingTime = new Date(); Attribute attr = new Attribute(CMSAttributes.signingTime, new DERSet(new Time(signingTime))); std.put(attr.getAttrType(), attr); } if (!std.containsKey(CMSAttributes.messageDigest)) { byte[] messageDigest = (byte[])parameters.get( CMSAttributeTableGenerator.DIGEST); Attribute attr = new Attribute(CMSAttributes.messageDigest, new DERSet(new DEROctetString(messageDigest))); std.put(attr.getAttrType(), attr); } return std; } /** * @param parameters source parameters * @return the populated attribute table */ public AttributeTable getAttributes(Map parameters) { return new AttributeTable(createStandardAttributeTable(parameters)); } } bouncycastle-1.49.orig/j2me/org/bouncycastle/cms/KeyAgreeRecipientInformation.java0000644000175000017500000001140711731764001027745 0ustar ebourgebourgpackage org.bouncycastle.cms; import java.io.IOException; import java.util.List; import org.bouncycastle.asn1.ASN1OctetString; import org.bouncycastle.asn1.ASN1Sequence; import org.bouncycastle.asn1.cms.IssuerAndSerialNumber; import org.bouncycastle.asn1.cms.KeyAgreeRecipientIdentifier; import org.bouncycastle.asn1.cms.KeyAgreeRecipientInfo; import org.bouncycastle.asn1.cms.OriginatorIdentifierOrKey; import org.bouncycastle.asn1.cms.OriginatorPublicKey; import org.bouncycastle.asn1.cms.RecipientEncryptedKey; import org.bouncycastle.asn1.cms.RecipientKeyIdentifier; import org.bouncycastle.asn1.x509.AlgorithmIdentifier; import org.bouncycastle.asn1.x509.SubjectKeyIdentifier; import org.bouncycastle.asn1.x509.SubjectPublicKeyInfo; /** * the RecipientInfo class for a recipient who has been sent a message * encrypted using key agreement. */ public class KeyAgreeRecipientInformation extends RecipientInformation { private KeyAgreeRecipientInfo info; private ASN1OctetString encryptedKey; static void readRecipientInfo(List infos, KeyAgreeRecipientInfo info, AlgorithmIdentifier messageAlgorithm, CMSSecureReadable secureReadable, AuthAttributesProvider additionalData) { ASN1Sequence s = info.getRecipientEncryptedKeys(); for (int i = 0; i < s.size(); ++i) { RecipientEncryptedKey id = RecipientEncryptedKey.getInstance( s.getObjectAt(i)); RecipientId rid; KeyAgreeRecipientIdentifier karid = id.getIdentifier(); IssuerAndSerialNumber iAndSN = karid.getIssuerAndSerialNumber(); if (iAndSN != null) { rid = new KeyAgreeRecipientId(iAndSN.getName(), iAndSN.getSerialNumber().getValue()); } else { RecipientKeyIdentifier rKeyID = karid.getRKeyID(); // Note: 'date' and 'other' fields of RecipientKeyIdentifier appear to be only informational rid = new KeyAgreeRecipientId(rKeyID.getSubjectKeyIdentifier().getOctets()); } infos.add(new KeyAgreeRecipientInformation(info, rid, id.getEncryptedKey(), messageAlgorithm, secureReadable, additionalData)); } } KeyAgreeRecipientInformation( KeyAgreeRecipientInfo info, RecipientId rid, ASN1OctetString encryptedKey, AlgorithmIdentifier messageAlgorithm, CMSSecureReadable secureReadable, AuthAttributesProvider additionalData) { super(info.getKeyEncryptionAlgorithm(), messageAlgorithm, secureReadable, additionalData); this.info = info; this.rid = rid; this.encryptedKey = encryptedKey; } private SubjectPublicKeyInfo getSenderPublicKeyInfo(AlgorithmIdentifier recKeyAlgId, OriginatorIdentifierOrKey originator) throws CMSException, IOException { OriginatorPublicKey opk = originator.getOriginatorKey(); if (opk != null) { return getPublicKeyInfoFromOriginatorPublicKey(recKeyAlgId, opk); } OriginatorId origID; IssuerAndSerialNumber iAndSN = originator.getIssuerAndSerialNumber(); if (iAndSN != null) { origID = new OriginatorId(iAndSN.getName(), iAndSN.getSerialNumber().getValue()); } else { SubjectKeyIdentifier ski = originator.getSubjectKeyIdentifier(); origID = new OriginatorId(ski.getKeyIdentifier()); } return getPublicKeyInfoFromOriginatorId(origID); } private SubjectPublicKeyInfo getPublicKeyInfoFromOriginatorPublicKey(AlgorithmIdentifier recKeyAlgId, OriginatorPublicKey originatorPublicKey) { SubjectPublicKeyInfo pubInfo = new SubjectPublicKeyInfo( recKeyAlgId, originatorPublicKey.getPublicKey().getBytes()); return pubInfo; } private SubjectPublicKeyInfo getPublicKeyInfoFromOriginatorId(OriginatorId origID) throws CMSException { // TODO Support all alternatives for OriginatorIdentifierOrKey // see RFC 3852 6.2.2 throw new CMSException("No support for 'originator' as IssuerAndSerialNumber or SubjectKeyIdentifier"); } protected RecipientOperator getRecipientOperator(Recipient recipient) throws CMSException, IOException { KeyAgreeRecipient agreeRecipient = (KeyAgreeRecipient)recipient; AlgorithmIdentifier recKeyAlgId = agreeRecipient.getPrivateKeyAlgorithmIdentifier(); return ((KeyAgreeRecipient)recipient).getRecipientOperator(keyEncAlg, messageAlgorithm, getSenderPublicKeyInfo(recKeyAlgId, info.getOriginator()), info.getUserKeyingMaterial(), encryptedKey.getOctets()); } } bouncycastle-1.49.orig/j2me/org/bouncycastle/cms/SignerInfoGenerator.java0000644000175000017500000002150711732460753026124 0ustar ebourgebourgpackage org.bouncycastle.cms; import java.io.IOException; import java.io.OutputStream; import java.util.Collections; import java.util.HashMap; import java.util.Map; import org.bouncycastle.asn1.ASN1Encoding; import org.bouncycastle.asn1.ASN1ObjectIdentifier; import org.bouncycastle.asn1.ASN1Set; import org.bouncycastle.asn1.DERObjectIdentifier; import org.bouncycastle.asn1.DEROctetString; import org.bouncycastle.asn1.DERSet; import org.bouncycastle.asn1.cms.AttributeTable; import org.bouncycastle.asn1.cms.SignerIdentifier; import org.bouncycastle.asn1.cms.SignerInfo; import org.bouncycastle.asn1.x509.AlgorithmIdentifier; import org.bouncycastle.cert.X509CertificateHolder; import org.bouncycastle.operator.ContentSigner; import org.bouncycastle.operator.DefaultDigestAlgorithmIdentifierFinder; import org.bouncycastle.operator.DigestAlgorithmIdentifierFinder; import org.bouncycastle.operator.DigestCalculator; import org.bouncycastle.operator.DigestCalculatorProvider; import org.bouncycastle.operator.OperatorCreationException; import org.bouncycastle.util.Arrays; import org.bouncycastle.util.io.TeeOutputStream; public class SignerInfoGenerator { private final SignerIdentifier signerIdentifier; private final CMSAttributeTableGenerator sAttrGen; private final CMSAttributeTableGenerator unsAttrGen; private final ContentSigner signer; private final DigestCalculator digester; private final DigestAlgorithmIdentifierFinder digAlgFinder = new DefaultDigestAlgorithmIdentifierFinder(); private final CMSSignatureEncryptionAlgorithmFinder sigEncAlgFinder; private byte[] calculatedDigest = null; private X509CertificateHolder certHolder; SignerInfoGenerator( SignerIdentifier signerIdentifier, ContentSigner signer, DigestCalculatorProvider digesterProvider, CMSSignatureEncryptionAlgorithmFinder sigEncAlgFinder) throws OperatorCreationException { this(signerIdentifier, signer, digesterProvider, sigEncAlgFinder, false); } SignerInfoGenerator( SignerIdentifier signerIdentifier, ContentSigner signer, DigestCalculatorProvider digesterProvider, CMSSignatureEncryptionAlgorithmFinder sigEncAlgFinder, boolean isDirectSignature) throws OperatorCreationException { this.signerIdentifier = signerIdentifier; this.signer = signer; if (digesterProvider != null) { this.digester = digesterProvider.get(digAlgFinder.find(signer.getAlgorithmIdentifier())); } else { this.digester = null; } if (isDirectSignature) { this.sAttrGen = null; this.unsAttrGen = null; } else { this.sAttrGen = new DefaultSignedAttributeTableGenerator(); this.unsAttrGen = null; } this.sigEncAlgFinder = sigEncAlgFinder; } public SignerInfoGenerator( SignerInfoGenerator original, CMSAttributeTableGenerator sAttrGen, CMSAttributeTableGenerator unsAttrGen) { this.signerIdentifier = original.signerIdentifier; this.signer = original.signer; this.digester = original.digester; this.sigEncAlgFinder = original.sigEncAlgFinder; this.sAttrGen = sAttrGen; this.unsAttrGen = unsAttrGen; } SignerInfoGenerator( SignerIdentifier signerIdentifier, ContentSigner signer, DigestCalculatorProvider digesterProvider, CMSSignatureEncryptionAlgorithmFinder sigEncAlgFinder, CMSAttributeTableGenerator sAttrGen, CMSAttributeTableGenerator unsAttrGen) throws OperatorCreationException { this.signerIdentifier = signerIdentifier; this.signer = signer; if (digesterProvider != null) { this.digester = digesterProvider.get(digAlgFinder.find(signer.getAlgorithmIdentifier())); } else { this.digester = null; } this.sAttrGen = sAttrGen; this.unsAttrGen = unsAttrGen; this.sigEncAlgFinder = sigEncAlgFinder; } public boolean hasAssociatedCertificate() { return certHolder != null; } public X509CertificateHolder getAssociatedCertificate() { return certHolder; } public AlgorithmIdentifier getDigestAlgorithm() { if (digester != null) { return digester.getAlgorithmIdentifier(); } return digAlgFinder.find(signer.getAlgorithmIdentifier()); } public OutputStream getCalculatingOutputStream() { if (digester != null) { if (sAttrGen == null) { return new TeeOutputStream(digester.getOutputStream(), signer.getOutputStream()); } return digester.getOutputStream(); } else { return signer.getOutputStream(); } } public SignerInfo generate(ASN1ObjectIdentifier contentType) throws CMSException { try { /* RFC 3852 5.4 * The result of the message digest calculation process depends on * whether the signedAttrs field is present. When the field is absent, * the result is just the message digest of the content as described * * above. When the field is present, however, the result is the message * digest of the complete DER encoding of the SignedAttrs value * contained in the signedAttrs field. */ ASN1Set signedAttr = null; AlgorithmIdentifier digestAlg = null; if (sAttrGen != null) { digestAlg = digester.getAlgorithmIdentifier(); calculatedDigest = digester.getDigest(); Map parameters = getBaseParameters(contentType, digester.getAlgorithmIdentifier(), calculatedDigest); AttributeTable signed = sAttrGen.getAttributes(Collections.unmodifiableMap(parameters)); signedAttr = getAttributeSet(signed); // sig must be composed from the DER encoding. OutputStream sOut = signer.getOutputStream(); sOut.write(signedAttr.getEncoded(ASN1Encoding.DER)); sOut.close(); } else { if (digester != null) { digestAlg = digester.getAlgorithmIdentifier(); calculatedDigest = digester.getDigest(); } else { digestAlg = digAlgFinder.find(signer.getAlgorithmIdentifier()); calculatedDigest = null; } } byte[] sigBytes = signer.getSignature(); ASN1Set unsignedAttr = null; if (unsAttrGen != null) { Map parameters = getBaseParameters(contentType, digestAlg, calculatedDigest); parameters.put(CMSAttributeTableGenerator.SIGNATURE, Arrays.clone(sigBytes)); AttributeTable unsigned = unsAttrGen.getAttributes(Collections.unmodifiableMap(parameters)); unsignedAttr = getAttributeSet(unsigned); } AlgorithmIdentifier digestEncryptionAlgorithm = sigEncAlgFinder.findEncryptionAlgorithm(signer.getAlgorithmIdentifier()); return new SignerInfo(signerIdentifier, digestAlg, signedAttr, digestEncryptionAlgorithm, new DEROctetString(sigBytes), unsignedAttr); } catch (IOException e) { throw new CMSException("encoding error.", e); } } void setAssociatedCertificate(X509CertificateHolder certHolder) { this.certHolder = certHolder; } private ASN1Set getAttributeSet( AttributeTable attr) { if (attr != null) { return new DERSet(attr.toASN1EncodableVector()); } return null; } private Map getBaseParameters(DERObjectIdentifier contentType, AlgorithmIdentifier digAlgId, byte[] hash) { Map param = new HashMap(); if (contentType != null) { param.put(CMSAttributeTableGenerator.CONTENT_TYPE, contentType); } param.put(CMSAttributeTableGenerator.DIGEST_ALGORITHM_IDENTIFIER, digAlgId); param.put(CMSAttributeTableGenerator.DIGEST, Arrays.clone(hash)); return param; } public byte[] getCalculatedDigest() { if (calculatedDigest != null) { return Arrays.clone(calculatedDigest); } return null; } public CMSAttributeTableGenerator getSignedAttributeTableGenerator() { return sAttrGen; } public CMSAttributeTableGenerator getUnsignedAttributeTableGenerator() { return unsAttrGen; } } bouncycastle-1.49.orig/j2me/org/bouncycastle/cms/CMSEnvelopedGenerator.java0000644000175000017500000000743511731765272026354 0ustar ebourgebourgpackage org.bouncycastle.cms; import java.security.SecureRandom; import java.util.ArrayList; import java.util.List; import org.bouncycastle.asn1.cms.OriginatorInfo; import org.bouncycastle.asn1.kisa.KISAObjectIdentifiers; import org.bouncycastle.asn1.nist.NISTObjectIdentifiers; import org.bouncycastle.asn1.ntt.NTTObjectIdentifiers; import org.bouncycastle.asn1.pkcs.PKCSObjectIdentifiers; import org.bouncycastle.asn1.x9.X9ObjectIdentifiers; /** * General class for generating a CMS enveloped-data message. */ public class CMSEnvelopedGenerator { public static final String DES_EDE3_CBC = PKCSObjectIdentifiers.des_EDE3_CBC.getId(); public static final String RC2_CBC = PKCSObjectIdentifiers.RC2_CBC.getId(); public static final String IDEA_CBC = "1.3.6.1.4.1.188.7.1.1.2"; public static final String CAST5_CBC = "1.2.840.113533.7.66.10"; public static final String AES128_CBC = NISTObjectIdentifiers.id_aes128_CBC.getId(); public static final String AES192_CBC = NISTObjectIdentifiers.id_aes192_CBC.getId(); public static final String AES256_CBC = NISTObjectIdentifiers.id_aes256_CBC.getId(); public static final String CAMELLIA128_CBC = NTTObjectIdentifiers.id_camellia128_cbc.getId(); public static final String CAMELLIA192_CBC = NTTObjectIdentifiers.id_camellia192_cbc.getId(); public static final String CAMELLIA256_CBC = NTTObjectIdentifiers.id_camellia256_cbc.getId(); public static final String SEED_CBC = KISAObjectIdentifiers.id_seedCBC.getId(); public static final String DES_EDE3_WRAP = PKCSObjectIdentifiers.id_alg_CMS3DESwrap.getId(); public static final String AES128_WRAP = NISTObjectIdentifiers.id_aes128_wrap.getId(); public static final String AES192_WRAP = NISTObjectIdentifiers.id_aes192_wrap.getId(); public static final String AES256_WRAP = NISTObjectIdentifiers.id_aes256_wrap.getId(); public static final String CAMELLIA128_WRAP = NTTObjectIdentifiers.id_camellia128_wrap.getId(); public static final String CAMELLIA192_WRAP = NTTObjectIdentifiers.id_camellia192_wrap.getId(); public static final String CAMELLIA256_WRAP = NTTObjectIdentifiers.id_camellia256_wrap.getId(); public static final String SEED_WRAP = KISAObjectIdentifiers.id_npki_app_cmsSeed_wrap.getId(); public static final String ECDH_SHA1KDF = X9ObjectIdentifiers.dhSinglePass_stdDH_sha1kdf_scheme.getId(); public static final String ECMQV_SHA1KDF = X9ObjectIdentifiers.mqvSinglePass_sha1kdf_scheme.getId(); final List oldRecipientInfoGenerators = new ArrayList(); final List recipientInfoGenerators = new ArrayList(); protected CMSAttributeTableGenerator unprotectedAttributeGenerator = null; final SecureRandom rand; protected OriginatorInfo originatorInfo; /** * base constructor */ public CMSEnvelopedGenerator() { this(new SecureRandom()); } /** * constructor allowing specific source of randomness * @param rand instance of SecureRandom to use */ public CMSEnvelopedGenerator( SecureRandom rand) { this.rand = rand; } public void setUnprotectedAttributeGenerator(CMSAttributeTableGenerator unprotectedAttributeGenerator) { this.unprotectedAttributeGenerator = unprotectedAttributeGenerator; } public void setOriginatorInfo(OriginatorInformation originatorInfo) { this.originatorInfo = originatorInfo.toASN1Structure(); } /** * Add a generator to produce the recipient info required. * * @param recipientGenerator a generator of a recipient info object. */ public void addRecipientInfoGenerator(RecipientInfoGenerator recipientGenerator) { recipientInfoGenerators.add(recipientGenerator); } } bouncycastle-1.49.orig/j2me/org/bouncycastle/cms/CMSSignedDataParser.java0000644000175000017500000005227512150050436025727 0ustar ebourgebourgpackage org.bouncycastle.cms; import java.io.ByteArrayInputStream; import java.io.IOException; import java.io.InputStream; import java.io.OutputStream; import java.util.ArrayList; import java.util.HashMap; import java.util.Iterator; import java.util.List; import java.util.Map; import org.bouncycastle.asn1.ASN1Encodable; import org.bouncycastle.asn1.ASN1EncodableVector; import org.bouncycastle.asn1.ASN1Generator; import org.bouncycastle.asn1.ASN1ObjectIdentifier; import org.bouncycastle.asn1.ASN1OctetStringParser; import org.bouncycastle.asn1.ASN1SequenceParser; import org.bouncycastle.asn1.ASN1Set; import org.bouncycastle.asn1.ASN1SetParser; import org.bouncycastle.asn1.ASN1StreamParser; import org.bouncycastle.asn1.BERSequenceGenerator; import org.bouncycastle.asn1.BERSetParser; import org.bouncycastle.asn1.BERTaggedObject; import org.bouncycastle.asn1.BERTags; import org.bouncycastle.asn1.DERSet; import org.bouncycastle.asn1.DERTaggedObject; import org.bouncycastle.asn1.cms.CMSObjectIdentifiers; import org.bouncycastle.asn1.cms.ContentInfoParser; import org.bouncycastle.asn1.cms.SignedDataParser; import org.bouncycastle.asn1.cms.SignerInfo; import org.bouncycastle.asn1.x509.AlgorithmIdentifier; import org.bouncycastle.cert.jcajce.JcaCertStoreBuilder; import org.bouncycastle.operator.DigestCalculator; import org.bouncycastle.operator.DigestCalculatorProvider; import org.bouncycastle.operator.OperatorCreationException; import org.bouncycastle.operator.bc.BcDigestCalculatorProvider; import org.bouncycastle.util.Store; import org.bouncycastle.util.io.Streams; import org.bouncycastle.x509.NoSuchStoreException; import org.bouncycastle.x509.X509Store; /** * Parsing class for an CMS Signed Data object from an input stream. *

    * Note: that because we are in a streaming mode only one signer can be tried and it is important * that the methods on the parser are called in the appropriate order. *

    *

    * A simple example of usage for an encapsulated signature. *

    *

    * Two notes: first, in the example below the validity of * the certificate isn't verified, just the fact that one of the certs * matches the given signer, and, second, because we are in a streaming * mode the order of the operations is important. *

    *
     *      CMSSignedDataParser     sp = new CMSSignedDataParser(new JcaDigestCalculatorProviderBuilder().setProvider("BC").build(), encapSigData);
     *
     *      sp.getSignedContent().drain();
     *
     *      Store                   certStore = sp.getCertificates();
     *      SignerInformationStore  signers = sp.getSignerInfos();
     *      
     *      Collection              c = signers.getSigners();
     *      Iterator                it = c.iterator();
     *
     *      while (it.hasNext())
     *      {
     *          SignerInformation   signer = (SignerInformation)it.next();
     *          Collection          certCollection = certStore.getMatches(signer.getSID());
     *
     *          Iterator        certIt = certCollection.iterator();
     *          X509CertificateHolder cert = (X509CertificateHolder)certIt.next();
     *
     *          System.out.println("verify returns: " + signer.verify(new JcaSimpleSignerInfoVerifierBuilder().setProvider("BC").build(cert)));
     *      }
     * 
    * Note also: this class does not introduce buffering - if you are processing large files you should create * the parser with: *
     *          CMSSignedDataParser     ep = new CMSSignedDataParser(new BufferedInputStream(encapSigData, bufSize));
     *  
    * where bufSize is a suitably large buffer size. */ public class CMSSignedDataParser extends CMSContentInfoParser { private static final CMSSignedHelper HELPER = CMSSignedHelper.INSTANCE; private SignedDataParser _signedData; private ASN1ObjectIdentifier _signedContentType; private CMSTypedStream _signedContent; private Map digests; private SignerInformationStore _signerInfoStore; private X509Store _attributeStore; private ASN1Set _certSet, _crlSet; private boolean _isCertCrlParsed; private X509Store _certificateStore; private X509Store _crlStore; public CMSSignedDataParser( DigestCalculatorProvider digestCalculatorProvider, byte[] sigBlock) throws CMSException { this(digestCalculatorProvider, new ByteArrayInputStream(sigBlock)); } public CMSSignedDataParser( DigestCalculatorProvider digestCalculatorProvider, CMSTypedStream signedContent, byte[] sigBlock) throws CMSException { this(digestCalculatorProvider, signedContent, new ByteArrayInputStream(sigBlock)); } private static DigestCalculatorProvider createDefaultDigestProvider() throws CMSException { return new BcDigestCalculatorProvider(); } /** * base constructor - with encapsulated content */ public CMSSignedDataParser( DigestCalculatorProvider digestCalculatorProvider, InputStream sigData) throws CMSException { this(digestCalculatorProvider, null, sigData); } /** * base constructor * * @param digestCalculatorProvider for generating accumulating digests * @param signedContent the content that was signed. * @param sigData the signature object stream. */ public CMSSignedDataParser( DigestCalculatorProvider digestCalculatorProvider, CMSTypedStream signedContent, InputStream sigData) throws CMSException { super(sigData); try { _signedContent = signedContent; _signedData = SignedDataParser.getInstance(_contentInfo.getContent(BERTags.SEQUENCE)); digests = new HashMap(); ASN1SetParser digAlgs = _signedData.getDigestAlgorithms(); ASN1Encodable o; while ((o = digAlgs.readObject()) != null) { AlgorithmIdentifier algId = AlgorithmIdentifier.getInstance(o); try { DigestCalculator calculator = digestCalculatorProvider.get(algId); if (calculator != null) { this.digests.put(algId.getAlgorithm(), calculator); } } catch (OperatorCreationException e) { // ignore } } // // If the message is simply a certificate chain message getContent() may return null. // ContentInfoParser cont = _signedData.getEncapContentInfo(); ASN1OctetStringParser octs = (ASN1OctetStringParser) cont.getContent(BERTags.OCTET_STRING); if (octs != null) { CMSTypedStream ctStr = new CMSTypedStream( cont.getContentType().getId(), octs.getOctetStream()); if (_signedContent == null) { _signedContent = ctStr; } else { // // content passed in, need to read past empty encapsulated content info object if present // ctStr.drain(); } } if (signedContent == null) { _signedContentType = cont.getContentType(); } else { _signedContentType = _signedContent.getContentType(); } } catch (IOException e) { throw new CMSException("io exception: " + e.getMessage(), e); } if (digests.isEmpty()) { throw new CMSException("no digests could be created for message."); } } /** * Return the version number for the SignedData object * * @return the version number */ public int getVersion() { return _signedData.getVersion().getValue().intValue(); } /** * return the collection of signers that are associated with the * signatures for the message. * @throws CMSException */ public SignerInformationStore getSignerInfos() throws CMSException { if (_signerInfoStore == null) { populateCertCrlSets(); List signerInfos = new ArrayList(); Map hashes = new HashMap(); Iterator it = digests.keySet().iterator(); while (it.hasNext()) { Object digestKey = it.next(); hashes.put(digestKey, ((DigestCalculator)digests.get(digestKey)).getDigest()); } try { ASN1SetParser s = _signedData.getSignerInfos(); ASN1Encodable o; while ((o = s.readObject()) != null) { SignerInfo info = SignerInfo.getInstance(o.toASN1Primitive()); byte[] hash = (byte[])hashes.get(info.getDigestAlgorithm().getAlgorithm()); signerInfos.add(new SignerInformation(info, _signedContentType, null, hash)); } } catch (IOException e) { throw new CMSException("io exception: " + e.getMessage(), e); } _signerInfoStore = new SignerInformationStore(signerInfos); } return _signerInfoStore; } /** * Return any X.509 certificate objects in this SignedData structure as a Store of X509CertificateHolder objects. * * @return a Store of X509CertificateHolder objects. */ public Store getCertificates() throws CMSException { populateCertCrlSets(); return HELPER.getCertificates(_certSet); } /** * Return any X.509 CRL objects in this SignedData structure as a Store of X509CRLHolder objects. * * @return a Store of X509CRLHolder objects. */ public Store getCRLs() throws CMSException { populateCertCrlSets(); return HELPER.getCRLs(_crlSet); } /** * Return any X.509 attribute certificate objects in this SignedData structure as a Store of X509AttributeCertificateHolder objects. * * @return a Store of X509AttributeCertificateHolder objects. */ public Store getAttributeCertificates() throws CMSException { populateCertCrlSets(); return HELPER.getAttributeCertificates(_certSet); } /** * Return any OtherRevocationInfo OtherRevInfo objects of the type indicated by otherRevocationInfoFormat in * this SignedData structure. * * @param otherRevocationInfoFormat OID of the format type been looked for. * * @return a Store of ASN1Encodable objects representing any objects of otherRevocationInfoFormat found. */ public Store getOtherRevocationInfo(ASN1ObjectIdentifier otherRevocationInfoFormat) throws CMSException { populateCertCrlSets(); return HELPER.getOtherRevocationInfo(otherRevocationInfoFormat, _crlSet); } private void populateCertCrlSets() throws CMSException { if (_isCertCrlParsed) { return; } _isCertCrlParsed = true; try { // care! Streaming - these must be done in exactly this order. _certSet = getASN1Set(_signedData.getCertificates()); _crlSet = getASN1Set(_signedData.getCrls()); } catch (IOException e) { throw new CMSException("problem parsing cert/crl sets", e); } } /** * Return the a string representation of the OID associated with the * encapsulated content info structure carried in the signed data. * * @return the OID for the content type. */ public String getSignedContentTypeOID() { return _signedContentType.getId(); } public CMSTypedStream getSignedContent() { if (_signedContent == null) { return null; } InputStream digStream = CMSUtils.attachDigestsToInputStream( digests.values(), _signedContent.getContentStream()); return new CMSTypedStream(_signedContent.getContentType(), digStream); } /** * Replace the signerinformation store associated with the passed * in message contained in the stream original with the new one passed in. * You would probably only want to do this if you wanted to change the unsigned * attributes associated with a signer, or perhaps delete one. *

    * The output stream is returned unclosed. *

    * @param original the signed data stream to be used as a base. * @param signerInformationStore the new signer information store to use. * @param out the stream to write the new signed data object to. * @return out. */ public static OutputStream replaceSigners( InputStream original, SignerInformationStore signerInformationStore, OutputStream out) throws CMSException, IOException { ASN1StreamParser in = new ASN1StreamParser(original); ContentInfoParser contentInfo = new ContentInfoParser((ASN1SequenceParser)in.readObject()); SignedDataParser signedData = SignedDataParser.getInstance(contentInfo.getContent(BERTags.SEQUENCE)); BERSequenceGenerator sGen = new BERSequenceGenerator(out); sGen.addObject(CMSObjectIdentifiers.signedData); BERSequenceGenerator sigGen = new BERSequenceGenerator(sGen.getRawOutputStream(), 0, true); // version number sigGen.addObject(signedData.getVersion()); // digests signedData.getDigestAlgorithms().toASN1Primitive(); // skip old ones ASN1EncodableVector digestAlgs = new ASN1EncodableVector(); for (Iterator it = signerInformationStore.getSigners().iterator(); it.hasNext();) { SignerInformation signer = (SignerInformation)it.next(); digestAlgs.add(CMSSignedHelper.INSTANCE.fixAlgID(signer.getDigestAlgorithmID())); } sigGen.getRawOutputStream().write(new DERSet(digestAlgs).getEncoded()); // encap content info ContentInfoParser encapContentInfo = signedData.getEncapContentInfo(); BERSequenceGenerator eiGen = new BERSequenceGenerator(sigGen.getRawOutputStream()); eiGen.addObject(encapContentInfo.getContentType()); pipeEncapsulatedOctetString(encapContentInfo, eiGen.getRawOutputStream()); eiGen.close(); writeSetToGeneratorTagged(sigGen, signedData.getCertificates(), 0); writeSetToGeneratorTagged(sigGen, signedData.getCrls(), 1); ASN1EncodableVector signerInfos = new ASN1EncodableVector(); for (Iterator it = signerInformationStore.getSigners().iterator(); it.hasNext();) { SignerInformation signer = (SignerInformation)it.next(); signerInfos.add(signer.toASN1Structure()); } sigGen.getRawOutputStream().write(new DERSet(signerInfos).getEncoded()); sigGen.close(); sGen.close(); return out; } /** * Replace the certificate and CRL information associated with this * CMSSignedData object with the new one passed in. *

    * The output stream is returned unclosed. *

    * @param original the signed data stream to be used as a base. * @param certs new certificates to be used, if any. * @param crls new CRLs to be used, if any. * @param attrCerts new attribute certificates to be used, if any. * @param out the stream to write the new signed data object to. * @return out. * @exception CMSException if there is an error processing the CertStore */ public static OutputStream replaceCertificatesAndCRLs( InputStream original, Store certs, Store crls, Store attrCerts, OutputStream out) throws CMSException, IOException { ASN1StreamParser in = new ASN1StreamParser(original); ContentInfoParser contentInfo = new ContentInfoParser((ASN1SequenceParser)in.readObject()); SignedDataParser signedData = SignedDataParser.getInstance(contentInfo.getContent(BERTags.SEQUENCE)); BERSequenceGenerator sGen = new BERSequenceGenerator(out); sGen.addObject(CMSObjectIdentifiers.signedData); BERSequenceGenerator sigGen = new BERSequenceGenerator(sGen.getRawOutputStream(), 0, true); // version number sigGen.addObject(signedData.getVersion()); // digests sigGen.getRawOutputStream().write(signedData.getDigestAlgorithms().toASN1Primitive().getEncoded()); // encap content info ContentInfoParser encapContentInfo = signedData.getEncapContentInfo(); BERSequenceGenerator eiGen = new BERSequenceGenerator(sigGen.getRawOutputStream()); eiGen.addObject(encapContentInfo.getContentType()); pipeEncapsulatedOctetString(encapContentInfo, eiGen.getRawOutputStream()); eiGen.close(); // // skip existing certs and CRLs // getASN1Set(signedData.getCertificates()); getASN1Set(signedData.getCrls()); // // replace the certs and crls in the SignedData object // if (certs != null || attrCerts != null) { List certificates = new ArrayList(); if (certs != null) { certificates.addAll(CMSUtils.getCertificatesFromStore(certs)); } if (attrCerts != null) { certificates.addAll(CMSUtils.getAttributeCertificatesFromStore(attrCerts)); } ASN1Set asn1Certs = CMSUtils.createBerSetFromList(certificates); if (asn1Certs.size() > 0) { sigGen.getRawOutputStream().write(new DERTaggedObject(false, 0, asn1Certs).getEncoded()); } } if (crls != null) { ASN1Set asn1Crls = CMSUtils.createBerSetFromList(CMSUtils.getCRLsFromStore(crls)); if (asn1Crls.size() > 0) { sigGen.getRawOutputStream().write(new DERTaggedObject(false, 1, asn1Crls).getEncoded()); } } sigGen.getRawOutputStream().write(signedData.getSignerInfos().toASN1Primitive().getEncoded()); sigGen.close(); sGen.close(); return out; } private static void writeSetToGeneratorTagged( ASN1Generator asn1Gen, ASN1SetParser asn1SetParser, int tagNo) throws IOException { ASN1Set asn1Set = getASN1Set(asn1SetParser); if (asn1Set != null) { if (asn1SetParser instanceof BERSetParser) { asn1Gen.getRawOutputStream().write(new BERTaggedObject(false, tagNo, asn1Set).getEncoded()); } else { asn1Gen.getRawOutputStream().write(new DERTaggedObject(false, tagNo, asn1Set).getEncoded()); } } } private static ASN1Set getASN1Set( ASN1SetParser asn1SetParser) { return asn1SetParser == null ? null : ASN1Set.getInstance(asn1SetParser.toASN1Primitive()); } private static void pipeEncapsulatedOctetString(ContentInfoParser encapContentInfo, OutputStream rawOutputStream) throws IOException { ASN1OctetStringParser octs = (ASN1OctetStringParser) encapContentInfo.getContent(BERTags.OCTET_STRING); if (octs != null) { pipeOctetString(octs, rawOutputStream); } // BERTaggedObjectParser contentObject = (BERTaggedObjectParser)encapContentInfo.getContentObject(); // if (contentObject != null) // { // // Handle IndefiniteLengthInputStream safely // InputStream input = ASN1StreamParser.getSafeRawInputStream(contentObject.getContentStream(true)); // // // TODO BerTaggedObjectGenerator? // BEROutputStream berOut = new BEROutputStream(rawOutputStream); // berOut.write(DERTags.CONSTRUCTED | DERTags.TAGGED | 0); // berOut.write(0x80); // // pipeRawOctetString(input, rawOutputStream); // // berOut.write(0x00); // berOut.write(0x00); // // input.close(); // } } private static void pipeOctetString( ASN1OctetStringParser octs, OutputStream output) throws IOException { // TODO Allow specification of a specific fragment size? OutputStream outOctets = CMSUtils.createBEROctetOutputStream( output, 0, true, 0); Streams.pipeAll(octs.getOctetStream(), outOctets); outOctets.close(); } // private static void pipeRawOctetString( // InputStream rawInput, // OutputStream rawOutput) // throws IOException // { // InputStream tee = new TeeInputStream(rawInput, rawOutput); // ASN1StreamParser sp = new ASN1StreamParser(tee); // ASN1OctetStringParser octs = (ASN1OctetStringParser)sp.readObject(); // Streams.drain(octs.getOctetStream()); // } } bouncycastle-1.49.orig/j2me/org/bouncycastle/cms/CMSEnvelopedDataParser.java0000644000175000017500000001466511731763433026454 0ustar ebourgebourgpackage org.bouncycastle.cms; import java.io.ByteArrayInputStream; import java.io.IOException; import java.io.InputStream; import org.bouncycastle.asn1.ASN1Encodable; import org.bouncycastle.asn1.ASN1EncodableVector; import org.bouncycastle.asn1.ASN1OctetStringParser; import org.bouncycastle.asn1.ASN1SequenceParser; import org.bouncycastle.asn1.ASN1Set; import org.bouncycastle.asn1.ASN1SetParser; import org.bouncycastle.asn1.BERTags; import org.bouncycastle.asn1.DERSet; import org.bouncycastle.asn1.cms.AttributeTable; import org.bouncycastle.asn1.cms.EncryptedContentInfoParser; import org.bouncycastle.asn1.cms.EnvelopedDataParser; import org.bouncycastle.asn1.cms.OriginatorInfo; import org.bouncycastle.asn1.x509.AlgorithmIdentifier; /** * Parsing class for an CMS Enveloped Data object from an input stream. *

    * Note: that because we are in a streaming mode only one recipient can be tried and it is important * that the methods on the parser are called in the appropriate order. *

    *

    * Example of use - assuming the first recipient matches the private key we have. *

     *      CMSEnvelopedDataParser     ep = new CMSEnvelopedDataParser(inputStream);
     *
     *      RecipientInformationStore  recipients = ep.getRecipientInfos();
     *
     *      Collection  c = recipients.getRecipients();
     *      Iterator    it = c.iterator();
     *      
     *      if (it.hasNext())
     *      {
     *          RecipientInformation   recipient = (RecipientInformation)it.next();
     *
     *          CMSTypedStream recData = recipient.getContentStream(new JceKeyTransEnvelopedRecipient(privateKey).setProvider("BC"));
     *          
     *          processDataStream(recData.getContentStream());
     *      }
     *  
    * Note: this class does not introduce buffering - if you are processing large files you should create * the parser with: *
     *          CMSEnvelopedDataParser     ep = new CMSEnvelopedDataParser(new BufferedInputStream(inputStream, bufSize));
     *  
    * where bufSize is a suitably large buffer size. */ public class CMSEnvelopedDataParser extends CMSContentInfoParser { RecipientInformationStore recipientInfoStore; EnvelopedDataParser envelopedData; private AlgorithmIdentifier encAlg; private AttributeTable unprotectedAttributes; private boolean attrNotRead; private OriginatorInformation originatorInfo; public CMSEnvelopedDataParser( byte[] envelopedData) throws CMSException, IOException { this(new ByteArrayInputStream(envelopedData)); } public CMSEnvelopedDataParser( InputStream envelopedData) throws CMSException, IOException { super(envelopedData); this.attrNotRead = true; this.envelopedData = new EnvelopedDataParser((ASN1SequenceParser)_contentInfo.getContent(BERTags.SEQUENCE)); // TODO Validate version? //DERInteger version = this._envelopedData.getVersion(); OriginatorInfo info = this.envelopedData.getOriginatorInfo(); if (info != null) { this.originatorInfo = new OriginatorInformation(info); } // // read the recipients // ASN1Set recipientInfos = ASN1Set.getInstance(this.envelopedData.getRecipientInfos().toASN1Primitive()); // // read the encrypted content info // EncryptedContentInfoParser encInfo = this.envelopedData.getEncryptedContentInfo(); this.encAlg = encInfo.getContentEncryptionAlgorithm(); CMSReadable readable = new CMSProcessableInputStream( ((ASN1OctetStringParser)encInfo.getEncryptedContent(BERTags.OCTET_STRING)).getOctetStream()); CMSSecureReadable secureReadable = new CMSEnvelopedHelper.CMSEnvelopedSecureReadable( this.encAlg, readable); // // build the RecipientInformationStore // this.recipientInfoStore = CMSEnvelopedHelper.buildRecipientInformationStore( recipientInfos, this.encAlg, secureReadable); } /** * return the object identifier for the content encryption algorithm. */ public String getEncryptionAlgOID() { return encAlg.getAlgorithm().toString(); } /** * return the ASN.1 encoded encryption algorithm parameters, or null if * there aren't any. */ public byte[] getEncryptionAlgParams() { try { return encodeObj(encAlg.getParameters()); } catch (Exception e) { throw new RuntimeException("exception getting encryption parameters " + e); } } /** * Return the content encryption algorithm details for the data in this object. * * @return AlgorithmIdentifier representing the content encryption algorithm. */ public AlgorithmIdentifier getContentEncryptionAlgorithm() { return encAlg; } /** * Return the originator information associated with this message if present. * * @return OriginatorInformation, null if not present. */ public OriginatorInformation getOriginatorInfo() { return originatorInfo; } /** * return a store of the intended recipients for this message */ public RecipientInformationStore getRecipientInfos() { return recipientInfoStore; } /** * return a table of the unprotected attributes indexed by * the OID of the attribute. * @exception IOException */ public AttributeTable getUnprotectedAttributes() throws IOException { if (unprotectedAttributes == null && attrNotRead) { ASN1SetParser set = envelopedData.getUnprotectedAttrs(); attrNotRead = false; if (set != null) { ASN1EncodableVector v = new ASN1EncodableVector(); ASN1Encodable o; while ((o = set.readObject()) != null) { ASN1SequenceParser seq = (ASN1SequenceParser)o; v.add(seq.toASN1Primitive()); } unprotectedAttributes = new AttributeTable(new DERSet(v)); } } return unprotectedAttributes; } private byte[] encodeObj( ASN1Encodable obj) throws IOException { if (obj != null) { return obj.toASN1Primitive().getEncoded(); } return null; } } bouncycastle-1.49.orig/j2me/org/bouncycastle/cms/CMSEnvelopedDataGenerator.java0000644000175000017500000001063311731763201027126 0ustar ebourgebourgpackage org.bouncycastle.cms; import java.io.ByteArrayOutputStream; import java.io.IOException; import java.io.OutputStream; import java.security.SecureRandom; import java.util.HashMap; import java.util.Iterator; import org.bouncycastle.asn1.ASN1EncodableVector; import org.bouncycastle.asn1.ASN1OctetString; import org.bouncycastle.asn1.ASN1Set; import org.bouncycastle.asn1.BEROctetString; import org.bouncycastle.asn1.BERSet; import org.bouncycastle.asn1.DERSet; import org.bouncycastle.asn1.cms.AttributeTable; import org.bouncycastle.asn1.cms.CMSObjectIdentifiers; import org.bouncycastle.asn1.cms.ContentInfo; import org.bouncycastle.asn1.cms.EncryptedContentInfo; import org.bouncycastle.asn1.cms.EnvelopedData; import org.bouncycastle.asn1.x509.AlgorithmIdentifier; import org.bouncycastle.operator.GenericKey; import org.bouncycastle.operator.OutputEncryptor; /** * General class for generating a CMS enveloped-data message. * * A simple example of usage. * *
     *       CMSTypedData msg     = new CMSProcessableByteArray("Hello World!".getBytes());
     *
     *       CMSEnvelopedDataGenerator edGen = new CMSEnvelopedDataGenerator();
     *
     *       edGen.addRecipientInfoGenerator(new JceKeyTransRecipientInfoGenerator(recipientCert).setProvider("BC"));
     *
     *       CMSEnvelopedData ed = edGen.generate(
     *                                       msg,
     *                                       new JceCMSContentEncryptorBuilder(CMSAlgorithm.DES_EDE3_CBC)
     *                                              .setProvider("BC").build());
     *
     * 
    */ public class CMSEnvelopedDataGenerator extends CMSEnvelopedGenerator { /** * base constructor */ public CMSEnvelopedDataGenerator() { } /** * constructor allowing specific source of randomness * @param rand instance of SecureRandom to use * @deprecated use no args constructor. */ public CMSEnvelopedDataGenerator( SecureRandom rand) { super(rand); } private CMSEnvelopedData doGenerate( CMSTypedData content, OutputEncryptor contentEncryptor) throws CMSException { if (!oldRecipientInfoGenerators.isEmpty()) { throw new IllegalStateException("can only use addRecipientGenerator() with this method"); } ASN1EncodableVector recipientInfos = new ASN1EncodableVector(); AlgorithmIdentifier encAlgId; ASN1OctetString encContent; ByteArrayOutputStream bOut = new ByteArrayOutputStream(); try { OutputStream cOut = contentEncryptor.getOutputStream(bOut); content.write(cOut); cOut.close(); } catch (IOException e) { throw new CMSException(""); } byte[] encryptedContent = bOut.toByteArray(); encAlgId = contentEncryptor.getAlgorithmIdentifier(); encContent = new BEROctetString(encryptedContent); GenericKey encKey = contentEncryptor.getKey(); for (Iterator it = recipientInfoGenerators.iterator(); it.hasNext();) { RecipientInfoGenerator recipient = (RecipientInfoGenerator)it.next(); recipientInfos.add(recipient.generate(encKey)); } EncryptedContentInfo eci = new EncryptedContentInfo( content.getContentType(), encAlgId, encContent); ASN1Set unprotectedAttrSet = null; if (unprotectedAttributeGenerator != null) { AttributeTable attrTable = unprotectedAttributeGenerator.getAttributes(new HashMap()); unprotectedAttrSet = new BERSet(attrTable.toASN1EncodableVector()); } ContentInfo contentInfo = new ContentInfo( CMSObjectIdentifiers.envelopedData, new EnvelopedData(originatorInfo, new DERSet(recipientInfos), eci, unprotectedAttrSet)); return new CMSEnvelopedData(contentInfo); } /** * generate an enveloped object that contains an CMS Enveloped Data * object using the given provider. * * @param content the content to be encrypted * @param contentEncryptor the symmetric key based encryptor to encrypt the content with. */ public CMSEnvelopedData generate( CMSTypedData content, OutputEncryptor contentEncryptor) throws CMSException { return doGenerate(content, contentEncryptor); } } bouncycastle-1.49.orig/j2me/org/bouncycastle/cms/RecipientInformation.java0000644000175000017500000001300711731764001026326 0ustar ebourgebourgpackage org.bouncycastle.cms; import java.io.ByteArrayInputStream; import java.io.IOException; import org.bouncycastle.asn1.ASN1Encodable; import org.bouncycastle.asn1.ASN1Encoding; import org.bouncycastle.asn1.x509.AlgorithmIdentifier; import org.bouncycastle.util.io.Streams; public abstract class RecipientInformation { protected RecipientId rid; protected AlgorithmIdentifier keyEncAlg; protected AlgorithmIdentifier messageAlgorithm; protected CMSSecureReadable secureReadable; private AuthAttributesProvider additionalData; private byte[] resultMac; private RecipientOperator operator; RecipientInformation( AlgorithmIdentifier keyEncAlg, AlgorithmIdentifier messageAlgorithm, CMSSecureReadable secureReadable, AuthAttributesProvider additionalData) { this.keyEncAlg = keyEncAlg; this.messageAlgorithm = messageAlgorithm; this.secureReadable = secureReadable; this.additionalData = additionalData; } public RecipientId getRID() { return rid; } private byte[] encodeObj( ASN1Encodable obj) throws IOException { if (obj != null) { return obj.toASN1Primitive().getEncoded(); } return null; } /** * Return the key encryption algorithm details for the key in this recipient. * * @return AlgorithmIdentifier representing the key encryption algorithm. */ public AlgorithmIdentifier getKeyEncryptionAlgorithm() { return keyEncAlg; } /** * return the object identifier for the key encryption algorithm. * * @return OID for key encryption algorithm. */ public String getKeyEncryptionAlgOID() { return keyEncAlg.getObjectId().getId(); } /** * return the ASN.1 encoded key encryption algorithm parameters, or null if * there aren't any. * * @return ASN.1 encoding of key encryption algorithm parameters. */ public byte[] getKeyEncryptionAlgParams() { try { return encodeObj(keyEncAlg.getParameters()); } catch (Exception e) { throw new RuntimeException("exception getting encryption parameters " + e); } } /** * Return the content digest calculated during the read of the content if one has been generated. This will * only happen if we are dealing with authenticated data and authenticated attributes are present. * * @return byte array containing the digest. */ public byte[] getContentDigest() { if (secureReadable instanceof CMSEnvelopedHelper.CMSDigestAuthenticatedSecureReadable) { return ((CMSEnvelopedHelper.CMSDigestAuthenticatedSecureReadable)secureReadable).getDigest(); } return null; } /** * Return the MAC calculated for the recipient. Note: this call is only meaningful once all * the content has been read. * * @return byte array containing the mac. */ public byte[] getMac() { if (resultMac == null) { if (operator.isMacBased()) { if (additionalData != null) { try { Streams.drain(operator.getInputStream(new ByteArrayInputStream(additionalData.getAuthAttributes().getEncoded(ASN1Encoding.DER)))); } catch (IOException e) { e.printStackTrace(); //To change body of catch statement use File | Settings | File Templates. } } resultMac = operator.getMac(); } } return resultMac; } /** * Return the decrypted/encapsulated content in the EnvelopedData after recovering the content * encryption/MAC key using the passed in Recipient. * * @param recipient recipient object to use to recover content encryption key * @return the content inside the EnvelopedData this RecipientInformation is associated with. * @throws CMSException if the content-encryption/MAC key cannot be recovered. */ public byte[] getContent( Recipient recipient) throws CMSException { try { return CMSUtils.streamToByteArray(getContentStream(recipient).getContentStream()); } catch (IOException e) { throw new CMSException("unable to parse internal stream: " + e.getMessage(), e); } } /** * Return a CMSTypedStream representing the content in the EnvelopedData after recovering the content * encryption/MAC key using the passed in Recipient. * * @param recipient recipient object to use to recover content encryption key * @return the content inside the EnvelopedData this RecipientInformation is associated with. * @throws CMSException if the content-encryption/MAC key cannot be recovered. */ public CMSTypedStream getContentStream(Recipient recipient) throws CMSException, IOException { operator = getRecipientOperator(recipient); if (additionalData != null) { return new CMSTypedStream(secureReadable.getInputStream()); } return new CMSTypedStream(operator.getInputStream(secureReadable.getInputStream())); } protected abstract RecipientOperator getRecipientOperator(Recipient recipient) throws CMSException, IOException; } bouncycastle-1.49.orig/j2me/org/bouncycastle/cms/CMSEnvelopedData.java0000644000175000017500000001343311731765024025265 0ustar ebourgebourgpackage org.bouncycastle.cms; import java.io.IOException; import java.io.InputStream; import org.bouncycastle.asn1.ASN1Encodable; import org.bouncycastle.asn1.ASN1Set; import org.bouncycastle.asn1.cms.AttributeTable; import org.bouncycastle.asn1.cms.ContentInfo; import org.bouncycastle.asn1.cms.EncryptedContentInfo; import org.bouncycastle.asn1.cms.EnvelopedData; import org.bouncycastle.asn1.x509.AlgorithmIdentifier; /** * containing class for an CMS Enveloped Data object *

    * Example of use - assuming the first recipient matches the private key we have. *

     *      CMSEnvelopedData     ed = new CMSEnvelopedData(inputStream);
     *
     *      RecipientInformationStore  recipients = ed.getRecipientInfos();
     *
     *      Collection  c = recipients.getRecipients();
     *      Iterator    it = c.iterator();
     *
     *      if (it.hasNext())
     *      {
     *          RecipientInformation   recipient = (RecipientInformation)it.next();
     *
     *          byte[] recData = recipient.getContent(new JceKeyTransEnvelopedRecipient(privateKey).setProvider("BC"));
     *
     *          processData(recData);
     *      }
     *  
    */ public class CMSEnvelopedData { RecipientInformationStore recipientInfoStore; ContentInfo contentInfo; private AlgorithmIdentifier encAlg; private ASN1Set unprotectedAttributes; private OriginatorInformation originatorInfo; public CMSEnvelopedData( byte[] envelopedData) throws CMSException { this(CMSUtils.readContentInfo(envelopedData)); } public CMSEnvelopedData( InputStream envelopedData) throws CMSException { this(CMSUtils.readContentInfo(envelopedData)); } /** * Construct a CMSEnvelopedData object from a content info object. * * @param contentInfo the contentInfo containing the CMS EnvelopedData object. * @throws CMSException in the case where malformed content is encountered. */ public CMSEnvelopedData( ContentInfo contentInfo) throws CMSException { this.contentInfo = contentInfo; try { EnvelopedData envData = EnvelopedData.getInstance(contentInfo.getContent()); if (envData.getOriginatorInfo() != null) { originatorInfo = new OriginatorInformation(envData.getOriginatorInfo()); } // // read the recipients // ASN1Set recipientInfos = envData.getRecipientInfos(); // // read the encrypted content info // EncryptedContentInfo encInfo = envData.getEncryptedContentInfo(); this.encAlg = encInfo.getContentEncryptionAlgorithm(); CMSReadable readable = new CMSProcessableByteArray(encInfo.getEncryptedContent().getOctets()); CMSSecureReadable secureReadable = new CMSEnvelopedHelper.CMSEnvelopedSecureReadable( this.encAlg, readable); // // build the RecipientInformationStore // this.recipientInfoStore = CMSEnvelopedHelper.buildRecipientInformationStore( recipientInfos, this.encAlg, secureReadable); this.unprotectedAttributes = envData.getUnprotectedAttrs(); } catch (ClassCastException e) { throw new CMSException("Malformed content.", e); } catch (IllegalArgumentException e) { throw new CMSException("Malformed content.", e); } } private byte[] encodeObj( ASN1Encodable obj) throws IOException { if (obj != null) { return obj.toASN1Primitive().getEncoded(); } return null; } /** * Return the originator information associated with this message if present. * * @return OriginatorInformation, null if not present. */ public OriginatorInformation getOriginatorInfo() { return originatorInfo; } /** * Return the content encryption algorithm details for the data in this object. * * @return AlgorithmIdentifier representing the content encryption algorithm. */ public AlgorithmIdentifier getContentEncryptionAlgorithm() { return encAlg; } /** * return the object identifier for the content encryption algorithm. */ public String getEncryptionAlgOID() { return encAlg.getAlgorithm().getId(); } /** * return the ASN.1 encoded encryption algorithm parameters, or null if * there aren't any. */ public byte[] getEncryptionAlgParams() { try { return encodeObj(encAlg.getParameters()); } catch (Exception e) { throw new RuntimeException("exception getting encryption parameters " + e); } } /** * return a store of the intended recipients for this message */ public RecipientInformationStore getRecipientInfos() { return recipientInfoStore; } /** * return the ContentInfo * @deprecated use toASN1Structure() */ public ContentInfo getContentInfo() { return contentInfo; } /** * return the ContentInfo */ public ContentInfo toASN1Structure() { return contentInfo; } /** * return a table of the unprotected attributes indexed by * the OID of the attribute. */ public AttributeTable getUnprotectedAttributes() { if (unprotectedAttributes == null) { return null; } return new AttributeTable(unprotectedAttributes); } /** * return the ASN.1 encoded representation of this object. */ public byte[] getEncoded() throws IOException { return contentInfo.getEncoded(); } } bouncycastle-1.49.orig/j2me/org/bouncycastle/cms/CMSSignedHelper.java0000644000175000017500000002574512150050436025122 0ustar ebourgebourgpackage org.bouncycastle.cms; import java.io.IOException; import java.util.ArrayList; import java.util.Collection; import java.util.Enumeration; import java.util.HashMap; import java.util.Iterator; import java.util.List; import java.util.Map; import org.bouncycastle.asn1.ASN1Encodable; import org.bouncycastle.asn1.ASN1ObjectIdentifier; import org.bouncycastle.asn1.ASN1Primitive; import org.bouncycastle.asn1.ASN1Sequence; import org.bouncycastle.asn1.ASN1Set; import org.bouncycastle.asn1.ASN1TaggedObject; import org.bouncycastle.asn1.DERNull; import org.bouncycastle.asn1.cms.OtherRevocationInfoFormat; import org.bouncycastle.asn1.cryptopro.CryptoProObjectIdentifiers; import org.bouncycastle.asn1.eac.EACObjectIdentifiers; import org.bouncycastle.asn1.nist.NISTObjectIdentifiers; import org.bouncycastle.asn1.oiw.OIWObjectIdentifiers; import org.bouncycastle.asn1.pkcs.PKCSObjectIdentifiers; import org.bouncycastle.asn1.teletrust.TeleTrusTObjectIdentifiers; import org.bouncycastle.asn1.x509.AlgorithmIdentifier; import org.bouncycastle.asn1.x509.AttributeCertificate; import org.bouncycastle.asn1.x509.Certificate; import org.bouncycastle.asn1.x509.CertificateList; import org.bouncycastle.asn1.x509.X509ObjectIdentifiers; import org.bouncycastle.asn1.x9.X9ObjectIdentifiers; import org.bouncycastle.cert.X509AttributeCertificateHolder; import org.bouncycastle.cert.X509CRLHolder; import org.bouncycastle.cert.X509CertificateHolder; import org.bouncycastle.util.CollectionStore; import org.bouncycastle.util.Store; class CMSSignedHelper { static final CMSSignedHelper INSTANCE = new CMSSignedHelper(); private static final Map encryptionAlgs = new HashMap(); private static final Map digestAlgs = new HashMap(); private static final Map digestAliases = new HashMap(); private static void addEntries(ASN1ObjectIdentifier alias, String digest, String encryption) { digestAlgs.put(alias.getId(), digest); encryptionAlgs.put(alias.getId(), encryption); } static { addEntries(NISTObjectIdentifiers.dsa_with_sha224, "SHA224", "DSA"); addEntries(NISTObjectIdentifiers.dsa_with_sha256, "SHA256", "DSA"); addEntries(NISTObjectIdentifiers.dsa_with_sha384, "SHA384", "DSA"); addEntries(NISTObjectIdentifiers.dsa_with_sha512, "SHA512", "DSA"); addEntries(OIWObjectIdentifiers.dsaWithSHA1, "SHA1", "DSA"); addEntries(OIWObjectIdentifiers.md4WithRSA, "MD4", "RSA"); addEntries(OIWObjectIdentifiers.md4WithRSAEncryption, "MD4", "RSA"); addEntries(OIWObjectIdentifiers.md5WithRSA, "MD5", "RSA"); addEntries(OIWObjectIdentifiers.sha1WithRSA, "SHA1", "RSA"); addEntries(PKCSObjectIdentifiers.md2WithRSAEncryption, "MD2", "RSA"); addEntries(PKCSObjectIdentifiers.md4WithRSAEncryption, "MD4", "RSA"); addEntries(PKCSObjectIdentifiers.md5WithRSAEncryption, "MD5", "RSA"); addEntries(PKCSObjectIdentifiers.sha1WithRSAEncryption, "SHA1", "RSA"); addEntries(PKCSObjectIdentifiers.sha224WithRSAEncryption, "SHA224", "RSA"); addEntries(PKCSObjectIdentifiers.sha256WithRSAEncryption, "SHA256", "RSA"); addEntries(PKCSObjectIdentifiers.sha384WithRSAEncryption, "SHA384", "RSA"); addEntries(PKCSObjectIdentifiers.sha512WithRSAEncryption, "SHA512", "RSA"); addEntries(X9ObjectIdentifiers.ecdsa_with_SHA1, "SHA1", "ECDSA"); addEntries(X9ObjectIdentifiers.ecdsa_with_SHA224, "SHA224", "ECDSA"); addEntries(X9ObjectIdentifiers.ecdsa_with_SHA256, "SHA256", "ECDSA"); addEntries(X9ObjectIdentifiers.ecdsa_with_SHA384, "SHA384", "ECDSA"); addEntries(X9ObjectIdentifiers.ecdsa_with_SHA512, "SHA512", "ECDSA"); addEntries(X9ObjectIdentifiers.id_dsa_with_sha1, "SHA1", "DSA"); addEntries(EACObjectIdentifiers.id_TA_ECDSA_SHA_1, "SHA1", "ECDSA"); addEntries(EACObjectIdentifiers.id_TA_ECDSA_SHA_224, "SHA224", "ECDSA"); addEntries(EACObjectIdentifiers.id_TA_ECDSA_SHA_256, "SHA256", "ECDSA"); addEntries(EACObjectIdentifiers.id_TA_ECDSA_SHA_384, "SHA384", "ECDSA"); addEntries(EACObjectIdentifiers.id_TA_ECDSA_SHA_512, "SHA512", "ECDSA"); addEntries(EACObjectIdentifiers.id_TA_RSA_v1_5_SHA_1, "SHA1", "RSA"); addEntries(EACObjectIdentifiers.id_TA_RSA_v1_5_SHA_256, "SHA256", "RSA"); addEntries(EACObjectIdentifiers.id_TA_RSA_PSS_SHA_1, "SHA1", "RSAandMGF1"); addEntries(EACObjectIdentifiers.id_TA_RSA_PSS_SHA_256, "SHA256", "RSAandMGF1"); encryptionAlgs.put(X9ObjectIdentifiers.id_dsa.getId(), "DSA"); encryptionAlgs.put(PKCSObjectIdentifiers.rsaEncryption.getId(), "RSA"); encryptionAlgs.put(TeleTrusTObjectIdentifiers.teleTrusTRSAsignatureAlgorithm, "RSA"); encryptionAlgs.put(X509ObjectIdentifiers.id_ea_rsa.getId(), "RSA"); encryptionAlgs.put(CMSSignedDataGenerator.ENCRYPTION_RSA_PSS, "RSAandMGF1"); encryptionAlgs.put(CryptoProObjectIdentifiers.gostR3410_94.getId(), "GOST3410"); encryptionAlgs.put(CryptoProObjectIdentifiers.gostR3410_2001.getId(), "ECGOST3410"); encryptionAlgs.put("1.3.6.1.4.1.5849.1.6.2", "ECGOST3410"); encryptionAlgs.put("1.3.6.1.4.1.5849.1.1.5", "GOST3410"); encryptionAlgs.put(CryptoProObjectIdentifiers.gostR3411_94_with_gostR3410_2001.getId(), "ECGOST3410"); encryptionAlgs.put(CryptoProObjectIdentifiers.gostR3411_94_with_gostR3410_94.getId(), "GOST3410"); digestAlgs.put(PKCSObjectIdentifiers.md2.getId(), "MD2"); digestAlgs.put(PKCSObjectIdentifiers.md4.getId(), "MD4"); digestAlgs.put(PKCSObjectIdentifiers.md5.getId(), "MD5"); digestAlgs.put(OIWObjectIdentifiers.idSHA1.getId(), "SHA1"); digestAlgs.put(NISTObjectIdentifiers.id_sha224.getId(), "SHA224"); digestAlgs.put(NISTObjectIdentifiers.id_sha256.getId(), "SHA256"); digestAlgs.put(NISTObjectIdentifiers.id_sha384.getId(), "SHA384"); digestAlgs.put(NISTObjectIdentifiers.id_sha512.getId(), "SHA512"); digestAlgs.put(TeleTrusTObjectIdentifiers.ripemd128.getId(), "RIPEMD128"); digestAlgs.put(TeleTrusTObjectIdentifiers.ripemd160.getId(), "RIPEMD160"); digestAlgs.put(TeleTrusTObjectIdentifiers.ripemd256.getId(), "RIPEMD256"); digestAlgs.put(CryptoProObjectIdentifiers.gostR3411.getId(), "GOST3411"); digestAlgs.put("1.3.6.1.4.1.5849.1.2.1", "GOST3411"); digestAliases.put("SHA1", new String[] { "SHA-1" }); digestAliases.put("SHA224", new String[] { "SHA-224" }); digestAliases.put("SHA256", new String[] { "SHA-256" }); digestAliases.put("SHA384", new String[] { "SHA-384" }); digestAliases.put("SHA512", new String[] { "SHA-512" }); } /** * Return the digest algorithm using one of the standard JCA string * representations rather than the algorithm identifier (if possible). */ String getDigestAlgName( String digestAlgOID) { String algName = (String)digestAlgs.get(digestAlgOID); if (algName != null) { return algName; } return digestAlgOID; } /** * Return the digest encryption algorithm using one of the standard * JCA string representations rather the the algorithm identifier (if * possible). */ String getEncryptionAlgName( String encryptionAlgOID) { String algName = (String)encryptionAlgs.get(encryptionAlgOID); if (algName != null) { return algName; } return encryptionAlgOID; } AlgorithmIdentifier fixAlgID(AlgorithmIdentifier algId) { if (algId.getParameters() == null) { return new AlgorithmIdentifier(algId.getAlgorithm(), DERNull.INSTANCE); } return algId; } void setSigningEncryptionAlgorithmMapping(ASN1ObjectIdentifier oid, String algorithmName) { encryptionAlgs.put(oid.getId(), algorithmName); } void setSigningDigestAlgorithmMapping(ASN1ObjectIdentifier oid, String algorithmName) { digestAlgs.put(oid.getId(), algorithmName); } Store getCertificates(ASN1Set certSet) { if (certSet != null) { List certList = new ArrayList(certSet.size()); for (Enumeration en = certSet.getObjects(); en.hasMoreElements();) { ASN1Primitive obj = ((ASN1Encodable)en.nextElement()).toASN1Primitive(); if (obj instanceof ASN1Sequence) { certList.add(new X509CertificateHolder(Certificate.getInstance(obj))); } } return new CollectionStore(certList); } return new CollectionStore(new ArrayList()); } Store getAttributeCertificates(ASN1Set certSet) { if (certSet != null) { List certList = new ArrayList(certSet.size()); for (Enumeration en = certSet.getObjects(); en.hasMoreElements();) { ASN1Primitive obj = ((ASN1Encodable)en.nextElement()).toASN1Primitive(); if (obj instanceof ASN1TaggedObject) { certList.add(new X509AttributeCertificateHolder(AttributeCertificate.getInstance(((ASN1TaggedObject)obj).getObject()))); } } return new CollectionStore(certList); } return new CollectionStore(new ArrayList()); } Store getCRLs(ASN1Set crlSet) { if (crlSet != null) { List crlList = new ArrayList(crlSet.size()); for (Enumeration en = crlSet.getObjects(); en.hasMoreElements();) { ASN1Primitive obj = ((ASN1Encodable)en.nextElement()).toASN1Primitive(); if (obj instanceof ASN1Sequence) { crlList.add(new X509CRLHolder(CertificateList.getInstance(obj))); } } return new CollectionStore(crlList); } return new CollectionStore(new ArrayList()); } Store getOtherRevocationInfo(ASN1ObjectIdentifier otherRevocationInfoFormat, ASN1Set crlSet) { if (crlSet != null) { List crlList = new ArrayList(crlSet.size()); for (Enumeration en = crlSet.getObjects(); en.hasMoreElements();) { ASN1Primitive obj = ((ASN1Encodable)en.nextElement()).toASN1Primitive(); if (obj instanceof ASN1TaggedObject) { ASN1TaggedObject tObj = ASN1TaggedObject.getInstance(obj); if (tObj.getTagNo() == 1) { OtherRevocationInfoFormat other = OtherRevocationInfoFormat.getInstance(tObj, false); if (otherRevocationInfoFormat.equals(other.getInfoFormat())) { crlList.add(other.getInfo()); } } } } return new CollectionStore(crlList); } return new CollectionStore(new ArrayList()); } } bouncycastle-1.49.orig/j2me/org/bouncycastle/cms/CMSEnvelopedDataStreamGenerator.java0000644000175000017500000002163411731763202030306 0ustar ebourgebourgpackage org.bouncycastle.cms; import java.io.IOException; import java.io.OutputStream; import java.util.HashMap; import java.util.Iterator; import org.bouncycastle.asn1.ASN1EncodableVector; import org.bouncycastle.asn1.ASN1Integer; import org.bouncycastle.asn1.ASN1ObjectIdentifier; import org.bouncycastle.asn1.ASN1Set; import org.bouncycastle.asn1.BERSequenceGenerator; import org.bouncycastle.asn1.BERSet; import org.bouncycastle.asn1.DERInteger; import org.bouncycastle.asn1.DERSet; import org.bouncycastle.asn1.DERTaggedObject; import org.bouncycastle.asn1.cms.AttributeTable; import org.bouncycastle.asn1.cms.CMSObjectIdentifiers; import org.bouncycastle.asn1.cms.EnvelopedData; import org.bouncycastle.asn1.x509.AlgorithmIdentifier; import org.bouncycastle.operator.GenericKey; import org.bouncycastle.operator.OutputEncryptor; /** * General class for generating a CMS enveloped-data message stream. *

    * A simple example of usage. *

     *      CMSEnvelopedDataStreamGenerator edGen = new CMSEnvelopedDataStreamGenerator();
     *
     *      edGen.addRecipientInfoGenerator(new JceKeyTransRecipientInfoGenerator(recipientCert).setProvider("BC"));
     *
     *      ByteArrayOutputStream  bOut = new ByteArrayOutputStream();
     *      
     *      OutputStream out = edGen.open(
     *                              bOut, new JceCMSContentEncryptorBuilder(CMSAlgorithm.DES_EDE3_CBC)
     *                                              .setProvider("BC").build());
     *      out.write(data);
     *      
     *      out.close();
     * 
    */ public class CMSEnvelopedDataStreamGenerator extends CMSEnvelopedGenerator { private ASN1Set _unprotectedAttributes = null; private int _bufferSize; private boolean _berEncodeRecipientSet; /** * base constructor */ public CMSEnvelopedDataStreamGenerator() { } /** * Set the underlying string size for encapsulated data * * @param bufferSize length of octet strings to buffer the data. */ public void setBufferSize( int bufferSize) { _bufferSize = bufferSize; } /** * Use a BER Set to store the recipient information */ public void setBEREncodeRecipients( boolean berEncodeRecipientSet) { _berEncodeRecipientSet = berEncodeRecipientSet; } private DERInteger getVersion() { if (originatorInfo != null || _unprotectedAttributes != null) { return new DERInteger(2); } else { return new DERInteger(0); } } private OutputStream doOpen( ASN1ObjectIdentifier dataType, OutputStream out, OutputEncryptor encryptor) throws IOException, CMSException { ASN1EncodableVector recipientInfos = new ASN1EncodableVector(); GenericKey encKey = encryptor.getKey(); Iterator it = recipientInfoGenerators.iterator(); while (it.hasNext()) { RecipientInfoGenerator recipient = (RecipientInfoGenerator)it.next(); recipientInfos.add(recipient.generate(encKey)); } return open(dataType, out, recipientInfos, encryptor); } protected OutputStream open( ASN1ObjectIdentifier dataType, OutputStream out, ASN1EncodableVector recipientInfos, OutputEncryptor encryptor) throws IOException { // // ContentInfo // BERSequenceGenerator cGen = new BERSequenceGenerator(out); cGen.addObject(CMSObjectIdentifiers.envelopedData); // // Encrypted Data // BERSequenceGenerator envGen = new BERSequenceGenerator(cGen.getRawOutputStream(), 0, true); envGen.addObject(getVersion()); if (originatorInfo != null) { envGen.addObject(new DERTaggedObject(false, 0, originatorInfo)); } if (_berEncodeRecipientSet) { envGen.getRawOutputStream().write(new BERSet(recipientInfos).getEncoded()); } else { envGen.getRawOutputStream().write(new DERSet(recipientInfos).getEncoded()); } BERSequenceGenerator eiGen = new BERSequenceGenerator(envGen.getRawOutputStream()); eiGen.addObject(dataType); AlgorithmIdentifier encAlgId = encryptor.getAlgorithmIdentifier(); eiGen.getRawOutputStream().write(encAlgId.getEncoded()); OutputStream octetStream = CMSUtils.createBEROctetOutputStream( eiGen.getRawOutputStream(), 0, false, _bufferSize); OutputStream cOut = encryptor.getOutputStream(octetStream); return new CmsEnvelopedDataOutputStream(cOut, cGen, envGen, eiGen); } protected OutputStream open( OutputStream out, ASN1EncodableVector recipientInfos, OutputEncryptor encryptor) throws CMSException { try { // // ContentInfo // BERSequenceGenerator cGen = new BERSequenceGenerator(out); cGen.addObject(CMSObjectIdentifiers.envelopedData); // // Encrypted Data // BERSequenceGenerator envGen = new BERSequenceGenerator(cGen.getRawOutputStream(), 0, true); ASN1Set recipients; if (_berEncodeRecipientSet) { recipients = new BERSet(recipientInfos); } else { recipients = new DERSet(recipientInfos); } envGen.addObject(new ASN1Integer(EnvelopedData.calculateVersion(originatorInfo, recipients, _unprotectedAttributes))); if (originatorInfo != null) { envGen.addObject(new DERTaggedObject(false, 0, originatorInfo)); } envGen.getRawOutputStream().write(recipients.getEncoded()); BERSequenceGenerator eiGen = new BERSequenceGenerator(envGen.getRawOutputStream()); eiGen.addObject(CMSObjectIdentifiers.data); AlgorithmIdentifier encAlgId = encryptor.getAlgorithmIdentifier(); eiGen.getRawOutputStream().write(encAlgId.getEncoded()); OutputStream octetStream = CMSUtils.createBEROctetOutputStream( eiGen.getRawOutputStream(), 0, false, _bufferSize); return new CmsEnvelopedDataOutputStream(encryptor.getOutputStream(octetStream), cGen, envGen, eiGen); } catch (IOException e) { throw new CMSException("exception decoding algorithm parameters.", e); } } /** * generate an enveloped object that contains an CMS Enveloped Data * object using the given encryptor. */ public OutputStream open( OutputStream out, OutputEncryptor encryptor) throws CMSException, IOException { return doOpen(new ASN1ObjectIdentifier(CMSObjectIdentifiers.data.getId()), out, encryptor); } /** * generate an enveloped object that contains an CMS Enveloped Data * object using the given encryptor and marking the data as being of the passed * in type. */ public OutputStream open( ASN1ObjectIdentifier dataType, OutputStream out, OutputEncryptor encryptor) throws CMSException, IOException { return doOpen(dataType, out, encryptor); } private class CmsEnvelopedDataOutputStream extends OutputStream { private OutputStream _out; private BERSequenceGenerator _cGen; private BERSequenceGenerator _envGen; private BERSequenceGenerator _eiGen; public CmsEnvelopedDataOutputStream( OutputStream out, BERSequenceGenerator cGen, BERSequenceGenerator envGen, BERSequenceGenerator eiGen) { _out = out; _cGen = cGen; _envGen = envGen; _eiGen = eiGen; } public void write( int b) throws IOException { _out.write(b); } public void write( byte[] bytes, int off, int len) throws IOException { _out.write(bytes, off, len); } public void write( byte[] bytes) throws IOException { _out.write(bytes); } public void close() throws IOException { _out.close(); _eiGen.close(); if (unprotectedAttributeGenerator != null) { AttributeTable attrTable = unprotectedAttributeGenerator.getAttributes(new HashMap()); ASN1Set unprotectedAttrs = new BERSet(attrTable.toASN1EncodableVector()); _envGen.addObject(new DERTaggedObject(false, 1, unprotectedAttrs)); } _envGen.close(); _cGen.close(); } } } bouncycastle-1.49.orig/j2me/org/bouncycastle/cms/KEKRecipientInformation.java0000644000175000017500000000225711731764640026677 0ustar ebourgebourgpackage org.bouncycastle.cms; import java.io.IOException; import org.bouncycastle.asn1.cms.KEKIdentifier; import org.bouncycastle.asn1.cms.KEKRecipientInfo; import org.bouncycastle.asn1.x509.AlgorithmIdentifier; /** * the RecipientInfo class for a recipient who has been sent a message * encrypted using a secret key known to the other side. */ public class KEKRecipientInformation extends RecipientInformation { private KEKRecipientInfo info; KEKRecipientInformation( KEKRecipientInfo info, AlgorithmIdentifier messageAlgorithm, CMSSecureReadable secureReadable, AuthAttributesProvider additionalData) { super(info.getKeyEncryptionAlgorithm(), messageAlgorithm, secureReadable, additionalData); this.info = info; KEKIdentifier kekId = info.getKekid(); this.rid = new KEKRecipientId(kekId.getKeyIdentifier().getOctets()); } protected RecipientOperator getRecipientOperator(Recipient recipient) throws CMSException, IOException { return ((KEKRecipient)recipient).getRecipientOperator(keyEncAlg, messageAlgorithm, info.getEncryptedKey().getOctets()); } } bouncycastle-1.49.orig/j2me/org/bouncycastle/tsp/0000755000175000017500000000000012152033550021352 5ustar ebourgebourgbouncycastle-1.49.orig/j2me/org/bouncycastle/tsp/TimeStampResponseGenerator.java0000644000175000017500000001703611732001575027522 0ustar ebourgebourgpackage org.bouncycastle.tsp; import java.io.ByteArrayInputStream; import java.io.IOException; import java.math.BigInteger; import java.util.Date; import java.util.HashSet; import java.util.Iterator; import java.util.Set; import org.bouncycastle.asn1.ASN1EncodableVector; import org.bouncycastle.asn1.ASN1InputStream; import org.bouncycastle.asn1.ASN1ObjectIdentifier; import org.bouncycastle.asn1.DERBitString; import org.bouncycastle.asn1.DERInteger; import org.bouncycastle.asn1.DERSequence; import org.bouncycastle.asn1.DERUTF8String; import org.bouncycastle.asn1.cmp.PKIFailureInfo; import org.bouncycastle.asn1.cmp.PKIFreeText; import org.bouncycastle.asn1.cmp.PKIStatus; import org.bouncycastle.asn1.cmp.PKIStatusInfo; import org.bouncycastle.asn1.cms.ContentInfo; import org.bouncycastle.asn1.tsp.TimeStampResp; /** * Generator for RFC 3161 Time Stamp Responses. */ public class TimeStampResponseGenerator { int status; ASN1EncodableVector statusStrings; int failInfo; private TimeStampTokenGenerator tokenGenerator; private Set acceptedAlgorithms; private Set acceptedPolicies; private Set acceptedExtensions; /** * * @param tokenGenerator * @param acceptedAlgorithms a set of OIDs giving accepted algorithms. */ public TimeStampResponseGenerator( TimeStampTokenGenerator tokenGenerator, Set acceptedAlgorithms) { this(tokenGenerator, acceptedAlgorithms, null, null); } /** * * @param tokenGenerator * @param acceptedAlgorithms a set of OIDs giving accepted algorithms. * @param acceptedPolicies if non-null a set of policies OIDs we are willing to sign under. */ public TimeStampResponseGenerator( TimeStampTokenGenerator tokenGenerator, Set acceptedAlgorithms, Set acceptedPolicies) { this(tokenGenerator, acceptedAlgorithms, acceptedPolicies, null); } /** * * @param tokenGenerator * @param acceptedAlgorithms a set of OIDs giving accepted algorithms. * @param acceptedPolicies if non-null a set of policies OIDs we are willing to sign under. * @param acceptedExtensions if non-null a set of extensions OIDs we are willing to accept. */ public TimeStampResponseGenerator( TimeStampTokenGenerator tokenGenerator, Set acceptedAlgorithms, Set acceptedPolicies, Set acceptedExtensions) { this.tokenGenerator = tokenGenerator; this.acceptedAlgorithms = convert(acceptedAlgorithms); this.acceptedPolicies = convert(acceptedPolicies); this.acceptedExtensions = convert(acceptedExtensions); statusStrings = new ASN1EncodableVector(); } private void addStatusString(String statusString) { statusStrings.add(new DERUTF8String(statusString)); } private void setFailInfoField(int field) { failInfo = failInfo | field; } private PKIStatusInfo getPKIStatusInfo() { ASN1EncodableVector v = new ASN1EncodableVector(); v.add(new DERInteger(status)); if (statusStrings.size() > 0) { v.add(PKIFreeText.getInstance(new DERSequence(statusStrings))); } if (failInfo != 0) { DERBitString failInfoBitString = new FailInfo(failInfo); v.add(failInfoBitString); } return PKIStatusInfo.getInstance(new DERSequence(v)); } /** * Return an appropriate TimeStampResponse. *

    * If genTime is null a timeNotAvailable error response will be returned. * * @param request the request this response is for. * @param serialNumber serial number for the response token. * @param genTime generation time for the response token. * @return * @throws TSPException */ public TimeStampResponse generate( TimeStampRequest request, BigInteger serialNumber, Date genTime) throws TSPException { TimeStampResp resp; try { if (genTime == null) { throw new TSPValidationException("The time source is not available.", PKIFailureInfo.timeNotAvailable); } request.validate(acceptedAlgorithms, acceptedPolicies, acceptedExtensions); status = PKIStatus.GRANTED; this.addStatusString("Operation Okay"); PKIStatusInfo pkiStatusInfo = getPKIStatusInfo(); ContentInfo tstTokenContentInfo = null; try { ByteArrayInputStream bIn = new ByteArrayInputStream(tokenGenerator.generate(request, serialNumber, genTime).toCMSSignedData().getEncoded()); ASN1InputStream aIn = new ASN1InputStream(bIn); tstTokenContentInfo = ContentInfo.getInstance(aIn.readObject()); } catch (java.io.IOException ioEx) { throw new TSPException( "Timestamp token received cannot be converted to ContentInfo", ioEx); } resp = new TimeStampResp(pkiStatusInfo, tstTokenContentInfo); } catch (TSPValidationException e) { status = PKIStatus.REJECTION; this.setFailInfoField(e.getFailureCode()); this.addStatusString(e.getMessage()); PKIStatusInfo pkiStatusInfo = getPKIStatusInfo(); resp = new TimeStampResp(pkiStatusInfo, null); } try { return new TimeStampResponse(resp); } catch (IOException e) { throw new TSPException("created badly formatted response!"); } } class FailInfo extends DERBitString { FailInfo(int failInfoValue) { super(getBytes(failInfoValue), getPadBits(failInfoValue)); } } /** * Generate a TimeStampResponse with chosen status and FailInfoField. * * @param status the PKIStatus to set. * @param failInfoField the FailInfoField to set. * @param statusString an optional string describing the failure. * @return a TimeStampResponse with a failInfoField and optional statusString * @throws TSPException in case the response could not be created */ public TimeStampResponse generateFailResponse(int status, int failInfoField, String statusString) throws TSPException { this.status = status; this.setFailInfoField(failInfoField); if (statusString != null) { this.addStatusString(statusString); } PKIStatusInfo pkiStatusInfo = getPKIStatusInfo(); TimeStampResp resp = new TimeStampResp(pkiStatusInfo, null); try { return new TimeStampResponse(resp); } catch (IOException e) { throw new TSPException("created badly formatted response!"); } } private Set convert(Set orig) { if (orig == null) { return orig; } Set con = new HashSet(orig.size()); for (Iterator it = orig.iterator(); it.hasNext();) { Object o = it.next(); if (o instanceof String) { con.add(new ASN1ObjectIdentifier((String)o)); } else { con.add(o); } } return con; } } bouncycastle-1.49.orig/j2me/org/bouncycastle/tsp/TimeStampRequest.java0000644000175000017500000001706411732002115025475 0ustar ebourgebourgpackage org.bouncycastle.tsp; import java.io.ByteArrayInputStream; import java.io.IOException; import java.io.InputStream; import java.math.BigInteger; import java.util.Arrays; import java.util.Collections; import java.util.Enumeration; import java.util.HashSet; import java.util.Iterator; import java.util.List; import java.util.Set; import org.bouncycastle.asn1.ASN1InputStream; import org.bouncycastle.asn1.ASN1ObjectIdentifier; import org.bouncycastle.asn1.DERObjectIdentifier; import org.bouncycastle.asn1.cmp.PKIFailureInfo; import org.bouncycastle.asn1.tsp.TimeStampReq; import org.bouncycastle.asn1.x509.Extension; import org.bouncycastle.asn1.x509.Extensions; /** * Base class for an RFC 3161 Time Stamp Request. */ public class TimeStampRequest { private static Set EMPTY_SET = Collections.unmodifiableSet(new HashSet()); private TimeStampReq req; private Extensions extensions; public TimeStampRequest(TimeStampReq req) { this.req = req; this.extensions = req.getExtensions(); } /** * Create a TimeStampRequest from the past in byte array. * * @param req byte array containing the request. * @throws IOException if the request is malformed. */ public TimeStampRequest(byte[] req) throws IOException { this(new ByteArrayInputStream(req)); } /** * Create a TimeStampRequest from the past in input stream. * * @param in input stream containing the request. * @throws IOException if the request is malformed. */ public TimeStampRequest(InputStream in) throws IOException { try { this.req = TimeStampReq.getInstance(new ASN1InputStream(in).readObject()); } catch (ClassCastException e) { throw new IOException("malformed request: " + e); } catch (IllegalArgumentException e) { throw new IOException("malformed request: " + e); } } public int getVersion() { return req.getVersion().getValue().intValue(); } public ASN1ObjectIdentifier getMessageImprintAlgOID() { return req.getMessageImprint().getHashAlgorithm().getAlgorithm(); } public byte[] getMessageImprintDigest() { return req.getMessageImprint().getHashedMessage(); } public ASN1ObjectIdentifier getReqPolicy() { if (req.getReqPolicy() != null) { return req.getReqPolicy(); } else { return null; } } public BigInteger getNonce() { if (req.getNonce() != null) { return req.getNonce().getValue(); } else { return null; } } public boolean getCertReq() { if (req.getCertReq() != null) { return req.getCertReq().isTrue(); } else { return false; } } /** * Validate the timestamp request, checking the digest to see if it is of an * accepted type and whether it is of the correct length for the algorithm specified. * * @param algorithms a set of OIDs giving accepted algorithms. * @param policies if non-null a set of policies OIDs we are willing to sign under. * @param extensions if non-null a set of extensions OIDs we are willing to accept. * @throws TSPException if the request is invalid, or processing fails. */ public void validate( Set algorithms, Set policies, Set extensions) throws TSPException { algorithms = convert(algorithms); policies = convert(policies); extensions = convert(extensions); if (!algorithms.contains(this.getMessageImprintAlgOID())) { throw new TSPValidationException("request contains unknown algorithm.", PKIFailureInfo.badAlg); } if (policies != null && this.getReqPolicy() != null && !policies.contains(this.getReqPolicy())) { throw new TSPValidationException("request contains unknown policy.", PKIFailureInfo.unacceptedPolicy); } if (this.getExtensions() != null && extensions != null) { Enumeration en = this.getExtensions().oids(); while(en.hasMoreElements()) { String oid = ((DERObjectIdentifier)en.nextElement()).getId(); if (!extensions.contains(oid)) { throw new TSPValidationException("request contains unknown extension.", PKIFailureInfo.unacceptedExtension); } } } int digestLength = TSPUtil.getDigestLength(this.getMessageImprintAlgOID().getId()); if (digestLength != this.getMessageImprintDigest().length) { throw new TSPValidationException("imprint digest the wrong length.", PKIFailureInfo.badDataFormat); } } /** * return the ASN.1 encoded representation of this object. * @return the default ASN,1 byte encoding for the object. */ public byte[] getEncoded() throws IOException { return req.getEncoded(); } Extensions getExtensions() { return extensions; } public boolean hasExtensions() { return extensions != null; } public Extension getExtension(ASN1ObjectIdentifier oid) { if (extensions != null) { return extensions.getExtension(oid); } return null; } public List getExtensionOIDs() { return TSPUtil.getExtensionOIDs(extensions); } /* (non-Javadoc) * @see java.security.cert.X509Extension#getExtensionValue(java.lang.String) * @deprecated use getExtension(ASN1ObjectIdentifier) */ public byte[] getExtensionValue(String oid) { Extensions exts = req.getExtensions(); if (exts != null) { Extension ext = exts.getExtension(new ASN1ObjectIdentifier(oid)); if (ext != null) { try { return ext.getExtnValue().getEncoded(); } catch (Exception e) { throw new RuntimeException("error encoding " + e.toString()); } } } return null; } /** * Returns a set of ASN1ObjectIdentifiers giving the non-critical extensions. * @return a set of ASN1ObjectIdentifiers. */ public Set getNonCriticalExtensionOIDs() { if (extensions == null) { return EMPTY_SET; } return Collections.unmodifiableSet(new HashSet(Arrays.asList(extensions.getNonCriticalExtensionOIDs()))); } /** * Returns a set of ASN1ObjectIdentifiers giving the critical extensions. * @return a set of ASN1ObjectIdentifiers. */ public Set getCriticalExtensionOIDs() { if (extensions == null) { return EMPTY_SET; } return Collections.unmodifiableSet(new HashSet(Arrays.asList(extensions.getCriticalExtensionOIDs()))); } private Set convert(Set orig) { if (orig == null) { return orig; } Set con = new HashSet(orig.size()); for (Iterator it = orig.iterator(); it.hasNext();) { Object o = it.next(); if (o instanceof String) { con.add(new ASN1ObjectIdentifier((String)o)); } else { con.add(o); } } return con; } } bouncycastle-1.49.orig/j2me/org/bouncycastle/tsp/TimeStampTokenGenerator.java0000644000175000017500000002751412150050436027001 0ustar ebourgebourgpackage org.bouncycastle.tsp; import java.io.ByteArrayOutputStream; import java.io.IOException; import java.io.OutputStream; import java.math.BigInteger; import java.util.ArrayList; import java.util.Collection; import java.util.Date; import java.util.Hashtable; import java.util.Iterator; import java.util.List; import java.util.Map; import org.bouncycastle.asn1.ASN1Boolean; import org.bouncycastle.asn1.ASN1Encoding; import org.bouncycastle.asn1.ASN1GeneralizedTime; import org.bouncycastle.asn1.ASN1Integer; import org.bouncycastle.asn1.ASN1ObjectIdentifier; import org.bouncycastle.asn1.DERNull; import org.bouncycastle.asn1.DERSet; import org.bouncycastle.asn1.cms.Attribute; import org.bouncycastle.asn1.cms.AttributeTable; import org.bouncycastle.asn1.ess.ESSCertID; import org.bouncycastle.asn1.ess.ESSCertIDv2; import org.bouncycastle.asn1.ess.SigningCertificate; import org.bouncycastle.asn1.ess.SigningCertificateV2; import org.bouncycastle.asn1.oiw.OIWObjectIdentifiers; import org.bouncycastle.asn1.pkcs.PKCSObjectIdentifiers; import org.bouncycastle.asn1.tsp.Accuracy; import org.bouncycastle.asn1.tsp.MessageImprint; import org.bouncycastle.asn1.tsp.TSTInfo; import org.bouncycastle.asn1.x509.AlgorithmIdentifier; import org.bouncycastle.asn1.x509.GeneralName; import org.bouncycastle.cms.CMSAttributeTableGenerationException; import org.bouncycastle.cms.CMSAttributeTableGenerator; import org.bouncycastle.cms.CMSException; import org.bouncycastle.cms.CMSProcessableByteArray; import org.bouncycastle.cms.CMSSignedData; import org.bouncycastle.cms.CMSSignedDataGenerator; import org.bouncycastle.cms.CMSSignedGenerator; import org.bouncycastle.cms.DefaultSignedAttributeTableGenerator; import org.bouncycastle.cms.SignerInfoGenerator; import org.bouncycastle.cms.SimpleAttributeTableGenerator; import org.bouncycastle.operator.DigestCalculator; import org.bouncycastle.operator.OperatorCreationException; import org.bouncycastle.util.CollectionStore; import org.bouncycastle.util.Store; /** * Currently the class supports ESSCertID by if a digest calculator based on SHA1 is passed in, otherwise it uses * ESSCertIDv2. In the event you need to pass both types, you will need to override the SignedAttributeGenerator * for the SignerInfoGeneratorBuilder you are using. For the default for ESSCertIDv2 the code will look something * like the following: *

     * final ESSCertID essCertid = new ESSCertID(certHashSha1, issuerSerial);
     * final ESSCertIDv2 essCertidV2 = new ESSCertIDv2(certHashSha256, issuerSerial);
     *
     * signerInfoGenBuilder.setSignedAttributeGenerator(new CMSAttributeTableGenerator()
     * {
     *     public AttributeTable getAttributes(Map parameters)
     *         throws CMSAttributeTableGenerationException
     *     {
     *         CMSAttributeTableGenerator attrGen = new DefaultSignedAttributeTableGenerator();
     *
     *         AttributeTable table = attrGen.getAttributes(parameters);
     *
     *         table = table.add(PKCSObjectIdentifiers.id_aa_signingCertificate, new SigningCertificate(essCertid));
     *         table = table.add(PKCSObjectIdentifiers.id_aa_signingCertificateV2, new SigningCertificateV2(essCertidV2));
     *
     *         return table;
     *     }
     * });
     * 
    */ public class TimeStampTokenGenerator { int accuracySeconds = -1; int accuracyMillis = -1; int accuracyMicros = -1; boolean ordering = false; GeneralName tsa = null; private ASN1ObjectIdentifier tsaPolicyOID; String digestOID; AttributeTable signedAttr; AttributeTable unsignedAttr; private List certs = new ArrayList(); private List crls = new ArrayList(); private List attrCerts = new ArrayList(); private SignerInfoGenerator signerInfoGen; /** * Basic Constructor - set up a calculator based on signerInfoGen with a ESSCertID calculated from * the signer's associated certificate using the sha1DigestCalculator. If alternate values are required * for id-aa-signingCertificate they should be added to the signerInfoGen object before it is passed in, * otherwise a standard digest based value will be added. * * @param signerInfoGen the generator for the signer we are using. * @param digestCalculator calculator for to use for digest of certificate. * @param tsaPolicy tasPolicy to send. * @throws IllegalArgumentException if calculator is not SHA-1 or there is no associated certificate for the signer, * @throws TSPException if the signer certificate cannot be processed. */ public TimeStampTokenGenerator( final SignerInfoGenerator signerInfoGen, DigestCalculator digestCalculator, ASN1ObjectIdentifier tsaPolicy) throws IllegalArgumentException, TSPException { this.signerInfoGen = signerInfoGen; this.tsaPolicyOID = tsaPolicy; if (!signerInfoGen.hasAssociatedCertificate()) { throw new IllegalArgumentException("SignerInfoGenerator must have an associated certificate"); } TSPUtil.validateCertificate(signerInfoGen.getAssociatedCertificate()); try { OutputStream dOut = digestCalculator.getOutputStream(); dOut.write(signerInfoGen.getAssociatedCertificate().getEncoded()); dOut.close(); if (digestCalculator.getAlgorithmIdentifier().getAlgorithm().equals(OIWObjectIdentifiers.idSHA1)) { final ESSCertID essCertid = new ESSCertID(digestCalculator.getDigest()); this.signerInfoGen = new SignerInfoGenerator(signerInfoGen, new CMSAttributeTableGenerator() { public AttributeTable getAttributes(Map parameters) throws CMSAttributeTableGenerationException { AttributeTable table = signerInfoGen.getSignedAttributeTableGenerator().getAttributes(parameters); if (table.get(PKCSObjectIdentifiers.id_aa_signingCertificate) == null) { return table.add(PKCSObjectIdentifiers.id_aa_signingCertificate, new SigningCertificate(essCertid)); } return table; } }, signerInfoGen.getUnsignedAttributeTableGenerator()); } else { AlgorithmIdentifier digAlgID = new AlgorithmIdentifier(digestCalculator.getAlgorithmIdentifier().getAlgorithm()); final ESSCertIDv2 essCertid = new ESSCertIDv2(digAlgID, digestCalculator.getDigest()); this.signerInfoGen = new SignerInfoGenerator(signerInfoGen, new CMSAttributeTableGenerator() { public AttributeTable getAttributes(Map parameters) throws CMSAttributeTableGenerationException { AttributeTable table = signerInfoGen.getSignedAttributeTableGenerator().getAttributes(parameters); if (table.get(PKCSObjectIdentifiers.id_aa_signingCertificateV2) == null) { return table.add(PKCSObjectIdentifiers.id_aa_signingCertificateV2, new SigningCertificateV2(essCertid)); } return table; } }, signerInfoGen.getUnsignedAttributeTableGenerator()); } } catch (IOException e) { throw new TSPException("Exception processing certificate.", e); } } /** * Add the store of X509 Certificates to the generator. * * @param certStore a Store containing X509CertificateHolder objects */ public void addCertificates( Store certStore) { certs.addAll(certStore.getMatches(null)); } /** * * @param crlStore a Store containing X509CRLHolder objects. */ public void addCRLs( Store crlStore) { crls.addAll(crlStore.getMatches(null)); } /** * * @param attrStore a Store containing X509AttributeCertificate objects. */ public void addAttributeCertificates( Store attrStore) { attrCerts.addAll(attrStore.getMatches(null)); } public void setAccuracySeconds(int accuracySeconds) { this.accuracySeconds = accuracySeconds; } public void setAccuracyMillis(int accuracyMillis) { this.accuracyMillis = accuracyMillis; } public void setAccuracyMicros(int accuracyMicros) { this.accuracyMicros = accuracyMicros; } public void setOrdering(boolean ordering) { this.ordering = ordering; } public void setTSA(GeneralName tsa) { this.tsa = tsa; } public TimeStampToken generate( TimeStampRequest request, BigInteger serialNumber, Date genTime) throws TSPException { if (signerInfoGen == null) { throw new IllegalStateException("can only use this method with SignerInfoGenerator constructor"); } ASN1ObjectIdentifier digestAlgOID = request.getMessageImprintAlgOID(); AlgorithmIdentifier algID = new AlgorithmIdentifier(digestAlgOID, DERNull.INSTANCE); MessageImprint messageImprint = new MessageImprint(algID, request.getMessageImprintDigest()); Accuracy accuracy = null; if (accuracySeconds > 0 || accuracyMillis > 0 || accuracyMicros > 0) { ASN1Integer seconds = null; if (accuracySeconds > 0) { seconds = new ASN1Integer(accuracySeconds); } ASN1Integer millis = null; if (accuracyMillis > 0) { millis = new ASN1Integer(accuracyMillis); } ASN1Integer micros = null; if (accuracyMicros > 0) { micros = new ASN1Integer(accuracyMicros); } accuracy = new Accuracy(seconds, millis, micros); } ASN1Boolean derOrdering = null; if (ordering) { derOrdering = new ASN1Boolean(ordering); } ASN1Integer nonce = null; if (request.getNonce() != null) { nonce = new ASN1Integer(request.getNonce()); } ASN1ObjectIdentifier tsaPolicy = tsaPolicyOID; if (request.getReqPolicy() != null) { tsaPolicy = request.getReqPolicy(); } TSTInfo tstInfo = new TSTInfo(tsaPolicy, messageImprint, new ASN1Integer(serialNumber), new ASN1GeneralizedTime(genTime), accuracy, derOrdering, nonce, tsa, request.getExtensions()); try { CMSSignedDataGenerator signedDataGenerator = new CMSSignedDataGenerator(); if (request.getCertReq()) { // TODO: do we need to check certs non-empty? signedDataGenerator.addCertificates(new CollectionStore(certs)); signedDataGenerator.addCRLs(new CollectionStore(crls)); signedDataGenerator.addAttributeCertificates(new CollectionStore(attrCerts)); } else { signedDataGenerator.addCRLs(new CollectionStore(crls)); } signedDataGenerator.addSignerInfoGenerator(signerInfoGen); byte[] derEncodedTSTInfo = tstInfo.getEncoded(ASN1Encoding.DER); CMSSignedData signedData = signedDataGenerator.generate(new CMSProcessableByteArray(PKCSObjectIdentifiers.id_ct_TSTInfo, derEncodedTSTInfo), true); return new TimeStampToken(signedData); } catch (CMSException cmsEx) { throw new TSPException("Error generating time-stamp token", cmsEx); } catch (IOException e) { throw new TSPException("Exception encoding info", e); } } } bouncycastle-1.49.orig/j2me/org/bouncycastle/tsp/cms/0000755000175000017500000000000012152033550022134 5ustar ebourgebourgbouncycastle-1.49.orig/j2me/org/bouncycastle/tsp/cms/CMSTimeStampedDataParser.java0000644000175000017500000001443611732006435027542 0ustar ebourgebourgpackage org.bouncycastle.tsp.cms; import java.io.ByteArrayInputStream; import java.io.IOException; import java.io.InputStream; import org.bouncycastle.asn1.BERTags; import org.bouncycastle.asn1.DERIA5String; import org.bouncycastle.asn1.cms.AttributeTable; import org.bouncycastle.asn1.cms.CMSObjectIdentifiers; import org.bouncycastle.asn1.cms.ContentInfoParser; import org.bouncycastle.asn1.cms.TimeStampedDataParser; import org.bouncycastle.cms.CMSContentInfoParser; import org.bouncycastle.cms.CMSException; import org.bouncycastle.operator.DigestCalculator; import org.bouncycastle.operator.DigestCalculatorProvider; import org.bouncycastle.operator.OperatorCreationException; import org.bouncycastle.tsp.TimeStampToken; import org.bouncycastle.util.io.Streams; public class CMSTimeStampedDataParser extends CMSContentInfoParser { private TimeStampedDataParser timeStampedData; private TimeStampDataUtil util; public CMSTimeStampedDataParser(InputStream in) throws CMSException { super(in); initialize(_contentInfo); } public CMSTimeStampedDataParser(byte[] baseData) throws CMSException { this(new ByteArrayInputStream(baseData)); } private void initialize(ContentInfoParser contentInfo) throws CMSException { try { if (CMSObjectIdentifiers.timestampedData.equals(contentInfo.getContentType())) { this.timeStampedData = TimeStampedDataParser.getInstance(contentInfo.getContent(BERTags.SEQUENCE)); } else { throw new IllegalArgumentException("Malformed content - type must be " + CMSObjectIdentifiers.timestampedData.getId()); } } catch (IOException e) { throw new CMSException("parsing exception: " + e.getMessage(), e); } } public byte[] calculateNextHash(DigestCalculator calculator) throws CMSException { return util.calculateNextHash(calculator); } public InputStream getContent() { if (timeStampedData.getContent() != null) { return timeStampedData.getContent().getOctetStream(); } return null; } public String getDataUri() { DERIA5String dataURI = this.timeStampedData.getDataUri(); if (dataURI != null) { return dataURI.getString(); } return null; } public String getFileName() { return util.getFileName(); } public String getMediaType() { return util.getMediaType(); } public AttributeTable getOtherMetaData() { return util.getOtherMetaData(); } /** * Initialise the passed in calculator with the MetaData for this message, if it is * required as part of the initial message imprint calculation. * * @param calculator the digest calculator to be initialised. * @throws CMSException if the MetaData is required and cannot be processed */ public void initialiseMessageImprintDigestCalculator(DigestCalculator calculator) throws CMSException { util.initialiseMessageImprintDigestCalculator(calculator); } /** * Returns an appropriately initialised digest calculator based on the message imprint algorithm * described in the first time stamp in the TemporalData for this message. If the metadata is required * to be included in the digest calculation, the returned calculator will be pre-initialised. * * @param calculatorProvider a provider of DigestCalculator objects. * @return an initialised digest calculator. * @throws OperatorCreationException if the provider is unable to create the calculator. */ public DigestCalculator getMessageImprintDigestCalculator(DigestCalculatorProvider calculatorProvider) throws OperatorCreationException { try { parseTimeStamps(); } catch (CMSException e) { throw new OperatorCreationException("unable to extract algorithm ID: " + e.getMessage(), e); } return util.getMessageImprintDigestCalculator(calculatorProvider); } public TimeStampToken[] getTimeStampTokens() throws CMSException { parseTimeStamps(); return util.getTimeStampTokens(); } /** * Validate the digests present in the TimeStampTokens contained in the CMSTimeStampedData. * * @param calculatorProvider provider for digest calculators * @param dataDigest the calculated data digest for the message * @throws ImprintDigestInvalidException if an imprint digest fails to compare * @throws CMSException if an exception occurs processing the message. */ public void validate(DigestCalculatorProvider calculatorProvider, byte[] dataDigest) throws ImprintDigestInvalidException, CMSException { parseTimeStamps(); util.validate(calculatorProvider, dataDigest); } /** * Validate the passed in timestamp token against the tokens and data present in the message. * * @param calculatorProvider provider for digest calculators * @param dataDigest the calculated data digest for the message. * @param timeStampToken the timestamp token of interest. * @throws ImprintDigestInvalidException if the token is not present in the message, or an imprint digest fails to compare. * @throws CMSException if an exception occurs processing the message. */ public void validate(DigestCalculatorProvider calculatorProvider, byte[] dataDigest, TimeStampToken timeStampToken) throws ImprintDigestInvalidException, CMSException { parseTimeStamps(); util.validate(calculatorProvider, dataDigest, timeStampToken); } private void parseTimeStamps() throws CMSException { try { if (util == null) { InputStream cont = this.getContent(); if (cont != null) { Streams.drain(cont); } util = new TimeStampDataUtil(timeStampedData); } } catch (IOException e) { throw new CMSException("unable to parse evidence block: " + e.getMessage(), e); } } } bouncycastle-1.49.orig/j2me/org/bouncycastle/tsp/cms/CMSTimeStampedGenerator.java0000644000175000017500000000577712103632343027446 0ustar ebourgebourgpackage org.bouncycastle.tsp.cms; import org.bouncycastle.asn1.ASN1Boolean; import org.bouncycastle.asn1.DERBoolean; import org.bouncycastle.asn1.DERIA5String; import org.bouncycastle.asn1.DERUTF8String; import org.bouncycastle.asn1.cms.Attributes; import org.bouncycastle.asn1.cms.MetaData; import org.bouncycastle.cms.CMSException; import org.bouncycastle.operator.DigestCalculator; import org.bouncycastle.util.Integers; public class CMSTimeStampedGenerator { protected MetaData metaData; protected String dataUri; /** * Set the dataURI to be included in message. * * @param dataUri URI for the data the initial message imprint digest is based on. */ public void setDataUri(String dataUri) { this.dataUri = dataUri; } /** * Set the MetaData for the generated message. * * @param hashProtected true if the MetaData should be included in first imprint calculation, false otherwise. * @param fileName optional file name, may be null. * @param mediaType optional media type, may be null. */ public void setMetaData(boolean hashProtected, String fileName, String mediaType) { setMetaData(hashProtected, fileName, mediaType, null); } /** * Set the MetaData for the generated message. * * @param hashProtected true if the MetaData should be included in first imprint calculation, false otherwise. * @param fileName optional file name, may be null. * @param mediaType optional media type, may be null. * @param attributes optional attributes, may be null. */ public void setMetaData(boolean hashProtected, String fileName, String mediaType, Attributes attributes) { DERUTF8String asn1FileName = null; if (fileName != null) { asn1FileName = new DERUTF8String(fileName); } DERIA5String asn1MediaType = null; if (mediaType != null) { asn1MediaType = new DERIA5String(mediaType); } setMetaData(hashProtected, asn1FileName, asn1MediaType, attributes); } private void setMetaData(boolean hashProtected, DERUTF8String fileName, DERIA5String mediaType, Attributes attributes) { this.metaData = new MetaData(ASN1Boolean.getInstance(hashProtected), fileName, mediaType, attributes); } /** * Initialise the passed in calculator with the MetaData for this message, if it is * required as part of the initial message imprint calculation. After initialisation the * calculator can then be used to calculate the initial message imprint digest for the first * timestamp. * * @param calculator the digest calculator to be initialised. * @throws CMSException if the MetaData is required and cannot be processed */ public void initialiseMessageImprintDigestCalculator(DigestCalculator calculator) throws CMSException { MetaDataUtil util = new MetaDataUtil(metaData); util.initialiseMessageImprintDigestCalculator(calculator); } } bouncycastle-1.49.orig/j2me/org/bouncycastle/tsp/cms/CMSTimeStampedData.java0000644000175000017500000001525212150050436026355 0ustar ebourgebourgpackage org.bouncycastle.tsp.cms; import java.io.ByteArrayInputStream; import java.io.IOException; import java.io.InputStream; import org.bouncycastle.asn1.ASN1InputStream; import org.bouncycastle.asn1.DERIA5String; import org.bouncycastle.asn1.cms.AttributeTable; import org.bouncycastle.asn1.cms.CMSObjectIdentifiers; import org.bouncycastle.asn1.cms.ContentInfo; import org.bouncycastle.asn1.cms.Evidence; import org.bouncycastle.asn1.cms.TimeStampAndCRL; import org.bouncycastle.asn1.cms.TimeStampTokenEvidence; import org.bouncycastle.asn1.cms.TimeStampedData; import org.bouncycastle.cms.CMSException; import org.bouncycastle.operator.DigestCalculator; import org.bouncycastle.operator.DigestCalculatorProvider; import org.bouncycastle.operator.OperatorCreationException; import org.bouncycastle.tsp.TimeStampToken; public class CMSTimeStampedData { private TimeStampedData timeStampedData; private ContentInfo contentInfo; private TimeStampDataUtil util; public CMSTimeStampedData(ContentInfo contentInfo) { this.initialize(contentInfo); } public CMSTimeStampedData(InputStream in) throws IOException { try { initialize(ContentInfo.getInstance(new ASN1InputStream(in).readObject())); } catch (ClassCastException e) { throw new IOException("Malformed content: " + e); } catch (IllegalArgumentException e) { throw new IOException("Malformed content: " + e); } } public CMSTimeStampedData(byte[] baseData) throws IOException { this(new ByteArrayInputStream(baseData)); } private void initialize(ContentInfo contentInfo) { this.contentInfo = contentInfo; if (CMSObjectIdentifiers.timestampedData.equals(contentInfo.getContentType())) { this.timeStampedData = TimeStampedData.getInstance(contentInfo.getContent()); } else { throw new IllegalArgumentException("Malformed content - type must be " + CMSObjectIdentifiers.timestampedData.getId()); } util = new TimeStampDataUtil(this.timeStampedData); } public byte[] calculateNextHash(DigestCalculator calculator) throws CMSException { return util.calculateNextHash(calculator); } /** * Return a new timeStampedData object with the additional token attached. * * @throws CMSException */ public CMSTimeStampedData addTimeStamp(TimeStampToken token) throws CMSException { TimeStampAndCRL[] timeStamps = util.getTimeStamps(); TimeStampAndCRL[] newTimeStamps = new TimeStampAndCRL[timeStamps.length + 1]; System.arraycopy(timeStamps, 0, newTimeStamps, 0, timeStamps.length); newTimeStamps[timeStamps.length] = new TimeStampAndCRL(token.toCMSSignedData().toASN1Structure()); return new CMSTimeStampedData(new ContentInfo(CMSObjectIdentifiers.timestampedData, new TimeStampedData(timeStampedData.getDataUri(), timeStampedData.getMetaData(), timeStampedData.getContent(), new Evidence(new TimeStampTokenEvidence(newTimeStamps))))); } public byte[] getContent() { if (timeStampedData.getContent() != null) { return timeStampedData.getContent().getOctets(); } return null; } public String getDataUri() { DERIA5String dataURI = this.timeStampedData.getDataUri(); if (dataURI != null) { return dataURI.getString(); } return null; } public String getFileName() { return util.getFileName(); } public String getMediaType() { return util.getMediaType(); } public AttributeTable getOtherMetaData() { return util.getOtherMetaData(); } public TimeStampToken[] getTimeStampTokens() throws CMSException { return util.getTimeStampTokens(); } /** * Initialise the passed in calculator with the MetaData for this message, if it is * required as part of the initial message imprint calculation. * * @param calculator the digest calculator to be initialised. * @throws CMSException if the MetaData is required and cannot be processed */ public void initialiseMessageImprintDigestCalculator(DigestCalculator calculator) throws CMSException { util.initialiseMessageImprintDigestCalculator(calculator); } /** * Returns an appropriately initialised digest calculator based on the message imprint algorithm * described in the first time stamp in the TemporalData for this message. If the metadata is required * to be included in the digest calculation, the returned calculator will be pre-initialised. * * @param calculatorProvider a provider of DigestCalculator objects. * @return an initialised digest calculator. * @throws OperatorCreationException if the provider is unable to create the calculator. */ public DigestCalculator getMessageImprintDigestCalculator(DigestCalculatorProvider calculatorProvider) throws OperatorCreationException { return util.getMessageImprintDigestCalculator(calculatorProvider); } /** * Validate the digests present in the TimeStampTokens contained in the CMSTimeStampedData. * * @param calculatorProvider provider for digest calculators * @param dataDigest the calculated data digest for the message * @throws ImprintDigestInvalidException if an imprint digest fails to compare * @throws CMSException if an exception occurs processing the message. */ public void validate(DigestCalculatorProvider calculatorProvider, byte[] dataDigest) throws ImprintDigestInvalidException, CMSException { util.validate(calculatorProvider, dataDigest); } /** * Validate the passed in timestamp token against the tokens and data present in the message. * * @param calculatorProvider provider for digest calculators * @param dataDigest the calculated data digest for the message. * @param timeStampToken the timestamp token of interest. * @throws ImprintDigestInvalidException if the token is not present in the message, or an imprint digest fails to compare. * @throws CMSException if an exception occurs processing the message. */ public void validate(DigestCalculatorProvider calculatorProvider, byte[] dataDigest, TimeStampToken timeStampToken) throws ImprintDigestInvalidException, CMSException { util.validate(calculatorProvider, dataDigest, timeStampToken); } public byte[] getEncoded() throws IOException { return contentInfo.getEncoded(); } } bouncycastle-1.49.orig/j2me/org/bouncycastle/tsp/TimeStampTokenInfo.java0000644000175000017500000000441711732006176025752 0ustar ebourgebourgpackage org.bouncycastle.tsp; import java.io.IOException; import java.math.BigInteger; import java.util.Date; import org.bouncycastle.asn1.ASN1ObjectIdentifier; import org.bouncycastle.asn1.tsp.Accuracy; import org.bouncycastle.asn1.tsp.TSTInfo; import org.bouncycastle.asn1.x509.AlgorithmIdentifier; import org.bouncycastle.asn1.x509.GeneralName; public class TimeStampTokenInfo { TSTInfo tstInfo; Date genTime; TimeStampTokenInfo(TSTInfo tstInfo) throws TSPException, IOException { this.tstInfo = tstInfo; this.genTime = tstInfo.getGenTime().getDate(); } public boolean isOrdered() { return tstInfo.getOrdering().isTrue(); } public Accuracy getAccuracy() { return tstInfo.getAccuracy(); } public Date getGenTime() { return genTime; } public GenTimeAccuracy getGenTimeAccuracy() { if (this.getAccuracy() != null) { return new GenTimeAccuracy(this.getAccuracy()); } return null; } public ASN1ObjectIdentifier getPolicy() { return tstInfo.getPolicy(); } public BigInteger getSerialNumber() { return tstInfo.getSerialNumber().getValue(); } public GeneralName getTsa() { return tstInfo.getTsa(); } /** * @return the nonce value, null if there isn't one. */ public BigInteger getNonce() { if (tstInfo.getNonce() != null) { return tstInfo.getNonce().getValue(); } return null; } public AlgorithmIdentifier getHashAlgorithm() { return tstInfo.getMessageImprint().getHashAlgorithm(); } public ASN1ObjectIdentifier getMessageImprintAlgOID() { return tstInfo.getMessageImprint().getHashAlgorithm().getAlgorithm(); } public byte[] getMessageImprintDigest() { return tstInfo.getMessageImprint().getHashedMessage(); } public byte[] getEncoded() throws IOException { return tstInfo.getEncoded(); } /** * @deprecated use toASN1Structure * @return */ public TSTInfo toTSTInfo() { return tstInfo; } public TSTInfo toASN1Structure() { return tstInfo; } } bouncycastle-1.49.orig/j2me/org/bouncycastle/tsp/TimeStampToken.java0000644000175000017500000003007411732001726025130 0ustar ebourgebourgpackage org.bouncycastle.tsp; import java.io.ByteArrayInputStream; import java.io.ByteArrayOutputStream; import java.io.IOException; import java.io.OutputStream; import java.util.Collection; import java.util.Date; import org.bouncycastle.asn1.ASN1InputStream; import org.bouncycastle.asn1.cms.Attribute; import org.bouncycastle.asn1.cms.AttributeTable; import org.bouncycastle.asn1.cms.ContentInfo; import org.bouncycastle.asn1.cms.IssuerAndSerialNumber; import org.bouncycastle.asn1.ess.ESSCertID; import org.bouncycastle.asn1.ess.ESSCertIDv2; import org.bouncycastle.asn1.ess.SigningCertificate; import org.bouncycastle.asn1.ess.SigningCertificateV2; import org.bouncycastle.asn1.nist.NISTObjectIdentifiers; import org.bouncycastle.asn1.oiw.OIWObjectIdentifiers; import org.bouncycastle.asn1.pkcs.PKCSObjectIdentifiers; import org.bouncycastle.asn1.tsp.TSTInfo; import org.bouncycastle.asn1.x500.X500Name; import org.bouncycastle.asn1.x509.AlgorithmIdentifier; import org.bouncycastle.asn1.x509.GeneralName; import org.bouncycastle.asn1.x509.IssuerSerial; import org.bouncycastle.asn1.x509.X509Name; import org.bouncycastle.cert.X509CertificateHolder; import org.bouncycastle.cms.CMSException; import org.bouncycastle.cms.CMSProcessable; import org.bouncycastle.cms.CMSSignedData; import org.bouncycastle.cms.SignerId; import org.bouncycastle.cms.SignerInformation; import org.bouncycastle.cms.SignerInformationVerifier; import org.bouncycastle.operator.DigestCalculator; import org.bouncycastle.operator.OperatorCreationException; import org.bouncycastle.util.Arrays; import org.bouncycastle.util.Store; public class TimeStampToken { CMSSignedData tsToken; SignerInformation tsaSignerInfo; Date genTime; TimeStampTokenInfo tstInfo; CertID certID; public TimeStampToken(ContentInfo contentInfo) throws TSPException, IOException { this(getSignedData(contentInfo)); } private static CMSSignedData getSignedData(ContentInfo contentInfo) throws TSPException { try { return new CMSSignedData(contentInfo); } catch (CMSException e) { throw new TSPException("TSP parsing error: " + e.getMessage(), e.getCause()); } } public TimeStampToken(CMSSignedData signedData) throws TSPException, IOException { this.tsToken = signedData; if (!this.tsToken.getSignedContentTypeOID().equals(PKCSObjectIdentifiers.id_ct_TSTInfo.getId())) { throw new TSPValidationException("ContentInfo object not for a time stamp."); } Collection signers = tsToken.getSignerInfos().getSigners(); if (signers.size() != 1) { throw new IllegalArgumentException("Time-stamp token signed by " + signers.size() + " signers, but it must contain just the TSA signature."); } tsaSignerInfo = (SignerInformation)signers.iterator().next(); try { CMSProcessable content = tsToken.getSignedContent(); ByteArrayOutputStream bOut = new ByteArrayOutputStream(); content.write(bOut); ASN1InputStream aIn = new ASN1InputStream(new ByteArrayInputStream(bOut.toByteArray())); this.tstInfo = new TimeStampTokenInfo(TSTInfo.getInstance(aIn.readObject())); Attribute attr = tsaSignerInfo.getSignedAttributes().get(PKCSObjectIdentifiers.id_aa_signingCertificate); if (attr != null) { SigningCertificate signCert = SigningCertificate.getInstance(attr.getAttrValues().getObjectAt(0)); this.certID = new CertID(ESSCertID.getInstance(signCert.getCerts()[0])); } else { attr = tsaSignerInfo.getSignedAttributes().get(PKCSObjectIdentifiers.id_aa_signingCertificateV2); if (attr == null) { throw new TSPValidationException("no signing certificate attribute found, time stamp invalid."); } SigningCertificateV2 signCertV2 = SigningCertificateV2.getInstance(attr.getAttrValues().getObjectAt(0)); this.certID = new CertID(ESSCertIDv2.getInstance(signCertV2.getCerts()[0])); } } catch (CMSException e) { throw new TSPException(e.getMessage(), e.getUnderlyingException()); } } public TimeStampTokenInfo getTimeStampInfo() { return tstInfo; } public SignerId getSID() { return tsaSignerInfo.getSID(); } public AttributeTable getSignedAttributes() { return tsaSignerInfo.getSignedAttributes(); } public AttributeTable getUnsignedAttributes() { return tsaSignerInfo.getUnsignedAttributes(); } public Store getCertificates() { return tsToken.getCertificates(); } public Store getCRLs() { return tsToken.getCRLs(); } public Store getAttributeCertificates() { return tsToken.getAttributeCertificates(); } /** * Validate the time stamp token. *

    * To be valid the token must be signed by the passed in certificate and * the certificate must be the one referred to by the SigningCertificate * attribute included in the hashed attributes of the token. The * certificate must also have the ExtendedKeyUsageExtension with only * KeyPurposeId.id_kp_timeStamping and have been valid at the time the * timestamp was created. *

    *

    * A successful call to validate means all the above are true. *

    * * @param sigVerifier the content verifier create the objects required to verify the CMS object in the timestamp. * @throws TSPException if an exception occurs in processing the token. * @throws TSPValidationException if the certificate or signature fail to be valid. * @throws IllegalArgumentException if the sigVerifierProvider has no associated certificate. */ public void validate( SignerInformationVerifier sigVerifier) throws TSPException, TSPValidationException { if (!sigVerifier.hasAssociatedCertificate()) { throw new IllegalArgumentException("verifier provider needs an associated certificate"); } try { X509CertificateHolder certHolder = sigVerifier.getAssociatedCertificate(); DigestCalculator calc = sigVerifier.getDigestCalculator(certID.getHashAlgorithm()); OutputStream cOut = calc.getOutputStream(); cOut.write(certHolder.getEncoded()); cOut.close(); if (!Arrays.constantTimeAreEqual(certID.getCertHash(), calc.getDigest())) { throw new TSPValidationException("certificate hash does not match certID hash."); } if (certID.getIssuerSerial() != null) { IssuerAndSerialNumber issuerSerial = new IssuerAndSerialNumber(certHolder.toASN1Structure()); if (!certID.getIssuerSerial().getSerial().equals(issuerSerial.getSerialNumber())) { throw new TSPValidationException("certificate serial number does not match certID for signature."); } GeneralName[] names = certID.getIssuerSerial().getIssuer().getNames(); boolean found = false; for (int i = 0; i != names.length; i++) { if (names[i].getTagNo() == 4 && X500Name.getInstance(names[i].getName()).equals(X500Name.getInstance(issuerSerial.getName()))) { found = true; break; } } if (!found) { throw new TSPValidationException("certificate name does not match certID for signature. "); } } TSPUtil.validateCertificate(certHolder); if (!certHolder.isValidOn(tstInfo.getGenTime())) { throw new TSPValidationException("certificate not valid when time stamp created."); } if (!tsaSignerInfo.verify(sigVerifier)) { throw new TSPValidationException("signature not created by certificate."); } } catch (CMSException e) { if (e.getUnderlyingException() != null) { throw new TSPException(e.getMessage(), e.getUnderlyingException()); } else { throw new TSPException("CMS exception: " + e, e); } } catch (IOException e) { throw new TSPException("problem processing certificate: " + e, e); } catch (OperatorCreationException e) { throw new TSPException("unable to create digest: " + e.getMessage(), e); } } /** * Return true if the signature on time stamp token is valid. *

    * Note: this is a much weaker proof of correctness than calling validate(). *

    * * @param sigVerifier the content verifier create the objects required to verify the CMS object in the timestamp. * @return true if the signature matches, false otherwise. * @throws TSPException if the signature cannot be processed or the provider cannot match the algorithm. */ public boolean isSignatureValid( SignerInformationVerifier sigVerifier) throws TSPException { try { return tsaSignerInfo.verify(sigVerifier); } catch (CMSException e) { if (e.getUnderlyingException() != null) { throw new TSPException(e.getMessage(), e.getUnderlyingException()); } else { throw new TSPException("CMS exception: " + e, e); } } } /** * Return the underlying CMSSignedData object. * * @return the underlying CMS structure. */ public CMSSignedData toCMSSignedData() { return tsToken; } /** * Return a ASN.1 encoded byte stream representing the encoded object. * * @throws IOException if encoding fails. */ public byte[] getEncoded() throws IOException { return tsToken.getEncoded(); } // perhaps this should be done using an interface on the ASN.1 classes... private class CertID { private ESSCertID certID; private ESSCertIDv2 certIDv2; CertID(ESSCertID certID) { this.certID = certID; this.certIDv2 = null; } CertID(ESSCertIDv2 certID) { this.certIDv2 = certID; this.certID = null; } public String getHashAlgorithmName() { if (certID != null) { return "SHA-1"; } else { if (NISTObjectIdentifiers.id_sha256.equals(certIDv2.getHashAlgorithm().getAlgorithm())) { return "SHA-256"; } return certIDv2.getHashAlgorithm().getAlgorithm().getId(); } } public AlgorithmIdentifier getHashAlgorithm() { if (certID != null) { return new AlgorithmIdentifier(OIWObjectIdentifiers.idSHA1); } else { return certIDv2.getHashAlgorithm(); } } public byte[] getCertHash() { if (certID != null) { return certID.getCertHash(); } else { return certIDv2.getCertHash(); } } public IssuerSerial getIssuerSerial() { if (certID != null) { return certID.getIssuerSerial(); } else { return certIDv2.getIssuerSerial(); } } } } bouncycastle-1.49.orig/j2me/org/bouncycastle/tsp/TSPUtil.java0000644000175000017500000002263212103632343023527 0ustar ebourgebourgpackage org.bouncycastle.tsp; import java.io.ByteArrayInputStream; import java.io.IOException; import java.io.OutputStream; import java.util.ArrayList; import java.util.Collection; import java.util.Collections; import java.util.HashMap; import java.util.HashSet; import java.util.List; import java.util.Map; import java.util.Set; import org.bouncycastle.asn1.ASN1Encodable; import org.bouncycastle.asn1.ASN1EncodableVector; import org.bouncycastle.asn1.ASN1InputStream; import org.bouncycastle.asn1.ASN1ObjectIdentifier; import org.bouncycastle.asn1.ASN1OctetString; import org.bouncycastle.asn1.ASN1Set; import org.bouncycastle.asn1.cms.Attribute; import org.bouncycastle.asn1.cms.AttributeTable; import org.bouncycastle.asn1.cms.ContentInfo; import org.bouncycastle.asn1.cryptopro.CryptoProObjectIdentifiers; import org.bouncycastle.asn1.nist.NISTObjectIdentifiers; import org.bouncycastle.asn1.oiw.OIWObjectIdentifiers; import org.bouncycastle.asn1.pkcs.PKCSObjectIdentifiers; import org.bouncycastle.asn1.teletrust.TeleTrusTObjectIdentifiers; import org.bouncycastle.asn1.x509.ExtendedKeyUsage; import org.bouncycastle.asn1.x509.Extension; import org.bouncycastle.asn1.x509.Extensions; import org.bouncycastle.asn1.x509.ExtensionsGenerator; import org.bouncycastle.asn1.x509.KeyPurposeId; import org.bouncycastle.asn1.x509.X509Extensions; import org.bouncycastle.cert.X509CertificateHolder; import org.bouncycastle.cms.SignerInformation; import org.bouncycastle.operator.DigestCalculator; import org.bouncycastle.operator.DigestCalculatorProvider; import org.bouncycastle.operator.OperatorCreationException; import org.bouncycastle.util.Arrays; import org.bouncycastle.util.Integers; public class TSPUtil { private static Set EMPTY_SET = Collections.unmodifiableSet(new HashSet()); private static List EMPTY_LIST = Collections.unmodifiableList(new ArrayList()); private static final Map digestLengths = new HashMap(); private static final Map digestNames = new HashMap(); static { digestLengths.put(PKCSObjectIdentifiers.md5.getId(), Integers.valueOf(16)); digestLengths.put(OIWObjectIdentifiers.idSHA1.getId(), Integers.valueOf(20)); digestLengths.put(NISTObjectIdentifiers.id_sha224.getId(), Integers.valueOf(28)); digestLengths.put(NISTObjectIdentifiers.id_sha256.getId(), Integers.valueOf(32)); digestLengths.put(NISTObjectIdentifiers.id_sha384.getId(), Integers.valueOf(48)); digestLengths.put(NISTObjectIdentifiers.id_sha512.getId(), Integers.valueOf(64)); digestLengths.put(TeleTrusTObjectIdentifiers.ripemd128.getId(), Integers.valueOf(16)); digestLengths.put(TeleTrusTObjectIdentifiers.ripemd160.getId(), Integers.valueOf(20)); digestLengths.put(TeleTrusTObjectIdentifiers.ripemd256.getId(), Integers.valueOf(32)); digestLengths.put(CryptoProObjectIdentifiers.gostR3411.getId(), Integers.valueOf(32)); digestNames.put(PKCSObjectIdentifiers.md5.getId(), "MD5"); digestNames.put(OIWObjectIdentifiers.idSHA1.getId(), "SHA1"); digestNames.put(NISTObjectIdentifiers.id_sha224.getId(), "SHA224"); digestNames.put(NISTObjectIdentifiers.id_sha256.getId(), "SHA256"); digestNames.put(NISTObjectIdentifiers.id_sha384.getId(), "SHA384"); digestNames.put(NISTObjectIdentifiers.id_sha512.getId(), "SHA512"); digestNames.put(PKCSObjectIdentifiers.sha1WithRSAEncryption.getId(), "SHA1"); digestNames.put(PKCSObjectIdentifiers.sha224WithRSAEncryption.getId(), "SHA224"); digestNames.put(PKCSObjectIdentifiers.sha256WithRSAEncryption.getId(), "SHA256"); digestNames.put(PKCSObjectIdentifiers.sha384WithRSAEncryption.getId(), "SHA384"); digestNames.put(PKCSObjectIdentifiers.sha512WithRSAEncryption.getId(), "SHA512"); digestNames.put(TeleTrusTObjectIdentifiers.ripemd128.getId(), "RIPEMD128"); digestNames.put(TeleTrusTObjectIdentifiers.ripemd160.getId(), "RIPEMD160"); digestNames.put(TeleTrusTObjectIdentifiers.ripemd256.getId(), "RIPEMD256"); digestNames.put(CryptoProObjectIdentifiers.gostR3411.getId(), "GOST3411"); } /** * Fetches the signature time-stamp attributes from a SignerInformation object. * Checks that the MessageImprint for each time-stamp matches the signature field. * (see RFC 3161 Appendix A). * * @param signerInfo a SignerInformation to search for time-stamps * @param digCalcProvider provider for digest calculators * @return a collection of TimeStampToken objects * @throws TSPValidationException */ public static Collection getSignatureTimestamps(SignerInformation signerInfo, DigestCalculatorProvider digCalcProvider) throws TSPValidationException { List timestamps = new ArrayList(); AttributeTable unsignedAttrs = signerInfo.getUnsignedAttributes(); if (unsignedAttrs != null) { ASN1EncodableVector allTSAttrs = unsignedAttrs.getAll( PKCSObjectIdentifiers.id_aa_signatureTimeStampToken); for (int i = 0; i < allTSAttrs.size(); ++i) { Attribute tsAttr = (Attribute)allTSAttrs.get(i); ASN1Set tsAttrValues = tsAttr.getAttrValues(); for (int j = 0; j < tsAttrValues.size(); ++j) { try { ContentInfo contentInfo = ContentInfo.getInstance(tsAttrValues.getObjectAt(j)); TimeStampToken timeStampToken = new TimeStampToken(contentInfo); TimeStampTokenInfo tstInfo = timeStampToken.getTimeStampInfo(); DigestCalculator digCalc = digCalcProvider.get(tstInfo.getHashAlgorithm()); OutputStream dOut = digCalc.getOutputStream(); dOut.write(signerInfo.getSignature()); dOut.close(); byte[] expectedDigest = digCalc.getDigest(); if (!Arrays.constantTimeAreEqual(expectedDigest, tstInfo.getMessageImprintDigest())) { throw new TSPValidationException("Incorrect digest in message imprint"); } timestamps.add(timeStampToken); } catch (OperatorCreationException e) { throw new TSPValidationException("Unknown hash algorithm specified in timestamp"); } catch (Exception e) { throw new TSPValidationException("Timestamp could not be parsed"); } } } } return timestamps; } /** * Validate the passed in certificate as being of the correct type to be used * for time stamping. To be valid it must have an ExtendedKeyUsage extension * which has a key purpose identifier of id-kp-timeStamping. * * @param cert the certificate of interest. * @throws TSPValidationException if the certicate fails on one of the check points. */ public static void validateCertificate( X509CertificateHolder cert) throws TSPValidationException { if (cert.toASN1Structure().getVersionNumber() != 3) { throw new IllegalArgumentException("Certificate must have an ExtendedKeyUsage extension."); } Extension ext = cert.getExtension(Extension.extendedKeyUsage); if (ext == null) { throw new TSPValidationException("Certificate must have an ExtendedKeyUsage extension."); } if (!ext.isCritical()) { throw new TSPValidationException("Certificate must have an ExtendedKeyUsage extension marked as critical."); } ExtendedKeyUsage extKey = ExtendedKeyUsage.getInstance(ext.getParsedValue()); if (!extKey.hasKeyPurposeId(KeyPurposeId.id_kp_timeStamping) || extKey.size() != 1) { throw new TSPValidationException("ExtendedKeyUsage not solely time stamping."); } } /* * Return the digest algorithm using one of the standard JCA string * representations rather than the algorithm identifier (if possible). */ static String getDigestAlgName( String digestAlgOID) { String digestName = (String)digestNames.get(digestAlgOID); if (digestName != null) { return digestName; } return digestAlgOID; } static int getDigestLength( String digestAlgOID) throws TSPException { Integer length = (Integer)digestLengths.get(digestAlgOID); if (length != null) { return length.intValue(); } throw new TSPException("digest algorithm cannot be found."); } static List getExtensionOIDs(Extensions extensions) { if (extensions == null) { return EMPTY_LIST; } return Collections.unmodifiableList(java.util.Arrays.asList(extensions.getExtensionOIDs())); } static void addExtension(ExtensionsGenerator extGenerator, ASN1ObjectIdentifier oid, boolean isCritical, ASN1Encodable value) throws TSPIOException { try { extGenerator.addExtension(oid, isCritical, value); } catch (IOException e) { throw new TSPIOException("cannot encode extension: " + e.getMessage(), e); } } } bouncycastle-1.49.orig/j2me/org/bouncycastle/operator/0000755000175000017500000000000012152033550022377 5ustar ebourgebourgbouncycastle-1.49.orig/j2me/org/bouncycastle/operator/bc/0000755000175000017500000000000012152033550022763 5ustar ebourgebourgbouncycastle-1.49.orig/j2me/org/bouncycastle/operator/bc/OperatorUtils.java0000644000175000017500000000055711731751377026471 0ustar ebourgebourgpackage org.bouncycastle.operator.bc; import org.bouncycastle.operator.GenericKey; class OperatorUtils { static byte[] getKeyBytes(GenericKey key) { if (key.getRepresentation() instanceof byte[]) { return (byte[])key.getRepresentation(); } throw new IllegalArgumentException("unknown generic key type"); } } bouncycastle-1.49.orig/j2me/java/0000755000175000017500000000000012152033550016203 5ustar ebourgebourgbouncycastle-1.49.orig/j2me/java/util/0000755000175000017500000000000012152033550017160 5ustar ebourgebourgbouncycastle-1.49.orig/j2me/java/util/AbstractCollection.java0000644000175000017500000001315412062253471023614 0ustar ebourgebourgpackage java.util; public abstract class AbstractCollection implements Collection { protected AbstractCollection() { } public abstract Iterator iterator(); public abstract int size(); public boolean isEmpty() { return size() == 0; } public boolean contains(Object o) { Iterator it = iterator(); while (it.hasNext()) { Object e = it.next(); if (o == null) { if (e == null) { return true; } } else { if (o.equals(e)) { return true; } } } return false; } public Object[] toArray() { Object[] arObjects = new Object[size()]; Iterator it = iterator(); int i = 0; while (it.hasNext()) { arObjects[i++] = it.next(); } return arObjects; } public Object[] toArray(Object[] a) throws NullPointerException, ArrayStoreException //TODO: Check if this is realy compatible to SUN!!! { if (a == null) { throw new NullPointerException(); } if (isEmpty()) { return a; } Object[] arObjects = null; int size = size(); if (a.length < size) { Iterator it = iterator(); Object o = it.next(); if (o == null) //no object or object is null { throw new ArrayStoreException(); //correct ? } throw new ArrayStoreException("please pass array of correct size"); } else { arObjects = a; if (a.length > size) { arObjects[size] = null; } } Iterator it = iterator(); int i = 0; while (it.hasNext()) { Object o = it.next(); arObjects[i++] = o; } return arObjects; } public boolean add(Object o) throws RuntimeException, NullPointerException, ClassCastException, IllegalArgumentException { throw new RuntimeException(); } public boolean remove(Object o) throws RuntimeException { Iterator it = iterator(); while (it.hasNext()) { Object e = it.next(); if (o == null) { if (e == null) { try { it.remove(); } catch (RuntimeException ue) { throw ue; } return true; } } else { if (o.equals(e)) { try { it.remove(); } catch (RuntimeException ue) { throw ue; } return true; } } } return false; } public boolean containsAll(Collection c) { Iterator it = c.iterator(); while (it.hasNext()) { if (!contains(it.next())) { return false; } } return true; } public boolean addAll(Collection c) throws RuntimeException { Iterator it = c.iterator(); boolean ret = false; while (it.hasNext()) { try { ret |= add(it.next()); } catch (RuntimeException ue) { throw ue; } } return ret; } public boolean removeAll(Collection c) throws RuntimeException { Iterator it = iterator(); boolean ret = false; while (it.hasNext()) { if (c.contains(it.next())) { try { it.remove(); ret = true; } catch (RuntimeException ue) { throw ue; } } } return ret; } public boolean retainAll(Collection c) throws RuntimeException { Iterator it = iterator(); boolean ret = false; while (it.hasNext()) { if (!c.contains(it.next())) { try { it.remove(); ret = true; } catch (RuntimeException ue) { throw ue; } } } return ret; } public void clear() throws RuntimeException { Iterator it = iterator(); while (it.hasNext()) { try { it.next(); it.remove(); } catch (RuntimeException ue) { throw ue; } } } public String toString() { StringBuffer ret = new StringBuffer("["); Iterator it = iterator(); if (it.hasNext()) { ret.append(String.valueOf(it.next())); } while (it.hasNext()) { ret.append(", "); ret.append(String.valueOf(it.next())); } ret.append("]"); return ret.toString(); } } bouncycastle-1.49.orig/j2me/java/util/ArrayList.java0000644000175000017500000000454411731760703021755 0ustar ebourgebourgpackage java.util; public class ArrayList extends AbstractList implements List { Vector m_Vector=null; public ArrayList() { m_Vector=new Vector(); } public ArrayList(Collection c) { m_Vector=new Vector((int)(c.size()*1.1)); addAll(c); } public ArrayList(int initialCapacity) { m_Vector=new Vector(initialCapacity); } public void trimToSize() { m_Vector.trimToSize(); } public void ensureCapacity(int minCapacity) { m_Vector.ensureCapacity(minCapacity); } public int size() { return m_Vector.size(); } public boolean contains(Object elem) { return m_Vector.contains(elem); } public int indexOf(Object elem) { return m_Vector.indexOf(elem); } public int lastIndexOf(Object elem) { return m_Vector.lastIndexOf(elem); } public Object clone() { ArrayList al=new ArrayList(this); return al; } public Object[] toArray() { Object[] o=new Object[m_Vector.size()]; m_Vector.copyInto(o); return o; } public Object get(int index) { return m_Vector.elementAt(index); } public Object set(int index,Object elem) { Object o=m_Vector.elementAt(index); m_Vector.setElementAt(elem,index); return o; } public boolean add(Object o) { m_Vector.addElement(o); return true; } public void add(int index,Object elem) { m_Vector.insertElementAt(elem,index); } public Object remove(int index) { Object o=m_Vector.elementAt(index); m_Vector.removeElementAt(index); return o; } public void clear() { m_Vector.removeAllElements(); } } bouncycastle-1.49.orig/j2me/java/util/AbstractMap.java0000644000175000017500000000721711732445210022236 0ustar ebourgebourgpackage java.util; public abstract class AbstractMap implements Map { protected AbstractMap() { } public int size() { return entrySet().size(); } public boolean isEmpty() { return size() == 0; } public boolean containsValue(Object value) { Iterator it = entrySet().iterator(); while (it.hasNext()) { Map.Entry v = (Map.Entry)it.next(); if (value == null) { if (v.getValue() == null) { return true; } } else { if (value.equals(v.getValue())) { return true; } } } return false; } public boolean containsKey(Object key) throws ClassCastException, NullPointerException { Iterator it = entrySet().iterator(); while (it.hasNext()) { Map.Entry v = (Map.Entry)it.next(); if (key == null) { if (v.getKey() == null) { return true; } } else { if (key.equals(v.getKey())) { return true; } } } return false; } public Object get(Object key) throws ClassCastException, NullPointerException { Iterator it = entrySet().iterator(); while (it.hasNext()) { Map.Entry v = (Map.Entry)it.next(); if (key == null) { if (v.getKey() == null) { return v.getValue(); } } else { if (key.equals(v.getKey())) { return v.getValue(); } } } return null; } public Object put(Object key, Object value) throws RuntimeException { throw new RuntimeException(); } public Object remove(Object key) { Iterator it = entrySet().iterator(); Object o = null; while (it.hasNext()) { Map.Entry v = (Map.Entry)it.next(); if (key == null) { if (v.getKey() == null) { o = v.getValue(); it.remove(); return o; } } else { if (key.equals(v.getKey())) { o = v.getValue(); it.remove(); return o; } } } return null; } public void putAll(Map t) { Iterator it = t.entrySet().iterator(); while (it.hasNext()) { Map.Entry v = (Map.Entry)it.next(); put(v.getKey(), v.getValue()); } } public void clear() { entrySet().clear(); } public Set keySet() { throw new RuntimeException("no keySet in AbstractMap()"); } public Collection values() { throw new RuntimeException("no values in AbstractMap()"); } public abstract Set entrySet(); public boolean equals(Object o) { throw new RuntimeException("no equals in AbstractMap()"); } public int hashCode() { throw new RuntimeException("no hashCode in AbstractMap()"); } public String toString() { throw new RuntimeException("no toString in AbstractMap()"); } } bouncycastle-1.49.orig/j2me/java/util/StringTokenizer.java0000644000175000017500000000407011731751623023177 0ustar ebourgebourgpackage java.util; import java.util.Enumeration; import java.util.NoSuchElementException; public class StringTokenizer implements Enumeration { private String s; private String delims; private boolean retDelims; private int maxPos; private int pos; public StringTokenizer(String s, String delims) { this(s, delims, false); } public StringTokenizer(String s, String delims, boolean retDelims) { this.s = s; this.delims = delims; this.retDelims = retDelims; this.maxPos = s.length(); } public boolean hasMoreTokens() { if (retDelims) { return pos < maxPos; } else { int next = pos; while (next < maxPos && isDelim(next)) { next++; } return next < maxPos; } } public String nextToken() { String tok; if (pos == maxPos) { throw new NoSuchElementException("no more tokens"); } if (retDelims) { if (isDelim(pos)) { tok = s.substring(pos, pos + 1); pos++; return tok; } } while (pos < maxPos && isDelim(pos)) { pos++; } int start = pos; while (pos < maxPos && !isDelim(pos)) { pos++; } if (pos < maxPos) { tok = s.substring(start, pos); } else { tok = s.substring(start); } return tok; } public boolean hasMoreElements() { return hasMoreTokens(); } public Object nextElement() { return nextToken(); } private boolean isDelim(int index) { char c = s.charAt(index); for (int i = 0; i != delims.length(); i++) { if (delims.charAt(i) == c) { return true; } } return false; } } bouncycastle-1.49.orig/j2me/java/util/List.java0000644000175000017500000000165411732445210020747 0ustar ebourgebourgpackage java.util; public interface List extends Collection { void add(int index, Object element) throws RuntimeException, ClassCastException, IllegalArgumentException, IndexOutOfBoundsException; boolean addAll(int index, Collection c) throws RuntimeException, ClassCastException, IllegalArgumentException, IndexOutOfBoundsException; Object get(int index) throws IndexOutOfBoundsException; int indexOf(Object o); int lastIndexOf(Object o); ListIterator listIterator(); ListIterator listIterator(int index) throws IndexOutOfBoundsException; Object remove(int index) throws RuntimeException, IndexOutOfBoundsException; Object set(int index, Object element) throws RuntimeException, ClassCastException, IllegalArgumentException, IndexOutOfBoundsException; List subList(int fromIndex, int toIndex) throws IndexOutOfBoundsException; } bouncycastle-1.49.orig/j2me/java/util/Set.java0000644000175000017500000000115011732445210020556 0ustar ebourgebourgpackage java.util; public interface Set extends Collection { public int size(); public boolean isEmpty(); public boolean contains(Object o); public Iterator iterator(); public Object[] toArray(); public Object[] toArray(Object[] a); public boolean add(Object o); public boolean remove(Object o); public boolean containsAll(Collection c); public boolean addAll(Collection c); public boolean retainAll(Collection c); public boolean removeAll(Collection c); public void clear(); public boolean equals(Object o); public int hashCode(); } bouncycastle-1.49.orig/j2me/java/util/ListIterator.java0000644000175000017500000000074311732445210022457 0ustar ebourgebourgpackage java.util; public interface ListIterator extends Iterator { public boolean hasPrevious(); public Object previous() throws NoSuchElementException; public int nextIndex(); public int previousIndex(); public void set(Object o) throws RuntimeException, ClassCastException, IllegalArgumentException, IllegalStateException; public void add(Object o) throws RuntimeException, ClassCastException, IllegalArgumentException; } bouncycastle-1.49.orig/j2me/java/util/AbstractList.java0000644000175000017500000001553111732445210022432 0ustar ebourgebourgpackage java.util; public abstract class AbstractList extends AbstractCollection implements List { protected AbstractList al = this; protected AbstractList() { } public boolean add(Object o) throws RuntimeException, ClassCastException, IllegalArgumentException { try { add(size(), o); return true; } catch (RuntimeException ue) { throw ue; } } public abstract Object get(int index) throws IndexOutOfBoundsException; public Object set(int index, Object element) throws RuntimeException, ClassCastException, IllegalArgumentException, IndexOutOfBoundsException { throw new RuntimeException(); } public void add(int index, Object element) throws RuntimeException, ClassCastException, IllegalArgumentException, IndexOutOfBoundsException { throw new RuntimeException(); } public Object remove(int index) throws RuntimeException, IndexOutOfBoundsException { Object o = get(index); removeRange(index, index + 1); return o; } public int indexOf(Object o) { ListIterator li = listIterator(); Object e; while (li.hasNext()) { int index = li.nextIndex(); e = li.next(); System.out.println(e); if (o == null) { if (e == null) { return index; } } else { if (o.equals(e)) { return index; } } } return -1; } public int lastIndexOf(Object o) { ListIterator li = listIterator(size()); while (li.hasPrevious()) { int index = li.previousIndex(); Object e = li.previous(); if (o == null) { if (e == null) { return index; } } else { if (o.equals(e)) { return index; } } } return -1; } public void clear() throws RuntimeException { try { removeRange(0, size()); } catch (RuntimeException ue) { throw ue; } } public boolean addAll(int index, Collection c) throws RuntimeException, ClassCastException, IllegalArgumentException, IndexOutOfBoundsException { Iterator it = c.iterator(); boolean ret = false; while (it.hasNext()) { try { add(index++, it.next()); ret = true; } catch (RuntimeException ue) { throw ue; } } return ret; } public Iterator iterator() { return new AbstractListIterator(this, 0); } public ListIterator listIterator() { return listIterator(0); } public ListIterator listIterator(int index) throws IndexOutOfBoundsException { if (index < 0 || index > size()) { throw new IndexOutOfBoundsException(); } return new AbstractListListIterator(this, index); } public List subList(int fromIndex, int toIndex) throws IndexOutOfBoundsException, IllegalArgumentException { if (fromIndex < 0 || toIndex > size()) { throw new IndexOutOfBoundsException(); } if (fromIndex > toIndex) { throw new IllegalArgumentException(); } return (List)new Sublist(this, fromIndex, toIndex); } public boolean equals(Object o) { if (o == this) { return true; } if (!(o instanceof List)) { return false; } Iterator it1 = iterator(); Iterator it2 = ((List)o).iterator(); while (it1.hasNext()) { if (!it2.hasNext()) { return false; } Object e1 = it1.next(); Object e2 = it2.next(); if (e1 == null) { if (e2 != null) { return false; } } if (!e1.equals(e2)) { return false; } } return true; } public int hashCode() { int hashCode = 1; Iterator it = iterator(); while (it.hasNext()) { Object o = it.next(); hashCode = 31 * hashCode + (o == null ? 0 : o.hashCode()); } return hashCode; } protected void removeRange(int fromIndex, int toIndex) { System.out.println("breakpoint 1"); if (fromIndex == toIndex) { return; } System.out.println("breakpoint 2"); ListIterator li = listIterator(fromIndex); System.out.println("breakpoint 3"); int i = fromIndex; do { li.next(); li.remove(); i++; } while (li.hasNext() && i < toIndex); } private class AbstractListIterator implements Iterator { AbstractList m_al = null; int m_nextIndex = 0; public AbstractListIterator(AbstractList al, int index) { m_al = al; m_nextIndex = index; } public boolean hasNext() { return m_nextIndex < m_al.size(); } public Object next() { return m_al.get(m_nextIndex++); } public void remove() { m_al.remove(m_nextIndex - 1); } } private class AbstractListListIterator extends AbstractListIterator implements ListIterator { public AbstractListListIterator(AbstractList al, int index) { super(al, index); } public boolean hasPrevious() { return m_nextIndex > 0; } public Object previous()// throws NoSuchElementException; { return m_al.get(--m_nextIndex); } public int nextIndex() { return m_nextIndex; } public int previousIndex() { return m_nextIndex - 1; } public void set(Object o) //throws RuntimeException, ClassCastException, IllegalArgumentException,IllegalStateException; { m_al.set(m_nextIndex - 1, o); } public void add(Object o)// throws RuntimeException, ClassCastException, IllegalArgumentException; { m_al.add(m_nextIndex - 1, o); } } } bouncycastle-1.49.orig/j2me/java/util/HashSet.java0000644000175000017500000000222211732445455021376 0ustar ebourgebourgpackage java.util; public class HashSet extends AbstractSet { private HashMap m_HashMap = null; public HashSet() { m_HashMap = new HashMap(); } public HashSet(Collection c) { m_HashMap = new HashMap(Math.max(11, c.size() * 2)); addAll(c); } public HashSet(int initialCapacity) { m_HashMap = new HashMap(initialCapacity); } public Iterator iterator() { return (m_HashMap.keySet()).iterator(); } public int size() { return m_HashMap.size(); } public boolean contains(Object o) { return m_HashMap.containsKey(o); } public boolean add(Object o) { if (!m_HashMap.containsValue(o)) { m_HashMap.put((Object)o, (Object)o); return true; } return false; } public boolean remove(Object o) { return (m_HashMap.remove(o) != null); } public void clear() { m_HashMap.clear(); } public Object clone() { HashSet hs = new HashSet(); hs.m_HashMap = (HashMap)m_HashMap.clone(); return hs; } } bouncycastle-1.49.orig/j2me/java/util/Collections.java0000644000175000017500000001735311732452732022324 0ustar ebourgebourgpackage java.util; public class Collections { public static List EMPTY_LIST = new ArrayList(); private Collections() { } public static Collection unmodifiableCollection(Collection c) { return new UnmodifiableCollection(c); } static class UnmodifiableCollection implements Collection { Collection c; UnmodifiableCollection(Collection c) { this.c = c; } public int size() { return c.size(); } public boolean isEmpty() { return c.isEmpty(); } public boolean contains(Object o) { return c.contains(o); } public Object[] toArray() { return c.toArray(); } public Object[] toArray(Object[] a) { return c.toArray(a); } public Iterator iterator() { return new Iterator() { Iterator i = c.iterator(); public boolean hasNext() { return i.hasNext(); } public Object next() { return i.next(); } public void remove() { throw new RuntimeException(); } }; } public boolean add(Object o) { throw new RuntimeException(); } public boolean remove(Object o) { throw new RuntimeException(); } public boolean containsAll(Collection coll) { return c.containsAll(coll); } public boolean addAll(Collection coll) { throw new RuntimeException(); } public boolean removeAll(Collection coll) { throw new RuntimeException(); } public boolean retainAll(Collection coll) { throw new RuntimeException(); } public void clear() { throw new RuntimeException(); } public String toString() { return c.toString(); } } public static Set unmodifiableSet(Set s) { return new UnmodifiableSet(s); } static class UnmodifiableSet extends UnmodifiableCollection implements Set { UnmodifiableSet(Set s) { super(s); } public boolean equals(Object o) { return c.equals(o); } public int hashCode() { return c.hashCode(); } } public static Map unmodifiableMap(Map map) { return new UnmodifiableMap(map); } static class UnmodifiableMap implements Map { private Map map; UnmodifiableMap(Map map) { this.map = map; } public int size() { return map.size(); } public boolean isEmpty() { return map.isEmpty(); } public boolean containsKey(Object key) throws ClassCastException, NullPointerException { return map.containsKey(key); } public boolean containsValue(Object value) { return map.containsValue(value); } public Object get(Object key) throws ClassCastException, NullPointerException { return map.get(key); } public Object put(Object key, Object value) throws RuntimeException, ClassCastException, IllegalArgumentException, NullPointerException { throw new RuntimeException("unsupported operation - map unmodifiable"); } public Object remove(Object key) throws RuntimeException { throw new RuntimeException("unsupported operation - map unmodifiable"); } public void putAll(Map t) throws RuntimeException, ClassCastException, IllegalArgumentException, NullPointerException { throw new RuntimeException("unsupported operation - map unmodifiable"); } public void clear() throws RuntimeException { throw new RuntimeException("unsupported operation - map unmodifiable"); } public Set keySet() { return map.keySet(); } public Collection values() { return map.values(); } public Set entrySet() { return map.entrySet(); } } public static List unmodifiableList(List list) { return new UnmodifiableList(list); } static class UnmodifiableList extends UnmodifiableCollection implements List { private List list; UnmodifiableList(List list) { super(list); this.list = list; } public boolean equals(Object o) { return list.equals(o); } public int hashCode() { return list.hashCode(); } public Object get(int index) { return list.get(index); } public Object set(int index, Object element) { throw new RuntimeException(); } public void add(int index, Object element) { throw new RuntimeException(); } public Object remove(int index) { throw new RuntimeException(); } public int indexOf(Object o) { return list.indexOf(o); } public int lastIndexOf(Object o) { return list.lastIndexOf(o); } public boolean addAll(int index, Collection c) { throw new RuntimeException(); } public ListIterator listIterator() { return listIterator(0); } public ListIterator listIterator(final int index) { return new ListIterator() { ListIterator i = list.listIterator(index); public boolean hasNext() { return i.hasNext(); } public Object next() { return i.next(); } public boolean hasPrevious() { return i.hasPrevious(); } public Object previous() { return i.previous(); } public int nextIndex() { return i.nextIndex(); } public int previousIndex() { return i.previousIndex(); } public void remove() { throw new RuntimeException(); } public void set(Object o) { throw new RuntimeException(); } public void add(Object o) { throw new RuntimeException(); } }; } public List subList(int fromIndex, int toIndex) { return new UnmodifiableList(list.subList(fromIndex, toIndex)); } } public static Enumeration enumeration(final Collection c) { return new Enumeration() { Iterator i = c.iterator(); public boolean hasMoreElements() { return i.hasNext(); } public Object nextElement() { return i.next(); } }; } } bouncycastle-1.49.orig/j2me/java/util/Sublist.java0000644000175000017500000000564011732445367021475 0ustar ebourgebourgpackage java.util; public class Sublist extends AbstractList { AbstractList m_al = null; int m_fromIndex = 0; int m_toIndex = 0; int size = 0; public Sublist(AbstractList ali, int fromIndex, int toIndex) { m_al = ali; m_toIndex = toIndex; m_fromIndex = fromIndex; size = size(); } public Object set(int index, Object o) { if (index < size) { o = m_al.set(index + m_fromIndex, o); if (o != null) { size++; m_toIndex++; } return o; } else { throw new IndexOutOfBoundsException(); } } public Object get(int index) throws IndexOutOfBoundsException { if (index < size) { return m_al.get(index + m_fromIndex); } else { throw new IndexOutOfBoundsException(); } } public void add(int index, Object o) { if (index <= size) { m_al.add(index + m_fromIndex, o); m_toIndex++; size++; } else { throw new IndexOutOfBoundsException(); } } public Object remove(int index, Object o) { if (index < size) { Object ob = m_al.remove(index + m_fromIndex); if (ob != null) { m_toIndex--; size--; } return ob; } else { throw new IndexOutOfBoundsException(); } } public boolean addAll(int index, Collection c) { if (index < size) { boolean bool = m_al.addAll(index + m_fromIndex, c); if (bool) { int lange = c.size(); m_toIndex = m_toIndex + lange; size = size + lange; } return bool; } else { throw new IndexOutOfBoundsException(); } } public boolean addAll(Collection c) { boolean bool = m_al.addAll(m_toIndex, c); if (bool) { int lange = c.size(); m_toIndex = m_toIndex + lange; size = size + lange; } return bool; } public void removeRange(int from, int to) { if ((from <= to) && (from <= size) && (to <= size)) { m_al.removeRange(from, to); int lange = to - from; m_toIndex = m_toIndex - lange; size = size - lange; } else { if (from > to) { throw new IllegalArgumentException(); } else { throw new IndexOutOfBoundsException(); } } } public int size() { return (m_toIndex - m_fromIndex); } } bouncycastle-1.49.orig/j2me/java/util/Collection.java0000644000175000017500000000172611731751622022135 0ustar ebourgebourg package java.util; public interface Collection { public boolean add(Object o) throws RuntimeException,ClassCastException,IllegalArgumentException; public boolean addAll(Collection c) throws RuntimeException,ClassCastException,IllegalArgumentException; public void clear() throws RuntimeException; public boolean contains(Object o); public boolean containsAll(Collection c); public boolean equals(Object o); public int hashCode(); public boolean isEmpty(); public Iterator iterator(); public /*SK13*/boolean remove(Object o) throws RuntimeException; public boolean removeAll(Collection c) throws RuntimeException; public boolean retainAll(Collection c) throws RuntimeException; public int size(); public Object[] toArray(); public Object[] toArray(Object[] a) throws ArrayStoreException; } bouncycastle-1.49.orig/j2me/java/util/AbstractSet.java0000644000175000017500000000151511732445210022247 0ustar ebourgebourgpackage java.util; public abstract class AbstractSet extends AbstractCollection implements Set { protected AbstractSet() { } public boolean equals(Object o) { if (this == o) { return true; } if (o == null) { return false; } if (!(o instanceof Set)) { return false; } if (((Set)o).size() != size()) { return false; } return containsAll((Collection)o); } public int hashCode() { int hashCode = 0; Iterator it = iterator(); while (it.hasNext()) { Object o = it.next(); if (o != null) { hashCode += o.hashCode(); } } return hashCode; } } bouncycastle-1.49.orig/j2me/java/util/HashMap.java0000644000175000017500000001362411731760461021364 0ustar ebourgebourgpackage java.util; public class HashMap extends AbstractMap{ ////////////////////////////////////////////////////////////// ///// innere Klasse Null //////////////////////////////////// ////////////////////////////////////////////////////////////// public class Null extends Object { public Null() { } public String toString() { return "Nullobject"; } } ////////////////////////////////////////////////////////////// ///// innere Klasse innerSet //////////////////////////////////// ////////////////////////////////////////////////////////////// class ISet extends AbstractSet implements java.util.Set { Vector vec = null; public ISet() { vec = new Vector(); } public boolean add(Object o) { vec.addElement(o); return true; } public int size() { return vec.size(); } public Iterator iterator() { return new IIterator(vec); } } ////////////////////////////////////////////////////////////// ///// innere Klasse Iterator //////////////////////////////////// ////////////////////////////////////////////////////////////// class IIterator implements java.util.Iterator { int index = 0; Vector vec = null; public IIterator(Vector ve) { vec = ve; } public boolean hasNext() { if (vec.size() > index) return true; return false; } public Object next() { Object o = vec.elementAt(index); if (o==Nullobject) o=null; index++; return o; } public void remove() { index--; vec.removeElementAt(index); } } ////////////////////////////////////////////////////////////// ///// innere Klasse Entry //////////////////////////////////// ////////////////////////////////////////////////////////////// class Entry implements Map.Entry { public Object key=null; public Object value=null; public Entry(Object ke,Object valu) { key = ke; value = valu; } public boolean equals(Object o) { if (value == ((Entry)o).value && key == ((Entry)o).key ) return true; else return false; } public Object getValue() { return value; } public Object getKey() { return (Object)key; } public int hashCode() { return value.hashCode() + key.hashCode(); } public Object setValue(Object valu) { value = (String)valu; return this; } } //////////////////////////////////////////////////////////////////// private Hashtable m_HashTable=null; private Null Nullobject = null; public HashMap() { Nullobject = new Null(); m_HashTable=new Hashtable(); } public HashMap(int initialCapacity) { Nullobject = new Null(); m_HashTable=new Hashtable(initialCapacity); } public HashMap(Map t) { Nullobject = new Null(); m_HashTable=new Hashtable(); this.putAll(t); } public void clear() { m_HashTable.clear(); } public Object clone() { HashMap hm=new HashMap(this); return hm; } public boolean containsKey(Object key) { if (key == null) key = Nullobject; boolean b = m_HashTable.containsKey(key); return b; } public boolean containsValue(Object value) { if (value == null ) value = Nullobject; boolean b = m_HashTable.contains(value); return b; } public Set entrySet() { Object Key = null; ISet s = new ISet(); Enumeration en = m_HashTable.keys(); while (en.hasMoreElements()) { Key = en.nextElement(); s.add(new Entry(Key,m_HashTable.get(Key))); } return s; } public Object get(Object key) { if (key==null) key= Nullobject; Object o = m_HashTable.get(key); if (o == Nullobject) o=null; return o; } public boolean isEmpty() { return m_HashTable.isEmpty(); } public Set keySet() { ISet s=new ISet(); Enumeration en = m_HashTable.keys(); while (en.hasMoreElements()) { s.add(en.nextElement()); } return s; } public Object put(Object key, Object value) { if (key==null) key=Nullobject; if (value==null) value = Nullobject; return m_HashTable.put(key,value); } public void putAll(Map m) { Iterator it = m.entrySet().iterator(); Object key=null; Object value=null; while (it.hasNext()) { Map.Entry me = (Map.Entry)it.next(); if (me.getKey() == null) key = Nullobject; else key= me.getKey(); if (me.getValue()==null) value = Nullobject; else value = me.getValue(); m_HashTable.put(key,value); } } public Object remove(Object key) { return m_HashTable.remove(key); } public int size() { return m_HashTable.size(); } public Collection values() { ISet s=new ISet(); Enumeration en = m_HashTable.keys(); while (en.hasMoreElements()) { Object Key = en.nextElement(); //s.add(((Map.Entry)m_HashTable.get(Key)).getValue()); s.add(m_HashTable.get(Key)); } return s; } } bouncycastle-1.49.orig/j2me/java/util/Iterator.java0000644000175000017500000000035411731751622021627 0ustar ebourgebourg package java.util; public interface Iterator { public abstract boolean hasNext(); public abstract Object next() throws NoSuchElementException; public abstract void remove() throws RuntimeException,IllegalStateException; } bouncycastle-1.49.orig/j2me/java/util/Arrays.java0000644000175000017500000000424611732460221021274 0ustar ebourgebourgpackage java.util; public class Arrays { private Arrays() { } public static void fill(byte[] ret, byte v) { for (int i = 0; i != ret.length; i++) { ret[i] = v; } } public static boolean equals(byte[] a, byte[] a2) { if (a == a2) { return true; } if (a == null || a2 == null) { return false; } int length = a.length; if (a2.length != length) { return false; } for (int i = 0; i < length; i++) { if (a[i] != a2[i]) { return false; } } return true; } public static List asList(Object[] a) { return new ArrayList(a); } private static class ArrayList extends AbstractList { private Object[] a; ArrayList(Object[] array) { a = array; } public int size() { return a.length; } public Object[] toArray() { Object[] tmp = new Object[a.length]; System.arraycopy(a, 0, tmp, 0, tmp.length); return tmp; } public Object get(int index) { return a[index]; } public Object set(int index, Object element) { Object oldValue = a[index]; a[index] = element; return oldValue; } public int indexOf(Object o) { if (o == null) { for (int i = 0; i < a.length; i++) { if (a[i] == null) { return i; } } } else { for (int i = 0; i < a.length; i++) { if (o.equals(a[i])) { return i; } } } return -1; } public boolean contains(Object o) { return indexOf(o) != -1; } } } bouncycastle-1.49.orig/j2me/java/util/Map.java0000644000175000017500000000233611732445210020547 0ustar ebourgebourgpackage java.util; public interface Map { public static interface Entry { public Object getKey(); public Object getValue(); public Object setValue(Object value) throws RuntimeException, ClassCastException, IllegalArgumentException, NullPointerException; public boolean equals(Object o); public int hashCode(); } public int size(); public boolean isEmpty(); public boolean containsKey(Object Key) throws ClassCastException, NullPointerException; public boolean containsValue(Object value); public Object get(Object key) throws ClassCastException, NullPointerException; public Object put(Object key, Object value) throws RuntimeException, ClassCastException, IllegalArgumentException, NullPointerException; public Object remove(Object key) throws RuntimeException; public void putAll(Map t) throws RuntimeException, ClassCastException, IllegalArgumentException, NullPointerException; public void clear() throws RuntimeException; public Set keySet(); public Collection values(); public Set entrySet(); public boolean equals(Object o); public int hashCode(); } bouncycastle-1.49.orig/j2me/java/math/0000755000175000017500000000000012152033550017134 5ustar ebourgebourgbouncycastle-1.49.orig/j2me/java/math/test/0000755000175000017500000000000012152033550020113 5ustar ebourgebourgbouncycastle-1.49.orig/j2me/java/math/test/BigIntegerTest.java0000644000175000017500000003155112062253471023650 0ustar ebourgebourgpackage java.math.test; import java.math.BigInteger; import java.security.SecureRandom; import org.bouncycastle.util.test.*; public class BigIntegerTest extends SimpleTest { private static BigInteger VALUE1 = new BigInteger("1234"); private static BigInteger VALUE2 = new BigInteger("1234567890"); private static BigInteger VALUE3 = new BigInteger("12345678901234567890123"); private static BigInteger zero = BigInteger.ZERO; private static BigInteger one = BigInteger.ONE; private static BigInteger two = BigInteger.valueOf(2); public String getName() { return "BigInteger"; } private void clearBitTest() { BigInteger value = VALUE1.clearBit(3); BigInteger result = new BigInteger("1234"); if (!value.equals(result)) { fail("clearBit - expected: " + result + " got: " + value); } value = VALUE2.clearBit(3); result = new BigInteger("1234567890"); if (!value.equals(result)) { fail("clearBit - expected: " + result + " got: " + value); } value = VALUE3.clearBit(3); result = new BigInteger("12345678901234567890115"); if (!value.equals(result)) { fail("clearBit - expected: " + result + " got: " + value); } value = VALUE2.clearBit(55); result = new BigInteger("1234567890"); if (!value.equals(result)) { fail("clearBit - expected: " + result + " got: " + value); } value = VALUE3.clearBit(55); result = new BigInteger("12345642872437548926155"); if (!value.equals(result)) { fail("clearBit - expected: " + result + " got: " + value); } } private void flipBitTest() { BigInteger value = VALUE1.flipBit(3); BigInteger result = new BigInteger("1242"); if (!value.equals(result)) { fail("flipBit - expected: " + result + " got: " + value); } value = VALUE2.flipBit(3); result = new BigInteger("1234567898"); if (!value.equals(result)) { fail("flipBit - expected: " + result + " got: " + value); } value = VALUE3.flipBit(3); result = new BigInteger("12345678901234567890115"); if (!value.equals(result)) { fail("flipBit - expected: " + result + " got: " + value); } value = VALUE2.flipBit(55); result = new BigInteger("36028798253531858"); if (!value.equals(result)) { fail("flipBit - expected: " + result + " got: " + value); } value = VALUE3.flipBit(55); result = new BigInteger("12345642872437548926155"); if (!value.equals(result)) { fail("flipBit - expected: " + result + " got: " + value); } } private void setBitTest() { BigInteger value = VALUE1.setBit(3); BigInteger result = new BigInteger("1242"); if (!value.equals(result)) { fail("setBit - expected: " + result + " got: " + value); } value = VALUE2.setBit(3); result = new BigInteger("1234567898"); if (!value.equals(result)) { fail("setBit - expected: " + result + " got: " + value); } value = VALUE3.setBit(3); result = new BigInteger("12345678901234567890123"); if (!value.equals(result)) { fail("setBit - expected: " + result + " got: " + value); } value = VALUE2.setBit(55); result = new BigInteger("36028798253531858"); if (!value.equals(result)) { fail("setBit - expected: " + result + " got: " + value); } value = VALUE3.setBit(55); result = new BigInteger("12345678901234567890123"); if (!value.equals(result)) { fail("setBit - expected: " + result + " got: " + value); } } private void testDivideAndRemainder() { SecureRandom random = new SecureRandom(); BigInteger n = new BigInteger(48, random); BigInteger[] qr = n.divideAndRemainder(n); if (!qr[0].equals(one) || !qr[1].equals(zero)) { fail("testDivideAndRemainder - expected: 1/0 got: " + qr[0] + "/" + qr[1]); } qr = n.divideAndRemainder(one); if (!qr[0].equals(n) || !qr[1].equals(zero)) { fail("testDivideAndRemainder - expected: " + n + "/0 got: " + qr[0] + "/" + qr[1]); } for (int rep = 0; rep < 10; ++rep) { BigInteger a = new BigInteger(100 - rep, 0, random); BigInteger b = new BigInteger(100 + rep, 0, random); BigInteger c = new BigInteger(10 + rep, 0, random); BigInteger d = a.multiply(b).add(c); BigInteger[] es = d.divideAndRemainder(a); if (!es[0].equals(b) || !es[1].equals(c)) { fail("testDivideAndRemainder - expected: " + b + "/" + c + " got: " + qr[0] + "/" + qr[1]); } } } private void testModInverse() { SecureRandom random = new SecureRandom(); for (int i = 0; i < 10; ++i) { BigInteger p = BigInteger.probablePrime(64, random); BigInteger q = new BigInteger(63, random).add(one); BigInteger inv = q.modInverse(p); BigInteger inv2 = inv.modInverse(p); if (!q.equals(inv2)) { fail("testModInverse failed symmetry test"); } BigInteger check = q.multiply(inv).mod(p); if (!one.equals(check)) { fail("testModInverse - expected: 1 got: " + check); } } // ModInverse for powers of 2 for (int i = 1; i <= 128; ++i) { BigInteger m = one.shiftLeft(i); BigInteger d = new BigInteger(i, random).setBit(0); BigInteger x = d.modInverse(m); BigInteger check = x.multiply(d).mod(m); if (!one.equals(check)) { fail("testModInverse - expected: 1 got: " + check); } } } private void testNegate() { if (!zero.equals(zero.negate())) { fail("zero - negate falied"); } if (!one.equals(one.negate().negate())) { fail("one - negate falied"); } if (!two.equals(two.negate().negate())) { fail("two - negate falied"); } } private void testNot() { for (int i = -10; i <= 10; ++i) { if(!BigInteger.valueOf(~i).equals( BigInteger.valueOf(i).not())) { fail("Problem: ~" + i + " should be " + ~i); } } } private void testOr() { for (int i = -10; i <= 10; ++i) { for (int j = -10; j <= 10; ++j) { if (!BigInteger.valueOf(i | j).equals( BigInteger.valueOf(i).or(BigInteger.valueOf(j)))) { fail("Problem: " + i + " OR " + j + " should be " + (i | j)); } } } } public void testPow() { if (!one.equals(zero.pow(0))) { fail("one pow equals failed"); } if (!zero.equals(zero.pow(123))) { fail("zero pow equals failed"); } if (!one.equals(one.pow(0))) { fail("one one equals failed"); } if (!one.equals(one.pow(123))) { fail("1 123 equals failed"); } if (!two.pow(147).equals(one.shiftLeft(147))) { fail("2 pow failed"); } if (!one.shiftLeft(7).pow(11).equals(one.shiftLeft(77))) { fail("pow 2 pow failed"); } BigInteger n = new BigInteger("1234567890987654321"); BigInteger result = one; for (int i = 0; i < 10; ++i) { try { BigInteger.valueOf(i).pow(-1); fail("expected ArithmeticException"); } catch (ArithmeticException e) {} if (!result.equals(n.pow(i))) { fail("mod pow equals failed"); } result = result.multiply(n); } } public void testToString() { SecureRandom random = new SecureRandom(); int trials = 256; BigInteger[] tests = new BigInteger[trials]; for (int i = 0; i < trials; ++i) { int len = random.nextInt(i + 1); tests[i] = new BigInteger(len, random); } for (int radix = Character.MIN_RADIX; radix <= Character.MAX_RADIX; ++radix) { for (int i = 0; i < trials; ++i) { BigInteger n1 = tests[i]; String s = n1.toString(radix); BigInteger n2 = new BigInteger(s, radix); if (!n1.equals(n2)) { fail("testToStringRadix - radix:" + radix + ", n1:" + n1.toString(16) + ", n2:" + n2.toString(16)); } } } } private void xorTest() { BigInteger value = VALUE1.xor(VALUE2); BigInteger result = new BigInteger("1234568704"); if (!value.equals(result)) { fail("xor - expected: " + result + " got: " + value); } value = VALUE1.xor(VALUE3); result = new BigInteger("12345678901234567888921"); if (!value.equals(result)) { fail("xor - expected: " + result + " got: " + value); } value = VALUE3.xor(VALUE1); result = new BigInteger("12345678901234567888921"); if (!value.equals(result)) { fail("xor - expected: " + result + " got: " + value); } value = VALUE2.xor(new BigInteger("-1")); result = new BigInteger("-1234567891"); if (!value.equals(result)) { fail("xor - expected: " + result + " got: " + value); } value = VALUE3.xor(VALUE3); result = new BigInteger("0"); if (!value.equals(result)) { fail("xor - expected: " + result + " got: " + value); } } public void performTest() { clearBitTest(); flipBitTest(); setBitTest(); testDivideAndRemainder(); testModInverse(); testNegate(); testNot(); testOr(); testPow(); testToString(); xorTest(); BigInteger n1, n2, r1; // test division where the difference in bit length of the dividend and divisor is 32 bits n1 = new BigInteger("54975581388"); n2 = new BigInteger("10"); r1 = n1.divide(n2); if (!r1.toString(10).equals("5497558138")) { fail("BigInteger: failed Divide Test"); } // two's complement test byte[] zeroBytes = BigInteger.ZERO.toByteArray(); byte[] oneBytes = BigInteger.ONE.toByteArray(); byte[] minusOneBytes = BigInteger.ONE.negate().toByteArray(); BigInteger zero = new BigInteger(zeroBytes); if (!zero.equals(BigInteger.ZERO)) { fail("Failed constructing zero"); } BigInteger one = new BigInteger(oneBytes); if (!one.equals(BigInteger.ONE)) { fail("Failed constructing one"); } BigInteger minusOne = new BigInteger(minusOneBytes); if (!minusOne.equals(BigInteger.ONE.negate())) { fail("Failed constructing minus one"); } SecureRandom random = new SecureRandom(); byte[] randomBytes = new byte[100]; for (int i=0; i < 100; i++) { random.nextBytes(randomBytes); BigInteger bcInt = new BigInteger(randomBytes); BigInteger bcInt2 = new BigInteger(bcInt.toByteArray()); if (!bcInt.equals(bcInt2)) { fail("Failed constructing random value " + i); } // java.math.BigInteger jdkInt = new java.math.BigInteger(randomBytes); // byte[] bcBytes = bcInt.toByteArray(); // byte[] jdkBytes = jdkInt.toByteArray(); // if (!arrayEquals(bcBytes, jdkBytes)) // { // fail(""Failed constructing random value " + i); // } } } public static void main( String[] args) { runTest(new BigIntegerTest()); } } bouncycastle-1.49.orig/j2me/java/math/test/RegressionTest.java0000644000175000017500000000067710262753174023763 0ustar ebourgebourgpackage java.math.test; import org.bouncycastle.util.test.Test; import org.bouncycastle.util.test.TestResult; public class RegressionTest { public static Test[] tests = { new BigIntegerTest() }; public static void main( String[] args) { for (int i = 0; i != tests.length; i++) { TestResult result = tests[i].perform(); System.out.println(result); } } } bouncycastle-1.49.orig/j2me/java/math/BigInteger.java0000644000175000017500000024576012076150720022040 0ustar ebourgebourgpackage java.math; import java.util.Random; import java.util.Stack; import org.bouncycastle.util.Arrays; public class BigInteger { // The first few odd primes /* 3 5 7 11 13 17 19 23 29 31 37 41 43 47 53 59 61 67 71 73 79 83 89 97 101 103 107 109 113 127 131 137 139 149 151 157 163 167 173 179 181 191 193 197 199 211 223 227 229 233 239 241 251 257 263 269 271 277 281 283 293 307 311 313 317 331 337 347 349 353 359 367 373 379 383 389 397 401 409 419 421 431 433 439 443 449 457 461 463 467 479 487 491 499 503 509 521 523 541 547 557 563 569 571 577 587 593 599 601 607 613 617 619 631 641 643 647 653 659 661 673 677 683 691 701 709 719 727 733 739 743 751 757 761 769 773 787 797 809 811 821 823 827 829 839 853 857 859 863 877 881 883 887 907 911 919 929 937 941 947 953 967 971 977 983 991 997 1009 1013 1019 1021 1031 1033 1039 1049 1051 1061 1063 1069 1087 1091 1093 1097 1103 1109 1117 1123 1129 1151 1153 1163 1171 1181 1187 1193 1201 1213 1217 1223 1229 1231 1237 1249 1259 1277 1279 1283 1289 */ // Each list has a product < 2^31 private static final int[][] primeLists = new int[][] { new int[]{ 3, 5, 7, 11, 13, 17, 19, 23 }, new int[]{ 29, 31, 37, 41, 43 }, new int[]{ 47, 53, 59, 61, 67 }, new int[]{ 71, 73, 79, 83 }, new int[]{ 89, 97, 101, 103 }, new int[]{ 107, 109, 113, 127 }, new int[]{ 131, 137, 139, 149 }, new int[]{ 151, 157, 163, 167 }, new int[]{ 173, 179, 181, 191 }, new int[]{ 193, 197, 199, 211 }, new int[]{ 223, 227, 229 }, new int[]{ 233, 239, 241 }, new int[]{ 251, 257, 263 }, new int[]{ 269, 271, 277 }, new int[]{ 281, 283, 293 }, new int[]{ 307, 311, 313 }, new int[]{ 317, 331, 337 }, new int[]{ 347, 349, 353 }, new int[]{ 359, 367, 373 }, new int[]{ 379, 383, 389 }, new int[]{ 397, 401, 409 }, new int[]{ 419, 421, 431 }, new int[]{ 433, 439, 443 }, new int[]{ 449, 457, 461 }, new int[]{ 463, 467, 479 }, new int[]{ 487, 491, 499 }, new int[]{ 503, 509, 521 }, new int[]{ 523, 541, 547 }, new int[]{ 557, 563, 569 }, new int[]{ 571, 577, 587 }, new int[]{ 593, 599, 601 }, new int[]{ 607, 613, 617 }, new int[]{ 619, 631, 641 }, new int[]{ 643, 647, 653 }, new int[]{ 659, 661, 673 }, new int[]{ 677, 683, 691 }, new int[]{ 701, 709, 719 }, new int[]{ 727, 733, 739 }, new int[]{ 743, 751, 757 }, new int[]{ 761, 769, 773 }, new int[]{ 787, 797, 809 }, new int[]{ 811, 821, 823 }, new int[]{ 827, 829, 839 }, new int[]{ 853, 857, 859 }, new int[]{ 863, 877, 881 }, new int[]{ 883, 887, 907 }, new int[]{ 911, 919, 929 }, new int[]{ 937, 941, 947 }, new int[]{ 953, 967, 971 }, new int[]{ 977, 983, 991 }, new int[]{ 997, 1009, 1013 }, new int[]{ 1019, 1021, 1031 }, new int[]{ 1033, 1039, 1049 }, new int[]{ 1051, 1061, 1063 }, new int[]{ 1069, 1087, 1091 }, new int[]{ 1093, 1097, 1103 }, new int[]{ 1109, 1117, 1123 }, new int[]{ 1129, 1151, 1153 }, new int[]{ 1163, 1171, 1181 }, new int[]{ 1187, 1193, 1201 }, new int[]{ 1213, 1217, 1223 }, new int[]{ 1229, 1231, 1237 }, new int[]{ 1249, 1259, 1277 }, new int[]{ 1279, 1283, 1289 }, }; private static int[] primeProducts; private static final long IMASK = 0xffffffffL; private static final int[] ZERO_MAGNITUDE = new int[0]; private static final BigInteger[] SMALL_CONSTANTS = new BigInteger[17]; public static final BigInteger ZERO; public static final BigInteger ONE; public static final BigInteger TWO; public static final BigInteger THREE; public static final BigInteger TEN; private final static byte[] bitCounts = { 0, 1, 1, 2, 1, 2, 2, 3, 1, 2, 2, 3, 2, 3, 3, 4, 1, 2, 2, 3, 2, 3, 3, 4, 2, 3, 3, 4, 3, 4, 4, 5, 1, 2, 2, 3, 2, 3, 3, 4, 2, 3, 3, 4, 3, 4, 4, 5, 2, 3, 3, 4, 3, 4, 4, 5, 3, 4, 4, 5, 4, 5, 5, 6, 1, 2, 2, 3, 2, 3, 3, 4, 2, 3, 3, 4, 3, 4, 4, 5, 2, 3, 3, 4, 3, 4, 4, 5, 3, 4, 4, 5, 4, 5, 5, 6, 2, 3, 3, 4, 3, 4, 4, 5, 3, 4, 4, 5, 4, 5, 5, 6, 3, 4, 4, 5, 4, 5, 5, 6, 4, 5, 5, 6, 5, 6, 6, 7, 1, 2, 2, 3, 2, 3, 3, 4, 2, 3, 3, 4, 3, 4, 4, 5, 2, 3, 3, 4, 3, 4, 4, 5, 3, 4, 4, 5, 4, 5, 5, 6, 2, 3, 3, 4, 3, 4, 4, 5, 3, 4, 4, 5, 4, 5, 5, 6, 3, 4, 4, 5, 4, 5, 5, 6, 4, 5, 5, 6, 5, 6, 6, 7, 2, 3, 3, 4, 3, 4, 4, 5, 3, 4, 4, 5, 4, 5, 5, 6, 3, 4, 4, 5, 4, 5, 5, 6, 4, 5, 5, 6, 5, 6, 6, 7, 3, 4, 4, 5, 4, 5, 5, 6, 4, 5, 5, 6, 5, 6, 6, 7, 4, 5, 5, 6, 5, 6, 6, 7, 5, 6, 6, 7, 6, 7, 7, 8 }; private final static byte[] bitLengths = { 0, 1, 2, 2, 3, 3, 3, 3, 4, 4, 4, 4, 4, 4, 4, 4, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8 }; /* * These are the threshold bit-lengths (of an exponent) where we increase the window size. * These were calculated according to the expected savings in multiplications. * Some squares will also be saved on average, but we offset these against the extra storage costs. */ private static final int[] EXP_WINDOW_THRESHOLDS = { 7, 25, 81, 241, 673, 1793, 4609, Integer.MAX_VALUE }; static { /* * Avoid using large windows in VMs with little memory. * Window size limited to 2 below 256kB, then increased by one for every doubling, * i.e. at 512kB, 1MB, 2MB, etc... */ long totalMemory = Runtime.getRuntime().totalMemory(); if (totalMemory <= Integer.MAX_VALUE) { int mem = (int)totalMemory; int maxExpThreshold = 1 + bitLen(mem >> 18); if (maxExpThreshold < EXP_WINDOW_THRESHOLDS.length) { EXP_WINDOW_THRESHOLDS[maxExpThreshold] = Integer.MAX_VALUE; } } ZERO = new BigInteger(0, ZERO_MAGNITUDE); ZERO.nBits = 0; ZERO.nBitLength = 0; SMALL_CONSTANTS[0] = ZERO; int numBits = 0; for (int i = 1; i < SMALL_CONSTANTS.length; ++i) { SMALL_CONSTANTS[i] = createValueOf(i); // Check for a power of two if ((i & -i) == i) { SMALL_CONSTANTS[i].nBits = 1; ++numBits; } SMALL_CONSTANTS[i].nBitLength = numBits; } ONE = SMALL_CONSTANTS[1]; TWO = SMALL_CONSTANTS[2]; THREE = SMALL_CONSTANTS[3]; TEN = SMALL_CONSTANTS[10]; primeProducts = new int[primeLists.length]; for (int i = 0; i < primeLists.length; ++i) { int[] primeList = primeLists[i]; int product = 1; for (int j = 0; j < primeList.length; ++j) { product *= primeList[j]; } primeProducts[i] = product; } } private int sign; // -1 means -ve; +1 means +ve; 0 means 0; private int[] magnitude; // array of ints with [0] being the most significant private int nBits = -1; // cache bitCount() value private int nBitLength = -1; // cache bitLength() value private int mQuote = 0; // -m^(-1) mod b, b = 2^32 (see Montgomery mult.), 0 when uninitialised private BigInteger() { } private BigInteger(int signum, int[] mag) { if (mag.length > 0) { sign = signum; int i = 0; while (i < mag.length && mag[i] == 0) { i++; } if (i == 0) { magnitude = mag; } else { // strip leading 0 bytes int[] newMag = new int[mag.length - i]; System.arraycopy(mag, i, newMag, 0, newMag.length); magnitude = newMag; if (newMag.length == 0) sign = 0; } } else { magnitude = mag; sign = 0; } } public BigInteger(String sval) throws NumberFormatException { this(sval, 10); } public BigInteger(String sval, int rdx) throws NumberFormatException { if (sval.length() == 0) { throw new NumberFormatException("Zero length BigInteger"); } if (rdx < Character.MIN_RADIX || rdx > Character.MAX_RADIX) { throw new NumberFormatException("Radix out of range"); } int index = 0; sign = 1; if (sval.charAt(0) == '-') { if (sval.length() == 1) { throw new NumberFormatException("Zero length BigInteger"); } sign = -1; index = 1; } // strip leading zeros from the string value while (index < sval.length() && Character.digit(sval.charAt(index), rdx) == 0) { index++; } if (index >= sval.length()) { // zero value - we're done sign = 0; magnitude = new int[0]; return; } ////// // could we work out the max number of ints required to store // sval.length digits in the given base, then allocate that // storage in one hit?, then generate the magnitude in one hit too? ////// BigInteger b = ZERO; BigInteger r = valueOf(rdx); while (index < sval.length()) { // (optimise this by taking chunks of digits instead?) b = b.multiply(r).add(valueOf(Character.digit(sval.charAt(index), rdx))); index++; } magnitude = b.magnitude; return; } public BigInteger(byte[] bval) throws NumberFormatException { if (bval.length == 0) { throw new NumberFormatException("Zero length BigInteger"); } sign = 1; if (bval[0] < 0) { sign = -1; } magnitude = makeMagnitude(bval, sign); if (magnitude.length == 0) { sign = 0; } } /** * If sign >= 0, packs bytes into an array of ints, most significant first * If sign < 0, packs 2's complement of bytes into * an array of ints, most significant first, * adding an extra most significant byte in case bval = {0x80, 0x00, ..., 0x00} * * @param bval * @param sign * @return */ private int[] makeMagnitude(byte[] bval, int sign) { if (sign >= 0) { int i; int[] mag; int firstSignificant; // strip leading zeros for (firstSignificant = 0; firstSignificant < bval.length && bval[firstSignificant] == 0; firstSignificant++); if (firstSignificant >= bval.length) { return new int[0]; } int nInts = (bval.length - firstSignificant + 3) / 4; int bCount = (bval.length - firstSignificant) % 4; if (bCount == 0) bCount = 4; // n = k * (n / k) + n % k // bval.length - firstSignificant + 3 = 4 * nInts + bCount - 1 // bval.length - firstSignificant + 4 - bCount = 4 * nInts mag = new int[nInts]; int v = 0; int magnitudeIndex = 0; for (i = firstSignificant; i < bval.length; i++) { // bval.length + 4 - bCount - i + 4 * magnitudeIndex = 4 * nInts // 1 <= bCount <= 4 v <<= 8; v |= bval[i] & 0xff; bCount--; if (bCount <= 0) { mag[magnitudeIndex] = v; magnitudeIndex++; bCount = 4; v = 0; } } // 4 - bCount + 4 * magnitudeIndex = 4 * nInts // bCount = 4 * (1 + magnitudeIndex - nInts) // 1 <= bCount <= 4 // So bCount = 4 and magnitudeIndex = nInts = mag.length // if (magnitudeIndex < mag.length) // { // mag[magnitudeIndex] = v; // } return mag; } else { int i; int[] mag; int firstSignificant; // strip leading -1's for (firstSignificant = 0; firstSignificant < bval.length - 1 && bval[firstSignificant] == 0xff; firstSignificant++); int nBytes = bval.length; boolean leadingByte = false; // check for -2^(n-1) if (bval[firstSignificant] == 0x80) { for (i = firstSignificant + 1; i < bval.length; i++) { if (bval[i] != 0) { break; } } if (i == bval.length) { nBytes++; leadingByte = true; } } int nInts = (nBytes - firstSignificant + 3) / 4; int bCount = (nBytes - firstSignificant) % 4; if (bCount == 0) bCount = 4; // n = k * (n / k) + n % k // nBytes - firstSignificant + 3 = 4 * nInts + bCount - 1 // nBytes - firstSignificant + 4 - bCount = 4 * nInts // 1 <= bCount <= 4 mag = new int[nInts]; int v = 0; int magnitudeIndex = 0; // nBytes + 4 - bCount - i + 4 * magnitudeIndex = 4 * nInts // 1 <= bCount <= 4 if (leadingByte) { // bval.length + 1 + 4 - bCount - i + 4 * magnitudeIndex = 4 * nInts bCount--; // bval.length + 1 + 4 - (bCount + 1) - i + 4 * magnitudeIndex = 4 * nInts // bval.length + 4 - bCount - i + 4 * magnitudeIndex = 4 * nInts if (bCount <= 0) { magnitudeIndex++; bCount = 4; } // bval.length + 4 - bCount - i + 4 * magnitudeIndex = 4 * nInts // 1 <= bCount <= 4 } for (i = firstSignificant; i < bval.length; i++) { // bval.length + 4 - bCount - i + 4 * magnitudeIndex = 4 * nInts // 1 <= bCount <= 4 v <<= 8; v |= ~bval[i] & 0xff; bCount--; if (bCount <= 0) { mag[magnitudeIndex] = v; magnitudeIndex++; bCount = 4; v = 0; } } // 4 - bCount + 4 * magnitudeIndex = 4 * nInts // 1 <= bCount <= 4 // bCount = 4 * (1 + magnitudeIndex - nInts) // 1 <= bCount <= 4 // So bCount = 4 and magnitudeIndex = nInts = mag.length // if (magnitudeIndex < mag.length) // { // mag[magnitudeIndex] = v; // } mag = inc(mag); // TODO Fix above so that this is not necessary? if (mag[0] == 0) { int[] tmp = new int[mag.length - 1]; System.arraycopy(mag, 1, tmp, 0, tmp.length); mag = tmp; } return mag; } } public BigInteger(int sign, byte[] mag) throws NumberFormatException { if (sign < -1 || sign > 1) { throw new NumberFormatException("Invalid sign value"); } if (sign == 0) { this.sign = 0; this.magnitude = new int[0]; return; } // copy bytes this.magnitude = makeMagnitude(mag, 1); this.sign = sign; } public BigInteger(int numBits, Random rnd) throws IllegalArgumentException { if (numBits < 0) { throw new IllegalArgumentException("numBits must be non-negative"); } this.nBits = -1; this.nBitLength = -1; if (numBits == 0) { // this.sign = 0; this.magnitude = ZERO_MAGNITUDE; return; } int nBytes = (numBits + 7) / 8; byte[] b = new byte[nBytes]; nextRndBytes(rnd, b); // strip off any excess bits in the MSB int xBits = BITS_PER_BYTE * nBytes - numBits; b[0] &= (byte)(255 >>> xBits); this.magnitude = makeMagnitude(b, 1); this.sign = this.magnitude.length < 1 ? 0 : 1; } private static final int BITS_PER_BYTE = 8; private static final int BYTES_PER_INT = 4; /** * strictly speaking this is a little dodgey from a compliance * point of view as it forces people to be using SecureRandom as * well, that being said - this implementation is for a crypto * library and you do have the source! */ private void nextRndBytes(Random rnd, byte[] bytes) { int numRequested = bytes.length; int numGot = 0, r = 0; if (rnd instanceof java.security.SecureRandom) { ((java.security.SecureRandom)rnd).nextBytes(bytes); } else { for (; ; ) { for (int i = 0; i < BYTES_PER_INT; i++) { if (numGot == numRequested) { return; } r = (i == 0 ? rnd.nextInt() : r >> BITS_PER_BYTE); bytes[numGot++] = (byte)r; } } } } public BigInteger(int bitLength, int certainty, Random rnd) throws ArithmeticException { if (bitLength < 2) { throw new ArithmeticException("bitLength < 2"); } this.sign = 1; this.nBitLength = bitLength; if (bitLength == 2) { this.magnitude = rnd.nextInt() < 0 ? TWO.magnitude : THREE.magnitude; return; } int nBytes = (bitLength + 7) / BITS_PER_BYTE; int xBits = BITS_PER_BYTE * nBytes - bitLength; byte mask = (byte)(255 >>> xBits); byte[] b = new byte[nBytes]; for (;;) { nextRndBytes(rnd, b); // strip off any excess bits in the MSB b[0] &= mask; // ensure the leading bit is 1 (to meet the strength requirement) b[0] |= (byte)(1 << (7 - xBits)); // ensure the trailing bit is 1 (i.e. must be odd) b[nBytes - 1] |= (byte)1; this.magnitude = makeMagnitude(b, 1); this.nBits = -1; this.mQuote = 0; if (certainty < 1) break; if (this.isProbablePrime(certainty)) break; if (bitLength > 32) { for (int rep = 0; rep < 10000; ++rep) { int n = 33 + (rnd.nextInt() >>> 1) % (bitLength - 2); this.magnitude[this.magnitude.length - (n >>> 5)] ^= (1 << (n & 31)); this.magnitude[this.magnitude.length - 1] ^= (rnd.nextInt() << 1); this.mQuote = 0; if (this.isProbablePrime(certainty)) return; } } } } public BigInteger abs() { return (sign >= 0) ? this : this.negate(); } /** * return a = a + b - b preserved. */ private int[] add(int[] a, int[] b) { int tI = a.length - 1; int vI = b.length - 1; long m = 0; while (vI >= 0) { m += (((long)a[tI]) & IMASK) + (((long)b[vI--]) & IMASK); a[tI--] = (int)m; m >>>= 32; } while (tI >= 0 && m != 0) { m += (((long)a[tI]) & IMASK); a[tI--] = (int)m; m >>>= 32; } return a; } /** * return a = a + 1. */ private int[] inc(int[] a) { int tI = a.length - 1; long m = 0; m = (((long)a[tI]) & IMASK) + 1L; a[tI--] = (int)m; m >>>= 32; while (tI >= 0 && m != 0) { m += (((long)a[tI]) & IMASK); a[tI--] = (int)m; m >>>= 32; } return a; } public BigInteger add(BigInteger val) throws ArithmeticException { if (val.sign == 0 || val.magnitude.length == 0) return this; if (this.sign == 0 || this.magnitude.length == 0) return val; if (val.sign < 0) { if (this.sign > 0) return this.subtract(val.negate()); } else { if (this.sign < 0) return val.subtract(this.negate()); } return addToMagnitude(val.magnitude); } private BigInteger addToMagnitude( int[] magToAdd) { int[] big, small; if (this.magnitude.length < magToAdd.length) { big = magToAdd; small = this.magnitude; } else { big = this.magnitude; small = magToAdd; } // Conservatively avoid over-allocation when no overflow possible int limit = Integer.MAX_VALUE; if (big.length == small.length) limit -= small[0]; boolean possibleOverflow = (big[0] ^ (1 << 31)) >= limit; int extra = possibleOverflow ? 1 : 0; int[] bigCopy = new int[big.length + extra]; System.arraycopy(big, 0, bigCopy, extra, big.length); bigCopy = add(bigCopy, small); return new BigInteger(this.sign, bigCopy); } public BigInteger and( BigInteger value) { if (this.sign == 0 || value.sign == 0) { return ZERO; } int[] aMag = this.sign > 0 ? this.magnitude : add(ONE).magnitude; int[] bMag = value.sign > 0 ? value.magnitude : value.add(ONE).magnitude; boolean resultNeg = sign < 0 && value.sign < 0; int resultLength = Math.max(aMag.length, bMag.length); int[] resultMag = new int[resultLength]; int aStart = resultMag.length - aMag.length; int bStart = resultMag.length - bMag.length; for (int i = 0; i < resultMag.length; ++i) { int aWord = i >= aStart ? aMag[i - aStart] : 0; int bWord = i >= bStart ? bMag[i - bStart] : 0; if (this.sign < 0) { aWord = ~aWord; } if (value.sign < 0) { bWord = ~bWord; } resultMag[i] = aWord & bWord; if (resultNeg) { resultMag[i] = ~resultMag[i]; } } BigInteger result = new BigInteger(1, resultMag); // TODO Optimise this case if (resultNeg) { result = result.not(); } return result; } public BigInteger andNot( BigInteger value) { return and(value.not()); } public int bitCount() { if (nBits == -1) { if (sign < 0) { // TODO Optimise this case nBits = not().bitCount(); } else { int sum = 0; for (int i = 0; i < magnitude.length; i++) { sum += bitCounts[magnitude[i] & 0xff]; sum += bitCounts[(magnitude[i] >> 8) & 0xff]; sum += bitCounts[(magnitude[i] >> 16) & 0xff]; sum += bitCounts[(magnitude[i] >> 24) & 0xff]; } nBits = sum; } } return nBits; } private static int calcBitLength(int sign, int indx, int[] mag) { if (mag.length == 0) { return 0; } while (indx != mag.length && mag[indx] == 0) { indx++; } if (indx == mag.length) { return 0; } // bit length for everything after the first int int bitLength = 32 * ((mag.length - indx) - 1); // and determine bitlength of first int bitLength += bitLen(mag[indx]); if (sign < 0) { // Check if magnitude is a power of two boolean pow2 = ((bitCounts[mag[indx] & 0xff]) + (bitCounts[(mag[indx] >> 8) & 0xff]) + (bitCounts[(mag[indx] >> 16) & 0xff]) + (bitCounts[(mag[indx] >> 24) & 0xff])) == 1; for (int i = indx + 1; i < mag.length && pow2; i++) { pow2 = (mag[i] == 0); } bitLength -= (pow2 ? 1 : 0); } return bitLength; } public int bitLength() { if (nBitLength == -1) { if (sign == 0) { nBitLength = 0; } else { nBitLength = calcBitLength(sign, 0, magnitude); } } return nBitLength; } // // bitLen(value) is the number of bits in value. // private static int bitLen(int w) { int t = w >>> 24; if (t != 0) { return 24 + bitLengths[t]; } t = w >>> 16; if (t != 0) { return 16 + bitLengths[t]; } t = w >>> 8; if (t != 0) { return 8 + bitLengths[t]; } return bitLengths[w]; } private boolean quickPow2Check() { return sign > 0 && nBits == 1; } public int compareTo(Object o) { return compareTo((BigInteger)o); } /** * unsigned comparison on two arrays - note the arrays may * start with leading zeros. */ private static int compareTo(int xIndx, int[] x, int yIndx, int[] y) { while (xIndx != x.length && x[xIndx] == 0) { xIndx++; } while (yIndx != y.length && y[yIndx] == 0) { yIndx++; } return compareNoLeadingZeroes(xIndx, x, yIndx, y); } private static int compareNoLeadingZeroes(int xIndx, int[] x, int yIndx, int[] y) { int diff = (x.length - y.length) - (xIndx - yIndx); if (diff != 0) { return diff < 0 ? -1 : 1; } // lengths of magnitudes the same, test the magnitude values while (xIndx < x.length) { int v1 = x[xIndx++]; int v2 = y[yIndx++]; if (v1 != v2) { return (v1 ^ Integer.MIN_VALUE) < (v2 ^ Integer.MIN_VALUE) ? -1 : 1; } } return 0; } public int compareTo(BigInteger val) { if (sign < val.sign) return -1; if (sign > val.sign) return 1; if (sign == 0) return 0; return sign * compareTo(0, magnitude, 0, val.magnitude); } /** * return z = x / y - done in place (z value preserved, x contains the * remainder) */ private int[] divide(int[] x, int[] y) { int xyCmp = compareTo(0, x, 0, y); int[] count; if (xyCmp > 0) { int[] c; int shift = calcBitLength(1, 0, x) - calcBitLength(1, 0, y); if (shift > 1) { c = shiftLeft(y, shift - 1); count = shiftLeft(ONE.magnitude, shift - 1); if (shift % 32 == 0) { // Special case where the shift is the size of an int. int countSpecial[] = new int[shift / 32 + 1]; System.arraycopy(count, 0, countSpecial, 1, countSpecial.length - 1); countSpecial[0] = 0; count = countSpecial; } } else { c = new int[x.length]; count = new int[1]; System.arraycopy(y, 0, c, c.length - y.length, y.length); count[0] = 1; } int[] iCount = new int[count.length]; subtract(0, x, 0, c); System.arraycopy(count, 0, iCount, 0, count.length); int xStart = 0; int cStart = 0; int iCountStart = 0; for (; ; ) { int cmp = compareTo(xStart, x, cStart, c); while (cmp >= 0) { subtract(xStart, x, cStart, c); add(count, iCount); cmp = compareTo(xStart, x, cStart, c); } xyCmp = compareTo(xStart, x, 0, y); if (xyCmp > 0) { if (x[xStart] == 0) { xStart++; } shift = calcBitLength(1, cStart, c) - calcBitLength(1, xStart, x); if (shift == 0) { shiftRightOneInPlace(cStart, c); shiftRightOneInPlace(iCountStart, iCount); } else { shiftRightInPlace(cStart, c, shift); shiftRightInPlace(iCountStart, iCount, shift); } if (c[cStart] == 0) { cStart++; } if (iCount[iCountStart] == 0) { iCountStart++; } } else if (xyCmp == 0) { add(count, ONE.magnitude); for (int i = xStart; i != x.length; i++) { x[i] = 0; } break; } else { break; } } } else if (xyCmp == 0) { count = new int[1]; count[0] = 1; Arrays.fill(x, 0); } else { count = new int[1]; count[0] = 0; } return count; } public BigInteger divide(BigInteger val) throws ArithmeticException { if (val.sign == 0) { throw new ArithmeticException("Divide by zero"); } if (sign == 0) { return BigInteger.ZERO; } if (val.compareTo(BigInteger.ONE) == 0) { return this; } int[] mag = new int[this.magnitude.length]; System.arraycopy(this.magnitude, 0, mag, 0, mag.length); return new BigInteger(this.sign * val.sign, divide(mag, val.magnitude)); } public BigInteger[] divideAndRemainder(BigInteger val) throws ArithmeticException { if (val.sign == 0) { throw new ArithmeticException("Divide by zero"); } BigInteger biggies[] = new BigInteger[2]; if (sign == 0) { biggies[0] = biggies[1] = BigInteger.ZERO; return biggies; } if (val.compareTo(BigInteger.ONE) == 0) { biggies[0] = this; biggies[1] = BigInteger.ZERO; return biggies; } int[] remainder = new int[this.magnitude.length]; System.arraycopy(this.magnitude, 0, remainder, 0, remainder.length); int[] quotient = divide(remainder, val.magnitude); biggies[0] = new BigInteger(this.sign * val.sign, quotient); biggies[1] = new BigInteger(this.sign, remainder); return biggies; } public boolean equals(Object val) { if (val == this) return true; if (!(val instanceof BigInteger)) return false; BigInteger biggie = (BigInteger)val; return sign == biggie.sign && isEqualMagnitude(biggie); } private boolean isEqualMagnitude(BigInteger x) { if (magnitude.length != x.magnitude.length) { return false; } for (int i = 0; i < magnitude.length; i++) { if (magnitude[i] != x.magnitude[i]) { return false; } } return true; } public BigInteger gcd(BigInteger val) { if (val.sign == 0) return this.abs(); else if (sign == 0) return val.abs(); BigInteger r; BigInteger u = this; BigInteger v = val; while (v.sign != 0) { r = u.mod(v); u = v; v = r; } return u; } public int hashCode() { int hc = magnitude.length; if (magnitude.length > 0) { hc ^= magnitude[0]; if (magnitude.length > 1) { hc ^= magnitude[magnitude.length - 1]; } } return sign < 0 ? ~hc : hc; } public int intValue() { if (sign == 0) { return 0; } int n = magnitude.length; int val = magnitude[n - 1]; return sign < 0 ? -val : val; } public byte byteValue() { return (byte)intValue(); } /** * return whether or not a BigInteger is probably prime with a * probability of 1 - (1/2)**certainty. *

    * From Knuth Vol 2, pg 395. */ public boolean isProbablePrime(int certainty) { if (certainty <= 0) return true; if (sign == 0) return false; BigInteger n = this.abs(); if (!n.testBit(0)) return n.equals(TWO); if (n.equals(ONE)) return false; // Try to reduce the penalty for really small numbers int numLists = Math.min(n.bitLength() - 1, primeLists.length); for (int i = 0; i < numLists; ++i) { int test = n.remainder(primeProducts[i]); int[] primeList = primeLists[i]; for (int j = 0; j < primeList.length; ++j) { int prime = primeList[j]; int qRem = test % prime; if (qRem == 0) { // We may find small numbers in the list return n.bitLength() < 16 && n.intValue() == prime; } } } // // let n = 1 + 2^kq // int s = n.getLowestSetBitMaskFirst(-1 << 1); BigInteger r = n.shiftRight(s); Random random = new Random(); // NOTE: Avoid conversion to/from Montgomery form and check for R/-R as result instead BigInteger montRadix = ONE.shiftLeft(32 * n.magnitude.length).remainder(n); BigInteger minusMontRadix = n.subtract(montRadix); do { BigInteger a; do { a = new BigInteger(n.bitLength(), random); } while (a.sign == 0 || a.compareTo(n) >= 0 || a.isEqualMagnitude(montRadix) || a.isEqualMagnitude(minusMontRadix)); BigInteger y = modPowMonty(a, r, n, false); if (!y.equals(montRadix)) { int j = 0; while (!y.equals(minusMontRadix)) { if (++j == s) { return false; } y = modPowMonty(y, TWO, n, false); if (y.equals(montRadix)) { return false; } } } certainty -= 2; // composites pass for only 1/4 possible 'a' } while (certainty > 0); return true; } public long longValue() { if (sign == 0) { return 0; } int n = magnitude.length; long val = magnitude[n - 1] & IMASK; if (n > 1) { val |= (magnitude[n - 2] & IMASK) << 32; } return sign < 0 ? -val : val; } public BigInteger max(BigInteger val) { return (compareTo(val) > 0) ? this : val; } public BigInteger min(BigInteger val) { return (compareTo(val) < 0) ? this : val; } public BigInteger mod(BigInteger m) throws ArithmeticException { if (m.sign <= 0) { throw new ArithmeticException("BigInteger: modulus is not positive"); } BigInteger biggie = this.remainder(m); return (biggie.sign >= 0 ? biggie : biggie.add(m)); } public BigInteger modInverse(BigInteger m) throws ArithmeticException { if (m.sign < 1) { throw new ArithmeticException("Modulus must be positive"); } if (m.quickPow2Check()) { return modInversePow2(m); } BigInteger d = this.remainder(m); BigInteger x = new BigInteger(); BigInteger gcd = BigInteger.extEuclid(d, m, x, null); if (!gcd.equals(BigInteger.ONE)) { throw new ArithmeticException("Numbers not relatively prime."); } if (x.compareTo(BigInteger.ZERO) < 0) { x = x.add(m); } return x; } private BigInteger modInversePow2(BigInteger m) { // assert m.signum() > 0; // assert m.bitCount() == 1; if (!testBit(0)) { throw new ArithmeticException("Numbers not relatively prime."); } int pow = m.bitLength() - 1; if (pow <= 64) { long inv = modInverse64(longValue()); if (pow < 64) { inv &= (m.longValue() - 1); } return BigInteger.valueOf(inv); } BigInteger d = this.remainder(m); BigInteger x = d; int bitsCorrect = 3; while (bitsCorrect < pow) { BigInteger t = x.multiply(d).remainder(m); x = x.multiply(TWO.subtract(t)).remainder(m); bitsCorrect <<= 1; } if (x.sign < 0) { x = x.add(m); } return x; } private static int modInverse32(int d) { // Newton-Raphson division (roughly) int x = d; // d.x == 1 mod 2**3 x *= 2 - d * x; // d.x == 1 mod 2**6 x *= 2 - d * x; // d.x == 1 mod 2**12 x *= 2 - d * x; // d.x == 1 mod 2**24 x *= 2 - d * x; // d.x == 1 mod 2**48 // assert d * x == 1; return x; } private static long modInverse64(long d) { // Newton-Raphson division (roughly) long x = d; // d.x == 1 mod 2**3 x *= 2 - d * x; // d.x == 1 mod 2**6 x *= 2 - d * x; // d.x == 1 mod 2**12 x *= 2 - d * x; // d.x == 1 mod 2**24 x *= 2 - d * x; // d.x == 1 mod 2**48 x *= 2 - d * x; // d.x == 1 mod 2**96 // assert d * x == 1L; return x; } /** * Calculate the numbers u1, u2, and u3 such that: * * u1 * a + u2 * b = u3 * * where u3 is the greatest common divider of a and b. * a and b using the extended Euclid algorithm (refer p. 323 * of The Art of Computer Programming vol 2, 2nd ed). * This also seems to have the side effect of calculating * some form of multiplicative inverse. * * @param a First number to calculate gcd for * @param b Second number to calculate gcd for * @param u1Out the return object for the u1 value * @param u2Out the return object for the u2 value * @return The greatest common divisor of a and b */ private static BigInteger extEuclid(BigInteger a, BigInteger b, BigInteger u1Out, BigInteger u2Out) { BigInteger u1 = BigInteger.ONE; BigInteger u3 = a; BigInteger v1 = BigInteger.ZERO; BigInteger v3 = b; while (v3.sign > 0) { BigInteger[] q = u3.divideAndRemainder(v3); BigInteger tn = u1.subtract(v1.multiply(q[0])); u1 = v1; v1 = tn; u3 = v3; v3 = q[1]; } if (u1Out != null) { u1Out.sign = u1.sign; u1Out.magnitude = u1.magnitude; } if (u2Out != null) { BigInteger res = u3.subtract(u1.multiply(a)).divide(b); u2Out.sign = res.sign; u2Out.magnitude = res.magnitude; } return u3; } /** * zero out the array x */ private static void zero(int[] x) { for (int i = 0; i != x.length; i++) { x[i] = 0; } } public BigInteger modPow(BigInteger e, BigInteger m) { if (m.sign < 1) { throw new ArithmeticException("Modulus must be positive"); } if (m.equals(ONE)) { return ZERO; } if (e.sign == 0) { return ONE; } if (sign == 0) { return ZERO; } boolean negExp = e.sign < 0; if (negExp) { e = e.negate(); } BigInteger result = this.mod(m); if (!e.equals(ONE)) { if ((m.magnitude[m.magnitude.length - 1] & 1) == 0) { result = modPowBarrett(result, e, m); } else { result = modPowMonty(result, e, m, true); } } if (negExp) { result = result.modInverse(m); } return result; } private static BigInteger modPowBarrett(BigInteger b, BigInteger e, BigInteger m) { int k = m.magnitude.length; BigInteger mr = ONE.shiftLeft((k + 1) << 5); BigInteger yu = ONE.shiftLeft(k << 6).divide(m); // Sliding window from MSW to LSW int extraBits = 0, expLength = e.bitLength(); while (expLength > EXP_WINDOW_THRESHOLDS[extraBits]) { ++extraBits; } int numPowers = 1 << extraBits; BigInteger[] oddPowers = new BigInteger[numPowers]; oddPowers[0] = b; BigInteger b2 = reduceBarrett(b.square(), m, mr, yu); for (int i = 1; i < numPowers; ++i) { oddPowers[i] = reduceBarrett(oddPowers[i - 1].multiply(b2), m, mr, yu); } int[] windowList = getWindowList(e.magnitude, extraBits); // assert windowList.size() > 0; int window = windowList[0]; int mult = window & 0xFF, lastZeroes = window >>> 8; BigInteger y; if (mult == 1) { y = b2; --lastZeroes; } else { y = oddPowers[mult >>> 1]; } int windowPos = 1; while ((window = windowList[windowPos++]) != -1) { mult = window & 0xFF; int bits = lastZeroes + bitLengths[mult]; for (int j = 0; j < bits; ++j) { y = reduceBarrett(y.square(), m, mr, yu); } y = reduceBarrett(y.multiply(oddPowers[mult >>> 1]), m, mr, yu); lastZeroes = window >>> 8; } for (int i = 0; i < lastZeroes; ++i) { y = reduceBarrett(y.square(), m, mr, yu); } return y; } private static BigInteger reduceBarrett(BigInteger x, BigInteger m, BigInteger mr, BigInteger yu) { int xLen = x.bitLength(), mLen = m.bitLength(); if (xLen < mLen) { return x; } if (xLen - mLen > 1) { int k = m.magnitude.length; BigInteger q1 = x.divideWords(k - 1); BigInteger q2 = q1.multiply(yu); // TODO Only need partial multiplication here BigInteger q3 = q2.divideWords(k + 1); BigInteger r1 = x.remainderWords(k + 1); BigInteger r2 = q3.multiply(m); // TODO Only need partial multiplication here BigInteger r3 = r2.remainderWords(k + 1); x = r1.subtract(r3); if (x.sign < 0) { x = x.add(mr); } } while (x.compareTo(m) >= 0) { x = x.subtract(m); } return x; } private static BigInteger modPowMonty(BigInteger b, BigInteger e, BigInteger m, boolean convert) { int n = m.magnitude.length; int powR = 32 * n; boolean smallMontyModulus = m.bitLength() + 2 <= powR; int mDash = m.getMQuote(); // tmp = this * R mod m if (convert) { b = b.shiftLeft(powR).remainder(m); } int[] yAccum = new int[n + 1]; int[] zVal = b.magnitude; // assert zVal.length <= n; if (zVal.length < n) { int[] tmp = new int[n]; System.arraycopy(zVal, 0, tmp, n - zVal.length, zVal.length); zVal = tmp; } // Sliding window from MSW to LSW int extraBits = 0; // Filter the common case of small RSA exponents with few bits set if (e.magnitude.length > 1 || e.bitCount() > 2) { int expLength = e.bitLength(); while (expLength > EXP_WINDOW_THRESHOLDS[extraBits]) { ++extraBits; } } int numPowers = 1 << extraBits; int[][] oddPowers = new int[numPowers][]; oddPowers[0] = zVal; int[] zSquared = Arrays.clone(zVal); squareMonty(yAccum, zSquared, m.magnitude, mDash, smallMontyModulus); for (int i = 1; i < numPowers; ++i) { oddPowers[i] = Arrays.clone(oddPowers[i - 1]); multiplyMonty(yAccum, oddPowers[i], zSquared, m.magnitude, mDash, smallMontyModulus); } int[] windowList = getWindowList(e.magnitude, extraBits); // assert windowList.size() > 0; int window = windowList[0]; int mult = window & 0xFF, lastZeroes = window >>> 8; int[] yVal; if (mult == 1) { yVal = zSquared; --lastZeroes; } else { yVal = Arrays.clone(oddPowers[mult >>> 1]); } int windowPos = 1; while ((window = windowList[windowPos++]) != -1) { mult = window & 0xFF; int bits = lastZeroes + bitLengths[mult]; for (int j = 0; j < bits; ++j) { squareMonty(yAccum, yVal, m.magnitude, mDash, smallMontyModulus); } multiplyMonty(yAccum, yVal, oddPowers[mult >>> 1], m.magnitude, mDash, smallMontyModulus); lastZeroes = window >>> 8; } for (int i = 0; i < lastZeroes; ++i) { squareMonty(yAccum, yVal, m.magnitude, mDash, smallMontyModulus); } if (convert) { // Return y * R^(-1) mod m reduceMonty(yVal, m.magnitude, mDash); } else if (smallMontyModulus && compareTo(0, yVal, 0, m.magnitude) >= 0) { subtract(0, yVal, 0, m.magnitude); } return new BigInteger(1, yVal); } private static int[] getWindowList(int[] mag, int extraBits) { int v = mag[0]; // assert v != 0; int leadingBits = bitLen(v); int resultSize = (((mag.length - 1) << 5) + leadingBits) / (1 + extraBits) + 2; int[] result = new int[resultSize]; int resultPos = 0; int bitPos = 33 - leadingBits; v <<= bitPos; int mult = 1, multLimit = 1 << extraBits; int zeroes = 0; int i = 0; for (; ; ) { for (; bitPos < 32; ++bitPos) { if (mult < multLimit) { mult = (mult << 1) | (v >>> 31); } else if (v < 0) { result[resultPos++] = createWindowEntry(mult, zeroes); mult = 1; zeroes = 0; } else { ++zeroes; } v <<= 1; } if (++i == mag.length) { result[resultPos++] = createWindowEntry(mult, zeroes); break; } v = mag[i]; bitPos = 0; } result[resultPos] = -1; return result; } private static int createWindowEntry(int mult, int zeroes) { while ((mult & 1) == 0) { mult >>>= 1; ++zeroes; } return mult | (zeroes << 8); } /** * return w with w = x * x - w is assumed to have enough space. */ private static int[] square(int[] w, int[] x) { // Note: this method allows w to be only (2 * x.Length - 1) words if result will fit // if (w.length != 2 * x.length) // { // throw new IllegalArgumentException("no I don't think so..."); // } long c; int wBase = w.length - 1; for (int i = x.length - 1; i != 0; --i) { long v = x[i] & IMASK; c = v * v + (w[wBase] & IMASK); w[wBase] = (int)c; c >>>= 32; for (int j = i - 1; j >= 0; --j) { long prod = v * (x[j] & IMASK); c += (w[--wBase] & IMASK) + ((prod << 1) & IMASK); w[wBase] = (int)c; c = (c >>> 32) + (prod >>> 31); } c += w[--wBase] & IMASK; w[wBase] = (int)c; if (--wBase >= 0) { w[wBase] = (int)(c >> 32); } wBase += i; } c = x[0] & IMASK; c = c * c + (w[wBase] & IMASK); w[wBase] = (int)c; if (--wBase >= 0) { w[wBase] += (int)(c >> 32); } return w; } /** * return x with x = y * z - x is assumed to have enough space. */ private static int[] multiply(int[] x, int[] y, int[] z) { int i = z.length; if (i < 1) { return x; } int xBase = x.length - y.length; for (;;) { long a = z[--i] & IMASK; long val = 0; for (int j = y.length - 1; j >= 0; j--) { val += a * (y[j] & IMASK) + (x[xBase + j] & IMASK); x[xBase + j] = (int)val; val >>>= 32; } --xBase; if (i < 1) { if (xBase >= 0) { x[xBase] = (int)val; } break; } x[xBase] = (int)val; } return x; } /** * Calculate mQuote = -m^(-1) mod b with b = 2^32 (32 = word size) */ private int getMQuote() { if (mQuote != 0) { return mQuote; // already calculated } // assert this.sign > 0; int d = -magnitude[magnitude.length - 1]; // assert (d & 1) != 0; return mQuote = modInverse32(d); } private static void reduceMonty(int[] x, int[] m, int mDash) // mDash = -m^(-1) mod b { // NOTE: Not a general purpose reduction (which would allow x up to twice the bitlength of m) // assert x.length == m.length; int n = m.length; for (int i = n - 1; i >= 0; --i) { int x0 = x[n - 1]; long t = (x0 * mDash) & IMASK; long carry = t * (m[n - 1] & IMASK) + (x0 & IMASK); // assert (int)carry == 0; carry >>>= 32; for (int j = n - 2; j >= 0; --j) { carry += t * (m[j] & IMASK) + (x[j] & IMASK); x[j + 1] = (int)carry; carry >>>= 32; } x[0] = (int)carry; // assert carry >>> 32 == 0; } if (compareTo(0, x, 0, m) >= 0) { subtract(0, x, 0, m); } } /** * Montgomery multiplication: a = x * y * R^(-1) mod m *
    * Based algorithm 14.36 of Handbook of Applied Cryptography. *
    *

  • m, x, y should have length n
  • *
  • a should have length (n + 1)
  • *
  • b = 2^32, R = b^n
  • *
    * The result is put in x *
    * NOTE: the indices of x, y, m, a different in HAC and in Java */ private static void multiplyMonty(int[] a, int[] x, int[] y, int[] m, int mDash, boolean smallMontyModulus) // mDash = -m^(-1) mod b { int n = m.length; long y_0 = y[n - 1] & IMASK; // 1. a = 0 (Notation: a = (a_{n} a_{n-1} ... a_{0})_{b} ) for (int i = 0; i <= n; i++) { a[i] = 0; } // 2. for i from 0 to (n - 1) do the following: for (int i = n; i > 0; i--) { long a0 = a[n] & IMASK; long x_i = x[i - 1] & IMASK; long prod1 = x_i * y_0; long carry = (prod1 & IMASK) + a0; // 2.1 u = ((a[0] + (x[i] * y[0]) * mDash) mod b long u = ((int)carry * mDash) & IMASK; // 2.2 a = (a + x_i * y + u * m) / b long prod2 = u * (m[n - 1] & IMASK); carry += (prod2 & IMASK); // assert (int)carry == 0; carry = (carry >>> 32) + (prod1 >>> 32) + (prod2 >>> 32); for (int j = n - 2; j >= 0; j--) { prod1 = x_i * (y[j] & IMASK); prod2 = u * (m[j] & IMASK); carry += (prod1 & IMASK) + (prod2 & IMASK) + (a[j + 1] & IMASK); a[j + 2] = (int)carry; carry = (carry >>> 32) + (prod1 >>> 32) + (prod2 >>> 32); } carry += (a[0] & IMASK); a[1] = (int)carry; a[0] = (int)(carry >>> 32); } // 3. if x >= m the x = x - m if (!smallMontyModulus && compareTo(0, a, 0, m) >= 0) { subtract(0, a, 0, m); } // put the result in x System.arraycopy(a, 1, x, 0, n); } private static void squareMonty(int[] a, int[] x, int[] m, int mDash, boolean smallMontyModulus) // mDash = -m^(-1) mod b { int n = m.length; long x0 = x[n - 1] & IMASK; { long carry = x0 * x0; long u = ((int)carry * mDash) & IMASK; long prod1, prod2 = u * (m[n - 1] & IMASK); carry += (prod2 & IMASK); // assert (int)carry == 0; carry = (carry >>> 32) + (prod2 >>> 32); // assert carry <= (IMASK << 1); for (int j = n - 2; j >= 0; --j) { prod1 = x0 * (x[j] & IMASK); prod2 = u * (m[j] & IMASK); carry += ((prod1 << 1) & IMASK) + (prod2 & IMASK); a[j + 2] = (int)carry; carry = (carry >>> 32) + (prod1 >>> 31) + (prod2 >>> 32); } a[1] = (int)carry; a[0] = (int)(carry >>> 32); } for (int i = n - 2; i >= 0; --i) { int a0 = a[n]; long u = (a0 * mDash) & IMASK; long carry = u * (m[n - 1] & IMASK) + (a0 & IMASK); // assert (int)carry == 0; carry >>>= 32; for (int j = n - 2; j > i; --j) { carry += u * (m[j] & IMASK) + (a[j + 1] & IMASK); a[j + 2] = (int)carry; carry >>>= 32; } long xi = x[i] & IMASK; { long prod1 = xi * xi; long prod2 = u * (m[i] & IMASK); carry += (prod1 & IMASK) + (prod2 & IMASK) + (a[i + 1] & IMASK); a[i + 2] = (int)carry; carry = (carry >>> 32) + (prod1 >>> 32) + (prod2 >>> 32); } for (int j = i - 1; j >= 0; --j) { long prod1 = xi * (x[j] & IMASK); long prod2 = u * (m[j] & IMASK); carry += ((prod1 << 1) & IMASK) + (prod2 & IMASK) + (a[j + 1] & IMASK); a[j + 2] = (int)carry; carry = (carry >>> 32) + (prod1 >>> 31) + (prod2 >>> 32); } carry += (a[0] & IMASK); a[1] = (int)carry; a[0] = (int)(carry >>> 32); } if (!smallMontyModulus && compareTo(0, a, 0, m) >= 0) { subtract(0, a, 0, m); } System.arraycopy(a, 1, x, 0, n); } public BigInteger multiply(BigInteger val) { if (val == this) return square(); if ((sign & val.sign) == 0) return ZERO; if (val.quickPow2Check()) // val is power of two { BigInteger result = this.shiftLeft(val.abs().bitLength() - 1); return val.sign > 0 ? result : result.negate(); } if (this.quickPow2Check()) // this is power of two { BigInteger result = val.shiftLeft(this.abs().bitLength() - 1); return this.sign > 0 ? result : result.negate(); } int resLength = magnitude.length + val.magnitude.length; int[] res = new int[resLength]; multiply(res, this.magnitude, val.magnitude); int resSign = sign ^ val.sign ^ 1; return new BigInteger(resSign, res); } public BigInteger square() { if (sign == 0) { return ZERO; } if (this.quickPow2Check()) { return shiftLeft(abs().bitLength() - 1); } int resLength = magnitude.length << 1; if ((magnitude[0] >>> 16) == 0) { --resLength; } int[] res = new int[resLength]; square(res, magnitude); return new BigInteger(1, res); } public BigInteger negate() { if (sign == 0) { return this; } return new BigInteger(-sign, magnitude); } public BigInteger not() { return add(ONE).negate(); } public BigInteger pow(int exp) throws ArithmeticException { if (exp <= 0) { if (exp < 0) throw new ArithmeticException("Negative exponent"); return ONE; } if (sign == 0) { return this; } if (quickPow2Check()) { long powOf2 = (long)exp * (bitLength() - 1); if (powOf2 > Integer.MAX_VALUE) { throw new ArithmeticException("Result too large"); } return ONE.shiftLeft((int)powOf2); } BigInteger y = BigInteger.ONE, z = this; while (exp != 0) { if ((exp & 0x1) == 1) { y = y.multiply(z); } exp >>= 1; if (exp != 0) { z = z.multiply(z); } } return y; } public static BigInteger probablePrime( int bitLength, Random random) { return new BigInteger(bitLength, 100, random); } private int remainder(int m) { long acc = 0; for (int pos = 0; pos < magnitude.length; ++pos) { acc = (acc << 32 | ((long)magnitude[pos] & 0xffffffffL)) % m; } return (int) acc; } /** * return x = x % y - done in place (y value preserved) */ private static int[] remainder(int[] x, int[] y) { int xStart = 0; while (xStart < x.length && x[xStart] == 0) { ++xStart; } int yStart = 0; while (yStart < y.length && y[yStart] == 0) { ++yStart; } int xyCmp = compareNoLeadingZeroes(xStart, x, yStart, y); if (xyCmp > 0) { int yBitLength = calcBitLength(1, yStart, y); int xBitLength = calcBitLength(1, xStart, x); int shift = xBitLength - yBitLength; int[] c; int cStart = 0; int cBitLength = yBitLength; if (shift > 0) { c = shiftLeft(y, shift); cBitLength += shift; } else { int len = y.length - yStart; c = new int[len]; System.arraycopy(y, yStart, c, 0, len); } for (;;) { if (cBitLength < xBitLength || compareNoLeadingZeroes(xStart, x, cStart, c) >= 0) { subtract(xStart, x, cStart, c); while (x[xStart] == 0) { if (++xStart == x.length) { return x; } } xyCmp = compareNoLeadingZeroes(xStart, x, yStart, y); if (xyCmp <= 0) { break; } //xBitLength = bitLength(xStart, x); xBitLength = 32 * (x.length - xStart - 1) + bitLen(x[xStart]); } shift = cBitLength - xBitLength; if (shift < 2) { shiftRightOneInPlace(cStart, c); --cBitLength; } else { shiftRightInPlace(cStart, c, shift); cBitLength -= shift; } // cStart = c.length - ((cBitLength + 31) / 32); while (c[cStart] == 0) { ++cStart; } } } if (xyCmp == 0) { for (int i = xStart; i < x.length; ++i) { x[i] = 0; } } return x; } public BigInteger remainder(BigInteger n) throws ArithmeticException { if (n.sign == 0) { throw new ArithmeticException("BigInteger: Divide by zero"); } if (sign == 0) { return BigInteger.ZERO; } // For small values, use fast remainder method if (n.magnitude.length == 1) { int val = n.magnitude[0]; if (val > 0) { if (val == 1) return ZERO; int rem = remainder(val); return rem == 0 ? ZERO : new BigInteger(sign, new int[]{ rem }); } } if (compareTo(0, magnitude, 0, n.magnitude) < 0) return this; int[] res; if (n.quickPow2Check()) // n is power of two { // TODO Move before small values branch above? res = lastNBits(n.abs().bitLength() - 1); } else { res = new int[this.magnitude.length]; System.arraycopy(this.magnitude, 0, res, 0, res.length); res = remainder(res, n.magnitude); } return new BigInteger(sign, res); } private int[] lastNBits( int n) { if (n < 1) { return ZERO_MAGNITUDE; } int numWords = (n + 31) / 32; numWords = Math.min(numWords, this.magnitude.length); int[] result = new int[numWords]; System.arraycopy(this.magnitude, this.magnitude.length - numWords, result, 0, numWords); int excessBits = (numWords << 5) - n; if (excessBits > 0) { result[0] &= (-1 >>> excessBits); } return result; } private BigInteger divideWords(int w) { // assert w >= 0; int n = magnitude.length; if (w >= n) { return ZERO; } int[] mag = new int[n - w]; System.arraycopy(magnitude, 0, mag, 0, n - w); return new BigInteger(sign, mag); } private BigInteger remainderWords(int w) { // assert w >= 0; int n = magnitude.length; if (w >= n) { return this; } int[] mag = new int[w]; System.arraycopy(magnitude, n - w, mag, 0, w); return new BigInteger(sign, mag); } /** * do a left shift - this returns a new array. */ private static int[] shiftLeft(int[] mag, int n) { int nInts = n >>> 5; int nBits = n & 0x1f; int magLen = mag.length; int newMag[] = null; if (nBits == 0) { newMag = new int[magLen + nInts]; System.arraycopy(mag, 0, newMag, 0, magLen); } else { int i = 0; int nBits2 = 32 - nBits; int highBits = mag[0] >>> nBits2; if (highBits != 0) { newMag = new int[magLen + nInts + 1]; newMag[i++] = highBits; } else { newMag = new int[magLen + nInts]; } int m = mag[0]; for (int j = 0; j < magLen - 1; j++) { int next = mag[j + 1]; newMag[i++] = (m << nBits) | (next >>> nBits2); m = next; } newMag[i] = mag[magLen - 1] << nBits; } return newMag; } private static int shiftLeftOneInPlace(int[] x, int carry) { // assert carry == 0 || carry == 1; int pos = x.length; while (--pos >= 0) { int val = x[pos]; x[pos] = (val << 1) | carry; carry = val >>> 31; } return carry; } public BigInteger shiftLeft(int n) { if (sign == 0 || magnitude.length == 0) { return ZERO; } if (n == 0) { return this; } if (n < 0) { return shiftRight( -n); } BigInteger result = new BigInteger(sign, shiftLeft(magnitude, n)); if (this.nBits != -1) { result.nBits = sign > 0 ? this.nBits : this.nBits + n; } if (this.nBitLength != -1) { result.nBitLength = this.nBitLength + n; } return result; } /** * do a right shift - this does it in place. */ private static void shiftRightInPlace(int start, int[] mag, int n) { int nInts = (n >>> 5) + start; int nBits = n & 0x1f; int magEnd = mag.length - 1; if (nInts != start) { int delta = (nInts - start); for (int i = magEnd; i >= nInts; i--) { mag[i] = mag[i - delta]; } for (int i = nInts - 1; i >= start; i--) { mag[i] = 0; } } if (nBits != 0) { int nBits2 = 32 - nBits; int m = mag[magEnd]; for (int i = magEnd; i >= nInts + 1; i--) { int next = mag[i - 1]; mag[i] = (m >>> nBits) | (next << nBits2); m = next; } mag[nInts] >>>= nBits; } } /** * do a right shift by one - this does it in place. */ private static void shiftRightOneInPlace(int start, int[] mag) { int magEnd = mag.length - 1; int m = mag[magEnd]; for (int i = magEnd; i > start; i--) { int next = mag[i - 1]; mag[i] = (m >>> 1) | (next << 31); m = next; } mag[start] >>>= 1; } public BigInteger shiftRight(int n) { if (n == 0) { return this; } if (n < 0) { return shiftLeft( -n); } if (n >= bitLength()) { return (this.sign < 0 ? valueOf( -1) : BigInteger.ZERO); } int[] res = new int[this.magnitude.length]; System.arraycopy(this.magnitude, 0, res, 0, res.length); shiftRightInPlace(0, res, n); return new BigInteger(this.sign, res); // TODO Port C# version's optimisations... } public int signum() { return sign; } /** * returns x = x - y - we assume x is >= y */ private static int[] subtract(int xStart, int[] x, int yStart, int[] y) { int iT = x.length; int iV = y.length; long m; int borrow = 0; do { m = ((long)x[--iT] & IMASK) - ((long)y[--iV] & IMASK) + borrow; x[iT] = (int)m; // borrow = (m < 0) ? -1 : 0; borrow = (int)(m >> 63); } while (iV > yStart); if (borrow != 0) { while (--x[--iT] == -1) { } } return x; } public BigInteger subtract(BigInteger val) { if (val.sign == 0 || val.magnitude.length == 0) { return this; } if (sign == 0 || magnitude.length == 0) { return val.negate(); } if (this.sign != val.sign) { return this.add(val.negate()); } int compare = compareTo(0, magnitude, 0, val.magnitude); if (compare == 0) { return ZERO; } BigInteger bigun, littlun; if (compare < 0) { bigun = val; littlun = this; } else { bigun = this; littlun = val; } int res[] = new int[bigun.magnitude.length]; System.arraycopy(bigun.magnitude, 0, res, 0, res.length); return new BigInteger(this.sign * compare, subtract(0, res, 0, littlun.magnitude)); } public byte[] toByteArray() { if (sign == 0) { return new byte[1]; } int bitLength = bitLength(); byte[] bytes = new byte[bitLength / 8 + 1]; int magIndex = magnitude.length; int bytesIndex = bytes.length; if (sign > 0) { while (magIndex > 1) { int mag = magnitude[--magIndex]; bytes[--bytesIndex] = (byte) mag; bytes[--bytesIndex] = (byte)(mag >>> 8); bytes[--bytesIndex] = (byte)(mag >>> 16); bytes[--bytesIndex] = (byte)(mag >>> 24); } int lastMag = magnitude[0]; while ((lastMag & 0xFFFFFF00) != 0) { bytes[--bytesIndex] = (byte) lastMag; lastMag >>>= 8; } bytes[--bytesIndex] = (byte) lastMag; } else { boolean carry = true; while (magIndex > 1) { int mag = ~magnitude[--magIndex]; if (carry) { carry = (++mag == 0); } bytes[--bytesIndex] = (byte) mag; bytes[--bytesIndex] = (byte)(mag >>> 8); bytes[--bytesIndex] = (byte)(mag >>> 16); bytes[--bytesIndex] = (byte)(mag >>> 24); } int lastMag = magnitude[0]; if (carry) { // Never wraps because magnitude[0] != 0 --lastMag; } while ((lastMag & 0xFFFFFF00) != 0) { bytes[--bytesIndex] = (byte) ~lastMag; lastMag >>>= 8; } bytes[--bytesIndex] = (byte) ~lastMag; if (bytesIndex > 0) { bytes[--bytesIndex] = (byte)0xFF; } } return bytes; } public BigInteger xor(BigInteger val) { if (this.sign == 0) { return val; } if (val.sign == 0) { return this; } int[] aMag = this.sign > 0 ? this.magnitude : this.add(ONE).magnitude; int[] bMag = val.sign > 0 ? val.magnitude : val.add(ONE).magnitude; boolean resultNeg = (sign < 0 && val.sign >= 0) || (sign >= 0 && val.sign < 0); int resultLength = Math.max(aMag.length, bMag.length); int[] resultMag = new int[resultLength]; int aStart = resultMag.length - aMag.length; int bStart = resultMag.length - bMag.length; for (int i = 0; i < resultMag.length; ++i) { int aWord = i >= aStart ? aMag[i - aStart] : 0; int bWord = i >= bStart ? bMag[i - bStart] : 0; if (this.sign < 0) { aWord = ~aWord; } if (val.sign < 0) { bWord = ~bWord; } resultMag[i] = aWord ^ bWord; if (resultNeg) { resultMag[i] = ~resultMag[i]; } } BigInteger result = new BigInteger(1, resultMag); if (resultNeg) { result = result.not(); } return result; } public BigInteger or( BigInteger value) { if (this.sign == 0) { return value; } if (value.sign == 0) { return this; } int[] aMag = this.sign > 0 ? this.magnitude : this.add(ONE).magnitude; int[] bMag = value.sign > 0 ? value.magnitude : value.add(ONE).magnitude; boolean resultNeg = sign < 0 || value.sign < 0; int resultLength = Math.max(aMag.length, bMag.length); int[] resultMag = new int[resultLength]; int aStart = resultMag.length - aMag.length; int bStart = resultMag.length - bMag.length; for (int i = 0; i < resultMag.length; ++i) { int aWord = i >= aStart ? aMag[i - aStart] : 0; int bWord = i >= bStart ? bMag[i - bStart] : 0; if (this.sign < 0) { aWord = ~aWord; } if (value.sign < 0) { bWord = ~bWord; } resultMag[i] = aWord | bWord; if (resultNeg) { resultMag[i] = ~resultMag[i]; } } BigInteger result = new BigInteger(1, resultMag); if (resultNeg) { result = result.not(); } return result; } public BigInteger setBit(int n) throws ArithmeticException { if (n < 0) { throw new ArithmeticException("Bit address less than zero"); } if (testBit(n)) { return this; } // TODO Handle negative values and zero if (sign > 0 && n < (bitLength() - 1)) { return flipExistingBit(n); } return or(ONE.shiftLeft(n)); } public BigInteger clearBit(int n) throws ArithmeticException { if (n < 0) { throw new ArithmeticException("Bit address less than zero"); } if (!testBit(n)) { return this; } // TODO Handle negative values if (sign > 0 && n < (bitLength() - 1)) { return flipExistingBit(n); } return andNot(ONE.shiftLeft(n)); } public BigInteger flipBit(int n) throws ArithmeticException { if (n < 0) { throw new ArithmeticException("Bit address less than zero"); } // TODO Handle negative values and zero if (sign > 0 && n < (bitLength() - 1)) { return flipExistingBit(n); } return xor(ONE.shiftLeft(n)); } private BigInteger flipExistingBit(int n) { int[] mag = new int[this.magnitude.length]; System.arraycopy(this.magnitude, 0, mag, 0, mag.length); mag[mag.length - 1 - (n >>> 5)] ^= (1 << (n & 31)); // Flip 0 bit to 1 //mag[mag.Length - 1 - (n / 32)] |= (1 << (n % 32)); return new BigInteger(this.sign, mag); } public String toString() { return toString(10); } public String toString(int rdx) { if (magnitude == null) { return "null"; } if (sign == 0) { return "0"; } if (rdx < Character.MIN_RADIX || rdx > Character.MAX_RADIX) { rdx = 10; } // NOTE: This *should* be unnecessary, since the magnitude *should* never have leading zero digits int firstNonZero = 0; while (firstNonZero < magnitude.length) { if (magnitude[firstNonZero] != 0) { break; } ++firstNonZero; } if (firstNonZero == magnitude.length) { return "0"; } StringBuffer sb = new StringBuffer(); if (sign == -1) { sb.append('-'); } switch (rdx) { case 2: { int pos = firstNonZero; sb.append(Integer.toBinaryString(magnitude[pos])); while (++pos < magnitude.length) { appendZeroExtendedString(sb, Integer.toBinaryString(magnitude[pos]), 32); } break; } case 4: { int pos = firstNonZero; int mag = magnitude[pos]; if (mag < 0) { sb.append(Integer.toString(mag >>> 30, 4)); mag &= (1 << 30) - 1; appendZeroExtendedString(sb, Integer.toString(mag, 4), 15); } else { sb.append(Integer.toString(mag, 4)); } int mask = (1 << 16) - 1; while (++pos < magnitude.length) { mag = magnitude[pos]; appendZeroExtendedString(sb, Integer.toString(mag >>> 16, 4), 8); appendZeroExtendedString(sb, Integer.toString(mag & mask, 4), 8); } break; } case 8: { long mask = (1L << 63) - 1; BigInteger u = this.abs(); int bits = u.bitLength(); Stack S = new Stack(); while (bits > 63) { S.push(Long.toString((u.longValue() & mask),8)); u = u.shiftRight(63); bits -= 63; } sb.append(Long.toString(u.longValue(), 8)); while (!S.empty()) { appendZeroExtendedString(sb, (String)S.pop(), 21); } break; } case 16: { int pos = firstNonZero; sb.append(Integer.toHexString(magnitude[pos])); while (++pos < magnitude.length) { appendZeroExtendedString(sb, Integer.toHexString(magnitude[pos]), 8); } break; } default: { BigInteger q = this.abs(); if (q.bitLength() < 64) { sb.append(Long.toString(q.longValue(), rdx)); break; } // Based on algorithm 1a from chapter 4.4 in Seminumerical Algorithms (Knuth) // Work out the largest power of 'rdx' that is a positive 64-bit integer // TODO possibly cache power/exponent against radix? long limit = Long.MAX_VALUE / rdx; long power = rdx; int exponent = 1; while (power <= limit) { power *= rdx; ++exponent; } BigInteger bigPower = BigInteger.valueOf(power); Stack S = new Stack(); while (q.compareTo(bigPower) >= 0) { BigInteger[] qr = q.divideAndRemainder(bigPower); S.push(Long.toString(qr[1].longValue(), rdx)); q = qr[0]; } sb.append(Long.toString(q.longValue(), rdx)); while (!S.empty()) { appendZeroExtendedString(sb, (String)S.pop(), exponent); } break; } } return sb.toString(); } private static void appendZeroExtendedString(StringBuffer sb, String s, int minLength) { for (int len = s.length(); len < minLength; ++len) { sb.append('0'); } sb.append(s); } public static BigInteger valueOf(long val) { if (val >= 0 && val < SMALL_CONSTANTS.length) { return SMALL_CONSTANTS[(int)val]; } return createValueOf(val); } private static BigInteger createValueOf(long val) { if (val < 0) { if (val == Long.MIN_VALUE) { return valueOf(~val).not(); } return valueOf(-val).negate(); } // store val into a byte array byte[] b = new byte[8]; for (int i = 0; i < 8; i++) { b[7 - i] = (byte)val; val >>= 8; } return new BigInteger(b); } public int getLowestSetBit() { if (this.sign == 0) { return -1; } return getLowestSetBitMaskFirst(-1); } private int getLowestSetBitMaskFirst(int firstWordMask) { int w = magnitude.length, offset = 0; int word = magnitude[--w] & firstWordMask; // assert magnitude[0] != 0; while (word == 0) { word = magnitude[--w]; offset += 32; } while ((word & 0xFF) == 0) { word >>>= 8; offset += 8; } while ((word & 1) == 0) { word >>>= 1; ++offset; } return offset; } public boolean testBit(int n) throws ArithmeticException { if (n < 0) { throw new ArithmeticException("Bit position must not be negative"); } if (sign < 0) { return !not().testBit(n); } int wordNum = n / 32; if (wordNum >= magnitude.length) return false; int word = magnitude[magnitude.length - 1 - wordNum]; return ((word >> (n % 32)) & 1) > 0; } } bouncycastle-1.49.orig/j2me/java/io/0000755000175000017500000000000012152033550016612 5ustar ebourgebourgbouncycastle-1.49.orig/j2me/java/io/FilterOutputStream.java0000644000175000017500000000131710262753174023314 0ustar ebourgebourgpackage java.io; public class FilterOutputStream extends OutputStream { protected OutputStream out; protected FilterOutputStream(OutputStream underlying) { out = underlying; } public void write(int b) throws IOException { out.write(b); } public void write(byte[] b) throws IOException { write(b, 0, b.length); } public void write(byte[] b, int offset, int length) throws IOException { for (int i = 0; i < length; i++) { write(b[offset + i]); } } public void flush() throws IOException { out.flush(); } public void close() throws IOException { out.close(); } } bouncycastle-1.49.orig/j2me/java/io/FilterInputStream.java0000644000175000017500000000174310262753174023116 0ustar ebourgebourgpackage java.io; public class FilterInputStream extends InputStream { protected InputStream in; protected FilterInputStream(InputStream underlying) { in = underlying; } public int read() throws IOException { return in.read(); } public int read(byte[] b) throws IOException { return read(b, 0, b.length); } public int read(byte[] b, int offset, int length) throws IOException { return in.read(b, offset, length); } public long skip(long n) throws IOException { return in.skip(n); } public int available() throws IOException { return in.available(); } public void close() throws IOException { in.close(); } public void mark(int readlimit) { in.mark(readlimit); } public void reset() throws IOException { in.reset(); } public boolean markSupported() { return in.markSupported(); } } bouncycastle-1.49.orig/j2me/java/security/0000755000175000017500000000000012152033550020052 5ustar ebourgebourgbouncycastle-1.49.orig/j2me/java/security/SecureRandom.java0000644000175000017500000000704711240730117023314 0ustar ebourgebourgpackage java.security; import java.util.Random; import org.bouncycastle.crypto.digests.SHA1Digest; import org.bouncycastle.crypto.digests.SHA256Digest; import org.bouncycastle.crypto.prng.RandomGenerator; import org.bouncycastle.crypto.prng.DigestRandomGenerator; /** * An implementation of SecureRandom specifically for the light-weight API, JDK * 1.0, and the J2ME. Random generation is based on the traditional SHA1 with * counter. Calling setSeed will always increase the entropy of the hash. *

    * Do not use this class without calling setSeed at least once! There * are some example seed generators in the org.bouncycastle.prng package. */ public class SecureRandom extends java.util.Random { // Note: all objects of this class should be deriving their random data from // a single generator appropriate to the digest being used. private static final RandomGenerator sha1Generator = new DigestRandomGenerator(new SHA1Digest()); private static final RandomGenerator sha256Generator = new DigestRandomGenerator(new SHA256Digest()); protected RandomGenerator generator; // public constructors public SecureRandom() { this(sha1Generator); setSeed(System.currentTimeMillis()); } public SecureRandom(byte[] inSeed) { this(sha1Generator); setSeed(inSeed); } protected SecureRandom( RandomGenerator generator) { super(0); this.generator = generator; } // protected constructors // protected SecureRandom(SecureRandomSpi srs, Provider provider); // public class methods public static SecureRandom getInstance(String algorithm) { if (algorithm.equals("SHA1PRNG")) { return new SecureRandom(sha1Generator); } if (algorithm.equals("SHA256PRNG")) { return new SecureRandom(sha256Generator); } return new SecureRandom(); // follow old behaviour } public static SecureRandom getInstance(String algorithm, String provider) { return getInstance(algorithm); } public static byte[] getSeed(int numBytes) { byte[] rv = new byte[numBytes]; sha1Generator.addSeedMaterial(System.currentTimeMillis()); sha1Generator.nextBytes(rv); return rv; } // public instance methods public byte[] generateSeed(int numBytes) { byte[] rv = new byte[numBytes]; nextBytes(rv); return rv; } // public final Provider getProvider(); public void setSeed(byte[] inSeed) { generator.addSeedMaterial(inSeed); } // public methods overriding random public void nextBytes(byte[] bytes) { generator.nextBytes(bytes); } public void setSeed(long rSeed) { if (rSeed != 0) // to avoid problems with Random calling setSeed in construction { generator.addSeedMaterial(rSeed); } } public int nextInt() { byte[] intBytes = new byte[4]; nextBytes(intBytes); int result = 0; for (int i = 0; i < 4; i++) { result = (result << 8) + (intBytes[i] & 0xff); } return result; } protected final int next(int numBits) { int size = (numBits + 7) / 8; byte[] bytes = new byte[size]; nextBytes(bytes); int result = 0; for (int i = 0; i < size; i++) { result = (result << 8) + (bytes[i] & 0xff); } return result & ((1 << numBits) - 1); } } bouncycastle-1.49.orig/bc+-build.xml0000644000175000017500000012710112151567702016717 0ustar ebourgebourg bouncycastle-1.49.orig/jce/0000755000175000017500000000000012152033546015173 5ustar ebourgebourgbouncycastle-1.49.orig/jce/src/0000755000175000017500000000000012152033546015762 5ustar ebourgebourgbouncycastle-1.49.orig/jce/src/javax/0000755000175000017500000000000012152033546017073 5ustar ebourgebourgbouncycastle-1.49.orig/jce/src/javax/crypto/0000755000175000017500000000000012152033546020413 5ustar ebourgebourgbouncycastle-1.49.orig/jce/src/javax/crypto/BadPaddingException.java0000644000175000017500000000167010757407514025127 0ustar ebourgebourgpackage javax.crypto; import java.security.GeneralSecurityException; /** * This exception is thrown when a particular padding mechanism is * expected for the input data but the data is not padded properly * */ public class BadPaddingException extends GeneralSecurityException { private static final long serialVersionUID = -5315033893984728443L; /** * Constructs a BadPaddingException with no detail * message. A detail message is a String that describes this * particular exception. */ public BadPaddingException() { } /** * Constructs a BadPaddingException with the specified * detail message. A detail message is a String that describes * this particular exception, which may, for example, specify which * algorithm is not available. * * @param msg the detail message. */ public BadPaddingException( String msg) { super(msg); } } bouncycastle-1.49.orig/jce/src/javax/crypto/SecretKeyFactorySpi.java0000644000175000017500000000570510445172704025172 0ustar ebourgebourgpackage javax.crypto; import java.security.InvalidKeyException; import java.security.spec.KeySpec; import java.security.spec.InvalidKeySpecException; /** * This class defines the Service Provider Interface (SPI) * for the SecretKeyFactory class. * All the abstract methods in this class must be implemented by each * cryptographic service provider who wishes to supply the implementation * of a secret-key factory for a particular algorithm. *

    * A provider should document all the key specifications supported by its * secret key factory. * For example, the DES secret-key factory supplied by the "SunJCE" provider * supports DESKeySpec as a transparent representation of DES * keys, and that provider's secret-key factory for Triple DES keys supports * DESedeKeySpec as a transparent representation of Triple DES * keys. * * @see SecretKey * @see javax.crypto.spec.DESKeySpec * @see javax.crypto.spec.DESedeKeySpec */ public abstract class SecretKeyFactorySpi { public SecretKeyFactorySpi() { } /** * Generates a SecretKey object from the * provided key specification (key material). * * @param keySpec the specification (key material) of the secret key * @return the secret key * @exception InvalidKeySpecException if the given key specification * is inappropriate for this secret-key factory to produce a secret key. */ protected abstract SecretKey engineGenerateSecret( KeySpec keySpec) throws InvalidKeySpecException; /** * Returns a specification (key material) of the given key object in the requested format. * * @param key the key * @param keySpec the requested format in which the key material shall be returned * @return the underlying key specification (key material) in the requested format * @exception InvalidKeySpecException if the requested key specification is inappropriate for * the given key (e.g., the algorithms associated with key and keySpec do * not match, or key references a key on a cryptographic hardware device whereas * keySpec is the specification of a software-based key), or the given key cannot be * dealt with (e.g., the given key has an algorithm or format not supported by this secret-key factory). */ protected abstract KeySpec engineGetKeySpec( SecretKey key, Class keySpec) throws InvalidKeySpecException; /** * Translates a key object, whose provider may be unknown or potentially untrusted, into a * corresponding key object of this secret-key factory. * * @param key the key whose provider is unknown or untrusted * @return InvalidKeyException if the given key cannot be processed by this secret-key factory. */ protected abstract SecretKey engineTranslateKey( SecretKey key) throws InvalidKeyException; } bouncycastle-1.49.orig/jce/src/javax/crypto/ExemptionMechanism.java0000644000175000017500000000026710445172704025063 0ustar ebourgebourgpackage javax.crypto; /** * this is a place holder class, no exemption mechanism facility is * required in this modified version of the JCE */ public class ExemptionMechanism { } bouncycastle-1.49.orig/jce/src/javax/crypto/KeyGeneratorSpi.java0000644000175000017500000000401010445172704024327 0ustar ebourgebourgpackage javax.crypto; import java.security.SecureRandom; import java.security.spec.AlgorithmParameterSpec; import java.security.InvalidParameterException; import java.security.InvalidAlgorithmParameterException; /** * This class defines the Service Provider Interface (SPI) * for the KeyGenerator class. * All the abstract methods in this class must be implemented by each * cryptographic service provider who wishes to supply the implementation * of a key generator for a particular algorithm. * * @see SecretKey */ public abstract class KeyGeneratorSpi { public KeyGeneratorSpi() { } /** * Initializes the key generator. * * @param random the source of randomness for this generator */ protected abstract void engineInit( SecureRandom random); /** * Initializes the key generator with the specified parameter * set and a user-provided source of randomness. * * @param params the key generation parameters * @param random the source of randomness for this key generator * @exception InvalidAlgorithmParameterException if params is * inappropriate for this key generator */ protected abstract void engineInit( AlgorithmParameterSpec params, SecureRandom random) throws InvalidAlgorithmParameterException; /** * Initializes this key generator for a certain keysize, using the given * source of randomness. * * @param keysize the keysize. This is an algorithm-specific metric, specified in number of bits. * @param random the source of randomness for this key generator. * @exception InvalidParameterException if keysize is wrong or not supported. */ protected abstract void engineInit( int keysize, SecureRandom random) throws InvalidParameterException; /** * Generates a secret key. * * @return the new key. */ protected abstract SecretKey engineGenerateKey(); } bouncycastle-1.49.orig/jce/src/javax/crypto/EncryptedPrivateKeyInfo.java0000644000175000017500000001724311730536621026045 0ustar ebourgebourgpackage javax.crypto; import java.io.*; import java.security.*; import java.security.spec.*; import org.bouncycastle.asn1.ASN1InputStream; import org.bouncycastle.asn1.DEROutputStream; import org.bouncycastle.asn1.ASN1Sequence; import org.bouncycastle.asn1.DERObjectIdentifier; import org.bouncycastle.asn1.x509.AlgorithmIdentifier; /** * This class implements the EncryptedPrivateKeyInfo type * as defined in PKCS #8. *

    Its ASN.1 definition is as follows: * *

     * EncryptedPrivateKeyInfo ::=  SEQUENCE {
     *     encryptionAlgorithm   AlgorithmIdentifier,
     *     encryptedData   OCTET STRING }
     * 
     * AlgorithmIdentifier  ::=  SEQUENCE  {
     *     algorithm              OBJECT IDENTIFIER,
     *     parameters             ANY DEFINED BY algorithm OPTIONAL  }
     * 
    */ public class EncryptedPrivateKeyInfo { private org.bouncycastle.asn1.pkcs.EncryptedPrivateKeyInfo infoObj; private AlgorithmParameters algP; /* * Constructs (i.e., parses) an EncryptedPrivateKeyInfo from * its ASN.1 encoding. * * @param encoded the ASN.1 encoding of this object. * @exception NullPointerException if the encoded is null. * @exception IOException if error occurs when parsing the ASN.1 encoding. */ public EncryptedPrivateKeyInfo( byte[] encoded) throws NullPointerException, IOException { if (encoded == null) { throw new NullPointerException("parameters null"); } ByteArrayInputStream bIn = new ByteArrayInputStream(encoded); ASN1InputStream dIn = new ASN1InputStream(bIn); infoObj = org.bouncycastle.asn1.pkcs.EncryptedPrivateKeyInfo.getInstance((ASN1Sequence)dIn.readObject()); try { algP = this.getParameters(); } catch (NoSuchAlgorithmException e) { throw new IOException("can't create parameters: " + e.toString()); } } /* * Constructs an EncryptedPrivateKeyInfo from the * encryption algorithm name and the encrypted data. *

    Note: the encrypedData is cloned when constructing * this object. *

    * If encryption algorithm has associated parameters use the constructor * with AlgorithmParameters as the parameter. * * @param algName algorithm name. * @param encryptedData encrypted data. * @exception NullPointerException if algName or encryptedData is null. * @exception IllegalArgumentException if encryptedData is empty, i.e. 0-length. * @exception NoSuchAlgorithmException if the specified algName is not supported. */ public EncryptedPrivateKeyInfo( String algName, byte[] encryptedData) throws NullPointerException, IllegalArgumentException, NoSuchAlgorithmException { if (algName == null || encryptedData == null) { throw new NullPointerException("parameters null"); } org.bouncycastle.asn1.x509.AlgorithmIdentifier kAlgId = new AlgorithmIdentifier(new DERObjectIdentifier(algName), null); infoObj = new org.bouncycastle.asn1.pkcs.EncryptedPrivateKeyInfo(kAlgId, (byte[])encryptedData.clone()); algP = this.getParameters(); } /** * Constructs an EncryptedPrivateKeyInfo from the * encryption algorithm parameters and the encrypted data. *

    Note: the encrypedData is cloned when constructing * this object. * * @param algParams the algorithm parameters for the encryption * algorithm. algParams.getEncoded() should return * the ASN.1 encoded bytes of the parameters field * of the AlgorithmIdentifer component of the * EncryptedPrivateKeyInfo type. * @param encryptedData encrypted data. * @exception NullPointerException if algParams or encryptedData is null. * @exception IllegalArgumentException if encryptedData is empty, i.e. 0-length. * @exception NoSuchAlgorithmException if the specified algName of the specified algParams parameter is not supported. */ public EncryptedPrivateKeyInfo( AlgorithmParameters algParams, byte[] encryptedData) throws NullPointerException, IllegalArgumentException, NoSuchAlgorithmException { if (algParams == null || encryptedData == null) { throw new NullPointerException("parameters null"); } org.bouncycastle.asn1.x509.AlgorithmIdentifier kAlgId = null; try { ByteArrayInputStream bIn = new ByteArrayInputStream(algParams.getEncoded()); ASN1InputStream dIn = new ASN1InputStream(bIn); kAlgId = new AlgorithmIdentifier( new DERObjectIdentifier(algParams.getAlgorithm()), dIn.readObject()); } catch (IOException e) { throw new IllegalArgumentException("error in encoding: " + e.toString()); } infoObj = new org.bouncycastle.asn1.pkcs.EncryptedPrivateKeyInfo(kAlgId, (byte[])encryptedData.clone()); algP = this.getParameters(); } /** * Returns the encryption algorithm. * * @returns the algorithm name. */ public String getAlgName() { return infoObj.getEncryptionAlgorithm().getObjectId().getId(); } private AlgorithmParameters getParameters() throws NoSuchAlgorithmException { AlgorithmParameters ap = AlgorithmParameters.getInstance(this.getAlgName()); ByteArrayOutputStream bOut = new ByteArrayOutputStream(); DEROutputStream dOut = new DEROutputStream(bOut); try { dOut.writeObject(infoObj.getEncryptionAlgorithm().getParameters()); dOut.close(); ap.init(bOut.toByteArray()); } catch (IOException e) { throw new NoSuchAlgorithmException("unable to parse parameters"); } return ap; } /** * Returns the algorithm parameters used by the encryption algorithm. * * @returns the algorithm parameters. */ public AlgorithmParameters getAlgParameters() { return algP; } /** * Returns a copy of the encrypted data. * * @returns a copy of the encrypted data. */ public byte[] getEncryptedData() { return infoObj.getEncryptedData(); } /** * Extract the enclosed PKCS8EncodedKeySpec object from the * encrypted data and return it. * * @return the PKCS8EncodedKeySpec object. * @exception InvalidKeySpecException if the given cipher is * inappropriate for the encrypted data or the encrypted * data is corrupted and cannot be decrypted. */ public PKCS8EncodedKeySpec getKeySpec( Cipher c) throws InvalidKeySpecException { try { return new PKCS8EncodedKeySpec(c.doFinal(this.getEncryptedData())); } catch (Exception e) { throw new InvalidKeySpecException("can't get keySpec: " + e.toString()); } } /** * Returns the ASN.1 encoding of this object. * * @returns the ASN.1 encoding. * @throws IOException if error occurs when constructing its ASN.1 encoding. */ public byte[] getEncoded() throws IOException { ByteArrayOutputStream bOut = new ByteArrayOutputStream(); DEROutputStream dOut = new DEROutputStream(bOut); dOut.writeObject(infoObj); dOut.close(); return bOut.toByteArray(); } } bouncycastle-1.49.orig/jce/src/javax/crypto/SecretKey.java0000644000175000017500000000171210445172704023160 0ustar ebourgebourgpackage javax.crypto; import java.security.Key; /** * A secret (symmetric) key. *

    * This interface contains no methods or constants. * Its only purpose is to group (and provide type safety for) secret keys. *

    * Provider implementations of this interface must overwrite the * equals and hashCode methods inherited from * java.lang.Object, so that secret keys are compared based on * their underlying key material and not based on reference. *

    * Keys that implement this interface return the string RAW * as their encoding format (see getFormat), and return the * raw key bytes as the result of a getEncoded method call. (The * getFormat and getEncoded methods are inherited * from the java.security.Key parent interface.) * * @see SecretKeyFactory * @see Cipher */ public abstract interface SecretKey extends Key { } bouncycastle-1.49.orig/jce/src/javax/crypto/NullCipher.java0000644000175000017500000001551710445172704023337 0ustar ebourgebourgpackage javax.crypto; import java.security.Key; import java.security.SecureRandom; import java.security.InvalidKeyException; import java.security.AlgorithmParameters; import java.security.NoSuchAlgorithmException; import java.security.InvalidAlgorithmParameterException; import java.security.spec.AlgorithmParameterSpec; /** * The NullCipher class is a class that provides an * "identity cipher" -- one that does not tranform the plaintext. As * a consequence, the ciphertext is identical to the plaintext. All * initialization methods do nothing, while the blocksize is set to 1 * byte. * * @since JCE1.2 */ public class NullCipher extends Cipher { static private class NullCipherSpi extends CipherSpi { /** * Sets the mode of this cipher - no op. */ protected void engineSetMode( String mode) throws NoSuchAlgorithmException { } /** * Sets the padding mechanism of this cipher - no op. */ protected void engineSetPadding( String padding) throws NoSuchPaddingException { } /** * Returns the block size (in bytes) - 1 */ protected int engineGetBlockSize() { return 1; } /** * Returns the length in bytes that an output buffer would * need to be in order to hold the result of the next update * or doFinal operation, given the input length * inputLen (in bytes). * * @param inputLen the input length (in bytes) * @return the required output buffer size (in bytes) */ protected int engineGetOutputSize( int inputLen) { return inputLen; } /** * Returns the initialization vector (IV) in a new buffer. * * @return null */ protected byte[] engineGetIV() { return null; } /** * Returns the parameters used with this cipher - null */ protected AlgorithmParameters engineGetParameters() { return null; } /** * Initializes this cipher with a key and a source * of randomness - no op. */ protected void engineInit( int opmode, Key key, SecureRandom random) throws InvalidKeyException { } /** * Initializes this cipher with a key, a set of * algorithm parameters, and a source of randomness - no op. */ protected void engineInit( int opmode, Key key, AlgorithmParameterSpec params, SecureRandom random) throws InvalidKeyException, InvalidAlgorithmParameterException { } /** * Initializes this cipher with a key, a set of * algorithm parameters, and a source of randomness - no op. */ protected void engineInit( int opmode, Key key, AlgorithmParameters params, SecureRandom random) throws InvalidKeyException, InvalidAlgorithmParameterException { } /** * Continues a multiple-part encryption or decryption operation * (depending on how this cipher was initialized), processing another data * part - in this case just return a copy of the input. */ protected byte[] engineUpdate( byte[] input, int inputOffset, int inputLen) { if (input == null) { return null; } byte[] tmp = new byte[inputLen]; System.arraycopy(input, inputOffset, tmp, 0, inputLen); return tmp; } /** * Continues a multiple-part encryption or decryption operation * (depending on how this cipher was initialized), processing another data * part - in this case just copy the input to the output. */ protected int engineUpdate( byte[] input, int inputOffset, int inputLen, byte[] output, int outputOffset) throws ShortBufferException { if (input == null) { return 0; } if ((output.length - outputOffset) < inputLen) { throw new ShortBufferException("output buffer to short for NullCipher"); } System.arraycopy(input, inputOffset, output, outputOffset, inputLen); return inputLen; } /** * Encrypts or decrypts data in a single-part operation, or finishes a multiple-part operation. * The data is encrypted or decrypted, depending on how this cipher was initialized * - in this case just return a copy of the input. */ protected byte[] engineDoFinal( byte[] input, int inputOffset, int inputLen) throws IllegalBlockSizeException, BadPaddingException { if (input == null) { return new byte[0]; } byte[] tmp = new byte[inputLen]; System.arraycopy(input, inputOffset, tmp, 0, inputLen); return tmp; } /** * Encrypts or decrypts data in a single-part operation, * or finishes a multiple-part operation. * The data is encrypted or decrypted, depending on how this cipher was * initialized. */ protected int engineDoFinal( byte[] input, int inputOffset, int inputLen, byte[] output, int outputOffset) throws ShortBufferException, IllegalBlockSizeException, BadPaddingException { if (input == null) { return 0; } if ((output.length - outputOffset) < inputLen) { throw new ShortBufferException("output buffer too short for NullCipher"); } System.arraycopy(input, inputOffset, output, outputOffset, inputLen); return inputLen; } /** * Returns the key size of the given key object - 0 */ protected int engineGetKeySize( Key key) throws InvalidKeyException { return 0; } } public NullCipher() { super(new NullCipherSpi(), null, "NULL"); } } bouncycastle-1.49.orig/jce/src/javax/crypto/KeyAgreementSpi.java0000644000175000017500000001676410445172704024333 0ustar ebourgebourgpackage javax.crypto; import java.security.Key; import java.security.SecureRandom; import java.security.InvalidKeyException; import java.security.NoSuchAlgorithmException; import java.security.InvalidAlgorithmParameterException; import java.security.spec.AlgorithmParameterSpec; /** * This class defines the Service Provider Interface (SPI) * for the KeyAgreement class. * All the abstract methods in this class must be implemented by each * cryptographic service provider who wishes to supply the implementation * of a particular key agreement algorithm. *

    * The keys involved in establishing a shared secret are created by one of the * key generators (KeyPairGenerator or KeyGenerator), * a KeyFactory, or as a result from an intermediate phase of the key * agreement protocol (see engineDoPhase). *

    * For each of the correspondents in the key exchange, engineDoPhase * needs to be called. For example, if the key exchange is with one other * party, engineDoPhase needs to be called once, with the * lastPhase flag set to true. * If the key exchange is with two other parties, engineDoPhase needs to be called twice, * the first time setting the lastPhase flag to * false, and the second time setting it to true. * There may be any number of parties involved in a key exchange. * * @see KeyGenerator * @see SecretKey */ public abstract class KeyAgreementSpi { public KeyAgreementSpi() { } /** * Initializes this key agreement with the given key and source of * randomness. The given key is required to contain all the algorithm * parameters required for this key agreement. *

    * If the key agreement algorithm requires random bytes, it gets them * from the given source of randomness, random. * However, if the underlying * algorithm implementation does not require any random bytes, * random is ignored. * * @param key the party's private information. For example, in the case * of the Diffie-Hellman key agreement, this would be the party's own Diffie-Hellman private key. * @param random the source of randomness * @exception InvalidKeyException if the given key is inappropriate for this key agreement, e.g., is * of the wrong type or has an incompatible algorithm type. */ protected abstract void engineInit( Key key, SecureRandom random) throws InvalidKeyException; /** * Initializes this key agreement with the given key, set of * algorithm parameters, and source of randomness. * * @param key the party's private information. For example, in the case * of the Diffie-Hellman key agreement, this would be the party's own * Diffie-Hellman private key. * @param params the key agreement parameters * @param random the source of randomness * @exception InvalidKeyException if the given key is inappropriate for this key agreement, e.g., is of the * wrong type or has an incompatible algorithm type. * @exception InvalidAlgorithmParameterException if the given parameters are inappropriate for this key * agreement. */ protected abstract void engineInit( Key key, AlgorithmParameterSpec params, SecureRandom random) throws InvalidKeyException, InvalidAlgorithmParameterException; /** * Executes the next phase of this key agreement with the given * key that was received from one of the other parties involved in this key * agreement. * @param key the key for this phase. For example, in the case of * Diffie-Hellman between 2 parties, this would be the other party's * Diffie-Hellman public key. * @param lastPhase flag which indicates whether or not this is the last * phase of this key agreement. * @return the (intermediate) key resulting from this phase, or null if this phase does not yield a key * @exception InvalidKeyException if the given key is inappropriate for this phase. * @exception IllegalStateException if this key agreement has not been initialized. */ protected abstract Key engineDoPhase( Key key, boolean lastPhase) throws InvalidKeyException, IllegalStateException; /** * Generates the shared secret and returns it in a new buffer. *

    * This method resets this KeyAgreementSpi object, so that it * can be reused for further key agreements. Unless this key agreement is * reinitialized with one of the engineInit methods, the same * private information and algorithm parameters will be used for * subsequent key agreements. * @return the new buffer with the shared secret * @exception IllegalStateException if this key agreement has not been completed yet */ protected abstract byte[] engineGenerateSecret() throws IllegalStateException; /** * Generates the shared secret, and places it into the buffer * sharedSecret, beginning at offset inclusive. *

    * If the sharedSecret buffer is too small to hold the result, * a ShortBufferException is thrown. In this case, this call should be * repeated with a larger output buffer. *

    * This method resets this KeyAgreementSpi object, so that it * can be reused for further key agreements. Unless this key agreement is * reinitialized with one of the engineInit methods, the same * private information and algorithm parameters will be used for subsequent key agreements. * * @param sharedSecret the buffer for the shared secret * @param offset the offset in sharedSecret where the shared secret will be stored * @return the number of bytes placed into sharedSecret * @exception IllegalStateException if this key agreement has not been completed yet * @exception ShortBufferException if the given output buffer is too small to hold the secret */ protected abstract int engineGenerateSecret( byte[] sharedSecret, int offset) throws IllegalStateException, ShortBufferException; /** * Creates the shared secret and returns it as a secret key object * of the requested algorithm type. *

    * This method resets this KeyAgreementSpi object, so that it * can be reused for further key agreements. Unless this key agreement is * reinitialized with one of the engineInit methods, the same * private information and algorithm parameters will be used for * subsequent key agreements. * * @param algorithm the requested secret key algorithm * @return the shared secret key * @exception IllegalStateException if this key agreement has not been completed yet * @exception NoSuchAlgorithmException if the requested secret key algorithm is not available * @exception InvalidKeyException if the shared secret key material cannot be used to generate * a secret key of the requested algorithm type (e.g., the key material is too short) */ protected abstract SecretKey engineGenerateSecret( String algorithm) throws IllegalStateException, NoSuchAlgorithmException, InvalidKeyException; } bouncycastle-1.49.orig/jce/src/javax/crypto/CipherOutputStream.java0000644000175000017500000001272210445172704025074 0ustar ebourgebourgpackage javax.crypto; import java.io.OutputStream; import java.io.IOException; import java.io.FilterOutputStream; /** * A CipherOutputStream is composed of an OutputStream and a Cipher so * that write() methods first process the data before writing them out * to the underlying OutputStream. The cipher must be fully * initialized before being used by a CipherOutputStream. *

    * For example, if the cipher is initialized for encryption, the * CipherOutputStream will attempt to encrypt data before writing out the * encrypted data. *

    * This class adheres strictly to the semantics, especially the * failure semantics, of its ancestor classes * java.io.OutputStream and java.io.FilterOutputStream. This class * has exactly those methods specified in its ancestor classes, and * overrides them all. Moreover, this class catches all exceptions * that are not thrown by its ancestor classes. *

    * It is crucial for a programmer using this class not to use * methods that are not defined or overriden in this class (such as a * new method or constructor that is later added to one of the super * classes), because the design and implementation of those methods * are unlikely to have considered security impact with regard to * CipherOutputStream. * * @since JCE1.2 * @see OutputStream * @see FilterOutputStream * @see Cipher * @see CipherInputStream */ public class CipherOutputStream extends FilterOutputStream { private Cipher c; private byte[] oneByte = new byte[1]; /** * Constructs a CipherOutputStream from an OutputStream and a * Cipher. */ public CipherOutputStream( OutputStream os, Cipher c) { super(os); this.c = c; } /** * Constructs a CipherOutputStream from an OutputStream without * specifying a Cipher. This has the effect of constructing a * CipherOutputStream using a NullCipher. */ protected CipherOutputStream( OutputStream os) { this(os, new NullCipher()); } /** * Writes the specified byte to this output stream. * * @param b the byte. * @exception IOException if an I/O error occurs. * @since JCE1.2 */ public void write( int b) throws IOException { oneByte[0] = (byte)b; byte[] bytes = c.update(oneByte, 0, 1); if (bytes != null) { out.write(bytes, 0, bytes.length); } } /** * Writes b.length bytes from the specified byte array * to this output stream. *

    * The write method of * CipherOutputStream calls the write * method of three arguments with the three arguments * b, 0, and b.length. * * @param b the data. * @exception IOException if an I/O error occurs. * @since JCE1.2 * @see #write(byte[], int, int) */ public void write( byte[] b) throws IOException { write(b, 0, b.length); } /** * Writes len bytes from the specified byte array * starting at offset off to this output stream. * * @param b the data. * @param off the start offset in the data. * @param len the number of bytes to write. * @exception IOException if an I/O error occurs. * @since JCE1.2 */ public void write( byte[] b, int off, int len) throws IOException { byte[] bytes = c.update(b, off, len); if (bytes != null) { out.write(bytes, 0, bytes.length); } } /** * Flushes this output stream by forcing any buffered output bytes * that have already been processed by the encapsulated cipher object * to be written out. * *

    * Any bytes buffered by the encapsulated cipher * and waiting to be processed by it will not be written out. For example, * if the encapsulated cipher is a block cipher, and the total number of * bytes written using one of the write methods is less than * the cipher's block size, no bytes will be written out. * * @exception IOException if an I/O error occurs. * @since JCE1.2 */ public void flush() throws IOException { super.flush(); } /** * Closes this output stream and releases any system resources * associated with this stream. *

    * This method invokes the doFinal method of the encapsulated * cipher object, which causes any bytes buffered by the encapsulated * cipher to be processed. The result is written out by calling the * flush method of this output stream. *

    * This method resets the encapsulated cipher object to its initial state * and calls the close method of the underlying output * stream. * * @exception IOException if an I/O error occurs. * @since JCE1.2 */ public void close() throws IOException { try { byte[] bytes = c.doFinal(); if (bytes != null) { out.write(bytes, 0, bytes.length); } } catch (Exception e) { throw new IOException("Error closing stream: " + e.toString()); } flush(); super.close(); } } bouncycastle-1.49.orig/jce/src/javax/crypto/SealedObject.java0000644000175000017500000002431610757410275023617 0ustar ebourgebourgpackage javax.crypto; import java.io.*; import java.security.*; /** * This class enables a programmer to create an object and protect its * confidentiality with a cryptographic algorithm. * *

    * Given any Serializable object, one can create a SealedObject * that encapsulates the original object, in serialized * format (i.e., a "deep copy"), and seals (encrypts) its serialized contents, * using a cryptographic algorithm such as DES, to protect its * confidentiality. The encrypted content can later be decrypted (with * the corresponding algorithm using the correct decryption key) and * de-serialized, yielding the original object. * *

    * Note that the Cipher object must be fully initialized with the * correct algorithm, key, padding scheme, etc., before being applied * to a SealedObject. * *

    * The original object that was sealed can be recovered in two different * ways: *

    * *

      * *
    • by using the getObject * method that takes a Cipher object. * *

      * This method requires a fully initialized Cipher object, * initialized with the * exact same algorithm, key, padding scheme, etc., that were used to seal the * object. * *

      * This approach has the advantage that the party who unseals the * sealed object does not require knowledge of the decryption key. For example, * after one party has initialized the cipher object with the required * decryption key, it could hand over the cipher object to * another party who then unseals the sealed object. * *

      * *

    • by using one of the * getObject methods * that take a Key object. * *

      In this approach, the getObject method creates a cipher * object for the appropriate decryption algorithm and initializes it with the * given decryption key and the algorithm parameters (if any) that were stored * in the sealed object. * *

      This approach has the advantage that the party who * unseals the object does not need to keep track of the parameters (e.g., an * IV) that were used to seal the object. * *

    * * @see Cipher */ public class SealedObject implements Serializable { private static final long serialVersionUID = 4482838265551344752L; private byte[] encodedParams; private byte[] encryptedContent; private String paramsAlg; private String sealAlg; /** * Constructs a SealedObject from any Serializable object. *

    * The given object is serialized, and its serialized contents are * encrypted using the given Cipher, which must be fully initialized. *

    * Any algorithm parameters that may be used in the encryption * operation are stored inside of the new SealedObject. * * @param object the object to be sealed. * @param c the cipher used to seal the object. * @exception IOException if an error occurs during serialization * @exception IllegalBlockSizeException if the given cipher is a block * cipher, no padding has been requested, and the total input length * (i.e., the length of the serialized object contents) is not a multiple * of the cipher's block size */ public SealedObject( Serializable object, Cipher c) throws IOException, IllegalBlockSizeException { ByteArrayOutputStream bOut = new ByteArrayOutputStream(); ObjectOutputStream oOut = new ObjectOutputStream(bOut); oOut.writeObject(object); oOut.close(); byte[] encodedObject = bOut.toByteArray(); if (c == null) { throw new IllegalArgumentException("cipher object is null!"); } try { this.encryptedContent = c.doFinal(encodedObject); } catch (BadPaddingException e) { // should not happen throw new IOException(e.getMessage()); } this.sealAlg = c.getAlgorithm(); AlgorithmParameters params = c.getParameters(); if (params != null) { this.encodedParams = params.getEncoded(); this.paramsAlg = params.getAlgorithm(); } } /** * Returns the algorithm that was used to seal this object. * * @return the algorithm that was used to seal this object. */ public final String getAlgorithm() { return sealAlg; } /** * Retrieves the original (encapsulated) object. *

    * This method creates a cipher for the algorithm that had been used in * the sealing operation. * If the default provider package provides an implementation of that * algorithm, an instance of Cipher containing that implementation is used. * If the algorithm is not available in the default package, other * packages are searched. * The Cipher object is initialized for decryption, using the given * key and the parameters (if any) that had been used in the * sealing operation. *

    * The encapsulated object is unsealed and de-serialized, before it is * returned. * * @param key the key used to unseal the object. * @return the original object. * @exception IOException if an error occurs during de-serialiazation. * @exception ClassNotFoundException if an error occurs during de-serialiazation. * @exception NoSuchAlgorithmException if the algorithm to unseal the object is not available. * @exception InvalidKeyException if the given key cannot be used to unseal * the object (e.g., it has the wrong algorithm). */ public final Object getObject( Key key) throws IOException, ClassNotFoundException, NoSuchAlgorithmException, InvalidKeyException { if (key == null) { throw new IllegalArgumentException("key object is null!"); } try { return getObject(key, null); } catch (NoSuchProviderException e) { throw new NoSuchAlgorithmException(e.getMessage()); } } /** * Retrieves the original (encapsulated) object. *

    * The encapsulated object is unsealed (using the given Cipher, * assuming that the Cipher is already properly initialized) and * de-serialized, before it is returned. * * @param c the cipher used to unseal the object * @return the original object. * @exception IOException if an error occurs during de-serialiazation * @exception ClassNotFoundException if an error occurs during de-serialiazation * @exception IllegalBlockSizeException if the given cipher is a block * cipher, no padding has been requested, and the total input length is * not a multiple of the cipher's block size * @exception BadPaddingException if the given cipher has been * initialized for decryption, and padding has been specified, but * the input data does not have proper expected padding bytes */ public final Object getObject( Cipher c) throws IOException, ClassNotFoundException, IllegalBlockSizeException, BadPaddingException { if (c == null) { throw new IllegalArgumentException("cipher object is null!"); } byte[] encodedObject = c.doFinal(encryptedContent); ObjectInputStream oIn = new ObjectInputStream( new ByteArrayInputStream(encodedObject)); return oIn.readObject(); } /** * Retrieves the original (encapsulated) object. *

    * This method creates a cipher for the algorithm that had been used in * the sealing operation, using an implementation of that algorithm from * the given provider. * The Cipher object is initialized for decryption, using the given * key and the parameters (if any) that had been used in the * sealing operation. *

    * The encapsulated object is unsealed and de-serialized, before it is * returned. * * @param key the key used to unseal the object. * @param provider the name of the provider of the algorithm to unseal * the object. * @return the original object. * @exception IOException if an error occurs during de-serialiazation. * @exception ClassNotFoundException if an error occurs during * de-serialization. * @exception NoSuchAlgorithmException if the algorithm to unseal the * object is not available. * @exception NoSuchProviderException if the given provider is not * configured. * @exception InvalidKeyException if the given key cannot be used to unseal * the object (e.g., it has the wrong algorithm). */ public final Object getObject( Key key, String provider) throws IOException, ClassNotFoundException, NoSuchAlgorithmException, NoSuchProviderException, InvalidKeyException { if (key == null) { throw new IllegalArgumentException("key object is null!"); } Cipher cipher = null; try { if (provider != null) { cipher = Cipher.getInstance(sealAlg, provider); } else { cipher = Cipher.getInstance(sealAlg); } } catch (NoSuchPaddingException e) { throw new NoSuchAlgorithmException(e.getMessage()); } if (paramsAlg == null) { cipher.init(Cipher.DECRYPT_MODE, key); } else { AlgorithmParameters algParams = AlgorithmParameters.getInstance(paramsAlg); algParams.init(encodedParams); try { cipher.init(Cipher.DECRYPT_MODE, key, algParams); } catch (InvalidAlgorithmParameterException e) { throw new IOException(e.getMessage()); } } try { return getObject(cipher); } catch (BadPaddingException e) { throw new IOException(e.getMessage()); } catch (IllegalBlockSizeException e2) { throw new IOException(e2.getMessage()); } } } bouncycastle-1.49.orig/jce/src/javax/crypto/spec/0000755000175000017500000000000012152033546021345 5ustar ebourgebourgbouncycastle-1.49.orig/jce/src/javax/crypto/spec/PBEParameterSpec.java0000644000175000017500000000240310445172704025274 0ustar ebourgebourgpackage javax.crypto.spec; import java.security.spec.AlgorithmParameterSpec; /** * This class specifies the set of parameters used with password-based encryption (PBE), as defined in the * PKCS #5 standard. */ public class PBEParameterSpec implements AlgorithmParameterSpec { private byte[] salt; private int iterationCount; /** * Constructs a parameter set for password-based encryption as defined in * the PKCS #5 standard. * * @param salt the salt. * @param iterationCount the iteration count. */ public PBEParameterSpec( byte[] salt, int iterationCount) { this.salt = new byte[salt.length]; System.arraycopy(salt, 0, this.salt, 0, salt.length); this.iterationCount = iterationCount; } /** * Returns the salt. * * @return the salt */ public byte[] getSalt() { byte[] tmp = new byte[salt.length]; System.arraycopy(salt, 0, tmp, 0, salt.length); return tmp; } /** * Returns the iteration count. * * @return the iteration count */ public int getIterationCount() { return iterationCount; } } bouncycastle-1.49.orig/jce/src/javax/crypto/spec/DHGenParameterSpec.java0000644000175000017500000000326110445172704025616 0ustar ebourgebourgpackage javax.crypto.spec; import java.security.spec.AlgorithmParameterSpec; /** * This class specifies the set of parameters used for generating * Diffie-Hellman (system) parameters for use in Diffie-Hellman key * agreement. This is typically done by a central * authority. *

    * The central authority, after computing the parameters, must send this * information to the parties looking to agree on a secret key. */ public class DHGenParameterSpec implements AlgorithmParameterSpec { private int primeSize; private int exponentSize; /** * Constructs a parameter set for the generation of Diffie-Hellman * (system) parameters. The constructed parameter set can be used to * initialize an AlgorithmParameterGenerator * object for the generation of Diffie-Hellman parameters. * * @param primeSize the size (in bits) of the prime modulus. * @param exponentSize the size (in bits) of the random exponent. */ public DHGenParameterSpec( int primeSize, int exponentSize) { this.primeSize = primeSize; this.exponentSize = exponentSize; } /** * Returns the size in bits of the prime modulus. * * @return the size in bits of the prime modulus */ public int getPrimeSize() { return primeSize; } /** * Returns the size in bits of the random exponent (private value). * * @return the size in bits of the random exponent (private value) */ public int getExponentSize() { return exponentSize; } } bouncycastle-1.49.orig/jce/src/javax/crypto/spec/PBEKeySpec.java0000644000175000017500000001500611130651750024102 0ustar ebourgebourgpackage javax.crypto.spec; import java.security.spec.KeySpec; import javax.crypto.SecretKeyFactory; /** * A user-chosen password that can be used with password-based encryption (PBE). *

    * The password can be viewed as some kind of raw key material, from which the * encryption mechanism that uses it derives a cryptographic key. *

    * Different PBE mechanisms may consume different bits of each password * character. For example, the PBE mechanism defined in PKCS #5 looks at only * the low order 8 bits of each character, whereas PKCS #12 looks at all 16 bits * of each character. *

    * You convert the password characters to a PBE key by creating an instance of * the appropriate secret-key factory. For example, a secret-key factory for * PKCS #5 will construct a PBE key from only the low order 8 bits of each * password character, whereas a secret-key factory for PKCS #12 will take all * 16 bits of each character. *

    * Also note that this class stores passwords as char arrays instead of String * objects (which would seem more logical), because the String class is * immutable and there is no way to overwrite its internal value when the * password stored in it is no longer needed. Hence, this class requests the * password as a char array, so it can be overwritten when done. * * @see SecretKeyFactory * @see PBEParameterSpec */ public class PBEKeySpec implements KeySpec { private char[] password; private byte[] salt; private int iterationCount; private int keyLength; private boolean isPasswordCleared; /** * Constructor that takes a password. An empty char[] is used if null is * specified. *

    * Note: password is cloned before it is stored in the new PBEKeySpec * object. * * @param password - * the password. */ public PBEKeySpec(char[] password) { if (password == null) { this.password = new char[0]; } else { this.password = new char[password.length]; System.arraycopy(password, 0, this.password, 0, password.length); } } /** * Returns a copy of the password. *

    * Note: this method returns a copy of the password. It is the caller's * responsibility to zero out the password information after it is no longer * needed. * * @return the password * @throws IllegalStateException - * if password has been cleared by calling clearPassword method. */ public final char[] getPassword() { if (isPasswordCleared) { throw new IllegalStateException("Password has been cleared"); } return password; } /** * Constructor that takes a password, salt, iteration count, and * to-be-derived key length for generating PBEKey of variable-key-size PBE * ciphers. An empty char[] is used if null is specified for password. *

    * Note: the password and salt are cloned before they are stored in the new * PBEKeySpec object. * * * @param password * password - the password. * @param salt * salt - the salt. * @param iterationCount * iterationCount - the iteration count. * @param keyLength * keyLength - the to-be-derived key length. * @throws NullPointerException - * if salt is null. * @throws IllegalArgumentException - * if salt is empty, i.e. 0-length, iterationCount or keyLength * is not positive. */ public PBEKeySpec(char[] password, byte[] salt, int iterationCount, int keyLength) { this(password); if (salt == null) { throw new NullPointerException("salt is null"); } if (salt.length == 0) { throw new IllegalArgumentException("salt is empty"); } if (iterationCount < 0) { throw new IllegalArgumentException("iterationCount is not positive"); } if (keyLength < 0) { throw new IllegalArgumentException("keyLength is not positive"); } this.keyLength = keyLength; this.iterationCount = iterationCount; this.salt = (byte[]) salt.clone(); } /** * Constructor that takes a password, salt, iteration count for generating * PBEKey of fixed-key-size PBE ciphers. An empty char[] is used if null is * specified for password. *

    * Note: the password and salt are cloned before they are stored in the new * PBEKeySpec object. * * @param password - * the password. * @param salt - * the salt. * @param iterationCount - * the iteration count. * @throws NullPointerException - * if salt is null. * @throws IllegalArgumentException - * if salt is empty, i.e. 0-length, or iterationCount is not * positive. */ public PBEKeySpec(char[] password, byte[] salt, int iterationCount) { this(password, salt, iterationCount, 0); } /** * Clears the internal copy of the password. */ public final void clearPassword() { for (int i = 0; i < password.length; i++) { password[i] = 0; } password = null; isPasswordCleared = true; } /** * Returns a copy of the salt or null if not specified. * * Note: this method should return a copy of the salt. It is the caller's * responsibility to zero out the salt information after it is no longer * needed. * * @return the salt. */ public final byte[] getSalt() { if (salt != null) { byte[] tmp = new byte[salt.length]; System.arraycopy(salt, 0, tmp, 0, salt.length); return tmp; } return null; } /** * Returns the iteration count or 0 if not specified. * * @return the iteration count. */ public final int getIterationCount() { return iterationCount; } /** * Returns the to-be-derived key length or 0 if not specified. *

    * Note: this is used to indicate the preference on key length for * variable-key-size ciphers. The actual key size depends on each provider's * implementation. * * @return the to-be-derived key length. */ public final int getKeyLength() { return keyLength; } } bouncycastle-1.49.orig/jce/src/javax/crypto/spec/PSource.java0000644000175000017500000000505310757413045023600 0ustar ebourgebourgpackage javax.crypto.spec; /** * This class specifies the source for encoding input P in OAEP Padding, as * defined in the {@link http://www.ietf.org/rfc/rfc3447.txt PKCS #1} standard. * *

     *  
     *  PKCS1PSourceAlgorithms    ALGORITHM-IDENTIFIER ::= {
     *  { OID id-pSpecified PARAMETERS OCTET STRING },
     *  ...  -- Allows for future expansion --
     *  }
     * 
    */ public class PSource { /** * This class is used to explicitly specify the value for encoding input P * in OAEP Padding. * */ public final static class PSpecified extends PSource { private byte[] p; /** * The encoding input P whose value equals byte[0]. */ public static final PSpecified DEFAULT = new PSpecified(new byte[0]); /** * Constructs the source explicitly with the specified value p as the * encoding input P. * * @param p the value of the encoding input. The contents of the array * are copied to protect against subsequent modification. * @throws NullPointerException if p is null. */ public PSpecified(byte[] p) { super("PSpecified"); if (p == null) { throw new NullPointerException("The encoding input is null"); } this.p = copyOf(p); } /** * Returns the value of encoding input P. * * @return the value of encoding input P. A new array is returned each * time this method is called. */ public byte[] getValue() { return copyOf(p); } private byte[] copyOf(byte[] b) { byte[] tmp = new byte[b.length]; System.arraycopy(b, 0, tmp, 0, b.length); return tmp; } } private String pSrcName; /** * Constructs a source of the encoding input P for OAEP padding as defined * in the PKCS #1 standard using the specified PSource algorithm. * * @param pSrcName the algorithm for the source of the encoding input P. * @throws NullPointerException if pSrcName is null. */ protected PSource(String pSrcName) { if (pSrcName == null) { throw new NullPointerException("pSrcName is null"); } this.pSrcName = pSrcName; } /** * Returns the PSource algorithm name. * * @return the PSource algorithm name. */ public String getAlgorithm() { return pSrcName; } } bouncycastle-1.49.orig/jce/src/javax/crypto/spec/DHPublicKeySpec.java0000644000175000017500000000227510445172704025137 0ustar ebourgebourgpackage javax.crypto.spec; import java.math.BigInteger; import java.security.spec.KeySpec; /** * This class specifies a Diffie-Hellman public key with its associated parameters. * * @see DHPrivateKeySpec */ public class DHPublicKeySpec implements KeySpec { private BigInteger y; private BigInteger p; private BigInteger g; /** * Constructor that takes a public value y, a prime * modulus p, and a base generator g. */ public DHPublicKeySpec( BigInteger y, BigInteger p, BigInteger g) { this.y = y; this.p = p; this.g = g; } /** * Returns the public value y. * * @return the public value y */ public BigInteger getY() { return y; } /** * Returns the prime modulus p. * * @return the prime modulus p */ public BigInteger getP() { return p; } /** * Returns the base generator g. * * @return the base generator g */ public BigInteger getG() { return g; } } bouncycastle-1.49.orig/jce/src/javax/crypto/spec/DESedeKeySpec.java0000644000175000017500000000601710445172704024574 0ustar ebourgebourgpackage javax.crypto.spec; import java.security.InvalidKeyException; import java.security.spec.KeySpec; /** * This class specifies a DES-EDE ("triple-DES") key. */ public class DESedeKeySpec implements KeySpec { public static final int DES_EDE_KEY_LEN = 24; private byte[] keyBytes = new byte[DES_EDE_KEY_LEN]; /** * Uses the first 24 bytes in key as the DES-EDE key. *

    * The bytes that constitute the DES-EDE key are those between * key[0] and key[23] inclusive * * @param key the buffer with the DES-EDE key material. * @exception InvalidKeyException if the given key material is shorter * than 24 bytes. */ public DESedeKeySpec( byte[] key) throws InvalidKeyException { if (key.length < DES_EDE_KEY_LEN) { throw new InvalidKeyException("DESede key material too short in construction"); } System.arraycopy(key, 0, keyBytes, 0, keyBytes.length); } /** * Uses the first 24 bytes in key, beginning at * offset inclusive, as the DES-EDE key. *

    * The bytes that constitute the DES-EDE key are those between * key[offset] and key[offset+23] inclusive. * @param key the buffer with the DES-EDE key material. * @param offset the offset in key, where the DES-EDE key * material starts. * @exception InvalidKeyException if the given key material, starting at * offset inclusive, is shorter than 24 bytes */ public DESedeKeySpec( byte[] key, int offset) throws InvalidKeyException { if ((key.length - offset) < DES_EDE_KEY_LEN) { throw new InvalidKeyException("DESede key material too short in construction"); } System.arraycopy(key, 0, keyBytes, 0, keyBytes.length); } /** * Returns the DES-EDE key. * * @return the DES-EDE key */ public byte[] getKey() { byte[] tmp = new byte[DES_EDE_KEY_LEN]; System.arraycopy(keyBytes, 0, tmp, 0, tmp.length); return tmp; } /** * Checks if the given DES-EDE key, starting at offset * inclusive, is parity-adjusted. * * @return true if the given DES-EDE key is parity-adjusted, false * otherwise * @exception InvalidKeyException if the given key material, starting at * offset inclusive, is shorter than 24 bytes */ public static boolean isParityAdjusted( byte[] key, int offset) throws InvalidKeyException { if ((key.length - offset) < DES_EDE_KEY_LEN) { throw new InvalidKeyException("key material too short in DESedeKeySpec.isParityAdjusted"); } return (DESKeySpec.isParityAdjusted(key, offset) && DESKeySpec.isParityAdjusted(key, offset + 8) && DESKeySpec.isParityAdjusted(key, offset + 16)); } } bouncycastle-1.49.orig/jce/src/javax/crypto/spec/SecretKeySpec.java0000644000175000017500000001313510757412436024734 0ustar ebourgebourgpackage javax.crypto.spec; import javax.crypto.SecretKey; import java.security.spec.KeySpec; /** * This class specifies a secret key in a provider-independent fashion. *

    * It can be used to construct a SecretKey from a byte array, * without having to go through a (provider-based) * SecretKeyFactory. *

    * This class is only useful for raw secret keys that can be represented as * a byte array and have no key parameters associated with them, e.g., DES or * Triple DES keys. * * @see SecretKey * @see javax.crypto.SecretKeyFactory */ public class SecretKeySpec implements KeySpec, SecretKey { private static final long serialVersionUID = 6577238317307289933L; private String algorithm; private byte[] key; /** * Constructs a secret key from the given byte array. *

    * This constructor does not check if the given bytes indeed specify a * secret key of the specified algorithm. For example, if the algorithm is * DES, this constructor does not check if key is 8 bytes * long, and also does not check for weak or semi-weak keys. * In order for those checks to be performed, an algorithm-specific * key specification class (in this case: * DESKeySpec) * should be used. * * @param key the key material of the secret key. * @param algorithm the name of the secret-key algorithm to be associated * See Appendix A in the Java Cryptography Extension API Specification & Reference * for information about standard algorithm names. */ public SecretKeySpec( byte[] key, String algorithm) { if (key == null) { throw new IllegalArgumentException("null key passed"); } if (algorithm == null) { throw new IllegalArgumentException("null algorithm passed"); } this.key = new byte[key.length]; System.arraycopy(key, 0, this.key, 0, key.length); this.algorithm = algorithm; } /** * Constructs a secret key from the given byte array, using the first * len bytes of key, starting at * offset inclusive. *

    * The bytes that constitute the secret key are those between key[offset] and * key[offset+len-1] inclusive. *

    * This constructor does not check if the given bytes indeed specify a * secret key of the specified algorithm. For example, if the algorithm is * DES, this constructor does not check if key is 8 bytes * long, and also does not check for weak or semi-weak keys. * In order for those checks to be performed, an algorithm-specific key * specification class (in this case: DESKeySpec) * must be used. * * @param key the key material of the secret key. * @param offset the offset in key where the key material starts. * @param len the length of the key material. * @param algorithm the name of the secret-key algorithm to be associated * with the given key material. See Appendix A in the Java Cryptography Extension API * Specification & Reference for information about standard algorithm names. */ public SecretKeySpec( byte[] key, int offset, int len, String algorithm) { if (key == null) { throw new IllegalArgumentException("Null key passed"); } if ((key.length - offset) < len) { throw new IllegalArgumentException("Bad offset/len"); } if (algorithm == null) { throw new IllegalArgumentException("Null algorithm string passed"); } this.key = new byte[len]; System.arraycopy(key, offset, this.key, 0, len); this.algorithm = algorithm; } /** * Returns the name of the algorithm associated with this secret key. * * @return the secret key algorithm. */ public String getAlgorithm() { return algorithm; } /** * Returns the name of the encoding format for this secret key. * * @return the string "RAW". */ public java.lang.String getFormat() { return "RAW"; } /** * Returns the key material of this secret key. * * @return the key material */ public byte[] getEncoded() { byte[] tmp = new byte[key.length]; System.arraycopy(key, 0, tmp, 0, tmp.length); return tmp; } /** * Calculates a hash code value for the object. * Objects that are equal will also have the same hashcode. */ public int hashCode() { int code = algorithm.toUpperCase().hashCode(); for (int i = 0; i != this.key.length; i++) { code ^= this.key[i] << (8 * (i % 4)); } return code; } public boolean equals( Object obj) { if ((obj == null) || !(obj instanceof SecretKeySpec)) { return false; } SecretKeySpec spec = (SecretKeySpec)obj; if (!this.algorithm.equalsIgnoreCase(spec.algorithm)) { return false; } if (this.key.length != spec.key.length) { return false; } for (int i = 0; i != this.key.length; i++) { if (this.key[i] != spec.key[i]) { return false; } } return true; } } bouncycastle-1.49.orig/jce/src/javax/crypto/spec/RC5ParameterSpec.java0000644000175000017500000001333710445172704025267 0ustar ebourgebourgpackage javax.crypto.spec; import java.security.spec.AlgorithmParameterSpec; /** * This class specifies the parameters used with the * RC5 * algorithm. *

    * The parameters consist of a version number, a rounds count, a word * size, and optionally an initialization vector (IV) (only in feedback mode). *

    * This class can be used to initialize a Cipher object that * implements the RC5 algorithm as supplied by * RSA Data Security, Inc. (RSA DSI), * or any parties authorized by RSA DSI. */ public class RC5ParameterSpec implements AlgorithmParameterSpec { private int version; private int rounds; private int wordSize; private byte[] iv; /** * Constructs a parameter set for RC5 from the given version, number of * rounds and word size (in bits). * * @param version the version. * @param rounds the number of rounds. * @param wordSize the word size in bits. */ public RC5ParameterSpec( int version, int rounds, int wordSize) { this.version = version; this.rounds = rounds; this.wordSize = wordSize; this.iv = null; } /** * Constructs a parameter set for RC5 from the given version, number of * rounds, word size (in bits), and IV. *

    * Note that the size of the IV (block size) must be twice the word * size. The bytes that constitute the IV are those between * iv[0] and iv[2*(wordSize/8)-1] inclusive. * * @param version the version. * @param rounds the number of rounds. * @param wordSize the word size in bits. * @param iv the buffer with the IV. */ public RC5ParameterSpec( int version, int rounds, int wordSize, byte[] iv) { this(version, rounds, wordSize, iv, 0); } /** * Constructs a parameter set for RC5 from the given version, number of * rounds, word size (in bits), and IV. *

    * The IV is taken from iv, starting at offset inclusive. * Note that the size of the IV (block size), starting at * offset inclusive, must be twice the word size. * The bytes that constitute the IV are those between * iv[offset] and iv[offset+2*(wordSize/8)-1] * inclusive. * * @param version the version. * @param rounds the number of rounds. * @param wordSize the word size in bits. * @param iv the buffer with the IV. * @param offset the offset in iv where the IV starts. */ public RC5ParameterSpec( int version, int rounds, int wordSize, byte[] iv, int offset) { this.version = version; this.rounds = rounds; this.wordSize = wordSize; this.iv = new byte[2 * (wordSize / 8)]; System.arraycopy(iv, offset, this.iv, 0, this.iv.length); } /** * Returns the version. * * @return the version. */ public int getVersion() { return version; } /** * Returns the number of rounds. * * @return the number of rounds. */ public int getRounds() { return rounds; } /** * Returns the word size in bits * * @return the word size in bits. */ public int getWordSize() { return wordSize; } /** * Returns the IV or null if this parameter set does not contain an IV. * * @return the IV or null if this parameter set does not contain an IV. */ public byte[] getIV() { if (iv == null) { return null; } byte[] tmp = new byte[iv.length]; System.arraycopy(iv, 0, tmp, 0, iv.length); return tmp; } /** * Tests for equality between the specified object and this * object. Two RC5ParameterSpec objects are considered equal if their * version numbers, number of rounds, word sizes, and IVs are equal. * (Two IV references are considered equal if both are null.) * * @param obj the object to test for equality with this object. * @return true if the objects are considered equal, false otherwise. */ public boolean equals( Object obj) { if ((obj == null) || !(obj instanceof RC5ParameterSpec)) { return false; } RC5ParameterSpec spec = (RC5ParameterSpec)obj; if (this.version != spec.version) { return false; } if (this.rounds != spec.rounds) { return false; } if (this.wordSize != spec.wordSize) { return false; } if (iv != null) { if (spec.iv == null || spec.iv.length != iv.length) { return false; } for (int i = 0; i != iv.length; i++) { if (iv[i] != spec.iv[i]) { return false; } } } else if (spec.iv != null) { return false; } return true; } /** * Calculates a hash code value for the object. * Objects that are equal will also have the same hashcode. */ public int hashCode() { int code = version ^ rounds ^ wordSize; if (iv != null) { for (int i = 0; i != iv.length; i++) { code ^= iv[i] << (8 * (i % 4)); } } return code; } } bouncycastle-1.49.orig/jce/src/javax/crypto/spec/DESKeySpec.java0000644000175000017500000001514611130654231024111 0ustar ebourgebourgpackage javax.crypto.spec; import java.security.InvalidKeyException; import java.security.spec.KeySpec; /** * This class specifies a DES key. */ public class DESKeySpec implements KeySpec { public static final int DES_KEY_LEN = 8; private byte[] keyBytes = new byte[DES_KEY_LEN]; /** * Uses the first 8 bytes in key as the key material for the DES key. *

    * The bytes that constitute the DES key are those between * key[0] and key[7] inclusive. * * @param key - the buffer with the DES key material. * @exception InvalidKeyException - if the given key material is shorter than 8 bytes. */ public DESKeySpec( byte[] key) throws InvalidKeyException { if (key.length < DES_KEY_LEN) { throw new InvalidKeyException("DES key material too short in construction"); } System.arraycopy(key, 0, keyBytes, 0, keyBytes.length); } /** * Uses the first 8 bytes in key, beginning at * offset inclusive, as the key material for the DES key. *

    * The bytes that constitute the DES key are those between * key[offset] and key[offset+7] inclusive. * * @param key the buffer with the DES key material. * @param offset the offset in key, where the DES key material starts. * @exception InvalidKeyException if the given key material, starting at * offset inclusive, is shorter than 8 bytes. */ public DESKeySpec( byte[] key, int offset) throws InvalidKeyException { if ((key.length - offset) < DES_KEY_LEN) { throw new InvalidKeyException("DES key material too short in construction"); } System.arraycopy(key, offset, keyBytes, 0, keyBytes.length); } /** * Returns the DES key material. * * @return the DES key material. */ public byte[] getKey() { byte[] tmp = new byte[DES_KEY_LEN]; System.arraycopy(keyBytes, 0, tmp, 0, tmp.length); return tmp; } /** * Checks if the given DES key material, starting at offset * inclusive, is parity-adjusted. * * @param key the buffer with the DES key material. * @param offset the offset in key, where the DES key material starts. * @returns true if the given DES key material is parity-adjusted, false otherwise. * @exception InvalidKeyException if the given key material, starting at offset * inclusive, is shorter than 8 bytes. */ public static boolean isParityAdjusted( byte[] key, int offset) throws InvalidKeyException { if ((key.length - offset) < DES_KEY_LEN) { throw new InvalidKeyException("key material too short in DESKeySpec.isParityAdjusted"); } for (int i = 0; i < DES_KEY_LEN; i++) { byte keyByte = key[i + offset]; int count = 0; keyByte = (byte)((keyByte & 0xff) >> 1); while (keyByte != 0) { /* * we increment for every "on" bit */ if ((keyByte & 0x01) != 0) { count++; } keyByte = (byte)((keyByte & 0xff) >> 1); } if ((count & 1) == 1) { if ((key[i + offset] & 1) == 1) { return false; } } else if ((key[i + offset] & 1) != 1) { return false; } } return true; } /* * Table of weak and semi-weak keys taken from Schneier pp281 */ static private final int N_DES_WEAK_KEYS = 16; static private byte[] DES_weak_keys = { /* weak keys */ (byte)0x01,(byte)0x01,(byte)0x01,(byte)0x01, (byte)0x01,(byte)0x01,(byte)0x01,(byte)0x01, (byte)0x1f,(byte)0x1f,(byte)0x1f,(byte)0x1f, (byte)0x0e,(byte)0x0e,(byte)0x0e,(byte)0x0e, (byte)0xe0,(byte)0xe0,(byte)0xe0,(byte)0xe0, (byte)0xf1,(byte)0xf1,(byte)0xf1,(byte)0xf1, (byte)0xfe,(byte)0xfe,(byte)0xfe,(byte)0xfe, (byte)0xfe,(byte)0xfe,(byte)0xfe,(byte)0xfe, /* semi-weak keys */ (byte)0x01,(byte)0xfe,(byte)0x01,(byte)0xfe, (byte)0x01,(byte)0xfe,(byte)0x01,(byte)0xfe, (byte)0x1f,(byte)0xe0,(byte)0x1f,(byte)0xe0, (byte)0x0e,(byte)0xf1,(byte)0x0e,(byte)0xf1, (byte)0x01,(byte)0xe0,(byte)0x01,(byte)0xe0, (byte)0x01,(byte)0xf1,(byte)0x01,(byte)0xf1, (byte)0x1f,(byte)0xfe,(byte)0x1f,(byte)0xfe, (byte)0x0e,(byte)0xfe,(byte)0x0e,(byte)0xfe, (byte)0x01,(byte)0x1f,(byte)0x01,(byte)0x1f, (byte)0x01,(byte)0x0e,(byte)0x01,(byte)0x0e, (byte)0xe0,(byte)0xfe,(byte)0xe0,(byte)0xfe, (byte)0xf1,(byte)0xfe,(byte)0xf1,(byte)0xfe, (byte)0xfe,(byte)0x01,(byte)0xfe,(byte)0x01, (byte)0xfe,(byte)0x01,(byte)0xfe,(byte)0x01, (byte)0xe0,(byte)0x1f,(byte)0xe0,(byte)0x1f, (byte)0xf1,(byte)0x0e,(byte)0xf1,(byte)0x0e, (byte)0xe0,(byte)0x01,(byte)0xe0,(byte)0x01, (byte)0xf1,(byte)0x01,(byte)0xf1,(byte)0x01, (byte)0xfe,(byte)0x1f,(byte)0xfe,(byte)0x1f, (byte)0xfe,(byte)0x0e,(byte)0xfe,(byte)0x0e, (byte)0x1f,(byte)0x01,(byte)0x1f,(byte)0x01, (byte)0x0e,(byte)0x01,(byte)0x0e,(byte)0x01, (byte)0xfe,(byte)0xe0,(byte)0xfe,(byte)0xe0, (byte)0xfe,(byte)0xf1,(byte)0xfe,(byte)0xf1 }; /** * Checks if the given DES key material is weak or semi-weak. * * @param key the buffer with the DES key material. * @param offset the offset in key, where the DES key * material starts. * @return true if the given DES key material is weak or semi-weak, false otherwise. * @exception InvalidKeyException if the given key material, starting at offset * inclusive, is shorter than 8 bytes. */ public static boolean isWeak( byte[] key, int offset) throws InvalidKeyException { if (key.length - offset < DES_KEY_LEN) { throw new InvalidKeyException("key material too short in DESKeySpec.isWeak"); } nextkey: for (int i = 0; i < N_DES_WEAK_KEYS; i++) { for (int j = 0; j < DES_KEY_LEN; j++) { if (key[j + offset] != DES_weak_keys[i * DES_KEY_LEN + j]) { continue nextkey; } } return true; } return false; } } bouncycastle-1.49.orig/jce/src/javax/crypto/spec/OAEPParameterSpec.java0000644000175000017500000000611311070571075025413 0ustar ebourgebourgpackage javax.crypto.spec; import java.security.spec.AlgorithmParameterSpec; /** * This class specifies the set of parameters used with OAEP Padding, as defined * in the PKCS #1 standard. Its ASN.1 definition in PKCS#1 standard is described * below: * *

    * * RSAES-OAEP-params ::= SEQUENCE { hashAlgorithm [0] OAEP-PSSDigestAlgorithms * DEFAULT sha1, maskGenAlgorithm [1] PKCS1MGFAlgorithms DEFAULT mgf1SHA1, * pSourceAlgorithm [2] PKCS1PSourceAlgorithms DEFAULT pSpecifiedEmpty } * * * * where * *
     * 
     * OAEP-PSSDigestAlgorithms ALGORITHM-IDENTIFIER ::= { { OID id-sha1 PARAMETERS
     * NULL }| { OID id-sha256 PARAMETERS NULL }| { OID id-sha384 PARAMETERS NULL } | {
     * OID id-sha512 PARAMETERS NULL }, ... -- Allows for future expansion -- }
     * PKCS1MGFAlgorithms ALGORITHM-IDENTIFIER ::= { { OID id-mgf1 PARAMETERS
     * OAEP-PSSDigestAlgorithms }, ... -- Allows for future expansion -- }
     * PKCS1PSourceAlgorithms ALGORITHM-IDENTIFIER ::= { { OID id-pSpecified
     * PARAMETERS OCTET STRING }, ... -- Allows for future expansion -- }
     * 
     * 
    * * @see PSource */ public class OAEPParameterSpec implements AlgorithmParameterSpec { private String mdName; private String mgfName; private AlgorithmParameterSpec mgfSpec; private PSource pSrc; /** * Constructs a parameter set for OAEP padding as defined in the PKCS #1 * standard using the specified message digest algorithm mdName, mask * generation function algorithm mgfName, parameters for the mask generation * function mgfSpec, and source of the encoding input P pSrc. * * @param mdName the algorithm name for the message digest. * @param mgfName the algorithm name for the mask generation function. * @param mgfSpec the parameters for the mask generation function. If null is * specified, null will be returned by getMGFParameters(). * @param pSrc the source of the encoding input P. * @throws NullPointerException if mdName, mgfName, or pSrc is null. */ public OAEPParameterSpec(String mdName, String mgfName, AlgorithmParameterSpec mgfSpec, PSource pSrc) { this.mdName = mdName; this.mgfName = mgfName; this.mgfSpec = mgfSpec; this.pSrc = pSrc; } /** * Returns the message digest algorithm name. * * @return the message digest algorithm name. */ public String getDigestAlgorithm() { return mdName; } /** * Returns the mask generation function algorithm name. * * @return the mask generation function algorithm name. */ public String getMGFAlgorithm() { return mgfName; } /** * Returns the parameters for the mask generation function. * * @return the parameters for the mask generation function. */ public AlgorithmParameterSpec getMGFParameters() { return mgfSpec; } /** * Returns the source of encoding input P. * * @return the source of encoding input P. */ public PSource getPSource() { return pSrc; } } bouncycastle-1.49.orig/jce/src/javax/crypto/spec/IvParameterSpec.java0000644000175000017500000000351710445172704025253 0ustar ebourgebourgpackage javax.crypto.spec; import java.security.spec.AlgorithmParameterSpec; /** * This class specifies an initialization vector (IV). IVs are used * by ciphers in feedback mode, e.g., DES in CBC mode. */ public class IvParameterSpec implements AlgorithmParameterSpec { private byte[] iv; /** * Uses the bytes in iv as the IV. * * @param iv the buffer with the IV */ public IvParameterSpec( byte[] iv) { if (iv == null) { throw new IllegalArgumentException("null iv passed"); } this.iv = new byte[iv.length]; System.arraycopy(iv, 0, this.iv, 0, iv.length); } /** * Uses the first len bytes in iv, * beginning at offset inclusive, as the IV. *

    * The bytes that constitute the IV are those between * iv[offset] and iv[offset+len-1] inclusive. * * @param iv the buffer with the IV * @param offset the offset in iv where the IV starts * @param len the number of IV bytes */ public IvParameterSpec( byte[] iv, int offset, int len) { if (iv == null) { throw new IllegalArgumentException("Null iv passed"); } if (offset < 0 || len < 0 || (iv.length - offset) < len) { throw new IllegalArgumentException("Bad offset/len"); } this.iv = new byte[len]; System.arraycopy(iv, offset, this.iv, 0, len); } /** * Returns the initialization vector (IV). * * @return the initialization vector (IV) */ public byte[] getIV() { byte[] tmp = new byte[iv.length]; System.arraycopy(iv, 0, tmp, 0, iv.length); return tmp; } } bouncycastle-1.49.orig/jce/src/javax/crypto/spec/DHPrivateKeySpec.java0000644000175000017500000000230310445172704025323 0ustar ebourgebourgpackage javax.crypto.spec; import java.math.BigInteger; import java.security.spec.KeySpec; /** * This class specifies a Diffie-Hellman private key with its associated parameters. * * @see DHPublicKeySpec */ public class DHPrivateKeySpec implements KeySpec { private BigInteger x; private BigInteger p; private BigInteger g; /** * Constructor that takes a private value x, a prime * modulus p, and a base generator g. */ public DHPrivateKeySpec( BigInteger x, BigInteger p, BigInteger g) { this.x = x; this.p = p; this.g = g; } /** * Returns the private value x. * * @return the private value x */ public BigInteger getX() { return x; } /** * Returns the prime modulus p. * * @return the prime modulus p */ public BigInteger getP() { return p; } /** * Returns the base generator g. * * @return the base generator g */ public BigInteger getG() { return g; } } bouncycastle-1.49.orig/jce/src/javax/crypto/spec/RC2ParameterSpec.java0000644000175000017500000001044010445172704025254 0ustar ebourgebourgpackage javax.crypto.spec; import java.security.spec.AlgorithmParameterSpec; /** * This class specifies the parameters used with the * RC2 * algorithm. *

    * The parameters consist of an effective key size and optionally * an 8-byte initialization vector (IV) (only in feedback mode). *

    * This class can be used to initialize a Cipher object that * implements the RC2 algorithm. */ public class RC2ParameterSpec implements AlgorithmParameterSpec { private int effectiveKeyBits; private byte[] iv = new byte[8]; /** * Constructs a parameter set for RC2 from the given effective key size * (in bits). * * @param effectiveKeyBits the effective key size in bits. */ public RC2ParameterSpec( int effectiveKeyBits) { this.effectiveKeyBits = effectiveKeyBits; } /** * Constructs a parameter set for RC2 from the given effective key size * (in bits) and an 8-byte IV. *

    * The bytes that constitute the IV are those between * iv[0] and iv[7] inclusive. * * @param effectiveKeyBits the effective key size in bits. * @param iv the buffer with the 8-byte IV. */ public RC2ParameterSpec( int effectiveKeyBits, byte[] iv) { this(effectiveKeyBits, iv, 0); } /** * Constructs a parameter set for RC2 from the given effective key size * (in bits) and IV. *

    * The IV is taken from iv, starting at * offset inclusive. * The bytes that constitute the IV are those between * iv[offset] and iv[offset+7] inclusive. * * @param effectiveKeyBits the effective key size in bits. * @param iv the buffer with the IV. * @param offset the offset in iv where the 8-byte IV starts. */ public RC2ParameterSpec( int effectiveKeyBits, byte[] iv, int offset) { this.effectiveKeyBits = effectiveKeyBits; this.iv = new byte[8]; System.arraycopy(iv, offset, this.iv, 0, this.iv.length); } /** * Returns the effective key size in bits. * * @return the effective key size in bits. */ public int getEffectiveKeyBits() { return effectiveKeyBits; } /** * Returns the IV or null if this parameter set does not contain an IV. * * @return the IV or null if this parameter set does not contain an IV. */ public byte[] getIV() { if (iv == null) { return null; } byte[] tmp = new byte[iv.length]; System.arraycopy(iv, 0, tmp, 0, tmp.length); return tmp; } /** * Tests for equality between the specified object and this * object. Two RC2ParameterSpec objects are considered equal if their * effective key sizes and IVs are equal. * (Two IV references are considered equal if both are null.) * * @param obj the object to test for equality with this object. * @return true if the objects are considered equal, false otherwise. * @override equals in class java.lang.Object */ public boolean equals( Object obj) { if ((obj == null) || !(obj instanceof RC2ParameterSpec)) { return false; } RC2ParameterSpec spec = (RC2ParameterSpec)obj; if (this.effectiveKeyBits != spec.effectiveKeyBits) { return false; } if (iv != null) { if (spec.iv == null) { return false; } for (int i = 0; i != iv.length; i++) { if (iv[i] != spec.iv[i]) { return false; } } } else if (spec.iv != null) { return false; } return true; } /** * Calculates a hash code value for the object. * Objects that are equal will also have the same hashcode. * * @override hashCode in class java.lang.Object */ public int hashCode() { throw new RuntimeException("Not yet implemented"); } } bouncycastle-1.49.orig/jce/src/javax/crypto/spec/DHParameterSpec.java0000644000175000017500000000504510445172704025166 0ustar ebourgebourgpackage javax.crypto.spec; import java.math.BigInteger; import java.security.spec.AlgorithmParameterSpec; /** * This class specifies the set of parameters used with the Diffie-Hellman * algorithm, as specified in PKCS #3: Diffie-Hellman Key-Agreement * Standard. *

    * A central authority generates parameters and gives them to the two * entities seeking to generate a secret key. The parameters are a prime * p, a base g, and optionally the length * in bits of the private value, l. *

    * It is possible that more than one instance of parameters may be * generated by a given central authority, and that there may be more than * one central authority. Indeed, each individual may be its own central * authority, with different entities having different parameters. * * @see javax.crypto.KeyAgreement */ public class DHParameterSpec implements AlgorithmParameterSpec { private BigInteger p; private BigInteger g; private int l; /** * Constructs a parameter set for Diffie-Hellman, using a prime modulus * p and a base generator g. * * @param p the prime modulus * @param g the base generator */ public DHParameterSpec( BigInteger p, BigInteger g) { this.p = p; this.g = g; } /** * Constructs a parameter set for Diffie-Hellman, using a prime modulus * p, a base generator g, and the size in bits, * l, of the random exponent (private value). * * @param p the prime modulus * @param g the base generator * @param l the size in bits of the random exponent (private value) */ public DHParameterSpec( BigInteger p, BigInteger g, int l) { this.p = p; this.g = g; this.l = l; } /** * Returns the prime modulus p. * * @return the prime modulus p */ public BigInteger getP() { return p; } /** * Returns the base generator g. * * @return the base generator g */ public BigInteger getG() { return g; } /** * Returns the size in bits, l, of the random exponent * (private value). * * @return the size in bits, l, of the random exponent * (private value), or 0 if this size has not been set */ public int getL() { return l; } } bouncycastle-1.49.orig/jce/src/javax/crypto/IllegalBlockSizeException.java0000644000175000017500000000164110757407671026333 0ustar ebourgebourgpackage javax.crypto; import java.security.GeneralSecurityException; /** * This exception is thrown when the length of data provided to a block * cipher is incorrect, i.e., does not match the block size of the cipher. * */ public class IllegalBlockSizeException extends GeneralSecurityException { private static final long serialVersionUID = -1965144811953540392L; /** * Constructs an IllegalBlockSizeException with no detail message. * (A detail message is a String that describes this particular * exception.) */ public IllegalBlockSizeException() { } /** * Constructs an IllegalBlockSizeException with the specified * detail message. (A detail message is a String that describes * this particular exception.) * * @param msg the detail message. */ public IllegalBlockSizeException( String msg) { super(msg); } } bouncycastle-1.49.orig/jce/src/javax/crypto/SecretKeyFactory.java0000644000175000017500000002267311062413510024506 0ustar ebourgebourgpackage javax.crypto; import java.security.Provider; import java.security.InvalidKeyException; import java.security.NoSuchAlgorithmException; import java.security.NoSuchProviderException; import java.security.spec.KeySpec; import java.security.spec.InvalidKeySpecException; /** * This class represents a factory for secret keys. * *

    * Key factories are used to convert keys (opaque * cryptographic keys of type Key) into key specifications * (transparent representations of the underlying key material), and vice versa. * Secret key factories operate only on secret (symmetric) keys. *

    * Key factories are bi-directional, i.e., they allow to build an opaque * key object from a given key specification (key material), or to retrieve * the underlying key material of a key object in a suitable format. *

    * Application developers should refer to their provider's documentation * to find out which key specifications are supported by the * generateSecret and * getKeySpec methods. * For example, the DES secret-key factory supplied by the "SunJCE" provider * supports DESKeySpec as a transparent representation of DES * keys, and that provider's secret-key factory for Triple DES keys supports * DESedeKeySpec as a transparent representation of Triple DES keys. * * @see SecretKey * @see javax.crypto.spec.DESKeySpec * @see javax.crypto.spec.DESedeKeySpec * @see javax.crypto.spec.PBEKeySpec */ public class SecretKeyFactory { SecretKeyFactorySpi keyFacSpi; Provider provider; String algorithm; /** * Creates a SecretKeyFactory object. * * @param keyFacSpi the delegate * @param provider the provider * @param algorithm the secret-key algorithm */ protected SecretKeyFactory( SecretKeyFactorySpi keyFacSpi, Provider provider, String algorithm) { this.keyFacSpi = keyFacSpi; this.provider = provider; this.algorithm = algorithm; } /** * Generates a SecretKeyFactory object for the specified secret-key algorithm. * If the default provider package provides an implementation of the * requested factory, an instance of SecretKeyFactory * containing that implementation is returned. * If the requested factory is not available in the default provider * package, other provider packages are searched. * * @param algorithm the standard name of the requested secret-key algorithm. * See Appendix A in the Java Cryptography Extension API Specification & Reference * for information about standard algorithm names. * @return a SecretKeyFactory object for the specified secret-key algorithm. * @exception NoSuchAlgorithmException if a secret-key factory for the specified algorithm * is not available in the default provider package or any of the other provider packages * that were searched. */ public static final SecretKeyFactory getInstance( String algorithm) throws NoSuchAlgorithmException { try { JCEUtil.Implementation imp = JCEUtil.getImplementation("SecretKeyFactory", algorithm, (String) null); if (imp == null) { throw new NoSuchAlgorithmException(algorithm + " not found"); } SecretKeyFactory keyFact = new SecretKeyFactory( (SecretKeyFactorySpi)imp.getEngine(), imp.getProvider(), algorithm); return keyFact; } catch (NoSuchProviderException e) { throw new NoSuchAlgorithmException(algorithm + " not found"); } } /** * Generates a SecretKeyFactory object for the specified * secret-key algorithm from the specified provider. * * @param algorithm the standard name of the requested secret-key algorithm. * See Appendix A in the Java Cryptography Extension API Specification & Reference * for information about standard algorithm names. * @param provider the name of the provider. * @return a SecretKeyFactory object for the specified secret-key algorithm. * @exception NoSuchAlgorithmException if a secret-key factory for the specified algorithm is not * available from the specified provider. * @exception NoSuchProviderException if the specified provider has not been configured. */ public static final SecretKeyFactory getInstance( String algorithm, String provider) throws NoSuchAlgorithmException, NoSuchProviderException { if (provider == null) { throw new IllegalArgumentException("No provider specified to SecretKeyFactory.getInstance()"); } JCEUtil.Implementation imp = JCEUtil.getImplementation("SecretKeyFactory", algorithm, provider); if (imp == null) { throw new NoSuchAlgorithmException(algorithm + " not found"); } SecretKeyFactory keyFact = new SecretKeyFactory( (SecretKeyFactorySpi)imp.getEngine(), imp.getProvider(), algorithm); return keyFact; } /** * Generates a SecretKeyFactory object for the specified * secret-key algorithm from the specified provider. * * @param algorithm the standard name of the requested secret-key algorithm. * See Appendix A in the Java Cryptography Extension API Specification & Reference * for information about standard algorithm names. * @param provider the provider. * @return a SecretKeyFactory object for the specified secret-key algorithm. * @exception NoSuchAlgorithmException if a secret-key factory for the specified algorithm is not * available from the specified provider. */ public static final SecretKeyFactory getInstance( String algorithm, Provider provider) throws NoSuchAlgorithmException { if (provider == null) { throw new IllegalArgumentException("No provider specified to SecretKeyFactory.getInstance()"); } JCEUtil.Implementation imp = JCEUtil.getImplementation("SecretKeyFactory", algorithm, provider); if (imp == null) { throw new NoSuchAlgorithmException(algorithm + " not found"); } SecretKeyFactory keyFact = new SecretKeyFactory( (SecretKeyFactorySpi)imp.getEngine(), imp.getProvider(), algorithm); return keyFact; } /** * Returns the provider of this SecretKeyFactory object. * * @return the provider of this SecretKeyFactory object */ public final Provider getProvider() { return provider; } /** * Returns the algorithm name of this SecretKeyFactory object. *

    * This is the same name that was specified in one of the getInstance calls * that created this SecretKeyFactory object. * * @return the algorithm name of this SecretKeyFactory object. */ public final String getAlgorithm() { return algorithm; } /** * Generates a SecretKey object from the provided key specification (key material). * * @param keySpec the specification (key material) of the secret key * @return the secret key * @exception InvalidKeySpecException if the given key specification * is inappropriate for this secret-key factory to produce a secret key. */ public final SecretKey generateSecret( KeySpec keySpec) throws InvalidKeySpecException { return keyFacSpi.engineGenerateSecret(keySpec); } /** * Returns a specification (key material) of the given key object * in the requested format. * * @param key the key * @param keySpec the requested format in which the key material shall be * returned * @return the underlying key specification (key material) in the requested format * @exception InvalidKeySpecException if the requested key specification is inappropriate for * the given key (e.g., the algorithms associated with key and keySpec do * not match, or key references a key on a cryptographic hardware device whereas * keySpec is the specification of a software-based key), or the given key cannot be dealt with * (e.g., the given key has an algorithm or format not supported by this secret-key factory). */ public final KeySpec getKeySpec( SecretKey key, Class keySpec) throws InvalidKeySpecException { return keyFacSpi.engineGetKeySpec(key, keySpec); } /** * Translates a key object, whose provider may be unknown or potentially * untrusted, into a corresponding key object of this secret-key factory. * * @param key the key whose provider is unknown or untrusted * @return the translated key * @exception InvalidKeyException if the given key cannot be processed by this secret-key factory. */ public final SecretKey translateKey( SecretKey key) throws InvalidKeyException { return keyFacSpi.engineTranslateKey(key); } } bouncycastle-1.49.orig/jce/src/javax/crypto/KeyAgreement.java0000644000175000017500000003677711062413514023656 0ustar ebourgebourgpackage javax.crypto; import java.security.Key; import java.security.Provider; import java.security.SecureRandom; import java.security.InvalidKeyException; import java.security.NoSuchProviderException; import java.security.NoSuchAlgorithmException; import java.security.InvalidAlgorithmParameterException; import java.security.spec.AlgorithmParameterSpec; /** * This class provides the functionality of a key agreement (or key * exchange) protocol. * The keys involved in establishing a shared secret are created by one of the * key generators (KeyPairGenerator or * KeyGenerator), a KeyFactory, or as a result from * an intermediate phase of the key agreement protocol * (see doPhase). * * For each of the correspondents in the key exchange, doPhase * needs to be called. For example, if this key exchange is with one other * party, doPhase needs to be called once, with the * lastPhase flag set to true. * If this key exchange is * with two other parties, doPhase needs to be called twice, * the first time setting the lastPhase flag to * false, and the second time setting it to true. * There may be any number of parties involved in a key exchange. * * @see KeyGenerator * @see SecretKey */ public class KeyAgreement { KeyAgreementSpi keyAgreeSpi; Provider provider; String algorithm; /** * Creates a KeyAgreement object. * * @param keyAgreeSpi the delegate * @param provider the provider * @param algorithm the algorithm */ protected KeyAgreement( KeyAgreementSpi keyAgreeSpi, Provider provider, String algorithm) { this.keyAgreeSpi = keyAgreeSpi; this.provider = provider; this.algorithm = algorithm; } /** * Returns the algorithm name of this KeyAgreement object. *

    * This is the same name that was specified in one of the * getInstance calls that created this * KeyAgreement object. * * @return the algorithm name of this KeyAgreement object. */ public final String getAlgorithm() { return algorithm; } /** * Generates a KeyAgreement object that implements the * specified key agreement algorithm. * If the default provider package provides an implementation of the * requested key agreement algorithm, an instance of * KeyAgreement containing that implementation is returned. * If the algorithm is not available in the default provider package, * other provider packages are searched. * * @param algorithm the standard name of the requested key agreement algorithm. * See Appendix A in the Java Cryptography Extension API Specification & Reference * for information about standard algorithm names. * @return the new KeyAgreement object * @exception NoSuchAlgorithmException if the specified algorithm is not * available in the default provider package or any of the other provider * packages that were searched. */ public static final KeyAgreement getInstance( String algorithm) throws NoSuchAlgorithmException { try { JCEUtil.Implementation imp = JCEUtil.getImplementation("KeyAgreement", algorithm, (String) null); if (imp == null) { throw new NoSuchAlgorithmException(algorithm + " not found"); } KeyAgreement keyAgree = new KeyAgreement((KeyAgreementSpi)imp.getEngine(), imp.getProvider(), algorithm); return keyAgree; } catch (NoSuchProviderException e) { throw new NoSuchAlgorithmException(algorithm + " not found"); } } /** * Generates a KeyAgreement object for the specified key * agreement algorithm from the specified provider. * * @param algorithm the standard name of the requested key agreement algorithm. * See Appendix A in the Java Cryptography Extension API Specification & Reference * for information about standard algorithm names. * @param provider the provider * @return the new KeyAgreement object * @exception NoSuchAlgorithmException if the specified algorithm is not * available from the specified provider. */ public static final KeyAgreement getInstance( String algorithm, Provider provider) throws NoSuchAlgorithmException { if (provider == null) { throw new IllegalArgumentException("No provider specified to KeyAgreement.getInstance()"); } JCEUtil.Implementation imp = JCEUtil.getImplementation("KeyAgreement", algorithm, provider); if (imp == null) { throw new NoSuchAlgorithmException(algorithm + " not found"); } KeyAgreement keyAgree = new KeyAgreement((KeyAgreementSpi)imp.getEngine(), imp.getProvider(), algorithm); return keyAgree; } /** * Generates a KeyAgreement object for the specified key * agreement algorithm from the specified provider. * * @param algorithm the standard name of the requested key agreement algorithm. * See Appendix A in the Java Cryptography Extension API Specification & Reference * for information about standard algorithm names. * @param provider the name of the provider * @return the new KeyAgreement object * @exception NoSuchAlgorithmException if the specified algorithm is not * available from the specified provider. * @exception NoSuchProviderException if the specified provider has not * been configured. */ public static final KeyAgreement getInstance( String algorithm, String provider) throws NoSuchAlgorithmException, NoSuchProviderException { if (provider == null) { throw new IllegalArgumentException("No provider specified to KeyAgreement.getInstance()"); } JCEUtil.Implementation imp = JCEUtil.getImplementation("KeyAgreement", algorithm, provider); if (imp == null) { throw new NoSuchAlgorithmException(algorithm + " not found"); } KeyAgreement keyAgree = new KeyAgreement((KeyAgreementSpi)imp.getEngine(), imp.getProvider(), algorithm); return keyAgree; } /** * Returns the provider of this KeyAgreement object. * * @return the provider of this KeyAgreement object */ public final Provider getProvider() { return provider; } /** * Initializes this key agreement with the given key, which is required to * contain all the algorithm parameters required for this key agreement. *

    * If this key agreement requires any random bytes, it will get * them using the * SecureRandom implementation of the highest-priority * installed provider as the source of randomness. * (If none of the installed providers supply an implementation of * SecureRandom, a system-provided source of randomness will be used.) * * @param key the party's private information. For example, in the case * of the Diffie-Hellman key agreement, this would be the party's own * Diffie-Hellman private key. * @exception InvalidKeyException if the given key is * inappropriate for this key agreement, e.g., is of the wrong type or * has an incompatible algorithm type. */ public final void init( Key key) throws InvalidKeyException { keyAgreeSpi.engineInit(key, null); } /** * Initializes this key agreement with the given key and source of * randomness. The given key is required to contain all the algorithm * parameters required for this key agreement. *

    * If the key agreement algorithm requires random bytes, it gets them * from the given source of randomness, random. * However, if the underlying * algorithm implementation does not require any random bytes, * random is ignored. * * @param key the party's private information. For example, in the case * of the Diffie-Hellman key agreement, this would be the party's own * Diffie-Hellman private key. * @param random the source of randomness * @exception InvalidKeyException if the given key is * inappropriate for this key agreement, e.g., is of the wrong type or * has an incompatible algorithm type. */ public final void init( Key key, SecureRandom random) throws InvalidKeyException { keyAgreeSpi.engineInit(key, random); } /** * Initializes this key agreement with the given key and set of * algorithm parameters. *

    * If this key agreement requires any random bytes, it will get * them using the * SecureRandom implementation of the highest-priority * installed provider as the source of randomness. * (If none of the installed providers supply an implementation of * SecureRandom, a system-provided source of randomness will be used.) * * @param key the party's private information. For example, in the case * of the Diffie-Hellman key agreement, this would be the party's own * Diffie-Hellman private key. * @param params the key agreement parameters * @exception InvalidKeyException if the given key is inappropriate for this * key agreement, e.g., is of the wrong type or has an incompatible algorithm type. * @exception InvalidAlgorithmParameterException if the given parameters * are inappropriate for this key agreement. */ public final void init( Key key, AlgorithmParameterSpec params) throws InvalidKeyException, InvalidAlgorithmParameterException { keyAgreeSpi.engineInit(key, params, null); } /** * Initializes this key agreement with the given key, set of * algorithm parameters, and source of randomness. * * @param key the party's private information. For example, in the case * of the Diffie-Hellman key agreement, this would be the party's own * Diffie-Hellman private key. * @param params the key agreement parameters * @param random the source of randomness * @exception InvalidKeyException if the given key is * inappropriate for this key agreement, e.g., is of the wrong type or * has an incompatible algorithm type. * @exception InvalidAlgorithmParameterException if the given parameters * are inappropriate for this key agreement. */ public final void init( Key key, AlgorithmParameterSpec params, SecureRandom random) throws InvalidKeyException, InvalidAlgorithmParameterException { keyAgreeSpi.engineInit(key, params, random); } /** * Executes the next phase of this key agreement with the given * key that was received from one of the other parties involved in this key * agreement. * * @param key the key for this phase. For example, in the case of * Diffie-Hellman between 2 parties, this would be the other party's * Diffie-Hellman public key. * @param lastPhase flag which indicates whether or not this is the last * phase of this key agreement. * @return the (intermediate) key resulting from this phase, or null * if this phase does not yield a key * @exception InvalidKeyException if the given key is inappropriate for this phase. * @exception IllegalStateException if this key agreement has not been * initialized. */ public final Key doPhase( Key key, boolean lastPhase) throws InvalidKeyException, IllegalStateException { return keyAgreeSpi.engineDoPhase(key, lastPhase); } /** * Generates the shared secret and returns it in a new buffer. *

    * This method resets this KeyAgreement object, so that it * can be reused for further key agreements. Unless this key agreement is * reinitialized with one of the init methods, the same * private information and algorithm parameters will be used for * subsequent key agreements. * * @return the new buffer with the shared secret * @exception IllegalStateException if this key agreement has not been completed yet */ public final byte[] generateSecret() throws IllegalStateException { return keyAgreeSpi.engineGenerateSecret(); } /** * Generates the shared secret, and places it into the buffer * sharedSecret, beginning at offset inclusive. *

    * If the sharedSecret buffer is too small to hold the * result, a ShortBufferException is thrown. * In this case, this call should be repeated with a larger output buffer. *

    * This method resets this KeyAgreement object, so that it * can be reused for further key agreements. Unless this key agreement is * reinitialized with one of the init methods, the same * private information and algorithm parameters will be used for * subsequent key agreements. * * @param sharedSecret the buffer for the shared secret * @param offset the offset in sharedSecret where the * shared secret will be stored * @return the number of bytes placed into sharedSecret * @exception IllegalStateException if this key agreement has not been * completed yet * @exception ShortBufferException if the given output buffer is too small * to hold the secret */ public final int generateSecret( byte[] sharedSecret, int offset) throws IllegalStateException, ShortBufferException { return keyAgreeSpi.engineGenerateSecret(sharedSecret, offset); } /** * Creates the shared secret and returns it as a SecretKey * object of the specified algorithm. *

    * This method resets this KeyAgreement object, so that it * can be reused for further key agreements. Unless this key agreement is * reinitialized with one of the init methods, the same * private information and algorithm parameters will be used for * subsequent key agreements. * * @param algorithm the requested secret-key algorithm * @return the shared secret key * @exception IllegalStateException if this key agreement has not been * completed yet * @exception NoSuchAlgorithmException if the specified secret-key * algorithm is not available * @exception InvalidKeyException if the shared secret-key material cannot * be used to generate a secret key of the specified algorithm (e.g., * the key material is too short) */ public final SecretKey generateSecret( String algorithm) throws IllegalStateException, NoSuchAlgorithmException, InvalidKeyException { return keyAgreeSpi.engineGenerateSecret(algorithm); } } bouncycastle-1.49.orig/jce/src/javax/crypto/JCEUtil.java0000644000175000017500000001321311062413463022514 0ustar ebourgebourgpackage javax.crypto; import java.security.NoSuchProviderException; import java.security.Provider; import java.security.Security; import java.util.Locale; class JCEUtil { static class Implementation { Object engine; Provider provider; Implementation( Object engine, Provider provider) { this.engine = engine; this.provider = provider; } Object getEngine() { return engine; } Provider getProvider() { return provider; } } /** * see if we can find an algorithm (or its alias and what it represents) in * the property table for the given provider. * * @return null if no algorithm found, an Implementation if it is. */ static private Implementation findImplementation( String baseName, String algorithm, Provider prov) { String alias; while ((alias = prov.getProperty("Alg.Alias." + baseName + "." + algorithm)) != null) { algorithm = alias; } String className = prov.getProperty(baseName + "." + algorithm); if (className != null) { try { Class cls; ClassLoader clsLoader = prov.getClass().getClassLoader(); if (clsLoader != null) { cls = clsLoader.loadClass(className); } else { cls = Class.forName(className); } return new Implementation(cls.newInstance(), prov); } catch (ClassNotFoundException e) { throw new IllegalStateException( "algorithm " + algorithm + " in provider " + prov.getName() + " but no class \"" + className + "\" found!"); } catch (Exception e) { throw new IllegalStateException( "algorithm " + algorithm + " in provider " + prov.getName() + " but class \"" + className + "\" inaccessible!"); } } return null; } /** * return an implementation for a given algorithm/provider. * If the provider is null, we grab the first avalaible who has the required algorithm. * * @return null if no algorithm found, an Implementation if it is. * @exception NoSuchProviderException if a provider is specified and not found. */ static Implementation getImplementation( String baseName, String algorithm, String provider) throws NoSuchProviderException { if (provider == null) { Provider[] prov = Security.getProviders(); // // search every provider looking for the algorithm we want. // for (int i = 0; i != prov.length; i++) { // // try case insensitive // Implementation imp = findImplementation(baseName, algorithm.toUpperCase(Locale.ENGLISH), prov[i]); if (imp != null) { return imp; } imp = findImplementation(baseName, algorithm, prov[i]); if (imp != null) { return imp; } } } else { Provider prov = Security.getProvider(provider); if (prov == null) { throw new NoSuchProviderException("Provider " + provider + " not found"); } // // try case insensitive // Implementation imp = findImplementation(baseName, algorithm.toUpperCase(Locale.ENGLISH), prov); if (imp != null) { return imp; } return findImplementation(baseName, algorithm, prov); } return null; } /** * return an implementation for a given algorithm/provider. * If the provider is null, we grab the first avalaible who has the required algorithm. * * @return null if no algorithm found, an Implementation if it is. * @exception NoSuchProviderException if a provider is specified and not found. */ static Implementation getImplementation( String baseName, String algorithm, Provider provider) { if (provider == null) { Provider[] prov = Security.getProviders(); // // search every provider looking for the algorithm we want. // for (int i = 0; i != prov.length; i++) { // // try case insensitive // Implementation imp = findImplementation(baseName, algorithm.toUpperCase(Locale.ENGLISH), prov[i]); if (imp != null) { return imp; } imp = findImplementation(baseName, algorithm, prov[i]); if (imp != null) { return imp; } } } else { // // try case insensitive // Implementation imp = findImplementation(baseName, algorithm.toUpperCase(Locale.ENGLISH), provider); if (imp != null) { return imp; } return findImplementation(baseName, algorithm, provider); } return null; } } bouncycastle-1.49.orig/jce/src/javax/crypto/interfaces/0000755000175000017500000000000012152033546022536 5ustar ebourgebourgbouncycastle-1.49.orig/jce/src/javax/crypto/interfaces/DHPublicKey.java0000644000175000017500000000063410445172705025513 0ustar ebourgebourgpackage javax.crypto.interfaces; import java.math.BigInteger; import java.security.PublicKey; /** * The interface to a Diffie-Hellman public key. * * @see DHKey * @see DHPrivateKey */ public abstract interface DHPublicKey extends DHKey, PublicKey { /** * Returns the public value, y. * * @return the public value, y */ public BigInteger getY(); } bouncycastle-1.49.orig/jce/src/javax/crypto/interfaces/DHKey.java0000644000175000017500000000055310445172705024354 0ustar ebourgebourgpackage javax.crypto.interfaces; import javax.crypto.spec.DHParameterSpec; /** * The interface to a Diffie-Hellman key. * * @see DHParameterSpec * @see DHPublicKey * @see DHPrivateKey */ public abstract interface DHKey { /** * Returns the key parameters. * * @return the key parameters */ public DHParameterSpec getParams(); } bouncycastle-1.49.orig/jce/src/javax/crypto/interfaces/PBEKey.java0000644000175000017500000000167010757410614024470 0ustar ebourgebourgpackage javax.crypto.interfaces; import javax.crypto.SecretKey; /** * The interface to a PBE key. * * @see PBEKeySpec, SecretKey */ public interface PBEKey extends SecretKey { /** * Returns the password. * * Note: this method should return a copy of the password. It is the * caller's responsibility to zero out the password information after it is * no longer needed. * * @return the password. */ public char[] getPassword(); /** * Returns the salt or null if not specified. * * Note: this method should return a copy of the salt. It is the caller's * responsibility to zero out the salt information after it is no longer * needed. * * @return the salt. */ public byte[] getSalt(); /** * Returns the iteration count or 0 if not specified. * * @return the iteration count. */ public int getIterationCount(); } bouncycastle-1.49.orig/jce/src/javax/crypto/interfaces/DHPrivateKey.java0000644000175000017500000000064110445172705025705 0ustar ebourgebourgpackage javax.crypto.interfaces; import java.math.BigInteger; import java.security.PrivateKey; /** * The interface to a Diffie-Hellman private key. * * @see DHKey * @see DHPublicKey */ public abstract interface DHPrivateKey extends DHKey, PrivateKey { /** * Returns the private value, x. * * @return the private value, x */ public BigInteger getX(); } bouncycastle-1.49.orig/jce/src/javax/crypto/ShortBufferException.java0000644000175000017500000000165110757410030025365 0ustar ebourgebourgpackage javax.crypto; import java.security.GeneralSecurityException; /** * This exception is thrown when an output buffer provided by the user * is too short to hold the operation result. */ public class ShortBufferException extends GeneralSecurityException { private static final long serialVersionUID = 8427718640832943747L; /** * Constructs a ShortBufferException with no detail * message. A detail message is a String that describes this * particular exception. */ public ShortBufferException() { } /** * Constructs a ShortBufferException with the specified * detail message. A detail message is a String that describes * this particular exception, which may, for example, specify which * algorithm is not available. * * @param msg the detail message. */ public ShortBufferException( String msg) { super(msg); } } bouncycastle-1.49.orig/jce/src/javax/crypto/NoSuchPaddingException.java0000644000175000017500000000167210757407754025650 0ustar ebourgebourgpackage javax.crypto; import java.security.GeneralSecurityException; /** * This exception is thrown when a particular padding mechanism is * requested but is not available in the environment. */ public class NoSuchPaddingException extends GeneralSecurityException { private static final long serialVersionUID = -4572885201200175466L; /** * Constructs a NoSuchPaddingException with no detail * message. A detail message is a String that describes this * particular exception. */ public NoSuchPaddingException() { } /** * Constructs a NoSuchPaddingException with the specified * detail message. A detail message is a String that describes * this particular exception, which may, for example, specify which * algorithm is not available. * * @param msg - the detail message. */ public NoSuchPaddingException( String msg) { super(msg); } } bouncycastle-1.49.orig/jce/src/javax/crypto/MacSpi.java0000644000175000017500000000545710445172704022450 0ustar ebourgebourgpackage javax.crypto; import java.security.Key; import java.security.InvalidKeyException; import java.security.InvalidAlgorithmParameterException; import java.security.spec.AlgorithmParameterSpec; /** * This class defines the Service Provider Interface (SPI) * for the Mac class. * All the abstract methods in this class must be implemented by each * cryptographic service provider who wishes to supply the implementation * of a particular MAC algorithm. *

    * Implementations are free to implement the Cloneable interface. */ public abstract class MacSpi { public MacSpi() { } /** * Returns the length of the MAC in bytes. * * @return the MAC length in bytes. */ protected abstract int engineGetMacLength(); /** * Initializes the MAC with the given (secret) key and algorithm * parameters. * * @param key - the (secret) key. * @param params - the algorithm parameters. * @exception InvalidKeyException if the given key is inappropriate for initializing this MAC. * @exception InvalidAlgorithmParameterException - if the given algorithm parameters are inappropriate * for this MAC. */ protected abstract void engineInit( Key key, AlgorithmParameterSpec params) throws InvalidKeyException, InvalidAlgorithmParameterException; /** * Processes the given byte. * * @param input - the input byte to be processed. */ protected abstract void engineUpdate( byte input); /** * Processes the first len bytes in input, * starting at offset inclusive. * * @param input the input buffer. * @param offset the offset in input where the input starts. * @param len the number of bytes to process. */ protected abstract void engineUpdate( byte[] input, int offset, int len); /** * Completes the MAC computation and resets the MAC for further use, * maintaining the secret key that the MAC was initialized with. * * @return the MAC result. */ protected abstract byte[] engineDoFinal(); /** * Resets the MAC for further use, maintaining the secret key that the * MAC was initialized with. */ protected abstract void engineReset(); /** * Returns a clone if the implementation is cloneable. * * @return a clone if the implementation is cloneable. * @exception CloneNotSupportedException if this is called on an implementation that does not support * Cloneable. */ public Object clone() throws CloneNotSupportedException { throw new CloneNotSupportedException("Underlying MAC does not support cloning"); } } bouncycastle-1.49.orig/jce/src/javax/crypto/ExemptionMechanismException.java0000644000175000017500000000151510757407601026742 0ustar ebourgebourgpackage javax.crypto; import java.security.GeneralSecurityException; /** * This is the generic ExemptionMechanism exception. * */ public class ExemptionMechanismException extends GeneralSecurityException { private static final long serialVersionUID = 1572699429277957109L; /** * Constructs a ExemptionMechanismException with no detailed message. * (A detailed message is a String that describes this particular exception.) */ public ExemptionMechanismException() { } /** * Constructs a ExemptionMechanismException with the specified * detailed message. (A detailed message is a String that describes * this particular exception.) * * @param msg the detailed message. */ public ExemptionMechanismException( String msg) { super(msg); } } bouncycastle-1.49.orig/jce/src/javax/crypto/Cipher.java0000644000175000017500000017411311062413475022501 0ustar ebourgebourgpackage javax.crypto; import java.util.StringTokenizer; import java.security.Key; import java.security.Provider; import java.security.SecureRandom; import java.security.AlgorithmParameters; import java.security.InvalidKeyException; import java.security.NoSuchAlgorithmException; import java.security.NoSuchProviderException; import java.security.InvalidAlgorithmParameterException; import java.security.cert.Certificate; import java.security.spec.AlgorithmParameterSpec; /** * This class provides the functionality of a cryptographic cipher for * encryption and decryption. It forms the core of the Java Cryptographic * Extension (JCE) framework. *

    * In order to create a Cipher object, the application calls the * Cipher's getInstance method, and passes the name of the * requested transformation to it. Optionally, the name of a provider * may be specified. *

    * A transformation is a string that describes the operation (or * set of operations) to be performed on the given input, to produce some * output. A transformation always includes the name of a cryptographic * algorithm (e.g., DES), and may be followed by a feedback mode and * padding scheme. * *

    A transformation is of the form:

    * *

      *
    • "algorithm/mode/padding" or *

      *

    • "algorithm" *
    * *

    (in the latter case, * provider-specific default values for the mode and padding scheme are used). * For example, the following is a valid transformation:

    * *

     *     Cipher c = Cipher.getInstance("DES/CBC/PKCS5Padding");
     * 
    *

    * When requesting a block cipher in stream cipher mode (e.g., * DES in CFB or OFB mode), the user may * optionally specify the number of bits to be * processed at a time, by appending this number to the mode name as shown in * the "DES/CFB8/NoPadding" and "DES/OFB32/PKCS5Padding" * transformations. If no such number is specified, a provider-specific default * is used. (For example, the "SunJCE" provider uses a default of 64 bits.) */ public class Cipher { static private final int UNINITIALIZED = 0; static public final int ENCRYPT_MODE = 1; static public final int DECRYPT_MODE = 2; static public final int WRAP_MODE = 3; static public final int UNWRAP_MODE = 4; static public final int PUBLIC_KEY = 1; static public final int PRIVATE_KEY = 2; static public final int SECRET_KEY = 3; private CipherSpi cipherSpi; private Provider provider; private String transformation; private int mode = UNINITIALIZED; /** * Creates a Cipher object. * * @param cipherSpi the delegate * @param provider the provider * @param transformation the transformation */ protected Cipher( CipherSpi cipherSpi, Provider provider, String transformation) { this.cipherSpi = cipherSpi; this.provider = provider; this.transformation = transformation; } /** * Generates a Cipher object that implements the specified * transformation. *

    * If the default provider package supplies an implementation of the * requested transformation, an instance of Cipher containing * that implementation is returned. * If the transformation is not available in the default provider package, * other provider packages are searched. * * @param transformation the name of the transformation, e.g., DES/CBC/PKCS5Padding. * See Appendix A in the Java Cryptography Extension API Specification & Reference * for information about standard transformation names. * * @return a cipher that implements the requested transformation * @exception NoSuchAlgorithmException if the specified transformation is not available in the default * provider package or any of the other provider packages that were searched. * @exception NoSuchPaddingException if transformation contains a padding scheme that is * not available. */ public static final Cipher getInstance( String transformation) throws NoSuchAlgorithmException, NoSuchPaddingException { try { JCEUtil.Implementation imp = JCEUtil.getImplementation("Cipher", transformation, (String) null); if (imp != null) { return new Cipher((CipherSpi)imp.getEngine(), imp.getProvider(), transformation); } // // try the long way // StringTokenizer tok = new StringTokenizer(transformation, "/"); String algorithm = tok.nextToken(); imp = JCEUtil.getImplementation("Cipher", algorithm, (String) null); if (imp == null) { throw new NoSuchAlgorithmException(transformation + " not found"); } CipherSpi cipherSpi = (CipherSpi)imp.getEngine(); // // make sure we don't get fooled by a "//" in the string // if (tok.hasMoreTokens() && !transformation.regionMatches(algorithm.length(), "//", 0, 2)) { cipherSpi.engineSetMode(tok.nextToken()); } if (tok.hasMoreTokens()) { cipherSpi.engineSetPadding(tok.nextToken()); } return new Cipher(cipherSpi, imp.getProvider(), transformation); } catch (NoSuchProviderException e) { throw new NoSuchAlgorithmException(transformation + " not found"); } } /** * Creates a Cipher object that implements the specified * transformation, as supplied by the specified provider. * * @param transformation the name of the transformation, e.g., DES/CBC/PKCS5Padding. * See Appendix A in the Java Cryptography Extension API Specification & Reference * for information about standard transformation names. * * @param provider the provider * @return a cipher that implements the requested transformation * @exception NoSuchAlgorithmException if no transformation was specified, or if the specified * transformation is not available from the specified provider. * @exception NoSuchPaddingException if transformation contains a padding scheme * that is not available. */ public static final Cipher getInstance( String transformation, Provider provider) throws NoSuchAlgorithmException, NoSuchPaddingException { if (transformation == null) { throw new IllegalArgumentException("No transformation specified for Cipher.getInstance()"); } JCEUtil.Implementation imp = JCEUtil.getImplementation("Cipher", transformation, provider); if (imp != null) { return new Cipher((CipherSpi)imp.getEngine(), imp.getProvider(), transformation); } // // try the long way // StringTokenizer tok = new StringTokenizer(transformation, "/"); String algorithm = tok.nextToken(); imp = JCEUtil.getImplementation("Cipher", algorithm, provider); if (imp == null) { throw new NoSuchAlgorithmException(transformation + " not found"); } CipherSpi cipherSpi = (CipherSpi)imp.getEngine(); // // make sure we don't get fooled by a "//" in the string // if (tok.hasMoreTokens() && !transformation.regionMatches(algorithm.length(), "//", 0, 2)) { cipherSpi.engineSetMode(tok.nextToken()); } if (tok.hasMoreTokens()) { cipherSpi.engineSetPadding(tok.nextToken()); } return new Cipher(cipherSpi, imp.getProvider(), transformation); } /** * Creates a Cipher object that implements the specified * transformation, as supplied by the specified provider. * * @param transformation the name of the transformation, e.g., DES/CBC/PKCS5Padding. * See Appendix A in the Java Cryptography Extension API Specification & Reference * for information about standard transformation names. * * @param provider the name of the provider * @return a cipher that implements the requested transformation * @exception NoSuchAlgorithmException if no transformation was specified, or if the specified * transformation is not available from the specified provider. * @exception NoSuchProviderException if the specified provider has not been configured. * @exception NoSuchPaddingException if transformation contains a padding scheme * that is not available. */ public static final Cipher getInstance( String transformation, String provider) throws NoSuchAlgorithmException, NoSuchProviderException, NoSuchPaddingException { if (transformation == null) { throw new IllegalArgumentException("No transformation specified for Cipher.getInstance()"); } JCEUtil.Implementation imp = JCEUtil.getImplementation("Cipher", transformation, provider); if (imp != null) { return new Cipher((CipherSpi)imp.getEngine(), imp.getProvider(), transformation); } // // try the long way // StringTokenizer tok = new StringTokenizer(transformation, "/"); String algorithm = tok.nextToken(); imp = JCEUtil.getImplementation("Cipher", algorithm, provider); if (imp == null) { throw new NoSuchAlgorithmException(transformation + " not found"); } CipherSpi cipherSpi = (CipherSpi)imp.getEngine(); // // make sure we don't get fooled by a "//" in the string // if (tok.hasMoreTokens() && !transformation.regionMatches(algorithm.length(), "//", 0, 2)) { cipherSpi.engineSetMode(tok.nextToken()); } if (tok.hasMoreTokens()) { cipherSpi.engineSetPadding(tok.nextToken()); } return new Cipher(cipherSpi, imp.getProvider(), transformation); } /** * Returns the provider of this Cipher object. * * @return the provider of this Cipher object */ public final Provider getProvider() { return provider; } /** * Returns the algorithm name of this Cipher object. *

    * This is the same name that was specified in one of the * getInstance calls that created this Cipher * object.. * * @return the algorithm name of this Cipher object. */ public final String getAlgorithm() { return transformation; } /** * Returns the block size (in bytes). * * @return the block size (in bytes), or 0 if the underlying algorithm is not a block cipher */ public final int getBlockSize() { return cipherSpi.engineGetBlockSize(); } /** * Returns the length in bytes that an output buffer would need to be in * order to hold the result of the next update or * doFinal operation, given the input length inputLen (in bytes). *

    * This call takes into account any unprocessed (buffered) data from a * previous update call, and padding. *

    * The actual output length of the next update or * doFinal call may be smaller than the length returned by * this method. * * @param inputLen the input length (in bytes) * @return the required output buffer size (in bytes) * @exception java.lang.IllegalStateException if this cipher is in a wrong state (e.g., has not * yet been initialized) */ public final int getOutputSize( int inputLen) throws IllegalStateException { if (mode != ENCRYPT_MODE && mode != DECRYPT_MODE) { throw new IllegalStateException("Cipher is uninitialised"); } return cipherSpi.engineGetOutputSize(inputLen); } /** * Returns the initialization vector (IV) in a new buffer. *

    * This is useful in the case where a random IV was created, * or in the context of password-based encryption or decryption, where the IV * is derived from a user-supplied password. * * @return the initialization vector in a new buffer, or null if the * underlying algorithm does not use an IV, or if the IV has not yet been set. */ public final byte[] getIV() { return cipherSpi.engineGetIV(); } /** * Returns the parameters used with this cipher. *

    * The returned parameters may be the same that were used to initialize * this cipher, or may contain a combination of default and random * parameter values used by the underlying cipher implementation if this * cipher requires algorithm parameters but was not initialized with any. * * @return the parameters used with this cipher, or null if this cipher * does not use any parameters. */ public final AlgorithmParameters getParameters() { return cipherSpi.engineGetParameters(); } /** * Returns the exemption mechanism object used with this cipher. * * @return the exemption mechanism object used with this cipher, or * null if this cipher does not use any exemption mechanism. */ public final ExemptionMechanism getExemptionMechanism() { return null; } /** * Initializes this cipher with a key. *

    * The cipher is initialized for one of the following four operations: * encryption, decryption, key wrapping or key unwrapping, depending * on the value of opmode. *

    * If this cipher requires any algorithm parameters that cannot be * derived from the given key, the underlying cipher * implementation is supposed to generate the required parameters itself * (using provider-specific default or random values) if it is being * initialized for encryption or key wrapping, and raise an * InvalidKeyException if it is being * initialized for decryption or key unwrapping. * The generated parameters can be retrieved using * getParameters or * getIV (if the parameter is an IV). *

    * If this cipher (including its underlying feedback or padding scheme) * requires any random bytes (e.g., for parameter generation), it will get * them using the * SecureRandom implementation of the highest-priority * installed provider as the source of randomness. * (If none of the installed providers supply an implementation of * SecureRandom, a system-provided source of randomness will be used.) *

    * Note that when a Cipher object is initialized, it loses all * previously-acquired state. In other words, initializing a Cipher is * equivalent to creating a new instance of that Cipher and initializing * it. * * @param opmode the operation mode of this cipher (this is one of the following: * ENCRYPT_MODE, DECRYPT_MODE, * WRAP_MODE or UNWRAP_MODE) * @param key the key * @exception InvalidKeyException if the given key is inappropriate for * initializing this cipher, or if this cipher is being initialized for * decryption and requires algorithm parameters that cannot be * determined from the given key, or if the given key has a keysize that * exceeds the maximum allowable keysize (as determined from the * configured jurisdiction policy files). Note: Jurisdiction files are ignored * in this implementation. */ public final void init( int opmode, Key key) throws InvalidKeyException { cipherSpi.engineInit(opmode, key, new SecureRandom()); mode = opmode; } /** * Initializes this cipher with a key and a source of randomness. *

    * The cipher is initialized for one of the following four operations: * encryption, decryption, key wrapping or key unwrapping, depending * on the value of opmode. *

    * If this cipher requires any algorithm parameters that cannot be * derived from the given key, the underlying cipher * implementation is supposed to generate the required parameters itself * (using provider-specific default or random values) if it is being * initialized for encryption or key wrapping, and raise an * InvalidKeyException if it is being * initialized for decryption or key unwrapping. * The generated parameters can be retrieved using * engineGetParameters or * engineGetIV (if the parameter is an IV). *

    * If this cipher (including its underlying feedback or padding scheme) * requires any random bytes (e.g., for parameter generation), it will get * them from random. *

    * Note that when a Cipher object is initialized, it loses all * previously-acquired state. In other words, initializing a Cipher is * equivalent to creating a new instance of that Cipher and initializing * it. * @param opmode the operation mode of this cipher (this is one of the * following: ENCRYPT_MODE, DECRYPT_MODE, * WRAP_MODE or UNWRAP_MODE) * @param key the encryption key * @param random the source of randomness * @exception InvalidKeyException if the given key is inappropriate for * initializing this cipher, or if this cipher is being initialized for * decryption and requires algorithm parameters that cannot be * determined from the given key, or if the given key has a keysize that * exceeds the maximum allowable keysize (as determined from the * configured jurisdiction policy files). Note: Jurisdiction files are ignored * in this implementation. */ public final void init( int opmode, Key key, SecureRandom random) throws InvalidKeyException { cipherSpi.engineInit(opmode, key, random); mode = opmode; } /** * Initializes this cipher with a key and a set of algorithm parameters. *

    * The cipher is initialized for one of the following four operations: * encryption, decryption, key wrapping or key unwrapping, depending * on the value of opmode. *

    * If this cipher requires any algorithm parameters and * params is null, the underlying cipher implementation is * supposed to generate the required parameters itself (using * provider-specific default or random values) if it is being * initialized for encryption or key wrapping, and raise an * InvalidAlgorithmParameterException if it is being * initialized for decryption or key unwrapping. * The generated parameters can be retrieved using * getParameters or * getIV (if the parameter is an IV). *

    * If this cipher (including its underlying feedback or padding scheme) * requires any random bytes (e.g., for parameter generation), it will get * them using the * * SecureRandom implementation of the highest-priority * installed provider as the source of randomness. * (If none of the installed providers supply an implementation of * SecureRandom, a system-provided source of randomness will be used.) *

    * Note that when a Cipher object is initialized, it loses all * previously-acquired state. In other words, initializing a Cipher is * equivalent to creating a new instance of that Cipher and initializing * it. * * @param opmode the operation mode of this cipher (this is one of the * following: ENCRYPT_MODE, DECRYPT_MODE, WRAP_MODE * or UNWRAP_MODE) * @param key the encryption key * @param params the algorithm parameters * @exception InvalidKeyException if the given key is inappropriate for initializing this * cipher, or its keysize exceeds the maximum allowable keysize (as determined from the * configured jurisdiction policy files). * @exception InvalidAlgorithmParameterException if the given algorithm parameters are * inappropriate for this cipher, or this cipher is being initialized for decryption and * requires algorithm parameters and params is null, or the given algorithm * parameters imply a cryptographic strength that would exceed the legal limits (as determined * from the configured jurisdiction policy files). Note: Jurisdiction files are ignored * in this implementation. */ public final void init( int opmode, Key key, AlgorithmParameterSpec params) throws InvalidKeyException, InvalidAlgorithmParameterException { cipherSpi.engineInit(opmode, key, params, new SecureRandom()); mode = opmode; } /** * Initializes this cipher with a key, a set of algorithm * parameters, and a source of randomness. *

    * The cipher is initialized for one of the following four operations: * encryption, decryption, key wrapping or key unwrapping, depending * on the value of opmode. *

    * If this cipher requires any algorithm parameters and * params is null, the underlying cipher implementation is * supposed to generate the required parameters itself (using * provider-specific default or random values) if it is being * initialized for encryption or key wrapping, and raise an * InvalidAlgorithmParameterException if it is being * initialized for decryption or key unwrapping. * The generated parameters can be retrieved using * getParameters or * getIV (if the parameter is an IV). *

    * If this cipher (including its underlying feedback or padding scheme) * requires any random bytes (e.g., for parameter generation), it will get * them from random. *

    * Note that when a Cipher object is initialized, it loses all * previously-acquired state. In other words, initializing a Cipher is * equivalent to creating a new instance of that Cipher and initializing * it. * * @param opmode the operation mode of this cipher (this is one of the * following: ENCRYPT_MODE, DECRYPT_MODE, * WRAP_MODE or UNWRAP_MODE) * @param key the encryption key * @param params the algorithm parameters * @param random the source of randomness * @exception InvalidKeyException if the given key is inappropriate for * initializing this cipher, or its keysize exceeds the maximum allowable * keysize (as determined from the configured jurisdiction policy files). * @exception InvalidAlgorithmParameterException if the given algorithm * parameters are inappropriate for this cipher, * or this cipher is being initialized for decryption and requires * algorithm parameters and params is null, or the given * algorithm parameters imply a cryptographic strength that would exceed * the legal limits (as determined from the configured jurisdiction * policy files). * Note: Jurisdiction files are ignored in this implementation. */ public final void init( int opmode, Key key, AlgorithmParameterSpec params, SecureRandom random) throws InvalidKeyException, InvalidAlgorithmParameterException { cipherSpi.engineInit(opmode, key, params, random); mode = opmode; } /** * Initializes this cipher with a key and a set of algorithm * parameters. *

    * The cipher is initialized for one of the following four operations: * encryption, decryption, key wrapping or key unwrapping, depending * on the value of opmode. *

    * If this cipher requires any algorithm parameters and * params is null, the underlying cipher implementation is * supposed to generate the required parameters itself (using * provider-specific default or random values) if it is being * initialized for encryption or key wrapping, and raise an * InvalidAlgorithmParameterException if it is being * initialized for decryption or key unwrapping. * The generated parameters can be retrieved using * getParameters or * getIV (if the parameter is an IV). *

    * If this cipher (including its underlying feedback or padding scheme) * requires any random bytes (e.g., for parameter generation), it will get * them using the * * SecureRandom implementation of the highest-priority * installed provider as the source of randomness. * (If none of the installed providers supply an implementation of * SecureRandom, a system-provided source of randomness will be used.) *

    * Note that when a Cipher object is initialized, it loses all * previously-acquired state. In other words, initializing a Cipher is * equivalent to creating a new instance of that Cipher and initializing * it. * * @param opmode the operation mode of this cipher (this is one of the * following: ENCRYPT_MODE, DECRYPT_MODE, WRAP_MODE * or UNWRAP_MODE) * @param key the encryption key * @param params the algorithm parameters * @exception InvalidKeyException if the given key is inappropriate for * initializing this cipher, or its keysize exceeds the maximum allowable * keysize (as determined from the configured jurisdiction policy files). * @exception InvalidAlgorithmParameterException if the given algorithm * parameters are inappropriate for this cipher, * or this cipher is being initialized for decryption and requires * algorithm parameters and params is null, or the given * algorithm parameters imply a cryptographic strength that would exceed * the legal limits (as determined from the configured jurisdiction * policy files). * Note: Jurisdiction files are ignored in this implementation. */ public final void init( int opmode, Key key, AlgorithmParameters params) throws InvalidKeyException, InvalidAlgorithmParameterException { cipherSpi.engineInit(opmode, key, params, new SecureRandom()); mode = opmode; } /** * Initializes this cipher with a key, a set of algorithm * parameters, and a source of randomness. *

    * The cipher is initialized for one of the following four operations: * encryption, decryption, key wrapping or key unwrapping, depending * on the value of opmode. *

    * If this cipher requires any algorithm parameters and * params is null, the underlying cipher implementation is * supposed to generate the required parameters itself (using * provider-specific default or random values) if it is being * initialized for encryption or key wrapping, and raise an * InvalidAlgorithmParameterException if it is being * initialized for decryption or key unwrapping. * The generated parameters can be retrieved using * getParameters or * getIV (if the parameter is an IV). *

    * If this cipher (including its underlying feedback or padding scheme) * requires any random bytes (e.g., for parameter generation), it will get * them from random. *

    * Note that when a Cipher object is initialized, it loses all * previously-acquired state. In other words, initializing a Cipher is * equivalent to creating a new instance of that Cipher and initializing * it. * * @param opmode the operation mode of this cipher (this is one of the * following: ENCRYPT_MODE, DECRYPT_MODE, WRAP_MODE * or UNWRAP_MODE) * @param key the encryption key * @param params the algorithm parameters * @param random the source of randomness * @exception InvalidKeyException if the given key is inappropriate for * initializing this cipher, or its keysize exceeds the maximum allowable * keysize (as determined from the configured jurisdiction policy files). * @exception InvalidAlgorithmParameterException if the given algorithm * parameters are inappropriate for this cipher, * or this cipher is being initialized for decryption and requires * algorithm parameters and params is null, or the given * algorithm parameters imply a cryptographic strength that would exceed * the legal limits (as determined from the configured jurisdiction * policy files). * Note: Jurisdiction files are ignored in this implementation. */ public final void init( int opmode, Key key, AlgorithmParameters params, SecureRandom random) throws InvalidKeyException, InvalidAlgorithmParameterException { cipherSpi.engineInit(opmode, key, params, random); mode = opmode; } /** * Initializes this cipher with the public key from the given certificate. *

    * The cipher is initialized for one of the following four operations: * encryption, decryption, key wrapping or key unwrapping, depending * on the value of opmode. *

    * If the certificate is of type X.509 and has a key usage * extension field marked as critical, and the value of the key usage * extension field implies that the public key in * the certificate and its corresponding private key are not * supposed to be used for the operation represented by the value * of opmode, * an InvalidKeyException * is thrown. *

    * If this cipher requires any algorithm parameters that cannot be * derived from the public key in the given certificate, the underlying * cipher * implementation is supposed to generate the required parameters itself * (using provider-specific default or ramdom values) if it is being * initialized for encryption or key wrapping, and raise an * InvalidKeyException if it is being initialized for decryption or * key unwrapping. * The generated parameters can be retrieved using * getParameters or * getIV (if the parameter is an IV). *

    * If this cipher (including its underlying feedback or padding scheme) * requires any random bytes (e.g., for parameter generation), it will get * them using the * * SecureRandom * implementation of the highest-priority installed provider as the source of randomness. * (If none of the installed providers supply an implementation of * SecureRandom, a system-provided source of randomness will be used.) *

    * Note that when a Cipher object is initialized, it loses all * previously-acquired state. In other words, initializing a Cipher is * equivalent to creating a new instance of that Cipher and initializing * it. * @param opmode the operation mode of this cipher (this is one of the * following: * ENCRYPT_MODE, DECRYPT_MODE, * WRAP_MODE or UNWRAP_MODE) * @param certificate the certificate * @exception InvalidKeyException if the public key in the given * certificate is inappropriate for initializing this cipher, or this * cipher is being initialized for decryption or unwrapping keys and * requires algorithm parameters that cannot be determined from the * public key in the given certificate, or the keysize of the public key * in the given certificate has a keysize that exceeds the maximum * allowable keysize (as determined by the configured jurisdiction policy * files). * Note: Jurisdiction files are ignored in this implementation. */ public final void init( int opmode, Certificate certificate) throws InvalidKeyException { cipherSpi.engineInit(opmode, certificate.getPublicKey(), new SecureRandom()); mode = opmode; } /** * Initializes this cipher with the public key from the given certificate * and a source of randomness. *

    The cipher is initialized for one of the following four operations: * encryption, decryption, key wrapping * or key unwrapping, depending on * the value of opmode. *

    * If the certificate is of type X.509 and has a key usage * extension field marked as critical, and the value of the key usage * extension field implies that the public key in * the certificate and its corresponding private key are not * supposed to be used for the operation represented by the value of * opmode, * an InvalidKeyException * is thrown. *

    * If this cipher requires any algorithm parameters that cannot be * derived from the public key in the given certificate, * the underlying cipher * implementation is supposed to generate the required parameters itself * (using provider-specific default or random values) if it is being * initialized for encryption or key wrapping, and raise an * InvalidKeyException if it is being * initialized for decryption or key unwrapping. * The generated parameters can be retrieved using * engineGetParameters or * engineGetIV (if the parameter is an IV). *

    * If this cipher (including its underlying feedback or padding scheme) * requires any random bytes (e.g., for parameter generation), it will get * them from random. *

    * Note that when a Cipher object is initialized, it loses all * previously-acquired state. In other words, initializing a Cipher is * equivalent to creating a new instance of that Cipher and initializing * it. * * @param opmode the operation mode of this cipher (this is one of the * following: ENCRYPT_MODE, DECRYPT_MODE, * WRAP_MODE or UNWRAP_MODE) * @param certificate the certificate * @param random the source of randomness * @exception InvalidKeyException if the public key in the given * certificate is inappropriate for initializing this cipher, or this * cipher is being initialized for decryption or unwrapping keys and * requires algorithm parameters that cannot be determined from the * public key in the given certificate, or the keysize of the public key * in the given certificate has a keysize that exceeds the maximum * allowable keysize (as determined by the configured jurisdiction policy * files). */ public final void init( int opmode, Certificate certificate, SecureRandom random) throws InvalidKeyException { cipherSpi.engineInit(opmode, certificate.getPublicKey(), random); mode = opmode; } /** * Continues a multiple-part encryption or decryption operation * (depending on how this cipher was initialized), processing another data * part. *

    * The bytes in the input buffer are processed, and the * result is stored in a new buffer. *

    * If input has a length of zero, this method returns * null. * * @param input the input buffer * @return the new buffer with the result, or null if the underlying * cipher is a block cipher and the input data is too short to result in a * new block. * @exception IllegalStateException if this cipher is in a wrong state * (e.g., has not been initialized) */ public final byte[] update( byte[] input) throws IllegalStateException { if (mode != ENCRYPT_MODE && mode != DECRYPT_MODE) { throw new IllegalStateException("Cipher is uninitialised"); } if (input == null) { throw new IllegalArgumentException("Null input buffer"); } if (input.length == 0) { return null; } return cipherSpi.engineUpdate(input, 0, input.length); } /** * Continues a multiple-part encryption or decryption operation * (depending on how this cipher was initialized), processing another data * part. *

    * The first inputLen bytes in the input * buffer, starting at inputOffset inclusive, are processed, * and the result is stored in a new buffer. *

    * If inputLen is zero, this method returns * null. * * @param input the input buffer * @param inputOffset the offset in input where the input * starts * @param inputLen the input length * @return the new buffer with the result, or null if the underlying * cipher is a block cipher and the input data is too short to result in a * new block. * @exception IllegalStateException if this cipher is in a wrong state * (e.g., has not been initialized) */ public final byte[] update( byte[] input, int inputOffset, int inputLen) throws IllegalStateException { if (mode != ENCRYPT_MODE && mode != DECRYPT_MODE) { throw new IllegalStateException("Cipher is uninitialised"); } if (input == null) { throw new IllegalArgumentException("Null input passed"); } if (inputLen < 0 || inputOffset < 0 || inputLen > (input.length - inputOffset)) { throw new IllegalArgumentException("Bad inputOffset/inputLen"); } if (inputLen == 0) { return null; } return cipherSpi.engineUpdate(input, inputOffset, inputLen); } /** * Continues a multiple-part encryption or decryption operation * (depending on how this cipher was initialized), processing another data * part. *

    * The first inputLen bytes in the input * buffer, starting at inputOffset inclusive, are processed, * and the result is stored in the output buffer. *

    * If the output buffer is too small to hold the result, * a ShortBufferException is thrown. In this case, repeat this * call with a larger output buffer. Use * getOutputSize to determine how big * the output buffer should be. *

    * If inputLen is zero, this method returns * a length of zero. * * @param input the input buffer * @param inputOffset the offset in input where the input starts * @param inputLen the input length * @param output the buffer for the result * @return the number of bytes stored in output * @exception IllegalStateException if this cipher is in a wrong state * (e.g., has not been initialized) * @exception ShortBufferException if the given output buffer is too small * to hold the result */ public final int update( byte[] input, int inputOffset, int inputLen, byte[] output) throws IllegalStateException, ShortBufferException { if (mode != ENCRYPT_MODE && mode != DECRYPT_MODE) { throw new IllegalStateException("Cipher is uninitialised"); } if (input == null) { throw new IllegalArgumentException("Null input passed"); } if (inputLen < 0 || inputOffset < 0 || inputLen > (input.length - inputOffset)) { throw new IllegalArgumentException("Bad inputOffset/inputLen"); } if (output == null) { throw new IllegalArgumentException("Null output passed"); } if (inputLen == 0) { return 0; } return cipherSpi.engineUpdate(input, inputOffset, inputLen, output, 0); } /** * Continues a multiple-part encryption or decryption operation * (depending on how this cipher was initialized), processing another data * part. *

    * The first inputLen bytes in the input * buffer, starting at inputOffset inclusive, are processed, * and the result is stored in the output buffer, starting at * outputOffset inclusive. *

    * If the output buffer is too small to hold the result, * a ShortBufferException is thrown. In this case, repeat this * call with a larger output buffer. Use * getOutputSize to determine how big * the output buffer should be. *

    * If inputLen is zero, this method returns * a length of zero. * * @param input the input buffer * @param inputOffset the offset in input where the input starts * @param inputLen the input length * @param output the buffer for the result * @param outputOffset the offset in output where the result * is stored * @return the number of bytes stored in output * @exception IllegalStateException if this cipher is in a wrong state * (e.g., has not been initialized) * @exception ShortBufferException if the given output buffer is too small * to hold the result */ public final int update( byte[] input, int inputOffset, int inputLen, byte[] output, int outputOffset) throws IllegalStateException, ShortBufferException { if (mode != ENCRYPT_MODE && mode != DECRYPT_MODE) { throw new IllegalStateException("Cipher is uninitialised"); } if (input == null) { throw new IllegalArgumentException("Null input passed"); } if (inputLen < 0 || inputOffset < 0 || inputLen > (input.length - inputOffset)) { throw new IllegalArgumentException("Bad inputOffset/inputLen"); } if (output == null) { throw new IllegalArgumentException("Null output passed"); } if (outputOffset < 0 || outputOffset >= output.length) { throw new IllegalArgumentException("Bad outputOffset"); } if (inputLen == 0) { return 0; } return cipherSpi.engineUpdate(input, inputOffset, inputLen, output, outputOffset); } /** * Finishes a multiple-part encryption or decryption operation, depending * on how this cipher was initialized. *

    * Input data that may have been buffered during a previous * update operation is processed, with padding (if requested) * being applied. * The result is stored in a new buffer. *

    * A call to this method resets this cipher object to the state * it was in when previously initialized via a call to init. * That is, the object is reset and available to encrypt or decrypt * (depending on the operation mode that was specified in the call to * init) more data. * @return the new buffer with the result * @exception IllegalStateException if this cipher is in a wrong state * (e.g., has not been initialized) * @exception IllegalBlockSizeException if this cipher is a block cipher, * no padding has been requested (only in encryption mode), and the total * input length of the data processed by this cipher is not a multiple of * block size * @exception BadPaddingException if this cipher is in decryption mode, * and (un)padding has been requested, but the decrypted data is not * bounded by the appropriate padding bytes */ public final byte[] doFinal() throws java.lang.IllegalStateException, IllegalBlockSizeException, BadPaddingException { if (mode != ENCRYPT_MODE && mode != DECRYPT_MODE) { throw new IllegalStateException("Cipher is uninitialised"); } return cipherSpi.engineDoFinal(null, 0, 0); } /** * Finishes a multiple-part encryption or decryption operation, depending * on how this cipher was initialized. *

    * Input data that may have been buffered during a previous * update operation is processed, with padding (if requested) * being applied. * The result is stored in the output buffer, starting at * outputOffset inclusive. *

    * If the output buffer is too small to hold the result, * a ShortBufferException is thrown. In this case, repeat this * call with a larger output buffer. Use * getOutputSize to determine how big * the output buffer should be. *

    * A call to this method resets this cipher object to the state * it was in when previously initialized via a call to init. * That is, the object is reset and available to encrypt or decrypt * (depending on the operation mode that was specified in the call to * init) more data. * * @param output the buffer for the result * @param outputOffset the offset in output where the result * is stored * @return the number of bytes stored in output * @exception IllegalStateException if this cipher is in a wrong state * (e.g., has not been initialized) * @exception IllegalBlockSizeException if this cipher is a block cipher, * no padding has been requested (only in encryption mode), and the total * input length of the data processed by this cipher is not a multiple of * block size * @exception ShortBufferException if the given output buffer is too small * to hold the result * @exception BadPaddingException if this cipher is in decryption mode, * and (un)padding has been requested, but the decrypted data is not * bounded by the appropriate padding bytes */ public final int doFinal( byte[] output, int outputOffset) throws IllegalStateException, IllegalBlockSizeException, ShortBufferException, BadPaddingException { if (mode != ENCRYPT_MODE && mode != DECRYPT_MODE) { throw new IllegalStateException("Cipher is uninitialised"); } if (output == null) { throw new IllegalArgumentException("Null output passed"); } if (outputOffset < 0 || outputOffset >= output.length) { throw new IllegalArgumentException("Bad outputOffset"); } return cipherSpi.engineDoFinal(null, 0, 0, output, outputOffset); } /** * Encrypts or decrypts data in a single-part operation, or finishes a * multiple-part operation. The data is encrypted or decrypted, * depending on how this cipher was initialized. *

    * The bytes in the input buffer, and any input bytes that * may have been buffered during a previous update operation, * are processed, with padding (if requested) being applied. * The result is stored in a new buffer. *

    * A call to this method resets this cipher object to the state * it was in when previously initialized via a call to init. * That is, the object is reset and available to encrypt or decrypt * (depending on the operation mode that was specified in the call to * init) more data. * * @param input the input buffer * @return the new buffer with the result * @exception IllegalStateException if this cipher is in a wrong state * (e.g., has not been initialized) * @exception IllegalBlockSizeException if this cipher is a block cipher, * no padding has been requested (only in encryption mode), and the total * input length of the data processed by this cipher is not a multiple of * block size * @exception BadPaddingException if this cipher is in decryption mode, * and (un)padding has been requested, but the decrypted data is not * bounded by the appropriate padding bytes */ public final byte[] doFinal( byte[] input) throws java.lang.IllegalStateException, IllegalBlockSizeException, BadPaddingException { if (mode != ENCRYPT_MODE && mode != DECRYPT_MODE) { throw new IllegalStateException("Cipher is uninitialised"); } if (input == null) { throw new IllegalArgumentException("Null input passed"); } return cipherSpi.engineDoFinal(input, 0, input.length); } /** * Encrypts or decrypts data in a single-part operation, or finishes a * multiple-part operation. The data is encrypted or decrypted, * depending on how this cipher was initialized. *

    * The first inputLen bytes in the input * buffer, starting at inputOffset inclusive, and any input * bytes that may have been buffered during a previous update * operation, are processed, with padding (if requested) being applied. * The result is stored in a new buffer. *

    A call to this method resets this cipher object to the state * it was in when previously initialized via a call to init. * That is, the object is reset and available to encrypt or decrypt * (depending on the operation mode that was specified in the call to * init) more data. * * @param input the input buffer * @param inputOffset the offset in input where the input starts * @param inputLen the input length * @return the new buffer with the result * @exception IllegalStateException if this cipher is in a wrong state * (e.g., has not been initialized) * @exception IllegalBlockSizeException if this cipher is a block cipher, * no padding has been requested (only in encryption mode), and the total * input length of the data processed by this cipher is not a multiple of * block size * @exception BadPaddingException if this cipher is in decryption mode, * and (un)padding has been requested, but the decrypted data is not * bounded by the appropriate padding bytes */ public final byte[] doFinal( byte[] input, int inputOffset, int inputLen) throws IllegalStateException, IllegalBlockSizeException, BadPaddingException { if (mode != ENCRYPT_MODE && mode != DECRYPT_MODE) { throw new IllegalStateException("Cipher is uninitialised"); } if (input == null) { throw new IllegalArgumentException("Null input passed"); } if (inputLen < 0 || inputOffset < 0 || inputLen > (input.length - inputOffset)) { throw new IllegalArgumentException("Bad inputOffset/inputLen"); } return cipherSpi.engineDoFinal(input, inputOffset, inputLen); } /** * Encrypts or decrypts data in a single-part operation, or finishes a * multiple-part operation. The data is encrypted or decrypted, * depending on how this cipher was initialized. *

    * The first inputLen bytes in the input * buffer, starting at inputOffset inclusive, and any input * bytes that may have been buffered during a previous update * operation, are processed, with padding (if requested) being applied. * The result is stored in the output buffer. *

    * If the output buffer is too small to hold the result, * a ShortBufferException is thrown. In this case, repeat this * call with a larger output buffer. Use * getOutputSize to determine how big * the output buffer should be. *

    * A call to this method resets this cipher object to the state * it was in when previously initialized via a call to init. * That is, the object is reset and available to encrypt or decrypt * (depending on the operation mode that was specified in the call to * init) more data. * @param input the input buffer * @param inputOffset the offset in input where the input starts * @param inputLen the input length * @param output the buffer for the result * @return the number of bytes stored in output * @exception IllegalStateException if this cipher is in a wrong state * (e.g., has not been initialized) * @exception IllegalBlockSizeException if this cipher is a block cipher, * no padding has been requested (only in encryption mode), and the total * input length of the data processed by this cipher is not a multiple of * block size * @exception ShortBufferException if the given output buffer is too small * to hold the result * @exception BadPaddingException if this cipher is in decryption mode, * and (un)padding has been requested, but the decrypted data is not * bounded by the appropriate padding bytes */ public final int doFinal( byte[] input, int inputOffset, int inputLen, byte[] output) throws IllegalStateException, ShortBufferException, IllegalBlockSizeException, BadPaddingException { if (mode != ENCRYPT_MODE && mode != DECRYPT_MODE) { throw new IllegalStateException("Cipher is uninitialised"); } if (input == null) { throw new IllegalArgumentException("Null input passed"); } if (inputLen < 0 || inputOffset < 0 || inputLen > (input.length - inputOffset)) { throw new IllegalArgumentException("Bad inputOffset/inputLen"); } if (output == null) { throw new IllegalArgumentException("Null output passed"); } return cipherSpi.engineDoFinal(input, inputOffset, inputLen, output, 0); } /** * Encrypts or decrypts data in a single-part operation, or finishes a * multiple-part operation. The data is encrypted or decrypted, * depending on how this cipher was initialized. *

    * The first inputLen bytes in the input * buffer, starting at inputOffset inclusive, and any input * bytes that may have been buffered during a previous * update operation, are processed, with padding * (if requested) being applied. * The result is stored in the output buffer, starting at * outputOffset inclusive. *

    * If the output buffer is too small to hold the result, * a ShortBufferException is thrown. In this case, repeat this * call with a larger output buffer. Use * getOutputSize to determine how big * the output buffer should be. *

    * A call to this method resets this cipher object to the state * it was in when previously initialized via a call to init. * That is, the object is reset and available to encrypt or decrypt * (depending on the operation mode that was specified in the call to * init) more data. * * @param input the input buffer * @param inputOffset the offset in input where the input starts * @param inputLen the input length * @param output the buffer for the result * @param outputOffset the offset in output where the result is * stored * @return the number of bytes stored in output * @exception IllegalStateException if this cipher is in a wrong state * (e.g., has not been initialized) * @exception IllegalBlockSizeException if this cipher is a block cipher, * no padding has been requested (only in encryption mode), and the total * input length of the data processed by this cipher is not a multiple of * block size * @exception ShortBufferException if the given output buffer is too small * to hold the result * @exception BadPaddingException if this cipher is in decryption mode, * and (un)padding has been requested, but the decrypted data is not * bounded by the appropriate padding bytes */ public final int doFinal( byte[] input, int inputOffset, int inputLen, byte[] output, int outputOffset) throws IllegalStateException, ShortBufferException, IllegalBlockSizeException, BadPaddingException { if (mode != ENCRYPT_MODE && mode != DECRYPT_MODE) { throw new IllegalStateException("Cipher is uninitialised"); } if (input == null) { throw new IllegalArgumentException("Null input passed"); } if (inputLen < 0 || inputOffset < 0 || inputLen > (input.length - inputOffset)) { throw new IllegalArgumentException("Bad inputOffset/inputLen"); } if (output == null) { throw new IllegalArgumentException("Null output passed"); } if (outputOffset < 0 || outputOffset >= output.length) { throw new IllegalArgumentException("Bad outputOffset"); } return cipherSpi.engineDoFinal(input, inputOffset, inputLen, output, outputOffset); } /** * Wrap a key. * * @param key the key to be wrapped. * @return the wrapped key. * @exception IllegalStateException if this cipher is in a wrong state (e.g., has not * been initialized). * @exception IllegalBlockSizeException if this cipher is a block cipher, no padding * has been requested, and the length of the encoding of the key to be wrapped is not a * multiple of the block size. * @exception

    java.security.InvalidKeyException - if it is impossible or unsafe to * wrap the key with this cipher (e.g., a hardware protected key is being passed to a * software-only cipher). */ public final byte[] wrap( Key key) throws IllegalStateException, IllegalBlockSizeException, InvalidKeyException { if (mode != WRAP_MODE) { throw new IllegalStateException("Cipher is not initialised for wrapping"); } if (key == null) { throw new IllegalArgumentException("Null key passed"); } return cipherSpi.engineWrap(key); } /** * Unwrap a previously wrapped key. * * @param wrappedKey the key to be unwrapped. * @param wrappedKeyAlgorithm the algorithm associated with the wrapped key. * @param wrappedKeyType the type of the wrapped key. This must be one of * SECRET_KEY, PRIVATE_KEY, or PUBLIC_KEY. * @return the unwrapped key. * @exception IllegalStateException if this cipher is in a wrong state * (e.g., has not been initialized). * @exception InvalidKeyException if wrappedKey does not * represent a wrapped key, or if the algorithm associated with the * wrapped key is different from wrappedKeyAlgorithm * and/or its key type is different from wrappedKeyType. * @exception NoSuchAlgorithmException - if no installed providers * can create keys for the wrappedKeyAlgorithm. */ public final Key unwrap( byte[] wrappedKey, String wrappedKeyAlgorithm, int wrappedKeyType) throws IllegalStateException, InvalidKeyException, NoSuchAlgorithmException { if (mode != UNWRAP_MODE) { throw new IllegalStateException("Cipher is not initialised for unwrapping"); } if (wrappedKeyType != SECRET_KEY && wrappedKeyType != PUBLIC_KEY && wrappedKeyType != PRIVATE_KEY) { throw new IllegalArgumentException("Invalid key type argument"); } if (wrappedKey == null) { throw new IllegalArgumentException("Null wrappedKey passed"); } if (wrappedKeyAlgorithm == null) { throw new IllegalArgumentException("Null wrappedKeyAlgorithm string passed"); } return cipherSpi.engineUnwrap(wrappedKey, wrappedKeyAlgorithm, wrappedKeyType); } } bouncycastle-1.49.orig/jce/src/javax/crypto/CipherInputStream.java0000644000175000017500000002275510445172704024702 0ustar ebourgebourgpackage javax.crypto; import java.io.InputStream; import java.io.IOException; import java.io.FilterInputStream; /** * A CipherInputStream is composed of an InputStream and a Cipher so * that read() methods return data that are read in from the * underlying InputStream but have been additionally processed by the * Cipher. The Cipher must be fully initialized before being used by * a CipherInputStream. *

    * For example, if the Cipher is initialized for decryption, the * CipherInputStream will attempt to read in data and decrypt them, * before returning the decrypted data. *

    * This class adheres strictly to the semantics, especially the * failure semantics, of its ancestor classes * java.io.FilterInputStream and java.io.InputStream. This class has * exactly those methods specified in its ancestor classes, and * overrides them all. Moreover, this class catches all exceptions * that are not thrown by its ancestor classes. In particular, the * skip method skips, and the available * method counts only data that have been processed by the encapsulated Cipher. *

    * It is crucial for a programmer using this class not to use * methods that are not defined or overriden in this class (such as a * new method or constructor that is later added to one of the super * classes), because the design and implementation of those methods * are unlikely to have considered security impact with regard to * CipherInputStream. * * @since JCE1.2 * @see InputStream * @see FilterInputStream * @see Cipher * @see CipherOutputStream */ public class CipherInputStream extends FilterInputStream { private Cipher c; private byte[] buf; private byte[] inBuf; private int bufOff; private int maxBuf; private boolean finalized; private static final int INPUT_BUF_SIZE = 2048; /** * Constructs a CipherInputStream from an InputStream and a * Cipher. */ public CipherInputStream( InputStream is, Cipher c) { super(is); this.c = c; buf = new byte[c.getOutputSize(INPUT_BUF_SIZE)]; inBuf = new byte[INPUT_BUF_SIZE]; } /** * Constructs a CipherInputStream from an InputStream without * specifying a Cipher. This has the effect of constructing a * CipherInputStream using a NullCipher. */ protected CipherInputStream( InputStream is) { this(is, new NullCipher()); } /** * grab the next chunk of input from the underlying input stream */ private int nextChunk() throws IOException { int available = super.available(); // must always try to read 1 byte! // some buggy InputStreams return < 0! if (available <= 0) { available = 1; } if (available > inBuf.length) { available = super.read(inBuf, 0, inBuf.length); } else { available = super.read(inBuf, 0, available); } if (available < 0) { if (finalized) { return -1; } try { buf = c.doFinal(); } catch (Exception e) { throw new IOException("error processing stream: " + e.toString()); } bufOff = 0; if (buf != null) { maxBuf = buf.length; } else { maxBuf = 0; } finalized = true; if (bufOff == maxBuf) { return -1; } } else { bufOff = 0; try { maxBuf = c.update(inBuf, 0, available, buf, 0); } catch (Exception e) { throw new IOException("error processing stream: " + e.toString()); } if (maxBuf == 0) // not enough bytes read for first block... { return nextChunk(); } } return maxBuf; } /** * Reads the next byte of data from this input stream. The value * byte is returned as an int in the range * 0 to 255. If no byte is available * because the end of the stream has been reached, the value * -1 is returned. This method blocks until input data * is available, the end of the stream is detected, or an exception * is thrown. * * @return the next byte of data, or -1 if the end of the * stream is reached. * @exception IOException if an I/O error occurs. * @since JCE1.2 */ public int read() throws IOException { if (bufOff == maxBuf) { if (nextChunk() < 0) { return -1; } } return buf[bufOff++] & 0xff; } /** * Reads up to b.length bytes of data from this input * stream into an array of bytes. *

    * The read method of InputStream calls * the read method of three arguments with the arguments * b, 0, and b.length. * * @param b the buffer into which the data is read. * @return the total number of bytes read into the buffer, or * -1 is there is no more data because the end of * the stream has been reached. * @exception IOException if an I/O error occurs. * @since JCE1.2 * @see #read(byte[], int, int) */ public int read( byte[] b) throws IOException { return read(b, 0, b.length); } /** * Reads up to len bytes of data from this input stream * into an array of bytes. This method blocks until some input is * available. If the first argument is null, up to * len bytes are read and discarded. * * @param b the buffer into which the data is read. * @param off the start offset of the data. * @param len the maximum number of bytes read. * @return the total number of bytes read into the buffer, or -1 * if there is no more data because the end of the stream has been reached. * @exception IOException if an I/O error occurs. * @since JCE1.2 * @see #read() */ public int read( byte[] b, int off, int len) throws IOException { if (bufOff == maxBuf) { if (nextChunk() < 0) { return -1; } } int available = maxBuf - bufOff; if (len > available) { System.arraycopy(buf, bufOff, b, off, available); bufOff = maxBuf; return available; } else { System.arraycopy(buf, bufOff, b, off, len); bufOff += len; return len; } } /** * Skips n bytes of input from the bytes that can be read * from this input stream without blocking. *

    * Fewer bytes than requested might be skipped. * The actual number of bytes skipped is equal to n or * the result of a call to available, * whichever is smaller. * If n is less than zero, no bytes are skipped. *

    * The actual number of bytes skipped is returned. * * @param n the number of bytes to be skipped. * @return the actual number of bytes skipped. * @exception IOException if an I/O error occurs. * @since JCE1.2 */ public long skip( long n) throws IOException { if (n <= 0) { return 0; } int available = maxBuf - bufOff; if (n > available) { bufOff = maxBuf; return available; } else { bufOff += (int)n; return (int)n; } } /** * Returns the number of bytes that can be read from this input * stream without blocking. The available method of * InputStream returns 0. This method * should be overridden by subclasses. * * @return the number of bytes that can be read from this input stream * without blocking. * @exception IOException if an I/O error occurs. * @since JCE1.2 */ public int available() throws IOException { return maxBuf - bufOff; } /** * Closes this input stream and releases any system resources * associated with the stream. *

    * The close method of CipherInputStream * calls the close method of its underlying input * stream. * * @exception IOException if an I/O error occurs. * @since JCE1.2 */ public void close() throws IOException { super.close(); } /** * Tests if this input stream supports the mark * and reset methods, which it does not. * * @return false, since this class does not support the * mark and reset methods. * @since JCE1.2 * @see #mark(int) * @see #reset() */ public boolean markSupported() { return false; } } bouncycastle-1.49.orig/jce/src/javax/crypto/CipherSpi.java0000644000175000017500000006305310445172704023156 0ustar ebourgebourgpackage javax.crypto; import java.security.Key; import java.security.SecureRandom; import java.security.InvalidKeyException; import java.security.AlgorithmParameters; import java.security.NoSuchAlgorithmException; import java.security.InvalidAlgorithmParameterException; import java.security.spec.AlgorithmParameterSpec; /** * This class defines the Service Provider Interface (SPI) * for the Cipher class. * All the abstract methods in this class must be implemented by each * cryptographic service provider who wishes to supply the implementation * of a particular cipher algorithm. *

    * In order to create an instance of Cipher, which * encapsulates an instance of this CipherSpi class, an * application calls one of the * getInstance * factory methods of the * Cipher engine class and specifies the requested * transformation. * Optionally, the application may also specify the name of a provider. *

    * A transformation is a string that describes the operation (or * set of operations) to be performed on the given input, to produce some * output. A transformation always includes the name of a cryptographic * algorithm (e.g., DES), and may be followed by a feedback mode and * padding scheme. *

    * A transformation is of the form: *

    *

      *
    • "algorithm/mode/padding" or *

      *

    • "algorithm" *
    * *

    (in the latter case, * provider-specific default values for the mode and padding scheme are used). * For example, the following is a valid transformation:

    * *

     *     Cipher c = Cipher.getInstance("DES/CBC/PKCS5Padding");
     * 
    * *

    A provider may supply a separate class for each combination * of algorithm/mode/padding, or may decide to provide more generic * classes representing sub-transformations corresponding to * algorithm or algorithm/mode or algorithm//padding * (note the double slashes), * in which case the requested mode and/or padding are set automatically by * the getInstance methods of Cipher, which invoke * the engineSetMode and * engineSetPadding * methods of the provider's subclass of CipherSpi. * *

    A Cipher property in a provider master class may have one of * the following formats: * *

      * *
    • *
       *     // provider's subclass of "CipherSpi" implements "algName" with
       *     // pluggable mode and padding
       *     Cipher.algName
       * 
      * *
    • *
       *     // provider's subclass of "CipherSpi" implements "algName" in the
       *     // specified "mode", with pluggable padding
       *     Cipher.algName/mode
       * 
      * *
    • *
       *    // provider's subclass of "CipherSpi" implements "algName" with the
       *    // specified "padding", with pluggable mode
       *    Cipher.algName//padding
       * 
      * *
    • *
       *    // provider's subclass of "CipherSpi" implements "algName" with the
       *    // specified "mode" and "padding"
       *    Cipher.algName/mode/padding
       * 
      * *
    * *

    For example, a provider may supply a subclass of CipherSpi * that implements DES/ECB/PKCS5Padding, one that implements * DES/CBC/PKCS5Padding, one that implements * DES/CFB/PKCS5Padding, and yet another one that implements * DES/OFB/PKCS5Padding. That provider would have the following * Cipher properties in its master class:

    * *

      * *
    • *
       *    Cipher.DES/ECB/PKCS5Padding
       * 
      * *
    • *
       *    Cipher.DES/CBC/PKCS5Padding
       * 
      * *
    • *
       *    Cipher.DES/CFB/PKCS5Padding
       * 
      * *
    • *
       *    Cipher.DES/OFB/PKCS5Padding
       * 
      * *
    * *

    Another provider may implement a class for each of the above modes * (i.e., one class for ECB, one for CBC, one for CFB, * and one for OFB), one class for PKCS5Padding, * and a generic DES class that subclasses from CipherSpi. * That provider would have the following * Cipher properties in its master class:

    * *

      * *
    • *
       *    Cipher.DES
       * 
      * *
    * *

    The getInstance factory method of the Cipher * engine class follows these rules in order to instantiate a provider's * implementation of CipherSpi for a * transformation of the form "algorithm": * *

      *
    1. * Check if the provider has registered a subclass of CipherSpi * for the specified "algorithm". *

      If the answer is YES, instantiate this * class, for whose mode and padding scheme default values (as supplied by * the provider) are used. *

      If the answer is NO, throw a NoSuchAlgorithmException * exception. *

    * *

    The getInstance factory method of the Cipher * engine class follows these rules in order to instantiate a provider's * implementation of CipherSpi for a * transformation of the form "algorithm/mode/padding": * *

      *
    1. * Check if the provider has registered a subclass of CipherSpi * for the specified "algorithm/mode/padding" transformation. *

      If the answer is YES, instantiate it. *

      If the answer is NO, go to the next step.

      *

    2. * Check if the provider has registered a subclass of CipherSpi * for the sub-transformation "algorithm/mode". *

      If the answer is YES, instantiate it, and call * engineSetPadding(padding) on the new instance. *

      If the answer is NO, go to the next step.

      *

    3. * Check if the provider has registered a subclass of CipherSpi * for the sub-transformation "algorithm//padding" (note the double * slashes). *

      If the answer is YES, instantiate it, and call * engineSetMode(mode) on the new instance. *

      If the answer is NO, go to the next step.

      *

    4. * Check if the provider has registered a subclass of CipherSpi * for the sub-transformation "algorithm". *

      If the answer is YES, instantiate it, and call * engineSetMode(mode) and * engineSetPadding(padding) on the new instance. *

      If the answer is NO, throw a NoSuchAlgorithmException * exception. *

    * * @see KeyGenerator * @see SecretKey */ public abstract class CipherSpi { public CipherSpi() { } /** * Sets the mode of this cipher. * * @param mode the cipher mode * @exception NoSuchAlgorithmException if the requested cipher mode does not exist */ protected abstract void engineSetMode( String mode) throws NoSuchAlgorithmException; /** * Sets the padding mechanism of this cipher. * * @param padding the padding mechanism * @exception NoSuchPaddingException if the requested padding mechanism does not exist */ protected abstract void engineSetPadding( String padding) throws NoSuchPaddingException; /** * Returns the block size (in bytes). * * @return the block size (in bytes), or 0 if the underlying algorithm is not a block cipher */ protected abstract int engineGetBlockSize(); /** * Returns the length in bytes that an output buffer would * need to be in order to hold the result of the next update * or doFinal operation, given the input length * inputLen (in bytes). *

    * This call takes into account any unprocessed (buffered) data from a * previous update call, and padding. *

    * The actual output length of the next update or * doFinal call may be smaller than the length returned by * this method. * * @param inputLen the input length (in bytes) * @return the required output buffer size (in bytes) */ protected abstract int engineGetOutputSize( int inputLen); /** * Returns the initialization vector (IV) in a new buffer. *

    * This is useful in the context of password-based encryption or * decryption, where the IV is derived from a user-provided passphrase. * * @return the initialization vector in a new buffer, or null if the * underlying algorithm does not use an IV, or if the IV has not yet * been set. */ protected abstract byte[] engineGetIV(); /** * Returns the parameters used with this cipher. *

    * The returned parameters may be the same that were used to initialize * this cipher, or may contain a combination of default and random * parameter values used by the underlying cipher implementation if this * cipher requires algorithm parameters but was not initialized with any. * * @return the parameters used with this cipher, or null if this cipher * does not use any parameters. */ protected abstract AlgorithmParameters engineGetParameters(); /** * Initializes this cipher with a key and a source * of randomness. *

    * The cipher is initialized for one of the following four operations: * encryption, decryption, key wrapping or key unwrapping, depending on * the value of opmode. *

    * If this cipher requires any algorithm parameters that cannot be * derived from the given key, the underlying cipher * implementation is supposed to generate the required parameters itself * (using provider-specific default or random values) if it is being * initialized for encryption or key wrapping, and raise an * InvalidKeyException if it is being * initialized for decryption or key unwrapping. * The generated parameters can be retrieved using * engineGetParameters or * engineGetIV (if the parameter is an IV). *

    * If this cipher (including its underlying feedback or padding scheme) * requires any random bytes (e.g., for parameter generation), it will get * them from random. * *

    Note that when a Cipher object is initialized, it loses all * previously-acquired state. In other words, initializing a Cipher is * equivalent to creating a new instance of that Cipher and initializing * it. * @param opmode the operation mode of this cipher (this is one of * the following: * ENCRYPT_MODE, DECRYPT_MODE, * WRAP_MODE or UNWRAP_MODE) * @param key the encryption key * @param random the source of randomness * @exception InvalidKeyException if the given key is inappropriate for * initializing this cipher, or if this cipher is being initialized for * decryption and requires algorithm parameters that cannot be * determined from the given key. */ protected abstract void engineInit( int opmode, Key key, SecureRandom random) throws InvalidKeyException; /** * Initializes this cipher with a key, a set of * algorithm parameters, and a source of randomness. *

    * The cipher is initialized for one of the following four operations: * encryption, decryption, key wrapping or key unwrapping, depending on * the value of opmode. *

    * If this cipher requires any algorithm parameters and * params is null, the underlying cipher implementation is * supposed to generate the required parameters itself (using * provider-specific default or random values) if it is being * initialized for encryption or key wrapping, and raise an * InvalidAlgorithmParameterException if it is being * initialized for decryption or key unwrapping. * The generated parameters can be retrieved using * engineGetParameters or * engineGetIV (if the parameter is an IV). *

    * If this cipher (including its underlying feedback or padding scheme) * requires any random bytes (e.g., for parameter generation), it will get * them from random. *

    * Note that when a Cipher object is initialized, it loses all * previously-acquired state. In other words, initializing a Cipher is * equivalent to creating a new instance of that Cipher and initializing * it. * * @param opmode the operation mode of this cipher (this is one of the following: * ENCRYPT_MODE, DECRYPT_MODE, * WRAP_MODE or UNWRAP_MODE) * @param key the encryption key * @param params the algorithm parameters * @param random the source of randomness * @exception InvalidKeyException if the given key is inappropriate for initializing this cipher * @exception InvalidAlgorithmParameterException if the given algorithm parameters are inappropriate * for this cipher, or if this cipher is being initialized for decryption and requires * algorithm parameters and params is null. */ protected abstract void engineInit( int opmode, Key key, AlgorithmParameterSpec params, SecureRandom random) throws InvalidKeyException, InvalidAlgorithmParameterException; /** * Initializes this cipher with a key, a set of * algorithm parameters, and a source of randomness. *

    * The cipher is initialized for one of the following four operations: * encryption, decryption, key wrapping or key unwrapping, depending on * the value of opmode. *

    * If this cipher requires any algorithm parameters and * params is null, the underlying cipher implementation is * supposed to generate the required parameters itself (using * provider-specific default or random values) if it is being * initialized for encryption or key wrapping, and raise an * InvalidAlgorithmParameterException if it is being * initialized for decryption or key unwrapping. * The generated parameters can be retrieved using * engineGetParameters or * engineGetIV (if the parameter is an IV). *

    * If this cipher (including its underlying feedback or padding scheme) * requires any random bytes (e.g., for parameter generation), it will get * them from random. *

    * Note that when a Cipher object is initialized, it loses all * previously-acquired state. In other words, initializing a Cipher is * equivalent to creating a new instance of that Cipher and initializing it. * * @param opmode the operation mode of this cipher (this is one of the following: * ENCRYPT_MODE, DECRYPT_MODE, WRAP_MODE * or UNWRAP_MODE) * @param key the encryption key * @param params the algorithm parameters * @param random the source of randomness * @exception InvalidKeyException if the given key is inappropriate for initializing this cipher * @exception InvalidAlgorithmParameterException if the given algorithm parameters are inappropriate * for this cipher, or if this cipher is being initialized for decryption and requires * algorithm parameters and params is null. */ protected abstract void engineInit( int opmode, Key key, AlgorithmParameters params, SecureRandom random) throws InvalidKeyException, InvalidAlgorithmParameterException; /** * Continues a multiple-part encryption or decryption operation * (depending on how this cipher was initialized), processing another data * part. *

    * The first inputLen bytes in the input * buffer, starting at inputOffset inclusive, are processed, * and the result is stored in a new buffer. * * @param input the input buffer * @param inputOffset the offset in input where the input starts * @param inputLen the input length * @return the new buffer with the result, or null if the underlying cipher is a * block cipher and the input data is too short to result in a new block. */ protected abstract byte[] engineUpdate( byte[] input, int inputOffset, int inputLen); /** * Continues a multiple-part encryption or decryption operation * (depending on how this cipher was initialized), processing another data * part. *

    * The first inputLen bytes in the input * buffer, starting at inputOffset inclusive, are processed, * and the result is stored in the output buffer, starting at * outputOffset inclusive. *

    * If the output buffer is too small to hold the result, * a ShortBufferException is thrown. * * @param input the input buffer * @param inputOffset the offset in input where the input starts * @param inputLen the input length * @param output the buffer for the result * @param outputOffset the offset in output where the result is stored * @return the number of bytes stored in output * @exception ShortBufferException if the given output buffer is too small to hold the result */ protected abstract int engineUpdate( byte[] input, int inputOffset, int inputLen, byte[] output, int outputOffset) throws ShortBufferException; /** * Encrypts or decrypts data in a single-part operation, or finishes a multiple-part operation. * The data is encrypted or decrypted, depending on how this cipher was initialized. *

    * The first inputLen bytes in the input * buffer, starting at inputOffset inclusive, and any input * bytes that may have been buffered during a previous update * operation, are processed, with padding (if requested) being applied. * The result is stored in a new buffer. *

    * A call to this method resets this cipher object to the state * it was in when previously initialized via a call to engineInit. * That is, the object is reset and available to encrypt or decrypt * (depending on the operation mode that was specified in the call to * engineInit) more data. * * @param input the input buffer * @param inputOffset the offset in input where the input starts * @param inputLen the input length * @return the new buffer with the result * @exception IllegalBlockSizeException if this cipher is a block cipher, no padding has been requested * (only in encryption mode), and the total input length of the data processed by this cipher is not a * multiple of block size * @exception BadPaddingException if this cipher is in decryption mode, and (un)padding has been requested, * but the decrypted data is not bounded by the appropriate padding bytes */ protected abstract byte[] engineDoFinal( byte[] input, int inputOffset, int inputLen) throws IllegalBlockSizeException, BadPaddingException; /** * Encrypts or decrypts data in a single-part operation, * or finishes a multiple-part operation. * The data is encrypted or decrypted, depending on how this cipher was * initialized. *

    * The first inputLen bytes in the input * buffer, starting at inputOffset inclusive, and any input * bytes that may have been buffered during a previous update * operation, are processed, with padding (if requested) being applied. * The result is stored in the output buffer, starting at * outputOffset inclusive. *

    * If the output buffer is too small to hold the result, * a ShortBufferException is thrown. *

    * A call to this method resets this cipher object to the state * it was in when previously initialized via a call to * engineInit. * That is, the object is reset and available to encrypt or decrypt * (depending on the operation mode that was specified in the call to * engineInit) more data. * * @param input the input buffer * @param inputOffset the offset in input where the input starts * @param inputLen the input length * @param output the buffer for the result * @param outputOffset the offset in output where the result is stored * @return the number of bytes stored in output * @exception IllegalBlockSizeException if this cipher is a block cipher, no padding has been * requested (only in encryption mode), and the total input length of the data processed by this * cipher is not a multiple of block size * @exception ShortBufferException if the given output buffer is too small to hold the result * @exception BadPaddingException if this cipher is in decryption mode, and (un)padding has been requested, * but the decrypted data is not bounded by the appropriate padding bytes */ protected abstract int engineDoFinal( byte[] input, int inputOffset, int inputLen, byte[] output, int outputOffset) throws ShortBufferException, IllegalBlockSizeException, BadPaddingException; /** * Wrap a key. *

    * This concrete method has been added to this previously-defined * abstract class. (For backwards compatibility, it cannot be abstract.) * It may be overridden by a provider to wrap a key. * Such an override is expected to throw an IllegalBlockSizeException or * InvalidKeyException (under the specified circumstances), * if the given key cannot be wrapped. * If this method is not overridden, it always throws an * UnsupportedOperationException. * * @param key the key to be wrapped. * @return the wrapped key. * @exception IllegalBlockSizeException if this cipher is a block cipher, no padding has been requested, * and the length of the encoding of the key to be wrapped is not a multiple of the block size. * @exception InvalidKeyException if it is impossible or unsafe to wrap the key with this cipher (e.g., * a hardware protected key is being passed to a software-only cipher). */ protected byte[] engineWrap( Key key) throws IllegalBlockSizeException, InvalidKeyException { throw new UnsupportedOperationException("Underlying cipher does not support key wrapping"); } /** * Unwrap a previously wrapped key. * *

    This concrete method has been added to this previously-defined * abstract class. (For backwards compatibility, it cannot be abstract.) * It may be overridden by a provider to unwrap a previously wrapped key. * Such an override is expected to throw an InvalidKeyException if * the given wrapped key cannot be unwrapped. * If this method is not overridden, it always throws an * UnsupportedOperationException. * * @param wrappedKey the key to be unwrapped. * @param wrappedKeyAlgorithm the algorithm associated with the wrapped key. * @param wrappedKeyType the type of the wrapped key. This is one of SECRET_KEY, * PRIVATE_KEY, or PUBLIC_KEY. * @return the unwrapped key. * @exception InvalidKeyException if wrappedKey does not represent a wrapped key, * or if the algorithm associated with the wrapped key is different from wrappedKeyAlgorithm * and/or its key type is different from wrappedKeyType. * @exception NoSuchAlgorithmException - if no installed providers can create keys for the * wrappedKeyAlgorithm. */ protected java.security.Key engineUnwrap( byte[] wrappedKey, String wrappedKeyAlgorithm, int wrappedKeyType) throws InvalidKeyException, NoSuchAlgorithmException { throw new UnsupportedOperationException("Underlying cipher does not support key unwrapping"); } /** * Returns the key size of the given key object. *

    * This concrete method has been added to this previously-defined * abstract class. It throws an UnsupportedOperationException * if it is not overridden by the provider. * * @param key the key object. * @return the key size of the given key object. * @exception InvalidKeyException if key is invalid. */ protected int engineGetKeySize( Key key) throws InvalidKeyException { throw new UnsupportedOperationException("Key size unavailable"); } } bouncycastle-1.49.orig/jce/src/javax/crypto/Mac.java0000644000175000017500000003500211062413470021753 0ustar ebourgebourgpackage javax.crypto; import java.security.Provider; import java.security.Key; import java.security.InvalidKeyException; import java.security.NoSuchAlgorithmException; import java.security.NoSuchProviderException; import java.security.spec.AlgorithmParameterSpec; import java.security.InvalidAlgorithmParameterException; /** * This class provides the functionality of a "Message Authentication Code" * (MAC) algorithm. *

    * A MAC provides a way to check the integrity of information transmitted over * or stored in an unreliable medium, based on a secret key. Typically, message * authentication codes are used between two parties that share a secret * key in order to validate information transmitted between these * parties. *

    * A MAC mechanism that is based on cryptographic hash functions is * referred to as HMAC. HMAC can be used with any cryptographic hash function, * e.g., MD5 or SHA-1, in combination with a secret shared key. HMAC is * specified in RFC 2104. */ public class Mac implements Cloneable { MacSpi macSpi; Provider provider; String algorithm; private boolean initialised = false; /** * Creates a MAC object. * * @param macSpi the delegate * @param provider the provider * @param algorithm the algorithm */ protected Mac( MacSpi macSpi, Provider provider, String algorithm) { this.macSpi = macSpi; this.provider = provider; this.algorithm = algorithm; } /** * Returns the algorithm name of this Mac object. *

    * This is the same name that was specified in one of the * getInstance calls that created this Mac object. * * @return the algorithm name of this Mac object. */ public final String getAlgorithm() { return algorithm; } /** * Generates an Mac object that implements the * specified MAC algorithm. * If the default provider package provides an implementation of the * requested MAC algorithm, an instance of * Mac containing that implementation is returned. * If the algorithm is not available in the default provider package, * other provider packages are searched. * * @param algorithm the standard name of the requested MAC algorithm. * See Appendix A in the Java Cryptography Extension API Specification & Reference * for information about standard algorithm names. * @return the new Mac object. * @exception NoSuchAlgorithmException if the specified algorithm is not * available in the default provider package or any of the other provider * packages that were searched. */ public static final Mac getInstance( String algorithm) throws NoSuchAlgorithmException { try { JCEUtil.Implementation imp = JCEUtil.getImplementation("Mac", algorithm, (String) null); if (imp == null) { throw new NoSuchAlgorithmException(algorithm + " not found"); } Mac mac = new Mac((MacSpi)imp.getEngine(), imp.getProvider(), algorithm); return mac; } catch (NoSuchProviderException e) { throw new NoSuchAlgorithmException(algorithm + " not found"); } } /** * Generates an Mac object for the specified MAC * algorithm from the specified provider. * * @param algorithm the standard name of the requested MAC algorithm. * See Appendix A in the Java Cryptography Extension API Specification & Reference * for information about standard algorithm names. * @param provider the name of the provider. * @return the new Mac object. * @exception NoSuchAlgorithmException if the specified algorithm is not available from the * specified provider. * @exception NoSuchProviderException if the specified provider has not been configured. */ public static final Mac getInstance( String algorithm, String provider) throws NoSuchAlgorithmException, NoSuchProviderException { if (provider == null) { throw new IllegalArgumentException("No provider specified to Mac.getInstance()"); } JCEUtil.Implementation imp = JCEUtil.getImplementation("Mac", algorithm, provider); if (imp == null) { throw new NoSuchAlgorithmException(algorithm + " not found"); } Mac mac = new Mac((MacSpi)imp.getEngine(), imp.getProvider(), algorithm); return mac; } /** * Generates an Mac object for the specified MAC * algorithm from the specified provider. * * @param algorithm the standard name of the requested MAC algorithm. * See Appendix A in the Java Cryptography Extension API Specification & Reference * for information about standard algorithm names. * @param provider the provider. * @return the new Mac object. * @exception NoSuchAlgorithmException if the specified algorithm is not available from the * specified provider. */ public static final Mac getInstance( String algorithm, Provider provider) throws NoSuchAlgorithmException { if (provider == null) { throw new IllegalArgumentException("No provider specified to Mac.getInstance()"); } JCEUtil.Implementation imp = JCEUtil.getImplementation("Mac", algorithm, provider); if (imp == null) { throw new NoSuchAlgorithmException(algorithm + " not found"); } Mac mac = new Mac((MacSpi)imp.getEngine(), imp.getProvider(), algorithm); return mac; } /** * Returns the provider of this Mac object. * * @return the provider of this Mac object. */ public final Provider getProvider() { return provider; } /** * Returns the length of the MAC in bytes. * * @return the MAC length in bytes. */ public final int getMacLength() { return macSpi.engineGetMacLength(); } /** * Initializes this Mac object with the given key. * * @param key the key. * @exception InvalidKeyException if the given key is inappropriate for initializing this MAC. */ public final void init( Key key) throws InvalidKeyException { try { macSpi.engineInit(key, null); initialised = true; } catch (InvalidAlgorithmParameterException e) { throw new IllegalArgumentException("underlying mac waon't work without an AlgorithmParameterSpec"); } } /** * Initializes this Mac object with the given key and * algorithm parameters. * * @param key the key. * @param params the algorithm parameters. * @exception InvalidKeyException if the given key is inappropriate for initializing this MAC. * @exception InvalidAlgorithmParameterException if the given algorithm parameters are inappropriate * for this MAC. */ public final void init( Key key, AlgorithmParameterSpec params) throws InvalidKeyException, InvalidAlgorithmParameterException { macSpi.engineInit(key, params); initialised = true; } /** * Processes the given byte. * * @param input the input byte to be processed. * @exception IllegalStateException if this Mac has not been initialized. */ public final void update( byte input) throws IllegalStateException { if (!initialised) { throw new IllegalStateException("MAC not initialised"); } macSpi.engineUpdate(input); } /** * Processes the given array of bytes. * * @param input the array of bytes to be processed. * @exception IllegalStateException if this Mac has not been initialized. */ public final void update( byte[] input) throws IllegalStateException { if (!initialised) { throw new IllegalStateException("MAC not initialised"); } if (input == null) { return; } macSpi.engineUpdate(input, 0, input.length); } /** * Processes the first len bytes in input, * starting at offset inclusive. * * @param input the input buffer. * @param offset the offset in input where the input starts. * @param len the number of bytes to process. * @exception IllegalStateException if this Mac has not been initialized. */ public final void update( byte[] input, int offset, int len) throws IllegalStateException { if (!initialised) { throw new IllegalStateException("MAC not initialised"); } if (input == null) { throw new IllegalArgumentException("Null input passed"); } if (len < 0 || offset < 0 || len > (input.length - offset)) { throw new IllegalArgumentException("Bad offset/len"); } if (input.length == 0) { return; } macSpi.engineUpdate(input, offset, len); } /** * Finishes the MAC operation. *

    * A call to this method resets this Mac object to the * state it was in when previously initialized via a call to init(Key) or * init(Key, AlgorithmParameterSpec). * That is, the object is reset and available to generate another MAC from * the same key, if desired, via new calls to update and * doFinal. * (In order to reuse this Mac object with a different key, * it must be reinitialized via a call to init(Key) or * init(Key, AlgorithmParameterSpec). * * @return the MAC result. * @exception IllegalStateException if this Mac has not been initialized. */ public final byte[] doFinal() throws IllegalStateException { if (!initialised) { throw new IllegalStateException("MAC not initialised"); } return macSpi.engineDoFinal(); } /** * Finishes the MAC operation. * *

    A call to this method resets this Mac object to the * state it was in when previously initialized via a call to * init(Key) or * init(Key, AlgorithmParameterSpec). * That is, the object is reset and available to generate another MAC from * the same key, if desired, via new calls to update and * doFinal. * (In order to reuse this Mac object with a different key, * it must be reinitialized via a call to init(Key) or * init(Key, AlgorithmParameterSpec). *

    * The MAC result is stored in output, starting at * outOffset inclusive. * * @param output the buffer where the MAC result is stored * @param outOffset the offset in output where the MAC is stored * @exception ShortBufferException if the given output buffer is too small to hold the result * @exception IllegalStateException if this Mac has not been initialized. */ public final void doFinal( byte[] output, int outOffset) throws ShortBufferException, IllegalStateException { if (!initialised) { throw new IllegalStateException("MAC not initialised"); } if ((output.length - outOffset) < macSpi.engineGetMacLength()) { throw new ShortBufferException("buffer to short for MAC output"); } byte[] mac = macSpi.engineDoFinal(); System.arraycopy(mac, 0, output, outOffset, mac.length); } /** * Processes the given array of bytes and finishes the MAC operation. *

    * A call to this method resets this Mac object to the * state it was in when previously initialized via a call to init(Key) or * init(Key, AlgorithmParameterSpec). That is, the object is reset and * available to generate another MAC from the same key, if desired, via new calls to * update and doFinal. * (In order to reuse this Mac object with a different key, * it must be reinitialized via a call to init(Key) or * init(Key, AlgorithmParameterSpec). * * @return the MAC result. * @exception IllegalStateException if this Mac has not been initialized. */ public final byte[] doFinal( byte[] input) throws IllegalStateException { if (!initialised) { throw new IllegalStateException("MAC not initialised"); } macSpi.engineUpdate(input, 0, input.length); return macSpi.engineDoFinal(); } /** * Resets this Mac object. *

    * A call to this method resets this Mac object to the * state it was in when previously initialized via a call to * init(Key) or init(Key, AlgorithmParameterSpec). * That is, the object is reset and available to generate another MAC from * the same key, if desired, via new calls to update and * doFinal. * (In order to reuse this Mac object with a different key, * it must be reinitialized via a call to init(Key) or * init(Key, AlgorithmParameterSpec). */ public final void reset() { macSpi.engineReset(); } /** * Returns a clone if the provider implementation is cloneable. * * @return a clone if the provider implementation is cloneable. * @exception CloneNotSupportedException if this is called on a delegate that does * not support Cloneable. */ public final Object clone() throws CloneNotSupportedException { Mac result = new Mac((MacSpi)macSpi.clone(), provider, algorithm); result.initialised = initialised; return result; } } bouncycastle-1.49.orig/jce/src/javax/crypto/KeyGenerator.java0000644000175000017500000002630511062413502023654 0ustar ebourgebourgpackage javax.crypto; import java.security.InvalidAlgorithmParameterException; import java.security.NoSuchAlgorithmException; import java.security.NoSuchProviderException; import java.security.Provider; import java.security.SecureRandom; import java.security.spec.AlgorithmParameterSpec; /** * This class provides the functionality of a (symmetric) key generator. *

    * Key generators are constructed using one of the getInstance * class methods of this class. *

    * KeyGenerator objects are reusable, i.e., after a key has been * generated, the same KeyGenerator object can be re-used to generate further * keys. *

    * There are two ways to generate a key: in an algorithm-independent manner, * and in an algorithm-specific manner. The only difference between the two is * the initialization of the object: * *

      *
    • Algorithm-Independent Initialization *

      All key generators share the concepts of a keysize and a * source of randomness. * There is an * init * method in this KeyGenerator class that takes these two universally * shared types of arguments. There is also one that takes just a * keysize argument, and uses the SecureRandom implementation * of the highest-priority installed provider as the source of randomness * (or a system-provided source of randomness if none of the installed * providers supply a SecureRandom implementation), and one that takes just a * source of randomness. *

      * Since no other parameters are specified when you call the above * algorithm-independent init methods, it is up to the * provider what to do about the algorithm-specific parameters (if any) to be * associated with each of the keys. *

      *

    • Algorithm-Specific Initialization *

      For situations where a set of algorithm-specific parameters already * exists, there are two * init * methods that have an AlgorithmParameterSpec * argument. One also has a SecureRandom argument, while the * other uses the SecureRandom implementation * of the highest-priority installed provider as the source of randomness * (or a system-provided source of randomness if none of the installed * providers supply a SecureRandom implementation). *

    * *

    In case the client does not explicitly initialize the KeyGenerator * (via a call to an init method), each provider must * supply (and document) a default initialization. * * @see SecretKey */ public class KeyGenerator { private KeyGeneratorSpi keyGenerator; private Provider provider; private String algorithm; /** * Creates a KeyGenerator object. * * @param keyGenSpi the delegate * @param provider the provider * @param algorithm the algorithm */ protected KeyGenerator( KeyGeneratorSpi keyGenSpi, Provider provider, String algorithm) { this.keyGenerator = keyGenSpi; this.provider = provider; this.algorithm = algorithm; } /** * Returns the algorithm name of this KeyGenerator object. *

    * This is the same name that was specified in one of the * getInstance calls that created this * KeyGenerator object. * * @return the algorithm name of this KeyGenerator object. */ public final String getAlgorithm() { return algorithm; } /** * Generates a KeyGenerator object for the specified algorithm. * If the default provider package provides an implementation of the * requested key generator, an instance of KeyGenerator containing * that implementation is returned. If the requested key generator is not available * in the default provider package, other provider packages are searched. * * @param algorithm the standard name of the requested key algorithm. See Appendix A in the * Java Cryptography Extension API Specification & Reference for information about standard * algorithm names. * @return the new KeyGenerator object * @exception NoSuchAlgorithmException if a key generator for the specified algorithm is not * available in the default provider package or any of the other provider packages that were searched. */ public static final KeyGenerator getInstance( String algorithm) throws NoSuchAlgorithmException { try { JCEUtil.Implementation imp = JCEUtil.getImplementation("KeyGenerator", algorithm, (String) null); if (imp == null) { throw new NoSuchAlgorithmException(algorithm + " not found"); } KeyGenerator keyGen = new KeyGenerator((KeyGeneratorSpi)imp.getEngine(), imp.getProvider(), algorithm); return keyGen; } catch (NoSuchProviderException e) { throw new NoSuchAlgorithmException(algorithm + " not found"); } } /** * Generates a KeyGenerator object for the specified key * algorithm from the specified provider. * * @param algorithm the standard name of the requested key algorithm. See Appendix A in the * Java Cryptography Extension API Specification & Reference for information about standard * algorithm names. * @param provider the provider * @return the new KeyGenerator object * @exception NoSuchAlgorithmException if a key generator for the specified algorithm is not * available from the specified provider. */ public static final KeyGenerator getInstance( String algorithm, Provider provider) throws NoSuchAlgorithmException { if (provider == null) { throw new IllegalArgumentException("No provider specified to KeyGenerator.getInstance()"); } JCEUtil.Implementation imp = JCEUtil.getImplementation("KeyGenerator", algorithm, provider); if (imp == null) { throw new NoSuchAlgorithmException(algorithm + " not found"); } KeyGenerator keyGen = new KeyGenerator((KeyGeneratorSpi)imp.getEngine(), imp.getProvider(), algorithm); return keyGen; } /** * Generates a KeyGenerator object for the specified key * algorithm from the specified provider. * * @param algorithm the standard name of the requested key algorithm. See Appendix A in the * Java Cryptography Extension API Specification & Reference for information about standard * algorithm names. * @param provider the name of the provider * @return the new KeyGenerator object * @exception NoSuchAlgorithmException if a key generator for the specified algorithm is not * available from the specified provider. * @exception NoSuchProviderException if the specified provider has not been configured. */ public static final KeyGenerator getInstance( String algorithm, String provider) throws NoSuchAlgorithmException, NoSuchProviderException { if (provider == null) { throw new IllegalArgumentException("No provider specified to KeyGenerator.getInstance()"); } JCEUtil.Implementation imp = JCEUtil.getImplementation("KeyGenerator", algorithm, provider); if (imp == null) { throw new NoSuchAlgorithmException(algorithm + " not found"); } KeyGenerator keyGen = new KeyGenerator((KeyGeneratorSpi)imp.getEngine(), imp.getProvider(), algorithm); return keyGen; } /** * Returns the provider of this KeyGenerator object. * * @return the provider of this KeyGenerator object */ public final Provider getProvider() { return provider; } /** * Initializes this key generator. * * @param random the source of randomness for this generator */ public final void init( SecureRandom random) { keyGenerator.engineInit(random); } /** * Initializes this key generator with the specified parameter set. *

    * If this key generator requires any random bytes, it will get them * using the * * SecureRandom implementation of the highest-priority installed * provider as the source of randomness. * (If none of the installed providers supply an implementation of * SecureRandom, a system-provided source of randomness will be used.) * * @param params the key generation parameters * @exception InvalidAlgorithmParameterException if the given parameters are inappropriate * for this key generator */ public final void init( AlgorithmParameterSpec params) throws InvalidAlgorithmParameterException { keyGenerator.engineInit(params, new SecureRandom()); } /** * Initializes this key generator with the specified parameter set and a user-provided source of randomness. * * @param params the key generation parameters * @param random the source of randomness for this key generator * @exception InvalidAlgorithmParameterException if params is inappropriate for this key generator */ public final void init( AlgorithmParameterSpec params, SecureRandom random) throws InvalidAlgorithmParameterException { keyGenerator.engineInit(params, random); } /** * Initializes this key generator for a certain keysize. *

    * If this key generator requires any random bytes, it will get them using the * * SecureRandom implementation of the highest-priority installed provider as * the source of randomness. (If none of the installed providers supply an implementation of * SecureRandom, a system-provided source of randomness will be used.) * * @param keysize the keysize. This is an algorithm-specific metric, specified in number of bits. * @exception InvalidParameterException if the keysize is wrong or not supported. */ public final void init( int keysize) { keyGenerator.engineInit(keysize, new SecureRandom()); } /** * Initializes this key generator for a certain keysize, using a user-provided source of randomness. * * @param keysize the keysize. This is an algorithm-specific metric, specified in number of bits. * @param random the source of randomness for this key generator * @exception InvalidParameterException if the keysize is wrong or not supported. */ public final void init( int keysize, SecureRandom random) { keyGenerator.engineInit(keysize, random); } /** * Generates a secret key. * * @return the new key */ public final SecretKey generateKey() { return keyGenerator.engineGenerateKey(); } } bouncycastle-1.49.orig/bc-build.properties0000644000175000017500000000007512152003154020223 0ustar ebourgebourg release.suffix: 149 release.name: 1.49 release.debug: false bouncycastle-1.49.orig/zips/0000755000175000017500000000000012152022376015416 5ustar ebourgebourgbouncycastle-1.49.orig/specifications.html0000644000175000017500000010615712152004574020334 0ustar ebourgebourg Bouncy Castle Crypto Package

    Bouncy Castle Crypto Package

    
    

    1.0 Introduction

    The Bouncy Castle Crypto package is a Java implementation of cryptographic algorithms. The package is organised so that it contains a light-weight API suitable for use in any environment (including the newly released J2ME) with the additional infrastructure to conform the algorithms to the JCE framework.

    Except where otherwise stated, this software is distributed under a license based on the MIT X Consortium license. To view the license, see here. The OpenPGP library also includes a modified BZIP2 library which is licensed under the Apache Software License, Version 2.0.

    If you have the full package you will have six jar files, bcprov*.jar which contains the BC provider, jce-*.jar which contains the JCE provider, clean room API, and bcmail*.jar which contains the mail API.

    Note: if you are using JDK 1.0, you will just find a class hierarchy in the classes directory.

    To view examples, look at the test programs in the packages:

    • org.bouncycastle.crypto.test
    • org.bouncycastle.jce.provider.test

    To verify the packages, run the following Java programs with the appropriate classpath:

    • java org.bouncycastle.crypto.test.RegressionTest
    • java org.bouncycastle.jce.provider.test.RegressionTest

    2.0 Patents

    Some of the algorithms in the Bouncy Castle APIs are patented in some places. It is upon the user of the library to be aware of what the legal situation is in their own situation, however we have been asked to specifically mention the patent below, in the following terms, at the request of the patent holder. Algorithms that appear here are only distributed in the -ext- versions of the provider.

    The IDEA encryption algorithm is patented in the USA, Japan, and Europe including at least Austria, France, Germany, Italy, Netherlands, Spain, Sweden, Switzerland and the United Kingdom. Non-commercial use is free, however any commercial products that make use of IDEA are liable for royalties. Please see www.mediacrypt.com for further details.

    3.0 Specifications

    • clean room implementation of the JCE API
    • light-weight cryptographic API consisting of support for
      • BlockCipher
      • BufferedBlockCipher
      • AsymmetricBlockCipher
      • BufferedAsymmetricBlockCipher
      • StreamCipher
      • BufferedStreamCipher
      • KeyAgreement
      • IESCipher
      • Digest
      • Mac
      • PBE
      • Signers
    • JCE compatible framework for a Bouncy Castle provider

    4.0 Light-weight API

    This API has been specifically developed for those circumstances where the rich API and integration requirements of the JCE are not required.

    However as a result, the light-weight API requires more effort and understanding on the part of a developer to initialise and utilise the algorithms.

    4.1 Example

    To utilise the light-weight API in a program, the fundamentals are as follows;

    
    	/*
    	 * This will use a supplied key, and encrypt the data
    	 * This is the equivalent of DES/CBC/PKCS5Padding
    	 */
    	BlockCipher engine = new DESEngine();
    	BufferedBlockCipher cipher = new PaddedBlockCipher(new CBCCipher(engine));
    
    	byte[] key = keyString.getBytes();
    	byte[] input = inputString.getBytes();
    
    	cipher.init(true, new KeyParameter(key));
    
    	byte[] cipherText = new byte[cipher.getOutputSize(input.length)];
    	
    	int outputLen = cipher.processBytes(input, 0, input.length, cipherText, 0);
    	try
    	{
    		cipher.doFinal(cipherText, outputLen);
    	}
    	catch (CryptoException ce)
    	{
    		System.err.println(ce);
    		System.exit(1);
    	}
    
    

    4.2 Algorithms

    The light-weight API has built in support for the following:

    Symmetric (Block)

    The base interface is BlockCipher and has the following implementations which match the modes the block cipher can be operated in.

    NameConstructorNotes
    BufferedBlockCipherBlockCipher 
    CBCBlockCipherBlockCipher 
    CFBBlockCipherBlockCipher, block size (in bits) 
    CCMBlockCipherBlockCipherPacket mode - requires all data up front.
    GCMBlockCipherBlockCipherPacket mode - NIST SP 800-38D.
    EAXBlockCipherBlockCipher 
    OFBBlockCipherBlockCipher, block size (in bits) 
    SICBlockCipherBlockCipher, block size (in bits)Also known as CTR mode
    OpenPGPCFBBlockCipherBlockCipher 
    GOFBBlockCipherBlockCipherGOST OFB mode

    BufferedBlockCipher has a further sub-classes

    NameConstructorNotes
    PaddedBufferedBlockCipherBlockCiphera buffered block cipher that can use padding - default PKCS5/7 padding
    CTSBlockCipherBlockCipherCipher Text Stealing

    The following paddings can be used with the PaddedBufferedBlockCipher.

    NameDescription
    PKCS7PaddingPKCS7/PKCS5 padding
    ISO10126d2PaddingISO 10126-2 padding
    X932PaddingX9.23 padding
    ISO7816d4PaddingISO 7816-4 padding (ISO 9797-1 scheme 2)
    ZeroBytePaddingPad with Zeros (not recommended)

    The following cipher engines are implemented that can be used with the above modes.

    NameKeySizes (in bits) Block SizeNotes
    AESEngine0 .. 256 128 bit 
    AESWrapEngine0 .. 256 128 bitImplements FIPS AES key wrapping
    BlowfishEngine0 .. 448 64 bit 
    CamelliaEngine128, 192, 256128 bit 
    CamelliaWrapEngine128, 192, 256128 bit 
    CAST5Engine0 .. 128 64 bit 
    CAST6Engine0 .. 256 128 bit 
    DESEngine6464 bit 
    DESedeEngine128, 19264 bit 
    DESedeWrapEngine128, 19264 bitImplements Draft IETF DESede key wrapping
    GOST28147Engine25664 bitHas a range of S-boxes
    IDEAEngine12864 bit 
    NoekeonEngine128128 bit 
    RC2Engine0 .. 1024 64 bit 
    RC532Engine0 .. 128 64 bitUses a 32 bit word
    RC564Engine0 .. 128 128 bitUses a 64 bit word
    RC6Engine0 .. 256 128 bit 
    RijndaelEngine0 .. 256 128 bit, 160 bit, 192 bit, 224 bit, 256 bit 
    SEEDEngine128128 bit 
    SEEDWrapEngine128128 bit 
    SerpentEngine128, 192, 256 128 bit 
    SkipjackEngine0 .. 128 64 bit 
    TEAEngine12864 bit 
    TwofishEngine128, 192, 256 128 bit 
    XTEAEngine12864 bit 

    Symmetric (Stream)

    The base interface is StreamCipher and has the following implementations which match the modes the stream cipher can be operated in.

    NameConstructorNotes
    BlockStreamCipherBlockCipher 

    The following cipher engines are implemented that can be used with the above modes.

    NameKeySizes (in bits) Notes
    RC4Engine40 .. 2048 
    HC128Engine128 
    HC256Engine256 
    Salsa20Engine128/256 
    ISAACEngine32 .. 8192 
    VMPCEngine8 .. 6144 
    Grainv1Engine8064 bit IV
    Grain128Engine12896 bit IV

    Block Asymmetric

    The base interface is AsymmetricBlockCipher and has the following implementations which match the modes the cipher can be operated in.

    NameConstructorNotes
    BufferedAsymmetricBlockCipherAsymmetricBlockCipher 
    OAEPEncodingAsymmetricBlockCipher 
    PKCS1EncodingAsymmetricBlockCipher 
    ISO9796d1EncodingAsymmetricBlockCipherISO9796-1

    The following cipher engines are implemented that can be used with the above modes.

    NameKeySizes (in bits)Notes
    RSAEngineany multiple of 8 large enough for the encoding. 
    ElGamalEngineany multiple of 8 large enough for the encoding. 
    NTRUEngineany multiple of 8 large enough for the encoding. 

    Digest

    The base interface is Digest and has the following implementations

    NameOutput (in bits)Notes
    MD2Digest128 
    MD4Digest128 
    MD5Digest128 
    RipeMD128Digest128basic RipeMD
    RipeMD160Digest160enhanced version of RipeMD
    RipeMD256Digest256expanded version of RipeMD128
    RipeMD320Digest320expanded version of RipeMD160
    SHA1Digest160 
    SHA224Digest224FIPS 180-2
    SHA256Digest256FIPS 180-2
    SHA384Digest384FIPS 180-2
    SHA512Digest512FIPS 180-2
    SHA3Digest224, 256, 288, 384, 512
    TigerDigest192The Tiger Digest.
    GOST3411Digest256The GOST-3411 Digest.
    WhirlpoolDigest512The Whirlpool Digest.

    MAC

    The base interface is Mac and has the following implementations

    NameOutput (in bits)Notes
    CBCBlockCipherMacblocksize/2 unless specified 
    CFBBlockCipherMacblocksize/2, in CFB 8 mode, unless specified 
    CMac24 to 128 bitsUsable with block ciphers, NIST SP 800-38B.
    GMac96 to 128 bitsUsable with GCM mode ciphers, defined for AES, NIST SP 800-38D.
    GOST28147Mac32 bits 
    ISO9797Alg3Macmultiple of 8 bits up to underlying cipher size. 
    HMacdigest length 
    SipHash64 bits 
    VMPCMac160 bits 

    PBE

    The base class is PBEParametersGenerator and has the following sub-classes

    NameConstructorNotes
    PKCS5S1ParametersGeneratorDigest 
    PKCS5S2ParametersGenerator Uses SHA1/Hmac as defined
    PKCS12ParametersGeneratorDigest 
    OpenSSLPBEParametersGenerator Uses MD5 as defined

    IESCipher

    The IES cipher is based on the one described in IEEE P1363a (draft 10), for use with either traditional Diffie-Hellman or Elliptic Curve Diffie-Hellman.

    Note: At the moment this is still a draft, don't use it for anything that may be subject to long term storage, the key values produced may well change as the draft is finalised.

    Commitments

    The base class is Committer and has the following sub-classes

    >
    NameNotes
    HashCommitterHash commitment algorithm described in Usenix RPC MixNet Paper (2002)

    Key Agreement

    Two versions of Diffie-Hellman key agreement are supported, the basic version, and one for use with long term public keys. Two versions of key agreement using Elliptic Curve cryptography are also supported, standard Diffie-Hellman key agreement and standard key agreement with co-factors.

    The agreement APIs are in the org.bouncycastle.crypto.agreement package. Classes for generating Diffie-Hellman parameters can be found in the org.bouncycastle.crypto.params and org.bouncycastle.crypto.generators packages.

    Key Encapsulation Mechanisms

    The base class is KeyEncapsulation and has the following sub-classes

    >
    NameNotes
    RSAKeyEncapsulationRSA-KEM from ISO 18033-2
    PKCS5S2ParametersGeneratorECIES-KEM from ISO 18033-2

    Signers

    DSA, ECDSA, ISO-9796-2, GOST-3410-94, GOST-3410-2001, DSTU-4145-2002, and RSA-PSS are supported by the org.bouncycastle.crypto.signers package. Note: as these are light weight classes, if you need to use SHA1 or GOST-3411 (as defined in the relevant standards) you'll also need to make use of the appropriate digest class in conjunction with these. Classes for generating DSA and ECDSA parameters can be found in the org.bouncycastle.crypto.params and org.bouncycastle.crypto.generators packages.

    4.4 Elliptic Curve Transforms.

    The org.bouncycastle.crypto.ec package contains implementations for a variety of EC cryptographic transforms such as EC ElGamal.

    4.4 TLS/DTLS

    The org.bouncycastle.crypto.tls package contains implementations for TLS 1.1 and DTLS 1.0.

    4.5 Deterministic Random Bit Generators (DRBG) and SecureRandom wrappers

    The org.bouncycastle.crypto.prng package contains implementations for a variety of bit generators including those from SP 800-90A, as well as builders for SecureRandom objects based around them.

    4.6 ASN.1 package

    The light-weight API has direct interfaces into a package capable of reading and writing DER-encoded ASN.1 objects and for the generation of X.509 V3 certificate objects and PKCS12 files. BER InputStream and OutputStream classes are provided as well.

    5.0 Bouncy Castle Provider

    The Bouncy Castle provider is a JCE compliant provider that is a wrapper built on top of the light-weight API.

    The advantage for writing application code that uses the provider interface to cryptographic algorithms is that the actual provider used can be selected at run time. This is extremely valuable for applications that may wish to make use of a provider that has underlying hardware for cryptographic computation, or where an application may have been developed in an environment with cryptographic export controls.

    5.1 Example

    To utilise the JCE provider in a program, the fundamentals are as follows;

    
    	/*
    	 * This will generate a random key, and encrypt the data
    	 */
    	Key		key;
    	KeyGenerator	keyGen;
    	Cipher		encrypt;
    
    	Security.addProvider(new BouncyCastleProvider());
    
    	try
    	{
    		// "BC" is the name of the BouncyCastle provider
    		keyGen = KeyGenerator.getInstance("DES", "BC");
    		keyGen.init(new SecureRandom());
    
    		key = keyGen.generateKey();
    
    		encrypt = Cipher.getInstance("DES/CBC/PKCS5Padding", "BC");
    	}
    	catch (Exception e)
    	{
    		System.err.println(e);
    		System.exit(1);
    	}
    
    	encrypt.init(Cipher.ENCRYPT_MODE, key);
    
    	bOut = new ByteArrayOutputStream();
    	cOut = new CipherOutputStream(bOut, encrypt);
    
    	cOut.write("plaintext".getBytes());
    	cOut.close();
    
    	// bOut now contains the cipher text
    
    

    The provider can also be configured as part of your environment via static registration by adding an entry to the java.security properties file (found in $JAVA_HOME/jre/lib/security/java.security, where $JAVA_HOME is the location of your JDK/JRE distribution). You'll find detailed instructions in the file but basically it comes down to adding a line:

    
        security.provider.<n>=org.bouncycastle.jce.provider.BouncyCastleProvider
    
    

    Where <n> is the preference you want the provider at (1 being the most prefered).

    Where you put the jar is up to mostly up to you, although with jdk1.3 and jdk1.4 the best (and in some cases only) place to have it is in $JAVA_HOME/jre/lib/ext. Note: under Windows there will normally be a JRE and a JDK install of Java if you think you have installed it correctly and it still doesn't work chances are you have added the provider to the installation not being used.

    Note: with JDK 1.4 and later you will need to have installed the unrestricted policy files to take full advantage of the provider. If you do not install the policy files you are likely to get something like the following:

            java.lang.SecurityException: Unsupported keysize or algorithm parameters
                    at javax.crypto.Cipher.init(DashoA6275)
    
    The policy files can be found at the same place you downloaded the JDK.

    5.2 Algorithms

    Symmetric (Block)

    Modes:

    • ECB
    • CBC
    • OFB(n)
    • CFB(n)
    • SIC (also known as CTR)
    • OpenPGPCFB
    • CTS (equivalent to CBC/WithCTS)
    • GOFB
    • CCM
    • EAX

    Where (n) is a multiple of 8 that gives the blocksize in bits, eg, OFB8. Note that OFB and CFB mode can be used with plain text that is not an exact multiple of the block size if NoPadding has been specified.

    Padding Schemes:

    • No padding
    • PKCS5/7
    • ISO10126/ISO10126-2
    • ISO7816-4/ISO9797-1
    • X9.23/X923
    • TBC
    • ZeroByte
    • withCTS (if used with ECB mode)

    When placed together this gives a specification for an algorithm as;

    • DES/CBC/X9.23Padding
    • DES/OFB8/NoPadding
    • IDEA/CBC/ISO10126Padding
    • IDEA/CBC/ISO7816-4Padding
    • SKIPJACK/ECB/PKCS7Padding
    • DES/ECB/WithCTS

    Note: default key sizes are in bold.

    NameKeySizes (in bits) Block SizeNotes
    AES0 .. 256 (192)128 bit 
    AESWrap0 .. 256 (192)128 bitA FIPS AES key wrapper
    Blowfish0 .. 448 (448)64 bit 
    Camellia128, 192, 256128 bit 
    CamelliaWrap128, 192, 256128 bit 
    CAST50 .. 128(128)64 bit 
    CAST60 .. 256(256)128 bit 
    DES6464 bit 
    DESede128, 19264 bit 
    DESedeWrap128, 192128 bitA Draft IETF DESede key wrapper
    GOST2814725664 bit 
    IDEA128 (128)64 bitOnly included in extended provider jar.
    Noekeon128(128)128 bit 
    RC20 .. 1024 (128)64 bit 
    RC50 .. 128 (128)64 bitUses a 32 bit word
    RC5-640 .. 256 (256)128 bitUses a 64 bit word
    RC60 .. 256 (128)128 bit 
    Rijndael0 .. 256 (192)128 bit 
    SEED128(128)128 bit 
    SEEDWrap128(128)128 bit 
    Serpent128, 192, 256 (256)128 bit 
    Skipjack0 .. 128 (128)64 bit 
    TEA128 (128)64 bit 
    Twofish128, 192, 256 (256)128 bit 
    XTEA128 (128)64 bit 

    Symmetric (Stream)

    Note: default key sizes are in bold.

    NameKeySizes (in bits)Notes
    RC440 .. 2048 bits (128) 
    HC128(128) 
    HC256(256) 
    Salsa20128/256(128) 
    VMPC128/6144(128) 
    Grainv18064 bit IV
    Grain12812896 bit IV

    Block Asymmetric

    Encoding:

    • OAEP - Optimal Asymmetric Encryption Padding
    • PCKS1 - PKCS v1.5 Padding
    • ISO9796-1 - ISO9796-1 edition 1 Padding

    Note: except as indicated in PKCS 1v2 we recommend you use OAEP, as mandated in X9.44.

    When placed together with RSA this gives a specification for an algorithm as;

    • RSA/NONE/NoPadding
    • RSA/NONE/PKCS1Padding
    • RSA/NONE/OAEPWithMD5AndMGF1Padding
    • RSA/NONE/OAEPWithSHA1AndMGF1Padding
    • RSA/NONE/OAEPWithSHA224AndMGF1Padding
    • RSA/NONE/OAEPWithSHA256AndMGF1Padding
    • RSA/NONE/OAEPWithSHA384AndMGF1Padding
    • RSA/NONE/OAEPWithSHA512AndMGF1Padding
    • RSA/NONE/ISO9796-1Padding
    NameKeySizes (in bits)Notes
    RSAany multiple of 8 bits large enough for the encryption(2048) 
    ElGamalany multiple of 8 bits large enough for the encryption(1024) 

    Key Agreement

    Diffie-Hellman key agreement is supported using the "DH", "ECDH", and "ECDHC" (ECDH with cofactors) key agreement instances.

    Note: with basic "DH" only the basic algorithm fits in with the JCE API, if you're using long-term public keys you may want to look at the light-weight API.

    ECIES

    An implementation of ECIES (stream mode) as described in IEEE P 1363a.

    Note: At the moment this is still a draft, don't use it for anything that may be subject to long term storage, the key values produced may well change as the draft is finalised.

    Digest

    NameOutput (in bits)Notes
    GOST3411256 
    MD2128 
    MD4128 
    MD5128 
    RipeMD128128basic RipeMD
    RipeMD160160enhanced version of RipeMD
    RipeMD256Digest256expanded version of RipeMD128
    RipeMD320Digest320expanded version of RipeMD160
    SHA1160 
    SHA-224224FIPS 180-2
    SHA-256256FIPS 180-2
    SHA-384384FIPS 180-2
    SHA-512512FIPS 180-2
    SHA3-224224 
    SHA3-256256 
    SHA3-384384 
    SHA3-512512 
    Tiger192 
    Whirlpool512 

    MAC

    NameOutput (in bits)Notes
    Any MAC based on a block cipher, CBC (the default) and CFB modes.half the cipher's block size (usually 32 bits) 
    VMPC-MAC128 
    HMac-MD2128 
    HMac-MD4128 
    HMac-MD5128 
    HMac-RipeMD128128 
    HMac-RipeMD160160 
    HMac-SHA1160 
    HMac-SHA224224 
    HMac-SHA256256 
    HMac-SHA384384 
    HMac-SHA512512 
    HMac-Tiger192 

    Examples:

    • DESMac
    • DESMac/CFB8
    • DESedeMac
    • DESedeMac/CFB8
    • DESedeMac64
    • SKIPJACKMac
    • SKIPJACKMac/CFB8
    • IDEAMac
    • IDEAMac/CFB8
    • RC2Mac
    • RC2Mac/CFB8
    • RC5Mac
    • RC5Mac/CFB8
    • ISO9797ALG3Mac

    Signature Algorithms

    Schemes:

    • DSTU4145
    • GOST3411withGOST3410 (GOST3411withGOST3410-94)
    • GOST3411withECGOST3410 (GOST3411withGOST3410-2001)
    • MD2withRSA
    • MD5withRSA
    • SHA1withRSA
    • RIPEMD128withRSA
    • RIPEMD160withRSA
    • RIPEMD160withECDSA
    • RIPEMD256withRSA
    • SHA1withDSA
    • NONEwithDSA
    • SHA1withECDSA
    • NONEwithECDSA
    • SHA224withECDSA
    • SHA256withECDSA
    • SHA384withECDSA
    • SHA512withECDSA
    • SHA1withECNR
    • SHA224withECNR
    • SHA256withECNR
    • SHA384withECNR
    • SHA512withECNR
    • SHA224withRSA
    • SHA256withRSA
    • SHA384withRSA
    • SHA512withRSA
    • SHA1withRSAandMGF1
    • SHA256withRSAandMGF1
    • SHA384withRSAandMGF1
    • SHA512withRSAandMGF1

    PBE

    Schemes:

    • PKCS5S1, any Digest, any symmetric Cipher, ASCII
    • PKCS5S2, SHA1/HMac, any symmetric Cipher, ASCII, UTF8
    • PKCS12, any Digest, any symmetric Cipher, Unicode

    Defined in Bouncy Castle JCE Provider
    NameKey Generation SchemeKey Length (in bits)Char to Byte conversion
    PBEWithMD2AndDESPKCS5 Scheme 1648 bit chars
    PBEWithMD2AndRC2PKCS5 Scheme 11288 bit chars
    PBEWithMD5AndDESPKCS5 Scheme 1648 bit chars
    PBEWithMD5AndRC2PKCS5 Scheme 11288 bit chars
    PBEWithSHA1AndDESPKCS5 Scheme 1648 bit chars
    PBEWithSHA1AndRC2PKCS5 Scheme 11288 bit chars
    PBKDF2WithHmacSHA1PKCS5 Scheme 2variableUTF-8 chars
    PBKDF2WithHmacSHA1AndUTF8PKCS5 Scheme 2variableUTF-8 chars
    PBKDF2WithHmacSHA1And8bitPKCS5 Scheme 2variable8 bit chars
    PBEWithSHAAnd2-KeyTripleDES-CBCPKCS1212816 bit chars
    PBEWithSHAAnd3-KeyTripleDES-CBCPKCS1219216 bit chars
    PBEWithSHAAnd128BitRC2-CBCPKCS1212816 bit chars
    PBEWithSHAAnd40BitRC2-CBCPKCS124016 bit chars
    PBEWithSHAAnd128BitRC4PKCS1212816 bit chars
    PBEWithSHAAnd40BitRC4PKCS124016 bit chars
    PBEWithSHAAndTwofish-CBCPKCS1225616 bit chars
    PBEWithSHAAndIDEA-CBCPKCS1212816 bit chars

    5.3 Certificates

    The Bouncy Castle provider will read X.509 certficates (v2 or v3) as per the examples in the java.security.cert.CertificateFactory class. They can be provided either in the normal PEM encoded format, or as DER binaries.

    The CertificateFactory will also read X.509 CRLs (v2) from either PEM or DER encodings.

    In addition to the classes in the org.bouncycastle.asn1.x509 package for certificate, CRLs, and OCSP, CRMF, and CMP message generation a more JCE "friendly" class is provided in the package org.bouncycastle.cert. The JCE "friendly" classes found in the jcajce subpackages support RSA, DSA, GOST, DTSU, and EC-DSA.

    5.4 Keystore

    The Bouncy Castle package has three implementation of a keystore.

    The first "BKS" is a keystore that will work with the keytool in the same fashion as the Sun "JKS" keystore. The keystore is resistent to tampering but not inspection.

    The second, Keystore.BouncyCastle, or Keystore.UBER will only work with the keytool if the password is provided on the command line, as the entire keystore is encrypted with a PBE based on SHA1 and Twofish. PBEWithSHAAndTwofish-CBC. This makes the entire keystore resistant to tampering and inspection, and forces verification. The Sun JDK provided keytool will attempt to load a keystore even if no password is given, this is impossible for this version. (One might wonder about going to all this trouble and then having the password on the command line! New keytool anyone?).

    In the first case, the keys are encrypted with 3-Key-TripleDES.

    The third is a PKCS12 compatible keystore. PKCS12 provides a slightly different situation from the regular key store, the keystore password is currently the only password used for storing keys. Otherwise it supports all the functionality required for it to be used with the keytool. In some situations other libraries always expect to be dealing with Sun certificates, if this is the case use PKCS12-DEF, and the certificates produced by the key store will be made using the default provider. In the default case PKCS12 uses 3DES for key protection and 40 bit RC2 for protecting the certificates. It is also possible to use 3DES for both by using PKCS12-3DES-3DES or PKCS12-DEF-3DES-3DES as the KeyStore type.

    There is an example program that produces PKCS12 files suitable for loading into browsers. It is in the package org.bouncycastle.jce.examples.

    5.5 Additional support classes for Elliptic Curve.

    There are no classes for supporting EC in the JDK prior to JDK 1.5. If you are using an earlier JDK you can find classes for using EC in the following packages:

    • org.bouncycastle.jce.spec
    • org.bouncycastle.jce.interfaces
    • org.bouncycastle.jce

    6.0 BouncyCastle S/MIME

    To be able to fully compile and utilise the BouncyCastle S/MIME package (including the test classes) you need the jar files for the following APIs.

    6.1 Setting up BouncyCastle S/MIME in JavaMail

    The BouncyCastle S/MIME handlers may be set in JavaMail two ways.
    • STATICALLY
      Add the following entries to the mailcap file:
          application/pkcs7-signature;; x-java-content-handler=org.bouncycastle.mail.smime.handlers.pkcs7_signature
          application/pkcs7-mime;; x-java-content-handler=org.bouncycastle.mail.smime.handlers.pkcs7_mime
          application/x-pkcs7-signature;; x-java-content-handler=org.bouncycastle.mail.smime.handlers.x_pkcs7_signature
          application/x-pkcs7-mime;; x-java-content-handler=org.bouncycastle.mail.smime.handlers.x_pkcs7_mime
          multipart/signed;; x-java-content-handler=org.bouncycastle.mail.smime.handlers.multipart_signed
          
    • DYNAMICALLY
      The following code will add the BouncyCastle S/MIME handlers dynamically:
          import javax.activation.MailcapCommandMap;
          import javax.activation.CommandMap;
      
          public static void setDefaultMailcap()
          {
              MailcapCommandMap _mailcap =
                  (MailcapCommandMap)CommandMap.getDefaultCommandMap();
      
              _mailcap.addMailcap("application/pkcs7-signature;; x-java-content-handler=org.bouncycastle.mail.smime.handlers.pkcs7_signature");
              _mailcap.addMailcap("application/pkcs7-mime;; x-java-content-handler=org.bouncycastle.mail.smime.handlers.pkcs7_mime");
              _mailcap.addMailcap("application/x-pkcs7-signature;; x-java-content-handler=org.bouncycastle.mail.smime.handlers.x_pkcs7_signature");
              _mailcap.addMailcap("application/x-pkcs7-mime;; x-java-content-handler=org.bouncycastle.mail.smime.handlers.x_pkcs7_mime");
              _mailcap.addMailcap("multipart/signed;; x-java-content-handler=org.bouncycastle.mail.smime.handlers.multipart_signed");
      
              CommandMap.setDefaultCommandMap(_mailcap);
          }